summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2007-01-02 19:19:48 +0000
committerrubidium <rubidium@openttd.org>2007-01-02 19:19:48 +0000
commit66bbf336c6af7353ef0aeed58002c46543b30635 (patch)
treead4a63860df2626b22f77e7dac712e958bea54cb /src
parentccc0a3f4dbf58c005b22341ac8874252924690cd (diff)
downloadopenttd-66bbf336c6af7353ef0aeed58002c46543b30635.tar.xz
(svn r7759) -Merge: makefile rewrite. This merge features:
- A proper ./configure, so everything needs to be configured only once, not for every make. - Usage of makedepend when available. This greatly reduces the time needed for generating the dependencies. - A generator for all project files. There is a single file with sources, which is used to generate Makefiles and the project files for MSVC. - Proper support for OSX universal binaries. - Object files for non-MSVC compiles are also placed in separate directories, making is faster to switch between debug and release compiles and it does not touch the directory with the source files. - Functionality to make a bundle of all needed files for for example a nightly or distribution of a binary with all needed GRFs and language files. Note: as this merge moves almost all files, it is recommended to make a backup of your working copy before updating your working copy.
Diffstat (limited to 'src')
-rw-r--r--src/ai/ai.c247
-rw-r--r--src/ai/ai.h111
-rw-r--r--src/ai/default/default.c3934
-rw-r--r--src/ai/default/default.h8
-rw-r--r--src/ai/trolly/build.c324
-rw-r--r--src/ai/trolly/pathfinder.c510
-rw-r--r--src/ai/trolly/shared.c118
-rw-r--r--src/ai/trolly/trolly.c1353
-rw-r--r--src/ai/trolly/trolly.h262
-rw-r--r--src/aircraft.h26
-rw-r--r--src/aircraft_cmd.c2120
-rw-r--r--src/aircraft_gui.c350
-rw-r--r--src/airport.c489
-rw-r--r--src/airport.h163
-rw-r--r--src/airport_gui.c286
-rw-r--r--src/airport_movement.h794
-rw-r--r--src/aystar.c296
-rw-r--r--src/aystar.h179
-rw-r--r--src/bmp.c378
-rw-r--r--src/bmp.h36
-rw-r--r--src/bridge.h32
-rw-r--r--src/bridge_gui.c167
-rw-r--r--src/bridge_map.c51
-rw-r--r--src/bridge_map.h163
-rw-r--r--src/build_vehicle_gui.c492
-rw-r--r--src/callback_table.c91
-rw-r--r--src/callback_table.h11
-rw-r--r--src/clear_cmd.c803
-rw-r--r--src/clear_map.h145
-rw-r--r--src/command.c562
-rw-r--r--src/command.h213
-rwxr-xr-xsrc/configure323
-rw-r--r--src/console.c1150
-rw-r--r--src/console.h160
-rw-r--r--src/console_cmds.c1608
-rw-r--r--src/currency.c182
-rw-r--r--src/currency.h45
-rw-r--r--src/date.c304
-rw-r--r--src/date.h61
-rw-r--r--src/debug.c153
-rw-r--r--src/debug.h108
-rw-r--r--src/dedicated.c58
-rw-r--r--src/depot.c127
-rw-r--r--src/depot.h112
-rw-r--r--src/depot_gui.c954
-rw-r--r--src/direction.h147
-rw-r--r--src/disaster_cmd.c1001
-rw-r--r--src/dock_gui.c378
-rw-r--r--src/driver.c221
-rw-r--r--src/driver.h13
-rw-r--r--src/dummy_land.c83
-rw-r--r--src/economy.c1738
-rw-r--r--src/economy.h70
-rw-r--r--src/elrail.c445
-rw-r--r--src/endian_check.c52
-rw-r--r--src/engine.c650
-rw-r--r--src/engine.h309
-rw-r--r--src/engine_gui.c285
-rw-r--r--src/fileio.c151
-rw-r--r--src/fileio.h19
-rw-r--r--src/fios.c412
-rw-r--r--src/fios.h86
-rw-r--r--src/fontcache.c524
-rw-r--r--src/fontcache.h56
-rw-r--r--src/functions.h227
-rw-r--r--src/genworld.c292
-rw-r--r--src/genworld.h94
-rw-r--r--src/genworld_gui.c898
-rw-r--r--src/gfx.c2025
-rw-r--r--src/gfx.h163
-rw-r--r--src/gfxinit.c390
-rw-r--r--src/gfxinit.h9
-rw-r--r--src/graph_gui.c1258
-rw-r--r--src/gui.h141
-rw-r--r--src/hal.h49
-rw-r--r--src/heightmap.c459
-rw-r--r--src/heightmap.h33
-rw-r--r--src/helpers.cpp70
-rw-r--r--src/industry.h199
-rw-r--r--src/industry_cmd.c1910
-rw-r--r--src/industry_gui.c693
-rw-r--r--src/industry_map.h259
-rw-r--r--src/intro_gui.c149
-rw-r--r--src/landscape.c731
-rw-r--r--src/lang/american.txt3116
-rw-r--r--src/lang/brazilian_portuguese.txt3109
-rw-r--r--src/lang/bulgarian.txt3068
-rw-r--r--src/lang/catalan.txt3116
-rw-r--r--src/lang/czech.txt3174
-rw-r--r--src/lang/danish.txt3116
-rw-r--r--src/lang/dutch.txt3116
-rw-r--r--src/lang/english.txt3116
-rw-r--r--src/lang/esperanto.txt3116
-rw-r--r--src/lang/estonian.txt3216
-rw-r--r--src/lang/finnish.txt3111
-rw-r--r--src/lang/french.txt3117
-rw-r--r--src/lang/galician.txt2985
-rw-r--r--src/lang/german.txt3117
-rw-r--r--src/lang/hungarian.txt3217
-rw-r--r--src/lang/icelandic.txt2900
-rw-r--r--src/lang/italian.txt3116
-rw-r--r--src/lang/norwegian.txt3114
-rw-r--r--src/lang/origveh.txt261
-rw-r--r--src/lang/polish.txt3245
-rw-r--r--src/lang/portuguese.txt3116
-rw-r--r--src/lang/romanian.txt3116
-rw-r--r--src/lang/russian.txt3115
-rw-r--r--src/lang/slovak.txt3180
-rw-r--r--src/lang/spanish.txt3117
-rw-r--r--src/lang/swedish.txt3116
-rw-r--r--src/lang/turkish.txt3114
-rw-r--r--src/lang/ukrainian.txt3113
-rw-r--r--src/lang/unfinished/afrikaans.txt2541
-rw-r--r--src/lang/unfinished/croatian.txt1713
-rw-r--r--src/lang/unfinished/frisian.txt354
-rw-r--r--src/lang/unfinished/greek.txt1529
-rw-r--r--src/lang/unfinished/japanese.txt1436
-rw-r--r--src/lang/unfinished/latvian.txt1485
-rw-r--r--src/lang/unfinished/lithuanian.txt3118
-rw-r--r--src/lang/unfinished/serbian.txt3
-rw-r--r--src/lang/unfinished/simplified_chinese.txt1761
-rw-r--r--src/lang/unfinished/slovenian.txt2318
-rw-r--r--src/lang/unfinished/traditional_chinese.txt2
-rw-r--r--src/livery.h58
-rw-r--r--src/lzoconf.h452
-rw-r--r--src/macros.h190
-rw-r--r--src/main_gui.c2436
-rw-r--r--src/map.c246
-rw-r--r--src/map.h190
-rw-r--r--src/masm64.rules266
-rw-r--r--src/md5.c384
-rw-r--r--src/md5.h93
-rw-r--r--src/mersenne.c74
-rw-r--r--src/minilzo.c1971
-rw-r--r--src/minilzo.h97
-rw-r--r--src/misc.c634
-rw-r--r--src/misc_cmd.c336
-rw-r--r--src/misc_gui.c1912
-rw-r--r--src/mixer.c140
-rw-r--r--src/mixer.h23
-rw-r--r--src/music.c28
-rw-r--r--src/music.h16
-rw-r--r--src/music/bemidi.cpp53
-rw-r--r--src/music/bemidi.h10
-rw-r--r--src/music/dmusic.cpp232
-rw-r--r--src/music/dmusic.h10
-rw-r--r--src/music/extmidi.c108
-rw-r--r--src/music/extmidi.h10
-rw-r--r--src/music/null_m.c21
-rw-r--r--src/music/null_m.h10
-rw-r--r--src/music/os2_m.c77
-rw-r--r--src/music/os2_m.h10
-rw-r--r--src/music/qtmidi.c371
-rw-r--r--src/music/qtmidi.h10
-rw-r--r--src/music/win32_m.c170
-rw-r--r--src/music/win32_m.h10
-rw-r--r--src/music_gui.c506
-rw-r--r--src/namegen.c790
-rw-r--r--src/namegen.h10
-rw-r--r--src/network/core/config.h49
-rw-r--r--src/network/core/game.h47
-rw-r--r--src/network/core/os_abstraction.h181
-rw-r--r--src/network/core/packet.c216
-rw-r--r--src/network/core/packet.h67
-rw-r--r--src/network/core/tcp.c227
-rw-r--r--src/network/core/tcp.h60
-rw-r--r--src/network/core/udp.c277
-rw-r--r--src/network/core/udp.h62
-rw-r--r--src/network/network.c1451
-rw-r--r--src/network/network.h212
-rw-r--r--src/network/network_client.c819
-rw-r--r--src/network/network_client.h25
-rw-r--r--src/network/network_data.c106
-rw-r--r--src/network/network_data.h167
-rw-r--r--src/network/network_gamelist.c74
-rw-r--r--src/network/network_gamelist.h11
-rw-r--r--src/network/network_gui.c1706
-rw-r--r--src/network/network_gui.h26
-rw-r--r--src/network/network_server.c1528
-rw-r--r--src/network/network_server.h39
-rw-r--r--src/network/network_udp.c663
-rw-r--r--src/network/network_udp.h17
-rw-r--r--src/newgrf.c3694
-rw-r--r--src/newgrf.h73
-rw-r--r--src/newgrf_callbacks.h89
-rw-r--r--src/newgrf_cargo.c68
-rw-r--r--src/newgrf_cargo.h60
-rw-r--r--src/newgrf_config.c463
-rw-r--r--src/newgrf_config.h64
-rw-r--r--src/newgrf_engine.c1157
-rw-r--r--src/newgrf_engine.h67
-rw-r--r--src/newgrf_gui.c534
-rw-r--r--src/newgrf_sound.c68
-rw-r--r--src/newgrf_sound.h25
-rw-r--r--src/newgrf_spritegroup.c233
-rw-r--r--src/newgrf_spritegroup.h196
-rw-r--r--src/newgrf_station.c766
-rw-r--r--src/newgrf_station.h128
-rw-r--r--src/newgrf_text.c436
-rw-r--r--src/newgrf_text.h16
-rw-r--r--src/news.h83
-rw-r--r--src/news_gui.c922
-rw-r--r--src/npf.c894
-rw-r--r--src/npf.h121
-rw-r--r--src/oldloader.c1583
-rw-r--r--src/oldpool.c86
-rw-r--r--src/oldpool.h96
-rw-r--r--src/openttd.c1685
-rw-r--r--src/openttd.h567
-rw-r--r--src/order.h202
-rw-r--r--src/order_cmd.c1278
-rw-r--r--src/order_gui.c664
-rw-r--r--src/os/macosx/G5_detector.c29
-rw-r--r--src/os/macosx/macos.h30
-rw-r--r--src/os/macosx/macos.m162
-rw-r--r--src/os/macosx/osx_stdafx.h19
-rw-r--r--src/os/macosx/splash.c144
-rw-r--r--src/os/macosx/splash.h10
-rw-r--r--src/os2.c266
-rw-r--r--src/os_timer.c70
-rw-r--r--src/ottdres.rc107
-rw-r--r--src/pathfind.c968
-rw-r--r--src/pathfind.h77
-rw-r--r--src/player.h354
-rw-r--r--src/player_gui.c1131
-rw-r--r--src/players.c1339
-rw-r--r--src/queue.c736
-rw-r--r--src/queue.h208
-rw-r--r--src/rail.c132
-rw-r--r--src/rail.h471
-rw-r--r--src/rail_cmd.c1985
-rw-r--r--src/rail_gui.c1188
-rw-r--r--src/rail_map.h342
-rw-r--r--src/railtypes.h214
-rw-r--r--src/resource.h17
-rw-r--r--src/road.h26
-rw-r--r--src/road_cmd.c1065
-rw-r--r--src/road_cmd.h10
-rw-r--r--src/road_gui.c560
-rw-r--r--src/road_map.c54
-rw-r--r--src/road_map.h213
-rw-r--r--src/roadveh.h22
-rw-r--r--src/roadveh_cmd.c1826
-rw-r--r--src/roadveh_gui.c546
-rw-r--r--src/saveload.c1686
-rw-r--r--src/saveload.h305
-rw-r--r--src/screenshot.c575
-rw-r--r--src/screenshot.h25
-rw-r--r--src/sdl.c139
-rw-r--r--src/sdl.h58
-rw-r--r--src/settings.c1861
-rw-r--r--src/settings.h77
-rw-r--r--src/settings_gui.c1140
-rw-r--r--src/ship.h22
-rw-r--r--src/ship_cmd.c1110
-rw-r--r--src/ship_gui.c527
-rw-r--r--src/signs.c277
-rw-r--r--src/signs.h68
-rw-r--r--src/slope.h41
-rw-r--r--src/smallmap_gui.c1114
-rw-r--r--src/sound.c244
-rw-r--r--src/sound.h113
-rw-r--r--src/sound/cocoa_s.c149
-rw-r--r--src/sound/cocoa_s.h10
-rw-r--r--src/sound/null_s.c13
-rw-r--r--src/sound/null_s.h10
-rw-r--r--src/sound/sdl_s.c47
-rw-r--r--src/sound/sdl_s.h10
-rw-r--r--src/sound/win32_s.c87
-rw-r--r--src/sound/win32_s.h10
-rw-r--r--src/sprite.h45
-rw-r--r--src/spritecache.c461
-rw-r--r--src/spritecache.h35
-rw-r--r--src/station.h237
-rw-r--r--src/station_cmd.c3280
-rw-r--r--src/station_gui.c825
-rw-r--r--src/station_map.c19
-rw-r--r--src/station_map.h304
-rw-r--r--src/stdafx.h311
-rw-r--r--src/strgen/strgen.c1399
-rw-r--r--src/string.c247
-rw-r--r--src/string.h114
-rw-r--r--src/strings.c1311
-rw-r--r--src/strings.h14
-rw-r--r--src/subsidy_gui.c176
-rw-r--r--src/table/ai_rail.h480
-rw-r--r--src/table/animcursors.h79
-rw-r--r--src/table/autorail.h72
-rw-r--r--src/table/bridge_land.h521
-rw-r--r--src/table/build_industry.h1600
-rw-r--r--src/table/clear_land.h62
-rw-r--r--src/table/control_codes.h105
-rw-r--r--src/table/elrail_data.h445
-rw-r--r--src/table/engines.h689
-rw-r--r--src/table/files.h64
-rw-r--r--src/table/genland.h159
-rw-r--r--src/table/industry_land.h1022
-rw-r--r--src/table/landscape_const.h257
-rw-r--r--src/table/landscape_sprite.h167
-rw-r--r--src/table/namegen.h3302
-rw-r--r--src/table/palettes.h199
-rw-r--r--src/table/road_land.h281
-rw-r--r--src/table/roadveh.h1077
-rw-r--r--src/table/sprites.h1397
-rw-r--r--src/table/station_land.h1203
-rw-r--r--src/table/town_land.h2226
-rw-r--r--src/table/track_land.h52
-rw-r--r--src/table/train_cmd.h57
-rw-r--r--src/table/tree_land.h228
-rw-r--r--src/table/unicode.h21
-rw-r--r--src/table/unmovable_land.h131
-rw-r--r--src/table/water_land.h151
-rw-r--r--src/terraform_gui.c289
-rw-r--r--src/texteff.c384
-rw-r--r--src/tgp.c829
-rw-r--r--src/tgp.h8
-rw-r--r--src/thread.c157
-rw-r--r--src/thread.h14
-rw-r--r--src/tile.c63
-rw-r--r--src/tile.h121
-rw-r--r--src/town.h230
-rw-r--r--src/town_cmd.c1965
-rw-r--r--src/town_gui.c524
-rw-r--r--src/town_map.h197
-rw-r--r--src/train.h227
-rw-r--r--src/train_cmd.c3810
-rw-r--r--src/train_gui.c1135
-rw-r--r--src/tree_cmd.c672
-rw-r--r--src/tree_map.h131
-rw-r--r--src/tunnel_map.c50
-rw-r--r--src/tunnel_map.h75
-rw-r--r--src/tunnelbridge_cmd.c1313
-rw-r--r--src/unix.c386
-rw-r--r--src/unmovable.h8
-rw-r--r--src/unmovable_cmd.c414
-rw-r--r--src/unmovable_map.h121
-rw-r--r--src/variables.h420
-rw-r--r--src/vehicle.c3235
-rw-r--r--src/vehicle.h484
-rw-r--r--src/vehicle_gui.c1945
-rw-r--r--src/vehicle_gui.h77
-rw-r--r--src/video/cocoa_keys.h127
-rw-r--r--src/video/cocoa_v.h10
-rw-r--r--src/video/cocoa_v.m2064
-rw-r--r--src/video/dedicated_v.c298
-rw-r--r--src/video/dedicated_v.h10
-rw-r--r--src/video/null_v.c45
-rw-r--r--src/video/null_v.h10
-rw-r--r--src/video/sdl_v.c515
-rw-r--r--src/video/sdl_v.h10
-rw-r--r--src/video/win32_v.c876
-rw-r--r--src/video/win32_v.h10
-rw-r--r--src/viewport.c2504
-rw-r--r--src/viewport.h151
-rw-r--r--src/void_map.h18
-rw-r--r--src/water_cmd.c731
-rw-r--r--src/water_map.h142
-rw-r--r--src/waypoint.c442
-rw-r--r--src/waypoint.h73
-rw-r--r--src/widget.c700
-rw-r--r--src/win32.c1140
-rw-r--r--src/win32.h45
-rw-r--r--src/win64.asm17
-rw-r--r--src/window.c2000
-rw-r--r--src/window.h843
-rw-r--r--src/yapf/array.hpp71
-rw-r--r--src/yapf/autocopyptr.hpp83
-rw-r--r--src/yapf/binaryheap.hpp225
-rw-r--r--src/yapf/blob.hpp342
-rw-r--r--src/yapf/countedptr.hpp100
-rw-r--r--src/yapf/crc32.hpp65
-rw-r--r--src/yapf/fixedsizearray.hpp99
-rw-r--r--src/yapf/follow_track.cpp47
-rw-r--r--src/yapf/follow_track.hpp279
-rw-r--r--src/yapf/hashtable.hpp240
-rw-r--r--src/yapf/nodelist.hpp130
-rw-r--r--src/yapf/track_dir.hpp35
-rw-r--r--src/yapf/yapf.h120
-rw-r--r--src/yapf/yapf.hpp93
-rw-r--r--src/yapf/yapf_base.hpp331
-rw-r--r--src/yapf/yapf_common.cpp29
-rw-r--r--src/yapf/yapf_common.hpp163
-rw-r--r--src/yapf/yapf_costbase.hpp37
-rw-r--r--src/yapf/yapf_costcache.hpp196
-rw-r--r--src/yapf/yapf_costrail.hpp381
-rw-r--r--src/yapf/yapf_destrail.hpp149
-rw-r--r--src/yapf/yapf_node.hpp77
-rw-r--r--src/yapf/yapf_node_rail.hpp113
-rw-r--r--src/yapf/yapf_node_road.hpp36
-rw-r--r--src/yapf/yapf_rail.cpp277
-rw-r--r--src/yapf/yapf_road.cpp451
-rw-r--r--src/yapf/yapf_settings.h68
-rw-r--r--src/yapf/yapf_ship.cpp176
393 files changed, 259085 insertions, 0 deletions
diff --git a/src/ai/ai.c b/src/ai/ai.c
new file mode 100644
index 000000000..58b97ad39
--- /dev/null
+++ b/src/ai/ai.c
@@ -0,0 +1,247 @@
+/* $Id$ */
+
+#include "../stdafx.h"
+#include "../openttd.h"
+#include "../variables.h"
+#include "../command.h"
+#include "../network/network.h"
+#include "ai.h"
+#include "default/default.h"
+
+/**
+ * Dequeues commands put in the queue via AI_PutCommandInQueue.
+ */
+static void AI_DequeueCommands(PlayerID player)
+{
+ AICommand *com, *entry_com;
+
+ entry_com = _ai_player[player].queue;
+
+ /* It happens that DoCommandP issues a new DoCommandAI which adds a new command
+ * to this very same queue (don't argue about this, if it currently doesn't
+ * happen I can tell you it will happen with AIScript -- TrueLight). If we
+ * do not make the queue NULL, that commands will be dequeued immediatly.
+ * Therefor we safe the entry-point to entry_com, and make the queue NULL, so
+ * the new queue can be safely built up. */
+ _ai_player[player].queue = NULL;
+ _ai_player[player].queue_tail = NULL;
+
+ /* Dequeue all commands */
+ while ((com = entry_com) != NULL) {
+ _current_player = player;
+
+ _cmd_text = com->text;
+ DoCommandP(com->tile, com->p1, com->p2, com->callback, com->procc);
+
+ /* Free item */
+ entry_com = com->next;
+ free(com->text);
+ free(com);
+ }
+}
+
+/**
+ * Needed for SP; we need to delay DoCommand with 1 tick, because else events
+ * will make infinite loops (AIScript).
+ */
+static void AI_PutCommandInQueue(PlayerID player, TileIndex tile, uint32 p1, uint32 p2, uint procc, CommandCallback* callback)
+{
+ AICommand *com;
+
+ if (_ai_player[player].queue_tail == NULL) {
+ /* There is no item in the queue yet, create the queue */
+ _ai_player[player].queue = malloc(sizeof(AICommand));
+ _ai_player[player].queue_tail = _ai_player[player].queue;
+ } else {
+ /* Add an item at the end */
+ _ai_player[player].queue_tail->next = malloc(sizeof(AICommand));
+ _ai_player[player].queue_tail = _ai_player[player].queue_tail->next;
+ }
+
+ /* This is our new item */
+ com = _ai_player[player].queue_tail;
+
+ /* Assign the info */
+ com->tile = tile;
+ com->p1 = p1;
+ com->p2 = p2;
+ com->procc = procc;
+ com->callback = callback;
+ com->next = NULL;
+ com->text = NULL;
+
+ /* Copy the cmd_text, if needed */
+ if (_cmd_text != NULL) {
+ com->text = strdup(_cmd_text);
+ _cmd_text = NULL;
+ }
+}
+
+/**
+ * Executes a raw DoCommand for the AI.
+ */
+int32 AI_DoCommandCc(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc, CommandCallback* callback)
+{
+ PlayerID old_lp;
+ int32 res = 0;
+ const char* tmp_cmdtext;
+
+ /* If you enable DC_EXEC with DC_QUERY_COST you are a really strange
+ * person.. should we check for those funny jokes?
+ */
+
+ /* The test already resets _cmd_text, so backup the pointer */
+ tmp_cmdtext = _cmd_text;
+
+ /* First, do a test-run to see if we can do this */
+ res = DoCommand(tile, p1, p2, flags & ~DC_EXEC, procc);
+ /* The command failed, or you didn't want to execute, or you are quering, return */
+ if (CmdFailed(res) || !(flags & DC_EXEC) || (flags & DC_QUERY_COST)) {
+ return res;
+ }
+
+ /* Restore _cmd_text */
+ _cmd_text = tmp_cmdtext;
+
+ /* If we did a DC_EXEC, and the command did not return an error, execute it
+ * over the network */
+ if (flags & DC_AUTO) procc |= CMD_AUTO;
+ if (flags & DC_NO_WATER) procc |= CMD_NO_WATER;
+
+ /* NetworkSend_Command needs _local_player to be set correctly, so
+ * adjust it, and put it back right after the function */
+ old_lp = _local_player;
+ _local_player = _current_player;
+
+#ifdef ENABLE_NETWORK
+ /* Send the command */
+ if (_networking) {
+ /* Network is easy, send it to his handler */
+ NetworkSend_Command(tile, p1, p2, procc, callback);
+ } else {
+#else
+ {
+#endif
+ /* If we execute BuildCommands directly in SP, we have a big problem with events
+ * so we need to delay is for 1 tick */
+ AI_PutCommandInQueue(_current_player, tile, p1, p2, procc, callback);
+ }
+
+ /* Set _local_player back */
+ _local_player = old_lp;
+
+ return res;
+}
+
+
+int32 AI_DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc)
+{
+ return AI_DoCommandCc(tile, p1, p2, flags, procc, NULL);
+}
+
+
+/**
+ * Run 1 tick of the AI. Don't overdo it, keep it realistic.
+ */
+static void AI_RunTick(PlayerID player)
+{
+ extern void AiNewDoGameLoop(Player *p);
+
+ Player *p = GetPlayer(player);
+ _current_player = player;
+
+ if (_patches.ainew_active) {
+ AiNewDoGameLoop(p);
+ } else {
+ /* Enable all kind of cheats the old AI needs in order to operate correctly... */
+ _is_old_ai_player = true;
+ AiDoGameLoop(p);
+ _is_old_ai_player = false;
+ }
+}
+
+
+/**
+ * The gameloop for AIs.
+ * Handles one tick for all the AIs.
+ */
+void AI_RunGameLoop(void)
+{
+ /* Don't do anything if ai is disabled */
+ if (!_ai.enabled) return;
+
+ /* Don't do anything if we are a network-client, or the AI has been disabled */
+ if (_networking && (!_network_server || !_patches.ai_in_multiplayer)) return;
+
+ /* New tick */
+ _ai.tick++;
+
+ /* Make sure the AI follows the difficulty rule.. */
+ assert(_opt.diff.competitor_speed <= 4);
+ if ((_ai.tick & ((1 << (4 - _opt.diff.competitor_speed)) - 1)) != 0) return;
+
+ /* Check for AI-client (so joining a network with an AI) */
+ if (!_networking || _network_server) {
+ /* Check if we want to run AIs (server or SP only) */
+ const Player* p;
+
+ FOR_ALL_PLAYERS(p) {
+ if (p->is_active && p->is_ai) {
+ /* This should always be true, else something went wrong... */
+ assert(_ai_player[p->index].active);
+
+ /* Run the script */
+ AI_DequeueCommands(p->index);
+ AI_RunTick(p->index);
+ }
+ }
+ }
+
+ _current_player = OWNER_NONE;
+}
+
+/**
+ * A new AI sees the day of light. You can do here what ever you think is needed.
+ */
+void AI_StartNewAI(PlayerID player)
+{
+ assert(IsValidPlayer(player));
+
+ /* Called if a new AI is booted */
+ _ai_player[player].active = true;
+}
+
+/**
+ * This AI player died. Give it some chance to make a final puf.
+ */
+void AI_PlayerDied(PlayerID player)
+{
+ /* Called if this AI died */
+ _ai_player[player].active = false;
+}
+
+/**
+ * Initialize some AI-related stuff.
+ */
+void AI_Initialize(void)
+{
+ /* First, make sure all AIs are DEAD! */
+ AI_Uninitialize();
+
+ memset(&_ai, 0, sizeof(_ai));
+ memset(&_ai_player, 0, sizeof(_ai_player));
+
+ _ai.enabled = true;
+}
+
+/**
+ * Deinitializer for AI-related stuff.
+ */
+void AI_Uninitialize(void)
+{
+ const Player* p;
+
+ FOR_ALL_PLAYERS(p) {
+ if (p->is_active && p->is_ai) AI_PlayerDied(p->index);
+ }
+}
diff --git a/src/ai/ai.h b/src/ai/ai.h
new file mode 100644
index 000000000..6123970ac
--- /dev/null
+++ b/src/ai/ai.h
@@ -0,0 +1,111 @@
+#ifndef AI_H
+#define AI_H
+
+#include "../functions.h"
+#include "../network/network.h"
+#include "../player.h"
+#include "../command.h"
+
+/* How DoCommands look like for an AI */
+typedef struct AICommand {
+ uint32 tile;
+ uint32 p1;
+ uint32 p2;
+ uint32 procc;
+ CommandCallback* callback;
+
+ char *text;
+ uint uid;
+
+ struct AICommand *next;
+} AICommand;
+
+/* The struct for an AIScript Player */
+typedef struct AIPlayer {
+ bool active; ///< Is this AI active?
+ AICommand *queue; ///< The commands that he has in his queue
+ AICommand *queue_tail; ///< The tail of this queue
+} AIPlayer;
+
+/* The struct to keep some data about the AI in general */
+typedef struct AIStruct {
+ /* General */
+ bool enabled; ///< Is AI enabled?
+ uint tick; ///< The current tick (something like _frame_counter, only for AIs)
+} AIStruct;
+
+VARDEF AIStruct _ai;
+VARDEF AIPlayer _ai_player[MAX_PLAYERS];
+
+// ai.c
+void AI_StartNewAI(PlayerID player);
+void AI_PlayerDied(PlayerID player);
+void AI_RunGameLoop(void);
+void AI_Initialize(void);
+void AI_Uninitialize(void);
+int32 AI_DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc);
+int32 AI_DoCommandCc(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc, CommandCallback* callback);
+
+/** Is it allowed to start a new AI.
+ * This function checks some boundries to see if we should launch a new AI.
+ * @return True if we can start a new AI.
+ */
+static inline bool AI_AllowNewAI(void)
+{
+ /* If disabled, no AI */
+ if (!_ai.enabled)
+ return false;
+
+ /* If in network, but no server, no AI */
+ if (_networking && !_network_server)
+ return false;
+
+ /* If in network, and server, possible AI */
+ if (_networking && _network_server) {
+ /* Do we want AIs in multiplayer? */
+ if (!_patches.ai_in_multiplayer)
+ return false;
+
+ /* Only the NewAI is allowed... sadly enough the old AI just doesn't support this
+ * system, because all commands are delayed by at least 1 tick, which causes
+ * a big problem, because it uses variables that are only set AFTER the command
+ * is really executed... */
+ if (!_patches.ainew_active)
+ return false;
+ }
+
+ return true;
+}
+
+#define AI_CHANCE16(a,b) ((uint16) AI_Random() <= (uint16)((65536 * a) / b))
+#define AI_CHANCE16R(a,b,r) ((uint16)(r = AI_Random()) <= (uint16)((65536 * a) / b))
+
+/**
+ * The random-function that should be used by ALL AIs.
+ */
+static inline uint AI_RandomRange(uint max)
+{
+ /* We pick RandomRange if we are in SP (so when saved, we do the same over and over)
+ * but we pick InteractiveRandomRange if we are a network_server or network-client.
+ */
+ if (_networking)
+ return InteractiveRandomRange(max);
+ else
+ return RandomRange(max);
+}
+
+/**
+ * The random-function that should be used by ALL AIs.
+ */
+static inline uint32 AI_Random(void)
+{
+/* We pick RandomRange if we are in SP (so when saved, we do the same over and over)
+ * but we pick InteractiveRandomRange if we are a network_server or network-client.
+ */
+ if (_networking)
+ return InteractiveRandom();
+ else
+ return Random();
+}
+
+#endif /* AI_H */
diff --git a/src/ai/default/default.c b/src/ai/default/default.c
new file mode 100644
index 000000000..143e724b9
--- /dev/null
+++ b/src/ai/default/default.c
@@ -0,0 +1,3934 @@
+/* $Id$ */
+
+#include "../../stdafx.h"
+#include "../../openttd.h"
+#include "../../aircraft.h"
+#include "../../bridge_map.h"
+#include "../../functions.h"
+#include "../../map.h"
+#include "../../rail_map.h"
+#include "../../road_map.h"
+#include "../../roadveh.h"
+#include "../../station_map.h"
+#include "../../tile.h"
+#include "../../player.h"
+#include "../../tunnel_map.h"
+#include "../../vehicle.h"
+#include "../../engine.h"
+#include "../../command.h"
+#include "../../town.h"
+#include "../../industry.h"
+#include "../../station.h"
+#include "../../pathfind.h"
+#include "../../economy.h"
+#include "../../airport.h"
+#include "../../depot.h"
+#include "../../variables.h"
+#include "../../bridge.h"
+#include "../../date.h"
+#include "default.h"
+
+// remove some day perhaps?
+static uint _ai_service_interval;
+
+typedef void AiStateAction(Player *p);
+
+enum {
+ AIS_0 = 0,
+ AIS_1 = 1,
+ AIS_VEH_LOOP = 2,
+ AIS_VEH_CHECK_REPLACE_VEHICLE = 3,
+ AIS_VEH_DO_REPLACE_VEHICLE = 4,
+ AIS_WANT_NEW_ROUTE = 5,
+ AIS_BUILD_DEFAULT_RAIL_BLOCKS = 6,
+ AIS_BUILD_RAIL = 7,
+ AIS_BUILD_RAIL_VEH = 8,
+ AIS_DELETE_RAIL_BLOCKS = 9,
+ AIS_BUILD_DEFAULT_ROAD_BLOCKS = 10,
+ AIS_BUILD_ROAD = 11,
+ AIS_BUILD_ROAD_VEHICLES = 12,
+ AIS_DELETE_ROAD_BLOCKS = 13,
+ AIS_AIRPORT_STUFF = 14,
+ AIS_BUILD_DEFAULT_AIRPORT_BLOCKS = 15,
+ AIS_BUILD_AIRCRAFT_VEHICLES = 16,
+ AIS_CHECK_SHIP_STUFF = 17,
+ AIS_BUILD_DEFAULT_SHIP_BLOCKS = 18,
+ AIS_DO_SHIP_STUFF = 19,
+ AIS_SELL_VEHICLE = 20,
+ AIS_REMOVE_STATION = 21,
+ AIS_REMOVE_TRACK = 22,
+ AIS_REMOVE_SINGLE_RAIL_TILE = 23
+};
+
+
+#include "../../table/ai_rail.h"
+
+static byte GetRailTrackStatus(TileIndex tile)
+{
+ uint32 r = GetTileTrackStatus(tile, TRANSPORT_RAIL);
+ return (byte) (r | r >> 8);
+}
+
+
+static void AiCase0(Player *p)
+{
+ p->ai.state = AIS_REMOVE_TRACK;
+ p->ai.state_counter = 0;
+}
+
+static void AiCase1(Player *p)
+{
+ p->ai.cur_veh = NULL;
+ p->ai.state = AIS_VEH_LOOP;
+}
+
+static void AiStateVehLoop(Player *p)
+{
+ Vehicle *v;
+ uint index;
+
+ index = (p->ai.cur_veh == NULL) ? 0 : p->ai.cur_veh->index + 1;
+
+ FOR_ALL_VEHICLES_FROM(v, index) {
+ if (v->owner != _current_player) continue;
+
+ if ((v->type == VEH_Train && v->subtype == 0) ||
+ v->type == VEH_Road ||
+ (v->type == VEH_Aircraft && v->subtype <= 2) ||
+ v->type == VEH_Ship) {
+ /* replace engine? */
+ if (v->type == VEH_Train && v->engine_type < 3 &&
+ (_price.build_railvehicle >> 3) < p->player_money) {
+ p->ai.state = AIS_VEH_CHECK_REPLACE_VEHICLE;
+ p->ai.cur_veh = v;
+ return;
+ }
+
+ /* not profitable? */
+ if (v->age >= 730 &&
+ v->profit_last_year < _price.station_value * 5 &&
+ v->profit_this_year < _price.station_value * 5) {
+ p->ai.state_counter = 0;
+ p->ai.state = AIS_SELL_VEHICLE;
+ p->ai.cur_veh = v;
+ return;
+ }
+
+ /* not reliable? */
+ if (v->age >= v->max_age || (
+ v->age != 0 &&
+ GetEngine(v->engine_type)->reliability < 35389
+ )) {
+ p->ai.state = AIS_VEH_CHECK_REPLACE_VEHICLE;
+ p->ai.cur_veh = v;
+ return;
+ }
+ }
+ }
+
+ p->ai.state = AIS_WANT_NEW_ROUTE;
+ p->ai.state_counter = 0;
+}
+
+static EngineID AiChooseTrainToBuild(RailType railtype, int32 money, byte flag, TileIndex tile)
+{
+ EngineID best_veh_index = INVALID_ENGINE;
+ byte best_veh_score = 0;
+ int32 ret;
+ EngineID i;
+
+ for (i = 0; i < NUM_TRAIN_ENGINES; i++) {
+ const RailVehicleInfo *rvi = RailVehInfo(i);
+ const Engine* e = GetEngine(i);
+
+ if (!IsCompatibleRail(e->railtype, railtype) ||
+ rvi->flags & RVI_WAGON ||
+ (rvi->flags & RVI_MULTIHEAD && flag & 1) ||
+ !HASBIT(e->player_avail, _current_player) ||
+ e->reliability < 0x8A3D) {
+ continue;
+ }
+
+ ret = DoCommand(tile, i, 0, 0, CMD_BUILD_RAIL_VEHICLE);
+ if (!CmdFailed(ret) && ret <= money && rvi->ai_rank >= best_veh_score) {
+ best_veh_score = rvi->ai_rank;
+ best_veh_index = i;
+ }
+ }
+
+ return best_veh_index;
+}
+
+static EngineID AiChooseRoadVehToBuild(CargoID cargo, int32 money, TileIndex tile)
+{
+ EngineID best_veh_index = INVALID_ENGINE;
+ int32 best_veh_rating = 0;
+ EngineID i = ROAD_ENGINES_INDEX;
+ EngineID end = i + NUM_ROAD_ENGINES;
+
+ for (; i != end; i++) {
+ const RoadVehicleInfo *rvi = RoadVehInfo(i);
+ const Engine* e = GetEngine(i);
+ int32 rating;
+ int32 ret;
+
+ if (!HASBIT(e->player_avail, _current_player) || e->reliability < 0x8A3D) {
+ continue;
+ }
+
+ /* Skip vehicles which can't take our cargo type */
+ if (rvi->cargo_type != cargo && !CanRefitTo(i, cargo)) continue;
+
+ /* Rate and compare the engine by speed & capacity */
+ rating = rvi->max_speed * rvi->capacity;
+ if (rating <= best_veh_rating) continue;
+
+ ret = DoCommand(tile, i, 0, 0, CMD_BUILD_ROAD_VEH);
+ if (CmdFailed(ret)) continue;
+
+ /* Add the cost of refitting */
+ if (rvi->cargo_type != cargo) ret += GetRefitCost(i);
+ if (ret > money) continue;
+
+ best_veh_rating = rating;
+ best_veh_index = i;
+ }
+
+ return best_veh_index;
+}
+
+static EngineID AiChooseAircraftToBuild(int32 money, byte flag)
+{
+ EngineID best_veh_index = INVALID_ENGINE;
+ int32 best_veh_cost = 0;
+ EngineID i;
+
+ for (i = AIRCRAFT_ENGINES_INDEX; i != AIRCRAFT_ENGINES_INDEX + NUM_AIRCRAFT_ENGINES; i++) {
+ const Engine* e = GetEngine(i);
+ int32 ret;
+
+ if (!HASBIT(e->player_avail, _current_player) || e->reliability < 0x8A3D) {
+ continue;
+ }
+
+ if ((AircraftVehInfo(i)->subtype & AIR_CTOL) != flag) continue;
+
+ ret = DoCommand(0, i, 0, DC_QUERY_COST, CMD_BUILD_AIRCRAFT);
+ if (!CmdFailed(ret) && ret <= money && ret >= best_veh_cost) {
+ best_veh_cost = ret;
+ best_veh_index = i;
+ }
+ }
+
+ return best_veh_index;
+}
+
+static int32 AiGetBasePrice(const Player* p)
+{
+ int32 base = _price.station_value;
+
+ // adjust base price when more expensive vehicles are available
+ switch (p->ai.railtype_to_use) {
+ default: NOT_REACHED();
+ case RAILTYPE_RAIL: break;
+ case RAILTYPE_ELECTRIC: break;
+ case RAILTYPE_MONO: base = (base * 3) >> 1; break;
+ case RAILTYPE_MAGLEV: base *= 2; break;
+ }
+
+ return base;
+}
+
+#if 0
+static EngineID AiChooseShipToBuild(byte cargo, int32 money)
+{
+ // XXX: not done
+ return INVALID_ENGINE;
+}
+#endif
+
+static EngineID AiChooseRoadVehToReplaceWith(const Player* p, const Vehicle* v)
+{
+ int32 avail_money = p->player_money + v->value;
+ return AiChooseRoadVehToBuild(v->cargo_type, avail_money, v->tile);
+}
+
+static EngineID AiChooseAircraftToReplaceWith(const Player* p, const Vehicle* v)
+{
+ int32 avail_money = p->player_money + v->value;
+ return AiChooseAircraftToBuild(
+ avail_money, AircraftVehInfo(v->engine_type)->subtype & AIR_CTOL
+ );
+}
+
+static EngineID AiChooseTrainToReplaceWith(const Player* p, const Vehicle* v)
+{
+ int32 avail_money = p->player_money + v->value;
+ const Vehicle* u = v;
+ int num = 0;
+
+ while (++num, u->next != NULL) {
+ u = u->next;
+ }
+
+ // XXX: check if a wagon
+ return AiChooseTrainToBuild(v->u.rail.railtype, avail_money, 0, v->tile);
+}
+
+static EngineID AiChooseShipToReplaceWith(const Player* p, const Vehicle* v)
+{
+ error("!AiChooseShipToReplaceWith");
+
+ /* maybe useless, but avoids compiler warning this way */
+ return INVALID_ENGINE;
+}
+
+static void AiHandleGotoDepot(Player *p, int cmd)
+{
+ if (p->ai.cur_veh->current_order.type != OT_GOTO_DEPOT)
+ DoCommand(0, p->ai.cur_veh->index, 0, DC_EXEC, cmd);
+
+ if (++p->ai.state_counter <= 1387) {
+ p->ai.state = AIS_VEH_DO_REPLACE_VEHICLE;
+ return;
+ }
+
+ if (p->ai.cur_veh->current_order.type == OT_GOTO_DEPOT) {
+ p->ai.cur_veh->current_order.type = OT_DUMMY;
+ p->ai.cur_veh->current_order.flags = 0;
+ InvalidateWindow(WC_VEHICLE_VIEW, p->ai.cur_veh->index);
+ }
+}
+
+static void AiRestoreVehicleOrders(Vehicle *v, BackuppedOrders *bak)
+{
+ uint i;
+
+ for (i = 0; bak->order[i].type != OT_NOTHING; i++) {
+ if (!DoCommandP(0, v->index + (i << 16), PackOrder(&bak->order[i]), NULL, CMD_INSERT_ORDER | CMD_NO_TEST_IF_IN_NETWORK))
+ break;
+ }
+}
+
+static void AiHandleReplaceTrain(Player *p)
+{
+ const Vehicle* v = p->ai.cur_veh;
+ BackuppedOrders orderbak[1];
+ EngineID veh;
+
+ // wait until the vehicle reaches the depot.
+ if (!IsTileDepotType(v->tile, TRANSPORT_RAIL) || v->u.rail.track != 0x80 || !(v->vehstatus&VS_STOPPED)) {
+ AiHandleGotoDepot(p, CMD_SEND_TRAIN_TO_DEPOT);
+ return;
+ }
+
+ veh = AiChooseTrainToReplaceWith(p, v);
+ if (veh != INVALID_ENGINE) {
+ TileIndex tile;
+
+ BackupVehicleOrders(v, orderbak);
+ tile = v->tile;
+
+ if (!CmdFailed(DoCommand(0, v->index, 2, DC_EXEC, CMD_SELL_RAIL_WAGON)) &&
+ !CmdFailed(DoCommand(tile, veh, 0, DC_EXEC, CMD_BUILD_RAIL_VEHICLE))) {
+ VehicleID veh = _new_vehicle_id;
+ AiRestoreVehicleOrders(GetVehicle(veh), orderbak);
+ DoCommand(0, veh, 0, DC_EXEC, CMD_START_STOP_TRAIN);
+
+ DoCommand(0, veh, _ai_service_interval, DC_EXEC, CMD_CHANGE_SERVICE_INT);
+ }
+ }
+}
+
+static void AiHandleReplaceRoadVeh(Player *p)
+{
+ const Vehicle* v = p->ai.cur_veh;
+ BackuppedOrders orderbak[1];
+ EngineID veh;
+
+ if (!IsRoadVehInDepotStopped(v)) {
+ AiHandleGotoDepot(p, CMD_SEND_ROADVEH_TO_DEPOT);
+ return;
+ }
+
+ veh = AiChooseRoadVehToReplaceWith(p, v);
+ if (veh != INVALID_ENGINE) {
+ TileIndex tile;
+
+ BackupVehicleOrders(v, orderbak);
+ tile = v->tile;
+
+ if (!CmdFailed(DoCommand(0, v->index, 0, DC_EXEC, CMD_SELL_ROAD_VEH)) &&
+ !CmdFailed(DoCommand(tile, veh, 0, DC_EXEC, CMD_BUILD_ROAD_VEH))) {
+ VehicleID veh = _new_vehicle_id;
+
+ AiRestoreVehicleOrders(GetVehicle(veh), orderbak);
+ DoCommand(0, veh, 0, DC_EXEC, CMD_START_STOP_ROADVEH);
+ DoCommand(0, veh, _ai_service_interval, DC_EXEC, CMD_CHANGE_SERVICE_INT);
+ }
+ }
+}
+
+static void AiHandleReplaceAircraft(Player *p)
+{
+ const Vehicle* v = p->ai.cur_veh;
+ BackuppedOrders orderbak[1];
+ EngineID veh;
+
+ if (!IsAircraftInHangarStopped(v)) {
+ AiHandleGotoDepot(p, CMD_SEND_AIRCRAFT_TO_HANGAR);
+ return;
+ }
+
+ veh = AiChooseAircraftToReplaceWith(p, v);
+ if (veh != INVALID_ENGINE) {
+ TileIndex tile;
+
+ BackupVehicleOrders(v, orderbak);
+ tile = v->tile;
+
+ if (!CmdFailed(DoCommand(0, v->index, 0, DC_EXEC, CMD_SELL_AIRCRAFT)) &&
+ !CmdFailed(DoCommand(tile, veh, 0, DC_EXEC, CMD_BUILD_AIRCRAFT))) {
+ VehicleID veh = _new_vehicle_id;
+ AiRestoreVehicleOrders(GetVehicle(veh), orderbak);
+ DoCommand(0, veh, 0, DC_EXEC, CMD_START_STOP_AIRCRAFT);
+
+ DoCommand(0, veh, _ai_service_interval, DC_EXEC, CMD_CHANGE_SERVICE_INT);
+ }
+ }
+}
+
+static void AiHandleReplaceShip(Player *p)
+{
+ error("!AiHandleReplaceShip");
+}
+
+typedef EngineID CheckReplaceProc(const Player* p, const Vehicle* v);
+
+static CheckReplaceProc* const _veh_check_replace_proc[] = {
+ AiChooseTrainToReplaceWith,
+ AiChooseRoadVehToReplaceWith,
+ AiChooseShipToReplaceWith,
+ AiChooseAircraftToReplaceWith,
+};
+
+typedef void DoReplaceProc(Player *p);
+static DoReplaceProc* const _veh_do_replace_proc[] = {
+ AiHandleReplaceTrain,
+ AiHandleReplaceRoadVeh,
+ AiHandleReplaceShip,
+ AiHandleReplaceAircraft
+};
+
+static void AiStateCheckReplaceVehicle(Player *p)
+{
+ const Vehicle* v = p->ai.cur_veh;
+
+ if (!IsValidVehicle(v) ||
+ v->owner != _current_player ||
+ v->type > VEH_Ship ||
+ _veh_check_replace_proc[v->type - VEH_Train](p, v) == INVALID_ENGINE) {
+ p->ai.state = AIS_VEH_LOOP;
+ } else {
+ p->ai.state_counter = 0;
+ p->ai.state = AIS_VEH_DO_REPLACE_VEHICLE;
+ }
+}
+
+static void AiStateDoReplaceVehicle(Player *p)
+{
+ const Vehicle* v = p->ai.cur_veh;
+
+ p->ai.state = AIS_VEH_LOOP;
+ // vehicle is not owned by the player anymore, something went very wrong.
+ if (!IsValidVehicle(v) || v->owner != _current_player) return;
+ _veh_do_replace_proc[v->type - VEH_Train](p);
+}
+
+typedef struct FoundRoute {
+ int distance;
+ CargoID cargo;
+ void *from;
+ void *to;
+} FoundRoute;
+
+static Town *AiFindRandomTown(void)
+{
+ return GetRandomTown();
+}
+
+static Industry *AiFindRandomIndustry(void)
+{
+ return GetRandomIndustry();
+}
+
+static void AiFindSubsidyIndustryRoute(FoundRoute *fr)
+{
+ uint i;
+ CargoID cargo;
+ const Subsidy* s;
+ Industry* from;
+ TileIndex to_xy;
+
+ // initially error
+ fr->distance = -1;
+
+ // Randomize subsidy index..
+ i = RandomRange(lengthof(_subsidies) * 3);
+ if (i >= lengthof(_subsidies)) return;
+
+ s = &_subsidies[i];
+
+ // Don't want passengers or mail
+ cargo = s->cargo_type;
+ if (cargo == CT_INVALID ||
+ cargo == CT_PASSENGERS ||
+ cargo == CT_MAIL ||
+ s->age > 7) {
+ return;
+ }
+ fr->cargo = cargo;
+
+ fr->from = from = GetIndustry(s->from);
+
+ if (cargo == CT_GOODS || cargo == CT_FOOD) {
+ Town* to_tow = GetTown(s->to);
+
+ if (to_tow->population < (cargo == CT_FOOD ? 200U : 900U)) return; // error
+ fr->to = to_tow;
+ to_xy = to_tow->xy;
+ } else {
+ Industry* to_ind = GetIndustry(s->to);
+
+ fr->to = to_ind;
+ to_xy = to_ind->xy;
+ }
+
+ fr->distance = DistanceManhattan(from->xy, to_xy);
+}
+
+static void AiFindSubsidyPassengerRoute(FoundRoute *fr)
+{
+ uint i;
+ const Subsidy* s;
+ Town *from,*to;
+
+ // initially error
+ fr->distance = -1;
+
+ // Randomize subsidy index..
+ i = RandomRange(lengthof(_subsidies) * 3);
+ if (i >= lengthof(_subsidies)) return;
+
+ s = &_subsidies[i];
+
+ // Only want passengers
+ if (s->cargo_type != CT_PASSENGERS || s->age > 7) return;
+ fr->cargo = s->cargo_type;
+
+ fr->from = from = GetTown(s->from);
+ fr->to = to = GetTown(s->to);
+
+ // They must be big enough
+ if (from->population < 400 || to->population < 400) return;
+
+ fr->distance = DistanceManhattan(from->xy, to->xy);
+}
+
+static void AiFindRandomIndustryRoute(FoundRoute *fr)
+{
+ Industry* i;
+ uint32 r;
+ CargoID cargo;
+
+ // initially error
+ fr->distance = -1;
+
+ r = Random();
+
+ // pick a source
+ fr->from = i = AiFindRandomIndustry();
+ if (i == NULL) return;
+
+ // pick a random produced cargo
+ cargo = i->produced_cargo[0];
+ if (r & 1 && i->produced_cargo[1] != CT_INVALID) cargo = i->produced_cargo[1];
+
+ fr->cargo = cargo;
+
+ // don't allow passengers
+ if (cargo == CT_INVALID || cargo == CT_PASSENGERS) return;
+
+ if (cargo != CT_GOODS && cargo != CT_FOOD) {
+ // pick a dest, and see if it can receive
+ Industry* i2 = AiFindRandomIndustry();
+
+ if (i2 == NULL || i == i2 || (
+ i2->accepts_cargo[0] != cargo &&
+ i2->accepts_cargo[1] != cargo &&
+ i2->accepts_cargo[2] != cargo)
+ ) {
+ return;
+ }
+
+ fr->to = i2;
+ fr->distance = DistanceManhattan(i->xy, i2->xy);
+ } else {
+ // pick a dest town, and see if it's big enough
+ Town* t = AiFindRandomTown();
+
+ if (t == NULL || t->population < (cargo == CT_FOOD ? 200U : 900U)) return;
+
+ fr->to = t;
+ fr->distance = DistanceManhattan(i->xy, t->xy);
+ }
+}
+
+static void AiFindRandomPassengerRoute(FoundRoute *fr)
+{
+ Town* source;
+ Town* dest;
+
+ // initially error
+ fr->distance = -1;
+
+ fr->from = source = AiFindRandomTown();
+ if (source == NULL || source->population < 400) return;
+
+ fr->to = dest = AiFindRandomTown();
+ if (dest == NULL || source == dest || dest->population < 400) return;
+
+ fr->distance = DistanceManhattan(source->xy, dest->xy);
+}
+
+// Warn: depends on 'xy' being the first element in both Town and Industry
+#define GET_TOWN_OR_INDUSTRY_TILE(p) (((Town*)(p))->xy)
+
+static bool AiCheckIfRouteIsGood(Player *p, FoundRoute *fr, byte bitmask)
+{
+ TileIndex from_tile, to_tile;
+ Station *st;
+ int dist;
+ uint same_station = 0;
+
+ // Make sure distance to closest station is < 37 pixels.
+ from_tile = GET_TOWN_OR_INDUSTRY_TILE(fr->from);
+ to_tile = GET_TOWN_OR_INDUSTRY_TILE(fr->to);
+
+ dist = 0xFFFF;
+ FOR_ALL_STATIONS(st) {
+ int cur;
+
+ if (st->owner != _current_player) continue;
+ cur = DistanceMax(from_tile, st->xy);
+ if (cur < dist) dist = cur;
+ cur = DistanceMax(to_tile, st->xy);
+ if (cur < dist) dist = cur;
+ if (to_tile == from_tile && st->xy == to_tile) same_station++;
+ }
+
+ // To prevent the AI from building ten busstations in the same town, do some calculations
+ // For each road or airport station, we want 350 of population!
+ if ((bitmask == 2 || bitmask == 4) &&
+ same_station > 2 &&
+ ((Town*)fr->from)->population < same_station * 350) {
+ return false;
+ }
+
+ if (dist != 0xFFFF && dist > 37) return false;
+
+ if (p->ai.route_type_mask != 0 &&
+ !(p->ai.route_type_mask & bitmask) &&
+ !CHANCE16(1, 5)) {
+ return false;
+ }
+
+ if (fr->cargo == CT_PASSENGERS || fr->cargo == CT_MAIL) {
+ const Town* from = fr->from;
+ const Town* to = fr->to;
+
+ if (from->pct_pass_transported > 0x99 ||
+ to->pct_pass_transported > 0x99) {
+ return false;
+ }
+
+ // Make sure it has a reasonably good rating
+ if (from->ratings[_current_player] < -100 ||
+ to->ratings[_current_player] < -100) {
+ return false;
+ }
+ } else {
+ const Industry* i = (const Industry*)fr->from;
+
+ if (i->pct_transported[fr->cargo != i->produced_cargo[0]] > 0x99 ||
+ i->total_production[fr->cargo != i->produced_cargo[0]] == 0) {
+ return false;
+ }
+ }
+
+ p->ai.route_type_mask |= bitmask;
+ return true;
+}
+
+static byte AiGetDirectionBetweenTiles(TileIndex a, TileIndex b)
+{
+ byte i = (TileX(a) < TileX(b)) ? 1 : 0;
+ if (TileY(a) >= TileY(b)) i ^= 3;
+ return i;
+}
+
+static TileIndex AiGetPctTileBetween(TileIndex a, TileIndex b, byte pct)
+{
+ return TileXY(
+ TileX(a) + ((TileX(b) - TileX(a)) * pct >> 8),
+ TileY(a) + ((TileY(b) - TileY(a)) * pct >> 8)
+ );
+}
+
+static void AiWantLongIndustryRoute(Player *p)
+{
+ int i;
+ FoundRoute fr;
+
+ i = 60;
+ for (;;) {
+ // look for one from the subsidy list
+ AiFindSubsidyIndustryRoute(&fr);
+ if (IS_INT_INSIDE(fr.distance, 60, 90 + 1)) break;
+
+ // try a random one
+ AiFindRandomIndustryRoute(&fr);
+ if (IS_INT_INSIDE(fr.distance, 60, 90 + 1)) break;
+
+ // only test 60 times
+ if (--i == 0) return;
+ }
+
+ if (!AiCheckIfRouteIsGood(p, &fr, 1)) return;
+
+ // Fill the source field
+ p->ai.dst.spec_tile = GET_TOWN_OR_INDUSTRY_TILE(fr.to);
+ p->ai.src.spec_tile = GET_TOWN_OR_INDUSTRY_TILE(fr.from);
+
+ p->ai.src.use_tile = 0;
+ p->ai.src.rand_rng = 9;
+ p->ai.src.cur_building_rule = 0xFF;
+ p->ai.src.unk6 = 1;
+ p->ai.src.unk7 = 0;
+ p->ai.src.buildcmd_a = 0x24;
+ p->ai.src.buildcmd_b = 0xFF;
+ p->ai.src.direction = AiGetDirectionBetweenTiles(
+ p->ai.src.spec_tile,
+ p->ai.dst.spec_tile
+ );
+ p->ai.src.cargo = fr.cargo | 0x80;
+
+ // Fill the dest field
+
+ p->ai.dst.use_tile = 0;
+ p->ai.dst.rand_rng = 9;
+ p->ai.dst.cur_building_rule = 0xFF;
+ p->ai.dst.unk6 = 1;
+ p->ai.dst.unk7 = 0;
+ p->ai.dst.buildcmd_a = 0x34;
+ p->ai.dst.buildcmd_b = 0xFF;
+ p->ai.dst.direction = AiGetDirectionBetweenTiles(
+ p->ai.dst.spec_tile,
+ p->ai.src.spec_tile
+ );
+ p->ai.dst.cargo = fr.cargo;
+
+ // Fill middle field 1
+ p->ai.mid1.spec_tile = AiGetPctTileBetween(
+ p->ai.src.spec_tile,
+ p->ai.dst.spec_tile,
+ 0x55
+ );
+ p->ai.mid1.use_tile = 0;
+ p->ai.mid1.rand_rng = 6;
+ p->ai.mid1.cur_building_rule = 0xFF;
+ p->ai.mid1.unk6 = 2;
+ p->ai.mid1.unk7 = 1;
+ p->ai.mid1.buildcmd_a = 0x30;
+ p->ai.mid1.buildcmd_b = 0xFF;
+ p->ai.mid1.direction = p->ai.src.direction;
+ p->ai.mid1.cargo = fr.cargo;
+
+ // Fill middle field 2
+ p->ai.mid2.spec_tile = AiGetPctTileBetween(
+ p->ai.src.spec_tile,
+ p->ai.dst.spec_tile,
+ 0xAA
+ );
+ p->ai.mid2.use_tile = 0;
+ p->ai.mid2.rand_rng = 6;
+ p->ai.mid2.cur_building_rule = 0xFF;
+ p->ai.mid2.unk6 = 2;
+ p->ai.mid2.unk7 = 1;
+ p->ai.mid2.buildcmd_a = 0xFF;
+ p->ai.mid2.buildcmd_b = 0xFF;
+ p->ai.mid2.direction = p->ai.dst.direction;
+ p->ai.mid2.cargo = fr.cargo;
+
+ // Fill common fields
+ p->ai.cargo_type = fr.cargo;
+ p->ai.num_wagons = 3;
+ p->ai.build_kind = 2;
+ p->ai.num_build_rec = 4;
+ p->ai.num_loco_to_build = 2;
+ p->ai.num_want_fullload = 2;
+ p->ai.wagon_list[0] = INVALID_VEHICLE;
+ p->ai.order_list_blocks[0] = 0;
+ p->ai.order_list_blocks[1] = 1;
+ p->ai.order_list_blocks[2] = 255;
+
+ p->ai.state = AIS_BUILD_DEFAULT_RAIL_BLOCKS;
+ p->ai.state_mode = -1;
+ p->ai.state_counter = 0;
+ p->ai.timeout_counter = 0;
+}
+
+static void AiWantMediumIndustryRoute(Player *p)
+{
+ int i;
+ FoundRoute fr;
+
+ i = 60;
+ for (;;) {
+ // look for one from the subsidy list
+ AiFindSubsidyIndustryRoute(&fr);
+ if (IS_INT_INSIDE(fr.distance, 40, 60 + 1)) break;
+
+ // try a random one
+ AiFindRandomIndustryRoute(&fr);
+ if (IS_INT_INSIDE(fr.distance, 40, 60 + 1)) break;
+
+ // only test 60 times
+ if (--i == 0) return;
+ }
+
+ if (!AiCheckIfRouteIsGood(p, &fr, 1)) return;
+
+ // Fill the source field
+ p->ai.src.spec_tile = GET_TOWN_OR_INDUSTRY_TILE(fr.from);
+ p->ai.src.use_tile = 0;
+ p->ai.src.rand_rng = 9;
+ p->ai.src.cur_building_rule = 0xFF;
+ p->ai.src.unk6 = 1;
+ p->ai.src.unk7 = 0;
+ p->ai.src.buildcmd_a = 0x10;
+ p->ai.src.buildcmd_b = 0xFF;
+ p->ai.src.direction = AiGetDirectionBetweenTiles(
+ GET_TOWN_OR_INDUSTRY_TILE(fr.from),
+ GET_TOWN_OR_INDUSTRY_TILE(fr.to)
+ );
+ p->ai.src.cargo = fr.cargo | 0x80;
+
+ // Fill the dest field
+ p->ai.dst.spec_tile = GET_TOWN_OR_INDUSTRY_TILE(fr.to);
+ p->ai.dst.use_tile = 0;
+ p->ai.dst.rand_rng = 9;
+ p->ai.dst.cur_building_rule = 0xFF;
+ p->ai.dst.unk6 = 1;
+ p->ai.dst.unk7 = 0;
+ p->ai.dst.buildcmd_a = 0xFF;
+ p->ai.dst.buildcmd_b = 0xFF;
+ p->ai.dst.direction = AiGetDirectionBetweenTiles(
+ GET_TOWN_OR_INDUSTRY_TILE(fr.to),
+ GET_TOWN_OR_INDUSTRY_TILE(fr.from)
+ );
+ p->ai.dst.cargo = fr.cargo;
+
+ // Fill common fields
+ p->ai.cargo_type = fr.cargo;
+ p->ai.num_wagons = 3;
+ p->ai.build_kind = 1;
+ p->ai.num_build_rec = 2;
+ p->ai.num_loco_to_build = 1;
+ p->ai.num_want_fullload = 1;
+ p->ai.wagon_list[0] = INVALID_VEHICLE;
+ p->ai.order_list_blocks[0] = 0;
+ p->ai.order_list_blocks[1] = 1;
+ p->ai.order_list_blocks[2] = 255;
+ p->ai.state = AIS_BUILD_DEFAULT_RAIL_BLOCKS;
+ p->ai.state_mode = -1;
+ p->ai.state_counter = 0;
+ p->ai.timeout_counter = 0;
+}
+
+static void AiWantShortIndustryRoute(Player *p)
+{
+ int i;
+ FoundRoute fr;
+
+ i = 60;
+ for (;;) {
+ // look for one from the subsidy list
+ AiFindSubsidyIndustryRoute(&fr);
+ if (IS_INT_INSIDE(fr.distance, 15, 40 + 1)) break;
+
+ // try a random one
+ AiFindRandomIndustryRoute(&fr);
+ if (IS_INT_INSIDE(fr.distance, 15, 40 + 1)) break;
+
+ // only test 60 times
+ if (--i == 0) return;
+ }
+
+ if (!AiCheckIfRouteIsGood(p, &fr, 1)) return;
+
+ // Fill the source field
+ p->ai.src.spec_tile = GET_TOWN_OR_INDUSTRY_TILE(fr.from);
+ p->ai.src.use_tile = 0;
+ p->ai.src.rand_rng = 9;
+ p->ai.src.cur_building_rule = 0xFF;
+ p->ai.src.unk6 = 1;
+ p->ai.src.unk7 = 0;
+ p->ai.src.buildcmd_a = 0x10;
+ p->ai.src.buildcmd_b = 0xFF;
+ p->ai.src.direction = AiGetDirectionBetweenTiles(
+ GET_TOWN_OR_INDUSTRY_TILE(fr.from),
+ GET_TOWN_OR_INDUSTRY_TILE(fr.to)
+ );
+ p->ai.src.cargo = fr.cargo | 0x80;
+
+ // Fill the dest field
+ p->ai.dst.spec_tile = GET_TOWN_OR_INDUSTRY_TILE(fr.to);
+ p->ai.dst.use_tile = 0;
+ p->ai.dst.rand_rng = 9;
+ p->ai.dst.cur_building_rule = 0xFF;
+ p->ai.dst.unk6 = 1;
+ p->ai.dst.unk7 = 0;
+ p->ai.dst.buildcmd_a = 0xFF;
+ p->ai.dst.buildcmd_b = 0xFF;
+ p->ai.dst.direction = AiGetDirectionBetweenTiles(
+ GET_TOWN_OR_INDUSTRY_TILE(fr.to),
+ GET_TOWN_OR_INDUSTRY_TILE(fr.from)
+ );
+ p->ai.dst.cargo = fr.cargo;
+
+ // Fill common fields
+ p->ai.cargo_type = fr.cargo;
+ p->ai.num_wagons = 2;
+ p->ai.build_kind = 1;
+ p->ai.num_build_rec = 2;
+ p->ai.num_loco_to_build = 1;
+ p->ai.num_want_fullload = 1;
+ p->ai.wagon_list[0] = INVALID_VEHICLE;
+ p->ai.order_list_blocks[0] = 0;
+ p->ai.order_list_blocks[1] = 1;
+ p->ai.order_list_blocks[2] = 255;
+ p->ai.state = AIS_BUILD_DEFAULT_RAIL_BLOCKS;
+ p->ai.state_mode = -1;
+ p->ai.state_counter = 0;
+ p->ai.timeout_counter = 0;
+}
+
+static void AiWantMailRoute(Player *p)
+{
+ int i;
+ FoundRoute fr;
+
+ i = 60;
+ for (;;) {
+ // look for one from the subsidy list
+ AiFindSubsidyPassengerRoute(&fr);
+ if (IS_INT_INSIDE(fr.distance, 60, 110 + 1)) break;
+
+ // try a random one
+ AiFindRandomPassengerRoute(&fr);
+ if (IS_INT_INSIDE(fr.distance, 60, 110 + 1)) break;
+
+ // only test 60 times
+ if (--i == 0) return;
+ }
+
+ fr.cargo = CT_MAIL;
+ if (!AiCheckIfRouteIsGood(p, &fr, 1)) return;
+
+ // Fill the source field
+ p->ai.src.spec_tile = GET_TOWN_OR_INDUSTRY_TILE(fr.from);
+ p->ai.src.use_tile = 0;
+ p->ai.src.rand_rng = 7;
+ p->ai.src.cur_building_rule = 0xFF;
+ p->ai.src.unk6 = 1;
+ p->ai.src.unk7 = 0;
+ p->ai.src.buildcmd_a = 0x24;
+ p->ai.src.buildcmd_b = 0xFF;
+ p->ai.src.direction = AiGetDirectionBetweenTiles(
+ GET_TOWN_OR_INDUSTRY_TILE(fr.from),
+ GET_TOWN_OR_INDUSTRY_TILE(fr.to)
+ );
+ p->ai.src.cargo = fr.cargo;
+
+ // Fill the dest field
+ p->ai.dst.spec_tile = GET_TOWN_OR_INDUSTRY_TILE(fr.to);
+ p->ai.dst.use_tile = 0;
+ p->ai.dst.rand_rng = 7;
+ p->ai.dst.cur_building_rule = 0xFF;
+ p->ai.dst.unk6 = 1;
+ p->ai.dst.unk7 = 0;
+ p->ai.dst.buildcmd_a = 0x34;
+ p->ai.dst.buildcmd_b = 0xFF;
+ p->ai.dst.direction = AiGetDirectionBetweenTiles(
+ GET_TOWN_OR_INDUSTRY_TILE(fr.to),
+ GET_TOWN_OR_INDUSTRY_TILE(fr.from)
+ );
+ p->ai.dst.cargo = fr.cargo;
+
+ // Fill middle field 1
+ p->ai.mid1.spec_tile = AiGetPctTileBetween(
+ GET_TOWN_OR_INDUSTRY_TILE(fr.from),
+ GET_TOWN_OR_INDUSTRY_TILE(fr.to),
+ 0x55
+ );
+ p->ai.mid1.use_tile = 0;
+ p->ai.mid1.rand_rng = 6;
+ p->ai.mid1.cur_building_rule = 0xFF;
+ p->ai.mid1.unk6 = 2;
+ p->ai.mid1.unk7 = 1;
+ p->ai.mid1.buildcmd_a = 0x30;
+ p->ai.mid1.buildcmd_b = 0xFF;
+ p->ai.mid1.direction = p->ai.src.direction;
+ p->ai.mid1.cargo = fr.cargo;
+
+ // Fill middle field 2
+ p->ai.mid2.spec_tile = AiGetPctTileBetween(
+ GET_TOWN_OR_INDUSTRY_TILE(fr.from),
+ GET_TOWN_OR_INDUSTRY_TILE(fr.to),
+ 0xAA
+ );
+ p->ai.mid2.use_tile = 0;
+ p->ai.mid2.rand_rng = 6;
+ p->ai.mid2.cur_building_rule = 0xFF;
+ p->ai.mid2.unk6 = 2;
+ p->ai.mid2.unk7 = 1;
+ p->ai.mid2.buildcmd_a = 0xFF;
+ p->ai.mid2.buildcmd_b = 0xFF;
+ p->ai.mid2.direction = p->ai.dst.direction;
+ p->ai.mid2.cargo = fr.cargo;
+
+ // Fill common fields
+ p->ai.cargo_type = fr.cargo;
+ p->ai.num_wagons = 3;
+ p->ai.build_kind = 2;
+ p->ai.num_build_rec = 4;
+ p->ai.num_loco_to_build = 2;
+ p->ai.num_want_fullload = 0;
+ p->ai.wagon_list[0] = INVALID_VEHICLE;
+ p->ai.order_list_blocks[0] = 0;
+ p->ai.order_list_blocks[1] = 1;
+ p->ai.order_list_blocks[2] = 255;
+ p->ai.state = AIS_BUILD_DEFAULT_RAIL_BLOCKS;
+ p->ai.state_mode = -1;
+ p->ai.state_counter = 0;
+ p->ai.timeout_counter = 0;
+}
+
+static void AiWantPassengerRoute(Player *p)
+{
+ int i;
+ FoundRoute fr;
+
+ i = 60;
+ for (;;) {
+ // look for one from the subsidy list
+ AiFindSubsidyPassengerRoute(&fr);
+ if (IS_INT_INSIDE(fr.distance, 0, 55 + 1)) break;
+
+ // try a random one
+ AiFindRandomPassengerRoute(&fr);
+ if (IS_INT_INSIDE(fr.distance, 0, 55 + 1)) break;
+
+ // only test 60 times
+ if (--i == 0) return;
+ }
+
+ fr.cargo = CT_PASSENGERS;
+ if (!AiCheckIfRouteIsGood(p, &fr, 1)) return;
+
+ // Fill the source field
+ p->ai.src.spec_tile = GET_TOWN_OR_INDUSTRY_TILE(fr.from);
+ p->ai.src.use_tile = 0;
+ p->ai.src.rand_rng = 7;
+ p->ai.src.cur_building_rule = 0xFF;
+ p->ai.src.unk6 = 1;
+ p->ai.src.unk7 = 0;
+ p->ai.src.buildcmd_a = 0x10;
+ p->ai.src.buildcmd_b = 0xFF;
+ p->ai.src.direction = AiGetDirectionBetweenTiles(
+ GET_TOWN_OR_INDUSTRY_TILE(fr.from),
+ GET_TOWN_OR_INDUSTRY_TILE(fr.to)
+ );
+ p->ai.src.cargo = fr.cargo;
+
+ // Fill the dest field
+ p->ai.dst.spec_tile = GET_TOWN_OR_INDUSTRY_TILE(fr.to);
+ p->ai.dst.use_tile = 0;
+ p->ai.dst.rand_rng = 7;
+ p->ai.dst.cur_building_rule = 0xFF;
+ p->ai.dst.unk6 = 1;
+ p->ai.dst.unk7 = 0;
+ p->ai.dst.buildcmd_a = 0xFF;
+ p->ai.dst.buildcmd_b = 0xFF;
+ p->ai.dst.direction = AiGetDirectionBetweenTiles(
+ GET_TOWN_OR_INDUSTRY_TILE(fr.to),
+ GET_TOWN_OR_INDUSTRY_TILE(fr.from)
+ );
+ p->ai.dst.cargo = fr.cargo;
+
+ // Fill common fields
+ p->ai.cargo_type = fr.cargo;
+ p->ai.num_wagons = 2;
+ p->ai.build_kind = 1;
+ p->ai.num_build_rec = 2;
+ p->ai.num_loco_to_build = 1;
+ p->ai.num_want_fullload = 0;
+ p->ai.wagon_list[0] = INVALID_VEHICLE;
+ p->ai.order_list_blocks[0] = 0;
+ p->ai.order_list_blocks[1] = 1;
+ p->ai.order_list_blocks[2] = 255;
+ p->ai.state = AIS_BUILD_DEFAULT_RAIL_BLOCKS;
+ p->ai.state_mode = -1;
+ p->ai.state_counter = 0;
+ p->ai.timeout_counter = 0;
+}
+
+static void AiWantTrainRoute(Player *p)
+{
+ uint16 r = GB(Random(), 0, 16);
+
+ p->ai.railtype_to_use = GetBestRailtype(p);
+
+ if (r > 0xD000) {
+ AiWantLongIndustryRoute(p);
+ } else if (r > 0x6000) {
+ AiWantMediumIndustryRoute(p);
+ } else if (r > 0x1000) {
+ AiWantShortIndustryRoute(p);
+ } else if (r > 0x800) {
+ AiWantPassengerRoute(p);
+ } else {
+ AiWantMailRoute(p);
+ }
+}
+
+static void AiWantLongRoadIndustryRoute(Player *p)
+{
+ int i;
+ FoundRoute fr;
+
+ i = 60;
+ for (;;) {
+ // look for one from the subsidy list
+ AiFindSubsidyIndustryRoute(&fr);
+ if (IS_INT_INSIDE(fr.distance, 35, 55 + 1)) break;
+
+ // try a random one
+ AiFindRandomIndustryRoute(&fr);
+ if (IS_INT_INSIDE(fr.distance, 35, 55 + 1)) break;
+
+ // only test 60 times
+ if (--i == 0) return;
+ }
+
+ if (!AiCheckIfRouteIsGood(p, &fr, 2)) return;
+
+ // Fill the source field
+ p->ai.src.spec_tile = GET_TOWN_OR_INDUSTRY_TILE(fr.from);
+ p->ai.src.use_tile = 0;
+ p->ai.src.rand_rng = 9;
+ p->ai.src.cur_building_rule = 0xFF;
+ p->ai.src.buildcmd_a = 1;
+ p->ai.src.direction = 0;
+ p->ai.src.cargo = fr.cargo | 0x80;
+
+ // Fill the dest field
+ p->ai.dst.spec_tile = GET_TOWN_OR_INDUSTRY_TILE(fr.to);
+ p->ai.dst.use_tile = 0;
+ p->ai.dst.rand_rng = 9;
+ p->ai.dst.cur_building_rule = 0xFF;
+ p->ai.dst.buildcmd_a = 0xFF;
+ p->ai.dst.direction = 0;
+ p->ai.dst.cargo = fr.cargo;
+
+ // Fill common fields
+ p->ai.cargo_type = fr.cargo;
+ p->ai.num_build_rec = 2;
+ p->ai.num_loco_to_build = 5;
+ p->ai.num_want_fullload = 5;
+
+// p->ai.loco_id = INVALID_VEHICLE;
+ p->ai.order_list_blocks[0] = 0;
+ p->ai.order_list_blocks[1] = 1;
+ p->ai.order_list_blocks[2] = 255;
+
+ p->ai.state = AIS_BUILD_DEFAULT_ROAD_BLOCKS;
+ p->ai.state_mode = -1;
+ p->ai.state_counter = 0;
+ p->ai.timeout_counter = 0;
+}
+
+static void AiWantMediumRoadIndustryRoute(Player *p)
+{
+ int i;
+ FoundRoute fr;
+
+ i = 60;
+ for (;;) {
+ // look for one from the subsidy list
+ AiFindSubsidyIndustryRoute(&fr);
+ if (IS_INT_INSIDE(fr.distance, 15, 40 + 1)) break;
+
+ // try a random one
+ AiFindRandomIndustryRoute(&fr);
+ if (IS_INT_INSIDE(fr.distance, 15, 40 + 1)) break;
+
+ // only test 60 times
+ if (--i == 0) return;
+ }
+
+ if (!AiCheckIfRouteIsGood(p, &fr, 2)) return;
+
+ // Fill the source field
+ p->ai.src.spec_tile = GET_TOWN_OR_INDUSTRY_TILE(fr.from);
+ p->ai.src.use_tile = 0;
+ p->ai.src.rand_rng = 9;
+ p->ai.src.cur_building_rule = 0xFF;
+ p->ai.src.buildcmd_a = 1;
+ p->ai.src.direction = 0;
+ p->ai.src.cargo = fr.cargo | 0x80;
+
+ // Fill the dest field
+ p->ai.dst.spec_tile = GET_TOWN_OR_INDUSTRY_TILE(fr.to);
+ p->ai.dst.use_tile = 0;
+ p->ai.dst.rand_rng = 9;
+ p->ai.dst.cur_building_rule = 0xFF;
+ p->ai.dst.buildcmd_a = 0xFF;
+ p->ai.dst.direction = 0;
+ p->ai.dst.cargo = fr.cargo;
+
+ // Fill common fields
+ p->ai.cargo_type = fr.cargo;
+ p->ai.num_build_rec = 2;
+ p->ai.num_loco_to_build = 3;
+ p->ai.num_want_fullload = 3;
+
+// p->ai.loco_id = INVALID_VEHICLE;
+ p->ai.order_list_blocks[0] = 0;
+ p->ai.order_list_blocks[1] = 1;
+ p->ai.order_list_blocks[2] = 255;
+
+ p->ai.state = AIS_BUILD_DEFAULT_ROAD_BLOCKS;
+ p->ai.state_mode = -1;
+ p->ai.state_counter = 0;
+ p->ai.timeout_counter = 0;
+}
+
+static void AiWantLongRoadPassengerRoute(Player *p)
+{
+ int i;
+ FoundRoute fr;
+
+ i = 60;
+ for (;;) {
+ // look for one from the subsidy list
+ AiFindSubsidyPassengerRoute(&fr);
+ if (IS_INT_INSIDE(fr.distance, 55, 180 + 1)) break;
+
+ // try a random one
+ AiFindRandomPassengerRoute(&fr);
+ if (IS_INT_INSIDE(fr.distance, 55, 180 + 1)) break;
+
+ // only test 60 times
+ if (--i == 0) return;
+ }
+
+ fr.cargo = CT_PASSENGERS;
+
+ if (!AiCheckIfRouteIsGood(p, &fr, 2)) return;
+
+ // Fill the source field
+ p->ai.src.spec_tile = GET_TOWN_OR_INDUSTRY_TILE(fr.to);
+ p->ai.src.use_tile = 0;
+ p->ai.src.rand_rng = 10;
+ p->ai.src.cur_building_rule = 0xFF;
+ p->ai.src.buildcmd_a = 1;
+ p->ai.src.direction = 0;
+ p->ai.src.cargo = CT_PASSENGERS;
+
+ // Fill the dest field
+ p->ai.dst.spec_tile = GET_TOWN_OR_INDUSTRY_TILE(fr.from);
+ p->ai.dst.use_tile = 0;
+ p->ai.dst.rand_rng = 10;
+ p->ai.dst.cur_building_rule = 0xFF;
+ p->ai.dst.buildcmd_a = 0xFF;
+ p->ai.dst.direction = 0;
+ p->ai.dst.cargo = CT_PASSENGERS;
+
+ // Fill common fields
+ p->ai.cargo_type = CT_PASSENGERS;
+ p->ai.num_build_rec = 2;
+ p->ai.num_loco_to_build = 4;
+ p->ai.num_want_fullload = 0;
+
+// p->ai.loco_id = INVALID_VEHICLE;
+ p->ai.order_list_blocks[0] = 0;
+ p->ai.order_list_blocks[1] = 1;
+ p->ai.order_list_blocks[2] = 255;
+
+ p->ai.state = AIS_BUILD_DEFAULT_ROAD_BLOCKS;
+ p->ai.state_mode = -1;
+ p->ai.state_counter = 0;
+ p->ai.timeout_counter = 0;
+}
+
+static void AiWantPassengerRouteInsideTown(Player *p)
+{
+ int i;
+ FoundRoute fr;
+ Town *t;
+
+ i = 60;
+ for (;;) {
+ // Find a town big enough
+ t = AiFindRandomTown();
+ if (t != NULL && t->population >= 700) break;
+
+ // only test 60 times
+ if (--i == 0) return;
+ }
+
+ fr.cargo = CT_PASSENGERS;
+ fr.from = fr.to = t;
+
+ if (!AiCheckIfRouteIsGood(p, &fr, 2)) return;
+
+ // Fill the source field
+ p->ai.src.spec_tile = t->xy;
+ p->ai.src.use_tile = 0;
+ p->ai.src.rand_rng = 10;
+ p->ai.src.cur_building_rule = 0xFF;
+ p->ai.src.buildcmd_a = 1;
+ p->ai.src.direction = 0;
+ p->ai.src.cargo = CT_PASSENGERS;
+
+ // Fill the dest field
+ p->ai.dst.spec_tile = t->xy;
+ p->ai.dst.use_tile = 0;
+ p->ai.dst.rand_rng = 10;
+ p->ai.dst.cur_building_rule = 0xFF;
+ p->ai.dst.buildcmd_a = 0xFF;
+ p->ai.dst.direction = 0;
+ p->ai.dst.cargo = CT_PASSENGERS;
+
+ // Fill common fields
+ p->ai.cargo_type = CT_PASSENGERS;
+ p->ai.num_build_rec = 2;
+ p->ai.num_loco_to_build = 2;
+ p->ai.num_want_fullload = 0;
+
+// p->ai.loco_id = INVALID_VEHICLE;
+ p->ai.order_list_blocks[0] = 0;
+ p->ai.order_list_blocks[1] = 1;
+ p->ai.order_list_blocks[2] = 255;
+
+ p->ai.state = AIS_BUILD_DEFAULT_ROAD_BLOCKS;
+ p->ai.state_mode = -1;
+ p->ai.state_counter = 0;
+ p->ai.timeout_counter = 0;
+}
+
+static void AiWantRoadRoute(Player *p)
+{
+ uint16 r = GB(Random(), 0, 16);
+
+ if (r > 0x4000) {
+ AiWantLongRoadIndustryRoute(p);
+ } else if (r > 0x2000) {
+ AiWantMediumRoadIndustryRoute(p);
+ } else if (r > 0x1000) {
+ AiWantLongRoadPassengerRoute(p);
+ } else {
+ AiWantPassengerRouteInsideTown(p);
+ }
+}
+
+static void AiWantPassengerAircraftRoute(Player *p)
+{
+ FoundRoute fr;
+ int i;
+
+ i = 60;
+ for (;;) {
+ // look for one from the subsidy list
+ AiFindSubsidyPassengerRoute(&fr);
+ if (IS_INT_INSIDE(fr.distance, 0, 95 + 1)) break;
+
+ // try a random one
+ AiFindRandomPassengerRoute(&fr);
+ if (IS_INT_INSIDE(fr.distance, 0, 95 + 1)) break;
+
+ // only test 60 times
+ if (--i == 0) return;
+ }
+
+ fr.cargo = CT_PASSENGERS;
+ if (!AiCheckIfRouteIsGood(p, &fr, 4)) return;
+
+
+ // Fill the source field
+ p->ai.src.spec_tile = GET_TOWN_OR_INDUSTRY_TILE(fr.to);
+ p->ai.src.use_tile = 0;
+ p->ai.src.rand_rng = 12;
+ p->ai.src.cur_building_rule = 0xFF;
+ p->ai.src.cargo = fr.cargo;
+
+ // Fill the dest field
+ p->ai.dst.spec_tile = GET_TOWN_OR_INDUSTRY_TILE(fr.from);
+ p->ai.dst.use_tile = 0;
+ p->ai.dst.rand_rng = 12;
+ p->ai.dst.cur_building_rule = 0xFF;
+ p->ai.dst.cargo = fr.cargo;
+
+ // Fill common fields
+ p->ai.cargo_type = fr.cargo;
+ p->ai.build_kind = 0;
+ p->ai.num_build_rec = 2;
+ p->ai.num_loco_to_build = 1;
+ p->ai.num_want_fullload = 1;
+// p->ai.loco_id = INVALID_VEHICLE;
+ p->ai.order_list_blocks[0] = 0;
+ p->ai.order_list_blocks[1] = 1;
+ p->ai.order_list_blocks[2] = 255;
+
+ p->ai.state = AIS_AIRPORT_STUFF;
+ p->ai.timeout_counter = 0;
+}
+
+static void AiWantOilRigAircraftRoute(Player *p)
+{
+ int i;
+ FoundRoute fr;
+ Town *t;
+ Industry *in;
+
+ i = 60;
+ for (;;) {
+ // Find a town
+ t = AiFindRandomTown();
+ if (t != NULL) {
+ // Find a random oil rig industry
+ in = AiFindRandomIndustry();
+ if (in != NULL && in->type == IT_OIL_RIG) {
+ if (DistanceManhattan(t->xy, in->xy) < 60)
+ break;
+ }
+ }
+
+ // only test 60 times
+ if (--i == 0) return;
+ }
+
+ fr.cargo = CT_PASSENGERS;
+ fr.from = fr.to = t;
+
+ if (!AiCheckIfRouteIsGood(p, &fr, 4)) return;
+
+ // Fill the source field
+ p->ai.src.spec_tile = t->xy;
+ p->ai.src.use_tile = 0;
+ p->ai.src.rand_rng = 12;
+ p->ai.src.cur_building_rule = 0xFF;
+ p->ai.src.cargo = CT_PASSENGERS;
+
+ // Fill the dest field
+ p->ai.dst.spec_tile = in->xy;
+ p->ai.dst.use_tile = 0;
+ p->ai.dst.rand_rng = 5;
+ p->ai.dst.cur_building_rule = 0xFF;
+ p->ai.dst.cargo = CT_PASSENGERS;
+
+ // Fill common fields
+ p->ai.cargo_type = CT_PASSENGERS;
+ p->ai.build_kind = 1;
+ p->ai.num_build_rec = 2;
+ p->ai.num_loco_to_build = 1;
+ p->ai.num_want_fullload = 0;
+// p->ai.loco_id = INVALID_VEHICLE;
+ p->ai.order_list_blocks[0] = 0;
+ p->ai.order_list_blocks[1] = 1;
+ p->ai.order_list_blocks[2] = 255;
+
+ p->ai.state = AIS_AIRPORT_STUFF;
+ p->ai.timeout_counter = 0;
+}
+
+static void AiWantAircraftRoute(Player *p)
+{
+ uint16 r = (uint16)Random();
+
+ if (r >= 0x2AAA || _date < 0x3912 + DAYS_TILL_ORIGINAL_BASE_YEAR) {
+ AiWantPassengerAircraftRoute(p);
+ } else {
+ AiWantOilRigAircraftRoute(p);
+ }
+}
+
+static void AiWantShipRoute(Player *p)
+{
+ // XXX
+// error("AiWaitShipRoute");
+}
+
+
+
+static void AiStateWantNewRoute(Player *p)
+{
+ uint16 r;
+ int i;
+
+ if (p->player_money < AiGetBasePrice(p) * 500) {
+ p->ai.state = AIS_0;
+ return;
+ }
+
+ i = 200;
+ for (;;) {
+ r = (uint16)Random();
+
+ if (_patches.ai_disable_veh_train &&
+ _patches.ai_disable_veh_roadveh &&
+ _patches.ai_disable_veh_aircraft &&
+ _patches.ai_disable_veh_ship) {
+ return;
+ }
+
+ if (r < 0x7626) {
+ if (_patches.ai_disable_veh_train) continue;
+ AiWantTrainRoute(p);
+ } else if (r < 0xC4EA) {
+ if (_patches.ai_disable_veh_roadveh) continue;
+ AiWantRoadRoute(p);
+ } else if (r < 0xD89B) {
+ if (_patches.ai_disable_veh_aircraft) continue;
+ AiWantAircraftRoute(p);
+ } else {
+ if (_patches.ai_disable_veh_ship) continue;
+ AiWantShipRoute(p);
+ }
+
+ // got a route?
+ if (p->ai.state != AIS_WANT_NEW_ROUTE) break;
+
+ // time out?
+ if (--i == 0) {
+ if (++p->ai.state_counter == 556) p->ai.state = AIS_0;
+ break;
+ }
+ }
+}
+
+static bool AiCheckTrackResources(TileIndex tile, const AiDefaultBlockData *p, byte cargo)
+{
+ uint rad = (_patches.modified_catchment) ? CA_TRAIN : 4;
+
+ for (; p->mode != 4; p++) {
+ AcceptedCargo values;
+ TileIndex tile2;
+ uint w;
+ uint h;
+
+ if (p->mode != 1) continue;
+
+ tile2 = TILE_ADD(tile, ToTileIndexDiff(p->tileoffs));
+ w = GB(p->attr, 1, 3);
+ h = GB(p->attr, 4, 3);
+
+ if (p->attr & 1) uintswap(w, h);
+
+ if (cargo & 0x80) {
+ GetProductionAroundTiles(values, tile2, w, h, rad);
+ return values[cargo & 0x7F] != 0;
+ } else {
+ GetAcceptanceAroundTiles(values, tile2, w, h, rad);
+ if (!(values[cargo] & ~7))
+ return false;
+ if (cargo != CT_MAIL)
+ return true;
+ return !!((values[cargo]>>1) & ~7);
+ }
+ }
+
+ return true;
+}
+
+static int32 AiDoBuildDefaultRailTrack(TileIndex tile, const AiDefaultBlockData* p, RailType railtype, byte flag)
+{
+ int32 ret;
+ int32 total_cost = 0;
+ Town *t = NULL;
+ int rating = 0;
+ int i,j,k;
+
+ for (;;) {
+ // This will seldomly overflow for valid reasons. Mask it to be on the safe side.
+ uint c = TILE_MASK(tile + ToTileIndexDiff(p->tileoffs));
+
+ _cleared_town = NULL;
+
+ if (p->mode < 2) {
+ if (p->mode == 0) {
+ // Depot
+ ret = DoCommand(c, railtype, p->attr, flag | DC_AUTO | DC_NO_WATER | DC_AI_BUILDING, CMD_BUILD_TRAIN_DEPOT);
+ } else {
+ // Station
+ ret = DoCommand(c, (p->attr&1) | (p->attr>>4)<<8 | (p->attr>>1&7)<<16, railtype, flag | DC_AUTO | DC_NO_WATER | DC_AI_BUILDING, CMD_BUILD_RAILROAD_STATION);
+ }
+
+ if (CmdFailed(ret)) return CMD_ERROR;
+ total_cost += ret;
+
+clear_town_stuff:;
+ if (_cleared_town != NULL) {
+ if (t != NULL && t != _cleared_town)
+ return CMD_ERROR;
+ t = _cleared_town;
+ rating += _cleared_town_rating;
+ }
+ } else if (p->mode == 2) {
+ // Rail
+ if (IsTileType(c, MP_RAILWAY)) return CMD_ERROR;
+
+ j = p->attr;
+ k = 0;
+
+ // Build the rail
+ for (i = 0; i != 6; i++, j >>= 1) {
+ if (j&1) {
+ k = i;
+ ret = DoCommand(c, railtype, i, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_SINGLE_RAIL);
+ if (CmdFailed(ret)) return CMD_ERROR;
+ total_cost += ret;
+ }
+ }
+
+ /* signals too? */
+ if (j & 3) {
+ // Can't build signals on a road.
+ if (IsTileType(c, MP_STREET)) return CMD_ERROR;
+
+ if (flag & DC_EXEC) {
+ j = 4 - j;
+ do {
+ ret = DoCommand(c, k, 0, flag, CMD_BUILD_SIGNALS);
+ } while (--j);
+ } else {
+ ret = _price.build_signals;
+ }
+ if (CmdFailed(ret)) return CMD_ERROR;
+ total_cost += ret;
+ }
+ } else if (p->mode == 3) {
+ //Clear stuff and then build single rail.
+ if (GetTileSlope(c, NULL) != SLOPE_FLAT) return CMD_ERROR;
+ ret = DoCommand(c, 0, 0, flag | DC_AUTO | DC_NO_WATER | DC_AI_BUILDING, CMD_LANDSCAPE_CLEAR);
+ if (CmdFailed(ret)) return CMD_ERROR;
+ total_cost += ret + _price.build_rail;
+
+ if (flag & DC_EXEC) {
+ DoCommand(c, railtype, p->attr&1, flag | DC_AUTO | DC_NO_WATER | DC_AI_BUILDING, CMD_BUILD_SINGLE_RAIL);
+ }
+
+ goto clear_town_stuff;
+ } else {
+ // Unk
+ break;
+ }
+
+ p++;
+ }
+
+ if (!(flag & DC_EXEC)) {
+ if (t != NULL && rating > t->ratings[_current_player]) {
+ return CMD_ERROR;
+ }
+ }
+
+ return total_cost;
+}
+
+// Returns rule and cost
+static int AiBuildDefaultRailTrack(TileIndex tile, byte p0, byte p1, byte p2, byte p3, byte dir, byte cargo, RailType railtype, int32* cost)
+{
+ int i;
+ const AiDefaultRailBlock *p;
+
+ for (i = 0; (p = _default_rail_track_data[i]) != NULL; i++) {
+ if (p->p0 == p0 && p->p1 == p1 && p->p2 == p2 && p->p3 == p3 &&
+ (p->dir == 0xFF || p->dir == dir || ((p->dir - 1) & 3) == dir)) {
+ *cost = AiDoBuildDefaultRailTrack(tile, p->data, railtype, DC_NO_TOWN_RATING);
+ if (!CmdFailed(*cost) && AiCheckTrackResources(tile, p->data, cargo))
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+static const byte _terraform_up_flags[] = {
+ 14, 13, 12, 11,
+ 10, 9, 8, 7,
+ 6, 5, 4, 3,
+ 2, 1, 0, 1,
+ 2, 1, 4, 1,
+ 2, 1, 8, 1,
+ 2, 1, 4, 2,
+ 2, 1
+};
+
+static const byte _terraform_down_flags[] = {
+ 1, 2, 3, 4,
+ 5, 6, 1, 8,
+ 9, 10, 8, 12,
+ 4, 2, 0, 0,
+ 1, 2, 3, 4,
+ 5, 6, 2, 8,
+ 9, 10, 1, 12,
+ 8, 4
+};
+
+static void AiDoTerraformLand(TileIndex tile, int dir, int unk, int mode)
+{
+ PlayerID old_player;
+ uint32 r;
+ Slope slope;
+ uint h;
+
+ old_player = _current_player;
+ _current_player = OWNER_NONE;
+
+ r = Random();
+
+ unk &= (int)r;
+
+ do {
+ tile = TILE_MASK(tile + TileOffsByDiagDir(dir));
+
+ r >>= 2;
+ if (r & 2) {
+ dir++;
+ if (r & 1) dir -= 2;
+ }
+ dir &= 3;
+ } while (--unk >= 0);
+
+ slope = GetTileSlope(tile, &h);
+
+ if (slope != SLOPE_FLAT) {
+ if (mode > 0 || (mode == 0 && !(r & 0xC))) {
+ // Terraform up
+ DoCommand(tile, _terraform_up_flags[slope - 1], 1,
+ DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_TERRAFORM_LAND);
+ } else if (h != 0) {
+ // Terraform down
+ DoCommand(tile, _terraform_down_flags[slope - 1], 0,
+ DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_TERRAFORM_LAND);
+ }
+ }
+
+ _current_player = old_player;
+}
+
+static void AiStateBuildDefaultRailBlocks(Player *p)
+{
+ uint i;
+ int j;
+ AiBuildRec *aib;
+ int rule;
+ int32 cost;
+
+ // time out?
+ if (++p->ai.timeout_counter == 1388) {
+ p->ai.state = AIS_DELETE_RAIL_BLOCKS;
+ return;
+ }
+
+ // do the following 8 times
+ for (i = 0; i < 8; i++) {
+ // check if we can build the default track
+ aib = &p->ai.src;
+ j = p->ai.num_build_rec;
+ do {
+ // this item has already been built?
+ if (aib->cur_building_rule != 255) continue;
+
+ // adjust the coordinate randomly,
+ // to make sure that we find a position.
+ aib->use_tile = AdjustTileCoordRandomly(aib->spec_tile, aib->rand_rng);
+
+ // check if the track can be build there.
+ rule = AiBuildDefaultRailTrack(aib->use_tile,
+ p->ai.build_kind, p->ai.num_wagons,
+ aib->unk6, aib->unk7,
+ aib->direction, aib->cargo,
+ p->ai.railtype_to_use,
+ &cost
+ );
+
+ if (rule == -1) {
+ // cannot build, terraform after a while
+ if (p->ai.state_counter >= 600) {
+ AiDoTerraformLand(aib->use_tile, Random()&3, 3, (int8)p->ai.state_mode);
+ }
+ // also try the other terraform direction
+ if (++p->ai.state_counter >= 1000) {
+ p->ai.state_counter = 0;
+ p->ai.state_mode = -p->ai.state_mode;
+ }
+ } else if (CheckPlayerHasMoney(cost)) {
+ int32 r;
+ // player has money, build it.
+ aib->cur_building_rule = rule;
+
+ r = AiDoBuildDefaultRailTrack(
+ aib->use_tile,
+ _default_rail_track_data[rule]->data,
+ p->ai.railtype_to_use,
+ DC_EXEC | DC_NO_TOWN_RATING
+ );
+ assert(!CmdFailed(r));
+ }
+ } while (++aib,--j);
+ }
+
+ // check if we're done with all of them
+ aib = &p->ai.src;
+ j = p->ai.num_build_rec;
+ do {
+ if (aib->cur_building_rule == 255) return;
+ } while (++aib,--j);
+
+ // yep, all are done. switch state to the rail building state.
+ p->ai.state = AIS_BUILD_RAIL;
+ p->ai.state_mode = 255;
+}
+
+static TileIndex AiGetEdgeOfDefaultRailBlock(byte rule, TileIndex tile, byte cmd, int *dir)
+{
+ const AiDefaultBlockData *p = _default_rail_track_data[rule]->data;
+
+ while (p->mode != 3 || !((--cmd) & 0x80)) p++;
+
+ return tile + ToTileIndexDiff(p->tileoffs) - TileOffsByDiagDir(*dir = p->attr);
+}
+
+typedef struct AiRailPathFindData {
+ TileIndex tile;
+ TileIndex tile2;
+ int count;
+ bool flag;
+} AiRailPathFindData;
+
+static bool AiEnumFollowTrack(TileIndex tile, AiRailPathFindData *a, int track, uint length, byte *state)
+{
+ if (a->flag) return true;
+
+ if (length > 20 || tile == a->tile) {
+ a->flag = true;
+ return true;
+ }
+
+ if (DistanceMax(tile, a->tile2) < 4) a->count++;
+
+ return false;
+}
+
+static bool AiDoFollowTrack(const Player* p)
+{
+ AiRailPathFindData arpfd;
+
+ arpfd.tile = p->ai.start_tile_a;
+ arpfd.tile2 = p->ai.cur_tile_a;
+ arpfd.flag = false;
+ arpfd.count = 0;
+ FollowTrack(p->ai.cur_tile_a + TileOffsByDiagDir(p->ai.cur_dir_a), 0x2000 | TRANSPORT_RAIL, p->ai.cur_dir_a^2,
+ (TPFEnumProc*)AiEnumFollowTrack, NULL, &arpfd);
+ return arpfd.count > 8;
+}
+
+typedef struct AiRailFinder {
+ TileIndex final_tile;
+ byte final_dir;
+ byte depth;
+ byte recursive_mode;
+ byte cur_best_dir;
+ byte best_dir;
+ byte cur_best_depth;
+ byte best_depth;
+ uint cur_best_dist;
+ const byte *best_ptr;
+ uint best_dist;
+ TileIndex cur_best_tile, best_tile;
+ TileIndex bridge_end_tile;
+ Player *player;
+} AiRailFinder;
+
+static const byte _ai_table_15[4][8] = {
+ {0, 0, 4, 3, 3, 1, 128 + 0, 64},
+ {1, 1, 2, 0, 4, 2, 128 + 1, 65},
+ {0, 2, 2, 3, 5, 1, 128 + 2, 66},
+ {1, 3, 5, 0, 3, 2, 128 + 3, 67}
+};
+
+static const byte _dir_table_1[] = { 3, 9, 12, 6};
+static const byte _dir_table_2[] = {12, 6, 3, 9};
+
+
+static bool AiIsTileBanned(const Player* p, TileIndex tile, byte val)
+{
+ int i;
+
+ for (i = 0; i != p->ai.banned_tile_count; i++) {
+ if (p->ai.banned_tiles[i] == tile && p->ai.banned_val[i] == val) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static void AiBanTile(Player* p, TileIndex tile, byte val)
+{
+ uint i;
+
+ for (i = lengthof(p->ai.banned_tiles) - 1; i != 0; i--) {
+ p->ai.banned_tiles[i] = p->ai.banned_tiles[i - 1];
+ p->ai.banned_val[i] = p->ai.banned_val[i - 1];
+ }
+
+ p->ai.banned_tiles[0] = tile;
+ p->ai.banned_val[0] = val;
+
+ if (p->ai.banned_tile_count != lengthof(p->ai.banned_tiles)) {
+ p->ai.banned_tile_count++;
+ }
+}
+
+static void AiBuildRailRecursive(AiRailFinder *arf, TileIndex tile, int dir);
+
+static bool AiCheckRailPathBetter(AiRailFinder *arf, const byte *p)
+{
+ bool better = false;
+
+ if (arf->recursive_mode < 1) {
+ // Mode is 0. This means destination has not been found yet.
+ // If the found path is shorter than the current one, remember it.
+ if (arf->cur_best_dist < arf->best_dist) {
+ arf->best_dir = arf->cur_best_dir;
+ arf->best_dist = arf->cur_best_dist;
+ arf->best_ptr = p;
+ arf->best_tile = arf->cur_best_tile;
+ better = true;
+ }
+ } else if (arf->recursive_mode > 1) {
+ // Mode is 2.
+ if (arf->best_dist != 0 || arf->cur_best_depth < arf->best_depth) {
+ arf->best_depth = arf->cur_best_depth;
+ arf->best_dist = 0;
+ arf->best_ptr = p;
+ arf->best_tile = 0;
+ better = true;
+ }
+ }
+ arf->recursive_mode = 0;
+ arf->cur_best_dist = (uint)-1;
+ arf->cur_best_depth = 0xff;
+
+ return better;
+}
+
+static inline void AiCheckBuildRailBridgeHere(AiRailFinder *arf, TileIndex tile, const byte *p)
+{
+ Slope tileh;
+ uint z;
+ bool flag;
+
+ int dir2 = p[0] & 3;
+
+ tileh = GetTileSlope(tile, &z);
+ if (tileh == _dir_table_1[dir2] || (tileh == SLOPE_FLAT && z != 0)) {
+ TileIndex tile_new = tile;
+
+ // Allow bridges directly over bottom tiles
+ flag = z == 0;
+ for (;;) {
+ TileType type;
+
+ if ((TileIndexDiff)tile_new < -TileOffsByDiagDir(dir2)) return; // Wraping around map, no bridge possible!
+ tile_new = TILE_MASK(tile_new + TileOffsByDiagDir(dir2));
+ type = GetTileType(tile_new);
+
+ if (type == MP_CLEAR || type == MP_TREES || GetTileSlope(tile_new, NULL) != SLOPE_FLAT) {
+ if (!flag) return;
+ break;
+ }
+ if (type != MP_WATER && type != MP_RAILWAY && type != MP_STREET) return;
+ flag = true;
+ }
+
+ // Is building a (rail)bridge possible at this place (type doesn't matter)?
+ if (CmdFailed(DoCommand(tile_new, tile, 0 | arf->player->ai.railtype_to_use << 8, DC_AUTO, CMD_BUILD_BRIDGE))) {
+ return;
+ }
+ AiBuildRailRecursive(arf, tile_new, dir2);
+
+ // At the bottom depth, check if the new path is better than the old one.
+ if (arf->depth == 1) {
+ if (AiCheckRailPathBetter(arf, p)) arf->bridge_end_tile = tile_new;
+ }
+ }
+}
+
+static inline void AiCheckBuildRailTunnelHere(AiRailFinder *arf, TileIndex tile, const byte *p)
+{
+ uint z;
+
+ if (GetTileSlope(tile, &z) == _dir_table_2[p[0] & 3] && z != 0) {
+ int32 cost = DoCommand(tile, arf->player->ai.railtype_to_use, 0, DC_AUTO, CMD_BUILD_TUNNEL);
+
+ if (!CmdFailed(cost) && cost <= (arf->player->player_money>>4)) {
+ AiBuildRailRecursive(arf, _build_tunnel_endtile, p[0]&3);
+ if (arf->depth == 1) AiCheckRailPathBetter(arf, p);
+ }
+ }
+}
+
+
+static void AiBuildRailRecursive(AiRailFinder *arf, TileIndex tile, int dir)
+{
+ const byte *p;
+
+ tile = TILE_MASK(tile + TileOffsByDiagDir(dir));
+
+ // Reached destination?
+ if (tile == arf->final_tile) {
+ if (arf->final_dir != (dir^2)) {
+ if (arf->recursive_mode != 2) arf->recursive_mode = 1;
+ } else if (arf->recursive_mode != 2) {
+ arf->recursive_mode = 2;
+ arf->cur_best_depth = arf->depth;
+ } else {
+ if (arf->depth < arf->cur_best_depth) arf->cur_best_depth = arf->depth;
+ }
+ return;
+ }
+
+ // Depth too deep?
+ if (arf->depth >= 4) {
+ uint dist = DistanceMaxPlusManhattan(tile, arf->final_tile);
+
+ if (dist < arf->cur_best_dist) {
+ // Store the tile that is closest to the final position.
+ arf->cur_best_depth = arf->depth;
+ arf->cur_best_dist = dist;
+ arf->cur_best_tile = tile;
+ arf->cur_best_dir = dir;
+ }
+ return;
+ }
+
+ // Increase recursion depth
+ arf->depth++;
+
+ // Grab pointer to list of stuff that is possible to build
+ p = _ai_table_15[dir];
+
+ // Try to build a single rail in all directions.
+ if (GetTileZ(tile) == 0) {
+ p += 6;
+ } else {
+ do {
+ // Make sure the tile is not in the list of banned tiles and that a rail can be built here.
+ if (!AiIsTileBanned(arf->player, tile, p[0]) &&
+ !CmdFailed(DoCommand(tile, arf->player->ai.railtype_to_use, p[0], DC_AUTO | DC_NO_WATER | DC_NO_RAIL_OVERLAP, CMD_BUILD_SINGLE_RAIL))) {
+ AiBuildRailRecursive(arf, tile, p[1]);
+ }
+
+ // At the bottom depth?
+ if (arf->depth == 1) AiCheckRailPathBetter(arf, p);
+
+ p += 2;
+ } while (!(p[0]&0x80));
+ }
+
+ AiCheckBuildRailBridgeHere(arf, tile, p);
+ AiCheckBuildRailTunnelHere(arf, tile, p+1);
+
+ arf->depth--;
+}
+
+
+static const byte _dir_table_3[]= {0x25, 0x2A, 0x19, 0x16};
+
+static void AiBuildRailConstruct(Player *p)
+{
+ AiRailFinder arf;
+ int i;
+
+ // Check too much lookahead?
+ if (AiDoFollowTrack(p)) {
+ p->ai.state_counter = (Random()&0xE)+6; // Destruct this amount of blocks
+ p->ai.state_mode = 1; // Start destruct
+
+ // Ban this tile and don't reach it for a while.
+ AiBanTile(p, p->ai.cur_tile_a, FindFirstBit(GetRailTrackStatus(p->ai.cur_tile_a)));
+ return;
+ }
+
+ // Setup recursive finder and call it.
+ arf.player = p;
+ arf.final_tile = p->ai.cur_tile_b;
+ arf.final_dir = p->ai.cur_dir_b;
+ arf.depth = 0;
+ arf.recursive_mode = 0;
+ arf.best_ptr = NULL;
+ arf.cur_best_dist = (uint)-1;
+ arf.cur_best_depth = 0xff;
+ arf.best_dist = (uint)-1;
+ arf.best_depth = 0xff;
+ arf.cur_best_tile = 0;
+ arf.best_tile = 0;
+ AiBuildRailRecursive(&arf, p->ai.cur_tile_a, p->ai.cur_dir_a);
+
+ // Reached destination?
+ if (arf.recursive_mode == 2 && arf.cur_best_depth == 0) {
+ p->ai.state_mode = 255;
+ return;
+ }
+
+ // Didn't find anything to build?
+ if (arf.best_ptr == NULL) {
+ // Terraform some
+ for (i = 0; i != 5; i++) {
+ AiDoTerraformLand(p->ai.cur_tile_a, p->ai.cur_dir_a, 3, 0);
+ }
+
+ if (++p->ai.state_counter == 21) {
+ p->ai.state_counter = 40;
+ p->ai.state_mode = 1;
+
+ // Ban this tile
+ AiBanTile(p, p->ai.cur_tile_a, FindFirstBit(GetRailTrackStatus(p->ai.cur_tile_a)));
+ }
+ return;
+ }
+
+ p->ai.cur_tile_a += TileOffsByDiagDir(p->ai.cur_dir_a);
+
+ if (arf.best_ptr[0] & 0x80) {
+ int i;
+ int32 bridge_len = GetBridgeLength(arf.bridge_end_tile, p->ai.cur_tile_a);
+
+ /* Figure out which (rail)bridge type to build
+ * start with best bridge, then go down to worse and worse bridges
+ * unnecessary to check for worst bridge (i=0), since AI will always build
+ * that. AI is so fucked up that fixing this small thing will probably not
+ * solve a thing
+ */
+ for (i = MAX_BRIDGES - 1; i != 0; i--) {
+ if (CheckBridge_Stuff(i, bridge_len)) {
+ int32 cost = DoCommand(arf.bridge_end_tile, p->ai.cur_tile_a, i | (p->ai.railtype_to_use << 8), DC_AUTO, CMD_BUILD_BRIDGE);
+ if (!CmdFailed(cost) && cost < (p->player_money >> 5)) break;
+ }
+ }
+
+ // Build it
+ DoCommand(arf.bridge_end_tile, p->ai.cur_tile_a, i | (p->ai.railtype_to_use << 8), DC_AUTO | DC_EXEC, CMD_BUILD_BRIDGE);
+
+ p->ai.cur_tile_a = arf.bridge_end_tile;
+ p->ai.state_counter = 0;
+ } else if (arf.best_ptr[0] & 0x40) {
+ // tunnel
+ DoCommand(p->ai.cur_tile_a, p->ai.railtype_to_use, 0, DC_AUTO | DC_EXEC, CMD_BUILD_TUNNEL);
+ p->ai.cur_tile_a = _build_tunnel_endtile;
+ p->ai.state_counter = 0;
+ } else {
+ // rail
+ p->ai.cur_dir_a = arf.best_ptr[1];
+ DoCommand(p->ai.cur_tile_a, p->ai.railtype_to_use, arf.best_ptr[0],
+ DC_EXEC | DC_AUTO | DC_NO_WATER | DC_NO_RAIL_OVERLAP, CMD_BUILD_SINGLE_RAIL);
+ p->ai.state_counter = 0;
+ }
+
+ if (arf.best_tile != 0) {
+ for (i = 0; i != 2; i++) {
+ AiDoTerraformLand(arf.best_tile, arf.best_dir, 3, 0);
+ }
+ }
+}
+
+static bool AiRemoveTileAndGoForward(Player *p)
+{
+ byte b;
+ int bit;
+ const byte *ptr;
+ TileIndex tile = p->ai.cur_tile_a;
+ TileIndex tilenew;
+
+ if (IsTileType(tile, MP_TUNNELBRIDGE)) {
+ if (IsTunnel(tile)) {
+ // Clear the tunnel and continue at the other side of it.
+ if (CmdFailed(DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR)))
+ return false;
+ p->ai.cur_tile_a = TILE_MASK(_build_tunnel_endtile - TileOffsByDiagDir(p->ai.cur_dir_a));
+ return true;
+ } else {
+ // Check if the bridge points in the right direction.
+ // This is not really needed the first place AiRemoveTileAndGoForward is called.
+ if (DiagDirToAxis(GetBridgeRampDirection(tile)) != (p->ai.cur_dir_a & 1U)) return false;
+
+ tile = GetOtherBridgeEnd(tile);
+
+ tilenew = TILE_MASK(tile - TileOffsByDiagDir(p->ai.cur_dir_a));
+ // And clear the bridge.
+ if (CmdFailed(DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR)))
+ return false;
+ p->ai.cur_tile_a = tilenew;
+ return true;
+ }
+ }
+
+ // Find the railtype at the position. Quit if no rail there.
+ b = GetRailTrackStatus(tile) & _dir_table_3[p->ai.cur_dir_a];
+ if (b == 0) return false;
+
+ // Convert into a bit position that CMD_REMOVE_SINGLE_RAIL expects.
+ bit = FindFirstBit(b);
+
+ // Then remove and signals if there are any.
+ if (IsTileType(tile, MP_RAILWAY) &&
+ GetRailTileType(tile) == RAIL_TILE_SIGNALS) {
+ DoCommand(tile, 0, 0, DC_EXEC, CMD_REMOVE_SIGNALS);
+ }
+
+ // And also remove the rail.
+ if (CmdFailed(DoCommand(tile, 0, bit, DC_EXEC, CMD_REMOVE_SINGLE_RAIL)))
+ return false;
+
+ // Find the direction at the other edge of the rail.
+ ptr = _ai_table_15[p->ai.cur_dir_a ^ 2];
+ while (ptr[0] != bit) ptr += 2;
+ p->ai.cur_dir_a = ptr[1] ^ 2;
+
+ // And then also switch tile.
+ p->ai.cur_tile_a = TILE_MASK(p->ai.cur_tile_a - TileOffsByDiagDir(p->ai.cur_dir_a));
+
+ return true;
+}
+
+
+static void AiBuildRailDestruct(Player *p)
+{
+ // Decrease timeout.
+ if (!--p->ai.state_counter) {
+ p->ai.state_mode = 2;
+ p->ai.state_counter = 0;
+ }
+
+ // Don't do anything if the destination is already reached.
+ if (p->ai.cur_tile_a == p->ai.start_tile_a) return;
+
+ AiRemoveTileAndGoForward(p);
+}
+
+
+static void AiBuildRail(Player *p)
+{
+ switch (p->ai.state_mode) {
+ case 0: // Construct mode, build new rail.
+ AiBuildRailConstruct(p);
+ break;
+
+ case 1: // Destruct mode, destroy the rail currently built.
+ AiBuildRailDestruct(p);
+ break;
+
+ case 2: {
+ uint i;
+
+ // Terraform some and then try building again.
+ for (i = 0; i != 4; i++) {
+ AiDoTerraformLand(p->ai.cur_tile_a, p->ai.cur_dir_a, 3, 0);
+ }
+
+ if (++p->ai.state_counter == 4) {
+ p->ai.state_counter = 0;
+ p->ai.state_mode = 0;
+ }
+ }
+
+ default: break;
+ }
+}
+
+static void AiStateBuildRail(Player *p)
+{
+ int num;
+ AiBuildRec *aib;
+ byte cmd;
+ TileIndex tile;
+ int dir;
+
+ // time out?
+ if (++p->ai.timeout_counter == 1388) {
+ p->ai.state = AIS_DELETE_RAIL_BLOCKS;
+ return;
+ }
+
+ // Currently building a rail between two points?
+ if (p->ai.state_mode != 255) {
+ AiBuildRail(p);
+
+ // Alternate between edges
+ swap_tile(&p->ai.start_tile_a, &p->ai.start_tile_b);
+ swap_tile(&p->ai.cur_tile_a, &p->ai.cur_tile_b);
+ swap_byte(&p->ai.start_dir_a, &p->ai.start_dir_b);
+ swap_byte(&p->ai.cur_dir_a, &p->ai.cur_dir_b);
+ return;
+ }
+
+ // Now, find two new points to build between
+ num = p->ai.num_build_rec;
+ aib = &p->ai.src;
+
+ for (;;) {
+ cmd = aib->buildcmd_a;
+ aib->buildcmd_a = 255;
+ if (cmd != 255) break;
+
+ cmd = aib->buildcmd_b;
+ aib->buildcmd_b = 255;
+ if (cmd != 255) break;
+
+ aib++;
+ if (--num == 0) {
+ p->ai.state = AIS_BUILD_RAIL_VEH;
+ p->ai.state_counter = 0; // timeout
+ return;
+ }
+ }
+
+ // Find first edge to build from.
+ tile = AiGetEdgeOfDefaultRailBlock(aib->cur_building_rule, aib->use_tile, cmd&3, &dir);
+ p->ai.start_tile_a = tile;
+ p->ai.cur_tile_a = tile;
+ p->ai.start_dir_a = dir;
+ p->ai.cur_dir_a = dir;
+ DoCommand(TILE_MASK(tile + TileOffsByDiagDir(dir)), 0, (dir&1)?1:0, DC_EXEC, CMD_REMOVE_SINGLE_RAIL);
+
+ assert(TILE_MASK(tile) != 0xFF00);
+
+ // Find second edge to build to
+ aib = (&p->ai.src) + ((cmd >> 4)&0xF);
+ tile = AiGetEdgeOfDefaultRailBlock(aib->cur_building_rule, aib->use_tile, (cmd>>2)&3, &dir);
+ p->ai.start_tile_b = tile;
+ p->ai.cur_tile_b = tile;
+ p->ai.start_dir_b = dir;
+ p->ai.cur_dir_b = dir;
+ DoCommand(TILE_MASK(tile + TileOffsByDiagDir(dir)), 0, (dir&1)?1:0, DC_EXEC, CMD_REMOVE_SINGLE_RAIL);
+
+ assert(TILE_MASK(tile) != 0xFF00);
+
+ // And setup state.
+ p->ai.state_mode = 2;
+ p->ai.state_counter = 0;
+ p->ai.banned_tile_count = 0;
+}
+
+static StationID AiGetStationIdByDef(TileIndex tile, int id)
+{
+ const AiDefaultBlockData *p = _default_rail_track_data[id]->data;
+ while (p->mode != 1) p++;
+ return GetStationIndex(TILE_ADD(tile, ToTileIndexDiff(p->tileoffs)));
+}
+
+static EngineID AiFindBestWagon(CargoID cargo, RailType railtype)
+{
+ EngineID best_veh_index = INVALID_ENGINE;
+ EngineID i;
+ uint16 best_capacity = 0;
+ uint16 best_speed = 0;
+ uint speed;
+
+ for (i = 0; i < NUM_TRAIN_ENGINES; i++) {
+ const RailVehicleInfo *rvi = RailVehInfo(i);
+ const Engine* e = GetEngine(i);
+
+ if (!IsCompatibleRail(e->railtype, railtype) ||
+ !(rvi->flags & RVI_WAGON) ||
+ !HASBIT(e->player_avail, _current_player)) {
+ continue;
+ }
+
+ if (rvi->cargo_type != cargo) continue;
+
+ /* max_speed of 0 indicates no speed limit */
+ speed = rvi->max_speed == 0 ? 0xFFFF : rvi->max_speed;
+
+ if (rvi->capacity >= best_capacity && speed >= best_speed) {
+ best_capacity = rvi->capacity;
+ best_speed = best_speed;
+ best_veh_index = i;
+ }
+ }
+
+ return best_veh_index;
+}
+
+static void AiStateBuildRailVeh(Player *p)
+{
+ const AiDefaultBlockData *ptr;
+ TileIndex tile;
+ EngineID veh;
+ int i;
+ CargoID cargo;
+ int32 cost;
+ Vehicle *v;
+ VehicleID loco_id;
+
+ ptr = _default_rail_track_data[p->ai.src.cur_building_rule]->data;
+ while (ptr->mode != 0) ptr++;
+
+ tile = TILE_ADD(p->ai.src.use_tile, ToTileIndexDiff(ptr->tileoffs));
+
+
+ cargo = p->ai.cargo_type;
+ for (i = 0;;) {
+ if (p->ai.wagon_list[i] == INVALID_VEHICLE) {
+ veh = AiFindBestWagon(cargo, p->ai.railtype_to_use);
+ /* veh will return INVALID_ENGINE if no suitable wagon is available.
+ * We shall treat this in the same way as having no money */
+ if (veh == INVALID_ENGINE) goto handle_nocash;
+ cost = DoCommand(tile, veh, 0, DC_EXEC, CMD_BUILD_RAIL_VEHICLE);
+ if (CmdFailed(cost)) goto handle_nocash;
+ p->ai.wagon_list[i] = _new_vehicle_id;
+ p->ai.wagon_list[i + 1] = INVALID_VEHICLE;
+ return;
+ }
+ if (cargo == CT_MAIL) cargo = CT_PASSENGERS;
+ if (++i == p->ai.num_wagons * 2 - 1) break;
+ }
+
+ // Which locomotive to build?
+ veh = AiChooseTrainToBuild(p->ai.railtype_to_use, p->player_money, cargo != CT_PASSENGERS ? 1 : 0, tile);
+ if (veh == INVALID_ENGINE) {
+handle_nocash:
+ // after a while, if AI still doesn't have cash, get out of this block by selling the wagons.
+ if (++p->ai.state_counter == 1000) {
+ for (i = 0; p->ai.wagon_list[i] != INVALID_VEHICLE; i++) {
+ cost = DoCommand(tile, p->ai.wagon_list[i], 0, DC_EXEC, CMD_SELL_RAIL_WAGON);
+ assert(!CmdFailed(cost));
+ }
+ p->ai.state = AIS_0;
+ }
+ return;
+ }
+
+ // Try to build the locomotive
+ cost = DoCommand(tile, veh, 0, DC_EXEC, CMD_BUILD_RAIL_VEHICLE);
+ assert(!CmdFailed(cost));
+ loco_id = _new_vehicle_id;
+
+ // Sell a vehicle if the train is double headed.
+ v = GetVehicle(loco_id);
+ if (v->next != NULL) {
+ i = p->ai.wagon_list[p->ai.num_wagons * 2 - 2];
+ p->ai.wagon_list[p->ai.num_wagons * 2 - 2] = INVALID_VEHICLE;
+ DoCommand(tile, i, 0, DC_EXEC, CMD_SELL_RAIL_WAGON);
+ }
+
+ // Move the wagons onto the train
+ for (i = 0; p->ai.wagon_list[i] != INVALID_VEHICLE; i++) {
+ DoCommand(tile, p->ai.wagon_list[i] | (loco_id << 16), 0, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
+ }
+
+ for (i = 0; p->ai.order_list_blocks[i] != 0xFF; i++) {
+ const AiBuildRec* aib = &p->ai.src + p->ai.order_list_blocks[i];
+ bool is_pass = (
+ p->ai.cargo_type == CT_PASSENGERS ||
+ p->ai.cargo_type == CT_MAIL ||
+ (_opt.landscape == LT_NORMAL && p->ai.cargo_type == CT_VALUABLES)
+ );
+ Order order;
+
+ order.type = OT_GOTO_STATION;
+ order.flags = 0;
+ order.dest = AiGetStationIdByDef(aib->use_tile, aib->cur_building_rule);
+
+ if (!is_pass && i == 1) order.flags |= OF_UNLOAD;
+ if (p->ai.num_want_fullload != 0 && (is_pass || i == 0))
+ order.flags |= OF_FULL_LOAD;
+
+ DoCommand(0, loco_id + (i << 16), PackOrder(&order), DC_EXEC, CMD_INSERT_ORDER);
+ }
+
+ DoCommand(0, loco_id, 0, DC_EXEC, CMD_START_STOP_TRAIN);
+
+ DoCommand(0, loco_id, _ai_service_interval, DC_EXEC, CMD_CHANGE_SERVICE_INT);
+
+ if (p->ai.num_want_fullload != 0) p->ai.num_want_fullload--;
+
+ if (--p->ai.num_loco_to_build != 0) {
+// p->ai.loco_id = INVALID_VEHICLE;
+ p->ai.wagon_list[0] = INVALID_VEHICLE;
+ } else {
+ p->ai.state = AIS_0;
+ }
+}
+
+static void AiStateDeleteRailBlocks(Player *p)
+{
+ const AiBuildRec* aib = &p->ai.src;
+ uint num = p->ai.num_build_rec;
+
+ do {
+ const AiDefaultBlockData* b;
+
+ if (aib->cur_building_rule == 255) continue;
+ for (b = _default_rail_track_data[aib->cur_building_rule]->data; b->mode != 4; b++) {
+ DoCommand(TILE_ADD(aib->use_tile, ToTileIndexDiff(b->tileoffs)), 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
+ }
+ } while (++aib,--num);
+
+ p->ai.state = AIS_0;
+}
+
+static bool AiCheckRoadResources(TileIndex tile, const AiDefaultBlockData *p, byte cargo)
+{
+ uint values[NUM_CARGO];
+ int rad;
+
+ if (_patches.modified_catchment) {
+ rad = CA_TRUCK; // Same as CA_BUS at the moment?
+ } else { // change that at some point?
+ rad = 4;
+ }
+
+ for (;; p++) {
+ if (p->mode == 4) {
+ return true;
+ } else if (p->mode == 1) {
+ TileIndex tile2 = TILE_ADD(tile, ToTileIndexDiff(p->tileoffs));
+
+ if (cargo & 0x80) {
+ GetProductionAroundTiles(values, tile2, 1, 1, rad);
+ return values[cargo & 0x7F] != 0;
+ } else {
+ GetAcceptanceAroundTiles(values, tile2, 1, 1, rad);
+ return (values[cargo]&~7) != 0;
+ }
+ }
+ }
+}
+
+static bool _want_road_truck_station;
+static int32 AiDoBuildDefaultRoadBlock(TileIndex tile, const AiDefaultBlockData *p, byte flag);
+
+// Returns rule and cost
+static int AiFindBestDefaultRoadBlock(TileIndex tile, byte direction, byte cargo, int32 *cost)
+{
+ int i;
+ const AiDefaultRoadBlock *p;
+
+ _want_road_truck_station = (cargo & 0x7F) != CT_PASSENGERS;
+
+ for (i = 0; (p = _road_default_block_data[i]) != NULL; i++) {
+ if (p->dir == direction) {
+ *cost = AiDoBuildDefaultRoadBlock(tile, p->data, 0);
+ if (!CmdFailed(*cost) && AiCheckRoadResources(tile, p->data, cargo))
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+static int32 AiDoBuildDefaultRoadBlock(TileIndex tile, const AiDefaultBlockData *p, byte flag)
+{
+ int32 ret;
+ int32 total_cost = 0;
+ Town *t = NULL;
+ int rating = 0;
+ int roadflag = 0;
+
+ for (;p->mode != 4;p++) {
+ TileIndex c = TILE_MASK(tile + ToTileIndexDiff(p->tileoffs));
+
+ _cleared_town = NULL;
+
+ if (p->mode == 2) {
+ if (IsTileType(c, MP_STREET) &&
+ GetRoadTileType(c) == ROAD_TILE_NORMAL &&
+ (GetRoadBits(c) & p->attr) != 0) {
+ roadflag |= 2;
+
+ // all bits are already built?
+ if ((GetRoadBits(c) & p->attr) == p->attr) continue;
+ }
+
+ ret = DoCommand(c, p->attr, 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD);
+ if (CmdFailed(ret)) return CMD_ERROR;
+ total_cost += ret;
+
+ continue;
+ }
+
+ if (p->mode == 0) {
+ // Depot
+ ret = DoCommand(c, p->attr, 0, flag | DC_AUTO | DC_NO_WATER | DC_AI_BUILDING, CMD_BUILD_ROAD_DEPOT);
+ goto clear_town_stuff;
+ } else if (p->mode == 1) {
+ if (_want_road_truck_station) {
+ // Truck station
+ ret = DoCommand(c, p->attr, RS_TRUCK, flag | DC_AUTO | DC_NO_WATER | DC_AI_BUILDING, CMD_BUILD_ROAD_STOP);
+ } else {
+ // Bus station
+ ret = DoCommand(c, p->attr, RS_BUS, flag | DC_AUTO | DC_NO_WATER | DC_AI_BUILDING, CMD_BUILD_ROAD_STOP);
+ }
+clear_town_stuff:;
+
+ if (CmdFailed(ret)) return CMD_ERROR;
+ total_cost += ret;
+
+ if (_cleared_town != NULL) {
+ if (t != NULL && t != _cleared_town) return CMD_ERROR;
+ t = _cleared_town;
+ rating += _cleared_town_rating;
+ }
+ } else if (p->mode == 3) {
+ if (flag & DC_EXEC) continue;
+
+ if (GetTileSlope(c, NULL) != SLOPE_FLAT) return CMD_ERROR;
+
+ if (!IsTileType(c, MP_STREET) || GetRoadTileType(c) != ROAD_TILE_NORMAL) {
+ ret = DoCommand(c, 0, 0, flag | DC_AUTO | DC_NO_WATER | DC_AI_BUILDING, CMD_LANDSCAPE_CLEAR);
+ if (CmdFailed(ret)) return CMD_ERROR;
+ }
+
+ }
+ }
+
+ if (!_want_road_truck_station && !(roadflag & 2)) return CMD_ERROR;
+
+ if (!(flag & DC_EXEC)) {
+ if (t != NULL && rating > t->ratings[_current_player]) return CMD_ERROR;
+ }
+ return total_cost;
+}
+
+// Make sure the blocks are not too close to each other
+static bool AiCheckBlockDistances(Player *p, TileIndex tile)
+{
+ const AiBuildRec* aib = &p->ai.src;
+ uint num = p->ai.num_build_rec;
+
+ do {
+ if (aib->cur_building_rule != 255) {
+ if (DistanceManhattan(aib->use_tile, tile) < 9) return false;
+ }
+ } while (++aib, --num);
+
+ return true;
+}
+
+
+static void AiStateBuildDefaultRoadBlocks(Player *p)
+{
+ uint i;
+ int j;
+ AiBuildRec *aib;
+ int rule;
+ int32 cost;
+
+ // time out?
+ if (++p->ai.timeout_counter == 1388) {
+ p->ai.state = AIS_DELETE_RAIL_BLOCKS;
+ return;
+ }
+
+ // do the following 8 times
+ for (i = 0; i != 8; i++) {
+ // check if we can build the default track
+ aib = &p->ai.src;
+ j = p->ai.num_build_rec;
+ do {
+ // this item has already been built?
+ if (aib->cur_building_rule != 255) continue;
+
+ // adjust the coordinate randomly,
+ // to make sure that we find a position.
+ aib->use_tile = AdjustTileCoordRandomly(aib->spec_tile, aib->rand_rng);
+
+ // check if the road can be built there.
+ rule = AiFindBestDefaultRoadBlock(
+ aib->use_tile, aib->direction, aib->cargo, &cost
+ );
+
+ if (rule == -1) {
+ // cannot build, terraform after a while
+ if (p->ai.state_counter >= 600) {
+ AiDoTerraformLand(aib->use_tile, Random()&3, 3, (int8)p->ai.state_mode);
+ }
+ // also try the other terraform direction
+ if (++p->ai.state_counter >= 1000) {
+ p->ai.state_counter = 0;
+ p->ai.state_mode = -p->ai.state_mode;
+ }
+ } else if (CheckPlayerHasMoney(cost) && AiCheckBlockDistances(p,aib->use_tile)) {
+ int32 r;
+
+ // player has money, build it.
+ aib->cur_building_rule = rule;
+
+ r = AiDoBuildDefaultRoadBlock(
+ aib->use_tile,
+ _road_default_block_data[rule]->data,
+ DC_EXEC | DC_NO_TOWN_RATING
+ );
+ assert(!CmdFailed(r));
+ }
+ } while (++aib,--j);
+ }
+
+ // check if we're done with all of them
+ aib = &p->ai.src;
+ j = p->ai.num_build_rec;
+ do {
+ if (aib->cur_building_rule == 255) return;
+ } while (++aib,--j);
+
+ // yep, all are done. switch state to the rail building state.
+ p->ai.state = AIS_BUILD_ROAD;
+ p->ai.state_mode = 255;
+}
+
+typedef struct {
+ TileIndex final_tile;
+ byte final_dir;
+ byte depth;
+ byte recursive_mode;
+ byte cur_best_dir;
+ byte best_dir;
+ byte cur_best_depth;
+ byte best_depth;
+ uint cur_best_dist;
+ const byte *best_ptr;
+ uint best_dist;
+ TileIndex cur_best_tile, best_tile;
+ TileIndex bridge_end_tile;
+ Player *player;
+} AiRoadFinder;
+
+typedef struct AiRoadEnum {
+ TileIndex dest;
+ TileIndex best_tile;
+ int best_track;
+ uint best_dist;
+} AiRoadEnum;
+
+static const byte _dir_by_track[] = {
+ 0, 1, 0, 1, 2, 1,
+ 0, 0,
+ 2, 3, 3, 2, 3, 0,
+};
+
+static void AiBuildRoadRecursive(AiRoadFinder *arf, TileIndex tile, int dir);
+
+static bool AiCheckRoadPathBetter(AiRoadFinder *arf, const byte *p)
+{
+ bool better = false;
+
+ if (arf->recursive_mode < 1) {
+ // Mode is 0. This means destination has not been found yet.
+ // If the found path is shorter than the current one, remember it.
+ if (arf->cur_best_dist < arf->best_dist ||
+ (arf->cur_best_dist == arf->best_dist && arf->cur_best_depth < arf->best_depth)) {
+ arf->best_depth = arf->cur_best_depth;
+ arf->best_dist = arf->cur_best_dist;
+ arf->best_dir = arf->cur_best_dir;
+ arf->best_ptr = p;
+ arf->best_tile = arf->cur_best_tile;
+ better = true;
+ }
+ } else if (arf->recursive_mode > 1) {
+ // Mode is 2.
+ if (arf->best_dist != 0 || arf->cur_best_depth < arf->best_depth) {
+ arf->best_depth = arf->cur_best_depth;
+ arf->best_dist = 0;
+ arf->best_ptr = p;
+ arf->best_tile = 0;
+ better = true;
+ }
+ }
+ arf->recursive_mode = 0;
+ arf->cur_best_dist = (uint)-1;
+ arf->cur_best_depth = 0xff;
+
+ return better;
+}
+
+
+static bool AiEnumFollowRoad(TileIndex tile, AiRoadEnum *a, int track, uint length, byte *state)
+{
+ uint dist = DistanceManhattan(tile, a->dest);
+
+ if (dist <= a->best_dist) {
+ TileIndex tile2 = TILE_MASK(tile + TileOffsByDiagDir(_dir_by_track[track]));
+
+ if (IsTileType(tile2, MP_STREET) && GetRoadTileType(tile2) == ROAD_TILE_NORMAL) {
+ a->best_dist = dist;
+ a->best_tile = tile;
+ a->best_track = track;
+ }
+ }
+
+ return false;
+}
+
+static const uint16 _ai_road_table_and[4] = {
+ 0x1009,
+ 0x16,
+ 0x520,
+ 0x2A00,
+};
+
+static bool AiCheckRoadFinished(Player *p)
+{
+ AiRoadEnum are;
+ TileIndex tile;
+ int dir = p->ai.cur_dir_a;
+ uint32 bits;
+ int i;
+
+ are.dest = p->ai.cur_tile_b;
+ tile = TILE_MASK(p->ai.cur_tile_a + TileOffsByDiagDir(dir));
+
+ if (IsRoadStopTile(tile) || IsTileDepotType(tile, TRANSPORT_ROAD)) return false;
+ bits = GetTileTrackStatus(tile, TRANSPORT_ROAD) & _ai_road_table_and[dir];
+ if (bits == 0) return false;
+
+ are.best_dist = (uint)-1;
+
+ for_each_bit(i, bits) {
+ FollowTrack(tile, 0x3000 | TRANSPORT_ROAD, _dir_by_track[i], (TPFEnumProc*)AiEnumFollowRoad, NULL, &are);
+ }
+
+ if (DistanceManhattan(tile, are.dest) <= are.best_dist) return false;
+
+ if (are.best_dist == 0) return true;
+
+ p->ai.cur_tile_a = are.best_tile;
+ p->ai.cur_dir_a = _dir_by_track[are.best_track];
+ return false;
+}
+
+
+static bool AiBuildRoadHelper(TileIndex tile, int flags, int type)
+{
+ static const RoadBits _road_bits[] = {
+ ROAD_X,
+ ROAD_Y,
+ ROAD_NW | ROAD_NE,
+ ROAD_SW | ROAD_SE,
+ ROAD_NW | ROAD_SW,
+ ROAD_SE | ROAD_NE
+ };
+ return !CmdFailed(DoCommand(tile, _road_bits[type], 0, flags, CMD_BUILD_ROAD));
+}
+
+static inline void AiCheckBuildRoadBridgeHere(AiRoadFinder *arf, TileIndex tile, const byte *p)
+{
+ Slope tileh;
+ uint z;
+ bool flag;
+
+ int dir2 = p[0] & 3;
+
+ tileh = GetTileSlope(tile, &z);
+ if (tileh == _dir_table_1[dir2] || (tileh == SLOPE_FLAT && z != 0)) {
+ TileIndex tile_new = tile;
+
+ // Allow bridges directly over bottom tiles
+ flag = z == 0;
+ for (;;) {
+ TileType type;
+
+ if ((TileIndexDiff)tile_new < -TileOffsByDiagDir(dir2)) return; // Wraping around map, no bridge possible!
+ tile_new = TILE_MASK(tile_new + TileOffsByDiagDir(dir2));
+ type = GetTileType(tile_new);
+
+ if (type == MP_CLEAR || type == MP_TREES || GetTileSlope(tile, NULL) != SLOPE_FLAT) {
+ // Allow a bridge if either we have a tile that's water, rail or street,
+ // or if we found an up tile.
+ if (!flag) return;
+ break;
+ }
+ if (type != MP_WATER && type != MP_RAILWAY && type != MP_STREET) return;
+ flag = true;
+ }
+
+ // Is building a (rail)bridge possible at this place (type doesn't matter)?
+ if (CmdFailed(DoCommand(tile_new, tile, 0x8000, DC_AUTO, CMD_BUILD_BRIDGE)))
+ return;
+ AiBuildRoadRecursive(arf, tile_new, dir2);
+
+ // At the bottom depth, check if the new path is better than the old one.
+ if (arf->depth == 1) {
+ if (AiCheckRoadPathBetter(arf, p)) arf->bridge_end_tile = tile_new;
+ }
+ }
+}
+
+static inline void AiCheckBuildRoadTunnelHere(AiRoadFinder *arf, TileIndex tile, const byte *p)
+{
+ uint z;
+
+ if (GetTileSlope(tile, &z) == _dir_table_2[p[0] & 3] && z != 0) {
+ int32 cost = DoCommand(tile, 0x200, 0, DC_AUTO, CMD_BUILD_TUNNEL);
+
+ if (!CmdFailed(cost) && cost <= (arf->player->player_money>>4)) {
+ AiBuildRoadRecursive(arf, _build_tunnel_endtile, p[0]&3);
+ if (arf->depth == 1) AiCheckRoadPathBetter(arf, p);
+ }
+ }
+}
+
+
+
+static void AiBuildRoadRecursive(AiRoadFinder *arf, TileIndex tile, int dir)
+{
+ const byte *p;
+
+ tile = TILE_MASK(tile + TileOffsByDiagDir(dir));
+
+ // Reached destination?
+ if (tile == arf->final_tile) {
+ if ((arf->final_dir^2) == dir) {
+ arf->recursive_mode = 2;
+ arf->cur_best_depth = arf->depth;
+ }
+ return;
+ }
+
+ // Depth too deep?
+ if (arf->depth >= 4) {
+ uint dist = DistanceMaxPlusManhattan(tile, arf->final_tile);
+ if (dist < arf->cur_best_dist) {
+ // Store the tile that is closest to the final position.
+ arf->cur_best_dist = dist;
+ arf->cur_best_tile = tile;
+ arf->cur_best_dir = dir;
+ arf->cur_best_depth = arf->depth;
+ }
+ return;
+ }
+
+ // Increase recursion depth
+ arf->depth++;
+
+ // Grab pointer to list of stuff that is possible to build
+ p = _ai_table_15[dir];
+
+ // Try to build a single rail in all directions.
+ if (GetTileZ(tile) == 0) {
+ p += 6;
+ } else {
+ do {
+ // Make sure that a road can be built here.
+ if (AiBuildRoadHelper(tile, DC_AUTO | DC_NO_WATER | DC_AI_BUILDING, p[0])) {
+ AiBuildRoadRecursive(arf, tile, p[1]);
+ }
+
+ // At the bottom depth?
+ if (arf->depth == 1) AiCheckRoadPathBetter(arf, p);
+
+ p += 2;
+ } while (!(p[0] & 0x80));
+ }
+
+ AiCheckBuildRoadBridgeHere(arf, tile, p);
+ AiCheckBuildRoadTunnelHere(arf, tile, p+1);
+
+ arf->depth--;
+}
+
+
+static void AiBuildRoadConstruct(Player *p)
+{
+ AiRoadFinder arf;
+ int i;
+ TileIndex tile;
+
+ // Reached destination?
+ if (AiCheckRoadFinished(p)) {
+ p->ai.state_mode = 255;
+ return;
+ }
+
+ // Setup recursive finder and call it.
+ arf.player = p;
+ arf.final_tile = p->ai.cur_tile_b;
+ arf.final_dir = p->ai.cur_dir_b;
+ arf.depth = 0;
+ arf.recursive_mode = 0;
+ arf.best_ptr = NULL;
+ arf.cur_best_dist = (uint)-1;
+ arf.cur_best_depth = 0xff;
+ arf.best_dist = (uint)-1;
+ arf.best_depth = 0xff;
+ arf.cur_best_tile = 0;
+ arf.best_tile = 0;
+ AiBuildRoadRecursive(&arf, p->ai.cur_tile_a, p->ai.cur_dir_a);
+
+ // Reached destination?
+ if (arf.recursive_mode == 2 && arf.cur_best_depth == 0) {
+ p->ai.state_mode = 255;
+ return;
+ }
+
+ // Didn't find anything to build?
+ if (arf.best_ptr == NULL) {
+ // Terraform some
+do_some_terraform:
+ for (i = 0; i != 5; i++)
+ AiDoTerraformLand(p->ai.cur_tile_a, p->ai.cur_dir_a, 3, 0);
+
+ if (++p->ai.state_counter == 21) {
+ p->ai.state_mode = 1;
+
+ p->ai.cur_tile_a = TILE_MASK(p->ai.cur_tile_a + TileOffsByDiagDir(p->ai.cur_dir_a));
+ p->ai.cur_dir_a ^= 2;
+ p->ai.state_counter = 0;
+ }
+ return;
+ }
+
+ tile = TILE_MASK(p->ai.cur_tile_a + TileOffsByDiagDir(p->ai.cur_dir_a));
+
+ if (arf.best_ptr[0]&0x80) {
+ int i;
+ int32 bridge_len;
+ p->ai.cur_tile_a = arf.bridge_end_tile;
+ bridge_len = GetBridgeLength(tile, p->ai.cur_tile_a); // tile
+
+ /* Figure out what (road)bridge type to build
+ * start with best bridge, then go down to worse and worse bridges
+ * unnecessary to check for worse bridge (i=0), since AI will always build that.
+ *AI is so fucked up that fixing this small thing will probably not solve a thing
+ */
+ for (i = 10; i != 0; i--) {
+ if (CheckBridge_Stuff(i, bridge_len)) {
+ int32 cost = DoCommand(tile, p->ai.cur_tile_a, i + (0x80 << 8), DC_AUTO, CMD_BUILD_BRIDGE);
+ if (!CmdFailed(cost) && cost < (p->player_money >> 5)) break;
+ }
+ }
+
+ // Build it
+ DoCommand(tile, p->ai.cur_tile_a, i + (0x80 << 8), DC_AUTO | DC_EXEC, CMD_BUILD_BRIDGE);
+
+ p->ai.state_counter = 0;
+ } else if (arf.best_ptr[0]&0x40) {
+ // tunnel
+ DoCommand(tile, 0x200, 0, DC_AUTO | DC_EXEC, CMD_BUILD_TUNNEL);
+ p->ai.cur_tile_a = _build_tunnel_endtile;
+ p->ai.state_counter = 0;
+ } else {
+ // road
+ if (!AiBuildRoadHelper(tile, DC_EXEC | DC_AUTO | DC_NO_WATER | DC_AI_BUILDING, arf.best_ptr[0]))
+ goto do_some_terraform;
+
+ p->ai.cur_dir_a = arf.best_ptr[1];
+ p->ai.cur_tile_a = tile;
+ p->ai.state_counter = 0;
+ }
+
+ if (arf.best_tile != 0) {
+ for (i = 0; i != 2; i++)
+ AiDoTerraformLand(arf.best_tile, arf.best_dir, 3, 0);
+ }
+}
+
+
+static void AiBuildRoad(Player *p)
+{
+ if (p->ai.state_mode < 1) {
+ // Construct mode, build new road.
+ AiBuildRoadConstruct(p);
+ } else if (p->ai.state_mode == 1) {
+ // Destruct mode, not implemented for roads.
+ p->ai.state_mode = 2;
+ p->ai.state_counter = 0;
+ } else if (p->ai.state_mode == 2) {
+ uint i;
+
+ // Terraform some and then try building again.
+ for (i = 0; i != 4; i++) {
+ AiDoTerraformLand(p->ai.cur_tile_a, p->ai.cur_dir_a, 3, 0);
+ }
+
+ if (++p->ai.state_counter == 4) {
+ p->ai.state_counter = 0;
+ p->ai.state_mode = 0;
+ }
+ }
+}
+
+static TileIndex AiGetRoadBlockEdge(byte rule, TileIndex tile, int *dir)
+{
+ const AiDefaultBlockData *p = _road_default_block_data[rule]->data;
+ while (p->mode != 1) p++;
+ *dir = p->attr;
+ return TILE_ADD(tile, ToTileIndexDiff(p->tileoffs));
+}
+
+
+static void AiStateBuildRoad(Player *p)
+{
+ int num;
+ AiBuildRec *aib;
+ byte cmd;
+ TileIndex tile;
+ int dir;
+
+ // time out?
+ if (++p->ai.timeout_counter == 1388) {
+ p->ai.state = AIS_DELETE_ROAD_BLOCKS;
+ return;
+ }
+
+ // Currently building a road between two points?
+ if (p->ai.state_mode != 255) {
+ AiBuildRoad(p);
+
+ // Alternate between edges
+ swap_tile(&p->ai.start_tile_a, &p->ai.start_tile_b);
+ swap_tile(&p->ai.cur_tile_a, &p->ai.cur_tile_b);
+ swap_byte(&p->ai.start_dir_a, &p->ai.start_dir_b);
+ swap_byte(&p->ai.cur_dir_a, &p->ai.cur_dir_b);
+
+ return;
+ }
+
+ // Now, find two new points to build between
+ num = p->ai.num_build_rec;
+ aib = &p->ai.src;
+
+ for (;;) {
+ cmd = aib->buildcmd_a;
+ aib->buildcmd_a = 255;
+ if (cmd != 255) break;
+
+ aib++;
+ if (--num == 0) {
+ p->ai.state = AIS_BUILD_ROAD_VEHICLES;
+ return;
+ }
+ }
+
+ // Find first edge to build from.
+ tile = AiGetRoadBlockEdge(aib->cur_building_rule, aib->use_tile, &dir);
+ p->ai.start_tile_a = tile;
+ p->ai.cur_tile_a = tile;
+ p->ai.start_dir_a = dir;
+ p->ai.cur_dir_a = dir;
+
+ // Find second edge to build to
+ aib = (&p->ai.src) + (cmd&0xF);
+ tile = AiGetRoadBlockEdge(aib->cur_building_rule, aib->use_tile, &dir);
+ p->ai.start_tile_b = tile;
+ p->ai.cur_tile_b = tile;
+ p->ai.start_dir_b = dir;
+ p->ai.cur_dir_b = dir;
+
+ // And setup state.
+ p->ai.state_mode = 2;
+ p->ai.state_counter = 0;
+ p->ai.banned_tile_count = 0;
+}
+
+static StationID AiGetStationIdFromRoadBlock(TileIndex tile, int id)
+{
+ const AiDefaultBlockData *p = _road_default_block_data[id]->data;
+ while (p->mode != 1) p++;
+ return GetStationIndex(TILE_ADD(tile, ToTileIndexDiff(p->tileoffs)));
+}
+
+static void AiStateBuildRoadVehicles(Player *p)
+{
+ const AiDefaultBlockData *ptr;
+ TileIndex tile;
+ VehicleID loco_id;
+ EngineID veh;
+ uint i;
+
+ ptr = _road_default_block_data[p->ai.src.cur_building_rule]->data;
+ for (; ptr->mode != 0; ptr++) {}
+ tile = TILE_ADD(p->ai.src.use_tile, ToTileIndexDiff(ptr->tileoffs));
+
+ veh = AiChooseRoadVehToBuild(p->ai.cargo_type, p->player_money, tile);
+ if (veh == INVALID_ENGINE) {
+ p->ai.state = AIS_0;
+ return;
+ }
+
+ if (CmdFailed(DoCommand(tile, veh, 0, DC_EXEC, CMD_BUILD_ROAD_VEH))) return;
+
+ loco_id = _new_vehicle_id;
+
+ if (GetVehicle(loco_id)->cargo_type != p->ai.cargo_type) {
+ /* Cargo type doesn't match, so refit it */
+ if (CmdFailed(DoCommand(tile, loco_id, p->ai.cargo_type, DC_EXEC, CMD_REFIT_ROAD_VEH))) {
+ /* Refit failed... sell the vehicle */
+ DoCommand(tile, loco_id, 0, DC_EXEC, CMD_SELL_ROAD_VEH);
+ return;
+ }
+ }
+
+ for (i = 0; p->ai.order_list_blocks[i] != 0xFF; i++) {
+ const AiBuildRec* aib = &p->ai.src + p->ai.order_list_blocks[i];
+ bool is_pass = (
+ p->ai.cargo_type == CT_PASSENGERS ||
+ p->ai.cargo_type == CT_MAIL ||
+ (_opt.landscape == LT_NORMAL && p->ai.cargo_type == CT_VALUABLES)
+ );
+ Order order;
+
+ order.type = OT_GOTO_STATION;
+ order.flags = 0;
+ order.dest = AiGetStationIdFromRoadBlock(aib->use_tile, aib->cur_building_rule);
+
+ if (!is_pass && i == 1) order.flags |= OF_UNLOAD;
+ if (p->ai.num_want_fullload != 0 && (is_pass || i == 0))
+ order.flags |= OF_FULL_LOAD;
+
+ DoCommand(0, loco_id + (i << 16), PackOrder(&order), DC_EXEC, CMD_INSERT_ORDER);
+ }
+
+ DoCommand(0, loco_id, 0, DC_EXEC, CMD_START_STOP_ROADVEH);
+ DoCommand(0, loco_id, _ai_service_interval, DC_EXEC, CMD_CHANGE_SERVICE_INT);
+
+ if (p->ai.num_want_fullload != 0) p->ai.num_want_fullload--;
+ if (--p->ai.num_loco_to_build == 0) p->ai.state = AIS_0;
+}
+
+static void AiStateDeleteRoadBlocks(Player *p)
+{
+ const AiBuildRec* aib = &p->ai.src;
+ uint num = p->ai.num_build_rec;
+
+ do {
+ const AiDefaultBlockData* b;
+
+ if (aib->cur_building_rule == 255) continue;
+ for (b = _road_default_block_data[aib->cur_building_rule]->data; b->mode != 4; b++) {
+ if (b->mode > 1) continue;
+ DoCommand(TILE_ADD(aib->use_tile, ToTileIndexDiff(b->tileoffs)), 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
+ }
+ } while (++aib,--num);
+
+ p->ai.state = AIS_0;
+}
+
+
+static void AiStateAirportStuff(Player *p)
+{
+ const Station* st;
+ byte acc_planes;
+ int i;
+ AiBuildRec *aib;
+ byte rule;
+
+ // Here we look for an airport we could use instead of building a new
+ // one. If we find such an aiport for any waypoint,
+ // AiStateBuildDefaultAirportBlocks() will kindly skip that one when
+ // building the waypoints.
+
+ i = 0;
+ do {
+ // We do this all twice - once for the source (town in the case
+ // of oilrig route) and then for the destination (oilrig in the
+ // case of oilrig route).
+ aib = &p->ai.src + i;
+
+ FOR_ALL_STATIONS(st) {
+ // Is this an airport?
+ if (!(st->facilities & FACIL_AIRPORT)) continue;
+
+ // Do we own the airport? (Oilrigs aren't owned, though.)
+ if (st->owner != OWNER_NONE && st->owner != _current_player) continue;
+
+ acc_planes = GetAirport(st->airport_type)->acc_planes;
+
+ // Dismiss heliports, unless we are checking an oilrig.
+ if (acc_planes == HELICOPTERS_ONLY && (p->ai.build_kind != 1 || i != 1))
+ continue;
+
+ // Dismiss country airports if we are doing the other
+ // endpoint of an oilrig route.
+ if (acc_planes == AIRCRAFT_ONLY && (p->ai.build_kind == 1 && i == 0))
+ continue;
+
+ // Dismiss airports too far away.
+ if (DistanceMax(st->airport_tile, aib->spec_tile) > aib->rand_rng)
+ continue;
+
+ // It's ideal airport, let's take it!
+
+ /* XXX: This part is utterly broken - rule should
+ * contain number of the rule appropriate for the
+ * airport type (country, town, ...), see
+ * _airport_default_block_data (rule is just an index
+ * in this array). But the only difference between the
+ * currently existing two rules (rule 0 - town and rule
+ * 1 - country) is the attr field which is used only
+ * when building new airports - and that's irrelevant
+ * for us. So using just about any rule will suffice
+ * here for now (some of the new airport types would be
+ * broken because they will probably need different
+ * tileoff values etc), no matter that
+ * IsHangarTile() makes no sense. --pasky */
+ if (acc_planes == HELICOPTERS_ONLY) {
+ /* Heliports should have maybe own rulesets but
+ * OTOH we don't want AI to pick them up when
+ * looking for a suitable airport type to build.
+ * So any of rules 0 or 1 would do for now. The
+ * original rule number was 2 but that's a bug
+ * because we have no such rule. */
+ rule = 1;
+ } else {
+ rule = IsHangarTile(st->airport_tile);
+ }
+
+ aib->cur_building_rule = rule;
+ aib->use_tile = st->airport_tile;
+ break;
+ }
+ } while (++i != p->ai.num_build_rec);
+
+ p->ai.state = AIS_BUILD_DEFAULT_AIRPORT_BLOCKS;
+ p->ai.state_mode = 255;
+ p->ai.state_counter = 0;
+}
+
+static int32 AiDoBuildDefaultAirportBlock(TileIndex tile, const AiDefaultBlockData *p, byte flag)
+{
+ int32 total_cost = 0, ret;
+
+ for (; p->mode == 0; p++) {
+ if (!HASBIT(_avail_aircraft, p->attr)) return CMD_ERROR;
+ ret = DoCommand(TILE_MASK(tile + ToTileIndexDiff(p->tileoffs)), p->attr,0,flag | DC_AUTO | DC_NO_WATER,CMD_BUILD_AIRPORT);
+ if (CmdFailed(ret)) return CMD_ERROR;
+ total_cost += ret;
+ }
+
+ return total_cost;
+}
+
+static bool AiCheckAirportResources(TileIndex tile, const AiDefaultBlockData *p, byte cargo)
+{
+ uint values[NUM_CARGO];
+ int rad;
+
+ if (_patches.modified_catchment) {
+ rad = CA_AIR_LARGE; // I Have NFI what airport the
+ } else { // AI is going to build here
+ rad = 4;
+ }
+
+ for (; p->mode == 0; p++) {
+ TileIndex tile2 = TILE_ADD(tile, ToTileIndexDiff(p->tileoffs));
+ const AirportFTAClass* airport = GetAirport(p->attr);
+ uint w = airport->size_x;
+ uint h = airport->size_y;
+
+ if (cargo & 0x80) {
+ GetProductionAroundTiles(values, tile2, w, h, rad);
+ return values[cargo & 0x7F] != 0;
+ } else {
+ GetAcceptanceAroundTiles(values, tile2, w, h, rad);
+ return values[cargo] >= 8;
+ }
+ }
+ return true;
+}
+
+static int AiFindBestDefaultAirportBlock(TileIndex tile, byte cargo, byte heli, int32 *cost)
+{
+ const AiDefaultBlockData *p;
+ uint i;
+
+ for (i = 0; (p = _airport_default_block_data[i]) != NULL; i++) {
+ // If we are doing a helicopter service, avoid building
+ // airports where they can't land.
+ if (heli && GetAirport(p->attr)->acc_planes == AIRCRAFT_ONLY) continue;
+
+ *cost = AiDoBuildDefaultAirportBlock(tile, p, 0);
+ if (!CmdFailed(*cost) && AiCheckAirportResources(tile, p, cargo))
+ return i;
+ }
+ return -1;
+}
+
+static void AiStateBuildDefaultAirportBlocks(Player *p)
+{
+ int i, j;
+ AiBuildRec *aib;
+ int rule;
+ int32 cost;
+
+ // time out?
+ if (++p->ai.timeout_counter == 1388) {
+ p->ai.state = AIS_0;
+ return;
+ }
+
+ // do the following 8 times
+ i = 8;
+ do {
+ // check if we can build the default
+ aib = &p->ai.src;
+ j = p->ai.num_build_rec;
+ do {
+ // this item has already been built?
+ if (aib->cur_building_rule != 255) continue;
+
+ // adjust the coordinate randomly,
+ // to make sure that we find a position.
+ aib->use_tile = AdjustTileCoordRandomly(aib->spec_tile, aib->rand_rng);
+
+ // check if the aircraft stuff can be built there.
+ rule = AiFindBestDefaultAirportBlock(aib->use_tile, aib->cargo, p->ai.build_kind, &cost);
+
+// SetRedErrorSquare(aib->use_tile);
+
+ if (rule == -1) {
+ // cannot build, terraform after a while
+ if (p->ai.state_counter >= 600) {
+ AiDoTerraformLand(aib->use_tile, Random()&3, 3, (int8)p->ai.state_mode);
+ }
+ // also try the other terraform direction
+ if (++p->ai.state_counter >= 1000) {
+ p->ai.state_counter = 0;
+ p->ai.state_mode = -p->ai.state_mode;
+ }
+ } else if (CheckPlayerHasMoney(cost) && AiCheckBlockDistances(p,aib->use_tile)) {
+ // player has money, build it.
+ int32 r;
+
+ aib->cur_building_rule = rule;
+
+ r = AiDoBuildDefaultAirportBlock(
+ aib->use_tile,
+ _airport_default_block_data[rule],
+ DC_EXEC | DC_NO_TOWN_RATING
+ );
+ assert(!CmdFailed(r));
+ }
+ } while (++aib,--j);
+ } while (--i);
+
+ // check if we're done with all of them
+ aib = &p->ai.src;
+ j = p->ai.num_build_rec;
+ do {
+ if (aib->cur_building_rule == 255) return;
+ } while (++aib,--j);
+
+ // yep, all are done. switch state.
+ p->ai.state = AIS_BUILD_AIRCRAFT_VEHICLES;
+}
+
+static StationID AiGetStationIdFromAircraftBlock(TileIndex tile, int id)
+{
+ const AiDefaultBlockData *p = _airport_default_block_data[id];
+ while (p->mode != 1) p++;
+ return GetStationIndex(TILE_ADD(tile, ToTileIndexDiff(p->tileoffs)));
+}
+
+static void AiStateBuildAircraftVehicles(Player *p)
+{
+ const AiDefaultBlockData *ptr;
+ TileIndex tile;
+ EngineID veh;
+ int i;
+ VehicleID loco_id;
+
+ ptr = _airport_default_block_data[p->ai.src.cur_building_rule];
+ for (; ptr->mode != 0; ptr++) {}
+
+ tile = TILE_ADD(p->ai.src.use_tile, ToTileIndexDiff(ptr->tileoffs));
+
+ veh = AiChooseAircraftToBuild(p->player_money, p->ai.build_kind != 0 ? 0 : AIR_CTOL);
+ if (veh == INVALID_ENGINE) return;
+
+ /* XXX - Have the AI pick the hangar terminal in an airport. Eg get airport-type
+ * and offset to the FIRST depot because the AI picks the st->xy tile */
+ tile += ToTileIndexDiff(GetAirport(GetStationByTile(tile)->airport_type)->airport_depots[0]);
+ if (CmdFailed(DoCommand(tile, veh, 0, DC_EXEC, CMD_BUILD_AIRCRAFT))) return;
+ loco_id = _new_vehicle_id;
+
+ for (i = 0; p->ai.order_list_blocks[i] != 0xFF; i++) {
+ AiBuildRec *aib = (&p->ai.src) + p->ai.order_list_blocks[i];
+ bool is_pass = (p->ai.cargo_type == CT_PASSENGERS || p->ai.cargo_type == CT_MAIL);
+ Order order;
+
+ order.type = OT_GOTO_STATION;
+ order.flags = 0;
+ order.dest = AiGetStationIdFromAircraftBlock(aib->use_tile, aib->cur_building_rule);
+
+ if (!is_pass && i == 1) order.flags |= OF_UNLOAD;
+ if (p->ai.num_want_fullload != 0 && (is_pass || i == 0))
+ order.flags |= OF_FULL_LOAD;
+
+ DoCommand(0, loco_id + (i << 16), PackOrder(&order), DC_EXEC, CMD_INSERT_ORDER);
+ }
+
+ DoCommand(0, loco_id, 0, DC_EXEC, CMD_START_STOP_AIRCRAFT);
+
+ DoCommand(0, loco_id, _ai_service_interval, DC_EXEC, CMD_CHANGE_SERVICE_INT);
+
+ if (p->ai.num_want_fullload != 0) p->ai.num_want_fullload--;
+
+ if (--p->ai.num_loco_to_build == 0) p->ai.state = AIS_0;
+}
+
+static void AiStateCheckShipStuff(Player *p)
+{
+ // XXX
+ error("!AiStateCheckShipStuff");
+}
+
+static void AiStateBuildDefaultShipBlocks(Player *p)
+{
+ // XXX
+ error("!AiStateBuildDefaultShipBlocks");
+}
+
+static void AiStateDoShipStuff(Player *p)
+{
+ // XXX
+ error("!AiStateDoShipStuff");
+}
+
+static void AiStateSellVeh(Player *p)
+{
+ Vehicle *v = p->ai.cur_veh;
+
+ if (v->owner == _current_player) {
+ if (v->type == VEH_Train) {
+
+ if (!IsTileDepotType(v->tile, TRANSPORT_RAIL) || v->u.rail.track != 0x80 || !(v->vehstatus&VS_STOPPED)) {
+ if (v->current_order.type != OT_GOTO_DEPOT)
+ DoCommand(0, v->index, 0, DC_EXEC, CMD_SEND_TRAIN_TO_DEPOT);
+ goto going_to_depot;
+ }
+
+ // Sell whole train
+ DoCommand(v->tile, v->index, 1, DC_EXEC, CMD_SELL_RAIL_WAGON);
+
+ } else if (v->type == VEH_Road) {
+ if (!IsRoadVehInDepotStopped(v)) {
+ if (v->current_order.type != OT_GOTO_DEPOT)
+ DoCommand(0, v->index, 0, DC_EXEC, CMD_SEND_ROADVEH_TO_DEPOT);
+ goto going_to_depot;
+ }
+
+ DoCommand(0, v->index, 0, DC_EXEC, CMD_SELL_ROAD_VEH);
+ } else if (v->type == VEH_Aircraft) {
+ if (!IsAircraftInHangarStopped(v)) {
+ if (v->current_order.type != OT_GOTO_DEPOT)
+ DoCommand(0, v->index, 0, DC_EXEC, CMD_SEND_AIRCRAFT_TO_HANGAR);
+ goto going_to_depot;
+ }
+
+ DoCommand(0, v->index, 0, DC_EXEC, CMD_SELL_AIRCRAFT);
+ } else if (v->type == VEH_Ship) {
+ // XXX: not implemented
+ error("!v->type == VEH_Ship");
+ }
+ }
+
+ goto return_to_loop;
+going_to_depot:;
+ if (++p->ai.state_counter <= 832) return;
+
+ if (v->current_order.type == OT_GOTO_DEPOT) {
+ v->current_order.type = OT_DUMMY;
+ v->current_order.flags = 0;
+ InvalidateWindow(WC_VEHICLE_VIEW, v->index);
+ }
+return_to_loop:;
+ p->ai.state = AIS_VEH_LOOP;
+}
+
+static void AiStateRemoveStation(Player *p)
+{
+ // Remove stations that aren't in use by any vehicle
+ byte *in_use;
+ const Order *ord;
+ const Station *st;
+ TileIndex tile;
+
+ // Go to this state when we're done.
+ p->ai.state = AIS_1;
+
+ // Get a list of all stations that are in use by a vehicle
+ in_use = malloc(GetMaxStationIndex() + 1);
+ memset(in_use, 0, GetMaxStationIndex() + 1);
+ FOR_ALL_ORDERS(ord) {
+ if (ord->type == OT_GOTO_STATION) in_use[ord->dest] = 1;
+ }
+
+ // Go through all stations and delete those that aren't in use
+ FOR_ALL_STATIONS(st) {
+ if (st->owner == _current_player && !in_use[st->index] &&
+ ( (st->bus_stops != NULL && (tile = st->bus_stops->xy) != 0) ||
+ (st->truck_stops != NULL && (tile = st->truck_stops->xy)) != 0 ||
+ (tile = st->train_tile) != 0 ||
+ (tile = st->dock_tile) != 0 ||
+ (tile = st->airport_tile) != 0)) {
+ DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
+ }
+ }
+
+ free(in_use);
+}
+
+static void AiRemovePlayerRailOrRoad(Player *p, TileIndex tile)
+{
+ TrackBits rails;
+
+ if (IsTileType(tile, MP_RAILWAY)) {
+ if (!IsTileOwner(tile, _current_player)) return;
+
+ if (IsPlainRailTile(tile)) {
+is_rail_crossing:;
+ rails = GetRailTrackStatus(tile);
+
+ if (rails == TRACK_BIT_HORZ || rails == TRACK_BIT_VERT) return;
+
+ if (rails & TRACK_BIT_3WAY_NE) {
+pos_0:
+ if ((GetRailTrackStatus(TILE_MASK(tile - TileDiffXY(1, 0))) & TRACK_BIT_3WAY_SW) == 0) {
+ p->ai.cur_dir_a = 0;
+ p->ai.cur_tile_a = tile;
+ p->ai.state = AIS_REMOVE_SINGLE_RAIL_TILE;
+ return;
+ }
+ }
+
+ if (rails & TRACK_BIT_3WAY_SE) {
+pos_1:
+ if ((GetRailTrackStatus(TILE_MASK(tile + TileDiffXY(0, 1))) & TRACK_BIT_3WAY_NW) == 0) {
+ p->ai.cur_dir_a = 1;
+ p->ai.cur_tile_a = tile;
+ p->ai.state = AIS_REMOVE_SINGLE_RAIL_TILE;
+ return;
+ }
+ }
+
+ if (rails & TRACK_BIT_3WAY_SW) {
+pos_2:
+ if ((GetRailTrackStatus(TILE_MASK(tile + TileDiffXY(1, 0))) & TRACK_BIT_3WAY_NE) == 0) {
+ p->ai.cur_dir_a = 2;
+ p->ai.cur_tile_a = tile;
+ p->ai.state = AIS_REMOVE_SINGLE_RAIL_TILE;
+ return;
+ }
+ }
+
+ if (rails & TRACK_BIT_3WAY_NW) {
+pos_3:
+ if ((GetRailTrackStatus(TILE_MASK(tile - TileDiffXY(0, 1))) & TRACK_BIT_3WAY_SE) == 0) {
+ p->ai.cur_dir_a = 3;
+ p->ai.cur_tile_a = tile;
+ p->ai.state = AIS_REMOVE_SINGLE_RAIL_TILE;
+ return;
+ }
+ }
+ } else {
+ static const byte _depot_bits[] = {0x19,0x16,0x25,0x2A};
+
+ DiagDirection dir = GetRailDepotDirection(tile);
+
+ if (GetRailTrackStatus(tile + TileOffsByDiagDir(dir)) & _depot_bits[dir])
+ return;
+
+ DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
+ }
+ } else if (IsTileType(tile, MP_STREET)) {
+ if (!IsTileOwner(tile, _current_player)) return;
+
+ if (IsLevelCrossing(tile)) goto is_rail_crossing;
+
+ if (GetRoadTileType(tile) == ROAD_TILE_DEPOT) {
+ DiagDirection dir;
+ TileIndex t;
+
+ // Check if there are any stations around.
+ t = tile + TileDiffXY(-1, 0);
+ if (IsTileType(t, MP_STATION) && IsTileOwner(t, _current_player)) return;
+
+ t = tile + TileDiffXY(1, 0);
+ if (IsTileType(t, MP_STATION) && IsTileOwner(t, _current_player)) return;
+
+ t = tile + TileDiffXY(0, -1);
+ if (IsTileType(t, MP_STATION) && IsTileOwner(t, _current_player)) return;
+
+ t = tile + TileDiffXY(0, 1);
+ if (IsTileType(t, MP_STATION) && IsTileOwner(t, _current_player)) return;
+
+ dir = GetRoadDepotDirection(tile);
+
+ DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
+ DoCommand(
+ TILE_MASK(tile + TileOffsByDiagDir(dir)),
+ DiagDirToRoadBits(ReverseDiagDir(dir)),
+ 0,
+ DC_EXEC,
+ CMD_REMOVE_ROAD);
+ }
+ } else if (IsTileType(tile, MP_TUNNELBRIDGE)) {
+ if (!IsTileOwner(tile, _current_player) ||
+ !IsBridge(tile) ||
+ GetBridgeTransportType(tile) != TRANSPORT_RAIL) {
+ return;
+ }
+
+ rails = 0;
+
+ switch (GetBridgeRampDirection(tile)) {
+ default:
+ case DIAGDIR_NE: goto pos_2;
+ case DIAGDIR_SE: goto pos_3;
+ case DIAGDIR_SW: goto pos_0;
+ case DIAGDIR_NW: goto pos_1;
+ }
+ }
+}
+
+static void AiStateRemoveTrack(Player *p)
+{
+ /* Was 1000 for standard 8x8 maps. */
+ int num = MapSizeX() * 4;
+
+ do {
+ TileIndex tile = ++p->ai.state_counter;
+
+ // Iterated all tiles?
+ if (tile >= MapSize()) {
+ p->ai.state = AIS_REMOVE_STATION;
+ return;
+ }
+
+ // Remove player stuff in that tile
+ AiRemovePlayerRailOrRoad(p, tile);
+ if (p->ai.state != AIS_REMOVE_TRACK) return;
+ } while (--num);
+}
+
+static void AiStateRemoveSingleRailTile(Player *p)
+{
+ // Remove until we can't remove more.
+ if (!AiRemoveTileAndGoForward(p)) p->ai.state = AIS_REMOVE_TRACK;
+}
+
+static AiStateAction * const _ai_actions[] = {
+ AiCase0,
+ AiCase1,
+ AiStateVehLoop,
+ AiStateCheckReplaceVehicle,
+ AiStateDoReplaceVehicle,
+ AiStateWantNewRoute,
+
+ AiStateBuildDefaultRailBlocks,
+ AiStateBuildRail,
+ AiStateBuildRailVeh,
+ AiStateDeleteRailBlocks,
+
+ AiStateBuildDefaultRoadBlocks,
+ AiStateBuildRoad,
+ AiStateBuildRoadVehicles,
+ AiStateDeleteRoadBlocks,
+
+ AiStateAirportStuff,
+ AiStateBuildDefaultAirportBlocks,
+ AiStateBuildAircraftVehicles,
+
+ AiStateCheckShipStuff,
+ AiStateBuildDefaultShipBlocks,
+ AiStateDoShipStuff,
+
+ AiStateSellVeh,
+ AiStateRemoveStation,
+ AiStateRemoveTrack,
+
+ AiStateRemoveSingleRailTile
+};
+
+extern void ShowBuyCompanyDialog(uint player);
+
+static void AiHandleTakeover(Player *p)
+{
+ if (p->bankrupt_timeout != 0) {
+ p->bankrupt_timeout -= 8;
+ if (p->bankrupt_timeout > 0) return;
+ p->bankrupt_timeout = 0;
+ DeleteWindowById(WC_BUY_COMPANY, _current_player);
+ if (IsLocalPlayer()) {
+ AskExitToGameMenu();
+ return;
+ }
+ if (IsHumanPlayer(_current_player)) return;
+ }
+
+ if (p->bankrupt_asked == 255) return;
+
+ {
+ uint asked = p->bankrupt_asked;
+ Player *pp, *best_pl = NULL;
+ int32 best_val = -1;
+ uint old_p;
+
+ // Ask the guy with the highest performance hist.
+ FOR_ALL_PLAYERS(pp) {
+ if (pp->is_active &&
+ !(asked&1) &&
+ pp->bankrupt_asked == 0 &&
+ best_val < pp->old_economy[1].performance_history) {
+ best_val = pp->old_economy[1].performance_history;
+ best_pl = pp;
+ }
+ asked>>=1;
+ }
+
+ // Asked all players?
+ if (best_val == -1) {
+ p->bankrupt_asked = 255;
+ return;
+ }
+
+ SETBIT(p->bankrupt_asked, best_pl->index);
+
+ if (best_pl->index == _local_player) {
+ p->bankrupt_timeout = 4440;
+ ShowBuyCompanyDialog(_current_player);
+ return;
+ }
+ if (IsHumanPlayer(best_pl->index)) return;
+
+ // Too little money for computer to buy it?
+ if (best_pl->player_money >> 1 >= p->bankrupt_value) {
+ // Computer wants to buy it.
+ old_p = _current_player;
+ _current_player = p->index;
+ DoCommand(0, old_p, 0, DC_EXEC, CMD_BUY_COMPANY);
+ _current_player = old_p;
+ }
+ }
+}
+
+static void AiAdjustLoan(const Player* p)
+{
+ int32 base = AiGetBasePrice(p);
+
+ if (p->player_money > base * 1400) {
+ // Decrease loan
+ if (p->current_loan != 0) {
+ DoCommand(0, 0, 0, DC_EXEC, CMD_DECREASE_LOAN);
+ }
+ } else if (p->player_money < base * 500) {
+ // Increase loan
+ if (p->current_loan < _economy.max_loan &&
+ p->num_valid_stat_ent >= 2 &&
+ -(p->old_economy[0].expenses+p->old_economy[1].expenses) < base * 60) {
+ DoCommand(0, 0, 0, DC_EXEC, CMD_INCREASE_LOAN);
+ }
+ }
+}
+
+static void AiBuildCompanyHQ(Player *p)
+{
+ TileIndex tile;
+
+ if (p->location_of_house == 0 &&
+ p->last_build_coordinate != 0) {
+ tile = AdjustTileCoordRandomly(p->last_build_coordinate, 8);
+ DoCommand(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_BUILD_COMPANY_HQ);
+ }
+}
+
+
+void AiDoGameLoop(Player *p)
+{
+ if (p->bankrupt_asked != 0) {
+ AiHandleTakeover(p);
+ return;
+ }
+
+ // Ugly hack to make sure the service interval of the AI is good, not looking
+ // to the patch-setting
+ // Also, it takes into account the setting if the service-interval is in days
+ // or in %
+ _ai_service_interval = _patches.servint_ispercent?80:180;
+
+ if (IsHumanPlayer(_current_player)) return;
+
+ AiAdjustLoan(p);
+ AiBuildCompanyHQ(p);
+
+#if 0
+ {
+ static byte old_state = 99;
+ static bool hasdots = false;
+ char *_ai_state_names[]={
+ "AiCase0",
+ "AiCase1",
+ "AiStateVehLoop",
+ "AiStateCheckReplaceVehicle",
+ "AiStateDoReplaceVehicle",
+ "AiStateWantNewRoute",
+ "AiStateBuildDefaultRailBlocks",
+ "AiStateBuildRail",
+ "AiStateBuildRailVeh",
+ "AiStateDeleteRailBlocks",
+ "AiStateBuildDefaultRoadBlocks",
+ "AiStateBuildRoad",
+ "AiStateBuildRoadVehicles",
+ "AiStateDeleteRoadBlocks",
+ "AiStateAirportStuff",
+ "AiStateBuildDefaultAirportBlocks",
+ "AiStateBuildAircraftVehicles",
+ "AiStateCheckShipStuff",
+ "AiStateBuildDefaultShipBlocks",
+ "AiStateDoShipStuff",
+ "AiStateSellVeh",
+ "AiStateRemoveStation",
+ "AiStateRemoveTrack",
+ "AiStateRemoveSingleRailTile"
+ };
+
+ if (p->ai.state != old_state) {
+ if (hasdots)
+ printf("\n");
+ hasdots=false;
+ printf("AiState: %s\n", _ai_state_names[old_state=p->ai.state]);
+ } else {
+ printf(".");
+ hasdots=true;
+ }
+ }
+#endif
+
+ _ai_actions[p->ai.state](p);
+}
diff --git a/src/ai/default/default.h b/src/ai/default/default.h
new file mode 100644
index 000000000..d367d4a72
--- /dev/null
+++ b/src/ai/default/default.h
@@ -0,0 +1,8 @@
+/* $Id$ */
+
+#ifndef DEFAULT_H
+#define DEFAULT_H
+
+void AiDoGameLoop(Player*);
+
+#endif
diff --git a/src/ai/trolly/build.c b/src/ai/trolly/build.c
new file mode 100644
index 000000000..9959d0d04
--- /dev/null
+++ b/src/ai/trolly/build.c
@@ -0,0 +1,324 @@
+/* $Id$ */
+
+#include "../../stdafx.h"
+#include "../../openttd.h"
+#include "../../debug.h"
+#include "../../functions.h"
+#include "../../map.h"
+#include "../../road_map.h"
+#include "../../tile.h"
+#include "../../vehicle.h"
+#include "../../command.h"
+#include "trolly.h"
+#include "../../engine.h"
+#include "../../station.h"
+#include "../../variables.h"
+#include "../../bridge.h"
+#include "../ai.h"
+
+// Build HQ
+// Params:
+// tile : tile where HQ is going to be build
+bool AiNew_Build_CompanyHQ(Player *p, TileIndex tile)
+{
+ if (CmdFailed(AI_DoCommand(tile, 0, 0, DC_AUTO | DC_NO_WATER, CMD_BUILD_COMPANY_HQ)))
+ return false;
+ AI_DoCommand(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_BUILD_COMPANY_HQ);
+ return true;
+}
+
+
+// Build station
+// Params:
+// type : AI_TRAIN/AI_BUS/AI_TRUCK : indicates the type of station
+// tile : tile where station is going to be build
+// length : in case of AI_TRAIN: length of station
+// numtracks : in case of AI_TRAIN: tracks of station
+// direction : the direction of the station
+// flag : flag passed to DoCommand (normally 0 to get the cost or DC_EXEC to build it)
+int AiNew_Build_Station(Player *p, byte type, TileIndex tile, byte length, byte numtracks, byte direction, byte flag)
+{
+ if (type == AI_TRAIN)
+ return AI_DoCommand(tile, direction + (numtracks << 8) + (length << 16), 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_RAILROAD_STATION);
+
+ if (type == AI_BUS)
+ return AI_DoCommand(tile, direction, RS_BUS, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD_STOP);
+
+ return AI_DoCommand(tile, direction, RS_TRUCK, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD_STOP);
+}
+
+
+// Builds a brdige. The second best out of the ones available for this player
+// Params:
+// tile_a : starting point
+// tile_b : end point
+// flag : flag passed to DoCommand
+int AiNew_Build_Bridge(Player *p, TileIndex tile_a, TileIndex tile_b, byte flag)
+{
+ int bridge_type, bridge_len, type, type2;
+
+ // Find a good bridgetype (the best money can buy)
+ bridge_len = GetBridgeLength(tile_a, tile_b);
+ type = type2 = 0;
+ for (bridge_type = MAX_BRIDGES-1; bridge_type >= 0; bridge_type--) {
+ if (CheckBridge_Stuff(bridge_type, bridge_len)) {
+ type2 = type;
+ type = bridge_type;
+ // We found two bridges, exit
+ if (type2 != 0) break;
+ }
+ }
+ // There is only one bridge that can be built
+ if (type2 == 0 && type != 0) type2 = type;
+
+ // Now, simply, build the bridge!
+ if (p->ainew.tbt == AI_TRAIN) {
+ return AI_DoCommand(tile_a, tile_b, (0x00 << 8) + type2, flag | DC_AUTO, CMD_BUILD_BRIDGE);
+ } else {
+ return AI_DoCommand(tile_a, tile_b, (0x80 << 8) + type2, flag | DC_AUTO, CMD_BUILD_BRIDGE);
+ }
+}
+
+
+// Build the route part by part
+// Basicly what this function do, is build that amount of parts of the route
+// that go in the same direction. It sets 'part' to the last part of the route builded.
+// The return value is the cost for the builded parts
+//
+// Params:
+// PathFinderInfo : Pointer to the PathFinderInfo used for AiPathFinder
+// part : Which part we need to build
+//
+// TODO: skip already builded road-pieces (e.g.: cityroad)
+int AiNew_Build_RoutePart(Player *p, Ai_PathFinderInfo *PathFinderInfo, byte flag)
+{
+ int part = PathFinderInfo->position;
+ byte *route_extra = PathFinderInfo->route_extra;
+ TileIndex *route = PathFinderInfo->route;
+ int dir;
+ int old_dir = -1;
+ int cost = 0;
+ int res;
+ // We need to calculate the direction with the parent of the parent.. so we skip
+ // the first pieces and the last piece
+ if (part < 1) part = 1;
+ // When we are done, stop it
+ if (part >= PathFinderInfo->route_length - 1) {
+ PathFinderInfo->position = -2;
+ return 0;
+ }
+
+
+ if (PathFinderInfo->rail_or_road) {
+ // Tunnel code
+ if ((AI_PATHFINDER_FLAG_TUNNEL & route_extra[part]) != 0) {
+ cost += AI_DoCommand(route[part], 0, 0, flag, CMD_BUILD_TUNNEL);
+ PathFinderInfo->position++;
+ // TODO: problems!
+ if (CmdFailed(cost)) {
+ DEBUG(ai, 0, "[BuildPath] tunnel could not be built (0x%X)", route[part]);
+ return 0;
+ }
+ return cost;
+ }
+ // Bridge code
+ if ((AI_PATHFINDER_FLAG_BRIDGE & route_extra[part]) != 0) {
+ cost += AiNew_Build_Bridge(p, route[part], route[part-1], flag);
+ PathFinderInfo->position++;
+ // TODO: problems!
+ if (CmdFailed(cost)) {
+ DEBUG(ai, 0, "[BuildPath] bridge could not be built (0x%X, 0x%X)", route[part], route[part - 1]);
+ return 0;
+ }
+ return cost;
+ }
+
+ // Build normal rail
+ // Keep it doing till we go an other way
+ if (route_extra[part - 1] == 0 && route_extra[part] == 0) {
+ while (route_extra[part] == 0) {
+ // Get the current direction
+ dir = AiNew_GetRailDirection(route[part-1], route[part], route[part+1]);
+ // Is it the same as the last one?
+ if (old_dir != -1 && old_dir != dir) break;
+ old_dir = dir;
+ // Build the tile
+ res = AI_DoCommand(route[part], 0, dir, flag, CMD_BUILD_SINGLE_RAIL);
+ if (CmdFailed(res)) {
+ // Problem.. let's just abort it all!
+ p->ainew.state = AI_STATE_NOTHING;
+ return 0;
+ }
+ cost += res;
+ // Go to the next tile
+ part++;
+ // Check if it is still in range..
+ if (part >= PathFinderInfo->route_length - 1) break;
+ }
+ part--;
+ }
+ // We want to return the last position, so we go back one
+ PathFinderInfo->position = part;
+ } else {
+ // Tunnel code
+ if ((AI_PATHFINDER_FLAG_TUNNEL & route_extra[part]) != 0) {
+ cost += AI_DoCommand(route[part], 0x200, 0, flag, CMD_BUILD_TUNNEL);
+ PathFinderInfo->position++;
+ // TODO: problems!
+ if (CmdFailed(cost)) {
+ DEBUG(ai, 0, "[BuildPath] tunnel could not be built (0x%X)", route[part]);
+ return 0;
+ }
+ return cost;
+ }
+ // Bridge code
+ if ((AI_PATHFINDER_FLAG_BRIDGE & route_extra[part]) != 0) {
+ cost += AiNew_Build_Bridge(p, route[part], route[part+1], flag);
+ PathFinderInfo->position++;
+ // TODO: problems!
+ if (CmdFailed(cost)) {
+ DEBUG(ai, 0, "[BuildPath] bridge could not be built (0x%X, 0x%X)", route[part], route[part + 1]);
+ return 0;
+ }
+ return cost;
+ }
+
+ // Build normal road
+ // Keep it doing till we go an other way
+ // EnsureNoVehicle makes sure we don't build on a tile where a vehicle is. This way
+ // it will wait till the vehicle is gone..
+ if (route_extra[part-1] == 0 && route_extra[part] == 0 && (flag != DC_EXEC || EnsureNoVehicle(route[part]))) {
+ while (route_extra[part] == 0 && (flag != DC_EXEC || EnsureNoVehicle(route[part]))) {
+ // Get the current direction
+ dir = AiNew_GetRoadDirection(route[part-1], route[part], route[part+1]);
+ // Is it the same as the last one?
+ if (old_dir != -1 && old_dir != dir) break;
+ old_dir = dir;
+ // There is already some road, and it is a bridge.. don't build!!!
+ if (!IsTileType(route[part], MP_TUNNELBRIDGE)) {
+ // Build the tile
+ res = AI_DoCommand(route[part], dir, 0, flag | DC_NO_WATER, CMD_BUILD_ROAD);
+ // Currently, we ignore CMD_ERRORs!
+ if (CmdFailed(res) && flag == DC_EXEC && !IsTileType(route[part], MP_STREET) && !EnsureNoVehicle(route[part])) {
+ // Problem.. let's just abort it all!
+ DEBUG(ai, 0, "[BuidPath] route building failed at tile 0x%X, aborting", route[part]);
+ p->ainew.state = AI_STATE_NOTHING;
+ return 0;
+ }
+
+ if (!CmdFailed(res)) cost += res;
+ }
+ // Go to the next tile
+ part++;
+ // Check if it is still in range..
+ if (part >= PathFinderInfo->route_length - 1) break;
+ }
+ part--;
+ // We want to return the last position, so we go back one
+ }
+ if (!EnsureNoVehicle(route[part]) && flag == DC_EXEC) part--;
+ PathFinderInfo->position = part;
+ }
+
+ return cost;
+}
+
+
+// This functions tries to find the best vehicle for this type of cargo
+// It returns INVALID_ENGINE if not suitable engine is found
+EngineID AiNew_PickVehicle(Player *p)
+{
+ if (p->ainew.tbt == AI_TRAIN) {
+ // Not supported yet
+ return INVALID_ENGINE;
+ } else {
+ EngineID best_veh_index = INVALID_ENGINE;
+ int32 best_veh_rating = 0;
+ EngineID start = ROAD_ENGINES_INDEX;
+ EngineID end = ROAD_ENGINES_INDEX + NUM_ROAD_ENGINES;
+ EngineID i;
+
+ /* Loop through all road vehicles */
+ for (i = start; i != end; i++) {
+ const RoadVehicleInfo *rvi = RoadVehInfo(i);
+ const Engine* e = GetEngine(i);
+ int32 rating;
+ int32 ret;
+
+ /* Skip vehicles which can't take our cargo type */
+ if (rvi->cargo_type != p->ainew.cargo && !CanRefitTo(i, p->ainew.cargo)) continue;
+
+ // Is it availiable?
+ // Also, check if the reliability of the vehicle is above the AI_VEHICLE_MIN_RELIABILTY
+ if (!HASBIT(e->player_avail, _current_player) || e->reliability * 100 < AI_VEHICLE_MIN_RELIABILTY << 16) continue;
+
+ /* Rate and compare the engine by speed & capacity */
+ rating = rvi->max_speed * rvi->capacity;
+ if (rating <= best_veh_rating) continue;
+
+ // Can we build it?
+ ret = AI_DoCommand(0, i, 0, DC_QUERY_COST, CMD_BUILD_ROAD_VEH);
+ if (CmdFailed(ret)) continue;
+
+ best_veh_rating = rating;
+ best_veh_index = i;
+ }
+
+ return best_veh_index;
+ }
+}
+
+
+void CcAI(bool success, TileIndex tile, uint32 p1, uint32 p2)
+{
+ Player* p = GetPlayer(_current_player);
+
+ if (success) {
+ p->ainew.state = AI_STATE_GIVE_ORDERS;
+ p->ainew.veh_id = _new_vehicle_id;
+
+ if (GetVehicle(p->ainew.veh_id)->cargo_type != p->ainew.cargo) {
+ /* Cargo type doesn't match, so refit it */
+ if (CmdFailed(DoCommand(tile, p->ainew.veh_id, p->ainew.cargo, DC_EXEC, CMD_REFIT_ROAD_VEH))) {
+ /* Refit failed, so sell the vehicle */
+ DoCommand(tile, p->ainew.veh_id, 0, DC_EXEC, CMD_SELL_ROAD_VEH);
+ p->ainew.state = AI_STATE_NOTHING;
+ }
+ }
+ } else {
+ /* XXX this should be handled more gracefully */
+ p->ainew.state = AI_STATE_NOTHING;
+ }
+}
+
+
+// Builds the best vehicle possible
+int AiNew_Build_Vehicle(Player *p, TileIndex tile, byte flag)
+{
+ EngineID i = AiNew_PickVehicle(p);
+
+ if (i == INVALID_ENGINE) return CMD_ERROR;
+ if (p->ainew.tbt == AI_TRAIN) return CMD_ERROR;
+
+ if (flag & DC_EXEC) {
+ return AI_DoCommandCc(tile, i, 0, flag, CMD_BUILD_ROAD_VEH, CcAI);
+ } else {
+ return AI_DoCommand(tile, i, 0, flag, CMD_BUILD_ROAD_VEH);
+ }
+}
+
+int AiNew_Build_Depot(Player* p, TileIndex tile, DiagDirection direction, byte flag)
+{
+ int ret, ret2;
+ if (p->ainew.tbt == AI_TRAIN) {
+ return AI_DoCommand(tile, 0, direction, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_TRAIN_DEPOT);
+ } else {
+ ret = AI_DoCommand(tile, direction, 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD_DEPOT);
+ if (CmdFailed(ret)) return ret;
+ // Try to build the road from the depot
+ ret2 = AI_DoCommand(tile + TileOffsByDiagDir(direction), DiagDirToRoadBits(ReverseDiagDir(direction)), 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD);
+ // If it fails, ignore it..
+ if (CmdFailed(ret2)) return ret;
+ return ret + ret2;
+ }
+}
diff --git a/src/ai/trolly/pathfinder.c b/src/ai/trolly/pathfinder.c
new file mode 100644
index 000000000..6ffdf1fec
--- /dev/null
+++ b/src/ai/trolly/pathfinder.c
@@ -0,0 +1,510 @@
+/* $Id$ */
+
+#include "../../stdafx.h"
+#include "../../openttd.h"
+#include "../../bridge_map.h"
+#include "../../debug.h"
+#include "../../functions.h"
+#include "../../map.h"
+#include "../../tile.h"
+#include "../../command.h"
+#include "trolly.h"
+#include "../../depot.h"
+#include "../../tunnel_map.h"
+#include "../../bridge.h"
+#include "../ai.h"
+
+#define TEST_STATION_NO_DIR 0xFF
+
+// Tests if a station can be build on the given spot
+// TODO: make it train compatible
+static bool TestCanBuildStationHere(TileIndex tile, byte dir)
+{
+ Player *p = GetPlayer(_current_player);
+
+ if (dir == TEST_STATION_NO_DIR) {
+ int32 ret;
+ // TODO: currently we only allow spots that can be access from al 4 directions...
+ // should be fixed!!!
+ for (dir = 0; dir < 4; dir++) {
+ ret = AiNew_Build_Station(p, p->ainew.tbt, tile, 1, 1, dir, DC_QUERY_COST);
+ if (!CmdFailed(ret)) return true;
+ }
+ return false;
+ }
+
+ // return true if command succeeded, so the inverse of CmdFailed()
+ return !CmdFailed(AiNew_Build_Station(p, p->ainew.tbt, tile, 1, 1, dir, DC_QUERY_COST));
+}
+
+
+static bool IsRoad(TileIndex tile)
+{
+ return
+ // MP_STREET, but not a road depot?
+ (IsTileType(tile, MP_STREET) && !IsTileDepotType(tile, TRANSPORT_ROAD)) ||
+ (IsTileType(tile, MP_TUNNELBRIDGE) && (
+ (IsTunnel(tile) && GetTunnelTransportType(tile) == TRANSPORT_ROAD) ||
+ (IsBridge(tile) && GetBridgeTransportType(tile) == TRANSPORT_ROAD)
+ ));
+}
+
+
+// Checks if a tile 'a' is between the tiles 'b' and 'c'
+#define TILES_BETWEEN(a, b, c) (TileX(a) >= TileX(b) && TileX(a) <= TileX(c) && TileY(a) >= TileY(b) && TileY(a) <= TileY(c))
+
+
+// Check if the current tile is in our end-area
+static int32 AyStar_AiPathFinder_EndNodeCheck(AyStar *aystar, OpenListNode *current)
+{
+ const Ai_PathFinderInfo* PathFinderInfo = aystar->user_target;
+
+ // It is not allowed to have a station on the end of a bridge or tunnel ;)
+ if (current->path.node.user_data[0] != 0) return AYSTAR_DONE;
+ if (TILES_BETWEEN(current->path.node.tile, PathFinderInfo->end_tile_tl, PathFinderInfo->end_tile_br))
+ if (IsTileType(current->path.node.tile, MP_CLEAR) || IsTileType(current->path.node.tile, MP_TREES))
+ if (current->path.parent == NULL || TestCanBuildStationHere(current->path.node.tile, AiNew_GetDirection(current->path.parent->node.tile, current->path.node.tile)))
+ return AYSTAR_FOUND_END_NODE;
+
+ return AYSTAR_DONE;
+}
+
+
+// Calculates the hash
+// Currently it is a 10 bit hash, so the hash array has a max depth of 6 bits (so 64)
+static uint AiPathFinder_Hash(uint key1, uint key2)
+{
+ return (TileX(key1) & 0x1F) + ((TileY(key1) & 0x1F) << 5);
+}
+
+
+// Clear the memory of all the things
+static void AyStar_AiPathFinder_Free(AyStar *aystar)
+{
+ AyStarMain_Free(aystar);
+ free(aystar);
+}
+
+
+static int32 AyStar_AiPathFinder_CalculateG(AyStar *aystar, AyStarNode *current, OpenListNode *parent);
+static int32 AyStar_AiPathFinder_CalculateH(AyStar *aystar, AyStarNode *current, OpenListNode *parent);
+static void AyStar_AiPathFinder_FoundEndNode(AyStar *aystar, OpenListNode *current);
+static void AyStar_AiPathFinder_GetNeighbours(AyStar *aystar, OpenListNode *current);
+
+
+// This creates the AiPathFinder
+AyStar *new_AyStar_AiPathFinder(int max_tiles_around, Ai_PathFinderInfo *PathFinderInfo)
+{
+ PathNode start_node;
+ uint x;
+ uint y;
+ // Create AyStar
+ AyStar *result = malloc(sizeof(AyStar));
+ init_AyStar(result, AiPathFinder_Hash, 1 << 10);
+ // Set the function pointers
+ result->CalculateG = AyStar_AiPathFinder_CalculateG;
+ result->CalculateH = AyStar_AiPathFinder_CalculateH;
+ result->EndNodeCheck = AyStar_AiPathFinder_EndNodeCheck;
+ result->FoundEndNode = AyStar_AiPathFinder_FoundEndNode;
+ result->GetNeighbours = AyStar_AiPathFinder_GetNeighbours;
+
+ result->free = AyStar_AiPathFinder_Free;
+
+ // Set some information
+ result->loops_per_tick = AI_PATHFINDER_LOOPS_PER_TICK;
+ result->max_path_cost = 0;
+ result->max_search_nodes = AI_PATHFINDER_MAX_SEARCH_NODES;
+
+ // Set the user_data to the PathFinderInfo
+ result->user_target = PathFinderInfo;
+
+ // Set the start node
+ start_node.parent = NULL;
+ start_node.node.direction = 0;
+ start_node.node.user_data[0] = 0;
+
+ // Now we add all the starting tiles
+ for (x = TileX(PathFinderInfo->start_tile_tl); x <= TileX(PathFinderInfo->start_tile_br); x++) {
+ for (y = TileY(PathFinderInfo->start_tile_tl); y <= TileY(PathFinderInfo->start_tile_br); y++) {
+ start_node.node.tile = TileXY(x, y);
+ result->addstart(result, &start_node.node, 0);
+ }
+ }
+
+ return result;
+}
+
+
+// To reuse AyStar we sometimes have to clean all the memory
+void clean_AyStar_AiPathFinder(AyStar *aystar, Ai_PathFinderInfo *PathFinderInfo)
+{
+ PathNode start_node;
+ uint x;
+ uint y;
+
+ aystar->clear(aystar);
+
+ // Set the user_data to the PathFinderInfo
+ aystar->user_target = PathFinderInfo;
+
+ // Set the start node
+ start_node.parent = NULL;
+ start_node.node.direction = 0;
+ start_node.node.user_data[0] = 0;
+ start_node.node.tile = PathFinderInfo->start_tile_tl;
+
+ // Now we add all the starting tiles
+ for (x = TileX(PathFinderInfo->start_tile_tl); x <= TileX(PathFinderInfo->start_tile_br); x++) {
+ for (y = TileY(PathFinderInfo->start_tile_tl); y <= TileY(PathFinderInfo->start_tile_br); y++) {
+ TileIndex tile = TileXY(x, y);
+
+ if (!IsTileType(tile, MP_CLEAR) && !IsTileType(tile, MP_TREES)) continue;
+ if (!TestCanBuildStationHere(tile, TEST_STATION_NO_DIR)) continue;
+ start_node.node.tile = tile;
+ aystar->addstart(aystar, &start_node.node, 0);
+ }
+ }
+}
+
+
+// The h-value, simple calculation
+static int32 AyStar_AiPathFinder_CalculateH(AyStar *aystar, AyStarNode *current, OpenListNode *parent)
+{
+ const Ai_PathFinderInfo* PathFinderInfo = aystar->user_target;
+ int r, r2;
+
+ if (PathFinderInfo->end_direction != AI_PATHFINDER_NO_DIRECTION) {
+ // The station is pointing to a direction, add a tile towards that direction, so the H-value is more accurate
+ r = DistanceManhattan(current->tile, PathFinderInfo->end_tile_tl + TileOffsByDiagDir(PathFinderInfo->end_direction));
+ r2 = DistanceManhattan(current->tile, PathFinderInfo->end_tile_br + TileOffsByDiagDir(PathFinderInfo->end_direction));
+ } else {
+ // No direction, so just get the fastest route to the station
+ r = DistanceManhattan(current->tile, PathFinderInfo->end_tile_tl);
+ r2 = DistanceManhattan(current->tile, PathFinderInfo->end_tile_br);
+ }
+ // See if the bottomright is faster than the topleft..
+ if (r2 < r) r = r2;
+ return r * AI_PATHFINDER_H_MULTIPLER;
+}
+
+
+// We found the end.. let's get the route back and put it in an array
+static void AyStar_AiPathFinder_FoundEndNode(AyStar *aystar, OpenListNode *current)
+{
+ Ai_PathFinderInfo *PathFinderInfo = (Ai_PathFinderInfo*)aystar->user_target;
+ uint i = 0;
+ PathNode *parent = &current->path;
+
+ do {
+ PathFinderInfo->route_extra[i] = parent->node.user_data[0];
+ PathFinderInfo->route[i++] = parent->node.tile;
+ if (i > lengthof(PathFinderInfo->route)) {
+ // We ran out of space for the PathFinder
+ DEBUG(ai, 0, "No more space in pathfinder route[] array");
+ PathFinderInfo->route_length = -1; // -1 indicates out of space
+ return;
+ }
+ parent = parent->parent;
+ } while (parent != NULL);
+ PathFinderInfo->route_length = i;
+ DEBUG(ai, 1, "Found route of %d nodes long in %d nodes of searching", i, Hash_Size(&aystar->ClosedListHash));
+}
+
+
+// What tiles are around us.
+static void AyStar_AiPathFinder_GetNeighbours(AyStar *aystar, OpenListNode *current)
+{
+ uint i;
+ int ret;
+ int dir;
+
+ Ai_PathFinderInfo *PathFinderInfo = (Ai_PathFinderInfo*)aystar->user_target;
+
+ aystar->num_neighbours = 0;
+
+ // Go through all surrounding tiles and check if they are within the limits
+ for (i = 0; i < 4; i++) {
+ TileIndex ctile = current->path.node.tile; // Current tile
+ TileIndex atile = ctile + TileOffsByDiagDir(i); // Adjacent tile
+
+ if (TileX(atile) > 1 && TileX(atile) < MapMaxX() - 1 &&
+ TileY(atile) > 1 && TileY(atile) < MapMaxY() - 1) {
+ // We also directly test if the current tile can connect to this tile..
+ // We do this simply by just building the tile!
+
+ // If the next step is a bridge, we have to enter it the right way
+ if (!PathFinderInfo->rail_or_road && IsRoad(atile)) {
+ if (IsTileType(atile, MP_TUNNELBRIDGE)) {
+ if (IsTunnel(atile)) {
+ if (GetTunnelDirection(atile) != i) continue;
+ } else {
+ if ((_m[atile].m5 & 1U) != DiagDirToAxis(i)) continue;
+ }
+ }
+ }
+ // But also if we are on a bridge, we can only move a certain direction
+ if (!PathFinderInfo->rail_or_road && IsRoad(ctile)) {
+ if (IsTileType(ctile, MP_TUNNELBRIDGE)) {
+ // An existing bridge/tunnel... let's test the direction ;)
+ if ((_m[ctile].m5 & 1U) != (i & 1)) continue;
+ }
+ }
+
+ if ((AI_PATHFINDER_FLAG_BRIDGE & current->path.node.user_data[0]) != 0 ||
+ (AI_PATHFINDER_FLAG_TUNNEL & current->path.node.user_data[0]) != 0) {
+ // We are a bridge/tunnel, how cool!!
+ // This means we can only point forward.. get the direction from the user_data
+ if (i != (current->path.node.user_data[0] >> 8)) continue;
+ }
+ dir = 0;
+
+ // First, check if we have a parent
+ if (current->path.parent == NULL && current->path.node.user_data[0] == 0) {
+ // If not, this means we are at the starting station
+ if (PathFinderInfo->start_direction != AI_PATHFINDER_NO_DIRECTION) {
+ // We do need a direction?
+ if (AiNew_GetDirection(ctile, atile) != PathFinderInfo->start_direction) {
+ // We are not pointing the right way, invalid tile
+ continue;
+ }
+ }
+ } else if (current->path.node.user_data[0] == 0) {
+ if (PathFinderInfo->rail_or_road) {
+ // Rail check
+ dir = AiNew_GetRailDirection(current->path.parent->node.tile, ctile, atile);
+ ret = AI_DoCommand(ctile, 0, dir, DC_AUTO | DC_NO_WATER, CMD_BUILD_SINGLE_RAIL);
+ if (CmdFailed(ret)) continue;
+#ifdef AI_PATHFINDER_NO_90DEGREES_TURN
+ if (current->path.parent->parent != NULL) {
+ // Check if we don't make a 90degree curve
+ int dir1 = AiNew_GetRailDirection(current->path.parent->parent->node.tile, current->path.parent->node.tile, ctile);
+ if (_illegal_curves[dir1] == dir || _illegal_curves[dir] == dir1) {
+ continue;
+ }
+ }
+#endif
+ } else {
+ // Road check
+ dir = AiNew_GetRoadDirection(current->path.parent->node.tile, ctile, atile);
+ if (IsRoad(ctile)) {
+ if (IsTileType(ctile, MP_TUNNELBRIDGE)) {
+ // We have a bridge, how nicely! We should mark it...
+ dir = 0;
+ } else {
+ // It already has road.. check if we miss any bits!
+ if ((_m[ctile].m5 & dir) != dir) {
+ // We do miss some pieces :(
+ dir &= ~_m[ctile].m5;
+ } else {
+ dir = 0;
+ }
+ }
+ }
+ // Only destruct things if it is MP_CLEAR of MP_TREES
+ if (dir != 0) {
+ ret = AI_DoCommand(ctile, dir, 0, DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD);
+ if (CmdFailed(ret)) continue;
+ }
+ }
+ }
+
+ // The tile can be connected
+ aystar->neighbours[aystar->num_neighbours].tile = atile;
+ aystar->neighbours[aystar->num_neighbours].user_data[0] = 0;
+ aystar->neighbours[aystar->num_neighbours++].direction = 0;
+ }
+ }
+
+ // Next step, check for bridges and tunnels
+ if (current->path.parent != NULL && current->path.node.user_data[0] == 0) {
+ // First we get the dir from this tile and his parent
+ DiagDirection dir = AiNew_GetDirection(current->path.parent->node.tile, current->path.node.tile);
+ // It means we can only walk with the track, so the bridge has to be in the same direction
+ TileIndex tile = current->path.node.tile;
+ TileIndex new_tile = tile;
+ Slope tileh = GetTileSlope(tile, NULL);
+
+ // Bridges can only be build on land that is not flat
+ // And if there is a road or rail blocking
+ if (tileh != SLOPE_FLAT ||
+ (PathFinderInfo->rail_or_road && IsTileType(tile + TileOffsByDiagDir(dir), MP_STREET)) ||
+ (!PathFinderInfo->rail_or_road && IsTileType(tile + TileOffsByDiagDir(dir), MP_RAILWAY))) {
+ for (;;) {
+ new_tile += TileOffsByDiagDir(dir);
+
+ // Precheck, is the length allowed?
+ if (!CheckBridge_Stuff(0, GetBridgeLength(tile, new_tile))) break;
+
+ // Check if we hit the station-tile.. we don't like that!
+ if (TILES_BETWEEN(new_tile, PathFinderInfo->end_tile_tl, PathFinderInfo->end_tile_br)) break;
+
+ // Try building the bridge..
+ ret = AI_DoCommand(tile, new_tile, (0 << 8) + (MAX_BRIDGES / 2), DC_AUTO, CMD_BUILD_BRIDGE);
+ if (CmdFailed(ret)) continue;
+ // We can build a bridge here.. add him to the neighbours
+ aystar->neighbours[aystar->num_neighbours].tile = new_tile;
+ aystar->neighbours[aystar->num_neighbours].user_data[0] = AI_PATHFINDER_FLAG_BRIDGE + (dir << 8);
+ aystar->neighbours[aystar->num_neighbours++].direction = 0;
+ // We can only have 12 neighbours, and we need 1 left for tunnels
+ if (aystar->num_neighbours == 11) break;
+ }
+ }
+
+ // Next, check for tunnels!
+ // Tunnels can only be built on slopes corresponding to the direction
+ // For now, we check both sides for this tile.. terraforming gives fuzzy result
+ if ((dir == DIAGDIR_NE && tileh == SLOPE_NE) ||
+ (dir == DIAGDIR_SE && tileh == SLOPE_SE) ||
+ (dir == DIAGDIR_SW && tileh == SLOPE_SW) ||
+ (dir == DIAGDIR_NW && tileh == SLOPE_NW)) {
+ // Now simply check if a tunnel can be build
+ ret = AI_DoCommand(tile, (PathFinderInfo->rail_or_road?0:0x200), 0, DC_AUTO, CMD_BUILD_TUNNEL);
+ tileh = GetTileSlope(_build_tunnel_endtile, NULL);
+ if (!CmdFailed(ret) && (tileh == SLOPE_SW || tileh == SLOPE_SE || tileh == SLOPE_NW || tileh == SLOPE_NE)) {
+ aystar->neighbours[aystar->num_neighbours].tile = _build_tunnel_endtile;
+ aystar->neighbours[aystar->num_neighbours].user_data[0] = AI_PATHFINDER_FLAG_TUNNEL + (dir << 8);
+ aystar->neighbours[aystar->num_neighbours++].direction = 0;
+ }
+ }
+ }
+}
+
+
+extern uint GetRailFoundation(Slope tileh, TrackBits bits); // XXX function declaration in .c
+extern uint GetRoadFoundation(Slope tileh, uint bits); // XXX function declaration in .c
+extern uint GetBridgeFoundation(Slope tileh, Axis); // XXX function declaration in .c
+enum {
+ BRIDGE_NO_FOUNDATION = 1 << 0 | 1 << 3 | 1 << 6 | 1 << 9 | 1 << 12,
+};
+
+// The most important function: it calculates the g-value
+static int32 AyStar_AiPathFinder_CalculateG(AyStar *aystar, AyStarNode *current, OpenListNode *parent)
+{
+ Ai_PathFinderInfo *PathFinderInfo = (Ai_PathFinderInfo*)aystar->user_target;
+ int r, res = 0;
+ Slope tileh = GetTileSlope(current->tile, NULL);
+ Slope parent_tileh = GetTileSlope(parent->path.node.tile, NULL);
+
+ // Check if we hit the end-tile
+ if (TILES_BETWEEN(current->tile, PathFinderInfo->end_tile_tl, PathFinderInfo->end_tile_br)) {
+ // We are at the end-tile, check if we had a direction or something...
+ if (PathFinderInfo->end_direction != AI_PATHFINDER_NO_DIRECTION && AiNew_GetDirection(current->tile, parent->path.node.tile) != PathFinderInfo->end_direction) {
+ // We are not pointing the right way, invalid tile
+ return AYSTAR_INVALID_NODE;
+ }
+ // If it was valid, drop out.. we don't build on the endtile
+ return 0;
+ }
+
+ // Give everything a small penalty
+ res += AI_PATHFINDER_PENALTY;
+
+ if (!PathFinderInfo->rail_or_road) {
+ // Road has the lovely advantage it can use other road... check if
+ // the current tile is road, and if so, give a good bonus
+ if (IsRoad(current->tile)) {
+ res -= AI_PATHFINDER_ROAD_ALREADY_EXISTS_BONUS;
+ }
+ }
+
+ // We should give a penalty when the tile is going up or down.. this is one way to do so!
+ // Too bad we have to count it from the parent.. but that is not so bad.
+ // We also dislike long routes on slopes, since they do not look too realistic
+ // when there is a flat land all around, they are more expensive to build, and
+ // especially they essentially block the ability to connect or cross the road
+ // from one side.
+ if (parent_tileh != SLOPE_FLAT && parent->path.parent != NULL) {
+ // Skip if the tile was from a bridge or tunnel
+ if (parent->path.node.user_data[0] == 0 && current->user_data[0] == 0) {
+ if (PathFinderInfo->rail_or_road) {
+ r = GetRailFoundation(parent_tileh, 1 << AiNew_GetRailDirection(parent->path.parent->node.tile, parent->path.node.tile, current->tile));
+ // Maybe is BRIDGE_NO_FOUNDATION a bit strange here, but it contains just the right information..
+ if (r >= 15 || (r == 0 && HASBIT(BRIDGE_NO_FOUNDATION, tileh))) {
+ res += AI_PATHFINDER_TILE_GOES_UP_PENALTY;
+ } else {
+ res += AI_PATHFINDER_FOUNDATION_PENALTY;
+ }
+ } else {
+ if (!IsRoad(parent->path.node.tile) || !IsTileType(parent->path.node.tile, MP_TUNNELBRIDGE)) {
+ r = GetRoadFoundation(parent_tileh, AiNew_GetRoadDirection(parent->path.parent->node.tile, parent->path.node.tile, current->tile));
+ if (r >= 15 || r == 0) {
+ res += AI_PATHFINDER_TILE_GOES_UP_PENALTY;
+ } else {
+ res += AI_PATHFINDER_FOUNDATION_PENALTY;
+ }
+ }
+ }
+ }
+ }
+
+ // Are we part of a tunnel?
+ if ((AI_PATHFINDER_FLAG_TUNNEL & current->user_data[0]) != 0) {
+ // Tunnels are very expensive when build on long routes..
+ // Ironicly, we are using BridgeCode here ;)
+ r = AI_PATHFINDER_TUNNEL_PENALTY * GetBridgeLength(current->tile, parent->path.node.tile);
+ res += r + (r >> 8);
+ }
+
+ // Are we part of a bridge?
+ if ((AI_PATHFINDER_FLAG_BRIDGE & current->user_data[0]) != 0) {
+ // That means for every length a penalty
+ res += AI_PATHFINDER_BRIDGE_PENALTY * GetBridgeLength(current->tile, parent->path.node.tile);
+ // Check if we are going up or down, first for the starting point
+ // In user_data[0] is at the 8th bit the direction
+ if (!HASBIT(BRIDGE_NO_FOUNDATION, parent_tileh)) {
+ if (GetBridgeFoundation(parent_tileh, (current->user_data[0] >> 8) & 1) < 15) {
+ res += AI_PATHFINDER_BRIDGE_GOES_UP_PENALTY;
+ }
+ }
+ // Second for the end point
+ if (!HASBIT(BRIDGE_NO_FOUNDATION, tileh)) {
+ if (GetBridgeFoundation(tileh, (current->user_data[0] >> 8) & 1) < 15) {
+ res += AI_PATHFINDER_BRIDGE_GOES_UP_PENALTY;
+ }
+ }
+ if (parent_tileh == SLOPE_FLAT) res += AI_PATHFINDER_BRIDGE_GOES_UP_PENALTY;
+ if (tileh == SLOPE_FLAT) res += AI_PATHFINDER_BRIDGE_GOES_UP_PENALTY;
+ }
+
+ // To prevent the AI from taking the fastest way in tiles, but not the fastest way
+ // in speed, we have to give a good penalty to direction changing
+ // This way, we get almost the fastest way in tiles, and a very good speed on the track
+ if (!PathFinderInfo->rail_or_road) {
+ if (parent->path.parent != NULL &&
+ AiNew_GetDirection(current->tile, parent->path.node.tile) != AiNew_GetDirection(parent->path.node.tile, parent->path.parent->node.tile)) {
+ // When road exists, we don't like turning, but its free, so don't be to piggy about it
+ if (IsRoad(parent->path.node.tile)) {
+ res += AI_PATHFINDER_DIRECTION_CHANGE_ON_EXISTING_ROAD_PENALTY;
+ } else {
+ res += AI_PATHFINDER_DIRECTION_CHANGE_PENALTY;
+ }
+ }
+ } else {
+ // For rail we have 1 exeption: diagonal rail..
+ // So we fetch 2 raildirection. That of the current one, and of the one before that
+ if (parent->path.parent != NULL && parent->path.parent->parent != NULL) {
+ int dir1 = AiNew_GetRailDirection(parent->path.parent->node.tile, parent->path.node.tile, current->tile);
+ int dir2 = AiNew_GetRailDirection(parent->path.parent->parent->node.tile, parent->path.parent->node.tile, parent->path.node.tile);
+ // First, see if we are on diagonal path, that is better than straight path
+ if (dir1 > 1) res -= AI_PATHFINDER_DIAGONAL_BONUS;
+
+ // First see if they are different
+ if (dir1 != dir2) {
+ // dir 2 and 3 are 1 diagonal track, and 4 and 5.
+ if (!(((dir1 == 2 || dir1 == 3) && (dir2 == 2 || dir2 == 3)) || ((dir1 == 4 || dir1 == 5) && (dir2 == 4 || dir2 == 5)))) {
+ // It is not, so we changed of direction
+ res += AI_PATHFINDER_DIRECTION_CHANGE_PENALTY;
+ }
+ if (parent->path.parent->parent->parent != NULL) {
+ int dir3 = AiNew_GetRailDirection(parent->path.parent->parent->parent->node.tile, parent->path.parent->parent->node.tile, parent->path.parent->node.tile);
+ // Check if we changed 3 tiles of direction in 3 tiles.. bad!!!
+ if ((dir1 == 0 || dir1 == 1) && dir2 > 1 && (dir3 == 0 || dir3 == 1)) {
+ res += AI_PATHFINDER_CURVE_PENALTY;
+ }
+ }
+ }
+ }
+ }
+
+ return (res < 0) ? 0 : res;
+}
diff --git a/src/ai/trolly/shared.c b/src/ai/trolly/shared.c
new file mode 100644
index 000000000..e683b60ea
--- /dev/null
+++ b/src/ai/trolly/shared.c
@@ -0,0 +1,118 @@
+/* $Id$ */
+
+#include "../../stdafx.h"
+#include "../../openttd.h"
+#include "../../debug.h"
+#include "../../map.h"
+#include "trolly.h"
+#include "../../vehicle.h"
+
+int AiNew_GetRailDirection(TileIndex tile_a, TileIndex tile_b, TileIndex tile_c)
+{
+ // 0 = vert
+ // 1 = horz
+ // 2 = dig up-left
+ // 3 = dig down-right
+ // 4 = dig down-left
+ // 5 = dig up-right
+
+ uint x1 = TileX(tile_a);
+ uint x2 = TileX(tile_b);
+ uint x3 = TileX(tile_c);
+
+ uint y1 = TileY(tile_a);
+ uint y2 = TileY(tile_b);
+ uint y3 = TileY(tile_c);
+
+ if (y1 == y2 && y2 == y3) return 0;
+ if (x1 == x2 && x2 == x3) return 1;
+ if (y2 > y1) return x2 > x3 ? 2 : 4;
+ if (x2 > x1) return y2 > y3 ? 2 : 5;
+ if (y1 > y2) return x2 > x3 ? 5 : 3;
+ if (x1 > x2) return y2 > y3 ? 4 : 3;
+
+ return 0;
+}
+
+int AiNew_GetRoadDirection(TileIndex tile_a, TileIndex tile_b, TileIndex tile_c)
+{
+ int x1, x2, x3;
+ int y1, y2, y3;
+ int r;
+
+ x1 = TileX(tile_a);
+ x2 = TileX(tile_b);
+ x3 = TileX(tile_c);
+
+ y1 = TileY(tile_a);
+ y2 = TileY(tile_b);
+ y3 = TileY(tile_c);
+
+ r = 0;
+
+ if (x1 < x2) r += 8;
+ if (y1 < y2) r += 1;
+ if (x1 > x2) r += 2;
+ if (y1 > y2) r += 4;
+
+ if (x2 < x3) r += 2;
+ if (y2 < y3) r += 4;
+ if (x2 > x3) r += 8;
+ if (y2 > y3) r += 1;
+
+ return r;
+}
+
+// Get's the direction between 2 tiles seen from tile_a
+DiagDirection AiNew_GetDirection(TileIndex tile_a, TileIndex tile_b)
+{
+ if (TileY(tile_a) < TileY(tile_b)) return DIAGDIR_SE;
+ if (TileY(tile_a) > TileY(tile_b)) return DIAGDIR_NW;
+ if (TileX(tile_a) < TileX(tile_b)) return DIAGDIR_SW;
+ return DIAGDIR_NE;
+}
+
+
+// This functions looks up if this vehicle is special for this AI
+// and returns his flag
+uint AiNew_GetSpecialVehicleFlag(Player* p, Vehicle* v)
+{
+ uint i;
+
+ for (i = 0; i < AI_MAX_SPECIAL_VEHICLES; i++) {
+ if (p->ainew.special_vehicles[i].veh_id == v->index) {
+ return p->ainew.special_vehicles[i].flag;
+ }
+ }
+
+ // Not found :(
+ return 0;
+}
+
+
+bool AiNew_SetSpecialVehicleFlag(Player* p, Vehicle* v, uint flag)
+{
+ int new_id = -1;
+ uint i;
+
+ for (i = 0; i < AI_MAX_SPECIAL_VEHICLES; i++) {
+ if (p->ainew.special_vehicles[i].veh_id == v->index) {
+ p->ainew.special_vehicles[i].flag |= flag;
+ return true;
+ }
+ if (new_id == -1 &&
+ p->ainew.special_vehicles[i].veh_id == 0 &&
+ p->ainew.special_vehicles[i].flag == 0) {
+ new_id = i;
+ }
+ }
+
+ // Out of special_vehicle spots :s
+ if (new_id == -1) {
+ DEBUG(ai, 1, "special_vehicles list is too small");
+ return false;
+ }
+ p->ainew.special_vehicles[new_id].veh_id = v->index;
+ p->ainew.special_vehicles[new_id].flag = flag;
+ return true;
+}
diff --git a/src/ai/trolly/trolly.c b/src/ai/trolly/trolly.c
new file mode 100644
index 000000000..35115a880
--- /dev/null
+++ b/src/ai/trolly/trolly.c
@@ -0,0 +1,1353 @@
+/* $Id$ */
+
+/*
+ * This AI was created as a direct reaction to the big demand for some good AIs
+ * in OTTD. Too bad it never left alpha-stage, and it is considered dead in its
+ * current form.
+ * By the time of writing this, we, the creator of this AI and a good friend of
+ * mine, are designing a whole new AI-system that allows us to create AIs
+ * easier and without all the fuzz we encountered while I was working on this
+ * AI. By the time that system is finished, you can expect that this AI will
+ * dissapear, because it is pretty obselete and bad programmed.
+ *
+ * Meanwhile I wish you all much fun with this AI; if you are interested as
+ * AI-developer in this AI, I advise you not stare too long to some code, some
+ * things in here really are... strange ;) But in either way: enjoy :)
+ *
+ * -- TrueLight :: 2005-09-01
+ */
+
+#include "../../stdafx.h"
+#include "../../openttd.h"
+#include "../../debug.h"
+#include "../../functions.h"
+#include "../../road_map.h"
+#include "../../station_map.h"
+#include "table/strings.h"
+#include "../../map.h"
+#include "../../tile.h"
+#include "../../command.h"
+#include "trolly.h"
+#include "../../town.h"
+#include "../../industry.h"
+#include "../../station.h"
+#include "../../engine.h"
+#include "../../gui.h"
+#include "../../depot.h"
+#include "../../vehicle.h"
+#include "../../date.h"
+#include "../ai.h"
+
+// This function is called after StartUp. It is the init of an AI
+static void AiNew_State_FirstTime(Player *p)
+{
+ // This assert is used to protect those function from misuse
+ // You have quickly a small mistake in the state-array
+ // With that, everything would go wrong. Finding that, is almost impossible
+ // With this assert, that problem can never happen.
+ assert(p->ainew.state == AI_STATE_FIRST_TIME);
+ // We first have to init some things
+
+ if (_current_player == 1) ShowErrorMessage(INVALID_STRING_ID, TEMP_AI_IN_PROGRESS, 0, 0);
+
+ // The PathFinder (AyStar)
+ // TODO: Maybe when an AI goes bankrupt, this is de-init
+ // or when coming from a savegame.. should be checked out!
+ p->ainew.path_info.start_tile_tl = 0;
+ p->ainew.path_info.start_tile_br = 0;
+ p->ainew.path_info.end_tile_tl = 0;
+ p->ainew.path_info.end_tile_br = 0;
+ p->ainew.pathfinder = new_AyStar_AiPathFinder(12, &p->ainew.path_info);
+
+ p->ainew.idle = 0;
+ p->ainew.last_vehiclecheck_date = _date;
+
+ // We ALWAYS start with a bus route.. just some basic money ;)
+ p->ainew.action = AI_ACTION_BUS_ROUTE;
+
+ // Let's popup the news, and after that, start building..
+ p->ainew.state = AI_STATE_WAKE_UP;
+}
+
+
+// This function just waste some time
+// It keeps it more real. The AI can build on such tempo no normal user
+// can ever keep up with that. The competitor_speed already delays a bit
+// but after the AI finished a track it really needs to go to sleep.
+//
+// Let's say, we sleep between one and three days if the AI is put on Very Fast.
+// This means that on Very Slow it will be between 16 and 48 days.. slow enough?
+static void AiNew_State_Nothing(Player *p)
+{
+ assert(p->ainew.state == AI_STATE_NOTHING);
+ // If we are done idling, start over again
+ if (p->ainew.idle == 0) p->ainew.idle = AI_RandomRange(DAY_TICKS * 2) + DAY_TICKS;
+ if (--p->ainew.idle == 0) {
+ // We are done idling.. what you say? Let's do something!
+ // I mean.. the next tick ;)
+ p->ainew.state = AI_STATE_WAKE_UP;
+ }
+}
+
+
+// This function picks out a task we are going to do.
+// Currently supported:
+// - Make new route
+// - Check route
+// - Build HQ
+static void AiNew_State_WakeUp(Player *p)
+{
+ int32 money;
+ int c;
+ assert(p->ainew.state == AI_STATE_WAKE_UP);
+ // First, check if we have a HQ
+ if (p->location_of_house == 0) {
+ // We have no HQ yet, build one on a random place
+ // Random till we found a place for it!
+ // TODO: this should not be on a random place..
+ AiNew_Build_CompanyHQ(p, AI_Random() % MapSize());
+ // Enough for now, but we want to come back here the next time
+ // so we do not change any status
+ return;
+ }
+
+ money = p->player_money - AI_MINIMUM_MONEY;
+
+ // Let's pick an action!
+ if (p->ainew.action == AI_ACTION_NONE) {
+ c = AI_Random() & 0xFF;
+ if (p->current_loan > 0 &&
+ p->old_economy[1].income > AI_MINIMUM_INCOME_FOR_LOAN &&
+ c < 10) {
+ p->ainew.action = AI_ACTION_REPAY_LOAN;
+ } else if (p->ainew.last_vehiclecheck_date + AI_DAYS_BETWEEN_VEHICLE_CHECKS < _date) {
+ // Check all vehicles once in a while
+ p->ainew.action = AI_ACTION_CHECK_ALL_VEHICLES;
+ p->ainew.last_vehiclecheck_date = _date;
+ } else if (c < 100 && !_patches.ai_disable_veh_roadveh) {
+ // Do we have any spots for road-vehicles left open?
+ if (GetFreeUnitNumber(VEH_Road) <= _patches.max_roadveh) {
+ if (c < 85) {
+ p->ainew.action = AI_ACTION_TRUCK_ROUTE;
+ } else {
+ p->ainew.action = AI_ACTION_BUS_ROUTE;
+ }
+ }
+#if 0
+ } else if (c < 200 && !_patches.ai_disable_veh_train) {
+ if (GetFreeUnitNumber(VEH_Train) <= _patches.max_trains) {
+ p->ainew.action = AI_ACTION_TRAIN_ROUTE;
+ }
+#endif
+ }
+
+ p->ainew.counter = 0;
+ }
+
+ if (p->ainew.counter++ > AI_MAX_TRIES_FOR_SAME_ROUTE) {
+ p->ainew.action = AI_ACTION_NONE;
+ return;
+ }
+
+ if (_patches.ai_disable_veh_roadveh && (
+ p->ainew.action == AI_ACTION_BUS_ROUTE ||
+ p->ainew.action == AI_ACTION_TRUCK_ROUTE
+ )) {
+ p->ainew.action = AI_ACTION_NONE;
+ return;
+ }
+
+ if (p->ainew.action == AI_ACTION_REPAY_LOAN &&
+ money > AI_MINIMUM_LOAN_REPAY_MONEY) {
+ // We start repaying some money..
+ p->ainew.state = AI_STATE_REPAY_MONEY;
+ return;
+ }
+
+ if (p->ainew.action == AI_ACTION_CHECK_ALL_VEHICLES) {
+ p->ainew.state = AI_STATE_CHECK_ALL_VEHICLES;
+ return;
+ }
+
+ // It is useless to start finding a route if we don't have enough money
+ // to build the route anyway..
+ if (p->ainew.action == AI_ACTION_BUS_ROUTE &&
+ money > AI_MINIMUM_BUS_ROUTE_MONEY) {
+ if (GetFreeUnitNumber(VEH_Road) > _patches.max_roadveh) {
+ p->ainew.action = AI_ACTION_NONE;
+ return;
+ }
+ p->ainew.cargo = AI_NEED_CARGO;
+ p->ainew.state = AI_STATE_LOCATE_ROUTE;
+ p->ainew.tbt = AI_BUS; // Bus-route
+ return;
+ }
+ if (p->ainew.action == AI_ACTION_TRUCK_ROUTE &&
+ money > AI_MINIMUM_TRUCK_ROUTE_MONEY) {
+ if (GetFreeUnitNumber(VEH_Road) > _patches.max_roadveh) {
+ p->ainew.action = AI_ACTION_NONE;
+ return;
+ }
+ p->ainew.cargo = AI_NEED_CARGO;
+ p->ainew.last_id = 0;
+ p->ainew.state = AI_STATE_LOCATE_ROUTE;
+ p->ainew.tbt = AI_TRUCK;
+ return;
+ }
+
+ p->ainew.state = AI_STATE_NOTHING;
+}
+
+
+static void AiNew_State_ActionDone(Player *p)
+{
+ p->ainew.action = AI_ACTION_NONE;
+ p->ainew.state = AI_STATE_NOTHING;
+}
+
+
+// Check if a city or industry is good enough to start a route there
+static bool AiNew_Check_City_or_Industry(Player *p, int ic, byte type)
+{
+ if (type == AI_CITY) {
+ const Town* t = GetTown(ic);
+ const Station* st;
+ uint count = 0;
+ int j = 0;
+
+ // We don't like roadconstructions, don't even true such a city
+ if (t->road_build_months != 0) return false;
+
+ // Check if the rating in a city is high enough
+ // If not, take a chance if we want to continue
+ if (t->ratings[_current_player] < 0 && AI_CHANCE16(1,4)) return false;
+
+ if (t->max_pass - t->act_pass < AI_CHECKCITY_NEEDED_CARGO && !AI_CHANCE16(1,AI_CHECKCITY_CITY_CHANCE)) return false;
+
+ // Check if we have build a station in this town the last 6 months
+ // else we don't do it. This is done, because stat updates can be slow
+ // and sometimes it takes up to 4 months before the stats are corectly.
+ // This way we don't get 12 busstations in one city of 100 population ;)
+ FOR_ALL_STATIONS(st) {
+ // Do we own it?
+ if (st->owner == _current_player) {
+ // Are we talking busses?
+ if (p->ainew.tbt == AI_BUS && (FACIL_BUS_STOP & st->facilities) != FACIL_BUS_STOP) continue;
+ // Is it the same city as we are in now?
+ if (st->town != t) continue;
+ // When was this station build?
+ if (_date - st->build_date < AI_CHECKCITY_DATE_BETWEEN) return false;
+ // Cound the amount of stations in this city that we own
+ count++;
+ } else {
+ // We do not own it, request some info about the station
+ // we want to know if this station gets the same good. If so,
+ // we want to know its rating. If it is too high, we are not going
+ // to build there
+ if (!st->goods[CT_PASSENGERS].last_speed) continue;
+ // Is it around our city
+ if (DistanceManhattan(st->xy, t->xy) > 10) continue;
+ // It does take this cargo.. what is his rating?
+ if (st->goods[CT_PASSENGERS].rating < AI_CHECKCITY_CARGO_RATING) continue;
+ j++;
+ // When this is the first station, we build a second with no problem ;)
+ if (j == 1) continue;
+ // The rating is high.. second station...
+ // a little chance that we still continue
+ // But if there are 3 stations of this size, we never go on...
+ if (j == 2 && AI_CHANCE16(1, AI_CHECKCITY_CARGO_RATING_CHANCE)) continue;
+ // We don't like this station :(
+ return false;
+ }
+ }
+
+ // We are about to add one...
+ count++;
+ // Check if we the city can provide enough cargo for this amount of stations..
+ if (count * AI_CHECKCITY_CARGO_PER_STATION > t->max_pass) return false;
+
+ // All check are okay, so we can build here!
+ return true;
+ }
+ if (type == AI_INDUSTRY) {
+ const Industry* i = GetIndustry(ic);
+ const Station* st;
+ int count = 0;
+ int j = 0;
+
+ if (i->town != NULL && i->town->ratings[_current_player] < 0 && AI_CHANCE16(1,4)) return false;
+
+ // No limits on delevering stations!
+ // Or for industry that does not give anything yet
+ if (i->produced_cargo[0] == CT_INVALID || i->total_production[0] == 0) return true;
+
+ if (i->total_production[0] - i->total_transported[0] < AI_CHECKCITY_NEEDED_CARGO) return false;
+
+ // Check if we have build a station in this town the last 6 months
+ // else we don't do it. This is done, because stat updates can be slow
+ // and sometimes it takes up to 4 months before the stats are corectly.
+ FOR_ALL_STATIONS(st) {
+ // Do we own it?
+ if (st->owner == _current_player) {
+ // Are we talking trucks?
+ if (p->ainew.tbt == AI_TRUCK && (FACIL_TRUCK_STOP & st->facilities) != FACIL_TRUCK_STOP) continue;
+ // Is it the same city as we are in now?
+ if (st->town != i->town) continue;
+ // When was this station build?
+ if (_date - st->build_date < AI_CHECKCITY_DATE_BETWEEN) return false;
+ // Cound the amount of stations in this city that we own
+ count++;
+ } else {
+ // We do not own it, request some info about the station
+ // we want to know if this station gets the same good. If so,
+ // we want to know its rating. If it is too high, we are not going
+ // to build there
+ if (i->produced_cargo[0] == CT_INVALID) continue;
+ // It does not take this cargo
+ if (!st->goods[i->produced_cargo[0]].last_speed) continue;
+ // Is it around our industry
+ if (DistanceManhattan(st->xy, i->xy) > 5) continue;
+ // It does take this cargo.. what is his rating?
+ if (st->goods[i->produced_cargo[0]].rating < AI_CHECKCITY_CARGO_RATING) continue;
+ j++;
+ // The rating is high.. a little chance that we still continue
+ // But if there are 2 stations of this size, we never go on...
+ if (j == 1 && AI_CHANCE16(1, AI_CHECKCITY_CARGO_RATING_CHANCE)) continue;
+ // We don't like this station :(
+ return false;
+ }
+ }
+
+ // We are about to add one...
+ count++;
+ // Check if we the city can provide enough cargo for this amount of stations..
+ if (count * AI_CHECKCITY_CARGO_PER_STATION > i->total_production[0]) return false;
+
+ // All check are okay, so we can build here!
+ return true;
+ }
+
+ return true;
+}
+
+
+// This functions tries to locate a good route
+static void AiNew_State_LocateRoute(Player *p)
+{
+ assert(p->ainew.state == AI_STATE_LOCATE_ROUTE);
+ // For now, we only support PASSENGERS, CITY and BUSSES
+
+ // We don't have a route yet
+ if (p->ainew.cargo == AI_NEED_CARGO) {
+ p->ainew.new_cost = 0; // No cost yet
+ p->ainew.temp = -1;
+ // Reset the counter
+ p->ainew.counter = 0;
+
+ p->ainew.from_ic = -1;
+ p->ainew.to_ic = -1;
+ if (p->ainew.tbt == AI_BUS) {
+ // For now we only have a passenger route
+ p->ainew.cargo = CT_PASSENGERS;
+
+ // Find a route to cities
+ p->ainew.from_type = AI_CITY;
+ p->ainew.to_type = AI_CITY;
+ } else if (p->ainew.tbt == AI_TRUCK) {
+ p->ainew.cargo = AI_NO_CARGO;
+
+ p->ainew.from_type = AI_INDUSTRY;
+ p->ainew.to_type = AI_INDUSTRY;
+ }
+
+ // Now we are doing initing, we wait one tick
+ return;
+ }
+
+ // Increase the counter and abort if it is taking too long!
+ p->ainew.counter++;
+ if (p->ainew.counter > AI_LOCATE_ROUTE_MAX_COUNTER) {
+ // Switch back to doing nothing!
+ p->ainew.state = AI_STATE_NOTHING;
+ return;
+ }
+
+ // We are going to locate a city from where we are going to connect
+ if (p->ainew.from_ic == -1) {
+ if (p->ainew.temp == -1) {
+ // First, we pick a random spot to search from
+ if (p->ainew.from_type == AI_CITY) {
+ p->ainew.temp = AI_RandomRange(GetMaxTownIndex() + 1);
+ } else {
+ p->ainew.temp = AI_RandomRange(GetMaxIndustryIndex() + 1);
+ }
+ }
+
+ if (!AiNew_Check_City_or_Industry(p, p->ainew.temp, p->ainew.from_type)) {
+ // It was not a valid city
+ // increase the temp with one, and return. We will come back later here
+ // to try again
+ p->ainew.temp++;
+ if (p->ainew.from_type == AI_CITY) {
+ if (p->ainew.temp > GetMaxTownIndex()) p->ainew.temp = 0;
+ } else {
+ if (p->ainew.temp > GetMaxIndustryIndex()) p->ainew.temp = 0;
+ }
+
+ // Don't do an attempt if we are trying the same id as the last time...
+ if (p->ainew.last_id == p->ainew.temp) return;
+ p->ainew.last_id = p->ainew.temp;
+
+ return;
+ }
+
+ // We found a good city/industry, save the data of it
+ p->ainew.from_ic = p->ainew.temp;
+
+ // Start the next tick with finding a to-city
+ p->ainew.temp = -1;
+ return;
+ }
+
+ // Find a to-city
+ if (p->ainew.temp == -1) {
+ // First, we pick a random spot to search to
+ if (p->ainew.to_type == AI_CITY) {
+ p->ainew.temp = AI_RandomRange(GetMaxTownIndex() + 1);
+ } else {
+ p->ainew.temp = AI_RandomRange(GetMaxIndustryIndex() + 1);
+ }
+ }
+
+ // The same city is not allowed
+ // Also check if the city is valid
+ if (p->ainew.temp != p->ainew.from_ic && AiNew_Check_City_or_Industry(p, p->ainew.temp, p->ainew.to_type)) {
+ // Maybe it is valid..
+
+ /* We need to know if they are not to far apart from eachother..
+ * We do that by checking how much cargo we have to move and how long the
+ * route is.
+ */
+
+ if (p->ainew.from_type == AI_CITY && p->ainew.tbt == AI_BUS) {
+ const Town* town_from = GetTown(p->ainew.from_ic);
+ const Town* town_temp = GetTown(p->ainew.temp);
+ uint distance = DistanceManhattan(town_from->xy, town_temp->xy);
+ int max_cargo;
+
+ max_cargo = town_from->max_pass + town_temp->max_pass;
+ max_cargo -= town_from->act_pass + town_temp->act_pass;
+
+ // max_cargo is now the amount of cargo we can move between the two cities
+ // If it is more than the distance, we allow it
+ if (distance <= max_cargo * AI_LOCATEROUTE_BUS_CARGO_DISTANCE) {
+ // We found a good city/industry, save the data of it
+ p->ainew.to_ic = p->ainew.temp;
+ p->ainew.state = AI_STATE_FIND_STATION;
+
+ DEBUG(ai, 1, "[LocateRoute] found bus-route of %d tiles long (from %d to %d)",
+ distance,
+ p->ainew.from_ic,
+ p->ainew.temp
+ );
+
+ p->ainew.from_tile = 0;
+ p->ainew.to_tile = 0;
+
+ return;
+ }
+ } else if (p->ainew.tbt == AI_TRUCK) {
+ const Industry* ind_from = GetIndustry(p->ainew.from_ic);
+ const Industry* ind_temp = GetIndustry(p->ainew.temp);
+ bool found = false;
+ int max_cargo = 0;
+ uint i;
+
+ // TODO: in max_cargo, also check other cargo (beside [0])
+ // First we check if the from_ic produces cargo that this ic accepts
+ if (ind_from->produced_cargo[0] != CT_INVALID && ind_from->total_production[0] != 0) {
+ for (i = 0; i < lengthof(ind_temp->accepts_cargo); i++) {
+ if (ind_temp->accepts_cargo[i] == CT_INVALID) break;
+ if (ind_from->produced_cargo[0] == ind_temp->accepts_cargo[i]) {
+ // Found a compatible industry
+ max_cargo = ind_from->total_production[0] - ind_from->total_transported[0];
+ found = true;
+ p->ainew.from_deliver = true;
+ p->ainew.to_deliver = false;
+ break;
+ }
+ }
+ }
+ if (!found && ind_temp->produced_cargo[0] != CT_INVALID && ind_temp->total_production[0] != 0) {
+ // If not check if the current ic produces cargo that the from_ic accepts
+ for (i = 0; i < lengthof(ind_from->accepts_cargo); i++) {
+ if (ind_from->accepts_cargo[i] == CT_INVALID) break;
+ if (ind_temp->produced_cargo[0] == ind_from->accepts_cargo[i]) {
+ // Found a compatbiel industry
+ found = true;
+ max_cargo = ind_temp->total_production[0] - ind_temp->total_transported[0];
+ p->ainew.from_deliver = false;
+ p->ainew.to_deliver = true;
+ break;
+ }
+ }
+ }
+ if (found) {
+ // Yeah, they are compatible!!!
+ // Check the length against the amount of goods
+ uint distance = DistanceManhattan(ind_from->xy, ind_temp->xy);
+
+ if (distance > AI_LOCATEROUTE_TRUCK_MIN_DISTANCE &&
+ distance <= max_cargo * AI_LOCATEROUTE_TRUCK_CARGO_DISTANCE) {
+ p->ainew.to_ic = p->ainew.temp;
+ if (p->ainew.from_deliver) {
+ p->ainew.cargo = ind_from->produced_cargo[0];
+ } else {
+ p->ainew.cargo = ind_temp->produced_cargo[0];
+ }
+ p->ainew.state = AI_STATE_FIND_STATION;
+
+ DEBUG(ai, 1, "[LocateRoute] found truck-route of %d tiles long (from %d to %d)",
+ distance,
+ p->ainew.from_ic,
+ p->ainew.temp
+ );
+
+ p->ainew.from_tile = 0;
+ p->ainew.to_tile = 0;
+
+ return;
+ }
+ }
+ }
+ }
+
+ // It was not a valid city
+ // increase the temp with one, and return. We will come back later here
+ // to try again
+ p->ainew.temp++;
+ if (p->ainew.to_type == AI_CITY) {
+ if (p->ainew.temp > GetMaxTownIndex()) p->ainew.temp = 0;
+ } else {
+ if (p->ainew.temp > GetMaxIndustryIndex()) p->ainew.temp = 0;
+ }
+
+ // Don't do an attempt if we are trying the same id as the last time...
+ if (p->ainew.last_id == p->ainew.temp) return;
+ p->ainew.last_id = p->ainew.temp;
+}
+
+
+// Check if there are not more than a certain amount of vehicles pointed to a certain
+// station. This to prevent 10 busses going to one station, which gives... problems ;)
+static bool AiNew_CheckVehicleStation(Player *p, Station *st)
+{
+ int count = 0;
+ Vehicle *v;
+
+ // Also check if we don't have already a lot of busses to this city...
+ FOR_ALL_VEHICLES(v) {
+ if (v->owner == _current_player) {
+ const Order *order;
+
+ FOR_VEHICLE_ORDERS(v, order) {
+ if (order->type == OT_GOTO_STATION && GetStation(order->dest) == st) {
+ // This vehicle has this city in its list
+ count++;
+ }
+ }
+ }
+ }
+
+ if (count > AI_CHECK_MAX_VEHICLE_PER_STATION) return false;
+ return true;
+}
+
+// This function finds a good spot for a station
+static void AiNew_State_FindStation(Player *p)
+{
+ TileIndex tile;
+ Station *st;
+ int count = 0;
+ EngineID i;
+ TileIndex new_tile = 0;
+ byte direction = 0;
+ Town *town = NULL;
+ assert(p->ainew.state == AI_STATE_FIND_STATION);
+
+ if (p->ainew.from_tile == 0) {
+ // First we scan for a station in the from-city
+ if (p->ainew.from_type == AI_CITY) {
+ town = GetTown(p->ainew.from_ic);
+ tile = town->xy;
+ } else {
+ tile = GetIndustry(p->ainew.from_ic)->xy;
+ }
+ } else if (p->ainew.to_tile == 0) {
+ // Second we scan for a station in the to-city
+ if (p->ainew.to_type == AI_CITY) {
+ town = GetTown(p->ainew.to_ic);
+ tile = town->xy;
+ } else {
+ tile = GetIndustry(p->ainew.to_ic)->xy;
+ }
+ } else {
+ // Unsupported request
+ // Go to FIND_PATH
+ p->ainew.temp = -1;
+ p->ainew.state = AI_STATE_FIND_PATH;
+ return;
+ }
+
+ // First, we are going to look at the stations that already exist inside the city
+ // If there is enough cargo left in the station, we take that station
+ // If that is not possible, and there are more than 2 stations in the city, abort
+ i = AiNew_PickVehicle(p);
+ // Euhmz, this should not happen _EVER_
+ // Quit finding a route...
+ if (i == INVALID_ENGINE) {
+ p->ainew.state = AI_STATE_NOTHING;
+ return;
+ }
+
+ FOR_ALL_STATIONS(st) {
+ if (st->owner == _current_player) {
+ if (p->ainew.tbt == AI_BUS && (FACIL_BUS_STOP & st->facilities) == FACIL_BUS_STOP) {
+ if (st->town == town) {
+ // Check how much cargo there is left in the station
+ if ((st->goods[p->ainew.cargo].waiting_acceptance & 0xFFF) > RoadVehInfo(i)->capacity * AI_STATION_REUSE_MULTIPLER) {
+ if (AiNew_CheckVehicleStation(p, st)) {
+ // We did found a station that was good enough!
+ new_tile = st->xy;
+ direction = GetRoadStopDir(st->xy);
+ break;
+ }
+ }
+ count++;
+ }
+ }
+ }
+ }
+ // We are going to add a new station...
+ if (new_tile == 0) count++;
+ // No more than 2 stations allowed in a city
+ // This is because only the best 2 stations of one cargo do get any cargo
+ if (count > 2) {
+ p->ainew.state = AI_STATE_NOTHING;
+ return;
+ }
+
+ if (new_tile == 0 && p->ainew.tbt == AI_BUS) {
+ uint x, y, i = 0;
+ int r;
+ uint best;
+ uint accepts[NUM_CARGO];
+ TileIndex found_spot[AI_FINDSTATION_TILE_RANGE*AI_FINDSTATION_TILE_RANGE*4];
+ uint found_best[AI_FINDSTATION_TILE_RANGE*AI_FINDSTATION_TILE_RANGE*4];
+ // To find a good spot we scan a range from the center, a get the point
+ // where we get the most cargo and where it is buildable.
+ // TODO: also check for station of myself and make sure we are not
+ // taking eachothers passangers away (bad result when it does not)
+ for (x = TileX(tile) - AI_FINDSTATION_TILE_RANGE; x <= TileX(tile) + AI_FINDSTATION_TILE_RANGE; x++) {
+ for (y = TileY(tile) - AI_FINDSTATION_TILE_RANGE; y <= TileY(tile) + AI_FINDSTATION_TILE_RANGE; y++) {
+ new_tile = TileXY(x, y);
+ if (IsTileType(new_tile, MP_CLEAR) || IsTileType(new_tile, MP_TREES)) {
+ // This tile we can build on!
+ // Check acceptance
+ // XXX - Get the catchment area
+ GetAcceptanceAroundTiles(accepts, new_tile, 1, 1, 4);
+ // >> 3 == 0 means no cargo
+ if (accepts[p->ainew.cargo] >> 3 == 0) continue;
+ // See if we can build the station
+ r = AiNew_Build_Station(p, p->ainew.tbt, new_tile, 0, 0, 0, DC_QUERY_COST);
+ if (CmdFailed(r)) continue;
+ // We can build it, so add it to found_spot
+ found_spot[i] = new_tile;
+ found_best[i++] = accepts[p->ainew.cargo];
+ }
+ }
+ }
+
+ // If i is still zero, we did not find anything
+ if (i == 0) {
+ p->ainew.state = AI_STATE_NOTHING;
+ return;
+ }
+
+ // Go through all the found_best and check which has the highest value
+ best = 0;
+ new_tile = 0;
+
+ for (x = 0; x < i; x++) {
+ if (found_best[x] > best ||
+ (found_best[x] == best && DistanceManhattan(tile, new_tile) > DistanceManhattan(tile, found_spot[x]))) {
+ new_tile = found_spot[x];
+ best = found_best[x];
+ }
+ }
+
+ // See how much it is going to cost us...
+ r = AiNew_Build_Station(p, p->ainew.tbt, new_tile, 0, 0, 0, DC_QUERY_COST);
+ p->ainew.new_cost += r;
+
+ direction = AI_PATHFINDER_NO_DIRECTION;
+ } else if (new_tile == 0 && p->ainew.tbt == AI_TRUCK) {
+ // Truck station locater works differently.. a station can be on any place
+ // as long as it is in range. So we give back code AI_STATION_RANGE
+ // so the pathfinder routine can work it out!
+ new_tile = AI_STATION_RANGE;
+ direction = AI_PATHFINDER_NO_DIRECTION;
+ }
+
+ if (p->ainew.from_tile == 0) {
+ p->ainew.from_tile = new_tile;
+ p->ainew.from_direction = direction;
+ // Now we found thisone, go in for to_tile
+ return;
+ } else if (p->ainew.to_tile == 0) {
+ p->ainew.to_tile = new_tile;
+ p->ainew.to_direction = direction;
+ // K, done placing stations!
+ p->ainew.temp = -1;
+ p->ainew.state = AI_STATE_FIND_PATH;
+ return;
+ }
+}
+
+
+// We try to find a path between 2 points
+static void AiNew_State_FindPath(Player *p)
+{
+ int r;
+ assert(p->ainew.state == AI_STATE_FIND_PATH);
+
+ // First time, init some data
+ if (p->ainew.temp == -1) {
+ // Init path_info
+ if (p->ainew.from_tile == AI_STATION_RANGE) {
+ const Industry* i = GetIndustry(p->ainew.from_ic);
+
+ // For truck routes we take a range around the industry
+ p->ainew.path_info.start_tile_tl = i->xy - TileDiffXY(1, 1);
+ p->ainew.path_info.start_tile_br = i->xy + TileDiffXY(i->width + 1, i->height + 1);
+ p->ainew.path_info.start_direction = p->ainew.from_direction;
+ } else {
+ p->ainew.path_info.start_tile_tl = p->ainew.from_tile;
+ p->ainew.path_info.start_tile_br = p->ainew.from_tile;
+ p->ainew.path_info.start_direction = p->ainew.from_direction;
+ }
+
+ if (p->ainew.to_tile == AI_STATION_RANGE) {
+ const Industry* i = GetIndustry(p->ainew.to_ic);
+
+ p->ainew.path_info.end_tile_tl = i->xy - TileDiffXY(1, 1);
+ p->ainew.path_info.end_tile_br = i->xy + TileDiffXY(i->width + 1, i->height + 1);
+ p->ainew.path_info.end_direction = p->ainew.to_direction;
+ } else {
+ p->ainew.path_info.end_tile_tl = p->ainew.to_tile;
+ p->ainew.path_info.end_tile_br = p->ainew.to_tile;
+ p->ainew.path_info.end_direction = p->ainew.to_direction;
+ }
+
+ p->ainew.path_info.rail_or_road = (p->ainew.tbt == AI_TRAIN);
+
+ // First, clean the pathfinder with our new begin and endpoints
+ clean_AyStar_AiPathFinder(p->ainew.pathfinder, &p->ainew.path_info);
+
+ p->ainew.temp = 0;
+ }
+
+ // Start the pathfinder
+ r = p->ainew.pathfinder->main(p->ainew.pathfinder);
+ switch (r) {
+ case AYSTAR_NO_PATH:
+ DEBUG(ai, 1, "No route found by pathfinder");
+ // Start all over again
+ p->ainew.state = AI_STATE_NOTHING;
+ break;
+
+ case AYSTAR_FOUND_END_NODE: // We found the end-point
+ p->ainew.temp = -1;
+ p->ainew.state = AI_STATE_FIND_DEPOT;
+ break;
+
+ // In any other case, we are still busy finding the route
+ default: break;
+ }
+}
+
+
+// This function tries to locate a good place for a depot!
+static void AiNew_State_FindDepot(Player *p)
+{
+ // To place the depot, we walk through the route, and if we find a lovely spot (MP_CLEAR, MP_TREES), we place it there..
+ // Simple, easy, works!
+ // To make the depot stand in the middle of the route, we start from the center..
+ // But first we walk through the route see if we can find a depot that is ours
+ // this keeps things nice ;)
+ int g, i, r;
+ DiagDirection j;
+ TileIndex tile;
+ assert(p->ainew.state == AI_STATE_FIND_DEPOT);
+
+ p->ainew.depot_tile = 0;
+
+ for (i=2;i<p->ainew.path_info.route_length-2;i++) {
+ tile = p->ainew.path_info.route[i];
+ for (j = 0; j < 4; j++) {
+ TileIndex t = tile + TileOffsByDiagDir(j);
+
+ if (IsTileType(t, MP_STREET) &&
+ GetRoadTileType(t) == ROAD_TILE_DEPOT &&
+ IsTileOwner(t, _current_player) &&
+ GetRoadDepotDirection(t) == ReverseDiagDir(j)) {
+ p->ainew.depot_tile = t;
+ p->ainew.depot_direction = ReverseDiagDir(j);
+ p->ainew.state = AI_STATE_VERIFY_ROUTE;
+ return;
+ }
+ }
+ }
+
+ // This routine let depot finding start in the middle, and work his way to the stations
+ // It makes depot placing nicer :)
+ i = p->ainew.path_info.route_length / 2;
+ g = 1;
+ while (i > 1 && i < p->ainew.path_info.route_length - 2) {
+ i += g;
+ g *= -1;
+ (g < 0?g--:g++);
+
+ if (p->ainew.path_info.route_extra[i] != 0 || p->ainew.path_info.route_extra[i+1] != 0) {
+ // Bridge or tunnel.. we can't place a depot there
+ continue;
+ }
+
+ tile = p->ainew.path_info.route[i];
+
+ for (j = 0; j < 4; j++) {
+ TileIndex t = tile + TileOffsByDiagDir(j);
+
+ // It may not be placed on the road/rail itself
+ // And because it is not build yet, we can't see it on the tile..
+ // So check the surrounding tiles :)
+ if (t == p->ainew.path_info.route[i - 1] ||
+ t == p->ainew.path_info.route[i + 1]) {
+ continue;
+ }
+ // Not around a bridge?
+ if (p->ainew.path_info.route_extra[i] != 0) continue;
+ if (IsTileType(tile, MP_TUNNELBRIDGE)) continue;
+ // Is the terrain clear?
+ if (IsTileType(t, MP_CLEAR) || IsTileType(t, MP_TREES)) {
+ // If the current tile is on a slope then we do not allow this
+ if (GetTileSlope(tile, NULL) != SLOPE_FLAT) continue;
+ // Check if everything went okay..
+ r = AiNew_Build_Depot(p, t, ReverseDiagDir(j), 0);
+ if (CmdFailed(r)) continue;
+ // Found a spot!
+ p->ainew.new_cost += r;
+ p->ainew.depot_tile = t;
+ p->ainew.depot_direction = ReverseDiagDir(j); // Reverse direction
+ p->ainew.state = AI_STATE_VERIFY_ROUTE;
+ return;
+ }
+ }
+ }
+
+ // Failed to find a depot?
+ p->ainew.state = AI_STATE_NOTHING;
+}
+
+
+// This function calculates how many vehicles there are needed on this
+// traject.
+// It works pretty simple: get the length, see how much we move around
+// and hussle that, and you know how many vehicles there are needed.
+// It returns the cost for the vehicles
+static int AiNew_HowManyVehicles(Player *p)
+{
+ if (p->ainew.tbt == AI_BUS) {
+ // For bus-routes we look at the time before we are back in the station
+ EngineID i;
+ int length, tiles_a_day;
+ int amount;
+ i = AiNew_PickVehicle(p);
+ if (i == INVALID_ENGINE) return 0;
+ // Passenger run.. how long is the route?
+ length = p->ainew.path_info.route_length;
+ // Calculating tiles a day a vehicle moves is not easy.. this is how it must be done!
+ tiles_a_day = RoadVehInfo(i)->max_speed * DAY_TICKS / 256 / 16;
+ // We want a vehicle in a station once a month at least, so, calculate it!
+ // (the * 2 is because we have 2 stations ;))
+ amount = length * 2 * 2 / tiles_a_day / 30;
+ if (amount == 0) amount = 1;
+ return amount;
+ } else if (p->ainew.tbt == AI_TRUCK) {
+ // For truck-routes we look at the cargo
+ EngineID i;
+ int length, amount, tiles_a_day;
+ int max_cargo;
+ i = AiNew_PickVehicle(p);
+ if (i == INVALID_ENGINE) return 0;
+ // Passenger run.. how long is the route?
+ length = p->ainew.path_info.route_length;
+ // Calculating tiles a day a vehicle moves is not easy.. this is how it must be done!
+ tiles_a_day = RoadVehInfo(i)->max_speed * DAY_TICKS / 256 / 16;
+ if (p->ainew.from_deliver) {
+ max_cargo = GetIndustry(p->ainew.from_ic)->total_production[0];
+ } else {
+ max_cargo = GetIndustry(p->ainew.to_ic)->total_production[0];
+ }
+
+ // This is because moving 60% is more than we can dream of!
+ max_cargo *= 0.6;
+ // We want all the cargo to be gone in a month.. so, we know the cargo it delivers
+ // we know what the vehicle takes with him, and we know the time it takes him
+ // to get back here.. now let's do some math!
+ amount = 2 * length * max_cargo / tiles_a_day / 30 / RoadVehInfo(i)->capacity;
+ amount += 1;
+ return amount;
+ } else {
+ // Currently not supported
+ return 0;
+ }
+}
+
+
+// This function checks:
+// - If the route went okay
+// - Calculates the amount of money needed to build the route
+// - Calculates how much vehicles needed for the route
+static void AiNew_State_VerifyRoute(Player *p)
+{
+ int res, i;
+ assert(p->ainew.state == AI_STATE_VERIFY_ROUTE);
+
+ // Let's calculate the cost of the path..
+ // new_cost already contains the cost of the stations
+ p->ainew.path_info.position = -1;
+
+ do {
+ p->ainew.path_info.position++;
+ p->ainew.new_cost += AiNew_Build_RoutePart(p, &p->ainew.path_info, DC_QUERY_COST);
+ } while (p->ainew.path_info.position != -2);
+
+ // Now we know the price of build station + path. Now check how many vehicles
+ // we need and what the price for that will be
+ res = AiNew_HowManyVehicles(p);
+ // If res == 0, no vehicle was found, or an other problem did occour
+ if (res == 0) {
+ p->ainew.state = AI_STATE_NOTHING;
+ return;
+ }
+ p->ainew.amount_veh = res;
+ p->ainew.cur_veh = 0;
+
+ // Check how much it it going to cost us..
+ for (i=0;i<res;i++) {
+ p->ainew.new_cost += AiNew_Build_Vehicle(p, 0, DC_QUERY_COST);
+ }
+
+ // Now we know how much the route is going to cost us
+ // Check if we have enough money for it!
+ if (p->ainew.new_cost > p->player_money - AI_MINIMUM_MONEY) {
+ // Too bad..
+ DEBUG(ai, 1, "Insufficient funds to build route (%d)", p->ainew.new_cost);
+ p->ainew.state = AI_STATE_NOTHING;
+ return;
+ }
+
+ // Now we can build the route, check the direction of the stations!
+ if (p->ainew.from_direction == AI_PATHFINDER_NO_DIRECTION) {
+ p->ainew.from_direction = AiNew_GetDirection(p->ainew.path_info.route[p->ainew.path_info.route_length-1], p->ainew.path_info.route[p->ainew.path_info.route_length-2]);
+ }
+ if (p->ainew.to_direction == AI_PATHFINDER_NO_DIRECTION) {
+ p->ainew.to_direction = AiNew_GetDirection(p->ainew.path_info.route[0], p->ainew.path_info.route[1]);
+ }
+ if (p->ainew.from_tile == AI_STATION_RANGE)
+ p->ainew.from_tile = p->ainew.path_info.route[p->ainew.path_info.route_length-1];
+ if (p->ainew.to_tile == AI_STATION_RANGE)
+ p->ainew.to_tile = p->ainew.path_info.route[0];
+
+ p->ainew.state = AI_STATE_BUILD_STATION;
+ p->ainew.temp = 0;
+
+ DEBUG(ai, 1, "The route is set and buildable, building 0x%X to 0x%X...", p->ainew.from_tile, p->ainew.to_tile);
+}
+
+
+// Build the stations
+static void AiNew_State_BuildStation(Player *p)
+{
+ int res = 0;
+ assert(p->ainew.state == AI_STATE_BUILD_STATION);
+ if (p->ainew.temp == 0) {
+ if (!IsTileType(p->ainew.from_tile, MP_STATION))
+ res = AiNew_Build_Station(p, p->ainew.tbt, p->ainew.from_tile, 0, 0, p->ainew.from_direction, DC_EXEC);
+ } else {
+ if (!IsTileType(p->ainew.to_tile, MP_STATION))
+ res = AiNew_Build_Station(p, p->ainew.tbt, p->ainew.to_tile, 0, 0, p->ainew.to_direction, DC_EXEC);
+ p->ainew.state = AI_STATE_BUILD_PATH;
+ }
+ if (CmdFailed(res)) {
+ DEBUG(ai, 0, "[BuildStation] station could not be built (0x%X)", p->ainew.to_tile);
+ p->ainew.state = AI_STATE_NOTHING;
+ // If the first station _was_ build, destroy it
+ if (p->ainew.temp != 0)
+ AI_DoCommand(p->ainew.from_tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
+ return;
+ }
+ p->ainew.temp++;
+}
+
+
+// Build the path
+static void AiNew_State_BuildPath(Player *p)
+{
+ assert(p->ainew.state == AI_STATE_BUILD_PATH);
+ // p->ainew.temp is set to -1 when this function is called for the first time
+ if (p->ainew.temp == -1) {
+ DEBUG(ai, 1, "Starting to build new path");
+ // Init the counter
+ p->ainew.counter = (4 - _opt.diff.competitor_speed) * AI_BUILDPATH_PAUSE + 1;
+ // Set the position to the startingplace (-1 because in a minute we do ++)
+ p->ainew.path_info.position = -1;
+ // And don't do this again
+ p->ainew.temp = 0;
+ }
+ // Building goes very fast on normal rate, so we are going to slow it down..
+ // By let the counter count from AI_BUILDPATH_PAUSE to 0, we have a nice way :)
+ if (--p->ainew.counter != 0) return;
+ p->ainew.counter = (4 - _opt.diff.competitor_speed) * AI_BUILDPATH_PAUSE + 1;
+
+ // Increase the building position
+ p->ainew.path_info.position++;
+ // Build route
+ AiNew_Build_RoutePart(p, &p->ainew.path_info, DC_EXEC);
+ if (p->ainew.path_info.position == -2) {
+ // This means we are done building!
+
+ if (p->ainew.tbt == AI_TRUCK && !_patches.roadveh_queue) {
+ // If they not queue, they have to go up and down to try again at a station...
+ // We don't want that, so try building some road left or right of the station
+ int dir1, dir2, dir3;
+ TileIndex tile;
+ int i, ret;
+ for (i=0;i<2;i++) {
+ if (i == 0) {
+ tile = p->ainew.from_tile + TileOffsByDiagDir(p->ainew.from_direction);
+ dir1 = p->ainew.from_direction - 1;
+ if (dir1 < 0) dir1 = 3;
+ dir2 = p->ainew.from_direction + 1;
+ if (dir2 > 3) dir2 = 0;
+ dir3 = p->ainew.from_direction;
+ } else {
+ tile = p->ainew.to_tile + TileOffsByDiagDir(p->ainew.to_direction);
+ dir1 = p->ainew.to_direction - 1;
+ if (dir1 < 0) dir1 = 3;
+ dir2 = p->ainew.to_direction + 1;
+ if (dir2 > 3) dir2 = 0;
+ dir3 = p->ainew.to_direction;
+ }
+
+ ret = AI_DoCommand(tile, DiagDirToRoadBits(ReverseDiagDir(dir1)), 0, DC_EXEC | DC_NO_WATER, CMD_BUILD_ROAD);
+ if (!CmdFailed(ret)) {
+ dir1 = TileOffsByDiagDir(dir1);
+ if (IsTileType(tile + dir1, MP_CLEAR) || IsTileType(tile + dir1, MP_TREES)) {
+ ret = AI_DoCommand(tile+dir1, AiNew_GetRoadDirection(tile, tile+dir1, tile+dir1+dir1), 0, DC_EXEC | DC_NO_WATER, CMD_BUILD_ROAD);
+ if (!CmdFailed(ret)) {
+ if (IsTileType(tile + dir1 + dir1, MP_CLEAR) || IsTileType(tile + dir1 + dir1, MP_TREES))
+ AI_DoCommand(tile+dir1+dir1, AiNew_GetRoadDirection(tile+dir1, tile+dir1+dir1, tile+dir1+dir1+dir1), 0, DC_EXEC | DC_NO_WATER, CMD_BUILD_ROAD);
+ }
+ }
+ }
+
+ ret = AI_DoCommand(tile, DiagDirToRoadBits(ReverseDiagDir(dir2)), 0, DC_EXEC | DC_NO_WATER, CMD_BUILD_ROAD);
+ if (!CmdFailed(ret)) {
+ dir2 = TileOffsByDiagDir(dir2);
+ if (IsTileType(tile + dir2, MP_CLEAR) || IsTileType(tile + dir2, MP_TREES)) {
+ ret = AI_DoCommand(tile+dir2, AiNew_GetRoadDirection(tile, tile+dir2, tile+dir2+dir2), 0, DC_EXEC | DC_NO_WATER, CMD_BUILD_ROAD);
+ if (!CmdFailed(ret)) {
+ if (IsTileType(tile + dir2 + dir2, MP_CLEAR) || IsTileType(tile + dir2 + dir2, MP_TREES))
+ AI_DoCommand(tile+dir2+dir2, AiNew_GetRoadDirection(tile+dir2, tile+dir2+dir2, tile+dir2+dir2+dir2), 0, DC_EXEC | DC_NO_WATER, CMD_BUILD_ROAD);
+ }
+ }
+ }
+
+ ret = AI_DoCommand(tile, DiagDirToRoadBits(dir3), 0, DC_EXEC | DC_NO_WATER, CMD_BUILD_ROAD);
+ if (!CmdFailed(ret)) {
+ dir3 = TileOffsByDiagDir(dir3);
+ if (IsTileType(tile + dir3, MP_CLEAR) || IsTileType(tile + dir3, MP_TREES)) {
+ ret = AI_DoCommand(tile+dir3, AiNew_GetRoadDirection(tile, tile+dir3, tile+dir3+dir3), 0, DC_EXEC | DC_NO_WATER, CMD_BUILD_ROAD);
+ if (!CmdFailed(ret)) {
+ if (IsTileType(tile + dir3 + dir3, MP_CLEAR) || IsTileType(tile + dir3 + dir3, MP_TREES))
+ AI_DoCommand(tile+dir3+dir3, AiNew_GetRoadDirection(tile+dir3, tile+dir3+dir3, tile+dir3+dir3+dir3), 0, DC_EXEC | DC_NO_WATER, CMD_BUILD_ROAD);
+ }
+ }
+ }
+ }
+ }
+
+ DEBUG(ai, 1, "Finished building path, cost: %d", p->ainew.new_cost);
+ p->ainew.state = AI_STATE_BUILD_DEPOT;
+ }
+}
+
+
+// Builds the depot
+static void AiNew_State_BuildDepot(Player *p)
+{
+ int res = 0;
+ assert(p->ainew.state == AI_STATE_BUILD_DEPOT);
+
+ if (IsTileType(p->ainew.depot_tile, MP_STREET) && GetRoadTileType(p->ainew.depot_tile) == ROAD_TILE_DEPOT) {
+ if (IsTileOwner(p->ainew.depot_tile, _current_player)) {
+ // The depot is already built
+ p->ainew.state = AI_STATE_BUILD_VEHICLE;
+ return;
+ } else {
+ // There is a depot, but not of our team! :(
+ p->ainew.state = AI_STATE_NOTHING;
+ return;
+ }
+ }
+
+ // There is a bus on the tile we want to build road on... idle till he is gone! (BAD PERSON! :p)
+ if (!EnsureNoVehicle(p->ainew.depot_tile + TileOffsByDiagDir(p->ainew.depot_direction)))
+ return;
+
+ res = AiNew_Build_Depot(p, p->ainew.depot_tile, p->ainew.depot_direction, DC_EXEC);
+ if (CmdFailed(res)) {
+ DEBUG(ai, 0, "[BuildDepot] depot could not be built (0x%X)", p->ainew.depot_tile);
+ p->ainew.state = AI_STATE_NOTHING;
+ return;
+ }
+
+ p->ainew.state = AI_STATE_BUILD_VEHICLE;
+ p->ainew.idle = 10;
+ p->ainew.veh_main_id = INVALID_VEHICLE;
+}
+
+
+// Build vehicles
+static void AiNew_State_BuildVehicle(Player *p)
+{
+ int res;
+ assert(p->ainew.state == AI_STATE_BUILD_VEHICLE);
+
+ // Check if we need to build a vehicle
+ if (p->ainew.amount_veh == 0) {
+ // Nope, we are done!
+ // This means: we are all done! The route is open.. go back to NOTHING
+ // He will idle some time and it will all start over again.. :)
+ p->ainew.state = AI_STATE_ACTION_DONE;
+ return;
+ }
+ if (--p->ainew.idle != 0) return;
+ // It is realistic that the AI can only build 1 vehicle a day..
+ // This makes sure of that!
+ p->ainew.idle = AI_BUILD_VEHICLE_TIME_BETWEEN;
+
+ // Build the vehicle
+ res = AiNew_Build_Vehicle(p, p->ainew.depot_tile, DC_EXEC);
+ if (CmdFailed(res)) {
+ // This happens when the AI can't build any more vehicles!
+ p->ainew.state = AI_STATE_NOTHING;
+ return;
+ }
+ // Increase the current counter
+ p->ainew.cur_veh++;
+ // Decrease the total counter
+ p->ainew.amount_veh--;
+ // Go give some orders!
+ p->ainew.state = AI_STATE_WAIT_FOR_BUILD;
+}
+
+
+// Put the stations in the order list
+static void AiNew_State_GiveOrders(Player *p)
+{
+ int idx;
+ Order order;
+
+ assert(p->ainew.state == AI_STATE_GIVE_ORDERS);
+
+ if (p->ainew.veh_main_id != INVALID_VEHICLE) {
+ AI_DoCommand(0, p->ainew.veh_id + (p->ainew.veh_main_id << 16), 0, DC_EXEC, CMD_CLONE_ORDER);
+
+ p->ainew.state = AI_STATE_START_VEHICLE;
+ return;
+ } else {
+ p->ainew.veh_main_id = p->ainew.veh_id;
+ }
+
+ // Very handy for AI, goto depot.. but yeah, it needs to be activated ;)
+ if (_patches.gotodepot) {
+ idx = 0;
+ order.type = OT_GOTO_DEPOT;
+ order.flags = OF_UNLOAD;
+ order.dest = GetDepotByTile(p->ainew.depot_tile)->index;
+ AI_DoCommand(0, p->ainew.veh_id + (idx << 16), PackOrder(&order), DC_EXEC, CMD_INSERT_ORDER);
+ }
+
+ idx = 0;
+ order.type = OT_GOTO_STATION;
+ order.flags = 0;
+ order.dest = GetStationIndex(p->ainew.to_tile);
+ if (p->ainew.tbt == AI_TRUCK && p->ainew.to_deliver)
+ order.flags |= OF_FULL_LOAD;
+ AI_DoCommand(0, p->ainew.veh_id + (idx << 16), PackOrder(&order), DC_EXEC, CMD_INSERT_ORDER);
+
+ idx = 0;
+ order.type = OT_GOTO_STATION;
+ order.flags = 0;
+ order.dest = GetStationIndex(p->ainew.from_tile);
+ if (p->ainew.tbt == AI_TRUCK && p->ainew.from_deliver)
+ order.flags |= OF_FULL_LOAD;
+ AI_DoCommand(0, p->ainew.veh_id + (idx << 16), PackOrder(&order), DC_EXEC, CMD_INSERT_ORDER);
+
+ // Start the engines!
+ p->ainew.state = AI_STATE_START_VEHICLE;
+}
+
+
+// Start the vehicle
+static void AiNew_State_StartVehicle(Player *p)
+{
+ assert(p->ainew.state == AI_STATE_START_VEHICLE);
+
+ // Skip the first order if it is a second vehicle
+ // This to make vehicles go different ways..
+ if (p->ainew.cur_veh & 1)
+ AI_DoCommand(0, p->ainew.veh_id, 0, DC_EXEC, CMD_SKIP_ORDER);
+
+ // 3, 2, 1... go! (give START_STOP command ;))
+ AI_DoCommand(0, p->ainew.veh_id, 0, DC_EXEC, CMD_START_STOP_ROADVEH);
+ // Try to build an other vehicle (that function will stop building when needed)
+ p->ainew.idle = 10;
+ p->ainew.state = AI_STATE_BUILD_VEHICLE;
+}
+
+
+// Repays money
+static void AiNew_State_RepayMoney(Player *p)
+{
+ uint i;
+
+ for (i = 0; i < AI_LOAN_REPAY; i++) {
+ AI_DoCommand(0, 0, 0, DC_EXEC, CMD_DECREASE_LOAN);
+ }
+ p->ainew.state = AI_STATE_ACTION_DONE;
+}
+
+
+static void AiNew_CheckVehicle(Player *p, Vehicle *v)
+{
+ // When a vehicle is under the 6 months, we don't check for anything
+ if (v->age < 180) return;
+
+ // When a vehicle is older then 1 year, it should make money...
+ if (v->age > 360) {
+ // If both years together are not more than AI_MINIMUM_ROUTE_PROFIT,
+ // it is not worth the line I guess...
+ if (v->profit_last_year + v->profit_this_year < AI_MINIMUM_ROUTE_PROFIT ||
+ (v->reliability * 100 >> 16) < 40) {
+ // There is a possibility that the route is fucked up...
+ if (v->cargo_days > AI_VEHICLE_LOST_DAYS) {
+ // The vehicle is lost.. check the route, or else, get the vehicle
+ // back to a depot
+ // TODO: make this piece of code
+ }
+
+
+ // We are already sending him back
+ if (AiNew_GetSpecialVehicleFlag(p, v) & AI_VEHICLEFLAG_SELL) {
+ if (v->type == VEH_Road && IsTileDepotType(v->tile, TRANSPORT_ROAD) &&
+ (v->vehstatus&VS_STOPPED)) {
+ // We are at the depot, sell the vehicle
+ AI_DoCommand(0, v->index, 0, DC_EXEC, CMD_SELL_ROAD_VEH);
+ }
+ return;
+ }
+
+ if (!AiNew_SetSpecialVehicleFlag(p, v, AI_VEHICLEFLAG_SELL)) return;
+ {
+ int ret = 0;
+ if (v->type == VEH_Road)
+ ret = AI_DoCommand(0, v->index, 0, DC_EXEC, CMD_SEND_ROADVEH_TO_DEPOT);
+ // This means we can not find a depot :s
+ // if (CmdFailed(ret))
+ }
+ }
+ }
+}
+
+
+// Checks all vehicles if they are still valid and make money and stuff
+static void AiNew_State_CheckAllVehicles(Player *p)
+{
+ Vehicle *v;
+
+ FOR_ALL_VEHICLES(v) {
+ if (v->owner != p->index) continue;
+ // Currently, we only know how to handle road-vehicles
+ if (v->type != VEH_Road) continue;
+
+ AiNew_CheckVehicle(p, v);
+ }
+
+ p->ainew.state = AI_STATE_ACTION_DONE;
+}
+
+
+// Using the technique simular to the original AI
+// Keeps things logical
+// It really should be in the same order as the AI_STATE's are!
+static AiNew_StateFunction* const _ainew_state[] = {
+ NULL,
+ AiNew_State_FirstTime,
+ AiNew_State_Nothing,
+ AiNew_State_WakeUp,
+ AiNew_State_LocateRoute,
+ AiNew_State_FindStation,
+ AiNew_State_FindPath,
+ AiNew_State_FindDepot,
+ AiNew_State_VerifyRoute,
+ AiNew_State_BuildStation,
+ AiNew_State_BuildPath,
+ AiNew_State_BuildDepot,
+ AiNew_State_BuildVehicle,
+ NULL,
+ AiNew_State_GiveOrders,
+ AiNew_State_StartVehicle,
+ AiNew_State_RepayMoney,
+ AiNew_State_CheckAllVehicles,
+ AiNew_State_ActionDone,
+ NULL,
+};
+
+static void AiNew_OnTick(Player *p)
+{
+ if (_ainew_state[p->ainew.state] != NULL)
+ _ainew_state[p->ainew.state](p);
+}
+
+
+void AiNewDoGameLoop(Player *p)
+{
+ if (p->ainew.state == AI_STATE_STARTUP) {
+ // The AI just got alive!
+ p->ainew.state = AI_STATE_FIRST_TIME;
+ p->ainew.tick = 0;
+
+ // Only startup the AI
+ return;
+ }
+
+ // We keep a ticker. We use it for competitor_speed
+ p->ainew.tick++;
+
+ // If we come here, we can do a tick.. do so!
+ AiNew_OnTick(p);
+}
diff --git a/src/ai/trolly/trolly.h b/src/ai/trolly/trolly.h
new file mode 100644
index 000000000..e0d70fbf6
--- /dev/null
+++ b/src/ai/trolly/trolly.h
@@ -0,0 +1,262 @@
+/* $Id$ */
+
+#ifndef AI_TROLLY_H
+#define AI_TROLLY_H
+
+#include "../../aystar.h"
+#include "../../player.h"
+
+/*
+ * These defines can be altered to change the behavoir of the AI
+ *
+ * WARNING:
+ * This can also alter the AI in a negative way. I will never claim these settings
+ * are perfect, but don't change them if you don't know what the effect is.
+ */
+
+// How many times it the H multiplied. The higher, the more it will go straight to the
+// end point. The lower, how more it will find the route with the lowest cost.
+// also: the lower, the longer it takes before route is calculated..
+#define AI_PATHFINDER_H_MULTIPLER 100
+
+// How many loops may AyStar do before it stops
+// 0 = infinite
+#define AI_PATHFINDER_LOOPS_PER_TICK 5
+
+// How long may the AI search for one route?
+// 0 = infinite
+// This number is the number of tiles tested.
+// It takes (AI_PATHFINDER_MAX_SEARCH_NODES / AI_PATHFINDER_LOOPS_PER_TICK) ticks
+// to get here.. with 5000 / 10 = 500. 500 / 74 (one day) = 8 days till it aborts
+// (that is: if the AI is on VERY FAST! :p
+#define AI_PATHFINDER_MAX_SEARCH_NODES 5000
+
+// If you enable this, the AI is not allowed to make 90degree turns
+#define AI_PATHFINDER_NO_90DEGREES_TURN
+
+// Below are defines for the g-calculation
+
+// Standard penalty given to a tile
+#define AI_PATHFINDER_PENALTY 150
+// The penalty given to a tile that is going up
+#define AI_PATHFINDER_TILE_GOES_UP_PENALTY 450
+// The penalty given to a tile which would have to use fundation
+#define AI_PATHFINDER_FOUNDATION_PENALTY 100
+// Changing direction is a penalty, to prevent curved ways (with that: slow ways)
+#define AI_PATHFINDER_DIRECTION_CHANGE_PENALTY 200
+// Same penalty, only for when road already exists
+#define AI_PATHFINDER_DIRECTION_CHANGE_ON_EXISTING_ROAD_PENALTY 50
+// A diagonal track cost the same as a straigh, but a diagonal is faster... so give
+// a bonus for using diagonal track
+#ifdef AI_PATHFINDER_NO_90DEGREES_TURN
+#define AI_PATHFINDER_DIAGONAL_BONUS 95
+#else
+#define AI_PATHFINDER_DIAGONAL_BONUS 75
+#endif
+// If a roadblock already exists, it gets a bonus
+#define AI_PATHFINDER_ROAD_ALREADY_EXISTS_BONUS 140
+// To prevent 3 direction changes in 3 tiles, this penalty is given in such situation
+#define AI_PATHFINDER_CURVE_PENALTY 200
+
+// Penalty a bridge gets per length
+#define AI_PATHFINDER_BRIDGE_PENALTY 180
+// The penalty for a bridge going up
+#define AI_PATHFINDER_BRIDGE_GOES_UP_PENALTY 1000
+
+// Tunnels are expensive...
+// Because of that, every tile the cost is increased with 1/8th of his value
+// This is also true if you are building a tunnel yourself
+#define AI_PATHFINDER_TUNNEL_PENALTY 350
+
+/*
+ * Ai_New defines
+ */
+
+// How long may we search cities and industry for a new route?
+#define AI_LOCATE_ROUTE_MAX_COUNTER 200
+
+// How many days must there be between building the first station and the second station
+// within one city. This number is in days and should be more than 4 months.
+#define AI_CHECKCITY_DATE_BETWEEN 180
+
+// How many cargo is needed for one station in a city?
+#define AI_CHECKCITY_CARGO_PER_STATION 60
+// How much cargo must there not be used in a city before we can build a new station?
+#define AI_CHECKCITY_NEEDED_CARGO 50
+// When there is already a station which takes the same good and the rating of that
+// city is higher then this numer, we are not going to attempt to build anything
+// there
+#define AI_CHECKCITY_CARGO_RATING 50
+// But, there is a chance of 1 out of this number, that we do ;)
+#define AI_CHECKCITY_CARGO_RATING_CHANCE 5
+// If a city is too small to contain a station, there is a small chance
+// that we still do so.. just to make the city bigger!
+#define AI_CHECKCITY_CITY_CHANCE 5
+
+// This number indicates for every unit of cargo, how many tiles two stations maybe be away
+// from eachother. In other words: if we have 120 units of cargo in one station, and 120 units
+// of the cargo in the other station, both stations can be 96 units away from eachother, if the
+// next number is 0.4.
+#define AI_LOCATEROUTE_BUS_CARGO_DISTANCE 0.4
+#define AI_LOCATEROUTE_TRUCK_CARGO_DISTANCE 0.7
+// In whole tiles, the minimum distance for a truck route
+#define AI_LOCATEROUTE_TRUCK_MIN_DISTANCE 30
+
+// The amount of tiles in a square from -X to +X that is scanned for a station spot
+// (so if this number is 10, 20x20 = 400 tiles are scanned for _the_ perfect spot
+// Safe values are between 15 and 5
+#define AI_FINDSTATION_TILE_RANGE 10
+
+// Building on normal speed goes very fast. Idle this amount of ticks between every
+// building part. It is calculated like this: (4 - competitor_speed) * num + 1
+// where competitor_speed is between 0 (very slow) to 4 (very fast)
+#define AI_BUILDPATH_PAUSE 10
+
+// Minimum % of reliabilty a vehicle has to have before the AI buys it
+#define AI_VEHICLE_MIN_RELIABILTY 60
+
+// The minimum amount of money a player should always have
+#define AI_MINIMUM_MONEY 15000
+
+// If the most cheap route is build, how much is it going to cost..
+// This is to prevent the AI from trying to build a route which can not be paid for
+#define AI_MINIMUM_BUS_ROUTE_MONEY 25000
+#define AI_MINIMUM_TRUCK_ROUTE_MONEY 35000
+
+// The minimum amount of money before we are going to repay any money
+#define AI_MINIMUM_LOAN_REPAY_MONEY 40000
+// How many repays do we do if we have enough money to do so?
+// Every repay is 10000
+#define AI_LOAN_REPAY 2
+// How much income must we have before paying back a loan? Month-based (and looked at the last month)
+#define AI_MINIMUM_INCOME_FOR_LOAN 7000
+
+// If there is <num> time as much cargo in the station then the vehicle can handle
+// reuse the station instead of building a new one!
+#define AI_STATION_REUSE_MULTIPLER 2
+
+// No more than this amount of vehicles per station..
+#define AI_CHECK_MAX_VEHICLE_PER_STATION 10
+
+// How many thick between building 2 vehicles
+#define AI_BUILD_VEHICLE_TIME_BETWEEN DAY_TICKS
+
+// How many days must there between vehicle checks
+// The more often, the less non-money-making lines there will be
+// but the unfair it may seem to a human player
+#define AI_DAYS_BETWEEN_VEHICLE_CHECKS 30
+
+// How money profit does a vehicle needs to make to stay in order
+// This is the profit of this year + profit of last year
+// But also for vehicles that are just one year old. In other words:
+// Vehicles of 2 years do easier meet this setting then vehicles
+// of one year. This is a very good thing. New vehicles are filtered,
+// while old vehicles stay longer, because we do get less in return.
+#define AI_MINIMUM_ROUTE_PROFIT 1000
+
+// A vehicle is considered lost when he his cargo is more than 180 days old
+#define AI_VEHICLE_LOST_DAYS 180
+
+// How many times may the AI try to find a route before it gives up
+#define AI_MAX_TRIES_FOR_SAME_ROUTE 8
+
+/*
+ * End of defines
+ */
+
+// This stops 90degrees curves
+static const byte _illegal_curves[6] = {
+ 255, 255, // Horz and vert, don't have the effect
+ 5, // upleft and upright are not valid
+ 4, // downright and downleft are not valid
+ 2, // downleft and upleft are not valid
+ 3, // upright and downright are not valid
+};
+
+enum {
+ AI_STATE_STARTUP = 0,
+ AI_STATE_FIRST_TIME,
+ AI_STATE_NOTHING,
+ AI_STATE_WAKE_UP,
+ AI_STATE_LOCATE_ROUTE,
+ AI_STATE_FIND_STATION,
+ AI_STATE_FIND_PATH,
+ AI_STATE_FIND_DEPOT,
+ AI_STATE_VERIFY_ROUTE,
+ AI_STATE_BUILD_STATION,
+ AI_STATE_BUILD_PATH,
+ AI_STATE_BUILD_DEPOT,
+ AI_STATE_BUILD_VEHICLE,
+ AI_STATE_WAIT_FOR_BUILD,
+ AI_STATE_GIVE_ORDERS,
+ AI_STATE_START_VEHICLE,
+ AI_STATE_REPAY_MONEY,
+ AI_STATE_CHECK_ALL_VEHICLES,
+ AI_STATE_ACTION_DONE,
+ AI_STATE_STOP, // Temporary function to stop the AI
+};
+
+// Used for tbt (train/bus/truck)
+enum {
+ AI_TRAIN = 0,
+ AI_BUS,
+ AI_TRUCK,
+};
+
+enum {
+ AI_ACTION_NONE = 0,
+ AI_ACTION_BUS_ROUTE,
+ AI_ACTION_TRUCK_ROUTE,
+ AI_ACTION_REPAY_LOAN,
+ AI_ACTION_CHECK_ALL_VEHICLES,
+};
+
+// Used for from_type/to_type
+enum {
+ AI_NO_TYPE = 0,
+ AI_CITY,
+ AI_INDUSTRY,
+};
+
+// Flags for in the vehicle
+enum {
+ AI_VEHICLEFLAG_SELL = 1,
+ // Remember, flags must be in power of 2
+};
+
+#define AI_NO_CARGO 0xFF // Means that there is no cargo defined yet (used for industry)
+#define AI_NEED_CARGO 0xFE // Used when the AI needs to find out a cargo for the route
+#define AI_STATION_RANGE TileXY(MapMaxX(), MapMaxY())
+
+#define AI_PATHFINDER_NO_DIRECTION (byte)-1
+
+// Flags used in user_data
+#define AI_PATHFINDER_FLAG_BRIDGE 1
+#define AI_PATHFINDER_FLAG_TUNNEL 2
+
+typedef void AiNew_StateFunction(Player *p);
+
+// ai_new.c
+void AiNewDoGameLoop(Player *p);
+
+// ai_pathfinder.c
+AyStar *new_AyStar_AiPathFinder(int max_tiles_around, Ai_PathFinderInfo *PathFinderInfo);
+void clean_AyStar_AiPathFinder(AyStar *aystar, Ai_PathFinderInfo *PathFinderInfo);
+
+// ai_shared.c
+int AiNew_GetRailDirection(TileIndex tile_a, TileIndex tile_b, TileIndex tile_c);
+int AiNew_GetRoadDirection(TileIndex tile_a, TileIndex tile_b, TileIndex tile_c);
+DiagDirection AiNew_GetDirection(TileIndex tile_a, TileIndex tile_b);
+bool AiNew_SetSpecialVehicleFlag(Player *p, Vehicle *v, uint flag);
+uint AiNew_GetSpecialVehicleFlag(Player *p, Vehicle *v);
+
+// ai_build.c
+bool AiNew_Build_CompanyHQ(Player *p, TileIndex tile);
+int AiNew_Build_Station(Player *p, byte type, TileIndex tile, byte length, byte numtracks, byte direction, byte flag);
+int AiNew_Build_Bridge(Player *p, TileIndex tile_a, TileIndex tile_b, byte flag);
+int AiNew_Build_RoutePart(Player *p, Ai_PathFinderInfo *PathFinderInfo, byte flag);
+EngineID AiNew_PickVehicle(Player *p);
+int AiNew_Build_Vehicle(Player *p, TileIndex tile, byte flag);
+int AiNew_Build_Depot(Player* p, TileIndex tile, DiagDirection direction, byte flag);
+
+#endif /* AI_TROLLY_H */
diff --git a/src/aircraft.h b/src/aircraft.h
new file mode 100644
index 000000000..15d2bbe27
--- /dev/null
+++ b/src/aircraft.h
@@ -0,0 +1,26 @@
+/* $Id$ */
+
+#ifndef AIRCRAFT_H
+#define AIRCRAFT_H
+
+#include "station_map.h"
+#include "vehicle.h"
+
+
+static inline bool IsAircraftInHangar(const Vehicle* v)
+{
+ assert(v->type == VEH_Aircraft);
+ return v->vehstatus & VS_HIDDEN && IsHangarTile(v->tile);
+}
+
+static inline bool IsAircraftInHangarStopped(const Vehicle* v)
+{
+ return IsAircraftInHangar(v) && v->vehstatus & VS_STOPPED;
+}
+
+uint16 AircraftDefaultCargoCapacity(CargoID cid, EngineID engine_type);
+
+void CcCloneAircraft(bool success, TileIndex tile, uint32 p1, uint32 p2);
+void HandleAircraftEnterHangar(Vehicle *v);
+
+#endif /* AIRCRAFT_H */
diff --git a/src/aircraft_cmd.c b/src/aircraft_cmd.c
new file mode 100644
index 000000000..bbc3aa4db
--- /dev/null
+++ b/src/aircraft_cmd.c
@@ -0,0 +1,2120 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "aircraft.h"
+#include "debug.h"
+#include "functions.h"
+#include "station_map.h"
+#include "table/strings.h"
+#include "map.h"
+#include "tile.h"
+#include "vehicle.h"
+#include "depot.h"
+#include "engine.h"
+#include "command.h"
+#include "station.h"
+#include "news.h"
+#include "sound.h"
+#include "player.h"
+#include "airport.h"
+#include "vehicle_gui.h"
+#include "table/sprites.h"
+#include "newgrf_engine.h"
+#include "newgrf_callbacks.h"
+#include "newgrf_text.h"
+#include "newgrf_sound.h"
+#include "date.h"
+
+static bool AirportMove(Vehicle *v, const AirportFTAClass *apc);
+static bool AirportSetBlocks(Vehicle *v, AirportFTA *current_pos, const AirportFTAClass *apc);
+static bool AirportHasBlock(Vehicle *v, const AirportFTA *current_pos, const AirportFTAClass *apc);
+static bool AirportFindFreeTerminal(Vehicle *v, const AirportFTAClass *apc);
+static bool AirportFindFreeHelipad(Vehicle *v, const AirportFTAClass *apc);
+static void AirportGoToNextPosition(Vehicle *v, const AirportFTAClass *apc);
+static void CrashAirplane(Vehicle *v);
+
+static void AircraftNextAirportPos_and_Order(Vehicle *v);
+static byte GetAircraftFlyingAltitude(const Vehicle *v);
+
+static const SpriteID _aircraft_sprite[] = {
+ 0x0EB5, 0x0EBD, 0x0EC5, 0x0ECD,
+ 0x0ED5, 0x0EDD, 0x0E9D, 0x0EA5,
+ 0x0EAD, 0x0EE5, 0x0F05, 0x0F0D,
+ 0x0F15, 0x0F1D, 0x0F25, 0x0F2D,
+ 0x0EED, 0x0EF5, 0x0EFD, 0x0F35,
+ 0x0E9D, 0x0EA5, 0x0EAD, 0x0EB5,
+ 0x0EBD, 0x0EC5
+};
+
+/* Helicopter rotor animation states */
+enum HelicopterRotorStates {
+ HRS_ROTOR_STOPPED,
+ HRS_ROTOR_MOVING_1,
+ HRS_ROTOR_MOVING_2,
+ HRS_ROTOR_MOVING_3,
+};
+
+/* Find the nearest hangar to v
+ * INVALID_STATION is returned, if the player does not have any suitable
+ * airports (like helipads only)
+ */
+static StationID FindNearestHangar(const Vehicle *v)
+{
+ const Station *st;
+ uint best = 0;
+ StationID index = INVALID_STATION;
+ TileIndex vtile = TileVirtXY(v->x_pos, v->y_pos);
+
+ FOR_ALL_STATIONS(st) {
+ if (st->owner == v->owner && st->facilities & FACIL_AIRPORT &&
+ GetAirport(st->airport_type)->nof_depots > 0) {
+ uint distance;
+
+ // don't crash the plane if we know it can't land at the airport
+ if ((AircraftVehInfo(v->engine_type)->subtype & AIR_FAST) &&
+ (st->airport_type == AT_SMALL || st->airport_type == AT_COMMUTER) &&
+ !_cheats.no_jetcrash.value)
+ continue;
+
+ // v->tile can't be used here, when aircraft is flying v->tile is set to 0
+ distance = DistanceSquare(vtile, st->airport_tile);
+ if (distance < best || index == INVALID_STATION) {
+ best = distance;
+ index = st->index;
+ }
+ }
+ }
+ return index;
+}
+
+#if 0
+// returns true if vehicle v have an airport in the schedule, that has a hangar
+static bool HaveHangarInOrderList(Vehicle *v)
+{
+ const Order *order;
+
+ FOR_VEHICLE_ORDERS(v, order) {
+ const Station *st = GetStation(order->station);
+ if (st->owner == v->owner && st->facilities & FACIL_AIRPORT) {
+ // If an airport doesn't have a hangar, skip it
+ if (GetAirport(st->airport_type)->nof_depots != 0)
+ return true;
+ }
+ }
+
+ return false;
+}
+#endif
+
+int GetAircraftImage(const Vehicle* v, Direction direction)
+{
+ int spritenum = v->spritenum;
+
+ if (is_custom_sprite(spritenum)) {
+ int sprite = GetCustomVehicleSprite(v, direction);
+
+ if (sprite != 0) return sprite;
+ spritenum = orig_aircraft_vehicle_info[v->engine_type - AIRCRAFT_ENGINES_INDEX].image_index;
+ }
+ return direction + _aircraft_sprite[spritenum];
+}
+
+SpriteID GetRotorImage(const Vehicle *v)
+{
+ const Vehicle *w;
+
+ assert((v->subtype & 1) == 0);
+
+ w = v->next->next;
+ if (is_custom_sprite(v->spritenum)) {
+ SpriteID spritenum = GetCustomRotorSprite(v, false);
+ if (spritenum != 0) return spritenum;
+ }
+
+ /* Return standard rotor sprites if there are no custom sprites for this helicopter */
+ return SPR_ROTOR_STOPPED + w->u.air.state;
+}
+
+void DrawAircraftEngine(int x, int y, EngineID engine, uint32 image_ormod)
+{
+ const AircraftVehicleInfo* avi = AircraftVehInfo(engine);
+ int spritenum = avi->image_index;
+ int sprite = (6 + _aircraft_sprite[spritenum]);
+
+ if (is_custom_sprite(spritenum)) {
+ sprite = GetCustomVehicleIcon(engine, DIR_W);
+ if (sprite == 0) {
+ spritenum = orig_aircraft_vehicle_info[engine - AIRCRAFT_ENGINES_INDEX].image_index;
+ sprite = (6 + _aircraft_sprite[spritenum]);
+ }
+ }
+
+ DrawSprite(sprite | image_ormod, x, y);
+
+ if (!(avi->subtype & AIR_CTOL)) {
+ SpriteID rotor_sprite = GetCustomRotorIcon(engine);
+ if (rotor_sprite == 0) rotor_sprite = SPR_ROTOR_STOPPED;
+ DrawSprite(rotor_sprite, x, y - 5);
+ }
+}
+
+static int32 EstimateAircraftCost(EngineID engine_type)
+{
+ return AircraftVehInfo(engine_type)->base_cost * (_price.aircraft_base>>3)>>5;
+}
+
+
+/**
+ * Calculates cargo capacity based on an aircraft's passenger
+ * and mail capacities.
+ * @param cid Which cargo type to calculate a capacity for.
+ * @param engine Which engine to find a cargo capacity for.
+ * @return New cargo capacity value.
+ */
+uint16 AircraftDefaultCargoCapacity(CargoID cid, EngineID engine_type)
+{
+ const AircraftVehicleInfo *avi = AircraftVehInfo(engine_type);
+
+ assert(cid != CT_INVALID);
+
+ /* An aircraft can carry twice as much goods as normal cargo,
+ * and four times as many passengers. */
+ switch (cid) {
+ case CT_PASSENGERS:
+ return avi->passenger_capacity;
+ case CT_MAIL:
+ return avi->passenger_capacity + avi->mail_capacity;
+ case CT_GOODS:
+ return (avi->passenger_capacity + avi->mail_capacity) / 2;
+ default:
+ return (avi->passenger_capacity + avi->mail_capacity) / 4;
+ }
+}
+
+
+/** Build an aircraft.
+ * @param tile tile of depot where aircraft is built
+ * @param p1 aircraft type being built (engine)
+ * @param p2 bit 0 when set, the unitnumber will be 0, otherwise it will be a free number
+ */
+int32 CmdBuildAircraft(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ int32 value;
+ Vehicle *vl[3], *v, *u, *w;
+ UnitID unit_num;
+ const AircraftVehicleInfo *avi;
+ const AirportFTAClass* ap;
+ Engine *e;
+
+ if (!IsEngineBuildable(p1, VEH_Aircraft, _current_player)) return_cmd_error(STR_ENGINE_NOT_BUILDABLE);
+
+ value = EstimateAircraftCost(p1);
+
+ // to just query the cost, it is not neccessary to have a valid tile (automation/AI)
+ if (flags & DC_QUERY_COST) return value;
+
+ if (!IsHangarTile(tile) || !IsTileOwner(tile, _current_player)) return CMD_ERROR;
+
+ SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
+
+ avi = AircraftVehInfo(p1);
+
+ // Prevent building aircraft types at places which can't handle them
+ ap = GetAirport(GetStationByTile(tile)->airport_type);
+ if ((avi->subtype & AIR_CTOL ? HELICOPTERS_ONLY : AIRCRAFT_ONLY) == ap->acc_planes) {
+ return CMD_ERROR;
+ }
+
+ // allocate 2 or 3 vehicle structs, depending on type
+ if (!AllocateVehicles(vl, avi->subtype & AIR_CTOL ? 2 : 3) ||
+ IsOrderPoolFull()) {
+ return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
+ }
+
+ unit_num = HASBIT(p2, 0) ? 0 : GetFreeUnitNumber(VEH_Aircraft);
+ if (unit_num > _patches.max_aircraft)
+ return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
+
+ if (flags & DC_EXEC) {
+ CargoID cargo;
+ uint x;
+ uint y;
+
+ v = vl[0];
+ u = vl[1];
+
+ v->unitnumber = unit_num;
+ v->type = u->type = VEH_Aircraft;
+ v->direction = 3;
+
+ v->owner = u->owner = _current_player;
+
+ v->tile = tile;
+// u->tile = 0;
+
+ x = TileX(tile) * TILE_SIZE + 5;
+ y = TileY(tile) * TILE_SIZE + 3;
+
+ v->x_pos = u->x_pos = x;
+ v->y_pos = u->y_pos = y;
+
+ u->z_pos = GetSlopeZ(x, y);
+ v->z_pos = u->z_pos + 1;
+
+ v->x_offs = v->y_offs = -1;
+// u->delta_x = u->delta_y = 0;
+
+ v->sprite_width = v->sprite_height = 2;
+ v->z_height = 5;
+
+ u->sprite_width = u->sprite_height = 2;
+ u->z_height = 1;
+
+ v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
+ u->vehstatus = VS_HIDDEN | VS_UNCLICKABLE | VS_SHADOW;
+
+ v->spritenum = avi->image_index;
+// v->cargo_count = u->number_of_pieces = 0;
+
+ v->cargo_cap = avi->passenger_capacity;
+ u->cargo_cap = avi->mail_capacity;
+
+ v->cargo_type = CT_PASSENGERS;
+ u->cargo_type = CT_MAIL;
+
+ v->cargo_subtype = 0;
+
+ v->string_id = STR_SV_AIRCRAFT_NAME;
+// v->next_order_param = v->next_order = 0;
+
+// v->load_unload_time_rem = 0;
+// v->progress = 0;
+ v->last_station_visited = INVALID_STATION;
+// v->destination_coords = 0;
+
+ v->max_speed = avi->max_speed;
+ v->acceleration = avi->acceleration;
+ v->engine_type = p1;
+
+ v->subtype = (avi->subtype & AIR_CTOL ? 2 : 0);
+ v->value = value;
+
+ u->subtype = 4;
+
+ /* Danger, Will Robinson!
+ * If the aircraft is refittable, but cannot be refitted to
+ * passengers, we select the cargo type from the refit mask.
+ * This is a fairly nasty hack to get around the fact that TTD
+ * has no default cargo type specifier for planes... */
+ cargo = FindFirstRefittableCargo(p1);
+ if (cargo != CT_INVALID && cargo != CT_PASSENGERS) {
+ uint16 callback = CALLBACK_FAILED;
+
+ v->cargo_type = cargo;
+
+ if (HASBIT(EngInfo(p1)->callbackmask, CBM_REFIT_CAPACITY)) {
+ callback = GetVehicleCallback(CBID_VEHICLE_REFIT_CAPACITY, 0, 0, v->engine_type, v);
+ }
+
+ if (callback == CALLBACK_FAILED) {
+ /* Callback failed, or not executed; use the default cargo capacity */
+ v->cargo_cap = AircraftDefaultCargoCapacity(v->cargo_type, v->engine_type);
+ } else {
+ v->cargo_cap = callback;
+ }
+
+ /* Set the 'second compartent' capacity to none */
+ u->cargo_cap = 0;
+ }
+
+ e = GetEngine(p1);
+ v->reliability = e->reliability;
+ v->reliability_spd_dec = e->reliability_spd_dec;
+ v->max_age = e->lifelength * 366;
+
+ _new_vehicle_id = v->index;
+
+ v->u.air.pos = MAX_ELEMENTS;
+
+ /* When we click on hangar we know the tile it is on. By that we know
+ * its position in the array of depots the airport has.....we can search
+ * layout for #th position of depot. Since layout must start with a listing
+ * of all depots, it is simple */
+ {
+ const Station* st = GetStationByTile(tile);
+ const AirportFTAClass* apc = GetAirport(st->airport_type);
+ uint i;
+
+ for (i = 0; i < apc->nof_depots; i++) {
+ if (st->airport_tile + ToTileIndexDiff(apc->airport_depots[i]) == tile) {
+ assert(apc->layout[i].heading == HANGAR);
+ v->u.air.pos = apc->layout[i].position;
+ break;
+ }
+ }
+ // to ensure v->u.air.pos has been given a value
+ assert(v->u.air.pos != MAX_ELEMENTS);
+ }
+
+ v->u.air.state = HANGAR;
+ v->u.air.previous_pos = v->u.air.pos;
+ v->u.air.targetairport = GetStationIndex(tile);
+ v->next = u;
+
+ v->service_interval = _patches.servint_aircraft;
+
+ v->date_of_last_service = _date;
+ v->build_year = u->build_year = _cur_year;
+
+ v->cur_image = u->cur_image = 0xEA0;
+
+ v->random_bits = VehicleRandomBits();
+ u->random_bits = VehicleRandomBits();
+
+ VehiclePositionChanged(v);
+ VehiclePositionChanged(u);
+
+ // Aircraft with 3 vehicles (chopper)?
+ if (v->subtype == 0) {
+ w = vl[2];
+
+ u->next = w;
+
+ w->type = VEH_Aircraft;
+ w->direction = 0;
+ w->owner = _current_player;
+ w->x_pos = v->x_pos;
+ w->y_pos = v->y_pos;
+ w->z_pos = v->z_pos + 5;
+ w->x_offs = w->y_offs = -1;
+ w->sprite_width = w->sprite_height = 2;
+ w->z_height = 1;
+ w->vehstatus = VS_HIDDEN | VS_UNCLICKABLE;
+ w->spritenum = 0xFF;
+ w->subtype = 6;
+ w->cur_image = SPR_ROTOR_STOPPED;
+ w->random_bits = VehicleRandomBits();
+ /* Use rotor's air.state to store the rotor animation frame */
+ w->u.air.state = HRS_ROTOR_STOPPED;
+ VehiclePositionChanged(w);
+ }
+ GetPlayer(_current_player)->num_engines[p1]++;
+
+ InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
+ RebuildVehicleLists();
+ InvalidateWindow(WC_COMPANY, v->owner);
+ if (IsLocalPlayer())
+ InvalidateWindow(WC_REPLACE_VEHICLE, VEH_Aircraft); //updates the replace Aircraft window
+ }
+
+ return value;
+}
+
+
+static void DoDeleteAircraft(Vehicle *v)
+{
+ DeleteWindowById(WC_VEHICLE_VIEW, v->index);
+ RebuildVehicleLists();
+ InvalidateWindow(WC_COMPANY, v->owner);
+ DeleteDepotHighlightOfVehicle(v);
+ DeleteVehicleChain(v);
+ InvalidateWindowClasses(WC_AIRCRAFT_LIST);
+}
+
+/** Sell an aircraft.
+ * @param tile unused
+ * @param p1 vehicle ID to be sold
+ * @param p2 unused
+ */
+int32 CmdSellAircraft(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle *v;
+
+ if (!IsValidVehicleID(p1)) return CMD_ERROR;
+
+ v = GetVehicle(p1);
+
+ if (v->type != VEH_Aircraft || !CheckOwnership(v->owner)) return CMD_ERROR;
+ if (!IsAircraftInHangarStopped(v)) return_cmd_error(STR_A01B_AIRCRAFT_MUST_BE_STOPPED);
+
+ SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
+
+ if (flags & DC_EXEC) {
+ // Invalidate depot
+ InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
+ DoDeleteAircraft(v);
+ if (IsLocalPlayer())
+ InvalidateWindow(WC_REPLACE_VEHICLE, VEH_Aircraft); // updates the replace Aircraft window
+ }
+
+ return -(int32)v->value;
+}
+
+/** Start/Stop an aircraft.
+ * @param tile unused
+ * @param p1 aircraft ID to start/stop
+ * @param p2 unused
+ */
+int32 CmdStartStopAircraft(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle *v;
+ uint16 callback;
+
+ if (!IsValidVehicleID(p1)) return CMD_ERROR;
+
+ v = GetVehicle(p1);
+
+ if (v->type != VEH_Aircraft || !CheckOwnership(v->owner)) return CMD_ERROR;
+
+ // cannot stop airplane when in flight, or when taking off / landing
+ if (v->u.air.state >= STARTTAKEOFF && v->u.air.state < TERM7)
+ return_cmd_error(STR_A017_AIRCRAFT_IS_IN_FLIGHT);
+
+ /* Check if this aircraft can be started/stopped. The callback will fail or
+ * return 0xFF if it can. */
+ callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
+ if (callback != CALLBACK_FAILED && callback != 0xFF) {
+ StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
+ return_cmd_error(error);
+ }
+
+ if (flags & DC_EXEC) {
+ if (IsAircraftInHangarStopped(v)) {
+ DeleteVehicleNews(p1, STR_A014_AIRCRAFT_IS_WAITING_IN);
+ }
+
+ v->vehstatus ^= VS_STOPPED;
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
+ InvalidateWindowClasses(WC_AIRCRAFT_LIST);
+ }
+
+ return 0;
+}
+
+/** Send an aircraft to the hangar.
+ * @param tile unused
+ * @param p1 vehicle ID to send to the hangar
+ * @param p2 various bitmasked elements
+ * - p2 bit 0-3 - DEPOT_ flags (see vehicle.h)
+ * - p2 bit 8-10 - VLW flag (for mass goto depot)
+ */
+int32 CmdSendAircraftToHangar(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle *v;
+
+ if (p2 & DEPOT_MASS_SEND) {
+ /* Mass goto depot requested */
+ if (!ValidVLWFlags(p2 & VLW_MASK)) return CMD_ERROR;
+ return SendAllVehiclesToDepot(VEH_Aircraft, flags, p2 & DEPOT_SERVICE, _current_player, (p2 & VLW_MASK), p1);
+ }
+
+ if (!IsValidVehicleID(p1)) return CMD_ERROR;
+
+ v = GetVehicle(p1);
+
+ if (v->type != VEH_Aircraft || !CheckOwnership(v->owner) || IsAircraftInHangar(v)) return CMD_ERROR;
+
+ if (v->current_order.type == OT_GOTO_DEPOT && !(p2 & DEPOT_LOCATE_HANGAR)) {
+ if (!!(p2 & DEPOT_SERVICE) == HASBIT(v->current_order.flags, OFB_HALT_IN_DEPOT)) {
+ /* We called with a different DEPOT_SERVICE setting.
+ * Now we change the setting to apply the new one and let the vehicle head for the same hangar.
+ * Note: the if is (true for requesting service == true for ordered to stop in hangar) */
+ if (flags & DC_EXEC) {
+ TOGGLEBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ }
+ return 0;
+ }
+
+ if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of hangar orders
+ if (flags & DC_EXEC) {
+ if (v->current_order.flags & OF_UNLOAD) v->cur_order_index++;
+ v->current_order.type = OT_DUMMY;
+ v->current_order.flags = 0;
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ }
+ } else {
+ bool next_airport_has_hangar = true;
+ StationID next_airport_index = v->u.air.targetairport;
+ const Station *st = GetStation(next_airport_index);
+ /* If the station is not a valid airport or if it has no hangars */
+ if (!IsValidStation(st) || st->airport_tile == 0 || GetAirport(st->airport_type)->nof_depots == 0) {
+ StationID station;
+
+ // the aircraft has to search for a hangar on its own
+ station = FindNearestHangar(v);
+
+ next_airport_has_hangar = false;
+ if (station == INVALID_STATION) return CMD_ERROR;
+ st = GetStation(station);
+ next_airport_index = station;
+
+ }
+
+ if (flags & DC_EXEC) {
+ v->current_order.type = OT_GOTO_DEPOT;
+ v->current_order.flags = OF_NON_STOP;
+ if (!(p2 & DEPOT_SERVICE)) SETBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
+ v->current_order.refit_cargo = CT_INVALID;
+ v->current_order.dest = next_airport_index;
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ if (v->u.air.state == FLYING && !next_airport_has_hangar) {
+ /* The aircraft is now heading for a different hangar than the next in the orders */
+ AircraftNextAirportPos_and_Order(v);
+ v->u.air.targetairport = next_airport_index;
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+/** Refits an aircraft to the specified cargo type.
+ * @param tile unused
+ * @param p1 vehicle ID of the aircraft to refit
+ * @param p2 various bitstuffed elements
+ * - p2 = (bit 0-7) - the new cargo type to refit to
+ * - p2 = (bit 8-15) - the new cargo subtype to refit to
+ */
+int32 CmdRefitAircraft(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle *v;
+ int pass, mail;
+ int32 cost;
+ CargoID new_cid = GB(p2, 0, 8);
+ byte new_subtype = GB(p2, 8, 8);
+ const AircraftVehicleInfo *avi;
+ uint16 callback = CALLBACK_FAILED;
+
+ if (!IsValidVehicleID(p1)) return CMD_ERROR;
+
+ v = GetVehicle(p1);
+
+ if (v->type != VEH_Aircraft || !CheckOwnership(v->owner)) return CMD_ERROR;
+ if (!IsAircraftInHangarStopped(v)) return_cmd_error(STR_A01B_AIRCRAFT_MUST_BE_STOPPED);
+
+ avi = AircraftVehInfo(v->engine_type);
+
+ /* Check cargo */
+ if (new_cid > NUM_CARGO || !CanRefitTo(v->engine_type, new_cid)) return CMD_ERROR;
+
+ SET_EXPENSES_TYPE(EXPENSES_AIRCRAFT_RUN);
+
+ /* Check the refit capacity callback */
+ if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_REFIT_CAPACITY)) {
+ /* Back up the existing cargo type */
+ CargoID temp_cid = v->cargo_type;
+ byte temp_subtype = v->cargo_subtype;
+ v->cargo_type = new_cid;
+ v->cargo_subtype = new_subtype;
+
+ callback = GetVehicleCallback(CBID_VEHICLE_REFIT_CAPACITY, 0, 0, v->engine_type, v);
+
+ /* Restore the cargo type */
+ v->cargo_type = temp_cid;
+ v->cargo_subtype = temp_subtype;
+ }
+
+ if (callback == CALLBACK_FAILED) {
+ /* If the callback failed, or wasn't executed, use the aircraft's
+ * default cargo capacity */
+ pass = AircraftDefaultCargoCapacity(new_cid, v->engine_type);
+ } else {
+ pass = callback;
+ }
+ _returned_refit_capacity = pass;
+
+ cost = 0;
+ if (IsHumanPlayer(v->owner) && new_cid != v->cargo_type) {
+ cost = GetRefitCost(v->engine_type);
+ }
+
+ if (flags & DC_EXEC) {
+ Vehicle *u;
+ v->cargo_cap = pass;
+
+ u = v->next;
+ mail = (new_cid != CT_PASSENGERS) ? 0 : avi->mail_capacity;
+ u->cargo_cap = mail;
+ if (v->cargo_type == new_cid) {
+ v->cargo_count = min(pass, v->cargo_count);
+ u->cargo_count = min(mail, u->cargo_count);
+ } else {
+ v->cargo_count = 0;
+ u->cargo_count = 0;
+ }
+ v->cargo_type = new_cid;
+ v->cargo_subtype = new_subtype;
+ InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
+ InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
+ RebuildVehicleLists();
+ }
+
+ return cost;
+}
+
+
+static void CheckIfAircraftNeedsService(Vehicle *v)
+{
+ const Station* st;
+
+ if (_patches.servint_aircraft == 0) return;
+ if (!VehicleNeedsService(v)) return;
+ if (v->vehstatus & VS_STOPPED) return;
+
+ if (v->current_order.type == OT_GOTO_DEPOT &&
+ v->current_order.flags & OF_HALT_IN_DEPOT)
+ return;
+
+ if (_patches.gotodepot && VehicleHasDepotOrders(v)) return;
+
+ if (IsAircraftInHangar(v)) {
+ VehicleServiceInDepot(v);
+ return;
+ }
+
+ st = GetStation(v->current_order.dest);
+ // only goto depot if the target airport has terminals (eg. it is airport)
+ if (IsValidStation(st) && st->airport_tile != 0 && GetAirport(st->airport_type)->terminals != NULL) {
+// printf("targetairport = %d, st->index = %d\n", v->u.air.targetairport, st->index);
+// v->u.air.targetairport = st->index;
+ v->current_order.type = OT_GOTO_DEPOT;
+ v->current_order.flags = OF_NON_STOP;
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ } else if (v->current_order.type == OT_GOTO_DEPOT) {
+ v->current_order.type = OT_DUMMY;
+ v->current_order.flags = 0;
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ }
+}
+
+void OnNewDay_Aircraft(Vehicle *v)
+{
+ int32 cost;
+
+ if (v->subtype > 2) return;
+
+ if ((++v->day_counter & 7) == 0) DecreaseVehicleValue(v);
+
+ CheckOrders(v);
+
+ CheckVehicleBreakdown(v);
+ AgeVehicle(v);
+ CheckIfAircraftNeedsService(v);
+
+ if (v->vehstatus & VS_STOPPED) return;
+
+ cost = AircraftVehInfo(v->engine_type)->running_cost * _price.aircraft_running / 364;
+
+ v->profit_this_year -= cost >> 8;
+
+ SET_EXPENSES_TYPE(EXPENSES_AIRCRAFT_RUN);
+ SubtractMoneyFromPlayerFract(v->owner, cost);
+
+ InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
+ InvalidateWindowClasses(WC_AIRCRAFT_LIST);
+}
+
+void AircraftYearlyLoop(void)
+{
+ Vehicle *v;
+
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == VEH_Aircraft && v->subtype <= 2) {
+ v->profit_last_year = v->profit_this_year;
+ v->profit_this_year = 0;
+ InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
+ }
+ }
+}
+
+static void AgeAircraftCargo(Vehicle *v)
+{
+ if (_age_cargo_skip_counter != 0) return;
+
+ do {
+ if (v->cargo_days != 0xFF) v->cargo_days++;
+ v = v->next;
+ } while (v != NULL);
+}
+
+static void HelicopterTickHandler(Vehicle *v)
+{
+ Vehicle *u;
+ int tick,spd;
+ SpriteID img;
+
+ u = v->next->next;
+
+ if (u->vehstatus & VS_HIDDEN) return;
+
+ // if true, helicopter rotors do not rotate. This should only be the case if a helicopter is
+ // loading/unloading at a terminal or stopped
+ if (v->current_order.type == OT_LOADING || (v->vehstatus & VS_STOPPED)) {
+ if (u->cur_speed != 0) {
+ u->cur_speed++;
+ if (u->cur_speed >= 0x80 && u->u.air.state == HRS_ROTOR_MOVING_3) {
+ u->cur_speed = 0;
+ }
+ }
+ } else {
+ if (u->cur_speed == 0)
+ u->cur_speed = 0x70;
+
+ if (u->cur_speed >= 0x50)
+ u->cur_speed--;
+ }
+
+ tick = ++u->tick_counter;
+ spd = u->cur_speed >> 4;
+
+ if (spd == 0) {
+ u->u.air.state = HRS_ROTOR_STOPPED;
+ img = GetRotorImage(v);
+ if (u->cur_image == img) return;
+ } else if (tick >= spd) {
+ u->tick_counter = 0;
+ u->u.air.state++;
+ if (u->u.air.state > HRS_ROTOR_MOVING_3) u->u.air.state = HRS_ROTOR_MOVING_1;
+ img = GetRotorImage(v);
+ } else {
+ return;
+ }
+
+ u->cur_image = img;
+
+ BeginVehicleMove(u);
+ VehiclePositionChanged(u);
+ EndVehicleMove(u);
+}
+
+static void SetAircraftPosition(Vehicle *v, int x, int y, int z)
+{
+ Vehicle *u;
+ int safe_x;
+ int safe_y;
+
+ v->x_pos = x;
+ v->y_pos = y;
+ v->z_pos = z;
+
+ v->cur_image = GetAircraftImage(v, v->direction);
+ if (v->subtype == 0) v->next->next->cur_image = GetRotorImage(v);
+
+ BeginVehicleMove(v);
+ VehiclePositionChanged(v);
+ EndVehicleMove(v);
+
+ u = v->next;
+
+ safe_x = clamp(x, 0, MapMaxX() * TILE_SIZE);
+ safe_y = clamp(y - 1, 0, MapMaxY() * TILE_SIZE);
+ u->x_pos = x;
+ u->y_pos = y - ((v->z_pos-GetSlopeZ(safe_x, safe_y)) >> 3);;
+
+ safe_y = clamp(u->y_pos, 0, MapMaxY() * TILE_SIZE);
+ u->z_pos = GetSlopeZ(safe_x, safe_y);
+ u->cur_image = v->cur_image;
+
+ BeginVehicleMove(u);
+ VehiclePositionChanged(u);
+ EndVehicleMove(u);
+
+ u = u->next;
+ if (u != NULL) {
+ u->x_pos = x;
+ u->y_pos = y;
+ u->z_pos = z + 5;
+
+ BeginVehicleMove(u);
+ VehiclePositionChanged(u);
+ EndVehicleMove(u);
+ }
+}
+
+/** Handle Aircraft specific tasks when a an Aircraft enters a hangar
+ * @param *v Vehicle that enters the hangar
+ */
+void HandleAircraftEnterHangar(Vehicle *v)
+{
+ Vehicle *u;
+
+ v->subspeed = 0;
+ v->progress = 0;
+
+ u = v->next;
+ u->vehstatus |= VS_HIDDEN;
+ u = u->next;
+ if (u != NULL) {
+ u->vehstatus |= VS_HIDDEN;
+ u->cur_speed = 0;
+ }
+
+ SetAircraftPosition(v, v->x_pos, v->y_pos, v->z_pos);
+}
+
+static void PlayAircraftSound(const Vehicle* v)
+{
+ if (!PlayVehicleSound(v, VSE_START)) {
+ SndPlayVehicleFx(AircraftVehInfo(v->engine_type)->sfx, v);
+ }
+}
+
+static bool UpdateAircraftSpeed(Vehicle *v)
+{
+ uint spd = v->acceleration * 2;
+ byte t;
+
+ v->subspeed = (t=v->subspeed) + (byte)spd;
+ spd = min(v->cur_speed + (spd >> 8) + (v->subspeed < t), v->max_speed);
+
+ // adjust speed for broken vehicles
+ if (v->vehstatus & VS_AIRCRAFT_BROKEN) spd = min(spd, 27);
+
+ //updates statusbar only if speed have changed to save CPU time
+ if (spd != v->cur_speed) {
+ v->cur_speed = spd;
+ if (_patches.vehicle_speed)
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ }
+
+ if (!(v->direction & 1)) spd = spd * 3 / 4;
+
+ if (spd == 0) return false;
+
+ if ((byte)++spd == 0) return true;
+
+ v->progress = (t = v->progress) - (byte)spd;
+
+ return t < v->progress;
+}
+
+// get Aircraft running altitude
+static byte GetAircraftFlyingAltitude(const Vehicle *v)
+{
+ switch (v->max_speed) {
+ case 37: return 162;
+ case 74: return 171;
+ default: return 180;
+ }
+}
+
+static bool AircraftController(Vehicle *v)
+{
+ Station *st;
+ const AirportMovingData *amd;
+ Vehicle *u;
+ byte z,newdir,maxz,curz;
+ GetNewVehiclePosResult gp;
+ uint dist;
+ int x,y;
+
+ st = GetStation(v->u.air.targetairport);
+
+ // prevent going to 0,0 if airport is deleted.
+ {
+ TileIndex tile = st->airport_tile;
+
+ if (tile == 0) tile = st->xy;
+ // xy of destination
+ x = TileX(tile) * TILE_SIZE;
+ y = TileY(tile) * TILE_SIZE;
+ }
+
+ // get airport moving data
+ amd = GetAirportMovingData(st->airport_type, v->u.air.pos);
+
+ // Helicopter raise
+ if (amd->flag & AMED_HELI_RAISE) {
+ u = v->next->next;
+
+ // Make sure the rotors don't rotate too fast
+ if (u->cur_speed > 32) {
+ v->cur_speed = 0;
+ if (--u->cur_speed == 32) SndPlayVehicleFx(SND_18_HELICOPTER, v);
+ } else {
+ u->cur_speed = 32;
+ if (UpdateAircraftSpeed(v)) {
+ v->tile = 0;
+
+ // Reached altitude?
+ if (v->z_pos >= 184) {
+ v->cur_speed = 0;
+ return true;
+ }
+ SetAircraftPosition(v, v->x_pos, v->y_pos, v->z_pos+1);
+ }
+ }
+ return false;
+ }
+
+ // Helicopter landing.
+ if (amd->flag & AMED_HELI_LOWER) {
+ if (UpdateAircraftSpeed(v)) {
+ if (st->airport_tile == 0) {
+ // FIXME - AircraftController -> if station no longer exists, do not land
+ // helicopter will circle until sign disappears, then go to next order
+ // * what to do when it is the only order left, right now it just stays in 1 place
+ v->u.air.state = FLYING;
+ AircraftNextAirportPos_and_Order(v);
+ return false;
+ }
+
+ // Vehicle is now at the airport.
+ v->tile = st->airport_tile;
+
+ // Find altitude of landing position.
+ z = GetSlopeZ(x, y) + 1;
+ if (st->airport_type == AT_OILRIG) z += 54;
+ if (st->airport_type == AT_HELIPORT) z += 60;
+
+ if (z == v->z_pos) {
+ u = v->next->next;
+
+ // Increase speed of rotors. When speed is 80, we've landed.
+ if (u->cur_speed >= 80) return true;
+ u->cur_speed += 4;
+ } else if (v->z_pos > z) {
+ SetAircraftPosition(v, v->x_pos, v->y_pos, v->z_pos-1);
+ } else {
+ SetAircraftPosition(v, v->x_pos, v->y_pos, v->z_pos+1);
+ }
+ }
+ return false;
+ }
+
+ // Get distance from destination pos to current pos.
+ dist = myabs(x + amd->x - v->x_pos) + myabs(y + amd->y - v->y_pos);
+
+ // Need exact position?
+ if (!(amd->flag & AMED_EXACTPOS) && dist <= (amd->flag & AMED_SLOWTURN ? 8U : 4U))
+ return true;
+
+ // At final pos?
+ if (dist == 0) {
+ DirDiff dirdiff;
+
+ if (v->cur_speed > 12) v->cur_speed = 12;
+
+ // Change direction smoothly to final direction.
+ dirdiff = DirDifference(amd->direction, v->direction);
+ // if distance is 0, and plane points in right direction, no point in calling
+ // UpdateAircraftSpeed(). So do it only afterwards
+ if (dirdiff == DIRDIFF_SAME) {
+ v->cur_speed = 0;
+ return true;
+ }
+
+ if (!UpdateAircraftSpeed(v)) return false;
+
+ v->direction = ChangeDir(v->direction, dirdiff > DIRDIFF_REVERSE ? DIRDIFF_45LEFT : DIRDIFF_45RIGHT);
+ v->cur_speed >>= 1;
+
+ SetAircraftPosition(v, v->x_pos, v->y_pos, v->z_pos);
+ return false;
+ }
+
+ if (!(amd->flag & AMED_NOSPDCLAMP) && v->cur_speed > 12) v->cur_speed = 12;
+
+ if (!UpdateAircraftSpeed(v)) return false;
+
+ if (v->load_unload_time_rem != 0) v->load_unload_time_rem--;
+
+ // Turn. Do it slowly if in the air.
+ newdir = GetDirectionTowards(v, x + amd->x, y + amd->y);
+ if (newdir != v->direction) {
+ if (amd->flag & AMED_SLOWTURN) {
+ if (v->load_unload_time_rem == 0) v->load_unload_time_rem = 8;
+ v->direction = newdir;
+ } else {
+ v->cur_speed >>= 1;
+ v->direction = newdir;
+ }
+ }
+
+ // Move vehicle.
+ GetNewVehiclePos(v, &gp);
+ v->tile = gp.new_tile;
+
+ // If vehicle is in the air, use tile coordinate 0.
+ if (amd->flag & (AMED_TAKEOFF | AMED_SLOWTURN | AMED_LAND)) v->tile = 0;
+
+ // Adjust Z for land or takeoff?
+ z = v->z_pos;
+
+ if (amd->flag & AMED_TAKEOFF) {
+ z += 2;
+ maxz = GetAircraftFlyingAltitude(v);
+ if (z > maxz) z = maxz;
+ }
+
+ if (amd->flag & AMED_LAND) {
+ if (st->airport_tile == 0) {
+ v->u.air.state = FLYING;
+ AircraftNextAirportPos_and_Order(v);
+ // get aircraft back on running altitude
+ SetAircraftPosition(v, gp.x, gp.y, GetAircraftFlyingAltitude(v));
+ return false;
+ }
+
+ curz = GetSlopeZ(x, y) + 1;
+
+ if (curz > z) {
+ z++;
+ } else {
+ int t = max(1, dist - 4);
+
+ z -= ((z - curz) + t - 1) / t;
+ if (z < curz) z = curz;
+ }
+ }
+
+ // We've landed. Decrase speed when we're reaching end of runway.
+ if (amd->flag & AMED_BRAKE) {
+ curz = GetSlopeZ(x, y) + 1;
+
+ if (z > curz) {
+ z--;
+ } else if (z < curz) {
+ z++;
+ }
+
+ if (dist < 64 && v->cur_speed > 12) v->cur_speed -= 4;
+ }
+
+ SetAircraftPosition(v, gp.x, gp.y, z);
+ return false;
+}
+
+
+static void HandleCrashedAircraft(Vehicle *v)
+{
+ uint32 r;
+ Station *st;
+ int z;
+
+ v->u.air.crashed_counter++;
+
+ st = GetStation(v->u.air.targetairport);
+
+ // make aircraft crash down to the ground
+ if (v->u.air.crashed_counter < 500 && st->airport_tile==0 && ((v->u.air.crashed_counter % 3) == 0) ) {
+ z = GetSlopeZ(v->x_pos, v->y_pos);
+ v->z_pos -= 1;
+ if (v->z_pos == z) {
+ v->u.air.crashed_counter = 500;
+ v->z_pos++;
+ }
+ }
+
+ if (v->u.air.crashed_counter < 650) {
+ if (CHANCE16R(1,32,r)) {
+ static const DirDiff delta[] = {
+ DIRDIFF_45LEFT, DIRDIFF_SAME, DIRDIFF_SAME, DIRDIFF_45RIGHT
+ };
+
+ v->direction = ChangeDir(v->direction, delta[GB(r, 16, 2)]);
+ SetAircraftPosition(v, v->x_pos, v->y_pos, v->z_pos);
+ r = Random();
+ CreateEffectVehicleRel(v,
+ GB(r, 0, 4) + 4,
+ GB(r, 4, 4) + 4,
+ GB(r, 8, 4),
+ EV_EXPLOSION_SMALL);
+ }
+ } else if (v->u.air.crashed_counter >= 10000) {
+ // remove rubble of crashed airplane
+
+ // clear runway-in on all airports, set by crashing plane
+ // small airports use AIRPORT_BUSY, city airports use RUNWAY_IN_OUT_block, etc.
+ // but they all share the same number
+ CLRBITS(st->airport_flags, RUNWAY_IN_block);
+ CLRBITS(st->airport_flags, RUNWAY_IN_OUT_block); // commuter airport
+ CLRBITS(st->airport_flags, RUNWAY_IN2_block); // intercontinental
+
+ BeginVehicleMove(v);
+ EndVehicleMove(v);
+
+ DoDeleteAircraft(v);
+ }
+}
+
+static void HandleBrokenAircraft(Vehicle *v)
+{
+ if (v->breakdown_ctr != 1) {
+ v->breakdown_ctr = 1;
+ v->vehstatus |= VS_AIRCRAFT_BROKEN;
+
+ if (v->breakdowns_since_last_service != 255)
+ v->breakdowns_since_last_service++;
+ InvalidateWindow(WC_VEHICLE_VIEW, v->index);
+ InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
+ }
+}
+
+
+static void HandleAircraftSmoke(Vehicle *v)
+{
+ static const struct {
+ int8 x;
+ int8 y;
+ } smoke_pos[] = {
+ { 5, 5 },
+ { 6, 0 },
+ { 5, -5 },
+ { 0, -6 },
+ { -5, -5 },
+ { -6, 0 },
+ { -5, 5 },
+ { 0, 6 }
+ };
+
+ if (!(v->vehstatus & VS_AIRCRAFT_BROKEN)) return;
+
+ if (v->cur_speed < 10) {
+ v->vehstatus &= ~VS_AIRCRAFT_BROKEN;
+ v->breakdown_ctr = 0;
+ return;
+ }
+
+ if ((v->tick_counter & 0x1F) == 0) {
+ CreateEffectVehicleRel(v,
+ smoke_pos[v->direction].x,
+ smoke_pos[v->direction].y,
+ 2,
+ EV_SMOKE
+ );
+ }
+}
+
+static void ProcessAircraftOrder(Vehicle *v)
+{
+ const Order *order;
+
+ switch (v->current_order.type) {
+ case OT_GOTO_DEPOT:
+ if (!(v->current_order.flags & OF_PART_OF_ORDERS)) return;
+ if (v->current_order.flags & OF_SERVICE_IF_NEEDED &&
+ !VehicleNeedsService(v)) {
+ v->cur_order_index++;
+ }
+ break;
+
+ case OT_LOADING: return;
+
+ default: break;
+ }
+
+ if (v->cur_order_index >= v->num_orders) v->cur_order_index = 0;
+
+ order = GetVehicleOrder(v, v->cur_order_index);
+
+ if (order == NULL) {
+ v->current_order.type = OT_NOTHING;
+ v->current_order.flags = 0;
+ return;
+ }
+
+ if (order->type == OT_DUMMY && !CheckForValidOrders(v)) CrashAirplane(v);
+
+ if (order->type == v->current_order.type &&
+ order->flags == v->current_order.flags &&
+ order->dest == v->current_order.dest)
+ return;
+
+ v->current_order = *order;
+
+ // orders are changed in flight, ensure going to the right station
+ if (order->type == OT_GOTO_STATION && v->u.air.state == FLYING) {
+ AircraftNextAirportPos_and_Order(v);
+ v->u.air.targetairport = order->dest;
+ }
+
+ InvalidateVehicleOrder(v);
+
+ InvalidateWindowClasses(WC_AIRCRAFT_LIST);
+}
+
+/** Mark all views dirty for an aircraft.
+ * @param v vehicle to be redrawn.
+ */
+static void MarkAircraftDirty(Vehicle *v)
+{
+ v->cur_image = GetAircraftImage(v, v->direction);
+ if (v->subtype == 0) {
+ v->next->next->cur_image = GetRotorImage(v);
+ }
+ MarkAllViewportsDirty(v->left_coord, v->top_coord, v->right_coord + 1, v->bottom_coord + 1);
+}
+
+static void HandleAircraftLoading(Vehicle *v, int mode)
+{
+ if (v->current_order.type == OT_NOTHING) return;
+
+ if (v->current_order.type != OT_DUMMY) {
+ if (v->current_order.type != OT_LOADING) return;
+ if (mode != 0) return;
+ if (--v->load_unload_time_rem != 0) return;
+
+ if (CanFillVehicle(v) && (v->current_order.flags & OF_FULL_LOAD ||
+ (_patches.gradual_loading && !HASBIT(v->load_status, LS_LOADING_FINISHED)))) {
+ SET_EXPENSES_TYPE(EXPENSES_AIRCRAFT_INC);
+ if (LoadUnloadVehicle(v, false)) {
+ InvalidateWindow(WC_AIRCRAFT_LIST, v->owner);
+ MarkAircraftDirty(v);
+ }
+ return;
+ }
+
+ {
+ Order b = v->current_order;
+ v->current_order.type = OT_NOTHING;
+ v->current_order.flags = 0;
+ MarkAircraftDirty(v);
+ if (!(b.flags & OF_NON_STOP)) return;
+ }
+ }
+ v->cur_order_index++;
+ InvalidateVehicleOrder(v);
+}
+
+static void CrashAirplane(Vehicle *v)
+{
+ uint16 amt;
+ Station *st;
+ StringID newsitem;
+
+ v->vehstatus |= VS_CRASHED;
+ v->u.air.crashed_counter = 0;
+
+ CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE);
+
+ InvalidateWindow(WC_VEHICLE_VIEW, v->index);
+
+ amt = 2;
+ if (v->cargo_type == CT_PASSENGERS) amt += v->cargo_count;
+ SetDParam(0, amt);
+
+ v->cargo_count = 0;
+ v->next->cargo_count = 0,
+ st = GetStation(v->u.air.targetairport);
+ if (st->airport_tile == 0) {
+ newsitem = STR_PLANE_CRASH_OUT_OF_FUEL;
+ } else {
+ SetDParam(1, st->index);
+ newsitem = STR_A034_PLANE_CRASH_DIE_IN_FIREBALL;
+ }
+
+ SetDParam(1, st->index);
+ AddNewsItem(newsitem,
+ NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ACCIDENT, 0),
+ v->index,
+ 0);
+
+ SndPlayVehicleFx(SND_12_EXPLOSION, v);
+}
+
+static void MaybeCrashAirplane(Vehicle *v)
+{
+ Station *st;
+ uint16 prob;
+ uint i;
+
+ st = GetStation(v->u.air.targetairport);
+
+ //FIXME -- MaybeCrashAirplane -> increase crashing chances of very modern airplanes on smaller than AT_METROPOLITAN airports
+ prob = 0x10000 / 1500;
+ if (((st->airport_type == AT_SMALL) || (st->airport_type == AT_COMMUTER)) && (AircraftVehInfo(v->engine_type)->subtype & AIR_FAST) && !_cheats.no_jetcrash.value) {
+ prob = 0x10000 / 20;
+ }
+
+ if (GB(Random(), 0, 16) > prob) return;
+
+ // Crash the airplane. Remove all goods stored at the station.
+ for (i = 0; i != NUM_CARGO; i++) {
+ st->goods[i].rating = 1;
+ SB(st->goods[i].waiting_acceptance, 0, 12, 0);
+ }
+
+ CrashAirplane(v);
+}
+
+// we've landed and just arrived at a terminal
+static void AircraftEntersTerminal(Vehicle *v)
+{
+ Station *st;
+ Order old_order;
+
+ if (v->current_order.type == OT_GOTO_DEPOT) return;
+
+ st = GetStation(v->u.air.targetairport);
+ v->last_station_visited = v->u.air.targetairport;
+
+ /* Check if station was ever visited before */
+ if (!(st->had_vehicle_of_type & HVOT_AIRCRAFT)) {
+ uint32 flags;
+
+ st->had_vehicle_of_type |= HVOT_AIRCRAFT;
+ SetDParam(0, st->index);
+ // show newsitem of celebrating citizens
+ flags = (v->owner == _local_player) ? NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ARRIVAL_PLAYER, 0) : NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ARRIVAL_OTHER, 0);
+ AddNewsItem(
+ STR_A033_CITIZENS_CELEBRATE_FIRST,
+ flags,
+ v->index,
+ 0);
+ }
+
+ old_order = v->current_order;
+ v->current_order.type = OT_LOADING;
+ v->current_order.flags = 0;
+
+ if (old_order.type == OT_GOTO_STATION &&
+ v->current_order.dest == v->last_station_visited) {
+ v->current_order.flags =
+ (old_order.flags & (OF_FULL_LOAD | OF_UNLOAD | OF_TRANSFER)) | OF_NON_STOP;
+ }
+
+ SET_EXPENSES_TYPE(EXPENSES_AIRCRAFT_INC);
+ LoadUnloadVehicle(v, true);
+ MarkAircraftDirty(v);
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ InvalidateWindowClasses(WC_AIRCRAFT_LIST);
+}
+
+static void AircraftLand(Vehicle *v)
+{
+ v->sprite_width = v->sprite_height = 2;
+}
+
+static void AircraftLandAirplane(Vehicle *v)
+{
+ AircraftLand(v);
+ if (!PlayVehicleSound(v, VSE_TOUCHDOWN)) {
+ SndPlayVehicleFx(SND_17_SKID_PLANE, v);
+ }
+ MaybeCrashAirplane(v);
+}
+
+// set the right pos when heading to other airports after takeoff
+static void AircraftNextAirportPos_and_Order(Vehicle *v)
+{
+ const Station* st;
+ const AirportFTAClass *apc;
+
+ if (v->current_order.type == OT_GOTO_STATION ||
+ v->current_order.type == OT_GOTO_DEPOT)
+ v->u.air.targetairport = v->current_order.dest;
+
+ st = GetStation(v->u.air.targetairport);
+ apc = GetAirport(st->airport_type);
+ v->u.air.pos = v->u.air.previous_pos = apc->entry_point;
+}
+
+static void AircraftLeaveHangar(Vehicle *v)
+{
+ v->cur_speed = 0;
+ v->subspeed = 0;
+ v->progress = 0;
+ v->direction = 3;
+ v->vehstatus &= ~VS_HIDDEN;
+ {
+ Vehicle *u = v->next;
+ u->vehstatus &= ~VS_HIDDEN;
+
+ // Rotor blades
+ u = u->next;
+ if (u != NULL) {
+ u->vehstatus &= ~VS_HIDDEN;
+ u->cur_speed = 80;
+ }
+ }
+
+ VehicleServiceInDepot(v);
+ SetAircraftPosition(v, v->x_pos, v->y_pos, v->z_pos);
+ InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
+ InvalidateWindowClasses(WC_AIRCRAFT_LIST);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+/////////////////// AIRCRAFT MOVEMENT SCHEME ////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+static void AircraftEventHandler_EnterTerminal(Vehicle *v, const AirportFTAClass *apc)
+{
+ AircraftEntersTerminal(v);
+ v->u.air.state = apc->layout[v->u.air.pos].heading;
+}
+
+static void AircraftEventHandler_EnterHangar(Vehicle *v, const AirportFTAClass *apc)
+{
+ VehicleEnterDepot(v);
+ v->u.air.state = apc->layout[v->u.air.pos].heading;
+}
+
+// In an Airport Hangar
+static void AircraftEventHandler_InHangar(Vehicle *v, const AirportFTAClass *apc)
+{
+ // if we just arrived, execute EnterHangar first
+ if (v->u.air.previous_pos != v->u.air.pos) {
+ AircraftEventHandler_EnterHangar(v, apc);
+ return;
+ }
+
+ // if we were sent to the depot, stay there
+ if (v->current_order.type == OT_GOTO_DEPOT && (v->vehstatus & VS_STOPPED)) {
+ v->current_order.type = OT_NOTHING;
+ v->current_order.flags = 0;
+ return;
+ }
+
+ if (v->current_order.type != OT_GOTO_STATION &&
+ v->current_order.type != OT_GOTO_DEPOT)
+ return;
+
+ // if the block of the next position is busy, stay put
+ if (AirportHasBlock(v, &apc->layout[v->u.air.pos], apc)) return;
+
+ // We are already at the target airport, we need to find a terminal
+ if (v->current_order.dest == v->u.air.targetairport) {
+ // FindFreeTerminal:
+ // 1. Find a free terminal, 2. Occupy it, 3. Set the vehicle's state to that terminal
+ if (v->subtype != 0) {
+ if (!AirportFindFreeTerminal(v, apc)) return; // airplane
+ } else {
+ if (!AirportFindFreeHelipad(v, apc)) return; // helicopter
+ }
+ } else { // Else prepare for launch.
+ // airplane goto state takeoff, helicopter to helitakeoff
+ v->u.air.state = (v->subtype != 0) ? TAKEOFF : HELITAKEOFF;
+ }
+ AircraftLeaveHangar(v);
+ AirportMove(v, apc);
+}
+
+// At one of the Airport's Terminals
+static void AircraftEventHandler_AtTerminal(Vehicle *v, const AirportFTAClass *apc)
+{
+ // if we just arrived, execute EnterTerminal first
+ if (v->u.air.previous_pos != v->u.air.pos) {
+ AircraftEventHandler_EnterTerminal(v, apc);
+ // on an airport with helipads, a helicopter will always land there
+ // and get serviced at the same time - patch setting
+ if (_patches.serviceathelipad) {
+ if (v->subtype == 0 && apc->helipads != NULL) {
+ // an exerpt of ServiceAircraft, without the invisibility stuff
+ v->date_of_last_service = _date;
+ v->breakdowns_since_last_service = 0;
+ v->reliability = GetEngine(v->engine_type)->reliability;
+ InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
+ }
+ }
+ return;
+ }
+
+ if (v->current_order.type == OT_NOTHING) return;
+
+ // if the block of the next position is busy, stay put
+ if (AirportHasBlock(v, &apc->layout[v->u.air.pos], apc)) return;
+
+ // airport-road is free. We either have to go to another airport, or to the hangar
+ // ---> start moving
+
+ switch (v->current_order.type) {
+ case OT_GOTO_STATION: // ready to fly to another airport
+ // airplane goto state takeoff, helicopter to helitakeoff
+ v->u.air.state = (v->subtype != 0) ? TAKEOFF : HELITAKEOFF;
+ break;
+ case OT_GOTO_DEPOT: // visit hangar for serivicing, sale, etc.
+ if (v->current_order.dest == v->u.air.targetairport) {
+ v->u.air.state = HANGAR;
+ } else {
+ v->u.air.state = (v->subtype != 0) ? TAKEOFF : HELITAKEOFF;
+ }
+ break;
+ default: // orders have been deleted (no orders), goto depot and don't bother us
+ v->current_order.type = OT_NOTHING;
+ v->current_order.flags = 0;
+ v->u.air.state = HANGAR;
+ }
+ AirportMove(v, apc);
+}
+
+static void AircraftEventHandler_General(Vehicle *v, const AirportFTAClass *apc)
+{
+ assert("OK, you shouldn't be here, check your Airport Scheme!" && 0);
+}
+
+static void AircraftEventHandler_TakeOff(Vehicle *v, const AirportFTAClass *apc) {
+ PlayAircraftSound(v); // play takeoffsound for airplanes
+ v->u.air.state = STARTTAKEOFF;
+}
+
+static void AircraftEventHandler_StartTakeOff(Vehicle *v, const AirportFTAClass *apc)
+{
+ v->sprite_width = v->sprite_height = 24; // ??? no idea what this is
+ v->u.air.state = ENDTAKEOFF;
+}
+
+static void AircraftEventHandler_EndTakeOff(Vehicle *v, const AirportFTAClass *apc)
+{
+ v->u.air.state = FLYING;
+ // get the next position to go to, differs per airport
+ AircraftNextAirportPos_and_Order(v);
+}
+
+static void AircraftEventHandler_HeliTakeOff(Vehicle *v, const AirportFTAClass *apc)
+{
+ const Player* p = GetPlayer(v->owner);
+ v->sprite_width = v->sprite_height = 24; // ??? no idea what this is
+ v->u.air.state = FLYING;
+ // get the next position to go to, differs per airport
+ AircraftNextAirportPos_and_Order(v);
+
+ // check if the aircraft needs to be replaced or renewed and send it to a hangar if needed
+ // unless it is due for renewal but the engine is no longer available
+ if (v->owner == _local_player && (
+ EngineHasReplacementForPlayer(p, v->engine_type) ||
+ ((p->engine_renew && v->age - v->max_age > p->engine_renew_months * 30) &&
+ HASBIT(GetEngine(v->engine_type)->player_avail, _local_player))
+ )) {
+ _current_player = _local_player;
+ DoCommandP(v->tile, v->index, DEPOT_SERVICE | DEPOT_LOCATE_HANGAR, NULL, CMD_SEND_AIRCRAFT_TO_HANGAR | CMD_SHOW_NO_ERROR);
+ _current_player = OWNER_NONE;
+ }
+}
+
+static void AircraftEventHandler_Flying(Vehicle *v, const AirportFTAClass *apc)
+{
+ Station *st;
+ byte landingtype;
+ AirportFTA *current;
+ uint16 tcur_speed, tsubspeed;
+
+ st = GetStation(v->u.air.targetairport);
+ // flying device is accepted at this station
+ // small airport --> no helicopters (AIRCRAFT_ONLY)
+ // all other airports --> all types of flying devices (ALL)
+ // heliport/oilrig, etc --> no airplanes (HELICOPTERS_ONLY)
+ // runway busy or not allowed to use this airstation, circle
+ if (v->subtype != apc->acc_planes &&
+ st->airport_tile != 0 &&
+ (st->owner == OWNER_NONE || st->owner == v->owner)) {
+ // {32,FLYING,NOTHING_block,37}, {32,LANDING,N,33}, {32,HELILANDING,N,41},
+ // if it is an airplane, look for LANDING, for helicopter HELILANDING
+ // it is possible to choose from multiple landing runways, so loop until a free one is found
+ landingtype = (v->subtype != 0) ? LANDING : HELILANDING;
+ current = apc->layout[v->u.air.pos].next;
+ while (current != NULL) {
+ if (current->heading == landingtype) {
+ // save speed before, since if AirportHasBlock is false, it resets them to 0
+ // we don't want that for plane in air
+ // hack for speed thingie
+ tcur_speed = v->cur_speed;
+ tsubspeed = v->subspeed;
+ if (!AirportHasBlock(v, current, apc)) {
+ v->u.air.state = landingtype; // LANDING / HELILANDING
+ // it's a bit dirty, but I need to set position to next position, otherwise
+ // if there are multiple runways, plane won't know which one it took (because
+ // they all have heading LANDING). And also occupy that block!
+ v->u.air.pos = current->next_position;
+ SETBITS(st->airport_flags, apc->layout[v->u.air.pos].block);
+ return;
+ }
+ v->cur_speed = tcur_speed;
+ v->subspeed = tsubspeed;
+ }
+ current = current->next;
+ }
+ }
+ v->u.air.state = FLYING;
+ v->u.air.pos = apc->layout[v->u.air.pos].next_position;
+}
+
+static void AircraftEventHandler_Landing(Vehicle *v, const AirportFTAClass *apc)
+{
+ const Player* p = GetPlayer(v->owner);
+ AircraftLandAirplane(v); // maybe crash airplane
+ v->u.air.state = ENDLANDING;
+ // check if the aircraft needs to be replaced or renewed and send it to a hangar if needed
+ if (v->current_order.type != OT_GOTO_DEPOT && v->owner == _local_player) {
+ // only the vehicle owner needs to calculate the rest (locally)
+ if (EngineHasReplacementForPlayer(p, v->engine_type) ||
+ (p->engine_renew && v->age - v->max_age > (p->engine_renew_months * 30))) {
+ // send the aircraft to the hangar at next airport
+ _current_player = _local_player;
+ DoCommandP(v->tile, v->index, DEPOT_SERVICE, NULL, CMD_SEND_AIRCRAFT_TO_HANGAR | CMD_SHOW_NO_ERROR);
+ _current_player = OWNER_NONE;
+ }
+ }
+}
+
+static void AircraftEventHandler_HeliLanding(Vehicle *v, const AirportFTAClass *apc)
+{
+ AircraftLand(v); // helicopters don't crash
+ v->u.air.state = HELIENDLANDING;
+}
+
+static void AircraftEventHandler_EndLanding(Vehicle *v, const AirportFTAClass *apc)
+{
+ // next block busy, don't do a thing, just wait
+ if (AirportHasBlock(v, &apc->layout[v->u.air.pos], apc)) return;
+
+ // if going to terminal (OT_GOTO_STATION) choose one
+ // 1. in case all terminals are busy AirportFindFreeTerminal() returns false or
+ // 2. not going for terminal (but depot, no order),
+ // --> get out of the way to the hangar.
+ if (v->current_order.type == OT_GOTO_STATION) {
+ if (AirportFindFreeTerminal(v, apc)) return;
+ }
+ v->u.air.state = HANGAR;
+
+}
+
+static void AircraftEventHandler_HeliEndLanding(Vehicle *v, const AirportFTAClass *apc)
+{
+ // next block busy, don't do a thing, just wait
+ if (AirportHasBlock(v, &apc->layout[v->u.air.pos], apc)) return;
+
+ // if going to helipad (OT_GOTO_STATION) choose one. If airport doesn't have helipads, choose terminal
+ // 1. in case all terminals/helipads are busy (AirportFindFreeHelipad() returns false) or
+ // 2. not going for terminal (but depot, no order),
+ // --> get out of the way to the hangar IF there are terminals on the airport.
+ // --> else TAKEOFF
+ // the reason behind this is that if an airport has a terminal, it also has a hangar. Airplanes
+ // must go to a hangar.
+ if (v->current_order.type == OT_GOTO_STATION) {
+ if (AirportFindFreeHelipad(v, apc)) return;
+ }
+ v->u.air.state = (apc->nof_depots != 0) ? HANGAR : HELITAKEOFF;
+}
+
+typedef void AircraftStateHandler(Vehicle *v, const AirportFTAClass *apc);
+static AircraftStateHandler * const _aircraft_state_handlers[] = {
+ AircraftEventHandler_General, // TO_ALL = 0
+ AircraftEventHandler_InHangar, // HANGAR = 1
+ AircraftEventHandler_AtTerminal, // TERM1 = 2
+ AircraftEventHandler_AtTerminal, // TERM2 = 3
+ AircraftEventHandler_AtTerminal, // TERM3 = 4
+ AircraftEventHandler_AtTerminal, // TERM4 = 5
+ AircraftEventHandler_AtTerminal, // TERM5 = 6
+ AircraftEventHandler_AtTerminal, // TERM6 = 7
+ AircraftEventHandler_AtTerminal, // HELIPAD1 = 8
+ AircraftEventHandler_AtTerminal, // HELIPAD2 = 9
+ AircraftEventHandler_TakeOff, // TAKEOFF = 10
+ AircraftEventHandler_StartTakeOff, // STARTTAKEOFF = 11
+ AircraftEventHandler_EndTakeOff, // ENDTAKEOFF = 12
+ AircraftEventHandler_HeliTakeOff, // HELITAKEOFF = 13
+ AircraftEventHandler_Flying, // FLYING = 14
+ AircraftEventHandler_Landing, // LANDING = 15
+ AircraftEventHandler_EndLanding, // ENDLANDING = 16
+ AircraftEventHandler_HeliLanding, // HELILANDING = 17
+ AircraftEventHandler_HeliEndLanding, // HELIENDLANDING = 18
+ AircraftEventHandler_AtTerminal, // TERM7 = 19
+ AircraftEventHandler_AtTerminal, // TERM8 = 20
+ AircraftEventHandler_AtTerminal, // HELIPAD3 = 21
+ AircraftEventHandler_AtTerminal, // HELIPAD4 = 22
+};
+
+static void AirportClearBlock(const Vehicle *v, const AirportFTAClass *apc)
+{
+ // we have left the previous block, and entered the new one. Free the previous block
+ if (apc->layout[v->u.air.previous_pos].block != apc->layout[v->u.air.pos].block) {
+ Station *st = GetStation(v->u.air.targetairport);
+
+ CLRBITS(st->airport_flags, apc->layout[v->u.air.previous_pos].block);
+ }
+}
+
+static void AirportGoToNextPosition(Vehicle *v, const AirportFTAClass *apc)
+{
+ // if aircraft is not in position, wait until it is
+ if (!AircraftController(v)) return;
+
+ AirportClearBlock(v, apc);
+ AirportMove(v, apc); // move aircraft to next position
+}
+
+// gets pos from vehicle and next orders
+static bool AirportMove(Vehicle *v, const AirportFTAClass *apc)
+{
+ AirportFTA *current;
+ byte prev_pos;
+
+ // error handling
+ if (v->u.air.pos >= apc->nofelements) {
+ DEBUG(misc, 0, "[Ap] position %d is not valid for current airport. Max position is %d", v->u.air.pos, apc->nofelements-1);
+ assert(v->u.air.pos < apc->nofelements);
+ }
+
+ current = &apc->layout[v->u.air.pos];
+ // we have arrived in an important state (eg terminal, hangar, etc.)
+ if (current->heading == v->u.air.state) {
+ prev_pos = v->u.air.pos; // location could be changed in state, so save it before-hand
+ _aircraft_state_handlers[v->u.air.state](v, apc);
+ if (v->u.air.state != FLYING) v->u.air.previous_pos = prev_pos;
+ return true;
+ }
+
+ v->u.air.previous_pos = v->u.air.pos; // save previous location
+
+ // there is only one choice to move to
+ if (current->next == NULL) {
+ if (AirportSetBlocks(v, current, apc)) {
+ v->u.air.pos = current->next_position;
+ } // move to next position
+ return false;
+ }
+
+ // there are more choices to choose from, choose the one that
+ // matches our heading
+ do {
+ if (v->u.air.state == current->heading || current->heading == TO_ALL) {
+ if (AirportSetBlocks(v, current, apc)) {
+ v->u.air.pos = current->next_position;
+ } // move to next position
+ return false;
+ }
+ current = current->next;
+ } while (current != NULL);
+
+ DEBUG(misc, 0, "[Ap] cannot move further on Airport! (pos %d state %d)", v->u.air.pos, v->u.air.state);
+ DEBUG(misc, 0, "[Ap] airport entry point: %d, Vehicle: %d", apc->entry_point, v->index);
+ assert(0);
+ return false;
+}
+
+// returns true if the road ahead is busy, eg. you must wait before proceeding
+static bool AirportHasBlock(Vehicle *v, const AirportFTA *current_pos, const AirportFTAClass *apc)
+{
+ const AirportFTA *reference = &apc->layout[v->u.air.pos];
+ const AirportFTA *next = &apc->layout[current_pos->next_position];
+
+ // same block, then of course we can move
+ if (apc->layout[current_pos->position].block != next->block) {
+ const Station *st = GetStation(v->u.air.targetairport);
+ uint32 airport_flags = next->block;
+
+ // check additional possible extra blocks
+ if (current_pos != reference && current_pos->block != NOTHING_block) {
+ airport_flags |= current_pos->block;
+ }
+
+ if (HASBITS(st->airport_flags, airport_flags)) {
+ v->cur_speed = 0;
+ v->subspeed = 0;
+ return true;
+ }
+ }
+ return false;
+}
+
+// returns true on success. Eg, next block was free and we have occupied it
+static bool AirportSetBlocks(Vehicle *v, AirportFTA *current_pos, const AirportFTAClass *apc)
+{
+ AirportFTA *next = &apc->layout[current_pos->next_position];
+ AirportFTA *reference = &apc->layout[v->u.air.pos];
+
+ // if the next position is in another block, check it and wait until it is free
+ if ((apc->layout[current_pos->position].block & next->block) != next->block) {
+ uint32 airport_flags = next->block;
+ Station* st = GetStation(v->u.air.targetairport);
+ //search for all all elements in the list with the same state, and blocks != N
+ // this means more blocks should be checked/set
+ AirportFTA *current = current_pos;
+ if (current == reference) current = current->next;
+ while (current != NULL) {
+ if (current->heading == current_pos->heading && current->block != 0) {
+ airport_flags |= current->block;
+ break;
+ }
+ current = current->next;
+ };
+
+ // if the block to be checked is in the next position, then exclude that from
+ // checking, because it has been set by the airplane before
+ if (current_pos->block == next->block) airport_flags ^= next->block;
+
+ if (HASBITS(st->airport_flags, airport_flags)) {
+ v->cur_speed = 0;
+ v->subspeed = 0;
+ return false;
+ }
+
+ if (next->block != NOTHING_block) {
+ SETBITS(st->airport_flags, airport_flags); // occupy next block
+ }
+ }
+ return true;
+}
+
+static bool FreeTerminal(Vehicle *v, byte i, byte last_terminal)
+{
+ Station *st = GetStation(v->u.air.targetairport);
+ for (; i < last_terminal; i++) {
+ if (!HASBIT(st->airport_flags, _airport_terminal_flag[i])) {
+ // TERMINAL# HELIPAD#
+ v->u.air.state = _airport_terminal_state[i]; // start moving to that terminal/helipad
+ SETBIT(st->airport_flags, _airport_terminal_flag[i]); // occupy terminal/helipad
+ return true;
+ }
+ }
+ return false;
+}
+
+static uint GetNumTerminals(const AirportFTAClass *apc)
+{
+ uint num = 0;
+ uint i;
+
+ for (i = apc->terminals[0]; i > 0; i--) num += apc->terminals[i];
+
+ return num;
+}
+
+static bool AirportFindFreeTerminal(Vehicle *v, const AirportFTAClass *apc)
+{
+ /* example of more terminalgroups
+ * {0,HANGAR,NOTHING_block,1}, {0,255,TERM_GROUP1_block,0}, {0,255,TERM_GROUP2_ENTER_block,1}, {0,0,N,1},
+ * Heading 255 denotes a group. We see 2 groups here:
+ * 1. group 0 -- TERM_GROUP1_block (check block)
+ * 2. group 1 -- TERM_GROUP2_ENTER_block (check block)
+ * First in line is checked first, group 0. If the block (TERM_GROUP1_block) is free, it
+ * looks at the corresponding terminals of that group. If no free ones are found, other
+ * possible groups are checked (in this case group 1, since that is after group 0). If that
+ * fails, then attempt fails and plane waits
+ */
+ if (apc->terminals[0] > 1) {
+ Station *st = GetStation(v->u.air.targetairport);
+ AirportFTA *temp = apc->layout[v->u.air.pos].next;
+
+ while (temp != NULL) {
+ if (temp->heading == 255) {
+ if (!HASBITS(st->airport_flags, temp->block)) {
+ int target_group;
+ int i;
+ int group_start = 0;
+ int group_end;
+
+ //read which group do we want to go to?
+ //(the first free group)
+ target_group = temp->next_position + 1;
+
+ //at what terminal does the group start?
+ //that means, sum up all terminals of
+ //groups with lower number
+ for (i = 1; i < target_group; i++)
+ group_start += apc->terminals[i];
+
+ group_end = group_start + apc->terminals[target_group];
+ if (FreeTerminal(v, group_start, group_end)) return true;
+ }
+ } else {
+ /* once the heading isn't 255, we've exhausted the possible blocks.
+ * So we cannot move */
+ return false;
+ }
+ temp = temp->next;
+ }
+ }
+
+ // if there is only 1 terminalgroup, all terminals are checked (starting from 0 to max)
+ return FreeTerminal(v, 0, GetNumTerminals(apc));
+}
+
+static uint GetNumHelipads(const AirportFTAClass *apc)
+{
+ uint num = 0;
+ uint i;
+
+ for (i = apc->helipads[0]; i > 0; i--) num += apc->helipads[i];
+
+ return num;
+}
+
+
+static bool AirportFindFreeHelipad(Vehicle *v, const AirportFTAClass *apc)
+{
+ // if an airport doesn't have helipads, use terminals
+ if (apc->helipads == NULL) return AirportFindFreeTerminal(v, apc);
+
+ // if there are more helicoptergroups, pick one, just as in AirportFindFreeTerminal()
+ if (apc->helipads[0] > 1) {
+ const Station* st = GetStation(v->u.air.targetairport);
+ const AirportFTA* temp = apc->layout[v->u.air.pos].next;
+
+ while (temp != NULL) {
+ if (temp->heading == 255) {
+ if (!HASBITS(st->airport_flags, temp->block)) {
+ int target_group;
+ int i;
+ int group_start = 0;
+ int group_end;
+
+ //read which group do we want to go to?
+ //(the first free group)
+ target_group = temp->next_position + 1;
+
+ //at what terminal does the group start?
+ //that means, sum up all terminals of
+ //groups with lower number
+ for (i = 1; i < target_group; i++)
+ group_start += apc->helipads[i];
+
+ group_end = group_start + apc->helipads[target_group];
+ if (FreeTerminal(v, group_start, group_end)) return true;
+ }
+ } else {
+ /* once the heading isn't 255, we've exhausted the possible blocks.
+ * So we cannot move */
+ return false;
+ }
+ temp = temp->next;
+ }
+ } else {
+ // only 1 helicoptergroup, check all helipads
+ // The blocks for helipads start after the last terminal (MAX_TERMINALS)
+ return FreeTerminal(v, MAX_TERMINALS, GetNumHelipads(apc) + MAX_TERMINALS);
+ }
+ return false; // it shouldn't get here anytime, but just to be sure
+}
+
+static void AircraftEventHandler(Vehicle *v, int loop)
+{
+ v->tick_counter++;
+
+ if (v->vehstatus & VS_CRASHED) {
+ HandleCrashedAircraft(v);
+ return;
+ }
+
+ if (v->vehstatus & VS_STOPPED) return;
+
+ /* aircraft is broken down? */
+ if (v->breakdown_ctr != 0) {
+ if (v->breakdown_ctr <= 2) {
+ HandleBrokenAircraft(v);
+ } else {
+ v->breakdown_ctr--;
+ }
+ }
+
+ HandleAircraftSmoke(v);
+ ProcessAircraftOrder(v);
+ HandleAircraftLoading(v, loop);
+
+ if (v->current_order.type >= OT_LOADING) return;
+
+ // pass the right airport structure to the functions
+ // DEREF_STATION gets target airport (Station *st), its type is passed to GetAirport
+ // that returns the correct layout depending on type
+ AirportGoToNextPosition(v, GetAirport(GetStation(v->u.air.targetairport)->airport_type));
+}
+
+void Aircraft_Tick(Vehicle *v)
+{
+ int i;
+
+ if (v->subtype > 2) return;
+
+ if (v->subtype == 0) HelicopterTickHandler(v);
+
+ AgeAircraftCargo(v);
+
+ for (i = 0; i != 6; i++) {
+ AircraftEventHandler(v, i);
+ if (v->type != VEH_Aircraft) // In case it was deleted
+ break;
+ }
+}
+
+void UpdateOilRig(void)
+{
+ Station* st;
+
+ FOR_ALL_STATIONS(st) {
+ if (st->airport_type == 5) st->airport_type = AT_OILRIG;
+ }
+}
+
+// need to be called to load aircraft from old version
+void UpdateOldAircraft(void)
+{
+ Station *st;
+ Vehicle *v_oldstyle;
+ GetNewVehiclePosResult gp;
+
+ // set airport_flags to 0 for all airports just to be sure
+ FOR_ALL_STATIONS(st) {
+ st->airport_flags = 0; // reset airport
+ // type of oilrig has been moved, update it (3-5)
+ if (st->airport_type == 3) st->airport_type = AT_OILRIG;
+ }
+
+ FOR_ALL_VEHICLES(v_oldstyle) {
+ // airplane has another vehicle with subtype 4 (shadow), helicopter also has 3 (rotor)
+ // skip those
+ if (v_oldstyle->type == VEH_Aircraft && v_oldstyle->subtype <= 2) {
+ // airplane in terminal stopped doesn't hurt anyone, so goto next
+ if (v_oldstyle->vehstatus & VS_STOPPED && v_oldstyle->u.air.state == 0) {
+ v_oldstyle->u.air.state = HANGAR;
+ continue;
+ }
+
+ AircraftLeaveHangar(v_oldstyle); // make airplane visible if it was in a depot for example
+ v_oldstyle->vehstatus &= ~VS_STOPPED; // make airplane moving
+ v_oldstyle->u.air.state = FLYING;
+ AircraftNextAirportPos_and_Order(v_oldstyle); // move it to the entry point of the airport
+ GetNewVehiclePos(v_oldstyle, &gp); // get the position of the plane (to be used for setting)
+ v_oldstyle->tile = 0; // aircraft in air is tile=0
+
+ // correct speed of helicopter-rotors
+ if (v_oldstyle->subtype == 0) v_oldstyle->next->next->cur_speed = 32;
+
+ // set new position x,y,z
+ SetAircraftPosition(v_oldstyle, gp.x, gp.y, GetAircraftFlyingAltitude(v_oldstyle));
+ }
+ }
+}
+
+void UpdateAirplanesOnNewStation(Station *st)
+{
+ GetNewVehiclePosResult gp;
+ Vehicle *v;
+ byte takeofftype;
+ uint16 cnt;
+ // only 1 station is updated per function call, so it is enough to get entry_point once
+ const AirportFTAClass *ap = GetAirport(st->airport_type);
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == VEH_Aircraft && v->subtype <= 2) {
+ if (v->u.air.targetairport == st->index) { // if heading to this airport
+ /* update position of airplane. If plane is not flying, landing, or taking off
+ *you cannot delete airport, so it doesn't matter
+ */
+ if (v->u.air.state >= FLYING) { // circle around
+ v->u.air.pos = v->u.air.previous_pos = ap->entry_point;
+ v->u.air.state = FLYING;
+ // landing plane needs to be reset to flying height (only if in pause mode upgrade,
+ // in normal mode, plane is reset in AircraftController. It doesn't hurt for FLYING
+ GetNewVehiclePos(v, &gp);
+ // set new position x,y,z
+ SetAircraftPosition(v, gp.x, gp.y, GetAircraftFlyingAltitude(v));
+ } else {
+ assert(v->u.air.state == ENDTAKEOFF || v->u.air.state == HELITAKEOFF);
+ takeofftype = (v->subtype == 0) ? HELITAKEOFF : ENDTAKEOFF;
+ // search in airportdata for that heading
+ // easiest to do, since this doesn't happen a lot
+ for (cnt = 0; cnt < ap->nofelements; cnt++) {
+ if (ap->layout[cnt].heading == takeofftype) {
+ v->u.air.pos = ap->layout[cnt].position;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/aircraft_gui.c b/src/aircraft_gui.c
new file mode 100644
index 000000000..ded25b463
--- /dev/null
+++ b/src/aircraft_gui.c
@@ -0,0 +1,350 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "aircraft.h"
+#include "debug.h"
+#include "functions.h"
+#include "table/sprites.h"
+#include "table/strings.h"
+#include "map.h"
+#include "window.h"
+#include "gui.h"
+#include "vehicle.h"
+#include "gfx.h"
+#include "command.h"
+#include "engine.h"
+#include "viewport.h"
+#include "player.h"
+#include "depot.h"
+#include "vehicle_gui.h"
+#include "newgrf_engine.h"
+
+
+void CcCloneAircraft(bool success, TileIndex tile, uint32 p1, uint32 p2)
+{
+ if (success) ShowAircraftViewWindow(GetVehicle(_new_vehicle_id));
+}
+
+static void AircraftDetailsWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ const Vehicle *v = GetVehicle(w->window_number);
+
+ SetWindowWidgetDisabledState(w, 2, v->owner != _local_player);
+
+ /* Disable service-scroller when interval is set to disabled */
+ SetWindowWidgetDisabledState(w, 5, !_patches.servint_aircraft);
+ SetWindowWidgetDisabledState(w, 6, !_patches.servint_aircraft);
+
+ SetDParam(0, v->string_id);
+ SetDParam(1, v->unitnumber);
+ DrawWindowWidgets(w);
+
+ /* Draw running cost */
+ {
+ int year = v->age / 366;
+
+ SetDParam(1, year);
+
+ SetDParam(0, (v->age + 365 < v->max_age) ? STR_AGE : STR_AGE_RED);
+ SetDParam(2, v->max_age / 366);
+ SetDParam(3, _price.aircraft_running * AircraftVehInfo(v->engine_type)->running_cost >> 8);
+ DrawString(2, 15, STR_A00D_AGE_RUNNING_COST_YR, 0);
+ }
+
+ /* Draw max speed */
+ {
+ SetDParam(0, v->max_speed * 128 / 10);
+ DrawString(2, 25, STR_A00E_MAX_SPEED, 0);
+ }
+
+ /* Draw profit */
+ {
+ SetDParam(0, v->profit_this_year);
+ SetDParam(1, v->profit_last_year);
+ DrawString(2, 35, STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR, 0);
+ }
+
+ /* Draw breakdown & reliability */
+ {
+ SetDParam(0, v->reliability * 100 >> 16);
+ SetDParam(1, v->breakdowns_since_last_service);
+ DrawString(2, 45, STR_A010_RELIABILITY_BREAKDOWNS, 0);
+ }
+
+ /* Draw service interval text */
+ {
+ SetDParam(0, v->service_interval);
+ SetDParam(1, v->date_of_last_service);
+ DrawString(13, 103, _patches.servint_ispercent?STR_SERVICING_INTERVAL_PERCENT:STR_883C_SERVICING_INTERVAL_DAYS, 0);
+ }
+
+ DrawAircraftImage(v, 3, 57, INVALID_VEHICLE);
+
+ {
+ const Vehicle *u;
+ int y = 57;
+
+ do {
+ if (v->subtype <= 2) {
+ SetDParam(0, GetCustomEngineName(v->engine_type));
+ SetDParam(1, v->build_year);
+ SetDParam(2, v->value);
+ DrawString(60, y, STR_A011_BUILT_VALUE, 0);
+ y += 10;
+
+ SetDParam(0, v->cargo_type);
+ SetDParam(1, v->cargo_cap);
+ u = v->next;
+ SetDParam(2, u->cargo_type);
+ SetDParam(3, u->cargo_cap);
+ DrawString(60, y, (u->cargo_cap != 0) ? STR_A019_CAPACITY : STR_A01A_CAPACITY, 0);
+ y += 14;
+ }
+
+ if (v->cargo_count != 0) {
+
+ /* Cargo names (fix pluralness) */
+ SetDParam(0, v->cargo_type);
+ SetDParam(1, v->cargo_count);
+ SetDParam(2, v->cargo_source);
+ DrawString(60, y, STR_8813_FROM, 0);
+
+ y += 10;
+ }
+ } while ( (v=v->next) != NULL);
+ }
+ } break;
+
+ case WE_CLICK: {
+ int mod;
+ const Vehicle *v;
+ switch (e->we.click.widget) {
+ case 2: /* rename */
+ v = GetVehicle(w->window_number);
+ SetDParam(0, v->unitnumber);
+ ShowQueryString(v->string_id, STR_A030_NAME_AIRCRAFT, 31, 150, w, CS_ALPHANUMERAL);
+ break;
+ case 5: /* increase int */
+ mod = _ctrl_pressed? 5 : 10;
+ goto do_change_service_int;
+ case 6: /* decrease int */
+ mod = _ctrl_pressed?- 5 : -10;
+do_change_service_int:
+ v = GetVehicle(w->window_number);
+
+ mod = GetServiceIntervalClamped(mod + v->service_interval);
+ if (mod == v->service_interval) return;
+
+ DoCommandP(v->tile, v->index, mod, NULL, CMD_CHANGE_SERVICE_INT | CMD_MSG(STR_018A_CAN_T_CHANGE_SERVICING));
+ break;
+ }
+ } break;
+
+ case WE_ON_EDIT_TEXT:
+ if (e->we.edittext.str[0] != '\0') {
+ _cmd_text = e->we.edittext.str;
+ DoCommandP(0, w->window_number, 0, NULL,
+ CMD_NAME_VEHICLE | CMD_MSG(STR_A031_CAN_T_NAME_AIRCRAFT));
+ }
+ break;
+ }
+}
+
+
+static const Widget _aircraft_details_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW },
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 349, 0, 13, STR_A00C_DETAILS, STR_018C_WINDOW_TITLE_DRAG_THIS },
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 350, 389, 0, 13, STR_01AA_NAME, STR_A032_NAME_AIRCRAFT },
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 389, 14, 55, 0x0, STR_NULL },
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 389, 56, 101, 0x0, STR_NULL },
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 0, 10, 102, 107, STR_0188, STR_884D_INCREASE_SERVICING_INTERVAL },
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 0, 10, 108, 113, STR_0189, STR_884E_DECREASE_SERVICING_INTERVAL },
+{ WWT_PANEL, RESIZE_NONE, 14, 11, 389, 102, 113, 0x0, STR_NULL },
+{ WIDGETS_END},
+};
+
+static const WindowDesc _aircraft_details_desc = {
+ WDP_AUTO, WDP_AUTO, 390, 114,
+ WC_VEHICLE_DETAILS, WC_VEHICLE_VIEW,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _aircraft_details_widgets,
+ AircraftDetailsWndProc
+};
+
+
+static void ShowAircraftDetailsWindow(const Vehicle *v)
+{
+ Window *w;
+ VehicleID veh = v->index;
+
+ DeleteWindowById(WC_VEHICLE_ORDERS, veh);
+ DeleteWindowById(WC_VEHICLE_DETAILS, veh);
+
+ w = AllocateWindowDescFront(&_aircraft_details_desc, veh);
+ w->caption_color = v->owner;
+// w->vscroll.cap = 6;
+// w->traindetails_d.tab = 0;
+}
+
+
+static const Widget _aircraft_view_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW },
+{ WWT_CAPTION, RESIZE_RIGHT, 14, 11, 237, 0, 13, STR_A00A, STR_018C_WINDOW_TITLE_DRAG_THIS },
+{ WWT_STICKYBOX, RESIZE_LR, 14, 238, 249, 0, 13, 0x0, STR_STICKY_BUTTON },
+{ WWT_PANEL, RESIZE_RB, 14, 0, 231, 14, 103, 0x0, STR_NULL },
+{ WWT_INSET, RESIZE_RB, 14, 2, 229, 16, 101, 0x0, STR_NULL },
+{ WWT_PUSHBTN, RESIZE_RTB, 14, 0, 237, 104, 115, 0x0, STR_A027_CURRENT_AIRCRAFT_ACTION },
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 232, 249, 14, 31, SPR_CENTRE_VIEW_VEHICLE, STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT },
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 232, 249, 32, 49, SPR_SEND_AIRCRAFT_TODEPOT,STR_A02A_SEND_AIRCRAFT_TO_HANGAR },
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 232, 249, 50, 67, SPR_REFIT_VEHICLE, STR_A03B_REFIT_AIRCRAFT_TO_CARRY },
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 232, 249, 68, 85, SPR_SHOW_ORDERS, STR_A028_SHOW_AIRCRAFT_S_ORDERS },
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 232, 249, 86, 103, SPR_SHOW_VEHICLE_DETAILS, STR_A02B_SHOW_AIRCRAFT_DETAILS },
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 232, 249, 32, 49, SPR_CLONE_AIRCRAFT, STR_CLONE_AIRCRAFT_INFO },
+{ WWT_PANEL, RESIZE_LRB, 14, 232, 249, 104, 103, 0x0, STR_NULL },
+{ WWT_RESIZEBOX, RESIZE_LRTB, 14, 238, 249, 104, 115, 0x0, STR_NULL },
+{ WIDGETS_END},
+};
+
+
+static void AircraftViewWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ const Vehicle *v = GetVehicle(w->window_number);
+ StringID str;
+ bool is_localplayer = v->owner == _local_player;
+
+ SetWindowWidgetDisabledState(w, 7, !is_localplayer);
+ SetWindowWidgetDisabledState(w, 8, !IsAircraftInHangarStopped(v) || !is_localplayer);
+ SetWindowWidgetDisabledState(w, 11, !is_localplayer);
+
+
+ /* draw widgets & caption */
+ SetDParam(0, v->string_id);
+ SetDParam(1, v->unitnumber);
+ DrawWindowWidgets(w);
+
+ if (v->vehstatus & VS_CRASHED) {
+ str = STR_8863_CRASHED;
+ } else if (v->vehstatus & VS_STOPPED) {
+ str = STR_8861_STOPPED;
+ } else {
+ switch (v->current_order.type) {
+ case OT_GOTO_STATION: {
+ SetDParam(0, v->current_order.dest);
+ SetDParam(1, v->cur_speed * 128 / 10);
+ str = STR_HEADING_FOR_STATION + _patches.vehicle_speed;
+ } break;
+
+ case OT_GOTO_DEPOT: {
+ /* Aircrafts always go to a station, even if you say depot */
+ SetDParam(0, v->current_order.dest);
+ SetDParam(1, v->cur_speed * 128 / 10);
+ if (HASBIT(v->current_order.flags, OFB_HALT_IN_DEPOT) && !HASBIT(v->current_order.flags, OFB_PART_OF_ORDERS)) {
+ str = STR_HEADING_FOR_HANGAR + _patches.vehicle_speed;
+ } else {
+ str = STR_HEADING_FOR_HANGAR_SERVICE + _patches.vehicle_speed;
+ }
+ } break;
+
+ case OT_LOADING:
+ str = STR_882F_LOADING_UNLOADING;
+ break;
+
+ default:
+ if (v->num_orders == 0) {
+ str = STR_NO_ORDERS + _patches.vehicle_speed;
+ SetDParam(0, v->cur_speed * 128 / 10);
+ } else {
+ str = STR_EMPTY;
+ }
+ break;
+ }
+ }
+
+ /* draw the flag plus orders */
+ DrawSprite(v->vehstatus & VS_STOPPED ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, 2, w->widget[5].top + 1);
+ DrawStringCenteredTruncated(w->widget[5].left + 8, w->widget[5].right, w->widget[5].top + 1, str, 0);
+ DrawWindowViewport(w);
+ } break;
+
+ case WE_CLICK: {
+ const Vehicle *v = GetVehicle(w->window_number);
+
+ switch (e->we.click.widget) {
+ case 5: /* start stop */
+ DoCommandP(v->tile, v->index, 0, NULL, CMD_START_STOP_AIRCRAFT | CMD_MSG(STR_A016_CAN_T_STOP_START_AIRCRAFT));
+ break;
+ case 6: /* center main view */
+ ScrollMainWindowTo(v->x_pos, v->y_pos);
+ break;
+ case 7: /* goto hangar */
+ DoCommandP(v->tile, v->index, _ctrl_pressed ? DEPOT_SERVICE : 0, NULL, CMD_SEND_AIRCRAFT_TO_HANGAR | CMD_MSG(STR_A012_CAN_T_SEND_AIRCRAFT_TO));
+ break;
+ case 8: /* refit */
+ ShowVehicleRefitWindow(v, INVALID_VEH_ORDER_ID);
+ break;
+ case 9: /* show orders */
+ ShowOrdersWindow(v);
+ break;
+ case 10: /* show details */
+ ShowAircraftDetailsWindow(v);
+ break;
+ case 11:
+ /* clone vehicle */
+ DoCommandP(v->tile, v->index, _ctrl_pressed ? 1 : 0, CcCloneAircraft, CMD_CLONE_VEHICLE | CMD_MSG(STR_A008_CAN_T_BUILD_AIRCRAFT));
+ break;
+ }
+ } break;
+
+ case WE_RESIZE:
+ w->viewport->width += e->we.sizing.diff.x;
+ w->viewport->height += e->we.sizing.diff.y;
+ w->viewport->virtual_width += e->we.sizing.diff.x;
+ w->viewport->virtual_height += e->we.sizing.diff.y;
+ break;
+
+ case WE_DESTROY:
+ DeleteWindowById(WC_VEHICLE_ORDERS, w->window_number);
+ DeleteWindowById(WC_VEHICLE_REFIT, w->window_number);
+ DeleteWindowById(WC_VEHICLE_DETAILS, w->window_number);
+ break;
+
+ case WE_MOUSELOOP: {
+ const Vehicle *v = GetVehicle(w->window_number);
+ bool plane_stopped = IsAircraftInHangarStopped(v);
+
+ /* Widget 7 (send to hangar) must be hidden if the plane is already stopped in hangar.
+ * Widget 11 (clone) should then be shown, since cloning is allowed only while in hangar and stopped.
+ * This sytem allows to have two buttons, on top of each other*/
+ if (plane_stopped != IsWindowWidgetHidden(w, 7) || plane_stopped == IsWindowWidgetHidden(w, 11)) {
+ SetWindowWidgetHiddenState(w, 7, plane_stopped); // send to hangar
+ SetWindowWidgetHiddenState(w, 11, !plane_stopped); // clone
+ SetWindowDirty(w);
+ }
+ } break;
+ }
+}
+
+
+static const WindowDesc _aircraft_view_desc = {
+ WDP_AUTO, WDP_AUTO, 250, 116,
+ WC_VEHICLE_VIEW ,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
+ _aircraft_view_widgets,
+ AircraftViewWndProc
+};
+
+
+void ShowAircraftViewWindow(const Vehicle *v)
+{
+ Window *w = AllocateWindowDescFront(&_aircraft_view_desc, v->index);
+
+ if (w != NULL) {
+ w->caption_color = v->owner;
+ AssignWindowViewport(w, 3, 17, 0xE2, 0x54, w->window_number | (1 << 31), 0);
+ }
+}
diff --git a/src/airport.c b/src/airport.c
new file mode 100644
index 000000000..2135bd11b
--- /dev/null
+++ b/src/airport.c
@@ -0,0 +1,489 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "debug.h"
+#include "map.h"
+#include "airport.h"
+#include "macros.h"
+#include "variables.h"
+#include "airport_movement.h"
+#include "date.h"
+
+/* Uncomment this to print out a full report of the airport-structure
+ * You should either use
+ * - true: full-report, print out every state and choice with string-names
+ * OR
+ * - false: give a summarized report which only shows current and next position */
+//#define DEBUG_AIRPORT false
+
+static AirportFTAClass *CountryAirport;
+static AirportFTAClass *CityAirport;
+static AirportFTAClass *Oilrig;
+static AirportFTAClass *Heliport;
+static AirportFTAClass *MetropolitanAirport;
+static AirportFTAClass *InternationalAirport;
+static AirportFTAClass *CommuterAirport;
+static AirportFTAClass *HeliDepot;
+static AirportFTAClass *IntercontinentalAirport;
+static AirportFTAClass *HeliStation;
+
+static void AirportFTAClass_Constructor(AirportFTAClass *apc,
+ const byte *terminals, const byte *helipads,
+ const byte entry_point, const byte acc_planes,
+ const AirportFTAbuildup *apFA,
+ const TileIndexDiffC *depots, const byte nof_depots,
+ uint size_x, uint size_y
+);
+static void AirportFTAClass_Destructor(AirportFTAClass *apc);
+
+static uint16 AirportGetNofElements(const AirportFTAbuildup *apFA);
+static void AirportBuildAutomata(AirportFTAClass *apc, const AirportFTAbuildup *apFA);
+static byte AirportGetTerminalCount(const byte *terminals, byte *groups);
+static byte AirportTestFTA(const AirportFTAClass *apc);
+
+#ifdef DEBUG_AIRPORT
+static void AirportPrintOut(const AirportFTAClass *apc, bool full_report);
+#endif /* DEBUG_AIRPORT */
+
+void InitializeAirports(void)
+{
+ // country airport
+ CountryAirport = malloc(sizeof(AirportFTAClass));
+
+ AirportFTAClass_Constructor(
+ CountryAirport,
+ _airport_terminal_country,
+ NULL,
+ 16,
+ ALL,
+ _airport_fta_country,
+ _airport_depots_country,
+ lengthof(_airport_depots_country),
+ 4, 3
+ );
+
+ // city airport
+ CityAirport = malloc(sizeof(AirportFTAClass));
+
+ AirportFTAClass_Constructor(
+ CityAirport,
+ _airport_terminal_city,
+ NULL,
+ 19,
+ ALL,
+ _airport_fta_city,
+ _airport_depots_city,
+ lengthof(_airport_depots_city),
+ 6, 6
+ );
+
+ // metropolitan airport
+ MetropolitanAirport = malloc(sizeof(AirportFTAClass));
+
+ AirportFTAClass_Constructor(
+ MetropolitanAirport,
+ _airport_terminal_metropolitan,
+ NULL,
+ 20,
+ ALL,
+ _airport_fta_metropolitan,
+ _airport_depots_metropolitan,
+ lengthof(_airport_depots_metropolitan),
+ 6, 6
+ );
+
+ // international airport
+ InternationalAirport = (AirportFTAClass *)malloc(sizeof(AirportFTAClass));
+
+ AirportFTAClass_Constructor(
+ InternationalAirport,
+ _airport_terminal_international,
+ _airport_helipad_international,
+ 37,
+ ALL,
+ _airport_fta_international,
+ _airport_depots_international,
+ lengthof(_airport_depots_international),
+ 7, 7
+ );
+
+ // intercontintental airport
+ IntercontinentalAirport = (AirportFTAClass *)malloc(sizeof(AirportFTAClass));
+
+ AirportFTAClass_Constructor(
+ IntercontinentalAirport,
+ _airport_terminal_intercontinental,
+ _airport_helipad_intercontinental,
+ 43,
+ ALL,
+ _airport_fta_intercontinental,
+ _airport_depots_intercontinental,
+ lengthof(_airport_depots_intercontinental),
+ 9,11
+ );
+
+ // heliport, oilrig
+ Heliport = (AirportFTAClass *)malloc(sizeof(AirportFTAClass));
+
+ AirportFTAClass_Constructor(
+ Heliport,
+ NULL,
+ _airport_helipad_heliport_oilrig,
+ 7,
+ HELICOPTERS_ONLY,
+ _airport_fta_heliport_oilrig,
+ NULL,
+ 0,
+ 1, 1
+ );
+
+ Oilrig = Heliport; // exactly the same structure for heliport/oilrig, so share state machine
+
+ // commuter airport
+ CommuterAirport = malloc(sizeof(AirportFTAClass));
+
+ AirportFTAClass_Constructor(
+ CommuterAirport,
+ _airport_terminal_commuter,
+ _airport_helipad_commuter,
+ 22,
+ ALL,
+ _airport_fta_commuter,
+ _airport_depots_commuter,
+ lengthof(_airport_depots_commuter),
+ 5,4
+ );
+
+ // helidepot airport
+ HeliDepot = malloc(sizeof(AirportFTAClass));
+
+ AirportFTAClass_Constructor(
+ HeliDepot,
+ NULL,
+ _airport_helipad_helidepot,
+ 4,
+ HELICOPTERS_ONLY,
+ _airport_fta_helidepot,
+ _airport_depots_helidepot,
+ lengthof(_airport_depots_helidepot),
+ 2,2
+ );
+
+ // helistation airport
+ HeliStation = malloc(sizeof(AirportFTAClass));
+
+ AirportFTAClass_Constructor(
+ HeliStation,
+ NULL,
+ _airport_helipad_helistation,
+ 25,
+ HELICOPTERS_ONLY,
+ _airport_fta_helistation,
+ _airport_depots_helistation,
+ lengthof(_airport_depots_helistation),
+ 4,2
+ );
+
+}
+
+void UnInitializeAirports(void)
+{
+ AirportFTAClass_Destructor(CountryAirport);
+ AirportFTAClass_Destructor(CityAirport);
+ AirportFTAClass_Destructor(Heliport);
+ AirportFTAClass_Destructor(MetropolitanAirport);
+ AirportFTAClass_Destructor(InternationalAirport);
+ AirportFTAClass_Destructor(CommuterAirport);
+ AirportFTAClass_Destructor(HeliDepot);
+ AirportFTAClass_Destructor(IntercontinentalAirport);
+ AirportFTAClass_Destructor(HeliStation);
+}
+
+static void AirportFTAClass_Constructor(AirportFTAClass *apc,
+ const byte *terminals, const byte *helipads,
+ const byte entry_point, const byte acc_planes,
+ const AirportFTAbuildup *apFA,
+ const TileIndexDiffC *depots, const byte nof_depots,
+ uint size_x, uint size_y
+)
+{
+ byte nofterminals, nofhelipads;
+ byte nofterminalgroups, nofhelipadgroups;
+
+ apc->size_x = size_x;
+ apc->size_y = size_y;
+
+ /* Set up the terminal and helipad count for an airport.
+ * TODO: If there are more than 10 terminals or 4 helipads, internal variables
+ * need to be changed, so don't allow that for now */
+ nofterminals = AirportGetTerminalCount(terminals, &nofterminalgroups);
+ if (nofterminals > MAX_TERMINALS) {
+ DEBUG(misc, 0, "[Ap] only a maximum of %d terminals are supported (requested %d)", MAX_TERMINALS, nofterminals);
+ assert(nofterminals <= MAX_TERMINALS);
+ }
+ apc->terminals = terminals;
+
+ nofhelipads = AirportGetTerminalCount(helipads, &nofhelipadgroups);
+ if (nofhelipads > MAX_HELIPADS) {
+ DEBUG(misc, 0, "[Ap] only a maximum of %d helipads are supported (requested %d)", MAX_HELIPADS, nofhelipads);
+ assert(nofhelipads <= MAX_HELIPADS);
+ }
+ apc->helipads = helipads;
+
+ /* Get the number of elements from the source table. We also double check this
+ * with the entry point which must be within bounds and use this information
+ * later on to build and validate the state machine */
+ apc->nofelements = AirportGetNofElements(apFA);
+ if (entry_point >= apc->nofelements) {
+ DEBUG(misc, 0, "[Ap] entry (%d) must be within the airport (maximum %d)", entry_point, apc->nofelements);
+ assert(entry_point < apc->nofelements);
+ }
+
+ apc->acc_planes = acc_planes;
+ apc->entry_point = entry_point;
+ apc->airport_depots = depots;
+ apc->nof_depots = nof_depots;
+
+ /* Build the state machine itself */
+ AirportBuildAutomata(apc, apFA);
+ DEBUG(misc, 2, "[Ap] #count %3d; #term %2d (%dgrp); #helipad %2d (%dgrp); entry %3d",
+ apc->nofelements, nofterminals, nofterminalgroups, nofhelipads, nofhelipadgroups, apc->entry_point);
+
+ /* Test if everything went allright. This is only a rude static test checking
+ * the symantic correctness. By no means does passing the test mean that the
+ * airport is working correctly or will not deadlock for example */
+ { byte ret = AirportTestFTA(apc);
+ if (ret != MAX_ELEMENTS) DEBUG(misc, 0, "[Ap] problem with element: %d", ret - 1);
+ assert(ret == MAX_ELEMENTS);
+ }
+
+#ifdef DEBUG_AIRPORT
+ AirportPrintOut(apc, DEBUG_AIRPORT);
+#endif
+}
+
+static void AirportFTAClass_Destructor(AirportFTAClass *apc)
+{
+ int i;
+ AirportFTA *current, *next;
+
+ for (i = 0; i < apc->nofelements; i++) {
+ current = apc->layout[i].next;
+ while (current != NULL) {
+ next = current->next;
+ free(current);
+ current = next;
+ };
+ }
+ free(apc->layout);
+ free(apc);
+}
+
+/** Get the number of elements of a source Airport state automata
+ * Since it is actually just a big array of AirportFTA types, we only
+ * know one element from the other by differing 'position' identifiers */
+static uint16 AirportGetNofElements(const AirportFTAbuildup *apFA)
+{
+ int i;
+ uint16 nofelements = 0;
+ int temp = apFA[0].position;
+
+ for (i = 0; i < MAX_ELEMENTS; i++) {
+ if (temp != apFA[i].position) {
+ nofelements++;
+ temp = apFA[i].position;
+ }
+ if (apFA[i].position == MAX_ELEMENTS) break;
+ }
+ return nofelements;
+}
+
+/* We calculate the terminal/helipod count based on the data passed to us
+ * This data (terminals) contains an index as a first element as to how many
+ * groups there are, and then the number of terminals for each group */
+static byte AirportGetTerminalCount(const byte *terminals, byte *groups)
+{
+ byte i;
+ byte nof_terminals = 0;
+ *groups = 0;
+
+ if (terminals != NULL) {
+ i = terminals[0];
+ *groups = i;
+ while (i-- > 0) {
+ terminals++;
+ assert(*terminals != 0); // no empty groups please
+ nof_terminals += *terminals;
+ }
+ }
+ return nof_terminals;
+}
+
+static void AirportBuildAutomata(AirportFTAClass *apc, const AirportFTAbuildup *apFA)
+{
+ AirportFTA *current;
+ AirportFTA *FAutomata = malloc(sizeof(AirportFTA) * apc->nofelements);
+ uint16 internalcounter = 0;
+ uint16 i;
+
+ apc->layout = FAutomata;
+ for (i = 0; i < apc->nofelements; i++) {
+ current = &apc->layout[i];
+ current->position = apFA[internalcounter].position;
+ current->heading = apFA[internalcounter].heading;
+ current->block = apFA[internalcounter].block;
+ current->next_position = apFA[internalcounter].next;
+
+ // outgoing nodes from the same position, create linked list
+ while (current->position == apFA[internalcounter + 1].position) {
+ AirportFTA *newNode = malloc(sizeof(AirportFTA));
+
+ newNode->position = apFA[internalcounter + 1].position;
+ newNode->heading = apFA[internalcounter + 1].heading;
+ newNode->block = apFA[internalcounter + 1].block;
+ newNode->next_position = apFA[internalcounter + 1].next;
+ // create link
+ current->next = newNode;
+ current = current->next;
+ internalcounter++;
+ } // while
+ current->next = NULL;
+ internalcounter++;
+ }
+}
+
+static byte AirportTestFTA(const AirportFTAClass *apc)
+{
+ byte position, i, next_position;
+ AirportFTA *current, *first;
+ next_position = 0;
+
+ for (i = 0; i < apc->nofelements; i++) {
+ position = apc->layout[i].position;
+ if (position != next_position) return i;
+ current = first = &apc->layout[i];
+
+ for (; current != NULL; current = current->next) {
+ /* A heading must always be valid. The only exceptions are
+ * - multiple choices as start, identified by a special value of 255
+ * - terminal group which is identified by a special value of 255 */
+ if (current->heading > MAX_HEADINGS) {
+ if (current->heading != 255) return i;
+ if (current == first && current->next == NULL) return i;
+ if (current != first && current->next_position > apc->terminals[0]) return i;
+ }
+
+ /* If there is only one choice, it must be at the end */
+ if (current->heading == 0 && current->next != NULL) return i;
+ /* Obviously the elements of the linked list must have the same identifier */
+ if (position != current->position) return i;
+ /* A next position must be within bounds */
+ if (current->next_position >= apc->nofelements) return i;
+ }
+ next_position++;
+ }
+ return MAX_ELEMENTS;
+}
+
+#ifdef DEBUG_AIRPORT
+static const char* const _airport_heading_strings[] = {
+ "TO_ALL",
+ "HANGAR",
+ "TERM1",
+ "TERM2",
+ "TERM3",
+ "TERM4",
+ "TERM5",
+ "TERM6",
+ "HELIPAD1",
+ "HELIPAD2",
+ "TAKEOFF",
+ "STARTTAKEOFF",
+ "ENDTAKEOFF",
+ "HELITAKEOFF",
+ "FLYING",
+ "LANDING",
+ "ENDLANDING",
+ "HELILANDING",
+ "HELIENDLANDING",
+ "TERM7",
+ "TERM8",
+ "HELIPAD3",
+ "HELIPAD4",
+ "DUMMY" // extra heading for 255
+};
+
+static uint AirportBlockToString(uint32 block)
+{
+ uint i = 0;
+ if (block & 0xffff0000) { block >>= 16; i += 16; }
+ if (block & 0x0000ff00) { block >>= 8; i += 8; }
+ if (block & 0x000000f0) { block >>= 4; i += 4; }
+ if (block & 0x0000000c) { block >>= 2; i += 2; }
+ if (block & 0x00000002) { i += 1; }
+ return i;
+}
+
+static void AirportPrintOut(const AirportFTAClass *apc, bool full_report)
+{
+ uint16 i;
+
+ if (!full_report) printf("(P = Current Position; NP = Next Position)\n");
+
+ for (i = 0; i < apc->nofelements; i++) {
+ AirportFTA *current = &apc->layout[i];
+
+ for (; current != NULL; current = current->next) {
+ if (full_report) {
+ byte heading = (current->heading == 255) ? MAX_HEADINGS + 1 : current->heading;
+ printf("\tPos:%2d NPos:%2d Heading:%15s Block:%2d\n", current->position,
+ current->next_position, _airport_heading_strings[heading],
+ AirportBlockToString(current->block));
+ } else {
+ printf("P:%2d NP:%2d", current->position, current->next_position);
+ }
+ }
+ printf("\n");
+ }
+}
+#endif
+
+const AirportFTAClass *GetAirport(const byte airport_type)
+{
+ //FIXME -- AircraftNextAirportPos_and_Order -> Needs something nicer, don't like this code
+ // needs constant change if more airports are added
+ switch (airport_type) {
+ default: NOT_REACHED();
+ case AT_SMALL: return CountryAirport;
+ case AT_LARGE: return CityAirport;
+ case AT_METROPOLITAN: return MetropolitanAirport;
+ case AT_HELIPORT: return Heliport;
+ case AT_OILRIG: return Oilrig;
+ case AT_INTERNATIONAL: return InternationalAirport;
+ case AT_COMMUTER: return CommuterAirport;
+ case AT_HELIDEPOT: return HeliDepot;
+ case AT_INTERCON: return IntercontinentalAirport;
+ case AT_HELISTATION: return HeliStation;
+ }
+}
+
+const AirportMovingData *GetAirportMovingData(byte airport_type, byte position)
+{
+ assert(airport_type < lengthof(_airport_moving_datas));
+ assert(position < GetAirport(airport_type)->nofelements);
+ return &_airport_moving_datas[airport_type][position];
+}
+
+uint32 GetValidAirports(void)
+{
+ uint32 bytemask = _avail_aircraft; /// sets the first 3 bytes, 0 - 2, @see AdjustAvailAircraft()
+
+ if (_cur_year >= 1980) SETBIT(bytemask, 3); // metropolitan airport
+ if (_cur_year >= 1990) SETBIT(bytemask, 4); // international airport
+ if (_cur_year >= 1983) SETBIT(bytemask, 5); // commuter airport
+ if (_cur_year >= 1976) SETBIT(bytemask, 6); // helidepot
+ if (_cur_year >= 2002) SETBIT(bytemask, 7); // intercontinental airport
+ if (_cur_year >= 1980) SETBIT(bytemask, 8); // helistation
+ return bytemask;
+}
diff --git a/src/airport.h b/src/airport.h
new file mode 100644
index 000000000..2dcbd1660
--- /dev/null
+++ b/src/airport.h
@@ -0,0 +1,163 @@
+/* $Id$ */
+
+#ifndef AIRPORT_H
+#define AIRPORT_H
+
+enum {MAX_TERMINALS = 10};
+enum {MAX_HELIPADS = 4};
+enum {MAX_ELEMENTS = 255};
+enum {MAX_HEADINGS = 22};
+
+// Airport types
+enum {
+ AT_SMALL = 0,
+ AT_LARGE = 1,
+ AT_HELIPORT = 2,
+ AT_METROPOLITAN = 3,
+ AT_INTERNATIONAL = 4,
+ AT_COMMUTER = 5,
+ AT_HELIDEPOT = 6,
+ AT_INTERCON = 7,
+ AT_HELISTATION = 8,
+ AT_OILRIG = 15
+};
+
+// do not change unless you change v->subtype too. This aligns perfectly with its current setting
+enum {
+ AIRCRAFT_ONLY = 0,
+ ALL = 1,
+ HELICOPTERS_ONLY = 2,
+};
+
+enum {
+ AMED_NOSPDCLAMP = 1 << 0,
+ AMED_TAKEOFF = 1 << 1,
+ AMED_SLOWTURN = 1 << 2,
+ AMED_LAND = 1 << 3,
+ AMED_EXACTPOS = 1 << 4,
+ AMED_BRAKE = 1 << 5,
+ AMED_HELI_RAISE = 1 << 6,
+ AMED_HELI_LOWER = 1 << 7,
+};
+
+/* Movement States on Airports (headings target) */
+enum {
+ TO_ALL = 0,
+ HANGAR = 1,
+ TERM1 = 2,
+ TERM2 = 3,
+ TERM3 = 4,
+ TERM4 = 5,
+ TERM5 = 6,
+ TERM6 = 7,
+ HELIPAD1 = 8,
+ HELIPAD2 = 9,
+ TAKEOFF = 10,
+ STARTTAKEOFF = 11,
+ ENDTAKEOFF = 12,
+ HELITAKEOFF = 13,
+ FLYING = 14,
+ LANDING = 15,
+ ENDLANDING = 16,
+ HELILANDING = 17,
+ HELIENDLANDING = 18,
+ TERM7 = 19,
+ TERM8 = 20,
+ HELIPAD3 = 21,
+ HELIPAD4 = 22
+};
+
+// this maps the terminal to its corresponding state and block flag
+// currently set for 10 terms, 4 helipads
+static const byte _airport_terminal_state[] = {2, 3, 4, 5, 6, 7, 19, 20, 0, 0, 8, 9, 21, 22};
+static const byte _airport_terminal_flag[] = {0, 1, 2, 3, 4, 5, 22, 23, 0, 0, 6, 7, 24, 25};
+
+/* Movement Blocks on Airports */
+// blocks (eg_airport_flags)
+enum {
+ TERM1_block = 1 << 0,
+ TERM2_block = 1 << 1,
+ TERM3_block = 1 << 2,
+ TERM4_block = 1 << 3,
+ TERM5_block = 1 << 4,
+ TERM6_block = 1 << 5,
+ HELIPAD1_block = 1 << 6,
+ HELIPAD2_block = 1 << 7,
+ RUNWAY_IN_OUT_block = 1 << 8,
+ RUNWAY_IN_block = 1 << 8,
+ AIRPORT_BUSY_block = 1 << 8,
+ RUNWAY_OUT_block = 1 << 9,
+ TAXIWAY_BUSY_block = 1 << 10,
+ OUT_WAY_block = 1 << 11,
+ IN_WAY_block = 1 << 12,
+ AIRPORT_ENTRANCE_block = 1 << 13,
+ TERM_GROUP1_block = 1 << 14,
+ TERM_GROUP2_block = 1 << 15,
+ HANGAR2_AREA_block = 1 << 16,
+ TERM_GROUP2_ENTER1_block = 1 << 17,
+ TERM_GROUP2_ENTER2_block = 1 << 18,
+ TERM_GROUP2_EXIT1_block = 1 << 19,
+ TERM_GROUP2_EXIT2_block = 1 << 20,
+ PRE_HELIPAD_block = 1 << 21,
+
+// blocks for new airports
+ TERM7_block = 1 << 22,
+ TERM8_block = 1 << 23,
+ TERM9_block = 1 << 24,
+ HELIPAD3_block = 1 << 24,
+ TERM10_block = 1 << 25,
+ HELIPAD4_block = 1 << 25,
+ HANGAR1_AREA_block = 1 << 26,
+ OUT_WAY2_block = 1 << 27,
+ IN_WAY2_block = 1 << 28,
+ RUNWAY_IN2_block = 1 << 29,
+ RUNWAY_OUT2_block = 1 << 10, // note re-uses TAXIWAY_BUSY
+ HELIPAD_GROUP_block = 1 << 13, // note re-uses AIRPORT_ENTRANCE
+ OUT_WAY_block2 = 1 << 31,
+// end of new blocks
+
+ NOTHING_block = 1 << 30
+};
+
+typedef struct AirportMovingData {
+ int x,y;
+ byte flag;
+ byte direction;
+} AirportMovingData;
+
+// Finite sTate mAchine --> FTA
+typedef struct AirportFTAClass {
+ byte nofelements; // number of positions the airport consists of
+ const byte *terminals;
+ const byte *helipads;
+ byte entry_point; // when an airplane arrives at this airport, enter it at position entry_point
+ byte acc_planes; // accept airplanes or helicopters or both
+ const TileIndexDiffC *airport_depots; // gives the position of the depots on the airports
+ byte nof_depots; // number of depots this airport has
+ struct AirportFTA *layout; // state machine for airport
+ byte size_x;
+ byte size_y;
+} AirportFTAClass;
+
+// internal structure used in openttd - Finite sTate mAchine --> FTA
+typedef struct AirportFTA {
+ byte position; // the position that an airplane is at
+ byte next_position; // next position from this position
+ uint32 block; // 32 bit blocks (st->airport_flags), should be enough for the most complex airports
+ byte heading; // heading (current orders), guiding an airplane to its target on an airport
+ struct AirportFTA *next; // possible extra movement choices from this position
+} AirportFTA;
+
+void InitializeAirports(void);
+void UnInitializeAirports(void);
+const AirportFTAClass *GetAirport(const byte airport_type);
+const AirportMovingData *GetAirportMovingData(byte airport_type, byte position);
+
+/** Get buildable airport bitmask.
+ * @return get all buildable airports at this given time, bitmasked.
+ * Bit 0 means the small airport is buildable, etc.
+ * @todo set availability of airports by year, instead of airplane
+ */
+uint32 GetValidAirports(void);
+
+#endif /* AIRPORT_H */
diff --git a/src/airport_gui.c b/src/airport_gui.c
new file mode 100644
index 000000000..c049d50d5
--- /dev/null
+++ b/src/airport_gui.c
@@ -0,0 +1,286 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "table/sprites.h"
+#include "table/strings.h"
+#include "functions.h"
+#include "map.h"
+#include "window.h"
+#include "gui.h"
+#include "viewport.h"
+#include "gfx.h"
+#include "sound.h"
+#include "command.h"
+#include "vehicle.h"
+#include "station.h"
+#include "airport.h"
+#include "depot.h"
+
+static byte _selected_airport_type;
+
+static void ShowBuildAirportPicker(void);
+
+
+void CcBuildAirport(bool success, TileIndex tile, uint32 p1, uint32 p2)
+{
+ if (success) {
+ SndPlayTileFx(SND_1F_SPLAT, tile);
+ ResetObjectToPlace();
+ }
+}
+
+static void PlaceAirport(TileIndex tile)
+{
+ DoCommandP(tile, _selected_airport_type, 0, CcBuildAirport, CMD_BUILD_AIRPORT | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_A001_CAN_T_BUILD_AIRPORT_HERE));
+}
+
+static void PlaceAir_DemolishArea(TileIndex tile)
+{
+ VpStartPlaceSizing(tile, 4);
+}
+
+
+enum {
+ ATW_AIRPORT = 3,
+ ATW_DEMOLISH = 4
+};
+
+
+static void BuildAirClick_Airport(Window *w)
+{
+ if (HandlePlacePushButton(w, ATW_AIRPORT, SPR_CURSOR_AIRPORT, 1, PlaceAirport)) ShowBuildAirportPicker();
+}
+
+static void BuildAirClick_Demolish(Window *w)
+{
+ HandlePlacePushButton(w, ATW_DEMOLISH, ANIMCURSOR_DEMOLISH, 1, PlaceAir_DemolishArea);
+}
+
+static void BuildAirClick_Landscaping(Window *w)
+{
+ ShowTerraformToolbar();
+}
+
+typedef void OnButtonClick(Window *w);
+static OnButtonClick * const _build_air_button_proc[] = {
+ BuildAirClick_Airport,
+ BuildAirClick_Demolish,
+ BuildAirClick_Landscaping,
+};
+
+static void BuildAirToolbWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT:
+ DrawWindowWidgets(w);
+ break;
+
+ case WE_CLICK:
+ if (e->we.click.widget - 3 >= 0)
+ _build_air_button_proc[e->we.click.widget - 3](w);
+ break;
+
+ case WE_KEYPRESS: {
+ switch (e->we.keypress.keycode) {
+ case '1': BuildAirClick_Airport(w); break;
+ case '2': BuildAirClick_Demolish(w); break;
+ case 'l': BuildAirClick_Landscaping(w); break;
+ default: return;
+ }
+ } break;
+
+ case WE_PLACE_OBJ:
+ _place_proc(e->we.place.tile);
+ break;
+
+ case WE_PLACE_DRAG:
+ VpSelectTilesWithMethod(e->we.place.pt.x, e->we.place.pt.y, e->we.place.userdata);
+ break;
+
+ case WE_PLACE_MOUSEUP:
+ if (e->we.place.pt.x != -1) {
+ DoCommandP(e->we.place.tile, e->we.place.starttile, 0, CcPlaySound10, CMD_CLEAR_AREA | CMD_MSG(STR_00B5_CAN_T_CLEAR_THIS_AREA));
+ }
+ break;
+
+ case WE_ABORT_PLACE_OBJ:
+ RaiseWindowButtons(w);
+
+ w = FindWindowById(WC_BUILD_STATION, 0);
+ if (w != 0)
+ WP(w,def_d).close = true;
+ break;
+
+ case WE_DESTROY:
+ if (_patches.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0);
+ break;
+ }
+}
+
+static const Widget _air_toolbar_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW },
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 73, 0, 13, STR_A000_AIRPORTS, STR_018C_WINDOW_TITLE_DRAG_THIS },
+{ WWT_STICKYBOX, RESIZE_NONE, 7, 74, 85, 0, 13, 0x0, STR_STICKY_BUTTON },
+{ WWT_IMGBTN, RESIZE_NONE, 7, 0, 41, 14, 35, SPR_IMG_AIRPORT, STR_A01E_BUILD_AIRPORT },
+{ WWT_IMGBTN, RESIZE_NONE, 7, 42, 63, 14, 35, SPR_IMG_DYNAMITE, STR_018D_DEMOLISH_BUILDINGS_ETC },
+{ WWT_IMGBTN, RESIZE_NONE, 7, 64, 85, 14, 35, SPR_IMG_LANDSCAPING, STR_LANDSCAPING_TOOLBAR_TIP },
+{ WIDGETS_END},
+};
+
+
+static const WindowDesc _air_toolbar_desc = {
+ WDP_ALIGN_TBR, 22, 86, 36,
+ WC_BUILD_TOOLBAR, 0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON,
+ _air_toolbar_widgets,
+ BuildAirToolbWndProc
+};
+
+void ShowBuildAirToolbar(void)
+{
+ if (!IsValidPlayer(_current_player)) return;
+
+ DeleteWindowById(WC_BUILD_TOOLBAR, 0);
+ AllocateWindowDescFront(&_air_toolbar_desc, 0);
+ if (_patches.link_terraform_toolbar) ShowTerraformToolbar();
+}
+
+static void BuildAirportPickerWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_CREATE:
+ SetWindowWidgetLoweredState(w, 16, !_station_show_coverage);
+ SetWindowWidgetLoweredState(w, 17, _station_show_coverage);
+ LowerWindowWidget(w, _selected_airport_type + 7);
+ break;
+
+ case WE_PAINT: {
+ int i; // airport enabling loop
+ int rad = 4; // default catchment radious
+ uint32 avail_airports;
+ const AirportFTAClass *airport;
+
+ if (WP(w,def_d).close) return;
+
+ avail_airports = GetValidAirports();
+
+ RaiseWindowWidget(w, _selected_airport_type + 7);
+ if (!HASBIT(avail_airports, 0) && _selected_airport_type == AT_SMALL) _selected_airport_type = AT_LARGE;
+ if (!HASBIT(avail_airports, 1) && _selected_airport_type == AT_LARGE) _selected_airport_type = AT_SMALL;
+ LowerWindowWidget(w, _selected_airport_type + 7);
+
+ /* 'Country Airport' starts at widget 7, and if its bit is set, it is
+ * available, so take its opposite value to set the disabled state.
+ * There are 9 buildable airports
+ * XXX TODO : all airports should be held in arrays, with all relevant data.
+ * This should be part of newgrf-airports, i suppose
+ */
+ for (i = 0; i < 9; i++) SetWindowWidgetDisabledState(w, i + 7, !HASBIT(avail_airports, i));
+
+ // select default the coverage area to 'Off' (16)
+ airport = GetAirport(_selected_airport_type);
+ SetTileSelectSize(airport->size_x, airport->size_y);
+
+ if (_patches.modified_catchment) {
+ switch (_selected_airport_type) {
+ case AT_OILRIG: rad = CA_AIR_OILPAD; break;
+ case AT_HELIPORT: rad = CA_AIR_HELIPORT; break;
+ case AT_SMALL: rad = CA_AIR_SMALL; break;
+ case AT_LARGE: rad = CA_AIR_LARGE; break;
+ case AT_METROPOLITAN: rad = CA_AIR_METRO; break;
+ case AT_INTERNATIONAL: rad = CA_AIR_INTER; break;
+ case AT_COMMUTER: rad = CA_AIR_COMMUTER; break;
+ case AT_HELIDEPOT: rad = CA_AIR_HELIDEPOT; break;
+ case AT_INTERCON: rad = CA_AIR_INTERCON; break;
+ case AT_HELISTATION: rad = CA_AIR_HELISTATION; break;
+ }
+ }
+
+ if (_station_show_coverage) SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
+
+ DrawWindowWidgets(w);
+ // strings such as 'Size' and 'Coverage Area'
+ // 'Coverage Area'
+ DrawStationCoverageAreaText(2, 206, (uint)-1, rad);
+ break;
+ }
+
+ case WE_CLICK: {
+ switch (e->we.click.widget) {
+ case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
+ RaiseWindowWidget(w, _selected_airport_type + 7);
+ _selected_airport_type = e->we.click.widget - 7;
+ LowerWindowWidget(w, _selected_airport_type + 7);
+ SndPlayFx(SND_15_BEEP);
+ SetWindowDirty(w);
+ break;
+ case 16: case 17:
+ _station_show_coverage = e->we.click.widget - 16;
+ SetWindowWidgetLoweredState(w, 16, !_station_show_coverage);
+ SetWindowWidgetLoweredState(w, 17, _station_show_coverage);
+ SndPlayFx(SND_15_BEEP);
+ SetWindowDirty(w);
+ break;
+ }
+ } break;
+
+ case WE_MOUSELOOP: {
+ if (WP(w,def_d).close) {
+ DeleteWindow(w);
+ return;
+ }
+
+ CheckRedrawStationCoverage(w);
+ } break;
+
+ case WE_DESTROY:
+ if (!WP(w,def_d).close) ResetObjectToPlace();
+ break;
+ }
+}
+
+static const Widget _build_airport_picker_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 147, 0, 13, STR_3001_AIRPORT_SELECTION, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 147, 14, 52, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 147, 53, 89, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 147, 90, 127, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 147, 128, 177, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 147, 178, 239, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 145, 27, 38, STR_SMALL_AIRPORT, STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 145, 65, 76, STR_CITY_AIRPORT, STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 145, 141, 152, STR_HELIPORT, STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 145, 77, 88, STR_METRO_AIRPORT , STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 145, 103, 114, STR_INTERNATIONAL_AIRPORT, STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 145, 39, 50, STR_COMMUTER_AIRPORT, STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 145, 165, 176, STR_HELIDEPOT, STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 145, 115, 126, STR_INTERCONTINENTAL_AIRPORT, STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 145, 153, 164, STR_HELISTATION, STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 14, 73, 191, 202, STR_02DB_OFF, STR_3065_DON_T_HIGHLIGHT_COVERAGE},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 74, 133, 191, 202, STR_02DA_ON, STR_3064_HIGHLIGHT_COVERAGE_AREA},
+{ WWT_LABEL, RESIZE_NONE, 7, 0, 147, 14, 27, STR_SMALL_AIRPORTS, STR_NULL},
+{ WWT_LABEL, RESIZE_NONE, 7, 0, 147, 52, 65, STR_LARGE_AIRPORTS, STR_NULL},
+{ WWT_LABEL, RESIZE_NONE, 7, 0, 147, 90, 103, STR_HUB_AIRPORTS, STR_NULL},
+{ WWT_LABEL, RESIZE_NONE, 7, 0, 147, 128, 141, STR_HELIPORTS, STR_NULL},
+{ WWT_LABEL, RESIZE_NONE, 7, 0, 147, 178, 191, STR_3066_COVERAGE_AREA_HIGHLIGHT, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _build_airport_desc = {
+ WDP_AUTO, WDP_AUTO, 148, 240,
+ WC_BUILD_STATION, WC_BUILD_TOOLBAR,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _build_airport_picker_widgets,
+ BuildAirportPickerWndProc
+};
+
+static void ShowBuildAirportPicker(void)
+{
+ AllocateWindowDesc(&_build_airport_desc);
+}
+
+void InitializeAirportGui(void)
+{
+ _selected_airport_type = AT_SMALL;
+}
diff --git a/src/airport_movement.h b/src/airport_movement.h
new file mode 100644
index 000000000..1ca00ed75
--- /dev/null
+++ b/src/airport_movement.h
@@ -0,0 +1,794 @@
+/* $Id$ */
+
+#ifndef AIRPORT_MOVEMENT_H
+#define AIRPORT_MOVEMENT_H
+
+
+// state machine input struct (from external file, etc.)
+// Finite sTate mAchine --> FTA
+typedef struct AirportFTAbuildup {
+ byte position; // the position that an airplane is at
+ byte heading; // the current orders (eg. TAKEOFF, HANGAR, ENDLANDING, etc.)
+ uint32 block; // the block this position is on on the airport (st->airport_flags)
+ byte next; // next position from this position
+} AirportFTAbuildup;
+
+///////////////////////////////////////////////////////////////////////
+/////*********Movement Positions on Airports********************///////
+// Country Airfield (small) 4x3
+static const AirportMovingData _airport_moving_data_country[22] = {
+ { 53, 3, AMED_EXACTPOS, 3 }, // 00 In Hangar
+ { 53, 27, 0, 0 }, // 01 Taxi to right outside depot
+ { 32, 23, AMED_EXACTPOS, 7 }, // 02 Terminal 1
+ { 10, 23, AMED_EXACTPOS, 7 }, // 03 Terminal 2
+ { 43, 37, 0, 0 }, // 04 Going towards terminal 2
+ { 24, 37, 0, 0 }, // 05 Going towards terminal 2
+ { 53, 37, 0, 0 }, // 06 Going for takeoff
+ { 61, 40, AMED_EXACTPOS, 1 }, // 07 Taxi to start of runway (takeoff)
+ { 3, 40, AMED_NOSPDCLAMP, 0 }, // 08 Accelerate to end of runway
+ { -79, 40, AMED_NOSPDCLAMP | AMED_TAKEOFF, 0 }, // 09 Take off
+ { 177, 40, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 10 Fly to landing position in air
+ { 56, 40, AMED_NOSPDCLAMP | AMED_LAND, 0 }, // 11 Going down for land
+ { 3, 40, AMED_NOSPDCLAMP | AMED_BRAKE, 0 }, // 12 Just landed, brake until end of runway
+ { 7, 40, 0, 0 }, // 13 Just landed, turn around and taxi 1 square
+ { 53, 40, 0, 0 }, // 14 Taxi from runway to crossing
+ { -31, 193, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 15 Fly around waiting for a landing spot (north-east)
+ { 1, 1, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 16 Fly around waiting for a landing spot (north-west)
+ { 257, 1, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 17 Fly around waiting for a landing spot (south-west)
+ { 273, 49, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 18 Fly around waiting for a landing spot (south)
+ { 44, 37, AMED_HELI_RAISE, 0 }, // 19 Helicopter takeoff
+ { 44, 40, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 20 In position above landing spot helicopter
+ { 44, 40, AMED_HELI_LOWER, 0 }, // 21 Helicopter landing
+};
+
+// Commuter Airfield (small) 5x4
+static const AirportMovingData _airport_moving_data_commuter[37] = {
+ { 69, 3, AMED_EXACTPOS, 3 }, // 00 In Hangar
+ { 72, 22, 0, 0 }, // 01 Taxi to right outside depot
+ { 8, 22, AMED_EXACTPOS, 5 }, // 01 Taxi to right outside depot
+ { 24, 36, AMED_EXACTPOS, 3 }, // 03 Terminal 1
+ { 40, 36, AMED_EXACTPOS, 3 }, // 04 Terminal 2
+ { 56, 36, AMED_EXACTPOS, 3 }, // 05 Terminal 3
+ { 40, 8, AMED_EXACTPOS, 1 }, // 06 Helipad 1
+ { 56, 8, AMED_EXACTPOS, 1 }, // 07 Helipad 2
+ { 24, 22, 0, 5 }, // 08 Taxiing
+ { 40, 22, 0, 5 }, // 09 Taxiing
+ { 56, 22, 0, 5 }, // 10 Taxiing
+ { 72, 40, 0, 3 }, // 11 Airport OUTWAY
+ { 72, 54, AMED_EXACTPOS, 1 }, // 12 Accelerate to end of runway
+ { 7, 54, AMED_NOSPDCLAMP, 0 }, // 13 Release control of runway, for smoother movement
+ { 5, 54, AMED_NOSPDCLAMP, 0 }, // 14 End of runway
+ { -79, 54, AMED_NOSPDCLAMP | AMED_TAKEOFF, 0 }, // 15 Take off
+ { 145, 54, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 16 Fly to landing position in air
+ { 73, 54, AMED_NOSPDCLAMP | AMED_LAND, 0 }, // 17 Going down for land
+ { 3, 54, AMED_NOSPDCLAMP | AMED_BRAKE, 0 }, // 18 Just landed, brake until end of runway
+ { 12, 54, 0, 7 }, // 19 Just landed, turn around and taxi
+ { 8, 32, 0, 7 }, // 20 Taxi from runway to crossing
+ { -31, 149, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 21 Fly around waiting for a landing spot (north-east)
+ { 1, 6, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 22 Fly around waiting for a landing spot (north-west)
+ { 193, 6, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 23 Fly around waiting for a landing spot (south-west)
+ { 225, 81, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 24 Fly around waiting for a landing spot (south)
+ // Helicopter
+ { 80, 0, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 25 Bufferspace before helipad
+ { 80, 0, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 26 Bufferspace before helipad
+ { 32, 8, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 27 Get in position for Helipad1
+ { 48, 8, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 28 Get in position for Helipad2
+ { 32, 8, AMED_HELI_LOWER, 0 }, // 29 Land at Helipad1
+ { 48, 8, AMED_HELI_LOWER, 0 }, // 30 Land at Helipad2
+ { 32, 8, AMED_HELI_RAISE, 0 }, // 31 Takeoff Helipad1
+ { 48, 8, AMED_HELI_RAISE, 0 }, // 32 Takeoff Helipad2
+ { 64, 22, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 33 Go to position for Hangarentrance in air
+ { 64, 22, AMED_HELI_LOWER, 0 }, // 34 Land in front of hangar
+ { 40, 8, AMED_EXACTPOS, 0 }, // pre-helitakeoff helipad 1
+ { 56, 8, AMED_EXACTPOS, 0 }, // pre-helitakeoff helipad 2
+};
+
+// City Airport (large) 6x6
+static const AirportMovingData _airport_moving_data_town[25] = {
+ { 85, 3, AMED_EXACTPOS, 3 }, // 00 In Hangar
+ { 85, 27, 0, 0 }, // 01 Taxi to right outside depot
+ { 26, 41, AMED_EXACTPOS, 5 }, // 02 Terminal 1
+ { 56, 20, AMED_EXACTPOS, 3 }, // 03 Terminal 2
+ { 38, 8, AMED_EXACTPOS, 5 }, // 04 Terminal 3
+ { 65, 6, 0, 0 }, // 05 Taxi to right in infront of terminal 2/3
+ { 80, 27, 0, 0 }, // 06 Taxiway terminals 2-3
+ { 44, 63, 0, 0 }, // 07 Taxi to Airport center
+ { 58, 71, 0, 0 }, // 08 Towards takeoff
+ { 72, 85, 0, 0 }, // 09 Taxi to runway (takeoff)
+ { 89, 85, AMED_EXACTPOS, 1 }, // 10 Taxi to start of runway (takeoff)
+ { 3, 85, AMED_NOSPDCLAMP, 0 }, // 11 Accelerate to end of runway
+ { -79, 85, AMED_NOSPDCLAMP | AMED_TAKEOFF, 0 }, // 12 Take off
+ { 177, 85, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 13 Fly to landing position in air
+ { 89, 85, AMED_NOSPDCLAMP | AMED_LAND, 0 }, // 14 Going down for land
+ { 3, 85, AMED_NOSPDCLAMP | AMED_BRAKE, 0 }, // 15 Just landed, brake until end of runway
+ { 20, 87, 0, 0 }, // 16 Just landed, turn around and taxi 1 square
+ { 36, 71, 0, 0 }, // 17 Taxi from runway to crossing
+ { -31, 193, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 18 Fly around waiting for a landing spot (north-east)
+ { 1, 1, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 19 Fly around waiting for a landing spot (north-west)
+ { 257, 1, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 20 Fly around waiting for a landing spot (south-west)
+ { 273, 49, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 21 Fly around waiting for a landing spot (south)
+ { 44, 63, AMED_HELI_RAISE, 0 }, // 22 Helicopter takeoff
+ { 28, 74, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 23 In position above landing spot helicopter
+ { 28, 74, AMED_HELI_LOWER, 0 }, // 24 Helicopter landing
+};
+
+// Metropolitan Airport (metropolitan) - 2 runways
+static const AirportMovingData _airport_moving_data_metropolitan[27] = {
+ { 85, 3, AMED_EXACTPOS, 3 }, // 00 In Hangar
+ { 85, 27, 0, 0 }, // 01 Taxi to right outside depot
+ { 26, 41, AMED_EXACTPOS, 5 }, // 02 Terminal 1
+ { 56, 20, AMED_EXACTPOS, 3 }, // 03 Terminal 2
+ { 38, 8, AMED_EXACTPOS, 5 }, // 04 Terminal 3
+ { 65, 6, 0, 0 }, // 05 Taxi to right in infront of terminal 2/3
+ { 70, 33, 0, 0 }, // 06 Taxiway terminals 2-3
+ { 44, 58, 0, 0 }, // 07 Taxi to Airport center
+ { 72, 58, 0, 0 }, // 08 Towards takeoff
+ { 72, 69, 0, 0 }, // 09 Taxi to runway (takeoff)
+ { 89, 69, AMED_EXACTPOS, 1 }, // 10 Taxi to start of runway (takeoff)
+ { 3, 69, AMED_NOSPDCLAMP, 0 }, // 11 Accelerate to end of runway
+ { -79, 69, AMED_NOSPDCLAMP | AMED_TAKEOFF, 0 }, // 12 Take off
+ { 177, 85, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 13 Fly to landing position in air
+ { 89, 85, AMED_NOSPDCLAMP | AMED_LAND, 0 }, // 14 Going down for land
+ { 3, 85, AMED_NOSPDCLAMP | AMED_BRAKE, 0 }, // 15 Just landed, brake until end of runway
+ { 21, 85, 0, 0 }, // 16 Just landed, turn around and taxi 1 square
+ { 21, 69, 0, 0 }, // 17 On Runway-out taxiing to In-Way
+ { 21, 54, AMED_EXACTPOS, 5 }, // 18 Taxi from runway to crossing
+ { -31, 193, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 19 Fly around waiting for a landing spot (north-east)
+ { 1, 1, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 20 Fly around waiting for a landing spot (north-west)
+ { 257, 1, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 21 Fly around waiting for a landing spot (south-west)
+ { 273, 49, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 22 Fly around waiting for a landing spot (south)
+ { 44, 58, 0, 0 }, // 23 Helicopter takeoff spot on ground (to clear airport sooner)
+ { 44, 63, AMED_HELI_RAISE, 0 }, // 24 Helicopter takeoff
+ { 15, 54, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 25 Get in position above landing spot helicopter
+ { 15, 54, AMED_HELI_LOWER, 0 }, // 26 Helicopter landing
+};
+
+// International Airport (international) - 2 runways, 6 terminals, dedicated helipod
+static const AirportMovingData _airport_moving_data_international[51] = {
+ { 7, 55, AMED_EXACTPOS, 3 }, // 00 In Hangar 1
+ { 100, 21, AMED_EXACTPOS, 3 }, // 01 In Hangar 2
+ { 7, 70, 0, 0 }, // 02 Taxi to right outside depot
+ { 100, 36, 0, 0 }, // 03 Taxi to right outside depot
+ { 38, 70, AMED_EXACTPOS, 5 }, // 04 Terminal 1
+ { 38, 54, AMED_EXACTPOS, 5 }, // 05 Terminal 2
+ { 38, 38, AMED_EXACTPOS, 5 }, // 06 Terminal 3
+ { 70, 70, AMED_EXACTPOS, 1 }, // 07 Terminal 4
+ { 70, 54, AMED_EXACTPOS, 1 }, // 08 Terminal 5
+ { 70, 38, AMED_EXACTPOS, 1 }, // 09 Terminal 6
+ { 104, 71, AMED_EXACTPOS, 1 }, // 10 Helipad 1
+ { 104, 55, AMED_EXACTPOS, 1 }, // 11 Helipad 2
+ { 22, 87, 0, 0 }, // 12 Towards Terminals 4/5/6, Helipad 1/2
+ { 60, 87, 0, 0 }, // 13 Towards Terminals 4/5/6, Helipad 1/2
+ { 66, 87, 0, 0 }, // 14 Towards Terminals 4/5/6, Helipad 1/2
+ { 86, 87, AMED_EXACTPOS, 7 }, // 15 Towards Terminals 4/5/6, Helipad 1/2
+ { 86, 70, 0, 0 }, // 16 In Front of Terminal 4 / Helipad 1
+ { 86, 54, 0, 0 }, // 17 In Front of Terminal 5 / Helipad 2
+ { 86, 38, 0, 0 }, // 18 In Front of Terminal 6
+ { 86, 22, 0, 0 }, // 19 Towards Terminals Takeoff (Taxiway)
+ { 66, 22, 0, 0 }, // 20 Towards Terminals Takeoff (Taxiway)
+ { 60, 22, 0, 0 }, // 21 Towards Terminals Takeoff (Taxiway)
+ { 38, 22, 0, 0 }, // 22 Towards Terminals Takeoff (Taxiway)
+ { 22, 70, 0, 0 }, // 23 In Front of Terminal 1
+ { 22, 58, 0, 0 }, // 24 In Front of Terminal 2
+ { 22, 38, 0, 0 }, // 25 In Front of Terminal 3
+ { 22, 22, AMED_EXACTPOS, 7 }, // 26 Going for Takeoff
+ { 22, 6, 0, 0 }, // 27 On Runway-out, prepare for takeoff
+ { 3, 6, AMED_EXACTPOS, 5 }, // 28 Accelerate to end of runway
+ { 60, 6, AMED_NOSPDCLAMP, 0 }, // 29 Release control of runway, for smoother movement
+ { 105, 6, AMED_NOSPDCLAMP, 0 }, // 30 End of runway
+ { 190, 6, AMED_NOSPDCLAMP | AMED_TAKEOFF, 0 }, // 31 Take off
+ { 193, 104, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 32 Fly to landing position in air
+ { 105, 104, AMED_NOSPDCLAMP | AMED_LAND, 0 }, // 33 Going down for land
+ { 3, 104, AMED_NOSPDCLAMP | AMED_BRAKE, 0 }, // 34 Just landed, brake until end of runway
+ { 12, 104, 0, 0 }, // 35 Just landed, turn around and taxi 1 square
+ { 7, 84, 0, 0 }, // 36 Taxi from runway to crossing
+ { -31, 209, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 37 Fly around waiting for a landing spot (north-east)
+ { 1, 6, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 38 Fly around waiting for a landing spot (north-west)
+ { 273, 6, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 39 Fly around waiting for a landing spot (south-west)
+ { 305, 81, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 40 Fly around waiting for a landing spot (south)
+ // Helicopter
+ { 128, 80, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 41 Bufferspace before helipad
+ { 128, 80, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 42 Bufferspace before helipad
+ { 96, 71, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 43 Get in position for Helipad1
+ { 96, 55, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 44 Get in position for Helipad2
+ { 96, 71, AMED_HELI_LOWER, 0 }, // 45 Land at Helipad1
+ { 96, 55, AMED_HELI_LOWER, 0 }, // 46 Land at Helipad2
+ { 104, 71, AMED_HELI_RAISE, 0 }, // 47 Takeoff Helipad1
+ { 104, 55, AMED_HELI_RAISE, 0 }, // 48 Takeoff Helipad2
+ { 104, 32, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 49 Go to position for Hangarentrance in air
+ { 104, 32, AMED_HELI_LOWER, 0} // 50 Land in HANGAR2_AREA to go to hangar
+};
+
+// Intercontinental Airport - 4 runways, 8 terminals, 2 dedicated helipads
+static const AirportMovingData _airport_moving_data_intercontinental[77] = {
+ { 7, 87, AMED_EXACTPOS, 3 }, // 00 In Hangar 1
+ { 135, 72, AMED_EXACTPOS, 3 }, // 01 In Hangar 2
+ { 7, 104, 0, 0 }, // 02 Taxi to right outside depot 1
+ { 135, 88, 0, 0 }, // 03 Taxi to right outside depot 2
+ { 56, 120, AMED_EXACTPOS, 6 }, // 04 Terminal 1
+ { 56, 104, AMED_EXACTPOS, 5 }, // 05 Terminal 2
+ { 56, 88, AMED_EXACTPOS, 5 }, // 06 Terminal 3
+ { 56, 72, AMED_EXACTPOS, 5 }, // 07 Terminal 4
+ { 88, 120, AMED_EXACTPOS, 0 }, // 08 Terminal 5
+ { 88, 104, AMED_EXACTPOS, 1 }, // 09 Terminal 6
+ { 88, 88, AMED_EXACTPOS, 1 }, // 10 Terminal 7
+ { 88, 72, AMED_EXACTPOS, 1 }, // 11 Terminal 8
+ { 88, 56, AMED_EXACTPOS, 3 }, // 12 Helipad 1
+ { 72, 56, AMED_EXACTPOS, 1 }, // 13 Helipad 2
+ { 40, 136, 0, 0 }, // 14 Term group 2 enter 1 a
+ { 56, 136, 0, 0 }, // 15 Term group 2 enter 1 b
+ { 88, 136, 0, 0 }, // 16 Term group 2 enter 2 a
+ { 104, 136, 0, 0 }, // 17 Term group 2 enter 2 b
+ { 104, 120, 0, 0 }, // 18 Term group 2 - opp term 5
+ { 104, 104, 0, 0 }, // 19 Term group 2 - opp term 6 & exit2
+ { 104, 88, 0, 0 }, // 20 Term group 2 - opp term 7 & hangar area 2
+ { 104, 72, 0, 0 }, // 21 Term group 2 - opp term 8
+ { 104, 56, 0, 0 }, // 22 Taxi Term group 2 exit a
+ { 104, 40, 0, 0 }, // 23 Taxi Term group 2 exit b
+ { 56, 40, 0, 0 }, // 24 Term group 2 exit 2a
+ { 40, 40, 0, 0 }, // 25 Term group 2 exit 2b
+ { 40, 120, 0, 0 }, // 26 Term group 1 - opp term 1
+ { 40, 104, 0, 0 }, // 27 Term group 1 - opp term 2 & hangar area 1
+ { 40, 88, 0, 0 }, // 28 Term group 1 - opp term 3
+ { 40, 72, 0, 0 }, // 29 Term group 1 - opp term 4
+ { 18, 72, 0, 7 }, // 30 Outway 1
+ { 8, 40, 0, 7 }, // 31 Airport OUTWAY
+ { 8, 24, AMED_EXACTPOS, 5 }, // 32 Accelerate to end of runway
+ { 119, 24, AMED_NOSPDCLAMP, 0 }, // 33 Release control of runway, for smoother movement
+ { 117, 24, AMED_NOSPDCLAMP, 0 }, // 34 End of runway
+ { 197, 24, AMED_NOSPDCLAMP | AMED_TAKEOFF, 0 }, // 35 Take off
+ { 254, 84, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 36 Flying to landing position in air
+ { 117, 168, AMED_NOSPDCLAMP | AMED_LAND, 0 }, // 37 Going down for land
+ { 3, 168, AMED_NOSPDCLAMP | AMED_BRAKE, 0 }, // 38 Just landed, brake until end of runway
+ { 8, 168, 0, 0 }, // 39 Just landed, turn around and taxi
+ { 8, 144, 0, 7 }, // 40 Taxi from runway
+ { 8, 128, 0, 7 }, // 41 Taxi from runway
+ { 8, 120, AMED_EXACTPOS, 5 }, // 42 Airport entrance
+ { 56, 344, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 43 Fly around waiting for a landing spot (north-east)
+ { -200, 88, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 44 Fly around waiting for a landing spot (north-west)
+ { 56, -168, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 45 Fly around waiting for a landing spot (south-west)
+ { 312, 88, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 46 Fly around waiting for a landing spot (south)
+ // Helicopter
+ { 96, 40, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 47 Bufferspace before helipad
+ { 96, 40, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 48 Bufferspace before helipad
+ { 82, 54, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 49 Get in position for Helipad1
+ { 64, 56, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 50 Get in position for Helipad2
+ { 81, 55, AMED_HELI_LOWER, 0 }, // 51 Land at Helipad1
+ { 64, 56, AMED_HELI_LOWER, 0 }, // 52 Land at Helipad2
+ { 80, 56, AMED_HELI_RAISE, 0 }, // 53 Takeoff Helipad1
+ { 64, 56, AMED_HELI_RAISE, 0 }, // 54 Takeoff Helipad2
+ { 136, 96, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 55 Go to position for Hangarentrance in air
+ { 136, 96, AMED_HELI_LOWER, 0 }, // 56 Land in front of hangar2
+ { 126, 104, 0, 3 }, // 57 Outway 2
+ { 136, 136, 0, 1 }, // 58 Airport OUTWAY 2
+ { 136, 152, AMED_EXACTPOS, 5 }, // 59 Accelerate to end of runway2
+ { 16, 152, AMED_NOSPDCLAMP, 0 }, // 60 Release control of runway2, for smoother movement
+ { 20, 152, AMED_NOSPDCLAMP, 0 }, // 61 End of runway2
+ { -56, 152, AMED_NOSPDCLAMP | AMED_TAKEOFF, 0 }, // 62 Take off2
+ { 24, 8, AMED_NOSPDCLAMP | AMED_LAND, 0 }, // 63 Going down for land2
+ { 136, 8, AMED_NOSPDCLAMP | AMED_BRAKE, 0 }, // 64 Just landed, brake until end of runway2in
+ { 136, 8, 0, 0 }, // 65 Just landed, turn around and taxi
+ { 136, 24, 0, 3 }, // 66 Taxi from runway 2in
+ { 136, 40, 0, 3 }, // 67 Taxi from runway 2in
+ { 136, 56, AMED_EXACTPOS, 1 }, // 68 Airport entrance2
+ { -56, 8, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 69 Fly to landing position in air2
+ { 88, 40, 0, 0 }, // 70 Taxi Term group 2 exit - opp heli1
+ { 72, 40, 0, 0 }, // 71 Taxi Term group 2 exit - opp heli2
+ { 88, 57, AMED_EXACTPOS, 3 }, // 72 pre-helitakeoff helipad 1
+ { 71, 56, AMED_EXACTPOS, 1 }, // 73 pre-helitakeoff helipad 2
+ { 8, 120, AMED_HELI_RAISE, 0 }, // 74 Helitakeoff outside depot 1
+ { 136, 104, AMED_HELI_RAISE, 0 }, // 75 Helitakeoff outside depot 2
+ { 197, 168, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0} // 76 Fly to landing position in air1
+};
+
+
+// Heliport (heliport)
+static const AirportMovingData _airport_moving_data_heliport[9] = {
+ { 5, 9, AMED_EXACTPOS, 1 }, // 0 - At heliport terminal
+ { 2, 9, AMED_HELI_RAISE, 0 }, // 1 - Take off (play sound)
+ { -3, 9, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 2 - In position above landing spot helicopter
+ { -3, 9, AMED_HELI_LOWER, 0 }, // 3 - Land
+ { 2, 9, 0, 0 }, // 4 - Goto terminal on ground
+ { -31, 59, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 5 - Circle #1 (north-east)
+ { -31, -49, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 6 - Circle #2 (north-west)
+ { 49, -49, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 7 - Circle #3 (south-west)
+ { 70, 9, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 8 - Circle #4 (south)
+};
+
+// HeliDepot 2x2 (heliport)
+static const AirportMovingData _airport_moving_data_helidepot[18] = {
+ { 24, 4, AMED_EXACTPOS, 1 }, // 0 - At depot
+ { 24, 28, 0, 0 }, // 1 Taxi to right outside depot
+ { 5, 38, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 2 Flying
+ { -15, -15, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 3 - Circle #1 (north-east)
+ { -15, -49, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 4 - Circle #2 (north-west)
+ { 49, -49, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 5 - Circle #3 (south-west)
+ { 49, -15, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 6 - Circle #4 (south-east)
+ { 8, 32, AMED_NOSPDCLAMP | AMED_SLOWTURN, 7 }, // 7 - PreHelipad
+ { 8, 32, AMED_NOSPDCLAMP | AMED_SLOWTURN, 7 }, // 8 - Helipad
+ { 8, 16, AMED_NOSPDCLAMP | AMED_SLOWTURN, 7 }, // 9 - Land
+ { 8, 16, AMED_HELI_LOWER, 7 }, // 10 - Land
+ { 8, 24, AMED_HELI_RAISE, 0 }, // 11 - Take off (play sound)
+ { 32, 24, AMED_NOSPDCLAMP | AMED_SLOWTURN, 7 }, // 12 Air to above hangar area
+ { 32, 24, AMED_HELI_LOWER, 7 }, // 13 Taxi to right outside depot
+ { 8, 24, AMED_EXACTPOS, 7 }, // 14 - on helipad1
+ { 24, 28, AMED_HELI_RAISE, 0 }, // 15 Takeoff right outside depot
+ { 8, 24, AMED_HELI_RAISE, 5 }, // 16 - Take off (play sound)
+ { 8, 24, AMED_SLOWTURN | AMED_EXACTPOS, 2 }, // 17 - turn on helipad1 for takeoff
+};
+
+// HeliDepot 2x2 (heliport)
+static const AirportMovingData _airport_moving_data_helistation[33] = {
+ { 8, 3, AMED_EXACTPOS, 3 }, // 00 In Hangar2
+ { 8, 22, 0, 0 }, // 01 outside hangar 2
+ { 116, 24, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 02 Fly to landing position in air
+ { 14, 22, AMED_HELI_RAISE, 0 }, // 03 Helitakeoff outside hangar1(play sound)
+ { 24, 22, 0, 0 }, // 04 taxiing
+ { 40, 22, 0, 0 }, // 05 taxiing
+ { 40, 8, AMED_EXACTPOS, 1 }, // 06 Helipad 1
+ { 56, 8, AMED_EXACTPOS, 1 }, // 07 Helipad 2
+ { 56, 24, AMED_EXACTPOS, 1 }, // 08 Helipad 3
+ { 40, 8, AMED_EXACTPOS, 0 }, // 09 pre-helitakeoff helipad 1
+ { 56, 8, AMED_EXACTPOS, 0 }, // 10 pre-helitakeoff helipad 2
+ { 56, 24, AMED_EXACTPOS, 0 }, // 11 pre-helitakeoff helipad 3
+ { 32, 8, AMED_HELI_RAISE, 0 }, // 12 Takeoff Helipad1
+ { 48, 8, AMED_HELI_RAISE, 0 }, // 13 Takeoff Helipad2
+ { 48, 24, AMED_HELI_RAISE, 0 }, // 14 Takeoff Helipad3
+ { 84, 24, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 15 Bufferspace before helipad
+ { 68, 24, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 16 Bufferspace before helipad
+ { 32, 8, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 17 Get in position for Helipad1
+ { 48, 8, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 18 Get in position for Helipad2
+ { 48, 24, AMED_NOSPDCLAMP | AMED_SLOWTURN, 1 }, // 19 Get in position for Helipad3
+ { 40, 8, AMED_HELI_LOWER, 0 }, // 20 Land at Helipad1
+ { 48, 8, AMED_HELI_LOWER, 0 }, // 21 Land at Helipad2
+ { 48, 24, AMED_HELI_LOWER, 0 }, // 22 Land at Helipad3
+ { 0, 22, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 23 Go to position for Hangarentrance in air
+ { 0, 22, AMED_HELI_LOWER, 0 }, // 24 Land in front of hangar
+ { 148, -8, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 25 Fly around waiting for a landing spot (south-east)
+ { 148, 8, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 26 Fly around waiting for a landing spot (south-west)
+ { 132, 24, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 27 Fly around waiting for a landing spot (south-west)
+ { 100, 24, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 28 Fly around waiting for a landing spot (north-east)
+ { 84, 8, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 29 Fly around waiting for a landing spot (south-east)
+ { 84, -8, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 30 Fly around waiting for a landing spot (south-west)
+ { 100, -24, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 31 Fly around waiting for a landing spot (north-west)
+ { 132, -24, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 32 Fly around waiting for a landing spot (north-east)
+};
+
+// Oilrig
+static const AirportMovingData _airport_moving_data_oilrig[9] = {
+ { 31, 9, AMED_EXACTPOS, 1 }, // 0 - At oilrig terminal
+ { 28, 9, AMED_HELI_RAISE, 0 }, // 1 - Take off (play sound)
+ { 23, 9, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 2 - In position above landing spot helicopter
+ { 23, 9, AMED_HELI_LOWER, 0 }, // 3 - Land
+ { 28, 9, 0, 0 }, // 4 - Goto terminal on ground
+ { -31, 69, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 5 - circle #1 (north-east)
+ { -31, -49, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 6 - circle #2 (north-west)
+ { 69, -49, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 7 - circle #3 (south-west)
+ { 70, 9, AMED_NOSPDCLAMP | AMED_SLOWTURN, 0 }, // 8 - circle #4 (south)
+};
+
+///////////////////////////////////////////////////////////////////////
+/////**********Movement Machine on Airports*********************///////
+/* First element of terminals array tells us how many depots there are (to know size of array)
+ * this may be changed later when airports are moved to external file */
+static const TileIndexDiffC _airport_depots_country[] = {{3, 0}};
+static const byte _airport_terminal_country[] = {1, 2};
+static const AirportFTAbuildup _airport_fta_country[] = {
+ { 0, HANGAR, NOTHING_block, 1 },
+ { 1, 255, AIRPORT_BUSY_block, 0 }, { 1, HANGAR, 0, 0 }, { 1, TERM1, TERM1_block, 2 }, { 1, TERM2, 0, 4 }, { 1, HELITAKEOFF, 0, 19 }, { 1, 0, 0, 6 },
+ { 2, TERM1, TERM1_block, 1 },
+ { 3, TERM2, TERM2_block, 5 },
+ { 4, 255, AIRPORT_BUSY_block, 0 }, { 4, TERM2, 0, 5 }, { 4, HANGAR, 0, 1 }, { 4, TAKEOFF, 0, 6 }, { 4, HELITAKEOFF, 0, 1 },
+ { 5, 255, AIRPORT_BUSY_block, 0 }, { 5, TERM2, TERM2_block, 3 }, { 5, 0, 0, 4 },
+ { 6, 0, AIRPORT_BUSY_block, 7 },
+ // takeoff
+ { 7, TAKEOFF, AIRPORT_BUSY_block, 8 },
+ { 8, STARTTAKEOFF, NOTHING_block, 9 },
+ { 9, ENDTAKEOFF, NOTHING_block, 0 },
+ // landing
+ { 10, FLYING, NOTHING_block, 15 }, { 10, LANDING, 0, 11 }, { 10, HELILANDING, 0, 20 },
+ { 11, LANDING, AIRPORT_BUSY_block, 12 },
+ { 12, 0, AIRPORT_BUSY_block, 13 },
+ { 13, ENDLANDING, AIRPORT_BUSY_block, 14 }, { 13, TERM2, 0, 5 }, { 13, 0, 0, 14 },
+ { 14, 0, AIRPORT_BUSY_block, 1 },
+ // In air
+ { 15, 0, NOTHING_block, 16 },
+ { 16, 0, NOTHING_block, 17 },
+ { 17, 0, NOTHING_block, 18 },
+ { 18, 0, NOTHING_block, 10 },
+ { 19, HELITAKEOFF, NOTHING_block, 0 },
+ { 20, HELILANDING, AIRPORT_BUSY_block, 21 },
+ { 21, HELIENDLANDING, AIRPORT_BUSY_block, 1 },
+ { MAX_ELEMENTS, 0, 0, 0 } // end marker. DO NOT REMOVE
+};
+
+static const TileIndexDiffC _airport_depots_commuter[] = { { 4, 0 } };
+static const byte _airport_terminal_commuter[] = { 1, 3 };
+static const byte _airport_helipad_commuter[] = { 1, 2 };
+static const AirportFTAbuildup _airport_fta_commuter[] = {
+ { 0, HANGAR, NOTHING_block, 1 }, { 0, HELITAKEOFF, HELIPAD2_block, 1 }, { 0, 0, 0, 1 },
+ { 1, 255, TAXIWAY_BUSY_block, 0 }, { 1, HANGAR, 0, 0 }, { 1, TAKEOFF, 0, 11 }, { 1, TERM1, TAXIWAY_BUSY_block, 10 }, { 1, TERM2, TAXIWAY_BUSY_block, 10 }, { 1, TERM3, TAXIWAY_BUSY_block, 10 }, { 1, HELIPAD1, TAXIWAY_BUSY_block, 10 }, { 1, HELIPAD2, TAXIWAY_BUSY_block, 10 }, { 1, HELITAKEOFF, TAXIWAY_BUSY_block, 10 }, { 1, 0, 0, 0 },
+ { 2, 255, AIRPORT_ENTRANCE_block, 2 }, { 2, HANGAR, 0, 8 }, { 2, TERM1, 0, 8 }, { 2, TERM2, 0, 8 }, { 2, TERM3, 0, 8 }, { 2, HELIPAD1, 0, 8 }, { 2, HELIPAD2, 0, 8 }, { 2, HELITAKEOFF, 0, 8 }, { 2, 0, 0, 2 },
+ { 3, TERM1, TERM1_block, 8 }, { 3, HANGAR, 0, 8 }, { 3, TAKEOFF, 0, 8 }, { 3, 0, 0, 3 },
+ { 4, TERM2, TERM2_block, 9 }, { 4, HANGAR, 0, 9 }, { 4, TAKEOFF, 0, 9 }, { 4, 0, 0, 4 },
+ { 5, TERM3, TERM3_block, 10 }, { 5, HANGAR, 0, 10 }, { 5, TAKEOFF, 0, 10 }, { 5, 0, 0, 5 },
+ { 6, HELIPAD1, HELIPAD1_block, 6 }, { 6, HANGAR, TAXIWAY_BUSY_block, 9 }, { 6, HELITAKEOFF, 0, 35 },
+ { 7, HELIPAD2, HELIPAD2_block, 7 }, { 7, HANGAR, TAXIWAY_BUSY_block, 10 }, { 7, HELITAKEOFF, 0, 36 },
+ { 8, 255, TAXIWAY_BUSY_block, 8 }, { 8, TAKEOFF, TAXIWAY_BUSY_block, 9 }, { 8, HANGAR, TAXIWAY_BUSY_block, 9 }, { 8, TERM1, TERM1_block, 3 }, { 8, 0, TAXIWAY_BUSY_block, 9 },
+ { 9, 255, TAXIWAY_BUSY_block, 9 }, { 9, TAKEOFF, TAXIWAY_BUSY_block, 10 }, { 9, HANGAR, TAXIWAY_BUSY_block, 10 }, { 9, TERM2, TERM2_block, 4 }, { 9, HELIPAD1, HELIPAD1_block, 6 }, { 9, HELITAKEOFF, HELIPAD1_block, 6 }, { 9, TERM1, TAXIWAY_BUSY_block, 8 }, { 9, 0, TAXIWAY_BUSY_block, 10 },
+ { 10, 255, TAXIWAY_BUSY_block, 10 }, { 10, TERM3, TERM3_block, 5 }, { 10, HELIPAD1, 0, 9 }, { 10, HELIPAD2, HELIPAD2_block, 7 }, { 10, HELITAKEOFF, HELIPAD2_block, 7 }, { 10, TAKEOFF, TAXIWAY_BUSY_block, 1 }, { 10, HANGAR, TAXIWAY_BUSY_block, 1 }, { 10, 0, TAXIWAY_BUSY_block, 9 },
+ { 11, 0, OUT_WAY_block, 12 },
+ // takeoff
+ { 12, TAKEOFF, RUNWAY_IN_OUT_block, 13 },
+ { 13, 0, RUNWAY_IN_OUT_block, 14 },
+ { 14, STARTTAKEOFF, RUNWAY_IN_OUT_block, 15 },
+ { 15, ENDTAKEOFF, NOTHING_block, 0 },
+ // landing
+ { 16, FLYING, NOTHING_block, 21 }, { 16, LANDING, IN_WAY_block, 17 }, { 16, HELILANDING, 0, 25 },
+ { 17, LANDING, RUNWAY_IN_OUT_block, 18 },
+ { 18, 0, RUNWAY_IN_OUT_block, 19 },
+ { 19, 0, RUNWAY_IN_OUT_block, 20 },
+ { 20, ENDLANDING, IN_WAY_block, 2 },
+ // In Air
+ { 21, 0, NOTHING_block, 22 },
+ { 22, 0, NOTHING_block, 23 },
+ { 23, 0, NOTHING_block, 24 },
+ { 24, 0, NOTHING_block, 16 },
+ // Helicopter -- stay in air in special place as a buffer to choose from helipads
+ { 25, HELILANDING, PRE_HELIPAD_block, 26 },
+ { 26, HELIENDLANDING, PRE_HELIPAD_block, 26 }, { 26, HELIPAD1, 0, 27 }, { 26, HELIPAD2, 0, 28 }, { 26, HANGAR, 0, 33 },
+ { 27, 0, NOTHING_block, 29 }, //helipad1 approach
+ { 28, 0, NOTHING_block, 30 },
+ // landing
+ { 29, 255, NOTHING_block, 0 }, { 29, HELIPAD1, HELIPAD1_block, 6 },
+ { 30, 255, NOTHING_block, 0 }, { 30, HELIPAD2, HELIPAD2_block, 7 },
+ // Helicopter -- takeoff
+ { 31, HELITAKEOFF, NOTHING_block, 0 },
+ { 32, HELITAKEOFF, NOTHING_block, 0 },
+ { 33, 0, TAXIWAY_BUSY_block, 34 }, // need to go to hangar when waiting in air
+ { 34, 0, TAXIWAY_BUSY_block, 1 },
+ { 35, 0, HELIPAD1_block, 31 },
+ { 36, 0, HELIPAD2_block, 32 },
+ { MAX_ELEMENTS, 0, 0, 0 } // end marker. DO NOT REMOVE
+};
+
+static const TileIndexDiffC _airport_depots_city[] = { { 5, 0 } };
+static const byte _airport_terminal_city[] = { 1, 3 };
+static const AirportFTAbuildup _airport_fta_city[] = {
+ { 0, HANGAR, NOTHING_block, 1 }, { 0, TAKEOFF, OUT_WAY_block, 1 }, { 0, 0, 0, 1 },
+ { 1, 255, TAXIWAY_BUSY_block, 0 }, { 1, HANGAR, 0, 0 }, { 1, TERM2, 0, 6 }, { 1, TERM3, 0, 6 }, { 1, 0, 0, 7 }, // for all else, go to 7
+ { 2, TERM1, TERM1_block, 7 }, { 2, TAKEOFF, OUT_WAY_block, 7 }, { 2, 0, 0, 7 },
+ { 3, TERM2, TERM2_block, 5 }, { 3, TAKEOFF, OUT_WAY_block, 5 }, { 3, 0, 0, 5 },
+ { 4, TERM3, TERM3_block, 5 }, { 4, TAKEOFF, OUT_WAY_block, 5 }, { 4, 0, 0, 5 },
+ { 5, 255, TAXIWAY_BUSY_block, 0 }, { 5, TERM2, TERM2_block, 3 }, { 5, TERM3, TERM3_block, 4 }, { 5, 0, 0, 6 },
+ { 6, 255, TAXIWAY_BUSY_block, 0 }, { 6, TERM2, 0, 5 }, { 6, TERM3, 0, 5 }, { 6, HANGAR, 0, 1 }, { 6, 0, 0, 7 },
+ { 7, 255, TAXIWAY_BUSY_block, 0 }, { 7, TERM1, TERM1_block, 2 }, { 7, TAKEOFF, OUT_WAY_block, 8 }, { 7, HELITAKEOFF, 0, 22 }, { 7, HANGAR, 0, 1 }, { 7, 0, 0, 6 },
+ { 8, 0, OUT_WAY_block, 9 },
+ { 9, 0, RUNWAY_IN_OUT_block, 10 },
+ // takeoff
+ { 10, TAKEOFF, RUNWAY_IN_OUT_block, 11 },
+ { 11, STARTTAKEOFF, NOTHING_block, 12 },
+ { 12, ENDTAKEOFF, NOTHING_block, 0 },
+ // landing
+ { 13, FLYING, NOTHING_block, 18 }, { 13, LANDING, 0, 14 }, { 13, HELILANDING, 0, 23 },
+ { 14, LANDING, RUNWAY_IN_OUT_block, 15 },
+ { 15, 0, RUNWAY_IN_OUT_block, 16 },
+ { 16, 0, RUNWAY_IN_OUT_block, 17 },
+ { 17, ENDLANDING, IN_WAY_block, 7 },
+ // In Air
+ { 18, 0, NOTHING_block, 19 },
+ { 19, 0, NOTHING_block, 20 },
+ { 20, 0, NOTHING_block, 21 },
+ { 21, 0, NOTHING_block, 13 },
+ // helicopter
+ { 22, HELITAKEOFF, NOTHING_block, 0 },
+ { 23, HELILANDING, IN_WAY_block, 24 },
+ { 24, HELIENDLANDING, IN_WAY_block, 17 },
+ { MAX_ELEMENTS, 0, 0, 0 } // end marker. DO NOT REMOVE
+};
+
+static const TileIndexDiffC _airport_depots_metropolitan[] = { { 5, 0 } };
+static const byte _airport_terminal_metropolitan[] = { 1, 3 };
+static const AirportFTAbuildup _airport_fta_metropolitan[] = {
+ { 0, HANGAR, NOTHING_block, 1 },
+ { 1, 255, TAXIWAY_BUSY_block, 0 }, { 1, HANGAR, 0, 0 }, { 1, TERM2, 0, 6 }, { 1, TERM3, 0, 6 }, { 1, 0, 0, 7 }, // for all else, go to 7
+ { 2, TERM1, TERM1_block, 7 },
+ { 3, TERM2, TERM2_block, 5 },
+ { 4, TERM3, TERM3_block, 5 },
+ { 5, 255, TAXIWAY_BUSY_block, 0 }, { 5, TERM2, TERM2_block, 3 }, { 5, TERM3, TERM3_block, 4 }, { 5, 0, 0, 6 },
+ { 6, 255, TAXIWAY_BUSY_block, 0 }, { 6, TERM2, 0, 5 }, { 6, TERM3, 0, 5 }, { 6, HANGAR, 0, 1 }, { 6, 0, 0, 7 },
+ { 7, 255, TAXIWAY_BUSY_block, 0 }, { 7, TERM1, TERM1_block, 2 }, { 7, TAKEOFF, 0, 8 }, { 7, HELITAKEOFF, 0, 23 }, { 7, HANGAR, 0, 1 }, { 7, 0, 0, 6 },
+ { 8, 0, OUT_WAY_block, 9 },
+ { 9, 0, RUNWAY_OUT_block, 10 },
+ // takeoff
+ { 10, TAKEOFF, RUNWAY_OUT_block, 11 },
+ { 11, STARTTAKEOFF, NOTHING_block, 12 },
+ { 12, ENDTAKEOFF, NOTHING_block, 0 },
+ // landing
+ { 13, FLYING, NOTHING_block, 19 }, { 13, LANDING, 0, 14 }, { 13, HELILANDING, 0, 25 },
+ { 14, LANDING, RUNWAY_IN_block, 15 },
+ { 15, 0, RUNWAY_IN_block, 16 },
+ { 16, 255, RUNWAY_IN_block, 0 }, { 16, ENDLANDING, IN_WAY_block, 17 },
+ { 17, 255, RUNWAY_OUT_block, 0 }, { 17, ENDLANDING, IN_WAY_block, 18 },
+ { 18, ENDLANDING, IN_WAY_block, 7 },
+ // In Air
+ { 19, 0, NOTHING_block, 20 },
+ { 20, 0, NOTHING_block, 21 },
+ { 21, 0, NOTHING_block, 22 },
+ { 22, 0, NOTHING_block, 13 },
+ // helicopter
+ { 23, 0, NOTHING_block, 24 },
+ { 24, HELITAKEOFF, NOTHING_block, 0 },
+ { 25, HELILANDING, IN_WAY_block, 26 },
+ { 26, HELIENDLANDING, IN_WAY_block, 18 },
+ { MAX_ELEMENTS, 0, 0, 0 } // end marker. DO NOT REMOVE
+};
+
+static const TileIndexDiffC _airport_depots_international[] = { { 0, 3 }, { 6, 1 } };
+static const byte _airport_terminal_international[] = { 2, 3, 3 };
+static const byte _airport_helipad_international[] = { 1, 2 };
+static const AirportFTAbuildup _airport_fta_international[] = {
+ { 0, HANGAR, NOTHING_block, 2 }, { 0, 255, TERM_GROUP1_block, 0 }, { 0, 255, TERM_GROUP2_ENTER1_block, 1 }, { 0, HELITAKEOFF, HELIPAD1_block, 2 }, { 0, 0, 0, 2 },
+ { 1, HANGAR, NOTHING_block, 3 }, { 1, 255, HANGAR2_AREA_block, 1 }, { 1, HELITAKEOFF, HELIPAD2_block, 3 }, { 1, 0, 0, 3 },
+ { 2, 255, AIRPORT_ENTRANCE_block, 0 }, { 2, HANGAR, 0, 0 }, { 2, TERM4, 0, 12 }, { 2, TERM5, 0, 12 }, { 2, TERM6, 0, 12 }, { 2, HELIPAD1, 0, 12 }, { 2, HELIPAD2, 0, 12 }, { 2, HELITAKEOFF, 0, 12 }, { 2, 0, 0, 23 },
+ { 3, 255, HANGAR2_AREA_block, 0 }, { 3, HANGAR, 0, 1 }, { 3, 0, 0, 18 },
+ { 4, TERM1, TERM1_block, 23 }, { 4, HANGAR, AIRPORT_ENTRANCE_block, 23 }, { 4, 0, 0, 23 },
+ { 5, TERM2, TERM2_block, 24 }, { 5, HANGAR, AIRPORT_ENTRANCE_block, 24 }, { 5, 0, 0, 24 },
+ { 6, TERM3, TERM3_block, 25 }, { 6, HANGAR, AIRPORT_ENTRANCE_block, 25 }, { 6, 0, 0, 25 },
+ { 7, TERM4, TERM4_block, 16 }, { 7, HANGAR, HANGAR2_AREA_block, 16 }, { 7, 0, 0, 16 },
+ { 8, TERM5, TERM5_block, 17 }, { 8, HANGAR, HANGAR2_AREA_block, 17 }, { 8, 0, 0, 17 },
+ { 9, TERM6, TERM6_block, 18 }, { 9, HANGAR, HANGAR2_AREA_block, 18 }, { 9, 0, 0, 18 },
+ { 10, HELIPAD1, HELIPAD1_block, 10 }, { 10, HANGAR, HANGAR2_AREA_block, 16 }, { 10, HELITAKEOFF, 0, 47 },
+ { 11, HELIPAD2, HELIPAD2_block, 11 }, { 11, HANGAR, HANGAR2_AREA_block, 17 }, { 11, HELITAKEOFF, 0, 48 },
+ { 12, 0, TERM_GROUP2_ENTER1_block, 13 },
+ { 13, 0, TERM_GROUP2_ENTER1_block, 14 },
+ { 14, 0, TERM_GROUP2_ENTER2_block, 15 },
+ { 15, 0, TERM_GROUP2_ENTER2_block, 16 },
+ { 16, 255, TERM_GROUP2_block, 0 }, { 16, TERM4, TERM4_block, 7 }, { 16, HELIPAD1, HELIPAD1_block, 10 }, { 16, HELITAKEOFF, HELIPAD1_block, 10 }, { 16, 0, 0, 17 },
+ { 17, 255, TERM_GROUP2_block, 0 }, { 17, TERM5, TERM5_block, 8 }, { 17, TERM4, 0, 16 }, { 17, HELIPAD1, 0, 16 }, { 17, HELIPAD2, HELIPAD2_block, 11 }, { 17, HELITAKEOFF, HELIPAD2_block, 11 }, { 17, 0, 0, 18 },
+ { 18, 255, TERM_GROUP2_block, 0 }, { 18, TERM6, TERM6_block, 9 }, { 18, TAKEOFF, 0, 19 }, { 18, HANGAR, HANGAR2_AREA_block, 3 }, { 18, 0, 0, 17 },
+ { 19, 0, TERM_GROUP2_EXIT1_block, 20 },
+ { 20, 0, TERM_GROUP2_EXIT1_block, 21 },
+ { 21, 0, TERM_GROUP2_EXIT2_block, 22 },
+ { 22, 0, TERM_GROUP2_EXIT2_block, 26 },
+ { 23, 255, TERM_GROUP1_block, 0 }, { 23, TERM1, TERM1_block, 4 }, { 23, HANGAR, AIRPORT_ENTRANCE_block, 2 }, { 23, 0, 0, 24 },
+ { 24, 255, TERM_GROUP1_block, 0 }, { 24, TERM2, TERM2_block, 5 }, { 24, TERM1, 0, 23 }, { 24, HANGAR, 0, 23 }, { 24, 0, 0, 25 },
+ { 25, 255, TERM_GROUP1_block, 0 }, { 25, TERM3, TERM3_block, 6 }, { 25, TAKEOFF, 0, 26 }, { 25, 0, 0, 24 },
+ { 26, 255, TAXIWAY_BUSY_block, 0 }, { 26, TAKEOFF, 0, 27 }, { 26, 0, 0, 25 },
+ { 27, 0, OUT_WAY_block, 28 },
+ // takeoff
+ { 28, TAKEOFF, OUT_WAY_block, 29 },
+ { 29, 0, RUNWAY_OUT_block, 30 },
+ { 30, STARTTAKEOFF, NOTHING_block, 31 },
+ { 31, ENDTAKEOFF, NOTHING_block, 0 },
+ // landing
+ { 32, FLYING, NOTHING_block, 37 }, { 32, LANDING, 0, 33 }, { 32, HELILANDING, 0, 41 },
+ { 33, LANDING, RUNWAY_IN_block, 34 },
+ { 34, 0, RUNWAY_IN_block, 35 },
+ { 35, 0, RUNWAY_IN_block, 36 },
+ { 36, ENDLANDING, IN_WAY_block, 36 }, { 36, 255, TERM_GROUP1_block, 0 }, { 36, 255, TERM_GROUP2_ENTER1_block, 1 }, { 36, TERM4, 0, 12 }, { 36, TERM5, 0, 12 }, { 36, TERM6, 0, 12 }, { 36, 0, 0, 2 },
+ // In Air
+ { 37, 0, NOTHING_block, 38 },
+ { 38, 0, NOTHING_block, 39 },
+ { 39, 0, NOTHING_block, 40 },
+ { 40, 0, NOTHING_block, 32 },
+ // Helicopter -- stay in air in special place as a buffer to choose from helipads
+ { 41, HELILANDING, PRE_HELIPAD_block, 42 },
+ { 42, HELIENDLANDING, PRE_HELIPAD_block, 42 }, { 42, HELIPAD1, 0, 43 }, { 42, HELIPAD2, 0, 44 }, { 42, HANGAR, 0, 49 },
+ { 43, 0, NOTHING_block, 45 },
+ { 44, 0, NOTHING_block, 46 },
+ // landing
+ { 45, 255, NOTHING_block, 0 }, { 45, HELIPAD1, HELIPAD1_block, 10 },
+ { 46, 255, NOTHING_block, 0 }, { 46, HELIPAD2, HELIPAD2_block, 11 },
+ // Helicopter -- takeoff
+ { 47, HELITAKEOFF, NOTHING_block, 0 },
+ { 48, HELITAKEOFF, NOTHING_block, 0 },
+ { 49, 0, HANGAR2_AREA_block, 50 }, // need to go to hangar when waiting in air
+ { 50, 0, HANGAR2_AREA_block, 3 },
+ { MAX_ELEMENTS, 0, 0, 0 } // end marker. DO NOT REMOVE
+};
+
+// intercontinental
+static const TileIndexDiffC _airport_depots_intercontinental[] = { { 0, 5 }, { 8, 4 } };
+static const byte _airport_terminal_intercontinental[] = { 2, 4, 4 };
+static const byte _airport_helipad_intercontinental[] = { 1, 2 };
+static const AirportFTAbuildup _airport_fta_intercontinental[] = {
+ { 0, HANGAR, NOTHING_block, 2 }, { 0, 255, HANGAR1_AREA_block | TERM_GROUP1_block, 0 }, { 0, 255, HANGAR1_AREA_block | TERM_GROUP1_block, 1 }, { 0, TAKEOFF, HANGAR1_AREA_block | TERM_GROUP1_block, 2 }, { 0, 0, 0, 2 },
+ { 1, HANGAR, NOTHING_block, 3 }, { 1, 255, HANGAR2_AREA_block, 1 }, { 1, 255, HANGAR2_AREA_block, 0 }, { 1, 0, 0, 3 },
+ { 2, 255, HANGAR1_AREA_block, 0 }, { 2, 255, TERM_GROUP1_block, 0 }, { 2, 255, TERM_GROUP1_block, 1 }, { 2, HANGAR, 0, 0 }, { 2, TAKEOFF, TERM_GROUP1_block, 27 }, { 2, TERM5, 0, 26 }, { 2, TERM6, 0, 26 }, { 2, TERM7, 0, 26 }, { 2, TERM8, 0, 26 }, { 2, HELIPAD1, 0, 26 }, { 2, HELIPAD2, 0, 26 }, { 2, HELITAKEOFF, 0, 74 }, { 2, 0, 0, 27 },
+ { 3, 255, HANGAR2_AREA_block, 0 }, { 3, HANGAR, 0, 1 }, { 3, HELITAKEOFF, 0, 75 }, { 3, 0, 0, 20 },
+ { 4, TERM1, TERM1_block, 26 }, { 4, HANGAR, HANGAR1_AREA_block | TERM_GROUP1_block, 26 }, { 4, 0, 0, 26 },
+ { 5, TERM2, TERM2_block, 27 }, { 5, HANGAR, HANGAR1_AREA_block | TERM_GROUP1_block, 27 }, { 5, 0, 0, 27 },
+ { 6, TERM3, TERM3_block, 28 }, { 6, HANGAR, HANGAR1_AREA_block | TERM_GROUP1_block, 28 }, { 6, 0, 0, 28 },
+ { 7, TERM4, TERM4_block, 29 }, { 7, HANGAR, HANGAR1_AREA_block | TERM_GROUP1_block, 29 }, { 7, 0, 0, 29 },
+ { 8, TERM5, TERM5_block, 18 }, { 8, HANGAR, HANGAR2_AREA_block, 18 }, { 8, 0, 0, 18 },
+ { 9, TERM6, TERM6_block, 19 }, { 9, HANGAR, HANGAR2_AREA_block, 19 }, { 9, 0, 0, 19 },
+ { 10, TERM7, TERM7_block, 20 }, { 10, HANGAR, HANGAR2_AREA_block, 20 }, { 10, 0, 0, 20 },
+ { 11, TERM8, TERM8_block, 21 }, { 11, HANGAR, HANGAR2_AREA_block, 21 }, { 11, 0, 0, 21 },
+ { 12, HELIPAD1, HELIPAD1_block, 12 }, { 12, HANGAR, 0, 70 }, { 12, HELITAKEOFF, 0, 72 },
+ { 13, HELIPAD2, HELIPAD2_block, 13 }, { 13, HANGAR, 0, 71 }, { 13, HELITAKEOFF, 0, 73 },
+ { 14, 0, TERM_GROUP2_ENTER1_block, 15 },
+ { 15, 0, TERM_GROUP2_ENTER1_block, 16 },
+ { 16, 0, TERM_GROUP2_ENTER2_block, 17 },
+ { 17, 0, TERM_GROUP2_ENTER2_block, 18 },
+ { 18, 255, TERM_GROUP2_block, 0 }, { 18, TERM5, TERM5_block, 8 }, { 18, TAKEOFF, 0, 19 }, { 18, HELITAKEOFF, HELIPAD1_block, 19 }, { 18, 0, TERM_GROUP2_EXIT1_block, 19 },
+ { 19, 255, TERM_GROUP2_block, 0 }, { 19, TERM6, TERM6_block, 9 }, { 19, TERM5, 0, 18 }, { 19, TAKEOFF, 0, 57 }, { 19, HELITAKEOFF, HELIPAD1_block, 20 }, { 19, 0, TERM_GROUP2_EXIT1_block, 20 }, // add exit to runway out 2
+ { 20, 255, TERM_GROUP2_block, 0 }, { 20, TERM7, TERM7_block, 10 }, { 20, TERM5, 0, 19 }, { 20, TERM6, 0, 19 }, { 20, HANGAR, HANGAR2_AREA_block, 3 }, { 20, TAKEOFF, 0, 19 }, { 20, 0, TERM_GROUP2_EXIT1_block, 21 },
+ { 21, 255, TERM_GROUP2_block, 0 }, { 21, TERM8, TERM8_block, 11 }, { 21, HANGAR, HANGAR2_AREA_block, 20 }, { 21, TERM5, 0, 20 }, { 21, TERM6, 0, 20 }, { 21, TERM7, 0, 20 }, { 21, TAKEOFF, 0, 20 }, { 21, 0, TERM_GROUP2_EXIT1_block, 22 },
+ { 22, 255, TERM_GROUP2_block, 0 }, { 22, HANGAR, 0, 21 }, { 22, TERM5, 0, 21 }, { 22, TERM6, 0, 21 }, { 22, TERM7, 0, 21 }, { 22, TERM8, 0, 21 }, { 22, TAKEOFF, 0, 21 }, { 22, 0, 0, 23 },
+ { 23, 0, TERM_GROUP2_EXIT1_block, 70 },
+ { 24, 0, TERM_GROUP2_EXIT2_block, 25 },
+ { 25, 255, TERM_GROUP2_EXIT2_block, 0 }, { 25, HANGAR, HANGAR1_AREA_block | TERM_GROUP1_block, 29 }, { 25, 0, 0, 29 },
+ { 26, 255, TERM_GROUP1_block, 0 }, { 26, TERM1, TERM1_block, 4 }, { 26, HANGAR, HANGAR1_AREA_block, 27 }, { 26, TERM5, TERM_GROUP2_ENTER1_block, 14 }, { 26, TERM6, TERM_GROUP2_ENTER1_block, 14 }, { 26, TERM7, TERM_GROUP2_ENTER1_block, 14 }, { 26, TERM8, TERM_GROUP2_ENTER1_block, 14 }, { 26, HELIPAD1, TERM_GROUP2_ENTER1_block, 14 }, { 26, HELIPAD2, TERM_GROUP2_ENTER1_block, 14 }, { 26, HELITAKEOFF, TERM_GROUP2_ENTER1_block, 14 }, { 26, 0, 0, 27 },
+ { 27, 255, TERM_GROUP1_block, 0 }, { 27, TERM2, TERM2_block, 5 }, { 27, HANGAR, HANGAR1_AREA_block, 2 }, { 27, TERM1, 0, 26 }, { 27, TERM5, 0, 26 }, { 27, TERM6, 0, 26 }, { 27, TERM7, 0, 26 }, { 27, TERM8, 0, 26 }, { 27, HELIPAD1, 0, 14 }, { 27, HELIPAD2, 0, 14 }, { 27, 0, 0, 28 },
+ { 28, 255, TERM_GROUP1_block, 0 }, { 28, TERM3, TERM3_block, 6 }, { 28, HANGAR, HANGAR1_AREA_block, 27 }, { 28, TERM1, 0, 27 }, { 28, TERM2, 0, 27 }, { 28, TERM4, 0, 29 }, { 28, TERM5, 0, 14 }, { 28, TERM6, 0, 14 }, { 28, TERM7, 0, 14 }, { 28, TERM8, 0, 14 }, { 28, HELIPAD1, 0, 14 }, { 28, HELIPAD2, 0, 14 }, { 28, 0, 0, 29 },
+ { 29, 255, TERM_GROUP1_block, 0 }, { 29, TERM4, TERM4_block, 7 }, { 29, HANGAR, HANGAR1_AREA_block, 27 }, { 29, TAKEOFF, 0, 30 }, { 29, 0, 0, 28 },
+ { 30, 0, OUT_WAY_block2, 31 },
+ { 31, 0, OUT_WAY_block, 32 },
+ // takeoff
+ { 32, TAKEOFF, RUNWAY_OUT_block, 33 },
+ { 33, 0, RUNWAY_OUT_block, 34 },
+ { 34, STARTTAKEOFF, NOTHING_block, 35 },
+ { 35, ENDTAKEOFF, NOTHING_block, 0 },
+ // landing
+ { 36, 0, 0, 0 },
+ { 37, LANDING, RUNWAY_IN_block, 38 },
+ { 38, 0, RUNWAY_IN_block, 39 },
+ { 39, 0, RUNWAY_IN_block, 40 },
+ { 40, ENDLANDING, RUNWAY_IN_block, 41 },
+ { 41, 0, IN_WAY_block, 42 },
+ { 42, 255, IN_WAY_block, 0 }, { 42, 255, TERM_GROUP1_block, 0 }, { 42, 255, TERM_GROUP1_block, 1 }, { 42, HANGAR, 0, 2 }, { 42, 0, 0, 26 },
+ // In Air
+ { 43, 0, 0, 44 },
+ { 44, FLYING, 0, 45 }, { 44, HELILANDING, 0, 47 }, { 44, LANDING, 0, 69 }, { 44, 0, 0, 45 },
+ { 45, 0, 0, 46 },
+ { 46, FLYING, 0, 43 }, { 46, LANDING, 0, 76 }, { 46, 0, 0, 43 },
+ // Helicopter -- stay in air in special place as a buffer to choose from helipads
+ { 47, HELILANDING, PRE_HELIPAD_block, 48 },
+ { 48, HELIENDLANDING, PRE_HELIPAD_block, 48 }, { 48, HELIPAD1, 0, 49 }, { 48, HELIPAD2, 0, 50 }, { 48, HANGAR, 0, 55 },
+ { 49, 0, NOTHING_block, 51 },
+ { 50, 0, NOTHING_block, 52 },
+ // landing
+ { 51, 255, NOTHING_block, 0 }, { 51, HELIPAD1, HELIPAD1_block, 12 }, { 51, HANGAR, 0, 55 }, { 51, 0, 0, 12 },
+ { 52, 255, NOTHING_block, 0 }, { 52, HELIPAD2, HELIPAD2_block, 13 }, { 52, HANGAR, 0, 55 }, { 52, 0, 0, 13 },
+ // Helicopter -- takeoff
+ { 53, HELITAKEOFF, NOTHING_block, 0 },
+ { 54, HELITAKEOFF, NOTHING_block, 0 },
+ { 55, 0, HANGAR2_AREA_block, 56 }, // need to go to hangar when waiting in air
+ { 56, 0, HANGAR2_AREA_block, 3 },
+ // runway 2 out support
+ { 57, 255, OUT_WAY2_block, 0 }, { 57, TAKEOFF, 0, 58 }, { 57, 0, 0, 58 },
+ { 58, 0, OUT_WAY2_block, 59 },
+ { 59, TAKEOFF, RUNWAY_OUT2_block, 60 }, // takeoff
+ { 60, 0, RUNWAY_OUT2_block, 61 },
+ { 61, STARTTAKEOFF, NOTHING_block, 62 },
+ { 62, ENDTAKEOFF, NOTHING_block, 0 },
+ // runway 2 in support
+ { 63, LANDING, RUNWAY_IN2_block, 64 },
+ { 64, 0, RUNWAY_IN2_block, 65 },
+ { 65, 0, RUNWAY_IN2_block, 66 },
+ { 66, ENDLANDING, RUNWAY_IN2_block, 0 }, { 66, 255, 0, 1 }, { 66, 255, 0, 0 }, { 66, 0, 0, 67 },
+ { 67, 0, IN_WAY2_block, 68 },
+ { 68, 255, IN_WAY2_block, 0 }, { 68, 255, TERM_GROUP2_block, 1 }, { 68, 255, TERM_GROUP1_block, 0 }, { 68, HANGAR, HANGAR2_AREA_block, 22 }, { 68, 0, 0, 22 },
+ { 69, 255, RUNWAY_IN2_block, 0 }, { 69, 0, RUNWAY_IN2_block, 63 },
+ { 70, 255, TERM_GROUP2_EXIT1_block, 0 }, { 70, HELIPAD1, HELIPAD1_block, 12 }, { 70, HELITAKEOFF, HELIPAD1_block, 12 }, { 70, 0, 0, 71 },
+ { 71, 255, TERM_GROUP2_EXIT1_block, 0 }, { 71, HELIPAD2, HELIPAD2_block, 13 }, { 71, HELITAKEOFF, HELIPAD1_block, 12 }, { 71, 0, 0, 24 },
+ { 72, 0, HELIPAD1_block, 53 },
+ { 73, 0, HELIPAD2_block, 54 },
+ { 74, HELITAKEOFF, NOTHING_block, 0 },
+ { 75, HELITAKEOFF, NOTHING_block, 0 },
+ { 76, 255, RUNWAY_IN_block, 0 }, { 76, 0, RUNWAY_IN_block, 37 },
+ { MAX_ELEMENTS, 0, 0, 0 } // end marker. DO NOT REMOVE
+};
+
+
+// heliports, oilrigs don't have depots
+static const byte _airport_helipad_heliport_oilrig[] = { 1, 1 };
+static const AirportFTAbuildup _airport_fta_heliport_oilrig[] = {
+ { 0, HELIPAD1, HELIPAD1_block, 1 },
+ { 1, HELITAKEOFF, NOTHING_block, 0 }, // takeoff
+ { 2, 255, AIRPORT_BUSY_block, 0 }, { 2, HELILANDING, 0, 3 }, { 2, HELITAKEOFF, 0, 1 },
+ { 3, HELILANDING, AIRPORT_BUSY_block, 4 },
+ { 4, HELIENDLANDING, AIRPORT_BUSY_block, 4 }, { 4, HELIPAD1, HELIPAD1_block, 0 }, { 4, HELITAKEOFF, 0, 2 },
+ // In Air
+ { 5, 0, NOTHING_block, 6 },
+ { 6, 0, NOTHING_block, 7 },
+ { 7, 0, NOTHING_block, 8 },
+ { 8, FLYING, NOTHING_block, 5 }, { 8, HELILANDING, HELIPAD1_block, 2 }, // landing
+ { MAX_ELEMENTS, 0, 0, 0 } // end marker. DO NOT REMOVE
+};
+
+// helidepots
+static const TileIndexDiffC _airport_depots_helidepot[] = { { 1, 0 } };
+static const byte _airport_helipad_helidepot[] = { 1, 1 };
+static const AirportFTAbuildup _airport_fta_helidepot[] = {
+ { 0, HANGAR, NOTHING_block, 1 },
+ { 1, 255, HANGAR2_AREA_block, 0 }, { 1, HANGAR, 0, 0 }, { 1, HELIPAD1, HELIPAD1_block, 14 }, { 1, HELITAKEOFF, 0, 15 }, { 1, 0, 0, 0 },
+ { 2, FLYING, NOTHING_block, 3 }, { 2, HELILANDING, PRE_HELIPAD_block, 7 }, { 2, HANGAR, 0, 12 }, { 2, HELITAKEOFF, NOTHING_block, 16 },
+ // In Air
+ { 3, 0, NOTHING_block, 4 },
+ { 4, 0, NOTHING_block, 5 },
+ { 5, 0, NOTHING_block, 6 },
+ { 6, 0, NOTHING_block, 2 },
+ // Helicopter -- stay in air in special place as a buffer to choose from helipads
+ { 7, HELILANDING, PRE_HELIPAD_block, 8 },
+ { 8, HELIENDLANDING, PRE_HELIPAD_block, 8 }, { 8, HELIPAD1, 0, 9 }, { 8, HANGAR, 0, 12 }, { 8, 0, 0, 2 },
+ { 9, 0, NOTHING_block, 10 },
+ // landing
+ { 10, 255, NOTHING_block, 10 }, { 10, HELIPAD1, HELIPAD1_block, 14 }, { 10, HANGAR, 0, 1 }, { 10, 0, 0, 14 },
+ // Helicopter -- takeoff
+ { 11, HELITAKEOFF, NOTHING_block, 0 },
+ { 12, 0, HANGAR2_AREA_block, 13 }, // need to go to hangar when waiting in air
+ { 13, 0, HANGAR2_AREA_block, 1 },
+ { 14, HELIPAD1, HELIPAD1_block, 14 }, { 14, HANGAR, 0, 1 }, { 14, HELITAKEOFF, 0, 17 },
+ { 15, HELITAKEOFF, NOTHING_block, 0 }, // takeoff outside depot
+ { 16, HELITAKEOFF, 0, 14 },
+ { 17, 0, NOTHING_block, 11 },
+ { MAX_ELEMENTS, 0, 0, 0 } // end marker. DO NOT REMOVE
+};
+
+// helistation
+static const TileIndexDiffC _airport_depots_helistation[] = { { 0, 0 } };
+static const byte _airport_helipad_helistation[] = { 1, 3 };
+static const AirportFTAbuildup _airport_fta_helistation[] = {
+ { 0, HANGAR, NOTHING_block, 8 }, { 0, HELIPAD1, 0, 1 }, { 0, HELIPAD2, 0, 1 }, { 0, HELIPAD3, 0, 1 }, { 0, HELITAKEOFF, 0, 1 }, { 0, 0, 0, 0 },
+ { 1, 255, HANGAR2_AREA_block, 0 }, { 1, HANGAR, 0, 0 }, { 1, HELITAKEOFF, 0, 3 }, { 1, 0, 0, 4 },
+ // landing
+ { 2, FLYING, NOTHING_block, 28 }, { 2, HELILANDING, 0, 15 }, { 2, 0, 0, 28 },
+ // helicopter side
+ { 3, HELITAKEOFF, NOTHING_block, 0 }, // helitakeoff outside hangar2
+ { 4, 255, TAXIWAY_BUSY_block, 0 }, { 4, HANGAR, HANGAR2_AREA_block, 1 }, { 4, HELITAKEOFF, 0, 1 }, { 4, 0, 0, 5 },
+ { 5, 255, TAXIWAY_BUSY_block, 0 }, { 5, HELIPAD1, HELIPAD1_block, 6 }, { 5, HELIPAD2, HELIPAD2_block, 7 }, { 5, HELIPAD3, HELIPAD3_block, 8 }, { 5, 0, 0, 4 },
+ { 6, HELIPAD1, HELIPAD1_block, 5 }, { 6, HANGAR, HANGAR2_AREA_block, 5 }, { 6, HELITAKEOFF, 0, 9 }, { 6, 0, 0, 6 },
+ { 7, HELIPAD2, HELIPAD2_block, 5 }, { 7, HANGAR, HANGAR2_AREA_block, 5 }, { 7, HELITAKEOFF, 0, 10 }, { 7, 0, 0, 7 },
+ { 8, HELIPAD3, HELIPAD3_block, 5 }, { 8, HANGAR, HANGAR2_AREA_block, 5 }, { 8, HELITAKEOFF, 0, 11 }, { 8, 0, 0, 8 },
+ { 9, 0, HELIPAD1_block, 12 },
+ { 10, 0, HELIPAD2_block, 13 },
+ { 11, 0, HELIPAD3_block, 14 },
+ { 12, HELITAKEOFF, NOTHING_block, 0 },
+ { 13, HELITAKEOFF, NOTHING_block, 0 },
+ { 14, HELITAKEOFF, NOTHING_block, 0 },
+ // heli - in flight moves
+ { 15, HELILANDING, PRE_HELIPAD_block, 16 },
+ { 16, HELIENDLANDING, PRE_HELIPAD_block, 16 }, { 16, HELIPAD1, 0, 17 }, { 16, HELIPAD2, 0, 18 }, { 16, HELIPAD3, 0, 19 }, { 16, HANGAR, 0, 23 },
+ { 17, 0, NOTHING_block, 20 },
+ { 18, 0, NOTHING_block, 21 },
+ { 19, 0, NOTHING_block, 22 },
+ // heli landing
+ { 20, 255, NOTHING_block, 0 }, { 20, HELIPAD1, HELIPAD1_block, 6 }, { 20, HANGAR, 0, 23 }, { 20, 0, 0, 6 },
+ { 21, 255, NOTHING_block, 0 }, { 21, HELIPAD2, HELIPAD2_block, 7 }, { 21, HANGAR, 0, 23 }, { 21, 0, 0, 7 },
+ { 22, 255, NOTHING_block, 0 }, { 22, HELIPAD3, HELIPAD3_block, 8 }, { 22, HANGAR, 0, 23 }, { 22, 0, 0, 8 },
+ { 23, 0, HANGAR2_AREA_block, 24 }, // need to go to helihangar when waiting in air
+ { 24, 0, HANGAR2_AREA_block, 1 },
+ { 25, 0, NOTHING_block, 26 },
+ { 26, 0, NOTHING_block, 27 },
+ { 27, 0, NOTHING_block, 2 },
+ { 28, 0, NOTHING_block, 29 },
+ { 29, 0, NOTHING_block, 30 },
+ { 30, 0, NOTHING_block, 31 },
+ { 31, 0, NOTHING_block, 32 },
+ { 32, 0, NOTHING_block, 25 },
+ { MAX_ELEMENTS, 0, 0, 0 } // end marker. DO NOT REMOVE
+};
+
+
+static const AirportMovingData * const _airport_moving_datas[] = {
+ _airport_moving_data_country, // Country Airfield (small) 4x3
+ _airport_moving_data_town, // City Airport (large) 6x6
+ _airport_moving_data_heliport, // Heliport
+ _airport_moving_data_metropolitan, // Metropolitain Airport (large) - 2 runways
+ _airport_moving_data_international, // International Airport (xlarge) - 2 runways
+ _airport_moving_data_commuter, // Commuter Airfield (small) 5x4
+ _airport_moving_data_helidepot, // Helidepot
+ _airport_moving_data_intercontinental, // Intercontinental Airport (xxlarge) - 4 runways
+ _airport_moving_data_helistation, // Helistation
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _airport_moving_data_oilrig // Oilrig
+};
+
+#endif /* AIRPORT_MOVEMENT_H */
diff --git a/src/aystar.c b/src/aystar.c
new file mode 100644
index 000000000..0000d584c
--- /dev/null
+++ b/src/aystar.c
@@ -0,0 +1,296 @@
+/* $Id$ */
+
+/*
+ * This file has the core function for AyStar
+ * AyStar is a fast pathfinding routine and is used for things like
+ * AI_pathfinding and Train_pathfinding.
+ * For more information about AyStar (A* Algorithm), you can look at
+ * http://en.wikipedia.org/wiki/A-star_search_algorithm
+ */
+
+/*
+ * Friendly reminder:
+ * Call (AyStar).free() when you are done with Aystar. It reserves a lot of memory
+ * And when not free'd, it can cause system-crashes.
+ * Also remember that when you stop an algorithm before it is finished, your
+ * should call clear() yourself!
+ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "aystar.h"
+
+int _aystar_stats_open_size;
+int _aystar_stats_closed_size;
+
+// This looks in the Hash if a node exists in ClosedList
+// If so, it returns the PathNode, else NULL
+static PathNode* AyStarMain_ClosedList_IsInList(AyStar *aystar, const AyStarNode *node)
+{
+ return (PathNode*)Hash_Get(&aystar->ClosedListHash, node->tile, node->direction);
+}
+
+// This adds a node to the ClosedList
+// It makes a copy of the data
+static void AyStarMain_ClosedList_Add(AyStar *aystar, const PathNode *node)
+{
+ // Add a node to the ClosedList
+ PathNode *new_node = malloc(sizeof(*new_node));
+ *new_node = *node;
+ Hash_Set(&aystar->ClosedListHash, node->node.tile, node->node.direction, new_node);
+}
+
+// Checks if a node is in the OpenList
+// If so, it returns the OpenListNode, else NULL
+static OpenListNode *AyStarMain_OpenList_IsInList(AyStar *aystar, const AyStarNode *node)
+{
+ return (OpenListNode*)Hash_Get(&aystar->OpenListHash, node->tile, node->direction);
+}
+
+// Gets the best node from OpenList
+// returns the best node, or NULL of none is found
+// Also it deletes the node from the OpenList
+static OpenListNode *AyStarMain_OpenList_Pop(AyStar *aystar)
+{
+ // Return the item the Queue returns.. the best next OpenList item.
+ OpenListNode *res = (OpenListNode*)aystar->OpenListQueue.pop(&aystar->OpenListQueue);
+ if (res != NULL) {
+ Hash_Delete(&aystar->OpenListHash, res->path.node.tile, res->path.node.direction);
+ }
+
+ return res;
+}
+
+// Adds a node to the OpenList
+// It makes a copy of node, and puts the pointer of parent in the struct
+static void AyStarMain_OpenList_Add(AyStar *aystar, PathNode *parent, const AyStarNode *node, int f, int g)
+{
+ // Add a new Node to the OpenList
+ OpenListNode *new_node = malloc(sizeof(*new_node));
+ new_node->g = g;
+ new_node->path.parent = parent;
+ new_node->path.node = *node;
+ Hash_Set(&aystar->OpenListHash, node->tile, node->direction, new_node);
+
+ // Add it to the queue
+ aystar->OpenListQueue.push(&aystar->OpenListQueue, new_node, f);
+}
+
+/*
+ * Checks one tile and calculate his f-value
+ * return values:
+ * AYSTAR_DONE : indicates we are done
+ */
+int AyStarMain_CheckTile(AyStar *aystar, AyStarNode *current, OpenListNode *parent)
+{
+ int new_f, new_g, new_h;
+ PathNode *closedlist_parent;
+ OpenListNode *check;
+
+ // Check the new node against the ClosedList
+ if (AyStarMain_ClosedList_IsInList(aystar, current) != NULL) return AYSTAR_DONE;
+
+ // Calculate the G-value for this node
+ new_g = aystar->CalculateG(aystar, current, parent);
+ // If the value was INVALID_NODE, we don't do anything with this node
+ if (new_g == AYSTAR_INVALID_NODE) return AYSTAR_DONE;
+
+ // There should not be given any other error-code..
+ assert(new_g >= 0);
+ // Add the parent g-value to the new g-value
+ new_g += parent->g;
+ if (aystar->max_path_cost != 0 && (uint)new_g > aystar->max_path_cost) return AYSTAR_DONE;
+
+ // Calculate the h-value
+ new_h = aystar->CalculateH(aystar, current, parent);
+ // There should not be given any error-code..
+ assert(new_h >= 0);
+
+ // The f-value if g + h
+ new_f = new_g + new_h;
+
+ // Get the pointer to the parent in the ClosedList (the currentone is to a copy of the one in the OpenList)
+ closedlist_parent = AyStarMain_ClosedList_IsInList(aystar, &parent->path.node);
+
+ // Check if this item is already in the OpenList
+ check = AyStarMain_OpenList_IsInList(aystar, current);
+ if (check != NULL) {
+ uint i;
+ // Yes, check if this g value is lower..
+ if (new_g > check->g) return AYSTAR_DONE;
+ aystar->OpenListQueue.del(&aystar->OpenListQueue, check, 0);
+ // It is lower, so change it to this item
+ check->g = new_g;
+ check->path.parent = closedlist_parent;
+ /* Copy user data, will probably have changed */
+ for (i = 0; i < lengthof(current->user_data); i++) {
+ check->path.node.user_data[i] = current->user_data[i];
+ }
+ // Readd him in the OpenListQueue
+ aystar->OpenListQueue.push(&aystar->OpenListQueue, check, new_f);
+ } else {
+ // A new node, add him to the OpenList
+ AyStarMain_OpenList_Add(aystar, closedlist_parent, current, new_f, new_g);
+ }
+
+ return AYSTAR_DONE;
+}
+
+/*
+ * This function is the core of AyStar. It handles one item and checks
+ * his neighbour items. If they are valid, they are added to be checked too.
+ * return values:
+ * AYSTAR_EMPTY_OPENLIST : indicates all items are tested, and no path
+ * has been found.
+ * AYSTAR_LIMIT_REACHED : Indicates that the max_nodes limit has been
+ * reached.
+ * AYSTAR_FOUND_END_NODE : indicates we found the end. Path_found now is true, and in path is the path found.
+ * AYSTAR_STILL_BUSY : indicates we have done this tile, did not found the path yet, and have items left to try.
+ */
+int AyStarMain_Loop(AyStar *aystar)
+{
+ int i, r;
+
+ // Get the best node from OpenList
+ OpenListNode *current = AyStarMain_OpenList_Pop(aystar);
+ // If empty, drop an error
+ if (current == NULL) return AYSTAR_EMPTY_OPENLIST;
+
+ // Check for end node and if found, return that code
+ if (aystar->EndNodeCheck(aystar, current) == AYSTAR_FOUND_END_NODE) {
+ if (aystar->FoundEndNode != NULL)
+ aystar->FoundEndNode(aystar, current);
+ free(current);
+ return AYSTAR_FOUND_END_NODE;
+ }
+
+ // Add the node to the ClosedList
+ AyStarMain_ClosedList_Add(aystar, &current->path);
+
+ // Load the neighbours
+ aystar->GetNeighbours(aystar, current);
+
+ // Go through all neighbours
+ for (i = 0; i < aystar->num_neighbours; i++) {
+ // Check and add them to the OpenList if needed
+ r = aystar->checktile(aystar, &aystar->neighbours[i], current);
+ }
+
+ // Free the node
+ free(current);
+
+ if (aystar->max_search_nodes != 0 && Hash_Size(&aystar->ClosedListHash) >= aystar->max_search_nodes) {
+ /* We've expanded enough nodes */
+ return AYSTAR_LIMIT_REACHED;
+ } else {
+ // Return that we are still busy
+ return AYSTAR_STILL_BUSY;
+ }
+}
+
+/*
+ * This function frees the memory it allocated
+ */
+void AyStarMain_Free(AyStar *aystar)
+{
+ aystar->OpenListQueue.free(&aystar->OpenListQueue, false);
+ /* 2nd argument above is false, below is true, to free the values only
+ * once */
+ delete_Hash(&aystar->OpenListHash, true);
+ delete_Hash(&aystar->ClosedListHash, true);
+#ifdef AYSTAR_DEBUG
+ printf("[AyStar] Memory free'd\n");
+#endif
+}
+
+/*
+ * This function make the memory go back to zero
+ * This function should be called when you are using the same instance again.
+ */
+void AyStarMain_Clear(AyStar *aystar)
+{
+ // Clean the Queue, but not the elements within. That will be done by
+ // the hash.
+ aystar->OpenListQueue.clear(&aystar->OpenListQueue, false);
+ // Clean the hashes
+ clear_Hash(&aystar->OpenListHash, true);
+ clear_Hash(&aystar->ClosedListHash, true);
+
+#ifdef AYSTAR_DEBUG
+ printf("[AyStar] Cleared AyStar\n");
+#endif
+}
+
+/*
+ * This is the function you call to run AyStar.
+ * return values:
+ * AYSTAR_FOUND_END_NODE : indicates we found an end node.
+ * AYSTAR_NO_PATH : indicates that there was no path found.
+ * AYSTAR_STILL_BUSY : indicates we have done some checked, that we did not found the path yet, and that we still have items left to try.
+ * When the algorithm is done (when the return value is not AYSTAR_STILL_BUSY)
+ * aystar->clear() is called. Note that when you stop the algorithm halfway,
+ * you should still call clear() yourself!
+ */
+int AyStarMain_Main(AyStar *aystar) {
+ int r, i = 0;
+ // Loop through the OpenList
+ // Quit if result is no AYSTAR_STILL_BUSY or is more than loops_per_tick
+ while ((r = aystar->loop(aystar)) == AYSTAR_STILL_BUSY && (aystar->loops_per_tick == 0 || ++i < aystar->loops_per_tick)) { }
+#ifdef AYSTAR_DEBUG
+ switch (r) {
+ case AYSTAR_FOUND_END_NODE: printf("[AyStar] Found path!\n"); break;
+ case AYSTAR_EMPTY_OPENLIST: printf("[AyStar] OpenList run dry, no path found\n"); break;
+ case AYSTAR_LIMIT_REACHED: printf("[AyStar] Exceeded search_nodes, no path found\n"); break;
+ default: break;
+ }
+#endif
+ if (r != AYSTAR_STILL_BUSY) {
+ /* We're done, clean up */
+ _aystar_stats_open_size = aystar->OpenListHash.size;
+ _aystar_stats_closed_size = aystar->ClosedListHash.size;
+ aystar->clear(aystar);
+ }
+
+ switch (r) {
+ case AYSTAR_FOUND_END_NODE: return AYSTAR_FOUND_END_NODE;
+ case AYSTAR_EMPTY_OPENLIST:
+ case AYSTAR_LIMIT_REACHED: return AYSTAR_NO_PATH;
+ default: return AYSTAR_STILL_BUSY;
+ }
+}
+
+/*
+ * Adds a node from where to start an algorithm. Multiple nodes can be added
+ * if wanted. You should make sure that clear() is called before adding nodes
+ * if the AyStar has been used before (though the normal main loop calls
+ * clear() automatically when the algorithm finishes
+ * g is the cost for starting with this node.
+ */
+void AyStarMain_AddStartNode(AyStar *aystar, AyStarNode *start_node, uint g)
+{
+#ifdef AYSTAR_DEBUG
+ printf("[AyStar] Starting A* Algorithm from node (%d, %d, %d)\n",
+ TileX(start_node->tile), TileY(start_node->tile), start_node->direction);
+#endif
+ AyStarMain_OpenList_Add(aystar, NULL, start_node, 0, g);
+}
+
+void init_AyStar(AyStar *aystar, Hash_HashProc hash, uint num_buckets)
+{
+ // Allocated the Hash for the OpenList and ClosedList
+ init_Hash(&aystar->OpenListHash, hash, num_buckets);
+ init_Hash(&aystar->ClosedListHash, hash, num_buckets);
+
+ // Set up our sorting queue
+ // BinaryHeap allocates a block of 1024 nodes
+ // When thatone gets full it reserves an otherone, till this number
+ // That is why it can stay this high
+ init_BinaryHeap(&aystar->OpenListQueue, 102400);
+
+ aystar->addstart = AyStarMain_AddStartNode;
+ aystar->main = AyStarMain_Main;
+ aystar->loop = AyStarMain_Loop;
+ aystar->free = AyStarMain_Free;
+ aystar->clear = AyStarMain_Clear;
+ aystar->checktile = AyStarMain_CheckTile;
+}
diff --git a/src/aystar.h b/src/aystar.h
new file mode 100644
index 000000000..4920a37d4
--- /dev/null
+++ b/src/aystar.h
@@ -0,0 +1,179 @@
+/* $Id$ */
+
+/*
+ * This file has the header for AyStar
+ * AyStar is a fast pathfinding routine and is used for things like
+ * AI_pathfinding and Train_pathfinding.
+ * For more information about AyStar (A* Algorithm), you can look at
+ * http://en.wikipedia.org/wiki/A-star_search_algorithm
+ */
+
+#ifndef AYSTAR_H
+#define AYSTAR_H
+
+#include "queue.h"
+
+//#define AYSTAR_DEBUG
+enum {
+ AYSTAR_FOUND_END_NODE,
+ AYSTAR_EMPTY_OPENLIST,
+ AYSTAR_STILL_BUSY,
+ AYSTAR_NO_PATH,
+ AYSTAR_LIMIT_REACHED,
+ AYSTAR_DONE
+};
+
+enum{
+ AYSTAR_INVALID_NODE = -1,
+};
+
+typedef struct AyStarNode AyStarNode;
+struct AyStarNode {
+ TileIndex tile;
+ uint direction;
+ uint user_data[2];
+};
+
+// The resulting path has nodes looking like this.
+typedef struct PathNode PathNode;
+struct PathNode {
+ AyStarNode node;
+ // The parent of this item
+ PathNode *parent;
+};
+
+// For internal use only
+// We do not save the h-value, because it is only needed to calculate the f-value.
+// h-value should _always_ be the distance left to the end-tile.
+typedef struct OpenListNode OpenListNode;
+struct OpenListNode {
+ int g;
+ PathNode path;
+};
+
+typedef struct AyStar AyStar;
+/*
+ * This function is called to check if the end-tile is found
+ * return values can be:
+ * AYSTAR_FOUND_END_NODE : indicates this is the end tile
+ * AYSTAR_DONE : indicates this is not the end tile (or direction was wrong)
+ */
+/*
+ * The 2nd parameter should be OpenListNode, and NOT AyStarNode. AyStarNode is
+ * part of OpenListNode and so it could be accessed without any problems.
+ * The good part about OpenListNode is, and how AIs use it, that you can
+ * access the parent of the current node, and so check if you, for example
+ * don't try to enter the file tile with a 90-degree curve. So please, leave
+ * this an OpenListNode, it works just fine -- TrueLight
+ */
+typedef int32 AyStar_EndNodeCheck(AyStar *aystar, OpenListNode *current);
+
+/*
+ * This function is called to calculate the G-value for AyStar Algorithm.
+ * return values can be:
+ * AYSTAR_INVALID_NODE : indicates an item is not valid (e.g.: unwalkable)
+ * Any value >= 0 : the g-value for this tile
+ */
+typedef int32 AyStar_CalculateG(AyStar *aystar, AyStarNode *current, OpenListNode *parent);
+
+/*
+ * This function is called to calculate the H-value for AyStar Algorithm.
+ * Mostly, this must result the distance (Manhattan way) between the
+ * current point and the end point
+ * return values can be:
+ * Any value >= 0 : the h-value for this tile
+ */
+typedef int32 AyStar_CalculateH(AyStar *aystar, AyStarNode *current, OpenListNode *parent);
+
+/*
+ * This function request the tiles around the current tile and put them in tiles_around
+ * tiles_around is never resetted, so if you are not using directions, just leave it alone.
+ * Warning: never add more tiles_around than memory allocated for it.
+ */
+typedef void AyStar_GetNeighbours(AyStar *aystar, OpenListNode *current);
+
+/*
+ * If the End Node is found, this function is called.
+ * It can do, for example, calculate the route and put that in an array
+ */
+typedef void AyStar_FoundEndNode(AyStar *aystar, OpenListNode *current);
+
+// For internal use, see aystar.c
+typedef void AyStar_AddStartNode(AyStar *aystar, AyStarNode *start_node, uint g);
+typedef int AyStar_Main(AyStar *aystar);
+typedef int AyStar_Loop(AyStar *aystar);
+typedef int AyStar_CheckTile(AyStar *aystar, AyStarNode *current, OpenListNode *parent);
+typedef void AyStar_Free(AyStar *aystar);
+typedef void AyStar_Clear(AyStar *aystar);
+
+struct AyStar {
+/* These fields should be filled before initting the AyStar, but not changed
+ * afterwards (except for user_data and user_path)! (free and init again to change them) */
+
+ /* These should point to the application specific routines that do the
+ * actual work */
+ AyStar_CalculateG *CalculateG;
+ AyStar_CalculateH *CalculateH;
+ AyStar_GetNeighbours *GetNeighbours;
+ AyStar_EndNodeCheck *EndNodeCheck;
+ AyStar_FoundEndNode *FoundEndNode;
+
+ /* These are completely untouched by AyStar, they can be accesed by
+ * the application specific routines to input and output data.
+ * user_path should typically contain data about the resulting path
+ * afterwards, user_target should typically contain information about
+ * what where looking for, and user_data can contain just about
+ * everything */
+ void *user_path;
+ void *user_target;
+ uint user_data[10];
+
+ /* How many loops are there called before AyStarMain_Main gives
+ * control back to the caller. 0 = until done */
+ byte loops_per_tick;
+ /* If the g-value goes over this number, it stops searching
+ * 0 = infinite */
+ uint max_path_cost;
+ /* The maximum amount of nodes that will be expanded, 0 = infinite */
+ uint max_search_nodes;
+
+ /* These should be filled with the neighbours of a tile by
+ * GetNeighbours */
+ AyStarNode neighbours[12];
+ byte num_neighbours;
+
+ /* These will contain the methods for manipulating the AyStar. Only
+ * main() should be called externally */
+ AyStar_AddStartNode *addstart;
+ AyStar_Main *main;
+ AyStar_Loop *loop;
+ AyStar_Free *free;
+ AyStar_Clear *clear;
+ AyStar_CheckTile *checktile;
+
+ /* These will contain the open and closed lists */
+
+ /* The actual closed list */
+ Hash ClosedListHash;
+ /* The open queue */
+ Queue OpenListQueue;
+ /* An extra hash to speed up the process of looking up an element in
+ * the open list */
+ Hash OpenListHash;
+};
+
+
+void AyStarMain_AddStartNode(AyStar *aystar, AyStarNode *start_node, uint g);
+int AyStarMain_Main(AyStar *aystar);
+int AyStarMain_Loop(AyStar *aystar);
+int AyStarMain_CheckTile(AyStar *aystar, AyStarNode *current, OpenListNode *parent);
+void AyStarMain_Free(AyStar *aystar);
+void AyStarMain_Clear(AyStar *aystar);
+
+/* Initialize an AyStar. You should fill all appropriate fields before
+ * callling init_AyStar (see the declaration of AyStar for which fields are
+ * internal */
+void init_AyStar(AyStar *aystar, Hash_HashProc hash, uint num_buckets);
+
+
+#endif /* AYSTAR_H */
diff --git a/src/bmp.c b/src/bmp.c
new file mode 100644
index 000000000..c2bd91270
--- /dev/null
+++ b/src/bmp.c
@@ -0,0 +1,378 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "gfx.h"
+#include "bmp.h"
+#include "macros.h"
+
+void BmpInitializeBuffer(BmpBuffer *buffer, FILE *file) {
+ buffer->pos = -1;
+ buffer->file = file;
+ buffer->read = 0;
+ buffer->real_pos = ftell(file);
+}
+
+static inline void AdvanceBuffer(BmpBuffer *buffer)
+{
+ buffer->read = (int)fread(buffer->data, 1, BMP_BUFFER_SIZE, buffer->file);
+ buffer->pos = 0;
+}
+
+static inline bool EndOfBuffer(BmpBuffer *buffer)
+{
+ if (buffer->pos == buffer->read || buffer->pos < 0) AdvanceBuffer(buffer);
+ return buffer->pos == buffer->read;
+}
+
+static inline byte ReadByte(BmpBuffer *buffer)
+{
+ if (buffer->pos == buffer->read || buffer->pos < 0) AdvanceBuffer(buffer);
+ buffer->real_pos++;
+ return buffer->data[buffer->pos++];
+}
+
+static inline uint16 ReadWord(BmpBuffer *buffer)
+{
+ uint16 var = ReadByte(buffer);
+ return var | (ReadByte(buffer) << 8);
+}
+
+static inline uint32 ReadDword(BmpBuffer *buffer)
+{
+ uint32 var = ReadWord(buffer);
+ return var | (ReadWord(buffer) << 16);
+}
+
+static inline void SkipBytes(BmpBuffer *buffer, int bytes)
+{
+ int i;
+ for (i = 0; i < bytes; i++) ReadByte(buffer);
+}
+
+static inline void SetStreamOffset(BmpBuffer *buffer, int offset)
+{
+ fseek(buffer->file, offset, SEEK_SET);
+ buffer->pos = -1;
+ buffer->real_pos = offset;
+ AdvanceBuffer(buffer);
+}
+
+/**
+ * Reads a 1 bpp uncompressed bitmap
+ * The bitmap is converted to a 8 bpp bitmap
+ */
+static inline bool BmpRead1(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
+{
+ uint x, y, i;
+ byte pad = GB(4 - info->width / 8, 0, 2);
+ byte *pixel_row;
+ byte b;
+ for (y = info->height; y > 0; y--) {
+ x = 0;
+ pixel_row = &data->bitmap[(y - 1) * info->width];
+ while (x < info->width) {
+ if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
+ b = ReadByte(buffer);
+ for (i = 8; i > 0; i--) {
+ if (x < info->width) *pixel_row++ = GB(b, i - 1, 1);
+ x++;
+ }
+ }
+ /* Padding for 32 bit align */
+ SkipBytes(buffer, pad);
+ }
+ return true;
+}
+
+/**
+ * Reads a 4 bpp uncompressed bitmap
+ * The bitmap is converted to a 8 bpp bitmap
+ */
+static inline bool BmpRead4(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
+{
+ uint x, y;
+ byte pad = GB(4 - info->width / 2, 0, 2);
+ byte *pixel_row;
+ byte b;
+ for (y = info->height; y > 0; y--) {
+ x = 0;
+ pixel_row = &data->bitmap[(y - 1) * info->width];
+ while (x < info->width) {
+ if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
+ b = ReadByte(buffer);
+ *pixel_row++ = GB(b, 4, 4);
+ x++;
+ if (x < info->width) {
+ *pixel_row++ = GB(b, 0, 4);
+ x++;
+ }
+ }
+ /* Padding for 32 bit align */
+ SkipBytes(buffer, pad);
+ }
+ return true;
+}
+
+/**
+ * Reads a 4-bit RLE compressed bitmap
+ * The bitmap is converted to a 8 bpp bitmap
+ */
+static inline bool BmpRead4Rle(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
+{
+ uint i;
+ uint x = 0;
+ uint y = info->height - 1;
+ byte n, c, b;
+ byte *pixel = &data->bitmap[y * info->width];
+ while (y != 0 || x < info->width) {
+ if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
+ n = ReadByte(buffer);
+ c = ReadByte(buffer);
+ if (n == 0) {
+ switch (c) {
+ case 0: // end of line
+ x = 0;
+ pixel = &data->bitmap[--y * info->width];
+ break;
+ case 1: // end of bitmap
+ x = info->width;
+ y = 0;
+ pixel = NULL;
+ break;
+ case 2: // delta
+ x += ReadByte(buffer);
+ i = ReadByte(buffer);
+ if (x >= info->width || (y == 0 && i > 0)) return false;
+ y -= i;
+ pixel = &data->bitmap[y * info->width + x];
+ break;
+ default: // uncompressed
+ i = 0;
+ while (i++ < c) {
+ if (EndOfBuffer(buffer) || x >= info->width) return false;
+ b = ReadByte(buffer);
+ *pixel++ = GB(b, 4, 4);
+ x++;
+ if (x < info->width && i++ < c) {
+ *pixel++ = GB(b, 0, 4);
+ x++;
+ }
+ }
+ /* Padding for 16 bit align */
+ SkipBytes(buffer, ((c + 1) / 2) % 2);
+ break;
+ }
+ } else {
+ i = 0;
+ while (i++ < n) {
+ if (EndOfBuffer(buffer) || x >= info->width) return false;
+ *pixel++ = GB(c, 4, 4);
+ x++;
+ if (x < info->width && i++ < n) {
+ *pixel++ = GB(c, 0, 4);
+ x++;
+ }
+ }
+ }
+ }
+ return true;
+}
+
+/**
+ * Reads a 8 bpp bitmap
+ */
+static inline bool BmpRead8(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
+{
+ uint i;
+ uint y;
+ byte pad = GB(4 - info->width, 0, 2);
+ byte *pixel;
+ for (y = info->height; y > 0; y--) {
+ if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
+ pixel = &data->bitmap[(y - 1) * info->width];
+ for (i = 0; i < info->width; i++) *pixel++ = ReadByte(buffer);
+ /* Padding for 32 bit align */
+ SkipBytes(buffer, pad);
+ }
+ return true;
+}
+
+/**
+ * Reads a 8-bit RLE compressed bpp bitmap
+ */
+static inline bool BmpRead8Rle(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
+{
+ uint i;
+ uint x = 0;
+ uint y = info->height - 1;
+ byte n, c;
+ byte *pixel = &data->bitmap[y * info->width];
+ while (y != 0 || x < info->width) {
+ if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
+ n = ReadByte(buffer);
+ c = ReadByte(buffer);
+ if (n == 0) {
+ switch (c) {
+ case 0: // end of line
+ x = 0;
+ pixel = &data->bitmap[--y * info->width];
+ break;
+ case 1: // end of bitmap
+ x = info->width;
+ y = 0;
+ pixel = NULL;
+ break;
+ case 2: // delta
+ x += ReadByte(buffer);
+ i = ReadByte(buffer);
+ if (x >= info->width || (y == 0 && i > 0)) return false;
+ y -= i;
+ pixel = &data->bitmap[y * info->width + x];
+ break;
+ default: // uncompressed
+ if ((x += c) > info->width) return false;
+ for (i = 0; i < c; i++) *pixel++ = ReadByte(buffer);
+ /* Padding for 16 bit align */
+ SkipBytes(buffer, c % 2);
+ break;
+ }
+ } else {
+ for (i = 0; i < n; i++) {
+ if (x >= info->width) return false;
+ *pixel++ = c;
+ x++;
+ }
+ }
+ }
+ return true;
+}
+
+/**
+ * Reads a 24 bpp uncompressed bitmap
+ */
+static inline bool BmpRead24(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
+{
+ uint x, y;
+ byte pad = GB(4 - info->width * 3, 0, 2);
+ byte *pixel_row;
+ for (y = info->height; y > 0; y--) {
+ pixel_row = &data->bitmap[(y - 1) * info->width * 3];
+ for (x = 0; x < info->width; x++) {
+ if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
+ *(pixel_row + 2) = ReadByte(buffer); // green
+ *(pixel_row + 1) = ReadByte(buffer); // blue
+ *pixel_row = ReadByte(buffer); // red
+ pixel_row += 3;
+ }
+ /* Padding for 32 bit align */
+ SkipBytes(buffer, pad);
+ }
+ return true;
+}
+
+/*
+ * Reads bitmap headers, and palette (if any)
+ */
+bool BmpReadHeader(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
+{
+ uint32 header_size;
+ assert(info != NULL);
+
+ /* Reading BMP header */
+ if (ReadWord(buffer) != 0x4D42) return false; // signature should be 'BM'
+ SkipBytes(buffer, 8); // skip file size and reserved
+ info->offset = ReadDword(buffer);
+
+ /* Reading info header */
+ header_size = ReadDword(buffer);
+ if (header_size < 12) return false; // info header should be at least 12 bytes long
+
+ info->os2_bmp = (header_size == 12); // OS/2 1.x or windows 2.x info header is 12 bytes long
+
+ if (info->os2_bmp) {
+ info->width = ReadWord(buffer);
+ info->height = ReadWord(buffer);
+ header_size -= 8;
+ } else {
+ info->width = ReadDword(buffer);
+ info->height = ReadDword(buffer);
+ header_size -= 12;
+ }
+
+ if (ReadWord(buffer) != 1) return false; // BMP can have only 1 plane
+
+ info->bpp = ReadWord(buffer);
+ if (info->bpp != 1 && info->bpp != 4 && info->bpp != 8 && info->bpp != 24) {
+ /* Only 1 bpp, 4 bpp, 8bpp and 24 bpp bitmaps are supported */
+ return false;
+ }
+
+ /* Reads compression method if available in info header*/
+ if ((header_size -= 4) >= 4) {
+ info->compression = ReadDword(buffer);
+ header_size -= 4;
+ }
+
+ /* Only 4-bit and 8-bit rle compression is supported */
+ if (info->compression > 2 || (info->compression > 0 && !(info->bpp == 4 || info->bpp == 8))) return false;
+
+ if (info->bpp <= 8) {
+ uint i;
+
+ /* Reads number of colors if available in info header */
+ if (header_size >= 16) {
+ SkipBytes(buffer, 12); // skip image size and resolution
+ info->palette_size = ReadDword(buffer); // number of colors in palette
+ SkipBytes(buffer, header_size - 16); // skip the end of info header
+ }
+ if (info->palette_size == 0) info->palette_size = 1 << info->bpp;
+
+ data->palette = calloc(info->palette_size, sizeof(*(data->palette)));
+ if (data->palette == NULL) return false;
+
+ for (i = 0; i < info->palette_size; i++) {
+ data->palette[i].b = ReadByte(buffer);
+ data->palette[i].g = ReadByte(buffer);
+ data->palette[i].r = ReadByte(buffer);
+ if (!info->os2_bmp) SkipBytes(buffer, 1); // unused
+ }
+ }
+
+ return buffer->real_pos <= info->offset;
+}
+
+/*
+ * Reads the bitmap
+ * 1 bpp and 4 bpp bitmaps are converted to 8 bpp bitmaps
+ */
+bool BmpReadBitmap(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
+{
+ assert(info != NULL && data != NULL);
+
+ data->bitmap = calloc(info->width * info->height, ((info->bpp == 24) ? 3 : 1) * sizeof(byte));
+ if (data->bitmap == NULL) return false;
+
+ /* Load image */
+ SetStreamOffset(buffer, info->offset);
+ switch (info->compression) {
+ case 0: // no compression
+ switch (info->bpp) {
+ case 1: return BmpRead1(buffer, info, data);
+ case 4: return BmpRead4(buffer, info, data);
+ case 8: return BmpRead8(buffer, info, data);
+ case 24: return BmpRead24(buffer, info, data);
+ default: NOT_REACHED(); return false;
+ }
+ case 1: return BmpRead8Rle(buffer, info, data); // 8-bit RLE compression
+ case 2: return BmpRead4Rle(buffer, info, data); // 4-bit RLE compression
+ default: NOT_REACHED(); return false;
+ }
+}
+
+void BmpDestroyData(BmpData *data)
+{
+ assert(data != NULL);
+ free(data->palette);
+ free(data->bitmap);
+}
diff --git a/src/bmp.h b/src/bmp.h
new file mode 100644
index 000000000..0587bab65
--- /dev/null
+++ b/src/bmp.h
@@ -0,0 +1,36 @@
+/* $Id$ */
+
+#ifndef BMP_H
+#define BMP_H
+
+typedef struct {
+ uint32 offset; ///< offset of bitmap data from .bmp file begining
+ uint32 width; ///< bitmap width
+ uint32 height; ///< bitmap height
+ bool os2_bmp; ///< true if OS/2 1.x or windows 2.x bitmap
+ uint16 bpp; ///< bits per pixel
+ uint32 compression; ///< compression method (0 = none, 1 = 8-bit RLE, 2 = 4-bit RLE)
+ uint32 palette_size; ///< number of colors in palette
+} BmpInfo;
+
+typedef struct {
+ Colour *palette;
+ byte *bitmap;
+} BmpData;
+
+#define BMP_BUFFER_SIZE 1024
+
+typedef struct {
+ byte data[BMP_BUFFER_SIZE];
+ int pos;
+ int read;
+ FILE *file;
+ uint real_pos;
+} BmpBuffer;
+
+void BmpInitializeBuffer(BmpBuffer *buffer, FILE *file);
+bool BmpReadHeader(BmpBuffer *buffer, BmpInfo *info, BmpData *data);
+bool BmpReadBitmap(BmpBuffer *buffer, BmpInfo *info, BmpData *data);
+void BmpDestroyData(BmpData *data);
+
+#endif /* BMP_H */
diff --git a/src/bridge.h b/src/bridge.h
new file mode 100644
index 000000000..7a63e28d7
--- /dev/null
+++ b/src/bridge.h
@@ -0,0 +1,32 @@
+/* $Id$ */
+
+/** @file bridge.h Header file for bridges */
+
+#ifndef BRIDGE_H
+#define BRIDGE_H
+
+enum {
+ MAX_BRIDGES = 13
+};
+
+/** Struct containing information about a single bridge type
+ */
+typedef struct Bridge {
+ Year avail_year; ///< the year in which the bridge becomes available
+ byte min_length; ///< the minimum length of the bridge (not counting start and end tile)
+ byte max_length; ///< the maximum length of the bridge (not counting start and end tile)
+ uint16 price; ///< the relative price of the bridge
+ uint16 speed; ///< maximum travel speed
+ PalSpriteID sprite; ///< the sprite which is used in the GUI (possibly with a recolor sprite)
+ StringID material; ///< the string that contains the bridge description
+ PalSpriteID **sprite_table; ///< table of sprites for drawing the bridge
+ byte flags; ///< bit 0 set: disable drawing of far pillars.
+} Bridge;
+
+extern const Bridge orig_bridge[MAX_BRIDGES];
+extern Bridge _bridge[MAX_BRIDGES];
+
+uint GetBridgeFoundation(Slope tileh, Axis axis);
+uint SetSpeedLimitOnBridge(Vehicle *);
+
+#endif /* BRIDGE_H */
diff --git a/src/bridge_gui.c b/src/bridge_gui.c
new file mode 100644
index 000000000..f426da18e
--- /dev/null
+++ b/src/bridge_gui.c
@@ -0,0 +1,167 @@
+/* $Id$ */
+
+/** @file bridge_gui.c Graphical user interface for bridge construction*/
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "table/strings.h"
+#include "functions.h"
+#include "map.h"
+#include "window.h"
+#include "gui.h"
+#include "viewport.h"
+#include "gfx.h"
+#include "command.h"
+#include "sound.h"
+#include "variables.h"
+#include "bridge.h"
+
+static struct BridgeData {
+ uint count;
+ TileIndex start_tile;
+ TileIndex end_tile;
+ byte type;
+ byte indexes[MAX_BRIDGES];
+ int32 costs[MAX_BRIDGES];
+} _bridgedata;
+
+void CcBuildBridge(bool success, TileIndex tile, uint32 p1, uint32 p2)
+{
+ if (success) SndPlayTileFx(SND_27_BLACKSMITH_ANVIL, tile);
+}
+
+static void BuildBridge(Window *w, int i)
+{
+ DeleteWindow(w);
+ DoCommandP(_bridgedata.end_tile, _bridgedata.start_tile,
+ _bridgedata.indexes[i] | (_bridgedata.type << 8), CcBuildBridge,
+ CMD_BUILD_BRIDGE | CMD_AUTO | CMD_MSG(STR_5015_CAN_T_BUILD_BRIDGE_HERE));
+}
+
+static void BuildBridgeWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ uint i;
+
+ DrawWindowWidgets(w);
+
+ for (i = 0; i < 4 && i + w->vscroll.pos < _bridgedata.count; i++) {
+ const Bridge *b = &_bridge[_bridgedata.indexes[i + w->vscroll.pos]];
+
+ SetDParam(2, _bridgedata.costs[i + w->vscroll.pos]);
+ SetDParam(1, b->speed);
+ SetDParam(0, b->material);
+ DrawSprite(b->sprite, 3, 15 + i * 22);
+
+ DrawString(44, 15 + i * 22 , STR_500D, 0);
+ }
+ } break;
+
+ case WE_KEYPRESS: {
+ uint i = e->we.keypress.keycode - '1';
+ if (i < 9 && i < _bridgedata.count) {
+ e->we.keypress.cont = false;
+ BuildBridge(w, i);
+ }
+
+ break;
+ }
+
+ case WE_CLICK:
+ if (e->we.click.widget == 2) {
+ uint ind = ((int)e->we.click.pt.y - 14) / 22;
+ if (ind < 4 && (ind += w->vscroll.pos) < _bridgedata.count)
+ BuildBridge(w, ind);
+ }
+ break;
+ }
+}
+
+static const Widget _build_bridge_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 199, 0, 13, STR_100D_SELECT_RAIL_BRIDGE, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_MATRIX, RESIZE_NONE, 7, 0, 187, 14, 101, 0x401, STR_101F_BRIDGE_SELECTION_CLICK},
+{ WWT_SCROLLBAR, RESIZE_NONE, 7, 188, 199, 14, 101, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _build_bridge_desc = {
+ WDP_AUTO, WDP_AUTO, 200, 102,
+ WC_BUILD_BRIDGE, WC_BUILD_TOOLBAR,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _build_bridge_widgets,
+ BuildBridgeWndProc
+};
+
+
+static const Widget _build_road_bridge_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 199, 0, 13, STR_1803_SELECT_ROAD_BRIDGE, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_MATRIX, RESIZE_NONE, 7, 0, 187, 14, 101, 0x401, STR_101F_BRIDGE_SELECTION_CLICK},
+{ WWT_SCROLLBAR, RESIZE_NONE, 7, 188, 199, 14, 101, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _build_road_bridge_desc = {
+ WDP_AUTO, WDP_AUTO, 200, 102,
+ WC_BUILD_BRIDGE, WC_BUILD_TOOLBAR,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _build_road_bridge_widgets,
+ BuildBridgeWndProc
+};
+
+
+void ShowBuildBridgeWindow(TileIndex start, TileIndex end, byte bridge_type)
+{
+ uint j = 0;
+ int32 ret;
+ StringID errmsg;
+
+ DeleteWindowById(WC_BUILD_BRIDGE, 0);
+
+ _bridgedata.type = bridge_type;
+ _bridgedata.start_tile = start;
+ _bridgedata.end_tile = end;
+
+ errmsg = INVALID_STRING_ID;
+
+ // only query bridge building possibility once, result is the same for all bridges!
+ // returns CMD_ERROR on failure, and price on success
+ ret = DoCommand(end, start, (bridge_type << 8), DC_AUTO | DC_QUERY_COST, CMD_BUILD_BRIDGE);
+
+ if (CmdFailed(ret)) {
+ errmsg = _error_message;
+ } else {
+ // check which bridges can be built
+ int bridge_len; // length of the middle parts of the bridge
+ int tot_bridgedata_len; // total length of bridge
+
+ // get absolute bridge length
+ bridge_len = GetBridgeLength(start, end);
+ tot_bridgedata_len = bridge_len + 2;
+
+ tot_bridgedata_len = CalcBridgeLenCostFactor(tot_bridgedata_len);
+
+ for (bridge_type = 0; bridge_type != MAX_BRIDGES; bridge_type++) { // loop for all bridgetypes
+ if (CheckBridge_Stuff(bridge_type, bridge_len)) {
+ const Bridge *b = &_bridge[bridge_type];
+ // bridge is accepted, add to list
+ // add to terraforming & bulldozing costs the cost of the bridge itself (not computed with DC_QUERY_COST)
+ _bridgedata.costs[j] = ret + (((int64)tot_bridgedata_len * _price.build_bridge * b->price) >> 8);
+ _bridgedata.indexes[j] = bridge_type;
+ j++;
+ }
+ }
+ }
+
+ _bridgedata.count = j;
+
+ if (j != 0) {
+ Window *w = AllocateWindowDesc((_bridgedata.type & 0x80) ? &_build_road_bridge_desc : &_build_bridge_desc);
+ w->vscroll.cap = 4;
+ w->vscroll.count = (byte)j;
+ } else {
+ ShowErrorMessage(errmsg, STR_5015_CAN_T_BUILD_BRIDGE_HERE, TileX(end) * TILE_SIZE, TileY(end) * TILE_SIZE);
+ }
+}
diff --git a/src/bridge_map.c b/src/bridge_map.c
new file mode 100644
index 000000000..8e2405ea3
--- /dev/null
+++ b/src/bridge_map.c
@@ -0,0 +1,51 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "bridge_map.h"
+#include "variables.h"
+
+
+TileIndex GetBridgeEnd(TileIndex tile, DiagDirection dir)
+{
+ TileIndexDiff delta = TileOffsByDiagDir(dir);
+
+ dir = ReverseDiagDir(dir);
+ do {
+ tile += delta;
+ } while (!IsBridgeTile(tile) || GetBridgeRampDirection(tile) != dir);
+
+ return tile;
+}
+
+
+TileIndex GetNorthernBridgeEnd(TileIndex t)
+{
+ return GetBridgeEnd(t, ReverseDiagDir(AxisToDiagDir(GetBridgeAxis(t))));
+}
+
+
+TileIndex GetSouthernBridgeEnd(TileIndex t)
+{
+ return GetBridgeEnd(t, AxisToDiagDir(GetBridgeAxis(t)));
+}
+
+
+TileIndex GetOtherBridgeEnd(TileIndex tile)
+{
+ assert(IsBridgeTile(tile));
+ return GetBridgeEnd(tile, GetBridgeRampDirection(tile));
+}
+
+uint GetBridgeHeight(TileIndex t)
+{
+ uint h;
+ uint tileh = GetTileSlope(t, &h);
+ uint f = GetBridgeFoundation(tileh, DiagDirToAxis(GetBridgeRampDirection(t)));
+
+ // one height level extra if the ramp is on a flat foundation
+ return
+ h + TILE_HEIGHT +
+ (IS_INT_INSIDE(f, 1, 15) ? TILE_HEIGHT : 0) +
+ (IsSteepSlope(tileh) ? TILE_HEIGHT : 0);
+}
diff --git a/src/bridge_map.h b/src/bridge_map.h
new file mode 100644
index 000000000..1cda0da9d
--- /dev/null
+++ b/src/bridge_map.h
@@ -0,0 +1,163 @@
+/* $Id$ */
+
+#ifndef BRIDGE_MAP_H
+#define BRIDGE_MAP_H
+
+#include "direction.h"
+#include "macros.h"
+#include "map.h"
+#include "rail.h"
+#include "road_map.h"
+#include "tile.h"
+
+
+void DrawBridgeMiddle(const TileInfo* ti); // XXX
+
+
+static inline bool IsBridge(TileIndex t)
+{
+ assert(IsTileType(t, MP_TUNNELBRIDGE));
+ return HASBIT(_m[t].m5, 7);
+}
+
+static inline bool IsBridgeTile(TileIndex t)
+{
+ return IsTileType(t, MP_TUNNELBRIDGE) && IsBridge(t);
+}
+
+
+static inline bool MayHaveBridgeAbove(TileIndex t)
+{
+ return
+ IsTileType(t, MP_CLEAR) ||
+ IsTileType(t, MP_RAILWAY) ||
+ IsTileType(t, MP_STREET) ||
+ IsTileType(t, MP_WATER) ||
+ IsTileType(t, MP_TUNNELBRIDGE) ||
+ IsTileType(t, MP_UNMOVABLE);
+}
+
+
+static inline bool IsBridgeAbove(TileIndex t)
+{
+ assert(MayHaveBridgeAbove(t));
+ return GB(_m[t].extra, 6, 2) != 0;
+}
+
+
+/**
+ * Determines the type of bridge on a tile
+ * @param tile The tile to analyze
+ * @return The bridge type
+ */
+static inline uint GetBridgeType(TileIndex t)
+{
+ assert(IsBridgeTile(t));
+ return GB(_m[t].m2, 4, 4);
+}
+
+
+/**
+ * Get the direction pointing onto the bridge
+ */
+static inline DiagDirection GetBridgeRampDirection(TileIndex t)
+{
+ assert(IsBridgeTile(t));
+ return (DiagDirection)GB(_m[t].m5, 0, 2);
+}
+
+
+static inline Axis GetBridgeAxis(TileIndex t)
+{
+ assert(IsBridgeAbove(t));
+ return (Axis)(GB(_m[t].extra, 6, 2) - 1);
+}
+
+
+static inline TransportType GetBridgeTransportType(TileIndex t)
+{
+ assert(IsBridgeTile(t));
+ return (TransportType)GB(_m[t].m5, 2, 2);
+}
+
+
+static inline bool HasBridgeSnowOrDesert(TileIndex t)
+{
+ assert(IsBridgeTile(t));
+ return HASBIT(_m[t].m4, 7);
+}
+
+
+static inline void SetBridgeSnowOrDesert(TileIndex t, bool snow_or_desert)
+{
+ assert(IsBridgeTile(t));
+ SB(_m[t].m4, 7, 1, snow_or_desert);
+}
+
+/**
+ * Finds the end of a bridge in the specified direction starting at a middle tile
+ */
+TileIndex GetBridgeEnd(TileIndex, DiagDirection);
+
+/**
+ * Finds the northern end of a bridge starting at a middle tile
+ */
+TileIndex GetNorthernBridgeEnd(TileIndex t);
+
+/**
+ * Finds the southern end of a bridge starting at a middle tile
+ */
+TileIndex GetSouthernBridgeEnd(TileIndex t);
+
+
+/**
+ * Starting at one bridge end finds the other bridge end
+ */
+TileIndex GetOtherBridgeEnd(TileIndex);
+
+uint GetBridgeHeight(TileIndex tile);
+uint GetBridgeFoundation(Slope tileh, Axis axis);
+
+static inline void ClearSingleBridgeMiddle(TileIndex t, Axis a)
+{
+ assert(MayHaveBridgeAbove(t));
+ CLRBIT(_m[t].extra, 6 + a);
+}
+
+
+static inline void ClearBridgeMiddle(TileIndex t)
+{
+ ClearSingleBridgeMiddle(t, AXIS_X);
+ ClearSingleBridgeMiddle(t, AXIS_Y);
+}
+
+static inline void SetBridgeMiddle(TileIndex t, Axis a)
+{
+ assert(MayHaveBridgeAbove(t));
+ SETBIT(_m[t].extra, 6 + a);
+}
+
+
+static inline void MakeBridgeRamp(TileIndex t, Owner o, uint bridgetype, DiagDirection d, TransportType tt)
+{
+ SetTileType(t, MP_TUNNELBRIDGE);
+ SetTileOwner(t, o);
+ _m[t].m2 = bridgetype << 4;
+ _m[t].m4 = 0;
+ _m[t].m5 = 1 << 7 | tt << 2 | d;
+}
+
+static inline void MakeRoadBridgeRamp(TileIndex t, Owner o, uint bridgetype, DiagDirection d)
+{
+ MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_ROAD);
+ _m[t].m3 = 0;
+}
+
+static inline void MakeRailBridgeRamp(TileIndex t, Owner o, uint bridgetype, DiagDirection d, RailType r)
+{
+ MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_RAIL);
+ _m[t].m3 = r;
+}
+
+
+#endif /* BRIDGE_MAP_H */
diff --git a/src/build_vehicle_gui.c b/src/build_vehicle_gui.c
new file mode 100644
index 000000000..b293b516c
--- /dev/null
+++ b/src/build_vehicle_gui.c
@@ -0,0 +1,492 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "aircraft.h"
+#include "debug.h"
+#include "functions.h"
+#include "table/sprites.h"
+#include "table/strings.h"
+#include "window.h"
+#include "gui.h"
+#include "vehicle.h"
+#include "gfx.h"
+#include "station.h"
+#include "command.h"
+#include "engine.h"
+#include "player.h"
+#include "depot.h"
+#include "airport.h"
+#include "vehicle_gui.h"
+#include "newgrf_engine.h"
+#include "date.h"
+#include "strings.h"
+
+
+enum BuildVehicleWidgets {
+ BUILD_VEHICLE_WIDGET_CLOSEBOX = 0,
+ BUILD_VEHICLE_WIDGET_CAPTION,
+ BUILD_VEHICLE_WIDGET_SORT_ASSENDING_DESCENDING,
+ BUILD_VEHICLE_WIDGET_SORT_TEXT,
+ BUILD_VEHICLE_WIDGET_SORT_DROPDOWN,
+ BUILD_VEHICLE_WIDGET_LIST,
+ BUILD_VEHICLE_WIDGET_SCROLLBAR,
+ BUILD_VEHICLE_WIDGET_PANEL,
+ BUILD_VEHICLE_WIDGET_BUILD,
+ BUILD_VEHICLE_WIDGET_RENAME,
+ BUILD_VEHICLE_WIDGET_RESIZE,
+};
+
+static const Widget _build_vehicle_widgets[] = {
+ { WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW },
+ { WWT_CAPTION, RESIZE_NONE, 14, 11, 239, 0, 13, STR_A005_NEW_AIRCRAFT, STR_018C_WINDOW_TITLE_DRAG_THIS },
+ { WWT_PUSHTXTBTN, RESIZE_NONE, 14, 0, 80, 14, 25, STR_SORT_BY, STR_SORT_ORDER_TIP},
+ { WWT_PANEL, RESIZE_NONE, 14, 81, 227, 14, 25, 0x0, STR_SORT_CRITERIA_TIP},
+ { WWT_TEXTBTN, RESIZE_NONE, 14, 228, 239, 14, 25, STR_0225, STR_SORT_CRITERIA_TIP},
+ { WWT_MATRIX, RESIZE_BOTTOM, 14, 0, 227, 26, 121, 0x401, STR_A025_AIRCRAFT_SELECTION_LIST },
+ { WWT_SCROLLBAR, RESIZE_BOTTOM, 14, 228, 239, 26, 121, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST },
+ { WWT_PANEL, RESIZE_TB, 14, 0, 239, 122, 213, 0x0, STR_NULL },
+
+ { WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 114, 214, 225, STR_A006_BUILD_AIRCRAFT, STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT },
+ { WWT_PUSHTXTBTN, RESIZE_TB, 14, 115, 227, 214, 225, STR_A037_RENAME, STR_A038_RENAME_AIRCRAFT_TYPE },
+ { WWT_RESIZEBOX, RESIZE_TB, 14, 228, 239, 214, 225, 0x0, STR_RESIZE_BUTTON },
+ { WIDGETS_END},
+};
+
+static bool _internal_sort_order; // descending/ascending
+static byte _last_sort_criteria = 0;
+static bool _last_sort_order = false;
+
+static int CDECL EngineNumberSorter(const void *a, const void *b)
+{
+ const EngineID va = *(const EngineID*)a;
+ const EngineID vb = *(const EngineID*)b;
+ int r = va - vb;
+
+ return _internal_sort_order ? -r : r;
+}
+
+static int CDECL EngineIntroDateSorter(const void *a, const void *b)
+{
+ const int va = GetEngine(*(const EngineID*)a)->intro_date;
+ const int vb = GetEngine(*(const EngineID*)b)->intro_date;
+ const int r = va - vb;
+
+ if (r == 0) {
+ /* Use EngineID to sort instead since we want consistent sorting */
+ return EngineNumberSorter(a, b);
+ }
+ return _internal_sort_order ? -r : r;
+}
+
+static int CDECL EngineNameSorter(const void *a, const void *b)
+{
+ static EngineID last_engine[2] = { INVALID_ENGINE, INVALID_ENGINE };
+ static char last_name[2][64] = { "\0", "\0" };
+
+ const EngineID va = *(const EngineID*)a;
+ const EngineID vb = *(const EngineID*)b;
+ int r;
+
+ if (va != last_engine[0]) {
+ last_engine[0] = va;
+ GetString(last_name[0], GetCustomEngineName(va), lastof(last_name[0]));
+ }
+
+ if (vb != last_engine[1]) {
+ last_engine[1] = vb;
+ GetString(last_name[1], GetCustomEngineName(vb), lastof(last_name[1]));
+ }
+
+ r = strcmp(last_name[0], last_name[1]); // sort by name
+
+ if (r == 0) {
+ /* Use EngineID to sort instead since we want consistent sorting */
+ return EngineNumberSorter(a, b);
+ }
+ return _internal_sort_order ? -r : r;
+}
+
+static int CDECL EngineReliabilitySorter(const void *a, const void *b)
+{
+ const int va = GetEngine(*(const EngineID*)a)->reliability;
+ const int vb = GetEngine(*(const EngineID*)b)->reliability;
+ const int r = va - vb;
+
+ if (r == 0) {
+ /* Use EngineID to sort instead since we want consistent sorting */
+ return EngineNumberSorter(a, b);
+ }
+ return _internal_sort_order ? -r : r;
+}
+
+/* Aircraft sorting functions */
+
+static int CDECL AircraftEngineCostSorter(const void *a, const void *b)
+{
+ const int va = AircraftVehInfo(*(const EngineID*)a)->base_cost;
+ const int vb = AircraftVehInfo(*(const EngineID*)b)->base_cost;
+ int r = va - vb;
+
+ return _internal_sort_order ? -r : r;
+}
+
+static int CDECL AircraftEngineSpeedSorter(const void *a, const void *b)
+{
+ const int va = AircraftVehInfo(*(const EngineID*)a)->max_speed;
+ const int vb = AircraftVehInfo(*(const EngineID*)b)->max_speed;
+ const int r = va - vb;
+
+ if (r == 0) {
+ /* Use EngineID to sort instead since we want consistent sorting */
+ return EngineNumberSorter(a, b);
+ }
+ return _internal_sort_order ? -r : r;
+}
+
+static int CDECL AircraftEngineRunningCostSorter(const void *a, const void *b)
+{
+ const int va = AircraftVehInfo(*(const EngineID*)a)->running_cost;
+ const int vb = AircraftVehInfo(*(const EngineID*)b)->running_cost;
+ const int r = va - vb;
+
+ if (r == 0) {
+ /* Use EngineID to sort instead since we want consistent sorting */
+ return EngineNumberSorter(a, b);
+ }
+ return _internal_sort_order ? -r : r;
+}
+
+static int CDECL AircraftEngineCargoSorter(const void *a, const void *b)
+{
+ const int va = AircraftVehInfo(*(const EngineID*)a)->passenger_capacity;
+ const int vb = AircraftVehInfo(*(const EngineID*)b)->passenger_capacity;
+ const int r = va - vb;
+
+ if (r == 0) {
+ /* Use EngineID to sort instead since we want consistent sorting */
+ return EngineNumberSorter(a, b);
+ }
+ return _internal_sort_order ? -r : r;
+}
+
+static EngList_SortTypeFunction * const _aircraft_sorter[] = {
+ &EngineNumberSorter,
+ &AircraftEngineCostSorter,
+ &AircraftEngineSpeedSorter,
+ &EngineIntroDateSorter,
+ &EngineNameSorter,
+ &AircraftEngineRunningCostSorter,
+ &EngineReliabilitySorter,
+ &AircraftEngineCargoSorter,
+};
+
+static const StringID _aircraft_sort_listing[] = {
+ STR_ENGINE_SORT_ENGINE_ID,
+ STR_ENGINE_SORT_COST,
+ STR_SORT_BY_MAX_SPEED,
+ STR_ENGINE_SORT_INTRO_DATE,
+ STR_SORT_BY_DROPDOWN_NAME,
+ STR_ENGINE_SORT_RUNNING_COST,
+ STR_SORT_BY_RELIABILITY,
+ STR_ENGINE_SORT_CARGO_CAPACITY,
+ INVALID_STRING_ID
+};
+
+
+/**
+* Draw the purchase info details of an aircraft at a given location.
+ * @param x,y location where to draw the info
+ * @param engine_number the engine of which to draw the info of
+ */
+void DrawAircraftPurchaseInfo(int x, int y, uint w, EngineID engine_number)
+{
+ const AircraftVehicleInfo *avi = AircraftVehInfo(engine_number);
+ const Engine *e = GetEngine(engine_number);
+ CargoID cargo;
+ YearMonthDay ymd;
+ ConvertDateToYMD(e->intro_date, &ymd);
+
+ /* Purchase cost - Max speed */
+ SetDParam(0, avi->base_cost * (_price.aircraft_base>>3)>>5);
+ SetDParam(1, avi->max_speed * 128 / 10);
+ DrawString(x, y, STR_PURCHASE_INFO_COST_SPEED, 0);
+ y += 10;
+
+ /* Cargo capacity */
+ cargo = FindFirstRefittableCargo(engine_number);
+ if (cargo == CT_INVALID || cargo == CT_PASSENGERS) {
+ SetDParam(0, avi->passenger_capacity);
+ SetDParam(1, avi->mail_capacity);
+ DrawString(x, y, STR_PURCHASE_INFO_AIRCRAFT_CAPACITY, 0);
+ } else {
+ /* Note, if the default capacity is selected by the refit capacity
+ * callback, then the capacity shown is likely to be incorrect. */
+ SetDParam(0, cargo);
+ SetDParam(1, AircraftDefaultCargoCapacity(cargo, engine_number));
+ SetDParam(2, STR_9842_REFITTABLE);
+ DrawString(x, y, STR_PURCHASE_INFO_CAPACITY, 0);
+ }
+ y += 10;
+
+ /* Running cost */
+ SetDParam(0, avi->running_cost * _price.aircraft_running >> 8);
+ DrawString(x, y, STR_PURCHASE_INFO_RUNNINGCOST, 0);
+ y += 10;
+
+ /* Design date - Life length */
+ SetDParam(0, ymd.year);
+ SetDParam(1, e->lifelength);
+ DrawString(x, y, STR_PURCHASE_INFO_DESIGNED_LIFE, 0);
+ y += 10;
+
+ /* Reliability */
+ SetDParam(0, e->reliability * 100 >> 16);
+ DrawString(x, y, STR_PURCHASE_INFO_RELIABILITY, 0);
+ y += 10;
+
+ /* Additional text from NewGRF */
+ y += ShowAdditionalText(x, y, w, engine_number);
+ y += ShowRefitOptionsList(x, y, w, engine_number);
+}
+
+void DrawAircraftImage(const Vehicle *v, int x, int y, VehicleID selection)
+{
+ PalSpriteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
+ DrawSprite(GetAircraftImage(v, DIR_W) | pal, x + 25, y + 10);
+ if (v->subtype == 0) {
+ SpriteID rotor_sprite = GetCustomRotorSprite(v, true);
+ if (rotor_sprite == 0) rotor_sprite = SPR_ROTOR_STOPPED;
+ DrawSprite(rotor_sprite, x + 25, y + 5);
+ }
+ if (v->index == selection) {
+ DrawFrameRect(x - 1, y - 1, x + 58, y + 21, 0xF, FR_BORDERONLY);
+ }
+}
+
+void CcBuildAircraft(bool success, TileIndex tile, uint32 p1, uint32 p2)
+{
+ if (success) {
+ const Vehicle *v = GetVehicle(_new_vehicle_id);
+
+ if (v->tile == _backup_orders_tile) {
+ _backup_orders_tile = 0;
+ RestoreVehicleOrders(v, _backup_orders_data);
+ }
+ ShowAircraftViewWindow(v);
+ }
+}
+
+static void GenerateBuildAircraftList(Window *w)
+{
+ EngineID eid, sel_id;
+ buildvehicle_d *bv = &WP(w, buildvehicle_d);
+
+ EngList_RemoveAll(&bv->eng_list);
+
+ /* Make list of all available planes.
+ * Also check to see if the previously selected plane is still available,
+ * and if not, reset selection to INVALID_ENGINE. This could be the case
+ * when planes become obsolete and are removed */
+ sel_id = INVALID_ENGINE;
+ for (eid = AIRCRAFT_ENGINES_INDEX; eid < AIRCRAFT_ENGINES_INDEX + NUM_AIRCRAFT_ENGINES; eid++) {
+ if (IsEngineBuildable(eid, VEH_Aircraft, _local_player)) {
+ const AircraftVehicleInfo *avi = AircraftVehInfo(eid);
+ switch (bv->filter.acc_planes) {
+ case HELICOPTERS_ONLY:
+ if (avi->subtype != 0) continue; // if not helicopter
+ break;
+
+ case AIRCRAFT_ONLY:
+ if (avi->subtype == 0) continue; // if helicopter
+ break;
+
+ case ALL: break;
+ }
+ EngList_Add(&bv->eng_list, eid);
+
+ if (eid == bv->sel_engine) sel_id = eid;
+ }
+ }
+
+ bv->sel_engine = sel_id;
+}
+
+static void GenerateBuildList(Window *w)
+{
+ buildvehicle_d *bv = &WP(w, buildvehicle_d);
+
+ switch (bv->vehicle_type) {
+ case VEH_Aircraft:
+ GenerateBuildAircraftList(w);
+ _internal_sort_order = bv->descending_sort_order;
+ EngList_Sort(&bv->eng_list, _aircraft_sorter[bv->sort_criteria]);
+ break;
+
+ default: NOT_REACHED();
+ }
+}
+
+static void DrawBuildAircraftWindow(Window *w)
+{
+ const buildvehicle_d *bv = &WP(w, buildvehicle_d);
+
+ SetWindowWidgetDisabledState(w, BUILD_VEHICLE_WIDGET_BUILD, w->window_number == 0);
+
+ SetVScrollCount(w, EngList_Count(&bv->eng_list));
+ DrawWindowWidgets(w);
+
+ {
+ int x = 2;
+ int y = 27;
+ EngineID selected_id = bv->sel_engine;
+ EngineID eid = w->vscroll.pos;
+ uint16 max = min(w->vscroll.pos + w->vscroll.cap, EngList_Count(&bv->eng_list));
+
+ for (; eid < max; eid++) {
+ const EngineID engine = bv->eng_list[eid];
+
+ DrawString(x + 62, y + 7, GetCustomEngineName(engine), engine == selected_id ? 0xC : 0x10);
+ DrawAircraftEngine(x + 29, y + 10, engine, GetEnginePalette(engine, _local_player));
+ y += 24;
+ }
+
+ if (selected_id != INVALID_ENGINE) {
+ const Widget *wi = &w->widget[BUILD_VEHICLE_WIDGET_PANEL];
+ DrawAircraftPurchaseInfo(x, wi->top + 1, wi->right - wi->left - 2, selected_id);
+ }
+ }
+ DrawString(85, 15, _aircraft_sort_listing[bv->sort_criteria], 0x10);
+ DoDrawString(bv->descending_sort_order ? DOWNARROW : UPARROW, 69, 15, 0x10);
+}
+
+static void BuildAircraftClickEvent(Window *w, WindowEvent *e)
+{
+ buildvehicle_d *bv = &WP(w, buildvehicle_d);
+
+ switch (e->we.click.widget) {
+ case BUILD_VEHICLE_WIDGET_SORT_ASSENDING_DESCENDING:
+ bv->descending_sort_order ^= true;
+ _last_sort_order = bv->descending_sort_order;
+ GenerateBuildList(w);
+ SetWindowDirty(w);
+ break;
+
+ case BUILD_VEHICLE_WIDGET_LIST: {
+ uint i = (e->we.click.pt.y - 26) / 24 + w->vscroll.pos;
+ uint num_items = EngList_Count(&bv->eng_list);
+ bv->sel_engine = (i < num_items) ? bv->eng_list[i] : INVALID_ENGINE;
+ SetWindowDirty(w);
+ break;
+ }
+
+ case BUILD_VEHICLE_WIDGET_SORT_TEXT: case BUILD_VEHICLE_WIDGET_SORT_DROPDOWN:/* Select sorting criteria dropdown menu */
+ ShowDropDownMenu(w, _aircraft_sort_listing, bv->sort_criteria, BUILD_VEHICLE_WIDGET_SORT_DROPDOWN, 0, 0);
+ return;
+
+ case BUILD_VEHICLE_WIDGET_BUILD: {
+ EngineID sel_eng = bv->sel_engine;
+ if (sel_eng != INVALID_ENGINE) {
+ DoCommandP(w->window_number, sel_eng, 0, CcBuildAircraft, CMD_BUILD_AIRCRAFT | CMD_MSG(STR_A008_CAN_T_BUILD_AIRCRAFT));
+ }
+ break;
+ }
+
+ case BUILD_VEHICLE_WIDGET_RENAME: {
+ EngineID sel_eng = bv->sel_engine;
+ if (sel_eng != INVALID_ENGINE) {
+ bv->rename_engine = sel_eng;
+ ShowQueryString(GetCustomEngineName(sel_eng), STR_A039_RENAME_AIRCRAFT_TYPE, 31, 160, w, CS_ALPHANUMERAL);
+ }
+ break;
+ }
+ }
+}
+
+static void NewAircraftWndProc(Window *w, WindowEvent *e)
+{
+ buildvehicle_d *bv = &WP(w, buildvehicle_d);
+
+ switch (e->event) {
+ case WE_INVALIDATE_DATA:
+ GenerateBuildList(w);
+ break;
+
+ case WE_DESTROY:
+ EngList_Destroy(&bv->eng_list);
+ break;
+
+ case WE_PAINT:
+ DrawBuildAircraftWindow(w);
+ break;
+
+ case WE_CLICK:
+ BuildAircraftClickEvent(w, e);
+ break;
+
+ case WE_ON_EDIT_TEXT: {
+ if (e->we.edittext.str[0] != '\0') {
+ _cmd_text = e->we.edittext.str;
+ DoCommandP(0, bv->rename_engine, 0, NULL, CMD_RENAME_ENGINE | CMD_MSG(STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE));
+ }
+ break;
+ }
+
+ case WE_DROPDOWN_SELECT: /* we have selected a dropdown item in the list */
+ if (bv->sort_criteria != e->we.dropdown.index) {
+ bv->sort_criteria = _last_sort_criteria = e->we.dropdown.index;
+ GenerateBuildList(w);
+ }
+ SetWindowDirty(w);
+ break;
+
+ case WE_RESIZE:
+ w->vscroll.cap += e->we.sizing.diff.y / 24;
+ w->widget[BUILD_VEHICLE_WIDGET_LIST].data = (w->vscroll.cap << 8) + 1;
+ break;
+ }
+}
+
+static const WindowDesc _build_vehicle_desc = {
+ WDP_AUTO, WDP_AUTO, 240, 226,
+ WC_BUILD_VEHICLE,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
+ _build_vehicle_widgets,
+ NewAircraftWndProc
+};
+
+void ShowBuildVehicleWindow(TileIndex tile, byte type)
+{
+ buildvehicle_d *bv;
+ Window *w;
+
+ DeleteWindowById(WC_BUILD_VEHICLE, tile);
+ w = AllocateWindowDescFront(&_build_vehicle_desc, tile);
+ if (w == NULL) return;
+
+ w->caption_color = (tile != 0) ? GetTileOwner(tile) : _local_player;
+ w->resize.step_height = GetVehicleListHeight(type);
+ w->vscroll.cap = 4;
+ w->widget[BUILD_VEHICLE_WIDGET_LIST].data = (w->vscroll.cap << 8) + 1;
+
+ bv = &WP(w, buildvehicle_d);
+ EngList_Create(&bv->eng_list);
+ bv->sel_engine = INVALID_ENGINE;
+ bv->sort_criteria = _last_sort_criteria;
+ bv->descending_sort_order = _last_sort_order;
+
+ bv->vehicle_type = type;
+
+ switch (type) {
+ case VEH_Aircraft: {
+ byte acc_planes = (tile == 0) ? ALL : GetAirport(GetStationByTile(tile)->airport_type)->acc_planes;
+ bv->filter.acc_planes = acc_planes;
+ break;
+ }
+ default: NOT_REACHED();
+ }
+
+ GenerateBuildList(w);
+ /* Select the first plane in the list as default when opening the window */
+ if (EngList_Count(&bv->eng_list) > 0) bv->sel_engine = bv->eng_list[0];
+}
diff --git a/src/callback_table.c b/src/callback_table.c
new file mode 100644
index 000000000..65e140742
--- /dev/null
+++ b/src/callback_table.c
@@ -0,0 +1,91 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "callback_table.h"
+#include "functions.h"
+
+// If you add a callback for DoCommandP, also add the callback in here
+// see below for the full list!
+// If you don't do it, it won't work across the network!!
+
+/* aircraft_gui.c */
+CommandCallback CcBuildAircraft;
+CommandCallback CcCloneAircraft;
+
+/* airport_gui.c */
+CommandCallback CcBuildAirport;
+
+/* bridge_gui.c */
+CommandCallback CcBuildBridge;
+
+/* dock_gui.c */
+CommandCallback CcBuildDocks;
+CommandCallback CcBuildCanal;
+
+/* depot_gui.c */
+CommandCallback CcCloneVehicle;
+
+/* main_gui.c */
+CommandCallback CcPlaySound10;
+CommandCallback CcPlaceSign;
+CommandCallback CcTerraform;
+CommandCallback CcBuildTown;
+
+/* rail_gui.c */
+CommandCallback CcPlaySound1E;
+CommandCallback CcRailDepot;
+CommandCallback CcStation;
+CommandCallback CcBuildRailTunnel;
+
+/* road_gui.c */
+CommandCallback CcPlaySound1D;
+CommandCallback CcBuildRoadTunnel;
+CommandCallback CcRoadDepot;
+
+/* roadveh_gui.c */
+CommandCallback CcBuildRoadVeh;
+CommandCallback CcCloneRoadVeh;
+
+/* ship_gui.c */
+CommandCallback CcBuildShip;
+CommandCallback CcCloneShip;
+
+/* train_gui.c */
+CommandCallback CcBuildWagon;
+CommandCallback CcBuildLoco;
+CommandCallback CcCloneTrain;
+
+CommandCallback CcAI;
+
+CommandCallback *_callback_table[] = {
+ /* 0x00 */ NULL,
+ /* 0x01 */ CcBuildAircraft,
+ /* 0x02 */ CcBuildAirport,
+ /* 0x03 */ CcBuildBridge,
+ /* 0x04 */ CcBuildCanal,
+ /* 0x05 */ CcBuildDocks,
+ /* 0x06 */ CcBuildLoco,
+ /* 0x07 */ CcBuildRoadVeh,
+ /* 0x08 */ CcBuildShip,
+ /* 0x09 */ CcBuildTown,
+ /* 0x0A */ CcBuildRoadTunnel,
+ /* 0x0B */ CcBuildRailTunnel,
+ /* 0x0C */ CcBuildWagon,
+ /* 0x0D */ CcRoadDepot,
+ /* 0x0E */ CcRailDepot,
+ /* 0x0F */ CcPlaceSign,
+ /* 0x10 */ CcPlaySound10,
+ /* 0x11 */ CcPlaySound1D,
+ /* 0x12 */ CcPlaySound1E,
+ /* 0x13 */ CcStation,
+ /* 0x14 */ CcTerraform,
+ /* 0x15 */ CcCloneAircraft,
+ /* 0x16 */ CcCloneRoadVeh,
+ /* 0x17 */ CcCloneShip,
+ /* 0x18 */ CcCloneTrain,
+ /* 0x19 */ CcAI,
+ /* 0x1A */ CcCloneVehicle
+};
+
+const int _callback_table_count = lengthof(_callback_table);
diff --git a/src/callback_table.h b/src/callback_table.h
new file mode 100644
index 000000000..f555fcf60
--- /dev/null
+++ b/src/callback_table.h
@@ -0,0 +1,11 @@
+/* $Id$ */
+
+#ifndef CALLBACK_TABLE_H
+#define CALLBACK_TABLE_H
+
+#include "command.h"
+
+extern CommandCallback *_callback_table[];
+extern const int _callback_table_count;
+
+#endif /* CALLBACK_TABLE_H */
diff --git a/src/clear_cmd.c b/src/clear_cmd.c
new file mode 100644
index 000000000..4d1a78ba9
--- /dev/null
+++ b/src/clear_cmd.c
@@ -0,0 +1,803 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "clear_map.h"
+#include "rail_map.h"
+#include "table/strings.h"
+#include "functions.h"
+#include "map.h"
+#include "player.h"
+#include "tile.h"
+#include "viewport.h"
+#include "command.h"
+#include "tunnel_map.h"
+#include "bridge_map.h"
+#include "variables.h"
+#include "table/sprites.h"
+#include "unmovable_map.h"
+#include "genworld.h"
+#include "industry.h"
+
+typedef struct TerraformerHeightMod {
+ TileIndex tile;
+ byte height;
+} TerraformerHeightMod;
+
+typedef struct TerraformerState {
+ int height[4];
+ uint32 flags;
+
+ int direction;
+ int modheight_count;
+ int tile_table_count;
+
+ int32 cost;
+
+ TileIndex *tile_table;
+ TerraformerHeightMod *modheight;
+
+} TerraformerState;
+
+static int TerraformAllowTileProcess(TerraformerState *ts, TileIndex tile)
+{
+ TileIndex *t;
+ int count;
+
+ if (TileX(tile) == MapMaxX() || TileY(tile) == MapMaxY()) return -1;
+
+ t = ts->tile_table;
+ for (count = ts->tile_table_count; count != 0; count--, t++) {
+ if (*t == tile) return 0;
+ }
+
+ return 1;
+}
+
+static int TerraformGetHeightOfTile(TerraformerState *ts, TileIndex tile)
+{
+ TerraformerHeightMod *mod = ts->modheight;
+ int count;
+
+ for (count = ts->modheight_count; count != 0; count--, mod++) {
+ if (mod->tile == tile) return mod->height;
+ }
+
+ return TileHeight(tile);
+}
+
+static void TerraformAddDirtyTile(TerraformerState *ts, TileIndex tile)
+{
+ int count;
+ TileIndex *t;
+
+ count = ts->tile_table_count;
+
+ if (count >= 625) return;
+
+ for (t = ts->tile_table; count != 0; count--,t++) {
+ if (*t == tile) return;
+ }
+
+ ts->tile_table[ts->tile_table_count++] = tile;
+}
+
+static void TerraformAddDirtyTileAround(TerraformerState *ts, TileIndex tile)
+{
+ TerraformAddDirtyTile(ts, tile + TileDiffXY( 0, -1));
+ TerraformAddDirtyTile(ts, tile + TileDiffXY(-1, -1));
+ TerraformAddDirtyTile(ts, tile + TileDiffXY(-1, 0));
+ TerraformAddDirtyTile(ts, tile);
+}
+
+static int TerraformProc(TerraformerState *ts, TileIndex tile, int mode)
+{
+ int r;
+ int32 ret;
+
+ assert(tile < MapSize());
+
+ r = TerraformAllowTileProcess(ts, tile);
+ if (r <= 0) return r;
+
+ if (IsTileType(tile, MP_RAILWAY)) {
+ static const TrackBits safe_track[] = { TRACK_BIT_LOWER, TRACK_BIT_LEFT, TRACK_BIT_UPPER, TRACK_BIT_RIGHT };
+ static const Slope unsafe_slope[] = { SLOPE_S, SLOPE_W, SLOPE_N, SLOPE_E };
+
+ Slope tileh;
+ uint z;
+
+ // Nothing could be built at the steep slope - this avoids a bug
+ // when you have a single diagonal track in one corner on a
+ // basement and then you raise/lower the other corner.
+ tileh = GetTileSlope(tile, &z);
+ if (tileh == unsafe_slope[mode] ||
+ tileh == ComplementSlope(unsafe_slope[mode])) {
+ _terraform_err_tile = tile;
+ _error_message = STR_1008_MUST_REMOVE_RAILROAD_TRACK;
+ return -1;
+ }
+
+ // If we have a single diagonal track there, the other side of
+ // tile can be terraformed.
+ if (IsPlainRailTile(tile) && GetTrackBits(tile) == safe_track[mode]) {
+ /* If terraforming downwards prevent damaging a potential tunnel below.
+ * This check is only necessary for flat tiles, because if the tile is
+ * non-flat, then the corner opposing the rail is raised. Only this corner
+ * can be lowered and this is a safe action
+ */
+ if (tileh == SLOPE_FLAT &&
+ ts->direction == -1 &&
+ IsTunnelInWay(tile, z - TILE_HEIGHT)) {
+ _terraform_err_tile = tile;
+ _error_message = STR_1002_EXCAVATION_WOULD_DAMAGE;
+ return -1;
+ }
+ return 0;
+ }
+ }
+
+ ret = DoCommand(tile, 0,0, ts->flags & ~DC_EXEC, CMD_LANDSCAPE_CLEAR);
+
+ if (CmdFailed(ret)) {
+ _terraform_err_tile = tile;
+ return -1;
+ }
+
+ ts->cost += ret;
+
+ if (ts->tile_table_count >= 625) return -1;
+ ts->tile_table[ts->tile_table_count++] = tile;
+
+ return 0;
+}
+
+static bool TerraformTileHeight(TerraformerState *ts, TileIndex tile, int height)
+{
+ int nh;
+ TerraformerHeightMod *mod;
+ int count;
+
+ assert(tile < MapSize());
+
+ if (height < 0) {
+ _error_message = STR_1003_ALREADY_AT_SEA_LEVEL;
+ return false;
+ }
+
+ _error_message = STR_1004_TOO_HIGH;
+
+ if (height > 15) return false;
+
+ nh = TerraformGetHeightOfTile(ts, tile);
+ if (nh < 0 || height == nh) return false;
+
+ if (TerraformProc(ts, tile, 0) < 0) return false;
+ if (TerraformProc(ts, tile + TileDiffXY( 0, -1), 1) < 0) return false;
+ if (TerraformProc(ts, tile + TileDiffXY(-1, -1), 2) < 0) return false;
+ if (TerraformProc(ts, tile + TileDiffXY(-1, 0), 3) < 0) return false;
+
+ mod = ts->modheight;
+ count = ts->modheight_count;
+
+ for (;;) {
+ if (count == 0) {
+ if (ts->modheight_count >= 576) return false;
+ ts->modheight_count++;
+ break;
+ }
+ if (mod->tile == tile) break;
+ mod++;
+ count--;
+ }
+
+ mod->tile = tile;
+ mod->height = (byte)height;
+
+ ts->cost += _price.terraform;
+
+ {
+ int direction = ts->direction, r;
+ const TileIndexDiffC *ttm;
+
+ static const TileIndexDiffC _terraform_tilepos[] = {
+ { 1, 0},
+ {-2, 0},
+ { 1, 1},
+ { 0, -2}
+ };
+
+ for (ttm = _terraform_tilepos; ttm != endof(_terraform_tilepos); ttm++) {
+ tile += ToTileIndexDiff(*ttm);
+
+ r = TerraformGetHeightOfTile(ts, tile);
+ if (r != height && r-direction != height && r+direction != height) {
+ if (!TerraformTileHeight(ts, tile, r+direction))
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+/** Terraform land
+ * @param tile tile to terraform
+ * @param p1 corners to terraform.
+ * @param p2 direction; eg up or down
+ */
+int32 CmdTerraformLand(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ TerraformerState ts;
+ TileIndex t;
+ int direction;
+
+ TerraformerHeightMod modheight_data[576];
+ TileIndex tile_table_data[625];
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ _terraform_err_tile = 0;
+
+ ts.direction = direction = p2 ? 1 : -1;
+ ts.flags = flags;
+ ts.modheight_count = ts.tile_table_count = 0;
+ ts.cost = 0;
+ ts.modheight = modheight_data;
+ ts.tile_table = tile_table_data;
+
+ /* Make an extra check for map-bounds cause we add tiles to the originating tile */
+ if (tile + TileDiffXY(1, 1) >= MapSize()) return CMD_ERROR;
+
+ if (p1 & 1) {
+ t = tile + TileDiffXY(1, 0);
+ if (!TerraformTileHeight(&ts, t, TileHeight(t) + direction)) {
+ return CMD_ERROR;
+ }
+ }
+
+ if (p1 & 2) {
+ t = tile + TileDiffXY(1, 1);
+ if (!TerraformTileHeight(&ts, t, TileHeight(t) + direction)) {
+ return CMD_ERROR;
+ }
+ }
+
+ if (p1 & 4) {
+ t = tile + TileDiffXY(0, 1);
+ if (!TerraformTileHeight(&ts, t, TileHeight(t) + direction)) {
+ return CMD_ERROR;
+ }
+ }
+
+ if (p1 & 8) {
+ t = tile + TileDiffXY(0, 0);
+ if (!TerraformTileHeight(&ts, t, TileHeight(t) + direction)) {
+ return CMD_ERROR;
+ }
+ }
+
+ {
+ /* Check if tunnel would take damage */
+ int count;
+ TileIndex *ti = ts.tile_table;
+
+ for (count = ts.tile_table_count; count != 0; count--, ti++) {
+ TileIndex tile = *ti;
+
+ if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) {
+ return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
+ }
+
+ if (direction == -1) {
+ uint z, t;
+
+ z = TerraformGetHeightOfTile(&ts, tile + TileDiffXY(0, 0));
+ t = TerraformGetHeightOfTile(&ts, tile + TileDiffXY(1, 0));
+ if (t <= z) z = t;
+ t = TerraformGetHeightOfTile(&ts, tile + TileDiffXY(1, 1));
+ if (t <= z) z = t;
+ t = TerraformGetHeightOfTile(&ts, tile + TileDiffXY(0, 1));
+ if (t <= z) z = t;
+
+ if (IsTunnelInWay(tile, z * TILE_HEIGHT)) {
+ return_cmd_error(STR_1002_EXCAVATION_WOULD_DAMAGE);
+ }
+ }
+ }
+ }
+
+ if (flags & DC_EXEC) {
+ /* Clear the landscape at the tiles */
+ {
+ int count;
+ TileIndex *ti = ts.tile_table;
+ for (count = ts.tile_table_count; count != 0; count--, ti++) {
+ DoCommand(*ti, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+ }
+ }
+
+ /* change the height */
+ {
+ int count;
+ TerraformerHeightMod *mod;
+
+ mod = ts.modheight;
+ for (count = ts.modheight_count; count != 0; count--, mod++) {
+ TileIndex til = mod->tile;
+
+ SetTileHeight(til, mod->height);
+ TerraformAddDirtyTileAround(&ts, til);
+ }
+ }
+
+ /* finally mark the dirty tiles dirty */
+ {
+ int count;
+ TileIndex *ti = ts.tile_table;
+ for (count = ts.tile_table_count; count != 0; count--, ti++) {
+ MarkTileDirtyByTile(*ti);
+ }
+ }
+ }
+ return ts.cost;
+}
+
+
+/** Levels a selected (rectangle) area of land
+ * @param tile end tile of area-drag
+ * @param p1 start tile of area drag
+ * @param p2 unused
+ */
+int32 CmdLevelLand(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ int size_x, size_y;
+ int ex;
+ int ey;
+ int sx, sy;
+ uint h, curh;
+ int32 ret, cost, money;
+
+ if (p1 >= MapSize()) return CMD_ERROR;
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ // remember level height
+ h = TileHeight(p1);
+
+ // make sure sx,sy are smaller than ex,ey
+ ex = TileX(tile);
+ ey = TileY(tile);
+ sx = TileX(p1);
+ sy = TileY(p1);
+ if (ex < sx) intswap(ex, sx);
+ if (ey < sy) intswap(ey, sy);
+ tile = TileXY(sx, sy);
+
+ size_x = ex-sx+1;
+ size_y = ey-sy+1;
+
+ money = GetAvailableMoneyForCommand();
+ cost = 0;
+
+ BEGIN_TILE_LOOP(tile2, size_x, size_y, tile) {
+ curh = TileHeight(tile2);
+ while (curh != h) {
+ ret = DoCommand(tile2, 8, (curh > h) ? 0 : 1, flags & ~DC_EXEC, CMD_TERRAFORM_LAND);
+ if (CmdFailed(ret)) break;
+ cost += ret;
+
+ if (flags & DC_EXEC) {
+ if ((money -= ret) < 0) {
+ _additional_cash_required = ret;
+ return cost - ret;
+ }
+ DoCommand(tile2, 8, (curh > h) ? 0 : 1, flags, CMD_TERRAFORM_LAND);
+ }
+
+ curh += (curh > h) ? -1 : 1;
+ }
+ } END_TILE_LOOP(tile2, size_x, size_y, tile)
+
+ return (cost == 0) ? CMD_ERROR : cost;
+}
+
+/** Purchase a land area. Actually you only purchase one tile, so
+ * the name is a bit confusing ;p
+ * @param tile the tile the player is purchasing
+ * @param p1 unused
+ * @param p2 unused
+ */
+int32 CmdPurchaseLandArea(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ int32 cost;
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ if (!EnsureNoVehicle(tile)) return CMD_ERROR;
+
+ if (IsOwnedLandTile(tile) && IsTileOwner(tile, _current_player)) {
+ return_cmd_error(STR_5807_YOU_ALREADY_OWN_IT);
+ }
+
+ cost = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+ if (CmdFailed(cost)) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ MakeOwnedLand(tile, _current_player);
+ MarkTileDirtyByTile(tile);
+ }
+
+ return cost + _price.purchase_land * 10;
+}
+
+
+static int32 ClearTile_Clear(TileIndex tile, byte flags)
+{
+ static const int32* clear_price_table[] = {
+ &_price.clear_1,
+ &_price.purchase_land,
+ &_price.clear_2,
+ &_price.clear_3,
+ &_price.purchase_land,
+ &_price.purchase_land,
+ &_price.clear_2, // XXX unused?
+ };
+ int32 price;
+
+ if (IsClearGround(tile, CLEAR_GRASS) && GetClearDensity(tile) == 0) {
+ price = 0;
+ } else {
+ price = *clear_price_table[GetClearGround(tile)];
+ }
+
+ if (flags & DC_EXEC) DoClearSquare(tile);
+
+ return price;
+}
+
+/** Sell a land area. Actually you only sell one tile, so
+ * the name is a bit confusing ;p
+ * @param tile the tile the player is selling
+ * @param p1 unused
+ * @param p2 unused
+ */
+int32 CmdSellLandArea(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ if (!IsOwnedLandTile(tile)) return CMD_ERROR;
+ if (!CheckTileOwnership(tile) && _current_player != OWNER_WATER) return CMD_ERROR;
+
+
+ if (!EnsureNoVehicle(tile)) return CMD_ERROR;
+
+ if (flags & DC_EXEC) DoClearSquare(tile);
+
+ return - _price.purchase_land * 2;
+}
+
+
+#include "table/clear_land.h"
+
+
+void DrawClearLandTile(const TileInfo *ti, byte set)
+{
+ DrawGroundSprite(SPR_FLAT_BARE_LAND + _tileh_to_sprite[ti->tileh] + set * 19);
+}
+
+void DrawHillyLandTile(const TileInfo *ti)
+{
+ if (ti->tileh != SLOPE_FLAT) {
+ DrawGroundSprite(SPR_FLAT_ROUGH_LAND + _tileh_to_sprite[ti->tileh]);
+ } else {
+ DrawGroundSprite(_landscape_clear_sprites[GB(ti->x ^ ti->y, 4, 3)]);
+ }
+}
+
+void DrawClearLandFence(const TileInfo *ti)
+{
+ byte z = ti->z;
+
+ if (ti->tileh & SLOPE_S) {
+ z += TILE_HEIGHT;
+ if (ti->tileh == SLOPE_STEEP_S) z += TILE_HEIGHT;
+ }
+
+ if (GetFenceSW(ti->tile) != 0) {
+ DrawGroundSpriteAt(_clear_land_fence_sprites_1[GetFenceSW(ti->tile) - 1] + _fence_mod_by_tileh[ti->tileh], ti->x, ti->y, z);
+ }
+
+ if (GetFenceSE(ti->tile) != 0) {
+ DrawGroundSpriteAt(_clear_land_fence_sprites_1[GetFenceSE(ti->tile) - 1] + _fence_mod_by_tileh_2[ti->tileh], ti->x, ti->y, z);
+ }
+}
+
+static void DrawTile_Clear(TileInfo *ti)
+{
+ switch (GetClearGround(ti->tile)) {
+ case CLEAR_GRASS:
+ DrawClearLandTile(ti, GetClearDensity(ti->tile));
+ break;
+
+ case CLEAR_ROUGH:
+ DrawHillyLandTile(ti);
+ break;
+
+ case CLEAR_ROCKS:
+ DrawGroundSprite(SPR_FLAT_ROCKY_LAND_1 + _tileh_to_sprite[ti->tileh]);
+ break;
+
+ case CLEAR_FIELDS:
+ DrawGroundSprite(_clear_land_sprites_1[GetFieldType(ti->tile)] + _tileh_to_sprite[ti->tileh]);
+ break;
+
+ case CLEAR_SNOW:
+ DrawGroundSprite(_clear_land_sprites_2[GetClearDensity(ti->tile)] + _tileh_to_sprite[ti->tileh]);
+ break;
+
+ case CLEAR_DESERT:
+ DrawGroundSprite(_clear_land_sprites_3[GetClearDensity(ti->tile)] + _tileh_to_sprite[ti->tileh]);
+ break;
+ }
+
+ DrawClearLandFence(ti);
+ DrawBridgeMiddle(ti);
+}
+
+static uint GetSlopeZ_Clear(TileIndex tile, uint x, uint y)
+{
+ uint z;
+ uint tileh = GetTileSlope(tile, &z);
+
+ return z + GetPartialZ(x & 0xF, y & 0xF, tileh);
+}
+
+static Slope GetSlopeTileh_Clear(TileIndex tile, Slope tileh)
+{
+ return tileh;
+}
+
+static void GetAcceptedCargo_Clear(TileIndex tile, AcceptedCargo ac)
+{
+ /* unused */
+}
+
+static void AnimateTile_Clear(TileIndex tile)
+{
+ /* unused */
+}
+
+void TileLoopClearHelper(TileIndex tile)
+{
+ byte self;
+ byte neighbour;
+ TileIndex dirty = INVALID_TILE;
+
+ self = (IsTileType(tile, MP_CLEAR) && IsClearGround(tile, CLEAR_FIELDS));
+
+ neighbour = (IsTileType(TILE_ADDXY(tile, 1, 0), MP_CLEAR) && IsClearGround(TILE_ADDXY(tile, 1, 0), CLEAR_FIELDS));
+ if (GetFenceSW(tile) == 0) {
+ if (self != neighbour) {
+ SetFenceSW(tile, 3);
+ dirty = tile;
+ }
+ } else {
+ if (self == 0 && neighbour == 0) {
+ SetFenceSW(tile, 0);
+ dirty = tile;
+ }
+ }
+
+ neighbour = (IsTileType(TILE_ADDXY(tile, 0, 1), MP_CLEAR) && IsClearGround(TILE_ADDXY(tile, 0, 1), CLEAR_FIELDS));
+ if (GetFenceSE(tile) == 0) {
+ if (self != neighbour) {
+ SetFenceSE(tile, 3);
+ dirty = tile;
+ }
+ } else {
+ if (self == 0 && neighbour == 0) {
+ SetFenceSE(tile, 0);
+ dirty = tile;
+ }
+ }
+
+ if (dirty != INVALID_TILE) MarkTileDirtyByTile(dirty);
+}
+
+
+/* convert into snowy tiles */
+static void TileLoopClearAlps(TileIndex tile)
+{
+ int k = GetTileZ(tile) - _opt.snow_line + TILE_HEIGHT;
+
+ if (k < 0) { // well below the snow line
+ if (!IsClearGround(tile, CLEAR_SNOW)) return;
+ if (GetClearDensity(tile) == 0) SetClearGroundDensity(tile, CLEAR_GRASS, 3);
+ } else {
+ if (!IsClearGround(tile, CLEAR_SNOW)) {
+ SetClearGroundDensity(tile, CLEAR_SNOW, 0);
+ } else {
+ uint density = min((uint)k / TILE_HEIGHT, 3);
+
+ if (GetClearDensity(tile) < density) {
+ AddClearDensity(tile, 1);
+ } else if (GetClearDensity(tile) > density) {
+ AddClearDensity(tile, -1);
+ } else {
+ return;
+ }
+ }
+ }
+
+ MarkTileDirtyByTile(tile);
+}
+
+static void TileLoopClearDesert(TileIndex tile)
+{
+ if (IsClearGround(tile, CLEAR_DESERT)) return;
+
+ if (GetTropicZone(tile) == TROPICZONE_DESERT) {
+ SetClearGroundDensity(tile, CLEAR_DESERT, 3);
+ } else {
+ if (GetTropicZone(tile + TileDiffXY( 1, 0)) != TROPICZONE_DESERT &&
+ GetTropicZone(tile + TileDiffXY(-1, 0)) != TROPICZONE_DESERT &&
+ GetTropicZone(tile + TileDiffXY( 0, 1)) != TROPICZONE_DESERT &&
+ GetTropicZone(tile + TileDiffXY( 0, -1)) != TROPICZONE_DESERT)
+ return;
+ SetClearGroundDensity(tile, CLEAR_DESERT, 1);
+ }
+
+ MarkTileDirtyByTile(tile);
+}
+
+static void TileLoop_Clear(TileIndex tile)
+{
+ TileLoopClearHelper(tile);
+
+ switch (_opt.landscape) {
+ case LT_DESERT: TileLoopClearDesert(tile); break;
+ case LT_HILLY: TileLoopClearAlps(tile); break;
+ }
+
+ switch (GetClearGround(tile)) {
+ case CLEAR_GRASS:
+ if (GetClearDensity(tile) == 3) return;
+
+ if (_game_mode != GM_EDITOR) {
+ if (GetClearCounter(tile) < 7) {
+ AddClearCounter(tile, 1);
+ return;
+ } else {
+ SetClearCounter(tile, 0);
+ AddClearDensity(tile, 1);
+ }
+ } else {
+ SetClearGroundDensity(tile, GB(Random(), 0, 8) > 21 ? CLEAR_GRASS : CLEAR_ROUGH, 3);
+ }
+ break;
+
+ case CLEAR_FIELDS: {
+ uint field_type;
+
+ if (_game_mode == GM_EDITOR) return;
+
+ if (GetClearCounter(tile) < 7) {
+ AddClearCounter(tile, 1);
+ return;
+ } else {
+ SetClearCounter(tile, 0);
+ }
+
+ if (GetIndustryIndexOfField(tile) == INVALID_INDUSTRY && GetFieldType(tile) >= 7) {
+ /* This farmfield is no longer farmfield, so make it grass again */
+ MakeClear(tile, CLEAR_GRASS, 2);
+ } else {
+ field_type = GetFieldType(tile);
+ field_type = (field_type < 8) ? field_type + 1 : 0;
+ SetFieldType(tile, field_type);
+ }
+ break;
+ }
+
+ default:
+ return;
+ }
+
+ MarkTileDirtyByTile(tile);
+}
+
+void GenerateClearTile(void)
+{
+ uint i, gi;
+ TileIndex tile;
+
+ /* add rough tiles */
+ i = ScaleByMapSize(GB(Random(), 0, 10) + 0x400);
+ gi = ScaleByMapSize(GB(Random(), 0, 7) + 0x80);
+
+ SetGeneratingWorldProgress(GWP_ROUGH_ROCKY, gi + i);
+ do {
+ IncreaseGeneratingWorldProgress(GWP_ROUGH_ROCKY);
+ tile = RandomTile();
+ if (IsTileType(tile, MP_CLEAR) && !IsClearGround(tile, CLEAR_DESERT)) SetClearGroundDensity(tile, CLEAR_ROUGH, 3);
+ } while (--i);
+
+ /* add rocky tiles */
+ i = gi;
+ do {
+ uint32 r = Random();
+ tile = RandomTileSeed(r);
+
+ IncreaseGeneratingWorldProgress(GWP_ROUGH_ROCKY);
+ if (IsTileType(tile, MP_CLEAR) && !IsClearGround(tile, CLEAR_DESERT)) {
+ uint j = GB(r, 16, 4) + 5;
+ for (;;) {
+ TileIndex tile_new;
+
+ SetClearGroundDensity(tile, CLEAR_ROCKS, 3);
+ do {
+ if (--j == 0) goto get_out;
+ tile_new = tile + TileOffsByDiagDir(GB(Random(), 0, 2));
+ } while (!IsTileType(tile_new, MP_CLEAR) || IsClearGround(tile_new, CLEAR_DESERT));
+ tile = tile_new;
+ }
+get_out:;
+ }
+ } while (--i);
+}
+
+static void ClickTile_Clear(TileIndex tile)
+{
+ /* not used */
+}
+
+static uint32 GetTileTrackStatus_Clear(TileIndex tile, TransportType mode)
+{
+ return 0;
+}
+
+static const StringID _clear_land_str[] = {
+ STR_080D_GRASS,
+ STR_080B_ROUGH_LAND,
+ STR_080A_ROCKS,
+ STR_080E_FIELDS,
+ STR_080F_SNOW_COVERED_LAND,
+ STR_0810_DESERT
+};
+
+static void GetTileDesc_Clear(TileIndex tile, TileDesc *td)
+{
+ if (IsClearGround(tile, CLEAR_GRASS) && GetClearDensity(tile) == 0) {
+ td->str = STR_080C_BARE_LAND;
+ } else {
+ td->str = _clear_land_str[GetClearGround(tile)];
+ }
+ td->owner = GetTileOwner(tile);
+}
+
+static void ChangeTileOwner_Clear(TileIndex tile, PlayerID old_player, PlayerID new_player)
+{
+ return;
+}
+
+void InitializeClearLand(void)
+{
+ _opt.snow_line = _patches.snow_line_height * TILE_HEIGHT;
+}
+
+const TileTypeProcs _tile_type_clear_procs = {
+ DrawTile_Clear, /* draw_tile_proc */
+ GetSlopeZ_Clear, /* get_slope_z_proc */
+ ClearTile_Clear, /* clear_tile_proc */
+ GetAcceptedCargo_Clear, /* get_accepted_cargo_proc */
+ GetTileDesc_Clear, /* get_tile_desc_proc */
+ GetTileTrackStatus_Clear, /* get_tile_track_status_proc */
+ ClickTile_Clear, /* click_tile_proc */
+ AnimateTile_Clear, /* animate_tile_proc */
+ TileLoop_Clear, /* tile_loop_clear */
+ ChangeTileOwner_Clear, /* change_tile_owner_clear */
+ NULL, /* get_produced_cargo_proc */
+ NULL, /* vehicle_enter_tile_proc */
+ GetSlopeTileh_Clear, /* get_slope_tileh_proc */
+};
diff --git a/src/clear_map.h b/src/clear_map.h
new file mode 100644
index 000000000..50ae63b1b
--- /dev/null
+++ b/src/clear_map.h
@@ -0,0 +1,145 @@
+/* $Id$ */
+
+#ifndef CLEAR_MAP_H
+#define CLEAR_MAP_H
+
+#include "macros.h"
+#include "tile.h"
+
+/* ground type, m5 bits 2...4
+ * valid densities (bits 0...1) in comments after the enum
+ */
+typedef enum ClearGround {
+ CLEAR_GRASS = 0, // 0-3
+ CLEAR_ROUGH = 1, // 3
+ CLEAR_ROCKS = 2, // 3
+ CLEAR_FIELDS = 3, // 3
+ CLEAR_SNOW = 4, // 0-3
+ CLEAR_DESERT = 5 // 1,3
+} ClearGround;
+
+
+static inline ClearGround GetClearGround(TileIndex t)
+{
+ assert(IsTileType(t, MP_CLEAR));
+ return GB(_m[t].m5, 2, 3);
+}
+
+static inline bool IsClearGround(TileIndex t, ClearGround ct)
+{
+ return GetClearGround(t) == ct;
+}
+
+
+static inline uint GetClearDensity(TileIndex t)
+{
+ assert(IsTileType(t, MP_CLEAR));
+ return GB(_m[t].m5, 0, 2);
+}
+
+static inline void AddClearDensity(TileIndex t, int d)
+{
+ assert(IsTileType(t, MP_CLEAR)); // XXX incomplete
+ _m[t].m5 += d;
+}
+
+
+static inline uint GetClearCounter(TileIndex t)
+{
+ assert(IsTileType(t, MP_CLEAR));
+ return GB(_m[t].m5, 5, 3);
+}
+
+static inline void AddClearCounter(TileIndex t, int c)
+{
+ assert(IsTileType(t, MP_CLEAR)); // XXX incomplete
+ _m[t].m5 += c << 5;
+}
+
+static inline void SetClearCounter(TileIndex t, uint c)
+{
+ assert(IsTileType(t, MP_CLEAR)); // XXX incomplete
+ SB(_m[t].m5, 5, 3, c);
+}
+
+
+/* Sets type and density in one go, also sets the counter to 0 */
+static inline void SetClearGroundDensity(TileIndex t, ClearGround type, uint density)
+{
+ assert(IsTileType(t, MP_CLEAR)); // XXX incomplete
+ _m[t].m5 = 0 << 5 | type << 2 | density;
+}
+
+
+static inline uint GetFieldType(TileIndex t)
+{
+ assert(GetClearGround(t) == CLEAR_FIELDS);
+ return GB(_m[t].m3, 0, 4);
+}
+
+static inline void SetFieldType(TileIndex t, uint f)
+{
+ assert(GetClearGround(t) == CLEAR_FIELDS); // XXX incomplete
+ SB(_m[t].m3, 0, 4, f);
+}
+
+static inline uint16 GetIndustryIndexOfField(TileIndex t)
+{
+ assert(GetClearGround(t) == CLEAR_FIELDS);
+ return _m[t].m2;
+}
+
+static inline void SetIndustryIndexOfField(TileIndex t, uint16 i)
+{
+ assert(GetClearGround(t) == CLEAR_FIELDS);
+ _m[t].m2 = i;
+}
+
+/* Is used by tree tiles, too */
+static inline uint GetFenceSE(TileIndex t)
+{
+ assert(IsTileType(t, MP_CLEAR) || IsTileType(t, MP_TREES));
+ return GB(_m[t].m4, 2, 3);
+}
+
+static inline void SetFenceSE(TileIndex t, uint h)
+{
+ assert(IsTileType(t, MP_CLEAR) || IsTileType(t, MP_TREES)); // XXX incomplete
+ SB(_m[t].m4, 2, 3, h);
+}
+
+static inline uint GetFenceSW(TileIndex t)
+{
+ assert(IsTileType(t, MP_CLEAR) || IsTileType(t, MP_TREES));
+ return GB(_m[t].m4, 5, 3);
+}
+
+static inline void SetFenceSW(TileIndex t, uint h)
+{
+ assert(IsTileType(t, MP_CLEAR) || IsTileType(t, MP_TREES)); // XXX incomplete
+ SB(_m[t].m4, 5, 3, h);
+}
+
+
+static inline void MakeClear(TileIndex t, ClearGround g, uint density)
+{
+ SetTileType(t, MP_CLEAR);
+ SetTileOwner(t, OWNER_NONE);
+ _m[t].m2 = 0;
+ _m[t].m3 = 0;
+ _m[t].m4 = 0 << 5 | 0 << 2;
+ SetClearGroundDensity(t, g, density);
+}
+
+
+static inline void MakeField(TileIndex t, uint field_type, uint16 industry)
+{
+ SetTileType(t, MP_CLEAR);
+ SetTileOwner(t, OWNER_NONE);
+ _m[t].m2 = industry;
+ _m[t].m3 = field_type;
+ _m[t].m4 = 0 << 5 | 0 << 2;
+ SetClearGroundDensity(t, CLEAR_FIELDS, 3);
+}
+
+#endif /* CLEAR_MAP_H */
diff --git a/src/command.c b/src/command.c
new file mode 100644
index 000000000..f99371946
--- /dev/null
+++ b/src/command.c
@@ -0,0 +1,562 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "table/strings.h"
+#include "functions.h"
+#include "map.h"
+#include "gui.h"
+#include "command.h"
+#include "player.h"
+#include "network/network.h"
+#include "variables.h"
+#include "genworld.h"
+
+const char* _cmd_text = NULL;
+
+#define DEF_COMMAND(yyyy) int32 yyyy(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+
+DEF_COMMAND(CmdBuildRailroadTrack);
+DEF_COMMAND(CmdRemoveRailroadTrack);
+DEF_COMMAND(CmdBuildSingleRail);
+DEF_COMMAND(CmdRemoveSingleRail);
+
+DEF_COMMAND(CmdLandscapeClear);
+
+DEF_COMMAND(CmdBuildBridge);
+
+DEF_COMMAND(CmdBuildRailroadStation);
+DEF_COMMAND(CmdRemoveFromRailroadStation);
+DEF_COMMAND(CmdConvertRail);
+
+DEF_COMMAND(CmdBuildSingleSignal);
+DEF_COMMAND(CmdRemoveSingleSignal);
+
+DEF_COMMAND(CmdTerraformLand);
+
+DEF_COMMAND(CmdPurchaseLandArea);
+DEF_COMMAND(CmdSellLandArea);
+
+DEF_COMMAND(CmdBuildTunnel);
+
+DEF_COMMAND(CmdBuildTrainDepot);
+DEF_COMMAND(CmdBuildTrainWaypoint);
+DEF_COMMAND(CmdRenameWaypoint);
+DEF_COMMAND(CmdRemoveTrainWaypoint);
+
+DEF_COMMAND(CmdBuildRoadStop);
+
+DEF_COMMAND(CmdBuildLongRoad);
+DEF_COMMAND(CmdRemoveLongRoad);
+DEF_COMMAND(CmdBuildRoad);
+DEF_COMMAND(CmdRemoveRoad);
+
+DEF_COMMAND(CmdBuildRoadDepot);
+
+DEF_COMMAND(CmdBuildAirport);
+
+DEF_COMMAND(CmdBuildDock);
+
+DEF_COMMAND(CmdBuildShipDepot);
+
+DEF_COMMAND(CmdBuildBuoy);
+
+DEF_COMMAND(CmdPlantTree);
+
+DEF_COMMAND(CmdBuildRailVehicle);
+DEF_COMMAND(CmdMoveRailVehicle);
+
+DEF_COMMAND(CmdStartStopTrain);
+
+DEF_COMMAND(CmdSellRailWagon);
+
+DEF_COMMAND(CmdSendTrainToDepot);
+DEF_COMMAND(CmdForceTrainProceed);
+DEF_COMMAND(CmdReverseTrainDirection);
+
+DEF_COMMAND(CmdModifyOrder);
+DEF_COMMAND(CmdSkipOrder);
+DEF_COMMAND(CmdDeleteOrder);
+DEF_COMMAND(CmdInsertOrder);
+DEF_COMMAND(CmdChangeServiceInt);
+DEF_COMMAND(CmdRestoreOrderIndex);
+
+DEF_COMMAND(CmdBuildIndustry);
+
+DEF_COMMAND(CmdBuildCompanyHQ);
+DEF_COMMAND(CmdSetPlayerFace);
+DEF_COMMAND(CmdSetPlayerColor);
+
+DEF_COMMAND(CmdIncreaseLoan);
+DEF_COMMAND(CmdDecreaseLoan);
+
+DEF_COMMAND(CmdWantEnginePreview);
+
+DEF_COMMAND(CmdNameVehicle);
+DEF_COMMAND(CmdRenameEngine);
+
+DEF_COMMAND(CmdChangeCompanyName);
+DEF_COMMAND(CmdChangePresidentName);
+
+DEF_COMMAND(CmdRenameStation);
+
+DEF_COMMAND(CmdSellAircraft);
+DEF_COMMAND(CmdStartStopAircraft);
+DEF_COMMAND(CmdBuildAircraft);
+DEF_COMMAND(CmdSendAircraftToHangar);
+DEF_COMMAND(CmdRefitAircraft);
+
+DEF_COMMAND(CmdPlaceSign);
+DEF_COMMAND(CmdRenameSign);
+
+DEF_COMMAND(CmdBuildRoadVeh);
+DEF_COMMAND(CmdStartStopRoadVeh);
+DEF_COMMAND(CmdSellRoadVeh);
+DEF_COMMAND(CmdSendRoadVehToDepot);
+DEF_COMMAND(CmdTurnRoadVeh);
+DEF_COMMAND(CmdRefitRoadVeh);
+
+DEF_COMMAND(CmdPause);
+
+DEF_COMMAND(CmdBuyShareInCompany);
+DEF_COMMAND(CmdSellShareInCompany);
+DEF_COMMAND(CmdBuyCompany);
+
+DEF_COMMAND(CmdBuildTown);
+
+DEF_COMMAND(CmdRenameTown);
+DEF_COMMAND(CmdDoTownAction);
+
+DEF_COMMAND(CmdSetRoadDriveSide);
+
+DEF_COMMAND(CmdChangeDifficultyLevel);
+DEF_COMMAND(CmdChangePatchSetting);
+
+DEF_COMMAND(CmdStartStopShip);
+DEF_COMMAND(CmdSellShip);
+DEF_COMMAND(CmdBuildShip);
+DEF_COMMAND(CmdSendShipToDepot);
+DEF_COMMAND(CmdRefitShip);
+
+DEF_COMMAND(CmdOrderRefit);
+DEF_COMMAND(CmdCloneOrder);
+
+DEF_COMMAND(CmdClearArea);
+
+DEF_COMMAND(CmdGiveMoney);
+DEF_COMMAND(CmdMoneyCheat);
+DEF_COMMAND(CmdBuildCanal);
+DEF_COMMAND(CmdBuildLock);
+
+DEF_COMMAND(CmdPlayerCtrl);
+
+DEF_COMMAND(CmdLevelLand);
+
+DEF_COMMAND(CmdRefitRailVehicle);
+
+DEF_COMMAND(CmdBuildSignalTrack);
+DEF_COMMAND(CmdRemoveSignalTrack);
+
+DEF_COMMAND(CmdSetAutoReplace);
+
+DEF_COMMAND(CmdCloneVehicle);
+DEF_COMMAND(CmdMassStartStopVehicle);
+DEF_COMMAND(CmdDepotSellAllVehicles);
+DEF_COMMAND(CmdDepotMassAutoReplace);
+
+/* The master command table */
+static const Command _command_proc_table[] = {
+ {CmdBuildRailroadTrack, 0}, /* 0 */
+ {CmdRemoveRailroadTrack, 0}, /* 1 */
+ {CmdBuildSingleRail, 0}, /* 2 */
+ {CmdRemoveSingleRail, 0}, /* 3 */
+ {CmdLandscapeClear, 0}, /* 4 */
+ {CmdBuildBridge, 0}, /* 5 */
+ {CmdBuildRailroadStation, 0}, /* 6 */
+ {CmdBuildTrainDepot, 0}, /* 7 */
+ {CmdBuildSingleSignal, 0}, /* 8 */
+ {CmdRemoveSingleSignal, 0}, /* 9 */
+ {CmdTerraformLand, 0}, /* 10 */
+ {CmdPurchaseLandArea, 0}, /* 11 */
+ {CmdSellLandArea, 0}, /* 12 */
+ {CmdBuildTunnel, 0}, /* 13 */
+ {CmdRemoveFromRailroadStation, 0}, /* 14 */
+ {CmdConvertRail, 0}, /* 15 */
+ {CmdBuildTrainWaypoint, 0}, /* 16 */
+ {CmdRenameWaypoint, 0}, /* 17 */
+ {CmdRemoveTrainWaypoint, 0}, /* 18 */
+ {NULL, 0}, /* 19 */
+ {NULL, 0}, /* 20 */
+ {CmdBuildRoadStop, 0}, /* 21 */
+ {NULL, 0}, /* 22 */
+ {CmdBuildLongRoad, 0}, /* 23 */
+ {CmdRemoveLongRoad, 0}, /* 24 */
+ {CmdBuildRoad, 0}, /* 25 */
+ {CmdRemoveRoad, 0}, /* 26 */
+ {CmdBuildRoadDepot, 0}, /* 27 */
+ {NULL, 0}, /* 28 */
+ {CmdBuildAirport, 0}, /* 29 */
+ {CmdBuildDock, 0}, /* 30 */
+ {CmdBuildShipDepot, 0}, /* 31 */
+ {CmdBuildBuoy, 0}, /* 32 */
+ {CmdPlantTree, 0}, /* 33 */
+ {CmdBuildRailVehicle, 0}, /* 34 */
+ {CmdMoveRailVehicle, 0}, /* 35 */
+ {CmdStartStopTrain, 0}, /* 36 */
+ {NULL, 0}, /* 37 */
+ {CmdSellRailWagon, 0}, /* 38 */
+ {CmdSendTrainToDepot, 0}, /* 39 */
+ {CmdForceTrainProceed, 0}, /* 40 */
+ {CmdReverseTrainDirection, 0}, /* 41 */
+
+ {CmdModifyOrder, 0}, /* 42 */
+ {CmdSkipOrder, 0}, /* 43 */
+ {CmdDeleteOrder, 0}, /* 44 */
+ {CmdInsertOrder, 0}, /* 45 */
+
+ {CmdChangeServiceInt, 0}, /* 46 */
+
+ {CmdBuildIndustry, 0}, /* 47 */
+ {CmdBuildCompanyHQ, 0}, /* 48 */
+ {CmdSetPlayerFace, 0}, /* 49 */
+ {CmdSetPlayerColor, 0}, /* 50 */
+
+ {CmdIncreaseLoan, 0}, /* 51 */
+ {CmdDecreaseLoan, 0}, /* 52 */
+
+ {CmdWantEnginePreview, 0}, /* 53 */
+
+ {CmdNameVehicle, 0}, /* 54 */
+ {CmdRenameEngine, 0}, /* 55 */
+
+ {CmdChangeCompanyName, 0}, /* 56 */
+ {CmdChangePresidentName, 0}, /* 57 */
+
+ {CmdRenameStation, 0}, /* 58 */
+
+ {CmdSellAircraft, 0}, /* 59 */
+ {CmdStartStopAircraft, 0}, /* 60 */
+
+ {CmdBuildAircraft, 0}, /* 61 */
+ {CmdSendAircraftToHangar, 0}, /* 62 */
+ {NULL, 0}, /* 63 */
+ {CmdRefitAircraft, 0}, /* 64 */
+
+ {CmdPlaceSign, 0}, /* 65 */
+ {CmdRenameSign, 0}, /* 66 */
+
+ {CmdBuildRoadVeh, 0}, /* 67 */
+ {CmdStartStopRoadVeh, 0}, /* 68 */
+ {CmdSellRoadVeh, 0}, /* 69 */
+ {CmdSendRoadVehToDepot, 0}, /* 70 */
+ {CmdTurnRoadVeh, 0}, /* 71 */
+ {CmdRefitRoadVeh, 0}, /* 72 */
+
+ {CmdPause, CMD_SERVER}, /* 73 */
+
+ {CmdBuyShareInCompany, 0}, /* 74 */
+ {CmdSellShareInCompany, 0}, /* 75 */
+ {CmdBuyCompany, 0}, /* 76 */
+
+ {CmdBuildTown, CMD_OFFLINE}, /* 77 */
+ {NULL, 0}, /* 78 */
+ {NULL, 0}, /* 79 */
+ {CmdRenameTown, CMD_SERVER}, /* 80 */
+ {CmdDoTownAction, 0}, /* 81 */
+
+ {CmdSetRoadDriveSide, CMD_SERVER}, /* 82 */
+ {NULL, 0}, /* 83 */
+ {NULL, 0}, /* 84 */
+ {CmdChangeDifficultyLevel, CMD_SERVER}, /* 85 */
+
+ {CmdStartStopShip, 0}, /* 86 */
+ {CmdSellShip, 0}, /* 87 */
+ {CmdBuildShip, 0}, /* 88 */
+ {CmdSendShipToDepot, 0}, /* 89 */
+ {NULL, 0}, /* 90 */
+ {CmdRefitShip, 0}, /* 91 */
+
+ {NULL, 0}, /* 92 */
+ {NULL, 0}, /* 93 */
+ {NULL, 0}, /* 94 */
+ {NULL, 0}, /* 95 */
+ {NULL, 0}, /* 96 */
+ {NULL, 0}, /* 97 */
+
+ {CmdOrderRefit, 0}, /* 98 */
+ {CmdCloneOrder, 0}, /* 99 */
+
+ {CmdClearArea, 0}, /* 100 */
+ {NULL, 0}, /* 101 */
+
+ {CmdMoneyCheat, CMD_OFFLINE}, /* 102 */
+ {CmdBuildCanal, 0}, /* 103 */
+ {CmdPlayerCtrl, 0}, /* 104 */
+
+ {CmdLevelLand, 0}, /* 105 */
+
+ {CmdRefitRailVehicle, 0}, /* 106 */
+ {CmdRestoreOrderIndex, 0}, /* 107 */
+ {CmdBuildLock, 0}, /* 108 */
+ {NULL, 0}, /* 109 */
+ {CmdBuildSignalTrack, 0}, /* 110 */
+ {CmdRemoveSignalTrack, 0}, /* 111 */
+ {NULL, 0}, /* 112 */
+ {CmdGiveMoney, 0}, /* 113 */
+ {CmdChangePatchSetting, CMD_SERVER}, /* 114 */
+ {CmdSetAutoReplace, 0}, /* 115 */
+ {CmdCloneVehicle, 0}, /* 116 */
+ {CmdMassStartStopVehicle, 0}, /* 117 */
+ {CmdDepotSellAllVehicles, 0}, /* 118 */
+ {CmdDepotMassAutoReplace, 0}, /* 119 */
+};
+
+/* This function range-checks a cmd, and checks if the cmd is not NULL */
+bool IsValidCommand(uint cmd)
+{
+ cmd &= 0xFF;
+
+ return
+ cmd < lengthof(_command_proc_table) &&
+ _command_proc_table[cmd].proc != NULL;
+}
+
+byte GetCommandFlags(uint cmd)
+{
+ return _command_proc_table[cmd & 0xFF].flags;
+}
+
+
+static int _docommand_recursive;
+
+int32 DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc)
+{
+ int32 res;
+ CommandProc *proc;
+
+ /* Do not even think about executing out-of-bounds tile-commands */
+ if (tile >= MapSize()) {
+ _cmd_text = NULL;
+ return CMD_ERROR;
+ }
+
+ proc = _command_proc_table[procc].proc;
+
+ if (_docommand_recursive == 0) _error_message = INVALID_STRING_ID;
+
+ _docommand_recursive++;
+
+ // only execute the test call if it's toplevel, or we're not execing.
+ if (_docommand_recursive == 1 || !(flags & DC_EXEC) || (flags & DC_FORCETEST) ) {
+ res = proc(tile, flags & ~DC_EXEC, p1, p2);
+ if (CmdFailed(res)) {
+ if (res & 0xFFFF) _error_message = res & 0xFFFF;
+ goto error;
+ }
+
+ if (_docommand_recursive == 1 &&
+ !(flags & DC_QUERY_COST) &&
+ res != 0 &&
+ !CheckPlayerHasMoney(res)) {
+ goto error;
+ }
+
+ if (!(flags & DC_EXEC)) {
+ _docommand_recursive--;
+ _cmd_text = NULL;
+ return res;
+ }
+ }
+
+ /* Execute the command here. All cost-relevant functions set the expenses type
+ * themselves with "SET_EXPENSES_TYPE(...);" at the beginning of the function */
+ res = proc(tile, flags, p1, p2);
+ if (CmdFailed(res)) {
+ if (res & 0xFFFF) _error_message = res & 0xFFFF;
+error:
+ _docommand_recursive--;
+ _cmd_text = NULL;
+ return CMD_ERROR;
+ }
+
+ // if toplevel, subtract the money.
+ if (--_docommand_recursive == 0) {
+ SubtractMoneyFromPlayer(res);
+ // XXX - Old AI hack which doesn't use DoCommandDP; update last build coord of player
+ if (tile != 0 && IsValidPlayer(_current_player)) {
+ GetPlayer(_current_player)->last_build_coordinate = tile;
+ }
+ }
+
+ _cmd_text = NULL;
+ return res;
+}
+
+int32 GetAvailableMoneyForCommand(void)
+{
+ PlayerID pid = _current_player;
+ if (!IsValidPlayer(pid)) return 0x7FFFFFFF; // max int
+ return GetPlayer(pid)->player_money;
+}
+
+// toplevel network safe docommand function for the current player. must not be called recursively.
+// the callback is called when the command succeeded or failed.
+bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, CommandCallback *callback, uint32 cmd)
+{
+ int32 res = 0,res2;
+ CommandProc *proc;
+ uint32 flags;
+ bool notest;
+ StringID error_part1;
+
+ int x = TileX(tile) * TILE_SIZE;
+ int y = TileY(tile) * TILE_SIZE;
+
+ /* Do not even think about executing out-of-bounds tile-commands */
+ if (tile >= MapSize()) {
+ _cmd_text = NULL;
+ return false;
+ }
+
+ assert(_docommand_recursive == 0);
+
+ _error_message = INVALID_STRING_ID;
+ error_part1 = GB(cmd, 16, 16);
+ _additional_cash_required = 0;
+
+ /** Spectator has no rights except for the (dedicated) server which
+ * is/can be a spectator but as the server it can do anything */
+ if (_current_player == PLAYER_SPECTATOR && !_network_server) {
+ ShowErrorMessage(_error_message, error_part1, x, y);
+ _cmd_text = NULL;
+ return false;
+ }
+
+ flags = 0;
+ if (cmd & CMD_AUTO) flags |= DC_AUTO;
+ if (cmd & CMD_NO_WATER) flags |= DC_NO_WATER;
+
+ // get pointer to command handler
+ assert((cmd & 0xFF) < lengthof(_command_proc_table));
+ proc = _command_proc_table[cmd & 0xFF].proc;
+ if (proc == NULL) {
+ _cmd_text = NULL;
+ return false;
+ }
+
+ // Some commands have a different output in dryrun than the realrun
+ // e.g.: if you demolish a whole town, the dryrun would say okay.
+ // but by really destroying, your rating drops and at a certain point
+ // it will fail. so res and res2 are different
+ // CMD_REMOVE_ROAD: This command has special local authority
+ // restrictions which may cause the test run to fail (the previous
+ // road fragments still stay there and the town won't let you
+ // disconnect the road system), but the exec will succeed and this
+ // fact will trigger an assertion failure. --pasky
+ notest =
+ (cmd & 0xFF) == CMD_CLEAR_AREA ||
+ (cmd & 0xFF) == CMD_CONVERT_RAIL ||
+ (cmd & 0xFF) == CMD_LEVEL_LAND ||
+ (cmd & 0xFF) == CMD_REMOVE_ROAD ||
+ (cmd & 0xFF) == CMD_REMOVE_LONG_ROAD;
+
+ _docommand_recursive = 1;
+
+ // cost estimation only?
+ if (!IsGeneratingWorld() && _shift_pressed && IsLocalPlayer() && !(cmd & (CMD_NETWORK_COMMAND | CMD_SHOW_NO_ERROR))) {
+ // estimate the cost.
+ res = proc(tile, flags, p1, p2);
+ if (CmdFailed(res)) {
+ if (res & 0xFFFF) _error_message = res & 0xFFFF;
+ ShowErrorMessage(_error_message, error_part1, x, y);
+ } else {
+ ShowEstimatedCostOrIncome(res, x, y);
+ }
+
+ _docommand_recursive = 0;
+ _cmd_text = NULL;
+ return false;
+ }
+
+
+ if (!((cmd & CMD_NO_TEST_IF_IN_NETWORK) && _networking)) {
+ // first test if the command can be executed.
+ res = proc(tile, flags, p1, p2);
+ if (CmdFailed(res)) {
+ if (res & 0xFFFF) _error_message = res & 0xFFFF;
+ goto show_error;
+ }
+ // no money? Only check if notest is off
+ if (!notest && res != 0 && !CheckPlayerHasMoney(res)) goto show_error;
+ }
+
+#ifdef ENABLE_NETWORK
+ /** If we are in network, and the command is not from the network
+ * send it to the command-queue and abort execution
+ * If we are a dedicated server temporarily switch local player, otherwise
+ * the other parties won't be able to execute our command and will desync.
+ * We also need to do this if the server's company has gone bankrupt
+ * @todo Rewrite (dedicated) server to something more than a dirty hack!
+ */
+ if (_networking && !(cmd & CMD_NETWORK_COMMAND)) {
+ PlayerID pbck = _local_player;
+ if (_network_dedicated || (_network_server && pbck == PLAYER_SPECTATOR)) _local_player = 0;
+ NetworkSend_Command(tile, p1, p2, cmd, callback);
+ if (_network_dedicated || (_network_server && pbck == PLAYER_SPECTATOR)) _local_player = pbck;
+ _docommand_recursive = 0;
+ _cmd_text = NULL;
+ return true;
+ }
+#endif /* ENABLE_NETWORK */
+
+ // update last build coordinate of player.
+ if (tile != 0 && IsValidPlayer(_current_player)) {
+ GetPlayer(_current_player)->last_build_coordinate = tile;
+ }
+
+ /* Actually try and execute the command. If no cost-type is given
+ * use the construction one */
+ _yearly_expenses_type = EXPENSES_CONSTRUCTION;
+ res2 = proc(tile, flags | DC_EXEC, p1, p2);
+
+ // If notest is on, it means the result of the test can be different than
+ // the real command.. so ignore the test
+ if (!notest && !((cmd & CMD_NO_TEST_IF_IN_NETWORK) && _networking)) {
+ assert(res == res2); // sanity check
+ } else {
+ if (CmdFailed(res2)) {
+ if (res2 & 0xFFFF) _error_message = res2 & 0xFFFF;
+ goto show_error;
+ }
+ }
+
+ SubtractMoneyFromPlayer(res2);
+
+ if (IsLocalPlayer() && _game_mode != GM_EDITOR) {
+ if (res2 != 0) ShowCostOrIncomeAnimation(x, y, GetSlopeZ(x, y), res2);
+ if (_additional_cash_required) {
+ SetDParam(0, _additional_cash_required);
+ ShowErrorMessage(STR_0003_NOT_ENOUGH_CASH_REQUIRES, error_part1, x,y);
+ if (res2 == 0) goto callb_err;
+ }
+ }
+
+ _docommand_recursive = 0;
+
+ if (callback) callback(true, tile, p1, p2);
+ _cmd_text = NULL;
+ return true;
+
+show_error:
+ // show error message if the command fails?
+ if (IsLocalPlayer() && error_part1 != 0) {
+ ShowErrorMessage(_error_message, error_part1, x,y);
+ }
+
+callb_err:
+ _docommand_recursive = 0;
+
+ if (callback) callback(false, tile, p1, p2);
+ _cmd_text = NULL;
+ return false;
+}
diff --git a/src/command.h b/src/command.h
new file mode 100644
index 000000000..d46c771dd
--- /dev/null
+++ b/src/command.h
@@ -0,0 +1,213 @@
+/* $Id$ */
+
+#ifndef COMMAND_H
+#define COMMAND_H
+
+enum {
+ CMD_BUILD_RAILROAD_TRACK = 0,
+ CMD_REMOVE_RAILROAD_TRACK = 1,
+ CMD_BUILD_SINGLE_RAIL = 2,
+ CMD_REMOVE_SINGLE_RAIL = 3,
+ CMD_LANDSCAPE_CLEAR = 4,
+ CMD_BUILD_BRIDGE = 5,
+ CMD_BUILD_RAILROAD_STATION = 6,
+ CMD_BUILD_TRAIN_DEPOT = 7,
+ CMD_BUILD_SIGNALS = 8,
+ CMD_REMOVE_SIGNALS = 9,
+ CMD_TERRAFORM_LAND = 10,
+ CMD_PURCHASE_LAND_AREA = 11,
+ CMD_SELL_LAND_AREA = 12,
+ CMD_BUILD_TUNNEL = 13,
+
+ CMD_REMOVE_FROM_RAILROAD_STATION = 14,
+ CMD_CONVERT_RAIL = 15,
+
+ CMD_BUILD_TRAIN_WAYPOINT = 16,
+ CMD_RENAME_WAYPOINT = 17,
+ CMD_REMOVE_TRAIN_WAYPOINT = 18,
+
+ CMD_BUILD_ROAD_STOP = 21,
+ CMD_BUILD_LONG_ROAD = 23,
+ CMD_REMOVE_LONG_ROAD = 24,
+ CMD_BUILD_ROAD = 25,
+ CMD_REMOVE_ROAD = 26,
+ CMD_BUILD_ROAD_DEPOT = 27,
+
+ CMD_BUILD_AIRPORT = 29,
+
+ CMD_BUILD_DOCK = 30,
+
+ CMD_BUILD_SHIP_DEPOT = 31,
+ CMD_BUILD_BUOY = 32,
+
+ CMD_PLANT_TREE = 33,
+
+ CMD_BUILD_RAIL_VEHICLE = 34,
+ CMD_MOVE_RAIL_VEHICLE = 35,
+
+ CMD_START_STOP_TRAIN = 36,
+
+ CMD_SELL_RAIL_WAGON = 38,
+
+ CMD_SEND_TRAIN_TO_DEPOT = 39,
+ CMD_FORCE_TRAIN_PROCEED = 40,
+ CMD_REVERSE_TRAIN_DIRECTION = 41,
+
+ CMD_MODIFY_ORDER = 42,
+ CMD_SKIP_ORDER = 43,
+ CMD_DELETE_ORDER = 44,
+ CMD_INSERT_ORDER = 45,
+
+ CMD_CHANGE_SERVICE_INT = 46,
+
+ CMD_BUILD_INDUSTRY = 47,
+
+ CMD_BUILD_COMPANY_HQ = 48,
+ CMD_SET_PLAYER_FACE = 49,
+ CMD_SET_PLAYER_COLOR = 50,
+
+ CMD_INCREASE_LOAN = 51,
+ CMD_DECREASE_LOAN = 52,
+
+ CMD_WANT_ENGINE_PREVIEW = 53,
+
+ CMD_NAME_VEHICLE = 54,
+ CMD_RENAME_ENGINE = 55,
+ CMD_CHANGE_COMPANY_NAME = 56,
+ CMD_CHANGE_PRESIDENT_NAME = 57,
+ CMD_RENAME_STATION = 58,
+
+ CMD_SELL_AIRCRAFT = 59,
+ CMD_START_STOP_AIRCRAFT = 60,
+ CMD_BUILD_AIRCRAFT = 61,
+ CMD_SEND_AIRCRAFT_TO_HANGAR = 62,
+ CMD_REFIT_AIRCRAFT = 64,
+
+ CMD_PLACE_SIGN = 65,
+ CMD_RENAME_SIGN = 66,
+
+ CMD_BUILD_ROAD_VEH = 67,
+ CMD_START_STOP_ROADVEH = 68,
+ CMD_SELL_ROAD_VEH = 69,
+ CMD_SEND_ROADVEH_TO_DEPOT = 70,
+ CMD_TURN_ROADVEH = 71,
+ CMD_REFIT_ROAD_VEH = 72,
+
+ CMD_PAUSE = 73,
+
+ CMD_BUY_SHARE_IN_COMPANY = 74,
+ CMD_SELL_SHARE_IN_COMPANY = 75,
+ CMD_BUY_COMPANY = 76,
+
+ CMD_BUILD_TOWN = 77,
+
+ CMD_RENAME_TOWN = 80,
+ CMD_DO_TOWN_ACTION = 81,
+
+ CMD_SET_ROAD_DRIVE_SIDE = 82,
+
+ CMD_CHANGE_DIFFICULTY_LEVEL = 85,
+
+ CMD_START_STOP_SHIP = 86,
+ CMD_SELL_SHIP = 87,
+ CMD_BUILD_SHIP = 88,
+ CMD_SEND_SHIP_TO_DEPOT = 89,
+ CMD_REFIT_SHIP = 91,
+
+ CMD_ORDER_REFIT = 98,
+ CMD_CLONE_ORDER = 99,
+ CMD_CLEAR_AREA = 100,
+
+ CMD_MONEY_CHEAT = 102,
+ CMD_BUILD_CANAL = 103,
+
+ CMD_PLAYER_CTRL = 104, // used in multiplayer to create a new player etc.
+ CMD_LEVEL_LAND = 105, // level land
+
+ CMD_REFIT_RAIL_VEHICLE = 106,
+ CMD_RESTORE_ORDER_INDEX = 107,
+ CMD_BUILD_LOCK = 108,
+
+ CMD_BUILD_SIGNAL_TRACK = 110,
+ CMD_REMOVE_SIGNAL_TRACK = 111,
+
+ CMD_GIVE_MONEY = 113,
+ CMD_CHANGE_PATCH_SETTING = 114,
+
+ CMD_SET_AUTOREPLACE = 115,
+
+ CMD_CLONE_VEHICLE = 116,
+ CMD_MASS_START_STOP = 117,
+ CMD_DEPOT_SELL_ALL_VEHICLES = 118,
+ CMD_DEPOT_MASS_AUTOREPLACE = 119,
+};
+
+enum {
+ DC_EXEC = 0x01,
+ DC_AUTO = 0x02, // don't allow building on structures
+ DC_QUERY_COST = 0x04, // query cost only, don't build.
+ DC_NO_WATER = 0x08, // don't allow building on water
+ DC_NO_RAIL_OVERLAP = 0x10, // don't allow overlap of rails (used in buildrail)
+ DC_AI_BUILDING = 0x20, // special building rules for AI
+ DC_NO_TOWN_RATING = 0x40, // town rating does not disallow you from building
+ DC_FORCETEST = 0x80, // force test too.
+
+ CMD_ERROR = ((int32)0x80000000),
+};
+
+#define CMD_MSG(x) ((x)<<16)
+
+enum {
+ CMD_AUTO = 0x0200,
+ CMD_NO_WATER = 0x0400,
+ CMD_NETWORK_COMMAND = 0x0800, // execute the command without sending it on the network
+ CMD_NO_TEST_IF_IN_NETWORK = 0x1000, // When enabled, the command will bypass the no-DC_EXEC round if in network
+ CMD_SHOW_NO_ERROR = 0x2000,
+};
+
+/** Command flags for the command table
+ * @see _command_proc_table
+ */
+enum {
+ CMD_SERVER = 0x1, /// the command can only be initiated by the server
+ CMD_OFFLINE = 0x2, /// the command cannot be executed in a multiplayer game; single-player only
+};
+
+typedef int32 CommandProc(TileIndex tile, uint32 flags, uint32 p1, uint32 p2);
+
+typedef struct Command {
+ CommandProc *proc;
+ byte flags;
+} Command;
+
+//#define return_cmd_error(errcode) do { _error_message=(errcode); return CMD_ERROR; } while(0)
+#define return_cmd_error(errcode) do { return CMD_ERROR | (errcode); } while (0)
+
+/**
+ * Check the return value of a DoCommand*() function
+ * @param res the resulting value from the command to be checked
+ * @return Return true if the command failed, false otherwise
+ */
+static inline bool CmdFailed(int32 res)
+{
+ // lower 16bits are the StringID of the possible error
+ return res <= (CMD_ERROR | INVALID_STRING_ID);
+}
+
+/* command.c */
+typedef void CommandCallback(bool success, TileIndex tile, uint32 p1, uint32 p2);
+int32 DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc);
+bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, CommandCallback *callback, uint32 cmd);
+
+#ifdef ENABLE_NETWORK
+
+void NetworkSend_Command(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback);
+#endif /* ENABLE_NETWORK */
+
+extern const char* _cmd_text; // Text, which gets sent with a command
+
+bool IsValidCommand(uint cmd);
+byte GetCommandFlags(uint cmd);
+int32 GetAvailableMoneyForCommand(void);
+
+#endif /* COMMAND_H */
diff --git a/src/configure b/src/configure
new file mode 100755
index 000000000..2fd293954
--- /dev/null
+++ b/src/configure
@@ -0,0 +1,323 @@
+#!/bin/sh
+
+# This 'configure' script is a very easy wrapper around 'make updateconf'
+# It allows cross-compilers to do their job much more easy.
+
+function showhelp() {
+ echo "Configure for OpenTTD"
+ echo ""
+ echo "Usage:"
+ echo " $0 --your_options"
+ echo ""
+ echo "Params:"
+ echo " --debug Create debug-release [no]"
+ echo " --profile Create profile-release [no]"
+ echo " --dedicated Make a dedicated build [no]"
+ echo " --revision Set the revision of the compilation [detected]"
+ echo " --target-cc Sets the target-compiler [\$CC]"
+ echo " --target-cxx Sets the C++ target-compiler []"
+ echo " --host-cc Sets the host-compiler [\$CC]"
+ echo " --host-cxx Sets the C++ host-compiler []"
+ echo " --os Sets the OS. Listens to: [detected]"
+ echo " UNIX, OSX, FREEBSD, MORPHOS"
+ echo " BEOS, SUNOS, CYGWIN, MINGW, OS2"
+ echo " --windres Sets the windres (Windows) [windres]"
+ echo " --force-le Force LE platform [no]"
+ echo " --force-be Force BE platform [no]"
+ echo ""
+ echo "Params that can be used with --with or --without"
+ echo " (e.g.: --without-static disables static (default))"
+ echo " static Do you want a static build? [no]"
+ echo " directmusic Do you want direct-music? [no]"
+ echo " zlib Do you want zlib-support? [yes]"
+ echo " sdl Do you want SDL-support? [yes]"
+ echo " png Do you want PNG-support? [yes]"
+ echo " iconv Do you want iconv-support? [no]"
+ echo " network Do you want network-support? [yes]"
+ echo " cocoa Do you want cocoa-support? (MacOSX) [no]"
+ echo " freetype Do you want freetype-support? [yes]"
+ echo " fontconfig Do you want fontconfig-support? [yes]"
+ echo ""
+ echo "Params used to configure external libs:"
+ echo " --static-zlib-path Set the path to your static zlib []"
+ echo " --sdl-config Where is your sdl-config [sdl-config]"
+ echo " --libpng-config Where is your libpng-config [libpng-config]"
+ echo " --freetype-config Where is your freetype-config [freetype-config]"
+ echo " --fontconfig-config Where is your fontconfig-config [pkg-config fontconfig]"
+ echo " --with-iconv Set the path to your iconv headers []"
+ echo " "
+}
+
+function handle() {
+ PARAM="$PARAM \"$1=`awk 'BEGIN { FS="="; $0="'"$2"'"; print $2;}'`\""
+}
+
+# The things you can use inside this case:
+# handle NAME VALUE - Sets the value to give the 'make upgradeconf'
+# Value is in form: tag=REAL_VALUE
+# ITEM="NAME" - Will set the value as above, only with the next param
+# SITEM="NAME" - Will set the var $NAME to the next param
+for n in "$@"
+do
+ case "$n" in
+ --help | -h)
+ showhelp
+ exit 0
+ ;;
+
+ --debug)
+ DEBUG_SET=1
+ ITEM="DEBUG"
+ ;;
+ --debug=*)
+ handle "DEBUG" "$n"
+ ;;
+ --profile)
+ PARAM="$PARAM PROFILE=1"
+ ;;
+ --dedicated)
+ PARAM="$PARAM DEDICATED=1"
+ ;;
+ --revision=*)
+ RELEASE=`awk 'BEGIN { FS="="; $0="'"$n"'"; print $2;}'`
+ ;;
+ --revision)
+ SITEM="RELEASE"
+ ;;
+ --target-cc=*)
+ handle "CC_TARGET" "$n"
+ ;;
+ --target-cc)
+ ITEM="CC_TARGET"
+ ;;
+ --target-cxx=*)
+ handle "CXX_TARGET" "$n"
+ ;;
+ --target-cxx)
+ SITEM="CXX_TARGET"
+ ;;
+ --host-cc=*)
+ handle "CC_HOST" "$n"
+ ;;
+ --host-cc)
+ ITEM="CC_HOST"
+ ;;
+ --host-cxx=*)
+ handle "CXX_HOST" "$n"
+ ;;
+ --host-cxx)
+ ITEM="CXX_HOST"
+ ;;
+ --host-cflags=*)
+ handle CFLAGS_HOST "$n"
+ ;;
+ --host-cflags)
+ ITEM="CFLAGS_HOST"
+ ;;
+ --os=*)
+ TARGET_OS=`awk 'BEGIN { FS="="; $0="'"$n"'"; print $2;}'`
+ ;;
+ --os)
+ SITEM="TARGET_OS"
+ ;;
+ --windres=*)
+ handle WINDRES "$n"
+ ;;
+ --windres)
+ ITEM="WINDRES"
+ ;;
+ --force-le)
+ PARAM="$PARAM ENDIAN_FORCE=LE"
+ ;;
+ --force-be)
+ PARAM="$PARAM ENDIAN_FORCE=BE"
+ ;;
+
+ --with-static)
+ PARAM="$PARAM STATIC=1"
+ ;;
+ --without-static)
+ PARAM="$PARAM STATIC="
+ ;;
+ --with-directmusic)
+ PARAM="$PARAM WITH_DIRECTMUSIC=1"
+ ;;
+ --without-directmusic)
+ PARAM="$PARAM WITH_DIRECTMUSIC="
+ ;;
+ --with-zlib)
+ PARAM="$PARAM WITH_ZLIB=1"
+ ;;
+ --without-zlib)
+ PARAM="$PARAM WITH_ZLIB="
+ ;;
+ --with-sdl)
+ PARAM="$PARAM WITH_SDL=1"
+ ;;
+ --without-sdl)
+ PARAM="$PARAM WITH_SDL="
+ ;;
+ --with-png)
+ PARAM="$PARAM WITH_PNG=1"
+ ;;
+ --without-png)
+ PARAM="$PARAM WITH_PNG="
+ ;;
+ --with-iconv)
+ PARAM="$PARAM WITH_ICONV=1"
+ ;;
+ --with-iconv=*)
+ PARAM="$PARAM WITH_ICONV=1"
+ handle WITH_ICONV_PATH "$n"
+ ;;
+ --without-iconv)
+ PARAM="$PARAM WITH_ICONV="
+ ;;
+ --with-cocoa)
+ PARAM="$PARAM WITH_COCOA=1"
+ ;;
+ --with-network)
+ PARAM="$PARAM WITH_NETWORK=1"
+ ;;
+ --without-network)
+ PARAM="$PARAM WITH_NETWORK="
+ ;;
+ --without-cocoa)
+ PARAM="$PARAM WITH_COCOA="
+ ;;
+ --with-freetype)
+ PARAM="$PARAM WITH_FREETYPE=1"
+ ;;
+ --without-freetype)
+ PARAM="$PARAM WITH_FREETYPE="
+ ;;
+ --with-fontconfig)
+ PARAM="$PARAM WITH_FONTCONFIG=1"
+ ;;
+ --without-fontconfig)
+ PARAM="$PARAM WITH_FONTCONFIG="
+ ;;
+ --static-zlib-path=*)
+ handle STATIC_ZLIB_PATH "$n"
+ ;;
+ --static-zlib-path)
+ ITEM="STATIC_ZLIB_PATH"
+ ;;
+ --sdl-config=*)
+ handle SDL_CONFIG "$n"
+ ;;
+ --sdl-config)
+ ITEM="SDL_CONFIG"
+ ;;
+ --libpng-config=*)
+ handle LIBPNG_CONFIG "$n"
+ ;;
+ --libpng-config)
+ ITEM="LIBPNG_CONFIG"
+ ;;
+ --freetype-config=*)
+ handle FREETYPE_CONFIG "$n"
+ ;;
+ --freetype-config)
+ ITEM="FREETYPE_CONFIG"
+ ;;
+ --fontconfig-config=*)
+ handle FONTCONFIG_CONFIG "$n"
+ ;;
+ --fontconfig-config)
+ ITEM="FONTCONFIG_CONFIG"
+ ;;
+
+ --*=*)
+ echo -n "Unknown switch "
+ echo `awk 'BEGIN { FS="="; $0="'"$n"'"; print $1;}'`
+ exit 1
+ ;;
+ -*)
+ echo "Unknown switch $n"
+ exit 1
+ ;;
+
+ *)
+ if ! test -z "$ITEM"
+ then
+ PARAM="$PARAM $ITEM=\"$n\""
+ ITEM="";
+ elif ! test -z "$SITEM"
+ then
+ export $SITEM="$n"
+ SITEM=""
+ else
+ echo "Unknown switch $n"
+ exit 1
+ fi
+ ;;
+ esac
+done
+
+if ! test -z "$TARGET_OS"
+then
+ TARGET_OS=`echo $TARGET_OS | tr '[:lower:]' '[:upper:]'`
+ case "$TARGET_OS" in
+ WIN32)
+ PARAM="$PARAM WIN32=1"
+ ;;
+ UNIX)
+ PARAM="$PARAM UNIX=1"
+ ;;
+ OSX)
+ PARAM="$PARAM OSX=1 UNIX=1"
+ ;;
+ FREEBSD)
+ PARAM="$PARAM FREEBSD=1"
+ ;;
+ MORPHOS)
+ PARAM="$PARAM MORPHOS=1 UNIX=1"
+ ;;
+ BEOS)
+ PARAM="$PARAM BEOS=1 UNIX=1"
+ ;;
+ OS2)
+ PARAM="$PARAM OS2=1 UNIX=1"
+ ;;
+ SUNOS)
+ PARAM="$PARAM SUNOS=1 UNIX=1"
+ ;;
+ CYGWIN)
+ PARAM="$PARAM CYGWIN=1 WIN32=1"
+ ;;
+ MINGW)
+ PARAM="$PARAM MINGW=1 WIN32=1"
+ ;;
+ *)
+ echo "Unknown OS: $TARGET_OS"
+ exit 1
+ ;;
+ esac
+ PARAM="$PARAM BYPASS_OS_DETECT=1"
+fi
+
+if ! test -z "$DEBUG_SET"
+then
+ if test -z "`echo $PARAM | grep "DEBUG="`"
+ then
+ # Someone did --debug, without assigning a value, assume 1
+ PARAM="$PARAM DEBUG=1"
+ fi
+fi
+
+# First remove the Makefile.config, else you can have double entries
+rm -f Makefile.config
+
+echo "make upgradeconf $PARAM" > Makefile.run
+. Makefile.run
+rm -f Makefile.run
+
+# Makefile.config currently doesn't support custom RELEASE (revision), so, we add the line
+# yourself!
+
+if ! test -z "$RELEASE"
+then
+ echo "RELEASE=$RELEASE" >> Makefile.config
+fi
+
diff --git a/src/console.c b/src/console.c
new file mode 100644
index 000000000..07d218130
--- /dev/null
+++ b/src/console.c
@@ -0,0 +1,1150 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "table/strings.h"
+#include "functions.h"
+#include "window.h"
+#include "gui.h"
+#include "gfx.h"
+#include "player.h"
+#include "variables.h"
+#include "string.h"
+#include <stdarg.h>
+#include <string.h>
+#include "console.h"
+#include "network/network.h"
+#include "network/network_data.h"
+#include "network/network_server.h"
+
+#define ICON_BUFFER 79
+#define ICON_HISTORY_SIZE 20
+#define ICON_LINE_HEIGHT 12
+#define ICON_RIGHT_BORDERWIDTH 10
+#define ICON_BOTTOM_BORDERWIDTH 12
+#define ICON_MAX_ALIAS_LINES 40
+#define ICON_TOKEN_COUNT 20
+
+// ** main console ** //
+static char *_iconsole_buffer[ICON_BUFFER + 1];
+static uint16 _iconsole_cbuffer[ICON_BUFFER + 1];
+static Textbuf _iconsole_cmdline;
+
+// ** stdlib ** //
+byte _stdlib_developer = 1;
+bool _stdlib_con_developer = false;
+FILE *_iconsole_output_file;
+
+// ** main console cmd buffer
+static char *_iconsole_history[ICON_HISTORY_SIZE];
+static byte _iconsole_historypos;
+
+/* *************** */
+/* end of header */
+/* *************** */
+
+static void IConsoleClearCommand(void)
+{
+ memset(_iconsole_cmdline.buf, 0, ICON_CMDLN_SIZE);
+ _iconsole_cmdline.length = 0;
+ _iconsole_cmdline.width = 0;
+ _iconsole_cmdline.caretpos = 0;
+ _iconsole_cmdline.caretxoffs = 0;
+ SetWindowDirty(FindWindowById(WC_CONSOLE, 0));
+}
+
+static inline void IConsoleResetHistoryPos(void) {_iconsole_historypos = ICON_HISTORY_SIZE - 1;}
+
+
+static void IConsoleHistoryAdd(const char *cmd);
+static void IConsoleHistoryNavigate(int direction);
+
+// ** console window ** //
+static void IConsoleWndProc(Window *w, WindowEvent *e)
+{
+ static byte iconsole_scroll = ICON_BUFFER;
+
+ switch (e->event) {
+ case WE_PAINT: {
+ int i = iconsole_scroll;
+ int max = (w->height / ICON_LINE_HEIGHT) - 1;
+ int delta = 0;
+ GfxFillRect(w->left, w->top, w->width, w->height - 1, 0);
+ while ((i > 0) && (i > iconsole_scroll - max) && (_iconsole_buffer[i] != NULL)) {
+ DoDrawString(_iconsole_buffer[i], 5,
+ w->height - (iconsole_scroll + 2 - i) * ICON_LINE_HEIGHT, _iconsole_cbuffer[i]);
+ i--;
+ }
+ /* If the text is longer than the window, don't show the starting ']' */
+ delta = w->width - 10 - _iconsole_cmdline.width - ICON_RIGHT_BORDERWIDTH;
+ if (delta > 0) {
+ DoDrawString("]", 5, w->height - ICON_LINE_HEIGHT, _icolour_cmd);
+ delta = 0;
+ }
+
+ DoDrawString(_iconsole_cmdline.buf, 10 + delta, w->height - ICON_LINE_HEIGHT, _icolour_cmd);
+
+ if (_iconsole_cmdline.caret)
+ DoDrawString("_", 10 + delta + _iconsole_cmdline.caretxoffs, w->height - ICON_LINE_HEIGHT, 12);
+ break;
+ }
+ case WE_MOUSELOOP:
+ if (HandleCaret(&_iconsole_cmdline))
+ SetWindowDirty(w);
+ break;
+ case WE_DESTROY:
+ _iconsole_mode = ICONSOLE_CLOSED;
+ break;
+ case WE_KEYPRESS:
+ e->we.keypress.cont = false;
+ switch (e->we.keypress.keycode) {
+ case WKC_UP:
+ IConsoleHistoryNavigate(+1);
+ SetWindowDirty(w);
+ break;
+ case WKC_DOWN:
+ IConsoleHistoryNavigate(-1);
+ SetWindowDirty(w);
+ break;
+ case WKC_SHIFT | WKC_PAGEUP:
+ if (iconsole_scroll - (w->height / ICON_LINE_HEIGHT) - 1 < 0) {
+ iconsole_scroll = 0;
+ } else {
+ iconsole_scroll -= (w->height / ICON_LINE_HEIGHT) - 1;
+ }
+ SetWindowDirty(w);
+ break;
+ case WKC_SHIFT | WKC_PAGEDOWN:
+ if (iconsole_scroll + (w->height / ICON_LINE_HEIGHT) - 1 > ICON_BUFFER) {
+ iconsole_scroll = ICON_BUFFER;
+ } else {
+ iconsole_scroll += (w->height / ICON_LINE_HEIGHT) - 1;
+ }
+ SetWindowDirty(w);
+ break;
+ case WKC_SHIFT | WKC_UP:
+ if (iconsole_scroll <= 0) {
+ iconsole_scroll = 0;
+ } else {
+ --iconsole_scroll;
+ }
+ SetWindowDirty(w);
+ break;
+ case WKC_SHIFT | WKC_DOWN:
+ if (iconsole_scroll >= ICON_BUFFER) {
+ iconsole_scroll = ICON_BUFFER;
+ } else {
+ ++iconsole_scroll;
+ }
+ SetWindowDirty(w);
+ break;
+ case WKC_BACKQUOTE:
+ IConsoleSwitch();
+ break;
+ case WKC_RETURN: case WKC_NUM_ENTER:
+ IConsolePrintF(_icolour_cmd, "] %s", _iconsole_cmdline.buf);
+ IConsoleHistoryAdd(_iconsole_cmdline.buf);
+
+ IConsoleCmdExec(_iconsole_cmdline.buf);
+ IConsoleClearCommand();
+ break;
+ case WKC_CTRL | WKC_RETURN:
+ _iconsole_mode = (_iconsole_mode == ICONSOLE_FULL) ? ICONSOLE_OPENED : ICONSOLE_FULL;
+ IConsoleResize(w);
+ MarkWholeScreenDirty();
+ break;
+ case (WKC_CTRL | 'V'):
+ if (InsertTextBufferClipboard(&_iconsole_cmdline)) {
+ IConsoleResetHistoryPos();
+ SetWindowDirty(w);
+ }
+ break;
+ case (WKC_CTRL | 'L'):
+ IConsoleCmdExec("clear");
+ break;
+ case (WKC_CTRL | 'U'):
+ DeleteTextBufferAll(&_iconsole_cmdline);
+ SetWindowDirty(w);
+ break;
+ case WKC_BACKSPACE: case WKC_DELETE:
+ if (DeleteTextBufferChar(&_iconsole_cmdline, e->we.keypress.keycode)) {
+ IConsoleResetHistoryPos();
+ SetWindowDirty(w);
+ }
+ break;
+ case WKC_LEFT: case WKC_RIGHT: case WKC_END: case WKC_HOME:
+ if (MoveTextBufferPos(&_iconsole_cmdline, e->we.keypress.keycode)) {
+ IConsoleResetHistoryPos();
+ SetWindowDirty(w);
+ }
+ break;
+ default:
+ if (IsValidChar(e->we.keypress.key, CS_ALPHANUMERAL)) {
+ iconsole_scroll = ICON_BUFFER;
+ InsertTextBufferChar(&_iconsole_cmdline, e->we.keypress.key);
+ IConsoleResetHistoryPos();
+ SetWindowDirty(w);
+ } else {
+ e->we.keypress.cont = true;
+ }
+ break;
+ }
+ }
+}
+
+static const Widget _iconsole_window_widgets[] = {
+ {WIDGETS_END}
+};
+
+static const WindowDesc _iconsole_window_desc = {
+ 0, 0, 2, 2,
+ WC_CONSOLE, 0,
+ WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _iconsole_window_widgets,
+ IConsoleWndProc,
+};
+
+void IConsoleInit(void)
+{
+ extern const char _openttd_revision[];
+ _iconsole_output_file = NULL;
+ _icolour_def = 1;
+ _icolour_err = 3;
+ _icolour_warn = 13;
+ _icolour_dbg = 5;
+ _icolour_cmd = 2;
+ _iconsole_historypos = ICON_HISTORY_SIZE - 1;
+ _iconsole_mode = ICONSOLE_CLOSED;
+
+#ifdef ENABLE_NETWORK /* Initialize network only variables */
+ _redirect_console_to_client = 0;
+#endif
+
+ memset(_iconsole_history, 0, sizeof(_iconsole_history));
+ memset(_iconsole_buffer, 0, sizeof(_iconsole_buffer));
+ memset(_iconsole_cbuffer, 0, sizeof(_iconsole_cbuffer));
+ _iconsole_cmdline.buf = calloc(ICON_CMDLN_SIZE, sizeof(*_iconsole_cmdline.buf)); // create buffer and zero it
+ _iconsole_cmdline.maxlength = ICON_CMDLN_SIZE;
+
+ IConsolePrintF(13, "OpenTTD Game Console Revision 7 - %s", _openttd_revision);
+ IConsolePrint(12, "------------------------------------");
+ IConsolePrint(12, "use \"help\" for more information");
+ IConsolePrint(12, "");
+ IConsoleStdLibRegister();
+ IConsoleClearCommand();
+ IConsoleHistoryAdd("");
+}
+
+void IConsoleClearBuffer(void)
+{
+ uint i;
+ for (i = 0; i <= ICON_BUFFER; i++) {
+ free(_iconsole_buffer[i]);
+ _iconsole_buffer[i] = NULL;
+ }
+}
+
+static void IConsoleClear(void)
+{
+ free(_iconsole_cmdline.buf);
+ IConsoleClearBuffer();
+}
+
+static void IConsoleWriteToLogFile(const char *string)
+{
+ if (_iconsole_output_file != NULL) {
+ // if there is an console output file ... also print it there
+ fwrite(string, strlen(string), 1, _iconsole_output_file);
+ fwrite("\n", 1, 1, _iconsole_output_file);
+ }
+}
+
+bool CloseConsoleLogIfActive(void)
+{
+ if (_iconsole_output_file != NULL) {
+ IConsolePrintF(_icolour_def, "file output complete");
+ fclose(_iconsole_output_file);
+ _iconsole_output_file = NULL;
+ return true;
+ }
+
+ return false;
+}
+
+void IConsoleFree(void)
+{
+ IConsoleClear();
+ CloseConsoleLogIfActive();
+}
+
+void IConsoleResize(Window *w)
+{
+ switch (_iconsole_mode) {
+ case ICONSOLE_OPENED:
+ w->height = _screen.height / 3;
+ w->width = _screen.width;
+ break;
+ case ICONSOLE_FULL:
+ w->height = _screen.height - ICON_BOTTOM_BORDERWIDTH;
+ w->width = _screen.width;
+ break;
+ default: return;
+ }
+
+ MarkWholeScreenDirty();
+}
+
+void IConsoleSwitch(void)
+{
+ switch (_iconsole_mode) {
+ case ICONSOLE_CLOSED: {
+ Window *w = AllocateWindowDesc(&_iconsole_window_desc);
+ w->height = _screen.height / 3;
+ w->width = _screen.width;
+ _iconsole_mode = ICONSOLE_OPENED;
+ SETBIT(_no_scroll, SCROLL_CON); // override cursor arrows; the gamefield will not scroll
+ } break;
+ case ICONSOLE_OPENED: case ICONSOLE_FULL:
+ DeleteWindowById(WC_CONSOLE, 0);
+ _iconsole_mode = ICONSOLE_CLOSED;
+ CLRBIT(_no_scroll, SCROLL_CON);
+ break;
+ }
+
+ MarkWholeScreenDirty();
+}
+
+void IConsoleClose(void) {if (_iconsole_mode == ICONSOLE_OPENED) IConsoleSwitch();}
+void IConsoleOpen(void) {if (_iconsole_mode == ICONSOLE_CLOSED) IConsoleSwitch();}
+
+/**
+ * Add the entered line into the history so you can look it back
+ * scroll, etc. Put it to the beginning as it is the latest text
+ * @param cmd Text to be entered into the 'history'
+ */
+static void IConsoleHistoryAdd(const char *cmd)
+{
+ free(_iconsole_history[ICON_HISTORY_SIZE - 1]);
+
+ memmove(&_iconsole_history[1], &_iconsole_history[0], sizeof(_iconsole_history[0]) * (ICON_HISTORY_SIZE - 1));
+ _iconsole_history[0] = strdup(cmd);
+ IConsoleResetHistoryPos();
+}
+
+/**
+ * Navigate Up/Down in the history of typed commands
+ * @param direction Go further back in history (+1), go to recently typed commands (-1)
+ */
+static void IConsoleHistoryNavigate(int direction)
+{
+ int i = _iconsole_historypos + direction;
+
+ // watch out for overflows, just wrap around
+ if (i < 0) i = ICON_HISTORY_SIZE - 1;
+ if (i >= ICON_HISTORY_SIZE) i = 0;
+
+ if (direction > 0)
+ if (_iconsole_history[i] == NULL) i = 0;
+
+ if (direction < 0) {
+ while (i > 0 && _iconsole_history[i] == NULL) i--;
+ }
+
+ _iconsole_historypos = i;
+ IConsoleClearCommand();
+ // copy history to 'command prompt / bash'
+ assert(_iconsole_history[i] != NULL && IS_INT_INSIDE(i, 0, ICON_HISTORY_SIZE));
+ ttd_strlcpy(_iconsole_cmdline.buf, _iconsole_history[i], _iconsole_cmdline.maxlength);
+ UpdateTextBufferSize(&_iconsole_cmdline);
+}
+
+/**
+ * Handle the printing of text entered into the console or redirected there
+ * by any other means. Text can be redirected to other players in a network game
+ * as well as to a logfile. If the network server is a dedicated server, all activities
+ * are also logged. All lines to print are added to a temporary buffer which can be
+ * used as a history to print them onscreen
+ * @param color_code the colour of the command. Red in case of errors, etc.
+ * @param string the message entered or output on the console (notice, error, etc.)
+ */
+void IConsolePrint(uint16 color_code, const char *string)
+{
+ char *str;
+#ifdef ENABLE_NETWORK
+ if (_redirect_console_to_client != 0) {
+ /* Redirect the string to the client */
+ SEND_COMMAND(PACKET_SERVER_RCON)(NetworkFindClientStateFromIndex(_redirect_console_to_client), color_code, string);
+ return;
+ }
+#endif
+
+ /* Create a copy of the string, strip if of colours and invalid
+ * characters and (when applicable) assign it to the console buffer */
+ str = strdup(string);
+ str_strip_colours(str);
+ str_validate(str);
+
+ if (_network_dedicated) {
+ printf("%s\n", str);
+ IConsoleWriteToLogFile(str);
+ free(str); // free duplicated string since it's not used anymore
+ return;
+ }
+
+ /* move up all the strings in the buffer one place and do the same for colour
+ * to accomodate for the new command/message */
+ free(_iconsole_buffer[0]);
+ memmove(&_iconsole_buffer[0], &_iconsole_buffer[1], sizeof(_iconsole_buffer[0]) * ICON_BUFFER);
+ _iconsole_buffer[ICON_BUFFER] = str;
+
+ memmove(&_iconsole_cbuffer[0], &_iconsole_cbuffer[1], sizeof(_iconsole_cbuffer[0]) * ICON_BUFFER);
+ _iconsole_cbuffer[ICON_BUFFER] = color_code;
+
+ IConsoleWriteToLogFile(_iconsole_buffer[ICON_BUFFER]);
+
+ SetWindowDirty(FindWindowById(WC_CONSOLE, 0));
+}
+
+/**
+ * Handle the printing of text entered into the console or redirected there
+ * by any other means. Uses printf() style format, for more information look
+ * at @IConsolePrint()
+ */
+void CDECL IConsolePrintF(uint16 color_code, const char *s, ...)
+{
+ va_list va;
+ char buf[ICON_MAX_STREAMSIZE];
+
+ va_start(va, s);
+ vsnprintf(buf, sizeof(buf), s, va);
+ va_end(va);
+
+ IConsolePrint(color_code, buf);
+}
+
+/**
+ * It is possible to print debugging information to the console,
+ * which is achieved by using this function. Can only be used by
+ * @debug() in debug.c. You need at least a level 2 (developer) for debugging
+ * messages to show up
+ * @param dbg debugging category
+ * @param string debugging message
+ */
+void IConsoleDebug(const char *dbg, const char *string)
+{
+ if (_stdlib_developer > 1)
+ IConsolePrintF(_icolour_dbg, "dbg: [%s] %s", dbg, string);
+}
+
+/**
+ * It is possible to print warnings to the console. These are mostly
+ * errors or mishaps, but non-fatal. You need at least a level 1 (developer) for
+ * debugging messages to show up
+ */
+void IConsoleWarning(const char *string)
+{
+ if (_stdlib_developer > 0)
+ IConsolePrintF(_icolour_warn, "WARNING: %s", string);
+}
+
+/**
+ * It is possible to print error information to the console. This can include
+ * game errors, or errors in general you would want the user to notice
+ */
+void IConsoleError(const char *string)
+{
+ IConsolePrintF(_icolour_err, "ERROR: %s", string);
+}
+
+/**
+ * Change a string into its number representation. Supports
+ * decimal and hexadecimal numbers as well as 'on'/'off' 'true'/'false'
+ * @param *value the variable a successfull conversion will be put in
+ * @param *arg the string to be converted
+ * @return Return true on success or false on failure
+ */
+bool GetArgumentInteger(uint32 *value, const char *arg)
+{
+ char *endptr;
+
+ if (strcmp(arg, "on") == 0 || strcmp(arg, "true") == 0) {
+ *value = 1;
+ return true;
+ }
+ if (strcmp(arg, "off") == 0 || strcmp(arg, "false") == 0) {
+ *value = 0;
+ return true;
+ }
+
+ *value = strtoul(arg, &endptr, 0);
+ return arg != endptr;
+}
+
+// * ************************* * //
+// * hooking code * //
+// * ************************* * //
+/**
+ * General internal hooking code that is the same for both commands and variables
+ * @param hooks @IConsoleHooks structure that will be set according to
+ * @param type type access trigger
+ * @param proc function called when the hook criteria is met
+ */
+static void IConsoleHookAdd(IConsoleHooks *hooks, IConsoleHookTypes type, IConsoleHook *proc)
+{
+ if (hooks == NULL || proc == NULL) return;
+
+ switch (type) {
+ case ICONSOLE_HOOK_ACCESS:
+ hooks->access = proc;
+ break;
+ case ICONSOLE_HOOK_PRE_ACTION:
+ hooks->pre = proc;
+ break;
+ case ICONSOLE_HOOK_POST_ACTION:
+ hooks->post = proc;
+ break;
+ default: NOT_REACHED();
+ }
+}
+
+/**
+ * Handle any special hook triggers. If the hook type is met check if
+ * there is a function associated with that and if so, execute it
+ * @param hooks @IConsoleHooks structure that will be checked
+ * @param type type of hook, trigger that needs to be activated
+ * @return true on a successfull execution of the hook command or if there
+ * is no hook/trigger present at all. False otherwise
+ */
+static bool IConsoleHookHandle(const IConsoleHooks *hooks, IConsoleHookTypes type)
+{
+ IConsoleHook *proc = NULL;
+ if (hooks == NULL) return false;
+
+ switch (type) {
+ case ICONSOLE_HOOK_ACCESS:
+ proc = hooks->access;
+ break;
+ case ICONSOLE_HOOK_PRE_ACTION:
+ proc = hooks->pre;
+ break;
+ case ICONSOLE_HOOK_POST_ACTION:
+ proc = hooks->post;
+ break;
+ default: NOT_REACHED();
+ }
+
+ return (proc == NULL) ? true : proc();
+}
+
+/**
+ * Add a hook to a command that will be triggered at certain points
+ * @param name name of the command that the hook is added to
+ * @param type type of hook that is added (ACCESS, BEFORE and AFTER change)
+ * @param proc function called when the hook criteria is met
+ */
+void IConsoleCmdHookAdd(const char *name, IConsoleHookTypes type, IConsoleHook *proc)
+{
+ IConsoleCmd *cmd = IConsoleCmdGet(name);
+ if (cmd == NULL) return;
+ IConsoleHookAdd(&cmd->hook, type, proc);
+}
+
+/**
+ * Add a hook to a variable that will be triggered at certain points
+ * @param name name of the variable that the hook is added to
+ * @param type type of hook that is added (ACCESS, BEFORE and AFTER change)
+ * @param proc function called when the hook criteria is met
+ */
+void IConsoleVarHookAdd(const char *name, IConsoleHookTypes type, IConsoleHook *proc)
+{
+ IConsoleVar *var = IConsoleVarGet(name);
+ if (var == NULL) return;
+ IConsoleHookAdd(&var->hook, type, proc);
+}
+
+/**
+ * Perhaps ugly macro, but this saves us the trouble of writing the same function
+ * three types, just with different variables. Yes, templates would be handy. It was
+ * either this define or an even more ugly void* magic function
+ */
+#define IConsoleAddSorted(_base, item_new, IConsoleType, type) \
+{ \
+ IConsoleType *item, *item_before; \
+ /* first command */ \
+ if (_base == NULL) { \
+ _base = item_new; \
+ return; \
+ } \
+ \
+ item_before = NULL; \
+ item = _base; \
+ \
+ /* BEGIN - Alphabetically insert the commands into the linked list */ \
+ while (item != NULL) { \
+ int i = strcmp(item->name, item_new->name); \
+ if (i == 0) { \
+ IConsoleError(type " with this name already exists; insertion aborted"); \
+ free(item_new); \
+ return; \
+ } \
+ \
+ if (i > 0) break; /* insert at this position */ \
+ \
+ item_before = item; \
+ item = item->next; \
+ } \
+ \
+ if (item_before == NULL) { \
+ _base = item_new; \
+ } else { \
+ item_before->next = item_new; \
+ } \
+ \
+ item_new->next = item; \
+ /* END - Alphabetical insert */ \
+}
+
+/**
+ * Register a new command to be used in the console
+ * @param name name of the command that will be used
+ * @param proc function that will be called upon execution of command
+ */
+void IConsoleCmdRegister(const char *name, IConsoleCmdProc *proc)
+{
+ char *new_cmd = strdup(name);
+ IConsoleCmd *item_new = malloc(sizeof(IConsoleCmd));
+
+ item_new->next = NULL;
+ item_new->proc = proc;
+ item_new->name = new_cmd;
+
+ item_new->hook.access = NULL;
+ item_new->hook.pre = NULL;
+ item_new->hook.post = NULL;
+
+ IConsoleAddSorted(_iconsole_cmds, item_new, IConsoleCmd, "a command");
+}
+
+/**
+ * Find the command pointed to by its string
+ * @param name command to be found
+ * @return return Cmdstruct of the found command, or NULL on failure
+ */
+IConsoleCmd *IConsoleCmdGet(const char *name)
+{
+ IConsoleCmd *item;
+
+ for (item = _iconsole_cmds; item != NULL; item = item->next) {
+ if (strcmp(item->name, name) == 0) return item;
+ }
+ return NULL;
+}
+
+/**
+ * Register a an alias for an already existing command in the console
+ * @param name name of the alias that will be used
+ * @param cmd name of the command that 'name' will be alias of
+ */
+void IConsoleAliasRegister(const char *name, const char *cmd)
+{
+ char *new_alias = strdup(name);
+ char *cmd_aliased = strdup(cmd);
+ IConsoleAlias *item_new = malloc(sizeof(IConsoleAlias));
+
+ item_new->next = NULL;
+ item_new->cmdline = cmd_aliased;
+ item_new->name = new_alias;
+
+ IConsoleAddSorted(_iconsole_aliases, item_new, IConsoleAlias, "an alias");
+}
+
+/**
+ * Find the alias pointed to by its string
+ * @param name alias to be found
+ * @return return Aliasstruct of the found alias, or NULL on failure
+ */
+IConsoleAlias *IConsoleAliasGet(const char *name)
+{
+ IConsoleAlias* item;
+
+ for (item = _iconsole_aliases; item != NULL; item = item->next) {
+ if (strcmp(item->name, name) == 0) return item;
+ }
+
+ return NULL;
+}
+
+/** copy in an argument into the aliasstream */
+static inline int IConsoleCopyInParams(char *dst, const char *src, uint bufpos)
+{
+ int len = min(ICON_MAX_STREAMSIZE - bufpos, (uint)strlen(src));
+ strncpy(dst, src, len);
+
+ return len;
+}
+
+/**
+ * An alias is just another name for a command, or for more commands
+ * Execute it as well.
+ * @param *alias is the alias of the command
+ * @param tokencount the number of parameters passed
+ * @param *tokens are the parameters given to the original command (0 is the first param)
+ */
+static void IConsoleAliasExec(const IConsoleAlias *alias, byte tokencount, char *tokens[ICON_TOKEN_COUNT])
+{
+ const char *cmdptr;
+ char *aliases[ICON_MAX_ALIAS_LINES], aliasstream[ICON_MAX_STREAMSIZE];
+ uint i;
+ uint a_index, astream_i;
+
+ memset(&aliases, 0, sizeof(aliases));
+ memset(&aliasstream, 0, sizeof(aliasstream));
+
+ if (_stdlib_con_developer)
+ IConsolePrintF(_icolour_dbg, "condbg: requested command is an alias; parsing...");
+
+ aliases[0] = aliasstream;
+ for (cmdptr = alias->cmdline, a_index = 0, astream_i = 0; *cmdptr != '\0'; cmdptr++) {
+ if (a_index >= lengthof(aliases) || astream_i >= lengthof(aliasstream)) break;
+
+ switch (*cmdptr) {
+ case '\'': /* ' will double for "" */
+ aliasstream[astream_i++] = '"';
+ break;
+ case ';': /* Cmd seperator, start new command */
+ aliasstream[astream_i] = '\0';
+ aliases[++a_index] = &aliasstream[++astream_i];
+ cmdptr++;
+ break;
+ case '%': /* Some or all parameters */
+ cmdptr++;
+ switch (*cmdptr) {
+ case '+': { /* All parameters seperated: "[param 1]" "[param 2]" */
+ for (i = 0; i != tokencount; i++) {
+ aliasstream[astream_i++] = '"';
+ astream_i += IConsoleCopyInParams(&aliasstream[astream_i], tokens[i], astream_i);
+ aliasstream[astream_i++] = '"';
+ aliasstream[astream_i++] = ' ';
+ }
+ } break;
+ case '!': { /* Merge the parameters to one: "[param 1] [param 2] [param 3...]" */
+ aliasstream[astream_i++] = '"';
+ for (i = 0; i != tokencount; i++) {
+ astream_i += IConsoleCopyInParams(&aliasstream[astream_i], tokens[i], astream_i);
+ aliasstream[astream_i++] = ' ';
+ }
+ aliasstream[astream_i++] = '"';
+
+ } break;
+ default: { /* One specific parameter: %A = [param 1] %B = [param 2] ... */
+ int param = *cmdptr - 'A';
+
+ if (param < 0 || param >= tokencount) {
+ IConsoleError("too many or wrong amount of parameters passed to alias, aborting");
+ IConsolePrintF(_icolour_warn, "Usage of alias '%s': %s", alias->name, alias->cmdline);
+ return;
+ }
+
+ aliasstream[astream_i++] = '"';
+ astream_i += IConsoleCopyInParams(&aliasstream[astream_i], tokens[param], astream_i);
+ aliasstream[astream_i++] = '"';
+ } break;
+ } break;
+
+ default:
+ aliasstream[astream_i++] = *cmdptr;
+ break;
+ }
+ }
+
+ for (i = 0; i <= a_index; i++) IConsoleCmdExec(aliases[i]); // execute each alias in turn
+}
+
+/**
+ * Special function for adding string-type variables. They in addition
+ * also need a 'size' value saying how long their string buffer is.
+ * @param size the length of the string buffer
+ * For more information see @IConsoleVarRegister()
+ */
+void IConsoleVarStringRegister(const char *name, void *addr, uint32 size, const char *help)
+{
+ IConsoleVar *var;
+ IConsoleVarRegister(name, addr, ICONSOLE_VAR_STRING, help);
+ var = IConsoleVarGet(name);
+ var->size = size;
+}
+
+/**
+ * Register a new variable to be used in the console
+ * @param name name of the variable that will be used
+ * @param addr memory location the variable will point to
+ * @param help the help string shown for the variable
+ * @param type the type of the variable (simple atomic) so we know which values it can get
+ */
+void IConsoleVarRegister(const char *name, void *addr, IConsoleVarTypes type, const char *help)
+{
+ char *new_cmd = strdup(name);
+ IConsoleVar *item_new = malloc(sizeof(IConsoleVar));
+
+ item_new->help = (help != NULL) ? strdup(help) : NULL;
+
+ item_new->next = NULL;
+ item_new->name = new_cmd;
+ item_new->addr = addr;
+ item_new->proc = NULL;
+ item_new->type = type;
+
+ item_new->hook.access = NULL;
+ item_new->hook.pre = NULL;
+ item_new->hook.post = NULL;
+
+ IConsoleAddSorted(_iconsole_vars, item_new, IConsoleVar, "a variable");
+}
+
+/**
+ * Find the variable pointed to by its string
+ * @param name variable to be found
+ * @return return Varstruct of the found variable, or NULL on failure
+ */
+IConsoleVar *IConsoleVarGet(const char *name)
+{
+ IConsoleVar *item;
+ for (item = _iconsole_vars; item != NULL; item = item->next) {
+ if (strcmp(item->name, name) == 0) return item;
+ }
+
+ return NULL;
+}
+
+/**
+ * Set a new value to a console variable
+ * @param *var the variable being set/changed
+ * @param value the new value given to the variable, cast properly
+ */
+static void IConsoleVarSetValue(const IConsoleVar *var, uint32 value)
+{
+ IConsoleHookHandle(&var->hook, ICONSOLE_HOOK_PRE_ACTION);
+ switch (var->type) {
+ case ICONSOLE_VAR_BOOLEAN:
+ *(bool*)var->addr = (value != 0);
+ break;
+ case ICONSOLE_VAR_BYTE:
+ *(byte*)var->addr = (byte)value;
+ break;
+ case ICONSOLE_VAR_UINT16:
+ *(uint16*)var->addr = (uint16)value;
+ break;
+ case ICONSOLE_VAR_INT16:
+ *(int16*)var->addr = (int16)value;
+ break;
+ case ICONSOLE_VAR_UINT32:
+ *(uint32*)var->addr = (uint32)value;
+ break;
+ case ICONSOLE_VAR_INT32:
+ *(int32*)var->addr = (int32)value;
+ break;
+ default: NOT_REACHED();
+ }
+
+ IConsoleHookHandle(&var->hook, ICONSOLE_HOOK_POST_ACTION);
+ IConsoleVarPrintSetValue(var);
+}
+
+/**
+ * Set a new value to a string-type variable. Basically this
+ * means to copy the new value over to the container.
+ * @param *var the variable in question
+ * @param *value the new value
+ */
+static void IConsoleVarSetStringvalue(const IConsoleVar *var, const char *value)
+{
+ if (var->type != ICONSOLE_VAR_STRING || var->addr == NULL) return;
+
+ IConsoleHookHandle(&var->hook, ICONSOLE_HOOK_PRE_ACTION);
+ ttd_strlcpy(var->addr, value, var->size);
+ IConsoleHookHandle(&var->hook, ICONSOLE_HOOK_POST_ACTION);
+ IConsoleVarPrintSetValue(var); // print out the new value, giving feedback
+ return;
+}
+
+/**
+ * Query the current value of a variable and return it
+ * @param *var the variable queried
+ * @return current value of the variable
+ */
+static uint32 IConsoleVarGetValue(const IConsoleVar *var)
+{
+ uint32 result = 0;
+
+ switch (var->type) {
+ case ICONSOLE_VAR_BOOLEAN:
+ result = *(bool*)var->addr;
+ break;
+ case ICONSOLE_VAR_BYTE:
+ result = *(byte*)var->addr;
+ break;
+ case ICONSOLE_VAR_UINT16:
+ result = *(uint16*)var->addr;
+ break;
+ case ICONSOLE_VAR_INT16:
+ result = *(int16*)var->addr;
+ break;
+ case ICONSOLE_VAR_UINT32:
+ result = *(uint32*)var->addr;
+ break;
+ case ICONSOLE_VAR_INT32:
+ result = *(int32*)var->addr;
+ break;
+ default: NOT_REACHED();
+ }
+ return result;
+}
+
+/**
+ * Get the value of the variable and put it into a printable
+ * string form so we can use it for printing
+ */
+static char *IConsoleVarGetStringValue(const IConsoleVar *var)
+{
+ static char tempres[50];
+ char *value = tempres;
+
+ switch (var->type) {
+ case ICONSOLE_VAR_BOOLEAN:
+ snprintf(tempres, sizeof(tempres), "%s", (*(bool*)var->addr) ? "on" : "off");
+ break;
+ case ICONSOLE_VAR_BYTE:
+ snprintf(tempres, sizeof(tempres), "%u", *(byte*)var->addr);
+ break;
+ case ICONSOLE_VAR_UINT16:
+ snprintf(tempres, sizeof(tempres), "%u", *(uint16*)var->addr);
+ break;
+ case ICONSOLE_VAR_UINT32:
+ snprintf(tempres, sizeof(tempres), "%u", *(uint32*)var->addr);
+ break;
+ case ICONSOLE_VAR_INT16:
+ snprintf(tempres, sizeof(tempres), "%i", *(int16*)var->addr);
+ break;
+ case ICONSOLE_VAR_INT32:
+ snprintf(tempres, sizeof(tempres), "%i", *(int32*)var->addr);
+ break;
+ case ICONSOLE_VAR_STRING:
+ value = (char*)var->addr;
+ break;
+ default: NOT_REACHED();
+ }
+
+ return value;
+}
+
+/**
+ * Print out the value of the variable when asked
+ */
+void IConsoleVarPrintGetValue(const IConsoleVar *var)
+{
+ char *value;
+ /* Some variables need really specific handling, handle this in its
+ * callback function */
+ if (var->proc != NULL) {
+ var->proc(0, NULL);
+ return;
+ }
+
+ value = IConsoleVarGetStringValue(var);
+ IConsolePrintF(_icolour_warn, "Current value for '%s' is: %s", var->name, value);
+}
+
+/**
+ * Print out the value of the variable after it has been assigned
+ * a new value, thus giving us feedback on the action
+ */
+void IConsoleVarPrintSetValue(const IConsoleVar *var)
+{
+ char *value = IConsoleVarGetStringValue(var);
+ IConsolePrintF(_icolour_warn, "'%s' changed to: %s", var->name, value);
+}
+
+/**
+ * Execute a variable command. Without any parameters, print out its value
+ * with parameters it assigns a new value to the variable
+ * @param *var the variable that we will be querying/changing
+ * @param tokencount how many additional parameters have been given to the commandline
+ * @param *token the actual parameters the variable was called with
+ */
+void IConsoleVarExec(const IConsoleVar *var, byte tokencount, char *token[ICON_TOKEN_COUNT])
+{
+ const char *tokenptr = token[0];
+ byte t_index = tokencount;
+ uint32 value;
+
+ if (_stdlib_con_developer)
+ IConsolePrintF(_icolour_dbg, "condbg: requested command is a variable");
+
+ if (tokencount == 0) { /* Just print out value */
+ IConsoleVarPrintGetValue(var);
+ return;
+ }
+
+ /* Use of assignment sign is not mandatory but supported, so just 'ignore it appropiately' */
+ if (strcmp(tokenptr, "=") == 0) tokencount--;
+
+ if (tokencount == 1) {
+ /* Some variables need really special handling, handle it in their callback procedure */
+ if (var->proc != NULL) {
+ var->proc(tokencount, &token[t_index - tokencount]); // set the new value
+ return;
+ }
+ /* Strings need special processing. No need to convert the argument to
+ * an integer value, just copy over the argument on a one-by-one basis */
+ if (var->type == ICONSOLE_VAR_STRING) {
+ IConsoleVarSetStringvalue(var, token[t_index - tokencount]);
+ return;
+ } else if (GetArgumentInteger(&value, token[t_index - tokencount])) {
+ IConsoleVarSetValue(var, value);
+ return;
+ }
+
+ /* Increase or decrease the value by one. This of course can only happen to 'number' types */
+ if (strcmp(tokenptr, "++") == 0 && var->type != ICONSOLE_VAR_STRING) {
+ IConsoleVarSetValue(var, IConsoleVarGetValue(var) + 1);
+ return;
+ }
+
+ if (strcmp(tokenptr, "--") == 0 && var->type != ICONSOLE_VAR_STRING) {
+ IConsoleVarSetValue(var, IConsoleVarGetValue(var) - 1);
+ return;
+ }
+ }
+
+ IConsoleError("invalid variable assignment");
+}
+
+/**
+ * Add a callback function to the variable. Some variables need
+ * very special processing, which can only be done with custom code
+ * @param name name of the variable the callback function is added to
+ * @param proc the function called
+ */
+void IConsoleVarProcAdd(const char *name, IConsoleCmdProc *proc)
+{
+ IConsoleVar *var = IConsoleVarGet(name);
+ if (var == NULL) return;
+ var->proc = proc;
+}
+
+/**
+ * Execute a given command passed to us. First chop it up into
+ * individual tokens (seperated by spaces), then execute it if possible
+ * @param cmdstr string to be parsed and executed
+ */
+void IConsoleCmdExec(const char *cmdstr)
+{
+ IConsoleCmd *cmd = NULL;
+ IConsoleAlias *alias = NULL;
+ IConsoleVar *var = NULL;
+
+ const char *cmdptr;
+ char *tokens[ICON_TOKEN_COUNT], tokenstream[ICON_MAX_STREAMSIZE];
+ uint t_index, tstream_i;
+
+ bool longtoken = false;
+ bool foundtoken = false;
+
+ if (cmdstr[0] == '#') return; // comments
+
+ for (cmdptr = cmdstr; *cmdptr != '\0'; cmdptr++) {
+ if (!IsValidChar(*cmdptr, CS_ALPHANUMERAL)) {
+ IConsoleError("command contains malformed characters, aborting");
+ IConsolePrintF(_icolour_err, "ERROR: command was: '%s'", cmdstr);
+ return;
+ }
+ }
+
+ if (_stdlib_con_developer)
+ IConsolePrintF(_icolour_dbg, "condbg: executing cmdline: '%s'", cmdstr);
+
+ memset(&tokens, 0, sizeof(tokens));
+ memset(&tokenstream, 0, sizeof(tokenstream));
+
+ /* 1. Split up commandline into tokens, seperated by spaces, commands
+ * enclosed in "" are taken as one token. We can only go as far as the amount
+ * of characters in our stream or the max amount of tokens we can handle */
+ for (cmdptr = cmdstr, t_index = 0, tstream_i = 0; *cmdptr != '\0'; cmdptr++) {
+ if (t_index >= lengthof(tokens) || tstream_i >= lengthof(tokenstream)) break;
+
+ switch (*cmdptr) {
+ case ' ': /* Token seperator */
+ if (!foundtoken) break;
+
+ if (longtoken) {
+ tokenstream[tstream_i] = *cmdptr;
+ } else {
+ tokenstream[tstream_i] = '\0';
+ foundtoken = false;
+ }
+
+ tstream_i++;
+ break;
+ case '"': /* Tokens enclosed in "" are one token */
+ longtoken = !longtoken;
+ break;
+ case '\\': /* Escape character for "" */
+ if (cmdptr[1] == '"' && tstream_i + 1 < lengthof(tokenstream)) {
+ tokenstream[tstream_i++] = *++cmdptr;
+ break;
+ }
+ /* fallthrough */
+ default: /* Normal character */
+ tokenstream[tstream_i++] = *cmdptr;
+
+ if (!foundtoken) {
+ tokens[t_index++] = &tokenstream[tstream_i - 1];
+ foundtoken = true;
+ }
+ break;
+ }
+ }
+
+ if (_stdlib_con_developer) {
+ uint i;
+
+ for (i = 0; tokens[i] != NULL; i++) {
+ IConsolePrintF(_icolour_dbg, "condbg: token %d is: '%s'", i, tokens[i]);
+ }
+ }
+
+ if (tokens[0] == '\0') return; // don't execute empty commands
+ /* 2. Determine type of command (cmd, alias or variable) and execute
+ * First try commands, then aliases, and finally variables. Execute
+ * the found action taking into account its hooking code
+ */
+ cmd = IConsoleCmdGet(tokens[0]);
+ if (cmd != NULL) {
+ if (IConsoleHookHandle(&cmd->hook, ICONSOLE_HOOK_ACCESS)) {
+ IConsoleHookHandle(&cmd->hook, ICONSOLE_HOOK_PRE_ACTION);
+ if (cmd->proc(t_index, tokens)) { // index started with 0
+ IConsoleHookHandle(&cmd->hook, ICONSOLE_HOOK_POST_ACTION);
+ } else {
+ cmd->proc(0, NULL); // if command failed, give help
+ }
+ }
+ return;
+ }
+
+ t_index--; // ignore the variable-name for comfort for both aliases and variaables
+ alias = IConsoleAliasGet(tokens[0]);
+ if (alias != NULL) {
+ IConsoleAliasExec(alias, t_index, &tokens[1]);
+ return;
+ }
+
+ var = IConsoleVarGet(tokens[0]);
+ if (var != NULL) {
+ if (IConsoleHookHandle(&var->hook, ICONSOLE_HOOK_ACCESS)) {
+ IConsoleVarExec(var, t_index, &tokens[1]);
+ }
+ return;
+ }
+
+ IConsoleError("command or variable not found");
+}
diff --git a/src/console.h b/src/console.h
new file mode 100644
index 000000000..ef8063bc8
--- /dev/null
+++ b/src/console.h
@@ -0,0 +1,160 @@
+/* $Id$ */
+
+#ifndef CONSOLE_H
+#define CONSOLE_H
+
+// maximum length of a typed in command
+#define ICON_CMDLN_SIZE 255
+// maximum length of a totally expanded command
+#define ICON_MAX_STREAMSIZE 1024
+
+typedef enum IConsoleVarTypes {
+ ICONSOLE_VAR_BOOLEAN,
+ ICONSOLE_VAR_BYTE,
+ ICONSOLE_VAR_UINT16,
+ ICONSOLE_VAR_UINT32,
+ ICONSOLE_VAR_INT16,
+ ICONSOLE_VAR_INT32,
+ ICONSOLE_VAR_STRING
+} IConsoleVarTypes;
+
+typedef enum IConsoleModes {
+ ICONSOLE_FULL,
+ ICONSOLE_OPENED,
+ ICONSOLE_CLOSED
+} IConsoleModes;
+
+typedef enum IConsoleHookTypes {
+ ICONSOLE_HOOK_ACCESS,
+ ICONSOLE_HOOK_PRE_ACTION,
+ ICONSOLE_HOOK_POST_ACTION
+} IConsoleHookTypes;
+
+/** --Hooks--
+ * Hooks are certain triggers get get accessed/executed on either
+ * access, before execution/change or after execution/change. This allows
+ * for general flow of permissions or special action needed in some cases
+ */
+typedef bool IConsoleHook(void);
+typedef struct IConsoleHooks{
+ IConsoleHook *access; // trigger when accessing the variable/command
+ IConsoleHook *pre; // trigger before the variable/command is changed/executed
+ IConsoleHook *post; // trigger after the variable/command is changed/executed
+} IConsoleHooks;
+
+/** --Commands--
+ * Commands are commands, or functions. They get executed once and any
+ * effect they produce are carried out. The arguments to the commands
+ * are given to them, each input word seperated by a double-quote (") is an argument
+ * If you want to handle multiple words as one, enclose them in double-quotes
+ * eg. 'say "hello sexy boy"'
+ */
+typedef bool (IConsoleCmdProc)(byte argc, char *argv[]);
+
+struct IConsoleCmd;
+typedef struct IConsoleCmd {
+ char *name; // name of command
+ struct IConsoleCmd *next; // next command in list
+
+ IConsoleCmdProc *proc; // process executed when command is typed
+ IConsoleHooks hook; // any special trigger action that needs executing
+} IConsoleCmd;
+
+/** --Variables--
+ * Variables are pointers to real ingame variables which allow for
+ * changing while ingame. After changing they keep their new value
+ * and can be used for debugging, gameplay, etc. It accepts:
+ * - no arguments; just print out current value
+ * - '= <new value>' to assign a new value to the variable
+ * - '++' to increase value by one
+ * - '--' to decrease value by one
+ */
+struct IConsoleVar;
+typedef struct IConsoleVar {
+ char *name; // name of the variable
+ struct IConsoleVar *next; // next variable in list
+
+ void *addr; // the address where the variable is pointing at
+ uint32 size; // size of the variable, used for strings
+ char *help; // the optional help string shown when requesting information
+ IConsoleVarTypes type; // type of variable (for correct assignment/output)
+ IConsoleCmdProc *proc; // some variables need really special handling, use a callback function for that
+ IConsoleHooks hook; // any special trigger action that needs executing
+} IConsoleVar;
+
+/** --Aliases--
+ * Aliases are like shortcuts for complex functions, variable assignments,
+ * etc. You can use a simple alias to rename a longer command (eg 'lv' for
+ * 'list_vars' for example), or concatenate more commands into one
+ * (eg. 'ng' for 'load %A; unpause; debug_level 5'). Aliases can parse the arguments
+ * given to them in the command line.
+ * - "%A - %Z" substitute arguments 1 t/m 26
+ * - "%+" lists all parameters keeping them seperated
+ * - "%!" also lists all parameters but presenting them to the aliased command as one argument
+ * - ";" allows for combining commands (see example 'ng')
+ */
+struct IConsoleAlias;
+typedef struct IConsoleAlias {
+ char *name; // name of the alias
+ struct IConsoleAlias *next; // next alias in list
+
+ char *cmdline; // command(s) that is/are being aliased
+} IConsoleAlias;
+
+/* console parser */
+VARDEF IConsoleCmd *_iconsole_cmds; // list of registred commands
+VARDEF IConsoleVar *_iconsole_vars; // list of registred vars
+VARDEF IConsoleAlias *_iconsole_aliases; // list of registred aliases
+
+/* console colors/modes */
+VARDEF byte _icolour_def;
+VARDEF byte _icolour_err;
+VARDEF byte _icolour_warn;
+VARDEF byte _icolour_dbg;
+VARDEF byte _icolour_cmd;
+VARDEF IConsoleModes _iconsole_mode;
+
+/* console functions */
+void IConsoleInit(void);
+void IConsoleFree(void);
+void IConsoleClearBuffer(void);
+void IConsoleResize(Window *w);
+void IConsoleSwitch(void);
+void IConsoleClose(void);
+void IConsoleOpen(void);
+
+/* console output */
+void IConsolePrint(uint16 color_code, const char *string);
+void CDECL IConsolePrintF(uint16 color_code, const char *s, ...);
+void IConsoleDebug(const char *dbg, const char *string);
+void IConsoleWarning(const char *string);
+void IConsoleError(const char *string);
+
+/* Commands */
+void IConsoleCmdRegister(const char *name, IConsoleCmdProc *proc);
+void IConsoleAliasRegister(const char *name, const char *cmd);
+IConsoleCmd *IConsoleCmdGet(const char *name);
+IConsoleAlias *IConsoleAliasGet(const char *name);
+
+/* Variables */
+void IConsoleVarRegister(const char *name, void *addr, IConsoleVarTypes type, const char *help);
+void IConsoleVarStringRegister(const char *name, void *addr, uint32 size, const char *help);
+IConsoleVar* IConsoleVarGet(const char *name);
+void IConsoleVarPrintGetValue(const IConsoleVar *var);
+void IConsoleVarPrintSetValue(const IConsoleVar *var);
+
+/* Parser */
+void IConsoleCmdExec(const char *cmdstr);
+void IConsoleVarExec(const IConsoleVar *var, byte tokencount, char *token[]);
+
+/* console std lib (register ingame commands/aliases/variables) */
+void IConsoleStdLibRegister(void);
+
+/* Hooking code */
+void IConsoleCmdHookAdd(const char *name, IConsoleHookTypes type, IConsoleHook *proc);
+void IConsoleVarHookAdd(const char *name, IConsoleHookTypes type, IConsoleHook *proc);
+void IConsoleVarProcAdd(const char *name, IConsoleCmdProc *proc);
+
+/* Supporting functions */
+bool GetArgumentInteger(uint32 *value, const char *arg);
+#endif /* CONSOLE_H */
diff --git a/src/console_cmds.c b/src/console_cmds.c
new file mode 100644
index 000000000..7ec55c6b9
--- /dev/null
+++ b/src/console_cmds.c
@@ -0,0 +1,1608 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "console.h"
+#include "debug.h"
+#include "engine.h"
+#include "functions.h"
+#include "saveload.h"
+#include "string.h"
+#include "variables.h"
+#include "network/network_data.h"
+#include "network/network_client.h"
+#include "network/network_server.h"
+#include "network/network_udp.h"
+#include "command.h"
+#include "settings.h"
+#include "fios.h"
+#include "vehicle.h"
+#include "station.h"
+#include "strings.h"
+#include "screenshot.h"
+#include "genworld.h"
+#include "date.h"
+#include "network/network.h"
+
+// ** scriptfile handling ** //
+static FILE *_script_file;
+static bool _script_running;
+
+// ** console command / variable defines ** //
+#define DEF_CONSOLE_CMD(function) static bool function(byte argc, char *argv[])
+#define DEF_CONSOLE_HOOK(function) static bool function(void)
+
+
+/* **************************** */
+/* variable and command hooks */
+/* **************************** */
+
+#ifdef ENABLE_NETWORK
+
+static inline bool NetworkAvailable(void)
+{
+ if (!_network_available) {
+ IConsoleError("You cannot use this command because there is no network available.");
+ return false;
+ }
+ return true;
+}
+
+DEF_CONSOLE_HOOK(ConHookServerOnly)
+{
+ if (!NetworkAvailable()) return false;
+
+ if (!_network_server) {
+ IConsoleError("This command/variable is only available to a network server.");
+ return false;
+ }
+ return true;
+}
+
+DEF_CONSOLE_HOOK(ConHookClientOnly)
+{
+ if (!NetworkAvailable()) return false;
+
+ if (_network_server) {
+ IConsoleError("This command/variable is not available to a network server.");
+ return false;
+ }
+ return true;
+}
+
+DEF_CONSOLE_HOOK(ConHookNeedNetwork)
+{
+ if (!NetworkAvailable()) return false;
+
+ if (!_networking) {
+ IConsoleError("Not connected. This command/variable is only available in multiplayer.");
+ return false;
+ }
+ return true;
+}
+
+DEF_CONSOLE_HOOK(ConHookNoNetwork)
+{
+ if (_networking) {
+ IConsoleError("This command/variable is forbidden in multiplayer.");
+ return false;
+ }
+ return true;
+}
+
+#endif /* ENABLE_NETWORK */
+
+static void IConsoleHelp(const char *str)
+{
+ IConsolePrintF(_icolour_warn, "- %s", str);
+}
+
+DEF_CONSOLE_CMD(ConResetEngines)
+{
+ if (argc == 0) {
+ IConsoleHelp("Reset status data of all engines. This might solve some issues with 'lost' engines. Usage: 'resetengines'");
+ return true;
+ }
+
+ StartupEngines();
+ return true;
+}
+
+#ifdef _DEBUG
+DEF_CONSOLE_CMD(ConResetTile)
+{
+ if (argc == 0) {
+ IConsoleHelp("Reset a tile to bare land. Usage: 'resettile <tile>'");
+ IConsoleHelp("Tile can be either decimal (34161) or hexadecimal (0x4a5B)");
+ return true;
+ }
+
+ if (argc == 2) {
+ uint32 result;
+ if (GetArgumentInteger(&result, argv[1])) {
+ DoClearSquare((TileIndex)result);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+DEF_CONSOLE_CMD(ConStopAllVehicles)
+{
+ Vehicle* v;
+ if (argc == 0) {
+ IConsoleHelp("Stops all vehicles in the game. For debugging only! Use at your own risk... Usage: 'stopall'");
+ return true;
+ }
+
+ FOR_ALL_VEHICLES(v) {
+ /* Code ripped from CmdStartStopTrain. Can't call it, because of
+ * ownership problems, so we'll duplicate some code, for now */
+ if (v->type == VEH_Train)
+ v->u.rail.days_since_order_progr = 0;
+ v->vehstatus |= VS_STOPPED;
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
+ }
+ return true;
+}
+#endif /* _DEBUG */
+
+DEF_CONSOLE_CMD(ConScrollToTile)
+{
+ if (argc == 0) {
+ IConsoleHelp("Center the screen on a given tile. Usage: 'scrollto <tile>'");
+ IConsoleHelp("Tile can be either decimal (34161) or hexadecimal (0x4a5B)");
+ return true;
+ }
+
+ if (argc == 2) {
+ uint32 result;
+ if (GetArgumentInteger(&result, argv[1])) {
+ if (result >= MapSize()) {
+ IConsolePrint(_icolour_err, "Tile does not exist");
+ return true;
+ }
+ ScrollMainWindowToTile((TileIndex)result);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+extern bool SafeSaveOrLoad(const char *filename, int mode, int newgm);
+extern void BuildFileList(void);
+extern void SetFiosType(const byte fiostype);
+
+/* Save the map to a file */
+DEF_CONSOLE_CMD(ConSave)
+{
+ if (argc == 0) {
+ IConsoleHelp("Save the current game. Usage: 'save <filename>'");
+ return true;
+ }
+
+ if (argc == 2) {
+ char buf[200];
+
+ snprintf(buf, lengthof(buf), "%s%s%s.sav", _paths.save_dir, PATHSEP, argv[1]);
+ IConsolePrint(_icolour_def, "Saving map...");
+
+ if (SaveOrLoad(buf, SL_SAVE) != SL_OK) {
+ IConsolePrint(_icolour_err, "SaveMap failed");
+ } else {
+ IConsolePrintF(_icolour_def, "Map sucessfully saved to %s", buf);
+ }
+ return true;
+ }
+
+ return false;
+}
+
+static const FiosItem* GetFiosItem(const char* file)
+{
+ int i;
+
+ _saveload_mode = SLD_LOAD_GAME;
+ BuildFileList();
+
+ for (i = 0; i < _fios_num; i++) {
+ if (strcmp(file, _fios_list[i].name) == 0) break;
+ if (strcmp(file, _fios_list[i].title) == 0) break;
+ }
+
+ if (i == _fios_num) { /* If no name matches, try to parse it as number */
+ char* endptr;
+
+ i = strtol(file, &endptr, 10);
+ if (file == endptr || *endptr != '\0') i = -1;
+ }
+
+ return IS_INT_INSIDE(i, 0, _fios_num) ? &_fios_list[i] : NULL;
+}
+
+
+DEF_CONSOLE_CMD(ConLoad)
+{
+ const FiosItem *item;
+ const char *file;
+
+ if (argc == 0) {
+ IConsoleHelp("Load a game by name or index. Usage: 'load <file | number>'");
+ return true;
+ }
+
+ if (argc != 2) return false;
+
+ file = argv[1];
+ item = GetFiosItem(file);
+ if (item != NULL) {
+ switch (item->type) {
+ case FIOS_TYPE_FILE: case FIOS_TYPE_OLDFILE: {
+ _switch_mode = SM_LOAD;
+ SetFiosType(item->type);
+
+ ttd_strlcpy(_file_to_saveload.name, FiosBrowseTo(item), sizeof(_file_to_saveload.name));
+ ttd_strlcpy(_file_to_saveload.title, item->title, sizeof(_file_to_saveload.title));
+ } break;
+ default: IConsolePrintF(_icolour_err, "%s: Not a savegame.", file);
+ }
+ } else {
+ IConsolePrintF(_icolour_err, "%s: No such file or directory.", file);
+ }
+
+ FiosFreeSavegameList();
+ return true;
+}
+
+
+DEF_CONSOLE_CMD(ConRemove)
+{
+ const FiosItem* item;
+ const char* file;
+
+ if (argc == 0) {
+ IConsoleHelp("Remove a savegame by name or index. Usage: 'rm <file | number>'");
+ return true;
+ }
+
+ if (argc != 2) return false;
+
+ file = argv[1];
+ item = GetFiosItem(file);
+ if (item != NULL) {
+ if (!FiosDelete(item->name))
+ IConsolePrintF(_icolour_err, "%s: Failed to delete file", file);
+ } else {
+ IConsolePrintF(_icolour_err, "%s: No such file or directory.", file);
+ }
+
+ FiosFreeSavegameList();
+ return true;
+}
+
+
+/* List all the files in the current dir via console */
+DEF_CONSOLE_CMD(ConListFiles)
+{
+ int i;
+
+ if (argc == 0) {
+ IConsoleHelp("List all loadable savegames and directories in the current dir via console. Usage: 'ls | dir'");
+ return true;
+ }
+
+ BuildFileList();
+
+ for (i = 0; i < _fios_num; i++) {
+ const FiosItem *item = &_fios_list[i];
+ IConsolePrintF(_icolour_def, "%d) %s", i, item->title);
+ }
+
+ FiosFreeSavegameList();
+ return true;
+}
+
+/* Change the dir via console */
+DEF_CONSOLE_CMD(ConChangeDirectory)
+{
+ const FiosItem *item;
+ const char *file;
+
+ if (argc == 0) {
+ IConsoleHelp("Change the dir via console. Usage: 'cd <directory | number>'");
+ return true;
+ }
+
+ if (argc != 2) return false;
+
+ file = argv[1];
+ item = GetFiosItem(file);
+ if (item != NULL) {
+ switch (item->type) {
+ case FIOS_TYPE_DIR: case FIOS_TYPE_DRIVE: case FIOS_TYPE_PARENT:
+ FiosBrowseTo(item);
+ break;
+ default: IConsolePrintF(_icolour_err, "%s: Not a directory.", file);
+ }
+ } else {
+ IConsolePrintF(_icolour_err, "%s: No such file or directory.", file);
+ }
+
+ FiosFreeSavegameList();
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConPrintWorkingDirectory)
+{
+ const char *path;
+
+ if (argc == 0) {
+ IConsoleHelp("Print out the current working directory. Usage: 'pwd'");
+ return true;
+ }
+
+ // XXX - Workaround for broken file handling
+ FiosGetSavegameList(SLD_LOAD_GAME);
+ FiosFreeSavegameList();
+
+ FiosGetDescText(&path, NULL);
+ IConsolePrint(_icolour_def, path);
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConClearBuffer)
+{
+ if (argc == 0) {
+ IConsoleHelp("Clear the console buffer. Usage: 'clear'");
+ return true;
+ }
+
+ IConsoleClearBuffer();
+ InvalidateWindow(WC_CONSOLE, 0);
+ return true;
+}
+
+
+// ********************************* //
+// * Network Core Console Commands * //
+// ********************************* //
+#ifdef ENABLE_NETWORK
+
+DEF_CONSOLE_CMD(ConBan)
+{
+ NetworkClientInfo *ci;
+ const char *banip = NULL;
+ uint32 index;
+
+ if (argc == 0) {
+ IConsoleHelp("Ban a player from a network game. Usage: 'ban <ip | client-id>'");
+ IConsoleHelp("For client-id's, see the command 'clients'");
+ IConsoleHelp("If the client is no longer online, you can still ban his/her IP");
+ return true;
+ }
+
+ if (argc != 2) return false;
+
+ if (strchr(argv[1], '.') == NULL) { // banning with ID
+ index = atoi(argv[1]);
+ ci = NetworkFindClientInfoFromIndex(index);
+ } else { // banning IP
+ ci = NetworkFindClientInfoFromIP(argv[1]);
+ if (ci == NULL) {
+ banip = argv[1];
+ index = (uint32)-1;
+ } else {
+ index = ci->client_index;
+ }
+ }
+
+ if (index == NETWORK_SERVER_INDEX) {
+ IConsoleError("Silly boy, you can not ban yourself!");
+ return true;
+ }
+
+ if (index == 0 || (ci == NULL && index != (uint32)-1)) {
+ IConsoleError("Invalid client");
+ return true;
+ }
+
+ if (ci != NULL) {
+ banip = inet_ntoa(*(struct in_addr *)&ci->client_ip);
+ SEND_COMMAND(PACKET_SERVER_ERROR)(NetworkFindClientStateFromIndex(index), NETWORK_ERROR_KICKED);
+ IConsolePrint(_icolour_def, "Client banned");
+ } else {
+ IConsolePrint(_icolour_def, "Client not online, banned IP");
+ }
+
+ /* Add user to ban-list */
+ for (index = 0; index < lengthof(_network_ban_list); index++) {
+ if (_network_ban_list[index] == NULL) {
+ _network_ban_list[index] = strdup(banip);
+ break;
+ }
+ }
+
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConUnBan)
+{
+ uint i, index;
+
+ if (argc == 0) {
+ IConsoleHelp("Unban a player from a network game. Usage: 'unban <ip | client-id>'");
+ IConsoleHelp("For a list of banned IP's, see the command 'banlist'");
+ return true;
+ }
+
+ if (argc != 2) return false;
+
+ index = (strchr(argv[1], '.') == NULL) ? atoi(argv[1]) : 0;
+ index--;
+
+ for (i = 0; i < lengthof(_network_ban_list); i++) {
+ if (_network_ban_list[i] == NULL) continue;
+
+ if (strcmp(_network_ban_list[i], argv[1]) == 0 || index == i) {
+ free(_network_ban_list[i]);
+ _network_ban_list[i] = NULL;
+ IConsolePrint(_icolour_def, "IP unbanned.");
+ return true;
+ }
+ }
+
+ IConsolePrint(_icolour_def, "IP not in ban-list.");
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConBanList)
+{
+ uint i;
+
+ if (argc == 0) {
+ IConsoleHelp("List the IP's of banned clients: Usage 'banlist'");
+ return true;
+ }
+
+ IConsolePrint(_icolour_def, "Banlist: ");
+
+ for (i = 0; i < lengthof(_network_ban_list); i++) {
+ if (_network_ban_list[i] != NULL)
+ IConsolePrintF(_icolour_def, " %d) %s", i + 1, _network_ban_list[i]);
+ }
+
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConPauseGame)
+{
+ if (argc == 0) {
+ IConsoleHelp("Pause a network game. Usage: 'pause'");
+ return true;
+ }
+
+ if (_pause == 0) {
+ DoCommandP(0, 1, 0, NULL, CMD_PAUSE);
+ IConsolePrint(_icolour_def, "Game paused.");
+ } else {
+ IConsolePrint(_icolour_def, "Game is already paused.");
+ }
+
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConUnPauseGame)
+{
+ if (argc == 0) {
+ IConsoleHelp("Unpause a network game. Usage: 'unpause'");
+ return true;
+ }
+
+ if (_pause != 0) {
+ DoCommandP(0, 0, 0, NULL, CMD_PAUSE);
+ IConsolePrint(_icolour_def, "Game unpaused.");
+ } else {
+ IConsolePrint(_icolour_def, "Game is already unpaused.");
+ }
+
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConRcon)
+{
+ if (argc == 0) {
+ IConsoleHelp("Remote control the server from another client. Usage: 'rcon <password> <command>'");
+ IConsoleHelp("Remember to enclose the command in quotes, otherwise only the first parameter is sent");
+ return true;
+ }
+
+ if (argc < 3) return false;
+
+ SEND_COMMAND(PACKET_CLIENT_RCON)(argv[1], argv[2]);
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConStatus)
+{
+ static const char* const stat_str[] = {
+ "inactive",
+ "authorized",
+ "waiting",
+ "loading map",
+ "map done",
+ "ready",
+ "active"
+ };
+
+ const NetworkClientState *cs;
+
+ if (argc == 0) {
+ IConsoleHelp("List the status of all clients connected to the server. Usage 'status'");
+ return true;
+ }
+
+ FOR_ALL_CLIENTS(cs) {
+ int lag = NetworkCalculateLag(cs);
+ const NetworkClientInfo *ci = DEREF_CLIENT_INFO(cs);
+ const char* status;
+
+ status = (cs->status < lengthof(stat_str) ? stat_str[cs->status] : "unknown");
+ IConsolePrintF(8, "Client #%1d name: '%s' status: '%s' frame-lag: %3d company: %1d IP: %s unique-id: '%s'",
+ cs->index, ci->client_name, status, lag,
+ ci->client_playas + (IsValidPlayer(ci->client_playas) ? 1 : 0),
+ GetPlayerIP(ci), ci->unique_id);
+ }
+
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConServerInfo)
+{
+ const NetworkGameInfo *gi;
+
+ if (argc == 0) {
+ IConsoleHelp("List current and maximum client/player limits. Usage 'server_info'");
+ IConsoleHelp("You can change these values by setting the variables 'max_clients', 'max_companies' and 'max_spectators'");
+ return true;
+ }
+
+ gi = &_network_game_info;
+ IConsolePrintF(_icolour_def, "Current/maximum clients: %2d/%2d", gi->clients_on, gi->clients_max);
+ IConsolePrintF(_icolour_def, "Current/maximum companies: %2d/%2d", ActivePlayerCount(), gi->companies_max);
+ IConsolePrintF(_icolour_def, "Current/maximum spectators: %2d/%2d", NetworkSpectatorCount(), gi->spectators_max);
+
+ return true;
+}
+
+DEF_CONSOLE_HOOK(ConHookValidateMaxClientsCount)
+{
+ /* XXX - hardcoded, string limiation -- TrueLight
+ * XXX - also see network.c:NetworkStartup ~1356 */
+ if (_network_game_info.clients_max > 10) {
+ _network_game_info.clients_max = 10;
+ IConsoleError("Maximum clients out of bounds, truncating to limit.");
+ }
+
+ return true;
+}
+
+DEF_CONSOLE_HOOK(ConHookValidateMaxCompaniesCount)
+{
+ if (_network_game_info.companies_max > MAX_PLAYERS) {
+ _network_game_info.companies_max = MAX_PLAYERS;
+ IConsoleError("Maximum companies out of bounds, truncating to limit.");
+ }
+
+ return true;
+}
+
+DEF_CONSOLE_HOOK(ConHookValidateMaxSpectatorsCount)
+{
+ /* XXX @see ConHookValidateMaxClientsCount */
+ if (_network_game_info.spectators_max > 10) {
+ _network_game_info.spectators_max = 10;
+ IConsoleError("Maximum spectators out of bounds, truncating to limit.");
+ }
+
+ return true;
+}
+
+DEF_CONSOLE_HOOK(ConHookCheckMinPlayers)
+{
+ CheckMinPlayers();
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConKick)
+{
+ NetworkClientInfo *ci;
+ uint32 index;
+
+ if (argc == 0) {
+ IConsoleHelp("Kick a player from a network game. Usage: 'kick <ip | client-id>'");
+ IConsoleHelp("For client-id's, see the command 'clients'");
+ return true;
+ }
+
+ if (argc != 2) return false;
+
+ if (strchr(argv[1], '.') == NULL) {
+ index = atoi(argv[1]);
+ ci = NetworkFindClientInfoFromIndex(index);
+ } else {
+ ci = NetworkFindClientInfoFromIP(argv[1]);
+ index = (ci == NULL) ? 0 : ci->client_index;
+ }
+
+ if (index == NETWORK_SERVER_INDEX) {
+ IConsoleError("Silly boy, you can not kick yourself!");
+ return true;
+ }
+
+ if (index == 0) {
+ IConsoleError("Invalid client");
+ return true;
+ }
+
+ if (ci != NULL) {
+ SEND_COMMAND(PACKET_SERVER_ERROR)(NetworkFindClientStateFromIndex(index), NETWORK_ERROR_KICKED);
+ } else {
+ IConsoleError("Client not found");
+ }
+
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConResetCompany)
+{
+ const Player *p;
+ const NetworkClientState *cs;
+ const NetworkClientInfo *ci;
+ PlayerID index;
+
+ if (argc == 0) {
+ IConsoleHelp("Remove an idle company from the game. Usage: 'reset_company <company-id>'");
+ IConsoleHelp("For company-id's, see the list of companies from the dropdown menu. Player 1 is 1, etc.");
+ return true;
+ }
+
+ if (argc != 2) return false;
+
+ index = atoi(argv[1]) - 1;
+
+ /* Check valid range */
+ if (!IsValidPlayer(index)) {
+ IConsolePrintF(_icolour_err, "Company does not exist. Company-id must be between 1 and %d.", MAX_PLAYERS);
+ return true;
+ }
+
+ /* Check if company does exist */
+ p = GetPlayer(index);
+ if (!p->is_active) {
+ IConsoleError("Company does not exist.");
+ return true;
+ }
+
+ if (p->is_ai) {
+ IConsoleError("Company is owned by an AI.");
+ return true;
+ }
+
+ /* Check if the company has active players */
+ FOR_ALL_CLIENTS(cs) {
+ ci = DEREF_CLIENT_INFO(cs);
+ if (ci->client_playas == index) {
+ IConsoleError("Cannot remove company: a client is connected to that company.");
+ return true;
+ }
+ }
+ ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
+ if (ci->client_playas == index) {
+ IConsoleError("Cannot remove company: the server is connected to that company.");
+ return true;
+ }
+
+ /* It is safe to remove this company */
+ DoCommandP(0, 2, index, NULL, CMD_PLAYER_CTRL);
+ IConsolePrint(_icolour_def, "Company deleted.");
+
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConNetworkClients)
+{
+ NetworkClientInfo *ci;
+
+ if (argc == 0) {
+ IConsoleHelp("Get a list of connected clients including their ID, name, company-id, and IP. Usage: 'clients'");
+ return true;
+ }
+
+ FOR_ALL_ACTIVE_CLIENT_INFOS(ci) {
+ IConsolePrintF(8, "Client #%1d name: '%s' company: %1d IP: %s",
+ ci->client_index, ci->client_name,
+ ci->client_playas + (IsValidPlayer(ci->client_playas) ? 1 : 0),
+ GetPlayerIP(ci));
+ }
+
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConNetworkConnect)
+{
+ char *ip;
+ const char *port = NULL;
+ const char *player = NULL;
+ uint16 rport;
+
+ if (argc == 0) {
+ IConsoleHelp("Connect to a remote OTTD server and join the game. Usage: 'connect <ip>'");
+ IConsoleHelp("IP can contain port and player: 'IP[[#Player]:Port]', eg: 'server.ottd.org#2:443'");
+ IConsoleHelp("Player #255 is spectator all others are a certain company with Company 1 being #1");
+ return true;
+ }
+
+ if (argc < 2) return false;
+ if (_networking) NetworkDisconnect(); // we are in network-mode, first close it!
+
+ ip = argv[1];
+ /* Default settings: default port and new company */
+ rport = NETWORK_DEFAULT_PORT;
+ _network_playas = PLAYER_NEW_COMPANY;
+
+ ParseConnectionString(&player, &port, ip);
+
+ IConsolePrintF(_icolour_def, "Connecting to %s...", ip);
+ if (player != NULL) {
+ _network_playas = atoi(player);
+ IConsolePrintF(_icolour_def, " player-no: %d", _network_playas);
+
+ /* From a user pov 0 is a new player, internally it's different and all
+ * players are offset by one to ease up on users (eg players 1-8 not 0-7) */
+ if (_network_playas != PLAYER_SPECTATOR) {
+ _network_playas--;
+ if (!IsValidPlayer(_network_playas)) return false;
+ }
+ }
+ if (port != NULL) {
+ rport = atoi(port);
+ IConsolePrintF(_icolour_def, " port: %s", port);
+ }
+
+ NetworkClientConnectGame(ip, rport);
+
+ return true;
+}
+
+#endif /* ENABLE_NETWORK */
+
+/* ******************************** */
+/* script file console commands */
+/* ******************************** */
+
+DEF_CONSOLE_CMD(ConExec)
+{
+ char cmdline[ICON_CMDLN_SIZE];
+ char *cmdptr;
+
+ if (argc == 0) {
+ IConsoleHelp("Execute a local script file. Usage: 'exec <script> <?>'");
+ return true;
+ }
+
+ if (argc < 2) return false;
+
+ _script_file = fopen(argv[1], "r");
+
+ if (_script_file == NULL) {
+ if (argc == 2 || atoi(argv[2]) != 0) IConsoleError("script file not found");
+ return true;
+ }
+
+ _script_running = true;
+
+ while (_script_running && fgets(cmdline, sizeof(cmdline), _script_file) != NULL) {
+ /* Remove newline characters from the executing script */
+ for (cmdptr = cmdline; *cmdptr != '\0'; cmdptr++) {
+ if (*cmdptr == '\n' || *cmdptr == '\r') {
+ *cmdptr = '\0';
+ break;
+ }
+ }
+ IConsoleCmdExec(cmdline);
+ }
+
+ if (ferror(_script_file))
+ IConsoleError("Encountered errror while trying to read from script file");
+
+ _script_running = false;
+ fclose(_script_file);
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConReturn)
+{
+ if (argc == 0) {
+ IConsoleHelp("Stop executing a running script. Usage: 'return'");
+ return true;
+ }
+
+ _script_running = false;
+ return true;
+}
+
+/* **************************** */
+/* default console commands */
+/* **************************** */
+extern bool CloseConsoleLogIfActive(void);
+
+DEF_CONSOLE_CMD(ConScript)
+{
+ extern FILE* _iconsole_output_file;
+
+ if (argc == 0) {
+ IConsoleHelp("Start or stop logging console output to a file. Usage: 'script <filename>'");
+ IConsoleHelp("If filename is omitted, a running log is stopped if it is active");
+ return true;
+ }
+
+ if (!CloseConsoleLogIfActive()) {
+ if (argc < 2) return false;
+
+ IConsolePrintF(_icolour_def, "file output started to: %s", argv[1]);
+ _iconsole_output_file = fopen(argv[1], "ab");
+ if (_iconsole_output_file == NULL) IConsoleError("could not open file");
+ }
+
+ return true;
+}
+
+
+DEF_CONSOLE_CMD(ConEcho)
+{
+ if (argc == 0) {
+ IConsoleHelp("Print back the first argument to the console. Usage: 'echo <arg>'");
+ return true;
+ }
+
+ if (argc < 2) return false;
+ IConsolePrint(_icolour_def, argv[1]);
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConEchoC)
+{
+ if (argc == 0) {
+ IConsoleHelp("Print back the first argument to the console in a given colour. Usage: 'echoc <colour> <arg2>'");
+ return true;
+ }
+
+ if (argc < 3) return false;
+ IConsolePrint(atoi(argv[1]), argv[2]);
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConNewGame)
+{
+ if (argc == 0) {
+ IConsoleHelp("Start a new game. Usage: 'newgame [seed]'");
+ IConsoleHelp("The server can force a new game using 'newgame'; any client joined will rejoin after the server is done generating the new game.");
+ return true;
+ }
+
+ StartNewGameWithoutGUI((argc == 2) ? (uint)atoi(argv[1]) : GENERATE_NEW_SEED);
+ return true;
+}
+
+extern void SwitchMode(int new_mode);
+
+DEF_CONSOLE_CMD(ConRestart)
+{
+ if (argc == 0) {
+ IConsoleHelp("Restart game. Usage: 'restart'");
+ IConsoleHelp("Restarts a game. It tries to reproduce the exact same map as the game started with.");
+ return true;
+ }
+
+ /* Don't copy the _newgame pointers to the real pointers, so call SwitchMode directly */
+ _patches.map_x = MapLogX();
+ _patches.map_y = FindFirstBit(MapSizeY());
+ SwitchMode(SM_NEWGAME);
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConGetSeed)
+{
+ if (argc == 0) {
+ IConsoleHelp("Returns the seed used to create this game. Usage: 'getseed'");
+ IConsoleHelp("The seed can be used to reproduce the exact same map as the game started with.");
+ return true;
+ }
+
+ IConsolePrintF(_icolour_def, "Generation Seed: %u", _patches.generation_seed);
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConAlias)
+{
+ IConsoleAlias *alias;
+
+ if (argc == 0) {
+ IConsoleHelp("Add a new alias, or redefine the behaviour of an existing alias . Usage: 'alias <name> <command>'");
+ return true;
+ }
+
+ if (argc < 3) return false;
+
+ alias = IConsoleAliasGet(argv[1]);
+ if (alias == NULL) {
+ IConsoleAliasRegister(argv[1], argv[2]);
+ } else {
+ free(alias->cmdline);
+ alias->cmdline = strdup(argv[2]);
+ }
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConScreenShot)
+{
+ if (argc == 0) {
+ IConsoleHelp("Create a screenshot of the game. Usage: 'screenshot [big | no_con]'");
+ IConsoleHelp("'big' makes a screenshot of the whole map, 'no_con' hides the console to create the screenshot");
+ return true;
+ }
+
+ if (argc > 3) return false;
+
+ SetScreenshotType(SC_VIEWPORT);
+ if (argc > 1) {
+ if (strcmp(argv[1], "big") == 0 || (argc == 3 && strcmp(argv[2], "big") == 0))
+ SetScreenshotType(SC_WORLD);
+
+ if (strcmp(argv[1], "no_con") == 0 || (argc == 3 && strcmp(argv[2], "no_con") == 0))
+ IConsoleClose();
+ }
+
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConInfoVar)
+{
+ static const char *_icon_vartypes[] = {"boolean", "byte", "uint16", "uint32", "int16", "int32", "string"};
+ const IConsoleVar *var;
+
+ if (argc == 0) {
+ IConsoleHelp("Print out debugging information about a variable. Usage: 'info_var <var>'");
+ return true;
+ }
+
+ if (argc < 2) return false;
+
+ var = IConsoleVarGet(argv[1]);
+ if (var == NULL) {
+ IConsoleError("the given variable was not found");
+ return true;
+ }
+
+ IConsolePrintF(_icolour_def, "variable name: %s", var->name);
+ IConsolePrintF(_icolour_def, "variable type: %s", _icon_vartypes[var->type]);
+ IConsolePrintF(_icolour_def, "variable addr: 0x%X", var->addr);
+
+ if (var->hook.access) IConsoleWarning("variable is access hooked");
+ if (var->hook.pre) IConsoleWarning("variable is pre hooked");
+ if (var->hook.post) IConsoleWarning("variable is post hooked");
+ return true;
+}
+
+
+DEF_CONSOLE_CMD(ConInfoCmd)
+{
+ const IConsoleCmd *cmd;
+
+ if (argc == 0) {
+ IConsoleHelp("Print out debugging information about a command. Usage: 'info_cmd <cmd>'");
+ return true;
+ }
+
+ if (argc < 2) return false;
+
+ cmd = IConsoleCmdGet(argv[1]);
+ if (cmd == NULL) {
+ IConsoleError("the given command was not found");
+ return true;
+ }
+
+ IConsolePrintF(_icolour_def, "command name: %s", cmd->name);
+ IConsolePrintF(_icolour_def, "command proc: 0x%X", cmd->proc);
+
+ if (cmd->hook.access) IConsoleWarning("command is access hooked");
+ if (cmd->hook.pre) IConsoleWarning("command is pre hooked");
+ if (cmd->hook.post) IConsoleWarning("command is post hooked");
+
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConDebugLevel)
+{
+ if (argc == 0) {
+ IConsoleHelp("Get/set the default debugging level for the game. Usage: 'debug_level [<level>]'");
+ IConsoleHelp("Level can be any combination of names, levels. Eg 'net=5 ms=4'. Remember to enclose it in \"'s");
+ return true;
+ }
+
+ if (argc > 2) return false;
+
+ if (argc == 1) {
+ IConsolePrintF(_icolour_def, "Current debug-level: '%s'", GetDebugString());
+ } else {
+ SetDebugString(argv[1]);
+ }
+
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConExit)
+{
+ if (argc == 0) {
+ IConsoleHelp("Exit the game. Usage: 'exit'");
+ return true;
+ }
+
+ _exit_game = true;
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConPart)
+{
+ if (argc == 0) {
+ IConsoleHelp("Leave the currently joined/running game (only ingame). Usage: 'part'");
+ return true;
+ }
+
+ if (_game_mode != GM_NORMAL) return false;
+
+ _switch_mode = SM_MENU;
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConHelp)
+{
+ if (argc == 2) {
+ const IConsoleCmd *cmd;
+ const IConsoleVar *var;
+ const IConsoleAlias *alias;
+
+ cmd = IConsoleCmdGet(argv[1]);
+ if (cmd != NULL) {
+ cmd->proc(0, NULL);
+ return true;
+ }
+
+ alias = IConsoleAliasGet(argv[1]);
+ if (alias != NULL) {
+ cmd = IConsoleCmdGet(alias->cmdline);
+ if (cmd != NULL) {
+ cmd->proc(0, NULL);
+ return true;
+ }
+ IConsolePrintF(_icolour_err, "ERROR: alias is of special type, please see its execution-line: '%s'", alias->cmdline);
+ return true;
+ }
+
+ var = IConsoleVarGet(argv[1]);
+ if (var != NULL && var->help != NULL) {
+ IConsoleHelp(var->help);
+ return true;
+ }
+
+ IConsoleError("command or variable not found");
+ return true;
+ }
+
+ IConsolePrint(13, " ---- OpenTTD Console Help ---- ");
+ IConsolePrint( 1, " - variables: [command to list all variables: list_vars]");
+ IConsolePrint( 1, " set value with '<var> = <value>', use '++/--' to in-or decrement");
+ IConsolePrint( 1, " or omit '=' and just '<var> <value>'. get value with typing '<var>'");
+ IConsolePrint( 1, " - commands: [command to list all commands: list_cmds]");
+ IConsolePrint( 1, " call commands with '<command> <arg2> <arg3>...'");
+ IConsolePrint( 1, " - to assign strings, or use them as arguments, enclose it within quotes");
+ IConsolePrint( 1, " like this: '<command> \"string argument with spaces\"'");
+ IConsolePrint( 1, " - use 'help <command> | <variable>' to get specific information");
+ IConsolePrint( 1, " - scroll console output with shift + (up | down) | (pageup | pagedown))");
+ IConsolePrint( 1, " - scroll console input history with the up | down arrows");
+ IConsolePrint( 1, "");
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConListCommands)
+{
+ const IConsoleCmd *cmd;
+ size_t l = 0;
+
+ if (argc == 0) {
+ IConsoleHelp("List all registered commands. Usage: 'list_cmds [<pre-filter>]'");
+ return true;
+ }
+
+ if (argv[1] != NULL) l = strlen(argv[1]);
+
+ for (cmd = _iconsole_cmds; cmd != NULL; cmd = cmd->next) {
+ if (argv[1] == NULL || strncmp(cmd->name, argv[1], l) == 0) {
+ IConsolePrintF(_icolour_def, "%s", cmd->name);
+ }
+ }
+
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConListVariables)
+{
+ const IConsoleVar *var;
+ size_t l = 0;
+
+ if (argc == 0) {
+ IConsoleHelp("List all registered variables. Usage: 'list_vars [<pre-filter>]'");
+ return true;
+ }
+
+ if (argv[1] != NULL) l = strlen(argv[1]);
+
+ for (var = _iconsole_vars; var != NULL; var = var->next) {
+ if (argv[1] == NULL || strncmp(var->name, argv[1], l) == 0)
+ IConsolePrintF(_icolour_def, "%s", var->name);
+ }
+
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConListAliases)
+{
+ const IConsoleAlias *alias;
+ size_t l = 0;
+
+ if (argc == 0) {
+ IConsoleHelp("List all registered aliases. Usage: 'list_aliases [<pre-filter>]'");
+ return true;
+ }
+
+ if (argv[1] != NULL) l = strlen(argv[1]);
+
+ for (alias = _iconsole_aliases; alias != NULL; alias = alias->next) {
+ if (argv[1] == NULL || strncmp(alias->name, argv[1], l) == 0)
+ IConsolePrintF(_icolour_def, "%s => %s", alias->name, alias->cmdline);
+ }
+
+ return true;
+}
+
+#ifdef ENABLE_NETWORK
+
+DEF_CONSOLE_CMD(ConSay)
+{
+ if (argc == 0) {
+ IConsoleHelp("Chat to your fellow players in a multiplayer game. Usage: 'say \"<msg>\"'");
+ return true;
+ }
+
+ if (argc != 2) return false;
+
+ if (!_network_server) {
+ SEND_COMMAND(PACKET_CLIENT_CHAT)(NETWORK_ACTION_CHAT, DESTTYPE_BROADCAST, 0 /* param does not matter */, argv[1]);
+ } else {
+ NetworkServer_HandleChat(NETWORK_ACTION_CHAT, DESTTYPE_BROADCAST, 0, argv[1], NETWORK_SERVER_INDEX);
+ }
+
+ return true;
+}
+
+#ifdef ENABLE_NETWORK
+ #include "table/strings.h"
+#endif /* ENABLE_NETWORK */
+
+DEF_CONSOLE_CMD(ConPlayers)
+{
+ Player *p;
+
+ if (argc == 0) {
+ IConsoleHelp("List the in-game details of all clients connected to the server. Usage 'players'");
+ return true;
+ }
+ NetworkPopulateCompanyInfo();
+
+ FOR_ALL_PLAYERS(p) {
+ char buffer[512];
+
+ if (!p->is_active) continue;
+
+ GetString(buffer, STR_00D1_DARK_BLUE + _player_colors[p->index], lastof(buffer));
+ IConsolePrintF(8, "#:%d(%s) Company Name: '%s' Year Founded: %d Money: %d Loan: %d Value: %" OTTD_PRINTF64 "d (T:%d, R:%d, P:%d, S:%d)",
+ p->index + 1, buffer, _network_player_info[p->index].company_name, p->inaugurated_year, p->player_money, p->current_loan, CalculateCompanyValue(p),
+ /* trains */ _network_player_info[p->index].num_vehicle[0],
+ /* lorry + bus */ _network_player_info[p->index].num_vehicle[1] + _network_player_info[p->index].num_vehicle[2],
+ /* planes */ _network_player_info[p->index].num_vehicle[3],
+ /* ships */ _network_player_info[p->index].num_vehicle[4]);
+ }
+
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConSayPlayer)
+{
+ if (argc == 0) {
+ IConsoleHelp("Chat to a certain player in a multiplayer game. Usage: 'say_player <player-no> \"<msg>\"'");
+ IConsoleHelp("PlayerNo is the player that plays as company <playerno>, 1 through max_players");
+ return true;
+ }
+
+ if (argc != 3) return false;
+
+ if (atoi(argv[1]) < 1 || atoi(argv[1]) > MAX_PLAYERS) {
+ IConsolePrintF(_icolour_def, "Unknown player. Player range is between 1 and %d.", MAX_PLAYERS);
+ return true;
+ }
+
+ if (!_network_server) {
+ SEND_COMMAND(PACKET_CLIENT_CHAT)(NETWORK_ACTION_CHAT_COMPANY, DESTTYPE_TEAM, atoi(argv[1]), argv[2]);
+ } else {
+ NetworkServer_HandleChat(NETWORK_ACTION_CHAT_COMPANY, DESTTYPE_TEAM, atoi(argv[1]), argv[2], NETWORK_SERVER_INDEX);
+ }
+
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConSayClient)
+{
+ if (argc == 0) {
+ IConsoleHelp("Chat to a certain player in a multiplayer game. Usage: 'say_client <client-no> \"<msg>\"'");
+ IConsoleHelp("For client-id's, see the command 'clients'");
+ return true;
+ }
+
+ if (argc != 3) return false;
+
+ if (!_network_server) {
+ SEND_COMMAND(PACKET_CLIENT_CHAT)(NETWORK_ACTION_CHAT_CLIENT, DESTTYPE_CLIENT, atoi(argv[1]), argv[2]);
+ } else {
+ NetworkServer_HandleChat(NETWORK_ACTION_CHAT_CLIENT, DESTTYPE_CLIENT, atoi(argv[1]), argv[2], NETWORK_SERVER_INDEX);
+ }
+
+ return true;
+}
+
+DEF_CONSOLE_HOOK(ConHookServerPW)
+{
+ if (strcmp(_network_server_password, "*") == 0) {
+ _network_server_password[0] = '\0';
+ _network_game_info.use_password = 0;
+ } else {
+ ttd_strlcpy(_network_game_info.server_password, _network_server_password, sizeof(_network_server_password));
+ _network_game_info.use_password = 1;
+ }
+
+ return true;
+}
+
+DEF_CONSOLE_HOOK(ConHookRconPW)
+{
+ if (strcmp(_network_rcon_password, "*") == 0)
+ _network_rcon_password[0] = '\0';
+
+ ttd_strlcpy(_network_game_info.rcon_password, _network_rcon_password, sizeof(_network_game_info.rcon_password));
+
+ return true;
+}
+
+/* Also use from within player_gui to change the password graphically */
+bool NetworkChangeCompanyPassword(byte argc, char *argv[])
+{
+ if (argc == 0) {
+ if (!IsValidPlayer(_local_player)) return true; // dedicated server
+ IConsolePrintF(_icolour_warn, "Current value for 'company_pw': %s", _network_player_info[_local_player].password);
+ return true;
+ }
+
+ if (!IsValidPlayer(_local_player)) {
+ IConsoleError("You have to own a company to make use of this command.");
+ return false;
+ }
+
+ if (argc != 1) return false;
+
+ if (strcmp(argv[0], "*") == 0) argv[0][0] = '\0';
+
+ ttd_strlcpy(_network_player_info[_local_player].password, argv[0], sizeof(_network_player_info[_local_player].password));
+
+ if (!_network_server)
+ SEND_COMMAND(PACKET_CLIENT_SET_PASSWORD)(_network_player_info[_local_player].password);
+
+ IConsolePrintF(_icolour_warn, "'company_pw' changed to: %s", _network_player_info[_local_player].password);
+
+ return true;
+}
+
+DEF_CONSOLE_HOOK(ConProcPlayerName)
+{
+ NetworkClientInfo *ci = NetworkFindClientInfoFromIndex(_network_own_client_index);
+
+ if (ci == NULL) return false;
+
+ // Don't change the name if it is the same as the old name
+ if (strcmp(ci->client_name, _network_player_name) != 0) {
+ if (!_network_server) {
+ SEND_COMMAND(PACKET_CLIENT_SET_NAME)(_network_player_name);
+ } else {
+ if (NetworkFindName(_network_player_name)) {
+ NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, 1, false, ci->client_name, "%s", _network_player_name);
+ ttd_strlcpy(ci->client_name, _network_player_name, sizeof(ci->client_name));
+ NetworkUpdateClientInfo(NETWORK_SERVER_INDEX);
+ }
+ }
+ }
+
+ return true;
+}
+
+DEF_CONSOLE_HOOK(ConHookServerName)
+{
+ ttd_strlcpy(_network_game_info.server_name, _network_server_name, sizeof(_network_game_info.server_name));
+ return true;
+}
+
+DEF_CONSOLE_HOOK(ConHookServerAdvertise)
+{
+ if (!_network_advertise) // remove us from advertising
+ NetworkUDPRemoveAdvertise();
+
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConProcServerIP)
+{
+ if (argc == 0) {
+ IConsolePrintF(_icolour_warn, "Current value for 'server_ip': %s", inet_ntoa(*(struct in_addr *)&_network_server_bind_ip));
+ return true;
+ }
+
+ if (argc != 1) return false;
+
+ _network_server_bind_ip = (strcmp(argv[0], "all") == 0) ? inet_addr("0.0.0.0") : inet_addr(argv[0]);
+ snprintf(_network_server_bind_ip_host, sizeof(_network_server_bind_ip_host), "%s", inet_ntoa(*(struct in_addr *)&_network_server_bind_ip));
+ IConsolePrintF(_icolour_warn, "'server_ip' changed to: %s", inet_ntoa(*(struct in_addr *)&_network_server_bind_ip));
+ return true;
+}
+#endif /* ENABLE_NETWORK */
+
+DEF_CONSOLE_CMD(ConPatch)
+{
+ if (argc == 0) {
+ IConsoleHelp("Change patch variables for all players. Usage: 'patch <name> [<value>]'");
+ IConsoleHelp("Omitting <value> will print out the current value of the patch-setting.");
+ return true;
+ }
+
+ if (argc == 1 || argc > 3) return false;
+
+ if (argc == 2) {
+ IConsoleGetPatchSetting(argv[1]);
+ } else {
+ uint32 val;
+
+ if (GetArgumentInteger(&val, argv[2])) {
+ if (!IConsoleSetPatchSetting(argv[1], val)) {
+ IConsoleError("This command/variable is only available to a network server.");
+ }
+ }
+ }
+
+ return true;
+}
+
+DEF_CONSOLE_CMD(ConListDumpVariables)
+{
+ const IConsoleVar *var;
+ size_t l = 0;
+
+ if (argc == 0) {
+ IConsoleHelp("List all variables with their value. Usage: 'dump_vars [<pre-filter>]'");
+ return true;
+ }
+
+ if (argv[1] != NULL) l = strlen(argv[1]);
+
+ for (var = _iconsole_vars; var != NULL; var = var->next) {
+ if (argv[1] == NULL || strncmp(var->name, argv[1], l) == 0)
+ IConsoleVarPrintGetValue(var);
+ }
+
+ return true;
+}
+
+
+#ifdef _DEBUG
+/* ****************************************** */
+/* debug commands and variables */
+/* ****************************************** */
+
+static void IConsoleDebugLibRegister(void)
+{
+ // debugging variables and functions
+ extern bool _stdlib_con_developer; /* XXX extern in .c */
+
+ IConsoleVarRegister("con_developer", &_stdlib_con_developer, ICONSOLE_VAR_BOOLEAN, "Enable/disable console debugging information (internal)");
+ IConsoleCmdRegister("resettile", ConResetTile);
+ IConsoleCmdRegister("stopall", ConStopAllVehicles);
+ IConsoleAliasRegister("dbg_echo", "echo %A; echo %B");
+ IConsoleAliasRegister("dbg_echo2", "echo %!");
+}
+#endif
+
+/* ****************************************** */
+/* console command and variable registration */
+/* ****************************************** */
+
+void IConsoleStdLibRegister(void)
+{
+ // stdlib
+ extern byte _stdlib_developer; /* XXX extern in .c */
+
+ // default variables and functions
+ IConsoleCmdRegister("debug_level", ConDebugLevel);
+ IConsoleCmdRegister("dump_vars", ConListDumpVariables);
+ IConsoleCmdRegister("echo", ConEcho);
+ IConsoleCmdRegister("echoc", ConEchoC);
+ IConsoleCmdRegister("exec", ConExec);
+ IConsoleCmdRegister("exit", ConExit);
+ IConsoleCmdRegister("part", ConPart);
+ IConsoleCmdRegister("help", ConHelp);
+ IConsoleCmdRegister("info_cmd", ConInfoCmd);
+ IConsoleCmdRegister("info_var", ConInfoVar);
+ IConsoleCmdRegister("list_cmds", ConListCommands);
+ IConsoleCmdRegister("list_vars", ConListVariables);
+ IConsoleCmdRegister("list_aliases", ConListAliases);
+ IConsoleCmdRegister("newgame", ConNewGame);
+ IConsoleCmdRegister("restart", ConRestart);
+ IConsoleCmdRegister("getseed", ConGetSeed);
+ IConsoleCmdRegister("quit", ConExit);
+ IConsoleCmdRegister("resetengines", ConResetEngines);
+ IConsoleCmdRegister("return", ConReturn);
+ IConsoleCmdRegister("screenshot", ConScreenShot);
+ IConsoleCmdRegister("script", ConScript);
+ IConsoleCmdRegister("scrollto", ConScrollToTile);
+ IConsoleCmdRegister("alias", ConAlias);
+ IConsoleCmdRegister("load", ConLoad);
+ IConsoleCmdRegister("rm", ConRemove);
+ IConsoleCmdRegister("save", ConSave);
+ IConsoleCmdRegister("ls", ConListFiles);
+ IConsoleCmdRegister("cd", ConChangeDirectory);
+ IConsoleCmdRegister("pwd", ConPrintWorkingDirectory);
+ IConsoleCmdRegister("clear", ConClearBuffer);
+ IConsoleCmdRegister("patch", ConPatch);
+
+ IConsoleAliasRegister("dir", "ls");
+ IConsoleAliasRegister("del", "rm %+");
+ IConsoleAliasRegister("newmap", "newgame");
+ IConsoleAliasRegister("new_map", "newgame");
+ IConsoleAliasRegister("new_game", "newgame");
+
+
+ IConsoleVarRegister("developer", &_stdlib_developer, ICONSOLE_VAR_BYTE, "Redirect debugging output from the console/command line to the ingame console (value 2). Default value: 1");
+
+ /* networking variables and functions */
+#ifdef ENABLE_NETWORK
+ /* Network hooks; only active in network */
+ IConsoleCmdHookAdd ("resetengines", ICONSOLE_HOOK_ACCESS, ConHookNoNetwork);
+
+ /*** Networking commands ***/
+ IConsoleCmdRegister("say", ConSay);
+ IConsoleCmdHookAdd("say", ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
+ IConsoleCmdRegister("players", ConPlayers);
+ IConsoleCmdHookAdd("players", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+ IConsoleCmdRegister("say_player", ConSayPlayer);
+ IConsoleCmdHookAdd("say_player", ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
+ IConsoleCmdRegister("say_client", ConSayClient);
+ IConsoleCmdHookAdd("say_client", ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
+
+ IConsoleCmdRegister("connect", ConNetworkConnect);
+ IConsoleCmdHookAdd("connect", ICONSOLE_HOOK_ACCESS, ConHookClientOnly);
+ IConsoleAliasRegister("join", "connect %A");
+ IConsoleCmdRegister("clients", ConNetworkClients);
+ IConsoleCmdHookAdd("clients", ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
+ IConsoleCmdRegister("status", ConStatus);
+ IConsoleCmdHookAdd("status", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+ IConsoleCmdRegister("server_info", ConServerInfo);
+ IConsoleCmdHookAdd("server_info", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+ IConsoleAliasRegister("info", "server_info");
+ IConsoleCmdRegister("rcon", ConRcon);
+ IConsoleCmdHookAdd("rcon", ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
+
+ IConsoleCmdRegister("reset_company", ConResetCompany);
+ IConsoleCmdHookAdd("reset_company", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+ IConsoleAliasRegister("clean_company", "reset_company %A");
+ IConsoleCmdRegister("kick", ConKick);
+ IConsoleCmdHookAdd("kick", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+ IConsoleCmdRegister("ban", ConBan);
+ IConsoleCmdHookAdd("ban", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+ IConsoleCmdRegister("unban", ConUnBan);
+ IConsoleCmdHookAdd("unban", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+ IConsoleCmdRegister("banlist", ConBanList);
+ IConsoleCmdHookAdd("banlist", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+
+ IConsoleCmdRegister("pause", ConPauseGame);
+ IConsoleCmdHookAdd("pause", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+ IConsoleCmdRegister("unpause", ConUnPauseGame);
+ IConsoleCmdHookAdd("unpause", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+
+ /*** Networking variables ***/
+ IConsoleVarRegister("net_frame_freq", &_network_frame_freq, ICONSOLE_VAR_BYTE, "The amount of frames before a command will be (visibly) executed. Default value: 1");
+ IConsoleVarHookAdd("net_frame_freq", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+ IConsoleVarRegister("net_sync_freq", &_network_sync_freq, ICONSOLE_VAR_UINT16, "The amount of frames to check if the game is still in sync. Default value: 100");
+ IConsoleVarHookAdd("net_sync_freq", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+
+ IConsoleVarStringRegister("server_pw", &_network_server_password, sizeof(_network_server_password), "Set the server password to protect your server. Use '*' to clear the password");
+ IConsoleVarHookAdd("server_pw", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+ IConsoleVarHookAdd("server_pw", ICONSOLE_HOOK_POST_ACTION, ConHookServerPW);
+ IConsoleAliasRegister("server_password", "server_pw %+");
+ IConsoleVarStringRegister("rcon_pw", &_network_rcon_password, sizeof(_network_rcon_password), "Set the rcon-password to change server behaviour. Use '*' to disable rcon");
+ IConsoleVarHookAdd("rcon_pw", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+ IConsoleVarHookAdd("rcon_pw", ICONSOLE_HOOK_POST_ACTION, ConHookRconPW);
+ IConsoleAliasRegister("rcon_password", "rcon_pw %+");
+ IConsoleVarStringRegister("company_pw", NULL, 0, "Set a password for your company, so no one without the correct password can join. Use '*' to clear the password");
+ IConsoleVarHookAdd("company_pw", ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
+ IConsoleVarProcAdd("company_pw", NetworkChangeCompanyPassword);
+ IConsoleAliasRegister("company_password", "company_pw %+");
+
+ IConsoleVarStringRegister("name", &_network_player_name, sizeof(_network_player_name), "Set your name for multiplayer");
+ IConsoleVarHookAdd("name", ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
+ IConsoleVarHookAdd("name", ICONSOLE_HOOK_POST_ACTION, ConProcPlayerName);
+ IConsoleVarStringRegister("server_name", &_network_server_name, sizeof(_network_server_name), "Set the name of the server for multiplayer");
+ IConsoleVarHookAdd("server_name", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+ IConsoleVarHookAdd("server_name", ICONSOLE_HOOK_POST_ACTION, ConHookServerName);
+
+ IConsoleVarRegister("server_port", &_network_server_port, ICONSOLE_VAR_UINT32, "Set the server port. Changes take effect the next time you start a server");
+ IConsoleVarRegister("server_ip", &_network_server_bind_ip, ICONSOLE_VAR_UINT32, "Set the IP the server binds to. Changes take effect the next time you start a server. Use 'all' to bind to any IP.");
+ IConsoleVarProcAdd("server_ip", ConProcServerIP);
+ IConsoleAliasRegister("server_bind_ip", "server_ip %+");
+ IConsoleAliasRegister("server_ip_bind", "server_ip %+");
+ IConsoleAliasRegister("server_bind", "server_ip %+");
+ IConsoleVarRegister("server_advertise", &_network_advertise, ICONSOLE_VAR_BOOLEAN, "Set if the server will advertise to the master server and show up there");
+ IConsoleVarHookAdd("server_advertise", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+ IConsoleVarHookAdd("server_advertise", ICONSOLE_HOOK_POST_ACTION, ConHookServerAdvertise);
+
+ IConsoleVarRegister("max_clients", &_network_game_info.clients_max, ICONSOLE_VAR_BYTE, "Control the maximum amount of connected players during runtime. Default value: 10");
+ IConsoleVarHookAdd("max_clients", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+ IConsoleVarHookAdd("max_clients", ICONSOLE_HOOK_POST_ACTION, ConHookValidateMaxClientsCount);
+ IConsoleVarRegister("max_companies", &_network_game_info.companies_max, ICONSOLE_VAR_BYTE, "Control the maximum amount of active companies during runtime. Default value: 8");
+ IConsoleVarHookAdd("max_companies", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+ IConsoleVarHookAdd("max_companies", ICONSOLE_HOOK_POST_ACTION, ConHookValidateMaxCompaniesCount);
+ IConsoleVarRegister("max_spectators", &_network_game_info.spectators_max, ICONSOLE_VAR_BYTE, "Control the maximum amount of active spectators during runtime. Default value: 9");
+ IConsoleVarHookAdd("max_spectators", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+ IConsoleVarHookAdd("max_spectators", ICONSOLE_HOOK_POST_ACTION, ConHookValidateMaxSpectatorsCount);
+
+ IConsoleVarRegister("max_join_time", &_network_max_join_time, ICONSOLE_VAR_UINT16, "Set the maximum amount of time (ticks) a client is allowed to join. Default value: 500");
+
+ IConsoleVarRegister("pause_on_join", &_network_pause_on_join, ICONSOLE_VAR_BOOLEAN, "Set if the server should pause gameplay while a client is joining. This might help slow users");
+ IConsoleVarHookAdd("pause_on_join", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+
+ IConsoleVarRegister("autoclean_companies", &_network_autoclean_companies, ICONSOLE_VAR_BOOLEAN, "Automatically shut down inactive companies to free them up for other players. Customize with 'autoclean_(un)protected'");
+ IConsoleVarHookAdd("autoclean_companies", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+ IConsoleVarRegister("autoclean_protected", &_network_autoclean_protected, ICONSOLE_VAR_BYTE, "Automatically remove the password from an inactive company after the given amount of months");
+ IConsoleVarHookAdd("autoclean_protected", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+ IConsoleVarRegister("autoclean_unprotected", &_network_autoclean_unprotected, ICONSOLE_VAR_BYTE, "Automatically shut down inactive companies after the given amount of months");
+ IConsoleVarHookAdd("autoclean_unprotected", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+ IConsoleVarRegister("restart_game_year", &_network_restart_game_year, ICONSOLE_VAR_UINT16, "Auto-restart the server when Jan 1st of the set year is reached. Use '0' to disable this");
+ IConsoleVarHookAdd("restart_game_year", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+
+ IConsoleVarRegister("min_players", &_network_min_players, ICONSOLE_VAR_BYTE, "Automatically pause the game when the number of active players passes below the given amount");
+ IConsoleVarHookAdd("min_players", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+ IConsoleVarHookAdd("min_players", ICONSOLE_HOOK_POST_ACTION, ConHookCheckMinPlayers);
+
+#endif /* ENABLE_NETWORK */
+
+ // debugging stuff
+#ifdef _DEBUG
+ IConsoleDebugLibRegister();
+#endif
+}
diff --git a/src/currency.c b/src/currency.c
new file mode 100644
index 000000000..7bc81139a
--- /dev/null
+++ b/src/currency.c
@@ -0,0 +1,182 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "currency.h"
+#include "news.h"
+#include "variables.h"
+#include "table/strings.h"
+#include "date.h"
+
+ // exchange rate prefix symbol_pos
+ // | separator | postfix |
+ // | | Euro year | | | name
+ // | | | | | | |
+static const CurrencySpec origin_currency_specs[NUM_CURRENCY] = {
+ { 1, ',', CF_NOEURO, "£", "", 0, STR_CURR_GBP }, // british pounds
+ { 2, ',', CF_NOEURO, "$", "", 0, STR_CURR_USD }, // us dollars
+ { 2, ',', CF_ISEURO, "€", "", 0, STR_CURR_EUR }, // Euro
+ { 220, ',', CF_NOEURO, "Â¥", "", 0, STR_CURR_YEN }, // yen
+ { 20, ',', 2002, "", " S.", 1, STR_CURR_ATS }, // austrian schilling
+ { 59, ',', 2002, "BEF ", "", 0, STR_CURR_BEF }, // belgian franc
+ { 2, ',', CF_NOEURO, "CHF ", "", 0, STR_CURR_CHF }, // swiss franc
+ { 41, ',', CF_NOEURO, "", " KÄ", 1, STR_CURR_CZK }, // czech koruna
+ { 3, '.', 2002, "DM ", "", 0, STR_CURR_DEM }, // deutsche mark
+ { 11, '.', CF_NOEURO, "", " kr", 1, STR_CURR_DKK }, // danish krone
+ { 245, '.', 2002, "Pts ", "", 0, STR_CURR_ESP }, // spanish pesetas
+ { 9, ',', 2002, "", " mk", 1, STR_CURR_FIM }, // finnish markka
+ { 10, '.', 2002, "FF ", "", 0, STR_CURR_FRF }, // french francs
+ { 500, ',', 2002, "", "Dr.", 1, STR_CURR_GRD }, // greek drachma
+ { 378, ',', 2010, "", " Ft", 1, STR_CURR_HUF }, // hungarian forint
+ { 130, '.', CF_NOEURO, "", " Kr", 1, STR_CURR_ISK }, // icelandic krona
+ { 2850, ',', 2002, "", " L.", 1, STR_CURR_ITL }, // italian lira
+ { 3, ',', 2002, "NLG ", "", 0, STR_CURR_NLG }, // dutch gulden
+ { 12, '.', CF_NOEURO, "", " Kr", 1, STR_CURR_NOK }, // norwegian krone
+ { 6, ' ', CF_NOEURO, "", " zl", 1, STR_CURR_PLN }, // polish zloty
+ { 5, '.', CF_NOEURO, "", " Lei", 1, STR_CURR_ROL }, // romanian Lei
+ { 50, ' ', CF_NOEURO, "", " p", 1, STR_CURR_RUR }, // russian rouble
+ { 352, '.', CF_NOEURO, "", " SIT", 1, STR_CURR_SIT }, // slovenian tolar
+ { 13, '.', CF_NOEURO, "", " Kr", 1, STR_CURR_SEK }, // swedish krona
+ { 3, '.', CF_NOEURO, "", " YTL", 1, STR_CURR_YTL }, // turkish lira
+ { 52, ',', CF_NOEURO, "", " Sk", 1, STR_CURR_SKK }, // slovak koruna
+ { 4, ',', CF_NOEURO, "R$ ", "", 0, STR_CURR_BRR }, // brazil real
+ { 1, ' ', CF_NOEURO, "", "", 2, STR_CURR_CUSTOM }, // custom currency
+};
+
+/* Array of currencies used by the system */
+CurrencySpec _currency_specs[NUM_CURRENCY];
+
+/**
+ * These enums are only declared in order to make sens
+ * out of the TTDPatch_To_OTTDIndex array that will follow
+ * Every currency used by Ottd is there, just in case TTDPatch will
+ * add those missing in its code
+ **/
+enum {
+ CURR_GBP,
+ CURR_USD,
+ CURR_EUR,
+ CURR_YEN,
+ CURR_ATS,
+ CURR_BEF,
+ CURR_CHF,
+ CURR_CZK,
+ CURR_DEM,
+ CURR_DKK,
+ CURR_ESP,
+ CURR_FIM,
+ CURR_FRF,
+ CURR_GRD,
+ CURR_HUF,
+ CURR_ISK,
+ CURR_ITL,
+ CURR_NLG,
+ CURR_NOK,
+ CURR_PLN,
+ CURR_ROL,
+ CURR_RUR,
+ CURR_SIT,
+ CURR_SEK,
+ CURR_YTL,
+};
+
+/**
+ * This array represent the position of OpenTTD's currencies,
+ * compared to TTDPatch's ones.
+ * When a grf sends currencies, they are based on the order defined by TTDPatch.
+ * So, we must reindex them to our own order.
+ **/
+const byte TTDPatch_To_OTTDIndex[] =
+{
+ CURR_GBP,
+ CURR_USD,
+ CURR_FRF,
+ CURR_DEM,
+ CURR_YEN,
+ CURR_ESP,
+ CURR_HUF,
+ CURR_PLN,
+ CURR_ATS,
+ CURR_BEF,
+ CURR_DKK,
+ CURR_FIM,
+ CURR_GRD,
+ CURR_CHF,
+ CURR_NLG,
+ CURR_ITL,
+ CURR_SEK,
+ CURR_RUR,
+ CURR_EUR,
+};
+
+/**
+ * Will return the ottd's index correspondance to
+ * the ttdpatch's id. If the id is bigger then the array,
+ * it is a grf written for ottd, thus returning the same id.
+ * Only called from newgrf.c
+ * @param grfcurr_id currency id coming from newgrf
+ * @return the corrected index
+ **/
+byte GetNewgrfCurrencyIdConverted(byte grfcurr_id)
+{
+ return (grfcurr_id >= lengthof(TTDPatch_To_OTTDIndex)) ? grfcurr_id : TTDPatch_To_OTTDIndex[grfcurr_id];
+}
+
+/* get a mask of the allowed currencies depending on the year */
+uint GetMaskOfAllowedCurrencies(void)
+{
+ uint mask = 0;
+ uint i;
+
+ for (i = 0; i < NUM_CURRENCY; i++) {
+ Year to_euro = _currency_specs[i].to_euro;
+
+ if (to_euro != CF_NOEURO && to_euro != CF_ISEURO && _cur_year >= to_euro) continue;
+ if (to_euro == CF_ISEURO && _cur_year < 2000) continue;
+ mask |= (1 << i);
+ }
+ mask |= (1 << CUSTOM_CURRENCY_ID); // always allow custom currency
+ return mask;
+}
+
+/**
+ * Verify if the currency chosen by the user is about to be converted to Euro
+ **/
+void CheckSwitchToEuro(void)
+{
+ if (_currency_specs[_opt.currency].to_euro != CF_NOEURO &&
+ _currency_specs[_opt.currency].to_euro != CF_ISEURO &&
+ _cur_year >= _currency_specs[_opt.currency].to_euro) {
+ _opt.currency = 2; // this is the index of euro above.
+ AddNewsItem(STR_EURO_INTRODUCE, NEWS_FLAGS(NM_NORMAL, 0, NT_ECONOMY, 0), 0, 0);
+ }
+}
+
+/**
+ * Called only from newgrf.c. Will fill _currency_specs array with
+ * default values from origin_currency_specs
+ **/
+void ResetCurrencies(void)
+{
+ memcpy(&_currency_specs, &origin_currency_specs, sizeof(origin_currency_specs));
+}
+
+/**
+ * Build a list of currency names StringIDs to use in a dropdown list
+ * @return Pointer to a (static) array of StringIDs
+ */
+StringID* BuildCurrencyDropdown(void)
+{
+ /* Allow room for all currencies, plus a terminator entry */
+ static StringID names[CUSTOM_CURRENCY_ID];
+ uint i;
+
+ /* Add each name */
+ for (i = 0; i < NUM_CURRENCY; i++) {
+ names[i] = _currency_specs[i].name;
+ }
+ /* Terminate the list */
+ names[i] = INVALID_STRING_ID;
+
+ return names;
+}
diff --git a/src/currency.h b/src/currency.h
new file mode 100644
index 000000000..40fb553a4
--- /dev/null
+++ b/src/currency.h
@@ -0,0 +1,45 @@
+/* $Id$ */
+
+#ifndef CURRENCY_H
+#define CURRENCY_H
+
+enum {
+ CF_NOEURO = 0,
+ CF_ISEURO = 1,
+ NUM_CURRENCY = 28,
+ CUSTOM_CURRENCY_ID = NUM_CURRENCY - 1
+};
+
+typedef struct {
+ uint16 rate;
+ char separator;
+ Year to_euro;
+ char prefix[16];
+ char suffix[16];
+ /**
+ * The currency symbol is represented by two possible values, prefix and suffix
+ * Usage of one or the other is determined by symbol_pos.
+ * 0 = prefix
+ * 1 = suffix
+ * 2 = both : Special case only for custom currency.
+ * It is not a spec from Newgrf,
+ * rather a way to let users do what they want with custom curency
+ */
+ byte symbol_pos;
+ StringID name;
+} CurrencySpec;
+
+
+extern CurrencySpec _currency_specs[NUM_CURRENCY];
+
+// XXX small hack, but makes the rest of the code a bit nicer to read
+#define _custom_currency (_currency_specs[CUSTOM_CURRENCY_ID])
+#define _currency ((const CurrencySpec*)&_currency_specs[_opt_ptr->currency])
+
+uint GetMaskOfAllowedCurrencies(void);
+void CheckSwitchToEuro(void);
+void ResetCurrencies(void);
+StringID* BuildCurrencyDropdown(void);
+byte GetNewgrfCurrencyIdConverted(byte grfcurr_id);
+
+#endif /* CURRENCY_H */
diff --git a/src/date.c b/src/date.c
new file mode 100644
index 000000000..856ca4528
--- /dev/null
+++ b/src/date.c
@@ -0,0 +1,304 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "date.h"
+#include "variables.h"
+#include "macros.h"
+#include "vehicle.h"
+#include "network/network.h"
+#include "network/network_data.h"
+#include "network/network_server.h"
+#include "functions.h"
+#include "currency.h"
+
+Year _cur_year;
+Month _cur_month;
+Date _date;
+DateFract _date_fract;
+
+
+void SetDate(Date date)
+{
+ YearMonthDay ymd;
+
+ _date = date;
+ ConvertDateToYMD(date, &ymd);
+ _cur_year = ymd.year;
+ _cur_month = ymd.month;
+#ifdef ENABLE_NETWORK
+ _network_last_advertise_frame = 0;
+ _network_need_advertise = true;
+#endif /* ENABLE_NETWORK */
+}
+
+#define M(a, b) ((a << 5) | b)
+static const uint16 _month_date_from_year_day[] = {
+ M( 0, 1), M( 0, 2), M( 0, 3), M( 0, 4), M( 0, 5), M( 0, 6), M( 0, 7), M( 0, 8), M( 0, 9), M( 0, 10), M( 0, 11), M( 0, 12), M( 0, 13), M( 0, 14), M( 0, 15), M( 0, 16), M( 0, 17), M( 0, 18), M( 0, 19), M( 0, 20), M( 0, 21), M( 0, 22), M( 0, 23), M( 0, 24), M( 0, 25), M( 0, 26), M( 0, 27), M( 0, 28), M( 0, 29), M( 0, 30), M( 0, 31),
+ M( 1, 1), M( 1, 2), M( 1, 3), M( 1, 4), M( 1, 5), M( 1, 6), M( 1, 7), M( 1, 8), M( 1, 9), M( 1, 10), M( 1, 11), M( 1, 12), M( 1, 13), M( 1, 14), M( 1, 15), M( 1, 16), M( 1, 17), M( 1, 18), M( 1, 19), M( 1, 20), M( 1, 21), M( 1, 22), M( 1, 23), M( 1, 24), M( 1, 25), M( 1, 26), M( 1, 27), M( 1, 28), M( 1, 29),
+ M( 2, 1), M( 2, 2), M( 2, 3), M( 2, 4), M( 2, 5), M( 2, 6), M( 2, 7), M( 2, 8), M( 2, 9), M( 2, 10), M( 2, 11), M( 2, 12), M( 2, 13), M( 2, 14), M( 2, 15), M( 2, 16), M( 2, 17), M( 2, 18), M( 2, 19), M( 2, 20), M( 2, 21), M( 2, 22), M( 2, 23), M( 2, 24), M( 2, 25), M( 2, 26), M( 2, 27), M( 2, 28), M( 2, 29), M( 2, 30), M( 2, 31),
+ M( 3, 1), M( 3, 2), M( 3, 3), M( 3, 4), M( 3, 5), M( 3, 6), M( 3, 7), M( 3, 8), M( 3, 9), M( 3, 10), M( 3, 11), M( 3, 12), M( 3, 13), M( 3, 14), M( 3, 15), M( 3, 16), M( 3, 17), M( 3, 18), M( 3, 19), M( 3, 20), M( 3, 21), M( 3, 22), M( 3, 23), M( 3, 24), M( 3, 25), M( 3, 26), M( 3, 27), M( 3, 28), M( 3, 29), M( 3, 30),
+ M( 4, 1), M( 4, 2), M( 4, 3), M( 4, 4), M( 4, 5), M( 4, 6), M( 4, 7), M( 4, 8), M( 4, 9), M( 4, 10), M( 4, 11), M( 4, 12), M( 4, 13), M( 4, 14), M( 4, 15), M( 4, 16), M( 4, 17), M( 4, 18), M( 4, 19), M( 4, 20), M( 4, 21), M( 4, 22), M( 4, 23), M( 4, 24), M( 4, 25), M( 4, 26), M( 4, 27), M( 4, 28), M( 4, 29), M( 4, 30), M( 4, 31),
+ M( 5, 1), M( 5, 2), M( 5, 3), M( 5, 4), M( 5, 5), M( 5, 6), M( 5, 7), M( 5, 8), M( 5, 9), M( 5, 10), M( 5, 11), M( 5, 12), M( 5, 13), M( 5, 14), M( 5, 15), M( 5, 16), M( 5, 17), M( 5, 18), M( 5, 19), M( 5, 20), M( 5, 21), M( 5, 22), M( 5, 23), M( 5, 24), M( 5, 25), M( 5, 26), M( 5, 27), M( 5, 28), M( 5, 29), M( 5, 30),
+ M( 6, 1), M( 6, 2), M( 6, 3), M( 6, 4), M( 6, 5), M( 6, 6), M( 6, 7), M( 6, 8), M( 6, 9), M( 6, 10), M( 6, 11), M( 6, 12), M( 6, 13), M( 6, 14), M( 6, 15), M( 6, 16), M( 6, 17), M( 6, 18), M( 6, 19), M( 6, 20), M( 6, 21), M( 6, 22), M( 6, 23), M( 6, 24), M( 6, 25), M( 6, 26), M( 6, 27), M( 6, 28), M( 6, 29), M( 6, 30), M( 6, 31),
+ M( 7, 1), M( 7, 2), M( 7, 3), M( 7, 4), M( 7, 5), M( 7, 6), M( 7, 7), M( 7, 8), M( 7, 9), M( 7, 10), M( 7, 11), M( 7, 12), M( 7, 13), M( 7, 14), M( 7, 15), M( 7, 16), M( 7, 17), M( 7, 18), M( 7, 19), M( 7, 20), M( 7, 21), M( 7, 22), M( 7, 23), M( 7, 24), M( 7, 25), M( 7, 26), M( 7, 27), M( 7, 28), M( 7, 29), M( 7, 30), M( 7, 31),
+ M( 8, 1), M( 8, 2), M( 8, 3), M( 8, 4), M( 8, 5), M( 8, 6), M( 8, 7), M( 8, 8), M( 8, 9), M( 8, 10), M( 8, 11), M( 8, 12), M( 8, 13), M( 8, 14), M( 8, 15), M( 8, 16), M( 8, 17), M( 8, 18), M( 8, 19), M( 8, 20), M( 8, 21), M( 8, 22), M( 8, 23), M( 8, 24), M( 8, 25), M( 8, 26), M( 8, 27), M( 8, 28), M( 8, 29), M( 8, 30),
+ M( 9, 1), M( 9, 2), M( 9, 3), M( 9, 4), M( 9, 5), M( 9, 6), M( 9, 7), M( 9, 8), M( 9, 9), M( 9, 10), M( 9, 11), M( 9, 12), M( 9, 13), M( 9, 14), M( 9, 15), M( 9, 16), M( 9, 17), M( 9, 18), M( 9, 19), M( 9, 20), M( 9, 21), M( 9, 22), M( 9, 23), M( 9, 24), M( 9, 25), M( 9, 26), M( 9, 27), M( 9, 28), M( 9, 29), M( 9, 30), M( 9, 31),
+ M(10, 1), M(10, 2), M(10, 3), M(10, 4), M(10, 5), M(10, 6), M(10, 7), M(10, 8), M(10, 9), M(10, 10), M(10, 11), M(10, 12), M(10, 13), M(10, 14), M(10, 15), M(10, 16), M(10, 17), M(10, 18), M(10, 19), M(10, 20), M(10, 21), M(10, 22), M(10, 23), M(10, 24), M(10, 25), M(10, 26), M(10, 27), M(10, 28), M(10, 29), M(10, 30),
+ M(11, 1), M(11, 2), M(11, 3), M(11, 4), M(11, 5), M(11, 6), M(11, 7), M(11, 8), M(11, 9), M(11, 10), M(11, 11), M(11, 12), M(11, 13), M(11, 14), M(11, 15), M(11, 16), M(11, 17), M(11, 18), M(11, 19), M(11, 20), M(11, 21), M(11, 22), M(11, 23), M(11, 24), M(11, 25), M(11, 26), M(11, 27), M(11, 28), M(11, 29), M(11, 30), M(11, 31),
+};
+#undef M
+
+enum {
+ ACCUM_JAN = 0,
+ ACCUM_FEB = ACCUM_JAN + 31,
+ ACCUM_MAR = ACCUM_FEB + 29,
+ ACCUM_APR = ACCUM_MAR + 31,
+ ACCUM_MAY = ACCUM_APR + 30,
+ ACCUM_JUN = ACCUM_MAY + 31,
+ ACCUM_JUL = ACCUM_JUN + 30,
+ ACCUM_AUG = ACCUM_JUL + 31,
+ ACCUM_SEP = ACCUM_AUG + 31,
+ ACCUM_OCT = ACCUM_SEP + 30,
+ ACCUM_NOV = ACCUM_OCT + 31,
+ ACCUM_DEC = ACCUM_NOV + 30,
+};
+
+static const uint16 _accum_days_for_month[] = {
+ ACCUM_JAN, ACCUM_FEB, ACCUM_MAR, ACCUM_APR,
+ ACCUM_MAY, ACCUM_JUN, ACCUM_JUL, ACCUM_AUG,
+ ACCUM_SEP, ACCUM_OCT, ACCUM_NOV, ACCUM_DEC,
+};
+
+static inline bool IsLeapYear(Year yr)
+{
+ return yr % 4 == 0 && (yr % 100 != 0 || yr % 400 == 0);
+}
+
+/**
+ * Converts a Date to a Year, Month & Day.
+ * @param date the date to convert from
+ * @param ymd the year, month and day to write to
+ */
+void ConvertDateToYMD(Date date, YearMonthDay *ymd)
+{
+ /*
+ * Year determination in multiple steps to account for leap
+ * years. First do the large steps, then the smaller ones.
+ */
+
+ /* There are 97 leap years in 400 years */
+ Year yr = 400 * (date / (365 * 400 + 97));
+ int rem = date % (365 * 400 + 97);
+ uint16 x;
+
+ if (rem >= 365 * 100 + 25) {
+ /* There are 25 leap years in the first 100 years after
+ * every 400th year, as every 400th year is a leap year */
+ yr += 100;
+ rem -= 365 * 100 + 25;
+
+ /* There are 24 leap years in the next couple of 100 years */
+ yr += 100 * (rem / (365 * 100 + 24));
+ rem = (rem % (365 * 100 + 24));
+ }
+
+ if (!IsLeapYear(yr) && rem >= 365 * 4) {
+ /* The first 4 year of the century are not always a leap year */
+ yr += 4;
+ rem -= 365 * 4;
+ }
+
+ /* There is 1 leap year every 4 years */
+ yr += 4 * (rem / (365 * 4 + 1));
+ rem = rem % (365 * 4 + 1);
+
+ /* The last (max 3) years to account for; the first one
+ * can be, but is not necessarily a leap year */
+ while (rem >= (IsLeapYear(yr) ? 366 : 365)) {
+ rem -= IsLeapYear(yr) ? 366 : 365;
+ yr++;
+ }
+
+ /* Skip the 29th of February in non-leap years */
+ if (!IsLeapYear(yr) && rem >= ACCUM_MAR - 1) rem++;
+
+ ymd->year = yr;
+
+ x = _month_date_from_year_day[rem];
+ ymd->month = x >> 5;
+ ymd->day = x & 0x1F;
+}
+
+/**
+ * Converts a tupe of Year, Month and Day to a Date.
+ * @param year is a number between 0..MAX_YEAR
+ * @param month is a number between 0..11
+ * @param day is a number between 1..31
+ */
+Date ConvertYMDToDate(Year year, Month month, Day day)
+{
+ /*
+ * Each passed leap year adds one day to the 'day count'.
+ *
+ * A special case for the year 0 as no year has been passed,
+ * but '(year - 1) / 4' does not yield '-1' to counteract the
+ * '+1' at the end of the formula as divisions round to zero.
+ */
+ int nr_of_leap_years = (year == 0) ? 0 : ((year - 1) / 4 - (year - 1) / 100 + (year - 1) / 400 + 1);
+
+ /* Day-offset in a leap year */
+ int days = _accum_days_for_month[month] + day - 1;
+
+ /* Account for the missing of the 29th of February in non-leap years */
+ if (!IsLeapYear(year) && days >= ACCUM_MAR) days--;
+
+ return year * 365 + nr_of_leap_years + days;
+}
+
+/** Functions used by the IncreaseDate function */
+
+extern void OnNewDay_Train(Vehicle *v);
+extern void OnNewDay_RoadVeh(Vehicle *v);
+extern void OnNewDay_Aircraft(Vehicle *v);
+extern void OnNewDay_Ship(Vehicle *v);
+static void OnNewDay_EffectVehicle(Vehicle *v) { /* empty */ }
+extern void OnNewDay_DisasterVehicle(Vehicle *v);
+
+typedef void OnNewVehicleDayProc(Vehicle *v);
+
+static OnNewVehicleDayProc * _on_new_vehicle_day_proc[] = {
+ OnNewDay_Train,
+ OnNewDay_RoadVeh,
+ OnNewDay_Ship,
+ OnNewDay_Aircraft,
+ OnNewDay_EffectVehicle,
+ OnNewDay_DisasterVehicle,
+};
+
+extern void WaypointsDailyLoop(void);
+extern void TextMessageDailyLoop(void);
+extern void EnginesDailyLoop(void);
+extern void DisasterDailyLoop(void);
+
+extern void PlayersMonthlyLoop(void);
+extern void EnginesMonthlyLoop(void);
+extern void TownsMonthlyLoop(void);
+extern void IndustryMonthlyLoop(void);
+extern void StationMonthlyLoop(void);
+
+extern void PlayersYearlyLoop(void);
+extern void TrainsYearlyLoop(void);
+extern void RoadVehiclesYearlyLoop(void);
+extern void AircraftYearlyLoop(void);
+extern void ShipsYearlyLoop(void);
+
+extern void ShowEndGameChart(void);
+
+
+static const Month _autosave_months[] = {
+ 0, // never
+ 1, // every month
+ 3, // every 3 months
+ 6, // every 6 months
+ 12, // every 12 months
+};
+
+/**
+ * Runs the day_proc for every DAY_TICKS vehicle starting at daytick.
+ */
+static void RunVehicleDayProc(uint daytick)
+{
+ uint total = GetMaxVehicleIndex() + 1;
+ uint i;
+
+ for (i = daytick; i < total; i += DAY_TICKS) {
+ Vehicle *v = GetVehicle(i);
+
+ if (IsValidVehicle(v)) _on_new_vehicle_day_proc[v->type - 0x10](v);
+ }
+}
+
+void IncreaseDate(void)
+{
+ YearMonthDay ymd;
+
+ if (_game_mode == GM_MENU) {
+ _tick_counter++;
+ return;
+ }
+
+ RunVehicleDayProc(_date_fract);
+
+ /* increase day, and check if a new day is there? */
+ _tick_counter++;
+
+ _date_fract++;
+ if (_date_fract < DAY_TICKS) return;
+ _date_fract = 0;
+
+ /* yeah, increase day counter and call various daily loops */
+ _date++;
+
+ TextMessageDailyLoop();
+
+ DisasterDailyLoop();
+ WaypointsDailyLoop();
+
+ if (_game_mode != GM_MENU) {
+ InvalidateWindowWidget(WC_STATUS_BAR, 0, 0);
+ EnginesDailyLoop();
+ }
+
+ /* check if we entered a new month? */
+ ConvertDateToYMD(_date, &ymd);
+ if (ymd.month == _cur_month) return;
+ _cur_month = ymd.month;
+
+ /* yes, call various monthly loops */
+ if (_game_mode != GM_MENU) {
+ if (_opt.autosave != 0 && (_cur_month % _autosave_months[_opt.autosave]) == 0) {
+ _do_autosave = true;
+ RedrawAutosave();
+ }
+
+ PlayersMonthlyLoop();
+ EnginesMonthlyLoop();
+ TownsMonthlyLoop();
+ IndustryMonthlyLoop();
+ StationMonthlyLoop();
+ if (_network_server) NetworkServerMonthlyLoop();
+ }
+
+ /* check if we entered a new year? */
+ if (ymd.year == _cur_year) return;
+ _cur_year = ymd.year;
+
+ /* yes, call various yearly loops */
+ PlayersYearlyLoop();
+ TrainsYearlyLoop();
+ RoadVehiclesYearlyLoop();
+ AircraftYearlyLoop();
+ ShipsYearlyLoop();
+ if (_network_server) NetworkServerYearlyLoop();
+
+ /* check if we reached end of the game */
+ if (_cur_year == _patches.ending_year) {
+ ShowEndGameChart();
+ /* check if we reached the maximum year, decrement dates by a year */
+ } else if (_cur_year == MAX_YEAR + 1) {
+ Vehicle *v;
+ uint days_this_year;
+
+ _cur_year--;
+ days_this_year = IsLeapYear(_cur_year) ? 366 : 365;
+ _date -= days_this_year;
+ FOR_ALL_VEHICLES(v) v->date_of_last_service -= days_this_year;
+
+ /* Because the _date wraps here, and text-messages expire by game-days, we have to clean out
+ * all of them if the date is set back, else those messages will hang for ever */
+ InitTextMessage();
+ }
+
+ if (_patches.auto_euro) CheckSwitchToEuro();
+}
diff --git a/src/date.h b/src/date.h
new file mode 100644
index 000000000..488a9dc3a
--- /dev/null
+++ b/src/date.h
@@ -0,0 +1,61 @@
+/* $Id$ */
+
+#ifndef DATE_H
+#define DATE_H
+
+#include "openttd.h"
+
+/**
+ * 1 day is 74 ticks; _date_fract used to be uint16 and incremented by 885. On
+ * an overflow the new day begun and 65535 / 885 = 74.
+ * 1 tick is approximately 30 ms.
+ * 1 day is thus about 2 seconds (74 * 30 = 2220) on a machine that can run OpenTTD normally
+ */
+#define DAY_TICKS 74
+
+/*
+ * ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR and DAYS_TILL_ORIGINAL_BASE_YEAR are
+ * primarily used for loading newgrf and savegame data and returning some
+ * newgrf (callback) functions that were in the original (TTD) inherited
+ * format, where '_date == 0' meant that it was 1920-01-01.
+ */
+
+/** The minimum starting year/base year of the original TTD */
+#define ORIGINAL_BASE_YEAR 1920
+/** The maximum year of the original TTD */
+#define ORIGINAL_MAX_YEAR 2090
+
+/**
+ * The offset in days from the '_date == 0' till
+ * 'ConvertYMDToDate(ORIGINAL_BASE_YEAR, 0, 1)'
+ */
+#define DAYS_TILL_ORIGINAL_BASE_YEAR (365 * ORIGINAL_BASE_YEAR + ORIGINAL_BASE_YEAR / 4 - ORIGINAL_BASE_YEAR / 100 + ORIGINAL_BASE_YEAR / 400)
+
+/* The absolute minimum & maximum years in OTTD */
+#define MIN_YEAR 0
+/* MAX_YEAR, nicely rounded value of the number of years that can
+ * be encoded in a single 32 bits date, about 2^31 / 366 years. */
+#define MAX_YEAR 5000000
+
+/* Year and Date are defined elsewhere */
+typedef uint8 Month;
+typedef uint8 Day;
+typedef uint16 DateFract;
+
+typedef struct YearMonthDay {
+ Year year;
+ Month month;
+ Day day;
+} YearMonthDay;
+
+extern Year _cur_year;
+extern Month _cur_month;
+extern Date _date;
+extern DateFract _date_fract;
+
+
+void SetDate(Date date);
+void ConvertDateToYMD(Date date, YearMonthDay *ymd);
+Date ConvertYMDToDate(Year year, Month month, Day day);
+
+#endif /* DATE_H */
diff --git a/src/debug.c b/src/debug.c
new file mode 100644
index 000000000..536d21c6a
--- /dev/null
+++ b/src/debug.c
@@ -0,0 +1,153 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include <stdio.h>
+#include <stdarg.h>
+#include "openttd.h"
+#include "console.h"
+#include "debug.h"
+#include "functions.h"
+#include "string.h"
+
+int _debug_ai_level;
+int _debug_driver_level;
+int _debug_grf_level;
+int _debug_map_level;
+int _debug_misc_level;
+int _debug_ms_level;
+int _debug_net_level;
+int _debug_sprite_level;
+int _debug_oldloader_level;
+int _debug_ntp_level;
+int _debug_npf_level;
+int _debug_yapf_level;
+int _debug_freetype_level;
+int _debug_sl_level;
+
+
+typedef struct DebugLevel {
+ const char *name;
+ int *level;
+} DebugLevel;
+
+#define DEBUG_LEVEL(x) { #x, &_debug_##x##_level }
+ static const DebugLevel debug_level[] = {
+ DEBUG_LEVEL(ai),
+ DEBUG_LEVEL(driver),
+ DEBUG_LEVEL(grf),
+ DEBUG_LEVEL(map),
+ DEBUG_LEVEL(misc),
+ DEBUG_LEVEL(ms),
+ DEBUG_LEVEL(net),
+ DEBUG_LEVEL(sprite),
+ DEBUG_LEVEL(oldloader),
+ DEBUG_LEVEL(ntp),
+ DEBUG_LEVEL(npf),
+ DEBUG_LEVEL(yapf),
+ DEBUG_LEVEL(freetype),
+ DEBUG_LEVEL(sl),
+ };
+#undef DEBUG_LEVEL
+
+#if !defined(NO_DEBUG_MESSAGES)
+
+/** Functionized DEBUG macro for compilers that don't support
+ * variadic macros (__VA_ARGS__) such as...yes MSVC2003 and lower */
+#if defined(NO_VARARG_MACRO)
+void CDECL DEBUG(int name, int level, ...)
+{
+ va_list va;
+ const char *dbg;
+ const DebugLevel *dl = &debug_level[name];
+
+ if (level != 0 && *dl->level < level) return;
+ dbg = dl->name;
+ va_start(va, level);
+#else
+void CDECL debug(const char *dbg, ...)
+{
+ va_list va;
+ va_start(va, dbg);
+#endif /* NO_VARARG_MACRO */
+ {
+ const char *s;
+ char buf[1024];
+
+ s = va_arg(va, const char*);
+ vsnprintf(buf, lengthof(buf), s, va);
+ va_end(va);
+ fprintf(stderr, "dbg: [%s] %s\n", dbg, buf);
+ IConsoleDebug(dbg, buf);
+ }
+}
+#endif /* NO_DEBUG_MESSAGES */
+
+void SetDebugString(const char *s)
+{
+ int v;
+ char *end;
+ const char *t;
+
+ // global debugging level?
+ if (*s >= '0' && *s <= '9') {
+ const DebugLevel *i;
+
+ v = strtoul(s, &end, 0);
+ s = end;
+
+ for (i = debug_level; i != endof(debug_level); ++i) *i->level = v;
+ }
+
+ // individual levels
+ for (;;) {
+ const DebugLevel *i;
+ int *p;
+
+ // skip delimiters
+ while (*s == ' ' || *s == ',' || *s == '\t') s++;
+ if (*s == '\0') break;
+
+ t = s;
+ while (*s >= 'a' && *s <= 'z') s++;
+
+ // check debugging levels
+ p = NULL;
+ for (i = debug_level; i != endof(debug_level); ++i)
+ if (s == t + strlen(i->name) && strncmp(t, i->name, s - t) == 0) {
+ p = i->level;
+ break;
+ }
+
+ if (*s == '=') s++;
+ v = strtoul(s, &end, 0);
+ s = end;
+ if (p != NULL) {
+ *p = v;
+ } else {
+ ShowInfoF("Unknown debug level '%.*s'", s - t, t);
+ return;
+ }
+ }
+}
+
+/** Print out the current debug-level
+ * Just return a string with the values of all the debug categorites
+ * @return string with debug-levels
+ */
+const char *GetDebugString(void)
+{
+ const DebugLevel *i;
+ static char dbgstr[100];
+ char dbgval[20];
+
+ memset(dbgstr, 0, sizeof(dbgstr));
+ i = debug_level;
+ snprintf(dbgstr, sizeof(dbgstr), "%s=%d", i->name, *i->level);
+
+ for (i++; i != endof(debug_level); i++) {
+ snprintf(dbgval, sizeof(dbgval), ", %s=%d", i->name, *i->level);
+ ttd_strlcat(dbgstr, dbgval, sizeof(dbgstr));
+ }
+
+ return dbgstr;
+}
diff --git a/src/debug.h b/src/debug.h
new file mode 100644
index 000000000..c99795ddd
--- /dev/null
+++ b/src/debug.h
@@ -0,0 +1,108 @@
+/* $Id$ */
+
+#ifndef DEBUG_H
+#define DEBUG_H
+
+/* Debugging messages policy:
+ * These should be the severities used for direct DEBUG() calls
+ * maximum debugging level should be 10 if really deep, deep
+ * debugging is needed.
+ * (there is room for exceptions, but you have to have a good cause):
+ * 0 - errors or severe warnings
+ * 1 - other non-fatal, non-severe warnings
+ * 2 - crude progress indicator of functionality
+ * 3 - important debugging messages (function entry)
+ * 4 - debugging messages (crude loop status, etc.)
+ * 5 - detailed debugging information
+ * 6.. - extremely detailed spamming
+ */
+
+/* Of course MSVC 2003 and lower has no support for variadic macros
+ * so we need to work around this... *sigh* */
+#if defined(_MSC_VER) && (_MSC_VER < 1400)
+ #define NO_VARARG_MACRO
+#endif
+
+#if defined(NO_VARARG_MACRO)
+ enum DebugLevelType {
+ ai,
+ driver,
+ grf,
+ map,
+ misc,
+ ms,
+ net,
+ sprite,
+ oldloader,
+ ntp,
+ npf,
+ yapf,
+ freetype,
+ sl,
+ };
+#endif /* NO_VARARG_MACRO */
+
+#ifdef NO_DEBUG_MESSAGES
+ #if defined(NO_VARARG_MACRO)
+ static inline void DEBUG(int name, int level, ...) {}
+ #elif defined(__GNUC__) && (__GNUC__ < 3)
+ #define DEBUG(name, level, args...)
+ #else
+ #define DEBUG(name, level, ...)
+ #endif
+#else /* NO_DEBUG_MESSAGES */
+ #if defined(NO_VARARG_MACRO)
+ void CDECL DEBUG(int name, int level, ...);
+ #elif defined(__GNUC__) && (__GNUC__ < 3)
+ #define DEBUG(name, level, args...) if ((level == 0) || ( _debug_ ## name ## _level >= level)) debug(#name, args)
+ #else
+ #define DEBUG(name, level, ...) if (level == 0 || _debug_ ## name ## _level >= level) debug(#name, __VA_ARGS__)
+ #endif
+
+ extern int _debug_ai_level;
+ extern int _debug_driver_level;
+ extern int _debug_grf_level;
+ extern int _debug_map_level;
+ extern int _debug_misc_level;
+ extern int _debug_ms_level;
+ extern int _debug_net_level;
+ extern int _debug_sprite_level;
+ extern int _debug_oldloader_level;
+ extern int _debug_ntp_level;
+ extern int _debug_npf_level;
+ extern int _debug_yapf_level;
+ extern int _debug_freetype_level;
+ extern int _debug_sl_level;
+
+ #if !defined(NO_VARARG_MACRO)
+ void CDECL debug(const char *dbg, ...);
+ #endif /* NO_VARARG_MACRO */
+#endif /* NO_DEBUG_MESSAGES */
+
+void SetDebugString(const char *s);
+const char *GetDebugString(void);
+
+/* MSVCRT of course has to have a different syntax for long long *sigh* */
+#if defined(_MSC_VER) || defined(__MINGW32__)
+ #define OTTD_PRINTF64 "I64"
+#else
+ #define OTTD_PRINTF64 "ll"
+#endif
+
+// Used for profiling
+#define TIC() {\
+ extern uint64 _rdtsc(void);\
+ uint64 _xxx_ = _rdtsc();\
+ static uint64 __sum__ = 0;\
+ static uint32 __i__ = 0;
+
+#define TOC(str, count)\
+ __sum__ += _rdtsc() - _xxx_;\
+ if (++__i__ == count) {\
+ DEBUG(misc, 0, "[%s] %" OTTD_PRINTF64 "u [avg: %.1f]\n", str, __sum__, __sum__/(double)__i__);\
+ __i__ = 0;\
+ __sum__ = 0;\
+ }\
+}
+
+#endif /* DEBUG_H */
diff --git a/src/dedicated.c b/src/dedicated.c
new file mode 100644
index 000000000..1905fa498
--- /dev/null
+++ b/src/dedicated.c
@@ -0,0 +1,58 @@
+/* $Id$ */
+
+#include "stdafx.h"
+
+#ifdef ENABLE_NETWORK
+
+#if defined(UNIX) && !defined(__MORPHOS__)
+
+#include "openttd.h"
+#include "variables.h"
+
+#include <sys/types.h>
+#include <unistd.h>
+
+void DedicatedFork(void)
+{
+ /* Fork the program */
+ pid_t pid = fork();
+ switch (pid) {
+ case -1:
+ perror("Unable to fork");
+ exit(1);
+
+ case 0: { // We're the child
+ FILE* f;
+
+ /* Open the log-file to log all stuff too */
+ f = fopen(_log_file, "a");
+ if (f == NULL) {
+ perror("Unable to open logfile");
+ exit(1);
+ }
+ /* Redirect stdout and stderr to log-file */
+ if (dup2(fileno(f), fileno(stdout)) == -1) {
+ perror("Rerouting stdout");
+ exit(1);
+ }
+ if (dup2(fileno(f), fileno(stderr)) == -1) {
+ perror("Rerouting stderr");
+ exit(1);
+ }
+ break;
+ }
+
+ default:
+ // We're the parent
+ printf("Loading dedicated server...\n");
+ printf(" - Forked to background with pid %d\n", pid);
+ exit(0);
+ }
+}
+#endif
+
+#else
+
+void DedicatedFork(void) {}
+
+#endif /* ENABLE_NETWORK */
diff --git a/src/depot.c b/src/depot.c
new file mode 100644
index 000000000..49fdfa21c
--- /dev/null
+++ b/src/depot.c
@@ -0,0 +1,127 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "depot.h"
+#include "functions.h"
+#include "tile.h"
+#include "map.h"
+#include "table/strings.h"
+#include "saveload.h"
+#include "order.h"
+
+
+/**
+ * Called if a new block is added to the depot-pool
+ */
+static void DepotPoolNewBlock(uint start_item)
+{
+ Depot *d;
+
+ /* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
+ * TODO - This is just a temporary stage, this will be removed. */
+ for (d = GetDepot(start_item); d != NULL; d = (d->index + 1U < GetDepotPoolSize()) ? GetDepot(d->index + 1U) : NULL) d->index = start_item++;
+}
+
+DEFINE_OLD_POOL(Depot, Depot, DepotPoolNewBlock, NULL)
+
+
+/**
+ * Gets a depot from a tile
+ *
+ * @return Returns the depot if the tile had a depot, else it returns NULL
+ */
+Depot *GetDepotByTile(TileIndex tile)
+{
+ Depot *depot;
+
+ FOR_ALL_DEPOTS(depot) {
+ if (depot->xy == tile) return depot;
+ }
+
+ return NULL;
+}
+
+/**
+ * Allocate a new depot
+ */
+Depot *AllocateDepot(void)
+{
+ Depot *d;
+
+ /* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
+ * TODO - This is just a temporary stage, this will be removed. */
+ for (d = GetDepot(0); d != NULL; d = (d->index + 1U < GetDepotPoolSize()) ? GetDepot(d->index + 1U) : NULL) {
+ if (!IsValidDepot(d)) {
+ DepotID index = d->index;
+
+ memset(d, 0, sizeof(Depot));
+ d->index = index;
+
+ return d;
+ }
+ }
+
+ /* Check if we can add a block to the pool */
+ if (AddBlockToPool(&_Depot_pool)) return AllocateDepot();
+
+ return NULL;
+}
+
+/**
+ * Clean up a depot
+ */
+void DestroyDepot(Depot *depot)
+{
+ /* Clear the tile */
+ DoClearSquare(depot->xy);
+
+ /* Clear the depot from all order-lists */
+ RemoveOrderFromAllVehicles(OT_GOTO_DEPOT, depot->index);
+
+ /* Delete the depot-window */
+ DeleteWindowById(WC_VEHICLE_DEPOT, depot->xy);
+}
+
+void InitializeDepots(void)
+{
+ CleanPool(&_Depot_pool);
+ AddBlockToPool(&_Depot_pool);
+}
+
+
+static const SaveLoad _depot_desc[] = {
+ SLE_CONDVAR(Depot, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+ SLE_CONDVAR(Depot, xy, SLE_UINT32, 6, SL_MAX_VERSION),
+ SLE_VAR(Depot, town_index, SLE_UINT16),
+ SLE_END()
+};
+
+static void Save_DEPT(void)
+{
+ Depot *depot;
+
+ FOR_ALL_DEPOTS(depot) {
+ SlSetArrayIndex(depot->index);
+ SlObject(depot, _depot_desc);
+ }
+}
+
+static void Load_DEPT(void)
+{
+ int index;
+
+ while ((index = SlIterateArray()) != -1) {
+ Depot *depot;
+
+ if (!AddBlockIfNeeded(&_Depot_pool, index))
+ error("Depots: failed loading savegame: too many depots");
+
+ depot = GetDepot(index);
+ SlObject(depot, _depot_desc);
+ }
+}
+
+const ChunkHandler _depot_chunk_handlers[] = {
+ { 'DEPT', Save_DEPT, Load_DEPT, CH_ARRAY | CH_LAST},
+};
diff --git a/src/depot.h b/src/depot.h
new file mode 100644
index 000000000..7cf25a1b1
--- /dev/null
+++ b/src/depot.h
@@ -0,0 +1,112 @@
+/* $Id$ */
+
+#ifndef DEPOT_H
+#define DEPOT_H
+
+/** @file depot.h Header files for depots (not hangars)
+ * @see depot.c */
+
+#include "direction.h"
+#include "oldpool.h"
+#include "tile.h"
+#include "variables.h"
+
+struct Depot {
+ TileIndex xy;
+ TownID town_index;
+ DepotID index;
+};
+
+DECLARE_OLD_POOL(Depot, Depot, 3, 8000)
+
+/**
+ * Check if a depot really exists.
+ */
+static inline bool IsValidDepot(const Depot *depot)
+{
+ return depot != NULL && depot->xy != 0;
+}
+
+static inline bool IsValidDepotID(uint index)
+{
+ return index < GetDepotPoolSize() && IsValidDepot(GetDepot(index));
+}
+
+void DestroyDepot(Depot *depot);
+
+static inline void DeleteDepot(Depot *depot)
+{
+ DestroyDepot(depot);
+ depot->xy = 0;
+}
+
+void ShowDepotWindow(TileIndex tile, byte type);
+
+#define FOR_ALL_DEPOTS_FROM(d, start) for (d = GetDepot(start); d != NULL; d = (d->index + 1U < GetDepotPoolSize()) ? GetDepot(d->index + 1U) : NULL) if (IsValidDepot(d))
+#define FOR_ALL_DEPOTS(d) FOR_ALL_DEPOTS_FROM(d, 0)
+
+#define MIN_SERVINT_PERCENT 5
+#define MAX_SERVINT_PERCENT 90
+#define MIN_SERVINT_DAYS 30
+#define MAX_SERVINT_DAYS 800
+
+/**
+ * Get the service interval domain.
+ * Get the new proposed service interval for the vehicle is indeed, clamped
+ * within the given bounds. @see MIN_SERVINT_PERCENT ,etc.
+ * @param index proposed service interval
+ */
+static inline Date GetServiceIntervalClamped(uint index)
+{
+ return (_patches.servint_ispercent) ? clamp(index, MIN_SERVINT_PERCENT, MAX_SERVINT_PERCENT) : clamp(index, MIN_SERVINT_DAYS, MAX_SERVINT_DAYS);
+}
+
+/**
+ * Check if a tile is a depot of the given type.
+ */
+static inline bool IsTileDepotType(TileIndex tile, TransportType type)
+{
+ switch (type) {
+ case TRANSPORT_RAIL:
+ return IsTileType(tile, MP_RAILWAY) && (_m[tile].m5 & 0xFC) == 0xC0;
+
+ case TRANSPORT_ROAD:
+ return IsTileType(tile, MP_STREET) && (_m[tile].m5 & 0xF0) == 0x20;
+
+ case TRANSPORT_WATER:
+ return IsTileType(tile, MP_WATER) && (_m[tile].m5 & ~3) == 0x80;
+
+ default:
+ assert(0);
+ return false;
+ }
+}
+
+
+/**
+ * Find out if the slope of the tile is suitable to build a depot of given direction
+ * @param direction The direction in which the depot's exit points. Starts with 0 as NE and goes Clockwise
+ * @param tileh The slope of the tile in question
+ * @return true if the construction is possible
+
+ * This is checked by the ugly 0x4C >> direction magic, which does the following:
+ * 0x4C is 0100 1100 and tileh has only bits 0..3 set (steep tiles are ruled out)
+ * So: for direction (only the significant bits are shown)<p>
+ * 00 (exit towards NE) we need either bit 2 or 3 set in tileh: 0x4C >> 0 = 1100<p>
+ * 01 (exit towards SE) we need either bit 1 or 2 set in tileh: 0x4C >> 1 = 0110<p>
+ * 02 (exit towards SW) we need either bit 0 or 1 set in tileh: 0x4C >> 2 = 0011<p>
+ * 03 (exit towards NW) we need either bit 0 or 4 set in tileh: 0x4C >> 3 = 1001<p>
+ * So ((0x4C >> direction) & tileh) determines whether the depot can be built on the current tileh
+ */
+static inline bool CanBuildDepotByTileh(uint32 direction, Slope tileh)
+{
+ return ((0x4C >> direction) & tileh) != 0;
+}
+
+Depot *GetDepotByTile(TileIndex tile);
+void InitializeDepots(void);
+Depot *AllocateDepot(void);
+
+void DeleteDepotHighlightOfVehicle(const Vehicle *v);
+
+#endif /* DEPOT_H */
diff --git a/src/depot_gui.c b/src/depot_gui.c
new file mode 100644
index 000000000..d929696b8
--- /dev/null
+++ b/src/depot_gui.c
@@ -0,0 +1,954 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "functions.h"
+#include "train.h"
+#include "roadveh.h"
+#include "ship.h"
+#include "aircraft.h"
+#include "table/strings.h"
+#include "table/sprites.h"
+#include "gui.h"
+#include "gfx.h"
+#include "vehicle.h"
+#include "viewport.h"
+#include "command.h"
+#include "depot.h"
+#include "vehicle_gui.h"
+#include "station_map.h"
+#include "newgrf_engine.h"
+
+/*
+ * Since all depot window sizes aren't the same, we need to modify sizes a little.
+ * It's done with the following arrays of widget indexes. Each of them tells if a widget side should be moved and in what direction.
+ * How long they should be moved and for what window types are controlled in ShowDepotWindow()
+ */
+
+/* Names of the widgets. Keep them in the same order as in the widget array */
+enum DepotWindowWidgets {
+ DEPOT_WIDGET_CLOSEBOX = 0,
+ DEPOT_WIDGET_CAPTION,
+ DEPOT_WIDGET_STICKY,
+ DEPOT_WIDGET_SELL,
+ DEPOT_WIDGET_SELL_CHAIN,
+ DEPOT_WIDGET_SELL_ALL,
+ DEPOT_WIDGET_AUTOREPLACE,
+ DEPOT_WIDGET_MATRIX,
+ DEPOT_WIDGET_V_SCROLL, // Vertical scrollbar
+ DEPOT_WIDGET_H_SCROLL, // Horizontal scrollbar
+ DEPOT_WIDGET_BUILD,
+ DEPOT_WIDGET_CLONE,
+ DEPOT_WIDGET_LOCATION,
+ DEPOT_WIDGET_VEHICLE_LIST,
+ DEPOT_WIDGET_STOP_ALL,
+ DEPOT_WIDGET_START_ALL,
+ DEPOT_WIDGET_RESIZE,
+};
+
+/* Widget array for all depot windows.
+ * If a widget is needed in some windows only (like train specific), add it for all windows
+ * and use HideWindowWidget in ShowDepotWindow() to remove it in the windows where it should not be
+ * Keep the widget numbers in sync with the enum or really bad stuff will happen!!! */
+
+/* When adding widgets, place them as you would place them for the ship depot and define how you want it to move in widget_moves[]
+ * If you want a widget for one window only, set it to be hidden in ShowDepotWindow() for the windows where you don't want it
+ * NOTE: the train only widgets are moved/resized in ShowDepotWindow() so they follow certain other widgets if they are moved to ensure that they stick together.
+ * Changing the size of those here will not have an effect at all. It should be done in ShowDepotWindow()
+ */
+static const Widget _depot_widgets[] = {
+ { WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, // DEPOT_WIDGET_CLOSEBOX
+ { WWT_CAPTION, RESIZE_RIGHT, 14, 11, 292, 0, 13, 0x0, STR_018C_WINDOW_TITLE_DRAG_THIS}, // DEPOT_WIDGET_CAPTION
+ { WWT_STICKYBOX, RESIZE_LR, 14, 293, 304, 0, 13, 0x0, STR_STICKY_BUTTON}, // DEPOT_WIDGET_STICKY
+
+ /* Widgets are set up run-time */
+ { WWT_IMGBTN, RESIZE_LRB, 14, 270, 292, 14, 37, 0x0, STR_NULL}, // DEPOT_WIDGET_SELL
+ { WWT_IMGBTN, RESIZE_LRTB, 14, 270, 292, 14, 37, SPR_SELL_CHAIN_TRAIN,STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP}, // DEPOT_WIDGET_SELL_CHAIN, trains only
+ { WWT_PUSHIMGBTN, RESIZE_LRTB, 14, 270, 292, 38, 60, 0x0, STR_NULL}, // DEPOT_WIDGET_SELL_ALL
+ { WWT_PUSHIMGBTN, RESIZE_LRTB, 14, 270, 292, 61, 83, 0x0, STR_NULL}, // DEPOT_WIDGET_AUTOREPLACE
+
+ { WWT_MATRIX, RESIZE_RB, 14, 0, 269, 14, 83, 0x0, STR_NULL}, // DEPOT_WIDGET_MATRIX
+ { WWT_SCROLLBAR, RESIZE_LRB, 14, 293, 304, 14, 83, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST}, // DEPOT_WIDGET_V_SCROLL
+
+ { WWT_HSCROLLBAR, RESIZE_RTB, 14, 0, 269, 72, 83, 0x0, STR_HSCROLL_BAR_SCROLLS_LIST}, // DEPOT_WIDGET_H_SCROLL, trains only
+
+ /* The buttons in the bottom of the window. left and right is not important as they are later resized to be equal in size
+ * This calculation is based on right in DEPOT_WIDGET_LOCATION and it presumes left of DEPOT_WIDGET_BUILD is 0 */
+ { WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 85, 84, 95, 0x0, STR_NULL}, // DEPOT_WIDGET_BUILD
+ { WWT_TEXTBTN, RESIZE_TB, 14, 86, 170, 84, 95, 0x0, STR_NULL}, // DEPOT_WIDGET_CLONE
+ { WWT_PUSHTXTBTN, RESIZE_RTB, 14, 171, 257, 84, 95, STR_00E4_LOCATION, STR_NULL}, // DEPOT_WIDGET_LOCATION
+ { WWT_PUSHTXTBTN, RESIZE_LRTB, 14, 258, 269, 84, 95, 0x0, STR_NULL}, // DEPOT_WIDGET_VEHICLE_LIST
+ { WWT_PUSHIMGBTN, RESIZE_LRTB, 14, 270, 280, 84, 95, SPR_FLAG_VEH_STOPPED,STR_NULL}, // DEPOT_WIDGET_STOP_ALL
+ { WWT_PUSHIMGBTN, RESIZE_LRTB, 14, 281, 292, 84, 95, SPR_FLAG_VEH_RUNNING,STR_NULL}, // DEPOT_WIDGET_START_ALL
+ { WWT_RESIZEBOX, RESIZE_LRTB, 14, 293, 304, 84, 95, 0x0, STR_RESIZE_BUTTON}, // DEPOT_WIDGET_RESIZE
+ { WIDGETS_END},
+};
+
+static void DepotWndProc(Window *w, WindowEvent *e);
+
+static const WindowDesc _train_depot_desc = {
+ WDP_AUTO, WDP_AUTO, 305, 96,
+ WC_VEHICLE_DEPOT,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
+ _depot_widgets,
+ DepotWndProc
+};
+
+static const WindowDesc _road_depot_desc = {
+ WDP_AUTO, WDP_AUTO, 305, 96,
+ WC_VEHICLE_DEPOT,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
+ _depot_widgets,
+ DepotWndProc
+};
+
+static const WindowDesc _ship_depot_desc = {
+ WDP_AUTO, WDP_AUTO, 305, 96,
+ WC_VEHICLE_DEPOT,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
+ _depot_widgets,
+ DepotWndProc
+};
+
+static const WindowDesc _aircraft_depot_desc = {
+ WDP_AUTO, WDP_AUTO, 305, 96,
+ WC_VEHICLE_DEPOT,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
+ _depot_widgets,
+ DepotWndProc
+};
+
+extern int WagonLengthToPixels(int len);
+
+void CcCloneVehicle(bool success, TileIndex tile, uint32 p1, uint32 p2)
+{
+ if (!success) return;
+ switch(GetVehicle(p1)->type) {
+ case VEH_Train: CcCloneTrain( true, tile, p1, p2); break;
+ case VEH_Road: CcCloneRoadVeh( true, tile, p1, p2); break;
+ case VEH_Ship: CcCloneShip( true, tile, p1, p2); break;
+ case VEH_Aircraft: CcCloneAircraft(true, tile, p1, p2); break;
+ }
+}
+
+static inline void ShowVehicleViewWindow(const Vehicle *v)
+{
+ switch (v->type) {
+ case VEH_Train: ShowTrainViewWindow(v); break;
+ case VEH_Road: ShowRoadVehViewWindow(v); break;
+ case VEH_Ship: ShowShipViewWindow(v); break;
+ case VEH_Aircraft: ShowAircraftViewWindow(v); break;
+ default: NOT_REACHED();
+ }
+}
+
+static void DepotSellAllConfirmationCallback(Window *w, bool confirmed)
+{
+ if (confirmed) {
+ TileIndex tile = w->window_number;
+ byte vehtype = WP(w, depot_d).type;
+ DoCommandP(tile, vehtype, 0, NULL, CMD_DEPOT_SELL_ALL_VEHICLES);
+ }
+}
+
+/** Draw a vehicle in the depot window in the box with the top left corner at x,y
+ * @param *w Window to draw in
+ * @param *v Vehicle to draw
+ * @param x Left side of the box to draw in
+ * @param y Top of the box to draw in
+ */
+static void DrawVehicleInDepot(Window *w, const Vehicle *v, int x, int y)
+{
+ byte diff_x = 0, diff_y = 0;
+
+ switch (v->type) {
+ case VEH_Train:
+ DrawTrainImage(v, x + 21, y, w->hscroll.cap + 4, w->hscroll.pos, WP(w,depot_d).sel);
+
+ /* Number of wagons relative to a standard length wagon (rounded up) */
+ SetDParam(0, (v->u.rail.cached_total_length + 7) / 8);
+ DrawStringRightAligned(w->widget[DEPOT_WIDGET_MATRIX].right - 1, y + 4, STR_TINY_BLACK, 0); // Draw the counter
+ break;
+
+ case VEH_Road: DrawRoadVehImage( v, x + 24, y, WP(w, depot_d).sel); break;
+ case VEH_Ship: DrawShipImage( v, x + 19, y, WP(w, depot_d).sel); break;
+ case VEH_Aircraft: DrawAircraftImage(v, x + 12, y, WP(w, depot_d).sel); break;
+ default: NOT_REACHED();
+ }
+
+ if (w->resize.step_height == 14) {
+ /* VEH_Train and VEH_Road, which are low */
+ diff_x = 15;
+ } else {
+ /* VEH_Ship and VEH_Aircraft, which are tall */
+ diff_y = 12;
+ }
+
+ DrawSprite((v->vehstatus & VS_STOPPED) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, x + diff_x, y + diff_y);
+
+ SetDParam(0, v->unitnumber);
+ DrawString(x, y + 2, (uint16)(v->max_age-366) >= v->age ? STR_00E2 : STR_00E3, 0);
+}
+
+static void DrawDepotWindow(Window *w)
+{
+ Vehicle **vl = WP(w, depot_d).vehicle_list;
+ TileIndex tile = w->window_number;
+ int x, y, i, hnum, max;
+ uint16 num = WP(w, depot_d).engine_count;
+
+ /* Set the row and number of boxes in each row based on the number of boxes drawn in the matrix */
+ uint16 rows_in_display = w->widget[DEPOT_WIDGET_MATRIX].data >> 8;
+ uint16 boxes_in_each_row = w->widget[DEPOT_WIDGET_MATRIX].data & 0xFF;
+
+ /* setup disabled buttons */
+ SetWindowWidgetsDisabledState(w, !IsTileOwner(tile, _local_player),
+ DEPOT_WIDGET_STOP_ALL,
+ DEPOT_WIDGET_START_ALL,
+ DEPOT_WIDGET_SELL,
+ DEPOT_WIDGET_SELL_CHAIN,
+ DEPOT_WIDGET_SELL_ALL,
+ DEPOT_WIDGET_BUILD,
+ DEPOT_WIDGET_CLONE,
+ DEPOT_WIDGET_AUTOREPLACE,
+ WIDGET_LIST_END);
+
+ /* determine amount of items for scroller */
+ if (WP(w, depot_d).type == VEH_Train) {
+ hnum = 8;
+ for (num = 0; num < WP(w, depot_d).engine_count; num++) {
+ const Vehicle *v = vl[num];
+ hnum = maxu(hnum, v->u.rail.cached_total_length);
+ }
+ /* Always have 1 empty row, so people can change the setting of the train */
+ SetVScrollCount(w, WP(w, depot_d).engine_count + WP(w, depot_d).wagon_count + 1);
+ SetHScrollCount(w, WagonLengthToPixels(hnum));
+ } else {
+ SetVScrollCount(w, (num + w->hscroll.cap - 1) / w->hscroll.cap);
+ }
+
+ /* locate the depot struct */
+ if (WP(w, depot_d).type == VEH_Aircraft) {
+ SetDParam(0, GetStationIndex(tile)); // Airport name
+ } else {
+ Depot *depot = GetDepotByTile(tile);
+ assert(depot != NULL);
+
+ SetDParam(0, depot->town_index);
+ }
+
+ DrawWindowWidgets(w);
+
+ num = w->vscroll.pos * boxes_in_each_row;
+ max = min(WP(w, depot_d).engine_count, num + (rows_in_display * boxes_in_each_row));
+
+ for (x = 2, y = 15; num < max; y += w->resize.step_height, x = 2) { // Draw the rows
+ byte i;
+
+ for (i = 0; i < boxes_in_each_row && num < max; i++, num++, x += w->resize.step_width) {
+ /* Draw all vehicles in the current row */
+ const Vehicle *v = vl[num];
+ DrawVehicleInDepot(w, v, x, y);
+ }
+ }
+
+ max = min(WP(w, depot_d).engine_count + WP(w, depot_d).wagon_count, (w->vscroll.pos * boxes_in_each_row) + (rows_in_display * boxes_in_each_row));
+
+ /* draw the train wagons, that do not have an engine in front */
+ for (; num < max; num++, y += 14) {
+ const Vehicle *v = WP(w, depot_d).wagon_list[num - WP(w, depot_d).engine_count];
+ const Vehicle *u;
+
+ DrawTrainImage(v, x + 50, y, w->hscroll.cap - 29, 0, WP(w,depot_d).sel);
+ DrawString(x, y + 2, STR_8816, 0);
+
+ /*Draw the train counter */
+ i = 0;
+ u = v;
+ do i++; while ( (u=u->next) != NULL); // Determine length of train
+ SetDParam(0, i); // Set the counter
+ DrawStringRightAligned(w->widget[DEPOT_WIDGET_MATRIX].right - 1, y + 4, STR_TINY_BLACK, 0); // Draw the counter
+ }
+}
+
+typedef struct GetDepotVehiclePtData {
+ Vehicle *head;
+ Vehicle *wagon;
+} GetDepotVehiclePtData;
+
+enum {
+ MODE_ERROR = 1,
+ MODE_DRAG_VEHICLE = 0,
+ MODE_SHOW_VEHICLE = -1,
+ MODE_START_STOP = -2,
+};
+
+static int GetVehicleFromDepotWndPt(const Window *w, int x, int y, Vehicle **veh, GetDepotVehiclePtData *d)
+{
+ Vehicle **vl = WP(w, depot_d).vehicle_list;
+ uint xt, row, xm = 0, ym = 0;
+ int pos, skip = 0;
+ uint16 boxes_in_each_row = w->widget[DEPOT_WIDGET_MATRIX].data & 0xFF;
+
+ if (WP(w, depot_d).type == VEH_Train) {
+ xt = 0;
+ x -= 23;
+ } else {
+ xt = x / w->resize.step_width;
+ xm = x % w->resize.step_width;
+ if (xt >= w->hscroll.cap) return MODE_ERROR;
+
+ ym = (y - 14) % w->resize.step_height;
+ }
+
+ row = (y - 14) / w->resize.step_height;
+ if (row >= w->vscroll.cap) return MODE_ERROR;
+
+ pos = ((row + w->vscroll.pos) * boxes_in_each_row) + xt;
+
+ if (WP(w, depot_d).engine_count + WP(w, depot_d).wagon_count <= pos) {
+ if (WP(w, depot_d).type == VEH_Train) {
+ d->head = NULL;
+ d->wagon = NULL;
+ return MODE_DRAG_VEHICLE;
+ } else {
+ return MODE_ERROR; // empty block, so no vehicle is selected
+ }
+ }
+
+ if (WP(w, depot_d).engine_count > pos) {
+ *veh = vl[pos];
+ skip = w->hscroll.pos;
+ } else {
+ vl = WP(w, depot_d).wagon_list;
+ pos -= WP(w, depot_d).engine_count;
+ *veh = vl[pos];
+ /* free wagons don't have an initial loco. */
+ x -= _traininfo_vehicle_width;
+ }
+
+ switch (WP(w, depot_d).type) {
+ case VEH_Train: {
+ Vehicle *v = *veh;
+ d->head = d->wagon = v;
+
+ /* either pressed the flag or the number, but only when it's a loco */
+ if (x < 0 && IsFrontEngine(v)) return (x >= -10) ? MODE_START_STOP : MODE_SHOW_VEHICLE;
+
+ skip = (skip * 8) / _traininfo_vehicle_width;
+ x = (x * 8) / _traininfo_vehicle_width;
+
+ /* Skip vehicles that are scrolled off the list */
+ x += skip;
+
+ /* find the vehicle in this row that was clicked */
+ while (v != NULL && (x -= v->u.rail.cached_veh_length) >= 0) v = v->next;
+
+ /* if an articulated part was selected, find its parent */
+ while (v != NULL && IsArticulatedPart(v)) v = GetPrevVehicleInChain(v);
+
+ d->wagon = v;
+
+ return MODE_DRAG_VEHICLE;
+ }
+ break;
+
+ case VEH_Road:
+ if (xm >= 24) return MODE_DRAG_VEHICLE;
+ if (xm <= 16) return MODE_SHOW_VEHICLE;
+ break;
+
+ case VEH_Ship:
+ if (xm >= 19) return MODE_DRAG_VEHICLE;
+ if (ym <= 10) return MODE_SHOW_VEHICLE;
+ break;
+
+ case VEH_Aircraft:
+ if (xm >= 12) return MODE_DRAG_VEHICLE;
+ if (ym <= 12) return MODE_SHOW_VEHICLE;
+ break;
+
+ default: NOT_REACHED();
+ }
+ return MODE_START_STOP;
+}
+
+static void TrainDepotMoveVehicle(Vehicle *wagon, VehicleID sel, Vehicle *head)
+{
+ Vehicle *v;
+
+ v = GetVehicle(sel);
+
+ if (v == wagon) return;
+
+ if (wagon == NULL) {
+ if (head != NULL) wagon = GetLastVehicleInChain(head);
+ } else {
+ wagon = GetPrevVehicleInChain(wagon);
+ if (wagon == NULL) return;
+ }
+
+ if (wagon == v) return;
+
+ DoCommandP(v->tile, v->index + ((wagon == NULL ? INVALID_VEHICLE : wagon->index) << 16), _ctrl_pressed ? 1 : 0, NULL, CMD_MOVE_RAIL_VEHICLE | CMD_MSG(STR_8837_CAN_T_MOVE_VEHICLE));
+}
+
+static void DepotClick(Window *w, int x, int y)
+{
+ GetDepotVehiclePtData gdvp;
+ Vehicle *v = NULL;
+ int mode = GetVehicleFromDepotWndPt(w, x, y, &v, &gdvp);
+
+ /* share / copy orders */
+ if (_thd.place_mode && mode <= 0) {
+ _place_clicked_vehicle = (WP(w, depot_d).type == VEH_Train ? gdvp.head : v);
+ return;
+ }
+
+ if (WP(w, depot_d).type == VEH_Train) v = gdvp.wagon;
+
+ switch (mode) {
+ case MODE_ERROR: // invalid
+ return;
+
+ case MODE_DRAG_VEHICLE: { // start dragging of vehicle
+ VehicleID sel = WP(w, depot_d).sel;
+
+ if (WP(w, depot_d).type == VEH_Train && sel != INVALID_VEHICLE) {
+ WP(w,depot_d).sel = INVALID_VEHICLE;
+ TrainDepotMoveVehicle(v, sel, gdvp.head);
+ } else if (v != NULL) {
+ int image;
+
+ switch (WP(w, depot_d).type) {
+ case VEH_Train: image = GetTrainImage(v, DIR_W); break;
+ case VEH_Road: image = GetRoadVehImage(v, DIR_W); break;
+ case VEH_Ship: image = GetShipImage(v, DIR_W); break;
+ case VEH_Aircraft: image = GetAircraftImage(v, DIR_W); break;
+ default: NOT_REACHED(); image = 0;
+ }
+
+ WP(w, depot_d).sel = v->index;
+ SetWindowDirty(w);
+ SetObjectToPlaceWnd(GetVehiclePalette(v) | image, 4, w);
+ }
+ }
+ break;
+
+ case MODE_SHOW_VEHICLE: // show info window
+ ShowVehicleViewWindow(v);
+ break;
+
+ case MODE_START_STOP: { // click start/stop flag
+ uint command;
+
+ switch (WP(w, depot_d).type) {
+ case VEH_Train: command = CMD_START_STOP_TRAIN | CMD_MSG(STR_883B_CAN_T_STOP_START_TRAIN); break;
+ case VEH_Road: command = CMD_START_STOP_ROADVEH | CMD_MSG(STR_9015_CAN_T_STOP_START_ROAD_VEHICLE); break;
+ case VEH_Ship: command = CMD_START_STOP_SHIP | CMD_MSG(STR_9818_CAN_T_STOP_START_SHIP); break;
+ case VEH_Aircraft: command = CMD_START_STOP_AIRCRAFT | CMD_MSG(STR_A016_CAN_T_STOP_START_AIRCRAFT); break;
+ default: NOT_REACHED(); command = 0;
+ }
+ DoCommandP(v->tile, v->index, 0, NULL, command);
+ }
+ break;
+
+ default: NOT_REACHED();
+ }
+}
+
+/**
+ * Clones a vehicle
+ * @param *v is the original vehicle to clone
+ * @param *w is the window of the depot where the clone is build
+ */
+static void HandleCloneVehClick(const Vehicle *v, const Window *w)
+{
+ uint error_str;
+
+ if (v == NULL) return;
+
+ if (v->type == VEH_Train && !IsFrontEngine(v)) {
+ v = GetFirstVehicleInChain(v);
+ /* Do nothing when clicking on a train in depot with no loc attached */
+ if (!IsFrontEngine(v)) return;
+ }
+
+ switch (v->type) {
+ case VEH_Train: error_str = CMD_MSG(STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE); break;
+ case VEH_Road: error_str = CMD_MSG(STR_9009_CAN_T_BUILD_ROAD_VEHICLE); break;
+ case VEH_Ship: error_str = CMD_MSG(STR_980D_CAN_T_BUILD_SHIP); break;
+ case VEH_Aircraft: error_str = CMD_MSG(STR_A008_CAN_T_BUILD_AIRCRAFT); break;
+ default: return;
+ }
+
+ DoCommandP(w->window_number, v->index, _ctrl_pressed ? 1 : 0, CcCloneVehicle, CMD_CLONE_VEHICLE | error_str);
+
+ ResetObjectToPlace();
+}
+
+static void ClonePlaceObj(const Window *w)
+{
+ const Vehicle *v = CheckMouseOverVehicle();
+
+ if (v != NULL) HandleCloneVehClick(v, w);
+}
+
+static void ResizeDepotButtons(Window *w)
+{
+ /* We got the widget moved around. Now we will make some widgets to fill the gap between some widgets in equal sizes */
+
+ /* Make the buttons in the bottom equal in size */
+ w->widget[DEPOT_WIDGET_BUILD].right = w->widget[DEPOT_WIDGET_LOCATION].right / 3;
+ w->widget[DEPOT_WIDGET_LOCATION].left = w->widget[DEPOT_WIDGET_BUILD].right * 2;
+ w->widget[DEPOT_WIDGET_CLONE].left = w->widget[DEPOT_WIDGET_BUILD].right + 1;
+ w->widget[DEPOT_WIDGET_CLONE].right = w->widget[DEPOT_WIDGET_LOCATION].left - 1;
+
+ if (WP(w, depot_d).type == VEH_Train) {
+ /* Divide the size of DEPOT_WIDGET_SELL into two equally big buttons so DEPOT_WIDGET_SELL and DEPOT_WIDGET_SELL_CHAIN will get the same size.
+ * This way it will stay the same even if DEPOT_WIDGET_SELL_CHAIN is resized for some reason */
+ w->widget[DEPOT_WIDGET_SELL_CHAIN].top = ((w->widget[DEPOT_WIDGET_SELL_CHAIN].bottom - w->widget[DEPOT_WIDGET_SELL].top) / 2) + w->widget[DEPOT_WIDGET_SELL].top;
+ w->widget[DEPOT_WIDGET_SELL].bottom = w->widget[DEPOT_WIDGET_SELL_CHAIN].top - 1;
+ }
+}
+
+/* Function to set up vehicle specific sprites and strings
+ * Only use this if it's the same widget, that's used for more than one vehicle type and it needs different text/sprites
+ * Vehicle specific text/sprites, that's in a widget, that's only shown for one vehicle type (like sell whole train) is set in the widget array
+ */
+static void SetupStringsForDepotWindow(Window *w, byte type)
+{
+ switch (type) {
+ case VEH_Train:
+ w->widget[DEPOT_WIDGET_CAPTION].data = STR_8800_TRAIN_DEPOT;
+ w->widget[DEPOT_WIDGET_STOP_ALL].tooltips = STR_MASS_STOP_DEPOT_TRAIN_TIP;
+ w->widget[DEPOT_WIDGET_START_ALL].tooltips= STR_MASS_START_DEPOT_TRAIN_TIP;
+ w->widget[DEPOT_WIDGET_SELL].tooltips = STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE;
+ w->widget[DEPOT_WIDGET_SELL_ALL].tooltips = STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP;
+ w->widget[DEPOT_WIDGET_MATRIX].tooltips = STR_883F_TRAINS_CLICK_ON_TRAIN_FOR;
+
+ w->widget[DEPOT_WIDGET_BUILD].data = STR_8815_NEW_VEHICLES;
+ w->widget[DEPOT_WIDGET_BUILD].tooltips = STR_8840_BUILD_NEW_TRAIN_VEHICLE;
+ w->widget[DEPOT_WIDGET_CLONE].data = STR_CLONE_TRAIN;
+ w->widget[DEPOT_WIDGET_CLONE].tooltips = STR_CLONE_TRAIN_DEPOT_INFO;
+
+ w->widget[DEPOT_WIDGET_LOCATION].tooltips = STR_8842_CENTER_MAIN_VIEW_ON_TRAIN;
+ w->widget[DEPOT_WIDGET_VEHICLE_LIST].data = STR_TRAIN;
+ w->widget[DEPOT_WIDGET_VEHICLE_LIST].tooltips = STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP;
+ w->widget[DEPOT_WIDGET_AUTOREPLACE].tooltips = STR_DEPOT_AUTOREPLACE_TRAIN_TIP;
+
+ /* Sprites */
+ w->widget[DEPOT_WIDGET_SELL].data = SPR_SELL_TRAIN;
+ w->widget[DEPOT_WIDGET_SELL_ALL].data = SPR_SELL_ALL_TRAIN;
+ w->widget[DEPOT_WIDGET_AUTOREPLACE].data = SPR_REPLACE_TRAIN;
+ break;
+
+ case VEH_Road:
+ w->widget[DEPOT_WIDGET_CAPTION].data = STR_9003_ROAD_VEHICLE_DEPOT;
+ w->widget[DEPOT_WIDGET_STOP_ALL].tooltips = STR_MASS_STOP_DEPOT_ROADVEH_TIP;
+ w->widget[DEPOT_WIDGET_START_ALL].tooltips= STR_MASS_START_DEPOT_ROADVEH_TIP;
+ w->widget[DEPOT_WIDGET_SELL].tooltips = STR_9024_DRAG_ROAD_VEHICLE_TO_HERE;
+ w->widget[DEPOT_WIDGET_SELL_ALL].tooltips = STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP;
+ w->widget[DEPOT_WIDGET_MATRIX].tooltips = STR_9022_VEHICLES_CLICK_ON_VEHICLE;
+
+ w->widget[DEPOT_WIDGET_BUILD].data = STR_9004_NEW_VEHICLES;
+ w->widget[DEPOT_WIDGET_BUILD].tooltips = STR_9023_BUILD_NEW_ROAD_VEHICLE;
+ w->widget[DEPOT_WIDGET_CLONE].data = STR_CLONE_ROAD_VEHICLE;
+ w->widget[DEPOT_WIDGET_CLONE].tooltips = STR_CLONE_ROAD_VEHICLE_DEPOT_INFO;
+
+ w->widget[DEPOT_WIDGET_LOCATION].tooltips = STR_9025_CENTER_MAIN_VIEW_ON_ROAD;
+ w->widget[DEPOT_WIDGET_VEHICLE_LIST].data = STR_LORRY;
+ w->widget[DEPOT_WIDGET_VEHICLE_LIST].tooltips = STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP;
+ w->widget[DEPOT_WIDGET_AUTOREPLACE].tooltips = STR_DEPOT_AUTOREPLACE_ROADVEH_TIP;
+
+ /* Sprites */
+ w->widget[DEPOT_WIDGET_SELL].data = SPR_SELL_ROADVEH;
+ w->widget[DEPOT_WIDGET_SELL_ALL].data = SPR_SELL_ALL_ROADVEH;
+ w->widget[DEPOT_WIDGET_AUTOREPLACE].data = SPR_REPLACE_ROADVEH;
+ break;
+
+ case VEH_Ship:
+ w->widget[DEPOT_WIDGET_CAPTION].data = STR_9803_SHIP_DEPOT;
+ w->widget[DEPOT_WIDGET_STOP_ALL].tooltips = STR_MASS_STOP_DEPOT_SHIP_TIP;
+ w->widget[DEPOT_WIDGET_START_ALL].tooltips= STR_MASS_START_DEPOT_SHIP_TIP;
+ w->widget[DEPOT_WIDGET_SELL].tooltips = STR_9821_DRAG_SHIP_TO_HERE_TO_SELL;
+ w->widget[DEPOT_WIDGET_SELL_ALL].tooltips = STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP;
+ w->widget[DEPOT_WIDGET_MATRIX].tooltips = STR_981F_SHIPS_CLICK_ON_SHIP_FOR;
+
+ w->widget[DEPOT_WIDGET_BUILD].data = STR_9804_NEW_SHIPS;
+ w->widget[DEPOT_WIDGET_BUILD].tooltips = STR_9820_BUILD_NEW_SHIP;
+ w->widget[DEPOT_WIDGET_CLONE].data = STR_CLONE_SHIP;
+ w->widget[DEPOT_WIDGET_CLONE].tooltips = STR_CLONE_SHIP_DEPOT_INFO;
+
+ w->widget[DEPOT_WIDGET_LOCATION].tooltips = STR_9822_CENTER_MAIN_VIEW_ON_SHIP;
+ w->widget[DEPOT_WIDGET_VEHICLE_LIST].data = STR_SHIP;
+ w->widget[DEPOT_WIDGET_VEHICLE_LIST].tooltips = STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP;
+ w->widget[DEPOT_WIDGET_AUTOREPLACE].tooltips = STR_DEPOT_AUTOREPLACE_SHIP_TIP;
+
+ /* Sprites */
+ w->widget[DEPOT_WIDGET_SELL].data = SPR_SELL_SHIP;
+ w->widget[DEPOT_WIDGET_SELL_ALL].data = SPR_SELL_ALL_SHIP;
+ w->widget[DEPOT_WIDGET_AUTOREPLACE].data = SPR_REPLACE_SHIP;
+ break;
+
+ case VEH_Aircraft:
+ w->widget[DEPOT_WIDGET_CAPTION].data = STR_A002_AIRCRAFT_HANGAR;
+ w->widget[DEPOT_WIDGET_STOP_ALL].tooltips = STR_MASS_STOP_HANGAR_TIP;
+ w->widget[DEPOT_WIDGET_START_ALL].tooltips= STR_MASS_START_HANGAR_TIP;
+ w->widget[DEPOT_WIDGET_SELL].tooltips = STR_A023_DRAG_AIRCRAFT_TO_HERE_TO;
+ w->widget[DEPOT_WIDGET_SELL_ALL].tooltips = STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP;
+ w->widget[DEPOT_WIDGET_MATRIX].tooltips = STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT;
+
+ w->widget[DEPOT_WIDGET_BUILD].data = STR_A003_NEW_AIRCRAFT;
+ w->widget[DEPOT_WIDGET_BUILD].tooltips = STR_A022_BUILD_NEW_AIRCRAFT;
+ w->widget[DEPOT_WIDGET_CLONE].data = STR_CLONE_AIRCRAFT;
+ w->widget[DEPOT_WIDGET_CLONE].tooltips = STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW;
+
+ w->widget[DEPOT_WIDGET_LOCATION].tooltips = STR_A024_CENTER_MAIN_VIEW_ON_HANGAR;
+ w->widget[DEPOT_WIDGET_VEHICLE_LIST].data = STR_PLANE;
+ w->widget[DEPOT_WIDGET_VEHICLE_LIST].tooltips = STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP;
+ w->widget[DEPOT_WIDGET_AUTOREPLACE].tooltips = STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP;
+
+ /* Sprites */
+ w->widget[DEPOT_WIDGET_SELL].data = SPR_SELL_AIRCRAFT;
+ w->widget[DEPOT_WIDGET_SELL_ALL].data = SPR_SELL_ALL_AIRCRAFT;
+ w->widget[DEPOT_WIDGET_AUTOREPLACE].data = SPR_REPLACE_AIRCRAFT;
+ break;
+ }
+}
+
+static void CreateDepotListWindow(Window *w, byte type)
+{
+ WP(w, depot_d).type = type;
+ _backup_orders_tile = 0;
+
+ /* Resize the window according to the vehicle type */
+ switch (type) {
+ default: NOT_REACHED();
+ case VEH_Train:
+ w->vscroll.cap = 6;
+ w->hscroll.cap = 10 * 29;
+ w->resize.step_width = 1;
+ ResizeWindow(w, 56, 26);
+ break;
+
+ case VEH_Road:
+ w->vscroll.cap = 5;
+ w->hscroll.cap = 5;
+ w->resize.step_width = 56;
+ ResizeWindow(w, 10, 0);
+ break;
+
+ case VEH_Ship:
+ w->vscroll.cap = 3;
+ w->hscroll.cap = 3;
+ w->resize.step_width = 90;
+ ResizeWindow(w, 0, 2);
+ break;
+
+ case VEH_Aircraft:
+ w->vscroll.cap = 3;
+ w->hscroll.cap = 4;
+ w->resize.step_width = 74;
+ ResizeWindow(w, 26, 2);
+ break;
+ }
+
+ /* Set the minimum window size to the current window size */
+ w->resize.width = w->width;
+ w->resize.height = w->height;
+ w->resize.step_height = GetVehicleListHeight(type);
+
+ SetupStringsForDepotWindow(w, type);
+
+ w->widget[DEPOT_WIDGET_MATRIX].data =
+ (w->vscroll.cap * 0x100) // number of rows to draw on the background
+ + (type == VEH_Train ? 1 : w->hscroll.cap); // number of boxes in each row. Trains always have just one
+
+
+ SetWindowWidgetsHiddenState(w, type != VEH_Train,
+ DEPOT_WIDGET_H_SCROLL,
+ DEPOT_WIDGET_SELL_CHAIN,
+ WIDGET_LIST_END);
+
+ /* The train depot has a horizontal scroller, make the matrix that much shorter to fit */
+ if (type == VEH_Train) w->widget[DEPOT_WIDGET_MATRIX].bottom -= 12;
+ ResizeDepotButtons(w);
+}
+
+void DepotSortList(Vehicle **v, uint16 length);
+
+static void DepotWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_CREATE:
+ WP(w, depot_d).sel = INVALID_VEHICLE;
+ WP(w, depot_d).vehicle_list = NULL;
+ WP(w, depot_d).wagon_list = NULL;
+ WP(w, depot_d).engine_count = 0;
+ WP(w, depot_d).wagon_count = 0;
+ WP(w, depot_d).generate_list = true;
+ break;
+
+ case WE_INVALIDATE_DATA:
+ WP(w, depot_d).generate_list = true;
+ break;
+
+ case WE_PAINT:
+ if (WP(w, depot_d).generate_list) {
+ /* Generate the vehicle list
+ * It's ok to use the wagon pointers for non-trains as they will be ignored */
+ BuildDepotVehicleList(WP(w, depot_d).type, w->window_number,
+ &WP(w, depot_d).vehicle_list, &WP(w, depot_d).engine_list_length, &WP(w, depot_d).engine_count,
+ &WP(w, depot_d).wagon_list, &WP(w, depot_d).wagon_list_length, &WP(w, depot_d).wagon_count);
+ WP(w, depot_d).generate_list = false;
+ DepotSortList(WP(w, depot_d).vehicle_list, WP(w, depot_d).engine_count);
+//#ifndef NDEBUG
+#if 0
+/* We disabled this check for now, but will keep it to quickly make this test again later (if we change some code) */
+ } else {
+ /* Here we got a piece of code, that only checks if we got a different number of vehicles in the depot list and the number of vehicles actually being in the depot.
+ * IF they aren't the same, then WE_INVALIDATE_DATA should have been called somewhere, but it wasn't and we got a bug
+ * Since this is a time consuming check and not nice to memory fragmentation, it may not stay for long, but it's a good way to check this
+ * We can turn it on/off by switching between #ifndef NDEBUG and #if 0 */
+ Vehicle **engines = NULL, **wagons = NULL;
+ uint16 engine_count = 0, engine_length = 0;
+ uint16 wagon_count = 0, wagon_length = 0;
+ BuildDepotVehicleList(WP(w, depot_d).type, w->window_number, &engines, &engine_length, &engine_count,
+ &wagons, &wagon_length, &wagon_count);
+
+ assert(engine_count == WP(w, depot_d).engine_count);
+ assert(wagon_count == WP(w, depot_d).wagon_count);
+ free((void*)engines);
+ free((void*)wagons);
+#endif
+ }
+ DrawDepotWindow(w);
+ break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case DEPOT_WIDGET_MATRIX: // List
+ DepotClick(w, e->we.click.pt.x, e->we.click.pt.y);
+ break;
+
+ case DEPOT_WIDGET_BUILD: // Build vehicle
+ ResetObjectToPlace();
+ switch (WP(w, depot_d).type) {
+ case VEH_Train: ShowBuildTrainWindow(w->window_number); break;
+ case VEH_Road: ShowBuildRoadVehWindow(w->window_number); break;
+ case VEH_Ship: ShowBuildShipWindow(w->window_number); break;
+ case VEH_Aircraft:
+ ShowBuildVehicleWindow(w->window_number, WP(w, depot_d).type);
+ break;
+ default: NOT_REACHED();
+ }
+ break;
+
+ case DEPOT_WIDGET_CLONE: // Clone button
+ InvalidateWidget(w, DEPOT_WIDGET_CLONE);
+ ToggleWidgetLoweredState(w, DEPOT_WIDGET_CLONE);
+
+ if (IsWindowWidgetLowered(w, DEPOT_WIDGET_CLONE)) {
+ static const CursorID clone_icons[] = {
+ SPR_CURSOR_CLONE_TRAIN, SPR_CURSOR_CLONE_ROADVEH,
+ SPR_CURSOR_CLONE_SHIP, SPR_CURSOR_CLONE_AIRPLANE
+ };
+
+ _place_clicked_vehicle = NULL;
+ SetObjectToPlaceWnd(clone_icons[WP(w, depot_d).type - VEH_Train], VHM_RECT, w);
+ } else {
+ ResetObjectToPlace();
+ }
+ break;
+
+ case DEPOT_WIDGET_LOCATION: ScrollMainWindowToTile(w->window_number); break;
+
+ case DEPOT_WIDGET_STOP_ALL:
+ case DEPOT_WIDGET_START_ALL:
+ DoCommandP(w->window_number, 0, WP(w, depot_d).type | (e->we.click.widget == DEPOT_WIDGET_START_ALL ? (1 << 5) : 0), NULL, CMD_MASS_START_STOP);
+ break;
+
+ case DEPOT_WIDGET_SELL_ALL:
+ /* Only open the confimation window if there are anything to sell */
+ if (WP(w, depot_d).engine_count != 0 || WP(w, depot_d).wagon_count != 0) {
+ static const StringID confirm_captions[] = {
+ STR_8800_TRAIN_DEPOT,
+ STR_9003_ROAD_VEHICLE_DEPOT,
+ STR_9803_SHIP_DEPOT,
+ STR_A002_AIRCRAFT_HANGAR
+ };
+ TileIndex tile = w->window_number;
+ byte vehtype = WP(w, depot_d).type;
+
+ SetDParam(0, (vehtype == VEH_Aircraft) ? GetStationIndex(tile) : GetDepotByTile(tile)->town_index);
+ ShowQuery(
+ confirm_captions[vehtype - VEH_Train],
+ STR_DEPOT_SELL_CONFIRMATION_TEXT,
+ w,
+ DepotSellAllConfirmationCallback
+ );
+ }
+ break;
+
+ case DEPOT_WIDGET_VEHICLE_LIST:
+ ShowVehDepotOrders(GetTileOwner(w->window_number), WP(w, depot_d).type, w->window_number);
+ break;
+
+ case DEPOT_WIDGET_AUTOREPLACE:
+ DoCommandP(w->window_number, WP(w, depot_d).type, 0, NULL, CMD_DEPOT_MASS_AUTOREPLACE);
+ break;
+
+ }
+ break;
+
+ case WE_PLACE_OBJ: {
+ ClonePlaceObj(w);
+ } break;
+
+ case WE_ABORT_PLACE_OBJ: {
+ RaiseWindowWidget(w, DEPOT_WIDGET_CLONE);
+ InvalidateWidget(w, DEPOT_WIDGET_CLONE);
+ } break;
+
+ /* check if a vehicle in a depot was clicked.. */
+ case WE_MOUSELOOP: {
+ const Vehicle *v = _place_clicked_vehicle;
+
+ /* since OTTD checks all open depot windows, we will make sure that it triggers the one with a clicked clone button */
+ if (v != NULL && IsWindowWidgetLowered(w, DEPOT_WIDGET_CLONE)) {
+ _place_clicked_vehicle = NULL;
+ HandleCloneVehClick(v, w);
+ }
+ } break;
+
+ case WE_DESTROY:
+ DeleteWindowById(WC_BUILD_VEHICLE, w->window_number);
+ free((void*)WP(w, depot_d).vehicle_list);
+ free((void*)WP(w, depot_d).wagon_list);
+ break;
+
+ case WE_DRAGDROP:
+ switch (e->we.click.widget) {
+ case DEPOT_WIDGET_MATRIX: {
+ Vehicle *v;
+ VehicleID sel = WP(w, depot_d).sel;
+
+ WP(w, depot_d).sel = INVALID_VEHICLE;
+ SetWindowDirty(w);
+
+ if (WP(w, depot_d).type == VEH_Train) {
+ GetDepotVehiclePtData gdvp;
+
+ if (GetVehicleFromDepotWndPt(w, e->we.dragdrop.pt.x, e->we.dragdrop.pt.y, &v, &gdvp) == MODE_DRAG_VEHICLE &&
+ sel != INVALID_VEHICLE) {
+ if (gdvp.wagon != NULL && gdvp.wagon->index == sel && _ctrl_pressed) {
+ DoCommandP(GetVehicle(sel)->tile, GetVehicle(sel)->index, true, NULL, CMD_REVERSE_TRAIN_DIRECTION | CMD_MSG(STR_9033_CAN_T_MAKE_VEHICLE_TURN));
+ } else if (gdvp.wagon == NULL || gdvp.wagon->index != sel) {
+ TrainDepotMoveVehicle(gdvp.wagon, sel, gdvp.head);
+ } else if (gdvp.head != NULL && IsFrontEngine(gdvp.head)) {
+ ShowTrainViewWindow(gdvp.head);
+ }
+ }
+ } else if (GetVehicleFromDepotWndPt(w, e->we.dragdrop.pt.x, e->we.dragdrop.pt.y, &v, NULL) == MODE_DRAG_VEHICLE &&
+ v != NULL &&
+ sel == v->index) {
+ ShowVehicleViewWindow(v);
+ }
+ } break;
+
+ case DEPOT_WIDGET_SELL: case DEPOT_WIDGET_SELL_CHAIN:
+ if (!IsWindowWidgetDisabled(w, DEPOT_WIDGET_SELL) &&
+ WP(w, depot_d).sel != INVALID_VEHICLE) {
+ Vehicle *v;
+ uint command;
+ int sell_cmd;
+ bool is_engine;
+
+ if (IsWindowWidgetDisabled(w, e->we.click.widget)) return;
+ if (WP(w, depot_d).sel == INVALID_VEHICLE) return;
+
+ HandleButtonClick(w, e->we.click.widget);
+
+ v = GetVehicle(WP(w, depot_d).sel);
+ WP(w, depot_d).sel = INVALID_VEHICLE;
+ SetWindowDirty(w);
+
+ sell_cmd = (v->type == VEH_Train && (e->we.click.widget == DEPOT_WIDGET_SELL_CHAIN || _ctrl_pressed)) ? 1 : 0;
+
+ is_engine = (!(v->type == VEH_Train && !IsFrontEngine(v)));
+
+ if (is_engine) {
+ _backup_orders_tile = v->tile;
+ BackupVehicleOrders(v, _backup_orders_data);
+ }
+
+ switch (v->type) {
+ case VEH_Train: command = CMD_SELL_RAIL_WAGON | CMD_MSG(STR_8839_CAN_T_SELL_RAILROAD_VEHICLE); break;
+ case VEH_Road: command = CMD_SELL_ROAD_VEH | CMD_MSG(STR_9014_CAN_T_SELL_ROAD_VEHICLE); break;
+ case VEH_Ship: command = CMD_SELL_SHIP | CMD_MSG(STR_980C_CAN_T_SELL_SHIP); break;
+ case VEH_Aircraft: command = CMD_SELL_AIRCRAFT | CMD_MSG(STR_A01C_CAN_T_SELL_AIRCRAFT); break;
+ default: NOT_REACHED(); command = 0;
+ }
+
+ if (!DoCommandP(v->tile, v->index, sell_cmd, NULL, command) && is_engine) _backup_orders_tile = 0;
+ }
+ break;
+ default:
+ WP(w, depot_d).sel = INVALID_VEHICLE;
+ SetWindowDirty(w);
+ }
+ break;
+
+ case WE_RESIZE:
+ w->vscroll.cap += e->we.sizing.diff.y / (int)w->resize.step_height;
+ w->hscroll.cap += e->we.sizing.diff.x / (int)w->resize.step_width;
+ w->widget[DEPOT_WIDGET_MATRIX].data = (w->vscroll.cap << 8) + (WP(w, depot_d).type == VEH_Train ? 1 : w->hscroll.cap);
+ ResizeDepotButtons(w);
+ break;
+ }
+}
+
+/** Opens a depot window
+ * @param tile The tile where the depot/hangar is located
+ * @param type The type of vehicles in the depot
+ */
+void ShowDepotWindow(TileIndex tile, byte type)
+{
+ Window *w;
+
+ switch (type) {
+ default: NOT_REACHED();
+ case VEH_Train:
+ w = AllocateWindowDescFront(&_train_depot_desc, tile); break;
+ case VEH_Road:
+ w = AllocateWindowDescFront(&_road_depot_desc, tile); break;
+ case VEH_Ship:
+ w = AllocateWindowDescFront(&_ship_depot_desc, tile); break;
+ case VEH_Aircraft:
+ w = AllocateWindowDescFront(&_aircraft_depot_desc, tile); break;
+ }
+
+ if (w != NULL) {
+ w->caption_color = GetTileOwner(tile);
+ CreateDepotListWindow(w, type);
+ }
+}
+
+/** Removes the highlight of a vehicle in a depot window
+ * @param *v Vehicle to remove all highlights from
+ */
+void DeleteDepotHighlightOfVehicle(const Vehicle *v)
+{
+ Window *w;
+
+ /* If we haven't got any vehicles on the mouse pointer, we haven't got any highlighted in any depots either
+ * If that is the case, we can skip looping though the windows and save time */
+ if (_special_mouse_mode != WSM_DRAGDROP) return;
+
+ w = FindWindowById(WC_VEHICLE_DEPOT, v->tile);
+ if (w != NULL) {
+ WP(w, depot_d).sel = INVALID_VEHICLE;
+ ResetObjectToPlace();
+ }
+}
diff --git a/src/direction.h b/src/direction.h
new file mode 100644
index 000000000..477c34046
--- /dev/null
+++ b/src/direction.h
@@ -0,0 +1,147 @@
+/* $Id$ */
+
+#ifndef DIRECTION_H
+#define DIRECTION_H
+
+/* Direction as commonly used in v->direction, 8 way. */
+typedef enum Direction {
+ DIR_N = 0,
+ DIR_NE = 1, /* Northeast, upper right on your monitor */
+ DIR_E = 2,
+ DIR_SE = 3,
+ DIR_S = 4,
+ DIR_SW = 5,
+ DIR_W = 6,
+ DIR_NW = 7,
+ DIR_END,
+ INVALID_DIR = 0xFF,
+} Direction;
+
+static inline Direction ReverseDir(Direction d)
+{
+ return (Direction)(4 ^ d);
+}
+
+
+typedef enum DirDiff {
+ DIRDIFF_SAME = 0,
+ DIRDIFF_45RIGHT = 1,
+ DIRDIFF_90RIGHT = 2,
+ DIRDIFF_REVERSE = 4,
+ DIRDIFF_90LEFT = 6,
+ DIRDIFF_45LEFT = 7
+} DirDiff;
+
+static inline DirDiff DirDifference(Direction d0, Direction d1)
+{
+ return (DirDiff)((d0 + 8 - d1) % 8);
+}
+
+static inline DirDiff ChangeDirDiff(DirDiff d, DirDiff delta)
+{
+ return (DirDiff)((d + delta) % 8);
+}
+
+
+static inline Direction ChangeDir(Direction d, DirDiff delta)
+{
+ return (Direction)((d + delta) % 8);
+}
+
+
+/* Direction commonly used as the direction of entering and leaving tiles, 4-way */
+typedef enum DiagDirection {
+ DIAGDIR_NE = 0, /* Northeast, upper right on your monitor */
+ DIAGDIR_SE = 1,
+ DIAGDIR_SW = 2,
+ DIAGDIR_NW = 3,
+ DIAGDIR_END,
+ INVALID_DIAGDIR = 0xFF,
+} DiagDirection;
+
+static inline DiagDirection ReverseDiagDir(DiagDirection d)
+{
+ return (DiagDirection)(2 ^ d);
+}
+
+
+typedef enum DiagDirDiff {
+ DIAGDIRDIFF_SAME = 0,
+ DIAGDIRDIFF_90RIGHT = 1,
+ DIAGDIRDIFF_REVERSE = 2,
+ DIAGDIRDIFF_90LEFT = 3
+} DiagDirDiff;
+
+static inline DiagDirection ChangeDiagDir(DiagDirection d, DiagDirDiff delta)
+{
+ return (DiagDirection)((d + delta) % 4);
+}
+
+
+static inline DiagDirection DirToDiagDir(Direction dir)
+{
+ return (DiagDirection)(dir >> 1);
+}
+
+
+static inline Direction DiagDirToDir(DiagDirection dir)
+{
+ return (Direction)(dir * 2 + 1);
+}
+
+
+/* the 2 axis */
+typedef enum Axis {
+ AXIS_X = 0,
+ AXIS_Y = 1,
+ AXIS_END
+} Axis;
+
+
+static inline Axis OtherAxis(Axis a)
+{
+ return (Axis)(a ^ 1);
+}
+
+
+static inline Axis DiagDirToAxis(DiagDirection d)
+{
+ return (Axis)(d & 1);
+}
+
+
+/*
+ * Converts an Axis to a DiagDirection
+ * Points always in the positive direction, i.e. S[EW]
+ */
+static inline DiagDirection AxisToDiagDir(Axis a)
+{
+ return (DiagDirection)(2 - a);
+}
+
+/**
+ * Convert an axis and a flag for north/south into a DiagDirection
+ * @param ns north -> 0, south -> 1
+ */
+static inline DiagDirection XYNSToDiagDir(Axis xy, uint ns)
+{
+ return (DiagDirection)(xy * 3 ^ ns * 2);
+}
+
+
+static inline bool IsValidDiagDirection(DiagDirection d)
+{
+ return d < DIAGDIR_END;
+}
+
+static inline bool IsValidDirection(Direction d)
+{
+ return d < DIR_END;
+}
+
+static inline bool IsValidAxis(Axis d)
+{
+ return d < AXIS_END;
+}
+
+#endif /* DIRECTION_H */
diff --git a/src/disaster_cmd.c b/src/disaster_cmd.c
new file mode 100644
index 000000000..2d4579b52
--- /dev/null
+++ b/src/disaster_cmd.c
@@ -0,0 +1,1001 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "functions.h"
+#include "industry_map.h"
+#include "station_map.h"
+#include "table/strings.h"
+#include "map.h"
+#include "tile.h"
+#include "vehicle.h"
+#include "command.h"
+#include "news.h"
+#include "station.h"
+#include "waypoint.h"
+#include "town.h"
+#include "industry.h"
+#include "player.h"
+#include "airport.h"
+#include "sound.h"
+#include "variables.h"
+#include "table/sprites.h"
+#include "date.h"
+
+static void DisasterClearSquare(TileIndex tile)
+{
+ if (!EnsureNoVehicle(tile)) return;
+
+ switch (GetTileType(tile)) {
+ case MP_RAILWAY:
+ if (IsHumanPlayer(GetTileOwner(tile)) && !IsRailWaypoint(tile)) {
+ PlayerID p = _current_player;
+ _current_player = OWNER_WATER;
+ DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
+ _current_player = p;
+ }
+ break;
+
+ case MP_HOUSE: {
+ PlayerID p = _current_player;
+ _current_player = OWNER_NONE;
+ DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
+ _current_player = p;
+ break;
+ }
+
+ case MP_TREES:
+ case MP_CLEAR:
+ DoClearSquare(tile);
+ break;
+
+ default:
+ break;
+ }
+}
+
+static const SpriteID _disaster_images_1[] = {0xF41, 0xF41, 0xF41, 0xF41, 0xF41, 0xF41, 0xF41, 0xF41};
+static const SpriteID _disaster_images_2[] = {0xF44, 0xF44, 0xF44, 0xF44, 0xF44, 0xF44, 0xF44, 0xF44};
+static const SpriteID _disaster_images_3[] = {0xF4E, 0xF4E, 0xF4E, 0xF4E, 0xF4E, 0xF4E, 0xF4E, 0xF4E};
+static const SpriteID _disaster_images_4[] = {0xF46, 0xF46, 0xF47, 0xF47, 0xF48, 0xF48, 0xF49, 0xF49};
+static const SpriteID _disaster_images_5[] = {0xF4A, 0xF4A, 0xF4B, 0xF4B, 0xF4C, 0xF4C, 0xF4D, 0xF4D};
+static const SpriteID _disaster_images_6[] = {0xF50, 0xF50, 0xF50, 0xF50, 0xF50, 0xF50, 0xF50, 0xF50};
+static const SpriteID _disaster_images_7[] = {0xF51, 0xF51, 0xF51, 0xF51, 0xF51, 0xF51, 0xF51, 0xF51};
+static const SpriteID _disaster_images_8[] = {0xF52, 0xF52, 0xF52, 0xF52, 0xF52, 0xF52, 0xF52, 0xF52};
+static const SpriteID _disaster_images_9[] = {0xF3E, 0xF3E, 0xF3E, 0xF3E, 0xF3E, 0xF3E, 0xF3E, 0xF3E};
+
+static const SpriteID * const _disaster_images[] = {
+ _disaster_images_1, _disaster_images_1,
+ _disaster_images_2, _disaster_images_2,
+ _disaster_images_3, _disaster_images_3,
+ _disaster_images_8, _disaster_images_8, _disaster_images_9,
+ _disaster_images_6, _disaster_images_6,
+ _disaster_images_7, _disaster_images_7,
+ _disaster_images_4, _disaster_images_5,
+};
+
+static void DisasterVehicleUpdateImage(Vehicle *v)
+{
+ int img = v->u.disaster.image_override;
+ if (img == 0)
+ img = _disaster_images[v->subtype][v->direction];
+ v->cur_image = img;
+}
+
+static void InitializeDisasterVehicle(Vehicle* v, int x, int y, byte z, Direction direction, byte subtype)
+{
+ v->type = VEH_Disaster;
+ v->x_pos = x;
+ v->y_pos = y;
+ v->z_pos = z;
+ v->tile = TileVirtXY(x, y);
+ v->direction = direction;
+ v->subtype = subtype;
+ v->x_offs = -1;
+ v->y_offs = -1;
+ v->sprite_width = 2;
+ v->sprite_height = 2;
+ v->z_height = 5;
+ v->owner = OWNER_NONE;
+ v->vehstatus = VS_UNCLICKABLE;
+ v->u.disaster.image_override = 0;
+ v->current_order.type = OT_NOTHING;
+ v->current_order.flags = 0;
+ v->current_order.dest = 0;
+
+ DisasterVehicleUpdateImage(v);
+ VehiclePositionChanged(v);
+ BeginVehicleMove(v);
+ EndVehicleMove(v);
+}
+
+static void DeleteDisasterVeh(Vehicle *v)
+{
+ DeleteVehicleChain(v);
+}
+
+static void SetDisasterVehiclePos(Vehicle *v, int x, int y, byte z)
+{
+ Vehicle *u;
+
+ BeginVehicleMove(v);
+ v->x_pos = x;
+ v->y_pos = y;
+ v->z_pos = z;
+ v->tile = TileVirtXY(x, y);
+
+ DisasterVehicleUpdateImage(v);
+ VehiclePositionChanged(v);
+ EndVehicleMove(v);
+
+ if ( (u=v->next) != NULL) {
+ int safe_x = clamp(x, 0, MapMaxX() * TILE_SIZE);
+ int safe_y = clamp(y - 1, 0, MapMaxY() * TILE_SIZE);
+ BeginVehicleMove(u);
+
+ u->x_pos = x;
+ u->y_pos = y - 1 - (max(z - GetSlopeZ(safe_x, safe_y), 0) >> 3);
+ safe_y = clamp(u->y_pos, 0, MapMaxY() * TILE_SIZE);
+ u->z_pos = GetSlopeZ(safe_x, safe_y);
+ u->direction = v->direction;
+
+ DisasterVehicleUpdateImage(u);
+ VehiclePositionChanged(u);
+ EndVehicleMove(u);
+
+ if ( (u=u->next) != NULL) {
+ BeginVehicleMove(u);
+ u->x_pos = x;
+ u->y_pos = y;
+ u->z_pos = z + 5;
+ VehiclePositionChanged(u);
+ EndVehicleMove(u);
+ }
+ }
+}
+
+
+static void DisasterTick_Zeppeliner(Vehicle *v)
+{
+ GetNewVehiclePosResult gp;
+ Station *st;
+ int x,y;
+ byte z;
+ TileIndex tile;
+
+ ++v->tick_counter;
+
+ if (v->current_order.dest < 2) {
+ if (v->tick_counter&1)
+ return;
+
+ GetNewVehiclePos(v, &gp);
+
+ SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
+
+ if (v->current_order.dest == 1) {
+ if (++v->age == 38) {
+ v->current_order.dest = 2;
+ v->age = 0;
+ }
+
+ if ((v->tick_counter&7)==0) {
+ CreateEffectVehicleRel(v, 0, -17, 2, EV_SMOKE);
+ }
+ } else if (v->current_order.dest == 0) {
+ tile = v->tile; /**/
+
+ if (IsValidTile(tile) &&
+ IsTileType(tile, MP_STATION) &&
+ IsAirport(tile) &&
+ IsHumanPlayer(GetTileOwner(tile))) {
+ v->current_order.dest = 1;
+ v->age = 0;
+
+ SetDParam(0, GetStationIndex(tile));
+ AddNewsItem(STR_B000_ZEPPELIN_DISASTER_AT,
+ NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ACCIDENT, 0),
+ v->index,
+ 0);
+ }
+ }
+ if (v->y_pos >= ((int)MapSizeY() + 9) * TILE_SIZE - 1)
+ DeleteDisasterVeh(v);
+ return;
+ }
+
+ if (v->current_order.dest > 2) {
+ if (++v->age <= 13320)
+ return;
+
+ tile = v->tile; /**/
+
+ if (IsValidTile(tile) &&
+ IsTileType(tile, MP_STATION) &&
+ IsAirport(tile) &&
+ IsHumanPlayer(GetTileOwner(tile))) {
+ st = GetStationByTile(tile);
+ CLRBITS(st->airport_flags, RUNWAY_IN_block);
+ }
+
+ SetDisasterVehiclePos(v, v->x_pos, v->y_pos, v->z_pos);
+ DeleteDisasterVeh(v);
+ return;
+ }
+
+ x = v->x_pos;
+ y = v->y_pos;
+ z = GetSlopeZ(x,y);
+ if (z < v->z_pos)
+ z = v->z_pos - 1;
+ SetDisasterVehiclePos(v, x, y, z);
+
+ if (++v->age == 1) {
+ CreateEffectVehicleRel(v, 0, 7, 8, EV_EXPLOSION_LARGE);
+ SndPlayVehicleFx(SND_12_EXPLOSION, v);
+ v->u.disaster.image_override = SPR_BLIMP_CRASHING;
+ } else if (v->age == 70) {
+ v->u.disaster.image_override = SPR_BLIMP_CRASHED;
+ } else if (v->age <= 300) {
+ if (!(v->tick_counter&7)) {
+ uint32 r = Random();
+
+ CreateEffectVehicleRel(v,
+ GB(r, 0, 4) - 7,
+ GB(r, 4, 4) - 7,
+ GB(r, 8, 3) + 5,
+ EV_EXPLOSION_SMALL);
+ }
+ } else if (v->age == 350) {
+ v->current_order.dest = 3;
+ v->age = 0;
+ }
+
+ tile = v->tile;/**/
+ if (IsValidTile(tile) &&
+ IsTileType(tile, MP_STATION) &&
+ IsAirport(tile) &&
+ IsHumanPlayer(GetTileOwner(tile))) {
+ st = GetStationByTile(tile);
+ SETBITS(st->airport_flags, RUNWAY_IN_block);
+ }
+}
+
+// UFO starts in the middle, and flies around a bit until it locates
+// a road vehicle which it targets.
+static void DisasterTick_UFO(Vehicle *v)
+{
+ GetNewVehiclePosResult gp;
+ Vehicle *u;
+ uint dist;
+ byte z;
+
+ v->u.disaster.image_override = (++v->tick_counter & 8) ? SPR_UFO_SMALL_SCOUT_DARKER : SPR_UFO_SMALL_SCOUT;
+
+ if (v->current_order.dest == 0) {
+// fly around randomly
+ int x = TileX(v->dest_tile) * TILE_SIZE;
+ int y = TileY(v->dest_tile) * TILE_SIZE;
+ if (abs(x - v->x_pos) + abs(y - v->y_pos) >= TILE_SIZE) {
+ v->direction = GetDirectionTowards(v, x, y);
+ GetNewVehiclePos(v, &gp);
+ SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
+ return;
+ }
+ if (++v->age < 6) {
+ v->dest_tile = RandomTile();
+ return;
+ }
+ v->current_order.dest = 1;
+
+ FOR_ALL_VEHICLES(u) {
+ if (u->type == VEH_Road && IsHumanPlayer(u->owner)) {
+ v->dest_tile = u->index;
+ v->age = 0;
+ return;
+ }
+ }
+
+ DeleteDisasterVeh(v);
+ } else {
+// target a vehicle
+ u = GetVehicle(v->dest_tile);
+ if (u->type != VEH_Road) {
+ DeleteDisasterVeh(v);
+ return;
+ }
+
+ dist = abs(v->x_pos - u->x_pos) + abs(v->y_pos - u->y_pos);
+
+ if (dist < TILE_SIZE && !(u->vehstatus&VS_HIDDEN) && u->breakdown_ctr==0) {
+ u->breakdown_ctr = 3;
+ u->breakdown_delay = 140;
+ }
+
+ v->direction = GetDirectionTowards(v, u->x_pos, u->y_pos);
+ GetNewVehiclePos(v, &gp);
+
+ z = v->z_pos;
+ if (dist <= TILE_SIZE && z > u->z_pos) z--;
+ SetDisasterVehiclePos(v, gp.x, gp.y, z);
+
+ if (z <= u->z_pos && (u->vehstatus&VS_HIDDEN)==0) {
+ v->age++;
+ if (u->u.road.crashed_ctr == 0) {
+ u->u.road.crashed_ctr++;
+ u->vehstatus |= VS_CRASHED;
+
+ AddNewsItem(STR_B001_ROAD_VEHICLE_DESTROYED,
+ NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ACCIDENT, 0),
+ u->index,
+ 0);
+ }
+ }
+
+// destroy?
+ if (v->age > 50) {
+ CreateEffectVehicleRel(v, 0, 7, 8, EV_EXPLOSION_LARGE);
+ SndPlayVehicleFx(SND_12_EXPLOSION, v);
+ DeleteDisasterVeh(v);
+ }
+ }
+}
+
+static void DestructIndustry(Industry *i)
+{
+ TileIndex tile;
+
+ for (tile = 0; tile != MapSize(); tile++) {
+ if (IsTileType(tile, MP_INDUSTRY) && GetIndustryIndex(tile) == i->index) {
+ ResetIndustryConstructionStage(tile);
+ MarkTileDirtyByTile(tile);
+ }
+ }
+}
+
+// Airplane which destroys an oil refinery
+static void DisasterTick_2(Vehicle *v)
+{
+ GetNewVehiclePosResult gp;
+
+ v->tick_counter++;
+ v->u.disaster.image_override =
+ (v->current_order.dest == 1 && v->tick_counter & 4) ? SPR_F_15_FIRING : 0;
+
+ GetNewVehiclePos(v, &gp);
+ SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
+
+ if (gp.x < -160) {
+ DeleteDisasterVeh(v);
+ return;
+ }
+
+ if (v->current_order.dest == 2) {
+ if (!(v->tick_counter&3)) {
+ Industry *i = GetIndustry(v->dest_tile);
+ int x = TileX(i->xy) * TILE_SIZE;
+ int y = TileY(i->xy) * TILE_SIZE;
+ uint32 r = Random();
+
+ CreateEffectVehicleAbove(
+ GB(r, 0, 6) + x,
+ GB(r, 6, 6) + y,
+ GB(r, 12, 4),
+ EV_EXPLOSION_SMALL);
+
+ if (++v->age >= 55)
+ v->current_order.dest = 3;
+ }
+ } else if (v->current_order.dest == 1) {
+ if (++v->age == 112) {
+ Industry *i;
+
+ v->current_order.dest = 2;
+ v->age = 0;
+
+ i = GetIndustry(v->dest_tile);
+ DestructIndustry(i);
+
+ SetDParam(0, i->town->index);
+ AddNewsItem(STR_B002_OIL_REFINERY_EXPLOSION, NEWS_FLAGS(NM_THIN,NF_VIEWPORT|NF_TILE,NT_ACCIDENT,0), i->xy, 0);
+ SndPlayTileFx(SND_12_EXPLOSION, i->xy);
+ }
+ } else if (v->current_order.dest == 0) {
+ int x,y;
+ TileIndex tile;
+ uint ind;
+
+ x = v->x_pos - 15 * TILE_SIZE;
+ y = v->y_pos;
+
+ if ( (uint)x > MapMaxX() * TILE_SIZE - 1)
+ return;
+
+ tile = TileVirtXY(x, y);
+ if (!IsTileType(tile, MP_INDUSTRY))
+ return;
+
+ ind = GetIndustryIndex(tile);
+ v->dest_tile = ind;
+
+ if (GetIndustry(ind)->type == IT_OIL_REFINERY) {
+ v->current_order.dest = 1;
+ v->age = 0;
+ }
+ }
+}
+
+// Helicopter which destroys a factory
+static void DisasterTick_3(Vehicle *v)
+{
+ GetNewVehiclePosResult gp;
+
+ v->tick_counter++;
+ v->u.disaster.image_override =
+ (v->current_order.dest == 1 && v->tick_counter & 4) ? SPR_AH_64A_FIRING : 0;
+
+ GetNewVehiclePos(v, &gp);
+ SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
+
+ if (gp.x > (int)MapSizeX() * TILE_SIZE + 9 * TILE_SIZE - 1) {
+ DeleteDisasterVeh(v);
+ return;
+ }
+
+ if (v->current_order.dest == 2) {
+ if (!(v->tick_counter&3)) {
+ Industry *i = GetIndustry(v->dest_tile);
+ int x = TileX(i->xy) * TILE_SIZE;
+ int y = TileY(i->xy) * TILE_SIZE;
+ uint32 r = Random();
+
+ CreateEffectVehicleAbove(
+ GB(r, 0, 6) + x,
+ GB(r, 6, 6) + y,
+ GB(r, 12, 4),
+ EV_EXPLOSION_SMALL);
+
+ if (++v->age >= 55)
+ v->current_order.dest = 3;
+ }
+ } else if (v->current_order.dest == 1) {
+ if (++v->age == 112) {
+ Industry *i;
+
+ v->current_order.dest = 2;
+ v->age = 0;
+
+ i = GetIndustry(v->dest_tile);
+ DestructIndustry(i);
+
+ SetDParam(0, i->town->index);
+ AddNewsItem(STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS, NEWS_FLAGS(NM_THIN,NF_VIEWPORT|NF_TILE,NT_ACCIDENT,0), i->xy, 0);
+ SndPlayTileFx(SND_12_EXPLOSION, i->xy);
+ }
+ } else if (v->current_order.dest == 0) {
+ int x,y;
+ TileIndex tile;
+ uint ind;
+
+ x = v->x_pos - 15 * TILE_SIZE;
+ y = v->y_pos;
+
+ if ( (uint)x > MapMaxX() * TILE_SIZE - 1)
+ return;
+
+ tile = TileVirtXY(x, y);
+ if (!IsTileType(tile, MP_INDUSTRY))
+ return;
+
+ ind = GetIndustryIndex(tile);
+ v->dest_tile = ind;
+
+ if (GetIndustry(ind)->type == IT_FACTORY) {
+ v->current_order.dest = 1;
+ v->age = 0;
+ }
+ }
+}
+
+// Helicopter rotor blades
+static void DisasterTick_3b(Vehicle *v)
+{
+ if (++v->tick_counter & 1)
+ return;
+
+ if (++v->cur_image > SPR_ROTOR_MOVING_3) v->cur_image = SPR_ROTOR_MOVING_1;
+
+ VehiclePositionChanged(v);
+ BeginVehicleMove(v);
+ EndVehicleMove(v);
+}
+
+// Big UFO which lands on a piece of rail.
+// Will be shot down by a plane
+static void DisasterTick_4(Vehicle *v)
+{
+ GetNewVehiclePosResult gp;
+ byte z;
+ Vehicle *u,*w;
+ Town *t;
+ TileIndex tile;
+ TileIndex tile_org;
+
+ v->tick_counter++;
+
+ if (v->current_order.dest == 1) {
+ int x = TileX(v->dest_tile) * TILE_SIZE + TILE_SIZE / 2;
+ int y = TileY(v->dest_tile) * TILE_SIZE + TILE_SIZE / 2;
+ if (abs(v->x_pos - x) + abs(v->y_pos - y) >= 8) {
+ v->direction = GetDirectionTowards(v, x, y);
+
+ GetNewVehiclePos(v, &gp);
+ SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
+ return;
+ }
+
+ z = GetSlopeZ(v->x_pos, v->y_pos);
+ if (z < v->z_pos) {
+ SetDisasterVehiclePos(v, v->x_pos, v->y_pos, v->z_pos - 1);
+ return;
+ }
+
+ v->current_order.dest = 2;
+
+ FOR_ALL_VEHICLES(u) {
+ if (u->type == VEH_Train || u->type == VEH_Road) {
+ if (abs(u->x_pos - v->x_pos) + abs(u->y_pos - v->y_pos) <= 12 * TILE_SIZE) {
+ u->breakdown_ctr = 5;
+ u->breakdown_delay = 0xF0;
+ }
+ }
+ }
+
+ t = ClosestTownFromTile(v->dest_tile, (uint)-1);
+ SetDParam(0, t->index);
+ AddNewsItem(STR_B004_UFO_LANDS_NEAR,
+ NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_TILE, NT_ACCIDENT, 0),
+ v->tile,
+ 0);
+
+ u = ForceAllocateSpecialVehicle();
+ if (u == NULL) {
+ DeleteDisasterVeh(v);
+ return;
+ }
+
+ InitializeDisasterVehicle(u, -6 * TILE_SIZE, v->y_pos, 135, DIR_SW, 11);
+ u->u.disaster.unk2 = v->index;
+
+ w = ForceAllocateSpecialVehicle();
+ if (w == NULL)
+ return;
+
+ u->next = w;
+ InitializeDisasterVehicle(w, -6 * TILE_SIZE, v->y_pos, 0, DIR_SW, 12);
+ w->vehstatus |= VS_SHADOW;
+ } else if (v->current_order.dest < 1) {
+
+ int x = TileX(v->dest_tile) * TILE_SIZE;
+ int y = TileY(v->dest_tile) * TILE_SIZE;
+ if (abs(x - v->x_pos) + abs(y - v->y_pos) >= TILE_SIZE) {
+ v->direction = GetDirectionTowards(v, x, y);
+ GetNewVehiclePos(v, &gp);
+ SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
+ return;
+ }
+
+ if (++v->age < 6) {
+ v->dest_tile = RandomTile();
+ return;
+ }
+ v->current_order.dest = 1;
+
+ tile_org = tile = RandomTile();
+ do {
+ if (IsTileType(tile, MP_RAILWAY) &&
+ IsPlainRailTile(tile) &&
+ IsHumanPlayer(GetTileOwner(tile))) {
+ break;
+ }
+ tile = TILE_MASK(tile+1);
+ } while (tile != tile_org);
+ v->dest_tile = tile;
+ v->age = 0;
+ } else {
+ return;
+ }
+}
+
+// The plane which will shoot down the UFO
+static void DisasterTick_4b(Vehicle *v)
+{
+ GetNewVehiclePosResult gp;
+ Vehicle *u;
+ int i;
+
+ v->tick_counter++;
+
+ GetNewVehiclePos(v, &gp);
+ SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
+
+ if (gp.x > (int)MapSizeX() * TILE_SIZE + 9 * TILE_SIZE - 1) {
+ DeleteDisasterVeh(v);
+ return;
+ }
+
+ if (v->current_order.dest == 0) {
+ u = GetVehicle(v->u.disaster.unk2);
+ if (abs(v->x_pos - u->x_pos) > TILE_SIZE)
+ return;
+ v->current_order.dest = 1;
+
+ CreateEffectVehicleRel(u, 0, 7, 8, EV_EXPLOSION_LARGE);
+ SndPlayVehicleFx(SND_12_EXPLOSION, u);
+
+ DeleteDisasterVeh(u);
+
+ for (i = 0; i != 80; i++) {
+ uint32 r = Random();
+ CreateEffectVehicleAbove(
+ GB(r, 0, 6) + v->x_pos - 32,
+ GB(r, 5, 6) + v->y_pos - 32,
+ 0,
+ EV_EXPLOSION_SMALL);
+ }
+
+ BEGIN_TILE_LOOP(tile, 6, 6, v->tile - TileDiffXY(3, 3))
+ tile = TILE_MASK(tile);
+ DisasterClearSquare(tile);
+ END_TILE_LOOP(tile, 6, 6, v->tile - TileDiffXY(3, 3))
+ }
+}
+
+// Submarine handler
+static void DisasterTick_5_and_6(Vehicle *v)
+{
+ uint32 r;
+ GetNewVehiclePosResult gp;
+ TileIndex tile;
+
+ v->tick_counter++;
+
+ if (++v->age > 8880) {
+ VehiclePositionChanged(v);
+ BeginVehicleMove(v);
+ EndVehicleMove(v);
+ DeleteVehicle(v);
+ return;
+ }
+
+ if (!(v->tick_counter & 1)) return;
+
+ tile = v->tile + TileOffsByDiagDir(DirToDiagDir(v->direction));
+ if (IsValidTile(tile) &&
+ (r=GetTileTrackStatus(tile,TRANSPORT_WATER),(byte)(r+(r >> 8)) == 0x3F) &&
+ !CHANCE16(1,90)) {
+ GetNewVehiclePos(v, &gp);
+ SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
+ return;
+ }
+
+ v->direction = ChangeDir(v->direction, GB(Random(), 0, 1) ? DIRDIFF_90RIGHT : DIRDIFF_90LEFT);
+}
+
+
+static void DisasterTick_NULL(Vehicle *v) {}
+typedef void DisasterVehicleTickProc(Vehicle *v);
+
+static DisasterVehicleTickProc * const _disastervehicle_tick_procs[] = {
+ DisasterTick_Zeppeliner,DisasterTick_NULL,
+ DisasterTick_UFO,DisasterTick_NULL,
+ DisasterTick_2,DisasterTick_NULL,
+ DisasterTick_3,DisasterTick_NULL,DisasterTick_3b,
+ DisasterTick_4,DisasterTick_NULL,
+ DisasterTick_4b,DisasterTick_NULL,
+ DisasterTick_5_and_6,
+ DisasterTick_5_and_6,
+};
+
+
+void DisasterVehicle_Tick(Vehicle *v)
+{
+ _disastervehicle_tick_procs[v->subtype](v);
+}
+
+
+void OnNewDay_DisasterVehicle(Vehicle *v)
+{
+ // not used
+}
+
+typedef void DisasterInitProc(void);
+
+// Zeppeliner which crashes on a small airport
+static void Disaster0_Init(void)
+{
+ Vehicle *v = ForceAllocateSpecialVehicle(), *u;
+ Station *st;
+ int x;
+
+ if (v == NULL) return;
+
+ /* Pick a random place, unless we find a small airport */
+ x = TileX(Random()) * TILE_SIZE + TILE_SIZE / 2;
+
+ FOR_ALL_STATIONS(st) {
+ if (st->airport_tile != 0 &&
+ st->airport_type <= 1 &&
+ IsHumanPlayer(st->owner)) {
+ x = (TileX(st->xy) + 2) * TILE_SIZE;
+ break;
+ }
+ }
+
+ InitializeDisasterVehicle(v, x, 0, 135, DIR_SE, 0);
+
+ // Allocate shadow too?
+ u = ForceAllocateSpecialVehicle();
+ if (u != NULL) {
+ v->next = u;
+ InitializeDisasterVehicle(u, x, 0, 0, DIR_SE, 1);
+ u->vehstatus |= VS_SHADOW;
+ }
+}
+
+static void Disaster1_Init(void)
+{
+ Vehicle *v = ForceAllocateSpecialVehicle(), *u;
+ int x;
+
+ if (v == NULL) return;
+
+ x = TileX(Random()) * TILE_SIZE + TILE_SIZE / 2;
+
+ InitializeDisasterVehicle(v, x, 0, 135, DIR_SE, 2);
+ v->dest_tile = TileXY(MapSizeX() / 2, MapSizeY() / 2);
+ v->age = 0;
+
+ // Allocate shadow too?
+ u = ForceAllocateSpecialVehicle();
+ if (u != NULL) {
+ v->next = u;
+ InitializeDisasterVehicle(u, x, 0, 0, DIR_SE, 3);
+ u->vehstatus |= VS_SHADOW;
+ }
+}
+
+static void Disaster2_Init(void)
+{
+ Industry *i, *found;
+ Vehicle *v,*u;
+ int x,y;
+
+ found = NULL;
+
+ FOR_ALL_INDUSTRIES(i) {
+ if (i->type == IT_OIL_REFINERY &&
+ (found == NULL || CHANCE16(1, 2))) {
+ found = i;
+ }
+ }
+
+ if (found == NULL) return;
+
+ v = ForceAllocateSpecialVehicle();
+ if (v == NULL) return;
+
+ x = (MapSizeX() + 9) * TILE_SIZE - 1;
+ y = TileY(found->xy) * TILE_SIZE + 37;
+
+ InitializeDisasterVehicle(v, x, y, 135, DIR_NE, 4);
+
+ u = ForceAllocateSpecialVehicle();
+ if (u != NULL) {
+ v->next = u;
+ InitializeDisasterVehicle(u, x, y, 0, DIR_SE, 5);
+ u->vehstatus |= VS_SHADOW;
+ }
+}
+
+static void Disaster3_Init(void)
+{
+ Industry *i, *found;
+ Vehicle *v,*u,*w;
+ int x,y;
+
+ found = NULL;
+
+ FOR_ALL_INDUSTRIES(i) {
+ if (i->type == IT_FACTORY &&
+ (found==NULL || CHANCE16(1,2))) {
+ found = i;
+ }
+ }
+
+ if (found == NULL) return;
+
+ v = ForceAllocateSpecialVehicle();
+ if (v == NULL) return;
+
+ x = -16 * TILE_SIZE;
+ y = TileY(found->xy) * TILE_SIZE + 37;
+
+ InitializeDisasterVehicle(v, x, y, 135, DIR_SW, 6);
+
+ u = ForceAllocateSpecialVehicle();
+ if (u != NULL) {
+ v->next = u;
+ InitializeDisasterVehicle(u, x, y, 0, DIR_SW, 7);
+ u->vehstatus |= VS_SHADOW;
+
+ w = ForceAllocateSpecialVehicle();
+ if (w != NULL) {
+ u->next = w;
+ InitializeDisasterVehicle(w, x, y, 140, DIR_SW, 8);
+ }
+ }
+}
+
+static void Disaster4_Init(void)
+{
+ Vehicle *v = ForceAllocateSpecialVehicle(), *u;
+ int x,y;
+
+ if (v == NULL) return;
+
+ x = TileX(Random()) * TILE_SIZE + TILE_SIZE / 2;
+
+ y = MapMaxX() * TILE_SIZE - 1;
+ InitializeDisasterVehicle(v, x, y, 135, DIR_NW, 9);
+ v->dest_tile = TileXY(MapSizeX() / 2, MapSizeY() / 2);
+ v->age = 0;
+
+ // Allocate shadow too?
+ u = ForceAllocateSpecialVehicle();
+ if (u != NULL) {
+ v->next = u;
+ InitializeDisasterVehicle(u, x, y, 0, DIR_NW, 10);
+ u->vehstatus |= VS_SHADOW;
+ }
+}
+
+// Submarine type 1
+static void Disaster5_Init(void)
+{
+ Vehicle *v = ForceAllocateSpecialVehicle();
+ int x,y;
+ Direction dir;
+ uint32 r;
+
+ if (v == NULL) return;
+
+ r = Random();
+ x = TileX(r) * TILE_SIZE + TILE_SIZE / 2;
+
+ if (r & 0x80000000) {
+ y = MapMaxX() * TILE_SIZE - TILE_SIZE / 2 - 1;
+ dir = DIR_NW;
+ } else {
+ y = TILE_SIZE / 2;
+ dir = DIR_SE;
+ }
+ InitializeDisasterVehicle(v, x, y, 0, dir, 13);
+ v->age = 0;
+}
+
+// Submarine type 2
+static void Disaster6_Init(void)
+{
+ Vehicle *v = ForceAllocateSpecialVehicle();
+ int x,y;
+ Direction dir;
+ uint32 r;
+
+ if (v == NULL) return;
+
+ r = Random();
+ x = TileX(r) * TILE_SIZE + TILE_SIZE / 2;
+
+ if (r & 0x80000000) {
+ y = MapMaxX() * TILE_SIZE - TILE_SIZE / 2 - 1;
+ dir = DIR_NW;
+ } else {
+ y = TILE_SIZE / 2;
+ dir = DIR_SE;
+ }
+ InitializeDisasterVehicle(v, x, y, 0, dir, 14);
+ v->age = 0;
+}
+
+static void Disaster7_Init(void)
+{
+ int index = GB(Random(), 0, 4);
+ uint m;
+
+ for (m = 0; m < 15; m++) {
+ const Industry* i;
+
+ FOR_ALL_INDUSTRIES(i) {
+ if (i->type == IT_COAL_MINE && --index < 0) {
+ SetDParam(0, i->town->index);
+ AddNewsItem(STR_B005_COAL_MINE_SUBSIDENCE_LEAVES,
+ NEWS_FLAGS(NM_THIN,NF_VIEWPORT|NF_TILE,NT_ACCIDENT,0), i->xy + TileDiffXY(1, 1), 0);
+
+ {
+ TileIndex tile = i->xy;
+ TileIndexDiff step = TileOffsByDiagDir(GB(Random(), 0, 2));
+ uint n;
+
+ for (n = 0; n < 30; n++) {
+ DisasterClearSquare(tile);
+ tile = TILE_MASK(tile + step);
+ }
+ }
+ return;
+ }
+ }
+ }
+}
+
+static DisasterInitProc * const _disaster_initprocs[] = {
+ Disaster0_Init,
+ Disaster1_Init,
+ Disaster2_Init,
+ Disaster3_Init,
+ Disaster4_Init,
+ Disaster5_Init,
+ Disaster6_Init,
+ Disaster7_Init,
+};
+
+static const struct {
+ Year min;
+ Year max;
+} _dis_years[] = {
+ { 1930, 1955 },
+ { 1940, 1970 },
+ { 1960, 1990 },
+ { 1970, 2000 },
+ { 2000, 2100 },
+ { 1940, 1965 },
+ { 1975, 2010 },
+ { 1950, 1985 }
+};
+
+
+static void DoDisaster(void)
+{
+ byte buf[lengthof(_dis_years)];
+ uint i;
+ uint j;
+
+ j = 0;
+ for (i = 0; i != lengthof(_dis_years); i++) {
+ if (_cur_year >= _dis_years[i].min && _cur_year < _dis_years[i].max) buf[j++] = i;
+ }
+
+ if (j == 0) return;
+
+ _disaster_initprocs[buf[RandomRange(j)]]();
+}
+
+
+static void ResetDisasterDelay(void)
+{
+ _disaster_delay = GB(Random(), 0, 9) + 730;
+}
+
+void DisasterDailyLoop(void)
+{
+ if (--_disaster_delay != 0) return;
+
+ ResetDisasterDelay();
+
+ if (_opt.diff.disasters != 0) DoDisaster();
+}
+
+void StartupDisasters(void)
+{
+ ResetDisasterDelay();
+}
diff --git a/src/dock_gui.c b/src/dock_gui.c
new file mode 100644
index 000000000..8e550e9ec
--- /dev/null
+++ b/src/dock_gui.c
@@ -0,0 +1,378 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "table/sprites.h"
+#include "table/strings.h"
+#include "functions.h"
+#include "map.h"
+#include "window.h"
+#include "station.h"
+#include "gui.h"
+#include "viewport.h"
+#include "gfx.h"
+#include "sound.h"
+#include "command.h"
+#include "variables.h"
+
+static void ShowBuildDockStationPicker(void);
+static void ShowBuildDocksDepotPicker(void);
+
+static Axis _ship_depot_direction;
+
+void CcBuildDocks(bool success, TileIndex tile, uint32 p1, uint32 p2)
+{
+ if (success) {
+ SndPlayTileFx(SND_02_SPLAT, tile);
+ ResetObjectToPlace();
+ }
+}
+
+void CcBuildCanal(bool success, TileIndex tile, uint32 p1, uint32 p2)
+{
+ if (success) SndPlayTileFx(SND_02_SPLAT, tile);
+}
+
+
+static void PlaceDocks_Dock(TileIndex tile)
+{
+ DoCommandP(tile, 0, 0, CcBuildDocks, CMD_BUILD_DOCK | CMD_AUTO | CMD_MSG(STR_9802_CAN_T_BUILD_DOCK_HERE));
+}
+
+static void PlaceDocks_Depot(TileIndex tile)
+{
+ DoCommandP(tile, _ship_depot_direction, 0, CcBuildDocks, CMD_BUILD_SHIP_DEPOT | CMD_AUTO | CMD_MSG(STR_3802_CAN_T_BUILD_SHIP_DEPOT));
+}
+
+static void PlaceDocks_Buoy(TileIndex tile)
+{
+ DoCommandP(tile, 0, 0, CcBuildDocks, CMD_BUILD_BUOY | CMD_AUTO | CMD_MSG(STR_9835_CAN_T_POSITION_BUOY_HERE));
+}
+
+static void PlaceDocks_DemolishArea(TileIndex tile)
+{
+ VpStartPlaceSizing(tile, VPM_X_AND_Y | GUI_PlaceProc_DemolishArea);
+}
+
+static void PlaceDocks_BuildCanal(TileIndex tile)
+{
+ VpStartPlaceSizing(tile, VPM_X_OR_Y);
+}
+
+static void PlaceDocks_BuildLock(TileIndex tile)
+{
+ DoCommandP(tile, 0, 0, CcBuildDocks, CMD_BUILD_LOCK | CMD_AUTO | CMD_MSG(STR_CANT_BUILD_LOCKS));
+}
+
+
+enum {
+ DTW_CANAL = 3,
+ DTW_LOCK = 4,
+ DTW_DEMOLISH = 6,
+ DTW_DEPOT = 7,
+ DTW_STATION = 8,
+ DTW_BUOY = 9
+};
+
+
+static void BuildDocksClick_Canal(Window *w)
+{
+ HandlePlacePushButton(w, DTW_CANAL, SPR_CURSOR_CANAL, 1, PlaceDocks_BuildCanal);
+}
+
+static void BuildDocksClick_Lock(Window *w)
+{
+ HandlePlacePushButton(w, DTW_LOCK, SPR_CURSOR_LOCK, 1, PlaceDocks_BuildLock);
+}
+
+static void BuildDocksClick_Demolish(Window *w)
+{
+ HandlePlacePushButton(w, DTW_DEMOLISH, ANIMCURSOR_DEMOLISH, 1, PlaceDocks_DemolishArea);
+}
+
+static void BuildDocksClick_Depot(Window *w)
+{
+ if (HandlePlacePushButton(w, DTW_DEPOT, SPR_CURSOR_SHIP_DEPOT, 1, PlaceDocks_Depot)) ShowBuildDocksDepotPicker();
+}
+
+static void BuildDocksClick_Dock(Window *w)
+{
+ if (HandlePlacePushButton(w, DTW_STATION, SPR_CURSOR_DOCK, 3, PlaceDocks_Dock)) ShowBuildDockStationPicker();
+}
+
+static void BuildDocksClick_Buoy(Window *w)
+{
+ HandlePlacePushButton(w, DTW_BUOY, SPR_CURSOR_BOUY, 1, PlaceDocks_Buoy);
+}
+
+static void BuildDocksClick_Landscaping(Window *w)
+{
+ ShowTerraformToolbar();
+}
+
+typedef void OnButtonClick(Window *w);
+static OnButtonClick * const _build_docks_button_proc[] = {
+ BuildDocksClick_Canal,
+ BuildDocksClick_Lock,
+ NULL,
+ BuildDocksClick_Demolish,
+ BuildDocksClick_Depot,
+ BuildDocksClick_Dock,
+ BuildDocksClick_Buoy,
+ BuildDocksClick_Landscaping,
+};
+
+static void BuildDocksToolbWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT:
+ DrawWindowWidgets(w);
+ break;
+
+ case WE_CLICK:
+ if (e->we.click.widget - 3 >= 0 && e->we.click.widget != 5) _build_docks_button_proc[e->we.click.widget - 3](w);
+ break;
+
+ case WE_KEYPRESS:
+ switch (e->we.keypress.keycode) {
+ case '1': BuildDocksClick_Canal(w); break;
+ case '2': BuildDocksClick_Lock(w); break;
+ case '3': BuildDocksClick_Demolish(w); break;
+ case '4': BuildDocksClick_Depot(w); break;
+ case '5': BuildDocksClick_Dock(w); break;
+ case '6': BuildDocksClick_Buoy(w); break;
+ case 'l': BuildDocksClick_Landscaping(w); break;
+ default: return;
+ }
+ break;
+
+ case WE_PLACE_OBJ:
+ _place_proc(e->we.place.tile);
+ break;
+
+ case WE_PLACE_DRAG: {
+ VpSelectTilesWithMethod(e->we.place.pt.x, e->we.place.pt.y, e->we.place.userdata);
+ return;
+ }
+
+ case WE_PLACE_MOUSEUP:
+ if (e->we.place.pt.x != -1) {
+ if ((e->we.place.userdata & 0xF) == VPM_X_AND_Y) { // dragged actions
+ GUIPlaceProcDragXY(e);
+ } else if (e->we.place.userdata == VPM_X_OR_Y) {
+ DoCommandP(e->we.place.tile, e->we.place.starttile, _ctrl_pressed, CcBuildCanal, CMD_BUILD_CANAL | CMD_AUTO | CMD_MSG(STR_CANT_BUILD_CANALS));
+ }
+ }
+ break;
+
+ case WE_ABORT_PLACE_OBJ:
+ RaiseWindowButtons(w);
+
+ w = FindWindowById(WC_BUILD_STATION, 0);
+ if (w != NULL) WP(w,def_d).close = true;
+
+ w = FindWindowById(WC_BUILD_DEPOT, 0);
+ if (w != NULL) WP(w,def_d).close = true;
+ break;
+
+ case WE_PLACE_PRESIZE: {
+ TileIndex tile_from;
+ TileIndex tile_to;
+
+ tile_from = tile_to = e->we.place.tile;
+ switch (GetTileSlope(tile_from, NULL)) {
+ case SLOPE_SW: tile_to += TileDiffXY(-1, 0); break;
+ case SLOPE_SE: tile_to += TileDiffXY( 0, -1); break;
+ case SLOPE_NW: tile_to += TileDiffXY( 0, 1); break;
+ case SLOPE_NE: tile_to += TileDiffXY( 1, 0); break;
+ default: break;
+ }
+ VpSetPresizeRange(tile_from, tile_to);
+ } break;
+
+ case WE_DESTROY:
+ if (_patches.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0);
+ break;
+ }
+}
+
+static const Widget _build_docks_toolb_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 145, 0, 13, STR_9801_DOCK_CONSTRUCTION, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_STICKYBOX, RESIZE_NONE, 7, 146, 157, 0, 13, 0x0, STR_STICKY_BUTTON},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 0, 21, 14, 35, SPR_IMG_BUILD_CANAL, STR_BUILD_CANALS_TIP},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 22, 43, 14, 35, SPR_IMG_BUILD_LOCK, STR_BUILD_LOCKS_TIP},
+
+{ WWT_PANEL, RESIZE_NONE, 7, 44, 47, 14, 35, 0x0, STR_NULL},
+
+{ WWT_IMGBTN, RESIZE_NONE, 7, 48, 69, 14, 35, SPR_IMG_DYNAMITE, STR_018D_DEMOLISH_BUILDINGS_ETC},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 70, 91, 14, 35, SPR_IMG_SHIP_DEPOT, STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 92, 113, 14, 35, SPR_IMG_SHIP_DOCK, STR_981D_BUILD_SHIP_DOCK},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 114, 135, 14, 35, SPR_IMG_BOUY, STR_9834_POSITION_BUOY_WHICH_CAN},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 136, 157, 14, 35, SPR_IMG_LANDSCAPING, STR_LANDSCAPING_TOOLBAR_TIP},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _build_docks_toolbar_desc = {
+ WDP_ALIGN_TBR, 22, 158, 36,
+ WC_BUILD_TOOLBAR, 0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON,
+ _build_docks_toolb_widgets,
+ BuildDocksToolbWndProc
+};
+
+void ShowBuildDocksToolbar(void)
+{
+ if (!IsValidPlayer(_current_player)) return;
+
+ DeleteWindowById(WC_BUILD_TOOLBAR, 0);
+ AllocateWindowDesc(&_build_docks_toolbar_desc);
+ if (_patches.link_terraform_toolbar) ShowTerraformToolbar();
+}
+
+static void BuildDockStationWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_CREATE: LowerWindowWidget(w, _station_show_coverage + 3); break;
+
+ case WE_PAINT: {
+ int rad;
+
+ if (WP(w,def_d).close) return;
+ DrawWindowWidgets(w);
+
+ rad = (_patches.modified_catchment) ? CA_DOCK : 4;
+
+ if (_station_show_coverage) SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
+
+ DrawStationCoverageAreaText(4, 50, (uint)-1, rad);
+ break;
+ }
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 3:
+ case 4:
+ RaiseWindowWidget(w, _station_show_coverage + 3);
+ _station_show_coverage = e->we.click.widget - 3;
+ LowerWindowWidget(w, _station_show_coverage + 3);
+ SndPlayFx(SND_15_BEEP);
+ SetWindowDirty(w);
+ break;
+ }
+ break;
+
+ case WE_MOUSELOOP:
+ if (WP(w,def_d).close) {
+ DeleteWindow(w);
+ return;
+ }
+
+ CheckRedrawStationCoverage(w);
+ break;
+
+ case WE_DESTROY:
+ if (!WP(w,def_d).close) ResetObjectToPlace();
+ break;
+ }
+}
+
+static const Widget _build_dock_station_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 147, 0, 13, STR_3068_DOCK, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 147, 14, 74, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 14, 73, 30, 40, STR_02DB_OFF, STR_3065_DON_T_HIGHLIGHT_COVERAGE},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 74, 133, 30, 40, STR_02DA_ON, STR_3064_HIGHLIGHT_COVERAGE_AREA},
+{ WWT_LABEL, RESIZE_NONE, 7, 0, 147, 17, 30, STR_3066_COVERAGE_AREA_HIGHLIGHT, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _build_dock_station_desc = {
+ WDP_AUTO, WDP_AUTO, 148, 75,
+ WC_BUILD_STATION, WC_BUILD_TOOLBAR,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _build_dock_station_widgets,
+ BuildDockStationWndProc
+};
+
+static void ShowBuildDockStationPicker(void)
+{
+ AllocateWindowDesc(&_build_dock_station_desc);
+}
+
+static void UpdateDocksDirection(void)
+{
+ if (_ship_depot_direction != AXIS_X) {
+ SetTileSelectSize(1, 2);
+ } else {
+ SetTileSelectSize(2, 1);
+ }
+}
+
+static void BuildDocksDepotWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_CREATE: LowerWindowWidget(w, _ship_depot_direction + 3); break;
+
+ case WE_PAINT:
+ DrawWindowWidgets(w);
+
+ DrawShipDepotSprite(67, 35, 0);
+ DrawShipDepotSprite(35, 51, 1);
+ DrawShipDepotSprite(135, 35, 2);
+ DrawShipDepotSprite(167, 51, 3);
+ return;
+
+ case WE_CLICK: {
+ switch (e->we.click.widget) {
+ case 3:
+ case 4:
+ RaiseWindowWidget(w, _ship_depot_direction + 3);
+ _ship_depot_direction = e->we.click.widget - 3;
+ LowerWindowWidget(w, _ship_depot_direction + 3);
+ SndPlayFx(SND_15_BEEP);
+ UpdateDocksDirection();
+ SetWindowDirty(w);
+ break;
+ }
+ } break;
+
+ case WE_MOUSELOOP:
+ if (WP(w,def_d).close) DeleteWindow(w);
+ break;
+
+ case WE_DESTROY:
+ if (!WP(w,def_d).close) ResetObjectToPlace();
+ break;
+ }
+}
+
+static const Widget _build_docks_depot_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 203, 0, 13, STR_3800_SHIP_DEPOT_ORIENTATION, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 203, 14, 85, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 14, 3, 100, 17, 82, 0x0, STR_3803_SELECT_SHIP_DEPOT_ORIENTATION},
+{ WWT_PANEL, RESIZE_NONE, 14, 103, 200, 17, 82, 0x0, STR_3803_SELECT_SHIP_DEPOT_ORIENTATION},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _build_docks_depot_desc = {
+ WDP_AUTO, WDP_AUTO, 204, 86,
+ WC_BUILD_DEPOT, WC_BUILD_TOOLBAR,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _build_docks_depot_widgets,
+ BuildDocksDepotWndProc
+};
+
+
+static void ShowBuildDocksDepotPicker(void)
+{
+ AllocateWindowDesc(&_build_docks_depot_desc);
+ UpdateDocksDirection();
+}
+
+
+void InitializeDockGui(void)
+{
+ _ship_depot_direction = AXIS_X;
+}
diff --git a/src/driver.c b/src/driver.c
new file mode 100644
index 000000000..d8f4f1f15
--- /dev/null
+++ b/src/driver.c
@@ -0,0 +1,221 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "debug.h"
+#include "driver.h"
+#include "functions.h"
+#include "hal.h"
+#include "string.h"
+
+#include "music/bemidi.h"
+#include "music/dmusic.h"
+#include "music/extmidi.h"
+#include "music/null_m.h"
+#include "music/os2_m.h"
+#include "music/win32_m.h"
+#include "music/qtmidi.h"
+
+#include "sound/null_s.h"
+#include "sound/sdl_s.h"
+#include "sound/cocoa_s.h"
+#include "sound/win32_s.h"
+
+#include "video/dedicated_v.h"
+#include "video/null_v.h"
+#include "video/sdl_v.h"
+#include "video/cocoa_v.h"
+#include "video/win32_v.h"
+
+typedef struct DriverDesc {
+ const char* name;
+ const char* longname;
+ const HalCommonDriver* drv;
+} DriverDesc;
+
+typedef struct DriverClass {
+ const DriverDesc *descs;
+ const char *name;
+ const HalCommonDriver** drv;
+} DriverClass;
+
+
+#define M(x, y, z) { x, y, (const HalCommonDriver *)(void *)z }
+static const DriverDesc _music_driver_descs[] = {
+#ifdef __BEOS__
+ M("bemidi", "BeOS MIDI Driver", &_bemidi_music_driver),
+#endif
+#if defined(__OS2__) && !defined(__INNOTEK_LIBC__)
+ M("os2", "OS/2 Music Driver", &_os2_music_driver),
+#endif
+#ifdef WIN32_ENABLE_DIRECTMUSIC_SUPPORT
+ M("dmusic", "DirectMusic MIDI Driver", &_dmusic_midi_driver),
+#endif
+#ifdef WIN32
+ M("win32", "Win32 MIDI Driver", &_win32_music_driver),
+#endif
+#if defined(__APPLE__) && !defined(DEDICATED)
+ M("qt", "QuickTime MIDI Driver", &_qtime_music_driver),
+#endif
+#ifdef UNIX
+#if !defined(__MORPHOS__) && !defined(__AMIGA__)
+ M("extmidi", "External MIDI Driver", &_extmidi_music_driver),
+#endif
+#endif
+ M("null", "Null Music Driver", &_null_music_driver),
+ M(NULL, NULL, NULL)
+};
+
+static const DriverDesc _sound_driver_descs[] = {
+#ifdef WIN32
+ M("win32", "Win32 WaveOut Driver", &_win32_sound_driver),
+#endif
+#ifdef WITH_SDL
+ M("sdl", "SDL Sound Driver", &_sdl_sound_driver),
+#endif
+#ifdef WITH_COCOA
+ M("cocoa", "Cocoa Sound Driver", &_cocoa_sound_driver),
+#endif
+ M("null", "Null Sound Driver", &_null_sound_driver),
+ M(NULL, NULL, NULL)
+};
+
+static const DriverDesc _video_driver_descs[] = {
+#ifdef WIN32
+ M("win32", "Win32 GDI Video Driver", &_win32_video_driver),
+#endif
+#ifdef WITH_SDL
+ M("sdl", "SDL Video Driver", &_sdl_video_driver),
+#endif
+#ifdef WITH_COCOA
+ M("cocoa", "Cocoa Video Driver", &_cocoa_video_driver),
+#endif
+ M("null", "Null Video Driver", &_null_video_driver),
+#ifdef ENABLE_NETWORK
+ M("dedicated", "Dedicated Video Driver", &_dedicated_video_driver),
+#endif
+ M(NULL, NULL, NULL)
+};
+#undef M
+
+
+#define M(x, y, z) { x, y, (const HalCommonDriver **)(void *)z }
+static const DriverClass _driver_classes[] = {
+ M(_video_driver_descs, "video", &_video_driver),
+ M(_sound_driver_descs, "sound", &_sound_driver),
+ M(_music_driver_descs, "music", &_music_driver)
+};
+#undef M
+
+static const DriverDesc* GetDriverByName(const DriverDesc* dd, const char* name)
+{
+ for (; dd->name != NULL; dd++) {
+ if (strcmp(dd->name, name) == 0) return dd;
+ }
+ return NULL;
+}
+
+void LoadDriver(int driver, const char *name)
+{
+ const DriverClass *dc = &_driver_classes[driver];
+ const DriverDesc *dd;
+ const char *err;
+
+ if (*name == '\0') {
+ for (dd = dc->descs; dd->name != NULL; dd++) {
+ err = dd->drv->start(NULL);
+ if (err == NULL) break;
+ DEBUG(driver, 1, "Probing %s driver '%s' failed with error: %s",
+ dc->name, dd->name, err
+ );
+ }
+ if (dd->name == NULL) error("Couldn't find any suitable %s driver", dc->name);
+
+ DEBUG(driver, 1, "Successfully probed %s driver '%s'", dc->name, dd->name);
+
+ *dc->drv = dd->drv;
+ } else {
+ char* parm;
+ char buffer[256];
+ const char* parms[32];
+
+ // Extract the driver name and put parameter list in parm
+ ttd_strlcpy(buffer, name, sizeof(buffer));
+ parm = strchr(buffer, ':');
+ parms[0] = NULL;
+ if (parm != NULL) {
+ uint np = 0;
+ // Tokenize the parm.
+ do {
+ *parm++ = '\0';
+ if (np < lengthof(parms) - 1)
+ parms[np++] = parm;
+ while (*parm != '\0' && *parm != ',')
+ parm++;
+ } while (*parm == ',');
+ parms[np] = NULL;
+ }
+ dd = GetDriverByName(dc->descs, buffer);
+ if (dd == NULL)
+ error("No such %s driver: %s\n", dc->name, buffer);
+
+ if (*dc->drv != NULL) (*dc->drv)->stop();
+ *dc->drv = NULL;
+
+ err = dd->drv->start(parms);
+ if (err != NULL) {
+ error("Unable to load driver %s(%s). The error was: %s\n",
+ dd->name, dd->longname, err
+ );
+ }
+ *dc->drv = dd->drv;
+ }
+}
+
+
+static const char* GetDriverParam(const char* const* parm, const char* name)
+{
+ size_t len;
+
+ if (parm == NULL) return NULL;
+
+ len = strlen(name);
+ for (; *parm != NULL; parm++) {
+ const char* p = *parm;
+
+ if (strncmp(p, name, len) == 0) {
+ if (p[len] == '=') return p + len + 1;
+ if (p[len] == '\0') return p + len;
+ }
+ }
+ return NULL;
+}
+
+bool GetDriverParamBool(const char* const* parm, const char* name)
+{
+ return GetDriverParam(parm, name) != NULL;
+}
+
+int GetDriverParamInt(const char* const* parm, const char* name, int def)
+{
+ const char* p = GetDriverParam(parm, name);
+ return p != NULL ? atoi(p) : def;
+}
+
+
+char *GetDriverList(char* p, const char *last)
+{
+ const DriverClass* dc;
+
+ for (dc = _driver_classes; dc != endof(_driver_classes); dc++) {
+ const DriverDesc* dd;
+
+ p += snprintf(p, last - p, "List of %s drivers:\n", dc->name);
+ for (dd = dc->descs; dd->name != NULL; dd++) {
+ p += snprintf(p, last - p, "%10s: %s\n", dd->name, dd->longname);
+ }
+ p = strecpy(p, "\n", last);
+ }
+
+ return p;
+}
diff --git a/src/driver.h b/src/driver.h
new file mode 100644
index 000000000..4e25714f7
--- /dev/null
+++ b/src/driver.h
@@ -0,0 +1,13 @@
+/* $Id$ */
+
+#ifndef DRIVER_H
+#define DRIVER_H
+
+void LoadDriver(int driver, const char *name);
+
+bool GetDriverParamBool(const char* const* parm, const char* name);
+int GetDriverParamInt(const char* const* parm, const char* name, int def);
+
+char *GetDriverList(char *p, const char *last);
+
+#endif /* DRIVER_H */
diff --git a/src/dummy_land.c b/src/dummy_land.c
new file mode 100644
index 000000000..10952fc00
--- /dev/null
+++ b/src/dummy_land.c
@@ -0,0 +1,83 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "table/strings.h"
+#include "functions.h"
+#include "viewport.h"
+#include "command.h"
+#include "table/sprites.h"
+
+static void DrawTile_Dummy(TileInfo *ti)
+{
+ DrawGroundSpriteAt(SPR_SHADOW_CELL, ti->x, ti->y, ti->z);
+}
+
+
+static uint GetSlopeZ_Dummy(TileIndex tile, uint x, uint y)
+{
+ return 0;
+}
+
+static Slope GetSlopeTileh_Dummy(TileIndex tile, Slope tileh)
+{
+ return SLOPE_FLAT;
+}
+
+static int32 ClearTile_Dummy(TileIndex tile, byte flags)
+{
+ return_cmd_error(STR_0001_OFF_EDGE_OF_MAP);
+}
+
+
+static void GetAcceptedCargo_Dummy(TileIndex tile, AcceptedCargo ac)
+{
+ /* not used */
+}
+
+static void GetTileDesc_Dummy(TileIndex tile, TileDesc *td)
+{
+ td->str = STR_EMPTY;
+ td->owner = OWNER_NONE;
+}
+
+static void AnimateTile_Dummy(TileIndex tile)
+{
+ /* not used */
+}
+
+static void TileLoop_Dummy(TileIndex tile)
+{
+ /* not used */
+}
+
+static void ClickTile_Dummy(TileIndex tile)
+{
+ /* not used */
+}
+
+static void ChangeTileOwner_Dummy(TileIndex tile, PlayerID old_player, PlayerID new_player)
+{
+ /* not used */
+}
+
+static uint32 GetTileTrackStatus_Dummy(TileIndex tile, TransportType mode)
+{
+ return 0;
+}
+
+const TileTypeProcs _tile_type_dummy_procs = {
+ DrawTile_Dummy, /* draw_tile_proc */
+ GetSlopeZ_Dummy, /* get_slope_z_proc */
+ ClearTile_Dummy, /* clear_tile_proc */
+ GetAcceptedCargo_Dummy, /* get_accepted_cargo_proc */
+ GetTileDesc_Dummy, /* get_tile_desc_proc */
+ GetTileTrackStatus_Dummy, /* get_tile_track_status_proc */
+ ClickTile_Dummy, /* click_tile_proc */
+ AnimateTile_Dummy, /* animate_tile_proc */
+ TileLoop_Dummy, /* tile_loop_clear */
+ ChangeTileOwner_Dummy, /* change_tile_owner_clear */
+ NULL, /* get_produced_cargo_proc */
+ NULL, /* vehicle_enter_tile_proc */
+ GetSlopeTileh_Dummy, /* get_slope_tileh_proc */
+};
diff --git a/src/economy.c b/src/economy.c
new file mode 100644
index 000000000..bcd3ac552
--- /dev/null
+++ b/src/economy.c
@@ -0,0 +1,1738 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "currency.h"
+#include "functions.h"
+#include "strings.h" // XXX InjectDParam()
+#include "table/strings.h"
+#include "table/sprites.h"
+#include "map.h"
+#include "news.h"
+#include "player.h"
+#include "station.h"
+#include "vehicle.h"
+#include "window.h"
+#include "gfx.h"
+#include "command.h"
+#include "saveload.h"
+#include "economy.h"
+#include "industry.h"
+#include "town.h"
+#include "network/network.h"
+#include "sound.h"
+#include "engine.h"
+#include "network/network_data.h"
+#include "variables.h"
+#include "vehicle_gui.h"
+#include "ai/ai.h"
+#include "train.h"
+#include "newgrf_engine.h"
+#include "newgrf_sound.h"
+#include "newgrf_callbacks.h"
+#include "unmovable.h"
+#include "date.h"
+
+// Score info
+const ScoreInfo _score_info[] = {
+ { SCORE_VEHICLES, 120, 100 },
+ { SCORE_STATIONS, 80, 100 },
+ { SCORE_MIN_PROFIT, 10000, 100 },
+ { SCORE_MIN_INCOME, 50000, 50 },
+ { SCORE_MAX_INCOME, 100000, 100 },
+ { SCORE_DELIVERED, 40000, 400 },
+ { SCORE_CARGO, 8, 50 },
+ { SCORE_MONEY, 10000000, 50 },
+ { SCORE_LOAN, 250000, 50 },
+ { SCORE_TOTAL, 0, 0 }
+};
+
+int _score_part[MAX_PLAYERS][NUM_SCORE];
+
+int64 CalculateCompanyValue(const Player* p)
+{
+ PlayerID owner = p->index;
+ int64 value;
+
+ {
+ Station *st;
+ uint num = 0;
+
+ FOR_ALL_STATIONS(st) {
+ if (st->owner == owner) {
+ uint facil = st->facilities;
+ do num += (facil&1); while (facil >>= 1);
+ }
+ }
+
+ value = num * _price.station_value * 25;
+ }
+
+ {
+ Vehicle *v;
+
+ FOR_ALL_VEHICLES(v) {
+ if (v->owner != owner) continue;
+
+ if (v->type == VEH_Train ||
+ v->type == VEH_Road ||
+ (v->type == VEH_Aircraft && v->subtype<=2) ||
+ v->type == VEH_Ship) {
+ value += v->value * 3 >> 1;
+ }
+ }
+ }
+
+ value += p->money64 - p->current_loan; // add real money value
+
+ return max64(value, 1);
+}
+
+// if update is set to true, the economy is updated with this score
+// (also the house is updated, should only be true in the on-tick event)
+int UpdateCompanyRatingAndValue(Player *p, bool update)
+{
+ byte owner = p->index;
+ int score = 0;
+
+ memset(_score_part[owner], 0, sizeof(_score_part[owner]));
+
+/* Count vehicles */
+ {
+ Vehicle *v;
+ int32 min_profit = 0;
+ bool min_profit_first = true;
+ uint num = 0;
+
+ FOR_ALL_VEHICLES(v) {
+ if (v->owner != owner) continue;
+ if ((v->type == VEH_Train && IsFrontEngine(v)) ||
+ v->type == VEH_Road ||
+ (v->type == VEH_Aircraft && v->subtype <= 2) ||
+ v->type == VEH_Ship) {
+ num++;
+ if (v->age > 730) {
+ /* Find the vehicle with the lowest amount of profit */
+ if (min_profit_first == true) {
+ min_profit = v->profit_last_year;
+ min_profit_first = false;
+ } else if (min_profit > v->profit_last_year) {
+ min_profit = v->profit_last_year;
+ }
+ }
+ }
+ }
+
+ _score_part[owner][SCORE_VEHICLES] = num;
+ /* Don't allow negative min_profit to show */
+ if (min_profit > 0)
+ _score_part[owner][SCORE_MIN_PROFIT] = min_profit;
+ }
+
+/* Count stations */
+ {
+ uint num = 0;
+ const Station* st;
+
+ FOR_ALL_STATIONS(st) {
+ if (st->owner == owner) {
+ int facil = st->facilities;
+ do num += facil&1; while (facil>>=1);
+ }
+ }
+ _score_part[owner][SCORE_STATIONS] = num;
+ }
+
+/* Generate statistics depending on recent income statistics */
+ {
+ const PlayerEconomyEntry* pee;
+ int numec;
+ int32 min_income;
+ int32 max_income;
+
+ numec = min(p->num_valid_stat_ent, 12);
+ if (numec != 0) {
+ min_income = 0x7FFFFFFF;
+ max_income = 0;
+ pee = p->old_economy;
+ do {
+ min_income = min(min_income, pee->income + pee->expenses);
+ max_income = max(max_income, pee->income + pee->expenses);
+ } while (++pee,--numec);
+
+ if (min_income > 0)
+ _score_part[owner][SCORE_MIN_INCOME] = min_income;
+
+ _score_part[owner][SCORE_MAX_INCOME] = max_income;
+ }
+ }
+
+/* Generate score depending on amount of transported cargo */
+ {
+ const PlayerEconomyEntry* pee;
+ int numec;
+ uint32 total_delivered;
+
+ numec = min(p->num_valid_stat_ent, 4);
+ if (numec != 0) {
+ pee = p->old_economy;
+ total_delivered = 0;
+ do {
+ total_delivered += pee->delivered_cargo;
+ } while (++pee,--numec);
+
+ _score_part[owner][SCORE_DELIVERED] = total_delivered;
+ }
+ }
+
+/* Generate score for variety of cargo */
+ {
+ uint cargo = p->cargo_types;
+ uint num = 0;
+ do num += cargo&1; while (cargo>>=1);
+ _score_part[owner][SCORE_CARGO] = num;
+ if (update) p->cargo_types = 0;
+ }
+
+/* Generate score for player money */
+ {
+ int32 money = p->player_money;
+ if (money > 0) {
+ _score_part[owner][SCORE_MONEY] = money;
+ }
+ }
+
+/* Generate score for loan */
+ {
+ _score_part[owner][SCORE_LOAN] = _score_info[SCORE_LOAN].needed - p->current_loan;
+ }
+
+ // Now we calculate the score for each item..
+ {
+ int i;
+ int total_score = 0;
+ int s;
+ score = 0;
+ for (i = 0; i < NUM_SCORE; i++) {
+ // Skip the total
+ if (i == SCORE_TOTAL) continue;
+ // Check the score
+ s = (_score_part[owner][i] >= _score_info[i].needed) ?
+ _score_info[i].score :
+ _score_part[owner][i] * _score_info[i].score / _score_info[i].needed;
+ if (s < 0) s = 0;
+ score += s;
+ total_score += _score_info[i].score;
+ }
+
+ _score_part[owner][SCORE_TOTAL] = score;
+
+ // We always want the score scaled to SCORE_MAX (1000)
+ if (total_score != SCORE_MAX) score = score * SCORE_MAX / total_score;
+ }
+
+ if (update) {
+ p->old_economy[0].performance_history = score;
+ UpdateCompanyHQ(p, score);
+ p->old_economy[0].company_value = CalculateCompanyValue(p);
+ }
+
+ InvalidateWindow(WC_PERFORMANCE_DETAIL, 0);
+ return score;
+}
+
+// use PLAYER_SPECTATOR as new_player to delete the player.
+void ChangeOwnershipOfPlayerItems(PlayerID old_player, PlayerID new_player)
+{
+ Town *t;
+ PlayerID old = _current_player;
+ _current_player = old_player;
+
+ /* Temporarily increase the player's money, to be sure that
+ * removing his/her property doesn't fail because of lack of money.
+ * Not too drastically though, because it could overflow */
+ if (new_player == PLAYER_SPECTATOR) {
+ GetPlayer(old_player)->money64 = MAX_UVALUE(uint64) >>2; // jackpot ;p
+ UpdatePlayerMoney32(GetPlayer(old_player));
+ }
+
+ if (new_player == PLAYER_SPECTATOR) {
+ Subsidy *s;
+
+ for (s = _subsidies; s != endof(_subsidies); s++) {
+ if (s->cargo_type != CT_INVALID && s->age >= 12) {
+ if (GetStation(s->to)->owner == old_player) s->cargo_type = CT_INVALID;
+ }
+ }
+ }
+
+ /* Take care of rating in towns */
+ FOR_ALL_TOWNS(t) {
+ /* If a player takes over, give the ratings to that player. */
+ if (new_player != PLAYER_SPECTATOR) {
+ if (HASBIT(t->have_ratings, old_player)) {
+ if (HASBIT(t->have_ratings, new_player)) {
+ // use max of the two ratings.
+ t->ratings[new_player] = max(t->ratings[new_player], t->ratings[old_player]);
+ } else {
+ SETBIT(t->have_ratings, new_player);
+ t->ratings[new_player] = t->ratings[old_player];
+ }
+ }
+ }
+
+ /* Reset the ratings for the old player */
+ t->ratings[old_player] = 500;
+ CLRBIT(t->have_ratings, old_player);
+ }
+
+ {
+ int num_train = 0;
+ int num_road = 0;
+ int num_ship = 0;
+ int num_aircraft = 0;
+ Vehicle *v;
+
+ // Determine Ids for the new vehicles
+ FOR_ALL_VEHICLES(v) {
+ if (v->owner == new_player) {
+ switch (v->type) {
+ case VEH_Train: if (IsFrontEngine(v)) num_train++; break;
+ case VEH_Road: num_road++; break;
+ case VEH_Ship: num_ship++; break;
+ case VEH_Aircraft: if (v->subtype <= 2) num_aircraft++; break;
+ default: break;
+ }
+ }
+ }
+
+ FOR_ALL_VEHICLES(v) {
+ if (v->owner == old_player && IS_BYTE_INSIDE(v->type, VEH_Train, VEH_Aircraft + 1)) {
+ if (new_player == PLAYER_SPECTATOR) {
+ DeleteWindowById(WC_VEHICLE_VIEW, v->index);
+ DeleteWindowById(WC_VEHICLE_DETAILS, v->index);
+ DeleteWindowById(WC_VEHICLE_ORDERS, v->index);
+ DeleteVehicle(v);
+ } else {
+ v->owner = new_player;
+ if (IsEngineCountable(v)) GetPlayer(new_player)->num_engines[v->engine_type]++;
+ switch (v->type) {
+ case VEH_Train: if (IsFrontEngine(v)) v->unitnumber = ++num_train; break;
+ case VEH_Road: v->unitnumber = ++num_road; break;
+ case VEH_Ship: v->unitnumber = ++num_ship; break;
+ case VEH_Aircraft: if (v->subtype <= 2) v->unitnumber = ++num_aircraft; break;
+ }
+ }
+ }
+ }
+ }
+
+ // Change ownership of tiles
+ {
+ TileIndex tile = 0;
+ do {
+ ChangeTileOwner(tile, old_player, new_player);
+ } while (++tile != MapSize());
+ }
+
+ /* Change color of existing windows */
+ if (new_player != PLAYER_SPECTATOR) ChangeWindowOwner(old_player, new_player);
+
+ {
+ Player *p;
+ uint i;
+
+ /* Check for shares */
+ FOR_ALL_PLAYERS(p) {
+ for (i = 0; i < 4; i++) {
+ /* 'Sell' the share if this player has any */
+ if (p->share_owners[i] == _current_player) {
+ p->share_owners[i] = PLAYER_SPECTATOR;
+ }
+ }
+ }
+ p = GetPlayer(_current_player);
+ /* Sell all the shares that people have on this company */
+ for (i = 0; i < 4; i++)
+ p->share_owners[i] = PLAYER_SPECTATOR;
+ }
+
+ _current_player = old;
+
+ MarkWholeScreenDirty();
+}
+
+static void PlayersCheckBankrupt(Player *p)
+{
+ PlayerID owner;
+ int64 val;
+
+ // If the player has money again, it does not go bankrupt
+ if (p->player_money >= 0) {
+ p->quarters_of_bankrupcy = 0;
+ return;
+ }
+
+ p->quarters_of_bankrupcy++;
+
+ owner = p->index;
+
+ switch (p->quarters_of_bankrupcy) {
+ case 2:
+ AddNewsItem( (StringID)(owner | NB_BTROUBLE),
+ NEWS_FLAGS(NM_CALLBACK, 0, NT_COMPANY_INFO, DNC_BANKRUPCY),0,0);
+ break;
+ case 3: {
+ /* XXX - In multiplayer, should we ask other players if it wants to take
+ over when it is a human company? -- TrueLight */
+ if (IsHumanPlayer(owner)) {
+ AddNewsItem( (StringID)(owner | NB_BTROUBLE),
+ NEWS_FLAGS(NM_CALLBACK, 0, NT_COMPANY_INFO, DNC_BANKRUPCY),0,0);
+ break;
+ }
+
+ // Check if the company has any value.. if not, declare it bankrupt
+ // right now
+ val = CalculateCompanyValue(p);
+ if (val > 0) {
+ p->bankrupt_value = val;
+ p->bankrupt_asked = 1 << owner; // Don't ask the owner
+ p->bankrupt_timeout = 0;
+ break;
+ }
+ // Else, falltrue to case 4...
+ }
+ case 4: {
+ // Close everything the owner has open
+ DeletePlayerWindows(owner);
+
+// Show bankrupt news
+ SetDParam(0, p->name_1);
+ SetDParam(1, p->name_2);
+ AddNewsItem( (StringID)(owner | NB_BBANKRUPT), NEWS_FLAGS(NM_CALLBACK, 0, NT_COMPANY_INFO, DNC_BANKRUPCY),0,0);
+
+ if (IsHumanPlayer(owner)) {
+ /* XXX - If we are in offline mode, leave the player playing. Eg. there
+ * is no THE-END, otherwise mark the player as spectator to make sure
+ * he/she is no long in control of this company */
+ if (!_networking) {
+ p->bankrupt_asked = 0xFF;
+ p->bankrupt_timeout = 0x456;
+ break;
+ } else if (owner == _local_player) {
+ _network_playas = PLAYER_SPECTATOR;
+ SetLocalPlayer(PLAYER_SPECTATOR);
+ }
+
+#ifdef ENABLE_NETWORK
+ /* The server has to handle all administrative issues, for example
+ * updating and notifying all clients of what has happened */
+ if (_network_server) {
+ const NetworkClientState *cs;
+ NetworkClientInfo *ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
+
+ /* The server has just gone belly-up, mark it as spectator */
+ if (owner == ci->client_playas) {
+ ci->client_playas = PLAYER_SPECTATOR;
+ NetworkUpdateClientInfo(NETWORK_SERVER_INDEX);
+ }
+
+ /* Find all clients that were in control of this company,
+ * and mark them as spectator; broadcast this message to everyone */
+ FOR_ALL_CLIENTS(cs) {
+ ci = DEREF_CLIENT_INFO(cs);
+ if (ci->client_playas == owner) {
+ ci->client_playas = PLAYER_SPECTATOR;
+ NetworkUpdateClientInfo(ci->client_index);
+ }
+ }
+ }
+#endif /* ENABLE_NETWORK */
+ }
+
+ /* Remove the player */
+ ChangeOwnershipOfPlayerItems(owner, PLAYER_SPECTATOR);
+ /* Register the player as not-active */
+ p->is_active = false;
+
+ if (!IsHumanPlayer(owner) && (!_networking || _network_server) && _ai.enabled)
+ AI_PlayerDied(owner);
+ }
+ }
+}
+
+void DrawNewsBankrupcy(Window *w)
+{
+ Player *p;
+
+ DrawNewsBorder(w);
+
+ p = GetPlayer(GB(WP(w,news_d).ni->string_id, 0, 4));
+ DrawPlayerFace(p->face, p->player_color, 2, 23);
+ GfxFillRect(3, 23, 3+91, 23+118, 0x323 | USE_COLORTABLE);
+
+ SetDParam(0, p->president_name_1);
+ SetDParam(1, p->president_name_2);
+
+ DrawStringMultiCenter(49, 148, STR_7058_PRESIDENT, 94);
+
+ switch (WP(w,news_d).ni->string_id & 0xF0) {
+ case NB_BTROUBLE:
+ DrawStringCentered(w->width>>1, 1, STR_7056_TRANSPORT_COMPANY_IN_TROUBLE, 0);
+
+ SetDParam(0, p->name_1);
+ SetDParam(1, p->name_2);
+
+ DrawStringMultiCenter(
+ ((w->width - 101) >> 1) + 98,
+ 90,
+ STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED,
+ w->width - 101);
+ break;
+
+ case NB_BMERGER: {
+ int32 price;
+
+ DrawStringCentered(w->width>>1, 1, STR_7059_TRANSPORT_COMPANY_MERGER, 0);
+ COPY_IN_DPARAM(0,WP(w,news_d).ni->params, 2);
+ SetDParam(2, p->name_1);
+ SetDParam(3, p->name_2);
+ price = WP(w,news_d).ni->params[2];
+ SetDParam(4, price);
+ DrawStringMultiCenter(
+ ((w->width - 101) >> 1) + 98,
+ 90,
+ price==0 ? STR_707F_HAS_BEEN_TAKEN_OVER_BY : STR_705A_HAS_BEEN_SOLD_TO_FOR,
+ w->width - 101);
+ break;
+ }
+
+ case NB_BBANKRUPT:
+ DrawStringCentered(w->width>>1, 1, STR_705C_BANKRUPT, 0);
+ COPY_IN_DPARAM(0,WP(w,news_d).ni->params, 2);
+ DrawStringMultiCenter(
+ ((w->width - 101) >> 1) + 98,
+ 90,
+ STR_705D_HAS_BEEN_CLOSED_DOWN_BY,
+ w->width - 101);
+ break;
+
+ case NB_BNEWCOMPANY:
+ DrawStringCentered(w->width>>1, 1, STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED, 0);
+ SetDParam(0, p->name_1);
+ SetDParam(1, p->name_2);
+ COPY_IN_DPARAM(2,WP(w,news_d).ni->params, 2);
+ DrawStringMultiCenter(
+ ((w->width - 101) >> 1) + 98,
+ 90,
+ STR_705F_STARTS_CONSTRUCTION_NEAR,
+ w->width - 101);
+ break;
+
+ default:
+ NOT_REACHED();
+ }
+}
+
+StringID GetNewsStringBankrupcy(const NewsItem *ni)
+{
+ const Player *p = GetPlayer(GB(ni->string_id, 0, 4));
+
+ switch (ni->string_id & 0xF0) {
+ case NB_BTROUBLE:
+ SetDParam(0, STR_7056_TRANSPORT_COMPANY_IN_TROUBLE);
+ SetDParam(1, STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED);
+ SetDParam(2, p->name_1);
+ SetDParam(3, p->name_2);
+ return STR_02B6;
+ case NB_BMERGER:
+ SetDParam(0, STR_7059_TRANSPORT_COMPANY_MERGER);
+ SetDParam(1, STR_705A_HAS_BEEN_SOLD_TO_FOR);
+ COPY_IN_DPARAM(2,ni->params, 2);
+ SetDParam(4, p->name_1);
+ SetDParam(5, p->name_2);
+ COPY_IN_DPARAM(6,ni->params + 2, 1);
+ return STR_02B6;
+ case NB_BBANKRUPT:
+ SetDParam(0, STR_705C_BANKRUPT);
+ SetDParam(1, STR_705D_HAS_BEEN_CLOSED_DOWN_BY);
+ COPY_IN_DPARAM(2,ni->params, 2);
+ return STR_02B6;
+ case NB_BNEWCOMPANY:
+ SetDParam(0, STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED);
+ SetDParam(1, STR_705F_STARTS_CONSTRUCTION_NEAR);
+ SetDParam(2, p->name_1);
+ SetDParam(3, p->name_2);
+ COPY_IN_DPARAM(4,ni->params, 2);
+ return STR_02B6;
+ default:
+ NOT_REACHED();
+ }
+
+ /* useless, but avoids compiler warning this way */
+ return 0;
+}
+
+static void PlayersGenStatistics(void)
+{
+ Station *st;
+ Player *p;
+
+ FOR_ALL_STATIONS(st) {
+ _current_player = st->owner;
+ SET_EXPENSES_TYPE(EXPENSES_PROPERTY);
+ SubtractMoneyFromPlayer(_price.station_value >> 1);
+ }
+
+ if (!HASBIT(1<<0|1<<3|1<<6|1<<9, _cur_month))
+ return;
+
+ FOR_ALL_PLAYERS(p) {
+ if (p->is_active) {
+ memmove(&p->old_economy[1], &p->old_economy[0], sizeof(p->old_economy) - sizeof(p->old_economy[0]));
+ p->old_economy[0] = p->cur_economy;
+ memset(&p->cur_economy, 0, sizeof(p->cur_economy));
+
+ if (p->num_valid_stat_ent != 24) p->num_valid_stat_ent++;
+
+ UpdateCompanyRatingAndValue(p, true);
+ PlayersCheckBankrupt(p);
+
+ if (p->block_preview != 0) p->block_preview--;
+ }
+ }
+
+ InvalidateWindow(WC_INCOME_GRAPH, 0);
+ InvalidateWindow(WC_OPERATING_PROFIT, 0);
+ InvalidateWindow(WC_DELIVERED_CARGO, 0);
+ InvalidateWindow(WC_PERFORMANCE_HISTORY, 0);
+ InvalidateWindow(WC_COMPANY_VALUE, 0);
+ InvalidateWindow(WC_COMPANY_LEAGUE, 0);
+}
+
+static void AddSingleInflation(int32 *value, uint16 *frac, int32 amt)
+{
+ int64 tmp;
+ int32 low;
+ tmp = BIGMULS(*value, amt);
+ *frac = (uint16)(low = (uint16)tmp + *frac);
+ *value += (int32)(tmp >> 16) + (low >> 16);
+}
+
+static void AddInflation(void)
+{
+ int i;
+ int32 inf = _economy.infl_amount * 54;
+
+ for (i = 0; i != NUM_PRICES; i++) {
+ AddSingleInflation((int32*)&_price + i, _price_frac + i, inf);
+ }
+
+ _economy.max_loan_unround += BIGMULUS(_economy.max_loan_unround, inf, 16);
+
+ if (_economy.max_loan + 50000 <= _economy.max_loan_unround)
+ _economy.max_loan += 50000;
+
+ inf = _economy.infl_amount_pr * 54;
+ for (i = 0; i != NUM_CARGO; i++) {
+ AddSingleInflation(
+ (int32*)_cargo_payment_rates + i,
+ _cargo_payment_rates_frac + i,
+ inf
+ );
+ }
+
+ InvalidateWindowClasses(WC_BUILD_VEHICLE);
+ InvalidateWindowClasses(WC_REPLACE_VEHICLE);
+ InvalidateWindowClasses(WC_VEHICLE_DETAILS);
+ InvalidateWindow(WC_PAYMENT_RATES, 0);
+}
+
+static void PlayersPayInterest(void)
+{
+ const Player* p;
+ int interest = _economy.interest_rate * 54;
+
+ FOR_ALL_PLAYERS(p) {
+ if (!p->is_active) continue;
+
+ _current_player = p->index;
+ SET_EXPENSES_TYPE(EXPENSES_LOAN_INT);
+
+ SubtractMoneyFromPlayer(BIGMULUS(p->current_loan, interest, 16));
+
+ SET_EXPENSES_TYPE(EXPENSES_OTHER);
+ SubtractMoneyFromPlayer(_price.station_value >> 2);
+ }
+}
+
+static void HandleEconomyFluctuations(void)
+{
+ if (_opt.diff.economy == 0) return;
+
+ if (--_economy.fluct == 0) {
+ _economy.fluct = -(int)GB(Random(), 0, 2);
+ AddNewsItem(STR_7073_WORLD_RECESSION_FINANCIAL, NEWS_FLAGS(NM_NORMAL,0,NT_ECONOMY,0), 0, 0);
+ } else if (_economy.fluct == -12) {
+ _economy.fluct = GB(Random(), 0, 8) + 312;
+ AddNewsItem(STR_7074_RECESSION_OVER_UPTURN_IN, NEWS_FLAGS(NM_NORMAL,0,NT_ECONOMY,0), 0, 0);
+ }
+}
+
+static byte _price_category[NUM_PRICES] = {
+ 0, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 1, 1, 1, 1, 1, 1,
+ 2,
+};
+
+static const int32 _price_base[NUM_PRICES] = {
+ 100, // station_value
+ 100, // build_rail
+ 95, // build_road
+ 65, // build_signals
+ 275, // build_bridge
+ 600, // build_train_depot
+ 500, // build_road_depot
+ 700, // build_ship_depot
+ 450, // build_tunnel
+ 200, // train_station_track
+ 180, // train_station_length
+ 600, // build_airport
+ 200, // build_bus_station
+ 200, // build_truck_station
+ 350, // build_dock
+ 400000, // build_railvehicle
+ 2000, // build_railwagon
+ 700000, // aircraft_base
+ 14000, // roadveh_base
+ 65000, // ship_base
+ 20, // build_trees
+ 250, // terraform
+ 20, // clear_1
+ 40, // purchase_land
+ 200, // clear_2
+ 500, // clear_3
+ 20, // remove_trees
+ -70, // remove_rail
+ 10, // remove_signals
+ 50, // clear_bridge
+ 80, // remove_train_depot
+ 80, // remove_road_depot
+ 90, // remove_ship_depot
+ 30, // clear_tunnel
+ 10000, // clear_water
+ 50, // remove_rail_station
+ 30, // remove_airport
+ 50, // remove_bus_station
+ 50, // remove_truck_station
+ 55, // remove_dock
+ 1600, // remove_house
+ 40, // remove_road
+ 5600, // running_rail[0] railroad
+ 5200, // running_rail[1] monorail
+ 4800, // running_rail[2] maglev
+ 9600, // aircraft_running
+ 1600, // roadveh_running
+ 5600, // ship_running
+ 1000000, // build_industry
+};
+
+static byte price_base_multiplier[NUM_PRICES];
+
+/**
+ * Reset changes to the price base multipliers.
+ */
+void ResetPriceBaseMultipliers(void)
+{
+ uint i;
+
+ // 8 means no multiplier.
+ for (i = 0; i < NUM_PRICES; i++)
+ price_base_multiplier[i] = 8;
+}
+
+/**
+ * Change a price base by the given factor.
+ * The price base is altered by factors of two, with an offset of 8.
+ * NewBaseCost = OldBaseCost * 2^(n-8)
+ * @param price Index of price base to change.
+ * @param factor Amount to change by.
+ */
+void SetPriceBaseMultiplier(uint price, byte factor)
+{
+ assert(price < NUM_PRICES);
+ price_base_multiplier[price] = factor;
+}
+
+void StartupEconomy(void)
+{
+ int i;
+
+ assert(sizeof(_price) == NUM_PRICES * sizeof(int32));
+
+ for (i = 0; i != NUM_PRICES; i++) {
+ int32 price = _price_base[i];
+ if (_price_category[i] != 0) {
+ uint mod = _price_category[i] == 1 ? _opt.diff.vehicle_costs : _opt.diff.construction_cost;
+ if (mod < 1) {
+ price = price * 3 >> 2;
+ } else if (mod > 1) {
+ price = price * 9 >> 3;
+ }
+ }
+ if (price_base_multiplier[i] > 8) {
+ price <<= price_base_multiplier[i] - 8;
+ } else {
+ price >>= 8 - price_base_multiplier[i];
+ }
+ ((int32*)&_price)[i] = price;
+ _price_frac[i] = 0;
+ }
+
+ _economy.interest_rate = _opt.diff.initial_interest;
+ _economy.infl_amount = _opt.diff.initial_interest;
+ _economy.infl_amount_pr = max(0, _opt.diff.initial_interest - 1);
+ _economy.max_loan_unround = _economy.max_loan = _opt.diff.max_loan * 1000;
+ _economy.fluct = GB(Random(), 0, 8) + 168;
+}
+
+Pair SetupSubsidyDecodeParam(const Subsidy* s, bool mode)
+{
+ TileIndex tile;
+ TileIndex tile2;
+ Pair tp;
+
+ /* if mode is false, use the singular form */
+ SetDParam(0, _cargoc.names_s[s->cargo_type] + (mode ? 0 : 32));
+
+ if (s->age < 12) {
+ if (s->cargo_type != CT_PASSENGERS && s->cargo_type != CT_MAIL) {
+ SetDParam(1, STR_INDUSTRY);
+ SetDParam(2, s->from);
+ tile = GetIndustry(s->from)->xy;
+
+ if (s->cargo_type != CT_GOODS && s->cargo_type != CT_FOOD) {
+ SetDParam(4, STR_INDUSTRY);
+ SetDParam(5, s->to);
+ tile2 = GetIndustry(s->to)->xy;
+ } else {
+ SetDParam(4, STR_TOWN);
+ SetDParam(5, s->to);
+ tile2 = GetTown(s->to)->xy;
+ }
+ } else {
+ SetDParam(1, STR_TOWN);
+ SetDParam(2, s->from);
+ tile = GetTown(s->from)->xy;
+
+ SetDParam(4, STR_TOWN);
+ SetDParam(5, s->to);
+ tile2 = GetTown(s->to)->xy;
+ }
+ } else {
+ SetDParam(1, s->from);
+ tile = GetStation(s->from)->xy;
+
+ SetDParam(2, s->to);
+ tile2 = GetStation(s->to)->xy;
+ }
+
+ tp.a = tile;
+ tp.b = tile2;
+
+ return tp;
+}
+
+void DeleteSubsidyWithTown(TownID index)
+{
+ Subsidy *s;
+
+ for (s = _subsidies; s != endof(_subsidies); s++) {
+ if (s->cargo_type != CT_INVALID && s->age < 12 &&
+ (((s->cargo_type == CT_PASSENGERS || s->cargo_type == CT_MAIL) && (index == s->from || index == s->to)) ||
+ ((s->cargo_type == CT_GOODS || s->cargo_type == CT_FOOD) && index == s->to))) {
+ s->cargo_type = CT_INVALID;
+ }
+ }
+}
+
+void DeleteSubsidyWithIndustry(IndustryID index)
+{
+ Subsidy *s;
+
+ for (s = _subsidies; s != endof(_subsidies); s++) {
+ if (s->cargo_type != CT_INVALID && s->age < 12 &&
+ s->cargo_type != CT_PASSENGERS && s->cargo_type != CT_MAIL &&
+ (index == s->from || (s->cargo_type != CT_GOODS && s->cargo_type != CT_FOOD && index == s->to))) {
+ s->cargo_type = CT_INVALID;
+ }
+ }
+}
+
+void DeleteSubsidyWithStation(StationID index)
+{
+ Subsidy *s;
+ bool dirty = false;
+
+ for (s = _subsidies; s != endof(_subsidies); s++) {
+ if (s->cargo_type != CT_INVALID && s->age >= 12 &&
+ (s->from == index || s->to == index)) {
+ s->cargo_type = CT_INVALID;
+ dirty = true;
+ }
+ }
+
+ if (dirty)
+ InvalidateWindow(WC_SUBSIDIES_LIST, 0);
+}
+
+typedef struct FoundRoute {
+ uint distance;
+ CargoID cargo;
+ void *from;
+ void *to;
+} FoundRoute;
+
+static void FindSubsidyPassengerRoute(FoundRoute *fr)
+{
+ Town *from,*to;
+
+ fr->distance = (uint)-1;
+
+ fr->from = from = GetRandomTown();
+ if (from == NULL || from->population < 400) return;
+
+ fr->to = to = GetRandomTown();
+ if (from == to || to == NULL || to->population < 400 || to->pct_pass_transported > 42)
+ return;
+
+ fr->distance = DistanceManhattan(from->xy, to->xy);
+}
+
+static void FindSubsidyCargoRoute(FoundRoute *fr)
+{
+ Industry *i;
+ int trans, total;
+ CargoID cargo;
+
+ fr->distance = (uint)-1;
+
+ fr->from = i = GetRandomIndustry();
+ if (i == NULL) return;
+
+ // Randomize cargo type
+ if (Random()&1 && i->produced_cargo[1] != CT_INVALID) {
+ cargo = i->produced_cargo[1];
+ trans = i->pct_transported[1];
+ total = i->total_production[1];
+ } else {
+ cargo = i->produced_cargo[0];
+ trans = i->pct_transported[0];
+ total = i->total_production[0];
+ }
+
+ // Quit if no production in this industry
+ // or if the cargo type is passengers
+ // or if the pct transported is already large enough
+ if (total == 0 || trans > 42 || cargo == CT_INVALID || cargo == CT_PASSENGERS)
+ return;
+
+ fr->cargo = cargo;
+
+ if (cargo == CT_GOODS || cargo == CT_FOOD) {
+ // The destination is a town
+ Town *t = GetRandomTown();
+
+ // Only want big towns
+ if (t == NULL || t->population < 900) return;
+
+ fr->distance = DistanceManhattan(i->xy, t->xy);
+ fr->to = t;
+ } else {
+ // The destination is an industry
+ Industry *i2 = GetRandomIndustry();
+
+ // The industry must accept the cargo
+ if (i == i2 || i == NULL ||
+ (cargo != i2->accepts_cargo[0] &&
+ cargo != i2->accepts_cargo[1] &&
+ cargo != i2->accepts_cargo[2]))
+ return;
+ fr->distance = DistanceManhattan(i->xy, i2->xy);
+ fr->to = i2;
+ }
+}
+
+static bool CheckSubsidyDuplicate(Subsidy *s)
+{
+ const Subsidy* ss;
+
+ for (ss = _subsidies; ss != endof(_subsidies); ss++) {
+ if (s != ss &&
+ ss->from == s->from &&
+ ss->to == s->to &&
+ ss->cargo_type == s->cargo_type) {
+ s->cargo_type = CT_INVALID;
+ return true;
+ }
+ }
+ return false;
+}
+
+
+static void SubsidyMonthlyHandler(void)
+{
+ Subsidy *s;
+ Pair pair;
+ Station *st;
+ uint n;
+ FoundRoute fr;
+ bool modified = false;
+
+ for (s = _subsidies; s != endof(_subsidies); s++) {
+ if (s->cargo_type == CT_INVALID) continue;
+
+ if (s->age == 12-1) {
+ pair = SetupSubsidyDecodeParam(s, 1);
+ AddNewsItem(STR_202E_OFFER_OF_SUBSIDY_EXPIRED, NEWS_FLAGS(NM_NORMAL, NF_TILE, NT_SUBSIDIES, 0), pair.a, pair.b);
+ s->cargo_type = CT_INVALID;
+ modified = true;
+ } else if (s->age == 2*12-1) {
+ st = GetStation(s->to);
+ if (st->owner == _local_player) {
+ pair = SetupSubsidyDecodeParam(s, 1);
+ AddNewsItem(STR_202F_SUBSIDY_WITHDRAWN_SERVICE, NEWS_FLAGS(NM_NORMAL, NF_TILE, NT_SUBSIDIES, 0), pair.a, pair.b);
+ }
+ s->cargo_type = CT_INVALID;
+ modified = true;
+ } else {
+ s->age++;
+ }
+ }
+
+ // 25% chance to go on
+ if (CHANCE16(1,4)) {
+ // Find a free slot
+ s = _subsidies;
+ while (s->cargo_type != CT_INVALID) {
+ if (++s == endof(_subsidies))
+ goto no_add;
+ }
+
+ n = 1000;
+ do {
+ FindSubsidyPassengerRoute(&fr);
+ if (fr.distance <= 70) {
+ s->cargo_type = CT_PASSENGERS;
+ s->from = ((Town*)fr.from)->index;
+ s->to = ((Town*)fr.to)->index;
+ goto add_subsidy;
+ }
+ FindSubsidyCargoRoute(&fr);
+ if (fr.distance <= 70) {
+ s->cargo_type = fr.cargo;
+ s->from = ((Industry*)fr.from)->index;
+ s->to = (fr.cargo == CT_GOODS || fr.cargo == CT_FOOD) ? ((Town*)fr.to)->index : ((Industry*)fr.to)->index;
+ add_subsidy:
+ if (!CheckSubsidyDuplicate(s)) {
+ s->age = 0;
+ pair = SetupSubsidyDecodeParam(s, 0);
+ AddNewsItem(STR_2030_SERVICE_SUBSIDY_OFFERED, NEWS_FLAGS(NM_NORMAL, NF_TILE, NT_SUBSIDIES, 0), pair.a, pair.b);
+ modified = true;
+ break;
+ }
+ }
+ } while (n--);
+ }
+no_add:;
+ if (modified)
+ InvalidateWindow(WC_SUBSIDIES_LIST, 0);
+}
+
+static const SaveLoad _subsidies_desc[] = {
+ SLE_VAR(Subsidy, cargo_type, SLE_UINT8),
+ SLE_VAR(Subsidy, age, SLE_UINT8),
+ SLE_CONDVAR(Subsidy, from, SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
+ SLE_CONDVAR(Subsidy, from, SLE_UINT16, 5, SL_MAX_VERSION),
+ SLE_CONDVAR(Subsidy, to, SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
+ SLE_CONDVAR(Subsidy, to, SLE_UINT16, 5, SL_MAX_VERSION),
+ SLE_END()
+};
+
+static void Save_SUBS(void)
+{
+ int i;
+ Subsidy *s;
+
+ for (i = 0; i != lengthof(_subsidies); i++) {
+ s = &_subsidies[i];
+ if (s->cargo_type != CT_INVALID) {
+ SlSetArrayIndex(i);
+ SlObject(s, _subsidies_desc);
+ }
+ }
+}
+
+static void Load_SUBS(void)
+{
+ int index;
+ while ((index = SlIterateArray()) != -1)
+ SlObject(&_subsidies[index], _subsidies_desc);
+}
+
+int32 GetTransportedGoodsIncome(uint num_pieces, uint dist, byte transit_days, CargoID cargo_type)
+{
+ CargoID cargo = cargo_type;
+ byte f;
+
+ /* zero the distance if it's the bank and very short transport. */
+ if (_opt.landscape == LT_NORMAL && cargo == CT_VALUABLES && dist < 10)
+ dist = 0;
+
+ f = 255;
+ if (transit_days > _cargoc.transit_days_1[cargo]) {
+ transit_days -= _cargoc.transit_days_1[cargo];
+ f -= transit_days;
+
+ if (transit_days > _cargoc.transit_days_2[cargo]) {
+ transit_days -= _cargoc.transit_days_2[cargo];
+
+ if (f < transit_days) {
+ f = 0;
+ } else {
+ f -= transit_days;
+ }
+ }
+ }
+ if (f < 31) f = 31;
+
+ return BIGMULSS(dist * f * num_pieces, _cargo_payment_rates[cargo], 21);
+}
+
+static void DeliverGoodsToIndustry(TileIndex xy, CargoID cargo_type, int num_pieces)
+{
+ Industry* best = NULL;
+ Industry* ind;
+ uint u;
+
+ // Check if there's an industry close to the station that accepts the cargo
+ // XXX - Think of something better to
+ // 1) Only deliver to industries which are withing the catchment radius
+ // 2) Distribute between industries if more then one is present
+ u = (_patches.station_spread + 8) * 2;
+ FOR_ALL_INDUSTRIES(ind) {
+ uint t;
+
+ if (( cargo_type == ind->accepts_cargo[0] ||
+ cargo_type == ind->accepts_cargo[1] ||
+ cargo_type == ind->accepts_cargo[2]
+ ) &&
+ ind->produced_cargo[0] != CT_INVALID &&
+ ind->produced_cargo[0] != cargo_type &&
+ (t = DistanceManhattan(ind->xy, xy)) < u) {
+ u = t;
+ best = ind;
+ }
+ }
+
+ /* Found one? */
+ if (best != NULL) {
+ best->was_cargo_delivered = true;
+ best->cargo_waiting[0] = min(best->cargo_waiting[0] + num_pieces, 0xFFFF);
+ }
+}
+
+static bool CheckSubsidised(Station *from, Station *to, CargoID cargo_type)
+{
+ Subsidy *s;
+ TileIndex xy;
+ Pair pair;
+ Player *p;
+
+ // check if there is an already existing subsidy that applies to us
+ for (s = _subsidies; s != endof(_subsidies); s++) {
+ if (s->cargo_type == cargo_type &&
+ s->age >= 12 &&
+ s->from == from->index &&
+ s->to == to->index) {
+ return true;
+ }
+ }
+
+ /* check if there's a new subsidy that applies.. */
+ for (s = _subsidies; s != endof(_subsidies); s++) {
+ if (s->cargo_type == cargo_type && s->age < 12) {
+ /* Check distance from source */
+ if (cargo_type == CT_PASSENGERS || cargo_type == CT_MAIL) {
+ xy = GetTown(s->from)->xy;
+ } else {
+ xy = (GetIndustry(s->from))->xy;
+ }
+ if (DistanceMax(xy, from->xy) > 9) continue;
+
+ /* Check distance from dest */
+ switch (cargo_type) {
+ case CT_PASSENGERS:
+ case CT_MAIL:
+ case CT_GOODS:
+ case CT_FOOD:
+ xy = GetTown(s->to)->xy;
+ break;
+
+ default:
+ xy = GetIndustry(s->to)->xy;
+ break;
+ }
+ if (DistanceMax(xy, to->xy) > 9) continue;
+
+ /* Found a subsidy, change the values to indicate that it's in use */
+ s->age = 12;
+ s->from = from->index;
+ s->to = to->index;
+
+ /* Add a news item */
+ pair = SetupSubsidyDecodeParam(s, 0);
+ InjectDParam(2);
+
+ p = GetPlayer(_current_player);
+ SetDParam(0, p->name_1);
+ SetDParam(1, p->name_2);
+ AddNewsItem(
+ STR_2031_SERVICE_SUBSIDY_AWARDED + _opt.diff.subsidy_multiplier,
+ NEWS_FLAGS(NM_NORMAL, NF_TILE, NT_SUBSIDIES, 0),
+ pair.a, pair.b
+ );
+
+ InvalidateWindow(WC_SUBSIDIES_LIST, 0);
+ return true;
+ }
+ }
+ return false;
+}
+
+static int32 DeliverGoods(int num_pieces, CargoID cargo_type, StationID source, StationID dest, byte days_in_transit)
+{
+ bool subsidised;
+ Station *s_from, *s_to;
+ int32 profit;
+
+ assert(num_pieces > 0);
+
+ // Update player statistics
+ {
+ Player *p = GetPlayer(_current_player);
+ p->cur_economy.delivered_cargo += num_pieces;
+ SETBIT(p->cargo_types, cargo_type);
+ }
+
+ // Get station pointers.
+ s_from = GetStation(source);
+ s_to = GetStation(dest);
+
+ // Check if a subsidy applies.
+ subsidised = CheckSubsidised(s_from, s_to, cargo_type);
+
+ // Increase town's counter for some special goods types
+ if (cargo_type == CT_FOOD) s_to->town->new_act_food += num_pieces;
+ if (cargo_type == CT_WATER) s_to->town->new_act_water += num_pieces;
+
+ // Give the goods to the industry.
+ DeliverGoodsToIndustry(s_to->xy, cargo_type, num_pieces);
+
+ // Determine profit
+ profit = GetTransportedGoodsIncome(num_pieces, DistanceManhattan(s_from->xy, s_to->xy), days_in_transit, cargo_type);
+
+ // Modify profit if a subsidy is in effect
+ if (subsidised) {
+ switch (_opt.diff.subsidy_multiplier) {
+ case 0: profit += profit >> 1; break;
+ case 1: profit *= 2; break;
+ case 2: profit *= 3; break;
+ default: profit *= 4; break;
+ }
+ }
+
+ return profit;
+}
+
+/*
+ * Returns true if Vehicle v should wait loading because other vehicle is
+ * already loading the same cargo type
+ * v = vehicle to load, u = GetFirstInChain(v)
+ */
+static bool LoadWait(const Vehicle* v, const Vehicle* u)
+{
+ const Vehicle *w;
+ const Vehicle *x;
+ bool has_any_cargo = false;
+
+ if (!(u->current_order.flags & OF_FULL_LOAD)) return false;
+
+ for (w = u; w != NULL; w = w->next) {
+ if (w->cargo_count != 0) {
+ if (v->cargo_type == w->cargo_type &&
+ u->last_station_visited == w->cargo_source) {
+ return false;
+ }
+ has_any_cargo = true;
+ }
+ }
+
+ FOR_ALL_VEHICLES(x) {
+ if ((x->type != VEH_Train || IsFrontEngine(x)) && // for all locs
+ u->last_station_visited == x->last_station_visited && // at the same station
+ !(x->vehstatus & (VS_STOPPED | VS_CRASHED)) && // not stopped or crashed
+ x->current_order.type == OT_LOADING && // loading
+ u != x) { // not itself
+ bool other_has_any_cargo = false;
+ bool has_space_for_same_type = false;
+ bool other_has_same_type = false;
+
+ for (w = x; w != NULL; w = w->next) {
+ if (w->cargo_count < w->cargo_cap && v->cargo_type == w->cargo_type) {
+ has_space_for_same_type = true;
+ }
+
+ if (w->cargo_count != 0) {
+ if (v->cargo_type == w->cargo_type &&
+ u->last_station_visited == w->cargo_source) {
+ other_has_same_type = true;
+ }
+ other_has_any_cargo = true;
+ }
+ }
+
+ if (has_space_for_same_type) {
+ if (other_has_same_type) return true;
+ if (other_has_any_cargo && !has_any_cargo) return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+int LoadUnloadVehicle(Vehicle *v, bool just_arrived)
+{
+ int profit = 0;
+ int v_profit = 0; //virtual profit for feeder systems
+ int v_profit_total = 0;
+ int unloading_time = 20;
+ Vehicle *u = v;
+ int result = 0;
+ StationID last_visited;
+ Station *st;
+ int t;
+ uint count, cap;
+ PlayerID old_player;
+ bool completely_empty = true;
+ byte load_amount;
+ bool anything_loaded = false;
+
+ assert(v->current_order.type == OT_LOADING);
+
+ v->cur_speed = 0;
+
+ /* Loading can only have finished when all the cargo has been unloaded, and
+ * there is nothing left to load. It's easier to clear this if the
+ * conditions haven't been met than attempting to check them all before
+ * enabling though. */
+ SETBIT(v->load_status, LS_LOADING_FINISHED);
+
+ old_player = _current_player;
+ _current_player = v->owner;
+
+ last_visited = v->last_station_visited;
+ st = GetStation(last_visited);
+
+ for (; v != NULL; v = v->next) {
+ GoodsEntry* ge;
+ load_amount = EngInfo(v->engine_type)->load_amount;
+ if (_patches.gradual_loading) {
+ uint16 cb_load_amount = GetVehicleCallback(CBID_VEHICLE_LOAD_AMOUNT, 0, 0, v->engine_type, v);
+ if (cb_load_amount != CALLBACK_FAILED) load_amount = cb_load_amount & 0xFF;
+ }
+
+ if (v->cargo_cap == 0) continue;
+
+ /* If the vehicle has just arrived, set it to unload. */
+ if (just_arrived) SETBIT(v->load_status, LS_CARGO_UNLOADING);
+
+ ge = &st->goods[v->cargo_type];
+ count = GB(ge->waiting_acceptance, 0, 12);
+
+ /* unload? */
+ if (v->cargo_count != 0 && HASBIT(v->load_status, LS_CARGO_UNLOADING)) {
+ uint16 amount_unloaded = _patches.gradual_loading ? min(v->cargo_count, load_amount) : v->cargo_count;
+
+ CLRBIT(u->load_status, LS_LOADING_FINISHED);
+
+ if (v->cargo_source != last_visited && ge->waiting_acceptance & 0x8000 && !(u->current_order.flags & OF_TRANSFER)) {
+ // deliver goods to the station
+ st->time_since_unload = 0;
+
+ unloading_time += v->cargo_count; /* TTDBUG: bug in original TTD */
+ if (just_arrived && !HASBIT(v->load_status, LS_CARGO_PAID_FOR)) {
+ profit += DeliverGoods(v->cargo_count, v->cargo_type, v->cargo_source, last_visited, v->cargo_days);
+ SETBIT(v->load_status, LS_CARGO_PAID_FOR);
+ }
+ result |= 1;
+ v->cargo_count -= amount_unloaded;
+ if (_patches.gradual_loading) continue;
+ } else if (u->current_order.flags & (OF_UNLOAD | OF_TRANSFER)) {
+ /* unload goods and let it wait at the station */
+ st->time_since_unload = 0;
+ if (just_arrived && (u->current_order.flags & OF_TRANSFER) && !HASBIT(v->load_status, LS_CARGO_PAID_FOR)) {
+ v_profit = GetTransportedGoodsIncome(
+ v->cargo_count,
+ DistanceManhattan(GetStation(v->cargo_source)->xy, GetStation(last_visited)->xy),
+ v->cargo_days,
+ v->cargo_type) * 3 / 2;
+
+ v_profit_total += v_profit;
+ SETBIT(v->load_status, LS_CARGO_PAID_FOR);
+ }
+
+ unloading_time += v->cargo_count;
+ t = GB(ge->waiting_acceptance, 0, 12);
+ if (t == 0) {
+ // No goods waiting at station
+ ge->enroute_time = v->cargo_days;
+ ge->enroute_from = v->cargo_source;
+ } else {
+ // Goods already waiting at station. Set counters to the worst value.
+ if (v->cargo_days >= ge->enroute_time)
+ ge->enroute_time = v->cargo_days;
+ if (last_visited != ge->enroute_from)
+ ge->enroute_from = v->cargo_source;
+ }
+ // Update amount of waiting cargo
+ SB(ge->waiting_acceptance, 0, 12, min(amount_unloaded + t, 0xFFF));
+
+ if (u->current_order.flags & OF_TRANSFER) {
+ ge->feeder_profit += v_profit;
+ u->profit_this_year += v_profit;
+ }
+ result |= 2;
+ v->cargo_count -= amount_unloaded;
+ if (_patches.gradual_loading) continue;
+ }
+
+ if (v->cargo_count != 0) completely_empty = false;
+ }
+
+ /* The vehicle must have been unloaded because it is either empty, or
+ * the UNLOADING bit is already clear in v->load_status. */
+ CLRBIT(v->load_status, LS_CARGO_UNLOADING);
+ CLRBIT(v->load_status, LS_CARGO_PAID_FOR);
+
+ /* don't pick up goods that we unloaded */
+ if (u->current_order.flags & OF_UNLOAD) continue;
+
+ /* update stats */
+ ge->days_since_pickup = 0;
+ switch (u->type) {
+ case VEH_Train: t = u->u.rail.cached_max_speed; break;
+ case VEH_Road: t = u->max_speed / 2; break;
+ default: t = u->max_speed; break;
+ }
+
+ // if last speed is 0, we treat that as if no vehicle has ever visited the station.
+ ge->last_speed = min(t, 255);
+ ge->last_age = _cur_year - v->build_year;
+
+ // If there's goods waiting at the station, and the vehicle
+ // has capacity for it, load it on the vehicle.
+ if (count != 0 &&
+ (cap = v->cargo_cap - v->cargo_count) != 0) {
+ int cargoshare;
+ int feeder_profit_share;
+
+ if (v->cargo_count == 0)
+ TriggerVehicle(v, VEHICLE_TRIGGER_NEW_CARGO);
+
+ /* Skip loading this vehicle if another train/vehicle is already handling
+ * the same cargo type at this station */
+ if (_patches.improved_load && (u->current_order.flags & OF_FULL_LOAD) && LoadWait(v,u)) continue;
+
+ /* TODO: Regarding this, when we do gradual loading, we
+ * should first unload all vehicles and then start
+ * loading them. Since this will cause
+ * VEHICLE_TRIGGER_EMPTY to be called at the time when
+ * the whole vehicle chain is really totally empty, the
+ * @completely_empty assignment can then be safely
+ * removed; that's how TTDPatch behaves too. --pasky */
+ completely_empty = false;
+ anything_loaded = true;
+
+ if (cap > count) cap = count;
+ if (_patches.gradual_loading) cap = min(cap, load_amount);
+ if (cap < count) CLRBIT(u->load_status, LS_LOADING_FINISHED);
+ cargoshare = cap * 10000 / ge->waiting_acceptance;
+ feeder_profit_share = ge->feeder_profit * cargoshare / 10000;
+ v->cargo_count += cap;
+ ge->waiting_acceptance -= cap;
+ v->profit_this_year -= feeder_profit_share;
+ ge->feeder_profit -= feeder_profit_share;
+ unloading_time += cap;
+ st->time_since_load = 0;
+
+ // And record the source of the cargo, and the days in travel.
+ v->cargo_source = ge->enroute_from;
+ v->cargo_days = ge->enroute_time;
+ result |= 2;
+ st->last_vehicle_type = v->type;
+ }
+ }
+
+ v = u;
+
+ if (_patches.gradual_loading) {
+ /* The time it takes to load one 'slice' of cargo or passengers depends
+ * on the vehicle type - the values here are those found in TTDPatch */
+ uint gradual_loading_wait_time[] = { 40, 20, 10, 20 };
+
+ unloading_time = gradual_loading_wait_time[v->type - VEH_Train];
+ if (HASBIT(v->load_status, LS_LOADING_FINISHED)) {
+ if (anything_loaded) {
+ unloading_time += 20;
+ } else {
+ unloading_time = 20;
+ }
+ }
+ }
+
+ if (v_profit_total > 0) {
+ ShowFeederIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, v_profit_total);
+ }
+
+ if (v->type == VEH_Train) {
+ // Each platform tile is worth 2 rail vehicles.
+ int overhang = v->u.rail.cached_total_length - GetStationPlatforms(st, v->tile) * TILE_SIZE;
+ if (overhang > 0) {
+ unloading_time <<= 1;
+ unloading_time += (overhang * unloading_time) / 8;
+ }
+ }
+
+ v->load_unload_time_rem = unloading_time;
+
+ if (completely_empty) {
+ TriggerVehicle(v, VEHICLE_TRIGGER_EMPTY);
+ }
+
+ if (result != 0) {
+ InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
+ MarkStationTilesDirty(st);
+
+ if (result & 2) InvalidateWindow(WC_STATION_VIEW, last_visited);
+
+ if (profit != 0) {
+ v->profit_this_year += profit;
+ SubtractMoneyFromPlayer(-profit);
+
+ if (IsLocalPlayer() && !PlayVehicleSound(v, VSE_LOAD_UNLOAD)) {
+ SndPlayVehicleFx(SND_14_CASHTILL, v);
+ }
+
+ ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, -profit);
+ }
+ }
+
+ _current_player = old_player;
+ return result;
+}
+
+void PlayersMonthlyLoop(void)
+{
+ PlayersGenStatistics();
+ if (_patches.inflation && _cur_year < MAX_YEAR)
+ AddInflation();
+ PlayersPayInterest();
+ // Reset the _current_player flag
+ _current_player = OWNER_NONE;
+ HandleEconomyFluctuations();
+ SubsidyMonthlyHandler();
+}
+
+static void DoAcquireCompany(Player *p)
+{
+ Player *owner;
+ int i,pi;
+ int64 value;
+
+ SetDParam(0, p->name_1);
+ SetDParam(1, p->name_2);
+ SetDParam(2, p->bankrupt_value);
+ AddNewsItem( (StringID)(_current_player | NB_BMERGER), NEWS_FLAGS(NM_CALLBACK, 0, NT_COMPANY_INFO, DNC_BANKRUPCY),0,0);
+
+ // original code does this a little bit differently
+ pi = p->index;
+ ChangeOwnershipOfPlayerItems(pi, _current_player);
+
+ if (p->bankrupt_value == 0) {
+ owner = GetPlayer(_current_player);
+ owner->current_loan += p->current_loan;
+ }
+
+ value = CalculateCompanyValue(p) >> 2;
+ for (i = 0; i != 4; i++) {
+ if (p->share_owners[i] != PLAYER_SPECTATOR) {
+ owner = GetPlayer(p->share_owners[i]);
+ owner->money64 += value;
+ owner->yearly_expenses[0][EXPENSES_OTHER] += value;
+ UpdatePlayerMoney32(owner);
+ }
+ }
+
+ p->is_active = false;
+
+ DeletePlayerWindows(pi);
+ RebuildVehicleLists(); //Updates the open windows to add the newly acquired vehicles to the lists
+}
+
+extern int GetAmountOwnedBy(Player *p, byte owner);
+
+/** Acquire shares in an opposing company.
+ * @param tile unused
+ * @param p1 player to buy the shares from
+ * @param p2 unused
+ */
+int32 CmdBuyShareInCompany(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Player *p;
+ int64 cost;
+
+ /* Check if buying shares is allowed (protection against modified clients */
+ if (!IsValidPlayer((PlayerID)p1) || !_patches.allow_shares) return CMD_ERROR;
+
+ SET_EXPENSES_TYPE(EXPENSES_OTHER);
+ p = GetPlayer(p1);
+
+ /* Protect new companies from hostile takeovers */
+ if (_cur_year - p->inaugurated_year < 6) return_cmd_error(STR_7080_PROTECTED);
+
+ /* Those lines are here for network-protection (clients can be slow) */
+ if (GetAmountOwnedBy(p, PLAYER_SPECTATOR) == 0) return 0;
+
+ /* We can not buy out a real player (temporarily). TODO: well, enable it obviously */
+ if (GetAmountOwnedBy(p, PLAYER_SPECTATOR) == 1 && !p->is_ai) return 0;
+
+ cost = CalculateCompanyValue(p) >> 2;
+ if (flags & DC_EXEC) {
+ PlayerID* b = p->share_owners;
+ int i;
+
+ while (*b != PLAYER_SPECTATOR) b++; /* share owners is guaranteed to contain at least one PLAYER_SPECTATOR */
+ *b = _current_player;
+
+ for (i = 0; p->share_owners[i] == _current_player;) {
+ if (++i == 4) {
+ p->bankrupt_value = 0;
+ DoAcquireCompany(p);
+ break;
+ }
+ }
+ InvalidateWindow(WC_COMPANY, p1);
+ }
+ return cost;
+}
+
+/** Sell shares in an opposing company.
+ * @param tile unused
+ * @param p1 player to sell the shares from
+ * @param p2 unused
+ */
+int32 CmdSellShareInCompany(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Player *p;
+ int64 cost;
+
+ /* Check if buying shares is allowed (protection against modified clients */
+ if (!IsValidPlayer((PlayerID)p1) || !_patches.allow_shares) return CMD_ERROR;
+
+ SET_EXPENSES_TYPE(EXPENSES_OTHER);
+ p = GetPlayer(p1);
+
+ /* Those lines are here for network-protection (clients can be slow) */
+ if (GetAmountOwnedBy(p, _current_player) == 0) return 0;
+
+ /* adjust it a little to make it less profitable to sell and buy */
+ cost = CalculateCompanyValue(p) >> 2;
+ cost = -(cost - (cost >> 7));
+
+ if (flags & DC_EXEC) {
+ PlayerID* b = p->share_owners;
+ while (*b != _current_player) b++; /* share owners is guaranteed to contain player */
+ *b = PLAYER_SPECTATOR;
+ InvalidateWindow(WC_COMPANY, p1);
+ }
+ return cost;
+}
+
+/** Buy up another company.
+ * When a competing company is gone bankrupt you get the chance to purchase
+ * that company.
+ * @todo currently this only works for AI players
+ * @param tile unused
+ * @param p1 player/company to buy up
+ * @param p2 unused
+ */
+int32 CmdBuyCompany(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Player *p;
+
+ /* Disable takeovers in multiplayer games */
+ if (!IsValidPlayer((PlayerID)p1) || _networking) return CMD_ERROR;
+
+ SET_EXPENSES_TYPE(EXPENSES_OTHER);
+ p = GetPlayer(p1);
+
+ if (!p->is_ai) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ DoAcquireCompany(p);
+ }
+ return p->bankrupt_value;
+}
+
+// Prices
+static void SaveLoad_PRIC(void)
+{
+ SlArray(&_price, NUM_PRICES, SLE_INT32);
+ SlArray(&_price_frac, NUM_PRICES, SLE_UINT16);
+}
+
+// Cargo payment rates
+static void SaveLoad_CAPR(void)
+{
+ SlArray(&_cargo_payment_rates, NUM_CARGO, SLE_INT32);
+ SlArray(&_cargo_payment_rates_frac, NUM_CARGO, SLE_UINT16);
+}
+
+static const SaveLoad _economy_desc[] = {
+ SLE_VAR(Economy, max_loan, SLE_INT32),
+ SLE_VAR(Economy, max_loan_unround, SLE_INT32),
+ SLE_VAR(Economy, fluct, SLE_FILE_I16 | SLE_VAR_I32),
+ SLE_VAR(Economy, interest_rate, SLE_UINT8),
+ SLE_VAR(Economy, infl_amount, SLE_UINT8),
+ SLE_VAR(Economy, infl_amount_pr, SLE_UINT8),
+ SLE_END()
+};
+
+// Economy variables
+static void SaveLoad_ECMY(void)
+{
+ SlObject(&_economy, _economy_desc);
+}
+
+const ChunkHandler _economy_chunk_handlers[] = {
+ { 'PRIC', SaveLoad_PRIC, SaveLoad_PRIC, CH_RIFF | CH_AUTO_LENGTH},
+ { 'CAPR', SaveLoad_CAPR, SaveLoad_CAPR, CH_RIFF | CH_AUTO_LENGTH},
+ { 'SUBS', Save_SUBS, Load_SUBS, CH_ARRAY},
+ { 'ECMY', SaveLoad_ECMY, SaveLoad_ECMY, CH_RIFF | CH_LAST},
+};
diff --git a/src/economy.h b/src/economy.h
new file mode 100644
index 000000000..823e167c8
--- /dev/null
+++ b/src/economy.h
@@ -0,0 +1,70 @@
+/* $Id$ */
+
+#ifndef ECONOMY_H
+#define ECONOMY_H
+
+void ResetPriceBaseMultipliers(void);
+void SetPriceBaseMultiplier(uint price, byte factor);
+
+typedef struct {
+ // Maximum possible loan
+ int32 max_loan;
+ int32 max_loan_unround;
+ // Economy fluctuation status
+ int fluct;
+ // Interest
+ byte interest_rate;
+ byte infl_amount;
+ byte infl_amount_pr;
+} Economy;
+
+VARDEF Economy _economy;
+
+typedef struct Subsidy {
+ CargoID cargo_type;
+ byte age;
+ /* from and to can either be TownID, StationID or IndustryID */
+ uint16 from;
+ uint16 to;
+} Subsidy;
+
+
+enum {
+ SCORE_VEHICLES = 0,
+ SCORE_STATIONS = 1,
+ SCORE_MIN_PROFIT = 2,
+ SCORE_MIN_INCOME = 3,
+ SCORE_MAX_INCOME = 4,
+ SCORE_DELIVERED = 5,
+ SCORE_CARGO = 6,
+ SCORE_MONEY = 7,
+ SCORE_LOAN = 8,
+ SCORE_TOTAL = 9, // This must always be the last entry
+
+ NUM_SCORE = 10, // How many scores are there..
+
+ SCORE_MAX = 1000 // The max score that can be in the performance history
+ // the scores together of score_info is allowed to be more!
+};
+
+typedef struct ScoreInfo {
+ byte id; // Unique ID of the score
+ int needed; // How much you need to get the perfect score
+ int score; // How much score it will give
+} ScoreInfo;
+
+extern const ScoreInfo _score_info[];
+extern int _score_part[MAX_PLAYERS][NUM_SCORE];
+
+int UpdateCompanyRatingAndValue(Player *p, bool update);
+
+VARDEF Subsidy _subsidies[MAX_PLAYERS];
+Pair SetupSubsidyDecodeParam(const Subsidy* s, bool mode);
+void DeleteSubsidyWithTown(TownID index);
+void DeleteSubsidyWithIndustry(IndustryID index);
+void DeleteSubsidyWithStation(StationID index);
+
+int32 GetTransportedGoodsIncome(uint num_pieces, uint dist, byte transit_days, CargoID cargo_type);
+uint MoveGoodsToStation(TileIndex tile, int w, int h, int type, uint amount);
+
+#endif /* ECONOMY_H */
diff --git a/src/elrail.c b/src/elrail.c
new file mode 100644
index 000000000..da043b582
--- /dev/null
+++ b/src/elrail.c
@@ -0,0 +1,445 @@
+/* $Id$ */
+/** @file elrail.c
+ * This file deals with displaying wires and pylons for electric railways.
+ * <h2>Basics</h2>
+ *
+ * <h3>Tile Types</h3>
+ *
+ * We have two different types of tiles in the drawing code:
+ * Normal Railway Tiles (NRTs) which can have more than one track on it, and
+ * Special Railways tiles (SRTs) which have only one track (like crossings, depots
+ * stations, etc).
+ *
+ * <h3>Location Categories</h3>
+ *
+ * All tiles are categorized into three location groups (TLG):
+ * Group 0: Tiles with both an even X coordinate and an even Y coordinate
+ * Group 1: Tiles with an even X and an odd Y coordinate
+ * Group 2: Tiles with an odd X and an even Y coordinate
+ * Group 3: Tiles with both an odd X and Y coordnate.
+ *
+ * <h3>Pylon Points</h3>
+ * <h4>Control Points</h4>
+ * A Pylon Control Point (PCP) is a position where a wire (or rather two)
+ * is mounted onto a pylon.
+ * Each NRT does contain 4 PCPs which are bitmapped to a byte
+ * variable and are represented by the DiagDirection enum
+ *
+ * Each track ends on two PCPs and thus requires one pylon on each end. However,
+ * there is one exception: Straight-and-level tracks only have one pylon every
+ * other tile.
+ *
+ * Now on each edge there are two PCPs: One from each adjacent tile. Both PCPs
+ * are merged using an OR operation (i. e. if one tile needs a PCP at the postion
+ * in question, both tiles get it).
+ *
+ * <h4>Position Points</h4>
+ * A Pylon Position Point (PPP) is a position where a pylon is located on the
+ * ground. Each PCP owns 8 in (45 degree steps) PPPs that are located around
+ * it. PPPs are represented using the Direction enum. Each track bit has PPPs
+ * that are impossible (because the pylon would be situated on the track) and
+ * some that are preferred (because the pylon would be rectangular to the track).
+ *
+ * <img src="../../elrail_tile.png">
+ * <img src="../../elrail_track.png">
+ *
+ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "station_map.h"
+#include "tile.h"
+#include "viewport.h"
+#include "functions.h" /* We should REALLY get rid of this goddamn file, as it is butt-ugly */
+#include "variables.h" /* ... same here */
+#include "rail.h"
+#include "debug.h"
+#include "tunnel_map.h"
+#include "road_map.h"
+#include "bridge_map.h"
+#include "bridge.h"
+#include "rail_map.h"
+#include "table/sprites.h"
+#include "table/elrail_data.h"
+#include "vehicle.h"
+#include "train.h"
+#include "gui.h"
+
+static inline TLG GetTLG(TileIndex t)
+{
+ return (HASBIT(TileX(t), 0) << 1) + HASBIT(TileY(t), 0);
+}
+
+/** Finds which Rail Bits are present on a given tile. For bridge tiles,
+ * returns track bits under the bridge
+ */
+static TrackBits GetRailTrackBitsUniversal(TileIndex t, byte *override)
+{
+ switch (GetTileType(t)) {
+ case MP_RAILWAY:
+ if (GetRailType(t) != RAILTYPE_ELECTRIC) return 0;
+ switch (GetRailTileType(t)) {
+ case RAIL_TILE_NORMAL: case RAIL_TILE_SIGNALS:
+ return GetTrackBits(t);
+ case RAIL_TILE_DEPOT_WAYPOINT:
+ if (GetRailTileSubtype(t) == RAIL_SUBTYPE_WAYPOINT) return GetRailWaypointBits(t);
+ default:
+ return 0;
+ }
+ break;
+
+ case MP_TUNNELBRIDGE:
+ if (IsTunnel(t)) {
+ if (GetRailType(t) != RAILTYPE_ELECTRIC) return 0;
+ if (override != NULL) *override = 1 << GetTunnelDirection(t);
+ return AxisToTrackBits(DiagDirToAxis(GetTunnelDirection(t)));
+ } else {
+ if (GetRailType(t) != RAILTYPE_ELECTRIC) return 0;
+ if (override != NULL && DistanceMax(t, GetOtherBridgeEnd(t)) > 1) {
+ *override = 1 << GetBridgeRampDirection(t);
+ }
+ return AxisToTrackBits(DiagDirToAxis(GetBridgeRampDirection(t)));
+ }
+
+ case MP_STREET:
+ if (GetRoadTileType(t) != ROAD_TILE_CROSSING) return 0;
+ if (GetRailTypeCrossing(t) != RAILTYPE_ELECTRIC) return 0;
+ return GetCrossingRailBits(t);
+
+ case MP_STATION:
+ if (!IsRailwayStation(t)) return 0;
+ if (GetRailType(t) != RAILTYPE_ELECTRIC) return 0;
+ if (!IsStationTileElectrifiable(t)) return 0;
+ return TrackToTrackBits(GetRailStationTrack(t));
+
+ default:
+ return 0;
+ }
+}
+
+/** Corrects the tileh for certain tile types. Returns an effective tileh for the track on the tile.
+ * @param tile The tile to analyse
+ * @param *tileh the tileh
+ */
+static void AdjustTileh(TileIndex tile, Slope *tileh)
+{
+ if (IsTileType(tile, MP_TUNNELBRIDGE)) {
+ if (IsTunnel(tile)) {
+ *tileh = SLOPE_FLAT;
+ } else {
+ if (*tileh != SLOPE_FLAT) {
+ *tileh = SLOPE_FLAT;
+ } else {
+ switch (GetBridgeRampDirection(tile)) {
+ case DIAGDIR_NE: *tileh = SLOPE_NE; break;
+ case DIAGDIR_SE: *tileh = SLOPE_SE; break;
+ case DIAGDIR_SW: *tileh = SLOPE_SW; break;
+ case DIAGDIR_NW: *tileh = SLOPE_NW; break;
+ default: NOT_REACHED();
+ }
+ }
+ }
+ }
+}
+
+/** Draws wires and, if required, pylons on a given tile
+ * @param ti The Tileinfo to draw the tile for
+ */
+static void DrawCatenaryRailway(const TileInfo *ti)
+{
+ /* Pylons are placed on a tile edge, so we need to take into account
+ * the track configuration of 2 adjacent tiles. trackconfig[0] stores the
+ * current tile (home tile) while [1] holds the neighbour */
+ TrackBits trackconfig[TS_END];
+ bool isflat[TS_END];
+ /* Note that ti->tileh has already been adjusted for Foundations */
+ Slope tileh[TS_END] = { ti->tileh, SLOPE_FLAT };
+
+ TLG tlg = GetTLG(ti->tile);
+ byte PCPstatus = 0;
+ byte OverridePCP = 0;
+ byte PPPpreferred[DIAGDIR_END];
+ byte PPPallowed[DIAGDIR_END];
+ DiagDirection i;
+ Track t;
+
+ /* Find which rail bits are present, and select the override points.
+ * We don't draw a pylon:
+ * 1) INSIDE a tunnel (we wouldn't see it anyway)
+ * 2) on the "far" end of a bridge head (the one that connects to bridge middle),
+ * because that one is drawn on the bridge. Exception is for length 0 bridges
+ * which have no middle tiles */
+ trackconfig[TS_HOME] = GetRailTrackBitsUniversal(ti->tile, &OverridePCP);
+ /* If a track bit is present that is not in the main direction, the track is level */
+ isflat[TS_HOME] = trackconfig[TS_HOME] & (TRACK_BIT_HORZ | TRACK_BIT_VERT);
+
+ AdjustTileh(ti->tile, &tileh[TS_HOME]);
+
+ for (i = DIAGDIR_NE; i < DIAGDIR_END; i++) {
+ TileIndex neighbour = ti->tile + TileOffsByDiagDir(i);
+ uint foundation = 0;
+ int k;
+
+ /* Here's one of the main headaches. GetTileSlope does not correct for possibly
+ * existing foundataions, so we do have to do that manually later on.*/
+ tileh[TS_NEIGHBOUR] = GetTileSlope(neighbour, NULL);
+ trackconfig[TS_NEIGHBOUR] = GetRailTrackBitsUniversal(neighbour, NULL);
+ if (IsTunnelTile(neighbour) && i != GetTunnelDirection(neighbour)) trackconfig[TS_NEIGHBOUR] = 0;
+ isflat[TS_NEIGHBOUR] = trackconfig[TS_NEIGHBOUR] & (TRACK_BIT_HORZ | TRACK_BIT_VERT);
+
+ PPPpreferred[i] = 0xFF; /* We start with preferring everything (end-of-line in any direction) */
+ PPPallowed[i] = AllowedPPPonPCP[i];
+
+ /* We cycle through all the existing tracks at a PCP and see what
+ * PPPs we want to have, or may not have at all */
+ for (k = 0; k < NUM_TRACKS_AT_PCP; k++) {
+ /* Next to us, we have a bridge head, don't worry about that one, if it shows away from us */
+ if (TrackSourceTile[i][k] == TS_NEIGHBOUR &&
+ IsBridgeTile(neighbour) &&
+ GetBridgeRampDirection(neighbour) == ReverseDiagDir(i)) {
+ continue;
+ }
+
+ /* We check whether the track in question (k) is present in the tile
+ * (TrackSourceTile) */
+ if (HASBIT(trackconfig[TrackSourceTile[i][k]], TracksAtPCP[i][k])) {
+ /* track found, if track is in the neighbour tile, adjust the number
+ * of the PCP for preferred/allowed determination*/
+ DiagDirection PCPpos = (TrackSourceTile[i][k] == TS_HOME) ? i : ReverseDiagDir(i);
+ SETBIT(PCPstatus, i); /* This PCP is in use */
+
+ PPPpreferred[i] &= PreferredPPPofTrackAtPCP[TracksAtPCP[i][k]][PCPpos];
+ PPPallowed[i] &= ~DisallowedPPPofTrackAtPCP[TracksAtPCP[i][k]][PCPpos];
+ }
+ }
+
+ /* Deactivate all PPPs if PCP is not used */
+ PPPpreferred[i] *= HASBIT(PCPstatus, i);
+ PPPallowed[i] *= HASBIT(PCPstatus, i);
+
+ /* A station is always "flat", so adjust the tileh accordingly */
+ if (IsTileType(neighbour, MP_STATION)) tileh[TS_NEIGHBOUR] = SLOPE_FLAT;
+
+ /* Read the foundataions if they are present, and adjust the tileh */
+ if (IsTileType(neighbour, MP_RAILWAY) && GetRailType(neighbour) == RAILTYPE_ELECTRIC) foundation = GetRailFoundation(tileh[TS_NEIGHBOUR], trackconfig[TS_NEIGHBOUR]);
+ if (IsBridgeTile(neighbour)) {
+ foundation = GetBridgeFoundation(tileh[TS_NEIGHBOUR], DiagDirToAxis(GetBridgeRampDirection(neighbour)));
+ }
+
+ if (foundation != 0) {
+ if (foundation < 15) {
+ tileh[TS_NEIGHBOUR] = SLOPE_FLAT;
+ } else {
+ tileh[TS_NEIGHBOUR] = _inclined_tileh[foundation - 15];
+ }
+ }
+
+ AdjustTileh(neighbour, &tileh[TS_NEIGHBOUR]);
+
+ /* If we have a straight (and level) track, we want a pylon only every 2 tiles
+ * Delete the PCP if this is the case. */
+ /* Level means that the slope is the same, or the track is flat */
+ if (tileh[TS_HOME] == tileh[TS_NEIGHBOUR] || (isflat[TS_HOME] && isflat[TS_NEIGHBOUR])) {
+ for (k = 0; k < NUM_IGNORE_GROUPS; k++)
+ if (PPPpreferred[i] == IgnoredPCP[k][tlg][i]) CLRBIT(PCPstatus, i);
+ }
+
+ /* Now decide where we draw our pylons. First try the preferred PPPs, but they may not exist.
+ * In that case, we try the any of the allowed ones. if they don't exist either, don't draw
+ * anything. Note that the preferred PPPs still contain the end-of-line markers.
+ * Remove those (simply by ANDing with allowed, since these markers are never allowed) */
+ if ((PPPallowed[i] & PPPpreferred[i]) != 0) PPPallowed[i] &= PPPpreferred[i];
+
+ if (MayHaveBridgeAbove(ti->tile) && IsBridgeAbove(ti->tile)) {
+ Track bridgetrack = GetBridgeAxis(ti->tile) == AXIS_X ? TRACK_X : TRACK_Y;
+ uint height = GetBridgeHeight(GetNorthernBridgeEnd(ti->tile));
+
+ if ((height <= TilePixelHeight(ti->tile) + TILE_HEIGHT) &&
+ (i == PCPpositions[bridgetrack][0] || i == PCPpositions[bridgetrack][1])) SETBIT(OverridePCP, i);
+ }
+
+ if (PPPallowed[i] != 0 && HASBIT(PCPstatus, i) && !HASBIT(OverridePCP, i)) {
+ for (k = 0; k < DIR_END; k++) {
+ byte temp = PPPorder[i][GetTLG(ti->tile)][k];
+
+ if (HASBIT(PPPallowed[i], temp)) {
+ uint x = ti->x + x_pcp_offsets[i] + x_ppp_offsets[temp];
+ uint y = ti->y + y_pcp_offsets[i] + y_ppp_offsets[temp];
+
+ /* Don't build the pylon if it would be outside the tile */
+ if (!HASBIT(OwnedPPPonPCP[i], temp)) {
+ /* We have a neighour that will draw it, bail out */
+ if (trackconfig[TS_NEIGHBOUR] != 0) break;
+ continue; /* No neighbour, go looking for a better position */
+ }
+
+ AddSortableSpriteToDraw(pylons_normal[temp], x, y, 1, 1, 10,
+ GetSlopeZ(ti->x + x_pcp_offsets[i], ti->y + y_pcp_offsets[i]));
+ break; /* We already have drawn a pylon, bail out */
+ }
+ }
+ }
+ }
+
+ /* Don't draw a wire under a low bridge */
+ if (MayHaveBridgeAbove(ti->tile) && IsBridgeAbove(ti->tile) && !(_display_opt & DO_TRANS_BUILDINGS)) {
+ uint height = GetBridgeHeight(GetNorthernBridgeEnd(ti->tile));
+
+ if (height <= TilePixelHeight(ti->tile) + TILE_HEIGHT) return;
+ }
+
+ /* Drawing of pylons is finished, now draw the wires */
+ for (t = 0; t < TRACK_END; t++) {
+ if (HASBIT(trackconfig[TS_HOME], t)) {
+
+ byte PCPconfig = HASBIT(PCPstatus, PCPpositions[t][0]) +
+ (HASBIT(PCPstatus, PCPpositions[t][1]) << 1);
+
+ const SortableSpriteStruct *sss;
+ int tileh_selector = !(tileh[TS_HOME] % 3) * tileh[TS_HOME] / 3; /* tileh for the slopes, 0 otherwise */
+
+ assert(PCPconfig != 0); /* We have a pylon on neither end of the wire, that doesn't work (since we have no sprites for that) */
+ assert(!IsSteepSlope(tileh[TS_HOME]));
+ sss = &CatenarySpriteData[Wires[tileh_selector][t][PCPconfig]];
+
+ AddSortableSpriteToDraw( sss->image, ti->x + sss->x_offset, ti->y + sss->y_offset,
+ sss->x_size, sss->y_size, sss->z_size, GetSlopeZ(ti->x + min(sss->x_offset, TILE_SIZE - 1), ti->y + min(sss->y_offset, TILE_SIZE - 1)) + sss->z_offset);
+ }
+ }
+}
+
+static void DrawCatenaryOnBridge(const TileInfo *ti)
+{
+ TileIndex end = GetSouthernBridgeEnd(ti->tile);
+ TileIndex start = GetOtherBridgeEnd(end);
+
+ uint length = GetBridgeLength(start, end);
+ uint num = DistanceMax(ti->tile, start);
+ uint height;
+
+ const SortableSpriteStruct *sss;
+ Axis axis = GetBridgeAxis(ti->tile);
+ TLG tlg = GetTLG(ti->tile);
+
+ CatenarySprite offset = axis == AXIS_X ? 0 : WIRE_Y_FLAT_BOTH - WIRE_X_FLAT_BOTH;
+
+ if ((length % 2) && num == length) {
+ /* Draw the "short" wire on the southern end of the bridge
+ * only needed if the length of the bridge is odd */
+ sss = &CatenarySpriteData[WIRE_X_FLAT_BOTH + offset];
+ } else {
+ /* Draw "long" wires on all other tiles of the bridge (one pylon every two tiles) */
+ sss = &CatenarySpriteData[WIRE_X_FLAT_SW + (num % 2) + offset];
+ }
+
+ height = GetBridgeHeight(end);
+
+ AddSortableSpriteToDraw( sss->image, ti->x + sss->x_offset, ti->y + sss->y_offset,
+ sss->x_size, sss->y_size, sss->z_size, height + sss->z_offset
+ );
+
+ /* Finished with wires, draw pylons */
+ /* every other tile needs a pylon on the northern end */
+ if (num % 2) {
+ if (axis == AXIS_X) {
+ AddSortableSpriteToDraw(pylons_bridge[0 + HASBIT(tlg, 0)], ti->x, ti->y + 4 + 8 * HASBIT(tlg, 0), 1, 1, 10, height);
+ } else {
+ AddSortableSpriteToDraw(pylons_bridge[2 + HASBIT(tlg, 1)], ti->x + 4 + 8 * HASBIT(tlg, 1), ti->y, 1, 1, 10, height);
+ }
+ }
+
+ /* need a pylon on the southern end of the bridge */
+ if (DistanceMax(ti->tile, start) == length) {
+ if (axis == AXIS_X) {
+ AddSortableSpriteToDraw(pylons_bridge[0 + HASBIT(tlg, 0)], ti->x + 16, ti->y + 4 + 8 * HASBIT(tlg, 0), 1, 1, 10, height);
+ } else {
+ AddSortableSpriteToDraw(pylons_bridge[2 + HASBIT(tlg, 1)], ti->x + 4 + 8 * HASBIT(tlg, 1), ti->y + 16, 1, 1, 10, height);
+ }
+ }
+}
+
+void DrawCatenary(const TileInfo *ti)
+{
+ if (MayHaveBridgeAbove(ti->tile) && IsBridgeAbove(ti->tile)) {
+ TileIndex head = GetNorthernBridgeEnd(ti->tile);
+
+ if (GetBridgeTransportType(head) == TRANSPORT_RAIL && GetRailType(head) == RAILTYPE_ELECTRIC) {
+ DrawCatenaryOnBridge(ti);
+ }
+ }
+ if (_patches.disable_elrails) return;
+
+ switch (GetTileType(ti->tile)) {
+ case MP_RAILWAY:
+ if (IsRailDepot(ti->tile)) {
+ const SortableSpriteStruct* sss = &CatenarySpriteData_Depot[GetRailDepotDirection(ti->tile)];
+
+ AddSortableSpriteToDraw(
+ sss->image, ti->x + sss->x_offset, ti->y + sss->y_offset,
+ sss->x_size, sss->y_size, sss->z_size,
+ GetTileMaxZ(ti->tile) + sss->z_offset
+ );
+ return;
+ }
+ break;
+
+ case MP_TUNNELBRIDGE:
+ case MP_STREET:
+ case MP_STATION:
+ break;
+
+ default: return;
+ }
+ DrawCatenaryRailway(ti);
+}
+
+int32 SettingsDisableElrail(int32 p1)
+{
+ EngineID e_id;
+ Vehicle* v;
+ Player *p;
+ bool disable = (p1 != 0);
+
+ /* we will now walk through all electric train engines and change their railtypes if it is the wrong one*/
+ const RailType old_railtype = disable ? RAILTYPE_ELECTRIC : RAILTYPE_RAIL;
+ const RailType new_railtype = disable ? RAILTYPE_RAIL : RAILTYPE_ELECTRIC;
+
+ /* walk through all train engines */
+ for (e_id = 0; e_id < NUM_TRAIN_ENGINES; e_id++) {
+ const RailVehicleInfo *rv_info = RailVehInfo(e_id);
+ Engine *e = GetEngine(e_id);
+ /* if it is an electric rail engine and its railtype is the wrong one */
+ if (rv_info->engclass == 2 && e->railtype == old_railtype) {
+ /* change it to the proper one */
+ e->railtype = new_railtype;
+ }
+ }
+
+ /* when disabling elrails, make sure that all existing trains can run on
+ * normal rail too */
+ if (disable) {
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == VEH_Train && v->u.rail.railtype == RAILTYPE_ELECTRIC) {
+ /* this railroad vehicle is now compatible only with elrail,
+ * so add there also normal rail compatibility */
+ v->u.rail.compatible_railtypes |= (1 << RAILTYPE_RAIL);
+ v->u.rail.railtype = RAILTYPE_RAIL;
+ SETBIT(v->u.rail.flags, VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL);
+ }
+ }
+ }
+
+ /* setup total power for trains */
+ FOR_ALL_VEHICLES(v) {
+ /* power is cached only for front engines */
+ if (v->type == VEH_Train && IsFrontEngine(v)) TrainPowerChanged(v);
+ }
+
+ FOR_ALL_PLAYERS(p) p->avail_railtypes = GetPlayerRailtypes(p->index);
+
+ /* This resets the _last_built_railtype, which will be invalid for electric
+ * rails. It may have unintended consequences if that function is ever
+ * extended, though. */
+ ReinitGuiAfterToggleElrail(disable);
+ return 0;
+}
diff --git a/src/endian_check.c b/src/endian_check.c
new file mode 100644
index 000000000..a302ea40b
--- /dev/null
+++ b/src/endian_check.c
@@ -0,0 +1,52 @@
+/* $Id$ */
+
+#include <stdio.h>
+
+// This pretty simple file checks if the system is LITTLE_ENDIAN or BIG_ENDIAN
+// it does that by putting a 1 and a 0 in an array, and read it out as one
+// number. If it is 1, it is LITTLE_ENDIAN, if it is 256, it is BIG_ENDIAN
+//
+// After that it outputs the contents of an include files (endian.h)
+// that says or TTD_LITTLE_ENDIAN, or TTD_BIG_ENDIAN. Makefile takes
+// care of the real writing to the file.
+
+int main (int argc, char *argv[]) {
+ unsigned char EndianTest[2] = { 1, 0 };
+ int force_BE = 0, force_LE = 0, force_PREPROCESSOR = 0;
+
+ if (argc > 1 && strcmp(argv[1], "BE") == 0)
+ force_BE = 1;
+ if (argc > 1 && strcmp(argv[1], "LE") == 0)
+ force_LE = 1;
+ if (argc > 1 && strcmp(argv[1], "PREPROCESSOR") == 0)
+ force_PREPROCESSOR = 1;
+
+ printf("#ifndef ENDIAN_H\n#define ENDIAN_H\n");
+
+ if (force_LE == 1) {
+ printf("#define TTD_LITTLE_ENDIAN\n");
+ } else {
+ if (force_BE == 1) {
+ printf("#define TTD_BIG_ENDIAN\n");
+ } else {
+ if (force_PREPROCESSOR == 1) {
+ // adding support for universal binaries on OSX
+ // Universal binaries supports both PPC and x86
+ // If a compiler for OSX gets this setting, it will always pick the correct endian and no test is needed
+ printf("#ifdef __BIG_ENDIAN__\n");
+ printf("#define TTD_BIG_ENDIAN\n");
+ printf("#else\n");
+ printf("#define TTD_LITTLE_ENDIAN\n");
+ printf("#endif\n");
+ } else {
+ if ( *(short *) EndianTest == 1 )
+ printf("#define TTD_LITTLE_ENDIAN\n");
+ else
+ printf("#define TTD_BIG_ENDIAN\n");
+ }
+ }
+ }
+ printf("#endif\n");
+
+ return 0;
+}
diff --git a/src/engine.c b/src/engine.c
new file mode 100644
index 000000000..0a4b21c3d
--- /dev/null
+++ b/src/engine.c
@@ -0,0 +1,650 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "debug.h"
+#include "functions.h"
+#include "table/strings.h"
+#include "engine.h"
+#include "gfx.h"
+#include "player.h"
+#include "command.h"
+#include "vehicle.h"
+#include "news.h"
+#include "saveload.h"
+#include "variables.h"
+#include "train.h"
+#include "newgrf_cargo.h"
+#include "date.h"
+#include "table/engines.h"
+
+EngineInfo _engine_info[TOTAL_NUM_ENGINES];
+RailVehicleInfo _rail_vehicle_info[NUM_TRAIN_ENGINES];
+ShipVehicleInfo _ship_vehicle_info[NUM_SHIP_ENGINES];
+AircraftVehicleInfo _aircraft_vehicle_info[NUM_AIRCRAFT_ENGINES];
+RoadVehicleInfo _road_vehicle_info[NUM_ROAD_ENGINES];
+
+enum {
+ ENGINE_AVAILABLE = 1,
+ ENGINE_INTRODUCING = 2,
+ ENGINE_PREVIEWING = 4,
+};
+
+enum {
+ YEAR_ENGINE_AGING_STOPS = 2050,
+};
+
+
+void ShowEnginePreviewWindow(EngineID engine);
+
+void DeleteCustomEngineNames(void)
+{
+ uint i;
+ StringID old;
+
+ for (i = 0; i != TOTAL_NUM_ENGINES; i++) {
+ old = _engine_name_strings[i];
+ _engine_name_strings[i] = i + STR_8000_KIRBY_PAUL_TANK_STEAM;
+ DeleteName(old);
+ }
+
+ _vehicle_design_names &= ~1;
+}
+
+void LoadCustomEngineNames(void)
+{
+ /* XXX: not done */
+ DEBUG(misc, 1, "LoadCustomEngineNames: not done");
+}
+
+static void SetupEngineNames(void)
+{
+ StringID *name;
+
+ for (name = _engine_name_strings; name != endof(_engine_name_strings); name++)
+ *name = STR_SV_EMPTY;
+
+ DeleteCustomEngineNames();
+ LoadCustomEngineNames();
+}
+
+static void AdjustAvailAircraft(void)
+{
+ byte avail = 0;
+ if (_cur_year >= 1955) avail |= 2; // big airport
+ if (_cur_year < 1960 || _patches.always_small_airport) avail |= 1; // small airport
+ if (_cur_year >= 1963) avail |= 4; // enable heliport
+
+ if (avail != _avail_aircraft) {
+ _avail_aircraft = avail;
+ InvalidateWindow(WC_BUILD_STATION, 0);
+ }
+}
+
+static void CalcEngineReliability(Engine *e)
+{
+ uint age = e->age;
+
+ if (age < e->duration_phase_1) {
+ uint start = e->reliability_start;
+ e->reliability = age * (e->reliability_max - start) / e->duration_phase_1 + start;
+ } else if ((age -= e->duration_phase_1) < e->duration_phase_2 || _patches.never_expire_vehicles) {
+ /* We are at the peak of this engines life. It will have max reliability.
+ * This is also true if the engines never expire. They will not go bad over time */
+ e->reliability = e->reliability_max;
+ } else if ((age -= e->duration_phase_2) < e->duration_phase_3) {
+ uint max = e->reliability_max;
+ e->reliability = (int)age * (int)(e->reliability_final - max) / e->duration_phase_3 + max;
+ } else {
+ /* time's up for this engine.
+ * We will now completely retire this design */
+ e->player_avail = 0;
+ e->reliability = e->reliability_final;
+ InvalidateWindowClassesData(WC_BUILD_VEHICLE); // Kick this engine out of the lists
+ }
+ InvalidateWindowClasses(WC_BUILD_VEHICLE); // Update to show the new reliability
+}
+
+void AddTypeToEngines(void)
+{
+ Engine* e = _engines;
+
+ do e->type = VEH_Train; while (++e < &_engines[ROAD_ENGINES_INDEX]);
+ do e->type = VEH_Road; while (++e < &_engines[SHIP_ENGINES_INDEX]);
+ do e->type = VEH_Ship; while (++e < &_engines[AIRCRAFT_ENGINES_INDEX]);
+ do e->type = VEH_Aircraft; while (++e < &_engines[TOTAL_NUM_ENGINES]);
+ do e->type = VEH_Special; while (++e < endof(_engines));
+}
+
+void StartupEngines(void)
+{
+ Engine *e;
+ const EngineInfo *ei;
+ /* Aging of vehicles stops, so account for that when starting late */
+ const Date aging_date = min(_date, ConvertYMDToDate(YEAR_ENGINE_AGING_STOPS, 0, 1));
+
+ SetupEngineNames();
+
+ for (e = _engines, ei = _engine_info; e != endof(_engines); e++, ei++) {
+ uint32 r;
+
+ e->age = 0;
+ e->railtype = ei->railtype;
+ e->flags = 0;
+ e->player_avail = 0;
+
+ // The magic value of 729 days below comes from the NewGRF spec. If the
+ // base intro date is before 1922 then the random number of days is not
+ // added.
+ r = Random();
+ e->intro_date = ei->base_intro <= ConvertYMDToDate(1922, 0, 1) ? ei->base_intro : (Date)GB(r, 0, 9) + ei->base_intro;
+ if (e->intro_date <= _date) {
+ e->age = (aging_date - e->intro_date) >> 5;
+ e->player_avail = (byte)-1;
+ e->flags |= ENGINE_AVAILABLE;
+ }
+
+ e->reliability_start = GB(r, 16, 14) + 0x7AE0;
+ r = Random();
+ e->reliability_max = GB(r, 0, 14) + 0xBFFF;
+ e->reliability_final = GB(r, 16, 14) + 0x3FFF;
+
+ r = Random();
+ e->duration_phase_1 = GB(r, 0, 5) + 7;
+ 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->unk2&0x7F) << 2;
+
+ /* my invented flag for something that is a wagon */
+ if (ei->unk2 & 0x80) {
+ e->age = 0xFFFF;
+ } else {
+ CalcEngineReliability(e);
+ }
+
+ e->lifelength = ei->lifelength + _patches.extend_vehicle_life;
+
+ // prevent certain engines from ever appearing.
+ if (!HASBIT(ei->climates, _opt.landscape)) {
+ e->flags |= ENGINE_AVAILABLE;
+ e->player_avail = 0;
+ }
+
+ /* This sets up type for the engine
+ * It is needed if you want to ask the engine what type it is
+ * It should hopefully be the same as when you ask a vehicle what it is
+ * but using this, you can ask what type an engine number is
+ * even if it is not a vehicle (yet)*/
+ }
+
+ AdjustAvailAircraft();
+}
+
+static void AcceptEnginePreview(Engine *e, PlayerID player)
+{
+ Player *p = GetPlayer(player);
+
+ assert(e->railtype < RAILTYPE_END);
+ SETBIT(e->player_avail, player);
+ SETBIT(p->avail_railtypes, e->railtype);
+
+ e->preview_player = 0xFF;
+ if (player == _local_player) {
+ InvalidateWindowClassesData(WC_BUILD_VEHICLE);
+ InvalidateWindowClasses(WC_REPLACE_VEHICLE);
+ }
+}
+
+static PlayerID GetBestPlayer(PlayerID pp)
+{
+ const Player *p;
+ int32 best_hist;
+ PlayerID best_player;
+ uint mask = 0;
+
+ do {
+ best_hist = -1;
+ best_player = PLAYER_SPECTATOR;
+ FOR_ALL_PLAYERS(p) {
+ if (p->is_active && p->block_preview == 0 && !HASBIT(mask, p->index) &&
+ p->old_economy[0].performance_history > best_hist) {
+ best_hist = p->old_economy[0].performance_history;
+ best_player = p->index;
+ }
+ }
+
+ if (best_player == PLAYER_SPECTATOR) return PLAYER_SPECTATOR;
+
+ SETBIT(mask, best_player);
+ } while (--pp != 0);
+
+ return best_player;
+}
+
+void EnginesDailyLoop(void)
+{
+ EngineID i;
+
+ if (_cur_year >= YEAR_ENGINE_AGING_STOPS) return;
+
+ for (i = 0; i != lengthof(_engines); i++) {
+ Engine *e = &_engines[i];
+
+ if (e->flags & ENGINE_INTRODUCING) {
+ if (e->flags & ENGINE_PREVIEWING) {
+ if (e->preview_player != 0xFF && !--e->preview_wait) {
+ e->flags &= ~ENGINE_PREVIEWING;
+ DeleteWindowById(WC_ENGINE_PREVIEW, i);
+ e->preview_player++;
+ }
+ } else if (e->preview_player != 0xFF) {
+ PlayerID best_player = GetBestPlayer(e->preview_player);
+
+ if (best_player == PLAYER_SPECTATOR) {
+ e->preview_player = 0xFF;
+ continue;
+ }
+
+ if (!IsHumanPlayer(best_player)) {
+ /* XXX - TTDBUG: TTD has a bug here ???? */
+ AcceptEnginePreview(e, best_player);
+ } else {
+ e->flags |= ENGINE_PREVIEWING;
+ e->preview_wait = 20;
+ if (IsInteractivePlayer(best_player)) ShowEnginePreviewWindow(i);
+ }
+ }
+ }
+ }
+}
+
+/** Accept an engine prototype. XXX - it is possible that the top-player
+ * changes while you are waiting to accept the offer? Then it becomes invalid
+ * @param tile unused
+ * @param p1 engine-prototype offered
+ * @param p2 unused
+ */
+int32 CmdWantEnginePreview(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Engine *e;
+
+ if (!IsEngineIndex(p1)) return CMD_ERROR;
+ e = GetEngine(p1);
+ if (GetBestPlayer(e->preview_player) != _current_player) return CMD_ERROR;
+
+ if (flags & DC_EXEC) AcceptEnginePreview(e, _current_player);
+
+ return 0;
+}
+
+// Determine if an engine type is a wagon (and not a loco)
+static bool IsWagon(EngineID index)
+{
+ return index < NUM_TRAIN_ENGINES && RailVehInfo(index)->flags & RVI_WAGON;
+}
+
+static void NewVehicleAvailable(Engine *e)
+{
+ Vehicle *v;
+ Player *p;
+ EngineID index = e - _engines;
+
+ // In case the player didn't build the vehicle during the intro period,
+ // prevent that player from getting future intro periods for a while.
+ if (e->flags & ENGINE_INTRODUCING) {
+ FOR_ALL_PLAYERS(p) {
+ uint block_preview = p->block_preview;
+
+ if (!HASBIT(e->player_avail, p->index)) continue;
+
+ /* We assume the user did NOT build it.. prove me wrong ;) */
+ p->block_preview = 20;
+
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == VEH_Train || v->type == VEH_Road || v->type == VEH_Ship ||
+ (v->type == VEH_Aircraft && v->subtype <= 2)) {
+ if (v->owner == p->index && v->engine_type == index) {
+ /* The user did prove me wrong, so restore old value */
+ p->block_preview = block_preview;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ e->flags = (e->flags & ~ENGINE_INTRODUCING) | ENGINE_AVAILABLE;
+ InvalidateWindowClassesData(WC_BUILD_VEHICLE);
+ InvalidateWindowClasses(WC_REPLACE_VEHICLE);
+
+ // Now available for all players
+ e->player_avail = (byte)-1;
+
+ // Do not introduce new rail wagons
+ if (IsWagon(index)) return;
+
+ // make maglev / monorail available
+ FOR_ALL_PLAYERS(p) {
+ if (p->is_active) {
+ assert(e->railtype < RAILTYPE_END);
+ SETBIT(p->avail_railtypes, e->railtype);
+ }
+ }
+
+ if (index < NUM_TRAIN_ENGINES) {
+ AddNewsItem(index, NEWS_FLAGS(NM_CALLBACK, 0, NT_NEW_VEHICLES, DNC_TRAINAVAIL), 0, 0);
+ } else if (index < NUM_TRAIN_ENGINES + NUM_ROAD_ENGINES) {
+ AddNewsItem(index, NEWS_FLAGS(NM_CALLBACK, 0, NT_NEW_VEHICLES, DNC_ROADAVAIL), 0, 0);
+ } else if (index < NUM_TRAIN_ENGINES + NUM_ROAD_ENGINES + NUM_SHIP_ENGINES) {
+ AddNewsItem(index, NEWS_FLAGS(NM_CALLBACK, 0, NT_NEW_VEHICLES, DNC_SHIPAVAIL), 0, 0);
+ } else {
+ AddNewsItem(index, NEWS_FLAGS(NM_CALLBACK, 0, NT_NEW_VEHICLES, DNC_AIRCRAFTAVAIL), 0, 0);
+ }
+}
+
+void EnginesMonthlyLoop(void)
+{
+ Engine *e;
+
+ if (_cur_year < YEAR_ENGINE_AGING_STOPS) {
+ for (e = _engines; e != endof(_engines); e++) {
+ // Age the vehicle
+ if (e->flags & ENGINE_AVAILABLE && e->age != 0xFFFF) {
+ e->age++;
+ CalcEngineReliability(e);
+ }
+
+ if (!(e->flags & ENGINE_AVAILABLE) && _date >= (e->intro_date + 365)) {
+ // Introduce it to all players
+ NewVehicleAvailable(e);
+ } else if (!(e->flags & (ENGINE_AVAILABLE|ENGINE_INTRODUCING)) && _date >= e->intro_date) {
+ // Introduction date has passed.. show introducing dialog to one player.
+ e->flags |= ENGINE_INTRODUCING;
+
+ // Do not introduce new rail wagons
+ if (!IsWagon(e - _engines))
+ e->preview_player = 1; // Give to the player with the highest rating.
+ }
+ }
+ }
+ AdjustAvailAircraft();
+}
+
+/** Rename an engine.
+ * @param tile unused
+ * @param p1 engine ID to rename
+ * @param p2 unused
+ */
+int32 CmdRenameEngine(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ StringID str;
+
+ if (!IsEngineIndex(p1) || _cmd_text[0] == '\0') return CMD_ERROR;
+
+ str = AllocateNameUnique(_cmd_text, 0);
+ if (str == 0) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ StringID old_str = _engine_name_strings[p1];
+ _engine_name_strings[p1] = str;
+ DeleteName(old_str);
+ _vehicle_design_names |= 3;
+ MarkWholeScreenDirty();
+ } else {
+ DeleteName(str);
+ }
+
+ return 0;
+}
+
+
+/*
+ * returns true if an engine is valid, of the specified type, and buildable by
+ * the given player, false otherwise
+ *
+ * engine = index of the engine to check
+ * type = the type the engine should be of (VEH_xxx)
+ * player = index of the player
+ */
+bool IsEngineBuildable(EngineID engine, byte type, PlayerID player)
+{
+ const Engine *e;
+
+ // check if it's an engine that is in the engine array
+ if (!IsEngineIndex(engine)) return false;
+
+ e = GetEngine(engine);
+
+ // check if it's an engine of specified type
+ if (e->type != type) return false;
+
+ // check if it's available
+ if (!HASBIT(e->player_avail, player)) return false;
+
+ return true;
+}
+
+/************************************************************************
+ * Engine Replacement stuff
+ ************************************************************************/
+
+static void EngineRenewPoolNewBlock(uint start_item);
+
+DEFINE_OLD_POOL(EngineRenew, EngineRenew, EngineRenewPoolNewBlock, NULL)
+
+static void EngineRenewPoolNewBlock(uint start_item)
+{
+ EngineRenew *er;
+
+ /* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
+ * TODO - This is just a temporary stage, this will be removed. */
+ for (er = GetEngineRenew(start_item); er != NULL; er = (er->index + 1U < GetEngineRenewPoolSize()) ? GetEngineRenew(er->index + 1U) : NULL) {
+ er->index = start_item++;
+ er->from = INVALID_ENGINE;
+ }
+}
+
+
+static EngineRenew *AllocateEngineRenew(void)
+{
+ EngineRenew *er;
+
+ /* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
+ * TODO - This is just a temporary stage, this will be removed. */
+ for (er = GetEngineRenew(0); er != NULL; er = (er->index + 1U < GetEngineRenewPoolSize()) ? GetEngineRenew(er->index + 1U) : NULL) {
+ if (IsValidEngineRenew(er)) continue;
+
+ er->to = INVALID_ENGINE;
+ er->next = NULL;
+ return er;
+ }
+
+ /* Check if we can add a block to the pool */
+ if (AddBlockToPool(&_EngineRenew_pool)) return AllocateEngineRenew();
+
+ return NULL;
+}
+
+/**
+ * Retrieves the EngineRenew that specifies the replacement of the given
+ * engine type from the given renewlist */
+static EngineRenew *GetEngineReplacement(EngineRenewList erl, EngineID engine)
+{
+ EngineRenew *er = (EngineRenew *)erl;
+
+ while (er) {
+ if (er->from == engine) return er;
+ er = er->next;
+ }
+ return NULL;
+}
+
+void RemoveAllEngineReplacement(EngineRenewList *erl)
+{
+ EngineRenew *er = (EngineRenew *)(*erl);
+ EngineRenew *next;
+
+ while (er) {
+ next = er->next;
+ DeleteEngineRenew(er);
+ er = next;
+ }
+ *erl = NULL; // Empty list
+}
+
+EngineID EngineReplacement(EngineRenewList erl, EngineID engine)
+{
+ const EngineRenew *er = GetEngineReplacement(erl, engine);
+ return er == NULL ? INVALID_ENGINE : er->to;
+}
+
+int32 AddEngineReplacement(EngineRenewList *erl, EngineID old_engine, EngineID new_engine, uint32 flags)
+{
+ EngineRenew *er;
+
+ /* Check if the old vehicle is already in the list */
+ er = GetEngineReplacement(*erl, old_engine);
+ if (er != NULL) {
+ if (flags & DC_EXEC) er->to = new_engine;
+ return 0;
+ }
+
+ er = AllocateEngineRenew();
+ if (er == NULL) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ er->from = old_engine;
+ er->to = new_engine;
+
+ /* Insert before the first element */
+ er->next = (EngineRenew *)(*erl);
+ *erl = (EngineRenewList)er;
+ }
+
+ return 0;
+}
+
+int32 RemoveEngineReplacement(EngineRenewList *erl, EngineID engine, uint32 flags)
+{
+ EngineRenew *er = (EngineRenew *)(*erl);
+ EngineRenew *prev = NULL;
+
+ while (er)
+ {
+ if (er->from == engine) {
+ if (flags & DC_EXEC) {
+ if (prev == NULL) { // First element
+ /* The second becomes the new first element */
+ *erl = (EngineRenewList)er->next;
+ } else {
+ /* Cut this element out */
+ prev->next = er->next;
+ }
+ DeleteEngineRenew(er);
+ }
+ return 0;
+ }
+ prev = er;
+ er = er->next;
+ }
+
+ return CMD_ERROR;
+}
+
+static const SaveLoad _engine_renew_desc[] = {
+ SLE_VAR(EngineRenew, from, SLE_UINT16),
+ SLE_VAR(EngineRenew, to, SLE_UINT16),
+
+ SLE_REF(EngineRenew, next, REF_ENGINE_RENEWS),
+
+ SLE_END()
+};
+
+static void Save_ERNW(void)
+{
+ EngineRenew *er;
+
+ FOR_ALL_ENGINE_RENEWS(er) {
+ SlSetArrayIndex(er->index);
+ SlObject(er, _engine_renew_desc);
+ }
+}
+
+static void Load_ERNW(void)
+{
+ int index;
+
+ while ((index = SlIterateArray()) != -1) {
+ EngineRenew *er;
+
+ if (!AddBlockIfNeeded(&_EngineRenew_pool, index))
+ error("EngineRenews: failed loading savegame: too many EngineRenews");
+
+ er = GetEngineRenew(index);
+ SlObject(er, _engine_renew_desc);
+ }
+}
+
+static const SaveLoad _engine_desc[] = {
+ SLE_CONDVAR(Engine, intro_date, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
+ SLE_CONDVAR(Engine, intro_date, SLE_INT32, 31, SL_MAX_VERSION),
+ SLE_CONDVAR(Engine, age, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
+ SLE_CONDVAR(Engine, age, SLE_INT32, 31, SL_MAX_VERSION),
+ SLE_VAR(Engine, reliability, SLE_UINT16),
+ SLE_VAR(Engine, reliability_spd_dec, SLE_UINT16),
+ SLE_VAR(Engine, reliability_start, SLE_UINT16),
+ SLE_VAR(Engine, reliability_max, SLE_UINT16),
+ SLE_VAR(Engine, reliability_final, SLE_UINT16),
+ SLE_VAR(Engine, duration_phase_1, SLE_UINT16),
+ SLE_VAR(Engine, duration_phase_2, SLE_UINT16),
+ SLE_VAR(Engine, duration_phase_3, SLE_UINT16),
+
+ SLE_VAR(Engine, lifelength, SLE_UINT8),
+ SLE_VAR(Engine, flags, SLE_UINT8),
+ SLE_VAR(Engine, preview_player, SLE_UINT8),
+ SLE_VAR(Engine, preview_wait, SLE_UINT8),
+ SLE_VAR(Engine, railtype, SLE_UINT8),
+ SLE_VAR(Engine, player_avail, SLE_UINT8),
+
+ // reserve extra space in savegame here. (currently 16 bytes)
+ SLE_CONDNULL(16, 2, SL_MAX_VERSION),
+
+ SLE_END()
+};
+
+static void Save_ENGN(void)
+{
+ uint i;
+
+ for (i = 0; i != lengthof(_engines); i++) {
+ SlSetArrayIndex(i);
+ SlObject(&_engines[i], _engine_desc);
+ }
+}
+
+static void Load_ENGN(void)
+{
+ int index;
+ while ((index = SlIterateArray()) != -1) {
+ SlObject(GetEngine(index), _engine_desc);
+ }
+}
+
+static void LoadSave_ENGS(void)
+{
+ SlArray(_engine_name_strings, lengthof(_engine_name_strings), SLE_STRINGID);
+}
+
+const ChunkHandler _engine_chunk_handlers[] = {
+ { 'ENGN', Save_ENGN, Load_ENGN, CH_ARRAY },
+ { 'ENGS', LoadSave_ENGS, LoadSave_ENGS, CH_RIFF },
+ { 'ERNW', Save_ERNW, Load_ERNW, CH_ARRAY | CH_LAST},
+};
+
+void InitializeEngines(void)
+{
+ /* Clean the engine renew pool and create 1 block in it */
+ CleanPool(&_EngineRenew_pool);
+ AddBlockToPool(&_EngineRenew_pool);
+}
diff --git a/src/engine.h b/src/engine.h
new file mode 100644
index 000000000..2fa6b9eb0
--- /dev/null
+++ b/src/engine.h
@@ -0,0 +1,309 @@
+/* $Id$ */
+
+#ifndef ENGINE_H
+#define ENGINE_H
+
+/** @file engine.h */
+
+#include "oldpool.h"
+
+typedef struct RailVehicleInfo {
+ byte image_index;
+ byte flags; /* 1=multihead engine, 2=wagon */
+ byte base_cost;
+ uint16 max_speed;
+ uint16 power;
+ uint16 weight;
+ byte running_cost_base;
+ byte running_cost_class;
+ byte engclass; // 0: steam, 1: diesel, 2: electric
+ byte capacity;
+ CargoID cargo_type;
+ byte ai_rank;
+ uint16 pow_wag_power;
+ byte pow_wag_weight;
+ byte visual_effect; // NOTE: this is not 100% implemented yet, at the moment it is only used as a 'fallback' value
+ // for when the 'powered wagon' callback fails. But it should really also determine what
+ // kind of visual effect to generate for a vehicle (default, steam, diesel, electric).
+ // Same goes for the callback result, which atm is only used to check if a wagon is powered.
+ byte shorten_factor; // length on main map for this type is 8 - shorten_factor
+ byte tractive_effort; ///< Tractive effort coefficient
+ byte user_def_data; ///! Property 0x25: "User-defined bit mask" Used only for (very few) NewGRF vehicles
+} RailVehicleInfo;
+
+typedef struct ShipVehicleInfo {
+ byte image_index;
+ byte base_cost;
+ uint16 max_speed;
+ CargoID cargo_type;
+ uint16 capacity;
+ byte running_cost;
+ byte sfx;
+ byte refittable;
+} ShipVehicleInfo;
+
+// Aircraft subtypes
+enum {
+ AIR_CTOL = 1, // Conventional Take Off and Landing, i.e. planes
+ AIR_FAST = 2
+};
+
+typedef struct AircraftVehicleInfo {
+ byte image_index;
+ byte base_cost;
+ byte running_cost;
+ byte subtype;
+ byte sfx;
+ byte acceleration;
+ byte max_speed;
+ byte mail_capacity;
+ uint16 passenger_capacity;
+} AircraftVehicleInfo;
+
+typedef struct RoadVehicleInfo {
+ byte image_index;
+ byte base_cost;
+ byte running_cost;
+ byte sfx;
+ byte max_speed;
+ byte capacity;
+ CargoID cargo_type;
+} RoadVehicleInfo;
+
+/** Information about a vehicle
+ * @see table/engines.h
+ */
+typedef struct EngineInfo {
+ Date base_intro;
+ byte unk2; ///< Carriages have the highest bit set in this one
+ Year lifelength;
+ Year base_life;
+ byte load_amount;
+ byte railtype:4;
+ byte climates:4;
+ uint32 refit_mask;
+ byte refit_cost;
+ byte misc_flags;
+ byte callbackmask;
+} EngineInfo;
+
+typedef struct Engine {
+ Date intro_date;
+ Date age;
+ uint16 reliability;
+ uint16 reliability_spd_dec;
+ uint16 reliability_start, reliability_max, reliability_final;
+ uint16 duration_phase_1, duration_phase_2, duration_phase_3;
+ byte lifelength;
+ byte flags;
+ byte preview_player;
+ byte preview_wait;
+ byte railtype;
+ byte player_avail;
+ byte type; // type, ie VEH_Road, VEH_Train, etc. Same as in vehicle.h
+} Engine;
+
+/**
+ * EngineInfo.misc_flags is a bitmask, with the following values
+ */
+enum {
+ EF_RAIL_TILTS = 0, ///< Rail vehicle tilts in curves (unsupported)
+ EF_ROAD_TRAM = 0, ///< Road vehicle is a tram/light rail vehicle (unsup)
+ EF_USES_2CC = 1, ///< Vehicle uses two company colours
+ EF_RAIL_IS_MU = 2, ///< Rail vehicle is a multiple-unit (DMU/EMU)
+};
+
+enum {
+ RVI_MULTIHEAD = 1,
+ RVI_WAGON = 2,
+};
+
+enum {
+ NUM_VEHICLE_TYPES = 6
+};
+
+enum {
+ INVALID_ENGINE = 0xFFFF,
+};
+
+void AddTypeToEngines(void);
+void StartupEngines(void);
+
+
+void DrawTrainEngine(int x, int y, EngineID engine, uint32 image_ormod);
+void DrawRoadVehEngine(int x, int y, EngineID engine, uint32 image_ormod);
+void DrawShipEngine(int x, int y, EngineID engine, uint32 image_ormod);
+void DrawAircraftEngine(int x, int y, EngineID engine, uint32 image_ormod);
+
+void LoadCustomEngineNames(void);
+void DeleteCustomEngineNames(void);
+
+bool IsEngineBuildable(EngineID engine, byte type, PlayerID player);
+
+enum {
+ NUM_NORMAL_RAIL_ENGINES = 54,
+ NUM_MONORAIL_ENGINES = 30,
+ NUM_MAGLEV_ENGINES = 32,
+ NUM_TRAIN_ENGINES = NUM_NORMAL_RAIL_ENGINES + NUM_MONORAIL_ENGINES + NUM_MAGLEV_ENGINES,
+ NUM_ROAD_ENGINES = 88,
+ NUM_SHIP_ENGINES = 11,
+ NUM_AIRCRAFT_ENGINES = 41,
+ TOTAL_NUM_ENGINES = NUM_TRAIN_ENGINES + NUM_ROAD_ENGINES + NUM_SHIP_ENGINES + NUM_AIRCRAFT_ENGINES,
+ AIRCRAFT_ENGINES_INDEX = NUM_TRAIN_ENGINES + NUM_ROAD_ENGINES + NUM_SHIP_ENGINES,
+ SHIP_ENGINES_INDEX = NUM_TRAIN_ENGINES + NUM_ROAD_ENGINES,
+ ROAD_ENGINES_INDEX = NUM_TRAIN_ENGINES,
+};
+VARDEF Engine _engines[TOTAL_NUM_ENGINES];
+#define FOR_ALL_ENGINES(e) for (e = _engines; e != endof(_engines); e++)
+
+static inline Engine* GetEngine(EngineID i)
+{
+ assert(i < lengthof(_engines));
+ return &_engines[i];
+}
+
+VARDEF StringID _engine_name_strings[TOTAL_NUM_ENGINES];
+
+static inline bool IsEngineIndex(uint index)
+{
+ return index < TOTAL_NUM_ENGINES;
+}
+
+/* Access Vehicle Data */
+//#include "table/engines.h"
+extern const EngineInfo orig_engine_info[TOTAL_NUM_ENGINES];
+extern const RailVehicleInfo orig_rail_vehicle_info[NUM_TRAIN_ENGINES];
+extern const ShipVehicleInfo orig_ship_vehicle_info[NUM_SHIP_ENGINES];
+extern const AircraftVehicleInfo orig_aircraft_vehicle_info[NUM_AIRCRAFT_ENGINES];
+extern const RoadVehicleInfo orig_road_vehicle_info[NUM_ROAD_ENGINES];
+
+extern EngineInfo _engine_info[TOTAL_NUM_ENGINES];
+extern RailVehicleInfo _rail_vehicle_info[NUM_TRAIN_ENGINES];
+extern ShipVehicleInfo _ship_vehicle_info[NUM_SHIP_ENGINES];
+extern AircraftVehicleInfo _aircraft_vehicle_info[NUM_AIRCRAFT_ENGINES];
+extern RoadVehicleInfo _road_vehicle_info[NUM_ROAD_ENGINES];
+
+static inline const EngineInfo *EngInfo(EngineID e)
+{
+ assert(e < lengthof(_engine_info));
+ return &_engine_info[e];
+}
+
+static inline const RailVehicleInfo* RailVehInfo(EngineID e)
+{
+ assert(e < lengthof(_rail_vehicle_info));
+ return &_rail_vehicle_info[e];
+}
+
+static inline const ShipVehicleInfo* ShipVehInfo(EngineID e)
+{
+ assert(e >= SHIP_ENGINES_INDEX && e < SHIP_ENGINES_INDEX + lengthof(_ship_vehicle_info));
+ return &_ship_vehicle_info[e - SHIP_ENGINES_INDEX];
+}
+
+static inline const AircraftVehicleInfo* AircraftVehInfo(EngineID e)
+{
+ assert(e >= AIRCRAFT_ENGINES_INDEX && e < AIRCRAFT_ENGINES_INDEX + lengthof(_aircraft_vehicle_info));
+ return &_aircraft_vehicle_info[e - AIRCRAFT_ENGINES_INDEX];
+}
+
+static inline const RoadVehicleInfo* RoadVehInfo(EngineID e)
+{
+ assert(e >= ROAD_ENGINES_INDEX && e < ROAD_ENGINES_INDEX + lengthof(_road_vehicle_info));
+ return &_road_vehicle_info[e - ROAD_ENGINES_INDEX];
+}
+
+/************************************************************************
+ * Engine Replacement stuff
+ ************************************************************************/
+
+/**
+ * Struct to store engine replacements. DO NOT USE outside of engine.c. Is
+ * placed here so the only exception to this rule, the saveload code, can use
+ * it.
+ */
+struct EngineRenew {
+ EngineRenewID index;
+ EngineID from;
+ EngineID to;
+ struct EngineRenew *next;
+};
+
+typedef struct EngineRenew EngineRenew;
+
+/**
+ * Memory pool for engine renew elements. DO NOT USE outside of engine.c. Is
+ * placed here so the only exception to this rule, the saveload code, can use
+ * it.
+ */
+DECLARE_OLD_POOL(EngineRenew, EngineRenew, 3, 8000)
+
+/**
+ * Check if a EngineRenew really exists.
+ */
+static inline bool IsValidEngineRenew(const EngineRenew *er)
+{
+ return er->from != INVALID_ENGINE;
+}
+
+static inline void DeleteEngineRenew(EngineRenew *er)
+{
+ er->from = INVALID_ENGINE;
+}
+
+#define FOR_ALL_ENGINE_RENEWS_FROM(er, start) for (er = GetEngineRenew(start); er != NULL; er = (er->index + 1U < GetEngineRenewPoolSize()) ? GetEngineRenew(er->index + 1U) : NULL) if (er->from != INVALID_ENGINE) if (IsValidEngineRenew(er))
+#define FOR_ALL_ENGINE_RENEWS(er) FOR_ALL_ENGINE_RENEWS_FROM(er, 0)
+
+
+/**
+ * A list to group EngineRenew directives together (such as per-player).
+ */
+typedef EngineRenew* EngineRenewList;
+
+/**
+ * Remove all engine replacement settings for the player.
+ * @param er The renewlist for a given player.
+ * @return The new renewlist for the player.
+ */
+void RemoveAllEngineReplacement(EngineRenewList* erl);
+
+/**
+ * Retrieve the engine replacement in a given renewlist for an original engine type.
+ * @param erl The renewlist to search in.
+ * @param engine Engine type to be replaced.
+ * @return The engine type to replace with, or INVALID_ENGINE if no
+ * replacement is in the list.
+ */
+EngineID EngineReplacement(EngineRenewList erl, EngineID engine);
+
+/**
+ * Add an engine replacement to the given renewlist.
+ * @param erl The renewlist to add to.
+ * @param old_engine The original engine type.
+ * @param new_engine The replacement engine type.
+ * @param flags The calling command flags.
+ * @return 0 on success, CMD_ERROR on failure.
+ */
+int32 AddEngineReplacement(EngineRenewList* erl, EngineID old_engine, EngineID new_engine, uint32 flags);
+
+/**
+ * Remove an engine replacement from a given renewlist.
+ * @param erl The renewlist from which to remove the replacement
+ * @param engine The original engine type.
+ * @param flags The calling command flags.
+ * @return 0 on success, CMD_ERROR on failure.
+ */
+int32 RemoveEngineReplacement(EngineRenewList* erl, EngineID engine, uint32 flags);
+
+/* Engine list manipulators - current implementation is only C wrapper of CBlobT<EngineID> class (helpers.cpp) */
+void EngList_Create(EngineList *el); ///< Creates engine list
+void EngList_Destroy(EngineList *el); ///< Deallocate and destroy engine list
+uint EngList_Count(const EngineList *el); ///< Returns number of items in the engine list
+void EngList_Add(EngineList *el, EngineID eid); ///< Append one item at the end of engine list
+EngineID* EngList_Items(EngineList *el); ///< Returns engine list items as C array
+void EngList_RemoveAll(EngineList *el); ///< Removes all items from engine list
+typedef int CDECL EngList_SortTypeFunction(const void*, const void*); ///< argument type for EngList_Sort()
+void EngList_Sort(EngineList *el, EngList_SortTypeFunction compare); ///< qsort of the engine list
+void EngList_SortPartial(EngineList *el, EngList_SortTypeFunction compare, uint begin, uint num_items); ///< qsort of specified portion of the engine list
+
+#endif /* ENGINE_H */
diff --git a/src/engine_gui.c b/src/engine_gui.c
new file mode 100644
index 000000000..31f175cf1
--- /dev/null
+++ b/src/engine_gui.c
@@ -0,0 +1,285 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "table/strings.h"
+#include "table/sprites.h"
+#include "functions.h"
+#include "window.h"
+#include "gui.h"
+#include "viewport.h"
+#include "gfx.h"
+#include "engine.h"
+#include "command.h"
+#include "news.h"
+#include "variables.h"
+#include "newgrf_engine.h"
+
+
+static StringID GetEngineCategoryName(EngineID engine)
+{
+ if (engine < NUM_TRAIN_ENGINES) {
+ switch (GetEngine(engine)->railtype) {
+ case RAILTYPE_RAIL: return STR_8102_RAILROAD_LOCOMOTIVE;
+ case RAILTYPE_ELECTRIC: return STR_8102_RAILROAD_LOCOMOTIVE;
+ case RAILTYPE_MONO: return STR_8106_MONORAIL_LOCOMOTIVE;
+ case RAILTYPE_MAGLEV: return STR_8107_MAGLEV_LOCOMOTIVE;
+ }
+ }
+
+ if (engine < NUM_TRAIN_ENGINES + NUM_ROAD_ENGINES)
+ return STR_8103_ROAD_VEHICLE;
+
+ if (engine < NUM_TRAIN_ENGINES + NUM_ROAD_ENGINES + NUM_SHIP_ENGINES)
+ return STR_8105_SHIP;
+
+ return STR_8104_AIRCRAFT;
+}
+
+static const Widget _engine_preview_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 5, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 5, 11, 299, 0, 13, STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 5, 0, 299, 14, 191, 0x0, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 5, 85, 144, 172, 183, STR_00C9_NO, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 5, 155, 214, 172, 183, STR_00C8_YES, STR_NULL},
+{ WIDGETS_END},
+};
+
+typedef void DrawEngineProc(int x, int y, EngineID engine, uint32 image_ormod);
+typedef void DrawEngineInfoProc(EngineID, int x, int y, int maxw);
+
+typedef struct DrawEngineInfo {
+ DrawEngineProc *engine_proc;
+ DrawEngineInfoProc *info_proc;
+} DrawEngineInfo;
+
+static void DrawTrainEngineInfo(EngineID engine, int x, int y, int maxw);
+static void DrawRoadVehEngineInfo(EngineID engine, int x, int y, int maxw);
+static void DrawShipEngineInfo(EngineID engine, int x, int y, int maxw);
+static void DrawAircraftEngineInfo(EngineID engine, int x, int y, int maxw);
+
+static const DrawEngineInfo _draw_engine_list[4] = {
+ {DrawTrainEngine,DrawTrainEngineInfo},
+ {DrawRoadVehEngine,DrawRoadVehEngineInfo},
+ {DrawShipEngine,DrawShipEngineInfo},
+ {DrawAircraftEngine,DrawAircraftEngineInfo},
+};
+
+static void EnginePreviewWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ EngineID engine = w->window_number;
+ const DrawEngineInfo* dei;
+ int width;
+
+ DrawWindowWidgets(w);
+
+ SetDParam(0, GetEngineCategoryName(engine));
+ DrawStringMultiCenter(150, 44, STR_8101_WE_HAVE_JUST_DESIGNED_A, 296);
+
+ DrawStringCentered(w->width >> 1, 80, GetCustomEngineName(engine), 0x10);
+
+ (dei = _draw_engine_list,engine < NUM_TRAIN_ENGINES) ||
+ (dei++,engine < NUM_TRAIN_ENGINES + NUM_ROAD_ENGINES) ||
+ (dei++,engine < NUM_TRAIN_ENGINES + NUM_ROAD_ENGINES + NUM_SHIP_ENGINES) ||
+ (dei++, true);
+
+ width = w->width;
+ dei->engine_proc(width >> 1, 100, engine, 0);
+ dei->info_proc(engine, width >> 1, 130, width - 52);
+ break;
+ }
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 4:
+ DoCommandP(0, w->window_number, 0, NULL, CMD_WANT_ENGINE_PREVIEW);
+ /* Fallthrough */
+ case 3:
+ DeleteWindow(w);
+ break;
+ }
+ break;
+ }
+}
+
+static const WindowDesc _engine_preview_desc = {
+ WDP_CENTER, WDP_CENTER, 300, 192,
+ WC_ENGINE_PREVIEW,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _engine_preview_widgets,
+ EnginePreviewWndProc
+};
+
+
+void ShowEnginePreviewWindow(EngineID engine)
+{
+ AllocateWindowDescFront(&_engine_preview_desc, engine);
+}
+
+static void DrawTrainEngineInfo(EngineID engine, int x, int y, int maxw)
+{
+ const RailVehicleInfo *rvi = RailVehInfo(engine);
+ uint multihead = (rvi->flags & RVI_MULTIHEAD) ? 1 : 0;
+
+ SetDParam(0, (_price.build_railvehicle >> 3) * rvi->base_cost >> 5);
+ SetDParam(2, rvi->max_speed);
+ SetDParam(3, rvi->power << multihead);
+ SetDParam(1, rvi->weight << multihead);
+
+ SetDParam(4, rvi->running_cost_base * _price.running_rail[rvi->running_cost_class] >> 8 << multihead);
+
+ if (rvi->capacity != 0) {
+ SetDParam(5, rvi->cargo_type);
+ SetDParam(6, rvi->capacity << multihead);
+ } else {
+ SetDParam(5, CT_INVALID);
+ }
+ DrawStringMultiCenter(x, y, STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER, maxw);
+}
+
+void DrawNewsNewTrainAvail(Window *w)
+{
+ EngineID engine;
+
+ DrawNewsBorder(w);
+
+ engine = WP(w,news_d).ni->string_id;
+ SetDParam(0, GetEngineCategoryName(engine));
+ DrawStringMultiCenter(w->width >> 1, 20, STR_8859_NEW_NOW_AVAILABLE, w->width - 2);
+
+ GfxFillRect(25, 56, w->width - 25, w->height - 2, 10);
+
+ SetDParam(0, GetCustomEngineName(engine));
+ DrawStringMultiCenter(w->width >> 1, 57, STR_885A, w->width - 2);
+
+ DrawTrainEngine(w->width >> 1, 88, engine, 0);
+ GfxFillRect(25, 56, w->width - 56, 112, 0x323 | USE_COLORTABLE);
+ DrawTrainEngineInfo(engine, w->width >> 1, 129, w->width - 52);
+}
+
+StringID GetNewsStringNewTrainAvail(const NewsItem *ni)
+{
+ EngineID engine = ni->string_id;
+ SetDParam(0, STR_8859_NEW_NOW_AVAILABLE);
+ SetDParam(1, GetEngineCategoryName(engine));
+ SetDParam(2, GetCustomEngineName(engine));
+ return STR_02B6;
+}
+
+static void DrawAircraftEngineInfo(EngineID engine, int x, int y, int maxw)
+{
+ const AircraftVehicleInfo *avi = AircraftVehInfo(engine);
+ SetDParam(0, (_price.aircraft_base >> 3) * avi->base_cost >> 5);
+ SetDParam(1, avi->max_speed * 128 / 10);
+ SetDParam(2, avi->passenger_capacity);
+ SetDParam(3, avi->mail_capacity);
+ SetDParam(4, avi->running_cost * _price.aircraft_running >> 8);
+
+ DrawStringMultiCenter(x, y, STR_A02E_COST_MAX_SPEED_CAPACITY, maxw);
+}
+
+void DrawNewsNewAircraftAvail(Window *w)
+{
+ EngineID engine;
+
+ DrawNewsBorder(w);
+
+ engine = WP(w,news_d).ni->string_id;
+
+ DrawStringMultiCenter(w->width >> 1, 20, STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE, w->width - 2);
+ GfxFillRect(25, 56, w->width - 25, w->height - 2, 10);
+
+ SetDParam(0, GetCustomEngineName(engine));
+ DrawStringMultiCenter(w->width >> 1, 57, STR_A02D, w->width - 2);
+
+ DrawAircraftEngine(w->width >> 1, 93, engine, 0);
+ GfxFillRect(25, 56, w->width - 56, 110, 0x323 | USE_COLORTABLE);
+ DrawAircraftEngineInfo(engine, w->width >> 1, 131, w->width - 52);
+}
+
+StringID GetNewsStringNewAircraftAvail(const NewsItem *ni)
+{
+ EngineID engine = ni->string_id;
+ SetDParam(0, STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE);
+ SetDParam(1, GetCustomEngineName(engine));
+ return STR_02B6;
+}
+
+static void DrawRoadVehEngineInfo(EngineID engine, int x, int y, int maxw)
+{
+ const RoadVehicleInfo *rvi = RoadVehInfo(engine);
+
+ SetDParam(0, (_price.roadveh_base >> 3) * rvi->base_cost >> 5);
+ SetDParam(1, rvi->max_speed / 2);
+ SetDParam(2, rvi->running_cost * _price.roadveh_running >> 8);
+ SetDParam(3, rvi->cargo_type);
+ SetDParam(4, rvi->capacity);
+
+ DrawStringMultiCenter(x, y, STR_902A_COST_SPEED_RUNNING_COST, maxw);
+}
+
+void DrawNewsNewRoadVehAvail(Window *w)
+{
+ EngineID engine;
+
+ DrawNewsBorder(w);
+
+ engine = WP(w,news_d).ni->string_id;
+ DrawStringMultiCenter(w->width >> 1, 20, STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE, w->width - 2);
+ GfxFillRect(25, 56, w->width - 25, w->height - 2, 10);
+
+ SetDParam(0, GetCustomEngineName(engine));
+ DrawStringMultiCenter(w->width >> 1, 57, STR_9029, w->width - 2);
+
+ DrawRoadVehEngine(w->width >> 1, 88, engine, 0);
+ GfxFillRect(25, 56, w->width - 56, 112, 0x323 | USE_COLORTABLE);
+ DrawRoadVehEngineInfo(engine, w->width >> 1, 129, w->width - 52);
+}
+
+StringID GetNewsStringNewRoadVehAvail(const NewsItem *ni)
+{
+ EngineID engine = ni->string_id;
+ SetDParam(0, STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE);
+ SetDParam(1, GetCustomEngineName(engine));
+ return STR_02B6;
+}
+
+static void DrawShipEngineInfo(EngineID engine, int x, int y, int maxw)
+{
+ const ShipVehicleInfo *svi = ShipVehInfo(engine);
+ SetDParam(0, svi->base_cost * (_price.ship_base >> 3) >> 5);
+ SetDParam(1, svi->max_speed / 2);
+ SetDParam(2, svi->cargo_type);
+ SetDParam(3, svi->capacity);
+ SetDParam(4, svi->running_cost * _price.ship_running >> 8);
+ DrawStringMultiCenter(x, y, STR_982E_COST_MAX_SPEED_CAPACITY, maxw);
+}
+
+void DrawNewsNewShipAvail(Window *w)
+{
+ EngineID engine;
+
+ DrawNewsBorder(w);
+
+ engine = WP(w,news_d).ni->string_id;
+
+ DrawStringMultiCenter(w->width >> 1, 20, STR_982C_NEW_SHIP_NOW_AVAILABLE, w->width - 2);
+ GfxFillRect(25, 56, w->width - 25, w->height - 2, 10);
+
+ SetDParam(0, GetCustomEngineName(engine));
+ DrawStringMultiCenter(w->width >> 1, 57, STR_982D, w->width - 2);
+
+ DrawShipEngine(w->width >> 1, 93, engine, 0);
+ GfxFillRect(25, 56, w->width - 56, 110, 0x323 | USE_COLORTABLE);
+ DrawShipEngineInfo(engine, w->width >> 1, 131, w->width - 52);
+}
+
+StringID GetNewsStringNewShipAvail(const NewsItem *ni)
+{
+ EngineID engine = ni->string_id;
+ SetDParam(0, STR_982C_NEW_SHIP_NOW_AVAILABLE);
+ SetDParam(1, GetCustomEngineName(engine));
+ return STR_02B6;
+}
diff --git a/src/fileio.c b/src/fileio.c
new file mode 100644
index 000000000..2a09916ea
--- /dev/null
+++ b/src/fileio.c
@@ -0,0 +1,151 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "fileio.h"
+#include "functions.h"
+#include "string.h"
+#include "macros.h"
+#include "variables.h"
+
+/*************************************************/
+/* FILE IO ROUTINES ******************************/
+/*************************************************/
+
+#define FIO_BUFFER_SIZE 512
+
+typedef struct {
+ byte *buffer, *buffer_end; ///< position pointer in local buffer and last valid byte of buffer
+ uint32 pos; ///< current (system) position in file
+ FILE *cur_fh; ///< current file handle
+ FILE *handles[64]; ///< array of file handles we can have open
+ byte buffer_start[FIO_BUFFER_SIZE]; ///< local buffer when read from file
+} Fio;
+
+static Fio _fio;
+
+// Get current position in file
+uint32 FioGetPos(void)
+{
+ return _fio.pos + (_fio.buffer - _fio.buffer_start) - FIO_BUFFER_SIZE;
+}
+
+void FioSeekTo(uint32 pos, int mode)
+{
+ if (mode == SEEK_CUR) pos += FioGetPos();
+ _fio.buffer = _fio.buffer_end = _fio.buffer_start + FIO_BUFFER_SIZE;
+ _fio.pos = pos;
+ fseek(_fio.cur_fh, _fio.pos, SEEK_SET);
+}
+
+// Seek to a file and a position
+void FioSeekToFile(uint32 pos)
+{
+ FILE *f = _fio.handles[pos >> 24];
+ assert(f != NULL);
+ _fio.cur_fh = f;
+ FioSeekTo(GB(pos, 0, 24), SEEK_SET);
+}
+
+byte FioReadByte(void)
+{
+ if (_fio.buffer == _fio.buffer_end) {
+ _fio.pos += FIO_BUFFER_SIZE;
+ fread(_fio.buffer = _fio.buffer_start, 1, FIO_BUFFER_SIZE, _fio.cur_fh);
+ }
+ return *_fio.buffer++;
+}
+
+void FioSkipBytes(int n)
+{
+ for (;;) {
+ int m = min(_fio.buffer_end - _fio.buffer, n);
+ _fio.buffer += m;
+ n -= m;
+ if (n == 0) break;
+ FioReadByte();
+ n--;
+ }
+}
+
+uint16 FioReadWord(void)
+{
+ byte b = FioReadByte();
+ return (FioReadByte() << 8) | b;
+}
+
+uint32 FioReadDword(void)
+{
+ uint b = FioReadWord();
+ return (FioReadWord() << 16) | b;
+}
+
+void FioReadBlock(void *ptr, uint size)
+{
+ FioSeekTo(FioGetPos(), SEEK_SET);
+ _fio.pos += size;
+ fread(ptr, 1, size, _fio.cur_fh);
+}
+
+static inline void FioCloseFile(int slot)
+{
+ if (_fio.handles[slot] != NULL) {
+ fclose(_fio.handles[slot]);
+ _fio.handles[slot] = NULL;
+ }
+}
+
+void FioCloseAll(void)
+{
+ int i;
+
+ for (i = 0; i != lengthof(_fio.handles); i++)
+ FioCloseFile(i);
+}
+
+bool FioCheckFileExists(const char *filename)
+{
+ FILE *f = FioFOpenFile(filename);
+ if (f == NULL) return false;
+
+ fclose(f);
+ return true;
+}
+
+FILE *FioFOpenFile(const char *filename)
+{
+ FILE *f;
+ char buf[MAX_PATH];
+
+ snprintf(buf, lengthof(buf), "%s%s", _paths.data_dir, filename);
+
+ f = fopen(buf, "rb");
+#if !defined(WIN32)
+ if (f == NULL) {
+ strtolower(buf + strlen(_paths.data_dir) - 1);
+ f = fopen(buf, "rb");
+
+#if defined SECOND_DATA_DIR
+ // tries in the 2nd data directory
+ if (f == NULL) {
+ snprintf(buf, lengthof(buf), "%s%s", _paths.second_data_dir, filename);
+ strtolower(buf + strlen(_paths.second_data_dir) - 1);
+ f = fopen(buf, "rb");
+ }
+#endif
+ }
+#endif
+
+ return f;
+}
+
+void FioOpenFile(int slot, const char *filename)
+{
+ FILE *f = FioFOpenFile(filename);
+
+ if (f == NULL) error("Cannot open file '%s%s'", _paths.data_dir, filename);
+
+ FioCloseFile(slot); // if file was opened before, close it
+ _fio.handles[slot] = f;
+ FioSeekToFile(slot << 24);
+}
diff --git a/src/fileio.h b/src/fileio.h
new file mode 100644
index 000000000..6ee58b32c
--- /dev/null
+++ b/src/fileio.h
@@ -0,0 +1,19 @@
+/* $Id$ */
+
+#ifndef FILEIO_H
+#define FILEIO_H
+
+void FioSeekTo(uint32 pos, int mode);
+void FioSeekToFile(uint32 pos);
+uint32 FioGetPos(void);
+byte FioReadByte(void);
+uint16 FioReadWord(void);
+uint32 FioReadDword(void);
+void FioCloseAll(void);
+FILE *FioFOpenFile(const char *filename);
+void FioOpenFile(int slot, const char *filename);
+void FioReadBlock(void *ptr, uint size);
+void FioSkipBytes(int n);
+bool FioCheckFileExists(const char *filename);
+
+#endif /* FILEIO_H */
diff --git a/src/fios.c b/src/fios.c
new file mode 100644
index 000000000..950e26a23
--- /dev/null
+++ b/src/fios.c
@@ -0,0 +1,412 @@
+/* $Id$ */
+
+/** @file fios.c
+ * This file contains functions for building file lists for the save/load dialogs.
+ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "hal.h"
+#include "string.h"
+#include "variables.h"
+#include "functions.h"
+#include "heightmap.h"
+#include "table/strings.h"
+#include "fios.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef WIN32
+# include <io.h>
+#else
+# include <unistd.h>
+# include <dirent.h>
+#endif /* WIN32 */
+
+/* Variables to display file lists */
+int _fios_num;
+
+static char *_fios_path;
+static FiosItem *_fios_items;
+static int _fios_count, _fios_alloc;
+
+/* OS-specific functions are taken from their respective files (win32/unix/os2 .c) */
+extern bool FiosIsRoot(const char *path);
+extern bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb);
+extern void FiosGetDrives(void);
+extern bool FiosGetDiskFreeSpace(const char *path, uint32 *tot);
+
+/* get the name of an oldstyle savegame */
+extern void GetOldSaveGameName(char *title, const char *path, const char *file);
+
+/**
+ * Allocate a new FiosItem.
+ * @return A pointer to the newly allocated FiosItem.
+ */
+FiosItem *FiosAlloc(void)
+{
+ if (_fios_count == _fios_alloc) {
+ _fios_alloc += 256;
+ _fios_items = realloc(_fios_items, _fios_alloc * sizeof(FiosItem));
+ }
+ return &_fios_items[_fios_count++];
+}
+
+/**
+ * Compare two FiosItem's. Used with qsort when sorting the file list.
+ * @param a A pointer to the first FiosItem to compare.
+ * @param a A pointer to the second FiosItem to compare.
+ * @return -1, 0 or 1, depending on how the two items should be sorted.
+ */
+int CDECL compare_FiosItems(const void *a, const void *b)
+{
+ const FiosItem *da = (const FiosItem *)a;
+ const FiosItem *db = (const FiosItem *)b;
+ int r;
+
+ if (_savegame_sort_order & SORT_BY_NAME) {
+ r = strcasecmp(da->title, db->title);
+ } else {
+ r = da->mtime < db->mtime ? -1 : 1;
+ }
+
+ if (_savegame_sort_order & SORT_DESCENDING) r = -r;
+ return r;
+}
+
+/**
+ * Free the list of savegames
+ */
+void FiosFreeSavegameList(void)
+{
+ free(_fios_items);
+ _fios_items = NULL;
+ _fios_alloc = _fios_count = 0;
+}
+
+/**
+ * Get descriptive texts. Returns the path and free space
+ * left on the device
+ * @param path string describing the path
+ * @param total_free total free space in megabytes, optional (can be NULL)
+ * @return StringID describing the path (free space or failure)
+ */
+StringID FiosGetDescText(const char **path, uint32 *total_free)
+{
+ *path = _fios_path;
+ return FiosGetDiskFreeSpace(*path, total_free) ? STR_4005_BYTES_FREE : STR_4006_UNABLE_TO_READ_DRIVE;
+}
+
+/* Browse to a new path based on the passed FiosItem struct
+ * @param *item FiosItem object telling us what to do
+ * @return a string if we have given a file as a target, otherwise NULL */
+char *FiosBrowseTo(const FiosItem *item)
+{
+ char *s;
+ char *path = _fios_path;
+
+ switch (item->type) {
+#if defined(WIN32) || defined(__OS2__)
+ case FIOS_TYPE_DRIVE: sprintf(path, "%c:" PATHSEP, item->title[0]); break;
+#endif
+
+ case FIOS_TYPE_PARENT:
+ /* Check for possible NULL ptr (not required for UNIXes, but AmigaOS-alikes) */
+ if ((s = strrchr(path, PATHSEPCHAR)) != NULL) {
+ s[1] = '\0'; // go up a directory
+ if (!FiosIsRoot(path)) s[0] = '\0';
+ }
+#if defined(__MORPHOS__) || defined(__AMIGAOS__)
+ /* On MorphOS or AmigaOS paths look like: "Volume:directory/subdirectory" */
+ else if ((s = strrchr(path, ':')) != NULL) s[1] = '\0';
+#endif
+ break;
+
+ case FIOS_TYPE_DIR:
+ if (!FiosIsRoot(path)) strcat(path, PATHSEP);
+ strcat(path, item->name);
+ break;
+
+ case FIOS_TYPE_DIRECT:
+ sprintf(path, "%s" PATHSEP, item->name);
+ s = strrchr(path, PATHSEPCHAR);
+ if (s != NULL && s[1] == '\0') s[0] = '\0'; // strip trailing slash
+ break;
+
+ case FIOS_TYPE_FILE:
+ case FIOS_TYPE_OLDFILE:
+ case FIOS_TYPE_SCENARIO:
+ case FIOS_TYPE_OLD_SCENARIO:
+ case FIOS_TYPE_PNG:
+ case FIOS_TYPE_BMP:
+ {
+ static char str_buffr[512];
+
+#if defined(__MORPHOS__) || defined(__AMIGAOS__)
+ /* On MorphOS or AmigaOS paths look like: "Volume:directory/subdirectory" */
+ if (FiosIsRoot(path)) {
+ snprintf(str_buffr, lengthof(str_buffr), "%s:%s", path, item->name);
+ } else // XXX - only next line!
+#endif
+ snprintf(str_buffr, lengthof(str_buffr), "%s" PATHSEP "%s", path, item->name);
+
+ return str_buffr;
+ }
+ }
+
+ return NULL;
+}
+
+void FiosMakeSavegameName(char *buf, const char *name, size_t size)
+{
+ const char *extension, *period;
+
+ extension = (_game_mode == GM_EDITOR) ? ".scn" : ".sav";
+
+ /* Don't append the extension if it is already there */
+ period = strrchr(name, '.');
+ if (period != NULL && strcasecmp(period, extension) == 0) extension = "";
+
+ snprintf(buf, size, "%s" PATHSEP "%s%s", _fios_path, name, extension);
+}
+
+#if defined(WIN32) || defined(WIN64)
+# define unlink _wunlink
+#endif
+
+bool FiosDelete(const char *name)
+{
+ char filename[512];
+
+ FiosMakeSavegameName(filename, name, lengthof(filename));
+ return unlink(OTTD2FS(filename)) == 0;
+}
+
+bool FileExists(const char *filename)
+{
+ return access(filename, 0) == 0;
+}
+
+typedef byte fios_getlist_callback_proc(int mode, const char *filename, const char *ext, char *title);
+
+/** Create a list of the files in a directory, according to some arbitrary rule.
+ * @param num Will be filled with the amount of items.
+ * @param mode The mode we are in. Some modes don't allow 'parent'.
+ * @param callback The function that is called where you need to do the filtering.
+ * @return Return the list of files. */
+static FiosItem *FiosGetFileList(int mode, fios_getlist_callback_proc *callback_proc)
+{
+ struct stat sb;
+ struct dirent *dirent;
+ DIR *dir;
+ FiosItem *fios;
+ int sort_start;
+
+ /* A parent directory link exists if we are not in the root directory */
+ if (!FiosIsRoot(_fios_path) && mode != SLD_NEW_GAME) {
+ fios = FiosAlloc();
+ fios->type = FIOS_TYPE_PARENT;
+ fios->mtime = 0;
+ ttd_strlcpy(fios->name, "..", lengthof(fios->name));
+ ttd_strlcpy(fios->title, ".. (Parent directory)", lengthof(fios->title));
+ }
+
+ /* Show subdirectories */
+ if (mode != SLD_NEW_GAME && (dir = opendir(_fios_path)) != NULL) {
+ while ((dirent = readdir(dir)) != NULL) {
+ const char *d_name = FS2OTTD(dirent->d_name);
+
+ /* found file must be directory, but not '.' or '..' */
+ if (FiosIsValidFile(_fios_path, dirent, &sb) && (sb.st_mode & S_IFDIR) &&
+ strcmp(d_name, ".") != 0 && strcmp(d_name, "..") != 0) {
+ fios = FiosAlloc();
+ fios->type = FIOS_TYPE_DIR;
+ fios->mtime = 0;
+ ttd_strlcpy(fios->name, d_name, lengthof(fios->name));
+ snprintf(fios->title, lengthof(fios->title), "%s" PATHSEP " (Directory)", d_name);
+ str_validate(fios->title);
+ }
+ }
+ closedir(dir);
+ }
+
+ /* Sort the subdirs always by name, ascending, remember user-sorting order */
+ {
+ byte order = _savegame_sort_order;
+ _savegame_sort_order = SORT_BY_NAME | SORT_ASCENDING;
+ qsort(_fios_items, _fios_count, sizeof(FiosItem), compare_FiosItems);
+ _savegame_sort_order = order;
+ }
+
+ /* This is where to start sorting for the filenames */
+ sort_start = _fios_count;
+
+ /* Show files */
+ dir = opendir(_fios_path);
+ if (dir != NULL) {
+ while ((dirent = readdir(dir)) != NULL) {
+ char fios_title[64];
+ char *t;
+ char *d_name = (char*)FS2OTTD(dirent->d_name);
+ byte type;
+
+ if (!FiosIsValidFile(_fios_path, dirent, &sb) || !(sb.st_mode & S_IFREG)) continue;
+
+ /* File has no extension, skip it */
+ if ((t = strrchr(d_name, '.')) == NULL) continue;
+ fios_title[0] = '\0'; // reset the title;
+
+ type = callback_proc(mode, d_name, t, fios_title);
+ if (type != FIOS_TYPE_INVALID) {
+ fios = FiosAlloc();
+ fios->mtime = sb.st_mtime;
+ fios->type = type;
+ ttd_strlcpy(fios->name, d_name, lengthof(fios->name));
+
+ /* Some callbacks want to lookup the title of the file. Allow that.
+ * If we just copy the title from the filename, strip the extension */
+ t = (fios_title[0] == '\0') ? *t = '\0', d_name : fios_title;
+ ttd_strlcpy(fios->title, t, lengthof(fios->title));
+ str_validate(fios->title);
+ }
+ }
+ closedir(dir);
+ }
+
+ qsort(_fios_items + sort_start, _fios_count - sort_start, sizeof(FiosItem), compare_FiosItems);
+
+ /* Show drives */
+ if (mode != SLD_NEW_GAME) FiosGetDrives();
+
+ _fios_num = _fios_count;
+ return _fios_items;
+}
+
+/**
+ * Callback for FiosGetFileList. It tells if a file is a savegame or not.
+ * @param mode Save/load mode.
+ * @param file Name of the file to check.
+ * @param ext A pointer to the extension identifier inside file
+ * @param title Buffer if a callback wants to lookup the title of the file
+ * @return a FIOS_TYPE_* type of the found file, FIOS_TYPE_INVALID if not a savegame
+ * @see FiosGetFileList
+ * @see FiosGetSavegameList
+ */
+static byte FiosGetSavegameListCallback(int mode, const char *file, const char *ext, char *title)
+{
+ /* Show savegame files
+ * .SAV OpenTTD saved game
+ * .SS1 Transport Tycoon Deluxe preset game
+ * .SV1 Transport Tycoon Deluxe (Patch) saved game
+ * .SV2 Transport Tycoon Deluxe (Patch) saved 2-player game */
+ if (strcasecmp(ext, ".sav") == 0) return FIOS_TYPE_FILE;
+
+ if (mode == SLD_LOAD_GAME || mode == SLD_LOAD_SCENARIO) {
+ if (strcasecmp(ext, ".ss1") == 0 || strcasecmp(ext, ".sv1") == 0 ||
+ strcasecmp(ext, ".sv2") == 0) {
+ GetOldSaveGameName(title, _fios_path, file);
+ return FIOS_TYPE_OLDFILE;
+ }
+ }
+
+ return FIOS_TYPE_INVALID;
+}
+
+/**
+ * Get a list of savegames.
+ * @param mode Save/load mode.
+ * @return A pointer to an array of FiosItem representing all the files to be shown in the save/load dialog.
+ * @see FiosGetFileList
+ */
+FiosItem *FiosGetSavegameList(int mode)
+{
+ static char *_fios_save_path = NULL;
+
+ if (_fios_save_path == NULL) {
+ _fios_save_path = malloc(MAX_PATH);
+ ttd_strlcpy(_fios_save_path, _paths.save_dir, MAX_PATH);
+ }
+
+ _fios_path = _fios_save_path;
+
+ return FiosGetFileList(mode, &FiosGetSavegameListCallback);
+}
+
+/**
+ * Callback for FiosGetFileList. It tells if a file is a scenario or not.
+ * @param mode Save/load mode.
+ * @param file Name of the file to check.
+ * @param ext A pointer to the extension identifier inside file
+ * @param title Buffer if a callback wants to lookup the title of the file
+ * @return a FIOS_TYPE_* type of the found file, FIOS_TYPE_INVALID if not a scenario
+ * @see FiosGetFileList
+ * @see FiosGetScenarioList
+ */
+static byte FiosGetScenarioListCallback(int mode, const char *file, const char *ext, char *title)
+{
+ /* Show scenario files
+ * .SCN OpenTTD style scenario file
+ * .SV0 Transport Tycoon Deluxe (Patch) scenario
+ * .SS0 Transport Tycoon Deluxe preset scenario */
+ if (strcasecmp(ext, ".scn") == 0) return FIOS_TYPE_SCENARIO;
+
+ if (mode == SLD_LOAD_GAME || mode == SLD_LOAD_SCENARIO || mode == SLD_NEW_GAME) {
+ if (strcasecmp(ext, ".sv0") == 0 || strcasecmp(ext, ".ss0") == 0 ) {
+ GetOldSaveGameName(title, _fios_path, file);
+ return FIOS_TYPE_OLD_SCENARIO;
+ }
+ }
+
+ return FIOS_TYPE_INVALID;
+}
+
+/**
+ * Get a list of scenarios.
+ * @param mode Save/load mode.
+ * @return A pointer to an array of FiosItem representing all the files to be shown in the save/load dialog.
+ * @see FiosGetFileList
+ */
+FiosItem *FiosGetScenarioList(int mode)
+{
+ static char *_fios_scn_path = NULL;
+
+ if (_fios_scn_path == NULL) {
+ _fios_scn_path = malloc(MAX_PATH);
+ ttd_strlcpy(_fios_scn_path, _paths.scenario_dir, MAX_PATH);
+ }
+
+ _fios_path = _fios_scn_path;
+
+ return FiosGetFileList(mode, &FiosGetScenarioListCallback);
+}
+
+static byte FiosGetHeightmapListCallback(int mode, const char *file, const char *ext, char *title)
+{
+ /* Show heightmap files
+ * .PNG PNG Based heightmap files
+ * .BMP BMP Based heightmap files
+ */
+
+#ifdef WITH_PNG
+ if (strcasecmp(ext, ".png") == 0) return FIOS_TYPE_PNG;
+#endif /* WITH_PNG */
+
+ if (strcasecmp(ext, ".bmp") == 0) return FIOS_TYPE_BMP;
+
+ return FIOS_TYPE_INVALID;
+}
+
+// Get a list of Heightmaps
+FiosItem *FiosGetHeightmapList(int mode)
+{
+ static char *_fios_hmap_path = NULL;
+
+ if (_fios_hmap_path == NULL) {
+ _fios_hmap_path = malloc(MAX_PATH);
+ strcpy(_fios_hmap_path, _paths.heightmap_dir);
+ }
+
+ _fios_path = _fios_hmap_path;
+
+ return FiosGetFileList(mode, &FiosGetHeightmapListCallback);
+}
diff --git a/src/fios.h b/src/fios.h
new file mode 100644
index 000000000..85d0b6041
--- /dev/null
+++ b/src/fios.h
@@ -0,0 +1,86 @@
+/* $Id$ */
+
+#ifndef FIOS_H
+#define FIOS_H
+
+/* Deals with finding savegames */
+typedef struct {
+ byte type;
+ uint64 mtime;
+ char title[64];
+ char name[256 - 12 - 64];
+} FiosItem;
+
+enum {
+ FIOS_TYPE_DRIVE = 0,
+ FIOS_TYPE_PARENT = 1,
+ FIOS_TYPE_DIR = 2,
+ FIOS_TYPE_FILE = 3,
+ FIOS_TYPE_OLDFILE = 4,
+ FIOS_TYPE_SCENARIO = 5,
+ FIOS_TYPE_OLD_SCENARIO = 6,
+ FIOS_TYPE_DIRECT = 7,
+ FIOS_TYPE_PNG = 8,
+ FIOS_TYPE_BMP = 9,
+ FIOS_TYPE_INVALID = 255,
+};
+
+/* Variables to display file lists */
+extern FiosItem *_fios_list; // defined in misc_gui.c
+extern int _fios_num; // defined in fios.c, read_only version of _fios_count
+extern int _saveload_mode; // defined in misc_gui.c
+
+// Get a list of savegames
+FiosItem *FiosGetSavegameList(int mode);
+// Get a list of scenarios
+FiosItem *FiosGetScenarioList(int mode);
+// Get a list of Heightmaps
+FiosItem *FiosGetHeightmapList(int mode);
+// Free the list of savegames
+void FiosFreeSavegameList(void);
+// Browse to. Returns a filename w/path if we reached a file.
+char *FiosBrowseTo(const FiosItem *item);
+// Return path, free space and stringID
+StringID FiosGetDescText(const char **path, uint32 *total_free);
+// Delete a name
+bool FiosDelete(const char *name);
+// Make a filename from a name
+void FiosMakeSavegameName(char *buf, const char *name, size_t size);
+// Allocate a new FiosItem
+FiosItem *FiosAlloc(void);
+
+int CDECL compare_FiosItems(const void *a, const void *b);
+
+/* Implementation of opendir/readdir/closedir for Windows */
+#if defined(WIN32)
+#include <windows.h>
+typedef struct DIR DIR;
+
+typedef struct dirent { // XXX - only d_name implemented
+ wchar_t *d_name; /* name of found file */
+ /* little hack which will point to parent DIR struct which will
+ * save us a call to GetFileAttributes if we want information
+ * about the file (for example in function fio_bla */
+ DIR *dir;
+} dirent;
+
+struct DIR {
+ HANDLE hFind;
+ /* the dirent returned by readdir.
+ * note: having only one global instance is not possible because
+ * multiple independent opendir/readdir sequences must be supported. */
+ dirent ent;
+ WIN32_FIND_DATAW fd;
+ /* since opendir calls FindFirstFile, we need a means of telling the
+ * first call to readdir that we already have a file.
+ * that's the case iff this is true */
+ bool at_first_entry;
+};
+
+DIR *opendir(const char *path);
+struct dirent *readdir(DIR *d);
+int closedir(DIR *d);
+
+#endif /* defined(WIN32) */
+
+#endif /* FIOS_H */
diff --git a/src/fontcache.c b/src/fontcache.c
new file mode 100644
index 000000000..d555eea94
--- /dev/null
+++ b/src/fontcache.c
@@ -0,0 +1,524 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "functions.h"
+#include "macros.h"
+#include "debug.h"
+#include "table/sprites.h"
+#include "table/control_codes.h"
+#include "spritecache.h"
+#include "gfx.h"
+#include "string.h"
+#include "fontcache.h"
+
+#ifdef WITH_FREETYPE
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_GLYPH_H
+
+#ifdef WITH_FONTCONFIG
+#include <fontconfig/fontconfig.h>
+#endif
+
+static FT_Library _library = NULL;
+static FT_Face _face_small = NULL;
+static FT_Face _face_medium = NULL;
+static FT_Face _face_large = NULL;
+
+FreeTypeSettings _freetype;
+
+enum {
+ FACE_COLOUR = 1,
+ SHADOW_COLOUR = 2,
+};
+
+/** Get the font loaded into a Freetype face by using a font-name.
+ * If no appropiate font is found, the function returns an error */
+#ifdef WIN32
+#include <windows.h>
+#include <tchar.h>
+#include <shlobj.h> // SHGetFolderPath
+#include "win32.h"
+
+/* Get the font file to be loaded into Freetype by looping the registry
+ * location where windows lists all installed fonts. Not very nice, will
+ * surely break if the registry path changes, but it works. Much better
+ * solution would be to use CreateFont, and extract the font data from it
+ * by GetFontData. The problem with this is that the font file needs to be
+ * kept in memory then until the font is no longer needed. This could mean
+ * an additional memory usage of 30MB (just for fonts!) when using an eastern
+ * font for all font sizes */
+#define FONT_DIR_NT "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"
+#define FONT_DIR_9X "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Fonts"
+static FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
+{
+ FT_Error err = FT_Err_Cannot_Open_Resource;
+ HKEY hKey;
+ LONG ret;
+ TCHAR vbuffer[MAX_PATH], dbuffer[256];
+ TCHAR *font_namep;
+ char *font_path;
+ uint index;
+
+ /* On windows NT (2000, NT3.5, XP, etc.) the fonts are stored in the
+ * "Windows NT" key, on Windows 9x in the Windows key. To save us having
+ * to retrieve the windows version, we'll just query both */
+ ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T(FONT_DIR_NT), 0, KEY_READ, &hKey);
+ if (ret != ERROR_SUCCESS) ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T(FONT_DIR_9X), 0, KEY_READ, &hKey);
+
+ if (ret != ERROR_SUCCESS) {
+ DEBUG(freetype, 0, "Cannot open registry key HKLM\\SOFTWARE\\Microsoft\\Windows (NT)\\CurrentVersion\\Fonts");
+ return err;
+ }
+
+ /* For Unicode we need some conversion between widechar and
+ * normal char to match the data returned by RegEnumValue,
+ * otherwise just use parameter */
+#if defined(UNICODE)
+ font_namep = malloc(MAX_PATH * sizeof(TCHAR));
+ MB_TO_WIDE_BUFFER(font_name, font_namep, MAX_PATH * sizeof(TCHAR));
+#else
+ font_namep = (char*)font_name; // only cast because in unicode pointer is not const
+#endif
+
+ for (index = 0;; index++) {
+ TCHAR *s;
+ DWORD vbuflen = lengthof(vbuffer);
+ DWORD dbuflen = lengthof(dbuffer);
+
+ ret = RegEnumValue(hKey, index, vbuffer, &vbuflen, NULL, NULL, (byte*)dbuffer, &dbuflen);
+ if (ret != ERROR_SUCCESS) goto registry_no_font_found;
+
+ /* The font names in the registry are of the following 3 forms:
+ * - ADMUI3.fon
+ * - Book Antiqua Bold (TrueType)
+ * - Batang & BatangChe & Gungsuh & GungsuhChe (TrueType)
+ * We will strip the font-type '()' if any and work with the font name
+ * itself, which must match exactly; if...
+ * TTC files, font files which contain more than one font are seperated
+ * byt '&'. Our best bet will be to do substr match for the fontname
+ * and then let FreeType figure out which index to load */
+ s = _tcschr(vbuffer, _T('('));
+ if (s != NULL) s[-1] = '\0';
+
+ if (_tcschr(vbuffer, _T('&')) == NULL) {
+ if (_tcsicmp(vbuffer, font_namep) == 0) break;
+ } else {
+ if (_tcsstr(vbuffer, font_namep) != NULL) break;
+ }
+ }
+
+ if (!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_FONTS, NULL, SHGFP_TYPE_CURRENT, vbuffer))) {
+ DEBUG(freetype, 0, "SHGetFolderPath cannot return fonts directory");
+ goto folder_error;
+ }
+
+ /* Some fonts are contained in .ttc files, TrueType Collection fonts. These
+ * contain multiple fonts inside this single file. GetFontData however
+ * returns the whole file, so we need to check each font inside to get the
+ * proper font.
+ * Also note that FreeType does not support UNICODE filesnames! */
+#if defined(UNICODE)
+ /* We need a cast here back from wide because FreeType doesn't support
+ * widechar filenames. Just use the buffer we allocated before for the
+ * font_name search */
+ font_path = (char*)font_namep;
+ WIDE_TO_MB_BUFFER(vbuffer, font_path, MAX_PATH * sizeof(TCHAR));
+#else
+ font_path = vbuffer;
+#endif
+
+ ttd_strlcat(font_path, "\\", MAX_PATH * sizeof(TCHAR));
+ ttd_strlcat(font_path, WIDE_TO_MB(dbuffer), MAX_PATH * sizeof(TCHAR));
+ index = 0;
+ do {
+ err = FT_New_Face(_library, font_path, index, face);
+ if (err != FT_Err_Ok) break;
+
+ if (strncasecmp(font_name, (*face)->family_name, strlen((*face)->family_name)) == 0) break;
+ err = FT_Err_Cannot_Open_Resource;
+
+ } while ((FT_Long)++index != (*face)->num_faces);
+
+
+folder_error:
+#if defined(UNICODE)
+ free(font_path);
+#endif
+registry_no_font_found:
+ RegCloseKey(hKey);
+ return err;
+}
+#else
+# ifdef WITH_FONTCONFIG
+static FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
+{
+ FT_Error err = FT_Err_Cannot_Open_Resource;
+
+ if (!FcInit()) {
+ ShowInfoF("Unable to load font configuration");
+ } else {
+ FcPattern *match;
+ FcPattern *pat;
+ FcFontSet *fs;
+ FcResult result;
+ char *font_style;
+ char *font_family;
+
+ /* Split & strip the font's style */
+ font_family = strdup(font_name);
+ font_style = strchr(font_family, ',');
+ if (font_style != NULL) {
+ font_style[0] = '\0';
+ font_style++;
+ while (*font_style == ' ' || *font_style == '\t') font_style++;
+ }
+
+ /* Resolve the name and populate the information structure */
+ pat = FcNameParse((FcChar8*)font_family);
+ if (font_style != NULL) FcPatternAddString(pat, FC_STYLE, (FcChar8*)font_style);
+ FcConfigSubstitute(0, pat, FcMatchPattern);
+ FcDefaultSubstitute(pat);
+ fs = FcFontSetCreate();
+ match = FcFontMatch(0, pat, &result);
+
+ if (fs != NULL && match != NULL) {
+ int i;
+ FcChar8 *family;
+ FcChar8 *style;
+ FcChar8 *file;
+ FcFontSetAdd(fs, match);
+
+ for (i = 0; err != FT_Err_Ok && i < fs->nfont; i++) {
+ /* Try the new filename */
+ if (FcPatternGetString(fs->fonts[i], FC_FILE, 0, &file) == FcResultMatch &&
+ FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, &family) == FcResultMatch &&
+ FcPatternGetString(fs->fonts[i], FC_STYLE, 0, &style) == FcResultMatch) {
+
+ /* The correct style? */
+ if (font_style != NULL && strcasecmp(font_style, (char*)style) != 0) continue;
+
+ /* Font config takes the best shot, which, if the family name is spelled
+ * wrongly a 'random' font, so check whether the family name is the
+ * same as the supplied name */
+ if (strcasecmp(font_family, (char*)family) == 0) {
+ err = FT_New_Face(_library, (char *)file, 0, face);
+ }
+ }
+ }
+ }
+
+ free(font_family);
+ FcPatternDestroy(pat);
+ FcFontSetDestroy(fs);
+ FcFini();
+ }
+
+ return err;
+}
+# else
+FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) {return FT_Err_Cannot_Open_Resource;}
+# endif /* WITH_FONTCONFIG */
+
+#endif
+
+/**
+ * Loads the freetype font.
+ * First type to load the fontname as if it were a path. If that fails,
+ * try to resolve the filename of the font using fontconfig, where the
+ * format is 'font family name' or 'font family name, font style'.
+ */
+static void LoadFreeTypeFont(const char *font_name, FT_Face *face, const char *type)
+{
+ FT_Error error;
+
+ if (strlen(font_name) == 0) return;
+
+ error = FT_New_Face(_library, font_name, 0, face);
+
+ if (error != FT_Err_Ok) error = GetFontByFaceName(font_name, face);
+
+ if (error == FT_Err_Ok) {
+ DEBUG(freetype, 2, "Requested '%s', using '%s %s'", font_name, (*face)->family_name, (*face)->style_name);
+
+ /* Attempt to select the unicode character map */
+ error = FT_Select_Charmap(*face, ft_encoding_unicode);
+ if (error == FT_Err_Ok) return; // Success
+
+ if (error == FT_Err_Invalid_CharMap_Handle) {
+ /* Try to pick a different character map instead. We default to
+ * the first map, but platform_id 0 encoding_id 0 should also
+ * be unicode (strange system...) */
+ FT_CharMap found = (*face)->charmaps[0];
+ int i;
+
+ for (i = 0; i < (*face)->num_charmaps; i++) {
+ FT_CharMap charmap = (*face)->charmaps[i];
+ if (charmap->platform_id == 0 && charmap->encoding_id == 0) {
+ found = charmap;
+ }
+ }
+
+ if (found != NULL) {
+ error = FT_Set_Charmap(*face, found);
+ if (error == FT_Err_Ok) return;
+ }
+ }
+ }
+
+ FT_Done_Face(*face);
+ *face = NULL;
+
+ ShowInfoF("Unable to use '%s' for %s font, FreeType reported error 0x%X, using sprite font instead", font_name, type, error);
+}
+
+
+void InitFreeType(void)
+{
+ if (strlen(_freetype.small_font) == 0 && strlen(_freetype.medium_font) == 0 && strlen(_freetype.large_font) == 0) {
+ DEBUG(freetype, 1, "No font faces specified, using sprite fonts instead");
+ return;
+ }
+
+ if (FT_Init_FreeType(&_library) != FT_Err_Ok) {
+ ShowInfoF("Unable to initialize FreeType, using sprite fonts instead");
+ return;
+ }
+
+ DEBUG(freetype, 2, "Initialized");
+
+ /* Load each font */
+ LoadFreeTypeFont(_freetype.small_font, &_face_small, "small");
+ LoadFreeTypeFont(_freetype.medium_font, &_face_medium, "medium");
+ LoadFreeTypeFont(_freetype.large_font, &_face_large, "large");
+
+ /* Set each font size */
+ if (_face_small != NULL) FT_Set_Pixel_Sizes(_face_small, 0, _freetype.small_size);
+ if (_face_medium != NULL) FT_Set_Pixel_Sizes(_face_medium, 0, _freetype.medium_size);
+ if (_face_large != NULL) FT_Set_Pixel_Sizes(_face_large, 0, _freetype.large_size);
+}
+
+
+static FT_Face GetFontFace(FontSize size)
+{
+ switch (size) {
+ default: NOT_REACHED();
+ case FS_NORMAL: return _face_medium;
+ case FS_SMALL: return _face_small;
+ case FS_LARGE: return _face_large;
+ }
+}
+
+
+typedef struct GlyphEntry {
+ Sprite *sprite;
+ byte width;
+} GlyphEntry;
+
+
+/* The glyph cache. This is structured to reduce memory consumption.
+ * 1) There is a 'segment' table for each font size.
+ * 2) Each segment table is a discrete block of characters.
+ * 3) Each block contains 256 (aligned) characters sequential characters.
+ *
+ * The cache is accessed in the following way:
+ * For character 0x0041 ('A'): _glyph_ptr[FS_NORMAL][0x00][0x41]
+ * For character 0x20AC (Euro): _glyph_ptr[FS_NORMAL][0x20][0xAC]
+ *
+ * Currently only 256 segments are allocated, "limiting" us to 65536 characters.
+ * This can be simply changed in the two functions Get & SetGlyphPtr.
+ */
+static GlyphEntry **_glyph_ptr[FS_END];
+
+
+static GlyphEntry *GetGlyphPtr(FontSize size, WChar key)
+{
+ if (_glyph_ptr[size] == NULL) return NULL;
+ if (_glyph_ptr[size][GB(key, 8, 8)] == NULL) return NULL;
+ return &_glyph_ptr[size][GB(key, 8, 8)][GB(key, 0, 8)];
+}
+
+
+static void SetGlyphPtr(FontSize size, WChar key, const GlyphEntry *glyph)
+{
+ if (_glyph_ptr[size] == NULL) {
+ DEBUG(freetype, 3, "Allocating root glyph cache for size %u", size);
+ _glyph_ptr[size] = calloc(256, sizeof(**_glyph_ptr));
+ }
+
+ if (_glyph_ptr[size][GB(key, 8, 8)] == NULL) {
+ DEBUG(freetype, 3, "Allocating glyph cache for range 0x%02X00, size %u", GB(key, 8, 8), size);
+ _glyph_ptr[size][GB(key, 8, 8)] = calloc(256, sizeof(***_glyph_ptr));
+ }
+
+ DEBUG(freetype, 4, "Set glyph for unicode character 0x%04X, size %u", key, size);
+ _glyph_ptr[size][GB(key, 8, 8)][GB(key, 0, 8)].sprite = glyph->sprite;
+ _glyph_ptr[size][GB(key, 8, 8)][GB(key, 0, 8)].width = glyph->width;
+}
+
+
+const Sprite *GetGlyph(FontSize size, WChar key)
+{
+ FT_Face face = GetFontFace(size);
+ FT_GlyphSlot slot;
+ GlyphEntry new_glyph;
+ GlyphEntry *glyph;
+ Sprite *sprite;
+ int width;
+ int height;
+ int x;
+ int y;
+ int y_adj;
+
+ assert(IsPrintable(key));
+
+ /* Bail out if no face loaded, or for our special characters */
+ if (face == NULL || (key >= SCC_SPRITE_START && key <= SCC_SPRITE_END)) {
+ SpriteID sprite = GetUnicodeGlyph(size, key);
+ if (sprite == 0) sprite = GetUnicodeGlyph(size, '?');
+ return GetSprite(sprite);
+ }
+
+ /* Check for the glyph in our cache */
+ glyph = GetGlyphPtr(size, key);
+ if (glyph != NULL && glyph->sprite != NULL) return glyph->sprite;
+
+ slot = face->glyph;
+
+ FT_Load_Char(face, key, FT_LOAD_DEFAULT);
+ FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO);
+
+ /* Add 1 pixel for the shadow on the medium font. Our sprite must be at least 1x1 pixel */
+ width = max(1, slot->bitmap.width + (size == FS_NORMAL));
+ height = max(1, slot->bitmap.rows + (size == FS_NORMAL));
+
+ /* FreeType has rendered the glyph, now we allocate a sprite and copy the image into it */
+ sprite = calloc(width * height + 8, 1);
+ sprite->info = 1;
+ sprite->width = width;
+ sprite->height = height;
+ sprite->x_offs = slot->bitmap_left;
+ // XXX 2 should be determined somehow... it's right for the normal face
+ y_adj = (size == FS_NORMAL) ? 2 : 0;
+ sprite->y_offs = GetCharacterHeight(size) - slot->bitmap_top - y_adj;
+
+ /* Draw shadow for medium size */
+ if (size == FS_NORMAL) {
+ for (y = 0; y < slot->bitmap.rows; y++) {
+ for (x = 0; x < 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] = SHADOW_COLOUR;
+ }
+ }
+ }
+ }
+
+ for (y = 0; y < slot->bitmap.rows; y++) {
+ for (x = 0; x < slot->bitmap.width; x++) {
+ if (HASBIT(slot->bitmap.buffer[(x / 8) + y * slot->bitmap.pitch], 7 - (x % 8))) {
+ sprite->data[x + y * sprite->width] = FACE_COLOUR;
+ }
+ }
+ }
+
+ new_glyph.sprite = sprite;
+ new_glyph.width = (slot->advance.x >> 6) + (size != FS_NORMAL);
+
+ SetGlyphPtr(size, key, &new_glyph);
+
+ return sprite;
+}
+
+
+uint GetGlyphWidth(FontSize size, WChar key)
+{
+ FT_Face face = GetFontFace(size);
+ GlyphEntry *glyph;
+
+ if (face == NULL || (key >= SCC_SPRITE_START && key <= SCC_SPRITE_END)) {
+ SpriteID sprite = GetUnicodeGlyph(size, key);
+ if (sprite == 0) sprite = GetUnicodeGlyph(size, '?');
+ return SpriteExists(sprite) ? GetSprite(sprite)->width + (size != FS_NORMAL) : 0;
+ }
+
+ glyph = GetGlyphPtr(size, key);
+ if (glyph == NULL || glyph->sprite == NULL) {
+ GetGlyph(size, key);
+ glyph = GetGlyphPtr(size, key);
+ }
+
+ return glyph->width;
+}
+
+
+#endif /* WITH_FREETYPE */
+
+/* Sprite based glyph mapping */
+
+#include "table/unicode.h"
+
+static SpriteID **_unicode_glyph_map[FS_END];
+
+
+/** Get the SpriteID of the first glyph for the given font size */
+static SpriteID GetFontBase(FontSize size)
+{
+ switch (size) {
+ default: NOT_REACHED();
+ case FS_NORMAL: return SPR_ASCII_SPACE;
+ case FS_SMALL: return SPR_ASCII_SPACE_SMALL;
+ case FS_LARGE: return SPR_ASCII_SPACE_BIG;
+ }
+}
+
+
+SpriteID GetUnicodeGlyph(FontSize size, uint32 key)
+{
+ if (_unicode_glyph_map[size][GB(key, 8, 8)] == NULL) return 0;
+ return _unicode_glyph_map[size][GB(key, 8, 8)][GB(key, 0, 8)];
+}
+
+
+void SetUnicodeGlyph(FontSize size, uint32 key, SpriteID sprite)
+{
+ if (_unicode_glyph_map[size] == NULL) _unicode_glyph_map[size] = calloc(256, sizeof(*_unicode_glyph_map[size]));
+ if (_unicode_glyph_map[size][GB(key, 8, 8)] == NULL) _unicode_glyph_map[size][GB(key, 8, 8)] = calloc(256, sizeof(**_unicode_glyph_map[size]));
+ _unicode_glyph_map[size][GB(key, 8, 8)][GB(key, 0, 8)] = sprite;
+}
+
+
+void InitializeUnicodeGlyphMap(void)
+{
+ FontSize size;
+ SpriteID base;
+ SpriteID sprite;
+ uint i;
+
+ for (size = FS_NORMAL; size != FS_END; size++) {
+ /* Clear out existing glyph map if it exists */
+ if (_unicode_glyph_map[size] != NULL) {
+ for (i = 0; i < 256; i++) {
+ if (_unicode_glyph_map[size][i] != NULL) free(_unicode_glyph_map[size][i]);
+ }
+ free(_unicode_glyph_map[size]);
+ _unicode_glyph_map[size] = NULL;
+ }
+
+ base = GetFontBase(size);
+ for (i = ASCII_LETTERSTART; i < 256; i++) {
+ sprite = base + i - ASCII_LETTERSTART;
+ if (!SpriteExists(sprite)) continue;
+ SetUnicodeGlyph(size, i, sprite);
+ SetUnicodeGlyph(size, i + SCC_SPRITE_START, sprite);
+ }
+ for (i = 0; i < lengthof(_default_unicode_map); i++) {
+ sprite = base + _default_unicode_map[i].key - ASCII_LETTERSTART;
+ SetUnicodeGlyph(size, _default_unicode_map[i].code, sprite);
+ }
+ }
+}
+
+
+
diff --git a/src/fontcache.h b/src/fontcache.h
new file mode 100644
index 000000000..249f35cd0
--- /dev/null
+++ b/src/fontcache.h
@@ -0,0 +1,56 @@
+/* $Id$ */
+
+#ifndef FONTCACHE_H
+#define FONTCACHE_H
+
+/** Get the SpriteID mapped to the given font size and key */
+SpriteID GetUnicodeGlyph(FontSize size, uint32 key);
+
+/** Map a SpriteID to the font size and key */
+void SetUnicodeGlyph(FontSize size, uint32 key, SpriteID sprite);
+
+/** Initialize the glyph map */
+void InitializeUnicodeGlyphMap(void);
+
+#ifdef WITH_FREETYPE
+
+typedef struct FreeTypeSettings {
+ char small_font[260];
+ char medium_font[260];
+ char large_font[260];
+ uint small_size;
+ uint medium_size;
+ uint large_size;
+} FreeTypeSettings;
+
+extern FreeTypeSettings _freetype;
+
+void InitFreeType(void);
+const struct Sprite *GetGlyph(FontSize size, uint32 key);
+uint GetGlyphWidth(FontSize size, uint32 key);
+
+#else
+
+/* Stub for initializiation */
+static inline void InitFreeType(void) {}
+
+/** Get the Sprite for a glyph */
+static inline const Sprite *GetGlyph(FontSize size, uint32 key)
+{
+ SpriteID sprite = GetUnicodeGlyph(size, key);
+ if (sprite == 0) sprite = GetUnicodeGlyph(size, '?');
+ return GetSprite(sprite);
+}
+
+
+/** Get the width of a glyph */
+static inline uint GetGlyphWidth(FontSize size, uint32 key)
+{
+ SpriteID sprite = GetUnicodeGlyph(size, key);
+ if (sprite == 0) sprite = GetUnicodeGlyph(size, '?');
+ return SpriteExists(sprite) ? GetSprite(sprite)->width + (size != FS_NORMAL) : 0;
+}
+
+#endif /* WITH_FREETYPE */
+
+#endif /* FONTCACHE_H */
diff --git a/src/functions.h b/src/functions.h
new file mode 100644
index 000000000..0529c1646
--- /dev/null
+++ b/src/functions.h
@@ -0,0 +1,227 @@
+/* $Id$ */
+
+#ifndef FUNCTIONS_H
+#define FUNCTIONS_H
+
+void DoClearSquare(TileIndex tile);
+void RunTileLoop(void);
+
+uint GetPartialZ(int x, int y, Slope corners);
+uint GetSlopeZ(int x, int y);
+uint32 GetTileTrackStatus(TileIndex tile, TransportType mode);
+void GetAcceptedCargo(TileIndex tile, AcceptedCargo ac);
+void ChangeTileOwner(TileIndex tile, byte old_player, byte new_player);
+void AnimateTile(TileIndex tile);
+void ClickTile(TileIndex tile);
+void GetTileDesc(TileIndex tile, TileDesc *td);
+void UpdateTownMaxPass(Town *t);
+
+bool IsValidTile(TileIndex tile);
+
+static inline Point RemapCoords(int x, int y, int z)
+{
+#if !defined(NEW_ROTATION)
+ Point pt;
+ pt.x = (y - x) * 2;
+ pt.y = y + x - z;
+#else
+ Point pt;
+ pt.x = (x + y) * 2;
+ pt.y = x - y - z;
+#endif
+ return pt;
+}
+
+static inline Point RemapCoords2(int x, int y)
+{
+ return RemapCoords(x, y, GetSlopeZ(x, y));
+}
+
+
+/* clear_land.c */
+void DrawHillyLandTile(const TileInfo *ti);
+void DrawClearLandTile(const TileInfo *ti, byte set);
+void DrawClearLandFence(const TileInfo *ti);
+void TileLoopClearHelper(TileIndex tile);
+
+/* water_land.c */
+void DrawShipDepotSprite(int x, int y, int image);
+void TileLoop_Water(TileIndex tile);
+
+/* players.c */
+bool CheckPlayerHasMoney(int32 cost);
+void SubtractMoneyFromPlayer(int32 cost);
+void SubtractMoneyFromPlayerFract(PlayerID player, int32 cost);
+bool CheckOwnership(Owner owner);
+bool CheckTileOwnership(TileIndex tile);
+StringID GetPlayerNameString(PlayerID player, uint index);
+
+/* standard */
+void ShowInfo(const char *str);
+void CDECL ShowInfoF(const char *str, ...);
+void NORETURN CDECL error(const char *str, ...);
+
+/* openttd.c */
+
+/**************
+ * Warning: DO NOT enable this unless you understand what it does
+ *
+ * If enabled, in a network game all randoms will be dumped to the
+ * stdout if the first client joins (or if you are a client). This
+ * is to help finding desync problems.
+ *
+ * Warning: DO NOT enable this unless you understand what it does
+ **************/
+
+//#define RANDOM_DEBUG
+
+
+// Enable this to produce higher quality random numbers.
+// Doesn't work with network yet.
+//#define MERSENNE_TWISTER
+
+// Mersenne twister functions
+void SeedMT(uint32 seed);
+uint32 RandomMT(void);
+
+
+#ifdef MERSENNE_TWISTER
+ static inline uint32 Random(void) { return RandomMT(); }
+ uint RandomRange(uint max);
+#else
+
+#ifdef RANDOM_DEBUG
+ #define Random() DoRandom(__LINE__, __FILE__)
+ uint32 DoRandom(int line, const char *file);
+ #define RandomRange(max) DoRandomRange(max, __LINE__, __FILE__)
+ uint DoRandomRange(uint max, int line, const char *file);
+#else
+ uint32 Random(void);
+ uint RandomRange(uint max);
+#endif
+#endif // MERSENNE_TWISTER
+
+static inline TileIndex RandomTileSeed(uint32 r) { return TILE_MASK(r); }
+static inline TileIndex RandomTile(void) { return TILE_MASK(Random()); }
+
+
+uint32 InteractiveRandom(void); /* Used for random sequences that are not the same on the other end of the multiplayer link */
+uint InteractiveRandomRange(uint max);
+
+/* facedraw.c */
+void DrawPlayerFace(uint32 face, int color, int x, int y);
+
+/* texteff.c */
+void MoveAllTextEffects(void);
+void AddTextEffect(StringID msg, int x, int y, uint16 duration);
+void InitTextEffects(void);
+void DrawTextEffects(DrawPixelInfo *dpi);
+
+void InitTextMessage(void);
+void DrawTextMessage(void);
+void CDECL AddTextMessage(uint16 color, uint8 duration, const char *message, ...);
+void UndrawTextMessage(void);
+
+bool AddAnimatedTile(TileIndex tile);
+void DeleteAnimatedTile(TileIndex tile);
+void AnimateAnimatedTiles(void);
+void InitializeAnimatedTiles(void);
+
+/* tunnelbridge_cmd.c */
+bool CheckBridge_Stuff(byte bridge_type, uint bridge_len);
+uint32 GetBridgeLength(TileIndex begin, TileIndex end);
+int CalcBridgeLenCostFactor(int x);
+
+/* misc_cmd.c */
+void PlaceTreesRandomly(void);
+
+void InitializeLandscapeVariables(bool only_constants);
+
+/* misc.c */
+bool IsCustomName(StringID id);
+void DeleteName(StringID id);
+char *GetName(char *buff, StringID id, const char* last);
+
+// AllocateNameUnique also tests if the name used is not used anywere else
+// and if it is used, it returns an error.
+#define AllocateNameUnique(name, skip) RealAllocateName(name, skip, true)
+#define AllocateName(name, skip) RealAllocateName(name, skip, false)
+StringID RealAllocateName(const char *name, byte skip, bool check_double);
+void ConvertNameArray(void);
+
+/* misc functions */
+void MarkTileDirty(int x, int y);
+void MarkTileDirtyByTile(TileIndex tile);
+void InvalidateWindow(WindowClass cls, WindowNumber number);
+void InvalidateWindowWidget(WindowClass cls, WindowNumber number, byte widget_index);
+void InvalidateWindowClasses(WindowClass cls);
+void InvalidateWindowClassesData(WindowClass cls);
+void DeleteWindowById(WindowClass cls, WindowNumber number);
+void DeleteWindowByClass(WindowClass cls);
+
+void SetObjectToPlaceWnd(CursorID icon, byte mode, Window *w);
+void SetObjectToPlace(CursorID icon, byte mode, WindowClass window_class, WindowNumber window_num);
+
+void ResetObjectToPlace(void);
+
+bool ScrollWindowTo(int x, int y, Window * w);
+
+bool ScrollMainWindowToTile(TileIndex tile);
+bool ScrollMainWindowTo(int x, int y);
+void DrawSprite(uint32 img, int x, int y);
+bool EnsureNoVehicle(TileIndex tile);
+bool EnsureNoVehicleOnGround(TileIndex tile);
+void MarkAllViewportsDirty(int left, int top, int right, int bottom);
+void ShowCostOrIncomeAnimation(int x, int y, int z, int32 cost);
+void ShowFeederIncomeAnimation(int x, int y, int z, int32 cost);
+
+void DrawFoundation(TileInfo *ti, uint f);
+
+bool CheckIfAuthorityAllows(TileIndex tile);
+Town *ClosestTownFromTile(TileIndex tile, uint threshold);
+void ChangeTownRating(Town *t, int add, int max);
+
+uint GetTownRadiusGroup(const Town* t, TileIndex tile);
+int FindFirstBit(uint32 x);
+void ShowHighscoreTable(int difficulty, int8 rank);
+TileIndex AdjustTileCoordRandomly(TileIndex a, byte rng);
+
+void AfterLoadTown(void);
+void UpdatePatches(void);
+void AskExitGame(void);
+void AskExitToGameMenu(void);
+
+void RedrawAutosave(void);
+
+StringID RemapOldStringID(StringID s);
+
+void UpdateViewportSignPos(ViewportSign *sign, int left, int top, StringID str);
+
+enum {
+ SLD_LOAD_GAME,
+ SLD_LOAD_SCENARIO,
+ SLD_SAVE_GAME,
+ SLD_SAVE_SCENARIO,
+ SLD_LOAD_HEIGHTMAP,
+ SLD_NEW_GAME,
+};
+void ShowSaveLoadDialog(int mode);
+
+// callback from drivers that is called if the game size changes dynamically
+void GameSizeChanged(void);
+bool FileExists(const char *filename);
+bool ReadLanguagePack(int index);
+void InitializeLanguagePacks(void);
+const char *GetCurrentLocale(const char *param);
+void *ReadFileToMem(const char *filename, size_t *lenp, size_t maxsize);
+
+void LoadFromConfig(void);
+void SaveToConfig(void);
+void CheckConfig(void);
+int ttd_main(int argc, char* argv[]);
+void HandleExitGameRequest(void);
+
+void DeterminePaths(void);
+
+void CSleep(int milliseconds);
+#endif /* FUNCTIONS_H */
diff --git a/src/genworld.c b/src/genworld.c
new file mode 100644
index 000000000..ba9fe126f
--- /dev/null
+++ b/src/genworld.c
@@ -0,0 +1,292 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "functions.h"
+#include "player.h"
+#include "table/sprites.h"
+#include "variables.h"
+#include "thread.h"
+#include "genworld.h"
+#include "gfx.h"
+#include "gfxinit.h"
+#include "gui.h"
+#include "network/network.h"
+#include "debug.h"
+#include "settings.h"
+#include "heightmap.h"
+#include "date.h"
+
+void GenerateLandscape(byte mode);
+void GenerateClearTile(void);
+void GenerateIndustries(void);
+void GenerateUnmovables(void);
+bool GenerateTowns(void);
+void GenerateTrees(void);
+
+void StartupEconomy(void);
+void StartupPlayers(void);
+void StartupDisasters(void);
+
+void InitializeGame(int mode, uint size_x, uint size_y);
+
+void ConvertGroundTilesIntoWaterTiles(void);
+
+/* Please only use this variable in genworld.h and genworld.c and
+ * nowhere else. For speed improvements we need it to be global, but
+ * in no way the meaning of it is to use it anywhere else besides
+ * in the genworld.h and genworld.c! -- TrueLight */
+gw_info _gw;
+
+/**
+ * Set the status of the Paint flag.
+ * If it is true, the thread will hold with any futher generating till
+ * the drawing of the screen is done. This is handled by
+ * SetGeneratingWorldProgress(), so calling that function will stall
+ * from time to time.
+ */
+void SetGeneratingWorldPaintStatus(bool status)
+{
+ _gw.wait_for_draw = status;
+}
+
+/**
+ * Returns true if the thread wants the main program to do a (full) paint.
+ * If this returns false, please do not update the screen. Because we are
+ * writing in a thread, it can cause damaged data (reading and writing the
+ * same tile at the same time).
+ */
+bool IsGeneratingWorldReadyForPaint(void)
+{
+ /* If we are in quit_thread mode, ignore this and always return false. This
+ * forces the screen to not be drawn, and the GUI not to wait for a draw. */
+ if (!_gw.active || _gw.quit_thread || !_gw.threaded) return false;
+
+ return _gw.wait_for_draw;
+}
+
+/**
+ * Tells if the world generation is done in a thread or not.
+ */
+bool IsGenerateWorldThreaded(void)
+{
+ return _gw.threaded && !_gw.quit_thread;
+}
+
+/**
+ * The internal, real, generate function.
+ */
+static void *_GenerateWorld(void *arg)
+{
+ _generating_world = true;
+ if (_network_dedicated) DEBUG(net, 0, "Generating map, please wait...");
+ /* Set the Random() seed to generation_seed so we produce the same map with the same seed */
+ if (_patches.generation_seed == GENERATE_NEW_SEED) _patches.generation_seed = _patches_newgame.generation_seed = InteractiveRandom();
+ _random_seeds[0][0] = _random_seeds[0][1] = _patches.generation_seed;
+ SetGeneratingWorldProgress(GWP_MAP_INIT, 2);
+ SetObjectToPlace(SPR_CURSOR_ZZZ, 0, 0, 0);
+
+ IncreaseGeneratingWorldProgress(GWP_MAP_INIT);
+ // Must start economy early because of the costs.
+ StartupEconomy();
+
+ // Don't generate landscape items when in the scenario editor.
+ if (_gw.mode == GW_EMPTY) {
+ SetGeneratingWorldProgress(GWP_UNMOVABLE, 1);
+
+ /* Make the map the height of the patch setting */
+ if (_game_mode != GM_MENU) FlatEmptyWorld(_patches.se_flat_world_height);
+
+ ConvertGroundTilesIntoWaterTiles();
+ IncreaseGeneratingWorldProgress(GWP_UNMOVABLE);
+ } else {
+ GenerateLandscape(_gw.mode);
+ GenerateClearTile();
+
+ // only generate towns, tree and industries in newgame mode.
+ if (_game_mode != GM_EDITOR) {
+ GenerateTowns();
+ GenerateIndustries();
+ GenerateUnmovables();
+ GenerateTrees();
+ }
+ }
+
+ // These are probably pointless when inside the scenario editor.
+ SetGeneratingWorldProgress(GWP_GAME_INIT, 3);
+ StartupPlayers();
+ IncreaseGeneratingWorldProgress(GWP_GAME_INIT);
+ StartupEngines();
+ IncreaseGeneratingWorldProgress(GWP_GAME_INIT);
+ StartupDisasters();
+ _generating_world = false;
+
+ // No need to run the tile loop in the scenario editor.
+ if (_gw.mode != GW_EMPTY) {
+ uint i;
+
+ SetGeneratingWorldProgress(GWP_RUNTILELOOP, 0x500);
+ for (i = 0; i < 0x500; i++) {
+ RunTileLoop();
+ IncreaseGeneratingWorldProgress(GWP_RUNTILELOOP);
+ }
+ }
+
+ ResetObjectToPlace();
+ SetLocalPlayer(_gw.lp);
+
+ SetGeneratingWorldProgress(GWP_GAME_START, 1);
+ /* Call any callback */
+ if (_gw.proc != NULL) _gw.proc();
+ IncreaseGeneratingWorldProgress(GWP_GAME_START);
+
+ if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE);
+ /* Show all vital windows again, because we have hidden them */
+ if (_gw.threaded && _game_mode != GM_MENU) ShowVitalWindows();
+ _gw.active = false;
+ _gw.thread = NULL;
+ _gw.proc = NULL;
+ _gw.threaded = false;
+
+ DeleteWindowById(WC_GENERATE_PROGRESS_WINDOW, 0);
+ MarkWholeScreenDirty();
+
+ if (_network_dedicated) DEBUG(net, 0, "Map generated, starting game");
+
+ return NULL;
+}
+
+/**
+ * Set here the function, if any, that you want to be called when landscape
+ * generation is done.
+ */
+void GenerateWorldSetCallback(gw_done_proc *proc)
+{
+ _gw.proc = proc;
+}
+
+/**
+ * Set here the function, if any, that you want to be called when landscape
+ * generation is aborted.
+ */
+void GenerateWorldSetAbortCallback(gw_abort_proc *proc)
+{
+ _gw.abortp = proc;
+}
+
+/**
+ * This will wait for the thread to finish up his work. It will not continue
+ * till the work is done.
+ */
+void WaitTillGeneratedWorld(void)
+{
+ if (_gw.thread == NULL) return;
+ _gw.quit_thread = true;
+ OTTDJoinThread(_gw.thread);
+ _gw.thread = NULL;
+ _gw.threaded = false;
+}
+
+/**
+ * Initializes the abortion process
+ */
+void AbortGeneratingWorld(void)
+{
+ _gw.abort = true;
+}
+
+/**
+ * Is the generation being aborted?
+ */
+bool IsGeneratingWorldAborted(void)
+{
+ return _gw.abort;
+}
+
+/**
+ * Really handle the abortion, i.e. clean up some of the mess
+ */
+void HandleGeneratingWorldAbortion(void)
+{
+ /* Clean up - in SE create an empty map, otherwise, go to intro menu */
+ _switch_mode = (_game_mode == GM_EDITOR) ? SM_EDITOR : SM_MENU;
+
+ if (_gw.abortp != NULL) _gw.abortp();
+
+ if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE);
+ /* Show all vital windows again, because we have hidden them */
+ if (_gw.threaded && _game_mode != GM_MENU) ShowVitalWindows();
+ _gw.active = false;
+ _gw.thread = NULL;
+ _gw.proc = NULL;
+ _gw.abortp = NULL;
+ _gw.threaded = false;
+
+ DeleteWindowById(WC_GENERATE_PROGRESS_WINDOW, 0);
+ MarkWholeScreenDirty();
+
+ OTTDExitThread();
+}
+
+/**
+ * Generate a world.
+ * @param mode The mode of world generation (@see GenerateWorldModes).
+ * @param size_x The X-size of the map.
+ * @param size_y The Y-size of the map.
+ */
+void GenerateWorld(int mode, uint size_x, uint size_y)
+{
+ if (_gw.active) return;
+ _gw.mode = mode;
+ _gw.size_x = size_x;
+ _gw.size_y = size_y;
+ _gw.active = true;
+ _gw.abort = false;
+ _gw.abortp = NULL;
+ _gw.lp = _local_player;
+ _gw.wait_for_draw = false;
+ _gw.quit_thread = false;
+ _gw.threaded = true;
+
+ /* This disables some commands and stuff */
+ SetLocalPlayer(PLAYER_SPECTATOR);
+ /* Make sure everything is done via OWNER_NONE */
+ _current_player = OWNER_NONE;
+
+ /* Set the date before loading sprites as some newgrfs check it */
+ SetDate(ConvertYMDToDate(_patches.starting_year, 0, 1));
+
+ /* Load the right landscape stuff */
+ GfxLoadSprites();
+ LoadStringWidthTable();
+
+ InitializeGame(IG_NONE, _gw.size_x, _gw.size_y);
+ PrepareGenerateWorldProgress();
+
+ /* Re-init the windowing system */
+ ResetWindowSystem();
+
+ /* Create toolbars */
+ SetupColorsAndInitialWindow();
+
+ if (_network_dedicated ||
+ (_gw.thread = OTTDCreateThread(&_GenerateWorld, NULL)) == NULL) {
+ DEBUG(misc, 1, "Cannot create genworld thread, reverting to single-threaded mode");
+ _gw.threaded = false;
+ _GenerateWorld(NULL);
+ return;
+ }
+
+ /* Remove any open window */
+ DeleteAllNonVitalWindows();
+ /* Hide vital windows, because we don't allow to use them */
+ HideVitalWindows();
+
+ /* Don't show the dialog if we don't have a thread */
+ ShowGenerateWorldProgress();
+
+ /* Centre the view on the map */
+ if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) {
+ ScrollMainWindowToTile(TileXY(MapSizeX() / 2, MapSizeY() / 2));
+ }
+}
diff --git a/src/genworld.h b/src/genworld.h
new file mode 100644
index 000000000..0cf67cbe6
--- /dev/null
+++ b/src/genworld.h
@@ -0,0 +1,94 @@
+/* $Id$ */
+
+#ifndef GENWORLD_H
+#define GENWORLD_H
+
+/* If OTTDThread isn't defined, define it to a void, but make sure to undefine
+ * it after this include. This makes including genworld.h easier, as you
+ * don't need to include thread.h before it, while it stays possible to
+ * include it after it, and still work.
+ */
+#ifndef OTTDThread
+#define TEMPORARY_OTTDTHREAD_DEFINITION
+#define OTTDThread void
+#endif
+
+/*
+ * Order of these enums has to be the same as in lang/english.txt
+ * Otherwise you will get inconsistent behaviour.
+ */
+enum {
+ LG_ORIGINAL = 0, //! The original landscape generator
+ LG_TERRAGENESIS = 1, //! TerraGenesis Perlin landscape generator
+
+ GENERATE_NEW_SEED = (uint)-1, //! Create a new random seed
+};
+
+typedef void gw_done_proc(void);
+typedef void gw_abort_proc(void);
+
+typedef struct gw_info {
+ bool active; //! Is generating world active
+ bool abort; //! Whether to abort the thread ASAP
+ bool wait_for_draw; //! Are we waiting on a draw event
+ bool quit_thread; //! Do we want to quit the active thread
+ bool threaded; //! Whether we run _GenerateWorld threaded
+ int mode; //! What mode are we making a world in
+ byte lp; //! The local_player before generating
+ uint size_x; //! X-size of the map
+ uint size_y; //! Y-size of the map
+ gw_done_proc *proc; //! Proc that is called when done (can be NULL)
+ gw_abort_proc *abortp; //! Proc that is called when aborting (can be NULL)
+ OTTDThread *thread; //! The thread we are in (can be NULL)
+} gw_info;
+
+#ifdef TEMPORARY_OTTDTHREAD_DEFINITION
+#undef OTTDThread
+#undef TEMPORARY_OTTDTHREAD_DEFINITION
+#endif
+
+typedef enum gwp_classes {
+ GWP_MAP_INIT, /* Initialize/allocate the map, start economy */
+ GWP_LANDSCAPE, /* Create the landscape */
+ GWP_ROUGH_ROCKY, /* Make rough and rocky areas */
+ GWP_TOWN, /* Generate towns */
+ GWP_INDUSTRY, /* Generate industries */
+ GWP_UNMOVABLE, /* Generate unmovables (radio tower, light houses) */
+ GWP_TREE, /* Generate trees */
+ GWP_GAME_INIT, /* Initialize the game */
+ GWP_RUNTILELOOP, /* Runs the tile loop 1280 times to make snow etc */
+ GWP_GAME_START, /* Really prepare to start the game */
+ GWP_CLASS_COUNT
+} gwp_class;
+
+/**
+ * Check if we are currently in the process of generating a world.
+ */
+static inline bool IsGeneratingWorld(void)
+{
+ extern gw_info _gw;
+
+ return _gw.active;
+}
+
+/* genworld.c */
+void SetGeneratingWorldPaintStatus(bool status);
+bool IsGeneratingWorldReadyForPaint(void);
+bool IsGenerateWorldThreaded(void);
+void GenerateWorldSetCallback(gw_done_proc *proc);
+void GenerateWorldSetAbortCallback(gw_abort_proc *proc);
+void WaitTillGeneratedWorld(void);
+void GenerateWorld(int mode, uint size_x, uint size_y);
+void AbortGeneratingWorld(void);
+bool IsGeneratingWorldAborted(void);
+void HandleGeneratingWorldAbortion(void);
+
+/* genworld_gui.c */
+void SetGeneratingWorldProgress(gwp_class class, uint total);
+void IncreaseGeneratingWorldProgress(gwp_class class);
+void PrepareGenerateWorldProgress(void);
+void ShowGenerateWorldProgress(void);
+void StartNewGameWithoutGUI(uint seed);
+void ShowCreateScenario(void);
+
+#endif /* GENWORLD_H */
diff --git a/src/genworld_gui.c b/src/genworld_gui.c
new file mode 100644
index 000000000..83d0f4cf1
--- /dev/null
+++ b/src/genworld_gui.c
@@ -0,0 +1,898 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "heightmap.h"
+#include "functions.h"
+#include "table/strings.h"
+#include "table/sprites.h"
+#include "window.h"
+#include "gui.h"
+#include "gfx.h"
+#include "strings.h"
+#include "gfxinit.h"
+#include "player.h"
+#include "command.h"
+#include "sound.h"
+#include "variables.h"
+#include "string.h"
+#include "settings.h"
+#include "debug.h"
+#include "genworld.h"
+#include "network/network.h"
+#include "thread.h"
+#include "date.h"
+#include "newgrf_config.h"
+
+enum {
+ START_DATE_QUERY,
+ SNOW_LINE_QUERY,
+ FLAT_WORLD_HEIGHT_QUERY,
+
+ LEN_RND_SEED = 11,
+ SEED_EDIT = 15,
+};
+
+/**
+ * In what 'mode' the GenerateLandscapeWindowProc is.
+ */
+typedef enum glwp_modes {
+ GLWP_GENERATE,
+ GLWP_HEIGHTMAP,
+ GLWP_SCENARIO,
+ GLWP_END
+} glwp_modes;
+
+static uint _heightmap_x = 0;
+static uint _heightmap_y = 0;
+static StringID _heightmap_str = STR_NULL;
+static bool _goto_editor = false;
+
+extern void SwitchMode(int new_mode);
+
+static inline void SetNewLandscapeType(byte landscape)
+{
+ _opt_newgame.landscape = landscape;
+ InvalidateWindowClasses(WC_SELECT_GAME);
+ InvalidateWindowClasses(WC_GENERATE_LANDSCAPE);
+}
+
+// no longer static to allow calling from outside module
+const Widget _generate_landscape_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 13, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 13, 11, 337, 0, 13, STR_WORLD_GENERATION_CAPTION, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 13, 0, 337, 14, 267, 0x0, STR_NULL},
+
+{ WWT_IMGBTN_2, RESIZE_NONE, 12, 10, 86, 24, 78, SPR_SELECT_TEMPERATE, STR_030E_SELECT_TEMPERATE_LANDSCAPE},
+{ WWT_IMGBTN_2, RESIZE_NONE, 12, 90, 166, 24, 78, SPR_SELECT_SUB_ARCTIC, STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE},
+{ WWT_IMGBTN_2, RESIZE_NONE, 12, 170, 246, 24, 78, SPR_SELECT_SUB_TROPICAL, STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE},
+{ WWT_IMGBTN_2, RESIZE_NONE, 12, 250, 326, 24, 78, SPR_SELECT_TOYLAND, STR_0311_SELECT_TOYLAND_LANDSCAPE},
+
+{ WWT_PANEL, RESIZE_NONE, 12, 114, 149, 90, 101, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 12, 150, 161, 90, 101, STR_0225, STR_NULL}, // Mapsize X
+{ WWT_PANEL, RESIZE_NONE, 12, 180, 215, 90, 101, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 12, 216, 227, 90, 101, STR_0225, STR_NULL}, // Mapsize Y
+
+{ WWT_PANEL, RESIZE_NONE, 12, 114, 163, 112, 123, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 12, 164, 175, 112, 123, STR_0225, STR_NULL}, // Number of towns
+{ WWT_PANEL, RESIZE_NONE, 12, 114, 163, 130, 141, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 12, 164, 175, 130, 141, STR_0225, STR_NULL}, // Number of industries
+
+{ WWT_PANEL, RESIZE_NONE, 15, 114, 207, 152, 163, 0x0, STR_RANDOM_SEED_HELP}, // Edit box for seed
+{ WWT_TEXTBTN, RESIZE_NONE, 12, 216, 326, 152, 163, STR_RANDOM, STR_RANDOM_HELP},
+
+{ WWT_TEXTBTN, RESIZE_NONE, 6, 243, 326, 228, 257, STR_GENERATE, STR_NULL}, // Generate button
+
+{ WWT_IMGBTN, RESIZE_NONE, 12, 216, 227, 112, 123, SPR_ARROW_DOWN, STR_029E_MOVE_THE_STARTING_DATE},
+{ WWT_PANEL, RESIZE_NONE, 12, 228, 314, 112, 123, 0x0, STR_NULL},
+{ WWT_IMGBTN, RESIZE_NONE, 12, 315, 326, 112, 123, SPR_ARROW_UP, STR_029F_MOVE_THE_STARTING_DATE},
+
+{ WWT_IMGBTN, RESIZE_NONE, 12, 282, 293, 130, 141, SPR_ARROW_DOWN, STR_SNOW_LINE_DOWN},
+{ WWT_PANEL, RESIZE_NONE, 12, 294, 314, 130, 141, 0x0, STR_NULL},
+{ WWT_IMGBTN, RESIZE_NONE, 12, 315, 326, 130, 141, SPR_ARROW_UP, STR_SNOW_LINE_UP},
+
+{ WWT_PANEL, RESIZE_NONE, 12, 114, 219, 192, 203, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 12, 220, 231, 192, 203, STR_0225, STR_NULL}, // Tree placer
+
+{ WWT_PANEL, RESIZE_NONE, 12, 114, 219, 174, 185, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 12, 220, 231, 174, 185, STR_0225, STR_NULL}, // Landscape generator
+{ WWT_PANEL, RESIZE_NONE, 12, 114, 219, 210, 221, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 12, 220, 231, 210, 221, STR_0225, STR_NULL}, // Terrain type
+{ WWT_PANEL, RESIZE_NONE, 12, 113, 219, 228, 239, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 12, 220, 231, 228, 239, STR_0225, STR_NULL}, // Water quantity
+{ WWT_PANEL, RESIZE_NONE, 12, 113, 219, 246, 257, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 12, 220, 231, 246, 257, STR_0225, STR_NULL}, // Map smoothness
+{ WIDGETS_END},
+};
+
+const Widget _heightmap_load_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 13, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 13, 11, 337, 0, 13, STR_WORLD_GENERATION_CAPTION, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 13, 0, 337, 14, 235, 0x0, STR_NULL},
+
+{ WWT_IMGBTN_2, RESIZE_NONE, 12, 10, 86, 24, 78, SPR_SELECT_TEMPERATE, STR_030E_SELECT_TEMPERATE_LANDSCAPE},
+{ WWT_IMGBTN_2, RESIZE_NONE, 12, 90, 166, 24, 78, SPR_SELECT_SUB_ARCTIC, STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE},
+{ WWT_IMGBTN_2, RESIZE_NONE, 12, 170, 246, 24, 78, SPR_SELECT_SUB_TROPICAL, STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE},
+{ WWT_IMGBTN_2, RESIZE_NONE, 12, 250, 326, 24, 78, SPR_SELECT_TOYLAND, STR_0311_SELECT_TOYLAND_LANDSCAPE},
+
+{ WWT_PANEL, RESIZE_NONE, 12, 114, 149, 112, 123, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 12, 150, 161, 112, 123, STR_0225, STR_NULL}, // Mapsize X
+{ WWT_PANEL, RESIZE_NONE, 12, 180, 215, 112, 123, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 12, 216, 227, 112, 123, STR_0225, STR_NULL}, // Mapsize Y
+
+{ WWT_PANEL, RESIZE_NONE, 12, 114, 163, 134, 145, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 12, 164, 175, 134, 145, STR_0225, STR_NULL}, // Number of towns
+{ WWT_PANEL, RESIZE_NONE, 12, 114, 163, 152, 163, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 12, 164, 175, 152, 163, STR_0225, STR_NULL}, // Number of industries
+
+{ WWT_PANEL, RESIZE_NONE, 15, 114, 194, 174, 185, 0x0, STR_RANDOM_SEED_HELP}, // Edit box for seed
+{ WWT_TEXTBTN, RESIZE_NONE, 12, 203, 285, 174, 185, STR_RANDOM, STR_RANDOM_HELP},
+
+{ WWT_TEXTBTN, RESIZE_NONE, 6, 243, 326, 196, 225, STR_GENERATE, STR_NULL}, // Generate button
+
+{ WWT_IMGBTN, RESIZE_NONE, 12, 216, 227, 134, 145, SPR_ARROW_DOWN, STR_029E_MOVE_THE_STARTING_DATE},
+{ WWT_PANEL, RESIZE_NONE, 12, 228, 314, 134, 145, 0x0, STR_NULL},
+{ WWT_IMGBTN, RESIZE_NONE, 12, 315, 326, 134, 145, SPR_ARROW_UP, STR_029F_MOVE_THE_STARTING_DATE},
+
+{ WWT_IMGBTN, RESIZE_NONE, 12, 282, 293, 152, 163, SPR_ARROW_DOWN, STR_SNOW_LINE_DOWN},
+{ WWT_PANEL, RESIZE_NONE, 12, 294, 314, 152, 163, 0x0, STR_NULL},
+{ WWT_IMGBTN, RESIZE_NONE, 12, 315, 326, 152, 163, SPR_ARROW_UP, STR_SNOW_LINE_UP},
+
+{ WWT_PANEL, RESIZE_NONE, 12, 114, 219, 196, 207, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 12, 220, 231, 196, 207, STR_0225, STR_NULL}, // Tree placer
+
+{ WWT_PANEL, RESIZE_NONE, 12, 114, 219, 214, 225, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 12, 220, 231, 214, 225, STR_0225, STR_NULL}, // Heightmap rotation
+{ WIDGETS_END},
+};
+
+static void StartGeneratingLandscape(glwp_modes mode)
+{
+ /* If we want to go to the editor, and aren't yet, we need to delay
+ * it as long as possible, else it gives nasty side-effects (aborting
+ * results in ending up in the SE, which you don't want. Therefor we
+ * use this switch to do it at the very end.
+ */
+ if (_goto_editor) _game_mode = GM_EDITOR;
+
+ DeleteWindowByClass(WC_GENERATE_LANDSCAPE);
+ DeleteWindowByClass(WC_INDUSTRY_VIEW);
+ DeleteWindowByClass(WC_TOWN_VIEW);
+ DeleteWindowByClass(WC_LAND_INFO);
+
+ /* Copy all XXX_newgame to XXX */
+ UpdatePatches();
+ _opt_ptr = &_opt;
+ *_opt_ptr = _opt_newgame;
+ ResetGRFConfig(true);
+
+ SndPlayFx(SND_15_BEEP);
+ switch (mode) {
+ case GLWP_GENERATE: _switch_mode = (_game_mode == GM_EDITOR) ? SM_GENRANDLAND : SM_NEWGAME; break;
+ case GLWP_HEIGHTMAP: _switch_mode = (_game_mode == GM_EDITOR) ? SM_LOAD_HEIGHTMAP : SM_START_HEIGHTMAP; break;
+ case GLWP_SCENARIO: _switch_mode = SM_EDITOR; break;
+ default: NOT_REACHED(); return;
+ }
+}
+
+static void HeightmapScaledTooMuchCallback(Window *w, bool confirmed)
+{
+ if (confirmed) StartGeneratingLandscape((glwp_modes)w->window_number);
+}
+
+void GenerateLandscapeWndProc(Window *w, WindowEvent *e)
+{
+ static const StringID mapsizes[] = {STR_64, STR_128, STR_256, STR_512, STR_1024, STR_2048, INVALID_STRING_ID};
+ static const StringID elevations[] = {STR_682A_VERY_FLAT, STR_682B_FLAT, STR_682C_HILLY, STR_682D_MOUNTAINOUS, INVALID_STRING_ID};
+ static const StringID sea_lakes[] = {STR_VERY_LOW, STR_6820_LOW, STR_6821_MEDIUM, STR_6822_HIGH, INVALID_STRING_ID};
+ static const StringID smoothness[] = {STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH, STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH, STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH, STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH, INVALID_STRING_ID};
+ static const StringID tree_placer[] = {STR_CONFIG_PATCHES_TREE_PLACER_NONE, STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL, STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED, INVALID_STRING_ID};
+ static const StringID rotation[] = {STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE, STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE, INVALID_STRING_ID};
+ static const StringID landscape[] = {STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL, STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS, INVALID_STRING_ID};
+ static const StringID num_towns[] = {STR_6816_LOW, STR_6817_NORMAL, STR_6818_HIGH, INVALID_STRING_ID};
+ static const StringID num_inds[] = {STR_26816_NONE, STR_6816_LOW, STR_6817_NORMAL, STR_6818_HIGH, INVALID_STRING_ID};
+
+ /* Data used for the generate seed edit box */
+ static querystr_d _genseed_query;
+ static char _genseed_buffer[LEN_RND_SEED];
+
+ uint mode = w->window_number;
+ uint y;
+
+ switch (e->event) {
+ case WE_CREATE:
+ LowerWindowWidget(w, _opt_newgame.landscape + 3);
+
+ snprintf(_genseed_buffer, sizeof(_genseed_buffer), "%u", _patches_newgame.generation_seed);
+ InitializeTextBuffer(&_genseed_query.text, _genseed_buffer, lengthof(_genseed_buffer), 120);
+ _genseed_query.caption = STR_NULL;
+ _genseed_query.afilter = CS_NUMERAL;
+ break;
+
+ case WE_PAINT:
+ /* You can't select smoothness if not terragenesis */
+ if (mode == GLWP_GENERATE) {
+ SetWindowWidgetDisabledState(w, 32, _patches_newgame.land_generator == 0);
+ SetWindowWidgetDisabledState(w, 33, _patches_newgame.land_generator == 0);
+ }
+ /* Disable snowline if not hilly */
+ SetWindowWidgetDisabledState(w, 22, _opt_newgame.landscape != LT_HILLY);
+ /* Disable town and industry in SE */
+ SetWindowWidgetDisabledState(w, 11, _game_mode == GM_EDITOR);
+ SetWindowWidgetDisabledState(w, 12, _game_mode == GM_EDITOR);
+ SetWindowWidgetDisabledState(w, 13, _game_mode == GM_EDITOR);
+ SetWindowWidgetDisabledState(w, 14, _game_mode == GM_EDITOR);
+ SetWindowWidgetDisabledState(w, 24, _game_mode == GM_EDITOR);
+ SetWindowWidgetDisabledState(w, 25, _game_mode == GM_EDITOR);
+
+ SetWindowWidgetDisabledState(w, 18, _patches_newgame.starting_year <= MIN_YEAR);
+ SetWindowWidgetDisabledState(w, 20, _patches_newgame.starting_year >= MAX_YEAR);
+ SetWindowWidgetDisabledState(w, 21, _patches_newgame.snow_line_height <= 2 || _opt_newgame.landscape != LT_HILLY);
+ SetWindowWidgetDisabledState(w, 23, _patches_newgame.snow_line_height >= 13 || _opt_newgame.landscape != LT_HILLY);
+
+ SetWindowWidgetLoweredState(w, 3, _opt_newgame.landscape == LT_NORMAL);
+ SetWindowWidgetLoweredState(w, 4, _opt_newgame.landscape == LT_HILLY);
+ SetWindowWidgetLoweredState(w, 5, _opt_newgame.landscape == LT_DESERT);
+ SetWindowWidgetLoweredState(w, 6, _opt_newgame.landscape == LT_CANDY);
+ DrawWindowWidgets(w);
+
+ y = (mode == GLWP_HEIGHTMAP) ? 22 : 0;
+
+ DrawString( 12, 91 + y, STR_MAPSIZE, 0);
+ DrawString(119, 91 + y, mapsizes[_patches_newgame.map_x - 6], 0x10);
+ DrawString(168, 91 + y, STR_BY, 0);
+ DrawString(182, 91 + y, mapsizes[_patches_newgame.map_y - 6], 0x10);
+
+ DrawString( 12, 113 + y, STR_NUMBER_OF_TOWNS, 0);
+ DrawString( 12, 131 + y, STR_NUMBER_OF_INDUSTRIES, 0);
+ if (_game_mode == GM_EDITOR) {
+ DrawString(118, 113 + y, STR_6836_OFF, 0x10);
+ DrawString(118, 131 + y, STR_6836_OFF, 0x10);
+ } else {
+ DrawString(118, 113 + y, num_towns[_opt_newgame.diff.number_towns], 0x10);
+ DrawString(118, 131 + y, num_inds[_opt_newgame.diff.number_industries], 0x10);
+ }
+
+ DrawString( 12, 153 + y, STR_RANDOM_SEED, 0);
+ DrawEditBox(w, &_genseed_query, SEED_EDIT);
+
+ DrawString(182, 113 + y, STR_DATE, 0);
+ SetDParam(0, ConvertYMDToDate(_patches_newgame.starting_year, 0, 1));
+ DrawStringCentered(271, 113 + y, STR_GENERATE_DATE, 0);
+
+ DrawString(182, 131 + y, STR_SNOW_LINE_HEIGHT, 0);
+ SetDParam(0, _patches_newgame.snow_line_height);
+ DrawStringCentered(303, 131 + y, STR_SNOW_LINE_HEIGHT_NUM, 0x10);
+
+ if (mode == GLWP_GENERATE) {
+ DrawString( 12, 175, STR_LAND_GENERATOR, 0);
+ DrawString(118, 175, landscape[_patches_newgame.land_generator], 0x10);
+
+ DrawString( 12, 193, STR_TREE_PLACER, 0);
+ DrawString(118, 193, tree_placer[_patches_newgame.tree_placer], 0x10);
+
+ DrawString( 12, 211, STR_TERRAIN_TYPE, 0);
+ DrawString(118, 211, elevations[_opt_newgame.diff.terrain_type], 0x10);
+
+ DrawString( 12, 229, STR_QUANTITY_OF_SEA_LAKES, 0);
+ DrawString(118, 229, sea_lakes[_opt_newgame.diff.quantity_sea_lakes], 0x10);
+
+ DrawString( 12, 247, STR_SMOOTHNESS, 0);
+ DrawString(118, 247, smoothness[_patches_newgame.tgen_smoothness], 0x10);
+ } else {
+ char buffer[512];
+
+ if (_patches_newgame.heightmap_rotation == HM_CLOCKWISE) {
+ SetDParam(0, _heightmap_y);
+ SetDParam(1, _heightmap_x);
+ } else {
+ SetDParam(0, _heightmap_x);
+ SetDParam(1, _heightmap_y);
+ }
+ GetString(buffer, STR_HEIGHTMAP_SIZE, lastof(buffer));
+ DrawStringRightAligned(326, 91, STR_HEIGHTMAP_SIZE, 0x10);
+
+ DrawString( 12, 91, STR_HEIGHTMAP_NAME, 0x10);
+ SetDParam(0, _heightmap_str);
+ DrawStringTruncated(114, 91, STR_ORANGE, 0x10, 326 - 114 - GetStringBoundingBox(buffer).width - 5);
+
+ DrawString( 12, 197, STR_TREE_PLACER, 0);
+ DrawString(118, 197, tree_placer[_patches_newgame.tree_placer], 0x10);
+
+ DrawString( 12, 215, STR_HEIGHTMAP_ROTATION, 0);
+ DrawString(118, 215, rotation[_patches_newgame.heightmap_rotation], 0x10);
+ }
+
+ break;
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 0: DeleteWindow(w); break;
+ case 3: case 4: case 5: case 6:
+ RaiseWindowWidget(w, _opt_newgame.landscape + 3);
+ SetNewLandscapeType(e->we.click.widget - 3);
+ break;
+ case 7: case 8: // Mapsize X
+ ShowDropDownMenu(w, mapsizes, _patches_newgame.map_x - 6, 8, 0, 0);
+ break;
+ case 9: case 10: // Mapsize Y
+ ShowDropDownMenu(w, mapsizes, _patches_newgame.map_y - 6, 10, 0, 0);
+ break;
+ case 11: case 12: // Number of towns
+ ShowDropDownMenu(w, num_towns, _opt_newgame.diff.number_towns, 12, 0, 0);
+ break;
+ case 13: case 14: // Number of industries
+ ShowDropDownMenu(w, num_inds, _opt_newgame.diff.number_industries, 14, 0, 0);
+ break;
+ case 16: // Random seed
+ _patches_newgame.generation_seed = InteractiveRandom();
+ snprintf(_genseed_buffer, lengthof(_genseed_buffer), "%u", _patches_newgame.generation_seed);
+ UpdateTextBufferSize(&_genseed_query.text);
+ SetWindowDirty(w);
+ break;
+ case 17: // Generate
+ if (mode == GLWP_HEIGHTMAP && (
+ _heightmap_x * 2 < (1U << _patches_newgame.map_x) || _heightmap_x / 2 > (1U << _patches_newgame.map_x) ||
+ _heightmap_y * 2 < (1U << _patches_newgame.map_y) || _heightmap_y / 2 > (1U << _patches_newgame.map_y))) {
+ ShowQuery(
+ STR_HEIGHTMAP_SCALE_WARNING_CAPTION,
+ STR_HEIGHTMAP_SCALE_WARNING_MESSAGE,
+ w,
+ HeightmapScaledTooMuchCallback);
+ } else {
+ StartGeneratingLandscape(mode);
+ }
+ break;
+ case 18: case 20: // Year buttons
+ /* Don't allow too fast scrolling */
+ if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) {
+ HandleButtonClick(w, e->we.click.widget);
+ SetWindowDirty(w);
+
+ _patches_newgame.starting_year = clamp(_patches_newgame.starting_year + e->we.click.widget - 19, MIN_YEAR, MAX_YEAR);
+ }
+ _left_button_clicked = false;
+ break;
+ case 19: // Year text
+ WP(w, def_d).data_3 = START_DATE_QUERY;
+ SetDParam(0, _patches_newgame.starting_year);
+ ShowQueryString(STR_CONFIG_PATCHES_INT32, STR_START_DATE_QUERY_CAPT, 8, 100, w, CS_NUMERAL);
+ break;
+ case 21: case 23: // Snow line buttons
+ /* Don't allow too fast scrolling */
+ if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) {
+ HandleButtonClick(w, e->we.click.widget);
+ SetWindowDirty(w);
+
+ _patches_newgame.snow_line_height = clamp(_patches_newgame.snow_line_height + e->we.click.widget - 22, 2, 13);
+ }
+ _left_button_clicked = false;
+ break;
+ case 22: // Snow line text
+ WP(w, def_d).data_3 = SNOW_LINE_QUERY;
+ SetDParam(0, _patches_newgame.snow_line_height);
+ ShowQueryString(STR_CONFIG_PATCHES_INT32, STR_SNOW_LINE_QUERY_CAPT, 3, 100, w, CS_NUMERAL);
+ break;
+ case 24: case 25: // Tree placer
+ ShowDropDownMenu(w, tree_placer, _patches_newgame.tree_placer, 25, 0, 0);
+ break;
+ case 26: case 27: // Landscape generator OR Heightmap rotation
+ if (mode == GLWP_HEIGHTMAP) {
+ ShowDropDownMenu(w, rotation, _patches_newgame.heightmap_rotation, 27, 0, 0);
+ } else {
+ ShowDropDownMenu(w, landscape, _patches_newgame.land_generator, 27, 0, 0);
+ }
+ break;
+ case 28: case 29: // Terrain type
+ ShowDropDownMenu(w, elevations, _opt_newgame.diff.terrain_type, 29, 0, 0);
+ break;
+ case 30: case 31: // Water quantity
+ ShowDropDownMenu(w, sea_lakes, _opt_newgame.diff.quantity_sea_lakes, 31, 0, 0);
+ break;
+ case 32: case 33: // Map smoothness
+ ShowDropDownMenu(w, smoothness, _patches_newgame.tgen_smoothness, 33, 0, 0);
+ break;
+ }
+ break;
+
+ case WE_MOUSELOOP:
+ HandleEditBox(w, &_genseed_query, SEED_EDIT);
+ break;
+
+ case WE_KEYPRESS:
+ HandleEditBoxKey(w, &_genseed_query, SEED_EDIT, e);
+ /* the seed is unsigned, therefore atoi cannot be used.
+ * As 2^32 - 1 (MAX_UVALUE(uint32)) is a 'magic' value
+ * (use random seed) it should not be possible to be
+ * entered into the input field; the generate seed
+ * button can be used instead. */
+ _patches_newgame.generation_seed = minu(strtoul(_genseed_buffer, NULL, sizeof(_genseed_buffer) - 1), MAX_UVALUE(uint32) - 1);
+ break;
+
+ case WE_DROPDOWN_SELECT:
+ switch (e->we.dropdown.button) {
+ case 8: _patches_newgame.map_x = e->we.dropdown.index + 6; break;
+ case 10: _patches_newgame.map_y = e->we.dropdown.index + 6; break;
+ case 12:
+ _opt_newgame.diff.number_towns = e->we.dropdown.index;
+ if (_opt_newgame.diff_level != 3) ShowErrorMessage(INVALID_STRING_ID, STR_DIFFICULTY_TO_CUSTOM, 0, 0);
+ DoCommandP(0, 2, _opt_newgame.diff.number_towns, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
+ break;
+ case 14:
+ _opt_newgame.diff.number_industries = e->we.dropdown.index;
+ if (_opt_newgame.diff_level != 3) ShowErrorMessage(INVALID_STRING_ID, STR_DIFFICULTY_TO_CUSTOM, 0, 0);
+ DoCommandP(0, 3, _opt_newgame.diff.number_industries, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
+ break;
+ case 25:
+ _patches_newgame.tree_placer = e->we.dropdown.index;
+ break;
+ case 27:
+ if (mode == GLWP_HEIGHTMAP) {
+ _patches_newgame.heightmap_rotation = e->we.dropdown.index;
+ } else {
+ _patches_newgame.land_generator = e->we.dropdown.index;
+ }
+ break;
+ case 29:
+ _opt_newgame.diff.terrain_type = e->we.dropdown.index;
+ if (_opt_newgame.diff_level != 3) ShowErrorMessage(INVALID_STRING_ID, STR_DIFFICULTY_TO_CUSTOM, 0, 0);
+ DoCommandP(0, 12, _opt_newgame.diff.terrain_type, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
+ break;
+ case 31:
+ _opt_newgame.diff.quantity_sea_lakes = e->we.dropdown.index;
+ if (_opt_newgame.diff_level != 3) ShowErrorMessage(INVALID_STRING_ID, STR_DIFFICULTY_TO_CUSTOM, 0, 0);
+ DoCommandP(0, 13, _opt_newgame.diff.quantity_sea_lakes, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
+ break;
+ case 33:
+ _patches_newgame.tgen_smoothness = e->we.dropdown.index;
+ break;
+ }
+ SetWindowDirty(w);
+ break;
+
+ case WE_ON_EDIT_TEXT: {
+ if (e->we.edittext.str != NULL) {
+ int32 value = atoi(e->we.edittext.str);
+
+ switch (WP(w, def_d).data_3) {
+ case START_DATE_QUERY:
+ InvalidateWidget(w, 19);
+ _patches_newgame.starting_year = clamp(value, MIN_YEAR, MAX_YEAR);
+ break;
+ case SNOW_LINE_QUERY:
+ InvalidateWidget(w, 22);
+ _patches_newgame.snow_line_height = clamp(value, 2, 13);
+ break;
+ }
+
+ SetWindowDirty(w);
+ }
+ break;
+ }
+ }
+}
+
+const WindowDesc _generate_landscape_desc = {
+ WDP_CENTER, WDP_CENTER, 338, 268,
+ WC_GENERATE_LANDSCAPE, 0,
+ WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _generate_landscape_widgets,
+ GenerateLandscapeWndProc,
+};
+
+const WindowDesc _heightmap_load_desc = {
+ WDP_CENTER, WDP_CENTER, 338, 236,
+ WC_GENERATE_LANDSCAPE, 0,
+ WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _heightmap_load_widgets,
+ GenerateLandscapeWndProc,
+};
+
+static void _ShowGenerateLandscape(glwp_modes mode)
+{
+ Window *w;
+
+ /* Don't kill WC_GENERATE_LANDSCAPE:GLWP_SCENARIO, because it resets
+ * _goto_editor, which we maybe need later on. */
+ DeleteWindowById(WC_GENERATE_LANDSCAPE, GLWP_GENERATE);
+ DeleteWindowById(WC_GENERATE_LANDSCAPE, GLWP_HEIGHTMAP);
+
+ /* Always give a new seed if not editor */
+ if (_game_mode != GM_EDITOR) _patches_newgame.generation_seed = InteractiveRandom();
+
+ if (mode == GLWP_HEIGHTMAP) {
+ if (_heightmap_str != STR_NULL) DeleteName(_heightmap_str);
+
+ _heightmap_x = 0;
+ _heightmap_y = 0;
+ _heightmap_str = AllocateName(_file_to_saveload.title, 0);
+ /* If the function returns negative, it means there was a problem loading the heightmap */
+ if (!GetHeightmapDimensions(_file_to_saveload.name, &_heightmap_x, &_heightmap_y))
+ return;
+ }
+
+ w = AllocateWindowDescFront((mode == GLWP_HEIGHTMAP) ? &_heightmap_load_desc : &_generate_landscape_desc, mode);
+
+ if (w != NULL) {
+
+ InvalidateWindow(WC_GENERATE_LANDSCAPE, mode);
+ }
+}
+
+void ShowGenerateLandscape(void)
+{
+ _ShowGenerateLandscape(GLWP_GENERATE);
+}
+
+void ShowHeightmapLoad(void)
+{
+ _ShowGenerateLandscape(GLWP_HEIGHTMAP);
+}
+
+void StartNewGameWithoutGUI(uint seed)
+{
+ /* GenerateWorld takes care of the possible GENERATE_NEW_SEED value in 'seed' */
+ _patches_newgame.generation_seed = seed;
+
+ StartGeneratingLandscape(GLWP_GENERATE);
+}
+
+
+void CreateScenarioWndProc(Window *w, WindowEvent *e)
+{
+ static const StringID mapsizes[] = {STR_64, STR_128, STR_256, STR_512, STR_1024, STR_2048, INVALID_STRING_ID};
+
+ switch (e->event) {
+ case WE_CREATE: LowerWindowWidget(w, _opt_newgame.landscape + 3); break;
+
+ case WE_PAINT:
+ SetWindowWidgetDisabledState(w, 14, _patches_newgame.starting_year <= MIN_YEAR);
+ SetWindowWidgetDisabledState(w, 16, _patches_newgame.starting_year >= MAX_YEAR);
+ SetWindowWidgetDisabledState(w, 17, _patches_newgame.se_flat_world_height <= 0);
+ SetWindowWidgetDisabledState(w, 19, _patches_newgame.se_flat_world_height >= 15);
+
+ SetWindowWidgetLoweredState(w, 3, _opt_newgame.landscape == LT_NORMAL);
+ SetWindowWidgetLoweredState(w, 4, _opt_newgame.landscape == LT_HILLY);
+ SetWindowWidgetLoweredState(w, 5, _opt_newgame.landscape == LT_DESERT);
+ SetWindowWidgetLoweredState(w, 6, _opt_newgame.landscape == LT_CANDY);
+ DrawWindowWidgets(w);
+
+ DrawString( 12, 96, STR_MAPSIZE, 0);
+ DrawString(167, 96, mapsizes[_patches_newgame.map_x - 6], 0x10);
+ DrawString(216, 96, STR_BY, 0);
+ DrawString(230, 96, mapsizes[_patches_newgame.map_y - 6], 0x10);
+
+ DrawString(162, 118, STR_DATE, 0);
+ SetDParam(0, ConvertYMDToDate(_patches_newgame.starting_year, 0, 1));
+ DrawStringCentered(271, 118, STR_GENERATE_DATE, 0);
+
+ DrawString(162, 136, STR_FLAT_WORLD_HEIGHT, 0);
+ SetDParam(0, _patches_newgame.se_flat_world_height);
+ DrawStringCentered(303, 136, STR_FLAT_WORLD_HEIGHT_NUM, 0x10);
+
+ break;
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 0: DeleteWindow(w); break;
+ case 3: case 4: case 5: case 6:
+ RaiseWindowWidget(w, _opt_newgame.landscape + 3);
+ SetNewLandscapeType(e->we.click.widget - 3);
+ break;
+ case 7: case 8: // Mapsize X
+ ShowDropDownMenu(w, mapsizes, _patches_newgame.map_x - 6, 8, 0, 0);
+ break;
+ case 9: case 10: // Mapsize Y
+ ShowDropDownMenu(w, mapsizes, _patches_newgame.map_y - 6, 10, 0, 0);
+ break;
+ case 11: // Empty world / flat world
+ StartGeneratingLandscape(GLWP_SCENARIO);
+ break;
+ case 12: // Generate
+ _goto_editor = true;
+ ShowGenerateLandscape();
+ break;
+ case 13: // Heightmap
+ _goto_editor = true;
+ ShowSaveLoadDialog(SLD_LOAD_HEIGHTMAP);
+ break;
+ case 14: case 16: // Year buttons
+ /* Don't allow too fast scrolling */
+ if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) {
+ HandleButtonClick(w, e->we.click.widget);
+ SetWindowDirty(w);
+
+ _patches_newgame.starting_year = clamp(_patches_newgame.starting_year + e->we.click.widget - 15, MIN_YEAR, MAX_YEAR);
+ }
+ _left_button_clicked = false;
+ break;
+ case 15: // Year text
+ WP(w, def_d).data_3 = START_DATE_QUERY;
+ SetDParam(0, _patches_newgame.starting_year);
+ ShowQueryString(STR_CONFIG_PATCHES_INT32, STR_START_DATE_QUERY_CAPT, 8, 100, w, CS_NUMERAL);
+ break;
+ case 17: case 19: // Height level buttons
+ /* Don't allow too fast scrolling */
+ if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) {
+ HandleButtonClick(w, e->we.click.widget);
+ SetWindowDirty(w);
+
+ _patches_newgame.se_flat_world_height = clamp(_patches_newgame.se_flat_world_height + e->we.click.widget - 18, 0, 15);
+ }
+ _left_button_clicked = false;
+ break;
+ case 18: // Height level text
+ WP(w, def_d).data_3 = FLAT_WORLD_HEIGHT_QUERY;
+ SetDParam(0, _patches_newgame.se_flat_world_height);
+ ShowQueryString(STR_CONFIG_PATCHES_INT32, STR_FLAT_WORLD_HEIGHT_QUERY_CAPT, 3, 100, w, CS_NUMERAL);
+ break;
+ }
+ break;
+
+ case WE_DROPDOWN_SELECT:
+ switch (e->we.dropdown.button) {
+ case 8: _patches_newgame.map_x = e->we.dropdown.index + 6; break;
+ case 10: _patches_newgame.map_y = e->we.dropdown.index + 6; break;
+ }
+ SetWindowDirty(w);
+ break;
+
+ case WE_DESTROY:
+ _goto_editor = false;
+ break;
+
+ case WE_ON_EDIT_TEXT: {
+ if (e->we.edittext.str != NULL) {
+ int32 value = atoi(e->we.edittext.str);
+
+ switch (WP(w, def_d).data_3) {
+ case START_DATE_QUERY:
+ InvalidateWidget(w, 15);
+ _patches_newgame.starting_year = clamp(value, MIN_YEAR, MAX_YEAR);
+ break;
+ case FLAT_WORLD_HEIGHT_QUERY:
+ InvalidateWidget(w, 18);
+ _patches_newgame.se_flat_world_height = clamp(value, 0, 15);
+ break;
+ }
+
+ SetWindowDirty(w);
+ }
+ break;
+ }
+ }
+}
+
+const Widget _create_scenario_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 13, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 13, 11, 337, 0, 13, STR_SE_CAPTION, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 13, 0, 337, 14, 179, 0x0, STR_NULL},
+
+{ WWT_IMGBTN_2, RESIZE_NONE, 12, 10, 86, 24, 78, SPR_SELECT_TEMPERATE, STR_030E_SELECT_TEMPERATE_LANDSCAPE},
+{ WWT_IMGBTN_2, RESIZE_NONE, 12, 90, 166, 24, 78, SPR_SELECT_SUB_ARCTIC, STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE},
+{ WWT_IMGBTN_2, RESIZE_NONE, 12, 170, 246, 24, 78, SPR_SELECT_SUB_TROPICAL, STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE},
+{ WWT_IMGBTN_2, RESIZE_NONE, 12, 250, 326, 24, 78, SPR_SELECT_TOYLAND, STR_0311_SELECT_TOYLAND_LANDSCAPE},
+
+{ WWT_PANEL, RESIZE_NONE, 12, 162, 197, 95, 106, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 12, 198, 209, 95, 106, STR_0225, STR_NULL}, // Mapsize X
+{ WWT_PANEL, RESIZE_NONE, 12, 228, 263, 95, 106, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 12, 264, 275, 95, 106, STR_0225, STR_NULL}, // Mapsize Y
+
+{ WWT_TEXTBTN, RESIZE_NONE, 6, 12, 145, 117, 128, STR_SE_FLAT_WORLD, STR_SE_FLAT_WORLD_TIP}, // Empty (sea-level) map
+{ WWT_TEXTBTN, RESIZE_NONE, 6, 12, 145, 135, 146, STR_SE_RANDOM_LAND, STR_022A_GENERATE_RANDOM_LAND}, // Generate
+{ WWT_TEXTBTN, RESIZE_NONE, 6, 12, 145, 153, 164, STR_LOAD_GAME_HEIGHTMAP, STR_LOAD_SCEN_HEIGHTMAP}, // Heightmap
+
+{ WWT_IMGBTN, RESIZE_NONE, 12, 216, 227, 117, 128, SPR_ARROW_DOWN, STR_029E_MOVE_THE_STARTING_DATE},
+{ WWT_PANEL, RESIZE_NONE, 12, 228, 314, 117, 128, 0x0, STR_NULL},
+{ WWT_IMGBTN, RESIZE_NONE, 12, 315, 326, 117, 128, SPR_ARROW_UP, STR_029F_MOVE_THE_STARTING_DATE},
+
+{ WWT_IMGBTN, RESIZE_NONE, 12, 282, 293, 135, 146, SPR_ARROW_DOWN, STR_FLAT_WORLD_HEIGHT_DOWN},
+{ WWT_PANEL, RESIZE_NONE, 12, 294, 314, 135, 146, 0x0, STR_NULL},
+{ WWT_IMGBTN, RESIZE_NONE, 12, 315, 326, 135, 146, SPR_ARROW_UP, STR_FLAT_WORLD_HEIGHT_UP},
+{ WIDGETS_END},
+};
+
+const WindowDesc _create_scenario_desc = {
+ WDP_CENTER, WDP_CENTER, 338, 180,
+ WC_GENERATE_LANDSCAPE, 0,
+ WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _create_scenario_widgets,
+ CreateScenarioWndProc,
+};
+
+void ShowCreateScenario(void)
+{
+ DeleteWindowByClass(WC_GENERATE_LANDSCAPE);
+ AllocateWindowDescFront(&_create_scenario_desc, GLWP_SCENARIO);
+}
+
+
+static const Widget _show_terrain_progress_widgets[] = {
+{ WWT_CAPTION, RESIZE_NONE, 14, 0, 180, 0, 13, STR_GENERATION_WORLD, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 180, 14, 96, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 15, 20, 161, 74, 85, STR_GENERATION_ABORT, STR_NULL}, // Abort button
+{ WIDGETS_END},
+};
+
+typedef struct tp_info {
+ uint percent;
+ StringID class;
+ uint current;
+ uint total;
+ int timer;
+} tp_info;
+
+static tp_info _tp;
+
+static void AbortGeneratingWorldCallback(Window *w, bool confirmed)
+{
+ if (confirmed) {
+ AbortGeneratingWorld();
+ } else if (IsGeneratingWorld() && !IsGeneratingWorldAborted()) {
+ SetMouseCursor(SPR_CURSOR_ZZZ);
+ }
+}
+
+static void ShowTerrainProgressProc(Window* w, WindowEvent* e)
+{
+ switch (e->event) {
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 2:
+ if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE);
+ ShowQuery(
+ STR_GENERATION_ABORT_CAPTION,
+ STR_GENERATION_ABORT_MESSAGE,
+ w,
+ AbortGeneratingWorldCallback
+ );
+ break;
+ }
+ break;
+
+ case WE_PAINT:
+ DrawWindowWidgets(w);
+
+ /* Draw the % complete with a bar and a text */
+ DrawFrameRect(19, 20, (w->width - 18), 37, 14, FR_BORDERONLY);
+ DrawFrameRect(20, 21, (int)((w->width - 40) * _tp.percent / 100) + 20, 36, 10, 0);
+ SetDParam(0, _tp.percent);
+ DrawStringCentered(90, 25, STR_PROGRESS, 0);
+
+ /* Tell which class we are generating */
+ DrawStringCentered(90, 46, _tp.class, 0);
+
+ /* And say where we are in that class */
+ SetDParam(0, _tp.current);
+ SetDParam(1, _tp.total);
+ DrawStringCentered(90, 58, STR_GENERATION_PROGRESS, 0);
+
+ SetWindowDirty(w);
+ break;
+ }
+}
+
+static const WindowDesc _show_terrain_progress_desc = {
+ WDP_CENTER, WDP_CENTER, 181, 97,
+ WC_GENERATE_PROGRESS_WINDOW, 0,
+ WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _show_terrain_progress_widgets,
+ ShowTerrainProgressProc
+};
+
+/**
+ * Initializes the progress counters to the starting point.
+ */
+void PrepareGenerateWorldProgress(void)
+{
+ _tp.class = STR_WORLD_GENERATION;
+ _tp.current = 0;
+ _tp.total = 0;
+ _tp.percent = 0;
+ _tp.timer = 0; // Forces to paint the progress window immediatelly
+}
+
+/**
+ * Show the window where a user can follow the process of the map generation.
+ */
+void ShowGenerateWorldProgress(void)
+{
+ AllocateWindowDescFront(&_show_terrain_progress_desc, 0);
+}
+
+static void _SetGeneratingWorldProgress(gwp_class class, uint progress, uint total)
+{
+ static const int percent_table[GWP_CLASS_COUNT + 1] = {0, 5, 15, 20, 40, 60, 65, 80, 85, 99, 100 };
+ static const StringID class_table[GWP_CLASS_COUNT] = {
+ STR_WORLD_GENERATION,
+ STR_022E_LANDSCAPE_GENERATION,
+ STR_CLEARING_TILES,
+ STR_022F_TOWN_GENERATION,
+ STR_0230_INDUSTRY_GENERATION,
+ STR_UNMOVABLE_GENERATION,
+ STR_TREE_GENERATION,
+ STR_SETTINGUP_GAME,
+ STR_PREPARING_TILELOOP,
+ STR_PREPARING_GAME
+ };
+
+ assert(class < GWP_CLASS_COUNT);
+
+ /* Do not run this function if we aren't in a thread */
+ if (!IsGenerateWorldThreaded() && !_network_dedicated) return;
+
+ if (IsGeneratingWorldAborted()) HandleGeneratingWorldAbortion();
+
+ if (total == 0) {
+ assert(_tp.class == class_table[class]);
+ _tp.current += progress;
+ } else {
+ _tp.class = class_table[class];
+ _tp.current = progress;
+ _tp.total = total;
+ _tp.percent = percent_table[class];
+ }
+
+ /* Don't update the screen too often. So update it once in every 200ms.
+ * However, the _tick_counter increases by 8 every 30ms, so compensate
+ * for that. */
+ if (!_network_dedicated && _tp.timer != 0 && _timer_counter - _tp.timer < (200 * 8 / 30)) return;
+
+ /* Percentage is about the number of completed tasks, so 'current - 1' */
+ _tp.percent = percent_table[class] + (percent_table[class + 1] - percent_table[class]) * (_tp.current == 0 ? 0 : _tp.current - 1) / _tp.total;
+ _tp.timer = _timer_counter;
+
+ if (_network_dedicated) {
+ static uint last_percent = 0;
+
+ /* Never display 0% */
+ if (_tp.percent == 0) return;
+ /* Reset if percent is lower then the last recorded */
+ if (_tp.percent < last_percent) last_percent = 0;
+ /* Display every 5%, but 6% is also very valid.. just not smaller steps then 5% */
+ if (_tp.percent % 5 != 0 && _tp.percent <= last_percent + 5) return;
+ /* Never show steps smaller then 2%, even if it is a mod 5% */
+ if (_tp.percent <= last_percent + 2) return;
+
+ DEBUG(net, 1, "Map generation percentage complete: %d", _tp.percent);
+ last_percent = _tp.percent;
+
+ /* Don't continue as dedicated never has a thread running */
+ return;
+ }
+
+ InvalidateWindow(WC_GENERATE_PROGRESS_WINDOW, 0);
+ MarkWholeScreenDirty();
+ SetGeneratingWorldPaintStatus(true);
+
+ /* We wait here till the paint is done, so we don't read and write
+ * on the same tile at the same moment. Nasty hack, but that happens
+ * if you implement threading afterwards */
+ while (IsGeneratingWorldReadyForPaint()) { CSleep(10); }
+}
+
+/**
+ * Set the total of a stage of the world generation.
+ * @param class the current class we are in.
+ * @param total Set the total expected items for this class.
+ *
+ * Warning: this function isn't clever. Don't go from class 4 to 3. Go upwards, always.
+ * Also, progress works if total is zero, total works if progress is zero.
+ */
+void SetGeneratingWorldProgress(gwp_class class, uint total)
+{
+ if (total == 0) return;
+
+ _SetGeneratingWorldProgress(class, 0, total);
+}
+
+/**
+ * Increases the current stage of the world generation with one.
+ * @param class the current class we are in.
+ *
+ * Warning: this function isn't clever. Don't go from class 4 to 3. Go upwards, always.
+ * Also, progress works if total is zero, total works if progress is zero.
+ */
+void IncreaseGeneratingWorldProgress(gwp_class class)
+{
+ /* In fact the param 'class' isn't needed.. but for some security reasons, we want it around */
+ _SetGeneratingWorldProgress(class, 1, 0);
+}
diff --git a/src/gfx.c b/src/gfx.c
new file mode 100644
index 000000000..1d48fa25d
--- /dev/null
+++ b/src/gfx.c
@@ -0,0 +1,2025 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "functions.h"
+#include "macros.h"
+#include "spritecache.h"
+#include "strings.h"
+#include "string.h"
+#include "gfx.h"
+#include "table/palettes.h"
+#include "table/sprites.h"
+#include "hal.h"
+#include "variables.h"
+#include "table/control_codes.h"
+#include "fontcache.h"
+#include "genworld.h"
+#include "debug.h"
+
+#ifdef _DEBUG
+bool _dbg_screen_rect;
+#endif
+
+Colour _cur_palette[256];
+byte _stringwidth_table[FS_END][224];
+
+static void GfxMainBlitter(const Sprite *sprite, int x, int y, int mode);
+
+FontSize _cur_fontsize;
+static FontSize _last_fontsize;
+static Pixel _cursor_backup[64 * 64];
+static Rect _invalid_rect;
+static const byte *_color_remap_ptr;
+static byte _string_colorremap[3];
+
+#define DIRTY_BYTES_PER_LINE (MAX_SCREEN_WIDTH / 64)
+static byte _dirty_blocks[DIRTY_BYTES_PER_LINE * MAX_SCREEN_HEIGHT / 8];
+
+void memcpy_pitch(void *dst, void *src, int w, int h, int srcpitch, int dstpitch)
+{
+ byte *dstp = (byte*)dst;
+ byte *srcp = (byte*)src;
+
+ assert(h >= 0);
+ for (; h != 0; --h) {
+ memcpy(dstp, srcp, w);
+ dstp += dstpitch;
+ srcp += srcpitch;
+ }
+}
+
+void GfxScroll(int left, int top, int width, int height, int xo, int yo)
+{
+ const Pixel *src;
+ Pixel *dst;
+ int p;
+ int ht;
+
+ if (xo == 0 && yo == 0) return;
+
+ if (_cursor.visible) UndrawMouseCursor();
+ UndrawTextMessage();
+
+ p = _screen.pitch;
+
+ if (yo > 0) {
+ // Calculate pointers
+ dst = _screen.dst_ptr + (top + height - 1) * p + left;
+ src = dst - yo * p;
+
+ // Decrease height and increase top
+ top += yo;
+ height -= yo;
+ assert(height > 0);
+
+ // Adjust left & width
+ if (xo >= 0) {
+ dst += xo;
+ left += xo;
+ width -= xo;
+ } else {
+ src -= xo;
+ width += xo;
+ }
+
+ for (ht = height; ht > 0; --ht) {
+ memcpy(dst, src, width);
+ src -= p;
+ dst -= p;
+ }
+ } else {
+ // Calculate pointers
+ dst = _screen.dst_ptr + top * p + left;
+ src = dst - yo * p;
+
+ // Decrese height. (yo is <=0).
+ height += yo;
+ assert(height > 0);
+
+ // Adjust left & width
+ if (xo >= 0) {
+ dst += xo;
+ left += xo;
+ width -= xo;
+ } else {
+ src -= xo;
+ width += xo;
+ }
+
+ // the y-displacement may be 0 therefore we have to use memmove,
+ // because source and destination may overlap
+ for (ht = height; ht > 0; --ht) {
+ memmove(dst, src, width);
+ src += p;
+ dst += p;
+ }
+ }
+ // This part of the screen is now dirty.
+ _video_driver->make_dirty(left, top, width, height);
+}
+
+
+void GfxFillRect(int left, int top, int right, int bottom, int color)
+{
+ const DrawPixelInfo* dpi = _cur_dpi;
+ Pixel *dst;
+ const int otop = top;
+ const int oleft = left;
+
+ if (dpi->zoom != 0) return;
+ if (left > right || top > bottom) return;
+ if (right < dpi->left || left >= dpi->left + dpi->width) return;
+ if (bottom < dpi->top || top >= dpi->top + dpi->height) return;
+
+ if ( (left -= dpi->left) < 0) left = 0;
+ right = right - dpi->left + 1;
+ if (right > dpi->width) right = dpi->width;
+ right -= left;
+ assert(right > 0);
+
+ if ( (top -= dpi->top) < 0) top = 0;
+ bottom = bottom - dpi->top + 1;
+ if (bottom > dpi->height) bottom = dpi->height;
+ bottom -= top;
+ assert(bottom > 0);
+
+ dst = dpi->dst_ptr + top * dpi->pitch + left;
+
+ if (!(color & PALETTE_MODIFIER_GREYOUT)) {
+ if (!(color & USE_COLORTABLE)) {
+ do {
+ memset(dst, color, right);
+ dst += dpi->pitch;
+ } while (--bottom);
+ } else {
+ /* use colortable mode */
+ const byte* ctab = GetNonSprite(color & COLORTABLE_MASK) + 1;
+
+ do {
+ int i;
+ for (i = 0; i != right; i++) dst[i] = ctab[dst[i]];
+ dst += dpi->pitch;
+ } while (--bottom);
+ }
+ } else {
+ byte bo = (oleft - left + dpi->left + otop - top + dpi->top) & 1;
+ do {
+ int i;
+ for (i = (bo ^= 1); i < right; i += 2) dst[i] = (byte)color;
+ dst += dpi->pitch;
+ } while (--bottom > 0);
+ }
+}
+
+static void GfxSetPixel(int x, int y, int color)
+{
+ const DrawPixelInfo* dpi = _cur_dpi;
+ if ((x-=dpi->left) < 0 || x>=dpi->width || (y-=dpi->top)<0 || y>=dpi->height)
+ return;
+ dpi->dst_ptr[y * dpi->pitch + x] = color;
+}
+
+void GfxDrawLine(int x, int y, int x2, int y2, int color)
+{
+ int dy;
+ int dx;
+ int stepx;
+ int stepy;
+ int frac;
+
+ // Check clipping first
+ {
+ DrawPixelInfo *dpi = _cur_dpi;
+ int t;
+
+ if (x < dpi->left && x2 < dpi->left) return;
+
+ if (y < dpi->top && y2 < dpi->top) return;
+
+ t = dpi->left + dpi->width;
+ if (x > t && x2 > t) return;
+
+ t = dpi->top + dpi->height;
+ if (y > t && y2 > t) return;
+ }
+
+ dy = (y2 - y) * 2;
+ if (dy < 0) {
+ dy = -dy;
+ stepy = -1;
+ } else {
+ stepy = 1;
+ }
+
+ dx = (x2 - x) * 2;
+ if (dx < 0) {
+ dx = -dx;
+ stepx = -1;
+ } else {
+ stepx = 1;
+ }
+
+ GfxSetPixel(x, y, color);
+ if (dx > dy) {
+ frac = dy - (dx >> 1);
+ while (x != x2) {
+ if (frac >= 0) {
+ y += stepy;
+ frac -= dx;
+ }
+ x += stepx;
+ frac += dy;
+ GfxSetPixel(x, y, color);
+ }
+ } else {
+ frac = dx - (dy >> 1);
+ while (y != y2) {
+ if (frac >= 0) {
+ x += stepx;
+ frac -= dy;
+ }
+ y += stepy;
+ frac += dx;
+ GfxSetPixel(x, y, color);
+ }
+ }
+}
+
+
+/** Truncate a given string to a maximum width if neccessary.
+ * If the string is truncated, add three dots ('...') to show this.
+ * @param *dest string that is checked and possibly truncated
+ * @param maxw maximum width in pixels of the string
+ * @return new width of (truncated) string */
+static int TruncateString(char *str, int maxw)
+{
+ int w = 0;
+ FontSize size = _cur_fontsize;
+ int ddd, ddd_w;
+
+ WChar c;
+ char *ddd_pos;
+
+ ddd_w = ddd = GetCharacterWidth(size, '.') * 3;
+
+ for (ddd_pos = str; (c = Utf8Consume((const char **)&str)) != '\0'; ) {
+ if (IsPrintable(c)) {
+ w += GetCharacterWidth(size, c);
+
+ if (w >= maxw) {
+ // string got too big... insert dotdotdot
+ ddd_pos[0] = ddd_pos[1] = ddd_pos[2] = '.';
+ ddd_pos[3] = 0;
+ return ddd_w;
+ }
+ } else {
+ if (c == SCC_SETX) str++;
+ else if (c == SCC_SETXY) str += 2;
+ else if (c == SCC_TINYFONT) {
+ size = FS_SMALL;
+ ddd = GetCharacterWidth(size, '.') * 3;
+ } else if (c == SCC_BIGFONT) {
+ size = FS_LARGE;
+ ddd = GetCharacterWidth(size, '.') * 3;
+ }
+ }
+
+ // Remember the last position where three dots fit.
+ if (w + ddd < maxw) {
+ ddd_w = w + ddd;
+ ddd_pos = str;
+ }
+ }
+
+ return w;
+}
+
+static inline int TruncateStringID(StringID src, char *dest, int maxw, const char* last)
+{
+ GetString(dest, src, last);
+ return TruncateString(dest, maxw);
+}
+
+/* returns right coordinate */
+int DrawString(int x, int y, StringID str, uint16 color)
+{
+ char buffer[512];
+
+ GetString(buffer, str, lastof(buffer));
+ return DoDrawString(buffer, x, y, color);
+}
+
+int DrawStringTruncated(int x, int y, StringID str, uint16 color, uint maxw)
+{
+ char buffer[512];
+ TruncateStringID(str, buffer, maxw, lastof(buffer));
+ return DoDrawString(buffer, x, y, color);
+}
+
+
+int DrawStringRightAligned(int x, int y, StringID str, uint16 color)
+{
+ char buffer[512];
+ int w;
+
+ GetString(buffer, str, lastof(buffer));
+ w = GetStringBoundingBox(buffer).width;
+ DoDrawString(buffer, x - w, y, color);
+
+ return w;
+}
+
+void DrawStringRightAlignedTruncated(int x, int y, StringID str, uint16 color, uint maxw)
+{
+ char buffer[512];
+
+ TruncateStringID(str, buffer, maxw, lastof(buffer));
+ DoDrawString(buffer, x - GetStringBoundingBox(buffer).width, y, color);
+}
+
+void DrawStringRightAlignedUnderline(int x, int y, StringID str, uint16 color)
+{
+ int w = DrawStringRightAligned(x, y, str, color);
+ GfxFillRect(x - w, y + 10, x, y + 10, _string_colorremap[1]);
+}
+
+
+int DrawStringCentered(int x, int y, StringID str, uint16 color)
+{
+ char buffer[512];
+ int w;
+
+ GetString(buffer, str, lastof(buffer));
+
+ w = GetStringBoundingBox(buffer).width;
+ DoDrawString(buffer, x - w / 2, y, color);
+
+ return w;
+}
+
+int DrawStringCenteredTruncated(int xl, int xr, int y, StringID str, uint16 color)
+{
+ char buffer[512];
+ int w = TruncateStringID(str, buffer, xr - xl, lastof(buffer));
+ return DoDrawString(buffer, (xl + xr - w) / 2, y, color);
+}
+
+int DoDrawStringCentered(int x, int y, const char *str, uint16 color)
+{
+ int w = GetStringBoundingBox(str).width;
+ DoDrawString(str, x - w / 2, y, color);
+ return w;
+}
+
+void DrawStringCenterUnderline(int x, int y, StringID str, uint16 color)
+{
+ int w = DrawStringCentered(x, y, str, color);
+ GfxFillRect(x - (w >> 1), y + 10, x - (w >> 1) + w, y + 10, _string_colorremap[1]);
+}
+
+void DrawStringCenterUnderlineTruncated(int xl, int xr, int y, StringID str, uint16 color)
+{
+ int w = DrawStringCenteredTruncated(xl, xr, y, str, color);
+ GfxFillRect((xl + xr - w) / 2, y + 10, (xl + xr + w) / 2, y + 10, _string_colorremap[1]);
+}
+
+/** 'Correct' a string to a maximum length. Longer strings will be cut into
+ * additional lines at whitespace characters if possible. The string parameter
+ * is modified with terminating characters mid-string which are the
+ * placeholders for the newlines.<br/>
+ * The string WILL be truncated if there was no whitespace for the current
+ * line's maximum width.
+ *
+ * @note To know if the the terminating '\0' is the string end or just a
+ * newline, the returned 'num' value should be consulted. The num'th '\0',
+ * starting with index 0 is the real string end.
+ *
+ * @param str string to check and correct for length restrictions
+ * @param maxw the maximum width the string can have on one line
+ * @return return a 32bit wide number consisting of 2 packed values:
+ * 0 - 15 the number of lines ADDED to the string
+ * 16 - 31 the fontsize in which the length calculation was done at */
+uint32 FormatStringLinebreaks(char *str, int maxw)
+{
+ FontSize size = _cur_fontsize;
+ int num = 0;
+
+ assert(maxw > 0);
+
+ for (;;) {
+ char *last_space = NULL;
+ int w = 0;
+
+ for (;;) {
+ WChar c = Utf8Consume((const char **)&str);
+ /* whitespace is where we will insert the line-break */
+ if (c == ' ') last_space = str;
+
+ if (IsPrintable(c)) {
+ w += GetCharacterWidth(size, c);
+ /* string is longer than maximum width so we need to decide what to
+ * do. We can do two things:
+ * 1. If no whitespace was found at all up until now (on this line) then
+ * we will truncate the string and bail out.
+ * 2. In all other cases force a linebreak at the last seen whitespace */
+ if (w > maxw) {
+ if (last_space == NULL) {
+ str[-1] = '\0';
+ return num + (size << 16);
+ }
+ str = last_space;
+ break;
+ }
+ } else {
+ switch (c) {
+ case '\0': return num + (size << 16); break;
+ case SCC_SETX: str++; break;
+ case SCC_SETXY: str +=2; break;
+ case SCC_TINYFONT: size = FS_SMALL; break;
+ case SCC_BIGFONT: size = FS_LARGE; break;
+ case '\n': goto end_of_inner_loop;
+ }
+ }
+ }
+end_of_inner_loop:
+ /* string didn't fit on line, so 'dummy' terminate and increase linecount */
+ num++;
+ str[-1] = '\0';
+ }
+}
+
+/** Draw a given string with the centre around the given x coordinates
+ * @param x Centre the string around this pixel width
+ * @param y Draw the string at this pixel height (first line's bottom)
+ * @param str String to draw
+ * @param max Maximum width the string can have before it is wrapped */
+void DrawStringMultiCenter(int x, int y, StringID str, int maxw)
+{
+ char buffer[512];
+ uint32 tmp;
+ int num, w, mt;
+ const char *src;
+ WChar c;
+
+ GetString(buffer, str, lastof(buffer));
+
+ tmp = FormatStringLinebreaks(buffer, maxw);
+ num = GB(tmp, 0, 16);
+
+ mt = GetCharacterHeight(GB(tmp, 16, 16));
+
+ y -= (mt >> 1) * num;
+
+ src = buffer;
+
+ for (;;) {
+ w = GetStringBoundingBox(src).width;
+ DoDrawString(src, x - (w>>1), y, 0xFE);
+ _cur_fontsize = _last_fontsize;
+
+ for (;;) {
+ c = Utf8Consume(&src);
+ if (c == 0) {
+ y += mt;
+ if (--num < 0) {
+ _cur_fontsize = FS_NORMAL;
+ return;
+ }
+ break;
+ } else if (c == SCC_SETX) {
+ src++;
+ } else if (c == SCC_SETXY) {
+ src+=2;
+ }
+ }
+ }
+}
+
+
+uint DrawStringMultiLine(int x, int y, StringID str, int maxw)
+{
+ char buffer[512];
+ uint32 tmp;
+ int num, mt;
+ uint total_height;
+ const char *src;
+ WChar c;
+
+ GetString(buffer, str, lastof(buffer));
+
+ tmp = FormatStringLinebreaks(buffer, maxw);
+ num = GB(tmp, 0, 16);
+
+ mt = GetCharacterHeight(GB(tmp, 16, 16));
+ total_height = (num + 1) * mt;
+
+ src = buffer;
+
+ for (;;) {
+ DoDrawString(src, x, y, 0xFE);
+ _cur_fontsize = _last_fontsize;
+
+ for (;;) {
+ c = Utf8Consume(&src);
+ if (c == 0) {
+ y += mt;
+ if (--num < 0) {
+ _cur_fontsize = FS_NORMAL;
+ return total_height;
+ }
+ break;
+ } else if (c == SCC_SETX) {
+ src++;
+ } else if (c == SCC_SETXY) {
+ src+=2;
+ }
+ }
+ }
+}
+
+/** Return the string dimension in pixels. The height and width are returned
+ * in a single BoundingRect value. TINYFONT, BIGFONT modifiers are only
+ * supported as the first character of the string. The returned dimensions
+ * are therefore a rough estimation correct for all the current strings
+ * but not every possible combination
+ * @param str string to calculate pixel-width
+ * @return string width and height in pixels */
+BoundingRect GetStringBoundingBox(const char *str)
+{
+ FontSize size = _cur_fontsize;
+ BoundingRect br;
+ int max_width;
+ WChar c;
+
+ br.width = br.height = max_width = 0;
+ for (;;) {
+ c = Utf8Consume(&str);
+ if (c == 0) break;
+ if (IsPrintable(c)) {
+ br.width += GetCharacterWidth(size, c);
+ } else {
+ switch (c) {
+ case SCC_SETX: br.width += (byte)*str++; break;
+ case SCC_SETXY:
+ br.width += (byte)*str++;
+ br.height += (byte)*str++;
+ break;
+ case SCC_TINYFONT: size = FS_SMALL; break;
+ case SCC_BIGFONT: size = FS_LARGE; break;
+ case '\n':
+ br.height += GetCharacterHeight(size);
+ if (br.width > max_width) max_width = br.width;
+ br.width = 0;
+ break;
+ }
+ }
+ }
+ br.height += GetCharacterHeight(size);
+
+ br.width = max(br.width, max_width);
+ return br;
+}
+
+/** Draw a string at the given coordinates with the given colour
+ * @param string the string to draw
+ * @param x offset from left side of the screen, if negative offset from the right side
+ * @param x offset from top side of the screen, if negative offset from the bottom
+ * @param real_color colour of the string, see _string_colormap in
+ * table/palettes.h or docs/ottd-colourtext-palette.png
+ * @return the x-coordinates where the drawing has finished. If nothing is drawn
+ * the originally passed x-coordinate is returned */
+int DoDrawString(const char *string, int x, int y, uint16 real_color)
+{
+ DrawPixelInfo *dpi = _cur_dpi;
+ FontSize size = _cur_fontsize;
+ WChar c;
+ byte color;
+ int xo = x, yo = y;
+
+ color = real_color & 0xFF;
+
+ if (color != 0xFE) {
+ if (x >= dpi->left + dpi->width ||
+ x + _screen.width*2 <= dpi->left ||
+ y >= dpi->top + dpi->height ||
+ y + _screen.height <= dpi->top)
+ return x;
+
+ if (color != 0xFF) {
+switch_color:;
+ if (real_color & IS_PALETTE_COLOR) {
+ _string_colorremap[1] = color;
+ _string_colorremap[2] = 215;
+ } else {
+ _string_colorremap[1] = _string_colormap[color].text;
+ _string_colorremap[2] = _string_colormap[color].shadow;
+ }
+ _color_remap_ptr = _string_colorremap;
+ }
+ }
+
+check_bounds:
+ if (y + 19 <= dpi->top || dpi->top + dpi->height <= y) {
+skip_char:;
+ for (;;) {
+ c = Utf8Consume(&string);
+ if (!IsPrintable(c)) goto skip_cont;
+ }
+ }
+
+ for (;;) {
+ c = Utf8Consume(&string);
+skip_cont:;
+ if (c == 0) {
+ _last_fontsize = size;
+ return x;
+ }
+ if (IsPrintable(c)) {
+ if (x >= dpi->left + dpi->width) goto skip_char;
+ if (x + 26 >= dpi->left) {
+ GfxMainBlitter(GetGlyph(size, c), x, y, 1);
+ }
+ x += GetCharacterWidth(size, c);
+ } else if (c == '\n') { // newline = {}
+ x = xo;
+ y += GetCharacterHeight(size);
+ goto check_bounds;
+ } else if (c >= SCC_BLUE && c <= SCC_BLACK) { // change color?
+ color = (byte)(c - SCC_BLUE);
+ goto switch_color;
+ } else if (c == SCC_SETX) { // {SETX}
+ x = xo + (byte)*string++;
+ } else if (c == SCC_SETXY) {// {SETXY}
+ x = xo + (byte)*string++;
+ y = yo + (byte)*string++;
+ } else if (c == SCC_TINYFONT) { // {TINYFONT}
+ size = FS_SMALL;
+ } else if (c == SCC_BIGFONT) { // {BIGFONT}
+ size = FS_LARGE;
+ } else {
+ DEBUG(misc, 0, "[utf8] unknown string command character %d", c);
+ }
+ }
+}
+
+int DoDrawStringTruncated(const char *str, int x, int y, uint16 color, uint maxw)
+{
+ char buffer[512];
+ ttd_strlcpy(buffer, str, sizeof(buffer));
+ TruncateString(buffer, maxw);
+ return DoDrawString(buffer, x, y, color);
+}
+
+void DrawSprite(uint32 img, int x, int y)
+{
+ if (img & PALETTE_MODIFIER_COLOR) {
+ _color_remap_ptr = GetNonSprite(GB(img, PALETTE_SPRITE_START, PALETTE_SPRITE_WIDTH)) + 1;
+ GfxMainBlitter(GetSprite(img & SPRITE_MASK), x, y, 1);
+ } else if (img & PALETTE_MODIFIER_TRANSPARENT) {
+ _color_remap_ptr = GetNonSprite(GB(img, PALETTE_SPRITE_START, PALETTE_SPRITE_WIDTH)) + 1;
+ GfxMainBlitter(GetSprite(img & SPRITE_MASK), x, y, 2);
+ } else {
+ GfxMainBlitter(GetSprite(img & SPRITE_MASK), x, y, 0);
+ }
+}
+
+typedef struct BlitterParams {
+ int start_x, start_y;
+ const byte *sprite;
+ Pixel *dst;
+ int mode;
+ int width, height;
+ int width_org;
+ int pitch;
+} BlitterParams;
+
+static void GfxBlitTileZoomIn(BlitterParams *bp)
+{
+ const byte *src_o = bp->sprite;
+ const byte *src;
+ int num, skip;
+ byte done;
+ Pixel *dst;
+ const byte *ctab;
+
+ src_o += ReadLE16Aligned(src_o + bp->start_y * 2);
+ switch (bp->mode) {
+ case 1:
+ do {
+ do {
+ done = src_o[0];
+ num = done & 0x7F;
+ skip = src_o[1];
+ src = src_o + 2;
+ src_o += num + 2;
+
+ dst = bp->dst;
+
+ if ( (skip -= bp->start_x) > 0) {
+ dst += skip;
+ } else {
+ src -= skip;
+ num += skip;
+ if (num <= 0) continue;
+ skip = 0;
+ }
+
+ skip = skip + num - bp->width;
+ if (skip > 0) {
+ num -= skip;
+ if (num <= 0) continue;
+ }
+
+ ctab = _color_remap_ptr;
+
+ for (; num >= 4; num -=4) {
+ dst[3] = ctab[src[3]];
+ dst[2] = ctab[src[2]];
+ dst[1] = ctab[src[1]];
+ dst[0] = ctab[src[0]];
+ dst += 4;
+ src += 4;
+ }
+ for (; num != 0; num--) *dst++ = ctab[*src++];
+ } while (!(done & 0x80));
+
+ bp->dst += bp->pitch;
+ } while (--bp->height != 0);
+ break;
+
+ case 2:
+ do {
+ do {
+ done = src_o[0];
+ num = done & 0x7F;
+ skip = src_o[1];
+ src_o += num + 2;
+
+ dst = bp->dst;
+
+ if ( (skip -= bp->start_x) > 0) {
+ dst += skip;
+ } else {
+ num += skip;
+ if (num <= 0) continue;
+ skip = 0;
+ }
+
+ skip = skip + num - bp->width;
+ if (skip > 0) {
+ num -= skip;
+ if (num <= 0) continue;
+ }
+
+ ctab = _color_remap_ptr;
+ for (; num != 0; num--) {
+ *dst = ctab[*dst];
+ dst++;
+ }
+ } while (!(done & 0x80));
+
+ bp->dst += bp->pitch;
+ } while (--bp->height != 0);
+ break;
+
+ default:
+ do {
+ do {
+ done = src_o[0];
+ num = done & 0x7F;
+ skip = src_o[1];
+ src = src_o + 2;
+ src_o += num + 2;
+
+ dst = bp->dst;
+
+ if ( (skip -= bp->start_x) > 0) {
+ dst += skip;
+ } else {
+ src -= skip;
+ num += skip;
+ if (num <= 0) continue;
+ skip = 0;
+ }
+
+ skip = skip + num - bp->width;
+ if (skip > 0) {
+ num -= skip;
+ if (num <= 0) continue;
+ }
+#if defined(_WIN32)
+ if (num & 1) *dst++ = *src++;
+ if (num & 2) { *(uint16*)dst = *(uint16*)src; dst += 2; src += 2; }
+ if (num >>= 2) {
+ do {
+ *(uint32*)dst = *(uint32*)src;
+ dst += 4;
+ src += 4;
+ } while (--num != 0);
+ }
+#else
+ memcpy(dst, src, num);
+#endif
+ } while (!(done & 0x80));
+
+ bp->dst += bp->pitch;
+ } while (--bp->height != 0);
+ break;
+ }
+}
+
+static void GfxBlitZoomInUncomp(BlitterParams *bp)
+{
+ const byte *src = bp->sprite;
+ Pixel *dst = bp->dst;
+ int height = bp->height;
+ int width = bp->width;
+ int i;
+
+ assert(height > 0);
+ assert(width > 0);
+
+ switch (bp->mode) {
+ case 1: {
+ const byte *ctab = _color_remap_ptr;
+
+ do {
+ for (i = 0; i != width; i++) {
+ byte b = ctab[src[i]];
+
+ if (b != 0) dst[i] = b;
+ }
+ src += bp->width_org;
+ dst += bp->pitch;
+ } while (--height != 0);
+ break;
+ }
+
+ case 2: {
+ const byte *ctab = _color_remap_ptr;
+
+ do {
+ for (i = 0; i != width; i++)
+ if (src[i] != 0) dst[i] = ctab[dst[i]];
+ src += bp->width_org;
+ dst += bp->pitch;
+ } while (--height != 0);
+ break;
+ }
+
+ default:
+ do {
+ int n = width;
+
+ for (; n >= 4; n -= 4) {
+ if (src[0] != 0) dst[0] = src[0];
+ if (src[1] != 0) dst[1] = src[1];
+ if (src[2] != 0) dst[2] = src[2];
+ if (src[3] != 0) dst[3] = src[3];
+
+ dst += 4;
+ src += 4;
+ }
+
+ for (; n != 0; n--) {
+ if (src[0] != 0) dst[0] = src[0];
+ src++;
+ dst++;
+ }
+
+ src += bp->width_org - width;
+ dst += bp->pitch - width;
+ } while (--height != 0);
+ break;
+ }
+}
+
+static void GfxBlitTileZoomMedium(BlitterParams *bp)
+{
+ const byte *src_o = bp->sprite;
+ const byte *src;
+ int num, skip;
+ byte done;
+ Pixel *dst;
+ const byte *ctab;
+
+ src_o += ReadLE16Aligned(src_o + bp->start_y * 2);
+ switch (bp->mode) {
+ case 1:
+ do {
+ do {
+ done = src_o[0];
+ num = done & 0x7F;
+ skip = src_o[1];
+ src = src_o + 2;
+ src_o += num + 2;
+
+ dst = bp->dst;
+
+ if (skip & 1) {
+ skip++;
+ src++;
+ if (--num == 0) continue;
+ }
+
+ if ( (skip -= bp->start_x) > 0) {
+ dst += skip >> 1;
+ } else {
+ src -= skip;
+ num += skip;
+ if (num <= 0) continue;
+ skip = 0;
+ }
+
+ skip = skip + num - bp->width;
+ if (skip > 0) {
+ num -= skip;
+ if (num <= 0) continue;
+ }
+
+ ctab = _color_remap_ptr;
+ num = (num + 1) >> 1;
+ for (; num != 0; num--) {
+ *dst = ctab[*src];
+ dst++;
+ src += 2;
+ }
+ } while (!(done & 0x80));
+ bp->dst += bp->pitch;
+ if (--bp->height == 0) return;
+
+ do {
+ done = src_o[0];
+ src_o += (done & 0x7F) + 2;
+ } while (!(done & 0x80));
+ } while (--bp->height != 0);
+ break;
+
+ case 2:
+ do {
+ do {
+ done = src_o[0];
+ num = done & 0x7F;
+ skip = src_o[1];
+ src_o += num + 2;
+
+ dst = bp->dst;
+
+ if (skip & 1) {
+ skip++;
+ if (--num == 0) continue;
+ }
+
+ if ( (skip -= bp->start_x) > 0) {
+ dst += skip >> 1;
+ } else {
+ num += skip;
+ if (num <= 0) continue;
+ skip = 0;
+ }
+
+ skip = skip + num - bp->width;
+ if (skip > 0) {
+ num -= skip;
+ if (num <= 0) continue;
+ }
+
+ ctab = _color_remap_ptr;
+ num = (num + 1) >> 1;
+ for (; num != 0; num--) {
+ *dst = ctab[*dst];
+ dst++;
+ }
+ } while (!(done & 0x80));
+ bp->dst += bp->pitch;
+ if (--bp->height == 0) return;
+
+ do {
+ done = src_o[0];
+ src_o += (done & 0x7F) + 2;
+ } while (!(done & 0x80));
+ } while (--bp->height != 0);
+ break;
+
+ default:
+ do {
+ do {
+ done = src_o[0];
+ num = done & 0x7F;
+ skip = src_o[1];
+ src = src_o + 2;
+ src_o += num + 2;
+
+ dst = bp->dst;
+
+ if (skip & 1) {
+ skip++;
+ src++;
+ if (--num == 0) continue;
+ }
+
+ if ( (skip -= bp->start_x) > 0) {
+ dst += skip >> 1;
+ } else {
+ src -= skip;
+ num += skip;
+ if (num <= 0) continue;
+ skip = 0;
+ }
+
+ skip = skip + num - bp->width;
+ if (skip > 0) {
+ num -= skip;
+ if (num <= 0) continue;
+ }
+
+ num = (num + 1) >> 1;
+
+ for (; num != 0; num--) {
+ *dst = *src;
+ dst++;
+ src += 2;
+ }
+
+ } while (!(done & 0x80));
+
+ bp->dst += bp->pitch;
+ if (--bp->height == 0) return;
+
+ do {
+ done = src_o[0];
+ src_o += (done & 0x7F) + 2;
+ } while (!(done & 0x80));
+ } while (--bp->height != 0);
+ break;
+ }
+}
+
+static void GfxBlitZoomMediumUncomp(BlitterParams *bp)
+{
+ const byte *src = bp->sprite;
+ Pixel *dst = bp->dst;
+ int height = bp->height;
+ int width = bp->width;
+ int i;
+
+ assert(height > 0);
+ assert(width > 0);
+
+ switch (bp->mode) {
+ case 1: {
+ const byte *ctab = _color_remap_ptr;
+
+ for (height >>= 1; height != 0; height--) {
+ for (i = 0; i != width >> 1; i++) {
+ byte b = ctab[src[i * 2]];
+
+ if (b != 0) dst[i] = b;
+ }
+ src += bp->width_org * 2;
+ dst += bp->pitch;
+ }
+ break;
+ }
+
+ case 2: {
+ const byte *ctab = _color_remap_ptr;
+
+ for (height >>= 1; height != 0; height--) {
+ for (i = 0; i != width >> 1; i++)
+ if (src[i * 2] != 0) dst[i] = ctab[dst[i]];
+ src += bp->width_org * 2;
+ dst += bp->pitch;
+ }
+ break;
+ }
+
+ default:
+ for (height >>= 1; height != 0; height--) {
+ for (i = 0; i != width >> 1; i++)
+ if (src[i * 2] != 0) dst[i] = src[i * 2];
+ src += bp->width_org * 2;
+ dst += bp->pitch;
+ }
+ break;
+ }
+}
+
+static void GfxBlitTileZoomOut(BlitterParams *bp)
+{
+ const byte *src_o = bp->sprite;
+ const byte *src;
+ int num, skip;
+ byte done;
+ Pixel *dst;
+ const byte *ctab;
+
+ src_o += ReadLE16Aligned(src_o + bp->start_y * 2);
+ switch (bp->mode) {
+ case 1:
+ for (;;) {
+ do {
+ done = src_o[0];
+ num = done & 0x7F;
+ skip = src_o[1];
+ src = src_o + 2;
+ src_o += num + 2;
+
+ dst = bp->dst;
+
+ if (skip & 1) {
+ skip++;
+ src++;
+ if (--num == 0) continue;
+ }
+
+ if (skip & 2) {
+ skip += 2;
+ src += 2;
+ num -= 2;
+ if (num <= 0) continue;
+ }
+
+ if ( (skip -= bp->start_x) > 0) {
+ dst += skip >> 2;
+ } else {
+ src -= skip;
+ num += skip;
+ if (num <= 0) continue;
+ skip = 0;
+ }
+
+ skip = skip + num - bp->width;
+ if (skip > 0) {
+ num -= skip;
+ if (num <= 0) continue;
+ }
+
+ ctab = _color_remap_ptr;
+ num = (num + 3) >> 2;
+ for (; num != 0; num--) {
+ *dst = ctab[*src];
+ dst++;
+ src += 4;
+ }
+ } while (!(done & 0x80));
+ bp->dst += bp->pitch;
+ if (--bp->height == 0) return;
+
+ do {
+ done = src_o[0];
+ src_o += (done & 0x7F) + 2;
+ } while (!(done & 0x80));
+ if (--bp->height == 0) return;
+
+ do {
+ done = src_o[0];
+ src_o += (done & 0x7F) + 2;
+ } while (!(done & 0x80));
+ if (--bp->height == 0) return;
+
+ do {
+ done = src_o[0];
+ src_o += (done & 0x7F) + 2;
+ } while (!(done & 0x80));
+ if (--bp->height == 0) return;
+ }
+ break;
+
+ case 2:
+ for (;;) {
+ do {
+ done = src_o[0];
+ num = done & 0x7F;
+ skip = src_o[1];
+ src_o += num + 2;
+
+ dst = bp->dst;
+
+ if (skip & 1) {
+ skip++;
+ if (--num == 0) continue;
+ }
+
+ if (skip & 2) {
+ skip += 2;
+ num -= 2;
+ if (num <= 0) continue;
+ }
+
+ if ( (skip -= bp->start_x) > 0) {
+ dst += skip >> 2;
+ } else {
+ num += skip;
+ if (num <= 0) continue;
+ skip = 0;
+ }
+
+ skip = skip + num - bp->width;
+ if (skip > 0) {
+ num -= skip;
+ if (num <= 0) continue;
+ }
+
+ ctab = _color_remap_ptr;
+ num = (num + 3) >> 2;
+ for (; num != 0; num--) {
+ *dst = ctab[*dst];
+ dst++;
+ }
+
+ } while (!(done & 0x80));
+ bp->dst += bp->pitch;
+ if (--bp->height == 0) return;
+
+ do {
+ done = src_o[0];
+ src_o += (done & 0x7F) + 2;
+ } while (!(done & 0x80));
+ if (--bp->height == 0) return;
+
+ do {
+ done = src_o[0];
+ src_o += (done & 0x7F) + 2;
+ } while (!(done & 0x80));
+ if (--bp->height == 0) return;
+
+ do {
+ done = src_o[0];
+ src_o += (done & 0x7F) + 2;
+ } while (!(done & 0x80));
+ if (--bp->height == 0) return;
+ }
+ break;
+
+ default:
+ for (;;) {
+ do {
+ done = src_o[0];
+ num = done & 0x7F;
+ skip = src_o[1];
+ src = src_o + 2;
+ src_o += num + 2;
+
+ dst = bp->dst;
+
+ if (skip & 1) {
+ skip++;
+ src++;
+ if (--num == 0) continue;
+ }
+
+ if (skip & 2) {
+ skip += 2;
+ src += 2;
+ num -= 2;
+ if (num <= 0) continue;
+ }
+
+ if ( (skip -= bp->start_x) > 0) {
+ dst += skip >> 2;
+ } else {
+ src -= skip;
+ num += skip;
+ if (num <= 0) continue;
+ skip = 0;
+ }
+
+ skip = skip + num - bp->width;
+ if (skip > 0) {
+ num -= skip;
+ if (num <= 0) continue;
+ }
+
+ num = (num + 3) >> 2;
+
+ for (; num != 0; num--) {
+ *dst = *src;
+ dst++;
+ src += 4;
+ }
+ } while (!(done & 0x80));
+
+ bp->dst += bp->pitch;
+ if (--bp->height == 0) return;
+
+ do {
+ done = src_o[0];
+ src_o += (done & 0x7F) + 2;
+ } while (!(done & 0x80));
+ if (--bp->height == 0) return;
+
+ do {
+ done = src_o[0];
+ src_o += (done & 0x7F) + 2;
+ } while (!(done & 0x80));
+ if (--bp->height == 0) return;
+
+ do {
+ done = src_o[0];
+ src_o += (done & 0x7F) + 2;
+ } while (!(done & 0x80));
+ if (--bp->height == 0) return;
+ }
+ break;
+ }
+}
+
+static void GfxBlitZoomOutUncomp(BlitterParams *bp)
+{
+ const byte *src = bp->sprite;
+ Pixel *dst = bp->dst;
+ int height = bp->height;
+ int width = bp->width;
+ int i;
+
+ assert(height > 0);
+ assert(width > 0);
+
+ switch (bp->mode) {
+ case 1: {
+ const byte *ctab = _color_remap_ptr;
+
+ for (height >>= 2; height != 0; height--) {
+ for (i = 0; i != width >> 2; i++) {
+ byte b = ctab[src[i * 4]];
+
+ if (b != 0) dst[i] = b;
+ }
+ src += bp->width_org * 4;
+ dst += bp->pitch;
+ }
+ break;
+ }
+
+ case 2: {
+ const byte *ctab = _color_remap_ptr;
+
+ for (height >>= 2; height != 0; height--) {
+ for (i = 0; i != width >> 2; i++)
+ if (src[i * 4] != 0) dst[i] = ctab[dst[i]];
+ src += bp->width_org * 4;
+ dst += bp->pitch;
+ }
+ break;
+ }
+
+ default:
+ for (height >>= 2; height != 0; height--) {
+ for (i = 0; i != width >> 2; i++)
+ if (src[i * 4] != 0) dst[i] = src[i * 4];
+ src += bp->width_org * 4;
+ dst += bp->pitch;
+ }
+ break;
+ }
+}
+
+
+static void GfxMainBlitter(const Sprite *sprite, int x, int y, int mode)
+{
+ const DrawPixelInfo *dpi = _cur_dpi;
+ int start_x, start_y;
+ BlitterParams bp;
+ int zoom_mask = ~((1 << dpi->zoom) - 1);
+
+ /* decode sprite header */
+ x += sprite->x_offs;
+ y += sprite->y_offs;
+ bp.width_org = bp.width = sprite->width;
+ bp.height = sprite->height;
+ bp.sprite = sprite->data;
+ bp.dst = dpi->dst_ptr;
+ bp.mode = mode;
+ bp.pitch = dpi->pitch;
+
+ assert(bp.height > 0);
+ assert(bp.width > 0);
+
+ if (sprite->info & 8) {
+ /* tile blit */
+ start_y = 0;
+
+ if (dpi->zoom > 0) {
+ start_y += bp.height & ~zoom_mask;
+ bp.height &= zoom_mask;
+ if (bp.height == 0) return;
+ y &= zoom_mask;
+ }
+
+ if ( (y -= dpi->top) < 0) {
+ bp.height += y;
+ if (bp.height <= 0) return;
+ start_y -= y;
+ y = 0;
+ } else {
+ bp.dst += bp.pitch * (y >> dpi->zoom);
+ }
+ bp.start_y = start_y;
+
+ if ( (y = y + bp.height - dpi->height) > 0) {
+ bp.height -= y;
+ if (bp.height <= 0) return;
+ }
+
+ start_x = 0;
+ x &= zoom_mask;
+ if ( (x -= dpi->left) < 0) {
+ bp.width += x;
+ if (bp.width <= 0) return;
+ start_x -= x;
+ x = 0;
+ }
+ bp.start_x = start_x;
+ bp.dst += x >> dpi->zoom;
+
+ if ( (x = x + bp.width - dpi->width) > 0) {
+ bp.width -= x;
+ if (bp.width <= 0) return;
+ }
+
+ switch (dpi->zoom) {
+ default: NOT_REACHED();
+ case 0: GfxBlitTileZoomIn(&bp); break;
+ case 1: GfxBlitTileZoomMedium(&bp); break;
+ case 2: GfxBlitTileZoomOut(&bp); break;
+ }
+ } else {
+ bp.sprite += bp.width * (bp.height & ~zoom_mask);
+ bp.height &= zoom_mask;
+ if (bp.height == 0) return;
+
+ y &= zoom_mask;
+
+ if ( (y -= dpi->top) < 0) {
+ bp.height += y;
+ if (bp.height <= 0) return;
+ bp.sprite -= bp.width * y;
+ y = 0;
+ } else {
+ bp.dst += bp.pitch * (y >> dpi->zoom);
+ }
+
+ if (bp.height > dpi->height - y) {
+ bp.height = dpi->height - y;
+ if (bp.height <= 0) return;
+ }
+
+ x &= zoom_mask;
+
+ if ( (x -= dpi->left) < 0) {
+ bp.width += x;
+ if (bp.width <= 0) return;
+ bp.sprite -= x;
+ x = 0;
+ }
+ bp.dst += x >> dpi->zoom;
+
+ if (bp.width > dpi->width - x) {
+ bp.width = dpi->width - x;
+ if (bp.width <= 0) return;
+ }
+
+ switch (dpi->zoom) {
+ default: NOT_REACHED();
+ case 0: GfxBlitZoomInUncomp(&bp); break;
+ case 1: GfxBlitZoomMediumUncomp(&bp); break;
+ case 2: GfxBlitZoomOutUncomp(&bp); break;
+ }
+ }
+}
+
+void DoPaletteAnimations(void);
+
+void GfxInitPalettes(void)
+{
+ memcpy(_cur_palette, _palettes[_use_dos_palette ? 1 : 0], sizeof(_cur_palette));
+
+ _pal_first_dirty = 0;
+ _pal_last_dirty = 255;
+ DoPaletteAnimations();
+}
+
+#define EXTR(p, q) (((uint16)(_timer_counter * (p)) * (q)) >> 16)
+#define EXTR2(p, q) (((uint16)(~_timer_counter * (p)) * (q)) >> 16)
+
+void DoPaletteAnimations(void)
+{
+ const Colour *s;
+ Colour *d;
+ /* Amount of colors to be rotated.
+ * A few more for the DOS palette, because the water colors are
+ * 245-254 for DOS and 217-226 for Windows. */
+ const ExtraPaletteValues *ev = &_extra_palette_values;
+ int c = _use_dos_palette ? 38 : 28;
+ Colour old_val[38]; // max(38, 28)
+ uint i;
+ uint j;
+
+ d = &_cur_palette[217];
+ memcpy(old_val, d, c * sizeof(*old_val));
+
+ // Dark blue water
+ s = (_opt.landscape == LT_CANDY) ? ev->ac : ev->a;
+ j = EXTR(320, 5);
+ for (i = 0; i != 5; i++) {
+ *d++ = s[j];
+ j++;
+ if (j == 5) j = 0;
+ }
+
+ // Glittery water
+ s = (_opt.landscape == LT_CANDY) ? ev->bc : ev->b;
+ j = EXTR(128, 15);
+ for (i = 0; i != 5; i++) {
+ *d++ = s[j];
+ j += 3;
+ if (j >= 15) j -= 15;
+ }
+
+ s = ev->e;
+ j = EXTR2(512, 5);
+ for (i = 0; i != 5; i++) {
+ *d++ = s[j];
+ j++;
+ if (j == 5) j = 0;
+ }
+
+ // Oil refinery fire animation
+ s = ev->oil_ref;
+ j = EXTR2(512, 7);
+ for (i = 0; i != 7; i++) {
+ *d++ = s[j];
+ j++;
+ if (j == 7) j = 0;
+ }
+
+ // Radio tower blinking
+ {
+ byte i = (_timer_counter >> 1) & 0x7F;
+ byte v;
+
+ (v = 255, i < 0x3f) ||
+ (v = 128, i < 0x4A || i >= 0x75) ||
+ (v = 20);
+ d->r = v;
+ d->g = 0;
+ d->b = 0;
+ d++;
+
+ i ^= 0x40;
+ (v = 255, i < 0x3f) ||
+ (v = 128, i < 0x4A || i >= 0x75) ||
+ (v = 20);
+ d->r = v;
+ d->g = 0;
+ d->b = 0;
+ d++;
+ }
+
+ // Handle lighthouse and stadium animation
+ s = ev->lighthouse;
+ j = EXTR(256, 4);
+ for (i = 0; i != 4; i++) {
+ *d++ = s[j];
+ j++;
+ if (j == 4) j = 0;
+ }
+
+ // Animate water for old DOS graphics
+ if (_use_dos_palette) {
+ // Dark blue water DOS
+ s = (_opt.landscape == LT_CANDY) ? ev->ac : ev->a;
+ j = EXTR(320, 5);
+ for (i = 0; i != 5; i++) {
+ *d++ = s[j];
+ j++;
+ if (j == 5) j = 0;
+ }
+
+ // Glittery water DOS
+ s = (_opt.landscape == LT_CANDY) ? ev->bc : ev->b;
+ j = EXTR(128, 15);
+ for (i = 0; i != 5; i++) {
+ *d++ = s[j];
+ j += 3;
+ if (j >= 15) j -= 15;
+ }
+ }
+
+ if (memcmp(old_val, &_cur_palette[217], c * sizeof(*old_val)) != 0) {
+ if (_pal_first_dirty > 217) _pal_first_dirty = 217;
+ if (_pal_last_dirty < 217 + c) _pal_last_dirty = 217 + c;
+ }
+}
+
+
+void LoadStringWidthTable(void)
+{
+ uint i;
+
+ /* Normal font */
+ for (i = 0; i != 224; i++) {
+ _stringwidth_table[FS_NORMAL][i] = GetGlyphWidth(FS_NORMAL, i + 32);
+ }
+
+ /* Small font */
+ for (i = 0; i != 224; i++) {
+ _stringwidth_table[FS_SMALL][i] = GetGlyphWidth(FS_SMALL, i + 32);
+ }
+
+ /* Large font */
+ for (i = 0; i != 224; i++) {
+ _stringwidth_table[FS_LARGE][i] = GetGlyphWidth(FS_LARGE, i + 32);
+ }
+}
+
+
+byte GetCharacterWidth(FontSize size, WChar key)
+{
+ if (key >= 32 && key < 256) return _stringwidth_table[size][key - 32];
+
+ return GetGlyphWidth(size, key);
+}
+
+
+void ScreenSizeChanged(void)
+{
+ // check the dirty rect
+ if (_invalid_rect.right >= _screen.width) _invalid_rect.right = _screen.width;
+ if (_invalid_rect.bottom >= _screen.height) _invalid_rect.bottom = _screen.height;
+
+ // screen size changed and the old bitmap is invalid now, so we don't want to undraw it
+ _cursor.visible = false;
+}
+
+void UndrawMouseCursor(void)
+{
+ if (_cursor.visible) {
+ _cursor.visible = false;
+ memcpy_pitch(
+ _screen.dst_ptr + _cursor.draw_pos.x + _cursor.draw_pos.y * _screen.pitch,
+ _cursor_backup,
+ _cursor.draw_size.x, _cursor.draw_size.y, _cursor.draw_size.x, _screen.pitch);
+
+ _video_driver->make_dirty(_cursor.draw_pos.x, _cursor.draw_pos.y, _cursor.draw_size.x, _cursor.draw_size.y);
+ }
+}
+
+void DrawMouseCursor(void)
+{
+ int x;
+ int y;
+ int w;
+ int h;
+
+ /* Redraw mouse cursor but only when it's inside the window */
+ if (!_cursor.in_window) return;
+
+ // Don't draw the mouse cursor if it's already drawn
+ if (_cursor.visible) {
+ if (!_cursor.dirty) return;
+ UndrawMouseCursor();
+ }
+
+ w = _cursor.size.x;
+ x = _cursor.pos.x + _cursor.offs.x;
+ if (x < 0) {
+ w += x;
+ x = 0;
+ }
+ if (w > _screen.width - x) w = _screen.width - x;
+ if (w <= 0) return;
+ _cursor.draw_pos.x = x;
+ _cursor.draw_size.x = w;
+
+ h = _cursor.size.y;
+ y = _cursor.pos.y + _cursor.offs.y;
+ if (y < 0) {
+ h += y;
+ y = 0;
+ }
+ if (h > _screen.height - y) h = _screen.height - y;
+ if (h <= 0) return;
+ _cursor.draw_pos.y = y;
+ _cursor.draw_size.y = h;
+
+ assert(w * h < (int)sizeof(_cursor_backup));
+
+ // Make backup of stuff below cursor
+ memcpy_pitch(
+ _cursor_backup,
+ _screen.dst_ptr + _cursor.draw_pos.x + _cursor.draw_pos.y * _screen.pitch,
+ _cursor.draw_size.x, _cursor.draw_size.y, _screen.pitch, _cursor.draw_size.x);
+
+ // Draw cursor on screen
+ _cur_dpi = &_screen;
+ DrawSprite(_cursor.sprite, _cursor.pos.x, _cursor.pos.y);
+
+ _video_driver->make_dirty(_cursor.draw_pos.x, _cursor.draw_pos.y, _cursor.draw_size.x, _cursor.draw_size.y);
+
+ _cursor.visible = true;
+ _cursor.dirty = false;
+}
+
+#if defined(_DEBUG)
+static void DbgScreenRect(int left, int top, int right, int bottom)
+{
+ DrawPixelInfo dp;
+ DrawPixelInfo *old;
+
+ old = _cur_dpi;
+ _cur_dpi = &dp;
+ dp = _screen;
+ GfxFillRect(left, top, right - 1, bottom - 1, rand() & 255);
+ _cur_dpi = old;
+}
+#endif
+
+void RedrawScreenRect(int left, int top, int right, int bottom)
+{
+ assert(right <= _screen.width && bottom <= _screen.height);
+ if (_cursor.visible) {
+ if (right > _cursor.draw_pos.x &&
+ left < _cursor.draw_pos.x + _cursor.draw_size.x &&
+ bottom > _cursor.draw_pos.y &&
+ top < _cursor.draw_pos.y + _cursor.draw_size.y) {
+ UndrawMouseCursor();
+ }
+ }
+ UndrawTextMessage();
+
+#if defined(_DEBUG)
+ if (_dbg_screen_rect)
+ DbgScreenRect(left, top, right, bottom);
+ else
+#endif
+ DrawOverlappedWindowForAll(left, top, right, bottom);
+
+ _video_driver->make_dirty(left, top, right - left, bottom - top);
+}
+
+void DrawDirtyBlocks(void)
+{
+ byte *b = _dirty_blocks;
+ const int w = ALIGN(_screen.width, 64);
+ const int h = ALIGN(_screen.height, 8);
+ int x;
+ int y;
+
+ if (IsGeneratingWorld() && !IsGeneratingWorldReadyForPaint()) return;
+
+ y = 0;
+ do {
+ x = 0;
+ do {
+ if (*b != 0) {
+ int left;
+ int top;
+ int right = x + 64;
+ int bottom = y;
+ byte *p = b;
+ int h2;
+
+ // First try coalescing downwards
+ do {
+ *p = 0;
+ p += DIRTY_BYTES_PER_LINE;
+ bottom += 8;
+ } while (bottom != h && *p != 0);
+
+ // Try coalescing to the right too.
+ h2 = (bottom - y) >> 3;
+ assert(h2 > 0);
+ p = b;
+
+ while (right != w) {
+ byte *p2 = ++p;
+ int h = h2;
+ // Check if a full line of dirty flags is set.
+ do {
+ if (!*p2) goto no_more_coalesc;
+ p2 += DIRTY_BYTES_PER_LINE;
+ } while (--h != 0);
+
+ // Wohoo, can combine it one step to the right!
+ // Do that, and clear the bits.
+ right += 64;
+
+ h = h2;
+ p2 = p;
+ do {
+ *p2 = 0;
+ p2 += DIRTY_BYTES_PER_LINE;
+ } while (--h != 0);
+ }
+ no_more_coalesc:
+
+ left = x;
+ top = y;
+
+ if (left < _invalid_rect.left ) left = _invalid_rect.left;
+ if (top < _invalid_rect.top ) top = _invalid_rect.top;
+ if (right > _invalid_rect.right ) right = _invalid_rect.right;
+ if (bottom > _invalid_rect.bottom) bottom = _invalid_rect.bottom;
+
+ if (left < right && top < bottom) {
+ RedrawScreenRect(left, top, right, bottom);
+ }
+
+ }
+ } while (b++, (x += 64) != w);
+ } while (b += -(w >> 6) + DIRTY_BYTES_PER_LINE, (y += 8) != h);
+
+ _invalid_rect.left = w;
+ _invalid_rect.top = h;
+ _invalid_rect.right = 0;
+ _invalid_rect.bottom = 0;
+
+ /* If we are generating a world, and waiting for a paint run, mark it here
+ * as done painting, so we can continue generating. */
+ if (IsGeneratingWorld() && IsGeneratingWorldReadyForPaint()) {
+ SetGeneratingWorldPaintStatus(false);
+ }
+}
+
+
+void SetDirtyBlocks(int left, int top, int right, int bottom)
+{
+ byte *b;
+ int width;
+ int height;
+
+ if (left < 0) left = 0;
+ if (top < 0) top = 0;
+ if (right > _screen.width) right = _screen.width;
+ if (bottom > _screen.height) bottom = _screen.height;
+
+ if (left >= right || top >= bottom) return;
+
+ if (left < _invalid_rect.left ) _invalid_rect.left = left;
+ if (top < _invalid_rect.top ) _invalid_rect.top = top;
+ if (right > _invalid_rect.right ) _invalid_rect.right = right;
+ if (bottom > _invalid_rect.bottom) _invalid_rect.bottom = bottom;
+
+ left >>= 6;
+ top >>= 3;
+
+ b = _dirty_blocks + top * DIRTY_BYTES_PER_LINE + left;
+
+ width = ((right - 1) >> 6) - left + 1;
+ height = ((bottom - 1) >> 3) - top + 1;
+
+ assert(width > 0 && height > 0);
+
+ do {
+ int i = width;
+
+ do b[--i] = 0xFF; while (i);
+
+ b += DIRTY_BYTES_PER_LINE;
+ } while (--height != 0);
+}
+
+void MarkWholeScreenDirty(void)
+{
+ SetDirtyBlocks(0, 0, _screen.width, _screen.height);
+}
+
+/** Set up a clipping area for only drawing into a certain area. To do this,
+ * Fill a DrawPixelInfo object with the supplied relative rectangle, backup
+ * the original (calling) _cur_dpi and assign the just returned DrawPixelInfo
+ * _cur_dpi. When you are done, give restore _cur_dpi's original value
+ * @param *n the DrawPixelInfo that will be the clipping rectangle box allowed
+ * for drawing
+ * @param left,top,width,height the relative coordinates of the clipping
+ * rectangle relative to the current _cur_dpi. This will most likely be the
+ * offset from the calling window coordinates
+ * @return return false if the requested rectangle is not possible with the
+ * current dpi pointer. Only continue of the return value is true, or you'll
+ * get some nasty results */
+bool FillDrawPixelInfo(DrawPixelInfo *n, int left, int top, int width, int height)
+{
+ const DrawPixelInfo *o = _cur_dpi;
+
+ n->zoom = 0;
+
+ assert(width > 0);
+ assert(height > 0);
+
+ if ((left -= o->left) < 0) {
+ width += left;
+ if (width <= 0) return false;
+ n->left = -left;
+ left = 0;
+ } else {
+ n->left = 0;
+ }
+
+ if (width > o->width - left) {
+ width = o->width - left;
+ if (width <= 0) return false;
+ }
+ n->width = width;
+
+ if ((top -= o->top) < 0) {
+ height += top;
+ if (height <= 0) return false;
+ n->top = -top;
+ top = 0;
+ } else {
+ n->top = 0;
+ }
+
+ n->dst_ptr = o->dst_ptr + left + top * (n->pitch = o->pitch);
+
+ if (height > o->height - top) {
+ height = o->height - top;
+ if (height <= 0) return false;
+ }
+ n->height = height;
+
+ return true;
+}
+
+static void SetCursorSprite(CursorID cursor)
+{
+ CursorVars *cv = &_cursor;
+ const Sprite *p;
+
+ if (cv->sprite == cursor) return;
+
+ p = GetSprite(cursor & SPRITE_MASK);
+ cv->sprite = cursor;
+ cv->size.y = p->height;
+ cv->size.x = p->width;
+ cv->offs.x = p->x_offs;
+ cv->offs.y = p->y_offs;
+
+ cv->dirty = true;
+}
+
+static void SwitchAnimatedCursor(void)
+{
+ CursorVars *cv = &_cursor;
+ const CursorID *cur = cv->animate_cur;
+ CursorID sprite;
+
+ // ANIM_CURSOR_END is 0xFFFF in table/animcursors.h
+ if (cur == NULL || *cur == 0xFFFF) cur = cv->animate_list;
+
+ sprite = cur[0];
+ cv->animate_timeout = cur[1];
+ cv->animate_cur = cur + 2;
+
+ SetCursorSprite(sprite);
+}
+
+void CursorTick(void)
+{
+ if (_cursor.animate_timeout != 0 && --_cursor.animate_timeout == 0)
+ SwitchAnimatedCursor();
+}
+
+void SetMouseCursor(CursorID cursor)
+{
+ // Turn off animation
+ _cursor.animate_timeout = 0;
+ // Set cursor
+ SetCursorSprite(cursor);
+}
+
+void SetAnimatedMouseCursor(const CursorID *table)
+{
+ _cursor.animate_list = table;
+ _cursor.animate_cur = NULL;
+ SwitchAnimatedCursor();
+}
+
+bool ChangeResInGame(int w, int h)
+{
+ return
+ (_screen.width == w && _screen.height == h) ||
+ _video_driver->change_resolution(w, h);
+}
+
+void ToggleFullScreen(bool fs)
+{
+ _video_driver->toggle_fullscreen(fs);
+ if (_fullscreen != fs && _num_resolutions == 0) {
+ DEBUG(driver, 0, "Could not find a suitable fullscreen resolution");
+ }
+}
+
+static int CDECL compare_res(const void *pa, const void *pb)
+{
+ int x = ((const uint16*)pa)[0] - ((const uint16*)pb)[0];
+ if (x != 0) return x;
+ return ((const uint16*)pa)[1] - ((const uint16*)pb)[1];
+}
+
+void SortResolutions(int count)
+{
+ qsort(_resolutions, count, sizeof(_resolutions[0]), compare_res);
+}
diff --git a/src/gfx.h b/src/gfx.h
new file mode 100644
index 000000000..8636a36a6
--- /dev/null
+++ b/src/gfx.h
@@ -0,0 +1,163 @@
+/* $Id$ */
+
+#ifndef GFX_H
+#define GFX_H
+
+typedef byte Pixel;
+
+struct DrawPixelInfo {
+ Pixel *dst_ptr;
+ int left, top, width, height;
+ int pitch;
+ uint16 zoom;
+};
+
+
+typedef struct CursorVars {
+ Point pos, size, offs, delta; ///< position, size, offset from top-left, and movement
+ Point draw_pos, draw_size; ///< position and size bounding-box for drawing
+ CursorID sprite; ///< current image of cursor
+
+ int wheel; ///< mouse wheel movement
+ const CursorID *animate_list, *animate_cur; ///< in case of animated cursor, list of frames
+ uint animate_timeout; ///< current frame in list of animated cursor
+
+ bool visible; ///< cursor is visible
+ bool dirty; ///< the rect occupied by the mouse is dirty (redraw)
+ bool fix_at; ///< mouse is moving, but cursor is not (used for scrolling)
+ bool in_window; ///< mouse inside this window, determines drawing logic
+} CursorVars;
+
+
+typedef enum FontSizes {
+ FS_NORMAL,
+ FS_SMALL,
+ FS_LARGE,
+ FS_END,
+} FontSize;
+
+
+void RedrawScreenRect(int left, int top, int right, int bottom);
+void GfxScroll(int left, int top, int width, int height, int xo, int yo);
+
+
+// XXX doesn't really belong here, but the only
+// consumers always use it in conjunction with DoDrawString()
+#define UPARROW "\xEE\x8A\x80"
+#define DOWNARROW "\xEE\x8A\xAA"
+
+
+int DrawStringCentered(int x, int y, StringID str, uint16 color);
+int DrawStringCenteredTruncated(int xl, int xr, int y, StringID str, uint16 color);
+int DoDrawStringCentered(int x, int y, const char *str, uint16 color);
+
+int DrawString(int x, int y, StringID str, uint16 color);
+int DrawStringTruncated(int x, int y, StringID str, uint16 color, uint maxw);
+
+int DoDrawString(const char *string, int x, int y, uint16 color);
+int DoDrawStringTruncated(const char *str, int x, int y, uint16 color, uint maxw);
+
+void DrawStringCenterUnderline(int x, int y, StringID str, uint16 color);
+void DrawStringCenterUnderlineTruncated(int xl, int xr, int y, StringID str, uint16 color);
+
+int DrawStringRightAligned(int x, int y, StringID str, uint16 color);
+void DrawStringRightAlignedTruncated(int x, int y, StringID str, uint16 color, uint maxw);
+void DrawStringRightAlignedUnderline(int x, int y, StringID str, uint16 color);
+
+void GfxFillRect(int left, int top, int right, int bottom, int color);
+void GfxDrawLine(int left, int top, int right, int bottom, int color);
+
+BoundingRect GetStringBoundingBox(const char *str);
+uint32 FormatStringLinebreaks(char *str, int maxw);
+void LoadStringWidthTable(void);
+void DrawStringMultiCenter(int x, int y, StringID str, int maxw);
+uint DrawStringMultiLine(int x, int y, StringID str, int maxw);
+void DrawDirtyBlocks(void);
+void SetDirtyBlocks(int left, int top, int right, int bottom);
+void MarkWholeScreenDirty(void);
+
+void GfxInitPalettes(void);
+
+bool FillDrawPixelInfo(DrawPixelInfo* n, int left, int top, int width, int height);
+
+/* window.c */
+void DrawOverlappedWindowForAll(int left, int top, int right, int bottom);
+
+void SetMouseCursor(uint cursor);
+void SetAnimatedMouseCursor(const CursorID *table);
+void CursorTick(void);
+void DrawMouseCursor(void);
+void ScreenSizeChanged(void);
+void UndrawMouseCursor(void);
+bool ChangeResInGame(int w, int h);
+void SortResolutions(int count);
+void ToggleFullScreen(bool fs);
+
+/* gfx.c */
+#define ASCII_LETTERSTART 32
+extern FontSize _cur_fontsize;
+
+byte GetCharacterWidth(FontSize size, uint32 key);
+
+static inline byte GetCharacterHeight(FontSize size)
+{
+ switch (size) {
+ default: NOT_REACHED();
+ case FS_NORMAL: return 10;
+ case FS_SMALL: return 6;
+ case FS_LARGE: return 18;
+ }
+}
+
+VARDEF DrawPixelInfo _screen;
+VARDEF DrawPixelInfo *_cur_dpi;
+VARDEF CursorVars _cursor;
+
+enum {
+ COLOUR_DARK_BLUE,
+ COLOUR_PALE_GREEN,
+ COLOUR_PINK,
+ COLOUR_YELLOW,
+ COLOUR_RED,
+ COLOUR_LIGHT_BLUE,
+ COLOUR_GREEN,
+ COLOUR_DARK_GREEN,
+ COLOUR_BLUE,
+ COLOUR_CREAM,
+ COLOUR_MAUVE,
+ COLOUR_PURPLE,
+ COLOUR_ORANGE,
+ COLOUR_BROWN,
+ COLOUR_GREY,
+ COLOUR_WHITE
+};
+
+/**
+ * All 16 colour gradients
+ * 8 colours per gradient from darkest (0) to lightest (7)
+ */
+VARDEF byte _colour_gradient[16][8];
+
+VARDEF int _pal_first_dirty;
+VARDEF int _pal_last_dirty;
+
+VARDEF bool _use_dos_palette;
+
+typedef struct Colour {
+ byte r;
+ byte g;
+ byte b;
+} Colour;
+
+extern Colour _cur_palette[256];
+
+
+typedef enum StringColorFlags {
+ IS_PALETTE_COLOR = 0x100, // color value is already a real palette color index, not an index of a StringColor
+} StringColorFlags;
+
+#ifdef _DEBUG
+extern bool _dbg_screen_rect;
+#endif
+
+#endif /* GFX_H */
diff --git a/src/gfxinit.c b/src/gfxinit.c
new file mode 100644
index 000000000..ae9fb3cb8
--- /dev/null
+++ b/src/gfxinit.c
@@ -0,0 +1,390 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "debug.h"
+#include "functions.h"
+#include "gfx.h"
+#include "gfxinit.h"
+#include "spritecache.h"
+#include "table/sprites.h"
+#include "fileio.h"
+#include "string.h"
+#include "newgrf.h"
+#include "md5.h"
+#include "variables.h"
+#include "fontcache.h"
+#include <string.h>
+
+typedef struct MD5File {
+ const char * const filename; // filename
+ const md5_byte_t hash[16]; // md5 sum of the file
+} MD5File;
+
+typedef struct FileList {
+ const MD5File basic[4]; // grf files that always have to be loaded
+ const MD5File landscape[3]; // landscape specific grf files
+} FileList;
+
+enum {
+ SKIP = 0xFFFE,
+ END = 0xFFFF
+};
+
+#include "table/files.h"
+#include "table/landscape_sprite.h"
+
+static const SpriteID * const _landscape_spriteindexes[] = {
+ _landscape_spriteindexes_1,
+ _landscape_spriteindexes_2,
+ _landscape_spriteindexes_3,
+};
+
+static const SpriteID * const _slopes_spriteindexes[] = {
+ _slopes_spriteindexes_0,
+ _slopes_spriteindexes_1,
+ _slopes_spriteindexes_2,
+ _slopes_spriteindexes_3,
+};
+
+
+static uint LoadGrfFile(const char* filename, uint load_index, int file_index)
+{
+ uint load_index_org = load_index;
+
+ FioOpenFile(file_index, filename);
+
+ DEBUG(sprite, 2, "Reading grf-file '%s'", filename);
+
+ while (LoadNextSprite(load_index, file_index)) {
+ load_index++;
+ if (load_index >= MAX_SPRITES) {
+ error("Too many sprites. Recompile with higher MAX_SPRITES value or remove some custom GRF files.");
+ }
+ }
+ DEBUG(sprite, 2, "Currently %i sprites are loaded", load_index);
+
+ return load_index - load_index_org;
+}
+
+
+static void LoadGrfIndexed(const char* filename, const SpriteID* index_tbl, int file_index)
+{
+ uint start;
+
+ FioOpenFile(file_index, filename);
+
+ DEBUG(sprite, 2, "Reading indexed grf-file '%s'", filename);
+
+ while ((start = *index_tbl++) != END) {
+ uint end = *index_tbl++;
+
+ if (start == SKIP) { // skip sprites (amount in second var)
+ SkipSprites(end);
+ } else { // load sprites and use indexes from start to end
+ do {
+ #ifdef NDEBUG
+ LoadNextSprite(start, file_index);
+ #else
+ bool b = LoadNextSprite(start, file_index);
+ assert(b);
+ #endif
+ } while (++start <= end);
+ }
+ }
+}
+
+
+/* Check that the supplied MD5 hash matches that stored for the supplied filename */
+static bool CheckMD5Digest(const MD5File file, md5_byte_t *digest, bool warn)
+{
+ if (memcmp(file.hash, digest, sizeof(file.hash)) == 0) return true;
+ if (warn) fprintf(stderr, "MD5 of %s is ****INCORRECT**** - File Corrupt.\n", file.filename);
+ return false;
+}
+
+/* Calculate and check the MD5 hash of the supplied filename.
+ * returns true if the checksum is correct */
+static bool FileMD5(const MD5File file, bool warn)
+{
+ FILE *f;
+ char buf[MAX_PATH];
+
+ // open file
+ snprintf(buf, lengthof(buf), "%s%s", _paths.data_dir, file.filename);
+ f = fopen(buf, "rb");
+
+#if !defined(WIN32)
+ if (f == NULL) {
+ strtolower(buf + strlen(_paths.data_dir) - 1);
+ f = fopen(buf, "rb");
+ }
+#endif
+
+ if (f != NULL) {
+ md5_state_t filemd5state;
+ md5_byte_t buffer[1024];
+ md5_byte_t digest[16];
+ size_t len;
+
+ md5_init(&filemd5state);
+ while ((len = fread(buffer, 1, sizeof(buffer), f)) != 0)
+ md5_append(&filemd5state, buffer, len);
+
+ if (ferror(f) && warn) fprintf(stderr, "Error Reading from %s \n", buf);
+ fclose(f);
+
+ md5_finish(&filemd5state, digest);
+ return CheckMD5Digest(file, digest, warn);
+ } else { // file not found
+ return false;
+ }
+}
+
+/* Checks, if either the Windows files exist (TRG1R.GRF) or the DOS files (TRG1.GRF)
+ * by comparing the MD5 checksums of the files. _use_dos_palette is set accordingly.
+ * If neither are found, Windows palette is assumed.
+ *
+ * (Note: Also checks sample.cat for corruption) */
+void CheckExternalFiles(void)
+{
+ uint i;
+ // count of files from this version
+ uint dos = 0;
+ uint win = 0;
+
+ for (i = 0; i < 2; i++) if (FileMD5(files_dos.basic[i], true)) dos++;
+ for (i = 0; i < 3; i++) if (FileMD5(files_dos.landscape[i], true)) dos++;
+
+ for (i = 0; i < 2; i++) if (FileMD5(files_win.basic[i], true)) win++;
+ for (i = 0; i < 3; i++) if (FileMD5(files_win.landscape[i], true)) win++;
+
+ if (!FileMD5(sample_cat_win, false) && !FileMD5(sample_cat_dos, false))
+ fprintf(stderr, "Your sample.cat file is corrupted or missing!\n");
+
+ for (i = 0; i < lengthof(files_openttd); i++) {
+ if (!FileMD5(files_openttd[i], false)) {
+ fprintf(stderr, "Your %s file is corrupted or missing!\n", files_openttd[i].filename);
+ }
+ }
+
+ /*
+ * forced DOS palette via command line -> leave it that way
+ * all Windows files present -> Windows palette
+ * all DOS files present -> DOS palette
+ * no Windows files present and any DOS file present -> DOS palette
+ * otherwise -> Windows palette
+ */
+ if (_use_dos_palette) {
+ return;
+ } else if (win == 5) {
+ _use_dos_palette = false;
+ } else if (dos == 5 || (win == 0 && dos > 0)) {
+ _use_dos_palette = true;
+ } else {
+ _use_dos_palette = false;
+ }
+}
+
+
+static const SpriteID trg1idx[] = {
+ 0, 1, // Mouse cursor, ZZZ
+/* Medium font */
+ 2, 92, // ' ' till 'z'
+ SKIP, 36,
+ 160, 160, // Move ¾ to the correct position
+ 98, 98, // Up arrow
+ 131, 133,
+ SKIP, 1, // skip currency sign
+ 135, 135,
+ SKIP, 1,
+ 137, 137,
+ SKIP, 1,
+ 139, 139,
+ 140, 140, // TODO Down arrow
+ 141, 141,
+ 142, 142, // TODO Check mark
+ 143, 143, // TODO Cross
+ 144, 144,
+ 145, 145, // TODO Right arrow
+ 146, 149,
+ 118, 122, // Transport markers
+ SKIP, 2,
+ 157, 157,
+ 114, 115, // Small up/down arrows
+ SKIP, 1,
+ 161, 225,
+/* Small font */
+ 226, 316, // ' ' till 'z'
+ SKIP, 36,
+ 384, 384, // Move ¾ to the correct position
+ 322, 322, // Up arrow
+ 355, 357,
+ SKIP, 1, // skip currency sign
+ 359, 359,
+ SKIP, 1,
+ 361, 361,
+ SKIP, 1,
+ 363, 363,
+ 364, 364, // TODO Down arrow
+ 365, 366,
+ SKIP, 1,
+ 368, 368,
+ 369, 369, // TODO Right arrow
+ 370, 373,
+ SKIP, 7,
+ 381, 381,
+ SKIP, 3,
+ 385, 449,
+/* Big font */
+ 450, 540, // ' ' till 'z'
+ SKIP, 36,
+ 608, 608, // Move ¾ to the correct position
+ SKIP, 1,
+ 579, 581,
+ SKIP, 1,
+ 583, 583,
+ SKIP, 5,
+ 589, 589,
+ SKIP, 15,
+ 605, 605,
+ SKIP, 3,
+ 609, 625,
+ SKIP, 1,
+ 627, 632,
+ SKIP, 1,
+ 634, 639,
+ SKIP, 1,
+ 641, 657,
+ SKIP, 1,
+ 659, 664,
+ SKIP, 2,
+ 667, 671,
+ SKIP, 1,
+ 673, 673,
+/* Graphics */
+ 674, 4792,
+ END
+};
+
+/* NOTE: When adding a normal sprite, increase OPENTTD_SPRITES_COUNT with the
+ * amount of sprites and add them to the end of the list, with the index of
+ * the old sprite-count offset from SPR_OPENTTD_BASE. With this there is no
+ * correspondence of any kind with the ID's in the grf file, but results in
+ * a maximum use of sprite slots. */
+static const SpriteID _openttd_grf_indexes[] = {
+ SPR_IMG_AUTORAIL, SPR_CURSOR_WAYPOINT, // icons etc
+ 134, 134, // euro symbol medium size
+ 582, 582, // euro symbol large size
+ 358, 358, // euro symbol tiny
+ SPR_CURSOR_CANAL, SPR_IMG_FASTFORWARD, // more icons
+ 648, 648, // nordic char: æ
+ 616, 616, // nordic char: Æ
+ 666, 666, // nordic char: ø
+ 634, 634, // nordic char: Ø
+ SPR_PIN_UP, SPR_CURSOR_CLONE_TRAIN, // more icons
+ 382, 383, // ¼ ½ tiny
+ 158, 159, // ¼ ½ medium
+ 606, 607, // ¼ ½ large
+ 360, 360, // ¦ tiny
+ 362, 362, // ¨ tiny
+ 136, 136, // ¦ medium
+ 138, 138, // ¨ medium
+ 584, 584, // ¦ large
+ 586, 586, // ¨ large
+ 626, 626, // Ð large
+ 658, 658, // ð large
+ 374, 374, // ´ tiny
+ 378, 378, // ¸ tiny
+ 150, 150, // ´ medium
+ 154, 154, // ¸ medium
+ 598, 598, // ´ large
+ 602, 602, // ¸ large
+ 640, 640, // Þ large
+ 672, 672, // þ large
+ 380, 380, // º tiny
+ 156, 156, // º medium
+ 604, 604, // º large
+ 317, 320, // { | } ~ tiny
+ 93, 96, // { | } ~ medium
+ 541, 544, // { | } ~ large
+ SPR_HOUSE_ICON, SPR_HOUSE_ICON,
+ 585, 585, // § large
+ 587, 587, // © large
+ 592, 592, // ® large
+ 594, 597, // ° ± ² ³ large
+ 633, 633, // × large
+ 665, 665, // ÷ large
+ SPR_SELL_TRAIN, SPR_SHARED_ORDERS_ICON,
+ 377, 377, // · small
+ 153, 153, // · medium
+ 601, 601, // · large
+ END
+};
+
+
+static void LoadSpriteTables(void)
+{
+ const FileList* files = _use_dos_palette ? &files_dos : &files_win;
+ uint load_index;
+ uint i;
+
+ LoadGrfIndexed(files->basic[0].filename, trg1idx, 0);
+ DupSprite( 2, 130); // non-breaking space medium
+ DupSprite(226, 354); // non-breaking space tiny
+ DupSprite(450, 578); // non-breaking space large
+ load_index = 4793;
+
+ for (i = 1; files->basic[i].filename != NULL; i++) {
+ load_index += LoadGrfFile(files->basic[i].filename, load_index, i);
+ }
+
+ /* Load additional sprites for climates other than temperate */
+ if (_opt.landscape != LT_NORMAL) {
+ LoadGrfIndexed(
+ files->landscape[_opt.landscape - 1].filename,
+ _landscape_spriteindexes[_opt.landscape - 1],
+ i++
+ );
+ }
+
+ assert(load_index == SPR_SIGNALS_BASE);
+ load_index += LoadGrfFile("nsignalsw.grf", load_index, i++);
+
+ assert(load_index == SPR_CANALS_BASE);
+ load_index += LoadGrfFile("canalsw.grf", load_index, i++);
+
+ assert(load_index == SPR_SLOPES_BASE);
+ LoadGrfIndexed("trkfoundw.grf", _slopes_spriteindexes[_opt.landscape], i++);
+
+ load_index = SPR_AUTORAIL_BASE;
+ load_index += LoadGrfFile("autorail.grf", load_index, i++);
+
+ assert(load_index == SPR_ELRAIL_BASE);
+ load_index += LoadGrfFile("elrailsw.grf", load_index, i++);
+
+ assert(load_index == SPR_2CCMAP_BASE);
+ load_index += LoadGrfFile("2ccmap.grf", load_index, i++);
+
+ assert(load_index == SPR_OPENTTD_BASE);
+ LoadGrfIndexed("openttd.grf", _openttd_grf_indexes, i++);
+ load_index = SPR_OPENTTD_BASE + OPENTTD_SPRITES_COUNT;
+
+ assert(load_index == SPR_AIRPORTX_BASE);
+ load_index += LoadGrfFile("airports.grf", load_index, i++);
+
+ /* Initialize the unicode to sprite mapping table */
+ InitializeUnicodeGlyphMap();
+
+ LoadNewGRF(load_index, i);
+}
+
+
+void GfxLoadSprites(void)
+{
+ DEBUG(sprite, 2, "Loading sprite set %d", _opt.landscape);
+
+ GfxInitSpriteMem();
+ LoadSpriteTables();
+ GfxInitPalettes();
+}
diff --git a/src/gfxinit.h b/src/gfxinit.h
new file mode 100644
index 000000000..d3873ff23
--- /dev/null
+++ b/src/gfxinit.h
@@ -0,0 +1,9 @@
+/* $Id$ */
+
+#ifndef GFXINIT_H
+#define GFXINIT_H
+
+void CheckExternalFiles(void);
+void GfxLoadSprites(void);
+
+#endif /* GFXINIT_H */
diff --git a/src/graph_gui.c b/src/graph_gui.c
new file mode 100644
index 000000000..c6a9b845b
--- /dev/null
+++ b/src/graph_gui.c
@@ -0,0 +1,1258 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "table/strings.h"
+#include "table/sprites.h"
+#include "functions.h"
+#include "window.h"
+#include "gui.h"
+#include "gfx.h"
+#include "player.h"
+#include "economy.h"
+#include "signs.h"
+#include "strings.h"
+#include "debug.h"
+#include "variables.h"
+#include "date.h"
+
+const byte _cargo_colours[NUM_CARGO] = {152, 32, 15, 174, 208, 194, 191, 84, 184, 10, 202, 48};
+
+static uint _legend_excludebits;
+static uint _legend_cargobits;
+
+/************************/
+/* GENERIC GRAPH DRAWER */
+/************************/
+
+enum {GRAPH_NUM = 16};
+
+typedef struct GraphDrawer {
+ uint sel; // bitmask of the players *excluded* (e.g. 11111111 means that no players are shown)
+ byte num_dataset;
+ byte num_on_x_axis;
+ byte month;
+ Year year;
+ bool include_neg;
+ byte num_vert_lines;
+ uint16 unk61A;
+ uint16 unk61C;
+ int left, top;
+ uint height;
+ StringID format_str_y_axis;
+ byte color_3, color_2, bg_line_color;
+ byte colors[GRAPH_NUM];
+ uint64 cost[GRAPH_NUM][24]; // last 2 years
+} GraphDrawer;
+
+#define INVALID_VALUE 0x80000000
+
+static void DrawGraph(const GraphDrawer *gw)
+{
+
+ int i,j,k;
+ uint x,y,old_x,old_y;
+ int color;
+ int right, bottom;
+ int num_x, num_dataset;
+ const uint64 *row_ptr, *col_ptr;
+ int64 mx;
+ int adj_height;
+ uint64 y_scaling, tmp;
+ int64 value;
+ int64 cur_val;
+ uint sel;
+
+ /* the colors and cost array of GraphDrawer must accomodate
+ * both values for cargo and players. So if any are higher, quit */
+ assert(GRAPH_NUM >= NUM_CARGO && GRAPH_NUM >= MAX_PLAYERS);
+
+ color = _colour_gradient[gw->bg_line_color][4];
+
+ /* draw the vertical lines */
+ i = gw->num_vert_lines; assert(i > 0);
+ x = gw->left + 66;
+ bottom = gw->top + gw->height - 1;
+ do {
+ GfxFillRect(x, gw->top, x, bottom, color);
+ x += 22;
+ } while (--i);
+
+ /* draw the horizontal lines */
+ i = 9;
+ x = gw->left + 44;
+ y = gw->height + gw->top;
+ right = gw->left + 44 + gw->num_vert_lines*22-1;
+
+ do {
+ GfxFillRect(x, y, right, y, color);
+ y -= gw->height >> 3;
+ } while (--i);
+
+ /* draw vertical edge line */
+ GfxFillRect(x, gw->top, x, bottom, gw->color_2);
+
+ adj_height = gw->height;
+ if (gw->include_neg) adj_height >>= 1;
+
+ /* draw horiz edge line */
+ y = adj_height + gw->top;
+ GfxFillRect(x, y, right, y, gw->color_2);
+
+ /* find the max element */
+ if (gw->num_on_x_axis == 0)
+ return;
+
+ num_dataset = gw->num_dataset;
+ assert(num_dataset > 0);
+
+ row_ptr = gw->cost[0];
+ mx = 0;
+ /* bit selection for the showing of various players, base max element
+ * on to-be shown player-information. This way the graph can scale */
+ sel = gw->sel;
+ do {
+ if (!(sel&1)) {
+ num_x = gw->num_on_x_axis;
+ assert(num_x > 0);
+ col_ptr = row_ptr;
+ do {
+ if (*col_ptr != INVALID_VALUE) {
+ mx = max64(mx, myabs64(*col_ptr));
+ }
+ } while (col_ptr++, --num_x);
+ }
+ } while (sel>>=1, row_ptr+=24, --num_dataset);
+
+ /* setup scaling */
+ y_scaling = INVALID_VALUE;
+ value = adj_height * 2;
+
+ if (mx > value) {
+ mx = (mx + 7) & ~7;
+ y_scaling = (((uint64) (value>>1) << 32) / mx);
+ value = mx;
+ }
+
+ /* draw text strings on the y axis */
+ tmp = value;
+ if (gw->include_neg) tmp >>= 1;
+ x = gw->left + 45;
+ y = gw->top - 3;
+ i = 9;
+ do {
+ SetDParam(0, gw->format_str_y_axis);
+ SetDParam64(1, (int64)tmp);
+ tmp -= (value >> 3);
+ DrawStringRightAligned(x, y, STR_0170, gw->color_3);
+ y += gw->height >> 3;
+ } while (--i);
+
+ /* draw strings on the x axis */
+ if (gw->month != 0xFF) {
+ x = gw->left + 44;
+ y = gw->top + gw->height + 1;
+ j = gw->month;
+ k = gw->year;
+ i = gw->num_on_x_axis;assert(i>0);
+ do {
+ SetDParam(2, k);
+ SetDParam(0, j + STR_0162_JAN);
+ SetDParam(1, j + STR_0162_JAN + 2);
+ DrawString(x, y, j == 0 ? STR_016F : STR_016E, gw->color_3);
+
+ j += 3;
+ if (j >= 12) {
+ j = 0;
+ k++;
+ }
+ x += 22;
+ } while (--i);
+ } else {
+ x = gw->left + 52;
+ y = gw->top + gw->height + 1;
+ j = gw->unk61A;
+ i = gw->num_on_x_axis;assert(i>0);
+ do {
+ SetDParam(0, j);
+ DrawString(x, y, STR_01CB, gw->color_3);
+ j += gw->unk61C;
+ x += 22;
+ } while (--i);
+ }
+
+ /* draw lines and dots */
+ i = 0;
+ row_ptr = gw->cost[0];
+ sel = gw->sel; // show only selected lines. GraphDrawer qw->sel set in Graph-Legend (_legend_excludebits)
+ do {
+ if (!(sel & 1)) {
+ x = gw->left + 55;
+ j = gw->num_on_x_axis;assert(j>0);
+ col_ptr = row_ptr;
+ color = gw->colors[i];
+ old_y = old_x = INVALID_VALUE;
+ do {
+ cur_val = *col_ptr++;
+ if (cur_val != INVALID_VALUE) {
+ y = adj_height - BIGMULSS64(cur_val, y_scaling >> 1, 31) + gw->top;
+
+ GfxFillRect(x-1, y-1, x+1, y+1, color);
+ if (old_x != INVALID_VALUE)
+ GfxDrawLine(old_x, old_y, x, y, color);
+
+ old_x = x;
+ old_y = y;
+ } else {
+ old_x = INVALID_VALUE;
+ }
+ } while (x+=22,--j);
+ }
+ } while (sel>>=1,row_ptr+=24, ++i < gw->num_dataset);
+}
+
+/****************/
+/* GRAPH LEGEND */
+/****************/
+
+void DrawPlayerIcon(PlayerID p, int x, int y)
+{
+ DrawSprite(SPRITE_PALETTE(PLAYER_SPRITE_COLOR(p) + 0x2EB), x, y);
+}
+
+static void GraphLegendWndProc(Window *w, WindowEvent *e)
+{
+ const Player* p;
+
+ switch (e->event) {
+ case WE_CREATE: {
+ uint i;
+ for (i = 3; i < w->widget_count; i++) {
+ if (!HASBIT(_legend_excludebits, i - 3)) LowerWindowWidget(w, i);
+ }
+ break;
+ }
+
+ case WE_PAINT:
+ FOR_ALL_PLAYERS(p) {
+ if (!p->is_active) {
+ SETBIT(_legend_excludebits, p->index);
+ RaiseWindowWidget(w, p->index + 3);
+ }
+ }
+ DrawWindowWidgets(w);
+
+ FOR_ALL_PLAYERS(p) {
+ if (!p->is_active) continue;
+
+ DrawPlayerIcon(p->index, 4, 18+p->index*12);
+
+ SetDParam(0, p->name_1);
+ SetDParam(1, p->name_2);
+ SetDParam(2, GetPlayerNameString(p->index, 3));
+ DrawString(21,17+p->index*12,STR_7021,HASBIT(_legend_excludebits, p->index) ? 0x10 : 0xC);
+ }
+ break;
+
+ case WE_CLICK:
+ if (IS_INT_INSIDE(e->we.click.widget, 3, 11)) {
+ _legend_excludebits ^= (1 << (e->we.click.widget - 3));
+ ToggleWidgetLoweredState(w, e->we.click.widget);
+ SetWindowDirty(w);
+ InvalidateWindow(WC_INCOME_GRAPH, 0);
+ InvalidateWindow(WC_OPERATING_PROFIT, 0);
+ InvalidateWindow(WC_DELIVERED_CARGO, 0);
+ InvalidateWindow(WC_PERFORMANCE_HISTORY, 0);
+ InvalidateWindow(WC_COMPANY_VALUE, 0);
+ }
+ break;
+ }
+}
+
+static const Widget _graph_legend_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 249, 0, 13, STR_704E_KEY_TO_COMPANY_GRAPHS, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 249, 14, 113, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 14, 2, 247, 16, 27, 0x0, STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
+{ WWT_PANEL, RESIZE_NONE, 14, 2, 247, 28, 39, 0x0, STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
+{ WWT_PANEL, RESIZE_NONE, 14, 2, 247, 40, 51, 0x0, STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
+{ WWT_PANEL, RESIZE_NONE, 14, 2, 247, 52, 63, 0x0, STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
+{ WWT_PANEL, RESIZE_NONE, 14, 2, 247, 64, 75, 0x0, STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
+{ WWT_PANEL, RESIZE_NONE, 14, 2, 247, 76, 87, 0x0, STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
+{ WWT_PANEL, RESIZE_NONE, 14, 2, 247, 88, 99, 0x0, STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
+{ WWT_PANEL, RESIZE_NONE, 14, 2, 247, 100, 111, 0x0, STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _graph_legend_desc = {
+ WDP_AUTO, WDP_AUTO, 250, 114,
+ WC_GRAPH_LEGEND,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _graph_legend_widgets,
+ GraphLegendWndProc
+};
+
+static void ShowGraphLegend(void)
+{
+ AllocateWindowDescFront(&_graph_legend_desc, 0);
+}
+
+/********************/
+/* OPERATING PROFIT */
+/********************/
+
+static void SetupGraphDrawerForPlayers(GraphDrawer *gd)
+{
+ const Player* p;
+ uint excludebits = _legend_excludebits;
+ int nums;
+ int mo,yr;
+
+ // Exclude the players which aren't valid
+ FOR_ALL_PLAYERS(p) {
+ if (!p->is_active) SETBIT(excludebits,p->index);
+ }
+ gd->sel = excludebits;
+ gd->num_vert_lines = 24;
+
+ nums = 0;
+ FOR_ALL_PLAYERS(p) {
+ if (p->is_active) nums = max(nums,p->num_valid_stat_ent);
+ }
+ gd->num_on_x_axis = min(nums,24);
+
+ mo = (_cur_month/3-nums)*3;
+ yr = _cur_year;
+ while (mo < 0) {
+ yr--;
+ mo += 12;
+ }
+
+ gd->year = yr;
+ gd->month = mo;
+}
+
+static void OperatingProfitWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ GraphDrawer gd;
+ const Player* p;
+ int i,j;
+ int numd;
+
+ DrawWindowWidgets(w);
+
+ gd.left = 2;
+ gd.top = 18;
+ gd.height = 136;
+ gd.include_neg = true;
+ gd.format_str_y_axis = STR_CURRCOMPACT;
+ gd.color_3 = 0x10;
+ gd.color_2 = 0xD7;
+ gd.bg_line_color = 0xE;
+
+ SetupGraphDrawerForPlayers(&gd);
+
+ numd = 0;
+ FOR_ALL_PLAYERS(p) {
+ if (p->is_active) {
+ gd.colors[numd] = _colour_gradient[p->player_color][6];
+ for (j = gd.num_on_x_axis, i = 0; --j >= 0;) {
+ gd.cost[numd][i] = (j >= p->num_valid_stat_ent) ? INVALID_VALUE : (uint64)(p->old_economy[j].income + p->old_economy[j].expenses);
+ i++;
+ }
+ }
+ numd++;
+ }
+
+ gd.num_dataset = numd;
+
+ DrawGraph(&gd);
+ } break;
+ case WE_CLICK:
+ if (e->we.click.widget == 2) /* Clicked on Legend */
+ ShowGraphLegend();
+ break;
+ }
+}
+
+static const Widget _operating_profit_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 525, 0, 13, STR_7025_OPERATING_PROFIT_GRAPH, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 526, 575, 0, 13, STR_704C_KEY, STR_704D_SHOW_KEY_TO_GRAPHS},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 575, 14, 173, 0x0, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _operating_profit_desc = {
+ WDP_AUTO, WDP_AUTO, 576, 174,
+ WC_OPERATING_PROFIT,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _operating_profit_widgets,
+ OperatingProfitWndProc
+};
+
+
+void ShowOperatingProfitGraph(void)
+{
+ if (AllocateWindowDescFront(&_operating_profit_desc, 0)) {
+ InvalidateWindow(WC_GRAPH_LEGEND, 0);
+ }
+}
+
+
+/****************/
+/* INCOME GRAPH */
+/****************/
+
+static void IncomeGraphWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ GraphDrawer gd;
+ const Player* p;
+ int i,j;
+ int numd;
+
+ DrawWindowWidgets(w);
+
+ gd.left = 2;
+ gd.top = 18;
+ gd.height = 104;
+ gd.include_neg = false;
+ gd.format_str_y_axis = STR_CURRCOMPACT;
+ gd.color_3 = 0x10;
+ gd.color_2 = 0xD7;
+ gd.bg_line_color = 0xE;
+ SetupGraphDrawerForPlayers(&gd);
+
+ numd = 0;
+ FOR_ALL_PLAYERS(p) {
+ if (p->is_active) {
+ gd.colors[numd] = _colour_gradient[p->player_color][6];
+ for (j = gd.num_on_x_axis, i = 0; --j >= 0;) {
+ gd.cost[numd][i] = (j >= p->num_valid_stat_ent) ? INVALID_VALUE : (uint64)p->old_economy[j].income;
+ i++;
+ }
+ }
+ numd++;
+ }
+
+ gd.num_dataset = numd;
+
+ DrawGraph(&gd);
+ break;
+ }
+
+ case WE_CLICK:
+ if (e->we.click.widget == 2)
+ ShowGraphLegend();
+ break;
+ }
+}
+
+static const Widget _income_graph_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 525, 0, 13, STR_7022_INCOME_GRAPH, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 526, 575, 0, 13, STR_704C_KEY, STR_704D_SHOW_KEY_TO_GRAPHS},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 575, 14, 141, 0x0, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _income_graph_desc = {
+ WDP_AUTO, WDP_AUTO, 576, 142,
+ WC_INCOME_GRAPH,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _income_graph_widgets,
+ IncomeGraphWndProc
+};
+
+void ShowIncomeGraph(void)
+{
+ if (AllocateWindowDescFront(&_income_graph_desc, 0)) {
+ InvalidateWindow(WC_GRAPH_LEGEND, 0);
+ }
+}
+
+/*******************/
+/* DELIVERED CARGO */
+/*******************/
+
+static void DeliveredCargoGraphWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ GraphDrawer gd;
+ const Player* p;
+ int i,j;
+ int numd;
+
+ DrawWindowWidgets(w);
+
+ gd.left = 2;
+ gd.top = 18;
+ gd.height = 104;
+ gd.include_neg = false;
+ gd.format_str_y_axis = STR_7024;
+ gd.color_3 = 0x10;
+ gd.color_2 = 0xD7;
+ gd.bg_line_color = 0xE;
+ SetupGraphDrawerForPlayers(&gd);
+
+ numd = 0;
+ FOR_ALL_PLAYERS(p) {
+ if (p->is_active) {
+ gd.colors[numd] = _colour_gradient[p->player_color][6];
+ for (j = gd.num_on_x_axis, i = 0; --j >= 0;) {
+ gd.cost[numd][i] = (j >= p->num_valid_stat_ent) ? INVALID_VALUE : (uint64)p->old_economy[j].delivered_cargo;
+ i++;
+ }
+ }
+ numd++;
+ }
+
+ gd.num_dataset = numd;
+
+ DrawGraph(&gd);
+ break;
+ }
+
+ case WE_CLICK:
+ if (e->we.click.widget == 2)
+ ShowGraphLegend();
+ break;
+ }
+}
+
+static const Widget _delivered_cargo_graph_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 525, 0, 13, STR_7050_UNITS_OF_CARGO_DELIVERED, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 526, 575, 0, 13, STR_704C_KEY, STR_704D_SHOW_KEY_TO_GRAPHS},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 575, 14, 141, 0x0, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _delivered_cargo_graph_desc = {
+ WDP_AUTO, WDP_AUTO, 576, 142,
+ WC_DELIVERED_CARGO,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _delivered_cargo_graph_widgets,
+ DeliveredCargoGraphWndProc
+};
+
+void ShowDeliveredCargoGraph(void)
+{
+ if (AllocateWindowDescFront(&_delivered_cargo_graph_desc, 0)) {
+ InvalidateWindow(WC_GRAPH_LEGEND, 0);
+ }
+}
+
+/***********************/
+/* PERFORMANCE HISTORY */
+/***********************/
+
+static void PerformanceHistoryWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ GraphDrawer gd;
+ const Player* p;
+ int i,j;
+ int numd;
+
+ DrawWindowWidgets(w);
+
+ gd.left = 2;
+ gd.top = 18;
+ gd.height = 200;
+ gd.include_neg = false;
+ gd.format_str_y_axis = STR_7024;
+ gd.color_3 = 0x10;
+ gd.color_2 = 0xD7;
+ gd.bg_line_color = 0xE;
+ SetupGraphDrawerForPlayers(&gd);
+
+ numd = 0;
+ FOR_ALL_PLAYERS(p) {
+ if (p->is_active) {
+ gd.colors[numd] = _colour_gradient[p->player_color][6];
+ for (j = gd.num_on_x_axis, i = 0; --j >= 0;) {
+ gd.cost[numd][i] = (j >= p->num_valid_stat_ent) ? INVALID_VALUE : (uint64)p->old_economy[j].performance_history;
+ i++;
+ }
+ }
+ numd++;
+ }
+
+ gd.num_dataset = numd;
+
+ DrawGraph(&gd);
+ break;
+ }
+
+ case WE_CLICK:
+ if (e->we.click.widget == 2)
+ ShowGraphLegend();
+ if (e->we.click.widget == 3)
+ ShowPerformanceRatingDetail();
+ break;
+ }
+}
+
+static const Widget _performance_history_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 475, 0, 13, STR_7051_COMPANY_PERFORMANCE_RATINGS, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 526, 575, 0, 13, STR_704C_KEY, STR_704D_SHOW_KEY_TO_GRAPHS},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 476, 525, 0, 13, STR_PERFORMANCE_DETAIL_KEY, STR_704D_SHOW_KEY_TO_GRAPHS},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 575, 14, 237, 0x0, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _performance_history_desc = {
+ WDP_AUTO, WDP_AUTO, 576, 238,
+ WC_PERFORMANCE_HISTORY,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _performance_history_widgets,
+ PerformanceHistoryWndProc
+};
+
+void ShowPerformanceHistoryGraph(void)
+{
+ if (AllocateWindowDescFront(&_performance_history_desc, 0)) {
+ InvalidateWindow(WC_GRAPH_LEGEND, 0);
+ }
+}
+
+/*****************/
+/* COMPANY VALUE */
+/*****************/
+
+static void CompanyValueGraphWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ GraphDrawer gd;
+ const Player* p;
+ int i,j;
+ int numd;
+
+ DrawWindowWidgets(w);
+
+ gd.left = 2;
+ gd.top = 18;
+ gd.height = 200;
+ gd.include_neg = false;
+ gd.format_str_y_axis = STR_CURRCOMPACT;
+ gd.color_3 = 0x10;
+ gd.color_2 = 0xD7;
+ gd.bg_line_color = 0xE;
+ SetupGraphDrawerForPlayers(&gd);
+
+ numd = 0;
+ FOR_ALL_PLAYERS(p) {
+ if (p->is_active) {
+ gd.colors[numd] = _colour_gradient[p->player_color][6];
+ for (j = gd.num_on_x_axis, i = 0; --j >= 0;) {
+ gd.cost[numd][i] = (j >= p->num_valid_stat_ent) ? INVALID_VALUE : (uint64)p->old_economy[j].company_value;
+ i++;
+ }
+ }
+ numd++;
+ }
+
+ gd.num_dataset = numd;
+
+ DrawGraph(&gd);
+ break;
+ }
+
+ case WE_CLICK:
+ if (e->we.click.widget == 2)
+ ShowGraphLegend();
+ break;
+ }
+}
+
+static const Widget _company_value_graph_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 525, 0, 13, STR_7052_COMPANY_VALUES, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 526, 575, 0, 13, STR_704C_KEY, STR_704D_SHOW_KEY_TO_GRAPHS},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 575, 14, 237, 0x0, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _company_value_graph_desc = {
+ WDP_AUTO, WDP_AUTO, 576, 238,
+ WC_COMPANY_VALUE,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _company_value_graph_widgets,
+ CompanyValueGraphWndProc
+};
+
+void ShowCompanyValueGraph(void)
+{
+ if (AllocateWindowDescFront(&_company_value_graph_desc, 0)) {
+ InvalidateWindow(WC_GRAPH_LEGEND, 0);
+ }
+}
+
+/*****************/
+/* PAYMENT RATES */
+/*****************/
+
+static void CargoPaymentRatesWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_CREATE: {
+ uint i;
+ for (i = 3; i < w->widget_count; i++) {
+ if (!HASBIT(_legend_cargobits, i - 3)) LowerWindowWidget(w, i);
+ }
+ break;
+ }
+
+ case WE_PAINT: {
+ int j, x, y;
+ CargoID i;
+ GraphDrawer gd;
+
+ DrawWindowWidgets(w);
+
+ x = 495;
+ y = 24;
+
+ gd.sel = _legend_cargobits;
+ gd.left = 2;
+ gd.top = 24;
+ gd.height = 104;
+ gd.include_neg = false;
+ gd.format_str_y_axis = STR_CURRCOMPACT;
+ gd.color_3 = 16;
+ gd.color_2 = 215;
+ gd.bg_line_color = 14;
+ gd.num_dataset = NUM_CARGO;
+ gd.num_on_x_axis = 20;
+ gd.num_vert_lines = 20;
+ gd.month = 0xFF;
+ gd.unk61A = 10;
+ gd.unk61C = 10;
+
+ for (i = 0; i != NUM_CARGO; i++) {
+ /* Since the buttons have no text, no images,
+ * both the text and the colored box have to be manually painted.
+ * clk_dif will move one pixel down and one pixel to the right
+ * when the button is clicked */
+ byte clk_dif = IsWindowWidgetLowered(w, i + 3) ? 1 : 0;
+
+ GfxFillRect(x + clk_dif, y + clk_dif, x + 8 + clk_dif, y + 5 + clk_dif, 0);
+ GfxFillRect(x + 1 + clk_dif, y + 1 + clk_dif, x + 7 + clk_dif, y + 4 + clk_dif, _cargo_colours[i]);
+ SetDParam(0, _cargoc.names_s[i]);
+ DrawString(x + 14 + clk_dif, y + clk_dif, STR_7065, 0);
+ y += 8;
+ gd.colors[i] = _cargo_colours[i];
+ for (j = 0; j != 20; j++) {
+ gd.cost[i][j] = (uint64)GetTransportedGoodsIncome(10, 20, j * 6 + 6, i);
+ }
+ }
+
+ DrawGraph(&gd);
+
+ DrawString(2 + 46, 24 + gd.height + 7, STR_7062_DAYS_IN_TRANSIT, 0);
+ DrawString(2 + 84, 24 - 9, STR_7063_PAYMENT_FOR_DELIVERING, 0);
+ } break;
+
+ case WE_CLICK: {
+ switch (e->we.click.widget) {
+ case 3: case 4: case 5: case 6:
+ case 7: case 8: case 9: case 10:
+ case 11: case 12: case 13: case 14:
+ TOGGLEBIT(_legend_cargobits, e->we.click.widget - 3);
+ ToggleWidgetLoweredState(w, e->we.click.widget);
+ SetWindowDirty(w);
+ break;
+ }
+ } break;
+ }
+}
+
+static const Widget _cargo_payment_rates_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 567, 0, 13, STR_7061_CARGO_PAYMENT_RATES, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 567, 14, 141, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 12, 493, 562, 24, 31, 0x0, STR_7064_TOGGLE_GRAPH_FOR_CARGO},
+{ WWT_PANEL, RESIZE_NONE, 12, 493, 562, 32, 39, 0x0, STR_7064_TOGGLE_GRAPH_FOR_CARGO},
+{ WWT_PANEL, RESIZE_NONE, 12, 493, 562, 40, 47, 0x0, STR_7064_TOGGLE_GRAPH_FOR_CARGO},
+{ WWT_PANEL, RESIZE_NONE, 12, 493, 562, 48, 55, 0x0, STR_7064_TOGGLE_GRAPH_FOR_CARGO},
+{ WWT_PANEL, RESIZE_NONE, 12, 493, 562, 56, 63, 0x0, STR_7064_TOGGLE_GRAPH_FOR_CARGO},
+{ WWT_PANEL, RESIZE_NONE, 12, 493, 562, 64, 71, 0x0, STR_7064_TOGGLE_GRAPH_FOR_CARGO},
+{ WWT_PANEL, RESIZE_NONE, 12, 493, 562, 72, 79, 0x0, STR_7064_TOGGLE_GRAPH_FOR_CARGO},
+{ WWT_PANEL, RESIZE_NONE, 12, 493, 562, 80, 87, 0x0, STR_7064_TOGGLE_GRAPH_FOR_CARGO},
+{ WWT_PANEL, RESIZE_NONE, 12, 493, 562, 88, 95, 0x0, STR_7064_TOGGLE_GRAPH_FOR_CARGO},
+{ WWT_PANEL, RESIZE_NONE, 12, 493, 562, 96, 103, 0x0, STR_7064_TOGGLE_GRAPH_FOR_CARGO},
+{ WWT_PANEL, RESIZE_NONE, 12, 493, 562, 104, 111, 0x0, STR_7064_TOGGLE_GRAPH_FOR_CARGO},
+{ WWT_PANEL, RESIZE_NONE, 12, 493, 562, 112, 119, 0x0, STR_7064_TOGGLE_GRAPH_FOR_CARGO},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _cargo_payment_rates_desc = {
+ WDP_AUTO, WDP_AUTO, 568, 142,
+ WC_PAYMENT_RATES,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _cargo_payment_rates_widgets,
+ CargoPaymentRatesWndProc
+};
+
+
+void ShowCargoPaymentRates(void)
+{
+ AllocateWindowDescFront(&_cargo_payment_rates_desc, 0);
+}
+
+/************************/
+/* COMPANY LEAGUE TABLE */
+/************************/
+
+static const StringID _performance_titles[] = {
+ STR_7066_ENGINEER,
+ STR_7066_ENGINEER,
+ STR_7067_TRAFFIC_MANAGER,
+ STR_7067_TRAFFIC_MANAGER,
+ STR_7068_TRANSPORT_COORDINATOR,
+ STR_7068_TRANSPORT_COORDINATOR,
+ STR_7069_ROUTE_SUPERVISOR,
+ STR_7069_ROUTE_SUPERVISOR,
+ STR_706A_DIRECTOR,
+ STR_706A_DIRECTOR,
+ STR_706B_CHIEF_EXECUTIVE,
+ STR_706B_CHIEF_EXECUTIVE,
+ STR_706C_CHAIRMAN,
+ STR_706C_CHAIRMAN,
+ STR_706D_PRESIDENT,
+ STR_706E_TYCOON,
+};
+
+static inline StringID GetPerformanceTitleFromValue(uint value)
+{
+ return _performance_titles[minu(value, 1000) >> 6];
+}
+
+static int CDECL PerfHistComp(const void* elem1, const void* elem2)
+{
+ const Player* p1 = *(const Player* const*)elem1;
+ const Player* p2 = *(const Player* const*)elem2;
+
+ return p2->old_economy[1].performance_history - p1->old_economy[1].performance_history;
+}
+
+static void CompanyLeagueWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ const Player* plist[MAX_PLAYERS];
+ const Player* p;
+ uint pl_num;
+ uint i;
+
+ DrawWindowWidgets(w);
+
+ pl_num = 0;
+ FOR_ALL_PLAYERS(p) if (p->is_active) plist[pl_num++] = p;
+
+ qsort((void*)plist, pl_num, sizeof(*plist), PerfHistComp);
+
+ for (i = 0; i != pl_num; i++) {
+ p = plist[i];
+ SetDParam(0, i + STR_01AC_1ST);
+ SetDParam(1, p->name_1);
+ SetDParam(2, p->name_2);
+ SetDParam(3, GetPlayerNameString(p->index, 4));
+ SetDParam(5, GetPerformanceTitleFromValue(p->old_economy[1].performance_history));
+
+ DrawString(2, 15 + i * 10, i == 0 ? STR_7054 : STR_7055, 0);
+ DrawPlayerIcon(p->index, 27, 16 + i * 10);
+ }
+
+ break;
+ }
+ }
+}
+
+
+static const Widget _company_league_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 387, 0, 13, STR_7053_COMPANY_LEAGUE_TABLE, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_STICKYBOX, RESIZE_NONE, 14, 388, 399, 0, 13, STR_NULL, STR_STICKY_BUTTON},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 399, 14, 96, 0x0, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _company_league_desc = {
+ WDP_AUTO, WDP_AUTO, 400, 97,
+ WC_COMPANY_LEAGUE,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON,
+ _company_league_widgets,
+ CompanyLeagueWndProc
+};
+
+void ShowCompanyLeagueTable(void)
+{
+ AllocateWindowDescFront(&_company_league_desc,0);
+}
+
+/*****************************/
+/* PERFORMANCE RATING DETAIL */
+/*****************************/
+
+static void PerformanceRatingDetailWndProc(Window *w, WindowEvent *e)
+{
+ static PlayerID _performance_rating_detail_player = 0;
+
+ switch (e->event) {
+ case WE_PAINT: {
+ int i;
+ byte x;
+ uint16 y = 14;
+ int total_score = 0;
+ int color_done, color_notdone;
+
+ // Draw standard stuff
+ DrawWindowWidgets(w);
+
+ // Paint the player icons
+ for (i = 0; i < MAX_PLAYERS; i++) {
+ if (!GetPlayer(i)->is_active) {
+ // Check if we have the player as an active player
+ if (!IsWindowWidgetDisabled(w, i + 13)) {
+ // Bah, player gone :(
+ DisableWindowWidget(w, i + 13);
+ // Is this player selected? If so, select first player (always save? :s)
+ if (IsWindowWidgetLowered(w, i + 13)) {
+ RaiseWindowWidget(w, i + 13);
+ LowerWindowWidget(w, 13);
+ _performance_rating_detail_player = 0;
+ }
+ // We need a repaint
+ SetWindowDirty(w);
+ }
+ continue;
+ }
+
+ // Check if we have the player marked as inactive
+ if (IsWindowWidgetDisabled(w, i + 13)) {
+ // New player! Yippie :p
+ EnableWindowWidget(w, i + 13);
+ // We need a repaint
+ SetWindowDirty(w);
+ }
+
+ x = (i == _performance_rating_detail_player) ? 1 : 0;
+ DrawPlayerIcon(i, i * 37 + 13 + x, 16 + x);
+ }
+
+ // The colors used to show how the progress is going
+ color_done = _colour_gradient[COLOUR_GREEN][4];
+ color_notdone = _colour_gradient[COLOUR_RED][4];
+
+ // Draw all the score parts
+ for (i = 0; i < NUM_SCORE; i++) {
+ int val = _score_part[_performance_rating_detail_player][i];
+ int needed = _score_info[i].needed;
+ int score = _score_info[i].score;
+
+ y += 20;
+ // SCORE_TOTAL has his own rulez ;)
+ if (i == SCORE_TOTAL) {
+ needed = total_score;
+ score = SCORE_MAX;
+ } else {
+ total_score += score;
+ }
+
+ DrawString(7, y, STR_PERFORMANCE_DETAIL_VEHICLES + i, 0);
+
+ // Draw the score
+ SetDParam(0, score);
+ DrawStringRightAligned(107, y, SET_PERFORMANCE_DETAIL_INT, 0);
+
+ // Calculate the %-bar
+ if (val > needed) {
+ x = 50;
+ } else if (val == 0) {
+ x = 0;
+ } else {
+ x = val * 50 / needed;
+ }
+
+ // SCORE_LOAN is inversed
+ if (val < 0 && i == SCORE_LOAN) x = 0;
+
+ // Draw the bar
+ if (x != 0) GfxFillRect(112, y - 2, 112 + x, y + 10, color_done);
+ if (x != 50) GfxFillRect(112 + x, y - 2, 112 + 50, y + 10, color_notdone);
+
+ // Calculate the %
+ x = (val <= needed) ? val * 100 / needed : 100;
+
+ // SCORE_LOAN is inversed
+ if (val < 0 && i == SCORE_LOAN) x = 0;
+
+ // Draw it
+ SetDParam(0, x);
+ DrawStringCentered(137, y, STR_PERFORMANCE_DETAIL_PERCENT, 0);
+
+ // SCORE_LOAN is inversed
+ if (i == SCORE_LOAN) val = needed - val;
+
+ // Draw the amount we have against what is needed
+ // For some of them it is in currency format
+ SetDParam(0, val);
+ SetDParam(1, needed);
+ switch (i) {
+ case SCORE_MIN_PROFIT:
+ case SCORE_MIN_INCOME:
+ case SCORE_MAX_INCOME:
+ case SCORE_MONEY:
+ case SCORE_LOAN:
+ DrawString(167, y, STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY, 0);
+ break;
+ default:
+ DrawString(167, y, STR_PERFORMANCE_DETAIL_AMOUNT_INT, 0);
+ }
+ }
+
+ break;
+ }
+
+ case WE_CLICK:
+ // Check which button is clicked
+ if (IS_INT_INSIDE(e->we.click.widget, 13, 21)) {
+ // Is it no on disable?
+ if (!IsWindowWidgetDisabled(w, e->we.click.widget)) {
+ RaiseWindowWidget(w, _performance_rating_detail_player + 13);
+ _performance_rating_detail_player = e->we.click.widget - 13;
+ LowerWindowWidget(w, _performance_rating_detail_player + 13);
+ SetWindowDirty(w);
+ }
+ }
+ break;
+
+ case WE_CREATE: {
+ int i;
+ Player *p2;
+
+ /* Disable the players who are not active */
+ for (i = 0; i < MAX_PLAYERS; i++) {
+ SetWindowWidgetDisabledState(w, i + 13, !GetPlayer(i)->is_active);
+ }
+ /* Update all player stats with the current data
+ * (this is because _score_info is not saved to a savegame) */
+ FOR_ALL_PLAYERS(p2) {
+ if (p2->is_active) UpdateCompanyRatingAndValue(p2, false);
+ }
+
+ w->custom[0] = DAY_TICKS;
+ w->custom[1] = 5;
+
+ _performance_rating_detail_player = 0;
+ LowerWindowWidget(w, _performance_rating_detail_player + 13);
+ SetWindowDirty(w);
+
+ break;
+ }
+
+ case WE_TICK: {
+ // Update the player score every 5 days
+ if (--w->custom[0] == 0) {
+ w->custom[0] = DAY_TICKS;
+ if (--w->custom[1] == 0) {
+ Player *p2;
+
+ w->custom[1] = 5;
+ FOR_ALL_PLAYERS(p2) {
+ // Skip if player is not active
+ if (p2->is_active) UpdateCompanyRatingAndValue(p2, false);
+ }
+ SetWindowDirty(w);
+ }
+ }
+
+ break;
+ }
+ }
+}
+
+static const Widget _performance_rating_detail_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 298, 0, 13, STR_PERFORMANCE_DETAIL, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 298, 14, 27, 0x0, STR_NULL},
+
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 298, 28, 47, 0x0, STR_PERFORMANCE_DETAIL_VEHICLES_TIP},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 298, 48, 67, 0x0, STR_PERFORMANCE_DETAIL_STATIONS_TIP},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 298, 68, 87, 0x0, STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 298, 88, 107, 0x0, STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 298, 108, 127, 0x0, STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 298, 128, 147, 0x0, STR_PERFORMANCE_DETAIL_DELIVERED_TIP},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 298, 148, 167, 0x0, STR_PERFORMANCE_DETAIL_CARGO_TIP},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 298, 168, 187, 0x0, STR_PERFORMANCE_DETAIL_MONEY_TIP},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 298, 188, 207, 0x0, STR_PERFORMANCE_DETAIL_LOAN_TIP},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 298, 208, 227, 0x0, STR_PERFORMANCE_DETAIL_TOTAL_TIP},
+
+{ WWT_PANEL, RESIZE_NONE, 14, 2, 38, 14, 26, 0x0, STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
+{ WWT_PANEL, RESIZE_NONE, 14, 39, 75, 14, 26, 0x0, STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
+{ WWT_PANEL, RESIZE_NONE, 14, 76, 112, 14, 26, 0x0, STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
+{ WWT_PANEL, RESIZE_NONE, 14, 113, 149, 14, 26, 0x0, STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
+{ WWT_PANEL, RESIZE_NONE, 14, 150, 186, 14, 26, 0x0, STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
+{ WWT_PANEL, RESIZE_NONE, 14, 187, 223, 14, 26, 0x0, STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
+{ WWT_PANEL, RESIZE_NONE, 14, 224, 260, 14, 26, 0x0, STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
+{ WWT_PANEL, RESIZE_NONE, 14, 261, 297, 14, 26, 0x0, STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _performance_rating_detail_desc = {
+ WDP_AUTO, WDP_AUTO, 299, 228,
+ WC_PERFORMANCE_DETAIL,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _performance_rating_detail_widgets,
+ PerformanceRatingDetailWndProc
+};
+
+void ShowPerformanceRatingDetail(void)
+{
+ AllocateWindowDescFront(&_performance_rating_detail_desc, 0);
+}
+
+
+static const Sign **_sign_sort;
+static uint _num_sign_sort;
+
+static char _bufcache[64];
+static const Sign *_last_sign;
+
+static int CDECL SignNameSorter(const void *a, const void *b)
+{
+ const Sign *sign0 = *(const Sign**)a;
+ const Sign *sign1 = *(const Sign**)b;
+ char buf1[64];
+
+ GetString(buf1, sign0->str, lastof(buf1));
+
+ if (sign1 != _last_sign) {
+ _last_sign = sign1;
+ GetString(_bufcache, sign1->str, lastof(_bufcache));
+ }
+
+ return strcmp(buf1, _bufcache); // sort by name
+}
+
+static void GlobalSortSignList(void)
+{
+ const Sign *si;
+ uint n = 0;
+
+ /* Create array for sorting */
+ _sign_sort = realloc((void *)_sign_sort, (GetMaxSignIndex() + 1)* sizeof(_sign_sort[0]));
+ if (_sign_sort == NULL) error("Could not allocate memory for the sign-sorting-list");
+
+ FOR_ALL_SIGNS(si) _sign_sort[n++] = si;
+ _num_sign_sort = n;
+
+ qsort((void*)_sign_sort, n, sizeof(_sign_sort[0]), SignNameSorter);
+
+ _sign_sort_dirty = false;
+
+ DEBUG(misc, 3, "Resorting global signs list");
+}
+
+static void SignListWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ int y = 16; // offset from top of widget
+
+ if (_sign_sort_dirty)
+ GlobalSortSignList();
+
+ SetVScrollCount(w, _num_sign_sort);
+
+ SetDParam(0, w->vscroll.count);
+ DrawWindowWidgets(w);
+
+ /* No signs? */
+ if (w->vscroll.count == 0) {
+ DrawString(2, y, STR_304A_NONE, 0);
+ return;
+ }
+
+ {
+ uint16 i;
+
+ /* Start drawing the signs */
+ for (i = w->vscroll.pos; i < w->vscroll.cap + w->vscroll.pos && i < w->vscroll.count; i++) {
+ const Sign *si = _sign_sort[i];
+
+ if (si->owner != OWNER_NONE)
+ DrawPlayerIcon(si->owner, 4, y + 1);
+
+ DrawString(22, y, si->str, 8);
+ y += 10;
+ }
+ }
+ } break;
+
+ case WE_CLICK: {
+ switch (e->we.click.widget) {
+ case 3: {
+ uint32 id_v = (e->we.click.pt.y - 15) / 10;
+ const Sign *si;
+
+ if (id_v >= w->vscroll.cap)
+ return;
+
+ id_v += w->vscroll.pos;
+
+ if (id_v >= w->vscroll.count)
+ return;
+
+ si = _sign_sort[id_v];
+ ScrollMainWindowToTile(TileVirtXY(si->x, si->y));
+ } break;
+ }
+ } break;
+
+ case WE_RESIZE:
+ w->vscroll.cap += e->we.sizing.diff.y / 10;
+ break;
+ }
+}
+
+static const Widget _sign_list_widget[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_RIGHT, 14, 11, 345, 0, 13, STR_SIGN_LIST_CAPTION, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_STICKYBOX, RESIZE_LR, 14, 346, 357, 0, 13, 0x0, STR_STICKY_BUTTON},
+{ WWT_PANEL, RESIZE_RB, 14, 0, 345, 14, 137, 0x0, STR_NULL},
+{ WWT_SCROLLBAR, RESIZE_LRB, 14, 346, 357, 14, 125, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WWT_RESIZEBOX, RESIZE_LRTB, 14, 346, 357, 126, 137, 0x0, STR_RESIZE_BUTTON},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _sign_list_desc = {
+ WDP_AUTO, WDP_AUTO, 358, 138,
+ WC_SIGN_LIST,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON | WDF_RESIZABLE,
+ _sign_list_widget,
+ SignListWndProc
+};
+
+
+void ShowSignList(void)
+{
+ Window *w;
+
+ w = AllocateWindowDescFront(&_sign_list_desc, 0);
+ if (w != NULL) {
+ w->vscroll.cap = 12;
+ w->resize.step_height = 10;
+ w->resize.height = w->height - 10 * 7; // minimum if 5 in the list
+ }
+}
diff --git a/src/gui.h b/src/gui.h
new file mode 100644
index 000000000..8ca055f43
--- /dev/null
+++ b/src/gui.h
@@ -0,0 +1,141 @@
+/* $Id$ */
+
+#ifndef GUI_H
+#define GUI_H
+
+#include "station.h"
+#include "window.h"
+#include "string.h"
+
+/* main_gui.c */
+void SetupColorsAndInitialWindow(void);
+void CcPlaySound10(bool success, TileIndex tile, uint32 p1, uint32 p2);
+void CcBuildCanal(bool success, TileIndex tile, uint32 p1, uint32 p2);
+void CcTerraform(bool success, TileIndex tile, uint32 p1, uint32 p2);
+
+/* settings_gui.c */
+void ShowGameOptions(void);
+void ShowGameDifficulty(void);
+void ShowPatchesSelection(void);
+void DrawArrowButtons(int x, int y, int ctab, byte state, bool clickable_left, bool clickable_right);
+
+/* graph_gui.c */
+extern const byte _cargo_colours[NUM_CARGO];
+void ShowOperatingProfitGraph(void);
+void ShowIncomeGraph(void);
+void ShowDeliveredCargoGraph(void);
+void ShowPerformanceHistoryGraph(void);
+void ShowCompanyValueGraph(void);
+void ShowCargoPaymentRates(void);
+void ShowCompanyLeagueTable(void);
+void ShowPerformanceRatingDetail(void);
+
+/* news_gui.c */
+void ShowLastNewsMessage(void);
+void ShowMessageOptions(void);
+void ShowMessageHistory(void);
+
+/* rail_gui.c */
+void ShowBuildRailToolbar(RailType railtype, int button);
+void PlaceProc_BuyLand(TileIndex tile);
+void ReinitGuiAfterToggleElrail(bool disable);
+
+/* train_gui.c */
+void ShowTrainViewWindow(const Vehicle *v);
+void ShowOrdersWindow(const Vehicle *v);
+
+/* road_gui.c */
+void ShowBuildRoadToolbar(void);
+void ShowBuildRoadScenToolbar(void);
+void ShowRoadVehViewWindow(const Vehicle *v);
+
+/* dock_gui.c */
+void ShowBuildDocksToolbar(void);
+void ShowShipViewWindow(const Vehicle *v);
+
+/* aircraft_gui.c */
+void ShowBuildAirToolbar(void);
+
+/* terraform_gui.c */
+void ShowTerraformToolbar(void);
+
+/* tgp_gui.c */
+void ShowGenerateLandscape(void);
+void ShowHeightmapLoad(void);
+
+void PlaceProc_DemolishArea(TileIndex tile);
+void PlaceProc_LevelLand(TileIndex tile);
+bool GUIPlaceProcDragXY(const WindowEvent *e);
+
+enum { // max 32 - 4 = 28 types
+ GUI_PlaceProc_DemolishArea = 0 << 4,
+ GUI_PlaceProc_LevelArea = 1 << 4,
+ GUI_PlaceProc_DesertArea = 2 << 4,
+ GUI_PlaceProc_WaterArea = 3 << 4,
+ GUI_PlaceProc_ConvertRailArea = 4 << 4,
+ GUI_PlaceProc_RockyArea = 5 << 4,
+};
+
+/* misc_gui.c */
+void PlaceLandBlockInfo(void);
+void ShowAboutWindow(void);
+void ShowBuildTreesToolbar(void);
+void ShowBuildTreesScenToolbar(void);
+void ShowTownDirectory(void);
+void ShowIndustryDirectory(void);
+void ShowSubsidiesList(void);
+void ShowPlayerStations(PlayerID player);
+void ShowPlayerFinances(PlayerID player);
+void ShowPlayerCompany(PlayerID player);
+void ShowSignList(void);
+
+void ShowEstimatedCostOrIncome(int32 cost, int x, int y);
+void ShowErrorMessage(StringID msg_1, StringID msg_2, int x, int y);
+
+void DrawStationCoverageAreaText(int sx, int sy, uint mask,int rad);
+void CheckRedrawStationCoverage(const Window *w);
+
+void ShowSmallMap(void);
+void ShowExtraViewPortWindow(void);
+void SetVScrollCount(Window *w, int num);
+void SetVScroll2Count(Window *w, int num);
+void SetHScrollCount(Window *w, int num);
+
+void ShowCheatWindow(void);
+
+void DrawEditBox(Window *w, querystr_d *string, int wid);
+void HandleEditBox(Window *w, querystr_d *string, int wid);
+int HandleEditBoxKey(Window *w, querystr_d *string, int wid, WindowEvent *we);
+bool HandleCaret(Textbuf *tb);
+
+void DeleteTextBufferAll(Textbuf *tb);
+bool DeleteTextBufferChar(Textbuf *tb, int delmode);
+bool InsertTextBufferChar(Textbuf *tb, uint32 key);
+bool InsertTextBufferClipboard(Textbuf *tb);
+bool MoveTextBufferPos(Textbuf *tb, int navmode);
+void InitializeTextBuffer(Textbuf *tb, const char *buf, uint16 maxlength, uint16 maxwidth);
+void UpdateTextBufferSize(Textbuf *tb);
+
+void BuildFileList(void);
+void SetFiosType(const byte fiostype);
+
+/* FIOS_TYPE_FILE, FIOS_TYPE_OLDFILE etc. different colours */
+extern const byte _fios_colors[];
+
+/* bridge_gui.c */
+void ShowBuildBridgeWindow(uint start, uint end, byte type);
+
+void ShowBuildIndustryWindow(void);
+void ShowQueryString(StringID str, StringID caption, uint maxlen, uint maxwidth, Window *parent, CharSetFilter afilter);
+void ShowQuery(StringID caption, StringID message, Window *w, void (*callback)(Window*, bool));
+void ShowMusicWindow(void);
+
+/* main_gui.c */
+void HandleOnEditText(const char *str);
+VARDEF byte _station_show_coverage;
+VARDEF PlaceProc *_place_proc;
+
+/* vehicle_gui.c */
+void InitializeGUI(void);
+
+#endif /* GUI_H */
diff --git a/src/hal.h b/src/hal.h
new file mode 100644
index 000000000..1b239162b
--- /dev/null
+++ b/src/hal.h
@@ -0,0 +1,49 @@
+/* $Id$ */
+
+#ifndef HAL_H
+#define HAL_H
+
+typedef struct {
+ const char *(*start)(const char * const *parm);
+ void (*stop)(void);
+} HalCommonDriver;
+
+typedef struct {
+ const char *(*start)(const char * const *parm);
+ void (*stop)(void);
+ void (*make_dirty)(int left, int top, int width, int height);
+ void (*main_loop)(void);
+ bool (*change_resolution)(int w, int h);
+ void (*toggle_fullscreen)(bool fullscreen);
+} HalVideoDriver;
+
+typedef struct {
+ const char *(*start)(const char * const *parm);
+ void (*stop)(void);
+} HalSoundDriver;
+
+typedef struct {
+ const char *(*start)(const char * const *parm);
+ void (*stop)(void);
+
+ void (*play_song)(const char *filename);
+ void (*stop_song)(void);
+ bool (*is_song_playing)(void);
+ void (*set_volume)(byte vol);
+} HalMusicDriver;
+
+VARDEF HalMusicDriver *_music_driver;
+VARDEF HalSoundDriver *_sound_driver;
+VARDEF HalVideoDriver *_video_driver;
+
+enum DriverType {
+ VIDEO_DRIVER = 0,
+ SOUND_DRIVER = 1,
+ MUSIC_DRIVER = 2,
+};
+
+void GameLoop(void);
+
+void CreateConsole(void);
+
+#endif /* HAL_H */
diff --git a/src/heightmap.c b/src/heightmap.c
new file mode 100644
index 000000000..aeaa5c38e
--- /dev/null
+++ b/src/heightmap.c
@@ -0,0 +1,459 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "variables.h"
+#include "functions.h"
+#include "heightmap.h"
+#include "clear_map.h"
+#include "table/strings.h"
+#include "void_map.h"
+#include "debug.h"
+#include "gfx.h"
+#include "gui.h"
+#include "saveload.h"
+#include "bmp.h"
+
+/**
+ * Convert RGB colors to Grayscale using 29.9% Red, 58.7% Green, 11.4% Blue
+ * (average luminosity formula) -- Dalestan
+ * This in fact is the NTSC Color Space -- TrueLight
+ */
+static inline byte RGBToGrayscale(byte red, byte green, byte blue)
+{
+ /* To avoid doubles and stuff, multiple it with a total of 65536 (16bits), then
+ * divide by it to normalize the value to a byte again. */
+ return ((red * 19595) + (green * 38470) + (blue * 7471)) / 65536;
+}
+
+
+#ifdef WITH_PNG
+
+#include "png.h"
+
+/**
+ * The PNG Heightmap loader.
+ */
+static void ReadHeightmapPNGImageData(byte *map, png_structp png_ptr, png_infop info_ptr)
+{
+ uint x, y;
+ byte gray_palette[256];
+ png_bytep *row_pointers = NULL;
+
+ /* Get palette and convert it to grayscale */
+ if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) {
+ int i;
+ int palette_size;
+ png_color *palette;
+ bool all_gray = true;
+
+ png_get_PLTE(png_ptr, info_ptr, &palette, &palette_size);
+ for (i = 0; i < palette_size && (palette_size != 16 || all_gray); i++) {
+ all_gray &= palette[i].red == palette[i].green && palette[i].red == palette[i].blue;
+ gray_palette[i] = RGBToGrayscale(palette[i].red, palette[i].green, palette[i].blue);
+ }
+
+ /**
+ * For a non-gray palette of size 16 we assume that
+ * the order of the palette determines the height;
+ * the first entry is the sea (level 0), the second one
+ * level 1, etc.
+ */
+ if (palette_size == 16 && !all_gray) {
+ for (i = 0; i < palette_size; i++) {
+ gray_palette[i] = 256 * i / palette_size;
+ }
+ }
+ }
+
+ row_pointers = png_get_rows(png_ptr, info_ptr);
+
+ /* Read the raw image data and convert in 8-bit grayscale */
+ for (x = 0; x < info_ptr->width; x++) {
+ for (y = 0; y < info_ptr->height; y++) {
+ byte *pixel = &map[y * info_ptr->width + x];
+ uint x_offset = x * info_ptr->channels;
+
+ if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) {
+ *pixel = gray_palette[row_pointers[y][x_offset]];
+ } else if (info_ptr->channels == 3) {
+ *pixel = RGBToGrayscale(row_pointers[y][x_offset + 0],
+ row_pointers[y][x_offset + 1], row_pointers[y][x_offset + 2]);
+ } else {
+ *pixel = row_pointers[y][x_offset];
+ }
+ }
+ }
+}
+
+/**
+ * Reads the heightmap and/or size of the heightmap from a PNG file.
+ * If map == NULL only the size of the PNG is read, otherwise a map
+ * with grayscale pixels is allocated and assigned to *map.
+ */
+static bool ReadHeightmapPNG(char *filename, uint *x, uint *y, byte **map)
+{
+ FILE *fp;
+ png_structp png_ptr = NULL;
+ png_infop info_ptr = NULL;
+
+ fp = fopen(filename, "rb");
+ if (fp == NULL) {
+ ShowErrorMessage(STR_PNGMAP_ERR_FILE_NOT_FOUND, STR_PNGMAP_ERROR, 0, 0);
+ return false;
+ }
+
+ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (png_ptr == NULL) {
+ ShowErrorMessage(STR_PNGMAP_ERR_MISC, STR_PNGMAP_ERROR, 0, 0);
+ fclose(fp);
+ return false;
+ }
+
+ info_ptr = png_create_info_struct(png_ptr);
+ if (info_ptr == NULL || setjmp(png_jmpbuf(png_ptr))) {
+ ShowErrorMessage(STR_PNGMAP_ERR_MISC, STR_PNGMAP_ERROR, 0, 0);
+ fclose(fp);
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+ return false;
+ }
+
+ png_init_io(png_ptr, fp);
+
+ /* Allocate memory and read image, without alpha or 16-bit samples
+ * (result is either 8-bit indexed/grayscale or 24-bit RGB) */
+ png_set_packing(png_ptr);
+ png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_PACKING | PNG_TRANSFORM_STRIP_ALPHA | PNG_TRANSFORM_STRIP_16, NULL);
+
+ /* Maps of wrong color-depth are not used.
+ * (this should have been taken care of by stripping alpha and 16-bit samples on load) */
+ if ((info_ptr->channels != 1) && (info_ptr->channels != 3) && (info_ptr->bit_depth != 8)) {
+ ShowErrorMessage(STR_PNGMAP_ERR_IMAGE_TYPE, STR_PNGMAP_ERROR, 0, 0);
+ fclose(fp);
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+ return false;
+ }
+
+ if (map != NULL) {
+ *map = malloc(info_ptr->width * info_ptr->height * sizeof(byte));
+
+ if (*map == NULL) {
+ ShowErrorMessage(STR_PNGMAP_ERR_MISC, STR_PNGMAP_ERROR, 0, 0);
+ fclose(fp);
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+ return false;
+ }
+
+ ReadHeightmapPNGImageData(*map, png_ptr, info_ptr);
+ }
+
+ *x = info_ptr->width;
+ *y = info_ptr->height;
+
+ fclose(fp);
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+ return true;
+}
+
+#endif /* WITH_PNG */
+
+
+/**
+ * The BMP Heightmap loader.
+ */
+static void ReadHeightmapBMPImageData(byte *map, BmpInfo *info, BmpData *data)
+{
+ uint x, y;
+ byte gray_palette[256];
+
+ if (data->palette != NULL) {
+ uint i;
+ bool all_gray = true;
+
+ if (info->palette_size != 2) {
+ for (i = 0; i < info->palette_size && (info->palette_size != 16 || all_gray); i++) {
+ all_gray &= data->palette[i].r == data->palette[i].g && data->palette[i].r == data->palette[i].b;
+ gray_palette[i] = RGBToGrayscale(data->palette[i].r, data->palette[i].g, data->palette[i].b);
+ }
+
+ /**
+ * For a non-gray palette of size 16 we assume that
+ * the order of the palette determines the height;
+ * the first entry is the sea (level 0), the second one
+ * level 1, etc.
+ */
+ if (info->palette_size == 16 && !all_gray) {
+ for (i = 0; i < info->palette_size; i++) {
+ gray_palette[i] = 256 * i / info->palette_size;
+ }
+ }
+ } else {
+ /**
+ * For a palette of size 2 we assume that the order of the palette determines the height;
+ * the first entry is the sea (level 0), the second one is the land (level 1)
+ */
+ gray_palette[0] = 0;
+ gray_palette[1] = 16;
+ }
+ }
+
+ /* Read the raw image data and convert in 8-bit grayscale */
+ for (y = 0; y < info->height; y++) {
+ byte *pixel = &map[y * info->width];
+ byte *bitmap = &data->bitmap[y * info->width * (info->bpp == 24 ? 3 : 1)];
+
+ for (x = 0; x < info->width; x++) {
+ if (info->bpp != 24) {
+ *pixel++ = gray_palette[*bitmap++];
+ } else {
+ *pixel++ = RGBToGrayscale(*bitmap, *(bitmap + 1), *(bitmap + 2));
+ bitmap += 3;
+ }
+ }
+ }
+}
+
+/**
+ * Reads the heightmap and/or size of the heightmap from a BMP file.
+ * If map == NULL only the size of the BMP is read, otherwise a map
+ * with grayscale pixels is allocated and assigned to *map.
+ */
+static bool ReadHeightmapBMP(char *filename, uint *x, uint *y, byte **map)
+{
+ FILE *f;
+ BmpInfo info;
+ BmpData data;
+ BmpBuffer buffer;
+
+ f = fopen(filename, "rb");
+ if (f == NULL) {
+ ShowErrorMessage(STR_PNGMAP_ERR_FILE_NOT_FOUND, STR_BMPMAP_ERROR, 0, 0);
+ return false;
+ }
+
+ BmpInitializeBuffer(&buffer, f);
+
+ if (!BmpReadHeader(&buffer, &info, &data)) {
+ ShowErrorMessage(STR_BMPMAP_ERR_IMAGE_TYPE, STR_BMPMAP_ERROR, 0, 0);
+ fclose(f);
+ BmpDestroyData(&data);
+ return false;
+ }
+
+ if (map != NULL) {
+ if (!BmpReadBitmap(&buffer, &info, &data)) {
+ ShowErrorMessage(STR_BMPMAP_ERR_IMAGE_TYPE, STR_BMPMAP_ERROR, 0, 0);
+ fclose(f);
+ BmpDestroyData(&data);
+ return false;
+ }
+
+ *map = malloc(info.width * info.height * sizeof(byte));
+ if (*map == NULL) {
+ ShowErrorMessage(STR_PNGMAP_ERR_MISC, STR_BMPMAP_ERROR, 0, 0);
+ fclose(f);
+ BmpDestroyData(&data);
+ return false;
+ }
+
+ ReadHeightmapBMPImageData(*map, &info, &data);
+
+ }
+
+ BmpDestroyData(&data);
+
+ *x = info.width;
+ *y = info.height;
+
+ fclose(f);
+ return true;
+}
+
+static void GrayscaleToMapHeights(uint img_width, uint img_height, byte *map)
+{
+ /* Defines the detail of the aspect ratio (to avoid doubles) */
+ const uint num_div = 16384;
+
+ uint width, height;
+ uint row, col;
+ uint row_pad = 0, col_pad = 0;
+ uint img_scale;
+ uint img_row, img_col;
+ TileIndex tile;
+
+ /* Get map size and calculate scale and padding values */
+ switch (_patches.heightmap_rotation) {
+ case HM_COUNTER_CLOCKWISE:
+ width = MapSizeX();
+ height = MapSizeY();
+ break;
+ case HM_CLOCKWISE:
+ width = MapSizeY();
+ height = MapSizeX();
+ break;
+ default:
+ NOT_REACHED();
+ /* Avoids compiler warnings */
+ return;
+ }
+
+ if ((img_width * num_div) / img_height > ((width * num_div) / height)) {
+ /* Image is wider than map - center vertically */
+ img_scale = (width * num_div) / img_width;
+ row_pad = (height - ((img_height * img_scale) / num_div)) / 2;
+ } else {
+ /* Image is taller than map - center horizontally */
+ img_scale = (height * num_div) / img_height;
+ col_pad = (width - ((img_width * img_scale) / num_div)) / 2;
+ }
+
+ /* Form the landscape */
+ for (row = 0; row < height - 1; row++) {
+ for (col = 0; col < width - 1; col++) {
+ switch (_patches.heightmap_rotation) {
+ case HM_COUNTER_CLOCKWISE: tile = TileXY(col, row); break;
+ case HM_CLOCKWISE: tile = TileXY(row, col); break;
+ default: NOT_REACHED(); return;
+ }
+
+ /* Check if current tile is within the 1-pixel map edge or padding regions */
+ if ((DistanceFromEdge(tile) <= 1) ||
+ (row < row_pad) || (row >= (img_height + row_pad)) ||
+ (col < col_pad) || (col >= (img_width + col_pad))) {
+ SetTileHeight(tile, 0);
+ } else {
+ /* Use nearest neighbor resizing to scale map data.
+ * We rotate the map 45 degrees (counter)clockwise */
+ img_row = (((row - row_pad) * num_div) / img_scale);
+ switch (_patches.heightmap_rotation) {
+ case HM_COUNTER_CLOCKWISE:
+ img_col = (((width - 1 - col - col_pad) * num_div) / img_scale);
+ break;
+ case HM_CLOCKWISE:
+ img_col = (((col - col_pad) * num_div) / img_scale);
+ break;
+ default:
+ NOT_REACHED();
+ /* Avoids compiler warnings */
+ return;
+ }
+
+ assert(img_row < img_height);
+ assert(img_col < img_width);
+
+ /* Color scales from 0 to 255, OpenTTD height scales from 0 to 15 */
+ SetTileHeight(tile, map[img_row * img_width + img_col] / 16);
+ }
+ MakeClear(tile, CLEAR_GRASS, 3);
+ }
+ }
+}
+
+/**
+ * This function takes care of the fact that land in OpenTTD can never differ
+ * more than 1 in height
+ */
+static void FixSlopes(void)
+{
+ uint width, height;
+ uint row, col;
+ byte current_tile;
+
+ /* Adjust height difference to maximum one horizontal/vertical change. */
+ width = MapSizeX();
+ height = MapSizeY();
+
+ /* Top and left edge */
+ for (row = 1; row < height - 2; row++) {
+ for (col = 1; col < width - 2; col++) {
+ /* Find lowest tile; either the top or left one */
+ current_tile = TileHeight(TileXY(col - 1, row)); // top edge
+ if (TileHeight(TileXY(col, row - 1)) < current_tile) {
+ current_tile = TileHeight(TileXY(col, row - 1)); // left edge
+ }
+
+ /* Does the height differ more than one? */
+ if (TileHeight(TileXY(col, row)) >= (uint)current_tile + 2) {
+ /* Then change the height to be no more than one */
+ SetTileHeight(TileXY(col, row), current_tile + 1);
+ }
+ }
+ }
+
+ /* Bottom and right edge */
+ for (row = height - 2; row > 0; row--) {
+ for (col = width - 2; col > 0; col--) {
+ /* Find lowest tile; either the bottom and right one */
+ current_tile = TileHeight(TileXY(col + 1, row)); // bottom edge
+ if (TileHeight(TileXY(col, row + 1)) < current_tile) {
+ current_tile = TileHeight(TileXY(col, row + 1)); // right edge
+ }
+
+ /* Does the height differ more than one? */
+ if (TileHeight(TileXY(col, row)) >= (uint)current_tile + 2) {
+ /* Then change the height to be no more than one */
+ SetTileHeight(TileXY(col, row), current_tile + 1);
+ }
+ }
+ }
+}
+
+/**
+ * Reads the heightmap with the correct file reader
+ */
+static bool ReadHeightMap(char *filename, uint *x, uint *y, byte **map)
+{
+ switch (_file_to_saveload.mode) {
+#ifdef WITH_PNG
+ case SL_PNG:
+ return ReadHeightmapPNG(filename, x, y, map);
+#endif /* WITH_PNG */
+ case SL_BMP:
+ return ReadHeightmapBMP(filename, x, y, map);
+
+ default:
+ NOT_REACHED();
+ /* Avoids compiler warnings */
+ return false;
+ }
+}
+
+bool GetHeightmapDimensions(char *filename, uint *x, uint *y)
+{
+ return ReadHeightMap(filename, x, y, NULL);
+}
+
+void LoadHeightmap(char *filename)
+{
+ uint x, y;
+ byte *map = NULL;
+
+ if (!ReadHeightMap(filename, &x, &y, &map)) {
+ free(map);
+ return;
+ }
+
+ GrayscaleToMapHeights(x, y, map);
+ free(map);
+
+ FixSlopes();
+ MarkWholeScreenDirty();
+}
+
+void FlatEmptyWorld(byte tile_height)
+{
+ uint width, height;
+ uint row, col;
+
+ width = MapSizeX();
+ height = MapSizeY();
+
+ for (row = 2; row < height - 2; row++) {
+ for (col = 2; col < width - 2; col++) {
+ SetTileHeight(TileXY(col, row), tile_height);
+ }
+ }
+
+ FixSlopes();
+ MarkWholeScreenDirty();
+}
diff --git a/src/heightmap.h b/src/heightmap.h
new file mode 100644
index 000000000..d7592bf27
--- /dev/null
+++ b/src/heightmap.h
@@ -0,0 +1,33 @@
+/* $Id$ */
+
+#ifndef HEIGHTMAP_H
+#define HEIGHTMAP_H
+
+/*
+ * Order of these enums has to be the same as in lang/english.txt
+ * Otherwise you will get inconsistent behaviour.
+ */
+enum {
+ HM_COUNTER_CLOCKWISE, //! Rotate the map counter clockwise 45 degrees
+ HM_CLOCKWISE, //! Rotate the map clockwise 45 degrees
+};
+
+/**
+ * Get the dimensions of a heightmap.
+ * @return Returns false if loading of the image failed.
+ */
+bool GetHeightmapDimensions(char *filename, uint *x, uint *y);
+
+/**
+ * Load a heightmap from file and change the map in his current dimensions
+ * to a landscape representing the heightmap.
+ * It converts pixels to height. The brighter, the higher.
+ */
+void LoadHeightmap(char *filename);
+
+/**
+ * Make an empty world where all tiles are of height 'tile_height'.
+ */
+void FlatEmptyWorld(byte tile_height);
+
+#endif /* HEIGHTMAP_H */
diff --git a/src/helpers.cpp b/src/helpers.cpp
new file mode 100644
index 000000000..b78df5de8
--- /dev/null
+++ b/src/helpers.cpp
@@ -0,0 +1,70 @@
+/* $Id$ */
+#include "stdafx.h"
+
+EXTERN_C_BEGIN
+#include "openttd.h"
+#include "engine.h"
+EXTERN_C_END
+
+#include <new>
+#include "yapf/blob.hpp"
+
+/* Engine list manipulators - current implementation is only C wrapper around CBlobT<EngineID> (see yapf/blob.hpp) */
+
+/* we cannot expose CBlobT directly to C so we must cast EngineList* to CBlobT<EngineID>* always when we are called from C */
+#define B (*(CBlobT<EngineID>*)el)
+
+/** Create Engine List (and initialize it to empty) */
+void EngList_Create(EngineList *el)
+{
+ // call CBlobT constructor explicitly
+ new (&B) CBlobT<EngineID>();
+}
+
+/** Destroy Engine List (and free its contents) */
+void EngList_Destroy(EngineList *el)
+{
+ // call CBlobT destructor explicitly
+ B.~CBlobT<EngineID>();
+}
+
+/** Return number of items stored in the Engine List */
+uint EngList_Count(const EngineList *el)
+{
+ return B.Size();
+}
+
+/** Add new item at the end of Engine List */
+void EngList_Add(EngineList *el, EngineID eid)
+{
+ B.Append(eid);
+}
+
+/** Return pointer to the items array held by Engine List */
+EngineID* EngList_Items(EngineList *el)
+{
+ return B.Data();
+}
+
+/** Clear the Engine List (by invalidating all its items == reseting item count to zero) */
+void EngList_RemoveAll(EngineList *el)
+{
+ B.Clear();
+}
+
+/** Sort all items using qsort() and given 'CompareItems' function */
+void EngList_Sort(EngineList *el, EngList_SortTypeFunction compare)
+{
+ qsort(B.Data(), B.Size(), sizeof(**el), compare);
+}
+
+/** Sort selected range of items (on indices @ <begin, begin+num_items-1>) */
+void EngList_SortPartial(EngineList *el, EngList_SortTypeFunction compare, uint begin, uint num_items)
+{
+ assert(begin <= (uint)B.Size());
+ assert(begin + num_items <= (uint)B.Size());
+ qsort(B.Data() + begin, num_items, sizeof(**el), compare);
+}
+
+#undef B
+
diff --git a/src/industry.h b/src/industry.h
new file mode 100644
index 000000000..f8cf63c82
--- /dev/null
+++ b/src/industry.h
@@ -0,0 +1,199 @@
+/* $Id$ */
+
+#ifndef INDUSTRY_H
+#define INDUSTRY_H
+
+#include "oldpool.h"
+
+typedef byte IndustryGfx;
+typedef uint8 IndustryType;
+
+enum {
+ INVALID_INDUSTRY = 0xFFFF,
+};
+
+typedef enum IndustryLifeTypes {
+ INDUSTRYLIFE_NOT_CLOSABLE, ///< Industry can never close
+ INDUSTRYLIFE_PRODUCTION, ///< Industry can close and change of production
+ INDUSTRYLIFE_CLOSABLE, ///< Industry can only close (no production change)
+} IndustryLifeType;
+
+struct Industry {
+ TileIndex xy;
+ byte width; /* swapped order of w/h with town */
+ byte height;
+ const Town* town;
+ CargoID produced_cargo[2];
+ uint16 cargo_waiting[2];
+ byte production_rate[2];
+ CargoID accepts_cargo[3];
+ byte prod_level;
+ uint16 last_mo_production[2];
+ uint16 last_mo_transported[2];
+ byte pct_transported[2];
+ uint16 total_production[2];
+ uint16 total_transported[2];
+ uint16 counter;
+
+ byte type;
+ byte owner;
+ byte random_color;
+ Year last_prod_year;
+ byte was_cargo_delivered;
+
+ IndustryID index;
+};
+
+typedef struct IndustryTileTable {
+ TileIndexDiffC ti;
+ IndustryGfx gfx;
+} IndustryTileTable;
+
+typedef struct IndustrySpec {
+ /** Tables with the 'layout' of different composition of GFXes */
+ const IndustryTileTable *const *table;
+ /** Number of elements in the table */
+ byte num_table;
+ /** Base cost multiplier*/
+ byte cost_multiplier;
+ /** Industries this industry cannot be close to */
+ IndustryType conflicting[3];
+ /** index to a procedure to check for conflicting circumstances */
+ byte check_proc;
+
+ CargoID produced_cargo[2];
+ byte production_rate[2];
+ /** The minimum amount of cargo transported to the stations; if the
+ * waiting cargo is less than this number, no cargo is moved to it*/
+ byte minimal_cargo;
+ CargoID accepts_cargo[3];
+
+ IndustryLifeType life_type; ///< This is also known as Industry production flag, in newgrf specs
+
+ byte climate_availability; ///< Bitmask, giving landscape enums as bit position
+
+ StringID name;
+ StringID closure_text;
+ StringID production_up_text;
+ StringID production_down_text;
+} IndustrySpec;
+
+const IndustrySpec *GetIndustrySpec(IndustryType thistype);
+
+DECLARE_OLD_POOL(Industry, Industry, 3, 8000)
+
+/**
+ * Check if an Industry really exists.
+ */
+static inline bool IsValidIndustry(const Industry *industry)
+{
+ return industry->xy != 0;
+}
+
+static inline bool IsValidIndustryID(IndustryID index)
+{
+ return index < GetIndustryPoolSize() && IsValidIndustry(GetIndustry(index));
+}
+
+VARDEF int _total_industries;
+
+static inline IndustryID GetMaxIndustryIndex(void)
+{
+ /* TODO - This isn't the real content of the function, but
+ * with the new pool-system this will be replaced with one that
+ * _really_ returns the highest index. Now it just returns
+ * the next safe value we are sure about everything is below.
+ */
+ return GetIndustryPoolSize() - 1;
+}
+
+static inline uint GetNumIndustries(void)
+{
+ return _total_industries;
+}
+
+/**
+ * Return a random valid industry.
+ */
+static inline Industry *GetRandomIndustry(void)
+{
+ int num = RandomRange(GetNumIndustries());
+ IndustryID index = INVALID_INDUSTRY;
+
+ if (GetNumIndustries() == 0) return NULL;
+
+ while (num >= 0) {
+ num--;
+ index++;
+
+ /* Make sure we have a valid industry */
+ while (!IsValidIndustryID(index)) {
+ index++;
+ assert(index <= GetMaxIndustryIndex());
+ }
+ }
+
+ return GetIndustry(index);
+}
+
+void DestroyIndustry(Industry *i);
+
+static inline void DeleteIndustry(Industry *i)
+{
+ DestroyIndustry(i);
+ i->xy = 0;
+}
+
+#define FOR_ALL_INDUSTRIES_FROM(i, start) for (i = GetIndustry(start); i != NULL; i = (i->index + 1U < GetIndustryPoolSize()) ? GetIndustry(i->index + 1U) : NULL) if (IsValidIndustry(i))
+#define FOR_ALL_INDUSTRIES(i) FOR_ALL_INDUSTRIES_FROM(i, 0)
+
+VARDEF const Industry** _industry_sort;
+VARDEF bool _industry_sort_dirty;
+
+
+void DeleteIndustry(Industry *is);
+void PlantRandomFarmField(const Industry *i);
+
+enum {
+ IT_COAL_MINE = 0,
+ IT_POWER_STATION = 1,
+ IT_SAWMILL = 2,
+ IT_FOREST = 3,
+ IT_OIL_REFINERY = 4,
+ IT_OIL_RIG = 5,
+ IT_FACTORY = 6,
+ IT_PRINTING_WORKS = 7,
+ IT_STEEL_MILL = 8,
+ IT_FARM = 9,
+ IT_COPPER_MINE = 10,
+ IT_OIL_WELL = 11,
+ IT_BANK_TEMP = 12,
+ IT_FOOD_PROCESS = 13,
+ IT_PAPER_MILL = 14,
+ IT_GOLD_MINE = 15,
+ IT_BANK_TROPIC_ARCTIC = 16,
+ IT_DIAMOND_MINE = 17,
+ IT_IRON_MINE = 18,
+ IT_FRUIT_PLANTATION = 19,
+ IT_RUBBER_PLANTATION = 20,
+ IT_WATER_SUPPLY = 21,
+ IT_WATER_TOWER = 22,
+ IT_FACTORY_2 = 23,
+ IT_FARM_2 = 24,
+ IT_LUMBER_MILL = 25,
+ IT_COTTON_CANDY = 26,
+ IT_CANDY_FACTORY = 27,
+ IT_BATTERY_FARM = 28,
+ IT_COLA_WELLS = 29,
+ IT_TOY_SHOP = 30,
+ IT_TOY_FACTORY = 31,
+ IT_PLASTIC_FOUNTAINS = 32,
+ IT_FIZZY_DRINK_FACTORY = 33,
+ IT_BUBBLE_GENERATOR = 34,
+ IT_TOFFEE_QUARRY = 35,
+ IT_SUGAR_MINE = 36,
+ IT_END,
+ IT_INVALID = 255,
+};
+
+#endif /* INDUSTRY_H */
diff --git a/src/industry_cmd.c b/src/industry_cmd.c
new file mode 100644
index 000000000..38e2c516b
--- /dev/null
+++ b/src/industry_cmd.c
@@ -0,0 +1,1910 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "clear_map.h"
+#include "functions.h"
+#include "industry_map.h"
+#include "station_map.h"
+#include "table/strings.h"
+#include "table/sprites.h"
+#include "map.h"
+#include "tile.h"
+#include "viewport.h"
+#include "command.h"
+#include "industry.h"
+#include "town.h"
+#include "vehicle.h"
+#include "news.h"
+#include "saveload.h"
+#include "economy.h"
+#include "sound.h"
+#include "variables.h"
+#include "table/industry_land.h"
+#include "table/build_industry.h"
+#include "genworld.h"
+#include "date.h"
+#include "water_map.h"
+
+void ShowIndustryViewWindow(int industry);
+void BuildOilRig(TileIndex tile);
+void DeleteOilRig(TileIndex tile);
+
+static byte _industry_sound_ctr;
+static TileIndex _industry_sound_tile;
+
+/**
+ * Called if a new block is added to the industry-pool
+ */
+static void IndustryPoolNewBlock(uint start_item)
+{
+ Industry *i;
+
+ /* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
+ * TODO - This is just a temporary stage, this will be removed. */
+ for (i = GetIndustry(start_item); i != NULL; i = (i->index + 1U < GetIndustryPoolSize()) ? GetIndustry(i->index + 1U) : NULL) i->index = start_item++;
+}
+
+DEFINE_OLD_POOL(Industry, Industry, IndustryPoolNewBlock, NULL)
+
+/**
+ * Retrieve the type for this industry. Although it is accessed by a tile,
+ * it will return the general type of industry, and not the sprite index
+ * as would do GetIndustryGfx.
+ * The same information can be accessed by looking at Industry->type
+ * @param tile that is queried
+ * @pre IsTileType(tile, MP_INDUSTRY)
+ * @return general type for this industry, as defined in industry.h
+ **/
+IndustryType GetIndustryType(TileIndex tile)
+{
+ IndustryGfx this_type = GetIndustryGfx(tile);
+ IndustryType iloop;
+
+ assert(IsTileType(tile, MP_INDUSTRY));
+
+ for (iloop = IT_COAL_MINE; iloop < IT_END; iloop += 1) {
+ if (IS_BYTE_INSIDE(this_type, industry_gfx_Solver[iloop].MinGfx,
+ industry_gfx_Solver[iloop].MaxGfx+1)) {
+ return iloop;
+ }
+ }
+
+ return IT_INVALID; //we have not found equivalent, whatever the reason
+}
+
+/**
+ * Accessor for array _industry_specs.
+ * This will ensure at once : proper access and
+ * not allowing modifications of it.
+ * @param thistype of industry (which is the index in _industry_specs)
+ * @pre thistype < IT_END
+ **/
+const IndustrySpec *GetIndustrySpec(IndustryType thistype)
+{
+ assert(thistype < IT_END);
+ return &_industry_specs[thistype];
+}
+
+void DestroyIndustry(Industry *i)
+{
+ BEGIN_TILE_LOOP(tile_cur, i->width, i->height, i->xy);
+ if (IsTileType(tile_cur, MP_INDUSTRY)) {
+ if (GetIndustryIndex(tile_cur) == i->index) {
+ DoClearSquare(tile_cur);
+ }
+ } else if (IsTileType(tile_cur, MP_STATION) && IsOilRig(tile_cur)) {
+ DeleteOilRig(tile_cur);
+ }
+ END_TILE_LOOP(tile_cur, i->width, i->height, i->xy);
+
+ if (i->type == IT_FARM || i->type == IT_FARM_2) {
+ /* Remove the farmland and convert it to regular tiles over time. */
+ BEGIN_TILE_LOOP(tile_cur, 42, 42, i->xy - TileDiffXY(21, 21)) {
+ tile_cur = TILE_MASK(tile_cur);
+ if (IsTileType(tile_cur, MP_CLEAR) && IsClearGround(tile_cur, CLEAR_FIELDS) &&
+ GetIndustryIndexOfField(tile_cur) == i->index) {
+ SetIndustryIndexOfField(tile_cur, INVALID_INDUSTRY);
+ }
+ } END_TILE_LOOP(tile_cur, 42, 42, i->xy - TileDiff(21, 21))
+ }
+
+ _industry_sort_dirty = true;
+ _total_industries--;
+ DeleteSubsidyWithIndustry(i->index);
+ DeleteWindowById(WC_INDUSTRY_VIEW, i->index);
+ InvalidateWindow(WC_INDUSTRY_DIRECTORY, 0);
+}
+
+static void IndustryDrawSugarMine(const TileInfo *ti)
+{
+ const DrawIndustrySpec1Struct *d;
+ uint32 image;
+
+ if (!IsIndustryCompleted(ti->tile)) return;
+
+ d = &_draw_industry_spec1[GetIndustryAnimationState(ti->tile)];
+
+ AddChildSpriteScreen(SPR_IT_SUGAR_MINE_SIEVE + d->image_1, d->x, 0);
+
+ image = d->image_2;
+ if (image != 0) AddChildSpriteScreen(SPR_IT_SUGAR_MINE_CLOUDS + image - 1, 8, 41);
+
+ image = d->image_3;
+ if (image != 0) {
+ AddChildSpriteScreen(SPR_IT_SUGAR_MINE_PILE + image - 1,
+ _drawtile_proc1_x[image - 1], _drawtile_proc1_y[image - 1]);
+ }
+}
+
+static void IndustryDrawToffeeQuarry(const TileInfo *ti)
+{
+ int x = 0;
+
+ if (IsIndustryCompleted(ti->tile)) {
+ x = _industry_anim_offs[GetIndustryAnimationState(ti->tile)];
+ if ( (byte)x == 0xFF)
+ x = 0;
+ }
+
+ AddChildSpriteScreen(SPR_IT_TOFFEE_QUARRY_SHOVEL, 22 - x, 24 + x);
+ AddChildSpriteScreen(SPR_IT_TOFFEE_QUARRY_TOFFEE, 6, 14);
+}
+
+static void IndustryDrawBubbleGenerator( const TileInfo *ti)
+{
+ if (IsIndustryCompleted(ti->tile)) {
+ AddChildSpriteScreen(SPR_IT_BUBBLE_GENERATOR_BUBBLE, 5, _industry_anim_offs_2[GetIndustryAnimationState(ti->tile)]);
+ } else {
+ AddChildSpriteScreen(SPR_IT_BUBBLE_GENERATOR_SPRING, 3, 67);
+ }
+}
+
+static void IndustryDrawToyFactory(const TileInfo *ti)
+{
+ const DrawIndustrySpec4Struct *d;
+
+ d = &_industry_anim_offs_3[GetIndustryAnimationState(ti->tile)];
+
+ if (d->image_1 != 0xFF) {
+ AddChildSpriteScreen(SPR_IT_TOY_FACTORY_CLAY, 50 - d->image_1 * 2, 96 + d->image_1);
+ }
+
+ if (d->image_2 != 0xFF) {
+ AddChildSpriteScreen(SPR_IT_TOY_FACTORY_ROBOT, 16 - d->image_2 * 2, 100 + d->image_2);
+ }
+
+ AddChildSpriteScreen(SPR_IT_TOY_FACTORY_STAMP, 7, d->image_3);
+ AddChildSpriteScreen(SPR_IT_TOY_FACTORY_STAMP_HOLDER, 0, 42);
+}
+
+static void IndustryDrawCoalPlantSparks(const TileInfo *ti)
+{
+ if (IsIndustryCompleted(ti->tile)) {
+ uint image = GetIndustryAnimationState(ti->tile);
+
+ if (image != 0 && image < 7) {
+ AddChildSpriteScreen(image + SPR_IT_POWER_PLANT_TRANSFORMERS,
+ _coal_plant_sparks_x[image - 1],
+ _coal_plant_sparks_y[image - 1]
+ );
+ }
+ }
+}
+
+typedef void IndustryDrawTileProc(const TileInfo *ti);
+static IndustryDrawTileProc * const _industry_draw_tile_procs[5] = {
+ IndustryDrawSugarMine,
+ IndustryDrawToffeeQuarry,
+ IndustryDrawBubbleGenerator,
+ IndustryDrawToyFactory,
+ IndustryDrawCoalPlantSparks,
+};
+
+static void DrawTile_Industry(TileInfo *ti)
+{
+ const IndustryGfx gfx = GetIndustryGfx(ti->tile);
+ const Industry *ind;
+ const DrawBuildingsTileStruct *dits;
+ byte z;
+ uint32 image, ormod;
+
+ /* Pointer to industry */
+ ind = GetIndustryByTile(ti->tile);
+ ormod = GENERAL_SPRITE_COLOR(ind->random_color);
+
+ /* Retrieve pointer to the draw industry tile struct */
+ dits = &_industry_draw_tile_data[gfx << 2 | (_industry_section_draw_animation_state[gfx] ?
+ GetIndustryAnimationState(ti->tile) & 3 :
+ GetIndustryConstructionStage(ti->tile))];
+
+ image = dits->ground;
+ if (image & PALETTE_MODIFIER_COLOR && (image & PALETTE_SPRITE_MASK) == 0)
+ image |= ormod;
+
+ z = ti->z;
+ /* Add bricks below the industry? */
+ if (ti->tileh != SLOPE_FLAT) {
+ AddSortableSpriteToDraw(SPR_FOUNDATION_BASE + ti->tileh, ti->x, ti->y, 16, 16, 7, z);
+ AddChildSpriteScreen(image, 31, 1);
+ z += TILE_HEIGHT;
+ } else {
+ /* Else draw regular ground */
+ DrawGroundSprite(image);
+ }
+
+ /* Add industry on top of the ground? */
+ image = dits->building;
+ if (image != 0) {
+ if (image & PALETTE_MODIFIER_COLOR && (image & PALETTE_SPRITE_MASK) == 0)
+ image |= ormod;
+
+ if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
+
+ AddSortableSpriteToDraw(image,
+ ti->x + dits->subtile_x,
+ ti->y + dits->subtile_y,
+ dits->width + 1,
+ dits->height + 1,
+ dits->dz,
+ z);
+
+ if (_display_opt & DO_TRANS_BUILDINGS) return;
+ }
+
+ {
+ int proc = dits->draw_proc - 1;
+ if (proc >= 0) _industry_draw_tile_procs[proc](ti);
+ }
+}
+
+static uint GetSlopeZ_Industry(TileIndex tile, uint x, uint y)
+{
+ return GetTileMaxZ(tile);
+}
+
+static Slope GetSlopeTileh_Industry(TileIndex tile, Slope tileh)
+{
+ return SLOPE_FLAT;
+}
+
+static void GetAcceptedCargo_Industry(TileIndex tile, AcceptedCargo ac)
+{
+ IndustryGfx gfx = GetIndustryGfx(tile);
+ CargoID a;
+
+ a = _industry_section_accepts_1[gfx];
+ if (a != CT_INVALID) ac[a] = (a == 0) ? 1 : 8;
+
+ a = _industry_section_accepts_2[gfx];
+ if (a != CT_INVALID) ac[a] = 8;
+
+ a = _industry_section_accepts_3[gfx];
+ if (a != CT_INVALID) ac[a] = 8;
+}
+
+static void GetTileDesc_Industry(TileIndex tile, TileDesc *td)
+{
+ const Industry *i = GetIndustryByTile(tile);
+
+ td->owner = i->owner;
+ td->str = GetIndustrySpec(i->type)->name;
+ if (!IsIndustryCompleted(tile)) {
+ SetDParamX(td->dparam, 0, td->str);
+ td->str = STR_2058_UNDER_CONSTRUCTION;
+ }
+}
+
+static int32 ClearTile_Industry(TileIndex tile, byte flags)
+{
+ Industry *i = GetIndustryByTile(tile);
+
+ /* water can destroy industries
+ * in editor you can bulldoze industries
+ * with magic_bulldozer cheat you can destroy industries
+ * (area around OILRIG is water, so water shouldn't flood it
+ */
+ if ((_current_player != OWNER_WATER && _game_mode != GM_EDITOR &&
+ !_cheats.magic_bulldozer.value) ||
+ (_current_player == OWNER_WATER && i->type == IT_OIL_RIG)) {
+ SetDParam(0, GetIndustrySpec(i->type)->name);
+ return_cmd_error(STR_4800_IN_THE_WAY);
+ }
+
+ if (flags & DC_EXEC) DeleteIndustry(i);
+ return 0;
+}
+
+static void TransportIndustryGoods(TileIndex tile)
+{
+ Industry *i = GetIndustryByTile(tile);
+ const IndustrySpec *indspec = GetIndustrySpec(i->type);
+ uint cw, am;
+
+ cw = min(i->cargo_waiting[0], 255);
+ if (cw > indspec->minimal_cargo/* && i->produced_cargo[0] != 0xFF*/) {
+ i->cargo_waiting[0] -= cw;
+
+ /* fluctuating economy? */
+ if (_economy.fluct <= 0) cw = (cw + 1) / 2;
+
+ i->last_mo_production[0] += cw;
+
+ am = MoveGoodsToStation(i->xy, i->width, i->height, i->produced_cargo[0], cw);
+ i->last_mo_transported[0] += am;
+ if (am != 0) {
+ uint newgfx = _industry_produce_section[GetIndustryGfx(tile)];
+
+ if (newgfx != 0xFF) {
+ ResetIndustryConstructionStage(tile);
+ SetIndustryCompleted(tile, true);
+ SetIndustryGfx(tile, newgfx);
+ MarkTileDirtyByTile(tile);
+ }
+ }
+ }
+
+ cw = min(i->cargo_waiting[1], 255);
+ if (cw > indspec->minimal_cargo) {
+ i->cargo_waiting[1] -= cw;
+
+ if (_economy.fluct <= 0) cw = (cw + 1) / 2;
+
+ i->last_mo_production[1] += cw;
+
+ am = MoveGoodsToStation(i->xy, i->width, i->height, i->produced_cargo[1], cw);
+ i->last_mo_transported[1] += am;
+ }
+}
+
+
+static void AnimateTile_Industry(TileIndex tile)
+{
+ byte m;
+
+ switch (GetIndustryGfx(tile)) {
+ case GFX_SUGAR_MINE_SIEVE:
+ if ((_tick_counter & 1) == 0) {
+ m = GetIndustryAnimationState(tile) + 1;
+
+ switch (m & 7) {
+ case 2: SndPlayTileFx(SND_2D_RIP_2, tile); break;
+ case 6: SndPlayTileFx(SND_29_RIP, tile); break;
+ }
+
+ if (m >= 96) {
+ m = 0;
+ DeleteAnimatedTile(tile);
+ }
+ SetIndustryAnimationState(tile, m);
+
+ MarkTileDirtyByTile(tile);
+ }
+ break;
+
+ case GFX_TOFFEE_QUARY:
+ if ((_tick_counter & 3) == 0) {
+ m = GetIndustryAnimationState(tile);
+
+ if (_industry_anim_offs[m] == 0xFF) {
+ SndPlayTileFx(SND_30_CARTOON_SOUND, tile);
+ }
+
+ if (++m >= 70) {
+ m = 0;
+ DeleteAnimatedTile(tile);
+ }
+ SetIndustryAnimationState(tile, m);
+
+ MarkTileDirtyByTile(tile);
+ }
+ break;
+
+ case GFX_BUBBLE_CATCHER:
+ if ((_tick_counter & 1) == 0) {
+ m = GetIndustryAnimationState(tile);
+
+ if (++m >= 40) {
+ m = 0;
+ DeleteAnimatedTile(tile);
+ }
+ SetIndustryAnimationState(tile, m);
+
+ MarkTileDirtyByTile(tile);
+ }
+ break;
+
+ // Sparks on a coal plant
+ case GFX_POWERPLANT_SPARKS:
+ if ((_tick_counter & 3) == 0) {
+ m = GetIndustryAnimationState(tile);
+ if (m == 6) {
+ SetIndustryAnimationState(tile, 0);
+ DeleteAnimatedTile(tile);
+ } else {
+ SetIndustryAnimationState(tile, m + 1);
+ MarkTileDirtyByTile(tile);
+ }
+ }
+ break;
+
+ case GFX_TOY_FACTORY:
+ if ((_tick_counter & 1) == 0) {
+ m = GetIndustryAnimationState(tile) + 1;
+
+ if (m == 1) {
+ SndPlayTileFx(SND_2C_MACHINERY, tile);
+ } else if (m == 23) {
+ SndPlayTileFx(SND_2B_COMEDY_HIT, tile);
+ } else if (m == 28) {
+ SndPlayTileFx(SND_2A_EXTRACT_AND_POP, tile);
+ }
+
+ if (m >= 50) {
+ int n = GetIndustryAnimationLoop(tile) + 1;
+ m = 0;
+ if (n >= 8) {
+ n = 0;
+ DeleteAnimatedTile(tile);
+ }
+ SetIndustryAnimationLoop(tile, n);
+ }
+ SetIndustryAnimationState(tile, m);
+ MarkTileDirtyByTile(tile);
+ }
+ break;
+
+ case GFX_PLASTIC_FOUNTAIN_ANIMATED_1: case GFX_PLASTIC_FOUNTAIN_ANIMATED_2:
+ case GFX_PLASTIC_FOUNTAIN_ANIMATED_3: case GFX_PLASTIC_FOUNTAIN_ANIMATED_4:
+ case GFX_PLASTIC_FOUNTAIN_ANIMATED_5: case GFX_PLASTIC_FOUNTAIN_ANIMATED_6:
+ case GFX_PLASTIC_FOUNTAIN_ANIMATED_7: case GFX_PLASTIC_FOUNTAIN_ANIMATED_8:
+ if ((_tick_counter & 3) == 0) {
+ IndustryGfx gfx = GetIndustryGfx(tile);
+
+ gfx = (gfx < 155) ? gfx + 1 : 148;
+ SetIndustryGfx(tile, gfx);
+ MarkTileDirtyByTile(tile);
+ }
+ break;
+
+ case GFX_OILWELL_ANIMATED_1:
+ case GFX_OILWELL_ANIMATED_2:
+ case GFX_OILWELL_ANIMATED_3:
+ if ((_tick_counter & 7) == 0) {
+ bool b = CHANCE16(1,7);
+ IndustryGfx gfx = GetIndustryGfx(tile);
+
+ m = GetIndustryAnimationState(tile) + 1;
+ if (m == 4 && (m = 0, ++gfx) == GFX_OILWELL_ANIMATED_3 + 1 && (gfx = GFX_OILWELL_ANIMATED_1, b)) {
+ SetIndustryGfx(tile, GFX_OILWELL_NOT_ANIMATED);
+ SetIndustryConstructionStage(tile, 3);
+ DeleteAnimatedTile(tile);
+ } else {
+ SetIndustryAnimationState(tile, m);
+ SetIndustryGfx(tile, gfx);
+ MarkTileDirtyByTile(tile);
+ }
+ }
+ break;
+
+ case GFX_COAL_MINE_TOWER_ANIMATED:
+ case GFX_COPPER_MINE_TOWER_ANIMATED:
+ case GFX_GOLD_MINE_TOWER_ANIMATED: {
+ int state = _tick_counter & 0x7FF;
+
+ if ((state -= 0x400) < 0)
+ return;
+
+ if (state < 0x1A0) {
+ if (state < 0x20 || state >= 0x180) {
+ m = GetIndustryAnimationState(tile);
+ if (!(m & 0x40)) {
+ SetIndustryAnimationState(tile, m | 0x40);
+ SndPlayTileFx(SND_0B_MINING_MACHINERY, tile);
+ }
+ if (state & 7)
+ return;
+ } else {
+ if (state & 3)
+ return;
+ }
+ m = (GetIndustryAnimationState(tile) + 1) | 0x40;
+ if (m > 0xC2) m = 0xC0;
+ SetIndustryAnimationState(tile, m);
+ MarkTileDirtyByTile(tile);
+ } else if (state >= 0x200 && state < 0x3A0) {
+ int i;
+ i = (state < 0x220 || state >= 0x380) ? 7 : 3;
+ if (state & i)
+ return;
+
+ m = (GetIndustryAnimationState(tile) & 0xBF) - 1;
+ if (m < 0x80) m = 0x82;
+ SetIndustryAnimationState(tile, m);
+ MarkTileDirtyByTile(tile);
+ }
+ } break;
+ }
+}
+
+static void CreateIndustryEffectSmoke(TileIndex tile)
+{
+ uint x = TileX(tile) * TILE_SIZE;
+ uint y = TileY(tile) * TILE_SIZE;
+ uint z = GetTileMaxZ(tile);
+
+ CreateEffectVehicle(x + 15, y + 14, z + 59, EV_CHIMNEY_SMOKE);
+}
+
+static void MakeIndustryTileBigger(TileIndex tile)
+{
+ byte cnt = GetIndustryConstructionCounter(tile) + 1;
+ byte stage;
+
+ if (cnt != 4) {
+ SetIndustryConstructionCounter(tile, cnt);
+ return;
+ }
+
+ stage = GetIndustryConstructionStage(tile) + 1;
+ SetIndustryConstructionCounter(tile, 0);
+ SetIndustryConstructionStage(tile, stage);
+ if (stage == 3) {
+ SetIndustryCompleted(tile, true);
+ }
+
+ MarkTileDirtyByTile(tile);
+
+ if (!IsIndustryCompleted(tile)) return;
+
+ switch (GetIndustryGfx(tile)) {
+ case GFX_POWERPLANT_CHIMNEY:
+ CreateIndustryEffectSmoke(tile);
+ break;
+
+ case GFX_OILRIG_1:
+ if (GetIndustryGfx(tile + TileDiffXY(0, 1)) == GFX_OILRIG_1) BuildOilRig(tile);
+ break;
+
+ case GFX_TOY_FACTORY:
+ case GFX_BUBBLE_CATCHER:
+ case GFX_TOFFEE_QUARY:
+ SetIndustryAnimationState(tile, 0);
+ SetIndustryAnimationLoop(tile, 0);
+ break;
+
+ case GFX_PLASTIC_FOUNTAIN_ANIMATED_1: case GFX_PLASTIC_FOUNTAIN_ANIMATED_2:
+ case GFX_PLASTIC_FOUNTAIN_ANIMATED_3: case GFX_PLASTIC_FOUNTAIN_ANIMATED_4:
+ case GFX_PLASTIC_FOUNTAIN_ANIMATED_5: case GFX_PLASTIC_FOUNTAIN_ANIMATED_6:
+ case GFX_PLASTIC_FOUNTAIN_ANIMATED_7: case GFX_PLASTIC_FOUNTAIN_ANIMATED_8:
+ AddAnimatedTile(tile);
+ break;
+ }
+}
+
+
+static void TileLoopIndustry_BubbleGenerator(TileIndex tile)
+{
+ int dir;
+ Vehicle *v;
+ static const int8 _tileloop_ind_case_161[12] = {
+ 11, 0, -4, -14,
+ -4, -10, -4, 1,
+ 49, 59, 60, 65,
+ };
+
+ SndPlayTileFx(SND_2E_EXTRACT_AND_POP, tile);
+
+ dir = Random() & 3;
+
+ v = CreateEffectVehicleAbove(
+ TileX(tile) * TILE_SIZE + _tileloop_ind_case_161[dir + 0],
+ TileY(tile) * TILE_SIZE + _tileloop_ind_case_161[dir + 4],
+ _tileloop_ind_case_161[dir + 8],
+ EV_BUBBLE
+ );
+
+ if (v != NULL) v->u.special.unk2 = dir;
+}
+
+static void TileLoop_Industry(TileIndex tile)
+{
+ IndustryGfx newgfx;
+ IndustryGfx gfx;
+
+ if (!IsIndustryCompleted(tile)) {
+ MakeIndustryTileBigger(tile);
+ return;
+ }
+
+ if (_game_mode == GM_EDITOR) return;
+
+ TransportIndustryGoods(tile);
+
+ newgfx = _industry_section_animation_next[GetIndustryGfx(tile)];
+ if (newgfx != 255) {
+ ResetIndustryConstructionStage(tile);
+ SetIndustryGfx(tile, newgfx);
+ MarkTileDirtyByTile(tile);
+ return;
+ }
+
+ gfx = GetIndustryGfx(tile);
+
+ switch (gfx) {
+ case GFX_OILRIG_1: // coast line at oilrigs
+ case GFX_OILRIG_2:
+ case GFX_OILRIG_3:
+ case GFX_OILRIG_4:
+ case GFX_OILRIG_5:
+ TileLoop_Water(tile);
+ break;
+
+ case GFX_COAL_MINE_TOWER_NOT_ANIMATED:
+ case GFX_COPPER_MINE_TOWER_NOT_ANIMATED:
+ case GFX_GOLD_MINE_TOWER_NOT_ANIMATED:
+ if (!(_tick_counter & 0x400) && CHANCE16(1, 2)) {
+ switch (gfx) {
+ case GFX_COAL_MINE_TOWER_NOT_ANIMATED: gfx = GFX_COAL_MINE_TOWER_ANIMATED; break;
+ case GFX_COPPER_MINE_TOWER_NOT_ANIMATED: gfx = GFX_COPPER_MINE_TOWER_ANIMATED; break;
+ case GFX_GOLD_MINE_TOWER_NOT_ANIMATED: gfx = GFX_GOLD_MINE_TOWER_ANIMATED; break;
+ }
+ SetIndustryGfx(tile, gfx);
+ SetIndustryAnimationState(tile, 0x80);
+ AddAnimatedTile(tile);
+ }
+ break;
+
+ case GFX_OILWELL_NOT_ANIMATED:
+ if (CHANCE16(1, 6)) {
+ SetIndustryGfx(tile, GFX_OILWELL_ANIMATED_1);
+ SetIndustryAnimationState(tile, 0);
+ AddAnimatedTile(tile);
+ }
+ break;
+
+ case GFX_COAL_MINE_TOWER_ANIMATED:
+ case GFX_COPPER_MINE_TOWER_ANIMATED:
+ case GFX_GOLD_MINE_TOWER_ANIMATED:
+ if (!(_tick_counter & 0x400)) {
+ switch (gfx) {
+ case GFX_COAL_MINE_TOWER_ANIMATED: gfx = GFX_COAL_MINE_TOWER_NOT_ANIMATED; break;
+ case GFX_COPPER_MINE_TOWER_ANIMATED: gfx = GFX_COPPER_MINE_TOWER_NOT_ANIMATED; break;
+ case GFX_GOLD_MINE_TOWER_ANIMATED: gfx = GFX_GOLD_MINE_TOWER_NOT_ANIMATED; break;
+ }
+ SetIndustryGfx(tile, gfx);
+ SetIndustryCompleted(tile, true);
+ SetIndustryConstructionStage(tile, 3);
+ DeleteAnimatedTile(tile);
+ }
+ break;
+
+ case GFX_POWERPLANT_SPARKS:
+ if (CHANCE16(1,3)) {
+ SndPlayTileFx(SND_0C_ELECTRIC_SPARK, tile);
+ AddAnimatedTile(tile);
+ }
+ break;
+
+ case GFX_COPPER_MINE_CHIMNEY:
+ CreateEffectVehicleAbove(TileX(tile) * TILE_SIZE + 6, TileY(tile) * TILE_SIZE + 6, 43, EV_SMOKE);
+ break;
+
+
+ case GFX_TOY_FACTORY: {
+ Industry *i = GetIndustryByTile(tile);
+ if (i->was_cargo_delivered) {
+ i->was_cargo_delivered = false;
+ SetIndustryAnimationLoop(tile, 0);
+ AddAnimatedTile(tile);
+ }
+ }
+ break;
+
+ case GFX_BUBBLE_GENERATOR:
+ TileLoopIndustry_BubbleGenerator(tile);
+ break;
+
+ case GFX_TOFFEE_QUARY:
+ AddAnimatedTile(tile);
+ break;
+
+ case GFX_SUGAR_MINE_SIEVE:
+ if (CHANCE16(1, 3)) AddAnimatedTile(tile);
+ break;
+ }
+}
+
+
+static void ClickTile_Industry(TileIndex tile)
+{
+ ShowIndustryViewWindow(GetIndustryIndex(tile));
+}
+
+static uint32 GetTileTrackStatus_Industry(TileIndex tile, TransportType mode)
+{
+ return 0;
+}
+
+static void GetProducedCargo_Industry(TileIndex tile, CargoID *b)
+{
+ const Industry *i = GetIndustryByTile(tile);
+
+ b[0] = i->produced_cargo[0];
+ b[1] = i->produced_cargo[1];
+}
+
+static void ChangeTileOwner_Industry(TileIndex tile, PlayerID old_player, PlayerID new_player)
+{
+ /* not used */
+}
+
+static const byte _plantfarmfield_type[] = {1, 1, 1, 1, 1, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6};
+
+static bool IsBadFarmFieldTile(TileIndex tile)
+{
+ switch (GetTileType(tile)) {
+ case MP_CLEAR: return IsClearGround(tile, CLEAR_FIELDS) || IsClearGround(tile, CLEAR_SNOW);
+ case MP_TREES: return false;
+ default: return true;
+ }
+}
+
+static bool IsBadFarmFieldTile2(TileIndex tile)
+{
+ switch (GetTileType(tile)) {
+ case MP_CLEAR: return IsClearGround(tile, CLEAR_SNOW);
+ case MP_TREES: return false;
+ default: return true;
+ }
+}
+
+static void SetupFarmFieldFence(TileIndex tile, int size, byte type, Axis direction)
+{
+ do {
+ tile = TILE_MASK(tile);
+
+ if (IsTileType(tile, MP_CLEAR) || IsTileType(tile, MP_TREES)) {
+ byte or = type;
+
+ if (or == 1 && CHANCE16(1, 7)) or = 2;
+
+ if (direction == AXIS_X) {
+ SetFenceSE(tile, or);
+ } else {
+ SetFenceSW(tile, or);
+ }
+ }
+
+ tile += (direction == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
+ } while (--size);
+}
+
+static void PlantFarmField(TileIndex tile, IndustryID industry)
+{
+ uint size_x, size_y;
+ uint32 r;
+ uint count;
+ uint counter;
+ uint field_type;
+ int type;
+
+ if (_opt.landscape == LT_HILLY) {
+ if (GetTileZ(tile) + TILE_HEIGHT * 2 >= _opt.snow_line)
+ return;
+ }
+
+ /* determine field size */
+ r = (Random() & 0x303) + 0x404;
+ if (_opt.landscape == LT_HILLY) r += 0x404;
+ size_x = GB(r, 0, 8);
+ size_y = GB(r, 8, 8);
+
+ /* offset tile to match size */
+ tile -= TileDiffXY(size_x / 2, size_y / 2);
+
+ /* check the amount of bad tiles */
+ count = 0;
+ BEGIN_TILE_LOOP(cur_tile, size_x, size_y, tile)
+ cur_tile = TILE_MASK(cur_tile);
+ count += IsBadFarmFieldTile(cur_tile);
+ END_TILE_LOOP(cur_tile, size_x, size_y, tile)
+ if (count * 2 >= size_x * size_y) return;
+
+ /* determine type of field */
+ r = Random();
+ counter = GB(r, 5, 3);
+ field_type = GB(r, 8, 8) * 9 >> 8;
+
+ /* make field */
+ BEGIN_TILE_LOOP(cur_tile, size_x, size_y, tile)
+ cur_tile = TILE_MASK(cur_tile);
+ if (!IsBadFarmFieldTile2(cur_tile)) {
+ MakeField(cur_tile, field_type, industry);
+ SetClearCounter(cur_tile, counter);
+ MarkTileDirtyByTile(cur_tile);
+ }
+ END_TILE_LOOP(cur_tile, size_x, size_y, tile)
+
+ type = 3;
+ if (_opt.landscape != LT_HILLY && _opt.landscape != LT_DESERT) {
+ type = _plantfarmfield_type[Random() & 0xF];
+ }
+
+ SetupFarmFieldFence(tile - TileDiffXY(1, 0), size_y, type, AXIS_Y);
+ SetupFarmFieldFence(tile - TileDiffXY(0, 1), size_x, type, AXIS_X);
+ SetupFarmFieldFence(tile + TileDiffXY(size_x - 1, 0), size_y, type, AXIS_Y);
+ SetupFarmFieldFence(tile + TileDiffXY(0, size_y - 1), size_x, type, AXIS_X);
+}
+
+void PlantRandomFarmField(const Industry *i)
+{
+ int x = i->width / 2 + Random() % 31 - 16;
+ int y = i->height / 2 + Random() % 31 - 16;
+
+ TileIndex tile = TileAddWrap(i->xy, x, y);
+
+ if (tile != INVALID_TILE) PlantFarmField(tile, i->index);
+}
+
+static void MaybePlantFarmField(const Industry *i)
+{
+ if (CHANCE16(1, 8)) PlantRandomFarmField(i);
+}
+
+/**
+ * Search callback function for ChopLumberMillTrees
+ * @param tile to test
+ * @param data that is passed by the caller. In this case, nothing
+ * @result of the test
+ */
+static bool SearchLumberMillTrees(TileIndex tile, uint32 data)
+{
+ if (IsTileType(tile, MP_TREES)) {
+ PlayerID old_player = _current_player;
+ /* found a tree */
+
+ _current_player = OWNER_NONE;
+ _industry_sound_ctr = 1;
+ _industry_sound_tile = tile;
+ SndPlayTileFx(SND_38_CHAINSAW, tile);
+
+ DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
+ SetTropicZone(tile, TROPICZONE_INVALID);
+
+ _current_player = old_player;
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Perform a circular search around the Lumber Mill in order to find trees to cut
+ * @param i industry
+ */
+static void ChopLumberMillTrees(Industry *i)
+{
+ TileIndex tile = i->xy;
+
+ if (!IsIndustryCompleted(tile)) return; ///< Can't proceed if not completed
+
+ if (CircularTileSearch(tile, 40, SearchLumberMillTrees, 0)) ///< 40x40 tiles to search
+ i->cargo_waiting[0] = min(0xffff, i->cargo_waiting[0] + 45); ///< Found a tree, add according value to waiting cargo
+}
+
+static const byte _industry_sounds[37][2] = {
+ {0},
+ {0},
+ {1, SND_28_SAWMILL},
+ {0},
+ {0},
+ {0},
+ {1, SND_03_FACTORY_WHISTLE},
+ {1, SND_03_FACTORY_WHISTLE},
+ {0},
+ {3, SND_24_SHEEP},
+ {0},
+ {0},
+ {0},
+ {0},
+ {1, SND_28_SAWMILL},
+ {0},
+ {0},
+ {0},
+ {0},
+ {0},
+ {0},
+ {0},
+ {0},
+ {1, SND_03_FACTORY_WHISTLE},
+ {0},
+ {0},
+ {0},
+ {0},
+ {0},
+ {0},
+ {0},
+ {0},
+ {1, SND_33_PLASTIC_MINE},
+ {0},
+ {0},
+ {0},
+ {0},
+};
+
+
+static void ProduceIndustryGoods(Industry *i)
+{
+ uint32 r;
+ uint num;
+
+ /* play a sound? */
+ if ((i->counter & 0x3F) == 0) {
+ if (CHANCE16R(1,14,r) && (num=_industry_sounds[i->type][0]) != 0) {
+ SndPlayTileFx(
+ _industry_sounds[i->type][1] + (((r >> 16) * num) >> 16),
+ i->xy);
+ }
+ }
+
+ i->counter--;
+
+ /* produce some cargo */
+ if ((i->counter & 0xFF) == 0) {
+ i->cargo_waiting[0] = min(0xffff, i->cargo_waiting[0] + i->production_rate[0]);
+ i->cargo_waiting[1] = min(0xffff, i->cargo_waiting[1] + i->production_rate[1]);
+
+ if (i->type == IT_FARM) {
+ MaybePlantFarmField(i);
+ } else if (i->type == IT_LUMBER_MILL && (i->counter & 0x1FF) == 0) {
+ ChopLumberMillTrees(i);
+ }
+ }
+}
+
+void OnTick_Industry(void)
+{
+ Industry *i;
+
+ if (_industry_sound_ctr != 0) {
+ _industry_sound_ctr++;
+
+ if (_industry_sound_ctr == 75) {
+ SndPlayTileFx(SND_37_BALLOON_SQUEAK, _industry_sound_tile);
+ } else if (_industry_sound_ctr == 160) {
+ _industry_sound_ctr = 0;
+ SndPlayTileFx(SND_36_CARTOON_CRASH, _industry_sound_tile);
+ }
+ }
+
+ if (_game_mode == GM_EDITOR) return;
+
+ FOR_ALL_INDUSTRIES(i) {
+ ProduceIndustryGoods(i);
+ }
+}
+
+
+static bool CheckNewIndustry_NULL(TileIndex tile)
+{
+ return true;
+}
+
+static bool CheckNewIndustry_Forest(TileIndex tile)
+{
+ if (_opt.landscape == LT_HILLY) {
+ if (GetTileZ(tile) < _opt.snow_line + TILE_HEIGHT * 2U) {
+ _error_message = STR_4831_FOREST_CAN_ONLY_BE_PLANTED;
+ return false;
+ }
+ }
+ return true;
+}
+
+static bool CheckNewIndustry_OilRefinery(TileIndex tile)
+{
+ if (_game_mode == GM_EDITOR) return true;
+ if (DistanceFromEdge(TILE_ADDXY(tile, 1, 1)) < _patches.oil_refinery_limit) return true;
+
+ _error_message = STR_483B_CAN_ONLY_BE_POSITIONED;
+ return false;
+}
+
+extern bool _ignore_restrictions;
+
+static bool CheckNewIndustry_OilRig(TileIndex tile)
+{
+ if (_game_mode == GM_EDITOR && _ignore_restrictions) return true;
+ if (TileHeight(tile) == 0 &&
+ DistanceFromEdge(TILE_ADDXY(tile, 1, 1)) < _patches.oil_refinery_limit) return true;
+
+ _error_message = STR_483B_CAN_ONLY_BE_POSITIONED;
+ return false;
+}
+
+static bool CheckNewIndustry_Farm(TileIndex tile)
+{
+ if (_opt.landscape == LT_HILLY) {
+ if (GetTileZ(tile) + TILE_HEIGHT * 2 >= _opt.snow_line) {
+ _error_message = STR_0239_SITE_UNSUITABLE;
+ return false;
+ }
+ }
+ return true;
+}
+
+static bool CheckNewIndustry_Plantation(TileIndex tile)
+{
+ if (GetTropicZone(tile) == TROPICZONE_DESERT) {
+ _error_message = STR_0239_SITE_UNSUITABLE;
+ return false;
+ }
+
+ return true;
+}
+
+static bool CheckNewIndustry_Water(TileIndex tile)
+{
+ if (GetTropicZone(tile) != TROPICZONE_DESERT) {
+ _error_message = STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT;
+ return false;
+ }
+
+ return true;
+}
+
+static bool CheckNewIndustry_Lumbermill(TileIndex tile)
+{
+ if (GetTropicZone(tile) != TROPICZONE_RAINFOREST) {
+ _error_message = STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST;
+ return false;
+ }
+ return true;
+}
+
+static bool CheckNewIndustry_BubbleGen(TileIndex tile)
+{
+ return GetTileZ(tile) <= TILE_HEIGHT * 4;
+}
+
+typedef bool CheckNewIndustryProc(TileIndex tile);
+static CheckNewIndustryProc * const _check_new_industry_procs[CHECK_END] = {
+ CheckNewIndustry_NULL,
+ CheckNewIndustry_Forest,
+ CheckNewIndustry_OilRefinery,
+ CheckNewIndustry_Farm,
+ CheckNewIndustry_Plantation,
+ CheckNewIndustry_Water,
+ CheckNewIndustry_Lumbermill,
+ CheckNewIndustry_BubbleGen,
+ CheckNewIndustry_OilRig
+};
+
+static bool CheckSuitableIndustryPos(TileIndex tile)
+{
+ uint x = TileX(tile);
+ uint y = TileY(tile);
+
+ if (x < 2 || y < 2 || x > MapMaxX() - 3 || y > MapMaxY() - 3) {
+ _error_message = STR_0239_SITE_UNSUITABLE;
+ return false;
+ }
+
+ return true;
+}
+
+static const Town *CheckMultipleIndustryInTown(TileIndex tile, int type)
+{
+ const Town *t;
+ const Industry *i;
+
+ t = ClosestTownFromTile(tile, (uint)-1);
+
+ if (_patches.multiple_industry_per_town) return t;
+
+ FOR_ALL_INDUSTRIES(i) {
+ if (i->type == (byte)type &&
+ i->town == t) {
+ _error_message = STR_0287_ONLY_ONE_ALLOWED_PER_TOWN;
+ return NULL;
+ }
+ }
+
+ return t;
+}
+
+static bool CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTileTable *it, int type)
+{
+ _error_message = STR_0239_SITE_UNSUITABLE;
+
+ do {
+ TileIndex cur_tile = tile + ToTileIndexDiff(it->ti);
+
+ if (!IsValidTile(cur_tile)) {
+ if (it->gfx == 0xff) continue;
+ return false;
+ }
+
+ if (it->gfx == 0xFF) {
+ if (!IsTileType(cur_tile, MP_WATER) ||
+ GetTileSlope(cur_tile, NULL) != SLOPE_FLAT) {
+ return false;
+ }
+ } else {
+ if (!EnsureNoVehicle(cur_tile)) return false;
+
+ if (type == IT_OIL_RIG) {
+ if (!IsClearWaterTile(cur_tile)) return false;
+ } else {
+ Slope tileh;
+
+ if (IsClearWaterTile(cur_tile)) return false;
+
+ tileh = GetTileSlope(cur_tile, NULL);
+ if (IsSteepSlope(tileh)) return false;
+
+ if (_patches.land_generator != LG_TERRAGENESIS || !_generating_world) {
+ /* It is almost impossible to have a fully flat land in TG, so what we
+ * do is that we check if we can make the land flat later on. See
+ * CheckIfCanLevelIndustryPlatform(). */
+ if (tileh != SLOPE_FLAT) {
+ Slope t;
+ byte bits = _industry_section_bits[it->gfx];
+
+ if (bits & 0x10) return false;
+
+ t = ComplementSlope(tileh);
+
+ if (bits & 1 && (t & SLOPE_NW)) return false;
+ if (bits & 2 && (t & SLOPE_NE)) return false;
+ if (bits & 4 && (t & SLOPE_SW)) return false;
+ if (bits & 8 && (t & SLOPE_SE)) return false;
+ }
+ }
+
+ if (type == IT_BANK_TEMP) {
+ if (!IsTileType(cur_tile, MP_HOUSE)) {
+ _error_message = STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS;
+ return false;
+ }
+ } else if (type == IT_BANK_TROPIC_ARCTIC) {
+ if (!IsTileType(cur_tile, MP_HOUSE)) {
+ _error_message = STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS;
+ return false;
+ }
+ } else if (type == IT_TOY_SHOP) {
+ if (!IsTileType(cur_tile, MP_HOUSE)) goto do_clear;
+ } else if (type == IT_WATER_TOWER) {
+ if (!IsTileType(cur_tile, MP_HOUSE)) {
+ _error_message = STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS;
+ return false;
+ }
+ } else {
+do_clear:
+ if (CmdFailed(DoCommand(cur_tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR)))
+ return false;
+ }
+ }
+ }
+ } while ((++it)->ti.x != -0x80);
+
+ return true;
+}
+
+static bool CheckIfIndustryIsAllowed(TileIndex tile, int type, const Town *t)
+{
+ if (type == IT_BANK_TEMP && t->population < 1200) {
+ _error_message = STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS;
+ return false;
+ }
+
+ if (type == IT_TOY_SHOP && DistanceMax(t->xy, tile) > 9) {
+ _error_message = STR_0239_SITE_UNSUITABLE;
+ return false;
+ }
+
+ return true;
+}
+
+static bool CheckCanTerraformSurroundingTiles(TileIndex tile, uint height, int internal)
+{
+ int size_x, size_y;
+ uint curh;
+
+ size_x = 2;
+ size_y = 2;
+
+ /* Check if we don't leave the map */
+ if (TileX(tile) == 0 || TileY(tile) == 0 || GetTileType(tile) == MP_VOID) return false;
+
+ tile += TileDiffXY(-1, -1);
+ BEGIN_TILE_LOOP(tile_walk, size_x, size_y, tile) {
+ curh = TileHeight(tile_walk);
+ /* Is the tile clear? */
+ if ((GetTileType(tile_walk) != MP_CLEAR) && (GetTileType(tile_walk) != MP_TREES))
+ return false;
+
+ /* Don't allow too big of a change if this is the sub-tile check */
+ if (internal != 0 && myabs(curh - height) > 1) return false;
+
+ /* Different height, so the surrounding tiles of this tile
+ * has to be correct too (in level, or almost in level)
+ * else you get a chain-reaction of terraforming. */
+ if (internal == 0 && curh != height) {
+ if (!CheckCanTerraformSurroundingTiles(tile_walk + TileDiffXY(-1, -1), height, internal + 1))
+ return false;
+ }
+ } END_TILE_LOOP(tile_walk, size_x, size_y, tile);
+
+ return true;
+}
+
+/**
+ * This function tries to flatten out the land below an industry, without
+ * damaging the surroundings too much.
+ */
+static bool CheckIfCanLevelIndustryPlatform(TileIndex tile, uint32 flags, const IndustryTileTable* it, int type)
+{
+ const int MKEND = -0x80; // used for last element in an IndustryTileTable (see build_industry.h)
+ int max_x = 0;
+ int max_y = 0;
+ TileIndex cur_tile;
+ uint size_x, size_y;
+ uint h, curh;
+
+ /* Finds dimensions of largest variant of this industry */
+ do {
+ if (it->ti.x > max_x) max_x = it->ti.x;
+ if (it->ti.y > max_y) max_y = it->ti.y;
+ } while ((++it)->ti.x != MKEND);
+
+ /* Remember level height */
+ h = TileHeight(tile);
+
+ /* Check that all tiles in area and surrounding are clear
+ * this determines that there are no obstructing items */
+ cur_tile = tile + TileDiffXY(-1, -1);
+ size_x = max_x + 4;
+ size_y = max_y + 4;
+
+ /* Check if we don't leave the map */
+ if (TileX(cur_tile) == 0 || TileY(cur_tile) == 0 || TileX(cur_tile) + size_x >= MapMaxX() || TileY(cur_tile) + size_y >= MapMaxY()) return false;
+
+ BEGIN_TILE_LOOP(tile_walk, size_x, size_y, cur_tile) {
+ curh = TileHeight(tile_walk);
+ if (curh != h) {
+ /* This tile needs terraforming. Check if we can do that without
+ * damaging the surroundings too much. */
+ if (!CheckCanTerraformSurroundingTiles(tile_walk, h, 0)) return false;
+ /* This is not 100% correct check, but the best we can do without modifying the map.
+ * What is missing, is if the difference in height is more than 1.. */
+ if (CmdFailed(DoCommand(tile_walk, 8, (curh > h) ? 0 : 1, flags & ~DC_EXEC, CMD_TERRAFORM_LAND))) return false;
+ }
+ } END_TILE_LOOP(tile_walk, size_x, size_y, cur_tile)
+
+ if (flags & DC_EXEC) {
+ /* Terraform the land under the industry */
+ BEGIN_TILE_LOOP(tile_walk, size_x, size_y, cur_tile) {
+ curh = TileHeight(tile_walk);
+ while (curh != h) {
+ /* We give the terraforming for free here, because we can't calculate
+ * exact cost in the test-round, and as we all know, that will cause
+ * a nice assert if they don't match ;) */
+ DoCommand(tile_walk, 8, (curh > h) ? 0 : 1, flags, CMD_TERRAFORM_LAND);
+ curh += (curh > h) ? -1 : 1;
+ }
+ } END_TILE_LOOP(tile_walk, size_x, size_y, cur_tile)
+ }
+
+ return true;
+}
+
+
+static bool CheckIfTooCloseToIndustry(TileIndex tile, int type)
+{
+ const IndustrySpec *indspec = GetIndustrySpec(type);
+ const Industry *i;
+
+ // accepting industries won't be close, not even with patch
+ if (_patches.same_industry_close && indspec->accepts_cargo[0] == CT_INVALID)
+ return true;
+
+ FOR_ALL_INDUSTRIES(i) {
+ // check if an industry that accepts the same goods is nearby
+ if (DistanceMax(tile, i->xy) <= 14 &&
+ indspec->accepts_cargo[0] != CT_INVALID &&
+ indspec->accepts_cargo[0] == i->accepts_cargo[0] && (
+ _game_mode != GM_EDITOR ||
+ !_patches.same_industry_close ||
+ !_patches.multiple_industry_per_town
+ )) {
+ _error_message = STR_INDUSTRY_TOO_CLOSE;
+ return false;
+ }
+
+ // check "not close to" field.
+ if ((i->type == indspec->conflicting[0] || i->type == indspec->conflicting[1] || i->type == indspec->conflicting[2]) &&
+ DistanceMax(tile, i->xy) <= 14) {
+ _error_message = STR_INDUSTRY_TOO_CLOSE;
+ return false;
+ }
+ }
+ return true;
+}
+
+static Industry *AllocateIndustry(void)
+{
+ Industry *i;
+
+ /* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
+ * TODO - This is just a temporary stage, this will be removed. */
+ for (i = GetIndustry(0); i != NULL; i = (i->index + 1U < GetIndustryPoolSize()) ? GetIndustry(i->index + 1U) : NULL) {
+ IndustryID index = i->index;
+
+ if (IsValidIndustry(i)) continue;
+
+ memset(i, 0, sizeof(*i));
+ i->index = index;
+
+ return i;
+ }
+
+ /* Check if we can add a block to the pool */
+ return AddBlockToPool(&_Industry_pool) ? AllocateIndustry() : NULL;
+}
+
+static void DoCreateNewIndustry(Industry *i, TileIndex tile, int type, const IndustryTileTable *it, const Town *t, byte owner)
+{
+ const IndustrySpec *indspec = GetIndustrySpec(type);
+ uint32 r;
+ int j;
+
+ _total_industries++;
+ i->xy = tile;
+ i->width = i->height = 0;
+ i->type = type;
+
+ i->produced_cargo[0] = indspec->produced_cargo[0];
+ i->produced_cargo[1] = indspec->produced_cargo[1];
+ i->accepts_cargo[0] = indspec->accepts_cargo[0];
+ i->accepts_cargo[1] = indspec->accepts_cargo[1];
+ i->accepts_cargo[2] = indspec->accepts_cargo[2];
+ i->production_rate[0] = indspec->production_rate[0];
+ i->production_rate[1] = indspec->production_rate[1];
+
+ if (_patches.smooth_economy) {
+ i->production_rate[0] = min((RandomRange(256) + 128) * i->production_rate[0] >> 8 , 255);
+ i->production_rate[1] = min((RandomRange(256) + 128) * i->production_rate[1] >> 8 , 255);
+ }
+
+ i->town = t;
+ i->owner = owner;
+
+ r = Random();
+ i->random_color = GB(r, 8, 4);
+ i->counter = GB(r, 0, 12);
+ i->cargo_waiting[0] = 0;
+ i->cargo_waiting[1] = 0;
+ i->last_mo_production[0] = 0;
+ i->last_mo_production[1] = 0;
+ i->last_mo_transported[0] = 0;
+ i->last_mo_transported[1] = 0;
+ i->pct_transported[0] = 0;
+ i->pct_transported[1] = 0;
+ i->total_transported[0] = 0;
+ i->total_transported[1] = 0;
+ i->was_cargo_delivered = false;
+ i->last_prod_year = _cur_year;
+ i->total_production[0] = i->production_rate[0] * 8;
+ i->total_production[1] = i->production_rate[1] * 8;
+
+ if (!_generating_world) i->total_production[0] = i->total_production[1] = 0;
+
+ i->prod_level = 0x10;
+
+ do {
+ TileIndex cur_tile = tile + ToTileIndexDiff(it->ti);
+
+ if (it->gfx != 0xFF) {
+ byte size;
+
+ size = it->ti.x;
+ if (size > i->width) i->width = size;
+ size = it->ti.y;
+ if (size > i->height)i->height = size;
+
+ DoCommand(cur_tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
+
+ MakeIndustry(cur_tile, i->index, it->gfx);
+ if (_generating_world) {
+ SetIndustryConstructionCounter(cur_tile, 3);
+ SetIndustryConstructionStage(cur_tile, 2);
+ }
+ }
+ } while ((++it)->ti.x != -0x80);
+
+ i->width++;
+ i->height++;
+
+ if (i->type == IT_FARM || i->type == IT_FARM_2) {
+ for (j = 0; j != 50; j++) PlantRandomFarmField(i);
+ }
+ _industry_sort_dirty = true;
+ InvalidateWindow(WC_INDUSTRY_DIRECTORY, 0);
+}
+
+static Industry *CreateNewIndustryHelper(TileIndex tile, IndustryType type, uint32 flags, const IndustrySpec *indspec, const IndustryTileTable *it)
+{
+ const Town *t;
+ Industry *i;
+
+ if (!CheckIfIndustryTilesAreFree(tile, it, type)) return NULL;
+ if (_patches.land_generator == LG_TERRAGENESIS && _generating_world && !CheckIfCanLevelIndustryPlatform(tile, 0, it, type)) return NULL;
+ if (!_check_new_industry_procs[indspec->check_proc](tile)) return NULL;
+ if (!CheckIfTooCloseToIndustry(tile, type)) return NULL;
+
+ t = CheckMultipleIndustryInTown(tile, type);
+ if (t == NULL) return NULL;
+
+ if (!CheckIfIndustryIsAllowed(tile, type, t)) return NULL;
+ if (!CheckSuitableIndustryPos(tile)) return NULL;
+
+ i = AllocateIndustry();
+ if (i == NULL) return NULL;
+
+ if (flags & DC_EXEC) {
+ CheckIfCanLevelIndustryPlatform(tile, DC_EXEC, it, type);
+ DoCreateNewIndustry(i, tile, type, it, t, OWNER_NONE);
+ }
+
+ return i;
+}
+
+/** Build/Fund an industry
+ * @param tile tile where industry is built
+ * @param p1 industry type @see build_industry.h and @see industry.h
+ * @param p2 unused
+ */
+int32 CmdBuildIndustry(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ int num;
+ const IndustryTileTable * const *itt;
+ const IndustryTileTable *it;
+ const IndustrySpec *indspec;
+
+ SET_EXPENSES_TYPE(EXPENSES_OTHER);
+
+ indspec = GetIndustrySpec(p1);
+
+ /* Check if the to-be built/founded industry is available for this climate. */
+ if (!HASBIT(indspec->climate_availability, _opt_ptr->landscape)) return CMD_ERROR;
+
+ /* If the patch for raw-material industries is not on, you cannot build raw-material industries.
+ * Raw material industries are industries that do not accept cargo (at least for now)
+ * Exclude the lumber mill (only "raw" industry that can be built) */
+ if (!_patches.build_rawmaterial_ind &&
+ indspec->accepts_cargo[0] == CT_INVALID &&
+ indspec->accepts_cargo[1] == CT_INVALID &&
+ indspec->accepts_cargo[2] == CT_INVALID &&
+ p1 != IT_LUMBER_MILL) {
+ return CMD_ERROR;
+ }
+
+ num = indspec->num_table;
+ itt = indspec->table;
+
+ do {
+ if (--num < 0) return_cmd_error(STR_0239_SITE_UNSUITABLE);
+ } while (!CheckIfIndustryTilesAreFree(tile, it = itt[num], p1));
+
+ if (CreateNewIndustryHelper(tile, p1, flags, indspec, it) == NULL) return CMD_ERROR;
+
+ return (_price.build_industry >> 5) * indspec->cost_multiplier;
+}
+
+
+Industry *CreateNewIndustry(TileIndex tile, IndustryType type)
+{
+ const IndustrySpec *indspec = GetIndustrySpec(type);
+ const IndustryTileTable *it = indspec->table[RandomRange(indspec->num_table)];
+
+ return CreateNewIndustryHelper(tile, type, DC_EXEC, indspec, it);
+}
+
+static const byte _numof_industry_table[4][12] = {
+ // difficulty settings for number of industries
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //none
+ {0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5}, //low
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, //normal
+ {0, 2, 3, 4, 6, 7, 8, 9, 10, 10, 10}, //high
+};
+
+static void PlaceInitialIndustry(IndustryType type, int amount)
+{
+ int num = _numof_industry_table[_opt.diff.number_industries][amount];
+
+ if (type == IT_OIL_REFINERY || type == IT_OIL_RIG) {
+ // These are always placed next to the coastline, so we scale by the perimeter instead.
+ num = ScaleByMapSize1D(num);
+ } else {
+ num = ScaleByMapSize(num);
+ }
+
+ if (_opt.diff.number_industries != 0) {
+ PlayerID old_player = _current_player;
+ _current_player = OWNER_NONE;
+ assert(num > 0);
+
+ do {
+ uint i;
+
+ IncreaseGeneratingWorldProgress(GWP_INDUSTRY);
+
+ for (i = 0; i < 2000; i++) {
+ if (CreateNewIndustry(RandomTile(), type) != NULL) break;
+ }
+ } while (--num);
+
+ _current_player = old_player;
+ }
+}
+
+void GenerateIndustries(void)
+{
+ const byte *b;
+ uint i = 0;
+
+ /* Find the total amount of industries */
+ b = _industry_create_table[_opt.landscape];
+ do {
+ int num = _numof_industry_table[_opt.diff.number_industries][b[0]];
+
+ if (b[1] == IT_OIL_REFINERY || b[1] == IT_OIL_RIG) {
+ /* These are always placed next to the coastline, so we scale by the perimeter instead. */
+ num = ScaleByMapSize1D(num);
+ } else {
+ num = ScaleByMapSize(num);
+ }
+
+ i += num;
+ } while ( (b+=2)[0] != 0);
+ SetGeneratingWorldProgress(GWP_INDUSTRY, i);
+
+ b = _industry_create_table[_opt.landscape];
+ do {
+ PlaceInitialIndustry(b[1], b[0]);
+ } while ( (b+=2)[0] != 0);
+}
+
+/* Change industry production or do closure */
+static void ExtChangeIndustryProduction(Industry *i)
+{
+ bool closeit = true;
+ int j;
+ const IndustrySpec *indspec = GetIndustrySpec(i->type);
+
+ switch (indspec->life_type) {
+ case INDUSTRYLIFE_NOT_CLOSABLE:
+ return;
+
+ case INDUSTRYLIFE_CLOSABLE:
+ if ((byte)(_cur_year - i->last_prod_year) < 5 || !CHANCE16(1, 180))
+ closeit = false;
+ break;
+
+ default: /* INDUSTRY_PRODUCTION */
+ for (j = 0; j < 2 && i->produced_cargo[j] != CT_INVALID; j++){
+ uint32 r = Random();
+ int old, new, percent;
+ int mag;
+
+ new = old = i->production_rate[j];
+ if (CHANCE16I(20, 1024, r))
+ new -= ((RandomRange(50) + 10) * old) >> 8;
+ if (CHANCE16I(20 + (i->pct_transported[j] * 20 >> 8), 1024, r >> 16))
+ new += ((RandomRange(50) + 10) * old) >> 8;
+
+ new = clamp(new, 0, 255);
+ if (new == old) {
+ closeit = false;
+ continue;
+ }
+
+ percent = new * 100 / old - 100;
+ i->production_rate[j] = new;
+
+ if (new >= indspec->production_rate[j] / 4)
+ closeit = false;
+
+ mag = abs(percent);
+ if (mag >= 10) {
+ SetDParam(2, mag);
+ SetDParam(0, _cargoc.names_s[i->produced_cargo[j]]);
+ SetDParam(1, i->index);
+ AddNewsItem(
+ percent >= 0 ? STR_INDUSTRY_PROD_GOUP : STR_INDUSTRY_PROD_GODOWN,
+ NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_TILE, NT_ECONOMY, 0),
+ i->xy + TileDiffXY(1, 1), 0
+ );
+ }
+ }
+ break;
+ }
+
+ /* If industry will be closed down, show this */
+ if (closeit) {
+ i->prod_level = 0;
+ SetDParam(0, i->index);
+ AddNewsItem(
+ indspec->closure_text,
+ NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_TILE, NT_ECONOMY, 0),
+ i->xy + TileDiffXY(1, 1), 0
+ );
+ }
+}
+
+
+static void UpdateIndustryStatistics(Industry *i)
+{
+ byte pct;
+
+ if (i->produced_cargo[0] != CT_INVALID) {
+ pct = 0;
+ if (i->last_mo_production[0] != 0) {
+ i->last_prod_year = _cur_year;
+ pct = min(i->last_mo_transported[0] * 256 / i->last_mo_production[0],255);
+ }
+ i->pct_transported[0] = pct;
+
+ i->total_production[0] = i->last_mo_production[0];
+ i->last_mo_production[0] = 0;
+
+ i->total_transported[0] = i->last_mo_transported[0];
+ i->last_mo_transported[0] = 0;
+ }
+
+ if (i->produced_cargo[1] != CT_INVALID) {
+ pct = 0;
+ if (i->last_mo_production[1] != 0) {
+ i->last_prod_year = _cur_year;
+ pct = min(i->last_mo_transported[1] * 256 / i->last_mo_production[1],255);
+ }
+ i->pct_transported[1] = pct;
+
+ i->total_production[1] = i->last_mo_production[1];
+ i->last_mo_production[1] = 0;
+
+ i->total_transported[1] = i->last_mo_transported[1];
+ i->last_mo_transported[1] = 0;
+ }
+
+
+ if (i->produced_cargo[0] != CT_INVALID || i->produced_cargo[1] != CT_INVALID)
+ InvalidateWindow(WC_INDUSTRY_VIEW, i->index);
+
+ if (i->prod_level == 0) {
+ DeleteIndustry(i);
+ } else if (_patches.smooth_economy) {
+ ExtChangeIndustryProduction(i);
+ }
+}
+
+static const byte _new_industry_rand[4][32] = {
+ {12, 12, 12, 12, 12, 12, 12, 0, 0, 6, 6, 9, 9, 3, 3, 3, 18, 18, 4, 4, 2, 2, 5, 5, 5, 5, 5, 5, 1, 1, 8, 8},
+ {16, 16, 16, 0, 0, 0, 9, 9, 9, 9, 13, 13, 3, 3, 3, 3, 15, 15, 15, 4, 4, 11, 11, 11, 11, 11, 14, 14, 1, 1, 7, 7},
+ {21, 21, 21, 24, 22, 22, 22, 22, 23, 23, 16, 16, 16, 4, 4, 19, 19, 19, 13, 13, 20, 20, 20, 11, 11, 11, 17, 17, 17, 10, 10, 10},
+ {30, 30, 30, 36, 36, 31, 31, 31, 27, 27, 27, 28, 28, 28, 26, 26, 26, 34, 34, 34, 35, 35, 35, 29, 29, 29, 32, 32, 32, 33, 33, 33},
+};
+
+static void MaybeNewIndustry(uint32 r)
+{
+ int type;
+ int j;
+ Industry *i;
+
+ type = _new_industry_rand[_opt.landscape][GB(r, 16, 5)];
+
+ if (type == IT_OIL_WELL && _cur_year > 1950) return;
+ if (type == IT_OIL_RIG && _cur_year < 1960) return;
+
+ j = 2000;
+ for (;;) {
+ i = CreateNewIndustry(RandomTile(), type);
+ if (i != NULL) break;
+ if (--j == 0) return;
+ }
+
+ SetDParam(0, GetIndustrySpec(type)->name);
+ SetDParam(1, i->town->index);
+ AddNewsItem(
+ (type != IT_FOREST && type != IT_FRUIT_PLANTATION && type != IT_RUBBER_PLANTATION && type != IT_COTTON_CANDY) ?
+ STR_482D_NEW_UNDER_CONSTRUCTION : STR_482E_NEW_BEING_PLANTED_NEAR,
+ NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_TILE, NT_ECONOMY,0), i->xy, 0
+ );
+}
+
+static void ChangeIndustryProduction(Industry *i)
+{
+ bool only_decrease = false;
+ StringID str = STR_NULL;
+ int type = i->type;
+ const IndustrySpec *indspec = GetIndustrySpec(type);
+
+ switch (indspec->life_type) {
+ case INDUSTRYLIFE_NOT_CLOSABLE:
+ return;
+
+ case INDUSTRYLIFE_PRODUCTION:
+ /* decrease or increase */
+ if (type == IT_OIL_WELL && _opt.landscape == LT_NORMAL)
+ only_decrease = true;
+
+ if (only_decrease || CHANCE16(1,3)) {
+ /* If you transport > 60%, 66% chance we increase, else 33% chance we increase */
+ if (!only_decrease && (i->pct_transported[0] > 153) != CHANCE16(1,3)) {
+ /* Increase production */
+ if (i->prod_level != 0x80) {
+ byte b;
+
+ i->prod_level <<= 1;
+
+ b = i->production_rate[0] * 2;
+ if (i->production_rate[0] >= 128)
+ b = 0xFF;
+ i->production_rate[0] = b;
+
+ b = i->production_rate[1] * 2;
+ if (i->production_rate[1] >= 128)
+ b = 0xFF;
+ i->production_rate[1] = b;
+
+ str = indspec->production_up_text;
+ }
+ } else {
+ /* Decrease production */
+ if (i->prod_level == 4) {
+ i->prod_level = 0;
+ str = indspec->closure_text;
+ } else {
+ i->prod_level >>= 1;
+ i->production_rate[0] = (i->production_rate[0] + 1) >> 1;
+ i->production_rate[1] = (i->production_rate[1] + 1) >> 1;
+
+ str = indspec->production_down_text;
+ }
+ }
+ }
+ break;
+
+ case INDUSTRYLIFE_CLOSABLE:
+ /* maybe close */
+ if ( (byte)(_cur_year - i->last_prod_year) >= 5 && CHANCE16(1,2)) {
+ i->prod_level = 0;
+ str = indspec->closure_text;
+ }
+ break;
+ }
+
+ if (str != STR_NULL) {
+ SetDParam(0, i->index);
+ AddNewsItem(str, NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_TILE, NT_ECONOMY, 0), i->xy + TileDiffXY(1, 1), 0);
+ }
+}
+
+void IndustryMonthlyLoop(void)
+{
+ Industry *i;
+ PlayerID old_player = _current_player;
+ _current_player = OWNER_NONE;
+
+ FOR_ALL_INDUSTRIES(i) {
+ UpdateIndustryStatistics(i);
+ }
+
+ /* 3% chance that we start a new industry */
+ if (CHANCE16(3, 100)) {
+ MaybeNewIndustry(Random());
+ } else if (!_patches.smooth_economy) {
+ i = GetRandomIndustry();
+ if (i != NULL) ChangeIndustryProduction(i);
+ }
+
+ _current_player = old_player;
+
+ // production-change
+ _industry_sort_dirty = true;
+ InvalidateWindow(WC_INDUSTRY_DIRECTORY, 0);
+}
+
+
+void InitializeIndustries(void)
+{
+ CleanPool(&_Industry_pool);
+ AddBlockToPool(&_Industry_pool);
+
+ _total_industries = 0;
+ _industry_sort_dirty = true;
+ _industry_sound_tile = 0;
+}
+
+const TileTypeProcs _tile_type_industry_procs = {
+ DrawTile_Industry, /* draw_tile_proc */
+ GetSlopeZ_Industry, /* get_slope_z_proc */
+ ClearTile_Industry, /* clear_tile_proc */
+ GetAcceptedCargo_Industry, /* get_accepted_cargo_proc */
+ GetTileDesc_Industry, /* get_tile_desc_proc */
+ GetTileTrackStatus_Industry, /* get_tile_track_status_proc */
+ ClickTile_Industry, /* click_tile_proc */
+ AnimateTile_Industry, /* animate_tile_proc */
+ TileLoop_Industry, /* tile_loop_proc */
+ ChangeTileOwner_Industry, /* change_tile_owner_proc */
+ GetProducedCargo_Industry, /* get_produced_cargo_proc */
+ NULL, /* vehicle_enter_tile_proc */
+ GetSlopeTileh_Industry, /* get_slope_tileh_proc */
+};
+
+static const SaveLoad _industry_desc[] = {
+ SLE_CONDVAR(Industry, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+ SLE_CONDVAR(Industry, xy, SLE_UINT32, 6, SL_MAX_VERSION),
+ SLE_VAR(Industry, width, SLE_UINT8),
+ SLE_VAR(Industry, height, SLE_UINT8),
+ SLE_REF(Industry, town, REF_TOWN),
+ SLE_ARR(Industry, produced_cargo, SLE_UINT8, 2),
+ SLE_ARR(Industry, cargo_waiting, SLE_UINT16, 2),
+ SLE_ARR(Industry, production_rate, SLE_UINT8, 2),
+ SLE_ARR(Industry, accepts_cargo, SLE_UINT8, 3),
+ SLE_VAR(Industry, prod_level, SLE_UINT8),
+ SLE_ARR(Industry, last_mo_production, SLE_UINT16, 2),
+ SLE_ARR(Industry, last_mo_transported, SLE_UINT16, 2),
+ SLE_ARR(Industry, pct_transported, SLE_UINT8, 2),
+ SLE_ARR(Industry, total_production, SLE_UINT16, 2),
+ SLE_ARR(Industry, total_transported, SLE_UINT16, 2),
+
+ SLE_VAR(Industry, counter, SLE_UINT16),
+
+ SLE_VAR(Industry, type, SLE_UINT8),
+ SLE_VAR(Industry, owner, SLE_UINT8),
+ SLE_VAR(Industry, random_color, SLE_UINT8),
+ SLE_CONDVAR(Industry, last_prod_year, SLE_FILE_U8 | SLE_VAR_I32, 0, 30),
+ SLE_CONDVAR(Industry, last_prod_year, SLE_INT32, 31, SL_MAX_VERSION),
+ SLE_VAR(Industry, was_cargo_delivered, SLE_UINT8),
+
+ // reserve extra space in savegame here. (currently 32 bytes)
+ SLE_CONDNULL(32, 2, SL_MAX_VERSION),
+
+ SLE_END()
+};
+
+static void Save_INDY(void)
+{
+ Industry *ind;
+
+ // Write the vehicles
+ FOR_ALL_INDUSTRIES(ind) {
+ SlSetArrayIndex(ind->index);
+ SlObject(ind, _industry_desc);
+ }
+}
+
+static void Load_INDY(void)
+{
+ int index;
+
+ _total_industries = 0;
+
+ while ((index = SlIterateArray()) != -1) {
+ Industry *i;
+
+ if (!AddBlockIfNeeded(&_Industry_pool, index))
+ error("Industries: failed loading savegame: too many industries");
+
+ i = GetIndustry(index);
+ SlObject(i, _industry_desc);
+
+ _total_industries++;
+ }
+}
+
+const ChunkHandler _industry_chunk_handlers[] = {
+ { 'INDY', Save_INDY, Load_INDY, CH_ARRAY | CH_LAST},
+};
diff --git a/src/industry_gui.c b/src/industry_gui.c
new file mode 100644
index 000000000..3e481ef88
--- /dev/null
+++ b/src/industry_gui.c
@@ -0,0 +1,693 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "debug.h"
+#include "functions.h"
+#include "strings.h"
+#include "table/strings.h"
+#include "table/sprites.h"
+#include "map.h"
+#include "gui.h"
+#include "window.h"
+#include "gfx.h"
+#include "command.h"
+#include "viewport.h"
+#include "industry.h"
+#include "town.h"
+#include "variables.h"
+
+const byte _build_industry_types[4][12] = {
+ { 1, 2, 4, 6, 8, 0, 3, 5, 9, 11, 18 },
+ { 1, 14, 4, 13, 7, 0, 3, 9, 11, 15 },
+ { 25, 13, 4, 23, 22, 11, 17, 10, 24, 19, 20, 21 },
+ { 27, 30, 31, 33, 26, 28, 29, 32, 34, 35, 36 },
+};
+
+static void UpdateIndustryProduction(Industry *i);
+
+static void BuildIndustryWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT:
+ DrawWindowWidgets(w);
+ if (_thd.place_mode == 1 && _thd.window_class == WC_BUILD_INDUSTRY) {
+ int ind_type = _build_industry_types[_opt_ptr->landscape][WP(w,def_d).data_1];
+
+ SetDParam(0, (_price.build_industry >> 5) * GetIndustrySpec(ind_type)->cost_multiplier);
+ DrawStringCentered(85, w->height - 21, STR_482F_COST, 0);
+ }
+ break;
+
+ case WE_CLICK: {
+ int wid = e->we.click.widget;
+ if (wid >= 3) {
+ if (HandlePlacePushButton(w, wid, SPR_CURSOR_INDUSTRY, 1, NULL))
+ WP(w,def_d).data_1 = wid - 3;
+ }
+ } break;
+
+ case WE_PLACE_OBJ:
+ if (DoCommandP(e->we.place.tile, _build_industry_types[_opt_ptr->landscape][WP(w,def_d).data_1], 0, NULL, CMD_BUILD_INDUSTRY | CMD_MSG(STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY)))
+ ResetObjectToPlace();
+ break;
+
+ case WE_ABORT_PLACE_OBJ:
+ RaiseWindowButtons(w);
+ break;
+ }
+}
+
+static const Widget _build_industry_land0_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 115, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_0241_POWER_STATION, STR_0263_CONSTRUCT_POWER_STATION},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 29, 40, STR_0242_SAWMILL, STR_0264_CONSTRUCT_SAWMILL},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_0244_OIL_REFINERY, STR_0266_CONSTRUCT_OIL_REFINERY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_0246_FACTORY, STR_0268_CONSTRUCT_FACTORY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 68, 79, STR_0247_STEEL_MILL, STR_0269_CONSTRUCT_STEEL_MILL},
+{ WIDGETS_END},
+};
+
+static const Widget _build_industry_land1_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 115, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_0241_POWER_STATION, STR_0263_CONSTRUCT_POWER_STATION},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 29, 40, STR_024C_PAPER_MILL, STR_026E_CONSTRUCT_PAPER_MILL},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_0244_OIL_REFINERY, STR_0266_CONSTRUCT_OIL_REFINERY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_024D_FOOD_PROCESSING_PLANT, STR_026F_CONSTRUCT_FOOD_PROCESSING},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 68, 79, STR_024E_PRINTING_WORKS, STR_0270_CONSTRUCT_PRINTING_WORKS},
+{ WIDGETS_END},
+};
+
+static const Widget _build_industry_land2_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 115, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_0250_LUMBER_MILL, STR_0273_CONSTRUCT_LUMBER_MILL_TO},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 29, 40, STR_024D_FOOD_PROCESSING_PLANT, STR_026F_CONSTRUCT_FOOD_PROCESSING},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_0244_OIL_REFINERY, STR_0266_CONSTRUCT_OIL_REFINERY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_0246_FACTORY, STR_0268_CONSTRUCT_FACTORY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 68, 79, STR_0254_WATER_TOWER, STR_0277_CONSTRUCT_WATER_TOWER_CAN},
+{ WIDGETS_END},
+};
+
+static const Widget _build_industry_land3_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 115, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_0258_CANDY_FACTORY, STR_027B_CONSTRUCT_CANDY_FACTORY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 29, 40, STR_025B_TOY_SHOP, STR_027E_CONSTRUCT_TOY_SHOP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_025C_TOY_FACTORY, STR_027F_CONSTRUCT_TOY_FACTORY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_025E_FIZZY_DRINK_FACTORY, STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY},
+{ WIDGETS_END},
+};
+
+static const Widget _build_industry_land0_widgets_extra[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 187, 0x0, STR_NULL},
+
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_0241_POWER_STATION, STR_0263_CONSTRUCT_POWER_STATION},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 29, 40, STR_0242_SAWMILL, STR_0264_CONSTRUCT_SAWMILL},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_0244_OIL_REFINERY, STR_0266_CONSTRUCT_OIL_REFINERY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_0246_FACTORY, STR_0268_CONSTRUCT_FACTORY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 68, 79, STR_0247_STEEL_MILL, STR_0269_CONSTRUCT_STEEL_MILL},
+
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 84, 95, STR_0240_COAL_MINE, STR_CONSTRUCT_COAL_MINE_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 97, 108, STR_0243_FOREST, STR_CONSTRUCT_FOREST_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 110, 121, STR_0245_OIL_RIG, STR_CONSTRUCT_OIL_RIG_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 123, 134, STR_0248_FARM, STR_CONSTRUCT_FARM_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 136, 147, STR_024A_OIL_WELLS, STR_CONSTRUCT_OIL_WELLS_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 149, 160, STR_0249_IRON_ORE_MINE, STR_CONSTRUCT_IRON_ORE_MINE_TIP},
+
+{ WIDGETS_END},
+};
+
+static const Widget _build_industry_land1_widgets_extra[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 174, 0x0, STR_NULL},
+
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_0241_POWER_STATION, STR_0263_CONSTRUCT_POWER_STATION},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 29, 40, STR_024C_PAPER_MILL, STR_026E_CONSTRUCT_PAPER_MILL},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_0244_OIL_REFINERY, STR_0266_CONSTRUCT_OIL_REFINERY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_024D_FOOD_PROCESSING_PLANT, STR_026F_CONSTRUCT_FOOD_PROCESSING},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 68, 79, STR_024E_PRINTING_WORKS, STR_0270_CONSTRUCT_PRINTING_WORKS},
+
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 84, 95, STR_0240_COAL_MINE, STR_CONSTRUCT_COAL_MINE_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 97, 108, STR_0243_FOREST, STR_CONSTRUCT_FOREST_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 110, 121, STR_0248_FARM, STR_CONSTRUCT_FARM_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 123, 134, STR_024A_OIL_WELLS, STR_CONSTRUCT_OIL_WELLS_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 136, 147, STR_024F_GOLD_MINE, STR_CONSTRUCT_GOLD_MINE_TIP},
+{ WIDGETS_END},
+};
+
+static const Widget _build_industry_land2_widgets_extra[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 200, 0x0, STR_NULL},
+
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_0250_LUMBER_MILL, STR_0273_CONSTRUCT_LUMBER_MILL_TO},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 29, 40, STR_024D_FOOD_PROCESSING_PLANT, STR_026F_CONSTRUCT_FOOD_PROCESSING},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_0244_OIL_REFINERY, STR_0266_CONSTRUCT_OIL_REFINERY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_0246_FACTORY, STR_0268_CONSTRUCT_FACTORY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 68, 79, STR_0254_WATER_TOWER, STR_0277_CONSTRUCT_WATER_TOWER_CAN},
+
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 84, 95, STR_024A_OIL_WELLS, STR_CONSTRUCT_OIL_WELLS_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 97, 108, STR_0255_DIAMOND_MINE, STR_CONSTRUCT_DIAMOND_MINE_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 110, 121, STR_0256_COPPER_ORE_MINE, STR_CONSTRUCT_COPPER_ORE_MINE_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 123, 134, STR_0248_FARM, STR_CONSTRUCT_FARM_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 136, 147, STR_0251_FRUIT_PLANTATION, STR_CONSTRUCT_FRUIT_PLANTATION_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 149, 160, STR_0252_RUBBER_PLANTATION, STR_CONSTRUCT_RUBBER_PLANTATION_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 162, 173, STR_0253_WATER_SUPPLY, STR_CONSTRUCT_WATER_SUPPLY_TIP},
+{ WIDGETS_END},
+};
+
+static const Widget _build_industry_land3_widgets_extra[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 187, 0x0, STR_NULL},
+
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_0258_CANDY_FACTORY, STR_027B_CONSTRUCT_CANDY_FACTORY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 29, 40, STR_025B_TOY_SHOP, STR_027E_CONSTRUCT_TOY_SHOP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_025C_TOY_FACTORY, STR_027F_CONSTRUCT_TOY_FACTORY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_025E_FIZZY_DRINK_FACTORY, STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY},
+
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 71, 82, STR_0257_COTTON_CANDY_FOREST, STR_CONSTRUCT_COTTON_CANDY_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 84, 95, STR_0259_BATTERY_FARM, STR_CONSTRUCT_BATTERY_FARM_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 97, 108, STR_025A_COLA_WELLS, STR_CONSTRUCT_COLA_WELLS_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 110, 121, STR_025D_PLASTIC_FOUNTAINS, STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 123, 134, STR_025F_BUBBLE_GENERATOR, STR_CONSTRUCT_BUBBLE_GENERATOR_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 136, 147, STR_0260_TOFFEE_QUARRY, STR_CONSTRUCT_TOFFEE_QUARRY_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 149, 160, STR_0261_SUGAR_MINE, STR_CONSTRUCT_SUGAR_MINE_TIP},
+{ WIDGETS_END},
+};
+
+
+static const WindowDesc _build_industry_land0_desc = {
+ WDP_AUTO, WDP_AUTO, 170, 116,
+ WC_BUILD_INDUSTRY,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _build_industry_land0_widgets,
+ BuildIndustryWndProc
+};
+
+static const WindowDesc _build_industry_land1_desc = {
+ WDP_AUTO, WDP_AUTO, 170, 116,
+ WC_BUILD_INDUSTRY,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _build_industry_land1_widgets,
+ BuildIndustryWndProc
+};
+
+static const WindowDesc _build_industry_land2_desc = {
+ WDP_AUTO, WDP_AUTO, 170, 116,
+ WC_BUILD_INDUSTRY,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _build_industry_land2_widgets,
+ BuildIndustryWndProc
+};
+
+static const WindowDesc _build_industry_land3_desc = {
+ WDP_AUTO, WDP_AUTO, 170, 116,
+ WC_BUILD_INDUSTRY,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _build_industry_land3_widgets,
+ BuildIndustryWndProc
+};
+
+static const WindowDesc _build_industry_land0_desc_extra = {
+ WDP_AUTO, WDP_AUTO, 170, 188,
+ WC_BUILD_INDUSTRY,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _build_industry_land0_widgets_extra,
+ BuildIndustryWndProc
+};
+
+static const WindowDesc _build_industry_land1_desc_extra = {
+ WDP_AUTO, WDP_AUTO, 170, 175,
+ WC_BUILD_INDUSTRY,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _build_industry_land1_widgets_extra,
+ BuildIndustryWndProc
+};
+
+static const WindowDesc _build_industry_land2_desc_extra = {
+ WDP_AUTO, WDP_AUTO, 170, 201,
+ WC_BUILD_INDUSTRY,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _build_industry_land2_widgets_extra,
+ BuildIndustryWndProc
+};
+
+static const WindowDesc _build_industry_land3_desc_extra = {
+ WDP_AUTO, WDP_AUTO, 170, 188,
+ WC_BUILD_INDUSTRY,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _build_industry_land3_widgets_extra,
+ BuildIndustryWndProc
+};
+
+static const WindowDesc * const _industry_window_desc[2][4] = {
+ {
+ &_build_industry_land0_desc,
+ &_build_industry_land1_desc,
+ &_build_industry_land2_desc,
+ &_build_industry_land3_desc,
+ },
+ {
+ &_build_industry_land0_desc_extra,
+ &_build_industry_land1_desc_extra,
+ &_build_industry_land2_desc_extra,
+ &_build_industry_land3_desc_extra,
+ },
+};
+
+void ShowBuildIndustryWindow(void)
+{
+ if (!IsValidPlayer(_current_player)) return;
+ AllocateWindowDescFront(_industry_window_desc[_patches.build_rawmaterial_ind][_opt_ptr->landscape],0);
+}
+
+static inline bool isProductionMinimum(const Industry *i, int pt) {
+ return i->production_rate[pt] == 1;
+}
+
+static inline bool isProductionMaximum(const Industry *i, int pt) {
+ return i->production_rate[pt] == 255;
+}
+
+static inline bool IsProductionAlterable(const Industry *i)
+{
+ return ((_game_mode == GM_EDITOR || _cheats.setup_prod.value) &&
+ (i->accepts_cargo[0] == CT_INVALID || i->accepts_cargo[0] == CT_VALUABLES));
+}
+
+static void IndustryViewWndProc(Window *w, WindowEvent *e)
+{
+ // WP(w,vp2_d).data_1 is for the editbox line
+ // WP(w,vp2_d).data_2 is for the clickline
+ // WP(w,vp2_d).data_3 is for the click pos (left or right)
+
+ switch (e->event) {
+ case WE_PAINT: {
+ const Industry *i = GetIndustry(w->window_number);
+
+ SetDParam(0, w->window_number);
+ DrawWindowWidgets(w);
+
+ if (i->accepts_cargo[0] != CT_INVALID) {
+ StringID str;
+
+ SetDParam(0, _cargoc.names_s[i->accepts_cargo[0]]);
+ str = STR_4827_REQUIRES;
+ if (i->accepts_cargo[1] != CT_INVALID) {
+ SetDParam(1, _cargoc.names_s[i->accepts_cargo[1]]);
+ str = STR_4828_REQUIRES;
+ if (i->accepts_cargo[2] != CT_INVALID) {
+ SetDParam(2, _cargoc.names_s[i->accepts_cargo[2]]);
+ str = STR_4829_REQUIRES;
+ }
+ }
+ DrawString(2, 107, str, 0);
+ }
+
+ if (i->produced_cargo[0] != CT_INVALID) {
+ DrawString(2, 117, STR_482A_PRODUCTION_LAST_MONTH, 0);
+
+ SetDParam(0, i->produced_cargo[0]);
+ SetDParam(1, i->total_production[0]);
+
+ SetDParam(2, i->pct_transported[0] * 100 >> 8);
+ DrawString(4 + (IsProductionAlterable(i) ? 30 : 0), 127, STR_482B_TRANSPORTED, 0);
+ // Let's put out those buttons..
+ if (IsProductionAlterable(i)) {
+ DrawArrowButtons(5, 127, 3, (WP(w,vp2_d).data_2 == 1) ? WP(w,vp2_d).data_3 : 0,
+ !isProductionMinimum(i, 0), !isProductionMaximum(i, 0));
+ }
+
+ if (i->produced_cargo[1] != CT_INVALID) {
+ SetDParam(0, i->produced_cargo[1]);
+ SetDParam(1, i->total_production[1]);
+ SetDParam(2, i->pct_transported[1] * 100 >> 8);
+ DrawString(4 + (IsProductionAlterable(i) ? 30 : 0), 137, STR_482B_TRANSPORTED, 0);
+ // Let's put out those buttons..
+ if (IsProductionAlterable(i)) {
+ DrawArrowButtons(5, 137, 3, (WP(w,vp2_d).data_2 == 2) ? WP(w,vp2_d).data_3 : 0,
+ !isProductionMinimum(i, 1), !isProductionMaximum(i, 1));
+ }
+ }
+ }
+
+ DrawWindowViewport(w);
+ }
+ break;
+
+ case WE_CLICK: {
+ Industry *i;
+
+ switch (e->we.click.widget) {
+ case 5: {
+ int line, x;
+
+ i = GetIndustry(w->window_number);
+
+ // We should work if needed..
+ if (!IsProductionAlterable(i)) return;
+
+ x = e->we.click.pt.x;
+ line = (e->we.click.pt.y - 127) / 10;
+ if (e->we.click.pt.y >= 127 && IS_INT_INSIDE(line, 0, 2) && i->produced_cargo[line] != CT_INVALID) {
+ if (IS_INT_INSIDE(x, 5, 25) ) {
+ /* Clicked buttons, decrease or increase production */
+ if (x < 15) {
+ if (isProductionMinimum(i, line)) return;
+ i->production_rate[line] = maxu(i->production_rate[line] / 2, 1);
+ } else {
+ if (isProductionMaximum(i, line)) return;
+ i->production_rate[line] = minu(i->production_rate[line] * 2, 255);
+ }
+
+ UpdateIndustryProduction(i);
+ SetWindowDirty(w);
+ w->flags4 |= 5 << WF_TIMEOUT_SHL;
+ WP(w,vp2_d).data_2 = line+1;
+ WP(w,vp2_d).data_3 = (x < 15 ? 1 : 2);
+ } else if (IS_INT_INSIDE(x, 34, 160)) {
+ // clicked the text
+ WP(w,vp2_d).data_1 = line;
+ SetDParam(0, i->production_rate[line] * 8);
+ ShowQueryString(STR_CONFIG_PATCHES_INT32, STR_CONFIG_GAME_PRODUCTION, 10, 100, w, CS_ALPHANUMERAL);
+ }
+ }
+ } break;
+ case 6:
+ i = GetIndustry(w->window_number);
+ ScrollMainWindowToTile(i->xy + TileDiffXY(1, 1));
+ } break;
+
+ }
+ break;
+ case WE_TIMEOUT:
+ WP(w,vp2_d).data_2 = 0;
+ WP(w,vp2_d).data_3 = 0;
+ SetWindowDirty(w);
+ break;
+
+ case WE_ON_EDIT_TEXT:
+ if (e->we.edittext.str[0] != '\0') {
+ Industry* i = GetIndustry(w->window_number);
+ int line = WP(w,vp2_d).data_1;
+
+ i->production_rate[line] = clampu(atoi(e->we.edittext.str), 0, 255);
+ UpdateIndustryProduction(i);
+ SetWindowDirty(w);
+ }
+ }
+}
+
+static void UpdateIndustryProduction(Industry *i)
+{
+ if (i->produced_cargo[0] != CT_INVALID)
+ i->total_production[0] = 8 * i->production_rate[0];
+
+ if (i->produced_cargo[1] != CT_INVALID)
+ i->total_production[1] = 8 * i->production_rate[1];
+}
+
+static const Widget _industry_view_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 9, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 9, 11, 247, 0, 13, STR_4801, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_STICKYBOX, RESIZE_NONE, 9, 248, 259, 0, 13, 0x0, STR_STICKY_BUTTON},
+{ WWT_PANEL, RESIZE_NONE, 9, 0, 259, 14, 105, 0x0, STR_NULL},
+{ WWT_INSET, RESIZE_NONE, 9, 2, 257, 16, 103, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 9, 0, 259, 106, 147, 0x0, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 9, 0, 129, 148, 159, STR_00E4_LOCATION, STR_482C_CENTER_THE_MAIN_VIEW_ON},
+{ WWT_PANEL, RESIZE_NONE, 9, 130, 259, 148, 159, 0x0, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _industry_view_desc = {
+ WDP_AUTO, WDP_AUTO, 260, 160,
+ WC_INDUSTRY_VIEW,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON,
+ _industry_view_widgets,
+ IndustryViewWndProc
+};
+
+void ShowIndustryViewWindow(int industry)
+{
+ Window *w = AllocateWindowDescFront(&_industry_view_desc, industry);
+
+ if (w != NULL) {
+ w->flags4 |= WF_DISABLE_VP_SCROLL;
+ WP(w,vp2_d).data_1 = 0;
+ WP(w,vp2_d).data_2 = 0;
+ WP(w,vp2_d).data_3 = 0;
+ AssignWindowViewport(w, 3, 17, 0xFE, 0x56, GetIndustry(w->window_number)->xy + TileDiffXY(1, 1), 1);
+ }
+}
+
+static const Widget _industry_directory_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 13, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 13, 11, 495, 0, 13, STR_INDUSTRYDIR_CAPTION, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_STICKYBOX, RESIZE_NONE, 13, 496, 507, 0, 13, 0x0, STR_STICKY_BUTTON},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 13, 0, 100, 14, 25, STR_SORT_BY_NAME, STR_SORT_ORDER_TIP},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 13, 101, 200, 14, 25, STR_SORT_BY_TYPE, STR_SORT_ORDER_TIP},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 13, 201, 300, 14, 25, STR_SORT_BY_PRODUCTION, STR_SORT_ORDER_TIP},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 13, 301, 400, 14, 25, STR_SORT_BY_TRANSPORTED, STR_SORT_ORDER_TIP},
+{ WWT_PANEL, RESIZE_NONE, 13, 401, 495, 14, 25, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_BOTTOM, 13, 0, 495, 26, 189, 0x0, STR_200A_TOWN_NAMES_CLICK_ON_NAME},
+{ WWT_SCROLLBAR, RESIZE_BOTTOM, 13, 496, 507, 14, 177, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WWT_RESIZEBOX, RESIZE_TB, 13, 496, 507, 178, 189, 0x0, STR_RESIZE_BUTTON},
+{ WIDGETS_END},
+};
+
+static uint _num_industry_sort;
+
+static char _bufcache[96];
+static const Industry* _last_industry;
+
+static byte _industry_sort_order;
+
+static int CDECL GeneralIndustrySorter(const void *a, const void *b)
+{
+ const Industry* i = *(const Industry**)a;
+ const Industry* j = *(const Industry**)b;
+ int r;
+
+ switch (_industry_sort_order >> 1) {
+ default: NOT_REACHED();
+ case 0: /* Sort by Name (handled later) */
+ r = 0;
+ break;
+
+ case 1: /* Sort by Type */
+ r = i->type - j->type;
+ break;
+
+ case 2: /* Sort by Production */
+ if (i->produced_cargo[0] == CT_INVALID) {
+ r = (j->produced_cargo[0] == CT_INVALID ? 0 : -1);
+ } else {
+ if (j->produced_cargo[0] == CT_INVALID) {
+ r = 1;
+ } else {
+ r =
+ (i->total_production[0] + i->total_production[1]) -
+ (j->total_production[0] + j->total_production[1]);
+ }
+ }
+ break;
+
+ case 3: /* Sort by transported fraction */
+ if (i->produced_cargo[0] == CT_INVALID) {
+ r = (j->produced_cargo[0] == CT_INVALID ? 0 : -1);
+ } else {
+ if (j->produced_cargo[0] == CT_INVALID) {
+ r = 1;
+ } else {
+ int pi;
+ int pj;
+
+ pi = i->pct_transported[0] * 100 >> 8;
+ if (i->produced_cargo[1] != CT_INVALID) {
+ int p = i->pct_transported[1] * 100 >> 8;
+ if (p < pi) pi = p;
+ }
+
+ pj = j->pct_transported[0] * 100 >> 8;
+ if (j->produced_cargo[1] != CT_INVALID) {
+ int p = j->pct_transported[1] * 100 >> 8;
+ if (p < pj) pj = p;
+ }
+
+ r = pi - pj;
+ }
+ }
+ break;
+ }
+
+ // default to string sorting if they are otherwise equal
+ if (r == 0) {
+ char buf1[96];
+
+ SetDParam(0, i->town->index);
+ GetString(buf1, STR_TOWN, lastof(buf1));
+
+ if (j != _last_industry) {
+ _last_industry = j;
+ SetDParam(0, j->town->index);
+ GetString(_bufcache, STR_TOWN, lastof(_bufcache));
+ }
+ r = strcmp(buf1, _bufcache);
+ }
+
+ if (_industry_sort_order & 1) r = -r;
+ return r;
+}
+
+static void MakeSortedIndustryList(void)
+{
+ const Industry* i;
+ int n = 0;
+
+ /* Don't attempt a sort if there are no industries */
+ if (GetNumIndustries() == 0) return;
+
+ /* Create array for sorting */
+ _industry_sort = realloc((void *)_industry_sort, (GetMaxIndustryIndex() + 1) * sizeof(_industry_sort[0]));
+ if (_industry_sort == NULL) error("Could not allocate memory for the industry-sorting-list");
+
+ FOR_ALL_INDUSTRIES(i) _industry_sort[n++] = i;
+
+ _num_industry_sort = n;
+ _last_industry = NULL; // used for "cache"
+
+ qsort((void*)_industry_sort, n, sizeof(_industry_sort[0]), GeneralIndustrySorter);
+
+ DEBUG(misc, 3, "Resorting industries list");
+}
+
+
+static void IndustryDirectoryWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ int n;
+ uint p;
+ static const uint16 _indicator_positions[4] = {88, 187, 284, 387};
+
+ if (_industry_sort_dirty) {
+ _industry_sort_dirty = false;
+ MakeSortedIndustryList();
+ }
+
+ SetVScrollCount(w, _num_industry_sort);
+
+ DrawWindowWidgets(w);
+ DoDrawString(_industry_sort_order & 1 ? DOWNARROW : UPARROW, _indicator_positions[_industry_sort_order>>1], 15, 0x10);
+
+ p = w->vscroll.pos;
+ n = 0;
+
+ while (p < _num_industry_sort) {
+ const Industry* i = _industry_sort[p];
+
+ SetDParam(0, i->index);
+ if (i->produced_cargo[0] != CT_INVALID) {
+ SetDParam(1, i->produced_cargo[0]);
+ SetDParam(2, i->total_production[0]);
+
+ if (i->produced_cargo[1] != CT_INVALID) {
+ SetDParam(3, i->produced_cargo[1]);
+ SetDParam(4, i->total_production[1]);
+ SetDParam(5, i->pct_transported[0] * 100 >> 8);
+ SetDParam(6, i->pct_transported[1] * 100 >> 8);
+ DrawString(4, 28+n*10, STR_INDUSTRYDIR_ITEM_TWO, 0);
+ } else {
+ SetDParam(3, i->pct_transported[0] * 100 >> 8);
+ DrawString(4, 28+n*10, STR_INDUSTRYDIR_ITEM, 0);
+ }
+ } else {
+ DrawString(4, 28+n*10, STR_INDUSTRYDIR_ITEM_NOPROD, 0);
+ }
+ p++;
+ if (++n == w->vscroll.cap) break;
+ }
+ } break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 3: {
+ _industry_sort_order = _industry_sort_order==0 ? 1 : 0;
+ _industry_sort_dirty = true;
+ SetWindowDirty(w);
+ } break;
+
+ case 4: {
+ _industry_sort_order = _industry_sort_order==2 ? 3 : 2;
+ _industry_sort_dirty = true;
+ SetWindowDirty(w);
+ } break;
+
+ case 5: {
+ _industry_sort_order = _industry_sort_order==4 ? 5 : 4;
+ _industry_sort_dirty = true;
+ SetWindowDirty(w);
+ } break;
+
+ case 6: {
+ _industry_sort_order = _industry_sort_order==6 ? 7 : 6;
+ _industry_sort_dirty = true;
+ SetWindowDirty(w);
+ } break;
+
+ case 8: {
+ int y = (e->we.click.pt.y - 28) / 10;
+ uint16 p;
+
+ if (!IS_INT_INSIDE(y, 0, w->vscroll.cap)) return;
+ p = y + w->vscroll.pos;
+ if (p < _num_industry_sort) {
+ ScrollMainWindowToTile(_industry_sort[p]->xy);
+ }
+ } break;
+ }
+ break;
+
+ case WE_4:
+ SetWindowDirty(w);
+ break;
+
+ case WE_RESIZE:
+ w->vscroll.cap += e->we.sizing.diff.y / 10;
+ break;
+ }
+}
+
+
+/* Industry List */
+static const WindowDesc _industry_directory_desc = {
+ WDP_AUTO, WDP_AUTO, 508, 190,
+ WC_INDUSTRY_DIRECTORY,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
+ _industry_directory_widgets,
+ IndustryDirectoryWndProc
+};
+
+
+void ShowIndustryDirectory(void)
+{
+ Window *w = AllocateWindowDescFront(&_industry_directory_desc, 0);
+
+ if (w != NULL) {
+ w->vscroll.cap = 16;
+ w->resize.height = w->height - 6 * 10; // minimum 10 items
+ w->resize.step_height = 10;
+ SetWindowDirty(w);
+ }
+}
diff --git a/src/industry_map.h b/src/industry_map.h
new file mode 100644
index 000000000..5a3512fd3
--- /dev/null
+++ b/src/industry_map.h
@@ -0,0 +1,259 @@
+/* $Id$ */
+
+/** @file industry_map.h Accessors for industries */
+
+#ifndef INDUSTRY_MAP_H
+#define INDUSTRY_MAP_H
+
+#include "industry.h"
+#include "macros.h"
+#include "tile.h"
+
+
+
+/**
+ * The following enums are indices used to know what to draw for this industry tile.
+ * They all are pointing toward array _industry_draw_tile_data, in table/industry_land.h
+ * How to calculate the correct position ? GFXid << 2 | IndustryStage (0 to 3)
+ */
+enum {
+ GFX_COAL_MINE_TOWER_NOT_ANIMATED = 0,
+ GFX_COAL_MINE_TOWER_ANIMATED = 1,
+ GFX_POWERPLANT_CHIMNEY = 8,
+ GFX_POWERPLANT_SPARKS = 10,
+ GFX_OILRIG_1 = 24,
+ GFX_OILRIG_2 = 25,
+ GFX_OILRIG_3 = 26,
+ GFX_OILRIG_4 = 27,
+ GFX_OILRIG_5 = 28,
+ GFX_OILWELL_NOT_ANIMATED = 29,
+ GFX_OILWELL_ANIMATED_1 = 30,
+ GFX_OILWELL_ANIMATED_2 = 31,
+ GFX_OILWELL_ANIMATED_3 = 32,
+ GFX_COPPER_MINE_TOWER_NOT_ANIMATED = 47,
+ GFX_COPPER_MINE_TOWER_ANIMATED = 48,
+ GFX_COPPER_MINE_CHIMNEY = 49,
+ GFX_GOLD_MINE_TOWER_NOT_ANIMATED = 79,
+ GFX_GOLD_MINE_TOWER_ANIMATED = 88,
+ GFX_TOY_FACTORY = 143,
+ GFX_PLASTIC_FOUNTAIN_ANIMATED_1 = 148,
+ GFX_PLASTIC_FOUNTAIN_ANIMATED_2 = 149,
+ GFX_PLASTIC_FOUNTAIN_ANIMATED_3 = 150,
+ GFX_PLASTIC_FOUNTAIN_ANIMATED_4 = 151,
+ GFX_PLASTIC_FOUNTAIN_ANIMATED_5 = 152,
+ GFX_PLASTIC_FOUNTAIN_ANIMATED_6 = 153,
+ GFX_PLASTIC_FOUNTAIN_ANIMATED_7 = 154,
+ GFX_PLASTIC_FOUNTAIN_ANIMATED_8 = 155,
+ GFX_BUBBLE_GENERATOR = 161,
+ GFX_BUBBLE_CATCHER = 162,
+ GFX_TOFFEE_QUARY = 165,
+ GFX_SUGAR_MINE_SIEVE = 174,
+ NUM_INDUSTRY_GFXES = 175,
+};
+
+static inline IndustryID GetIndustryIndex(TileIndex t)
+{
+ assert(IsTileType(t, MP_INDUSTRY));
+ return _m[t].m2;
+}
+
+static inline Industry* GetIndustryByTile(TileIndex t)
+{
+ return GetIndustry(GetIndustryIndex(t));
+}
+
+static inline bool IsIndustryCompleted(TileIndex t)
+{
+ assert(IsTileType(t, MP_INDUSTRY));
+ return HASBIT(_m[t].m1, 7);
+}
+
+IndustryType GetIndustryType(TileIndex tile);
+
+/**
+ * Set if the industry that owns the tile as under construction or not
+ * @param tile the tile to query
+ * @param isCompleted whether it is completed or not
+ * @pre IsTileType(tile, MP_INDUSTRY)
+ */
+static inline void SetIndustryCompleted(TileIndex tile, bool isCompleted)
+{
+ assert(IsTileType(tile, MP_INDUSTRY));
+ SB(_m[tile].m1, 7, 1, isCompleted ? 1 :0);
+}
+
+/**
+ * Returns the industry construction stage of the specified tile
+ * @param tile the tile to query
+ * @pre IsTileType(tile, MP_INDUSTRY)
+ * @return the construction stage
+ */
+static inline byte GetIndustryConstructionStage(TileIndex tile)
+{
+ assert(IsTileType(tile, MP_INDUSTRY));
+ return GB(_m[tile].m1, 0, 2);
+}
+
+/**
+ * Sets the industry construction stage of the specified tile
+ * @param tile the tile to query
+ * @param value the new construction stage
+ * @pre IsTileType(tile, MP_INDUSTRY)
+ */
+static inline void SetIndustryConstructionStage(TileIndex tile, byte value)
+{
+ assert(IsTileType(tile, MP_INDUSTRY));
+ SB(_m[tile].m1, 0, 2, value);
+}
+
+static inline IndustryGfx GetIndustryGfx(TileIndex t)
+{
+ assert(IsTileType(t, MP_INDUSTRY));
+ return _m[t].m5;
+}
+
+static inline void SetIndustryGfx(TileIndex t, IndustryGfx gfx)
+{
+ assert(IsTileType(t, MP_INDUSTRY));
+ _m[t].m5 = gfx;
+}
+
+static inline void MakeIndustry(TileIndex t, IndustryID index, IndustryGfx gfx)
+{
+ SetTileType(t, MP_INDUSTRY);
+ _m[t].m1 = 0;
+ _m[t].m2 = index;
+ _m[t].m3 = 0;
+ _m[t].m4 = 0;
+ _m[t].m5 = gfx;
+}
+
+/**
+ * Returns this indutry tile's construction counter value
+ * @param tile the tile to query
+ * @pre IsTileType(tile, MP_INDUSTRY)
+ * @return the construction counter
+ */
+static inline byte GetIndustryConstructionCounter(TileIndex tile)
+{
+ assert(IsTileType(tile, MP_INDUSTRY));
+ return GB(_m[tile].m1, 2, 2);
+}
+
+/**
+ * Sets this indutry tile's construction counter value
+ * @param tile the tile to query
+ * @param value the new value for the construction counter
+ * @pre IsTileType(tile, MP_INDUSTRY)
+ */
+static inline void SetIndustryConstructionCounter(TileIndex tile, byte value)
+{
+ assert(IsTileType(tile, MP_INDUSTRY));
+ SB(_m[tile].m1, 2, 2, value);
+}
+
+/**
+ * Reset the construction stage counter of the industry,
+ * as well as the completion bit.
+ * In fact, it is the same as restarting construction frmo ground up
+ * @param tile the tile to query
+ * @param generating_world whether generating a world or not
+ * @pre IsTileType(tile, MP_INDUSTRY)
+ */
+static inline void ResetIndustryConstructionStage(TileIndex tile)
+{
+ assert(IsTileType(tile, MP_INDUSTRY));
+ _m[tile].m1 = 0;
+}
+
+typedef struct IndustryTypeSolver {
+ IndustryGfx MinGfx;
+ IndustryGfx MaxGfx;
+} IndustryTypeSolver;
+
+static const IndustryTypeSolver industry_gfx_Solver [IT_END] = {
+ { 0, 6}, //IT_COAL_MINE
+ { 7, 10}, //IT_POWER_STATION,
+ { 11, 15}, //IT_SAWMILL,
+ { 16, 17}, //IT_FOREST,
+ { 18, 23}, //IT_OIL_REFINERY,
+ { 24, 28}, //IT_OIL_RIG,
+ { 29, 31}, //IT_OIL_WELL,
+ { 32, 38}, //IT_FARM,
+ { 39, 42}, //IT_FACTORY,
+ { 43, 46}, //IT_PRINTING_WORKS,
+ { 47, 51}, //IT_COPPER_MINE,
+ { 52, 57}, //IT_STEEL_MILL,
+ { 58, 59}, //IT_BANK_TEMP,
+ { 60, 63}, //IT_FOOD_PROCESS,
+ { 64, 71}, //IT_PAPER_MILL,
+ { 72, 88}, //IT_GOLD_MINE,
+ { 89, 90}, //IT_BANK_TROPIC_ARCTIC,
+ { 91, 99}, //IT_DIAMOND_MINE,
+ {100, 115}, //IT_IRON_MINE,
+ {116, 116}, //IT_FRUIT_PLANTATION,
+ {117, 117}, //IT_RUBBER_PLANTATION,
+ {118, 119}, //IT_WATER_SUPPLY,
+ {120, 120}, //IT_WATER_TOWER,
+ {121, 124}, //IT_FACTORY_2,
+ {125, 128}, //IT_LUMBER_MILL,
+ {129, 130}, //IT_COTTON_CANDY,
+ {131, 134}, //IT_CANDY_FACTORY or sweet factory
+ {135, 136}, //IT_BATTERY_FARM,
+ {137, 137}, //IT_COLA_WELLS,
+ {138, 141}, //IT_TOY_SHOP,
+ {142, 147}, //IT_TOY_FACTORY,
+ {148, 155}, //IT_PLASTIC_FOUNTAINS,
+ {156, 159}, //IT_FIZZY_DRINK_FACTORY,
+ {160, 163}, //IT_BUBBLE_GENERATOR,
+ {164, 166}, //IT_TOFFEE_QUARRY,
+ {167, 174} //IT_SUGAR_MINE,
+};
+
+/**
+ * Get the animation loop number
+ * @param tile the tile to get the animation loop number of
+ * @pre IsTileType(tile, MP_INDUSTRY)
+ */
+static inline byte GetIndustryAnimationLoop(TileIndex tile)
+{
+ assert(IsTileType(tile, MP_INDUSTRY));
+ return _m[tile].m4;
+}
+
+/**
+ * Set the animation loop number
+ * @param tile the tile to set the animation loop number of
+ * @param count the new animation frame number
+ * @pre IsTileType(tile, MP_INDUSTRY)
+ */
+static inline void SetIndustryAnimationLoop(TileIndex tile, byte count)
+{
+ assert(IsTileType(tile, MP_INDUSTRY));
+ _m[tile].m4 = count;
+}
+
+/**
+ * Get the animation state
+ * @param tile the tile to get the animation state of
+ * @pre IsTileType(tile, MP_INDUSTRY)
+ */
+static inline byte GetIndustryAnimationState(TileIndex tile)
+{
+ assert(IsTileType(tile, MP_INDUSTRY));
+ return _m[tile].m3;
+}
+
+/**
+ * Set the animation state
+ * @param tile the tile to set the animation state of
+ * @param count the new animation state
+ * @pre IsTileType(tile, MP_INDUSTRY)
+ */
+static inline void SetIndustryAnimationState(TileIndex tile, byte state)
+{
+ assert(IsTileType(tile, MP_INDUSTRY));
+ _m[tile].m3 = state;
+}
+
+#endif /* INDUSTRY_MAP_H */
diff --git a/src/intro_gui.c b/src/intro_gui.c
new file mode 100644
index 000000000..5f78e3a65
--- /dev/null
+++ b/src/intro_gui.c
@@ -0,0 +1,149 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "table/strings.h"
+#include "table/sprites.h"
+#include "functions.h"
+#include "window.h"
+#include "gui.h"
+#include "gfx.h"
+#include "player.h"
+#include "network/network.h"
+#include "variables.h"
+#include "settings.h"
+#include "heightmap.h"
+#include "genworld.h"
+#include "network/network_gui.h"
+#include "newgrf.h"
+
+static const Widget _select_game_widgets[] = {
+{ WWT_CAPTION, RESIZE_NONE, 13, 0, 335, 0, 13, STR_0307_OPENTTD, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 13, 0, 335, 14, 194, 0x0, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 12, 10, 167, 22, 33, STR_0140_NEW_GAME, STR_02FB_START_A_NEW_GAME},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 12, 168, 325, 22, 33, STR_0141_LOAD_GAME, STR_02FC_LOAD_A_SAVED_GAME},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 12, 10, 167, 40, 51, STR_029A_PLAY_SCENARIO, STR_0303_START_A_NEW_GAME_USING},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 12, 168, 325, 40, 51, STR_PLAY_HEIGHTMAP, STR_PLAY_HEIGHTMAP_HINT},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 12, 10, 167, 58, 69, STR_0220_CREATE_SCENARIO, STR_02FE_CREATE_A_CUSTOMIZED_GAME},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 12, 168, 325, 58, 69, STR_MULTIPLAYER, STR_0300_SELECT_MULTIPLAYER_GAME},
+
+{ WWT_IMGBTN_2, RESIZE_NONE, 12, 10, 86, 77, 131, SPR_SELECT_TEMPERATE, STR_030E_SELECT_TEMPERATE_LANDSCAPE},
+{ WWT_IMGBTN_2, RESIZE_NONE, 12, 90, 166, 77, 131, SPR_SELECT_SUB_ARCTIC, STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE},
+{ WWT_IMGBTN_2, RESIZE_NONE, 12, 170, 246, 77, 131, SPR_SELECT_SUB_TROPICAL, STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE},
+{ WWT_IMGBTN_2, RESIZE_NONE, 12, 250, 326, 77, 131, SPR_SELECT_TOYLAND, STR_0311_SELECT_TOYLAND_LANDSCAPE},
+
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 12, 10, 167, 139, 150, STR_0148_GAME_OPTIONS, STR_0301_DISPLAY_GAME_OPTIONS},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 12, 168, 325, 139, 150, STR_01FE_DIFFICULTY, STR_0302_DISPLAY_DIFFICULTY_OPTIONS},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 12, 10, 167, 157, 168, STR_CONFIG_PATCHES, STR_CONFIG_PATCHES_TIP},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 12, 168, 325, 157, 168, STR_NEWGRF_SETTINGS_BUTTON, STR_NULL},
+
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 12, 104, 231, 175, 186, STR_0304_QUIT, STR_0305_QUIT_OPENTTD},
+{ WIDGETS_END},
+};
+
+static inline void SetNewLandscapeType(byte landscape)
+{
+ _opt_newgame.landscape = landscape;
+ InvalidateWindowClasses(WC_SELECT_GAME);
+}
+
+static void SelectGameWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_CREATE: LowerWindowWidget(w, _opt_newgame.landscape + 8); break;
+
+ case WE_PAINT:
+ SetWindowWidgetLoweredState(w, 8, _opt_newgame.landscape == LT_NORMAL);
+ SetWindowWidgetLoweredState(w, 9, _opt_newgame.landscape == LT_HILLY);
+ SetWindowWidgetLoweredState(w, 10, _opt_newgame.landscape == LT_DESERT);
+ SetWindowWidgetLoweredState(w, 11, _opt_newgame.landscape == LT_CANDY);
+ SetDParam(0, STR_6801_EASY + _opt_newgame.diff_level);
+ DrawWindowWidgets(w);
+ break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 2: ShowGenerateLandscape(); break;
+ case 3: ShowSaveLoadDialog(SLD_LOAD_GAME); break;
+ case 4: ShowSaveLoadDialog(SLD_LOAD_SCENARIO); break;
+ case 5: ShowSaveLoadDialog(SLD_LOAD_HEIGHTMAP); break;
+ case 6: ShowCreateScenario(); break;
+ case 7:
+ if (!_network_available) {
+ ShowErrorMessage(INVALID_STRING_ID, STR_NETWORK_ERR_NOTAVAILABLE, 0, 0);
+ } else {
+ ShowNetworkGameWindow();
+ }
+ break;
+ case 8: case 9: case 10: case 11:
+ RaiseWindowWidget(w, _opt_newgame.landscape + 8);
+ SetNewLandscapeType(e->we.click.widget - 8);
+ break;
+ case 12: ShowGameOptions(); break;
+ case 13: ShowGameDifficulty(); break;
+ case 14: ShowPatchesSelection(); break;
+ case 15: ShowNewGRFSettings(true, true, false, &_grfconfig_newgame); break;
+ case 16: HandleExitGameRequest(); break;
+ }
+ break;
+ }
+}
+
+static const WindowDesc _select_game_desc = {
+ WDP_CENTER, WDP_CENTER, 336, 195,
+ WC_SELECT_GAME,0,
+ WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _select_game_widgets,
+ SelectGameWndProc
+};
+
+void ShowSelectGameWindow(void)
+{
+ AllocateWindowDesc(&_select_game_desc);
+}
+
+static void AskExitGameCallback(Window *w, bool confirmed)
+{
+ if (confirmed) _exit_game = true;
+}
+
+void AskExitGame(void)
+{
+#if defined(_WIN32)
+ SetDParam(0, STR_0133_WINDOWS);
+#elif defined(__APPLE__)
+ SetDParam(0, STR_0135_OSX);
+#elif defined(__BEOS__)
+ SetDParam(0, STR_OSNAME_BEOS);
+#elif defined(__MORPHOS__)
+ SetDParam(0, STR_OSNAME_MORPHOS);
+#elif defined(__AMIGA__)
+ SetDParam(0, STR_OSNAME_AMIGAOS);
+#elif defined(__OS2__)
+ SetDParam(0, STR_OSNAME_OS2);
+#else
+ SetDParam(0, STR_0134_UNIX);
+#endif
+ ShowQuery(
+ STR_00C7_QUIT,
+ STR_00CA_ARE_YOU_SURE_YOU_WANT_TO,
+ NULL,
+ AskExitGameCallback
+ );
+}
+
+
+static void AskExitToGameMenuCallback(Window *w, bool confirmed)
+{
+ if (confirmed) _switch_mode = SM_MENU;
+}
+
+void AskExitToGameMenu(void)
+{
+ ShowQuery(
+ STR_0161_QUIT_GAME,
+ (_game_mode != GM_EDITOR) ? STR_ABANDON_GAME_QUERY : STR_QUIT_SCENARIO_QUERY,
+ NULL,
+ AskExitToGameMenuCallback
+ );
+}
diff --git a/src/landscape.c b/src/landscape.c
new file mode 100644
index 000000000..2d8b7205b
--- /dev/null
+++ b/src/landscape.c
@@ -0,0 +1,731 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "bridge_map.h"
+#include "heightmap.h"
+#include "clear_map.h"
+#include "functions.h"
+#include "map.h"
+#include "player.h"
+#include "spritecache.h"
+#include "table/sprites.h"
+#include "tile.h"
+#include <stdarg.h>
+#include "viewport.h"
+#include "command.h"
+#include "vehicle.h"
+#include "variables.h"
+#include "void_map.h"
+#include "water_map.h"
+#include "tgp.h"
+#include "genworld.h"
+#include "heightmap.h"
+
+extern const TileTypeProcs
+ _tile_type_clear_procs,
+ _tile_type_rail_procs,
+ _tile_type_road_procs,
+ _tile_type_town_procs,
+ _tile_type_trees_procs,
+ _tile_type_station_procs,
+ _tile_type_water_procs,
+ _tile_type_dummy_procs,
+ _tile_type_industry_procs,
+ _tile_type_tunnelbridge_procs,
+ _tile_type_unmovable_procs;
+
+const TileTypeProcs * const _tile_type_procs[16] = {
+ &_tile_type_clear_procs,
+ &_tile_type_rail_procs,
+ &_tile_type_road_procs,
+ &_tile_type_town_procs,
+ &_tile_type_trees_procs,
+ &_tile_type_station_procs,
+ &_tile_type_water_procs,
+ &_tile_type_dummy_procs,
+ &_tile_type_industry_procs,
+ &_tile_type_tunnelbridge_procs,
+ &_tile_type_unmovable_procs,
+};
+
+/* landscape slope => sprite */
+const byte _tileh_to_sprite[32] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0,
+ 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 17, 0, 15, 18, 0,
+};
+
+const byte _inclined_tileh[] = {
+ SLOPE_SW, SLOPE_NW, SLOPE_SW, SLOPE_SE, SLOPE_NE, SLOPE_SE, SLOPE_NE, SLOPE_NW,
+ SLOPE_E, SLOPE_N, SLOPE_W, SLOPE_S,
+ SLOPE_NWS, SLOPE_WSE, SLOPE_SEN, SLOPE_ENW
+};
+
+
+uint GetPartialZ(int x, int y, Slope corners)
+{
+ int z = 0;
+
+ switch (corners) {
+ case SLOPE_W:
+ if (x - y >= 0)
+ z = (x - y) >> 1;
+ break;
+
+ case SLOPE_S:
+ y^=0xF;
+ if ( (x - y) >= 0)
+ z = (x - y) >> 1;
+ break;
+
+ case SLOPE_SW:
+ z = (x>>1) + 1;
+ break;
+
+ case SLOPE_E:
+ if (y - x >= 0)
+ z = (y - x) >> 1;
+ break;
+
+ case SLOPE_EW:
+ case SLOPE_NS:
+ case SLOPE_ELEVATED:
+ z = 4;
+ break;
+
+ case SLOPE_SE:
+ z = (y>>1) + 1;
+ break;
+
+ case SLOPE_WSE:
+ z = 8;
+ y^=0xF;
+ if (x - y < 0)
+ z += (x - y) >> 1;
+ break;
+
+ case SLOPE_N:
+ y ^= 0xF;
+ if (y - x >= 0)
+ z = (y - x) >> 1;
+ break;
+
+ case SLOPE_NW:
+ z = (y^0xF)>>1;
+ break;
+
+ case SLOPE_NWS:
+ z = 8;
+ if (x - y < 0)
+ z += (x - y) >> 1;
+ break;
+
+ case SLOPE_NE:
+ z = (x^0xF)>>1;
+ break;
+
+ case SLOPE_ENW:
+ z = 8;
+ y ^= 0xF;
+ if (y - x < 0)
+ z += (y - x) >> 1;
+ break;
+
+ case SLOPE_SEN:
+ z = 8;
+ if (y - x < 0)
+ z += (y - x) >> 1;
+ break;
+
+ case SLOPE_STEEP_S:
+ z = 1 + ((x+y)>>1);
+ break;
+
+ case SLOPE_STEEP_W:
+ z = 1 + ((x+(y^0xF))>>1);
+ break;
+
+ case SLOPE_STEEP_N:
+ z = 1 + (((x^0xF)+(y^0xF))>>1);
+ break;
+
+ case SLOPE_STEEP_E:
+ z = 1 + (((x^0xF)+(y^0xF))>>1);
+ break;
+
+ default: break;
+ }
+
+ return z;
+}
+
+uint GetSlopeZ(int x, int y)
+{
+ TileIndex tile = TileVirtXY(x, y);
+
+ return _tile_type_procs[GetTileType(tile)]->get_slope_z_proc(tile, x, y);
+}
+
+
+static Slope GetFoundationSlope(TileIndex tile, uint* z)
+{
+ Slope tileh = GetTileSlope(tile, z);
+ Slope slope = _tile_type_procs[GetTileType(tile)]->get_slope_tileh_proc(tile, tileh);
+
+ // Flatter slope -> higher base height
+ if (slope < tileh) *z += TILE_HEIGHT;
+ return slope;
+}
+
+
+static bool HasFoundationNW(TileIndex tile, Slope slope_here, uint z_here)
+{
+ uint z;
+ Slope slope = GetFoundationSlope(TILE_ADDXY(tile, 0, -1), &z);
+
+ return
+ (
+ z_here + (slope_here & SLOPE_N ? TILE_HEIGHT : 0) + (slope_here == SLOPE_STEEP_N ? TILE_HEIGHT : 0) >
+ z + (slope & SLOPE_E ? TILE_HEIGHT : 0) + (slope == SLOPE_STEEP_E ? TILE_HEIGHT : 0)
+ ) || (
+ z_here + (slope_here & SLOPE_W ? TILE_HEIGHT : 0) + (slope_here == SLOPE_STEEP_W ? TILE_HEIGHT : 0) >
+ z + (slope & SLOPE_S ? TILE_HEIGHT : 0) + (slope == SLOPE_STEEP_S ? TILE_HEIGHT : 0)
+ );
+}
+
+
+static bool HasFoundationNE(TileIndex tile, Slope slope_here, uint z_here)
+{
+ uint z;
+ Slope slope = GetFoundationSlope(TILE_ADDXY(tile, -1, 0), &z);
+
+ return
+ (
+ z_here + (slope_here & SLOPE_N ? TILE_HEIGHT : 0) + (slope_here == SLOPE_STEEP_N ? TILE_HEIGHT : 0) >
+ z + (slope & SLOPE_W ? TILE_HEIGHT : 0) + (slope == SLOPE_STEEP_W ? TILE_HEIGHT : 0)
+ ) || (
+ z_here + (slope_here & SLOPE_E ? TILE_HEIGHT : 0) + (slope_here == SLOPE_STEEP_E ? TILE_HEIGHT : 0) >
+ z + (slope & SLOPE_S ? TILE_HEIGHT : 0) + (slope == SLOPE_STEEP_S ? TILE_HEIGHT : 0)
+ );
+}
+
+
+void DrawFoundation(TileInfo *ti, uint f)
+{
+ uint32 sprite_base = SPR_SLOPES_BASE - 15;
+ Slope slope;
+ uint z;
+
+ slope = GetFoundationSlope(ti->tile, &z);
+ if (!HasFoundationNW(ti->tile, slope, z)) sprite_base += 22;
+ if (!HasFoundationNE(ti->tile, slope, z)) sprite_base += 44;
+
+ if (IsSteepSlope(ti->tileh)) {
+ uint32 lower_base;
+
+ // Lower part of foundation
+ lower_base = sprite_base;
+ if (lower_base == SPR_SLOPES_BASE - 15) lower_base = SPR_FOUNDATION_BASE;
+ AddSortableSpriteToDraw(
+ lower_base + (ti->tileh & ~SLOPE_STEEP), ti->x, ti->y, 16, 16, 7, ti->z
+ );
+ ti->z += TILE_HEIGHT;
+ ti->tileh = _inclined_tileh[f - 15];
+ if (f < 15 + 8) {
+ // inclined
+ AddSortableSpriteToDraw(sprite_base + f, ti->x, ti->y, 16, 16, 1, ti->z);
+ OffsetGroundSprite(31, 9);
+ } else if (f >= 15 + 8 + 4) {
+ // three corners raised
+ uint32 upper = sprite_base + 15 + (f - 15 - 8 - 4) * 2;
+
+ AddSortableSpriteToDraw(upper, ti->x, ti->y, 16, 16, 1, ti->z);
+ AddChildSpriteScreen(upper + 1, 31, 9);
+ OffsetGroundSprite(31, 9);
+ } else {
+ // one corner raised
+ OffsetGroundSprite(31, 1);
+ }
+ } else {
+ if (f < 15) {
+ // leveled foundation
+ // Use the original slope sprites if NW and NE borders should be visible
+ if (sprite_base == SPR_SLOPES_BASE - 15) sprite_base = SPR_FOUNDATION_BASE;
+
+ AddSortableSpriteToDraw(sprite_base + f, ti->x, ti->y, 16, 16, 7, ti->z);
+ ti->z += TILE_HEIGHT;
+ ti->tileh = SLOPE_FLAT;
+ OffsetGroundSprite(31, 1);
+ } else {
+ // inclined foundation
+ AddSortableSpriteToDraw(sprite_base + f, ti->x, ti->y, 16, 16, 1, ti->z);
+ ti->tileh = _inclined_tileh[f - 15];
+ OffsetGroundSprite(31, 9);
+ }
+ }
+}
+
+void DoClearSquare(TileIndex tile)
+{
+ MakeClear(tile, CLEAR_GRASS, _generating_world ? 3 : 0);
+ MarkTileDirtyByTile(tile);
+}
+
+uint32 GetTileTrackStatus(TileIndex tile, TransportType mode)
+{
+ return _tile_type_procs[GetTileType(tile)]->get_tile_track_status_proc(tile, mode);
+}
+
+void ChangeTileOwner(TileIndex tile, byte old_player, byte new_player)
+{
+ _tile_type_procs[GetTileType(tile)]->change_tile_owner_proc(tile, old_player, new_player);
+}
+
+void GetAcceptedCargo(TileIndex tile, AcceptedCargo ac)
+{
+ memset(ac, 0, sizeof(AcceptedCargo));
+ _tile_type_procs[GetTileType(tile)]->get_accepted_cargo_proc(tile, ac);
+}
+
+void AnimateTile(TileIndex tile)
+{
+ _tile_type_procs[GetTileType(tile)]->animate_tile_proc(tile);
+}
+
+void ClickTile(TileIndex tile)
+{
+ _tile_type_procs[GetTileType(tile)]->click_tile_proc(tile);
+}
+
+void GetTileDesc(TileIndex tile, TileDesc *td)
+{
+ _tile_type_procs[GetTileType(tile)]->get_tile_desc_proc(tile, td);
+}
+
+/** Clear a piece of landscape
+ * @param tile tile to clear
+ * @param p1 unused
+ * @param p2 unused
+ */
+int32 CmdLandscapeClear(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ return _tile_type_procs[GetTileType(tile)]->clear_tile_proc(tile, flags);
+}
+
+/** Clear a big piece of landscape
+ * @param tile end tile of area dragging
+ * @param p1 start tile of area dragging
+ * @param p2 unused
+ */
+int32 CmdClearArea(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ int32 cost, ret, money;
+ int ex;
+ int ey;
+ int sx,sy;
+ int x,y;
+ bool success = false;
+
+ if (p1 >= MapSize()) return CMD_ERROR;
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ // make sure sx,sy are smaller than ex,ey
+ ex = TileX(tile);
+ ey = TileY(tile);
+ sx = TileX(p1);
+ sy = TileY(p1);
+ if (ex < sx) intswap(ex, sx);
+ if (ey < sy) intswap(ey, sy);
+
+ money = GetAvailableMoneyForCommand();
+ cost = 0;
+
+ for (x = sx; x <= ex; ++x) {
+ for (y = sy; y <= ey; ++y) {
+ ret = DoCommand(TileXY(x, y), 0, 0, flags & ~DC_EXEC, CMD_LANDSCAPE_CLEAR);
+ if (CmdFailed(ret)) continue;
+ cost += ret;
+ success = true;
+
+ if (flags & DC_EXEC) {
+ if (ret > 0 && (money -= ret) < 0) {
+ _additional_cash_required = ret;
+ return cost - ret;
+ }
+ DoCommand(TileXY(x, y), 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+
+ // draw explosion animation...
+ if ((x == sx || x == ex) && (y == sy || y == ey)) {
+ // big explosion in each corner, or small explosion for single tiles
+ CreateEffectVehicleAbove(x * TILE_SIZE + TILE_SIZE / 2, y * TILE_SIZE + TILE_SIZE / 2, 2,
+ sy == ey && sx == ex ? EV_EXPLOSION_SMALL : EV_EXPLOSION_LARGE
+ );
+ }
+ }
+ }
+ }
+
+ return (success) ? cost : CMD_ERROR;
+}
+
+
+#define TILELOOP_BITS 4
+#define TILELOOP_SIZE (1 << TILELOOP_BITS)
+#define TILELOOP_ASSERTMASK ((TILELOOP_SIZE-1) + ((TILELOOP_SIZE-1) << MapLogX()))
+#define TILELOOP_CHKMASK (((1 << (MapLogX() - TILELOOP_BITS))-1) << TILELOOP_BITS)
+
+void RunTileLoop(void)
+{
+ TileIndex tile;
+ uint count;
+
+ tile = _cur_tileloop_tile;
+
+ assert( (tile & ~TILELOOP_ASSERTMASK) == 0);
+ count = (MapSizeX() / TILELOOP_SIZE) * (MapSizeY() / TILELOOP_SIZE);
+ do {
+ _tile_type_procs[GetTileType(tile)]->tile_loop_proc(tile);
+
+ if (TileX(tile) < MapSizeX() - TILELOOP_SIZE) {
+ tile += TILELOOP_SIZE; /* no overflow */
+ } else {
+ tile = TILE_MASK(tile - TILELOOP_SIZE * (MapSizeX() / TILELOOP_SIZE - 1) + TileDiffXY(0, TILELOOP_SIZE)); /* x would overflow, also increase y */
+ }
+ } while (--count);
+ assert( (tile & ~TILELOOP_ASSERTMASK) == 0);
+
+ tile += 9;
+ if (tile & TILELOOP_CHKMASK)
+ tile = (tile + MapSizeX()) & TILELOOP_ASSERTMASK;
+ _cur_tileloop_tile = tile;
+}
+
+void InitializeLandscape(void)
+{
+ uint maxx = MapMaxX();
+ uint maxy = MapMaxY();
+ uint sizex = MapSizeX();
+ uint x;
+ uint y;
+
+ for (y = 0; y < maxy; y++) {
+ for (x = 0; x < maxx; x++) {
+ MakeClear(sizex * y + x, CLEAR_GRASS, 3);
+ SetTileHeight(sizex * y + x, 0);
+ _m[sizex * y + x].extra = 0;
+ ClearBridgeMiddle(sizex * y + x);
+ }
+ MakeVoid(sizex * y + x);
+ }
+ for (x = 0; x < sizex; x++) MakeVoid(sizex * y + x);
+}
+
+void ConvertGroundTilesIntoWaterTiles(void)
+{
+ TileIndex tile;
+ uint z;
+ Slope slope;
+
+ for (tile = 0; tile < MapSize(); ++tile) {
+ slope = GetTileSlope(tile, &z);
+ if (IsTileType(tile, MP_CLEAR) && z == 0) {
+ /* Make both water for tiles at level 0
+ * and make shore, as that looks much better
+ * during the generation. */
+ switch (slope) {
+ case SLOPE_FLAT:
+ MakeWater(tile);
+ break;
+
+ case SLOPE_N:
+ case SLOPE_E:
+ case SLOPE_S:
+ case SLOPE_W:
+ case SLOPE_NW:
+ case SLOPE_SW:
+ case SLOPE_SE:
+ case SLOPE_NE:
+ MakeShore(tile);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+}
+
+static const byte _genterrain_tbl_1[5] = { 10, 22, 33, 37, 4 };
+static const byte _genterrain_tbl_2[5] = { 0, 0, 0, 0, 33 };
+
+static void GenerateTerrain(int type, int flag)
+{
+ uint32 r;
+ uint x;
+ uint y;
+ uint w;
+ uint h;
+ const Sprite* template;
+ const byte *p;
+ Tile* tile;
+ byte direction;
+
+ r = Random();
+ template = GetSprite((((r >> 24) * _genterrain_tbl_1[type]) >> 8) + _genterrain_tbl_2[type] + 4845);
+
+ x = r & MapMaxX();
+ y = (r >> MapLogX()) & MapMaxY();
+
+
+ if (x < 2 || y < 2) return;
+
+ direction = GB(r, 22, 2);
+ if (direction & 1) {
+ w = template->height;
+ h = template->width;
+ } else {
+ w = template->width;
+ h = template->height;
+ }
+ p = template->data;
+
+ if (flag & 4) {
+ uint xw = x * MapSizeY();
+ uint yw = y * MapSizeX();
+ uint bias = (MapSizeX() + MapSizeY()) * 16;
+
+ switch (flag & 3) {
+ case 0:
+ if (xw + yw > MapSize() - bias) return;
+ break;
+
+ case 1:
+ if (yw < xw + bias) return;
+ break;
+
+ case 2:
+ if (xw + yw < MapSize() + bias) return;
+ break;
+
+ case 3:
+ if (xw < yw + bias) return;
+ break;
+ }
+ }
+
+ if (x + w >= MapMaxX() - 1) return;
+ if (y + h >= MapMaxY() - 1) return;
+
+ tile = &_m[TileXY(x, y)];
+
+ switch (direction) {
+ case 0:
+ do {
+ Tile* tile_cur = tile;
+ uint w_cur;
+
+ for (w_cur = w; w_cur != 0; --w_cur) {
+ if (*p >= tile_cur->type_height) tile_cur->type_height = *p;
+ p++;
+ tile_cur++;
+ }
+ tile += TileDiffXY(0, 1);
+ } while (--h != 0);
+ break;
+
+ case 1:
+ do {
+ Tile* tile_cur = tile;
+ uint h_cur;
+
+ for (h_cur = h; h_cur != 0; --h_cur) {
+ if (*p >= tile_cur->type_height) tile_cur->type_height = *p;
+ p++;
+ tile_cur += TileDiffXY(0, 1);
+ }
+ tile++;
+ } while (--w != 0);
+ break;
+
+ case 2:
+ tile += TileDiffXY(w - 1, 0);
+ do {
+ Tile* tile_cur = tile;
+ uint w_cur;
+
+ for (w_cur = w; w_cur != 0; --w_cur) {
+ if (*p >= tile_cur->type_height) tile_cur->type_height = *p;
+ p++;
+ tile_cur--;
+ }
+ tile += TileDiffXY(0, 1);
+ } while (--h != 0);
+ break;
+
+ case 3:
+ tile += TileDiffXY(0, h - 1);
+ do {
+ Tile* tile_cur = tile;
+ uint h_cur;
+
+ for (h_cur = h; h_cur != 0; --h_cur) {
+ if (*p >= tile_cur->type_height) tile_cur->type_height = *p;
+ p++;
+ tile_cur -= TileDiffXY(0, 1);
+ }
+ tile++;
+ } while (--w != 0);
+ break;
+ }
+}
+
+
+#include "table/genland.h"
+
+static void CreateDesertOrRainForest(void)
+{
+ TileIndex tile;
+ TileIndex update_freq = MapSize() / 4;
+ const TileIndexDiffC *data;
+ uint i;
+
+ for (tile = 0; tile != MapSize(); ++tile) {
+ if ((tile % update_freq) == 0) IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
+
+ for (data = _make_desert_or_rainforest_data;
+ data != endof(_make_desert_or_rainforest_data); ++data) {
+ TileIndex t = TILE_MASK(tile + ToTileIndexDiff(*data));
+ if (TileHeight(t) >= 4 || IsTileType(t, MP_WATER)) break;
+ }
+ if (data == endof(_make_desert_or_rainforest_data))
+ SetTropicZone(tile, TROPICZONE_DESERT);
+ }
+
+ for (i = 0; i != 256; i++) {
+ if ((i % 64) == 0) IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
+
+ RunTileLoop();
+ }
+
+ for (tile = 0; tile != MapSize(); ++tile) {
+ if ((tile % update_freq) == 0) IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
+
+ for (data = _make_desert_or_rainforest_data;
+ data != endof(_make_desert_or_rainforest_data); ++data) {
+ TileIndex t = TILE_MASK(tile + ToTileIndexDiff(*data));
+ if (IsTileType(t, MP_CLEAR) && IsClearGround(t, CLEAR_DESERT)) break;
+ }
+ if (data == endof(_make_desert_or_rainforest_data))
+ SetTropicZone(tile, TROPICZONE_RAINFOREST);
+ }
+}
+
+void GenerateLandscape(byte mode)
+{
+ const int gwp_desert_amount = 4 + 8;
+ uint i;
+ uint flag;
+ uint32 r;
+
+ if (mode == GW_HEIGHTMAP) {
+ SetGeneratingWorldProgress(GWP_LANDSCAPE, (_opt.landscape == LT_DESERT) ? 1 + gwp_desert_amount : 1);
+ LoadHeightmap(_file_to_saveload.name);
+ IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
+ } else if (_patches.land_generator == LG_TERRAGENESIS) {
+ SetGeneratingWorldProgress(GWP_LANDSCAPE, (_opt.landscape == LT_DESERT) ? 3 + gwp_desert_amount : 3);
+ GenerateTerrainPerlin();
+ } else {
+ switch (_opt.landscape) {
+ case LT_HILLY:
+ SetGeneratingWorldProgress(GWP_LANDSCAPE, 2);
+
+ for (i = ScaleByMapSize((Random() & 0x7F) + 950); i != 0; --i) {
+ GenerateTerrain(2, 0);
+ }
+ IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
+
+ r = Random();
+ flag = GB(r, 0, 2) | 4;
+ for (i = ScaleByMapSize(GB(r, 16, 7) + 450); i != 0; --i) {
+ GenerateTerrain(4, flag);
+ }
+ IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
+ break;
+
+ case LT_DESERT:
+ SetGeneratingWorldProgress(GWP_LANDSCAPE, 3 + gwp_desert_amount);
+
+ for (i = ScaleByMapSize((Random() & 0x7F) + 170); i != 0; --i) {
+ GenerateTerrain(0, 0);
+ }
+ IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
+
+ r = Random();
+ flag = GB(r, 0, 2) | 4;
+ for (i = ScaleByMapSize(GB(r, 16, 8) + 1700); i != 0; --i) {
+ GenerateTerrain(0, flag);
+ }
+ IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
+
+ flag ^= 2;
+
+ for (i = ScaleByMapSize((Random() & 0x7F) + 410); i != 0; --i) {
+ GenerateTerrain(3, flag);
+ }
+ IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
+ break;
+
+ default:
+ SetGeneratingWorldProgress(GWP_LANDSCAPE, 1);
+
+ i = ScaleByMapSize((Random() & 0x7F) + (3 - _opt.diff.quantity_sea_lakes) * 256 + 100);
+ for (; i != 0; --i) {
+ GenerateTerrain(_opt.diff.terrain_type, 0);
+ }
+ IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
+ break;
+ }
+ }
+
+ ConvertGroundTilesIntoWaterTiles();
+
+ if (_opt.landscape == LT_DESERT) CreateDesertOrRainForest();
+}
+
+void OnTick_Town(void);
+void OnTick_Trees(void);
+void OnTick_Station(void);
+void OnTick_Industry(void);
+
+void OnTick_Players(void);
+void OnTick_Train(void);
+
+void CallLandscapeTick(void)
+{
+ OnTick_Town();
+ OnTick_Trees();
+ OnTick_Station();
+ OnTick_Industry();
+
+ OnTick_Players();
+ OnTick_Train();
+}
+
+TileIndex AdjustTileCoordRandomly(TileIndex a, byte rng)
+{
+ int rn = rng;
+ uint32 r = Random();
+
+ return TILE_MASK(TileXY(
+ TileX(a) + (GB(r, 0, 8) * rn * 2 >> 8) - rn,
+ TileY(a) + (GB(r, 8, 8) * rn * 2 >> 8) - rn
+ ));
+}
+
+bool IsValidTile(TileIndex tile)
+{
+ return (tile < MapSizeX() * MapMaxY() && TileX(tile) != MapMaxX());
+}
diff --git a/src/lang/american.txt b/src/lang/american.txt
new file mode 100644
index 000000000..fc169eb4c
--- /dev/null
+++ b/src/lang/american.txt
@@ -0,0 +1,3116 @@
+##name American
+##ownname English (US)
+##isocode en_US.UTF-8
+##plural 0
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Off edge of map
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Too close to edge of map
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Not enough cash - requires {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Flat land required
+STR_0008_WAITING :{BLACK}Waiting: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (en-route from
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Accepts: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Accepts: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :Passengers
+STR_0010_COAL :Coal
+STR_0011_MAIL :Mail
+STR_0012_OIL :Oil
+STR_0013_LIVESTOCK :Livestock
+STR_0014_GOODS :Goods
+STR_0015_GRAIN :Grain
+STR_0016_WOOD :Wood
+STR_0017_IRON_ORE :Iron Ore
+STR_0018_STEEL :Steel
+STR_0019_VALUABLES :Valuables
+STR_001A_COPPER_ORE :Copper Ore
+STR_001B_MAIZE :Maize
+STR_001C_FRUIT :Fruit
+STR_001D_DIAMONDS :Diamonds
+STR_001E_FOOD :Food
+STR_001F_PAPER :Paper
+STR_0020_GOLD :Gold
+STR_0021_WATER :Water
+STR_0022_WHEAT :Wheat
+STR_0023_RUBBER :Rubber
+STR_0024_SUGAR :Sugar
+STR_0025_TOYS :Toys
+STR_0026_CANDY :Candy
+STR_0027_COLA :Cola
+STR_0028_COTTON_CANDY :Cotton Candy
+STR_0029_BUBBLES :Bubbles
+STR_002A_TOFFEE :Toffee
+STR_002B_BATTERIES :Batteries
+STR_002C_PLASTIC :Plastic
+STR_002D_FIZZY_DRINKS :Fizzy Drinks
+STR_002E :
+STR_002F_PASSENGER :Passenger
+STR_0030_COAL :Coal
+STR_0031_MAIL :Mail
+STR_0032_OIL :Oil
+STR_0033_LIVESTOCK :Livestock
+STR_0034_GOODS :Goods
+STR_0035_GRAIN :Grain
+STR_0036_WOOD :Wood
+STR_0037_IRON_ORE :Iron Ore
+STR_0038_STEEL :Steel
+STR_0039_VALUABLES :Valuables
+STR_003A_COPPER_ORE :Copper Ore
+STR_003B_MAIZE :Maize
+STR_003C_FRUIT :Fruit
+STR_003D_DIAMOND :Diamond
+STR_003E_FOOD :Food
+STR_003F_PAPER :Paper
+STR_0040_GOLD :Gold
+STR_0041_WATER :Water
+STR_0042_WHEAT :Wheat
+STR_0043_RUBBER :Rubber
+STR_0044_SUGAR :Sugar
+STR_0045_TOY :Toy
+STR_0046_CANDY :Candy
+STR_0047_COLA :Cola
+STR_0048_COTTON_CANDY :Cotton Candy
+STR_0049_BUBBLE :Bubble
+STR_004A_TOFFEE :Toffee
+STR_004B_BATTERY :Battery
+STR_004C_PLASTIC :Plastic
+STR_004D_FIZZY_DRINK :Fizzy Drink
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} passenger{P "" s}
+STR_QUANTITY_COAL :{WEIGHT} of coal
+STR_QUANTITY_MAIL :{COMMA} bag{P "" s} of mail
+STR_QUANTITY_OIL :{VOLUME} of oil
+STR_QUANTITY_LIVESTOCK :{COMMA} item{P "" s} of livestock
+STR_QUANTITY_GOODS :{COMMA} crate{P "" s} of goods
+STR_QUANTITY_GRAIN :{WEIGHT} of grain
+STR_QUANTITY_WOOD :{WEIGHT} of wood
+STR_QUANTITY_IRON_ORE :{WEIGHT} of iron ore
+STR_QUANTITY_STEEL :{WEIGHT} of steel
+STR_QUANTITY_VALUABLES :{COMMA} bag{P "" s} of valuables
+STR_QUANTITY_COPPER_ORE :{WEIGHT} of copper ore
+STR_QUANTITY_MAIZE :{WEIGHT} of maize
+STR_QUANTITY_FRUIT :{WEIGHT} of fruit
+STR_QUANTITY_DIAMONDS :{COMMA} bag{P "" s} of diamonds
+STR_QUANTITY_FOOD :{WEIGHT} of food
+STR_QUANTITY_PAPER :{WEIGHT} of paper
+STR_QUANTITY_GOLD :{COMMA} bag{P "" s} of gold
+STR_QUANTITY_WATER :{VOLUME} of water
+STR_QUANTITY_WHEAT :{WEIGHT} of wheat
+STR_QUANTITY_RUBBER :{VOLUME} of rubber
+STR_QUANTITY_SUGAR :{WEIGHT} of sugar
+STR_QUANTITY_TOYS :{COMMA} toy{P "" s}
+STR_QUANTITY_SWEETS :{COMMA} bag{P "" s} of candy
+STR_QUANTITY_COLA :{VOLUME} of cola
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} of cotton candy
+STR_QUANTITY_BUBBLES :{COMMA} bubble{P "" s}
+STR_QUANTITY_TOFFEE :{WEIGHT} of toffee
+STR_QUANTITY_BATTERIES :{COMMA} batter{P y ies}
+STR_QUANTITY_PLASTIC :{VOLUME} of plastic
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} fizzy drink{P "" s}
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}PS
+STR_ABBREV_COAL :{TINYFONT}CL
+STR_ABBREV_MAIL :{TINYFONT}ML
+STR_ABBREV_OIL :{TINYFONT}OL
+STR_ABBREV_LIVESTOCK :{TINYFONT}LV
+STR_ABBREV_GOODS :{TINYFONT}GD
+STR_ABBREV_GRAIN :{TINYFONT}GR
+STR_ABBREV_WOOD :{TINYFONT}WD
+STR_ABBREV_IRON_ORE :{TINYFONT}OR
+STR_ABBREV_STEEL :{TINYFONT}ST
+STR_ABBREV_VALUABLES :{TINYFONT}VL
+STR_ABBREV_COPPER_ORE :{TINYFONT}CO
+STR_ABBREV_MAIZE :{TINYFONT}MZ
+STR_ABBREV_FRUIT :{TINYFONT}FT
+STR_ABBREV_DIAMONDS :{TINYFONT}DM
+STR_ABBREV_FOOD :{TINYFONT}FD
+STR_ABBREV_PAPER :{TINYFONT}PR
+STR_ABBREV_GOLD :{TINYFONT}GD
+STR_ABBREV_WATER :{TINYFONT}WR
+STR_ABBREV_WHEAT :{TINYFONT}WH
+STR_ABBREV_RUBBER :{TINYFONT}RB
+STR_ABBREV_SUGAR :{TINYFONT}SG
+STR_ABBREV_TOYS :{TINYFONT}TY
+STR_ABBREV_SWEETS :{TINYFONT}SW
+STR_ABBREV_COLA :{TINYFONT}CL
+STR_ABBREV_CANDYFLOSS :{TINYFONT}CF
+STR_ABBREV_BUBBLES :{TINYFONT}BU
+STR_ABBREV_TOFFEE :{TINYFONT}TF
+STR_ABBREV_BATTERIES :{TINYFONT}BA
+STR_ABBREV_PLASTIC :{TINYFONT}PL
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}FZ
+STR_ABBREV_NONE :{TINYFONT}NO
+STR_ABBREV_ALL :{TINYFONT}ALL
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Map - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Game Options
+STR_00B2_MESSAGE :{YELLOW}Message
+STR_00B3_MESSAGE_FROM :{YELLOW}Message from {STRING}
+STR_POPUP_CAUTION_CAPTION :{WHITE}Caution!
+STR_00B4_CAN_T_DO_THIS :{WHITE}Can't do this....
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Can't clear this area....
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Original copyright {COPYRIGHT} 1995 Chris Sawyer, All rights reserved
+STR_00B7_VERSION :{BLACK}OpenTTD version {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 The OpenTTD team
+STR_TRANSLATED_BY :{BLACK} Translator(s) -
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Quit
+STR_00C8_YES :{BLACK}Yes
+STR_00C9_NO :{BLACK}No
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Are you sure you want to abandon this game and return to {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Nothing
+STR_00D1_DARK_BLUE :Dark Blue
+STR_00D2_PALE_GREEN :Pale Green
+STR_00D3_PINK :Pink
+STR_00D4_YELLOW :Yellow
+STR_00D5_RED :Red
+STR_00D6_LIGHT_BLUE :Light Blue
+STR_00D7_GREEN :Green
+STR_00D8_DARK_GREEN :Dark Green
+STR_00D9_BLUE :Blue
+STR_00DA_CREAM :Cream
+STR_00DB_MAUVE :Mauve
+STR_00DC_PURPLE :Purple
+STR_00DD_ORANGE :Orange
+STR_00DE_BROWN :Brown
+STR_00DF_GREY :Gray
+STR_00E0_WHITE :White
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Too many vehicles in game
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Location
+STR_00E5_CONTOURS :Contours
+STR_00E6_VEHICLES :Vehicles
+STR_00E7_INDUSTRIES :Industries
+STR_00E8_ROUTES :Routes
+STR_00E9_VEGETATION :Vegetation
+STR_00EA_OWNERS :Owners
+STR_00EB_ROADS :{BLACK}{TINYFONT}Roads
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Railroads
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Stations/Airports/Docks
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Buildings/Industries
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Vehicles
+STR_00F0_100M :{BLACK}{TINYFONT}100m
+STR_00F1_200M :{BLACK}{TINYFONT}200m
+STR_00F2_300M :{BLACK}{TINYFONT}300m
+STR_00F3_400M :{BLACK}{TINYFONT}400m
+STR_00F4_500M :{BLACK}{TINYFONT}500m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Trains
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Road Vehicles
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Ships
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Aircraft
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Transport Routes
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Coal Mine
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Power Station
+STR_00FC_FOREST :{BLACK}{TINYFONT}Forest
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}Sawmill
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Oil Refinery
+STR_00FF_FARM :{BLACK}{TINYFONT}Farm
+STR_0100_FACTORY :{BLACK}{TINYFONT}Factory
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Printing Works
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Oil Wells
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Iron Ore Mine
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Steel Mill
+STR_0105_BANK :{BLACK}{TINYFONT}Bank
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Paper Mill
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Gold Mine
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Food Processing Plant
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Diamond Mine
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Copper Ore Mine
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Fruit Plantation
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Rubber Plantation
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Water Supply
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Water Tower
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}Lumber Mill
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Cotton Candy Forest
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Candy Factory
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Battery Farm
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Cola Wells
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Toy Shop
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Toy Factory
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Plastic Fountains
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Fizzy Drink Factory
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Bubble Generator
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Toffee Quarry
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Sugar Mine
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Railroad Station
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Truck Loading Bay
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Bus Station
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Airport/Heliport
+STR_011F_DOCK :{BLACK}{TINYFONT}Dock
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Rough Land
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Grass Land
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Bare Land
+STR_0123_FIELDS :{BLACK}{TINYFONT}Fields
+STR_0124_TREES :{BLACK}{TINYFONT}Trees
+STR_0125_ROCKS :{BLACK}{TINYFONT}Rocks
+STR_0126_WATER :{BLACK}{TINYFONT}Water
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}No Owner
+STR_0128_TOWNS :{BLACK}{TINYFONT}Towns
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Industries
+STR_012A_DESERT :{BLACK}{TINYFONT}Desert
+STR_012B_SNOW :{BLACK}{TINYFONT}Snow
+STR_012C_MESSAGE :{WHITE}Message
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Cancel
+STR_012F_OK :{BLACK}OK
+STR_0130_RENAME :{BLACK}Rename
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Too many names defined
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Chosen name already in use
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...owned by {STRING}
+STR_013C_CARGO :{BLACK}Cargo
+STR_013D_INFORMATION :{BLACK}Information
+STR_013E_CAPACITIES :{BLACK}Capacities
+STR_013E_TOTAL_CARGO :{BLACK}Total Cargo
+STR_013F_CAPACITY :{BLACK}Capacity: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}Capacity: {LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Total cargo (capacity) of this train:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}New Game
+STR_0141_LOAD_GAME :{BLACK}Load Game
+STR_SINGLE_PLAYER :{BLACK}Single player
+STR_MULTIPLAYER :{BLACK}Multiplayer
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Map size:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Game Options
+
+STR_0150_SOMEONE :someone{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Map of world
+STR_0152_TOWN_DIRECTORY :Town directory
+STR_0153_SUBSIDIES :Subsidies
+
+STR_UNITS_IMPERIAL :Imperial
+STR_UNITS_METRIC :Metric
+STR_UNITS_SI :SI
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} mph
+STR_UNITS_VELOCITY_METRIC :{COMMA} km/h
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}hp
+STR_UNITS_POWER_METRIC :{COMMA}hp
+STR_UNITS_POWER_SI :{COMMA}kW
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} ton{P "" s}
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} tonne{P "" s}
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} kg
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}gal
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}l
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}m³
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} gallon{P "" s}
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} litre{P "" s}
+STR_UNITS_VOLUME_LONG_SI :{COMMA} m³
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10³lbf
+STR_UNITS_FORCE_METRIC :{COMMA} tonne force
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Operating profit graph
+STR_0155_INCOME_GRAPH :Income graph
+STR_0156_DELIVERED_CARGO_GRAPH :Delivered cargo graph
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Performance history graph
+STR_0158_COMPANY_VALUE_GRAPH :Company value graph
+STR_0159_CARGO_PAYMENT_RATES :Cargo payment rates
+STR_015A_COMPANY_LEAGUE_TABLE :Company league table
+STR_PERFORMANCE_DETAIL_MENU :Detailed performance rating
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}OpenTTD
+STR_015C_SAVE_GAME :Save game
+STR_015D_LOAD_GAME :Load game
+STR_015E_QUIT_GAME :Quit game
+STR_015F_QUIT :Quit
+STR_ABANDON_GAME_QUERY :{YELLOW}Are you sure you want to quit this game ?
+STR_0161_QUIT_GAME :{WHITE}Quit Game
+STR_SORT_ORDER_TIP :{BLACK}Select sorting order (descending/ascending)
+STR_SORT_CRITERIA_TIP :{BLACK}Select sorting criteria
+STR_SORT_BY :{BLACK}Sort by
+
+STR_SORT_BY_POPULATION :{BLACK}Population
+STR_SORT_BY_PRODUCTION :{BLACK}Production
+STR_SORT_BY_TYPE :{BLACK}Type
+STR_SORT_BY_TRANSPORTED :{BLACK}Transported
+STR_SORT_BY_NAME :{BLACK}Name
+STR_SORT_BY_DROPDOWN_NAME :Name
+STR_SORT_BY_DATE :{BLACK}Date
+STR_SORT_BY_NUMBER :Number
+STR_SORT_BY_PROFIT_LAST_YEAR :Profit last year
+STR_SORT_BY_PROFIT_THIS_YEAR :Profit this year
+STR_SORT_BY_AGE :Age
+STR_SORT_BY_RELIABILITY :Reliability
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Total capacity per cargo type
+STR_SORT_BY_MAX_SPEED :Maximum speed
+STR_SORT_BY_MODEL :Model
+STR_SORT_BY_VALUE :Value
+STR_SORT_BY_FACILITY :Station type
+STR_SORT_BY_WAITING :Waiting cargo value
+STR_SORT_BY_RATING_MAX :Cargo rating
+STR_ENGINE_SORT_ENGINE_ID :EngineID (classic sort)
+STR_ENGINE_SORT_COST :Cost
+STR_ENGINE_SORT_POWER :Power
+STR_ENGINE_SORT_INTRO_DATE :Introduction Date
+STR_ENGINE_SORT_RUNNING_COST :Running Cost
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Power/Running Cost
+STR_ENGINE_SORT_CARGO_CAPACITY :Cargo Capacity
+STR_NO_WAITING_CARGO :{BLACK}No cargo of any type is waiting
+STR_SELECT_ALL_FACILITIES :{BLACK}Select all facilities
+STR_SELECT_ALL_TYPES :{BLACK}Select all cargo types (including no waiting cargo)
+STR_AVAILABLE_ENGINES_TIP :{BLACK}See a list of available engine designs for this vehicle type.
+STR_MANAGE_LIST :{BLACK}Manage list
+STR_MANAGE_LIST_TIP :{BLACK}Send instructions to all vehicles in this list
+STR_REPLACE_VEHICLES :Replace vehicles
+STR_SEND_TRAIN_TO_DEPOT :Send to Depot
+STR_SEND_ROAD_VEHICLE_TO_DEPOT :Send to Depot
+STR_SEND_SHIP_TO_DEPOT :Send to Depot
+STR_SEND_AIRCRAFT_TO_HANGAR :Send to Hangar
+STR_SEND_FOR_SERVICING :Send for Servicing
+
+############ range for months starts
+STR_0162_JAN :Jan
+STR_0163_FEB :Feb
+STR_0164_MAR :Mar
+STR_0165_APR :Apr
+STR_0166_MAY :May
+STR_0167_JUN :Jun
+STR_0168_JUL :Jul
+STR_0169_AUG :Aug
+STR_016A_SEP :Sep
+STR_016B_OCT :Oct
+STR_016C_NOV :Nov
+STR_016D_DEC :Dec
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Pause game
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Save game, quit game, quit
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Display list of company's stations
+STR_0174_DISPLAY_MAP :{BLACK}Display map
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Display map, town directory
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Display town directory
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Display company finances information
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Display general company information
+STR_0179_DISPLAY_GRAPHS :{BLACK}Display graphs
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Display company league table
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Display list of company's trains
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Display list of company's road vehicles
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Display list of company's ships
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Display list of company's aircraft
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Zoom the view in
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Zoom the view out
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Build railroad track
+STR_0182_BUILD_ROADS :{BLACK}Build roads
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Build ship docks
+STR_0184_BUILD_AIRPORTS :{BLACK}Build airports
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Plant trees, place signs etc.
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Land area information
+STR_0187_OPTIONS :{BLACK}Options
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Can't change servicing interval...
+STR_018B_CLOSE_WINDOW :{BLACK}Close window
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Window title - drag this to move window
+STR_STICKY_BUTTON :{BLACK}Mark this window as uncloseable for the 'Close All Windows' key
+STR_RESIZE_BUTTON :{BLACK}Click and drag to resize this window
+STR_SAVELOAD_HOME_BUTTON :{BLACK}Click here to jump to the current default save/load directory
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Demolish buildings etc. on a square of land
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Lower a corner of land
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Raise a corner of land
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Scroll bar - scrolls list up/down
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Scroll bar - scrolls list left/right
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Show land contours on map
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Show vehicles on map
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Show industries on map
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Show transport routes on map
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Show vegetation on map
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Show land owners on map
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Toggle town names on/off on map
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Profit this year: {CURRENCY} (last year: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} year{P "" s} ({COMMA})
+STR_AGE_RED :{RED}{COMMA} year{P "" s} ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Road vehicle
+STR_019D_AIRCRAFT :Aircraft
+STR_019E_SHIP :Ship
+STR_019F_TRAIN :Train
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} is getting old
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} is getting very old
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} is getting very old and urgently needs replacing
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Land Area Information
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Cost to clear: {LTBLUE}N/A
+STR_01A5_COST_TO_CLEAR :{BLACK}Cost to clear: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :N/A
+STR_01A7_OWNER :{BLACK}Owner: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Local authority: {LTBLUE}{STRING}
+STR_01A9_NONE :None
+STR_01AA_NAME :{BLACK}Name
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1st
+STR_01AD_2ND :2nd
+STR_01AE_3RD :3rd
+STR_01AF_4TH :4th
+STR_01B0_5TH :5th
+STR_01B1_6TH :6th
+STR_01B2_7TH :7th
+STR_01B3_8TH :8th
+STR_01B4_9TH :9th
+STR_01B5_10TH :10th
+STR_01B6_11TH :11th
+STR_01B7_12TH :12th
+STR_01B8_13TH :13th
+STR_01B9_14TH :14th
+STR_01BA_15TH :15th
+STR_01BB_16TH :16th
+STR_01BC_17TH :17th
+STR_01BD_18TH :18th
+STR_01BE_19TH :19th
+STR_01BF_20TH :20th
+STR_01C0_21ST :21st
+STR_01C1_22ND :22nd
+STR_01C2_23RD :23rd
+STR_01C3_24TH :24th
+STR_01C4_25TH :25th
+STR_01C5_26TH :26th
+STR_01C6_27TH :27th
+STR_01C7_28TH :28th
+STR_01C8_29TH :29th
+STR_01C9_30TH :30th
+STR_01CA_31ST :31st
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Cargo accepted: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Jazz Jukebox
+STR_01D3_SOUND_MUSIC :Sound/music
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Show sound/music window
+STR_01D5_ALL :{TINYFONT}All
+STR_01D6_OLD_STYLE :{TINYFONT}Old Style
+STR_01D7_NEW_STYLE :{TINYFONT}New Style
+STR_01D8_EZY_STREET :{TINYFONT}Ezy Street
+STR_01D9_CUSTOM_1 :{TINYFONT}Custom 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Custom 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Music Volume
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Effects Volume
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MIN ' ' ' ' ' ' MAX
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Skip to previous track in selection
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Skip to next track in selection
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Stop playing music
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Start playing music
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Drag sliders to set music and sound effect volumes
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Track{SETX 88}Title
+STR_01E9_SHUFFLE :{TINYFONT}Shuffle
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Program
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Music Program Selection
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Track Index
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Program - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}Clear
+STR_01F1_SAVE :{TINYFONT}{BLACK}Save
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Current program of music tracks
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Select 'all tracks' program
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Select 'old style music' program
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Select 'new style music' program
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Select 'Custom 1' (user-defined) program
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Select 'Custom 2' (user-defined) program
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Clear current program (Custom1 or Custom2 only)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Save music settings
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Click on music track to add to current program (Custom1 or Custom2 only)
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Click on music track to remove it from current program (Custom1 or Custom2 only)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Toggle program shuffle on/off
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Show music track selection window
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Click on service to center view on industry/town
+STR_01FE_DIFFICULTY :{BLACK}Difficulty ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Last message/news report
+STR_0201_MESSAGE_SETTINGS :Message settings
+STR_MESSAGE_HISTORY_MENU :Message History
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Show last message/news report, show message options
+STR_0204_MESSAGE_OPTIONS :{WHITE}Message Options
+STR_0205_MESSAGE_TYPES :{BLACK}Message types:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Arrival of first vehicle at player's station
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Arrival of first vehicle at competitor's station
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Accidents / disasters
+STR_0209_COMPANY_INFORMATION :{YELLOW}Company information
+STR_020A_ECONOMY_CHANGES :{YELLOW}Economy changes
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Advice / information on player's vehicles
+STR_020C_NEW_VEHICLES :{YELLOW}New vehicles
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Changes of cargo acceptance
+STR_020E_SUBSIDIES :{YELLOW}Subsidies
+STR_020F_GENERAL_INFORMATION :{YELLOW}General information
+STR_MESSAGES_ALL :{YELLOW}Setting for all messagetypes (off/summary/full)
+STR_MESSAGE_SOUND :{YELLOW}Play sound for summarized newsmessages
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...too far from previous destination
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Top companies who reached {NUM}{}({STRING} Level)
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Company League Table in {NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Businessman
+STR_0214_ENTREPRENEUR :Entrepreneur
+STR_0215_INDUSTRIALIST :Industrialist
+STR_0216_CAPITALIST :Capitalist
+STR_0217_MAGNATE :Magnate
+STR_0218_MOGUL :Mogul
+STR_0219_TYCOON_OF_THE_CENTURY :Tycoon of the Century
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} achieves '{STRING}' status!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} of {COMPANY} achieves '{STRING}' status!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Create Scenario
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Scenario Editor
+STR_0223_LAND_GENERATION :{WHITE}Land Generation
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Random Land
+STR_0227_RESET_LAND :{BLACK}Reset Land
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Increase area of land to lower/raise
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Decrease area of land to lower/raise
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Generate random land
+STR_022B_RESET_LANDSCAPE :{BLACK}Reset landscape
+STR_022C_RESET_LANDSCAPE :{WHITE}Reset Landscape
+STR_LOAD_GAME_HEIGHTMAP :{WHITE}Use Heightmap
+STR_LOAD_SCEN_HEIGHTMAP :{BLACK}Use Heightmap
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Are you sure you want to reset the landscape?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Landscape generation
+STR_022F_TOWN_GENERATION :{BLACK}Town generation
+STR_0230_INDUSTRY_GENERATION :{BLACK}Industry generation
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Road construction
+STR_0233_TOWN_GENERATION :{WHITE}Town Generation
+STR_0234_NEW_TOWN :{BLACK}New Town
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Construct new town
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Can't build town here...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...too close to edge of map
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...too close to another town
+STR_0239_SITE_UNSUITABLE :{WHITE}...site unsuitable
+STR_023A_TOO_MANY_TOWNS :{WHITE}...too many towns
+STR_CANNOT_GENERATE_TOWN :{WHITE}Can't build any towns
+STR_NO_SPACE_FOR_TOWN :{WHITE}...there is no more space on the map
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Increase size of town
+STR_023C_EXPAND :{BLACK}Expand
+STR_023D_RANDOM_TOWN :{BLACK}Random Town
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Build town in random location
+STR_023F_INDUSTRY_GENERATION :{WHITE}Industry Generation
+STR_0240_COAL_MINE :{BLACK}Coal Mine
+STR_0241_POWER_STATION :{BLACK}Power Station
+STR_0242_SAWMILL :{BLACK}Sawmill
+STR_0243_FOREST :{BLACK}Forest
+STR_0244_OIL_REFINERY :{BLACK}Oil Refinery
+STR_0245_OIL_RIG :{BLACK}Oil Rig
+STR_0246_FACTORY :{BLACK}Factory
+STR_0247_STEEL_MILL :{BLACK}Steel Mill
+STR_0248_FARM :{BLACK}Farm
+STR_0249_IRON_ORE_MINE :{BLACK}Iron Ore Mine
+STR_024A_OIL_WELLS :{BLACK}Oil Wells
+STR_024B_BANK :{BLACK}Bank
+STR_024C_PAPER_MILL :{BLACK}Paper Mill
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Food Processing Plant
+STR_024E_PRINTING_WORKS :{BLACK}Printing Works
+STR_024F_GOLD_MINE :{BLACK}Gold Mine
+STR_0250_LUMBER_MILL :{BLACK}Lumber Mill
+STR_0251_FRUIT_PLANTATION :{BLACK}Fruit Plantation
+STR_0252_RUBBER_PLANTATION :{BLACK}Rubber Plantation
+STR_0253_WATER_SUPPLY :{BLACK}Water Supply
+STR_0254_WATER_TOWER :{BLACK}Water Tower
+STR_0255_DIAMOND_MINE :{BLACK}Diamond Mine
+STR_0256_COPPER_ORE_MINE :{BLACK}Copper Ore Mine
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Cotton Candy Forest
+STR_0258_CANDY_FACTORY :{BLACK}Candy Factory
+STR_0259_BATTERY_FARM :{BLACK}Battery Farm
+STR_025A_COLA_WELLS :{BLACK}Cola Wells
+STR_025B_TOY_SHOP :{BLACK}Toy Shop
+STR_025C_TOY_FACTORY :{BLACK}Toy Factory
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Plastic Fountains
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Fizzy Drink Factory
+STR_025F_BUBBLE_GENERATOR :{BLACK}Bubble Generator
+STR_0260_TOFFEE_QUARRY :{BLACK}Toffee Quarry
+STR_0261_SUGAR_MINE :{BLACK}Sugar Mine
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Construct Coal Mine
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Construct Power Station
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Construct Sawmill
+STR_0265_PLANT_FOREST :{BLACK}Plant Forest
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Construct Oil Refinery
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Construct Oil Rig (Can only be built near the edges of the map)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Construct Factory
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Construct Steel Mill
+STR_026A_CONSTRUCT_FARM :{BLACK}Construct Farm
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Construct Iron Ore Mine
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Construct Oil Wells
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Construct Bank (Can only be built in towns with a population greater than 1200)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Construct Paper Mill
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Construct Food Processing Plant
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Construct Printing Works
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Construct Gold Mine
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Construct Bank (Can only be built in towns)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Construct Lumber Mill (to clear rainforest and produce Wood)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Plant Fruit Plantation
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Plant Rubber Plantation
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Construct Water Supply
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Construct Water Tower (Can only be built in towns)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Construct Diamond Mine
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Construct Copper Ore Mine
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Plant Cotton Candy Forest
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Construct Candy Factory
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Construct Battery Farm
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Construct Cola Wells
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Construct Toy Shop
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Construct Toy Factory
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Construct Plastic Fountains
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Construct Fizzy Drink Factory
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Construct Bubble Generator
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Construct Toffee Quarry
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Construct Sugar Mine
+STR_0285_CAN_T_BUILD_HERE :{WHITE}Can't build {STRING} here...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...must build town first
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...only one allowed per town
+STR_0288_PLANT_TREES :{BLACK}Plant trees
+STR_0289_PLACE_SIGN :{BLACK}Place sign
+STR_028A_RANDOM_TREES :{BLACK}Random Trees
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Plant trees randomly over landscape
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Place rocky areas on landscape
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Place lighthouse
+STR_028E_PLACE_TRANSMITTER :{BLACK}Place transmitter
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Define desert area.{}Press and hold CTRL to remove it
+STR_CREATE_LAKE :{BLACK}Define water area.{}It will flood its surroundings if at sea level
+STR_0290_DELETE :{BLACK}Delete
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Delete this town completely
+STR_0292_SAVE_SCENARIO :Save scenario
+STR_0293_LOAD_SCENARIO :Load scenario
+STR_0294_QUIT_EDITOR :Quit editor
+STR_0295 :
+STR_0296_QUIT :Quit
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Save scenario, load scenario, abandon scenario editor, quit
+STR_0298_LOAD_SCENARIO :{WHITE}Load Scenario
+STR_0299_SAVE_SCENARIO :{WHITE}Save Scenario
+STR_029A_PLAY_SCENARIO :{BLACK}Play Scenario
+STR_PLAY_HEIGHTMAP :{BLACK}Play Heightmap
+STR_PLAY_HEIGHTMAP_HINT :{BLACK}Start a new game, using a heightmap as landscape
+STR_QUIT_SCENARIO_QUERY :{YELLOW}Are you sure you want to quit this scenario ?
+STR_029C_QUIT_EDITOR :{WHITE}Quit Editor
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...can only be built in towns with a population of at least 1200
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Move the starting date backward 1 year
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Move the starting date forward 1 year
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...ends of bridge must both be on land
+STR_02A1_SMALL :{BLACK}Small
+STR_02A2_MEDIUM :{BLACK}Medium
+STR_02A3_LARGE :{BLACK}Large
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Select town size
+STR_02A5_TOWN_SIZE :{YELLOW}Town size:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Show last message or news report
+STR_OFF :Off
+STR_SUMMARY :Summary
+STR_FULL :Full
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Town directory
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Vehicle design names
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Default
+STR_02BF_CUSTOM :Custom
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Save custom names
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Vehicle design names selection
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Save customized vehicle design names
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Game options
+STR_02C5_DIFFICULTY_SETTINGS :Difficulty settings
+STR_02C7_CONFIG_PATCHES :Configure patches
+STR_NEWGRF_SETTINGS :Newgrf settings
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Town names displayed
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Station names displayed
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Signs displayed
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Waypoints displayed
+STR_02D0_FULL_ANIMATION :{SETX 12}Full animation
+STR_02D2_FULL_DETAIL :{SETX 12}Full detail
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Transparent buildings
+STR_TRANSPARENT_SIGNS :{SETX 12}Transparent station signs
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Land area information
+STR_02D6 :
+STR_CONSOLE_SETTING :Toggle Console
+STR_02D7_SCREENSHOT_CTRL_S :Screenshot (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Giant Screenshot (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :About 'OpenTTD'
+############ range ends here
+
+STR_02DB_OFF :{BLACK}Off
+STR_02DA_ON :{BLACK}On
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Display subsidies
+STR_02DD_SUBSIDIES :Subsidies
+STR_02DE_MAP_OF_WORLD :Map of world
+STR_EXTRA_VIEW_PORT :Extra viewport
+STR_SIGN_LIST :Sign list
+STR_02DF_TOWN_DIRECTORY :Town directory
+STR_TOWN_POPULATION :{BLACK}World population: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Viewport {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Copy to viewport
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Copy the location of the global view to this viewport
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Paste from viewport
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Paste the location of this viewport to the global view
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Currency units
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Currency units selection
+STR_MEASURING_UNITS :{BLACK}Measuring units
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Measuring units selection
+STR_02E6_ROAD_VEHICLES :{BLACK}Road vehicles
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Select side of road for vehicles to drive on
+STR_02E9_DRIVE_ON_LEFT :Drive on left
+STR_02EA_DRIVE_ON_RIGHT :Drive on right
+STR_02EB_TOWN_NAMES :{BLACK}Town names
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Select style of town names
+
+STR_02F4_AUTOSAVE :{BLACK}Autosave
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Select interval between automatic game saves
+STR_02F7_OFF :Off
+STR_02F8_EVERY_3_MONTHS :Every 3 months
+STR_02F9_EVERY_6_MONTHS :Every 6 months
+STR_02FA_EVERY_12_MONTHS :Every 12 months
+STR_02FB_START_A_NEW_GAME :{BLACK}Start a new game
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Load a saved game
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Create a customized game world/scenario
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Select single-player game
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Select multiplayer game of 2-8 players
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Display game options
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Display difficulty options
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Start a new game, using a customized scenario
+STR_0304_QUIT :{BLACK}Quit
+STR_0305_QUIT_OPENTTD :{BLACK}Quit 'OpenTTD'
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...can only be built in towns
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Select 'temperate' landscape style
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Select 'sub-arctic' landscape style
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Select 'sub-tropical' landscape style
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Select 'toyland' landscape style
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Fund construction of new industry
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Industry Directory
+STR_0313_FUND_NEW_INDUSTRY :Fund new industry
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Fund new industry
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...can only be built in towns
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...can only be built in rainforest areas
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...can only be built in desert areas
+STR_0319_PAUSED :{YELLOW}* * PAUSED * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Screenshot successfully saved as '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}Screenshot failed!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Purchase land for future use
+STR_032F_AUTOSAVE :{RED}AUTOSAVE
+STR_SAVING_GAME :{RED}* * SAVING GAME * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}Saving still in progress,{}please wait until it is finished!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Select 'Ezy Street style music' program
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :English (Original)
+STR_TOWNNAME_FRENCH :French
+STR_TOWNNAME_GERMAN :German
+STR_TOWNNAME_ADDITIONAL_ENGLISH :English (Additional)
+STR_TOWNNAME_LATIN_AMERICAN :Latin-American
+STR_TOWNNAME_SILLY :Silly
+STR_TOWNNAME_SWEDISH :Swedish
+STR_TOWNNAME_DUTCH :Dutch
+STR_TOWNNAME_FINNISH :Finnish
+STR_TOWNNAME_POLISH :Polish
+STR_TOWNNAME_SLOVAKISH :Slovakish
+STR_TOWNNAME_NORWEGIAN :Norwegian
+STR_TOWNNAME_HUNGARIAN :Hungarian
+STR_TOWNNAME_AUSTRIAN :Austrian
+STR_TOWNNAME_ROMANIAN :Romanian
+STR_TOWNNAME_CZECH :Czech
+STR_TOWNNAME_SWISS :Swiss
+STR_TOWNNAME_DANISH :Danish
+STR_TOWNNAME_TURKISH :Turkish
+STR_TOWNNAME_ITALIAN :Italian
+STR_TOWNNAME_CATALAN :Catalan
+############ end of townname region
+
+STR_CURR_GBP :Pounds (£)
+STR_CURR_USD :Dollars ($)
+STR_CURR_EUR :Euro (€)
+STR_CURR_YEN :Yen (Â¥)
+STR_CURR_ATS :Austrian Shilling (ATS)
+STR_CURR_BEF :Belgian Franc (BEF)
+STR_CURR_CHF :Swiss Franc (CHF)
+STR_CURR_CZK :Czech Koruna (CZK)
+STR_CURR_DEM :Deutschmark (DEM)
+STR_CURR_DKK :Danish Krone (DKK)
+STR_CURR_ESP :Peseta (ESP)
+STR_CURR_FIM :Finnish Markka (FIM)
+STR_CURR_FRF :Franc (FRF)
+STR_CURR_GRD :Greek Drachma (GRD)
+STR_CURR_HUF :Hungarian Forint (HUF)
+STR_CURR_ISK :Icelandic Krona (ISK)
+STR_CURR_ITL :Italian Lira (ITL)
+STR_CURR_NLG :Dutch Guilder (NLG)
+STR_CURR_NOK :Norwegian Krone (NOK)
+STR_CURR_PLN :Polish Zloty (PLN)
+STR_CURR_ROL :Romanian Leu (ROL)
+STR_CURR_RUR :Russian Rubel (RUR)
+STR_CURR_SIT :Slovenian Tolar (SIT)
+STR_CURR_SEK :Swedish Krona (SEK)
+STR_CURR_YTL :Turkish Lira (YTL)
+STR_CURR_SKK :Slovak Koruna (SKK)
+STR_CURR_BRR :Brazilian Real (BRL)
+
+STR_CURR_CUSTOM :Custom...
+
+STR_OPTIONS_LANG :{BLACK}Language
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Select the interface language to use
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Fullscreen
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}Check this box to play OpenTTD fullscreen mode
+
+STR_OPTIONS_RES :{BLACK}Screen resolution
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Select the screen resolution to use
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Screenshot format
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Select the screenshot format to use
+
+STR_AUTOSAVE_1_MONTH :Every month
+STR_AUTOSAVE_FAILED :{WHITE}Autosave failed
+
+STR_MONTH_JAN :January
+STR_MONTH_FEB :February
+STR_MONTH_MAR :March
+STR_MONTH_APR :April
+STR_MONTH_MAY :May
+STR_MONTH_JUN :June
+STR_MONTH_JUL :July
+STR_MONTH_AUG :August
+STR_MONTH_SEP :September
+STR_MONTH_OCT :October
+STR_MONTH_NOV :November
+STR_MONTH_DEC :December
+
+STR_HEADING_FOR_STATION :{LTBLUE}Heading for {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}Heading for {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}No orders
+STR_NO_ORDERS_VEL :{LTBLUE}No orders, {VELOCITY}
+
+STR_PASSENGERS :passengers
+STR_BAGS :bags
+STR_TONS :tonnes
+STR_LITERS :liters
+STR_ITEMS :items
+STR_CRATES :crates
+STR_RES_OTHER :other
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Can't share order list...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Can't copy order list...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - End of Shared Orders - -
+
+STR_TRAIN_IS_LOST :{WHITE}Train {COMMA} is lost.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}Train {COMMA}'s profit last year was {CURRENCY}
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}European Monetary Union!{}{}The Euro is introduced as the sole currency for everyday transactions in your country!
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Train {COMMA} has too few orders in the schedule
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}Train {COMMA} has a void order
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}Train {COMMA} has duplicate orders
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}Train {COMMA} has an invalid station in its orders
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}Road Vehicle {COMMA} has too few orders in the schedule
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}Road Vehicle {COMMA} has a void order
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}Road Vehicle {COMMA} has duplicate orders
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}Road Vehicle {COMMA} has an invalid station in its orders
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}Ship {COMMA} has too few orders in the schedule
+STR_SHIP_HAS_VOID_ORDER :{WHITE}Ship {COMMA} has a void order
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}Ship {COMMA} has duplicate orders
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}Ship {COMMA} has an invalid station in its orders
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}Aircraft {COMMA} has too few orders in the schedule
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}Aircraft {COMMA} has a void order
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}Aircraft {COMMA} has duplicate orders
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}Aircraft {COMMA} has an invalid station in its orders
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}Autorenew failed on train {COMMA} (money limit)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}Autorenew failed on road vehicle {COMMA} (money limit)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}Autorenew failed on ship {COMMA} (money limit)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}Autorenew failed on aircraft {COMMA} (money limit)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}Train {COMMA} is too long after replacement
+
+STR_CONFIG_PATCHES :{BLACK}Configure Patches
+STR_CONFIG_PATCHES_TIP :{BLACK}Configure the patches
+STR_CONFIG_PATCHES_CAPTION :{WHITE}Configure Patches
+
+STR_CONFIG_PATCHES_OFF :Off
+STR_CONFIG_PATCHES_ON :On
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Show vehicle speed in status bar: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Allow building on slopes and coasts: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Allow more realistically sized catchment areas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Allow removal of more town-owned roads, bridges, etc: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Enable building very long trains: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Enable realistic acceleration for trains: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Forbid trains and ships to make 90 deg turns: {ORANGE}{STRING} {LTBLUE} (requires NPF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Join train stations built next to each other: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Leave station when any cargo is full, if 'full load': {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Use improved loading algorithm: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GRADUAL_LOADING :{LTBLUE}Load vehicles gradually: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Inflation: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Deliver cargo to a station only when there is a demand: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Allow building very long bridges: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Allow goto depot orders: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Allow constructing raw material producing industries: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Allow multiple similar industries per town: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Industries of the same type can be built close to each other: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Always show long date in the status bar: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Show signals on the drive side: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Show finances window at the end of the year: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}TTDPatch compatible nonstop handling: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Road vehicle queueing (with quantum effects): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Pan window when mouse is at the edge: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Allow bribing of the local authority: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Nonuniform stations: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}New global pathfinding (NPF, overrides NTP): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FREIGHT_TRAINS :{LTBLUE}Weight multiplier for freight to simulate heavy trains: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Always allow small airports: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Warn if train is lost: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Review vehicles' orders: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :no
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :yes, but exclude stopped vehicles
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :of all vehicles
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Warn if a train's income is negative: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Vehicles never expire: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Autorenew vehicle when it gets old
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Autorenew when vehice is {ORANGE}{STRING}{LTBLUE} months before/after max age
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Autorenew minimum needed money for renew: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Duration of error message: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Show town population in the town name label: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Invisible trees (with transparent buildings): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Land generator: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :Original
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis
+STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}Oil Refineries' max distance from edge of map {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Snow line height: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN :{LTBLUE}Roughness of terrain (TerraGenesis only) : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Very Smooth
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH :Smooth
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH :Rough
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :Very Rough
+STR_CONFIG_PATCHES_TREE_PLACER :{LTBLUE}Tree placer algorithm: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TREE_PLACER_NONE :None
+STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL :Original
+STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED :Improved
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION :{LTBLUE}Heightmap rotation: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Anti-clockwise
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE :Clockwise
+STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT :{LTBLUE}The height level a flat scenario map gets: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Max station spread: {ORANGE}{STRING} {RED}Warning: High setting slows game
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Service helicopters at helipads automatically: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Link landscape toolbar to rail/road/water/airport toolbars: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Reverse scroll direction: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Show a measurement tooltip when using various build-tools: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Show company liveries: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES_NONE :None
+STR_CONFIG_PATCHES_LIVERIES_OWN :Own company
+STR_CONFIG_PATCHES_LIVERIES_ALL :All companies
+STR_CONFIG_PATCHES_PREFER_TEAMCHAT :{LTBLUE}Prefer team chat with <ENTER>: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Max trains per player: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Max road vehicles per player: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}Max aircraft per player: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}Max ships per player: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Disable trains for computer: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Disable road vehicles for computer: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Disable aircraft for computer: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Disable ships for computer: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Enable new AI (alpha): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Allow AIs in multiplayer (experimental): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Default service interval for trains: {ORANGE}{STRING} days/%
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Default service interval for trains: {ORANGE}disabled
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Default service interval for road vehicles: {ORANGE}{STRING} days/%
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Default service interval for road vehicles: {ORANGE}disabled
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Default service interval for aircraft: {ORANGE}{STRING} days/%
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Default service interval for aircraft: {ORANGE}disabled
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Default service interval for ships: {ORANGE}{STRING} days/%
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Default service interval for ships: {ORANGE}disabled
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Disable servicing when breakdowns set to none: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Enable railroad car speed limits: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}Disable electric rails: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Colored news appears in: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Starting date: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}End game in: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Enable smooth economy (more, smaller changes)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Allow buying shares from other companies
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}When dragging place signals every: {ORANGE}{STRING} tile(s)
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Position of main toolbar: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Left
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Centre
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Right
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Window snap radius: {ORANGE}{STRING} px
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Window snap radius: {ORANGE}disabled
+
+STR_CONFIG_PATCHES_GUI :{BLACK}Interface
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Construction
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Vehicles
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Stations
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Economy
+STR_CONFIG_PATCHES_AI :{BLACK}Competitors
+
+STR_CONFIG_PATCHES_DISABLED :disabled
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Change setting value
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Some or all of the default service interval(s) below are incompatible with chosen setting! 5-90% and 30-800 days are valid
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}Use YAPF for ships: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}Use YAPF for roadvehs: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}Use YAPF for trains: {ORANGE}{STRING}
+
+STR_TEMPERATE_LANDSCAPE :Temperate landscape
+STR_SUB_ARCTIC_LANDSCAPE :Sub-arctic landscape
+STR_SUB_TROPICAL_LANDSCAPE :Sub-tropical landscape
+STR_TOYLAND_LANDSCAPE :Toyland landscape
+
+STR_CHEATS :{WHITE}Cheats
+STR_CHEATS_TIP :{BLACK}Checkboxes indicate if you have used this cheat before
+STR_CHEATS_WARNING :{BLACK}Warning! You are about to betray your fellow competitors. Keep in mind that such a disgrace will be remembered for eternity.
+STR_CHEAT_MONEY :{LTBLUE}Increase money by {CURRENCY64}
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Playing as player: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Magic bulldozer (remove industries, unmovables): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Tunnels may cross each other: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Build while in pause mode: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Jetplanes will not crash (frequently) on small airports: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Switch climate: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Change date: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}Enable modifying production values: {ORANGE}{STRING}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}Heading for {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Heading for {WAYPOINT}, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :Go via {WAYPOINT}
+STR_GO_NON_STOP_TO_WAYPOINT :Go non-stop via {WAYPOINT}
+
+STR_WAYPOINTNAME_CITY :Waypoint {TOWN}
+STR_WAYPOINTNAME_CITY_SERIAL :Waypoint {TOWN} #{COMMA}
+STR_LANDINFO_WAYPOINT :Waypoint
+
+STR_WAYPOINT :{WHITE}Waypoint
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Select waypoint type
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}Edit waypoint name
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Can't change waypoint name...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Convert rail to waypoint
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Can't build train waypoint here...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Can't remove train waypoint here...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Build railroad track using the Autorail mode
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}...there is no town in this scenario
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}Are you sure you want to create a random landscape?
+STR_MANY_RANDOM_TOWNS :{BLACK}Many random towns
+STR_RANDOM_TOWNS_TIP :{BLACK}Cover the map with randomly placed towns
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Many random industries
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Cover the map with randomly placed industries
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Can't generate industries...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Open the landscaping toolbar to raise/lower land, plant trees, etc.
+STR_LANDSCAPING_TOOLBAR :{WHITE}Landscaping
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Level land
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Trees of random type
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}Place trees of random type
+
+STR_CANT_BUILD_CANALS :{WHITE}Can't build canals here...
+STR_BUILD_CANALS_TIP :{BLACK}Build canals
+STR_LANDINFO_CANAL :Canal
+
+STR_CANT_BUILD_LOCKS :{WHITE}Can't build locks here...
+STR_BUILD_LOCKS_TIP :{BLACK}Build locks
+STR_LANDINFO_LOCK :Lock
+
+STR_BUOY_IS_IN_USE :{WHITE}... buoy is in use!
+
+STR_LANDINFO_COORDS :{BLACK}Coordinates: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Can't remove part of station...
+STR_CANT_CONVERT_RAIL :{WHITE}Can't convert railtype here...
+STR_CONVERT_RAIL_TIP :{BLACK}Convert/Upgrade the type of the rail
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Drag train engine here to sell the whole train
+
+STR_DRAG_DROP :{BLACK}Drag & Drop
+STR_STATION_DRAG_DROP :{BLACK}Build a station with drag & drop
+STR_SELECT_STATION_CLASS_TIP :{BLACK}Select a station class to display
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Select the station type to build
+
+STR_FAST_FORWARD :{BLACK}Fast forward the game
+STR_MESSAGE_HISTORY :{WHITE}Message History
+STR_MESSAGE_HISTORY_TIP :{BLACK}A list of the recent news messages
+STR_MESSAGES_DISABLE_ALL :{BLACK}Disable all
+STR_MESSAGES_ENABLE_ALL :{BLACK}Enable all
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Construct Coal Mine
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Plant Forest
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Construct Oil Rig
+STR_CONSTRUCT_FARM_TIP :{BLACK}Fund Farm
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Construct Copper Ore Mine
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Drill for Oil
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Construct Gold Mine
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Construct Diamond Mine
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Construct Iron Ore Mine
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Fund Fruit Plantation
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Fund Rubber Plantation
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Fund Water Supply
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Plant Cotton Candy Forest
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}Fund Battery Farm
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Drill for Cola
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Fund Plastic Fountains
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Construct Bubble Generator
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Fund Toffee Quarry
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Construct Sugar Mine
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Industries
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA}% transported)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA}%/{COMMA}% transported)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}...too close to another industry
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Refit train to carry a different cargo type
+STR_RAIL_REFIT_VEHICLE :{BLACK}Refit train
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Select type of cargo for train to carry
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Refit train to carry highlighted cargo type
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Can't refit train...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Service intervals are in percents: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Change production
+
+TEMP_AI_IN_PROGRESS :{WHITE}Welcome to the new AI under development. If you encounter problems, take a screenshot and post it in the forum.
+TEMP_AI_ACTIVATED :{WHITE}Warning: this new AI is still alpha! Currently, only trucks and busses work!
+TEMP_AI_MULTIPLAYER :{WHITE}Warning: implementation is still experimental (using new AI). Please report any problems to truelight@openttd.org.
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Multiplayer
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Player name:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}This is the name other players will identify you by
+STR_NETWORK_CONNECTION :{BLACK}Connection:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Choose between an internet game or a local area nework game
+
+STR_NETWORK_START_SERVER :{BLACK}Start server
+STR_NETWORK_START_SERVER_TIP :{BLACK}Start an own server
+
+STR_NETWORK_GAME_NAME :{BLACK}Name
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Name of the game
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Language, server version, etc.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Click a game from the list to select it
+
+STR_NETWORK_FIND_SERVER :{BLACK}Find server
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Search network for a server
+STR_NETWORK_ADD_SERVER :{BLACK}Add server
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Adds a server to the list which will always be checked for running games.
+STR_NETWORK_ENTER_IP :{BLACK}Enter the IP address of the server
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Clients
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Clients online / clients max
+STR_NETWORK_GAME_INFO :{SILVER}GAME INFO
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Clients: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Language: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Tileset: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Map size: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}Server version: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}Server address: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Start date: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Current date: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Password protected!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}SERVER OFFLINE
+STR_NETWORK_SERVER_FULL :{SILVER}SERVER FULL
+STR_NETWORK_VERSION_MISMATCH :{SILVER}VERSION MISMATCH
+STR_NETWORK_GRF_MISMATCH :{SILVER}NEWGRF MISMATCH
+
+STR_NETWORK_JOIN_GAME :{BLACK}Join game
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}Start new game
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Game name:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}The game name will be displayed to other players in the multiplayer game selection menu
+STR_NETWORK_SET_PASSWORD :{BLACK}Set password
+STR_NETWORK_PASSWORD_TIP :{BLACK}Protect your game with a password if you don't want other people to join it
+STR_NETWORK_SELECT_MAP :{BLACK}Select a map:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}Which map do you want to play?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}Maximum allowed clients:
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Choose a maximum number of clients. Not all slots need to be filled.
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :LAN
+STR_NETWORK_INTERNET :Internet
+STR_NETWORK_LAN_INTERNET :LAN / Internet
+STR_NETWORK_INTERNET_ADVERTISE :Internet (advertize)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 players
+STR_NETWORK_1_PLAYERS :1 player
+STR_NETWORK_2_PLAYERS :2 players
+STR_NETWORK_3_PLAYERS :3 players
+STR_NETWORK_4_PLAYERS :4 players
+STR_NETWORK_5_PLAYERS :5 players
+STR_NETWORK_6_PLAYERS :6 players
+STR_NETWORK_7_PLAYERS :7 players
+STR_NETWORK_8_PLAYERS :8 players
+STR_NETWORK_9_PLAYERS :9 players
+STR_NETWORK_10_PLAYERS :10 players
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}Max companies:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Limit the server to a certain number of companies
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}Max spectators:
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Limit the server to a certain number of spectators
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Language spoken:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Other players will know which language is spoken on the server.
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}Start Game
+STR_NETWORK_START_GAME_TIP :{BLACK}Start a new network game from a random map, or scenario
+STR_NETWORK_LOAD_GAME :{BLACK}Load Game
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Resume an earlier saved multiplayer game (be sure to connect as the correct player)
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Any
+STR_NETWORK_LANG_ENGLISH :English
+STR_NETWORK_LANG_GERMAN :German
+STR_NETWORK_LANG_FRENCH :French
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Multiplayer game lobby
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Preparing to join: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}A list of all companies currently in this game. You can either join one or start a
+STR_NETWORK_NEW_COMPANY :{BLACK}New company
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Open a new company
+STR_NETWORK_SPECTATE_GAME :{BLACK}Watch game
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Watch the game as a spectator
+STR_NETWORK_JOIN_COMPANY :{BLACK}Join company
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Help managing this company
+STR_NETWORK_REFRESH :{BLACK}Refresh server
+STR_NETWORK_REFRESH_TIP :{BLACK}Refresh the server info
+
+STR_NETWORK_COMPANY_INFO :{SILVER}COMPANY INFO
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Company name: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}Inauguration: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}Company value: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Current balance: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Last year's income: {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}Performance: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}Vehicles: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Stations: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Players: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}Connecting...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) Connecting..
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Authorizing..
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Waiting..
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Downloading map..
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Processing data..
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) Registering..
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Fetching game info..
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Fetching company info..
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} client{P "" s} in front of us
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} kbytes downloaded so far
+
+STR_NETWORK_DISCONNECT :{BLACK}Disconnect
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Enter the amount of money you want to give
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Server is protected. Enter password
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Company is protected. Enter password
+STR_NETWORK_CLIENT_LIST :{WHITE}Client List
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE} No network devices found or compiled without ENABLE_NETWORK
+STR_NETWORK_ERR_NOSERVER :{WHITE} Could not find any network games
+STR_NETWORK_ERR_NOCONNECTION :{WHITE} The server didn't answer the request
+STR_NETWORK_ERR_DESYNC :{WHITE} Network-Game synchronization failed.
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} Network-Game connection lost.
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} Could not load server-savegame.
+STR_NETWORK_ERR_SERVER_START :{WHITE} Could not start the server.
+STR_NETWORK_ERR_CLIENT_START :{WHITE} Could not connect.
+STR_NETWORK_ERR_TIMEOUT :{WHITE} Connection #{NUM} timed out.
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE} We made a protocol-error and our connection is closed.
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE} The revision of this client does not match the revision of the server.
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} Wrong password.
+STR_NETWORK_ERR_SERVER_FULL :{WHITE} The server is full
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} You are banned from this server
+STR_NETWORK_ERR_KICKED :{WHITE} You are kicked out of the server
+STR_NETWORK_ERR_CHEATER :{WHITE} Cheating is not allowed on this server
+
+STR_NETWORK_ERR_LEFT :has left the game
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :general error
+STR_NETWORK_ERR_CLIENT_DESYNC :desync error
+STR_NETWORK_ERR_CLIENT_SAVEGAME :could not load map
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :connection lost
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :protocol error
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :not authorized
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :received strange packet
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :wrong revision
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :name already in use
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :wrong game-password
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :wrong player-id in DoCommand
+STR_NETWORK_ERR_CLIENT_KICKED :kicked by server
+STR_NETWORK_ERR_CLIENT_CHEATER :was trying to use a cheat
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :server full
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :has joined the game
+STR_NETWORK_GIVE_MONEY :gave you some money ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :you gave {STRING} some money ({CURRENCY})
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Team] :
+STR_NETWORK_CHAT_COMPANY :[Team] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Team] To {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[Private] :
+STR_NETWORK_CHAT_CLIENT :[Private] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[Private] To {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[All] :
+STR_NETWORK_CHAT_ALL :[All] {STRING}: {GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :has changed his name to
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE} The server closed the session
+STR_NETWORK_SERVER_REBOOT :{WHITE} The server is restarting...{}Please wait...
+
+STR_NETWORK_SERVER :Server
+STR_NETWORK_CLIENT :Client
+STR_NETWORK_SPECTATORS :Spectators
+
+STR_NETWORK_CLIENTLIST_NONE :(none)
+STR_NETWORK_CLIENTLIST_KICK :Kick
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Give money
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Speak to all
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Speak to company
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Private message
+
+
+STR_NETWORK_SEND :{BLACK}Send
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}X-size of map: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Y-size of map: {ORANGE}{STRING}
+
+
+##### PNG-MAP-Loader
+
+STR_PNGMAP_ERROR :{WHITE}Cannot load landscape from PNG...
+STR_PNGMAP_ERR_FILE_NOT_FOUND :{WHITE}...file not found.
+STR_PNGMAP_ERR_IMAGE_TYPE :{WHITE}...could not convert image type. 8 or 24-bit PNG image needed.
+STR_PNGMAP_ERR_MISC :{WHITE}...something just went wrong. Sorry. (probably corrupted file)
+
+STR_BMPMAP_ERROR :{WHITE}Cannot load landscape from BMP...
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}...could not convert image type.
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Cost: {CURRENCY}
+STR_0801_COST :{RED}Cost: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Income: {CURRENCY}
+STR_0803_INCOME :{GREEN}Income: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Transfer: {CURRENCY}
+STR_FEEDER :{YELLOW}Transfer: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Estimated Cost: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Estimated Income: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Can't raise land here...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Can't lower land here...
+STR_080A_ROCKS :Rocks
+STR_080B_ROUGH_LAND :Rough land
+STR_080C_BARE_LAND :Bare land
+STR_080D_GRASS :Grass
+STR_080E_FIELDS :Fields
+STR_080F_SNOW_COVERED_LAND :Snow-covered land
+STR_0810_DESERT :Desert
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Land sloped in wrong direction
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Impossible track combination
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}Excavation would damage tunnel
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Already at sea-level
+STR_1004_TOO_HIGH :{WHITE}Too high
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}No suitable railroad track
+STR_1007_ALREADY_BUILT :{WHITE}...already built
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Must remove railroad track first
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Railroad Construction
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Electrified Railroad Construction
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Monorail Construction
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}MagLev Construction
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Select Rail Bridge
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Can't build train depot here...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Can't build railroad station here...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Can't build signals here...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Can't build railroad track here...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Can't remove railroad track from here...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Can't remove signals from here...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Train Depot Orientation
+STR_1015_RAILROAD_CONSTRUCTION :Railroad construction
+STR_TOOLB_ELRAIL_CONSTRUCTION :Electrified Railroad construction
+STR_1016_MONORAIL_CONSTRUCTION :Monorail construction
+STR_1017_MAGLEV_CONSTRUCTION :MagLev construction
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Build railroad track
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Build train depot (for building and servicing trains)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Build railroad station
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Build railroad signals
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Build railroad bridge
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Build railroad tunnel
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Toggle build/remove for railroad track and signals
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Bridge selection - click on your prefered bridge to build it
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Select railroad depot orientation
+STR_1021_RAILROAD_TRACK :Railroad track
+STR_1023_RAILROAD_TRAIN_DEPOT :Railroad train depot
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...area is owned by another company
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :Railroad track with normal signals
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :Railroad track with pre-signals
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :Railroad track with exit-signals
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :Railroad track with combo-signals
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Must remove road first
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Road works in progress
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Road Construction
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Select Road Bridge
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Can't build road here...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Can't remove road from here...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Road Depot Orientation
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Can't build road vehicle depot here...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Can't build bus station...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Can't build truck station...
+STR_180A_ROAD_CONSTRUCTION :Road construction
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Build road section
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Build road vehicle depot (for building and servicing vehicles)
+STR_180D_BUILD_BUS_STATION :{BLACK}Build bus station
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Build truck loading bay
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Build road bridge
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Build road tunnel
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Toggle build/remove for road construction
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Select road vehicle depot orientation
+STR_1814_ROAD :Road
+STR_1815_ROAD_WITH_STREETLIGHTS :Road with streetlights
+STR_1816_TREE_LINED_ROAD :Tree-lined road
+STR_1817_ROAD_VEHICLE_DEPOT :Road vehicle depot
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :Road/rail grade crossing
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Towns
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Building must be demolished first
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}Population: {ORANGE}{COMMA}{BLACK} Houses: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Rename Town
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Can't rename town...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} local authority refuses to allow this
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Town names - click on name to center view on town
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Center the main view on town location
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Change town name
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passengers last month: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Mail last month: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Tall office block
+STR_2010_OFFICE_BLOCK :Office block
+STR_2011_SMALL_BLOCK_OF_FLATS :Small block of apartments
+STR_2012_CHURCH :Church
+STR_2013_LARGE_OFFICE_BLOCK :Large office block
+STR_2014_TOWN_HOUSES :Town houses
+STR_2015_HOTEL :Hotel
+STR_2016_STATUE :Statue
+STR_2017_FOUNTAIN :Fountain
+STR_2018_PARK :Park
+STR_2019_OFFICE_BLOCK :Office block
+STR_201A_SHOPS_AND_OFFICES :Shops and offices
+STR_201B_MODERN_OFFICE_BUILDING :Modern office building
+STR_201C_WAREHOUSE :Warehouse
+STR_201D_OFFICE_BLOCK :Office block
+STR_201E_STADIUM :Stadium
+STR_201F_OLD_HOUSES :Old houses
+STR_2020_LOCAL_AUTHORITY :{BLACK}Local authority
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Show information on local authority
+STR_2022_LOCAL_AUTHORITY :{WHITE}{TOWN} local authority
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Transport company ratings:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Subsidies
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Subsidies on offer for services taking:
+STR_2027_FROM_TO :{ORANGE}{STRING} from {STRING} to {STRING}
+STR_2028_BY :{YELLOW} (by {DATE_SHORT})
+STR_202A_NONE :{ORANGE}None
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Services already subsidized:
+STR_202C_FROM_TO :{ORANGE}{STRING} from {STATION} to {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, until {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}Offer of subsidy expired:{}{}{STRING} from {STRING} to {STRING} will now not attract a subsidy.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Subsidy withdrawn:{}{}{STRING} service from {STATION} to {STATION} is no longer subsidized.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Service subsidy offered:{}{}First {STRING} service from {STRING} to {STRING} will attract a year's subsidy from the local authority!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Service subsidy awarded to {COMPANY}!{}{}{STRING} service from {STATION} to {STATION} will pay 50% extra for the next year!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Service subsidy awarded to {COMPANY}!{}{}{STRING} service from {STATION} to {STATION} will pay double rates for the next year!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Service subsidy awarded to {COMPANY}!{}{}{STRING} service from {STATION} to {STATION} will pay triple rates for the next year!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Service subsidy awarded to {COMPANY}!{}{}{STRING} service from {STATION} to {STATION} will pay quadruple rates for the next year!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} local authority refuses to allow another airport to be built in this town
+STR_2036_COTTAGES :Cottages
+STR_2037_HOUSES :Houses
+STR_2038_FLATS :Apartments
+STR_2039_TALL_OFFICE_BLOCK :Tall office block
+STR_203A_SHOPS_AND_OFFICES :Shops and offices
+STR_203B_SHOPS_AND_OFFICES :Shops and offices
+STR_203C_THEATER :Theater
+STR_203D_STADIUM :Stadium
+STR_203E_OFFICES :Offices
+STR_203F_HOUSES :Houses
+STR_2040_CINEMA :Cinema
+STR_2041_SHOPPING_MALL :Shopping mall
+STR_2042_DO_IT :{BLACK}Do it
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}List of things to do at this town - click on item for more details
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Carry out the highlighted action in the list above
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Actions available:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Small advertising campaign
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Medium advertising campaign
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Large advertising campaign
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Fund local road reconstruction
+STR_204A_BUILD_STATUE_OF_COMPANY :Build statue of company owner
+STR_204B_FUND_NEW_BUILDINGS :Fund new buildings
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Buy exclusive transport rights
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Bribe the local authority
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Initiate a small local advertising campaign, to attract more passengers and cargo to your transport services.{} Cost: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Initiate a medium local advertising campaign, to attract more passengers and cargo to your transport services.{} Cost: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Initiate a large local advertising campaign, to attract more passengers and cargo to your transport services.{} Cost: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} Fund the reconstruction of the urban road network. Causes considerable disruption to road traffic for up to 6 months.{} Cost: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Build a statue in honor of your company.{} Cost: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Fund the construction of new commercial buildings in the town.{} Cost: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Buy 1 year's exclusive transport rights in town. Town authority will only allow passengers and cargo to use your company's stations.{} Cost: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Bribe the local authority to increase your rating, at the risk of a severe penalty if caught.{} Cost: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}Traffic chaos in {TOWN}!{}{}Road rebuilding program funded by {COMPANY} brings 6 months of misery to motorists!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (under construction)
+STR_2059_IGLOO :Igloo
+STR_205A_TEPEES :Tepees
+STR_205B_TEAPOT_HOUSE :Teapot-House
+STR_205C_PIGGY_BANK :Piggy-Bank
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN} {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Landscaping
+STR_2800_PLANT_TREES :Plant trees
+STR_2801_PLACE_SIGN :Place sign
+STR_2802_TREES :{WHITE}Trees
+STR_2803_TREE_ALREADY_HERE :{WHITE}...tree already here
+STR_2804_SITE_UNSUITABLE :{WHITE}...site unsuitable
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Can't plant tree here...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...too many signs
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Can't place sign here...
+STR_280A_SIGN :Sign
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Edit sign text
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Can't change sign name...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Select tree type to plant
+STR_280E_TREES :Trees
+STR_280F_RAINFOREST :Rainforest
+STR_2810_CACTUS_PLANTS :Cactuses
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Rail Station Selection
+STR_3001_AIRPORT_SELECTION :{WHITE}Airport Selection
+STR_3002_ORIENTATION :{BLACK}Orientation
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Number of tracks
+STR_3004_PLATFORM_LENGTH :{BLACK}Platform length
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Too close to another railroad station
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Adjoins more than one existing station/loading area
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}Too many stations/loading areas in this town
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}Too many stations/loading areas
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Too many bus stops
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}Too many truck stations
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Too close to another station/loading area
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Must demolish railroad station first
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Too close to another airport
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Must demolish airport first
+
+STR_3030_RENAME_STATION_LOADING :Rename station/loading area
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Can't rename station...
+STR_3032_RATINGS :{BLACK}Ratings
+STR_3033_ACCEPTS :{BLACK}Accepts
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}Local rating of transport service:
+
+############ range for rating starts
+STR_3035_APPALLING :Appalling
+STR_3036_VERY_POOR :Very Poor
+STR_3037_POOR :Poor
+STR_3038_MEDIOCRE :Mediocre
+STR_3039_GOOD :Good
+STR_303A_VERY_GOOD :Very Good
+STR_303B_EXCELLENT :Excellent
+STR_303C_OUTSTANDING :Outstanding
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} no longer accepts {STRING}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} no longer accepts {STRING} or {STRING}
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} now accepts {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} now accepts {STRING} and {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Bus Station Orientation
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Truck Station Orient.
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Must demolish bus station first
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Must demolish truck station first
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Station{P "" s}
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- None -
+STR_304B_SITE_UNSUITABLE :{WHITE}...site unsuitable
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Too close to another dock
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Must demolish dock first
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Select railroad station orientation
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Select number of platforms for railroad station
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Select length of railroad station
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Select bus station orientation
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Select truck loading bay orientation
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Center main view on station location
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Show station ratings
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Change name of station
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Show list of accepted cargo
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Station names - click on name to center main view on station
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Select size/type of airport
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :Railroad station
+STR_305F_AIRCRAFT_HANGAR :Aircraft hangar
+STR_3060_AIRPORT :Airport
+STR_3061_TRUCK_LOADING_AREA :Truck loading area
+STR_3062_BUS_STATION :Bus station
+STR_3063_SHIP_DOCK :Ship dock
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Highlight coverage area of proposed site
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Don't highlight coverage area of proposed site
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Coverage area highlight
+STR_3068_DOCK :{WHITE}Dock
+STR_3069_BUOY :Buoy
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...buoy in the way
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...station too spread out
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...nonuniform stations disabled
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Hold down CTRL to select more than one item
+
+STR_UNDEFINED :(undefined string)
+STR_STAT_CLASS_DFLT :Default station
+STR_STAT_CLASS_WAYP :Waypoints
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Ship Depot Orientation
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...must be built on water
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Can't build ship depot here...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Select ship depot orientation
+STR_3804_WATER :Water
+STR_3805_COAST_OR_RIVERBANK :Coast or riverbank
+STR_3806_SHIP_DEPOT :Ship depot
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...Can't build on water
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Save Game
+STR_4001_LOAD_GAME :{WHITE}Load Game
+STR_4002_SAVE :{BLACK}Save
+STR_4003_DELETE :{BLACK}Delete
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} megabyte{P "" s} free
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Unable to read drive
+STR_4007_GAME_SAVE_FAILED :{WHITE}Game Save Failed
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Unable to delete file
+STR_4009_GAME_LOAD_FAILED :{WHITE}Game Load Failed
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}List of drives, directories and saved-game files
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Currently selected name for saved-game
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Delete the currently selected saved-game
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Save the current game, using the selected name
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Select New Game Type
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Select scenario (green), pre-set game (blue), or random new game
+STR_4010_GENERATE_RANDOM_NEW_GAME :Generate random new game
+STR_4011_LOAD_HEIGHTMAP :{WHITE}Load Heightmap
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} in the way
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :Coal Mine
+STR_4803_POWER_STATION :Power Station
+STR_4804_SAWMILL :Sawmill
+STR_4805_FOREST :Forest
+STR_4806_OIL_REFINERY :Oil Refinery
+STR_4807_OIL_RIG :Oil Rig
+STR_4808_FACTORY :Factory
+STR_4809_PRINTING_WORKS :Printing Works
+STR_480A_STEEL_MILL :Steel Mill
+STR_480B_FARM :Farm
+STR_480C_COPPER_ORE_MINE :Copper Ore Mine
+STR_480D_OIL_WELLS :Oil Wells
+STR_480E_BANK :Bank
+STR_480F_FOOD_PROCESSING_PLANT :Food Processing Plant
+STR_4810_PAPER_MILL :Paper Mill
+STR_4811_GOLD_MINE :Gold Mine
+STR_4812_BANK :Bank
+STR_4813_DIAMOND_MINE :Diamond Mine
+STR_4814_IRON_ORE_MINE :Iron Ore Mine
+STR_4815_FRUIT_PLANTATION :Fruit Plantation
+STR_4816_RUBBER_PLANTATION :Rubber Plantation
+STR_4817_WATER_SUPPLY :Water Supply
+STR_4818_WATER_TOWER :Water Tower
+STR_4819_FACTORY :Factory
+STR_481A_FARM :Farm
+STR_481B_LUMBER_MILL :Lumber Mill
+STR_481C_COTTON_CANDY_FOREST :Cotton Candy Forest
+STR_481D_CANDY_FACTORY :Candy Factory
+STR_481E_BATTERY_FARM :Battery Farm
+STR_481F_COLA_WELLS :Cola Wells
+STR_4820_TOY_SHOP :Toy Shop
+STR_4821_TOY_FACTORY :Toy Factory
+STR_4822_PLASTIC_FOUNTAINS :Plastic Fountains
+STR_4823_FIZZY_DRINK_FACTORY :Fizzy Drink Factory
+STR_4824_BUBBLE_GENERATOR :Bubble Generator
+STR_4825_TOFFEE_QUARRY :Toffee Quarry
+STR_4826_SUGAR_MINE :Sugar Mine
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Requires: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Requires: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Requires: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Production last month:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% transported)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Center the main view on industry location
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}New {STRING} under construction near {TOWN}!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}New {STRING} being planted near {TOWN}!
+STR_482F_COST :{BLACK}Cost: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Can't construct this industry type here...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...forest can only be planted above snow-line
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} announces imminent closure!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}Supply problems cause {INDUSTRY} to announce imminent closure!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}Lack of nearby trees causes {INDUSTRY} to announce imminent closure!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} increases production!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}New coal seam found at {INDUSTRY}!{}Production is expected to double!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}New oil reserves found at {INDUSTRY}!{}Production is expected to double!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}Improved farming methods at {INDUSTRY} are expected to double production!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}{INDUSTRY} production down by 50%
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}Insect infestation causes havoc at {INDUSTRY}!{}Production down by 50%
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...can only be positioned near edges of map
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}{STRING} production at {INDUSTRY} increases by {COMMA}%!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}{STRING} production at {INDUSTRY} goes down by {COMMA}%!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Train in tunnel
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Road vehicle in tunnel
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Another tunnel in the way
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Unable to excavate land for other end of tunnel
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Must demolish tunnel first
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Must demolish bridge first
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Cannot start and end on same position
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Level land or water required under bridge
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}Start and end must be in line
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Site unsuitable for tunnel entrance
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Suspension, Steel
+STR_500F_GIRDER_STEEL :Girder, Steel
+STR_5010_CANTILEVER_STEEL :Cantilever, Steel
+STR_5011_SUSPENSION_CONCRETE :Suspension, Concrete
+STR_5012_WOODEN :Wooden
+STR_5013_CONCRETE :Concrete
+STR_5014_TUBULAR_STEEL :Tubular, Steel
+STR_BRIDGE_TUBULAR_SILICON :Tubular, Silicon
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Can't build bridge here...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Can't build tunnel here...
+STR_5017_RAILROAD_TUNNEL :Railroad tunnel
+STR_5018_ROAD_TUNNEL :Road tunnel
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Steel suspension rail bridge
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Steel girder rail bridge
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Steel cantilever rail bridge
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Reinforced concrete suspension rail bridge
+STR_501F_WOODEN_RAIL_BRIDGE :Wooden rail bridge
+STR_5020_CONCRETE_RAIL_BRIDGE :Concrete rail bridge
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Steel suspension road bridge
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Steel girder road bridge
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Steel cantilever road bridge
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Reinforced concrete suspension road bridge
+STR_5025_WOODEN_ROAD_BRIDGE :Wooden road bridge
+STR_5026_CONCRETE_ROAD_BRIDGE :Concrete road bridge
+STR_5027_TUBULAR_RAIL_BRIDGE :Tubular rail bridge
+STR_5028_TUBULAR_ROAD_BRIDGE :Tubular road bridge
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Object in the way
+STR_5801_TRANSMITTER :Transmitter
+STR_5802_LIGHTHOUSE :Lighthouse
+STR_5803_COMPANY_HEADQUARTERS :Company Headquarters
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...company headquarters in the way
+STR_5805_COMPANY_OWNED_LAND :Company-owned land
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Can't purchase this land area...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...you already own it!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Unnamed
+STR_SV_TRAIN_NAME :Train {COMMA}
+STR_SV_ROADVEH_NAME :Road Vehicle {COMMA}
+STR_SV_SHIP_NAME :Ship {COMMA}
+STR_SV_AIRCRAFT_NAME :Aircraft {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :{STRING} North
+STR_SV_STNAME_SOUTH :{STRING} South
+STR_SV_STNAME_EAST :{STRING} East
+STR_SV_STNAME_WEST :{STRING} West
+STR_SV_STNAME_CENTRAL :{STRING} Central
+STR_SV_STNAME_TRANSFER :{STRING} Transfer
+STR_SV_STNAME_HALT :{STRING} Halt
+STR_SV_STNAME_VALLEY :{STRING} Valley
+STR_SV_STNAME_HEIGHTS :{STRING} Heights
+STR_SV_STNAME_WOODS :{STRING} Woods
+STR_SV_STNAME_LAKESIDE :{STRING} Lakeside
+STR_SV_STNAME_EXCHANGE :{STRING} Exchange
+STR_SV_STNAME_AIRPORT :{STRING} Airport
+STR_SV_STNAME_OILFIELD :{STRING} Oilfield
+STR_SV_STNAME_MINES :{STRING} Mines
+STR_SV_STNAME_DOCKS :{STRING} Docks
+STR_SV_STNAME_BUOY_1 :{STRING} Buoy 1
+STR_SV_STNAME_BUOY_2 :{STRING} Buoy 2
+STR_SV_STNAME_BUOY_3 :{STRING} Buoy 3
+STR_SV_STNAME_BUOY_4 :{STRING} Buoy 4
+STR_SV_STNAME_BUOY_5 :{STRING} Buoy 5
+STR_SV_STNAME_BUOY_6 :{STRING} Buoy 6
+STR_SV_STNAME_BUOY_7 :{STRING} Buoy 7
+STR_SV_STNAME_BUOY_8 :{STRING} Buoy 8
+STR_SV_STNAME_BUOY_9 :{STRING} Buoy 9
+STR_SV_STNAME_ANNEXE :{STRING} Annexe
+STR_SV_STNAME_SIDINGS :{STRING} Sidings
+STR_SV_STNAME_BRANCH :{STRING} Branch
+STR_SV_STNAME_UPPER :Upper {STRING}
+STR_SV_STNAME_LOWER :Lower {STRING}
+STR_SV_STNAME_HELIPORT :{STRING} Heliport
+STR_SV_STNAME_FOREST :{STRING} Forest
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Difficulty Level
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Save
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Easy
+STR_6802_MEDIUM :{BLACK}Medium
+STR_6803_HARD :{BLACK}Hard
+STR_6804_CUSTOM :{BLACK}Custom
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maximum no. competitors: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Competitor start time: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}No. of towns: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}No. of industries: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Maximum initial loan: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Initial interest rate: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Vehicle running costs: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Construction speed of competitors: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Intelligence of competitors: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Vehicle breakdowns: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Subsidy multiplier: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Cost of construction: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Terrain type: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Quantity of sea/lakes: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Economy: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Train reversing: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Disasters: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}City council's attitude towards area restructuring: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :None
+STR_6816_LOW :Low
+STR_6817_NORMAL :Normal
+STR_6818_HIGH :High
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Very Slow
+STR_681C_SLOW :Slow
+STR_681D_MEDIUM :Medium
+STR_681E_FAST :Fast
+STR_681F_VERY_FAST :Very Fast
+STR_VERY_LOW :Very Low
+STR_6820_LOW :Low
+STR_6821_MEDIUM :Medium
+STR_6822_HIGH :High
+STR_6823_NONE :None
+STR_6824_REDUCED :Reduced
+STR_6825_NORMAL :Normal
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Very Flat
+STR_682B_FLAT :Flat
+STR_682C_HILLY :Hilly
+STR_682D_MOUNTAINOUS :Mountainous
+STR_682E_STEADY :Steady
+STR_682F_FLUCTUATING :Fluctuating
+STR_6830_IMMEDIATE :Immediate
+STR_6831_3_MONTHS_AFTER_PLAYER :3 months after player
+STR_6832_6_MONTHS_AFTER_PLAYER :6 months after player
+STR_6833_9_MONTHS_AFTER_PLAYER :9 months after player
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :At end of line, and at stations
+STR_6835_AT_END_OF_LINE_ONLY :At end of line only
+STR_6836_OFF :Off
+STR_6837_ON :On
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Show hi-score chart
+STR_6839_PERMISSIVE :Permissive
+STR_683A_TOLERANT :Tolerant
+STR_683B_HOSTILE :Hostile
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Player {COMMA})
+STR_7004_NEW_FACE :{BLACK}New Face
+STR_7005_COLOR_SCHEME :{BLACK}Color Scheme
+STR_7006_COLOR_SCHEME :{GOLD}Color Scheme:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}New Color Scheme
+STR_7008_COMPANY_NAME :{BLACK}Company Name
+STR_7009_PRESIDENT_NAME :{BLACK}President Name
+STR_700A_COMPANY_NAME :Company Name
+STR_700B_PRESIDENT_S_NAME :President's Name
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Can't change company name...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Can't change president's name...
+STR_700E_FINANCES :{WHITE}{COMPANY} Finances {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Expenditure/Income
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Construction
+STR_7012_NEW_VEHICLES :{GOLD}New Vehicles
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Train Running Costs
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Road Veh. Running Costs
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Aircraft Running Costs
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Ship Running Costs
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Property Maintenance
+STR_7018_TRAIN_INCOME :{GOLD}Train Income
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Road Vehicle Income
+STR_701A_AIRCRAFT_INCOME :{GOLD}Aircraft Income
+STR_701B_SHIP_INCOME :{GOLD}Ship Income
+STR_701C_LOAN_INTEREST :{GOLD}Loan Interest
+STR_701D_OTHER :{GOLD}Other
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Total:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Income Graph
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Operating Profit Graph
+STR_7026_BANK_BALANCE :{WHITE}Bank Balance
+STR_7027_LOAN :{WHITE}Loan
+STR_MAX_LOAN :{WHITE}Max Loan: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}Borrow {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Repay {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...maximum permitted loan size is {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Can't borrow any more money...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...no loan to repay
+STR_702E_REQUIRED :{WHITE}...{CURRENCY} required
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Can't repay loan...
+STR_INSUFFICIENT_FUNDS :{WHITE}Can't give away money that is loaned from the bank...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Select new face for president
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Change the company vehicle livery
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Change the president's name
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Change the company name
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Click on desired color scheme
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Increase size of loan
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Repay part of loan
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(President)
+STR_7038_INAUGURATED :{GOLD}Inaugurated: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Vehicles:
+STR_TRAINS :{WHITE}{COMMA} train{P "" s}
+STR_ROAD_VEHICLES :{WHITE}{COMMA} road vehicle{P "" s}
+STR_AIRCRAFT :{WHITE}{COMMA} aircraft
+STR_SHIPS :{WHITE}{COMMA} ship{P "" s}
+STR_7042_NONE :{WHITE}None
+STR_7043_FACE_SELECTION :{WHITE}Face Selection
+STR_7044_MALE :{BLACK}Male
+STR_7045_FEMALE :{BLACK}Female
+STR_7046_NEW_FACE :{BLACK}New Face
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Cancel new face selection
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Accept new face selection
+STR_7049_SELECT_MALE_FACES :{BLACK}Select male faces
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Select female faces
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Generate random new face
+STR_704C_KEY :{BLACK}Key
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Show key to graphs
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Key to company graphs
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Click here to toggle company's entry on graph on/off
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Units of cargo delivered
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Company performance ratings (maximum rating=1000)
+STR_7052_COMPANY_VALUES :{WHITE}Company values
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Company League Table
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}Transport company in trouble!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} will be sold off or declared bankrupt unless performance increases soon!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(President)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Transport company merger!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} has been sold to {COMPANY} for {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}We are looking for a transport company to take-over our company{}{}Do you want to purchase {COMPANY} for {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Bankrupt!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} has been closed down by creditors and all assets sold off!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}New transport company launched!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} starts construction near {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Can't buy company...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Cargo Payment Rates
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Days in transit
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Payment for delivering 10 units (or 10,000 litres) of cargo a distance of 20 squares
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Toggle graph for cargo type on/off
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Engineer
+STR_7067_TRAFFIC_MANAGER :Traffic Manager
+STR_7068_TRANSPORT_COORDINATOR :Transport Coordinator
+STR_7069_ROUTE_SUPERVISOR :Route Supervisor
+STR_706A_DIRECTOR :Director
+STR_706B_CHIEF_EXECUTIVE :Chief Executive
+STR_706C_CHAIRMAN :Chairman
+STR_706D_PRESIDENT :President
+STR_706E_TYCOON :Tycoon
+STR_706F_BUILD_HQ :{BLACK}Build HQ
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Build company headquarters / view company headquarters
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Rebuild company headquarters elsewhere for 1% cost of company value
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Can't build company headquarters...
+STR_7072_VIEW_HQ :{BLACK}View HQ
+STR_RELOCATE_HQ :{BLACK}Relocate HQ
+STR_COMPANY_PASSWORD :{BLACK}Password
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Password-protect your company to prevent unauthorized users from joining.
+STR_SET_COMPANY_PASSWORD :Set company password
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}World Recession!{}{}Financial experts fear worst as economy slumps!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Recession Over!{}{}Upturn in trade gives confidence to industries as economy strengthens!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Toggle large/small window size
+STR_7076_COMPANY_VALUE :{GOLD}Company value: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Buy 25% share in company
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Sell 25% share in company
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Buy 25% share in this company
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Sell 25% share in this company
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Can't buy 25% share in this company...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}Can't sell 25% share in this company...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% owned by {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% owned by {COMPANY}{} {COMMA}% owned by {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} has been taken over by {COMPANY}!
+STR_7080_PROTECTED :{WHITE}This company is not old enough to trade shares yet...
+
+STR_LIVERY_DEFAULT :Standard Livery
+STR_LIVERY_STEAM :Steam Engine
+STR_LIVERY_DIESEL :Diesel Engine
+STR_LIVERY_ELECTRIC :Electric Engine
+STR_LIVERY_MONORAIL :Monorail Engine
+STR_LIVERY_MAGLEV :Maglev Engine
+STR_LIVERY_DMU :DMU
+STR_LIVERY_EMU :EMU
+STR_LIVERY_PASSENGER_WAGON_STEAM :Passenger/Mail Car (Steam)
+STR_LIVERY_PASSENGER_WAGON_DIESEL :Passenger/Mail Car (Diesel)
+STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Passenger/Mail Car (Electric)
+STR_LIVERY_FREIGHT_WAGON :Freight Car
+STR_LIVERY_BUS :Bus
+STR_LIVERY_TRUCK :Truck
+STR_LIVERY_PASSENGER_SHIP :Passenger Ship
+STR_LIVERY_FREIGHT_SHIP :Freight Ship
+STR_LIVERY_HELICOPTER :Helicopter
+STR_LIVERY_SMALL_PLANE :Small Airplane
+STR_LIVERY_LARGE_PLANE :Large Airplane
+
+STR_LIVERY_GENERAL_TIP :{BLACK}Show general color schemes
+STR_LIVERY_TRAIN_TIP :{BLACK}Show train color schemes
+STR_LIVERY_ROADVEH_TIP :{BLACK}Show road vehicle color schemes
+STR_LIVERY_SHIP_TIP :{BLACK}Show ship color schemes
+STR_LIVERY_AIRCRAFT_TIP :{BLACK}Show aircraft color schemes
+STR_LIVERY_PRIMARY_TIP :{BLACK}Choose the primary color for the selected scheme
+STR_LIVERY_SECONDARY_TIP :{BLACK}Choose the secondary color for the selected scheme
+STR_LIVERY_PANEL_TIP :{BLACK}Select a color scheme to change, or multiple schemes with CTRL+click. Click on the box to toggle use of the scheme
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (Steam)
+STR_8001_MJS_250_DIESEL :MJS 250 (Diesel)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut Diesel
+STR_8006_POWERNAUT_DIESEL :Powernaut Diesel
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (Steam)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (Steam)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (Steam)
+STR_800A_SH_8P_STEAM :SH '8P' (Steam)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (Diesel)
+STR_800C_DASH_DIESEL :'Dash' (Diesel)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (Diesel)
+STR_800E_UU_37_DIESEL :UU '37' (Diesel)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (Diesel)
+STR_8010_CS_4000_DIESEL :CS 4000 (Diesel)
+STR_8011_CS_2400_DIESEL :CS 2400 (Diesel)
+STR_8012_CENTENNIAL_DIESEL :Centennial (Diesel)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (Diesel)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (Diesel)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (Diesel)
+STR_8016_SH_125_DIESEL :SH '125' (Diesel)
+STR_8017_SH_30_ELECTRIC :SH '30' (Electric)
+STR_8018_SH_40_ELECTRIC :SH '40' (Electric)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (Electric)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (Electric)
+STR_801B_PASSENGER_CAR :Passenger Car
+STR_801C_MAIL_VAN :Mail Van
+STR_801D_COAL_CAR :Coal Car
+STR_801E_OIL_TANKER :Oil Tanker
+STR_801F_LIVESTOCK_VAN :Livestock Van
+STR_8020_GOODS_VAN :Goods Van
+STR_8021_GRAIN_HOPPER :Grain Hopper
+STR_8022_WOOD_TRUCK :Wood Truck
+STR_8023_IRON_ORE_HOPPER :Iron Ore Hopper
+STR_8024_STEEL_TRUCK :Steel Truck
+STR_8025_ARMORED_VAN :Armored Van
+STR_8026_FOOD_VAN :Food Van
+STR_8027_PAPER_TRUCK :Paper Truck
+STR_8028_COPPER_ORE_HOPPER :Copper Ore Hopper
+STR_8029_WATER_TANKER :Water Tanker
+STR_802A_FRUIT_TRUCK :Fruit Truck
+STR_802B_RUBBER_TRUCK :Rubber Truck
+STR_802C_SUGAR_TRUCK :Sugar Truck
+STR_802D_COTTON_CANDY_HOPPER :Cotton Candy Hopper
+STR_802E_TOFFEE_HOPPER :Toffee Hopper
+STR_802F_BUBBLE_VAN :Bubble Van
+STR_8030_COLA_TANKER :Cola Tanker
+STR_8031_CANDY_VAN :Candy Van
+STR_8032_TOY_VAN :Toy Van
+STR_8033_BATTERY_TRUCK :Battery Truck
+STR_8034_FIZZY_DRINK_TRUCK :Fizzy Drink Truck
+STR_8035_PLASTIC_TRUCK :Plastic Truck
+STR_8036_X2001_ELECTRIC :'X2001' (Electric)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Electric)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :Passenger Car
+STR_803A_MAIL_VAN :Mail Van
+STR_803B_COAL_CAR :Coal Car
+STR_803C_OIL_TANKER :Oil Tanker
+STR_803D_LIVESTOCK_VAN :Livestock Van
+STR_803E_GOODS_VAN :Goods Van
+STR_803F_GRAIN_HOPPER :Grain Hopper
+STR_8040_WOOD_TRUCK :Wood Truck
+STR_8041_IRON_ORE_HOPPER :Iron Ore Hopper
+STR_8042_STEEL_TRUCK :Steel Truck
+STR_8043_ARMORED_VAN :Armored Van
+STR_8044_FOOD_VAN :Food Van
+STR_8045_PAPER_TRUCK :Paper Truck
+STR_8046_COPPER_ORE_HOPPER :Copper Ore Hopper
+STR_8047_WATER_TANKER :Water Tanker
+STR_8048_FRUIT_TRUCK :Fruit Truck
+STR_8049_RUBBER_TRUCK :Rubber Truck
+STR_804A_SUGAR_TRUCK :Sugar Truck
+STR_804B_COTTON_CANDY_HOPPER :Cotton Candy Hopper
+STR_804C_TOFFEE_HOPPER :Toffee Hopper
+STR_804D_BUBBLE_VAN :Bubble Van
+STR_804E_COLA_TANKER :Cola Tanker
+STR_804F_CANDY_VAN :Candy Van
+STR_8050_TOY_VAN :Toy Van
+STR_8051_BATTERY_TRUCK :Battery Truck
+STR_8052_FIZZY_DRINK_TRUCK :Fizzy Drink Truck
+STR_8053_PLASTIC_TRUCK :Plastic Truck
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (Electric)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (Electric)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (Electric)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (Electric)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :Passenger Car
+STR_805A_MAIL_VAN :Mail Van
+STR_805B_COAL_CAR :Coal Car
+STR_805C_OIL_TANKER :Oil Tanker
+STR_805D_LIVESTOCK_VAN :Livestock Van
+STR_805E_GOODS_VAN :Goods Van
+STR_805F_GRAIN_HOPPER :Grain Hopper
+STR_8060_WOOD_TRUCK :Wood Truck
+STR_8061_IRON_ORE_HOPPER :Iron Ore Hopper
+STR_8062_STEEL_TRUCK :Steel Truck
+STR_8063_ARMORED_VAN :Armored Van
+STR_8064_FOOD_VAN :Food Van
+STR_8065_PAPER_TRUCK :Paper Truck
+STR_8066_COPPER_ORE_HOPPER :Copper Ore Hopper
+STR_8067_WATER_TANKER :Water Tanker
+STR_8068_FRUIT_TRUCK :Fruit Truck
+STR_8069_RUBBER_TRUCK :Rubber Truck
+STR_806A_SUGAR_TRUCK :Sugar Truck
+STR_806B_COTTON_CANDY_HOPPER :Cotton Candy Hopper
+STR_806C_TOFFEE_HOPPER :Toffee Hopper
+STR_806D_BUBBLE_VAN :Bubble Van
+STR_806E_COLA_TANKER :Cola Tanker
+STR_806F_CANDY_VAN :Candy Van
+STR_8070_TOY_VAN :Toy Van
+STR_8071_BATTERY_TRUCK :Battery Truck
+STR_8072_FIZZY_DRINK_TRUCK :Fizzy Drink Truck
+STR_8073_PLASTIC_TRUCK :Plastic Truck
+STR_8074_MPS_REGAL_BUS :MPS Regal Bus
+STR_8075_HEREFORD_LEOPARD_BUS :Hereford Leopard Bus
+STR_8076_FOSTER_BUS :Foster Bus
+STR_8077_FOSTER_MKII_SUPERBUS :Foster MkII Superbus
+STR_8078_PLODDYPHUT_MKI_BUS :Ploddyphut MkI Bus
+STR_8079_PLODDYPHUT_MKII_BUS :Ploddyphut MkII Bus
+STR_807A_PLODDYPHUT_MKIII_BUS :Ploddyphut MkIII Bus
+STR_807B_BALOGH_COAL_TRUCK :Balogh Coal Truck
+STR_807C_UHL_COAL_TRUCK :Uhl Coal Truck
+STR_807D_DW_COAL_TRUCK :DW Coal Truck
+STR_807E_MPS_MAIL_TRUCK :MPS Mail Truck
+STR_807F_REYNARD_MAIL_TRUCK :Reynard Mail Truck
+STR_8080_PERRY_MAIL_TRUCK :Perry Mail Truck
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :MightyMover Mail Truck
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Powernaught Mail Truck
+STR_8083_WIZZOWOW_MAIL_TRUCK :Wizzowow Mail Truck
+STR_8084_WITCOMBE_OIL_TANKER :Witcombe Oil Tanker
+STR_8085_FOSTER_OIL_TANKER :Foster Oil Tanker
+STR_8086_PERRY_OIL_TANKER :Perry Oil Tanker
+STR_8087_TALBOTT_LIVESTOCK_VAN :Talbott Livestock Van
+STR_8088_UHL_LIVESTOCK_VAN :Uhl Livestock Van
+STR_8089_FOSTER_LIVESTOCK_VAN :Foster Livestock Van
+STR_808A_BALOGH_GOODS_TRUCK :Balogh Goods Truck
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Craighead Goods Truck
+STR_808C_GOSS_GOODS_TRUCK :Goss Goods Truck
+STR_808D_HEREFORD_GRAIN_TRUCK :Hereford Grain Truck
+STR_808E_THOMAS_GRAIN_TRUCK :Thomas Grain Truck
+STR_808F_GOSS_GRAIN_TRUCK :Goss Grain Truck
+STR_8090_WITCOMBE_WOOD_TRUCK :Witcombe Wood Truck
+STR_8091_FOSTER_WOOD_TRUCK :Foster Wood Truck
+STR_8092_MORELAND_WOOD_TRUCK :Moreland Wood Truck
+STR_8093_MPS_IRON_ORE_TRUCK :MPS Iron Ore Truck
+STR_8094_UHL_IRON_ORE_TRUCK :Uhl Iron Ore Truck
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Chippy Iron Ore Truck
+STR_8096_BALOGH_STEEL_TRUCK :Balogh Steel Truck
+STR_8097_UHL_STEEL_TRUCK :Uhl Steel Truck
+STR_8098_KELLING_STEEL_TRUCK :Kelling Steel Truck
+STR_8099_BALOGH_ARMORED_TRUCK :Balogh Armored Truck
+STR_809A_UHL_ARMORED_TRUCK :Uhl Armored Truck
+STR_809B_FOSTER_ARMORED_TRUCK :Foster Armored Truck
+STR_809C_FOSTER_FOOD_VAN :Foster Food Van
+STR_809D_PERRY_FOOD_VAN :Perry Food Van
+STR_809E_CHIPPY_FOOD_VAN :Chippy Food Van
+STR_809F_UHL_PAPER_TRUCK :Uhl Paper Truck
+STR_80A0_BALOGH_PAPER_TRUCK :Balogh Paper Truck
+STR_80A1_MPS_PAPER_TRUCK :MPS Paper Truck
+STR_80A2_MPS_COPPER_ORE_TRUCK :MPS Copper Ore Truck
+STR_80A3_UHL_COPPER_ORE_TRUCK :Uhl Copper Ore Truck
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Goss Copper Ore Truck
+STR_80A5_UHL_WATER_TANKER :Uhl Water Tanker
+STR_80A6_BALOGH_WATER_TANKER :Balogh Water Tanker
+STR_80A7_MPS_WATER_TANKER :MPS Water Tanker
+STR_80A8_BALOGH_FRUIT_TRUCK :Balogh Fruit Truck
+STR_80A9_UHL_FRUIT_TRUCK :Uhl Fruit Truck
+STR_80AA_KELLING_FRUIT_TRUCK :Kelling Fruit Truck
+STR_80AB_BALOGH_RUBBER_TRUCK :Balogh Rubber Truck
+STR_80AC_UHL_RUBBER_TRUCK :Uhl Rubber Truck
+STR_80AD_RMT_RUBBER_TRUCK :RMT Rubber Truck
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :MightyMover Sugar Truck
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Powernaught Sugar Truck
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Wizzowow Sugar Truck
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :MightyMover Cola Truck
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Powernaught Cola Truck
+STR_80B3_WIZZOWOW_COLA_TRUCK :Wizzowow Cola Truck
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :MightyMover Cotton Candy Truck
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Powernaught Cotton Candy Truck
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Wizzowow Cotton Candy Truck
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :MightyMover Toffee Truck
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Powernaught Toffee Truck
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Wizzowow Toffee Truck
+STR_80BA_MIGHTYMOVER_TOY_VAN :MightyMover Toy Van
+STR_80BB_POWERNAUGHT_TOY_VAN :Powernaught Toy Van
+STR_80BC_WIZZOWOW_TOY_VAN :Wizzowow Toy Van
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :MightyMover Candy Truck
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Powernaught Candy Truck
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Wizzowow Candy Truck
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :MightyMover Battery Truck
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Powernaught Battery Truck
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Wizzowow Battery Truck
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :MightyMover Fizzy Drink Truck
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Powernaught Fizzy Drink Truck
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Wizzowow Fizzy Drink Truck
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :MightyMover Plastic Truck
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Powernaught Plastic Truck
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Wizzowow Plastic Truck
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :MightyMover Bubble Truck
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Powernaught Bubble Truck
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Wizzowow Bubble Truck
+STR_80CC_MPS_OIL_TANKER :MPS Oil Tanker
+STR_80CD_CS_INC_OIL_TANKER :CS-Inc. Oil Tanker
+STR_80CE_MPS_PASSENGER_FERRY :MPS Passenger Ferry
+STR_80CF_FFP_PASSENGER_FERRY :FFP Passenger Ferry
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Bakewell 300 Hovercraft
+STR_80D1_CHUGGER_CHUG_PASSENGER :Chugger-Chug Passenger Ferry
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Shivershake Passenger Ferry
+STR_80D3_YATE_CARGO_SHIP :Yate Cargo ship
+STR_80D4_BAKEWELL_CARGO_SHIP :Bakewell Cargo ship
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Mightymover Cargo ship
+STR_80D6_POWERNAUT_CARGO_SHIP :Powernaut Cargo ship
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Tricario Helicopter
+STR_80FE_GURU_X2_HELICOPTER :Guru X2 Helicopter
+STR_80FF_POWERNAUT_HELICOPTER :Powernaut Helicopter
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Message from vehicle manufacturer
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}We have just designed a new {STRING} - would you be interested in a year's exclusive use of this vehicle, so we can see how it performs before making it universally available ?
+STR_8102_RAILROAD_LOCOMOTIVE :railroad locomotive
+STR_8103_ROAD_VEHICLE :road vehicle
+STR_8104_AIRCRAFT :aircraft
+STR_8105_SHIP :ship
+STR_8106_MONORAIL_LOCOMOTIVE :monorail locomotive
+STR_8107_MAGLEV_LOCOMOTIVE :maglev locomotive
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}{TOWN} Train Depot
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Citizens celebrate . . .{}First train arrives at {STATION}!
+STR_8802_DETAILS :{WHITE}{STRING} (Details)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Train in the way
+STR_8804 :{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8806_GO_TO :Go to {STATION}
+STR_8807_GO_TO_TRANSFER :Go to {STATION} (Transfer and take cargo)
+STR_8808_GO_TO_UNLOAD :Go to {STATION} (Unload)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Go to {STATION} (Transfer and leave empty)
+STR_880A_GO_TO_LOAD :Go to {STATION} (Load)
+STR_880B_GO_TO_TRANSFER_LOAD :Go to {STATION} (Transfer and wait for full load)
+STR_880C_GO_NON_STOP_TO :Go non-stop to {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Go non-stop to {STATION} (Transfer and take cargo)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Go non-stop to {STATION} (Unload)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Go non-stop to {STATION} (Transfer and leave empty)
+STR_8810_GO_NON_STOP_TO_LOAD :Go non-stop to {STATION} (Load)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Go non-stop to {STATION} (Transfer and wait for full load)
+STR_GO_TO_TRAIN_DEPOT :Go to {TOWN} Train Depot
+STR_SERVICE_AT_TRAIN_DEPOT :Service at {TOWN} Train Depot
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Go non-stop to {TOWN} Train Depot
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Service non-stop at {TOWN} Train Depot
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}Heading for {TOWN} Train Depot
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}Heading for {TOWN} Train Depot, {VELOCITY}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE :{LTBLUE}Service at {TOWN} Train Depot
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE_VEL :{LTBLUE}Service at {TOWN} Train Depot, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (Invalid Order)
+
+STR_UNKNOWN_DESTINATION :unknown destination
+STR_8812_EMPTY :{LTBLUE}Empty
+STR_8813_FROM :{LTBLUE}{CARGO} from {STATION}
+STR_FROM_MULT :{LTBLUE}{CARGO} from {STATION} (x{NUM})
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}Train {COMMA} is waiting in depot
+STR_8815_NEW_VEHICLES :{BLACK}New Vehicles
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Train too long
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Trains can only be altered when stopped inside a depot
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} Train{P "" s}
+
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}New Rail Vehicles
+STR_NEW_ELRAIL_VEHICLES :{WHITE}New Electric Rail Vehicles
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}New Monorail Vehicles
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}New Maglev Vehicles
+STR_ALL_AVAIL_RAIL_VEHICLES :{WHITE}Rail Vehicles
+
+STR_881F_BUILD_VEHICLE :{BLACK}Build Vehicle
+STR_CLONE_ROAD_VEHICLE :{BLACK}Clone Vehicle
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}This will build a copy of the road vehicle. Control-click will share the orders
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}This will build a copy of a road vehicle. Click this button and then on a road vehicle inside or outside the depot. Control-click will share the orders
+STR_CLONE_TRAIN :{BLACK}Clone Train
+STR_CLONE_TRAIN_INFO :{BLACK}This will build a copy of the train including all cars. Control-click will share the orders
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}This will build a copy of a train including all cars. Click this button and then on a train inside or outside the depot. Control-click will share the orders
+STR_8820_RENAME :{BLACK}Rename
+STR_8823_SKIP :{BLACK}Skip
+STR_8824_DELETE :{BLACK}Delete
+STR_8825_NON_STOP :{BLACK}Non-Stop
+STR_8826_GO_TO :{BLACK}Go To
+STR_8827_FULL_LOAD :{BLACK}Full Load
+STR_8828_UNLOAD :{BLACK}Unload
+STR_REFIT :{BLACK}Refit
+STR_REFIT_TIP :{BLACK}Select what cargo type to refit to in this order. Control click to remove refit instruction
+STR_REFIT_ORDER :(Refit to {STRING})
+STR_8829_ORDERS :{WHITE}{VEHICLE} (Orders)
+STR_882A_END_OF_ORDERS :{SETX 10}- - End of Orders - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}Service
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Can't build railroad vehicle...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Built: {LTBLUE}{NUM}{BLACK} Value: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Value: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}Loading / Unloading
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}Train must be stopped inside a depot
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Can't send train to depot...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}No more space for orders
+STR_8832_TOO_MANY_ORDERS :{WHITE}Too many orders
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Can't insert new order...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Can't delete this order...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Can't modify this order...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Can't move vehicle...
+STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}The rear engine will always follow its front counterpart
+STR_8838_N_A :N/A{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Can't sell railroad vehicle...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Unable to find route to local depot
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Can't stop/start train...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Servicing interval: {LTBLUE}{COMMA}days{BLACK} Last service: {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Servicing interval: {LTBLUE}{COMMA}%{BLACK} Last service: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Trains - click on train for information
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Build new trains (requires train depot)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Trains - click on train for info., drag vehicle to add/remove from train
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Build new train vehicle
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Drag train vehicle to here to sell it
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Center main view on train depot location
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Train vehicle selection list - click on vehicle for information
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Build the highlighted train vehicle
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Rename train vehicle type
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Current train action - click here to stop/start train
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Show train's orders
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Center main view on train's location
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Send train to depot
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Force train to proceed without waiting for signal to clear
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Reverse direction of train
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Show train details
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Increase servicing interval
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Decrease servicing interval
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Show details of cargo carried
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Show details of train vehicles
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Show capacities of each vehicle
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Show total capacity of train, split by cargo type
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Orders list - click on order to highlight it
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}Skip the current order, and start the next
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Delete the highlighted order
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Make the highlighted order non-stop
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Insert a new order before the highlighted order, or add to end of list
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Make the highlighted order force the vehicle to wait for a full load
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Make the highlighted order force the vehicle to unload
+STR_SERVICE_HINT :{BLACK}Skip this order unless a service is needed
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}New {STRING} now available!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Cost: {CURRENCY} Weight: {WEIGHT_S}{}Speed: {VELOCITY} Power: {POWER}{}Running Cost: {CURRENCY}/yr{}Capacity: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}Broken down
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}Age: {LTBLUE}{STRING}{BLACK} Running Cost: {LTBLUE}{CURRENCY}/yr
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Weight: {LTBLUE}{WEIGHT_S} {BLACK}Power: {LTBLUE}{POWER}{BLACK} Max. speed: {LTBLUE}{VELOCITY}
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Weight: {LTBLUE}{WEIGHT_S} {BLACK}Power: {LTBLUE}{POWER}{BLACK} Max. speed: {LTBLUE}{VELOCITY} {BLACK}Max. T.E.: {LTBLUE}{FORCE}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit this year: {LTBLUE}{CURRENCY} (last year: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}Reliability: {LTBLUE}{COMMA}% {BLACK}Breakdowns since last service: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Stopped
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Can't make train pass signal at danger...
+STR_8863_CRASHED :{RED}Crashed!
+
+STR_8865_NAME_TRAIN :{WHITE}Name train
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}Can't name train...
+STR_8867_NAME_TRAIN :{BLACK}Name train
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Train Crash!{}{COMMA} die in fireball after collision
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Can't reverse direction of train...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Rename train vehicle type
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Can't rename train vehicle type...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Make the highlighted order force the vehicle to dump cargo
+STR_886F_TRANSFER :{BLACK}Transfer
+
+STR_TRAIN_STOPPING :{RED}Stopping
+STR_TRAIN_STOPPING_VEL :{RED}Stopping, {VELOCITY}
+STR_INCOMPATIBLE_RAIL_TYPES :Incompatible rail types
+STR_TRAIN_NO_POWER :{RED}No power
+STR_TRAIN_START_NO_CATENARY :This track lacks catenary, so the train can't start
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Road vehicle in the way
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} Road Vehicle{P "" s}
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}{TOWN} Road Vehicle Depot
+STR_9004_NEW_VEHICLES :{BLACK}New Vehicles
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}New Road Vehicles
+STR_9007_BUILD_VEHICLE :{BLACK}Build Vehicle
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Can't build road vehicle...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (Details)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}Age: {LTBLUE}{STRING}{BLACK} Running Cost: {LTBLUE}{CURRENCY}/yr
+STR_900E_MAX_SPEED :{BLACK}Max. speed: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit this year: {LTBLUE}{CURRENCY} (last year: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}Reliability: {LTBLUE}{COMMA}% {BLACK}Breakdowns since last service: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Built: {LTBLUE}{NUM}{BLACK} Value: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Capacity: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}...must be stopped inside a road vehicle depot
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Can't sell road vehicle...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Can't stop/start road vehicle...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}Road Vehicle {COMMA} is waiting in depot
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}Heading for {TOWN} Road Depot
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}Heading for {TOWN} Road Depot, {VELOCITY}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE :{LTBLUE}Service at {TOWN} Road Depot
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE_VEL :{LTBLUE}Service at {TOWN} Road Depot, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Can't send vehicle to depot...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Unable to find local depot
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Road vehicles - click on vehicle for information
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Build new road vehicles (requires road vehicle depot)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Current vehicle action - click here to stop/start vehicle
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Show vehicle's orders
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Center main view on vehicle's location
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Send vehicle to depot
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Force vehicle to turn around
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Show road vehicle details
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Vehicles - click on vehicle for information
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Build new road vehicle
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Drag road vehicle to here to sell it
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Center main view on road vehicle depot location
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Road vehicle selection list - click on vehicle for information
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Build the highlighted road vehicle
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}New road vehicle now available!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Cost: {CURRENCY}{}Speed: {VELOCITY}{}Running Cost: {CURRENCY}/yr{}Capacity: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Name road vehicle
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Can't name road vehicle...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Name road vehicle
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Citizens celebrate . . .{}First bus arrives at {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Citizens celebrate . . .{}First truck arrives at {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}Road Vehicle Crash!{}Driver dies in fireball after collision with train
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}Road Vehicle Crash!{}{COMMA} die in fireball after collision with train
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Can't make vehicle turn around...
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}Can't turn vehicles consisting of multiple units
+STR_9034_RENAME :{BLACK}Rename
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Rename road vehicle type
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Rename road vehicle type
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Can't rename road vehicle type...
+STR_9038_GO_TO_ROADVEH_DEPOT :Go to {TOWN} Road Vehicle Depot
+STR_SERVICE_AT_ROADVEH_DEPOT :Service at {TOWN} Road Vehicle Depot
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Refit road vehicle to carry a different cargo type
+STR_REFIT_ROAD_VEHICLE :{BLACK}Refit road vehicle
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Refit road vehicle to carry highlighted cargo type
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Can't refit road vehicle...
+STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Select type of cargo for road vehicle to carry
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Dock construction
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Dock construction
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Can't build dock here...
+STR_9803_SHIP_DEPOT :{WHITE}{TOWN} Ship Depot
+STR_9804_NEW_SHIPS :{BLACK}New Ships
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} Ship{P "" s}
+STR_9808_NEW_SHIPS :{WHITE}New Ships
+STR_9809_BUILD_SHIP :{BLACK}Build Ship
+STR_CLONE_SHIP :{BLACK}Clone Ship
+STR_CLONE_SHIP_INFO :{BLACK}This will build a copy of the ship. Control-click will share the orders
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}This will build a copy of a ship. Click this button and then on a ship inside or outside the depot. Control-click will share the orders
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}Ship must be stopped in depot
+STR_980C_CAN_T_SELL_SHIP :{WHITE}Can't sell ship...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Can't build ship...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Ship in the way
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Details)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}Age: {LTBLUE}{STRING}{BLACK} Running Cost: {LTBLUE}{CURRENCY}/yr
+STR_9813_MAX_SPEED :{BLACK}Max. speed: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit this year: {LTBLUE}{CURRENCY} (last year: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}Reliability: {LTBLUE}{COMMA}% {BLACK}Breakdowns since last service: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Built: {LTBLUE}{NUM}{BLACK} Value: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}Capacity: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}Can't stop/start ship...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Can't send ship to depot...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Unable to find local depot
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}Heading for {TOWN} Ship Depot
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}Heading for {TOWN} Ship Depot, {VELOCITY}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE :{LTBLUE}Service at {TOWN} Ship Depot
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE_VEL :{LTBLUE}Service at {TOWN} Ship Depot, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}Ship {COMMA} is waiting in depot
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Build ship dock
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Build ship depot (for building and servicing ships)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Ships - click on ship for information
+STR_9820_BUILD_NEW_SHIP :{BLACK}Build new ship
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Drag ship to here to sell it
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Center main view on ship depot location
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Ships - click on ship for information
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Build new ships (requires ship depot)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}Ship selection list - click on ship for information
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Build the highlighted ship
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Current ship action - click here to stop/start ship
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Show ship's orders
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Center main view on ship's location
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Send ship to depot
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Show ship details
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}New ship now available!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Cost: {CURRENCY} Max. Speed: {VELOCITY}{}Capacity: {CARGO}{}Running Cost: {CURRENCY}/yr
+STR_982F_NAME_SHIP :{BLACK}Name ship
+
+STR_9831_NAME_SHIP :{WHITE}Name ship
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Can't name ship...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Citizens celebrate . . .{}First ship arrives at {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Place a buoy which can be used as a waypoint
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Can't place buoy here...
+STR_9836_RENAME :{BLACK}Rename
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Rename ship type
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Rename ship type
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Can't rename ship type...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Refit cargo ship to carry a different cargo type
+STR_983B_REFIT :{WHITE}{VEHICLE} (Refit)
+STR_983C_REFIT_SHIP :{BLACK}Refit ship
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Select type of cargo for ship to carry
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Refit ship to carry highlighted cargo type
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Select cargo type to carry:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}New capacity: {GOLD}{CARGO}{}{BLACK}Cost of refit: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Can't refit ship...
+STR_9842_REFITTABLE :(refittable)
+STR_GO_TO_SHIP_DEPOT :Go to {TOWN} Ship Depot
+SERVICE_AT_SHIP_DEPOT :Service at {TOWN} Ship Depot
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Airports
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Can't build airport here...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} Aircraft Hangar
+STR_A003_NEW_AIRCRAFT :{BLACK}New Aircraft
+STR_CLONE_AIRCRAFT :{BLACK}Clone Aircraft
+STR_CLONE_AIRCRAFT_INFO :{BLACK}This will build a copy of the aircraft. Control-click will share the orders
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}This will build a copy of an aircraft. Click this button and then on an aircraft inside or outside the hangar. Control-click will share the orders
+STR_A005_NEW_AIRCRAFT :{WHITE}New Aircraft
+STR_A006_BUILD_AIRCRAFT :{BLACK}Build Aircraft
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Can't build aircraft...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} Aircraft
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (Orders)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (Details)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Age: {LTBLUE}{STRING}{BLACK} Running Cost: {LTBLUE}{CURRENCY}/yr
+STR_A00E_MAX_SPEED :{BLACK}Max. speed: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit this year: {LTBLUE}{CURRENCY} (last year: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}Reliability: {LTBLUE}{COMMA}% {BLACK}Breakdowns since last service: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Built: {LTBLUE}{NUM}{BLACK} Value: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Can't send aircraft to hangar...
+STR_HEADING_FOR_HANGAR :{ORANGE}Heading for {STATION} Hangar
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}Heading for {STATION} Hangar, {VELOCITY}
+STR_HEADING_FOR_HANGAR_SERVICE :{LTBLUE}Service at {STATION} Hangar
+STR_HEADING_FOR_HANGAR_SERVICE_VEL :{LTBLUE}Service at {STATION} Hangar, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}Aircraft {COMMA} is waiting in the aircraft hangar
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Aircraft in the way
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Can't stop/start aircraft...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Aircraft is in flight
+STR_A019_CAPACITY :{BLACK}Capacity: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Capacity: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}Aircraft must be stopped in hangar
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Can't sell aircraft...
+STR_A01D_AIRPORT_CONSTRUCTION :Airport construction
+STR_A01E_BUILD_AIRPORT :{BLACK}Build airport
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Aircraft - click on aircraft for information
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Build new aircraft (requires airport with hangar)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Aircraft - click on aircraft for information
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Build new aircraft
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}Drag aircraft to here to sell it
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Center main view on hangar location
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Aircraft selection list - click on aircraft for information
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Build the highlighted aircraft
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Current aircraft action - click here to stop/start aircraft
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Show aircraft's orders
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Center main view on aircraft's location
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Send aircraft to hangar
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Show aircraft details
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}New aircraft now available!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Cost: {CURRENCY} Max. Speed: {VELOCITY}{}Capacity: {COMMA} passengers, {COMMA} bags of mail{}Running Cost: {CURRENCY}/yr
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Name aircraft
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Can't name aircraft...
+STR_A032_NAME_AIRCRAFT :{BLACK}Name aircraft
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Citizens celebrate . . .{}First aircraft arrives at {STATION}!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Plane Crash!{}{COMMA} die in fireball at {STATION}
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Plane Crash!{}Aircraft ran out of fuel, {COMMA} die in fireball!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Rename
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Rename aircraft type
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Rename aircraft type
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Can't rename aircraft type...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Refit aircraft to carry a different cargo type
+STR_A03C_REFIT :{WHITE}{VEHICLE} (Refit)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Refit aircraft
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Select type of cargo for aircraft to carry
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Refit aircraft to carry highlighted cargo type
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Select cargo type to carry:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}New capacity: {GOLD}{STRING}{}{BLACK}Cost of refit: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Can't refit aircraft...
+STR_GO_TO_AIRPORT_HANGAR :Go to {STATION} Hangar
+SERVICE_AT_AIRPORT_HANGAR :Service at {STATION} Hangar
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}Zeppelin disaster at {STATION}!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Road vehicle destroyed in 'UFO' collision!
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}Oil refinery explosion near {TOWN}!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}Factory destroyed in suspicious circumstances near {TOWN}!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}'UFO' lands near {TOWN}!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}Coal mine subsidence leaves trail of destruction near {TOWN}!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Floods!{}At least {COMMA} missing, presumed dead after significant flooding!
+
+STR_BRIBE_FAILED :{WHITE}Your attempted bribery has been
+STR_BRIBE_FAILED_2 :{WHITE}discovered by a regional investigator
+STR_BUILD_DATE :{BLACK}Built: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Detailed performance rating
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}Detail
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Vehicles:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Stations:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Min. profit:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Min. income:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Max. income:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Delivered:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Cargo:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Money:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Loan:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Total:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Number of vehicles; this includes road vehicles, trains, ships and aircraft
+STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}Number of station parts. Every part of a station (e.g. train station, bus stop, airport) is counted, even if they are connected to one station.
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}The profit of the vehicle with the lowest income (of all vehicles older than 2 years)
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Amount of cash made in the month with the lowest profit of the past 12 quarters
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Amount of cash made in the month with the highest profit of the past 12 quarters
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}Units of cargo delivered in the past four quarters.
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}Number of types of cargo delivered in the past quarter.
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Amount of money this company has in the bank
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}The amount of money this company has taken on loan
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Total points out of possible points
+
+STR_NEWGRF_SETTINGS_BUTTON :{BLACK}NewGRF Settings
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}Newgrf settings
+STR_NEWGRF_APPLY_CHANGES :{BLACK}Apply changes
+STR_NEWGRF_SET_PARAMETERS :{BLACK}Set parameters
+STR_NEWGRF_TIP :{BLACK}A list of all the Newgrf sets that you have installed. Click a set to change the settings.
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}There are currently no newgrf files installed! Please refer to the manual for instructions to install new graphics.
+STR_NEWGRF_FILENAME :{BLACK}Filename: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
+STR_NEWGRF_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING}
+STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}You are about to make changes to a running game; this can crash OpenTTD.{}Are you absolutely sure about this?
+
+STR_NEWGRF_ADD :{BLACK}Add
+STR_NEWGRF_ADD_TIP :{BLACK}Add a NewGRF file to the list
+STR_NEWGRF_REMOVE :{BLACK}Remove
+STR_NEWGRF_REMOVE_TIP :{BLACK}Remove the selected NewGRF file from the list
+STR_NEWGRF_MOVEUP :{BLACK}Move Up
+STR_NEWGRF_MOVEUP_TIP :{BLACK}Move the selected NewGRF file up the list
+STR_NEWGRF_MOVEDOWN :{BLACK}Move Down
+STR_NEWGRF_MOVEDOWN_TIP :{BLACK}Move the selected NewGRF file down the list
+STR_NEWGRF_FILE_TIP :{BLACK}A list of the NewGRF files that are installed. Click a file to change its parameters
+STR_NEWGRF_PARAMETER :{BLACK}Parameters: {SILVER}{STRING}
+STR_NEWGRF_PARAMETER_QUERY :{BLACK}Enter NewGRF parameters
+STR_NEWGRF_NO_INFO :{BLACK}No information available
+
+STR_NEWGRF_ADD_CAPTION :{WHITE}Available NewGRF files
+STR_NEWGRF_ADD_FILE :{BLACK}Add to selection
+STR_NEWGRF_ADD_FILE_TIP :{BLACK}Add the selected NewGRF file to your configuration
+STR_NEWGRF_RESCAN_FILES :{BLACK}Rescan files
+STR_NEWGRF_RESCAN_FILES_TIP :{BLACK}Update the list of available NewGRF files
+STR_NEWGRF_DUPLICATE_GRFID :{WHITE}Cannot add file: duplicate GRF ID
+
+STR_NEWGRF_NOT_FOUND :{RED}Matching file not found
+STR_NEWGRF_DISABLED :{RED}Disabled
+
+STR_CURRENCY_WINDOW :{WHITE}Custom currency
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Exchange rate: {ORANGE}{CURRENCY} = £ {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Separator:
+STR_CURRENCY_PREFIX :{LTBLUE}Prefix:
+STR_CURRENCY_SUFFIX :{LTBLUE}Suffix:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Switch to Euro: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Switch to Euro: {ORANGE}never
+STR_CURRENCY_PREVIEW :{LTBLUE}Preview: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Change custom currency parameter
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} Train{P "" s}
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} Road Vehicle{P "" s}
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} Aircraft
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} Ship{P "" s}
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Show all trains which have this station on their schedule
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Show all road vehicles which have this station on their schedule
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Show all aircraft which have this station on their schedule
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Show all ships which have this station on their schedule
+
+STR_VEH_WITH_SHARED_ORDERS_LIST :{WHITE}Shared orders of {COMMA} Vehicle{P "" s}
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}Show all vehicles which have the same schedule
+
+### depot strings
+STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}You are about to sell all the vehicles in the depot. Are you sure?
+
+STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP :{BLACK}Sell all trains in the depot
+STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP :{BLACK}Sell all road vehicles in the depot
+STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP :{BLACK}Sell all ships in the depot
+STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP :{BLACK}Sell all aircraft in the hangar
+
+STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP :{BLACK}Get a list of all trains with the current depot in their orders
+STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP :{BLACK}Get a list of all road vehicles with the current depot in their orders
+STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP :{BLACK}Get a list of all ships with the current depot in their orders
+STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP :{BLACK}Get a list of all aircraft with any hangar at this airport in their orders
+
+STR_DEPOT_AUTOREPLACE_TRAIN_TIP :{BLACK}Autoreplace all trains in the depot
+STR_DEPOT_AUTOREPLACE_ROADVEH_TIP :{BLACK}Autoreplace all road vehicles in the depot
+STR_DEPOT_AUTOREPLACE_SHIP_TIP :{BLACK}Autoreplace all ships in the depot
+STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP :{BLACK}Autoreplace all aircraft in the hangar
+
+STR_VEHICLE_LIST_TRAIN_DEPOT :{BLACK}{STRING} - {COMMA} Train{P "" s}
+STR_VEHICLE_LIST_ROADVEH_DEPOT :{BLACK}{STRING} - {COMMA} Road Vehicle{P "" s}
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} Ship{P "" s}
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} Aircraft
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}Replace {STRING}
+STR_REPLACE_VEHICLES_START :{BLACK}Start Replacing Vehicles
+STR_REPLACE_VEHICLES_STOP :{BLACK}Stop Replacing Vehicles
+STR_NOT_REPLACING :{BLACK}Not replacing
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}No vehicle selected
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Select the engine type to replace
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Select the new engine type you would like to use in place of the left selected engine type
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Press to stop the replacement of the engine type selected on the left
+STR_REPLACE_HELP_START_BUTTON :{BLACK}Press to begin replacement of the left selected engine type with the right selected engine type
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Choose the railtype you want to replace engines for
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Displays which engine the left selected engine is being replaced with, if any
+STR_REPLACE_HELP :{BLACK}This allows you to replace one engine type with another type, when trains of the original type enter a depot
+STR_REPLACE_REMOVE_WAGON :{BLACK}Car removal: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Make autoreplace keep the length of a train the same by removing cars (starting at the front), if replacing the engine would make the train longer.
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}Replacing: {ORANGE}{SKIP}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} EXPERIMENTAL FEATURE {}Switch between engine and car replacement windows.{}Car replacement will only be done if the new car can be refitted into carrying the same type of cargo as the old one. This is checked for each car when the actual replacement takes place.
+STR_ENGINE_NOT_BUILDABLE :{WHITE}Engine is not buildable
+
+STR_ENGINES :Engines
+STR_WAGONS :Cars
+
+STR_MASS_STOP_DEPOT_TRAIN_TIP :{BLACK}Click to stop all trains inside the depot
+STR_MASS_STOP_DEPOT_ROADVEH_TIP :{BLACK}Click to stop all road vehicles inside the depot
+STR_MASS_STOP_DEPOT_SHIP_TIP :{BLACK}Click to stop all ships inside the depot
+STR_MASS_STOP_HANGAR_TIP :{BLACK}Click to stop all aircraft inside the hangar
+
+STR_MASS_START_DEPOT_TRAIN_TIP :{BLACK}Click to start all trains inside the depot
+STR_MASS_START_DEPOT_ROADVEH_TIP :{BLACK}Click to start all the road vehicles inside the depot
+STR_MASS_START_DEPOT_SHIP_TIP :{BLACK}Click to start all ships inside the depot
+STR_MASS_START_HANGAR_TIP :{BLACK}Click to start all aircraft inside the hangar
+
+STR_MASS_STOP_LIST_TIP :{BLACK}Click to stop all vehicles in the list
+STR_MASS_START_LIST_TIP :{BLACK}Click to start all listed vehicles
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}Sign List - {COMMA} Sign{P "" s}
+
+STR_ORDER_REFIT_FAILED :{WHITE}Order refit failure stopped {STRING} {COMMA}
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :Rail Vehicles
+STR_ELRAIL_VEHICLES :Electrified Rail Vehicles
+STR_MONORAIL_VEHICLES :Monorail Vehicles
+STR_MAGLEV_VEHICLES :Maglev Vehicles
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Cost: {GOLD}{CURRENCY}{BLACK} Weight: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Speed: {GOLD}{VELOCITY}{BLACK} Power: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}Speed: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Running Cost: {GOLD}{CURRENCY}/yr
+STR_PURCHASE_INFO_CAPACITY :{BLACK}Capacity: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Designed: {GOLD}{NUM}{BLACK} Life: {GOLD}{COMMA} years
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}Max. Reliability: {GOLD}{COMMA}%
+STR_PURCHASE_INFO_COST :{BLACK}Cost: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Weight: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Cost: {GOLD}{CURRENCY}{BLACK} Speed: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Capacity: {GOLD}{COMMA} passengers, {COMMA} bags of mail
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Powered Wagons: {GOLD}+{POWER}{BLACK} Weight: {GOLD}+{WEIGHT_S}
+STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Refittable to: {GOLD}
+STR_PURCHASE_INFO_ALL_TYPES :All cargo types
+STR_PURCHASE_INFO_ALL_BUT :All but {GOLD}
+STR_PURCHASE_INFO_MAX_TE :{BLACK}Max. Tractive Effort: {GOLD}{FORCE}
+
+########### String for New Landscape Generator
+
+STR_GENERATE :{WHITE}Generate
+STR_RANDOM :{BLACK}Randomize
+STR_RANDOM_HELP :{BLACK}Change the random seed used for Terrain Generation
+STR_WORLD_GENERATION_CAPTION :{WHITE}World generation
+STR_RANDOM_SEED :{BLACK}Random Seed:
+STR_RANDOM_SEED_HELP :{BLACK}Click to enter a random seed
+STR_LAND_GENERATOR :{BLACK}Land generator:
+STR_TREE_PLACER :{BLACK}Tree algorithm:
+STR_HEIGHTMAP_ROTATION :{BLACK}Heightmap rotation:
+STR_TERRAIN_TYPE :{BLACK}Terrain type:
+STR_QUANTITY_OF_SEA_LAKES :{BLACK}Sea level:
+STR_SMOOTHNESS :{BLACK}Smoothness:
+STR_SNOW_LINE_HEIGHT :{BLACK}Snow line height:
+STR_DATE :{BLACK}Date:
+STR_NUMBER_OF_TOWNS :{BLACK}No. of towns:
+STR_NUMBER_OF_INDUSTRIES :{BLACK}No. of industries:
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_SNOW_LINE_UP :{BLACK}Move the snow line height up one
+STR_SNOW_LINE_DOWN :{BLACK}Move the snow line height down one
+STR_SNOW_LINE_QUERY_CAPT :{WHITE}Change snow line height
+STR_START_DATE_QUERY_CAPT :{WHITE}Change starting year
+STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Scale warning
+STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Resizing source map too much is not recommended. Continue with the generation?
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_HEIGHTMAP_NAME :{BLACK}Heightmap name:
+STR_HEIGHTMAP_SIZE :{BLACK}Size: {ORANGE}{NUM} x {NUM}
+STR_GENERATION_WORLD :{WHITE}Generating world...
+STR_GENERATION_ABORT :{BLACK}Cancel
+STR_GENERATION_ABORT_CAPTION :{WHITE}Cancel World Generation
+STR_GENERATION_ABORT_MESSAGE :{YELLOW}Do you really want to cancel the generation?
+STR_PROGRESS :{WHITE}{NUM}% complete
+STR_GENERATION_PROGRESS :{BLACK}{NUM} / {NUM}
+STR_WORLD_GENERATION :{BLACK}World generation
+STR_TREE_GENERATION :{BLACK}Tree generation
+STR_UNMOVABLE_GENERATION :{BLACK}Unmovable generation
+STR_CLEARING_TILES :{BLACK}Rough and rocky area generation
+STR_SETTINGUP_GAME :{BLACK}Setting up game
+STR_PREPARING_TILELOOP :{BLACK}Running tile-loop
+STR_PREPARING_GAME :{BLACK}Preparing game
+STR_DIFFICULTY_TO_CUSTOM :{WHITE}This action changed the difficulty level to custom
+STR_SE_FLAT_WORLD :{WHITE}Flat land
+STR_SE_FLAT_WORLD_TIP :{BLACK}Generate a flat land
+STR_SE_RANDOM_LAND :{WHITE}Random land
+STR_SE_NEW_WORLD :{BLACK}Create new scenario
+STR_SE_CAPTION :{WHITE}Scenario type
+STR_FLAT_WORLD_HEIGHT_DOWN :{BLACK}Move the height of flat land down one
+STR_FLAT_WORLD_HEIGHT_UP :{BLACK}Move the height of flat land up one
+STR_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Change height of flat land
+STR_FLAT_WORLD_HEIGHT :{BLACK}Height of flat land:
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+STR_SMALLMAP_CENTER :{BLACK}Center the smallmap on the current position
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}Small
+STR_CITY_AIRPORT :{BLACK}City
+STR_METRO_AIRPORT :{BLACK}Metropolitan airport
+STR_INTERNATIONAL_AIRPORT :{BLACK}International airport
+STR_COMMUTER_AIRPORT :{BLACK}Commuter
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Intercontinental
+STR_HELIPORT :{BLACK}Heliport
+STR_HELIDEPOT :{BLACK}Helidepot
+STR_HELISTATION :{BLACK}Helistation
+
+STR_SMALL_AIRPORTS :{BLACK}Small airports
+STR_LARGE_AIRPORTS :{BLACK}Large airports
+STR_HUB_AIRPORTS :{BLACK}Hub airports
+STR_HELIPORTS :{BLACK}Helicopter airports
+
+############ Tooltip measurment
+
+STR_MEASURE_LENGTH :{BLACK}Length: {NUM}
+STR_MEASURE_AREA :{BLACK}Area: {NUM} x {NUM}
+STR_MEASURE_LENGTH_HEIGHTDIFF :{BLACK}Length: {NUM}{}Height difference: {NUM} m
+STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}Area: {NUM} x {NUM}{}Height difference: {NUM} m
+
+########
diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt
new file mode 100644
index 000000000..580206fa6
--- /dev/null
+++ b/src/lang/brazilian_portuguese.txt
@@ -0,0 +1,3109 @@
+##name Brazilian_Portuguese
+##ownname Português-Brasil
+##isocode pt_BR.UTF-8
+##plural 2
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Fora do mapa
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Muito próximo da borda do mapa
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Não há dinheiro - requer {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}É necessário terreno plano
+STR_0008_WAITING :{BLACK}Aguardando: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (em rota de
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Aceita: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Aceita: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :Passageiros
+STR_0010_COAL :Carvão
+STR_0011_MAIL :Correspondências
+STR_0012_OIL :Petróleo
+STR_0013_LIVESTOCK :Gado
+STR_0014_GOODS :Bens
+STR_0015_GRAIN :Grão
+STR_0016_WOOD :Madeira
+STR_0017_IRON_ORE :Minério de Ferro
+STR_0018_STEEL :Aço
+STR_0019_VALUABLES :Monetários
+STR_001A_COPPER_ORE :Minério de Cobre
+STR_001B_MAIZE :Milho
+STR_001C_FRUIT :Fruta
+STR_001D_DIAMONDS :Diamantes
+STR_001E_FOOD :Comida
+STR_001F_PAPER :Papel
+STR_0020_GOLD :Ouro
+STR_0021_WATER :Ãgua
+STR_0022_WHEAT :Trigo
+STR_0023_RUBBER :Borracha
+STR_0024_SUGAR :Açúcar
+STR_0025_TOYS :Brinquedos
+STR_0026_CANDY :Doces
+STR_0027_COLA :Cola
+STR_0028_COTTON_CANDY :Algodão Doce
+STR_0029_BUBBLES :Bolhas
+STR_002A_TOFFEE :Caramelo
+STR_002B_BATTERIES :Baterias
+STR_002C_PLASTIC :Plástico
+STR_002D_FIZZY_DRINKS :Bebidas Gasosas
+STR_002E :
+STR_002F_PASSENGER :Passageiro
+STR_0030_COAL :Carvão
+STR_0031_MAIL :Correspondências
+STR_0032_OIL :Petróleo
+STR_0033_LIVESTOCK :Gado
+STR_0034_GOODS :Bens
+STR_0035_GRAIN :Cereais
+STR_0036_WOOD :Madeira
+STR_0037_IRON_ORE :Minério de Ferro
+STR_0038_STEEL :Aço
+STR_0039_VALUABLES :Monetários
+STR_003A_COPPER_ORE :Minério de Cobre
+STR_003B_MAIZE :Milho
+STR_003C_FRUIT :Fruta
+STR_003D_DIAMOND :Diamantes
+STR_003E_FOOD :Comida
+STR_003F_PAPER :Papel
+STR_0040_GOLD :Ouro
+STR_0041_WATER :Ãgua
+STR_0042_WHEAT :Trigo
+STR_0043_RUBBER :Borracha
+STR_0044_SUGAR :Açúcar
+STR_0045_TOY :Brinquedos
+STR_0046_CANDY :Doces
+STR_0047_COLA :Cola
+STR_0048_COTTON_CANDY :Algodão Doce
+STR_0049_BUBBLE :Bolhas
+STR_004A_TOFFEE :Caramelo
+STR_004B_BATTERY :Baterias
+STR_004C_PLASTIC :Plástico
+STR_004D_FIZZY_DRINK :Bebidas Gasosas
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} passageiro{P "" s}
+STR_QUANTITY_COAL :{WEIGHT} de carvão
+STR_QUANTITY_MAIL :{COMMA} saco{P "" s} de correspondências
+STR_QUANTITY_OIL :{VOLUME} de petróleo
+STR_QUANTITY_LIVESTOCK :{COMMA} insumo{P "" s} de gado
+STR_QUANTITY_GOODS :{COMMA} caixas de bens
+STR_QUANTITY_GRAIN :{WEIGHT} de cereais
+STR_QUANTITY_WOOD :{WEIGHT} de madeira
+STR_QUANTITY_IRON_ORE :{WEIGHT} de minério de ferro
+STR_QUANTITY_STEEL :{WEIGHT} de aço
+STR_QUANTITY_VALUABLES :{COMMA} saco{P "" s} de valores
+STR_QUANTITY_COPPER_ORE :{WEIGHT} de minério de cobre
+STR_QUANTITY_MAIZE :{WEIGHT} de milho
+STR_QUANTITY_FRUIT :{WEIGHT} de fruta
+STR_QUANTITY_DIAMONDS :{COMMA} saco{P "" s} de diamantes
+STR_QUANTITY_FOOD :{WEIGHT} de comida
+STR_QUANTITY_PAPER :{WEIGHT} de papel
+STR_QUANTITY_GOLD :{COMMA} saco{P "" s} de ouro
+STR_QUANTITY_WATER :{VOLUME} de água
+STR_QUANTITY_WHEAT :{WEIGHT} de trigo
+STR_QUANTITY_RUBBER :{VOLUME} de borracha
+STR_QUANTITY_SUGAR :{WEIGHT} de açúcar
+STR_QUANTITY_TOYS :{COMMA} brinquedo{P "" s}
+STR_QUANTITY_SWEETS :{COMMA} saco{P "" s} de doces
+STR_QUANTITY_COLA :{VOLUME} de cola
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} de algodão doce
+STR_QUANTITY_BUBBLES :{COMMA} bolha{P "" s}
+STR_QUANTITY_TOFFEE :{WEIGHT} de caramelo
+STR_QUANTITY_BATTERIES :{COMMA} bateria{P "" s}
+STR_QUANTITY_PLASTIC :{VOLUME} de plástico
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} bebida{P "" s} gasosa
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}PS
+STR_ABBREV_COAL :{TINYFONT}CL
+STR_ABBREV_MAIL :{TINYFONT}ML
+STR_ABBREV_OIL :{TINYFONT}OL
+STR_ABBREV_LIVESTOCK :{TINYFONT}LV
+STR_ABBREV_GOODS :{TINYFONT}GD
+STR_ABBREV_GRAIN :{TINYFONT}GR
+STR_ABBREV_WOOD :{TINYFONT}WD
+STR_ABBREV_IRON_ORE :{TINYFONT}OR
+STR_ABBREV_STEEL :{TINYFONT}ST
+STR_ABBREV_VALUABLES :{TINYFONT}VL
+STR_ABBREV_COPPER_ORE :{TINYFONT}CO
+STR_ABBREV_MAIZE :{TINYFONT}MZ
+STR_ABBREV_FRUIT :{TINYFONT}FT
+STR_ABBREV_DIAMONDS :{TINYFONT}DM
+STR_ABBREV_FOOD :{TINYFONT}FD
+STR_ABBREV_PAPER :{TINYFONT}PR
+STR_ABBREV_GOLD :{TINYFONT}GD
+STR_ABBREV_WATER :{TINYFONT}WR
+STR_ABBREV_WHEAT :{TINYFONT}WH
+STR_ABBREV_RUBBER :{TINYFONT}RB
+STR_ABBREV_SUGAR :{TINYFONT}SG
+STR_ABBREV_TOYS :{TINYFONT}TY
+STR_ABBREV_SWEETS :{TINYFONT}SW
+STR_ABBREV_COLA :{TINYFONT}CL
+STR_ABBREV_CANDYFLOSS :{TINYFONT}CF
+STR_ABBREV_BUBBLES :{TINYFONT}BU
+STR_ABBREV_TOFFEE :{TINYFONT}TF
+STR_ABBREV_BATTERIES :{TINYFONT}BA
+STR_ABBREV_PLASTIC :{TINYFONT}PL
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}FZ
+STR_ABBREV_NONE :{TINYFONT}NENHUM
+STR_ABBREV_ALL :{TINYFONT}TODOS
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Mapa - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Opções do Jogo
+STR_00B2_MESSAGE :{YELLOW}Mensagem
+STR_00B3_MESSAGE_FROM :{YELLOW}Mensagem de {STRING}
+STR_00B4_CAN_T_DO_THIS :{WHITE}Não é possível fazer isto....
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Não é possível limpar esta área....
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Copyright original {COPYRIGHT} 1995 Chris Sawyer, Todos os direitos reservados
+STR_00B7_VERSION :{BLACK}OpenTTD versão {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 A equipe do OpenTTD
+STR_TRANSLATED_BY :{BLACK} Tradutor(es) -
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Sair
+STR_00C8_YES :{BLACK}Sim
+STR_00C9_NO :{BLACK}Não
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Tem a certeza que deseja abandonar este jogo e voltar ao {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Nada
+STR_00D1_DARK_BLUE :Azul Escuro
+STR_00D2_PALE_GREEN :Verde Claro
+STR_00D3_PINK :Rosa
+STR_00D4_YELLOW :Amarelo
+STR_00D5_RED :Vermelho
+STR_00D6_LIGHT_BLUE :Azul Claro
+STR_00D7_GREEN :Verde
+STR_00D8_DARK_GREEN :Verde Escuro
+STR_00D9_BLUE :Azul
+STR_00DA_CREAM :Creme
+STR_00DB_MAUVE :Malva
+STR_00DC_PURPLE :Roxo
+STR_00DD_ORANGE :Laranja
+STR_00DE_BROWN :Marrom
+STR_00DF_GREY :Cinza
+STR_00E0_WHITE :Branco
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Existem muitos veículos em jogo
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Localização
+STR_00E5_CONTOURS :Contornos
+STR_00E6_VEHICLES :Veículos
+STR_00E7_INDUSTRIES :Indústrias
+STR_00E8_ROUTES :Rotas
+STR_00E9_VEGETATION :Vegetação
+STR_00EA_OWNERS :Proprietários
+STR_00EB_ROADS :{BLACK}{TINYFONT}Estradas
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Ferrovias
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Estações/Aeroportos/Docas
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Edifícios/Indústrias
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Veículos
+STR_00F0_100M :{BLACK}{TINYFONT}100m
+STR_00F1_200M :{BLACK}{TINYFONT}200m
+STR_00F2_300M :{BLACK}{TINYFONT}300m
+STR_00F3_400M :{BLACK}{TINYFONT}400m
+STR_00F4_500M :{BLACK}{TINYFONT}500m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Trens
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Veículos de Estrada
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Navios
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Aeronaves
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Rotas de Transporte
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Mina de Carvão
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Usina de Energia
+STR_00FC_FOREST :{BLACK}{TINYFONT}Floresta
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}Serraria
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Refinaria de Petróleo
+STR_00FF_FARM :{BLACK}{TINYFONT}Fazenda
+STR_0100_FACTORY :{BLACK}{TINYFONT}Fábrica
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Gráfica
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Poços de Petróleo
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Mina de Ferro
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Siderúrgica
+STR_0105_BANK :{BLACK}{TINYFONT}Banco
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Fábrica de Papel
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Mina de Ouro
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Instalacão de Processamento de Comida
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Mina de Diamantes
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Mina de Cobre
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Plantação de Frutas
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Plantação de Seringueiras
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Suprimento de Ãgua
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Depósito de Ãgua
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}Serraria
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Floresta de Algodão Doce
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Fábrica de Doces
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Fazenda de Baterias
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Poços de Cola
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Loja de Brinquedos
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Fábrica de Brinquedos
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Fontes de Plástico
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Fábrica de Bebidas Gasosas
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Produtor de Bolhas
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Extração de Caramelo
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Mina de Açúcar
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Estação Ferroviária
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Ãrea de Carregamento de Caminhões
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Estação de Ônibus
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Aeroporto/Heliporto
+STR_011F_DOCK :{BLACK}{TINYFONT}Doca
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Terreno Irregular
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Grama
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Terra Limpa
+STR_0123_FIELDS :{BLACK}{TINYFONT}Campos
+STR_0124_TREES :{BLACK}{TINYFONT}Ãrvores
+STR_0125_ROCKS :{BLACK}{TINYFONT}Rochas
+STR_0126_WATER :{BLACK}{TINYFONT}Ãgua
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Sem Proprietário
+STR_0128_TOWNS :{BLACK}{TINYFONT}Cidades
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Indústrias
+STR_012A_DESERT :{BLACK}{TINYFONT}Deserto
+STR_012B_SNOW :{BLACK}{TINYFONT}Neve
+STR_012C_MESSAGE :{WHITE}Mensagem
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Cancelar
+STR_012F_OK :{BLACK}OK
+STR_0130_RENAME :{BLACK}Renomear
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Muitos nomes definidos
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}O nome escolhido já está sendo usado
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...propriedade de {STRING}
+STR_013C_CARGO :{BLACK}Carga
+STR_013D_INFORMATION :{BLACK}Informação
+STR_013E_CAPACITIES :{BLACK}Capacidades
+STR_013E_TOTAL_CARGO :{BLACK}Carga Total
+STR_013F_CAPACITY :{BLACK}Capacidade: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}Capacidade {LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Capacidade total deste trem:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}Novo Jogo
+STR_0141_LOAD_GAME :{BLACK}Abrir Jogo
+STR_SINGLE_PLAYER :{BLACK}1 jogador
+STR_MULTIPLAYER :{BLACK}Multi-jogador
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Tamanho do mapa:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Opções do Jogo
+
+STR_0150_SOMEONE :alguém{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Mapa mundial
+STR_0152_TOWN_DIRECTORY :Lista de cidades
+STR_0153_SUBSIDIES :Subsídios
+
+STR_UNITS_IMPERIAL :Imperial
+STR_UNITS_METRIC :Métrico
+STR_UNITS_SI :SI
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} mph
+STR_UNITS_VELOCITY_METRIC :{COMMA} km/h
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}hp
+STR_UNITS_POWER_METRIC :{COMMA}hp
+STR_UNITS_POWER_SI :{COMMA}kW
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} ton{P "" s}
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} ton{P "" s}
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} kg
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}gal
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}l
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}m³
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} galão{P "" s}
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} litro{P "" s}
+STR_UNITS_VOLUME_LONG_SI :{COMMA} m³
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10³ lbf
+STR_UNITS_FORCE_METRIC :{COMMA} ton/força
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Gráfico de lucros operacionais
+STR_0155_INCOME_GRAPH :Gráfico de entrada
+STR_0156_DELIVERED_CARGO_GRAPH :Carga entregue
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Histórico de lucro
+STR_0158_COMPANY_VALUE_GRAPH :Valor da empresa
+STR_0159_CARGO_PAYMENT_RATES :Tarifas por carga
+STR_015A_COMPANY_LEAGUE_TABLE :Classificação das empresas
+STR_PERFORMANCE_DETAIL_MENU :Avaliação detalhada
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}Sobre o OpenTTD...
+STR_015C_SAVE_GAME :Salvar jogo
+STR_015D_LOAD_GAME :Abrir jogo
+STR_015E_QUIT_GAME :Abandonar jogo
+STR_015F_QUIT :Sair
+STR_ABANDON_GAME_QUERY :{YELLOW}Tem certeza que deseja abandonar este jogo?
+STR_0161_QUIT_GAME :{WHITE}Abandonar jogo
+STR_SORT_ORDER_TIP :{BLACK}Selecione forma de classificação (descendente/ascendente)
+STR_SORT_CRITERIA_TIP :{BLACK}Selecione um critério de classificação
+STR_SORT_BY :{BLACK}Classificar por
+
+STR_SORT_BY_POPULATION :{BLACK}População
+STR_SORT_BY_PRODUCTION :{BLACK}Produção
+STR_SORT_BY_TYPE :{BLACK}Tipo
+STR_SORT_BY_TRANSPORTED :{BLACK}Transportado
+STR_SORT_BY_NAME :{BLACK}Nome
+STR_SORT_BY_DROPDOWN_NAME :Nome
+STR_SORT_BY_DATE :{BLACK}Data
+STR_SORT_BY_NUMBER :Número
+STR_SORT_BY_PROFIT_LAST_YEAR :Lucros do último ano
+STR_SORT_BY_PROFIT_THIS_YEAR :Lucros deste ano
+STR_SORT_BY_AGE :Idade
+STR_SORT_BY_RELIABILITY :Confiabilidade
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Capacidade total por tipo de carga
+STR_SORT_BY_MAX_SPEED :Velocidade máxima
+STR_SORT_BY_MODEL :Modelo
+STR_SORT_BY_VALUE :Valor
+STR_SORT_BY_FACILITY :Tipo de estação
+STR_SORT_BY_WAITING :Valor da carga aguardando
+STR_SORT_BY_RATING_MAX :Taxa de Carga
+STR_ENGINE_SORT_ENGINE_ID :No de Reg (padrão)
+STR_ENGINE_SORT_COST :Custo
+STR_ENGINE_SORT_POWER :Potência
+STR_ENGINE_SORT_INTRO_DATE :Data de Introdução
+STR_ENGINE_SORT_RUNNING_COST :Custo de Manutenção
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Potência por Custo
+STR_ENGINE_SORT_CARGO_CAPACITY :Capacidade de Carga
+STR_NO_WAITING_CARGO :{BLACK}Não há carga de nenhum tipo aguardando
+STR_SELECT_ALL_FACILITIES :{BLACK}Seleicionar todas as instalações
+STR_SELECT_ALL_TYPES :{BLACK}Selecionar todos os tipos de carga (inclusive as que não tem espera)
+STR_AVAILABLE_ENGINES_TIP :{BLACK}Ver uma lista dos designs de motor disponíveis para este tipo de veículo.
+STR_MANAGE_LIST :{BLACK}Administrar lista
+STR_MANAGE_LIST_TIP :{BLACK}Envia instruções a todos os veículos desta lista
+STR_REPLACE_VEHICLES :Substituir Veículos
+STR_SEND_TRAIN_TO_DEPOT :Enviar para Depósito
+STR_SEND_ROAD_VEHICLE_TO_DEPOT :Enviar para Depósito
+STR_SEND_SHIP_TO_DEPOT :Enviar para Depósito
+STR_SEND_AIRCRAFT_TO_HANGAR :Enviar para Hangar
+STR_SEND_FOR_SERVICING :Mandar para a Manutenção
+
+############ range for months starts
+STR_0162_JAN :Jan
+STR_0163_FEB :Fev
+STR_0164_MAR :Mar
+STR_0165_APR :Abr
+STR_0166_MAY :Mai
+STR_0167_JUN :Jun
+STR_0168_JUL :Jul
+STR_0169_AUG :Ago
+STR_016A_SEP :Set
+STR_016B_OCT :Out
+STR_016C_NOV :Nov
+STR_016D_DEC :Dez
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Pausar o jogo
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Salvar jogo, abandonar jogo, sair
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Mostrar lista de estações da empresa
+STR_0174_DISPLAY_MAP :{BLACK}Mostrar mapa
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Mostrar mapa, lista de cidades
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Mostrar lista de cidades
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Mostrar informações financeiras da empresa
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Mostrar informações gerais da empresa
+STR_0179_DISPLAY_GRAPHS :{BLACK}Mostrar gráficos
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Mostrar tabela de classificação de empresas
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Mostrar lista de trens da empresa
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Mostrar lista de veículos de estrada da empresa
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Mostrar lista de barcos da empresa
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Mostrar lista de aeronaves da empresa
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Ampliar
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Reduzir
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Construir ferrovias
+STR_0182_BUILD_ROADS :{BLACK}Construir estradas
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Construir docas
+STR_0184_BUILD_AIRPORTS :{BLACK}Construir aeroportos
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Plantar árvores, colocar placas, etc...
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Informações do terreno
+STR_0187_OPTIONS :{BLACK}Opções
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Não é possível alterar o intervalo de manutenção...
+STR_018B_CLOSE_WINDOW :{BLACK}Fechar janela
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Título da janela - arraste para mover a janela
+STR_STICKY_BUTTON :{BLACK}Marcar esta janela para não fechar pela tecla 'Fechar Todas as Janelas'
+STR_RESIZE_BUTTON :{BLACK}Clique e arraste para redimensionar a janela
+STR_SAVELOAD_HOME_BUTTON :{BLACK}Clique aqui para selecionar o diretório padrão de jogos salvos
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Demolir edifícios, etc. num quadrado de terreno
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Baixar um canto do terreno
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Levantar um canto do terreno
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Barra de rolamento - rola a lista acima/abaixo
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Barra de rolagem - Move a lista para esquerda/direita
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Mostrar contornos do terreno no mapa
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Mostrar veículos no mapa
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Mostrar indústrias no mapa
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Mostrar rotas de transporte no mapa
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Mostrar vegetação no mapa
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Mostrar proprietários do terreno no mapa
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Mostrar nomes das cidades no mapa
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Lucro deste ano: {CURRENCY} (ano passado: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} ano{P "" s} ({COMMA})
+STR_AGE_RED :{RED}{COMMA} ano{P "" s} ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Automóvel
+STR_019D_AIRCRAFT :Aeronave
+STR_019E_SHIP :Navio
+STR_019F_TRAIN :Trem
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} está a ficando velho
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} está ficando muito velho
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} está ficando muito velho e necessita ser substituído urgentemente
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Informações do Terreno
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Custo para limpar: {LTBLUE}N/D
+STR_01A5_COST_TO_CLEAR :{BLACK}Custo para limpar: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :N/D
+STR_01A7_OWNER :{BLACK}Proprietário: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Autoridade local: {LTBLUE}{STRING}
+STR_01A9_NONE :Nenhum
+STR_01AA_NAME :{BLACK}Nome
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1o
+STR_01AD_2ND :2o
+STR_01AE_3RD :3o
+STR_01AF_4TH :4o
+STR_01B0_5TH :5o
+STR_01B1_6TH :6o
+STR_01B2_7TH :7o
+STR_01B3_8TH :8o
+STR_01B4_9TH :9o
+STR_01B5_10TH :10o
+STR_01B6_11TH :11o
+STR_01B7_12TH :12o
+STR_01B8_13TH :13o
+STR_01B9_14TH :14o
+STR_01BA_15TH :15o
+STR_01BB_16TH :16o
+STR_01BC_17TH :17o
+STR_01BD_18TH :18o
+STR_01BE_19TH :19o
+STR_01BF_20TH :20o
+STR_01C0_21ST :21o
+STR_01C1_22ND :22o
+STR_01C2_23RD :23o
+STR_01C3_24TH :24o
+STR_01C4_25TH :25o
+STR_01C5_26TH :26o
+STR_01C6_27TH :27o
+STR_01C7_28TH :28o
+STR_01C8_29TH :29o
+STR_01C9_30TH :30o
+STR_01CA_31ST :31o
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Carga aceita: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Músicas
+STR_01D3_SOUND_MUSIC :Som/música
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Mostrar janela som/música
+STR_01D5_ALL :{TINYFONT}Todos
+STR_01D6_OLD_STYLE :{TINYFONT}Antigo
+STR_01D7_NEW_STYLE :{TINYFONT}Moderno
+STR_01D8_EZY_STREET :{TINYFONT}Easy Street
+STR_01D9_CUSTOM_1 :{TINYFONT}Personaliz. 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Personaliz. 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Volume da Música
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Volume dos efeitos
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MIN ' ' ' ' ' ' MAX
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Mudar para a faixa anterior da seleção
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Mudar para a faixa seguinte da seleção
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Parar a reprodução de música
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Iniciar reprodução de música
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Arraste os cursores para ajustar o volume da música e efeitos sonoros
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}'{STRING}'
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Faixa{SETX 88}Título
+STR_01E9_SHUFFLE :{TINYFONT}Embaralhar
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Programa
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Programação Musical
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} '{STRING}'
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} '{STRING}'
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Ãndice de faixas
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Programa - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}Limpar
+STR_01F1_SAVE :{TINYFONT}{BLACK}Salvar
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Programação atual de faixas de música
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Selecionar programa 'todas as faixas'
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Selecionar programa 'estilo antigo'
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Selecionar programa 'estilo moderno'
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Selecionar programa 'Personalizado 1'
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Selecionar programa 'Personalizado 2'
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Limpar programa atual (somente Personaliz. 1 ou Personaliz. 2)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Gravar configuração de música
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Clique na faixa de música para a adicionar ao programa atual (somente Personaliz. 1 ou Personaliz. 2)
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Clique na música para remover da programação (Custom1 ou Custom2 somente)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Ligar/Desligar programa aleatório
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Mostrar janela de seleção de faixas de música
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Clique num serviço para centralizar a visualização numa indústria/cidade
+STR_01FE_DIFFICULTY :{BLACK}Dificuldade ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Última mensagem/notícia
+STR_0201_MESSAGE_SETTINGS :Opções de mensagens
+STR_MESSAGE_HISTORY_MENU :Histórico de Mensagens
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Mostrar última mensagem/notícia, mostrar opções de mensagens
+STR_0204_MESSAGE_OPTIONS :{WHITE}Opções de Mensagens
+STR_0205_MESSAGE_TYPES :{BLACK}Tipos de mensagens:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Chegada do primeiro veículo à estação do jogador
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Chegada do primeiro veículo à estação de um oponente
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Acidentes / desastres
+STR_0209_COMPANY_INFORMATION :{YELLOW}Informações da empresa
+STR_020A_ECONOMY_CHANGES :{YELLOW}Alterações econômicas
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Avisos / informações dos veículos do jogador
+STR_020C_NEW_VEHICLES :{YELLOW}Novos veículos
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Alterações de aceitação de carga
+STR_020E_SUBSIDIES :{YELLOW}Subsídios
+STR_020F_GENERAL_INFORMATION :{YELLOW}Informações gerais
+STR_MESSAGES_ALL :{YELLOW}Configurações para todos os tipos de mensagem(on/off/resumo)
+STR_MESSAGE_SOUND :{YELLOW}Tocar som para notícias resumidas
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...muito distante do destino anterior
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Top de companhias que chegaram a {NUM}{}({STRING} Nivél)
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Tabela da Liga de Companhias em {NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Negociante
+STR_0214_ENTREPRENEUR :Empresário
+STR_0215_INDUSTRIALIST :Industrial
+STR_0216_CAPITALIST :Capitalista
+STR_0217_MAGNATE :Magnata
+STR_0218_MOGUL :Grande magnata
+STR_0219_TYCOON_OF_THE_CENTURY :Magnata do século
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} conquista o status de '{STRING}'!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} de {COMPANY} conquista o status de '{STRING}'!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Criar Cenário
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Editor de Cenário
+STR_0223_LAND_GENERATION :{WHITE}Gerar Terreno
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Terreno Aleatório
+STR_0227_RESET_LAND :{BLACK}Resetar Terreno
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Aumentar área de terreno a baixar/levantar
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Diminuir área de terreno a baixar/levantar
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Gerar terreno aleatório
+STR_022B_RESET_LANDSCAPE :{BLACK}Resetar terreno
+STR_022C_RESET_LANDSCAPE :{WHITE}Resetar Terreno
+STR_LOAD_GAME_HEIGHTMAP :{WHITE}Usar mapa de altitudes
+STR_LOAD_SCEN_HEIGHTMAP :{BLACK}Usar mapa de altitudes
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Tem a certeza que deseja resetar o terreno?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Gerar terreno
+STR_022F_TOWN_GENERATION :{BLACK}Gerar cidades
+STR_0230_INDUSTRY_GENERATION :{BLACK}Gerar indústrias
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Construir estradas
+STR_0233_TOWN_GENERATION :{WHITE}Gerar Cidades
+STR_0234_NEW_TOWN :{BLACK}Nova Cidade
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Construir nova cidade
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Não é possível construir uma cidade aqui...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...muito perto da borda do mapa
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...muito perto de outra cidade
+STR_0239_SITE_UNSUITABLE :{WHITE}...local inadequado
+STR_023A_TOO_MANY_TOWNS :{WHITE}...muitas cidades
+STR_CANNOT_GENERATE_TOWN :{WHITE}Impossível construir qualquer cidade
+STR_NO_SPACE_FOR_TOWN :{WHITE}...não há espaço no mapa
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Aumentar o tamanho da cidade
+STR_023C_EXPAND :{BLACK}Expandir
+STR_023D_RANDOM_TOWN :{BLACK}Cidade Aleatória
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Construir uma cidade num local aleatório
+STR_023F_INDUSTRY_GENERATION :{WHITE}Gerar Indústrias
+STR_0240_COAL_MINE :{BLACK}Mina de Carvão
+STR_0241_POWER_STATION :{BLACK}Usina de Energia
+STR_0242_SAWMILL :{BLACK}Serraria
+STR_0243_FOREST :{BLACK}Floresta
+STR_0244_OIL_REFINERY :{BLACK}Refinaria de Petróleo
+STR_0245_OIL_RIG :{BLACK}Plataforma Petrolífera
+STR_0246_FACTORY :{BLACK}Fábrica
+STR_0247_STEEL_MILL :{BLACK}Siderúrgica
+STR_0248_FARM :{BLACK}Fazenda
+STR_0249_IRON_ORE_MINE :{BLACK}Mina de Ferro
+STR_024A_OIL_WELLS :{BLACK}Poços de Petróleo
+STR_024B_BANK :{BLACK}Banco
+STR_024C_PAPER_MILL :{BLACK}Fábrica de Papel
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Companhia Alimenticia
+STR_024E_PRINTING_WORKS :{BLACK}Gráfica
+STR_024F_GOLD_MINE :{BLACK}Mina de Ouro
+STR_0250_LUMBER_MILL :{BLACK}Fábrica de Madeira
+STR_0251_FRUIT_PLANTATION :{BLACK}Plantação de Frutas
+STR_0252_RUBBER_PLANTATION :{BLACK}Plantação de Seringueiras
+STR_0253_WATER_SUPPLY :{BLACK}Suprimento de Ãgua
+STR_0254_WATER_TOWER :{BLACK}Torre de Ãgua
+STR_0255_DIAMOND_MINE :{BLACK}Mina de Diamantes
+STR_0256_COPPER_ORE_MINE :{BLACK}Mina de Cobre
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Floresta de Algodão Doce
+STR_0258_CANDY_FACTORY :{BLACK}Fábrica de Doces
+STR_0259_BATTERY_FARM :{BLACK}Fazenda de Baterias
+STR_025A_COLA_WELLS :{BLACK}Poços de Cola
+STR_025B_TOY_SHOP :{BLACK}Loja de Brinquedos
+STR_025C_TOY_FACTORY :{BLACK}Fábrica de Brinquedos
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Fontes de Plástico
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Fontes de Bebidas Gasosas
+STR_025F_BUBBLE_GENERATOR :{BLACK}Produtor de Bolhas
+STR_0260_TOFFEE_QUARRY :{BLACK}Extração de Caramelo
+STR_0261_SUGAR_MINE :{BLACK}Mina de Açúcar
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Construir Mina de Carvão
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Construir Usina de Energia
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Construir Serraria
+STR_0265_PLANT_FOREST :{BLACK}Plantar Floresta
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Construir Refinaria de Petróleo
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Construir Plataforma de Petróleo (Só pode ser construída perto das bordas do mapa)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Construir Fábrica
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Construir Siderúrgica
+STR_026A_CONSTRUCT_FARM :{BLACK}Construir Fazenda
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Construir Mina de Ferro
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Construir Poços de Petróleo
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Construir Banco (só pode ser construído em cidades com mais de 1200 habitantes)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Construir Fábrica de Papel
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Construir Instalação de Processamento de Comida
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Construir Gráfica
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Construir Mina de Ouro
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Construir Banco (só pode ser construído em cidades)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Construir Fábrica de Madeira (para limpar a floresta e produzir Madeira)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Criar Plantação de Frutas
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Criar Plantação de Seringueiras
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Construir Suprimento de Ãgua
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Construir Torre de Ãgua (só pode ser construído em cidades)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Construir Mina de Diamantes
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Construir Mina de Cobre
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Plantar Floresta de Algodão Doce
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Construir Fábrica de Doces
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Construir Fazenda de Baterias
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Construir Poços de Cola
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Construir Loja de Brinquedos
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Construir Fábrica de Brinquedos
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Construir Fontes de Plástico
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Construir Fábrica de Bebidas Gasosas
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Construir Produtor de Bolhas
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Construir Extração de Caramelo
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Construir Mina de Açúcar
+STR_0285_CAN_T_BUILD_HERE :{WHITE}Não é possível construir {STRING} aqui...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...é necessário construir uma cidade primeiro
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...só é permitido uma por cidade
+STR_0288_PLANT_TREES :{BLACK}Plantar árvores
+STR_0289_PLACE_SIGN :{BLACK}Colocar placas
+STR_028A_RANDOM_TREES :{BLACK}Plantar Aleatoriamente
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Plantar árvores aleatoriamente no terreno
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Colocar rochas no terreno
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Colocar farol
+STR_028E_PLACE_TRANSMITTER :{BLACK}Colocar transmissor
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Define área desértica.{}Pressione e segure CTRL para remove-la
+STR_CREATE_LAKE :{BLACK}Define área de água.{}Ela irá inundar quando no nível do mar
+STR_0290_DELETE :{BLACK}Apagar
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Apagar completamente esta cidade
+STR_0292_SAVE_SCENARIO :Salvar cenário
+STR_0293_LOAD_SCENARIO :Abrir cenário
+STR_0294_QUIT_EDITOR :Sair do editor
+STR_0295 :
+STR_0296_QUIT :Sair
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Salvar cenário, abrir cenário, abandonar editor de cenário, sair
+STR_0298_LOAD_SCENARIO :{WHITE}Abrir Cenário
+STR_0299_SAVE_SCENARIO :{WHITE}Guardar Cenário
+STR_029A_PLAY_SCENARIO :{BLACK}Jogar Cenário
+STR_PLAY_HEIGHTMAP :{BLACK}Jogar num mapa de altitudes
+STR_PLAY_HEIGHTMAP_HINT :{BLACK}Inica um novo jogo, a partir de um mapa de altitude
+STR_QUIT_SCENARIO_QUERY :{YELLOW}Tem a certeza que deseja abandonar este cenário?
+STR_029C_QUIT_EDITOR :{WHITE}Sair do Editor
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...só pode ser construído em cidades com pelo menos 1200 habitantes
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Retroceder data de inicio 1 ano
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Avançar data de inicio 1 ano
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...ambos os extremos da ponte devem estar em terra
+STR_02A1_SMALL :{BLACK}Pequena
+STR_02A2_MEDIUM :{BLACK}Média
+STR_02A3_LARGE :{BLACK}Grande
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Selecione o tamanho da cidade
+STR_02A5_TOWN_SIZE :{YELLOW}Tamanho da cidade:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Mostrar a última mensagem ou notícia
+STR_OFF :Off
+STR_SUMMARY :Resumo
+STR_FULL :Completo
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Lista de cidades
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Nomes dos veículos
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Predefinição
+STR_02BF_CUSTOM :Personalizado
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Gravar nomes personalizados
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Seleção de nomes dos veículos
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Salvar nomes dos veículos personalizados no disco
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Opções do Jogo
+STR_02C5_DIFFICULTY_SETTINGS :Configurações de dificuldade
+STR_02C7_CONFIG_PATCHES :Configurar correções
+STR_NEWGRF_SETTINGS :Definições Newgrf
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Mostrar nomes de cidades
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Mostrar nomes de estações
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Mostrar indicações
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Mostrar pontos de controle
+STR_02D0_FULL_ANIMATION :{SETX 12}Animação completa
+STR_02D2_FULL_DETAIL :{SETX 12}Máximo de detalhes
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Edifícios transparentes
+STR_TRANSPARENT_SIGNS :{SETX 12}Nomes de estações transparentes
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Informações do terreno
+STR_02D6 :
+STR_CONSOLE_SETTING :Ativar/desativar console
+STR_02D7_SCREENSHOT_CTRL_S :Captura de tela (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Captura gigante (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :Sobre o OpenTTD...
+############ range ends here
+
+STR_02DB_OFF :{BLACK}Off
+STR_02DA_ON :{BLACK}On
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Mostrar subsídios
+STR_02DD_SUBSIDIES :Subsídios
+STR_02DE_MAP_OF_WORLD :Mapa do mundo
+STR_EXTRA_VIEW_PORT :Visualizador extra
+STR_SIGN_LIST :Lista de sinais
+STR_02DF_TOWN_DIRECTORY :Lista de cidades
+STR_TOWN_POPULATION :{BLACK}População Mundial: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Visualizador {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Copiar para o visualizador
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Copiar a localização do visualizador global para este visualizador
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Colar do visualizador
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Colar a localização deste visualizador para o visualizador global
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Unidades monetárias
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Seleção de unidades monetárias
+STR_MEASURING_UNITS :{BLACK}Unidade de medida
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Seleção da unidade de medida
+STR_02E6_ROAD_VEHICLES :{BLACK}Veículos de estrada
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Seleccione o lado da estrada por onde os veículos deverão andar
+STR_02E9_DRIVE_ON_LEFT :Andam pela esquerda
+STR_02EA_DRIVE_ON_RIGHT :Andam pela direita
+STR_02EB_TOWN_NAMES :{BLACK}Nomes das cidades
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Selecionar o estilo dos nomes das cidades
+
+STR_02F4_AUTOSAVE :{BLACK}Salvar automaticamente
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Selecionar o intervalo para salvar automáticamente
+STR_02F7_OFF :Desativado
+STR_02F8_EVERY_3_MONTHS :A cada 3 meses
+STR_02F9_EVERY_6_MONTHS :A cada 6 meses
+STR_02FA_EVERY_12_MONTHS :A cada 12 meses
+STR_02FB_START_A_NEW_GAME :{BLACK}Iniciar um novo jogo
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Carregar um jogo gravado
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Criar um cenário de jogo personalizado
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Selecionar jogo de 1 jogador
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Selecione jogo multiplayer de 2 a 8 jogadores
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Mostrar opções de jogo
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Mostrar opções de dificuldade
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Iniciar um novo jogo, utilizando um cenário personalizado gravado no disco
+STR_0304_QUIT :{BLACK}Sair
+STR_0305_QUIT_OPENTTD :{BLACK}Sair de 'OpenTTD'
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...só se pode construir em cidades
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Selecionar cenário do estilo 'temperado'
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Selecionar cenário do estilo 'subárctico'
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Selecionar cenário do estilo 'subtropical'
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Selecionar cenário do estilo 'toyland'
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Financiar a construção de uma nova indústria
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Lista de Indústrias
+STR_0313_FUND_NEW_INDUSTRY :Financiar nova indústria
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Financiar nova indústria
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...só se pode construir em cidades
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...só se pode construir em zonas de floresta
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...só se pode construir em zonas de deserto
+STR_0319_PAUSED :{YELLOW}* * EM PAUSA * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Captura de tela gravada com sucesso como '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}A foto falhou!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Comprar terreno para uso futuro
+STR_032F_AUTOSAVE :{RED}Gravado automaticamente
+STR_SAVING_GAME :{RED}* * SALVANDO JOGO * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}Gravação em progresso,{}por favor aguarde até que termine!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Selecionar programa 'Ezy Street'
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :Inglês
+STR_TOWNNAME_FRENCH :Francês
+STR_TOWNNAME_GERMAN :Alemão
+STR_TOWNNAME_ADDITIONAL_ENGLISH :Inglês (Adicional)
+STR_TOWNNAME_LATIN_AMERICAN :Latino-Americano
+STR_TOWNNAME_SILLY :Absurdo
+STR_TOWNNAME_SWEDISH :Sueco
+STR_TOWNNAME_DUTCH :Holandês
+STR_TOWNNAME_FINNISH :Finlandês
+STR_TOWNNAME_POLISH :Polaco
+STR_TOWNNAME_SLOVAKISH :Eslovaco
+STR_TOWNNAME_NORWEGIAN :Noreguês
+STR_TOWNNAME_HUNGARIAN :Húngaro
+STR_TOWNNAME_AUSTRIAN :Austríaco
+STR_TOWNNAME_ROMANIAN :Romeno
+STR_TOWNNAME_CZECH :Checo
+STR_TOWNNAME_SWISS :Suiça
+STR_TOWNNAME_DANISH :Dinamarquês
+STR_TOWNNAME_TURKISH :Turco
+STR_TOWNNAME_ITALIAN :Italiano
+STR_TOWNNAME_CATALAN :Catalão
+############ end of townname region
+
+STR_CURR_GBP :Libras (£)
+STR_CURR_USD :Dólar ($)
+STR_CURR_EUR :Euro (€)
+STR_CURR_YEN :Yen (Â¥)
+STR_CURR_ATS :Shilling Austríaco (ATS)
+STR_CURR_BEF :Franco Belga (BEF)
+STR_CURR_CHF :Franco Suíço (CHF)
+STR_CURR_CZK :Coroa Checa (CZK)
+STR_CURR_DEM :Marco Alemão (DEM)
+STR_CURR_DKK :Coroa Dinamarquesa (DKK)
+STR_CURR_ESP :Peseta (ESP)
+STR_CURR_FIM :Marco Finlandês (FIM)
+STR_CURR_FRF :Franco (FRF)
+STR_CURR_GRD :Dracma Grego (GRD)
+STR_CURR_HUF :Forint Húngaro (HUF)
+STR_CURR_ISK :Coroa Islandesa (ISK)
+STR_CURR_ITL :Lira Italiana (ITL)
+STR_CURR_NLG :Guilda Holandesa (NLG)
+STR_CURR_NOK :Coroa Norueguesa (NOK)
+STR_CURR_PLN :Zloty Polaco (PLN)
+STR_CURR_ROL :Lei Romeno (ROL)
+STR_CURR_RUR :Rublo Russo (RUR)
+STR_CURR_SIT :Tolar Eslovênio (SIT)
+STR_CURR_SEK :Coroa Sueca (SEK)
+STR_CURR_YTL :Lira Turca (YTL)
+STR_CURR_SKK :Koruna Eslovaca (SKK)
+STR_CURR_BRR :Real Brasileiro (BRL)
+
+STR_CURR_CUSTOM :Personalizado...
+
+STR_OPTIONS_LANG :{BLACK}Idioma
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Selecionar o idioma da interface do jogo
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Tela Inteira
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}Selecione esta opção para jogar o OpenTTD em modo de tela inteiro
+
+STR_OPTIONS_RES :{BLACK}Resolução da tela
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Selecione a resolução de tela que deseja utilizar
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Formato da foto
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Selecione o formato de foto que deseja utilizar
+
+STR_AUTOSAVE_1_MONTH :A cada mês
+STR_AUTOSAVE_FAILED :{WHITE}Falha ao salvar automaticamente
+
+STR_MONTH_JAN :Janeiro
+STR_MONTH_FEB :Fevereiro
+STR_MONTH_MAR :Março
+STR_MONTH_APR :Abril
+STR_MONTH_MAY :Maio
+STR_MONTH_JUN :Junho
+STR_MONTH_JUL :Julho
+STR_MONTH_AUG :Agosto
+STR_MONTH_SEP :Setembro
+STR_MONTH_OCT :Outubro
+STR_MONTH_NOV :Novembro
+STR_MONTH_DEC :Dezembro
+
+STR_HEADING_FOR_STATION :{LTBLUE}Dirigindo-se para {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}Dirigindo-se para {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Sem ordens
+STR_NO_ORDERS_VEL :{LTBLUE}Sem ordens, {VELOCITY}
+
+STR_PASSENGERS :passageiros
+STR_BAGS :sacos
+STR_TONS :toneladas
+STR_LITERS :litros
+STR_ITEMS :itens
+STR_CRATES :caixas
+STR_RES_OTHER :outra
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Não é possível compartilhar a lista de ordens...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Não é possível copiar a lista de ordens...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - Fim de Ordens Compartilhadas - -
+
+STR_TRAIN_IS_LOST :{WHITE}O trem {COMMA} está perdido.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}O lucro do trem {COMMA} no último ano foi de {CURRENCY}
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}União Monetária Europeia!{}{}O Euro é introduzido como moeda única para todas as transações no seu país!
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}O trem {COMMA} tem muito poucas ordens definidas
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}O trem {COMMA} tem uma ordem inválida
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}O trem {COMMA} tem ordens duplicadas
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}O trem {COMMA} tem uma estação inválida nas suas ordens
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}O veículo de estrada {COMMA} tem muito poucas ordens definidas
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}O veículo de estrada {COMMA} tem uma ordem inválida
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}O veículo de estrada {COMMA} tem ordens duplicadas
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}O veículo de estrada {COMMA} tem uma estação inválida nas suas ordens
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}O barco {COMMA} tem muito poucas ordens definidas
+STR_SHIP_HAS_VOID_ORDER :{WHITE}O barco {COMMA} tem uma ordem inválida
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}O barco {COMMA} tem ordens duplicadas
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}O barco {COMMA} tem uma estação inválida nas suas ordens
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}A aeronave {COMMA} tem muito poucas ordens definidas
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}A aeronave {COMMA} tem uma ordem inválida
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}A aeronave {COMMA} tem ordens duplicadas
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}A aeronave {COMMA} tem uma estação inválida nas suas ordens
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}A auto-renovação do trem {COMMA} falhou (limite de dinheiro)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}A auto-renovação do veículo de estrada {COMMA} falhou (limite de dinheiro)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}A auto-renovação do barco {COMMA} falhou (limite de dinheiro)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}A auto-renovação da aeronave {COMMA} falhou (limite de dinheiro)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}O trem {COMMA} ficará muito longo após a reposição
+
+STR_CONFIG_PATCHES :{BLACK}Configurar Correções
+STR_CONFIG_PATCHES_TIP :{BLACK}Configurar as correções
+STR_CONFIG_PATCHES_CAPTION :{WHITE}Configurar Correções
+
+STR_CONFIG_PATCHES_OFF :Off
+STR_CONFIG_PATCHES_ON :On
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Mostrar velocidade do veículo na barra de estado: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Permitir a construção em declives e encostas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Permitir dimensionamento mais realista das áreas de abrangência: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Permitir a remoção de mais estradas, pontes, etc. das cidades: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Permitir a construção de trens muito longos: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Ativar aceleração realista para trens: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Proibir trens e barcos de virar em angulos de 90 graus: {ORANGE}{STRING} {LTBLUE} (requer NPF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Unir estações ferroviárias construídas juntas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Deixar a estação quando uma das cargas estiver completa: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Usar algoritmo de carregamento melhorado: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GRADUAL_LOADING :{LTBLUE}Carregar veículos gradualmente: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Inflação: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Somente entregar carga a uma estação quando houver procura: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Permitir a construção de pontes muito longas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Permitir ordens de ir para o depósito: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Permitir construção de indústrias de matérias-primas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Permitir várias indústrias semelhantes por cidade: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Indústrias do mesmo tipo podem ser construídas próximas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Mostrar sempre a data completa na barra de estado: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Mostrar sinais no lado da circulação: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Mostrar janela das finanças no fim do ano: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}Função non-stop compatível com TTDPatch: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Fila de veículos de estrada (com efeitos de quantidade): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Deslocar janela quando o cursor está na borda do mapa: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Permitir o suborno da autoridade local: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Estações não uniformes: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Novo busca de caminho global (NPF, sobrepõe NTP): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FREIGHT_TRAINS :{LTBLUE}Multiplicador de peso para comboios para simular trens pesados: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Permitir sempre aeroportos pequenos: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Avisar se o trem está perdido: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Analisar ordens dos veículos: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :Não
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :Sim, mas excluir veículos parados
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :de todos os veículos
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Avisar se o lucro de um trem for negativo: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Veículos nunca expiram: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Auto-renovação de veículos quando ficam velhos
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Auto-renovação do veículo {ORANGE}{STRING}{LTBLUE} meses antes/depois da idade máx.
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Dinheiro mínimo para fazer auto-renovação: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Duração das mensagens de erro: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Mostra população da cidade na janela da cidade: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Ãrvores invisíveis (com edifícios transparentes): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Gerador de Terreno: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :Original
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis
+STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}Distância máxima da borda para Refinarias de Petróleo {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Altitude da linha de neve: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN :{LTBLUE}Irregularidade do terreno (TerraGenesis apenas) : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Muito Regular
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH :Regular
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH :Irregular
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :Muito Irregular
+STR_CONFIG_PATCHES_TREE_PLACER :{LTBLUE}Algorítimo de colocação de árvores: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TREE_PLACER_NONE :Nenhum
+STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL :Original
+STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED :Melhorado
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION :{LTBLUE}Rotação do mapa de altitudes: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Sentido Anti-Horário
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE :Sentido Horário
+STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT :{LTBLUE}A altitude de um mapa regular é de: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Tamanho máx. de estações: {ORANGE}{STRING} {RED}Valores altos tornam o jogo lento!
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Manutenção automática de helicópteros em heliportos: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Ligar ferramentas de terreno às ferramentas de transportes: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Rolar a tela no sentido oposto ao movimento do mouse: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Mostrar distâncias quando usar ferramentas de construção: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Mostrar cores de companhias: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES_NONE :Nenhum
+STR_CONFIG_PATCHES_LIVERIES_OWN :Minha empresa
+STR_CONFIG_PATCHES_LIVERIES_ALL :Todas as empresas
+STR_CONFIG_PATCHES_PREFER_TEAMCHAT :{LTBLUE}Falar em time com <ENTER>: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Máximo de trens por jogador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Máximo de veículos de estrada por jogador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}Máximo de aeronaves por jogador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}Máximo de barcos por jogador: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Desativar trens para o computador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Desativar veículos de estrada para o computador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Desativar aeronaves para o computador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Desativar barcos para o computador: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Ativar nova IA (alpha): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Permitir AI em modo multiplayer (experimental): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Intervalo de serviço predefinido para trens: {ORANGE}{STRING} dias
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Intervalo de serviço predefinido para trens: {ORANGE}desativado
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Intervalo de serviço predefinido para veículos de estrada: {ORANGE}{STRING} dias
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Intervalo de serviço predefinido para veículos de estrada: {ORANGE}desactivado
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Intervalo de serviço predefinido para aeronaves: {ORANGE}{STRING} dias
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Intervalo de serviço predefinido para aeronaves: {ORANGE}desactivado
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Intervalo de serviço predefinido para barcos: {ORANGE}{STRING} dias
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Intervalo de serviço predefinido para barcos: {ORANGE}desactivado
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Desativar manutenção quando as quebras estão desativadas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Ativar limite de velocidade dos vagões: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}Disativar ferrovias elétricas: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Noticias coloridas aparecem em: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Data de início: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}Terminar jogo em: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Ativar economia regular (alterações menores)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Permite comprar ações de outras companhias
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Ao arrastar colocar sinais a cada: {ORANGE}{STRING} quadrado(s)
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Posição da barra de ferramentas principal: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Esquerda
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Centro
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Direita
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Raio de atração de janelas: {ORANGE}{STRING} px
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Raio de atração de janelas: {ORANGE}desativado
+
+STR_CONFIG_PATCHES_GUI :{BLACK}Interface
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Construção
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Veículos
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Estações
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Economia
+STR_CONFIG_PATCHES_AI :{BLACK}Oponentes
+
+STR_CONFIG_PATCHES_DISABLED :deactivado
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Alterar valor
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Alguns ou todos os intervalo(s) de serviço predefinidos abaixo são incompatíveis com o valor escolhido! São válidos 5-90% e 30-800 dias
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}Usar YAPF para navios: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}Usar YAPF para automóveis: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}Usar YAPF para trens: {ORANGE}{STRING}
+
+STR_TEMPERATE_LANDSCAPE :terreno temperado
+STR_SUB_ARCTIC_LANDSCAPE :terreno subárctico
+STR_SUB_TROPICAL_LANDSCAPE :terreno subtropical
+STR_TOYLAND_LANDSCAPE :terreno 'toyland'
+
+STR_CHEATS :{WHITE}Trapaças
+STR_CHEATS_TIP :{BLACK}As caixas de verificação indicam se esta trapaça já foi usada antes
+STR_CHEATS_WARNING :{BLACK}Atenção! Você está prestes a trair os seus oponentes. Saiba que isto ficará registrado para sempre.
+STR_CHEAT_MONEY :{LTBLUE}Aumentar dinheiro em {CURRENCY64}
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Jogar como jogador: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Bulldozer mágico (destrói indústrias, etc.): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Os túneis poderão cruzar-se: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Permitir construção quando em pausa: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Aviões a jato não irão ter acidentes em aeroportos pequenos: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Mudar de clima: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Alterar data: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}Ativar modificação de valores de produção: {ORANGE}{STRING}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}Dirigindo-se para {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Dirigindo-se para {WAYPOINT}, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :Ir via {WAYPOINT}
+STR_GO_NON_STOP_TO_WAYPOINT :Ir sem parar via {WAYPOINT}
+
+STR_WAYPOINTNAME_CITY :Ponto de controle {TOWN}
+STR_WAYPOINTNAME_CITY_SERIAL :Ponto de controle {TOWN} #{COMMA}
+STR_LANDINFO_WAYPOINT :Ponto de controle
+
+STR_WAYPOINT :{WHITE}Ponto de controle
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Selecione um tipo de ponto de controle
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}Editar nome do ponto de controle
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Não é possível alterar o nome do ponto de controle...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Converter linha em ponto de controle
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Não é possível construir ponto de controle de trem aqui...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Não é possível remover ponto de controle de trem aqui...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Construir ferrovias usando o modo automático
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}...não existe nenhuma cidade neste cenário
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}Tem certeza que deseja criar um terreno aleatório?
+STR_MANY_RANDOM_TOWNS :{BLACK}Várias cidades aleatórias
+STR_RANDOM_TOWNS_TIP :{BLACK}Cobrir o mapa com cidades colocadas aleatoriamente
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Várias indústrias aleatórias
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Cobrir o mapa com indústrias colocadas aleatoriamente
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Não é possível gerar indústrias...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Abra a barra de modelação ambiental para elevar ou baixar terreno, plantar árvores, etc.
+STR_LANDSCAPING_TOOLBAR :{WHITE}Terreno
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Nivelar terreno
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Ãrvores de tipo aleatório
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}Colocar árvores de tipo aleatório
+
+STR_CANT_BUILD_CANALS :{WHITE}Não é possível construir canais aqui...
+STR_BUILD_CANALS_TIP :{BLACK}Construir canais
+STR_LANDINFO_CANAL :Canal
+
+STR_CANT_BUILD_LOCKS :{WHITE}Não é possível construir eclusas aqui...
+STR_BUILD_LOCKS_TIP :{BLACK}Construir eclusas
+STR_LANDINFO_LOCK :Eclusa
+
+STR_BUOY_IS_IN_USE :{WHITE}...boia está em uso!
+
+STR_LANDINFO_COORDS :{BLACK}Coordenadas: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Não é possível remover parte da estação...
+STR_CANT_CONVERT_RAIL :{WHITE}Não é possível converter o tipo de linha aqui...
+STR_CONVERT_RAIL_TIP :{BLACK}Converter/Atualizar tipo de linha
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Arraste locomotiva aqui para vender todo o trem
+
+STR_DRAG_DROP :{BLACK}Arrastar
+STR_STATION_DRAG_DROP :{BLACK}Construir estação arrastando
+STR_SELECT_STATION_CLASS_TIP :{BLACK}Selecione a classe de estação a ser exibida
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Selecione o tipo de estação a construir
+
+STR_FAST_FORWARD :{BLACK}Aumentar velocidade do jogo
+STR_MESSAGE_HISTORY :{WHITE}Histórico de Mensagens
+STR_MESSAGE_HISTORY_TIP :{BLACK}Lista de notícias recentes
+STR_MESSAGES_DISABLE_ALL :{BLACK}Desativar tudo
+STR_MESSAGES_ENABLE_ALL :{BLACK}Ativar tudo
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Construir Mina de Carvão
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Plantar Floresta
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Construir Plataforma de Petróleo
+STR_CONSTRUCT_FARM_TIP :{BLACK}Construir Fazenda
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Construir Mina de Cobre
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Construir Poços de Petróleo
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Construir Mina de Ouro
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Construir Mina de Diamantes
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Construir Mina de Ferro
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Criar Plantação de Frutas
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Criar Plantação de Seringueiras
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Construir Poço Artesiano
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Plantar Floresta de Algodão Doce
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}Construir Campo de Baterias
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Construir Poços de Cola
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Construir Fontes de Plástico
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Construir Produtor de Bolhas
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Construir Extração de Caramelo
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Construir Mina de Açúcar
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Indústrias
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA}% transportado)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA}%/{COMMA}% transportado)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}...muito perto de outra indústria
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Adaptar trem para um tipo de carga diferente
+STR_RAIL_REFIT_VEHICLE :{BLACK}Adaptar trem
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Selecione o tipo de carga do trem
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Adaptar trem para transportar a carga selecionada
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Não é possível adaptar o trem...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Os intervalos de serviço são em percentagem: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Modificar produção
+
+TEMP_AI_IN_PROGRESS :{WHITE}Bem-vindo à nova IA, ainda em desenvolvimento. Se você encontrar problemas tire um printscreen e poste no fórum.
+TEMP_AI_ACTIVATED :{WHITE}Atenção: esta nova IA está ainda em versão alpha! Atualmente, só funcionam caminhões e ônibus!
+TEMP_AI_MULTIPLAYER :{WHITE}Atenção: esta função ainda é experimental (usando a nova IA). Por favor reporte quaisquer problemas para truelight@openttd.org.
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Multi-jogador
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Nome:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}Este é o nome pelo qual os outros jogadores irão te identificar
+STR_NETWORK_CONNECTION :{BLACK}Conexão:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Escolha entre um jogo pela Internet ou pela rede local
+
+STR_NETWORK_START_SERVER :{BLACK}Iniciar servidor
+STR_NETWORK_START_SERVER_TIP :{BLACK}Iniciar um servidor próprio
+
+STR_NETWORK_GAME_NAME :{BLACK}Nome
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Nome do jogo
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Idioma, versão do servidor, etc.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Clique num jogo da lista para o selecionar
+
+STR_NETWORK_FIND_SERVER :{BLACK}Localizar servidor
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Pesquisar por um servidor na rede
+STR_NETWORK_ADD_SERVER :{BLACK}Adicionar servidor
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Adiciona um servidor à lista que será sempre verificada se existem jogos ocorrendo.
+STR_NETWORK_ENTER_IP :{BLACK}Introduza o endereço IP do servidor
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Clientes
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Clientes ligados / max. clientes
+STR_NETWORK_GAME_INFO :{SILVER}INFORMAÇÃO DE JOGO
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Clientes: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Idioma: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Tileset: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Tamanho do Mapa: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}Versão do servidor: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}IP do servidor: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Data de inicio: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Data atual: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Protegido por senha!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}SERVIDOR DESLIGADO
+STR_NETWORK_SERVER_FULL :{SILVER}SERVIDOR CHEIO
+STR_NETWORK_VERSION_MISMATCH :{SILVER}VERSÃO INCOMPATÃVEL
+
+STR_NETWORK_JOIN_GAME :{BLACK}Juntar-se ao jogo
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}Iniciar novo jogo
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Nome do jogo:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}O nome do jogo será mostrado aos outros jogadores no menu de seleção de jogos multi-jogador
+STR_NETWORK_SET_PASSWORD :{BLACK}Definir senha
+STR_NETWORK_PASSWORD_TIP :{BLACK}Proteja o jogo com uma senha se não desejar que pessoas indesejadas entrem
+STR_NETWORK_SELECT_MAP :{BLACK}Selecione um mapa:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}Em que mapa deseja jogar?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}Máximo de clientes:
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Escolha o número máximo de clientes. Não necessitam estar todos presentes.
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :Rede Local
+STR_NETWORK_INTERNET :Internet
+STR_NETWORK_LAN_INTERNET :Rede Local / Internet
+STR_NETWORK_INTERNET_ADVERTISE :Internet (divulgar)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 jogadores
+STR_NETWORK_1_PLAYERS :1 jogador
+STR_NETWORK_2_PLAYERS :2 jogadores
+STR_NETWORK_3_PLAYERS :3 jogadores
+STR_NETWORK_4_PLAYERS :4 jogadores
+STR_NETWORK_5_PLAYERS :5 jogadores
+STR_NETWORK_6_PLAYERS :6 jogadores
+STR_NETWORK_7_PLAYERS :7 jogadores
+STR_NETWORK_8_PLAYERS :8 jogadores
+STR_NETWORK_9_PLAYERS :9 jogadores
+STR_NETWORK_10_PLAYERS :10 jogadores
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}Limite de companhias:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Limita o servidor para um certo valor de companhias
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}Max espectadores:
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Limita o servidor para um certa quantia de espectadores
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Idioma falado:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Outros jogadores saberão o idioma utilizado no servidor.
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}Iniciar Jogo
+STR_NETWORK_START_GAME_TIP :{BLACK}Iniciar um novo jogo em rede
+STR_NETWORK_LOAD_GAME :{BLACK}Abrir Jogo
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Continuar um jogo multi-jogador anteriormente gravado (assegure-se de conectar com o jogador correto)
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Qualquer
+STR_NETWORK_LANG_ENGLISH :Inglês
+STR_NETWORK_LANG_GERMAN :Alemão
+STR_NETWORK_LANG_FRENCH :Francês
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Sala de espera de jogo multi-jogador
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Preparando para conectar-se: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}Lista das companhias ativas neste jogo. Pode juntar-se a uma delas ou iniciar uma nova companhia.
+STR_NETWORK_NEW_COMPANY :{BLACK}Nova empresa
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Criar uma nova empresa
+STR_NETWORK_SPECTATE_GAME :{BLACK}Observar jogo
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Ver jogo como um espectador
+STR_NETWORK_JOIN_COMPANY :{BLACK}Juntar-se à companhia
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Auxiliar na gestão desta companhia
+STR_NETWORK_REFRESH :{BLACK}Atualizar dados
+STR_NETWORK_REFRESH_TIP :{BLACK}Atualiza as informações sobre o servidor
+
+STR_NETWORK_COMPANY_INFO :{SILVER}INFORMAÇÃO DA COMPANHIA
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Nome da empresa: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}Inauguração: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}Valor da Companhia: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Balanço atual: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Rendimento do último ano: {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}Desempenho: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}Veículos: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Estações: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Jogadores: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}Conectando...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) Conectando..
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Autorizando..
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Em espera..
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Obtendo mapa..
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Processando dados..
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) Registrando..
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Obtendo informações do jogo..
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Obtendo informações da Companhia..
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} cliente{P "" s} à sua frente
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} kbytes obtidos até agora
+
+STR_NETWORK_DISCONNECT :{BLACK}Desconectar
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Digite o valor do dinheiro que pretende dar
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Servidor protegido. Digite a senha
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Companhia protegida. Digite a senha
+STR_NETWORK_CLIENT_LIST :{WHITE}Lista de clientes
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE} Não foram encontradas interfaces de rede ou o jogo foi compilado sem ENABLE_NETWORK
+STR_NETWORK_ERR_NOSERVER :{WHITE} Não foram encontrados jogos de rede
+STR_NETWORK_ERR_NOCONNECTION :{WHITE} O servidor não respondeu ao pedido
+STR_NETWORK_ERR_DESYNC :{WHITE} A sincronização do jogo de rede falhou.
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} A conexão do jogo de rede perdeu-se.
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} Não foi possível abrir o jogo.
+STR_NETWORK_ERR_SERVER_START :{WHITE} Não foi possível iniciar o servidor
+STR_NETWORK_ERR_CLIENT_START :{WHITE} Não foi possível estabelecer ligação
+STR_NETWORK_ERR_TIMEOUT :{WHITE} Tempo de espera esgotado na conexão #{NUM}.
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE} Ocorreu um erro de protocolo e a conexão foi encerrada
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE} A revisão deste cliente não condiz com a revisão do servidor
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} Senha incorrecta
+STR_NETWORK_ERR_SERVER_FULL :{WHITE} Servidor cheio
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} Você foi banido deste SERVIDOR
+STR_NETWORK_ERR_KICKED :{WHITE} Você foi expulso do jogo
+STR_NETWORK_ERR_CHEATER :{WHITE} Trapaceiros não são permitidos neste servidor
+
+STR_NETWORK_ERR_LEFT :deixou o jogo
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :erro geral
+STR_NETWORK_ERR_CLIENT_DESYNC :erro de dessincronização
+STR_NETWORK_ERR_CLIENT_SAVEGAME :não foi possível carregar o mapa
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :conexão perdida
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :erro de protocolo
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :não autorizado
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :recebido um pacote estranho
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :revisão incorreta
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :nome já está sendo utilizado
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :A senha do jogo está incorreta
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :id do jogador incorreta em DoCommand
+STR_NETWORK_ERR_CLIENT_KICKED :chutado pelo servidor
+STR_NETWORK_ERR_CLIENT_CHEATER :estava a tentando trapacear
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :servidor cheio
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :entrou no jogo
+STR_NETWORK_GIVE_MONEY :deu à sua empresa algum dinheiro ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :você deu {STRING} algum dinheiro ({CURRENCY})
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Equipe] :
+STR_NETWORK_CHAT_COMPANY :[Equipe] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Equipe] Para {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[Privado] :
+STR_NETWORK_CHAT_CLIENT :[Privado] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[Privado] Para {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[Todos] :
+STR_NETWORK_CHAT_ALL :[Todos] {STRING}: {GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :mudou o nome dele/dela para
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE} O servidor fechou a sessão
+STR_NETWORK_SERVER_REBOOT :{WHITE} O servidor está reiniciando...{}Por favor espere...
+
+STR_NETWORK_SERVER :Servidor
+STR_NETWORK_CLIENT :Cliente
+STR_NETWORK_SPECTATORS :Espectadores
+
+STR_NETWORK_CLIENTLIST_NONE :(nenhum)
+STR_NETWORK_CLIENTLIST_KICK :Banir
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Dar dinheiro
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Falar com todos
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Falar com a empresa
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Mensagem privada
+
+
+STR_NETWORK_SEND :{BLACK}Enviar
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}X-tamanho do mapa: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Y-tamanho do mapa: {ORANGE}{STRING}
+
+
+##### PNG-MAP-Loader
+
+STR_PNGMAP_ERROR :{WHITE}Impossível carregar terreno a partir de PNG...
+STR_PNGMAP_ERR_FILE_NOT_FOUND :{WHITE}...arquivo não encontrado.
+STR_PNGMAP_ERR_IMAGE_TYPE :{WHITE}...impossível converter tipo de imagem. Necessária imagem PNG de 8 ou 24-bit.
+STR_PNGMAP_ERR_MISC :{WHITE}...alguma coisa deu errado. Desculpe. (provavel arquivo corrupto)
+
+STR_BMPMAP_ERROR :{WHITE}Impossível carregar terreno a partir de BMP...
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}...não foi possível converter o tipo de imagem
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Custo: {CURRENCY}
+STR_0801_COST :{RED}Custo: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Lucro: {CURRENCY}
+STR_0803_INCOME :{GREEN}Lucro: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Transfer: {CURRENCY}
+STR_FEEDER :{YELLOW}Transferência: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Custo Estimado: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Lucro Estimado: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Não é possível elevar terreno aqui...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Não é possível baixar terreno aqui...
+STR_080A_ROCKS :Rochas
+STR_080B_ROUGH_LAND :Terreno Irregular
+STR_080C_BARE_LAND :Deserto
+STR_080D_GRASS :Grama
+STR_080E_FIELDS :Campos
+STR_080F_SNOW_COVERED_LAND :Neve
+STR_0810_DESERT :Deserto
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Terreno inclinado na direção incorecta
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Combinação de linhas impossível
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}A escavação estragaria o túnel
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Já está ao nível do mar
+STR_1004_TOO_HIGH :{WHITE}Muito alto
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Tipo de linha não apropriado
+STR_1007_ALREADY_BUILT :{WHITE}...já construído
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Deverá remover a linha férrea primeiro
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Construir ferrovias
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Construção de Linhas Eletrificadas
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Construir ferrovias (monotrilho)
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}Construir ferrovias (trem-bala)
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Selecione Ponte Ferroviária
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Não é possível construir depósito aqui...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Não é possível construir estação ferroviária aqui...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Não é possível construir sinais aqui...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Não é possível construir linha férrea aqui...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Não é possível remover linha férrea daqui...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Não é possível remover sinais daqui...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Orientação do Depósito
+STR_1015_RAILROAD_CONSTRUCTION :Construir ferrovias
+STR_TOOLB_ELRAIL_CONSTRUCTION :Construção de Linhas Eletrificadas
+STR_1016_MONORAIL_CONSTRUCTION :Construir ferrovias (monotrilho)
+STR_1017_MAGLEV_CONSTRUCTION :Construir ferrovias (trem-bala)
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Construir linha férrea
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Construir depósito (para criação e manutenção de trens)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Construir estação ferroviária
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Construir sinais ferroviários
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Construir ponte ferroviária
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Construir túnel ferroviário
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Alternar entre construir/remover linha férrea e sinais
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Seleção de ponte - clique na ponte desejada para construir
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Selecionar a orientação do depósito
+STR_1021_RAILROAD_TRACK :Ferrovias
+STR_1023_RAILROAD_TRAIN_DEPOT :Depósito ferroviário
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...a área é propriedade de outra empresa
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :Ferrovia com sinais normais
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :Ferrovia com pre-sinais
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :Ferrovia com sinais de saída
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :Ferrovia com sinais combinados
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Deverá remover a estrada primeiro
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Trabalhos em ruas em progresso
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Construir Estradas
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Selecionar Ponte de Estrada
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Não é possível construir estrada aqui...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Não é possível remover estrada daqui...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Orientação do Depósito
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Não é possível construir depósito de veículos de estrada aqui...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Não é possível construir estação de ônibus...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Não é possível construir estação de carregamento de caminhões...
+STR_180A_ROAD_CONSTRUCTION :Construir estradas
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Construir estradas
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Construir depósito (para criação e manutenção de veículos de estrada)
+STR_180D_BUILD_BUS_STATION :{BLACK}Construir estação de ônibus
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Construir área de carregamento de caminhões
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Construir ponte de estrada
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Construir túnel de estrada
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Alternar entre construir/remover estradas
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Selecionar a orientação do depósito
+STR_1814_ROAD :Estrada
+STR_1815_ROAD_WITH_STREETLIGHTS :Estrada com iluminação
+STR_1816_TREE_LINED_ROAD :Estrada com árvores
+STR_1817_ROAD_VEHICLE_DEPOT :Depósito de veículos de estrada
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :Passagem de nível
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Cidades
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}O edifício deve ser demolido primeiro
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}População: {ORANGE}{COMMA}{BLACK} Casas: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Renomear Cidade
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Não é possível renomear cidade...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}A autoridade local de {TOWN} não autoriza
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Nomes das cidades - clique no nome para centralizar a visualização na cidade
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centralizar visualização na cidade
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Alterar o nome da cidade
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passageiros no mês passado: {ORANGE}{COMMA}{BLACK} máx: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Correspondências no mês passado: {ORANGE}{COMMA}{BLACK} máx: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Edifício alto de escritórios
+STR_2010_OFFICE_BLOCK :Edifício de escritórios
+STR_2011_SMALL_BLOCK_OF_FLATS :Edifício de apartamentos grande
+STR_2012_CHURCH :Igreja
+STR_2013_LARGE_OFFICE_BLOCK :Edifício de escritórios grande
+STR_2014_TOWN_HOUSES :Casas
+STR_2015_HOTEL :Hotel
+STR_2016_STATUE :Estátua
+STR_2017_FOUNTAIN :Fonte
+STR_2018_PARK :Parque
+STR_2019_OFFICE_BLOCK :Edifício de escritórios
+STR_201A_SHOPS_AND_OFFICES :Lojas e escritórios
+STR_201B_MODERN_OFFICE_BUILDING :Edifício de escritórios moderno
+STR_201C_WAREHOUSE :Armazém
+STR_201D_OFFICE_BLOCK :Edifício de escritórios
+STR_201E_STADIUM :Estádio
+STR_201F_OLD_HOUSES :Casas velhas
+STR_2020_LOCAL_AUTHORITY :{BLACK}Autoridade local
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Ver informações sobre a autoridade local
+STR_2022_LOCAL_AUTHORITY :{WHITE}{TOWN} autoridade local
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Avaliações da companhia de transporte
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Subsídios
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Oferta de subsídios para os serviços:
+STR_2027_FROM_TO :{ORANGE}{STRING} de {STRING} para {STRING}
+STR_2028_BY :{YELLOW} (por {DATE_SHORT})
+STR_202A_NONE :{ORANGE}Nenhum
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Serviços já subsidiados:
+STR_202C_FROM_TO :{ORANGE}{STRING} de {STATION} para {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, até {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}A oferta do subsídio expirou:{}{}{STRING} de {STRING} para {STRING} já não é subsidiado.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Subsídio retirado:{}{}serviço de transporte de {STRING} de {STATION} para {STATION} não é mais subsidiado.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Subsídio de transporte oferecido:{}{}Primeiro serviço de {STRING} de {STRING} para {STRING} atrairá o subsídio de um ano da autoridade local!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subsídio de transporte concedido a {COMPANY}!{}{}{STRING} ligação de {STATION} para {STATION} pagará 50% extra durante o próximo ano!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subsídio de transporte concedido a {COMPANY}!{}{}{STRING} ligação de {STATION} para {STATION} pagará em dobro durante o próximo ano!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subsídio de transporte concedido a {COMPANY}!{}{}{STRING} ligação de {STATION} para {STATION} pagará o triplo durante o próximo ano!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subsídio de transporte concedido a {COMPANY}!{}{}{STRING} ligação de {STATION} para {STATION} pagará o quadruplo durante o próximo ano!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} a autoridade local não permite que outro aeroporto seja construído nesta cidade
+STR_2036_COTTAGES :Casas de campo
+STR_2037_HOUSES :Casas
+STR_2038_FLATS :Apartamentos
+STR_2039_TALL_OFFICE_BLOCK :Prédio de escritórios alto
+STR_203A_SHOPS_AND_OFFICES :Lojas e escritórios
+STR_203B_SHOPS_AND_OFFICES :Lojas e escritórios
+STR_203C_THEATER :Teatro
+STR_203D_STADIUM :Estádio
+STR_203E_OFFICES :Escritórios
+STR_203F_HOUSES :Casas
+STR_2040_CINEMA :Cinema
+STR_2041_SHOPPING_MALL :Centro Comercial
+STR_2042_DO_IT :{BLACK}Aplicar
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}Lista de ações disponíveis nesta cidade - clique no item para mais detalhes
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Realizar a ação destacada na lista acima
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Ações disponíveis:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Pequena campanha publicitária
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Média campanha publicitária
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Grande campanha publicitária
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Financiar a reconstrução das estradas locais
+STR_204A_BUILD_STATUE_OF_COMPANY :Construir estátua do proprietário da companhia
+STR_204B_FUND_NEW_BUILDINGS :Financiar novos edifícios
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Comprar exclusividade da rede de transportes
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Subornar a autoridade local
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Iniciar uma campanha publicitária pequena, para atrair mais passageiros e carga à sua companhia.{} Custo: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Iniciar uma campanha publicitária média, para atrair mais passageiros e carga à sua companhia.{} Custo: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Iniciar uma campanha publicitária grande, para atrair mais passageiros e carga à sua companhia.{} Custo: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} Financiar a reconstrução da rede rodoviária urbana. Causa engarrafamentos consideráveis ao tráfego por até 6 meses.{} Custo: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Construir uma estátua em honra da sua companhia.{} Custo: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Financiar a construção de edifícios comerciais novos na cidade.{} Custo: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Comprar a exclusividade dos serviços durante 1 ano na cidade. A autoridade da cidade permitirá que os passageiros e a carga usem somente estações da sua companhia.{} Custo: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Subornar a autoridade local para aumentar a sua avaliação, correndo o risco de uma penalidade severa se apanhado.{} Custo: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}Tráfego caótico em {TOWN}!{}{}Programa de reconstrução de estradas financiado por {COMPANY} provoca 6 meses de miséria aos condutores!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (em construção)
+STR_2059_IGLOO :Iglú
+STR_205A_TEPEES :Tepees
+STR_205B_TEAPOT_HOUSE :Casa-bule
+STR_205C_PIGGY_BANK :Mealheiro
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN}, {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Paisagem
+STR_2800_PLANT_TREES :Plantar árvores
+STR_2801_PLACE_SIGN :Colocar sinal
+STR_2802_TREES :{WHITE}Ãrvores
+STR_2803_TREE_ALREADY_HERE :{WHITE}...árvore já plantada aqui
+STR_2804_SITE_UNSUITABLE :{WHITE}...local impróprio
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Impossível plantar árvore aqui...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...muitos sinais
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Não pode colocar um sinal aqui...
+STR_280A_SIGN :Sinal
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Editar texto do sinal
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Não pode alterar o nome do sinal...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Escolha um tipo de árvore para plantar
+STR_280E_TREES :Ãrvores
+STR_280F_RAINFOREST :Floresta Tropical
+STR_2810_CACTUS_PLANTS :Cactos
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Seleção de Estação
+STR_3001_AIRPORT_SELECTION :{WHITE}Seleção de Aeroporto
+STR_3002_ORIENTATION :{BLACK}Orientação
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Número de linhas
+STR_3004_PLATFORM_LENGTH :{BLACK}Tamanho da plataforma
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Muito perto de outra estação ferroviária
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Muito perto de uma estação/local de carga já existente
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}Muitas estações/locais de carga nesta cidade
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}Muitas estações/locais de carga
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Muitos pontos de ônibus
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}Muitos locais de carga
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Muito perto de uma estação/local de carga
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Precisa de demolir a estação primeiro
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Muito perto de outro aeroporto
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Precisa de demolir o aeroporto primeiro
+
+STR_3030_RENAME_STATION_LOADING :Alterar nome de estação/local de carga
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Não pode alterar o nome da estação...
+STR_3032_RATINGS :{BLACK}Avaliações
+STR_3033_ACCEPTS :{BLACK}Aceita
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}Avaliação local do serviço de transporte:
+
+############ range for rating starts
+STR_3035_APPALLING :Inexistente
+STR_3036_VERY_POOR :Muito Fraco
+STR_3037_POOR :Fraco
+STR_3038_MEDIOCRE :Medíocre
+STR_3039_GOOD :Bom
+STR_303A_VERY_GOOD :Muito Bom
+STR_303B_EXCELLENT :Excelente
+STR_303C_OUTSTANDING :Proeminente
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} não aceita mais {STRING}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} não aceita mais {STRING} ou {STRING}
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} agora aceita {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} agora aceita {STRING} e {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Orientação do ponto de ônibus
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Orientação do local de carga
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Precisa de demolir o ponto de ônibus primeiro
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Precisa de demolir o local de carga primeiro
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Estações
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Nenhuma -
+STR_304B_SITE_UNSUITABLE :{WHITE}...local inadequado
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Muito perto de outra doca
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Deverá demolir a doca primeiro
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Selecionar a orientação da estação ferroviária
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Selecionar o número de linhas da estação ferroviária
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Selecionar o tamanho da estação ferroviária
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Selecionar a orientação da estação de autocarros
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Seleccionar a orientação da estação de carregamento de camiões
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Centralizar visualização no local estação
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Mostrar avaliações da estação
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Alterar o nome da estação
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Mostrar lista de carga aceita
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Nome da estação - clique no nome para centralizar a visualização na estação
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Selecionar tamanho/tipo de aeroporto
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :Estação ferroviária
+STR_305F_AIRCRAFT_HANGAR :Hangar
+STR_3060_AIRPORT :Aeroporto
+STR_3061_TRUCK_LOADING_AREA :Ãrea de carregamento de caminhões
+STR_3062_BUS_STATION :Ponto de ônibus
+STR_3063_SHIP_DOCK :Doca
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Destacar área de cobertura da construção proposta
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Não destacar área de cobertura da construção proposto
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Destacar cobertura
+STR_3068_DOCK :{WHITE}Doca
+STR_3069_BUOY :Bóia
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...bóia no caminho
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...estação muito extensa
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...Estações não-uniformes desativadas
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Segure CTRL para selecionar mais de um item
+
+STR_UNDEFINED :(undefined string)
+STR_STAT_CLASS_DFLT :Estação Padrão
+STR_STAT_CLASS_WAYP :Pontos de Controle
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Orientação do Depósito
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...deverá ser construído na água
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Não é possível construir depósito naval aqui...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Selecione a orientação do depósito naval
+STR_3804_WATER :Ãgua
+STR_3805_COAST_OR_RIVERBANK :Costa ou margem
+STR_3806_SHIP_DEPOT :Depósito naval
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...Não é possível construir na água
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Salvar Jogo
+STR_4001_LOAD_GAME :{WHITE}Abrir Jogo
+STR_4002_SAVE :{BLACK}Salvar
+STR_4003_DELETE :{BLACK}Apagar
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} megabytes livres
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Não é possível ler unidade
+STR_4007_GAME_SAVE_FAILED :{WHITE}Falha ao Salvar Jogo
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Não é possível apagar o arquivo
+STR_4009_GAME_LOAD_FAILED :{WHITE}Falha ao Abrir Jogo
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}Lista de unidades, diretórios e arquivos de jogos gravados
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Nome escolhido para salvar o jogo
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Apagar o jogo selecionado
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Salvar o jogo atual, usando o nome escolhido
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Selecionar Novo Tipo de Jogo
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Selecionar cenário (verde), jogo pré-programado (azul), ou novo jogo aleatório
+STR_4010_GENERATE_RANDOM_NEW_GAME :Gerar novo jogo aleatório
+STR_4011_LOAD_HEIGHTMAP :{WHITE}Carregad Mapa de Altitudes
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} no caminho
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :Mina de Carvão
+STR_4803_POWER_STATION :Termeléctrica
+STR_4804_SAWMILL :Serraria
+STR_4805_FOREST :Floresta
+STR_4806_OIL_REFINERY :Refinaria de Petróleo
+STR_4807_OIL_RIG :Plataforma Petrolífera
+STR_4808_FACTORY :Fábrica
+STR_4809_PRINTING_WORKS :Gráfica
+STR_480A_STEEL_MILL :Siderurgica
+STR_480B_FARM :Fazenda
+STR_480C_COPPER_ORE_MINE :Mina de Cobre
+STR_480D_OIL_WELLS :Poços de Petróleo
+STR_480E_BANK :Banco
+STR_480F_FOOD_PROCESSING_PLANT :Companhia Alimenticia
+STR_4810_PAPER_MILL :Fábrica de Papel
+STR_4811_GOLD_MINE :Mina de Ouro
+STR_4812_BANK :Banco
+STR_4813_DIAMOND_MINE :Mina de Diamantes
+STR_4814_IRON_ORE_MINE :Mina de Ferro
+STR_4815_FRUIT_PLANTATION :Plantação de Frutas
+STR_4816_RUBBER_PLANTATION :Plantação de Seringueiras
+STR_4817_WATER_SUPPLY :Poço Artesiano
+STR_4818_WATER_TOWER :Depósito de Ãgua
+STR_4819_FACTORY :Fábrica
+STR_481A_FARM :Fazenda
+STR_481B_LUMBER_MILL :Fábrica de Madeira
+STR_481C_COTTON_CANDY_FOREST :Floresta de Algodão Doce
+STR_481D_CANDY_FACTORY :Fábrica de Doces
+STR_481E_BATTERY_FARM :Campo de Baterias
+STR_481F_COLA_WELLS :Poços de Cola
+STR_4820_TOY_SHOP :Loja de Brinquedos
+STR_4821_TOY_FACTORY :Fábrica de Brinquedos
+STR_4822_PLASTIC_FOUNTAINS :Fontes de Plástico
+STR_4823_FIZZY_DRINK_FACTORY :Fábrica de Bebidas Gasosas
+STR_4824_BUBBLE_GENERATOR :Produtor de Bolhas
+STR_4825_TOFFEE_QUARRY :Extração de Caramelo
+STR_4826_SUGAR_MINE :Mina de Açúcar
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Necessário: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Necessário: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Necessário: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Produção no mês passado:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% transportado)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centralizar visualização na localização da indústria
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Nova {STRING} em construção em {TOWN}!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Nova {STRING} sendo plantada em {TOWN}!
+STR_482F_COST :{BLACK}Custo: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Não é possível construir este tipo de indústria aqui...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...a floresta só pode ser plantada acima do nível de neve
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}Em {INDUSTRY} anuncia fechamento em breve!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}Problemas de abastecimento forçaram {INDUSTRY} a anunciar falência iminente!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}Falta de árvores nas proximidades forçaram {INDUSTRY} a anunciar falência iminente!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}Em {INDUSTRY} aumenta a produção!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}Nova jazida de carvão encontrada em {INDUSTRY}!{}A expectativa é de dobrar a produção!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}Novas reservas de petróleo encontradas em {INDUSTRY}!{}A expectativa é de dobrar a produção!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}Métodos aperfeiçoados de agricultura em {INDUSTRY}! A expectativa é de dobrar a produção!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}Em {INDUSTRY} diminui produção em 50%
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}Infestação de insetos causa destruição em {INDUSTRY}!{}Produção diminui em 50%
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...só pode ser colocado perto das bordas do mapa
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}{STRING} a produção em {INDUSTRY} aumenta {COMMA}%!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}{STRING} a produção em {INDUSTRY} diminui {COMMA}%!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Há um trem no túnel
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Há um veículo de estrada no túnel
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Há outro túnel no caminho
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Não é possível escavar o terreno para o outro lado do túnel
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Deverá demolir o túnel primeiro
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Deverá demolir a ponte primeiro
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Não é possível iniciar e terminar no mesmo ponto
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Debaixo da ponte é necessário um terreno plano ou água
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}Inicio e fim devem estar alinhados
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}O local não é adequado para a entrada do túnel
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Suspensa, Aço
+STR_500F_GIRDER_STEEL :Vigas, Aço
+STR_5010_CANTILEVER_STEEL :Cantilever, Aço
+STR_5011_SUSPENSION_CONCRETE :Suspensa, Betão
+STR_5012_WOODEN :De madeira
+STR_5013_CONCRETE :Concreto
+STR_5014_TUBULAR_STEEL :Tubular, Aço
+STR_BRIDGE_TUBULAR_SILICON :Tubular, Silício
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Não é possível construir ponte aqui...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Não é possível construir túnel aqui...
+STR_5017_RAILROAD_TUNNEL :Túnel ferroviário
+STR_5018_ROAD_TUNNEL :Túnel de estrada
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Ponte ferroviária suspensa em aço
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Ponte ferroviária com vigas em aço
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Ponte ferroviária cantilever em aço
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Ponte ferroviária suspensa de concreto reforçado
+STR_501F_WOODEN_RAIL_BRIDGE :Ponte ferroviária de madeira
+STR_5020_CONCRETE_RAIL_BRIDGE :Ponte ferroviária de concreto
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Ponte de estrada suspensa em aço
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Ponte de estrada com vigas em aço
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Ponte de estrada cantilever em aço
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Ponte de estrada suspensa de concreto reforçado
+STR_5025_WOODEN_ROAD_BRIDGE :Ponte de estrada de madeira
+STR_5026_CONCRETE_ROAD_BRIDGE :Ponte de estrada de concreto
+STR_5027_TUBULAR_RAIL_BRIDGE :Ponte ferroviária tubular
+STR_5028_TUBULAR_ROAD_BRIDGE :Ponte de estrada tubular
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Objeto no caminho
+STR_5801_TRANSMITTER :Transmissor
+STR_5802_LIGHTHOUSE :Farol
+STR_5803_COMPANY_HEADQUARTERS :Sede de Empresa
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...sede de empresa no caminho
+STR_5805_COMPANY_OWNED_LAND :O terreno é propriedade de uma empresa
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Não é possível comprar esta área...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...já a possui!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Sem nome
+STR_SV_TRAIN_NAME :Trem {COMMA}
+STR_SV_ROADVEH_NAME :Veículo de Estrada {COMMA}
+STR_SV_SHIP_NAME :Barco {COMMA}
+STR_SV_AIRCRAFT_NAME :Aeronave {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :Norte de {STRING}
+STR_SV_STNAME_SOUTH :Sul de {STRING}
+STR_SV_STNAME_EAST :{STRING} Leste
+STR_SV_STNAME_WEST :Oeste de {STRING}
+STR_SV_STNAME_CENTRAL :Central de {STRING}
+STR_SV_STNAME_TRANSFER :{STRING} Baldeação
+STR_SV_STNAME_HALT :Parada de {STRING}
+STR_SV_STNAME_VALLEY :Vale de {STRING}
+STR_SV_STNAME_HEIGHTS :Montes de {STRING}
+STR_SV_STNAME_WOODS :Floresta de {STRING}
+STR_SV_STNAME_LAKESIDE :Lago de {STRING}
+STR_SV_STNAME_EXCHANGE :Intercâmbio de {STRING}
+STR_SV_STNAME_AIRPORT :Aeroporto de {STRING}
+STR_SV_STNAME_OILFIELD :Petrolífera de {STRING}
+STR_SV_STNAME_MINES :Minas de {STRING}
+STR_SV_STNAME_DOCKS :Docas de {STRING}
+STR_SV_STNAME_BUOY_1 :{STRING} Bóia 1
+STR_SV_STNAME_BUOY_2 :{STRING} Bóia 2
+STR_SV_STNAME_BUOY_3 :{STRING} Bóia 3
+STR_SV_STNAME_BUOY_4 :{STRING} Bóia 4
+STR_SV_STNAME_BUOY_5 :{STRING} Bóia 5
+STR_SV_STNAME_BUOY_6 :{STRING} Bóia 6
+STR_SV_STNAME_BUOY_7 :{STRING} Bóia 7
+STR_SV_STNAME_BUOY_8 :{STRING} Bóia 8
+STR_SV_STNAME_BUOY_9 :{STRING} Bóia 9
+STR_SV_STNAME_ANNEXE :Anexo de {STRING}
+STR_SV_STNAME_SIDINGS :Desvio de {STRING}
+STR_SV_STNAME_BRANCH :Ramal de {STRING}
+STR_SV_STNAME_UPPER :{STRING} de cima
+STR_SV_STNAME_LOWER :Sul de {STRING}
+STR_SV_STNAME_HELIPORT :Heliporto de {STRING}
+STR_SV_STNAME_FOREST :Floresta de {STRING}
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :Nível de Dificuldade{WHITE}
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Salvar
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Fácil
+STR_6802_MEDIUM :{BLACK}Médio
+STR_6803_HARD :{BLACK}Difícil
+STR_6804_CUSTOM :{BLACK}Personalizado
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}Número máximo de oponentes: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Data de início dos oponentes: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}Quantidade de cidades: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}Quantidade de indústrias: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Empréstimo máximo inicial: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Taxa de juros inicial: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Custos de circulação dos veículos: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Velocidade de construção dos oponentes: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Inteligência dos oponentes: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Quebras de veículos: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Multiplicador de subsídio: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Custos de construção: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Tipo de terreno: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Quantidade de mar/lagos: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Economia: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Inverter trem: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Desastres: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Atitude das autoridades sobre reestruturamentos: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :Nenhum
+STR_6816_LOW :Baixo
+STR_6817_NORMAL :Normal
+STR_6818_HIGH :Alto
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Muito Lento
+STR_681C_SLOW :Lento
+STR_681D_MEDIUM :Médio
+STR_681E_FAST :Rápido
+STR_681F_VERY_FAST :Muito Rápido
+STR_VERY_LOW :Muito Baixo
+STR_6820_LOW :Baixo
+STR_6821_MEDIUM :Médio
+STR_6822_HIGH :Alto
+STR_6823_NONE :Nenhum
+STR_6824_REDUCED :Reduzido
+STR_6825_NORMAL :Normal
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Muito Plano
+STR_682B_FLAT :Plano
+STR_682C_HILLY :Acidentado
+STR_682D_MOUNTAINOUS :Montanhoso
+STR_682E_STEADY :Estável
+STR_682F_FLUCTUATING :Flutuante
+STR_6830_IMMEDIATE :Imediato
+STR_6831_3_MONTHS_AFTER_PLAYER :3 meses depois do jogador
+STR_6832_6_MONTHS_AFTER_PLAYER :6 meses depois do jogador
+STR_6833_9_MONTHS_AFTER_PLAYER :9 meses depois do jogador
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :No fim da linha e em estações
+STR_6835_AT_END_OF_LINE_ONLY :Só no fim da linha
+STR_6836_OFF :Off
+STR_6837_ON :On
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Mostrar melhores pontuações
+STR_6839_PERMISSIVE :Permissivo
+STR_683A_TOLERANT :Tolerante
+STR_683B_HOSTILE :Hostil
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Jogador {COMMA})
+STR_7004_NEW_FACE :{BLACK}Novo Rosto
+STR_7005_COLOR_SCHEME :{BLACK}Cores
+STR_7006_COLOR_SCHEME :{GOLD}Cores:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Novo Esquema de Cores
+STR_7008_COMPANY_NAME :{BLACK}Empresa
+STR_7009_PRESIDENT_NAME :{BLACK}Presidente
+STR_700A_COMPANY_NAME :Nome da Empresa
+STR_700B_PRESIDENT_S_NAME :Nome do Presidente
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Não é possível alterar o nome da empresa...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Não é possível alterar o nome do presidente...
+STR_700E_FINANCES :{WHITE}{COMPANY} Finanças {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Despesas/Lucros
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Construção
+STR_7012_NEW_VEHICLES :{GOLD}Novos Veículos
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Circulação de Trens
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Circulação de Veículos
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Circulação de Aeronaves
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Circulação de Navios
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Manutenção de Propriedades
+STR_7018_TRAIN_INCOME :{GOLD}Lucros dos Trens
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Lucros dos Veículos
+STR_701A_AIRCRAFT_INCOME :{GOLD}Lucros das Aeronaves
+STR_701B_SHIP_INCOME :{GOLD}Lucros dos Navios
+STR_701C_LOAN_INTEREST :{GOLD}Juros do Empréstimo
+STR_701D_OTHER :{GOLD}Outros
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Total:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Gráfico de Rendimentos
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Gráfico de Lucros Operacionais
+STR_7026_BANK_BALANCE :{WHITE}Balanço Bancário
+STR_7027_LOAN :{WHITE}Empréstimo
+STR_MAX_LOAN :{WHITE}Empréstimo Máximo: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}Pedir emprestado {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Pagar empréstimo {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...o empréstimo máximo permitido é de {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Não é possível pedir mais dinheiro emprestado...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...não há empréstimo para pagar
+STR_702E_REQUIRED :{WHITE}...necessário {CURRENCY}
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Não é possível pagar empréstimo...
+STR_INSUFFICIENT_FUNDS :{WHITE}Não é possível dar o dinheiro emprestado do banco
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Selecione um novo rosto para o presidente
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Alterar cores dos veículos
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Alterar nome do presidente
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Alterar nome da empresa
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Clique no novo esquema de cor
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Aumentar empréstimo
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Pagar parte do empréstimo
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(Presidente)
+STR_7038_INAUGURATED :{GOLD}Inaugurado: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Veículos:
+STR_TRAINS :{WHITE}{COMMA} tre{P m ns}
+STR_ROAD_VEHICLES :{WHITE}{COMMA} veículo{P "" s} de estrada
+STR_AIRCRAFT :{WHITE}{COMMA} aeronave{P "" s}
+STR_SHIPS :{WHITE}{COMMA} barco{P "" s}
+STR_7042_NONE :{WHITE}Nenhum
+STR_7043_FACE_SELECTION :{WHITE}Seleção de Rosto
+STR_7044_MALE :{BLACK}Masculino
+STR_7045_FEMALE :{BLACK}Feminino
+STR_7046_NEW_FACE :{BLACK}Novo Rosto
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Cancelar seleção da novo rosto
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Aceitar selecção da novo rosto
+STR_7049_SELECT_MALE_FACES :{BLACK}Selecionar rostos masculinas
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Seleccionar rostos femininas
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Gerar novo rosto aleatoriamente
+STR_704C_KEY :{BLACK}Legenda
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Mostrar legenda dos gráficos
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Legendas dos gráficos da empresa
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Clique aqui para mostrar/ocultar companhia no gráfico
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Unidades de carga entregues
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Avaliações da empresa (máximo=1000)
+STR_7052_COMPANY_VALUES :{WHITE}Valor da empresa
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Classificação de Empresas
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}Empresa de transportes em dificuldades!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} será vendida ou declarada falida a menos que melhore os seus rendimentos em breve!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(Presidente)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Fusão de empresa de transportes!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} foi vendida a {COMPANY} por {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Estamos à procura de uma empresa de transportes para comprar a nossa empresa{}{}Deseja comprar {COMPANY} por {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Falida!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} foi fechada pelos credores e todos os seus bens foram vendidos!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}Nova empresa de transportes!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} inicia construção em {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Não é possível comprar empresa...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Tarifas por carga
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Dias em trânsito
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Pagamento por entregar 10 unidades (ou 10 000 litros) de carga numa distância de 20 quadrados
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Mostrar/ocultar gráfico para o tipo de carga
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Engenheiro
+STR_7067_TRAFFIC_MANAGER :Gestor de Tráfego
+STR_7068_TRANSPORT_COORDINATOR :Coordenador de Transportes
+STR_7069_ROUTE_SUPERVISOR :Supervisor de Rotas
+STR_706A_DIRECTOR :Diretor
+STR_706B_CHIEF_EXECUTIVE :Chefe Executivo
+STR_706C_CHAIRMAN :Diretor Executivo
+STR_706D_PRESIDENT :Presidente
+STR_706E_TYCOON :Magnata
+STR_706F_BUILD_HQ :{BLACK}Construir sede
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Construir sede da empresa / ver sede da empresa
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Reconstruir sede da empresa em outro local por 1% do valor da empresa
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Não é possível construir sede da empresa...
+STR_7072_VIEW_HQ :{BLACK}Ver sede
+STR_RELOCATE_HQ :{BLACK}Mover sede
+STR_COMPANY_PASSWORD :{BLACK}Senha
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Usar senha na empresa para prevenir utilizadores não autorizados.
+STR_SET_COMPANY_PASSWORD :Definir senha da empresa
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}Recesso Mundial!{}{}Economistas temem crise!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Fim do recesso!{}{}Melhoras no comércio inspiram confiança nas indústrias à medida que a economia se fortalece!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Alternar entre janela grande/pequena
+STR_7076_COMPANY_VALUE :{GOLD}Valor da empresa: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Comprar 25% de ações
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Vender 25% de ações
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Comprar 25% de ações desta empresa
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Vender 25% de ações desta empresa
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Não é possível comprar 25% de ações desta empresa...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}Não é possível vender 25% de ações desta empresa...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% propriedade de {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% propriedade de {COMPANY}{} {COMMA}% propriedade de {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} foi comprada por {COMPANY}!
+STR_7080_PROTECTED :{WHITE}Esta empresa ainda não troca ações...
+
+STR_LIVERY_DEFAULT :Cores padrão
+STR_LIVERY_STEAM :Máquina a Vapor
+STR_LIVERY_DIESEL :Motor a Diesel
+STR_LIVERY_ELECTRIC :Motor Elétrico
+STR_LIVERY_MONORAIL :Motor Monotrilho
+STR_LIVERY_MAGLEV :Motor Maglev
+STR_LIVERY_DMU :DMU
+STR_LIVERY_EMU :EMU
+STR_LIVERY_PASSENGER_WAGON_STEAM :Vagão de Passageiro (Vapor)
+STR_LIVERY_PASSENGER_WAGON_DIESEL :Vagão de Passageiro (Diesel)
+STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Vagão de Passageiro (Elétrico)
+STR_LIVERY_FREIGHT_WAGON :Vagão de carga
+STR_LIVERY_BUS :Ônibus
+STR_LIVERY_TRUCK :Caminhão
+STR_LIVERY_PASSENGER_SHIP :Navio Passageiro
+STR_LIVERY_FREIGHT_SHIP :Cargueiro
+STR_LIVERY_HELICOPTER :Helicóptero
+STR_LIVERY_SMALL_PLANE :Pequeno Avião
+STR_LIVERY_LARGE_PLANE :Aeronave Grande
+
+STR_LIVERY_GENERAL_TIP :{BLACK}Mostrar esquemas de cor gerais
+STR_LIVERY_TRAIN_TIP :{BLACK}Mostra esquemas de cor de trens
+STR_LIVERY_ROADVEH_TIP :{BLACK}Mostra os esquemas de cor de automóveis
+STR_LIVERY_SHIP_TIP :{BLACK}Mostra esquemas de cor de navios
+STR_LIVERY_AIRCRAFT_TIP :{BLACK}Mostrar esquemas de cor de aviões
+STR_LIVERY_PRIMARY_TIP :{BLACK}Seleciona a cor principal para o esquema selecionado
+STR_LIVERY_SECONDARY_TIP :{BLACK}Seleciona a cor secundária para o esquema selecionado
+STR_LIVERY_PANEL_TIP :{BLACK}Selecione um esquema a mudar, ou múltiplos esquemas com CTRL+clique. Marque a opção para utilizar o esquema
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (Vapor)
+STR_8001_MJS_250_DIESEL :MJS 250 (Diesel)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut Diesel
+STR_8006_POWERNAUT_DIESEL :Powernaut Diesel
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (Vapor)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (Vapor)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (Vapor)
+STR_800A_SH_8P_STEAM :SH '8P' (Vapor)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (Diesel)
+STR_800C_DASH_DIESEL :'Dash' (Diesel)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (Diesel)
+STR_800E_UU_37_DIESEL :UU '37' (Diesel)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (Diesel)
+STR_8010_CS_4000_DIESEL :CS 4000 (Diesel)
+STR_8011_CS_2400_DIESEL :CS 2400 (Diesel)
+STR_8012_CENTENNIAL_DIESEL :Centennial (Diesel)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (Diesel)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (Diesel)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (Diesel)
+STR_8016_SH_125_DIESEL :SH '125' (Diesel)
+STR_8017_SH_30_ELECTRIC :SH '30' (Elétrico)
+STR_8018_SH_40_ELECTRIC :SH '40' (Elétrico)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (Elétrico)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (Elétrico)
+STR_801B_PASSENGER_CAR :Vagão de Passageiros
+STR_801C_MAIL_VAN :Vagão de Correspondências
+STR_801D_COAL_CAR :Vagão de Carvão
+STR_801E_OIL_TANKER :Tanque de Petróleo
+STR_801F_LIVESTOCK_VAN :Vagão de Gado
+STR_8020_GOODS_VAN :Vagão de Bens
+STR_8021_GRAIN_HOPPER :Vagão de Cereais
+STR_8022_WOOD_TRUCK :Vagão de Madeira
+STR_8023_IRON_ORE_HOPPER :Vagão de Minério de Ferro
+STR_8024_STEEL_TRUCK :Vagão de Aço
+STR_8025_ARMORED_VAN :Vagão Blindado
+STR_8026_FOOD_VAN :Vagão de Comida
+STR_8027_PAPER_TRUCK :Vagão de Papel
+STR_8028_COPPER_ORE_HOPPER :Vagão de Minério de Cobre
+STR_8029_WATER_TANKER :Tanque de Ãgua
+STR_802A_FRUIT_TRUCK :Vagão de Fruta
+STR_802B_RUBBER_TRUCK :Vagão de Borracha
+STR_802C_SUGAR_TRUCK :Vagão de Açúcar
+STR_802D_COTTON_CANDY_HOPPER :Vagão de Algodão Doce
+STR_802E_TOFFEE_HOPPER :Vagão de Caramelo
+STR_802F_BUBBLE_VAN :Vagão de Bolhas
+STR_8030_COLA_TANKER :Tanque de Cola
+STR_8031_CANDY_VAN :Vagão de Doces
+STR_8032_TOY_VAN :Vagão de Brinquedos
+STR_8033_BATTERY_TRUCK :Vagão de Baterias
+STR_8034_FIZZY_DRINK_TRUCK :Vagão de Bebidas Gasosas
+STR_8035_PLASTIC_TRUCK :Vagão de Plástico
+STR_8036_X2001_ELECTRIC :'X2001' (Elétrico)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Elétrico)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :Vagão de Passageiros
+STR_803A_MAIL_VAN :Vagão de Correspondências
+STR_803B_COAL_CAR :Vagão de Carvão
+STR_803C_OIL_TANKER :Tanque de Petróleo
+STR_803D_LIVESTOCK_VAN :Vagão de Gado
+STR_803E_GOODS_VAN :Vagão de Bens
+STR_803F_GRAIN_HOPPER :Vagão de Cereais
+STR_8040_WOOD_TRUCK :Vagão de Madeira
+STR_8041_IRON_ORE_HOPPER :Vagão de Minério de Ferro
+STR_8042_STEEL_TRUCK :Vagão de Aço
+STR_8043_ARMORED_VAN :Vagão Blindado
+STR_8044_FOOD_VAN :Vagão de Comida
+STR_8045_PAPER_TRUCK :Vagão de Papel
+STR_8046_COPPER_ORE_HOPPER :Vagão de Minério de Cobre
+STR_8047_WATER_TANKER :Tanque de Ãgua
+STR_8048_FRUIT_TRUCK :Vagão de Fruta
+STR_8049_RUBBER_TRUCK :Vagão de Borracha
+STR_804A_SUGAR_TRUCK :Vagão de Açúcar
+STR_804B_COTTON_CANDY_HOPPER :Vagão de Algodão Doce
+STR_804C_TOFFEE_HOPPER :Vagão de Caramelo
+STR_804D_BUBBLE_VAN :Vagão de Bolhas
+STR_804E_COLA_TANKER :Tanque de Cola
+STR_804F_CANDY_VAN :Vagão de Doces
+STR_8050_TOY_VAN :Vagão de Brinquedos
+STR_8051_BATTERY_TRUCK :Vagão de Baterias
+STR_8052_FIZZY_DRINK_TRUCK :Vagão de Bebidas Gasosas
+STR_8053_PLASTIC_TRUCK :Vagão de Plástico
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (Elétrico)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (Elétrico)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (Elétrico)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (Elétrico)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :Vagão de Passageiros
+STR_805A_MAIL_VAN :Vagão de Correspondências
+STR_805B_COAL_CAR :Vagão de Carvão
+STR_805C_OIL_TANKER :Tanque de Petróleo
+STR_805D_LIVESTOCK_VAN :Vagão de Gado
+STR_805E_GOODS_VAN :Vagão de Bens
+STR_805F_GRAIN_HOPPER :Vagão de Cereais
+STR_8060_WOOD_TRUCK :Vagão de Madeira
+STR_8061_IRON_ORE_HOPPER :Vagão de Minério de Ferro
+STR_8062_STEEL_TRUCK :Vagão de Aço
+STR_8063_ARMORED_VAN :Vagão Blindado
+STR_8064_FOOD_VAN :Vagão de Comida
+STR_8065_PAPER_TRUCK :Vagão de Papel
+STR_8066_COPPER_ORE_HOPPER :Vagão de Minério de Cobre
+STR_8067_WATER_TANKER :Tanque de Ãgua
+STR_8068_FRUIT_TRUCK :Vagão de Fruta
+STR_8069_RUBBER_TRUCK :Vagão de Borracha
+STR_806A_SUGAR_TRUCK :Vagão de Açúcar
+STR_806B_COTTON_CANDY_HOPPER :Vagão de Algodão Doce
+STR_806C_TOFFEE_HOPPER :Vagão de Caramelo
+STR_806D_BUBBLE_VAN :Vagão de Bolhas
+STR_806E_COLA_TANKER :Tanque de Cola
+STR_806F_CANDY_VAN :Vagão de Doces
+STR_8070_TOY_VAN :Vagão de Brinquedos
+STR_8071_BATTERY_TRUCK :Vagão de Baterias
+STR_8072_FIZZY_DRINK_TRUCK :Vagão de Bebidas Gasosas
+STR_8073_PLASTIC_TRUCK :Vagão de Plástico
+STR_8074_MPS_REGAL_BUS :Ônibus MPS Regal
+STR_8075_HEREFORD_LEOPARD_BUS :Ônibus Hereford Leopard
+STR_8076_FOSTER_BUS :Ônibus Foster
+STR_8077_FOSTER_MKII_SUPERBUS :Ônibus Foster MkII
+STR_8078_PLODDYPHUT_MKI_BUS :Ônibus Ploddyphut MkI
+STR_8079_PLODDYPHUT_MKII_BUS :Ônibus Ploddyphut MkII
+STR_807A_PLODDYPHUT_MKIII_BUS :Ônibus Ploddyphut MkIII
+STR_807B_BALOGH_COAL_TRUCK :Caminhão de Carvão Balogh
+STR_807C_UHL_COAL_TRUCK :Caminhão de Carvão Uhl
+STR_807D_DW_COAL_TRUCK :Caminhão de Carvão DW
+STR_807E_MPS_MAIL_TRUCK :Caminhão de Correspondências MPS
+STR_807F_REYNARD_MAIL_TRUCK :Caminhão de Correspondências Reynard
+STR_8080_PERRY_MAIL_TRUCK :Caminhão de Correspondências Perry
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :Caminhão de Correspondências MightyMover
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Caminhão de Correspondências Powernaught
+STR_8083_WIZZOWOW_MAIL_TRUCK :Caminhão de Correspondências Wizzowow
+STR_8084_WITCOMBE_OIL_TANKER :Tanque de Petróleo Witcombe
+STR_8085_FOSTER_OIL_TANKER :Tanque de Petróleo Foster
+STR_8086_PERRY_OIL_TANKER :Tanque de Petróleo Perry
+STR_8087_TALBOTT_LIVESTOCK_VAN :Caminhão de Gado Talbott
+STR_8088_UHL_LIVESTOCK_VAN :Caminhão de Gado Uhl
+STR_8089_FOSTER_LIVESTOCK_VAN :Caminhão de Gado Foster
+STR_808A_BALOGH_GOODS_TRUCK :Caminhão de Bens Balogh
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Caminhão de Bens Craighead
+STR_808C_GOSS_GOODS_TRUCK :Camnhião de Bens Goss
+STR_808D_HEREFORD_GRAIN_TRUCK :Caminhão de Cereais Hereford
+STR_808E_THOMAS_GRAIN_TRUCK :Caminhão de Cereais Thomas
+STR_808F_GOSS_GRAIN_TRUCK :Caminhão de Cereais Goss
+STR_8090_WITCOMBE_WOOD_TRUCK :Caminhão de Madeira Witcombe
+STR_8091_FOSTER_WOOD_TRUCK :Caminhão de Madeira Foster
+STR_8092_MORELAND_WOOD_TRUCK :Caminhão de Madeira Moreland
+STR_8093_MPS_IRON_ORE_TRUCK :Caminhão de Minério de Ferro MPS
+STR_8094_UHL_IRON_ORE_TRUCK :Caminhão de Minério de Ferro Uhl
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Caminhão de Minério de Ferro Chippy
+STR_8096_BALOGH_STEEL_TRUCK :Caminhão de Aço Balogh
+STR_8097_UHL_STEEL_TRUCK :Caminhão de Aço Uhl
+STR_8098_KELLING_STEEL_TRUCK :Caminhão de Aço Kelling
+STR_8099_BALOGH_ARMORED_TRUCK :Caminhão Blindado Balogh
+STR_809A_UHL_ARMORED_TRUCK :Caminhão Blindado Uhl
+STR_809B_FOSTER_ARMORED_TRUCK :Caminhão Blindado Foster
+STR_809C_FOSTER_FOOD_VAN :Caminhão de Comida Foster
+STR_809D_PERRY_FOOD_VAN :Caminhão de Comida Perry
+STR_809E_CHIPPY_FOOD_VAN :Caminhão de Comida Chippy
+STR_809F_UHL_PAPER_TRUCK :Caminhão de Papel Uhl
+STR_80A0_BALOGH_PAPER_TRUCK :Caminhão de Papel Balogh
+STR_80A1_MPS_PAPER_TRUCK :Caminhão de Papel MPS
+STR_80A2_MPS_COPPER_ORE_TRUCK :Caminhão de Minério de Cobre MPS
+STR_80A3_UHL_COPPER_ORE_TRUCK :Caminhão de Minério de Cobre Uhl
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Caminhão de Minério de Cobre Goss
+STR_80A5_UHL_WATER_TANKER :Cisterna de Ãgua Uhl
+STR_80A6_BALOGH_WATER_TANKER :Cisterna de Ãgua Balogh
+STR_80A7_MPS_WATER_TANKER :Cisterna de Ãgua MPS
+STR_80A8_BALOGH_FRUIT_TRUCK :Caminhão de Fruta Balogh
+STR_80A9_UHL_FRUIT_TRUCK :Caminhão de Fruta Uhl
+STR_80AA_KELLING_FRUIT_TRUCK :Caminhão de Fruta Kelling
+STR_80AB_BALOGH_RUBBER_TRUCK :Caminhão de Borracha Balogh
+STR_80AC_UHL_RUBBER_TRUCK :Caminhão de Borracha Uhl
+STR_80AD_RMT_RUBBER_TRUCK :Caminhão de Borracha RMT
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :Caminhão de Açúcar MightyMover
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Caminhão de Açúcar Powernaught
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Caminhão de Açúcar Wizzowow
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :Caminhão de Cola MightyMover
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Caminhão de Cola Powernaught
+STR_80B3_WIZZOWOW_COLA_TRUCK :Caminhão de Cola Wizzowow
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :Caminhão de Algodão Doce MightyMover
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Caminhão de Algodão Doce Powernaught
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Caminhão de Algodão Doce Wizzowow
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :Caminhão de Caramelo MightyMover
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Caminhão de Caramelo Powernaught
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Caminhão de Caramelo Wizzowow
+STR_80BA_MIGHTYMOVER_TOY_VAN :Caminhão de Brinquedos MightyMover
+STR_80BB_POWERNAUGHT_TOY_VAN :Caminhão de Brinquedos Powernaught
+STR_80BC_WIZZOWOW_TOY_VAN :Caminhão de Brinquedos Wizzowow
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :Caminhão de Doces MightyMover
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Caminhão de Doces Powernaught
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Caminhão de Doces Wizzowow
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :Caminhão de Baterias MightyMover
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Caminhão de Baterias Powernaught
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Caminhão de Baterias Wizzowow
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :Caminhão de Bebidas Gasosas MightyMover
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Caminhão de Bebidas Gasosas Powernaught
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Caminhão de Bebidas Gasosas Wizzowow
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :Caminhão de Plástico MightyMover
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Caminhão de Plástico Powernaught
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Caminhão de Plástico Wizzowow
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :Caminhão de Bolhas MightyMover
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Caminhão de Bolhas Powernaught
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Caminhão de Bolhas Wizzowow
+STR_80CC_MPS_OIL_TANKER :Cisterna de Petróleo MPS
+STR_80CD_CS_INC_OIL_TANKER :Cisterna de Petróleo CS-Inc.
+STR_80CE_MPS_PASSENGER_FERRY :Navio de Passageiros MPS
+STR_80CF_FFP_PASSENGER_FERRY :Navio de Passageiros FFP
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Hovercraft Bakewell 300
+STR_80D1_CHUGGER_CHUG_PASSENGER :Navio de Passageiros Chugger-Chug
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Navio de Passageiros Shivershake
+STR_80D3_YATE_CARGO_SHIP :Navio de Bens Yate
+STR_80D4_BAKEWELL_CARGO_SHIP :Navio de Bens Bakewell
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Navio de Bens Mightymover
+STR_80D6_POWERNAUT_CARGO_SHIP :Navio de Bens Powernaut
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Helicóptero Tricario
+STR_80FE_GURU_X2_HELICOPTER :Helicóptero Guru X2
+STR_80FF_POWERNAUT_HELICOPTER :Helicóptero Powernaut
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Mensagem de um fabricante de veículos
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}Projetamos um novo {STRING} - gostaria de ter um ano de exclusividade de uso deste veículo, de modo a que possamos avaliar a sua performance antes de o disponibilizar para todos ?
+STR_8102_RAILROAD_LOCOMOTIVE :locomotiva ferroviária
+STR_8103_ROAD_VEHICLE :veículo de estrada
+STR_8104_AIRCRAFT :aeronave
+STR_8105_SHIP :barco
+STR_8106_MONORAIL_LOCOMOTIVE :locomotiva monotrilho
+STR_8107_MAGLEV_LOCOMOTIVE :locomotiva trem-bala
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}{TOWN} Depósito Ferroviário
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Cidadãos celebram . . .{}Primeiro comboio chega a {STATION}!
+STR_8802_DETAILS :{WHITE}{STRING} (Detalhes)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Trem no caminho
+STR_8804 :{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8806_GO_TO :Ir para {STATION}
+STR_8807_GO_TO_TRANSFER :Ir para {STATION} (Transferir e carregar)
+STR_8808_GO_TO_UNLOAD :Ir para {STATION} (Descarregar)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Ir para {STATION} (Transferir e deixar vazio)
+STR_880A_GO_TO_LOAD :Ir para {STATION} (Carregar)
+STR_880B_GO_TO_TRANSFER_LOAD :Ir para {STATION} (Trasferir e aguardar carga total)
+STR_880C_GO_NON_STOP_TO :Ir sem parar para {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Ir sem parar para {STATION} (Transferir e carregar)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Ir sem parar para {STATION} (Descarregar)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Ir sem parar para {STATION} (Transferir e deixar vazio)
+STR_8810_GO_NON_STOP_TO_LOAD :Ir sem parar para {STATION} (Carregar)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Ir sem parar para {STATION} (Trasferir e aguardar carga total)
+STR_GO_TO_TRAIN_DEPOT :Ir para {TOWN} Depósito de Trens
+STR_SERVICE_AT_TRAIN_DEPOT :Manutenção no depósito de {TOWN}
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Ir sem parar para o depósito de {TOWN}
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Manutenção no depósito de {TOWN} sem parar
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}Dirigindo-se ao depósito de {TOWN}
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}Dirigindo-se ao depósito de {TOWN}, {VELOCITY}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE :{LTBLUE}Manutenção no Depósito de {TOWN}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE_VEL :{LTBLUE}Manutenção no Depósito de {TOWN}, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (Ordem Inválida)
+
+STR_UNKNOWN_DESTINATION :destino desconhecido
+STR_8812_EMPTY :{LTBLUE}Vazio
+STR_8813_FROM :{LTBLUE}{CARGO} de {STATION}
+STR_FROM_MULT :{LTBLUE}{CARGO} de {STATION} (x{NUM})
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}Trem {COMMA} está aguardando no depósito
+STR_8815_NEW_VEHICLES :{BLACK}Novos Veículos
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Trem muito longo
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Os trens só podem ser alterados quando parados num depósito
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} Trens
+
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Novos Veículos Ferroviários
+STR_NEW_ELRAIL_VEHICLES :{WHITE}Máquinas Elétricas Novas
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Novos Veículos Ferroviários(Monotrilho)
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Novos Veículos Ferroviários(Trem-Bala)
+STR_ALL_AVAIL_RAIL_VEHICLES :{WHITE}Trens
+
+STR_881F_BUILD_VEHICLE :{BLACK}Construir Veículo
+STR_CLONE_ROAD_VEHICLE :{BLACK}Clonar Veículo
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}Isso vai construir uma cópia do veículo. Control-clique vai compartilhar as ordens
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Isso vai construir uma cópia do veículo. Clique neste botão e depois em um veículo dentro ou fora do depósito. Control-clique vai compartilhar as ordens
+STR_CLONE_TRAIN :{BLACK}Clonar Trem
+STR_CLONE_TRAIN_INFO :{BLACK}Isso vai construir uma cópia do trem, incluindo os vagões. Control-clique vai compartilhar as ordens
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}Isso vai construir uma cópia do trem, incluindo os vagões. Clique nesse botão e depois em um trem dentro ou fora do depósito . Control-clique vai compartilhar as ordens
+STR_8820_RENAME :{BLACK}Renomear
+STR_8823_SKIP :{BLACK}Saltar
+STR_8824_DELETE :{BLACK}Eliminar
+STR_8825_NON_STOP :{BLACK}Sem parar
+STR_8826_GO_TO :{BLACK}Ir Para
+STR_8827_FULL_LOAD :{BLACK}Carga
+STR_8828_UNLOAD :{BLACK}Descarga
+STR_REFIT :{BLACK}Readaptar
+STR_REFIT_TIP :{BLACK}Selecione a adaptação na ordem atual. CTRL + Clique para remover a instrução
+STR_REFIT_ORDER :(Readaptar para {STRING})
+STR_8829_ORDERS :{WHITE}{VEHICLE} (Ordens)
+STR_882A_END_OF_ORDERS :{SETX 10}- - Fim de Ordens - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}Manutenção
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Não é possível construir veículo ferroviário...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Construído: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Valor: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}Carregando / descarregando
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}O trem deve estar parado dentro do depósito
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Não é possível mandar o trem para o depósito...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Não há espaço para mais ordens
+STR_8832_TOO_MANY_ORDERS :{WHITE}Muitas ordens
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Não é possível inserir nova ordem...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Não é possível eliminar esta ordem...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Não é possível modificar esta ordem...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Não é possível mover veículo...
+STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}A locomotiva traseira sempre deve seguir sua complementar frontal
+STR_8838_N_A :N/D{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Não é possível vender veículo ferroviário...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Não é possível encontrar rota para o depósito local
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Não é possível iniciar/parar o trem...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Intervalo de serviço: {LTBLUE}{COMMA}dias{BLACK} Último serviço: {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Intervalo de serviço: {LTBLUE}{COMMA}%{BLACK} Último serviço: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Trens - clique num comboio para informações
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Construir novos trens (necessita depósito de trens)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Trens - clique num trem para informações, arraste um veículo o adicionar ao tren ou remover
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Construir novo veículo ferroviário
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Arraste o veículo ferroviário para aqui para o vender
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centrar visualização na localização de um depósito ferroviário
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Lista de veículos ferroviários - clique num veículo para informações
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Construir o veículo ferroviário seleccionado
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Renomear tipo de veículo ferroviário
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Tarefa actual do comboio - clique aqui para iniciar/parar comboio
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Mostrar ordens do comboio
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centrar visualização na localização do comboio
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Mandar comboio para o depósito
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Forçar comboio a prosseguir sem esperar pelo sinal
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Inverter direcção do comboio
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Mostrar detalhes do comboio
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Aumentar intervalo de serviço
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Diminuir intervalo de serviço
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Mostrar detalhes da carga transportada
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Mostrar detalhes dos veículos
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Mostrar capacidades de cada veículo
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Mostrar capacidade total do comboio, dividir por tipo de carga
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Lista de ordens - clique numa ordem para a seleccionar
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}Saltar a ordem actual, e iniciar a próxima
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Eliminar a ordem seleccionada
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}A ordem seleccionada fará com que o veículo não para noutras estações pelo caminho
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Inserir nova ordem antes da ordem seleccionada, ou adicionar ao fim da lista
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}A ordem seleccionada fará com que o veículo espere carregar completamente
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}A ordem seleccionada forçará o veículo a descarregar
+STR_SERVICE_HINT :{BLACK}Saltar esta ordem a menos que seja necessário manutenção
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}Novo {STRING} disponível!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Custo: {CURRENCY} Peso: {WEIGHT_S}{}Velocidade: {VELOCITY} Potência: {POWER}{}Custo de circulação: {CURRENCY}/ano{}Capacidade: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}Quebrado
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}Idade: {LTBLUE}{STRING}{BLACK} Custo de circulação: {LTBLUE}{CURRENCY}/ano
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Peso: {LTBLUE}{WEIGHT_S} {BLACK}Potência: {LTBLUE}{POWER}{BLACK} Velocidade Máx.: {LTBLUE}{VELOCITY}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Lucros deste ano: {LTBLUE}{CURRENCY} (último ano: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}Confiabilidade: {LTBLUE}{COMMA}% {BLACK}Quebras desde a última manutenção: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Parado
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Não é possível fazer o comboio passar o sinal de perigo...
+STR_8863_CRASHED :{RED}Acidentado!
+
+STR_8865_NAME_TRAIN :{WHITE}Renomear comboio
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}Não é possível renomear comboio...
+STR_8867_NAME_TRAIN :{BLACK}Renomear comboio
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Acidente Ferroviário!{}{COMMA} mortos numa explosão após a colisão
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Não é possível inverter a direcção do comboio...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Renomear tipo de veículo ferroviário
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Não é possível renomear tipo de veículo ferroviário...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Força o veículo a deixar a carga na ordem selecionada
+STR_886F_TRANSFER :{BLACK}Transferência
+
+STR_TRAIN_STOPPING :{RED}A Parar
+STR_TRAIN_STOPPING_VEL :{RED}A Parar, {VELOCITY}
+STR_INCOMPATIBLE_RAIL_TYPES :Tipo de ferrovia incompatível
+STR_TRAIN_NO_POWER :{RED}Sem força
+STR_TRAIN_START_NO_CATENARY :Essa linha não tem energia, portanto o trem não parte
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Veículo de estrada no caminho
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} Veículos de Estrada
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}{TOWN} Depósito de Veículos de Estrada
+STR_9004_NEW_VEHICLES :{BLACK}Novos Veículos
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}Novos Veículos de Estrada
+STR_9007_BUILD_VEHICLE :{BLACK}Construir Veículo
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Não é possível construir veículo de estrada...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (Detalhes)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}Idade: {LTBLUE}{STRING}{BLACK} Custo de circulação: {LTBLUE}{CURRENCY}/ano
+STR_900E_MAX_SPEED :{BLACK}Velocidade Máx.: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Lucros deste ano: {LTBLUE}{CURRENCY} (último ano: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}Confiabilidade: {LTBLUE}{COMMA}% {BLACK}Quebras desde a última manutenção: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Construído: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Capacidade: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}...deve estar parado num depósito de veículos de estrada
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Não é possível vender veículo de estrada...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Não é possível iniciar/parar veículo de estrada...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}Veículo de Estrada {COMMA} está aguardando no depósito
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}Dirigindo-se ao depósito de {TOWN}
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}Dirigindo-se ao depósito de {TOWN}, {VELOCITY}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE :{LTBLUE}Manutenção no Depósito de {TOWN}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE_VEL :{LTBLUE}Manutenção do Depósito de {TOWN}, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Não é possível mandar o veículo para o depósito...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Não é possível encontrar o depósito local
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Veículos de estrada - clique num veículo para informações
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Construir novos veículos de estrada (necessita de depósito de veículos de estrada)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Tarefa actual do veículo - clique aqui para iniciar/parar veículo
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Mostrar ordens do veículo
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Centrar visualização na localização do veículo
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Mandar veículo para o depósito
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Forçar veículo a dar a volta
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Mostrar detalhes do veículo de estrada
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Veículos - clique num veículo para informações
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Construir novo veículo de estrada
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Arraste o veículo de estrada para aqui para o vender
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Centrar visualização na localização do depósito de veículos de estrada
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Lista de veículos de estrada - clique num veículo para informações
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Construir o veículo de estrada seleccionado
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}Novo veículo de estrada disponível!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Custo: {CURRENCY}{}Velocidade: {VELOCITY}{}Custo de circulação: {CURRENCY}/ano{}Capacidade: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Renomear veículo de estrada
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Não é possível renomear veículo de estrada...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Renomear veículo de estrada
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Cidadãos celebram . . .{}Primeiro autocarro chega a {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Cidadãos celebram . . .{}Primeiro camião chega a {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}Acidente de Veículo de Estrada!{}Condutor morre na explosão após a colisão com um comboio
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}Acidente de Veículo de Estrada!{}{COMMA} morrem na explosão após a colisão com um comboio
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Não é possível fazer o veículo dar a volta...
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}Impossível virar veículos formados por unidades múltiplas
+STR_9034_RENAME :{BLACK}Renomear
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Renomear tipo de veículo de estrada
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Renomear tipo de veículo de estrada
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Não é possível renomear tipo de veículo de estrada...
+STR_9038_GO_TO_ROADVEH_DEPOT :Ir para o depósito de {TOWN}
+STR_SERVICE_AT_ROADVEH_DEPOT :Manutenção no depósito de {TOWN}
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Reacondicionar veículo para carregar tipo de carga diferente
+STR_REFIT_ROAD_VEHICLE :{BLACK}Reacondicionar automóvel
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Reacondicionar veículo para carregar o tipo de carga selecionado
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Impossível reacondicionar
+STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Selecione o tipo de carga para o veículo
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Construir docas
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Construir docas
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Não é possível construir doca aqui...
+STR_9803_SHIP_DEPOT :{WHITE}{TOWN} Depósito Naval
+STR_9804_NEW_SHIPS :{BLACK}Novos Navios
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} Navios
+STR_9808_NEW_SHIPS :{WHITE}Novos Navios
+STR_9809_BUILD_SHIP :{BLACK}Construir Navio
+STR_CLONE_SHIP :{BLACK}Clonar Navio
+STR_CLONE_SHIP_INFO :{BLACK}Isso vai construir uma cópia do navio. Control-clique vai compartilhar as ordens
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}Isso vai construir uma cópia de um navio. Clique nesse botão e depois em um navio dentro ou fora do depósito. Control-clique vai compartilhar as ordens
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}O barco deverá estar parado no depósito
+STR_980C_CAN_T_SELL_SHIP :{WHITE}Não é possível vender barco...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Não é possível construir barco...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Navio no caminho
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Detalhes)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}Idade: {LTBLUE}{STRING}{BLACK} Custo de circulação: {LTBLUE}{CURRENCY}/ano
+STR_9813_MAX_SPEED :{BLACK}Velocidade Máx.: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Lucros deste ano: {LTBLUE}{CURRENCY} (último ano: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}Confiabilidade: {LTBLUE}{COMMA}% {BLACK}Quebras desde a última manutenção: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Construído: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}Capacidade: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}Não é possível iniciar/parar barco...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Não é possível mandar barco para o depósito...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Não é possível encontrar depósito local
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}Dirigindo-se ao depósito de {TOWN}
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}Dirigindo-se ao depósito {TOWN}, {VELOCITY}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE :{LTBLUE}Manutenção no Depósito de {TOWN}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE_VEL :{LTBLUE}Manutenção no Depósito de {TOWN}, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}Navio {COMMA} está aguardando no depósito
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Construir doca naval
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Construir depósito (para criação e manutenção de barcos)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Navios - clique num navio para informações
+STR_9820_BUILD_NEW_SHIP :{BLACK}Construir novo barco
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Arraste o barco para aqui para o vender
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centrar visualização na localização do depósito naval
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Navios - clique num navio para informações
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Construir novos barcos (necessita de depósito naval)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}Lista de Navios - clique num navio para informações
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Construir barco seleccionado
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Tarefa atual do navio - clique aqui para iniciar/parar navio
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Mostrar ordens do barco
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centrar visualização na localização do barco
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Mandar barco para o depósito
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Mostrar detalhes do barco
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}Novo barco disponível!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Custo: {CURRENCY} Velocidade Máx.: {VELOCITY}{}Capacidade: {CARGO}{}Custo de circulação: {CURRENCY}/ano
+STR_982F_NAME_SHIP :{BLACK}Renomear barco
+
+STR_9831_NAME_SHIP :{WHITE}Renomear barco
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Não é possível renomear barco...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Cidadãos celebram . . .{}Primeiro barco chega a {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Bóia de posição, que pode ser usada para marcar pontos de rota adicionais
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Não é possível posicionar bóia aqui...
+STR_9836_RENAME :{BLACK}Renomear
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Renomear tipo de barco
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Renomear tipo de barco
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Não é possível renomear tipo de barco...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Adaptar navio de carga para um tipo de carga diferente
+STR_983B_REFIT :{WHITE}{VEHICLE} (Adaptar)
+STR_983C_REFIT_SHIP :{BLACK}Adaptar barco
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Seleccionar tipo de carga do barco
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Adaptar barco para transportar a carga seleccionada
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Seleccionar tipo de carga:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nova capacidade: {GOLD}{CARGO}{}{BLACK}Custo da adaptação: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Não é possível adaptar barco...
+STR_9842_REFITTABLE :(adaptável)
+STR_GO_TO_SHIP_DEPOT :Ir para o depósito naval de {TOWN}
+SERVICE_AT_SHIP_DEPOT :Manutenção no depósito de {TOWN}
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Aeroportos
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Não é possível construir aeroporto aqui...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} Hangar
+STR_A003_NEW_AIRCRAFT :{BLACK}Nova Aeronave
+STR_CLONE_AIRCRAFT :{BLACK}Clonar Aeronave
+STR_CLONE_AIRCRAFT_INFO :{BLACK}Isso vai construir uma cópia da aeronave. Control-clique vai compartilhar as ordens
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Isso vai construir uma cópia de uma aeronave. Clique nesse botão e depois em uma aeronave dentro ou fora do hangar. Control-clique vai compartilhar as ordens
+STR_A005_NEW_AIRCRAFT :{WHITE}Nova Aeronave
+STR_A006_BUILD_AIRCRAFT :{BLACK}Construir Aeronave
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Não é possível construir aeronave...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} Aeronaves
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (Ordens)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (Detalhes)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Idade: {LTBLUE}{STRING}{BLACK} Custo de circulação: {LTBLUE}{CURRENCY}/ano
+STR_A00E_MAX_SPEED :{BLACK}Velocidade Máx.: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Lucros deste ano: {LTBLUE}{CURRENCY} (último ano: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}Confiabilidade: {LTBLUE}{COMMA}% {BLACK}Quebras desde a última manutenção: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Construído: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Não é possível mandar aeronave para o hangar...
+STR_HEADING_FOR_HANGAR :{ORANGE}Dirigindo-se ao hangar de {STATION}
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}Dirigindo-se ao hangar de {STATION}, {VELOCITY}
+STR_HEADING_FOR_HANGAR_SERVICE :{LTBLUE}Manutenção no Hangar de {STATION}
+STR_HEADING_FOR_HANGAR_SERVICE_VEL :{LTBLUE}Manutenção no Hangar de {STATION}, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}Aeronave {COMMA} está aguardando no hangar
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Aeronave no caminho
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Não é possível iniciar/parar aeronave...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Aeronave está em voo
+STR_A019_CAPACITY :{BLACK}Capacidade: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Capacidade: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}A aeronave deverá estar parada no hangar
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Não é possível vender aeronave...
+STR_A01D_AIRPORT_CONSTRUCTION :Construir aeroporto
+STR_A01E_BUILD_AIRPORT :{BLACK}Construir aeroporto
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Aeronave - clique na aeronave para informações
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Construir nova aeronave (necessita de aeroporto com hangar)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Aeronave - clique na aeronave para informações
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Construir nova aeronave
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}Arraste a aeronave para aqui para a vender
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Centrar visualização na localização do hangar
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Lista de aeronaves - clique na aeronave para informações
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Construir aeronave seleccionada
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Tarefa actual da aeronave - clique aqui para iniciar/parar a aeronave
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Mostrar ordens da aeronave
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Centrar visualização na localização da aeronave
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Mandar aeronave para o hangar
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Mostrar detalhes da aeronave
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}Nova aeronave disponível!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Custo: {CURRENCY} Velocidade Máx.: {VELOCITY}{}Capacidade: {COMMA} passageiros, {COMMA} sacos de correio{}Custo de circulação: {CURRENCY}/ano
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Renomear aeronave
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Não é possível renomear aeronave...
+STR_A032_NAME_AIRCRAFT :{BLACK}Renomear aeronave
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Cidadãos celebram . . .{}Primeira aeronave chega a {STATION}!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Acidente de Avião!{}{COMMA} morrem na explosão em {STATION}
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Desastre de Avião!{}Avião ficou sem combustivél, {COMMA} morreram em incêndiol!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Renomear
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Renomear tipo de aeronave
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Renomear tipo de aeronave
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Não é possível renomear tipo de aeronave...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Adaptar aeronave para um tipo de carga diferente
+STR_A03C_REFIT :{WHITE}{VEHICLE} (Adaptar)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Adaptar aeronave
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Seleccionar tipo de carga da aeronave
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Adaptar aeronave para transportar a carga seleccionada
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Seleccionar tipo de carga:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nova capacidade: {GOLD}{STRING}{}{BLACK}Custo da adaptação: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Não é possível adaptar aeronave...
+STR_GO_TO_AIRPORT_HANGAR :Ir para o hangar de {STATION}
+SERVICE_AT_AIRPORT_HANGAR :Manutenção no hangar de {STATION}
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}Acidente de Zepelim em {STATION}!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Veículo de estrada destruído em colisão com OVNI!
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}Explosão na refinaria de petróleo em {TOWN}!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}Fábrica destruída em circunstâncias suspeitas em {TOWN}!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}OVNI pousa em {TOWN}!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}Afundamento de mina de carvão deixa um rasto de destruição em {TOWN}!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Inundações!{}Pelo menos {COMMA} perdidos ou mortos após terríveis inundações!
+
+STR_BRIBE_FAILED :{WHITE}A sua tentativa de suborno foi
+STR_BRIBE_FAILED_2 :{WHITE}descoberta por um investigador regional
+STR_BUILD_DATE :{BLACK}Construído: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Detalhes de rendimentos
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}Detalhes
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Veículos:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Estações:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Min. lucros:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Min. rendimentos:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Máx. rendimentos:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Entregue:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Carga:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Dinheiro:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Empréstimo:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Total:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Número de veículos. Incluindo veículos de estrada, comboios, barcos e aeronaves.
+STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}Número de segmentos de estação. Cada parte de uma estação (ex. estação ferroviária, ponto de ônibus, aeroporto) é contado, mesmo se eles estiverem ligados a uma estação.
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}O lucro do veículo com o rendimento menor (de todos os veículos com mais de 2 anos)
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Dinheiro conseguido no mês com os lucros mais baixos dos últimos 12 trimestres
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Dinheiro conseguido no mês com os lucros mais altos dos últimos 12 trimestres
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}Unidades de carga entregues nos últimos 4 trimestres.
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}Tipos de carga entregues no último trimestre.
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Dinheiro 'em mãos'
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}Tem um empréstimo muito elevado?
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Total de pontos sobre o máximo de pontos
+
+STR_NEWGRF_SETTINGS_BUTTON :{BLACK}Configurações de NewGRF
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}Definições Newgrf
+STR_NEWGRF_APPLY_CHANGES :{BLACK}Aplicar alterações
+STR_NEWGRF_SET_PARAMETERS :{BLACK}Definir parâmetros
+STR_NEWGRF_TIP :{BLACK}Lista de todos os conjuntos Newgrf que instalou. Clique num conjunto para alterar as definições.
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}Não existem ficheiros newgrf actualmente instalados! Por favor consulte o manual para instruções sobre instalar novos gráficos.
+STR_NEWGRF_FILENAME :{BLACK}Nome do ficheiro: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
+STR_NEWGRF_MD5SUM :{BLACK}SomaMD5 (verf. de segurança): {SILVER}{STRING}
+
+STR_NEWGRF_ADD :{BLACK}Adicionar
+STR_NEWGRF_ADD_TIP :{BLACK}Adiciona um NewGRF à lista
+STR_NEWGRF_REMOVE :{BLACK}Remover
+STR_NEWGRF_REMOVE_TIP :{BLACK}Remove to NewGRF selecionado da lista
+STR_NEWGRF_MOVEUP :{BLACK}Mover para cima
+STR_NEWGRF_MOVEUP_TIP :{BLACK}Move o NewGRF selecionado para cima
+STR_NEWGRF_MOVEDOWN :{BLACK}Mover para baixo
+STR_NEWGRF_MOVEDOWN_TIP :{BLACK}Move o NewGRF selecionado para baixo
+STR_NEWGRF_FILE_TIP :{BLACK}Lista dos NewGRF instalados. Clique em um deles para mudar seus parâmetros
+STR_NEWGRF_PARAMETER :{BLACK}Parâmetros: {SILVER}{STRING}
+STR_NEWGRF_PARAMETER_QUERY :{BLACK}Insira novos parâmetros de NewGRF
+STR_NEWGRF_NO_INFO :{BLACK}Sem informação disponível
+
+STR_NEWGRF_ADD_CAPTION :{WHITE}NewGRF disponíveis
+STR_NEWGRF_ADD_FILE :{BLACK}Adicionar à seleção
+STR_NEWGRF_ADD_FILE_TIP :{BLACK}Adiciona o NewGRF selecionado à sua configuração
+STR_NEWGRF_RESCAN_FILES :{BLACK}Reescanear arquivos NewGRF
+STR_NEWGRF_RESCAN_FILES_TIP :{BLACK}Atualiza a lista de NewGRF disponíveis
+STR_NEWGRF_DUPLICATE_GRFID :{WHITE}Impossível adicionar: registro de GRF já existe
+
+STR_NEWGRF_NOT_FOUND :{RED}Arquivo correspondente não encontrado
+STR_NEWGRF_DISABLED :{RED}Desativado
+
+STR_CURRENCY_WINDOW :{WHITE}Moeda Modificada
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Taxa de câmbio: {ORANGE}{CURRENCY} = £ {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Separador:
+STR_CURRENCY_PREFIX :{LTBLUE}Prefixo:
+STR_CURRENCY_SUFFIX :{LTBLUE}Sufixo:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Mudar para Euro: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Mudar para Euro: {ORANGE}nunca
+STR_CURRENCY_PREVIEW :{LTBLUE}Prevêr: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Mudar parametro de moeda personalizada
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} Trem{P "" s}
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} Veiculos de Estrada
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} Aviões
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} Navio
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Mostrar todos os comboios que têm esta estação nas ordens de serviço
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Mostrar todos os veiculos de estrada que têm esta estação nas ordens de serviço
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Mostrar todos os aviões que têm esta estação nas ordens de serviço
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Mostrar todos os navios de cujo itinerário esta estação faz parte
+
+STR_VEH_WITH_SHARED_ORDERS_LIST :{WHITE}Ordens compartilhadas do veículo {COMMA} {P "" s}
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}Mostra todos os veículos com a mesma rota
+
+### depot strings
+STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP :{BLACK}Vender todos os trens no depósito
+STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP :{BLACK}Vender todos os veículos no depósito
+STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP :{BLACK}Vender todos os navios no depósito
+STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP :{BLACK}Vender todas as aeronaves no hangar
+
+STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP :{BLACK}Obtém uma lista de trens com este depósito em suas ordens
+STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP :{BLACK}Obtém uma lista de veículos com este depósito em suas ordens
+STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP :{BLACK}Obtém uma lista de navios com este depósito em suas ordens
+STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP :{BLACK}Obtém uma lista de aeronaves com este hangar em suas ordens
+
+STR_DEPOT_AUTOREPLACE_TRAIN_TIP :{BLACK}Autosubstituir todas os trens no depósito
+STR_DEPOT_AUTOREPLACE_ROADVEH_TIP :{BLACK}Autosubstituir todas os veículos no depósito
+STR_DEPOT_AUTOREPLACE_SHIP_TIP :{BLACK}Autosubstituir todas os navios no depósito
+STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP :{BLACK}Autosubstituir todas as aeronaves no hangar
+
+STR_VEHICLE_LIST_TRAIN_DEPOT :{BLACK}{STRING} - {COMMA} Trem{P "" s}
+STR_VEHICLE_LIST_ROADVEH_DEPOT :{BLACK}{STRING} - {COMMA} Automóvel{P "" s}
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} Navio{P "" s}
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} Aeronave
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}Substituir {STRING}
+STR_REPLACE_VEHICLES_START :{BLACK}Iniciar Substituição de Veículos
+STR_REPLACE_VEHICLES_STOP :{BLACK}Parar Substituição de Veículos
+STR_NOT_REPLACING :{BLACK}Não substituindo
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Nenhum veículo seleccionado
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Seleccione o tipo de motor a substituir
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Seleccione o novo tipo de motor para substituir o que seleccionou à esquerda
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Pressione para parar a subsituição do tipo de motor que seleccionou à esquerda
+STR_REPLACE_HELP_START_BUTTON :{BLACK}Pressione para iniciar a substituição do tipo de motor que seleccionou à esquerda, com o tipo de motor seleccionado à direita
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Seleccione o tipo de carril para o qual deseja efectuar a substituição dos motores
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Exibe o tipo de motor que substituirá o que está seleccionado à esquerda, se algum
+STR_REPLACE_HELP :{BLACK}Permite a substiuição de um tipo de motor por outro, quando comboios do tipo original entram num depósito
+STR_REPLACE_REMOVE_WAGON :{BLACK}Remoção de vagões: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Ordena a autosubstituição a manter o tamanho do trem removendo vagões (começando pela frente), se ao substituir a máquina o trem ficar maior.
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}Substituindo: {ORANGE}{SKIP}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} EXPERIMENTAL {}Troca entre substituir máquinas e substituir vagões.{}Só haverá a substituição se puder haver o reacondicionamento para carregar o mesmo tipo de carga. Essa checagem ocorre para cada vagão enquanto a substituição ocorre.
+STR_ENGINE_NOT_BUILDABLE :{WHITE}A locomotiva não pode ser construída
+
+STR_ENGINES :Motores
+STR_WAGONS :Vagões
+
+STR_MASS_STOP_DEPOT_TRAIN_TIP :{BLACK}Clique para parar todos os trens
+STR_MASS_STOP_DEPOT_ROADVEH_TIP :{BLACK}Clique para parar todos os veículos
+STR_MASS_STOP_DEPOT_SHIP_TIP :{BLACK}Clique para parar todos os navios
+STR_MASS_STOP_HANGAR_TIP :{BLACK}Clique para parar todos as aeronaves
+
+STR_MASS_START_DEPOT_TRAIN_TIP :{BLACK}Clique para mandar todos os trens para o trabalho
+STR_MASS_START_DEPOT_ROADVEH_TIP :{BLACK}Clique para mandar todos os veículos para o trabalho
+STR_MASS_START_DEPOT_SHIP_TIP :{BLACK}Clique para mandar todos os navios para o trabalho
+STR_MASS_START_HANGAR_TIP :{BLACK}Clique para mandar todos as aeronaves para o trabalho
+
+STR_MASS_STOP_LIST_TIP :{BLACK}Clique para mandar todos os veículos pararem
+STR_MASS_START_LIST_TIP :{BLACK}Clique para mandar todos os veículos para o trabalho
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}Lista de sinais - {COMMA} Sinais
+
+STR_ORDER_REFIT_FAILED :{WHITE}Erro na ordem de readaptação {STRING} {COMMA}
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :Trens
+STR_ELRAIL_VEHICLES :Máquinas Elétricas
+STR_MONORAIL_VEHICLES :Monocarris
+STR_MAGLEV_VEHICLES :Maglevs
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Custo: {GOLD}{CURRENCY}{BLACK} Peso: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Velocidade: {GOLD}{VELOCITY}{BLACK} Potência: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}Velocidade: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Manutenção: {GOLD}{CURRENCY}/ano
+STR_PURCHASE_INFO_CAPACITY :{BLACK}Capacidade: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Desenvolvida: {GOLD}{NUM}{BLACK} Vida: {GOLD}{COMMA} anos
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}Confiabilidade Max.: {GOLD}{COMMA}%
+STR_PURCHASE_INFO_COST :{BLACK}Custo: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Peso: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Custo: {GOLD}{CURRENCY}{BLACK} Velocidade: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Capacidade: {GOLD}{COMMA} passageiros, {COMMA} malas de correspondência
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Vagões energizados: {GOLD}+{POWER}{BLACK} Peso: {GOLD}+{WEIGHT_S}
+STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Readaptável para: {GOLD}
+STR_PURCHASE_INFO_ALL_TYPES :Todos as cargas
+STR_PURCHASE_INFO_ALL_BUT :Todas menos {GOLD}
+
+########### String for New Landscape Generator
+
+STR_GENERATE :{WHITE}Gerar
+STR_RANDOM :{BLACK}Randomizar
+STR_RANDOM_HELP :{BLACK}Muda a semente randômica da Geração de Terreno
+STR_WORLD_GENERATION_CAPTION :{WHITE}Geração de mundo
+STR_RANDOM_SEED :{BLACK}Semente:
+STR_RANDOM_SEED_HELP :{BLACK}Clique para digitar uma semente
+STR_LAND_GENERATOR :{BLACK}Gerador de terra
+STR_TREE_PLACER :{BLACK}Algorítimo de árvores
+STR_HEIGHTMAP_ROTATION :{BLACK}Rotação do mapa de altitudes:
+STR_TERRAIN_TYPE :{BLACK}Tipo de terreno
+STR_QUANTITY_OF_SEA_LAKES :{BLACK}Nível do mar:
+STR_SMOOTHNESS :{BLACK}Regularidade
+STR_SNOW_LINE_HEIGHT :{BLACK}Linha da neve
+STR_DATE :{BLACK}Data:
+STR_NUMBER_OF_TOWNS :{BLACK}No. de cidades:
+STR_NUMBER_OF_INDUSTRIES :{BLACK}No. de indústrias:
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_SNOW_LINE_UP :{BLACK}Aumentar a linha da neve em um ponto
+STR_SNOW_LINE_DOWN :{BLACK}Diminuir a linha da neve em um ponto
+STR_SNOW_LINE_QUERY_CAPT :{WHITE}Mudar linha da neve
+STR_START_DATE_QUERY_CAPT :{WHITE}Mudar data de início
+STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Aviso de Escala
+STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Alterar muito o tamanho do mapa original não é recomendado. Continuar com a geração?
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_HEIGHTMAP_NAME :{BLACK}Nome do mapa de altitudes:
+STR_HEIGHTMAP_SIZE :{BLACK}Tamanho: {ORANGE}{NUM} x {NUM}
+STR_GENERATION_WORLD :{WHITE}Gerando mundo...
+STR_GENERATION_ABORT :{BLACK}Abortar
+STR_GENERATION_ABORT_CAPTION :{WHITE}Abortar Geração de Mundo
+STR_GENERATION_ABORT_MESSAGE :{YELLOW}Você quer mesmo abortar a geração?
+STR_PROGRESS :{WHITE}{NUM}% completo
+STR_GENERATION_PROGRESS :{BLACK}{NUM} / {NUM}
+STR_WORLD_GENERATION :{BLACK}Geração de mundo
+STR_TREE_GENERATION :{BLACK}Geração de árvores
+STR_UNMOVABLE_GENERATION :{BLACK}Geração imóvel
+STR_CLEARING_TILES :{BLACK}Geração de area rochosa e irregular
+STR_SETTINGUP_GAME :{BLACK}Preparando jogo
+STR_PREPARING_TILELOOP :{BLACK}Passando tile-loop
+STR_PREPARING_GAME :{BLACK}Preparando jogo
+STR_DIFFICULTY_TO_CUSTOM :{WHITE}Essa ação mudou o nível de dificuldade para personalizado
+STR_SE_FLAT_WORLD :{WHITE}Terra plana
+STR_SE_FLAT_WORLD_TIP :{BLACK}Gera uma terra plana
+STR_SE_RANDOM_LAND :{WHITE}Terra randômica
+STR_SE_NEW_WORLD :{BLACK}Criar novo cenário
+STR_SE_CAPTION :{WHITE}Tipo de cenário
+STR_FLAT_WORLD_HEIGHT_DOWN :{BLACK}Mover a altitude da terra plana em uma unidade a menos
+STR_FLAT_WORLD_HEIGHT_UP :{BLACK}Mover a altitude da terra plana em uma unidade a mais
+STR_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Mudar a altitude da terra plana
+STR_FLAT_WORLD_HEIGHT :{BLACK}Altitude da terra plana
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+STR_SMALLMAP_CENTER :{BLACK}Centralizar o minimapa na posição atual
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}Pequeno
+STR_CITY_AIRPORT :{BLACK}Cidade
+STR_METRO_AIRPORT :{BLACK}Aeroportos Metropolitanos
+STR_INTERNATIONAL_AIRPORT :{BLACK}Aeroporto Internacional
+STR_COMMUTER_AIRPORT :{BLACK}Viajante
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Intercontinental
+STR_HELIPORT :{BLACK}Heliporto
+STR_HELIDEPOT :{BLACK}Deposito de helicópteros
+STR_HELISTATION :{BLACK}Heli-estação
+
+STR_SMALL_AIRPORTS :{BLACK}Aeroportos pequenos
+STR_LARGE_AIRPORTS :{BLACK}Aeroportos Grandes
+STR_HUB_AIRPORTS :{BLACK}Aeroportos modulares
+STR_HELIPORTS :{BLACK}Aeroportos de helicópteros
+
+############ Tooltip measurment
+
+STR_MEASURE_LENGTH :{BLACK}Comprimento: {NUM}
+STR_MEASURE_AREA :{BLACK}Area: {NUM} x {NUM}
+STR_MEASURE_LENGTH_HEIGHTDIFF :{BLACK}Comprimento: {NUM}{}Diferença de Altura: {NUM} m
+STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}Area: {NUM} x {NUM}{}Diferença de altura: {NUM} m
+
+########
diff --git a/src/lang/bulgarian.txt b/src/lang/bulgarian.txt
new file mode 100644
index 000000000..85eb15c61
--- /dev/null
+++ b/src/lang/bulgarian.txt
@@ -0,0 +1,3068 @@
+##name Bulgarian
+##ownname БългарÑки
+##isocode bg_BG.UTF-8
+##plural 0
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Извън картата
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}ÐšÑ€Ð°Ñ Ð½Ð° картата е прекалено близо
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}ÐедоÑтатъчно пари - Ñ‚Ñ€Ñбват {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}ТрÑбва равна земÑ
+STR_0008_WAITING :{BLACK}Чакане: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (на път от
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Приема: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Приема: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :Пътници
+STR_0010_COAL :Въглища
+STR_0011_MAIL :Поща
+STR_0012_OIL :Ðефт
+STR_0013_LIVESTOCK :Добитък
+STR_0014_GOODS :Стоки
+STR_0015_GRAIN :Зърно
+STR_0016_WOOD :Дърва
+STR_0017_IRON_ORE :ЖелÑзна руда
+STR_0018_STEEL :Стомана
+STR_0019_VALUABLES :СкъпоценноÑти
+STR_001A_COPPER_ORE :Медна руда
+STR_001B_MAIZE :Царевица
+STR_001C_FRUIT :Плодове
+STR_001D_DIAMONDS :Диаманти
+STR_001E_FOOD :Храна
+STR_001F_PAPER :ХартиÑ
+STR_0020_GOLD :Злато
+STR_0021_WATER :Вода
+STR_0022_WHEAT :Пшеница
+STR_0023_RUBBER :Каучук
+STR_0024_SUGAR :Захар
+STR_0025_TOYS :Играчки
+STR_0026_CANDY :Сладки
+STR_0027_COLA :Кола
+STR_0028_COTTON_CANDY :Захарен памук
+STR_0029_BUBBLES :Балони
+STR_002A_TOFFEE :Карамел
+STR_002B_BATTERIES :Батерии
+STR_002C_PLASTIC :ПлаÑтмаÑа
+STR_002D_FIZZY_DRINKS :Газирани напитки
+STR_002E :
+STR_002F_PASSENGER :Пътници
+STR_0030_COAL :Въглища
+STR_0031_MAIL :Поща
+STR_0032_OIL :Ðефт
+STR_0033_LIVESTOCK :Добитък
+STR_0034_GOODS :Стоки
+STR_0035_GRAIN :Зърно
+STR_0036_WOOD :Дърва
+STR_0037_IRON_ORE :ЖелÑзна руда
+STR_0038_STEEL :Стомана
+STR_0039_VALUABLES :СкъпоценноÑти
+STR_003A_COPPER_ORE :Медна руда
+STR_003B_MAIZE :Царевица
+STR_003C_FRUIT :Плодове
+STR_003D_DIAMOND :Диаманти
+STR_003E_FOOD :Храна
+STR_003F_PAPER :ХартиÑ
+STR_0040_GOLD :Злато
+STR_0041_WATER :Вода
+STR_0042_WHEAT :Пшеница
+STR_0043_RUBBER :Каучук
+STR_0044_SUGAR :Захар
+STR_0045_TOY :Играчки
+STR_0046_CANDY :Сладки
+STR_0047_COLA :Кола
+STR_0048_COTTON_CANDY :Захарен памук
+STR_0049_BUBBLE :Балони
+STR_004A_TOFFEE :Карамел
+STR_004B_BATTERY :Батерии
+STR_004C_PLASTIC :ПлаÑтмаÑа
+STR_004D_FIZZY_DRINK :Газирани напитки
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} пътни{P к ици}
+STR_QUANTITY_COAL :{WEIGHT} въглища
+STR_QUANTITY_MAIL :{COMMA} торб{P а и} Ñ Ð¿Ð¾Ñ‰Ð°
+STR_QUANTITY_OIL :{VOLUME} нефт
+STR_QUANTITY_LIVESTOCK :{COMMA} глав{P а и} добитък
+STR_QUANTITY_GOODS :{COMMA} кашон{P "" и} ÑÑŠÑ Ñтоки
+STR_QUANTITY_GRAIN :{WEIGHT} зърно
+STR_QUANTITY_WOOD :{WEIGHT} дърва
+STR_QUANTITY_IRON_ORE :{WEIGHT} желÑзна руда
+STR_QUANTITY_STEEL :{WEIGHT} Ñтомана
+STR_QUANTITY_VALUABLES :{COMMA} чант{P а и} ÑкъпоценноÑти
+STR_QUANTITY_COPPER_ORE :{WEIGHT} медна руда
+STR_QUANTITY_MAIZE :{WEIGHT} царевица
+STR_QUANTITY_FRUIT :{WEIGHT} плодове
+STR_QUANTITY_DIAMONDS :{COMMA} чант{P а и} диаманти
+STR_QUANTITY_FOOD :{WEIGHT} храна
+STR_QUANTITY_PAPER :{WEIGHT} хартиÑ
+STR_QUANTITY_GOLD :{COMMA} торб{P а и} ÑÑŠÑ Ð·Ð»Ð°Ñ‚Ð¾
+STR_QUANTITY_WATER :{VOLUME} вода
+STR_QUANTITY_WHEAT :{WEIGHT} пшеница
+STR_QUANTITY_RUBBER :{VOLUME} каучук
+STR_QUANTITY_SUGAR :{WEIGHT} захар
+STR_QUANTITY_TOYS :{COMMA} играчк{P а и}
+STR_QUANTITY_SWEETS :{COMMA} торб{P а и} ÑÑŠÑ Ñладки
+STR_QUANTITY_COLA :{VOLUME} кока-кола
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} захарен памук
+STR_QUANTITY_BUBBLES :{COMMA} мехурче{P "" та}
+STR_QUANTITY_TOFFEE :{WEIGHT} карамел
+STR_QUANTITY_BATTERIES :{COMMA} батери{P Ñ Ð¸Ð¸}
+STR_QUANTITY_PLASTIC :{VOLUME} плаÑтмаÑа
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} газиран{P а и} напитк{P а и}
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}ПÐ
+STR_ABBREV_COAL :{TINYFONT}ВГ
+STR_ABBREV_MAIL :{TINYFONT}ПЩ
+STR_ABBREV_OIL :{TINYFONT}ÐФ
+STR_ABBREV_LIVESTOCK :{TINYFONT}ДБ
+STR_ABBREV_GOODS :{TINYFONT}СТ
+STR_ABBREV_GRAIN :{TINYFONT}ЗР
+STR_ABBREV_WOOD :{TINYFONT}ДВ
+STR_ABBREV_IRON_ORE :{TINYFONT}ЖР
+STR_ABBREV_STEEL :{TINYFONT}СТ
+STR_ABBREV_VALUABLES :{TINYFONT}СЦ
+STR_ABBREV_COPPER_ORE :{TINYFONT}МР
+STR_ABBREV_MAIZE :{TINYFONT}ЦВ
+STR_ABBREV_FRUIT :{TINYFONT}ПЛ
+STR_ABBREV_DIAMONDS :{TINYFONT}ДМ
+STR_ABBREV_FOOD :{TINYFONT}ХР
+STR_ABBREV_PAPER :{TINYFONT}ХТ
+STR_ABBREV_GOLD :{TINYFONT}ЗЛ
+STR_ABBREV_WATER :{TINYFONT}ВД
+STR_ABBREV_WHEAT :{TINYFONT}ЗР
+STR_ABBREV_RUBBER :{TINYFONT}КЧ
+STR_ABBREV_SUGAR :{TINYFONT}ЗХ
+STR_ABBREV_TOYS :{TINYFONT}ИЧ
+STR_ABBREV_SWEETS :{TINYFONT}СЛ
+STR_ABBREV_COLA :{TINYFONT}КЛ
+STR_ABBREV_CANDYFLOSS :{TINYFONT}ЗП
+STR_ABBREV_BUBBLES :{TINYFONT}БЛ
+STR_ABBREV_TOFFEE :{TINYFONT}КМ
+STR_ABBREV_BATTERIES :{TINYFONT}БТ
+STR_ABBREV_PLASTIC :{TINYFONT}ПМ
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}ГÐ
+STR_ABBREV_NONE :{TINYFONT}ÐЩ
+STR_ABBREV_ALL :{TINYFONT}ВЧ
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Карта - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}ÐаÑтройки
+STR_00B2_MESSAGE :{YELLOW}Съобщение
+STR_00B3_MESSAGE_FROM :{YELLOW}Съобщение от {STRING}
+STR_00B4_CAN_T_DO_THIS :{WHITE}Това е невъзможно....
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}ИзчиÑтването е невъзможно....
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}ÐвторÑки права {COPYRIGHT} 1995 ÐšÑ€Ð¸Ñ Ð¡Ð¾Ð¹ÐµÑ€ (Chris Sawyer), Ð’Ñички права Ñа запазени
+STR_00B7_VERSION :{BLACK}OpenTTD верÑÐ¸Ñ {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 The OpenTTD team
+STR_TRANSLATED_BY :{BLACK} Преводач(и) -
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Изход
+STR_00C8_YES :{BLACK}Да
+STR_00C9_NO :{BLACK}Ðе
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Желаете ли да прекъÑнете играта и да Ñе върнете към {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Ðищо
+STR_00D1_DARK_BLUE :Тъмно Ñиньо
+STR_00D2_PALE_GREEN :Бледо зелено
+STR_00D3_PINK :Розово
+STR_00D4_YELLOW :Жълто
+STR_00D5_RED :Червено
+STR_00D6_LIGHT_BLUE :Светло Ñиньо
+STR_00D7_GREEN :Зелено
+STR_00D8_DARK_GREEN :Тъмно зелено
+STR_00D9_BLUE :Синьо
+STR_00DA_CREAM :Кремаво
+STR_00DB_MAUVE :Бледомораво
+STR_00DC_PURPLE :Пурпурно
+STR_00DD_ORANGE :Оранжево
+STR_00DE_BROWN :КафÑво
+STR_00DF_GREY :Сиво
+STR_00E0_WHITE :БÑло
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Прекалено много превозни ÑредÑтва
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}ПозициÑ
+STR_00E5_CONTOURS :Контури
+STR_00E6_VEHICLES :Превозни ÑредÑтва
+STR_00E7_INDUSTRIES :ИндуÑтрии
+STR_00E8_ROUTES :Маршрути
+STR_00E9_VEGETATION :РаÑтителноÑÑ‚
+STR_00EA_OWNERS :СобÑтвеници
+STR_00EB_ROADS :{BLACK}{TINYFONT}Пътища
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}ЖП
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Гари/Летища/Докове
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Сгради/ИндуÑтрии
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Превозни ÑредÑтва
+STR_00F0_100M :{BLACK}{TINYFONT}100 м
+STR_00F1_200M :{BLACK}{TINYFONT}200 м
+STR_00F2_300M :{BLACK}{TINYFONT}300 м
+STR_00F3_400M :{BLACK}{TINYFONT}400 м
+STR_00F4_500M :{BLACK}{TINYFONT}500 м
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Влакове
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Камиони/ÐвтобуÑи
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Кораби
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Самолети
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}ТранÑпортни маршрути
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Мина за въглища
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}ЕлектроÑтанциÑ
+STR_00FC_FOREST :{BLACK}{TINYFONT}Гора
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}ДъÑкорезница
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}РафинериÑ
+STR_00FF_FARM :{BLACK}{TINYFONT}Ферма
+STR_0100_FACTORY :{BLACK}{TINYFONT}Завод
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Печатница
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Ðефтен кладенец
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Мина за желÑзна руда
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}СтоманолеÑрна
+STR_0105_BANK :{BLACK}{TINYFONT}Банка
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Завод за хартиÑ
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Златна мина
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Хранителен завод
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Диамантена мина
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Медна мина
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Офощна плантациÑ
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Каучукова плантациÑ
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Извор
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Водна кула
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}Дърворезница
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Гора от захарен памук
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Завод за Ñладки
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Ферма за батерии
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Кола кладенци
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Магазин за играчки
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Завод за играчки
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}ПлаÑтмаÑов фонтан
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Завод за газирани напитки
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Генератор на балони
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Карамелоломна
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Захарна мина
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}ЖП гара
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Товарна гара
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Ðвтогара
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Летище
+STR_011F_DOCK :{BLACK}{TINYFONT}Док
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Ðеравна земÑ
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Тревна земÑ
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}ПуÑта земÑ
+STR_0123_FIELDS :{BLACK}{TINYFONT}Ðиви
+STR_0124_TREES :{BLACK}{TINYFONT}Дървета
+STR_0125_ROCKS :{BLACK}{TINYFONT}Скали
+STR_0126_WATER :{BLACK}{TINYFONT}Вода
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}ÐÑма ÑобÑтвеник
+STR_0128_TOWNS :{BLACK}{TINYFONT}Градове
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}ИндуÑтрии
+STR_012A_DESERT :{BLACK}{TINYFONT}ПуÑтинÑ
+STR_012B_SNOW :{BLACK}{TINYFONT}СнÑг
+STR_012C_MESSAGE :{WHITE}Съобщение
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}ПреуÑтанови
+STR_012F_OK :{BLACK}OK
+STR_0130_RENAME :{BLACK}Преименувай
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Прекалено много имена
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Избраното име вече е в употреба
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :ОС Х
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...ÑобÑтвеноÑÑ‚ на {STRING}
+STR_013C_CARGO :{BLACK}Товар
+STR_013D_INFORMATION :{BLACK}ИнформациÑ
+STR_013E_CAPACITIES :{BLACK}ВмеÑтимоÑти
+STR_013E_TOTAL_CARGO :{BLACK}Общо товар
+STR_013F_CAPACITY :{BLACK}ВмеÑтимоÑÑ‚: {LTBLUE}{CARGO}
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Обща товарна вмеÑтимоÑÑ‚ на влака:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_0140_NEW_GAME :{BLACK}Ðова игра
+STR_0141_LOAD_GAME :{BLACK}Отвори игра
+STR_SINGLE_PLAYER :{BLACK}Сам играч
+STR_MULTIPLAYER :{BLACK}Много играчи
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Размер на картата:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}ÐаÑтройки
+
+STR_0150_SOMEONE :нÑкой{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Карта на Ñвета
+STR_0152_TOWN_DIRECTORY :СпиÑък Ñ Ð³Ñ€Ð°Ð´Ð¾Ð²Ðµ
+STR_0153_SUBSIDIES :СубÑидии
+
+STR_UNITS_IMPERIAL :ÐнглийÑка
+STR_UNITS_METRIC :МетричеÑка
+STR_UNITS_SI :СИ
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} мили/ч
+STR_UNITS_VELOCITY_METRIC :{COMMA} км/ч
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}к.Ñ.
+STR_UNITS_POWER_METRIC :{COMMA}кÑ
+STR_UNITS_POWER_SI :{COMMA}кв
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}Ñ‚.
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}Ñ‚.
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}кг.
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} тон{P "" ове}
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} тон{P "" ове}
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} кг
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}галон
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}л.
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}куб. м.
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} галон{P "" а}
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} литър{P "" и}
+STR_UNITS_VOLUME_LONG_SI :{COMMA} куб. м.
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10³ lbf
+STR_UNITS_FORCE_METRIC :{COMMA} тон Ñила
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Графика на капитала
+STR_0155_INCOME_GRAPH :Графика на приходите
+STR_0156_DELIVERED_CARGO_GRAPH :Графика на доÑтавките
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Графика на изпълнение
+STR_0158_COMPANY_VALUE_GRAPH :СтойноÑÑ‚ на компаниÑта
+STR_0159_CARGO_PAYMENT_RATES :Тарифи за доÑтавка на Ñтоки
+STR_015A_COMPANY_LEAGUE_TABLE :КлаÑиране на компаниите
+STR_PERFORMANCE_DETAIL_MENU :Рейтинг на предÑтавÑнето в детайли
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}ОтноÑно OpenTTD
+STR_015C_SAVE_GAME :Запази игра
+STR_015D_LOAD_GAME :Отвори игра
+STR_015E_QUIT_GAME :ПреуÑтанови играта
+STR_015F_QUIT :Изход
+STR_ABANDON_GAME_QUERY :{YELLOW}Желаете ли да преуÑтановите играта?
+STR_0161_QUIT_GAME :{WHITE}ПреуÑтанови играта
+STR_SORT_ORDER_TIP :{BLACK}Избери вида на Ñортирането (намалÑващо/нараÑтващо)
+STR_SORT_CRITERIA_TIP :{BLACK}Избери критерий за Ñортиране
+STR_SORT_BY :{BLACK}Сортирай по
+
+STR_SORT_BY_POPULATION :{BLACK}ÐаÑеление
+STR_SORT_BY_PRODUCTION :{BLACK}ПродукциÑ
+STR_SORT_BY_TYPE :{BLACK}Вид
+STR_SORT_BY_TRANSPORTED :{BLACK}ТранÑпортирано
+STR_SORT_BY_NAME :{BLACK}Име
+STR_SORT_BY_DROPDOWN_NAME :Име
+STR_SORT_BY_DATE :{BLACK}Дата
+STR_SORT_BY_NUMBER :Ðомер
+STR_SORT_BY_PROFIT_LAST_YEAR :ЧиÑта печалба миналата година
+STR_SORT_BY_PROFIT_THIS_YEAR :ЧиÑта печалба тази година
+STR_SORT_BY_AGE :ВъзраÑÑ‚
+STR_SORT_BY_RELIABILITY :ÐадеждноÑÑ‚
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Обща вмеÑтимоÑÑ‚ по вида на товара
+STR_SORT_BY_MAX_SPEED :МакÑимална ÑкороÑÑ‚
+STR_SORT_BY_MODEL :Модел
+STR_SORT_BY_VALUE :Цена
+STR_SORT_BY_FACILITY :Вид на гарата
+STR_SORT_BY_WAITING :Цена на чакащиÑÑ‚ товар
+STR_SORT_BY_RATING_MAX :Рейтинг на товара
+STR_ENGINE_SORT_ENGINE_ID :Двигател â„– (клаÑичеÑко Ñортиране)
+STR_ENGINE_SORT_COST :Цена
+STR_ENGINE_SORT_POWER :МощноÑÑ‚
+STR_ENGINE_SORT_INTRO_DATE :Дата на оповеÑÑ‚Ñване
+STR_ENGINE_SORT_RUNNING_COST :Цена за движение
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :МощноÑÑ‚/Цена за движение
+STR_ENGINE_SORT_CARGO_CAPACITY :Товарен капацитет
+STR_NO_WAITING_CARGO :{BLACK}ÐÑма чакащ товар
+STR_SELECT_ALL_FACILITIES :{BLACK}Избор на вÑички ÑъоръжениÑ
+STR_SELECT_ALL_TYPES :{BLACK}Избор на вÑички товари (включително нечакащите)
+STR_REPLACE_VEHICLES :ЗамÑна на превозни ÑредÑтва
+
+############ range for months starts
+STR_0162_JAN :Ян
+STR_0163_FEB :Фев
+STR_0164_MAR :Март
+STR_0165_APR :Ðпр
+STR_0166_MAY :Май
+STR_0167_JUN :Юни
+STR_0168_JUL :Юли
+STR_0169_AUG :Ðвг
+STR_016A_SEP :Сеп
+STR_016B_OCT :Окт
+STR_016C_NOV :Ðое
+STR_016D_DEC :Дек
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Пауза
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Запази, преуÑтанови или излез от играта
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}СпиÑък ÑÑŠÑ Ñтанциите на компаниÑта
+STR_0174_DISPLAY_MAP :{BLACK}Покажи картата
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Покажи картата, ÑпиÑъка Ñ Ð³Ñ€Ð°Ð´Ð¾Ð²Ðµ
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Покажи ÑпиÑъка Ñ Ð³Ñ€Ð°Ð´Ð¾Ð²Ðµ
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Покажи финанÑова Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð° компаниÑта
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Покажи обща Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° компаниÑта
+STR_0179_DISPLAY_GRAPHS :{BLACK}Покажи графиките
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Покажи клаÑирането на компаниите
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Покажи ÑпиÑъка Ñ Ð²Ð»Ð°ÐºÐ¾Ð²Ðµ на компаниÑта
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Покажи ÑпиÑъка Ñ ÐºÐ°Ð¼Ð¸Ð¾Ð½Ð¸/автобуÑи на компаниÑта
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Покажи ÑпиÑъка Ñ ÐºÐ¾Ñ€Ð°Ð±Ð¸ на компаниÑта
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Покажи ÑпиÑъка ÑÑŠÑ Ñамолети на компаниÑта
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Увеличи мащаба
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}ÐамалÑване на мащаба
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}ПоÑтрой ЖП линии
+STR_0182_BUILD_ROADS :{BLACK}ПоÑтрой пътища
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}ПоÑтрой докове
+STR_0184_BUILD_AIRPORTS :{BLACK}ПоÑтрой летища
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}ЗаÑади дървета, поÑтави знаци и др.
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° земÑта
+STR_0187_OPTIONS :{BLACK}ÐаÑтройки
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Интервала на техн. преглед не може да Ñе промени...
+STR_018B_CLOSE_WINDOW :{BLACK}Затвори прозореца
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Заглавие на прозорец - премеÑтване на прозореца Ñ Ð¼Ð¸ÑˆÐºÐ°Ñ‚Ð°
+STR_STICKY_BUTTON :{BLACK}Маркиране прозореца за незатварÑне от клавиша 'ЗатварÑне вÑички прозороци'
+STR_RESIZE_BUTTON :{BLACK}ПремеÑтете за оразмерÑване прозореца
+STR_SAVELOAD_HOME_BUTTON :{BLACK}ПреÑкачане към директориÑта за запиÑ/зарездане по подразбиране
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Разруши поÑтройки и др. върху квадрат от картата
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Понижи ъгъл от земÑта
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Повиши ъгъл от земÑта
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Лента за позициониране - превърта ÑпиÑъка нагоре/надолу
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Превъртаща ивица - превърта ÑпиÑъка на лÑво/дÑÑно
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Покажи земните контури на картата
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Покажи превозните ÑредÑтва
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Покажи индуÑтриите на картата
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Покажи транÑпортните маршрути на картата
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Покажи раÑтителноÑтта на картата
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Покажи ÑобÑтвениците на Ð·ÐµÐ¼Ñ Ð½Ð° картата
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Покажи имената на градовете на картата
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Печалба тази година: {CURRENCY} (минала година: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} годин{P а и} ({COMMA})
+STR_AGE_RED :{RED}{COMMA} годин{P а и} ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :ÐвтобуÑ/камион
+STR_019D_AIRCRAFT :Самолет
+STR_019E_SHIP :Кораб
+STR_019F_TRAIN :Влак
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} е вече Ñтар
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} е вече много Ñтар
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} е вече много Ñтар и Ñпешно Ñе нуждае от подмÑна
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° земÑта
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Цена за изчиÑтване: {LTBLUE}N/A
+STR_01A5_COST_TO_CLEAR :{BLACK}Цена за изчиÑтване: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :Ðе Ñе предлага
+STR_01A7_OWNER :{BLACK}СобÑтвеник: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Община: {LTBLUE}{STRING}
+STR_01A9_NONE :Ðищо
+STR_01AA_NAME :{BLACK}Име
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1-ви
+STR_01AD_2ND :2-ри
+STR_01AE_3RD :3-ти
+STR_01AF_4TH :4-ти
+STR_01B0_5TH :5-и
+STR_01B1_6TH :6-и
+STR_01B2_7TH :7-и
+STR_01B3_8TH :8-и
+STR_01B4_9TH :9-ти
+STR_01B5_10TH :10-ти
+STR_01B6_11TH :11-ти
+STR_01B7_12TH :12-ти
+STR_01B8_13TH :13-ти
+STR_01B9_14TH :14-ти
+STR_01BA_15TH :15-ти
+STR_01BB_16TH :16-ти
+STR_01BC_17TH :17-ти
+STR_01BD_18TH :18-ти
+STR_01BE_19TH :19-ти
+STR_01BF_20TH :20-ти
+STR_01C0_21ST :21-ви
+STR_01C1_22ND :22-ри
+STR_01C2_23RD :23-ти
+STR_01C3_24TH :24-ти
+STR_01C4_25TH :25-ти
+STR_01C5_26TH :26-ти
+STR_01C6_27TH :27-ми
+STR_01C7_28TH :28-и
+STR_01C8_29TH :29-и
+STR_01C9_30TH :30-ти
+STR_01CA_31ST :31-ви
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Приет товар: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Джаз
+STR_01D3_SOUND_MUSIC :Звук/музика
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Покажи прозореца за звук/музика
+STR_01D5_ALL :{TINYFONT}Ð’Ñички
+STR_01D6_OLD_STYLE :{TINYFONT}Стар Ñтил
+STR_01D7_NEW_STYLE :{TINYFONT}Ðов Ñтил
+STR_01D8_EZY_STREET :{TINYFONT}Ezy Street
+STR_01D9_CUSTOM_1 :{TINYFONT}ПерÑонален 1
+STR_01DA_CUSTOM_2 :{TINYFONT}ПерÑонален 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Сила на музиката
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Сила на ефектите
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MIN ' ' ' ' ' ' MAX
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Превърти до предишната пеÑен
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Превърти до Ñледващата пеÑен
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Спри музиката
+STR_01E1_START_PLAYING_MUSIC :{BLACK}ПуÑни музиката
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}ПремеÑтете плъзгачите за промÑна Ñилата на звука
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}ПеÑен{SETX 88}Заглавие
+STR_01E9_SHUFFLE :{TINYFONT}Разбъркано
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Програма
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Избор на музикалната програма
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Ðомер на пеÑен
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Програма - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}ИзчиÑти
+STR_01F1_SAVE :{TINYFONT}{BLACK}Запази
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Текуща програма от музикални парчета
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Избери програма 'вÑички парчета'
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Избери програма 'Ñтар Ñтил музика'
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Избери програма 'нов Ñтил музика'
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Избери програма 'Мой вкуÑ1' (определена от теб)
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Избери програма 'Мой Ð²ÐºÑƒÑ 2' (определена от теб)
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}ИзчиÑти текущата програма (Ñамо Мой вкуÑ1 или Мой вкуÑ2)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Запази музикалните наÑтройки
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}ÐатиÑни върху музикално парче за да го добавиш към текущата програма (Ñамо Мой вкуÑ1 или Мой вкуÑ2)
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}ÐатиÑнете върху парче за да го премахнете от програмата (Custom1 и Custom2 Ñамо)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Ðктивирай/деактивирай размеÑтване на парчетата
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Покажи прозореца за избор на музикални парчета
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Кликни върху уÑлугата, за да Ñе фокуÑира върху индуÑтриÑта/града
+STR_01FE_DIFFICULTY :{BLACK}СложноÑÑ‚ ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :ПоÑледно Ñъобщение/новини
+STR_0201_MESSAGE_SETTINGS :ÐаÑтройки на ÑъобщениÑта
+STR_MESSAGE_HISTORY_MENU :ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ð½Ð° ÑъобщениÑта
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Покажи поÑледното Ñъобщение/новини, покажи наÑтройките на ÑъобщениÑта
+STR_0204_MESSAGE_OPTIONS :{WHITE}ÐаÑтройки на ÑъобщениÑта
+STR_0205_MESSAGE_TYPES :{BLACK}Типове ÑъобщениÑ:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Първо приÑтигане на превозно ÑредÑтво в ÑтанциÑ
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Първо приÑтигане на превозно ÑредÑтво в конкурентна ÑтанциÑ
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Инциденти / бедÑтвиÑ
+STR_0209_COMPANY_INFORMATION :{YELLOW}Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° компаниÑта
+STR_020A_ECONOMY_CHANGES :{YELLOW}Промени в икономиката
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Съвет / Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° превозните ÑредÑтва
+STR_020C_NEW_VEHICLES :{YELLOW}Ðови превозни ÑредÑтва
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Промени в приемането на товари
+STR_020E_SUBSIDIES :{YELLOW}СубÑидии
+STR_020F_GENERAL_INFORMATION :{YELLOW}Обща информациÑ
+STR_MESSAGES_ALL :{YELLOW}Ð’Ñички видове ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ñа: Изключено / Обобщено/ Пълно
+STR_MESSAGE_SOUND :{YELLOW}Покажи обобщените новини ÑÑŠÑ Ð·Ð²ÑƒÐº
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...прекалено далече от предходната цел
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Първите компании доÑтигнали {NUM}{}({STRING} ниво)
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Таблица Лига на компании в {NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :БизнеÑмен
+STR_0214_ENTREPRENEUR :Предприемач
+STR_0215_INDUSTRIALIST :ИндуÑтриалиÑÑ‚
+STR_0216_CAPITALIST :КапиталиÑÑ‚
+STR_0217_MAGNATE :Магнат
+STR_0218_MOGUL :Завоевател
+STR_0219_TYCOON_OF_THE_CENTURY :Ðкула на века
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} доÑтигна ÑÑ‚Ð°Ñ‚ÑƒÑ '{STRING}'!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} от {COMPANY} доÑтигна ÑÑ‚Ð°Ñ‚ÑƒÑ '{STRING}'!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Създай Ñценарий
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Редактор на Ñценарии
+STR_0223_LAND_GENERATION :{WHITE}Генератор на терен
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Случаен терен
+STR_0227_RESET_LAND :{BLACK}ИзчиÑти терена
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Увеличи площа на терена, за да го понижиш/повишиш
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Ðамали площа на терена, за да го понижиш/повишиш
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Генерирай Ñлучаен терен
+STR_022B_RESET_LANDSCAPE :{BLACK}ИзчиÑти терена
+STR_022C_RESET_LANDSCAPE :{WHITE}ИзчиÑти терена
+STR_LOAD_GAME_HEIGHTMAP :{WHITE}Използване на виÑочинна карта
+STR_LOAD_SCEN_HEIGHTMAP :{BLACK}Използване на виÑочинна карта
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Желаете ли да изчиÑтите терена?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Създаване на терен
+STR_022F_TOWN_GENERATION :{BLACK}Създаване на град
+STR_0230_INDUSTRY_GENERATION :{BLACK}Създаване на индуÑтриÑ
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Строене на път
+STR_0233_TOWN_GENERATION :{WHITE}Създаване на град
+STR_0234_NEW_TOWN :{BLACK}Ðов град
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}ПоÑтрой нов град
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Ðе може да поÑтроиш град тук...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...прекалено близо до ÐºÑ€Ð°Ñ Ð½Ð° картата
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...прекалено близо до друг град
+STR_0239_SITE_UNSUITABLE :{WHITE}...неподходÑщо мÑÑто
+STR_023A_TOO_MANY_TOWNS :{WHITE}...прекалено много градове
+STR_CANNOT_GENERATE_TOWN :{WHITE}Ðе може да Ñе ÑтроÑÑ‚ градове
+STR_NO_SPACE_FOR_TOWN :{WHITE}...нÑма повече мÑÑто на картата
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Увеличи размера на града
+STR_023C_EXPAND :{BLACK}Увеличи
+STR_023D_RANDOM_TOWN :{BLACK}Случаен град
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}ПоÑтроÑване град на произволно мÑÑто
+STR_023F_INDUSTRY_GENERATION :{WHITE}Създаване на индуÑтриÑ
+STR_0240_COAL_MINE :{BLACK}Въглищна мина
+STR_0241_POWER_STATION :{BLACK}ЕлектроÑтанциÑ
+STR_0242_SAWMILL :{BLACK}ДъÑкорезница
+STR_0243_FOREST :{BLACK}Гора
+STR_0244_OIL_REFINERY :{BLACK}РафинериÑ
+STR_0245_OIL_RIG :{BLACK}Ðефтена платформа
+STR_0246_FACTORY :{BLACK}Завод
+STR_0247_STEEL_MILL :{BLACK}СтоманолеÑрна
+STR_0248_FARM :{BLACK}Ферма
+STR_0249_IRON_ORE_MINE :{BLACK}ЖелÑзна мина
+STR_024A_OIL_WELLS :{BLACK}Ðефтен кладенец
+STR_024B_BANK :{BLACK}Банка
+STR_024C_PAPER_MILL :{BLACK}Хартиена фабрика
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Хранителна фабрика
+STR_024E_PRINTING_WORKS :{BLACK}Печатница
+STR_024F_GOLD_MINE :{BLACK}Златна мина
+STR_0250_LUMBER_MILL :{BLACK}ДъÑкорезница
+STR_0251_FRUIT_PLANTATION :{BLACK}Офошна градина
+STR_0252_RUBBER_PLANTATION :{BLACK}Каучукова плантациÑ
+STR_0253_WATER_SUPPLY :{BLACK}Водоизточник
+STR_0254_WATER_TOWER :{BLACK}Водна кула
+STR_0255_DIAMOND_MINE :{BLACK}Диамантена мина
+STR_0256_COPPER_ORE_MINE :{BLACK}Медна мина
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Гора от захарен памук
+STR_0258_CANDY_FACTORY :{BLACK}СладкарÑки цех
+STR_0259_BATTERY_FARM :{BLACK}Ферма за батерии
+STR_025A_COLA_WELLS :{BLACK}Кола кладенци
+STR_025B_TOY_SHOP :{BLACK}Магазин за играчки
+STR_025C_TOY_FACTORY :{BLACK}Фабрика за играчки
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}ПлаÑтмаÑови фонтани
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Завод за газирани напитки
+STR_025F_BUBBLE_GENERATOR :{BLACK}Генератор на балончета
+STR_0260_TOFFEE_QUARRY :{BLACK}Карамеломна
+STR_0261_SUGAR_MINE :{BLACK}Захарна мина
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Строене въглещна мина
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Строене електроÑтанциÑ
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Строене дъÑкорезница
+STR_0265_PLANT_FOREST :{BLACK}ПоÑадÑване гора
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Строене рафинериÑ
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Строене нефтена платформа (Ñамо в до краищата на картата)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Строене завод
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Строене ÑтоманолеÑрна
+STR_026A_CONSTRUCT_FARM :{BLACK}Строене ферма
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Строене желÑзна мина
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Строене нефтени кладенци
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Строене банка (Само в градове Ñ Ð½Ð°Ñеление повече от 1200)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Строене хартиена фабрика
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Строене хранителна фабрика
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Строене печатница
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Строене златна мина
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Строене банка (Ñамо в градове)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Строене дъÑкорезница (за изÑичане на гората и произвеждане на дърва)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}ЗаÑаждане овощна градина
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}ЗаÑаждане каучукова градина
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}СтроÑване водоизточник
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Строене водна кула(Ñамо в градове)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Строене диамантена мина
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Строене медна мина
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}ПоÑаждане гора от захарен памук
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Строене ÑладкарÑки цех
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Строене ферма за батерии
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Строене кола кладенци
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Строене магазин за играчки
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Строене завод за играчки
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Строене плаÑтмаÑови фонтани
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Строене завод за газирани напитки
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Строене генератор на балончета
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Строене карамеломна
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Строене захарна мина
+STR_0285_CAN_T_BUILD_HERE :{WHITE}Ðе може да поÑтрои {STRING} тук...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...Ñ‚Ñ€Ñбва град
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...Ñамо по един на град
+STR_0288_PLANT_TREES :{BLACK}ПоÑаждане дърва
+STR_0289_PLACE_SIGN :{BLACK}ПоÑтавÑне табела
+STR_028A_RANDOM_TREES :{BLACK}Произволни дървета
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}ЗаÑаждане дървета на произволни меÑта
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}ПоÑтавÑне ÑкалиÑти облаÑти
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}ПоÑтавÑне фар
+STR_028E_PLACE_TRANSMITTER :{BLACK}ПоÑтави предавател
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Избери пуÑтинен терен.{}Задръж CTRL за да го премахнеш.
+STR_CREATE_LAKE :{BLACK}ПоÑочване на водна зона.{}Ще наводни ÑÑŠÑедните ако Ñа на морÑкото ниво
+STR_0290_DELETE :{BLACK}Изтрий
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Премахни този град
+STR_0292_SAVE_SCENARIO :
+STR_0293_LOAD_SCENARIO :Зареждане на Ñценарий
+STR_0294_QUIT_EDITOR :Изход от редактора
+STR_0295 :
+STR_0296_QUIT :Изход
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Ð—Ð°Ð¿Ð¸Ñ Ð¸ зареждане на Ñценарий, затварÑне редактора, изход
+STR_0298_LOAD_SCENARIO :{WHITE}Зареждане на Ñценарии
+STR_0299_SAVE_SCENARIO :{WHITE}Ð—Ð°Ð¿Ð¸Ñ Ð½Ð° Ñценарии
+STR_029A_PLAY_SCENARIO :{BLACK}Играене на Ñценарий
+STR_PLAY_HEIGHTMAP :{BLACK}Игра виÑочинна карта
+STR_PLAY_HEIGHTMAP_HINT :{BLACK}Ðова игра, използвайки виÑочинна карта като терен
+STR_QUIT_SCENARIO_QUERY :{YELLOW}ÐаиÑтина ли желаете изход от ÑценариÑ?
+STR_029C_QUIT_EDITOR :{WHITE}ЗатварÑне на редактора
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...може да бъде поÑтроен Ñамо в градове Ñ Ð½Ð°Ñеление повече от 1200
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}ПремеÑти назад началната дата Ñ 1 година
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}ПремеÑти напред началната дата Ñ 1 година
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...краищата на моÑта Ñ‚Ñ€Ñбва да бъдат на земÑ
+STR_02A1_SMALL :{BLACK}Малък
+STR_02A2_MEDIUM :{BLACK}Среден
+STR_02A3_LARGE :{BLACK}ГолÑм
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Избери големина на града
+STR_02A5_TOWN_SIZE :{YELLOW}Големина на града:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Покажи поÑледното Ñъобщение или отчет на новините
+STR_OFF :Изключено
+STR_SUMMARY :Обобщение
+STR_FULL :Пълно
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :СпиÑък от градовете
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Имена на превозни ÑредÑтва
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :По подразбиране
+STR_02BF_CUSTOM :Изборен
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Ð—Ð°Ð¿Ð¸Ñ Ð½Ð° новоизбраните имена
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Избор на имена на превозни ÑредÑтва
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Ð—Ð°Ð¿Ð¸Ñ Ð½Ð° имена на превозни ÑредÑтва
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Игрови опции
+STR_02C5_DIFFICULTY_SETTINGS :Опции за трудноÑÑ‚
+STR_02C7_CONFIG_PATCHES :Конфигурирай патчове
+STR_NEWGRF_SETTINGS :Newgrf наÑтройки
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Показване имената на градовете
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Показване имената на Ñтанциите
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Показване на табелите
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Пътни точки Ñа показани
+STR_02D0_FULL_ANIMATION :{SETX 12}Пълна анимациÑ
+STR_02D2_FULL_DETAIL :{SETX 12}Пълни подробноÑти
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Прозрачни Ñгради
+STR_TRANSPARENT_SIGNS :{SETX 12}Прозрачни табели на Ñтанциите
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° терена
+STR_02D6 :
+STR_CONSOLE_SETTING :Показване/Ñкриване на конзола
+STR_02D7_SCREENSHOT_CTRL_S :Screenshot (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Огромен Screenshot (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :За 'OpenTTD'
+############ range ends here
+
+STR_02DB_OFF :{BLACK}Изключен
+STR_02DA_ON :{BLACK}Включен
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}
+STR_02DD_SUBSIDIES :
+STR_02DE_MAP_OF_WORLD :
+STR_EXTRA_VIEW_PORT :Допълнителна камера
+STR_SIGN_LIST :СпиÑък Ñ Ñ‚Ð°Ð±ÐµÐ»Ð¸
+STR_02DF_TOWN_DIRECTORY :
+STR_TOWN_POPULATION :{BLACK}Световна популациÑ: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Камера {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}ПремеÑтване на камерата
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}ПремеÑтване на тази камера до глобалната
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}ПремеÑтване глобалната камера
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}ПремеÑтване глобалната камера до тази
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Валутна единица
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Избиране на валутна единица
+STR_MEASURING_UNITS :{BLACK}Мерни единици
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Избор на мерни единици
+STR_02E6_ROAD_VEHICLES :{BLACK}Пътни превозни ÑредÑтва
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Избери поÑока на движение по пътищата
+STR_02E9_DRIVE_ON_LEFT :ЛÑво движение
+STR_02EA_DRIVE_ON_RIGHT :ДÑÑно движение
+STR_02EB_TOWN_NAMES :{BLACK}Имена на градовете
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Избери Ñтила на имената на градовете
+
+STR_02F4_AUTOSAVE :{BLACK}Ðвтозапазване
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Избери интервала между две автозапазваниÑ
+STR_02F7_OFF :Изключено
+STR_02F8_EVERY_3_MONTHS :Ðа вÑеки 3 меÑеца
+STR_02F9_EVERY_6_MONTHS :Ðа вÑеки 6 меÑеца
+STR_02FA_EVERY_12_MONTHS :Ðа вÑеки 12 меÑеца
+STR_02FB_START_A_NEW_GAME :{BLACK}Започни нова игра
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Отвори запаÑена игра
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Създай Ñвой ÑобÑтвен карта-ÑвÑÑ‚
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Избери игра ÑÑŠÑ Ñебе Ñи
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Избери игра в интернета Ñ Ð¾Ñ‰Ðµ 1-7 други играча
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Покажи параметрите на играта
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Покажи параметрите на трудноÑÑ‚
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Започни нова игра, използвайки предварително моделиран карта-ÑвÑÑ‚
+STR_0304_QUIT :{BLACK}Излез
+STR_0305_QUIT_OPENTTD :{BLACK}Излез от играта 'OpenTTD'
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...може да Ñе поÑтрои Ñамо в градовете
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Избери "умерен" климат на картата
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Избери "зимен" климат на картата
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Избери "пуÑтинен" климат на картата
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Избери "играчков" тип на картата
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}ИнвеÑтирай в нова индуÑтриÑ
+
+############ range for menu starts
+STR_INDUSTRY_DIR :СпиÑък на индуÑтриите
+STR_0313_FUND_NEW_INDUSTRY :ИнвеÑтирай в нова индуÑтриÑ
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}ИнвеÑтирай в нова индуÑтриÑ
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...може да бъде поÑтроено Ñамо в градовете
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...може да бъде поÑтроено Ñамо около и в джунглите
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...може да бъде поÑтроено Ñамо около и в пуÑтините
+STR_0319_PAUSED :{YELLOW}* * ИГРÐТРЕ Ð’ ПÐУЗР* *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}ЕкраноÑнимката е уÑпешно зъхранена Ñ Ð¸Ð¼ÐµÑ‚Ð¾ '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}ЕкраноÑнимката не Ñе получи!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Купи Ð·ÐµÐ¼Ñ Ð·Ð° бъдещо ползване
+STR_032F_AUTOSAVE :{RED}ÐВТОЗÐПÐЗВÐÐЕ
+STR_SAVING_GAME :{RED}* * ЗÐПИСВÐÐЕ ÐРИГРР* *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}ЗапиÑването продължава,{}Ð¼Ð¾Ð»Ñ Ð¸Ð·Ñ‡Ð°ÐºÐ°Ð¹Ñ‚Ðµ да Ñръши!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Избери програмата 'Ezy Street style music'
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :ÐнглийÑки
+STR_TOWNNAME_FRENCH :ФренÑки
+STR_TOWNNAME_GERMAN :ГерманÑки
+STR_TOWNNAME_ADDITIONAL_ENGLISH :ÐнглийÑки (допълнителни)
+STR_TOWNNAME_LATIN_AMERICAN :ЛатиноамериканÑки
+STR_TOWNNAME_SILLY :Глупави
+STR_TOWNNAME_SWEDISH :ШведÑки
+STR_TOWNNAME_DUTCH :ХоландÑки
+STR_TOWNNAME_FINNISH :ФинландÑки
+STR_TOWNNAME_POLISH :ПолÑки
+STR_TOWNNAME_SLOVAKISH :Словашки
+STR_TOWNNAME_NORWEGIAN :Ðорвежки
+STR_TOWNNAME_HUNGARIAN :УнгарÑки
+STR_TOWNNAME_AUSTRIAN :ÐвÑтрийÑки
+STR_TOWNNAME_ROMANIAN :РумънÑки
+STR_TOWNNAME_CZECH :Чешки
+STR_TOWNNAME_SWISS :ШвейцарÑки
+STR_TOWNNAME_DANISH :ДатÑки
+STR_TOWNNAME_TURKISH :ТурÑки
+STR_TOWNNAME_ITALIAN :ИталианÑки
+STR_TOWNNAME_CATALAN :КаталонÑки
+############ end of townname region
+
+STR_CURR_GBP :Паунд (£)
+STR_CURR_USD :Долар ($)
+STR_CURR_EUR :Евро (€)
+STR_CURR_YEN :Йена (¥)
+STR_CURR_ATS :ÐвÑтрийÑки шилинг (ATS)
+STR_CURR_BEF :БелгийÑки франк (BEF)
+STR_CURR_CHF :ШвейцарÑки франк (CHF)
+STR_CURR_CZK :Чешка крона (CZK)
+STR_CURR_DEM :ÐемÑка марка (DEM)
+STR_CURR_DKK :ДанÑка крона (DKK)
+STR_CURR_ESP :ПеÑета (ESP)
+STR_CURR_FIM :ФинландÑка марка
+STR_CURR_FRF :Франк (FRF)
+STR_CURR_GRD :Гръцка драхма (GRD)
+STR_CURR_HUF :УнгарÑки форинт (HUF)
+STR_CURR_ISK :ИÑландÑка крона (ISK)
+STR_CURR_ITL :ИталианÑка лира (ITL)
+STR_CURR_NLG :ÐемÑки гилдер (NLG)
+STR_CURR_NOK :Ðорвежка крона (NOK)
+STR_CURR_PLN :ПолÑка злота (PLN)
+STR_CURR_ROL :РомънÑка Ð»ÐµÑ (ROL)
+STR_CURR_RUR :РуÑка рубла (RUR)
+STR_CURR_SIT :СловенÑки толар (SIT)
+STR_CURR_SEK :ШведÑка крона (SEK)
+STR_CURR_YTL :ТурÑка лира (YTL)
+STR_CURR_SKK :Словашка коруна (SKK)
+STR_CURR_BRR :БразилÑки реал (BRL)
+
+STR_CURR_CUSTOM :Поръчкова...
+
+STR_OPTIONS_LANG :{BLACK}Език
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Избор на език
+
+STR_OPTIONS_FULLSCREEN :{BLACK}ЦÑл екран
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}Изберете тази Ð¾Ð¿Ñ†Ð¸Ñ Ð·Ð° да играете OpenTTD в цÑл екран
+
+STR_OPTIONS_RES :{BLACK}Размер на екрана
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Избор размера на екран
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Формат на екранните Ñнимки
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Избор на формата на екранните Ñнимки
+
+STR_AUTOSAVE_1_MONTH :Ð’Ñеки меÑец
+STR_AUTOSAVE_FAILED :{WHITE}Ðвтозапазването е неуÑпешно
+
+STR_MONTH_JAN :Януари
+STR_MONTH_FEB :Февруари
+STR_MONTH_MAR :Март
+STR_MONTH_APR :Ðприл
+STR_MONTH_MAY :Май
+STR_MONTH_JUN :Юни
+STR_MONTH_JUL :Юли
+STR_MONTH_AUG :ÐвгуÑÑ‚
+STR_MONTH_SEP :Септември
+STR_MONTH_OCT :Октомври
+STR_MONTH_NOV :Ðоември
+STR_MONTH_DEC :Декември
+
+STR_HEADING_FOR_STATION :{LTBLUE}Отиващ към {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}Отиващ към {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Без заповеди
+STR_NO_ORDERS_VEL :{LTBLUE}Без заповеди, {VELOCITY}
+
+STR_PASSENGERS :паÑажери
+STR_BAGS :торби
+STR_TONS :тона
+STR_LITERS :литри
+STR_ITEMS :елемента
+STR_CRATES :кратери
+STR_RES_OTHER :друго
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Ðе може да Ñе ÑÐ¿Ð¾Ð´ÐµÐ»Ñ ÑпиÑъка ÑÑŠÑ Ð·Ð°Ð´Ð°Ñ‡Ð¸...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Ðе може да Ñе копира ÑпиÑъка от задачи...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - Край на Ð¡Ð¿Ð¾Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¿ÑŠÑ‚ÐµÐ½ лиÑÑ‚ - -
+
+STR_TRAIN_IS_LOST :{WHITE}Влак {COMMA} е загубен.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}Печалбата на влак {COMMA} предходната година е {CURRENCY}
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}ЕвропейÑки монетарен Ñъюз!{}{}Еврото е прието като национална валута за вÑекидневни транзакции Ñтраната!
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Влак {COMMA} има прекалено малко заповеди в Ð¿ÑŠÑ‚Ð½Ð¸Ñ Ð»Ð¸ÑÑ‚
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}Влак {COMMA} има празен пътен лиÑÑ‚
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}Влак {COMMA} има дублирани заповеди
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}Влак {COMMA} има невалидна ÑÑ‚Ð°Ð½Ñ†Ð¸Ñ Ð² Ð¿ÑŠÑ‚Ð½Ð¸Ñ Ð»Ð¸ÑÑ‚
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}Ðвтомобил {COMMA} има прекалено малко заповеди в Ð¿ÑŠÑ‚Ð½Ð¸Ñ Ð»Ð¸ÑÑ‚
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}Ðвтомобил {COMMA} има празен пътен лиÑÑ‚
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}Ðвтомобил {COMMA} има дублирани заповеди
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}Ðвтомобил {COMMA} има невалидна ÑÑ‚Ð°Ð½Ñ†Ð¸Ñ Ð² Ð¿ÑŠÑ‚Ð½Ð¸Ñ Ð»Ð¸ÑÑ‚
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}Кораб {COMMA} има прекалено малко заповеди в Ð¿ÑŠÑ‚Ð½Ð¸Ñ Ð»Ð¸ÑÑ‚
+STR_SHIP_HAS_VOID_ORDER :{WHITE}Кораб {COMMA} има празен пътен лиÑÑ‚
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}Кораб {COMMA} има дублирани заповеди
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}Кораб {COMMA} има невалидна ÑÑ‚Ð°Ð½Ñ†Ð¸Ñ Ð² Ð¿ÑŠÑ‚Ð½Ð¸Ñ Ð»Ð¸ÑÑ‚
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}Самолет {COMMA} има прекалено малко заповеди в програмата Ñи
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}Самолет {COMMA} има празна заповед
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}Самолет {COMMA} има повтарÑщи Ñе заповеди
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}Самолет {COMMA} има невалидно летище в Ñвоите заповеди
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}Ðвтоматично подновÑване на влак {COMMA} не уÑÐ¿Ñ (ограничение на парите)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}Ðвтоматично подновÑване на автомобил {COMMA} не уÑÐ¿Ñ (ограничение на парите)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}Ðвтоматично подновÑване на кораб {COMMA} не уÑÐ¿Ñ (ограничение на парите)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}ÐвтообновÑването на Ñамолет е неуÑпешно {COMMA} (ограничени ÑредÑтва)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}Влак {COMMA} е прекалено дълъг Ñлед замÑната
+
+STR_CONFIG_PATCHES :{BLACK}ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð½Ð° кръпки
+STR_CONFIG_PATCHES_TIP :{BLACK}ÐаÑтройки на кръпките
+STR_CONFIG_PATCHES_CAPTION :{WHITE}ÐаÑтройка на кръпките
+
+STR_CONFIG_PATCHES_OFF :Изключено
+STR_CONFIG_PATCHES_ON :Включено
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Показване ÑкороÑтта на автомобилите в лента за ÑÑŠÑтоÑнието: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}ПозволÑване Ñтроенето на Ñклонове и брегове: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}По-реалиÑтична зона за обÑлужване: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Премахване на повече неща ÑобÑтвеноÑÑ‚ на град: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Строене на много дълги влакове: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}РеалиÑтично уÑкорÑване на влаковете: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Забрана на влакове и кораби да правÑÑ‚ 90 градуÑови завои: {ORANGE}{STRING} {LTBLUE} (Ñ‚Ñ€Ñбва NPF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}ОбединÑване на гари поÑтроени една до друга: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}ÐапуÑкане на ÑтанциÑта когато нÑкой товар е пълен, при 'пълно зареждане': {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Подобрен алгоритъм за зареждане: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}ИнфлациÑ: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}ДоÑтавÑне на Ñтока до ÑÑ‚Ð°Ð½Ñ†Ð¸Ñ Ñамо ако има Ñ‚ÑŠÑ€Ñене: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Строене на много дълги моÑтове: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Сервиз в маршрута: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}ПозволÑване израждане на промишленоÑÑ‚ добиваща Ñуровини: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}ÐÑколко еднакви индуÑтрии на град: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}ИндуÑтрии от еднакъв тип могат да бъдат Ñтроени близо една до друга: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Показване на дълга дата в ÑÑ‚Ð°Ñ‚ÑƒÑ Ð±Ð°Ñ€Ð°: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Показване на Ñемафорите ÑпрÑмо пътното движение: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Показване на финанÑÐ¾Ð²Ð¸Ñ Ð¿Ñ€Ð¾Ð·Ð¾Ñ€ÐµÑ† в ÐºÑ€Ð°Ñ Ð½Ð° годината: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}TTDPatch ÑъвмеÑтима обработка на "без Ñпиране": {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Опашка на колите (ÑÑŠÑ Ñумарен ефект): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}ПремеÑтване на прозореца когато мишката е в краÑ: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Подкупване на меÑтната влаÑÑ‚: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}ÐеÑтандартни Ñтанции: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Ðов глобален навигатор (NPF, Ð¾Ñ‚Ð¼ÐµÐ½Ñ NTP): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Малки летища Ñа винаги разрешени: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Предупреждение ако влак Ñе загуби {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Преглед на маршрута: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :не
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :да, но пропуÑни Ñпрените превозни ÑредÑтва
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :от вÑички превозни ÑредÑтва
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Предупреждение ако печалбата на влак е негативна: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Превозните ÑредÑтва никога не губÑÑ‚ валидноÑÑ‚: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Ðвтоматично подновÑване на превозно ÑредÑтво когато то оÑтарее
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Ðвтоматично подновÑване когато превозното ÑредÑтво е {ORANGE}{STRING}{LTBLUE} меÑеца преди/Ñлед макÑималната възраÑÑ‚
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Ðвтоматично възÑтановÑване на минималната Ñума пари необходима за започване отначало: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}ПродължителноÑÑ‚ на ÑъобщениÑта за грешки: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}ÐаÑелението на града в етикета Ñ Ð¸Ð¼ÐµÑ‚Ð¾ на града: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Ðевидими дървета (Ñ Ð½ÐµÐ²Ð¸Ð´Ð¸Ð¼Ð¸ Ñгради): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Генератор на земÑ: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :Оригинал
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :ТераГенезиÑ
+STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}МакÑимално разÑтоÑние на нефтените рафинерии от краищата на картата {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}ВиÑочина на Ñнежната ивица: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN :{LTBLUE}РъбавоÑÑ‚ на терен (Ñамо за TerraGenesis) : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Много гладък
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH :Гладен
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH :Ръбав
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :Много ръбав
+STR_CONFIG_PATCHES_TREE_PLACER :{LTBLUE}Ðлгоритъм за поÑтавÑне на дървета: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TREE_PLACER_NONE :Без
+STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL :Оригинален
+STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED :Подобрен
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION :{LTBLUE}Завъртане на картата: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Обратрно на чаÑовниковата Ñтрелка
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE :По чаÑовниковата Ñтрелка
+STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT :{LTBLUE}ВиÑочина на картата за плоÑък Ñценарий: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}МакÑ. разпръÑнатоÑÑ‚ на ÑтанциÑ: {ORANGE}{STRING} {RED}Внимание: ВиÑоките ÑтойноÑти забавÑÑ‚ играта
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Ðвтоматичен Ñервиз на хеликоптерите при кацане на хелипад: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Връзване на инÑтрументите за терен Ñ Ð¸Ð½Ñтрументите за жп/път/вода/летище: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Обърната поÑока на премеÑтване: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Показване на измервателна подÑказка при използване на инÑтрументите за Ñтроене: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Покажи цветовете на компаниÑта: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES_NONE :Ðито една
+STR_CONFIG_PATCHES_LIVERIES_OWN :ТвоÑта компаниÑ
+STR_CONFIG_PATCHES_LIVERIES_ALL :Ð’Ñички компании
+STR_CONFIG_PATCHES_PREFER_TEAMCHAT :{LTBLUE}Избери Ð¿Ñ€ÐµÐ´Ð¿Ð¾Ñ‡Ð¸Ñ‚Ð°Ð½Ð¸Ñ Ð¾Ñ‚Ð±Ð¾Ñ€ за чатене <ENTER>: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}МакÑ. влакове на играч: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}МакÑ. брой коли на играч: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}МакÑ. брой Ñамолети на играч: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}МакÑ. брой кораби на играч: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Премахване на влаковете за ÐºÐ¾Ð¼Ð¿ÑŽÑ‚ÑŠÑ€Ð½Ð¸Ñ Ð¸Ð³Ñ€Ð°Ñ‡: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Премахване на пътните превозни ÑредÑтва за ÐºÐ¾Ð¼Ð¿ÑŽÑ‚ÑŠÑ€Ð½Ð¸Ñ Ð¸Ð³Ñ€Ð°Ñ‡: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Премахване на летателните апарати за ÐºÐ¾Ð¼Ð¿ÑŽÑ‚ÑŠÑ€Ð½Ð¸Ñ Ð¸Ð³Ñ€Ð°Ñ‡: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Премахване на корабите за ÐºÐ¾Ð¼Ð¿ÑŽÑ‚ÑŠÑ€Ð½Ð¸Ñ Ð¸Ð³Ñ€Ð°Ñ‡: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Включване на нов ÐИ (алфа): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}ПозволÑване на компютърни играчи в мултиплейър (екÑпериментално): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Интервал на Ñервиз за влакове: {ORANGE}{STRING} дни/%
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Интервал на Ñервиз за влакове: {ORANGE}изключен
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Интервал на Ñервиз за автомобили: {ORANGE}{STRING} дни/%
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Интервал на Ñервиз за автомобили: {ORANGE}изключен
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Интервал на Ñервиз за Ñамолети: {ORANGE}{STRING} дни/%
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Интервал на Ñервиз за Ñамолети: {ORANGE}изключен
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Интервал на Ñервиз за кораби: {ORANGE}{STRING} дни/%
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Интервал на Ñервиз за кораби: {ORANGE}изключен
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Изключване на Ñервиза когато повредите Ñа изключени: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Вагоните имат ограничение на ÑкороÑтта: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}Без електричеÑки влакове: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Цветни нови Ñе поÑвÑват през: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Ðачална година: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}Край на играта през: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Плавна икономика (повече, по-малки промени)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}ПозволÑване покупката на акции от други компании
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}При влачене, поÑтавÑне на Ñемафори вÑеки: {ORANGE}{STRING} плочка(и)
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}ÐŸÐ¾Ð·Ð¸Ñ†Ð¸Ñ Ð½Ð° лента за инÑтрументи: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Лево
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Център
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :ДÑÑно
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Прилепване на прозорците: {ORANGE}{STRING} px
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Прилепване на прозорците: {ORANGE}изключено
+
+STR_CONFIG_PATCHES_GUI :{BLACK}ИнтерфейÑ
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Строене
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Ðвтомобили
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Станции
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Икономика
+STR_CONFIG_PATCHES_AI :{BLACK}Съперници
+
+STR_CONFIG_PATCHES_DISABLED :изключено
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}ПромÑна ÑтойноÑта на наÑтройка
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}ÐÑкои от ÑтойноÑтите за интервал(и) на Ñервиз Ñа неÑъвмеÑтими Ñ Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ‚Ðµ наÑтройки! 5-90% и 30-800 Ñа валидни ÑтойноÑти
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}YAPF за кораби: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}YAPF за автомобили: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}YAPF за влакове: {ORANGE}{STRING}
+
+STR_TEMPERATE_LANDSCAPE :Умерен климат
+STR_SUB_ARCTIC_LANDSCAPE :Ðрктичен климат
+STR_SUB_TROPICAL_LANDSCAPE :ТропичеÑки климат
+STR_TOYLAND_LANDSCAPE :ЗемÑта на играчките
+
+STR_CHEATS :{WHITE}Кодове
+STR_CHEATS_TIP :{BLACK}Кутийките показват дали този код е бил използван
+STR_CHEATS_WARNING :{BLACK}Внимание! По този начин ще измамите Ñвоите Ñъперници. Имайте в предвид, че това безчеÑтие ще бъде запомнено вовеки веков.
+STR_CHEAT_MONEY :{LTBLUE}Увеличаване на парите Ñ {CURRENCY64}
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Игра като: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}МагичеÑки булдозер (премахва промишленоÑÑ‚, неподвижни обекти): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Тунелите може да Ñе преÑичат: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Строене докато режима е Пауза: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Реактивните Ñамолети нÑма да Ñе разбиват (чеÑто) в малки летища: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}ПромÑна на климата: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}ПромÑна на датата: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}ПромÑна на производÑтвените ÑтойноÑти: {ORANGE}{STRING}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}Отиващ към {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Отиващ към {WAYPOINT}, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :Отиди чрез пътеводител {WAYPOINT}
+STR_GO_NON_STOP_TO_WAYPOINT :Премини без Ñпиране през {WAYPOINT}
+
+STR_WAYPOINTNAME_CITY :Пътна точка {TOWN}
+STR_WAYPOINTNAME_CITY_SERIAL :Пътна точка {TOWN} #{COMMA}
+STR_LANDINFO_WAYPOINT :Пътна точка
+
+STR_WAYPOINT :{WHITE}Пътна точка
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Избор тип на пътни точки
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}Ð ÐµÐ´Ð°ÐºÑ†Ð¸Ñ Ð¸Ð¼ÐµÑ‚Ð¾ на пътна точка
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Ðе може да Ñе Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ñ Ð¸Ð¼ÐµÑ‚Ð¾ на пункта...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}ПромÑна ЖП Ð»Ð¸Ð½Ð¸Ñ Ð½Ð° пункт
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Тук не може да Ñе Ñтрои влаков пункт...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Оттук не може да Ñе премахва Ð²Ð»Ð°ÐºÐ¾Ð²Ð¸Ñ Ð¿ÑƒÐ½ÐºÑ‚...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK} Строеж на жп Ð»Ð¸Ð½Ð¸Ñ Ð² режим Ðвтоматичен
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}...нÑма град в този Ñценарий
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}Потвърдете Ñъздаването на Ñлучаен терен?
+STR_MANY_RANDOM_TOWNS :{BLACK}Много Ñлучайни градове
+STR_RANDOM_TOWNS_TIP :{BLACK}Покриване на картата ÑÑŠÑ Ñлучайно поÑтавени градове
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Много Ñлучайни индуÑтрии
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Покриване на картата ÑÑŠÑ Ñлучайно поÑтавени индуÑтрии
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Ðе може да Ñе генерира промишленоÑÑ‚...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Отворете ивицата Ñ Ð¸Ð½Ñтрументи за тераформиране за да повишавате/понижавате земÑ, заÑаждате дърва, и др.
+STR_LANDSCAPING_TOOLBAR :{WHITE}Тераформиране
+STR_LEVEL_LAND_TOOLTIP :{BLACK}ПодравнÑване на земÑ
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Дървета от произволен тип
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}ПоÑтави дървета от произволен тип
+
+STR_CANT_BUILD_CANALS :{WHITE}Тук не може да Ñе ÑтроÑÑ‚ канали...
+STR_BUILD_CANALS_TIP :{BLACK}Строене на канали. ÐатиÑнете CTRL за да поÑтавите морÑка плочка (Ñамо на нивото на морето).
+STR_LANDINFO_CANAL :Канал
+
+STR_CANT_BUILD_LOCKS :{WHITE}Тук не може да Ñе ÑтроÑÑ‚ шлюзове...
+STR_BUILD_LOCKS_TIP :{BLACK}Строеж на шлюзове
+STR_LANDINFO_LOCK :Заключване
+
+STR_BUOY_IS_IN_USE :{WHITE}...шамандурата Ñе използва!
+
+STR_LANDINFO_COORDS :{BLACK}Координати: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Ðе може да Ñе премахва чаÑÑ‚ от гарата...
+STR_CANT_CONVERT_RAIL :{WHITE}Тук не може да Ñе Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ñ Ñ‚Ð¸Ð¿Ð° на жп линиÑта...
+STR_CONVERT_RAIL_TIP :{BLACK}ПромÑна/обновÑване на ЖП линиÑ
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}ПремеÑтване локомотива тук ще продаде Ñ†ÐµÐ»Ð¸Ñ Ð²Ð»Ð°Ðº
+
+STR_DRAG_DROP :{BLACK}Влачене & ПуÑкане
+STR_STATION_DRAG_DROP :{BLACK}Строене на ÑÑ‚Ð°Ð½Ñ†Ð¸Ñ Ñ‡Ñ€ÐµÐ· изтеглÑне
+STR_SELECT_STATION_CLASS_TIP :{BLACK}Избор на ÐºÐ»Ð°Ñ ÑÑ‚Ð°Ð½Ñ†Ð¸Ñ Ð·Ð° показване
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Избор тип на ÑÑ‚Ð°Ð½Ñ†Ð¸Ñ Ð·Ð° Ñтроене
+
+STR_FAST_FORWARD :{BLACK}Бързо превъртане на играта
+STR_MESSAGE_HISTORY :{WHITE}ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ð½Ð° ÑъобщениÑта
+STR_MESSAGE_HISTORY_TIP :{BLACK}СпиÑък Ñ Ð¿Ð¾Ñледните новини
+STR_MESSAGES_DISABLE_ALL :{BLACK}Изключване на вÑички
+STR_MESSAGES_ENABLE_ALL :{BLACK}Включване на вÑички
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Строене мина за въглища
+STR_CONSTRUCT_FOREST_TIP :{BLACK}ЗаÑаждане на гора
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Строене на нефтен кладенец
+STR_CONSTRUCT_FARM_TIP :{BLACK}Създаване на ферма
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Строене мина за мед
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Копаене за нефт
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Строене на мина за злато
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Строене мина за диаманти
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Строене на мина за желÑзо
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Създаване на плодова плантациÑ
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}ОÑноваване каукукова плантациÑ
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}ОÑноваване воден източник
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}ЗаÑаждане гора от захарен памук
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}ИнвеÑтиране във ферма за батерии
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Копаене за кола
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}ОÑноваване плаÑтмаÑови фонтани
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Строене генератор на балони
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}ОÑноваване карамеломна
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Строене захарна мина
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}ИндуÑтрии
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA}% превозено)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA}%/{COMMA}% превозено)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}...прекалено близо до друка индуÑтриÑ
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Преоборудване на влак да превозва друг товар
+STR_RAIL_REFIT_VEHICLE :{BLACK}Проборудване
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Избор тип на товар за влак
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Преоборудва влака да превозва Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ Ñ‚Ð¸Ð¿ товар
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Преоборудването на влака е невъзможно...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Интервал на Ñервиз е в проценти: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}ПромÑна на производÑтво
+
+TEMP_AI_IN_PROGRESS :{WHITE}Добре дошли в Ð½Ð¾Ð²Ð¸Ñ ÐИ, който е още в Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð½Ð° разработване. Ðко Ñрещнете проблеми, направете screenshot и го пуÑнете във форума.
+TEMP_AI_ACTIVATED :{WHITE}Внимание: този нов ÐИ е вÑе още alpha! ЗаÑега, Ñамо камионите и автобуÑите работÑÑ‚!
+TEMP_AI_MULTIPLAYER :{WHITE}Внимание: имплементациÑта е вÑе още екÑпериментална (използва Ñе Ð½Ð¾Ð²Ð¸Ñ ÐИ). ÐœÐ¾Ð»Ñ Ñъобщете за вÑÑкаквипроблеми на truelight@openttd.org.
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}ÐÑколко играча
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Име на играч:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}Чрез това име другите играчи ще ви идентифицират
+STR_NETWORK_CONNECTION :{BLACK}Връзка:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Избор между игра в интернет или локална мрежа (LAN)
+
+STR_NETWORK_START_SERVER :{BLACK}ПуÑкане на Ñървър
+STR_NETWORK_START_SERVER_TIP :{BLACK}ПуÑнете ваш ÑобÑтвен Ñървър
+
+STR_NETWORK_GAME_NAME :{BLACK}Име
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Име на играта
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Език, верÑÐ¸Ñ Ð½Ð° Ñървъра, и др.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Щракни върху игра от ÑпиÑъка, за да Ñ Ð¸Ð·Ð±ÐµÑ€ÐµÑˆ
+
+STR_NETWORK_FIND_SERVER :{BLACK}ТърÑене на Ñървър
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}ПретърÑване на мрежата за Ñървър
+STR_NETWORK_ADD_SERVER :{BLACK}Добави Ñървър
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}ДобÑви Ñървър към ÑпиÑакът, който винаги ще бъде проверÑван за активни игри.
+STR_NETWORK_ENTER_IP :{BLACK}Въведете адреÑа на хоÑта
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Играчи
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Онлайн играчи / макÑ. брой играчи{}Онлайн компании / макÑ. компании
+STR_NETWORK_GAME_INFO :{SILVER}ИÐФО ЗРИГРÐТÐ
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Играчи: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Език: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Терен: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Големина на картата: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}ВерÑÐ¸Ñ Ð½Ð° Ñървъра: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}ÐÐ´Ñ€ÐµÑ Ð½Ð° Ñървъра: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Ðачална дата: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Текуща дата: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Защитено Ñ Ð¿Ð°Ñ€Ð¾Ð»Ð°!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}ИЗКЛЮЧЕРСЪРВЪР
+STR_NETWORK_SERVER_FULL :{SILVER}ПЪЛЕРСЪРВЪР
+STR_NETWORK_VERSION_MISMATCH :{SILVER}ГРЕШÐРВЕРСИЯ
+
+STR_NETWORK_JOIN_GAME :{BLACK}ПриÑъединÑване към игра
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}Започване на нова игра
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Име на игра:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}Името на играта ще Ñе вижда от другите играчи при избор на игра
+STR_NETWORK_SET_PASSWORD :{BLACK}ПоÑтавÑне на парола
+STR_NETWORK_PASSWORD_TIP :{BLACK}Защитаване на вашата игра Ñ Ð¿Ð°Ñ€Ð¾Ð»Ð° за да не е публично доÑтъпна
+STR_NETWORK_SELECT_MAP :{BLACK}Избор на карта:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}ÐšÐ¾Ñ ÐºÐ°Ñ€Ñ‚Ð° желаете да играете?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}МакÑ. клиенти:
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Избор на макÑÐ¸Ð¼Ð°Ð»Ð½Ð¸Ñ Ð±Ñ€Ð¾Ð¹ клиенти. Ðе вÑички Ñлотове Ñ‚Ñ€Ñбва да Ñе попълнÑÑ‚
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :LAN
+STR_NETWORK_INTERNET :Интернет
+STR_NETWORK_LAN_INTERNET :LAN / Интернет
+STR_NETWORK_INTERNET_ADVERTISE :Интернет (реклама)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 играча
+STR_NETWORK_1_PLAYERS :1 играч
+STR_NETWORK_2_PLAYERS :2 играча
+STR_NETWORK_3_PLAYERS :3 играча
+STR_NETWORK_4_PLAYERS :4 играча
+STR_NETWORK_5_PLAYERS :5 играча
+STR_NETWORK_6_PLAYERS :6 играча
+STR_NETWORK_7_PLAYERS :7 играча
+STR_NETWORK_8_PLAYERS :8 играча
+STR_NETWORK_9_PLAYERS :9 играча
+STR_NETWORK_10_PLAYERS :10 играча
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}МакÑ. компании:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Ограничаване на играта до определен брой компании
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}МакÑ. наблюдатели:
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Ограничаване на Ñървъра до определен брой наблюдатели
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Говорим език:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Другите играчи ще знаÑÑ‚ езика на който Ñе говори на Ñървъра
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}Ðачало на игра
+STR_NETWORK_START_GAME_TIP :{BLACK}Започване на нова мрежова игра от Ñлучайна карта или Ñценарий
+STR_NETWORK_LOAD_GAME :{BLACK}Зареждане на игра
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Продължаване на предварително запиÑана мрежова игра (проверете дали Ñе Ñвързвате като Ð¿Ñ€Ð°Ð²Ð¸Ð»Ð½Ð¸Ñ Ð¸Ð³Ñ€Ð°Ñ‡)
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Ð’Ñеки
+STR_NETWORK_LANG_ENGLISH :ÐнглийÑки
+STR_NETWORK_LANG_GERMAN :ÐемÑки
+STR_NETWORK_LANG_FRENCH :ФренÑки
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Преддверие
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Подготовка за приÑъединÑване: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}СпиÑък Ñ Ð²Ñички компании в играта. Можете да Ñе приÑъедините към нÑÐºÐ¾Ñ Ð¸Ð»Ð¸ да започнете нова ако има Ñвободно мÑÑто
+STR_NETWORK_NEW_COMPANY :{BLACK}Ðова компаниÑ
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Създаване на нова компаниÑ
+STR_NETWORK_SPECTATE_GAME :{BLACK}Ðаблюдаване на играта
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Ðаблюдаване на играта като наблюдател
+STR_NETWORK_JOIN_COMPANY :{BLACK}ПриÑъединÑване към компаниÑ
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Помощ за управлението на компаниÑта
+STR_NETWORK_REFRESH :{BLACK}ОбновÑване Ñървъра
+STR_NETWORK_REFRESH_TIP :{BLACK}ОбновÑва информациÑта за Ñъръра
+
+STR_NETWORK_COMPANY_INFO :{SILVER}ИÐФОРМÐЦИЯ ЗРКОМПÐÐИЯ
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Име на компаниÑ: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}ОÑноваване: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}СтойноÑÑ‚ на компаниÑта: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Текущ баланÑ: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Приход от предходната година: {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}ПредÑтавÑне: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}Превозни ÑредÑтва: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Станции: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Играчи: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}Свързване...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) Свързване..
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Оторизиране..
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Изчакване..
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) СвалÑне на карта..
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Обработка на данни..
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) РегиÑтриране..
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}СвалÑне инфо за играта..
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}СвалÑне инфо за компаниÑта..
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} клиент{P "" и} Ñрещу ваÑ
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} кбайта Ñвалено до момента
+
+STR_NETWORK_DISCONNECT :{BLACK}Изключване
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Въведете Ñумата пари коÑто желаете да дадете
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Сървъра е защитен. Въведете парола
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}КомпаниÑта е защитена. Въведете парола
+STR_NETWORK_CLIENT_LIST :{WHITE}СпиÑък Ñ Ð¸Ð³Ñ€Ð°Ñ‡Ð¸Ñ‚Ðµ
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE} Ðе Ñа открити мрежови уÑтройÑтва или е компилирано без ENABLE_NETWORK
+STR_NETWORK_ERR_NOSERVER :{WHITE} Ðе може да Ð¾Ñ‚ÐºÑ€Ð¸Ñ Ð¼Ñ€ÐµÐ¶Ð¾Ð²Ð¸ игри
+STR_NETWORK_ERR_NOCONNECTION :{WHITE} Сървърът не отговори на заÑвката
+STR_NETWORK_ERR_DESYNC :{WHITE} Network-Game synchronisation failed
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} Network-Game connection lost
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} Ðе може да зареди играта
+STR_NETWORK_ERR_SERVER_START :{WHITE} Сървъра не може да бъде Ñтартиран
+STR_NETWORK_ERR_CLIENT_START :{WHITE} Ðе може да Ñе Ñвърже
+STR_NETWORK_ERR_TIMEOUT :{WHITE} Връзка #{NUM} изтече времето
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE} Грешка в протокола Ñе Ñлучи и връзката бе прекъÑната
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE} РевизиÑта на клиента не Ð¾Ñ‚Ð³Ð¾Ð²Ð°Ñ€Ñ Ð½Ð° Ñървъра
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} Грешна парола
+STR_NETWORK_ERR_SERVER_FULL :{WHITE} Сървъра е пълен
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} Забранено ви е влизането на този Ñървър
+STR_NETWORK_ERR_KICKED :{WHITE} БÑхте изхвърлен от играта
+STR_NETWORK_ERR_CHEATER :{WHITE} Маменето не е разрешено на този Ñървър
+
+STR_NETWORK_ERR_LEFT :напуÑна играта
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :обща грешка
+STR_NETWORK_ERR_CLIENT_DESYNC :загуба на ÑинхронизациÑ
+STR_NETWORK_ERR_CLIENT_SAVEGAME :не може да зареди картата
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :връзката прекъÑна
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :грешка в протокола
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :не оторизиран
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :получен Ñтранен пакет
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :грешна ревизиÑ
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :името вече Ñе използва
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :грешна парола
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :грешен играч № в DoCommand
+STR_NETWORK_ERR_CLIENT_KICKED :изхрърлен от Ñървъра
+STR_NETWORK_ERR_CLIENT_CHEATER :Ñе опита да използва измама
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :Ñървърът е пълен
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :Ñе приÑъедини към играта
+STR_NETWORK_GIVE_MONEY :даде пари на вашата ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ñ ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :дадохте на {STRING} пари ({CURRENCY})
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Team] :
+STR_NETWORK_CHAT_COMPANY :[Team] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Team] До {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[Private] :
+STR_NETWORK_CHAT_CLIENT :[Private] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[Private] До {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[All] :
+STR_NETWORK_CHAT_ALL :[All] {STRING}: {GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :Ñмени името Ñи на
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE} Сървъра прекъÑна ÑеÑиÑта
+STR_NETWORK_SERVER_REBOOT :{WHITE} Сървъра Ñе реÑтартира...{}ÐœÐ¾Ð»Ñ Ð¸Ð·Ñ‡Ð°ÐºÐ°Ð¹Ñ‚Ðµ...
+
+STR_NETWORK_SERVER :Сървър
+STR_NETWORK_CLIENT :Клиент
+STR_NETWORK_SPECTATORS :Ðаблюдатели
+
+STR_NETWORK_CLIENTLIST_NONE :(никой)
+STR_NETWORK_CLIENTLIST_KICK :Изгони
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Дай пари
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Кажи на вÑички
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Кажи на компаниÑ
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Лично Ñъобщение
+
+
+STR_NETWORK_SEND :{BLACK}Изпращане
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}X-размер на карта: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Y-размер на карта: {ORANGE}{STRING}
+
+
+##### PNG-MAP-Loader
+
+STR_PNGMAP_ERROR :{WHITE}Ðе може да зареди терена от PNG...
+STR_PNGMAP_ERR_FILE_NOT_FOUND :{WHITE}...файла не е намерен.
+STR_PNGMAP_ERR_IMAGE_TYPE :{WHITE}...преобразуване типа на картинката е невъзможно. ТрÑбва 8 или 24-битова PNG картинка.
+STR_PNGMAP_ERR_MISC :{WHITE}...нещо лошо Ñлочи. ИзвинениÑ. (вероÑтно повреден файл)
+
+STR_BMPMAP_ERROR :{WHITE}Ðе може да отвориш пейзаж от BMP..
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}...не може да Ñе промени бида на Ñнимката.
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Цена: {CURRENCY}
+STR_0801_COST :{RED}Цена: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Приход: {CURRENCY}
+STR_0803_INCOME :{GREEN}Приход: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Превод: {CURRENCY}
+STR_FEEDER :{YELLOW}Превод: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Приблизителна цена: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Приблизителен приход: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Ðе може да повдигаш земÑта тук...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Ðе може да понижиш земÑта тук...
+STR_080A_ROCKS :Скали
+STR_080B_ROUGH_LAND :Ðеравна земÑ
+STR_080C_BARE_LAND :ПуÑта земÑ
+STR_080D_GRASS :Трева
+STR_080E_FIELDS :ПолÑ
+STR_080F_SNOW_COVERED_LAND :ЗаÑнежена земÑ
+STR_0810_DESERT :ПуÑтинÑ
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}ЗемÑта е наклонена в неправилна поÑока
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Ðевъзможна ÐºÐ¾Ð¼Ð±Ð¸Ð½Ð°Ñ†Ð¸Ñ Ð½Ð° пътÑ
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}Изкопните работи ще повредÑÑ‚ тунела
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}МорÑкото ниво е вече доÑтигнато
+STR_1004_TOO_HIGH :{WHITE}Прекалено виÑоко
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}ÐеподходÑщ за употреба релÑов път
+STR_1007_ALREADY_BUILT :{WHITE}...вече е поÑтроено
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Първо Ñ‚Ñ€Ñбва да премахнеш релÑÐ¾Ð²Ð¸Ñ Ð¿ÑŠÑ‚
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}КонÑтрукции за ДвурелÑов път
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Строене на електрифицирана ЖП мрежа
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}КонÑтрукции за ЕднорелÑов път
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}КонÑтрукции за МагниторелÑов път
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Избери ЖП моÑÑ‚
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Ðе може да поÑтроиш влаково депо тук...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Ðе може да поÑтроиш ЖП гара тук...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Ðе може да Ñложиш ÑÐ¸Ð³Ð½Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ñ‚ÑƒÐº...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Ðе може да поÑтроиш ЖП релÑи тук...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Ðе може да премахнеш тези ЖП релÑи...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Ðе може да премахнеш тази ÑигнализациÑ...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}ПоÑока на входа на влаковото депо
+STR_1015_RAILROAD_CONSTRUCTION :КонÑтруиране на ДвурелÑов път
+STR_TOOLB_ELRAIL_CONSTRUCTION :Строене на електрифицирана ЖП мрежа
+STR_1016_MONORAIL_CONSTRUCTION :КонÑтруиране на ЕднорелÑов път
+STR_1017_MAGLEV_CONSTRUCTION :КонÑтруиране на МагниторелÑов път
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}ПоÑтрой релÑÐ¾Ð²Ð¸Ñ Ð¿ÑŠÑ‚
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}ПоÑтрой влаково депо (за купуване и обÑлужване на влакове)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}ПоÑтрой ЖП гара
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}ПоÑтрой ЖП ÑигнализациÑ
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}ПоÑтрой ЖП моÑÑ‚
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Строене на жп тунел
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Строене/премахване на жп Ð»Ð¸Ð½Ð¸Ñ Ð¸ Ñемафори
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Избиране на моÑÑ‚ - натиÑни върху Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ Ð¾Ñ‚ теб моÑÑ‚, за да Ñе поÑтрои
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Избиране Ð¾Ñ€Ð¸ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ Ð½Ð° ЖП депо
+STR_1021_RAILROAD_TRACK :ЖП линиÑ
+STR_1023_RAILROAD_TRAIN_DEPOT :ЖП депо
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...земÑта е притежание на друга компаниÑ
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :ЖП Ð»Ð¸Ð½Ð¸Ñ Ñ Ð½Ð¾Ñ€Ð¼Ð°Ð»Ð½Ð¸ Ñигнали
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :ЖП Ð»Ð¸Ð½Ð¸Ñ Ñ Ð¿Ñ€Ðµ-Ñигнали
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :ЖП Ð»Ð¸Ð½Ð¸Ñ Ñ Ð¸Ð·Ñ…Ð¾Ð´Ð½Ð¸ Ñигнали
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :ЖП Ð»Ð¸Ð½Ð¸Ñ Ñ ÐºÐ¾Ð¼Ð±Ð¸Ð½Ð¸Ñ€Ð°Ð½Ð¸ Ñигнали
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Първо махнете пътÑ
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Пътни ремонти в процеÑ
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Пътно ÑтроителÑтво
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Избор на аÑфалтов моÑÑ‚
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}ÐŸÑŠÑ‚Ñ Ð½Ðµ може да Ñе поÑтрои...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}ÐŸÑŠÑ‚Ñ Ð½Ðµ може да Ñе махне...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}ÐžÑ€Ð¸ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ Ð½Ð° гараж
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Гаража не може да Ñе поÑтрои...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Ðвтогарата не може да Ñе поÑтрои...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Товарната гара не може да Ñе поÑтрои...
+STR_180A_ROAD_CONSTRUCTION :Пътно ÑтроителÑтво
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Строене на път
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Строене на гараж (за Ñтроене и Ñервиз на МПС-та)
+STR_180D_BUILD_BUS_STATION :{BLACK}Строене на автогара
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Строене на товарна гара
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}ПоÑтрой моÑÑ‚
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}ПоÑтрой тунел
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Премахване на аÑфалтов път
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}ÐžÑ€Ð¸ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ Ð½Ð° гараж
+STR_1814_ROAD :път
+STR_1815_ROAD_WITH_STREETLIGHTS :ÐÑфалтов път Ñ ÑƒÐ»Ð¸Ñ‡Ð½Ð¸ лампи
+STR_1816_TREE_LINED_ROAD :ÐÑфалтов път Ñ Ð´ÑŠÑ€Ð²ÐµÑ‚Ð°
+STR_1817_ROAD_VEHICLE_DEPOT :Ðвто депо
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :ЖП прелез
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Градове
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Сградата първо Ñ‚Ñ€Ñбва да бъде разрушена
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}ÐаÑеление: {ORANGE}{COMMA}{BLACK} Жилища: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Преименуване на град
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Градът не може да бъде преименуван
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} меÑтните влаÑти отказват да позволÑÑ‚ това
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Имена на градовете - натиÑни на името за да центрираш този град
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Центриране на Ð³Ð»Ð°Ð²Ð½Ð¸Ñ Ð¸Ð·Ð³Ð»ÐµÐ´ ÑпрÑмо разположението на града
+STR_200C_CHANGE_TOWN_NAME :{BLACK}ПромÑна на име на град
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Пътници през поÑÐ»ÐµÐ´Ð½Ð¸Ñ Ð¼ÐµÑец: {ORANGE}{COMMA}{BLACK} макÑимум: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Поща през поÑÐ»ÐµÐ´Ð½Ð¸Ñ Ð¼ÐµÑец: {ORANGE}{COMMA}{BLACK} макÑимум: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :ВиÑока Ð¾Ñ„Ð¸Ñ Ñграда
+STR_2010_OFFICE_BLOCK :ÐžÑ„Ð¸Ñ Ñграда
+STR_2011_SMALL_BLOCK_OF_FLATS :Малък жилищен блок
+STR_2012_CHURCH :Църква
+STR_2013_LARGE_OFFICE_BLOCK :ГолÑма Ð¾Ñ„Ð¸Ñ Ñграда
+STR_2014_TOWN_HOUSES :ГрадÑки къщи
+STR_2015_HOTEL :Хотел
+STR_2016_STATUE :СтатуÑ
+STR_2017_FOUNTAIN :Фонтан
+STR_2018_PARK :Парк
+STR_2019_OFFICE_BLOCK :ÐžÑ„Ð¸Ñ Ñграда
+STR_201A_SHOPS_AND_OFFICES :Магазини и офиÑи
+STR_201B_MODERN_OFFICE_BUILDING :Модерна Ð¾Ñ„Ð¸Ñ Ñграда
+STR_201C_WAREHOUSE :Склад
+STR_201D_OFFICE_BLOCK :ÐžÑ„Ð¸Ñ Ñграда
+STR_201E_STADIUM :Стадион
+STR_201F_OLD_HOUSES :Стари къщи
+STR_2020_LOCAL_AUTHORITY :{BLACK}МеÑтни влаÑти
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Показване на Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° меÑтните влаÑти
+STR_2022_LOCAL_AUTHORITY :{WHITE}{TOWN} меÑтни влаÑти
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Рейтинги на транÑпортни компании:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}СубÑидии
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}СубÑидии за превоз на:
+STR_2027_FROM_TO :{ORANGE}{STRING} от {STRING} до {STRING}
+STR_2028_BY :{YELLOW} (от{DATE_SHORT})
+STR_202A_NONE :{ORANGE}Ðиколко
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}СубÑидирани превози на:
+STR_202C_FROM_TO :{ORANGE}{STRING} от {STATION} до {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, до {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}Предложението за ÑубÑÐ¸Ð´Ð¸Ñ Ð¸Ð·Ñ‚ÐµÑ‡Ðµ:{}{}Превоз на {STRING} от {STRING} до {STRING} нÑма да Ñпечели ÑубÑидиÑ.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Изтеглена ÑубÑидиÑ:{}{}Превоз на {STRING} от {STATION} до {STATION} вече не Ñе ÑубÑидира.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Предложена ÑубÑидиÑ:{}{}ПървиÑÑ‚ превоз на {STRING} от {STRING} до {STRING} ще Ñпечели едногодишна ÑубÑÐ¸Ð´Ð¸Ñ Ð¾Ñ‚ меÑтните влаÑти!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}{COMPANY} Ñпечели ÑубÑидиÑ!{}{}Превоз на {STRING} от {STATION} до {STATION} ще Ñе заплаща Ñ 50% повече през Ñледващата година!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}{COMPANY} Ñпечели ÑубÑидиÑ!!{}{}Превоз на {STRING} от {STATION} до {STATION} ще Ñе заплаща двойно през Ñледващата година!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}{COMPANY} Ñпечели ÑубÑидиÑ!!{}{}Превоз на {STRING} от {STATION} до {STATION} ще Ñе заплаща тройно през Ñледващата година!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}{COMPANY} Ñпечели ÑубÑидиÑ!!{}{}Превоз на {STRING} от {STATION} до {STATION} ще Ñе заплаща четворно през Ñледващата година!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} меÑтни влаÑти отказват да позволÑÑ‚ поÑтроÑването на друго летище в града
+STR_2036_COTTAGES :СелÑки къщи
+STR_2037_HOUSES :Къщи
+STR_2038_FLATS :Ðпартаменти
+STR_2039_TALL_OFFICE_BLOCK :ВиÑока Ð¾Ñ„Ð¸Ñ Ñграда
+STR_203A_SHOPS_AND_OFFICES :Магазини и офиÑи
+STR_203B_SHOPS_AND_OFFICES :Магазини и офиÑи
+STR_203C_THEATER :Театър
+STR_203D_STADIUM :Стадион
+STR_203E_OFFICES :ОфиÑи
+STR_203F_HOUSES :Къщи
+STR_2040_CINEMA :Кино
+STR_2041_SHOPPING_MALL :ТърговÑки център
+STR_2042_DO_IT :{BLACK}Ðаправи го
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}СпиÑък от нещата за правене в този град - натиÑни за подробноÑти
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Изпълнение на отбелÑзаната дейноÑÑ‚ в ÑпиÑъка по-горе
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Валидни дейноÑти:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Малка рекламна кампаниÑ
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Средна рекламна кампаниÑ
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :ГолÑма рекламна кампаниÑ
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :ФинанÑиране преуÑтройÑтвото на меÑтните пътища
+STR_204A_BUILD_STATUE_OF_COMPANY :ПоÑтроÑване на ÑÑ‚Ð°Ñ‚ÑƒÑ Ð½Ð° ÑобÑтвеника на компаниÑта
+STR_204B_FUND_NEW_BUILDINGS :ФинанÑиране поÑтроÑването на нови Ñгради
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Покупка на Ñпециални транÑпортни права
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Подкупи меÑтните влаÑти
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Иницииране на малка меÑтна рекламна кампаниÑ, за привличане на повече пътници и товар към вашите транÑпортни уÑлуги.{} Цена: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Иницииране на малка меÑтна рекламна кампаниÑ, за привличане на повече пътници и товар към вашите транÑпортни уÑлуги.{} Цена: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Иницииране на малка меÑтна рекламна кампаниÑ, за привличане на повече пътници и товар към вашите транÑпортни уÑлуги.{} Цена: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} ФинанÑиране преуÑтройÑтвото на градÑката пътна мрежа. Ще породи значителен разрив на градÑÐºÐ¸Ñ Ñ‚Ñ€Ð°Ñ„Ð¸Ðº за не повече от 6 меÑеца.{} Цена: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Строеж на ÑÑ‚Ð°Ñ‚ÑƒÑ Ð² чеÑÑ‚ на вашата компаниÑ.{} Цена: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} ФинанÑиране изграждането на нови комерÑиални Ñгради в града.{} Цена: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Покупка на едногодишни Ñпециални транÑпортни права в града. ГрадÑките влаÑти ще позволÑÑ‚ единÑтвено на пътниците и товара да използват гарите на вашата компаниÑ.{} Цена: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Подкупването на меÑтната влаÑÑ‚ за да увеличи рейтинга ноÑи огромен риÑк ако бъдете хванати{} Цена: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK} Ð¥Ð°Ð¾Ñ Ð½Ð° трафика в {TOWN}!{}{}Програма за пътна реконÑÑ‚Ñ€ÑƒÐºÑ†Ð¸Ñ Ñ„Ð¸Ð½Ð°Ð½Ñирана от {COMPANY} ноÑи 6 меÑеца Ð¼Ð¸Ð·ÐµÑ€Ð¸Ñ Ð·Ð° моториÑтите!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (в Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð½Ð° изграждане)
+STR_2059_IGLOO :Иглу
+STR_205A_TEPEES :ИндианÑки колиби
+STR_205B_TEAPOT_HOUSE :Фабрика за чай
+STR_205C_PIGGY_BANK :ДетÑка каÑичка
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN} {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Тераформиране
+STR_2800_PLANT_TREES :ЗаÑаждане на дървета
+STR_2801_PLACE_SIGN :ПоÑтавÑне на знак
+STR_2802_TREES :{WHITE}Дървета
+STR_2803_TREE_ALREADY_HERE :{WHITE}...вече има дърво
+STR_2804_SITE_UNSUITABLE :{WHITE}...неподходÑщо мÑÑто
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Тук не може да бъде заÑадено дърво...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...твърде много знаци
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Тук не може да бъде поÑтавÑн знак...
+STR_280A_SIGN :Знак
+STR_280B_EDIT_SIGN_TEXT :{WHITE}ПромÑна текÑта на знака
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Името на знака не може да бъде променÑно...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Избор тип на дърво за заÑаждане
+STR_280E_TREES :Дървета
+STR_280F_RAINFOREST :Дъждовни гори
+STR_2810_CACTUS_PLANTS :КактуÑи
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Избор на жп гара
+STR_3001_AIRPORT_SELECTION :{WHITE}Избор на летище
+STR_3002_ORIENTATION :{BLACK}ОриентациÑ
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Брои на пътищата
+STR_3004_PLATFORM_LENGTH :{BLACK}Дължина на платформата
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Твърде близо до друга жп гара
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Граничи Ñ Ð¿Ð¾Ð²ÐµÑ‡Ðµ от една гара/товарна платформа
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}Твърде много гари/товарни платформи в града
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}Твърде много гари/товарни платформи
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Твърде много автобуÑни Ñпирки
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}Твърде много гари за камиони
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Твърде близо до друга гара/товарна платформа
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Първо разрушете ЖП гарата
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Прекалено близо до друго летище
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Първо разрушете летището
+
+STR_3030_RENAME_STATION_LOADING :Преименуване на ÑтанциÑ
+STR_3031_CAN_T_RENAME_STATION :{WHITE}СтанциÑта не може да бъде преименувана...
+STR_3032_RATINGS :{BLACK}Рейтинги
+STR_3033_ACCEPTS :{BLACK}Приема
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}МеÑтно ниво на обÑлужване:
+
+############ range for rating starts
+STR_3035_APPALLING :Плачевно
+STR_3036_VERY_POOR :Много Ñлабо
+STR_3037_POOR :Слабо
+STR_3038_MEDIOCRE :Средно
+STR_3039_GOOD :Добро
+STR_303A_VERY_GOOD :Много добро
+STR_303B_EXCELLENT :Отлично
+STR_303C_OUTSTANDING :ÐевероÑтно
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} вече не приема {STRING}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} вече не приема {STRING} или {STRING}
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} вече приема {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} вече приема {STRING} и {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}ÐžÑ€Ð¸ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ Ð½Ð° автогара
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Ориент. товарна гара
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Първо разрушете автогарата
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Първо разрушете товарната гара
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Станци{P Ñ Ð¸}
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Ðиколко -
+STR_304B_SITE_UNSUITABLE :{WHITE}...неподходÑщо мÑÑто
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Прекалено близо до друг док
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Първо разрушете дока
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}ÐžÑ€Ð¸ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ Ð½Ð° ЖП гарата
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Брой на пероните
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Дължина на ЖП гарата
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}ÐžÑ€Ð¸ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ Ð½Ð° автогарата
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}ÐžÑ€Ð¸ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ Ð½Ð° товарната гара
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Центриране на Ð³Ð»Ð°Ð²Ð½Ð¸Ñ Ð¿Ñ€Ð¾Ð·Ð¾Ñ€ÐµÑ† върху ÑтанциÑта
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Покажи нивото на обÑлужване
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}ПромÑна името на ÑтанциÑта
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Покажи ÑпиÑък Ñ Ð¿Ñ€Ð¸ÐµÑ‚Ð¸Ñ‚Ðµ товари
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Имена на Ñтанции - натиÑнете върху името за да центрирате Ð³Ð»Ð°Ð²Ð½Ð¸Ñ Ð¿Ñ€Ð¾Ð·Ð¾Ñ€ÐµÑ† върху ÑтанциÑта
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Големина/тип на летището
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :ЖП гара
+STR_305F_AIRCRAFT_HANGAR :Хангар за Ñамолети
+STR_3060_AIRPORT :Летище
+STR_3061_TRUCK_LOADING_AREA :Товарна гара
+STR_3062_BUS_STATION :Ðвтогара
+STR_3063_SHIP_DOCK :Корабен док
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Отбележи зоната от предложеното мÑÑто
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Ðе отбелÑзвай зоната от предложеното мÑÑто
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Маркиране на ОтбелÑзаната зона
+STR_3068_DOCK :{WHITE}Док
+STR_3069_BUOY :Шамандура
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...шамандура на пътÑ
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...ÑтанциÑта е прекалено разпръÑната
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...неправилните Ñтанции Ñа изключени
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Задържете CTRL за да изберете повече от един обект
+
+STR_UNDEFINED :(неопределен текÑÑ‚)
+STR_STAT_CLASS_DFLT :Ð¡Ñ‚Ð°Ð½Ñ†Ð¸Ñ Ð¿Ð¾ подразбиране
+STR_STAT_CLASS_WAYP :Пътни точки
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}ÐžÑ€Ð¸ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ Ð½Ð° дока
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...Ñ‚Ñ€Ñбва да Ñе поÑтрои във вода
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Дока не може да бъде поÑтроен тук...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Избор на Ð¾Ñ€Ð¸ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ Ð½Ð° док
+STR_3804_WATER :Вода
+STR_3805_COAST_OR_RIVERBANK :БрÑг или поречие
+STR_3806_SHIP_DEPOT :Корабно депо
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...Ðе може да бъде поÑтроено във водата
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Запази играта
+STR_4001_LOAD_GAME :{WHITE}Отвори игра
+STR_4002_SAVE :{BLACK}Запази
+STR_4003_DELETE :{BLACK}Изтрий
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} мегабайт{P "" а} Ñвободно
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Ðе може да прочете диÑка
+STR_4007_GAME_SAVE_FAILED :{WHITE}Запазването на играта е неуÑпешно
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Изтриването на файла е неуÑпешно
+STR_4009_GAME_LOAD_FAILED :{WHITE}ОтварÑнето на играта е неуÑпешно
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}СпиÑък Ñ Ñ…Ð°Ñ€Ð´-диÑковете, директориите и запазените игри
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Избрано име за запазена игра
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Изтрий избраната запазената игра
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Запазване на наÑтоÑщата игра Ñ Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¾Ñ‚Ð¾ име
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Избери нов тип игра
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Избери на Ñценарии (зелено), предварително наÑтроена игра (Ñиньо), или произволна нова игра
+STR_4010_GENERATE_RANDOM_NEW_GAME :Генерирай произволна нова игра
+STR_4011_LOAD_HEIGHTMAP :{WHITE}Зареди виÑочинна карта
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} пречи
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :Мина за въглища
+STR_4803_POWER_STATION :
+STR_4804_SAWMILL :ДъÑкорезница
+STR_4805_FOREST :Гора
+STR_4806_OIL_REFINERY :Ðефтена рафинериÑ
+STR_4807_OIL_RIG :Ðефтен кладенец
+STR_4808_FACTORY :Завод
+STR_4809_PRINTING_WORKS :Печатница
+STR_480A_STEEL_MILL :СтоманолеÑрна
+STR_480B_FARM :Ферма
+STR_480C_COPPER_ORE_MINE :Медна мина
+STR_480D_OIL_WELLS :Ðефтени кладенци
+STR_480E_BANK :Банка
+STR_480F_FOOD_PROCESSING_PLANT :Завод за обработка на храни
+STR_4810_PAPER_MILL :Завод за ХартиÑ
+STR_4811_GOLD_MINE :Златна мина
+STR_4812_BANK :Банка
+STR_4813_DIAMOND_MINE :Диамантена мина
+STR_4814_IRON_ORE_MINE :ЖелÑзна мина
+STR_4815_FRUIT_PLANTATION :Офощна градина
+STR_4816_RUBBER_PLANTATION :Каучукова плантациÑ
+STR_4817_WATER_SUPPLY :Водоизточник
+STR_4818_WATER_TOWER :Водна кула
+STR_4819_FACTORY :Завод
+STR_481A_FARM :Ферма
+STR_481B_LUMBER_MILL :Дърворезница
+STR_481C_COTTON_CANDY_FOREST :Гора от захарен памук
+STR_481D_CANDY_FACTORY :Завод за Ñладки
+STR_481E_BATTERY_FARM :Ферма за батерии
+STR_481F_COLA_WELLS :Кола кладенци
+STR_4820_TOY_SHOP :Магазин за играчки
+STR_4821_TOY_FACTORY :Завод за играчки
+STR_4822_PLASTIC_FOUNTAINS :Фонатани от плаÑтмаÑа
+STR_4823_FIZZY_DRINK_FACTORY :Завод за газирани напитки
+STR_4824_BUBBLE_GENERATOR :Генератор на балончета
+STR_4825_TOFFEE_QUARRY :Карамелоломна
+STR_4826_SUGAR_MINE :Захарна мина
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Ðуждае Ñе от: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Ðуждае Ñе от: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Ðуждае Ñе от: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Произведено Ð¼Ð¸Ð½Ð°Ð»Ð¸Ñ Ð¼ÐµÑец:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% превозено)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Центриране Ð³Ð»Ð°Ð²Ð½Ð¸Ñ Ð¿Ñ€Ð¾Ð·Ð¾Ñ€ÐµÑ† върху индуÑтриÑта
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Ðова {STRING} Ñе Ñтрои близо до {TOWN}!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Ðова {STRING} Ñе заÑажда близо до {TOWN}!
+STR_482F_COST :{BLACK}Цена: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Този вид индуÑÑ‚Ð¸Ñ Ð½Ðµ може да бъде поÑтроена тук...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...гора може да Ñе заÑажда Ñамо над линиÑта на Ñнега
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} обÑви незабавно закриване!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}Проблеми Ñ Ð´Ð¾Ñтавките предизвикаха незабавно закриване на {INDUSTRY}!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}ЛипÑа на дървета предизвикаха незабавно закриване на {INDUSTRY}!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} увеличава прозводÑтвото!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}Ðови залежи на въглища Ñа намерени в {INDUSTRY}!{}Очаква Ñе производÑтвото да Ñе удвои!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}Ðови залежи на Ðефт Ñа намерени в {INDUSTRY}!{}Очаква Ñе производÑтото да Ñе удвои!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}ИноваторÑките ÑелÑкоÑтопанÑки технологии в {INDUSTRY} Ñе очаква да удвоÑÑ‚ производÑтвото!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}ПрозиводÑтвото в {INDUSTRY} Ñпадна Ñ 50%
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}ÐапаÑÑ‚ от наÑекоми предизвика опуÑтошение в {INDUSTRY}!{}ПроизводÑтвото Ð½Ð°Ð¼Ð°Ð»Ñ Ñ 50%
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...може да бъде поÑтавено Ñамо до краищата на картата
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}{STRING} Ð¿Ñ€Ð¾Ð´ÑƒÐºÑ†Ð¸Ñ Ð² {INDUSTRY} нараÑна Ñ {COMMA}%!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}{STRING} Ð¿Ñ€Ð¾Ð´ÑƒÐºÑ†Ð¸Ñ Ð² {INDUSTRY} Ð½Ð°Ð¼Ð°Ð»Ñ Ñ {COMMA}%!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Влак в тунела
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}МПС в тунела
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Друг тунел пречи
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Ðе може да бъде изкопан Ð´Ñ€ÑƒÐ³Ð¸Ñ ÐºÑ€Ð°Ð¹ на тунела
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Първо разрушете тунела
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Първо Ñ‚Ñ€Ñбва да разрушите моÑта
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Ðе може да започва и да Ñвърша на едно и Ñъщо мÑÑто
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Равна Ð·ÐµÐ¼Ñ Ð¸Ð»Ð¸ вода е необходима под моÑта
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}Ðачалото и краÑÑ‚ Ñ‚Ñ€Ñбва да Ñа на една линиÑ
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}ÐœÑÑтото е неподходÑщо за вход на тунел
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :ВиÑÑщ, Стоманен
+STR_500F_GIRDER_STEEL :Гредоред, Стоманен
+STR_5010_CANTILEVER_STEEL :Конзолен, Стоманен
+STR_5011_SUSPENSION_CONCRETE :ВиÑÑщ, Бетонен
+STR_5012_WOODEN :Дървен
+STR_5013_CONCRETE :Бетонен
+STR_5014_TUBULAR_STEEL :Тръбен, Стоманен
+STR_BRIDGE_TUBULAR_SILICON :Тръбен, Силиконов
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Ðе може да бъде поÑтроен моÑÑ‚ тук...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Ðе може да бъде поÑтроен тунел тук...
+STR_5017_RAILROAD_TUNNEL :ЖП тунел
+STR_5018_ROAD_TUNNEL :Пътен тунел
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Стоманен виÑÑщ ЖП моÑÑ‚
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Стоманен гредореден ЖП моÑÑ‚
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Стоманен конзолен ЖП моÑÑ‚
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Железобетонен виÑÑщ ЖП моÑÑ‚
+STR_501F_WOODEN_RAIL_BRIDGE :Дървен ЖП моÑÑ‚
+STR_5020_CONCRETE_RAIL_BRIDGE :Бетонен ЖП моÑÑ‚
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Стоманен виÑÑщ пътен моÑÑ‚
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Стоманен гредореден пътен моÑÑ‚
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Стоманен конзолен пътен моÑÑ‚
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Железобетонен виÑÑщ пътен моÑÑ‚
+STR_5025_WOODEN_ROAD_BRIDGE :Дървен пътен моÑÑ‚
+STR_5026_CONCRETE_ROAD_BRIDGE :Бетонен пътен моÑÑ‚
+STR_5027_TUBULAR_RAIL_BRIDGE :Тръбовиден ЖП моÑÑ‚
+STR_5028_TUBULAR_ROAD_BRIDGE :Тръбовиден пътен моÑÑ‚
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Обект на пътÑ
+STR_5801_TRANSMITTER :Предавател
+STR_5802_LIGHTHOUSE :Фар
+STR_5803_COMPANY_HEADQUARTERS :Централен офиÑ
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...централен Ð¾Ñ„Ð¸Ñ Ðµ на пътÑ
+STR_5805_COMPANY_OWNED_LAND :ЗемÑ, притежавана от компаниÑта
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}ЗемÑта не може да бъде закупена...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...вие вече притежавате това!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Ðеименован
+STR_SV_TRAIN_NAME :Влак {COMMA}
+STR_SV_ROADVEH_NAME :Ðвтомобил {COMMA}
+STR_SV_SHIP_NAME :Кораб {COMMA}
+STR_SV_AIRCRAFT_NAME :Самолет {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :{STRING} Север
+STR_SV_STNAME_SOUTH :{STRING} Юг
+STR_SV_STNAME_EAST :{STRING} Изток
+STR_SV_STNAME_WEST :{STRING} Запад
+STR_SV_STNAME_CENTRAL :{STRING} Център
+STR_SV_STNAME_TRANSFER :{STRING} ТранÑфер
+STR_SV_STNAME_HALT :{STRING} Край
+STR_SV_STNAME_VALLEY :{STRING} Долина
+STR_SV_STNAME_HEIGHTS :{STRING} ВиÑочини
+STR_SV_STNAME_WOODS :{STRING} Гора
+STR_SV_STNAME_LAKESIDE :{STRING} Езеро
+STR_SV_STNAME_EXCHANGE :{STRING} РазмÑна
+STR_SV_STNAME_AIRPORT :{STRING} Летище
+STR_SV_STNAME_OILFIELD :{STRING} Ðефтено поле
+STR_SV_STNAME_MINES :{STRING} Мини
+STR_SV_STNAME_DOCKS :{STRING} Докове
+STR_SV_STNAME_BUOY_1 :{STRING} Шамандура 1
+STR_SV_STNAME_BUOY_2 :{STRING} Шамандура 2
+STR_SV_STNAME_BUOY_3 :{STRING} Шамандура 3
+STR_SV_STNAME_BUOY_4 :{STRING} Шамандура 4
+STR_SV_STNAME_BUOY_5 :{STRING} Шамандура 5
+STR_SV_STNAME_BUOY_6 :{STRING} Шамандура 6
+STR_SV_STNAME_BUOY_7 :{STRING} Шамандура 7
+STR_SV_STNAME_BUOY_8 :{STRING} Шамандура 8
+STR_SV_STNAME_BUOY_9 :{STRING} Шамандура 9
+STR_SV_STNAME_ANNEXE :{STRING} ПриÑтройка
+STR_SV_STNAME_SIDINGS :{STRING} Обшивки
+STR_SV_STNAME_BRANCH :{STRING} Клон
+STR_SV_STNAME_UPPER :Горно {STRING}
+STR_SV_STNAME_LOWER :Долно {STRING}
+STR_SV_STNAME_HELIPORT :{STRING} Хелипорт
+STR_SV_STNAME_FOREST :{STRING} Дървета
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Ðиво на трудноÑÑ‚
+STR_OPTIONS_SAVE_CHANGES :{BLACK}ЗапиÑ
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}ЛеÑно
+STR_6802_MEDIUM :{BLACK}Средно
+STR_6803_HARD :{BLACK}Трудно
+STR_6804_CUSTOM :{BLACK}По твой избор
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}МакÑимален брой конкуренти: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Конкурентите Ñтартират: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}Брой на градовете: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}Брой на индуÑтриите: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}МакÑимален начален заем: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Ðачална лихва: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Оперативни разходи на превозните ÑредÑтва: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}СкороÑÑ‚ на Ñтроене на конкурентите: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}ИнтелигентноÑÑ‚ на конкурентите: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Повреди на превозното ÑредÑтво: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Множител на ÑубÑидиите: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Цена на ÑтроителÑтвото: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Тип на терена: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Съотношение морета/езера: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Икономика: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Обръщане на влаковете: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}БедÑтвиÑ: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Отношение на градÑките влаÑти към промÑна на земÑта: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :Ðиколко
+STR_6816_LOW :ÐиÑко/Малко
+STR_6817_NORMAL :Ðормално
+STR_6818_HIGH :ВиÑоко/Много
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Много бавно
+STR_681C_SLOW :Бавно
+STR_681D_MEDIUM :Средно
+STR_681E_FAST :Бързо
+STR_681F_VERY_FAST :Много бързо
+STR_VERY_LOW :Много ниÑък
+STR_6820_LOW :ÐиÑка/Малка
+STR_6821_MEDIUM :Средна
+STR_6822_HIGH :ВиÑока/ГолÑма
+STR_6823_NONE :Без
+STR_6824_REDUCED :Ðамалени
+STR_6825_NORMAL :Ðормални
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Изключително равнинен
+STR_682B_FLAT :Равнинен
+STR_682C_HILLY :ХълмиÑÑ‚
+STR_682D_MOUNTAINOUS :ПланинÑки
+STR_682E_STEADY :Стабилна
+STR_682F_FLUCTUATING :Променлива
+STR_6830_IMMEDIATE :Веднага
+STR_6831_3_MONTHS_AFTER_PLAYER :3 меÑеца Ñлед играча
+STR_6832_6_MONTHS_AFTER_PLAYER :6 меÑеца Ñлед играча
+STR_6833_9_MONTHS_AFTER_PLAYER :9 меÑеца Ñлед играча
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :Ð’ ÐºÑ€Ð°Ñ Ð½Ð° линиÑта и на Ñтанциите
+STR_6835_AT_END_OF_LINE_ONLY :Само в ÐºÑ€Ð°Ñ Ð½Ð° линиÑта
+STR_6836_OFF :Изключено
+STR_6837_ON :Включено
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Покажи клаÑирането
+STR_6839_PERMISSIVE :Разрешаващи
+STR_683A_TOLERANT :Толерантни
+STR_683B_HOSTILE :Враждебни
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Играч {COMMA})
+STR_7004_NEW_FACE :{BLACK}Ðово лице
+STR_7005_COLOR_SCHEME :{BLACK}Цветова Ñхема
+STR_7006_COLOR_SCHEME :{GOLD}Цветова гама:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Ðова цветова гама
+STR_7008_COMPANY_NAME :{BLACK}Име на КомпаниÑта
+STR_7009_PRESIDENT_NAME :{BLACK}Име на УправителÑÑ‚
+STR_700A_COMPANY_NAME :Име на КомпаниÑта
+STR_700B_PRESIDENT_S_NAME :Име на УправителÑ
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Ðе може да промениш името на компаниÑта...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Ðе може да промениш името на управителÑ...
+STR_700E_FINANCES :{WHITE}{COMPANY} ФинанÑи {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Разходи/Приходи
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Строеж
+STR_7012_NEW_VEHICLES :{GOLD}Ðови МПС-та
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Оперативни разходи на влака
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Оперативни разходи на МПС-то
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Оперативни разходи на Ñамолета
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Оперативни разходи на кораба
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Разходи по поддръжка
+STR_7018_TRAIN_INCOME :{GOLD}Приходи от влакове
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Приходи от МПС-та
+STR_701A_AIRCRAFT_INCOME :{GOLD}Приходи от Ñамолети
+STR_701B_SHIP_INCOME :{GOLD}Приходи от кораби
+STR_701C_LOAN_INTEREST :{GOLD}Лихва по заема
+STR_701D_OTHER :{GOLD}Други
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Ð’Ñичко:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Графика на приходите
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Графика на оперативните приходи
+STR_7026_BANK_BALANCE :{WHITE}Ð‘Ð°Ð»Ð°Ð½Ñ Ð½Ð° банковата Ñметка
+STR_7027_LOAN :{WHITE}Заем
+STR_MAX_LOAN :{WHITE}МакÑимален заем: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}Изтегли {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Изплати {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...макÑимално разрешениÑÑ‚ размер на заема е {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Ðе може да изтеглиш повече пари...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...нÑма заем за изплащане
+STR_702E_REQUIRED :{WHITE}...{CURRENCY} Ñа необходими
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Ðе може да изплатиш заема...
+STR_INSUFFICIENT_FUNDS :{WHITE}Ðе може да Ñе харчат пари които Ñа заети от банка...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Избери друго лице за управителÑ
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Смени цвета на компаниÑта
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Смени името на управителÑ
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Смени името на компаниÑта
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Кликни върху Ð¿Ñ€ÐµÐ´Ð¿Ð¾Ñ‡Ð¸Ñ‚Ð°Ð½Ð¸Ñ Ñ†Ð²ÑÑ‚
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Увеличи размера на заема
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Изплати чаÑÑ‚ от заема
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(Управител)
+STR_7038_INAUGURATED :{GOLD}Открита: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}МПС-та:
+STR_TRAINS :{WHITE}{COMMA} влак{P "" ове}
+STR_ROAD_VEHICLES :{WHITE}{COMMA} автомобил{P "" и}
+STR_AIRCRAFT :{WHITE}{COMMA} Ñамолет
+STR_SHIPS :{WHITE}{COMMA} кораб{P "" и}
+STR_7042_NONE :{WHITE}Ðиколко
+STR_7043_FACE_SELECTION :{WHITE}Избор на лице
+STR_7044_MALE :{BLACK}Мъж
+STR_7045_FEMALE :{BLACK}Жена
+STR_7046_NEW_FACE :{BLACK}Ðово лице
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}ПреуÑтанови избора на ново лице
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Признавам избора на ново лице
+STR_7049_SELECT_MALE_FACES :{BLACK}Избери мъжки лица
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Избери женÑки лица
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Генерирай произволно ново лице
+STR_704C_KEY :{BLACK}Легенда
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Покажи легендата на графиката
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Легенда на графиката за компаниите
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Кликни тук, за да активираш поÑвÑването/Ñкриването на компаниÑта от графиката
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Брой на доÑтавените Ñтоки
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Райтинг на предÑтавÑнето на компаниÑта (макÑимален рейтинг=1000)
+STR_7052_COMPANY_VALUES :{WHITE}СтойноÑÑ‚ на КомпаниÑта
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}КлаÑиране на Компаниите
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}ТранÑпортна ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ñ Ð² беда!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} ще бъде продадена или обÑвена в банкрут оÑвен ако предÑтавÑнето й не Ñе подобри Ñкоро!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(Manager)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Сливане на транÑпортни компании!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} беше продадена на {COMPANY} for {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Ðие Ñ‚ÑŠÑ€Ñим транÑпортна компаниÑ, коÑто да поеме нашата компаниÑ.{}{}Do you want to purchase {COMPANY} for {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Банкрут!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} беше закрита от кредиторите и цÑлото й имущеÑтво бе продадено!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}Ðова транÑпортна ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ñ Ñтартира!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} започна ÑтроителÑтво край {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Ðе може да купиш компаниÑта...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Заплащане за превоз на товар
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Дни на превоз
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Заплащане на доÑтавени 10 единици (или 10,000 литра) товар на разÑтоÑние 20 квадрата
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Ðктивирай/деактивирай графиката за видовете товар
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Инженер
+STR_7067_TRAFFIC_MANAGER :Ръководител на Трафика
+STR_7068_TRANSPORT_COORDINATOR :ТранÑпортен Координатор
+STR_7069_ROUTE_SUPERVISOR :Маршрутен Ðадзирател
+STR_706A_DIRECTOR :Директор
+STR_706B_CHIEF_EXECUTIVE :Шеф
+STR_706C_CHAIRMAN :ПредÑедател
+STR_706D_PRESIDENT :ПреÑидент
+STR_706E_TYCOON :Магнат
+STR_706F_BUILD_HQ :{BLACK}ПоÑтрой Централен ОфиÑ
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}ПоÑтрой централен Ð¾Ñ„Ð¸Ñ Ð½Ð° компаниÑта / покажи Ñ†ÐµÐ½Ñ‚Ñ€Ð°Ð»Ð½Ð¸Ñ Ð¾Ñ„Ð¸Ñ Ð½Ð° компаниÑта
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}ПремеÑтване централата на компаниÑта другаде за 1% от ÑтойноÑта на компаниÑта
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Ðе може на поÑтроиш централен офиÑ...
+STR_7072_VIEW_HQ :{BLACK}Покажи Ð¦ÐµÐ½Ñ‚Ñ€Ð°Ð»Ð½Ð¸Ñ ÐžÑ„Ð¸Ñ
+STR_RELOCATE_HQ :{BLACK}ПремеÑтване ЦК
+STR_COMPANY_PASSWORD :{BLACK}Парола
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}ПоÑтави парола за да предпазиш компаниÑта Ñи от неоторизирани потребители.
+STR_SET_COMPANY_PASSWORD :ПоÑтавÑне парола на компаниÑта
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}Световна икономичеÑка криза!{}{}ФинанÑовите екÑперти очакват най-лошото от Ñриващата Ñе Ñветовна икономика!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Световната икономичеÑка криза отмина!{}{}Възходът на търговиÑта дава увереноÑÑ‚ на индуÑтриите в новата заÑилваща Ñе икономичеÑка реалноÑÑ‚!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Ðктивирай голÑм/малък размер на прозореца
+STR_7076_COMPANY_VALUE :{GOLD}СтойноÑÑ‚ на КомпаниÑта: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Купи 25% от акциите на компаниÑта
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Продай 25% от акциите на компаниÑта
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Купи 25% от акциите на тази компаниÑ
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Продай 25% от акциите на тази компаниÑ
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Ðе може да купиш 25% от акциите на тази компаниÑ...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}Ðе може да продадеш 25% от акциите на тази компаниÑ...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% е притежание на {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% е притежание на {COMPANY}{} {COMMA}% е притежание на {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} бе закупена от {COMPANY}!
+STR_7080_PROTECTED :{WHITE}Тази ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ñ Ð²Ñе още не е доÑтатъчно Ñтара да предлага акции...
+
+STR_LIVERY_DEFAULT :Стандартен Ливъри
+STR_LIVERY_STEAM :Парен локомотив
+STR_LIVERY_DIESEL :ДиÑелов двигател
+STR_LIVERY_ELECTRIC :ЕлектричеÑки локомотив
+STR_LIVERY_MONORAIL :МонорелÑов локомотив
+STR_LIVERY_MAGLEV :Маглев локомотив
+STR_LIVERY_DMU :DMU
+STR_LIVERY_EMU :EMU
+STR_LIVERY_PASSENGER_WAGON_STEAM :ПътничеÑки вагон (Парен)
+STR_LIVERY_PASSENGER_WAGON_DIESEL :ПътничеÑки вагон (Дизел)
+STR_LIVERY_PASSENGER_WAGON_ELECTRIC :ПътничеÑки вагон (ЕлектричеÑки)
+STR_LIVERY_FREIGHT_WAGON :Товарен вагон
+STR_LIVERY_BUS :ÐвтобуÑ
+STR_LIVERY_TRUCK :Камион
+STR_LIVERY_PASSENGER_SHIP :ПътничеÑки ферибот
+STR_LIVERY_FREIGHT_SHIP :Товарен кораб
+STR_LIVERY_HELICOPTER :Хеликоптер
+STR_LIVERY_SMALL_PLANE :Малък аероплан
+STR_LIVERY_LARGE_PLANE :ГолÑм аероплан
+
+STR_LIVERY_GENERAL_TIP :{BLACK}Показване на общи цветови Ñхеми
+STR_LIVERY_TRAIN_TIP :{BLACK}Показване цветовите Ñхеми на влаковете
+STR_LIVERY_ROADVEH_TIP :{BLACK}Показване на цветови Ñхеми за автомобилите
+STR_LIVERY_SHIP_TIP :{BLACK}Показване цветови Ñхеми на корабите
+STR_LIVERY_AIRCRAFT_TIP :{BLACK}Показване цветовата Ñхема на Ñамолетите
+STR_LIVERY_PRIMARY_TIP :{BLACK}Изберете оÑÐ½Ð¾Ð²Ð½Ð¸Ñ Ñ†Ð²ÑÑ‚ за избранта Ñхема
+STR_LIVERY_SECONDARY_TIP :{BLACK}Изберете допълнителен жвÑÑ‚ за избраната Ñхема
+STR_LIVERY_PANEL_TIP :{BLACK}Изберете цветова Ñхема за промÑна или нÑколко - CTRL+щрак. ÐатиÑнете в кутиÑта за да превключите използването на Ñхемата
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul ЦиÑтерна (Парен)
+STR_8001_MJS_250_DIESEL :MJS 250 (Дизелов)
+STR_8002_PLODDYPHUT_CHOO_CHOO :УпоритиÑÑ‚ Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :СилниÑÑ‚ Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :ÐœÐ¾Ñ‰Ð½Ð¾Ð´Ð²Ð¸Ð³Ð°Ñ‚ÐµÐ»Ð½Ð¸Ñ Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :УпоритиÑÑ‚ Дизелов
+STR_8006_POWERNAUT_DIESEL :СилниÑÑ‚ Дизелов
+STR_8007_WILLS_2_8_0_STEAM :ÐепоколебимиÑÑ‚ 2-8-0 (парен)
+STR_8008_CHANEY_JUBILEE_STEAM :'Юбилей' (Парен)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (Парен)
+STR_800A_SH_8P_STEAM :SH '8P' (Парен)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (Дизелов)
+STR_800C_DASH_DIESEL :'СтремителниÑÑ‚' (Дизелов)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (Дизелов)
+STR_800E_UU_37_DIESEL :UU '37' (Дизелов)
+STR_800F_FLOSS_47_DIESEL :Ð¤Ð»Ð¾Ñ '47' (Дизелов)
+STR_8010_CS_4000_DIESEL :CS 4000 (Дизелов)
+STR_8011_CS_2400_DIESEL :CS 2400 (Дизелов)
+STR_8012_CENTENNIAL_DIESEL :Стогодишен (Дизелов)
+STR_8013_KELLING_3100_DIESEL :Келинг 3100 (Дизелов)
+STR_8014_TURNER_TURBO_DIESEL :Търнър Турбо (Дизелов)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (Дизелов)
+STR_8016_SH_125_DIESEL :SH '125' (Дизелов)
+STR_8017_SH_30_ELECTRIC :SH '30' (ЕлектричеÑки)
+STR_8018_SH_40_ELECTRIC :SH '40' (ЕлектричеÑки)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (ЕлектричеÑки)
+STR_801A_ASIASTAR_ELECTRIC :'Източна Звезда' (ЕлектричеÑки)
+STR_801B_PASSENGER_CAR :Вагон за пътници
+STR_801C_MAIL_VAN :Вагон за поща
+STR_801D_COAL_CAR :Вагон за въглища
+STR_801E_OIL_TANKER :ЦиÑтерна за нефт
+STR_801F_LIVESTOCK_VAN :Вагон за добитък
+STR_8020_GOODS_VAN :Вагон за Ñтоки
+STR_8021_GRAIN_HOPPER :Вагон за зърно
+STR_8022_WOOD_TRUCK :Вагон за дърва
+STR_8023_IRON_ORE_HOPPER :Вагон за желÑзна руда
+STR_8024_STEEL_TRUCK :Вагон за Ñтомана
+STR_8025_ARMORED_VAN :Вагон за ÑкъпоценноÑти
+STR_8026_FOOD_VAN :Вагон за храна
+STR_8027_PAPER_TRUCK :Вагон за хартиÑ
+STR_8028_COPPER_ORE_HOPPER :Вагон за медна руда
+STR_8029_WATER_TANKER :ЦиÑтерна за вода
+STR_802A_FRUIT_TRUCK :Вагон за плодове
+STR_802B_RUBBER_TRUCK :Вагон за каучук
+STR_802C_SUGAR_TRUCK :Вагон за захар
+STR_802D_COTTON_CANDY_HOPPER :Вагон за захарен памук
+STR_802E_TOFFEE_HOPPER :Вагон за карамел
+STR_802F_BUBBLE_VAN :Вагон за въздушни мехури
+STR_8030_COLA_TANKER :ЦиÑтерна за кола
+STR_8031_CANDY_VAN :Вагон за Ñладки
+STR_8032_TOY_VAN :Вагон за играчки
+STR_8033_BATTERY_TRUCK :Вагон за батерии
+STR_8034_FIZZY_DRINK_TRUCK :Вагон за газирани напитки
+STR_8035_PLASTIC_TRUCK :Вагон за плаÑтмаÑа
+STR_8036_X2001_ELECTRIC :'X2001' (ЕлектричеÑки)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'ХилÑдолетие Z1' (ЕлектричеÑки)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :Вагон за пътници
+STR_803A_MAIL_VAN :Вагон за поща
+STR_803B_COAL_CAR :Вагон за въглища
+STR_803C_OIL_TANKER :ЦиÑтерна за нефт
+STR_803D_LIVESTOCK_VAN :Вагон за добитък
+STR_803E_GOODS_VAN :Вагон за Ñтоки
+STR_803F_GRAIN_HOPPER :Вагон за зърно
+STR_8040_WOOD_TRUCK :Вагон за дърва
+STR_8041_IRON_ORE_HOPPER :Вагон за желÑзна руда
+STR_8042_STEEL_TRUCK :Вагон за Ñтомана
+STR_8043_ARMORED_VAN :Вагон за ÑкъпоценноÑти
+STR_8044_FOOD_VAN :Вагон за храна
+STR_8045_PAPER_TRUCK :Вагон за хартиÑ
+STR_8046_COPPER_ORE_HOPPER :Вагон за медна руда
+STR_8047_WATER_TANKER :ЦиÑтерна за вода
+STR_8048_FRUIT_TRUCK :Вагон за плодове
+STR_8049_RUBBER_TRUCK :Вагон за каучук
+STR_804A_SUGAR_TRUCK :Вагон за захар
+STR_804B_COTTON_CANDY_HOPPER :Вагон за захарен памук
+STR_804C_TOFFEE_HOPPER :Вагон за карамел
+STR_804D_BUBBLE_VAN :Вагон за въздушни мехури
+STR_804E_COLA_TANKER :ЦиÑтерна за кола
+STR_804F_CANDY_VAN :Вагон за Ñладки
+STR_8050_TOY_VAN :Вагон за играчки
+STR_8051_BATTERY_TRUCK :Вагон за батерии
+STR_8052_FIZZY_DRINK_TRUCK :Вагон за газирани напитки
+STR_8053_PLASTIC_TRUCK :Вагон за плаÑтмаÑа
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Чудовище' (ЕлектричеÑки)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Циклоп' (ЕлектричеÑки)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'ПегаÑ' (ЕлектричеÑки)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Химера' (ЕлектричеÑки)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Ракетата
+STR_8059_PASSENGER_CAR :Вагон за пътници
+STR_805A_MAIL_VAN :Вагон за поща
+STR_805B_COAL_CAR :Вагон за въглища
+STR_805C_OIL_TANKER :ЦиÑтерна за нефт
+STR_805D_LIVESTOCK_VAN :Вагон за добитък
+STR_805E_GOODS_VAN :Вагон за Ñтоки
+STR_805F_GRAIN_HOPPER :Вагон за зърно
+STR_8060_WOOD_TRUCK :Вагон за дърва
+STR_8061_IRON_ORE_HOPPER :Вагон за желÑзна руда
+STR_8062_STEEL_TRUCK :Вагон за Ñтомана
+STR_8063_ARMORED_VAN :Вагон за ÑкъпоценноÑти
+STR_8064_FOOD_VAN :Вагон за храна
+STR_8065_PAPER_TRUCK :Вагон за хартиÑ
+STR_8066_COPPER_ORE_HOPPER :Вагон за медна руда
+STR_8067_WATER_TANKER :Вагон-циÑтерна за вода
+STR_8068_FRUIT_TRUCK :Вагон за плодове
+STR_8069_RUBBER_TRUCK :Вагон за каучук
+STR_806A_SUGAR_TRUCK :Вагон за захар
+STR_806B_COTTON_CANDY_HOPPER :Вагон за захарен памук
+STR_806C_TOFFEE_HOPPER :Вагон за карамел
+STR_806D_BUBBLE_VAN :Вагон за балончета
+STR_806E_COLA_TANKER :Вагон-циÑтерна за кола
+STR_806F_CANDY_VAN :Вагон за Ñладки
+STR_8070_TOY_VAN :Вагон за играчки
+STR_8071_BATTERY_TRUCK :Вагон за батерии
+STR_8072_FIZZY_DRINK_TRUCK :Вагон за газирани напитки
+STR_8073_PLASTIC_TRUCK :Вагон за плаÑтмаÑа
+STR_8074_MPS_REGAL_BUS :ÐÐ²Ñ‚Ð¾Ð±ÑƒÑ ÐœÐŸÐ¡ ЦаÑÑ€Ñки
+STR_8075_HEREFORD_LEOPARD_BUS :ÐÐ²Ñ‚Ð¾Ð±ÑƒÑ Ð¥ÐµÑ€ÐµÑ„Ð¾Ñ€Ð´ Леопард
+STR_8076_FOSTER_BUS :ÐÐ²Ñ‚Ð¾Ð±ÑƒÑ Ð“Ñ€Ð¸Ð¶Ð¾Ð²Ð½Ð¸Ñ
+STR_8077_FOSTER_MKII_SUPERBUS :ÐÐ²Ñ‚Ð¾Ð±ÑƒÑ Ð“Ñ€Ð¸Ð¶Ð¾Ð²Ð½Ð¸Ñ ÐœÐš II
+STR_8078_PLODDYPHUT_MKI_BUS :ÐÐ²Ñ‚Ð¾Ð±ÑƒÑ Ð£Ð¿Ð¾Ñ€Ð¸Ñ‚Ð¸Ñ ÐœÐš I
+STR_8079_PLODDYPHUT_MKII_BUS :ÐÐ²Ñ‚Ð¾Ð±ÑƒÑ Ð£Ð¿Ð¾Ñ€Ð¸Ñ‚Ð¸Ñ ÐœÐš II
+STR_807A_PLODDYPHUT_MKIII_BUS :ÐÐ²Ñ‚Ð¾Ð±ÑƒÑ Ð£Ð¿Ð¾Ñ€Ð¸Ñ‚Ð¸Ñ ÐœÐš III
+STR_807B_BALOGH_COAL_TRUCK :Камион за въглища "Балоф"
+STR_807C_UHL_COAL_TRUCK :Камион за въглища "Ухл"
+STR_807D_DW_COAL_TRUCK :Камион за въглища "ДВ"
+STR_807E_MPS_MAIL_TRUCK :Камион за поща "МПС"
+STR_807F_REYNARD_MAIL_TRUCK :Камион за поща "Рейнард"
+STR_8080_PERRY_MAIL_TRUCK :Камион за поща "Пери"
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :Камион за поща "Мощнодвигателен"
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Камион за поща "СилниÑÑ‚"
+STR_8083_WIZZOWOW_MAIL_TRUCK :Камион за поща "Уизоуоу"
+STR_8084_WITCOMBE_OIL_TANKER :Камион-циÑтерна "Уиткомб"
+STR_8085_FOSTER_OIL_TANKER :Камион-циÑтерна "Уиткомб"
+STR_8086_PERRY_OIL_TANKER :Камион-циÑтерна "Пери"
+STR_8087_TALBOTT_LIVESTOCK_VAN :Камион за добитък "Талбот"
+STR_8088_UHL_LIVESTOCK_VAN :Камион за добитък "Ухл"
+STR_8089_FOSTER_LIVESTOCK_VAN :Камион за добитък "ГрижовниÑÑ‚"
+STR_808A_BALOGH_GOODS_TRUCK :Камион за Ñтоки "Балоф"
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Камион за Ñтоки "ТвърдоглавиÑÑ‚"
+STR_808C_GOSS_GOODS_TRUCK :Камион за Ñтоки "ШумниÑÑ‚"
+STR_808D_HEREFORD_GRAIN_TRUCK :Камион за зърно "Херефорд"
+STR_808E_THOMAS_GRAIN_TRUCK :Камион за зърно "ТомаÑ"
+STR_808F_GOSS_GRAIN_TRUCK :Камион за зърно "ШумниÑÑ‚"
+STR_8090_WITCOMBE_WOOD_TRUCK :Камион за дърва "Уиткомб"
+STR_8091_FOSTER_WOOD_TRUCK :Камион за дърва "ГрижовниÑÑ‚"
+STR_8092_MORELAND_WOOD_TRUCK :Камион за дърва "МногоземниÑÑ‚"
+STR_8093_MPS_IRON_ORE_TRUCK :Камион за желÑзна руда "МПС"
+STR_8094_UHL_IRON_ORE_TRUCK :Камион за желÑзна руда "Ухл"
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Камион за желÑзна руда "СкучниÑÑ‚"
+STR_8096_BALOGH_STEEL_TRUCK :Камион за Ñтомана "Балоф"
+STR_8097_UHL_STEEL_TRUCK :Камион за Ñтомана "Ухл"
+STR_8098_KELLING_STEEL_TRUCK :Камион за Ñтомана "Келинг"
+STR_8099_BALOGH_ARMORED_TRUCK :Камион за ÑкъпоценноÑти "Балоф"
+STR_809A_UHL_ARMORED_TRUCK :Камион за ÑкъпоценноÑти "Ухл"
+STR_809B_FOSTER_ARMORED_TRUCK :Камион за ÑкъпоценноÑти "ГрижовниÑÑ‚"
+STR_809C_FOSTER_FOOD_VAN :камион за храна ФоÑтер
+STR_809D_PERRY_FOOD_VAN :камион за храна Пери
+STR_809E_CHIPPY_FOOD_VAN :камион за храна Чипи
+STR_809F_UHL_PAPER_TRUCK :камион за Ñ…Ð°Ñ€Ñ‚Ð¸Ñ Ð£Ð»
+STR_80A0_BALOGH_PAPER_TRUCK :камион за Ñ…Ð°Ñ€Ñ‚Ð¸Ñ Ð‘ÐµÐ¹Ð»Ð¾Ñ„
+STR_80A1_MPS_PAPER_TRUCK :камион за Ñ…Ð°Ñ€Ñ‚Ð¸Ñ MPS
+STR_80A2_MPS_COPPER_ORE_TRUCK :камион за медна руда MPS
+STR_80A3_UHL_COPPER_ORE_TRUCK :камион за медна руда Ул
+STR_80A4_GOSS_COPPER_ORE_TRUCK :камион за медна руда ГоÑ
+STR_80A5_UHL_WATER_TANKER :камион за вода Ул
+STR_80A6_BALOGH_WATER_TANKER :камион за вода Бейлоф
+STR_80A7_MPS_WATER_TANKER :камион за вода MPS
+STR_80A8_BALOGH_FRUIT_TRUCK :камион за плодове Бейлоф
+STR_80A9_UHL_FRUIT_TRUCK :камион за плодове Ул
+STR_80AA_KELLING_FRUIT_TRUCK :камион за плодове Келинг
+STR_80AB_BALOGH_RUBBER_TRUCK :камион за каучук Бейлоф
+STR_80AC_UHL_RUBBER_TRUCK :камион за каучук Ул
+STR_80AD_RMT_RUBBER_TRUCK :камион за каучук RMT
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :камион за захар Майтимувер
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :камион за захар Пауернат
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :камион за захар Уизоуоу
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :камион за кола Майтимувер
+STR_80B2_POWERNAUGHT_COLA_TRUCK :камион за кола Пауернат
+STR_80B3_WIZZOWOW_COLA_TRUCK :камион за кола Уизоуоу
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :камион за захарен памук Майтимувер
+STR_80B5_POWERNAUGHT_COTTON_CANDY :камион за захарен памук Пауернат
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Уизоуоу камион за захарен памук
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :Майтимувер камион за карамел
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Пауернаут камион за карамел
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Уизоуоу камион за карамел
+STR_80BA_MIGHTYMOVER_TOY_VAN :Майтимувер камион за играчки
+STR_80BB_POWERNAUGHT_TOY_VAN :Пауернаут камион за играчки
+STR_80BC_WIZZOWOW_TOY_VAN :Уизоуоу камион за играчки
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :Майтимувер камион за Ñладки
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Пауернаут камион за Ñладки
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Уизоуоу камион за Ñладки
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :Майтимувер камион за батерии
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Пауернаут камион за батерии
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Уизоуоу камион за батерии
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :Майтимувер камион за газирани напитки
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Пауернаут камион за газирани напитки
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Уизоуоу камион за газирани напитки
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :Майтимувер камион за плаÑтмаÑа
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Пауернаут камион за плаÑтмаÑа
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Уизоуоу камион за плаÑтмаÑа
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :Майтимувер камион за балончета
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Пауернаут камион за балончета
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Уизоуоу камион за балончета
+STR_80CC_MPS_OIL_TANKER :MPS танкер
+STR_80CD_CS_INC_OIL_TANKER :CS-Inc. танкер
+STR_80CE_MPS_PASSENGER_FERRY :MPS ферибот
+STR_80CF_FFP_PASSENGER_FERRY :FFP ферибот
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Бейкуел 300 кораб на въздушна възглавница
+STR_80D1_CHUGGER_CHUG_PASSENGER :Чугер-чуг ферибот
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Шивершейк ферибот
+STR_80D3_YATE_CARGO_SHIP :Яте товарен кораб
+STR_80D4_BAKEWELL_CARGO_SHIP :Бейкуел товарен кораб
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Майтимувер товарен кораб
+STR_80D6_POWERNAUT_CARGO_SHIP :Пауернаут товарен кораб
+STR_80D7_SAMPSON_U52 :СампÑон U52
+STR_80D8_COLEMAN_COUNT :Коулман Каунт
+STR_80D9_FFP_DART :FFP Дарт
+STR_80DA_YATE_HAUGAN :Яте Хюган
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Бейкуел КотÑуалд LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Бейкуел Лъкет LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Бейкуел Лъкет LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Бейкуел Лъкет LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Бейкуел Лъкет LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Бейкуел Лъкет LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Яте ÐероÑÐ¿ÐµÐ¹Ñ YAC 1-11
+STR_80E2_DARWIN_100 :Дарвин 100
+STR_80E3_DARWIN_200 :Дарвин 200
+STR_80E4_DARWIN_300 :Дарвин 300
+STR_80E5_DARWIN_400 :Дарвин 400
+STR_80E6_DARWIN_500 :Дарвин 500
+STR_80E7_DARWIN_600 :Дарвин 600
+STR_80E8_GURU_GALAXY :Гуру ГалакÑи
+STR_80E9_AIRTAXI_A21 :ÐертакÑи A21
+STR_80EA_AIRTAXI_A31 :ÐертакÑи A31
+STR_80EB_AIRTAXI_A32 :ÐертакÑи A32
+STR_80EC_AIRTAXI_A33 :ÐертакÑи A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Яте ÐероÑÐ¿ÐµÐ¹Ñ YAe46
+STR_80EE_DINGER_100 :Дингер 100
+STR_80EF_AIRTAXI_A34_1000 :ÐертакÑи A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Яте Z-Shuttle
+STR_80F1_KELLING_K1 :Келинг K1
+STR_80F2_KELLING_K6 :Келинг K6
+STR_80F3_KELLING_K7 :Келинг K7
+STR_80F4_DARWIN_700 :Дарвин 700
+STR_80F5_FFP_HYPERDART_2 :FFP Хипердарт 2
+STR_80F6_DINGER_200 :Дингер 200
+STR_80F7_DINGER_1000 :Дингер 1000
+STR_80F8_PLODDYPHUT_100 :Плодифат 100
+STR_80F9_PLODDYPHUT_500 :Плодифат 500
+STR_80FA_FLASHBANG_X1 :Флашбанг X1
+STR_80FB_JUGGERPLANE_M1 :Джагерплейн M1
+STR_80FC_FLASHBANG_WIZZER :Флашбанг Уизер
+STR_80FD_TRICARIO_HELICOPTER :Трикарио хеликоптер
+STR_80FE_GURU_X2_HELICOPTER :Гуру X2 хеликоптер
+STR_80FF_POWERNAUT_HELICOPTER :Пауернат хеликоптер
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Съобщение от автомобилниÑÑ‚ производител
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}Току-що Ñъздадохме нов {STRING} - бихте ли Ñе ÑъглаÑили не едногодишна употреба на това МПС, за да видим как то работи преди да го пуÑнем на пазара за маÑова употреба?
+STR_8102_RAILROAD_LOCOMOTIVE :локомотив за двурелÑов път
+STR_8103_ROAD_VEHICLE :МПС
+STR_8104_AIRCRAFT :Ñамолет
+STR_8105_SHIP :кораб
+STR_8106_MONORAIL_LOCOMOTIVE :локомотив за еднорелÑов път
+STR_8107_MAGLEV_LOCOMOTIVE :локомотив за магниторелÑов път
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}{TOWN} Влаково депо
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Хората празнуват . . .{}Първи влак приÑтигна на {STATION}!
+STR_8802_DETAILS :{WHITE}{STRING} (ПодробноÑти)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Влак на пътÑ
+STR_8804 :{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8806_GO_TO :Отиди на {STATION}
+STR_8807_GO_TO_TRANSFER :Отиди на {STATION} (Обмени и вземи товар)
+STR_8808_GO_TO_UNLOAD :Отиди на {STATION} (Разтовари)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Отиди на {STATION} (Обмени и не взимай нов товар)
+STR_880A_GO_TO_LOAD :Отиди на {STATION} (Товари)
+STR_880B_GO_TO_TRANSFER_LOAD :Отиди на {STATION} (Обмени и изчакай до пълен товар)
+STR_880C_GO_NON_STOP_TO :Отиди без да Ñпираш на {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Отиди без да Ñпираш на {STATION} (Обмени и вземи товар)
+STR_880E_GO_NON_STOP_TO_UNLOAD :отиди без да Ñпираш на {STATION} (Разтовари)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Отиди без да Ñпираш на {STATION} (Обмени и не товари)
+STR_8810_GO_NON_STOP_TO_LOAD :Отиди без да Ñпираш на {STATION} (Товари)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Отиди без да Ñпираш на {STATION} (Обмени и изчакай до пълен товар)
+STR_GO_TO_TRAIN_DEPOT :Отиди до Влаковото депо на {TOWN}
+STR_SERVICE_AT_TRAIN_DEPOT :Ремонт в {TOWN} влаково депо
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Отиди без да Ñпираш на {TOWN} Влаково депо
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Ремонт без Ñпиране в {TOWN} влаково депо
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}Отиващ към Влаковото депо на {TOWN}
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}Отиващ към Влаковото депо на {TOWN}, {VELOCITY}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE :{LTBLUE}Ðа ремонт във Влаковото депо на {TOWN}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE_VEL :{LTBLUE}Ремонт във Влаковото депо на {TOWN}, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (Ðевалидна заповед)
+
+STR_UNKNOWN_DESTINATION :неизвеÑтна деÑтинациÑ
+STR_8812_EMPTY :{LTBLUE}Празен
+STR_8813_FROM :{LTBLUE}{CARGO} от {STATION}
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}Влакът {COMMA} чака в депото
+STR_8815_NEW_VEHICLES :{BLACK}Ðови МПС-та
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Влакът е прекалено дълъг
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Влаковете могат да бъдат променÑни Ñамо когато Ñа Ñпрени в депото
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} Влак{P "" ове}
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Ðови Машини за ДвурелÑов път
+STR_NEW_ELRAIL_VEHICLES :{WHITE}Ðови електричеÑки влакове
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Ðови Машини за МонорелÑов път
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Ðови Машини за МагниторелÑов път
+STR_881F_BUILD_VEHICLE :{BLACK}Купи Машина
+STR_CLONE_ROAD_VEHICLE :{BLACK}Копиране на превозно ÑредÑтво
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}Така ще бъде поÑтроено копие на пътното превозно ÑредÑтво. ÐатиÑни CTRL за да Ñподелиш задачите
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Така ще бъде поÑтроено копие на пътното превозно ÑредÑтво. ÐатиÑни на този бутон и Ñлед това на пътно превозно ÑредÑтво вътре или вън от депото. ÐатиÑни CTRL за да Ñподелиш задачите
+STR_CLONE_TRAIN :{BLACK}Клониране на влак
+STR_CLONE_TRAIN_INFO :{BLACK}Така ще бъде поÑтроено копие на влака заедно Ñ Ð²Ñички негови вагони. ÐатиÑни CTRL за да Ñподелиш задачите
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}Така ще бъде поÑтроено копие на влака заедно Ñ Ð²Ñички негови вагони. ÐатиÑни на този бутон и Ñлед това на влак вътре или вън от депото. ÐатиÑни CTRL за да Ñподелиш задачите
+STR_8820_RENAME :{BLACK}Преименувай
+STR_8823_SKIP :{BLACK}ОÑтави
+STR_8824_DELETE :{BLACK}Изтрий
+STR_8825_NON_STOP :{BLACK}Без да Ñпира
+STR_8826_GO_TO :{BLACK}Отиди на
+STR_8827_FULL_LOAD :{BLACK}Пълен товар
+STR_8828_UNLOAD :{BLACK}Разтовари
+STR_REFIT :{BLACK}ПреуÑтройÑтво
+STR_REFIT_TIP :{BLACK}Избор какво преуÑтройÑто да Ñе направи. Щракване ÑÑŠÑ Ð·Ð°Ð´ÑŠÑ€Ð¶Ð°Ð½ контрол премахва инÑтрукциÑта
+STR_REFIT_ORDER :(ПреуÑтройÑтво към {STRING})
+STR_8829_ORDERS :{WHITE}{VEHICLE} (Заповеди)
+STR_882A_END_OF_ORDERS :{SETX 10}- - Край на Заповедите - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}Ремонт
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Ðе може да купиш ЖП машина...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Купи: {LTBLUE}{NUM}{BLACK} Цена: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Цена: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}Товарене/ Разтоварване
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}Влакът Ñ‚Ñ€Ñбва да бъде ÑпрÑн в депото
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Ðе може да пратиш влака в депото...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}ÐÑма повече мÑÑто за още заповеди
+STR_8832_TOO_MANY_ORDERS :{WHITE}Прекалено много заповеди
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Ðе може да зададеш нова заповед...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Ðе може да изтриеш тази заповед...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Ðе може да промениш тази заповед...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Ðе може да премеÑтиш машината...
+STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}Ð—Ð°Ð´Ð½Ð¸Ñ Ð»Ð¾ÐºÐ¾Ð¼Ð¾Ñ‚Ð¸Ð² ще Ñледва винаги Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ñи Ñъбрат
+STR_8838_N_A :Ðе Ñе предлага{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Ðе може да продадеш ЖП машината...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Ðе може да намери маршрута до меÑтното депо
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Ðе може да Ñпреш/пуÑнеш влака...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Дни на обÑлужване: {LTBLUE}{COMMA}дни{BLACK} ПоÑледно облужване: {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Интервал на ремонт: {LTBLUE}{COMMA}%{BLACK} ПоÑледен ремонт: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Влакове - кликни върху нÑкой влак за повече информациÑ
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Купи нови влакове (изиÑква влаково депо)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Влакове - кликни върху нÑкой влак за повече информациÑ, домъкни машина за да Ñ Ð´Ð¾Ð²Ð°Ð²Ð¸Ñˆ/премахнеш от влака
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Купи нова ЖП машина
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Домъкни ЖП машина тук, за да Ñ Ð¿Ñ€Ð¾Ð´Ð°Ð´ÐµÑˆ
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}ФокуÑирай върху мÑÑтото на влаковото депо
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}СпиÑък Ñ Ð²Ð»Ð°ÐºÐ¾Ð²Ðµ - натиÑни върху влак за информациÑ
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Строене на Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ Ð²Ð»Ð°Ðº
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Преименуване на влак
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Текущо ÑъщоÑние на влака - натиÑнете за Ñпиране/пуÑкане
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Пътен лиÑÑ‚
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Центриране Ð³Ð»Ð°Ð²Ð½Ð¸Ñ Ð¿Ñ€Ð¾Ð·Ð¾Ñ€ÐµÑ† върху влака
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Изпращане влака в депо
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Игнориране на Ñемафор
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Обръщане поÑоката на влака
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Показва Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° влака
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Увеличава интервалa за Ñервиз
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}ÐамалÑва интервал за Ñервиз
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° Ð¿Ñ€ÐµÐ²Ð¾Ð·Ð²Ð°Ð½Ð¸Ñ Ñ‚Ð¾Ð²Ð°Ñ€
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° влаковата композициÑ
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Капацитет на влаковата композициÑ
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Общ капацитет на влака, разбит по типове товар
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Пътен лиÑÑ‚ - натиÑнете върху назначение за маркиране. CTRL + натиÑкане - центрира върху ÑтанциÑта
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}ПреÑкачане на текущото назначение и наÑочване към Ñледващото
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Изтриване на избраното назначение
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Преминавай през избраното назначение без Ñпиране
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}ДобавÑне на назначение преди избраната или в ÐºÑ€Ð°Ñ Ð½Ð° ÑпиÑъка
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Изчакай на избраното назначение до пълно зареждане Ñ Ñ‚Ð¾Ð²Ð°Ñ€
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Разтоварва на избраното назначение Ñ†ÐµÐ»Ð¸Ñ Ñ‚Ð¾Ð²Ð°Ñ€
+STR_SERVICE_HINT :{BLACK}ПропуÑни оÑвен ако е необходим ремонт
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}Ðов {STRING} вече е доÑтъпен!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Цена: {CURRENCY} Тегло: {WEIGHT_S}{}СкороÑÑ‚: {VELOCITY} МощноÑÑ‚: {POWER}{}Разход: {CURRENCY}/г.{}Капацитет: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}Развален
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}ВъзраÑÑ‚: {LTBLUE}{STRING}{BLACK} Оперативни разходи: {LTBLUE}{CURRENCY}/г.
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Тегло: {LTBLUE}{WEIGHT_S} {BLACK}МощноÑÑ‚: {LTBLUE}{POWER}{BLACK} МакÑимална ÑкороÑÑ‚: {LTBLUE}{VELOCITY}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Приход тази година: {LTBLUE}{CURRENCY} (предходна: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}ÐадеждноÑÑ‚: {LTBLUE}{COMMA}% {BLACK}РазвалÑÐ½Ð¸Ñ Ñлед поÑÐ»ÐµÐ´Ð½Ð¸Ñ Ñервиз: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}СпрÑн
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Влака не може да пропуÑне Ñигнала при опаÑноÑÑ‚...
+STR_8863_CRASHED :{RED}КатаÑтрофа!
+
+STR_8865_NAME_TRAIN :{WHITE}Име на влак
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}Ðе може да Ñложи име...
+STR_8867_NAME_TRAIN :{BLACK}Име на влак
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Влакова катаÑтрофа!{}{COMMA} умрели в огнената екÑплозиÑ
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Ðе може да обърне поÑоката на влак...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Преименуване на влак
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Ðе може да Ñе преименува влак...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}ИзхвърлÑне на товара при доÑтигане на избраното назначение
+STR_886F_TRANSFER :{BLACK}Транфер
+
+STR_TRAIN_STOPPING :{RED}Спира
+STR_TRAIN_STOPPING_VEL :{RED}Спира, {VELOCITY}
+STR_INCOMPATIBLE_RAIL_TYPES :ÐеÑъвмеÑтими ЖП линии
+STR_TRAIN_NO_POWER :{RED}ÐÑма мощноÑÑ‚
+STR_TRAIN_START_NO_CATENARY :Влака не може да тръгне, защото ЖП линиÑта нÑма catenary
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Кола на пътÑ
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} Кол{P а и}
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}{TOWN} гараж за коли
+STR_9004_NEW_VEHICLES :{BLACK}Ðово превозно ÑредÑтво
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}Ðова кола
+STR_9007_BUILD_VEHICLE :{BLACK}Покупка на превозно ÑредÑтво
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Ðе може да купи кола...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (ИнформациÑ)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}ВъзраÑÑ‚: {LTBLUE}{STRING}{BLACK} Разход: {LTBLUE}{CURRENCY}/г.
+STR_900E_MAX_SPEED :{BLACK}МакÑ. ÑкороÑÑ‚: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Печалба тази година: {LTBLUE}{CURRENCY} (предходна година: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}ÐадеждноÑÑ‚: {LTBLUE}{COMMA}% {BLACK}Повреди от поÑÐ»ÐµÐ´Ð½Ð¸Ñ Ñервиз: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} ПроизводÑтво: {LTBLUE}{NUM}{BLACK} СтойноÑÑ‚: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Капацитет: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}...Ñ‚Ñ€Ñбва да бъде ÑпрÑно в Ñервиз за коли
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Ðе може да продаде колата...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Ðе може да пуÑне/Ñпре колата...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}Кола {COMMA} чака в Ñервиз
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}Отиващ към Ðвтодепото на {TOWN}
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}Отиващ към Ðвтодепото на {TOWN}, {VELOCITY}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE :{LTBLUE}Ðа ремонт в Ðвтодепото на {TOWN}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE_VEL :{LTBLUE}Ðа ремонт в Ðвтодепото на {TOWN}, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Ðе може да изпрати колата в Ñервиз...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Ðе може да намери Ð»Ð¾ÐºÐ°Ð»Ð½Ð¸Ñ Ñервиз
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Коли - натиÑнете върху кола за информациÑ
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Покупка на коли (Ñ‚Ñ€Ñбва Ñервиз за коли)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Текущо дейÑтвие - натиÑнете за Ñпиране/пуÑкане на превозното ÑредÑтво
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Пътен лиÑÑ‚
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Центриране на Ð³Ð»Ð°Ð²Ð½Ð¸Ñ Ð¿Ñ€Ð¾Ð·Ð¾Ñ€ÐµÑ† върху превозното ÑредÑтво
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Прати МПС-то в депото
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Ðакарай МПС-то да обърне
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Покажи детайлите на МПС-то
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}МПС-та - натиÑни върху МПС за информациÑ
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Купи ново МПС
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}ПремеÑти МПС-то тук, за да го продадеш
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}ФокуÑирай Ð¾Ð±Ñ‰Ð¸Ñ Ð¿Ð»Ð°Ð½ върху меÑтонахождението на МПС-депото
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}СпиÑък Ñ Ð¸Ð·Ð±Ð¾Ñ€ на МПС-та - натиÑни върху МПС за информациÑ
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Купи поÑоченото МПС
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}Ðово МПС излезе на пазара!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Цена: {CURRENCY}{}СкороÑÑ‚: {VELOCITY}{}Оперативен разход: {CURRENCY}/год{}ВмеÑтимоÑÑ‚: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Преименувай МПС-то
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Ðе може да преименуваш МПС-то...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Преименувай МПС-то
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Хората празнуват . . .{}Първи Ð°Ð²Ñ‚Ð¾Ð±ÑƒÑ Ð¿Ñ€Ð¸Ñтигна на {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Хората празнуват . . .{}Първи камион приÑтигна на {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}Пътно-транÑпортно ПроизшеÑтвие!{}Шофьор загина на мÑÑто при ÐµÐºÐ¿Ð»Ð¾Ð·Ð¸Ñ Ð½Ð° МПС Ñлед ÑблъÑък Ñ Ð²Ð»Ð°Ðº
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}Пътно-транÑпортно ПроизшеÑтвие!{}{COMMA} загинаха на мÑÑто при ÐµÐºÐ¿Ð»Ð¾Ð·Ð¸Ñ Ð½Ð° МПС Ñлед ÑблъÑък Ñ Ð²Ð»Ð°Ðº
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Ðе може да обърнеш МПС-то...
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}Ðе може да обърне превозно ÑредÑтво ÑÑŠÑтоÑщо Ñе от нÑколко елемента
+STR_9034_RENAME :{BLACK}Преименувай
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Преименувай МПС-то
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Преименувай МПС-то
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Ðе може да преименуваш МПС-то...
+STR_9038_GO_TO_ROADVEH_DEPOT :Отиди в {TOWN} МПС-депото
+STR_SERVICE_AT_ROADVEH_DEPOT :Ремонт в {TOWN} гараж
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Преоборудване автомобила за друг товар
+STR_REFIT_ROAD_VEHICLE :{BLACK}Проборудване на автомобила
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Преоборудване на автомобила за Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ Ñ‚Ð¾Ð²Ð°Ñ€
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Преоборудването на автомобила е невъзможно...
+STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Избор тип това за автомобила да превозва
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Създаване на ПриÑтанище
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Създаване на ПриÑтанище
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Ðе може да поÑтроиш приÑтанище тук...
+STR_9803_SHIP_DEPOT :{WHITE}{TOWN} Корабно депо
+STR_9804_NEW_SHIPS :{BLACK}Ðови Кораби
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} Кораб{P "" и}
+STR_9808_NEW_SHIPS :{WHITE}Ðови Кораби
+STR_9809_BUILD_SHIP :{BLACK}Купи Кораб
+STR_CLONE_SHIP :{BLACK}Клониране на кораб
+STR_CLONE_SHIP_INFO :{BLACK}Така ще бъде поÑтроено копие на кораб. ÐатиÑни CTRL за да Ñподелиш задачите
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}Така ще бъде поÑтроено копие на кораб. ÐатиÑни този бутон и Ñлед това върху кораб вътре или вън от депото. ÐатиÑни CTRL за да Ñподелиш задачите
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}Корабът Ñ‚Ñ€Ñбва да е ÑпрÑн в депото
+STR_980C_CAN_T_SELL_SHIP :{WHITE}Ðе може да продадеш кораба...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Ðе може да купиш кораба...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Кораб на пътÑ
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Детайли)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}ВъзраÑÑ‚: {LTBLUE}{STRING}{BLACK} Оперативни разходи: {LTBLUE}{CURRENCY}/год
+STR_9813_MAX_SPEED :{BLACK}МакÑ. ÑкороÑÑ‚: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Печалба тази година: {LTBLUE}{CURRENCY} (миналата година: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}ÐадеждноÑÑ‚: {LTBLUE}{COMMA}% {BLACK}Повреди Ñлед поÑÐ»ÐµÐ´Ð½Ð¸Ñ Ñервиз: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Купен: {LTBLUE}{NUM}{BLACK} Цена: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}ВмеÑтимоÑÑ‚: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}Ðе може да Ñпреш/задвижиш кораба...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Ðе може да пратиш кораба в депото...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Ðе може да намери меÑтното депо
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}Отиващ към Корабното депо на {TOWN}
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}Отиващ към Корабното депо на {TOWN}, {VELOCITY}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE :{LTBLUE}Ðа ремонт в Корабното депо на {TOWN}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE_VEL :{LTBLUE}Ðа ремонт в Корабното депо на {TOWN}, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}Кораб {COMMA} чака в депото
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Създай ПриÑтанище
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Създай Корабно Депо (за закупуване и обÑлужване на кораби)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Кораби - натиÑни върху кораб за инфорамциÑ
+STR_9820_BUILD_NEW_SHIP :{BLACK}Купи нов кораб
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}ПремеÑти кораба тук, за да го продадеш
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}ФокуÑирай Ð¾Ð±Ñ‰Ð¸Ñ Ð¿Ð»Ð°Ð½ върху меÑтонахождението на корабното депо
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Кораби - натиÑни върху кораб за информациÑ
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Купи нови кораби (необходимо е корабно депо)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}СпиÑък Ñ Ð¸Ð·Ð±Ð¾Ñ€ на кораби - натиÑни върху кораб за информациÑ
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Купи поÑочениÑÑ‚ кораб
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}ÐаÑтоÑщо корабно дейÑтвие - натиÑни тук, за да Ñпреш/задвижиш кораба
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Покажи заповедите на кораба
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}ФокуÑирай Ð¾Ð±Ñ‰Ð¸Ñ Ð¿Ð»Ð°Ð½ върху меÑтонахождението на кораба
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Прати кораба в депото
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Покажи детайлите за кораба
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}Ðов кораб излезе на пазара!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Cost: {CURRENCY} МакÑ. СкороÑÑ‚: {VELOCITY}{}ВмеÑтимоÑÑ‚: {CARGO}{}Разход: {CURRENCY}/год.
+STR_982F_NAME_SHIP :{BLACK}Ðаименувай кораба
+
+STR_9831_NAME_SHIP :{WHITE}Ðаименувай кораба
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Ðе може да наименуваш кораба...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Гражданите празнуват . . .{}ÐŸÑŠÑ€Ð²Ð¸Ñ ÐºÐ¾Ñ€Ð°Ð± приÑтигнал в {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}ПоÑтавете шамандура, използва Ñе като отправна точка
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Ðе може да поÑтави шамандура...
+STR_9836_RENAME :{BLACK}ПромÑна на име
+STR_9837_RENAME_SHIP_TYPE :{BLACK}ПромÑна името на кораб
+STR_9838_RENAME_SHIP_TYPE :{WHITE}ПромÑна името на кораба
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Ðе може да Ñмени името на кораба...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}ПреуÑтройване на товарен кораб за друг тип товар
+STR_983B_REFIT :{WHITE}{VEHICLE} (ПреуÑтройване)
+STR_983C_REFIT_SHIP :{BLACK}ПреуÑтройване на кораб
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Избор на вид товар за превоз от кораба
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}ПреуÑтройване на кораба да превозва Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ Ð²Ð¸Ð´ товар
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Изберете вид товар за превозване:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Ðов капацитет: {GOLD}{CARGO}{}{BLACK}Цена за преуÑтройÑтво: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Ðе може да преуÑтрои кораб...
+STR_9842_REFITTABLE :(преуÑтроим)
+STR_GO_TO_SHIP_DEPOT :Отиди до Корабното депо до {TOWN}
+SERVICE_AT_SHIP_DEPOT :Сервиз на {TOWN} док
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Летища
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Ðе може да поÑтрои летище...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} хангар за Ñамолети
+STR_A003_NEW_AIRCRAFT :{BLACK}Ðово летище
+STR_CLONE_AIRCRAFT :{BLACK}Клониране на летателен апарат
+STR_CLONE_AIRCRAFT_INFO :{BLACK}Така ще бъде поÑтроено копие на Ð»ÐµÑ‚Ð°Ñ‚ÐµÐ»Ð½Ð¸Ñ Ð°Ð¿Ð°Ñ€Ð°Ñ‚. ÐатиÑни CTRL за да Ñподелиш задачите
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Така ще бъде поÑтроено копие на Ð»ÐµÑ‚Ð°Ñ‚ÐµÐ»Ð½Ð¸Ñ Ð°Ð¿Ð°Ñ€Ð°Ñ‚. ÐатиÑни на този бутон и Ñлед това на летателен апарат вътре или вън от хангара. ÐатиÑни CTRL за да Ñподелиш задачите
+STR_A005_NEW_AIRCRAFT :{WHITE}Ðово Ñамолет
+STR_A006_BUILD_AIRCRAFT :{BLACK}Строене на Ñамолет
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Ðе може да поÑтрои Ñамолет...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} Самолет
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (Маршрут)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (ИнформациÑ)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}ВъзраÑÑ‚: {LTBLUE}{STRING}{BLACK} Разход: {LTBLUE}{CURRENCY}/г.
+STR_A00E_MAX_SPEED :{BLACK}МакÑ. ÑкороÑÑ‚: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Печалба тази година: {LTBLUE}{CURRENCY} (предходната: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}ÐадеждноÑÑ‚: {LTBLUE}{COMMA}% {BLACK}Повреди от поÑÐ»ÐµÐ´Ð½Ð¸Ñ Ñервиз: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Произведен: {LTBLUE}{NUM}{BLACK} СтойноÑÑ‚: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Ðе може да изпрати Ñамолета в хангар...
+STR_HEADING_FOR_HANGAR :{ORANGE}Отиващ към Хангара на летище {STATION}
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}Отиващ към Хангара на летище {STATION}, {VELOCITY}
+STR_HEADING_FOR_HANGAR_SERVICE :{LTBLUE}Ðа ремонт в Хангара на летище {STATION}
+STR_HEADING_FOR_HANGAR_SERVICE_VEL :{LTBLUE}Ðа ремонт в Хангара на летище {STATION}, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}Самолет {COMMA} чака в хангар
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Самолет на пътÑ
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Ðе може да Ñпре/пуÑне Ñамолет...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Самолета е във въздуха
+STR_A019_CAPACITY :{BLACK}Капацитет: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Капацитет: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}Самолета Ñ‚Ñ€Ñбва да бъде ÑпрÑн в хангар
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Ðе може да продаде Ñамолета...
+STR_A01D_AIRPORT_CONSTRUCTION :Строене на летище
+STR_A01E_BUILD_AIRPORT :{BLACK}Строене на летище
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Самолет - натиÑнете върху Ñамолет за информациÑ
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Строене на Ñамолет (необходимо е летище Ñ Ñ…Ð°Ð½Ð³Ð°Ñ€)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Самолет - натиÑнете върху Ñамолет за информациÑ
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Строене на Ñамолет
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}ПремеÑтете Ñамолет тук за да го продадете
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Центриране на Ð³Ð»Ð°Ð²Ð½Ð¸Ñ Ð¿Ñ€Ð¾Ð·Ð¾Ñ€ÐµÑ† върху хангара
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Избор на Ñамолет - натиÑнете върху Ñамолет за информациÑ
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Строене на Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ Ñамолет
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}СъÑтоÑние на Ñамолета - натиÑнете за Ñпиране/пуÑкане
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Маршрут на Ñамолета
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Центриране на Ð³Ð»Ð°Ð²Ð½Ð¸Ñ Ð¿Ñ€Ð¾Ð·Ð¾Ñ€ÐµÑ† върху Ñамолета
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Изпращане на Ñамолета в хангар
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° Ñамолета
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}Ðов Ñамолет е доÑтъпен!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Цена: {CURRENCY} МакÑ. ÑкороÑÑ‚: {VELOCITY}{}Капацитет: {COMMA} пътника, {COMMA} чувала поща{}Разход: {CURRENCY}/г.
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Име на Ñамолет
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Ðе може да нарече Ñамолета...
+STR_A032_NAME_AIRCRAFT :{BLACK}Име на Ñамолет
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Гражданите празнуват . . .{}ÐŸÑŠÑ€Ð²Ð¸Ñ Ñамолет кацнал на {STATION}!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Самолетна катаÑтрофа!{}{COMMA} умират в Ð¾Ð³ÑŠÐ½Ñ Ð½Ð° {STATION}
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Самолетна катаÑтрофа!{}Самолета оÑтана без гориво, {COMMA} умрÑха в огненото кълбо!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}СмÑна на името
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}СмÑна името на Ñамолета
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}СнÑна името на Ñамолета
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Ðе може да Ñе Ñмени името на Ñамолета...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}ПреуÑтройване на Ñамолета за превоз на друг товар
+STR_A03C_REFIT :{WHITE}{VEHICLE} (ПреуÑтрой)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}ПреуÑтрой Ñамолета
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Избор какъв тип товар да превозва Ñамолета
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}ПреуÑтрой Ñамолета да превозва поÑÐ¾Ñ‡ÐµÐ½Ð¸Ñ Ñ‚Ð¸Ð¿ товар
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Избор тип товар за превозване:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Ðова вмеÑтимоÑÑ‚: {GOLD}{STRING}{}{BLACK}Цена на преуÑтройÑтвото: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Ðе може да Ñе преуÑтрои Ñамолета...
+STR_GO_TO_AIRPORT_HANGAR :Отиди до Хангара на летище {STATION}
+SERVICE_AT_AIRPORT_HANGAR :Сервиз в {STATION} хангар
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}КатаÑтрофа Ñ Ð¦ÐµÐ¿ÐµÐ»Ð¸Ð½ на {STATION}!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}МПС бе унищожено при ÑблъÑък Ñ ÐЛО!
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}Ð•ÐºÐ¿Ð»Ð¾Ð·Ð¸Ñ Ð² нефтена Ñ€Ð°Ñ„Ð¸Ð½ÐµÑ€Ð¸Ñ Ð±Ð»Ð¸Ð·Ð¾ до {TOWN}!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}Фабрика бе унищожена при Ñъмнителни обÑтоÑтелÑтва близо до {TOWN}!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}ÐЛО кацна близо до {TOWN}!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}Срутване на мина за въглища оÑтави Ñледи от разрушение близо до {TOWN}!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}ÐаводнениÑ!{}Ðай-малко {COMMA} Ñа изчезнали, Ñчитат Ñе за загинали Ñлед значителни наводнениÑ!
+
+STR_BRIBE_FAILED :{WHITE}ТвоÑÑ‚ опит за подкуп беше
+STR_BRIBE_FAILED_2 :{WHITE}разкрит от меÑтен дознател
+STR_BUILD_DATE :{BLACK}ПоÑтроен: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Подробна оценка на предÑтавÑнето
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}ПодробноÑти
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Превозни ÑредÑтва:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Станции:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Мин. печалба:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Мин. приход:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}МакÑ. приход:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}ДоÑтавено:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Товар:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Пари:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Заем:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Общо:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Брой превозни ÑредÑтва; това включва автомобили, влакове, кораби и Ñамолети
+STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}Брой Ñтанции. Ð’ÑÑка чаÑÑ‚ на ÑÑ‚Ð°Ð½Ñ†Ð¸Ñ (напр. ЖП гара, автогара, летище) Ñе брои отделно, даже ако Ñа Ñвързани като една ÑтанциÑ
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}Печалбата на превозното ÑредÑтво Ñ Ð½Ð°Ð¹-ниÑък доход (от вÑички на поне 2 години)
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Сумата пари Ñпечелена през меÑеца Ñ Ð½Ð°Ð¹-ниÑка печалба от поÑледните 12 четвъртини
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Сумата пари Ñпечелена през меÑеца Ñ Ð½Ð°Ð¹-виÑока печалба от поÑледните 12 четвъртини
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}Единици товар доÑтавени през поÑледната година
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}Брой различни видове товари доÑтавени през поÑледните 4 меÑеца
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Сума пари тази ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ñ Ð¸Ð¼Ð° в банката
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}Сума пари тази ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ñ Ðµ вÑела от банката
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Ðатрупани точки от Ð¾Ð±Ñ‰Ð¸Ñ Ð²ÑŠÐ·Ð¼Ð¾Ð¶ÐµÐ½ брой
+
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}Newgrf наÑтройки
+STR_NEWGRF_APPLY_CHANGES :{BLACK}Прилагане на промените
+STR_NEWGRF_SET_PARAMETERS :{BLACK}ÐаÑтройване на параметрите
+STR_NEWGRF_TIP :{BLACK}СпиÑък Ñ Ð²Ñички инÑталирани Newgrf пакети. ÐатиÑни на пакет за промÑна на наÑтройките
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}Ð’ момента нÑма инÑталирани newgrf файлове! ÐœÐ¾Ð»Ñ Ð¾Ð±ÑŠÑ€Ð½ÐµÑ‚Ðµ Ñе към наръчника за инÑтрукции по инÑталирането на нова графика
+STR_NEWGRF_FILENAME :{BLACK}Име на файл: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
+
+STR_CURRENCY_WINDOW :{WHITE}Поръчкова валута
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Обменен курÑ: {ORANGE}{CURRENCY} = £ {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Разделител:
+STR_CURRENCY_PREFIX :{LTBLUE}ПредÑтавка:
+STR_CURRENCY_SUFFIX :{LTBLUE}ÐадÑтавка:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Преобразуване в евро: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Преобразуване в евро: {ORANGE}никога
+STR_CURRENCY_PREVIEW :{LTBLUE}Преглед: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}ПромÑна параметрите на поръчкова валута
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} Влак{P "" ове}
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} Ðвтомобил{P "" и}
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} Самолет{P "" и}
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} Кораб{P "" и}
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Показване на вÑички влакове които минават през гарата
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Показване на вÑички автомобили които минават през гарата
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Показване на вÑички Ñамолети които кацат на летището
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Показване на вÑички кораби които Ñпират на приÑтанището
+
+STR_VEH_WITH_SHARED_ORDERS_LIST :{WHITE}Споделено разпиÑание Ñ {COMMA} превозн{P о и} ÑредÑÑ‚{P о а}
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}Показване на вÑички превозни ÑредÑтва които ÑподелÑÑ‚ разпиÑанието
+
+### depot strings
+STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP :{BLACK}Продажба вÑички влакове в депото
+STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP :{BLACK}Продажба вÑички автомобили в гаража
+STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP :{BLACK}Продажба вÑички кораби в депото
+STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP :{BLACK}Продажба вÑички Ñамолети в хангара
+
+STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP :{BLACK}СпиÑък на вÑички влакове Ñ Ñ‚Ð¾Ð²Ð° депо в Ñ‚ÐµÑ…Ð½Ð¸Ñ Ð¿ÑŠÑ‚ÐµÐ½ лиÑÑ‚
+STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP :{BLACK}СпиÑък на вÑички автомобили Ñ Ñ‚Ð¾Ð·Ð¸ гараж в Ñ‚ÐµÑ…Ð½Ð¸Ñ Ð¿ÑŠÑ‚ÐµÐ½ лиÑÑ‚
+STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP :{BLACK}СпиÑък на вÑички кораби Ñ Ñ‚Ð¾Ð²Ð° депо в Ñ‚ÐµÑ…Ð½Ð¸Ñ Ð¿ÑŠÑ‚ÐµÐ½ лиÑÑ‚
+STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP :{BLACK}СпиÑък на вÑички Ñамолети Ñ Ñ…Ð°Ð½Ð³Ð°Ñ€ на това летище в Ñ‚ÐµÑ…Ð½Ð¸Ñ Ð¿ÑŠÑ‚ÐµÐ½ лиÑÑ‚
+
+STR_DEPOT_AUTOREPLACE_TRAIN_TIP :{BLACK}Ðвтоматична замÑна на вÑички влакове в депото
+STR_DEPOT_AUTOREPLACE_ROADVEH_TIP :{BLACK}Ðвтоматична замÑна на вÑички автомобили в депото
+STR_DEPOT_AUTOREPLACE_SHIP_TIP :{BLACK}Ðвтоматична замÑна на вÑички кораби в депото
+STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP :{BLACK}Ðвтоматична замÑна на вÑички Ñамолети в хангара
+
+STR_VEHICLE_LIST_TRAIN_DEPOT :{BLACK}{STRING} - {COMMA} Влак{P "" ове}
+STR_VEHICLE_LIST_ROADVEH_DEPOT :{BLACK}{STRING} - {COMMA} Ðвтомобил{P "" и}
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} Кораб{P "" и}
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} Самолет{P "" и}
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}ЗамÑна {STRING}
+STR_REPLACE_VEHICLES_START :{BLACK}Започване замÑната
+STR_REPLACE_VEHICLES_STOP :{BLACK}Спиране на замÑната
+STR_NOT_REPLACING :{BLACK}ÐезаменÑ
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}ÐÑма избрани превозни ÑредÑтва
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Избор на нов двигател за замÑната
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Изберете нов двигател, който бихте желали да поÑтавите на мÑÑтото на Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ Ð² лÑво двигател
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}ÐатиÑнете за Ñпиране подновÑването на Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ Ð² лÑво двигател
+STR_REPLACE_HELP_START_BUTTON :{BLACK}ÐатиÑнете за започване подмÑната на лÑво Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ Ð´Ð²Ð¸Ð³Ð°Ñ‚ÐµÐ» Ñ Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ Ð² дÑÑно
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Избор на ЖП Ð»Ð¸Ð½Ð¸Ñ Ñ ÐºÐ¾Ñто да Ñе заменÑÑ‚ локомотивите
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Показване Ñ ÐºÐ¾Ð¹ двигател Ñе Ð·Ð°Ð¼ÐµÐ½Ñ Ð»Ñво избраниÑ, ако има
+STR_REPLACE_HELP :{BLACK}От тук можете да заменÑте един локомотив Ñ Ð´Ñ€ÑƒÐ³, когато локомотиви от Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ Ñ‚Ð¸Ð¿ влÑзат в депо
+STR_REPLACE_REMOVE_WAGON :{BLACK}Премахване на вагон: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Ðвтоматичната замÑна ще запази дължината на влака като премахне вагони (започвайки от предните), ако замÑната довежда до по-дълъг влак.
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}ЗамÑна: {ORANGE}{SKIP}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} ЕКСПЕРИМЕÐТÐЛÐРВЪЗМОЖÐОСТ {}Превключване между замÑна на локомотиви и вагони.{}ЗамÑната на вагони ще бъде направена Ñамо ако Ð½Ð¾Ð²Ð¸Ñ Ñ‚Ð¸Ð¿ вагони може да Ñе преуÑтрои да превозва ÑÑŠÑ‰Ð¸Ñ Ñ‚Ð¸Ð¿ товар като Ñтарите. Това Ñе проверÑва за вÑеки вагон когато замÑната Ñе Ñлучва.
+STR_ENGINE_NOT_BUILDABLE :{WHITE}Ð”Ð²Ð¸Ð³Ð°Ñ‚ÐµÐ»Ñ Ð½Ðµ е Ñтроим
+
+STR_ENGINES :Двигатели
+STR_WAGONS :Вагони
+
+STR_MASS_STOP_DEPOT_TRAIN_TIP :{BLACK}Спиране на вÑички влакове в депото
+STR_MASS_STOP_DEPOT_ROADVEH_TIP :{BLACK}Спиране на вÑички автомобили в гаража
+STR_MASS_STOP_DEPOT_SHIP_TIP :{BLACK}Спиране на вÑички кораби в депото
+STR_MASS_STOP_HANGAR_TIP :{BLACK}Спиране на вÑички Ñамолети в хангара
+
+STR_MASS_START_DEPOT_TRAIN_TIP :{BLACK}Стартиране на вÑички влакове в депото
+STR_MASS_START_DEPOT_ROADVEH_TIP :{BLACK}Стартиране на вÑички автомобили в депото
+STR_MASS_START_DEPOT_SHIP_TIP :{BLACK}Стартиране на вÑички кораби в депото
+STR_MASS_START_HANGAR_TIP :{BLACK}Стартиране на вÑички Ñамолети в хангара
+
+STR_MASS_STOP_LIST_TIP :{BLACK}Спиране на вÑички превозни ÑредÑтва в ÑпиÑъка
+STR_MASS_START_LIST_TIP :{BLACK}Стартиране на вÑички превозни ÑредÑтва в ÑпиÑъка
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}СпиÑък Ñ Ñ‚Ð°Ð±ÐµÐ»Ð¸ - {COMMA} Табел{P а и}
+
+STR_ORDER_REFIT_FAILED :{WHITE}ПреуÑтройÑтвото не може да Ñе направи защото {STRING} {COMMA}
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :ЖП влакове
+STR_ELRAIL_VEHICLES :ЕлектричеÑки локомотиви
+STR_MONORAIL_VEHICLES :МонорелÑови локомотиви
+STR_MAGLEV_VEHICLES :Маглев влакове
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Цема: {GOLD}{CURRENCY}{BLACK} Тегло: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}СкороÑÑ‚: {GOLD}{VELOCITY}{BLACK} МощноÑÑ‚: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}СкороÑÑ‚: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Разход: {GOLD}{CURRENCY}/год.
+STR_PURCHASE_INFO_CAPACITY :{BLACK}Капацитет: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Модел: {GOLD}{NUM}{BLACK} Живот: {GOLD}{COMMA} години
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}МакÑ. надеждноÑÑ‚: {GOLD}{COMMA}%
+STR_PURCHASE_INFO_COST :{BLACK}Цена: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Тегло: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Цема {GOLD}{CURRENCY}{BLACK} СкороÑÑ‚: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Капацитет: {GOLD}{COMMA} паÑажера, {COMMA} пощенÑки чувала
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Вагони Ñ Ð¼Ð¾Ñ‰Ð½Ð¾ÑÑ‚: {GOLD}+{POWER}{BLACK} Тегло: {GOLD}+{WEIGHT_S}
+STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Преобразуваем до: {GOLD}
+STR_PURCHASE_INFO_ALL_TYPES :Ð’Ñички видове товар
+STR_PURCHASE_INFO_ALL_BUT :Ð’Ñички оÑвен {GOLD}
+
+########### String for New Landscape Generator
+
+STR_GENERATE :{WHITE}Генериране
+STR_RANDOM :{BLACK}СлучайноÑÑ‚
+STR_RANDOM_HELP :{BLACK}ПромÑна на ÑлучайноÑтта използване за генериране на терен
+STR_WORLD_GENERATION_CAPTION :{WHITE}Световна генерациÑ
+STR_RANDOM_SEED :{BLACK}Семе на ÑлучайноÑÑ‚:
+STR_RANDOM_SEED_HELP :{BLACK}ÐатиÑнете за въвеждане Ñеме на ÑлучайноÑÑ‚
+STR_LAND_GENERATOR :{BLACK}Генератор на земÑ:
+STR_TREE_PLACER :{BLACK}Ðлгоритъм за дървета:
+STR_HEIGHTMAP_ROTATION :{BLACK}Завъртане на виÑочинна карта:
+STR_TERRAIN_TYPE :{BLACK}Тип на терен:
+STR_QUANTITY_OF_SEA_LAKES :{BLACK}МорÑко ниво:
+STR_SMOOTHNESS :{BLACK}ЗагладеноÑÑ‚:
+STR_SNOW_LINE_HEIGHT :{BLACK}ВиÑочина на Ñнежната линиÑ:
+STR_DATE :{BLACK}Дата:
+STR_NUMBER_OF_TOWNS :{BLACK}Брой градове:
+STR_NUMBER_OF_INDUSTRIES :{BLACK}Брой индуÑтрии:
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_SNOW_LINE_UP :{BLACK}ПремеÑтване Ñнежната Ð»Ð¸Ð½Ð¸Ñ Ð½Ð°Ð³Ð¾Ñ€Ðµ
+STR_SNOW_LINE_DOWN :{BLACK}ПремеÑтване Ñнежната Ð»Ð¸Ð½Ð¸Ñ Ð½Ð°Ð´Ð¾Ð»Ñƒ
+STR_SNOW_LINE_QUERY_CAPT :{WHITE}ВиÑочина на Ñнежната линиÑ
+STR_START_DATE_QUERY_CAPT :{WHITE}ПромÑна началната година
+STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Мащаб предупреждение
+STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Прекаленото оразмерÑване не е препорачително. Продължаване Ñ Ð³ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñта?
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_HEIGHTMAP_NAME :{BLACK}Име на виÑочинна карта:
+STR_HEIGHTMAP_SIZE :{BLACK}Размер: {ORANGE}{NUM} x {NUM}
+STR_GENERATION_WORLD :{WHITE}Създаване на ÑвÑÑ‚...
+STR_GENERATION_ABORT :{BLACK}ПрекъÑване
+STR_GENERATION_ABORT_CAPTION :{WHITE}ПрекъÑване генерирането на ÑвÑÑ‚
+STR_GENERATION_ABORT_MESSAGE :{YELLOW}Потвърдете прекъÑването на генерациÑта?
+STR_PROGRESS :{WHITE}{NUM}% готово
+STR_GENERATION_PROGRESS :{BLACK}{NUM} / {NUM}
+STR_WORLD_GENERATION :{BLACK}Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ Ð½Ð° ÑвÑÑ‚
+STR_TREE_GENERATION :{BLACK}Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ Ð½Ð° дърва
+STR_UNMOVABLE_GENERATION :{BLACK}Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ Ð½Ð° Ñтатични
+STR_CLEARING_TILES :{BLACK}Създаване на твърда и Ñкална повърноÑÑ‚
+STR_SETTINGUP_GAME :{BLACK}ÐаÑтройка на играта
+STR_PREPARING_TILELOOP :{BLACK}ИзпълнÑване цикъл на плочките
+STR_PREPARING_GAME :{BLACK}ПодготвÑне на играта
+STR_DIFFICULTY_TO_CUSTOM :{WHITE}Това дейÑтвие промени нивото на трудноÑÑ‚ на custom
+STR_SE_FLAT_WORLD :{WHITE}ПлоÑка земÑ
+STR_SE_FLAT_WORLD_TIP :{BLACK}Генериране на плоÑка земÑ
+STR_SE_RANDOM_LAND :{WHITE}Случайна карта
+STR_SE_NEW_WORLD :{BLACK}Създаване на нов Ñценарий
+STR_SE_CAPTION :{WHITE}Тип на ÑценариÑ
+STR_FLAT_WORLD_HEIGHT_DOWN :{BLACK}СвалÑне виÑочината на плоÑка земÑ
+STR_FLAT_WORLD_HEIGHT_UP :{BLACK}Повишаване виÑочината на плоÑка земÑ
+STR_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}ПромÑна виÑочината на плоÑка земÑ
+STR_FLAT_WORLD_HEIGHT :{BLACK}ВиÑочина на плоÑка земÑ:
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+STR_SMALLMAP_CENTER :{BLACK}Центриране на малката карта на текущата позициÑ
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}Малко
+STR_CITY_AIRPORT :{BLACK}Град
+STR_METRO_AIRPORT :{BLACK}МетрополиÑно летище
+STR_INTERNATIONAL_AIRPORT :{BLACK}Международно летище
+STR_COMMUTER_AIRPORT :{BLACK}Комютър
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Междуконтинентално
+STR_HELIPORT :{BLACK}Хеликоптерна площадка
+STR_HELIDEPOT :{BLACK}Хеликоптерен хангар
+STR_HELISTATION :{BLACK}Хеликоптерна ÑтанциÑ
+
+STR_SMALL_AIRPORTS :{BLACK}Малки летища
+STR_LARGE_AIRPORTS :{BLACK}ГолÑмо летище
+STR_HUB_AIRPORTS :{BLACK}Централни летища
+STR_HELIPORTS :{BLACK}Хеликоптерни Ñамолети
+
+############ Tooltip measurment
+
+STR_MEASURE_LENGTH :{BLACK}Дължина: {NUM}
+STR_MEASURE_AREA :{BLACK}Площ: {NUM} x {NUM}
+STR_MEASURE_LENGTH_HEIGHTDIFF :{BLACK}Дължина: {NUM}{}Разлика във виÑочината: {NUM} м
+STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}Площ: {NUM} x {NUM}{}Разлика във виÑочината: {NUM} м
+
+########
diff --git a/src/lang/catalan.txt b/src/lang/catalan.txt
new file mode 100644
index 000000000..de2e07037
--- /dev/null
+++ b/src/lang/catalan.txt
@@ -0,0 +1,3116 @@
+##name Catalan
+##ownname Català
+##isocode ca_ES.UTF-8
+##plural 0
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Fora del marc del mapa
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Massa a prop del marc del mapa
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}No tens prou diners - et fan falta {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Es necessita un terreny pla
+STR_0008_WAITING :{BLACK}Esperant: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (en ruta des de
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Accepta: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Accepta: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :Passatgers
+STR_0010_COAL :Carbó
+STR_0011_MAIL :Correu
+STR_0012_OIL :Petroli
+STR_0013_LIVESTOCK :Bestiar
+STR_0014_GOODS :Mercaderies
+STR_0015_GRAIN :Gra
+STR_0016_WOOD :Fusta
+STR_0017_IRON_ORE :Mineral de Ferro
+STR_0018_STEEL :Acer
+STR_0019_VALUABLES :Valors
+STR_001A_COPPER_ORE :Mineral de Coure
+STR_001B_MAIZE :Blat de Moro
+STR_001C_FRUIT :Fruita
+STR_001D_DIAMONDS :Diamants
+STR_001E_FOOD :Menjar
+STR_001F_PAPER :Paper
+STR_0020_GOLD :Or
+STR_0021_WATER :Aigua
+STR_0022_WHEAT :Blat
+STR_0023_RUBBER :Cautxú
+STR_0024_SUGAR :Sucre
+STR_0025_TOYS :Joguines
+STR_0026_CANDY :Dolços
+STR_0027_COLA :Refrescs
+STR_0028_COTTON_CANDY :Cotó de Sucre
+STR_0029_BUBBLES :Bombolles
+STR_002A_TOFFEE :Caramels
+STR_002B_BATTERIES :Bateries
+STR_002C_PLASTIC :Plàstic
+STR_002D_FIZZY_DRINKS :Begudes Gasoses
+STR_002E :
+STR_002F_PASSENGER :Passatger
+STR_0030_COAL :Carbó
+STR_0031_MAIL :Correu
+STR_0032_OIL :Petroli
+STR_0033_LIVESTOCK :Bestiar
+STR_0034_GOODS :Mercaderia
+STR_0035_GRAIN :Gra
+STR_0036_WOOD :Fusta
+STR_0037_IRON_ORE :Mineral de Ferro
+STR_0038_STEEL :Acer
+STR_0039_VALUABLES :Valors
+STR_003A_COPPER_ORE :Mineral de Coure
+STR_003B_MAIZE :Blat de Moro
+STR_003C_FRUIT :Fruita
+STR_003D_DIAMOND :Diamant
+STR_003E_FOOD :Queviure
+STR_003F_PAPER :Paper
+STR_0040_GOLD :Or
+STR_0041_WATER :Aigua
+STR_0042_WHEAT :Blat
+STR_0043_RUBBER :Cautxú
+STR_0044_SUGAR :Sucre
+STR_0045_TOY :Joguina
+STR_0046_CANDY :Dolç
+STR_0047_COLA :Refresc
+STR_0048_COTTON_CANDY :Cotó de Sucre
+STR_0049_BUBBLE :Bombolla
+STR_004A_TOFFEE :Caramel
+STR_004B_BATTERY :Pila
+STR_004C_PLASTIC :Plàstic
+STR_004D_FIZZY_DRINK :Beguda Gasosa
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} passatger{P "" s}
+STR_QUANTITY_COAL :{WEIGHT} de carbó
+STR_QUANTITY_MAIL :{COMMA} sac{P "" s} de correu
+STR_QUANTITY_OIL :{VOLUME} de petroli
+STR_QUANTITY_LIVESTOCK :{COMMA} cap{P "" s} de bestiar
+STR_QUANTITY_GOODS :{COMMA} palet{P "" s} de mercaderies
+STR_QUANTITY_GRAIN :{WEIGHT} de gra
+STR_QUANTITY_WOOD :{WEIGHT} de fusta
+STR_QUANTITY_IRON_ORE :{WEIGHT} de mineral de ferro
+STR_QUANTITY_STEEL :{WEIGHT} d'acer
+STR_QUANTITY_VALUABLES :{COMMA} sac{P "" s} de valors
+STR_QUANTITY_COPPER_ORE :{WEIGHT} de mineral de coure
+STR_QUANTITY_MAIZE :{WEIGHT} de blat de moro
+STR_QUANTITY_FRUIT :{WEIGHT} de fruita
+STR_QUANTITY_DIAMONDS :{COMMA} boss{P a es} de diamants
+STR_QUANTITY_FOOD :{WEIGHT} de queviures
+STR_QUANTITY_PAPER :{WEIGHT} de paper
+STR_QUANTITY_GOLD :{COMMA} sa{P ca ques} d'or
+STR_QUANTITY_WATER :{VOLUME} d'aigua
+STR_QUANTITY_WHEAT :{WEIGHT} de blat
+STR_QUANTITY_RUBBER :{VOLUME} de cautxú
+STR_QUANTITY_SUGAR :{WEIGHT} de sucre
+STR_QUANTITY_TOYS :{COMMA} joguin{P a es}
+STR_QUANTITY_SWEETS :{COMMA} boss{P a es} de dolços
+STR_QUANTITY_COLA :{VOLUME} de refrescs
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} de cotó de sucre
+STR_QUANTITY_BUBBLES :{COMMA} bomboll{P a es}
+STR_QUANTITY_TOFFEE :{WEIGHT} de caramel
+STR_QUANTITY_BATTERIES :{COMMA} pil{P a es}
+STR_QUANTITY_PLASTIC :{VOLUME} de plàstic
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} begud{P a es} gasosa
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}PS
+STR_ABBREV_COAL :{TINYFONT}CB
+STR_ABBREV_MAIL :{TINYFONT}CR
+STR_ABBREV_OIL :{TINYFONT}PT
+STR_ABBREV_LIVESTOCK :{TINYFONT}BE
+STR_ABBREV_GOODS :{TINYFONT}ME
+STR_ABBREV_GRAIN :{TINYFONT}GR
+STR_ABBREV_WOOD :{TINYFONT}FU
+STR_ABBREV_IRON_ORE :{TINYFONT}FE
+STR_ABBREV_STEEL :{TINYFONT}AC
+STR_ABBREV_VALUABLES :{TINYFONT}VL
+STR_ABBREV_COPPER_ORE :{TINYFONT}CO
+STR_ABBREV_MAIZE :{TINYFONT}BM
+STR_ABBREV_FRUIT :{TINYFONT}FR
+STR_ABBREV_DIAMONDS :{TINYFONT}DM
+STR_ABBREV_FOOD :{TINYFONT}QV
+STR_ABBREV_PAPER :{TINYFONT}PR
+STR_ABBREV_GOLD :{TINYFONT}OR
+STR_ABBREV_WATER :{TINYFONT}AI
+STR_ABBREV_WHEAT :{TINYFONT}BL
+STR_ABBREV_RUBBER :{TINYFONT}CX
+STR_ABBREV_SUGAR :{TINYFONT}SU
+STR_ABBREV_TOYS :{TINYFONT}JO
+STR_ABBREV_SWEETS :{TINYFONT}XU
+STR_ABBREV_COLA :{TINYFONT}RF
+STR_ABBREV_CANDYFLOSS :{TINYFONT}CS
+STR_ABBREV_BUBBLES :{TINYFONT}BM
+STR_ABBREV_TOFFEE :{TINYFONT}CA
+STR_ABBREV_BATTERIES :{TINYFONT}BA
+STR_ABBREV_PLASTIC :{TINYFONT}PL
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}BG
+STR_ABBREV_NONE :{TINYFONT}NO
+STR_ABBREV_ALL :{TINYFONT}TOT
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Mapa - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Opcions del Joc
+STR_00B2_MESSAGE :{YELLOW}Missatge
+STR_00B3_MESSAGE_FROM :{YELLOW}Missatge de {STRING}
+STR_POPUP_CAUTION_CAPTION :{WHITE}Alerta!
+STR_00B4_CAN_T_DO_THIS :{WHITE}No es pot fer això....
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}No es pot netejar l'àrea....
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Copyright original {COPYRIGHT} 1995 Chris Sawyer, Tots els drets reservats
+STR_00B7_VERSION :{BLACK}OpenTTD versió {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 L'equip d'OpenTTD
+STR_TRANSLATED_BY :{BLACK} Traductor(s) -
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Sortir
+STR_00C8_YES :{BLACK}Si
+STR_00C9_NO :{BLACK}No
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Estàs segur que vols abandonar aquest joc i tornar a {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Res
+STR_00D1_DARK_BLUE :Blau Fosc
+STR_00D2_PALE_GREEN :Verd Pàlid
+STR_00D3_PINK :Rosa
+STR_00D4_YELLOW :Groc
+STR_00D5_RED :Vermell
+STR_00D6_LIGHT_BLUE :Blau Cel
+STR_00D7_GREEN :Verd
+STR_00D8_DARK_GREEN :Verd Fosc
+STR_00D9_BLUE :Blau
+STR_00DA_CREAM :Crema
+STR_00DB_MAUVE :Malva
+STR_00DC_PURPLE :Porpre
+STR_00DD_ORANGE :Taronja
+STR_00DE_BROWN :Marró
+STR_00DF_GREY :Gris
+STR_00E0_WHITE :Blanc
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Massa vehicles en joc
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Situació
+STR_00E5_CONTOURS :Límits
+STR_00E6_VEHICLES :Vehicles
+STR_00E7_INDUSTRIES :Indústries
+STR_00E8_ROUTES :Rutes
+STR_00E9_VEGETATION :Vegetació
+STR_00EA_OWNERS :Propietaris
+STR_00EB_ROADS :{BLACK}{TINYFONT}Carreteres
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Vies
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Estacions/Aeroports/Ports
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Edificis/Indústries
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Vehicles
+STR_00F0_100M :{BLACK}{TINYFONT}100m
+STR_00F1_200M :{BLACK}{TINYFONT}200m
+STR_00F2_300M :{BLACK}{TINYFONT}300m
+STR_00F3_400M :{BLACK}{TINYFONT}400m
+STR_00F4_500M :{BLACK}{TINYFONT}500m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Trens
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Vehicles de carretera
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Vaixells
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Aeronaus
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Rutes de Transport
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Mina de Carbó
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Central Tèrmica
+STR_00FC_FOREST :{BLACK}{TINYFONT}Bosc
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}Serradora
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Refineria de Petroli
+STR_00FF_FARM :{BLACK}{TINYFONT}Granja
+STR_0100_FACTORY :{BLACK}{TINYFONT}Fàbrica
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Impremta
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Pous de Petroli
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Mina de Ferro
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Alt Forn
+STR_0105_BANK :{BLACK}{TINYFONT}Banc
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Paperera
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Mina d'Or
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Planta de Manipulació d'Aliments
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Mina de Diamants
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Mina de Coure
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Plantació de Fruita
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Plantació de Cautxú
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Sortidor d'Aigua
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Torre d'Aigua
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}Cabana de Fusta
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Bosc de Cotó de Sucre
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Fàbrica de Dolços
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Granja de Piles
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Pous de Refresc
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Botiga de Joguines
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Fàbrica de Joguines
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Fonts de Plàstic
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Fàbrica de Begudes Gasoses
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Generador de Bombolles
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Cantera de Caramels
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Mina de Sucre
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Estació de Ferrocarril
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Moll de Càrrega de Camions
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Parada d'autobús
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Aeroport/Heliport
+STR_011F_DOCK :{BLACK}{TINYFONT}Moll
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Terreny Irregular
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Gespa
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Terreny erm
+STR_0123_FIELDS :{BLACK}{TINYFONT}Camps
+STR_0124_TREES :{BLACK}{TINYFONT}Arbres
+STR_0125_ROCKS :{BLACK}{TINYFONT}Roques
+STR_0126_WATER :{BLACK}{TINYFONT}Aigua
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Sense Propietari
+STR_0128_TOWNS :{BLACK}{TINYFONT}Poblacions
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Indústries
+STR_012A_DESERT :{BLACK}{TINYFONT}Desert
+STR_012B_SNOW :{BLACK}{TINYFONT}Neu
+STR_012C_MESSAGE :{WHITE}Missatge
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Cancel·la
+STR_012F_OK :{BLACK}Bé
+STR_0130_RENAME :{BLACK}Reanomena
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Massa noms definits
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Aquest nom ja es fa servir
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...propietat de {STRING}
+STR_013C_CARGO :{BLACK}Càrrega
+STR_013D_INFORMATION :{BLACK}Informació
+STR_013E_CAPACITIES :{BLACK}Capacitats
+STR_013E_TOTAL_CARGO :{BLACK}Càrrega Total
+STR_013F_CAPACITY :{BLACK}Capacitats: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}Capacitat: {LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Càrrega total (capacitat) d'aquest tren:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}Joc Nou
+STR_0141_LOAD_GAME :{BLACK}Carrega un Joc
+STR_SINGLE_PLAYER :{BLACK}Jugador individual
+STR_MULTIPLAYER :{BLACK}Multijugador
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Tamany del mapa:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Opcions del Joc
+
+STR_0150_SOMEONE :algú{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Mapa del món
+STR_0152_TOWN_DIRECTORY :Directori de Poblacions
+STR_0153_SUBSIDIES :Subvencions
+
+STR_UNITS_IMPERIAL :Imperial
+STR_UNITS_METRIC :Mètric
+STR_UNITS_SI :Si
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} mph
+STR_UNITS_VELOCITY_METRIC :{COMMA} km/h
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}hp
+STR_UNITS_POWER_METRIC :{COMMA}hp
+STR_UNITS_POWER_SI :{COMMA}kW
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} tona{P "" s}
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} tone{P "" s}
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} kg
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}gal
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}l
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}m³
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} galó{P "" s}
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} litre{P "" s}
+STR_UNITS_VOLUME_LONG_SI :{COMMA} m³
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10³ lbf
+STR_UNITS_FORCE_METRIC :{COMMA} força per tona
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Gràfic de benefici operatiu
+STR_0155_INCOME_GRAPH :Gràfic d'ingressos
+STR_0156_DELIVERED_CARGO_GRAPH :Gràfic d'entrega de càrrega
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Gràfic històric de rendiment
+STR_0158_COMPANY_VALUE_GRAPH :Gràfic de valor de l'Empresa
+STR_0159_CARGO_PAYMENT_RATES :Tarifes de pagament per càrrega
+STR_015A_COMPANY_LEAGUE_TABLE :Taula de la Lliga d'Empreses
+STR_PERFORMANCE_DETAIL_MENU :Detall de ratis de rendiment
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}Quant a OpenTTD
+STR_015C_SAVE_GAME :Desa el joc
+STR_015D_LOAD_GAME :Carrega el joc
+STR_015E_QUIT_GAME :Abandona el joc
+STR_015F_QUIT :Sortir
+STR_ABANDON_GAME_QUERY :{YELLOW}Estàs segur que vols abandonar aquest joc?
+STR_0161_QUIT_GAME :{WHITE}Abandona el Joc
+STR_SORT_ORDER_TIP :{BLACK}Selecciona ordre de classificació (descendent/ascendent)
+STR_SORT_CRITERIA_TIP :{BLACK}Selecciona criteri de classificació
+STR_SORT_BY :{BLACK}Ordenar per
+
+STR_SORT_BY_POPULATION :{BLACK}Població
+STR_SORT_BY_PRODUCTION :{BLACK}Producció
+STR_SORT_BY_TYPE :{BLACK}Tipus
+STR_SORT_BY_TRANSPORTED :{BLACK}Transportat
+STR_SORT_BY_NAME :{BLACK}Nom
+STR_SORT_BY_DROPDOWN_NAME :Nom
+STR_SORT_BY_DATE :{BLACK}Data
+STR_SORT_BY_NUMBER :Número
+STR_SORT_BY_PROFIT_LAST_YEAR :Benef. darrer any
+STR_SORT_BY_PROFIT_THIS_YEAR :Benef. aquest any
+STR_SORT_BY_AGE :Antig.
+STR_SORT_BY_RELIABILITY :Rendibilitat
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Capac. total per tipus de càrrega
+STR_SORT_BY_MAX_SPEED :Veloc. Màxima
+STR_SORT_BY_MODEL :Model
+STR_SORT_BY_VALUE :Valor
+STR_SORT_BY_FACILITY :Tipus de estació
+STR_SORT_BY_WAITING :Valor de espera de càrrega
+STR_SORT_BY_RATING_MAX :Rati de càrrega
+STR_ENGINE_SORT_ENGINE_ID :IDMotor (ordre clàssic)
+STR_ENGINE_SORT_COST :Cost
+STR_ENGINE_SORT_POWER :Potència
+STR_ENGINE_SORT_INTRO_DATE :Data de llançament
+STR_ENGINE_SORT_RUNNING_COST :Cost d'utilització
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Potència/Cost d'utilització
+STR_ENGINE_SORT_CARGO_CAPACITY :Capacitat de càrrega
+STR_NO_WAITING_CARGO :{BLACK}No hi ha càrrega d'aquest tipus esperant
+STR_SELECT_ALL_FACILITIES :{BLACK}Seleccionar totes les instal·lacions
+STR_SELECT_ALL_TYPES :{BLACK}Selecciona tots els tipus de càrrega (inloent carga sense espera)
+STR_AVAILABLE_ENGINES_TIP :{BLACK}Veure una llista dels motors disponibles per aquest tipus de vehicle
+STR_MANAGE_LIST :{BLACK}Administra llista
+STR_MANAGE_LIST_TIP :{BLACK}Envia instruccions a tots els vehicles de la llista
+STR_REPLACE_VEHICLES :Substitueix Vehicles
+STR_SEND_TRAIN_TO_DEPOT :Enviar a la Cotxera
+STR_SEND_ROAD_VEHICLE_TO_DEPOT :Enviar a la Cotxera
+STR_SEND_SHIP_TO_DEPOT :Enviar a la Drassana
+STR_SEND_AIRCRAFT_TO_HANGAR :Enviar a l'Hangar
+STR_SEND_FOR_SERVICING :Enviar a fer Revisió
+
+############ range for months starts
+STR_0162_JAN :Gen
+STR_0163_FEB :Feb
+STR_0164_MAR :Mar
+STR_0165_APR :Abr
+STR_0166_MAY :Mai
+STR_0167_JUN :Jun
+STR_0168_JUL :Jul
+STR_0169_AUG :Ago
+STR_016A_SEP :Sep
+STR_016B_OCT :Oct
+STR_016C_NOV :Nov
+STR_016D_DEC :Des
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Para el joc
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Desa el joc, abandona el joc, sortir
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Mostra la llista d'estacions de l'empresa
+STR_0174_DISPLAY_MAP :{BLACK}Mostra el mapa
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Mostra el mapa, directori de poblacions
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Mostra el directori de poblacions
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Mostra informació financera de l'empresa
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Mostra informació general de l'empresa
+STR_0179_DISPLAY_GRAPHS :{BLACK}Mostra gràfics
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Mostra la taula de la lliga d'empreses
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Mostra la llista de trens de l'empresa
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Mostra la llista de vehicles de l'empresa
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Mostra la llista de vaixells de l'empresa
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Mostra la llista d'aeronaus de l'empresa
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Apropar-se
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Allunyar-se
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Construeix vies
+STR_0182_BUILD_ROADS :{BLACK}Construeix carreteres
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Construeix ports
+STR_0184_BUILD_AIRPORTS :{BLACK}Construeix aeroports
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Planta arbres, situa senyals, etc.
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Informació del terreny
+STR_0187_OPTIONS :{BLACK}Opcions
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}No es pot canviar l'interval del manteniment...
+STR_018B_CLOSE_WINDOW :{BLACK}Tanca la finestra
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Títol de la finestra - arrossega això per moure la finestra
+STR_STICKY_BUTTON :{BLACK}Marca aquesta finestra com a no eliminable pel 'Tanca totes les Finestres'
+STR_RESIZE_BUTTON :{BLACK}Prem i arrossega per canviar el tamany de la finestra
+STR_SAVELOAD_HOME_BUTTON :{BLACK}Prem aquí per anar a la carpeta per defecte actual de desa/carrega
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Demolició d'edificis etc. en un quadre de terreny
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Rebaixa una cantonada del terreny
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Eleva una cantonada del terreny
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Barra de desplaçament - desplaça la llista amunt/avall
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Barra de desplaçament - desplaça la llista dreta/esquerra
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Mostra els limits de terreny al mapa
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Mostra els vehicles al mapa
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Mostra les indústries al mapa
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Mostra les rutes de transport al mapa
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Mostra la vegetació al mapa
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Mostra els propietaris del terreny al mapa
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Activa/desactiva noms de poblacions al mapa
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Benefici enguany: {CURRENCY} (darrer any: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} any{P "" s} ({COMMA})
+STR_AGE_RED :{RED}{COMMA} any{P "" s} ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Vehicle
+STR_019D_AIRCRAFT :Aeronau
+STR_019E_SHIP :Vaixell
+STR_019F_TRAIN :Tren
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} s'està envellint
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} s'està envellint molt
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} s'està envellint molt i necessita substitució urgent
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Informació del terreny
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Cost de neteja: {LTBLUE}N/A
+STR_01A5_COST_TO_CLEAR :{BLACK}Cost de neteja: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :N/D
+STR_01A7_OWNER :{BLACK}Propietari: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Autoritat Local: {LTBLUE}{STRING}
+STR_01A9_NONE :Ningú
+STR_01AA_NAME :{BLACK}Nom
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1
+STR_01AD_2ND :2
+STR_01AE_3RD :3
+STR_01AF_4TH :4
+STR_01B0_5TH :5
+STR_01B1_6TH :6
+STR_01B2_7TH :7
+STR_01B3_8TH :8
+STR_01B4_9TH :9
+STR_01B5_10TH :10
+STR_01B6_11TH :11
+STR_01B7_12TH :12
+STR_01B8_13TH :13
+STR_01B9_14TH :14
+STR_01BA_15TH :15
+STR_01BB_16TH :16
+STR_01BC_17TH :17
+STR_01BD_18TH :18
+STR_01BE_19TH :19
+STR_01BF_20TH :20
+STR_01C0_21ST :21
+STR_01C1_22ND :22
+STR_01C2_23RD :23
+STR_01C3_24TH :24
+STR_01C4_25TH :25
+STR_01C5_26TH :26
+STR_01C6_27TH :27
+STR_01C7_28TH :28
+STR_01C8_29TH :29
+STR_01C9_30TH :30
+STR_01CA_31ST :31
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Càrrega acceptada: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Jukebox de Jazz
+STR_01D3_SOUND_MUSIC :So/música
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Mostra la finestra de so/música
+STR_01D5_ALL :{TINYFONT}Tot
+STR_01D6_OLD_STYLE :{TINYFONT}Estil Antic
+STR_01D7_NEW_STYLE :{TINYFONT}Estil Nou
+STR_01D8_EZY_STREET :{TINYFONT}Ezy Street
+STR_01D9_CUSTOM_1 :{TINYFONT}Opcional 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Opcional 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Volum de la música
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Volum dels efectes
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MIN ' ' ' ' ' ' MAX
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Salta a la pista anterior de la selecció
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Salta a la pista següent de la selecció
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Para la música
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Engega la música
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Arrosega els controls per establir el volum de la música i els efectes de so
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Pista{SETX 88}Títol
+STR_01E9_SHUFFLE :{TINYFONT}Aleatori
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Programa
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Selecció del Programa de Música
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Index de Pista
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Programa - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}Esborra
+STR_01F1_SAVE :{TINYFONT}{BLACK}Desa
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Programa actual de pistes de música
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Selecciona el programa 'totes les pistes'
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Selecciona el programa 'música estil antic'
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Selecciona el programa 'música de nou estil'
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Selecciona el programa 'Opcional 1' (definit per l'usuari)
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Selecciona el programa 'Opcional 2' (definit per l'usuari)
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Esborra el programa actual (només Opcional 1 o Opcional 2)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Desa els paràmetres de la música
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Clica a la pista de música per afegir-la al programa actual (només Opcional 1 o Opcional 2)
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Click en la pista de musica per treure-la del programa actual (Custom1 o Custom2 només)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Control de programa aleatori actiu/inactiu
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Mostra la finestra de selecció de pistes de música
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Clica al servei per centrar la vista a l'indústria/població
+STR_01FE_DIFFICULTY :{BLACK}Dificultat ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Darrer missatge/notícia
+STR_0201_MESSAGE_SETTINGS :Preferències dels Missatges
+STR_MESSAGE_HISTORY_MENU :Historial de Missatges
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Mostra els darrers missatges/notícies, mostra les opcions de missatges
+STR_0204_MESSAGE_OPTIONS :{WHITE}Opcions de Missatges
+STR_0205_MESSAGE_TYPES :{BLACK}Tipus de Missages:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Arribada del 1er. vehicle a una estació pròpia
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Arribada del 1er. vehicle a una estació competidora
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Accidents / desastres
+STR_0209_COMPANY_INFORMATION :{YELLOW}Informació de l'Empresa
+STR_020A_ECONOMY_CHANGES :{YELLOW}Canvis de l'Economia
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Avisos / informació dels teus vehicles
+STR_020C_NEW_VEHICLES :{YELLOW}Nous vehicles
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Canvis en admisió de càrrega
+STR_020E_SUBSIDIES :{YELLOW}Subvencions
+STR_020F_GENERAL_INFORMATION :{YELLOW}Informació General
+STR_MESSAGES_ALL :{YELLOW}Adjust per tots els tipus de missatge (actiu/inactiu/resum)
+STR_MESSAGE_SOUND :{YELLOW}Emetre so per als nous missatges resumits
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...massa lluny del destí previ
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Principals Empreses en asolir el Nivell {NUM}{}({STRING} )
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Taula de Lliga d'Empreses a {NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Empresari
+STR_0214_ENTREPRENEUR :Emprenedor
+STR_0215_INDUSTRIALIST :Industrial
+STR_0216_CAPITALIST :Capitalista
+STR_0217_MAGNATE :Magnate
+STR_0218_MOGUL :Gran Magnate
+STR_0219_TYCOON_OF_THE_CENTURY :Magnate del Segle
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} asoleix l'estat '{STRING}' !
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} de {COMPANY} asoleix l'estat '{STRING}' !
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Crea un Escenari
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Editor d'Escenaris
+STR_0223_LAND_GENERATION :{WHITE}Generador de Terreny
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Terreny Aleatori
+STR_0227_RESET_LAND :{BLACK}Restableix Terreny
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Augmenta la mida de l'àrea de terreny a rebaixar/elevar
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Disminueix la mida de l'àrea de terreny a rebaixar/elevar
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Genera un terreny aleatori
+STR_022B_RESET_LANDSCAPE :{BLACK}Restableix paisatge
+STR_022C_RESET_LANDSCAPE :{WHITE}Restablir Paisatge
+STR_LOAD_GAME_HEIGHTMAP :{WHITE}Utilitza un mapa d'alçades
+STR_LOAD_SCEN_HEIGHTMAP :{BLACK}Utilitza un mapa d'alçades
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Estàs segur que vols restablir el paisatge?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Generació de Paisatges
+STR_022F_TOWN_GENERATION :{BLACK}Generació de Poblacions
+STR_0230_INDUSTRY_GENERATION :{BLACK}Generació d'indústries
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Construcció de carreteres
+STR_0233_TOWN_GENERATION :{WHITE}Generació de Poblacions
+STR_0234_NEW_TOWN :{BLACK}Nova Població
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Construcció de nova població
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}No es pot construir una població aquí...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...massa aprop del límit del mapa
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...massa aprop d'una altra població
+STR_0239_SITE_UNSUITABLE :{WHITE}...lloc inadequat
+STR_023A_TOO_MANY_TOWNS :{WHITE}...massa poblacions
+STR_CANNOT_GENERATE_TOWN :{WHITE}Impossible construir poblacions
+STR_NO_SPACE_FOR_TOWN :{WHITE}...no queda espai al mapa
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Incrementa el tamany de la població
+STR_023C_EXPAND :{BLACK}Expandeix
+STR_023D_RANDOM_TOWN :{BLACK}Localitat Aleatòria
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Construeix una població en un lloc aleatori
+STR_023F_INDUSTRY_GENERATION :{WHITE}Generació d'indústries
+STR_0240_COAL_MINE :{BLACK}Mina de Carbó
+STR_0241_POWER_STATION :{BLACK}Central Tèrmica
+STR_0242_SAWMILL :{BLACK}Asserradora
+STR_0243_FOREST :{BLACK}Bosc
+STR_0244_OIL_REFINERY :{BLACK}Refineria de Petroli
+STR_0245_OIL_RIG :{BLACK}Plataforma Petrolífera
+STR_0246_FACTORY :{BLACK}Fàbrica
+STR_0247_STEEL_MILL :{BLACK}Alt Forn
+STR_0248_FARM :{BLACK}Granja
+STR_0249_IRON_ORE_MINE :{BLACK}Mina de Ferro
+STR_024A_OIL_WELLS :{BLACK}Pous de Petroli
+STR_024B_BANK :{BLACK}Banc
+STR_024C_PAPER_MILL :{BLACK}Paperera
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Planta de Manipulació de Queviures
+STR_024E_PRINTING_WORKS :{BLACK}Arts Gràfiques
+STR_024F_GOLD_MINE :{BLACK}Mina d'Or
+STR_0250_LUMBER_MILL :{BLACK}Cabana de Fusta
+STR_0251_FRUIT_PLANTATION :{BLACK}Plantació de Fruita
+STR_0252_RUBBER_PLANTATION :{BLACK}Plantació de Cautxú
+STR_0253_WATER_SUPPLY :{BLACK}Surtidor d'aigua
+STR_0254_WATER_TOWER :{BLACK}Torre d'aigua
+STR_0255_DIAMOND_MINE :{BLACK}Mina de Diamants
+STR_0256_COPPER_ORE_MINE :{BLACK}Mina de Coure
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Bosc de Cotó de Sucre
+STR_0258_CANDY_FACTORY :{BLACK}Fàbrica de Dolços
+STR_0259_BATTERY_FARM :{BLACK}Granja de Piles
+STR_025A_COLA_WELLS :{BLACK}Pous de Refresc
+STR_025B_TOY_SHOP :{BLACK}Botiga de Joguines
+STR_025C_TOY_FACTORY :{BLACK}Fàbrica de Joguines
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Fonts de Plàstic
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Fàbrica de Begudes Gasoses
+STR_025F_BUBBLE_GENERATOR :{BLACK}Generador de Bombolles
+STR_0260_TOFFEE_QUARRY :{BLACK}Cantera de Caramel
+STR_0261_SUGAR_MINE :{BLACK}Mina de sucre
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Construeix una Mina de Carbó
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Construeix una Central Tèrmica
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Construeix una Serralleria
+STR_0265_PLANT_FOREST :{BLACK}Planta un Bosc
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Construeix una Refineria de Petroli
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Construeix una Plataforma Petrolífera (Només es pot construir vora els límits del mapa)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Construeix una Fàbrica
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Construeix un Alt Forn
+STR_026A_CONSTRUCT_FARM :{BLACK}Construeix una Granja
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Construeix una Mina de Ferro
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Construeix uns Pous de Petroli
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Construeix un Banc (Només es pot construir en poblacions de més de 1200 hab.)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Construeix una Paperera
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Construeix una Planta de Manipulació de Queviures
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Construeix unes Arts Gràfiques
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Construeix una Mina d'Or
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Construeix un Banc (Només es pot construir en poblacions)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Construeix una Cabana de Fusta (per netejar la selva tropical i produïr Fusta)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Crea una Plantació de Fruita
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Crea una Plantació de Cautxú
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Construeix un Surtidor d'Aigua
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Construeix una Torre d'aigua (Només es pot construir en poblacions)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Construeix una Mina de Diamants
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Construeix una Mina de Coure
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Planta un Bosc de Cotó de Sucre
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Construeix una Fàbrica de Dolços
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Construeix una Granja de Piles
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Construeix uns Pous de Refresc
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Construeix una Botiga de Joguines
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Construeix una Fàbrica de Joguines
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Construeix unes Fonts de Plàstic
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Construeix una Fàbrica de Begudes Gasoses
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Construeix un Generador de Bombolles
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Construeix una Cantera de Caramel
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Construeix una Mina de Sucre
+STR_0285_CAN_T_BUILD_HERE :{WHITE}Aquí no es pot construir {STRING}...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...has de construir la població primer
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...només un permés per població
+STR_0288_PLANT_TREES :{BLACK}Planta arbres
+STR_0289_PLACE_SIGN :{BLACK}Situa una senyal
+STR_028A_RANDOM_TREES :{BLACK}Arbres Aleatoris
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Planta arbres aleatòriament al paisatge
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Situa àrees de roques al paisatge
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Situa un far
+STR_028E_PLACE_TRANSMITTER :{BLACK}Situa un repetidor
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Defineix àrea de desert.{}Prem i mantingues la tecla CTRL per treure'l
+STR_CREATE_LAKE :{BLACK}Defineix àrea d'aigua.{}Inundarà els voltants si és a nivell del mar
+STR_0290_DELETE :{BLACK}Esborra
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Esborra totalment aquesta població
+STR_0292_SAVE_SCENARIO :Desa l'escenari
+STR_0293_LOAD_SCENARIO :Carrega un escenari
+STR_0294_QUIT_EDITOR :Sortir de l'editor
+STR_0295 :
+STR_0296_QUIT :Sortir
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Desa l'escenari, carrega un escenari, abandona l'editor d'escenaris, sortir
+STR_0298_LOAD_SCENARIO :{WHITE}Carrega un Escenari
+STR_0299_SAVE_SCENARIO :{WHITE}Desa l'Escenari
+STR_029A_PLAY_SCENARIO :{BLACK}Juga un Escenari
+STR_PLAY_HEIGHTMAP :{BLACK}Juga un mapa d'alçades
+STR_PLAY_HEIGHTMAP_HINT :{BLACK}Comença un nou joc, utilitzant un mapa d'alçades com a terreny
+STR_QUIT_SCENARIO_QUERY :{YELLOW}Estàs segur que vols sortir d'aquest escenari ?
+STR_029C_QUIT_EDITOR :{WHITE}Sortir de l'Editor
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...només es pot construir en poblacions de més de 1200 hab.
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Retarda la data d'inici 1 any
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Avança la data d'inici 1 any
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...els extrems del pont han d'estar tots dos a terra
+STR_02A1_SMALL :{BLACK}Petit
+STR_02A2_MEDIUM :{BLACK}Mitjà
+STR_02A3_LARGE :{BLACK}Gran
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Selecciona mida de població
+STR_02A5_TOWN_SIZE :{YELLOW}Mida de població:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Mostra el darrer missatge o notícia
+STR_OFF :Fora
+STR_SUMMARY :Resum
+STR_FULL :Complet
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Directori de Poblacions
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Noms de dissenys de vehicles
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Per defecte
+STR_02BF_CUSTOM :Personalitzat
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Desa els noms configurables
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Selecció de noms de disseny de vehicles
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Desa els noms de disseny de vehicles personalitzats al disc
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Opcions del Joc
+STR_02C5_DIFFICULTY_SETTINGS :Paràmetres de dificultat
+STR_02C7_CONFIG_PATCHES :Configura pedaços
+STR_NEWGRF_SETTINGS :Configuracions de Newgrf
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Mostra els noms de les poblacions
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Mostra els noms de les estacions
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Mostra les senyals
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Mostra punts de control
+STR_02D0_FULL_ANIMATION :{SETX 12}Animació completa
+STR_02D2_FULL_DETAIL :{SETX 12}Detall complet
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Edificis Transparents
+STR_TRANSPARENT_SIGNS :{SETX 12}Signes d'estació transparents
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Informació de l'àrea de terreny
+STR_02D6 :
+STR_CONSOLE_SETTING :Canvia a cònsola
+STR_02D7_SCREENSHOT_CTRL_S :Còpia de Pantalla (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Còpia de Pantalla Gran (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :Quant a 'OpenTTD'
+############ range ends here
+
+STR_02DB_OFF :{BLACK}Inactiu
+STR_02DA_ON :{BLACK}Actiu
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Mostra les subvencions
+STR_02DD_SUBSIDIES :Subvencions
+STR_02DE_MAP_OF_WORLD :Mapa del món
+STR_EXTRA_VIEW_PORT :Vista extra
+STR_SIGN_LIST :Llista de senyals
+STR_02DF_TOWN_DIRECTORY :Directori de Poblacions
+STR_TOWN_POPULATION :{BLACK}Població mundial: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Vista {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Copia a la vista
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Copia el lloc de la vista global a aquesta vista
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Ves a la vista
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Ves al lloc d'aquesta vista a la vista global
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Unitats de moneda
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Selecció d'unitats de moneda
+STR_MEASURING_UNITS :{BLACK}Unitats de mesura
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Unitats de mesura seleccionades
+STR_02E6_ROAD_VEHICLES :{BLACK}Automòbils
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Selecciona el sentit de circulació dels automòbils
+STR_02E9_DRIVE_ON_LEFT :Condueix per l'esquerra
+STR_02EA_DRIVE_ON_RIGHT :Condueix per la dreta
+STR_02EB_TOWN_NAMES :{BLACK}Noms de Poblacions
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Selecciona l'estil des noms de poblacions
+
+STR_02F4_AUTOSAVE :{BLACK}Desa automàticament
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Selecciona l'interval en que el joc es desa automàticament
+STR_02F7_OFF :Inactiu
+STR_02F8_EVERY_3_MONTHS :Cada 3 mesos
+STR_02F9_EVERY_6_MONTHS :Cada 6 mesos
+STR_02FA_EVERY_12_MONTHS :Cada 12 mesos
+STR_02FB_START_A_NEW_GAME :{BLACK}Comença un joc nou
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Carrega un joc desat
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Crea un joc amb un món/escenari personalitzat
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Selecciona un joc per un jugador
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Selecciona un joc multijugador de 2-8 jugadors
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Mostra les opcions del joc
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Mostra les opcions de dificultat
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Comença un joc nou, utilitzant un escenari personalitzat
+STR_0304_QUIT :{BLACK}Sortir
+STR_0305_QUIT_OPENTTD :{BLACK}Sortir d'OpenTTD
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...només es pot construir en poblacions
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Selecciona l'estil de paisatge 'temperat'
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Selecciona l'estil de paisatge 'subàrtic'
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Selecciona l'estil de paisatge 'subtropical'
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Selecciona l'estil de paisatge 'toyland'
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Patrocina la construcció d'una nova indústria
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Directori d'indústries
+STR_0313_FUND_NEW_INDUSTRY :Patrocina una nova indústria
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Patrocina una nova indústria
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...només es pot construir en poblacions
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...només es pot construir en àrees de selva tropical
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...només es pot construir en àrees de desert
+STR_0319_PAUSED :{YELLOW}* * EN PAUSA * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Còpia de pantalla desada correctament a disc com a '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}Error a la còpia de pantalla!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Compra un terreny per un ús posterior
+STR_032F_AUTOSAVE :{RED}AUTO DESAR
+STR_SAVING_GAME :{RED}* * DESANT JOC * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}S'està desant el joc,{}espera a que acabi l'operació!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Selecciona el programa 'Ezy Street style music'
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :Anglès
+STR_TOWNNAME_FRENCH :Francès
+STR_TOWNNAME_GERMAN :Alemany
+STR_TOWNNAME_ADDITIONAL_ENGLISH :Anglès (Adicional)
+STR_TOWNNAME_LATIN_AMERICAN :Latinoamericà
+STR_TOWNNAME_SILLY :Tonto
+STR_TOWNNAME_SWEDISH :Suec
+STR_TOWNNAME_DUTCH :Holandès
+STR_TOWNNAME_FINNISH :Finès
+STR_TOWNNAME_POLISH :Polac
+STR_TOWNNAME_SLOVAKISH :Eslovac
+STR_TOWNNAME_NORWEGIAN :Noruec
+STR_TOWNNAME_HUNGARIAN :Húngar
+STR_TOWNNAME_AUSTRIAN :Austríac
+STR_TOWNNAME_ROMANIAN :Romanès
+STR_TOWNNAME_CZECH :Txec
+STR_TOWNNAME_SWISS :Suís
+STR_TOWNNAME_DANISH :Danès
+STR_TOWNNAME_TURKISH :Turc
+STR_TOWNNAME_ITALIAN :Italià
+STR_TOWNNAME_CATALAN :Català
+############ end of townname region
+
+STR_CURR_GBP :Lliures (£)
+STR_CURR_USD :Dòlars ($)
+STR_CURR_EUR :Euros (€)
+STR_CURR_YEN :Iens (Â¥)
+STR_CURR_ATS :Shillings Austríacs (ATS)
+STR_CURR_BEF :Francs Belgues (BEF)
+STR_CURR_CHF :Francs Suissos (CHF)
+STR_CURR_CZK :Corones Txeques (CZK)
+STR_CURR_DEM :Marcs Alemanys (DEM)
+STR_CURR_DKK :Corones Daneses (DKK)
+STR_CURR_ESP :Peseta (ESP)
+STR_CURR_FIM :Marcs Finesos (FIM)
+STR_CURR_FRF :Franc (FRF)
+STR_CURR_GRD :Dracmes Gregues (GRD)
+STR_CURR_HUF :Florí Hungarès (HUF)
+STR_CURR_ISK :Corones Islandeses (ISK)
+STR_CURR_ITL :Lires Italianes (ITL)
+STR_CURR_NLG :Florins Holandesos (NLG)
+STR_CURR_NOK :Corones Noruegues (NOK)
+STR_CURR_PLN :Zloty Polac (PLN)
+STR_CURR_ROL :Leu RomanÚs (ROL)
+STR_CURR_RUR :Rubles Russos (RUR)
+STR_CURR_SIT :Eslovè Tolar (SIT)
+STR_CURR_SEK :Corones Sueques (SEK)
+STR_CURR_YTL :Lira Turca (YTL)
+STR_CURR_SKK :Corona Eslovaca (SKK)
+STR_CURR_BRR :Real Brasiler (BRL)
+
+STR_CURR_CUSTOM :Personalitzat...
+
+STR_OPTIONS_LANG :{BLACK}Idioma
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Selecciona l'idioma de la interficie
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Pantalla Completa
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}Marca la casella per tenir l'OpenTTD en pantalla completa
+
+STR_OPTIONS_RES :{BLACK}Resolució de Pantalla
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Selecciona la resolució de pantalla
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Format de captures de pantalla
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Selecciona el format per les captures de pantalla
+
+STR_AUTOSAVE_1_MONTH :Cada mes
+STR_AUTOSAVE_FAILED :{WHITE}Ha fallat el desat automàtic
+
+STR_MONTH_JAN :Gener
+STR_MONTH_FEB :Febrer
+STR_MONTH_MAR :Març
+STR_MONTH_APR :Abril
+STR_MONTH_MAY :Maig
+STR_MONTH_JUN :Juny
+STR_MONTH_JUL :Juliol
+STR_MONTH_AUG :Agost
+STR_MONTH_SEP :Setembre
+STR_MONTH_OCT :Octubre
+STR_MONTH_NOV :Novembre
+STR_MONTH_DEC :Desembre
+
+STR_HEADING_FOR_STATION :{LTBLUE}Cap a {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}Cap a {STATION}, a {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Sense ordres
+STR_NO_ORDERS_VEL :{LTBLUE}Sense ordres, a {VELOCITY}
+
+STR_PASSENGERS :passatgers
+STR_BAGS :sacs
+STR_TONS :tones
+STR_LITERS :litres
+STR_ITEMS :caps
+STR_CRATES :palets
+STR_RES_OTHER :altres
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}No es pot compartir la llista d'ordres...
+STR_CANT_COPY_ORDER_LIST :{WHITE}No es pot copiar la llista d'ordres...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - Fi d'Ordres Compartides - -
+
+STR_TRAIN_IS_LOST :{WHITE}El tren {COMMA} s'ha perdut.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}El benefici del tren {COMMA} el darrer any ha estat de {CURRENCY}
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}Unió Monetària Europea!{}{}S'introdueix l'Euro com a moneda única per les transaccions diàries del teu país!
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Tren {COMMA} té massa poques ordres a la planificació
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}Tren {COMMA} té una ordre buida
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}Tren {COMMA} té ordres duplicades
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}Tren {COMMA} té una estació incorrecta en les ordres
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}Vehicle Rodat {COMMA} té massa poques ordres a la planificació
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}Vehicle Rodat {COMMA} té una ordre buida
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}Vehicle Rodat {COMMA} té ordres duplicades
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}Vehicle Rodat {COMMA} té una estació incorrecta en les ordres
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}Vaixell {COMMA} té massa poques ordres a la planificació
+STR_SHIP_HAS_VOID_ORDER :{WHITE}Vaixell {COMMA} té una ordre buida
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}Vaixell {COMMA} té ordres duplicades
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}Vaixell {COMMA} té una estació incorrecta en les ordres
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}Aeronau {COMMA} té massa poques ordres a la planificació
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}Aeronau {COMMA} té una ordre buida
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}Aeronau {COMMA} has duplicate orders
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}Aeronau {COMMA} té una estació incorrecta en les ordres
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}Autorenovació ha fallat al tren {COMMA} (límit de diners)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}Autorenovació ha fallat a l'automòbil {COMMA} (límit de diners)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}Autorenovació ha fallat al vaixell {COMMA} (límit de diners)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}Autorenovació ha fallat a l'aeronau {COMMA} (límit de diners)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}El tren {COMMA} és massa llarg després del canvi
+
+STR_CONFIG_PATCHES :{BLACK}Configura Pedaços
+STR_CONFIG_PATCHES_TIP :{BLACK}Configurar els pedaços
+STR_CONFIG_PATCHES_CAPTION :{WHITE}Configura Pedaços
+
+STR_CONFIG_PATCHES_OFF :Inactiu
+STR_CONFIG_PATCHES_ON :Actiu
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Mostra la velocitat del vehicle a la barra d'estat: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Permet construir en desnivells i costes: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Permet un tamany més real de l'àrea d'influència: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Permet l'esborrat de propietats de les poblacions: carreteres, ponts, túnels, etc: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Activa la construcció de trens molt llargs: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Activa l'acceleració realista per als trens: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Prohibeix fer girs de 90 graus als trens i vaixells: {ORANGE}{STRING} {LTBLUE} (necessita NPF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Ajunta estacions de tren fetes al costat d'una altra: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Marxa de l'estació quan un tipus de càrrega estigui ple, si 'càrrega completa': {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Utilitza algorisme millorat de càrrega: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GRADUAL_LOADING :{LTBLUE}Carrega els vehicles gradualment: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Inflació: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Entrega càrreges en una estació només quan ho demana: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Permet construir ponts molt llargs: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Permet ordres anar a cotxeres: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Permet fabricar material no processat en indústries: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Permet vàries indústries similars per població: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Permet construir a prop indústries del mateix tipus: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Mostra sempre la data llarga a la barra d'estat: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Mostra senyals en el sentit de la marxa: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Mostra finestra de balanç al finalitzar cada any: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}Gestió de la funció 'nonstop' compatible amb TTDPatch: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Cues d'automòbils (amb efectes quàntics): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Finestra d'avis quan el ratolí és al marc del programa: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Permet subornar a les autoritats locals: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Estacions no uniformes: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Nova cerca de rutes global (NPF, anul·la NTP): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FREIGHT_TRAINS :{LTBLUE}Multiplicador de pes per contenidor per simular trens pesats: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Permet sempre aeroports petits: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Avisa si un tren es perd: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Revisa ordres dels vehicles: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :no
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :si, excepte vehicles parats
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :per a tots els vehicles
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Avisa si els ingressos dels trens són negatius: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Els vehicles mai caduquen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Autorenova el vehicle quan sigui vell
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Autorenova el vehicle quan tingui {ORANGE}{STRING}{LTBLUE} mesos abans/després antig. max.
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Autorenovació: mínim de diners per renovar: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Duració del missatge d'error: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Mostra els habitants a la etiqueta del nom de població: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Arbres invisibles (amb edificis transparents): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Generador de terrenys: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :Original
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis
+STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}Max distància des del vertex per Refineries de Petroli{ORANGE}{STRING}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Alçada de la cota de neu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN :{LTBLUE}Geografia del terreny (TerraGenesis només) : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Molt suau
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH :Suau
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH :Escarpat
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :Molt escarpat
+STR_CONFIG_PATCHES_TREE_PLACER :{LTBLUE}Algorisme per situar arbres: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TREE_PLACER_NONE :Cap
+STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL :Original
+STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED :Millorat
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION :{LTBLUE}Rotació del mapa d'alçades: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Anti-horari
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE :Horari
+STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT :{LTBLUE}Alçada que un escenari pla pren: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Max extensió de estacions: {ORANGE}{STRING}{RED}Avís: Un valor alt enlenteix el joc
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Manteniment dels helicopters als heliports automàticament: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Enllaça la barra d'eines del paisatge a les barres d'eines de vies/carreteres/aigua/aeroports {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}En desplaçar la pantalla amb el ratolí mou la vista en la direcció contrària: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Mostra un cartell de mesura quan estiguis utilitzant vàries eines de construcció: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Mostra la decoració de la companyia: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES_NONE :Cap
+STR_CONFIG_PATCHES_LIVERIES_OWN :Pròpia companyia
+STR_CONFIG_PATCHES_LIVERIES_ALL :Totes les companyies
+STR_CONFIG_PATCHES_PREFER_TEAMCHAT :{LTBLUE}Prefereix fer un chat d'equip amb <ENTER>: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Max trens per jugador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Max automòbils per jugador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}Max aeronaus per jugador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}Max vaixells per jugador: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Desactiva trens per l'ordinador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Desactiva automòbils per a l'ordinador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Desactiva aeronaus per l'ordinador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Desactiva vaixells per l'ordinador: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Activa nova IA (alfa): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Permet IAs en multijugador (experimental): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Interval de manteniment per defecte dels trens: {ORANGE}{STRING} dies/%
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Interval de manteniment per defecte dels trens: {ORANGE}desactivat
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Interval de manteniment per defecte dels automòbils: {ORANGE}{STRING} dies/%
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Interval de manteniment per defecte dels automòbils: {ORANGE}desactivat
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Interval de manteniment per defecte de les aeronaus: {ORANGE}{STRING} dies/%
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Interval de manteniment per defecte de les aeronaus: {ORANGE}desactivat
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Interval de manteniment per defecte dels vaixells: {ORANGE}{STRING} dies/%
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Interval de manteniment per defecte dels vaixells: {ORANGE}desactivat
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Desactiva manteniment quan les avaries s'estableixen a cap: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Activa limit de velocitat per al vagó: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}Desactiva vies electrificades: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Les notícies en color apareixen en: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Data d'inici: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}Fi del joc en: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Activa economia suau (més canvis però més petits)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Permet comprar participacions d'altres empreses
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Arrossegant, sitúa senyals cada: {ORANGE}{STRING} quadre(s)
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Posició de la barra d'eines principal: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Esquerra
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Centre
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Dreta
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Radi de snap de finestra: {ORANGE}{STRING} px
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Radi de snap de finestra: {ORANGE}desactivat
+
+STR_CONFIG_PATCHES_GUI :{BLACK}Interficie
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Construcció
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Vehicles
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Estacions
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Economia
+STR_CONFIG_PATCHES_AI :{BLACK}Competidors
+
+STR_CONFIG_PATCHES_DISABLED :desactivat
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Canvia el valor de l'adjustament
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Alguns o tots els intervals de manteniment següents són incompatibles amb el valor triat! 5-90% i 30-800 dies són els vàlids
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}Utilitza YAPF pels vaixells: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}Utilitza YAPF pels automòvils: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}Utilitza YAPF pels trens: {ORANGE}{STRING}
+
+STR_TEMPERATE_LANDSCAPE :paisatge temperat
+STR_SUB_ARCTIC_LANDSCAPE :paisatge subàrtic
+STR_SUB_TROPICAL_LANDSCAPE :paisatge subtropical
+STR_TOYLAND_LANDSCAPE :paisatge de joguines
+
+STR_CHEATS :{WHITE}Trampes
+STR_CHEATS_TIP :{BLACK}Els quadres marcats indiquen que ja has fet servir aquesta trampa
+STR_CHEATS_WARNING :{BLACK}Atenció! Estàs a punt d'enredar als teus companys competidors. Pensa que una cosa així serà recordada per tota la eternitat!.
+STR_CHEAT_MONEY :{LTBLUE}Incrementa els diners en {CURRENCY64}
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Juga com el jugador: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Eruga màgica (treu indústries, inamovibles): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Els túnels es poden creuar: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Construeix mentre el joc està en pausa: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Els avions a reacció no tindran (freqüents) accidents en els aeroports petits: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Canvia el clima: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Canvia la data: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}Activa la modificació de valors de producció: {ORANGE}{STRING}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}Cap a {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Cap a {WAYPOINT}, a {VELOCITY}
+
+STR_GO_TO_WAYPOINT :Ves via {WAYPOINT}
+STR_GO_NON_STOP_TO_WAYPOINT :Ves sense parar via {WAYPOINT}
+
+STR_WAYPOINTNAME_CITY :Punt de Control {TOWN}
+STR_WAYPOINTNAME_CITY_SERIAL :Punt de Control {TOWN} #{COMMA}
+STR_LANDINFO_WAYPOINT :Punt de Control
+
+STR_WAYPOINT :{WHITE}Punt de control
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Selecciona tipus de punt de control
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}Edita nom de punt de control
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}No es pot canviar el nom del punt de control...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Converteix una via a punt de control
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Aquí no es pot construir punt de control de tren...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Aquí no es pot treure punt de control de tren...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Construeix vies de tren utilitzant el mode Autorail
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}...no hi ha poblacions en aquest escenari
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}Estàs segur que vols crear un paisatge aleatori?
+STR_MANY_RANDOM_TOWNS :{BLACK}Moltes poblacions aleatòries
+STR_RANDOM_TOWNS_TIP :{BLACK}Omple el mapa amb poblacions situades aleatòriament
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Moltes indústries aleatòries
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Omple el mapa amb indústries situades aleatòriament
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}No es poden generar indústries...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Obre la barra d'eines del terreny per elevar/rebaixar nivell, plantar arbres, etc.
+STR_LANDSCAPING_TOOLBAR :{WHITE}Creant paisatge
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Nivell de terreny
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Arbres de tipus aleatori
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}Situar arbres de tipus aleatori
+
+STR_CANT_BUILD_CANALS :{WHITE}Aquí no es poden construir canals...
+STR_BUILD_CANALS_TIP :{BLACK}Construeix canals
+STR_LANDINFO_CANAL :Canal
+
+STR_CANT_BUILD_LOCKS :{WHITE}Aquí no es pot construir una resclosa...
+STR_BUILD_LOCKS_TIP :{BLACK}Construeix rescloses
+STR_LANDINFO_LOCK :Resclosa
+
+STR_BUOY_IS_IN_USE :{WHITE}...boia en ús!
+
+STR_LANDINFO_COORDS :{BLACK}Coordenades: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}No es pot treure part de la estació...
+STR_CANT_CONVERT_RAIL :{WHITE}Aquí no es pot convertir el tipus de via...
+STR_CONVERT_RAIL_TIP :{BLACK}Converteix/Millora el tipus de via
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Arrossega la màquina de tren aquí per vendre el tren sencer
+
+STR_DRAG_DROP :{BLACK}Arrossega i Deixa
+STR_STATION_DRAG_DROP :{BLACK}Construeix una estació arrossegant i deixant
+STR_SELECT_STATION_CLASS_TIP :{BLACK}Selecciona un tipus de estació a mostrar
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Selecciona el tipus de estació a construir
+
+STR_FAST_FORWARD :{BLACK}Avanç ràpid del joc
+STR_MESSAGE_HISTORY :{WHITE}Històric de Missatges
+STR_MESSAGE_HISTORY_TIP :{BLACK}Llista de les notícies més recents
+STR_MESSAGES_DISABLE_ALL :{BLACK}Desactiva tots
+STR_MESSAGES_ENABLE_ALL :{BLACK}Activa tots
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Construeix Mina de Carbó
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Planta Bosc
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Construeix una Plataforma Petrolífera
+STR_CONSTRUCT_FARM_TIP :{BLACK}Funda Granja
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Construeix una Mina de Coure
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Perfora per buscar Petroli
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Construeix una Mina d'Or
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Construeix una Mina de Diamants
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Construeix una Mina de Ferro
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Funda Plantació de Fruita
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Funda Plantació de Cautxú
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Funda Surtidor d'Aigua
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Planta Bosc de Cotó de Sucre
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}Funda Granja de Piles
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Perfora per buscar Cola
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Funda Fonts de Plàstic
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Construeix un Generador de Bombolles
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Funda Cantera de Caramel
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Construeix una Mina de Sucre
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Indústries
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA}% transportat)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA}%/{COMMA}% transportat)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}...massa a prop d'altres indústries
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Remodela tren per transportar un altre tipus de càrrega
+STR_RAIL_REFIT_VEHICLE :{BLACK}Remodela tren
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Selecciona tipus de càrrega a transportar
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Remodela tren per transportar el tipus de càrrega seleccionat
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}No es pot remodelar el tren...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Els intervals de manteniment estàn en percentatges: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Canvi de producció
+
+TEMP_AI_IN_PROGRESS :{WHITE}Benvingut a aquesta nova IA, en desenvolupament. Pot ser que tinguis problemes. Quan en tinguis, fes una còpia de pantalla i publícala al forums.
+TEMP_AI_ACTIVATED :{WHITE}Atenció: aquest nova IA encara està en versió alfa! Actualment, només funcionen els autobusos i camions!
+TEMP_AI_MULTIPLAYER :{WHITE}Atenció: aquesta funció encara és experimental. Si us plau, informeu de qualsevol problema amb ella a truelight@openttd.org (en anglès).
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Multijugador
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Nom del jugador:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}Aquest és el nom amb el que els altres jugadors t'identificaran
+STR_NETWORK_CONNECTION :{BLACK}Connexió:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Tria entre jugar per internet o jugar en xarxa local
+
+STR_NETWORK_START_SERVER :{BLACK}Inicia el servidor
+STR_NETWORK_START_SERVER_TIP :{BLACK}Inicia en un servidor propi
+
+STR_NETWORK_GAME_NAME :{BLACK}Nom
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Nom del joc
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Idioma, versió de servidor, etc.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Clica en un joc de la llista per triar-lo
+
+STR_NETWORK_FIND_SERVER :{BLACK}Busca servidor
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Cercant un servidor a la xarxa
+STR_NETWORK_ADD_SERVER :{BLACK}Afegeix un servidor
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Afegeix un servidor a la llista que sempre es comprovarà per a jocs iniciats.
+STR_NETWORK_ENTER_IP :{BLACK}Entra l'adreça IP del servidor
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Clients
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Clients en línia / clients màxim
+STR_NETWORK_GAME_INFO :{SILVER}INFORMACIÓ DEL JOC
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Clients: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Idioma: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Grup de cel·les: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Tamany del mapa: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}Versió del servidor: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}Adreça del servidor: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Data inicial: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Data actual: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Protegit per contrasenya!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}SERVIDOR DESCONNECTAT
+STR_NETWORK_SERVER_FULL :{SILVER}SERVIDOR PLÉ
+STR_NETWORK_VERSION_MISMATCH :{SILVER}LA VERSIÓ NO COINCIDEIX
+STR_NETWORK_GRF_MISMATCH :{SILVER}NO COINCIDÈNCIA DE NEWGRF
+
+STR_NETWORK_JOIN_GAME :{BLACK}Connectar-se al joc
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}Inicia un nou joc multijugador
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Nom del joc:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}El nom del joc es mostrarà a altres jugadors en el menú de selecció de joc multijugador
+STR_NETWORK_SET_PASSWORD :{BLACK}Posa una contrasenya
+STR_NETWORK_PASSWORD_TIP :{BLACK}Protegeix el teu joc amb una contrasenya si no vols que d'altre gent el pugui utilitzar
+STR_NETWORK_SELECT_MAP :{BLACK}Selecciona un mapa:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}amb quin mapa vols jugar?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}Màxim de clients permesos:
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Tria el nombre màxim de clients. No és necessari omplir tots els llocs.
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :LAN
+STR_NETWORK_INTERNET :Internet
+STR_NETWORK_LAN_INTERNET :LAN / Internet
+STR_NETWORK_INTERNET_ADVERTISE :Internet (anunci)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 jugadors
+STR_NETWORK_1_PLAYERS :1 jugador
+STR_NETWORK_2_PLAYERS :2 jugadors
+STR_NETWORK_3_PLAYERS :3 jugadors
+STR_NETWORK_4_PLAYERS :4 jugadors
+STR_NETWORK_5_PLAYERS :5 jugadors
+STR_NETWORK_6_PLAYERS :6 jugadors
+STR_NETWORK_7_PLAYERS :7 jugadors
+STR_NETWORK_8_PLAYERS :8 jugadors
+STR_NETWORK_9_PLAYERS :9 jugadors
+STR_NETWORK_10_PLAYERS :10 jugadors
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}Màx companyies:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Limita el servidor a un cert nombre de companyies
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}Màx espectadors:
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Limita el servidor a un cert nombre de espectadors
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Idioma parlat:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Els altres jugadors sabran quin idioma es parla en aquest servidor.
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}Inicia el Joc
+STR_NETWORK_START_GAME_TIP :{BLACK}Inicia un nou joc de xarxa des de un mapa aleatori, o escenari
+STR_NETWORK_LOAD_GAME :{BLACK}Carrega Joc
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Continúa amb un joc multijugador desat previament (comprova de connectar-te amb el jugador correcte)
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Qualsevol
+STR_NETWORK_LANG_ENGLISH :Anglès
+STR_NETWORK_LANG_GERMAN :Alemany
+STR_NETWORK_LANG_FRENCH :Francès
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Lobby de partida multijugador
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Preparant per connectar: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}Una llista de totes les empreses actuals en aquest joc. Pots utilitzar-ne una o bé iniciar-ne una de nova si hi ha algún lloc lliure
+STR_NETWORK_NEW_COMPANY :{BLACK}Nova Empresa
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Obre una nova Empresa
+STR_NETWORK_SPECTATE_GAME :{BLACK}Espectador
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Veure el joc com a espectador
+STR_NETWORK_JOIN_COMPANY :{BLACK}Uneix-te a l'empresa
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Ajuda a gestionar aquesta empresa
+STR_NETWORK_REFRESH :{BLACK}Actualitza servidor
+STR_NETWORK_REFRESH_TIP :{BLACK}Actualitza la informació del servidor
+
+STR_NETWORK_COMPANY_INFO :{SILVER}INFORMACIÓ DE L'EMPRESA
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Nom empresa: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}Inauguració: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}Valor de l'empresa: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Balanç actual: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Ingressos de l'últim any: {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}Rendiment: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}Vehicles: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Estacions: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Jugadors: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}Connectant...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) Connectant..
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Autoritzant..
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Esperant..
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Descarregant mapa..
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Processant dades..
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) Registrant..
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Obtenint informació del joc..
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Obtenint informació de l'empresa..
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} client{P "" s} rivals
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} kbytes descarregats fins ara
+
+STR_NETWORK_DISCONNECT :{BLACK}Desconnecta
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Introdueix la quantitat de diners que vols obtenir
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Servidor protegit. Entra la contrasenya
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Empresa protegida. Entra la contrasenya
+STR_NETWORK_CLIENT_LIST :{WHITE}Llista de Clients
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE} No s'han trobat dispositius de xarxa o s'ha compilat sense l'opció ENABLE_NETWORK
+STR_NETWORK_ERR_NOSERVER :{WHITE} No es pot trobar cap joc a la xarxa
+STR_NETWORK_ERR_NOCONNECTION :{WHITE} El servidor no ha respós al requeriment
+STR_NETWORK_ERR_DESYNC :{WHITE} Ha fallat la sincronització del joc de xarxa.
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} S'ha perdut la connexió al joc de xarxa.
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} No es pot carregar un joc desat al servidor.
+STR_NETWORK_ERR_SERVER_START :{WHITE} No es pot inciar el servidor.
+STR_NETWORK_ERR_CLIENT_START :{WHITE} No es pot connectar.
+STR_NETWORK_ERR_TIMEOUT :{WHITE} La connexió #{NUM} ha esgotat el temps d'espera.
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE} S'ha obtingut un error de protocol i s'ha tancat la connexió.
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE} La revisió d'aquest client no concorda amb la revisió del servidor.
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} Contrasenya incorrecta.
+STR_NETWORK_ERR_SERVER_FULL :{WHITE} El servidor és plé
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} Estàs exclòs d'aquest servidor
+STR_NETWORK_ERR_KICKED :{WHITE} T'han fet fora del servidor
+STR_NETWORK_ERR_CHEATER :{WHITE} No es permet fer trampes en aquest servidor
+
+STR_NETWORK_ERR_LEFT :ha deixat el joc
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :error general
+STR_NETWORK_ERR_CLIENT_DESYNC :error de desincronització
+STR_NETWORK_ERR_CLIENT_SAVEGAME :no es pot carregar el mapa
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :connexió perduda
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :error de protocol
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :no autoritzat
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :s'ha rebut un paquet de dades extrany
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :revisió incorrecta
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :nom ja utilitzat
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :contrasenya de joc incorrecta
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :id de jugador incorrecta en DoCommand
+STR_NETWORK_ERR_CLIENT_KICKED :tret pel servidor
+STR_NETWORK_ERR_CLIENT_CHEATER :s'ha intentat utilitzar una trampa
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :servidor ple
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :ha entrat al joc
+STR_NETWORK_GIVE_MONEY :gave you some money ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :Has entregat {STRING} diners ({CURRENCY})
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Team] :
+STR_NETWORK_CHAT_COMPANY :[Team] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Team] a {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[Private] :
+STR_NETWORK_CHAT_CLIENT :[Private] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[Private] a {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[All] :
+STR_NETWORK_CHAT_ALL :[All] {STRING}: {GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :ha canviat el seu nom a
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE} El servidor ha tancat la sesió
+STR_NETWORK_SERVER_REBOOT :{WHITE} El servidor està reiniciant...{}Espera un moment...
+
+STR_NETWORK_SERVER :Servidor
+STR_NETWORK_CLIENT :Client
+STR_NETWORK_SPECTATORS :Espectadors
+
+STR_NETWORK_CLIENTLIST_NONE :
+STR_NETWORK_CLIENTLIST_KICK :Breu
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Entrega diners
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Parla a tothom
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Parla a l'Empresa
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Missatge Privat
+
+
+STR_NETWORK_SEND :{BLACK}Envia
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}Tamany-X del mapa: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Tamany-Y del mapa: {ORANGE}{STRING}
+
+
+##### PNG-MAP-Loader
+
+STR_PNGMAP_ERROR :{WHITE}Impossible carregar un terreny des del PNG...
+STR_PNGMAP_ERR_FILE_NOT_FOUND :{WHITE}...fitxer no trobat.
+STR_PNGMAP_ERR_IMAGE_TYPE :{WHITE}...impossible convertir l'imatge. Es necessita una imatge PNG de 8 o 24-bit.
+STR_PNGMAP_ERR_MISC :{WHITE}...alguna cosa ha anat malament. Perdó. (probablement un fitxer corrupte)
+
+STR_BMPMAP_ERROR :{WHITE}Impossible carregar el terreny des del BMP...
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}...no s'ha pogut convertir la imatge.
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Cost: {CURRENCY}
+STR_0801_COST :{RED}Cost: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Ingressos: {CURRENCY}
+STR_0803_INCOME :{GREEN}Ingressos: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Transfereix: {CURRENCY}
+STR_FEEDER :{YELLOW}Transfereix: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Cost Estimat: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Ingressos Estimats: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Aquí no es pot elevar el terreny...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Aquí no es pot rebaixar el terreny...
+STR_080A_ROCKS :Roques
+STR_080B_ROUGH_LAND :Terreny Irregular
+STR_080C_BARE_LAND :Terreny erm
+STR_080D_GRASS :Gespa
+STR_080E_FIELDS :Camps
+STR_080F_SNOW_COVERED_LAND :Terreny nevat
+STR_0810_DESERT :Desert
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Terreny inclinat en direcció incorrecta
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Combinació de vies imposible
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}La excavació pot malmetre el túnel
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Ja ets a nivell del mar
+STR_1004_TOO_HIGH :{WHITE}Massa alt
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Via de tren no apropiada
+STR_1007_ALREADY_BUILT :{WHITE}...ja construit
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}S'ha de treure la via primer
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Construcció de Ferrocarril
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Construcció de Via Electrificada
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Construcció de Monorail
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}Construcció de Maglev
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Selecciona pont per la via
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Aquí no es poden construir cotxeres de tren...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Aquí no es pot construir una estació de tren...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Aquí no es poden construir senyals...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Aquí no es pot construir la via de tren...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Aquí no es pot treure la via de tren...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Aquí no es poden treure les senyals...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Cotxeres de Tren
+STR_1015_RAILROAD_CONSTRUCTION :Construcció de Ferrocarril
+STR_TOOLB_ELRAIL_CONSTRUCTION :Contrucció de Via Electrificada
+STR_1016_MONORAIL_CONSTRUCTION :Construcció de Monorail
+STR_1017_MAGLEV_CONSTRUCTION :Construcció de Maglev
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Construeix via de tren
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Construcció de cotxeres de tren (per construcció i manteniment de trens)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Construeix una estació de tren
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Construeix senyals de tren
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Construeix un pont de tren
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Construeix túnel de tren
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Intercanvia funció construeix/treu per vies de tren i senyals
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Selecció de pont - clica al pont triat per construir-lo
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Selecciona la orientació de les Cotxeres de tren
+STR_1021_RAILROAD_TRACK :Via de tren
+STR_1023_RAILROAD_TRAIN_DEPOT :Cotxeres de tren
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...l'àrea és propietat d'una altra empresa
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :Via de tren amb senyals normals
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :Via de tren amb pre-senyals
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :Via de tren amb senyals de sortida
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :Via de tren amb senyals combinades
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}S'ha de treure la carretera primer
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Obres en progrés
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Construcció de Carreteres
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Selecciona un Pont per Carretera
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Aquí no es pot construir una carretera...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Aquí no es pot treure una carretera...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Cotxeres
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Aquí no es pot construir una cotxera...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}No es pot construir una parada d'autobús...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}No es pot construir estació de mercaderies...
+STR_180A_ROAD_CONSTRUCTION :Construcció de Carreteres
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Construeix una secció de carretera
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Construeix una cotxera (per construir i mantenir vehicles)
+STR_180D_BUILD_BUS_STATION :{BLACK}Constueix una parada d'autobús
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Construeix un moll de càrrega
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Construeix un pont per carretera
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Construeix un túnel per carretera
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Intercanvia funció construeix/treu per la construcció de carreteres
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Selecciona la orientació de les Cotxeres
+STR_1814_ROAD :Carretera
+STR_1815_ROAD_WITH_STREETLIGHTS :Carretera amb fanals
+STR_1816_TREE_LINED_ROAD :Carretera de tres carrils
+STR_1817_ROAD_VEHICLE_DEPOT :Cotxeres
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :Pas a nivell
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Poblacions
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}L'edifici s'ha d'enderrocar primer
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}Població: {ORANGE}{COMMA}{BLACK} Cases: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Reanomena Població
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}No es pot reanomenar la població...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}Les autoritats locals de {TOWN} no permeten fer això
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Noms de Població - clica al nom per centrar la pantalla principal a la població
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centra la pantalla principal a la població
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Canvia el nom de la població
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passatgers el darrer mes: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Correu el darrer mes: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Bloc d'oficines alt
+STR_2010_OFFICE_BLOCK :Bloc d'oficines
+STR_2011_SMALL_BLOCK_OF_FLATS :Petit bloc d'apartaments
+STR_2012_CHURCH :Esglèsia
+STR_2013_LARGE_OFFICE_BLOCK :Bloc d'oficines gran
+STR_2014_TOWN_HOUSES :Cases de la població
+STR_2015_HOTEL :Hotel
+STR_2016_STATUE :Estàtua
+STR_2017_FOUNTAIN :Font
+STR_2018_PARK :Parc
+STR_2019_OFFICE_BLOCK :Bloc d'oficines
+STR_201A_SHOPS_AND_OFFICES :Botigues i Oficines
+STR_201B_MODERN_OFFICE_BUILDING :Edifici d'oficines modern
+STR_201C_WAREHOUSE :Gran Magatzem
+STR_201D_OFFICE_BLOCK :Bloc d'oficines
+STR_201E_STADIUM :Estadi
+STR_201F_OLD_HOUSES :Cases velles
+STR_2020_LOCAL_AUTHORITY :{BLACK}Autoritat local
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Mostra informació de l'autoritat local
+STR_2022_LOCAL_AUTHORITY :{WHITE}{TOWN} autoritat local
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Ratis de l'Empresa de Transports:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Subvencions
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Subvencions per prestació de serveis oferts:
+STR_2027_FROM_TO :{ORANGE}{STRING} de {STRING} a {STRING}
+STR_2028_BY :{YELLOW} (per {DATE_SHORT})
+STR_202A_NONE :{ORANGE}Cap
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Serveis ja subvencionats:
+STR_202C_FROM_TO :{ORANGE}{STRING} des de {STATION} fins a {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, fins a {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}Oferiment de subvenció caducada: {}{}{STRING} des de {STRING} fins a {STRING} s'ha declarat desert.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Subvenció retirada:{}{}{STRING} des de {STATION} fins a {STATION} ja no està subvencionat.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Subvenció per un servei oferta:{}{} El primer servei de {STRING} des de {STRING} fins a {STRING} tindrà una subvenció d'un any de l'autoritat local!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subvenció per Servei concedida a {COMPANY}!{}{} Servei de {STRING} des de {STATION} fins a {STATION} rebrà un 50% addicional durant el pròxim any!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subvenció per Servei concedida a {COMPANY}!{}{} Servei de {STRING} des de {STATION} fins a {STATION} percebrà el doble de la tarifa durant el pròxim any!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subvenció per Servei concedida a {COMPANY}!{}{} Servei de {STRING} des de {STATION} fins a {STATION} percebrà el triple de la tarifa durant el pròxim any!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subvenció per Servei concedida a {COMPANY}!{}{} Servei de {STRING} des de {STATION} fins a {STATION} percebrà el quàdruple de la tarifa durant el pròxim any!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} l'autoritat local denega el permís de construir un altre aeroport en aquesta població
+STR_2036_COTTAGES :Xalets
+STR_2037_HOUSES :Cases
+STR_2038_FLATS :Apartaments
+STR_2039_TALL_OFFICE_BLOCK :Bloc alt d'oficines
+STR_203A_SHOPS_AND_OFFICES :Botigues i oficines
+STR_203B_SHOPS_AND_OFFICES :Botigues i oficines
+STR_203C_THEATER :Teatre
+STR_203D_STADIUM :Estadi
+STR_203E_OFFICES :Oficines
+STR_203F_HOUSES :Cases
+STR_2040_CINEMA :Cine
+STR_2041_SHOPPING_MALL :Grans Magatzems
+STR_2042_DO_IT :{BLACK}Fer-ho
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}Llista de coses per fer en aquesta població - clica en un item per més detalls
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Treure l'acció marcada de la llista anterior
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Accions disponibles:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Petita campanya de publicitat
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Mitjana campanya de publicitat
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Gran campanya de publicitat
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Patrocina la reconstrucció dels carrers de la població
+STR_204A_BUILD_STATUE_OF_COMPANY :Construeix una estàtua del propietari de l'empresa
+STR_204B_FUND_NEW_BUILDINGS :Patrocina nous edificis
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Compra els drets de transport en exclusiva
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Subornar les autoritats locals
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Inicia una petita campanya de publicitat, per atraure més passatgers i càrregues als teus serveis de transport.{} Cost: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Inicia una mitjana campanya de publicitat, per atraure més passatgers i càrregues als teus serveis de transport.{} Cost: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Inicia una gran campanya de publicitat, per atraure més passatgers i càrregues als teus serveis de transport.{} Cost: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} Patrocina la reconstrucció de la xarxa local de carrers. Causa una notable distorsió del trànsit durant 6 mesos.{} Cost: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Construeix una estatua en honor a la teva empresa.{} Cost: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Patrocina la construcció de nous edificis comercials en la població.{} Cost: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Compra per 1 any els drets exclusius de transport en la població. La autoritat local només permetrà utilitzar les instal·lacions de la teva empresa de transports als passatgers i les mercaderies.{} Cost: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Subornar les autoritats locals per incrementar el teu rati, a risc de greus penalitzacions si et pesquen!!.{} Cost: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}Caos de trànsit en {TOWN}!{}{}El programa de rehabilitació dels carrers patrocinat per {COMPANY} porta 6 mesos de misèria als motoristes!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (en construcció)
+STR_2059_IGLOO :Iglú
+STR_205A_TEPEES :Tipis
+STR_205B_TEAPOT_HOUSE :Casa-Tetera
+STR_205C_PIGGY_BANK :Banc-Guardiola Porquet
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN} {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Paisatges
+STR_2800_PLANT_TREES :Planta arbres
+STR_2801_PLACE_SIGN :Situa una senyal
+STR_2802_TREES :{WHITE}Arbres
+STR_2803_TREE_ALREADY_HERE :{WHITE}...aquí ja hi ha arbres
+STR_2804_SITE_UNSUITABLE :{WHITE}...lloc inadequat
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Aquí no es poden plantar arbres...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...massa senyals
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Aquí no es pot situar una senyal...
+STR_280A_SIGN :Senyal
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Edita el text de la senyal
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}No es pot canviar el nom del senyal...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Selecciona el tipus d'arbre a plantar
+STR_280E_TREES :Arbres
+STR_280F_RAINFOREST :Selva Tropical
+STR_2810_CACTUS_PLANTS :Plantes de Cactus
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Estacions de Tren
+STR_3001_AIRPORT_SELECTION :{WHITE}Aeroports
+STR_3002_ORIENTATION :{BLACK}Orientació
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Nombre de vies
+STR_3004_PLATFORM_LENGTH :{BLACK}Mida de les andanes
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Massa a prop d'una altra estació de tren
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Fusiona més d'una estació/àrea de càrrega existent
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}Hi ha massa estacions/àrees de càrrega en aquesta població
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}Massa estacions/àrees de càrrega
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Massa parades d'autobús
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}Masses estacions de càrrega
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Massa a prop d'una altra estació/àrea de càrrega
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Primer has d'enderrocar l'estació de tren
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Massa a prop d'un altre aeroport
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Primer has d'enderrocar l'aeroport
+
+STR_3030_RENAME_STATION_LOADING :Reanomena l'estació/àrea de càrrega
+STR_3031_CAN_T_RENAME_STATION :{WHITE}No es pot reanomenar l'estació...
+STR_3032_RATINGS :{BLACK}Ratis
+STR_3033_ACCEPTS :{BLACK}Accepta
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}Ratis locals del servei de transport:
+
+############ range for rating starts
+STR_3035_APPALLING :Pèsim
+STR_3036_VERY_POOR :Molt Pobre
+STR_3037_POOR :Pobre
+STR_3038_MEDIOCRE :Mediocre
+STR_3039_GOOD :Bó
+STR_303A_VERY_GOOD :Molt Bó
+STR_303B_EXCELLENT :Excelent
+STR_303C_OUTSTANDING :Excepcional
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} ja no accepta més {STRING}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} ja no accepta més {STRING} o {STRING}
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} ara accepta {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} ara accepta {STRING} i {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Parada d'autobús
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Estació de Mercaderies
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Primer has d'enderrocar la parada d'autobús
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Primer has d'enderrocar l'estació de mercaderies
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Estacions/Parades
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Cap -
+STR_304B_SITE_UNSUITABLE :{WHITE}...lloc inadequat
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Massa a prop d'un altre moll
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Primer has d'enderrocar el moll
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Selecciona l'orientació de l'estació de tren
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Selecciona el nombre d'andanes de l'estació de tren
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Selecciona la mida de les andanes de l'estació de tren
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Selecciona l'orientació de la parada d'autobús
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Selecciona l'orientació del moll de càrrega de camions
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Centra la pantalla principal al lloc de l'estació
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Mostra els ratis de l'estació
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Canvia el nom de l'estació
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Mostra la llista de càrregues admeses
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Noms d'estació - clica al nom per centrar la pantalla principal a l'estació
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Selecciona mida/tipus d'aeroport
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :Estació de Ferrocarril
+STR_305F_AIRCRAFT_HANGAR :Hangar d'Aeronaus
+STR_3060_AIRPORT :Aeroport
+STR_3061_TRUCK_LOADING_AREA :Àrea de càrrega de camions
+STR_3062_BUS_STATION :Parada d'autobús
+STR_3063_SHIP_DOCK :Moll per vaixells
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Marcar l'àrea de cobertura del lloc proposat
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}No marcar l'àrea de cobertura del lloc proposat
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Marca l'àrea de cobertura
+STR_3068_DOCK :{WHITE}Moll
+STR_3069_BUOY :Boia
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...boia en el camí
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...estació massa extesa
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...estacions no uniformes desactivades
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Mantin apretat CTRL per a seleccionar més de un item
+
+STR_UNDEFINED :(cadena sense definir)
+STR_STAT_CLASS_DFLT :Estació per defecte
+STR_STAT_CLASS_WAYP :Punt de pas
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Drassanes
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...s'han de construir dins l'aigua
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Aquí no es pot construir una drassana...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Selecciona l'orientació de la drassana
+STR_3804_WATER :Aigua
+STR_3805_COAST_OR_RIVERBANK :Costa o marge de riu
+STR_3806_SHIP_DEPOT :Drassana
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...No es pot construir dins l'aigua
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Desa el Joc
+STR_4001_LOAD_GAME :{WHITE}Carrega un Joc
+STR_4002_SAVE :{BLACK}Desa
+STR_4003_DELETE :{BLACK}Esborra
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} megabytes lliures
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Impossible llegir la unitat de disc
+STR_4007_GAME_SAVE_FAILED :{WHITE}Desat del Joc erroni
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Impossible esborrar l'arxiu
+STR_4009_GAME_LOAD_FAILED :{WHITE}Càrrega del Joc errònia
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}Llista de dispositius de disc, carpetes i arxius de jocs desats
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Nom actualment seleccionat per joc desat
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Esborra el joc desat actualment seleccionat
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Desa el joc actual, usant el nom seleccionat
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Selecciona el Nou Tipus de Joc
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Selecciona l'escenari (verd), joc pre-programat (blau), o el nou joc aleatori
+STR_4010_GENERATE_RANDOM_NEW_GAME :Genera un nou joc aleatori
+STR_4011_LOAD_HEIGHTMAP :{WHITE}Carrega un Mapa d'alçades
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} en el camí
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :Mina de Carbó
+STR_4803_POWER_STATION :Central Tèrmica
+STR_4804_SAWMILL :Serradora
+STR_4805_FOREST :Bosc
+STR_4806_OIL_REFINERY :Refineria de Petroli
+STR_4807_OIL_RIG :Plataforma Petrolífera
+STR_4808_FACTORY :Fàbrica
+STR_4809_PRINTING_WORKS :Arts Gràfiques
+STR_480A_STEEL_MILL :Alt Forn
+STR_480B_FARM :Granja
+STR_480C_COPPER_ORE_MINE :Mina de Coure
+STR_480D_OIL_WELLS :Pous de Petroli
+STR_480E_BANK :Banc
+STR_480F_FOOD_PROCESSING_PLANT :Planta de Manipulació de Queviures
+STR_4810_PAPER_MILL :Paperera
+STR_4811_GOLD_MINE :Mina d'Or
+STR_4812_BANK :Banc
+STR_4813_DIAMOND_MINE :Mina de Diamants
+STR_4814_IRON_ORE_MINE :Mina de Ferro
+STR_4815_FRUIT_PLANTATION :Plantació de Fruita
+STR_4816_RUBBER_PLANTATION :Plantació de Cautxú
+STR_4817_WATER_SUPPLY :Surtidor d'Aigua
+STR_4818_WATER_TOWER :Torre d'Aigua
+STR_4819_FACTORY :Fàbrica
+STR_481A_FARM :Granja
+STR_481B_LUMBER_MILL :Cabana de Fusta
+STR_481C_COTTON_CANDY_FOREST :Bosc de Cotó de Sucre
+STR_481D_CANDY_FACTORY :Fàbrica de Dolços
+STR_481E_BATTERY_FARM :Granja de Piles
+STR_481F_COLA_WELLS :Pous de Refresc
+STR_4820_TOY_SHOP :Botiga de Joguines
+STR_4821_TOY_FACTORY :Fàbrica de Joguines
+STR_4822_PLASTIC_FOUNTAINS :Fonts de Plàstic
+STR_4823_FIZZY_DRINK_FACTORY :Fàbrica de Begudes Gasoses
+STR_4824_BUBBLE_GENERATOR :Generador de Bombolles
+STR_4825_TOFFEE_QUARRY :Cantera de Caramel
+STR_4826_SUGAR_MINE :Mina de Sucre
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Necessita: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Necessita: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Necessita: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Producció del darrer mes:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% transportat)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centra la pantalla principal al lloc de l'indústria
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Nou/nova {STRING} en construcció a prop de {TOWN}!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Nou/nova {STRING} s'està plantant a prop de {TOWN}!
+STR_482F_COST :{BLACK}Cost: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Aquí no es pot construir aquest tipus d'indústria...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...els boscos només es poden plantar sota la cota de neu
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} anuncia el seu inminent tancament!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}Problemes de subministrament fan que {INDUSTRY} anuncïi el seu inminent tancament!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}La falta d'arbres propers fan que {INDUSTRY} anuncïi el seu inminent tancament!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} incrementa la producció!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}Nova veta de carbó trobada a {INDUSTRY}!{}Es preveu doblar la producció!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}Noves reserves de petroli trobades a {INDUSTRY}!{}Es preveu doblar la producció!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}Sistemes de conreu millorats a {INDUSTRY} fan preveure doblar la producció!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}{INDUSTRY} la producció es redueix un 50%
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}Una plaga d'insectes provoca el caos a {INDUSTRY}!{}La producció es redueix un 50%
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...només es pot situar a prop dels límits del mapa
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}La producció de {STRING} a {INDUSTRY} creix un {COMMA}%!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}La producció de {STRING} a {INDUSTRY} es redueix un {COMMA}%!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Tren dins del túnel
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Vehicle dins del túnel
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Un altre túnel en el camí
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Impossible excavar la terra a l'altre extrem del túnel
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Primer has d'enderrocar el túnel
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Primer has d'enderrocar el pont
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}No es pot començar i acabar a la mateixa posició
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Es necessita una certa elevació sobre el terreny o aigua sota el pont
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}Inici i final han d'estar en línia recta
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Lloc inadequat per l'entrada del túnel
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Suspensió, Acer
+STR_500F_GIRDER_STEEL :Biga, Acer
+STR_5010_CANTILEVER_STEEL :Volada, Acer
+STR_5011_SUSPENSION_CONCRETE :Suspensió, Formigó
+STR_5012_WOODEN :De Fusta
+STR_5013_CONCRETE :Formigó
+STR_5014_TUBULAR_STEEL :Tubular, Acer
+STR_BRIDGE_TUBULAR_SILICON :Tubular, Silicona
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Aquí no es pot construir el pont...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Aquí no es pot construir el túnel...
+STR_5017_RAILROAD_TUNNEL :Túnel ferroviari
+STR_5018_ROAD_TUNNEL :Túnel de carretera
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Pont ferroviari en suspensió d'acer
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Pont ferroviari de biga d'acer
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Pont ferroviari de volada d'acer
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Pont ferroviari en suspensió de formigó reforçat
+STR_501F_WOODEN_RAIL_BRIDGE :Pont ferroviari de fusta
+STR_5020_CONCRETE_RAIL_BRIDGE :Pont ferroviari de formigó
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Pont de carretera en suspensió d'acer
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Pont de carretera de biga d'acer
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Pont de carretera de volada d'acer
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Pont de carretera en suspensió de formigó reforçat
+STR_5025_WOODEN_ROAD_BRIDGE :Pont de carretera de fusta
+STR_5026_CONCRETE_ROAD_BRIDGE :Pont de carretera de formigó
+STR_5027_TUBULAR_RAIL_BRIDGE :Pont ferroviari tubular
+STR_5028_TUBULAR_ROAD_BRIDGE :Pont de carretera tubular
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Objecte en el camí
+STR_5801_TRANSMITTER :Repetidor
+STR_5802_LIGHTHOUSE :Far
+STR_5803_COMPANY_HEADQUARTERS :Seu de l'Empresa
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...seu en el camí
+STR_5805_COMPANY_OWNED_LAND :terreny propietat de l'Empresa
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}No pots comprar aquesta àrea de terreny...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...ja és propietat teva!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Sense Nom
+STR_SV_TRAIN_NAME :Tren {COMMA}
+STR_SV_ROADVEH_NAME :Vehicle Rodat {COMMA}
+STR_SV_SHIP_NAME :Vaixell {COMMA}
+STR_SV_AIRCRAFT_NAME :Aeronau {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :{STRING} Nort
+STR_SV_STNAME_SOUTH :{STRING} Sud
+STR_SV_STNAME_EAST :{STRING} Est
+STR_SV_STNAME_WEST :{STRING} Oest
+STR_SV_STNAME_CENTRAL :{STRING} Central
+STR_SV_STNAME_TRANSFER :{STRING} Trànsit
+STR_SV_STNAME_HALT :{STRING} De Munt
+STR_SV_STNAME_VALLEY :{STRING} De Vall
+STR_SV_STNAME_HEIGHTS :{STRING} Coll
+STR_SV_STNAME_WOODS :{STRING} Boscos
+STR_SV_STNAME_LAKESIDE :{STRING} Del Llac
+STR_SV_STNAME_EXCHANGE :{STRING} Intercanvi
+STR_SV_STNAME_AIRPORT :{STRING} Aeroport
+STR_SV_STNAME_OILFIELD :{STRING} Camp de Petroli
+STR_SV_STNAME_MINES :{STRING} Mines
+STR_SV_STNAME_DOCKS :{STRING} Port
+STR_SV_STNAME_BUOY_1 :{STRING} Boia 1
+STR_SV_STNAME_BUOY_2 :{STRING} Boia 2
+STR_SV_STNAME_BUOY_3 :{STRING} Boia 3
+STR_SV_STNAME_BUOY_4 :{STRING} Boia 4
+STR_SV_STNAME_BUOY_5 :{STRING} Boia 5
+STR_SV_STNAME_BUOY_6 :{STRING} Boia 6
+STR_SV_STNAME_BUOY_7 :{STRING} Boia 7
+STR_SV_STNAME_BUOY_8 :{STRING} Boia 8
+STR_SV_STNAME_BUOY_9 :{STRING} Boia 9
+STR_SV_STNAME_ANNEXE :{STRING} Annex
+STR_SV_STNAME_SIDINGS :{STRING} Via Morta
+STR_SV_STNAME_BRANCH :{STRING} Bifurcació
+STR_SV_STNAME_UPPER :Sobre {STRING}
+STR_SV_STNAME_LOWER :Baix {STRING}
+STR_SV_STNAME_HELIPORT :{STRING} Heliport
+STR_SV_STNAME_FOREST :{STRING} Bosc
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Nivell de Dificultat
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Desa
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Fàcil
+STR_6802_MEDIUM :{BLACK}Mitjà
+STR_6803_HARD :{BLACK}Difícil
+STR_6804_CUSTOM :{BLACK}Personalitzable
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}Màxim no. de competidors: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Moment inici Competidors: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}No. de poblacions: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}No. d'indústries: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Màxim préstec inicial: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Interès inicial: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Cost de circulació de Vehicles: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Velocitat de Construcció dels competidors: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Intel·ligència dels competidors: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Avaries dels Vehicles: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Multiplicador de Subvencions: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Cost de construcció: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Tipus de Terreny: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Quantitat de mars/estanys: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Economia: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Canvi de sentit dels trens: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Desastres: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Actitud de l'Ajuntament sobre reestructuracions d'àrees: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :Cap
+STR_6816_LOW :Baix
+STR_6817_NORMAL :Normal
+STR_6818_HIGH :Alt
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Molt lent
+STR_681C_SLOW :Lent
+STR_681D_MEDIUM :Mitjà
+STR_681E_FAST :Ràpid
+STR_681F_VERY_FAST :Molt Ràpid
+STR_VERY_LOW :Molt Baix
+STR_6820_LOW :Baix
+STR_6821_MEDIUM :Mitjà
+STR_6822_HIGH :Alt
+STR_6823_NONE :Cap
+STR_6824_REDUCED :Reduït
+STR_6825_NORMAL :Normal
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Molt Pla
+STR_682B_FLAT :Pla
+STR_682C_HILLY :Accidentat
+STR_682D_MOUNTAINOUS :Montanyenc
+STR_682E_STEADY :Estable
+STR_682F_FLUCTUATING :Variable
+STR_6830_IMMEDIATE :Immediat
+STR_6831_3_MONTHS_AFTER_PLAYER :3 mesos després del jugador
+STR_6832_6_MONTHS_AFTER_PLAYER :6 mesos després del jugador
+STR_6833_9_MONTHS_AFTER_PLAYER :9 mesos després del jugador
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :Al final de la línia, i a les estacions
+STR_6835_AT_END_OF_LINE_ONLY :Només al final de la línia
+STR_6836_OFF :Desactivat
+STR_6837_ON :Activat
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Veure la taula de les majors puntuacions
+STR_6839_PERMISSIVE :Permisiu
+STR_683A_TOLERANT :Tolerant
+STR_683B_HOSTILE :Hostil
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Jugador {COMMA})
+STR_7004_NEW_FACE :{BLACK}Nova Cara
+STR_7005_COLOR_SCHEME :{BLACK}Esquema de color
+STR_7006_COLOR_SCHEME :{GOLD}Esquema de color:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Nou esquema de color
+STR_7008_COMPANY_NAME :{BLACK}Nom Empresa
+STR_7009_PRESIDENT_NAME :{BLACK}Nom President
+STR_700A_COMPANY_NAME :Nom Empresa
+STR_700B_PRESIDENT_S_NAME :Nom President
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}No es pot canviar el nom d'empresa...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}No es pot canviar el nom de president...
+STR_700E_FINANCES :{WHITE}{COMPANY} Economia {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Despeses/Ingressos
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Construcció
+STR_7012_NEW_VEHICLES :{GOLD}Nous Vehicles
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Desp. de Circ. de Trens
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Desp. de Circ. de Vehicles Rodats
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Desp. de Circ. d'Aeronaus
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Desp. de Circ. de Vaixells
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Manteniment de Propietats
+STR_7018_TRAIN_INCOME :{GOLD}Ingressos de Tren
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Ingressos de Vehicles Rodats
+STR_701A_AIRCRAFT_INCOME :{GOLD}Ingressos d'Aeronaus
+STR_701B_SHIP_INCOME :{GOLD}Ingressos de Vaixells
+STR_701C_LOAN_INTEREST :{GOLD}Interessos del Prèstec
+STR_701D_OTHER :{GOLD}Altres
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Total:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Gràfic d'Ingressos
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Gràfic de Rendiment d'Operacions
+STR_7026_BANK_BALANCE :{WHITE}Balanç del Banc
+STR_7027_LOAN :{WHITE}Préstec
+STR_MAX_LOAN :{WHITE}Max. Prèstec: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}Demana {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Amortitza {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...màxim import permès del préstec és {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}No pots demanar més diners...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...No queda préstec per amortitzar
+STR_702E_REQUIRED :{WHITE}...{CURRENCY} necessari
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}No es pot amortitzar préstec...
+STR_INSUFFICIENT_FUNDS :{WHITE}No es poden regalar els diners deixats pel banc...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Selecciona una nova cara pel president
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Canvia l'aspecte dels vehicles de l'empresa
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Canvia el nom del president
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Canvia el nom de l'empresa
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Clica al nou esquema de color triat
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Augmenta l'import del préstec
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Amortitza part del préstec
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(President)
+STR_7038_INAUGURATED :{GOLD}Inaugurat: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Vehicles:
+STR_TRAINS :{WHITE}{COMMA} tren{P "" s}
+STR_ROAD_VEHICLES :{WHITE}{COMMA} automòbil{P "" s}
+STR_AIRCRAFT :{WHITE}{COMMA} aeronau{P "" s}
+STR_SHIPS :{WHITE}{COMMA} vaixell{P "" s}
+STR_7042_NONE :{WHITE}Cap
+STR_7043_FACE_SELECTION :{WHITE}Selecció de cares
+STR_7044_MALE :{BLACK}Home
+STR_7045_FEMALE :{BLACK}Dona
+STR_7046_NEW_FACE :{BLACK}Nova Cara
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Cancel·la la selecció de nova cara
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Accepta la selecció de nova cara
+STR_7049_SELECT_MALE_FACES :{BLACK}Selecciona cares d'home
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Selecciona cares de dona
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Genera una nova cara aleatòria
+STR_704C_KEY :{BLACK}Llegenda
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Mostra la llegenda als gràfics
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Llegenda dels gràfics de l'empresa
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Clica aquí per activar/desactivar l'entrada als gràfics de l'empresa
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Unitats de càrrega entregada
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Ratis de rendiment de l'empresa (màxim rati=1000)
+STR_7052_COMPANY_VALUES :{WHITE}Valors de l'empresa
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Taula de la Lliga d'Empreses
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}Empresa de Transport en dificultats!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} ha de ser venuda o declarar-se en fallida a menys que el seu rendiment s'incrementi aviat!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(President)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Fusió d'Empreses de Transport!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} s'ha venut a {COMPANY} per {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Busquem empresa de transports per absorbir la nostra empresa{}{}Vols comprar a {COMPANY} per {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Fallida!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} ha estat tancada per els acreidors i tots els seus actius venuts!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}Creada nova empresa de transports!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} comença la construcció prop de {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}No pots comprar l'empresa...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Tarifes de Pagament de Càrrega
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Dies en trànsit
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Pagament per entregar 10 unitats (o 10,000 litres) de càrrega a una distància de 20 quadres
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Activa/desactiva gràfic de tipus de càrrega
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Enginyer
+STR_7067_TRAFFIC_MANAGER :Director de Trànsit
+STR_7068_TRANSPORT_COORDINATOR :Coordinador de Transport
+STR_7069_ROUTE_SUPERVISOR :Supervisor de Ruta
+STR_706A_DIRECTOR :Director
+STR_706B_CHIEF_EXECUTIVE :Cap Executiu
+STR_706C_CHAIRMAN :Conseller Delegat
+STR_706D_PRESIDENT :President
+STR_706E_TYCOON :Magnat
+STR_706F_BUILD_HQ :{BLACK}Construir Seu
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Construir seu de l'empresa / veure seu de l'empresa
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Trasllada la seu de l'empresa a un altre lloc amb el cost de l'1% del seu valor
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}No es pot construir la seu de l'empresa...
+STR_7072_VIEW_HQ :{BLACK}Veure Seu
+STR_RELOCATE_HQ :{BLACK}Trasllada la Seu
+STR_COMPANY_PASSWORD :{BLACK}Contrasenya
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Protegeix la teva Empresa amb contrasenya per tal d'evitar que la utilitzin usuaris no autoritzats.
+STR_SET_COMPANY_PASSWORD :Estableix la contrasenya de l'Empresa
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}Recessió Mundial!{}{}Economistes experts temen que l'economia es desplomi!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Recessió Acabada!{}{}La millora als negocis dóna confiança a les indústries a la vegada que l'economia s'enforteix!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Intercanvia mida gran/petita de finestra
+STR_7076_COMPANY_VALUE :{GOLD}Valor de l'Empresa: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Compra un 25% d'accions
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Vendre un 25% d'accions
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Compra el 25% d'accions d'aquesta empresa
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Ven un 25% d'accions d'aquesta empresa
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}No pots comprar el 25% de participació en aquesta empresa...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}No pots vendre el 25% de participació en aquesta empresa...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% propietat de {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% propietat de {COMPANY}{} {COMMA}% propietat de {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} ha estat absorbida per {COMPANY}!
+STR_7080_PROTECTED :{WHITE}Aquesta empresa ja no negocia participacions...
+
+STR_LIVERY_DEFAULT :Decoració estandard
+STR_LIVERY_STEAM :Motor de vapor
+STR_LIVERY_DIESEL :Motor Diesel
+STR_LIVERY_ELECTRIC :Motor Elèctric
+STR_LIVERY_MONORAIL :Motor Monorail
+STR_LIVERY_MAGLEV :Motor maglev
+STR_LIVERY_DMU :DMU
+STR_LIVERY_EMU :EMU
+STR_LIVERY_PASSENGER_WAGON_STEAM :Vagó de passatgers (Vapor)
+STR_LIVERY_PASSENGER_WAGON_DIESEL :Vagó de passatgers (Diesel)
+STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Vagó de passatgers (Elèctric)
+STR_LIVERY_FREIGHT_WAGON :Vagó de càrrega
+STR_LIVERY_BUS :Autobús
+STR_LIVERY_TRUCK :Camió
+STR_LIVERY_PASSENGER_SHIP :Vaixell de passatgers
+STR_LIVERY_FREIGHT_SHIP :Vaixell de càrrega
+STR_LIVERY_HELICOPTER :Helicòpter
+STR_LIVERY_SMALL_PLANE :Avió petit
+STR_LIVERY_LARGE_PLANE :Avió gran
+
+STR_LIVERY_GENERAL_TIP :{BLACK}Mostra esquemes de colors generals
+STR_LIVERY_TRAIN_TIP :{BLACK}Mostra els esquemes de colors dels trens
+STR_LIVERY_ROADVEH_TIP :{BLACK}Mostra els esquemes de colors dels automòbils
+STR_LIVERY_SHIP_TIP :{BLACK}Mostra els esquemes de colors dels vaixells
+STR_LIVERY_AIRCRAFT_TIP :{BLACK}Mostra esquemes de colors dels avions
+STR_LIVERY_PRIMARY_TIP :{BLACK}Escolleix el color primari per l'esquema triat
+STR_LIVERY_SECONDARY_TIP :{BLACK}Escolleix el color secundari per l'esquema triat
+STR_LIVERY_PANEL_TIP :{BLACK}Selecciona un esquema de colors per canviar-lo, o diversos esquemes amb CTRL+Clic. Clica a la casella per canviar l'esquema
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (Vapor)
+STR_8001_MJS_250_DIESEL :MJS 250 (Diesel)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut Diesel
+STR_8006_POWERNAUT_DIESEL :Powernaut Diesel
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (Vapor)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (Vapor)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (Vapor)
+STR_800A_SH_8P_STEAM :SH '8P' (Vapor)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (Diesel)
+STR_800C_DASH_DIESEL :'Dash' (Diesel)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (Diesel)
+STR_800E_UU_37_DIESEL :UU '37' (Diesel)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (Diesel)
+STR_8010_CS_4000_DIESEL :CS 4000 (Diesel)
+STR_8011_CS_2400_DIESEL :CS 2400 (Diesel)
+STR_8012_CENTENNIAL_DIESEL :Centennial (Diesel)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (Diesel)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (Diesel)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (Diesel)
+STR_8016_SH_125_DIESEL :SH '125' (Diesel)
+STR_8017_SH_30_ELECTRIC :SH '30' (Elèctric)
+STR_8018_SH_40_ELECTRIC :SH '40' (Elèctric)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (Elèctric)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (Elèctric)
+STR_801B_PASSENGER_CAR :Vagó per Passatgers
+STR_801C_MAIL_VAN :Furgó per Correu
+STR_801D_COAL_CAR :Vagó per Carbó
+STR_801E_OIL_TANKER :Tanc de Petroli
+STR_801F_LIVESTOCK_VAN :Furgó per Bestiar
+STR_8020_GOODS_VAN :Furgó de Mercaderies
+STR_8021_GRAIN_HOPPER :Furgó per Gra
+STR_8022_WOOD_TRUCK :Vagó per Fusta
+STR_8023_IRON_ORE_HOPPER :Vagó per Mineral de Ferro
+STR_8024_STEEL_TRUCK :Vagó per Acer
+STR_8025_ARMORED_VAN :Furgó Blindat
+STR_8026_FOOD_VAN :Furgó per Queviures
+STR_8027_PAPER_TRUCK :Vagó per Paper
+STR_8028_COPPER_ORE_HOPPER :Furgó per Mineral de Coure
+STR_8029_WATER_TANKER :Tanc d'Aigua
+STR_802A_FRUIT_TRUCK :Vagó per Fruita
+STR_802B_RUBBER_TRUCK :Vagó per Cautxú
+STR_802C_SUGAR_TRUCK :Vagó per Sucre
+STR_802D_COTTON_CANDY_HOPPER :Furgó per Cotó de Sucre
+STR_802E_TOFFEE_HOPPER :Furgó per Caramels
+STR_802F_BUBBLE_VAN :Furgó per Bombolles
+STR_8030_COLA_TANKER :Tanc per Refresc
+STR_8031_CANDY_VAN :Furgó per Dolços
+STR_8032_TOY_VAN :Furgó per Joguines
+STR_8033_BATTERY_TRUCK :Vagó per Piles
+STR_8034_FIZZY_DRINK_TRUCK :Vagó per Begudes Gasoses
+STR_8035_PLASTIC_TRUCK :Vagó per Plàstic
+STR_8036_X2001_ELECTRIC :'X2001' (Elèctric)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Elèctric)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :Vagó per Passatgers
+STR_803A_MAIL_VAN :Furgó per Correu
+STR_803B_COAL_CAR :Vagó per Carbó
+STR_803C_OIL_TANKER :Tanc de Petroli
+STR_803D_LIVESTOCK_VAN :Furgó per Bestiar
+STR_803E_GOODS_VAN :Furgó de Mercaderies
+STR_803F_GRAIN_HOPPER :Furgó per Gra
+STR_8040_WOOD_TRUCK :Vagó per Fusta
+STR_8041_IRON_ORE_HOPPER :Vagó per Mineral de Ferro
+STR_8042_STEEL_TRUCK :Vagó per Acer
+STR_8043_ARMORED_VAN :Furgó Blindat
+STR_8044_FOOD_VAN :Furgó per Queviures
+STR_8045_PAPER_TRUCK :Vagó per Paper
+STR_8046_COPPER_ORE_HOPPER :Furgó per Mineral de Coure
+STR_8047_WATER_TANKER :Tanc d'Aigua
+STR_8048_FRUIT_TRUCK :Vagó per Fruita
+STR_8049_RUBBER_TRUCK :Vagó per Cautxú
+STR_804A_SUGAR_TRUCK :Vagó per Sucre
+STR_804B_COTTON_CANDY_HOPPER :Furgó per Cotó de Sucre
+STR_804C_TOFFEE_HOPPER :Furgó per Caramels
+STR_804D_BUBBLE_VAN :Furgó per Bombolles
+STR_804E_COLA_TANKER :Tanc per Refresc
+STR_804F_CANDY_VAN :Furgó per Dolços
+STR_8050_TOY_VAN :Furgó per Joguines
+STR_8051_BATTERY_TRUCK :Vagó per Piles
+STR_8052_FIZZY_DRINK_TRUCK :Vagó per Begudes Gasoses
+STR_8053_PLASTIC_TRUCK :Vagó per Plàstic
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (Elèctric)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cíclope' (Elèctric)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (Elèctric)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Quimera' (Elèctric)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :Vagó per Passatgers
+STR_805A_MAIL_VAN :Furgó per Correu
+STR_805B_COAL_CAR :Vagó per Carbó
+STR_805C_OIL_TANKER :Tanc de Petroli
+STR_805D_LIVESTOCK_VAN :Furgó per Bestiar
+STR_805E_GOODS_VAN :Furgó de Mercaderies
+STR_805F_GRAIN_HOPPER :Furgó per Gra
+STR_8060_WOOD_TRUCK :Vagó per Fusta
+STR_8061_IRON_ORE_HOPPER :Vagó per Mineral de Ferro
+STR_8062_STEEL_TRUCK :Vagó per Acer
+STR_8063_ARMORED_VAN :Furgó Blindat
+STR_8064_FOOD_VAN :Furgó per Queviures
+STR_8065_PAPER_TRUCK :Vagó per Paper
+STR_8066_COPPER_ORE_HOPPER :Furgó per Mineral de Coure
+STR_8067_WATER_TANKER :Tanc d'Aigua
+STR_8068_FRUIT_TRUCK :Vagó per Fruita
+STR_8069_RUBBER_TRUCK :Vagó per Cautxú
+STR_806A_SUGAR_TRUCK :Vagó per Sucre
+STR_806B_COTTON_CANDY_HOPPER :Furgó per Cotó de Sucre
+STR_806C_TOFFEE_HOPPER :Furgó per Caramels
+STR_806D_BUBBLE_VAN :Furgó per Bombolles
+STR_806E_COLA_TANKER :Tanc per Refresc
+STR_806F_CANDY_VAN :Furgó per Dolços
+STR_8070_TOY_VAN :Furgó per Joguines
+STR_8071_BATTERY_TRUCK :Vagó per Piles
+STR_8072_FIZZY_DRINK_TRUCK :Vagó per Begudes Gasoses
+STR_8073_PLASTIC_TRUCK :Vagó per Plàstic
+STR_8074_MPS_REGAL_BUS :Autobus MPS Regal
+STR_8075_HEREFORD_LEOPARD_BUS :Autobus Hereford Leopard
+STR_8076_FOSTER_BUS :Autobus Foster
+STR_8077_FOSTER_MKII_SUPERBUS :Autobus Foster MkII
+STR_8078_PLODDYPHUT_MKI_BUS :Autobus Ploddyphut MkI
+STR_8079_PLODDYPHUT_MKII_BUS :Autobus Ploddyphut MkII
+STR_807A_PLODDYPHUT_MKIII_BUS :Autobus Ploddyphut MkIII
+STR_807B_BALOGH_COAL_TRUCK :Camió per Carbó Balogh
+STR_807C_UHL_COAL_TRUCK :Camió per Carbó Uhl
+STR_807D_DW_COAL_TRUCK :Camió per Carbó DW
+STR_807E_MPS_MAIL_TRUCK :Camió per Correu MPS
+STR_807F_REYNARD_MAIL_TRUCK :Camió per Correu Reynard
+STR_8080_PERRY_MAIL_TRUCK :Camió per Correu Perry
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :Camió per Correu MightyMover
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Camió per Correu Powernaught
+STR_8083_WIZZOWOW_MAIL_TRUCK :Camió per Correu Wizzowow
+STR_8084_WITCOMBE_OIL_TANKER :Cuba de Petroli Witcombe
+STR_8085_FOSTER_OIL_TANKER :Cuba de Petroli Foster
+STR_8086_PERRY_OIL_TANKER :Cuba de Petroli Perry
+STR_8087_TALBOTT_LIVESTOCK_VAN :Furgó de Bestiar Talbott
+STR_8088_UHL_LIVESTOCK_VAN :Furgó de Bestiar Uhl
+STR_8089_FOSTER_LIVESTOCK_VAN :Furgó de Bestiar Foster
+STR_808A_BALOGH_GOODS_TRUCK :Camió de Mercaderies
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Camió de Mercaderies
+STR_808C_GOSS_GOODS_TRUCK :Camió de Mercaderies Goss
+STR_808D_HEREFORD_GRAIN_TRUCK :Camió per Gra Hereford
+STR_808E_THOMAS_GRAIN_TRUCK :Camió per Gra Thomas
+STR_808F_GOSS_GRAIN_TRUCK :Camió per Gra Goss
+STR_8090_WITCOMBE_WOOD_TRUCK :Camió per Fusta Witcombe
+STR_8091_FOSTER_WOOD_TRUCK :Camió per Fusta Foster
+STR_8092_MORELAND_WOOD_TRUCK :Camió per Fusta Moreland
+STR_8093_MPS_IRON_ORE_TRUCK :Camió per Mineral de Ferro MPS
+STR_8094_UHL_IRON_ORE_TRUCK :Camió per Mineral de Ferro Uhl
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Camió per Mineral de Ferro Chippy
+STR_8096_BALOGH_STEEL_TRUCK :Camió per Acer Balogh
+STR_8097_UHL_STEEL_TRUCK :Camió per Acer Uhl
+STR_8098_KELLING_STEEL_TRUCK :Camió per Acer Kelling
+STR_8099_BALOGH_ARMORED_TRUCK :Furgó Blindat Balogh
+STR_809A_UHL_ARMORED_TRUCK :Furgó Blindat Uhl
+STR_809B_FOSTER_ARMORED_TRUCK :Furgó Blindat Foster
+STR_809C_FOSTER_FOOD_VAN :Camió per Queviures Foster
+STR_809D_PERRY_FOOD_VAN :Camió per Queviures Perry
+STR_809E_CHIPPY_FOOD_VAN :Camió per Queviures Chippy
+STR_809F_UHL_PAPER_TRUCK :Camió per Paper Uhl
+STR_80A0_BALOGH_PAPER_TRUCK :Camió per Paper Balogh
+STR_80A1_MPS_PAPER_TRUCK :Camió per Paper MPS
+STR_80A2_MPS_COPPER_ORE_TRUCK :Camió per Mineral de Coure MPS
+STR_80A3_UHL_COPPER_ORE_TRUCK :Camió per Mineral de Coure Uhl
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Camió per Mineral de Coure Goss
+STR_80A5_UHL_WATER_TANKER :Cuba d'Aigua Uhl
+STR_80A6_BALOGH_WATER_TANKER :Cuba d'Aigua Balogh
+STR_80A7_MPS_WATER_TANKER :Cuba d'Aigua MPS
+STR_80A8_BALOGH_FRUIT_TRUCK :Camió per Fruita Balogh
+STR_80A9_UHL_FRUIT_TRUCK :Camió per Fruita Uhl
+STR_80AA_KELLING_FRUIT_TRUCK :Camió per Fruita Kelling
+STR_80AB_BALOGH_RUBBER_TRUCK :Camió per Cautxú Balogh
+STR_80AC_UHL_RUBBER_TRUCK :Camió per Cautxú Uhl
+STR_80AD_RMT_RUBBER_TRUCK :Camió per Cautxú RMT
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :Camió per Sucre MightyMover
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Camió per Sucre Powernaught
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Camió per Sucre Wizzowow
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :Camió per Refresc MightyMover
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Camió per Refresc Powernaught
+STR_80B3_WIZZOWOW_COLA_TRUCK :Camió per Refresc Wizzowow
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :Camió per Cotó de Sucre MightyMover
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Camió per Cotó de Sucre Powernaught
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Camió per Cotó de Sucre Wizzowow
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :Camió per Caramels MightyMover
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Camió per Caramels Powernaught
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Camió per Caramels Wizzowow
+STR_80BA_MIGHTYMOVER_TOY_VAN :Camió per Joguines MightyMover
+STR_80BB_POWERNAUGHT_TOY_VAN :Camió per Joguines Powernaught
+STR_80BC_WIZZOWOW_TOY_VAN :Camió per Joguines Wizzowow
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :Camió per Dolços MightyMover
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Camió per Dolços Powernaught
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Camió per Dolços Wizzowow
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :Camió per Piles MightyMover
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Camió per Piles Powernaught
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Camió per Piles Wizzowow
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :Camió per Begudes Gasoses MightyMover
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Camió per Begudes Gasoses Powernaught
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Camió per Begudes Gasoses Wizzowow
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :Camió per Plàstic MightyMover
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Camió per Plàstic Powernaught
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Camió per Plàstic Wizzowow
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :Camió per Bombolles MightyMover
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Camió per Bombolles Powernaught
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Camió per Bombolles Wizzowow
+STR_80CC_MPS_OIL_TANKER :Petroler MPS
+STR_80CD_CS_INC_OIL_TANKER :Petroler CS-Inc.
+STR_80CE_MPS_PASSENGER_FERRY :Ferry de Passatgers MPS
+STR_80CF_FFP_PASSENGER_FERRY :Ferry de Passatgers FFP
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Hovercraft Bakewell 300
+STR_80D1_CHUGGER_CHUG_PASSENGER :Ferry de Passatgers Chugger-Chug
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Ferry de Passatgers Shivershake
+STR_80D3_YATE_CARGO_SHIP :Vaixell Mercant Yate
+STR_80D4_BAKEWELL_CARGO_SHIP :Vaixell Mercant Bakewell
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Vaixell Mercant Mightymover
+STR_80D6_POWERNAUT_CARGO_SHIP :Vaixell Mercant Powernaut
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AeroTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Helicopter Tricario
+STR_80FE_GURU_X2_HELICOPTER :Helicopter Guru X2
+STR_80FF_POWERNAUT_HELICOPTER :Helicopter Powernaut
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Missatge del fabricant de vehicles
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}Acabem de dissenyar el nou {STRING} - estàs interessat en fer ús exclusiu d'aquest vehicle durant un any, per veure com va, abans del seu llançament mundial ?
+STR_8102_RAILROAD_LOCOMOTIVE :locomotora de tren
+STR_8103_ROAD_VEHICLE :automòbil
+STR_8104_AIRCRAFT :aeronau
+STR_8105_SHIP :vaixell
+STR_8106_MONORAIL_LOCOMOTIVE :locomotora de monorail
+STR_8107_MAGLEV_LOCOMOTIVE :locomotora de maglev
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}{TOWN} Cotxeres de Tren
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Celebració popular . . .{} Arribada del 1er. tren a {STATION}!
+STR_8802_DETAILS :{WHITE}{STRING} (Detalls)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Tren en el camí
+STR_8804 :{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8806_GO_TO :Ves a {STATION}
+STR_8807_GO_TO_TRANSFER :Ves a {STATION} (Transfereix i agafa càrrega)
+STR_8808_GO_TO_UNLOAD :Ves a {STATION} (Descarrega)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Ves a {STATION} (Transfereix i deixa buit)
+STR_880A_GO_TO_LOAD :Ves a {STATION} (Carrega)
+STR_880B_GO_TO_TRANSFER_LOAD :Ves a {STATION} (Transfereix i espera càrrega completa)
+STR_880C_GO_NON_STOP_TO :Ves sense parar a {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Ves sense parar a {STATION} (Transfereix i agafa càrrega)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Ves sense parar a {STATION} (Descarrega)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Ves sense parar a {STATION} (Transfereix i deixa buit)
+STR_8810_GO_NON_STOP_TO_LOAD :Ves sense parar a {STATION} (Carrega)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Ves sense parar a {STATION} (Transfereix i espera càrrega completa)
+STR_GO_TO_TRAIN_DEPOT :Ves al Diposit {TOWN} de Tren
+STR_SERVICE_AT_TRAIN_DEPOT :Manteniment a cotxeres de {TOWN}.
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Ves sense parar a les cotxeres de {TOWN}.
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Manteniment sense parades a cotxeres de {TOWN}.
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}Cap a cotxeres de {TOWN}.
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}Cap a cotxeres de {TOWN}, a {VELOCITY}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE :{LTBLUE}Revisió a la cotxera de {TOWN}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE_VEL :{LTBLUE}Revisió a la cotxera de {TOWN}, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (Ordre incorrecte)
+
+STR_UNKNOWN_DESTINATION :destí desconegut
+STR_8812_EMPTY :{LTBLUE}Buit
+STR_8813_FROM :{LTBLUE}{CARGO} procedent{P "" s} de {STATION}
+STR_FROM_MULT :{LTBLUE}{CARGO} des de {STATION} (x{NUM})
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}Tren {COMMA} en espera en cotxeres
+STR_8815_NEW_VEHICLES :{BLACK}Nous Vehicles
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Tren massa llarg
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Els trens només es poden modificar quan estan parats dins d'una cotxera
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} Trens
+
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Nous Vehicles
+STR_NEW_ELRAIL_VEHICLES :{WHITE}Nous vehicles de Via Electrificada
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Nous Trens Monorail
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Nous Trens Maglev
+STR_ALL_AVAIL_RAIL_VEHICLES :{WHITE}Vehicles amb Vies
+
+STR_881F_BUILD_VEHICLE :{BLACK}Construeix Vehicle
+STR_CLONE_ROAD_VEHICLE :{BLACK}Clona Vehicle
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}Fa una còpia del vehicle. Control-Clic compartirà les ordres
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Fa una còpia del vehicle. Prem aquest botó i després en un vehicle dins o fora cotxeres. Control-Clic compartirà les ordres
+STR_CLONE_TRAIN :{BLACK}Clona Tren
+STR_CLONE_TRAIN_INFO :{BLACK}Fa una còpia del tren inclosos tots els vagons. Control-Clic compartirà les ordres
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}Fa una còpia del tren inclosos tots els vagons. Prem aquest botó i després en un tren dins o fora cotxeres. Control-Clic compartirà les ordres
+STR_8820_RENAME :{BLACK}Reanomena
+STR_8823_SKIP :{BLACK}Salta
+STR_8824_DELETE :{BLACK}Esborra
+STR_8825_NON_STOP :{BLACK}Sense Parar
+STR_8826_GO_TO :{BLACK}Ves a
+STR_8827_FULL_LOAD :{BLACK}Carrega
+STR_8828_UNLOAD :{BLACK}Descarrega
+STR_REFIT :{BLACK}Remodela
+STR_REFIT_TIP :{BLACK}Selecciona quin tipus de càrrega vols remodelar en aquesta ordre. Control + Clic per eliminar l'ordre de remodelar
+STR_REFIT_ORDER :(Remodela a {STRING})
+STR_8829_ORDERS :{WHITE}{VEHICLE} (Ordres)
+STR_882A_END_OF_ORDERS :{SETX 10}- - Fí d'Ordres - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}Servei
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}No es pot construir el vehicle...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Construit: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Valor: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}Carregant / Descarregant
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}El tren s'ha de parar dins de la cotxera
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}No pots enviar el tren a cotxeres...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}No hi ha més espai per ordres
+STR_8832_TOO_MANY_ORDERS :{WHITE}Massa ordres
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}No es pot afegir una nova ordre...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}No es pot esborrar aquesta ordre...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}No es pot modificar aquesta ordre...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}No es pot moure el vehicle...
+STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}La màquina posterior sempre ha de seguir la seva parella davantera
+STR_8838_N_A :N/A{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}No es pot vendre el vehicle...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Incapaç de trobar el camí a la cotxera local
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}No es pot parar/arrencar el tren...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Interval de manteniment: {LTBLUE}{COMMA}dies{BLACK} Darrer manteniment: {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Interval de manteniment: {LTBLUE}{COMMA}%{BLACK} Darrer manteniment: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Trens - clica al tren per informació
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Construeix nous trens (es necessita cotxera)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Trens - clica al tren per info., arrossega el vehicle per afegir/treure del tren
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Construeix un nou element de tren
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Arrossega l'element de tren fins aquí per vendre'l
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centra la vista de la pantalla principal en la situació de la cotxera
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Llista de selecció d'elements de tren - clica a l'element per informació
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Construeix l'element de tren seleccionat
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Reanomena el tipus d'element del tren
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Acció sobre el tren actual - clica aquí per parar/arrencar el tren
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Mostra les ordres del tren
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centra la vista de la pantalla principal a la situació del tren
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Envia el tren a cotxera
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Obliga al tren a actuar sense esperar a tenir la senyal lliure
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Inverteix la direcció del tren
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Mostra els detalls del tren
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Augmenta l'interval de manteniment
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Disminueix l'interval de manteniment
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Mostra els detalls de càrrega transportada
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Mostra els detalls d'elements del tren
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Mostra les capacitats de cada element
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Mostra la capacitat total del tren, separat per tipus de càrrega
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Llista d'ordres - clica en una per seleccionar-la
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}Salta l'ordre actual i comença la següent
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Esborra l'ordre seleccionada
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Fer sense parades l'ordre seleccionada
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Afegeix una nova ordre abans de la seleccionada, o afegeix-la al final de la llista
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Fer que en l'ordre seleccionada s'esperi a que l'element tingui càrrega total
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Obliga en l'ordre seleccionada a descarregar l'element
+STR_SERVICE_HINT :{BLACK}Saltar l'ordre a menys que es necessiti manteniment
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}Nova {STRING} disponible!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Cost: {CURRENCY} Pes: {WEIGHT_S}{}Velocitat: {VELOCITY} Potència: {POWER}{}Cost de circulació: {CURRENCY}/any{}Capacitat: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}Avariat
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}Edat: {LTBLUE}{STRING}{BLACK} Cost de Circulació: {LTBLUE}{CURRENCY}/any
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Pes: {LTBLUE}{WEIGHT_S} {BLACK}Potència: {LTBLUE}{POWER}{BLACK} Vel. Max.: {LTBLUE}{VELOCITY}
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Pes: {LTBLUE}{WEIGHT_S} {BLACK}Potència: {LTBLUE}{POWER}{BLACK} Velocitat Max.: {LTBLUE}{VELOCITY} {BLACK}Max. T.E.: {LTBLUE}{FORCE}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Benefici enguany: {LTBLUE}{CURRENCY} (darrer any: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}Rendibilitat: {LTBLUE}{COMMA}% {BLACK}Avaries des de l'últim manteniment: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Parat
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}No pots fer que un tren passi d'una senyal amb perill...
+STR_8863_CRASHED :{RED}Accident!
+
+STR_8865_NAME_TRAIN :{WHITE}Anomena tren
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}No es pot anomenar el tren...
+STR_8867_NAME_TRAIN :{BLACK}Anomena tren
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Tren accidentat!{}{COMMA} moren en una bola de foc després de la colisió
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}No es pot invertir la direcció del tren...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Reanomena el tipus d'element del tren
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}No es pot reanomenar el tipus d'element del tren...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Fer que l'ordre marcada forci al vehicle a volcar la càrrega
+STR_886F_TRANSFER :{BLACK}Transfereix
+
+STR_TRAIN_STOPPING :{RED}Parant
+STR_TRAIN_STOPPING_VEL :{RED}Parant, a {VELOCITY}
+STR_INCOMPATIBLE_RAIL_TYPES :Tipus de rail incompatible
+STR_TRAIN_NO_POWER :{RED}Sense energia
+STR_TRAIN_START_NO_CATENARY :Aquesta via no té catenària, el tren no pot arrencar
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Automòbil en camí
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} Vehicles Rodats
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}{TOWN} Cotxera de Vehicles Rodats
+STR_9004_NEW_VEHICLES :{BLACK}Nous Vehicles
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}Nous Vehicles Rodats
+STR_9007_BUILD_VEHICLE :{BLACK}Construeix Vehicle
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}No es pot construir l'automòbil...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (Detalls)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}Edat: {LTBLUE}{STRING}{BLACK} Cost de circulació: {LTBLUE}{CURRENCY}/any
+STR_900E_MAX_SPEED :{BLACK}Vel. Max.: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Benefici enguany: {LTBLUE}{CURRENCY} (darrer any: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}Rendibilitat: {LTBLUE}{COMMA}% {BLACK}Avaries des del darrer manteniment: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Construit: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Capacitat: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}...s'ha de parar dins d'una cotxera
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}No pots vendre l'automòbil...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}No es pot parar/arrencar l'automòbil...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}Vehicle Rodat {COMMA} esperant en cotxera
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}Cap a la cotxera de {TOWN}.
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}Cap a la cotxera de {TOWN}, a {VELOCITY}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE :{LTBLUE}Revisió a la cotxera de {TOWN}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE_VEL :{LTBLUE}Revisió a la cotxera de {TOWN}, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}No es pot enviar el vehicle a cotxera...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Impossible trobar la cotxera local
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Automòbils - clica en un vehicle per informació
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Construeix nous automòbils (necessita una cotxera)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Acció sobre el vehicle actual - clica aquí per parar/arrencar el vehicle
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Mostra les ordres dels vehicles
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Centra la pantalla principal a la situació del vehicle
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Envia el vehicle a cotxera
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Obliga al vehicle a tornar
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Mostra els detalls del vehicle
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Vehicles - clica en un vehicle per informació
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Construeix un nou automòbil
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Arrossega el vehicle fins aquí per vendre'l
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Centra la pantalla principal en la situació de la cotxera
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Llista de selecció de Vehicles Rodats - clica en un vehicle per informació
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Construeix l'automòbil seleccionat
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}Nou automòbil disponible!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Cost: {CURRENCY}{}Velocitat: {VELOCITY}{}Cost de circulació: {CURRENCY}/any{}Capacitat: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Anomena automòbil
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}No es pot anomenar l'automòbil...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Anomena automòbil
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Celebració popular . . .{}Primer autobús arriba a {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Celebració popular . . .{}Primer camió arriba a {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}Accident de Vehicle Rodat!{}El conductor mor en una bola de foc després de la colisió amb un tren
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}Accident de Vehicle Rodat!{}{COMMA} moren en una bola de foc després d'una colisió amb un tren
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}No es pot fer que el vehicle torni...
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}No es poden girar vehicles que estan formats per múltiples unitats
+STR_9034_RENAME :{BLACK}Reanomena
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Reanomena tipus d'automòbil
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Reanomena tipus d'automòbil
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}No es pot reanomenar tipus d'automòbil
+STR_9038_GO_TO_ROADVEH_DEPOT :Ves a la cotxera de {TOWN}.
+STR_SERVICE_AT_ROADVEH_DEPOT :Manteniment a la cotxera de {TOWN}.
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Remodela vehicle de carretera per dur un tipus diferent de càrrega
+STR_REFIT_ROAD_VEHICLE :{BLACK}Remodela vehicle de carretera
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Remodela vehicle de carretera per a dur el tipus de carrega senyalat
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}No es pot remodelar el vehicle de carretera...
+STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Selecciona el tipus de càrrega a transportar pel vehicle
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Construcció de Port
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Construcció de Port
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Aquí no es pot construir un port...
+STR_9803_SHIP_DEPOT :{WHITE}{TOWN} Drassana
+STR_9804_NEW_SHIPS :{BLACK}Nous Vaixells
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} Vaixells
+STR_9808_NEW_SHIPS :{WHITE}Nous Vaixells
+STR_9809_BUILD_SHIP :{BLACK}Construeix un Vaixell
+STR_CLONE_SHIP :{BLACK}Clona Vaixell
+STR_CLONE_SHIP_INFO :{BLACK}Fa una còpia del vaixell. Control-Clic compartirà les ordres
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}Fa una còpia del vaixell. Prem aquest botó i després en un vaixell dins o fora les drassanes. Control-Clic compartirà les ordres
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}El vaixell s'ha de parar a la drassana
+STR_980C_CAN_T_SELL_SHIP :{WHITE}No es pot vendre el vaixell...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}No es pot construir el vaixell...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Vaixell en el camí
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Detalls)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}Edat: {LTBLUE}{STRING}{BLACK} Cost de Circulació: {LTBLUE}{CURRENCY}/any
+STR_9813_MAX_SPEED :{BLACK}Max. velocitat: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Benefici enguany: {LTBLUE}{CURRENCY} (darrer any: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}Rendibilitat: {LTBLUE}{COMMA}% {BLACK}Avaries des de l'últim manteniment: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Construit: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}Capacitat: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}No es pot parar/arrencar el vaixell...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}No es pot enviar vaixell a la drassana...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Incapaç de trobar drassana local
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}Cap a la drassana de {TOWN}.
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}Cap a la drassana de{TOWN}, a {VELOCITY}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE :{LTBLUE}Revisió a la drassana de {TOWN}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE_VEL :{LTBLUE}Revisió a la drassana de {TOWN}, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}Vaixell {COMMA} esperant en drassana
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Construeix un port
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Construeix una drassana (per construir i revisar vaixells)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Vaixells - clica en un vaixell per informació
+STR_9820_BUILD_NEW_SHIP :{BLACK}Construeix un nou vaixell
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Arrossega el vaixell fins aquí per vendre'l
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centra la pantalla principal en la situació de la drassana
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Vaixells - clica en un vaixell per informació
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Construeix nous vaixells (necessites una drassana)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}LLista de selecció de Vaixells - clica en un vaixell per informació
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Construeix el vaixell seleccionat
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Accions sobre el vaixell actual - clica aquí per parar/arrencar el vaixell
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Mostra les ordres del vaixell
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centra la pantalla principal en la situació del vaixell
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Envia el vaixell a la drassana. CTRL+Clic per només revisió
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Mostra els detalls del vaixell
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}Nou vaixell disponible!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Cost: {CURRENCY} Max. Velocitat: {VELOCITY}{}Capacitat: {CARGO}{}Cost de Circulació: {CURRENCY}/any
+STR_982F_NAME_SHIP :{BLACK}Anomena vaixell
+
+STR_9831_NAME_SHIP :{WHITE}Anomena vaixell
+STR_9832_CAN_T_NAME_SHIP :{WHITE}No es pot anomenar el vaixell...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Celebració popular . . .{}El 1er. vaixell arriba a {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Situa boia, que pot ser útil per marques de ruta addicionals
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Aquí no es pot situar una boia...
+STR_9836_RENAME :{BLACK}Reanomena
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Reanomena tipus de vaixell
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Reanomena tipus de vaixell
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}No es pot reanomenar el tipus de vaixell...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Remodela vaixell mercant per portar un tipus diferent de càrrega
+STR_983B_REFIT :{WHITE}{VEHICLE} (Remodela)
+STR_983C_REFIT_SHIP :{BLACK}Remodela vaixell
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Selecciona el tipus de càrrega a transportar
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Remodela vaixell per portar el tipus de càrrega seleccionat
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Selecciona el tipus de càrrega a transportar:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nova capacitat: {GOLD}{CARGO}{}{BLACK}Cost de la remodelació: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}No es pot remodelar el vaixell...
+STR_9842_REFITTABLE :(remodelable)
+STR_GO_TO_SHIP_DEPOT :Ves a la drassana de {TOWN}.
+SERVICE_AT_SHIP_DEPOT :Manteniment a drassana de {TOWN}.
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Aeroports
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Aquí no es pot construir un aeroport...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} Hangar d'Aeronaus
+STR_A003_NEW_AIRCRAFT :{BLACK}Nova Aeronau
+STR_CLONE_AIRCRAFT :{BLACK}Clona Aeronau
+STR_CLONE_AIRCRAFT_INFO :{BLACK}Fa una còpia de l'aeronau. Control-Clic compartirà les ordres
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Fa una còpia de l'aeronau. Prem aquest botó i després en una aeronau dins o fora l'hangar. Control-Clic compartirà les ordres
+STR_A005_NEW_AIRCRAFT :{WHITE}Nova Aeronau
+STR_A006_BUILD_AIRCRAFT :{BLACK}Construeix una Aeronau
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}No es pot construir l'aeronau...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} Aeronaus
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (Ordres)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (Detalls)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Edat: {LTBLUE}{STRING}{BLACK} Cost de Circulació: {LTBLUE}{CURRENCY}/any
+STR_A00E_MAX_SPEED :{BLACK}Max. velocitat: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Benefici enguany: {LTBLUE}{CURRENCY} (darrer any: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}Rendibilitat: {LTBLUE}{COMMA}% {BLACK}Avaries des de l'últim manteniment: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Construït: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}No es pot enviar l'aeronau a l'hangar...
+STR_HEADING_FOR_HANGAR :{ORANGE}Cap a l'hangar de {STATION}.
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}Cap a l'hangar de {STATION}, a {VELOCITY}
+STR_HEADING_FOR_HANGAR_SERVICE :{LTBLUE}Revisió a l'hangar de {STATION}
+STR_HEADING_FOR_HANGAR_SERVICE_VEL :{LTBLUE}Revisió a l'hangar de {STATION}, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}L' aeronau {COMMA} esperant a l'hangar
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Aeronau en el camí
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}No es pot parar/arrencar l'aeronau...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Aeronau en vol
+STR_A019_CAPACITY :{BLACK}Capacitat: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Capacitat: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}L' aeronau s'ha de parar a l'hangar
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}No es pot vendre l' aeronau...
+STR_A01D_AIRPORT_CONSTRUCTION :Construcció d'Aeroport
+STR_A01E_BUILD_AIRPORT :{BLACK}Construeix un aeroport
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Aeronau - clica en l'aeronau per informació
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Construeix noves aeronaus (necessites un aeroport amb hangar)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Aeronau - clica en l' aeronau per informació
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Construeix noves aeronaus
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}Arrossega l'aeronau fins aquí per vendre-la
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Centra la pantalla principal en la situació de l'hangar
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Llista de selecció d'Aeronaus - clica en una aeronau per informació
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Construeix l'aeronau seleccionada
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Accions sobre l'aeronau actual - clica aquí per parar/arrencar l'aeronau
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Mostra les ordres de l'aeronau
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Centra la pantalla principal a la situació de l'aeronau
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Envia aeronau a l'hangar
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Mostra els detalls de l'aeronau
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}Nova aeronau disponible!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Cost: {CURRENCY} Max. Velocitat: {VELOCITY}{}Capacitat: {COMMA} passatgers, {COMMA} sacs de correu{}Cost de Circulació: {CURRENCY}/any
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Anomena aeronau
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}No es pot anomenar aeronaus...
+STR_A032_NAME_AIRCRAFT :{BLACK}Anomena aeronau
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Celebració popular . . .{}La primera aeronau arriba a {STATION}!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Accident d'avió!{}{COMMA} moren en una bola de foc a {STATION}
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Accident d'aviació!{}Aeronau sense combustible, {COMMA} morts en una bola de foc!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Reanomena
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Reanomena tipus d'aeronau
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Reanomena tipus d'aeronau
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}No es pot reanomenar tipus d'aeronau...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Remodela aeronaus per transportar diferent tipus de càrrega
+STR_A03C_REFIT :{WHITE}{VEHICLE} (Remodela)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Remodela aeronau
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Selecciona tipus de càrrega a transportar
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Remodela aeronau per transportar el tipus de càrrega seleccionat
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Selecciona el tipus de càrrega a transportar:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nova capacitat: {GOLD}{STRING}{}{BLACK}Cost de la remodelació: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}No es pot remodelar l'aeronau...
+STR_GO_TO_AIRPORT_HANGAR :Ves a l'hangar de {STATION}.
+SERVICE_AT_AIRPORT_HANGAR :Manteniment en l'hangar de {STATION}.
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}Desastre de Zeppelin a {STATION}!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Automòbil destruit en colisionar amb un 'OVNI'!
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}Explosió de refineria de petroli prop de {TOWN}!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}Fàbrica destruida en extranyes circunstàncies prop de {TOWN}!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}'OVNI' aterra prop de {TOWN}!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}L'enfonsament d'una mina de carbó deixa un rastre de destrucció prop de {TOWN}!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Inundacions!{}Al menys {COMMA} presuntament desapareguts o morts després de mortals inundacions!
+
+STR_BRIBE_FAILED :{WHITE}El teu intent de suborn ha estat
+STR_BRIBE_FAILED_2 :{WHITE}descobert per un investigador regional
+STR_BUILD_DATE :{BLACK}Construit: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Detall de ratis de rendiment
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}Detall
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Vehicles:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Estacions:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Min. benefici:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Min. ingrès:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Max. ingrès:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Entregat:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Càrrega:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Diner:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Prèstec:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Total:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Quantitat de vehicles. Inclou els automòbils, trens, vaixells i aeronaus.
+STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}Quantitat de parts d'estacions. Cada part d'una estació es compta (ex. estació de tren, parada d'autobus, aeroport), encara que estigui connectada a una altra estació.
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}El benefici del vehicle amb els menors ingressos (de tots els vehicles més antics de 2 anys)
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Quantitat de diners fets durant el mes amb el mínim benefici dels darrers 12 trimestres
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Quantitat de diners fets durant el mes amb el màxim benefici dels darrers 12 trimestres
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}Unitats de càrrega entregada en els darrers quatre trimestres.
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}Tipus de càrrega entregada durant el darrer trimestre.
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Quantitats de diners en efectiu
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}Tens un prèstec elevat?
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Total de punts sobre els punts possibles
+
+STR_NEWGRF_SETTINGS_BUTTON :{BLACK}Paràmetres NewGRF
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}Configuracions de Newgrf
+STR_NEWGRF_APPLY_CHANGES :{BLACK}Aplica els canvis
+STR_NEWGRF_SET_PARAMETERS :{BLACK}Estableix els paràmetres
+STR_NEWGRF_TIP :{BLACK}Llista de totes les opcions de Newgrf que has instal·lat. Prem en un grup d'opcions per canviar els seus atributs.
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}Ara no hi ha arxius de Newgrf instal·lats! Consulta el manual per a les instruccions d'instal·lació de nous gràfics.
+STR_NEWGRF_FILENAME :{BLACK}Nom d'arxiu: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}Id de GRF: {SILVER}{STRING}
+STR_NEWGRF_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING}
+STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}Estàs a punt de fer canvis en un joc actiu; això pot fer que OpenTTD es pengi.{}Estàs completament segur que vols fer-los?
+
+STR_NEWGRF_ADD :{BLACK}Afegeix
+STR_NEWGRF_ADD_TIP :{BLACK}Afegeix un arxiu NewGRF a la llista
+STR_NEWGRF_REMOVE :{BLACK}Treu
+STR_NEWGRF_REMOVE_TIP :{BLACK}Treu l'arxiu NewGRF seleccionat de la llista
+STR_NEWGRF_MOVEUP :{BLACK}Mou Amunt
+STR_NEWGRF_MOVEUP_TIP :{BLACK}Mou amunt l'arxiu NewGRF seleccionat de la llista
+STR_NEWGRF_MOVEDOWN :{BLACK}Mou Avall
+STR_NEWGRF_MOVEDOWN_TIP :{BLACK}Mou avall l'arxiu NewGRF seleccionat de la llista
+STR_NEWGRF_FILE_TIP :{BLACK}Una llista d'arxius NewGRF que ha estat instal·lada. Clica un arxiu per canviar els seus paràmetres
+STR_NEWGRF_PARAMETER :{BLACK}Paràmetres: {SILVER}{STRING}
+STR_NEWGRF_PARAMETER_QUERY :{BLACK}Introdueix els paràmetres NewGRF
+STR_NEWGRF_NO_INFO :{BLACK}No hi ha informació disponible
+
+STR_NEWGRF_ADD_CAPTION :{WHITE}Arxius NewGRF disponibles
+STR_NEWGRF_ADD_FILE :{BLACK}Afegeix a la selecció
+STR_NEWGRF_ADD_FILE_TIP :{BLACK}Afegeix l'arxiu NewGRF seleccionat a la teva configuració
+STR_NEWGRF_RESCAN_FILES :{BLACK}Reescaneja arxius
+STR_NEWGRF_RESCAN_FILES_TIP :{BLACK}Actualitza la llista d'arxius NewGRF disponibles
+STR_NEWGRF_DUPLICATE_GRFID :{WHITE}No es pot afegir l'arxiu: ID GRF duplicada
+
+STR_NEWGRF_NOT_FOUND :{RED}No s'ha trobat cap arxiu coincident
+STR_NEWGRF_DISABLED :{RED}Desactivat
+
+STR_CURRENCY_WINDOW :{WHITE}Moneda personalitzada
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Canvi de moneda: {ORANGE}{CURRENCY} = £ {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Separador:
+STR_CURRENCY_PREFIX :{LTBLUE}Prefix:
+STR_CURRENCY_SUFFIX :{LTBLUE}Sufix:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Canvi a Euro: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Canvi a Euro: {ORANGE}mai
+STR_CURRENCY_PREVIEW :{LTBLUE}Vista prèvia: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Canvia el paràmetre de la moneda personalitzada
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} Trens
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} Vehicles
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} Aeronaus
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} Vaixells
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Mostra tots els trens que tinguin aquesta estació al seu itinerari
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Mostra tots els vehicles que tinguin aquesta estació al seu itinerari
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Mostra totes les aeronaus que tinguin aquest aeroport al seu itinerari
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Mostra tots els vaixells que tinguin aquest port al seu itinerari
+
+STR_VEH_WITH_SHARED_ORDERS_LIST :{WHITE}Ordres compartides de {COMMA} Vehicle{P "" s}
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}Mostra tots els vehicles que tenen les mateixes ordres
+
+### depot strings
+STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Estàs a punt de vendre tots els vehicles de la cotxera. N'estàs segur?
+
+STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP :{BLACK}Vendre tots els trens de la cotxera
+STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP :{BLACK}Vendre tots els vehicles de la cotxera
+STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP :{BLACK}Vendre tots els vaixells de la drassana
+STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP :{BLACK}Vendre tots els avions de l'hangar
+
+STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP :{BLACK}Treure una llista de tots els trens amb aquesta cotxera en les seves ordres
+STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP :{BLACK}Treure una llista de tots els vehicles amb aquesta cotxera en les seves ordres
+STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP :{BLACK}Treure una llista de tots els vaixells amb aquesta drassana en les seves ordres
+STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP :{BLACK}Treu una llista de tots els avions amb algun hangar en aquest aeroport en les seves ordres
+
+STR_DEPOT_AUTOREPLACE_TRAIN_TIP :{BLACK}Autosubstitueix tots els trens de la cotxera
+STR_DEPOT_AUTOREPLACE_ROADVEH_TIP :{BLACK}Autosubstitueix tots els vehicles de la cotxera
+STR_DEPOT_AUTOREPLACE_SHIP_TIP :{BLACK}Autosubstitueix tots els vaixells de la drassana
+STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP :{BLACK}Autosubstitueix tots els avions de l'hangar
+
+STR_VEHICLE_LIST_TRAIN_DEPOT :{BLACK}{STRING} - {COMMA} Tren{P "" s}
+STR_VEHICLE_LIST_ROADVEH_DEPOT :{BLACK}{STRING} - {COMMA} Vehicle{P "" s}
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} Vaixell{P "" s}
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} Avió
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}Substitueix {STRING}
+STR_REPLACE_VEHICLES_START :{BLACK}Comença a substituir
+STR_REPLACE_VEHICLES_STOP :{BLACK}Para de substituir
+STR_NOT_REPLACING :{BLACK}No substituint
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Cap vehicle seleccionat
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Selecciona el tipus de motor a substituir
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Selecciona el nou tipus de motor que vols fer servir en lloc del seleccionat
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Prem per aturar el reemplaçament del tipus de motor seleccionat a l'esquerra
+STR_REPLACE_HELP_START_BUTTON :{BLACK}Prem per iniciar el reemplaçament del tipus de motor seleccionat a l'esquerra pel seleccionat a la dreta
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Tria el tipus de via pel que vols substituir motors
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Mosyta quin motor dels seleccionats a l'esquerra es reemplaça, si hi ha
+STR_REPLACE_HELP :{BLACK}Et permet substituir un tipus de motor per un altre, quan els trens del tipus original entrin a cotxeres
+STR_REPLACE_REMOVE_WAGON :{BLACK}Treure vagons: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Fer que la sustitució automàtica mantingui la llargària del tren eliminant vagons (començant pel front), si substituint la màquina el tren es fa més llarg
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}Sustituint: {ORANGE}{SKIP}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} CARACTERÃSTICA EXPERIMENTAL {}Alterna entre finestres de sustitució de vagons i de motors{}La sustitució del vagó només tindrà lloc si el nou vagó pot ser remodelat per admetre el mateix tipus de càrrega que el vell. Això es comprova per a cada vagó quan el reemplaçament es produeix.
+STR_ENGINE_NOT_BUILDABLE :{WHITE}El motor no es pot construir
+
+STR_ENGINES :Motors
+STR_WAGONS :Vagons
+
+STR_MASS_STOP_DEPOT_TRAIN_TIP :{BLACK}Clica per parar tots els trens de dins de la cotxera
+STR_MASS_STOP_DEPOT_ROADVEH_TIP :{BLACK}Clica per parar tots els vehicles de dins de la cotxera
+STR_MASS_STOP_DEPOT_SHIP_TIP :{BLACK}Clica per parar tots els vaixells de dins de la drassana
+STR_MASS_STOP_HANGAR_TIP :{BLACK}Clica per parar tots els avions de dins de l'hangar
+
+STR_MASS_START_DEPOT_TRAIN_TIP :{BLACK}Clica per arrencar tots els trens de dins de la cotxera
+STR_MASS_START_DEPOT_ROADVEH_TIP :{BLACK}Clica per arrencar tots els vehicles de dins de la cotxera
+STR_MASS_START_DEPOT_SHIP_TIP :{BLACK}Clica per arrencar tots els vaixells de dins de la drassana
+STR_MASS_START_HANGAR_TIP :{BLACK}Clica per arrencar tots els avions de dins de l'hangar
+
+STR_MASS_STOP_LIST_TIP :{BLACK}Clica per parar tots els vehicles de la llista
+STR_MASS_START_LIST_TIP :{BLACK}Clica per arrencar tots els vehicles de la llista
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}Llista de senyals - {COMMA} Senyals
+
+STR_ORDER_REFIT_FAILED :{WHITE}Ordre de remodelar fallida ha parat {STRING} {COMMA}
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :Trens de Vapor i Diesel
+STR_ELRAIL_VEHICLES :Trens Elèctrics
+STR_MONORAIL_VEHICLES :Trens Monorail
+STR_MAGLEV_VEHICLES :Trens Maglev
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Cost: {GOLD}{CURRENCY}{BLACK} Pes: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Velocitat: {GOLD}{VELOCITY}{BLACK} Potència: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}Velocitat: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Cost d'utilització: {GOLD}{CURRENCY}/any
+STR_PURCHASE_INFO_CAPACITY :{BLACK}Capacitat: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Dissenyat: {GOLD}{NUM}{BLACK} Vida: {GOLD}{COMMA} anys
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}Max. Rendiment: {GOLD}{COMMA}%
+STR_PURCHASE_INFO_COST :{BLACK}Cost: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Pes: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Cost: {GOLD}{CURRENCY}{BLACK} Velocitat: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Capacitat: {GOLD}{COMMA} passatgers, {COMMA} sacs de correu
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Vagons Automotrius: {GOLD}+{POWER}{BLACK} Pes: {GOLD}+{WEIGHT_S}
+STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Remodelable a: {GOLD}
+STR_PURCHASE_INFO_ALL_TYPES :Totes les càrregues
+STR_PURCHASE_INFO_ALL_BUT :Tots menys {GOLD}
+STR_PURCHASE_INFO_MAX_TE :{BLACK}Max. Esforç de Tracció: {GOLD}{FORCE}
+
+########### String for New Landscape Generator
+
+STR_GENERATE :{WHITE}Genera
+STR_RANDOM :{BLACK}Randomise
+STR_RANDOM_HELP :{BLACK}Canvia el nombre aleatori utilitzat pel Generador de Terrenys
+STR_WORLD_GENERATION_CAPTION :{WHITE}Generació del món
+STR_RANDOM_SEED :{BLACK}Nombre aleatori:
+STR_RANDOM_SEED_HELP :{BLACK}Click per introduïr un nombre aleatori
+STR_LAND_GENERATOR :{BLACK}Gen. de terrenys:
+STR_TREE_PLACER :{BLACK}Algoritme d'arbres:
+STR_HEIGHTMAP_ROTATION :{BLACK}Rotació del mapa d'alçades:
+STR_TERRAIN_TYPE :{BLACK}Tipus de terreny:
+STR_QUANTITY_OF_SEA_LAKES :{BLACK}Nivell del mar:
+STR_SMOOTHNESS :{BLACK}Planitut:
+STR_SNOW_LINE_HEIGHT :{BLACK}Alçada de la neu:
+STR_DATE :{BLACK}Data:
+STR_NUMBER_OF_TOWNS :{BLACK}No. de pobles:
+STR_NUMBER_OF_INDUSTRIES :{BLACK}No. d'indústries:
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_SNOW_LINE_UP :{BLACK}Moure la linia de neu un pas amunt
+STR_SNOW_LINE_DOWN :{BLACK}Moure la linia de neu un pas avall
+STR_SNOW_LINE_QUERY_CAPT :{WHITE}Canviar alçada de la linia de neu
+STR_START_DATE_QUERY_CAPT :{WHITE}Canviar l'any inicial
+STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Alerta d'escala
+STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}No es recomana redimensionar massa el mapa d'origen. Vols continuar amb la generació?
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_HEIGHTMAP_NAME :{BLACK}Nom del mapa d'alçades:
+STR_HEIGHTMAP_SIZE :{BLACK}Mida: {ORANGE}{NUM} x {NUM}
+STR_GENERATION_WORLD :{WHITE}Generant món...
+STR_GENERATION_ABORT :{BLACK}Aborta
+STR_GENERATION_ABORT_CAPTION :{WHITE}Aborta la Generació del Món
+STR_GENERATION_ABORT_MESSAGE :{YELLOW}Realment vols abortar la generació?
+STR_PROGRESS :{WHITE}{NUM}% complet
+STR_GENERATION_PROGRESS :{BLACK}{NUM} / {NUM}
+STR_WORLD_GENERATION :{BLACK}Generació del món
+STR_TREE_GENERATION :{BLACK}Generació d'arbres
+STR_UNMOVABLE_GENERATION :{BLACK}Generació innamovible
+STR_CLEARING_TILES :{BLACK}Generació d'una àrea escarpada i rocosa
+STR_SETTINGUP_GAME :{BLACK}Configurant el joc
+STR_PREPARING_TILELOOP :{BLACK}Passant el bucle de cel·les
+STR_PREPARING_GAME :{BLACK}Preparant el joc
+STR_DIFFICULTY_TO_CUSTOM :{WHITE}Aquesta acció canviarà el nivell de dificultat a personalitzat
+STR_SE_FLAT_WORLD :{WHITE}Terreny pla
+STR_SE_FLAT_WORLD_TIP :{BLACK}Generar un terreny pla
+STR_SE_RANDOM_LAND :{WHITE}Terreny aleatori
+STR_SE_NEW_WORLD :{BLACK}Crear nou escenari
+STR_SE_CAPTION :{WHITE}Tipus d'escenari
+STR_FLAT_WORLD_HEIGHT_DOWN :{BLACK}Moure l'alçada del terreny pla un pas avall
+STR_FLAT_WORLD_HEIGHT_UP :{BLACK}Moure l'alçada del terreny pla un pas amunt
+STR_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Canvia alçada del terreny pla
+STR_FLAT_WORLD_HEIGHT :{BLACK}Alçada del terreny pla:
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+STR_SMALLMAP_CENTER :{BLACK}Centrar el mapa petit a la posició actual
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}Petit
+STR_CITY_AIRPORT :{BLACK}Ciutadà
+STR_METRO_AIRPORT :{BLACK}Metropolità
+STR_INTERNATIONAL_AIRPORT :{BLACK}Internacional
+STR_COMMUTER_AIRPORT :{BLACK}Viatjer
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Intercontinental
+STR_HELIPORT :{BLACK}Heliport
+STR_HELIDEPOT :{BLACK}Helihangar
+STR_HELISTATION :{BLACK}Helistació
+
+STR_SMALL_AIRPORTS :{BLACK}Aeroports petits
+STR_LARGE_AIRPORTS :{BLACK}Aeroports grans
+STR_HUB_AIRPORTS :{BLACK}Aeroports d'enllaç
+STR_HELIPORTS :{BLACK}Aeroports d'helicòpters
+
+############ Tooltip measurment
+
+STR_MEASURE_LENGTH :{BLACK}Llargada: {NUM}
+STR_MEASURE_AREA :{BLACK}Àrea: {NUM} x {NUM}
+STR_MEASURE_LENGTH_HEIGHTDIFF :{BLACK}Llargada: {NUM}{}Diferència d'alçada: {NUM} m
+STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}Àrea: {NUM} x {NUM}{}Diferència d'alçada: {NUM} m
+
+########
diff --git a/src/lang/czech.txt b/src/lang/czech.txt
new file mode 100644
index 000000000..844470393
--- /dev/null
+++ b/src/lang/czech.txt
@@ -0,0 +1,3174 @@
+##name Czech
+##ownname ÄŒesky
+##isocode cs_CS.UTF-8
+##plural 6
+##case nom gen acc dat voc loc ins big
+##gender m m_a m_i f n
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Mimo okraj mapy
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Moc blízko k okraji mapy
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Nedostatek peněz - je potřeba {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Je potřeba plochá země
+STR_0008_WAITING :{BLACK}Čeká tu: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (na cestÄ› z
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Přijímá: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Přijímá: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :cestující
+STR_000F_PASSENGERS.gen :cestujících
+STR_000F_PASSENGERS.big :Cestující
+STR_0010_COAL :uhlí
+STR_0010_COAL.big :Uhlí
+STR_0011_MAIL :pošta
+STR_0011_MAIL.gen :pošty
+STR_0011_MAIL.big :Pošta
+STR_0012_OIL :ropa
+STR_0012_OIL.gen :ropy
+STR_0012_OIL.big :Ropa
+STR_0013_LIVESTOCK :dobytek
+STR_0013_LIVESTOCK.gen :dobytka
+STR_0013_LIVESTOCK.big :Dobytek
+STR_0014_GOODS :zboží
+STR_0014_GOODS.big :Zboží
+STR_0015_GRAIN :zrní
+STR_0015_GRAIN.big :Zrní
+STR_0016_WOOD :dřevo
+STR_0016_WOOD.gen :dřeva
+STR_0016_WOOD.big :Dřevo
+STR_0017_IRON_ORE :železná ruda
+STR_0017_IRON_ORE.gen :železné rudy
+STR_0017_IRON_ORE.big :Železná ruda
+STR_0018_STEEL :ocel
+STR_0018_STEEL.gen :oceli
+STR_0018_STEEL.big :Ocel
+STR_0019_VALUABLES :ceniny
+STR_0019_VALUABLES.gen :cenin
+STR_0019_VALUABLES.big :Ceniny
+STR_001A_COPPER_ORE :měděná ruda
+STR_001A_COPPER_ORE.gen :měděné rudy
+STR_001A_COPPER_ORE.big :Měděná ruda
+STR_001B_MAIZE :kukuřice
+STR_001B_MAIZE.big :Kukuřice
+STR_001C_FRUIT :ovoce
+STR_001C_FRUIT.big :Ovoce
+STR_001D_DIAMONDS :diamanty
+STR_001D_DIAMONDS.gen :diamantů
+STR_001D_DIAMONDS.big :Diamanty
+STR_001E_FOOD :jídlo
+STR_001E_FOOD.gen :jídlo
+STR_001E_FOOD.big :Jídlo
+STR_001F_PAPER :papír
+STR_001F_PAPER.gen :papíru
+STR_001F_PAPER.big :Papír
+STR_0020_GOLD :zlato
+STR_0020_GOLD.gen :zlata
+STR_0020_GOLD.big :Zlato
+STR_0021_WATER :voda
+STR_0021_WATER.gen :vody
+STR_0021_WATER.big :Voda
+STR_0022_WHEAT :pšenice
+STR_0022_WHEAT.big :PÅ¡enice
+STR_0023_RUBBER :kauÄuk
+STR_0023_RUBBER.gen :kauÄuku
+STR_0023_RUBBER.big :KauÄuk
+STR_0024_SUGAR :cukr
+STR_0024_SUGAR.gen :cukru
+STR_0024_SUGAR.big :Cukr
+STR_0025_TOYS :hraÄky
+STR_0025_TOYS.gen :hraÄek
+STR_0025_TOYS.big :HraÄky
+STR_0026_CANDY :bonbony
+STR_0026_CANDY.gen :bonbonů
+STR_0026_CANDY.big :Bonbony
+STR_0027_COLA :kola
+STR_0027_COLA.gen :koly
+STR_0027_COLA.big :Kola
+STR_0028_COTTON_CANDY :cukrová vata
+STR_0028_COTTON_CANDY.gen :cukrové vaty
+STR_0028_COTTON_CANDY.big :Cukrová vata
+STR_0029_BUBBLES :bubliny
+STR_0029_BUBBLES.gen :bublin
+STR_0029_BUBBLES.big :Bubliny
+STR_002A_TOFFEE :karamel
+STR_002A_TOFFEE.gen :karamelu
+STR_002A_TOFFEE.big :Karamel
+STR_002B_BATTERIES :baterie
+STR_002B_BATTERIES.gen :baterií
+STR_002B_BATTERIES.big :Baterie
+STR_002C_PLASTIC :plast
+STR_002C_PLASTIC.gen :plastu
+STR_002C_PLASTIC.big :Plast
+STR_002D_FIZZY_DRINKS :limonáda
+STR_002D_FIZZY_DRINKS.gen :limonád
+STR_002D_FIZZY_DRINKS.big :Limonáda
+STR_002E :
+STR_002F_PASSENGER :cestujících
+STR_0030_COAL :uhlí
+STR_0031_MAIL :pošty
+STR_0032_OIL :ropy
+STR_0033_LIVESTOCK :dobytka
+STR_0034_GOODS :zboží
+STR_0035_GRAIN :zrní
+STR_0036_WOOD :dřeva
+STR_0037_IRON_ORE :železné rudy
+STR_0038_STEEL :oceli
+STR_0039_VALUABLES :cenin
+STR_003A_COPPER_ORE :měděné rudy
+STR_003B_MAIZE :kukuřice
+STR_003C_FRUIT :ovoce
+STR_003D_DIAMOND :diamantů
+STR_003E_FOOD :jídla
+STR_003F_PAPER :papíru
+STR_0040_GOLD :zlata
+STR_0041_WATER :vody
+STR_0042_WHEAT :pšenice
+STR_0043_RUBBER :kauÄuku
+STR_0044_SUGAR :cukru
+STR_0045_TOY :hraÄek
+STR_0046_CANDY :bonbonů
+STR_0047_COLA :koly
+STR_0048_COTTON_CANDY :cukrové vaty
+STR_0049_BUBBLE :bublin
+STR_004A_TOFFEE :karamelu
+STR_004B_BATTERY :baterií
+STR_004C_PLASTIC :plastu
+STR_004D_FIZZY_DRINK :limonád
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} cestující{P "" "" ch}
+STR_QUANTITY_COAL :{WEIGHT} uhlí
+STR_QUANTITY_MAIL :{COMMA} balík{P "" y ů} pošty
+STR_QUANTITY_OIL :{VOLUME} ropy
+STR_QUANTITY_LIVESTOCK :{COMMA} kus{P "" y ů} dobytka
+STR_QUANTITY_GOODS :{COMMA} krabic{P e e ""} zboží
+STR_QUANTITY_GRAIN :{WEIGHT} zrní
+STR_QUANTITY_WOOD :{WEIGHT} dřeva
+STR_QUANTITY_IRON_ORE :{WEIGHT} železné rudy
+STR_QUANTITY_STEEL :{WEIGHT} oceli
+STR_QUANTITY_VALUABLES :{COMMA} balík{P "" y ů} cenin
+STR_QUANTITY_COPPER_ORE :{WEIGHT} měděné rudy
+STR_QUANTITY_MAIZE :{WEIGHT} kukuřice
+STR_QUANTITY_FRUIT :{WEIGHT} ovoce
+STR_QUANTITY_DIAMONDS :{COMMA} pyt{P el le lů} diamantů
+STR_QUANTITY_FOOD :{WEIGHT} jídla
+STR_QUANTITY_PAPER :{WEIGHT} papíru
+STR_QUANTITY_GOLD :{COMMA} balík{P "" y ů}
+STR_QUANTITY_WATER :{VOLUME} vody
+STR_QUANTITY_WHEAT :{WEIGHT} pšenice
+STR_QUANTITY_RUBBER :{VOLUME} kauÄuku
+STR_QUANTITY_SUGAR :{WEIGHT} cukru
+STR_QUANTITY_TOYS :{COMMA} hraÄ{P ka ky ek}
+STR_QUANTITY_SWEETS :{COMMA} pyt{P el le lů} bonbonů
+STR_QUANTITY_COLA :{VOLUME} koly
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} cukrové vaty
+STR_QUANTITY_BUBBLES :{COMMA} bublin{P a y ""}
+STR_QUANTITY_TOFFEE :{WEIGHT} karamelu
+STR_QUANTITY_BATTERIES :{COMMA} bateri{P e e í}
+STR_QUANTITY_PLASTIC :{VOLUME} plastu
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} limonád{P a y ""}
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}CS
+STR_ABBREV_COAL :{TINYFONT}UH
+STR_ABBREV_MAIL :{TINYFONT}PT
+STR_ABBREV_OIL :{TINYFONT}RP
+STR_ABBREV_LIVESTOCK :{TINYFONT}DB
+STR_ABBREV_GOODS :{TINYFONT}ZB
+STR_ABBREV_GRAIN :{TINYFONT}ZR
+STR_ABBREV_WOOD :{TINYFONT}DŘ
+STR_ABBREV_IRON_ORE :{TINYFONT}ŽR
+STR_ABBREV_STEEL :{TINYFONT}OC
+STR_ABBREV_VALUABLES :{TINYFONT}CN
+STR_ABBREV_COPPER_ORE :{TINYFONT}MD
+STR_ABBREV_MAIZE :{TINYFONT}KU
+STR_ABBREV_FRUIT :{TINYFONT}OV
+STR_ABBREV_DIAMONDS :{TINYFONT}DM
+STR_ABBREV_FOOD :{TINYFONT}JD
+STR_ABBREV_PAPER :{TINYFONT}PR
+STR_ABBREV_GOLD :{TINYFONT}ZL
+STR_ABBREV_WATER :{TINYFONT}VD
+STR_ABBREV_WHEAT :{TINYFONT}PÅ 
+STR_ABBREV_RUBBER :{TINYFONT}KA
+STR_ABBREV_SUGAR :{TINYFONT}CU
+STR_ABBREV_TOYS :{TINYFONT}HR
+STR_ABBREV_SWEETS :{TINYFONT}BO
+STR_ABBREV_COLA :{TINYFONT}KL
+STR_ABBREV_CANDYFLOSS :{TINYFONT}CV
+STR_ABBREV_BUBBLES :{TINYFONT}BU
+STR_ABBREV_TOFFEE :{TINYFONT}KR
+STR_ABBREV_BATTERIES :{TINYFONT}BA
+STR_ABBREV_PLASTIC :{TINYFONT}PL
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}LI
+STR_ABBREV_NONE :{TINYFONT}NIC
+STR_ABBREV_ALL :{TINYFONT}VÅ E
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Mapa - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Možnosti hry
+STR_00B2_MESSAGE :{YELLOW}Zpráva
+STR_00B3_MESSAGE_FROM :{YELLOW}Zpráva od {STRING}
+STR_POPUP_CAUTION_CAPTION :{WHITE}Varování!
+STR_00B4_CAN_T_DO_THIS :{WHITE}Tohle neumůžeš udělat...
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}NemůžeÅ¡ vyÄistit tuto oblast...
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Původní copyright: {COPYRIGHT} 1995 Chris Sawyer, všechna práva vyhrazena
+STR_00B7_VERSION :{BLACK}OpenTTD verze {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 Tým OpenTTD
+STR_TRANSLATED_BY :{BLACK} Překladatel(é) - Hadez, iSteve
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Konec
+STR_00C8_YES :{BLACK}Ano
+STR_00C9_NO :{BLACK}Ne
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Opravdu chceš opustit tuto hru a odejít do {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Nic
+STR_00D1_DARK_BLUE :Tmavomodrá
+STR_00D2_PALE_GREEN :Světlezelená
+STR_00D3_PINK :Růžová
+STR_00D4_YELLOW :Žlutá
+STR_00D5_RED :Červená
+STR_00D6_LIGHT_BLUE :Bleděmodrá
+STR_00D7_GREEN :Zelená
+STR_00D8_DARK_GREEN :Tmavozelená
+STR_00D9_BLUE :Modrá
+STR_00DA_CREAM :Krémová
+STR_00DB_MAUVE :Lila
+STR_00DC_PURPLE :Purpurová
+STR_00DD_ORANGE :Oranžová
+STR_00DE_BROWN :Hnědá
+STR_00DF_GREY :Šedá
+STR_00E0_WHITE :Bílá
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Příliš mnoho vozidel ve hře
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Umístění
+STR_00E5_CONTOURS :Profil
+STR_00E6_VEHICLES :Dopravní prostředky
+STR_00E7_INDUSTRIES :Průmysl
+STR_00E8_ROUTES :TratÄ›
+STR_00E9_VEGETATION :Vegetace
+STR_00EA_OWNERS :Vlastníci
+STR_00EB_ROADS :{BLACK}{TINYFONT}Silnice
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Železnice
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Stanice/Letiště/Přístavy
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Budovy/Průmysl
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Vozidla
+STR_00F0_100M :{BLACK}{TINYFONT}100 m
+STR_00F1_200M :{BLACK}{TINYFONT}200 m
+STR_00F2_300M :{BLACK}{TINYFONT}300 m
+STR_00F3_400M :{BLACK}{TINYFONT}400 m
+STR_00F4_500M :{BLACK}{TINYFONT}500 m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Vlaky
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}SilniÄní vozidla
+STR_00F7_SHIPS :{BLACK}{TINYFONT}LodÄ›
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Letadla
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Dopravní cesty
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Uhelný důl
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Elektrárna
+STR_00FC_FOREST :{BLACK}{TINYFONT}Les
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}Pila
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Ropná rafinerie
+STR_00FF_FARM :{BLACK}{TINYFONT}Farma
+STR_0100_FACTORY :{BLACK}{TINYFONT}Továrna
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Tiskárna
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Ropný vrt
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Důl na železnou rudu
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Ocelárna
+STR_0105_BANK :{BLACK}{TINYFONT}Banka
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Papírna
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Důl na zlato
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Továrna na zpracování potravin
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Diamantový důl
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Důl na měděnou rudu
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Ovocná plantáž
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}KauÄuková plantáž
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Zdroj vody
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Vodojem
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}Pila
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Les cukrové vaty
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Továrna na sladkosti
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Farma na baterie
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Kolové studny
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}HraÄkářství
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Továrna na hraÄky
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Plastové fontány
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}StáÄírna limonád
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Generátor bublin
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Karamelolom
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Cukerný důl
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Nádraží
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Nakládací rampa
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Autobusová zastávka
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Letiště/Heliport
+STR_011F_DOCK :{BLACK}{TINYFONT}Přístavy
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Hrbolatá zem
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Travnatá zem
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Holá zem
+STR_0123_FIELDS :{BLACK}{TINYFONT}Pole
+STR_0124_TREES :{BLACK}{TINYFONT}Stromy
+STR_0125_ROCKS :{BLACK}{TINYFONT}Kameny
+STR_0126_WATER :{BLACK}{TINYFONT}Voda
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Žádný vlastník
+STR_0128_TOWNS :{BLACK}{TINYFONT}Města
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Továrny
+STR_012A_DESERT :{BLACK}{TINYFONT}Poušť
+STR_012B_SNOW :{BLACK}{TINYFONT}Sníh
+STR_012C_MESSAGE :{WHITE}Zpráva
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Zrušit
+STR_012F_OK :{BLACK}OK
+STR_0130_RENAME :{BLACK}Přejmenovat
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Definováno příliš mnoho jmen
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Zvolené jméno se už používá
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unixu
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}... vlastněno {STRING}
+STR_013C_CARGO :{BLACK}Náklad
+STR_013D_INFORMATION :{BLACK}Informace
+STR_013E_CAPACITIES :{BLACK}Kapacity
+STR_013E_TOTAL_CARGO :{BLACK}Celkový náklad
+STR_013F_CAPACITY :{BLACK}Kapacita: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}Kapacita: {LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Celková kapacita tohoto vlaku:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}Nová hra
+STR_0141_LOAD_GAME :{BLACK}Nahrát hru
+STR_SINGLE_PLAYER :{BLACK}1 hráÄ
+STR_MULTIPLAYER :{BLACK}Více hráÄů
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Velikost mapy:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Možnosti hry
+
+STR_0150_SOMEONE :někdo{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Mapa světa
+STR_0152_TOWN_DIRECTORY :Seznam měst
+STR_0153_SUBSIDIES :Dotace
+
+STR_UNITS_IMPERIAL :Imperiální (míle)
+STR_UNITS_METRIC :Metrické (kilometry)
+STR_UNITS_SI :SI (metry)
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} mil/h
+STR_UNITS_VELOCITY_METRIC :{COMMA} km/h
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA} hp
+STR_UNITS_POWER_METRIC :{COMMA} hp
+STR_UNITS_POWER_SI :{COMMA} kW
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA} t
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA} t
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA} kg
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} tun{P a y ""}
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} tun{P a y ""}
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} kg
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA} gal
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA} l
+STR_UNITS_VOLUME_SHORT_SI :{COMMA} m³
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} galon{P "" y ů}
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} litr{P "" y ů}
+STR_UNITS_VOLUME_LONG_SI :{COMMA} m³
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10³ lbf
+STR_UNITS_FORCE_METRIC :{COMMA} megapond{P "" y ů}
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Graf provozního zisku
+STR_0155_INCOME_GRAPH :Graf příjmů
+STR_0156_DELIVERED_CARGO_GRAPH :Graf doruÄeného zboží
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Graf historie výkonu
+STR_0158_COMPANY_VALUE_GRAPH :Graf hodnoty spoleÄnosti
+STR_0159_CARGO_PAYMENT_RATES :Graf ceny plateb
+STR_015A_COMPANY_LEAGUE_TABLE :Tabulka spoleÄností
+STR_PERFORMANCE_DETAIL_MENU :Podrobné hodnocení výkonu
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}O OpenTTD
+STR_015C_SAVE_GAME :Uložit hru
+STR_015D_LOAD_GAME :NaÄíst hru
+STR_015E_QUIT_GAME :UkonÄit hru
+STR_015F_QUIT :UkonÄit program
+STR_ABANDON_GAME_QUERY :{YELLOW}Opravdu chceÅ¡ ukonÄit tuto hru?
+STR_0161_QUIT_GAME :{WHITE}Konec hry
+STR_SORT_ORDER_TIP :{BLACK}Vyber způsob řazeni (sestupně/vzestupně)
+STR_SORT_CRITERIA_TIP :{BLACK}Vyber, podle Äeho se má třídit
+STR_SORT_BY :{BLACK}Řadit podle
+
+STR_SORT_BY_POPULATION :{BLACK}Populace
+STR_SORT_BY_PRODUCTION :{BLACK}Prudukce
+STR_SORT_BY_TYPE :{BLACK}Typu
+STR_SORT_BY_TRANSPORTED :{BLACK}Přepraveno
+STR_SORT_BY_NAME :{BLACK}Podle jména
+STR_SORT_BY_DROPDOWN_NAME :jména
+STR_SORT_BY_DATE :{BLACK}Podle data
+STR_SORT_BY_NUMBER :Äísla
+STR_SORT_BY_PROFIT_LAST_YEAR :hrubého zisku vloni
+STR_SORT_BY_PROFIT_THIS_YEAR :hrubého zisku letos
+STR_SORT_BY_AGE :stáří
+STR_SORT_BY_RELIABILITY :spolehlivosti
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :celkové kapacity podle druhu nákladu
+STR_SORT_BY_MAX_SPEED :max. rychlosti
+STR_SORT_BY_MODEL :modelu
+STR_SORT_BY_VALUE :hodnoty
+STR_SORT_BY_FACILITY :druhu stanice
+STR_SORT_BY_WAITING :množství Äekajícího nákladu
+STR_SORT_BY_RATING_MAX :hodnocení přepravy
+STR_ENGINE_SORT_ENGINE_ID :ID lokomotivy (klasické pořadí)
+STR_ENGINE_SORT_COST :Cena
+STR_ENGINE_SORT_POWER :Výkon
+STR_ENGINE_SORT_INTRO_DATE :Datum uvedení na trh
+STR_ENGINE_SORT_RUNNING_COST :Provozní náklady
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Výkon/Provozní náklady
+STR_ENGINE_SORT_CARGO_CAPACITY :Přepravní kapacita
+STR_NO_WAITING_CARGO :{BLACK}NeÄeká žádná komodita jakéhokoli druhu
+STR_SELECT_ALL_FACILITIES :{BLACK}OznaÄit vÅ¡echny druhy stanic
+STR_SELECT_ALL_TYPES :{BLACK}OznaÄit vÅ¡echny druhy komodit (vÄetne žádného Äekajícího nákladu)
+STR_AVAILABLE_ENGINES_TIP :{BLACK}Ukázat seznam dostupných variant pro tento typ vozidla.
+STR_MANAGE_LIST :{BLACK}Upravit seznam
+STR_MANAGE_LIST_TIP :{BLACK}Poslat příkazy všem vozidlům v tomto seznamu
+STR_REPLACE_VEHICLES :Vyměňování vozidel
+STR_SEND_TRAIN_TO_DEPOT :Poslat do depa
+STR_SEND_ROAD_VEHICLE_TO_DEPOT :Poslat do depa
+STR_SEND_SHIP_TO_DEPOT :Poslat do depa
+STR_SEND_AIRCRAFT_TO_HANGAR :Poslat do hangáru
+STR_SEND_FOR_SERVICING :Provést údržbu
+
+############ range for months starts
+STR_0162_JAN :led
+STR_0163_FEB :úno
+STR_0164_MAR :bře
+STR_0165_APR :dub
+STR_0166_MAY :kvÄ›
+STR_0167_JUN :Äer
+STR_0168_JUL :Änc
+STR_0169_AUG :srp
+STR_016A_SEP :zář
+STR_016B_OCT :říj
+STR_016C_NOV :lis
+STR_016D_DEC :pro
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Pauza
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Uložit hru, opustit hru, ukonÄit
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Zobrazit seznam stanic spoleÄnosti
+STR_0174_DISPLAY_MAP :{BLACK}Zobrazit mapu
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Zobrazit mapu a seznam měst
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Zobrazit seznam měst
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Zobrazit finanÄní informace o spoleÄnosti
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Zobrazit obecné informace o spoleÄnosti
+STR_0179_DISPLAY_GRAPHS :{BLACK}Zobrazit grafy
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Zobrazit tabulku spoleÄností
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Zobrazit seznam vlaků spoleÄnosti
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Zobrazit seznam silniÄních vozidel spoleÄnosti
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Zobrazit seznam lodí spolecnosti
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Zobrazit seznam letadel spolecnosti
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Přiblížit pohled
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Oddálit pohled
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Stavět koleje
+STR_0182_BUILD_ROADS :{BLACK}Stavět silnice
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Stavět doky
+STR_0184_BUILD_AIRPORTS :{BLACK}Stavět letiště
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Zasadit stromy, umístit cedule, atd..
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Informace o zemi
+STR_0187_OPTIONS :{BLACK}Možnosti
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Nelze změnit interval oprav...
+STR_018B_CLOSE_WINDOW :{BLACK}Zavřít okno
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Titulek okna - tahej pro posun okna
+STR_STICKY_BUTTON :{BLACK}OznaÄit toto okno, aby se nedalo zavřít klávesou pro zavÅ™ení vÅ¡ech oken
+STR_RESIZE_BUTTON :{BLACK}Velikost okna změníš uchopením a táhnutím zde
+STR_SAVELOAD_HOME_BUTTON :{BLACK}Kliknutím sem se pÅ™esuneÅ¡ do souÄasného výchozího ukládacího adresáře
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Demolice budov, atd.
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Snížit roh země
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Zvýšit roh země
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Posuvník - posouvá výpisem nahoru nebo dolů
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Posuvník - posouvá výpisem doleva nebo doprava
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Zobrazit na mapě reliéf krajiny
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Zobrazit na mapě dopravní prostředky
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Zobrazit na mapě průmysl
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Zobrazit na mapě dopravní cesty
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Zobrazit na mapÄ› vegetaci
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Zobrazit na mapě vlastníky půdy
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Zobrazovat na mapě jména měst
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Zisk tento rok: {CURRENCY} (minulý rok: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} {P rok roky let} ({COMMA})
+STR_AGE_RED :{RED}{COMMA} {P rok roky let} ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :SilniÄní vozidlo
+STR_019D_AIRCRAFT :Letadlo
+STR_019E_SHIP :LoÄ
+STR_019F_TRAIN :Vlak
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} je staré
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} je velmi staré
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} je velmi staré a potřebuje nahradit
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Informace o uzemí
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Cena za vyÄiÅ¡tÄ›ní: {LTBLUE}N/A
+STR_01A5_COST_TO_CLEAR :{BLACK}Cena za vyÄiÅ¡tÄ›ní: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :N/A
+STR_01A7_OWNER :{BLACK}Vlastník: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Místní správa: {LTBLUE}{STRING}
+STR_01A9_NONE :Nic
+STR_01AA_NAME :{BLACK}Jméno
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1.
+STR_01AD_2ND :2.
+STR_01AE_3RD :3.
+STR_01AF_4TH :4.
+STR_01B0_5TH :5.
+STR_01B1_6TH :6.
+STR_01B2_7TH :7.
+STR_01B3_8TH :8.
+STR_01B4_9TH :9.
+STR_01B5_10TH :10.
+STR_01B6_11TH :11.
+STR_01B7_12TH :12.
+STR_01B8_13TH :13.
+STR_01B9_14TH :14.
+STR_01BA_15TH :15.
+STR_01BB_16TH :16.
+STR_01BC_17TH :17.
+STR_01BD_18TH :18.
+STR_01BE_19TH :19.
+STR_01BF_20TH :20.
+STR_01C0_21ST :21.
+STR_01C1_22ND :22.
+STR_01C2_23RD :23.
+STR_01C3_24TH :24.
+STR_01C4_25TH :25.
+STR_01C5_26TH :26.
+STR_01C6_27TH :27.
+STR_01C7_28TH :28.
+STR_01C8_29TH :29.
+STR_01C9_30TH :30.
+STR_01CA_31ST :31.
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Přijímané zboží: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Jukebox
+STR_01D3_SOUND_MUSIC :Zvuk/Hudba
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Ukázat zvukové/hudební okno
+STR_01D5_ALL :{TINYFONT}VÅ¡e
+STR_01D6_OLD_STYLE :{TINYFONT}Staré
+STR_01D7_NEW_STYLE :{TINYFONT}Nové
+STR_01D8_EZY_STREET :{TINYFONT}Ezy Street
+STR_01D9_CUSTOM_1 :{TINYFONT}Volba 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Volba 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Hlasitost hudby
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Hlasitost efektů
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MIN ' ' ' ' ' ' MAX
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}SkoÄit na pÅ™edchozí skladbu ve výbÄ›ru
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}SkoÄit na další skladbu ve výbÄ›ru
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Zastavit přehrávání hudby
+STR_01E1_START_PLAYING_MUSIC :{BLACK}ZaÄit pÅ™ehrávat hudbu
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Tahej posouvátka pro nastavení hlasitosti hudby a zvukových efektů
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Skladba{SETX 88}Název
+STR_01E9_SHUFFLE :{TINYFONT}Náhodně
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Program
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Volba programu hudby
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Index skladeb
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Program - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}Vymazat
+STR_01F1_SAVE :{TINYFONT}{BLACK}Uložit
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Momentální program skladeb
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Zvolit program 'všechny skladby'
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Zvolit program 'staré skladby'
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Zvolit program 'nové skladby'
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Zvolit program 'Volba 1' (uživatelsky nastavený)
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Zvolit program 'Volba 2' (uživatelsky nastavený)
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Vymaž aktuální program (jen u Volby 1 a 2)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Uložit nastavení hudby
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Skladba se přidá do zvoleného programu (Volba 1 nebo 2) klepnutím na její název
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Hudební stopu odstraníš ze souÄasného programu (pouze u vlastního) kliknutím na ni
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Zapnout/vypnout náhodné opakování skladeb
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Ukaž skladbu ve výběrovém okně
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Klepni na dotaci pro zobrazení města/průmyslu
+STR_01FE_DIFFICULTY :{BLACK}Obtížnost ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Poslední zpráva / Älánek
+STR_0201_MESSAGE_SETTINGS :Nastavení zpráv
+STR_MESSAGE_HISTORY_MENU :Historie zpráv
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Ukázat poslední zprávu / Älánek, možnosti zpráv
+STR_0204_MESSAGE_OPTIONS :{WHITE}Možnosti zpráv
+STR_0205_MESSAGE_TYPES :{BLACK}Typy zpráv:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Příjezd prvního vozidla do hráÄovy stanice
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Příjezd prvního vozidla do konkurenÄní stanice
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Nehody / katastrofy
+STR_0209_COMPANY_INFORMATION :{YELLOW}Informace o spoleÄnosti
+STR_020A_ECONOMY_CHANGES :{YELLOW}Změny v ekonomice
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Rady / informace o hráÄových vozidlech
+STR_020C_NEW_VEHICLES :{YELLOW}Nový dopravní prostředek
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Změny příjmu zboží
+STR_020E_SUBSIDIES :{YELLOW}Dotace
+STR_020F_GENERAL_INFORMATION :{YELLOW}Obecné informace
+STR_MESSAGES_ALL :{YELLOW}Nastavení vÅ¡ech zpráv (zapnuty/vypnuty/struÄnÄ›)
+STR_MESSAGE_SOUND :{YELLOW}PÅ™ehrát zvuk pro struÄné novinové zprávy
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}... příliš daleko od předcházejícího cíle
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Nejlepší spoleÄnosti, které dosáhly {NUM}{}({STRING} úroveň)
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Tabulka spoleÄností v roce {NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Obchodník
+STR_0214_ENTREPRENEUR :Manažer
+STR_0215_INDUSTRIALIST :Továrník
+STR_0216_CAPITALIST :Kapitalista
+STR_0217_MAGNATE :Magnát
+STR_0218_MOGUL :Velemagnát
+STR_0219_TYCOON_OF_THE_CENTURY :Magnát století
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} získal titul '{STRING}'!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} z {COMPANY} získal titul '{STRING}'!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Vytvořit mapu
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Editor mapy
+STR_0223_LAND_GENERATION :{WHITE}Generovat zemi
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Náhodná země
+STR_0227_RESET_LAND :{BLACK}Vymaž zemi
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Zvětšit oblast země pro snížení/zvýšení
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Zmenšit oblast země pro snížení/zvýšení
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Generovat náhodnou zemi
+STR_022B_RESET_LANDSCAPE :{BLACK}Smazat krajinu
+STR_022C_RESET_LANDSCAPE :{WHITE}Smazat krajinu
+STR_LOAD_GAME_HEIGHTMAP :{WHITE}Použít výškovou mapu
+STR_LOAD_SCEN_HEIGHTMAP :{BLACK}Použít výškovou mapu
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Urcite chceš smazat krajinu?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Generování krajiny
+STR_022F_TOWN_GENERATION :{BLACK}Generování měst
+STR_0230_INDUSTRY_GENERATION :{BLACK}Generování průmyslu
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Výstavba silnic
+STR_0233_TOWN_GENERATION :{WHITE}Generování měst
+STR_0234_NEW_TOWN :{BLACK}Nové město
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Vytvoř nové město
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Tady nemohu postavit město...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}... moc blízko k okraji mapy
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... moc blízko k jinému městu
+STR_0239_SITE_UNSUITABLE :{WHITE}... nepoužitelné místo
+STR_023A_TOO_MANY_TOWNS :{WHITE}... příliš mnoho měst
+STR_CANNOT_GENERATE_TOWN :{WHITE}Nelze vybudovat více měst
+STR_NO_SPACE_FOR_TOWN :{WHITE}... na mapě už není místo.
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Zvetšit velikost města
+STR_023C_EXPAND :{BLACK}Rozšířit
+STR_023D_RANDOM_TOWN :{BLACK}Náhodné město
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Vybuduj město na nahodné pozici
+STR_023F_INDUSTRY_GENERATION :{WHITE}Generování průmyslu
+STR_0240_COAL_MINE :{BLACK}Uhelný důl
+STR_0241_POWER_STATION :{BLACK}Elektrárna
+STR_0242_SAWMILL :{BLACK}Pila
+STR_0243_FOREST :{BLACK}Les
+STR_0244_OIL_REFINERY :{BLACK}Ropná rafinerie
+STR_0245_OIL_RIG :{BLACK}Ropná plošina
+STR_0246_FACTORY :{BLACK}Továrna
+STR_0247_STEEL_MILL :{BLACK}Ocelárna
+STR_0248_FARM :{BLACK}Farma
+STR_0249_IRON_ORE_MINE :{BLACK}Důl na železnou rudu
+STR_024A_OIL_WELLS :{BLACK}Ropný vrt
+STR_024B_BANK :{BLACK}Banka
+STR_024C_PAPER_MILL :{BLACK}Papírna
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Továrna na zpracování potravin
+STR_024E_PRINTING_WORKS :{BLACK}Tiskárna
+STR_024F_GOLD_MINE :{BLACK}Důl na zlato
+STR_0250_LUMBER_MILL :{BLACK}Pila
+STR_0251_FRUIT_PLANTATION :{BLACK}Ovocná plantáž
+STR_0252_RUBBER_PLANTATION :{BLACK}KauÄuková plantáž
+STR_0253_WATER_SUPPLY :{BLACK}Zdroj vody
+STR_0254_WATER_TOWER :{BLACK}Vodojem
+STR_0255_DIAMOND_MINE :{BLACK}Diamantový důl
+STR_0256_COPPER_ORE_MINE :{BLACK}Důl na měděnou rudu
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Les cukrové vaty
+STR_0258_CANDY_FACTORY :{BLACK}Továrna na sladkosti
+STR_0259_BATTERY_FARM :{BLACK}Farma na baterie
+STR_025A_COLA_WELLS :{BLACK}Kolové studny
+STR_025B_TOY_SHOP :{BLACK}HraÄkářství
+STR_025C_TOY_FACTORY :{BLACK}Továrna na hraÄky
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Plastové fontány
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}StáÄírna limonád
+STR_025F_BUBBLE_GENERATOR :{BLACK}Generátor bublin
+STR_0260_TOFFEE_QUARRY :{BLACK}Karamelolom
+STR_0261_SUGAR_MINE :{BLACK}Cukerný důl
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Postavit uhelný důl
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Postavit elektrárnu
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Postavit pilu
+STR_0265_PLANT_FOREST :{BLACK}Vysadit les
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Postavit rafinerii
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Postavit ropnou plošinu (lze vybudovat jen u okrajů mapy)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Postavit továrnu
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Postavit ocelárnu
+STR_026A_CONSTRUCT_FARM :{BLACK}Založit farmu
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Postavit důl na železnou rudu
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Postavit ropné vrty
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Postavit banku (lze vybudovat jen ve městech s populací vetší než 1200)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Postavit papírnu
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Postavit továrnu na zpracování potravin
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Postavit tiskárnu
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Postavit zlatý důl
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Postavit banku (lze vybudovat pouze ve městech)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Postavit pilu (mýtí stromy v pralese a produkuje dřevo)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Vysadit ovocnou plantáž
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Vysadit kauÄukovou plantáž
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Navrtat studnu
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Postavit vodojem (lze budovat pouze ve městech)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Postavit diamantový důl
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Postavit důl na měděnou rudu
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Vysadit les cukrové vaty
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Postavit továrnu na sladkosti
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Postavit farmu na baterie
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Vyvrtat kolové studny
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Postavit hraÄkářství
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Postavit továrnu na hraÄky
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Postavit plastové fontány
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Postavit stáÄírnu limonád
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Postavit generátor bublin
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Postavit karamelolom
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Postavit cukerný důl
+STR_0285_CAN_T_BUILD_HERE :{WHITE}Nemůžeš zde stavět {STRING} ...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}... musíš nejprve vystavět město
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... je povolena jen jedna na město
+STR_0288_PLANT_TREES :{BLACK}Vysadit stromy
+STR_0289_PLACE_SIGN :{BLACK}Umístit popisek
+STR_028A_RANDOM_TREES :{BLACK}Náhodné stromy
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Umístit stromy náhodně po krajině
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Umístit kamenitá území po mapě
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Umístit maják
+STR_028E_PLACE_TRANSMITTER :{BLACK}Umístit vysílaÄ
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Vytvořit pouštní oblast{}Stiskem CTRL ji odstraníš
+STR_CREATE_LAKE :{BLACK}Vytvořit vodní plochu.{}Sousední dílky se zaplaví také, pokud jsou na úrovni moře
+STR_0290_DELETE :{BLACK}Smaž
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Smazat celé toto město
+STR_0292_SAVE_SCENARIO :Uložit mapu
+STR_0293_LOAD_SCENARIO :Otevřit mapu
+STR_0294_QUIT_EDITOR :UkonÄit editor
+STR_0295 :
+STR_0296_QUIT :UkonÄit
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Uložit mapu, otevřít mapu, opustit editor map, ukonÄit...
+STR_0298_LOAD_SCENARIO :{WHITE}Otevřít mapu
+STR_0299_SAVE_SCENARIO :{WHITE}Uložit mapu
+STR_029A_PLAY_SCENARIO :{BLACK}Hrát mapu
+STR_PLAY_HEIGHTMAP :{BLACK}Hrát z výškové mapy
+STR_PLAY_HEIGHTMAP_HINT :{BLACK}ZaÄne novou hru s použitím výškové mapy k vytvoÅ™ení krajiny
+STR_QUIT_SCENARIO_QUERY :{YELLOW}UrÄite chceÅ¡ opustit toto mapu?
+STR_029C_QUIT_EDITOR :{WHITE}UkonÄit editor
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}... může být budováno jen ve městech s populací 1200 lidí a více
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Posunout startovní rok o rok zpět
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Posunout startovní rok o rok vpřed
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... oba konce mostu musí být na zemi
+STR_02A1_SMALL :{BLACK}Malé
+STR_02A2_MEDIUM :{BLACK}Středni
+STR_02A3_LARGE :{BLACK}Velké
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Zvol velikost města:
+STR_02A5_TOWN_SIZE :{YELLOW}Velikost města:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Ukázat poslední zprávu nebo Älánek
+STR_OFF :Vypnuto
+STR_SUMMARY :Shrnutí
+STR_FULL :Plná
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Seznam měst
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Názvy dopravních prostředků
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Základní
+STR_02BF_CUSTOM :Uživatelské
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Uložit vlastní jména
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Výběr názvů dopravních prostředků
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Uložit uživatelské názvy dopravních prostředků na disk
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Možnosti hry
+STR_02C5_DIFFICULTY_SETTINGS :Nastavení obtížnosti
+STR_02C7_CONFIG_PATCHES :Nastavení patchů
+STR_NEWGRF_SETTINGS :Nastavení newgrf
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Zobrazení jmen měst
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Zobrazení jmen stanic
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Zobrazení popisku
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Zobrazení kontrolních bodů
+STR_02D0_FULL_ANIMATION :{SETX 12}Plné animace
+STR_02D2_FULL_DETAIL :{SETX 12}Plné detaily
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Průhledné budovy
+STR_TRANSPARENT_SIGNS :{SETX 12}Průhledná jména stanic
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Informace o zemi
+STR_02D6 :
+STR_CONSOLE_SETTING :Zobrazit / skrýt konzoli
+STR_02D7_SCREENSHOT_CTRL_S :Screenshot (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Obrovský screenshot (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :O 'OpenTTD'
+############ range ends here
+
+STR_02DB_OFF :{BLACK}Vypnuto
+STR_02DA_ON :{BLACK}Zapnuto
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Zobrazit nabídky dotací
+STR_02DD_SUBSIDIES :Dotace
+STR_02DE_MAP_OF_WORLD :Mapa světa
+STR_EXTRA_VIEW_PORT :Další pohled
+STR_SIGN_LIST :Seznam popisků
+STR_02DF_TOWN_DIRECTORY :Seznam měst
+STR_TOWN_POPULATION :{BLACK}Populace světa: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Pohled {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Nastavit jako pohled
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Nastavit souÄasné zorné pole jako pohled
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Přejít na pohled
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Nastavit pohled do zorného pole
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Jednotky měny
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Výběr jednotek měny
+STR_MEASURING_UNITS :{BLACK}Jednotky vzdálenosti
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Výběr jednotek vzdálenosti
+STR_02E6_ROAD_VEHICLES :{BLACK}SilniÄní vozidla jezdí
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}VýbÄ›r strany, na které jezdí silniÄni vozidla
+STR_02E9_DRIVE_ON_LEFT :Vlevo
+STR_02EA_DRIVE_ON_RIGHT :Vpravo
+STR_02EB_TOWN_NAMES :{BLACK}Jména měst
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Výběr stylu jmen měst
+
+STR_02F4_AUTOSAVE :{BLACK}Automatické ukládání
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Volba intervalu mezi automatickým ukládáním hry
+STR_02F7_OFF :Vypnuto
+STR_02F8_EVERY_3_MONTHS :Každé 3 měsíce
+STR_02F9_EVERY_6_MONTHS :Každých 6 měsíců
+STR_02FA_EVERY_12_MONTHS :Každých 12 měsíců
+STR_02FB_START_A_NEW_GAME :{BLACK}Založit novou hru
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Nahrát hru
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Vytvořit vlastní mapu - scénář
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Vybrat hru pro jednoho hráÄe
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Vyberte hru pro 2-8 hráÄů
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Zobrazit možnosti hry
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Zobrazit nastavení obtížnosti
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Založit novou hru, použít scénář
+STR_0304_QUIT :{BLACK}UkonÄit
+STR_0305_QUIT_OPENTTD :{BLACK}UkonÄit 'OpenTTD'
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}... můze být budováno jen ve městech
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Krajina mírného pásma
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Subarktická krajina
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Subtropická krajina
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}ZemÄ› hraÄek
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Průmysl
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Seznam průmyslu
+STR_0313_FUND_NEW_INDUSTRY :Investovat do průmyslu
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Investovat do průmyslu
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}... může být budováno jen ve městech
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}... může být budováno jen v pralesech
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}... může být budováno jen na pouštích
+STR_0319_PAUSED :{YELLOW}* * PAUZA * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Screenshot úspěšně uložen jako '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}Screenshot neuložen!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Zakoupit zemi pro budoucí užití
+STR_032F_AUTOSAVE :{RED}Automatické ukládání
+STR_SAVING_GAME :{RED}* * UKLÃDÃ SE HRA * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}Ukládání jeÅ¡tÄ› běží,{}poÄkej prosím, než dobÄ›hne!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Zvolit 'Ezy Street style music' program
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :Anglická (původní)
+STR_TOWNNAME_FRENCH :Francouzská
+STR_TOWNNAME_GERMAN :Německá
+STR_TOWNNAME_ADDITIONAL_ENGLISH :Anglická (další)
+STR_TOWNNAME_LATIN_AMERICAN :Latinskoamerická
+STR_TOWNNAME_SILLY :Anglická (legraÄní)
+STR_TOWNNAME_SWEDISH :Švédská
+STR_TOWNNAME_DUTCH :Holandská
+STR_TOWNNAME_FINNISH :Finská
+STR_TOWNNAME_POLISH :Polská
+STR_TOWNNAME_SLOVAKISH :Slovenská
+STR_TOWNNAME_NORWEGIAN :Norská
+STR_TOWNNAME_HUNGARIAN :MaÄarská
+STR_TOWNNAME_AUSTRIAN :Rakouská
+STR_TOWNNAME_ROMANIAN :Rumunská
+STR_TOWNNAME_CZECH :Česká
+STR_TOWNNAME_SWISS :Švýcarská
+STR_TOWNNAME_DANISH :Dánská
+STR_TOWNNAME_TURKISH :Turecká
+STR_TOWNNAME_ITALIAN :Italská
+STR_TOWNNAME_CATALAN :Katalánská
+############ end of townname region
+
+STR_CURR_GBP :Libra (£)
+STR_CURR_USD :Dolar ($)
+STR_CURR_EUR :Euro (€)
+STR_CURR_YEN :Japonský jen (¥)
+STR_CURR_ATS :Rakouský šilink (ATS)
+STR_CURR_BEF :Belgický frank (BEF)
+STR_CURR_CHF :Švýcarský frank (CHF)
+STR_CURR_CZK :Česká koruna (CZK)
+STR_CURR_DEM :Německá marka (DEM)
+STR_CURR_DKK :Dánská koruna (DKK)
+STR_CURR_ESP :Španělská peseta (ESP)
+STR_CURR_FIM :Finská marka (FIM)
+STR_CURR_FRF :Francouzský frank (FRF)
+STR_CURR_GRD :Řecká drachma (GRD)
+STR_CURR_HUF :MaÄarský forint (HUF)
+STR_CURR_ISK :Islandská koruna (ISK)
+STR_CURR_ITL :Italská lira (ITL)
+STR_CURR_NLG :Holandský gulden (NLG)
+STR_CURR_NOK :Norská koruna (NOK)
+STR_CURR_PLN :Polský złotý (PLN)
+STR_CURR_ROL :Rumunský lei (ROL)
+STR_CURR_RUR :Ruský rubl (RUR)
+STR_CURR_SIT :Slovinský tolar (SIT)
+STR_CURR_SEK :Švédská koruna (SEK)
+STR_CURR_YTL :Turecká lira (YTL)
+STR_CURR_SKK :Slovenská koruna (SKK)
+STR_CURR_BRR :Brazilský real (BRL)
+
+STR_CURR_CUSTOM :Vlastní...
+
+STR_OPTIONS_LANG :{BLACK}Jazyk
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Zvolit jazyk uživatelského rozhraní
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Na celou obrazovku
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}Zaškrtnutím této volby poběží OpenTTD na celé obrazovce
+
+STR_OPTIONS_RES :{BLACK}Rozlišení obrazovky
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Zvolit rozlišení obrazovky
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Formát screenshotů
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Zvolit formát screenshotů
+
+STR_AUTOSAVE_1_MONTH :Každý měsíc
+STR_AUTOSAVE_FAILED :{WHITE}Automatické uložení selhalo
+
+STR_MONTH_JAN :Leden
+STR_MONTH_FEB :Únor
+STR_MONTH_MAR :Březen
+STR_MONTH_APR :Duben
+STR_MONTH_MAY :Květen
+STR_MONTH_JUN :ÄŒerven
+STR_MONTH_JUL :ÄŒervenec
+STR_MONTH_AUG :Srpen
+STR_MONTH_SEP :Září
+STR_MONTH_OCT :Říjen
+STR_MONTH_NOV :Listopad
+STR_MONTH_DEC :Prosinec
+
+STR_HEADING_FOR_STATION :{LTBLUE}Mířím do {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}Mířím do {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Bez příkazů
+STR_NO_ORDERS_VEL :{LTBLUE}Bez příkazů, {VELOCITY}
+
+STR_PASSENGERS :cestujících
+STR_BAGS :balíků
+STR_TONS :tun
+STR_LITERS :litrů
+STR_ITEMS :kusů
+STR_CRATES :krabic
+STR_RES_OTHER :jiné
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Nemůžu sdílet seznam příkazů...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Nemůžu kopírovat seznam příkazů...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - Konec sdílených příkazů - -
+
+STR_TRAIN_IS_LOST :{WHITE}Vlak {COMMA} je ztracen.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}Zisk vlaku {COMMA} za poslední rok byl {CURRENCY}
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}Evropská měnová unie{}{}Euro se v této zemi stalo jedinou měnou pro každodenní obchodní transakce!
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Vlak {COMMA} má příliš málo příkazů
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}Vlak {COMMA} nemá žádné příkazy
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}Vlak {COMMA} má zdvojené příkazy
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}Vlak {COMMA} má v příkazech neplatnou stanici
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}SilniÄní vozidlo {COMMA} má příliÅ¡ málo příkazů
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}SilniÄní vozidlo {COMMA} nemá žádné příkazy
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}SilniÄní vozidlo {COMMA} má zdvojené příkazy
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}SilniÄní vozidlo {COMMA} má v příkazech neplatnou stanici
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}LoÄ {COMMA} má příliÅ¡ málo příkazů
+STR_SHIP_HAS_VOID_ORDER :{WHITE}LoÄ {COMMA} nemá žádné příkazy
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}LoÄ {COMMA} má zdvojené příkazy
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}LoÄ {COMMA} má v příkazech neplatnou stanici
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}Letadlo {COMMA} má příliš málo příkazů
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}Letadlo {COMMA} nemá žádné příkazy
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}Letadlo {COMMA} má zdvojené příkazy
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}Letadlo {COMMA} má v příkazech neplatnou stanici
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}Obnovení vlaku {COMMA} selhalo (finanÄní limit)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}Obnovení silniÄního vozidla {COMMA} selhalo (finanÄní limit)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}Obnovení lodi {COMMA} selhalo (finanÄní limit)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}Obnovení letadla {COMMA} selhalo (finanÄní limit)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}Vlak {COMMA} je po výměně moc dlouhý
+
+STR_CONFIG_PATCHES :{BLACK}Nastavit patche
+STR_CONFIG_PATCHES_TIP :{BLACK}Nastavit patche
+STR_CONFIG_PATCHES_CAPTION :{WHITE}Nastavit patche
+
+STR_CONFIG_PATCHES_OFF :vypnuto
+STR_CONFIG_PATCHES_ON :zapnuto
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Ukazovat rychlost vozidla ve stavové liště: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Povolit výstavbu na svazích kopců a na pobřežích: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Povolit u oblasti pokrytí realistiÄtÄ›jší velikost: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Povolit bourání více městských silnic, mostů, tunelů, atp.: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Povolit stavbu dlouhých vlaků: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Zapnout realistické zrychlování vlaků: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Zakázat vlakům a lodím otáÄení o 90 stupňů: {ORANGE}{STRING} {LTBLUE} (vyžaduje NPF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Spojovat stanice postavené vedle sebe: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Odjet, když je plně naložen jakýkoli náklad při 'naložit': {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Použij vylepšený algoritmus nakládání: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GRADUAL_LOADING :{LTBLUE}Nakládat vozidla postupně: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Inflace: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Vozit zboží do stanice jen když je poptávka: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Povolit stavbu velmi dlouhých mostů: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Povolit příkaz 'jeÄ do depa': {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Povolit výstavbu průmyslu těžícího surový materiál: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Povolit více stejného průmyslu kolem jednoho města: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Průmysl stejného druhu může být budován poblíž sebe: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Ukazovat dlouhé datum ve stavové liště: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Ukazovat semafory na stranÄ›, kde jezdí silniÄní vozidla: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Ukazovat finanÄní okno na konci každého roku: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}Použití příkazu 'bez zastavení' jako v TTDPatchi: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}SilniÄní vozidla stojí fronty (s kvantovým efektem): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Posouvat okno, když je kurzor na okraji: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Povolit úplatek místní správě: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Nejednolité stanice: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Nový globální algoritmus hledání cesty (NPF, nahradí NTP): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FREIGHT_TRAINS :{LTBLUE}Pro simulaci těžkých vlaků vynásobit hmotnost nákladu: {ORANGE}{STRING}x
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Malá letiště se budou moci stále stavět: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Varovat, pokud vlak nenajde cestu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Obnovení příkazů vozidla: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :ne
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :ano, kromě zastavených vozidel (v depu)
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :ano, u všech vozidel
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Varovat, pokud vlak prodělává: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Vozidlům se nikdy nezastaví výroba ('nezastarají'): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Automaticky obnovit dopravní prostředek, když je starý
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Obnovit vozidlo {ORANGE}{STRING}{LTBLUE} měsíců před / po dosažení maximálního stáří
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Minimální Äástka pro automatické obnovení: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Doba zobrazení chybové zprávy: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Zobrazovat populaci města v jeho popisku: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Neviditelné stromy (spoleÄnÄ› s průhlednými budovami): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Tvůrce krajiny: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :původní
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis
+STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}Maximální vzdálenost ropných rafinerií od okraje mapy {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Výška snÄ›hové Äáry: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN :{LTBLUE}ÄŒlenitost krajiny (jen TerraGenesis): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :velmi rovná
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH :rovná
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH :Älenitá
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :velmi Älenitá
+STR_CONFIG_PATCHES_TREE_PLACER :{LTBLUE}Algoritmus sázení stromového porostu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TREE_PLACER_NONE :žádné
+STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL :původní
+STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED :vylepšené
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION :{LTBLUE}OtoÄení výškové mapy: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Doleva
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE :Doprava
+STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT :{LTBLUE}Výšková úroveň pro plochou krajinu: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Největší rozsah stanice: {ORANGE}{STRING} {RED}Pozor: Vysoké nastavení zpomalí hru
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Údržba vrtulníků na heliportech: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Otevírat lištu na úpravy terénu s lištami na výstavbu tratí/silnic atd.: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Posouvat pohled opaÄným smÄ›rem: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Ukázat rozměry při použití stavebních nástrojů: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Zobrazovat barvy spoleÄnosti pro: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES_NONE :žádnou spoleÄnost
+STR_CONFIG_PATCHES_LIVERIES_OWN :jen vlastní spoleÄnost
+STR_CONFIG_PATCHES_LIVERIES_ALL :vÅ¡echny spoleÄnosti
+STR_CONFIG_PATCHES_PREFER_TEAMCHAT :{LTBLUE}Přepnout na týmový chat <ENTER>em: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Maximum vlaků na hráÄe: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Maximum silniÄních vozidel na hráÄe: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}Maximum letadel na hráÄe: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}Maximum lodí na hráÄe: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Zakázat poÄítaÄi vlaky: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Zakázat poÄítaÄi silniÄní vozidla: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Zakázat poÄítaÄi letadla: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Zakázat poÄítaÄi lodÄ›: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Nová umělá inteligence (AI) (alpha verze): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Povolit AIs v síťové hře (experimentální): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Základní servisní interval pro vlaky: {ORANGE}{STRING} dní
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Základní servisní interval pro vlaky: {ORANGE}vypnuto
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Základní servisní interval pro silniÄní vozidla: {ORANGE}{STRING} dní
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Základní servisní interval pro silniÄní vozidla: {ORANGE}vypnuto
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Základní servisní interval pro letadla: {ORANGE}{STRING} dní
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Základní servisní interval pro letadla: {ORANGE}vypnuto
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Základní servisní interval pro lodě: {ORANGE}{STRING} dní
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Základní servisní interval pro lodě: {ORANGE}vypnuto
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Vypnout servisy, když jsou vypnuty poruchy: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Zapnout omezení rychlosti vagonů: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}Vypnout elektrickou železnici: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Barevné noviny se objeví: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}PoÄáteÄní datum: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}UkonÄit hru v roce: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Plynulé změny ekonomiky (více menších změn)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Povolit kupování podílu z ostatních spoleÄností
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Při tažení umisťovat signály každých(é): {ORANGE}{STRING} dilků(y)
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Umístění hlavní lišty: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :vlevo
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :uprostřed
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :vpravo
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Okno se přichytí k druhému, když je blíž než: {ORANGE}{STRING} px
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Okno se přichytí k druhému, když je blíž než: {ORANGE}vypnuto
+
+STR_CONFIG_PATCHES_GUI :{BLACK}Ovládaní
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Výstavba
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Dop. prostředky
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Stanice
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Ekonomika
+STR_CONFIG_PATCHES_AI :{BLACK}Konkurenti
+
+STR_CONFIG_PATCHES_DISABLED :vypnuto
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Změnit hodnotu nastavení
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Některé nebo všechny základní intervaly servisů níže nesouhlasí s vybraným nastavením! 5-90 % nebo 30-800 dní jsou platné hodnoty
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}Používat YAPF ("opět další pathfinder") pro lodě: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}Používat YAPF pro silniÄní vozidla: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}Používat YAPF pro vlaky: {ORANGE}{STRING}
+
+STR_TEMPERATE_LANDSCAPE :krajina mírného pásma
+STR_SUB_ARCTIC_LANDSCAPE :subarktická krajina
+STR_SUB_TROPICAL_LANDSCAPE :subtropická kraina
+STR_TOYLAND_LANDSCAPE :ZemÄ› hraÄek
+
+STR_CHEATS :{WHITE}Cheaty
+STR_CHEATS_TIP :{BLACK}ZaÅ¡krtávací políÄka ukazují, jestli jsi tento cheat už použil.
+STR_CHEATS_WARNING :{BLACK}Varování! Chystáš se podvést ostatní hráÄe. Pamatuj si, že tento podlý Äin nebude nikdy zapomenut!
+STR_CHEAT_MONEY :{LTBLUE}Navýšit peníze o {CURRENCY64}
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Hrát jako hráÄ: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Magický buldozer (odstraní průmysl a neodstranitelné předměty): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Tunely se mohou křížit: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Povolit stavění v pauze: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Letadla nebudou na malých letiÅ¡tích havarovat (tak Äasto): {ORANGE}{STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Změnit podnebí: {ORANGE}{STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Změnit datum: {ORANGE}{DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}Povolit změnu produkce průmyslu: {ORANGE}{STRING}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}Mířím do {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Mířím do {WAYPOINT}, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :Jet přes {WAYPOINT}
+STR_GO_NON_STOP_TO_WAYPOINT :Jet bez zastávky přes {WAYPOINT}
+
+STR_WAYPOINTNAME_CITY :Kontrolní bod {TOWN}
+STR_WAYPOINTNAME_CITY_SERIAL :Kontrolní bod {TOWN} #{COMMA}
+STR_LANDINFO_WAYPOINT :Kontrolní bod
+
+STR_WAYPOINT :{WHITE}Kontrolní bod
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Vyber typ kontrolního bodu
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}Změnit jméno kontrolního bodu
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Nemohu změnit jméno kontrolního bodu...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Změnit koleje v kontrolní bod
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Nemohu zde vybudovat kontrolní bod...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Nemohu zde zrušit kontrolní bod...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Budovat koleje použitím režimu Autokoleje
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}... v tomto scénáři není ani jedno město
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}Opravdu chceš vytvořit nový náhodný terén?
+STR_MANY_RANDOM_TOWNS :{BLACK}Hodně náhodných měst
+STR_RANDOM_TOWNS_TIP :{BLACK}Pokryje krajinu mnoha náhodnými městy
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Hodně náhodného průmyslu
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Pokryje krajinu náhodným průmyslem
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Nemůžu generovat průmysl...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Otevřít nástrojovou lištu na snížení / zvýšení terénu, výsadbu stromů, atd.
+STR_LANDSCAPING_TOOLBAR :{WHITE}Úpravy krajiny
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Srovnat terén
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Různé stromy
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}Umístit nahodné stromy
+
+STR_CANT_BUILD_CANALS :{WHITE}Zde nemohu postavit průplav...
+STR_BUILD_CANALS_TIP :{BLACK}Stavět průplav. Podržením CTRL můžete vytvořit vodní plochu (pouze na úrovni moře).
+STR_LANDINFO_CANAL :Průplav
+
+STR_CANT_BUILD_LOCKS :{WHITE}Zde nemohu postavit zdymadlo...
+STR_BUILD_LOCKS_TIP :{BLACK}Stavět zdymadlo
+STR_LANDINFO_LOCK :Zdymadlo
+
+STR_BUOY_IS_IN_USE :{WHITE}... bójka je používána!
+
+STR_LANDINFO_COORDS :{BLACK}Souřadnice: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Nemůžu odstranit Äást stanice...
+STR_CANT_CONVERT_RAIL :{WHITE}Zde nemohu změnit typ kolejí...
+STR_CONVERT_RAIL_TIP :{BLACK}Změnit / vylepšit typ kolejí
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Celý vlak prodáš lokomotivy na toto místo
+
+STR_DRAG_DROP :{BLACK}Táhni a pusť
+STR_STATION_DRAG_DROP :{BLACK}Stavět stanice pomocí tahaní myši
+STR_SELECT_STATION_CLASS_TIP :{BLACK}Vyber, který druh stanic se má zobrazit
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Vyber typ stavěné stanice
+
+STR_FAST_FORWARD :{BLACK}Zrychlit běh hry
+STR_MESSAGE_HISTORY :{WHITE}Historie zpráv
+STR_MESSAGE_HISTORY_TIP :{BLACK}Seznam předešlých zpráv
+STR_MESSAGES_DISABLE_ALL :{BLACK}Vypnout všechny
+STR_MESSAGES_ENABLE_ALL :{BLACK}Zapnout všechny
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Vyhloubit uhelný důl
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Vysadit les
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Postavit ropnou plošinu
+STR_CONSTRUCT_FARM_TIP :{BLACK}Založit farmu
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Vyhloubit měděný důl
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Vyvrtat ropný vrt
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Postavit zlatý důl
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Postavit diamantový důl
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Postavit důl na železnou rudu
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Založit ovocnou plantáž
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Založit kauÄukovou plantáž
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Vyvrtat studnu
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Vysadit cukrovou vatu
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}Založit farmu na baterie
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Vyvrtat kolovou studnu
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Založit plastové fontány
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Vybudovat generátor bublin
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Vyhloubit karamelolom
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Vyhloubit cukrový důl
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Průmysl
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA} % přepraveno)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA} %/{COMMA} % přepraveno)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}... příliš blízko k jinému průmyslu
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Přestavět vlak pro převoz jiného typu nákladu
+STR_RAIL_REFIT_VEHICLE :{BLACK}Přestavět vlak
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Zvolit typ nákladu, na který vlak přestavět
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}PÅ™estavÄ›t vlak na oznaÄený typ nákladu
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Nelze přestavět vlak...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Intervaly servisů v procentech: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Změnit produkci
+
+TEMP_AI_IN_PROGRESS :{WHITE}Představujeme ti novou umělou inteligenci (pracovní). Není ještě OK, takže s ní jsou problémy. Kdykoli můžeš, udělej screenshot a přispěj s ním do fóra. Ať se ti líbí!
+TEMP_AI_ACTIVATED :{WHITE}Pozor: tato nová umÄ›lá inteligence je jeÅ¡tÄ› v alpha verzi (= nebyla moc testována)! Zatím umí pracovat jen se silniÄními vozidly!
+TEMP_AI_MULTIPLAYER :{WHITE}Varování: tato funkce je stále experimentální. Prosím posílejte jakékoli problémy na truelight@openttd.org.
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Multiplayer
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Jméno hráÄe:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}Podle tohoto jména tÄ› ostatní hráÄi poznají
+STR_NETWORK_CONNECTION :{BLACK}Připojení:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Vyber si mezi hrou na internetu nebo v místní síti
+
+STR_NETWORK_START_SERVER :{BLACK}Spustit server
+STR_NETWORK_START_SERVER_TIP :{BLACK}Spustí tvůj vlastní server
+
+STR_NETWORK_GAME_NAME :{BLACK}Název
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Název hry
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Jazyk, verze serveru, atd.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Hru vybereš kliknutím do seznamu
+
+STR_NETWORK_FIND_SERVER :{BLACK}Najít server
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Hledat server v síti
+STR_NETWORK_ADD_SERVER :{BLACK}Přidat server
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Přidá server do seznamu, ve kterém se budou hledat běžící hry.
+STR_NETWORK_ENTER_IP :{BLACK}Vlož IP adresu serveru
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}HráÄů
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}HráÄů online / maximálnÄ›
+STR_NETWORK_GAME_INFO :{SILVER}INFO O HŘE
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Klientů: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Jazyk: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Prostředí: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Velikost mapy: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}Verze hry na serveru: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}Adresa serveru: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}PoÄáteÄní datum: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Momentální datum: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Chráněno heslem!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}SERVER JE OFFLINE
+STR_NETWORK_SERVER_FULL :{SILVER}SERVER JE PLNÃ
+STR_NETWORK_VERSION_MISMATCH :{SILVER}NESOUHLASÃ VERZE
+STR_NETWORK_GRF_MISMATCH :{SILVER}NESOUHLASÃ GRAFIKY
+
+STR_NETWORK_JOIN_GAME :{BLACK}Přidat se
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}ZaÄít novou hru
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Jméno hry:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}Jméno hry se zobrazí ostatním hráÄům v menu, kde si vybírají sitovou hru
+STR_NETWORK_SET_PASSWORD :{BLACK}Nastavit heslo
+STR_NETWORK_PASSWORD_TIP :{BLACK}Svoji hru si můžeš ochránit heslem, když nechceš, aby se ti do ni hlásili jiní lidé
+STR_NETWORK_SELECT_MAP :{BLACK}Vyber mapu:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}Ve které mapě si chceš zahrát?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}Maximální poÄet hráÄů:
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Zvol maximální poÄet hráÄů. Může se jich pÅ™ipojit i ménÄ›.
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :LAN
+STR_NETWORK_INTERNET :Internet
+STR_NETWORK_LAN_INTERNET :LAN / Internet
+STR_NETWORK_INTERNET_ADVERTISE :Internet (oznámit)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 hráÄů
+STR_NETWORK_1_PLAYERS :1 hráÄ
+STR_NETWORK_2_PLAYERS :2 hráÄi
+STR_NETWORK_3_PLAYERS :3 hráÄi
+STR_NETWORK_4_PLAYERS :4 hráÄi
+STR_NETWORK_5_PLAYERS :5 hráÄů
+STR_NETWORK_6_PLAYERS :6 hráÄů
+STR_NETWORK_7_PLAYERS :7 hráÄů
+STR_NETWORK_8_PLAYERS :8 hráÄů
+STR_NETWORK_9_PLAYERS :9 hráÄů
+STR_NETWORK_10_PLAYERS :10 hráÄů
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}Maximální poÄet spoleÄností:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Omezit serverem poÄet spoleÄností
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}Maximální poÄet pozorovatelů:
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Omezit serverem pocet pozorovatelů
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Jazyk ve hře:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Aby ostatní hráÄi vÄ›dÄ›li, jakým jazykem se bude ve hÅ™e mluvit.
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}ZaÄít hru
+STR_NETWORK_START_GAME_TIP :{BLACK}Hru po síti zaÄít s náhodnou mapou nebo se scénářem
+STR_NETWORK_LOAD_GAME :{BLACK}Nahrát hru
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}PokraÄovat ve dříve uložené hÅ™e pro více hráÄů (ujisti se, že se pÅ™ipojujeÅ¡ na správného hráÄe)
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Jakýkoli
+STR_NETWORK_LANG_ENGLISH :AngliÄtina
+STR_NETWORK_LANG_GERMAN :NÄ›mÄina
+STR_NETWORK_LANG_FRENCH :Francouzština
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Vstupní místnost do multiplayerové hry
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Připravuji se na vstoupení: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}SouÄasný seznam vÅ¡ech spoleÄností v této hÅ™e. BuÄ můžeÅ¡ do jedné vstoupit, nebo můžeÅ¡ založit novou.
+STR_NETWORK_NEW_COMPANY :{BLACK}Nová spoleÄnost
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Založit novou spoleÄnost
+STR_NETWORK_SPECTATE_GAME :{BLACK}Navštívit hru
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Připojit se do hry jako pozorovatel
+STR_NETWORK_JOIN_COMPANY :{BLACK}Vstoupit do spoleÄnosti
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Pomoz vést tuto spoleÄnost
+STR_NETWORK_REFRESH :{BLACK}Obnovit info
+STR_NETWORK_REFRESH_TIP :{BLACK}Znovu naÄte informace o serveru
+
+STR_NETWORK_COMPANY_INFO :{SILVER}INFO O SPOLEÄŒNOSTI
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Jméno spoleÄnosti: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}Založeno: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}Hodnota spoleÄnosti: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Stav na úÄtu: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Loňský hrubý zisk: {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}Výkon: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}Vozidla: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Stanice: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}HráÄi: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}Připojování...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) Připojování...
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Ověřování...
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Čekání...
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Stahování mapy...
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Zpracovávání dat...
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) Registrování...
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Přijímání informací o hře...
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}PÅ™ijímání informací o spoleÄnosti...
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} klient{P "" i ů} před námi
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} kB staženo
+
+STR_NETWORK_DISCONNECT :{BLACK}Odpojit se
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}NapiÅ¡ Äástku, kterou chceÅ¡ poskytnout
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Server je chráněný. Napiš heslo
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}SpoleÄnost je chránÄ›ná. NapiÅ¡ heslo
+STR_NETWORK_CLIENT_LIST :{WHITE}Seznam hráÄů
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE} Žádná síťová zařízení nebyla nalezena (nebo je hra zkompilována bez ENABLE_NETWORK)
+STR_NETWORK_ERR_NOSERVER :{WHITE} Nenalezena žádná síťová hra
+STR_NETWORK_ERR_NOCONNECTION :{WHITE} Server neodpověděl na požadavek
+STR_NETWORK_ERR_DESYNC :{WHITE} Síť - synchronizace hry selhala
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} Síť - spojení ztraceno
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} Nemohu nahrát uloženou hru ze serveru
+STR_NETWORK_ERR_SERVER_START :{WHITE} Nemohu spustit server
+STR_NETWORK_ERR_CLIENT_START :{WHITE} Nemohu se připojit
+STR_NETWORK_ERR_TIMEOUT :{WHITE} U spojení Ä. {NUM} byl pÅ™ekroÄen Äekací limit
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE} Vznikla chyba v protokolu a naše spojení je přerušeno
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE} Revize hry tohoto klienta neodpovídá revizi hry na serveru
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} Špatné heslo
+STR_NETWORK_ERR_SERVER_FULL :{WHITE} Server je plný
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} Jsi blokován serverem
+STR_NETWORK_ERR_KICKED :{WHITE} Byl jsi vyhozen ze hry
+STR_NETWORK_ERR_CHEATER :{WHITE} Používání cheatů není na tomto serveru povoleno
+
+STR_NETWORK_ERR_LEFT :opustil hru
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :všeobecná chyba
+STR_NETWORK_ERR_CLIENT_DESYNC :chyba v synchronizaci
+STR_NETWORK_ERR_CLIENT_SAVEGAME :nemohu nahrát hru
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :spojení ztraceno
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :chyba v protokolu
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :nevydáno povolení
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :přišel neplatný paket
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :špatná revize hry
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :jméno se už používá
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :špatné heslo
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :Å¡patné ID hráÄe v DoCommand
+STR_NETWORK_ERR_CLIENT_KICKED :vyhozen serverem
+STR_NETWORK_ERR_CLIENT_CHEATER :se pokoušel podvádět
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :na serveru je plno
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :vstoupil do hry
+STR_NETWORK_GIVE_MONEY :ti dal nějaké peníze ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :dal jsi {STRING} trochu peněz ({CURRENCY})
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Tým] :
+STR_NETWORK_CHAT_COMPANY :[Tým] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Tým] pro {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[Osobní] :
+STR_NETWORK_CHAT_CLIENT :[Osobní] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[Osobní] pro {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[VÅ¡ichni] :
+STR_NETWORK_CHAT_ALL :[VÅ¡ichni] {STRING}: {GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :si změnil jméno na
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE}Server ukonÄil relaci
+STR_NETWORK_SERVER_REBOOT :{WHITE}Server se restartuje...{}PoÄkejte prosím...
+
+STR_NETWORK_SERVER :Server
+STR_NETWORK_CLIENT :Klient
+STR_NETWORK_SPECTATORS :Pozorovatelé
+
+STR_NETWORK_CLIENTLIST_NONE :(nikdo)
+STR_NETWORK_CLIENTLIST_KICK :Vyhodit
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Darovat peníze
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Napsat všem
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Napsat spoleÄnosti
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Soukromá zpráva
+
+
+STR_NETWORK_SEND :{BLACK}Poslat
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}Rozmer X mapy: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Rozmer Y mapy: {ORANGE}{STRING}
+
+
+##### PNG-MAP-Loader
+
+STR_PNGMAP_ERROR :{WHITE}Nelze nahrát krajinu z PNG...
+STR_PNGMAP_ERR_FILE_NOT_FOUND :{WHITE}... soubor nenalezen.
+STR_PNGMAP_ERR_IMAGE_TYPE :{WHITE}... nelze převést formát obrázku. Je nutno použít 8- nebo 24bitové barvy.
+STR_PNGMAP_ERR_MISC :{WHITE}... něco se prostě pokazilo. Škoda. (Asi poškozený nebo nestandardní soubor.)
+
+STR_BMPMAP_ERROR :{WHITE}Nešlo nahrát krajinu z BMP...
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}... nelze převést formát obrázku.
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Cena: {CURRENCY}
+STR_0801_COST :{RED}Cena: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Příjem: {CURRENCY}
+STR_0803_INCOME :{GREEN}Příjem: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Překládka: {CURRENCY}
+STR_FEEDER :{YELLOW}Překládka: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Odhadovaná cena: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Odhadovaný příjem: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Zde nemohu zvednout zemi...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Zde nemohu snížit zemi...
+STR_080A_ROCKS :Kamení
+STR_080B_ROUGH_LAND :Hrbolatá země
+STR_080C_BARE_LAND :Prázdná země
+STR_080D_GRASS :Travnatá země
+STR_080E_FIELDS :Pole
+STR_080F_SNOW_COVERED_LAND :Zasněžená země
+STR_0810_DESERT :Poušť
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Země skloněna nesprávným směrem
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Nemožná kombinace kolejí
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}Úprava terénu by poškodila tunel
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Již na úrovni moře
+STR_1004_TOO_HIGH :{WHITE}Příliš vysoko
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Žádné použitelné koleje
+STR_1007_ALREADY_BUILT :{WHITE}... již vystavěno
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Musíš nejprve odstranit koleje
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Výstavba železnice
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Výstavba elektrifikované železnice
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Výstavba monorailu
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}Výstavba maglevu
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Zvolit železniÄní most
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Zde nemohu postavit depo...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Zde nemohu postavit nádraží...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Zde nemohu postavit semafory...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Zde nemohu postavit koleje...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Nemohu odsud odstranit koleje...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Nemohu odsud odstranit semafory...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Orientace vlakového depa
+STR_1015_RAILROAD_CONSTRUCTION :Výstavba železnice
+STR_TOOLB_ELRAIL_CONSTRUCTION :Výstavba elektrifikované železnice
+STR_1016_MONORAIL_CONSTRUCTION :Výstavba monorailu
+STR_1017_MAGLEV_CONSTRUCTION :Výstavba maglevu
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Položit koleje
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Postavit železniÄní depo (pro nákup a servis vlaků)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Postavit nádraží
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Postavit semafory
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Postavit železniÄní most
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Postavit železniÄní tunel
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Přepnout režim stavba/odstranění pro koleje a semafory
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Výběr mostů - staví se kliknutím na obrázek mostu
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Zvolit orientaci železniÄního depa
+STR_1021_RAILROAD_TRACK :Koleje
+STR_1023_RAILROAD_TRAIN_DEPOT :ŽelezniÄní depo
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}... území vlastní jiná spoleÄnost
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :ŽelezniÄní traÅ¥ s normálními signály
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :ŽelezniÄní traÅ¥ s presignály
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :ŽelezniÄní traÅ¥ s výstupními signály
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :ŽelezniÄní traÅ¥ s kombinovanými signály
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Musíš nejprve odstranit silnici
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Silnice je v rekonstrukci
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Výstavba silnic
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Zvolit silniÄní most
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Zde nemohu postavit silnici...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Nemohu odsud odstranit silnici
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Orientace garáže
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Tady nejde postavit garáž
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Nemohu postavit autobusovou stanici...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Nemohu postavit nákladovou rampu...
+STR_180A_ROAD_CONSTRUCTION :Výstavba silnic
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Postavit silnici
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Postavit garáž (pro nákup a servis vozidel)
+STR_180D_BUILD_BUS_STATION :{BLACK}Postavit autobusovou stanici
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Postavit nákladovou rampu
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Postavit silniÄní most
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Postavit silniÄní tunel
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Přepnout stavba / odstranění silnice
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Výběr orientace garáže
+STR_1814_ROAD :Silnice
+STR_1815_ROAD_WITH_STREETLIGHTS :Silnice s pouliÄním osvÄ›tlením
+STR_1816_TREE_LINED_ROAD :Silnice s alejí
+STR_1817_ROAD_VEHICLE_DEPOT :Garáž
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :ŽelezniÄní pÅ™ejezd
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Města
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Budova musí být nejprve zniÄena
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}Populace: {ORANGE}{COMMA}{BLACK} Domů: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Přejmenovat město
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Nemohu přejmenovat město:
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}Místní správa města {TOWN} odmítla vydat povolení.
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Jména měst - stiskni na jménu města pro pohled na město
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Umístit pohled na město
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Změnit jméno města
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Cestujících minulý měsíc: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Pošta za minulý měsíc: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Vysoký kancelářský blok
+STR_2010_OFFICE_BLOCK :Kancelářský blok
+STR_2011_SMALL_BLOCK_OF_FLATS :Malé bytovky
+STR_2012_CHURCH :Kostel
+STR_2013_LARGE_OFFICE_BLOCK :Velký kancelářský blok
+STR_2014_TOWN_HOUSES :Městské domy
+STR_2015_HOTEL :Hotel
+STR_2016_STATUE :Socha
+STR_2017_FOUNTAIN :Fontána
+STR_2018_PARK :Park
+STR_2019_OFFICE_BLOCK :Kancelářský blok
+STR_201A_SHOPS_AND_OFFICES :Obchody a kanceláře
+STR_201B_MODERN_OFFICE_BUILDING :Moderní kancelářský blok
+STR_201C_WAREHOUSE :Výrobní hala
+STR_201D_OFFICE_BLOCK :Kancelářský blok
+STR_201E_STADIUM :Stadion
+STR_201F_OLD_HOUSES :Staré domy
+STR_2020_LOCAL_AUTHORITY :{BLACK}Místní správa
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Ukázat informace o místní správě
+STR_2022_LOCAL_AUTHORITY :{WHITE}Místní správa města {TOWN}
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Hodnocení spoleÄností:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Dotace
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Nabídnuté dotace pro službu:
+STR_2027_FROM_TO :{ORANGE}{STRING.big} z {STRING} do {STRING}
+STR_2028_BY :{YELLOW} (do {DATE_SHORT})
+STR_202A_NONE :{ORANGE}Nic
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Již přiznané dotace:
+STR_202C_FROM_TO :{ORANGE}{STRING.big} z {STATION} do {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, do {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}Nabídka dotace přepravy vypršela:{}{}Dotace dopravy {STRING.gen} z {STRING} do {STRING} nebude dále nabízena.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}UkonÄení dotování dopravy:{}{}Dotace pro {STRING} z {STATION} do {STATION} již nebude dále poskytována.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Nabídka dotace:{}{}Doprava {STRING} z {STRING} do {STRING} bude jeden rok dotována místní správou!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Dotace pÅ™idÄ›lena spoleÄnosti {COMPANY}.{}{}Doprava {STRING.gen} z {STATION} do {STATION} bude po jeden rok vynášet 150 % normální ceny.
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Dotace pÅ™idÄ›lena spoleÄnosti {COMPANY}.{}{}Doprava {STRING.gen} z {STATION} do {STATION} bude po jeden rok vynášet dvojnásobek normální ceny!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Dotace pÅ™idÄ›lena spoleÄnosti {COMPANY}.{}{}Doprava {STRING.gen} z {STATION} do {STATION} bude po jeden rok vynášet trojnásobek normální ceny!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Dotace pÅ™idÄ›lena spoleÄnosti {COMPANY}.{}{}Doprava {STRING.gen} z {STATION} do {STATION} bude po jeden rok vynášet ÄtyÅ™násobek normální ceny!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}Místní správa města {TOWN} zakazuje stavbu dalšího letiště v tomto městě.
+STR_2036_COTTAGES :Chatky
+STR_2037_HOUSES :Domy
+STR_2038_FLATS :Byty
+STR_2039_TALL_OFFICE_BLOCK :Vysoký kancelářský blok
+STR_203A_SHOPS_AND_OFFICES :Obchody a kanceláře
+STR_203B_SHOPS_AND_OFFICES :Obchody a kanceláře
+STR_203C_THEATER :Divadlo
+STR_203D_STADIUM :Stadion
+STR_203E_OFFICES :Kanceláře
+STR_203F_HOUSES :Domy
+STR_2040_CINEMA :Kino
+STR_2041_SHOPPING_MALL :Nákupní středisko
+STR_2042_DO_IT :{BLACK}Provést
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}Seznam vÅ¡ech vÄ›cí, které lze dÄ›lat v tomto mÄ›stÄ› - oznaÄ Äinnost pro více detailů:
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}ProveÄ oznaÄenou Äinnost ze seznamu.
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Možné Äinnosti:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Malá reklamní kampaň
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Střední reklamní kampaň
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Velká reklamní kampan
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Dotovat rekonstrukci místních silnic
+STR_204A_BUILD_STATUE_OF_COMPANY :Postavit sochu majitele spoleÄnosti
+STR_204B_FUND_NEW_BUILDINGS :Dotovat nové budovy
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Koupit výhradní právo k přepravě
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Podplatit místní správu
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Zahájit malou reklamní kampaň, která přiláká více cestujících a nákladu.{} Cena: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Zahájit středně velkou reklamní kampaň, která přiláká více cestujících a nákladu.{} Cena: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Zahájit velkou reklamní kampaň, která přiláká více cestujících a nákladu.{} Cena: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} Dotovat rekonstrukci místní silniÄní sítÄ›. Způsobí problémy v dopravÄ› po dobu 6 mÄ›síců.{} Cena: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Postavit sochu vlastníka jako poctu tvé spoleÄnosti.{} Cena: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Dotovat stavbu nových obchodních budov ve městě.{} Cena: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Koupit výhradní práva k pÅ™epravÄ› zboží z tohoto mÄ›sta po dobu jednoho roku. Místní správa dovolí cestujícím a nákladu používat pouze stanice tvé spoleÄnosti.{} Cena: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Podplatit místní správu pro zvýšení hodnocení spoleÄnosti. Riziko trestu v případÄ› pÅ™istižení.{} Cena: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}{TOWN} zažívá dopravní chaos!{}{}Program přestavby ulic sponzorovaný {COMPANY} přináší motoristům 6 měsíců utrpení!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (ve výstavbě)
+STR_2059_IGLOO :Iglů
+STR_205A_TEPEES :Teepee
+STR_205B_TEAPOT_HOUSE :Dům konviÄka
+STR_205C_PIGGY_BANK :Banka prasátko
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{1:STRING} {0:TOWN}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Úpravy krajiny
+STR_2800_PLANT_TREES :Vysadit stromy
+STR_2801_PLACE_SIGN :Umístit nápis
+STR_2802_TREES :{WHITE}Stromy
+STR_2803_TREE_ALREADY_HERE :{WHITE}... strom už tu je
+STR_2804_SITE_UNSUITABLE :{WHITE}... nepoužitelné místo
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Zde nemůžeš vysadit strom...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}... příliš mnoho popisků
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Zde nemůžeš umístit nápis...
+STR_280A_SIGN :Nápis
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Upravit text popisku
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Nemůžeš změnit jméno nápisu...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Zvol typ stromu na vysazení
+STR_280E_TREES :Stromy
+STR_280F_RAINFOREST :Tropický prales
+STR_2810_CACTUS_PLANTS :Kaktusy
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Výběr nádraží
+STR_3001_AIRPORT_SELECTION :{WHITE}Výběr letiště
+STR_3002_ORIENTATION :{BLACK}Orientace
+STR_3003_NUMBER_OF_TRACKS :{BLACK}PoÄet nástupiÅ¡Å¥
+STR_3004_PLATFORM_LENGTH :{BLACK}Délka nástupiště
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Příliš blízko jinému nádraží
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Spojuje více jak jedno existující nádraží nebo nákladovou rampu...
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}Příliš mnoho nádraží nebo nákladových ramp v tomto městě
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}Příliš mnoho nádraží nebo nákladových ramp
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Příliš mnoho autobusových zastávek
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}Příliš mnoho zastávek nákladních automobilů
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Příliš blízko k jinému nádraží nebo nákladové rampě
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Musíš nejprve zniÄit stanici
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Příliš blízko k jinému letišti
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Musíš nejprve zniÄit letiÅ¡tÄ›
+
+STR_3030_RENAME_STATION_LOADING :Přejmenovat stanici
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Nemohu přejmenovat stanici...
+STR_3032_RATINGS :{BLACK}Hodnocení
+STR_3033_ACCEPTS :{BLACK}Přijímá
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}Místní hodnocení dopravní služby:
+
+############ range for rating starts
+STR_3035_APPALLING :Příšerné
+STR_3036_VERY_POOR :Velmi slabé
+STR_3037_POOR :Slabé
+STR_3038_MEDIOCRE :Průměrné
+STR_3039_GOOD :Dobré
+STR_303A_VERY_GOOD :Velmi dobré
+STR_303B_EXCELLENT :Vynikající
+STR_303C_OUTSTANDING :Úžasné
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} už dále nepřijímá {STRING}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} už dále nepřijímá {STRING} nebo {STRING}
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} nyní přijímá {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} nyní přijímá {STRING} a {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Orientace autobusové zastávky.
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Orientace nákladové rampy.
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Musíš nejprve zniÄit autobusovou zastávku
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Musíš nejprve zniÄit nákladovou rampu
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} stanic{P e e ""}
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Nic -
+STR_304B_SITE_UNSUITABLE :{WHITE}... nepoužitelné místo
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Příliš blízko k jinému doku
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Musíš nejprve zniÄit dok
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Zvolit orientaci nádraží
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Zvolit poÄet nástupiÅ¡Å¥ pro nádraží
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Zvolit délku nádraží
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Zvolit orientaci autobusové zastávky
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Zvolit orientaci nákladové rampy
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Vycentrovat pohled na stanici
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Ukázat hodnocení spoleÄností
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Změnit jméno stanice
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Ukázat seznam přijímaného nákladu
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Jména stanic - pro nahlédnutí na stanici klepni na její jméno
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Zvol velikost a typ letiště
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :Nádraží
+STR_305F_AIRCRAFT_HANGAR :Hangár
+STR_3060_AIRPORT :Letiště
+STR_3061_TRUCK_LOADING_AREA :Nákladová rampa
+STR_3062_BUS_STATION :Autobusová zastávka
+STR_3063_SHIP_DOCK :Dok
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Zvýraznit oblast pokrytí
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Nezvýrazňovat oblast pokrytí
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Zvýraznění oblasti pokrytí
+STR_3068_DOCK :{WHITE}Přístav
+STR_3069_BUOY :Bójka
+STR_306A_BUOY_IN_THE_WAY :{WHITE}... bójka v cestě
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}... stanice je příliš rozložitá
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}... nejednolité stanice nejsou povoleny
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Podržením CTRL můžeÅ¡ oznaÄit více položek
+
+STR_UNDEFINED :(nedefinovaný řetězec)
+STR_STAT_CLASS_DFLT :Původní stanice
+STR_STAT_CLASS_WAYP :Kontrolní body
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Orientace lodního depa
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}... musí být postaven na vodě
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Zde nemůžeš postavit lodní depo...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Zvolit orientaci lodního depa
+STR_3804_WATER :Voda
+STR_3805_COAST_OR_RIVERBANK :Pobřeží nebo břeh
+STR_3806_SHIP_DEPOT :Lodní depo
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}... nemohu stavět na vodě
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Uložit hru
+STR_4001_LOAD_GAME :{WHITE}Otevřít hru
+STR_4002_SAVE :{BLACK}Uložit
+STR_4003_DELETE :{BLACK}Smazat
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} MB voln{P ý é ých}
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Nemohu Äíst z jednotky
+STR_4007_GAME_SAVE_FAILED :{WHITE}Uložení hry selhalo
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Nemohu smazat soubor
+STR_4009_GAME_LOAD_FAILED :{WHITE}Nemohu otevřít hru
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}Seznam jednotek, adresářů a uložených her
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Zvolené jméno uložené hry
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Smazat oznaÄenou uloženou hru
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Uložit aktuální hru se zvoleným jménem
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Zvolit nový typ hry
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Zvolit scénář (zelená), přednastavenou hru (modrá), nebo novou náhodnou hru
+STR_4010_GENERATE_RANDOM_NEW_GAME :Vytvořit novou náhodnou hru
+STR_4011_LOAD_HEIGHTMAP :{WHITE}Nahrát výškovou mapu
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} v cestÄ›
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :Uhelný důl
+STR_4803_POWER_STATION :Elektrárna
+STR_4804_SAWMILL :Pila
+STR_4805_FOREST :Les
+STR_4806_OIL_REFINERY :Rafinerie
+STR_4807_OIL_RIG :Ropná plošina
+STR_4808_FACTORY :Továrna
+STR_4809_PRINTING_WORKS :Tiskárna
+STR_480A_STEEL_MILL :Ocelárna
+STR_480B_FARM :Farma
+STR_480C_COPPER_ORE_MINE :Důl na měděnou rudu
+STR_480D_OIL_WELLS :Ropné vrty
+STR_480E_BANK :Banka
+STR_480F_FOOD_PROCESSING_PLANT :Továrna na zpracování jídla
+STR_4810_PAPER_MILL :Papírna
+STR_4811_GOLD_MINE :Zlatý důl
+STR_4812_BANK :Banka
+STR_4813_DIAMOND_MINE :Diamantový důl
+STR_4814_IRON_ORE_MINE :Důl na železnou rudu
+STR_4815_FRUIT_PLANTATION :Ovocná plantáž
+STR_4816_RUBBER_PLANTATION :KauÄuková plantáž
+STR_4817_WATER_SUPPLY :Zdroj vody
+STR_4818_WATER_TOWER :Vodojem
+STR_4819_FACTORY :Továrna
+STR_481A_FARM :Farma
+STR_481B_LUMBER_MILL :Pila
+STR_481C_COTTON_CANDY_FOREST :Les cukrové vaty
+STR_481D_CANDY_FACTORY :Továrna na sladkosti
+STR_481E_BATTERY_FARM :Farma na baterie
+STR_481F_COLA_WELLS :Kolové studny
+STR_4820_TOY_SHOP :HraÄkářství
+STR_4821_TOY_FACTORY :Továrna na hraÄky
+STR_4822_PLASTIC_FOUNTAINS :Plastové fontány
+STR_4823_FIZZY_DRINK_FACTORY :Sodovkárna
+STR_4824_BUBBLE_GENERATOR :Generátor bublin
+STR_4825_TOFFEE_QUARRY :Karamelolom
+STR_4826_SUGAR_MINE :Cukerný důl
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Vyžaduje: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Vyžaduje: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Vyžaduje: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Produkce minulý měsíc:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA} % přepraveno)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Nastavit pohled na průmysl
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}{STRING} se staví poblíž města {TOWN}!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Nový {STRING} se vysazuje poblíž města {TOWN}!
+STR_482F_COST :{BLACK}Cena: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Tento druh průmyslu zde nemohu postavit...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... lesy lze vysadit jen nad snÄ›hovou Äáru
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} ohlašuje okamžité uzavření!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}Zásobovací problémy způsobily uzavření {INDUSTRY}!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}Nedostatek stromů způsobil uzavření {INDUSTRY}!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} zvyšuje produkci!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}Nové ložisko uhlí nalezené v {INDUSTRY}!{}Zdvojnásobí se produkce!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}Nové zásoby ropy nalezené v {INDUSTRY}!{}Zdvojnásobí se produkce!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}Lepší metody pěstování {INDUSTRY} zdvojnásobí produkci!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}{INDUSTRY} produkce poklesla o 50 %.
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}Zamoření škůdci v {INDUSTRY}!{}Produkce poklesla o 50 %.
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}... může být umístěno pouze poblíž okrajů mapy
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}{1:INDUSTRY} zvyšuje produkci {0:STRING.gen} o{NBSP}{2:COMMA}{NBSP}%!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}{1:INDUSTRY} snižuje produkci {0:STRING.gen} o{NBSP}{2:COMMA}{NBSP}%!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Vlak v tunelu
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}SilniÄní vozidlo v tunelu
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}V cestě je jiný tunel
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Nemohu vyrovnat zemi na druhém konci tunelu
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Nutno nejprve zniÄit tunel
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Nutno nejprve zniÄit most
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Nelze zaÄít a skonÄit na stejném místÄ›
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Pod mostem je nutná rovná země nebo voda
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}ZaÄátek a konec musí být ve stejné výšce
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Místo nevhodné pro vjezd do tunelu
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Zavěšený, ocelový
+STR_500F_GIRDER_STEEL :Trámový, ocelový
+STR_5010_CANTILEVER_STEEL :Konzolový, ocelový
+STR_5011_SUSPENSION_CONCRETE :Zavěšený, betonový
+STR_5012_WOODEN :Dřevěný
+STR_5013_CONCRETE :Betonový
+STR_5014_TUBULAR_STEEL :Potrubní, ocelový
+STR_BRIDGE_TUBULAR_SILICON :Potrubní, křemíkový
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Zde nelze postavit most...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Zde nelze postavit tunel...
+STR_5017_RAILROAD_TUNNEL :ŽelezniÄní tunel
+STR_5018_ROAD_TUNNEL :SilniÄní tunel
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Ocelový zavěšený železniÄní most
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Ocelový trámový železniÄní most
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Ocelový konzolový železniÄní most
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :ZpevnÄ›ný betonový zavěšený železniÄní most
+STR_501F_WOODEN_RAIL_BRIDGE :DÅ™evÄ›ný železniÄní most
+STR_5020_CONCRETE_RAIL_BRIDGE :Betonový železniÄní most
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Ocelový zavěšený silniÄní most
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Ocelový trámový silniÄní most
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Ocelový konzolový silniÄní most
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :ZpevnÄ›ný betonový zavěšený silniÄní most
+STR_5025_WOODEN_ROAD_BRIDGE :DÅ™evÄ›ný silniÄní most
+STR_5026_CONCRETE_ROAD_BRIDGE :Betonový silniÄní most
+STR_5027_TUBULAR_RAIL_BRIDGE :Potrubní železniÄní most
+STR_5028_TUBULAR_ROAD_BRIDGE :Potrubní silniÄní most
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}V cestÄ› je objekt
+STR_5801_TRANSMITTER :VysílaÄ
+STR_5802_LIGHTHOUSE :Maják
+STR_5803_COMPANY_HEADQUARTERS :Ředitelství spoleÄnosti
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}... v cestÄ› je Å™editelství spoleÄnosti
+STR_5805_COMPANY_OWNED_LAND :Půda vlastnÄ›na spoleÄností
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Nelze zakoupit tento pozemek...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}... již ji vlastníš!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Beze jména
+STR_SV_TRAIN_NAME :Vlak {COMMA}
+STR_SV_ROADVEH_NAME :SilniÄní vozidlo {COMMA}
+STR_SV_SHIP_NAME :LoÄ {COMMA}
+STR_SV_AIRCRAFT_NAME :Letadlo {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :{STRING} sever
+STR_SV_STNAME_SOUTH :{STRING} jih
+STR_SV_STNAME_EAST :{STRING} východ
+STR_SV_STNAME_WEST :{STRING} západ
+STR_SV_STNAME_CENTRAL :{STRING} střed
+STR_SV_STNAME_TRANSFER :{STRING} přestupní
+STR_SV_STNAME_HALT :{STRING} zastávka
+STR_SV_STNAME_VALLEY :{STRING} údolí
+STR_SV_STNAME_HEIGHTS :{STRING} výšina
+STR_SV_STNAME_WOODS :{STRING} polesí
+STR_SV_STNAME_LAKESIDE :{STRING} jezero
+STR_SV_STNAME_EXCHANGE :{STRING} centrála
+STR_SV_STNAME_AIRPORT :{STRING} letiště
+STR_SV_STNAME_OILFIELD :{STRING} ropná plošina
+STR_SV_STNAME_MINES :{STRING} doly
+STR_SV_STNAME_DOCKS :{STRING} přístav
+STR_SV_STNAME_BUOY_1 :{STRING} bójka 1
+STR_SV_STNAME_BUOY_2 :{STRING} bójka 2
+STR_SV_STNAME_BUOY_3 :{STRING} bójka 3
+STR_SV_STNAME_BUOY_4 :{STRING} bójka 4
+STR_SV_STNAME_BUOY_5 :{STRING} bójka 5
+STR_SV_STNAME_BUOY_6 :{STRING} bójka 6
+STR_SV_STNAME_BUOY_7 :{STRING} bójka 7
+STR_SV_STNAME_BUOY_8 :{STRING} bójka 8
+STR_SV_STNAME_BUOY_9 :{STRING} bójka 9
+STR_SV_STNAME_ANNEXE :{STRING} přípojné
+STR_SV_STNAME_SIDINGS :{STRING} odstavné
+STR_SV_STNAME_BRANCH :{STRING} odboÄka
+STR_SV_STNAME_UPPER :horní {STRING}
+STR_SV_STNAME_LOWER :dolní {STRING}
+STR_SV_STNAME_HELIPORT :{STRING} heliport
+STR_SV_STNAME_FOREST :{STRING} les
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Obtížnost
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Uložit
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Lehká
+STR_6802_MEDIUM :{BLACK}Střední
+STR_6803_HARD :{BLACK}Těžká
+STR_6804_CUSTOM :{BLACK}Uživatelská
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maximální poÄet protivníků: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Čas startu protivníků: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}Množství měst: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}Množství průmyslu: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Maximální poÄáteÄní dluh: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}PoÄáteÄní úroková sazba: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Cena provozu vozidel: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Rychlost výstavby protivníků: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Inteligence protivníků: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Poruchy vozidel: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Činitel dotací: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Cena výstavby: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Typ krajiny: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Kvantita jezer/moří: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Ekonomika: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}OtáÄení vlaků: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Katastrofy: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Postoj místní rady k (terénním) úpravám kolem města: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :žádný
+STR_6816_LOW :nízké
+STR_6817_NORMAL :střední
+STR_6818_HIGH :vysoké
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :velmi nízká
+STR_681C_SLOW :nízká
+STR_681D_MEDIUM :středně vysoká
+STR_681E_FAST :vysoká
+STR_681F_VERY_FAST :velmi vysoká
+STR_VERY_LOW :velmi nízká
+STR_6820_LOW :nízká
+STR_6821_MEDIUM :střední
+STR_6822_HIGH :vysoká
+STR_6823_NONE :žádné
+STR_6824_REDUCED :snížené
+STR_6825_NORMAL :běžné
+STR_6826_X1_5 :1,5x
+STR_6827_X2 :2x
+STR_6828_X3 :3x
+STR_6829_X4 :4x
+STR_682A_VERY_FLAT :velmi plochá
+STR_682B_FLAT :plochá
+STR_682C_HILLY :kopcovitá
+STR_682D_MOUNTAINOUS :hornatá
+STR_682E_STEADY :stabilní
+STR_682F_FLUCTUATING :proměnlivá
+STR_6830_IMMEDIATE :okamžitě
+STR_6831_3_MONTHS_AFTER_PLAYER :3 mÄ›síce po hráÄi
+STR_6832_6_MONTHS_AFTER_PLAYER :6 mÄ›síců po hráÄi
+STR_6833_9_MONTHS_AFTER_PLAYER :9 mÄ›síců po hráÄi
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :na konci tratě a ve stanicích
+STR_6835_AT_END_OF_LINE_ONLY :pouze na konci tratÄ›
+STR_6836_OFF :vypnuty
+STR_6837_ON :zapnuty
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Zobraz tabulku nejlepších výsledků
+STR_6839_PERMISSIVE :nezaujatý
+STR_683A_TOLERANT :tolerantní
+STR_683B_HOSTILE :zaujatý
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(hrÃ¡Ä {COMMA})
+STR_7004_NEW_FACE :{BLACK}Nový obliÄej
+STR_7005_COLOR_SCHEME :{BLACK}Barva
+STR_7006_COLOR_SCHEME :{GOLD}Barevné schéma:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Nové barevné schéma
+STR_7008_COMPANY_NAME :{BLACK}SpoleÄnost
+STR_7009_PRESIDENT_NAME :{BLACK}Prezident
+STR_700A_COMPANY_NAME :Jméno spoleÄnosti
+STR_700B_PRESIDENT_S_NAME :Jméno prezidenta
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Nemohu zmÄ›nit jméno spoleÄnosti.
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Nemohu změnit jméno prezidenta.
+STR_700E_FINANCES :{WHITE}{COMPANY} Finance {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Příjmy / výdaje
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Výstavba
+STR_7012_NEW_VEHICLES :{GOLD}Nové dopravní prostředky
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Provoz vlaků
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Provoz silniÄních vozidel
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Provoz letadel
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Provoz lodí
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Údržba
+STR_7018_TRAIN_INCOME :{GOLD}Příjmy vlaků
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Příjmy silniÄních vozidel
+STR_701A_AIRCRAFT_INCOME :{GOLD}Příjmy letadel
+STR_701B_SHIP_INCOME :{GOLD}Příjmy lodí
+STR_701C_LOAN_INTEREST :{GOLD}Úroky z půjÄek
+STR_701D_OTHER :{GOLD}Další
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Celkem:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Graf příjmu
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Graf provozního zisku
+STR_7026_BANK_BALANCE :{WHITE}Stav na úÄtu
+STR_7027_LOAN :{WHITE}PůjÄka
+STR_MAX_LOAN :{WHITE}Max. půjÄka: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}PůjÄit {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Vrátit {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}... maximální dovolená výše půjÄky je {CURRENCY}.
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Nemohu půjÄit více penÄ›z...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}... žádný dluh ke splacení
+STR_702E_REQUIRED :{WHITE}... je potřeba {CURRENCY}
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Nemohu zaplatit dluh.
+STR_INSUFFICIENT_FUNDS :{WHITE}NemůžeÅ¡ darovat peníze půjÄené z banky...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Zvol nový obliÄej prezidenta
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Zvol nový nátÄ›r vozidel spoleÄnosti
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Změnit jméno prezidenta
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}ZmÄ›nit jméno spoleÄnosti
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Stiskni vybrané barevné schéma
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}PůjÄit si více
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Splatit Äást dluhu
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(Prezident)
+STR_7038_INAUGURATED :{GOLD}Založeno: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Vozidla:
+STR_TRAINS :{WHITE}{COMMA} vlak{P "" y ů}
+STR_ROAD_VEHICLES :{WHITE}{COMMA} silniÄní{P "" "" ch} vozid{P lo la el}
+STR_AIRCRAFT :{WHITE}{COMMA} letad{P lo la el}
+STR_SHIPS :{WHITE}{COMMA} lo{P Ä dÄ› dí}
+STR_7042_NONE :{WHITE}Nic
+STR_7043_FACE_SELECTION :{WHITE}Volba tváře
+STR_7044_MALE :{BLACK}Mužské
+STR_7045_FEMALE :{BLACK}Ženské
+STR_7046_NEW_FACE :{BLACK}Nový obliÄej
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}ZruÅ¡it volbu nového obliÄeje
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Potvrdit výbÄ›r obliÄeje
+STR_7049_SELECT_MALE_FACES :{BLACK}Zvolit mužské obliÄeje
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Zvolit ženské obliÄeje
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Vytvořit náhodnou novou tvář
+STR_704C_KEY :{BLACK}Legenda
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Ukázat legendu ke grafům
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Legenda ke grafům spoleÄností
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Klepni zde pro pÅ™epnuti zobrazení spoleÄnosti na grafu
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}DoruÄeno jednotek zboží
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Hodnocení spoleÄností (nejvyšší hodnocení=1000)
+STR_7052_COMPANY_VALUES :{WHITE}Hodnota spoleÄností
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Tabulka poÅ™adí spoleÄností
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}Dopravní spoleÄnost má problémy!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} bude prodána nebo vyhlásí bankrot, pokud se brzy nezvýší výkonnost!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(Prezident)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}SlouÄení dopravních spoleÄností!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} byla prodána {COMPANY} za {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Hledáme spoleÄnost, která pÅ™evezme naÅ¡i spoleÄnost.{}{}Chcete zakoupit {COMPANY} za {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Bankrot!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} byla zavřena veřiteli a podíly byly prodány!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}Nová spoleÄnost založena!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} zaÄíná stavÄ›t poblíž {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Nemohu koupit spoleÄnost...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Ceny za přepravu nákladu
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Doba přepravy ve dnech
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Platba za doruÄeni 10 jednotek (nebo 10 000 litru) nákladu do vzdálenosti 20 Ätverecků
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Zobrazit / skrýt graf pro urÄitý druh nákladu
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Strojvůdce
+STR_7067_TRAFFIC_MANAGER :Manažer dopravy
+STR_7068_TRANSPORT_COORDINATOR :Koordinátor dopravy
+STR_7069_ROUTE_SUPERVISOR :Vedoucí trasy
+STR_706A_DIRECTOR :Ředitel
+STR_706B_CHIEF_EXECUTIVE :Výkonný ředitel
+STR_706C_CHAIRMAN :Předseda
+STR_706D_PRESIDENT :Prezident
+STR_706E_TYCOON :Magnát
+STR_706F_BUILD_HQ :{BLACK}Ředitelství
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Vybudovat Å™editelství spoleÄnosti / ukázat Å™editelství spoleÄnosti
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Sídlo spoleÄnosti můžeÅ¡ vystavit jinde za 1 % její hodnoty
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Nemohu postavit Å™editelství spoleÄnosti
+STR_7072_VIEW_HQ :{BLACK}Ředitelství
+STR_RELOCATE_HQ :{BLACK}Přesídlit
+STR_COMPANY_PASSWORD :{BLACK}Heslo
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Heslo - zabrání neautorizovaným uživatelům v pÅ™ipojení se k tvé spoleÄnosti.
+STR_SET_COMPANY_PASSWORD :Nastav heslo spoleÄnosti.
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}CelosvÄ›tový hospodářský úpadek!{}{}FinanÄní experti se kvůli prudkému poklesu ekonomiky obávají nejhoršího!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Konec hospodářského úpadku!{}{}Posílení trhu zvýšilo u průmyslu důvěru!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Přepnout velké/malé okno
+STR_7076_COMPANY_VALUE :{GOLD}Hodnota spoleÄnosti: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Koupit 25% podíl ve spoleÄnosti
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Prodat 25% podíl ve spoleÄnosti
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Koupit 25% podíl v této spoleÄnosti
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Prodat 25% podíl v této spoleÄnosti
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Nemohu koupit podíl v této spoleÄnosti...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}Nemohu prodat podíl v této spoleÄnosti...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% vlastněno {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% vlastněno {COMPANY}{} {COMMA}% vlastněno {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} byla převzata {COMPANY}!
+STR_7080_PROTECTED :{WHITE}Tato spoleÄnost zatím neobchoduje s akciemi...
+
+STR_LIVERY_DEFAULT :Výchozí barva
+STR_LIVERY_STEAM :Parní lokomotiva
+STR_LIVERY_DIESEL :Dieselová lokomotiva
+STR_LIVERY_ELECTRIC :Elektrická lokomotiva
+STR_LIVERY_MONORAIL :Jednokolejná lokomotiva
+STR_LIVERY_MAGLEV :Lokomotiva Maglev
+STR_LIVERY_DMU :DMU
+STR_LIVERY_EMU :EMU
+STR_LIVERY_PASSENGER_WAGON_STEAM :Osobní vagon (parní)
+STR_LIVERY_PASSENGER_WAGON_DIESEL :Osobní vagon (dieselový)
+STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Osobní vagon (elektrický)
+STR_LIVERY_FREIGHT_WAGON :Nákladní vagon
+STR_LIVERY_BUS :Autobus
+STR_LIVERY_TRUCK :Nákladní vůz
+STR_LIVERY_PASSENGER_SHIP :Trajekt
+STR_LIVERY_FREIGHT_SHIP :Nákladní loÄ
+STR_LIVERY_HELICOPTER :Vrtulník
+STR_LIVERY_SMALL_PLANE :Malé letadlo
+STR_LIVERY_LARGE_PLANE :Velké letadlo
+
+STR_LIVERY_GENERAL_TIP :{BLACK}Zobrazit všeobecná barevná schémata
+STR_LIVERY_TRAIN_TIP :{BLACK}Zobrazit barevná schémata pro vlaky
+STR_LIVERY_ROADVEH_TIP :{BLACK}Zobrazit barevná schémata pro silniÄní vozidla
+STR_LIVERY_SHIP_TIP :{BLACK}Zobrazit barevná schémata pro lodě
+STR_LIVERY_AIRCRAFT_TIP :{BLACK}Zobrazit barevná schémata pro letadla
+STR_LIVERY_PRIMARY_TIP :{BLACK}Vybrat primární barvu oznaÄeného schématu
+STR_LIVERY_SECONDARY_TIP :{BLACK}Vybrat sekundární barvu oznaÄeného schématu
+STR_LIVERY_PANEL_TIP :{BLACK}Vyber, které barevné schéma chceÅ¡ zmÄ›nit (více oznaÄíš s CTRL). Schéma zmÄ›níš kliknutím na tlaÄítko
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (parní)
+STR_8001_MJS_250_DIESEL :MJS 250 (dieselová)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut (dieselová)
+STR_8006_POWERNAUT_DIESEL :Powernaut (dieselová)
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (parní)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (parní)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (parní)
+STR_800A_SH_8P_STEAM :SH '8P' (parní)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (dieselová)
+STR_800C_DASH_DIESEL :'Dash' (dieselová)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (dieselová)
+STR_800E_UU_37_DIESEL :UU '37' (dieselová)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (dieselová)
+STR_8010_CS_4000_DIESEL :CS 4000 (dieselová)
+STR_8011_CS_2400_DIESEL :CS 2400 (dieselová)
+STR_8012_CENTENNIAL_DIESEL :Centennial (dieselová)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (dieselová)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (dieselová)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (dieselová)
+STR_8016_SH_125_DIESEL :SH '125' (dieselová)
+STR_8017_SH_30_ELECTRIC :SH '30' (elektrická)
+STR_8018_SH_40_ELECTRIC :SH '40' (elektrická)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (elektrická)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (elektrická)
+STR_801B_PASSENGER_CAR :Osobní vagon pro cestující
+STR_801C_MAIL_VAN :Poštovní vagon
+STR_801D_COAL_CAR :Vagon na uhlí
+STR_801E_OIL_TANKER :Cisternový vagon na ropu
+STR_801F_LIVESTOCK_VAN :Vagon pro dobytek
+STR_8020_GOODS_VAN :Vagon na zboží
+STR_8021_GRAIN_HOPPER :Vagon na zrní
+STR_8022_WOOD_TRUCK :Vagon na dřevo
+STR_8023_IRON_ORE_HOPPER :Vagon na železnou rudu
+STR_8024_STEEL_TRUCK :Vagon na ocel
+STR_8025_ARMORED_VAN :Vagon na ceniny
+STR_8026_FOOD_VAN :Vagon na jídlo
+STR_8027_PAPER_TRUCK :Vagon na papír
+STR_8028_COPPER_ORE_HOPPER :Vagon na měděnou rudu
+STR_8029_WATER_TANKER :Cisternový vagon na vodu
+STR_802A_FRUIT_TRUCK :Vagon na ovoce
+STR_802B_RUBBER_TRUCK :Vagon na kauÄuk
+STR_802C_SUGAR_TRUCK :Vagon na cukr
+STR_802D_COTTON_CANDY_HOPPER :Vagon na cukrovou vatu
+STR_802E_TOFFEE_HOPPER :Vagon na karamel
+STR_802F_BUBBLE_VAN :Vagon na bubliny
+STR_8030_COLA_TANKER :Cisternový vagon na kolu
+STR_8031_CANDY_VAN :Vagon na bonbony
+STR_8032_TOY_VAN :Vagon na hraÄky
+STR_8033_BATTERY_TRUCK :Vagon na baterie
+STR_8034_FIZZY_DRINK_TRUCK :Vagon na limonády
+STR_8035_PLASTIC_TRUCK :Vagon na plast
+STR_8036_X2001_ELECTRIC :'X2001' (elektrická)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (elektrická)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :Osobní vagon pro cestující
+STR_803A_MAIL_VAN :Poštovní vagon
+STR_803B_COAL_CAR :Vagon na uhlí
+STR_803C_OIL_TANKER :Cisternový vagon na ropu
+STR_803D_LIVESTOCK_VAN :Vagon pro dobytek
+STR_803E_GOODS_VAN :Vagon na zboží
+STR_803F_GRAIN_HOPPER :Vagon na zrní
+STR_8040_WOOD_TRUCK :Vagon na dřevo
+STR_8041_IRON_ORE_HOPPER :Vagon na železnou rudu
+STR_8042_STEEL_TRUCK :Vagon na ocel
+STR_8043_ARMORED_VAN :Vagon na ceniny
+STR_8044_FOOD_VAN :Vagon na jídlo
+STR_8045_PAPER_TRUCK :Vagon na papír
+STR_8046_COPPER_ORE_HOPPER :Vagon na měděnou rudu
+STR_8047_WATER_TANKER :Cisternový vagon na vodu
+STR_8048_FRUIT_TRUCK :Vagon na ovoce
+STR_8049_RUBBER_TRUCK :Vagon na kauÄuk
+STR_804A_SUGAR_TRUCK :Vagon na cukr
+STR_804B_COTTON_CANDY_HOPPER :Vagon na cukrovou vatu
+STR_804C_TOFFEE_HOPPER :Vagon na karamel
+STR_804D_BUBBLE_VAN :Vagon na bubliny
+STR_804E_COLA_TANKER :Cisternový vagon na kolu
+STR_804F_CANDY_VAN :Vagon na bonbony
+STR_8050_TOY_VAN :Vagon na hraÄky
+STR_8051_BATTERY_TRUCK :Vagon na baterie
+STR_8052_FIZZY_DRINK_TRUCK :Vagon na limonády
+STR_8053_PLASTIC_TRUCK :Vagon na plast
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (elektrická)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (elektrická)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (elektrická)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (elektrická)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :Osobní vagon pro cestující
+STR_805A_MAIL_VAN :Poštovní vagon
+STR_805B_COAL_CAR :Vagon na uhlí
+STR_805C_OIL_TANKER :Cisternový vagon na ropu
+STR_805D_LIVESTOCK_VAN :Vagon pro dobytek
+STR_805E_GOODS_VAN :Vagon na zboží
+STR_805F_GRAIN_HOPPER :Vagon na zrní
+STR_8060_WOOD_TRUCK :Vagon na dřevo
+STR_8061_IRON_ORE_HOPPER :Vagon na železnou rudu
+STR_8062_STEEL_TRUCK :Vagon na ocel
+STR_8063_ARMORED_VAN :Vagon na ceniny
+STR_8064_FOOD_VAN :Vagon na jídlo
+STR_8065_PAPER_TRUCK :Vagon na papír
+STR_8066_COPPER_ORE_HOPPER :Vagon na měděnou rudu
+STR_8067_WATER_TANKER :Cisternový vagon na vodu
+STR_8068_FRUIT_TRUCK :Vagon na ovoce
+STR_8069_RUBBER_TRUCK :Vagon na kauÄuk
+STR_806A_SUGAR_TRUCK :Vagon na cukr
+STR_806B_COTTON_CANDY_HOPPER :Vagon na cukrovou vatu
+STR_806C_TOFFEE_HOPPER :Vagon na karamel
+STR_806D_BUBBLE_VAN :Vagon na bubliny
+STR_806E_COLA_TANKER :Cisternový vagon na kolu
+STR_806F_CANDY_VAN :Vagon na bonbony
+STR_8070_TOY_VAN :Vagon na hraÄky
+STR_8071_BATTERY_TRUCK :Vagon na baterie
+STR_8072_FIZZY_DRINK_TRUCK :Vagon na limonády
+STR_8073_PLASTIC_TRUCK :Vagon na plast
+STR_8074_MPS_REGAL_BUS :MPS Regal Bus
+STR_8075_HEREFORD_LEOPARD_BUS :Hereford Leopard Bus
+STR_8076_FOSTER_BUS :Foster Bus
+STR_8077_FOSTER_MKII_SUPERBUS :Foster MkII Superbus
+STR_8078_PLODDYPHUT_MKI_BUS :Ploddyphut MkI Bus
+STR_8079_PLODDYPHUT_MKII_BUS :Ploddyphut MkII Bus
+STR_807A_PLODDYPHUT_MKIII_BUS :Ploddyphut MkIII Bus
+STR_807B_BALOGH_COAL_TRUCK :Balogh vůz na uhlí
+STR_807C_UHL_COAL_TRUCK :Uhl vůz na uhlí
+STR_807D_DW_COAL_TRUCK :DW vůz na uhlí
+STR_807E_MPS_MAIL_TRUCK :MPS poštovní vůz
+STR_807F_REYNARD_MAIL_TRUCK :Reynard poštovní vůz
+STR_8080_PERRY_MAIL_TRUCK :Perry poštovní vůz
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :MightyMover poštovní vůz
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Powernaught poštovní vůz
+STR_8083_WIZZOWOW_MAIL_TRUCK :Wizzowow poštovní vůz
+STR_8084_WITCOMBE_OIL_TANKER :Witcombe cisterna na ropu
+STR_8085_FOSTER_OIL_TANKER :Foster cisterna na ropu
+STR_8086_PERRY_OIL_TANKER :Perry cisterna na ropu
+STR_8087_TALBOTT_LIVESTOCK_VAN :Talbott vůz na dobytek
+STR_8088_UHL_LIVESTOCK_VAN :Uhl vůz na dobytek
+STR_8089_FOSTER_LIVESTOCK_VAN :Foster vůz na dobytek
+STR_808A_BALOGH_GOODS_TRUCK :Balogh vůz na zboží
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Craighead vůz na zboží
+STR_808C_GOSS_GOODS_TRUCK :Goss vůz na zboží
+STR_808D_HEREFORD_GRAIN_TRUCK :Hereford vůz na zrní
+STR_808E_THOMAS_GRAIN_TRUCK :Thomas vůz na zrní
+STR_808F_GOSS_GRAIN_TRUCK :Goss vůz na zrní
+STR_8090_WITCOMBE_WOOD_TRUCK :Witcombe vůz na dřevo
+STR_8091_FOSTER_WOOD_TRUCK :Foster vůz na dřevo
+STR_8092_MORELAND_WOOD_TRUCK :Moreland vůz na dřevo
+STR_8093_MPS_IRON_ORE_TRUCK :MPS vůz na železnou rudu
+STR_8094_UHL_IRON_ORE_TRUCK :Uhl vůz na železnou rudu
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Chippy vůz na železnou rudu
+STR_8096_BALOGH_STEEL_TRUCK :Balogh vůz na ocel
+STR_8097_UHL_STEEL_TRUCK :Uhl vůz na ocel
+STR_8098_KELLING_STEEL_TRUCK :Kelling vůz na ocel
+STR_8099_BALOGH_ARMORED_TRUCK :Balogh obrněný vůz
+STR_809A_UHL_ARMORED_TRUCK :Uhl obrněný vůz
+STR_809B_FOSTER_ARMORED_TRUCK :Foster obrněný vůz
+STR_809C_FOSTER_FOOD_VAN :Foster vůz na jídlo
+STR_809D_PERRY_FOOD_VAN :Perry vůz na jídlo
+STR_809E_CHIPPY_FOOD_VAN :Chippy vůz na jídlo
+STR_809F_UHL_PAPER_TRUCK :Uhl vůz na papír
+STR_80A0_BALOGH_PAPER_TRUCK :Balogh vůz na papír
+STR_80A1_MPS_PAPER_TRUCK :MPS vůz na papír
+STR_80A2_MPS_COPPER_ORE_TRUCK :MPS vůz na měděnou rudu
+STR_80A3_UHL_COPPER_ORE_TRUCK :Uhl vůz na měděnou rudu
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Goss vůz na měděnou rudu
+STR_80A5_UHL_WATER_TANKER :Uhl cisterna na vodu
+STR_80A6_BALOGH_WATER_TANKER :Balogh cisterna na vodu
+STR_80A7_MPS_WATER_TANKER :MPS cisterna na vodu
+STR_80A8_BALOGH_FRUIT_TRUCK :Balogh vůz na ovoce
+STR_80A9_UHL_FRUIT_TRUCK :Uhl vůz na ovoce
+STR_80AA_KELLING_FRUIT_TRUCK :Kelling vůz na ovoce
+STR_80AB_BALOGH_RUBBER_TRUCK :Balogh vůz na kauÄuk
+STR_80AC_UHL_RUBBER_TRUCK :Uhl vůz na kauÄuk
+STR_80AD_RMT_RUBBER_TRUCK :RMT vůz na kauÄuk
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :MightyMover vůz na cukr
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Powernaught vůz na cukr
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Wizzowow vůz na cukr
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :MightyMover cisterna na kolu
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Powernaught cisterna na kolu
+STR_80B3_WIZZOWOW_COLA_TRUCK :Wizzowow cisterna na kolu
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :MightyMover vůz na cukrovou vatu
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Powernaught vůz na cukrovou vatu
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Wizzowow vůz na cukrovou vatu
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :MightyMover vůz na karamel
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Powernaught vůz na karamel
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Wizzowow vůz na karamel
+STR_80BA_MIGHTYMOVER_TOY_VAN :MightyMover vůz na hraÄky
+STR_80BB_POWERNAUGHT_TOY_VAN :Powernaught vůz na hraÄky
+STR_80BC_WIZZOWOW_TOY_VAN :Wizzowow vůz na hraÄky
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :MightyMover vůz na bonbony
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Powernaught vůz na bonbony
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Wizzowow vůz na bonbony
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :MightyMover vůz na baterie
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Powernaught vůz na baterie
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Wizzowow vůz na baterie
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :MightyMover vůz na limonády
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Powernaught vůz na limonády
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Wizzowow vůz na limonády
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :MightyMover vůz na plast
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Powernaught vůz na plast
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Wizzowow vůz na plast
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :MightyMover vůz na bubliny
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Powernaught vůz na bubliny
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Wizzowow vůz na bubliny
+STR_80CC_MPS_OIL_TANKER :MPS ropný tanker
+STR_80CD_CS_INC_OIL_TANKER :CS-Inc. ropný tanker
+STR_80CE_MPS_PASSENGER_FERRY :MPS trajekt pro cestující
+STR_80CF_FFP_PASSENGER_FERRY :FFP trajekt pro cestující
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Bakewell 300 vznášedlo
+STR_80D1_CHUGGER_CHUG_PASSENGER :Chugger-Chug trajekt pro cestující
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Shivershake trajekt pro cestující
+STR_80D3_YATE_CARGO_SHIP :Yate nákladní loÄ
+STR_80D4_BAKEWELL_CARGO_SHIP :Bakewell nákladní loÄ
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Mightymover nákladní loÄ
+STR_80D6_POWERNAUT_CARGO_SHIP :Powernaut nákladní loÄ
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Vrtulník Tricairo
+STR_80FE_GURU_X2_HELICOPTER :Vrtulník Guru X2
+STR_80FF_POWERNAUT_HELICOPTER :Vrtulník Powernaut
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Zpráva od výrobce dopravních prostředků
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}PrávÄ› jsme vyvinuli nový dopravní prostÅ™edek - {STRING}. MÄ›l byste zájem o roÄní výhradní právo na používání tohoto prostÅ™edku, aby byl otestován pÅ™ed uvedením na trh?
+STR_8102_RAILROAD_LOCOMOTIVE :lokomotivu
+STR_8103_ROAD_VEHICLE :silniÄní vozidlo
+STR_8104_AIRCRAFT :letadlo
+STR_8105_SHIP :loÄ
+STR_8106_MONORAIL_LOCOMOTIVE :lokomotivu pro monorail
+STR_8107_MAGLEV_LOCOMOTIVE :lokomotivu Maglev
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}ŽelezniÄní depo {TOWN}
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Obyvatelé oslavují...{}První vlak dorazil do {STATION}!
+STR_8802_DETAILS :{WHITE}{STRING} (Detaily)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}V cestÄ› je vlak
+STR_8804 :{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8806_GO_TO :Jet do {STATION}
+STR_8807_GO_TO_TRANSFER :Jet do {STATION} (přeložit a naložit jiný náklad)
+STR_8808_GO_TO_UNLOAD :Jet do {STATION} (vyložit)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Jet do {STATION} (přeložit a nenakládat)
+STR_880A_GO_TO_LOAD :Jet do {STATION} (naložit)
+STR_880B_GO_TO_TRANSFER_LOAD :Jet do {STATION} (přeložit a plně naložit jiný náklad)
+STR_880C_GO_NON_STOP_TO :Jet bez zastavení do {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Jet bez zastavení do {STATION} (přeložit a naložit jiný náklad)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Jet bez zastavení do {STATION} (vyložit)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Jet bez zastavení do {STATION} (přeložit a nenakládat)
+STR_8810_GO_NON_STOP_TO_LOAD :Jet bez zastavení do {STATION} (naložit)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Jet bez zastavení do {STATION} (přeložit a plně naložit jiný náklad)
+STR_GO_TO_TRAIN_DEPOT :Jet do železniÄního depa v {TOWN}
+STR_SERVICE_AT_TRAIN_DEPOT :Údržba v železniÄním depu {TOWN}
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Jet bez zastavení do železniÄního depa {TOWN}
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Údržba bez zastavení v železniÄním depu {TOWN}
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}Jedu do železniÄního depa {TOWN}
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}Jedu do železniÄního depa {TOWN}, {VELOCITY}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE :{LTBLUE}Údržba v železniÄním depu {TOWN}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE_VEL :{LTBLUE}Údržba v železniÄním depu {TOWN}, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (neplatný příkaz)
+
+STR_UNKNOWN_DESTINATION :neznámý cíl
+STR_8812_EMPTY :{LTBLUE}Prázdný
+STR_8813_FROM :{LTBLUE}{CARGO} z {STATION}
+STR_FROM_MULT :{LTBLUE}{CARGO} z {STATION} (x{NUM})
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}Vlak {COMMA} Äeká v depu
+STR_8815_NEW_VEHICLES :{BLACK}Nová vozidla
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Příliš dlouhý vlak
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Vlaky lze měnit, jen když stojí v depu
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} vlak{P "" y ů}
+
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Nové lokomotivy a vagony
+STR_NEW_ELRAIL_VEHICLES :{WHITE}Nové elektrické lokomotivy a vagony
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Nové lokomotivy a vagony pro monorail
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Nové lokomotivy a vagony Maglev
+STR_ALL_AVAIL_RAIL_VEHICLES :{WHITE}ŽelezniÄní vozidla
+
+STR_881F_BUILD_VEHICLE :{BLACK}Koupit vůz
+STR_CLONE_ROAD_VEHICLE :{BLACK}Klonovat vozidlo
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}Vytvoří se kopie silniÄního vozidla. Se stisknutým Ctrl se budou sdílet příkazy.
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Vytvoří se kopie silniÄního vozidla. Klepni na toto tlaÄítko a pak na vozidlo v nebo vnÄ› depa. Se stisknutým Ctrl se budou sdílet příkazy.
+STR_CLONE_TRAIN :{BLACK}Klonovat vlak
+STR_CLONE_TRAIN_INFO :{BLACK}Vytvoří se kopie vlaku se všemi vagony. Se stisknutým Ctrl se budou sdílet příkazy.
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}Vytvoří se kopie vlaku se vÅ¡emi vagony. Klepni na toto tlaÄítko a pak na vlak v nebo vnÄ› depa. Se stisknutým Ctrl se budou sdílet příkazy.
+STR_8820_RENAME :{BLACK}Přejmenovat
+STR_8823_SKIP :{BLACK}PÅ™eskoÄit
+STR_8824_DELETE :{BLACK}Smazat
+STR_8825_NON_STOP :{BLACK}Nonstop
+STR_8826_GO_TO :{BLACK}Jet do
+STR_8827_FULL_LOAD :{BLACK}Naložit
+STR_8828_UNLOAD :{BLACK}Vyložit
+STR_REFIT :{BLACK}Přestavět
+STR_REFIT_TIP :{BLACK}Vyber, na který druh nákladu přestavět. CTRL-klik odstraní přestavbu z příkazu.
+STR_REFIT_ORDER :(Přestavět na {STRING})
+STR_8829_ORDERS :{WHITE}{VEHICLE} (Příkazy)
+STR_882A_END_OF_ORDERS :{SETX 10}- - Konec příkazů - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}Údržba
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Nemohu koupit vagon nebo lokomotivu...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Koupeno: {LTBLUE}{NUM}{BLACK} Hodnota: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Hodnota: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}Nakládání / vykládání
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}Vlak musí stát v depu
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Nelze poslat vlak do depa...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Nedostatek prostoru na příkazy
+STR_8832_TOO_MANY_ORDERS :{WHITE}Příliš mnoho příkazů
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Nemohu přidat nový příkaz
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Nemohu tento příkaz smazat...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Nemohu tento příkaz změnit...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Nemohu přesunout vozidlo...
+STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}Zadní stroj vždy doprovází svůj protějšek vepředu
+STR_8838_N_A :N/A{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Nemohu prodat vagon nebo lokomotivu...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Nemohu najít cestu do místního depa...
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Nemohu rozjet/zastavit vlak...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Interval servisů: {LTBLUE}{COMMA} d{P en ny ní}{BLACK} Naposledy v servisu: {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Interval servisů: {LTBLUE}{COMMA}%{BLACK} Naposledy v servisu: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Vlaky - klepni na vlak pro informace
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Kupovat nové vlaky (vyžaduje železniÄní depo)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Vlaky - stiskni na vlaku pro info, pÅ™esuň vagon pro pÅ™idání Äi odebrání z vlaku
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Koupit nový vagon/lokomotivu
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Přesuň sem vagon pro prodej
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Nastav pohled na vlakové depo
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Seznam vlaků - stiskni na vlaku pro informace
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Kup oznaÄený vagon/lokomotivu
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Přejmenovat typ vlaku
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Momentální akce vlaku - stiskni pro zastavení/rozjetí vlaku
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Ukaž příkazy vlaku
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Nastav pohled na vlak
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Pošli vlak do depa
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}DonuÅ¥ vlak prokraÄovat bez Äekání na povolení od semaforu
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}OtoÄit vlak
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Ukázat detaily vlaku
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Prodloužit interval servisů
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Zkrátit interval servisů
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Ukázat detaily přepravovaného zboží
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Ukázat detaily jednotlivých vagonů
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Ukázat kapacity jednotlivých vagonů
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Ukázat celkovou kapacitu vlaku, rozdělenou dle nákladu
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Seznam příkazů - stiskni příkaz pro oznaÄení. Kliknutím na příkaz se stisknutým CTRL se nastaví pohled na stanici
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}PÅ™eskoÄit příkaz a jít na další
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Smazat oznaÄený příkaz
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Provést oznaÄený příkaz bez zastavení
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Vložit nový příkaz pÅ™ed oznaÄený příkaz nebo na konec seznamu
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}OznaÄený příkaz provádÄ›t do plného naložení
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}OznaÄený příkaz vyloží vozidlo
+STR_SERVICE_HINT :{BLACK}PÅ™eskoÄ tento cíl, pokud není potÅ™eba pravidelná údržba
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}Další {STRING} je k dispozici!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Cena: {CURRENCY} Hmotnost: {WEIGHT_S}{}Rychlost: {VELOCITY} Výkon: {POWER}{}Cena provozu: {CURRENCY} roÄnÄ›{}Kapacita: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}Porucha
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}Stáří: {LTBLUE}{STRING}{BLACK} Cena provozu: {LTBLUE}{CURRENCY} roÄnÄ›
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Hmotnost: {LTBLUE}{WEIGHT_S} {BLACK}Výkon: {LTBLUE}{POWER}{BLACK} Max. rychlost: {LTBLUE}{VELOCITY}
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Hmotnost: {LTBLUE}{WEIGHT_S} {BLACK}Výkon: {LTBLUE}{POWER}{BLACK} Max. rychlost: {LTBLUE}{VELOCITY} {BLACK}Max. tažná síla: {LTBLUE}{FORCE}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Příjem tento rok: {LTBLUE}{CURRENCY} (minulý rok: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}Spolehlivost: {LTBLUE}{COMMA}% {BLACK}Poruch od posledního servisu: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Zastaveno
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Nemohu vlak nechat projet semafory v nebezpeÄí...
+STR_8863_CRASHED :{RED}Nehoda!
+
+STR_8865_NAME_TRAIN :{WHITE}Pojmenovat vlak
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}Nelze pojmenovat vlak...
+STR_8867_NAME_TRAIN :{BLACK}Pojmenovat vlak
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}ŽelezniÄní neÅ¡tÄ›stí!{}PÅ™i srážce {COMMA} {P ÄlovÄ›k lidé lidí} pÅ™iÅ¡{P el li lo} o život v plamenech.
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Nelze obrátit vlak...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}PÅ™ejmenovat typ železniÄního vozidla
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Nemohu pÅ™ejmenovat typ železniÄního vozidla...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}U oznaÄeného příkazu vozidlo musí vyložit náklad
+STR_886F_TRANSFER :{BLACK}Překládka
+
+STR_TRAIN_STOPPING :{RED}Zastavuje
+STR_TRAIN_STOPPING_VEL :{RED}Zastavuje, {VELOCITY}
+STR_INCOMPATIBLE_RAIL_TYPES :NesluÄitelné druhy kolejí
+STR_TRAIN_NO_POWER :{RED}Bez proudu
+STR_TRAIN_START_NO_CATENARY :Tato trať není elektrifikována, vlak nemůže odjet
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}SilniÄní vozidlo v cestÄ›
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} silniÄní{P "" "" ch} vozid{P lo la el}
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}Garáže pro silniÄní vozidla {TOWN}
+STR_9004_NEW_VEHICLES :{BLACK}Nová silniÄní vozidla
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}Nová silniÄní vozidla
+STR_9007_BUILD_VEHICLE :{BLACK}Koupit silniÄní vozidlo
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Nemohu koupit nové silniÄní vozidlo...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (Detaily)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}Stáří: {LTBLUE}{STRING}{BLACK} Cena provozu: {LTBLUE}{CURRENCY} roÄnÄ›
+STR_900E_MAX_SPEED :{BLACK}Max. rychlost: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Příjem tento rok: {LTBLUE}{CURRENCY} (minulý rok): {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}Spolehlivost: {LTBLUE}{COMMA}% {BLACK}Poruch od posledního servisu: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Koupen: {LTBLUE}{NUM}{BLACK} Cena: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Kapacita: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}... musí být zastaven v garáži
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Nemohu prodat silniÄní vozidlo...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Nemohu zastavit/rozjet silniÄní vozidlo...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}SilniÄní vozidlo {COMMA} Äeká v garáži
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}Mířím do garáže {TOWN}
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}Mířím do garáže {TOWN}, {VELOCITY}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE :{LTBLUE}Údržba v silniÄním depu {TOWN}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE_VEL :{LTBLUE}Údržba v silniÄním depu {TOWN}, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Nemohu poslat silniÄní vozidlo do garáže...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Nemohu najít místní garáž
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}SilniÄní vozidla - stiskni vozidlo pro informace
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Koupit nová silniÄní vozidla (vyžaduje garáže)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Momentální Äinnost silniÄního vozidla - stiskni pro zastavení/rozjetí vozidla
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Ukaž příkazy vozidla
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Nastav pohled na vozidlo
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Pošli vozidlo do garáže
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}OtoÄ vozidlo
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Ukaž detaily silniÄního vozidla
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Vozidla - stiskni vozidlo pro informace
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Koupit nové silniÄní vozidlo
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}PÅ™esuň sem silniÄní vozidlo k prodeji
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Nastav pohled na garáž
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Seznam silniÄních vozidel - klepni na vozidlo pro informace
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Koupit oznaÄené vozidlo
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}Nové silniÄní vozidlo je k dispozici!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Cena: {CURRENCY}{}Rychlost: {VELOCITY}{}Cena provozu: {CURRENCY} roÄnÄ›{}Kapacita: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}PÅ™ejmenovat silniÄní vozidlo
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Nelze pÅ™ejmenovat silniÄní vozidlo...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}PÅ™ejmenovat silniÄní vozidlo
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Obyvatelé oslavují...{}První autobus přijel do {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Obyvatelé oslavují...{}První nákladní vozidlo přijelo do {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}Dopravní nehoda!{}ŘidiÄ zahynul v plamenech pÅ™i srážce s vlakem
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}Dopravní nehoda!{}{COMMA} {P ÄlovÄ›k lidé lidí} zahynul{P "" i o} v plamenech pÅ™i srážce s vlakem
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Nelze otoÄit vozidlo...
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}Nelze otáÄet vozidla složená z více strojů
+STR_9034_RENAME :{BLACK}Přejmenovat
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}PÅ™ejmenovat typ silniÄního vozidla
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}PÅ™ejmenovat typ silniÄního vozidla
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Nelze pÅ™ejmenovat typ silniÄního vozidla...
+STR_9038_GO_TO_ROADVEH_DEPOT :Jet do garáže {TOWN}
+STR_SERVICE_AT_ROADVEH_DEPOT :Údržba v garáži {TOWN}
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}PÅ™estavÄ›t silniÄní vozidlo, aby mohlo vozit jiný druh nákladu
+STR_REFIT_ROAD_VEHICLE :{BLACK}PÅ™estavÄ›t silniÄní vozidlo
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}PÅ™estavÄ›t silniÄní vozidlo, aby vozilo vybraný druh nákladu
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Nelze pÅ™estavet silniÄní vozidlo...
+STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Vyber typ nákladu, který má vozidlo převážet
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Stavba přístavu
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Stavba přístavu
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Zde nelze postavit přístav...
+STR_9803_SHIP_DEPOT :{WHITE}Lodní depo {TOWN}
+STR_9804_NEW_SHIPS :{BLACK}Nové lodě
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} lo{P Ä dÄ› dí}
+STR_9808_NEW_SHIPS :{WHITE}Nové lodě
+STR_9809_BUILD_SHIP :{BLACK}Koupit loÄ
+STR_CLONE_SHIP :{BLACK}Klonovat loÄ
+STR_CLONE_SHIP_INFO :{BLACK}Vytvoří se kopie lodě. Se stisknutým Ctrl se budou sdílet příkazy.
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}Vytvoří se kopie lodÄ›. Klepni na toto tlaÄítko a pak na loÄ v nebo vnÄ› lodního depa. Se stisknutým Ctrl se budou sdílet příkazy.
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}LoÄ musí být zastavena v depu
+STR_980C_CAN_T_SELL_SHIP :{WHITE}Nelze prodat loÄ...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Nelze koupit loÄ...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}LoÄ v cestÄ›
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Detaily)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}Stáří: {LTBLUE}{STRING}{BLACK} Cena provozu: {LTBLUE}{CURRENCY} roÄnÄ›
+STR_9813_MAX_SPEED :{BLACK}Max. rychlost: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Příjem tento rok: {LTBLUE}{CURRENCY} (minulý rok: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}Spolehlivost: {LTBLUE}{COMMA}% {BLACK}Poruch od posledního servisu: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Koupeno: {LTBLUE}{NUM}{BLACK} Cena: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}Kapacita: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}Nelze rozjet/zastavit loÄ...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Nelze poslat loÄ do depa...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Nemohu najít místní depo
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}Jedu do depa {TOWN}
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}Mířím do depa {TOWN}, {VELOCITY}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE :{LTBLUE}Údržba v lodním depu {TOWN}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE_VEL :{LTBLUE}Údržba v lodním depu {TOWN}, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}LoÄ {COMMA} Äeká v depu
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Postavit přístavní molo
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Postavit lodní depo (na nákup a servis lodí)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Lodě - informace získáš klepnutím na jméno lodi
+STR_9820_BUILD_NEW_SHIP :{BLACK}Koupit novou loÄ
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Zde se dá loÄ prodat (pÅ™etáhnutím)
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Nastavit pohled na lodní depo
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Lodě - informace získáš klepnutím na jméno lodi
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Koupit nové lodě (vyžaduje lodní depo)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}Seznam lodí - informace získáš klepnutím na jméno lodi
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Koupit oznaÄenou loÄ
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Činnost lodi - na rozjetí nebo zastavení lodi klepni sem
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Ukázat příkazy lodi
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Nastavit pohled na loÄ
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Poslat loÄ do doku
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Ukázat detaily lodi
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}Nová loÄ je k dispozici!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Cena: {CURRENCY} Max. rychlost: {VELOCITY}{}Kapacita: {CARGO}{}Cena provozu: {CURRENCY} roÄnÄ›
+STR_982F_NAME_SHIP :{BLACK}PÅ™ejmenovat loÄ
+
+STR_9831_NAME_SHIP :{WHITE}PÅ™ejemnovat loÄ
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Nelze pÅ™ejmenovat loÄ...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Obyvatelé oslavují...{}První loÄ pÅ™istála v {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Umístit bójku, kterou lze použít jako navigaÄní bod
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Zde nelze umístit bójku...
+STR_9836_RENAME :{BLACK}Přejmenovat
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Přejmenovat typ lodi
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Přejmenovat typ lodi
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Nelze přejmenovat typ lodi...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Přestavět pro převážení jiného druhu nákladu
+STR_983B_REFIT :{WHITE}{VEHICLE} (Přestavět)
+STR_983C_REFIT_SHIP :{BLACK}Přestavět
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Zvolit druh nákladu, který bude loÄ pÅ™evážet
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}PÅ™estavÄ›t pro pÅ™evoz oznaÄeného nákladu
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Zvolit druh nákladu:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nová kapacita: {GOLD}{CARGO}{}{BLACK}Cena přestavby: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Nelze pÅ™estavÄ›t loÄ...
+STR_9842_REFITTABLE :(lze přestavět)
+STR_GO_TO_SHIP_DEPOT :Zajet do lodního depa {TOWN}
+SERVICE_AT_SHIP_DEPOT :Údržba v lodním depu {TOWN}
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Letiště
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Zde nelze postavit letiště...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} Letištní hangár
+STR_A003_NEW_AIRCRAFT :{BLACK}Nová letadla
+STR_CLONE_AIRCRAFT :{BLACK}Klonovat letadlo
+STR_CLONE_AIRCRAFT_INFO :{BLACK}Vytvoří se kopie letadla. Se stisknutým Ctrl se budou sdílet příkazy.
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Vytvoří se kopie letadla. Klepni na toto tlaÄítko a pak na letadlo v nebo vnÄ› hangáru. Se stisknutým Ctrl se budou sdílet příkazy.
+STR_A005_NEW_AIRCRAFT :{WHITE}Nové letadlo
+STR_A006_BUILD_AIRCRAFT :{BLACK}Koupit letadlo
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Nelze koupit letadlo...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} letad{P lo la el}
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (Příkazy)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (Detaily)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Stáří: {LTBLUE}{STRING}{BLACK} Cena provozu: {LTBLUE}{CURRENCY} roÄnÄ›
+STR_A00E_MAX_SPEED :{BLACK}Max. rychlost: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Příjem tento rok: {LTBLUE}{CURRENCY} (minulý rok: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}Spolehlivost: {LTBLUE}{COMMA}% {BLACK}Poruch od posledního servisu: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Koupeno: {LTBLUE}{NUM}{BLACK} Cena: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Nelze poslat letadlo do hangáru...
+STR_HEADING_FOR_HANGAR :{ORANGE}Jedu do hangáru {STATION}
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}Jedu do hangáru {STATION}, {VELOCITY}
+STR_HEADING_FOR_HANGAR_SERVICE :{LTBLUE}Údržba v hangáru {STATION}
+STR_HEADING_FOR_HANGAR_SERVICE_VEL :{LTBLUE}Údržba v hangáru {STATION}, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}Letadlo {COMMA} Äeká v hangáru
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Letadlo v cestÄ›
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Nemohu rozjet/zastavit letadlo...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Letadlo letí
+STR_A019_CAPACITY :{BLACK}Kapacita: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Kapacita: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}Letadlo musí být zastaveno v hangáru
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Nelze prodat letadlo...
+STR_A01D_AIRPORT_CONSTRUCTION :Stavba letiště
+STR_A01E_BUILD_AIRPORT :{BLACK}Postavit letiště
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Letadlo - klepni na letadlo pro informace
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Koupit nové letadlo (je potřeba letiště)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Letadlo - klepni na letadlo pro informace
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Koupit nové letadlo
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}Přesuň sem letadlo k prodeji
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Nastavit pohled na hangár
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Seznam letadel - klepni na letadlo pro informace
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Koupit oznaÄené letadlo
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Činnost letadla - stiskni pro rozjetí/zastavení letadla
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Ukázat příkazy letadla
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Nastavit pohled na letadlo
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Poslat letadlo do hangáru
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Ukázat detaily letadla
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}Nové letadlo je k dispozici!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Cena: {CURRENCY} Max. rychlost: {VELOCITY}{}Kapacita: {COMMA} cestující{P "" "" ch}, {COMMA} balík{P "" y ů} poÅ¡ty{}Cena provozu: {CURRENCY} roÄnÄ›
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Přejmenovat letadlo
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Nelze přejmenovat letadlo
+STR_A032_NAME_AIRCRAFT :{BLACK}Přejmenovat letadlo
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Obyvatelé oslavují...{}První letadlo přistálo v {STATION}!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Pád letadla!{}{COMMA} {P ÄlovÄ›k lidé lidí} zahynul{P "" i o} v plamenech v {STATION}.
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Letecká havárie!{}Kvůli vyÄerpání paliva {COMMA} {P ÄlovÄ›k lidé lidí} zemÅ™el{P "" i o} v ohnivém pekle!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Přejmenovat
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Přejmenovat typ letadla
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Přejmenovat typ letadla
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Nelze přejmenovat typ letadla...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Přestavět letadlo pro převážení jiného typu nákladu
+STR_A03C_REFIT :{WHITE}{VEHICLE} (Přestavět)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Přestavět letadlo
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Zvolit typ nákladu pro letadlo
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}PÅ™estavet letadlo pro pÅ™evážení oznaÄeného typu nákladu
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Zvolit typ nákladu pro prevážení:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nová kapacita: {GOLD}{STRING}{}{BLACK}Cena přestavby: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Nelze přestavět letadlo...
+STR_GO_TO_AIRPORT_HANGAR :Poslat do hangáru {STATION}
+SERVICE_AT_AIRPORT_HANGAR :Údržba v hangáru {STATION}
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}Zeppelin se zřítil do {STATION}!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}SilniÄní vozidlo bylo zniÄeno pÅ™i srážce s UFO!
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}Výbuch ropné rafinerie u {TOWN}!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}Za podezÅ™elých okolností byla zniÄena továrna u {TOWN}!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}UFO přistálo poblíž {TOWN}!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}Pokles terénu u uhelného dolu {TOWN} způsobil velké škody!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Záplavy!{}Po straÅ¡livých záplavách je odhadem {COMMA} {P ÄlovÄ›k lidé lidí} pohÅ™eÅ¡ov{P án áni aných} nebo mrt{P ev ví vých}!
+
+STR_BRIBE_FAILED :{WHITE}Tvůj pokus o úplatek byl
+STR_BRIBE_FAILED_2 :{WHITE}odhalen místním vyšetřovatelem.
+STR_BUILD_DATE :{BLACK}Postaveno: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Podrobné hodnocení výkonu
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}PodrobnÄ›
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Vozidla:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Stanice:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Min. hrubý zisk:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Min. příjem:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Max. příjem:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Přepraveno:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Druhů nákladu:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Hotovost:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Dluh:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Celkem:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}PoÄet dopravních prostÅ™edků, tzn. silniÄních vozidel, vlaků, lodí a letadel
+STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}PoÄet souÄástí stanic. Každá souÄást stanice (napr. nádraží, autobusová zastávka, letiÅ¡tÄ›) se zapoÄítává, i když patří jediné stanici
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}Minimální hrubý zisk (= s provoz. náklady) vozidla s nejnižším příjmem (staršího 2 let)
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}ÄŒistý zisk (= bez provoz. nakladu) v nejslabším mÄ›síci za posledních 12 Ätvrtletí
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}ÄŒistý zisk v mÄ›síci s nejvÄ›tším příjmem za posledních 12 Ätvrtletí
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}PoÄet doruÄených jednotek nákladu za poslední rok (4Q)
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}PoÄet doruÄených druhu nákladu za poslední 3 mÄ›síce (1Q)
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}SouÄasná hotovost spoleÄnosti
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}Má spoleÄnost velký dluh?
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Celkový poÄet bodů z 1000 možných
+
+STR_NEWGRF_SETTINGS_BUTTON :{BLACK}Nastavení grafik
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}Nastavení grafických souborů
+STR_NEWGRF_APPLY_CHANGES :{BLACK}Potvrdit změny
+STR_NEWGRF_SET_PARAMETERS :{BLACK}Nastavit parametry
+STR_NEWGRF_TIP :{BLACK}Tady je seznam všech nainstalovaných grafických setů. Nastavení změníš kliknutím na set.
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}Žádné soubory s grafikou nejsou nainstalovány! Pro instrukce, jak nainstalovat grafické soubory, se podívej do manuálu.
+STR_NEWGRF_FILENAME :{BLACK}Jméno souboru: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}ID GRF: {SILVER}{STRING}
+STR_NEWGRF_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING}
+STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}Právě se chystáš změnit nastavení grafik za běžící hry; může to shodit OpenTTD.{}Jsi si s tím opravdu jist/a?
+
+STR_NEWGRF_ADD :{BLACK}Přidat
+STR_NEWGRF_ADD_TIP :{BLACK}Přidat NewGRF soubor do seznamu
+STR_NEWGRF_REMOVE :{BLACK}Odebrat
+STR_NEWGRF_REMOVE_TIP :{BLACK}Odstranit oznaÄený NewGRF soubor ze seznamu
+STR_NEWGRF_MOVEUP :{BLACK}Nahoru
+STR_NEWGRF_MOVEUP_TIP :{BLACK}Posunout oznaÄený NewGRF soubor nahoru
+STR_NEWGRF_MOVEDOWN :{BLACK}Dolů
+STR_NEWGRF_MOVEDOWN_TIP :{BLACK}Posunout oznaÄený NewGRF soubor dolů
+STR_NEWGRF_FILE_TIP :{BLACK}Seznam NewGRF souborů, které jsou nainstalovány. Parametry souboru můžeš změnit kliknutím na něj.
+STR_NEWGRF_PARAMETER :{BLACK}Parametry: {SILVER}{STRING}
+STR_NEWGRF_PARAMETER_QUERY :{BLACK}Zadej parametry NewGRF souboru
+STR_NEWGRF_NO_INFO :{BLACK}Není dostupná žádná informace
+
+STR_NEWGRF_ADD_CAPTION :{WHITE}Dostupné NewGRF soubory
+STR_NEWGRF_ADD_FILE :{BLACK}Přidat do výběru
+STR_NEWGRF_ADD_FILE_TIP :{BLACK}Přidat vybraný NewGRF soubor do tvého nastavení
+STR_NEWGRF_RESCAN_FILES :{BLACK}NaÄíst soubory
+STR_NEWGRF_RESCAN_FILES_TIP :{BLACK}Aktualizovat seznam dostupných NewGRF souborů
+STR_NEWGRF_DUPLICATE_GRFID :{WHITE}Nelze přidat soubor: duplicitní GRF ID
+
+STR_NEWGRF_NOT_FOUND :{RED}Nenalezen odpovídající soubor
+STR_NEWGRF_DISABLED :{RED}Vypnuto
+
+STR_CURRENCY_WINDOW :{WHITE}Vlastní měna
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Kurz měny: {ORANGE}{CURRENCY} = £ {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}OddÄ›lovaÄ:
+STR_CURRENCY_PREFIX :{LTBLUE}Předpona:
+STR_CURRENCY_SUFFIX :{LTBLUE}Přípona:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Přechod k euru: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Přechod k euru: {ORANGE}nikdy
+STR_CURRENCY_PREVIEW :{LTBLUE}Náhled: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Změnit parametry vlastní měny
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} vlak{P "" y ů}
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} silniÄní{P "" "" ch} vozid{P lo la el}
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} letad{P lo la el}
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} lo{P Ä dÄ› dí}
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Zobrazit všechny vlaky, které mají tuto stanici v jízdním řádu
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Zobrazit vÅ¡echna silniÄní vozidla, která mají tuto stanici v jízdním řádu
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Zobrazit všechna letadla, která mají tuto stanici v jízdním řádu
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Zobrazit všechny lodě, které mají tuto stanici v jízdním řádu
+
+STR_VEH_WITH_SHARED_ORDERS_LIST :{WHITE}Sdílené příkazy {COMMA} vozid{P lo la el}
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}Zobrazit všechny prostředky se stejným jízdním řádem
+
+### depot strings
+STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Chceš prodat všechna vozidla v depu. Jsi si jistý?
+
+STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP :{BLACK}Prodat všechny vlaky v depu
+STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP :{BLACK}Prodat vÅ¡echna silniÄní vozidla v depu
+STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP :{BLACK}Prodat všechny lodě v depu
+STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP :{BLACK}Prodat všechna letadla a vrtulníky v hangáru
+
+STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP :{BLACK}Ukázat seznam všech vlaků, které mají toto depo v jízdním řádu
+STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP :{BLACK}Ukázat seznam vÅ¡ech silniÄních vozidel, které mají toto depo v jízdním řádu
+STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP :{BLACK}Ukázat seznam všech lodí, které mají toto depo v jízdním řádu
+STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP :{BLACK}Ukázat seznam všech letadel a vrtulníků, které mají jakýkoliv z hangaru na tomto letišti v letovém plánu
+
+STR_DEPOT_AUTOREPLACE_TRAIN_TIP :{BLACK}Nechat automaticky vyměňovat všechny vlaky přítomné v depu
+STR_DEPOT_AUTOREPLACE_ROADVEH_TIP :{BLACK}Nechat automaticky vyměňovat vÅ¡echna silniÄní vozidla přítomné v depu
+STR_DEPOT_AUTOREPLACE_SHIP_TIP :{BLACK}Nechat automaticky vyměňovat všechny lodě přítomné v depu
+STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP :{BLACK}Nechat automaticky vyměňovat všechna letadla a vrtulníky přítomné v hangáru
+
+STR_VEHICLE_LIST_TRAIN_DEPOT :{BLACK}{STRING} - {COMMA} vlak{P "" y ů}
+STR_VEHICLE_LIST_ROADVEH_DEPOT :{BLACK}{STRING} - {COMMA} silniÄní{P "" "" ch} vozid{P lo la el}
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} lo{P Ä dÄ› dí}
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} letad{P lo la el}
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}Vyměňování {STRING}
+STR_REPLACE_VEHICLES_START :{BLACK}Zapnout vyměňování
+STR_REPLACE_VEHICLES_STOP :{BLACK}Vypnout vyměňování
+STR_NOT_REPLACING :{BLACK}(nevyměňuje se)
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Není oznaÄeno žádné vozidlo
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Vyber typ lokomotivy na výměnu
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Vyber typ nové lokomotivy, kterou chceš použít místo vybrané v levém seznamu
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}ZmáÄkni toto tlaÄítko, když nechceÅ¡ vyměňovat typ lokomotivy vybraný v levém seznamu
+STR_REPLACE_HELP_START_BUTTON :{BLACK}ZmáÄkni toto tlaÄítko, když chceÅ¡ vyměňovat typ lokomotivy vybraný v levém seznamu lokomotivou vybranou v pravém seznamu
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Vyber typ kolejí, pro které chceš vybírat lokomotivy na výměnu
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Tady je zobrazeno, za jakou lokomotivu se ta v levém seznamu vyměňuje
+STR_REPLACE_HELP :{BLACK}Tato vlastnost hry ti umožňuje vybrat typ lokomotivy, který nechá vyměnit za jiný. To se bude automaticky provádět, když lokomotiva zajede do depa.
+STR_REPLACE_REMOVE_WAGON :{BLACK}Odebírání vagonů: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Funkce automatického vylepÅ¡ování vlaků může udržovat stejnou délku vlaku odstraňovaním vagonů (od zaÄátku vlaku), pokud by zmÄ›na maÅ¡iny vlak prodloužila.
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}Vyměňování: {ORANGE}{SKIP}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} EXPERIMENTÃLNà VLASTNOST {}PÅ™epne mezi okny na výmÄ›nu lokomotiv a vagonů.{}Vagon se vymÄ›ní, jen když je nový vagon schopen vozit stejnou komoditu, jako ten starý. Toto se ověřuje pro každý vagon.
+STR_ENGINE_NOT_BUILDABLE :{WHITE}Stroj nelze postavit
+
+STR_ENGINES :lokomotivy
+STR_WAGONS :vagony
+
+STR_MASS_STOP_DEPOT_TRAIN_TIP :{BLACK}Stiskni pro zastavení vlaků v depu
+STR_MASS_STOP_DEPOT_ROADVEH_TIP :{BLACK}Stiskni pro zastavení silniÄních vozidel v depu
+STR_MASS_STOP_DEPOT_SHIP_TIP :{BLACK}Stiskni pro zastavení lodí v depu
+STR_MASS_STOP_HANGAR_TIP :{BLACK}Stiskni pro zastavení letadel a vrtulníků v hangáru
+
+STR_MASS_START_DEPOT_TRAIN_TIP :{BLACK}Stiskni pro hromadný odjezd všech vlaků v depu
+STR_MASS_START_DEPOT_ROADVEH_TIP :{BLACK}Stiskni pro hromadný odjezd vÅ¡ech silniÄních vozidel v depu
+STR_MASS_START_DEPOT_SHIP_TIP :{BLACK}Stiskni pro hromadný odjezd všech lodí v depu
+STR_MASS_START_HANGAR_TIP :{BLACK}Stiskni pro hromadný odlet všech letadel a vrtulníků v hangáru
+
+STR_MASS_STOP_LIST_TIP :{BLACK}Kliknutím sem se zastaví všechna vozidla v seznamu
+STR_MASS_START_LIST_TIP :{BLACK}Kliknutím sem se rozjedou všechna vozidla v seznamu
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}Seznam popisků - {COMMA} popis{P ek ky ků}
+
+STR_ORDER_REFIT_FAILED :{WHITE}Přestavba se nezdařila. Konec.{STRING} {COMMA}
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :ŽelezniÄní lokomotivy
+STR_ELRAIL_VEHICLES :Elektrické lokomotivy
+STR_MONORAIL_VEHICLES :Lokomotivy pro monorail
+STR_MAGLEV_VEHICLES :Lokomotivy Maglev
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Cena: {GOLD}{CURRENCY}{BLACK} Hmotnost: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Rychlost: {GOLD}{VELOCITY}{BLACK} Výkon: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}Rychlost: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Provozní cena: {GOLD}{CURRENCY} roÄnÄ›
+STR_PURCHASE_INFO_CAPACITY :{BLACK}Kapacita: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Vyvinuto: {GOLD}{NUM}{BLACK} Životnost: {GOLD}{COMMA} {P rok roky let}
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}Max. spolehlivost: {GOLD}{COMMA} %
+STR_PURCHASE_INFO_COST :{BLACK}Cena: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Hmotnost: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Cena: {GOLD}{CURRENCY}{BLACK} Rychlost: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Kapacita: {GOLD}{COMMA} cestující{P "" "" ch}, {COMMA} bal{P ík íky iků} pošty
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Poháněné vagony: {GOLD}+{POWER}{BLACK} Hmotnost: {GOLD}+{WEIGHT_S}
+STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Refitovatelné na: {GOLD}
+STR_PURCHASE_INFO_ALL_TYPES :Všechny druhy nákladu
+STR_PURCHASE_INFO_ALL_BUT :VÅ¡echny kromÄ› {GOLD}
+STR_PURCHASE_INFO_MAX_TE :{BLACK}Max. tažná síla: {GOLD}{FORCE}
+
+########### String for New Landscape Generator
+
+STR_GENERATE :{WHITE}Vytvořit
+STR_RANDOM :{BLACK}Nové Äíslo
+STR_RANDOM_HELP :{BLACK}VytvoÅ™it nový seed (Äíslo) pro generátor terénu
+STR_WORLD_GENERATION_CAPTION :{WHITE}Tvorba krajiny
+STR_RANDOM_SEED :{BLACK}Náhodné Äíslo:
+STR_RANDOM_SEED_HELP :{BLACK}Zde můžeš zadat seed
+STR_LAND_GENERATOR :{BLACK}Generátor krajiny:
+STR_TREE_PLACER :{BLACK}Sázení stromů:
+STR_HEIGHTMAP_ROTATION :{BLACK}OtoÄení výškové mapy:
+STR_TERRAIN_TYPE :{BLACK}Typ krajiny:
+STR_QUANTITY_OF_SEA_LAKES :{BLACK}ÄŒetnost jezer:
+STR_SMOOTHNESS :{BLACK}ÄŒlenitost krajiny:
+STR_SNOW_LINE_HEIGHT :{BLACK}Výška sněžné Äáry:
+STR_DATE :{BLACK}Datum:
+STR_NUMBER_OF_TOWNS :{BLACK}Množství měst:
+STR_NUMBER_OF_INDUSTRIES :{BLACK}Množství průmyslu:
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_SNOW_LINE_UP :{BLACK}Zvýšit sněžnou Äáru o jednu úroveň
+STR_SNOW_LINE_DOWN :{BLACK}Snížit sněžnou Äáru o jednu úroveň
+STR_SNOW_LINE_QUERY_CAPT :{WHITE}ZmÄ›nit výšku sněžne Äáry
+STR_START_DATE_QUERY_CAPT :{WHITE}ZmÄ›nit poÄáteÄní rok
+STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Varování kvůli velikosti
+STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Tak velká zmena velikosti zdrojové mapy není doporuÄena. PokraÄovat s generováním?
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_HEIGHTMAP_NAME :{BLACK}Jméno výškové mapy:
+STR_HEIGHTMAP_SIZE :{BLACK}Velikost: {ORANGE}{NUM} x {NUM}
+STR_GENERATION_WORLD :{WHITE}Vytvářím krajinu...
+STR_GENERATION_ABORT :{BLACK}Přerušit
+STR_GENERATION_ABORT_CAPTION :{WHITE}Přerušit generování krajiny
+STR_GENERATION_ABORT_MESSAGE :{YELLOW}Opravdu chceš přerušit tento proces?
+STR_PROGRESS :Z {WHITE}{NUM} % hotovo
+STR_GENERATION_PROGRESS :{BLACK}{NUM} / {NUM}
+STR_WORLD_GENERATION :{BLACK}Tvorba krajiny
+STR_TREE_GENERATION :{BLACK}Výsadba stromů
+STR_UNMOVABLE_GENERATION :{BLACK}Výstavba nepřesunutelných objektů
+STR_CLEARING_TILES :{BLACK}Tvorba Älenitého a kamenitého území
+STR_SETTINGUP_GAME :{BLACK}Nastavování hry
+STR_PREPARING_TILELOOP :{BLACK}Spouštění tile-loopu (cyklus na dílcích mapy)
+STR_PREPARING_GAME :{BLACK}Připravování hry
+STR_DIFFICULTY_TO_CUSTOM :{WHITE}Tato akce změnila úroveň obtížnosti na 'vlastní'
+STR_SE_FLAT_WORLD :{WHITE}Plochá krajina
+STR_SE_FLAT_WORLD_TIP :{BLACK}Vytvořit plochou krajinu
+STR_SE_RANDOM_LAND :{WHITE}Náhodná krajina
+STR_SE_NEW_WORLD :{BLACK}Vytvořit nový scénář
+STR_SE_CAPTION :{WHITE}Typ krajiny
+STR_FLAT_WORLD_HEIGHT_DOWN :{BLACK}Snížit výšku ploché země o jednu úroveň
+STR_FLAT_WORLD_HEIGHT_UP :{BLACK}Zvednout výšku ploché země o jednu úroveň
+STR_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Změnit výšku ploché země
+STR_FLAT_WORLD_HEIGHT :{BLACK}Výška ploché zeme:
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+STR_SMALLMAP_CENTER :{BLACK}Vycentrovat malou mapu na tomto místě
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}Malé
+STR_CITY_AIRPORT :{BLACK}Městské
+STR_METRO_AIRPORT :{BLACK}Metropolitní
+STR_INTERNATIONAL_AIRPORT :{BLACK}Mezinárodní
+STR_COMMUTER_AIRPORT :{BLACK}Příměstské
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Mezikontinentální
+STR_HELIPORT :{BLACK}Klasické
+STR_HELIDEPOT :{BLACK}Servisní
+STR_HELISTATION :{BLACK}Stanice
+
+STR_SMALL_AIRPORTS :{BLACK}Malá letiště
+STR_LARGE_AIRPORTS :{BLACK}Velká letiště
+STR_HUB_AIRPORTS :{BLACK}Hlavní letiště
+STR_HELIPORTS :{BLACK}Letiště pro vrtulníky
+
+############ Tooltip measurment
+
+STR_MEASURE_LENGTH :{BLACK}Délka: {NUM}
+STR_MEASURE_AREA :{BLACK}Oblast: {NUM} x {NUM}
+STR_MEASURE_LENGTH_HEIGHTDIFF :{BLACK}Délka: {NUM}{}Výškový rozdíl: {NUM} m
+STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}Oblast: {NUM} x {NUM}{}Výškový rozdíl: {NUM} m
+
+########
diff --git a/src/lang/danish.txt b/src/lang/danish.txt
new file mode 100644
index 000000000..a89be00ae
--- /dev/null
+++ b/src/lang/danish.txt
@@ -0,0 +1,3116 @@
+##name Danish
+##ownname Dansk
+##isocode da_DA.UTF-8
+##plural 0
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Ude over kanten af kortet
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}For tæt på kanten af kortet
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Ikke nok penge - kræver {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Landskabet skal være fladt
+STR_0008_WAITING :{BLACK}Venter: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (på vej fra
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Accepterer: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Accepterer: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :Passagerer
+STR_0010_COAL :Kul
+STR_0011_MAIL :Post
+STR_0012_OIL :Olie
+STR_0013_LIVESTOCK :Kvæg
+STR_0014_GOODS :Stykgods
+STR_0015_GRAIN :Korn
+STR_0016_WOOD :Træ
+STR_0017_IRON_ORE :Jernmalm
+STR_0018_STEEL :Stål
+STR_0019_VALUABLES :Værdigenstande
+STR_001A_COPPER_ORE :Kobbermalm
+STR_001B_MAIZE :Majs
+STR_001C_FRUIT :Frugt
+STR_001D_DIAMONDS :Diamanter
+STR_001E_FOOD :Mad
+STR_001F_PAPER :Papir
+STR_0020_GOLD :Guld
+STR_0021_WATER :Vand
+STR_0022_WHEAT :Hvede
+STR_0023_RUBBER :Gummi
+STR_0024_SUGAR :Sukker
+STR_0025_TOYS :Legetøj
+STR_0026_CANDY :Slik
+STR_0027_COLA :Cola
+STR_0028_COTTON_CANDY :Candyfloss
+STR_0029_BUBBLES :Bobler
+STR_002A_TOFFEE :Karamel
+STR_002B_BATTERIES :Batterier
+STR_002C_PLASTIC :Plastik
+STR_002D_FIZZY_DRINKS :Sodavand
+STR_002E :
+STR_002F_PASSENGER :Passager
+STR_0030_COAL :Kul
+STR_0031_MAIL :Post
+STR_0032_OIL :Olie
+STR_0033_LIVESTOCK :Kvæg
+STR_0034_GOODS :Stykgods
+STR_0035_GRAIN :Korn
+STR_0036_WOOD :Træ
+STR_0037_IRON_ORE :Jernmalm
+STR_0038_STEEL :Stål
+STR_0039_VALUABLES :Værdigenstande
+STR_003A_COPPER_ORE :Kobbermalm
+STR_003B_MAIZE :Majs
+STR_003C_FRUIT :Frugt
+STR_003D_DIAMOND :Diamant
+STR_003E_FOOD :Mad
+STR_003F_PAPER :Papir
+STR_0040_GOLD :Guld
+STR_0041_WATER :Vand
+STR_0042_WHEAT :Hvede
+STR_0043_RUBBER :Gummi
+STR_0044_SUGAR :Sukker
+STR_0045_TOY :Legetøj
+STR_0046_CANDY :Slik
+STR_0047_COLA :Cola
+STR_0048_COTTON_CANDY :Candyfloss
+STR_0049_BUBBLE :Boble
+STR_004A_TOFFEE :Karamel
+STR_004B_BATTERY :Batteri
+STR_004C_PLASTIC :Plastik
+STR_004D_FIZZY_DRINK :Sodavand
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} passager{P "" er}
+STR_QUANTITY_COAL :{WEIGHT} kul
+STR_QUANTITY_MAIL :{COMMA} sæk{P "" ke} post
+STR_QUANTITY_OIL :{VOLUME} olie
+STR_QUANTITY_LIVESTOCK :{COMMA} stk. kvæg
+STR_QUANTITY_GOODS :{COMMA} kasse{P "" r} gods
+STR_QUANTITY_GRAIN :{WEIGHT} korn
+STR_QUANTITY_WOOD :{WEIGHT} træ
+STR_QUANTITY_IRON_ORE :{WEIGHT} jernmalm
+STR_QUANTITY_STEEL :{WEIGHT} stål
+STR_QUANTITY_VALUABLES :{COMMA} sæk{P "" ke} værdigendstande
+STR_QUANTITY_COPPER_ORE :{WEIGHT} kobbermalm
+STR_QUANTITY_MAIZE :{WEIGHT} majs
+STR_QUANTITY_FRUIT :{WEIGHT} frugt
+STR_QUANTITY_DIAMONDS :{COMMA} sæk{P "" ke} diamanter
+STR_QUANTITY_FOOD :{WEIGHT} mad
+STR_QUANTITY_PAPER :{WEIGHT} papir
+STR_QUANTITY_GOLD :{COMMA} sæk{P "" ke} guld
+STR_QUANTITY_WATER :{VOLUME} vand
+STR_QUANTITY_WHEAT :{WEIGHT} hvede
+STR_QUANTITY_RUBBER :{VOLUME} gummi
+STR_QUANTITY_SUGAR :{WEIGHT} sukker
+STR_QUANTITY_TOYS :{COMMA} legetøj
+STR_QUANTITY_SWEETS :{COMMA} sæk{P "" ke} slik
+STR_QUANTITY_COLA :{VOLUME} cola
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} candyfloss
+STR_QUANTITY_BUBBLES :{COMMA} boble{P "" r}
+STR_QUANTITY_TOFFEE :{WEIGHT} karamel
+STR_QUANTITY_BATTERIES :{COMMA} batteri{P "" er}
+STR_QUANTITY_PLASTIC :{VOLUME} plastik
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} sodavand
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}PS
+STR_ABBREV_COAL :{TINYFONT}KU
+STR_ABBREV_MAIL :{TINYFONT}PO
+STR_ABBREV_OIL :{TINYFONT}OL
+STR_ABBREV_LIVESTOCK :{TINYFONT}KV
+STR_ABBREV_GOODS :{TINYFONT}SG
+STR_ABBREV_GRAIN :{TINYFONT}KN
+STR_ABBREV_WOOD :{TINYFONT}TR
+STR_ABBREV_IRON_ORE :{TINYFONT}JM
+STR_ABBREV_STEEL :{TINYFONT}ST
+STR_ABBREV_VALUABLES :{TINYFONT}VÆ
+STR_ABBREV_COPPER_ORE :{TINYFONT}KO
+STR_ABBREV_MAIZE :{TINYFONT}MS
+STR_ABBREV_FRUIT :{TINYFONT}FR
+STR_ABBREV_DIAMONDS :{TINYFONT}DI
+STR_ABBREV_FOOD :{TINYFONT}MD
+STR_ABBREV_PAPER :{TINYFONT}PR
+STR_ABBREV_GOLD :{TINYFONT}GU
+STR_ABBREV_WATER :{TINYFONT}VA
+STR_ABBREV_WHEAT :{TINYFONT}HV
+STR_ABBREV_RUBBER :{TINYFONT}GM
+STR_ABBREV_SUGAR :{TINYFONT}SU
+STR_ABBREV_TOYS :{TINYFONT}LT
+STR_ABBREV_SWEETS :{TINYFONT}SL
+STR_ABBREV_COLA :{TINYFONT}CL
+STR_ABBREV_CANDYFLOSS :{TINYFONT}CF
+STR_ABBREV_BUBBLES :{TINYFONT}BO
+STR_ABBREV_TOFFEE :{TINYFONT}KA
+STR_ABBREV_BATTERIES :{TINYFONT}BA
+STR_ABBREV_PLASTIC :{TINYFONT}PL
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}SV
+STR_ABBREV_NONE :{TINYFONT}INT
+STR_ABBREV_ALL :{TINYFONT}ALT
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Kort - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Spilindstillinger
+STR_00B2_MESSAGE :{YELLOW}Besked
+STR_00B3_MESSAGE_FROM :{YELLOW}Besked fra {STRING}
+STR_POPUP_CAUTION_CAPTION :{WHITE}Advarsel!
+STR_00B4_CAN_T_DO_THIS :{WHITE}Det kan du ikke....
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Kan ikke rydde området....
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Original copyright {COPYRIGHT} 1995 Chris Sawyer, Alle rettigheder reserveret
+STR_00B7_VERSION :{BLACK}OpenTTD version {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 OpenTTD teamet
+STR_TRANSLATED_BY :{BLACK} Oversætter(e) -
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Afslut
+STR_00C8_YES :{BLACK}Ja
+STR_00C9_NO :{BLACK}Nej
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Er du sikker på du vil afslutte dette spil og returnere til {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Intet
+STR_00D1_DARK_BLUE :Mørk Blå
+STR_00D2_PALE_GREEN :Lys Grøn
+STR_00D3_PINK :Lyserød
+STR_00D4_YELLOW :Gul
+STR_00D5_RED :Rød
+STR_00D6_LIGHT_BLUE :Lys Blå
+STR_00D7_GREEN :Grøn
+STR_00D8_DARK_GREEN :Mørk Grøn
+STR_00D9_BLUE :Blå
+STR_00DA_CREAM :Lys Brun
+STR_00DB_MAUVE :Grålilla
+STR_00DC_PURPLE :Lilla
+STR_00DD_ORANGE :Orange
+STR_00DE_BROWN :Brun
+STR_00DF_GREY :Grå
+STR_00E0_WHITE :Hvid
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}For mange køretøjer i spillet
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Placering
+STR_00E5_CONTOURS :Konturer
+STR_00E6_VEHICLES :Køretøjer
+STR_00E7_INDUSTRIES :Industrier
+STR_00E8_ROUTES :Ruter
+STR_00E9_VEGETATION :Vegetation
+STR_00EA_OWNERS :Ejere
+STR_00EB_ROADS :{BLACK}{TINYFONT}Veje
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Jernbaner
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Stationer/Lufthavne/Havne
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Bygninger/Industrier
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Køretøjer
+STR_00F0_100M :{BLACK}{TINYFONT}100m
+STR_00F1_200M :{BLACK}{TINYFONT}200m
+STR_00F2_300M :{BLACK}{TINYFONT}300m
+STR_00F3_400M :{BLACK}{TINYFONT}400m
+STR_00F4_500M :{BLACK}{TINYFONT}500m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Toge
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Vejkøretøjer
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Skibe
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Fly
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Transportruter
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Kulmine
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Kraftværk
+STR_00FC_FOREST :{BLACK}{TINYFONT}Skov
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}Savværk
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Olieraffinaderi
+STR_00FF_FARM :{BLACK}{TINYFONT}Bondegård
+STR_0100_FACTORY :{BLACK}{TINYFONT}Fabrik
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Trykkeri
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Oliekilde
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Jernmalmsmine
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Stålværk
+STR_0105_BANK :{BLACK}{TINYFONT}Bank
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Papirmølle
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Guldmine
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Fødevareindustri
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Diamantmine
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Kobbermalmsmine
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Frugtplantage
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Gummiplantage
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Vandværk
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Vandtårn
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}Træfabrik
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Candyfloss-skov
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Slikfabrik
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Batterigård
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Colakilde
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Legetøjsforretning
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Legetøjsfabrik
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Plastikspringvand
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Sodavandsfabrik
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Boblegenerator
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Karamelbrud
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Sukkermine
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Banegård
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Fragtcentral
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Rutebilstation
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Lufthavn/Helikopterplads
+STR_011F_DOCK :{BLACK}{TINYFONT}Havn
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Hårdt terræn
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Græs
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Bart terræn
+STR_0123_FIELDS :{BLACK}{TINYFONT}Marker
+STR_0124_TREES :{BLACK}{TINYFONT}Træer
+STR_0125_ROCKS :{BLACK}{TINYFONT}Klipper
+STR_0126_WATER :{BLACK}{TINYFONT}Vand
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Ingen Ejer
+STR_0128_TOWNS :{BLACK}{TINYFONT}Byer
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Industrier
+STR_012A_DESERT :{BLACK}{TINYFONT}Ørken
+STR_012B_SNOW :{BLACK}{TINYFONT}Sne
+STR_012C_MESSAGE :{WHITE}Besked
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Annuller
+STR_012F_OK :{BLACK}OK
+STR_0130_RENAME :{BLACK}Omdøb
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}For mange navne defineret
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Valgt navn er allerede i brug
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...ejes af {STRING}
+STR_013C_CARGO :{BLACK}Last
+STR_013D_INFORMATION :{BLACK}Information
+STR_013E_CAPACITIES :{BLACK}Lasteevner
+STR_013E_TOTAL_CARGO :{BLACK}Samlet last
+STR_013F_CAPACITY :{BLACK}Lasteevne: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}Kapacitet: {LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Samlet last (lasteevne) på dette tog:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}Nyt Spil
+STR_0141_LOAD_GAME :{BLACK}Hent Spil
+STR_SINGLE_PLAYER :{BLACK}En spiller
+STR_MULTIPLAYER :{BLACK}Flere spillere
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Kortstørrelse:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Spilindstillinger
+
+STR_0150_SOMEONE :en eller anden{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Kort over verden
+STR_0152_TOWN_DIRECTORY :Byoversigt
+STR_0153_SUBSIDIES :Statsstøttede aftaler
+
+STR_UNITS_IMPERIAL :Britisk standard
+STR_UNITS_METRIC :Metersystem
+STR_UNITS_SI :SI
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} miles/t
+STR_UNITS_VELOCITY_METRIC :{COMMA} km/t
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}hk
+STR_UNITS_POWER_METRIC :{COMMA}hk
+STR_UNITS_POWER_SI :{COMMA}kW
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} ton{P "" s}
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} ton{P "" s}
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} kg
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}gal
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}l
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}m³
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} gallon{P "" s}
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} liter
+STR_UNITS_VOLUME_LONG_SI :{COMMA} m³
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10³ lbf
+STR_UNITS_FORCE_METRIC :{COMMA} ton kraft
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Graf over overskud
+STR_0155_INCOME_GRAPH :Graf over indkomster
+STR_0156_DELIVERED_CARGO_GRAPH :Graf over leveret last
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Graf over præstation
+STR_0158_COMPANY_VALUE_GRAPH :Graf over selskabsværdi
+STR_0159_CARGO_PAYMENT_RATES :Graf over lastudbetalingsrater
+STR_015A_COMPANY_LEAGUE_TABLE :Selskabsoversigt
+STR_PERFORMANCE_DETAIL_MENU :Præstations oversigt
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}Om OpenTTD
+STR_015C_SAVE_GAME :Gem Spil
+STR_015D_LOAD_GAME :Hent Spil
+STR_015E_QUIT_GAME :Afslut Spil
+STR_015F_QUIT :Afslut
+STR_ABANDON_GAME_QUERY :{YELLOW}Er du sikker på, at du vil afslutte dette spil ?
+STR_0161_QUIT_GAME :{WHITE}Afslut Spil
+STR_SORT_ORDER_TIP :{BLACK}Vælg sorteringsorden (faldende/stigende)
+STR_SORT_CRITERIA_TIP :{BLACK}Vælg sorteringskriterie
+STR_SORT_BY :{BLACK}Sorter efter
+
+STR_SORT_BY_POPULATION :{BLACK}Indbyggertal
+STR_SORT_BY_PRODUCTION :{BLACK}Produktion
+STR_SORT_BY_TYPE :{BLACK}Type
+STR_SORT_BY_TRANSPORTED :{BLACK}Transporteret
+STR_SORT_BY_NAME :{BLACK}Navn
+STR_SORT_BY_DROPDOWN_NAME :Navn
+STR_SORT_BY_DATE :{BLACK}Dato
+STR_SORT_BY_NUMBER :Nummer
+STR_SORT_BY_PROFIT_LAST_YEAR :Profit sidste år
+STR_SORT_BY_PROFIT_THIS_YEAR :Profit dette år
+STR_SORT_BY_AGE :Alder
+STR_SORT_BY_RELIABILITY :PÃ¥lidelighed
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Total kapacitet for hver lasttype
+STR_SORT_BY_MAX_SPEED :Tophastighed
+STR_SORT_BY_MODEL :Model
+STR_SORT_BY_VALUE :Værdi
+STR_SORT_BY_FACILITY :Stationstype
+STR_SORT_BY_WAITING :Værdi af ventende fragt
+STR_SORT_BY_RATING_MAX :Fragtrangering
+STR_ENGINE_SORT_ENGINE_ID :LokomotivID (klassisk sortering)
+STR_ENGINE_SORT_COST :Omkostning
+STR_ENGINE_SORT_POWER :Drivmiddel
+STR_ENGINE_SORT_INTRO_DATE :Introduktionsdato
+STR_ENGINE_SORT_RUNNING_COST :Driftsomkostning
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Drivmiddel/driftsomkostning
+STR_ENGINE_SORT_CARGO_CAPACITY :Lasteevne
+STR_NO_WAITING_CARGO :{BLACK}Der er ingen fragt af nogen type, der venter
+STR_SELECT_ALL_FACILITIES :{BLACK}Vælg alle faciliteter
+STR_SELECT_ALL_TYPES :{BLACK}Vælg alle lasttyper (inklusiv fragttyper, der ikke venter)
+STR_AVAILABLE_ENGINES_TIP :{BLACK}Se liste over tilgængelige designs for denne køretøjstype.
+STR_MANAGE_LIST :{BLACK}Administrer liste
+STR_MANAGE_LIST_TIP :{BLACK}Send instruktioner til alle køretøjer in denne liste
+STR_REPLACE_VEHICLES :Udskift køretøjer
+STR_SEND_TRAIN_TO_DEPOT :Send til remise
+STR_SEND_ROAD_VEHICLE_TO_DEPOT :Send til værksted
+STR_SEND_SHIP_TO_DEPOT :Send til dok
+STR_SEND_AIRCRAFT_TO_HANGAR :Send til hangar
+STR_SEND_FOR_SERVICING :Send til eftersyn
+
+############ range for months starts
+STR_0162_JAN :Jan
+STR_0163_FEB :Feb
+STR_0164_MAR :Mar
+STR_0165_APR :Apr
+STR_0166_MAY :Maj
+STR_0167_JUN :Jun
+STR_0168_JUL :Jul
+STR_0169_AUG :Aug
+STR_016A_SEP :Sep
+STR_016B_OCT :Okt
+STR_016C_NOV :Nov
+STR_016D_DEC :Dec
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Pause spillet
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Gem spillet, afslut spillet, afslut
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Vis en liste over selskabets stationer
+STR_0174_DISPLAY_MAP :{BLACK}Vis kortet
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Vis kortet, byoversigt
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Vis byoversigten
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Vis selskabets finansinformation
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Vis generel selskabsinformation
+STR_0179_DISPLAY_GRAPHS :{BLACK}Vis grafer
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Vis selskabsoversigten
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Vis liste over selskabets tog
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Vis liste over selskabets køretøjer
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Vis liste over selskabets skibe
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Vis liste over selskabets fly
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Zoom skærmen ind
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Zoom skærmen ud
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Byg jernbanespor
+STR_0182_BUILD_ROADS :{BLACK}Byg veje
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Byg havne
+STR_0184_BUILD_AIRPORTS :{BLACK}Byg lufthavne
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Plant træer, placér skilte osv.
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Landområde information
+STR_0187_OPTIONS :{BLACK}Indstillinger
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Kan ikke ændre serviceinterval...
+STR_018B_CLOSE_WINDOW :{BLACK}Luk vindue
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Vinduestitel - træk her for at flytte vinduet
+STR_STICKY_BUTTON :{BLACK}Marker dette vindue som ulukkeligt af 'Luk ALLE vinduer' tasten
+STR_RESIZE_BUTTON :{BLACK}Klik og træk for at ændre vinduets størrelse
+STR_SAVELOAD_HOME_BUTTON :{BLACK}Click her for at hoppe til det nuværende standard gemme/hente bibliotek
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Nedriv bygninger osv. på et stykke land
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Sænk et hjørne af landet
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Hæv et hjørne af landet
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Scroll bar - scroller listen op/ned
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Scroll bar - flytter listen mod venstre/højre
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Vis landskabskonturer på kortet
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Vis køretøjer på kortet
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Vis industrier på kortet
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Vis transportruter på kortet
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Vis vegetation på kortet
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Vis landejere på kortet
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Vis/skjul bynavne på kort
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Overskud i år: {CURRENCY} (sidste år: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} år ({COMMA})
+STR_AGE_RED :{RED}{COMMA} år ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Vejkøretøj
+STR_019D_AIRCRAFT :Fly
+STR_019E_SHIP :Skib
+STR_019F_TRAIN :Tog
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} er ved at være for gammel
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} er alt for gammel
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} er alt for gammel og bør udskiftes straks
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Landområde information
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Pris for at rydde: {LTBLUE}N/A
+STR_01A5_COST_TO_CLEAR :{BLACK}Pris for at rydde: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :N/A
+STR_01A7_OWNER :{BLACK}Ejer: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Lokal myndighed: {LTBLUE}{STRING}
+STR_01A9_NONE :Ingen
+STR_01AA_NAME :{BLACK}Navn
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1.
+STR_01AD_2ND :2.
+STR_01AE_3RD :3.
+STR_01AF_4TH :4.
+STR_01B0_5TH :5.
+STR_01B1_6TH :6.
+STR_01B2_7TH :7.
+STR_01B3_8TH :8.
+STR_01B4_9TH :9.
+STR_01B5_10TH :10.
+STR_01B6_11TH :11.
+STR_01B7_12TH :12.
+STR_01B8_13TH :13.
+STR_01B9_14TH :14.
+STR_01BA_15TH :15.
+STR_01BB_16TH :16.
+STR_01BC_17TH :17.
+STR_01BD_18TH :18.
+STR_01BE_19TH :19.
+STR_01BF_20TH :20.
+STR_01C0_21ST :21.
+STR_01C1_22ND :22.
+STR_01C2_23RD :23.
+STR_01C3_24TH :24.
+STR_01C4_25TH :25.
+STR_01C5_26TH :26.
+STR_01C6_27TH :27.
+STR_01C7_28TH :28.
+STR_01C8_29TH :29.
+STR_01C9_30TH :30.
+STR_01CA_31ST :31.
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Accepteret last: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Jazz Jukebox
+STR_01D3_SOUND_MUSIC :Lyd/Musik
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Vis lyd/musik vindue
+STR_01D5_ALL :{TINYFONT}Alle
+STR_01D6_OLD_STYLE :{TINYFONT}Old Style
+STR_01D7_NEW_STYLE :{TINYFONT}New Style
+STR_01D8_EZY_STREET :{TINYFONT}Ezy Street
+STR_01D9_CUSTOM_1 :{TINYFONT}Custom 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Custom 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Musik lydstyrke
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Effekt lydstyrke
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MIN ' ' ' ' ' ' MAKS
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Hop til forrige nummer
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Hop til næste nummer
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Stop musikken
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Start musikken
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Flyt slideren for at justere musik- og effektlydstyrken
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Nummer{SETX 88}Titel
+STR_01E9_SHUFFLE :{TINYFONT}Bland
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Programmer
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Musikprogram Valg
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Nummerliste
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Program - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}Ryd
+STR_01F1_SAVE :{TINYFONT}{BLACK}Gem
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Nuværende musikprogram valg
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Vælg 'Alle numre' programmet
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Vælg 'Old style musik' programmet
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Vælg 'New style musik' programmet
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Vælg 'Custom 1' (brugerdefineret) programmet
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Select 'Custom 2' (brugerdefineret) programmet
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Ryd det valgte program (Gælder kun Custom1/Custom2)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Gem opsætning for musik
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Klik på et musiknummer for at tilføje det til programlisten (kun for Custom1/Custom2)
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Klik på et musiknummer for at fjerne det fra programlisten (kun for Custom1/Custom2)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Tilfældig afspilning til/fra
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Vis vinduet med musiknummervalg
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Klik på servicen for at centrere skærmen over industrien/byen
+STR_01FE_DIFFICULTY :{BLACK}Sværhedsgrad ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Seneste besked/nyhedsrapport
+STR_0201_MESSAGE_SETTINGS :Beskedindstillinger
+STR_MESSAGE_HISTORY_MENU :Tidligere beskeder
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Vis sidste besked/nyhedsrapport, vis beskedindstillinger
+STR_0204_MESSAGE_OPTIONS :{WHITE}Beskedindstillinger
+STR_0205_MESSAGE_TYPES :{BLACK}Beskedtyper:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Ankomst af første køretøj til spillerens station
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Ankomst af første køretøj til modstanderens station
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Uheld / katastrofer
+STR_0209_COMPANY_INFORMATION :{YELLOW}Firmainformation
+STR_020A_ECONOMY_CHANGES :{YELLOW}Økonomiændringer
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Rådgivning / information om spillerens køretøjer
+STR_020C_NEW_VEHICLES :{YELLOW}Nye køretøjer
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Ændring i accepteret last
+STR_020E_SUBSIDIES :{YELLOW}Statsstøttede aftaler
+STR_020F_GENERAL_INFORMATION :{YELLOW}Generel information
+STR_MESSAGES_ALL :{YELLOW}Sæt alle beskedtyper til: Fra / Kortfattet / Fuld
+STR_MESSAGE_SOUND :{YELLOW}Afspil lyd for refererede nyheder
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...for langt fra forrige destination
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Bedste virksomheder, som har nået {NUM}{}({STRING} Niveau)
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Selskabsoversigt i {NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Forretningsmand
+STR_0214_ENTREPRENEUR :Entreprenør
+STR_0215_INDUSTRIALIST :Industrialist
+STR_0216_CAPITALIST :Kapitalist
+STR_0217_MAGNATE :Magnat
+STR_0218_MOGUL :Mogul
+STR_0219_TYCOON_OF_THE_CENTURY :Ã…rhundredes Matador
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} får '{STRING}' status!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} fra {COMPANY} får '{STRING}' status!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Lav et scenarie
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Scenarieeditor
+STR_0223_LAND_GENERATION :{WHITE}Land Generering
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Tilfældigt Land
+STR_0227_RESET_LAND :{BLACK}Nulstil Land
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Forstør landområdet der skal sænkes/hæves
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Formindsk landområdet der skal sænkes/hæves
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Generer tilfældigt land
+STR_022B_RESET_LANDSCAPE :{BLACK}Nulstil landskab
+STR_022C_RESET_LANDSCAPE :{WHITE}Nulstil Landskab
+STR_LOAD_GAME_HEIGHTMAP :{WHITE}Brug højdekort
+STR_LOAD_SCEN_HEIGHTMAP :{BLACK}Brug højdekort
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Er du sikker på, at du vil nulstille landskabet?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Landskabsgenerering
+STR_022F_TOWN_GENERATION :{BLACK}Bygenerering
+STR_0230_INDUSTRY_GENERATION :{BLACK}Industrigenerering
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Bygning af vej
+STR_0233_TOWN_GENERATION :{WHITE}Bygenerering
+STR_0234_NEW_TOWN :{BLACK}Ny By
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Byg en ny by
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Kan ikke bygge en by her...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...for tæt på kanten af kortet
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...for tæt på en anden by
+STR_0239_SITE_UNSUITABLE :{WHITE}...upassende placering
+STR_023A_TOO_MANY_TOWNS :{WHITE}...for mange byer
+STR_CANNOT_GENERATE_TOWN :{WHITE}Kan ikke bygge nogen byer
+STR_NO_SPACE_FOR_TOWN :{WHITE}...der er ikke mere plads på kortet
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Forøg størrelsen af byen
+STR_023C_EXPAND :{BLACK}Udvid
+STR_023D_RANDOM_TOWN :{BLACK}Tilfældig by
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Byg en by på en tilfældig placering
+STR_023F_INDUSTRY_GENERATION :{WHITE}Industrigenerering
+STR_0240_COAL_MINE :{BLACK}Kulmine
+STR_0241_POWER_STATION :{BLACK}Kraftværk
+STR_0242_SAWMILL :{BLACK}Savværk
+STR_0243_FOREST :{BLACK}Skov
+STR_0244_OIL_REFINERY :{BLACK}Olieraffinaderi
+STR_0245_OIL_RIG :{BLACK}Boreplatform
+STR_0246_FACTORY :{BLACK}Fabrik
+STR_0247_STEEL_MILL :{BLACK}Stålværk
+STR_0248_FARM :{BLACK}Bondegård
+STR_0249_IRON_ORE_MINE :{BLACK}Jernmalmsmine
+STR_024A_OIL_WELLS :{BLACK}Oliekilde
+STR_024B_BANK :{BLACK}Bank
+STR_024C_PAPER_MILL :{BLACK}Papirmølle
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Fødevareindustri
+STR_024E_PRINTING_WORKS :{BLACK}Trykkeri
+STR_024F_GOLD_MINE :{BLACK}Guldmine
+STR_0250_LUMBER_MILL :{BLACK}Træfabrik
+STR_0251_FRUIT_PLANTATION :{BLACK}Frugtplantage
+STR_0252_RUBBER_PLANTATION :{BLACK}Gummiplantage
+STR_0253_WATER_SUPPLY :{BLACK}Vandforsyning
+STR_0254_WATER_TOWER :{BLACK}Vandtårn
+STR_0255_DIAMOND_MINE :{BLACK}Diamantmine
+STR_0256_COPPER_ORE_MINE :{BLACK}Kobbermalmsmine
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Candyfloss-skov
+STR_0258_CANDY_FACTORY :{BLACK}Slikfabrik
+STR_0259_BATTERY_FARM :{BLACK}Batterigård
+STR_025A_COLA_WELLS :{BLACK}Colabrønd
+STR_025B_TOY_SHOP :{BLACK}Legetøjsforretning
+STR_025C_TOY_FACTORY :{BLACK}Legetøjsfabrik
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Plastikspringvand
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Sodavandsfabrik
+STR_025F_BUBBLE_GENERATOR :{BLACK}Boblegenerator
+STR_0260_TOFFEE_QUARRY :{BLACK}Karamelbrud
+STR_0261_SUGAR_MINE :{BLACK}Sukkermine
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Byg Kulmine
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Byg Kraftværk
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Byg Savværk
+STR_0265_PLANT_FOREST :{BLACK}Plant Skov
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Byg Olieraffinaderi
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Byg Boreplatform (Kan kun bygges tæt på kanten af kortet)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Byg Fabrik
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Byg Stålværk
+STR_026A_CONSTRUCT_FARM :{BLACK}Byg Bondegård
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Byg Jernmalmsmine
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Byg Oliekilde
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Byg Bank (Kan kun bygges i en by med mere end 1200 indbyggere)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Byg Papirmølle
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Byg Fødevareindustri
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Byg Trykkeri
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Byg Guldmine
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Byg Bank (Kan kun bygges i en by)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Byg Træfabrik (for at rydde regnskoven og producere træ)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Plant Frugtplantage
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Plant Gummiplantage
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Byg Vandværk
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Byg Vandtårn (Kan kun bygges i byer)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Byg Diamantmine
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Byg Kobbermalmsmine
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Plant Candyfloss-skov
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Byg Slikfabrik
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Byg Batterigård
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Byg Colabrønd
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Byg Legetøjsforretning
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Byg Legetøjsfabrik
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Byg Plastikspringvand
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Byg Sodavandsfabrik
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Byg Boblegenerator
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Byg Karamelbrud
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Byg Sukkermine
+STR_0285_CAN_T_BUILD_HERE :{WHITE}Kan ikke bygge {STRING} her...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...det er nødvendigt at bygge en by først
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...kun en tilladt per by
+STR_0288_PLANT_TREES :{BLACK}Plant træer
+STR_0289_PLACE_SIGN :{BLACK}Placér skilt
+STR_028A_RANDOM_TREES :{BLACK}Tilfældige Træer
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Plant træer tilfældigt i landskabet
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Placér klippeområder i landskabet
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Placér fyrtårn
+STR_028E_PLACE_TRANSMITTER :{BLACK}Placér sender
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Definer ørkenområde.{}Hold CTRL inde for at fjerne
+STR_CREATE_LAKE :{BLACK}Definer vandområde.{}Vil oversvømme nærlæggende land i samme plan
+STR_0290_DELETE :{BLACK}Slet
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Slet denne by fuldstændigt
+STR_0292_SAVE_SCENARIO :Gem scenarie
+STR_0293_LOAD_SCENARIO :Hent scenarie
+STR_0294_QUIT_EDITOR :Afslut editoren
+STR_0295 :
+STR_0296_QUIT :Afslut
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Gem scenarie, hent scenarie, forlad scenarie editoren, afslut
+STR_0298_LOAD_SCENARIO :{WHITE}Hent scenarie
+STR_0299_SAVE_SCENARIO :{WHITE}Gem scenarie
+STR_029A_PLAY_SCENARIO :{BLACK}Spil et scenarie
+STR_PLAY_HEIGHTMAP :{BLACK}Spil højdekort
+STR_PLAY_HEIGHTMAP_HINT :{BLACK}Start et nyt spil med et højdekort som landskab
+STR_QUIT_SCENARIO_QUERY :{YELLOW}Er du sikker på, at du vil afslutte dette scenarie ?
+STR_029C_QUIT_EDITOR :{WHITE}Afslut Editoren
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...kan kun bygges i byer med mindst 1200 indbyggere
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Flyt startdatoen 1 år tilbage
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Flyt startdatoen 1 år frem
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...begge ender af en bro skal være på land
+STR_02A1_SMALL :{BLACK}Lille
+STR_02A2_MEDIUM :{BLACK}Mellem
+STR_02A3_LARGE :{BLACK}Stor
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Vælg bystørrelse
+STR_02A5_TOWN_SIZE :{YELLOW}Bystørrelse:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Vis seneste besked eller nyhedsrapport
+STR_OFF :Fra
+STR_SUMMARY :Resume
+STR_FULL :Fuldt
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Byoversigt
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Køretøjsdesignnavne
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Standard
+STR_02BF_CUSTOM :Brugerdefineret
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Gem ikke brugerdefinerede navne
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Valg af køretøjsdesignnavne
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Gem brugerdefinerede køretøjsdesignnavne
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Spilindstillinger
+STR_02C5_DIFFICULTY_SETTINGS :Sværhedsgrad
+STR_02C7_CONFIG_PATCHES :Konfigurér patches
+STR_NEWGRF_SETTINGS :NewGRF indstillinger
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Bynavne vist
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Stationsnavne vist
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Skilte vist
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Kontrolsteder vist
+STR_02D0_FULL_ANIMATION :{SETX 12}Fuld animation
+STR_02D2_FULL_DETAIL :{SETX 12}Fuld detalje
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Gennemsigtige bygninger
+STR_TRANSPARENT_SIGNS :{SETX 12}Gennemsigtige stationsskilte
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Landområde information
+STR_02D6 :
+STR_CONSOLE_SETTING :Tænd/Sluk konsol
+STR_02D7_SCREENSHOT_CTRL_S :Skærmbillede (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Kæmpe skærmbillede (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :Om 'OpenTTD'
+############ range ends here
+
+STR_02DB_OFF :{BLACK}Fra
+STR_02DA_ON :{BLACK}Til
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Vis statsstøttede aftaler
+STR_02DD_SUBSIDIES :Statsstøttede aftaler
+STR_02DE_MAP_OF_WORLD :Kort over verden
+STR_EXTRA_VIEW_PORT :Flere lokalitetsvinduer
+STR_SIGN_LIST :Liste over skilte
+STR_02DF_TOWN_DIRECTORY :Byoversigt
+STR_TOWN_POPULATION :{BLACK}Verdens befolkning: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Lokalitetsvinduer {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}GÃ¥ til lokalitetsvindue
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Hent lokalitet fra global visning
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Hent fra lokalitetsvindue
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Kopier lokaliteten af dette vindue til det globale vindue
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Valutaenhed
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Valg af valutaenhed
+STR_MEASURING_UNITS :{BLACK}MÃ¥leenheder
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Vælg måleenheder
+STR_02E6_ROAD_VEHICLES :{BLACK}Vejkøretøjer
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Vælg den side af vejen, køretøjer skal køre i
+STR_02E9_DRIVE_ON_LEFT :Kør i venstre side
+STR_02EA_DRIVE_ON_RIGHT :Kør i højre side
+STR_02EB_TOWN_NAMES :{BLACK}Bynavne
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Vælg stil for bynavne
+
+STR_02F4_AUTOSAVE :{BLACK}Autogem
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Vælg interval imellem automatisk gemning
+STR_02F7_OFF :Fra
+STR_02F8_EVERY_3_MONTHS :Hver 3. måned
+STR_02F9_EVERY_6_MONTHS :Hver 6. måned
+STR_02FA_EVERY_12_MONTHS :Hver 12. måned
+STR_02FB_START_A_NEW_GAME :{BLACK}Start et nyt spil
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Hent et gemt spil
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Lav en brugerdefineret verden/scenarie
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Vælg enkeltspiller spil
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Vælg flerspiller spil med 2-8 spillere
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Vis spilindstillinger
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Vis sværhedsgrad-indstillinger
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Start et nyt spil med et brugerdefineret scenarie
+STR_0304_QUIT :{BLACK}Afslut
+STR_0305_QUIT_OPENTTD :{BLACK}Afslut 'OpenTTD'
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...kan kun bygges i byer
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Vælg 'tempereret' landskab
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Vælg 'subarktisk' landskab
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Vælg 'subtropisk' landskab
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Vælg 'legetøjsland' landskab
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Betal for bygning af nye industrier
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Industrioversigt
+STR_0313_FUND_NEW_INDUSTRY :Opfør ny industri
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Opfør ny industri
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...kan kun bygges i byer
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...kan kun bygges i regnskovsområder
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...kan kun bygges i ørkenområder
+STR_0319_PAUSED :{YELLOW}* * PAUSE * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Skærmbilledet blev gemt som '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}Fejl under tagning af skærmbillede!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Køb land til senere brug
+STR_032F_AUTOSAVE :{RED}AUTOSAVE
+STR_SAVING_GAME :{RED}* * GEMMER SPIL * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}Gemmer stadig,{}vent venligst!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Vælg 'Ezy Street musik' program
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :Engelske
+STR_TOWNNAME_FRENCH :Franske
+STR_TOWNNAME_GERMAN :Tyske
+STR_TOWNNAME_ADDITIONAL_ENGLISH :Engelske (ekstra)
+STR_TOWNNAME_LATIN_AMERICAN :Latin-Amerikanske
+STR_TOWNNAME_SILLY :Fjollede
+STR_TOWNNAME_SWEDISH :Svenske
+STR_TOWNNAME_DUTCH :Hollandske
+STR_TOWNNAME_FINNISH :Finske
+STR_TOWNNAME_POLISH :Polske
+STR_TOWNNAME_SLOVAKISH :Slovakiske
+STR_TOWNNAME_NORWEGIAN :Norske
+STR_TOWNNAME_HUNGARIAN :Ungarske
+STR_TOWNNAME_AUSTRIAN :Østrigske
+STR_TOWNNAME_ROMANIAN :Rumænske
+STR_TOWNNAME_CZECH :Tjekkiske
+STR_TOWNNAME_SWISS :Schweiziske
+STR_TOWNNAME_DANISH :Danske
+STR_TOWNNAME_TURKISH :Tyrkiske
+STR_TOWNNAME_ITALIAN :Italienske
+STR_TOWNNAME_CATALAN :Catalanske
+############ end of townname region
+
+STR_CURR_GBP :Pund (£)
+STR_CURR_USD :Dollar ($)
+STR_CURR_EUR :Euro (€)
+STR_CURR_YEN :Yen (Â¥)
+STR_CURR_ATS :Østrisk Shilling (ATS)
+STR_CURR_BEF :Belgiske Franc (BEF)
+STR_CURR_CHF :Sweiziske Franc (CHF)
+STR_CURR_CZK :Tjekkiske Koruna (CZK)
+STR_CURR_DEM :Deutschmark (DEM)
+STR_CURR_DKK :Danske Kroner (DKK)
+STR_CURR_ESP :Peseta (ESP)
+STR_CURR_FIM :Finske Markka (FIM)
+STR_CURR_FRF :Franc (FRF)
+STR_CURR_GRD :Græske Drachmer (GRD)
+STR_CURR_HUF :Ungarnske Forint (HUF)
+STR_CURR_ISK :Islandske Kroner (ISK)
+STR_CURR_ITL :Italienske Lire (ITL)
+STR_CURR_NLG :Hollandske Guilder (NLG)
+STR_CURR_NOK :Norske Kroner (NOK)
+STR_CURR_PLN :Polske Zloty (PLN)
+STR_CURR_ROL :Rumænske Lei (ROL)
+STR_CURR_RUR :Russiske Rubel (RUR)
+STR_CURR_SIT :Slovenske Tolare (SIT)
+STR_CURR_SEK :Svenske Kroner (SEK)
+STR_CURR_YTL :Tyrkiske Lira (TRY)
+STR_CURR_SKK :Slovakiske Koruna (SKK)
+STR_CURR_BRR :Brasilianske Real (BRL)
+
+STR_CURR_CUSTOM :Brugerdefineret...
+
+STR_OPTIONS_LANG :{BLACK}Sprog
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Vælg sprog til brugerfladen
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Fuld skærm
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}Afkryds for at spille OpenTTD i fuld skærm
+
+STR_OPTIONS_RES :{BLACK}Skærmopløsning
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Vælg skørmopløsning
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Skærmbillede format
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Vælg skærmbillede format
+
+STR_AUTOSAVE_1_MONTH :Hver måned
+STR_AUTOSAVE_FAILED :{WHITE}Fejl under autogem
+
+STR_MONTH_JAN :Januar
+STR_MONTH_FEB :Februar
+STR_MONTH_MAR :Marts
+STR_MONTH_APR :April
+STR_MONTH_MAY :Maj
+STR_MONTH_JUN :Juni
+STR_MONTH_JUL :Juli
+STR_MONTH_AUG :August
+STR_MONTH_SEP :September
+STR_MONTH_OCT :Oktober
+STR_MONTH_NOV :November
+STR_MONTH_DEC :December
+
+STR_HEADING_FOR_STATION :{LTBLUE}Retning mod {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}Retning mod {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Ingen ordre
+STR_NO_ORDERS_VEL :{LTBLUE}Ingen ordre, {VELOCITY}
+
+STR_PASSENGERS :passagerer
+STR_BAGS :sække
+STR_TONS :tons
+STR_LITERS :liter
+STR_ITEMS :stykker
+STR_CRATES :kasser
+STR_RES_OTHER :andet
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Kan ikke dele ordreliste...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Kan ikke kopiere ordreliste...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - Slut på delt ordreliste - -
+
+STR_TRAIN_IS_LOST :{WHITE}Tog {COMMA} er faret vild.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}Tog {COMMA}'s profit sidste år var {CURRENCY}
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}Europæisk fællesvaluta!{}{}Euroen er introduceret som eneste betalingsmiddel i dit land!
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Tog {COMMA} har for få ordrer i sin køreplan
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}Tog {COMMA} har en ugyldig ordre
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}Tog {COMMA} har dobbelt ordre
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}Tog {COMMA} har en ugyldig station i sin køreplan
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}Køretøj {COMMA} har for få ordre i sin køreplan
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}Køretøj {COMMA} har en ugyldig ordre
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}Køretøj {COMMA} har dobbelt ordre
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}Køretøj {COMMA} har en ugyldig station i sin køreplan
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}Skib {COMMA} har for få ordrer i sin sejlplan
+STR_SHIP_HAS_VOID_ORDER :{WHITE}Skib {COMMA} har en ugyldig ordre
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}Skib {COMMA} har dobbelt ordre
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}Skib {COMMA} har en ugyldig havn i sin sejlplan
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}Fly {COMMA} har for få ordre i sin flyveplan
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}Fly {COMMA} har en ugyldig ordre
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}Fly {COMMA} har dobbelt ordre
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}Fly {COMMA} har en ugyldig lufthavn i sin flyveplan
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}Automatisk fornyelse af tog mislykkedes {COMMA} (ikke penge nok)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}Automatisk fornyelse af køretøj mislykkedes {COMMA} (ikke penge nok)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}Automatisk fornyelse af skib mislykkedes {COMMA} (ikke penge nok)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}Automatisk fornyelse af fly mislykkedes {COMMA} (ikke penge nok)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}Tog {COMMA} er for langt efter udskiftning
+
+STR_CONFIG_PATCHES :{BLACK}Indstil Patches
+STR_CONFIG_PATCHES_TIP :{BLACK}Indstil Patchesne
+STR_CONFIG_PATCHES_CAPTION :{WHITE}Indstil Patches
+
+STR_CONFIG_PATCHES_OFF :Fra
+STR_CONFIG_PATCHES_ON :Til
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Vis køretøjets fart i statusbaren: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Tillad bygning på skråninger og kyster: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Tillad mere realistisk størrelse på stationernes opland: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Tillad nedriving af industribygninger, flere veje, osv: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Aktiver bygning af meget lange tog: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Aktiver realistisk acceleration af tog: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Forbyd skibe og tog at dreje 90 grader: {ORANGE}{STRING} {LTBLUE} (skal bruge NPF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Foren togstationer der bygges ved siden af hinanden: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Forlad stationen hvis en slags last bliver fyldt, hvis 'fuld last': {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Brug forbedret indlæsnings algoritme: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GRADUAL_LOADING :{LTBLUE}Last køretøjer gradvist: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Inflation: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Aflever kun last til en station hvis der er en forespørgsel: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Tillad bygning af meget lange broer: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Tillad gå til depot ordrer: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Tillad opførslen af råmateriale industrier: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Tillad flere af samme slags industri per by: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Tillad at flere af samme slags industri kan være tæt på hinanden: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Vis altid lang dato i statusbaren: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Vis signaler i kørselssiden: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Vis finansvinduet i slutningen af året: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}TTDPatch kombatibel nonstop håndtering: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Kødannelse af køretøjer (med kvanteeffekt): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Pannorer vindue når musen er ved kanten: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Tillad bestikkelse af de lokale myndigheder: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Ikke uniforme stationer: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Ny global ruteplanlægger (NPF, tilsidesætter NTP): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FREIGHT_TRAINS :{LTBLUE}Vægtfaktor for fragt for at simulere tunge tog: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Tillad altid små lufthavne: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Advar hvis tog er faret vild: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Kontroller køretøjers ordreliste: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :Nej
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :Ja, på nær ved stoppet køretøjer
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :Ja, på alle køretøjer
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Advar hvis et tog har underskud: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Køretøjernes levealder udløber aldrig: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Automatisk fornyelse af køretøjer når de bliver gamle
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Automatisk fornyelse når køretøj er {ORANGE}{STRING}{LTBLUE} måneder under/over max alder
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Antal penge i banken før automatisk fornyelse af køretøjer: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Levetid for fejlmeddelser: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Vis byens indbyggertal i bynavnet: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Usynlige træer (med gennemsigtige bygninger): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Landskabs generator: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :Original
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis
+STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}Den maksimale distance fra kanten til olieraffinaderier {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Snelinjehøjden: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN :{LTBLUE}Tærrenets hårdhed (kun TerraGenesis) : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Meget blødt
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH :Blødt
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH :RÃ¥t
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :Meget råt
+STR_CONFIG_PATCHES_TREE_PLACER :{LTBLUE}Algoritme ved placering af træer: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TREE_PLACER_NONE :Ingen
+STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL :Original
+STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED :Forbedret
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION :{LTBLUE}Rotér højdekort: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Mod uret
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE :Med uret
+STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT :{LTBLUE}Den højde et flat scenariekort får: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Maks. station udbreddelse: {ORANGE}{STRING} {RED}Advarsel: Høj værdi gør spillet langsomt
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Automatisk service på helikopterlandingspladser: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Link landskabs værktøjsbaren til skinne/vej/vand/lufthavn værktøjsbaren: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}NÃ¥r der scrolles med musen, flyt viewet i den modsatte retning: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Vis værktøjstip for måling under brug af div. bygge-værktøjer: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Vis firmafarver: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES_NONE :Ingen
+STR_CONFIG_PATCHES_LIVERIES_OWN :Eget firma
+STR_CONFIG_PATCHES_LIVERIES_ALL :Alle firmaer
+STR_CONFIG_PATCHES_PREFER_TEAMCHAT :{LTBLUE}Foretræk hold-chat med <ENTER>: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Maks antal tog per spiller: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Maks antal køretøjer per spiller: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}Maks antal fly per spiller: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}Maks antal skibe per spiller: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Deaktiver toge for computeren: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Deaktiver køretøjer for computeren: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Deaktiver fly for computeren: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Deaktiver skibe for computeren: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Slå den nye kunstige intelligents til (alpha): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Tillad AI i multiplayer (experimentiel): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Standard service interval for tog: {ORANGE}{STRING} dage/%
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Standard service interval for tog: {ORANGE}slået fra
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Standard service interval for vejkøretøjer: {ORANGE}{STRING} dage/%
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Standard service interval for vejkøretøjer: {ORANGE}slået fra
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Standard service interval for fly: {ORANGE}{STRING} dage/%
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Standard service interval for fly: {ORANGE}slået fra
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Standard service interval for skibe: {ORANGE}{STRING} dage/%
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Standard service interval for skibe: {ORANGE}slået fra
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Slå service fra, når nedbrud er sat til ingen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Aktiver hastigheds begrænsning for vogne: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}Slå elektriske jernbaner fra: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Farvede nyheder dukker op i: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Start dato: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}Afslut spillet i: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Aktiver rolig økonomi (flere små ændringer)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Tillad at købe aktier i andre selskaber
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Ved trækning placer signal hvert: {ORANGE}{STRING} felt
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Placering af værktøjslinie: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Venstre
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Center
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Højre
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Vinduernes sammenkoblings afstand: {ORANGE}{STRING} px
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Vinduernes sammenkoblings afstand: {ORANGE}slået fra
+
+STR_CONFIG_PATCHES_GUI :{BLACK}Brugerflade
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Konstruktion
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Køretøjer
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Stationer
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Økonomi
+STR_CONFIG_PATCHES_AI :{BLACK}Modstandere
+
+STR_CONFIG_PATCHES_DISABLED :deaktiveret
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Skift indstillingsværdi
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Nogle eller alle standard service intervaller nedenunder er uforenelige med den valgte opsætning! 5-90% og 30-800 dage er gyldige
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}Brug YAPF for skibe: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}Brug YAPF for busser: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}Brug YAPF for tog: {ORANGE}{STRING}
+
+STR_TEMPERATE_LANDSCAPE :Tempereret klima
+STR_SUB_ARCTIC_LANDSCAPE :Arktisk klima
+STR_SUB_TROPICAL_LANDSCAPE :Tropisk klima
+STR_TOYLAND_LANDSCAPE :Legetøjsland
+
+STR_CHEATS :{WHITE}Snydefunktioner
+STR_CHEATS_TIP :{BLACK}Checkbokse viser, om du har brugt denne snydefunktion før
+STR_CHEATS_WARNING :{BLACK}Advarsel! Du er ved at forråde dine modstandere. Husk at dette vil blive husket i al evighed.
+STR_CHEAT_MONEY :{LTBLUE}Forøg kassebeholdning med {CURRENCY64}
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Spil som spiller: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Magisk bulldozer (nedriv ting, som normalt ikke kan fjernes): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Tunneler kan krydse hinanden: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Tillad at bygge mens pause er aktiveret: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Jetfly vil ikke styrte (ofte) i små lufthavne: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Skift klima: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Ændre dato: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}Aktiver modifikation af produktion: {ORANGE}{STRING}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}Retning mod {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Retning mod {WAYPOINT}, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :Via {WAYPOINT}
+STR_GO_NON_STOP_TO_WAYPOINT :Kør uden stop via {WAYPOINT}
+
+STR_WAYPOINTNAME_CITY :Kontrolsted {TOWN}
+STR_WAYPOINTNAME_CITY_SERIAL :Kontrolsted {TOWN} #{COMMA}
+STR_LANDINFO_WAYPOINT :Kontrolsted
+
+STR_WAYPOINT :{WHITE}Kontrolsted
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Vælg udseende af kontrolsteder
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}Omdøb kontrolsted
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Kan ikke omdøbe kontrolsted...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Ændre jernbane til kontrolsted
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Kan ikke bygge kontrolsted for tog her...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Kan ikke fjerne kontrolsted for tog her...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Byg jernbane med auto-jernbane-værktøj
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}...der er ingen byer i dette scenarie
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}Er du sikker på, at du vil lave et tilfældigt landskab?
+STR_MANY_RANDOM_TOWNS :{BLACK}Mange tilfældige byer
+STR_RANDOM_TOWNS_TIP :{BLACK}Dæk kortet med tilfældigt placerede byer
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Mange tilfældige industrier
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Dæk kortet med tilfældigt placerede industrier
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Kan ikke lave industrier...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Åbn landskabsværktøjslinien for at hæve/sænke terræn, plante træer, osv.
+STR_LANDSCAPING_TOOLBAR :{WHITE}Landskabsværktøjer
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Udjævn land
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Træer af tilfældig type
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}Placer træer af tilfældig type
+
+STR_CANT_BUILD_CANALS :{WHITE}Kan ikke bygge en kanal her...
+STR_BUILD_CANALS_TIP :{BLACK}Byg kanaler
+STR_LANDINFO_CANAL :Kanal
+
+STR_CANT_BUILD_LOCKS :{WHITE}Kan ikke bygge en sluse her...
+STR_BUILD_LOCKS_TIP :{BLACK}Byg sluser
+STR_LANDINFO_LOCK :Sluse
+
+STR_BUOY_IS_IN_USE :{WHITE}... bøjen er i brug!
+
+STR_LANDINFO_COORDS :{BLACK}Koordinater: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Kan ikke fjerne en del af en station...
+STR_CANT_CONVERT_RAIL :{WHITE}Kan ikke konvertere jernbanetype her...
+STR_CONVERT_RAIL_TIP :{BLACK}Konverter/opgrader typen af jernbane
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Træk lokomotivet her for at sælge hele toget
+
+STR_DRAG_DROP :{BLACK}Træk & slip
+STR_STATION_DRAG_DROP :{BLACK}Byg en station vha. træk & slip
+STR_SELECT_STATION_CLASS_TIP :{BLACK}Vælg hvilken stationstype, der skal vises
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Vælg hvilen stationstype du vil bygge
+
+STR_FAST_FORWARD :{BLACK}Kør spillet hurtigere
+STR_MESSAGE_HISTORY :{WHITE}Tidligere beskeder
+STR_MESSAGE_HISTORY_TIP :{BLACK}En liste of seneste nyheder
+STR_MESSAGES_DISABLE_ALL :{BLACK}Slå alle fra
+STR_MESSAGES_ENABLE_ALL :{BLACK}Slå alle til
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Byg Kulmine
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Plant Skov
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Byg Boreplatform
+STR_CONSTRUCT_FARM_TIP :{BLACK}Opfør en bondegård
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Byg Kobbermalmsmine
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Bor efter olie
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Byg Guldmine
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Byg Diamandmine
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Byg Jernmalmsmine
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Opfør Frugtplantage
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Opfør Gummiplantage
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Opfør Vandforsyning
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Plant Candyfloss Skov
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}Opfør Batterigård
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Bor efter Cola
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Opfør Plastikspringvand
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Byg Boblegenerator
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Opfør Karamelbrud
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Byg Sukkermine
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Industrier
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA}% transporteret)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA}%/{COMMA}% transported)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}...for tæt på en anden industribygning
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Ombyg toget til at køre med en anden slags last
+STR_RAIL_REFIT_VEHICLE :{BLACK}Ombyg toget
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Vælg den slags last toget skal køre med
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Ombyg toget til at køre med den markerede slags last
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Kan ikke ombygge toget...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Service intervaller er i procent: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Skift produktion
+
+TEMP_AI_IN_PROGRESS :{WHITE}Velkommen til den nye kunstige intelligents, der er under udarbejdelse. Du kan forvente problemer. Når det sker, så lav et skærmbillede og sæt det på forummet.
+TEMP_AI_ACTIVATED :{WHITE}Advarsel: den nye kunstige intelligents er i et tidligt stadie! Lige nu virker den kun med busser og lastbiler!
+TEMP_AI_MULTIPLAYER :{WHITE}Advarsel: denne funktion er stadig eksperimentel. Rapporter venligst problemer til truelight@openttd.org.
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Netværksspil
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Spiller navn:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}Dette er det navn, som andre spillere vil kende dig ved
+STR_NETWORK_CONNECTION :{BLACK}Forbindelse:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Vælg mellem et internet baseret eller et lokalnet baseret spil
+
+STR_NETWORK_START_SERVER :{BLACK}Start server
+STR_NETWORK_START_SERVER_TIP :{BLACK}Start en ny server
+
+STR_NETWORK_GAME_NAME :{BLACK}Navn
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Spillets navn
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Sprog, server version, osv.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Klik på et spil fra listen for at vælge det
+
+STR_NETWORK_FIND_SERVER :{BLACK}Find server
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Søg netværket for en server
+STR_NETWORK_ADD_SERVER :{BLACK}Tilføj server
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Tilføj en server til listen, som altid vil blive checket for om den kører et spil
+STR_NETWORK_ENTER_IP :{BLACK}Skriv adressen på en server
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Klienter
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Klienter online / max klienter
+STR_NETWORK_GAME_INFO :{SILVER}SPIL INFO
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Klienter: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Sprog: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Klima: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Størrelse: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}Server version: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}Serveradresse: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Start dato: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Nuværende dato: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Beskyttet af kodeord!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}SERVEREN ER OFFLINE
+STR_NETWORK_SERVER_FULL :{SILVER}SERVEREN ER FULD
+STR_NETWORK_VERSION_MISMATCH :{SILVER}Din og serverens version passer ikke sammen
+STR_NETWORK_GRF_MISMATCH :{SILVER}NEWGRF MATCHER IKKE
+
+STR_NETWORK_JOIN_GAME :{BLACK}Tilslut dig et spil
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}Start et nyt netværksspil
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Spillets navn:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}Navnet vil blive vist til andre spillere i menuen, hvor man vælger netværksspil
+STR_NETWORK_SET_PASSWORD :{BLACK}Set kodeord
+STR_NETWORK_PASSWORD_TIP :{BLACK}Beskyt dit spil med et kodeord hvis du ikke vil have fremmede med
+STR_NETWORK_SELECT_MAP :{BLACK}Vælg et kort:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}Hvilket kort vil du spille?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}Maksimalt antal tilladte klienter:
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Vælg det maksimale antal klienter. Det er ikke nødvendigt at fylde dem alle
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :LAN
+STR_NETWORK_INTERNET :Internet
+STR_NETWORK_LAN_INTERNET :LAN / Internet
+STR_NETWORK_INTERNET_ADVERTISE :Internet (bekendtgør spillet)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 spillere
+STR_NETWORK_1_PLAYERS :1 spiller
+STR_NETWORK_2_PLAYERS :2 spillere
+STR_NETWORK_3_PLAYERS :3 spillere
+STR_NETWORK_4_PLAYERS :4 spillere
+STR_NETWORK_5_PLAYERS :5 spillere
+STR_NETWORK_6_PLAYERS :6 spillere
+STR_NETWORK_7_PLAYERS :7 spillere
+STR_NETWORK_8_PLAYERS :8 spillere
+STR_NETWORK_9_PLAYERS :9 spillere
+STR_NETWORK_10_PLAYERS :10 spillere
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}Maks. firmaer:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Begræns serveren to et bestemt antal firmaer
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}Maks. tilskuere:
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Begræns serveren til et bestemt antal tilskurere
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Talt sprog:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Andre spillere vil vide hvilket sprog, der bliver talt på serveren
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}Start spillet
+STR_NETWORK_START_GAME_TIP :{BLACK}Start et nyt netværksspil med et tilfældigt kort eller et scenarie
+STR_NETWORK_LOAD_GAME :{BLACK}Hent et spil
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Fortsyt et tidligere gemt spil med flere spillere (sør for at få den rigtige virksomhed)
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Hvilketsomhelst
+STR_NETWORK_LANG_ENGLISH :Engelsk
+STR_NETWORK_LANG_GERMAN :Tysk
+STR_NETWORK_LANG_FRENCH :Fransk
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Netværksspils lobby
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Forbereder tilslutning: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}En liste over alle selskaber i spillet lige nu. Du kan enten tilslutte dig et eller starte et nyt, hvis der er plads til flere selskaber
+STR_NETWORK_NEW_COMPANY :{BLACK}Ny virksomhed
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Lav en ny virksomhed
+STR_NETWORK_SPECTATE_GAME :{BLACK}Tilskuer spil
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Se et spil som tilskuer
+STR_NETWORK_JOIN_COMPANY :{BLACK}Tilslut dig selskab
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Hjælp med at bestyrre dette selskab
+STR_NETWORK_REFRESH :{BLACK}Genopfrisk serveren
+STR_NETWORK_REFRESH_TIP :{BLACK}Genopfrisk server info
+
+STR_NETWORK_COMPANY_INFO :{SILVER}VIRKSOMHEDSINFO
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Virksomhedens navn: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}Grundlagt: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}Virksomhedens værdi: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Nuværende beholdning: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Sidste års indtægt: {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}Præstation: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}Køretøjer: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Stationer: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Spillere: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}Forbinder...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) Forbinder..
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Godkender..
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Venter..
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Henter kort..
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Behandler data..
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) Registere..
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Henter spil info..
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Henter firma info..
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} klient{P "" er} foran dig
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} kbytes hentet indtil videre
+
+STR_NETWORK_DISCONNECT :{BLACK}Afbryd forbindelse
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Skriv det beløb, som du ønsker at give
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Serveren er beskyttet. Skriv kodeordet
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Virksomheden er beskyttet. Skriv kodeordet
+STR_NETWORK_CLIENT_LIST :{WHITE}Klient Liste
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE} Ingen netværksheder fundet eller kompilet uden ENABLE_NETWORK
+STR_NETWORK_ERR_NOSERVER :{WHITE} Kunne ikke finde nogen netværksspil
+STR_NETWORK_ERR_NOCONNECTION :{WHITE} Serveren besvarede ikke denne forspørgsel
+STR_NETWORK_ERR_DESYNC :{WHITE} Netværks synkroniseringsfejl
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} Netværksforbindelse mistet
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} Kunne ikke hente gemt spil
+STR_NETWORK_ERR_SERVER_START :{WHITE} Kunne ikke starte serveren
+STR_NETWORK_ERR_CLIENT_START :{WHITE} Kunne ikke forbinde
+STR_NETWORK_ERR_TIMEOUT :{WHITE} Forbindelsen #{NUM} svare ikke
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE} Der opstod en protokol-fejl og forbindelse blev lukket
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE} Revisionen af denne klient passer ikke sammen med serverens revision
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} Forkert kodeord
+STR_NETWORK_ERR_SERVER_FULL :{WHITE} Serveren er fuld
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} Du har forbud mod at bruge denne server
+STR_NETWORK_ERR_KICKED :{WHITE} Du blev smidt ud af spillet
+STR_NETWORK_ERR_CHEATER :{WHITE} Snyderi er ikke tilladt på denne server
+
+STR_NETWORK_ERR_LEFT :har forladt spillet
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :generel fejl
+STR_NETWORK_ERR_CLIENT_DESYNC :synkroniseringsfejl
+STR_NETWORK_ERR_CLIENT_SAVEGAME :kunne ikke hente kortet
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :forbindelsen blev afbrudt
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :protokol fejl
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :Ikke Autoriseret
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :modtog en underlig pakke
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :forkert revision
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :navnet er allerede i brug
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :forkert spil password
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :forkert player-id i DoCommand
+STR_NETWORK_ERR_CLIENT_KICKED :smidt ud af serveren
+STR_NETWORK_ERR_CLIENT_CHEATER :prøvede at snyde
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :serveren er fuld
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :har tilsluttet sig spillet
+STR_NETWORK_GIVE_MONEY :gav din virksomhed nogle penge ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :du gav {STRING} nogle penge ({CURRENCY})
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Hold] :
+STR_NETWORK_CHAT_COMPANY :[Hold] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Hold] Til {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[Privat] :
+STR_NETWORK_CHAT_CLIENT :[Privat] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[Privat] Til {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[Alle] :
+STR_NETWORK_CHAT_ALL :[Alle] {STRING}: {GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :har skiftet navn til
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE} Serveren har lukket ned for dette spil
+STR_NETWORK_SERVER_REBOOT :{WHITE} Serveren genstarter...{}Vent venligst...
+
+STR_NETWORK_SERVER :Server
+STR_NETWORK_CLIENT :Klient
+STR_NETWORK_SPECTATORS :Tilskuere
+
+STR_NETWORK_CLIENTLIST_NONE :(ingen)
+STR_NETWORK_CLIENTLIST_KICK :Smid ud
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Giv penge
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Tal til alle
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Tal til virksomhed
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Privat besked
+
+
+STR_NETWORK_SEND :{BLACK}Send
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}X-størrelse af kort: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Y-størrelse af kort: {ORANGE}{STRING}
+
+
+##### PNG-MAP-Loader
+
+STR_PNGMAP_ERROR :{WHITE}Kan ikke hente billedet fra PNG...
+STR_PNGMAP_ERR_FILE_NOT_FOUND :{WHITE}...filen blev ikke fundet.
+STR_PNGMAP_ERR_IMAGE_TYPE :{WHITE}...kan ikke konvertere billedtype. Der skal bruges 8 eller 24-bit PNG.
+STR_PNGMAP_ERR_MISC :{WHITE}...noget gik galt. Undskyld (Måske en ødelagt fil)
+
+STR_BMPMAP_ERROR :{WHITE}Kan ikke hente landskab fra BMP...
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}...kunne ikke konvertere billedtypen.
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Pris: {CURRENCY}
+STR_0801_COST :{RED}Pris: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Indkomst: {CURRENCY}
+STR_0803_INCOME :{GREEN}Indkomst: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Transfer: {CURRENCY}
+STR_FEEDER :{YELLOW}Transfer: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Anslået Pris: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Anslået Indkomst: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Kan ikke hæve landet her...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Kan ikke sænke landet her...
+STR_080A_ROCKS :Klipper
+STR_080B_ROUGH_LAND :Barskt land
+STR_080C_BARE_LAND :Bart land
+STR_080D_GRASS :Græs
+STR_080E_FIELDS :Marker
+STR_080F_SNOW_COVERED_LAND :Snedækket land
+STR_0810_DESERT :Ørken
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Landet hælder i den forkerte retning
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Umulig sporkombination
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}Udgravning ville skade en tunnel
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Allerede ved havoverfladen
+STR_1004_TOO_HIGH :{WHITE}For højt
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Ingen brugbar jernbane
+STR_1007_ALREADY_BUILT :{WHITE}...allerede bygget
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Det er nødvendigt at fjerne jernbaneskinnerne først
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Jernbanekonstruktion
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Elektrisk jernbane konstruktion
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Monorailkonstruktion
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}Magnetskinnekonstruktion
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Vælg togbro
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Kan ikke bygge en remise her...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Kan ikke bygge en banegård her...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Kan ikke bygge signaler her...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Kan ikke bygge jernbane her...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Kan ikke fjerne jernbane herfra...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Kan ikke fjerne signaler herfra...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Retning for remise
+STR_1015_RAILROAD_CONSTRUCTION :Jernbanekonstruktion
+STR_TOOLB_ELRAIL_CONSTRUCTION :Elektrisk jernbane konstruktion
+STR_1016_MONORAIL_CONSTRUCTION :Monorailkonstruktion
+STR_1017_MAGLEV_CONSTRUCTION :Magnetskinnekonstruktion
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Byg jernbane
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Byg en remise (til at bygge og servicere tog)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Byg banegård
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Byg signaler
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Byg bro
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Byg tunnel
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Skift mellem bygning/fjernelse af jernbaneskinner og signaler
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Valg af bro - klik på den valgte bro for at bygge den
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Vælg orientering af remise
+STR_1021_RAILROAD_TRACK :Jernbaneskinner
+STR_1023_RAILROAD_TRAIN_DEPOT :Remise
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...området ejes af et andet firma
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :Jernbane med almindelige signaler
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :Jernbane med indkørselssignaler
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :Jernbane med udkørselssignaler
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :Jernbane med kombinerede ind- og udkørselssignaler
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Det er nødvendigt at fjerne vejen først
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Vejarbejde er i gang
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Vejkonstruktion
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Vælg vejbro
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Kan ikke bygge vej her...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Kan ikke fjerne vej herfra...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Retning af værksted
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Kan ikke bygge værksted her...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Kan ikke bygge rutebilstation...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Kan ikke bygge fragtcentral...
+STR_180A_ROAD_CONSTRUCTION :Vejkonstruktion
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Byg en sektion vej
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Byg værksted (til servicering og bygning af vejkøretøjer)
+STR_180D_BUILD_BUS_STATION :{BLACK}Byg rutebilstation
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Byg fragtcentral
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Byg bro
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Byg tunnel
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Skift mellem bygning/fjernelse af veje
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Vælg retning for værksted
+STR_1814_ROAD :Vej
+STR_1815_ROAD_WITH_STREETLIGHTS :Vej med gadelygter
+STR_1816_TREE_LINED_ROAD :Vej med vejtræer
+STR_1817_ROAD_VEHICLE_DEPOT :Garage
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :Jernbaneoverskæring
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Byer
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Det er nødvendigt at nedrive bygningen først
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}Indbyggere: {ORANGE}{COMMA}{BLACK} Huse: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Omdøb Byen
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Kan ikke omdøbe byen...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} de lokale myndigheder nægter at tillade dette
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Bynavne - klik på et navn for at centrere skærmen over byen
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centrer skærmen over byens placering
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Ændre navnet på byen
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passagerer sidste måned: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Post sidste måned: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Høj kontorbygning
+STR_2010_OFFICE_BLOCK :Kontorbygning
+STR_2011_SMALL_BLOCK_OF_FLATS :Lille lejlighedskompleks
+STR_2012_CHURCH :Kirke
+STR_2013_LARGE_OFFICE_BLOCK :Stor kontorbygning
+STR_2014_TOWN_HOUSES :Villaer
+STR_2015_HOTEL :Hotel
+STR_2016_STATUE :Statue
+STR_2017_FOUNTAIN :Springvand
+STR_2018_PARK :Park
+STR_2019_OFFICE_BLOCK :Kontorbygning
+STR_201A_SHOPS_AND_OFFICES :Forretninger og kontorer
+STR_201B_MODERN_OFFICE_BUILDING :Moderne kontorbygning
+STR_201C_WAREHOUSE :Lagerbygning
+STR_201D_OFFICE_BLOCK :Kontorbygning
+STR_201E_STADIUM :Stadion
+STR_201F_OLD_HOUSES :Gamle huse
+STR_2020_LOCAL_AUTHORITY :{BLACK}Myndigheder
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Vis information om de lokale myndigheder
+STR_2022_LOCAL_AUTHORITY :{WHITE}{TOWN} lokal myndighed
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Transportselskabsbedømmelse:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Statsstøttede aftaler
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Statsstøttede aftaler i licitation:
+STR_2027_FROM_TO :{ORANGE}{STRING} fra {STRING} til {STRING}
+STR_2028_BY :{YELLOW} (inden {DATE_SHORT})
+STR_202A_NONE :{ORANGE}Ingen
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Statsstøttede aftaler der allerede er vundet:
+STR_202C_FROM_TO :{ORANGE}{STRING} fra {STATION} til {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, indtil {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}Statsstøttet aftale udløbet:{}{}{STRING} fra {STRING} til {STRING} vil ikke længere udløse tilskud.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Licitation af statsstøttet aftale tilbagetrukket:{}{}{STRING} fragt fra {STATION} til {STATION} er ikke længere i licitation.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Statsstøttet aftale i licitation:{}{}Første {STRING} fragt fra {STRING} til {STRING} vil udløse et års tilskud fra de lokale myndigheder!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Statsstøttet aftale tildelt {COMPANY}!{}{}{STRING} fragt fra {STATION} til {STATION} vil give 50% mere i de næste 12 måneder!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Statsstøttet aftale tildelt {COMPANY}!{}{}{STRING} fragt fra {STATION} til {STATION} vil give dobbelt udbytte i de næste 12 måneder!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Statsstøttet aftale tildelt {COMPANY}!{}{}{STRING} fragt fra {STATION} til {STATION} vil give tredobbelt udbytte i de næste 12 måneder!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Statsstøttet aftale tildelt {COMPANY}!{}{}{STRING} fragt fra {STATION} til {STATION} vil give firedobbelt udbytte i de næste 12 måneder!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} de lokale myndigheder tillader ikke, at der bliver bygget en lufthavn mere i byen
+STR_2036_COTTAGES :Hytter
+STR_2037_HOUSES :Huse
+STR_2038_FLATS :Lejligheder
+STR_2039_TALL_OFFICE_BLOCK :Høj kontorbygning
+STR_203A_SHOPS_AND_OFFICES :Forretninger og kontorer
+STR_203B_SHOPS_AND_OFFICES :Forretninger og kontorer
+STR_203C_THEATER :Teater
+STR_203D_STADIUM :Stadion
+STR_203E_OFFICES :Kontorer
+STR_203F_HOUSES :Huse
+STR_2040_CINEMA :Biograf
+STR_2041_SHOPPING_MALL :Indkøbscenter
+STR_2042_DO_IT :{BLACK}Gør det
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}Liste af ting der kan gøres i denne by - klik på en ting for yderligere detaljer
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Udfør den markerede ting i listen herover
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Handlinger til RÃ¥dighed:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Lille reklamekampagne
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Mellem reklamekampagne
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Stor reklamekampagne
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Betal for lokal vejfornyelse
+STR_204A_BUILD_STATUE_OF_COMPANY :Byg en statue af selskabets ejer
+STR_204B_FUND_NEW_BUILDINGS :Betal for opførsel af nye bygninger
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Køb eksklusive transportrettigheder i byen
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Bestik de lokale myndigheder
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Start en lille reklamekampagne for at tiltrække flere passagerer og last til dine stationer.{} Pris: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Start en mellem reklamekampagne, for at tiltrække flere passagerer og last til dine stationer.{} Pris: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Start en stor reklamekampagne, for at tiltrække flere passagerer og last til dine stationer.{} Pris: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} Betal for vejfornyelse i midtbyen. Forårsager stor forstyrrelse af vejnettet i de næste 6 måneder.{} Pris: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Byg en statue til ære for dit firma.{} Pris: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Betal for opførelse af forretningsbygninger i byen.{} Pris: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Køb et års eksklusive rettigheder til transport i byen. De lokale myndigheder vil kun tillade passagerer og last at bruge dine stationer.{} Prist: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Bestik de lokale myndigheder til at hæve din bedømmelse, med sandsynlighed for en stor straf hvis det bliver opdaget.{} Pris: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}Trafikkaos i byen {TOWN}!{}{}Vejfornyelse betalt af {COMPANY} forårsager 6 måneders kaos i trafikken!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (under konstruktion)
+STR_2059_IGLOO :Iglo
+STR_205A_TEPEES :Tipi
+STR_205B_TEAPOT_HOUSE :Tepottehus
+STR_205C_PIGGY_BANK :Sparegris
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN} {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Landskabsværktøjer
+STR_2800_PLANT_TREES :Plant træer
+STR_2801_PLACE_SIGN :Placer skilt
+STR_2802_TREES :{WHITE}Træer
+STR_2803_TREE_ALREADY_HERE :{WHITE}...der er allerede træer her
+STR_2804_SITE_UNSUITABLE :{WHITE}...placeringen er ikke egnet
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Kan ikke plante træer her...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...for mange skilte
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Kan ikke placere skilt her...
+STR_280A_SIGN :Skilt
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Ændre skiltets tekst
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Kan ikke ændre navnet på skiltet...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Vælg typen af træer der skal plantes
+STR_280E_TREES :Træer
+STR_280F_RAINFOREST :Regnskov
+STR_2810_CACTUS_PLANTS :Kaktusplanter
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Valg af banegård
+STR_3001_AIRPORT_SELECTION :{WHITE}Valg af lufthavn
+STR_3002_ORIENTATION :{BLACK}Retning
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Antal spor
+STR_3004_PLATFORM_LENGTH :{BLACK}Længde af perron
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}For tæt på en anden banegård
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Grænser op til mere end en eksisterende station/fragtcentral
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}For mange stationer/fragtcentraler i denne by
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}For mange stationer/fragtcentraler
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}For mange busterminaler
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}For mange fragtcentraler
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}For tæt på en anden station/fragtcentral
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Det er nødvendigt at rive stationen ned først
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}For tæt på en anden lufthavn
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Det er nødvendigt at rive lufthavnen ned først
+
+STR_3030_RENAME_STATION_LOADING :Omdøb stationen/fragtcentralen
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Kan ikke omdøbe stationen...
+STR_3032_RATINGS :{BLACK}Bedømmelse
+STR_3033_ACCEPTS :{BLACK}Accepterer
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}Lokal bedømmelse af transportservice:
+
+############ range for rating starts
+STR_3035_APPALLING :Rædselsfuld
+STR_3036_VERY_POOR :Meget DÃ¥rlig
+STR_3037_POOR :DÃ¥rlig
+STR_3038_MEDIOCRE :Middelmådig
+STR_3039_GOOD :God
+STR_303A_VERY_GOOD :Meget God
+STR_303B_EXCELLENT :Fortrinlig
+STR_303C_OUTSTANDING :Enestående
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} accepterer ikke længere {STRING}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} accepterer ikke længere {STRING} eller {STRING}
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} accepterer nu {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} accepterer nu {STRING} og {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Retning af rutebilstation
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Retning af fragtcentral
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Det er nødvendigt at rive rutebilstationen ned først
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Det er nødvendigt at rive fragtcentralen ned først
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Stationer
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Ingen -
+STR_304B_SITE_UNSUITABLE :{WHITE}...placeringen er uegnet
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}For tæt på en anden havn
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Det er nødvendigt at rive havnen ned først
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Vælg retning af banegård
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Vælg antal perroner på banegård
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Vælg længde af banegård
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Vælg retning af rutebilstation
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Vælg retning af fragtcentral
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Centrer skærmen over stationens placering
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Vis stationens bedømmelse
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Ændre stationens navn
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Vis liste over accepteret last
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Stationsnavne - klik på et navn for at centrere skærmen over stationen
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Vælg lufthavnens størrelse/type
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :Banegård
+STR_305F_AIRCRAFT_HANGAR :Hangar
+STR_3060_AIRPORT :Lufthavn
+STR_3061_TRUCK_LOADING_AREA :Fragtcentral
+STR_3062_BUS_STATION :Rutebilstation
+STR_3063_SHIP_DOCK :Havn
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Marker dækningsområdet af den foreslåede placering
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Marker ikke dækningsområdet af den foreslåede placering
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Markering af dækningsområdet
+STR_3068_DOCK :{WHITE}Havn
+STR_3069_BUOY :Bøje
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...der er en bøje i vejen
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...stationen er for spredt
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...ikke uniforme stationer er slået fra
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Hold CTRL nede for at vælge mere end en ting
+
+STR_UNDEFINED :(udefineret tekststring)
+STR_STAT_CLASS_DFLT :Standard station
+STR_STAT_CLASS_WAYP :Kontrolsteder
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Skibsdok Orientering
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...skal bygges på vand
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Kan ikke bygge en skibsdok her...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Vælg orientering af skibsdok
+STR_3804_WATER :Vand
+STR_3805_COAST_OR_RIVERBANK :Kyst eller flodbred
+STR_3806_SHIP_DEPOT :Skibsdok
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...kan ikke bygge på vand
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Gem Spil
+STR_4001_LOAD_GAME :{WHITE}Hent Spil
+STR_4002_SAVE :{BLACK}Gem
+STR_4003_DELETE :{BLACK}Slet
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} megabytes fri
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Kan ikke læse drevet
+STR_4007_GAME_SAVE_FAILED :{WHITE}Fejl under gemning af spil
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Kan ikke slette fil
+STR_4009_GAME_LOAD_FAILED :{WHITE}Fejl under hentning af spil
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}Liste over drev, biblioteker og gemte spilfiler
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Nuværende gemte spils navn
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Slet det valgte gemte spil
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Gem det nuværende spil, med det valgte navn
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Vælg Spiltype til Nyt Spil
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Vælg scenarie (grøn), predefineret spil (blå), eller nyt tilfældigt spil
+STR_4010_GENERATE_RANDOM_NEW_GAME :Generer nyt tilfældigt spil
+STR_4011_LOAD_HEIGHTMAP :{WHITE}Hent højdekort
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} i vejen
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :Kulmine
+STR_4803_POWER_STATION :Kraftværk
+STR_4804_SAWMILL :Savværk
+STR_4805_FOREST :Skov
+STR_4806_OIL_REFINERY :Olieraffinaderi
+STR_4807_OIL_RIG :Boreplatform
+STR_4808_FACTORY :Fabrik
+STR_4809_PRINTING_WORKS :Trykkeri
+STR_480A_STEEL_MILL :Stålværk
+STR_480B_FARM :Bondegård
+STR_480C_COPPER_ORE_MINE :Kobbermalmsmine
+STR_480D_OIL_WELLS :Oliekilde
+STR_480E_BANK :Bank
+STR_480F_FOOD_PROCESSING_PLANT :Fødevareindustri
+STR_4810_PAPER_MILL :Papirmølle
+STR_4811_GOLD_MINE :Guldmine
+STR_4812_BANK :Bank
+STR_4813_DIAMOND_MINE :Diamantmine
+STR_4814_IRON_ORE_MINE :Jernmalmsmine
+STR_4815_FRUIT_PLANTATION :Frugtplantage
+STR_4816_RUBBER_PLANTATION :Gummiplantage
+STR_4817_WATER_SUPPLY :Vandværk
+STR_4818_WATER_TOWER :Vandtårn
+STR_4819_FACTORY :Fabrik
+STR_481A_FARM :Bondegård
+STR_481B_LUMBER_MILL :Træfabrik
+STR_481C_COTTON_CANDY_FOREST :Candyfloss Skov
+STR_481D_CANDY_FACTORY :Slikfabrik
+STR_481E_BATTERY_FARM :Batterigård
+STR_481F_COLA_WELLS :Colabrønd
+STR_4820_TOY_SHOP :Legetøjsforretning
+STR_4821_TOY_FACTORY :Legetøjsfabrik
+STR_4822_PLASTIC_FOUNTAINS :Plastikspringvand
+STR_4823_FIZZY_DRINK_FACTORY :Sodavandsfabrik
+STR_4824_BUBBLE_GENERATOR :Boblegenerator
+STR_4825_TOFFEE_QUARRY :Karamelbrud
+STR_4826_SUGAR_MINE :Sukkermine
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Kræver: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Kræver: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Kræver: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Produktion sidste måned:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% transporteret)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centrer skærmen over placeringen af industrien
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Ny {STRING} under opførelse tæt på {TOWN}!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Ny {STRING} bliver plantet tæt på {TOWN}!
+STR_482F_COST :{BLACK}Pris: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Kan ikke bygge denne industritype her...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...skov kan kun plantes over snelinjen
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} rapporterer om øjeblikkelig nedlukning!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}Forsyningsproblemer får {INDUSTRY} til at lukke omgående!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}Mangel på træer i nærheden får {INDUSTRY} til at lukke omgående!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} øger produktionen!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}Ny kulåre fundet tæt på {INDUSTRY}!{}Produktionen forventes fordoblet!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}Nye oliereserver fundet tæt ved {INDUSTRY}!{}Produktionen forventes fordoblet!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}Forbedrede landbrugsmetoder ved {INDUSTRY} gør at produktionen forventes fordoblet!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}{INDUSTRY} produktion er faldet med 50%
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}Insekter foresager kaos ved {INDUSTRY}!{}Produktionen er faldet med 50%
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...kan kun placeres nær kanten af kortet
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}{STRING}produktionen på {INDUSTRY} vokser med {COMMA}%!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}{STRING}produktionen på {INDUSTRY} sænkes med {COMMA}%!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Der er et tog i tunnelen
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Der er et køretøj i tunnelen
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}En anden tunnel er i vejen
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Det er umuligt at lave en udgravning til tunnelen i den anden ende
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Det er nødvendigt at rive tunnelen ned først
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Det er nødvendigt at rive broen ned først
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Kan ikke starte og slutte på samme position
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Der skal være fladt land eller vand under broen
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}Start- og slutposition skal være på linje
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Dette sted er ikke brugbart til starten af en tunnel
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Hængebro, Stål
+STR_500F_GIRDER_STEEL :Bjælkebro, Stål
+STR_5010_CANTILEVER_STEEL :Fritbærende bro, Stål
+STR_5011_SUSPENSION_CONCRETE :Hængebro, Beton
+STR_5012_WOODEN :Træ
+STR_5013_CONCRETE :Beton
+STR_5014_TUBULAR_STEEL :Rørformet bro, Stål
+STR_BRIDGE_TUBULAR_SILICON :Rørformet bro, Silicium
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Kan ikke bygge en bro her...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Kan ikke bygge en tunnel her...
+STR_5017_RAILROAD_TUNNEL :Jernbanetunnel
+STR_5018_ROAD_TUNNEL :Tunnel
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Jernbanehængebro af stål
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Jernbanebjælkebro af stål
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Frithængende jernbanebro af stål
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Forstærket jernbanehængebro af beton
+STR_501F_WOODEN_RAIL_BRIDGE :Jernbanebro af træ
+STR_5020_CONCRETE_RAIL_BRIDGE :Jernbanebro af beton
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Hængebro af stål
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Bjælkebro af stål
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Frithængende bro af stål
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Forstærket hængebro af beton
+STR_5025_WOODEN_ROAD_BRIDGE :Bro af træ
+STR_5026_CONCRETE_ROAD_BRIDGE :Bro af beton
+STR_5027_TUBULAR_RAIL_BRIDGE :Rørformet jernbanebro
+STR_5028_TUBULAR_ROAD_BRIDGE :Rørformet bro
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Der er et objekt i vejen
+STR_5801_TRANSMITTER :Sender
+STR_5802_LIGHTHOUSE :Fyrtårn
+STR_5803_COMPANY_HEADQUARTERS :Selskabets hovedkontor
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...selskabets hovedkontor i vejen
+STR_5805_COMPANY_OWNED_LAND :Land ejet af selskabet
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Kan ikke købe dette landområde...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...du ejer det allerede!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Ikke navngivet
+STR_SV_TRAIN_NAME :Tog {COMMA}
+STR_SV_ROADVEH_NAME :Vejkøretøj {COMMA}
+STR_SV_SHIP_NAME :Skib {COMMA}
+STR_SV_AIRCRAFT_NAME :Fly {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :{STRING} Nord
+STR_SV_STNAME_SOUTH :{STRING} Syd
+STR_SV_STNAME_EAST :{STRING} Øst
+STR_SV_STNAME_WEST :{STRING} Vest
+STR_SV_STNAME_CENTRAL :{STRING} Hovedbanegård
+STR_SV_STNAME_TRANSFER :{STRING} Centrum
+STR_SV_STNAME_HALT :{STRING} Stop
+STR_SV_STNAME_VALLEY :{STRING} Dalen
+STR_SV_STNAME_HEIGHTS :{STRING} Bakke
+STR_SV_STNAME_WOODS :{STRING} Park
+STR_SV_STNAME_LAKESIDE :{STRING} Sø
+STR_SV_STNAME_EXCHANGE :{STRING} Marked
+STR_SV_STNAME_AIRPORT :{STRING} Lufthavn
+STR_SV_STNAME_OILFIELD :{STRING} Oliefelt
+STR_SV_STNAME_MINES :{STRING} Miner
+STR_SV_STNAME_DOCKS :{STRING} Havn
+STR_SV_STNAME_BUOY_1 :{STRING} Bøje 1
+STR_SV_STNAME_BUOY_2 :{STRING} Bøje 2
+STR_SV_STNAME_BUOY_3 :{STRING} Bøje 3
+STR_SV_STNAME_BUOY_4 :{STRING} Bøje 4
+STR_SV_STNAME_BUOY_5 :{STRING} Bøje 5
+STR_SV_STNAME_BUOY_6 :{STRING} Bøje 6
+STR_SV_STNAME_BUOY_7 :{STRING} Bøje 7
+STR_SV_STNAME_BUOY_8 :{STRING} Bøje 8
+STR_SV_STNAME_BUOY_9 :{STRING} Bøje 9
+STR_SV_STNAME_ANNEXE :{STRING} Forstad
+STR_SV_STNAME_SIDINGS :{STRING} Sidespor
+STR_SV_STNAME_BRANCH :{STRING} Torv
+STR_SV_STNAME_UPPER :Øvre {STRING}
+STR_SV_STNAME_LOWER :Nedre {STRING}
+STR_SV_STNAME_HELIPORT :{STRING} Helikopterplads
+STR_SV_STNAME_FOREST :{STRING} Skov
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Sværhedsgrad
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Gem
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Nem
+STR_6802_MEDIUM :{BLACK}Mellem
+STR_6803_HARD :{BLACK}Svær
+STR_6804_CUSTOM :{BLACK}Speciel
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maksimalt antal modstandere: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Modstandernes starttidspunkt: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}Antal byer: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}Antal industrier: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Maksimalt startlån: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Startrenten: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Køretøjers kørselsomkostning: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Byggehastighed for modstandere: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Modstandernes inteligens: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Nedbrud af køretøjer: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Statstilskudsfaktor: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Konstruktionspris: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Terræntype: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Antal søer/floder: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Økonomi: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Tog vender: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Katastrofer: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Byrådets holdning til ændring i landskabet: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :Ingen
+STR_6816_LOW :Lav
+STR_6817_NORMAL :Normal
+STR_6818_HIGH :Høj
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Meget Langsom
+STR_681C_SLOW :Langsom
+STR_681D_MEDIUM :Mellem
+STR_681E_FAST :Hurtig
+STR_681F_VERY_FAST :Meget Hurtig
+STR_VERY_LOW :Meget Lavt
+STR_6820_LOW :Lavt
+STR_6821_MEDIUM :Middel
+STR_6822_HIGH :Højt
+STR_6823_NONE :Ingen
+STR_6824_REDUCED :Reduceret
+STR_6825_NORMAL :Normal
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Meget Fladt
+STR_682B_FLAT :Fladt
+STR_682C_HILLY :Bakket
+STR_682D_MOUNTAINOUS :Bjergrigt
+STR_682E_STEADY :Rolig
+STR_682F_FLUCTUATING :Svingende
+STR_6830_IMMEDIATE :Med det samme
+STR_6831_3_MONTHS_AFTER_PLAYER :3 måneder efter spilleren
+STR_6832_6_MONTHS_AFTER_PLAYER :6 måneder efter spilleren
+STR_6833_9_MONTHS_AFTER_PLAYER :9 måneder efter spilleren
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :Ved slutningen af jernbanespor, og ved stationer
+STR_6835_AT_END_OF_LINE_ONLY :Kun ved slutningen af jernbanespor
+STR_6836_OFF :Fra
+STR_6837_ON :Til
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Vis higscoreliste
+STR_6839_PERMISSIVE :Passiv
+STR_683A_TOLERANT :Tolerant
+STR_683B_HOSTILE :Fjendtlig
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Spiller {COMMA})
+STR_7004_NEW_FACE :{BLACK}Nyt Ansigt
+STR_7005_COLOR_SCHEME :{BLACK}Farvetema
+STR_7006_COLOR_SCHEME :{GOLD}Farvetema:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Nyt Farvetema
+STR_7008_COMPANY_NAME :{BLACK}Firmanavn
+STR_7009_PRESIDENT_NAME :{BLACK}Direktørnavn
+STR_700A_COMPANY_NAME :Firmanavn
+STR_700B_PRESIDENT_S_NAME :Direktørens Navn
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Kan ikke ændre firmaets navn...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Kan ikke ændre direktørens navn...
+STR_700E_FINANCES :{WHITE}{COMPANY} Finanser {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Udgifter/Indkomst
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Konstruktion
+STR_7012_NEW_VEHICLES :{GOLD}Nye køretøjer
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Togdriftsomkostning
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Køretøjsdriftsomkostning
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Flydriftsomkostning
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Skibsdriftsomkostning
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Vedligeholdelse af ejendom
+STR_7018_TRAIN_INCOME :{GOLD}Togindkomst
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Køretøjsindkomst
+STR_701A_AIRCRAFT_INCOME :{GOLD}Flyindkomst
+STR_701B_SHIP_INCOME :{GOLD}Skibsindkomst
+STR_701C_LOAN_INTEREST :{GOLD}Renter
+STR_701D_OTHER :{GOLD}Andet
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Total:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Indkomst Graf
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Profit Garf
+STR_7026_BANK_BALANCE :{WHITE}Bank balance
+STR_7027_LOAN :{WHITE}LÃ¥n
+STR_MAX_LOAN :{WHITE}Maks. LÃ¥n: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}LÃ¥n {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Tilbagebetal {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...maksimale størrelse af lån er {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Kan ikke låne flere penge...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...ingen lån at tilbagebetale
+STR_702E_REQUIRED :{WHITE}...{CURRENCY} krævet
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Kan ikke tilbagebetale lån...
+STR_INSUFFICIENT_FUNDS :{WHITE}Du kan ikke forære penge væk, som du har lånt i banken...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Vælg nyt ansigt til direktøren
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Ændrer firmaets køretøjers farve
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Ændrer direktørens navn
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Ændrer firmaets navn
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Klik på det nye farvetema
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Forøg lånet
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Tilbagebetal en del af lånet
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(Direktør)
+STR_7038_INAUGURATED :{GOLD}Indivet: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Køretøjer:
+STR_TRAINS :{WHITE}{COMMA} tog
+STR_ROAD_VEHICLES :{WHITE}{COMMA} køretøj{P "" er}
+STR_AIRCRAFT :{WHITE}{COMMA} fly
+STR_SHIPS :{WHITE}{COMMA} skib{P "" e}
+STR_7042_NONE :{WHITE}Ingen
+STR_7043_FACE_SELECTION :{WHITE}Ansigtsvalg
+STR_7044_MALE :{BLACK}Mand
+STR_7045_FEMALE :{BLACK}Kvinde
+STR_7046_NEW_FACE :{BLACK}Nyt Ansigt
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Annuller nyt valg af ansigt
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Accepter nyt ansigtsvalg
+STR_7049_SELECT_MALE_FACES :{BLACK}Vælg mandlige ansigter
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Vælg kvindelige ansigter
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Generer nyt tilfældigt ansigt
+STR_704C_KEY :{BLACK}Nøgle
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Viser nøglen til grafen
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Nøgle til firmagraf
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Klik her for at vise/gemme firmaets graf
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Afleveret last
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Firmaets ydelsesrate (maksimal=1000)
+STR_7052_COMPANY_VALUES :{WHITE}Selskabsværdier
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Selskabsoversigt
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}Transportfirma i vanskeligheder!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} vil blive erklæret bankerupt eller solgt hvis ikke ydelsen stiger snart!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(Direktør)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Fussion mellem transportfirmaer!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} er blevet solgt til {COMPANY} for {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Vi leder efter et selskab til at overtage vores{}{}Vil du købe {COMPANY} for {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Bankerupt!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} er blevet lukket af kreditorerne og alle ejendomme er solgt!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}Nyt transportselskab er startet!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} starter konstruktion i nærheden af {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Kan ikke købe selskab...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Lastudbetalingsrater
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Antal dage undervejs
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Betaling for at transportere 10 enheder (eller 10,000 liter) last en distance på 20 enheder.
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Skift grafen for denne lasttype til/fra
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Ingeniør
+STR_7067_TRAFFIC_MANAGER :Trafikbestyrrer
+STR_7068_TRANSPORT_COORDINATOR :Trafikkoordinator
+STR_7069_ROUTE_SUPERVISOR :Routesuperviser
+STR_706A_DIRECTOR :Direktør
+STR_706B_CHIEF_EXECUTIVE :Administrende Direktør
+STR_706C_CHAIRMAN :Formand
+STR_706D_PRESIDENT :Præsident
+STR_706E_TYCOON :Matador
+STR_706F_BUILD_HQ :{BLACK}Byg HK
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Byg firmaets hovedkvarter / centrer over hovedkvarteret
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Flyt firmaets hovedkvarter for 1% af firmaets værdi
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Kan ikke bygge firmaets hovedkvarter...
+STR_7072_VIEW_HQ :{BLACK}Vis HK
+STR_RELOCATE_HQ :{BLACK}Flyt hovedkvarter
+STR_COMPANY_PASSWORD :{BLACK}Kodeord
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Beskyt din virksomhed med et kodeord for at undgå at fremmede slutter sig til spillet.
+STR_SET_COMPANY_PASSWORD :Sæt virksomhedens kodeord
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}Lavkonjuktur over hele verden!{}{}Vismændende frygter det værste, økonomien skrumper!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Økonomisk krise overvundet!{}{}Stigning i forbrug giver industrien selvtilliden tilbage, produktionen øges!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Skift mellem stort/lille vindue
+STR_7076_COMPANY_VALUE :{GOLD}Selskabsværdi: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Køb 25% aktier i firmaet
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Sælg 25% aktier i firmaet
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Kæb 25% aktier i dette firma
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Sælg 25% aktier i dette firma
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Kan ikke købe 25% aktier i dette firma...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}Kan ikke sælge 25% aktier i dette firma...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% ejes af {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% ejes af {COMPANY}{} {COMMA}% ejes af {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} er blevet overtaget af {COMPANY}!
+STR_7080_PROTECTED :{WHITE}Dette selskab sælger ikke aktier endnu...
+
+STR_LIVERY_DEFAULT :Standardfarver
+STR_LIVERY_STEAM :Damplokomotiv
+STR_LIVERY_DIESEL :Diesellokomotiv
+STR_LIVERY_ELECTRIC :Elektrisk lokomotiv
+STR_LIVERY_MONORAIL :Monorail-lokomotiv
+STR_LIVERY_MAGLEV :Magnetskinnelokomotiv
+STR_LIVERY_DMU :Dieseltogsæt
+STR_LIVERY_EMU :Eltogsæt
+STR_LIVERY_PASSENGER_WAGON_STEAM :Passagervogn (damp)
+STR_LIVERY_PASSENGER_WAGON_DIESEL :Passagervogn (diesel)
+STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Passagervogn (elektrisk)
+STR_LIVERY_FREIGHT_WAGON :Godsvogn
+STR_LIVERY_BUS :Bus
+STR_LIVERY_TRUCK :Lastbil
+STR_LIVERY_PASSENGER_SHIP :Passagerfærge
+STR_LIVERY_FREIGHT_SHIP :Fragtskib
+STR_LIVERY_HELICOPTER :Helikopter
+STR_LIVERY_SMALL_PLANE :Lille fly
+STR_LIVERY_LARGE_PLANE :Stort fly
+
+STR_LIVERY_GENERAL_TIP :{BLACK}Vis generelle farveskemaer
+STR_LIVERY_TRAIN_TIP :{BLACK}Vis farveskemaer for tog
+STR_LIVERY_ROADVEH_TIP :{BLACK}Vis farveskemaer for køretøjer
+STR_LIVERY_SHIP_TIP :{BLACK}Vis farveskemaer for skibe
+STR_LIVERY_AIRCRAFT_TIP :{BLACK}Vis farveskemaer for fly
+STR_LIVERY_PRIMARY_TIP :{BLACK}Vælg den primære farve for det valgte farveskema
+STR_LIVERY_SECONDARY_TIP :{BLACK}Vælg den sekundære farve for det valgte farveskema
+STR_LIVERY_PANEL_TIP :{BLACK}Vælg et farveskema, som skal ændres, eller flere farveskemaer vha. CTRL+klik. Klik på boksen for at slå brug af farveskemaet til/fra
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (Damp)
+STR_8001_MJS_250_DIESEL :MJS 250 (Diesel)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut Diesel
+STR_8006_POWERNAUT_DIESEL :Powernaut Diesel
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (Damp)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (Damp)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (Damp)
+STR_800A_SH_8P_STEAM :SH '8P' (Damp)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (Diesel)
+STR_800C_DASH_DIESEL :'Dash' (Diesel)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (Diesel)
+STR_800E_UU_37_DIESEL :UU '37' (Diesel)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (Diesel)
+STR_8010_CS_4000_DIESEL :CS 4000 (Diesel)
+STR_8011_CS_2400_DIESEL :CS 2400 (Diesel)
+STR_8012_CENTENNIAL_DIESEL :Centennial (Diesel)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (Diesel)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (Diesel)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (Diesel)
+STR_8016_SH_125_DIESEL :SH '125' (Diesel)
+STR_8017_SH_30_ELECTRIC :SH '30' (Elektrisk)
+STR_8018_SH_40_ELECTRIC :SH '40' (Elektrisk)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (Elektrisk)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (Elektrisk)
+STR_801B_PASSENGER_CAR :Personvogn
+STR_801C_MAIL_VAN :Postvogn
+STR_801D_COAL_CAR :Kulvogn
+STR_801E_OIL_TANKER :Olievogn
+STR_801F_LIVESTOCK_VAN :Kreaturvogn
+STR_8020_GOODS_VAN :Stykgodsvogn
+STR_8021_GRAIN_HOPPER :Kornvogn
+STR_8022_WOOD_TRUCK :Trævogn
+STR_8023_IRON_ORE_HOPPER :Jernmalmsvogn
+STR_8024_STEEL_TRUCK :Stålvogn
+STR_8025_ARMORED_VAN :Pansret vogn
+STR_8026_FOOD_VAN :Fødevarevogn
+STR_8027_PAPER_TRUCK :Papirvogn
+STR_8028_COPPER_ORE_HOPPER :Kobbermalmsvogn
+STR_8029_WATER_TANKER :Vandtanksvogn
+STR_802A_FRUIT_TRUCK :Frugtvogn
+STR_802B_RUBBER_TRUCK :Gummivogn
+STR_802C_SUGAR_TRUCK :Sukkervogn
+STR_802D_COTTON_CANDY_HOPPER :Candyflossvogn
+STR_802E_TOFFEE_HOPPER :Karamelvogn
+STR_802F_BUBBLE_VAN :Boblevogn
+STR_8030_COLA_TANKER :Colatankvogn
+STR_8031_CANDY_VAN :Slikvogn
+STR_8032_TOY_VAN :Legetøjsvogn
+STR_8033_BATTERY_TRUCK :Batterivogn
+STR_8034_FIZZY_DRINK_TRUCK :Sodavandsvogn
+STR_8035_PLASTIC_TRUCK :Plastikvogn
+STR_8036_X2001_ELECTRIC :'X2001' (Elektrisk)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Elektrisk)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :Personvogn
+STR_803A_MAIL_VAN :Postvogn
+STR_803B_COAL_CAR :Kulvogn
+STR_803C_OIL_TANKER :Olietank
+STR_803D_LIVESTOCK_VAN :Kreaturvogn
+STR_803E_GOODS_VAN :Stykgodsvogn
+STR_803F_GRAIN_HOPPER :Kornvogn
+STR_8040_WOOD_TRUCK :Trævogn
+STR_8041_IRON_ORE_HOPPER :Jernmalmsvogn
+STR_8042_STEEL_TRUCK :Stålvogn
+STR_8043_ARMORED_VAN :Pansret vogn
+STR_8044_FOOD_VAN :Fødevarevogn
+STR_8045_PAPER_TRUCK :Papirvogn
+STR_8046_COPPER_ORE_HOPPER :Kobbermalmsvogn
+STR_8047_WATER_TANKER :Vandtanksvogn
+STR_8048_FRUIT_TRUCK :Frugtvogn
+STR_8049_RUBBER_TRUCK :Gummivogn
+STR_804A_SUGAR_TRUCK :Sukkervogn
+STR_804B_COTTON_CANDY_HOPPER :Candyflossvogn
+STR_804C_TOFFEE_HOPPER :Karamelvogn
+STR_804D_BUBBLE_VAN :Boblevogn
+STR_804E_COLA_TANKER :Colatankvogn
+STR_804F_CANDY_VAN :Slikvogn
+STR_8050_TOY_VAN :Legetøjsvogn
+STR_8051_BATTERY_TRUCK :Batterivogn
+STR_8052_FIZZY_DRINK_TRUCK :Sodavandsvogn
+STR_8053_PLASTIC_TRUCK :Plastikvogn
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (Elektrisk)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (Elektrisk)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (Elektrisk)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (Elektrisk)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :Personvogn
+STR_805A_MAIL_VAN :Postvogn
+STR_805B_COAL_CAR :Kulvogn
+STR_805C_OIL_TANKER :Olietank
+STR_805D_LIVESTOCK_VAN :Kreaturvogn
+STR_805E_GOODS_VAN :Stykgodsvogn
+STR_805F_GRAIN_HOPPER :Kornvogn
+STR_8060_WOOD_TRUCK :Trævogn
+STR_8061_IRON_ORE_HOPPER :Jernmalmsvogn
+STR_8062_STEEL_TRUCK :Stålvogn
+STR_8063_ARMORED_VAN :Pansret vogn
+STR_8064_FOOD_VAN :Fødevarevogn
+STR_8065_PAPER_TRUCK :Papirvogn
+STR_8066_COPPER_ORE_HOPPER :Kobbermalmsvogn
+STR_8067_WATER_TANKER :Vandtanksvogn
+STR_8068_FRUIT_TRUCK :Frugtvogn
+STR_8069_RUBBER_TRUCK :Gummivogn
+STR_806A_SUGAR_TRUCK :Sukkervogn
+STR_806B_COTTON_CANDY_HOPPER :Candyflossvogn
+STR_806C_TOFFEE_HOPPER :Karamelvogn
+STR_806D_BUBBLE_VAN :Boblevogn
+STR_806E_COLA_TANKER :Colatankvogn
+STR_806F_CANDY_VAN :Slikvogn
+STR_8070_TOY_VAN :Legetøjsvogn
+STR_8071_BATTERY_TRUCK :Batterivogn
+STR_8072_FIZZY_DRINK_TRUCK :Sodavandsvogn
+STR_8073_PLASTIC_TRUCK :Plastikvogn
+STR_8074_MPS_REGAL_BUS :MPS Regal Bus
+STR_8075_HEREFORD_LEOPARD_BUS :Hereford Leopard Bus
+STR_8076_FOSTER_BUS :Foster Bus
+STR_8077_FOSTER_MKII_SUPERBUS :Foster MkII Superbus
+STR_8078_PLODDYPHUT_MKI_BUS :Ploddyphut MkI Bus
+STR_8079_PLODDYPHUT_MKII_BUS :Ploddyphut MkII Bus
+STR_807A_PLODDYPHUT_MKIII_BUS :Ploddyphut MkIII Bus
+STR_807B_BALOGH_COAL_TRUCK :Balogh Kullastbil
+STR_807C_UHL_COAL_TRUCK :Uhl Kullastbil
+STR_807D_DW_COAL_TRUCK :DW Kullastbil
+STR_807E_MPS_MAIL_TRUCK :MPS Postlastbil
+STR_807F_REYNARD_MAIL_TRUCK :Reynard Postlastbil
+STR_8080_PERRY_MAIL_TRUCK :Perry Postlastbil
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :MightyMover Postlastbil
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Powernaught Postlastbil
+STR_8083_WIZZOWOW_MAIL_TRUCK :Wizzowow Postlastbil
+STR_8084_WITCOMBE_OIL_TANKER :Witcombe Olietankbil
+STR_8085_FOSTER_OIL_TANKER :Foster Olietankbil
+STR_8086_PERRY_OIL_TANKER :Perry Olietankbil
+STR_8087_TALBOTT_LIVESTOCK_VAN :Talbott Kreaturlastbil
+STR_8088_UHL_LIVESTOCK_VAN :Uhl Kreaturlastbil
+STR_8089_FOSTER_LIVESTOCK_VAN :Foster Kreaturlastbil
+STR_808A_BALOGH_GOODS_TRUCK :Balogh Stykgodslastbil
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Craighead Stykgodslastbil
+STR_808C_GOSS_GOODS_TRUCK :Goss Stykgodslastbil
+STR_808D_HEREFORD_GRAIN_TRUCK :Hereford Kornlastbil
+STR_808E_THOMAS_GRAIN_TRUCK :Thomas Kornlastbil
+STR_808F_GOSS_GRAIN_TRUCK :Goss Kornlastbil
+STR_8090_WITCOMBE_WOOD_TRUCK :Witcombe Trælastbil
+STR_8091_FOSTER_WOOD_TRUCK :Foster Trælastbil
+STR_8092_MORELAND_WOOD_TRUCK :Moreland Trælastbil
+STR_8093_MPS_IRON_ORE_TRUCK :MPS Jernmalmslastbil
+STR_8094_UHL_IRON_ORE_TRUCK :Uhl Jernmalmslastbil
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Chippy Jernmalmslastbil
+STR_8096_BALOGH_STEEL_TRUCK :Balogh Stållastbil
+STR_8097_UHL_STEEL_TRUCK :Uhl Stållastbil
+STR_8098_KELLING_STEEL_TRUCK :Kelling Stållastbil
+STR_8099_BALOGH_ARMORED_TRUCK :Balogh Pansret Bil
+STR_809A_UHL_ARMORED_TRUCK :Uhl Pansret Bil
+STR_809B_FOSTER_ARMORED_TRUCK :Foster Pansret Bil
+STR_809C_FOSTER_FOOD_VAN :Foster Fødevarelastbil
+STR_809D_PERRY_FOOD_VAN :Perry Fødevarelastbil
+STR_809E_CHIPPY_FOOD_VAN :Chippy Fødevarelastbil
+STR_809F_UHL_PAPER_TRUCK :Uhl Papirlastbil
+STR_80A0_BALOGH_PAPER_TRUCK :Balogh Papirlastbil
+STR_80A1_MPS_PAPER_TRUCK :MPS Papirlastbil
+STR_80A2_MPS_COPPER_ORE_TRUCK :MPS Kobbermalmslastbil
+STR_80A3_UHL_COPPER_ORE_TRUCK :Uhl Kobbermalmslastbil
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Goss Kobbermalmslastbil
+STR_80A5_UHL_WATER_TANKER :Uhl Vandtankbil
+STR_80A6_BALOGH_WATER_TANKER :Balogh Vandtankbil
+STR_80A7_MPS_WATER_TANKER :MPS Vandtankbil
+STR_80A8_BALOGH_FRUIT_TRUCK :Balogh Frugtlastbil
+STR_80A9_UHL_FRUIT_TRUCK :Uhl Frugtlastbil
+STR_80AA_KELLING_FRUIT_TRUCK :Kelling Frugtlastbil
+STR_80AB_BALOGH_RUBBER_TRUCK :Balogh Gummilastbil
+STR_80AC_UHL_RUBBER_TRUCK :Uhl Gummilastbil
+STR_80AD_RMT_RUBBER_TRUCK :RMT Gummilastbil
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :MightyMover Sukkerlastbil
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Powernaught Sukkerlastbil
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Wizzowow Sukkerlastbil
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :MightyMover Colalastbil
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Powernaught Colalastbil
+STR_80B3_WIZZOWOW_COLA_TRUCK :Wizzowow Colalastbil
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :MightyMover Candyflosslastbil
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Powernaught Candyflosslastbil
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Wizzowow Candyflosslastbil
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :MightyMover Karamellastbil
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Powernaught Karamellastbil
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Wizzowow Karamellastbil
+STR_80BA_MIGHTYMOVER_TOY_VAN :MightyMover Legetøjslastbil
+STR_80BB_POWERNAUGHT_TOY_VAN :Powernaught Legetøjslastbil
+STR_80BC_WIZZOWOW_TOY_VAN :Wizzowow Legetøjslastbil
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :MightyMover Sliklastbil
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Powernaught Sliklastbil
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Wizzowow Sliklastbil
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :MightyMover Batterilastbil
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Powernaught Batterilastbil
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Wizzowow Batterilastbil
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :MightyMover Sodavandslastbil
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Powernaught Sodavandslastbil
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Wizzowow Sodavandslastbil
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :MightyMover Plastiklastbil
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Powernaught Plastiklastbil
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Wizzowow Plastiklastbil
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :MightyMover Bublelastlastbil
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Powernaught Bublelastlastbil
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Wizzowow Bublelastlastbil
+STR_80CC_MPS_OIL_TANKER :MPS Olietanker
+STR_80CD_CS_INC_OIL_TANKER :CS-Inc. Olietanker
+STR_80CE_MPS_PASSENGER_FERRY :MPS Passagerfærge
+STR_80CF_FFP_PASSENGER_FERRY :FFP Passagerfærge
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Bakewell 300 Luftpudebåd
+STR_80D1_CHUGGER_CHUG_PASSENGER :Chugger-Chug Passagerfærge
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Shivershake Passagerfærge
+STR_80D3_YATE_CARGO_SHIP :Yate Fragtskib
+STR_80D4_BAKEWELL_CARGO_SHIP :Bakewell Fragtskib
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Mightymover Fragtskib
+STR_80D6_POWERNAUT_CARGO_SHIP :Powernaut Fragtskib
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Tricario Helikopter
+STR_80FE_GURU_X2_HELICOPTER :Guru X2 Helikopter
+STR_80FF_POWERNAUT_HELICOPTER :Powernaut Helikopter
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Besked fra køretøjsfabrikken
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}Vi har lige designet en ny {STRING} - er du interesseret i et års ekslusiv testkørsel, så vi kan se hvordan den klarer sig inden vi gør den frit tilgængelig ?
+STR_8102_RAILROAD_LOCOMOTIVE :jernbanelokomotiv
+STR_8103_ROAD_VEHICLE :vejkøretøj
+STR_8104_AIRCRAFT :fly
+STR_8105_SHIP :skib
+STR_8106_MONORAIL_LOCOMOTIVE :monoraillokomotiv
+STR_8107_MAGLEV_LOCOMOTIVE :magnetskinnelokomotiv
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}{TOWN} Remise
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Indbyggerene fester . . .{}Første tog ankommer til {STATION}!
+STR_8802_DETAILS :{WHITE}{STRING} (Detaljer)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Tog i vejen
+STR_8804 :{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8806_GO_TO :GÃ¥ til {STATION}
+STR_8807_GO_TO_TRANSFER :Gå til {STATION} (Overfør og tag gods)
+STR_8808_GO_TO_UNLOAD :Gå til {STATION} (Aflæs)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Gå til {STATION} (Overfør og efterlad tom)
+STR_880A_GO_TO_LOAD :GÃ¥ til {STATION} (Fuld Last)
+STR_880B_GO_TO_TRANSFER_LOAD :Gå til {STATION} (Overfør og vent på fuld last)
+STR_880C_GO_NON_STOP_TO :GÃ¥ uden stop til {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Gå uden stop til {STATION} (Overfør og tag gods)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Gå uden stop til {STATION} (Aflæs)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Gå uden stop til {STATION} (Overfør og efterlad tom)
+STR_8810_GO_NON_STOP_TO_LOAD :GÃ¥ uden stop til {STATION} (Fuld Last)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Gå uden stop til {STATION} (Overfør og vent på fuld last)
+STR_GO_TO_TRAIN_DEPOT :GÃ¥ til {TOWN} Remise
+STR_SERVICE_AT_TRAIN_DEPOT :Service i {TOWN} Remise
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :GÃ¥ uden stop til {TOWN} Remise
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Service uden stop i {TOWN} Remise
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}Kører til {TOWN} Remise
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}Kører til {TOWN} Remise, {VELOCITY}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE :{LTBLUE}Eftersyn i {TOWN} remise
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE_VEL :{LTBLUE}Eftersyn i {TOWN} remise, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (Ugyldig Order)
+
+STR_UNKNOWN_DESTINATION :ukendt destination
+STR_8812_EMPTY :{LTBLUE}Tom
+STR_8813_FROM :{LTBLUE}{CARGO} fra {STATION}
+STR_FROM_MULT :{LTBLUE}{CARGO} fra {STATION} (x{NUM})
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}Tog {COMMA} venter i remise
+STR_8815_NEW_VEHICLES :{BLACK}Nye køretøjer
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Toget er for langt
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Tog kan kun ændres når de er stoppet i en remise
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} Tog
+
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Nye Jernbanekøretøjer
+STR_NEW_ELRAIL_VEHICLES :{WHITE}Nyt Elektrisk lokomotiv
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Nye Monorailkøretøjer
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Nye Magnetskinne køretøjer
+STR_ALL_AVAIL_RAIL_VEHICLES :{WHITE}Jernbanekøretøjer
+
+STR_881F_BUILD_VEHICLE :{BLACK}Byg Køretøj
+STR_CLONE_ROAD_VEHICLE :{BLACK}Klon køretøj
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}Dette vil bygge en kopi af køretøjet. Control-click vil dele ordre
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Dette vil bygge en kopi af køretøjet. Klik på denne knap, så på et køretøj indeni eller udenfor værkstedet. Control-click vil dele ordre
+STR_CLONE_TRAIN :{BLACK}Klon tog
+STR_CLONE_TRAIN_INFO :{BLACK}Dette vil bygge en kopi af toget inklusiv alle vogne. Control-click vil dele ordre
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}Dette vil bygge en kopi af toget inklusiv alle vogne. Klik på denne knap, så på et tog indeni eller udenfor remisen. Control-click vil dele ordre
+STR_8820_RENAME :{BLACK}Omdøb
+STR_8823_SKIP :{BLACK}Spring over
+STR_8824_DELETE :{BLACK}Slet
+STR_8825_NON_STOP :{BLACK}Uden stop
+STR_8826_GO_TO :{BLACK}GÃ¥ til
+STR_8827_FULL_LOAD :{BLACK}Fuld Last
+STR_8828_UNLOAD :{BLACK}Aflæs
+STR_REFIT :{BLACK}Ombyg
+STR_REFIT_TIP :{BLACK}Vælg hvilken lasttype der skal ombygges til i denne rækkefølge. CTRL+klik for at fjerne ombygningsinstruktion
+STR_REFIT_ORDER :(Ombyg til {STRING})
+STR_8829_ORDERS :{WHITE}{VEHICLE} (Ordre)
+STR_882A_END_OF_ORDERS :{SETX 10}- - Slut på ordre - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}Service
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Kan ikke bygge jernbanekøretøj...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Bygget: {LTBLUE}{NUM}{BLACK} Værdi: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Værdi: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}Læsser / Aflæsser
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}Toget skal være stoppet inde i en remise
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Kan ikke sende toget til remise...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Ikke mere plads til flere ordre
+STR_8832_TOO_MANY_ORDERS :{WHITE}For mange ordre
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Kan ikke indsætte ny ordre...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Kan ikke slette denne ordre...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Kan ikke ændre denne ordre...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Kan ikke flytte køretøjet...
+STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}Det bagerste lokomotiv vil altid følge dets forende
+STR_8838_N_A :N/A{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Kan ikke sælge jernbanekøretøjet...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Kan ikke finde en route til et lokalt depot
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Kan ikke stoppe/starte toget...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Serviceinterval: {LTBLUE}{COMMA}dage{BLACK} Sidste Service: {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Serviceinterval: {LTBLUE}{COMMA}%{BLACK} Sidste Service: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Tog - klik på et tog for information
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Byg nye tog (kræver en remise)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Tog - klik på et tog for information., træk vogn/lokomotiv for at fjerne/tilføje det til toget
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Byg nyt tog/togvogn
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Træk tog/togvogn her hend for at sælge
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centrer skærmen over placeringen af remisen
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Tog valgsliste - klik på et køretøj for mere information
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Byg det markerede lokomotiv/togvogn
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Omdøb tog-/togvognstypen
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Nuværende opførsel - klik her for at starte/stoppe toget
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Vis togets ordre
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centrer skærmen over togets placering
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Send toget til remise. CTRL+klik for kun eftersyn
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Tving toget til at fortsætte uden at vente på at signalet skifter til grønt
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Vend retningen af toget
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Vis detaljer om toget
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Forøg serviceintervallet
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Sænk serviceintervallet
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Vis detaljer omkring den last der medbringes
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Vis detaljer omkring toget/vognene
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Vis kapaciteten af hver togvogn
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Vis total lasteevne på toget, fordelt på lasttyper
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Ordreliste - klik på en ordre for at markere den
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}Spring over den nuværende ordre og gå til den næste
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Slet den markerede ordre
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Lav den markerede ordre til en "uden stop" ordre
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Indsæt en ny ordre før den markerede eller ved slutningen af ordrelisten
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Få den markerede ordre til at tvinge toget til at vente på en fuld last
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Få den markerede ordre til at tvinge toget til at aflæsse
+STR_SERVICE_HINT :{BLACK}Spring denne ordre over hvis der ikke er behov for service
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}Ny {STRING} tilgængelig nu!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Pris: {CURRENCY} Vægt: {WEIGHT_S}{}Hastighed: {VELOCITY} Styrke: {POWER}{}Driftsomkostninger: {CURRENCY}/år{}Kapacitet: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}GÃ¥et i stykker
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}Alder: {LTBLUE}{STRING}{BLACK} Kørselsomkostning: {LTBLUE}{CURRENCY}/år
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Vægt: {LTBLUE}{WEIGHT_S} {BLACK}Styrke: {LTBLUE}{POWER}{BLACK} Maks. hastighed: {LTBLUE}{VELOCITY}
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Vægt: {LTBLUE}{WEIGHT_S} {BLACK}Kraft: {LTBLUE}{POWER}{BLACK} Maks. hastighed: {LTBLUE}{VELOCITY} {BLACK}Maks. trækkraft: {LTBLUE}{FORCE}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Dette års profit: {LTBLUE}{CURRENCY} (sidste år: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}PÃ¥lidelighed {LTBLUE}{COMMA}% {BLACK}nedbrud siden sidste service: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Stoppet
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Kan ikke få toget til at passere signalet...
+STR_8863_CRASHED :{RED}Forulykket!
+
+STR_8865_NAME_TRAIN :{WHITE}Giv toget et navn
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}Kan ikke give toget navn...
+STR_8867_NAME_TRAIN :{BLACK}Giv toget et navn
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Tog forulykket!{}{COMMA} døde i flammerne efter kollision
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Kan ikke vende retningen af toget...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Omdøb tog-/togvognstypen
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Kan ikke omdøbe tog-/togvognstypen...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Få den valgte ordre til at tvinge køretøjet til at smide lasten
+STR_886F_TRANSFER :{BLACK}Transfer
+
+STR_TRAIN_STOPPING :{RED}Stopper
+STR_TRAIN_STOPPING_VEL :{RED}Stopper, {VELOCITY}
+STR_INCOMPATIBLE_RAIL_TYPES :Skinnetyperne passer ikke sammen
+STR_TRAIN_NO_POWER :{RED}Ingen strøm
+STR_TRAIN_START_NO_CATENARY :Toget kan ikke køre, fordi sporet ikke har køreledninger
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Køretøj i vejen
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} Køretøj{P "" er}
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}{TOWN} Værksted
+STR_9004_NEW_VEHICLES :{BLACK}Nye køretøjer
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}Nye køretøjer
+STR_9007_BUILD_VEHICLE :{BLACK}Byg køretøj
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Kan ikke bygge køretøj...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (Detaljer)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}Alder: {LTBLUE}{STRING}{BLACK} Kørselsomkostning: {LTBLUE}{CURRENCY}/år
+STR_900E_MAX_SPEED :{BLACK}Maks. hastighed: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Dette års profit: {LTBLUE}{CURRENCY} (sidste år: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}PÃ¥lidelighed: {LTBLUE}{COMMA}% {BLACK}Nedbrud siden sidste service: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Bygget: {LTBLUE}{NUM}{BLACK} Værdi: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Kapacitet: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}...skal være stoppet inde i et værksted først
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Kan ikke sælge køretøj...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Kan ikke stoppe/starte køretøj...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}Køretøj {COMMA} venter i værksted
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}Kører til {TOWN} Værksted
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}Kører til {TOWN} Værksted, {VELOCITY}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE :{LTBLUE}Eftersyn på {TOWN} værksted
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE_VEL :{LTBLUE}Eftersyn på {TOWN} værksted, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Kan ikke sende køretøj til værksted...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Kan ikke finde lokalt værksted
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Køretøjer - klik på et køretøj for information
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Byg nye køretøjer (kræver et værktøj)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Nuværende opførsel - klik her for at stoppe/starte køretøjet
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Vis køretøjets ordrer
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Centrer skærmen over placeringen af køretøjet
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Send køretøjet til værksted
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Tving køretøjet til at vende
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Vis køretøjets detaljer
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Køretøjer - klik på et køretøj for mere information
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Byg nyt køretøj
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Træk køretøjet herhen for at sælge
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Centrer skærmen over placeringen af værkstedet
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Liste over køretøjstyper - klik på køretøj for information
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Byg det markerede køretøj
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}Nyt køretøj er tilgængeligt!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Pris: {CURRENCY}{}Hastighed: {VELOCITY}{}Kørselsomkostning: {CURRENCY}/år{}Kapacitet: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Giv køretøjet et navn
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Kan ikke give køretøjet et navn...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Giv køretøjet et navn
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Indbyggerne fester . . .{}Første bus ankommer til {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Indbyggerne fester . . .{}Første lastbil ankommer til {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}Lastbil forulykket!{}Chaufføren død i flammerne efter at være kollideret med et tog!
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}Bus forulykket!{}{COMMA} dør i flammerne efter kollision med et tog
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Kan ikke få køretøjet til at vende...
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}Kan ikke vende et køretøg, der består af flere enheder
+STR_9034_RENAME :{BLACK}Omdøb
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Omdøb køretøjstypen
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Omdøb køretøjstypen
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Kan ikke omdøbe køretøjstypen...
+STR_9038_GO_TO_ROADVEH_DEPOT :Gå til {TOWN} Værksted
+STR_SERVICE_AT_ROADVEH_DEPOT :Service i {TOWN} Værksted
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Ombyg vejkøretøj til at laste en anden type last
+STR_REFIT_ROAD_VEHICLE :{BLACK}Ombyg lastbil
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Ombyg vejkøretøjet til at laste den markede type last
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Kan ikke ombygge vejkøretøj
+STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Vælg lasttype som lastbilen skal transportere
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Havnekonstruktion
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Havnekonstruktion
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Kan ikke bygge en havn her...
+STR_9803_SHIP_DEPOT :{WHITE}{TOWN} Dok
+STR_9804_NEW_SHIPS :{BLACK}Nye skibe
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} Skibe
+STR_9808_NEW_SHIPS :{WHITE}Nye skibe
+STR_9809_BUILD_SHIP :{BLACK}Byg skib
+STR_CLONE_SHIP :{BLACK}Klon skib
+STR_CLONE_SHIP_INFO :{BLACK}Dette vil bygge en kopi af skibet. Control-click vil dele ordre
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}Dette vil bygge en kopi af skibet. Klik på denne knap så, på et skib indeni eller udenfor dokken. Control-click vil dele ordre
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}Skibet skal være stoppet i dok
+STR_980C_CAN_T_SELL_SHIP :{WHITE}Kan ikke sælge skibet...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Kan ikke bygge skibet...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Der er et skib i vejen
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Detaljer)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}Alder: {LTBLUE}{STRING}{BLACK} Kørselsomkostning: {LTBLUE}{CURRENCY}/år
+STR_9813_MAX_SPEED :{BLACK}Maks. hastighed: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Dette års profit: {LTBLUE}{CURRENCY} (sidste år: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}PÃ¥lidelighed: {LTBLUE}{COMMA}% {BLACK}Nedbrud siden sidste service: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Bygget: {LTBLUE}{NUM}{BLACK} Værdi: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}Kapacitet: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}Kan ikke stoppe/starte skibet...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Kan ikke sende skibet til dok...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Kan ikke finde lokal dok
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}Sejler til {TOWN} Dok
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}Sejler til {TOWN} Dok, {VELOCITY}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE :{LTBLUE}Eftersyn i {TOWN} skibsdok
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE_VEL :{LTBLUE}Eftersyn i {TOWN} skibsdok, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}Skib {COMMA} venter i dok
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Byg havn
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Byg skibsdok (til bygning og servicering af skibe)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Skibe - klik på et skib for information
+STR_9820_BUILD_NEW_SHIP :{BLACK}Byg nyt skib
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Træk det her for at sælge det
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centrer skærmen over placeringen af skibsdokken
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Skibe - klik på et skib for information
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Byg nye skibe (kræver en dok)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}Skibstypeliste - klik på skibstype for information
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Byg det markerede skib
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Nuværende opførsel - klik her for at starte/stoppe skibet
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Vis skibets ordrer
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centrer skærmen over skibets placering
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Send skibet til dok. CTRL+klik for kun eftersyn
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Vis detaljer omkring skibet
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}Nyt skib er tilgængeligt!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Pris: {CURRENCY} Maks. hastighed: {VELOCITY}{}Kapacitet: {CARGO}{}Kørselsomkostning: {CURRENCY}/år
+STR_982F_NAME_SHIP :{BLACK}Giv skibet et navn
+
+STR_9831_NAME_SHIP :{WHITE}Giv skibet et navn
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Kan ikke give skibet et navn...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Indbyggere fester . . .{}Første skib ankommer til {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Positionsbøje, kan bruges som yderligere navigationspunkt
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Kan ikke placere en bøje her...
+STR_9836_RENAME :{BLACK}Omdøb
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Omdøb skibstypen
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Omdøb skibstypen
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Kan ikke omdøbe skibstypen...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Ombyg skibet til at sejle med en anden slags last
+STR_983B_REFIT :{WHITE}{VEHICLE} (Ombyg)
+STR_983C_REFIT_SHIP :{BLACK}Ombyg skibet
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Vælg den slags last skibet skal sejle med
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Ombyg skibet til den markerede slags last
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Vælg den lasttype der skal sejles med:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Ny kapacitet: {GOLD}{CARGO}{}{BLACK}Pris for ombyggelse: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Kan ikke ombygge skib...
+STR_9842_REFITTABLE :(ombygning mulig)
+STR_GO_TO_SHIP_DEPOT :Sejl til {TOWN} Dok
+SERVICE_AT_SHIP_DEPOT :Service i {TOWN} Skibsdok
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Lufthavne
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Kan ikke bygge en lufthavn her...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} Flyhangar
+STR_A003_NEW_AIRCRAFT :{BLACK}Nyt fly
+STR_CLONE_AIRCRAFT :{BLACK}Klon fly
+STR_CLONE_AIRCRAFT_INFO :{BLACK}Dette vil bygge en kopi af et fly. Control-click vil dele ordre
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Dette vil bygge en kopi af et fly. Klik på denne knap, så på et fly indeni eller udenfor hangaren. Control-click vil dele ordre
+STR_A005_NEW_AIRCRAFT :{WHITE}Nyt fly
+STR_A006_BUILD_AIRCRAFT :{BLACK}Byg et fly
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Kan ikke bygge fly...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} Fly
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (Ordre)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (Detaljer)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Alder: {LTBLUE}{STRING}{BLACK} Kørselsomkostning: {LTBLUE}{CURRENCY}/år
+STR_A00E_MAX_SPEED :{BLACK}Maks. hastighed: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Dette års profit: {LTBLUE}{CURRENCY} (sidste år: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}PÃ¥lidelighed: {LTBLUE}{COMMA}% {BLACK}Nedbrud siden sidste service: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Bygget: {LTBLUE}{NUM}{BLACK} Værdi: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Kan ikke sende flyet til en hangar...
+STR_HEADING_FOR_HANGAR :{ORANGE}Flyver til {STATION} Hangar
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}Flyver til {STATION} Hangar, {VELOCITY}
+STR_HEADING_FOR_HANGAR_SERVICE :{LTBLUE}Eftersyn i {STATION} hangar
+STR_HEADING_FOR_HANGAR_SERVICE_VEL :{LTBLUE}Eftersyn i {STATION} hangar, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}Fly {COMMA} venter i flyhangar
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Fly i vejen
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Kan ikke stoppe/starte fly...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Flyet er i luften
+STR_A019_CAPACITY :{BLACK}Kapacitet: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Kapacitet: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}Flyet skal være stoppet i en flyhangar
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Kan ikke sælge flyet...
+STR_A01D_AIRPORT_CONSTRUCTION :Lufthavnskonstruktion
+STR_A01E_BUILD_AIRPORT :{BLACK}Byg en lufthavn
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Fly - klik på et fly for information
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Byg nyt fly (kræver en lufthavn med hangar)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Fly - klik på et fly for information
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Byg nyt fly
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}Træk fly herhend for at sælge
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Centrer skærmen over placeringen af hangaren
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Flytypeliste - klik på en flytype for mere information
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Byg det markerede fly
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Nuværende opførsel - klik her for at starte/stoppe flyet
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Vis flyets ordre
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Centrer skærmen over placeringen af flyet
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Send flyet til en hangar
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Vis detaljet omkring flyet
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}Nyt fly tilgængeligt!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Pris: {CURRENCY} Maks. hastighed: {VELOCITY}{}Kapacitet: {COMMA} passagerer, {COMMA} sække post{}Kørselsomkostning: {CURRENCY}/år
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Navngiv flyet
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Kan ikke navngive flyet...
+STR_A032_NAME_AIRCRAFT :{BLACK}Navngiv fluet
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Indbyggerene fester . . .{}Første fly ankommer til{STATION}!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Flystyrt!{}{COMMA} dør i flammerne ved {STATION}
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Flystyrt!{}Fly løb tør for brændstof, {COMMA} døde i ildhelvede!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Omdøb
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Ømdøb flytypen
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Ømdøb flytypen
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Kan ikke omdøbe flytypen...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Ombyg flyet til at flyve med en anden slags last
+STR_A03C_REFIT :{WHITE}{VEHICLE} (Ombyg)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Ombyg fly
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Vælg den type last flyet skal flyve med
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Ombyg flyet til at flyve med den markerede slags last
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Vælg den type last der skal flyves med:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Ny kapacitet: {GOLD}{STRING}{}{BLACK}Ombygningspris: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Kan ikke ombygge fly...
+STR_GO_TO_AIRPORT_HANGAR :Flyv til {STATION} Hangar
+SERVICE_AT_AIRPORT_HANGAR :Service i {STATION} Hangar
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}Zeppelin katastrofe ved {STATION}!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Lastbil ødelagt i kollision med en UFO
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}Eksplosion af olieraffinaderi ved {TOWN}!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}Fabrik ødelagt under mystiske omstændigheder ved {TOWN}!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}En UFO lander tæt på {TOWN}!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}Sammenstyrtning af kulmine efterlader et spor af katastrofe ved {TOWN}!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Oversvømmelse!{}Mindst {COMMA} savnet og antages omkommet efter pludselig oversvømmelse!
+
+STR_BRIBE_FAILED :{WHITE}Dit forsøg på bestikkelse er blevet
+STR_BRIBE_FAILED_2 :{WHITE}opdaget af en inspektør.
+STR_BUILD_DATE :{BLACK}Produceret: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Præstations oversigt
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}Detailer
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Køretøjer:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Stationer:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Minimum profit:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Minimum indkomst:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Maks. indtægt:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Afleveret:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Last:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Penge:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}LÃ¥n:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Total:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Antal af køretøjer; dette inkludere vejkøretøjer, tog, skibe og fly
+STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}Antallet af stationer. Alle dele af en station (f.eks. tog station, bus station, lufthavn) tæller med, også selvom de er sat sammen til en station
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}Profit for det køretøj med lavest indkomst (af alle køretøjer ældre end 2 år)
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Indkomst i den måned med lavest profit i de sidste 12 kvartaler
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Indkomst i den måned med højest profit i de sidste 12 kvartaler
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}Antal enheder fragtet i de sidste 4 kvartaler
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}Antallet af lasttyper fragtet i sidste kvartal
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Kapital denne virksomhed har i banken
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}Har du et stort lån?
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Samlet point af max point
+
+STR_NEWGRF_SETTINGS_BUTTON :{BLACK}NewGRF indstillinger
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}NewGRF indstillinger
+STR_NEWGRF_APPLY_CHANGES :{BLACK}Anvend ændringer
+STR_NEWGRF_SET_PARAMETERS :{BLACK}Indstil parameter
+STR_NEWGRF_TIP :{BLACK}Liste med alle Newgrf sæt du har installeret. Marker et sæt for at ændre indstilliger.
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}Der er ingen newgrf filer installeret! Læs venligst om installation af nye grafiksæt i manualen
+STR_NEWGRF_FILENAME :{BLACK}Filnavn: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
+STR_NEWGRF_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING}
+STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}Du er ved at lave ændringer i et igangværende spil; dette kan få OpenTTD til at gå ned.{}Er du helt sikker på at du vil fortsætte?
+
+STR_NEWGRF_ADD :{BLACK}Tilføj
+STR_NEWGRF_ADD_TIP :{BLACK}Tilføj et NewGRF sæt til listen
+STR_NEWGRF_REMOVE :{BLACK}Fjern
+STR_NEWGRF_REMOVE_TIP :{BLACK}Fjern det valgte NewGRF sæt fra listen
+STR_NEWGRF_MOVEUP :{BLACK}Flyt op
+STR_NEWGRF_MOVEUP_TIP :{BLACK}Flyt det valgte NewGRF sæt op i listen
+STR_NEWGRF_MOVEDOWN :{BLACK}Flyt ned
+STR_NEWGRF_MOVEDOWN_TIP :{BLACK}Flyt det valgte NewGRF sæt ned i listen
+STR_NEWGRF_FILE_TIP :{BLACK}En liste over de NewGRF sæt der er installeret. Klik på et sæt for at ændre dets parameter
+STR_NEWGRF_PARAMETER :{BLACK}Parameter: {SILVER}{STRING}
+STR_NEWGRF_PARAMETER_QUERY :{BLACK}Indtast NewGRF-parameter
+STR_NEWGRF_NO_INFO :{BLACK}Ingen information tilgængelig
+
+STR_NEWGRF_ADD_CAPTION :{WHITE}Tilgængelige NewGRF sæt
+STR_NEWGRF_ADD_FILE :{BLACK}Tilføj til udvalg
+STR_NEWGRF_ADD_FILE_TIP :{BLACK}Tilføj det valgte NewGRF sæt til din konfiguration
+STR_NEWGRF_RESCAN_FILES :{BLACK}Genfind filer
+STR_NEWGRF_RESCAN_FILES_TIP :{BLACK}Opdater listen over tilgængelige NewGRF sæt
+STR_NEWGRF_DUPLICATE_GRFID :{WHITE}Kan ikke tilføje sæt: dobbelt GRF ID
+
+STR_NEWGRF_NOT_FOUND :{RED}Tilsvarende fil blev ikke fundet
+STR_NEWGRF_DISABLED :{RED}Deaktiveret
+
+STR_CURRENCY_WINDOW :{WHITE}Brugerdefineret møntfod
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Kurs: {ORANGE}{CURRENCY} = £ {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Tilskuer:
+STR_CURRENCY_PREFIX :{LTBLUE}Præfiks:
+STR_CURRENCY_SUFFIX :{LTBLUE}Endetillæg:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Skift til Euro: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Skift til Euro: {ORANGE}aldrig
+STR_CURRENCY_PREVIEW :{LTBLUE}Eksempel: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Skift brugerdefineret møntfods parametre
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} Tog{P "" e}
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} Køretøj{P "" er}
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} Fly
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} Skib{P "" e}
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Vis alle tog, som har denne station i deres køreplan
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Vis alle køretøjer, som har denne station i deres køreplan
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Vis alle fly, som har denne lufthavn i deres ruteplan
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Vis alle skibe, som har denne station i deres ruteplan
+
+STR_VEH_WITH_SHARED_ORDERS_LIST :{WHITE}Delte ordrer af {COMMA} transportmid{P del ler}
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}Vis alle transportmidler, som har den samme rute
+
+### depot strings
+STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Du er ved at sælge alle køretøjer i depotet. Er du sikker?
+
+STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP :{BLACK}Sælg alle toge i remisen
+STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP :{BLACK}Sælg alle køretøjer i værkstedet
+STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP :{BLACK}Sælg alle skibe i dokken
+STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP :{BLACK}Sælg alle fly i hangaren
+
+STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP :{BLACK}FÃ¥ vist en liste over alle toge med denne remise i deres ordreliste
+STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP :{BLACK}Få vist en liste over alle køretøjer med dette værksted i deres ordreliste
+STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP :{BLACK}FÃ¥ vist en liste over alle skibe med denne dok i deres ordreliste
+STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP :{BLACK}FÃ¥ vist en liste over alle fly med en hangar ved denne lufthavn i deres ordreliste
+
+STR_DEPOT_AUTOREPLACE_TRAIN_TIP :{BLACK}Udskift automatisk all toge i remisen
+STR_DEPOT_AUTOREPLACE_ROADVEH_TIP :{BLACK}Udskift automatisk alle køretøjer i værkstedet
+STR_DEPOT_AUTOREPLACE_SHIP_TIP :{BLACK}Udskift automatisk alle skibe i dokken
+STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP :{BLACK}Udskift automatisk alle fly i hangaren
+
+STR_VEHICLE_LIST_TRAIN_DEPOT :{BLACK}{STRING} - {COMMA} Tog{P "" e}
+STR_VEHICLE_LIST_ROADVEH_DEPOT :{BLACK}{STRING} - {COMMA} Køretøj{P "" er}
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} Skib{P "" e}
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} Fly
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}Udskift {STRING}
+STR_REPLACE_VEHICLES_START :{BLACK}Start udskiftning
+STR_REPLACE_VEHICLES_STOP :{BLACK}Stop udskiftning
+STR_NOT_REPLACING :{BLACK}Udskifter ikke
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Intet køretøj valgt
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Vælg en køretøjstype, som du ønsker udskiftet
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Vælg en køretøjstype, som du ønker at få i stedet for den type, du har valgt i venste side
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Tryk for at stoppe udskiftningen at den køretøjstype, som du har valgt til venstre
+STR_REPLACE_HELP_START_BUTTON :{BLACK}Tryk for at begynde at udskifte køretøjstypen til venstre med køretøjstypen til højre
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Vælg den skinnetype, hvor du vil udskifte lokomotiver
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Viser hvilket køretøj det valgte køretøj til venstre bliver udskiftet med, hvis det udskiftes
+STR_REPLACE_HELP :{BLACK}Dette giver dig mulighed for at udskifte en køretøjstype med en anden, når et køretøj af den oprindelige type kører i depot
+STR_REPLACE_REMOVE_WAGON :{BLACK}Fjern vogn: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Få autoudskift til at bevare længden af tog ved at fjerne vogne (startende fra fronten), hvis autoudskiftningen gør toget længere.
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}Udskifter: {ORANGE}{SKIP}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} EKSPERIMENTEL EGENSKAB {}Skift imellem lokomotiv- og vogn-udskiftningsvindue.{}Vognudskiftning vil kun finde sted hvis den nye vogn kan ændres til at transportere samme godstype some den gamle vogn. Dette bliver checket for hver vogn, når udskiftningen finder sted.
+STR_ENGINE_NOT_BUILDABLE :{WHITE}Køretøjet kan ikke bygges
+
+STR_ENGINES :Lokomotiver
+STR_WAGONS :Vogne
+
+STR_MASS_STOP_DEPOT_TRAIN_TIP :{BLACK}Klik for at stoppe alle toge i remisen
+STR_MASS_STOP_DEPOT_ROADVEH_TIP :{BLACK}Klik for at stoppe alle køretøjer i værkstedet
+STR_MASS_STOP_DEPOT_SHIP_TIP :{BLACK}Klik for at stoppe alle skibe i dokken
+STR_MASS_STOP_HANGAR_TIP :{BLACK}Klik for at stoppe alle fly i hangaren
+
+STR_MASS_START_DEPOT_TRAIN_TIP :{BLACK}Klik for at starte alle toge i remisen
+STR_MASS_START_DEPOT_ROADVEH_TIP :{BLACK}Klik for at starte alle køretøjer i værkstedet
+STR_MASS_START_DEPOT_SHIP_TIP :{BLACK}Klik for at starte alle skibe i dokken
+STR_MASS_START_HANGAR_TIP :{BLACK}Klik for at starte alle fly i hangaren
+
+STR_MASS_STOP_LIST_TIP :{BLACK}Klik for at stoppe alle køretøjer i listen
+STR_MASS_START_LIST_TIP :{BLACK}Klik for at starte alle køretøjer i listen
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}Liste over skilte - {COMMA} Skilt{P "" e}
+
+STR_ORDER_REFIT_FAILED :{WHITE}Ombygningsordre stoppet pga. fejl {STRING} {COMMA}
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :Jernbane
+STR_ELRAIL_VEHICLES :Eltog
+STR_MONORAIL_VEHICLES :Monorail
+STR_MAGLEV_VEHICLES :Magnetskinnetog
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Pris: {GOLD}{CURRENCY}{BLACK} Vægt: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Hastighed: {GOLD}{VELOCITY}{BLACK} Styrke: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}Hastighed: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Kørselsudgift: {GOLD}{CURRENCY}/år
+STR_PURCHASE_INFO_CAPACITY :{BLACK}Lasteevne: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Designet: {GOLD}{NUM}{BLACK} Levealder: {GOLD}{COMMA} år
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}Maks. pålidelighed: {GOLD}{COMMA}%
+STR_PURCHASE_INFO_COST :{BLACK}Pris: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Vægt: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Pris: {GOLD}{CURRENCY}{BLACK} Hastighed: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Lasteevne: {GOLD}{COMMA} passagerer, {COMMA} sække post
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Motoriserede Vogne: {GOLD}+{POWER}{BLACK} Vægt: {GOLD}+{WEIGHT_S}
+STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Kan ombygges til: {GOLD}
+STR_PURCHASE_INFO_ALL_TYPES :Alle lasttyper
+STR_PURCHASE_INFO_ALL_BUT :Alle undtagen {GOLD}
+STR_PURCHASE_INFO_MAX_TE :{BLACK}Maks. trækkraft: {GOLD}{FORCE}
+
+########### String for New Landscape Generator
+
+STR_GENERATE :{WHITE}Generer
+STR_RANDOM :{BLACK}Tilfældig
+STR_RANDOM_HELP :{BLACK}Ændre den tilfældige værdi ved brug i terrængeneratoren
+STR_WORLD_GENERATION_CAPTION :{WHITE}Verdensgenerering
+STR_RANDOM_SEED :{BLACK}Tilfældig
+STR_RANDOM_SEED_HELP :{BLACK}Klik for at angive tilfældighed
+STR_LAND_GENERATOR :{BLACK}Terrængenerator:
+STR_TREE_PLACER :{BLACK}Træalgoritme:
+STR_HEIGHTMAP_ROTATION :{BLACK}Højdekortets rotation:
+STR_TERRAIN_TYPE :{BLACK}Terræntype:
+STR_QUANTITY_OF_SEA_LAKES :{BLACK}Havniveau
+STR_SMOOTHNESS :{BLACK}Blødhed:
+STR_SNOW_LINE_HEIGHT :{BLACK}Snegrænse
+STR_DATE :{BLACK}Dato:
+STR_NUMBER_OF_TOWNS :{BLACK}Antal byer:
+STR_NUMBER_OF_INDUSTRIES :{BLACK}Antal industrier:
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_SNOW_LINE_UP :{BLACK}Flyt snegrænsen een op
+STR_SNOW_LINE_DOWN :{BLACK}Flyt snegrænsen een ned
+STR_SNOW_LINE_QUERY_CAPT :{WHITE}Ændre snegrænsen
+STR_START_DATE_QUERY_CAPT :{WHITE}Ændre startår
+STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Skalerings advarsel
+STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}At ændre størrelsen på kildebilledet anbefales ikke. Fortsæt genereringen?
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_HEIGHTMAP_NAME :{BLACK}Højdekortets navn:
+STR_HEIGHTMAP_SIZE :{BLACK}Størrelse: {ORANGE}{NUM} x {NUM}
+STR_GENERATION_WORLD :{WHITE}Genererer verden...
+STR_GENERATION_ABORT :{BLACK}Afbryd
+STR_GENERATION_ABORT_CAPTION :{WHITE}Afbryd Kortgenereringen
+STR_GENERATION_ABORT_MESSAGE :{YELLOW}Vil du virkelig afbryde kortgenereringen?
+STR_PROGRESS :{WHITE}{NUM}% færdig
+STR_GENERATION_PROGRESS :{BLACK}{NUM} / {NUM}
+STR_WORLD_GENERATION :{BLACK}Verdensgenerering
+STR_TREE_GENERATION :{BLACK}Trægenerering
+STR_UNMOVABLE_GENERATION :{BLACK}Ikke-flytbar generering
+STR_CLEARING_TILES :{BLACK}Generer råt og stenet område
+STR_SETTINGUP_GAME :{BLACK}Klargør spil
+STR_PREPARING_TILELOOP :{BLACK}Kører flise-løkken
+STR_PREPARING_GAME :{BLACK}Forbereder spil
+STR_DIFFICULTY_TO_CUSTOM :{WHITE}Denne handling ændrer sværhedsgraden til speciel
+STR_SE_FLAT_WORLD :{WHITE}Fladt land
+STR_SE_FLAT_WORLD_TIP :{BLACK}Generér fladt land
+STR_SE_RANDOM_LAND :{WHITE}Tilfældigt land
+STR_SE_NEW_WORLD :{BLACK}Opret nyt scenarie
+STR_SE_CAPTION :{WHITE}Scenarietype
+STR_FLAT_WORLD_HEIGHT_DOWN :{BLACK}Flyt højden af fladt land en ned
+STR_FLAT_WORLD_HEIGHT_UP :{BLACK}Flyt højden af fladt land en op
+STR_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Ændre højden af fladt land
+STR_FLAT_WORLD_HEIGHT :{BLACK}Højde af fladt land:
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+STR_SMALLMAP_CENTER :{BLACK}Centrer det lille kort ved den nuværende position
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}Lille
+STR_CITY_AIRPORT :{BLACK}By
+STR_METRO_AIRPORT :{BLACK}Metropollufthavn
+STR_INTERNATIONAL_AIRPORT :{BLACK}International lufthavn
+STR_COMMUTER_AIRPORT :{BLACK}Pendler
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}International
+STR_HELIPORT :{BLACK}Helikopterlandingsplads
+STR_HELIDEPOT :{BLACK}Helikopterværksted
+STR_HELISTATION :{BLACK}Helikopterplads
+
+STR_SMALL_AIRPORTS :{BLACK}Små lufthavne
+STR_LARGE_AIRPORTS :{BLACK}Store lufthavne
+STR_HUB_AIRPORTS :{BLACK}Central lufthavn
+STR_HELIPORTS :{BLACK}Helikopterlufthavn
+
+############ Tooltip measurment
+
+STR_MEASURE_LENGTH :{BLACK}Længde: {NUM}
+STR_MEASURE_AREA :{BLACK}Areal: {NUM} x {NUM}
+STR_MEASURE_LENGTH_HEIGHTDIFF :{BLACK}Længde: {NUM}{}Højdeforskel: {NUM} m
+STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}Areal: {NUM} x {NUM}{}Højdeforskel: {NUM} m
+
+########
diff --git a/src/lang/dutch.txt b/src/lang/dutch.txt
new file mode 100644
index 000000000..67e4f99e0
--- /dev/null
+++ b/src/lang/dutch.txt
@@ -0,0 +1,3116 @@
+##name Dutch
+##ownname Nederlands
+##isocode nl_NL.UTF-8
+##plural 0
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Buiten de kaart
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Te dicht bij de rand van de kaart
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Niet genoeg geld - {CURRENCY} nodig
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Vlak land nodig
+STR_0008_WAITING :{BLACK}Wachtend: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (onderweg uit
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Accepteert: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Accepteert: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :Passagiers
+STR_0010_COAL :Kolen
+STR_0011_MAIL :Post
+STR_0012_OIL :Olie
+STR_0013_LIVESTOCK :Vee
+STR_0014_GOODS :Goederen
+STR_0015_GRAIN :Graan
+STR_0016_WOOD :Hout
+STR_0017_IRON_ORE :IJzererts
+STR_0018_STEEL :Staal
+STR_0019_VALUABLES :Kostbaarheden
+STR_001A_COPPER_ORE :Kopererts
+STR_001B_MAIZE :Maïs
+STR_001C_FRUIT :Fruit
+STR_001D_DIAMONDS :Diamanten
+STR_001E_FOOD :Voedsel
+STR_001F_PAPER :Papier
+STR_0020_GOLD :Goud
+STR_0021_WATER :Water
+STR_0022_WHEAT :Tarwe
+STR_0023_RUBBER :Rubber
+STR_0024_SUGAR :Suiker
+STR_0025_TOYS :Speelgoed
+STR_0026_CANDY :Snoep
+STR_0027_COLA :Cola
+STR_0028_COTTON_CANDY :Suikerspinnen
+STR_0029_BUBBLES :Bellen
+STR_002A_TOFFEE :Toffee
+STR_002B_BATTERIES :Batterijen
+STR_002C_PLASTIC :Plastic
+STR_002D_FIZZY_DRINKS :Frisdrank
+STR_002E :
+STR_002F_PASSENGER :Passagier
+STR_0030_COAL :Kolen
+STR_0031_MAIL :Post
+STR_0032_OIL :Olie
+STR_0033_LIVESTOCK :Vee
+STR_0034_GOODS :Goederen
+STR_0035_GRAIN :Graan
+STR_0036_WOOD :Hout
+STR_0037_IRON_ORE :IJzererts
+STR_0038_STEEL :Staal
+STR_0039_VALUABLES :Kostbaarheden
+STR_003A_COPPER_ORE :Kopererts
+STR_003B_MAIZE :Maïs
+STR_003C_FRUIT :Fruit
+STR_003D_DIAMOND :Diamant
+STR_003E_FOOD :Voedsel
+STR_003F_PAPER :Papier
+STR_0040_GOLD :Goud
+STR_0041_WATER :Water
+STR_0042_WHEAT :Tarwe
+STR_0043_RUBBER :Rubber
+STR_0044_SUGAR :Suiker
+STR_0045_TOY :Speelgoed
+STR_0046_CANDY :Snoep
+STR_0047_COLA :Cola
+STR_0048_COTTON_CANDY :Suikerspin
+STR_0049_BUBBLE :Bel
+STR_004A_TOFFEE :Toffee
+STR_004B_BATTERY :Batterij
+STR_004C_PLASTIC :Plastic
+STR_004D_FIZZY_DRINK :Frisdrank
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} passagier{P "" s}
+STR_QUANTITY_COAL :{WEIGHT} kolen
+STR_QUANTITY_MAIL :{COMMA} zak{P "" ken} post
+STR_QUANTITY_OIL :{VOLUME} olie
+STR_QUANTITY_LIVESTOCK :{COMMA} stuk{P "" s} vee
+STR_QUANTITY_GOODS :{COMMA} pallet{P "" s} goederen
+STR_QUANTITY_GRAIN :{WEIGHT} graan
+STR_QUANTITY_WOOD :{WEIGHT} hout
+STR_QUANTITY_IRON_ORE :{WEIGHT} ijzererts
+STR_QUANTITY_STEEL :{WEIGHT} staal
+STR_QUANTITY_VALUABLES :{COMMA} zak{P "" ken} kostbaarheden
+STR_QUANTITY_COPPER_ORE :{WEIGHT} kopererts
+STR_QUANTITY_MAIZE :{WEIGHT} maïs
+STR_QUANTITY_FRUIT :{WEIGHT} fruit
+STR_QUANTITY_DIAMONDS :{COMMA} zak{P "" ken} diamanten
+STR_QUANTITY_FOOD :{WEIGHT} voedsel
+STR_QUANTITY_PAPER :{WEIGHT} papier
+STR_QUANTITY_GOLD :{COMMA} zak{P "" ken} goud
+STR_QUANTITY_WATER :{VOLUME} water
+STR_QUANTITY_WHEAT :{WEIGHT} tarwe
+STR_QUANTITY_RUBBER :{VOLUME} rubber
+STR_QUANTITY_SUGAR :{WEIGHT} suiker
+STR_QUANTITY_TOYS :{COMMA} speelgoed
+STR_QUANTITY_SWEETS :{COMMA} zak{P "" ken} snoep
+STR_QUANTITY_COLA :{VOLUME} cola
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} suikerspinnen
+STR_QUANTITY_BUBBLES :{COMMA} bel{P "" len}
+STR_QUANTITY_TOFFEE :{WEIGHT} toffee
+STR_QUANTITY_BATTERIES :{COMMA} batterij{P "" en}
+STR_QUANTITY_PLASTIC :{VOLUME} plastic
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} blikje{P "" s} frisdrank
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}PS
+STR_ABBREV_COAL :{TINYFONT}KL
+STR_ABBREV_MAIL :{TINYFONT}PT
+STR_ABBREV_OIL :{TINYFONT}OL
+STR_ABBREV_LIVESTOCK :{TINYFONT}VE
+STR_ABBREV_GOODS :{TINYFONT}GD
+STR_ABBREV_GRAIN :{TINYFONT}GR
+STR_ABBREV_WOOD :{TINYFONT}HT
+STR_ABBREV_IRON_ORE :{TINYFONT}IJ
+STR_ABBREV_STEEL :{TINYFONT}ST
+STR_ABBREV_VALUABLES :{TINYFONT}KB
+STR_ABBREV_COPPER_ORE :{TINYFONT}KE
+STR_ABBREV_MAIZE :{TINYFONT}MS
+STR_ABBREV_FRUIT :{TINYFONT}FT
+STR_ABBREV_DIAMONDS :{TINYFONT}DM
+STR_ABBREV_FOOD :{TINYFONT}VD
+STR_ABBREV_PAPER :{TINYFONT}PR
+STR_ABBREV_GOLD :{TINYFONT}GD
+STR_ABBREV_WATER :{TINYFONT}WR
+STR_ABBREV_WHEAT :{TINYFONT}TW
+STR_ABBREV_RUBBER :{TINYFONT}RB
+STR_ABBREV_SUGAR :{TINYFONT}SK
+STR_ABBREV_TOYS :{TINYFONT}SP
+STR_ABBREV_SWEETS :{TINYFONT}SN
+STR_ABBREV_COLA :{TINYFONT}CL
+STR_ABBREV_CANDYFLOSS :{TINYFONT}SS
+STR_ABBREV_BUBBLES :{TINYFONT}BE
+STR_ABBREV_TOFFEE :{TINYFONT}TF
+STR_ABBREV_BATTERIES :{TINYFONT}BA
+STR_ABBREV_PLASTIC :{TINYFONT}PL
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}FR
+STR_ABBREV_NONE :{TINYFONT}NEE
+STR_ABBREV_ALL :{TINYFONT}ALLES
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Kaart - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Spelopties
+STR_00B2_MESSAGE :{YELLOW}Bericht
+STR_00B3_MESSAGE_FROM :{YELLOW}Bericht van {STRING}
+STR_POPUP_CAUTION_CAPTION :{WHITE}Waarschuwing!
+STR_00B4_CAN_T_DO_THIS :{WHITE}Kan dit niet uitvoeren....
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Kan gebied niet ontruimen....
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Originele copyright {COPYRIGHT} 1995 Chris Sawyer, alle rechten voorbehouden
+STR_00B7_VERSION :{BLACK}OpenTTD versie {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 Het OpenTTD team
+STR_TRANSLATED_BY :{BLACK} Vertaler(s) -
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Afsluiten
+STR_00C8_YES :{BLACK}Ja
+STR_00C9_NO :{BLACK}Nee
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Weet je zeker dat je dit spel wilt verlaten en terug wilt keren naar {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Niets
+STR_00D1_DARK_BLUE :Donkerblauw
+STR_00D2_PALE_GREEN :Lichtgroen
+STR_00D3_PINK :Rose
+STR_00D4_YELLOW :Geel
+STR_00D5_RED :Rood
+STR_00D6_LIGHT_BLUE :Lichtblauw
+STR_00D7_GREEN :Groen
+STR_00D8_DARK_GREEN :Donkergroen
+STR_00D9_BLUE :Blauw
+STR_00DA_CREAM :Crème
+STR_00DB_MAUVE :Mauve
+STR_00DC_PURPLE :Paars
+STR_00DD_ORANGE :Oranje
+STR_00DE_BROWN :Bruin
+STR_00DF_GREY :Grijs
+STR_00E0_WHITE :Wit
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Te veel voertuigen in het spel
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Locatie
+STR_00E5_CONTOURS :Contouren
+STR_00E6_VEHICLES :Voertuigen
+STR_00E7_INDUSTRIES :Industrieën
+STR_00E8_ROUTES :Routes
+STR_00E9_VEGETATION :Begroeiïng
+STR_00EA_OWNERS :Eigenaren
+STR_00EB_ROADS :{BLACK}{TINYFONT}Wegen
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Spoorwegen
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Stations/Vliegvelden/Havens
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Gebouwen/Industrieën
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Voertuigen
+STR_00F0_100M :{BLACK}{TINYFONT}100m
+STR_00F1_200M :{BLACK}{TINYFONT}200m
+STR_00F2_300M :{BLACK}{TINYFONT}300m
+STR_00F3_400M :{BLACK}{TINYFONT}400m
+STR_00F4_500M :{BLACK}{TINYFONT}500m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Treinen
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Wagens
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Schepen
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Vliegtuig
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Transportroutes
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Kolenmijn
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Energiecentrale
+STR_00FC_FOREST :{BLACK}{TINYFONT}Bos
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}Houtzagerij
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Olieraffinaderij
+STR_00FF_FARM :{BLACK}{TINYFONT}Boerderij
+STR_0100_FACTORY :{BLACK}{TINYFONT}Fabriek
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Drukkerij
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Oliebron
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}IJzermijn
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Hoogoven
+STR_0105_BANK :{BLACK}{TINYFONT}Bank
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Papierfabriek
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Goudmijn
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Voedselverwerkings fabriek
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Diamantmijn
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Kopermijn
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Fruitplantage
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Rubberplantage
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Waterbron
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Watertoren
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}Houtkapperij
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Suikerspinbos
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Snoepfabriek
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Batterijplantage
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Colabronnen
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Speelgoedwinkel
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Speelgoedfabriek
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Plasticfonteinen
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Frisdrankfabriek
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Bellenblazer
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Toffeegroeve
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Suikermijn
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Treinstation
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Laadstation
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Busstation
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Vliegveld/Helipoort
+STR_011F_DOCK :{BLACK}{TINYFONT}Haven
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Woestenij
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Grasland
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Braakliggend land
+STR_0123_FIELDS :{BLACK}{TINYFONT}Velden
+STR_0124_TREES :{BLACK}{TINYFONT}Bomen
+STR_0125_ROCKS :{BLACK}{TINYFONT}Rotsen
+STR_0126_WATER :{BLACK}{TINYFONT}Water
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Geen eigenaar
+STR_0128_TOWNS :{BLACK}{TINYFONT}Steden
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Industrieën
+STR_012A_DESERT :{BLACK}{TINYFONT}Woestijn
+STR_012B_SNOW :{BLACK}{TINYFONT}Sneeuw
+STR_012C_MESSAGE :{WHITE}Bericht
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Annuleren
+STR_012F_OK :{BLACK}OK
+STR_0130_RENAME :{BLACK}Hernoem
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Te veel namen in gebruik
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Deze naam is al in gebruik
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...is van {STRING}
+STR_013C_CARGO :{BLACK}Lading
+STR_013D_INFORMATION :{BLACK}Informatie
+STR_013E_CAPACITIES :{BLACK}Capaciteiten
+STR_013E_TOTAL_CARGO :{BLACK}Totale lading
+STR_013F_CAPACITY :{BLACK}Capaciteit: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}Capaciteit: {LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Totale lading (capaciteit) van deze trein:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}Nieuw spel
+STR_0141_LOAD_GAME :{BLACK}Laad spel
+STR_SINGLE_PLAYER :{BLACK}Een speler
+STR_MULTIPLAYER :{BLACK}Multiplayer
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Mapgrootte:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Spelopties
+
+STR_0150_SOMEONE :iemand{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Wereldkaart
+STR_0152_TOWN_DIRECTORY :Stedenlijst
+STR_0153_SUBSIDIES :Subsidies
+
+STR_UNITS_IMPERIAL :Imperiaal
+STR_UNITS_METRIC :Metrisch
+STR_UNITS_SI :SI
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} mph
+STR_UNITS_VELOCITY_METRIC :{COMMA} km/u
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}pk
+STR_UNITS_POWER_METRIC :{COMMA}pk
+STR_UNITS_POWER_SI :{COMMA}kW
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} ton{P "" en}
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} ton
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} kg
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}gal
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}l
+STR_UNITS_VOLUME_SHORT_SI :{COMMA} m³
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} gallon{P "" s}
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} liter{P "" s}
+STR_UNITS_VOLUME_LONG_SI :{COMMA} m³
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10^3 lbf
+STR_UNITS_FORCE_METRIC :{COMMA} ton trekkracht
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Winstgrafiek
+STR_0155_INCOME_GRAPH :Inkomenstegrafiek
+STR_0156_DELIVERED_CARGO_GRAPH :Afgeleverde lading-grafiek
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Prestatiegrafiek
+STR_0158_COMPANY_VALUE_GRAPH :Bedrijfswaardegrafiek
+STR_0159_CARGO_PAYMENT_RATES :Ladingsprijzen
+STR_015A_COMPANY_LEAGUE_TABLE :Bedrijfscompetitietabel
+STR_PERFORMANCE_DETAIL_MENU :Detail prestatiewaarde
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}OpenTTD
+STR_015C_SAVE_GAME :Spel opslaan
+STR_015D_LOAD_GAME :Spel laden
+STR_015E_QUIT_GAME :Spel stoppen
+STR_015F_QUIT :Afsluiten
+STR_ABANDON_GAME_QUERY :{YELLOW}Weet je zeker dat je dit spel wilt afsluiten?
+STR_0161_QUIT_GAME :{WHITE}Spel stoppen
+STR_SORT_ORDER_TIP :{BLACK}Selecteer sorteerrichting (aflopend/oplopend)
+STR_SORT_CRITERIA_TIP :{BLACK}Selecteer sorteringscriteria
+STR_SORT_BY :{BLACK}Sorteer op
+
+STR_SORT_BY_POPULATION :{BLACK}Inwoners
+STR_SORT_BY_PRODUCTION :{BLACK}Productie
+STR_SORT_BY_TYPE :{BLACK}Soort
+STR_SORT_BY_TRANSPORTED :{BLACK}Vervoerd
+STR_SORT_BY_NAME :{BLACK}Naam
+STR_SORT_BY_DROPDOWN_NAME :Naam
+STR_SORT_BY_DATE :{BLACK}Datum
+STR_SORT_BY_NUMBER :Nummer
+STR_SORT_BY_PROFIT_LAST_YEAR :Winst vorig jaar
+STR_SORT_BY_PROFIT_THIS_YEAR :Winst dit jaar
+STR_SORT_BY_AGE :Leeftijd
+STR_SORT_BY_RELIABILITY :Betrouwbaarheid
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Capaciteit per vrachttype
+STR_SORT_BY_MAX_SPEED :Maximale snelheid
+STR_SORT_BY_MODEL :Model
+STR_SORT_BY_VALUE :Waarde
+STR_SORT_BY_FACILITY :
+STR_SORT_BY_WAITING :
+STR_SORT_BY_RATING_MAX :
+STR_ENGINE_SORT_ENGINE_ID :Motor ID (klassieke soort)
+STR_ENGINE_SORT_COST :Kosten
+STR_ENGINE_SORT_POWER :Kracht
+STR_ENGINE_SORT_INTRO_DATE :Introductie Datum
+STR_ENGINE_SORT_RUNNING_COST :Operatie kosten
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Kracht/Operatie kosten
+STR_ENGINE_SORT_CARGO_CAPACITY :Vracht capaciteit
+STR_NO_WAITING_CARGO :{BLACK}Er wacht geen vracht van enig type
+STR_SELECT_ALL_FACILITIES :{BLACK}Kies alle faciliteiten
+STR_SELECT_ALL_TYPES :{BLACK}Kies alle vracht typen (inclusief niet wachtende vracht)
+STR_AVAILABLE_ENGINES_TIP :{BLACK}Bekijk een lijst van beschikbare ontwerpen voor dit type voertuig.
+STR_MANAGE_LIST :{BLACK}Beheer lijst
+STR_MANAGE_LIST_TIP :{BLACK}Stuur instructies naar alle voertuigen in de lijst
+STR_REPLACE_VEHICLES :Vervang voertuigen
+STR_SEND_TRAIN_TO_DEPOT :Stuur naar Depot
+STR_SEND_ROAD_VEHICLE_TO_DEPOT :Stuur naar Depot
+STR_SEND_SHIP_TO_DEPOT :Stuur naar Depot
+STR_SEND_AIRCRAFT_TO_HANGAR :Stuur naar Hangar
+STR_SEND_FOR_SERVICING :Stuur naar onderhoud
+
+############ range for months starts
+STR_0162_JAN :Jan
+STR_0163_FEB :Feb
+STR_0164_MAR :Mrt
+STR_0165_APR :Apr
+STR_0166_MAY :Mei
+STR_0167_JUN :Jun
+STR_0168_JUL :Jul
+STR_0169_AUG :Aug
+STR_016A_SEP :Sep
+STR_016B_OCT :Okt
+STR_016C_NOV :Nov
+STR_016D_DEC :Dec
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Pauzeer spel
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Spel opslaan, spel stoppen, afsluiten
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Toon lijst met stations van het bedrijf
+STR_0174_DISPLAY_MAP :{BLACK}Toon kaart
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Toon kaart, stedenlijst
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Toon stedenlijst
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Toon financiële informatie van het bedrijf
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Toon algemene informatie van het bedrijf
+STR_0179_DISPLAY_GRAPHS :{BLACK}Toon grafieken
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Toon bedrijfscompetitietabel
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Toon lijst met treinen van het bedrijf
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Toon lijst met voertuigen van het bedrijf
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Toon lijst met schepen van het bedrijf
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Toon lijst met vliegtuigen van het bedrijf
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Inzoomen
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Uitzoomen
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Bouw rails
+STR_0182_BUILD_ROADS :{BLACK}Bouw wegen
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Bouw haven
+STR_0184_BUILD_AIRPORTS :{BLACK}Bouw vliegvelden
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Plaats bomen, borden, etc.
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Landinformatie
+STR_0187_OPTIONS :{BLACK}Opties
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Kan onderhoudsinterval niet aanpassen...
+STR_018B_CLOSE_WINDOW :{BLACK}Sluit venster
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Vensternaam - sleep om venster te verplaatsen
+STR_STICKY_BUTTON :{BLACK}Markeer dit venster als niet-verwijderbaar door de 'Sluit Alle Vensters' knop
+STR_RESIZE_BUTTON :{BLACK}Klik en sleep om dit venster van grootte te veranderen
+STR_SAVELOAD_HOME_BUTTON :{BLACK}Klik hier om naar de standaard bewaar/laad directorie te gaan
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Sloop gebouwen etc. op een stuk land
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Verlaag een hoek van het land
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Verhoog een hoek van het land
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Scrollbalk - scroll door de lijst
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Schuifbalk - verschuift de lijst naar links/rechts
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Toon landcontouren op de kaart
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Toon voertuigen op de kaart
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Toon industrieën op de kaart
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Toon transportroutes op de kaart
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Toon begroeiïng op de kaart
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Toon landeigenaren op de kaart
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Plaatsnamen op de kaart aan/uit
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Winst dit jaar: {CURRENCY} (vorig jaar: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} ja{P ar ren} ({COMMA})
+STR_AGE_RED :{RED}{COMMA} ja{P ar ren} ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Voertuig
+STR_019D_AIRCRAFT :Vliegtuig
+STR_019E_SHIP :Schip
+STR_019F_TRAIN :Trein
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} wordt oud
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} wordt erg oud
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} wordt erg oud en is aan vervanging toe
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Landinformatie
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Sloopkosten: {LTBLUE}niet mogelijk
+STR_01A5_COST_TO_CLEAR :{BLACK}Sloopkosten: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :(geen)
+STR_01A7_OWNER :{BLACK}Eigenaar: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Gemeente: {LTBLUE}{STRING}
+STR_01A9_NONE :Geen
+STR_01AA_NAME :{BLACK}Naam
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1
+STR_01AD_2ND :2
+STR_01AE_3RD :3
+STR_01AF_4TH :4
+STR_01B0_5TH :5
+STR_01B1_6TH :6
+STR_01B2_7TH :7
+STR_01B3_8TH :8
+STR_01B4_9TH :9
+STR_01B5_10TH :10
+STR_01B6_11TH :11
+STR_01B7_12TH :12
+STR_01B8_13TH :13
+STR_01B9_14TH :14
+STR_01BA_15TH :15
+STR_01BB_16TH :16
+STR_01BC_17TH :17
+STR_01BD_18TH :18
+STR_01BE_19TH :19
+STR_01BF_20TH :20
+STR_01C0_21ST :21
+STR_01C1_22ND :22
+STR_01C2_23RD :23
+STR_01C3_24TH :24
+STR_01C4_25TH :25
+STR_01C5_26TH :26
+STR_01C6_27TH :27
+STR_01C7_28TH :28
+STR_01C8_29TH :29
+STR_01C9_30TH :30
+STR_01CA_31ST :31
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Accepteert: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Jazz jukebox
+STR_01D3_SOUND_MUSIC :Geluid/muziek
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Toon geluid/muziek scherm
+STR_01D5_ALL :{TINYFONT}Alle
+STR_01D6_OLD_STYLE :{TINYFONT}Oude stijl
+STR_01D7_NEW_STYLE :{TINYFONT}Nieuwe stijl
+STR_01D8_EZY_STREET :{TINYFONT}Ezy street
+STR_01D9_CUSTOM_1 :{TINYFONT}Aangepast 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Aangepast 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Muziekvolume
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Geluidsvolume
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MIN ' ' ' ' ' ' MAX
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Vorige nummer in selectie
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Volgende nummer in selectie
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Stop muziek
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Start muziek
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Gebruik de schuifbalken om het volume aan te passen
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Nummer{SETX 88}Titel
+STR_01E9_SHUFFLE :{TINYFONT}Shuffle
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Programma
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Muziekprogrammakeuze
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Nummer index
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Programma - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}Leeg
+STR_01F1_SAVE :{TINYFONT}{BLACK}Sla op
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Huidig muziekprogramma
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Selecteer 'alle nummers' programma
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Selecteer 'oude stijl muziek' programma
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Selecteer 'nieuwe stijl muziek' programma
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Selecteer 'aangepast 1' programma
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Selecteer 'aangepast 2' programma
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Leeg huidig programma (alleen Aangepast 1 en Aangepast 2)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Sla muziekinstellingen op
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Klik op het nummer om aan programma toe te voegen (alleen Aangepast 1 en Aangepast 2)
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Klik op het muziek item om het van de lijst te verwijderen (Aangepast 1 en Aangepast 2)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Programmashuffle aan/uit
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Toon nummerselectiescherm
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Klik op de dienst om de stad/industrie te centreren
+STR_01FE_DIFFICULTY :{BLACK}Moeilijkheid ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Laatste (nieuws)bericht
+STR_0201_MESSAGE_SETTINGS :Berichteninstellingen
+STR_MESSAGE_HISTORY_MENU :Berichtengeschiedenis
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Toon laatste (nieuws)bericht, toon berichteninstellingen
+STR_0204_MESSAGE_OPTIONS :{WHITE}Berichtenopties
+STR_0205_MESSAGE_TYPES :{BLACK}Berichttypen:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Eerste voertuig bij eigen station
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Eerste voertuig bij concurrerend station
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Ongelukken/rampen
+STR_0209_COMPANY_INFORMATION :{YELLOW}Bedrijfsinformatie
+STR_020A_ECONOMY_CHANGES :{YELLOW}Veranderingen in de economie
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Advies/informatie over voertuigen van de speler
+STR_020C_NEW_VEHICLES :{YELLOW}Nieuwe voertuigen
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Verandering geaccepteerde goederen
+STR_020E_SUBSIDIES :{YELLOW}Subsidies
+STR_020F_GENERAL_INFORMATION :{YELLOW}Algemene informatie
+STR_MESSAGES_ALL :{YELLOW}Instelling voor alle berichttypes (aan/uit/samenvatting)
+STR_MESSAGE_SOUND :{YELLOW}Speel een geluid af voor samengevatte nieuwsberichten
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...te ver van vorige bestemming
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Top bedrijven die {NUM} bereikt hebben{}({STRING} Niveau)
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Bedrijfswedstrijdtabel in {NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Zakenman
+STR_0214_ENTREPRENEUR :Ondernemer
+STR_0215_INDUSTRIALIST :Fabrikant
+STR_0216_CAPITALIST :Kapitalist
+STR_0217_MAGNATE :Magnaat
+STR_0218_MOGUL :Mogol
+STR_0219_TYCOON_OF_THE_CENTURY :Tycoon van de Eeuw
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} bereikt '{STRING}' status!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} van {COMPANY} bereikt '{STRING}' status!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Maak scenario
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Scenario editor
+STR_0223_LAND_GENERATION :{WHITE}Landontwikkeling
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Willekeurig land
+STR_0227_RESET_LAND :{BLACK}Verwijder land
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Vergroot het stuk land om te verhogen/verlagen
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Verklein het stuk land om te verhogen/verlagen
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Genereer willekeurig land
+STR_022B_RESET_LANDSCAPE :{BLACK}Verwijder landschap
+STR_022C_RESET_LANDSCAPE :{WHITE}Verwijder landschap
+STR_LOAD_GAME_HEIGHTMAP :{WHITE}Gebruik hoogtekaart
+STR_LOAD_SCEN_HEIGHTMAP :{BLACK}Gebruik hoogtekaart
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Weet je zeker dat je het land wilt verwijderen?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Landschapproductie
+STR_022F_TOWN_GENERATION :{BLACK}Stadproductie
+STR_0230_INDUSTRY_GENERATION :{BLACK}Industrieproductie
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Wegenbouw
+STR_0233_TOWN_GENERATION :{WHITE}Stadproductie
+STR_0234_NEW_TOWN :{BLACK}Nieuwe stad
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Bouw nieuwe stad
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Kan hier geen nieuwe stad bouwen...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...te dicht bij de rand van de kaart
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...te dicht bij een andere stad
+STR_0239_SITE_UNSUITABLE :{WHITE}...lokatie ongeschikt
+STR_023A_TOO_MANY_TOWNS :{WHITE}...te veel steden
+STR_CANNOT_GENERATE_TOWN :{WHITE}Kan geen enkele stad bouwen
+STR_NO_SPACE_FOR_TOWN :{WHITE}...er is geen ruimte meer op de kaart
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Vergroot stad
+STR_023C_EXPAND :{BLACK}Vergroot
+STR_023D_RANDOM_TOWN :{BLACK}Willekeurige stad
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Bouw stad op willekeurige locatie
+STR_023F_INDUSTRY_GENERATION :{WHITE}Industrieproductie
+STR_0240_COAL_MINE :{BLACK}Kolenmijn
+STR_0241_POWER_STATION :{BLACK}Energiecentrale
+STR_0242_SAWMILL :{BLACK}Houtzagerij
+STR_0243_FOREST :{BLACK}Bos
+STR_0244_OIL_REFINERY :{BLACK}Olieraffinaderij
+STR_0245_OIL_RIG :{BLACK}Olieplatform
+STR_0246_FACTORY :{BLACK}Fabriek
+STR_0247_STEEL_MILL :{BLACK}Hoogoven
+STR_0248_FARM :{BLACK}Boerderij
+STR_0249_IRON_ORE_MINE :{BLACK}IJzermijn
+STR_024A_OIL_WELLS :{BLACK}Oliebron
+STR_024B_BANK :{BLACK}Bank
+STR_024C_PAPER_MILL :{BLACK}Papierfabriek
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Voedselverwerkingsfabriek
+STR_024E_PRINTING_WORKS :{BLACK}Drukkerij
+STR_024F_GOLD_MINE :{BLACK}Goudmijn
+STR_0250_LUMBER_MILL :{BLACK}Houtkapperij
+STR_0251_FRUIT_PLANTATION :{BLACK}Fruitplantage
+STR_0252_RUBBER_PLANTATION :{BLACK}Rubberplantage
+STR_0253_WATER_SUPPLY :{BLACK}Waterbron
+STR_0254_WATER_TOWER :{BLACK}Watertoren
+STR_0255_DIAMOND_MINE :{BLACK}Diamantmijn
+STR_0256_COPPER_ORE_MINE :{BLACK}Kopermijn
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Suikerspinbos
+STR_0258_CANDY_FACTORY :{BLACK}Snoepfabriek
+STR_0259_BATTERY_FARM :{BLACK}Batterijplantage
+STR_025A_COLA_WELLS :{BLACK}Colabronnen
+STR_025B_TOY_SHOP :{BLACK}Speelgoedwinkel
+STR_025C_TOY_FACTORY :{BLACK}Speelgoedfabriek
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Plasticfonteinen
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Frisdrankfabriek
+STR_025F_BUBBLE_GENERATOR :{BLACK}Bellenblazer
+STR_0260_TOFFEE_QUARRY :{BLACK}Toffeegroeve
+STR_0261_SUGAR_MINE :{BLACK}Suikermijn
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Plaats kolenmijn
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Plaats energiecentrale
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Plaats houtzagerij
+STR_0265_PLANT_FOREST :{BLACK}Plant bos
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Plaats olieraffinaderij
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Plaats olieplatform (alleen bij randen van de kaart)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Plaats fabriek
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Plaats hoogoven
+STR_026A_CONSTRUCT_FARM :{BLACK}Plaats boerderij
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Plaats ijzermijn
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Plaats oliebron
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Plaats bank (alleen in steden met een bevolking van meer dan 1200)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Plaats papierfabriek
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Plaats voedselverwerkingsfabriek
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Plaats drukkerij
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Plaats goudmijn
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Plaats bank (alleen in steden)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Plaats houtkapperij (kapt regenwoud en produceert hout)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Plant fruitplantage
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Plant rubberplantage
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Plaats waterbron
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Plaats watertoren (alleen in steden)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Plaats diamantmijn
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Plaats kopermijn
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Plant suikerspinbos
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Plaats snoepfabriek
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Plaats batterijplantage
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Plaats colabronnen
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Plaats speelgoedwinkel
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Plaats speelgoedfabriek
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Plaats plasticfonteinen
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Plaats frisdrankfabriek
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Plaats bellenblazer
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Plaats toffeegroeve
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Plaats suikermijn
+STR_0285_CAN_T_BUILD_HERE :{WHITE}Kan {STRING} hier niet bouwen...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...plaats eerst stad
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...slechts één per stad toegestaan
+STR_0288_PLANT_TREES :{BLACK}Plant bomen
+STR_0289_PLACE_SIGN :{BLACK}Plaats bord
+STR_028A_RANDOM_TREES :{BLACK}Verspreid willekeurige bomen
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Verspreid bomen over de kaart
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Plaats steenachtige gebieden op de kaart
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Plaats vuurtoren
+STR_028E_PLACE_TRANSMITTER :{BLACK}Plaats radiomast
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Definieer woestijn gebied.{}Gebruik CTRL om het te verwijderen
+STR_CREATE_LAKE :{BLACK}Definieer watergebied.{}Het zal de omgeving overstromen als deze op zeeniveau ligt
+STR_0290_DELETE :{BLACK}Verwijder
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Verwijder deze hele stad
+STR_0292_SAVE_SCENARIO :Scenario opslaan
+STR_0293_LOAD_SCENARIO :Scenario openen
+STR_0294_QUIT_EDITOR :Sluit editor
+STR_0295 :
+STR_0296_QUIT :Afsluiten
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Sla scenario op, open scenario, scenarioeditor verlaten, OpenTTD afsluiten
+STR_0298_LOAD_SCENARIO :{WHITE}Scenario openen
+STR_0299_SAVE_SCENARIO :{WHITE}Scenario opslaan
+STR_029A_PLAY_SCENARIO :{BLACK}Scenario spelen
+STR_PLAY_HEIGHTMAP :{BLACK}Speel Hoogtekaart
+STR_PLAY_HEIGHTMAP_HINT :{BLACK}Start een nieuw spel, gebruik een hoogtekaart als landschap
+STR_QUIT_SCENARIO_QUERY :{YELLOW}Weet je zeker dat je dit scenario wilt sluiten?
+STR_029C_QUIT_EDITOR :{WHITE}Sluit editor
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...kan alleen in steden met bevolking van meer dan 1200 gebouwd worden
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Verplaats begindatum 1 jaar achteruit
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Verplaats begindatum 1 jaar vooruit
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...uiteinden van brug moeten beiden op land zijn
+STR_02A1_SMALL :{BLACK}Klein
+STR_02A2_MEDIUM :{BLACK}Middel
+STR_02A3_LARGE :{BLACK}Groot
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Kies stadsgrootte
+STR_02A5_TOWN_SIZE :{YELLOW}Stadsgrootte:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Laat laatste (nieuws)bericht zien
+STR_OFF :Uit
+STR_SUMMARY :Kort
+STR_FULL :Volledig
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Stedenlijst
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Voertuignamen
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Standaard
+STR_02BF_CUSTOM :Aangepast
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Sla aangepaste namen op
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Keuze van voertuignamen
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Sla aangepaste voertuignamen op
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Spelopties
+STR_02C5_DIFFICULTY_SETTINGS :Moeilijkheidsgraad
+STR_02C7_CONFIG_PATCHES :Kies patches
+STR_NEWGRF_SETTINGS :Newgrf instellingen
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Geef stadsnamen weer
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Geef stationsnamen weer
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Geef borden weer
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Controlepost weergegeven
+STR_02D0_FULL_ANIMATION :{SETX 12}Alle animatie
+STR_02D2_FULL_DETAIL :{SETX 12}Alle details
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Transparante gebouwen
+STR_TRANSPARENT_SIGNS :{SETX 12}Transparant station bord
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Info over blok land
+STR_02D6 :
+STR_CONSOLE_SETTING :Schakel console aan/uit
+STR_02D7_SCREENSHOT_CTRL_S :Screenshot (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Grote screenshot (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :Over OpenTTD
+############ range ends here
+
+STR_02DB_OFF :{BLACK}Uit
+STR_02DA_ON :{BLACK}Aan
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Toon subsidies
+STR_02DD_SUBSIDIES :Subsidies
+STR_02DE_MAP_OF_WORLD :Kaart
+STR_EXTRA_VIEW_PORT :Extra kijkvenster
+STR_SIGN_LIST :Bordenlijst
+STR_02DF_TOWN_DIRECTORY :Stedenlijst
+STR_TOWN_POPULATION :{BLACK}Wereldbevolking: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Kijkvenster {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Kopieer naar kijkvenster
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Kopieer de lokatie van het algemene scherm naar dit kijkvenster
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Plak van kijkvenster
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Plak de lokatie van dit kijkvenster naar het algemene scherm
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Valuta
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Kies valuta
+STR_MEASURING_UNITS :{BLACK}Meeteenheden
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Selectie meeteenheden
+STR_02E6_ROAD_VEHICLES :{BLACK}Voertuigen
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Kies aan welke kant de voertuigen moeten rijden
+STR_02E9_DRIVE_ON_LEFT :Links rijden
+STR_02EA_DRIVE_ON_RIGHT :Rechts rijden
+STR_02EB_TOWN_NAMES :{BLACK}Plaatsnamen
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Kies type plaatsnamen
+
+STR_02F4_AUTOSAVE :{BLACK}Automatisch opslaan
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Kies interval tussen autosaves
+STR_02F7_OFF :Uit
+STR_02F8_EVERY_3_MONTHS :Iedere 3 maanden
+STR_02F9_EVERY_6_MONTHS :Iedere 6 maanden
+STR_02FA_EVERY_12_MONTHS :Iedere 12 maanden
+STR_02FB_START_A_NEW_GAME :{BLACK}Start een nieuw spel
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Laad een opgeslagen spel
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Maak een eigen spelwereld/scenario
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Kies een éénspelerspel
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Selecteer multiplayer spel van 2-8 spelers
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Bekijk opties
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Bekijk moeilijkheidsgraad
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Start een nieuw spel, gebaseerd op een scenario
+STR_0304_QUIT :{BLACK}Afsluiten
+STR_0305_QUIT_OPENTTD :{BLACK}Verlaat 'OpenTTD'
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...kan alleen in steden gebouwd worden
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Kies gematigd klimaat
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Kies subarctisch klimaat
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Kies subtropisch klimaat
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Kies 'speelgoedland'
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Betaal plaatsing van nieuwe industrie
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Industrielijst
+STR_0313_FUND_NEW_INDUSTRY :Subsidieer nieuwe industrie
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Betaal nieuwe industrie
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...kan alleen in steden gebouwd worden
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...kan alleen in het regenwoud gebouwd worden
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...kan alleen in woestijngebieden gebouwd worden
+STR_0319_PAUSED :{YELLOW}* * GEPAUZEERD * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Screenshot succesvol opgeslagen als '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}Screenshot mislukt!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Koop land voor toekomstig gebruik
+STR_032F_AUTOSAVE :{RED}AUTOSAVE
+STR_SAVING_GAME :{RED}* * SPEL WORDT OPGESLAGEN * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}Opslaan van spel is nog bezig,{}wacht tot dit voltooid is!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Kies 'Ezy Street style music' programma
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :Engels (Origineel)
+STR_TOWNNAME_FRENCH :Frans
+STR_TOWNNAME_GERMAN :Duits
+STR_TOWNNAME_ADDITIONAL_ENGLISH :Engels (Extra)
+STR_TOWNNAME_LATIN_AMERICAN :Latijns-Amerikaans
+STR_TOWNNAME_SILLY :Zot
+STR_TOWNNAME_SWEDISH :Zweeds
+STR_TOWNNAME_DUTCH :Nederlands
+STR_TOWNNAME_FINNISH :Fins
+STR_TOWNNAME_POLISH :Pools
+STR_TOWNNAME_SLOVAKISH :Slowaaks
+STR_TOWNNAME_NORWEGIAN :Noors
+STR_TOWNNAME_HUNGARIAN :Hongaars
+STR_TOWNNAME_AUSTRIAN :Oostenrijks
+STR_TOWNNAME_ROMANIAN :Roemeens
+STR_TOWNNAME_CZECH :Tsjechisch
+STR_TOWNNAME_SWISS :Zwitsers
+STR_TOWNNAME_DANISH :Deens
+STR_TOWNNAME_TURKISH :Turks
+STR_TOWNNAME_ITALIAN :Italiaans
+STR_TOWNNAME_CATALAN :Catalaans
+############ end of townname region
+
+STR_CURR_GBP :Pond (£)
+STR_CURR_USD :Dollar ($)
+STR_CURR_EUR :Euro (€)
+STR_CURR_YEN :Yen (Â¥)
+STR_CURR_ATS :Australische Shilling (ATS)
+STR_CURR_BEF :Belgische Franken (BEF)
+STR_CURR_CHF :Zwitserse Franken (CHF)
+STR_CURR_CZK :Tsjechise Koruna (CZK)
+STR_CURR_DEM :Duitse Mark (DEM)
+STR_CURR_DKK :Deense Kronen (DKK)
+STR_CURR_ESP :Spaanse Peseta (ESP)
+STR_CURR_FIM :Finse Mark (FIM)
+STR_CURR_FRF :Franse Franc (FRF)
+STR_CURR_GRD :Griekse Drachma (GRD)
+STR_CURR_HUF :Hongaarse Forint (HUF)
+STR_CURR_ISK :IJslandse Kronen (ISK)
+STR_CURR_ITL :Italiaanse Lieren (ITL)
+STR_CURR_NLG :Nederlandse Gulden (NLG)
+STR_CURR_NOK :Noorweegse Kronen (NOK)
+STR_CURR_PLN :Poolse Zloty (PLN)
+STR_CURR_ROL :Roemeense Leu (ROL)
+STR_CURR_RUR :Russische Rubel (RUR)
+STR_CURR_SIT :Sloveense Tolar (SIT)
+STR_CURR_SEK :Zweedse Kronen (SEK)
+STR_CURR_YTL :Turkse Lire (YTL)
+STR_CURR_SKK :Slovaakse Koruna (SKK)
+STR_CURR_BRR :Brazilliaanse Real (BRL)
+
+STR_CURR_CUSTOM :Aangepast...
+
+STR_OPTIONS_LANG :{BLACK}Taal
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Selecteer de interfacetaal
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Volledig scherm
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}Vink dit vakje aan om OpenTTD in het volledige scherm te spelen
+
+STR_OPTIONS_RES :{BLACK}Schermresolutie
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Selecteer de schermresolutie
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Screenshotformaat
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Selecteer het formaat van de schermprint
+
+STR_AUTOSAVE_1_MONTH :Elke maand
+STR_AUTOSAVE_FAILED :{WHITE}Automatisch opslaan mislukt
+
+STR_MONTH_JAN :Januari
+STR_MONTH_FEB :Februari
+STR_MONTH_MAR :Maart
+STR_MONTH_APR :April
+STR_MONTH_MAY :Mei
+STR_MONTH_JUN :Juni
+STR_MONTH_JUL :Juli
+STR_MONTH_AUG :Augustus
+STR_MONTH_SEP :September
+STR_MONTH_OCT :Oktober
+STR_MONTH_NOV :November
+STR_MONTH_DEC :December
+
+STR_HEADING_FOR_STATION :{LTBLUE}Op weg naar {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}Op weg naar {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Geen orders
+STR_NO_ORDERS_VEL :{LTBLUE}Geen orders, {VELOCITY}
+
+STR_PASSENGERS :passagiers
+STR_BAGS :zakken
+STR_TONS :ton
+STR_LITERS :liter
+STR_ITEMS :stuks
+STR_CRATES :kratten
+STR_RES_OTHER :anders
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Kan orderlijst niet delen...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Kan orderlijst niet kopieren...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - Einde gedeelde orders - -
+
+STR_TRAIN_IS_LOST :{WHITE}Trein {COMMA} is verdwaald.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}Winst van trein {COMMA} was vorig jaar {CURRENCY}
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}Europese Monetaire Unie!{}{}De Euro is geïntroduceerd als de enige munt voor alledaagse transacties in jouw land!
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Trein {COMMA} heeft te weinig opdrachten
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}Trein {COMMA} heeft een lege opdracht
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}Trein {COMMA} heeft dubbele orders
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}Trein {COMMA} heeft een ongeldig station in de orders
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}Wegvoertuig {COMMA} heeft te weinig orders in de orderlijst
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}Wegvoertuig {COMMA} heeft lege order
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}Wegvoertuig {COMMA} heeft dubbele orders
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}Wegvoertuig {COMMA} heeft een ongeldig station in de orders
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}Schip {COMMA} heeft te weinig order is orderlijst
+STR_SHIP_HAS_VOID_ORDER :{WHITE}Schip {COMMA} heeft lege order
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}Schip {COMMA} heeft dubbele orders
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}Schip {COMMA} heeft een ongeldig station in de orders
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}Vliegtuig {COMMA} heeft te weinig orders in orderlijst
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}Vliegtuig {COMMA} heeft lege order
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}Vliegtuig {COMMA} heeft dubbele orders
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}Vliegtuig {COMMA} heeft een ongeldig station in de orders
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}Automatisch vernieuwen mislukt bij trein {COMMA} (onvoldoende geld)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}Automatisch vernieuwen mislukt bij voertuig {COMMA} (onvoldoende geld)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}Automatisch vernieuwen mislukt bij schip {COMMA} (onvoldoende geld)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}Automatisch vernieuwen mislukt bij vliegtuig {COMMA} (onvoldoende geld)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}Trein {COMMA} is te lang na het vervangen
+
+STR_CONFIG_PATCHES :{BLACK}Selecteer patches
+STR_CONFIG_PATCHES_TIP :{BLACK}Kies welke patches je wilt gebruiken
+STR_CONFIG_PATCHES_CAPTION :{WHITE}Kies patches
+
+STR_CONFIG_PATCHES_OFF :Uit
+STR_CONFIG_PATCHES_ON :Aan
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Geef snelheid in statusbalk weer: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Bouwen op hellingen toestaan: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Gebruik realistisch handelsgebied: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Sta verwijderen van meer stedelijke wegen, bruggen, tunnels, enz. toe: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Zeer lange treinen toestaan: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Realistische acceleratie van treinen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Verbied schepen en treinen om 90 graden te draaien: {ORANGE}{STRING} {LTBLUE} (Vereist NPF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Stations samenvoegen als ze naast elkaar worden gebouwd: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Verlaat station wanneer één lading geladen is, met 'vol laden': {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Gebruik verbeterde laad algorithme: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GRADUAL_LOADING :{LTBLUE}Voertuigen geleidelijk laden: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Inflatie: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Lading alleen bezorgen aan een station als er vraag naar is: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Bouwen van zeer lange bruggen toestaan: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}'Ga naar depot' order toestaan: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Plaatsen van grondstofproducerende industrie toestaan: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Meerdere vergelijkbare industrieën per stad toestaan: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Industrieën van hetzelfde type dicht bij elkaar toestaan: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Altijd lange datum in statusbalk weergeven: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Seinen aan rijzijde plaatsen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Financieel overzicht aan het eind van het jaar weergeven: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}TTDPatch-compatibel nonstop-gebruik: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Rijvorming bij wegvoertuigen (met bijwerkingen): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Verschuif scherm als muis aan de rand is: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Omkopen van de gemeente toestaan: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Vrij gevormde stations: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Nieuwe globale routeplanner (NPF, voorkeur over NTP): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FREIGHT_TRAINS :{LTBLUE}Gewichtsverhouding voor vracht om zware treinen te simuleren: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Altijd kleine vliegvelden toestaan: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Waarschuwen als trein verdwaald is: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Herzie voertuigorders: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :nee
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :ja, maar sluit gestopte voertuigen uit
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :van alle voertuigen
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Waarschuw als het inkomen van een trein negatief is: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Voertuigen verlopen nooit: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Vernieuw voertuig automatisch wanneer deze oud wordt
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Vernieuw voertuig automatisch {ORANGE}{STRING}{LTBLUE} maanden voor/na max. leeftijd
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Minimum benodigd geld voor automatisch vernieuwen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Duur van foutmeldingen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Geef het inwoneraantal bij een stad weer: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Onzichtbare bomen (met transparante gebouwen): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Land generator: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :Origineel
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :Terra Genesis
+STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}Max afstand van de rand voor olierafinaderijen {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Sneeuwhoogte: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN :{LTBLUE}Ruwheid van het terrein (alleen Terra Genesis) : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Erg vlak
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH :vlak
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH :Ruig
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :Erg ruig
+STR_CONFIG_PATCHES_TREE_PLACER :{LTBLUE}Boomplaatser alogeritme: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TREE_PLACER_NONE :Geen
+STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL :Origineel
+STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED :Verbeterd
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION :{LTBLUE}Heightmap draaiing: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Tegen de klok
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE :Met de klok mee
+STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT :{LTBLUE}De hoogte van een plat scenario wordt: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Maximale stationsomvang: {ORANGE}{STRING} {RED}Pas op: Hoge waarde vertraagt spel
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Helikopters automatisch repareren op helipads: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Verbind de landschaptoolbar met de trein/weg/water/vliegveld toolbars: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Omgekeerde scrollrichting: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Toon dimensie informatie bij het gebruik van diverse bouw-tools: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Laat all bedrijfslogo's zien: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES_NONE :Niets
+STR_CONFIG_PATCHES_LIVERIES_OWN :Eigen bedrijf
+STR_CONFIG_PATCHES_LIVERIES_ALL :Alle bedrijven
+STR_CONFIG_PATCHES_PREFER_TEAMCHAT :{LTBLUE}Voorkeur voor team chat met <ENTER>: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Maximaal aantal treinen per speler: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Maximaal aantal wegvoertuigen per speler: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}Maximaal aantal vliegtuigen per speler: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}Maximaal aantal schepen per speler: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Treinen voor de computer uitschakelen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Wegvoertuigen voor de computer uitschakelen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Vliegtuigen voor de computer uitschakelen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Schepen voor de computer uitschakelen: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Nieuwe AI inschakelen (alpha): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Sta AI's toe in multiplayer (experimenteel): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Standaard reparatie interval bij treinen: {ORANGE}{STRING} dagen
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Standaard reparatie interval voor treinen: {ORANGE}uit
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Standaard reparatie interval bij wegvoertuigen: {ORANGE}{STRING} dagen
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Standaard reparatie interval voor voertuigen: {ORANGE}uit
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Standaard reparatie interval bij vliegtuigen: {ORANGE}{STRING} dagen
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Standaard reparatie interval voor vliegtuigen: {ORANGE}uit
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Standaard reparatie interval bij schepen: {ORANGE}{STRING} dagen
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Standaard reparatie interval voor schepen: {ORANGE}uit
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Schakel onderhoud uit wanneer defecten uit staan: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Zet wagon snelheidslimieten aan: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}Schakel electrische sporen uit: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Kleurenfoto's komen in: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Beginjaar: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}Stop spel in: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Vloeiende economie inschakelen (meer, kleinere veranderingen)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Sta het kopen van aandelen toe
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Bij slepen, plaats seinen elke: {ORANGE}{STRING} tegel(s)
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Positie van algemene toolbar: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Links
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Midden
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Rechts
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Vaste plaats venster radius: {ORANGE}{STRING} px
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Vaste plaats venster radius: {ORANGE}uit
+
+STR_CONFIG_PATCHES_GUI :{BLACK}Interface
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Constructie
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Voertuigen
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Stations
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Economie
+STR_CONFIG_PATCHES_AI :{BLACK}Tegenstanders
+
+STR_CONFIG_PATCHES_DISABLED :uitgeschakeld
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Verander waarde
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Sommige of alle van de standaard reparatie interval(len) hier onder zijn ongeldig met gekozen instelling! 5-90% en 30-800 dagen zijn geldig
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}Gebruik YAPF voor schepen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}Gebruik YAPF voor wegvoertuigen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}Gebruik YAPF voor treinen: {ORANGE}{STRING}
+
+STR_TEMPERATE_LANDSCAPE :gematigd landschap
+STR_SUB_ARCTIC_LANDSCAPE :subarctisch landschap
+STR_SUB_TROPICAL_LANDSCAPE :subtropisch landschap
+STR_TOYLAND_LANDSCAPE :speelgoed landschap
+
+STR_CHEATS :{WHITE}Cheats
+STR_CHEATS_TIP :{BLACK}Keuzevakjes geven aan of je deze cheat al ooit gebruikt hebt.
+STR_CHEATS_WARNING :{BLACK}Waarschuwing! Je staat op het punt je concurrenten te verraden. Bedenk dat zo'n schande eeuwig wordt onthouden.
+STR_CHEAT_MONEY :{LTBLUE}Verhoog geld met {CURRENCY64}
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Spelend als speler: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Magische bulldozer (industrieën en andere onverplaatsbare objecten verwijderen): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Tunnels mogen elkaar kruisen: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Bouwen in gepauzeerde toestand: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Jetvliegtuigen storten niet (vaak) neer op kleine vliegvelden: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Verander klimaat: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Verander datum: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}Sta aanpassen productiewaarden toe: {ORANGE}{STRING}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}Op weg naar {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Op weg naar {WAYPOINT}, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :Ga via {WAYPOINT}
+STR_GO_NON_STOP_TO_WAYPOINT :Ga non-stop via {WAYPOINT}
+
+STR_WAYPOINTNAME_CITY :Tussenstop {TOWN}
+STR_WAYPOINTNAME_CITY_SERIAL :Tussenstop {TOWN} #{COMMA}
+STR_LANDINFO_WAYPOINT :Controlepost
+
+STR_WAYPOINT :{WHITE}Controlepost
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Selecteer controlepost type
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}Naam controlepost aanpassen
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Kan naam controlepost niet aanpassen...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Converteer spoor naar controlepost
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Kan hier geen trein controlepost bouwen...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Kan hier trein controlepost niet weghalen...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Bouw spoor met de Autorail-methode
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}...er is geen stad in dit scenario
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}Weet je zeker dat je een willekeurig landschap wil maken?
+STR_MANY_RANDOM_TOWNS :{BLACK}Veel willekeurige steden
+STR_RANDOM_TOWNS_TIP :{BLACK}Bedek de kaart met willekeurig geplaatste steden
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Veel willekeurige industrieën
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Bedek de kaart met willekeurig geplaatste industrieën
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Kan geen industrieën genereren
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Open de landschapsbalk om land te verhogen/verlagen, bomen te planten, etc.
+STR_LANDSCAPING_TOOLBAR :{WHITE}Terreinvorming
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Landhoogte gelijk maken
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Willekeurige boomsoorten
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}Plant bomen van willekeurig type
+
+STR_CANT_BUILD_CANALS :{WHITE}Kan hier geen kanaal bouwen...
+STR_BUILD_CANALS_TIP :{BLACK}Bouw kanaal
+STR_LANDINFO_CANAL :Kanaal
+
+STR_CANT_BUILD_LOCKS :{WHITE}Kan hier geen sluis bouwen...
+STR_BUILD_LOCKS_TIP :{BLACK}Bouw sluis
+STR_LANDINFO_LOCK :Sluis
+
+STR_BUOY_IS_IN_USE :{WHITE}... boei is in gebruik!
+
+STR_LANDINFO_COORDS :{BLACK}Coördinaten: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Kan deel van station niet weghalen...
+STR_CANT_CONVERT_RAIL :{WHITE}Kan railtype hier niet veranderen...
+STR_CONVERT_RAIL_TIP :{BLACK}Verander railtype
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Sleep locomotief hierheen om de hele trein te verkopen
+
+STR_DRAG_DROP :{BLACK}Slepen
+STR_STATION_DRAG_DROP :{BLACK}Bouw een station door te slepen
+STR_SELECT_STATION_CLASS_TIP :{BLACK}Selecteer een station type
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Selecteer het type station om te bouwen
+
+STR_FAST_FORWARD :{BLACK}Verhoog de spelsnelheid
+STR_MESSAGE_HISTORY :{WHITE}Berichtgeschiedenis
+STR_MESSAGE_HISTORY_TIP :{BLACK}Een lijst met recente nieuwsberichten
+STR_MESSAGES_DISABLE_ALL :{BLACK}Alles uitschakelen
+STR_MESSAGES_ENABLE_ALL :{BLACK}Alles inschakelen
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Graaf kolenmijn
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Plant bos
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Plaats olieplatform
+STR_CONSTRUCT_FARM_TIP :{BLACK}Sticht boerderij
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Graaf kopermijn
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Boor voor olie
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Graaf goudmijn
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Graaf diamantmijn
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Graaf ijzermijn
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Sticht boomgaard
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Sticht rubberboerderij
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Sticht waterbron
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Plant suikerspinbos
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}Sticht batterijplantage
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Boor voor cola
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Sticht plasticfonteinen
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Plaats bellenblazer
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Sticht toffeegroeve
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Graaf suikermijn
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Industrielijst
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA}% vervoerd)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA}%/{COMMA}% vervoerd)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}...te dicht bij een andere industrie
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Bouw trein om voor een ander ladingtype
+STR_RAIL_REFIT_VEHICLE :{BLACK}Bouw trein om
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Kies type lading om te transporteren
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Bouw trein om voor geselecteerde ladingtype
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Kan trein niet ombouwen...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Reparatie intervallen zijn in percentages: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Verander productie
+
+TEMP_AI_IN_PROGRESS :{WHITE}Welkom bij deze nieuwe AI, in aanbouw. Je kan problemen verwachten. Gebeurt dat, maak een screenshot en plaats die op het forum. Veel plezier!
+TEMP_AI_ACTIVATED :{WHITE}Waarschuwing: deze nieuwe AI is nog steeds alpha! Momenteel werken alleen vrachtwagens en bussen!
+TEMP_AI_MULTIPLAYER :{WHITE}Waarschuwing: Deze functie is experimenteel. Mail eventuele problemen naar truelight@openttd.org.
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Netwerkspel
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Spelernaam:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}Dit is de naam waarmee andere spelers je herkennen
+STR_NETWORK_CONNECTION :{BLACK}Verbinding:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Kies tussen een internet spel of een lokaal netwerk spel
+
+STR_NETWORK_START_SERVER :{BLACK}Start server
+STR_NETWORK_START_SERVER_TIP :{BLACK}Start eigen server
+
+STR_NETWORK_GAME_NAME :{BLACK}Naam
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Naam van het spel
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Taal, serverversie, etc.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Klik op een spel uit de lijst om deze te selecteren
+
+STR_NETWORK_FIND_SERVER :{BLACK}Server zoeken
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Zoeken naar een netwerkserver
+STR_NETWORK_ADD_SERVER :{BLACK}Voeg server toe
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Voegt een server toe aan de lijst die altijd gecontroleerd zal worden op draaiende spellen.
+STR_NETWORK_ENTER_IP :{BLACK}IP adres van de server invoeren
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Spelers
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Spelers online / spelers maximaal
+STR_NETWORK_GAME_INFO :{SILVER}SPEL INFORMATIE
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Spelers: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Taal: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Klimaat: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Kaartgrootte: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}Server versie: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}Server adres: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Start datum: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Huidige datum: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Beveiligd met wachtwoord!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}SERVER OFFLINE
+STR_NETWORK_SERVER_FULL :{SILVER}SERVER VOL
+STR_NETWORK_VERSION_MISMATCH :{SILVER}ANDERE VERSIE
+STR_NETWORK_GRF_MISMATCH :{SILVER}NEWGRF NIET GELIJK
+
+STR_NETWORK_JOIN_GAME :{BLACK}Meespelen
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}Start nieuw spel
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Spelnaam:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}De spelnaam wordt weergegeven aan andere spelers in het multiplayer spelselectie menu
+STR_NETWORK_SET_PASSWORD :{BLACK}Zet wachtwoord
+STR_NETWORK_PASSWORD_TIP :{BLACK}Bescherm je spel met een wachtwoord als je niet wil dat andere mensen meespelen
+STR_NETWORK_SELECT_MAP :{BLACK}Selecteer een kaart:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}Op welke kaart wil je spelen?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}Maximaal aantal spelers
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Kies een maximaal aantal toegestane spelers. Niet alle posities hoeven gebruikt te worden.
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :Netwerk
+STR_NETWORK_INTERNET :Internet
+STR_NETWORK_LAN_INTERNET :LAN / Internet
+STR_NETWORK_INTERNET_ADVERTISE :Internet (adverteren)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 spelers
+STR_NETWORK_1_PLAYERS :1 speler
+STR_NETWORK_2_PLAYERS :2 spelers
+STR_NETWORK_3_PLAYERS :3 spelers
+STR_NETWORK_4_PLAYERS :4 spelers
+STR_NETWORK_5_PLAYERS :5 spelers
+STR_NETWORK_6_PLAYERS :6 spelers
+STR_NETWORK_7_PLAYERS :7 spelers
+STR_NETWORK_8_PLAYERS :8 spelers
+STR_NETWORK_9_PLAYERS :9 spelers
+STR_NETWORK_10_PLAYERS :10 spelers
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}Max bedrijven:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Beperk de server tot een bepaald aantal bedrijven
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}Max toeschouwers:
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Beperk de server tot een bepaald aantal toeschouwers
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Gesproken taal:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Andere spelers zullen weten welke taal er wordt gesproken op de server.
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}Start spel
+STR_NETWORK_START_GAME_TIP :{BLACK}Start een nieuw netwerkspel van een willekeurige kaart, of scenario
+STR_NETWORK_LOAD_GAME :{BLACK}Laad spel
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Hervat een eerder opgeslagen netwerkspel (ben er zeker van dat je verbind als de juiste speler)
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Elke
+STR_NETWORK_LANG_ENGLISH :Engels
+STR_NETWORK_LANG_GERMAN :Duits
+STR_NETWORK_LANG_FRENCH :Frans
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Multiplayer lobby
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Klaar om deel te nemen: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}Een lijst met alle bedrijven die momenteel in dit spel bestaan. Je kan meedoen met een bestaand bedrijf of een nieuw bedrijf beginnen.
+STR_NETWORK_NEW_COMPANY :{BLACK}Nieuw bedrijf
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Start een nieuw bedrijf
+STR_NETWORK_SPECTATE_GAME :{BLACK}Bekijk spel
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Bekijk het spel als een toeschouwer
+STR_NETWORK_JOIN_COMPANY :{BLACK}Dit bedrijf
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Help met het beheren van dit bedrijf
+STR_NETWORK_REFRESH :{BLACK}Ververs server
+STR_NETWORK_REFRESH_TIP :{BLACK}Ververs de informatie over deze server
+
+STR_NETWORK_COMPANY_INFO :{SILVER}BEDRIJFSINFORMATIE
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Bedrijfsnaam: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}Begonnen in: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}Bedrijfswaarde: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Huidige kas: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Inkomen vorig jaar: {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}Prestatie: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}Voertuigen: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Stations: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Spelers: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}Verbinden...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) Verbinden...
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Inloggen...
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Wachten...
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Downloaden kaart...
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Verwerken data...
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) Registeren...
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Ophalen spelinformatie...
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Ophalen bedrijfsinformatie...
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} spelers{P "" s} voor ons
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} kbytes gedownloaded
+
+STR_NETWORK_DISCONNECT :{BLACK}Verbinding verbroken
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Voer het geldbedrag dat je wilt geven in
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Server is beveiligd. Voer wachtwoord in.
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Bedrijf is beveiligd. Voer wachtwoord in.
+STR_NETWORK_CLIENT_LIST :{WHITE}Spelers Lijst
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE} Geen netwerkapparaten gevonden of gecompileerd zonder ENABLE_NETWORK
+STR_NETWORK_ERR_NOSERVER :{WHITE} Kon geen enkel netwerkspel vinden
+STR_NETWORK_ERR_NOCONNECTION :{WHITE} De server beantwoorde het verzoek niet
+STR_NETWORK_ERR_DESYNC :{WHITE} Netwerkspel synchronisatie mislukt.
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} Netwerkspel verbinding kwijt.
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} Kon server-opgeslagen spel niet laden
+STR_NETWORK_ERR_SERVER_START :{WHITE} Kan server niet starten.
+STR_NETWORK_ERR_CLIENT_START :{WHITE} Kan geen verbinding maken.
+STR_NETWORK_ERR_TIMEOUT :{WHITE} Verbinding #{NUM} duurde te lang.
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE} Er is een protocol-fout gemaakt en onze verbinding is gesloten.
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE} De revisie van deze client komt niet overeen met de revisie van de server.
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} Ongeldig wachtwoord.
+STR_NETWORK_ERR_SERVER_FULL :{WHITE} De server is vol
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE}Je bent verbannen van deze server
+STR_NETWORK_ERR_KICKED :{WHITE} Je bent van de server geschopt
+STR_NETWORK_ERR_CHEATER :{WHITE} Valsspelen is niet toegestaan op deze server
+
+STR_NETWORK_ERR_LEFT :heeft het spel verlaten
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :algemene fout
+STR_NETWORK_ERR_CLIENT_DESYNC :desynchronisatie fout
+STR_NETWORK_ERR_CLIENT_SAVEGAME :kan kaart niet laden
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :verbinding verbroken
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :protocol fout
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :niet toegelaten
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :raar pakket ontvangen
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :foute revisie
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :naam al in gebruik
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :fout spel-wachtwoord
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :fout speler-nummer in DoCommand
+STR_NETWORK_ERR_CLIENT_KICKED :geschopt door server
+STR_NETWORK_ERR_CLIENT_CHEATER :probeerde vals te spelen
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :server is vol
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :heeft zich bij het spel gevoegd
+STR_NETWORK_GIVE_MONEY :heeft je geld gegeven ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :je hebt {STRING} wat geld gegeven ({CURRENCY})
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Team] :
+STR_NETWORK_CHAT_COMPANY :[Team] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Team] Aan {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[Prive] :
+STR_NETWORK_CHAT_CLIENT :[Prive] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[Prive] Aan {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[Iedereen] :
+STR_NETWORK_CHAT_ALL :[Iedereen] {STRING}: {GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :heeft zijn naam veranderd in
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE} De server heeft de sessie gestopt.
+STR_NETWORK_SERVER_REBOOT :{WHITE} De server wordt opnieuw gestart...{}Wacht aub...
+
+STR_NETWORK_SERVER :Server
+STR_NETWORK_CLIENT :Client
+STR_NETWORK_SPECTATORS :Toeschouwer
+
+STR_NETWORK_CLIENTLIST_NONE :(geen)
+STR_NETWORK_CLIENTLIST_KICK :Schop uit het spel
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Geef geld
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Praat met iedereen
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Praat met het bedrijf
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Praat met deze persoon
+
+
+STR_NETWORK_SEND :{BLACK}Verstuur
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}X-grootte van de kaart: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Y-grootte van de kaart: {ORANGE}{STRING}
+
+
+##### PNG-MAP-Loader
+
+STR_PNGMAP_ERROR :{WHITE}Kan landschap uit PNG niet laden...
+STR_PNGMAP_ERR_FILE_NOT_FOUND :{WHITE}...bestand niet gevonden.
+STR_PNGMAP_ERR_IMAGE_TYPE :{WHITE}...kon plaatje niet omzetten. 8 óf 24-bit PNG benodigd.
+STR_PNGMAP_ERR_MISC :{WHITE}...er ging iets fout. Sorry. (waarschijnlijk corrupt bestand)
+
+STR_BMPMAP_ERROR :{WHITE}Kan het landschap uit de BMP niet laden...
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}...kan dit type foto niet omzetten.
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Kosten: {CURRENCY}
+STR_0801_COST :{RED}Kosten: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Inkomsten: {CURRENCY}
+STR_0803_INCOME :{GREEN}Inkomsten: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Overladen: {CURRENCY}
+STR_FEEDER :{YELLOW}Overladen: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Verwachte kosten: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Verwachte inkomsten: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Kan het land hier niet verhogen...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Kan het land hier niet verlagen...
+STR_080A_ROCKS :Rotsen
+STR_080B_ROUGH_LAND :Ruw land
+STR_080C_BARE_LAND :Onbegroeid land
+STR_080D_GRASS :Gras
+STR_080E_FIELDS :Akkers
+STR_080F_SNOW_COVERED_LAND :Sneeuw
+STR_0810_DESERT :Woestijn
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Landhelling is in de verkeerde richting
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Onmogelijke spoorcombinatie
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}Graafwerkzaamheden zouden tunnel beschadigen
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Reeds op zeeniveau
+STR_1004_TOO_HIGH :{WHITE}Te hoog
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Geen bruikbaar spoor
+STR_1007_ALREADY_BUILT :{WHITE}...reeds gebouwd
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Bestaand spoor moet eerst weggehaald worden
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Spoorwegconstructie
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Geëlectrificeerde spoorwegconstructie
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Monorailconstructie
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}MagLevconstructie
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Kies spoorbrug
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Kan hier geen treindepot bouwen...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Kan hier geen treinstation bouwen...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Kan hier geen seinen plaatsen...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Kan hier geen spoor leggen...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Kan hier geen spoor weghalen...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Kan hier geen seinen weghalen...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Bouw Treindepot
+STR_1015_RAILROAD_CONSTRUCTION :Spoorwegconstructie
+STR_TOOLB_ELRAIL_CONSTRUCTION :Geëlectrificeerde spoorwegconstructie
+STR_1016_MONORAIL_CONSTRUCTION :Monorailconstructie
+STR_1017_MAGLEV_CONSTRUCTION :MagLevconstructie
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Plaats spoor
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Bouw treindepot (om treinen te bouwen en te onderhouden)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Bouw treinstation
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Plaats seinen
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Bouw spoorbrug
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Graaf spoortunnel
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Kies tussen bouwen en weghalen voor spoor en seinen
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Brugkeuze - klik op de gewenste brug om die te bouwen
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Kies richting van treindepot
+STR_1021_RAILROAD_TRACK :Spoor
+STR_1023_RAILROAD_TRAIN_DEPOT :Treindepot
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...gebied is van ander bedrijf
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :Spoor met normale seinen
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :Spoor met voorseinen
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :Spoor met uitgangseinen
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :Spoor met combinatieseinen
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Moet weg eerst weghalen
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Er wordt aan de weg gewerkt
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Wegenbouw
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Kies brug
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Kan hier geen weg bouwen...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Kan hier geen weg weghalen...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Bouw wegvoertuigdepot
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Kan hier geen vrachtwagendepot bouwen...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Kan hier geen bushalte bouwen...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Kan hier geen laadstation bouwen...
+STR_180A_ROAD_CONSTRUCTION :Wegenbouw
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Bouw weg
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Bouw wegvoertuigdepot (om voertuigen te bouwen en te repareren)
+STR_180D_BUILD_BUS_STATION :{BLACK}Bouw bushalte
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Bouw vrachtwagen laadhal
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Bouw brug voor wegvoertuigen
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Bouw wegtunnel
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Schakel tussen bouwen en verwijderen voor wegbouw
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Selecteer richting van wegvoertuigdepot
+STR_1814_ROAD :Weg
+STR_1815_ROAD_WITH_STREETLIGHTS :Weg met straatlantaarns
+STR_1816_TREE_LINED_ROAD :Weg met bomenrij
+STR_1817_ROAD_VEHICLE_DEPOT :Wegvoertuigdepot
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :Gelijke weg/spoorweg kruising
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Steden
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Gebouw moet eerst gesloopt worden
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}Bevolking: {ORANGE}{COMMA}{BLACK} Huizen: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Hernoem stad
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Kan stad niet hernoemen...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}De gemeenteraad van {TOWN} staat dit niet toe
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Plaatsnamen - klik op naam om het hoofdbeeld te centreren op de stad
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centreer het hoofdbeeld op de lokatie van de stad
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Hernoem stad
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passagiers afelopen maand: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Post afgelopen maand: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Hoog kantoorgebouw
+STR_2010_OFFICE_BLOCK :Kantoorgebouw
+STR_2011_SMALL_BLOCK_OF_FLATS :Klein flatgebouw
+STR_2012_CHURCH :Kerk
+STR_2013_LARGE_OFFICE_BLOCK :Groot kantoorgebouw
+STR_2014_TOWN_HOUSES :Stedelijke huizen
+STR_2015_HOTEL :Hotel
+STR_2016_STATUE :Standbeeld
+STR_2017_FOUNTAIN :Fontein
+STR_2018_PARK :Park
+STR_2019_OFFICE_BLOCK :Kantorenblok
+STR_201A_SHOPS_AND_OFFICES :Winkels en kantoren
+STR_201B_MODERN_OFFICE_BUILDING :Modern kantoorgebouw
+STR_201C_WAREHOUSE :Warenhuis
+STR_201D_OFFICE_BLOCK :Kantoorgebouw
+STR_201E_STADIUM :Stadion
+STR_201F_OLD_HOUSES :Oude huizen
+STR_2020_LOCAL_AUTHORITY :{BLACK}Gemeente
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Geef informatie over de gemeente weer
+STR_2022_LOCAL_AUTHORITY :{WHITE}{TOWN}'s gemeenteraad
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Reputatie van transportbedrijven:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Subsidies
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Beschikbare subsidies:
+STR_2027_FROM_TO :{ORANGE}{STRING} van {STRING} naar {STRING}
+STR_2028_BY :{YELLOW} (voor {DATE_SHORT})
+STR_202A_NONE :{ORANGE}Geen
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Bestaande subsidies:
+STR_202C_FROM_TO :{ORANGE}{STRING} van {STATION} naar {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, tot {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}Subsidieaanbod is verlopen:{}{}{STRING} van {STRING} naar {STRING} wordt nu niet meer gesubsidieerd.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Subsidie teruggetrokken:{}{}{STRING}route van {STATION} naar {STATION} is nu niet meer gesubsidieerd.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Subsidie aangeboden:{}{}Eerste {STRING}route van {STRING} naar {STRING} krijgt een jaar lang subsidie van de gemeente!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subsidie uitgereikt aan {COMPANY}!{}{}{STRING}route van {STATION} naar {STATION} krijgt 50% extra voor het volgende jaar!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subsidie uitgereikt aan {COMPANY}!{}{}{STRING}route van {STATION} naar {STATION} krijgt dubbele omzet voor het volgende jaar!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subsidie uitgereikt aan {COMPANY}!{}{}{STRING}route van {STATION} naar {STATION} krijgt driedubbele omzet voor het volgende jaar!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subsidie uitgereikt aan {COMPANY}!{}{}{STRING}route van {STATION} naar {STATION} krijgt vierdubbele omzet voor het volgende jaar!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}De gemeenteraad van {TOWN} staat bouwen van nog een vliegveld niet toe
+STR_2036_COTTAGES :Plattelandshuisjes
+STR_2037_HOUSES :Huizen
+STR_2038_FLATS :Flats
+STR_2039_TALL_OFFICE_BLOCK :Hoog kantoorgebouw
+STR_203A_SHOPS_AND_OFFICES :Winkels en kantoren
+STR_203B_SHOPS_AND_OFFICES :Winkels en kantoren
+STR_203C_THEATER :Theater
+STR_203D_STADIUM :Stadion
+STR_203E_OFFICES :Kantoren
+STR_203F_HOUSES :Huizen
+STR_2040_CINEMA :Bioscoop
+STR_2041_SHOPPING_MALL :Winkelcentrum
+STR_2042_DO_IT :{BLACK}Doe het
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}Lijst met dingen die mogelijk zijn in deze stad - klik op een item voor meer details
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Voer de geselecteerde actie uit in de bovenstaande lijst
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Mogelijkheiden:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Kleine reclamecampagne
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Middelgrote reclamecampagne
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Grote reclamecampagne
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Betaal wegreparatie
+STR_204A_BUILD_STATUE_OF_COMPANY :Bouw standbeeld van directeur
+STR_204B_FUND_NEW_BUILDINGS :Betaal nieuwe gebouwen
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Koop exclusieve transportrechten
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Koop de gemeenteraad om
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Begin een kleine reclamecampagne, om meer passagiers en goederen naar je transportdiensten te trekken.{} Kosten: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Begin een middelgrote advertentiecampagne, om meer passagiers en goederen naar je transportdiensten te trekken.{} Kosten: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Begin een grote advertentiecampagne, om meer passagiers en goederen naar je transportdiensten te trekken.{} Kosten: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} Betaal een vernieuwing van het wegdek. Veroorzaakt merkbare verstoring van het wegverkeer tot 6 maanden.{} Kosten: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Bouw een standbeeld ter ere van jouw bedrijf.{} Kosten: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Betaal de bouw van nieuwe commerciele gebouwen in de stad.{} Kosten: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Koop 1 jaar exclusieve transportrechten in deze stad. De gemeenteraad staat passagiers en goederen toe alleen jouw stations te gebruiken.{} Kosten: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Koop het plaatselijk gezag om om je rang te verhogen, met het gevaar van een strenge sanctie, wanneer gepakt.{} Kosten: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}Verkeerschaos in {TOWN}!{}{}Wegreparatie betaald door {COMPANY} zorgt voor 6 maanden van irritatie bij weggebruikers!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (in aanbouw)
+STR_2059_IGLOO :Iglo
+STR_205A_TEPEES :Tepees
+STR_205B_TEAPOT_HOUSE :Theepothuis
+STR_205C_PIGGY_BANK :Varkensbank
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN} {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Terreinvorming
+STR_2800_PLANT_TREES :Plant bomen
+STR_2801_PLACE_SIGN :Plaats bord
+STR_2802_TREES :{WHITE}Bomen
+STR_2803_TREE_ALREADY_HERE :{WHITE}....er staat hier al een boom
+STR_2804_SITE_UNSUITABLE :{WHITE}...plek niet geschikt
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Kan hier geen boom planten...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...teveel borden
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Kan hier geen bord plaatsen
+STR_280A_SIGN :Bord
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Wijzig tekst van bord
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Kan de naam van het bord niet wijzigen
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Kies een boom om te planten
+STR_280E_TREES :Bomen
+STR_280F_RAINFOREST :Tropisch bos
+STR_2810_CACTUS_PLANTS :Cactus planten
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Station selectie
+STR_3001_AIRPORT_SELECTION :{WHITE}Vliegveld selectie
+STR_3002_ORIENTATION :{BLACK}Richting
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Aantal sporen
+STR_3004_PLATFORM_LENGTH :{BLACK}Platformlengte
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Te dicht bij een ander station
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Voegt meer dan één bestaand (laad)station samen
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}Teveel (laad)stations in de buurt van deze stad
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}Teveel (laad)stations
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Te veel bushaltes
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}Te veel vrachtwagenstations
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Te dicht bij een andere (laad)station
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Verwijder eerst treinstation
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Te dicht bij een ander vliegveld
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Verwijder eerst vliegveld
+
+STR_3030_RENAME_STATION_LOADING :Hernoem station/laadgebied
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Kan station niet hernoemen...
+STR_3032_RATINGS :{BLACK}Rangen
+STR_3033_ACCEPTS :{BLACK}Accepteert
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}Lokale rang van de vervoerdienst:
+
+############ range for rating starts
+STR_3035_APPALLING :Teleurstellend
+STR_3036_VERY_POOR :Erg slecht
+STR_3037_POOR :Slecht
+STR_3038_MEDIOCRE :Matig
+STR_3039_GOOD :Goed
+STR_303A_VERY_GOOD :Erg goed
+STR_303B_EXCELLENT :Geweldig
+STR_303C_OUTSTANDING :Uitstekend
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} accepteert niet langer {STRING}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} accepteert niet langer {STRING} en {STRING}
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} accepteert voortaan {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} accepteert voortaan {STRING} en {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Bouw bushalte
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Bouw Vrachtwagenstation
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Verwijder eerst bushalte
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Verwijder eerst vrachtwagenstation
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Stations
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Geen -
+STR_304B_SITE_UNSUITABLE :{WHITE}...plaats ongeschikt
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Te dicht bij een andere dok
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Verwijder eerst dock
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Selecteer treinstation richting
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Selecteer aantal platforms voor station
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Selecteer lengte van station
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Selecteer richting van bushalte
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Selecteer richting van vrachtwagenstation
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Centreer hoofdbeeld op lokatie van station
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Bekijk stationsreputaties
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Hernoem station
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Laat lijst van gevraagde goederen zien
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Station namen - klik op naam om het hoofdbeeld te centreren op het station
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Selecteer grootte en type van vliegveld
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :Treinstation
+STR_305F_AIRCRAFT_HANGAR :Vliegtuighangar
+STR_3060_AIRPORT :Vliegveld
+STR_3061_TRUCK_LOADING_AREA :Truck laadgebied
+STR_3062_BUS_STATION :Bushalte
+STR_3063_SHIP_DOCK :Haven
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Markeer het dekkingsgebied van de voorgestelde locatie
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Markeer het dekkingsgebied van de voorgestelde locatie niet
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Dekkingsgebied markeren
+STR_3068_DOCK :{WHITE}Dok
+STR_3069_BUOY :Boei
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...boei in de weg
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...station te verspreid
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...niet uniforme stations uit
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Houd CTRL ingedrukt om meer items te kiezen
+
+STR_UNDEFINED :(ongedefinieerde string)
+STR_STAT_CLASS_DFLT :Standaard station
+STR_STAT_CLASS_WAYP :Routepunt
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Bouw scheepswerf
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...moet op water gebouwd worden
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Kan scheepswerf hier niet bouwen...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Selecteer scheepswerf orientatie
+STR_3804_WATER :Water
+STR_3805_COAST_OR_RIVERBANK :Kust of rivierbed
+STR_3806_SHIP_DEPOT :Scheepswerf
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...Kan niet op water bouwen
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Spel Opslaan
+STR_4001_LOAD_GAME :{WHITE}Spel Laden
+STR_4002_SAVE :{BLACK}Opslaan
+STR_4003_DELETE :{BLACK}Verwijderen
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} megabytes vrij
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Kan niet lezen van schijf
+STR_4007_GAME_SAVE_FAILED :{WHITE}Opslaan Spel Mislukt
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Kan bestand niet verwijderen
+STR_4009_GAME_LOAD_FAILED :{WHITE}Laden Spel Mislukt
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}Lijst van schijven, mappen, en opgeslagen spellen
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Huidige gekozen naam voor opgeslagen spel
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Verwijder het momenteel geselecteerde opgeslagen spel
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Sla het huidige spel op onder de gekozen naam
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Selecteer nieuw speltype
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Selecteer scenario (groen), vooraf ingesteld spel (blauw), or willekeurig nieuw spel
+STR_4010_GENERATE_RANDOM_NEW_GAME :Genereer willekeurig nieuw spel
+STR_4011_LOAD_HEIGHTMAP :{WHITE}Laad Heightmap
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} in de weg
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :Kolenmijn
+STR_4803_POWER_STATION :Energiecentrale
+STR_4804_SAWMILL :Houtzagerij
+STR_4805_FOREST :Bos
+STR_4806_OIL_REFINERY :Olieraffinaderij
+STR_4807_OIL_RIG :Olieplatform
+STR_4808_FACTORY :Fabriek
+STR_4809_PRINTING_WORKS :Drukkerij
+STR_480A_STEEL_MILL :Hoogoven
+STR_480B_FARM :Boerderij
+STR_480C_COPPER_ORE_MINE :Kopermijn
+STR_480D_OIL_WELLS :Oliebron
+STR_480E_BANK :Bank
+STR_480F_FOOD_PROCESSING_PLANT :Voedselfabriek
+STR_4810_PAPER_MILL :Papierfabriek
+STR_4811_GOLD_MINE :Goudmijn
+STR_4812_BANK :Bank
+STR_4813_DIAMOND_MINE :Diamandmijn
+STR_4814_IRON_ORE_MINE :IJzermijn
+STR_4815_FRUIT_PLANTATION :Boomgaard
+STR_4816_RUBBER_PLANTATION :Rubberboerderij
+STR_4817_WATER_SUPPLY :Waterbron
+STR_4818_WATER_TOWER :Watertoren
+STR_4819_FACTORY :Fabriek
+STR_481A_FARM :Boerderij
+STR_481B_LUMBER_MILL :Houtkapperij
+STR_481C_COTTON_CANDY_FOREST :Suikerspinbos
+STR_481D_CANDY_FACTORY :Snoepfabriek
+STR_481E_BATTERY_FARM :Batterijplantage
+STR_481F_COLA_WELLS :Colabronnen
+STR_4820_TOY_SHOP :Speelgoedwinkel
+STR_4821_TOY_FACTORY :Speelgoedfabriek
+STR_4822_PLASTIC_FOUNTAINS :Plasticfonteinen
+STR_4823_FIZZY_DRINK_FACTORY :Frisdrankfabriek
+STR_4824_BUBBLE_GENERATOR :Bellenblazer
+STR_4825_TOFFEE_QUARRY :Toffeegroeve
+STR_4826_SUGAR_MINE :Suikermijn
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Vereist: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Vereist: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Vereist: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Productie vorige maand:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% getransporteerd)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centreer het hoofdbeeld op de locatie van de industrie
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Nieuw {STRING} in aanbouw bij {TOWN}!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Nieuw {STRING} in aanplant bij {TOWN}!
+STR_482F_COST :{BLACK}Kosten: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Kan dit type industrie hier niet bouwen...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...bossen kunnen alleen worden geplant boven de sneeuwgrens
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} kondigt dreigend faillissement aan!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}Leveringsproblemen noodzaken {INDUSTRY} dreigend faillissement aan te kondigen!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}Gebrek aan nabije bomen noodzaakt {INDUSTRY} dreigend faillissement aan te kondigen!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} verhoogt productie!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}Nieuwe kolenader gevonden bij {INDUSTRY}!{}Men verwacht productieverdubbeling!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}Nieuwe oliebronnen gevonden bij {INDUSTRY}!{}Men verwacht productieverdubbeling!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}Verbeterde landbouwmethoden bij {INDUSTRY} zorgen voor een verwachte productieverdubbeling!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}Productie van {INDUSTRY} verlaagd met 50%
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}Insectenplaag zorgt voor ravage bij {INDUSTRY}!{}Productie gezakt met 50%
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...kan alleen aan de rand van de kaart geplaatst worden
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}{STRING} productie van {INDUSTRY} stijgt met {COMMA}%!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}{STRING} productie van {INDUSTRY} daalt met {COMMA}%!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Trein in tunnel
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Wegvoertuig in tunnel
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Andere tunnel in de weg
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Kan geen land uitgraven voor andere uiteinde tunnel
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Tunnel moet eerst afgebroken worden
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Brug moet eerst afgebroken worden
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Kan niet beginnen en eindigen op dezelfde plaats
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Vlak land of water vereist onder brug
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}Begin en einde moeten op een lijn staan
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Locatie ongeschikt voor ingang tunnel
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Hangbrug, Staal
+STR_500F_GIRDER_STEEL :Vlak, Staal
+STR_5010_CANTILEVER_STEEL :Cantilever, Staal
+STR_5011_SUSPENSION_CONCRETE :Hangbrug, Beton
+STR_5012_WOODEN :Hout
+STR_5013_CONCRETE :Beton
+STR_5014_TUBULAR_STEEL :Koker, Staal
+STR_BRIDGE_TUBULAR_SILICON :Koker, Silicium
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Kan hier geen brug bouwen...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Kan hier geen tunnel bouwen...
+STR_5017_RAILROAD_TUNNEL :Spoortunnel
+STR_5018_ROAD_TUNNEL :Weg tunnel
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Stalen hangende spoorweg brug
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Stalen spoor brug
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Stalen cantilever spoorweg brug
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Gewapend betonnen hangende spoorweg brug
+STR_501F_WOODEN_RAIL_BRIDGE :Houten spoorweg brug
+STR_5020_CONCRETE_RAIL_BRIDGE :Betonnen spoorweg brug
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Stalen hangende weg brug
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Stalen vlakke weg brug
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Stalen cantilever weg brug
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Gewapend betonnen hangende weg brug
+STR_5025_WOODEN_ROAD_BRIDGE :Houten weg brug
+STR_5026_CONCRETE_ROAD_BRIDGE :Betonnen weg brug
+STR_5027_TUBULAR_RAIL_BRIDGE :Kokervormige spoorweg brug
+STR_5028_TUBULAR_ROAD_BRIDGE :Kokervormige weg brug
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Object in de weg
+STR_5801_TRANSMITTER :Zender
+STR_5802_LIGHTHOUSE :Vuurtoren
+STR_5803_COMPANY_HEADQUARTERS :Bedrijfs Hoofdkwartier
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...bedrijfs hoofdkwartier in de weg
+STR_5805_COMPANY_OWNED_LAND :Door een bedrijf opgekocht terrein
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Kan dit stuk land niet kopen...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...het is al van jou!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Geen naam
+STR_SV_TRAIN_NAME :Trein {COMMA}
+STR_SV_ROADVEH_NAME :Automobiel {COMMA}
+STR_SV_SHIP_NAME :Schip {COMMA}
+STR_SV_AIRCRAFT_NAME :Vliegtuig {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :{STRING} Noord
+STR_SV_STNAME_SOUTH :{STRING} Zuid
+STR_SV_STNAME_EAST :{STRING} Oost
+STR_SV_STNAME_WEST :{STRING} West
+STR_SV_STNAME_CENTRAL :{STRING} Centraal
+STR_SV_STNAME_TRANSFER :{STRING} Transferium
+STR_SV_STNAME_HALT :{STRING} Halte
+STR_SV_STNAME_VALLEY :{STRING} Vallei
+STR_SV_STNAME_HEIGHTS :{STRING} Hoogte
+STR_SV_STNAME_WOODS :{STRING} Bossen
+STR_SV_STNAME_LAKESIDE :{STRING} Meerkant
+STR_SV_STNAME_EXCHANGE :{STRING} Uitwisseling
+STR_SV_STNAME_AIRPORT :{STRING} Vliegveld
+STR_SV_STNAME_OILFIELD :{STRING} Olieveld
+STR_SV_STNAME_MINES :{STRING} Mijnen
+STR_SV_STNAME_DOCKS :{STRING} Haven
+STR_SV_STNAME_BUOY_1 :{STRING} Boei 1
+STR_SV_STNAME_BUOY_2 :{STRING} Boei 2
+STR_SV_STNAME_BUOY_3 :{STRING} Boei 3
+STR_SV_STNAME_BUOY_4 :{STRING} Boei 4
+STR_SV_STNAME_BUOY_5 :{STRING} Boei 5
+STR_SV_STNAME_BUOY_6 :{STRING} Boei 6
+STR_SV_STNAME_BUOY_7 :{STRING} Boei 7
+STR_SV_STNAME_BUOY_8 :{STRING} Boei 8
+STR_SV_STNAME_BUOY_9 :{STRING} Boei 9
+STR_SV_STNAME_ANNEXE :{STRING} Bijbouw
+STR_SV_STNAME_SIDINGS :{STRING} Zijspoor
+STR_SV_STNAME_BRANCH :{STRING} Aftakking
+STR_SV_STNAME_UPPER :Hoger {STRING}
+STR_SV_STNAME_LOWER :Lager {STRING}
+STR_SV_STNAME_HELIPORT :{STRING} Helihaven
+STR_SV_STNAME_FOREST :{STRING} Bossen
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Moeilijksheidsgraad
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Opslaan
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Gemakkelijk
+STR_6802_MEDIUM :{BLACK}Gemiddeld
+STR_6803_HARD :{BLACK}Moeilijk
+STR_6804_CUSTOM :{BLACK}Aangepast
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maximaal aantal tegenstanders: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Starttijd van tegenstanders: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}Aantal steden: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}Aantal industrieën: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Maximale lening: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Startrente: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Brandstofkosten: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Bouwsnelheid van tegenstanders: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Intelligentie van tegenstanders: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Voertuig defecten: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Vermenigvuldigingsfactor subsidie: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Bouwkosten: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Terreinsoort: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Hoeveelheid zee/meren: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Economie: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Treinen draaien om: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Rampen: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Houding van gemeente mbt landschapsaanpassingen: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :Geen
+STR_6816_LOW :Laag
+STR_6817_NORMAL :Normaal
+STR_6818_HIGH :Hoog
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Erg langzaam
+STR_681C_SLOW :Langzaam
+STR_681D_MEDIUM :Gemiddeld
+STR_681E_FAST :Snel
+STR_681F_VERY_FAST :Erg snel
+STR_VERY_LOW :Erg laag
+STR_6820_LOW :Laag
+STR_6821_MEDIUM :Gemiddeld
+STR_6822_HIGH :Hoog
+STR_6823_NONE :Geen
+STR_6824_REDUCED :Verminderd
+STR_6825_NORMAL :Normaal
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Erg plat
+STR_682B_FLAT :Plat
+STR_682C_HILLY :Heuvelachtig
+STR_682D_MOUNTAINOUS :Bergachtig
+STR_682E_STEADY :Stabiel
+STR_682F_FLUCTUATING :Schommelend
+STR_6830_IMMEDIATE :Meteen
+STR_6831_3_MONTHS_AFTER_PLAYER :3 maanden na speler
+STR_6832_6_MONTHS_AFTER_PLAYER :6 maanden na speler
+STR_6833_9_MONTHS_AFTER_PLAYER :9 maanden na speler
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :Aan het eind van het spoor, en in stations
+STR_6835_AT_END_OF_LINE_ONLY :Aan het eind van het spoor
+STR_6836_OFF :Uit
+STR_6837_ON :Aan
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Bekijk topscore lijst
+STR_6839_PERMISSIVE :Tolerant
+STR_683A_TOLERANT :Neutraal
+STR_683B_HOSTILE :Negatief
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Speler {COMMA})
+STR_7004_NEW_FACE :{BLACK}Nieuw gezicht
+STR_7005_COLOR_SCHEME :{BLACK}Kleurenschema
+STR_7006_COLOR_SCHEME :{GOLD}Kleurenschema:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Nieuw kleurenschema
+STR_7008_COMPANY_NAME :{BLACK}Bedrijfsnaam
+STR_7009_PRESIDENT_NAME :{BLACK}Naam directeur
+STR_700A_COMPANY_NAME :Bedrijfsnaam
+STR_700B_PRESIDENT_S_NAME :Naam van directeur
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Kan bedrijfsnaam niet veranderen...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Kan naam directeur niet veranderen...
+STR_700E_FINANCES :{WHITE}{COMPANY} Financiën {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Uitgaven/inkomsten
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Bouwkosten
+STR_7012_NEW_VEHICLES :{GOLD}Nieuwe voertuigen
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Trein brandstofkosten
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Wegvoertuig brandstofkosten
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Vliegtuig brandstofkosten
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Schip brandstofkosten
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Eigendomsonderhoud
+STR_7018_TRAIN_INCOME :{GOLD}Treininkomsten
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Wegvoertuiginkomsten
+STR_701A_AIRCRAFT_INCOME :{GOLD}Vliegtuiginkomsten
+STR_701B_SHIP_INCOME :{GOLD}Schipinkomsten
+STR_701C_LOAN_INTEREST :{GOLD}Rente van lening
+STR_701D_OTHER :{GOLD}Overig
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Totaal:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Inkomstengrafiek
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Bedrijfswinst Grafiek
+STR_7026_BANK_BALANCE :{WHITE}Banksaldo
+STR_7027_LOAN :{WHITE}Lening
+STR_MAX_LOAN :{WHITE}Max lening: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}Leen {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Betaal {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY} terug
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...maximaal toegestane leninggrootte is {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Kan geen geld meer lenen...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...geen lening om terug te betalen
+STR_702E_REQUIRED :{WHITE}...{CURRENCY} benodigd
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Kan geen lening terugbetalen
+STR_INSUFFICIENT_FUNDS :{WHITE}Kan geen geld weggeven dat van de bank geleend is...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Kies nieuw gezicht voor directeur
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Verander het uiterlijk van de bedrijfsvoertuigen
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Verander de naam van de directeur
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Verander de bedrijfsnaam
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Klik op geselecteerde nieuwe kleurenschema
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Vergroot lening
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Betaal deel van lening terug
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(Directeur)
+STR_7038_INAUGURATED :{GOLD}Gesticht: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Voertuigen:
+STR_TRAINS :{WHITE}{COMMA} trein{P "" en}
+STR_ROAD_VEHICLES :{WHITE}{COMMA} wegvoertuig{P "" en}
+STR_AIRCRAFT :{WHITE}{COMMA} vliegtuig{P "" en}
+STR_SHIPS :{WHITE}{COMMA} sch{P ip epen}
+STR_7042_NONE :{WHITE}Geen
+STR_7043_FACE_SELECTION :{WHITE}Gezichtsselectie
+STR_7044_MALE :{BLACK}Mannelijk
+STR_7045_FEMALE :{BLACK}Vrouwelijk
+STR_7046_NEW_FACE :{BLACK}Nieuw gezicht
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Annuleer nieuwe gezichtsselectie
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Accepteer nieuwe gezichtsselectie
+STR_7049_SELECT_MALE_FACES :{BLACK}Selecteer mannelijke gezichten
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Selecteer vrouwelijke gezichten
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Genereer willekeurig nieuw gezicht
+STR_704C_KEY :{BLACK}Legenda
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Laat grafieklegenda zien
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Legenda voor bedrijfsgrafieken
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Klik hier om dit bedrijf weer te geven of te verbergen op de grafiek
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Eenheden van goederen afgeleverd
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Bedrijfs prestatie score (maximale score=1000)
+STR_7052_COMPANY_VALUES :{WHITE}Bedrijfswaarde
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Bedrijfscompetitietabel
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}Transportbedrijf in de problemen!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} wordt verkocht of failliet verklaard tenzij finanicele situatie snel verbetert!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(Directeur)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Transportbedrijf overgenomen!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} is verkocht aan {COMPANY} voor {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}We zoeken voor een transportbedrijf dat ons bedrijf over kan nemen.{}{}Wil je {COMPANY} kopen voor {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Failliet!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} is gesloten door schuldeisers en alle eigendomen zijn verkocht!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}Nieuw transportbedrijf opgestart!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} begint werkzaamheden bij {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Kan bedrijf niet kopen...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Betalingsverhouding Vracht
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Dagen onderweg
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Betaling voor het leveren van 10 eenheden (of 10,000 liter) aan vracht over een afstand van 20 vakjes
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Schakel grafiek voor vrachttype aan/uit
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Ingenieur
+STR_7067_TRAFFIC_MANAGER :Verkeersleider
+STR_7068_TRANSPORT_COORDINATOR :Transport Coördinator
+STR_7069_ROUTE_SUPERVISOR :Route Opzichter
+STR_706A_DIRECTOR :Onderdirecteur
+STR_706B_CHIEF_EXECUTIVE :Directeur
+STR_706C_CHAIRMAN :Voorzitter
+STR_706D_PRESIDENT :President
+STR_706E_TYCOON :Tycoon
+STR_706F_BUILD_HQ :{BLACK}Bouw HQ
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Bouw bedrijfs hoofdkwartier / bekijk bedrijfs hoodkwartier
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Herbouw bedrijfs hoofdkwartier ergens anders voor 1% van de bedrijfswaarde
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Kan bedrijfs hoofdkwartier niet bouwen
+STR_7072_VIEW_HQ :{BLACK}Bekijk HQ
+STR_RELOCATE_HQ :{BLACK}Verplaats HQ
+STR_COMPANY_PASSWORD :{BLACK}Wachtwoord
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Bescherm het bedrijf met een wachtwoord zodat niet geautoriseerde personen niet mee kunnen doen.
+STR_SET_COMPANY_PASSWORD :Geef bedrijfswachtwoord op
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}Wereld Recessie!{}{}Financiële experts vrezen het ergste terwijl economie ineen stort!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Recessie Voorbij!{}{}Stijgende handel geeft industrie vertrouwen terwijl economie verstevigt!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Schakel tussen groot/klein venster
+STR_7076_COMPANY_VALUE :{GOLD}Bedrijfswaarde: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Koop 25% aandeel in bedrijf
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Verkoop 25% aandeel in bedrijf
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Koop een aandeel van 25% in dit bedrijf
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Verkoop een aandeel van 25% in dit bedrijf
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Kan geen 25% aandeel in dit bedrijf kopen...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}Kan geen 25% aandeel in dit bedrijf verkopen...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% eigendom van {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% eigendom van {COMPANY}{} {COMMA}% eigendom van {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} is overgenomen door {COMPANY}!
+STR_7080_PROTECTED :{WHITE}Dit bedrijf verhandelt nog geen aandelen...
+
+STR_LIVERY_DEFAULT :Standaard Logo
+STR_LIVERY_STEAM :Stoom Locomotief
+STR_LIVERY_DIESEL :Diesel Locomotief
+STR_LIVERY_ELECTRIC :Elektrische Locomotief
+STR_LIVERY_MONORAIL :Monorail Trein
+STR_LIVERY_MAGLEV :Zweeftrein
+STR_LIVERY_DMU :DMU
+STR_LIVERY_EMU :EMU
+STR_LIVERY_PASSENGER_WAGON_STEAM :Passagierswagon (Stoom)
+STR_LIVERY_PASSENGER_WAGON_DIESEL :Passagierswagon (Diesel)
+STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Passagierswagon (Elektrisch)
+STR_LIVERY_FREIGHT_WAGON :Vracht Wagon
+STR_LIVERY_BUS :Bus
+STR_LIVERY_TRUCK :Vrachtwagen
+STR_LIVERY_PASSENGER_SHIP :Passagiersboot
+STR_LIVERY_FREIGHT_SHIP :Vrachtschip
+STR_LIVERY_HELICOPTER :Helikopter
+STR_LIVERY_SMALL_PLANE :Klein Vliegtuig
+STR_LIVERY_LARGE_PLANE :Groot Vliegtuig
+
+STR_LIVERY_GENERAL_TIP :{BLACK}Laat de algemene kleurschema's zien
+STR_LIVERY_TRAIN_TIP :{BLACK}Laat trein kleurschema's zien
+STR_LIVERY_ROADVEH_TIP :{BLACK}Laat wegvoertuig kleurschema's zien
+STR_LIVERY_SHIP_TIP :{BLACK}Laat schip kleurschema's zien
+STR_LIVERY_AIRCRAFT_TIP :{BLACK}Laat de vliegtuig kleurschema's zien
+STR_LIVERY_PRIMARY_TIP :{BLACK}Kies de oofdkleur voor het geselecteerde schema
+STR_LIVERY_SECONDARY_TIP :{BLACK}Kies de tweede kleur voor het geselecteerde schema
+STR_LIVERY_PANEL_TIP :{BLACK}Kies een kleurschema om te wijzigen, of meerdere schema's met CTRL+klik. Klik in het venster het gebruik van het kleurschema te kiezen
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (Stoom)
+STR_8001_MJS_250_DIESEL :MJS 250 (Diesel)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut Diesel
+STR_8006_POWERNAUT_DIESEL :Powernaut Diesel
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (Stoom)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (Stoom)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (Stoom)
+STR_800A_SH_8P_STEAM :SH '8P' (Stoom)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (Diesel)
+STR_800C_DASH_DIESEL :'Dash' (Diesel)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (Diesel)
+STR_800E_UU_37_DIESEL :UU '37' (Diesel)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (Diesel)
+STR_8010_CS_4000_DIESEL :CS 4000 (Diesel)
+STR_8011_CS_2400_DIESEL :CS 2400 (Diesel)
+STR_8012_CENTENNIAL_DIESEL :Centennial (Diesel)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (Diesel)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (Diesel)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (Diesel)
+STR_8016_SH_125_DIESEL :SH '125' (Diesel)
+STR_8017_SH_30_ELECTRIC :SH '30' (Elektrisch)
+STR_8018_SH_40_ELECTRIC :SH '40' (Elektrisch)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (Elektrisch)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (Elektrisch)
+STR_801B_PASSENGER_CAR :Passagierswagon
+STR_801C_MAIL_VAN :Postwagen
+STR_801D_COAL_CAR :Kolenwagen
+STR_801E_OIL_TANKER :Olietanker
+STR_801F_LIVESTOCK_VAN :Veewagen
+STR_8020_GOODS_VAN :Goederenwagen
+STR_8021_GRAIN_HOPPER :Graan Wagon
+STR_8022_WOOD_TRUCK :Houttruck
+STR_8023_IRON_ORE_HOPPER :IJzererts Wagon
+STR_8024_STEEL_TRUCK :Staaltruck
+STR_8025_ARMORED_VAN :Gepanserde wagen
+STR_8026_FOOD_VAN :Voedselwagen
+STR_8027_PAPER_TRUCK :Papiertruck
+STR_8028_COPPER_ORE_HOPPER :Kopererts Wagon
+STR_8029_WATER_TANKER :Watertanker
+STR_802A_FRUIT_TRUCK :Fruittruck
+STR_802B_RUBBER_TRUCK :Rubbertruck
+STR_802C_SUGAR_TRUCK :Suikertruck
+STR_802D_COTTON_CANDY_HOPPER :Suikerspin Wagon
+STR_802E_TOFFEE_HOPPER :Toffee Wagon
+STR_802F_BUBBLE_VAN :Bellenwagen
+STR_8030_COLA_TANKER :Colatanker
+STR_8031_CANDY_VAN :Snoepwagen
+STR_8032_TOY_VAN :Speelgoedwagen
+STR_8033_BATTERY_TRUCK :Batterijwagen
+STR_8034_FIZZY_DRINK_TRUCK :Frisdrankwagen
+STR_8035_PLASTIC_TRUCK :Plastic Truck
+STR_8036_X2001_ELECTRIC :'X2001' (Elektrisch)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Elektrisch)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :Passagiers Rijtuig
+STR_803A_MAIL_VAN :Postwagen
+STR_803B_COAL_CAR :Kolen Truck
+STR_803C_OIL_TANKER :Olie Tanker
+STR_803D_LIVESTOCK_VAN :Veewagen
+STR_803E_GOODS_VAN :Goederenwagen
+STR_803F_GRAIN_HOPPER :Graan Wagon
+STR_8040_WOOD_TRUCK :Hout Truck
+STR_8041_IRON_ORE_HOPPER :IJzererts Wagon
+STR_8042_STEEL_TRUCK :Staal Truck
+STR_8043_ARMORED_VAN :Gepanserde wagen
+STR_8044_FOOD_VAN :Voedselwagen
+STR_8045_PAPER_TRUCK :Papier Truck
+STR_8046_COPPER_ORE_HOPPER :Koper erts Wagon
+STR_8047_WATER_TANKER :Water Tanker
+STR_8048_FRUIT_TRUCK :Fruit Truck
+STR_8049_RUBBER_TRUCK :Rubber Truck
+STR_804A_SUGAR_TRUCK :Suiker Truck
+STR_804B_COTTON_CANDY_HOPPER :Suikerspinwagen
+STR_804C_TOFFEE_HOPPER :Toffee Wagon
+STR_804D_BUBBLE_VAN :Bellenwagen
+STR_804E_COLA_TANKER :Cola Tanker
+STR_804F_CANDY_VAN :Snoepwagen
+STR_8050_TOY_VAN :Speelgoedwagen
+STR_8051_BATTERY_TRUCK :Batterij Truck
+STR_8052_FIZZY_DRINK_TRUCK :Frisdrank Truck
+STR_8053_PLASTIC_TRUCK :Plastic Truck
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (Elektrisch)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (Elektrisch)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (Elektrisch)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (Elektrisch)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :Passagiers Rijtuig
+STR_805A_MAIL_VAN :Postwagen
+STR_805B_COAL_CAR :Kolen Truck
+STR_805C_OIL_TANKER :Olie Tanker
+STR_805D_LIVESTOCK_VAN :Veewagen
+STR_805E_GOODS_VAN :Goederenwagen
+STR_805F_GRAIN_HOPPER :Graan Wagon
+STR_8060_WOOD_TRUCK :Hout Truck
+STR_8061_IRON_ORE_HOPPER :IJzererts Wagon
+STR_8062_STEEL_TRUCK :Staal Truck
+STR_8063_ARMORED_VAN :Gepanserde wagen
+STR_8064_FOOD_VAN :Voedselwagen
+STR_8065_PAPER_TRUCK :Papier Truck
+STR_8066_COPPER_ORE_HOPPER :Koper erts Wagon
+STR_8067_WATER_TANKER :Water Tanker
+STR_8068_FRUIT_TRUCK :Fruit Truck
+STR_8069_RUBBER_TRUCK :Rubber Truck
+STR_806A_SUGAR_TRUCK :Suiker Truck
+STR_806B_COTTON_CANDY_HOPPER :Suikerspin Wagon
+STR_806C_TOFFEE_HOPPER :Toffee Wagon
+STR_806D_BUBBLE_VAN :Bellenwagen
+STR_806E_COLA_TANKER :Cola Tanker
+STR_806F_CANDY_VAN :Snoepwagen
+STR_8070_TOY_VAN :Speelgoedwagen
+STR_8071_BATTERY_TRUCK :Batterij Truck
+STR_8072_FIZZY_DRINK_TRUCK :Drank Truck
+STR_8073_PLASTIC_TRUCK :Plastic Truck
+STR_8074_MPS_REGAL_BUS :MPS Regal Bus
+STR_8075_HEREFORD_LEOPARD_BUS :Hereford Leopard Bus
+STR_8076_FOSTER_BUS :Foster Bus
+STR_8077_FOSTER_MKII_SUPERBUS :Foster MkII Superbus
+STR_8078_PLODDYPHUT_MKI_BUS :Ploddyphut MkI Bus
+STR_8079_PLODDYPHUT_MKII_BUS :Ploddyphut MkII Bus
+STR_807A_PLODDYPHUT_MKIII_BUS :Ploddyphut MkIII Bus
+STR_807B_BALOGH_COAL_TRUCK :Balogh Kolen Truck
+STR_807C_UHL_COAL_TRUCK :Uhl Kolen Truck
+STR_807D_DW_COAL_TRUCK :DW Kolen Truck
+STR_807E_MPS_MAIL_TRUCK :MPS Post Truck
+STR_807F_REYNARD_MAIL_TRUCK :Reynard Post Truck
+STR_8080_PERRY_MAIL_TRUCK :Perry Post Truck
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :MightyMover Post Truck
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Powernaught Post Truck
+STR_8083_WIZZOWOW_MAIL_TRUCK :Wizzowow Post Truck
+STR_8084_WITCOMBE_OIL_TANKER :Witcombe Olie Tanker
+STR_8085_FOSTER_OIL_TANKER :Foster Olie Tanker
+STR_8086_PERRY_OIL_TANKER :Perry Olie Tanker
+STR_8087_TALBOTT_LIVESTOCK_VAN :Talbott Veewagen
+STR_8088_UHL_LIVESTOCK_VAN :Uhl Veewagen
+STR_8089_FOSTER_LIVESTOCK_VAN :Foster Veewagen
+STR_808A_BALOGH_GOODS_TRUCK :Balogh Goederen Truck
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Craighead Goederen Truck
+STR_808C_GOSS_GOODS_TRUCK :Goss Goederen Truck
+STR_808D_HEREFORD_GRAIN_TRUCK :Hereford Graan Truck
+STR_808E_THOMAS_GRAIN_TRUCK :Thomas Graan Truck
+STR_808F_GOSS_GRAIN_TRUCK :Goss Graan Truck
+STR_8090_WITCOMBE_WOOD_TRUCK :Witcombe Hout Truck
+STR_8091_FOSTER_WOOD_TRUCK :Foster Hout Truck
+STR_8092_MORELAND_WOOD_TRUCK :Moreland Hout Truck
+STR_8093_MPS_IRON_ORE_TRUCK :MPS IJzererts Truck
+STR_8094_UHL_IRON_ORE_TRUCK :Uhl IJzererts Truck
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Chippy IJzererts Truck
+STR_8096_BALOGH_STEEL_TRUCK :Balogh Staal Truck
+STR_8097_UHL_STEEL_TRUCK :Uhl Staal Truck
+STR_8098_KELLING_STEEL_TRUCK :Kelling Staal Truck
+STR_8099_BALOGH_ARMORED_TRUCK :Balogh Gepanserde Truck
+STR_809A_UHL_ARMORED_TRUCK :Uhl Gepanserde Truck
+STR_809B_FOSTER_ARMORED_TRUCK :Foster Gepanserde Truck
+STR_809C_FOSTER_FOOD_VAN :Foster Voedsel Wagen
+STR_809D_PERRY_FOOD_VAN :Perry Voedsel Wagen
+STR_809E_CHIPPY_FOOD_VAN :Chippy Voedsel Wagen
+STR_809F_UHL_PAPER_TRUCK :Uhl Papierwagen
+STR_80A0_BALOGH_PAPER_TRUCK :Balogh Papierwagen
+STR_80A1_MPS_PAPER_TRUCK :MPS Papier Truck
+STR_80A2_MPS_COPPER_ORE_TRUCK :MPS Koper erts Truck
+STR_80A3_UHL_COPPER_ORE_TRUCK :Uhl Koper erts Truck
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Goss Koper erts Truck
+STR_80A5_UHL_WATER_TANKER :Uhl Water Tanker
+STR_80A6_BALOGH_WATER_TANKER :Balogh Water Tanker
+STR_80A7_MPS_WATER_TANKER :MPS Water Tanker
+STR_80A8_BALOGH_FRUIT_TRUCK :Balogh Fruitwagen
+STR_80A9_UHL_FRUIT_TRUCK :Uhl Fruitwagen
+STR_80AA_KELLING_FRUIT_TRUCK :Kelling Fruitwagen
+STR_80AB_BALOGH_RUBBER_TRUCK :Balogh Rubber Truck
+STR_80AC_UHL_RUBBER_TRUCK :Uhl Rubber Truck
+STR_80AD_RMT_RUBBER_TRUCK :RMT Rubber Truck
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :MightyMover Suiker Truck
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Powernaught Suiker Truck
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Wizzowow Suiker Truck
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :MightyMover Cola Truck
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Powernaught Cola Truck
+STR_80B3_WIZZOWOW_COLA_TRUCK :Wizzowow Cola Truck
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :MightyMover Suikerspin Truck
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Powernaught Suikerspin Truck
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Wizzowow Suikerspin Truck
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :MightyMover Toffee Truck
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Powernaught Toffee Truck
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Wizzowow Toffee Truck
+STR_80BA_MIGHTYMOVER_TOY_VAN :MightyMover Speelgoed Wagen
+STR_80BB_POWERNAUGHT_TOY_VAN :Powernaught Speelgoed Wagen
+STR_80BC_WIZZOWOW_TOY_VAN :Wizzowow Speelgoed Wagen
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :MightyMover Snoep Truck
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Powernaught Snoep Truck
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Wizzowow Snoep Truck
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :MightyMover Batterij Truck
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Powernaught Batterij Truck
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Wizzowow Batterij Truck
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :MightyMover Frisdrank Truck
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Powernaught Frisdrank Truck
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Wizzowow Frisdrank Truck
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :MightyMover Plastic Truck
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Powernaught Plastic Truck
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Wizzowow Plastic Truck
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :MightyMover Bellen Truck
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Powernaught Bellen Truck
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Wizzowow Bellen Truck
+STR_80CC_MPS_OIL_TANKER :MPS Olietanker
+STR_80CD_CS_INC_OIL_TANKER :CS-Inc. Olietanker
+STR_80CE_MPS_PASSENGER_FERRY :MPS Veerboot
+STR_80CF_FFP_PASSENGER_FERRY :FFP Veerboot
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Bakewell 300 Hovercraft
+STR_80D1_CHUGGER_CHUG_PASSENGER :Chugger-Chug Veerboot
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Shivershake Veerboot
+STR_80D3_YATE_CARGO_SHIP :Yate Goederenschip
+STR_80D4_BAKEWELL_CARGO_SHIP :Bakewell Goederenschip
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Mightymover Goederenschip
+STR_80D6_POWERNAUT_CARGO_SHIP :Powernaut Goederenschip
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Tricario Helikopter
+STR_80FE_GURU_X2_HELICOPTER :Guru X2 Helikopter
+STR_80FF_POWERNAUT_HELICOPTER :Powernaut Helikopter
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Bericht van voertuigenfabrikant
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}We hebben zojuist een nieuwe {STRING} ontworpen - ben je geinteresseerd in een jaar lang exclusief gebruik van dit voertuig, zodat we kunnen zien of het goed werkt voordat we het wereldwijd beschikbaar maken?
+STR_8102_RAILROAD_LOCOMOTIVE :spoorweg locomotief
+STR_8103_ROAD_VEHICLE :wegvoertuig
+STR_8104_AIRCRAFT :vliegtuig
+STR_8105_SHIP :schip
+STR_8106_MONORAIL_LOCOMOTIVE :monorail locomotief
+STR_8107_MAGLEV_LOCOMOTIVE :maglev locomotief
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}{TOWN} Treindepot
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Inwoners feesten... {}Eerste trein arriveert in {STATION}!
+STR_8802_DETAILS :{WHITE}{STRING} (Details)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Trein in de weg
+STR_8804 :{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8806_GO_TO :Ga naar {STATION}
+STR_8807_GO_TO_TRANSFER :Ga naar {STATION} (Overladen en neem goederen)
+STR_8808_GO_TO_UNLOAD :Ga naar {STATION} (Uit laden)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Ga naar {STATION} (Overladen en leeg laten)
+STR_880A_GO_TO_LOAD :Ga naar {STATION} (Laden)
+STR_880B_GO_TO_TRANSFER_LOAD :Ga naar {STATION} (Overladen en wacht tot vol geladen)
+STR_880C_GO_NON_STOP_TO :Ga non-stop naar {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Ga non-stop naar {STATION} (Overladen en neem goederen)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Ga non-stop naar {STATION} (Uitladen)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Ga non-stop naar {STATION} (Overladen en leeg laten)
+STR_8810_GO_NON_STOP_TO_LOAD :Ga non-stop naar {STATION} (Laden)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Ga non-stop naar {STATION} (Overladen en wacht tot vol geladen)
+STR_GO_TO_TRAIN_DEPOT :Ga naar {TOWN} Trein Depot
+STR_SERVICE_AT_TRAIN_DEPOT :Reparatie in {TOWN} Treindepot
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Ga zonder tussenstop naar {TOWN} Treindepot
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Reparatie zonder tussentop in {TOWN} Treindepot
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}Op weg naar {TOWN} Trein Depot
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}Op weg naar {TOWN} Trein Depot, {VELOCITY}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE :{LTBLUE}Onderhoud bij {TOWN} Trein Depot
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE_VEL :{LTBLUE}Onderhoud bij {TOWN} Trein Depot, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (Ongeldige Order)
+
+STR_UNKNOWN_DESTINATION :onbekende bestemming
+STR_8812_EMPTY :{LTBLUE}Leeg
+STR_8813_FROM :{LTBLUE}{CARGO} van {STATION}
+STR_FROM_MULT :{LTBLUE}{CARGO} van {STATION} (x{NUM})
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}Trein {COMMA} wacht in depot
+STR_8815_NEW_VEHICLES :{BLACK}Nieuwe voertuigen
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Trein te lang
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Treinen kunnen alleen aangepast worden wanneer ze gestopt zijn binnen een depot
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} Treinen
+
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Nieuwe spoorvoertuigen
+STR_NEW_ELRAIL_VEHICLES :{WHITE}Nieuwe electrische spoorvoertuigen
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Nieuwe monorailvoertuigen
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Nieuwe maglevvoertuigen
+STR_ALL_AVAIL_RAIL_VEHICLES :{WHITE}Rails Voertuig
+
+STR_881F_BUILD_VEHICLE :{BLACK}Bouw voertuig
+STR_CLONE_ROAD_VEHICLE :{BLACK}Kloon voertuig
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}Hierdoor wordt een kopie gebouw van dit voertuig. Control-click deelt de orders
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Hierdoor wordt een kopie gebouwd van een voertuig. Klik op deze knop en dan op een voertuig binnen of buiten het depot. Control-click deelt de orders
+STR_CLONE_TRAIN :{BLACK}Kloon Trein
+STR_CLONE_TRAIN_INFO :{BLACK}Hierdoor wordt een kopie gebouw van deze trein inclusief wagons. Control-click deelt de orders
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}Hierdoor wordt een kopie gebouwd van een trein inclusief wagons. Klik op deze knop en dan op een trein binnen of buiten het depot. Control-click deelt de orders
+STR_8820_RENAME :{BLACK}Hernoemen
+STR_8823_SKIP :{BLACK}Sla over
+STR_8824_DELETE :{BLACK}Verwijder
+STR_8825_NON_STOP :{BLACK}Non-stop
+STR_8826_GO_TO :{BLACK}Ga naar
+STR_8827_FULL_LOAD :{BLACK}Vol laden
+STR_8828_UNLOAD :{BLACK}Uitladen
+STR_REFIT :{BLACK}Ombouwen
+STR_REFIT_TIP :{BLACK}Kies naar welk type vracht ombouwen in deze order. Ctrl-klik om ombouw instructie te verwijderen
+STR_REFIT_ORDER :(Ombouwen naar {STRING})
+STR_8829_ORDERS :{WHITE}{VEHICLE} (Orders)
+STR_882A_END_OF_ORDERS :{SETX 10}- - Einde van orders - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}Reparatie
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Kan spoorvoertuig niet bouwen...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Gebouwd: {LTBLUE}{NUM}{BLACK} Waarde: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Waarde: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}In- en uitladen
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}Trein moet gestopt zijn in depot
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Kan trein niet naar depot sturen...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Geen ruimte meer voor orders
+STR_8832_TOO_MANY_ORDERS :{WHITE}Teveel orders
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Kan nieuwe order niet invoegen...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Kan deze order niet verwijderen...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Kan deze order niet aanpassen...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Kan voertuig niet verplaatsen...
+STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}De achterste locomotief zal altijd het voorste deel volgen
+STR_8838_N_A :NVT.{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Kan treinonderdeel niet verkopen
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Kan geen route naar lokale depot vinden
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Kan trein niet starten of stoppen...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Reparatieinterval: {LTBLUE}{COMMA}dagen{BLACK} Laatste reparatie: {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Service interval: {LTBLUE}{COMMA}%{BLACK} Laatste service: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Treinen - klik op een trein voor informatie
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Bouw nieuwe treinen (treindepot nodig)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Treinen - klik op trein voor info., sleep voertuig om toe tevoegen/verwijderen van trein
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Bouw nieuw treinonderdeel
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Sleep treinonderdeel hier om het te verkopen
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centreer het scherm op de locatie van de trein depot
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Treinonderdeel selectie lijst - klik op een voertuig voor informatie
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Bouw de geselecteerde treinonderdeel
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Hernoem treinonderdeel
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Huidige trein actie - klik hier om de trein te starten/stoppen
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Toon trein orders
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centreer het scherm op de locatie van de trein
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Stuur trein naar depot
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Forceer trein verder te rijden zonder te wachten op een groen signaal
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Keer trein om
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Toon trein details
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Vergroot reperatie interval
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Verklein reparatieinterval
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Laat details zien van vervoerde goederen
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Laat details zien van treinvoertuigen
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Laat de mogelijkheden van elk voertuig zien
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Laat totale capaiteit van trein zien, gescheiden door goederentype
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Orderlijst - klik op een order om deze te selecteren. CTRL + klikken gaat naar het station
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}Sla de huidige order over en begin met de volgende
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Verwijder de geselecteerde order
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Maak de geselecteerde order non-stop
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Voeg een nieuwe order in voor de geselecteerde order, of voeg het toe aan de eind van de lijst
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Zorg dat de geselecteerde order het voertuig forceert te wachten voor een volledige belading
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Zorg dat de geselecteerde order het voertuig forceert uit te laden
+STR_SERVICE_HINT :{BLACK}Sla deze order over tenzij een reparatie nodig is
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}Nieuwe {STRING} nu beschikbaar!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Prijs: {CURRENCY} Gewicht: {WEIGHT_S}{}Snelheid: {VELOCITY} Kracht: {POWER}{}Brandstofprijs: {CURRENCY}/jr{}Capaciteit: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}Kapot
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}Leeftijd: {LTBLUE}{STRING}{BLACK} Brandstofkosten: {LTBLUE}{CURRENCY}/jr
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Gewicht: {LTBLUE}{WEIGHT_S} {BLACK}Kracht: {LTBLUE}{POWER}{BLACK} Max. snelheid: {LTBLUE}{VELOCITY}
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Gewicht: {LTBLUE}{WEIGHT_S} {BLACK}Kracht: {LTBLUE}{POWER}{BLACK} Max. snelheid: {LTBLUE}{VELOCITY} {BLACK}Max. T.K.: {LTBLUE}{FORCE}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Winst dit jaar: {LTBLUE}{CURRENCY} (vorig jaar: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}Betrouwbaarheid: {LTBLUE}{COMMA}% {BLACK}Pechgevallen sinds laatste reparatie: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Gestopt
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Kan trein niet het signaal laten passeren bij gevaar...
+STR_8863_CRASHED :{RED}Gecrashed!
+
+STR_8865_NAME_TRAIN :{WHITE}Hernoem trein
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}Kan trein niet zo noemen...
+STR_8867_NAME_TRAIN :{BLACK}Trein benaming
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Trein Ongeluk!{}{COMMA} gedood in een vuurbal na de botsing
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Kan de richting van de trein niet omdraaien...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Hernoem trein voertuig type
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Kan het trein voertuig type niet hernoemen...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Forceer het voertuig goederen te dumpen bij geselecteerde order
+STR_886F_TRANSFER :{BLACK}Overladen
+
+STR_TRAIN_STOPPING :{RED}Gestopt
+STR_TRAIN_STOPPING_VEL :{RED}Aan het stoppen, {VELOCITY}
+STR_INCOMPATIBLE_RAIL_TYPES :spoortypes niet verenigbaar
+STR_TRAIN_NO_POWER :{RED}Geen stroom
+STR_TRAIN_START_NO_CATENARY :Er is geen bovenleiding, de trein kan niet starten
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Wegvoertuig in de weg
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} Wegvoertuigen
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}{TOWN} Bouw wegvoertuigdepot
+STR_9004_NEW_VEHICLES :{BLACK}Nieuwe voertuigen
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}Nieuwe Wegvoertuigen
+STR_9007_BUILD_VEHICLE :{BLACK}Bouw Voertuigen
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Kan het wegvoertuig niet bouwen...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (Details)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}Leeftijd: {LTBLUE}{STRING}{BLACK} Brandstofkosten: {LTBLUE}{CURRENCY}/jr
+STR_900E_MAX_SPEED :{BLACK}Max. snelheid: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Winst dit jaar: {LTBLUE}{CURRENCY} (vorig jaar: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}Betrouwbaarheid: {LTBLUE}{COMMA}% {BLACK}Pechgevallen sinds laatste reparaties: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Gebouwd: {LTBLUE}{NUM}{BLACK} Waarde: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Capaciteit: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}...moet gestopt zijn binnen een wegvoertuig depot
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Kan dit wegvoertuig niet verkopen...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Kan wegvoertuig niet starten of stoppen...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}Wegvoertuig {COMMA} wacht in depot
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}Op weg naar {TOWN} Weg Depot
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}Op weg naar {TOWN} Weg Depot, {VELOCITY}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE :{LTBLUE}Onderhoud bij {TOWN} Weg Depot
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE_VEL :{LTBLUE}Onderhoud bij {TOWN} Weg Depot, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Kan voertuig niet naar depot sturen...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Kan geen lokaal depot vinden
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Wegvoertuigen - klik op een voertuig voor informatie
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Bouw nieuwe wegvoertuigen (heeft wegvoertuigdepot nodig)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Huidige actie van voertuig - klik hier om voertuig te starten of te stoppen
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Laat orders van voertuig zien
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Centreer hoofdscherm op de lokatie van het voertuig
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Stuur voertuig naar depot
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Dwing het voertuig om om te draaien
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Laat details van wegvoertuig zien
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Voertuigen - klik op voertuig voor informatie
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Bouw nieuw wegvoertuig
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Sleep een wegvoertuig hier om het te verkopen
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Centreer hoofdscherm op wegvoertuigs depot lokatie
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Wegvoertuig selectie lijst - klik op voertuig voor informatie
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Bouw het geselecteerde wegvoertuig
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}Nieuw wegvoertuig nu beschikbaar!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Prijs: {CURRENCY}{}Snelheid: {VELOCITY}{}Brandstofkosten: {CURRENCY}/jr{}Capaciteit: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Hernoem wegvoertuig
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Kan wegvoertuig niet hernoemen...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Benoem wegvoertuig
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Inwoners feesten...{}Eerste bus arriveert in {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Inwoners feesten...{}Eerste vrachtwagen arriveert in {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}Wegvoertuig gebotst!{}Bestuurder verongelukt door treinbotsing
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}Wegvoertuig gebotst!{}{COMMA} verongelukt door treinbotsing
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Kan voertuig niet omdraaien...
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}Kan voertuigen bestaande uit meerdere eenheden niet omdraaien
+STR_9034_RENAME :{BLACK}Hernoem
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Hernoem wegvoertuigtype
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Hernoem wegvoertuigtype
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Kan wegvoertuigtype niet hernoemen...
+STR_9038_GO_TO_ROADVEH_DEPOT :Ga naar {TOWN} Wegvoertuig Depot
+STR_SERVICE_AT_ROADVEH_DEPOT :Repareren in {TOWN} Wegvoertuig Depot
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Verbouw het wegvoertuig om een andere lading the vervoeren
+STR_REFIT_ROAD_VEHICLE :{BLACK}Verbouw wegvoertuig
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Verbouw wegvoertuig om geselecteerd vrachttype te vervoeren
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Kan wegvoertuig niet verbouwen
+STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Selecteer welk type vracht het wegvoertuig moet vervoeren
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Dokbouw
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Dokbouw
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Kan hier geen dok bouwen...
+STR_9803_SHIP_DEPOT :{WHITE}{TOWN} Scheepswerf
+STR_9804_NEW_SHIPS :{BLACK}Nieuwe schepen
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} Schepen
+STR_9808_NEW_SHIPS :{WHITE}Nieuwe schepen
+STR_9809_BUILD_SHIP :{BLACK}Bouw schip
+STR_CLONE_SHIP :{BLACK}Kloon Schip
+STR_CLONE_SHIP_INFO :{BLACK}Hierdoor wordt een kopie gebouw van dit schip. Control-click deelt de orders
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}Hierdoor wordt een kopie gebouwd van een schip. Klik op deze knop en dan op een schip binnen of buiten het depot. Control-click deelt de orders
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}Schip moet gestopt zijn binnen een depot
+STR_980C_CAN_T_SELL_SHIP :{WHITE}Kan schip niet verkopen...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Kan schip niet kopen...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Schip in de weg
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Details)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}Leeftijd: {LTBLUE}{STRING}{BLACK} Brandstofkosten: {LTBLUE}{CURRENCY}/jr
+STR_9813_MAX_SPEED :{BLACK}Max. snelheid: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Winst dit jaar: {LTBLUE}{CURRENCY} (vorig jaar: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}Betrouwbaarheid: {LTBLUE}{COMMA}% {BLACK}Pechgevallen sinds laatste reparatie: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Gebouwd: {LTBLUE}{NUM}{BLACK} Waarde: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}Capaciteit: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}Kan schip niet starten of stoppen...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Kan schip niet naar depot sturen...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Kan lokaal depot niet vinden
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}Op weg naar {TOWN} Scheepswerf
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}Op weg naar {TOWN} Scheepswerf, {VELOCITY}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE :{LTBLUE}Onderhoud bij {TOWN} Scheepswerf
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE_VEL :{LTBLUE}Onderhoud bij {TOWN} Scheepswerf, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}Schip {COMMA} wacht in depot
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Bouw haven
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Bouw scheepswerf (om schepen te bouwen en te repareren)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Schepen - klik op schip voor informatie
+STR_9820_BUILD_NEW_SHIP :{BLACK}Bouw nieuw schip
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Sleep schip hierheen om het te verkopen
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centreer hoofdbeeld op de lokatie van het schipdepot
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Schepen - klik op een schip voor informatie
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Bouw nieuwe schepen (heeft schipdepot nodig)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}Schepenlijst - klik op een schip voor informatie
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Bouw het geselecteerde schip
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Actie van dit schip - klik hier om het te starten of te stoppen
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Laat orders van schip zien
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centreer hoofdbeeld op de lokatie van dit schip
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Stuur schip naar depot
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Laat details van schip zien
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}Nieuw schip nu beschikbaar!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Prijs: {CURRENCY} Max. snelheid: {VELOCITY}{}Capaciteit: {CARGO}{}Brandstofkosten: {CURRENCY}/jr
+STR_982F_NAME_SHIP :{BLACK}Hernoem schip
+
+STR_9831_NAME_SHIP :{WHITE}Hernoem schip
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Kan schip niet hernoemen...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Inwoners feesten...{}Eerste schip arriveert in {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Plaats boei, kan gebruikt worden voor extra tussenstops
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Kan boei hier niet plaatsen...
+STR_9836_RENAME :{BLACK}Hernoem
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Hernoem schiptype
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Hernoem schiptype
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Kan schiptype niet hernoemen...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Bouw schip om om andere goederen te vervoeren
+STR_983B_REFIT :{WHITE}{VEHICLE} (Ombouwen)
+STR_983C_REFIT_SHIP :{BLACK}Schip ombouwen
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Selecteer type goederen dat dit schip moet vervoeren
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Bouw schip om om geselecteerde goederen te vervoeren
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Selecteer goederentype om te vervoeren:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nieuwe capaciteit: {GOLD}{CARGO}{}{BLACK}Ombouwkosten: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Kan schip niet ombouwen...
+STR_9842_REFITTABLE :(ombouwbaar)
+STR_GO_TO_SHIP_DEPOT :Ga naar {TOWN} Scheepswerf
+SERVICE_AT_SHIP_DEPOT :Reparatie in {TOWN} Scheepswerf
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Vliegvelden
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Kan vliegveld hier niet bouwen...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} Vliegtuighangar
+STR_A003_NEW_AIRCRAFT :{BLACK}Nieuw vliegtuig
+STR_CLONE_AIRCRAFT :{BLACK}Kloon Vliegtuig
+STR_CLONE_AIRCRAFT_INFO :{BLACK}Hierdoor wordt een kopie gebouw van dit vliegtuig. Control-click deelt de orders
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Hierdoor wordt een kopie gebouw van een vliegtuig. Klik op deze knop en dan op een vliegtuig binnen of buiten de hangar. Control-click deelt de orders
+STR_A005_NEW_AIRCRAFT :{WHITE}Nieuw Vliegtuig
+STR_A006_BUILD_AIRCRAFT :{BLACK}Bouw Vliegtuig
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Kan vliegtuig niet bouwen...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} Vliegtuigen
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (Orders)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (Details)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Leeftijd: {LTBLUE}{STRING}{BLACK} Brandstofkosten: {LTBLUE}{CURRENCY}/jr
+STR_A00E_MAX_SPEED :{BLACK}Max. snelheid: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Winst dit jaar: {LTBLUE}{CURRENCY} (vorig jaar: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}Betrouwbaarheid: {LTBLUE}{COMMA}% {BLACK}Pechgevallen sinds laatste reparatie: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Bouwdatum: {LTBLUE}{NUM}{BLACK} Waarde: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Kan vliegtuig niet naar hangar sturen...
+STR_HEADING_FOR_HANGAR :{ORANGE}Op weg naar {STATION} Hangar
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}Op weg naar {STATION} Hangar, {VELOCITY}
+STR_HEADING_FOR_HANGAR_SERVICE :{LTBLUE}Onderhoud bij {STATION} Hangar
+STR_HEADING_FOR_HANGAR_SERVICE_VEL :{LTBLUE}Onderhoud bij {STATION} Hangar, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}Vliegtuig {COMMA} wacht in de vliegtuig hangar
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Vliegtuig in de weg
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Kan vliegtuig niet stoppen/starten...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Vliegutig is in the lucht
+STR_A019_CAPACITY :{BLACK}Capaciteit: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Capaciteit: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}Vliegtuig moet gestopt zijn in een hangar
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Kan vliegtuig niet verkopen...
+STR_A01D_AIRPORT_CONSTRUCTION :Vliegveldbouw
+STR_A01E_BUILD_AIRPORT :{BLACK}Bouw vliegveld
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Vliegtuig - klik op vliegtuig voor informatie
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Bouw nieuw vliegtuig (heeft vliegveld met hangar nodig)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Vliegtuig - klik op vliegtuig voor informatie
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Bouw nieuw vliegtuig
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}Sleep vliegtuig hierheen om het te verkopen
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Centreer hoofdbeeld op hangarlokatie
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Vliegtuiglijst - klik op een vliegtuig voor informatie
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Bouw het geselecteerde vliegtuig
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Actie van huidig vliegtuig - klik hier om het vliegtuig te stoppen of te starten
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Laat vliegtuigorders zien
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Centreer hoofdbeeld op de vliegtuiglokatie
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Stuur vliegtuig naar hangar
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Laat vliegtuigdetails zien
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}Nieuw vliegtuig nu beschikbaar!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Prijs: {CURRENCY} Max. snelheid: {VELOCITY}{}Capaciteit: {COMMA} passagiers, {COMMA} zakken post{}Brandstofkosten: {CURRENCY}/jr
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Hernoem vliegtuig
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Kan vliegtuig niet hernoemen...
+STR_A032_NAME_AIRCRAFT :{BLACK}Hernoem vliegtuig
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Inwoners feesten...{}Eerste vliegtuig arriveert in {STATION}!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Vliegtuig neergestort!{}{COMMA} sterven in een vuurbal bij {STATION}
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Vliegtuig Neergestort!{}Vliegtuig had brandstoftekort, {COMMA} komen om in explosie!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Hernoem
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Hernoem vliegtuigtype
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Hernoem vliegtuigtype
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Kan vliegtuigtype niet hernoemen...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Bouw vliegtuig om om andere goederen te vervoeren
+STR_A03C_REFIT :{WHITE}{VEHICLE} (Omgebouwd)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Vliegtuig ombouwen
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Selecteer goederentype om te vervoeren door het vliegtuig
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Bouw vliegtuig om om het geselecteerde goederentype te vervoeren
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Selecteer goederentype om te vervoeren:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nieuwe capaciteit: {GOLD}{STRING}{}{BLACK}Ombouwkosten: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Kan vliegtuig niet ombouwen...
+STR_GO_TO_AIRPORT_HANGAR :Ga naar {STATION} hanger
+SERVICE_AT_AIRPORT_HANGAR :Reperatie bij {STATION} hanger
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}Zeppelin ongeluk bij {STATION}!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Voertuig vernietigd in botsing met 'UFO'
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}Olieraffinaderij in de buurt van {TOWN} is explodeerd!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}Fabriek in de buurt van {TOWN} is vernietigd onder verdachte omstandigheden!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}'UFO' landt in de buurt van {TOWN}!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}Instorting van kolenmijn laat spoor van vernietiging achter in de buurt van {TOWN}!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Overstromingen!{}Minstens {COMMA} zijn vermist of dood na overstromingen!
+
+STR_BRIBE_FAILED :{WHITE}Je poging tot omkopen is
+STR_BRIBE_FAILED_2 :{WHITE}ondekt door regionale onderzoekers
+STR_BUILD_DATE :{BLACK}Bouwjaar: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Detail van de prestatiewaarde
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}Detail
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Voertuigen:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Stations:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Min. winst:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Min. inkomen:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Max. inkomen:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Afgeleverd:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Lading:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Geld:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Lening:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Totaal:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Aantal voertuigen. Dit is inclusief wegvoertuigen, treinen, schepen en vliegtuigen.
+STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}Aantal stationsonderdelen. Elke deel van een station (b.v. trein station, bushalte, vliegveld) wordt geteld, zelfs als deze zijn verbonden met een station.
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}De winst van de voertuigen met het laagste inkomen (van alle voeruigen ouder dan 2 jaar)
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Het hoeveelheid aan geld dat is verdient in de maand met de laagste winst van de afgelopen 12 kwartalen
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Het hoeveelheid aan geld dat is verdient in de maand met de hoogste winst van de afgelopen 12 kwartalen
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}Het aantal eenheden aan goederen dat is bezorgd in de afgelopen vier kwartalen.
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}Typen goederen dat zijn bezorgd in het laatste kwartaal.
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Hoeveelheid contant geld
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}Heb je een hoge lening?
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Totaal aantal punten uit de mogelijke punten
+
+STR_NEWGRF_SETTINGS_BUTTON :{BLACK}NewGRF Instellingen
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}Newgrf instellingen
+STR_NEWGRF_APPLY_CHANGES :{BLACK}Wijzigingen doorvoeren
+STR_NEWGRF_SET_PARAMETERS :{BLACK}Stel parameters in
+STR_NEWGRF_TIP :{BLACK}Een lijst van alle geïnstalleerde Newgrf sets. Klik op een set om de instellingen te wijzigen.
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}Er zijn op dit moment geen newgrf bestanden geïnstalleerd! Raadpleeg het handboek voor instructies voor het installeren van nieuwe graphics.
+STR_NEWGRF_FILENAME :{BLACK}Bestandsnaam: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
+STR_NEWGRF_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING}
+STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}Je staat op het punt om wijzigingen te maken aan een lopend spel; dit dan OpenTTD laten crashen.{}Weet je het heel zeker?
+
+STR_NEWGRF_ADD :{BLACK}Toevoegen
+STR_NEWGRF_ADD_TIP :{BLACK}Voeg een NewGRF bestand toe aan te lijst
+STR_NEWGRF_REMOVE :{BLACK}Verwijderen
+STR_NEWGRF_REMOVE_TIP :{BLACK}Verwijder de geselecteerde NewGRF bestanden van de lijst
+STR_NEWGRF_MOVEUP :{BLACK}Naar Boven
+STR_NEWGRF_MOVEUP_TIP :{BLACK}Verplaats het geselecteerde NewGRF bestand naar boven
+STR_NEWGRF_MOVEDOWN :{BLACK}Naar Beneden
+STR_NEWGRF_MOVEDOWN_TIP :{BLACK}Verplaats het geselecteerde NewGRF bestand naar beneden
+STR_NEWGRF_FILE_TIP :{BLACK}Een lijst van de NewGRF bestanden die zijn geïnstalleerd. Klik op een bestand om de parameters te wijzigen
+STR_NEWGRF_PARAMETER :{BLACK}Parameters: {SILVER}{STRING}
+STR_NEWGRF_PARAMETER_QUERY :{BLACK}NewGRF parameters ingeven
+STR_NEWGRF_NO_INFO :{BLACK}Geen informatie beschikbaar
+
+STR_NEWGRF_ADD_CAPTION :{WHITE}Beschikbare NewGRF bestanden
+STR_NEWGRF_ADD_FILE :{BLACK}voeg toe aan selectie
+STR_NEWGRF_ADD_FILE_TIP :{BLACK}Voeg het geselecteerde NewGRF bestand toe aan je configuratie
+STR_NEWGRF_RESCAN_FILES :{BLACK}Bestanden opnieuw lezen
+STR_NEWGRF_RESCAN_FILES_TIP :{BLACK}Werk de lijst van beschikbare NewGRF bestanden bij
+STR_NEWGRF_DUPLICATE_GRFID :{WHITE}Kan bestand niet toevoegen: identieke GRF ID
+
+STR_NEWGRF_NOT_FOUND :{RED}Bestand niet gevonden
+STR_NEWGRF_DISABLED :{RED}Uitgeschakeld
+
+STR_CURRENCY_WINDOW :{WHITE}Aangepaste valuta
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Wisselkoers: {ORANGE}{CURRENCY} = £ {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Scheidingsteken:
+STR_CURRENCY_PREFIX :{LTBLUE}Voorvoegsel:
+STR_CURRENCY_SUFFIX :{LTBLUE}Achtervoegsel:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Overgaan op de Euro: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Overgaan op de Euro: {ORANGE}nooit
+STR_CURRENCY_PREVIEW :{LTBLUE}Voorbeeld: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Verander aangepaste valuta optie
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} Treinen
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} Wegvoertuigen
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} Vliegtuigen
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} Schepen
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Geef alle treinen weer die dit station in hun opdrachtenlijst hebben
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Geef alle wegvoertuigen weer die dit station in hun opdrachtenlijst hebben
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Geef alle vliegtuigen weer die dit station in hun opdrachtenlijst hebben
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Geef alle schepen weer die dit station in hun opdrachtenlijst hebben
+
+STR_VEH_WITH_SHARED_ORDERS_LIST :{WHITE}Gedeelde orders van {COMMA} voertuig{P "" en}
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}Toon alle voertuigen met de zelfde orders
+
+### depot strings
+STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Je staat op het punt alle voertuigen in het depot te verkopen. Weet je het zeker?
+
+STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP :{BLACK}Verkoop alle treinen in het depot
+STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP :{BLACK}Verkoop alle weg voertuigen in het depot
+STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP :{BLACK}Verkoop alle schepen in het depot
+STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP :{BLACK}Verkoop alle vliegtuigen in de hangar
+
+STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP :{BLACK}Geef een lijst van alle treinen met huidig depot in hun orders
+STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP :{BLACK}Geef een lijst van alle wegvoertuigen met huidig depot in hun orders
+STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP :{BLACK}Geef een lijst van alle schepen met huidig schepswerf in hun orders
+STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP :{BLACK}Geef een lijst van alle vliegtuigen met een hangar van dit vliegveld in hun orders
+
+STR_DEPOT_AUTOREPLACE_TRAIN_TIP :{BLACK}Vervang automatisch alle treinen in het depot
+STR_DEPOT_AUTOREPLACE_ROADVEH_TIP :{BLACK}Vervang automatisch alle weg voertuigen in het depot
+STR_DEPOT_AUTOREPLACE_SHIP_TIP :{BLACK}Vervang automatisch alle schepen in het depot
+STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP :{BLACK}Vervang automatisch alle vliegtuigen in de hangar
+
+STR_VEHICLE_LIST_TRAIN_DEPOT :{BLACK}{STRING} - {COMMA} Trein{P "" s}
+STR_VEHICLE_LIST_ROADVEH_DEPOT :{BLACK}{STRING} - {COMMA} Weg Voertuigen{P "" s}
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} Schip{P "" s}
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} Vliegtuig
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}Vervang {STRING}
+STR_REPLACE_VEHICLES_START :{BLACK}Start het Vervangen
+STR_REPLACE_VEHICLES_STOP :{BLACK}Stop het Vervangen
+STR_NOT_REPLACING :{BLACK}Niet aan het vervangen
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Geen voertuig geselecteerd
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Selecteer het type locmotief om te vervangen
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Selecteer een nieuw type locomotief die je wil gebruiken om het links geselecteerde type locomotief te vervangen
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Klik op deze knop als je de aan de linkerkant geselecteerde locomotief niet wil vervangen
+STR_REPLACE_HELP_START_BUTTON :{BLACK}Klik op deze knop als je de aan de linkerkant geseleteerde locomotief wil vervangen met die aan de rechterkant
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Selecteer een railtype waar je locomotieven voor wil selecteren
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Dit geeft weer waarmee de aan de linkerkant geselecteerde locomotief mee vervangen wordt
+STR_REPLACE_HELP :{BLACK}Deze optie stelt je in staat om een type voertuig te selecteren en die te vervangen door een andere, zodra de voertuigen een depot inrijden
+STR_REPLACE_REMOVE_WAGON :{BLACK}Wagons verwijderen: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}De te vervangen trein behoudt zijn lengte door wagons weg te halen (startend aan de voorkant), als het vervangen de trein langer zou maken
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}Aan het vervangen: {ORANGE}{SKIP}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} EXPERIMENTEEL {}Wissel tussen motor- en wagonvervangvensters.{}Wagonvervanging wordt alleen uitgevoerd als de nieuwe wagon omgebouwd kan worden om hetzelfde ladingtype te dragen als de oude wagon. Dit wordt gecontroleerd voor elke wagon wanneer de daadwerkelijke vervanging plaats vindt.
+STR_ENGINE_NOT_BUILDABLE :{WHITE}Locomotief kan niet gebouwd worden
+
+STR_ENGINES :Motoren
+STR_WAGONS :Wagons
+
+STR_MASS_STOP_DEPOT_TRAIN_TIP :{BLACK}Klik om alle treinen in het depot te stoppen
+STR_MASS_STOP_DEPOT_ROADVEH_TIP :{BLACK}Klik om alle weg voertuigen in het depot te stoppen
+STR_MASS_STOP_DEPOT_SHIP_TIP :{BLACK}Klik om alle schepen in het depot te stoppen
+STR_MASS_STOP_HANGAR_TIP :{BLACK}Klik om alle vliegtuigen in het depot te stoppen
+
+STR_MASS_START_DEPOT_TRAIN_TIP :{BLACK}Klik om alle treinen in het depot te starten
+STR_MASS_START_DEPOT_ROADVEH_TIP :{BLACK}Klik om alle weg voertuigen in het depot te starten
+STR_MASS_START_DEPOT_SHIP_TIP :{BLACK}Klik om alle schepen in het depot te starten
+STR_MASS_START_HANGAR_TIP :{BLACK}Klik om alle vliegtuigen in het depot te starten
+
+STR_MASS_STOP_LIST_TIP :{BLACK}Klik om alle voertuigen te stoppen in de lijst
+STR_MASS_START_LIST_TIP :{BLACK}Klik om alle voertuigen te starten in de lijst
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}Bordenlijst - {COMMA} bord{P "" en}
+
+STR_ORDER_REFIT_FAILED :{WHITE}Order ombouwen mislukt gestopt{STRING} {COMMA}
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :Treinstellen
+STR_ELRAIL_VEHICLES :Electrische spoorvoertuigen
+STR_MONORAIL_VEHICLES :Monorail Voertuigen
+STR_MAGLEV_VEHICLES :Maglev Voertuigen
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Kosten: {GOLD}{CURRENCY}{BLACK} Gewicht: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Snelheid: {GOLD}{VELOCITY}{BLACK} Kracht: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}Snelheid: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Onderhoudskosten: {GOLD}{CURRENCY}/jr
+STR_PURCHASE_INFO_CAPACITY :{BLACK}Capaciteit: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Ontworpen: {GOLD}{NUM}{BLACK} Levensduur: {GOLD}{COMMA} jaar
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}Max. Betrouwbaarheid: {GOLD}{COMMA}%
+STR_PURCHASE_INFO_COST :{BLACK}Kosten: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Gewicht: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Kosten: {GOLD}{CURRENCY}{BLACK} Snelheid: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Capaciteit: {GOLD}{COMMA} passagiers, {COMMA} zakken post
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Aangedreven wagons: {GOLD}+{POWER}{BLACK} Gewicht: {GOLD}+{WEIGHT_S}
+STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Herindeel naar: {GOLD}
+STR_PURCHASE_INFO_ALL_TYPES :Alle vracht typen
+STR_PURCHASE_INFO_ALL_BUT :Alles behalve {GOLD}
+STR_PURCHASE_INFO_MAX_TE :{BLACK}Max. Trekkracht: {GOLD}{FORCE}
+
+########### String for New Landscape Generator
+
+STR_GENERATE :{WHITE}Creeër
+STR_RANDOM :{BLACK}Willekeurig maken
+STR_RANDOM_HELP :{BLACK}Wijzig het willekeurige getal voor terrein creatie
+STR_WORLD_GENERATION_CAPTION :{WHITE}Wereld maken
+STR_RANDOM_SEED :{BLACK}Willekeurig getal
+STR_RANDOM_SEED_HELP :{BLACK}Klik voor een willekeurig getal
+STR_LAND_GENERATOR :{BLACK}Land generator:
+STR_TREE_PLACER :{BLACK}Bos algoritme:
+STR_HEIGHTMAP_ROTATION :{BLACK}Aantal graden hoogtekaart:
+STR_TERRAIN_TYPE :{BLACK}Terrein type:
+STR_QUANTITY_OF_SEA_LAKES :{BLACK}Zee niveau:
+STR_SMOOTHNESS :{BLACK}Vlakte:
+STR_SNOW_LINE_HEIGHT :{BLACK}Sneeuwlijn hoogte:
+STR_DATE :{BLACK}Datum:
+STR_NUMBER_OF_TOWNS :{BLACK}Aantal steden:
+STR_NUMBER_OF_INDUSTRIES :{BLACK}Aantal Industrieën:
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_SNOW_LINE_UP :{BLACK}Verschuif de sneeuwlijn één omhoog
+STR_SNOW_LINE_DOWN :{BLACK}Verschuif de sneeuwlijn één naar beneden
+STR_SNOW_LINE_QUERY_CAPT :{WHITE}Verander sneeuwlijn hoogte
+STR_START_DATE_QUERY_CAPT :{WHITE}Verander begin jaar
+STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Schaal waarschuwing
+STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Het aanpassen van de grootte van een bronkaar is niet aan te bevelen. Toch doorgaan?
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_HEIGHTMAP_NAME :{BLACK}Hoogtekaart naam:
+STR_HEIGHTMAP_SIZE :{BLACK}Grootte: {ORANGE}{NUM} x {NUM}
+STR_GENERATION_WORLD :{WHITE}Wereld creeren
+STR_GENERATION_ABORT :{BLACK}Stop
+STR_GENERATION_ABORT_CAPTION :{WHITE}Stop Wereld Generatie
+STR_GENERATION_ABORT_MESSAGE :{YELLOW}Weet je zeker dat je de actie wilt stoppen?
+STR_PROGRESS :{WHITE}{NUM}% compleet
+STR_GENERATION_PROGRESS :{BLACK}{NUM} / {NUM}
+STR_WORLD_GENERATION :{BLACK}Wereld maken
+STR_TREE_GENERATION :{BLACK}Bos plaatsing
+STR_UNMOVABLE_GENERATION :{BLACK}Onverplaatsbare generatie
+STR_CLEARING_TILES :{BLACK}Ruig en
+STR_SETTINGUP_GAME :{BLACK}Spel aan het instellen
+STR_PREPARING_TILELOOP :{BLACK}Bezig met vlakken
+STR_PREPARING_GAME :{BLACK}Voorbereiden spel
+STR_DIFFICULTY_TO_CUSTOM :{WHITE}Deze aktie past de moeilijkheidsgraag aan naam custom
+STR_SE_FLAT_WORLD :{WHITE}Vlak land
+STR_SE_FLAT_WORLD_TIP :{BLACK}Genereer een platte kaart
+STR_SE_RANDOM_LAND :{WHITE}Willekeurig land
+STR_SE_NEW_WORLD :{BLACK}Creeër nieuw scenario
+STR_SE_CAPTION :{WHITE}Scenario type
+STR_FLAT_WORLD_HEIGHT_DOWN :{BLACK}Maak de hoogte van plat land een lager
+STR_FLAT_WORLD_HEIGHT_UP :{BLACK}Maak de hoogte van plat land een hoger
+STR_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Verander hoogte van vlak land
+STR_FLAT_WORLD_HEIGHT :{BLACK}Hoogte van platte grond:
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+STR_SMALLMAP_CENTER :{BLACK}Centreerd de kleine kaart op heidige positie
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}Klein
+STR_CITY_AIRPORT :{BLACK}Stad
+STR_METRO_AIRPORT :{BLACK}Hoofdstedelijk vliegveld
+STR_INTERNATIONAL_AIRPORT :{BLACK}Internationaal vliegveld
+STR_COMMUTER_AIRPORT :{BLACK}Pendel
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Intercontinentaal
+STR_HELIPORT :{BLACK}Heliport
+STR_HELIDEPOT :{BLACK}Helihanger
+STR_HELISTATION :{BLACK}Helikopter station
+
+STR_SMALL_AIRPORTS :{BLACK}Kleine vliegvelden
+STR_LARGE_AIRPORTS :{BLACK}Grote vliegvelden
+STR_HUB_AIRPORTS :{BLACK}Centraal vliegveld
+STR_HELIPORTS :{BLACK}Helikopter vliegveld
+
+############ Tooltip measurment
+
+STR_MEASURE_LENGTH :{BLACK}Lengte: {NUM}
+STR_MEASURE_AREA :{BLACK}Gebied: {NUM} x {NUM}
+STR_MEASURE_LENGTH_HEIGHTDIFF :{BLACK}Lengte: {NUM}{}Hoogte verschil: {NUM} m
+STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}Gebied: {NUM} x {NUM}{}Hoogte verschil: {NUM} m
+
+########
diff --git a/src/lang/english.txt b/src/lang/english.txt
new file mode 100644
index 000000000..8a5ff5cd7
--- /dev/null
+++ b/src/lang/english.txt
@@ -0,0 +1,3116 @@
+##name English
+##ownname English (UK)
+##isocode en_GB.UTF-8
+##plural 0
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Off edge of map
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Too close to edge of map
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Not enough cash - requires {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Flat land required
+STR_0008_WAITING :{BLACK}Waiting: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (en-route from
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Accepts: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Accepts: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :Passengers
+STR_0010_COAL :Coal
+STR_0011_MAIL :Mail
+STR_0012_OIL :Oil
+STR_0013_LIVESTOCK :Livestock
+STR_0014_GOODS :Goods
+STR_0015_GRAIN :Grain
+STR_0016_WOOD :Wood
+STR_0017_IRON_ORE :Iron Ore
+STR_0018_STEEL :Steel
+STR_0019_VALUABLES :Valuables
+STR_001A_COPPER_ORE :Copper Ore
+STR_001B_MAIZE :Maize
+STR_001C_FRUIT :Fruit
+STR_001D_DIAMONDS :Diamonds
+STR_001E_FOOD :Food
+STR_001F_PAPER :Paper
+STR_0020_GOLD :Gold
+STR_0021_WATER :Water
+STR_0022_WHEAT :Wheat
+STR_0023_RUBBER :Rubber
+STR_0024_SUGAR :Sugar
+STR_0025_TOYS :Toys
+STR_0026_CANDY :Sweets
+STR_0027_COLA :Cola
+STR_0028_COTTON_CANDY :Candyfloss
+STR_0029_BUBBLES :Bubbles
+STR_002A_TOFFEE :Toffee
+STR_002B_BATTERIES :Batteries
+STR_002C_PLASTIC :Plastic
+STR_002D_FIZZY_DRINKS :Fizzy Drinks
+STR_002E :
+STR_002F_PASSENGER :Passenger
+STR_0030_COAL :Coal
+STR_0031_MAIL :Mail
+STR_0032_OIL :Oil
+STR_0033_LIVESTOCK :Livestock
+STR_0034_GOODS :Goods
+STR_0035_GRAIN :Grain
+STR_0036_WOOD :Wood
+STR_0037_IRON_ORE :Iron Ore
+STR_0038_STEEL :Steel
+STR_0039_VALUABLES :Valuables
+STR_003A_COPPER_ORE :Copper Ore
+STR_003B_MAIZE :Maize
+STR_003C_FRUIT :Fruit
+STR_003D_DIAMOND :Diamond
+STR_003E_FOOD :Food
+STR_003F_PAPER :Paper
+STR_0040_GOLD :Gold
+STR_0041_WATER :Water
+STR_0042_WHEAT :Wheat
+STR_0043_RUBBER :Rubber
+STR_0044_SUGAR :Sugar
+STR_0045_TOY :Toy
+STR_0046_CANDY :Sweet
+STR_0047_COLA :Cola
+STR_0048_COTTON_CANDY :Candyfloss
+STR_0049_BUBBLE :Bubble
+STR_004A_TOFFEE :Toffee
+STR_004B_BATTERY :Battery
+STR_004C_PLASTIC :Plastic
+STR_004D_FIZZY_DRINK :Fizzy Drink
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} passenger{P "" s}
+STR_QUANTITY_COAL :{WEIGHT} of coal
+STR_QUANTITY_MAIL :{COMMA} bag{P "" s} of mail
+STR_QUANTITY_OIL :{VOLUME} of oil
+STR_QUANTITY_LIVESTOCK :{COMMA} item{P "" s} of livestock
+STR_QUANTITY_GOODS :{COMMA} crate{P "" s} of goods
+STR_QUANTITY_GRAIN :{WEIGHT} of grain
+STR_QUANTITY_WOOD :{WEIGHT} of wood
+STR_QUANTITY_IRON_ORE :{WEIGHT} of iron ore
+STR_QUANTITY_STEEL :{WEIGHT} of steel
+STR_QUANTITY_VALUABLES :{COMMA} bag{P "" s} of valuables
+STR_QUANTITY_COPPER_ORE :{WEIGHT} of copper ore
+STR_QUANTITY_MAIZE :{WEIGHT} of maize
+STR_QUANTITY_FRUIT :{WEIGHT} of fruit
+STR_QUANTITY_DIAMONDS :{COMMA} bag{P "" s} of diamonds
+STR_QUANTITY_FOOD :{WEIGHT} of food
+STR_QUANTITY_PAPER :{WEIGHT} of paper
+STR_QUANTITY_GOLD :{COMMA} bag{P "" s} of gold
+STR_QUANTITY_WATER :{VOLUME} of water
+STR_QUANTITY_WHEAT :{WEIGHT} of wheat
+STR_QUANTITY_RUBBER :{VOLUME} of rubber
+STR_QUANTITY_SUGAR :{WEIGHT} of sugar
+STR_QUANTITY_TOYS :{COMMA} toy{P "" s}
+STR_QUANTITY_SWEETS :{COMMA} bag{P "" s} of sweets
+STR_QUANTITY_COLA :{VOLUME} of cola
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} of candyfloss
+STR_QUANTITY_BUBBLES :{COMMA} bubble{P "" s}
+STR_QUANTITY_TOFFEE :{WEIGHT} of toffee
+STR_QUANTITY_BATTERIES :{COMMA} batter{P y ies}
+STR_QUANTITY_PLASTIC :{VOLUME} of plastic
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} fizzy drink{P "" s}
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}PS
+STR_ABBREV_COAL :{TINYFONT}CL
+STR_ABBREV_MAIL :{TINYFONT}ML
+STR_ABBREV_OIL :{TINYFONT}OL
+STR_ABBREV_LIVESTOCK :{TINYFONT}LV
+STR_ABBREV_GOODS :{TINYFONT}GD
+STR_ABBREV_GRAIN :{TINYFONT}GR
+STR_ABBREV_WOOD :{TINYFONT}WD
+STR_ABBREV_IRON_ORE :{TINYFONT}OR
+STR_ABBREV_STEEL :{TINYFONT}ST
+STR_ABBREV_VALUABLES :{TINYFONT}VL
+STR_ABBREV_COPPER_ORE :{TINYFONT}CO
+STR_ABBREV_MAIZE :{TINYFONT}MZ
+STR_ABBREV_FRUIT :{TINYFONT}FT
+STR_ABBREV_DIAMONDS :{TINYFONT}DM
+STR_ABBREV_FOOD :{TINYFONT}FD
+STR_ABBREV_PAPER :{TINYFONT}PR
+STR_ABBREV_GOLD :{TINYFONT}GD
+STR_ABBREV_WATER :{TINYFONT}WR
+STR_ABBREV_WHEAT :{TINYFONT}WH
+STR_ABBREV_RUBBER :{TINYFONT}RB
+STR_ABBREV_SUGAR :{TINYFONT}SG
+STR_ABBREV_TOYS :{TINYFONT}TY
+STR_ABBREV_SWEETS :{TINYFONT}SW
+STR_ABBREV_COLA :{TINYFONT}CL
+STR_ABBREV_CANDYFLOSS :{TINYFONT}CF
+STR_ABBREV_BUBBLES :{TINYFONT}BU
+STR_ABBREV_TOFFEE :{TINYFONT}TF
+STR_ABBREV_BATTERIES :{TINYFONT}BA
+STR_ABBREV_PLASTIC :{TINYFONT}PL
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}FZ
+STR_ABBREV_NONE :{TINYFONT}NO
+STR_ABBREV_ALL :{TINYFONT}ALL
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Map - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Game Options
+STR_00B2_MESSAGE :{YELLOW}Message
+STR_00B3_MESSAGE_FROM :{YELLOW}Message from {STRING1}
+STR_POPUP_CAUTION_CAPTION :{WHITE}Caution!
+STR_00B4_CAN_T_DO_THIS :{WHITE}Can't do this....
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Can't clear this area....
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Original copyright {COPYRIGHT} 1995 Chris Sawyer, All rights reserved
+STR_00B7_VERSION :{BLACK}OpenTTD version {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 The OpenTTD team
+STR_TRANSLATED_BY :{BLACK} Translator(s) -
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Quit
+STR_00C8_YES :{BLACK}Yes
+STR_00C9_NO :{BLACK}No
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Are you sure you want to abandon this game and return to {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Nothing
+STR_00D1_DARK_BLUE :Dark Blue
+STR_00D2_PALE_GREEN :Pale Green
+STR_00D3_PINK :Pink
+STR_00D4_YELLOW :Yellow
+STR_00D5_RED :Red
+STR_00D6_LIGHT_BLUE :Light Blue
+STR_00D7_GREEN :Green
+STR_00D8_DARK_GREEN :Dark Green
+STR_00D9_BLUE :Blue
+STR_00DA_CREAM :Cream
+STR_00DB_MAUVE :Mauve
+STR_00DC_PURPLE :Purple
+STR_00DD_ORANGE :Orange
+STR_00DE_BROWN :Brown
+STR_00DF_GREY :Grey
+STR_00E0_WHITE :White
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Too many vehicles in game
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Location
+STR_00E5_CONTOURS :Contours
+STR_00E6_VEHICLES :Vehicles
+STR_00E7_INDUSTRIES :Industries
+STR_00E8_ROUTES :Routes
+STR_00E9_VEGETATION :Vegetation
+STR_00EA_OWNERS :Owners
+STR_00EB_ROADS :{BLACK}{TINYFONT}Roads
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Railways
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Stations/Airports/Docks
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Buildings/Industries
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Vehicles
+STR_00F0_100M :{BLACK}{TINYFONT}100m
+STR_00F1_200M :{BLACK}{TINYFONT}200m
+STR_00F2_300M :{BLACK}{TINYFONT}300m
+STR_00F3_400M :{BLACK}{TINYFONT}400m
+STR_00F4_500M :{BLACK}{TINYFONT}500m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Trains
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Road Vehicles
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Ships
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Aircraft
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Transport Routes
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Coal Mine
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Power Station
+STR_00FC_FOREST :{BLACK}{TINYFONT}Forest
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}Sawmill
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Oil Refinery
+STR_00FF_FARM :{BLACK}{TINYFONT}Farm
+STR_0100_FACTORY :{BLACK}{TINYFONT}Factory
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Printing Works
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Oil Wells
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Iron Ore Mine
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Steel Mill
+STR_0105_BANK :{BLACK}{TINYFONT}Bank
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Paper Mill
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Gold Mine
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Food Processing Plant
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Diamond Mine
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Copper Ore Mine
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Fruit Plantation
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Rubber Plantation
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Water Supply
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Water Tower
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}Lumber Mill
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Candyfloss Forest
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Sweet Factory
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Battery Farm
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Cola Wells
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Toy Shop
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Toy Factory
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Plastic Fountains
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Fizzy Drink Factory
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Bubble Generator
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Toffee Quarry
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Sugar Mine
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Railway Station
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Lorry Loading Bay
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Bus Station
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Airport/Heliport
+STR_011F_DOCK :{BLACK}{TINYFONT}Dock
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Rough Land
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Grass Land
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Bare Land
+STR_0123_FIELDS :{BLACK}{TINYFONT}Fields
+STR_0124_TREES :{BLACK}{TINYFONT}Trees
+STR_0125_ROCKS :{BLACK}{TINYFONT}Rocks
+STR_0126_WATER :{BLACK}{TINYFONT}Water
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}No Owner
+STR_0128_TOWNS :{BLACK}{TINYFONT}Towns
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Industries
+STR_012A_DESERT :{BLACK}{TINYFONT}Desert
+STR_012B_SNOW :{BLACK}{TINYFONT}Snow
+STR_012C_MESSAGE :{WHITE}Message
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Cancel
+STR_012F_OK :{BLACK}OK
+STR_0130_RENAME :{BLACK}Rename
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Too many names defined
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Chosen name already in use
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...owned by {STRING2}
+STR_013C_CARGO :{BLACK}Cargo
+STR_013D_INFORMATION :{BLACK}Information
+STR_013E_CAPACITIES :{BLACK}Capacities
+STR_013E_TOTAL_CARGO :{BLACK}Total Cargo
+STR_013F_CAPACITY :{BLACK}Capacity: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}Capacity: {LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Total cargo capacity of this train:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}New Game
+STR_0141_LOAD_GAME :{BLACK}Load Game
+STR_SINGLE_PLAYER :{BLACK}Single player
+STR_MULTIPLAYER :{BLACK}Multiplayer
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Map size:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Game Options
+
+STR_0150_SOMEONE :someone{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Map of world
+STR_0152_TOWN_DIRECTORY :Town directory
+STR_0153_SUBSIDIES :Subsidies
+
+STR_UNITS_IMPERIAL :Imperial
+STR_UNITS_METRIC :Metric
+STR_UNITS_SI :SI
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} mph
+STR_UNITS_VELOCITY_METRIC :{COMMA} km/h
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}hp
+STR_UNITS_POWER_METRIC :{COMMA}hp
+STR_UNITS_POWER_SI :{COMMA}kW
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} ton{P "" s}
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} tonne{P "" s}
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} kg
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}gal
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}l
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}m³
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} gallon{P "" s}
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} litre{P "" s}
+STR_UNITS_VOLUME_LONG_SI :{COMMA} m³
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10³ lbf
+STR_UNITS_FORCE_METRIC :{COMMA} ton force
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Operating profit graph
+STR_0155_INCOME_GRAPH :Income graph
+STR_0156_DELIVERED_CARGO_GRAPH :Delivered cargo graph
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Performance history graph
+STR_0158_COMPANY_VALUE_GRAPH :Company value graph
+STR_0159_CARGO_PAYMENT_RATES :Cargo payment rates
+STR_015A_COMPANY_LEAGUE_TABLE :Company league table
+STR_PERFORMANCE_DETAIL_MENU :Detailed performance rating
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}About OpenTTD
+STR_015C_SAVE_GAME :Save game
+STR_015D_LOAD_GAME :Load game
+STR_015E_QUIT_GAME :Abandon game
+STR_015F_QUIT :Exit
+STR_ABANDON_GAME_QUERY :{YELLOW}Are you sure you want to abandon this game?
+STR_0161_QUIT_GAME :{WHITE}Abandon Game
+STR_SORT_ORDER_TIP :{BLACK}Select sorting order (descending/ascending)
+STR_SORT_CRITERIA_TIP :{BLACK}Select sorting criteria
+STR_SORT_BY :{BLACK}Sort by
+
+STR_SORT_BY_POPULATION :{BLACK}Population
+STR_SORT_BY_PRODUCTION :{BLACK}Production
+STR_SORT_BY_TYPE :{BLACK}Type
+STR_SORT_BY_TRANSPORTED :{BLACK}Transported
+STR_SORT_BY_NAME :{BLACK}Name
+STR_SORT_BY_DROPDOWN_NAME :Name
+STR_SORT_BY_DATE :{BLACK}Date
+STR_SORT_BY_NUMBER :Number
+STR_SORT_BY_PROFIT_LAST_YEAR :Profit last year
+STR_SORT_BY_PROFIT_THIS_YEAR :Profit this year
+STR_SORT_BY_AGE :Age
+STR_SORT_BY_RELIABILITY :Reliability
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Total capacity per cargo type
+STR_SORT_BY_MAX_SPEED :Maximum speed
+STR_SORT_BY_MODEL :Model
+STR_SORT_BY_VALUE :Value
+STR_SORT_BY_FACILITY :Station type
+STR_SORT_BY_WAITING :Waiting cargo value
+STR_SORT_BY_RATING_MAX :Cargo rating
+STR_ENGINE_SORT_ENGINE_ID :EngineID (classic sort)
+STR_ENGINE_SORT_COST :Cost
+STR_ENGINE_SORT_POWER :Power
+STR_ENGINE_SORT_INTRO_DATE :Introduction Date
+STR_ENGINE_SORT_RUNNING_COST :Running Cost
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Power/Running Cost
+STR_ENGINE_SORT_CARGO_CAPACITY :Cargo Capacity
+STR_NO_WAITING_CARGO :{BLACK}No cargo of any type is waiting
+STR_SELECT_ALL_FACILITIES :{BLACK}Select all facilities
+STR_SELECT_ALL_TYPES :{BLACK}Select all cargo types (including no waiting cargo)
+STR_AVAILABLE_ENGINES_TIP :{BLACK}See a list of available engine designs for this vehicle type.
+STR_MANAGE_LIST :{BLACK}Manage list
+STR_MANAGE_LIST_TIP :{BLACK}Send instructions to all vehicles in this list
+STR_REPLACE_VEHICLES :Replace vehicles
+STR_SEND_TRAIN_TO_DEPOT :Send to Depot
+STR_SEND_ROAD_VEHICLE_TO_DEPOT :Send to Depot
+STR_SEND_SHIP_TO_DEPOT :Send to Depot
+STR_SEND_AIRCRAFT_TO_HANGAR :Send to Hangar
+STR_SEND_FOR_SERVICING :Send for Servicing
+
+############ range for months starts
+STR_0162_JAN :Jan
+STR_0163_FEB :Feb
+STR_0164_MAR :Mar
+STR_0165_APR :Apr
+STR_0166_MAY :May
+STR_0167_JUN :Jun
+STR_0168_JUL :Jul
+STR_0169_AUG :Aug
+STR_016A_SEP :Sep
+STR_016B_OCT :Oct
+STR_016C_NOV :Nov
+STR_016D_DEC :Dec
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING2}-
+STR_0171_PAUSE_GAME :{BLACK}Pause game
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Save game, abandon game, quit
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Display list of company's stations
+STR_0174_DISPLAY_MAP :{BLACK}Display map
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Display map, town directory
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Display town directory
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Display company finances information
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Display general company information
+STR_0179_DISPLAY_GRAPHS :{BLACK}Display graphs
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Display company league table
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Display list of company's trains
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Display list of company's road vehicles
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Display list of company's ships
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Display list of company's aircraft
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Zoom the view in
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Zoom the view out
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Build railway track
+STR_0182_BUILD_ROADS :{BLACK}Build roads
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Build ship docks
+STR_0184_BUILD_AIRPORTS :{BLACK}Build airports
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Plant trees, place signs etc.
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Land area information
+STR_0187_OPTIONS :{BLACK}Options
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Can't change servicing interval...
+STR_018B_CLOSE_WINDOW :{BLACK}Close window
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Window title - drag this to move window
+STR_STICKY_BUTTON :{BLACK}Mark this window as uncloseable by the 'Close All Windows' key
+STR_RESIZE_BUTTON :{BLACK}Click and drag to resize this window
+STR_SAVELOAD_HOME_BUTTON :{BLACK}Click here to jump to the current default save/load directory
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Demolish buildings etc. on a square of land
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Lower a corner of land
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Raise a corner of land
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Scroll bar - scrolls list up/down
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Scroll bar - scrolls list left/right
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Show land contours on map
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Show vehicles on map
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Show industries on map
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Show transport routes on map
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Show vegetation on map
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Show land owners on map
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Toggle town names on/off on map
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Profit this year: {CURRENCY} (last year: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} year{P "" s} ({COMMA})
+STR_AGE_RED :{RED}{COMMA} year{P "" s} ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Road vehicle
+STR_019D_AIRCRAFT :Aircraft
+STR_019E_SHIP :Ship
+STR_019F_TRAIN :Train
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} is getting old
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} is getting very old
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} is getting very old and urgently needs replacing
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Land Area Information
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Cost to clear: {LTBLUE}N/A
+STR_01A5_COST_TO_CLEAR :{BLACK}Cost to clear: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :N/A
+STR_01A7_OWNER :{BLACK}Owner: {LTBLUE}{STRING1}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Local authority: {LTBLUE}{STRING1}
+STR_01A9_NONE :None
+STR_01AA_NAME :{BLACK}Name
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1st
+STR_01AD_2ND :2nd
+STR_01AE_3RD :3rd
+STR_01AF_4TH :4th
+STR_01B0_5TH :5th
+STR_01B1_6TH :6th
+STR_01B2_7TH :7th
+STR_01B3_8TH :8th
+STR_01B4_9TH :9th
+STR_01B5_10TH :10th
+STR_01B6_11TH :11th
+STR_01B7_12TH :12th
+STR_01B8_13TH :13th
+STR_01B9_14TH :14th
+STR_01BA_15TH :15th
+STR_01BB_16TH :16th
+STR_01BC_17TH :17th
+STR_01BD_18TH :18th
+STR_01BE_19TH :19th
+STR_01BF_20TH :20th
+STR_01C0_21ST :21st
+STR_01C1_22ND :22nd
+STR_01C2_23RD :23rd
+STR_01C3_24TH :24th
+STR_01C4_25TH :25th
+STR_01C5_26TH :26th
+STR_01C6_27TH :27th
+STR_01C7_28TH :28th
+STR_01C8_29TH :29th
+STR_01C9_30TH :30th
+STR_01CA_31ST :31st
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Cargo accepted: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Jazz Jukebox
+STR_01D3_SOUND_MUSIC :Sound/music
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Show sound/music window
+STR_01D5_ALL :{TINYFONT}All
+STR_01D6_OLD_STYLE :{TINYFONT}Old Style
+STR_01D7_NEW_STYLE :{TINYFONT}New Style
+STR_01D8_EZY_STREET :{TINYFONT}Ezy Street
+STR_01D9_CUSTOM_1 :{TINYFONT}Custom 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Custom 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Music Volume
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Effects Volume
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MIN ' ' ' ' ' ' MAX
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Skip to previous track in selection
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Skip to next track in selection
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Stop playing music
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Start playing music
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Drag sliders to set music and sound effect volumes
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING1}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Track{SETX 88}Title
+STR_01E9_SHUFFLE :{TINYFONT}Shuffle
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Programme
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Music Programme Selection
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING1}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING1}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Track Index
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Programme - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}Clear
+STR_01F1_SAVE :{TINYFONT}{BLACK}Save
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Current programme of music tracks
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Select 'all tracks' programme
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Select 'old style music' programme
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Select 'new style music' programme
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Select 'Custom 1' (user-defined) programme
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Select 'Custom 2' (user-defined) programme
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Clear current programme (Custom1 or Custom2 only)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Save music settings
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Click on music track to add to current programme (Custom1 or Custom2 only)
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Click on music track to remove it from current programme (Custom1 or Custom2 only)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Toggle programme shuffle on/off
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Show music track selection window
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Click on service to centre view on industry/town
+STR_01FE_DIFFICULTY :{BLACK}Difficulty ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Last message/news report
+STR_0201_MESSAGE_SETTINGS :Message settings
+STR_MESSAGE_HISTORY_MENU :Message History
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Show last message/news report, show message options
+STR_0204_MESSAGE_OPTIONS :{WHITE}Message Options
+STR_0205_MESSAGE_TYPES :{BLACK}Message types:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Arrival of first vehicle at player's station
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Arrival of first vehicle at competitor's station
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Accidents / disasters
+STR_0209_COMPANY_INFORMATION :{YELLOW}Company information
+STR_020A_ECONOMY_CHANGES :{YELLOW}Economy changes
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Advice / information on player's vehicles
+STR_020C_NEW_VEHICLES :{YELLOW}New vehicles
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Changes to cargo acceptance
+STR_020E_SUBSIDIES :{YELLOW}Subsidies
+STR_020F_GENERAL_INFORMATION :{YELLOW}General information
+STR_MESSAGES_ALL :{YELLOW}Set all message types to: Off / Summary/ Full
+STR_MESSAGE_SOUND :{YELLOW}Play sound for summarised news messages
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...too far from previous destination
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Top companies who reached {NUM}{}({STRING} Level)
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Company League Table in {NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Businessman
+STR_0214_ENTREPRENEUR :Entrepreneur
+STR_0215_INDUSTRIALIST :Industrialist
+STR_0216_CAPITALIST :Capitalist
+STR_0217_MAGNATE :Magnate
+STR_0218_MOGUL :Mogul
+STR_0219_TYCOON_OF_THE_CENTURY :Tycoon of the Century
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} achieves '{STRING}' status!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} of {COMPANY} achieves '{STRING}' status!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Create Scenario
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Scenario Editor
+STR_0223_LAND_GENERATION :{WHITE}Land Generation
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Random Land
+STR_0227_RESET_LAND :{BLACK}Reset Land
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Increase area of land to lower/raise
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Decrease area of land to lower/raise
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Generate random land
+STR_022B_RESET_LANDSCAPE :{BLACK}Reset landscape
+STR_022C_RESET_LANDSCAPE :{WHITE}Reset Landscape
+STR_LOAD_GAME_HEIGHTMAP :{WHITE}Use Heightmap
+STR_LOAD_SCEN_HEIGHTMAP :{BLACK}Use Heightmap
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Are you sure you want to reset the landscape?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Landscape generation
+STR_022F_TOWN_GENERATION :{BLACK}Town generation
+STR_0230_INDUSTRY_GENERATION :{BLACK}Industry generation
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Road construction
+STR_0233_TOWN_GENERATION :{WHITE}Town Generation
+STR_0234_NEW_TOWN :{BLACK}New Town
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Construct new town
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Can't build town here...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...too close to edge of map
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...too close to another town
+STR_0239_SITE_UNSUITABLE :{WHITE}...site unsuitable
+STR_023A_TOO_MANY_TOWNS :{WHITE}...too many towns
+STR_CANNOT_GENERATE_TOWN :{WHITE}Can't build any towns
+STR_NO_SPACE_FOR_TOWN :{WHITE}...there is no more space on the map
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Increase size of town
+STR_023C_EXPAND :{BLACK}Expand
+STR_023D_RANDOM_TOWN :{BLACK}Random Town
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Build town in random location
+STR_023F_INDUSTRY_GENERATION :{WHITE}Industry Generation
+STR_0240_COAL_MINE :{BLACK}Coal Mine
+STR_0241_POWER_STATION :{BLACK}Power Station
+STR_0242_SAWMILL :{BLACK}Sawmill
+STR_0243_FOREST :{BLACK}Forest
+STR_0244_OIL_REFINERY :{BLACK}Oil Refinery
+STR_0245_OIL_RIG :{BLACK}Oil Rig
+STR_0246_FACTORY :{BLACK}Factory
+STR_0247_STEEL_MILL :{BLACK}Steel Mill
+STR_0248_FARM :{BLACK}Farm
+STR_0249_IRON_ORE_MINE :{BLACK}Iron Ore Mine
+STR_024A_OIL_WELLS :{BLACK}Oil Wells
+STR_024B_BANK :{BLACK}Bank
+STR_024C_PAPER_MILL :{BLACK}Paper Mill
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Food Processing Plant
+STR_024E_PRINTING_WORKS :{BLACK}Printing Works
+STR_024F_GOLD_MINE :{BLACK}Gold Mine
+STR_0250_LUMBER_MILL :{BLACK}Lumber Mill
+STR_0251_FRUIT_PLANTATION :{BLACK}Fruit Plantation
+STR_0252_RUBBER_PLANTATION :{BLACK}Rubber Plantation
+STR_0253_WATER_SUPPLY :{BLACK}Water Supply
+STR_0254_WATER_TOWER :{BLACK}Water Tower
+STR_0255_DIAMOND_MINE :{BLACK}Diamond Mine
+STR_0256_COPPER_ORE_MINE :{BLACK}Copper Ore Mine
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Candyfloss Forest
+STR_0258_CANDY_FACTORY :{BLACK}Sweet Factory
+STR_0259_BATTERY_FARM :{BLACK}Battery Farm
+STR_025A_COLA_WELLS :{BLACK}Cola Wells
+STR_025B_TOY_SHOP :{BLACK}Toy Shop
+STR_025C_TOY_FACTORY :{BLACK}Toy Factory
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Plastic Fountains
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Fizzy Drink Factory
+STR_025F_BUBBLE_GENERATOR :{BLACK}Bubble Generator
+STR_0260_TOFFEE_QUARRY :{BLACK}Toffee Quarry
+STR_0261_SUGAR_MINE :{BLACK}Sugar Mine
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Construct Coal Mine
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Construct Power Station
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Construct Sawmill
+STR_0265_PLANT_FOREST :{BLACK}Plant Forest
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Construct Oil Refinery
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Construct Oil Rig (Can only be built near the edges of the map)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Construct Factory
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Construct Steel Mill
+STR_026A_CONSTRUCT_FARM :{BLACK}Construct Farm
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Construct Iron Ore Mine
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Construct Oil Wells
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Construct Bank (Can only be built in towns with a population greater than 1200)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Construct Paper Mill
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Construct Food Processing Plant
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Construct Printing Works
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Construct Gold Mine
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Construct Bank (Can only be built in towns)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Construct Lumber Mill (to clear rainforest and produce Wood)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Plant Fruit Plantation
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Plant Rubber Plantation
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Construct Water Supply
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Construct Water Tower (Can only be built in towns)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Construct Diamond Mine
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Construct Copper Ore Mine
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Plant Candyfloss Forest
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Construct Sweet Factory
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Construct Battery Farm
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Construct Cola Wells
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Construct Toy Shop
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Construct Toy Factory
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Construct Plastic Fountains
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Construct Fizzy Drink Factory
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Construct Bubble Generator
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Construct Toffee Quarry
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Construct Sugar Mine
+STR_0285_CAN_T_BUILD_HERE :{WHITE}Can't build {STRING} here...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...must build town first
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...only one allowed per town
+STR_0288_PLANT_TREES :{BLACK}Plant trees
+STR_0289_PLACE_SIGN :{BLACK}Place sign
+STR_028A_RANDOM_TREES :{BLACK}Random Trees
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Plant trees randomly over landscape
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Place rocky areas on landscape
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Place lighthouse
+STR_028E_PLACE_TRANSMITTER :{BLACK}Place transmitter
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Define desert area.{}Press and hold CTRL to remove it
+STR_CREATE_LAKE :{BLACK}Define water area.{}It will flood its surroundings if at sea level
+STR_0290_DELETE :{BLACK}Delete
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Delete this town completely
+STR_0292_SAVE_SCENARIO :Save scenario
+STR_0293_LOAD_SCENARIO :Load scenario
+STR_0294_QUIT_EDITOR :Quit editor
+STR_0295 :
+STR_0296_QUIT :Quit
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Save scenario, load scenario, abandon scenario editor, quit
+STR_0298_LOAD_SCENARIO :{WHITE}Load Scenario
+STR_0299_SAVE_SCENARIO :{WHITE}Save Scenario
+STR_029A_PLAY_SCENARIO :{BLACK}Play Scenario
+STR_PLAY_HEIGHTMAP :{BLACK}Play Heightmap
+STR_PLAY_HEIGHTMAP_HINT :{BLACK}Start a new game, using a heightmap as landscape
+STR_QUIT_SCENARIO_QUERY :{YELLOW}Are you sure you want to quit this scenario ?
+STR_029C_QUIT_EDITOR :{WHITE}Quit Editor
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...can only be built in towns with a population of at least 1200
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Move the starting date backward 1 year
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Move the starting date forward 1 year
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...ends of bridge must both be on land
+STR_02A1_SMALL :{BLACK}Small
+STR_02A2_MEDIUM :{BLACK}Medium
+STR_02A3_LARGE :{BLACK}Large
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Select town size
+STR_02A5_TOWN_SIZE :{YELLOW}Town size:
+
+STR_02B6 :{STRING} - {STRING5}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Show last message or news report
+STR_OFF :Off
+STR_SUMMARY :Summary
+STR_FULL :Full
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Town directory
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Vehicle design names
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Default
+STR_02BF_CUSTOM :Custom
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Save custom names
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Vehicle design names selection
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Save customised vehicle design names
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Game options
+STR_02C5_DIFFICULTY_SETTINGS :Difficulty settings
+STR_02C7_CONFIG_PATCHES :Configure patches
+STR_NEWGRF_SETTINGS :NewGRF settings
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Town names displayed
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Station names displayed
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Signs displayed
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Waypoints displayed
+STR_02D0_FULL_ANIMATION :{SETX 12}Full animation
+STR_02D2_FULL_DETAIL :{SETX 12}Full detail
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Transparent buildings
+STR_TRANSPARENT_SIGNS :{SETX 12}Transparent station signs
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Land area information
+STR_02D6 :
+STR_CONSOLE_SETTING :Toggle Console
+STR_02D7_SCREENSHOT_CTRL_S :Screenshot (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Giant Screenshot (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :About 'OpenTTD'
+############ range ends here
+
+STR_02DB_OFF :{BLACK}Off
+STR_02DA_ON :{BLACK}On
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Display subsidies
+STR_02DD_SUBSIDIES :Subsidies
+STR_02DE_MAP_OF_WORLD :Map of world
+STR_EXTRA_VIEW_PORT :Extra viewport
+STR_SIGN_LIST :Sign list
+STR_02DF_TOWN_DIRECTORY :Town directory
+STR_TOWN_POPULATION :{BLACK}World population: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Viewport {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Copy to viewport
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Copy the location of the global view to this viewport
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Paste from viewport
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Paste the location of this viewport to the global view
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Currency units
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Currency units selection
+STR_MEASURING_UNITS :{BLACK}Measuring units
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Measuring units selection
+STR_02E6_ROAD_VEHICLES :{BLACK}Road vehicles
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Select side of road for vehicles to drive on
+STR_02E9_DRIVE_ON_LEFT :Drive on left
+STR_02EA_DRIVE_ON_RIGHT :Drive on right
+STR_02EB_TOWN_NAMES :{BLACK}Town names
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Select style of town names
+
+STR_02F4_AUTOSAVE :{BLACK}Autosave
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Select interval between automatic game saves
+STR_02F7_OFF :Off
+STR_02F8_EVERY_3_MONTHS :Every 3 months
+STR_02F9_EVERY_6_MONTHS :Every 6 months
+STR_02FA_EVERY_12_MONTHS :Every 12 months
+STR_02FB_START_A_NEW_GAME :{BLACK}Start a new game
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Load a saved game
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Create a customised game world/scenario
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Select single-player game
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Select multiplayer game of 2-8 players
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Display game options
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Display difficulty options
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Start a new game, using a customised scenario
+STR_0304_QUIT :{BLACK}Quit
+STR_0305_QUIT_OPENTTD :{BLACK}Quit 'OpenTTD'
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...can only be built in towns
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Select 'temperate' landscape style
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Select 'sub-arctic' landscape style
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Select 'sub-tropical' landscape style
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Select 'toyland' landscape style
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Fund construction of new industry
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Industry Directory
+STR_0313_FUND_NEW_INDUSTRY :Fund new industry
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Fund new industry
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...can only be built in towns
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...can only be built in rainforest areas
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...can only be built in desert areas
+STR_0319_PAUSED :{YELLOW}* * PAUSED * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Screenshot successfully saved as '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}Screenshot failed!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Purchase land for future use
+STR_032F_AUTOSAVE :{RED}AUTOSAVE
+STR_SAVING_GAME :{RED}* * SAVING GAME * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}Saving still in progress,{}please wait until it is finished!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Select 'Ezy Street style music' programme
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :English (Original)
+STR_TOWNNAME_FRENCH :French
+STR_TOWNNAME_GERMAN :German
+STR_TOWNNAME_ADDITIONAL_ENGLISH :English (Additional)
+STR_TOWNNAME_LATIN_AMERICAN :Latin-American
+STR_TOWNNAME_SILLY :Silly
+STR_TOWNNAME_SWEDISH :Swedish
+STR_TOWNNAME_DUTCH :Dutch
+STR_TOWNNAME_FINNISH :Finnish
+STR_TOWNNAME_POLISH :Polish
+STR_TOWNNAME_SLOVAKISH :Slovakish
+STR_TOWNNAME_NORWEGIAN :Norwegian
+STR_TOWNNAME_HUNGARIAN :Hungarian
+STR_TOWNNAME_AUSTRIAN :Austrian
+STR_TOWNNAME_ROMANIAN :Romanian
+STR_TOWNNAME_CZECH :Czech
+STR_TOWNNAME_SWISS :Swiss
+STR_TOWNNAME_DANISH :Danish
+STR_TOWNNAME_TURKISH :Turkish
+STR_TOWNNAME_ITALIAN :Italian
+STR_TOWNNAME_CATALAN :Catalan
+############ end of townname region
+
+STR_CURR_GBP :Pounds (£)
+STR_CURR_USD :Dollars ($)
+STR_CURR_EUR :Euro (€)
+STR_CURR_YEN :Yen (Â¥)
+STR_CURR_ATS :Austrian Shilling (ATS)
+STR_CURR_BEF :Belgian Franc (BEF)
+STR_CURR_CHF :Swiss Franc (CHF)
+STR_CURR_CZK :Czech Koruna (CZK)
+STR_CURR_DEM :Deutschmark (DEM)
+STR_CURR_DKK :Danish Krone (DKK)
+STR_CURR_ESP :Peseta (ESP)
+STR_CURR_FIM :Finnish Markka (FIM)
+STR_CURR_FRF :Franc (FRF)
+STR_CURR_GRD :Greek Drachma (GRD)
+STR_CURR_HUF :Hungarian Forint (HUF)
+STR_CURR_ISK :Icelandic Krona (ISK)
+STR_CURR_ITL :Italian Lira (ITL)
+STR_CURR_NLG :Dutch Guilder (NLG)
+STR_CURR_NOK :Norwegian Krone (NOK)
+STR_CURR_PLN :Polish Zloty (PLN)
+STR_CURR_ROL :Romanian Leu (ROL)
+STR_CURR_RUR :Russian Rubles (RUR)
+STR_CURR_SIT :Slovenian Tolar (SIT)
+STR_CURR_SEK :Swedish Krona (SEK)
+STR_CURR_YTL :Turkish Lira (YTL)
+STR_CURR_SKK :Slovak Koruna (SKK)
+STR_CURR_BRR :Brazilian Real (BRL)
+
+STR_CURR_CUSTOM :Custom...
+
+STR_OPTIONS_LANG :{BLACK}Language
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Select the interface language to use
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Fullscreen
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}Check this box to play OpenTTD fullscreen mode
+
+STR_OPTIONS_RES :{BLACK}Screen resolution
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Select the screen resolution to use
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Screenshot format
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Select the screenshot format to use
+
+STR_AUTOSAVE_1_MONTH :Every month
+STR_AUTOSAVE_FAILED :{WHITE}Autosave failed
+
+STR_MONTH_JAN :January
+STR_MONTH_FEB :February
+STR_MONTH_MAR :March
+STR_MONTH_APR :April
+STR_MONTH_MAY :May
+STR_MONTH_JUN :June
+STR_MONTH_JUL :July
+STR_MONTH_AUG :August
+STR_MONTH_SEP :September
+STR_MONTH_OCT :October
+STR_MONTH_NOV :November
+STR_MONTH_DEC :December
+
+STR_HEADING_FOR_STATION :{LTBLUE}Heading for {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}Heading for {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}No orders
+STR_NO_ORDERS_VEL :{LTBLUE}No orders, {VELOCITY}
+
+STR_PASSENGERS :passengers
+STR_BAGS :bags
+STR_TONS :tonnes
+STR_LITERS :litres
+STR_ITEMS :items
+STR_CRATES :crates
+STR_RES_OTHER :other
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Can't share order list...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Can't copy order list...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - End of Shared Orders - -
+
+STR_TRAIN_IS_LOST :{WHITE}Train {COMMA} is lost.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}Train {COMMA}'s profit last year was {CURRENCY}
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}European Monetary Union!{}{}The Euro is introduced as the sole currency for everyday transactions in your country!
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Train {COMMA} has too few orders in the schedule
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}Train {COMMA} has a void order
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}Train {COMMA} has duplicate orders
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}Train {COMMA} has an invalid station in its orders
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}Road Vehicle {COMMA} has too few orders in the schedule
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}Road Vehicle {COMMA} has a void order
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}Road Vehicle {COMMA} has duplicate orders
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}Road Vehicle {COMMA} has an invalid station in its orders
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}Ship {COMMA} has too few orders in the schedule
+STR_SHIP_HAS_VOID_ORDER :{WHITE}Ship {COMMA} has a void order
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}Ship {COMMA} has duplicate orders
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}Ship {COMMA} has an invalid station in its orders
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}Aircraft {COMMA} has too few orders in the schedule
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}Aircraft {COMMA} has a void order
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}Aircraft {COMMA} has duplicate orders
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}Aircraft {COMMA} has an invalid station in its orders
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}Autorenew failed on train {COMMA} (money limit)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}Autorenew failed on road vehicle {COMMA} (money limit)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}Autorenew failed on ship {COMMA} (money limit)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}Autorenew failed on aircraft {COMMA} (money limit)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}Train {COMMA} is too long after replacement
+
+STR_CONFIG_PATCHES :{BLACK}Configure Patches
+STR_CONFIG_PATCHES_TIP :{BLACK}Configure the patches
+STR_CONFIG_PATCHES_CAPTION :{WHITE}Configure Patches
+
+STR_CONFIG_PATCHES_OFF :Off
+STR_CONFIG_PATCHES_ON :On
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Show vehicle speed in status bar: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Allow building on slopes and coasts: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Allow more realistically sized catchment areas: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Allow removal of more town-owned roads, bridges, etc: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Enable building very long trains: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Enable realistic acceleration for trains: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Forbid trains and ships to make 90 deg turns: {ORANGE}{STRING1} {LTBLUE} (requires NPF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Join train stations built next to each other: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Leave station when any cargo is full, if 'full load': {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Use improved loading algorithm: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_GRADUAL_LOADING :{LTBLUE}Load vehicles gradually: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Inflation: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Deliver cargo to a station only when there is a demand: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Allow building very long bridges: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Allow goto depot orders: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Allow constructing raw material producing industries: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Allow multiple similar industries per town: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Industries of the same type can be built close to each other: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Always show long date in the status bar: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Show signals on the drive side: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Show finances window at the end of the year: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}TTDPatch compatible nonstop handling: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Road vehicle queueing (with quantum effects): {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Pan window when mouse is at the edge: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Allow bribing of the local authority: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Nonuniform stations: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}New global pathfinding (NPF, overrides NTP): {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_FREIGHT_TRAINS :{LTBLUE}Weight multiplier for freight to simulate heavy trains: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Always allow small airports: {ORANGE}{STRING1}
+
+STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Warn if train is lost: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Review vehicles' orders: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :no
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :yes, but exclude stopped vehicles
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :of all vehicles
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Warn if a train's income is negative: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Vehicles never expire: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Autorenew vehicle when it gets old
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Autorenew when vehice is {ORANGE}{STRING1}{LTBLUE} months before/after max age
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Autorenew minimum needed money for renew: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Duration of error message: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Show town population in the town name label: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Invisible trees (with transparent buildings): {ORANGE}{STRING1}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Land generator: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :Original
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis
+STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}Max distance from edge for Oil Refineries {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Snow line height: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN :{LTBLUE}Roughness of terrain (TerraGenesis only) : {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Very Smooth
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH :Smooth
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH :Rough
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :Very Rough
+STR_CONFIG_PATCHES_TREE_PLACER :{LTBLUE}Tree placer algorithm: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_TREE_PLACER_NONE :None
+STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL :Original
+STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED :Improved
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION :{LTBLUE}Heightmap rotation: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Counter clockwise
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE :Clockwise
+STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT :{LTBLUE}The height level a flat scenario map gets: {ORANGE}{STRING1}
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Max station spread: {ORANGE}{STRING1} {RED}Warning: High setting slows game
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Service helicopters at helipads automatically: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Link landscape toolbar to rail/road/water/airport toolbars: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Reverse scroll direction: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Show a measurement tooltip when using various build-tools: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Show company liveries: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_LIVERIES_NONE :None
+STR_CONFIG_PATCHES_LIVERIES_OWN :Own company
+STR_CONFIG_PATCHES_LIVERIES_ALL :All companies
+STR_CONFIG_PATCHES_PREFER_TEAMCHAT :{LTBLUE}Prefer team chat with <ENTER>: {ORANGE}{STRING1}
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Max trains per player: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Max road vehicles per player: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}Max aircraft per player: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}Max ships per player: {ORANGE}{STRING1}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Disable trains for computer: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Disable road vehicles for computer: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Disable aircraft for computer: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Disable ships for computer: {ORANGE}{STRING1}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Enable new AI (alpha): {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Allow AIs in multiplayer (experimental): {ORANGE}{STRING1}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Default service interval for trains: {ORANGE}{STRING1} days/%
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Default service interval for trains: {ORANGE}disabled
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Default service interval for road vehicles: {ORANGE}{STRING1} days/%
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Default service interval for road vehicles: {ORANGE}disabled
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Default service interval for aircraft: {ORANGE}{STRING1} days/%
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Default service interval for aircraft: {ORANGE}disabled
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Default service interval for ships: {ORANGE}{STRING1} days/%
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Default service interval for ships: {ORANGE}disabled
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Disable servicing when breakdowns set to none: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Enable wagon speed limits: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}Disable electric rails: {ORANGE}{STRING1}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Coloured news appears in: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Starting year: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}End game in: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Enable smooth economy (more, smaller changes)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Allow buying shares from other companies
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}When dragging, place signals every: {ORANGE}{STRING1} tile(s)
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Position of main toolbar: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Left
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Centre
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Right
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Window snap radius: {ORANGE}{STRING1} px
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Window snap radius: {ORANGE}disabled
+
+STR_CONFIG_PATCHES_GUI :{BLACK}Interface
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Construction
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Vehicles
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Stations
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Economy
+STR_CONFIG_PATCHES_AI :{BLACK}Competitors
+
+STR_CONFIG_PATCHES_DISABLED :disabled
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Change setting value
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Some or all of the default service interval(s) below are incompatible with the chosen setting! 5-90% and 30-800 days are valid
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}Use YAPF for ships: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}Use YAPF for roadvehs: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}Use YAPF for trains: {ORANGE}{STRING1}
+
+STR_TEMPERATE_LANDSCAPE :Temperate landscape
+STR_SUB_ARCTIC_LANDSCAPE :Sub-arctic landscape
+STR_SUB_TROPICAL_LANDSCAPE :Sub-tropical landscape
+STR_TOYLAND_LANDSCAPE :Toyland landscape
+
+STR_CHEATS :{WHITE}Cheats
+STR_CHEATS_TIP :{BLACK}Checkboxes indicate if you have used this cheat before
+STR_CHEATS_WARNING :{BLACK}Warning! You are about to betray your fellow competitors. Keep in mind that such a disgrace will be remembered for eternity.
+STR_CHEAT_MONEY :{LTBLUE}Increase money by {CURRENCY64}
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Playing as player: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Magic bulldozer (remove industries, unmovables): {ORANGE}{STRING1}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Tunnels may cross each other: {ORANGE}{STRING1}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Build while in pause mode: {ORANGE}{STRING1}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Jetplanes will not crash (frequently) on small airports: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Switch climate: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Change date: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}Enable modifying production values: {ORANGE}{STRING1}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}Heading for {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Heading for {WAYPOINT}, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :Go via {WAYPOINT}
+STR_GO_NON_STOP_TO_WAYPOINT :Go non-stop via {WAYPOINT}
+
+STR_WAYPOINTNAME_CITY :Waypoint {TOWN}
+STR_WAYPOINTNAME_CITY_SERIAL :Waypoint {TOWN} #{COMMA}
+STR_LANDINFO_WAYPOINT :Waypoint
+
+STR_WAYPOINT :{WHITE}Waypoint
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Select waypoint type
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}Edit waypoint name
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Can't change waypoint name...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Convert rail to waypoint
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Can't build train waypoint here...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Can't remove train waypoint here...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Build railway track using the Autorail mode
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}...there is no town in this scenario
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}Are you sure you want to create a random landscape?
+STR_MANY_RANDOM_TOWNS :{BLACK}Many random towns
+STR_RANDOM_TOWNS_TIP :{BLACK}Cover the map with randomly placed towns
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Many random industries
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Cover the map with randomly placed industries
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Can't generate industries...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Open the landscaping toolbar to raise/lower land, plant trees, etc.
+STR_LANDSCAPING_TOOLBAR :{WHITE}Landscaping
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Level land
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Trees of random type
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}Place trees of random type
+
+STR_CANT_BUILD_CANALS :{WHITE}Can't build canals here...
+STR_BUILD_CANALS_TIP :{BLACK}Build canals. Press CTRL to place sea tiles (at sea-level only.)
+STR_LANDINFO_CANAL :Canal
+
+STR_CANT_BUILD_LOCKS :{WHITE}Can't build locks here...
+STR_BUILD_LOCKS_TIP :{BLACK}Build locks
+STR_LANDINFO_LOCK :Lock
+
+STR_BUOY_IS_IN_USE :{WHITE}...buoy is in use!
+
+STR_LANDINFO_COORDS :{BLACK}Coordinates: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Can't remove part of station...
+STR_CANT_CONVERT_RAIL :{WHITE}Can't convert railtype here...
+STR_CONVERT_RAIL_TIP :{BLACK}Convert/Upgrade the type of rail
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Drag train engine here to sell the whole train
+
+STR_DRAG_DROP :{BLACK}Drag & Drop
+STR_STATION_DRAG_DROP :{BLACK}Build a station using drag & drop
+STR_SELECT_STATION_CLASS_TIP :{BLACK}Select a station class to display
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Select the station type to build
+
+STR_FAST_FORWARD :{BLACK}Fast forward the game
+STR_MESSAGE_HISTORY :{WHITE}Message History
+STR_MESSAGE_HISTORY_TIP :{BLACK}A list of the recent news messages
+STR_MESSAGES_DISABLE_ALL :{BLACK}Disable all
+STR_MESSAGES_ENABLE_ALL :{BLACK}Enable all
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Construct Coal Mine
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Plant Forest
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Construct Oil Rig
+STR_CONSTRUCT_FARM_TIP :{BLACK}Fund Farm
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Construct Copper Ore Mine
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Drill for Oil
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Construct Gold Mine
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Construct Diamond Mine
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Construct Iron Ore Mine
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Fund Fruit Plantation
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Fund Rubber Plantation
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Fund Water Supply
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Plant Candyfloss Forest
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}Fund Battery Farm
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Drill for Cola
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Fund Plastic Fountains
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Construct Bubble Generator
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Fund Toffee Quarry
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Construct Sugar Mine
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Industries
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA}% transported)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA}%/{COMMA}% transported)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}...too close to another industry
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Refit train to carry a different cargo type
+STR_RAIL_REFIT_VEHICLE :{BLACK}Refit train
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Select type of cargo for train to carry
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Refit train to carry highlighted cargo type
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Can't refit train...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Service intervals are in percents: {ORANGE}{STRING1}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Change production
+
+TEMP_AI_IN_PROGRESS :{WHITE}Welcome to the new AI under development. If you encounter problems, take a screenshot and post it in the forum.
+TEMP_AI_ACTIVATED :{WHITE}Warning: this new AI is still alpha! Currently, only trucks and busses work!
+TEMP_AI_MULTIPLAYER :{WHITE}Warning: implementation is still experimental (using new AI). Please report any problems to truelight@openttd.org.
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Multiplayer
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Player name:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}This is the name other players will identify you by
+STR_NETWORK_CONNECTION :{BLACK}Connection:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Choose between an internet game or a Local Area Network (LAN) game
+
+STR_NETWORK_START_SERVER :{BLACK}Start server
+STR_NETWORK_START_SERVER_TIP :{BLACK}Start your own server
+
+STR_NETWORK_GAME_NAME :{BLACK}Name
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Name of the game
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Language, server version, etc.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Click a game from the list to select it
+
+STR_NETWORK_FIND_SERVER :{BLACK}Find server
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Search network for a server
+STR_NETWORK_ADD_SERVER :{BLACK}Add server
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Adds a server to the list which will always be checked for running games.
+STR_NETWORK_ENTER_IP :{BLACK}Enter the address of the host
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Clients
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Clients online / clients max{}Companies online / companies max
+STR_NETWORK_GAME_INFO :{SILVER}GAME INFO
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Clients: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Language: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Tileset: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Map size: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}Server version: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}Server address: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Start date: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Current date: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Password protected!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}SERVER OFFLINE
+STR_NETWORK_SERVER_FULL :{SILVER}SERVER FULL
+STR_NETWORK_VERSION_MISMATCH :{SILVER}VERSION MISMATCH
+STR_NETWORK_GRF_MISMATCH :{SILVER}NEWGRF MISMATCH
+
+STR_NETWORK_JOIN_GAME :{BLACK}Join game
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}Start new multiplayer game
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Game name:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}The game name will be displayed to other players in the multiplayer game selection menu
+STR_NETWORK_SET_PASSWORD :{BLACK}Set password
+STR_NETWORK_PASSWORD_TIP :{BLACK}Protect your game with a password if you don't want it to be publicly accessible
+STR_NETWORK_SELECT_MAP :{BLACK}Select a map:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}Which map do you want to play?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}Max clients:
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Choose the maximum number of clients. Not all slots need to be filled
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :LAN
+STR_NETWORK_INTERNET :Internet
+STR_NETWORK_LAN_INTERNET :LAN / Internet
+STR_NETWORK_INTERNET_ADVERTISE :Internet (advertise)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 players
+STR_NETWORK_1_PLAYERS :1 player
+STR_NETWORK_2_PLAYERS :2 players
+STR_NETWORK_3_PLAYERS :3 players
+STR_NETWORK_4_PLAYERS :4 players
+STR_NETWORK_5_PLAYERS :5 players
+STR_NETWORK_6_PLAYERS :6 players
+STR_NETWORK_7_PLAYERS :7 players
+STR_NETWORK_8_PLAYERS :8 players
+STR_NETWORK_9_PLAYERS :9 players
+STR_NETWORK_10_PLAYERS :10 players
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}Max companies:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Limit the server to a certain amount of companies
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}Max spectators:
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Limit the server to a certain amount of spectators
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Language spoken:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Other players will know which language is spoken on the server
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}Start Game
+STR_NETWORK_START_GAME_TIP :{BLACK}Start a new network game from a random map, or scenario
+STR_NETWORK_LOAD_GAME :{BLACK}Load Game
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Resume an earlier saved multiplayer game (be sure to connect as the correct player)
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Any
+STR_NETWORK_LANG_ENGLISH :English
+STR_NETWORK_LANG_GERMAN :German
+STR_NETWORK_LANG_FRENCH :French
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Multiplayer game lobby
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Preparing to join: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}A list of all companies currently in this game. You can either join one or start a new one if there is a free company slot
+STR_NETWORK_NEW_COMPANY :{BLACK}New company
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Create a new company
+STR_NETWORK_SPECTATE_GAME :{BLACK}Spectate game
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Watch the game as a spectator
+STR_NETWORK_JOIN_COMPANY :{BLACK}Join company
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Help manage this company
+STR_NETWORK_REFRESH :{BLACK}Refresh server
+STR_NETWORK_REFRESH_TIP :{BLACK}Refresh the server info
+
+STR_NETWORK_COMPANY_INFO :{SILVER}COMPANY INFO
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Company name: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}Inauguration: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}Company value: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Current balance: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Last year's income: {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}Performance: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}Vehicles: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Stations: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Players: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}Connecting...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) Connecting..
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Authorising..
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Waiting..
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Downloading map..
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Processing data..
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) Registering..
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Fetching game info..
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Fetching company info..
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} client{P "" s} in front of you
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} kbytes downloaded so far
+
+STR_NETWORK_DISCONNECT :{BLACK}Disconnect
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Enter the amount of money you want to give
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Server is protected. Enter password
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Company is protected. Enter password
+STR_NETWORK_CLIENT_LIST :{WHITE}Client List
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE} No network devices found or compiled without ENABLE_NETWORK
+STR_NETWORK_ERR_NOSERVER :{WHITE} Could not find any network games
+STR_NETWORK_ERR_NOCONNECTION :{WHITE} The server didn't answer the request
+STR_NETWORK_ERR_DESYNC :{WHITE} Network-Game synchronisation failed
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} Network-Game connection lost
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} Could not load savegame
+STR_NETWORK_ERR_SERVER_START :{WHITE} Could not start the server
+STR_NETWORK_ERR_CLIENT_START :{WHITE} Could not connect
+STR_NETWORK_ERR_TIMEOUT :{WHITE} Connection #{NUM} timed out
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE} A protocol-error was made and the connection was closed
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE} The revision of this client does not match the server's revision
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} Wrong password
+STR_NETWORK_ERR_SERVER_FULL :{WHITE} The server is full
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} You are banned from this server
+STR_NETWORK_ERR_KICKED :{WHITE} You were kicked out of the game
+STR_NETWORK_ERR_CHEATER :{WHITE} Cheating is not allowed on this server
+
+STR_NETWORK_ERR_LEFT :has left the game
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :general error
+STR_NETWORK_ERR_CLIENT_DESYNC :desync error
+STR_NETWORK_ERR_CLIENT_SAVEGAME :could not load map
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :connection lost
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :protocol error
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :not authorized
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :received strange packet
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :wrong revision
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :name already in use
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :wrong password
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :wrong player-id in DoCommand
+STR_NETWORK_ERR_CLIENT_KICKED :kicked by server
+STR_NETWORK_ERR_CLIENT_CHEATER :was trying to use a cheat
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :server full
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :has joined the game
+STR_NETWORK_GIVE_MONEY :gave your company some money ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :you gave {STRING} some money ({CURRENCY})
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Team] :
+STR_NETWORK_CHAT_COMPANY :[Team] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Team] To {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[Private] :
+STR_NETWORK_CHAT_CLIENT :[Private] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[Private] To {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[All] :
+STR_NETWORK_CHAT_ALL :[All] {STRING}: {GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :has changed his/her name to
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE} The server closed the session
+STR_NETWORK_SERVER_REBOOT :{WHITE} The server is restarting...{}Please wait...
+
+STR_NETWORK_SERVER :Server
+STR_NETWORK_CLIENT :Client
+STR_NETWORK_SPECTATORS :Spectators
+
+STR_NETWORK_CLIENTLIST_NONE :(none)
+STR_NETWORK_CLIENTLIST_KICK :Kick
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Give money
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Speak to all
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Speak to company
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Private message
+
+
+STR_NETWORK_SEND :{BLACK}Send
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}X-size of map: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Y-size of map: {ORANGE}{STRING1}
+
+
+##### PNG-MAP-Loader
+
+STR_PNGMAP_ERROR :{WHITE}Cannot load landscape from PNG...
+STR_PNGMAP_ERR_FILE_NOT_FOUND :{WHITE}...file not found.
+STR_PNGMAP_ERR_IMAGE_TYPE :{WHITE}...could not convert image type. 8 or 24-bit PNG image needed.
+STR_PNGMAP_ERR_MISC :{WHITE}...something just went wrong. Sorry. (probably corrupted file)
+
+STR_BMPMAP_ERROR :{WHITE}Cannot load landscape from BMP...
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}...could not convert image type.
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Cost: {CURRENCY}
+STR_0801_COST :{RED}Cost: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Income: {CURRENCY}
+STR_0803_INCOME :{GREEN}Income: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Transfer: {CURRENCY}
+STR_FEEDER :{YELLOW}Transfer: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Estimated Cost: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Estimated Income: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Can't raise land here...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Can't lower land here...
+STR_080A_ROCKS :Rocks
+STR_080B_ROUGH_LAND :Rough land
+STR_080C_BARE_LAND :Bare land
+STR_080D_GRASS :Grass
+STR_080E_FIELDS :Fields
+STR_080F_SNOW_COVERED_LAND :Snow-covered land
+STR_0810_DESERT :Desert
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Land sloped in wrong direction
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Impossible track combination
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}Excavation would damage tunnel
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Already at sea-level
+STR_1004_TOO_HIGH :{WHITE}Too high
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}No suitable railway track
+STR_1007_ALREADY_BUILT :{WHITE}...already built
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Must remove railway track first
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Railway Construction
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Electrified Railway Construction
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Monorail Construction
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}MagLev Construction
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Select Rail Bridge
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Can't build train depot here...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Can't build railway station here...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Can't build signals here...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Can't build railway track here...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Can't remove railway track from here...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Can't remove signals from here...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Train Depot Orientation
+STR_1015_RAILROAD_CONSTRUCTION :Railway construction
+STR_TOOLB_ELRAIL_CONSTRUCTION :Electrified Railway construction
+STR_1016_MONORAIL_CONSTRUCTION :Monorail construction
+STR_1017_MAGLEV_CONSTRUCTION :MagLev construction
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Build railway track
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Build train depot (for building and servicing trains)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Build railway station
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Build railway signals
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Build railway bridge
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Build railway tunnel
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Toggle build/remove for railway track and signals
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Bridge selection - click on your prefered bridge to build it
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Select railway depot orientation
+STR_1021_RAILROAD_TRACK :Railway track
+STR_1023_RAILROAD_TRAIN_DEPOT :Railway train depot
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...area is owned by another company
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :Railway track with normal signals
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :Railway track with pre-signals
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :Railway track with exit-signals
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :Railway track with combo-signals
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Must remove road first
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Road works in progress
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Road Construction
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Select Road Bridge
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Can't build road here...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Can't remove road from here...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Road Depot Orientation
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Can't build road vehicle depot here...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Can't build bus station...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Can't build lorry station...
+STR_180A_ROAD_CONSTRUCTION :Road construction
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Build road section
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Build road vehicle depot (for building and servicing vehicles)
+STR_180D_BUILD_BUS_STATION :{BLACK}Build bus station
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Build lorry loading bay
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Build road bridge
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Build road tunnel
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Toggle build/remove for road construction
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Select road vehicle depot orientation
+STR_1814_ROAD :Road
+STR_1815_ROAD_WITH_STREETLIGHTS :Road with streetlights
+STR_1816_TREE_LINED_ROAD :Tree-lined road
+STR_1817_ROAD_VEHICLE_DEPOT :Road vehicle depot
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :Road/rail level crossing
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Towns
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING1}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Building must be demolished first
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}Population: {ORANGE}{COMMA}{BLACK} Houses: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Rename Town
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Can't rename town...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} local authority refuses to allow this
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Town names - click on name to centre view on town
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centre the main view on town location
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Change town name
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passengers last month: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Mail last month: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Tall office block
+STR_2010_OFFICE_BLOCK :Office block
+STR_2011_SMALL_BLOCK_OF_FLATS :Small block of flats
+STR_2012_CHURCH :Church
+STR_2013_LARGE_OFFICE_BLOCK :Large office block
+STR_2014_TOWN_HOUSES :Town houses
+STR_2015_HOTEL :Hotel
+STR_2016_STATUE :Statue
+STR_2017_FOUNTAIN :Fountain
+STR_2018_PARK :Park
+STR_2019_OFFICE_BLOCK :Office block
+STR_201A_SHOPS_AND_OFFICES :Shops and offices
+STR_201B_MODERN_OFFICE_BUILDING :Modern office building
+STR_201C_WAREHOUSE :Warehouse
+STR_201D_OFFICE_BLOCK :Office block
+STR_201E_STADIUM :Stadium
+STR_201F_OLD_HOUSES :Old houses
+STR_2020_LOCAL_AUTHORITY :{BLACK}Local authority
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Show information on local authority
+STR_2022_LOCAL_AUTHORITY :{WHITE}{TOWN} local authority
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Transport company ratings:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Subsidies
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Subsidies on offer for services taking:
+STR_2027_FROM_TO :{ORANGE}{STRING} from {STRING2} to {STRING2}
+STR_2028_BY :{YELLOW} (by {DATE_SHORT})
+STR_202A_NONE :{ORANGE}None
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Services already subsidised:
+STR_202C_FROM_TO :{ORANGE}{STRING} from {STATION} to {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, until {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}Offer of subsidy expired:{}{}{STRING} from {STRING2} to {STRING2} will now not attract a subsidy.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Subsidy withdrawn:{}{}{STRING} service from {STATION} to {STATION} is no longer subsidised.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Service subsidy offered:{}{}First {STRING} service from {STRING2} to {STRING2} will attract a year's subsidy from the local authority!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Service subsidy awarded to {COMPANY}!{}{}{STRING} service from {STATION} to {STATION} will pay 50% extra for the next year!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Service subsidy awarded to {COMPANY}!{}{}{STRING} service from {STATION} to {STATION} will pay double rates for the next year!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Service subsidy awarded to {COMPANY}!{}{}{STRING} service from {STATION} to {STATION} will pay triple rates for the next year!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Service subsidy awarded to {COMPANY}!{}{}{STRING} service from {STATION} to {STATION} will pay quadruple rates for the next year!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} local authority refuses to allow another airport to be built in this town
+STR_2036_COTTAGES :Cottages
+STR_2037_HOUSES :Houses
+STR_2038_FLATS :Flats
+STR_2039_TALL_OFFICE_BLOCK :Tall office block
+STR_203A_SHOPS_AND_OFFICES :Shops and offices
+STR_203B_SHOPS_AND_OFFICES :Shops and offices
+STR_203C_THEATER :Theatre
+STR_203D_STADIUM :Stadium
+STR_203E_OFFICES :Offices
+STR_203F_HOUSES :Houses
+STR_2040_CINEMA :Cinema
+STR_2041_SHOPPING_MALL :Shopping mall
+STR_2042_DO_IT :{BLACK}Do it
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}List of things to do at this town - click on item for more details
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Carry out the highlighted action in the list above
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Actions available:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Small advertising campaign
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Medium advertising campaign
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Large advertising campaign
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Fund local road reconstruction
+STR_204A_BUILD_STATUE_OF_COMPANY :Build statue of company owner
+STR_204B_FUND_NEW_BUILDINGS :Fund new buildings
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Buy exclusive transport rights
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Bribe the local authority
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Initiate a small local advertising campaign, to attract more passengers and cargo to your transport services.{} Cost: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Initiate a medium local advertising campaign, to attract more passengers and cargo to your transport services.{} Cost: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Initiate a large local advertising campaign, to attract more passengers and cargo to your transport services.{} Cost: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} Fund the reconstruction of the urban road network. Causes considerable disruption to road traffic for up to 6 months.{} Cost: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Build a statue in honour of your company.{} Cost: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Fund the construction of new commercial buildings in the town.{} Cost: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Buy 1 year's exclusive transport rights in town. Town authority will only allow passengers and cargo to use your company's stations.{} Cost: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Bribe the local authority to increase your rating, at the risk of a severe penalty if caught.{} Cost: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}Traffic chaos in {TOWN}!{}{}Road rebuilding programme funded by {COMPANY} brings 6 months of misery to motorists!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (under construction)
+STR_2059_IGLOO :Igloo
+STR_205A_TEPEES :Tepees
+STR_205B_TEAPOT_HOUSE :Teapot-House
+STR_205C_PIGGY_BANK :Piggy-Bank
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN} {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Landscaping
+STR_2800_PLANT_TREES :Plant trees
+STR_2801_PLACE_SIGN :Place sign
+STR_2802_TREES :{WHITE}Trees
+STR_2803_TREE_ALREADY_HERE :{WHITE}...tree already here
+STR_2804_SITE_UNSUITABLE :{WHITE}...site unsuitable
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Can't plant tree here...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...too many signs
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Can't place sign here...
+STR_280A_SIGN :Sign
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Edit sign text
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Can't change sign name...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Select tree type to plant
+STR_280E_TREES :Trees
+STR_280F_RAINFOREST :Rainforest
+STR_2810_CACTUS_PLANTS :Cactus Plants
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Rail Station Selection
+STR_3001_AIRPORT_SELECTION :{WHITE}Airport Selection
+STR_3002_ORIENTATION :{BLACK}Orientation
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Number of tracks
+STR_3004_PLATFORM_LENGTH :{BLACK}Platform length
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Too close to another railway station
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Adjoins more than one existing station/loading area
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}Too many stations/loading areas in this town
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}Too many stations/loading areas
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Too many bus stops
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}Too many lorry stations
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Too close to another station/loading area
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Must demolish railway station first
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Too close to another airport
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Must demolish airport first
+
+STR_3030_RENAME_STATION_LOADING :Rename station/loading area
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Can't rename station...
+STR_3032_RATINGS :{BLACK}Ratings
+STR_3033_ACCEPTS :{BLACK}Accepts
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}Local rating of transport service:
+
+############ range for rating starts
+STR_3035_APPALLING :Appalling
+STR_3036_VERY_POOR :Very Poor
+STR_3037_POOR :Poor
+STR_3038_MEDIOCRE :Mediocre
+STR_3039_GOOD :Good
+STR_303A_VERY_GOOD :Very Good
+STR_303B_EXCELLENT :Excellent
+STR_303C_OUTSTANDING :Outstanding
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} no longer accepts {STRING}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} no longer accepts {STRING} or {STRING}
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} now accepts {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} now accepts {STRING} and {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Bus Station Orientation
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Lorry Station Orient.
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Must demolish bus station first
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Must demolish lorry station first
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Station{P "" s}
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- None -
+STR_304B_SITE_UNSUITABLE :{WHITE}...site unsuitable
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Too close to another dock
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Must demolish dock first
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Select railway station orientation
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Select number of platforms for railway station
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Select length of railway station
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Select bus station orientation
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Select lorry loading bay orientation
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Centre main view on station location
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Show station ratings
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Change name of station
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Show list of accepted cargo
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Station names - click on name to centre main view on station
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Select size/type of airport
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :Railway station
+STR_305F_AIRCRAFT_HANGAR :Aircraft hangar
+STR_3060_AIRPORT :Airport
+STR_3061_TRUCK_LOADING_AREA :Lorry loading area
+STR_3062_BUS_STATION :Bus station
+STR_3063_SHIP_DOCK :Ship dock
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Highlight coverage area of proposed site
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Don't highlight coverage area of proposed site
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Coverage area highlight
+STR_3068_DOCK :{WHITE}Dock
+STR_3069_BUOY :Buoy
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...buoy in the way
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...station too spread out
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...nonuniform stations disabled
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Hold down CTRL to select more than one item
+
+STR_UNDEFINED :(undefined string)
+STR_STAT_CLASS_DFLT :Default station
+STR_STAT_CLASS_WAYP :Waypoints
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Ship Depot Orientation
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...must be built on water
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Can't build ship depot here...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Select ship depot orientation
+STR_3804_WATER :Water
+STR_3805_COAST_OR_RIVERBANK :Coast or riverbank
+STR_3806_SHIP_DEPOT :Ship depot
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...Can't build on water
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Save Game
+STR_4001_LOAD_GAME :{WHITE}Load Game
+STR_4002_SAVE :{BLACK}Save
+STR_4003_DELETE :{BLACK}Delete
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} megabyte{P "" s} free
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Unable to read drive
+STR_4007_GAME_SAVE_FAILED :{WHITE}Game Save Failed
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Unable to delete file
+STR_4009_GAME_LOAD_FAILED :{WHITE}Game Load Failed
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}List of drives, directories and saved-game files
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Currently selected name for saved-game
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Delete the currently selected saved-game
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Save the current game, using the selected name
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Select New Game Type
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Select scenario (green), pre-set game (blue), or random new game
+STR_4010_GENERATE_RANDOM_NEW_GAME :Generate random new game
+STR_4011_LOAD_HEIGHTMAP :{WHITE}Load Heightmap
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} in the way
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :Coal Mine
+STR_4803_POWER_STATION :Power Station
+STR_4804_SAWMILL :Sawmill
+STR_4805_FOREST :Forest
+STR_4806_OIL_REFINERY :Oil Refinery
+STR_4807_OIL_RIG :Oil Rig
+STR_4808_FACTORY :Factory
+STR_4809_PRINTING_WORKS :Printing Works
+STR_480A_STEEL_MILL :Steel Mill
+STR_480B_FARM :Farm
+STR_480C_COPPER_ORE_MINE :Copper Ore Mine
+STR_480D_OIL_WELLS :Oil Wells
+STR_480E_BANK :Bank
+STR_480F_FOOD_PROCESSING_PLANT :Food Processing Plant
+STR_4810_PAPER_MILL :Paper Mill
+STR_4811_GOLD_MINE :Gold Mine
+STR_4812_BANK :Bank
+STR_4813_DIAMOND_MINE :Diamond Mine
+STR_4814_IRON_ORE_MINE :Iron Ore Mine
+STR_4815_FRUIT_PLANTATION :Fruit Plantation
+STR_4816_RUBBER_PLANTATION :Rubber Plantation
+STR_4817_WATER_SUPPLY :Water Supply
+STR_4818_WATER_TOWER :Water Tower
+STR_4819_FACTORY :Factory
+STR_481A_FARM :Farm
+STR_481B_LUMBER_MILL :Lumber Mill
+STR_481C_COTTON_CANDY_FOREST :Candyfloss Forest
+STR_481D_CANDY_FACTORY :Sweet Factory
+STR_481E_BATTERY_FARM :Battery Farm
+STR_481F_COLA_WELLS :Cola Wells
+STR_4820_TOY_SHOP :Toy Shop
+STR_4821_TOY_FACTORY :Toy Factory
+STR_4822_PLASTIC_FOUNTAINS :Plastic Fountains
+STR_4823_FIZZY_DRINK_FACTORY :Fizzy Drink Factory
+STR_4824_BUBBLE_GENERATOR :Bubble Generator
+STR_4825_TOFFEE_QUARRY :Toffee Quarry
+STR_4826_SUGAR_MINE :Sugar Mine
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Requires: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Requires: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Requires: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Production last month:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% transported)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centre the main view on industry location
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}New {STRING} under construction near {TOWN}!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}New {STRING} being planted near {TOWN}!
+STR_482F_COST :{BLACK}Cost: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Can't construct this industry type here...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...forest can only be planted above snow-line
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} announces imminent closure!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}Supply problems cause {INDUSTRY} to announce imminent closure!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}Lack of nearby trees causes {INDUSTRY} to announce imminent closure!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} increases production!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}New coal seam found at {INDUSTRY}!{}Production is expected to double!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}New oil reserves found at {INDUSTRY}!{}Production is expected to double!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}Improved farming methods at {INDUSTRY} are expected to double production!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}{INDUSTRY} production down by 50%
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}Insect infestation causes havoc at {INDUSTRY}!{}Production down by 50%
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...can only be positioned near edges of map
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}{STRING} production at {INDUSTRY} increases {COMMA}%!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}{STRING} production at {INDUSTRY} decreases {COMMA}%!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Train in tunnel
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Road vehicle in tunnel
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Another tunnel in the way
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Unable to excavate land for other end of tunnel
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Must demolish tunnel first
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Must demolish bridge first
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Cannot start and end in the same spot
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Level land or water required under bridge
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}Start and end must be in line
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Site unsuitable for tunnel entrance
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Suspension, Steel
+STR_500F_GIRDER_STEEL :Girder, Steel
+STR_5010_CANTILEVER_STEEL :Cantilever, Steel
+STR_5011_SUSPENSION_CONCRETE :Suspension, Concrete
+STR_5012_WOODEN :Wooden
+STR_5013_CONCRETE :Concrete
+STR_5014_TUBULAR_STEEL :Tubular, Steel
+STR_BRIDGE_TUBULAR_SILICON :Tubular, Silicon
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Can't build bridge here...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Can't build tunnel here...
+STR_5017_RAILROAD_TUNNEL :Railway tunnel
+STR_5018_ROAD_TUNNEL :Road tunnel
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Steel suspension rail bridge
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Steel girder rail bridge
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Steel cantilever rail bridge
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Reinforced concrete suspension rail bridge
+STR_501F_WOODEN_RAIL_BRIDGE :Wooden rail bridge
+STR_5020_CONCRETE_RAIL_BRIDGE :Concrete rail bridge
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Steel suspension road bridge
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Steel girder road bridge
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Steel cantilever road bridge
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Reinforced concrete suspension road bridge
+STR_5025_WOODEN_ROAD_BRIDGE :Wooden road bridge
+STR_5026_CONCRETE_ROAD_BRIDGE :Concrete road bridge
+STR_5027_TUBULAR_RAIL_BRIDGE :Tubular rail bridge
+STR_5028_TUBULAR_ROAD_BRIDGE :Tubular road bridge
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Object in the way
+STR_5801_TRANSMITTER :Transmitter
+STR_5802_LIGHTHOUSE :Lighthouse
+STR_5803_COMPANY_HEADQUARTERS :Company Headquarters
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...company headquarters in the way
+STR_5805_COMPANY_OWNED_LAND :Company-owned land
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Can't purchase this land area...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...you already own it!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Unnamed
+STR_SV_TRAIN_NAME :Train {COMMA}
+STR_SV_ROADVEH_NAME :Road Vehicle {COMMA}
+STR_SV_SHIP_NAME :Ship {COMMA}
+STR_SV_AIRCRAFT_NAME :Aircraft {COMMA}
+
+STR_SV_STNAME :{STRING1}
+STR_SV_STNAME_NORTH :{STRING1} North
+STR_SV_STNAME_SOUTH :{STRING1} South
+STR_SV_STNAME_EAST :{STRING1} East
+STR_SV_STNAME_WEST :{STRING1} West
+STR_SV_STNAME_CENTRAL :{STRING1} Central
+STR_SV_STNAME_TRANSFER :{STRING1} Transfer
+STR_SV_STNAME_HALT :{STRING1} Halt
+STR_SV_STNAME_VALLEY :{STRING1} Valley
+STR_SV_STNAME_HEIGHTS :{STRING1} Heights
+STR_SV_STNAME_WOODS :{STRING1} Woods
+STR_SV_STNAME_LAKESIDE :{STRING1} Lakeside
+STR_SV_STNAME_EXCHANGE :{STRING1} Exchange
+STR_SV_STNAME_AIRPORT :{STRING1} Airport
+STR_SV_STNAME_OILFIELD :{STRING1} Oilfield
+STR_SV_STNAME_MINES :{STRING1} Mines
+STR_SV_STNAME_DOCKS :{STRING1} Docks
+STR_SV_STNAME_BUOY_1 :{STRING1} Buoy 1
+STR_SV_STNAME_BUOY_2 :{STRING1} Buoy 2
+STR_SV_STNAME_BUOY_3 :{STRING1} Buoy 3
+STR_SV_STNAME_BUOY_4 :{STRING1} Buoy 4
+STR_SV_STNAME_BUOY_5 :{STRING1} Buoy 5
+STR_SV_STNAME_BUOY_6 :{STRING1} Buoy 6
+STR_SV_STNAME_BUOY_7 :{STRING1} Buoy 7
+STR_SV_STNAME_BUOY_8 :{STRING1} Buoy 8
+STR_SV_STNAME_BUOY_9 :{STRING1} Buoy 9
+STR_SV_STNAME_ANNEXE :{STRING1} Annexe
+STR_SV_STNAME_SIDINGS :{STRING1} Sidings
+STR_SV_STNAME_BRANCH :{STRING1} Branch
+STR_SV_STNAME_UPPER :Upper {STRING1}
+STR_SV_STNAME_LOWER :Lower {STRING1}
+STR_SV_STNAME_HELIPORT :{STRING1} Heliport
+STR_SV_STNAME_FOREST :{STRING1} Forest
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Difficulty Level
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Save
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Easy
+STR_6802_MEDIUM :{BLACK}Medium
+STR_6803_HARD :{BLACK}Hard
+STR_6804_CUSTOM :{BLACK}Custom
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maximum no. competitors: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Competitor start time: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}No. of towns: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}No. of industries: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Maximum initial loan: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Initial interest rate: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Vehicle running costs: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Construction speed of competitors: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Intelligence of competitors: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Vehicle breakdowns: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Subsidy multiplier: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Cost of construction: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Terrain type: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Quantity of sea/lakes: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Economy: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Train reversing: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Disasters: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}City council's attitude towards area restructuring: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :None
+STR_6816_LOW :Low
+STR_6817_NORMAL :Normal
+STR_6818_HIGH :High
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Very Slow
+STR_681C_SLOW :Slow
+STR_681D_MEDIUM :Medium
+STR_681E_FAST :Fast
+STR_681F_VERY_FAST :Very Fast
+STR_VERY_LOW :Very Low
+STR_6820_LOW :Low
+STR_6821_MEDIUM :Medium
+STR_6822_HIGH :High
+STR_6823_NONE :None
+STR_6824_REDUCED :Reduced
+STR_6825_NORMAL :Normal
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Very Flat
+STR_682B_FLAT :Flat
+STR_682C_HILLY :Hilly
+STR_682D_MOUNTAINOUS :Mountainous
+STR_682E_STEADY :Steady
+STR_682F_FLUCTUATING :Fluctuating
+STR_6830_IMMEDIATE :Immediate
+STR_6831_3_MONTHS_AFTER_PLAYER :3 months after player
+STR_6832_6_MONTHS_AFTER_PLAYER :6 months after player
+STR_6833_9_MONTHS_AFTER_PLAYER :9 months after player
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :At end of line, and at stations
+STR_6835_AT_END_OF_LINE_ONLY :At end of line only
+STR_6836_OFF :Off
+STR_6837_ON :On
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Show hi-score chart
+STR_6839_PERMISSIVE :Permissive
+STR_683A_TOLERANT :Tolerant
+STR_683B_HOSTILE :Hostile
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Player {COMMA})
+STR_7004_NEW_FACE :{BLACK}New Face
+STR_7005_COLOR_SCHEME :{BLACK}Colour Scheme
+STR_7006_COLOR_SCHEME :{GOLD}Colour Scheme:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}New Colour Scheme
+STR_7008_COMPANY_NAME :{BLACK}Company Name
+STR_7009_PRESIDENT_NAME :{BLACK}Manager Name
+STR_700A_COMPANY_NAME :Company Name
+STR_700B_PRESIDENT_S_NAME :Manager's Name
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Can't change company name...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Can't change manager's name...
+STR_700E_FINANCES :{WHITE}{COMPANY} Finances {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Expenditure/Income
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Construction
+STR_7012_NEW_VEHICLES :{GOLD}New Vehicles
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Train Running Costs
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Road Veh. Running Costs
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Aircraft Running Costs
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Ship Running Costs
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Property Maintenance
+STR_7018_TRAIN_INCOME :{GOLD}Train Income
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Road Vehicle Income
+STR_701A_AIRCRAFT_INCOME :{GOLD}Aircraft Income
+STR_701B_SHIP_INCOME :{GOLD}Ship Income
+STR_701C_LOAN_INTEREST :{GOLD}Loan Interest
+STR_701D_OTHER :{GOLD}Other
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Total:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Income Graph
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Operating Profit Graph
+STR_7026_BANK_BALANCE :{WHITE}Bank Balance
+STR_7027_LOAN :{WHITE}Loan
+STR_MAX_LOAN :{WHITE}Max Loan: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}Borrow {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Repay {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...maximum permitted loan size is {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Can't borrow any more money...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...no loan to repay
+STR_702E_REQUIRED :{WHITE}...{CURRENCY} required
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Can't repay loan...
+STR_INSUFFICIENT_FUNDS :{WHITE}Can't give away money that is loaned from the bank...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Select new face for manager
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Change the company vehicle livery
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Change the manager's name
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Change the company name
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Click on desired colour scheme
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Increase size of loan
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Repay part of loan
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(Manager)
+STR_7038_INAUGURATED :{GOLD}Inaugurated: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Vehicles:
+STR_TRAINS :{WHITE}{COMMA} train{P "" s}
+STR_ROAD_VEHICLES :{WHITE}{COMMA} road vehicle{P "" s}
+STR_AIRCRAFT :{WHITE}{COMMA} aircraft
+STR_SHIPS :{WHITE}{COMMA} ship{P "" s}
+STR_7042_NONE :{WHITE}None
+STR_7043_FACE_SELECTION :{WHITE}Face Selection
+STR_7044_MALE :{BLACK}Male
+STR_7045_FEMALE :{BLACK}Female
+STR_7046_NEW_FACE :{BLACK}New Face
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Cancel new face selection
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Accept new face selection
+STR_7049_SELECT_MALE_FACES :{BLACK}Select male faces
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Select female faces
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Generate random new face
+STR_704C_KEY :{BLACK}Key
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Show key to graphs
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Key to company graphs
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Click here to toggle company's entry on graph on/off
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Units of cargo delivered
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Company performance ratings (maximum rating=1000)
+STR_7052_COMPANY_VALUES :{WHITE}Company values
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Company League Table
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}Transport company in trouble!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} will be sold off or declared bankrupt unless performance increases soon!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(Manager)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Transport company merger!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} has been sold to {COMPANY} for {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}We are looking for a transport company to take-over our company.{}{}Do you want to purchase {COMPANY} for {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Bankrupt!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} has been closed down by creditors and all assets sold off!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}New transport company launched!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} starts construction near {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Can't buy company...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Cargo Payment Rates
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Days in transit
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Payment for delivering 10 units (or 10,000 litres) of cargo a distance of 20 squares
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Toggle graph for cargo type on/off
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Engineer
+STR_7067_TRAFFIC_MANAGER :Traffic Manager
+STR_7068_TRANSPORT_COORDINATOR :Transport Coordinator
+STR_7069_ROUTE_SUPERVISOR :Route Supervisor
+STR_706A_DIRECTOR :Director
+STR_706B_CHIEF_EXECUTIVE :Chief Executive
+STR_706C_CHAIRMAN :Chairman
+STR_706D_PRESIDENT :President
+STR_706E_TYCOON :Tycoon
+STR_706F_BUILD_HQ :{BLACK}Build HQ
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Build company headquarters / view company headquarters
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Rebuild company headquarters elsewhere for 1% cost of company value
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Can't build company headquarters...
+STR_7072_VIEW_HQ :{BLACK}View HQ
+STR_RELOCATE_HQ :{BLACK}Relocate HQ
+STR_COMPANY_PASSWORD :{BLACK}Password
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Password-protect your company to prevent unauthorised users from joining.
+STR_SET_COMPANY_PASSWORD :Set company password
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}World Recession!{}{}Financial experts fear worst as economy slumps!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Recession Over!{}{}Upturn in trade gives confidence to industries as economy strengthens!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Toggle large/small window size
+STR_7076_COMPANY_VALUE :{GOLD}Company value: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Buy 25% share in company
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Sell 25% share in company
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Buy 25% share in this company
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Sell 25% share in this company
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Can't buy 25% share in this company...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}Can't sell 25% share in this company...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% owned by {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% owned by {COMPANY}{} {COMMA}% owned by {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} has been taken over by {COMPANY}!
+STR_7080_PROTECTED :{WHITE}This company is not old enough to trade shares yet...
+
+STR_LIVERY_DEFAULT :Standard Livery
+STR_LIVERY_STEAM :Steam Engine
+STR_LIVERY_DIESEL :Diesel Engine
+STR_LIVERY_ELECTRIC :Electric Engine
+STR_LIVERY_MONORAIL :Monorail Engine
+STR_LIVERY_MAGLEV :Maglev Engine
+STR_LIVERY_DMU :DMU
+STR_LIVERY_EMU :EMU
+STR_LIVERY_PASSENGER_WAGON_STEAM :Passenger Coach (Steam)
+STR_LIVERY_PASSENGER_WAGON_DIESEL :Passenger Coach (Diesel)
+STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Passenger Coach (Electric)
+STR_LIVERY_FREIGHT_WAGON :Freight Wagon
+STR_LIVERY_BUS :Bus
+STR_LIVERY_TRUCK :Lorry
+STR_LIVERY_PASSENGER_SHIP :Passenger Ferry
+STR_LIVERY_FREIGHT_SHIP :Freight Ship
+STR_LIVERY_HELICOPTER :Helicopter
+STR_LIVERY_SMALL_PLANE :Small Aeroplane
+STR_LIVERY_LARGE_PLANE :Large Aeroplane
+
+STR_LIVERY_GENERAL_TIP :{BLACK}Show general colour schemes
+STR_LIVERY_TRAIN_TIP :{BLACK}Show train colour schemes
+STR_LIVERY_ROADVEH_TIP :{BLACK}Show road vehicle colour schemes
+STR_LIVERY_SHIP_TIP :{BLACK}Show ship colour schemes
+STR_LIVERY_AIRCRAFT_TIP :{BLACK}Show aircraft colour schemes
+STR_LIVERY_PRIMARY_TIP :{BLACK}Choose the primary colour for the selected scheme
+STR_LIVERY_SECONDARY_TIP :{BLACK}Choose the secondary colour for the selected scheme
+STR_LIVERY_PANEL_TIP :{BLACK}Select a colour scheme to change, or multiple schemes with CTRL+click. Click on the box to toggle use of the scheme
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (Steam)
+STR_8001_MJS_250_DIESEL :MJS 250 (Diesel)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut Diesel
+STR_8006_POWERNAUT_DIESEL :Powernaut Diesel
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (Steam)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (Steam)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (Steam)
+STR_800A_SH_8P_STEAM :SH '8P' (Steam)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (Diesel)
+STR_800C_DASH_DIESEL :'Dash' (Diesel)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (Diesel)
+STR_800E_UU_37_DIESEL :UU '37' (Diesel)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (Diesel)
+STR_8010_CS_4000_DIESEL :CS 4000 (Diesel)
+STR_8011_CS_2400_DIESEL :CS 2400 (Diesel)
+STR_8012_CENTENNIAL_DIESEL :Centennial (Diesel)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (Diesel)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (Diesel)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (Diesel)
+STR_8016_SH_125_DIESEL :SH '125' (Diesel)
+STR_8017_SH_30_ELECTRIC :SH '30' (Electric)
+STR_8018_SH_40_ELECTRIC :SH '40' (Electric)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (Electric)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (Electric)
+STR_801B_PASSENGER_CAR :Passenger Carriage
+STR_801C_MAIL_VAN :Mail Van
+STR_801D_COAL_CAR :Coal Truck
+STR_801E_OIL_TANKER :Oil Tanker
+STR_801F_LIVESTOCK_VAN :Livestock Van
+STR_8020_GOODS_VAN :Goods Van
+STR_8021_GRAIN_HOPPER :Grain Hopper
+STR_8022_WOOD_TRUCK :Wood Truck
+STR_8023_IRON_ORE_HOPPER :Iron Ore Hopper
+STR_8024_STEEL_TRUCK :Steel Truck
+STR_8025_ARMORED_VAN :Armoured Van
+STR_8026_FOOD_VAN :Food Van
+STR_8027_PAPER_TRUCK :Paper Truck
+STR_8028_COPPER_ORE_HOPPER :Copper Ore Hopper
+STR_8029_WATER_TANKER :Water Tanker
+STR_802A_FRUIT_TRUCK :Fruit Truck
+STR_802B_RUBBER_TRUCK :Rubber Truck
+STR_802C_SUGAR_TRUCK :Sugar Truck
+STR_802D_COTTON_CANDY_HOPPER :Candyfloss Hopper
+STR_802E_TOFFEE_HOPPER :Toffee Hopper
+STR_802F_BUBBLE_VAN :Bubble Van
+STR_8030_COLA_TANKER :Cola Tanker
+STR_8031_CANDY_VAN :Sweet Van
+STR_8032_TOY_VAN :Toy Van
+STR_8033_BATTERY_TRUCK :Battery Truck
+STR_8034_FIZZY_DRINK_TRUCK :Fizzy Drink Truck
+STR_8035_PLASTIC_TRUCK :Plastic Truck
+STR_8036_X2001_ELECTRIC :'X2001' (Electric)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Electric)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :Passenger Carriage
+STR_803A_MAIL_VAN :Mail Van
+STR_803B_COAL_CAR :Coal Truck
+STR_803C_OIL_TANKER :Oil Tanker
+STR_803D_LIVESTOCK_VAN :Livestock Van
+STR_803E_GOODS_VAN :Goods Van
+STR_803F_GRAIN_HOPPER :Grain Hopper
+STR_8040_WOOD_TRUCK :Wood Truck
+STR_8041_IRON_ORE_HOPPER :Iron Ore Hopper
+STR_8042_STEEL_TRUCK :Steel Truck
+STR_8043_ARMORED_VAN :Armoured Van
+STR_8044_FOOD_VAN :Food Van
+STR_8045_PAPER_TRUCK :Paper Truck
+STR_8046_COPPER_ORE_HOPPER :Copper Ore Hopper
+STR_8047_WATER_TANKER :Water Tanker
+STR_8048_FRUIT_TRUCK :Fruit Truck
+STR_8049_RUBBER_TRUCK :Rubber Truck
+STR_804A_SUGAR_TRUCK :Sugar Truck
+STR_804B_COTTON_CANDY_HOPPER :Candyfloss Hopper
+STR_804C_TOFFEE_HOPPER :Toffee Hopper
+STR_804D_BUBBLE_VAN :Bubble Van
+STR_804E_COLA_TANKER :Cola Tanker
+STR_804F_CANDY_VAN :Sweet Van
+STR_8050_TOY_VAN :Toy Van
+STR_8051_BATTERY_TRUCK :Battery Truck
+STR_8052_FIZZY_DRINK_TRUCK :Fizzy Drink Truck
+STR_8053_PLASTIC_TRUCK :Plastic Truck
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (Electric)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (Electric)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (Electric)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (Electric)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :Passenger Carriage
+STR_805A_MAIL_VAN :Mail Van
+STR_805B_COAL_CAR :Coal Truck
+STR_805C_OIL_TANKER :Oil Tanker
+STR_805D_LIVESTOCK_VAN :Livestock Van
+STR_805E_GOODS_VAN :Goods Van
+STR_805F_GRAIN_HOPPER :Grain Hopper
+STR_8060_WOOD_TRUCK :Wood Truck
+STR_8061_IRON_ORE_HOPPER :Iron Ore Hopper
+STR_8062_STEEL_TRUCK :Steel Truck
+STR_8063_ARMORED_VAN :Armoured Van
+STR_8064_FOOD_VAN :Food Van
+STR_8065_PAPER_TRUCK :Paper Truck
+STR_8066_COPPER_ORE_HOPPER :Copper Ore Hopper
+STR_8067_WATER_TANKER :Water Tanker
+STR_8068_FRUIT_TRUCK :Fruit Truck
+STR_8069_RUBBER_TRUCK :Rubber Truck
+STR_806A_SUGAR_TRUCK :Sugar Truck
+STR_806B_COTTON_CANDY_HOPPER :Candyfloss Hopper
+STR_806C_TOFFEE_HOPPER :Toffee Hopper
+STR_806D_BUBBLE_VAN :Bubble Van
+STR_806E_COLA_TANKER :Cola Tanker
+STR_806F_CANDY_VAN :Sweet Van
+STR_8070_TOY_VAN :Toy Van
+STR_8071_BATTERY_TRUCK :Battery Truck
+STR_8072_FIZZY_DRINK_TRUCK :Fizzy Drink Truck
+STR_8073_PLASTIC_TRUCK :Plastic Truck
+STR_8074_MPS_REGAL_BUS :MPS Regal Bus
+STR_8075_HEREFORD_LEOPARD_BUS :Hereford Leopard Bus
+STR_8076_FOSTER_BUS :Foster Bus
+STR_8077_FOSTER_MKII_SUPERBUS :Foster MkII Superbus
+STR_8078_PLODDYPHUT_MKI_BUS :Ploddyphut MkI Bus
+STR_8079_PLODDYPHUT_MKII_BUS :Ploddyphut MkII Bus
+STR_807A_PLODDYPHUT_MKIII_BUS :Ploddyphut MkIII Bus
+STR_807B_BALOGH_COAL_TRUCK :Balogh Coal Truck
+STR_807C_UHL_COAL_TRUCK :Uhl Coal Truck
+STR_807D_DW_COAL_TRUCK :DW Coal Truck
+STR_807E_MPS_MAIL_TRUCK :MPS Mail Truck
+STR_807F_REYNARD_MAIL_TRUCK :Reynard Mail Truck
+STR_8080_PERRY_MAIL_TRUCK :Perry Mail Truck
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :MightyMover Mail Truck
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Powernaught Mail Truck
+STR_8083_WIZZOWOW_MAIL_TRUCK :Wizzowow Mail Truck
+STR_8084_WITCOMBE_OIL_TANKER :Witcombe Oil Tanker
+STR_8085_FOSTER_OIL_TANKER :Foster Oil Tanker
+STR_8086_PERRY_OIL_TANKER :Perry Oil Tanker
+STR_8087_TALBOTT_LIVESTOCK_VAN :Talbott Livestock Van
+STR_8088_UHL_LIVESTOCK_VAN :Uhl Livestock Van
+STR_8089_FOSTER_LIVESTOCK_VAN :Foster Livestock Van
+STR_808A_BALOGH_GOODS_TRUCK :Balogh Goods Truck
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Craighead Goods Truck
+STR_808C_GOSS_GOODS_TRUCK :Goss Goods Truck
+STR_808D_HEREFORD_GRAIN_TRUCK :Hereford Grain Truck
+STR_808E_THOMAS_GRAIN_TRUCK :Thomas Grain Truck
+STR_808F_GOSS_GRAIN_TRUCK :Goss Grain Truck
+STR_8090_WITCOMBE_WOOD_TRUCK :Witcombe Wood Truck
+STR_8091_FOSTER_WOOD_TRUCK :Foster Wood Truck
+STR_8092_MORELAND_WOOD_TRUCK :Moreland Wood Truck
+STR_8093_MPS_IRON_ORE_TRUCK :MPS Iron Ore Truck
+STR_8094_UHL_IRON_ORE_TRUCK :Uhl Iron Ore Truck
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Chippy Iron Ore Truck
+STR_8096_BALOGH_STEEL_TRUCK :Balogh Steel Truck
+STR_8097_UHL_STEEL_TRUCK :Uhl Steel Truck
+STR_8098_KELLING_STEEL_TRUCK :Kelling Steel Truck
+STR_8099_BALOGH_ARMORED_TRUCK :Balogh Armoured Truck
+STR_809A_UHL_ARMORED_TRUCK :Uhl Armoured Truck
+STR_809B_FOSTER_ARMORED_TRUCK :Foster Armoured Truck
+STR_809C_FOSTER_FOOD_VAN :Foster Food Van
+STR_809D_PERRY_FOOD_VAN :Perry Food Van
+STR_809E_CHIPPY_FOOD_VAN :Chippy Food Van
+STR_809F_UHL_PAPER_TRUCK :Uhl Paper Truck
+STR_80A0_BALOGH_PAPER_TRUCK :Balogh Paper Truck
+STR_80A1_MPS_PAPER_TRUCK :MPS Paper Truck
+STR_80A2_MPS_COPPER_ORE_TRUCK :MPS Copper Ore Truck
+STR_80A3_UHL_COPPER_ORE_TRUCK :Uhl Copper Ore Truck
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Goss Copper Ore Truck
+STR_80A5_UHL_WATER_TANKER :Uhl Water Tanker
+STR_80A6_BALOGH_WATER_TANKER :Balogh Water Tanker
+STR_80A7_MPS_WATER_TANKER :MPS Water Tanker
+STR_80A8_BALOGH_FRUIT_TRUCK :Balogh Fruit Truck
+STR_80A9_UHL_FRUIT_TRUCK :Uhl Fruit Truck
+STR_80AA_KELLING_FRUIT_TRUCK :Kelling Fruit Truck
+STR_80AB_BALOGH_RUBBER_TRUCK :Balogh Rubber Truck
+STR_80AC_UHL_RUBBER_TRUCK :Uhl Rubber Truck
+STR_80AD_RMT_RUBBER_TRUCK :RMT Rubber Truck
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :MightyMover Sugar Truck
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Powernaught Sugar Truck
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Wizzowow Sugar Truck
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :MightyMover Cola Truck
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Powernaught Cola Truck
+STR_80B3_WIZZOWOW_COLA_TRUCK :Wizzowow Cola Truck
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :MightyMover Candyfloss Truck
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Powernaught Candyfloss Truck
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Wizzowow Candyfloss Truck
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :MightyMover Toffee Truck
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Powernaught Toffee Truck
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Wizzowow Toffee Truck
+STR_80BA_MIGHTYMOVER_TOY_VAN :MightyMover Toy Van
+STR_80BB_POWERNAUGHT_TOY_VAN :Powernaught Toy Van
+STR_80BC_WIZZOWOW_TOY_VAN :Wizzowow Toy Van
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :MightyMover Sweet Truck
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Powernaught Sweet Truck
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Wizzowow Sweet Truck
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :MightyMover Battery Truck
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Powernaught Battery Truck
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Wizzowow Battery Truck
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :MightyMover Fizzy Drink Truck
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Powernaught Fizzy Drink Truck
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Wizzowow Fizzy Drink Truck
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :MightyMover Plastic Truck
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Powernaught Plastic Truck
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Wizzowow Plastic Truck
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :MightyMover Bubble Truck
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Powernaught Bubble Truck
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Wizzowow Bubble Truck
+STR_80CC_MPS_OIL_TANKER :MPS Oil Tanker
+STR_80CD_CS_INC_OIL_TANKER :CS-Inc. Oil Tanker
+STR_80CE_MPS_PASSENGER_FERRY :MPS Passenger Ferry
+STR_80CF_FFP_PASSENGER_FERRY :FFP Passenger Ferry
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Bakewell 300 Hovercraft
+STR_80D1_CHUGGER_CHUG_PASSENGER :Chugger-Chug Passenger Ferry
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Shivershake Passenger Ferry
+STR_80D3_YATE_CARGO_SHIP :Yate Cargo ship
+STR_80D4_BAKEWELL_CARGO_SHIP :Bakewell Cargo ship
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Mightymover Cargo ship
+STR_80D6_POWERNAUT_CARGO_SHIP :Powernaut Cargo ship
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Tricario Helicopter
+STR_80FE_GURU_X2_HELICOPTER :Guru X2 Helicopter
+STR_80FF_POWERNAUT_HELICOPTER :Powernaut Helicopter
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Message from vehicle manufacturer
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}We have just designed a new {STRING} - would you be interested in a year's exclusive use of this vehicle, so we can see how it performs before making it universally available?
+STR_8102_RAILROAD_LOCOMOTIVE :railway locomotive
+STR_8103_ROAD_VEHICLE :road vehicle
+STR_8104_AIRCRAFT :aircraft
+STR_8105_SHIP :ship
+STR_8106_MONORAIL_LOCOMOTIVE :monorail locomotive
+STR_8107_MAGLEV_LOCOMOTIVE :maglev locomotive
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}{TOWN} Train Depot
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Citizens celebrate . . .{}First train arrives at {STATION}!
+STR_8802_DETAILS :{WHITE}{STRING1} (Details)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Train in the way
+STR_8804 :{SETX 10}{COMMA}: {STRING1} {STRING1}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING1} {STRING1}
+STR_8806_GO_TO :Go to {STATION}
+STR_8807_GO_TO_TRANSFER :Go to {STATION} (Transfer and take cargo)
+STR_8808_GO_TO_UNLOAD :Go to {STATION} (Unload)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Go to {STATION} (Transfer and leave empty)
+STR_880A_GO_TO_LOAD :Go to {STATION} (Load)
+STR_880B_GO_TO_TRANSFER_LOAD :Go to {STATION} (Transfer and wait for full load)
+STR_880C_GO_NON_STOP_TO :Go non-stop to {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Go non-stop to {STATION} (Transfer and take cargo)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Go non-stop to {STATION} (Unload)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Go non-stop to {STATION} (Transfer and leave empty)
+STR_8810_GO_NON_STOP_TO_LOAD :Go non-stop to {STATION} (Load)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Go non-stop to {STATION} (Transfer and wait for full load)
+STR_GO_TO_TRAIN_DEPOT :Go to {TOWN} Train Depot
+STR_SERVICE_AT_TRAIN_DEPOT :Service at {TOWN} Train Depot
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Go non-stop to {TOWN} Train Depot
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Service non-stop at {TOWN} Train Depot
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}Heading for {TOWN} Train Depot
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}Heading for {TOWN} Train Depot, {VELOCITY}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE :{LTBLUE}Service at {TOWN} Train Depot
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE_VEL :{LTBLUE}Service at {TOWN} Train Depot, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (Invalid Order)
+
+STR_UNKNOWN_DESTINATION :unknown destination
+STR_8812_EMPTY :{LTBLUE}Empty
+STR_8813_FROM :{LTBLUE}{CARGO} from {STATION}
+STR_FROM_MULT :{LTBLUE}{CARGO} from {STATION} (x{NUM})
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}Train {COMMA} is waiting in depot
+STR_8815_NEW_VEHICLES :{BLACK}New Vehicles
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Train too long
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Trains can only be altered when stopped inside a depot
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} Train{P "" s}
+
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}New Rail Vehicles
+STR_NEW_ELRAIL_VEHICLES :{WHITE}New Electric Rail Vehicles
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}New Monorail Vehicles
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}New Maglev Vehicles
+STR_ALL_AVAIL_RAIL_VEHICLES :{WHITE}Rail Vehicles
+
+STR_881F_BUILD_VEHICLE :{BLACK}Build Vehicle
+STR_CLONE_ROAD_VEHICLE :{BLACK}Clone Vehicle
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}This will build a copy of the road vehicle. Control-click will share the orders
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}This will build a copy of a road vehicle. Click this button and then on a road vehicle inside or outside the depot. Control-click will share the orders
+STR_CLONE_TRAIN :{BLACK}Clone Train
+STR_CLONE_TRAIN_INFO :{BLACK}This will build a copy of the train including all cars. Control-click will share the orders
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}This will build a copy of a train including all cars. Click this button and then on a train inside or outside the depot. Control-click will share the orders
+STR_8820_RENAME :{BLACK}Rename
+STR_8823_SKIP :{BLACK}Skip
+STR_8824_DELETE :{BLACK}Delete
+STR_8825_NON_STOP :{BLACK}Non-Stop
+STR_8826_GO_TO :{BLACK}Go To
+STR_8827_FULL_LOAD :{BLACK}Full Load
+STR_8828_UNLOAD :{BLACK}Unload
+STR_REFIT :{BLACK}Refit
+STR_REFIT_TIP :{BLACK}Select what cargo type to refit to in this order. Control click to remove refit instruction
+STR_REFIT_ORDER :(Refit to {STRING})
+STR_8829_ORDERS :{WHITE}{VEHICLE} (Orders)
+STR_882A_END_OF_ORDERS :{SETX 10}- - End of Orders - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}Service
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Can't build railway vehicle...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Built: {LTBLUE}{NUM}{BLACK} Value: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Value: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}Loading / Unloading
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}Train must be stopped inside a depot
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Can't send train to depot...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}No more space for orders
+STR_8832_TOO_MANY_ORDERS :{WHITE}Too many orders
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Can't insert new order...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Can't delete this order...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Can't modify this order...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Can't move vehicle...
+STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}The rear engine will always follow its front counterpart
+STR_8838_N_A :N/A{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Can't sell railway vehicle...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Unable to find route to local depot
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Can't stop/start train...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Servicing interval: {LTBLUE}{COMMA}days{BLACK} Last service: {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Servicing interval: {LTBLUE}{COMMA}%{BLACK} Last service: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Trains - click on train for information
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Build new trains (requires train depot)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Trains - click on train for info., drag vehicle to add/remove from train
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Build new train vehicle
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Drag train vehicle to here to sell it
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centre main view on train depot location
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Train vehicle selection list - click on vehicle for information
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Build the highlighted train vehicle
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Rename train vehicle type
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Current train action - click here to stop/start train
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Show train's orders
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centre main view on train's location
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Send train to depot. CTRL+click will only service
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Force train to proceed without waiting for signal to clear it
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Reverse direction of train
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Show train details
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Increase servicing interval
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Decrease servicing interval
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Show details of cargo carried
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Show details of train vehicles
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Show capacities of each vehicle
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Show total capacity of train, split by cargo type
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Orders list - click on an order to highlight it. CTRL + click scrolls to the station
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}Skip the current order, and start the next
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Delete the highlighted order
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Make the highlighted order non-stop
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Insert a new order before the highlighted order, or add to end of list
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Make the highlighted order force the vehicle to wait for a full load
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Make the highlighted order force the vehicle to unload
+STR_SERVICE_HINT :{BLACK}Skip this order unless a service is needed
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}New {STRING} now available!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Cost: {CURRENCY} Weight: {WEIGHT_S}{}Speed: {VELOCITY} Power: {POWER}{}Running Cost: {CURRENCY}/yr{}Capacity: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}Broken down
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}Age: {LTBLUE}{STRING2}{BLACK} Running Cost: {LTBLUE}{CURRENCY}/yr
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Weight: {LTBLUE}{WEIGHT_S} {BLACK}Power: {LTBLUE}{POWER}{BLACK} Max. speed: {LTBLUE}{VELOCITY}
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Weight: {LTBLUE}{WEIGHT_S} {BLACK}Power: {LTBLUE}{POWER}{BLACK} Max. speed: {LTBLUE}{VELOCITY} {BLACK}Max. T.E.: {LTBLUE}{FORCE}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit this year: {LTBLUE}{CURRENCY} (last year: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}Reliability: {LTBLUE}{COMMA}% {BLACK}Breakdowns since last service: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Stopped
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Can't make train pass signal at danger...
+STR_8863_CRASHED :{RED}Crashed!
+
+STR_8865_NAME_TRAIN :{WHITE}Name train
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}Can't name train...
+STR_8867_NAME_TRAIN :{BLACK}Name train
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Train Crash!{}{COMMA} die in fireball after collision
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Can't reverse direction of train...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Rename train vehicle type
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Can't rename train vehicle type...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Make the highlighted order force the vehicle to dump cargo
+STR_886F_TRANSFER :{BLACK}Transfer
+
+STR_TRAIN_STOPPING :{RED}Stopping
+STR_TRAIN_STOPPING_VEL :{RED}Stopping, {VELOCITY}
+STR_INCOMPATIBLE_RAIL_TYPES :Incompatible rail types
+STR_TRAIN_NO_POWER :{RED}No power
+STR_TRAIN_START_NO_CATENARY :This track lacks catenary, so the train can't start
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Road vehicle in the way
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} Road Vehicle{P "" s}
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}{TOWN} Road Vehicle Depot
+STR_9004_NEW_VEHICLES :{BLACK}New Vehicles
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}New Road Vehicles
+STR_9007_BUILD_VEHICLE :{BLACK}Build Vehicle
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Can't build road vehicle...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (Details)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}Age: {LTBLUE}{STRING2}{BLACK} Running Cost: {LTBLUE}{CURRENCY}/yr
+STR_900E_MAX_SPEED :{BLACK}Max. speed: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit this year: {LTBLUE}{CURRENCY} (last year: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}Reliability: {LTBLUE}{COMMA}% {BLACK}Breakdowns since last service: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Built: {LTBLUE}{NUM}{BLACK} Value: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Capacity: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}...must be stopped inside a road vehicle depot
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Can't sell road vehicle...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Can't stop/start road vehicle...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}Road vehicle {COMMA} is waiting in depot
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}Heading for {TOWN} Road Depot
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}Heading for {TOWN} Road Depot, {VELOCITY}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE :{LTBLUE}Service at {TOWN} Road Depot
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE_VEL :{LTBLUE}Service at {TOWN} Road Depot, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Can't send vehicle to depot...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Unable to find local depot
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Road vehicles - click on vehicle for information
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Build new road vehicles (requires road vehicle depot)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Current vehicle action - click here to stop/start vehicle
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Show vehicle's orders
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Centre main view on vehicle's location
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Send vehicle to depot. CTRL+click will only service
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Force vehicle to turn around
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Show road vehicle details
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Vehicles - click on vehicle for information
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Build new road vehicle
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Drag road vehicle to here to sell it
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Centre main view on road vehicle depot location
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Road vehicle selection list - click on vehicle for information
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Build the highlighted road vehicle
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}New road vehicle now available!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Cost: {CURRENCY}{}Speed: {VELOCITY}{}Running Cost: {CURRENCY}/yr{}Capacity: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Name road vehicle
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Can't name road vehicle...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Name road vehicle
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Citizens celebrate . . .{}First bus arrives at {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Citizens celebrate . . .{}First truck arrives at {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}Road Vehicle Crash!{}Driver dies in fireball after collision with train
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}Road Vehicle Crash!{}{COMMA} die in fireball after collision with train
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Can't make vehicle turn around...
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}Can't turn vehicles consisting of multiple units
+STR_9034_RENAME :{BLACK}Rename
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Rename road vehicle type
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Rename road vehicle type
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Can't rename road vehicle type...
+STR_9038_GO_TO_ROADVEH_DEPOT :Go to {TOWN} Road Vehicle Depot
+STR_SERVICE_AT_ROADVEH_DEPOT :Service at {TOWN} Road Vehicle Depot
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Refit road vehicle to carry a different cargo type
+STR_REFIT_ROAD_VEHICLE :{BLACK}Refit road vehicle
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Refit road vehicle to carry highlighted cargo type
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Can't refit road vehicle...
+STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Select type of cargo for road vehicle to carry
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Dock construction
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Dock construction
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Can't build dock here...
+STR_9803_SHIP_DEPOT :{WHITE}{TOWN} Ship Depot
+STR_9804_NEW_SHIPS :{BLACK}New Ships
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} Ship{P "" s}
+STR_9808_NEW_SHIPS :{WHITE}New Ships
+STR_9809_BUILD_SHIP :{BLACK}Build Ship
+STR_CLONE_SHIP :{BLACK}Clone Ship
+STR_CLONE_SHIP_INFO :{BLACK}This will build a copy of the ship. Control-click will share the orders
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}This will build a copy of a ship. Click this button and then on a ship inside or outside the depot. Control-click will share the orders
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}Ship must be stopped in depot
+STR_980C_CAN_T_SELL_SHIP :{WHITE}Can't sell ship...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Can't build ship...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Ship in the way
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Details)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}Age: {LTBLUE}{STRING2}{BLACK} Running Cost: {LTBLUE}{CURRENCY}/yr
+STR_9813_MAX_SPEED :{BLACK}Max. speed: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit this year: {LTBLUE}{CURRENCY} (last year: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}Reliability: {LTBLUE}{COMMA}% {BLACK}Breakdowns since last service: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Built: {LTBLUE}{NUM}{BLACK} Value: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}Capacity: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}Can't stop/start ship...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Can't send ship to depot...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Unable to find local depot
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}Heading for {TOWN} Ship Depot
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}Heading for {TOWN} Ship Depot, {VELOCITY}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE :{LTBLUE}Service at {TOWN} Ship Depot
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE_VEL :{LTBLUE}Service at {TOWN} Ship Depot, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}Ship {COMMA} is waiting in depot
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Build ship dock
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Build ship depot (for building and servicing ships)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Ships - click on ship for information
+STR_9820_BUILD_NEW_SHIP :{BLACK}Build new ship
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Drag ship to here to sell it
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centre main view on ship depot location
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Ships - click on ship for information
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Build new ships (requires ship depot)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}Ship selection list - click on ship for information
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Build the highlighted ship
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Current ship action - click here to stop/start ship
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Show ship's orders
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centre main view on ship's location
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Send ship to depot. CTRL+click will only service
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Show ship details
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}New ship now available!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Cost: {CURRENCY} Max. Speed: {VELOCITY}{}Capacity: {CARGO}{}Running Cost: {CURRENCY}/yr
+STR_982F_NAME_SHIP :{BLACK}Name ship
+
+STR_9831_NAME_SHIP :{WHITE}Name ship
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Can't name ship...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Citizens celebrate . . .{}First ship arrives at {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Place a buoy which can be used as a waypoint
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Can't place buoy here...
+STR_9836_RENAME :{BLACK}Rename
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Rename ship type
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Rename ship type
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Can't rename ship type...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Refit cargo ship to carry a different cargo type
+STR_983B_REFIT :{WHITE}{VEHICLE} (Refit)
+STR_983C_REFIT_SHIP :{BLACK}Refit ship
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Select type of cargo for ship to carry
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Refit ship to carry highlighted cargo type
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Select cargo type to carry:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}New capacity: {GOLD}{CARGO}{}{BLACK}Cost of refit: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Can't refit ship...
+STR_9842_REFITTABLE :(refittable)
+STR_GO_TO_SHIP_DEPOT :Go to {TOWN} Ship Depot
+SERVICE_AT_SHIP_DEPOT :Service at {TOWN} Ship Depot
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Airports
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Can't build airport here...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} Aircraft Hangar
+STR_A003_NEW_AIRCRAFT :{BLACK}New Aircraft
+STR_CLONE_AIRCRAFT :{BLACK}Clone Aircraft
+STR_CLONE_AIRCRAFT_INFO :{BLACK}This will build a copy of the aircraft. Control-click will share the orders
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}This will build a copy of an aircraft. Click this button and then on an aircraft inside or outside the hangar. Control-click will share the orders
+STR_A005_NEW_AIRCRAFT :{WHITE}New Aircraft
+STR_A006_BUILD_AIRCRAFT :{BLACK}Build Aircraft
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Can't build aircraft...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} Aircraft
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (Orders)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (Details)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Age: {LTBLUE}{STRING2}{BLACK} Running Cost: {LTBLUE}{CURRENCY}/yr
+STR_A00E_MAX_SPEED :{BLACK}Max. speed: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit this year: {LTBLUE}{CURRENCY} (last year: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}Reliability: {LTBLUE}{COMMA}% {BLACK}Breakdowns since last service: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Built: {LTBLUE}{NUM}{BLACK} Value: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Can't send aircraft to hangar...
+STR_HEADING_FOR_HANGAR :{ORANGE}Heading for {STATION} Hangar
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}Heading for {STATION} Hangar, {VELOCITY}
+STR_HEADING_FOR_HANGAR_SERVICE :{LTBLUE}Service at {STATION} Hangar
+STR_HEADING_FOR_HANGAR_SERVICE_VEL :{LTBLUE}Service at {STATION} Hangar, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}Aircraft {COMMA} is waiting in the aircraft hangar
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Aircraft in the way
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Can't stop/start aircraft...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Aircraft is in flight
+STR_A019_CAPACITY :{BLACK}Capacity: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Capacity: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}Aircraft must be stopped in hangar
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Can't sell aircraft...
+STR_A01D_AIRPORT_CONSTRUCTION :Airport construction
+STR_A01E_BUILD_AIRPORT :{BLACK}Build airport
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Aircraft - click on aircraft for information
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Build new aircraft (requires airport with hangar)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Aircraft - click on aircraft for information
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Build new aircraft
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}Drag aircraft to here to sell it
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Centre main view on hangar location
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Aircraft selection list - click on aircraft for information
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Build the highlighted aircraft
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Current aircraft action - click here to stop/start aircraft
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Show aircraft's orders
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Centre main view on aircraft's location
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Send aircraft to hangar. CTRL+click will only service
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Show aircraft details
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}New aircraft now available!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Cost: {CURRENCY} Max. Speed: {VELOCITY}{}Capacity: {COMMA} passengers, {COMMA} bags of mail{}Running Cost: {CURRENCY}/yr
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Name aircraft
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Can't name aircraft...
+STR_A032_NAME_AIRCRAFT :{BLACK}Name aircraft
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Citizens celebrate . . .{}First aircraft arrives at {STATION}!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Plane Crash!{}{COMMA} die in fireball at {STATION}
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Plane Crash!{}Aircraft ran out of fuel, {COMMA} die in fireball!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Rename
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Rename aircraft type
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Rename aircraft type
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Can't rename aircraft type...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Refit aircraft to carry a different cargo type
+STR_A03C_REFIT :{WHITE}{VEHICLE} (Refit)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Refit aircraft
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Select type of cargo for aircraft to carry
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Refit aircraft to carry highlighted cargo type
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Select cargo type to carry:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}New capacity: {GOLD}{STRING1}{}{BLACK}Cost of refit: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Can't refit aircraft...
+STR_GO_TO_AIRPORT_HANGAR :Go to {STATION} Hangar
+SERVICE_AT_AIRPORT_HANGAR :Service at {STATION} Hangar
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}Zeppelin disaster at {STATION}!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Road vehicle destroyed in 'UFO' collision!
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}Oil refinery explosion near {TOWN}!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}Factory destroyed in suspicious circumstances near {TOWN}!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}'UFO' lands near {TOWN}!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}Coal mine subsidence leaves trail of destruction near {TOWN}!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Floods!{}At least {COMMA} missing, presumed dead after significant flooding!
+
+STR_BRIBE_FAILED :{WHITE}Your attempted bribe has been
+STR_BRIBE_FAILED_2 :{WHITE}discovered by a regional investigator
+STR_BUILD_DATE :{BLACK}Built: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Detailed performance rating
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}Detail
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Vehicles:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Stations:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Min. profit:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Min. income:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Max. income:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Delivered:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Cargo:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Money:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Loan:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Total:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Number of vehicles; this includes road vehicles, trains, ships and aircraft
+STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}Number of station parts. Every part of a station (e.g. train station, bus stop, airport) is counted, even if they are connected as one station
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}The profit of the vehicle with the lowest income (of all vehicles older than 2 years)
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Amount of cash made in the month with the lowest profit of the last 12 quarters
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Amount of cash made in the month with the highest profit of the last 12 quarters
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}Units of cargo delivered in the last four quarters
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}Number of types of cargo delivered in the last quarter
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Amount of money this company has in the bank
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}The amount of money this company has taken on loan
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Total points out of possible points
+
+STR_NEWGRF_SETTINGS_BUTTON :{BLACK}NewGRF Settings
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}NewGRF settings
+STR_NEWGRF_APPLY_CHANGES :{BLACK}Apply changes
+STR_NEWGRF_SET_PARAMETERS :{BLACK}Set parameters
+STR_NEWGRF_TIP :{BLACK}A list of all the Newgrf sets that you have installed. Click a set to change the settings
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}There are currently no newgrf files installed! Please refer to the manual for instructions on installing new graphics
+STR_NEWGRF_FILENAME :{BLACK}Filename: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
+STR_NEWGRF_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING}
+STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}You are about to make changes to a running game; this can crash OpenTTD.{}Are you absolutely sure about this?
+
+STR_NEWGRF_ADD :{BLACK}Add
+STR_NEWGRF_ADD_TIP :{BLACK}Add a NewGRF file to the list
+STR_NEWGRF_REMOVE :{BLACK}Remove
+STR_NEWGRF_REMOVE_TIP :{BLACK}Remove the selected NewGRF file from the list
+STR_NEWGRF_MOVEUP :{BLACK}Move Up
+STR_NEWGRF_MOVEUP_TIP :{BLACK}Move the selected NewGRF file up the list
+STR_NEWGRF_MOVEDOWN :{BLACK}Move Down
+STR_NEWGRF_MOVEDOWN_TIP :{BLACK}Move the selected NewGRF file down the list
+STR_NEWGRF_FILE_TIP :{BLACK}A list of the NewGRF files that are installed. Click a file to change its parameters
+STR_NEWGRF_PARAMETER :{BLACK}Parameters: {SILVER}{STRING}
+STR_NEWGRF_PARAMETER_QUERY :{BLACK}Enter NewGRF parameters
+STR_NEWGRF_NO_INFO :{BLACK}No information available
+
+STR_NEWGRF_ADD_CAPTION :{WHITE}Available NewGRF files
+STR_NEWGRF_ADD_FILE :{BLACK}Add to selection
+STR_NEWGRF_ADD_FILE_TIP :{BLACK}Add the selected NewGRF file to your configuration
+STR_NEWGRF_RESCAN_FILES :{BLACK}Rescan files
+STR_NEWGRF_RESCAN_FILES_TIP :{BLACK}Update the list of available NewGRF files
+STR_NEWGRF_DUPLICATE_GRFID :{WHITE}Cannot add file: duplicate GRF ID
+
+STR_NEWGRF_NOT_FOUND :{RED}Matching file not found
+STR_NEWGRF_DISABLED :{RED}Disabled
+
+STR_CURRENCY_WINDOW :{WHITE}Custom currency
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Exchange rate: {ORANGE}{CURRENCY} = £ {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Separator:
+STR_CURRENCY_PREFIX :{LTBLUE}Prefix:
+STR_CURRENCY_SUFFIX :{LTBLUE}Suffix:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Switch to Euro: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Switch to Euro: {ORANGE}never
+STR_CURRENCY_PREVIEW :{LTBLUE}Preview: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Change custom currency parameter
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} Train{P "" s}
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} Road Vehicle{P "" s}
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} Aircraft
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} Ship{P "" s}
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Show all trains which have this station on their schedule
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Show all road vehicles which have this station on their schedule
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Show all aircraft which have this station on their schedule
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Show all ships which have this station on their schedule
+
+STR_VEH_WITH_SHARED_ORDERS_LIST :{WHITE}Shared orders of {COMMA} Vehicle{P "" s}
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}Show all vehicles that share this schedule
+
+### depot strings
+STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}You are about to sell all the vehicles in the depot. Are you sure?
+
+STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP :{BLACK}Sell all trains in the depot
+STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP :{BLACK}Sell all road vehicles in the depot
+STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP :{BLACK}Sell all ships in the depot
+STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP :{BLACK}Sell all aircraft in the hangar
+
+STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP :{BLACK}Get a list of all trains with the current depot in their orders
+STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP :{BLACK}Get a list of all road vehicles with the current depot in their orders
+STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP :{BLACK}Get a list of all ships with the current depot in their orders
+STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP :{BLACK}Get a list of all aircraft with any hangar at this airport in their orders
+
+STR_DEPOT_AUTOREPLACE_TRAIN_TIP :{BLACK}Autoreplace all trains in the depot
+STR_DEPOT_AUTOREPLACE_ROADVEH_TIP :{BLACK}Autoreplace all road vehicles in the depot
+STR_DEPOT_AUTOREPLACE_SHIP_TIP :{BLACK}Autoreplace all ships in the depot
+STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP :{BLACK}Autoreplace all aircraft in the hangar
+
+STR_VEHICLE_LIST_TRAIN_DEPOT :{BLACK}{STRING1} - {COMMA} Train{P "" s}
+STR_VEHICLE_LIST_ROADVEH_DEPOT :{BLACK}{STRING1} - {COMMA} Road Vehicle{P "" s}
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING1} - {COMMA} Ship{P "" s}
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING1} - {COMMA} Aircraft
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}Replace {STRING}
+STR_REPLACE_VEHICLES_START :{BLACK}Start Replacing Vehicles
+STR_REPLACE_VEHICLES_STOP :{BLACK}Stop Replacing Vehicles
+STR_NOT_REPLACING :{BLACK}Not replacing
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}No vehicle selected
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Select the engine type to replace
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Select the new engine type you would like to use in place of the left selected engine type
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Press to stop the replacement of the engine type selected on the left
+STR_REPLACE_HELP_START_BUTTON :{BLACK}Press to begin replacement of the left selected engine type with the right selected engine type
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Choose the railtype you want to replace engines for
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Displays which engine the left selected engine is being replaced with, if any
+STR_REPLACE_HELP :{BLACK}This allows you to replace one engine type with another type, when trains of the original type enter a depot
+STR_REPLACE_REMOVE_WAGON :{BLACK}Wagon removal: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Make autoreplace keep the length of a train the same by removing wagons (starting at the front), if replacing the engine would make the train longer.
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}Replacing: {ORANGE}{SKIP}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} EXPERIMENTAL FEATURE {}Switch between engine and wagon replacement windows.{}Wagon replacement will only be done if the new wagon can be refitted into carrying the same type of cargo as the old one. This is checked for each wagon when the actual replacement takes place.
+STR_ENGINE_NOT_BUILDABLE :{WHITE}Engine is not buildable
+
+STR_ENGINES :Engines
+STR_WAGONS :Wagons
+
+STR_MASS_STOP_DEPOT_TRAIN_TIP :{BLACK}Click to stop all the trains inside the depot
+STR_MASS_STOP_DEPOT_ROADVEH_TIP :{BLACK}Click to stop all the road vehicles inside the depot
+STR_MASS_STOP_DEPOT_SHIP_TIP :{BLACK}Click to stop all the ships inside the depot
+STR_MASS_STOP_HANGAR_TIP :{BLACK}Click to stop all the aircraft inside the hangar
+
+STR_MASS_START_DEPOT_TRAIN_TIP :{BLACK}Click to start all the trains inside the depot
+STR_MASS_START_DEPOT_ROADVEH_TIP :{BLACK}Click to start all the road vehicles inside the depot
+STR_MASS_START_DEPOT_SHIP_TIP :{BLACK}Click to start all the ships inside the depot
+STR_MASS_START_HANGAR_TIP :{BLACK}Click to start all the aircraft inside the hangar
+
+STR_MASS_STOP_LIST_TIP :{BLACK}Click to stop all the vehicles in the list
+STR_MASS_START_LIST_TIP :{BLACK}Click to start all the vehicles in the list
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}Sign List - {COMMA} Sign{P "" s}
+
+STR_ORDER_REFIT_FAILED :{WHITE}Order refit failure stopped {STRING} {COMMA}
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :Rail Vehicles
+STR_ELRAIL_VEHICLES :Electrified Rail Vehicles
+STR_MONORAIL_VEHICLES :Monorail Vehicles
+STR_MAGLEV_VEHICLES :Maglev Vehicles
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Cost: {GOLD}{CURRENCY}{BLACK} Weight: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Speed: {GOLD}{VELOCITY}{BLACK} Power: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}Speed: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Running Cost: {GOLD}{CURRENCY}/yr
+STR_PURCHASE_INFO_CAPACITY :{BLACK}Capacity: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Designed: {GOLD}{NUM}{BLACK} Life: {GOLD}{COMMA} years
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}Max. Reliability: {GOLD}{COMMA}%
+STR_PURCHASE_INFO_COST :{BLACK}Cost: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Weight: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Cost: {GOLD}{CURRENCY}{BLACK} Speed: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Capacity: {GOLD}{COMMA} passengers, {COMMA} bags of mail
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Powered Wagons: {GOLD}+{POWER}{BLACK} Weight: {GOLD}+{WEIGHT_S}
+STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Refittable to: {GOLD}
+STR_PURCHASE_INFO_ALL_TYPES :All cargo types
+STR_PURCHASE_INFO_ALL_BUT :All but {GOLD}
+STR_PURCHASE_INFO_MAX_TE :{BLACK}Max. Tractive Effort: {GOLD}{FORCE}
+
+########### String for New Landscape Generator
+
+STR_GENERATE :{WHITE}Generate
+STR_RANDOM :{BLACK}Randomise
+STR_RANDOM_HELP :{BLACK}Change the random seed used for Terrain Generation
+STR_WORLD_GENERATION_CAPTION :{WHITE}World generation
+STR_RANDOM_SEED :{BLACK}Random Seed:
+STR_RANDOM_SEED_HELP :{BLACK}Click to enter a random seed
+STR_LAND_GENERATOR :{BLACK}Land generator:
+STR_TREE_PLACER :{BLACK}Tree algorithm:
+STR_HEIGHTMAP_ROTATION :{BLACK}Heightmap rotation:
+STR_TERRAIN_TYPE :{BLACK}Terrain type:
+STR_QUANTITY_OF_SEA_LAKES :{BLACK}Sea level:
+STR_SMOOTHNESS :{BLACK}Smoothness:
+STR_SNOW_LINE_HEIGHT :{BLACK}Snow line height:
+STR_DATE :{BLACK}Date:
+STR_NUMBER_OF_TOWNS :{BLACK}No. of towns:
+STR_NUMBER_OF_INDUSTRIES :{BLACK}No. of industries:
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_SNOW_LINE_UP :{BLACK}Move the snow line height one up
+STR_SNOW_LINE_DOWN :{BLACK}Move the snow line height one down
+STR_SNOW_LINE_QUERY_CAPT :{WHITE}Change snow line height
+STR_START_DATE_QUERY_CAPT :{WHITE}Change starting year
+STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Scale warning
+STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Resizing source map too much is not recommended. Continue with the generation?
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_HEIGHTMAP_NAME :{BLACK}Heightmap name:
+STR_HEIGHTMAP_SIZE :{BLACK}Size: {ORANGE}{NUM} x {NUM}
+STR_GENERATION_WORLD :{WHITE}Generating world...
+STR_GENERATION_ABORT :{BLACK}Abort
+STR_GENERATION_ABORT_CAPTION :{WHITE}Abort World Generation
+STR_GENERATION_ABORT_MESSAGE :{YELLOW}Do you really want to abort the generation?
+STR_PROGRESS :{WHITE}{NUM}% complete
+STR_GENERATION_PROGRESS :{BLACK}{NUM} / {NUM}
+STR_WORLD_GENERATION :{BLACK}World generation
+STR_TREE_GENERATION :{BLACK}Tree generation
+STR_UNMOVABLE_GENERATION :{BLACK}Unmovable generation
+STR_CLEARING_TILES :{BLACK}Rough and rocky area generation
+STR_SETTINGUP_GAME :{BLACK}Setting up game
+STR_PREPARING_TILELOOP :{BLACK}Running tile-loop
+STR_PREPARING_GAME :{BLACK}Preparing game
+STR_DIFFICULTY_TO_CUSTOM :{WHITE}This action changed the difficulty level to custom
+STR_SE_FLAT_WORLD :{WHITE}Flat land
+STR_SE_FLAT_WORLD_TIP :{BLACK}Generate a flat land
+STR_SE_RANDOM_LAND :{WHITE}Random land
+STR_SE_NEW_WORLD :{BLACK}Create new scenario
+STR_SE_CAPTION :{WHITE}Scenario type
+STR_FLAT_WORLD_HEIGHT_DOWN :{BLACK}Move the height of flat land one down
+STR_FLAT_WORLD_HEIGHT_UP :{BLACK}Move the height of flat land one up
+STR_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Change height of flat land
+STR_FLAT_WORLD_HEIGHT :{BLACK}Height of flat land:
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+STR_SMALLMAP_CENTER :{BLACK}Center the smallmap on the current position
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}Small
+STR_CITY_AIRPORT :{BLACK}City
+STR_METRO_AIRPORT :{BLACK}Metropolitan airport
+STR_INTERNATIONAL_AIRPORT :{BLACK}International airport
+STR_COMMUTER_AIRPORT :{BLACK}Commuter
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Intercontinental
+STR_HELIPORT :{BLACK}Heliport
+STR_HELIDEPOT :{BLACK}Helidepot
+STR_HELISTATION :{BLACK}Helistation
+
+STR_SMALL_AIRPORTS :{BLACK}Small airports
+STR_LARGE_AIRPORTS :{BLACK}Large airports
+STR_HUB_AIRPORTS :{BLACK}Hub airports
+STR_HELIPORTS :{BLACK}Helicopter airports
+
+############ Tooltip measurment
+
+STR_MEASURE_LENGTH :{BLACK}Length: {NUM}
+STR_MEASURE_AREA :{BLACK}Area: {NUM} x {NUM}
+STR_MEASURE_LENGTH_HEIGHTDIFF :{BLACK}Length: {NUM}{}Height difference: {NUM} m
+STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}Area: {NUM} x {NUM}{}Height difference: {NUM} m
+
+########
diff --git a/src/lang/esperanto.txt b/src/lang/esperanto.txt
new file mode 100644
index 000000000..9044454cc
--- /dev/null
+++ b/src/lang/esperanto.txt
@@ -0,0 +1,3116 @@
+##name Esperanto
+##ownname Esperanto
+##isocode eo_EO.UTF-8
+##plural 0
+##case n
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}For de la mapo
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Tro proksime al la mapa rando
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Ne sufiĉe da mono - vi bezonas {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Necesas ebena lando
+STR_0008_WAITING :{BLACK}Atendas: {WHITE}{STRING}
+STR_0009 :{WHITE} {CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (survoje de
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Akceptas: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Akceptas: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :PasaÄeroj
+STR_0010_COAL :Karbo
+STR_0011_MAIL :PoÅto
+STR_0012_OIL :Oleo
+STR_0013_LIVESTOCK :Brutoj
+STR_0014_GOODS :Varoj
+STR_0015_GRAIN :Greno
+STR_0016_WOOD :Ligno
+STR_0017_IRON_ORE :Fera Erco
+STR_0018_STEEL :Åœtalo
+STR_0019_VALUABLES :Valoraĵoj
+STR_001A_COPPER_ORE :Kupra Erco
+STR_001B_MAIZE :Maizo
+STR_001C_FRUIT :Fruktoj
+STR_001D_DIAMONDS :Diamantoj
+STR_001E_FOOD :ManÄaĵoj
+STR_001F_PAPER :Papero
+STR_0020_GOLD :Oro
+STR_0021_WATER :Akvo
+STR_0022_WHEAT :Tritiko
+STR_0023_RUBBER :Kaŭĉuko
+STR_0024_SUGAR :Sukero
+STR_0025_TOYS :Ludiloj
+STR_0026_CANDY :Dolĉaĵoj
+STR_0027_COLA :Kolao
+STR_0028_COTTON_CANDY :SukerÅpinaĵoj
+STR_0029_BUBBLES :Vezikoj
+STR_002A_TOFFEE :Tofeoj
+STR_002B_BATTERIES :Baterioj
+STR_002C_PLASTIC :Plastiko
+STR_002D_FIZZY_DRINKS :Amuzaj Trinkaĵoj
+STR_002E :
+STR_002F_PASSENGER :PasaÄero
+STR_0030_COAL :Karbo
+STR_0031_MAIL :PoÅto
+STR_0032_OIL :Oleo
+STR_0033_LIVESTOCK :Bruto
+STR_0034_GOODS :Varo
+STR_0035_GRAIN :Greno
+STR_0036_WOOD :Ligno
+STR_0037_IRON_ORE :Fera Erco
+STR_0038_STEEL :Åœtalo
+STR_0039_VALUABLES :Valoraĵoj
+STR_003A_COPPER_ORE :Kupra Erco
+STR_003B_MAIZE :Maizo
+STR_003C_FRUIT :Frukto
+STR_003D_DIAMOND :Diamanto
+STR_003E_FOOD :ManÄaĵo
+STR_003F_PAPER :Papero
+STR_0040_GOLD :Oro
+STR_0041_WATER :Akvo
+STR_0042_WHEAT :Tritiko
+STR_0043_RUBBER :Kaŭĉuko
+STR_0044_SUGAR :Sukero
+STR_0045_TOY :Ludilo
+STR_0046_CANDY :Dolĉaĵo
+STR_0047_COLA :Kolao
+STR_0048_COTTON_CANDY :SukerÅpinaĵo
+STR_0049_BUBBLE :Veziko
+STR_004A_TOFFEE :Tofeo
+STR_004B_BATTERY :Baterio
+STR_004C_PLASTIC :Plastiko
+STR_004D_FIZZY_DRINK :Amuza Trinkaĵo
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} pasaÄero{P "" j}
+STR_QUANTITY_COAL :{WEIGHT} da karbo
+STR_QUANTITY_MAIL :{COMMA} sako{P "" j} da poÅto
+STR_QUANTITY_OIL :{VOLUME} da oleo
+STR_QUANTITY_LIVESTOCK :{COMMA} bruto{P "" j}
+STR_QUANTITY_GOODS :{COMMA} kesto{P "" j} da varoj
+STR_QUANTITY_GRAIN :{WEIGHT} da greno
+STR_QUANTITY_WOOD :{WEIGHT} da ligno
+STR_QUANTITY_IRON_ORE :{WEIGHT} da fera erco
+STR_QUANTITY_STEEL :{WEIGHT} da Åtalo
+STR_QUANTITY_VALUABLES :{COMMA} sako{P "" j} da valoraĵoj
+STR_QUANTITY_COPPER_ORE :{WEIGHT} da kupra erco
+STR_QUANTITY_MAIZE :{WEIGHT} da maizo
+STR_QUANTITY_FRUIT :{WEIGHT} da fruktoj
+STR_QUANTITY_DIAMONDS :{COMMA} sako{P "" j} da diamantoj
+STR_QUANTITY_FOOD :{WEIGHT} da manÄaĵoj
+STR_QUANTITY_PAPER :{WEIGHT} da papero
+STR_QUANTITY_GOLD :{COMMA} sako{P "" j} da oro
+STR_QUANTITY_WATER :{VOLUME} da akvo
+STR_QUANTITY_WHEAT :{WEIGHT} da tritiko
+STR_QUANTITY_RUBBER :{VOLUME} da kaŭĉuko
+STR_QUANTITY_SUGAR :{WEIGHT} da sukero
+STR_QUANTITY_TOYS :{COMMA} ludilo{P "" j}
+STR_QUANTITY_SWEETS :{COMMA} sako{P "" j} da dolĉaĵoj
+STR_QUANTITY_COLA :{VOLUME} da kolao
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} da sukerÅpinaĵo
+STR_QUANTITY_BUBBLES :{COMMA} veziko{P "" j}
+STR_QUANTITY_TOFFEE :{WEIGHT} da tofeo
+STR_QUANTITY_BATTERIES :{COMMA} baterio{P "" j}
+STR_QUANTITY_PLASTIC :{VOLUME} da plastiko
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} amuza{P "" j} trinkaĵo{P "" j}
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}PS
+STR_ABBREV_COAL :{TINYFONT}KB
+STR_ABBREV_MAIL :{TINYFONT}PT
+STR_ABBREV_OIL :{TINYFONT}OL
+STR_ABBREV_LIVESTOCK :{TINYFONT}BR
+STR_ABBREV_GOODS :{TINYFONT}VR
+STR_ABBREV_GRAIN :{TINYFONT}GR
+STR_ABBREV_WOOD :{TINYFONT}LG
+STR_ABBREV_IRON_ORE :{TINYFONT}FE
+STR_ABBREV_STEEL :{TINYFONT}ÅœT
+STR_ABBREV_VALUABLES :{TINYFONT}VL
+STR_ABBREV_COPPER_ORE :{TINYFONT}KE
+STR_ABBREV_MAIZE :{TINYFONT}MZ
+STR_ABBREV_FRUIT :{TINYFONT}FT
+STR_ABBREV_DIAMONDS :{TINYFONT}DM
+STR_ABBREV_FOOD :{TINYFONT}MN
+STR_ABBREV_PAPER :{TINYFONT}PR
+STR_ABBREV_GOLD :{TINYFONT}OR
+STR_ABBREV_WATER :{TINYFONT}AK
+STR_ABBREV_WHEAT :{TINYFONT}TT
+STR_ABBREV_RUBBER :{TINYFONT}KA
+STR_ABBREV_SUGAR :{TINYFONT}SK
+STR_ABBREV_TOYS :{TINYFONT}LD
+STR_ABBREV_SWEETS :{TINYFONT}DL
+STR_ABBREV_COLA :{TINYFONT}KL
+STR_ABBREV_CANDYFLOSS :{TINYFONT}SS
+STR_ABBREV_BUBBLES :{TINYFONT}VZ
+STR_ABBREV_TOFFEE :{TINYFONT}TF
+STR_ABBREV_BATTERIES :{TINYFONT}BA
+STR_ABBREV_PLASTIC :{TINYFONT}PL
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}AT
+STR_ABBREV_NONE :{TINYFONT}NE
+STR_ABBREV_ALL :{TINYFONT}ĈIU
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Mapo - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Ludaj Opcioj
+STR_00B2_MESSAGE :{YELLOW}MesaÄo
+STR_00B3_MESSAGE_FROM :{YELLOW}MesaÄo de {STRING}
+STR_POPUP_CAUTION_CAPTION :{WHITE}Atentu!
+STR_00B4_CAN_T_DO_THIS :{WHITE}Ne eblas fari ĉi tion....
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Ne eblas malplenigi la regionon....
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Origina kopirajto {COPYRIGHT} 1995 Chris Sawyer, Ĉiuj rajtoj rezervitaj
+STR_00B7_VERSION :{BLACK}OpenTTD-versio {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 La teamo de OpenTTD
+STR_TRANSLATED_BY :{BLACK} Tradukanto(j) -
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Fermi
+STR_00C8_YES :{BLACK}Jes
+STR_00C9_NO :{BLACK}Ne
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Ĉu vi vere volas fermi la ludon kaj reiri al {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Nenio
+STR_00D1_DARK_BLUE :Malhelblua
+STR_00D2_PALE_GREEN :Palverda
+STR_00D3_PINK :Roza
+STR_00D4_YELLOW :Flava
+STR_00D5_RED :RuÄa
+STR_00D6_LIGHT_BLUE :Helblua
+STR_00D7_GREEN :Verda
+STR_00D8_DARK_GREEN :Malhelverda
+STR_00D9_BLUE :Blua
+STR_00DA_CREAM :Krema
+STR_00DB_MAUVE :Purpurverda
+STR_00DC_PURPLE :Purpura
+STR_00DD_ORANGE :OranÄa
+STR_00DE_BROWN :Bruna
+STR_00DF_GREY :Griza
+STR_00E0_WHITE :Blanka
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Tro da veturiloj en la ludo
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Loko
+STR_00E5_CONTOURS :Konturoj
+STR_00E6_VEHICLES :Veturiloj
+STR_00E7_INDUSTRIES :Industrioj
+STR_00E8_ROUTES :Vojiroj
+STR_00E9_VEGETATION :Verdaĵo
+STR_00EA_OWNERS :Posedantoj
+STR_00EB_ROADS :{BLACK}{TINYFONT}Vojoj
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Fervojoj
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Stacidomoj/Flughavenoj/Havenoj
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Konstruaĵoj/Industrioj
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Veturiloj
+STR_00F0_100M :{BLACK}{TINYFONT}100m
+STR_00F1_200M :{BLACK}{TINYFONT}200m
+STR_00F2_300M :{BLACK}{TINYFONT}300m
+STR_00F3_400M :{BLACK}{TINYFONT}400m
+STR_00F4_500M :{BLACK}{TINYFONT}500m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Trajnoj
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Vojaj Veturiloj
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Åœipoj
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Aviadiloj
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Transportvojoj
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Karbminejo
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Elektrejo
+STR_00FC_FOREST :{BLACK}{TINYFONT}Arbaro
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}Segejo
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Oleproduktejo
+STR_00FF_FARM :{BLACK}{TINYFONT}Farmbieno
+STR_0100_FACTORY :{BLACK}{TINYFONT}Farejo
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Printejo
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Olefonto
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Ferercminejo
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Åœtalejo
+STR_0105_BANK :{BLACK}{TINYFONT}Banko
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Paperejo
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Orminejo
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}ManÄaĵfarejo
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Diamantminejo
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Kuproercminejo
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Fruktkulturejo
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Kaŭĉukkulturejo
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Akvofonto
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Akvoturo
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}Lignejo
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}SukerÅpinaĵaro
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Dolĉaĵfarejo
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Bateribieno
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Kolafonto
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Ludilvendejo
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Ludilfarejo
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Plastikfontanaro
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Farejo de Amuzaj Trinkaĵoj
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Vezikgenerilo
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Tofeminejo
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Sukerminejo
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Fervoja Stacidomo
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}ÅœarÄaÅ­ta ÅœarÄejo
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Busstacio
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Flughaveno/Helikopterejo
+STR_011F_DOCK :{BLACK}{TINYFONT}Haveno
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Hazardlando
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Herba Lando
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Senuza lando
+STR_0123_FIELDS :{BLACK}{TINYFONT}Kampoj
+STR_0124_TREES :{BLACK}{TINYFONT}Arboj
+STR_0125_ROCKS :{BLACK}{TINYFONT}Rokoj
+STR_0126_WATER :{BLACK}{TINYFONT}Akvo
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Sen posedanto
+STR_0128_TOWNS :{BLACK}{TINYFONT}Urboj
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Industrioj
+STR_012A_DESERT :{BLACK}{TINYFONT}Dezerto
+STR_012B_SNOW :{BLACK}{TINYFONT}NeÄo
+STR_012C_MESSAGE :{WHITE}MesaÄo
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Nuligu
+STR_012F_OK :{BLACK}Bone
+STR_0130_RENAME :{BLACK}Renomu
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Tro da nomoj difinitaj
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}La elektita nomo jam uziÄas
+
+STR_0133_WINDOWS :Vindozo
+STR_0134_UNIX :Unikso
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...posedata de {STRING}
+STR_013C_CARGO :{BLACK}ÅœarÄo
+STR_013D_INFORMATION :{BLACK}Informoj
+STR_013E_CAPACITIES :{BLACK}Kapabloj
+STR_013E_TOTAL_CARGO :{BLACK}Tuta ÅœarÄo
+STR_013F_CAPACITY :{BLACK}Enhavkapablo: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}Kapablo: {LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Tuta ÅarÄkapablo de ĉi tiu trajno:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}Nova Ludo
+STR_0141_LOAD_GAME :{BLACK}ÅœarÄu ludon
+STR_SINGLE_PLAYER :{BLACK}Unu Ludanto
+STR_MULTIPLAYER :{BLACK}Pluraj Ludantoj
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Mapgrandeco:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Ludaj Opcioj
+
+STR_0150_SOMEONE :iu{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Mondomapo
+STR_0152_TOWN_DIRECTORY :Urbaro
+STR_0153_SUBSIDIES :Subvencioj
+
+STR_UNITS_IMPERIAL :Angla sistemo
+STR_UNITS_METRIC :Metra sistemo
+STR_UNITS_SI :Sistemo Internacia
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} mph
+STR_UNITS_VELOCITY_METRIC :{COMMA} km/h
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}ĉp
+STR_UNITS_POWER_METRIC :{COMMA}ĉp
+STR_UNITS_POWER_SI :{COMMA}kW
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} angla{P "" j} tuno{P "" j}
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} tuno{P "" j}
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} kg
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}gal
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}l
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}m³
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} galjono{P "" j}
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} litro{P "" j}
+STR_UNITS_VOLUME_LONG_SI :{COMMA} m³
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10³ lbf
+STR_UNITS_FORCE_METRIC :{COMMA} tuna forto
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Gajna grafiko
+STR_0155_INCOME_GRAPH :Enspeza grafiko
+STR_0156_DELIVERED_CARGO_GRAPH :Liveriteca grafiko
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Kvalithistoria grafiko
+STR_0158_COMPANY_VALUE_GRAPH :Kompanivalora grafiko
+STR_0159_CARGO_PAYMENT_RATES :ÅœarÄpaga grafiko
+STR_015A_COMPANY_LEAGUE_TABLE :Kompaniara tabelo
+STR_PERFORMANCE_DETAIL_MENU :Detala kvalittakso
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}Pri OpenTTD
+STR_015C_SAVE_GAME :Konservu ludon
+STR_015D_LOAD_GAME :ÅœarÄu ludon
+STR_015E_QUIT_GAME :Foriru de la ludo
+STR_015F_QUIT :Fermu
+STR_ABANDON_GAME_QUERY :{YELLOW}Ĉu vi certas ke vi volas foriri?
+STR_0161_QUIT_GAME :{WHITE}Foriri de la ludo
+STR_SORT_ORDER_TIP :{BLACK}Elektu vicordo (deira/alira)
+STR_SORT_CRITERIA_TIP :{BLACK}Elektu ordigaj kondiĉoj
+STR_SORT_BY :{BLACK}Ordigu laÅ­
+
+STR_SORT_BY_POPULATION :{BLACK}EnloÄantaro
+STR_SORT_BY_PRODUCTION :{BLACK}Produktado
+STR_SORT_BY_TYPE :{BLACK}Tipo
+STR_SORT_BY_TRANSPORTED :{BLACK}TransportiÄis
+STR_SORT_BY_NAME :{BLACK}Nomo
+STR_SORT_BY_DROPDOWN_NAME :Nomo
+STR_SORT_BY_DATE :{BLACK}Dato
+STR_SORT_BY_NUMBER :Numero
+STR_SORT_BY_PROFIT_LAST_YEAR :Gajno lastjara
+STR_SORT_BY_PROFIT_THIS_YEAR :Gajno ĉi-jara
+STR_SORT_BY_AGE :AÄo
+STR_SORT_BY_RELIABILITY :Fidebleco
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Tuta kapablo por ĉiu ÅarÄtipo
+STR_SORT_BY_MAX_SPEED :Maksimuma rapideco
+STR_SORT_BY_MODEL :Tipo
+STR_SORT_BY_VALUE :Valoro
+STR_SORT_BY_FACILITY :Stacidoma tipo
+STR_SORT_BY_WAITING :Valoro de atendanta ÅarÄo
+STR_SORT_BY_RATING_MAX :Takso de ÅarÄo
+STR_ENGINE_SORT_ENGINE_ID :MaÅina ID (klasika ordigo)
+STR_ENGINE_SORT_COST :Kosto
+STR_ENGINE_SORT_POWER :Potenco
+STR_ENGINE_SORT_INTRO_DATE :Enkonduka dato
+STR_ENGINE_SORT_RUNNING_COST :Irkosto
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Potenco/Irkosto
+STR_ENGINE_SORT_CARGO_CAPACITY :ÅœarÄkapablo
+STR_NO_WAITING_CARGO :{BLACK}Nenia ÅarÄo atendas
+STR_SELECT_ALL_FACILITIES :{BLACK}Elektu ĉiujn konstruaĵojn
+STR_SELECT_ALL_TYPES :{BLACK}Elektu ĉiujn ÅarÄotipojn (inkluzive de ne atendanta ÅarÄo)
+STR_AVAILABLE_ENGINES_TIP :{BLACK}Vidu liston da ĉiuj haveblaj maÅinoj por ĉi tiu veturilspeco.
+STR_MANAGE_LIST :{BLACK}ManaÄu liston
+STR_MANAGE_LIST_TIP :{BLACK}Sendu instrukciojn al ĉiuj veturiloj en la listo
+STR_REPLACE_VEHICLES :AnstataÅ­u veturilojn
+STR_SEND_TRAIN_TO_DEPOT :Sendu al Deponejo
+STR_SEND_ROAD_VEHICLE_TO_DEPOT :Sendu al Deponejo
+STR_SEND_SHIP_TO_DEPOT :Sendu al Deponejo
+STR_SEND_AIRCRAFT_TO_HANGAR :Sendu al Hangaro
+STR_SEND_FOR_SERVICING :Sendu por Prizorgo
+
+############ range for months starts
+STR_0162_JAN :Jan
+STR_0163_FEB :Feb
+STR_0164_MAR :Mar
+STR_0165_APR :Apr
+STR_0166_MAY :Maj
+STR_0167_JUN :Jun
+STR_0168_JUL :Jul
+STR_0169_AUG :Aug
+STR_016A_SEP :Sep
+STR_016B_OCT :Okt
+STR_016C_NOV :Nov
+STR_016D_DEC :Dec
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}PaÅ­zigu la ludon
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Konservu ludon, foriru de la ludo, fermu
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Montru liston da stacidomoj de kompanioj
+STR_0174_DISPLAY_MAP :{BLACK}Montru mapon
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Montru mapon, urbaron
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Montru urbaron
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Montru kompaniajn financajn informojn
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Montru Äeneralajn kompaniajn informojn
+STR_0179_DISPLAY_GRAPHS :{BLACK}Montru grafikojn
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Montru kompanian tabelon
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Montru liston da kompaniaj trajnoj
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Montru liston da kompaniaj vojveturiloj
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Montru liston da kompaniaj Åipoj
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Montru liston da kompaniaj aviadiloj
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Zomu vidon
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Malzomu vidon
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Konstruu relojn
+STR_0182_BUILD_ROADS :{BLACK}Konstruu vojojn
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Konstruu havenojn
+STR_0184_BUILD_AIRPORTS :{BLACK}Konstruu flughavenojn
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Plantu arbojn, metu signojn ktp.
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Landregionaj informoj
+STR_0187_OPTIONS :{BLACK}Opcioj
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Ne povas ÅanÄi prizorga intervalo...
+STR_018B_CLOSE_WINDOW :{BLACK}Fermu fenestron
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Fenestra titolo - tiru por movi la fenestron
+STR_STICKY_BUTTON :{BLACK}Marku ke ne fermiÄu la fenestro per la 'ĉiujn fenestrojn fermu'-klavo
+STR_RESIZE_BUTTON :{BLACK}Klaku kaj tiru por reformi la fenestron
+STR_SAVELOAD_HOME_BUTTON :{BLACK}Klaku ĉi tie por salti al la nuna defaŭlta konserva dosierujo
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Detruu konstruaĵojn ktp. sur landkvadrato
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Malaltigu landangulon
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Altigu landangulon
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Skrolbreto - skrolas la liston supren/malsupren
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Skrolbreto - skrolas la liston dekstren/maldekstren
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Montru landkonturojn sur la mapo
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Montru veturilojn sur la mapo
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Montru industriojn sur la mapo
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Montru transportvojojn sur la mapo
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Montru verdaĵojn sur la mapo
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Montru landposedantojn sur la mapo
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Vidu aÅ­ ne vidu urbonomojn sur la mapo
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Gajno ĉi-jare: {CURRENCY} (pasintjare: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} jaro{P "" j} ({COMMA})
+STR_AGE_RED :{RED}{COMMA} jaro{P "" j} ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Vojveturilo
+STR_019D_AIRCRAFT :Aviadilo
+STR_019E_SHIP :Åœipo
+STR_019F_TRAIN :Trajno
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} malnoviÄas
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} tre malnoviÄas
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} ege malnoviÄas kaj bezonas esti ÅanÄata
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Landregionaj informoj
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}ForviÅkosto: {LTBLUE}ne eblas
+STR_01A5_COST_TO_CLEAR :{BLACK}ForviÅkosto: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :N/A
+STR_01A7_OWNER :{BLACK}Posedanto: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Lokaj estroj: {LTBLUE}{STRING}
+STR_01A9_NONE :Neniu
+STR_01AA_NAME :{BLACK}Nomo
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1a de
+STR_01AD_2ND :2a de
+STR_01AE_3RD :3a de
+STR_01AF_4TH :4a de
+STR_01B0_5TH :5a de
+STR_01B1_6TH :6a de
+STR_01B2_7TH :7a de
+STR_01B3_8TH :8a de
+STR_01B4_9TH :9a de
+STR_01B5_10TH :10a de
+STR_01B6_11TH :11a de
+STR_01B7_12TH :12a de
+STR_01B8_13TH :13a de
+STR_01B9_14TH :14a de
+STR_01BA_15TH :15a de
+STR_01BB_16TH :16a de
+STR_01BC_17TH :17a de
+STR_01BD_18TH :18a de
+STR_01BE_19TH :19a de
+STR_01BF_20TH :20a de
+STR_01C0_21ST :21a de
+STR_01C1_22ND :22a de
+STR_01C2_23RD :23a de
+STR_01C3_24TH :24a de
+STR_01C4_25TH :25a de
+STR_01C5_26TH :26a de
+STR_01C6_27TH :27a de
+STR_01C7_28TH :28a de
+STR_01C8_29TH :29a de
+STR_01C9_30TH :30a de
+STR_01CA_31ST :31a de
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}ÅœarÄo akceptata: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Ä´aza Diskogurdo
+STR_01D3_SOUND_MUSIC :Sono/muziko
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Montru fenestron de sono/muziko
+STR_01D5_ALL :{TINYFONT}Ĉiu
+STR_01D6_OLD_STYLE :{TINYFONT}Malnovstile
+STR_01D7_NEW_STYLE :{TINYFONT}Novstile
+STR_01D8_EZY_STREET :{TINYFONT}Facila Vojo
+STR_01D9_CUSTOM_1 :{TINYFONT}Propra 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Propra 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Muzika Volumeno
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Efekta Volumeno
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}- ' ' ' ' ' ' +
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Saltu al antaÅ­a numero
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Saltu al posta numero
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Finu muzikludadon
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Komencu muzikludadon
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Tiru la glitilojn por agordi la muzikan kaj sonefektan volumenojn
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Numero{SETX 88}Titolo
+STR_01E9_SHUFFLE :{TINYFONT}Miksu
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Programo
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Elekto de Muzikprogramo
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Numera Indekso
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Programo - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}ViÅu
+STR_01F1_SAVE :{TINYFONT}{BLACK}Konservu
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Nuna programo da muziknumeroj
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Elektu la programon de ĉiuj numeroj
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Elektu la programon de malnovstila muziko
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Elektu la programon de novstila muziko
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Elektu la unuan propran programon
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Elektu la duan propran programon
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}ViÅu nunan programon (nur propran)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Konservu muzikagordojn
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Alklaku muzikeron por aldoni al la nuna programo (nur propra)
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Alklaku muzikeron por viÅi el la nuna programo (nur propra)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Miksu/ne miksu
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Montru muziker-elektan fenestron
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Alklaku servon por centrigi la vidon al industrio/urbo
+STR_01FE_DIFFICULTY :{BLACK}Malfacileco ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Lasta mesaÄo/novaĵo
+STR_0201_MESSAGE_SETTINGS :MesaÄaj agordoj
+STR_MESSAGE_HISTORY_MENU :MesaÄa Historio
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Montru lastan mesaÄon/novaĵon, montru mesaÄajn opciojn
+STR_0204_MESSAGE_OPTIONS :{WHITE}MesaÄaj Opcioj
+STR_0205_MESSAGE_TYPES :{BLACK}MesaÄtipoj:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Unua veturilo atingas propran stacion
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Unua veturilo atingas konkurantan stacion
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Akcidentoj / katastrofoj
+STR_0209_COMPANY_INFORMATION :{YELLOW}Kompaniaj informoj
+STR_020A_ECONOMY_CHANGES :{YELLOW}Ekonomiaj ÅanÄoj
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Konsiloj / informoj pri propraj veturiloj
+STR_020C_NEW_VEHICLES :{YELLOW}Novaj veturiloj
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}ÅœarÄakceptado ÅanÄiÄas
+STR_020E_SUBSIDIES :{YELLOW}Subvencioj
+STR_020F_GENERAL_INFORMATION :{YELLOW}Äœeneralaj informoj
+STR_MESSAGES_ALL :{YELLOW}Turnu ĉiujn mesaÄtipojn al: Ne / Resume/ Plene
+STR_MESSAGE_SOUND :{YELLOW}Ludu sonon por resumaj novaĵoj
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...tro for de la antaÅ­a destino
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Superkompanioj kiuj atingis {NUM}{}(Nivelo {STRING})
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Kompania tabelo en {NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Kompaniisto
+STR_0214_ENTREPRENEUR :Entreprenisto
+STR_0215_INDUSTRIALIST :Industriisto
+STR_0216_CAPITALIST :Kapitalisto
+STR_0217_MAGNATE :ManaÄisto
+STR_0218_MOGUL :Potenculo
+STR_0219_TYCOON_OF_THE_CENTURY :Plej potenca de la Jarcento
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} atingis staton de '{STRING}'!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} de {COMPANY} atingis staton de '{STRING}'!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Kreu Scenaron
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Scenarkreilon
+STR_0223_LAND_GENERATION :{WHITE}Landa Generado
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Hazarda Lando
+STR_0227_RESET_LAND :{BLACK}Reigu Landon
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Grandigu landparton por (mal)altigi
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Malgrandigu landparton por (mal)altigi
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Kreu landon hazarde
+STR_022B_RESET_LANDSCAPE :{BLACK}Reigu landaspekton
+STR_022C_RESET_LANDSCAPE :{WHITE}Reigu Landaspekton
+STR_LOAD_GAME_HEIGHTMAP :{WHITE}Uzu Altecmapon
+STR_LOAD_SCEN_HEIGHTMAP :{BLACK}Uzu Altecmapon
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Ĉu vi certas ke vi volas reigi la landaspekton?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Landaspekta generado
+STR_022F_TOWN_GENERATION :{BLACK}Urba generado
+STR_0230_INDUSTRY_GENERATION :{BLACK}Industria generado
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Vojkonstruado
+STR_0233_TOWN_GENERATION :{WHITE}Urba Generado
+STR_0234_NEW_TOWN :{BLACK}Nova Urbo
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Konstruu novan urbon
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Ne povas fari urbon ĉi tie...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...tro proksime al la mapa rando
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...tro proksime al alia urbo
+STR_0239_SITE_UNSUITABLE :{WHITE}...nekonvena ejo
+STR_023A_TOO_MANY_TOWNS :{WHITE}...tro da urboj
+STR_CANNOT_GENERATE_TOWN :{WHITE}Ne povas konstrui ajnan urbon
+STR_NO_SPACE_FOR_TOWN :{WHITE}...spaco mankas sur la mapo
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Grandigu la urbon
+STR_023C_EXPAND :{BLACK}Vastigu
+STR_023D_RANDOM_TOWN :{BLACK}Hazarda Urbo
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Konstruu urbon en hazarda loko
+STR_023F_INDUSTRY_GENERATION :{WHITE}Industria Generado
+STR_0240_COAL_MINE :{BLACK}Karbminejo
+STR_0241_POWER_STATION :{BLACK}Elektrejo
+STR_0242_SAWMILL :{BLACK}Segejo
+STR_0243_FOREST :{BLACK}Arbaro
+STR_0244_OIL_REFINERY :{BLACK}Oleproduktejo
+STR_0245_OIL_RIG :{BLACK}Oleplatformo
+STR_0246_FACTORY :{BLACK}Farejo
+STR_0247_STEEL_MILL :{BLACK}Åœtalejo
+STR_0248_FARM :{BLACK}Farmbieno
+STR_0249_IRON_ORE_MINE :{BLACK}Ferercminejo
+STR_024A_OIL_WELLS :{BLACK}Olefonto
+STR_024B_BANK :{BLACK}Banko
+STR_024C_PAPER_MILL :{BLACK}Paperejo
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}ManÄaĵfarejo
+STR_024E_PRINTING_WORKS :{BLACK}Printejo
+STR_024F_GOLD_MINE :{BLACK}Orminejo
+STR_0250_LUMBER_MILL :{BLACK}Lignejo
+STR_0251_FRUIT_PLANTATION :{BLACK}Fruktkulturejo
+STR_0252_RUBBER_PLANTATION :{BLACK}Kaŭĉukkulturejo
+STR_0253_WATER_SUPPLY :{BLACK}Akvofonto
+STR_0254_WATER_TOWER :{BLACK}Akvoturo
+STR_0255_DIAMOND_MINE :{BLACK}Diamantminejo
+STR_0256_COPPER_ORE_MINE :{BLACK}Kuproercminejo
+STR_0257_COTTON_CANDY_FOREST :{BLACK}SukerÅpinaĵaro
+STR_0258_CANDY_FACTORY :{BLACK}Dolĉaĵfarejo
+STR_0259_BATTERY_FARM :{BLACK}Bateribieno
+STR_025A_COLA_WELLS :{BLACK}Kolafonto
+STR_025B_TOY_SHOP :{BLACK}Ludilvendejo
+STR_025C_TOY_FACTORY :{BLACK}Ludilfarejo
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Plastikfontanaro
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Farejo de Amuzaj Trinkaĵoj
+STR_025F_BUBBLE_GENERATOR :{BLACK}Vezikgenerilo
+STR_0260_TOFFEE_QUARRY :{BLACK}Tofeminejo
+STR_0261_SUGAR_MINE :{BLACK}Sukerminejo
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Konstruu Karbminejon
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Konstruu Elektrejon
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Konstruu Segejon
+STR_0265_PLANT_FOREST :{BLACK}Plantu Arbaron
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Konstruu Oleproduktejon
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Konstruu Oleplatformon (Nur konstruebla rande de la mapo)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Konstruu Farejon
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Konstruu Åœtalejon
+STR_026A_CONSTRUCT_FARM :{BLACK}Konstruu Farmbienon
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Konstruu Ferercminejon
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Konstruu Olefonton
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Konstruu Bankon (Nur konstruebla en urboj pli grandaj ol 1200 enloÄantoj)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Konstruu Paperejon
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Konstruu ManÄaĵproduktejon
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Konstruu Printejon
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Konstruu Orminejon
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Konstruu Bankon (Nur konstruebla en urboj)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Konstruu Lignejon (por forigi praarbaron kaj produkti Lignon)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Plantu Fruktkulturejon
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Plantu Kaŭĉukkulturejon
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Konstruu Akvofonton
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Konstruu Akvoturon (Nur konstruebla en urboj)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Konstruu Diamantminejon
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Konstruu Kuproercminejon
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Plantu SukerÅpinaĵaron
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Konstruu Dolĉaĵfarejon
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Konstruu Bateribienon
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Konstruu Kolafonton
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Konstruu Ludilvendejon
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Konstruu Ludilfarejon
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Konstruu Plastikfontanaron
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Konstruu Farejon de Amuzaj Trinkaĵoj
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Konstruu Vezikgenerilon
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Konstruu Tofeminejon
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Konstruu Sukerminejon
+STR_0285_CAN_T_BUILD_HERE :{WHITE}Ne povas konstrui {STRING.n} ĉi tie...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...antaÅ­e konstruu urbon
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...nur unu permesiÄas en ĉiu urbo
+STR_0288_PLANT_TREES :{BLACK}Plantu arbojn
+STR_0289_PLACE_SIGN :{BLACK}Metu signon
+STR_028A_RANDOM_TREES :{BLACK}Hazardaj Arboj
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Hazarde plantu arbojn en la tuta lando
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Metu rokecajn lokojn en la lando
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Metu lumturon
+STR_028E_PLACE_TRANSMITTER :{BLACK}Metu transmitilon
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Difinu dezertan regionon.{}Premu kaj tenu CTRL por forigi Äin
+STR_CREATE_LAKE :{BLACK}Difinu akvoregionon.{}Inundos la ĉirkaŭon se marnivele
+STR_0290_DELETE :{BLACK}Forigu
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Plene forigu ĉi tiun urbon
+STR_0292_SAVE_SCENARIO :Konservu scenaron
+STR_0293_LOAD_SCENARIO :ÅœarÄu scenaron
+STR_0294_QUIT_EDITOR :Fermu kreilon
+STR_0295 :
+STR_0296_QUIT :Fermu
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Konservu scenaron, ÅarÄu scenaron, foriru el la kreilo, fermu
+STR_0298_LOAD_SCENARIO :{WHITE}ÅœarÄu Scenaron
+STR_0299_SAVE_SCENARIO :{WHITE}Konservu Scenaron
+STR_029A_PLAY_SCENARIO :{BLACK}Ludu Scenaron
+STR_PLAY_HEIGHTMAP :{BLACK}Ludu Altecmapon
+STR_PLAY_HEIGHTMAP_HINT :{BLACK}Startu novan ludon, uzante altecmapon por landaspekto
+STR_QUIT_SCENARIO_QUERY :{YELLOW}Ĉu vi certas ke vi volas forlasi ĉi tiun scenaron?
+STR_029C_QUIT_EDITOR :{WHITE}Fermu Kreilon
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...nur konstruebla en urboj havantaj pli ol 1200 enloÄantojn
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Movu la komencdaton 1 jaron posten
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Movu la komencdaton 1 jaron antaÅ­en
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...ambaÅ­ pontfinoj devas esti sur lando
+STR_02A1_SMALL :{BLACK}Malgranda
+STR_02A2_MEDIUM :{BLACK}Mezgranda
+STR_02A3_LARGE :{BLACK}Granda
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Elektu urban grandecon
+STR_02A5_TOWN_SIZE :{YELLOW}Urba grandeco:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Montru lastan mesaÄon aÅ­ novaĵon
+STR_OFF :Ne
+STR_SUMMARY :Resume
+STR_FULL :Plene
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Urbaro
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Veturilaj nomoj
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :DefaÅ­ltaj
+STR_02BF_CUSTOM :ÅœanÄitaj
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Konservu ÅanÄitajn nomojn
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Elekto de veturilaj nomoj
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Konservu ÅanÄitajn veturilajn nomojn
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Ludaj opcioj
+STR_02C5_DIFFICULTY_SETTINGS :Malfacilec-agordoj
+STR_02C7_CONFIG_PATCHES :Agordu flikojn
+STR_NEWGRF_SETTINGS :Agordoj de NewGRF
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Urbonomoj montriÄas
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Staciaj nomoj montriÄas
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Signoj montriÄas
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Trairejoj montriÄas
+STR_02D0_FULL_ANIMATION :{SETX 12}Plena animado
+STR_02D2_FULL_DETAIL :{SETX 12}Plenaj detaloj
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Travideblaj konstruaĵoj
+STR_TRANSPARENT_SIGNS :{SETX 12}Travideblaj staciaj signoj
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Landkvadrataj informoj
+STR_02D6 :
+STR_CONSOLE_SETTING :Åœaltu Tekstmodon
+STR_02D7_SCREENSHOT_CTRL_S :Ekranfoto (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Giganta Ekranfoto (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :Pri 'OpenTTD'
+############ range ends here
+
+STR_02DB_OFF :{BLACK}Malaktiva
+STR_02DA_ON :{BLACK}Aktiva
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Montru subvenciojn
+STR_02DD_SUBSIDIES :Subvencioj
+STR_02DE_MAP_OF_WORLD :Mondomapo
+STR_EXTRA_VIEW_PORT :Plia videjo
+STR_SIGN_LIST :Signolisto
+STR_02DF_TOWN_DIRECTORY :Urbaro
+STR_TOWN_POPULATION :{BLACK}Monda enloÄantaro: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Videjo {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Kopiu al videjo
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Kopiu la lokon de la ĉefvido al ĉi tiu videjo
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Gluu de videjo
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Gluu la lokon de ĉi tiu videjo al la ĉefvido
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Monunuoj
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Elekto de monunuoj
+STR_MEASURING_UNITS :{BLACK}Mezurunuoj
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Elekto de mezurunuoj
+STR_02E6_ROAD_VEHICLES :{BLACK}Vojveturiloj
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Elektu vojflankon kie veturu vojveturiloj
+STR_02E9_DRIVE_ON_LEFT :Veturu maldekstre
+STR_02EA_DRIVE_ON_RIGHT :Veturu dekstre
+STR_02EB_TOWN_NAMES :{BLACK}Urbonomoj
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Elektu stilon de urbonomoj
+
+STR_02F4_AUTOSAVE :{BLACK}AÅ­tomata konservado
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Elektu intervalon inter aÅ­tomataj konservadoj de la ludo
+STR_02F7_OFF :Malaktiva
+STR_02F8_EVERY_3_MONTHS :Je ĉiuj 3 monatoj
+STR_02F9_EVERY_6_MONTHS :Je ĉiuj 6 monatoj
+STR_02FA_EVERY_12_MONTHS :Je ĉiuj 12 monatoj
+STR_02FB_START_A_NEW_GAME :{BLACK}Startu novan ludon
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}ÅœarÄu konservitan ludon
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Kreu mem ludmondon/scenaron
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Elektu unuludantan ludon
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Elektu plurludantan ludon por 2-8 ludantoj
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Montru ludajn opciojn
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Montru malfacilec-opciojn
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Komencu novan ludon per propra scenaro
+STR_0304_QUIT :{BLACK}Fermu
+STR_0305_QUIT_OPENTTD :{BLACK}Fermu 'OpenTTD'
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...nur konstruebla en urboj
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Elektu 'moderan' landstilon
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Elektu 'sub-arktikan' landstilon
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Elektu 'sub-tropikan' landstilon
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Elektu 'ludlandan' landstilon
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Fondu konstruadon de nova industrio
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Industriaro
+STR_0313_FUND_NEW_INDUSTRY :Fondu novan industrion
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Fondu novan industrion
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...nur konstruebla en urboj
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...nur konstruebla en praarbaraj regionoj
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...nur konstruebla en dezertaj regionoj
+STR_0319_PAUSED :{YELLOW}* * PAŬZO * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Ekranfoto sukcese konserviÄis kiel '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}Ekranfoto fiaskis!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Aĉetu landon por onta uzo
+STR_032F_AUTOSAVE :{RED}AŬTOMATA KONSERVADO
+STR_SAVING_GAME :{RED}* * KONSERVAS LUDON * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}AnkoraÅ­ konservas,{}bv atendi Äis finiÄo!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Elektu programon de 'Facilvoja muziko'
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :Angle (Origine)
+STR_TOWNNAME_FRENCH :France
+STR_TOWNNAME_GERMAN :Germane
+STR_TOWNNAME_ADDITIONAL_ENGLISH :Angle (Aldone)
+STR_TOWNNAME_LATIN_AMERICAN :Latin-Amerike
+STR_TOWNNAME_SILLY :Angle (Stulte)
+STR_TOWNNAME_SWEDISH :Svede
+STR_TOWNNAME_DUTCH :Nederlande
+STR_TOWNNAME_FINNISH :Finne
+STR_TOWNNAME_POLISH :Pole
+STR_TOWNNAME_SLOVAKISH :Slovake
+STR_TOWNNAME_NORWEGIAN :Norvege
+STR_TOWNNAME_HUNGARIAN :Hungare
+STR_TOWNNAME_AUSTRIAN :AÅ­strie
+STR_TOWNNAME_ROMANIAN :Rumane
+STR_TOWNNAME_CZECH :Ĉeĥe
+STR_TOWNNAME_SWISS :Svise
+STR_TOWNNAME_DANISH :Dane
+STR_TOWNNAME_TURKISH :Turke
+STR_TOWNNAME_ITALIAN :Itale
+STR_TOWNNAME_CATALAN :Katalune
+############ end of townname region
+
+STR_CURR_GBP :Pundoj (£)
+STR_CURR_USD :Dolaroj ($)
+STR_CURR_EUR :Eŭroj (€)
+STR_CURR_YEN :Enoj (Â¥)
+STR_CURR_ATS :AÅ­striaj Åœilingoj (ATS)
+STR_CURR_BEF :Belgaj Frankoj (BEF)
+STR_CURR_CHF :Svisaj Frankoj (CHF)
+STR_CURR_CZK :Ĉeĥaj Korunoj (CZK)
+STR_CURR_DEM :Germanaj Markoj (DEM)
+STR_CURR_DKK :Danaj Kronoj (DKK)
+STR_CURR_ESP :Pesetoj (ESP)
+STR_CURR_FIM :Finnaj Markoj (FIM)
+STR_CURR_FRF :Frankoj (FRF)
+STR_CURR_GRD :Grekaj Draĥmoj (GRD)
+STR_CURR_HUF :Hungaraj Forintoj (HUF)
+STR_CURR_ISK :Islandaj Kronoj (ISK)
+STR_CURR_ITL :Italaj Liroj (ITL)
+STR_CURR_NLG :Nederlandaj Guldenoj (NLG)
+STR_CURR_NOK :Norvegaj Kronoj (NOK)
+STR_CURR_PLN :Polaj Zlotoj (PLN)
+STR_CURR_ROL :Rumanaj LeÅ­oj (ROL)
+STR_CURR_RUR :Rusaj Rubloj (RUR)
+STR_CURR_SIT :Slovenaj Tolaroj (SIT)
+STR_CURR_SEK :Svedaj Kronoj (SEK)
+STR_CURR_YTL :Turkaj Liroj (YTL)
+STR_CURR_SKK :Slovakaj Korunoj (SKK)
+STR_CURR_BRR :Brazilaj Realoj (BRL)
+
+STR_CURR_CUSTOM :Alia...
+
+STR_OPTIONS_LANG :{BLACK}Lingvo
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Elektu uzotan interfacan lingvon
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Plena ekrano
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}Ŝaltu ĉi tiun kvadrateton por plenekrane ludi OpenTTD
+
+STR_OPTIONS_RES :{BLACK}Ekrana montrogrando
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Elektu uzotan ekranan montrograndon
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Ekranfota formato
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Elektu uzotan ekranfotan formaton
+
+STR_AUTOSAVE_1_MONTH :Je ĉiu monato
+STR_AUTOSAVE_FAILED :{WHITE}Fiaskis aÅ­tomate konservi
+
+STR_MONTH_JAN :Januaro
+STR_MONTH_FEB :Februaro
+STR_MONTH_MAR :Marto
+STR_MONTH_APR :Aprilo
+STR_MONTH_MAY :Majo
+STR_MONTH_JUN :Junio
+STR_MONTH_JUL :Julio
+STR_MONTH_AUG :AÅ­gusto
+STR_MONTH_SEP :Septembro
+STR_MONTH_OCT :Oktobro
+STR_MONTH_NOV :Novembro
+STR_MONTH_DEC :Decembro
+
+STR_HEADING_FOR_STATION :{LTBLUE}Irante al {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}Irante al {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Sen ordenoj
+STR_NO_ORDERS_VEL :{LTBLUE}Sen ordenoj, {VELOCITY}
+
+STR_PASSENGERS :pasaÄeroj
+STR_BAGS :sakoj
+STR_TONS :tunoj
+STR_LITERS :litroj
+STR_ITEMS :pecoj
+STR_CRATES :kestoj
+STR_RES_OTHER :alia
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Ne povas dividi ordenliston...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Ne povas kopii ordenliston...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - Fino de Dividitaj Ordenoj - -
+
+STR_TRAIN_IS_LOST :{WHITE}Trajno {COMMA} perdiÄis.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}La gajno de trajno {COMMA} estis {CURRENCY} lastjare
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}EÅ­ropa Mona Unio!{}{}De nun uziÄos la EÅ­ro kiel monunuo por ĉiutagaj montransskriboj en via lando!
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Trajno {COMMA} havas maltro da ordenoj enplane
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}Trajno {COMMA} havas malplenan ordenon
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}Trajno {COMMA} havas duoblajn ordenojn
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}Trajnno {COMMA} havas nevalidan stacion en la ordenoj
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}Vojveturilo {COMMA} havas maltro da ordenoj enplane
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}Vojveturilo {COMMA} havas malplenan ordenon
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}Vojveturilo {COMMA} havas duoblajn ordenojn
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}Vojveturilo {COMMA} havas nevalidan stacion en la ordenoj
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}Åœipo {COMMA} havas maltro da ordenoj enplane
+STR_SHIP_HAS_VOID_ORDER :{WHITE}Åœipo {COMMA} havas malplenan ordenon
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}Åœipo {COMMA} havas duoblajn ordenojn
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}Åœipo {COMMA} havas nevalidan stacion en la ordenoj
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}Aviadilo {COMMA} havas maltro da ordenoj enplane
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}Aviadilo {COMMA} havas malplenan ordenon
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}Aviadilo {COMMA} havas duoblajn ordenojn
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}Aviadilo {COMMA} havas nevalidan stacion en la ordenoj
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}AÅ­tomata novigo fiaskis al trajno {COMMA} (monlimo)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}AÅ­tomata novigo fiaskis al vojveturilo {COMMA} (monlimo)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}AÅ­tomata novigo fiaskis al Åipo {COMMA} (monlimo)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}AÅ­tomata novigo fiaskis al aviadilo {COMMA} (monlimo)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}Trajno {COMMA} tro longas post ÅanÄo
+
+STR_CONFIG_PATCHES :{BLACK}Agordu Flikojn
+STR_CONFIG_PATCHES_TIP :{BLACK}Agordu la flikojn
+STR_CONFIG_PATCHES_CAPTION :{WHITE}Agordu Flikojn
+
+STR_CONFIG_PATCHES_OFF :Malaktiva
+STR_CONFIG_PATCHES_ON :Aktiva
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Montru veturilrapidecon en statbreto: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Permesu konstrui sur kliniÄoj kaj bordoj: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Permesu pli realgrandaj kaptoregionoj: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Permesu forigon de pli da urbaj vojoj, pontoj ktp: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Permesu konstrui tre longajn trajnojn: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Permesu realecan rapidigon por trajnoj: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Malpermesu trajnojn kaj Åipojn ort-turniÄi: {ORANGE}{STRING} {LTBLUE} (bezonas NPF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Ligu stacidomojn konstruatajn unu apud la alia: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Ĉe 'plene ÅarÄu' ekiru se ajna ÅarÄo estas plena: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Uzu plibonigitan ÅarÄalgoritmon: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GRADUAL_LOADING :{LTBLUE}LaÅ­grade ÅarÄu veturilojn: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Inflacio: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Nur liveru ÅarÄon al stacio se estas peto: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Permesu konstruadon de tre longaj pontoj: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Permesu ordenojn por iri al deponejo: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Permesu konstruadon de fontmalerialaj industrioj: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Permesu pliajn similajn industriojn en la sama urbo: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Samtipaj industrioj povas esti konstruataj proksime unu de la alia: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Ĉiam montru longan daton en la statbreto: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Montru signalojn veturflanke: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Montru financan fenestron fine de la jaro: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}TTDPatch-amika nonstop-traktado: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Vojveturila vicigo (kun kvantum-efektoj): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Ŝovu fenestron se la muso estas ĉe la rando: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Permesu subaĉeti la lokajn estrojn: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Nekonformaj stacioj: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Nova Äenerala vojtrovado (NPF, superas NTP): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FREIGHT_TRAINS :{LTBLUE}Pezpliigo pro ÅarÄo por imiti pezajn trajnojn: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Ĉiam permesu malgrandajn flughavenojn: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Avertu se trajno perdiÄas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Atentu veturilajn ordenojn: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :ne
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :jes, escepte de haltigitaj veturiloj
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :de ĉiuj veturiloj
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Avertu se trajno negative enspezas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Veturiloj neniam eluziÄas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}AÅ­tomate anstataÅ­u veturilon se malnoviÄas
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}AnstataÅ­u {ORANGE}{STRING}{LTBLUE} monatojn antaÅ­/post maksimuma aÄo de veturilo
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Minimuma mono por anstataÅ­ado: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}DaÅ­ro de erar-mesaÄo: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Montru enloÄantaron en urbnomindikilo: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Nevideblaj arboj (ĉe travideblaj konstruaĵoj): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Landgenerilo: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :Origina
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis
+STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}Maksimuma distanco de rando por Oleproduktejoj {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}NeÄregiona alto: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN :{LTBLUE}Nereguleco de tereno (nur por TerraGenesis) : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Tre Regule
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH :Regule
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH :Neregule
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :Malregule
+STR_CONFIG_PATCHES_TREE_PLACER :{LTBLUE}Arbometa algoritmo: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TREE_PLACER_NONE :Nenia
+STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL :Origina
+STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED :Plibonigita
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION :{LTBLUE}Altecmapa turniÄo: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Maldekstrume
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE :Dekstrume
+STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT :{LTBLUE}Kiom alta fariÄos scenara mapo: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Maksimuma stacivasteco: {ORANGE}{STRING} {RED}Atentu: Pli alte, malpli rapide
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}AÅ­tomate prizorgu helikopterojn sur helikopterejoj: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Ligu landaspekta breto al rela, voja, akva kaj flughavena bretoj: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Inversigu skroldirekton: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Montru mezuran konsilbalonon ĉe uzo de konstruaj iloj: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Montru kompaniajn liverojn: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES_NONE :Neniuj
+STR_CONFIG_PATCHES_LIVERIES_OWN :Propra kompanio
+STR_CONFIG_PATCHES_LIVERIES_ALL :Ĉiuj kompanioj
+STR_CONFIG_PATCHES_PREFER_TEAMCHAT :{LTBLUE}Preferu teambabiladon per <ENTER>: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Trajna maksimumo por ĉiu ludanto: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Vojveturila maksimumo por ĉiu ludanto: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}Aviadila maksimumo por ĉiu ludanto: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}Ŝipa maksimumo por ĉiu ludanto: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Malebligu trajnojn por la komputilo: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Malebligu vojveturilojn por la komputilo: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Malebligu aviadilojn por la komputilo: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Malebligu Åipojn por la komputilo: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Aktivigu novan AI (alfa): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Permesu komputilludantojn ĉe pluraj ludantoj (eksperimente): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}DefaÅ­lta prizorgintervalo por trajnoj: {ORANGE}{STRING} tagoj/%
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}DefaÅ­lta prizorgintervalo por trajnoj: {ORANGE}malaktiva
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}DefaÅ­lta prizorgintervalo por vojveturiloj: {ORANGE}{STRING} tagoj/%
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}DefaÅ­lta prizorgintervalo por vojveturiloj: {ORANGE}malaktiva
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}DefaÅ­lta prizorgintervalo por aviadiloj: {ORANGE}{STRING} tagoj/%
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}DefaÅ­lta prizorgintervalo por aviadiloj: {ORANGE}malaktiva
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}DefaÅ­lta prizorgintervalo por Åipoj: {ORANGE}{STRING} tagoj/%
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}DefaÅ­lta prizorgintervalo por Åipoj: {ORANGE}malaktiva
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}MalÅaltu prizorgadon se rompiÄoj ne okazas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Aktivigu vagonajn rapideclimojn: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}MalÅaltu elektrajn relojn: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Koloraj novaĵoj aperas en: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Komenca jaro: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}Finu ludon en: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Aktivigu glatan ekonomion (pliaj, etaj ÅanÄoj)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Permesu aĉetadon de dividaĵoj en aliaj kompanioj
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Tirante metu signalojn je ĉiuj: {ORANGE}{STRING} kvadrado(j)
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Loko de ĉefa ilbreto: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Maldekstre
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Centre
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Dekstre
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Fenestroliga distanco: {ORANGE}{STRING} px
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Fenestroliga distanco: {ORANGE}malaktiva
+
+STR_CONFIG_PATCHES_GUI :{BLACK}Interfaco
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Konstruado
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Veturiloj
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Stacioj
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Ekonomio
+STR_CONFIG_PATCHES_AI :{BLACK}Konkurantoj
+
+STR_CONFIG_PATCHES_DISABLED :malaktiva
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}ÅœanÄu agord-valoron
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Iuj aŭ ĉiuj defaŭltaj prizorgintervaloj ne validas laŭ la agordoj! 5-90% kaj 30-800 tagoj validas
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}Uzu YAPF por Åipoj: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}Uzu YAPF por vojveturiloj: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}Uzu YAPF por trajnoj: {ORANGE}{STRING}
+
+STR_TEMPERATE_LANDSCAPE :Modera landaspekto
+STR_SUB_ARCTIC_LANDSCAPE :Arktikeca landaspekto
+STR_SUB_TROPICAL_LANDSCAPE :Tropikeca landaspekto
+STR_TOYLAND_LANDSCAPE :Ludolandaspekto
+
+STR_CHEATS :{WHITE}Filudaĵoj
+STR_CHEATS_TIP :{BLACK}La kvadratetoj indikas ĉu vi jam uzis la filudaĵon antaŭe.
+STR_CHEATS_WARNING :{BLACK}Atentu! Vi perfidos viajn kunulajn konkurantojn. Memoru ke io tia rememoriÄos eterne.
+STR_CHEAT_MONEY :{LTBLUE}Altigu monkvanton per {CURRENCY64}
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Ludu kiel ludanto: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Magia forigilo (forviÅu industriojn, nemoveblaĵojn): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Tuneloj rajtas kruciÄi unu kun la alia: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Konstruado eblas dum paÅ­zo: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Jet-aviadiloj ne kraÅos (frekvente) sur etaj flughavenoj: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}ÅœanÄu klimaton: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}ÅœanÄu daton: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}Ebligu ÅanÄi produktvalorojn: {ORANGE}{STRING}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}Irante al {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Irante al {WAYPOINT}, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :Iru laÅ­ {WAYPOINT}
+STR_GO_NON_STOP_TO_WAYPOINT :Iru senhalte laÅ­ {WAYPOINT}
+
+STR_WAYPOINTNAME_CITY :Trairejo {TOWN}
+STR_WAYPOINTNAME_CITY_SERIAL :Trairejo {TOWN} #{COMMA}
+STR_LANDINFO_WAYPOINT :Trairejo
+
+STR_WAYPOINT :{WHITE}Trairejo
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Elektu trairejan tipon
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}ÅœanÄu trairejan nomon
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Ne povas ÅanÄi trairejan nomon...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}ÅœanÄu relon al trairejo
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Ne povas konstrui trajnan trairejon ĉi tie...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Ne povas forigi trajnan trairejon ĉi tie...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Konstruu fervojojn per AÅ­tomata relo
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}...mankas urboj en ĉi tiu scenaro
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}Ĉu vi certas ke vi volas krei hazardan landaspekton?
+STR_MANY_RANDOM_TOWNS :{BLACK}Multaj hazardaj urboj
+STR_RANDOM_TOWNS_TIP :{BLACK}Kovru la mapon per hazarde metitajn urbojn
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Multaj hazardaj industrioj
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Kovru la mapon per hazarde metitajn industriojn
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Ne povas generi industriojn...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Malfermu la landaspektan ilbreton por (mal)altigi landon, planti arbojn ktp.
+STR_LANDSCAPING_TOOLBAR :{WHITE}Landaspekto
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Ebenigu landon
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Arboj de hazardaj tipoj
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}Metu arbojn de hazardaj tipoj
+
+STR_CANT_BUILD_CANALS :{WHITE}Ne povas konstrui kanalojn ĉi tie...
+STR_BUILD_CANALS_TIP :{BLACK}Konstruu kanalojn. Premu CTRL por meti mar-kvadratojn (nur marnivele.)
+STR_LANDINFO_CANAL :Kanalo
+
+STR_CANT_BUILD_LOCKS :{WHITE}Ne povas konstrui kluzojn ĉi tie...
+STR_BUILD_LOCKS_TIP :{BLACK}Konstruu kluzojn
+STR_LANDINFO_LOCK :Kluzo
+
+STR_BUOY_IS_IN_USE :{WHITE}...buo estas uzata
+
+STR_LANDINFO_COORDS :{BLACK}Koordinatoj: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Ne povas forigi stacidomeron...
+STR_CANT_CONVERT_RAIL :{WHITE}Ne povas transigi reltipon ĉi tie...
+STR_CONVERT_RAIL_TIP :{BLACK}Transigu reltipon
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Tiru la lokomotivon ĉi tien por vendi la tutan trajnon.
+
+STR_DRAG_DROP :{BLACK}Tiru k metu
+STR_STATION_DRAG_DROP :{BLACK}Tiru por konstrui stacidomon
+STR_SELECT_STATION_CLASS_TIP :{BLACK}Elektu stacidomklason por montri
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Elektu stacidomtipon por konstrui
+
+STR_FAST_FORWARD :{BLACK}Rapide pluirigu la ludon
+STR_MESSAGE_HISTORY :{WHITE}MesaÄa Historio
+STR_MESSAGE_HISTORY_TIP :{BLACK}Listo da aktualaj novaĵoj
+STR_MESSAGES_DISABLE_ALL :{BLACK}Malaktivigu ĉiujn
+STR_MESSAGES_ENABLE_ALL :{BLACK}Aktivigu ĉiujn
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Konstruu Karbminejon
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Plantu Arbaron
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Konstruu Oleplatformon
+STR_CONSTRUCT_FARM_TIP :{BLACK}Fondu Farmbienon
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Konstruu Kuproercminejo
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Boru por Oleo
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Konstruu Orminejon
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Konstruu Diamantminejon
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Konstruu Ferercminejon
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Fondu Fruktkulturejon
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Fondu Kaŭĉukkulturejon
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Fondu Akvofonton
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Plantu SukerÅpinaĵaron
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}Fondu Bateribienon
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Boru por Kolao
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Fondu Plastikfontanaron
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Konstruu Vezikgenerilon
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Fondu Tofeminejon
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Konstruu Sukerminejon
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Industrioj
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA}% transportite)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA}%/{COMMA}% transportite)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}...tro proksime al alia industrio
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Transformu trajnon por ke Äi portu alian ÅarÄon
+STR_RAIL_REFIT_VEHICLE :{BLACK}Transformu trajnon
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Elektu ÅarÄospecon portotan de la trajno
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Transformu trajnon por porti la elektitan ÅarÄotipon
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Ne povas transformi la trajnon...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Prizorgintervala procentaĵo: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}ÅœanÄu produktadon
+
+TEMP_AI_IN_PROGRESS :{WHITE}Bonvenon al la novkreata AI. Se vi vidas problemojn, ekranfotu tion kaj metu Äin en la forumon.
+TEMP_AI_ACTIVATED :{WHITE}Atentu: la nova AI ankoraÅ­ estas alfaversia! Nur ÅarÄaÅ­toj kaj busoj funkcias!
+TEMP_AI_MULTIPLAYER :{WHITE}Atentu: implementado ankoraÅ­ estas eksperimenta (per nova AI). Bv raporti problemojn al truelight@openttd.org.
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Pluraj ludantoj
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Ludantnomo:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}Ĉi tio estas la nomo per kiu la aliaj ekkonas vin
+STR_NETWORK_CONNECTION :{BLACK}Konekto:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Elektu inter interreta kaj lokareta ludo
+
+STR_NETWORK_START_SERVER :{BLACK}Startu servilon
+STR_NETWORK_START_SERVER_TIP :{BLACK}Startu propran servilon
+
+STR_NETWORK_GAME_NAME :{BLACK}Nomo
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Nomo de la ludo
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Lingvo, servila versio ktp.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Alklaku ludon el la listo por elekti Äin
+
+STR_NETWORK_FIND_SERVER :{BLACK}Trovu servilon
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Serĉu reton por servilo
+STR_NETWORK_ADD_SERVER :{BLACK}Aldonu servilon
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Aldonas servilon al la listo kiu ĉiam estos kontrolata pri kurantaj ludoj.
+STR_NETWORK_ENTER_IP :{BLACK}Enigu la adreson de la gastiganto
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Klientoj
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Klientoj surrete / maksimume{}Kompanioj surrete / maksimume
+STR_NETWORK_GAME_INFO :{SILVER}LUDINFORMOJ
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Klientoj: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Lingvo: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Tegolaro: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Mapgrandeco: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}Servila versio: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}Servila adreso: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Komenca dato: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Nuna dato: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Protektata per pasvorto!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}SERVILO NE SURRETAS
+STR_NETWORK_SERVER_FULL :{SILVER}SERVILO PLENAS
+STR_NETWORK_VERSION_MISMATCH :{SILVER}VERSIOJ NE KONGRUAS
+STR_NETWORK_GRF_MISMATCH :{SILVER}MISO PRI NEWGRF
+
+STR_NETWORK_JOIN_GAME :{BLACK}AliÄu al la ludo
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}Komencu novan ludon por pluraj ludantoj
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Ludnomo:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}La ludnomo estos montrata al aliaj ludantoj en la ludelektejo por plurludantaj ludoj.
+STR_NETWORK_SET_PASSWORD :{BLACK}Agordu pasvorton
+STR_NETWORK_PASSWORD_TIP :{BLACK}Protektu vian ludon per pasvorto por ne publike atingebligi Äin
+STR_NETWORK_SELECT_MAP :{BLACK}Elektu mapon:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}Kiun mapon vi volas ludi?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}Klienta maksimumo:
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Elektu klientan maksimumon. Ne ĉiuj lokoj estas plenigendaj
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :Loka reto
+STR_NETWORK_INTERNET :Interreto
+STR_NETWORK_LAN_INTERNET :Loka reto / Interreto
+STR_NETWORK_INTERNET_ADVERTISE :Interreto (reklamu)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 ludantoj
+STR_NETWORK_1_PLAYERS :1 ludanto
+STR_NETWORK_2_PLAYERS :2 ludantoj
+STR_NETWORK_3_PLAYERS :3 ludantoj
+STR_NETWORK_4_PLAYERS :4 ludantoj
+STR_NETWORK_5_PLAYERS :5 ludantoj
+STR_NETWORK_6_PLAYERS :6 ludantoj
+STR_NETWORK_7_PLAYERS :7 ludantoj
+STR_NETWORK_8_PLAYERS :8 ludantoj
+STR_NETWORK_9_PLAYERS :9 ludantoj
+STR_NETWORK_10_PLAYERS :10 ludantoj
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}Kompania maksimumo:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Limu la servilon al certa kvanto da kompanioj
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}Spektanta maksimumo:
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Limigu la servilon al certa kvanto da spektantoj
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Parolata lingvo:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Aliaj ludantoj scios kiu lingvo paroliÄas en la servilo
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}Startu Ludon
+STR_NETWORK_START_GAME_TIP :{BLACK}Komencu novan retan ludon de hazarda mapo, aÅ­ scenaro
+STR_NETWORK_LOAD_GAME :{BLACK}ÅœarÄu Ludon
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Restartu antaÅ­an plurludantan ludon (certigu ke vi kiel la korekta ludanto konektu)
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Ajna
+STR_NETWORK_LANG_ENGLISH :Angla
+STR_NETWORK_LANG_GERMAN :Germana
+STR_NETWORK_LANG_FRENCH :Franca
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Atendejo por plurludantaj ludoj
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Preparas por aliÄi: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}Listo da kompanioj haveblaj en ĉi tiu ludo. Vi povas aliÄi al unu aÅ­ komenci novan kompanion se restas loko
+STR_NETWORK_NEW_COMPANY :{BLACK}Nova kompanio
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Kreu novan kompanion
+STR_NETWORK_SPECTATE_GAME :{BLACK}Spektu ludon
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Spektu la ludon kiel spektanto
+STR_NETWORK_JOIN_COMPANY :{BLACK}AliÄu al kompanio
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Helpu manaÄi ĉi tiun kompanion
+STR_NETWORK_REFRESH :{BLACK}RefreÅigu servilon
+STR_NETWORK_REFRESH_TIP :{BLACK}RefreÅigu servilajn informojn
+
+STR_NETWORK_COMPANY_INFO :{SILVER}KOMPANIAJ INFORMOJ
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Kompaninomo: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}EnaÅ­guro: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}Kompanivaloro: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Nuna monstato: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Lastjara enspezo: {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}Rendimento: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}Veturiloj: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Stacioj: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Ludantoj: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}Konektante...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) Konektante..
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Rajtigante..
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Atendante..
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) ElÅutante mapon..
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Procesante datenojn..
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) Registante..
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Kaptante ludinformojn..
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Kaptante kompaniajn informojn..
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} kliento{P "" j} antaÅ­ vi
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} kilobitokoj Äis nun elÅutiÄis
+
+STR_NETWORK_DISCONNECT :{BLACK}Malkonektu
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Enigu la monkvanton kiun vi volas doni
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Servilo estas protektata. Enigu pasvorton
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Kompanio estas protektata. Enigu pasvorton
+STR_NETWORK_CLIENT_LIST :{WHITE}Klientlisto
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE} Ne trovis retstirilojn aÅ­ kompiliÄis sen ENABLE_NETWORK
+STR_NETWORK_ERR_NOSERVER :{WHITE} Ne troveblas ajna reta ludo
+STR_NETWORK_ERR_NOCONNECTION :{WHITE} La servilo ne respondis al la peto
+STR_NETWORK_ERR_DESYNC :{WHITE} Retluda sinkronigado fiaskis
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} Perdis konekton al Retludo
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} Ne povis ÅarÄi konservitan ludon
+STR_NETWORK_ERR_SERVER_START :{WHITE} Ne povis starti la servilon
+STR_NETWORK_ERR_CLIENT_START :{WHITE} Ne povis konekti
+STR_NETWORK_ERR_TIMEOUT :{WHITE} Konekto #{NUM} ekstertempiÄis
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE} Protokoleraro fariÄis kaj la konekto fermiÄis
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE} La revidaĵo de la kliento ne kongruas kun la servila revidaĵo
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} MalÄusta pasvorto
+STR_NETWORK_ERR_SERVER_FULL :{WHITE} La servilo plenas
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} Oni forbaris vin de la servilo
+STR_NETWORK_ERR_KICKED :{WHITE} Oni forbatis vin de la ludo
+STR_NETWORK_ERR_CHEATER :{WHITE} Vi ne rajtas filudi en ĉi tiu servilo
+
+STR_NETWORK_ERR_LEFT :foriris de la ludo
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :Äenerala eraro
+STR_NETWORK_ERR_CLIENT_DESYNC :sensinkroneca eraro
+STR_NETWORK_ERR_CLIENT_SAVEGAME :ne povis ÅarÄi mapon
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :konekto perdiÄis
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :protokola eraro
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :ne rajtigite
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :ricevis strangan pakaĵon
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :malÄusta revidaĵo
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :nomo jam uziÄas
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :malÄusta pasvorto
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :malÄusta ludant-id en FarKomando
+STR_NETWORK_ERR_CLIENT_KICKED :forbatite de servilo
+STR_NETWORK_ERR_CLIENT_CHEATER :provis uzi filudaĵon
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :servilo plenas
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :aliÄis al la ludo
+STR_NETWORK_GIVE_MONEY :donis iom da mono al via kompanio ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :vi donis al {STRING} iom da mono ({CURRENCY})
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Teamo] :
+STR_NETWORK_CHAT_COMPANY :[Teamo] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Teamo] Al {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[Private] :
+STR_NETWORK_CHAT_CLIENT :[Private] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[Private] Al {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[Ĉiuj] :
+STR_NETWORK_CHAT_ALL :[Ĉiuj] {STRING}: {GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :ÅanÄis sian nomon al
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE} La servilo fermis la sesion
+STR_NETWORK_SERVER_REBOOT :{WHITE} La servilo restartiÄas...{}Bonvolu atendi...
+
+STR_NETWORK_SERVER :Servilo
+STR_NETWORK_CLIENT :Kliento
+STR_NETWORK_SPECTATORS :Spektantoj
+
+STR_NETWORK_CLIENTLIST_NONE :(neniu)
+STR_NETWORK_CLIENTLIST_KICK :Forbatu
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Donu monon
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Parolu al ĉiuj
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Parolu al kompanio
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Privata mesaÄo
+
+
+STR_NETWORK_SEND :{BLACK}Sendu
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}X-grandeco de la mapo: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Y-grandeco de la mapo: {ORANGE}{STRING}
+
+
+##### PNG-MAP-Loader
+
+STR_PNGMAP_ERROR :{WHITE}Ne povas ÅarÄi landaspekton de PNG...
+STR_PNGMAP_ERR_FILE_NOT_FOUND :{WHITE}...dosiero ne troviÄis.
+STR_PNGMAP_ERR_IMAGE_TYPE :{WHITE}...ne povis transformi bildtipon. Necesas 8-bita aÅ­ 24-bita PNG-bildo.
+STR_PNGMAP_ERR_MISC :{WHITE}...io simple fiaskis. Pardonu. (probable aĉa dosiero)
+
+STR_BMPMAP_ERROR :{WHITE}Ne povas ÅarÄi landaspekton el BMP...
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}...ne povis transigi bildotipon.
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Kosto: {CURRENCY}
+STR_0801_COST :{RED}Kosto: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Enspezo: {CURRENCY}
+STR_0803_INCOME :{GREEN}Enspezo: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Transigo: {CURRENCY}
+STR_FEEDER :{YELLOW}Transigo: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Estimated Cost: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Atendata enspezo: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Ne povas altigi landon ĉi tie...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Ne povas malaltigi landon ĉi tie...
+STR_080A_ROCKS :Rokoj
+STR_080B_ROUGH_LAND :Malglata lando
+STR_080C_BARE_LAND :Nuda lando
+STR_080D_GRASS :Herbo
+STR_080E_FIELDS :Kampoj
+STR_080F_SNOW_COVERED_LAND :NeÄkovrita lando
+STR_0810_DESERT :Dezerto
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Lando ne Äuste kliniÄas
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Neebla trakkombino
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}Elkavigo damaÄus tunelon
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Jam marnivele
+STR_1004_TOO_HIGH :{WHITE}Tro alte
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Nekonvena fervojtrako
+STR_1007_ALREADY_BUILT :{WHITE}...jam konstruite
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}AntaÅ­e forigu relon
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Konstruado de Reloj
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Konstruado de Elektraj Reloj
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Konstruado de Unurela Fervojo
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}Konstruado de Magleva Fervojo
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Elektu Relan Ponton
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Ne povas konstrui trajndeponejon ĉi tie...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Ne povas konstrui stacidomon ĉi tie...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Ne povas konstrui signalojn ĉi tie...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Ne povas konstrui relojn ĉi tie...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Ne povas forigi relojn de ĉi tie...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Ne povas forigi signalojn de ĉi tie...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Trajndeponeja Orientado
+STR_1015_RAILROAD_CONSTRUCTION :Fervoja Konstruado
+STR_TOOLB_ELRAIL_CONSTRUCTION :Elektrofervoja konstruado
+STR_1016_MONORAIL_CONSTRUCTION :Unurelfervoja konstruado
+STR_1017_MAGLEV_CONSTRUCTION :Maglevfervoja konstruado
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Konstruu relojn
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Konstruu trajndeponejon (por konstrui kaj prizorgi trajnojn)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Konstruu stacidomon
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Konstruu signalojn
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Konstruu fervojan ponton
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Konstruu fervojtunelon
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Elektu inter konstruado kaj forigado de reloj kaj signaloj
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Pontelekton - alklaku vian preferatan ponton por konstrui Äin
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Elektu deponejan orientadon
+STR_1021_RAILROAD_TRACK :Reloj
+STR_1023_RAILROAD_TRAIN_DEPOT :Trajndeponejo
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...regiono estas posedata de alia kompanio
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :Reloj kun normalaj signaloj
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :Reloj kun antaÅ­-signaloj
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :Reloj kun elir-signaloj
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :Reloj kun kombin-signaloj
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}AntaÅ­e forigu vojon
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Aktivas vojprilaborado
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Vojkonstruado
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Elektu Vojan Ponton
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Ne povas konstrui vojon ĉi tie...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Ne povas forigi vojon de ĉi tie...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Deponeja Orientado
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Ne povas konstrui vojveturilan deponejon ĉi tie...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Ne povas konstrui bushaltejon...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Ne povas konstrui ÅarÄstacion...
+STR_180A_ROAD_CONSTRUCTION :Vojkonstruado
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Konstruu vojeron
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Konstruu vojveturilan deponejon (por konstrui kaj prizorgi veturilojn)
+STR_180D_BUILD_BUS_STATION :{BLACK}Konstruu bushaltejon
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Konstruu ÅarÄaÅ­tan ÅarÄejon
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Konstruu vojponton
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Konstruu vojtunelon
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Ĉu konstrui ĉu forigi por vojkonstruado
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Elektu vojveturildeponejan direkton
+STR_1814_ROAD :Vojo
+STR_1815_ROAD_WITH_STREETLIGHTS :Vojo kun lanternoj
+STR_1816_TREE_LINED_ROAD :Vojo kun arboj apude
+STR_1817_ROAD_VEHICLE_DEPOT :Vojveturila deponejo
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :KruciÄo inter vojo kaj relo
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Urboj
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Antaŭe forigu konstruaĵon
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}EnloÄantoj: {ORANGE}{COMMA}{BLACK} Domoj: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Renomu Urbon
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Ne povas renomi urbon...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}La loka estraro de {TOWN} rifuzas permesi ĉi tion
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Urbonomoj - alklaku nomon por centre vidi la urbon
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centre en la ĉefvido vidu la urbon
+STR_200C_CHANGE_TOWN_NAME :{BLACK}ÅœanÄu urbonomon
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}PasaÄeroj lastmonate: {ORANGE}{COMMA}{BLACK} maksimume: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}PoÅto lastmonate: {ORANGE}{COMMA}{BLACK} maksimume: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Vasta oficejaro
+STR_2010_OFFICE_BLOCK :Oficejaro
+STR_2011_SMALL_BLOCK_OF_FLATS :Malgranda domturaro
+STR_2012_CHURCH :PreÄejo
+STR_2013_LARGE_OFFICE_BLOCK :Granda oficejaro
+STR_2014_TOWN_HOUSES :Urbaj domoj
+STR_2015_HOTEL :Hotelo
+STR_2016_STATUE :Statuo
+STR_2017_FOUNTAIN :Fontano
+STR_2018_PARK :Parko
+STR_2019_OFFICE_BLOCK :Oficejaro
+STR_201A_SHOPS_AND_OFFICES :Butikoj kaj oficejoj
+STR_201B_MODERN_OFFICE_BUILDING :Moderna oficeja konstruaĵo
+STR_201C_WAREHOUSE :Varvendejo
+STR_201D_OFFICE_BLOCK :Oficejaro
+STR_201E_STADIUM :Stadiono
+STR_201F_OLD_HOUSES :Antikvaj domoj
+STR_2020_LOCAL_AUTHORITY :{BLACK}Lokaj estroj
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Montru informojn pri lokaj estroj
+STR_2022_LOCAL_AUTHORITY :{WHITE}Lokaj estroj de {TOWN}
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Takso de transportkompanioj:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Subvencioj
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Subvencioj haveblas por jenaj servoj:
+STR_2027_FROM_TO :{ORANGE}{STRING} de {STRING} al {STRING}
+STR_2028_BY :{YELLOW} (antaÅ­ {DATE_SHORT})
+STR_202A_NONE :{ORANGE}Neniu
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Servoj subvenciataj:
+STR_202C_FROM_TO :{ORANGE}{STRING} de {STATION} al {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, Äis {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}Subvencia oferto ne plu validas:{}{}{STRING} de {STRING} al {STRING} ne estos subvenciata.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Subvencio retiriÄis:{}{}Servo de {STRING} de {STATION} al {STATION} ne plu estas subvenciata.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Subvencia oferto:{}{}Unua servo de {STRING} de {STRING} al {STRING} ricevos subvencion de jaro de la lokaj estroj!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subvencio doniÄis al {COMPANY}!{}{}Servo de {STRING} de {STATION} al {STATION} ricevis pliaĵon de 50% por la sekva jaro!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subvencio doniÄis al {COMPANY}!{}{}Servo de {STRING} de {STATION} al {STATION} ricevis duoblajn pagojn por la sekva jaro!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subvencio doniÄis al {COMPANY}!{}{}Servo de {STRING} de {STATION} al {STATION} ricevis trioblajn pagojn por la sekva jaro!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subvencio doniÄis al {COMPANY}!{}{}Servo de {STRING} de {STATION} al {STATION} ricevis kvaroblajn pagojn por la sekva jaro!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}La lokaj estroj de {TOWN} rifuzas permesi konstruadon de plia flughaveno ĉi-urbe
+STR_2036_COTTAGES :Plezurdomoj
+STR_2037_HOUSES :Domoj
+STR_2038_FLATS :Domturoj
+STR_2039_TALL_OFFICE_BLOCK :Vasta oficejaro
+STR_203A_SHOPS_AND_OFFICES :Butikoj kaj oficejoj
+STR_203B_SHOPS_AND_OFFICES :Butikoj kaj oficejoj
+STR_203C_THEATER :Teatro
+STR_203D_STADIUM :Stadiono
+STR_203E_OFFICES :Oficejoj
+STR_203F_HOUSES :Domoj
+STR_2040_CINEMA :Kinejo
+STR_2041_SHOPPING_MALL :Butikaro
+STR_2042_DO_IT :{BLACK}Faru
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}Fareblaĵoj en ĉi tiu urbo - alklaku por pliaj detaloj
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Plenumu la elektitan agon el la ĉi-supera listo
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Haveblaj agoj:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Malgranda reklama kampanjo
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Mezgranda reklama kampanjo
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Granda reklama kampanjo
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Fondu lokan vojrekonstruadon
+STR_204A_BUILD_STATUE_OF_COMPANY :Konstruu statuon de la kompaniestro
+STR_204B_FUND_NEW_BUILDINGS :Fondu novajn konstruaĵojn
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Aĉetu ekskluzivan transportrajton
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Subaĉetu la lokajn estrojn
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Komencu malgrandan lokan reklamadon, por altiri pli da pasaÄeroj kaj ÅarÄoj al viaj transportservoj.{} Kosto: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Komencu mezgrandan lokan reklamadon, por altiri pli da pasaÄeroj kaj ÅarÄoj al viaj transportservoj.{} Kosto: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Komencu grandan lokan reklamadon, por altiri pli da pasaÄeroj kaj ÅarÄoj al viaj transportservoj.{} Kosto: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} Fondu rekonstruadon de la urba voja reto. KaÅ­zos konsiderindan Äenon al la trafiko por Äis 6 monatoj.{} Kosto: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Konstruu statuon honore al via kompanio.{} Kosto: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Fondu la konstruadon de novaj komercaj konstruaĵoj en la urbo.{} Kosto: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Aĉetu ekskluzivan transportrajton en la urbo por 1 jaro. La urbo nur permesos pasaÄerojn kaj ÅarÄojn uzi viajn staciojn {} Cost: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Subaĉetu la lokajn estrojn por pliigi vian rendimenton, riskante grandan punon je kapto.{} Kosto: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}Trafika ĥaoso en {TOWN}!{}{}Vojrekonstruada programo komencita de {COMPANY} alportas 6-monatan mizeron al vojuzantoj!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (konstruata)
+STR_2059_IGLOO :Igluo
+STR_205A_TEPEES :Tipioj
+STR_205B_TEAPOT_HOUSE :Tekruĉa Domo
+STR_205C_PIGGY_BANK :Porko-Banko
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN} {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Landaspektigi
+STR_2800_PLANT_TREES :Plantu arbojn
+STR_2801_PLACE_SIGN :Metu signon
+STR_2802_TREES :{WHITE}Arboj
+STR_2803_TREE_ALREADY_HERE :{WHITE}...jam estas arbo
+STR_2804_SITE_UNSUITABLE :{WHITE}...loko ne uzeblas
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Ne povas planti arbon ĉi tie...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...tro da signoj
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Ne povas meti signon ĉi tie...
+STR_280A_SIGN :Signo
+STR_280B_EDIT_SIGN_TEXT :{WHITE}ÅœanÄu signo-tekston
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Ne povas ÅanÄi signan nomon...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Elektu arbo-tipon por plant
+STR_280E_TREES :Arboj
+STR_280F_RAINFOREST :Praarbaro
+STR_2810_CACTUS_PLANTS :Kaktusoj
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Elekto de Stacidomo
+STR_3001_AIRPORT_SELECTION :{WHITE}Elekto de Flughaveno
+STR_3002_ORIENTATION :{BLACK}Direkto
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Kiom da trakoj
+STR_3004_PLATFORM_LENGTH :{BLACK}Platforma longo
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Tro proksime al alia stacidomo
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Alligas pli ol unu ekzistantan stacion/ÅarÄejon
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}Tro da stacioj/ÅarÄejoj en la urbo
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}Tro da stacioj/ÅarÄejoj
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Tro da bushaltejoj
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}Tro da ÅarÄaÅ­taj stacioj
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Tro proksime al alia stacioj/ÅarÄejoj
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}AntaÅ­e forigu stacidomon
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Tro proksime al alia flughaveno
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}AntaÅ­e forigu flughavenon
+
+STR_3030_RENAME_STATION_LOADING :Renomu stacion/ÅarÄejon
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Ne povas renomi stacion...
+STR_3032_RATINGS :{BLACK}Takso
+STR_3033_ACCEPTS :{BLACK}Akceptas
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}Loka takso de transportservoj:
+
+############ range for rating starts
+STR_3035_APPALLING :Plorige
+STR_3036_VERY_POOR :Malbone
+STR_3037_POOR :Ne bone
+STR_3038_MEDIOCRE :Mezmeze
+STR_3039_GOOD :Bone
+STR_303A_VERY_GOOD :Tre bone
+STR_303B_EXCELLENT :Bonege
+STR_303C_OUTSTANDING :Elstare bonege
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} ne plu akceptas {STRING.n}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} ne plu akceptas {STRING.n} aÅ­ {STRING.n}
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} nun akceptas {STRING.n}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} nun akceptas {STRING.n} kaj {STRING.n}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Bushalteja Direkto
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}ÅœarÄstacia Direkto
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}AntaÅ­e forigu bushaltejon
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}AntaÅ­e forigu ÅarÄstacion
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Stacio{P "" j}
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Neniu -
+STR_304B_SITE_UNSUITABLE :{WHITE}...loko ne uzeblas
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Tro proksime al alia haveno
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}AntaÅ­e forigu havenon
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Elektu stacidoman direkton
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Elektu nombron da platformoj por stacidomo
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Elektu longon de stacidomo
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Elektu bushaltejan direkton
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Elektu ÅarÄstacian direkton
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Centre vidu stacion en la ĉefvido
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Montru stacian takson
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}ÅœanÄu nomon de stacio
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Montru liston de akceptataj ÅarÄoj
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Staciaj nomoj - alklaku nomon por centre de la ĉefvido vidi Äin
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Elektu grandecon/tipon de flughaveno
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :Stacidomo
+STR_305F_AIRCRAFT_HANGAR :Aviadila hangaro
+STR_3060_AIRPORT :Flughaveno
+STR_3061_TRUCK_LOADING_AREA :ÅœarÄejo
+STR_3062_BUS_STATION :Bushaltejo
+STR_3063_SHIP_DOCK :Haveno
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Marku ÅarÄregionon ĉe proponata loko
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Ne marku ÅarÄregionon de proponata loko
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}ÅœarÄregiona marko
+STR_3068_DOCK :{WHITE}Haveno
+STR_3069_BUOY :Buo
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...buo okupas la lokon
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...stacio tro vastas
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...nekonformaj stacioj neebligitaj
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Tenu la CTRL-klavon por elekti pliajn erojn
+
+STR_UNDEFINED :(nedifinita tekstero)
+STR_STAT_CLASS_DFLT :DefaÅ­lta stacio
+STR_STAT_CLASS_WAYP :Transirejoj
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Åœipdeponeja Direkto
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...devas esti konstruata sur akvo
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Ne povas konstrui Åipdeponejon ĉi tie...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Elektu Åipdeponejan direkton
+STR_3804_WATER :Akvo
+STR_3805_COAST_OR_RIVERBANK :Mara aÅ­ rivera bordo
+STR_3806_SHIP_DEPOT :Åœipdeponejo
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...Ne povas konstrui sur akvo
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Konservu Ludon
+STR_4001_LOAD_GAME :{WHITE}ÅœarÄu Ludon
+STR_4002_SAVE :{BLACK}Konservu
+STR_4003_DELETE :{BLACK}ForviÅu
+STR_4004 :{COMPANY} je {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} megabitoko{P "" j} libera{P "" j}
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Ne eblas legi diskon
+STR_4007_GAME_SAVE_FAILED :{WHITE}Ludkonservado Fiaskis
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Ne eblas forviÅi dosieron
+STR_4009_GAME_LOAD_FAILED :{WHITE}LudÅarÄado Fiaskis
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}Listo da diskoj, dosierujoj kaj luddosieroj
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Nune elektita nomo por luddosiero
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}ForviÅu la nun elektitan luddosieron
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Konservu la nunan ludon per la elektita nomo
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Elektu Novan Ludtipon
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Elektu scenaron (green), antaÅ­-agorditan ludon (blue), aÅ­ hazardan novan ludon
+STR_4010_GENERATE_RANDOM_NEW_GAME :Generu hazardan novan ludon
+STR_4011_LOAD_HEIGHTMAP :{WHITE}ÅœarÄu Altecmapon
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} okupas la lokon
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :Karbminejo
+STR_4803_POWER_STATION :Elektrejo
+STR_4804_SAWMILL :Segejo
+STR_4805_FOREST :Arbaro
+STR_4806_OIL_REFINERY :Oleproduktejo
+STR_4807_OIL_RIG :Oleplatformo
+STR_4808_FACTORY :Farejo
+STR_4809_PRINTING_WORKS :Printejo
+STR_480A_STEEL_MILL :Åœtalejo
+STR_480B_FARM :Farmbieno
+STR_480C_COPPER_ORE_MINE :Kuproercminejo
+STR_480D_OIL_WELLS :Olefonto
+STR_480E_BANK :Banko
+STR_480F_FOOD_PROCESSING_PLANT :ManÄaĵfarejo
+STR_4810_PAPER_MILL :Paperejo
+STR_4811_GOLD_MINE :Orminejo
+STR_4812_BANK :Banko
+STR_4813_DIAMOND_MINE :Diamantminejo
+STR_4814_IRON_ORE_MINE :Ferercminejo
+STR_4815_FRUIT_PLANTATION :Fruktkulturejo
+STR_4816_RUBBER_PLANTATION :Kaŭĉukkulturejo
+STR_4817_WATER_SUPPLY :Akvofonto
+STR_4818_WATER_TOWER :Akvoturo
+STR_4819_FACTORY :Farejo
+STR_481A_FARM :Farmbieno
+STR_481B_LUMBER_MILL :Lignejo
+STR_481C_COTTON_CANDY_FOREST :SukerÅpinaĵaro
+STR_481D_CANDY_FACTORY :Dolĉaĵfarejo
+STR_481E_BATTERY_FARM :Bateribieno
+STR_481F_COLA_WELLS :Kolafonto
+STR_4820_TOY_SHOP :Ludilvendejo
+STR_4821_TOY_FACTORY :Ludilfarejo
+STR_4822_PLASTIC_FOUNTAINS :Plastikfontanaro
+STR_4823_FIZZY_DRINK_FACTORY :Farejo de Amuzaj Trinkaĵoj
+STR_4824_BUBBLE_GENERATOR :Vezikgenerilo
+STR_4825_TOFFEE_QUARRY :Tofeminejo
+STR_4826_SUGAR_MINE :Sukerminejo
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Bezonas: {YELLOW}{STRING.n}
+STR_4828_REQUIRES :{BLACK}Bezonas: {YELLOW}{STRING.n}, {STRING.n}
+STR_4829_REQUIRES :{BLACK}Bezonas: {YELLOW}{STRING.n}, {STRING.n}, {STRING.n}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Lastmonata produktado:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% transportiÄis)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centre en la ĉefvido vidu la industilokon
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Nova {STRING} konstruiÄas ĉe {TOWN}!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Nova {STRING} plantiÄas ĉe {TOWN}!
+STR_482F_COST :{BLACK}Kosto: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Industritipo ne konstrueblas ĉi tie...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...arbaro nur planteblas super neÄa limlinio
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} anoncas tre baldaÅ­an fermiÄon!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}Liverproblemoj devigas al {INDUSTRY} anonci tre baldaÅ­an fermiÄon!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}Pro manko da proksimaj arboj {INDUSTRY} devas anonci tre baldaÅ­an fermiÄon!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} pliigas produktadon!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}Nova karbo trovita ĉe {INDUSTRY}!{}Oni atendas produktan duobligon!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}Nova oleo trovita ĉe {INDUSTRY}!{}Oni atendas produktan duobligon!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}Pro pli bona agroteÄ¥niko {INDUSTRY} verÅajne duobligos produktadon!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}La produktado de {INDUSTRY} duoniÄas
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}Insektoj kaÅ­zas plagon ĉe {INDUSTRY}!{}Produktado duoniÄas
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...nur lokebla ĉe la randoj de la mapo
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}Produktado de {STRING} ĉe {INDUSTRY} pliiÄas per {COMMA}%!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}Produktado de {STRING} ĉe {INDUSTRY} malpliiÄas per {COMMA}%!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Trajno en tunelo
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Vojveturilo en tunelo
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Alia tunelo okupas la lokon
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Ne eblas liberigi la landon aliflanke de la tunelo
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}AntaÅ­e forigu tunelon
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}AntaÅ­e forigu ponton
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Ne povas komenci kaj fini en la sama loko
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Ebena lando aÅ­ akvo necesas sub la ponto
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}Komenco kaj fino devas esti samliniaj
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Nekonvena loko por tunelkomenco
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Åœtala pendanta
+STR_500F_GIRDER_STEEL :Åœtala ebena
+STR_5010_CANTILEVER_STEEL :Åœtala luksa
+STR_5011_SUSPENSION_CONCRETE :Betona pendanta
+STR_5012_WOODEN :Ligna
+STR_5013_CONCRETE :Betona
+STR_5014_TUBULAR_STEEL :Åœtala tuba
+STR_BRIDGE_TUBULAR_SILICON :Tuba, Silicia
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Ne povas konstrui ponton ĉi tie...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Ne povas konstrui tunelon ĉi tie...
+STR_5017_RAILROAD_TUNNEL :Fervoja tunelo
+STR_5018_ROAD_TUNNEL :Voja tunelo
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Åœtala pendanta relponto
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Åœtala ebena relponto
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Åœtala luksa relponto
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Fortbetona pendanta relponto
+STR_501F_WOODEN_RAIL_BRIDGE :Ligna relponto
+STR_5020_CONCRETE_RAIL_BRIDGE :Betona relponto
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Åœtala pendanta vojponto
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Åœtala ebena vojponto
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Åœtala luksa vojponto
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Fortbetona pendanta vojponto
+STR_5025_WOODEN_ROAD_BRIDGE :Ligna vojponto
+STR_5026_CONCRETE_ROAD_BRIDGE :Betona vojponto
+STR_5027_TUBULAR_RAIL_BRIDGE :Tuba relponto
+STR_5028_TUBULAR_ROAD_BRIDGE :Tuba vojponto
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Objekto okupas la lokon
+STR_5801_TRANSMITTER :Transmitilo
+STR_5802_LIGHTHOUSE :Lumturo
+STR_5803_COMPANY_HEADQUARTERS :Kompania Ĉefkonstruaĵo
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...kompania ĉefkonstruaĵo okupas la lokon
+STR_5805_COMPANY_OWNED_LAND :Kompanie posedata lando
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Ne povas aĉeti ĉi tiun regionon...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...vi jam posedas Äin!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Sennome
+STR_SV_TRAIN_NAME :Trajno {COMMA}
+STR_SV_ROADVEH_NAME :Vojveturilo {COMMA}
+STR_SV_SHIP_NAME :Åœipo {COMMA}
+STR_SV_AIRCRAFT_NAME :Aviadilo {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :Norda {STRING}
+STR_SV_STNAME_SOUTH :Suda {STRING}
+STR_SV_STNAME_EAST :Orienta {STRING}
+STR_SV_STNAME_WEST :Okcidenta {STRING}
+STR_SV_STNAME_CENTRAL :Centra {STRING}
+STR_SV_STNAME_TRANSFER :Transiga {STRING}
+STR_SV_STNAME_HALT :Halteja {STRING}
+STR_SV_STNAME_VALLEY :Valo de {STRING}
+STR_SV_STNAME_HEIGHTS :Alta {STRING}
+STR_SV_STNAME_WOODS :{STRING} Arbaro
+STR_SV_STNAME_LAKESIDE :Lago ĉe {STRING}
+STR_SV_STNAME_EXCHANGE :InterÅanÄa {STRING}
+STR_SV_STNAME_AIRPORT :Flughaveno de {STRING}
+STR_SV_STNAME_OILFIELD :Olefonto de {STRING}
+STR_SV_STNAME_MINES :Minejo de {STRING}
+STR_SV_STNAME_DOCKS :Haveno de {STRING}
+STR_SV_STNAME_BUOY_1 :{STRING} Buo 1
+STR_SV_STNAME_BUOY_2 :{STRING} Buo 2
+STR_SV_STNAME_BUOY_3 :{STRING} Buo 3
+STR_SV_STNAME_BUOY_4 :{STRING} Buo 4
+STR_SV_STNAME_BUOY_5 :{STRING} Buo 5
+STR_SV_STNAME_BUOY_6 :{STRING} Buo 6
+STR_SV_STNAME_BUOY_7 :{STRING} Buo 7
+STR_SV_STNAME_BUOY_8 :{STRING} Buo 8
+STR_SV_STNAME_BUOY_9 :{STRING} Buo 9
+STR_SV_STNAME_ANNEXE :Ekstera {STRING}
+STR_SV_STNAME_SIDINGS :Flanka {STRING}
+STR_SV_STNAME_BRANCH :Branĉa {STRING}
+STR_SV_STNAME_UPPER :Supra {STRING}
+STR_SV_STNAME_LOWER :Malsupra {STRING}
+STR_SV_STNAME_HELIPORT :{STRING} Helikopterejo
+STR_SV_STNAME_FOREST :Arbaro de {STRING}
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Malfacilec-nivelo
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Konservu
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Facile
+STR_6802_MEDIUM :{BLACK}Meze
+STR_6803_HARD :{BLACK}Malfacile
+STR_6804_CUSTOM :{BLACK}ÅœanÄite
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maksimumo da konkurantoj: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Konkuranta komenctempo: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}Kiom da urboj: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}Kiom da industrioj: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Maksimuma komenca prunto: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Komenca rentumo: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Veturilaj irkostoj: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Konkuranta konstrurapideco: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Konkuranta inteligenteco: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Veturilaj rompiÄoj: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Subvencia kiomobligo: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Konstrukostoj: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Terentipo: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Kiom da maroj/lagoj: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Ekonomio: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Trajna inversigo: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Katastrofoj: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Urbestrara teniÄo al regiona strukturÅanÄiÄo: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :Neniu
+STR_6816_LOW :Malalte
+STR_6817_NORMAL :Normale
+STR_6818_HIGH :Alte
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Tre Malrapide
+STR_681C_SLOW :Malrapide
+STR_681D_MEDIUM :Meze
+STR_681E_FAST :Rapide
+STR_681F_VERY_FAST :Tre Rapide
+STR_VERY_LOW :Tre Malalte
+STR_6820_LOW :Malalte
+STR_6821_MEDIUM :Meze
+STR_6822_HIGH :Alte
+STR_6823_NONE :Neniu
+STR_6824_REDUCED :Malpli
+STR_6825_NORMAL :Normale
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Tre Ebene
+STR_682B_FLAT :Ebene
+STR_682C_HILLY :Montete
+STR_682D_MOUNTAINOUS :Monte
+STR_682E_STEADY :NeÅanÄiÄeme
+STR_682F_FLUCTUATING :ÅœanÄiÄeme
+STR_6830_IMMEDIATE :Tuj
+STR_6831_3_MONTHS_AFTER_PLAYER :3 monatoj post ludanto
+STR_6832_6_MONTHS_AFTER_PLAYER :6 monatoj post ludanto
+STR_6833_9_MONTHS_AFTER_PLAYER :9 monatoj post ludanto
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :Finlinie, kaj stacidome
+STR_6835_AT_END_OF_LINE_ONLY :Nur finlinie
+STR_6836_OFF :Malaktiva
+STR_6837_ON :Aktiva
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Montru plej bonajn ludantojn
+STR_6839_PERMISSIVE :Permeseme
+STR_683A_TOLERANT :Tolerante
+STR_683B_HOSTILE :Gastige
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Ludanto {COMMA})
+STR_7004_NEW_FACE :{BLACK}Nova VizaÄo
+STR_7005_COLOR_SCHEME :{BLACK}Kolorskemo
+STR_7006_COLOR_SCHEME :{GOLD}Kolorskemo:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Nova Kolorskemo
+STR_7008_COMPANY_NAME :{BLACK}Kompaninomo
+STR_7009_PRESIDENT_NAME :{BLACK}ManaÄantnomo
+STR_700A_COMPANY_NAME :Kompania Nomo
+STR_700B_PRESIDENT_S_NAME :Nomo de la ManaÄanto
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Ne povas ÅanÄi kompaninomon...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Ne povas ÅanÄi manaÄantnomon...
+STR_700E_FINANCES :{WHITE}Financoj de {COMPANY} {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Elspezo/Enspezo
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Konstruado
+STR_7012_NEW_VEHICLES :{GOLD}Novaj Veturiloj
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Trajnaj Irkostoj
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Vojveturilaj Irkostoj
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Aviadilaj Irkostoj
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Åœipaj Irkostoj
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Posedaĵa Konservado
+STR_7018_TRAIN_INCOME :{GOLD}Trajna Enspezo
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Vojveturila Enspezo
+STR_701A_AIRCRAFT_INCOME :{GOLD}Aviadila Enspezo
+STR_701B_SHIP_INCOME :{GOLD}Åœipa Enspezo
+STR_701C_LOAN_INTEREST :{GOLD}Rento pri Prunto
+STR_701D_OTHER :{GOLD}Alia
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Entute:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Enspeza Grafiko
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Gajna Grafiko
+STR_7026_BANK_BALANCE :{WHITE}Banka Balanco
+STR_7027_LOAN :{WHITE}Prunto
+STR_MAX_LOAN :{WHITE}Maksimuma prunto: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}Pruntu {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Repagu {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...maksimuma permesata prunto estas {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Ne povas prunti pli da mono...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...ne estas repagebla prunto
+STR_702E_REQUIRED :{WHITE}...{CURRENCY} necesas
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Ne povas repagi prunton...
+STR_INSUFFICIENT_FUNDS :{WHITE}Ne povas donaci monon pruntitan de la banko...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Elektu novan vizaÄon por la manaÄanto
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}ÅœanÄu la kompaniveturilan koloraron
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}ÅœanÄu la nomon de la manaÄanto
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}ÅœanÄu la nomon de la kompanio
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Alklaku la deziratan kolorskemon
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Grandigu prunton
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Repagu pruntparton
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(ManaÄanto)
+STR_7038_INAUGURATED :{GOLD}EnaÅ­guris: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Veturiloj:
+STR_TRAINS :{WHITE}{COMMA} trajno{P "" j}
+STR_ROAD_VEHICLES :{WHITE}{COMMA} vojveturilo{P "" j}
+STR_AIRCRAFT :{WHITE}{COMMA} aviadiloj
+STR_SHIPS :{WHITE}{COMMA} Åipo{P "" j}
+STR_7042_NONE :{WHITE}Neniu
+STR_7043_FACE_SELECTION :{WHITE}VizaÄelekto
+STR_7044_MALE :{BLACK}Vira
+STR_7045_FEMALE :{BLACK}Virina
+STR_7046_NEW_FACE :{BLACK}Nova VizaÄo
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Nuligu elekton de nova vizaÄo
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Akceptu elekton de nova vizaÄo
+STR_7049_SELECT_MALE_FACES :{BLACK}Elektu virajn vizaÄojn
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Elektu virinajn vizaÄojn
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Kreu hazardan novan vizaÄon
+STR_704C_KEY :{BLACK}Åœlosilo
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Montru Ålosilon al grafikoj
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Åœlosilo al kompanigrafikoj
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Klaku ĉi tie por (mal)Åalti la kompanian eron de la grafiko
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Kiom da ÅarÄo liveriÄis
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Kompania rendimento (maksimumo=1000)
+STR_7052_COMPANY_VALUES :{WHITE}Kompaniaj valoroj
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Kompaniara tabelo
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}Transportkompanio en problemoj!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} forvendiÄos aÅ­ bankrotiÄos krom se Äi pli bone faros!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(ManaÄanto)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Transportkompania kuniÄo!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} vendiÄis al {COMPANY} por {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Ni serĉas transportkompanion por transpreni nian kompanion.{}{}Ĉu vi volas aĉeti {COMPANY} por {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Bankrote!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} estas fermita de kreditantoj kaj ĉiuj partoj vendiÄis!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}Nova transportkompanio lanĉiÄis!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} ekkonstruas ĉe {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Ne povas aĉeti kompanion...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}ÅœarÄpagaj Tarifoj
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Tagoj en transporto
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Pago por liveri 10 unuojn (aÅ­ 10,000 litrojn) da ÅarÄo trans 20 kvadratoj
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}(Mal)Åaltu grafikon por ÅarÄo
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :InÄeniero
+STR_7067_TRAFFIC_MANAGER :Trafikkontrolisto
+STR_7068_TRANSPORT_COORDINATOR :TransportmanaÄanto
+STR_7069_ROUTE_SUPERVISOR :Transporta Supervidanto
+STR_706A_DIRECTOR :Direktoro
+STR_706B_CHIEF_EXECUTIVE :Ĉefa Plenumanto
+STR_706C_CHAIRMAN :Prezidanto
+STR_706D_PRESIDENT :Potenculo
+STR_706E_TYCOON :Plejpotenculo
+STR_706F_BUILD_HQ :{BLACK}Faru HQ
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Konstruu kompanian ĉefkonstruaĵon / vidu kompanian ĉefkonstruaĵon
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Rekonstruu kompanian ĉefkonstruaĵon aliloke por 1% de kompanivaloro
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Ne povas konstrui kompanian ĉefkonstruaĵon...
+STR_7072_VIEW_HQ :{BLACK}Vidu HQ
+STR_RELOCATE_HQ :{BLACK}Relokigu HQ
+STR_COMPANY_PASSWORD :{BLACK}Pasvorto
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Pasvorte protektu vian kompanion por eviti ke eksteruloj aliÄu.
+STR_SET_COMPANY_PASSWORD :Agordu kompanian pasvorton
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}Monda Recesio!{}{}Financaj spertuloj timas ke malpliboniÄas treege! Ekonomio malboniÄadas!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Recesio finiÄis!{}{}Komerca pliboniÄos donas konfidon al industrioj! Ekonomio pliboniÄas!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Åœaltu inter granda kaj malgranda fenestro
+STR_7076_COMPANY_VALUE :{GOLD}Kompania valoro: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Aĉetu 25%-an dividaĵon
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Vendu 25%-an dividaĵon
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Aĉetu 25%-an dividaĵon en ĉi tiu kompanio
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Vendu 25%-an dividaĵon en ĉi tiu kompanio
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Ne povas aĉeti 25%-an dividaĵon...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}Ne povas vendi 25%-an dividaĵon...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% posedataj de {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% posedataj de {COMPANY}{} {COMMA}% posedataj de {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} estas transprenita de {COMPANY}!
+STR_7080_PROTECTED :{WHITE}Ĉi tiu kompanio ne sufiĉe aÄas por jam komerci dividaĵojn...
+
+STR_LIVERY_DEFAULT :Normala Koloro
+STR_LIVERY_STEAM :VapormaÅino
+STR_LIVERY_DIESEL :DizelmaÅino
+STR_LIVERY_ELECTRIC :ElektromaÅino
+STR_LIVERY_MONORAIL :UnurelmaÅino
+STR_LIVERY_MAGLEV :MaglevmaÅino
+STR_LIVERY_DMU :DMU
+STR_LIVERY_EMU :EMU
+STR_LIVERY_PASSENGER_WAGON_STEAM :PasaÄera Vagono (Vaporo)
+STR_LIVERY_PASSENGER_WAGON_DIESEL :PasaÄera Vagono (Dizelo)
+STR_LIVERY_PASSENGER_WAGON_ELECTRIC :PasaÄera Vagono (Elektro)
+STR_LIVERY_FREIGHT_WAGON :ÅœarÄvagono
+STR_LIVERY_BUS :Buso
+STR_LIVERY_TRUCK :ÅœarÄaÅ­to
+STR_LIVERY_PASSENGER_SHIP :PasaÄera Åœipo
+STR_LIVERY_FREIGHT_SHIP :ÅœarÄÅipo
+STR_LIVERY_HELICOPTER :Helikoptero
+STR_LIVERY_SMALL_PLANE :Malgranda Aviadilo
+STR_LIVERY_LARGE_PLANE :Granda Aviadilo
+
+STR_LIVERY_GENERAL_TIP :{BLACK}Montru Äeneralajn kolorskemojn
+STR_LIVERY_TRAIN_TIP :{BLACK}Montru trajnajn kolorskemojn
+STR_LIVERY_ROADVEH_TIP :{BLACK}Montru vojveturilajn kolorskemojn
+STR_LIVERY_SHIP_TIP :{BLACK}Montru Åipkolorajn skemojn
+STR_LIVERY_AIRCRAFT_TIP :{BLACK}Montru aviadilajn kolorskemojn
+STR_LIVERY_PRIMARY_TIP :{BLACK}Elektu la unuan koloron por la elektita skemo
+STR_LIVERY_SECONDARY_TIP :{BLACK}Elektu la duan koloron por la elektita skemo
+STR_LIVERY_PANEL_TIP :{BLACK}Elektu kolorskemon por ÅanÄi, aÅ­ plurajn per CTRL+click. Alklaku kvadraton por uzi/ne uzi skemon
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (Vaporo)
+STR_8001_MJS_250_DIESEL :MJS 250 (Dizelo)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut Diesel
+STR_8006_POWERNAUT_DIESEL :Powernaut Diesel
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (Vaporo)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (Vaporo)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (Vaporo)
+STR_800A_SH_8P_STEAM :SH '8P' (Vaporo)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (Dizelo)
+STR_800C_DASH_DIESEL :'Dash' (Dizelo)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (Dizelo)
+STR_800E_UU_37_DIESEL :UU '37' (Dizelo)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (Dizelo)
+STR_8010_CS_4000_DIESEL :CS 4000 (Dizelo)
+STR_8011_CS_2400_DIESEL :CS 2400 (Dizelo)
+STR_8012_CENTENNIAL_DIESEL :Centennial (Dizelo)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (Dizelo)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (Dizelo)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (Dizelo)
+STR_8016_SH_125_DIESEL :SH '125' (Dizelo)
+STR_8017_SH_30_ELECTRIC :SH '30' (Elektro)
+STR_8018_SH_40_ELECTRIC :SH '40' (Elektro)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (Elektro)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (Elektro)
+STR_801B_PASSENGER_CAR :PasaÄervagono
+STR_801C_MAIL_VAN :PoÅtvagono
+STR_801D_COAL_CAR :Karbvagono
+STR_801E_OIL_TANKER :Olevagono
+STR_801F_LIVESTOCK_VAN :Brutvagono
+STR_8020_GOODS_VAN :Varvagono
+STR_8021_GRAIN_HOPPER :Grenvagono
+STR_8022_WOOD_TRUCK :Lignovagono
+STR_8023_IRON_ORE_HOPPER :Ferercavagono
+STR_8024_STEEL_TRUCK :Åœtalvagono
+STR_8025_ARMORED_VAN :Kirasa Vagono
+STR_8026_FOOD_VAN :ManÄaĵvagono
+STR_8027_PAPER_TRUCK :Papervagono
+STR_8028_COPPER_ORE_HOPPER :Kuproercvagono
+STR_8029_WATER_TANKER :Akvovagono
+STR_802A_FRUIT_TRUCK :Fruktvagono
+STR_802B_RUBBER_TRUCK :Kaŭĉukvagono
+STR_802C_SUGAR_TRUCK :Sukervagono
+STR_802D_COTTON_CANDY_HOPPER :SukerÅpinaĵvagono
+STR_802E_TOFFEE_HOPPER :Tofevagono
+STR_802F_BUBBLE_VAN :Vezikvagono
+STR_8030_COLA_TANKER :Kolavagono
+STR_8031_CANDY_VAN :Dolĉaĵvagono
+STR_8032_TOY_VAN :Ludilvagono
+STR_8033_BATTERY_TRUCK :Baterivagono
+STR_8034_FIZZY_DRINK_TRUCK :Amuztrinkaĵvagono
+STR_8035_PLASTIC_TRUCK :Plastikvagono
+STR_8036_X2001_ELECTRIC :'X2001' (Elektro)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Elektro)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :PasaÄervagono
+STR_803A_MAIL_VAN :PoÅtvagono
+STR_803B_COAL_CAR :Karbvagono
+STR_803C_OIL_TANKER :Olevagono
+STR_803D_LIVESTOCK_VAN :Brutvagono
+STR_803E_GOODS_VAN :Varvagono
+STR_803F_GRAIN_HOPPER :Grenvagono
+STR_8040_WOOD_TRUCK :Lignovagono
+STR_8041_IRON_ORE_HOPPER :Ferercvagono
+STR_8042_STEEL_TRUCK :Åœtalvagono
+STR_8043_ARMORED_VAN :Kirasa Vagono
+STR_8044_FOOD_VAN :ManÄaĵvagono
+STR_8045_PAPER_TRUCK :Papervagono
+STR_8046_COPPER_ORE_HOPPER :Kuproercvagono
+STR_8047_WATER_TANKER :Akvovagono
+STR_8048_FRUIT_TRUCK :Fruktvagono
+STR_8049_RUBBER_TRUCK :Kaŭĉukvagono
+STR_804A_SUGAR_TRUCK :Sukervagono
+STR_804B_COTTON_CANDY_HOPPER :SukerÅpinaĵvagono
+STR_804C_TOFFEE_HOPPER :Tofevagono
+STR_804D_BUBBLE_VAN :Vezikvagono
+STR_804E_COLA_TANKER :Kolavagono
+STR_804F_CANDY_VAN :Dolĉaĵvagono
+STR_8050_TOY_VAN :Ludilvagono
+STR_8051_BATTERY_TRUCK :Baterivagono
+STR_8052_FIZZY_DRINK_TRUCK :Amuztrinkaĵvagono
+STR_8053_PLASTIC_TRUCK :Plastikvagono
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Levjatano' (Elektro)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Ciklopo' (Eletro)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasuso' (Elektro)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Ĥimero' (Elektro)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :PasaÄervagono
+STR_805A_MAIL_VAN :PoÅtvagono
+STR_805B_COAL_CAR :Karbvagono
+STR_805C_OIL_TANKER :Olevagono
+STR_805D_LIVESTOCK_VAN :Brutvagono
+STR_805E_GOODS_VAN :Varvagono
+STR_805F_GRAIN_HOPPER :Grenvagono
+STR_8060_WOOD_TRUCK :Lignovagono
+STR_8061_IRON_ORE_HOPPER :Ferercvagono
+STR_8062_STEEL_TRUCK :Åœtalvagono
+STR_8063_ARMORED_VAN :Kirasa Vagono
+STR_8064_FOOD_VAN :ManÄaĵvagono
+STR_8065_PAPER_TRUCK :Papervagono
+STR_8066_COPPER_ORE_HOPPER :Kuproercvagono
+STR_8067_WATER_TANKER :Akvovagono
+STR_8068_FRUIT_TRUCK :Fruktvagono
+STR_8069_RUBBER_TRUCK :Kaŭĉukvagono
+STR_806A_SUGAR_TRUCK :Sukervagono
+STR_806B_COTTON_CANDY_HOPPER :SukerÅpinaĵvagono
+STR_806C_TOFFEE_HOPPER :Tofevagono
+STR_806D_BUBBLE_VAN :Vezikvagono
+STR_806E_COLA_TANKER :Kolavagono
+STR_806F_CANDY_VAN :Dolĉaĵvagono
+STR_8070_TOY_VAN :Ludilvagono
+STR_8071_BATTERY_TRUCK :Baterivagono
+STR_8072_FIZZY_DRINK_TRUCK :Amuztrinkaĵvagono
+STR_8073_PLASTIC_TRUCK :Plastikvagono
+STR_8074_MPS_REGAL_BUS :Buso "MPS Regal"
+STR_8075_HEREFORD_LEOPARD_BUS :Buso "Hereford Leopard"
+STR_8076_FOSTER_BUS :Buso "Foster"
+STR_8077_FOSTER_MKII_SUPERBUS :Buso "Foster MkII Superbus"
+STR_8078_PLODDYPHUT_MKI_BUS :Buso "Ploddyphut MkI"
+STR_8079_PLODDYPHUT_MKII_BUS :Buso "Ploddyphut MkII"
+STR_807A_PLODDYPHUT_MKIII_BUS :Buso "Ploddyphut MkIII"
+STR_807B_BALOGH_COAL_TRUCK :Karba ÅarÄaÅ­to "Balogh"
+STR_807C_UHL_COAL_TRUCK :Karba ÅarÄaÅ­to "Uhl"
+STR_807D_DW_COAL_TRUCK :Karba ÅarÄaÅ­to "DW"
+STR_807E_MPS_MAIL_TRUCK :PoÅtaÅ­to "MPS"
+STR_807F_REYNARD_MAIL_TRUCK :PoÅtaÅ­to "Reynard"
+STR_8080_PERRY_MAIL_TRUCK :PoÅtaÅ­to "Perry"
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :PoÅtaÅ­to "MightyMover"
+STR_8082_POWERNAUGHT_MAIL_TRUCK :PoÅtaÅ­to "Powernaught"
+STR_8083_WIZZOWOW_MAIL_TRUCK :PoÅtaÅ­to "Wizzowow"
+STR_8084_WITCOMBE_OIL_TANKER :OleÅarÄaÅ­to "Witcombe"
+STR_8085_FOSTER_OIL_TANKER :OleÅarÄaÅ­to "Foster"
+STR_8086_PERRY_OIL_TANKER :OleÅarÄaÅ­to "Perry"
+STR_8087_TALBOTT_LIVESTOCK_VAN :BrutÅarÄaÅ­to "Talbott"
+STR_8088_UHL_LIVESTOCK_VAN :BrutÅarÄaÅ­to "Uhl"
+STR_8089_FOSTER_LIVESTOCK_VAN :BrutÅarÄaÅ­to "Foster"
+STR_808A_BALOGH_GOODS_TRUCK :VarÅarÄaÅ­to "Balogh"
+STR_808B_CRAIGHEAD_GOODS_TRUCK :VarÅarÄaÅ­to "Craighead"
+STR_808C_GOSS_GOODS_TRUCK :VarÅarÄaÅ­to "Goss"
+STR_808D_HEREFORD_GRAIN_TRUCK :GrenÅarÄaÅ­to "Hereford"
+STR_808E_THOMAS_GRAIN_TRUCK :GrenÅarÄaÅ­to "Thomas"
+STR_808F_GOSS_GRAIN_TRUCK :GrenÅarÄaÅ­to "Goss"
+STR_8090_WITCOMBE_WOOD_TRUCK :LignoÅarÄaÅ­to "Witcombe"
+STR_8091_FOSTER_WOOD_TRUCK :LignoÅarÄaÅ­to "Foster"
+STR_8092_MORELAND_WOOD_TRUCK :LignoÅarÄaÅ­to "Moreland"
+STR_8093_MPS_IRON_ORE_TRUCK :FerercÅarÄaÅ­to "MPS"
+STR_8094_UHL_IRON_ORE_TRUCK :FerercÅarÄaÅ­to "Uhl"
+STR_8095_CHIPPY_IRON_ORE_TRUCK :FerercÅarÄaÅ­to "Chippy"
+STR_8096_BALOGH_STEEL_TRUCK :ÅœtalÅarÄaÅ­to "Balogh"
+STR_8097_UHL_STEEL_TRUCK :ÅœtalÅarÄaÅ­to "Uhl"
+STR_8098_KELLING_STEEL_TRUCK :ÅœtalÅarÄaÅ­to "Kelling"
+STR_8099_BALOGH_ARMORED_TRUCK :Kirasa ÅœarÄaÅ­to "Balogh"
+STR_809A_UHL_ARMORED_TRUCK :Kirasa ÅœarÄaÅ­to "Uhl"
+STR_809B_FOSTER_ARMORED_TRUCK :Kirasa ÅœarÄaÅ­to "Foster"
+STR_809C_FOSTER_FOOD_VAN :ManÄaĵÅarÄaÅ­to "Foster"
+STR_809D_PERRY_FOOD_VAN :ManÄaĵÅarÄaÅ­to "Perry"
+STR_809E_CHIPPY_FOOD_VAN :ManÄaĵÅarÄaÅ­to "Chippy"
+STR_809F_UHL_PAPER_TRUCK :PaperÅarÄaÅ­to "Uhl"
+STR_80A0_BALOGH_PAPER_TRUCK :PaperÅarÄaÅ­to "Balogh"
+STR_80A1_MPS_PAPER_TRUCK :PaperÅarÄaÅ­to "MPS"
+STR_80A2_MPS_COPPER_ORE_TRUCK :KuproercÅarÄaÅ­to "MPS"
+STR_80A3_UHL_COPPER_ORE_TRUCK :KuproercÅarÄaÅ­to "Uhl"
+STR_80A4_GOSS_COPPER_ORE_TRUCK :KuproercÅarÄaÅ­to "Goss"
+STR_80A5_UHL_WATER_TANKER :AkvoÅarÄaÅ­to "Uhl"
+STR_80A6_BALOGH_WATER_TANKER :AkvoÅarÄaÅ­to "Balogh"
+STR_80A7_MPS_WATER_TANKER :AkvoÅarÄaÅ­to "MPS"
+STR_80A8_BALOGH_FRUIT_TRUCK :FruktÅarÄaÅ­to "Balogh"
+STR_80A9_UHL_FRUIT_TRUCK :FruktÅarÄaÅ­to "Uhl"
+STR_80AA_KELLING_FRUIT_TRUCK :FruktÅarÄaÅ­to "Kelling"
+STR_80AB_BALOGH_RUBBER_TRUCK :KaŭĉukÅarÄaÅ­to "Balogh"
+STR_80AC_UHL_RUBBER_TRUCK :KaŭĉukÅarÄaÅ­to "Uhl"
+STR_80AD_RMT_RUBBER_TRUCK :KaŭĉukÅarÄaÅ­to "RMT"
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :SukerÅarÄaÅ­to "MightyMover"
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :SukerÅarÄaÅ­to "Powernaught"
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :SukerÅarÄaÅ­to "Wizzowow"
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :KolaÅarÄaÅ­to "MightyMover"
+STR_80B2_POWERNAUGHT_COLA_TRUCK :KolaÅarÄaÅ­to "Powernaught"
+STR_80B3_WIZZOWOW_COLA_TRUCK :KolaÅarÄaÅ­to "Wizzowow"
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :SukerÅpinaĵÅarÄaÅ­to "MightyMover"
+STR_80B5_POWERNAUGHT_COTTON_CANDY :SukerÅpinaĵÅarÄaÅ­to "Powernaught"
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :SukerÅpinaĵÅarÄaÅ­to "Wizzowow"
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :TofeÅarÄaÅ­to "MightyMover"
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :TofeÅarÄaÅ­to "Powernaught"
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :TofeÅarÄaÅ­to "Wizzowow"
+STR_80BA_MIGHTYMOVER_TOY_VAN :LudilÅarÄaÅ­to "MightyMover"
+STR_80BB_POWERNAUGHT_TOY_VAN :LudilÅarÄaÅ­to "Powernaught"
+STR_80BC_WIZZOWOW_TOY_VAN :LudilÅarÄaÅ­to "Wizzowow"
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :DolĉaĵÅarÄaÅ­to "MightyMover"
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :DolĉaĵÅarÄaÅ­to "Powernaught"
+STR_80BF_WIZZOWOW_CANDY_TRUCK :DolĉaĵÅarÄaÅ­to "Wizzowow"
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :BateriÅarÄaÅ­to "MightyMover"
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :BateriÅarÄaÅ­to "Powernaught"
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :BateriÅarÄaÅ­to "Wizzowow"
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :AmuztrinkaĵÅarÄaÅ­to "MightyMover"
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :AmuztrinkaĵÅarÄaÅ­to "Powernaught"
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :AmuztrinkaĵÅarÄaÅ­to "Wizzowow"
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :PlastikÅarÄaÅ­to "MightyMover"
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :PlastikÅarÄaÅ­to "Powernaught"
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :PlastikÅarÄaÅ­to "Wizzowow"
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :VezikÅarÄaÅ­to "MightyMover"
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :VezikÅarÄaÅ­to "Powernaught"
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :VezikÅarÄaÅ­to "Wizzowow"
+STR_80CC_MPS_OIL_TANKER :OleÅipo "MPS"
+STR_80CD_CS_INC_OIL_TANKER :OleÅipo "CS-Inc."
+STR_80CE_MPS_PASSENGER_FERRY :PasaÄerÅipo "MPS"
+STR_80CF_FFP_PASSENGER_FERRY :PasaÄerÅipo "FFP"
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Aeroglita "Bakewell 300"
+STR_80D1_CHUGGER_CHUG_PASSENGER :PasaÄerÅipo "Chugger-Chug"
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :PasaÄerÅipo "Shivershake"
+STR_80D3_YATE_CARGO_SHIP :ÅœarÄÅipo "Yate"
+STR_80D4_BAKEWELL_CARGO_SHIP :ÅœarÄÅipo "Bakewell"
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :ÅœarÄÅipo "Mightymover"
+STR_80D6_POWERNAUT_CARGO_SHIP :ÅœarÄÅipo "Powernaut"
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Helikoptero "Tricario"
+STR_80FE_GURU_X2_HELICOPTER :Helikoptero "Guru X2"
+STR_80FF_POWERNAUT_HELICOPTER :Helikoptero "Powernaut"
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}MesaÄo de veturil-produktanto
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}Nova {STRING} estas inventita - ĉu vi Åatus jaron ekskluzive uzi la veturilon, por ke ni povu vidi Äian funkciadon antaÅ­ ol Äi estos plene havebla?
+STR_8102_RAILROAD_LOCOMOTIVE :fervoja lokomotivo
+STR_8103_ROAD_VEHICLE :vojveturilo
+STR_8104_AIRCRAFT :aviadilo
+STR_8105_SHIP :Åipo
+STR_8106_MONORAIL_LOCOMOTIVE :unurellokomotivo
+STR_8107_MAGLEV_LOCOMOTIVE :magleva lokomotivo
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}{TOWN} Trajndeponejo
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}EnloÄantoj festas . . .{}Unua trajno alvenas ĉe {STATION}!
+STR_8802_DETAILS :{WHITE}{STRING} (Detaloj)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Trajno okupas la lokon
+STR_8804 :{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8806_GO_TO :Iru al {STATION}
+STR_8807_GO_TO_TRANSFER :Iru al {STATION} (Transigu kaj prenu ÅarÄon)
+STR_8808_GO_TO_UNLOAD :Iru al {STATION} (DeÅarÄu)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Iru al {STATION} (Transigu kaj lasu malplena)
+STR_880A_GO_TO_LOAD :Iru al {STATION} (ÅœarÄu)
+STR_880B_GO_TO_TRANSFER_LOAD :Iru al {STATION} (Transigu kaj atendu Äis plena ÅarÄo)
+STR_880C_GO_NON_STOP_TO :Iru senhalte al {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Iru senhalte al {STATION} (Transigu kaj prenu ÅarÄon)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Iru senhalte al {STATION} (DeÅarÄu)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Iru senhalte al {STATION} (Transigu kaj lasu malplena)
+STR_8810_GO_NON_STOP_TO_LOAD :Iru senhalte al {STATION} (ÅœarÄu)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Iru senhalte al {STATION} (Transigu kaj atendu Äis plena ÅarÄo)
+STR_GO_TO_TRAIN_DEPOT :Iru al {TOWN} Trajndeponejo
+STR_SERVICE_AT_TRAIN_DEPOT :Prizorgo ĉe {TOWN} Trajndeponejo
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Iru senhalte al {TOWN} Trajndeponejo
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Prizorgo senhalte ĉe {TOWN} Trajndeponejo
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}Irante al {TOWN} Trajndeponejo
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}Irante al {TOWN} Trajndeponejo, {VELOCITY}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE :{LTBLUE}Prizorgo ĉe {TOWN} Trajndeponejo
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE_VEL :{LTBLUE}Prizorgo ĉe {TOWN} Trajndeponejo, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (Nevalida Ordeno)
+
+STR_UNKNOWN_DESTINATION :nekonata destino
+STR_8812_EMPTY :{LTBLUE}Malplena
+STR_8813_FROM :{LTBLUE}{CARGO} de {STATION}
+STR_FROM_MULT :{LTBLUE}{CARGO} de {STATION} (x{NUM})
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}Trajno {COMMA} atendas en deponejo
+STR_8815_NEW_VEHICLES :{BLACK}Novaj Veturiloj
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Trajno tro longas
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Trajno nut povas esti adaptataj kiam halte en deponejo
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} Trajno{P "" j}
+
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Novaj Relaj Veturiloj
+STR_NEW_ELRAIL_VEHICLES :{WHITE}Novaj Elektraj Relaj Veturiloj
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Novaj Unurelaj Veturiloj
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Novaj Maglevaj Veturiloj
+STR_ALL_AVAIL_RAIL_VEHICLES :{WHITE}Vojveturiloj
+
+STR_881F_BUILD_VEHICLE :{BLACK}Kreu Veturilon
+STR_CLONE_ROAD_VEHICLE :{BLACK}Klonu Veturilon
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}Ĉi tiel konstruu kopion de la vojveturilo. CTRL+klako dividos la ordenojn
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Ĉi tio konstruas kopion de la vojveturilo. Alklaku ĉi tiun butenon kaj poste veturilon en aŭ ekster deponejo. CTRL+klako dividos la ordenojn
+STR_CLONE_TRAIN :{BLACK}Klonu Trajnon
+STR_CLONE_TRAIN_INFO :{BLACK}Ĉi tiel konstruu kopion de la trajno kun ĉiuj vagonoj. CTRL+klako dividos la ordenojn
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}Ĉi tio konstruas kopion de la trajno kun ĉiuj vagonoj. Alklaku ĉi tiun butenon kaj poste trajnon en aŭ ekster deponejo. CTRL+klako dividos la ordenojn
+STR_8820_RENAME :{BLACK}Renomu
+STR_8823_SKIP :{BLACK}Plusaltu
+STR_8824_DELETE :{BLACK}ForviÅu
+STR_8825_NON_STOP :{BLACK}Senhalte
+STR_8826_GO_TO :{BLACK}Iru al
+STR_8827_FULL_LOAD :{BLACK}Plene ÅarÄu
+STR_8828_UNLOAD :{BLACK}DeÅarÄu
+STR_REFIT :{BLACK}Transformu
+STR_REFIT_TIP :{BLACK}Elektu ÅarÄtipon por transformo en ĉi tiu ordeno. CTRL+klako por forigi instrukcion
+STR_REFIT_ORDER :(Transformu al {STRING})
+STR_8829_ORDERS :{WHITE}{VEHICLE} (Ordenoj)
+STR_882A_END_OF_ORDERS :{SETX 10}- - Fino de Ordenoj - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}Prizorgo
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Ne povas krei relan veturilon...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Kreite: {LTBLUE}{NUM}{BLACK} Valoro: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Valoro: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}ÅœarÄante / DeÅarÄante
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}Trajno estu halta en deponejo
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Ne povas sendi trajnon al deponejo...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Ne plu spaco por ordenoj
+STR_8832_TOO_MANY_ORDERS :{WHITE}Tro da ordenoj
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Ne povas enigi novan ordenon...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Ne povas forviÅi ĉi tiun ordenon...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Ne povas ÅanÄi ĉi tiun ordenon...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Ne povas movi veturilon
+STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}La malantaÅ­a maÅino ĉiam sekvos la antaÅ­an
+STR_8838_N_A :N/A{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Ne povas vendi relan veturilon...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Ne eblas trovi lokan deponejon
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Ne povas haltigi/starti trajnon...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Prizorga intervalo: {LTBLUE}{COMMA}tagoj{BLACK} Lasta prizorgo: {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Prizorga intervalo: {LTBLUE}{COMMA}%{BLACK} Lasta prizorgo: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Trajnoj - alklaku trajnon por pliaj informoj
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Kreu novajn trajnojn (bezonas trajndeponejon)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Trajnoj - alklaku trajnon por scii pli, tiru veturilon por aldoni aÅ­ forigi de trajno
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Kreu novan trajnan veturilon
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Tiru trajnan veturilon ĉi tien por vendi
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centre vidu la trajndeponejon en la ĉefvido
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Trajnveturila elektolisto - alklaku veturilon por informoj
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Kreu la elektitan trajnan veturilon
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Renomu trajnveturilan tipon
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Nuna trajna ago - klaku por haltigi/starti la trajnon
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Montru trajnajn ordenojn
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centre vidu trajnan lokon en la ĉefvido
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Sendu trajnon al deponejo. CTRL+klako nur prizorgos
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Igu trajnon iri malgraÅ­ signalo
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Inversigu trajnan direkton
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Montru trajnajn detalojn
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Pliigu prizorgintervalon
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Malpliigu prizorgintervalon
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Montru detalojn de portata ÅarÄo
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Montru detalojn de trajnaj veturiloj
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Montru kapablojn de ĉiu veturilo
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Montru tutan kapablon de trajno, dividite laÅ­ ÅarÄtipo
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Ordena listo - alklaku ordenon por elekti. CTRL + klako skrolas al la stacio
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}Saltu de la nuna ordeno al la sekva
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}ForviÅu la elektitan ordenon
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Senhaltigu elektitan ordenon
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Enigu novan ordenon antaÅ­ la elektita ordeno, aÅ­ aldonu fine de la listo
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}La elektita ordeno igu la veturilon atendi Äis plena ÅarÄo
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}La elektita ordeno igu la veturilon deÅarÄi
+STR_SERVICE_HINT :{BLACK}Transsaltu ordenon Äis prizorgo necesos
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}Nova {STRING} nun haveblas!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Kosto: {CURRENCY} Pezo: {WEIGHT_S}{}Rapideco: {VELOCITY} Forto: {POWER}{}Irkosto: po {CURRENCY} jare{}Kapablo: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}Rompite
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}AÄo: {LTBLUE}{STRING}{BLACK} Irkosto: {LTBLUE}po {CURRENCY} jare
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Pezo: {LTBLUE}{WEIGHT_S} {BLACK}Forto: {LTBLUE}{POWER}{BLACK} Pleja rapideco: {LTBLUE}{VELOCITY}
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Pezo: {LTBLUE}{WEIGHT_S} {BLACK}Forto: {LTBLUE}{POWER}{BLACK} Pleja rapido: {LTBLUE}{VELOCITY} {BLACK}Pleja tiro: {LTBLUE}{FORCE}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Ĉi-jara gajno: {LTBLUE}{CURRENCY} (lastjara: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}Fidebleco: {LTBLUE}{COMMA}% {BLACK}RompiÄoj post lasta prizorgo: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Haltis
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Ne povas igi trajnon transiri signalon je danÄero...
+STR_8863_CRASHED :{RED}KraÅis!
+
+STR_8865_NAME_TRAIN :{WHITE}Nomu trajnon
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}Ne povas nomi trajnon...
+STR_8867_NAME_TRAIN :{BLACK}Nomu trajnon
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Trajna KraÅo!{}{COMMA} mortis pro fajro post kolizio
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Ne povas inversigi direkton de trajno...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Renomu trajnan veturiltipon
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Ne povas renomi trajnan veturiltipon...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}La elektita ordeno igu la veturilon demeti la ÅarÄon
+STR_886F_TRANSFER :{BLACK}Transigu
+
+STR_TRAIN_STOPPING :{RED}HaltiÄas
+STR_TRAIN_STOPPING_VEL :{RED}HaltiÄas, {VELOCITY}
+STR_INCOMPATIBLE_RAIL_TYPES :NeinterÅanÄeblaj reltipoj
+STR_TRAIN_NO_POWER :{RED}Senforte
+STR_TRAIN_START_NO_CATENARY :Mankas ĉi-trake supera elektro, do la trajno ne povas starti
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Vojveturilo okupas la lokon
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} Vojveturilo{P "" j}
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}{TOWN} Vojveturila Deponejo
+STR_9004_NEW_VEHICLES :{BLACK}Novaj Veturiloj
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}Novaj Vojveturiloj
+STR_9007_BUILD_VEHICLE :{BLACK}Kreu Veturilon
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Ne povas krei vojveturilon
+STR_900C_DETAILS :{WHITE}{VEHICLE} (Detaloj)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}AÄo: {LTBLUE}{STRING}{BLACK} Irkosto: {LTBLUE}po {CURRENCY} jare
+STR_900E_MAX_SPEED :{BLACK}Maksimuma rapideco: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Ĉi-jara gajno: {LTBLUE}{CURRENCY} (lastjara: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}Fidebleco: {LTBLUE}{COMMA}% {BLACK}RompiÄoj post lasta prizorgo: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Kreite: {LTBLUE}{NUM}{BLACK} Valoro: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Kapablo: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}...devas esti haltigata en vojveturila deponejo
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Ne povas vendi vojveturilon...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Ne povas haltigi/starti vojveturilon...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}Vojveturilo {COMMA} atendas en deponejo
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}Irante al {TOWN} Voja Deponejo
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}Irante al {TOWN} Voja Deponejo, {VELOCITY}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE :{LTBLUE}Prizorgo ĉe {TOWN} Voja Deponejo
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE_VEL :{LTBLUE}Prizorgo ĉe {TOWN} Voja Deponejo, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Ne povas sendi veturilon al deponejo...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Ne eblas trovi lokan deponejon
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Vojveturiloj - alklaku veturilon por informoj
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Kreu novajn vojveturilojn (bezonas vojveturilan deponejon)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Nuna veturila ago - klaku ĉi tie por haltigi/starti veturilon
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Montru veturilajn ordenojn
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Centre vidu la veturilon en la ĉefvido
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Sendu veturilon al deponejo. CTRL+klako nur prizorgos
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Igu veturilon ĉirkaŭturni
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Montru vojveturilajn detalojn
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Veturiloj - alklaku veturilojn por informoj
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Kreu novan vojveturilon
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Tiru vojveturilon ĉi tien por vendi
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Centre vidu vojveturilan deponejon en la ĉefvido
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Vojveturilelektan liston - alklaku veturilon por informoj
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Kreu la elektitan vojveturilon
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}Nova vojveturilo nun haveblas!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Kosto: {CURRENCY}{}Rapideco: {VELOCITY}{}Irkosto: po {CURRENCY} jare{}Kapablo: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Nomu vojveturilon
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Ne povas nomi vojveturilon...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Nomu vojveturilon
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}EnloÄantoj festas . . .{}Unua buso alvenas en {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}EnloÄantoj festas . . .{}Unua ÅarÄaÅ­to alvenas en {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}Vojveturila kraÅo!{}Veturanto mortas pro fajro post kolizio kun trajno
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}Vojveturila KraÅo!{}{COMMA} mortas pro fajro post kolizio kun trajno
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Ne povas ĉirkaŭturni veturilon...
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}Ne povas turni veturilojn konsistantaj el pluraj unuoj
+STR_9034_RENAME :{BLACK}Renomu
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Renomu vojveturilan tipon
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Renomu vojveturilan tipon
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Ne povas renomi vojveturilan tipon...
+STR_9038_GO_TO_ROADVEH_DEPOT :Iru al {TOWN} Vojveturila Deponejo
+STR_SERVICE_AT_ROADVEH_DEPOT :Prizorgo ĉe {TOWN} Vojveturila Deponejo
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Transformu vojveturilon por porti alian ÅarÄon
+STR_REFIT_ROAD_VEHICLE :{BLACK}Transformu vojveturilon
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Transformu vojveturilon por porti elektitan ÅarÄon
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Ne povas transformi vojveturilon...
+STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Elektu portotan ÅarÄon de la vojveturilo
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Havenkonstruado
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Havenkonstruado
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Ne povas konstrui havenon ĉi tie...
+STR_9803_SHIP_DEPOT :{WHITE}{TOWN} Åœipdeponejo
+STR_9804_NEW_SHIPS :{BLACK}Novaj Åœipoj
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} Åœipo{P "" j}
+STR_9808_NEW_SHIPS :{WHITE}Novaj Åœipoj
+STR_9809_BUILD_SHIP :{BLACK}Kreu Åœipon
+STR_CLONE_SHIP :{BLACK}Klonu Åœipon
+STR_CLONE_SHIP_INFO :{BLACK}Ĉi tiel konstruu kopion de la Åipo. CTRL+klako dividos la ordenojn
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}Ĉi tio konstruas kopion de la Åipo. Alklaku ĉi tiun butenon kaj poste Åipon en aÅ­ ekster deponejo. CTRL+klako dividos la ordenojn
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}Åœipo devas halti en deponejo
+STR_980C_CAN_T_SELL_SHIP :{WHITE}Ne povas vendi Åipon...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Ne povas krei Åipon...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Åœipo okupas la lokon
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Detaloj)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}AÄo: {LTBLUE}{STRING}{BLACK} Irkosto: {LTBLUE}po {CURRENCY} jare
+STR_9813_MAX_SPEED :{BLACK}Maksimuma rapideco: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Ĉi-jara gajno: {LTBLUE}{CURRENCY} (lastjara: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}Fidebleco: {LTBLUE}{COMMA}% {BLACK}RompiÄoj post lasta prizorgo: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Kreite: {LTBLUE}{NUM}{BLACK} Valoro: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}Kapablo: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}Ne povas haltigi/starti Åipon...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Ne povas sendi Åipon al deponejo...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Ne eblas trovi lokan deponejon
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}Irante al {TOWN} Åœipdeponejo
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}Irante al {TOWN} Åœipdeponejo, {VELOCITY}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE :{LTBLUE}Prizorgo ĉe {TOWN} Ŝipdeponejo
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE_VEL :{LTBLUE}Prizorgo ĉe {TOWN} Ŝipdeponejo, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}Åœipo {COMMA} atendas en deponejo
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Konstruu havenon
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Konstruu Åipdeponejon (por krei kaj prizorgi Åipojn)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Åœipoj - alklaku Åipon por informoj
+STR_9820_BUILD_NEW_SHIP :{BLACK}Kreu novan Åipon
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Tiru Åipon ĉi tien por vendi
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centre vidu Åipdeponejon en ĉefvido
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Åœipoj - alklaku Åipon por informoj
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Kreu novajn Åipojn (bezonas Åipdeponejon)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}Åœipelekta listo - alklaku Åipon por informoj
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Kreu elektitan Åipon
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Nuna Åipa ago - klaku ĉi tie por haltigi/starti Åipon
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Montru Åipajn ordenojn
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centre vidu Åipon en ĉefvido
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Sendu Åipon al deponejo. CTRL+klako nur prizorgos
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Montru Åipajn detalojn
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}Nova Åipo nun haveblas!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Kosto: {CURRENCY} Maksimuma rapideco: {VELOCITY}{}Kapablo: {CARGO}{}Irkosto: po {CURRENCY} jare
+STR_982F_NAME_SHIP :{BLACK}Nomu Åipon
+
+STR_9831_NAME_SHIP :{WHITE}Nomu Åipon
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Ne povas nomi Åipon...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}EnloÄantoj festas . . .{}Unua Åipo alvenas en {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Metu buon kiu povas esti uzata kiel trairejo
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Ne povas meti buon ĉi tie...
+STR_9836_RENAME :{BLACK}Renomu
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Renomu Åiptipon
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Renomu Åiptipon
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Ne povas renomi Åiptipon...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Transformu ÅarÄÅipon por porti alian ÅarÄon
+STR_983B_REFIT :{WHITE}{VEHICLE} (Transformu)
+STR_983C_REFIT_SHIP :{BLACK}Transformu Åipon
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Elektu portotan ÅarÄotipon
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Transformu Åipon por porti elektitan ÅarÄotipon
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Elektu ÅarÄotipon por porti:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nova kapablo: {GOLD}{CARGO}{}{BLACK}Transformkosto: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Ne povas transformi Åipon...
+STR_9842_REFITTABLE :(transformebla)
+STR_GO_TO_SHIP_DEPOT :Iru al {TOWN} Åœipdeponejo
+SERVICE_AT_SHIP_DEPOT :Prizorgo en la Åipdeponejo de {TOWN}
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Flughavenoj
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Ne povas konstrui flughavenon ĉi tie...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} Hangaro
+STR_A003_NEW_AIRCRAFT :{BLACK}Novaj Aviadiloj
+STR_CLONE_AIRCRAFT :{BLACK}Klonu aviadilon
+STR_CLONE_AIRCRAFT_INFO :{BLACK}Ĉi tio konstruas kopion de la aviadilo. CTRL+klako dividos la ordenojn
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Ĉi tio konstruas kopion de la aviadilo. Alklaku ĉi tiun butenon kaj poste aviadilon en aŭ ekster hangaro. CTRL+klako dividos la ordenojn
+STR_A005_NEW_AIRCRAFT :{WHITE}Novaj Aviadiloj
+STR_A006_BUILD_AIRCRAFT :{BLACK}Kreu Aviadilon
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Ne povas krei aviadilon...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} Aviadiloj
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (Ordenoj)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (Detaloj)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}AÄo: {LTBLUE}{STRING}{BLACK} Irkosto: {LTBLUE}po {CURRENCY} jare
+STR_A00E_MAX_SPEED :{BLACK}Maksimuma rapideco: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Ĉi-jara gajno: {LTBLUE}{CURRENCY} (lastjara: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}Fidebleco: {LTBLUE}{COMMA}% {BLACK}RompiÄoj post lasta prizorgo: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Kreite: {LTBLUE}{NUM}{BLACK} Valoro: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Ne povas sendi aviadilon al hangaro...
+STR_HEADING_FOR_HANGAR :{ORANGE}Irante al {STATION} Hangaro
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}Irante al {STATION} Hangaro, {VELOCITY}
+STR_HEADING_FOR_HANGAR_SERVICE :{LTBLUE}Prizorgo ĉe {STATION} Hangaro
+STR_HEADING_FOR_HANGAR_SERVICE_VEL :{LTBLUE}Prizorgo ĉe {STATION} Hangaro, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}Aviadilo {COMMA} atendas en la hangaro
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Aviadilo okupas la lokon
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Ne povas haltigi/starti aviadilon...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Aviadilo flugas
+STR_A019_CAPACITY :{BLACK}Kapablo: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Kapablo: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}Aviadilo devas esti haltigata en la hangaro
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Ne povas vendi aviadilon...
+STR_A01D_AIRPORT_CONSTRUCTION :Flughavena konstruado
+STR_A01E_BUILD_AIRPORT :{BLACK}Kreu flughavenon
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Aviadiloj - alklaku aviadilon por informoj
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Kreu novan aviadilon (bezonas flughavenon kun hangaro)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Aviadiloj - alklaku aviadilon por informoj
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Kreu novan aviadilon
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}DTiru aviadilon ĉi tien por vendi
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Centre vidu hangaron en la ĉefvido
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Aviadilelekta listo - alklaku aviadilon por informoj
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Kreu la elektitan aviadilon
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Nuna aviadila ago - klaku ĉi tie por haltigi/starti aviadilon
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Montru aviadilajn ordenojn
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Centre vidu aviadilon en la ĉefvido
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Sendu aviadilon al hangaro. CTRL+klako nur prizorgos
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Montru aviadilajn detalojn
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}Nova aviadilo nun haveblas!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Kosto: {CURRENCY} Maksimuma rapideco: {VELOCITY}{}Kapablo: {COMMA} pasaÄeroj, {COMMA} sakoj da poÅto{}Irkosto: po {CURRENCY} jare
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Nomu aviadilon
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Ne povas nomi aviadilon...
+STR_A032_NAME_AIRCRAFT :{BLACK}Nomu aviadilon
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}EnloÄantoj festas . . .{}Unua aviadilo alvenas en {STATION}!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Aviadilo KraÅas!{}{COMMA} mortas pro fajro en {STATION}
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Aviadila KraÅo!{}Aviadilo ne havis sufiĉan brulaĵon, {COMMA} mortas pro fajro!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Renomu
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Renomu aviadiltipon
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Renomu aviadiltipon
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Ne povas renomi aviadiltipon...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Transformu aviadilon por porti alian ÅarÄotipon
+STR_A03C_REFIT :{WHITE}{VEHICLE} (Transformu)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Transformu aviadilon
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Elektu portotan ÅarÄon de aviadilo
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Transformu aviadilon por porti elektitan ÅarÄotipon
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Elektu ÅarÄtipon por porti:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nova kapablo: {GOLD}{STRING}{}{BLACK}Transformkosto: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Ne povas reformi aviadilon...
+STR_GO_TO_AIRPORT_HANGAR :Iru al {STATION} Hangaro
+SERVICE_AT_AIRPORT_HANGAR :Prizorgo en la hangaro de {STATION}
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}Zepelina katastrofo en {STATION}!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Vojveturilo detruita en 'UFO'-kolizio!
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}Oleprodukteja eksplodo ĉe {TOWN}!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}Farejo detruita en suspektataj cirkonstancooj ĉe {TOWN}!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}'UFO' landiÄas ĉe {TOWN}!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}Karbmineja terÅoviÄo lasas trakon da detruado ĉe {TOWN}!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Fluegoj!{}AlmenaÅ­ {COMMA} mankas kaj verÅajne mortis pro signifoplena fluego!
+
+STR_BRIBE_FAILED :{WHITE}Via subaĉeta provo estas
+STR_BRIBE_FAILED_2 :{WHITE}malkovrita de regiona esploristo
+STR_BUILD_DATE :{BLACK}Kreite: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Detala rendimento
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}Detaloj
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Veturiloj:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Stacioj:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Malpleja gajno:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Malpleja enspezo:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Pleja enspezo:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Liverite:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}ÅœarÄo:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Mono:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Prunto:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Entute:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Nombro da veturiloj; tio enkalkulas vojveturilojn, trajnojn, Åipojn kaj aviadilojn
+STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}Nombro da staciaj eroj. Ĉiu parto de stacio (ekz. stacidomo, bushaltejo, flughaveno) kalkuliÄas, eĉ se konektite kiel unu stacio
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}La gajno de la malplejenspeza veturilo (de ĉiuj veturiloj pli aÄaj ol 2 jaroj)
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Enspezite en la plej malaltenspeza monato de la lasta 12 kvaronoj
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Enspezite en la plej altenspeza monato de la lasta 12 kvaronoj
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}ÅœarÄunuoj liveritaj en la lastaj 4 kvaronoj
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}Nombro da ÅarÄtipoj liveritaj en la lasta kvarono
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Monkvanto de ĉi tiu kompanio en la banko
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}La monkvanto pruntita de ĉi tiu kompanio
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Entuta poentaro el eblaj poentoj
+
+STR_NEWGRF_SETTINGS_BUTTON :{BLACK}Agordoj de NewGRF
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}Agordoj de NewGRF
+STR_NEWGRF_APPLY_CHANGES :{BLACK}Apliku ÅanÄojn
+STR_NEWGRF_SET_PARAMETERS :{BLACK}Agordu parametrojn
+STR_NEWGRF_TIP :{BLACK}Listo da ĉiuj instalitaj Newgrf-aj aroj. Alklaku aron por ÅanÄi la agordojn
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}Nun ne estas instalitaj newgrf-dosieroj! Bonvolu legi la manlibron por ekscii kiel instali novajn grafikaĵojn
+STR_NEWGRF_FILENAME :{BLACK}Dosiernomo: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
+STR_NEWGRF_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING}
+STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}Vi ĉi tiel ÅanÄos al kuranta ludo; tio povas kraÅigi la ludon.{}Ĉu vi nepre volas fari tion?
+
+STR_NEWGRF_ADD :{BLACK}Aldonu
+STR_NEWGRF_ADD_TIP :{BLACK}Aldonu NewGRF-dosieron al la listo
+STR_NEWGRF_REMOVE :{BLACK}ForviÅu
+STR_NEWGRF_REMOVE_TIP :{BLACK}Remove the selected NewGRF file from the list
+STR_NEWGRF_MOVEUP :{BLACK}Supren
+STR_NEWGRF_MOVEUP_TIP :{BLACK}Movu la elektitan NewGRF-dosieron supren en la listo
+STR_NEWGRF_MOVEDOWN :{BLACK}Malsupren
+STR_NEWGRF_MOVEDOWN_TIP :{BLACK}Movu la elektitan NewGRF-dosieron malsupren en la listo
+STR_NEWGRF_FILE_TIP :{BLACK}Listo da instalitaj NewGRF-dosieroj. Alklaku dosieron por ÅanÄi la parametrojn
+STR_NEWGRF_PARAMETER :{BLACK}Parametroj: {SILVER}{STRING}
+STR_NEWGRF_PARAMETER_QUERY :{BLACK}Enigu NewGRF-parametrojn
+STR_NEWGRF_NO_INFO :{BLACK}Ne haveblas informoj
+
+STR_NEWGRF_ADD_CAPTION :{WHITE}Haveblaj NewGRF-dosieroj
+STR_NEWGRF_ADD_FILE :{BLACK}Aldonu al elekto
+STR_NEWGRF_ADD_FILE_TIP :{BLACK}Aldonu la elektitan NewGRF-dosieron al viaj agordoj
+STR_NEWGRF_RESCAN_FILES :{BLACK}Reserĉu dosierojn
+STR_NEWGRF_RESCAN_FILES_TIP :{BLACK}Äœisdatigu la liston da haveblaj NewGRF-dosieroj
+STR_NEWGRF_DUPLICATE_GRFID :{WHITE}Ne povas aldoni dosieron: duobla GRF ID
+
+STR_NEWGRF_NOT_FOUND :{RED}Ne trovis apartenan dosieron
+STR_NEWGRF_DISABLED :{RED}Malaktiva
+
+STR_CURRENCY_WINDOW :{WHITE}Alia monunuo
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}InterÅanÄa valoro: {ORANGE}{CURRENCY} = £ {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Dividilo:
+STR_CURRENCY_PREFIX :{LTBLUE}Prefikso:
+STR_CURRENCY_SUFFIX :{LTBLUE}Sufikso:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}ÅœanÄu al EÅ­roj: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}ÅœanÄu al EÅ­roj: {ORANGE}neniam
+STR_CURRENCY_PREVIEW :{LTBLUE}AntaÅ­vido: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}ÅœanÄu parametron por alia monunuo
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} Trajno{P "" j}
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} Vojveturilo{P "" j}
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} Aviadilo{P "" j}
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} Åœipo{P "" j}
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Montru ĉiujn trajnojn kun ĉi tiu stacio en la plano
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Montru ĉiujnvojveturilojn kun ĉi tiu stacio en la plano
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Montru ĉiujn aviadilojn kun ĉi tiu stacio en la plano
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Montru ĉiujn Åipojn kun ĉi tiu stacio en la plano
+
+STR_VEH_WITH_SHARED_ORDERS_LIST :{WHITE}Dividitaj ordenoj de {COMMA} Veturilo{P "" j}
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}Montru ĉiujn veturilojn kiuj dividas ĉi tiun planon
+
+### depot strings
+STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Vi volas vendi ĉiujn veturilojn en la deponejo. Ĉu vi certas?
+
+STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP :{BLACK}Vendu ĉiujn trajnojn en la deponejo
+STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP :{BLACK}Vendu ĉiujn vojveturilojn en la deponejo
+STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP :{BLACK}Vendu ĉiujn Åipojn en la deponejo
+STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP :{BLACK}Vendu ĉiujn aviadilojn en la hangaro
+
+STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP :{BLACK}Akiru liston da trajnoj kun ĉi tiu deponejo en siaj ordenoj
+STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP :{BLACK}Akiru liston da ĉiuj vojveturiloj kun ĉi tiu deponejo en siaj ordenoj
+STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP :{BLACK}Akiru liston da ĉiuj Åipoj kun ĉi tiu deponejo en siaj ordenoj
+STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP :{BLACK}Akiru liston da ĉiuj aviadiloj kun ajna hangaro en ĉi tiu flughaveno en siaj ordenoj
+
+STR_DEPOT_AUTOREPLACE_TRAIN_TIP :{BLACK}Aŭtomate anstataŭu ĉiujn trajnojn en la deponejo
+STR_DEPOT_AUTOREPLACE_ROADVEH_TIP :{BLACK}Aŭtomate anstataŭu ĉiujn vojveturilojn en la deponejo
+STR_DEPOT_AUTOREPLACE_SHIP_TIP :{BLACK}AÅ­tomate anstataÅ­u ĉiujn Åipojn en la deponejo
+STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP :{BLACK}Aŭtomate anstataŭu ĉiujn aviadilojn en la hangaro
+
+STR_VEHICLE_LIST_ROADVEH_DEPOT :{BLACK}{STRING} - {COMMA} Vojveturilo{P "" j}
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} Åœipo{P "" j}
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} Aviadilo{P "" j}
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}AnstataÅ­u {STRING.n}
+STR_REPLACE_VEHICLES_START :{BLACK}Komencu AnstataÅ­i
+STR_REPLACE_VEHICLES_STOP :{BLACK}Ĉesu Anstataŭi
+STR_NOT_REPLACING :{BLACK}Ne anstataÅ­ante
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Ne elektiÄis veturilo
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Elektu maÅinon por anstataÅ­i
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Elektu novan maÅinon por uzi anstataÅ­ la maldekstre elektitan
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Premu por ĉesi anstataÅ­i la maldekstre elektitan maÅinon
+STR_REPLACE_HELP_START_BUTTON :{BLACK}Premu por komenci anstataÅ­i la maldekstre elektitan maÅinon per la dekstre elektitan
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Elektu fervojtipon por kiu vi volas anstataÅ­igi maÅinojn
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Montras ontan maÅinecon de la maldekstra maÅino, se anstataÅ­ote
+STR_REPLACE_HELP :{BLACK}Ĉi tio permesas vin anstataÅ­i maÅinojn de unu al alia tipo, kiam trajnoj de la unu tipo eniras la deponejon
+STR_REPLACE_REMOVE_WAGON :{BLACK}Vagonforigo: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Ĉe aÅ­tomata anstataÅ­igo tenu saman longecon de la trajno per forigo de vagonoj (defronte), se per nova maÅino la trajno plilongiÄas
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}AnstataÅ­ante: {ORANGE}{SKIP}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} EKSPERIMENTA AÄ´O {}Åœaltu inter maÅina kaj vagona anstataÅ­igo.{}Vagona anstataÅ­igo nur okazos se la nova vagono povas transformiÄi por porti saman ÅarÄon kiel la malnova. Por ĉiu vagono tio kontroliÄos dum anstataÅ­ado.
+STR_ENGINE_NOT_BUILDABLE :{WHITE}MaÅino ne kreeblas
+
+STR_ENGINES :MaÅinoj
+STR_WAGONS :Vagonoj
+
+STR_MASS_STOP_DEPOT_TRAIN_TIP :{BLACK}Alklaku por haltigi ĉiujn trajnojn en la deponejo
+STR_MASS_STOP_DEPOT_ROADVEH_TIP :{BLACK}Alklaku por haltigi ĉiujn vojveturilojn en la deponejo
+STR_MASS_STOP_DEPOT_SHIP_TIP :{BLACK}Alklaku por haltigi ĉiujn Åipojn en la deponejo
+STR_MASS_STOP_HANGAR_TIP :{BLACK}Alklaku por haltigi ĉiujn aviadilojn en la hangaro
+
+STR_MASS_START_DEPOT_TRAIN_TIP :{BLACK}Alklaku por starti ĉiujn trajnojn en la deponejo
+STR_MASS_START_DEPOT_ROADVEH_TIP :{BLACK}Alklaku por starti ĉiujn vojveturilojn en la deponejo
+STR_MASS_START_DEPOT_SHIP_TIP :{BLACK}Alklaku por starti ĉiujn Åipojn en la deponejo
+STR_MASS_START_HANGAR_TIP :{BLACK}Alklaku por starti ĉiujn aviadilojn en la hangaro
+
+STR_MASS_STOP_LIST_TIP :{BLACK}Alklaku por haltigi ĉiujn veturilojn en la listo
+STR_MASS_START_LIST_TIP :{BLACK}Alklaku por starti ĉiujn veturilojn en la listo
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}Signolisto - {COMMA} Signo{P "" j}
+
+STR_ORDER_REFIT_FAILED :{WHITE}Fiasko de ordeno transformi haltigis {STRING.n} {COMMA}
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :Relaj Veturiloj
+STR_ELRAIL_VEHICLES :Elektraj Relaj Veturiloj
+STR_MONORAIL_VEHICLES :Unurelaj Veturiloj
+STR_MAGLEV_VEHICLES :Maglevaj Veturiloj
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Kosto: {GOLD}{CURRENCY}{BLACK} Pezo: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Rapido: {GOLD}{VELOCITY}{BLACK} Forto: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}Rapido: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Irkosto: {GOLD}po {CURRENCY} jare
+STR_PURCHASE_INFO_CAPACITY :{BLACK}Kapablo: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Pripensite: {GOLD}{NUM}{BLACK} Vivlongo: {GOLD}{COMMA} jaroj
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}Pleja Fidebleco: {GOLD}{COMMA}%
+STR_PURCHASE_INFO_COST :{BLACK}Kosto: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Pezo: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Kosto: {GOLD}{CURRENCY}{BLACK} Rapido: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Kapablo: {GOLD}{COMMA} pasaÄeroj, {COMMA} sakoj da poÅto
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Vagonfortoj: {GOLD}+{POWER}{BLACK} Weight: {GOLD}+{WEIGHT_S}
+STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Transformebla al: {GOLD}
+STR_PURCHASE_INFO_ALL_TYPES :Ĉiaj ÅarÄoj
+STR_PURCHASE_INFO_ALL_BUT :Ĉio krom {GOLD}
+STR_PURCHASE_INFO_MAX_TE :{BLACK}Maksimuma Tiro: {GOLD}{FORCE}
+
+########### String for New Landscape Generator
+
+STR_GENERATE :{WHITE}Generu
+STR_RANDOM :{BLACK}Hazardigu
+STR_RANDOM_HELP :{BLACK}ÅœanÄo la hazardan enigon uzatan de la terengenerilo
+STR_WORLD_GENERATION_CAPTION :{WHITE}Mondgenerado
+STR_RANDOM_SEED :{BLACK}Hazarda Enigo:
+STR_RANDOM_SEED_HELP :{BLACK}Klaku por enigi hazardan enigon
+STR_LAND_GENERATOR :{BLACK}Landgenerilo:
+STR_TREE_PLACER :{BLACK}Arba algoritmo:
+STR_HEIGHTMAP_ROTATION :{BLACK}Altecmapa turniÄo:
+STR_TERRAIN_TYPE :{BLACK}Terentipo:
+STR_QUANTITY_OF_SEA_LAKES :{BLACK}Marnivelo:
+STR_SMOOTHNESS :{BLACK}Ebeneco:
+STR_SNOW_LINE_HEIGHT :{BLACK}NeÄlinia alteco:
+STR_DATE :{BLACK}Dato:
+STR_NUMBER_OF_TOWNS :{BLACK}Kiom da urboj:
+STR_NUMBER_OF_INDUSTRIES :{BLACK}Kiom da industrioj:
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_SNOW_LINE_UP :{BLACK}Altigu la neÄlinion per unu
+STR_SNOW_LINE_DOWN :{BLACK}Malaltigu la neÄlinion per unu
+STR_SNOW_LINE_QUERY_CAPT :{WHITE}ÅœanÄu altecon de la neÄlinio
+STR_START_DATE_QUERY_CAPT :{WHITE}ÅœanÄu komencjaron
+STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Skala averto
+STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Ne rekomendindas tro ÅanÄi la grandecon de la mapo. Ĉu daÅ­rigi la generadon?
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_HEIGHTMAP_NAME :{BLACK}Altecmapa nomo:
+STR_HEIGHTMAP_SIZE :{BLACK}Grandeco: {ORANGE}{NUM} x {NUM}
+STR_GENERATION_WORLD :{WHITE}Generante mondon...
+STR_GENERATION_ABORT :{BLACK}Ĉesu
+STR_GENERATION_ABORT_CAPTION :{WHITE}Ĉesu generi mondon
+STR_GENERATION_ABORT_MESSAGE :{YELLOW}Ĉu vi vere volas ĉesi generi mondon?
+STR_PROGRESS :{WHITE}{NUM}% komplete
+STR_GENERATION_PROGRESS :{BLACK}{NUM} / {NUM}
+STR_WORLD_GENERATION :{BLACK}Mondgenerado
+STR_TREE_GENERATION :{BLACK}Arba generado
+STR_UNMOVABLE_GENERATION :{BLACK}Nemoveblaĵa generado
+STR_CLEARING_TILES :{BLACK}Generado de malglataj kaj rokaj regionoj
+STR_SETTINGUP_GAME :{BLACK}Agordante ludon
+STR_PREPARING_TILELOOP :{BLACK}Trakurante kvadratojn
+STR_PREPARING_GAME :{BLACK}Preparante ludon
+STR_DIFFICULTY_TO_CUSTOM :{WHITE}Ĉi tiu ago ÅanÄis la malfacilec-nivelon al 'ÅanÄite'
+STR_SE_FLAT_WORLD :{WHITE}Ebena lando
+STR_SE_FLAT_WORLD_TIP :{BLACK}Generu ebenan landon
+STR_SE_RANDOM_LAND :{WHITE}Hazarda lando
+STR_SE_NEW_WORLD :{BLACK}Kreu novan scenaron
+STR_SE_CAPTION :{WHITE}Scenara tipo
+STR_FLAT_WORLD_HEIGHT_DOWN :{BLACK}Malaltigu la altecon de ebena lando per unu
+STR_FLAT_WORLD_HEIGHT_UP :{BLACK}Altigu la altecon de ebena lando per unu
+STR_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}ÅœanÄu altecon de ebena lando
+STR_FLAT_WORLD_HEIGHT :{BLACK}Alteco de ebena lando:
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+STR_SMALLMAP_CENTER :{BLACK}Centrigu la mapeton al la nuna loko
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}Malgranda
+STR_CITY_AIRPORT :{BLACK}Urbo
+STR_METRO_AIRPORT :{BLACK}Ĉefurba Flughaveno
+STR_INTERNATIONAL_AIRPORT :{BLACK}Internacia flughaveno
+STR_COMMUTER_AIRPORT :{BLACK}Urbeta flughaveno
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Interkontinenta
+STR_HELIPORT :{BLACK}Helikopterejo
+STR_HELIDEPOT :{BLACK}Helikopterdeponejo
+STR_HELISTATION :{BLACK}Helikopterstacio
+
+STR_SMALL_AIRPORTS :{BLACK}Malgrandaj flughavenoj
+STR_LARGE_AIRPORTS :{BLACK}Grandaj flughavenoj
+STR_HUB_AIRPORTS :{BLACK}Nabaj flughavenoj
+STR_HELIPORTS :{BLACK}Helikopterhaveno
+
+############ Tooltip measurment
+
+STR_MEASURE_LENGTH :{BLACK}Longo: {NUM}
+STR_MEASURE_AREA :{BLACK}Regiono: {NUM} x {NUM}
+STR_MEASURE_LENGTH_HEIGHTDIFF :{BLACK}Longo: {NUM}{}Altecdiferenco: {NUM} m
+STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}Regiono: {NUM} x {NUM}{}Altecdiferenco: {NUM} m
+
+########
diff --git a/src/lang/estonian.txt b/src/lang/estonian.txt
new file mode 100644
index 000000000..37dda07e9
--- /dev/null
+++ b/src/lang/estonian.txt
@@ -0,0 +1,3216 @@
+##name Estonian
+##ownname Eesti keel
+##isocode et_ET.UTF-8
+##plural 0
+##case g genitiiv
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Väljaspool kaardi piire
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Kaardi äärele liiga lähedal
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Pole piisavalt raha - vajad {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Maa peab olema tasane
+STR_0008_WAITING :{BLACK}Ootel: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (tulnud jaamast
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Võtab vastu: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Võtab vastu: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :Reisijad
+STR_000F_PASSENGERS.g :Reisijate
+STR_0010_COAL :Kivisüsi
+STR_0010_COAL.g :Kivisöe
+STR_0011_MAIL :Post
+STR_0011_MAIL.g :Posti
+STR_0012_OIL :Nafta
+STR_0012_OIL.g :Nafta
+STR_0013_LIVESTOCK :Kariloomad
+STR_0013_LIVESTOCK.g :Kariloomade
+STR_0014_GOODS :Kaubad
+STR_0014_GOODS.g :Kaupade
+STR_0015_GRAIN :Teravili
+STR_0015_GRAIN.g :Teravilja
+STR_0016_WOOD :Puit
+STR_0016_WOOD.g :Puidu
+STR_0017_IRON_ORE :Rauamaak
+STR_0017_IRON_ORE.g :Rauamaagi
+STR_0018_STEEL :Teras
+STR_0018_STEEL.g :Terase
+STR_0019_VALUABLES :Väärisasjad
+STR_0019_VALUABLES.g :Väärisasjade
+STR_001A_COPPER_ORE :Vasemaak
+STR_001A_COPPER_ORE.g :Vasemaagi
+STR_001B_MAIZE :Mais
+STR_001B_MAIZE.g :Maisi
+STR_001C_FRUIT :Puuviljad
+STR_001C_FRUIT.g :Puuviljade
+STR_001D_DIAMONDS :Teemantid
+STR_001D_DIAMONDS.g :Teemantite
+STR_001D_DIAMONDS.genitiiv :Teemantite
+STR_001E_FOOD :Toit
+STR_001E_FOOD.g :Toidu
+STR_001E_FOOD.genitiiv :Toidu
+STR_001F_PAPER :Paber
+STR_001F_PAPER.g :Paberi
+STR_001F_PAPER.genitiiv :Paberi
+STR_0020_GOLD :Kuld
+STR_0020_GOLD.g :Kulla
+STR_0020_GOLD.genitiiv :Kulla
+STR_0021_WATER :Vesi
+STR_0021_WATER.g :Vee
+STR_0021_WATER.genitiiv :Vee
+STR_0022_WHEAT :Nisu
+STR_0022_WHEAT.g :Nisu
+STR_0022_WHEAT.genitiiv :Nisu
+STR_0023_RUBBER :Kumm
+STR_0023_RUBBER.g :Kummi
+STR_0023_RUBBER.genitiiv :Kummi
+STR_0024_SUGAR :Suhkur
+STR_0024_SUGAR.g :Suhkru
+STR_0024_SUGAR.genitiiv :Suhkru
+STR_0025_TOYS :Mänguasjad
+STR_0025_TOYS.g :Mänguasjade
+STR_0025_TOYS.genitiiv :Mänguasjade
+STR_0026_CANDY :Maiustused
+STR_0026_CANDY.g :Maiustuste
+STR_0026_CANDY.genitiiv :Maiustuste
+STR_0027_COLA :Koola
+STR_0027_COLA.g :Koola
+STR_0027_COLA.genitiiv :Koola
+STR_0028_COTTON_CANDY :Suhkruvatt
+STR_0028_COTTON_CANDY.g :Suhkruvati
+STR_0028_COTTON_CANDY.genitiiv :Suhkruvati
+STR_0029_BUBBLES :Mullid
+STR_0029_BUBBLES.g :Mullide
+STR_0029_BUBBLES.genitiiv :Mullide
+STR_002A_TOFFEE :Iiris
+STR_002A_TOFFEE.g :Iirise
+STR_002A_TOFFEE.genitiiv :Iirise
+STR_002B_BATTERIES :Patareid
+STR_002B_BATTERIES.g :Patareide
+STR_002B_BATTERIES.genitiiv :Patareide
+STR_002C_PLASTIC :Plastmass
+STR_002C_PLASTIC.g :Plastmassi
+STR_002C_PLASTIC.genitiiv :Plastmassi
+STR_002D_FIZZY_DRINKS :Kihisevad joogid
+STR_002D_FIZZY_DRINKS.g :Kihisevate jookide
+STR_002D_FIZZY_DRINKS.genitiiv :Kihisevate jookide
+STR_002E :
+STR_002F_PASSENGER :Reisija
+STR_002F_PASSENGER.g :Reisijate
+STR_002F_PASSENGER.genitiiv :Reisijate
+STR_0030_COAL :Kivisüsi
+STR_0030_COAL.g :Kivisöe
+STR_0030_COAL.genitiiv :Kivisöe
+STR_0031_MAIL :Post
+STR_0031_MAIL.g :Posti
+STR_0032_OIL :Nafta
+STR_0032_OIL.g :Nafta
+STR_0032_OIL.genitiiv :Nafta
+STR_0033_LIVESTOCK :Kariloom
+STR_0033_LIVESTOCK.g :Kariloomade
+STR_0033_LIVESTOCK.genitiiv :Kariloomade
+STR_0034_GOODS :Kaubad
+STR_0034_GOODS.g :Kaupade
+STR_0034_GOODS.genitiiv :Kaupade
+STR_0035_GRAIN :Teravili
+STR_0035_GRAIN.g :Teravilja
+STR_0035_GRAIN.genitiiv :Teravilja
+STR_0036_WOOD :Puit
+STR_0036_WOOD.g :Puidu
+STR_0036_WOOD.genitiiv :Puidu
+STR_0037_IRON_ORE :Rauamaak
+STR_0037_IRON_ORE.g :Rauamaagi
+STR_0037_IRON_ORE.genitiiv :Rauamaagi
+STR_0038_STEEL :Teras
+STR_0038_STEEL.g :Terase
+STR_0038_STEEL.genitiiv :Terase
+STR_0039_VALUABLES :Väärisesemed
+STR_0039_VALUABLES.g :Väärisesemete
+STR_0039_VALUABLES.genitiiv :Väärisesemete
+STR_003A_COPPER_ORE :Vasemaak
+STR_003A_COPPER_ORE.g :Vasemaagi
+STR_003A_COPPER_ORE.genitiiv :Vasemaagi
+STR_003B_MAIZE :Mais
+STR_003B_MAIZE.g :Maisi
+STR_003C_FRUIT :Puuviljad
+STR_003C_FRUIT.g :Puuviljade
+STR_003C_FRUIT.genitiiv :Puuviljade
+STR_003D_DIAMOND :Teemant
+STR_003D_DIAMOND.g :Teemantite
+STR_003D_DIAMOND.genitiiv :Teemantite
+STR_003E_FOOD :Toit
+STR_003E_FOOD.g :Toidu
+STR_003E_FOOD.genitiiv :Toidu
+STR_003F_PAPER :Paber
+STR_003F_PAPER.g :Paberi
+STR_003F_PAPER.genitiiv :Paberi
+STR_0040_GOLD :Kuld
+STR_0040_GOLD.g :Kulla
+STR_0040_GOLD.genitiiv :Kulla
+STR_0041_WATER :Vesi
+STR_0041_WATER.g :Vee
+STR_0041_WATER.genitiiv :Vee
+STR_0042_WHEAT :Nisu
+STR_0042_WHEAT.g :Nisu
+STR_0042_WHEAT.genitiiv :Nisu
+STR_0043_RUBBER :Kumm
+STR_0043_RUBBER.g :kummi
+STR_0043_RUBBER.genitiiv :Kummi
+STR_0044_SUGAR :Suhkur
+STR_0044_SUGAR.g :Suhkru
+STR_0044_SUGAR.genitiiv :Suhkru
+STR_0045_TOY :Mänguasjad
+STR_0045_TOY.genitiiv :Mänguasjade
+STR_0046_CANDY :Maiustus
+STR_0046_CANDY.genitiiv :Maiustuste
+STR_0047_COLA :Koola
+STR_0047_COLA.genitiiv :Koola
+STR_0048_COTTON_CANDY :Suhkruvatt
+STR_0048_COTTON_CANDY.genitiiv :Suhkruvati
+STR_0049_BUBBLE :Mullid
+STR_0049_BUBBLE.genitiiv :Mullide
+STR_004A_TOFFEE :Iiris
+STR_004A_TOFFEE.genitiiv :Iirise
+STR_004B_BATTERY :Patarei
+STR_004B_BATTERY.genitiiv :Patareide
+STR_004C_PLASTIC :Plastmass
+STR_004C_PLASTIC.genitiiv :Plastmassi
+STR_004D_FIZZY_DRINK :Kihisevad joogid
+STR_004D_FIZZY_DRINK.genitiiv :Kihisevate jookide
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} reisija{P "" t}
+STR_QUANTITY_COAL :{WEIGHT} kivisütt
+STR_QUANTITY_MAIL :{COMMA} postipakk{P "" i}
+STR_QUANTITY_OIL :{VOLUME} naftat
+STR_QUANTITY_LIVESTOCK :{COMMA} loom{P "" a}
+STR_QUANTITY_GOODS :{COMMA} kast{P "" i} kaupa
+STR_QUANTITY_GRAIN :{WEIGHT} teravilja
+STR_QUANTITY_WOOD :{WEIGHT} puitu
+STR_QUANTITY_IRON_ORE :{WEIGHT} rauamaaki
+STR_QUANTITY_STEEL :{WEIGHT} terast
+STR_QUANTITY_VALUABLES :{COMMA} kotitäi{P s t} väärisasju
+STR_QUANTITY_COPPER_ORE :{WEIGHT} vasemaaki
+STR_QUANTITY_MAIZE :{WEIGHT} maisi
+STR_QUANTITY_FRUIT :{WEIGHT} puuvilju
+STR_QUANTITY_DIAMONDS :{COMMA} kotitäi{P s t} teemante{P id ""}
+STR_QUANTITY_FOOD :{WEIGHT} toitu
+STR_QUANTITY_PAPER :{WEIGHT} paberit
+STR_QUANTITY_GOLD :{COMMA} kotitäi{P s t} kulda
+STR_QUANTITY_WATER :{VOLUME} vett
+STR_QUANTITY_WHEAT :{WEIGHT} nisu
+STR_QUANTITY_RUBBER :{VOLUME} kummi
+STR_QUANTITY_SUGAR :{WEIGHT} suhkrut
+STR_QUANTITY_TOYS :{COMMA} mänguas{P i ja}
+STR_QUANTITY_SWEETS :{COMMA} kontitäi{P s t} maiustusi
+STR_QUANTITY_COLA :{VOLUME} koolat
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} suhkruvatti
+STR_QUANTITY_BUBBLES :{COMMA} mull{P "" i}
+STR_QUANTITY_TOFFEE :{WEIGHT} iirist
+STR_QUANTITY_BATTERIES :{COMMA} patarei{P "" d}
+STR_QUANTITY_PLASTIC :{VOLUME} plastmassi
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} kihisevaid jooke
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}PS
+STR_ABBREV_COAL :{TINYFONT}CL
+STR_ABBREV_MAIL :{TINYFONT}ML
+STR_ABBREV_OIL :{TINYFONT}OL
+STR_ABBREV_LIVESTOCK :{TINYFONT}LV
+STR_ABBREV_GOODS :{TINYFONT}GD
+STR_ABBREV_GRAIN :{TINYFONT}GR
+STR_ABBREV_WOOD :{TINYFONT}WD
+STR_ABBREV_IRON_ORE :{TINYFONT}OR
+STR_ABBREV_STEEL :{TINYFONT}ST
+STR_ABBREV_VALUABLES :{TINYFONT}VL
+STR_ABBREV_COPPER_ORE :{TINYFONT}CO
+STR_ABBREV_MAIZE :{TINYFONT}MZ
+STR_ABBREV_FRUIT :{TINYFONT}FT
+STR_ABBREV_DIAMONDS :{TINYFONT}DM
+STR_ABBREV_FOOD :{TINYFONT}FD
+STR_ABBREV_PAPER :{TINYFONT}PR
+STR_ABBREV_GOLD :{TINYFONT}GD
+STR_ABBREV_WATER :{TINYFONT}WR
+STR_ABBREV_WHEAT :{TINYFONT}WH
+STR_ABBREV_RUBBER :{TINYFONT}RB
+STR_ABBREV_SUGAR :{TINYFONT}SG
+STR_ABBREV_TOYS :{TINYFONT}TY
+STR_ABBREV_SWEETS :{TINYFONT}SW
+STR_ABBREV_COLA :{TINYFONT}CL
+STR_ABBREV_CANDYFLOSS :{TINYFONT}CF
+STR_ABBREV_BUBBLES :{TINYFONT}BU
+STR_ABBREV_TOFFEE :{TINYFONT}TF
+STR_ABBREV_BATTERIES :{TINYFONT}BA
+STR_ABBREV_PLASTIC :{TINYFONT}PL
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}FZ
+STR_ABBREV_NONE :{TINYFONT}EI
+STR_ABBREV_ALL :{TINYFONT}KÕIK
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Kaart - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Mängu seaded
+STR_00B2_MESSAGE :{YELLOW}Sõnum
+STR_00B3_MESSAGE_FROM :{YELLOW}{STRING} teatab
+STR_POPUP_CAUTION_CAPTION :{WHITE}Ettevaatust!
+STR_00B4_CAN_T_DO_THIS :{WHITE}Seda ei saa teha....
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Seda ala ei saa puhastada....
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Originaali autorikaitse {COPYRIGHT} 1995 Chris Sawyer, kõik õigused kaitstud
+STR_00B7_VERSION :{BLACK}OpenTTD versioon {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 OpenTTD meeskond
+STR_TRANSLATED_BY :{BLACK} Tõlgi(d) -
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Mängust väljumine
+STR_00C8_YES :{BLACK}Jah
+STR_00C9_NO :{BLACK}Ei
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Kas sa oled kindel, et sa soovid sellest mängust lahkuda ja minna tagasi süsteemi {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Mitte midagi
+STR_00D1_DARK_BLUE :Tumesinine
+STR_00D2_PALE_GREEN :Kahvaturoheline
+STR_00D3_PINK :Roosa
+STR_00D4_YELLOW :Kollane
+STR_00D5_RED :Punane
+STR_00D6_LIGHT_BLUE :Helesinine
+STR_00D7_GREEN :Roheline
+STR_00D8_DARK_GREEN :Tumeroheline
+STR_00D9_BLUE :Sinine
+STR_00DA_CREAM :Kreemjas
+STR_00DB_MAUVE :Kahvatulilla
+STR_00DC_PURPLE :Lilla
+STR_00DD_ORANGE :Oranž
+STR_00DE_BROWN :Pruun
+STR_00DF_GREY :Hall
+STR_00E0_WHITE :Valge
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Mängus on liiga palju sõidukeid
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Asukoht
+STR_00E5_CONTOURS :Maastik
+STR_00E6_VEHICLES :Sõidukid
+STR_00E7_INDUSTRIES :Tööstused
+STR_00E8_ROUTES :Teed
+STR_00E9_VEGETATION :Taimestik
+STR_00EA_OWNERS :Omanikud
+STR_00EB_ROADS :{BLACK}{TINYFONT}Teed
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Raudteed
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Jaamad/lennujaamad/sadamad
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Ehitised/tööstused
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Sõidukid
+STR_00F0_100M :{BLACK}{TINYFONT}100 m
+STR_00F1_200M :{BLACK}{TINYFONT}200 m
+STR_00F2_300M :{BLACK}{TINYFONT}300 m
+STR_00F3_400M :{BLACK}{TINYFONT}400 m
+STR_00F4_500M :{BLACK}{TINYFONT}500 m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Rongid
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Maanteesõidukid
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Laevad
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Õhusõidukid
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Veoliinid
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Kivisöekaevandus
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Elektrijaam
+STR_00FC_FOREST :{BLACK}{TINYFONT}Mets
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}Saeveski
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Naftarafineerimistehas
+STR_00FF_FARM :{BLACK}{TINYFONT}Talu
+STR_0100_FACTORY :{BLACK}{TINYFONT}Vabrik
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Trükikoda
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Naftapuuraugud
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Rauamaagi kaevandus
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Terase tööstus
+STR_0105_BANK :{BLACK}{TINYFONT}Pank
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Paberitehas
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Kullakaevandus
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Toidutöötlustehas
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Teemantikaevandus
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Vasemaagi kaevandus
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Puuviljaistandus
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Kummipuuistandus
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Veepumbad
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Veetorn
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}Saeveski
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Suhkruvati mets
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Maiustuste tehas
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Patareitalu
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Koolapumbad
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Mänguasjapood
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Mänguasjatehas
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Plastmassiallikad
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Kihisevate jookide tehas
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Mulligeneraator
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Iirisekaevandus
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Suhkrukaevandus
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Raudteejaam
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Veoautode laadimisplats
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Bussijaam
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Lennujaam
+STR_011F_DOCK :{BLACK}{TINYFONT}Sadam
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Konarlik maa
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Muru
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Lage maa
+STR_0123_FIELDS :{BLACK}{TINYFONT}Põllud
+STR_0124_TREES :{BLACK}{TINYFONT}Puud
+STR_0125_ROCKS :{BLACK}{TINYFONT}Kivid
+STR_0126_WATER :{BLACK}{TINYFONT}Vesi
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Omanikuta
+STR_0128_TOWNS :{BLACK}{TINYFONT}Linnad
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Tööstused
+STR_012A_DESERT :{BLACK}{TINYFONT}Kõrb
+STR_012B_SNOW :{BLACK}{TINYFONT}Lumi
+STR_012C_MESSAGE :{WHITE}Teade
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Loobu
+STR_012F_OK :{BLACK}OK
+STR_0130_RENAME :{BLACK}Muuda nime
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Liiga palju määratletud nimesid
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Valitud nimi on juba kasutusel
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...omanik on {STRING}
+STR_013C_CARGO :{BLACK}Laadung
+STR_013D_INFORMATION :{BLACK}Informatsioon
+STR_013E_CAPACITIES :{BLACK}Mahutavused
+STR_013E_TOTAL_CARGO :{BLACK}Laadungit kokku
+STR_013F_CAPACITY :{BLACK}Mahutavus: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}Mahutavus: {LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Rongi kogumahutavus:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}Alusta mängu
+STR_0141_LOAD_GAME :{BLACK}Laadi mängu
+STR_SINGLE_PLAYER :{BLACK}Üksikmängija
+STR_MULTIPLAYER :{BLACK}Võrgumäng
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Kaardi suurus:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Mängu seaded
+
+STR_0150_SOMEONE :keegi{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Maailmakaart
+STR_0152_TOWN_DIRECTORY :Linnade nimistu
+STR_0153_SUBSIDIES :Toetus
+
+STR_UNITS_IMPERIAL :Mittemeetriline
+STR_UNITS_METRIC :Meetriline
+STR_UNITS_SI :SI
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} miili tunnis
+STR_UNITS_VELOCITY_METRIC :{COMMA} km/h
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}hj
+STR_UNITS_POWER_METRIC :{COMMA}hj
+STR_UNITS_POWER_SI :{COMMA}kW
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} ton{P "" ni}
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} tonn{P "" i}
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} kg
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}gal
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}l
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}m³
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} gallon{P "" it}
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} liit{P er rit}
+STR_UNITS_VOLUME_LONG_SI :{COMMA} m³
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10³ lbf
+STR_UNITS_FORCE_METRIC :{COMMA} tonnine jõud
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Opereerimiskasumi graafik
+STR_0155_INCOME_GRAPH :Sissetulekute graafik
+STR_0156_DELIVERED_CARGO_GRAPH :Transporditud kauba graafik
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Tegevustulemuste graafik
+STR_0158_COMPANY_VALUE_GRAPH :Ettevõtte väärtuse graafik
+STR_0159_CARGO_PAYMENT_RATES :Veotasude määrad
+STR_015A_COMPANY_LEAGUE_TABLE :Ettevõtete edetabel
+STR_PERFORMANCE_DETAIL_MENU :Ãœksikasjalik tulemusreiting
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}OpenTTD lisainfo
+STR_015C_SAVE_GAME :Salvesta mäng
+STR_015D_LOAD_GAME :Laadi mäng
+STR_015E_QUIT_GAME :Lahku mängust
+STR_015F_QUIT :Välju
+STR_ABANDON_GAME_QUERY :{YELLOW}Oled sa kindel, et tahad sellest mängust lahkuda?
+STR_0161_QUIT_GAME :{WHITE}Mängust lahkumine
+STR_SORT_ORDER_TIP :{BLACK}Sorteerimise järjekorra valimine (kahanev/kasvav)
+STR_SORT_CRITERIA_TIP :{BLACK}Sorteerimistingimuse valimine
+STR_SORT_BY :{BLACK}Sorteeri:
+
+STR_SORT_BY_POPULATION :{BLACK}Rahvastik
+STR_SORT_BY_PRODUCTION :{BLACK}Toodang
+STR_SORT_BY_TYPE :{BLACK}Tüüp
+STR_SORT_BY_TRANSPORTED :{BLACK}Transporditud
+STR_SORT_BY_NAME :{BLACK}Nimi
+STR_SORT_BY_DROPDOWN_NAME :Nimi
+STR_SORT_BY_DATE :{BLACK}Daatum
+STR_SORT_BY_NUMBER :Number
+STR_SORT_BY_PROFIT_LAST_YEAR :Eelmise aasta kasum
+STR_SORT_BY_PROFIT_THIS_YEAR :Selle aasta kasum
+STR_SORT_BY_AGE :Vanus
+STR_SORT_BY_RELIABILITY :Töökindlus
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Kogumahutavus veose tüübi kohta
+STR_SORT_BY_MAX_SPEED :Maksimaalne kiirus
+STR_SORT_BY_MODEL :Mudel
+STR_SORT_BY_VALUE :Väärtus
+STR_SORT_BY_FACILITY :Jaama tüüp
+STR_SORT_BY_WAITING :Ootava kauba väärtus
+STR_SORT_BY_RATING_MAX :Kauba hinnang
+STR_ENGINE_SORT_ENGINE_ID :MootoriID (klassikaline)
+STR_ENGINE_SORT_COST :Hind
+STR_ENGINE_SORT_POWER :Võimsus
+STR_ENGINE_SORT_INTRO_DATE :Esitluskuupäev
+STR_ENGINE_SORT_RUNNING_COST :Teenindusmaks
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Jõud/Teenindusmaks
+STR_ENGINE_SORT_CARGO_CAPACITY :Laadungi mahutavus
+STR_NO_WAITING_CARGO :{BLACK}Kaupa pole ootamas
+STR_SELECT_ALL_FACILITIES :{BLACK}Vali kõik tööstused
+STR_SELECT_ALL_TYPES :{BLACK}Vali kõik kaubatüüpid (ka mitteoodatav kaup)
+STR_AVAILABLE_ENGINES_TIP :{BLACK}Vaata nimekirja sellele sõidukitüübile saada olevatest veduritest.
+STR_MANAGE_LIST :{BLACK}Halda nimekirja
+STR_MANAGE_LIST_TIP :{BLACK}Saada juhised kõigile selles nimekirjas olevatele sõidukitele
+STR_REPLACE_VEHICLES :Asenda sõidukeid
+STR_SEND_TRAIN_TO_DEPOT :Saada depoose
+STR_SEND_ROAD_VEHICLE_TO_DEPOT :Saada depoose
+STR_SEND_SHIP_TO_DEPOT :Saada depoose
+STR_SEND_AIRCRAFT_TO_HANGAR :Saada angaari
+STR_SEND_FOR_SERVICING :Saada teenindusse
+
+############ range for months starts
+STR_0162_JAN :jaan
+STR_0163_FEB :veebr
+STR_0164_MAR :märts
+STR_0165_APR :apr
+STR_0166_MAY :mai
+STR_0167_JUN :juuni
+STR_0168_JUL :juuli
+STR_0169_AUG :aug
+STR_016A_SEP :sept
+STR_016B_OCT :okt
+STR_016C_NOV :nov
+STR_016D_DEC :dets
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Peata mäng
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Mängu salvestamine/laadimine, mängust lahkumine, väljumine
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Kuvab ettevõtte jaamade nimistu
+STR_0174_DISPLAY_MAP :{BLACK}Kuva kaart
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Kuva kaart, linnade nimistu
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Kuva linnade nimistu
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Kuva ettevõtte finantsolukord
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Kuva üldine info ettevõtte kohta
+STR_0179_DISPLAY_GRAPHS :{BLACK}Kuva graafikuid
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Kuva ettevõtete edetabel
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Kuva ettevõtte rongide nimistu
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Kuva ettevõtte sõidukite nimistu
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Kuva ettevõtte laevade nimistu
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Kuva ettevõtte õhusõidukite nimistu
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Suurenda vaadet
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Vähenda vaadet
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Ehita raudteed
+STR_0182_BUILD_ROADS :{BLACK}Ehita maanteid
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Ehita laevasadamat
+STR_0184_BUILD_AIRPORTS :{BLACK}Ehita lennujaamu
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Puude istutamine, siltide paigaldamine jne.
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Maa-ala informatsioon
+STR_0187_OPTIONS :{BLACK}Seaded
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Teenindusvahemikku ei saa muuta...
+STR_018B_CLOSE_WINDOW :{BLACK}Sulge aken
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Akna pealkiri - lohista akna liigutamiseks
+STR_STICKY_BUTTON :{BLACK}Keela selle akna sulgemine 'Sulge kõik aknad' nupu klõpsamisel
+STR_RESIZE_BUTTON :{BLACK}Kliki ja venita, et akna suurust muuta
+STR_SAVELOAD_HOME_BUTTON :{BLACK}Vajuta siia, et minna praegusesse vaikimisi valitud salvestamise/laadimise kausta
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Ehitiste jms. hävitamine
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Maapinna madaldamine
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Maapinna kõrgendamine
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Kerimisriba - kerib nimistut üles/alla
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Kerimisriba - kerib listi üles/alla
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Näitab kaardil maastikku
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Näita kaardil sõidukeid
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Näita kaardil tööstuseid
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Näita kaardil teid ja raudteid
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Näita kaardil taimestikku
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Näita kaardil maaomanikke
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Linnanimede sisse- ja välja lülitamine
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Kasum sellel aastal: {CURRENCY} (eelmisel aastal: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} aasta{P "" t} ({COMMA})
+STR_AGE_RED :{RED}{COMMA} aasta{P "" t} ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Sõiduk
+STR_019D_AIRCRAFT :Õhusõiduk
+STR_019E_SHIP :Laev
+STR_019F_TRAIN :Rong
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} on vanaks muutumas
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} on saamas väga vanaks
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} on saanud väga vanaks ja vajab kohest asendamist
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Maa-ala info
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Tühjendamise hind: {LTBLUE}N/A
+STR_01A5_COST_TO_CLEAR :{BLACK}Tühjendamise hind: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :k-tu
+STR_01A7_OWNER :{BLACK}Omanik: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Kohalik võim: {LTBLUE}{STRING}
+STR_01A9_NONE :Mitte keegi
+STR_01AA_NAME :{BLACK}Nimi
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1.
+STR_01AD_2ND :2.
+STR_01AE_3RD :3.
+STR_01AF_4TH :4.
+STR_01B0_5TH :5.
+STR_01B1_6TH :6.
+STR_01B2_7TH :7.
+STR_01B3_8TH :8.
+STR_01B4_9TH :9.
+STR_01B5_10TH :10.
+STR_01B6_11TH :11.
+STR_01B7_12TH :12.
+STR_01B8_13TH :13.
+STR_01B9_14TH :14.
+STR_01BA_15TH :15.
+STR_01BB_16TH :16.
+STR_01BC_17TH :17.
+STR_01BD_18TH :18.
+STR_01BE_19TH :19.
+STR_01BF_20TH :20.
+STR_01C0_21ST :21.
+STR_01C1_22ND :22.
+STR_01C2_23RD :23.
+STR_01C3_24TH :24.
+STR_01C4_25TH :25.
+STR_01C5_26TH :26.
+STR_01C6_27TH :27.
+STR_01C7_28TH :28.
+STR_01C8_29TH :29.
+STR_01C9_30TH :30.
+STR_01CA_31ST :31.
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Vastuvõetavad veosed: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Muusikakeskus
+STR_01D3_SOUND_MUSIC :Heli/muusika
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Näita heli/muusika akent
+STR_01D5_ALL :{TINYFONT}Kõik
+STR_01D6_OLD_STYLE :{TINYFONT}Vana stiil
+STR_01D7_NEW_STYLE :{TINYFONT}Uus stiil
+STR_01D8_EZY_STREET :{TINYFONT}Ezy Street
+STR_01D9_CUSTOM_1 :{TINYFONT}Omatehtud 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Omatehtud 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Muusika valjus
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Effektide valjus
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MIN ' ' ' ' ' ' MAX
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Eelmine lugu
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Järgmine lugu
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Lõpeta muusika mängimine
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Alusta muusika mängimist
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Muusika ja efektide valjuse muutmiseks liiguta liugurit
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Lugu{SETX 88}Pealkiri
+STR_01E9_SHUFFLE :{TINYFONT}Sega
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Programm
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Muusikaprogrammi valimine
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Loo number
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Programm - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}Puhasta
+STR_01F1_SAVE :{TINYFONT}{BLACK}Salvesta
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Hetkel kasutatav lugude programm
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Vali 'kõikide lugude' programm
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Vali 'vanas stiilis muusika' programm
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Vali 'uues stiilis muusika' programm
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Vali 'omatehtud 1' programm
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Vali 'omatehtud 2' programm
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Tühjenda valitud programm (ainult omatehtud 1 ja omatehtud 2)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Muusikaseadete salvestamine
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Vajuta loole, et seda programmi lisada (ainult omatehtud 1 ja omatehtud 2)
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Vajuta loole, et see eemaldada praegusest progammist (Custom1 või Custom2 ainult)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Lülita lugude segamine sisse ja välja
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Näita muusikalugude valimise akent
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Vajuta pakkumisele, et näha linna/tööstuse asukohta
+STR_01FE_DIFFICULTY :{BLACK}Raskusaste ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Viimane teade
+STR_0201_MESSAGE_SETTINGS :Teadete seadistused
+STR_MESSAGE_HISTORY_MENU :Teadete ajalugu
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Näita viimast teadet, kuva teadete seaded
+STR_0204_MESSAGE_OPTIONS :{WHITE}Teadete seaded
+STR_0205_MESSAGE_TYPES :{BLACK}Teate tüüp:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Esimene sõiduk saabus mängija jaama
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Esimene sõiduk saabus konkurendi jaama
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Õnnetused / katastroofid
+STR_0209_COMPANY_INFORMATION :{YELLOW}Ettevõtte teave
+STR_020A_ECONOMY_CHANGES :{YELLOW}Muutused majanduses
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Soovitused / teated mängija sõidukite kohta
+STR_020C_NEW_VEHICLES :{YELLOW}Uued sõidukid
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Veoste vastuvõtutingimuste muutumine
+STR_020E_SUBSIDIES :{YELLOW}Toetused
+STR_020F_GENERAL_INFORMATION :{YELLOW}Ãœldine teave
+STR_MESSAGES_ALL :{YELLOW}Vali kõikide uudiste tüüp: Väljas / Kokkuvõte / Täielikult
+STR_MESSAGE_SOUND :{YELLOW}Mängi heli ka kokkuvõetud uudistele
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...liiga kaugel eelmisest sihtpunktist
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Parimad ettevõtted, kes jõudsid tasemeni {NUM}{}({STRING})
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Ettevõtete edetabelis {NUM} kohal
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Ärimees
+STR_0214_ENTREPRENEUR :Ettevõtja
+STR_0215_INDUSTRIALIST :Tööstur
+STR_0216_CAPITALIST :Kapitalist
+STR_0217_MAGNATE :Magnaat
+STR_0218_MOGUL :Mogul
+STR_0219_TYCOON_OF_THE_CENTURY :Sajandi suurärimees
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} saavutas '{STRING}' staatuse!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} {COMPANY}'st saavutas '{STRING}' staatuse!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Loo stsenaarium
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Kaardiredaktor
+STR_0223_LAND_GENERATION :{WHITE}Maastiku loomine
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Juhuslik kaart
+STR_0227_RESET_LAND :{BLACK}Nulli kaart
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Suurenda kõrgendatava/madaldatava maa-ala pindala
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Vähenda kõrgendatava/madaldatava maa-ala pindala
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Juhusliku kaardi loomine
+STR_022B_RESET_LANDSCAPE :{BLACK}Nulli maastik
+STR_022C_RESET_LANDSCAPE :{WHITE}Nulli maastik
+STR_LOAD_GAME_HEIGHTMAP :{WHITE}Kasuta Kõrguskaarti
+STR_LOAD_SCEN_HEIGHTMAP :{BLACK}Kasuta Kõrguskaarti
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Oled sa kindel, et sa tahad maastikku nullida?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Maastiku loomine
+STR_022F_TOWN_GENERATION :{BLACK}Linnade loomine
+STR_0230_INDUSTRY_GENERATION :{BLACK}Tööstuste loomine
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Teede ehitamine
+STR_0233_TOWN_GENERATION :{WHITE}Linnade loomine
+STR_0234_NEW_TOWN :{BLACK}Uus linn
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Ehita uus linn
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Siia ei saa linna ehitada...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...liiga lähedal kaardi servale
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...liiga lähedal teisele linnale
+STR_0239_SITE_UNSUITABLE :{WHITE}...ebasobiv koht
+STR_023A_TOO_MANY_TOWNS :{WHITE}...liiga palju linnu
+STR_CANNOT_GENERATE_TOWN :{WHITE}Ei saa ühtegi linna ehitada
+STR_NO_SPACE_FOR_TOWN :{WHITE}...pole enam ruumi kaardil
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Linna suuruse suurendamine
+STR_023C_EXPAND :{BLACK}Laienda
+STR_023D_RANDOM_TOWN :{BLACK}Juhuslik linn
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Ehita linn suvalisse kohta
+STR_023F_INDUSTRY_GENERATION :{WHITE}Tööstuste loomine
+STR_0240_COAL_MINE :{BLACK}Kivisöekaevandus
+STR_0241_POWER_STATION :{BLACK}Elektrijaam
+STR_0242_SAWMILL :{BLACK}Saeveski
+STR_0243_FOREST :{BLACK}Mets
+STR_0244_OIL_REFINERY :{BLACK}Naftarafineerimistehas
+STR_0245_OIL_RIG :{BLACK}Naftaplatvorm
+STR_0246_FACTORY :{BLACK}Vabrik
+STR_0247_STEEL_MILL :{BLACK}Terasetööstus
+STR_0248_FARM :{BLACK}Talu
+STR_0249_IRON_ORE_MINE :{BLACK}Rauamaagi kaevandus
+STR_024A_OIL_WELLS :{BLACK}Naftapuurauk
+STR_024B_BANK :{BLACK}Pank
+STR_024C_PAPER_MILL :{BLACK}Paberitehas
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Toidutöötlustehas
+STR_024E_PRINTING_WORKS :{BLACK}Trükikoda
+STR_024F_GOLD_MINE :{BLACK}Kullakaevandus
+STR_0250_LUMBER_MILL :{BLACK}Saeveski
+STR_0251_FRUIT_PLANTATION :{BLACK}Puuviljaistandus
+STR_0252_RUBBER_PLANTATION :{BLACK}Kummipuuistandus
+STR_0253_WATER_SUPPLY :{BLACK}Veepumbad
+STR_0254_WATER_TOWER :{BLACK}Veetorn
+STR_0255_DIAMOND_MINE :{BLACK}Teemantikaevandus
+STR_0256_COPPER_ORE_MINE :{BLACK}Vasemaagikaevandus
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Suhkruvatimets
+STR_0258_CANDY_FACTORY :{BLACK}Maiustuste tehas
+STR_0259_BATTERY_FARM :{BLACK}Patareifarm
+STR_025A_COLA_WELLS :{BLACK}Koolapumbad
+STR_025B_TOY_SHOP :{BLACK}Mänguasjapood
+STR_025C_TOY_FACTORY :{BLACK}Mänguasjatehas
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Plastmassiallikad
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Kihisevate jookide tehas
+STR_025F_BUBBLE_GENERATOR :{BLACK}Mulligeneraator
+STR_0260_TOFFEE_QUARRY :{BLACK}Iirisekaevandus
+STR_0261_SUGAR_MINE :{BLACK}Suhkrukaevandus
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Ehita kivisöekaevandus
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Ehita elektrijaam
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Ehita saeveski
+STR_0265_PLANT_FOREST :{BLACK}Istuta mets
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Ehita naftarafineerimistehas
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Ehita naftaplatvorm (seda saab ehitada vaid kaardi serva)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Ehita vabrik
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Ehita terasetööstus
+STR_026A_CONSTRUCT_FARM :{BLACK}Raja farm
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Ehita rauamaagikaevandus
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Ehita naftapuuraugud
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Ehita pank (seda saab ehitada vaid linnadesse, mille rahvastikuarv ületab 1200)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Ehita paberitehas
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Ehita toidutööstus
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Ehita trükikoda
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Ehita kullakaevandus
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Ehita pank (seda saab vaid linnadesse ehitada)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Ehita saeveski (vihmametsade puhustamiseks ja puidu tootmiseks)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Istuta puuviljaistandus
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Istuta kummipuuistandus
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Ehita veepumbad
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Ehita veetorn (saab ainult linnadesse ehitada)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Ehita teemantikaevandus
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Ehita vasemaagikaevandus
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Istuta suhkruvatimets
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Ehita maiustuste tehas
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Ehita patareifarm
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Ehita koolapumbad
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Ehita mänguasjapood
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Ehita mänguasjatehas
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Ehita plastmassiallikad
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Ehita kihisevate jookide tehas
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Ehita mulligeneraator
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Ehita iirisekaevandus
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Ehita suhkrukaevandus
+STR_0285_CAN_T_BUILD_HERE :{WHITE}{STRING} ei saa siia ehitada...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...enne pead linna ehitama
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...iga linna kohta lubatud ainult üks
+STR_0288_PLANT_TREES :{BLACK}Istuta puid
+STR_0289_PLACE_SIGN :{BLACK}Paigalda silt
+STR_028A_RANDOM_TREES :{BLACK}Juhuslikud puud
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Istutab puid juhuslikult üle kogu maa
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Loo maastikule kivised alad
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Ehita tuletorn
+STR_028E_PLACE_TRANSMITTER :{BLACK}Paigalda saatjamast
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Loo kõrbealad.{}Eemaldamiseks klõpsa hoides all CTRL nuppu
+STR_CREATE_LAKE :{BLACK}Märgi vee ala.{}See uputab kogu läheduse kui on mereveetasemel
+STR_0290_DELETE :{BLACK}Kustuta
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Hävita see linn täielikult
+STR_0292_SAVE_SCENARIO :Salvesta kaart
+STR_0293_LOAD_SCENARIO :Laadi kaart
+STR_0294_QUIT_EDITOR :Lahku redaktorist
+STR_0295 :
+STR_0296_QUIT :Välju
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Kaardi salvestamine, kaardi laadimine, kaarditegemisest lahkumine, mängust väljumine
+STR_0298_LOAD_SCENARIO :{WHITE}Laadi stsenaariumit
+STR_0299_SAVE_SCENARIO :{WHITE}Salvesta stsenaarium
+STR_029A_PLAY_SCENARIO :{BLACK}Mängi stsenaariumit
+STR_PLAY_HEIGHTMAP :{BLACK}Mängi kõrguskaardil
+STR_PLAY_HEIGHTMAP_HINT :{BLACK}Alusta uut mängu kasutades kõrguskaarti maastikuna
+STR_QUIT_SCENARIO_QUERY :{YELLOW}Kas sa oled kindel, et sa tahad kaardi tegemise lõpetada?
+STR_029C_QUIT_EDITOR :{WHITE}Lahku redaktorist
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...saab ainult ehitada linna, mille rahvastikuarv ületab 1200
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Liiguta algusaega aasta võrra tagasi
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Liiguta algusaega aaata võrra edasi
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...mõlemad sillaotsad peavad olema maal
+STR_02A1_SMALL :{BLACK}Väike
+STR_02A2_MEDIUM :{BLACK}Keskmine
+STR_02A3_LARGE :{BLACK}Suur
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Vali linna suurus
+STR_02A5_TOWN_SIZE :{YELLOW}Linna suurus:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Näita viimast teadet
+STR_OFF :Off
+STR_SUMMARY :Lühike
+STR_FULL :Täielik
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Linnanimistu
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Sõidukite disaini nimed
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Vaikimisi valitud
+STR_02BF_CUSTOM :Omatehtud
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Salvesta oma nimega
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Sõidukite disaininimede valik
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Salvesta omatehtud disaininimed
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Mängu seaded
+STR_02C5_DIFFICULTY_SETTINGS :Raskusastme seaded
+STR_02C7_CONFIG_PATCHES :Paranduste seaded
+STR_NEWGRF_SETTINGS :Newgrf seaded
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Näidatavad linnanimed
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Näidatavad jaamanimed
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Näidatavad sildid
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Näidatavad kontrollpunktid
+STR_02D0_FULL_ANIMATION :{SETX 12}Täielik animeerimine
+STR_02D2_FULL_DETAIL :{SETX 12}Kõik üksikasjad
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Läbipaistvad hooned
+STR_TRANSPARENT_SIGNS :{SETX 12}Läbinähtavad jaama nimesildid
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Maapinna informatsioon
+STR_02D6 :
+STR_CONSOLE_SETTING :Lülita konsool sisse/välja
+STR_02D7_SCREENSHOT_CTRL_S :Ekraanitõmmis (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Hiiglaslik ekraanitõmmis (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :'OpenTTD' kohta
+############ range ends here
+
+STR_02DB_OFF :{BLACK}Väljas
+STR_02DA_ON :{BLACK}Sees
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Kuva toetused
+STR_02DD_SUBSIDIES :Toetused
+STR_02DE_MAP_OF_WORLD :Maailmakaart
+STR_EXTRA_VIEW_PORT :Lisa vaateaken
+STR_SIGN_LIST :Siltide nimekiri
+STR_02DF_TOWN_DIRECTORY :Linnade nimistu
+STR_TOWN_POPULATION :{BLACK}Maailma rahvastik: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Vaateaken {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Kopeeri vaateaknasse
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Kopeeri praegune vaade vaateaknasse
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Kleebi vaateaknast
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Vaatealma koha võtmine peamiseks vaateks
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Rahaühik
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Rahaühiku valimine
+STR_MEASURING_UNITS :{BLACK}Mõõtmisühikud
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Mõõtmisühikute valik
+STR_02E6_ROAD_VEHICLES :{BLACK}Sõidukid
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Vali, kummal pool teed sõidukid liiguvad
+STR_02E9_DRIVE_ON_LEFT :Vasakpoolne liiklus
+STR_02EA_DRIVE_ON_RIGHT :Parempoolne liiklus
+STR_02EB_TOWN_NAMES :{BLACK}Linnanimed
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Vali linnanimede stiil
+
+STR_02F4_AUTOSAVE :{BLACK}Automaatsalvestus
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Vali intervall, mille järel automaatsalvestus toimub
+STR_02F7_OFF :Väljas
+STR_02F8_EVERY_3_MONTHS :Iga 3 kuu tagant
+STR_02F9_EVERY_6_MONTHS :Iga 6 kuu tagant
+STR_02FA_EVERY_12_MONTHS :Iga 12 kuu tagant
+STR_02FB_START_A_NEW_GAME :{BLACK}Alusta uut mängu
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Laadi salvestatud mäng
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Loo oma mängukaart
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Vali üksikmäng
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Vali 2-8 mängijaga mitmikmäng
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Näita mängu seadeid
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Vaata raskusastmete seadeid
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Alusta omatehtud stsenaariumit kasutades uut mängu
+STR_0304_QUIT :{BLACK}Välju
+STR_0305_QUIT_OPENTTD :{BLACK}Välju 'OpenTTD'st
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...saab ainult linnadesse ehitada
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Vali 'parasvöötme' maastik
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Vali 'lähispolaarne' maastik
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Vali 'lähistroopiline' maastik
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Vali 'mänguasjamaa' maastik
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Rahasta uute ehitiste konstrueerimist
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Tööstuste nimistu
+STR_0313_FUND_NEW_INDUSTRY :Rahasta uue tööstuse ehitamist
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Rahasta uue tööstuse ehitamist
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...saab ehitada ainult linnadesse
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...saab ehitada ainult vihmametsadesse
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...saab ehitada ainult kõrbesse
+STR_0319_PAUSED :{YELLOW}* * PEATUS * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Ekraanitõmmis edukalt salvestatud nimega '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}Ekraanitõmmise tegemine ebaõnnestus!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Maa ostmine tulevaseks kasutamiseks
+STR_032F_AUTOSAVE :{RED}AUTOMAATSALVESTUS
+STR_SAVING_GAME :{RED}* * MÄNGU SALVESTAMINE * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}Ikka salvestamisel,{}palun oota salvestuse lõpuni!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}'Ezy Street' stiilis muusikaprogrammi valimine
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :Inglise (originaalne)
+STR_TOWNNAME_FRENCH :Prantsusmaa
+STR_TOWNNAME_GERMAN :Saksamaa
+STR_TOWNNAME_ADDITIONAL_ENGLISH :Inglise (Lisa)
+STR_TOWNNAME_LATIN_AMERICAN :Ladina-Ameerika
+STR_TOWNNAME_SILLY :Tobedad
+STR_TOWNNAME_SWEDISH :Rootsi
+STR_TOWNNAME_DUTCH :Hollandi
+STR_TOWNNAME_FINNISH :Soome
+STR_TOWNNAME_POLISH :Poola
+STR_TOWNNAME_SLOVAKISH :Slovakkia
+STR_TOWNNAME_NORWEGIAN :Norra
+STR_TOWNNAME_HUNGARIAN :Ungari
+STR_TOWNNAME_AUSTRIAN :Austria
+STR_TOWNNAME_ROMANIAN :Rumeenia
+STR_TOWNNAME_CZECH :TÅ¡ehhi
+STR_TOWNNAME_SWISS :Å veitsi
+STR_TOWNNAME_DANISH :Taani
+STR_TOWNNAME_TURKISH :Türgi
+STR_TOWNNAME_ITALIAN :Itaalia
+STR_TOWNNAME_CATALAN :Katalaani
+############ end of townname region
+
+STR_CURR_GBP :Naelad (£)
+STR_CURR_USD :Dollarid ($)
+STR_CURR_EUR :Euro (€)
+STR_CURR_YEN :Jeen (Â¥)
+STR_CURR_ATS :Austria ðilling (ATS)
+STR_CURR_BEF :Belgia frank (BEF)
+STR_CURR_CHF :Sveitði frank (CHF)
+STR_CURR_CZK :Tðehhi kroon (CZK)
+STR_CURR_DEM :Saksamargad (DEM)
+STR_CURR_DKK :Taani kroon (DKK)
+STR_CURR_ESP :Peseeta (ESP)
+STR_CURR_FIM :Soome mark (FIM)
+STR_CURR_FRF :Frank (FRF)
+STR_CURR_GRD :Kreeka drahm (GRD)
+STR_CURR_HUF :Ungari Forint (HUF)
+STR_CURR_ISK :Islandi kroon (ISK)
+STR_CURR_ITL :Itaalia liir (ITL)
+STR_CURR_NLG :Hollandi kulden (NLG)
+STR_CURR_NOK :Norra kroon (NOK)
+STR_CURR_PLN :Poola Zlott (PLN)
+STR_CURR_ROL :Rumeenia Leu (ROL)
+STR_CURR_RUR :Vene rubla (RUR)
+STR_CURR_SIT :Sloveenia Talaar (SIT)
+STR_CURR_SEK :Rootsi kroon (SEK)
+STR_CURR_YTL :Türgi Liir (YTL)
+STR_CURR_SKK :Slovakkia Kroon (SKK)
+STR_CURR_BRR :Brasiilia Reaal (BRL
+
+STR_CURR_CUSTOM :Omatehtud...
+
+STR_OPTIONS_LANG :{BLACK}Keel
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Mängus kasutatava keele valik
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Täisekraan
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}Märgistades selle kasti, toimub mäng täisekraanis
+
+STR_OPTIONS_RES :{BLACK}Kuvari eraldusvõime
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Kuvari eraldusvõime valimine
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Ekraanitõmmise formaat
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Valik, millises formaadis salvestatakse ekraanitõmmis
+
+STR_AUTOSAVE_1_MONTH :Iga kuu
+STR_AUTOSAVE_FAILED :{WHITE}Automaatsalvestus ebaõnnestus
+
+STR_MONTH_JAN :Jaanuar
+STR_MONTH_FEB :Veebruar
+STR_MONTH_MAR :Märts
+STR_MONTH_APR :Aprill
+STR_MONTH_MAY :Mai
+STR_MONTH_JUN :Juuni
+STR_MONTH_JUL :Juuli
+STR_MONTH_AUG :August
+STR_MONTH_SEP :September
+STR_MONTH_OCT :Oktoober
+STR_MONTH_NOV :November
+STR_MONTH_DEC :Detsember
+
+STR_HEADING_FOR_STATION :{LTBLUE}Sihtpunkt: {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}Sihtpunkt: {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Sihtpunkt puudub
+STR_NO_ORDERS_VEL :{LTBLUE}Sihtpunkt puudub, {VELOCITY}
+
+STR_PASSENGERS :reisijad
+STR_BAGS :kotti
+STR_TONS :tonni
+STR_LITERS :liitrit
+STR_ITEMS :ühikut
+STR_CRATES :kasti
+STR_RES_OTHER :teised
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Sihtpunktide nimekirja ei saa jagada...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Sihtpunktide nimekirja ei saa kopeerida...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - Jagatud sihtpunktide lõpp - -
+
+STR_TRAIN_IS_LOST :{WHITE}Rong {COMMA} on eksinud.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}Rongi {COMMA} eelmise aasta kasum oli {CURRENCY}
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}Euroopa rahaliit!{}{}Nüüdsest on riigi igapäevaseks käiberahaks Euro!
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Rongil {COMMA} on sõiduplaanis liiga vähe sihtpunkte
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}Rongil {COMMA} on tühistatud käsklus
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}Rongil {COMMA} on mõni sihtpunktidest topelt
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}Rongi {COMMA} plaanis on kehtetuid jaamu
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}Maanteesõiduki {COMMA} on liiga vähe sihtpunkte plaanis
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}Maanteesõidukil {COMMA} on kehtetuid sihtpunkte
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}Maanteesõidukil {COMMA} on mõni sihtpunkt on topelt
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}Maanteesõiduki {COMMA} sõiduplaan sisaldab kehtetuid jaamu
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}Laeval {COMMA} on plaanis liiga vähe sihtpunkte
+STR_SHIP_HAS_VOID_ORDER :{WHITE}Laeval {COMMA} on kehtetuid sihtpunkte
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}Laeval {COMMA} on mõni sihtpunkt on topelt
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}Laeva {COMMA} plaanis on kehtetuid jaamu
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}Õhusõidukil {COMMA} on plaanis liiga vähe sihtpunkte
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}Õhusõidukil {COMMA} on kehtetud sihtpunktid
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}Õhusõidukil {COMMA} on mõni sihtpunkt on topelt
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}Õhusõiduki {COMMA} plaanis on kehtetud jaam
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}Rongi automaatne uuendamine {COMMA} ebaõnnestus (rahalimiit)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}Maanteesõiduki automaatne uuendus ebaõnnestus {COMMA} (rahalimiit)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}Laeva automaatne uuendus ebaõnnestus {COMMA} (rahalimiit)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}Õhusõiduki automaatne uuendus ebaõnnestus{COMMA} (rahalimiit)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}Rong {COMMA} on peale asendust liiga pikk
+
+STR_CONFIG_PATCHES :{BLACK}Paranduste seaded
+STR_CONFIG_PATCHES_TIP :{BLACK}Paranduste seadistamine
+STR_CONFIG_PATCHES_CAPTION :{WHITE}Paranduste seaded
+
+STR_CONFIG_PATCHES_OFF :Väljas
+STR_CONFIG_PATCHES_ON :Sees
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Näita olekuribal sõidukite kiirust: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Luba ehitised nõlvadele ja kallastele: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Võimalda reaalsemaid veekogu alasid: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Luba linna teede, sildade, tunnelite jne eemaldamine: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Luba väga pikkade rongide ehitamine: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Aktiveeri realistlik rongide kiirendamine: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Keela rongidel ja laevadel 90 kraadised pöörded: {ORANGE}{STRING} {LTBLUE} (vajab NPF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Ühenda üksteise vastu ehitatud jaamad kokku: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Lahku jaamast, kui üks kaupadest on täis laetud: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Kasuta parandatud laadimisalgoritmi: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GRADUAL_LOADING :{LTBLUE}Laadi sõidukeid järkjärguliselt: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Inflatsioon: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Vii kaup jaama ainult siis, kui seal on nõudlus: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Luba väga pikkade sildade ehitus: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Luba 'mine depoosse' käsud: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Luba rajada toormaterjalide tehaseid: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Luba mitu sama liiki tööstust linna kohta: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Sama liiki tööstusi saab ehitada üksteise lähedale: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Alati näita olekuribal pikka kuupäeva: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Paiguta signaaltuled raudteele arvestades sõidusuunda: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Näita rahaliste seisude akent iga aasta lõpus: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}TTDPatchiga ühilduv 'mittepeatumine': {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Maanteesõidukite järjekorrad (koos mahueffektidega): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Keri vaadet, kui hiir on viidud ekraani serva: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Luba kohalikele võimudele altkäemaksu maksmine: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Luba suvalise kujuga jaamad: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Uus teeotsimise algoritm(NPF asendab NTP): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FREIGHT_TRAINS :{LTBLUE}Raskete rongide simuleerimiseks kasutatav raskuse korrutaja: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Luba väikesed lennujaamad kuni mängu lõpuni: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Hoiata, kui rong on eksinud: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Sõidukite sihtpunktide ülevaade: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :ei
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :jah, aga välja arvatud seisvad sõidukid
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :kõikide sõidukite
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Hoiata, kui rongi sissetulek on negatiivne: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Sõidukid ei aegu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Automaatne sõidukite uuendamine vananemisel
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Uuenda, kui sõiduk on {ORANGE}{STRING}{LTBLUE} kuud enne/pärast maksimaalset vanust
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Automaatsetele uuendusele kuluv minimaalne raha: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Veateate kuvamise kestus: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Näita linna nimesildil rahvaarvu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Nähtamatud puud (läbipaistvate ehitistega): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Maaala Generaator: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :Algupärane
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis
+STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}Suurim kaugus kaardi äärest nafta puuraukudeni {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Lumepiiri kõrgus: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN :{LTBLUE}Maa mägisus (TerraGenesis ainult) : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Väga sile
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH :Sile
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH :Mägine
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :Väga mägine
+STR_CONFIG_PATCHES_TREE_PLACER :{LTBLUE}Puude panemis süsteem: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TREE_PLACER_NONE :Pole
+STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL :Algupärane
+STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED :Täiustatud
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION :{LTBLUE}Kõrgustekaardi pööramine: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Vastu-päevapidi
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE :Päevapidi
+STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT :{LTBLUE}Kõrguse level kui kõrgele lapik kaart läheb: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Maksimaalne jaama ala: {ORANGE}{STRING} {RED}Hoiatus: kõrged seaded aeglustavad mängu
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Kopteri jaamades helikopterite automaatne teenindus: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Lingi maastiku riba raudtee/tee/vee/lennujaama tööriistaribaga: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Kui kerid hiirega, liiguta vaade vastassuunda: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Näita mitmesuguste ehitusvahendite kasutamisel mõõtmise kohtspikrit: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Näita firma livree: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES_NONE :Mitte ükski
+STR_CONFIG_PATCHES_LIVERIES_OWN :Enda firma
+STR_CONFIG_PATCHES_LIVERIES_ALL :Kõik Firmad
+STR_CONFIG_PATCHES_PREFER_TEAMCHAT :{LTBLUE}Eelista Meeskonnajututuba <ENTER>i vajutamisega: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Maks. rongide arv mängija kohta: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Maksimaalne maanteesõidukite arv mängija kohta: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}Maksimaalne õhusõidukite arv mängija kohta: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}Maksimaalne laevade arv mängija kohta: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Arvuti ei tohi ronge kasutada: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Arvuti ei tohi maanteesõidukeid kasutada: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Arvuti ei tohi õhusõidukeid kasutada: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Arvuti ei tohi laevasid kasutada: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Lülita uus TI (AI) sisse (alfa): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Luba TI (AI) võrgumängus (TESTIMISEL!): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Vaikimisi hooldusintervall rongidele: {ORANGE}{STRING} päeva
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Vaikimisi teenindusvahemik rongidel: {ORANGE}välja lülitatud
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Vaikimisi hooldusintervall maanteesõidukitele: {ORANGE}{STRING} päeva
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Vaikimisi teenindusvahemik maanteesõidukitel: {ORANGE}välja lülitatud
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Vaikimisi hooldusintervall õhusõidukitele: {ORANGE}{STRING} päeva
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Vaikimisi teenindusvahemik õhusõidukitele: {ORANGE}välja lülitatud
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Vaikimisi hooldusintervall laevadele: {ORANGE}{STRING} päeva
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Vaikimisi teenindusvahemik laevadele: {ORANGE}välja lülitatud
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Peata hooldus, kui purunemine on keelatud: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Luba vaguni kiiruse limiidid: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}Keela elektrirongid: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Värvilised uudised ilmuvad aastast {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Alustamise aeg: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}Mäng lõppeb aastal: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Luba sujuv majandus (väiksemad muutused)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Luba teiste ettevõtete aktsiate ostmine
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Venitades paigutatud signaaltulede tihedus: {ORANGE}{STRING} ühik(ut)
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Tööriistariba asukoht: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Vasakul
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Keskel
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Paremal
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Akna haaramise raadius: {ORANGE}{STRING} px
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Akna haaramise raadius: {ORANGE}välja lülitatud
+
+STR_CONFIG_PATCHES_GUI :{BLACK}Välimus
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Ehitamine
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Sõidukid
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Jaamad
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Majandus
+STR_CONFIG_PATCHES_AI :{BLACK}Konkurendid
+
+STR_CONFIG_PATCHES_DISABLED :Välja lülitatud
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Muuda seadete väärtusi
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Mõni või kõik vaikimisi teenindusvahemikud on kõlbmatud! Lubatud on 5-90% või 30-800 päeva
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}Kasuta YAPF'i laevadel: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}Kasuta YAPF'i autodel: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}Kasuta YAPF'i rongidel: {ORANGE}{STRING}
+
+STR_TEMPERATE_LANDSCAPE :Parasvöötme maastik
+STR_SUB_ARCTIC_LANDSCAPE :Arktiline maastik
+STR_SUB_TROPICAL_LANDSCAPE :Troopiline maastik
+STR_TOYLAND_LANDSCAPE :Mänguasjamaa
+
+STR_CHEATS :{WHITE}Petmine
+STR_CHEATS_TIP :{BLACK}Märgistatud kastid näitavad et, kas sa oled varem seda pettust kasutanud
+STR_CHEATS_WARNING :{BLACK}Hoiatus! Sa kavatsed oma konkurente reeta. Pea meeles, et sellisest häbist ei saa sa enam kunagi lahti.
+STR_CHEAT_MONEY :{LTBLUE}Suurenda raha hulka {CURRENCY64} võrra
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Mängi, kui mängija: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Maagiline buldooser(eemaldamatute objektide eemaldamine): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Tunnelid võivad üksteist läbida: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Pausi ajal ehitamine: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Reaktiivlennukid ei kuku alla (tihti) väikestel lennuväljadel: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Vaheta kliimat: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Muuda kuupäeva: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}Luba muutuvad tootmisväärtused: {ORANGE}{STRING}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}Suudub kontrollpunti: {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Suundub {WAYPOINT}, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :Läbi punkti {WAYPOINT}
+STR_GO_NON_STOP_TO_WAYPOINT :Läbi peatumata punkti{WAYPOINT}
+
+STR_WAYPOINTNAME_CITY :Kontrollpunkt {TOWN}
+STR_WAYPOINTNAME_CITY_SERIAL :Kontrollpunkt {TOWN} #{COMMA}
+STR_LANDINFO_WAYPOINT :Kontrollpunkt
+
+STR_WAYPOINT :{WHITE}Kontrollpunkt
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Kontrollpunkti tüübi valik
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}Kontrollpunkti nime muutmine
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Kontrollpunkti nime ei saa muuta...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Rööbaste muutmine kontrollpunktiks
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Rongide kontrollpunkti ei saa siia teha...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Rongide kontrollpunkti ei saa siit eemaldada...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Rööbaste ehitamine kasutades "venitamist"
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}...kaardil puudub linn
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}Oled sa kindel, et soovid luua suvalist maastikku?
+STR_MANY_RANDOM_TOWNS :{BLACK}Palju suvalisi linnu
+STR_RANDOM_TOWNS_TIP :{BLACK}Kaardi katmine suvaliselt asetatud linnadega
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Palju suvalisi tööstusi
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Kata kaart suvaliselt paigutatud tööstustega
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Tööstust ei saa tekitada...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Maastiku tööriistade avamine maa tõstmiseks/langetamiseks, puude istutamiseks, jne.
+STR_LANDSCAPING_TOOLBAR :{WHITE}Maastik
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Maapinna kõrgus
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Suvalised puutüübid
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}Istutab suvalisi puid
+
+STR_CANT_BUILD_CANALS :{WHITE}Siia ei saa kanaleid ehitada...
+STR_BUILD_CANALS_TIP :{BLACK}Kanali ehitamine. Veeruutude ehitamiseks vajuta CTRL (ainult merepinna kõrgusel)
+STR_LANDINFO_CANAL :Kanal
+
+STR_CANT_BUILD_LOCKS :{WHITE}Siia ei saa lüüse ehitada...
+STR_BUILD_LOCKS_TIP :{BLACK}Lüüsi ehitamine
+STR_LANDINFO_LOCK :Lüüs
+
+STR_BUOY_IS_IN_USE :{WHITE}...poi on kasutusel!
+
+STR_LANDINFO_COORDS :{BLACK}Koordinaadid: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Jaamaosa ei saa eemaldada...
+STR_CANT_CONVERT_RAIL :{WHITE}Siin ei saa raudteetüüpi muuta...
+STR_CONVERT_RAIL_TIP :{BLACK}Muuda/uuenda raudteetüüpi
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Tõsta vedur siia, et müüa maha kogu rong
+
+STR_DRAG_DROP :{BLACK}Venitamine
+STR_STATION_DRAG_DROP :{BLACK}Ehita jaam kasutades hiirega venitust
+STR_SELECT_STATION_CLASS_TIP :{BLACK}Vali jaama klass mida tahad näidata
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Vali ehitatava jaama tüüp
+
+STR_FAST_FORWARD :{BLACK}Mängu aja kiiresti edasi kerimine
+STR_MESSAGE_HISTORY :{WHITE}Sõnumite ajalugu
+STR_MESSAGE_HISTORY_TIP :{BLACK}Nimekiri hiljutistest uudistest
+STR_MESSAGES_DISABLE_ALL :{BLACK}Lülita kõik välja
+STR_MESSAGES_ENABLE_ALL :{BLACK}Luba kõik
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Kivisöe kaevanduse ehitamine
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Metsa istutamine
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Naftaplatrvormi ehitamine
+STR_CONSTRUCT_FARM_TIP :{BLACK}Talu rajamine
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Vasemaagi kaevanduse ehitamine
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Naftapuuraugu ehitamine
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Kullakaevanduse ehitamine
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Teemantikaevanduse ehitamine
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Rauamaagi kaevandus ehitamine
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Puuviljaistandusue istutamine
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Kummipuu istanduse istutamine
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Rahasta Veevärki
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Suhkruvati metsa istutamine
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}Patarei talu ehitamine
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Koolapumpade ehitamine
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Plastmassiallikate tekitamine
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Mulligeneraatori ehitamine
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Iirisekaevanduse ehitamine
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Suhkrukaevandus ehitamine
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Tööstused
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA}% transporditud)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA}%/{COMMA}% transporditud)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}...liiga lähedal mõnele teisele tööstusele
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Rongi seadistamine mõne teise laadungi transportimiseks
+STR_RAIL_REFIT_VEHICLE :{BLACK}Seadista ümber
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Vali laadung, mida rong peaks kandma
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Rongi ümberseadistamine valitud laadungi transportimiseks
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Ei ole võimalik ümber seadistada...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Teenindusvahemikud on protsentides: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Tootlikuse muutmine
+
+TEMP_AI_IN_PROGRESS :{WHITE}Tervitused uuele TI'le(AI). Töö selle kallal veel käib. Peaksite eeldama, et esineb probleeme. Kui juhtud tegema kuvatõmmise, siis postita see ka foorumisse. Edu!
+TEMP_AI_ACTIVATED :{WHITE}Hoiatus: uus tehisintelligents on veel katsetamisel! Hetkel töötavad ainult maanteesõidukid!
+TEMP_AI_MULTIPLAYER :{WHITE}TÄHELEPANU! Seda funksiooni veel teistitakse. Palun teata kõik probleemid sellega truelight@openttd.org.
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Võrgumäng
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Mängija nimi:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}Selle nime järgi tunnevad sind teised mängijad ära
+STR_NETWORK_CONNECTION :{BLACK}Ãœhendus:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Valik internetis ja kohalikus võrgus (LAN) toimuba mängu vahel
+
+STR_NETWORK_START_SERVER :{BLACK}Alusta serverit
+STR_NETWORK_START_SERVER_TIP :{BLACK}Isikliku serveri alustamine
+
+STR_NETWORK_GAME_NAME :{BLACK}Nimi
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Mängu nimi
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Keel, serveri versioon, jne.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Mäng valimiseks vajuta nimekirjas olevale nimele
+
+STR_NETWORK_FIND_SERVER :{BLACK}Serveri otsimine
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Võrgust serveri otsimine
+STR_NETWORK_ADD_SERVER :{BLACK}Lisa server
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Lisab nimekirja serveri, mida kontrollitakse alati, kas see töötab või mitte.
+STR_NETWORK_ENTER_IP :{BLACK}Sisesta serveri aadress
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Kliendid
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Kliente sees / maksimum
+STR_NETWORK_GAME_INFO :{SILVER}MÄNGU INFO
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Kliendid: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Keel: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Maastikuühikud: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Kaardi suurus: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}Serveri versioon: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}Serveri aadress: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Algus aeg: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Hetke aeg: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Parooliga kaitstud!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}SERVER ON MAAS
+STR_NETWORK_SERVER_FULL :{SILVER}SERVER ON TÄIS
+STR_NETWORK_VERSION_MISMATCH :{SILVER}VERSIOON EI SOBI
+STR_NETWORK_GRF_MISMATCH :{SILVER}NEWGRF SOBIMATUS
+
+STR_NETWORK_JOIN_GAME :{BLACK}Liitu mänguga
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}Uue võrgumängu alustamine
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Mängu nimi:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}Mängu nime näidatakse teistele mänijatele võrgumängu serverite nimekirjas
+STR_NETWORK_SET_PASSWORD :{BLACK}Sea parool
+STR_NETWORK_PASSWORD_TIP :{BLACK}Kaitse oma mäng parooliga, kui sa ei taha, et kõik sellele ligi pääseksid
+STR_NETWORK_SELECT_MAP :{BLACK}Vali kaart:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}Millist kaarti sa tahad mängida?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}Maksimaalne klientide arv:
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Määra suurim klientide arv. Kõik vabad kohad ei pea täidetud olema
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :kohtvõrk (LAN)
+STR_NETWORK_INTERNET :Internet
+STR_NETWORK_LAN_INTERNET :LAN / Internet
+STR_NETWORK_INTERNET_ADVERTISE :Internet (reklaami)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 mängijat
+STR_NETWORK_1_PLAYERS :1 mängija
+STR_NETWORK_2_PLAYERS :2 mängijat
+STR_NETWORK_3_PLAYERS :3 mängijat
+STR_NETWORK_4_PLAYERS :4 mängijat
+STR_NETWORK_5_PLAYERS :5 mängijat
+STR_NETWORK_6_PLAYERS :6 mängijat
+STR_NETWORK_7_PLAYERS :7 mängijat
+STR_NETWORK_8_PLAYERS :8 mängijat
+STR_NETWORK_9_PLAYERS :9 mängijat
+STR_NETWORK_10_PLAYERS :10 mängijat
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}Maks. firmasi:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Luba serveris X mängijat
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}Maks. vaatajaid
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Luba serveris X vaatajat
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Räägitav keel:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Teistele mängijatele teadmiseks, et mis keelt serveris räägitakse
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}Alusta mängu
+STR_NETWORK_START_GAME_TIP :{BLACK}Uue võrgumängu alustamine suvalise kaardiga
+STR_NETWORK_LOAD_GAME :{BLACK}Mängu laadimine
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Varasema võrgumängu jätkamine (vaata, et ühendad ennast õige mängijana)
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Suvaline
+STR_NETWORK_LANG_ENGLISH :Inglise keel
+STR_NETWORK_LANG_GERMAN :Saksa keel
+STR_NETWORK_LANG_FRENCH :Prantsuse keel
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Võrgumängu jututuba
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Ãœhinemiseks valmistumine: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}Nimekiri mängus oelvatest ettevõtetest. Saad liituda ühega või alustada uut, kui on vabu kohti
+STR_NETWORK_NEW_COMPANY :{BLACK}Uus ettevõte
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Uue ettevõtte loomine
+STR_NETWORK_SPECTATE_GAME :{BLACK}Jälgi mängu
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Vaata mängu kõrvalt
+STR_NETWORK_JOIN_COMPANY :{BLACK}Liitu ettevõttega
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Aita seda ettevõtet töös hoida
+STR_NETWORK_REFRESH :{BLACK}Värskenda servereid
+STR_NETWORK_REFRESH_TIP :{BLACK}Serveri info värskendamine
+
+STR_NETWORK_COMPANY_INFO :{SILVER}ETTEVÕTE INFO
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Ettevõtte nimi: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}Avamine: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}Ettevõtte väärtus: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Rahaline seis: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Eelmise aasta sissetulek: {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}Suutlikus: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}Sõidukid: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Jaamad: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Mängijad: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}Ãœhendan...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) Ãœhendan...
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Kontrollin õigusi...
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Ootel...
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) kaardi allalaadimine...
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Andmete töötlemine...
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) Registreerimine...
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Hangin mängu infot...
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Hangin ettevõtte infot...
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} kelint{P "" e} sinu ees
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} kbaiti tõmmatud
+
+STR_NETWORK_DISCONNECT :{BLACK}Katkesta
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Teisele mängijale saadetava rahasumma sisestamine
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Server on kaitstud. Sisesta parool
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Ettevõte on kaitstud. Sisesta parool
+STR_NETWORK_CLIENT_LIST :{WHITE}Klientide nimekiri
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE} Võrgukaarti ei leitud või kompileeritud ilma võtmeta ENABLE_NETWORK
+STR_NETWORK_ERR_NOSERVER :{WHITE} Ei leidnud ühtegi võrgumängu
+STR_NETWORK_ERR_NOCONNECTION :{WHITE} Server ei vastanud päringule
+STR_NETWORK_ERR_DESYNC :{WHITE} Võrgumäng läks sünkroonist välja
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} Võrgumängu ühendus katkes
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} Mängu laadimine ebaõnnestus
+STR_NETWORK_ERR_SERVER_START :{WHITE} Ei saa uut serverit alustada
+STR_NETWORK_ERR_CLIENT_START :{WHITE} Ei õnneust ühendada
+STR_NETWORK_ERR_TIMEOUT :{WHITE} Ãœhendusel #{NUM} sai aeg otsa
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE} Tekkis protokolliviga ja ühendus katkes
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE} Kliendi versioon ei vasta serveri versiooniga
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} Vale parool
+STR_NETWORK_ERR_SERVER_FULL :{WHITE} Server on täis
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} Sinu sisenemine siia serverisse on keelatud
+STR_NETWORK_ERR_KICKED :{WHITE} Sind visati mängust välja
+STR_NETWORK_ERR_CHEATER :{WHITE} Selles serveris on petmine keelatud
+
+STR_NETWORK_ERR_LEFT :lahkus mängust
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :üldine viga
+STR_NETWORK_ERR_CLIENT_DESYNC :sünkroniseerimise viga
+STR_NETWORK_ERR_CLIENT_SAVEGAME :ei saa kaarti laadida
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :ühendus katkes
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :protokolli viga
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :Keelatud
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :kahtlane pakett vastu võetud
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :vale versioon
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :nimi on juba kasutusel
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :vale mängu parool
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :vale mängija-id DoCommand'is
+STR_NETWORK_ERR_CLIENT_KICKED :server viskas välja
+STR_NETWORK_ERR_CLIENT_CHEATER :üritas pettust kasutada
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :server on täis
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :liitus mänguga
+STR_NETWORK_GIVE_MONEY :andis sinu ettevõtele raha ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :sina andsid ettevõttele {STRING} raha ({CURRENCY})
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Team] :
+STR_NETWORK_CHAT_COMPANY :[Team] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Team] kohta {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[Private] :
+STR_NETWORK_CHAT_CLIENT :[Private] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[Private] kohta {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[All] :
+STR_NETWORK_CHAT_ALL :[All] {STRING}: {GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :muutis oma nimeks
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE} Server sulges sessiooni
+STR_NETWORK_SERVER_REBOOT :{WHITE} Server restardib...{}Palun oota...
+
+STR_NETWORK_SERVER :Server
+STR_NETWORK_CLIENT :Klient
+STR_NETWORK_SPECTATORS :Pealtvaatajad
+
+STR_NETWORK_CLIENTLIST_NONE :(pole)
+STR_NETWORK_CLIENTLIST_KICK :Viska välja
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Anna raha
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Räägi kõigiga
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Räägi ettevõttega
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Privaatne sõnum
+
+
+STR_NETWORK_SEND :{BLACK}Saada
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}Kaardi X-telje suurus: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Kaardi Y-telje suurus: {ORANGE}{STRING}
+
+
+##### PNG-MAP-Loader
+
+STR_PNGMAP_ERROR :{WHITE}Ei saa maapinda PNG failist laadida...
+STR_PNGMAP_ERR_FILE_NOT_FOUND :{WHITE}...faili ei leitud.
+STR_PNGMAP_ERR_IMAGE_TYPE :{WHITE}...ei suutnud pilditüüpi teisendada. Vaja läheb 8 või 24-bitist PNG pilti.
+STR_PNGMAP_ERR_MISC :{WHITE}...midagi läks just valesti. Vabandust. (tõenäoliselt rikutud fail)
+
+STR_BMPMAP_ERROR :{WHITE}Ei suuda laadida maad BMP failist...
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}...ei suutnud muuta pildi tüüpi.
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Hind: {CURRENCY}
+STR_0801_COST :{RED}Hind: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Sissetulek: {CURRENCY}
+STR_0803_INCOME :{GREEN}Sissetulek: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Kanna üle: {CURRENCY}
+STR_FEEDER :{YELLOW}Kanna üle: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Eeldatav hind: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Eeldatav sissetulek: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Siin ei saa maad kõrgendada...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Siin ei saa maad madaldada...
+STR_080A_ROCKS :Kaljud
+STR_080B_ROUGH_LAND :Konarlik maa
+STR_080C_BARE_LAND :Paljas maa
+STR_080D_GRASS :Muru
+STR_080E_FIELDS :Põllud
+STR_080F_SNOW_COVERED_LAND :Lumekattega maa
+STR_0810_DESERT :Kõrb
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Maa on vales suunas kaldu
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Teostamatu raudteede kombinatsioon
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}Kaevandamine kahjustaks tunnelit
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Juba jõutud meretasemeni
+STR_1004_TOO_HIGH :{WHITE}Liiga kõrge
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Sobiv rongitee puudub
+STR_1007_ALREADY_BUILT :{WHITE}...juba ehitatud
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Raudtee tuleb eelnevalt eemaldada
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Raudteede ehitamine
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Elektriraudtee ehitus
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Monorelsi ehitus
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}MagLevi ehitus
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Vali raudteesild
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Siia ei saa depood ehitada...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Siia ei saa rongijaama ehitada...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Siia ei saa signaaltuld asetada...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Siia ei saa raudteed ehitada...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Siit ei saa raudteed eemaldada...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Siit ei saa signaaltulesid eemaldada...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Depoo suuna
+STR_1015_RAILROAD_CONSTRUCTION :Raudtee ehitus
+STR_TOOLB_ELRAIL_CONSTRUCTION :Elektriraudtee ehitus
+STR_1016_MONORAIL_CONSTRUCTION :Monorelsi ehitus
+STR_1017_MAGLEV_CONSTRUCTION :MagLevi ehitus
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Ehita rongitee
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Ehita rongidepoo (rongide ehitamiseks ja hoolduseks)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Ehita rongijaam
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Ehita rongisignaalid
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Ehita raudteesild
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Ehita rongitunnel
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Rööbaste ja signaaltulede ehitamine/eemaldamine
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Silla valik - klõpsa sobivale sillale, et seda ehitada
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Depoole suuna valimine
+STR_1021_RAILROAD_TRACK :Raudtee
+STR_1023_RAILROAD_TRAIN_DEPOT :Rongidepoo
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...ala kuulub teisele ettevõttele
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :Raudtee tavaliste signaaltuledega
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :Raudtee eel-signaalidega
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :Raudtee väljumis-signaalidega
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :Raudtee mitmiksignaalidega
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Enne on vaja maantee eemaldada
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Teede ehitamine
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Teede ehitamine
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Vali sillatüüp
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Siia ei saa maanteed ehitada...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Siit ei saa maanteed eemaldada...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Depoo suund
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Siia ei saa depood ehitada...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Siia ei saa bussijaama ehitada...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Siia ei saa laadimisplatsi ehitada...
+STR_180A_ROAD_CONSTRUCTION :Teeehitus
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Ehita tee osa
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Depoo ehitamine (sõidukite ehitamiseks ja hooldamiseks)
+STR_180D_BUILD_BUS_STATION :{BLACK}Ehita bussijaam
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Ehita veokite laadimisplats
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Ehita sild
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Ehita tunnel
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Teeehituse ja -eemaldamise vahetamine
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Vali depoole suund
+STR_1814_ROAD :Maantee
+STR_1815_ROAD_WITH_STREETLIGHTS :Valgustatud maantee
+STR_1816_TREE_LINED_ROAD :Kolmerajaline tee
+STR_1817_ROAD_VEHICLE_DEPOT :Depoo
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :Raudtee ülesõit
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Linnad
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Ehitis tuleb eelnevalt hävitada
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}Rahvastik: {ORANGE}{COMMA}{BLACK} Maju: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Linnanime muutmine
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Linnanime ei saa muuta...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} kohalik võim keeldub seda lubamast
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Linnanimed - vajuta linnanimele, et viia vaade linnale
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Vaate viimine linnale
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Linnanime muutmine
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Reisijaid eelmisel kuul: {ORANGE}{COMMA}{BLACK} maksimum: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Posti eelmisel kuul: {ORANGE}{COMMA}{BLACK} maksimum: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Kõrge büroohoone
+STR_2010_OFFICE_BLOCK :Büroohoone
+STR_2011_SMALL_BLOCK_OF_FLATS :Väike kortermaja
+STR_2012_CHURCH :Kirik
+STR_2013_LARGE_OFFICE_BLOCK :Suur büroohoone
+STR_2014_TOWN_HOUSES :Linna majad
+STR_2015_HOTEL :Hotell
+STR_2016_STATUE :Kuju
+STR_2017_FOUNTAIN :Purskkaev
+STR_2018_PARK :Park
+STR_2019_OFFICE_BLOCK :Büroohoone
+STR_201A_SHOPS_AND_OFFICES :Poed ja bürood
+STR_201B_MODERN_OFFICE_BUILDING :Moodne büroohoone
+STR_201C_WAREHOUSE :Ladu
+STR_201D_OFFICE_BLOCK :Büroohoone
+STR_201E_STADIUM :Staadion
+STR_201F_OLD_HOUSES :Vanad majad
+STR_2020_LOCAL_AUTHORITY :{BLACK}Kohalik võim
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Näita teavet kohaliku võimu kohta
+STR_2022_LOCAL_AUTHORITY :{WHITE}{TOWN} kohalik võim
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Ettevõtete hinnangud:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Toetused
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Pakutavad toetused teenusepakkumise eest:
+STR_2027_FROM_TO :{ORANGE}{STRING} kohast {STRING} kohta {STRING}
+STR_2028_BY :{YELLOW} (kuni {DATE_SHORT})
+STR_202A_NONE :{ORANGE}Mitte ühtegi
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Juba toetatavad teenused
+STR_202C_FROM_TO :{ORANGE}{STRING} kohast {STATION} kohta {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, kuni {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}Toetuse pakkumine lõppes: {}{}transporditeenuse {STRING} kohast {STRING} kohta {STRING} eest ei maksta enam toetusi.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Toetuse maksmise aeg sai läbi:{}{}{STRING}kohast {STATION} kohta {STATION} eest ei maksta enam edaspidi toetust.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Transporditeenusele pakutakse toetust:{}{}{STRING} kohast {STRING} kohta {STRING}. Esimesele, kes teenust pakkuma hakkab, makstakse aasta läbi toetusi!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Teenusetoetust makstakse ettevõttele {COMPANY}!{}{}{STRING} kohast {STATION} kohta {STATION} teenuse eest makstakse järgmisel aastal 50% rohkem!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Teenusetoetust makstakse ettevõttele {COMPANY}!{}{}{STRING} kohast {STATION} kohta {STATION} teenuse eest makstakse järgmisel aastal kahekordselt!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Teenusetoetust makstakse ettevõttele {COMPANY}!{}{}{STRING} kohast {STATION} kohta {STATION} teenuse eest makstakse järgmisel aastal kolmekordselt!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Teenusetoetust makstakse ettevõttele {COMPANY}!{}{}{STRING} kohast {STATION} kohta {STATION} teenuse eest makstakse järgmisel aastal neljakordselt!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}Linna {TOWN} kohalik võim keelab uut lennujaama siia ehitada
+STR_2036_COTTAGES :Suvilad
+STR_2037_HOUSES :Majad
+STR_2038_FLATS :Korterid
+STR_2039_TALL_OFFICE_BLOCK :Kõrge büroohoone
+STR_203A_SHOPS_AND_OFFICES :Poed ja bürood
+STR_203B_SHOPS_AND_OFFICES :Poed ja bürood
+STR_203C_THEATER :Teater
+STR_203D_STADIUM :Staadion
+STR_203E_OFFICES :Bürood
+STR_203F_HOUSES :Majad
+STR_2040_CINEMA :Kino
+STR_2041_SHOPPING_MALL :Ostukeskus
+STR_2042_DO_IT :{BLACK}Soorita toiming
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}Nimekiri asjadest, mida saab siin linnas teha - vajuta nimele, et saada rohkem informatsiooni
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Soorita ülalpool valitud toiming
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Pakutavad toimingud:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Väike reklaamikampaania
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Keskmine reklaamikampaania
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Suur reklaamikampaania
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Rahasta kohalikke teetöid
+STR_204A_BUILD_STATUE_OF_COMPANY :Ehita ettevõtte omaniku kuju
+STR_204B_FUND_NEW_BUILDINGS :Rahasta uute hoonete ehitust
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Osta monopoolsed transpordiõigused
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Paku kohalikele võimuesindajatele altkäemaksu
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Väikese reklaamikampaania korraldamine rohkemate reisijate ja kaupade meelitamiseks kasutama sinu teenuseid.{} Hind: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Keskmise reklaamikampaania korraldamine, et meelitada rohkem reisijaid ja kaupu sinu teenuste juurede.{} Hind: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Suure reklaamikampaania korraldamine, et meelitada rohkem reisijaid ja kaupu sinu teenuste juurede.{} Hind: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} Teetööde rahastamine. Põhjustab linnateedel tõsiseid liiklusprobleeme kuni 6 kuuks.{} Hind: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Oma ettevõtte auks kuju ehitamine.{} Hind: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Uute ärihoonete ehitamise rahastamine selles linnas.{} Hind: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Üheks aastaks monopoolsete transpordiõiguste ostmine selles linnas. Linna võimud lubavad reisijate ja kauba veoks kasutada ainult sinu jaamasid.{} Hind: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Linnavõimudele ettevõtu reitingu tõstmise eesmärgil altkäemaksu pakkumine. Vahele jäädes korral tuleb trahvi maksta.{} Hind: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}Liikluskaos linnas {TOWN}!{}{}Ettevõtte {COMPANY} poolt rahastatud teedeehitus tekitab 6 kuu jooksul maanteedel liiklushäireid!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (ehitusel)
+STR_2059_IGLOO :Iglu
+STR_205A_TEPEES :Tipid
+STR_205B_TEAPOT_HOUSE :Teepoti maja
+STR_205C_PIGGY_BANK :Krossu pank
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN} {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Maapinna kujunuds
+STR_2800_PLANT_TREES :Puude istutamine
+STR_2801_PLACE_SIGN :Paigalda silt
+STR_2802_TREES :{WHITE}Puud
+STR_2803_TREE_ALREADY_HERE :{WHITE}...siin on juba puu olemas
+STR_2804_SITE_UNSUITABLE :{WHITE}...ebasobiv koht
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Siia ei saa puud istutada...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...liiga palju silte
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Siia ei saa silti paigaldada...
+STR_280A_SIGN :Silt
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Sildi muutmine
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Silti ei saa muuta...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Istutatava puu liigi valimine
+STR_280E_TREES :Puud
+STR_280F_RAINFOREST :Vihmamets
+STR_2810_CACTUS_PLANTS :Kaktused
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Raudteejaama valik
+STR_3001_AIRPORT_SELECTION :{WHITE}Lennujaama valik
+STR_3002_ORIENTATION :{BLACK}Orientatsioon
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Radade arv
+STR_3004_PLATFORM_LENGTH :{BLACK}Platvormi pikkus
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Teisele raudteejaamale liiga lähedal
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Mitme olemasoleva jaama ühendamine
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}Selles linnas on juba liiga palju jaamasid
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}Liiga palju jaamu
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Liiga palju bussipeatusi
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}Liiga palju laadimisplatvorme
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Mõnele teisele jaamale liiga lähedal
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Raudteejaam tuleb eelnevalt hävitada
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Liiga lähedal teisele lennuväljale
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Lennujaam tuleb eelnevalt hävitada
+
+STR_3030_RENAME_STATION_LOADING :Jaama nime muutmine
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Jaama nime ei saa muuta...
+STR_3032_RATINGS :{BLACK}Reitingud
+STR_3033_ACCEPTS :{BLACK}Võtab vastu
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}Kohalik transporditeenuse reiting:
+
+############ range for rating starts
+STR_3035_APPALLING :Kohutav
+STR_3036_VERY_POOR :Väga halb
+STR_3037_POOR :Kehv
+STR_3038_MEDIOCRE :Keskpärane
+STR_3039_GOOD :Hea
+STR_303A_VERY_GOOD :Väga hea
+STR_303B_EXCELLENT :Suurepärane
+STR_303C_OUTSTANDING :Eesrindlik
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}Jaam {STATION} ei võta enam vastu veost {STRING}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}Jaam {STATION} ei võta enam vastu veoseid {STRING}, ega {STRING}
+STR_3040_NOW_ACCEPTS :{WHITE}Jaam {STATION} võtab nüüd vastu veost {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}Jaam {STATION} võtab nüüd vastu veoseid {STRING} ja {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Bussijaama suund
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Laadimisplatsi suund
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Bussijaam tuleb enne hävitada
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Enne pead laadimisplatsi hävitama
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Jaam{P "" ad}
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Puudub -
+STR_304B_SITE_UNSUITABLE :{WHITE}...ebasobiv koht
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Liiga lähedal teisele sadamale
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Enne pead sadama hävitama
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Raudteejaamale suuna valimine
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Vali raudteejaama platvormide arv
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Vali raudteejaama pikkus
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Vali bussijaamale suund
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Vali laadimisplatsile suund
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Vaate viimine jaama juurde
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Näita jaama reitinguid
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Muuda jaama nime
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Näita vastuvõetavate veoste nimistut
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Jaamade nimed - vajuta nimel, et viia vaadet jaamale
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Vali lennuvälja suurus, ning tüüp
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :Raudteejaam
+STR_305F_AIRCRAFT_HANGAR :Angaar
+STR_3060_AIRPORT :Lennujaam
+STR_3061_TRUCK_LOADING_AREA :Laadimisplats
+STR_3062_BUS_STATION :Bussijaam
+STR_3063_SHIP_DOCK :Laevasadam
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Lülita sisse jaama mõjupiirkonna näitamine
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Lülita välja jaama mõjupiirkonna näitamine
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Näita mõjupiirkonda
+STR_3068_DOCK :{WHITE}Sadam
+STR_3069_BUOY :Poi
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...poi on ees
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...jaam on liiga laiaks venitatud
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...korrapäratud jaamad keelatud
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Enam kui ühe eseme valimiseks hoia all CTRL klahvi
+
+STR_UNDEFINED :(määratlemata väljend)
+STR_STAT_CLASS_DFLT :Vaikimisi valitud jaam
+STR_STAT_CLASS_WAYP :Kontrollpunktid
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Paadikuuri Orientatsioon
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...peab ehitama vette
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Siia ei saa laevaangaari ehitada...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Laevaangaarile suuna valimine
+STR_3804_WATER :Vesi
+STR_3805_COAST_OR_RIVERBANK :Kallas
+STR_3806_SHIP_DEPOT :Laevaangaar
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...vette ei saa ehitada
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Salvesta mäng
+STR_4001_LOAD_GAME :{WHITE}Laadi mäng
+STR_4002_SAVE :{BLACK}Salvesta
+STR_4003_DELETE :{BLACK}Kustuta
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} megabaiti{P "" i} vaba
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Ei suuda kettalt lugeda
+STR_4007_GAME_SAVE_FAILED :{WHITE}Mängu salvestamine ebaõnnestus
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Faili ei saa kustutada
+STR_4009_GAME_LOAD_FAILED :{WHITE}Mängu laadimine ebaõnnestus
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}Nimekiri ketastest, kataloogidest ja salvestatud mängudest
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Mängu salvestuse nimi
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Kustuta valitud salvestus
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Salvesta mäng valitud nimega
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Vali uue mängu tüüp
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Vali valmis kaart (roheline), eelseadistatud mäng (sinine), või juhusliku kaardiga uus mäng
+STR_4010_GENERATE_RANDOM_NEW_GAME :Tekita juhuslik kaart
+STR_4011_LOAD_HEIGHTMAP :{WHITE}Laadi kõrguskaart
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} on ees
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :kivisöekaevandus
+STR_4803_POWER_STATION :elektrijaam
+STR_4804_SAWMILL :saeveski
+STR_4805_FOREST :mets
+STR_4806_OIL_REFINERY :naftatöötlustehas
+STR_4807_OIL_RIG :naftaplatvorm
+STR_4808_FACTORY :vabrik
+STR_4809_PRINTING_WORKS :trükikoda
+STR_480A_STEEL_MILL :terasetööstus
+STR_480B_FARM :farm
+STR_480C_COPPER_ORE_MINE :vasemaagi kaevandus
+STR_480D_OIL_WELLS :nafta puurauk
+STR_480E_BANK :pank
+STR_480F_FOOD_PROCESSING_PLANT :toiduainetetööstus
+STR_4810_PAPER_MILL :paberivabrik
+STR_4811_GOLD_MINE :kullakaevandus
+STR_4812_BANK :pank
+STR_4813_DIAMOND_MINE :teemantikaevandus
+STR_4814_IRON_ORE_MINE :rauamaagi kaevandus
+STR_4815_FRUIT_PLANTATION :puuviljaistandus
+STR_4816_RUBBER_PLANTATION :kummipuu istandus
+STR_4817_WATER_SUPPLY :veepumbad
+STR_4818_WATER_TOWER :veetorn
+STR_4819_FACTORY :vabrik
+STR_481A_FARM :farm
+STR_481B_LUMBER_MILL :saeveski
+STR_481C_COTTON_CANDY_FOREST :suhkruvati mets
+STR_481D_CANDY_FACTORY :kommivabrik
+STR_481E_BATTERY_FARM :patarei farm
+STR_481F_COLA_WELLS :koolapumbad
+STR_4820_TOY_SHOP :mänguasjapood
+STR_4821_TOY_FACTORY :mänguasjatehas
+STR_4822_PLASTIC_FOUNTAINS :plastmassiallikas
+STR_4823_FIZZY_DRINK_FACTORY :kihisevate jookide tehas
+STR_4824_BUBBLE_GENERATOR :mulligeneraator
+STR_4825_TOFFEE_QUARRY :iirisekaevandus
+STR_4826_SUGAR_MINE :suhkrukaevandus
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Vajab: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Vajab: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Vajab: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Eelmise kuu toodang:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% transporditud)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Vaate keskendamine tööstusele
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Uus {STRING} on linna {TOWN} lähedal ehitamisel!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Uus {STRING} on istutatud linna {TOWN} lähedale!
+STR_482F_COST :{BLACK}Hind: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Seda tüüpi tööstust ei saa siia ehitada...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...metsa saab istutada ainult lumepiirist kõrgemale
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} juhtkond teatab sulgemisest!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}{INDUSTRY} teatab sulgemisest varustusprobleemide tõttu!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}Lähiümbruse puude puudumine põhjustab {INDUSTRY} sulgemise!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} tõuseb toodang!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}{INDUSTRY} lähedal avati uus kivisöe kiht!{}Toodang kahekordistub!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}{INDUSTRY} lähedal avastati uusi naftareserve!{}Toodang kahekordistub!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}{INDUSTRY} võttis kasutusele uued põllutöövahendid! Toodang kahekordistub!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}{INDUSTRY} toodang langes 50%
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}Putukate rünnak - {INDUSTRY}!{}Toodang langes 50%
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...saab ainult ehitada kaardi serva
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}{STRING.g} toodang ettevõttes {INDUSTRY} langeb {COMMA}%!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}{STRING.g} toodang ettevõttes {INDUSTRY} langeb {COMMA}%!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Rong tunnelis
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Sõiduk tunnelis
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Teine tunnel on ees
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Ei saa tunneli teise otsa jaoks maad parajaks kaevata
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Enne tuleb tunnel hävitada
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Enne tuleb sild hävitada
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Ei saa alata ja lõppeda samas kohas
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Silla otsade kõrgus peab sama olema
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}Algus ja lõpp peavad samal joonel olema
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Koht ei sobi tunneli sissekäiguks
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Rippsild, terasest
+STR_500F_GIRDER_STEEL :Raamistikuga, terasest
+STR_5010_CANTILEVER_STEEL :Ulgtugi, terasest
+STR_5011_SUSPENSION_CONCRETE :Rippsild, betoonist
+STR_5012_WOODEN :Puidust
+STR_5013_CONCRETE :Betoonist
+STR_5014_TUBULAR_STEEL :Torujas, terasest
+STR_BRIDGE_TUBULAR_SILICON :Torujas, silikoonist
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Siia ei saa silda ehitada...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Siia ei saa tunnelit ehitada...
+STR_5017_RAILROAD_TUNNEL :Raudteetunnel
+STR_5018_ROAD_TUNNEL :Maanteetunnel
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Terasest raudtee rippsild
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Terasest võrestikuga raudteesild
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Terasest ulgtoestikuga raudteesild
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Raudbetoonist raudtee rippsild
+STR_501F_WOODEN_RAIL_BRIDGE :Puidust raudteesild
+STR_5020_CONCRETE_RAIL_BRIDGE :Betoonist raudteesild
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Terasest raudtee rippsild
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Terasraamistikuga maanteesild
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Terasest ulgtoestikuga maanteesild
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Raudbetoonist maantee rippsild
+STR_5025_WOODEN_ROAD_BRIDGE :Puidust maanteesild
+STR_5026_CONCRETE_ROAD_BRIDGE :Betoonist maanteesild
+STR_5027_TUBULAR_RAIL_BRIDGE :Torujas raudteesild
+STR_5028_TUBULAR_ROAD_BRIDGE :Torujas maanteesild
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Mingi objekt on ees
+STR_5801_TRANSMITTER :Retranslaator
+STR_5802_LIGHTHOUSE :Tuletorn
+STR_5803_COMPANY_HEADQUARTERS :Ettevõtte peakorter
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...ettevõtte peakorter on ees
+STR_5805_COMPANY_OWNED_LAND :Ettevõtte maa
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Seda maad ei saa osta...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...see on juba sinu oma!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Nimetu
+STR_SV_TRAIN_NAME :Rong {COMMA}
+STR_SV_ROADVEH_NAME :Maanteesõiduk {COMMA}
+STR_SV_SHIP_NAME :Laev {COMMA}
+STR_SV_AIRCRAFT_NAME :Õhusõiduk {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :Põhja {STRING}
+STR_SV_STNAME_SOUTH : Lõuna {STRING}
+STR_SV_STNAME_EAST : Ida {STRING}
+STR_SV_STNAME_WEST : Lääne {STRING}
+STR_SV_STNAME_CENTRAL :{STRING} keskus
+STR_SV_STNAME_TRANSFER :{STRING} ülekanne
+STR_SV_STNAME_HALT :{STRING} peatus
+STR_SV_STNAME_VALLEY :{STRING} org
+STR_SV_STNAME_HEIGHTS :{STRING} kõrgendikud
+STR_SV_STNAME_WOODS :{STRING} metsad
+STR_SV_STNAME_LAKESIDE :{STRING} järveäärne
+STR_SV_STNAME_EXCHANGE :{STRING} vahetus
+STR_SV_STNAME_AIRPORT :{STRING} lennujaam
+STR_SV_STNAME_OILFIELD :{STRING} naftaväli
+STR_SV_STNAME_MINES :{STRING} kaevandused
+STR_SV_STNAME_DOCKS :{STRING} sadam
+STR_SV_STNAME_BUOY_1 :{STRING} poi #1
+STR_SV_STNAME_BUOY_2 :{STRING} poi #2
+STR_SV_STNAME_BUOY_3 :{STRING} poi #3
+STR_SV_STNAME_BUOY_4 :{STRING} poi #4
+STR_SV_STNAME_BUOY_5 :{STRING} poi #5
+STR_SV_STNAME_BUOY_6 :{STRING} poi #6
+STR_SV_STNAME_BUOY_7 :{STRING} poi #7
+STR_SV_STNAME_BUOY_8 :{STRING} poi #8
+STR_SV_STNAME_BUOY_9 :{STRING} poi #9
+STR_SV_STNAME_ANNEXE :{STRING} juurdeehitis
+STR_SV_STNAME_SIDINGS :{STRING} hargnemine
+STR_SV_STNAME_BRANCH :{STRING} filiaal
+STR_SV_STNAME_UPPER :Ãœlemine {STRING}
+STR_SV_STNAME_LOWER :Alumine {STRING}
+STR_SV_STNAME_HELIPORT :{STRING} helikopteri maandumisplats
+STR_SV_STNAME_FOREST :{STRING} mets
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Raskusaste
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Salvesta
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Kerge
+STR_6802_MEDIUM :{BLACK}Keskmine
+STR_6803_HARD :{BLACK}Raske
+STR_6804_CUSTOM :{BLACK}Iseseadistatud
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maksimaalne konkurentide arv: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Konkurentide tulemise aeg: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}Linnade arv: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}Tööstuste arv: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Suurim laen alguses: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Intress alguses: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Sõidukite hoolduskulud: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Konkurentide ehituskiirus: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Konkurentide intelligentsus: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Sõidukite lagunemine: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Subsiidiumi suurus: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Ehitamise hind: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Maastiku tüüp: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Merede/järvede kogus: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Majandus: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Rongide ümberpööramine: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Katastroofid: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Linnanõukogu suhtumine maastikukujundusse: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :Pole
+STR_6816_LOW :Madal
+STR_6817_NORMAL :Harilik
+STR_6818_HIGH :Kõrge
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Väga aeglane
+STR_681C_SLOW :Aeglane
+STR_681D_MEDIUM :Keskmine
+STR_681E_FAST :Kiire
+STR_681F_VERY_FAST :Väga kiire
+STR_VERY_LOW :Väga madal
+STR_6820_LOW :Madal
+STR_6821_MEDIUM :Keskmine
+STR_6822_HIGH :Kõrge
+STR_6823_NONE :Puudub
+STR_6824_REDUCED :Vähendatud
+STR_6825_NORMAL :Harilik
+STR_6826_X1_5 :1,5x
+STR_6827_X2 :2x
+STR_6828_X3 :3x
+STR_6829_X4 :4x
+STR_682A_VERY_FLAT :Väga tasane
+STR_682B_FLAT :Tasane
+STR_682C_HILLY :Künklik
+STR_682D_MOUNTAINOUS :Mägine
+STR_682E_STEADY :Rahulik
+STR_682F_FLUCTUATING :Kõikuva nõudlusega
+STR_6830_IMMEDIATE :Koheselt
+STR_6831_3_MONTHS_AFTER_PLAYER :3 kuud pärast mängijat
+STR_6832_6_MONTHS_AFTER_PLAYER :6 kuud pärast mängijat
+STR_6833_9_MONTHS_AFTER_PLAYER :9 kuud pärast mängijat
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :Raudtee lõpus ja jaamas
+STR_6835_AT_END_OF_LINE_ONLY :Ainult raudtee lõpus
+STR_6836_OFF :Väljas
+STR_6837_ON :Sees
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Näita mängijate edetabelit
+STR_6839_PERMISSIVE :Soodustav
+STR_683A_TOLERANT :Tolerantne
+STR_683B_HOSTILE :Vaenulik
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY}{BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(mängija {COMMA})
+STR_7004_NEW_FACE :{BLACK}Uus nägu
+STR_7005_COLOR_SCHEME :{BLACK}Värvivalik
+STR_7006_COLOR_SCHEME :{GOLD}Värvivalik:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Uus värvivalik
+STR_7008_COMPANY_NAME :{BLACK}Ettevõtte nimi
+STR_7009_PRESIDENT_NAME :{BLACK}Presidendi nimi
+STR_700A_COMPANY_NAME :Ettevõtte nimi
+STR_700B_PRESIDENT_S_NAME :Presidendi nimi
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Ei saa ettevõtte nime muuta...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Ei saa presidendi nime muuta...
+STR_700E_FINANCES :{WHITE}{COMPANY} finantsaruanne {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Kulud/Tulud
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Ehitamine
+STR_7012_NEW_VEHICLES :{GOLD}Uued sõidukid
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Rongide hoolduskulud
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Mnt.sõidukite hoolduskulud
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Õhusõidukite hoolduskulud
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Laevade hoolduskulud
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Kinnisvara korrashoid
+STR_7018_TRAIN_INCOME :{GOLD}Rongide sissetulekud
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Mnt.sõidukite sissetulekud
+STR_701A_AIRCRAFT_INCOME :{GOLD}Õhusõidukite sissetulekud
+STR_701B_SHIP_INCOME :{GOLD}Laevade sissetulekud
+STR_701C_LOAN_INTEREST :{GOLD}Laenuintress
+STR_701D_OTHER :{GOLD}Kõik muu
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Kokku:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Sissetulekute graafik
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Opereerimiskasumi graafik
+STR_7026_BANK_BALANCE :{WHITE}Kontojääk
+STR_7027_LOAN :{WHITE}Laen
+STR_MAX_LOAN :{WHITE}Suurim võimalik laen: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}Laena {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Maksa tagasi {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...suurim lubatud laen on {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Rohkem raha ei saa laenata...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...pole laenu, mida tagasi maksta
+STR_702E_REQUIRED :{WHITE}...vajad {CURRENCY}
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Ei saa laenu tagasi maksta...
+STR_INSUFFICIENT_FUNDS :{WHITE}Ei saa anda raha, mis on laenatud pangast.
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Vali presidendile uus nägu
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Muuda ettevõtte sõidukite värvi
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Muuda presidendi nägu
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Muuda ettevõtte nime
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Värvil vajutades valib värvi
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Laena raha
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Maksa laen osaliselt tagasi
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(President)
+STR_7038_INAUGURATED :{GOLD}Asutatud: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Sõidukeid:
+STR_TRAINS :{WHITE}{COMMA} rong{P "" i}
+STR_ROAD_VEHICLES :{WHITE}{COMMA} veoki {P "" s}
+STR_AIRCRAFT :{WHITE}{COMMA} lennuk
+STR_SHIPS :{WHITE}{COMMA} laev{P "" s}
+STR_7042_NONE :{WHITE}Mitte ühtegi
+STR_7043_FACE_SELECTION :{WHITE}Näo valik
+STR_7044_MALE :{BLACK}Mees
+STR_7045_FEMALE :{BLACK}Naine
+STR_7046_NEW_FACE :{BLACK}Uus nägu
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Katkesta uue näo valimine
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Uue näo valimine
+STR_7049_SELECT_MALE_FACES :{BLACK}Vali mehe nägu
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Vali naise nägu
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Loo uus juhuslik nägu
+STR_704C_KEY :{BLACK}Selgitus
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Näita selgitust graafikute juures
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Ettevõttegraafiku selgitus
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Vajuta, et ettevõtte graafikut sisse ja välja lülitada
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Transporditud veoste kogus
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Ettevõtte tegevuse reiting (maksimaalne reiting=1000)
+STR_7052_COMPANY_VALUES :{WHITE}Ettevõtte väärtus
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Ettevõtete edetabel
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}Ettevõttel on probleeme!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}Ettevõte {COMPANY} müüakse maha ja kuulutatakse pankrot, kui tulemused peatselt ei parane!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(President)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Ettevõtete ühinemine!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} müüdi ettevõttele {COMPANY} {CURRENCY} eest!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Otsime ettevõtet, kes võtaks meie firma üle.{}{}Kas soovite osta ettevõtte {COMPANY} {CURRENCY} eest?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Pankrot!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} suleti asutajate poolt ja kõik varad müüakse maha!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}Loodi uus ettevõte!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}Ettevõte {COMPANY} alustas linna {TOWN} lähedal ehitustöid!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Ettevõtet ei saa osta...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Veoste hinnagraafik
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Päevi teel
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Makstav summa 10 ühiku (või 10'000 liitri) veo eest iga 20 ruudu kohta
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Lülita veoste graafik sisse/välja
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Insener
+STR_7067_TRAFFIC_MANAGER :Liiklusmänedžer
+STR_7068_TRANSPORT_COORDINATOR :Transpordi koordineerija
+STR_7069_ROUTE_SUPERVISOR :Marsruudi inspektor
+STR_706A_DIRECTOR :Direktor
+STR_706B_CHIEF_EXECUTIVE :Tegevjuht
+STR_706C_CHAIRMAN :Esimees
+STR_706D_PRESIDENT :President
+STR_706E_TYCOON :Magnaat
+STR_706F_BUILD_HQ :{BLACK}Ehita peakorter
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Ehita ettevõtte peakorter või vii vaade peakorterile
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Ehita ettevõtte peakorter mujale 1% ettevõtte väärtuse hinna eest
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Ettevõtte peakorterit ei saa ehitada...
+STR_7072_VIEW_HQ :{BLACK}Vaata peakorterit
+STR_RELOCATE_HQ :{BLACK}Liiguta peakorterit
+STR_COMPANY_PASSWORD :{BLACK}Salasõna
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Ettevõtte kaitsmine salasõnaga, et võõrad ei saaks ilma loata ühineda.
+STR_SET_COMPANY_PASSWORD :Vali ettevõttele salasõna
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}Majanduslik tagasilöök!{}{}Finantseksperdid ennustavad suurt majanduslangust!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Madalseis on läbi!{}{}Suurem kauplemine julgustab majanduse tugevnemisega ettevõtteid!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Lülita aken suureks/väikseks
+STR_7076_COMPANY_VALUE :{GOLD}Ettevõtte väärtus: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Osta 25% ettevõtte aktsiatest
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Müü 25% ettevõtte aktsiatest
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Osta 25% ettevõtte aktsiatest
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Müü 25% ettevõtte aktsiatest
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Selle ettevõtte aktsiatest ei saa 25% osta...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}Selle ettevõtte aktsiatest ei saa 25% müüa...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% on ettevõtte {COMPANY} käes)
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% on ettevõtte {COMPANY} käes{} {COMMA}% on ettevõtte {COMPANY} käes)
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} võeti üle ettevõtte {COMPANY} poolt!
+STR_7080_PROTECTED :{WHITE}See ettevõtte pole veel piisavalt vana, et aktsiaid vahetada...
+
+STR_LIVERY_DEFAULT :Tavaline Ãœleandmine
+STR_LIVERY_STEAM :Aurumootor
+STR_LIVERY_DIESEL :Diiselmootor
+STR_LIVERY_ELECTRIC :Elektrimootor
+STR_LIVERY_MONORAIL :Monorelsi Mootor
+STR_LIVERY_MAGLEV :Maglev'i Mootor
+STR_LIVERY_DMU :DMU
+STR_LIVERY_EMU :EMU
+STR_LIVERY_PASSENGER_WAGON_STEAM :Reisivagun (auru)
+STR_LIVERY_PASSENGER_WAGON_DIESEL :Reisivagun (diisel)
+STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Reisivagun (elektri)
+STR_LIVERY_FREIGHT_WAGON :Kaubavagun
+STR_LIVERY_BUS :Buss
+STR_LIVERY_TRUCK :Veoauto
+STR_LIVERY_PASSENGER_SHIP :Reisijate Praam
+STR_LIVERY_FREIGHT_SHIP :Kaubalaev
+STR_LIVERY_HELICOPTER :Helikopter
+STR_LIVERY_SMALL_PLANE :Väike Lennuk
+STR_LIVERY_LARGE_PLANE :Suur Lennuk
+
+STR_LIVERY_GENERAL_TIP :{BLACK}Näita üldist värviskeemi
+STR_LIVERY_TRAIN_TIP :{BLACK}Näita rongide värvistikke
+STR_LIVERY_ROADVEH_TIP :{BLACK}Näita maanteesõidukite värviskeeme
+STR_LIVERY_SHIP_TIP :{BLACK}Näita laeva värviskeeme
+STR_LIVERY_AIRCRAFT_TIP :{BLACK}Näita lennuki värviskeemi
+STR_LIVERY_PRIMARY_TIP :{BLACK}Vali põhivärv valitud skeemile
+STR_LIVERY_SECONDARY_TIP :{BLACK}Vali teine värv valitud skeemile
+STR_LIVERY_PANEL_TIP :{BLACK}Vali värviskeem mida muuta, või mitu tükki vajutades CTRL+Kõps. Vajuta kastil et valida värviskeemi kaustamise vahel.
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (auruvedur)
+STR_8001_MJS_250_DIESEL :MJS 250 (diisel)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphuti tšuhh-tšuhh
+STR_8003_POWERNAUT_CHOO_CHOO :Powernauti tšuhh-tšuhh
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymoveri tšuhh-tšuhh
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut diisel
+STR_8006_POWERNAUT_DIESEL :Powernaut diisel
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (auruvedur)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (auruvedur)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (auruvedur)
+STR_800A_SH_8P_STEAM :SH '8P' (auruvedur)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (diisel)
+STR_800C_DASH_DIESEL :'Dash' (diisel)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (diisel)
+STR_800E_UU_37_DIESEL :UU '37' (diisel)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (diisel)
+STR_8010_CS_4000_DIESEL :CS 4000 (diisel)
+STR_8011_CS_2400_DIESEL :CS 2400 (diisel)
+STR_8012_CENTENNIAL_DIESEL :Centennial (diisel)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (diisel)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (diisel)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (diisel)
+STR_8016_SH_125_DIESEL :SH '125' (diisel)
+STR_8017_SH_30_ELECTRIC :SH '30' (elektrivedur)
+STR_8018_SH_40_ELECTRIC :SH '40' (elektrivedur)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (elektrivedur)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (elektrivedur)
+STR_801B_PASSENGER_CAR :Reisivagun
+STR_801C_MAIL_VAN :Postivagun
+STR_801D_COAL_CAR :Kivisöevagun
+STR_801E_OIL_TANKER :Naftatanker
+STR_801F_LIVESTOCK_VAN :Loomavagun
+STR_8020_GOODS_VAN :Kaubavagun
+STR_8021_GRAIN_HOPPER :Teraviljavagun
+STR_8022_WOOD_TRUCK :Palgivagun
+STR_8023_IRON_ORE_HOPPER :Rauamaagivagun
+STR_8024_STEEL_TRUCK :Terasevagun
+STR_8025_ARMORED_VAN :Soomusvagun
+STR_8026_FOOD_VAN :Toiduvagun
+STR_8027_PAPER_TRUCK :Paberivagun
+STR_8028_COPPER_ORE_HOPPER :Vasemaagivagun
+STR_8029_WATER_TANKER :Veetanker
+STR_802A_FRUIT_TRUCK :Puuviljavagun
+STR_802B_RUBBER_TRUCK :Kummivagun
+STR_802C_SUGAR_TRUCK :Suhkruvagun
+STR_802D_COTTON_CANDY_HOPPER :Suhkruvativagun
+STR_802E_TOFFEE_HOPPER :Iirisevagun
+STR_802F_BUBBLE_VAN :Mullivagun
+STR_8030_COLA_TANKER :Koolavagun
+STR_8031_CANDY_VAN :Maiustuste vagun
+STR_8032_TOY_VAN :Mänguasjavagun
+STR_8033_BATTERY_TRUCK :Patareivagun
+STR_8034_FIZZY_DRINK_TRUCK :Kihisevate jookide vagun
+STR_8035_PLASTIC_TRUCK :Plastikuvagun
+STR_8036_X2001_ELECTRIC :'X2001' (elektri)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (elektri)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :Reisivagun
+STR_803A_MAIL_VAN :Postivagun
+STR_803B_COAL_CAR :Kivisöevagun
+STR_803C_OIL_TANKER :Naftatanker
+STR_803D_LIVESTOCK_VAN :Loomavagun
+STR_803E_GOODS_VAN :Kaubavagun
+STR_803F_GRAIN_HOPPER :Teraviljavagun
+STR_8040_WOOD_TRUCK :Palgivagun
+STR_8041_IRON_ORE_HOPPER :Rauamaagivagun
+STR_8042_STEEL_TRUCK :Terasevagun
+STR_8043_ARMORED_VAN :Soomusvagun
+STR_8044_FOOD_VAN :Toiduvagun
+STR_8045_PAPER_TRUCK :Paberivagun
+STR_8046_COPPER_ORE_HOPPER :Vasemaagivagun
+STR_8047_WATER_TANKER :Veetanker
+STR_8048_FRUIT_TRUCK :Puuviljavagun
+STR_8049_RUBBER_TRUCK :Kummivagun
+STR_804A_SUGAR_TRUCK :Suhkruvagun
+STR_804B_COTTON_CANDY_HOPPER :Suhkruvativagun
+STR_804C_TOFFEE_HOPPER :Iirisevagun
+STR_804D_BUBBLE_VAN :Mullivagun
+STR_804E_COLA_TANKER :Koolatanker
+STR_804F_CANDY_VAN :Maiustustevagun
+STR_8050_TOY_VAN :Mänguasjavagun
+STR_8051_BATTERY_TRUCK :Patareivagun
+STR_8052_FIZZY_DRINK_TRUCK :Kihisevate jookide vagun
+STR_8053_PLASTIC_TRUCK :Plastikuvagun
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (elektri)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (elektri)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (elektri)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (elektri)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :Reisivagun
+STR_805A_MAIL_VAN :Postivagun
+STR_805B_COAL_CAR :Kivisöevagun
+STR_805C_OIL_TANKER :Naftatanker
+STR_805D_LIVESTOCK_VAN :Loomavagun
+STR_805E_GOODS_VAN :Kaubavagun
+STR_805F_GRAIN_HOPPER :Teraviljavagun
+STR_8060_WOOD_TRUCK :Palgivagun
+STR_8061_IRON_ORE_HOPPER :Rauamaagivagun
+STR_8062_STEEL_TRUCK :Terasevagun
+STR_8063_ARMORED_VAN :Soomusvagun
+STR_8064_FOOD_VAN :Toiduvagun
+STR_8065_PAPER_TRUCK :Paberivagun
+STR_8066_COPPER_ORE_HOPPER :Vasemaagivagun
+STR_8067_WATER_TANKER :Veetanker
+STR_8068_FRUIT_TRUCK :Puuviljavagun
+STR_8069_RUBBER_TRUCK :Kummivagun
+STR_806A_SUGAR_TRUCK :Suhkruvagun
+STR_806B_COTTON_CANDY_HOPPER :Suhkruvativagun
+STR_806C_TOFFEE_HOPPER :Iirisevagun
+STR_806D_BUBBLE_VAN :Mullivagun
+STR_806E_COLA_TANKER :Koolatanker
+STR_806F_CANDY_VAN :Maiustustevagun
+STR_8070_TOY_VAN :Mänguasjavagun
+STR_8071_BATTERY_TRUCK :Patareivagun
+STR_8072_FIZZY_DRINK_TRUCK :Kihisevate jookide vagun
+STR_8073_PLASTIC_TRUCK :Plastikuvagun
+STR_8074_MPS_REGAL_BUS :Kuninglik MPS buss
+STR_8075_HEREFORD_LEOPARD_BUS :Hereford Leopard buss
+STR_8076_FOSTER_BUS :Foster buss
+STR_8077_FOSTER_MKII_SUPERBUS :Foster MkII superbuss
+STR_8078_PLODDYPHUT_MKI_BUS :Ploddyphut MkI buss
+STR_8079_PLODDYPHUT_MKII_BUS :Ploddyphut MkII buss
+STR_807A_PLODDYPHUT_MKIII_BUS :Ploddyphut MkIII buss
+STR_807B_BALOGH_COAL_TRUCK :Balogh kivisöeveok
+STR_807C_UHL_COAL_TRUCK :Uhl kivisõeveok
+STR_807D_DW_COAL_TRUCK :DW kivisõeveok
+STR_807E_MPS_MAIL_TRUCK :MPS postiauto
+STR_807F_REYNARD_MAIL_TRUCK :Reynard postiauto
+STR_8080_PERRY_MAIL_TRUCK :Perry postiauto
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :MightyMover postiauto
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Powernaught postiauto
+STR_8083_WIZZOWOW_MAIL_TRUCK :Wizzowow postiauto
+STR_8084_WITCOMBE_OIL_TANKER :Witcombe naftaveok
+STR_8085_FOSTER_OIL_TANKER :Foster naftaveok
+STR_8086_PERRY_OIL_TANKER :Perry naftaveok
+STR_8087_TALBOTT_LIVESTOCK_VAN :Talbott loomaveok
+STR_8088_UHL_LIVESTOCK_VAN :Uhl loomaveok
+STR_8089_FOSTER_LIVESTOCK_VAN :Foster loomaveok
+STR_808A_BALOGH_GOODS_TRUCK :Balogh kaubaveok
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Craighead kaubaveok
+STR_808C_GOSS_GOODS_TRUCK :Goss kaubaveok
+STR_808D_HEREFORD_GRAIN_TRUCK :Hereford viljaveok
+STR_808E_THOMAS_GRAIN_TRUCK :Thomas viljaveok
+STR_808F_GOSS_GRAIN_TRUCK :Goss viljaveok
+STR_8090_WITCOMBE_WOOD_TRUCK :Witcombe palgiveok
+STR_8091_FOSTER_WOOD_TRUCK :Foster palgiveok
+STR_8092_MORELAND_WOOD_TRUCK :Moreland palgiveok
+STR_8093_MPS_IRON_ORE_TRUCK :MPS rauamaagiveok
+STR_8094_UHL_IRON_ORE_TRUCK :Uhl rauamaagiveok
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Chippy rauamaagiveok
+STR_8096_BALOGH_STEEL_TRUCK :Balogh teraseveok
+STR_8097_UHL_STEEL_TRUCK :Uhl teraseveok
+STR_8098_KELLING_STEEL_TRUCK :Kelling teraseveok
+STR_8099_BALOGH_ARMORED_TRUCK :Balogh soomusauto
+STR_809A_UHL_ARMORED_TRUCK :Uhl soomusauto
+STR_809B_FOSTER_ARMORED_TRUCK :Foster soomusauto
+STR_809C_FOSTER_FOOD_VAN :Foster toiduveok
+STR_809D_PERRY_FOOD_VAN :Perry toiduveok
+STR_809E_CHIPPY_FOOD_VAN :Chippy toiduveok
+STR_809F_UHL_PAPER_TRUCK :Uhl paberiveok
+STR_80A0_BALOGH_PAPER_TRUCK :Balogh paberiveok
+STR_80A1_MPS_PAPER_TRUCK :MPS paberiveok
+STR_80A2_MPS_COPPER_ORE_TRUCK :MPS vasemaagiveok
+STR_80A3_UHL_COPPER_ORE_TRUCK :Uhl vasemaagiveok
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Goss vasemaagiveok
+STR_80A5_UHL_WATER_TANKER :Uhl veeveok
+STR_80A6_BALOGH_WATER_TANKER :Balogh veeveok
+STR_80A7_MPS_WATER_TANKER :MPS veeveok
+STR_80A8_BALOGH_FRUIT_TRUCK :Balogh veeveok
+STR_80A9_UHL_FRUIT_TRUCK :Uhl puuviljaveok
+STR_80AA_KELLING_FRUIT_TRUCK :Kelling puuviljaveok
+STR_80AB_BALOGH_RUBBER_TRUCK :Balogh kummiveok
+STR_80AC_UHL_RUBBER_TRUCK :Uhl kummiveok
+STR_80AD_RMT_RUBBER_TRUCK :RMT kummiveok
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :MightyMover suhkruveok
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Powernaught suhkruveok
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Wizzowow suhkruveok
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :MightyMover koolaveok
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Powernaught koolaveok
+STR_80B3_WIZZOWOW_COLA_TRUCK :Wizzowow koolaveok
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :MightyMover suhkruvativeok
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Powernaught suhkruvativeok
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Wizzowow suhkruvativeok
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :MightyMover iiriseveok
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Powernaught iiriseveok
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Wizzowow iiriseveok
+STR_80BA_MIGHTYMOVER_TOY_VAN :MightyMover mänguasjaveok
+STR_80BB_POWERNAUGHT_TOY_VAN :Powernaught mänguasjaveok
+STR_80BC_WIZZOWOW_TOY_VAN :Wizzowow mänguasjaveok
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :MightyMover maiustusteveok
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Powernaught maiustusteveok
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Wizzowow maiustusteveok
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :MightyMover patareiveok
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Powernaught patareiveok
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Wizzowow patareiveok
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :MightyMover limonaadiveok
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Powernaught limonaadiveok
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Wizzowow limonaadiveok
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :MightyMover plastikuveok
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Powernaught plastikuveok
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Wizzowow plastikuveok
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :MightyMover mulliveok
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Powernaught mulliveok
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Wizzowow mulliveok
+STR_80CC_MPS_OIL_TANKER :MPS naftatanker
+STR_80CD_CS_INC_OIL_TANKER :CS-Inc. naftatanker
+STR_80CE_MPS_PASSENGER_FERRY :MPS reisipraam
+STR_80CF_FFP_PASSENGER_FERRY :FFP reisipraam
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Bakewell 300 hõljuklaev
+STR_80D1_CHUGGER_CHUG_PASSENGER :Chugger-Chug reisipraam
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Shivershake reisipraam
+STR_80D3_YATE_CARGO_SHIP :Yate kaubalaev
+STR_80D4_BAKEWELL_CARGO_SHIP :Bakewell kaubalaev
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Mightymover kaubalaev
+STR_80D6_POWERNAUT_CARGO_SHIP :Powernaut Kaubalaev
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Tricario Helicopter
+STR_80FE_GURU_X2_HELICOPTER :Guru X2 Helicopter
+STR_80FF_POWERNAUT_HELICOPTER :Powernaut Helicopter
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Teade sõidukite tootjalt
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}Me oleme just kujundanud uue {STRING} - kas te tahaksite testida aasta aega enne kui see on saadaval kõigile?
+STR_8102_RAILROAD_LOCOMOTIVE :raudtee vedur
+STR_8103_ROAD_VEHICLE :tee sõiduk
+STR_8104_AIRCRAFT :lennuk
+STR_8105_SHIP :laev
+STR_8106_MONORAIL_LOCOMOTIVE :monorelsi vedur
+STR_8107_MAGLEV_LOCOMOTIVE :maglevi vedur
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}{TOWN} Rongi Depoo
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Rahvas rõõmustab. . .{}{STATION} jaama saabus esimene rong!
+STR_8802_DETAILS :{WHITE}{STRING} (Detailid)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Rong on ees
+STR_8804 :{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8806_GO_TO :Mine {STATION}
+STR_8807_GO_TO_TRANSFER :Mine {STATION} (Vea ja võta laadung)
+STR_8808_GO_TO_UNLOAD :Mine {STATION} (Laadi maha)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Mine {STATION} (Vea ja jäta tühjaks)
+STR_880A_GO_TO_LOAD :Mine {STATION} (Laadi)
+STR_880B_GO_TO_TRANSFER_LOAD :Mine {STATION} (Vea ja oota täislaadingut)
+STR_880C_GO_NON_STOP_TO :Sõida läbi {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Sõida läbi {STATION} (Vea ja oota täislaadingut)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Sõida läbi {STATION} (Laadi maha)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Sõida läbi {STATION} (Vea ja jäta tühjaks)
+STR_8810_GO_NON_STOP_TO_LOAD :Sõida läbi {STATION} (laadi)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Sõida läbi {STATION} (Vea ja oota täislaadingut)
+STR_GO_TO_TRAIN_DEPOT :Mine linna {TOWN} rongidepoosse
+STR_SERVICE_AT_TRAIN_DEPOT :Hooldus linna {TOWN} rongidepoos
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Sõida läbi linna {TOWN} rongidepoo
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Hooldus Läbisõidul läbi linna {TOWN} rongidepoo
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}Suundub linna {TOWN} rongidepoosse
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}Suundub linna {TOWN} rongidepoosse, {VELOCITY}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE :{LTBLUE}Parandus{TOWN} Rongijaamas
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE_VEL :{LTBLUE}Parandus {TOWN} Rongijaamas, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (Ebasobiv järjekord)
+
+STR_UNKNOWN_DESTINATION :tundmatu sihtpunkt
+STR_8812_EMPTY :{LTBLUE}Tühi
+STR_8813_FROM :{LTBLUE}{CARGO} {STATION}'st
+STR_FROM_MULT :{LTBLUE}{CARGO} jaamast {STATION} (x{NUM})
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}Rong {COMMA} ootab depoos
+STR_8815_NEW_VEHICLES :{BLACK}Uus sõiduk
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Rong on liiga pikk
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Ronge saab ainult siis muuta kui nad on peatatud depoo sees
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} Rong{P "" id}
+
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Uus Raudtee Sõiduk
+STR_NEW_ELRAIL_VEHICLES :{WHITE}Uued Elektrilised Raudtee sõidukid
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Uus Monorelssi Sõiduk
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Uus Maglevi Sõiduk
+STR_ALL_AVAIL_RAIL_VEHICLES :{WHITE}Raudteesõidukid
+
+STR_881F_BUILD_VEHICLE :{BLACK}Ehita sõiduk
+STR_CLONE_ROAD_VEHICLE :{BLACK}Klooni sõiduk
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}See ehitab koopia maanteesõidukist. CTRL-klikk jagab sihtpunkte
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}See ehitab koopia maanteesõidukist. Vajuta sellele nuppule, ning seejärel maanteesõidukile depoo sees või väljas. CTRL-klikk jagab sihtpunkte
+STR_CLONE_TRAIN :{BLACK}Klooni rong
+STR_CLONE_TRAIN_INFO :{BLACK}See ehitab koopia rongist koos kõikide vagunitega. CTRL-klikk jagab sihtpunkte
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}See ehitab koopia rongist koos kõikide vagunitega. Vajuta sellele nuppule, ning seejärel rongile depoo sees või väljas. CTRL-klikk jagab sihtpunkte
+STR_8820_RENAME :{BLACK}Muuda nime
+STR_8823_SKIP :{BLACK}Jäta vahele
+STR_8824_DELETE :{BLACK}Kustuta
+STR_8825_NON_STOP :{BLACK}Peatuseta
+STR_8826_GO_TO :{BLACK}Mine
+STR_8827_FULL_LOAD :{BLACK}Laadi täis
+STR_8828_UNLOAD :{BLACK}Laadi maha
+STR_REFIT :{BLACK}Taasseadista
+STR_REFIT_TIP :{BLACK}Vali, millist laadungit ümber seadistada selles järjestuses. Ümberseadistuse käsu eemaldamiseks hoia klõpsamise ajal all Control nuppu
+STR_REFIT_ORDER :(Taasseadista {STRING})
+STR_8829_ORDERS :{WHITE}{VEHICLE} (Käsud)
+STR_882A_END_OF_ORDERS :{SETX 10}- - Käskude Lõpp - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}Hooldus
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Ei saa ehitada raudteesõidukit...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Ehitatud: {LTBLUE}{NUM}{BLACK} Väärtus: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Väärtus: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}Laadin / Laadin maha
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}Rong peab olema depoos peatatud
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Ei saa saata rongi depoosse...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Pole ruumi käskudeks
+STR_8832_TOO_MANY_ORDERS :{WHITE}Liiga palju käske
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Ei saa lisada uut käsku...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Ei saa kustutada seda käsku...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Ei saa muuta seda käsku...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Ei saa liigutada sõidukit...
+STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}Tagumine vedur järgneb alati eesmisele
+STR_8838_N_A :N/A{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Ei saa müüa raudteesõidukit...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Ei leia teed kohalikku depoosse
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Ei saa peatada/startida rongi...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Teeninduse ajavahemik: {LTBLUE}{COMMA}Päeva{BLACK} Viimane teenindus: {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Teeninduse ajavahemik: {LTBLUE}{COMMA}%{BLACK} Viimane teenindus: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Rongid - vajuta rongile info jaoks
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Ehita uued rongid (vajab rongidepood)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Rongid -vajuta rongile info jaoks, tiri sõidukit, et lisada/võtta rongilt
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Osta uus rongi veok
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Tiri rongi veok siia et müüa
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Keskenda põhivaade rongidepoo kohale
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Rongivagunite nimekiri - vajuta sõidukile info jaoks
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Ehita valitud rongi sõiduk
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Muuda rongisõiduki tüübi nime
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Praegune rongi tegevus - vajuta siia et peatada/käivitada rong
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Näita rongi käske
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Vaate viimine rongi asukohale
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Saada rong depoosse
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Sunni rongi minema edasi signaali ootamata
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Pööra rong ümber
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Näita rongi detaile
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Suurenda teeninduse ajavahemikku
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Vähenda teeninduse ajavahemikku
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Näita detaile viidud kauba kohta
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Näita detaile rongi sõidukite kohta
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Näita iga sõiduki mahtu.
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Näita kogu rongi mahtu, jagatud kauba tüübi järgi
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Sihtpunktide nimekiri - vajuta käsul et see valida. CTRL + klik kerib jaama juurde
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}Jäta praegune käsk vahele ja mine järgmise käsu juurde.
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Kustuta valitud käsk
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Märgi valitud käsk ilma peatusetta peatuseks
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Lisa uus käsk enne valitud käsku või nimekirja lõppu
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Sunni valitud käsu juures oodata täis laadingut
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Sunni valitud käsu juures maha laadida.
+STR_SERVICE_HINT :{BLACK}Jäta see käsk vahele, kui just pole vaja teenindust
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}Uus {STRING} on nüüd olemas!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Maksumus: {CURRENCY} Mass: {WEIGHT_S}{}Kiirus: {VELOCITY} Võimsus: {POWER}{}Kulu: {CURRENCY}/aastas{}Mahutus: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}Lagunes
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}Vanus: {LTBLUE}{STRING}{BLACK} Kulud: {LTBLUE}{CURRENCY}/aastas
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Mass: {LTBLUE}{WEIGHT_S} {BLACK}Võimsus: {LTBLUE}{POWER}{BLACK} Suurim kiirus: {LTBLUE}{VELOCITY}
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Mass: {LTBLUE}{WEIGHT_S} {BLACK}Võimsus: {LTBLUE}{POWER}{BLACK} Max. speed: {LTBLUE}{VELOCITY} {BLACK}Suurim veojõud: {LTBLUE}{FORCE}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Selle aasta kasum: {LTBLUE}{CURRENCY} (eelmisel aastal: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}Töökindlus: {LTBLUE}{COMMA}% {BLACK}Lagunemisi alates eelmisest hoolduskorrast: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Peatatud
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Ohu korral ei ole võimalik sundida rongi signaali vahele jätma
+STR_8863_CRASHED :{RED}Kokkupõrge!
+
+STR_8865_NAME_TRAIN :{WHITE}Anna rongile nimi
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}Ei saa nimetada rongi...
+STR_8867_NAME_TRAIN :{BLACK}Rongi nimi
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}RONGIKOKKUPÕRGE!{}{COMMA} surid tules peale kokkusõitmist
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Ei saa rongi ümber pöörata.
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Muuda rongisõiduki tüübi nime
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Ei saa nimetada ümber rongisõiduki tüüpi...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Sunni valitud käsul visata maha laadung
+STR_886F_TRANSFER :{BLACK}Transpordi
+
+STR_TRAIN_STOPPING :{RED}Peatub
+STR_TRAIN_STOPPING_VEL :{RED}Peatub, {VELOCITY}
+STR_INCOMPATIBLE_RAIL_TYPES :Ühildamatud raudtee tüübid
+STR_TRAIN_NO_POWER :{RED}Vool puudub
+STR_TRAIN_START_NO_CATENARY :Selle raja ahel puudub, rong ei saa sõitu alustada
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Maanteesõiduk on ees
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} Maanteesõiduk{P "" s}
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}Linna {TOWN} maanteesõidukite depoo
+STR_9004_NEW_VEHICLES :{BLACK}Uued sõidukid
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}Uued maanteesõidukid
+STR_9007_BUILD_VEHICLE :{BLACK}Ehita sõidukeid
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Ei saa ehitada maanteesõidukit...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (Detailid)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}Vanus: {LTBLUE}{STRING}{BLACK} Hoolduskulud: {LTBLUE}{CURRENCY}/aastas
+STR_900E_MAX_SPEED :{BLACK}Maksimaalne kiirus: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Selle aasta kasum: {LTBLUE}{CURRENCY} (viimasel aastal: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}Töökindlus: {LTBLUE}{COMMA}% {BLACK}Lagunemisi alates viimasest hooldusest: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Ehitatud: {LTBLUE}{NUM}{BLACK} Väärtus: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Mahutavus: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}...peab garaaþis olema
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Ei saa veokit müüa...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Ei saa veokit peatada, ega startida...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}Veok {COMMA} ootab garaaþi
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}Suundub {TOWN} garaaþi
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}Suundub {TOWN} garaaþi, {VELOCITY}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE :{LTBLUE}Parandus{TOWN} Depoos
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE_VEL :{LTBLUE}Parandus{TOWN} Depoos, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Ei saa veokit garaaþi saata
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Ei leia kohalikku garaaþi üles
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Veokid - info saamiseks vajuta veokile
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Osta uus veok (vajab garaaþi)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Praegune sõiduki tegevus - vajuta siia et peatada või käivitada sõiduk
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Näita sõiduki käske
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Vii vaade sõiduki asukohale
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Saada sõiduk garaaþi
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Sunni sõidukit ümber pöörama
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Näita sõiduki detaile
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Sõidukid - info saamiseks vajuta sõidukile
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Ehita uus maanteesõiduk
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Müümiseks tiri sõiduk siia
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Vii vaade garaaþi asukohale
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Maanteesõidukite nimekiri - info saamiseks vajuta sõidukile
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Ehita valitud maanteesõiduk
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}Uus maanteesõiduk on nüüdsest olemas!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Hind: {CURRENCY}{}Kiirus: {VELOCITY}{}Hoolduskulud: {CURRENCY}/aastas{}Mahutavus: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Nimeta maanteeveok ümber
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Ei saa maanteveokit ümber nimetada...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Nimeta maanteeveok ümber
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Rahvas rõõmustab . . .{}{STATION} jaama saabus esimene buss!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Rahvas rõõmustab . . .{}{STATION} jaama saabus esimene maanteesõiduk!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}Rongikokkupõrge!{}Juht suri peale õnnetust tules
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}Maanteesõiduki kokkupõrge rongiga!{}{COMMA} suri tules peale kokkupõrget rongiga
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Maanteesõidukit ei saa ringi pöörata...
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}Sa ei saa pöörata sõidukeid millel on mitu üksust
+STR_9034_RENAME :{BLACK}Muuda nime
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Nimeta maanteesõiduki tüüp ümber
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Nimeta maanteesõiduki tüüp ümber
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Ei saa nimetada ümber maanteesõiduki tüüpi...
+STR_9038_GO_TO_ROADVEH_DEPOT :Mine linna {TOWN} garaaþi
+STR_SERVICE_AT_ROADVEH_DEPOT :Hoolda {TOWN} Garaaþis
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Seadista maanteesõidukit kandma teist tüüpi laadungit
+STR_REFIT_ROAD_VEHICLE :{BLACK}Muuda maanteesõiduki seadistust
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Seadista maanteesõiduk kandma valitud laadungitüüpi
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Maanteesõiduki seadistust ei saa ümber muuta
+STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Vali, millist tüüpi laadungit sõiduk veab
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Sadama ehitus
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Sadama ehitus
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Siia ei saa sadamat ehitada
+STR_9803_SHIP_DEPOT :{WHITE}{TOWN} Paadikuur
+STR_9804_NEW_SHIPS :{BLACK}Uus laev
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} Laev{P "" s}
+STR_9808_NEW_SHIPS :{WHITE}Uued laevad
+STR_9809_BUILD_SHIP :{BLACK}Ehita laev
+STR_CLONE_SHIP :{BLACK}Klooni laev
+STR_CLONE_SHIP_INFO :{BLACK}See ehitab koopia laevast. CTRL-klikk jagab sihtpunkte
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}See ehitab koopia laevast. Vajuta sellele nuppule, ning seejärel laevale paadikuuri sees või väljas. CTRL-klikk jagab sihtpunkte
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}Laev peab olema peatatud paadikuuris
+STR_980C_CAN_T_SELL_SHIP :{WHITE}Ei saa laeva müüa
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Ei saa laeva ehitada...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Laev on ees
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Detailid)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}Vanus: {LTBLUE}{STRING}{BLACK} Hoolduskulud: {LTBLUE}{CURRENCY}/aastas
+STR_9813_MAX_SPEED :{BLACK}Maks. kiirus: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Selle aasta kasum: {LTBLUE}{CURRENCY} (viimasel: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}Töökindlus: {LTBLUE}{COMMA}% {BLACK}Lagunemisi alates viimasest hooldusest: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Ehitati: {LTBLUE}{NUM}{BLACK} Väärtus: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}Mahutavus: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}Ei saa peatada/käivitada laeva...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Ei saa laeva paadikuuri saata...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Ei leia kohalikku paadikuuri
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}Suundub {TOWN}a paadikuuri
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}Suundub {TOWN}a paadikuuri, {VELOCITY}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE :{LTBLUE}Parandus{TOWN} Sadamas
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE_VEL :{LTBLUE}Parandus{TOWN} Sadamas, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}Laev {COMMA} ootab paadikuuris
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Ehita laevakuur
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Ehita laevakuur (laevade ehitamiseks ja hoolduseks)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Laevad - info saamiseks vajuta laevale
+STR_9820_BUILD_NEW_SHIP :{BLACK}Ehita uus laev
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Müügiks tiri laev siia
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Vii pea vaade paadikuuri juurde
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Laevad - info saamiseks vajuta laevale
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Ehita uus laev (vajad paadikuuri)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}Laevade nimekiri - info saamiseks vajuta laevale
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Ehita valitud laev
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Praegune laeva tegevus - vajuta siia, et peatada/käivitada laeva
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Näita laeva sihtpunkte
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Vii vaade laeva asukohale
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Saada laev paadikuuri
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Näita laeva detaile
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}Uus laev on nüüdsest saadaval!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Hind: {CURRENCY} Maks. Kiirus: {VELOCITY}{}Mahutavus: {CARGO}{}Hoolduskulud: {CURRENCY}/aasta
+STR_982F_NAME_SHIP :{BLACK}Anna laevale nimi
+
+STR_9831_NAME_SHIP :{WHITE}Anna laevale nimi
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Ei saa laeva ümber nimetada...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Rahvas rõõmustab . . .{}{STATION} sadamasse saabus esimene laev!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Aseta teemärgisena kasutatav poi
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Poid ei saa siia asetada...
+STR_9836_RENAME :{BLACK}Muuda nime
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Nimeta laeva tüüp ümber
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Nimeta laeva tüüp ümber
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Ei saa laeva tüüpi ümber nimetada...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Seadista laev ümber teise kaubatüübi jaoks
+STR_983B_REFIT :{WHITE}{VEHICLE} (Seadista ümber)
+STR_983C_REFIT_SHIP :{BLACK}Seadista laev ümber
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Vali kauba tüüp, mida laev hakkab kandma
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Seadista laev ümber valitud kaubatüübi jaoks
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Vali kaubatüüp, mida vedada:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Uus mahutavus: {GOLD}{CARGO}{}{BLACK}Laeva ümberseadistamise hind: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Ei saa laeva ümber seadistada...
+STR_9842_REFITTABLE :(ümberseadistatav)
+STR_GO_TO_SHIP_DEPOT :Mine {TOWN} paadikuuri
+SERVICE_AT_SHIP_DEPOT :Hooldus {TOWN} paadikuuris
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Lennujaamad
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Ei saa lennujaama siia ehitada...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} Lennujaama angaar
+STR_A003_NEW_AIRCRAFT :{BLACK}Uus lennuk
+STR_CLONE_AIRCRAFT :{BLACK}Klooni lennuk
+STR_CLONE_AIRCRAFT_INFO :{BLACK}See ehitab lennukist koopia. CTRL-klikk jagab sihtpunkte
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}See ehitab lennukist koopia. Vajuta sellele nuppule, ning seejärel lennukile angaari sees või väljas. CTRL-klikk jagab sihtpunkte
+STR_A005_NEW_AIRCRAFT :{WHITE}Uus lennuk
+STR_A006_BUILD_AIRCRAFT :{BLACK}Ehita lennuk
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Ei saa ehitada lennukit...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} Lennuk
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (sihtpunktid)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (Detailid)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Vanus: {LTBLUE}{STRING}{BLACK} Hoolduskulud: {LTBLUE}{CURRENCY}/aastas
+STR_A00E_MAX_SPEED :{BLACK}Maks. kiirus: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Selle aasta kasum: {LTBLUE}{CURRENCY} (eelmisel aastal: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}Töökindlus: {LTBLUE}{COMMA}% {BLACK}Lagunemisi alates viimasest hooldusest: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Ehitusaasta: {LTBLUE}{NUM}{BLACK} Väärtus: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Ei saa lennukit angaari saata...
+STR_HEADING_FOR_HANGAR :{ORANGE}Suundub {STATION} Angaari
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}Suundub {STATION} angaari, {VELOCITY}
+STR_HEADING_FOR_HANGAR_SERVICE :{LTBLUE} Parandus{STATION} Angaaris
+STR_HEADING_FOR_HANGAR_SERVICE_VEL :{LTBLUE}Parandus{STATION} Angaaris, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}Lennuk {COMMA} ootab angaaris
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Lennuk on teel
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Ei saa lennukit peatada/käivitada...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Lennuk on õhus
+STR_A019_CAPACITY :{BLACK}Mahutavus: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Mahutavus: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}Lennuk peab olema peatatud angaari sees
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Ei saa lennukit müüa...
+STR_A01D_AIRPORT_CONSTRUCTION :Lennujaama ehitus
+STR_A01E_BUILD_AIRPORT :{BLACK}Ehita lennujaam
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Lennuk - info saamiseks vajuta lennukile
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Ehita uus lennuk (vajab angaariga lennujaama)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Lennuk - info saamiseks vajuta lennukile
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Ehita uus lennuk
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}Müümiseks tiri lennuk siia
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Vii vaade angaarile
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Lennuki valikute nimekiri - info saamiseks vajuta lennukile
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Ehita valitud lennuk
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Praegune lennuki tegevus - vajuta siia et käivitada või peatada lennukit
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Näita lennuki sihtpunke
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Vii peavaade lennukile
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Saada lennuk angaari
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Näita lennuki detaile
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}Uus lennuk on saadaval!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Hind: {CURRENCY} Maks. kiirus: {VELOCITY}{}Mahutavus: {COMMA} reisijat, {COMMA} kotti kirju{}Hoolduskulud: {CURRENCY}/aastas
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Anna lennukile nimi
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Ei saa lennukile nime anda
+STR_A032_NAME_AIRCRAFT :{BLACK}Nimeta lennuk ümber
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Rahvas rõõmustab . . .{}{STATION} lennujaama saabus esimene lennuk!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Lennuõnnetus!{}{COMMA} surid tules {STATION}s
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Lennuõnnetus!{}Lennukil lõppes kütus, {COMMA} surid tules!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Muuda nime
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Nimeta lennuki tüüp ümber
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Nimeta lennuki tüüp ümber
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Ei saa lennuki tüüpi ümber nimetada...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Seadista lennuk teistsuguse kauba kandmiseks ümber
+STR_A03C_REFIT :{WHITE}{VEHICLE} (Seadista ümber)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Seadista lennuk ümber
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Vali kauba tüüp, mida lennuk hakkab kandma
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Seadista lennuk ümber, et kanda valitud kaubatüüpi
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Vali kaubatüüp, mida kanda:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Uus mahutavus: {GOLD}{STRING}{}{BLACK}Ãœmber seadistamise maksumus: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Ei saa lennukit ümber seadistada...
+STR_GO_TO_AIRPORT_HANGAR :Mine {STATION} Angaari
+SERVICE_AT_AIRPORT_HANGAR :Hooldus {STATION} angaaris
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}Tsepeliini õnnetus {STATION}s!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Maanteesõiduk plahvatas kokkupõrke 'UFO'ga!
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}Naftapuhastusjaama plahvatus {TOWN} lähedal!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}Tehas purunes teadmata põhjustel {TOWN} lähedal!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}'UFO' maandus {TOWN} lähedal!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}Söekaevanduse vajumine jättis purustused {TOWN} lähedal!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Üleujutused!{}Vähemalt {COMMA} kadunut arvatakse surnuks peale olulist üleujutust!
+
+STR_BRIBE_FAILED :{WHITE}Sinu altkäemaksu proov on
+STR_BRIBE_FAILED_2 :{WHITE}kohalike uurijate poolt avastatud
+STR_BUILD_DATE :{BLACK}Ehitatud: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Detailne tegevuse reiting
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}Detailne
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Sõidukeid:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Jaamu:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Vähim kasum:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Vähim sissetulek:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Maks. sissetulek:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Transporditud:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Kaupu:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Raha:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Laen:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Kokku:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Sõidukite arv; see sisaldab maanteesõidukeid, ronhe, laevu ja lennukeid
+STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}Jaamade osade arv. Iga osa jaamast (nt. rongijaam, bussipeatus, lennujaam) loetakse eraldi, isegi kui naad on ühendatud üheks jaamaks
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}Kasum sõidukil, millel on kõige väiksem sissetulek (ainult 2 aastat või vanemad sõidukid)
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Väikseim kuukasum viimase 12 kvartali jooksul
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Suurim kuukasum viimase 12 kvartali jooksul
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}Kauba arv, mis on veatud viimase 4 kvartali jooksul
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}Kauba arv, mis on veatud viimasel kvartalil
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Raha arv, mis on sellel firmal pangas
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}Raha arv, mida see firma on võtnud laenuks
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Kokku punkte võimalikest punktidest
+
+STR_NEWGRF_SETTINGS_BUTTON :{BLACK}NewGRF seaded
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}Uue graafika sätted
+STR_NEWGRF_APPLY_CHANGES :{BLACK}Kinnita sätted
+STR_NEWGRF_SET_PARAMETERS :{BLACK}Vali parameetrid
+STR_NEWGRF_TIP :{BLACK}Nimekiri kõikidest uue graafika sätted mida oled installeerinud. Vajuta komplektile et vahetada sätteid
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}Sa ei ole installeerinud ühtegi uue graafika komplekti! Vaata õpetust et vaadata juhendit uue graafika installeerimisek
+STR_NEWGRF_FILENAME :{BLACK}Faili nimi: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
+STR_NEWGRF_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING}
+STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}Sa oled tegemas muudatusi töötavasse mängu; see võib OpenTTD kokku jooksutada.{}Kas sa oled täielikult veendunud selles?
+
+STR_NEWGRF_ADD :{BLACK}Lisa
+STR_NEWGRF_ADD_TIP :{BLACK}Lisa nimekirja NewGRF fail
+STR_NEWGRF_REMOVE :{BLACK}Eemalda
+STR_NEWGRF_REMOVE_TIP :{BLACK}Eemalda nimekirjast valitud NewGRF fail
+STR_NEWGRF_MOVEUP :{BLACK}Liiguta Ãœles
+STR_NEWGRF_MOVEUP_TIP :{BLACK}Liiguta valitud NewGRF fail nimekirjas üles
+STR_NEWGRF_MOVEDOWN :{BLACK}Liiguta Alla
+STR_NEWGRF_MOVEDOWN_TIP :{BLACK}Liiguta valitud NewGRF fail nimekirjas alla
+STR_NEWGRF_FILE_TIP :{BLACK}Nimekiri installeerimata NewGRF failidest. Parameetrite muutmiseks klõpsa failil.
+STR_NEWGRF_PARAMETER :{BLACK}Parameetrid: {SILVER}{STRING}
+STR_NEWGRF_PARAMETER_QUERY :{BLACK}Sisesta NewGRF parameetrid
+STR_NEWGRF_NO_INFO :{BLACK}Informatsioon puudub
+
+STR_NEWGRF_ADD_CAPTION :{WHITE}Olemasolevad NewGRF failid
+STR_NEWGRF_ADD_FILE :{BLACK}Lisa valikule
+STR_NEWGRF_ADD_FILE_TIP :{BLACK}Lisa valitud NewGRF fail enda seadistusse
+STR_NEWGRF_RESCAN_FILES :{BLACK}Skanni failid uuesti
+STR_NEWGRF_RESCAN_FILES_TIP :{BLACK}Uuenda saadaval olevate NewGRF failide nimekirja
+STR_NEWGRF_DUPLICATE_GRFID :{WHITE}Ei saa faili lisada: korduv GRF ID
+
+STR_NEWGRF_NOT_FOUND :{RED}Sobivat faili ei leitud
+STR_NEWGRF_DISABLED :{RED}Väljas
+
+STR_CURRENCY_WINDOW :{WHITE}Personaalne valuuta
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Vahetuskurss: {ORANGE}{CURRENCY} = £ {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Vahe märk:
+STR_CURRENCY_PREFIX :{LTBLUE}Eesliide:
+STR_CURRENCY_SUFFIX :{LTBLUE}Lõppuliide:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Vaheta üle eurole: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Vaheta üle eurole: {ORANGE}Kunagi
+STR_CURRENCY_PREVIEW :{LTBLUE}Eelvaade: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Muuda personaalse valuuta parameetreid
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} Rong{P "" i}
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} maanteesõiduk{P "" it}
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} Lennuk{P "" it}
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} Laev{P "" a}
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Näita kõiki ronge millel on see jaam nende sõiduplaanis
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Näita kõiki maanteesõidukeid millel on see jaam nende sõiduplaanis
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Näita kõiki lennukeid, millel see jaam on sõiduplaanis
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Näita kõiki laevu millel see jaam on sõiduplaanis
+
+STR_VEH_WITH_SHARED_ORDERS_LIST :{WHITE}Jagatud sõiduplaan{COMMA} Auto{P "" d}
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}Näita kõiki sama sõidukavaga sõidukeid
+
+### depot strings
+STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Sa oled müümas kõiki depoos asuvaid masinaid. Kas sa oled kindel?
+
+STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP :{BLACK}Müü kõik rongid jaamast
+STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP :{BLACK}Müü kõik autod garaažist
+STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP :{BLACK}Müü kõik laevad sadamast
+STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP :{BLACK}Müü kõik lennukid angaarist
+
+STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP :{BLACK}Võta nimekiri kõikidest rongidest selles jaamas nende käskude järgi
+STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP :{BLACK}Võta nimekiri kõikidest autodest selles garaažis nende käskude järgi
+STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP :{BLACK}Võta nimekiri kõikidest laevadest selles sadamas nende käskude järgi
+STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP :{BLACK}Võta nimekiri kõikidest lennukitest suvalistest angaaridest selles lennujaamas nende käskude järgi
+
+STR_DEPOT_AUTOREPLACE_TRAIN_TIP :{BLACK}Asenda automaatselt kõik rongid jaamas
+STR_DEPOT_AUTOREPLACE_ROADVEH_TIP :{BLACK}Asenda automaatselt kõik sõidukid garaažis
+STR_DEPOT_AUTOREPLACE_SHIP_TIP :{BLACK}Asenda automaatselt kõik laevad sadamas
+STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP :{BLACK}Asenda automaatselt kõik lennumasinad angaaris
+
+STR_VEHICLE_LIST_TRAIN_DEPOT :{BLACK}{STRING} - {COMMA} Rong{P "" id}
+STR_VEHICLE_LIST_ROADVEH_DEPOT :{BLACK}{STRING} - {COMMA} Auto{P "" d}
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} Laev{P "" ad}
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} Lennumasin
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}Asenda {STRING}
+STR_REPLACE_VEHICLES_START :{BLACK}Alusa sõidukite asendamist
+STR_REPLACE_VEHICLES_STOP :{BLACK}Lõppeta sõidukite asendamist
+STR_NOT_REPLACING :{BLACK}Ei asenda praegu
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Pole valitud sõidukit
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Vali asendatav veduritüüp
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Vali uus vedur, millega sa soovid vasakult valitud vedurit välja vahetada.
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Vajuta lõpetamaks vasakult valitud veduri väljavahetust
+STR_REPLACE_HELP_START_BUTTON :{BLACK}Vajuta vasakul asuva veduri väljavahetust paremal valitud veduriga
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Vali raudteetüüp millel olevaid vedureid sa soovid vahetada
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Näitab mis veduriga soovitakse vasakult valitud vedurit vahetada, kui üldse
+STR_REPLACE_HELP :{BLACK}See lubab sul vahetada ühe veduritüübi teisega, kui esimest tüüpi rongid sisenevad depoosse
+STR_REPLACE_REMOVE_WAGON :{BLACK}Vagunite eemaldus: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Sunni automaatvahetus hoidma rongi pikkust samaks eemaldades vaguneid (alustades eestpoolt), kui vahetatav mootor muudaks rongi pikemaks.
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}Vahetamisel: {ORANGE}{SKIP}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} TESTIMISEL! {}Vaheta aken mootori ja vaguni vahetamise aknate vahel.{}Vaguni vahetus tehakse ainult siis kui uus vagun suudetakse muuta kandmaks sama tüüpi kaupa kui vana vagun. See valitakse igale vagunile kui tegelik vahetus käib
+STR_ENGINE_NOT_BUILDABLE :{WHITE}Vedurit ei saa ehitada
+
+STR_ENGINES :Vedurid
+STR_WAGONS :Vaguneid
+
+STR_MASS_STOP_DEPOT_TRAIN_TIP :{BLACK}Vajuta, kui tahad seisata kõiki ronge jaamas
+STR_MASS_STOP_DEPOT_ROADVEH_TIP :{BLACK}Vajuta, kui tahad seisata kõiki masinaid garaažis
+STR_MASS_STOP_DEPOT_SHIP_TIP :{BLACK}Klõpsa, et peatada kõik sadamas olevad laevad.
+STR_MASS_STOP_HANGAR_TIP :{BLACK}Vajuta, kui tahad seisata kõiki lennukeid angaaris
+
+STR_MASS_START_DEPOT_TRAIN_TIP :{BLACK}Klõpsa kõikide depoos asuvate rongide käivitamiseks
+STR_MASS_START_DEPOT_ROADVEH_TIP :{BLACK}Vajuta, et käivitada kõik sõidukid garaazis
+STR_MASS_START_DEPOT_SHIP_TIP :{BLACK}Klõpsa kõikide angaaris asuvate laevade käivitamiseks
+STR_MASS_START_HANGAR_TIP :{BLACK}Klõpsa kõikide angaaris asuvate lennukite käivitamiseks
+
+STR_MASS_STOP_LIST_TIP :{BLACK}Klõpsa, et kõik nimekirjas olevad masinad peatada
+STR_MASS_START_LIST_TIP :{BLACK}Vajuta, kui tahad käivitada kõiki masinaid nimekirjas
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}Siltide nimekiri - {COMMA} Silt{P "" i}
+
+STR_ORDER_REFIT_FAILED :{WHITE}Tellimuse ümberseadistus peatas {STRING} {COMMA}
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :Raudteesõidukid
+STR_ELRAIL_VEHICLES :Elektrirongid
+STR_MONORAIL_VEHICLES :Monorelsi sõidukid
+STR_MAGLEV_VEHICLES :Maglevi Sõidukid
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Maksuvus: {GOLD}{CURRENCY}{BLACK} Kaal: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Kiirus: {GOLD}{VELOCITY}{BLACK} Võimsus: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}Kiirus: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Hoolduskulud: {GOLD}{CURRENCY}/aasta
+STR_PURCHASE_INFO_CAPACITY :{BLACK}Mahutavus: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Kujundatud: {GOLD}{NUM}{BLACK} Vanus: {GOLD}{COMMA} aastat
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}Suurim töökindlus: {GOLD}{COMMA}%
+STR_PURCHASE_INFO_COST :{BLACK}Maksuvus: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Kaal: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Maksumus: {GOLD}{CURRENCY}{BLACK} Kiirus: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Mahutavus: {GOLD}{COMMA} reisijat, {COMMA} kotti kirju
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Kiirendavad vagunid: {GOLD}+{POWER}{BLACK} Kaal: {GOLD}+{WEIGHT_S}
+STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Ãœmberseadistatav: {GOLD}
+STR_PURCHASE_INFO_ALL_TYPES :Kõik kaubatüübid
+STR_PURCHASE_INFO_ALL_BUT :Kõik, välja arvatud {GOLD}
+STR_PURCHASE_INFO_MAX_TE :{BLACK}Suurim veojõud: {GOLD}{FORCE}
+
+########### String for New Landscape Generator
+
+STR_GENERATE :{WHITE}Genereeri
+STR_RANDOM :{BLACK}Muuda juhuslikuks
+STR_RANDOM_HELP :{BLACK}Muuda maastikuloomisel kasutatavat suvalist seemet
+STR_WORLD_GENERATION_CAPTION :{WHITE}Maailma genereerimine
+STR_RANDOM_SEED :{BLACK}Suvaline seeme:
+STR_RANDOM_SEED_HELP :{BLACK}Klõpsa, et sisestada juhuslik seeme
+STR_LAND_GENERATOR :{BLACK}Maa generaator:
+STR_TREE_PLACER :{BLACK}Puu algoritm:
+STR_HEIGHTMAP_ROTATION :{BLACK}Kõrgustekaardi pööre:
+STR_TERRAIN_TYPE :{BLACK}Maapinna tüüp:
+STR_QUANTITY_OF_SEA_LAKES :{BLACK}Merepinna tase:
+STR_SMOOTHNESS :{BLACK}Tasapinnalisus:
+STR_SNOW_LINE_HEIGHT :{BLACK}Lumepiiri kõrgus:
+STR_DATE :{BLACK}Algus:
+STR_NUMBER_OF_TOWNS :{BLACK}Linnade arv:
+STR_NUMBER_OF_INDUSTRIES :{BLACK}Tehaste arv
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_SNOW_LINE_UP :{BLACK}Liiguta lumepiiri ühe ühiku võrra üles
+STR_SNOW_LINE_DOWN :{BLACK}Liiguta lumepiiri ühe ühiku võrra alla
+STR_SNOW_LINE_QUERY_CAPT :{WHITE}Muuda lumepiiri kõrgust
+STR_START_DATE_QUERY_CAPT :{WHITE}Muuda algusaastat
+STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Skaala hoiatus
+STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Kaardi suuruse muutmine pole soovitatav. Jätka?
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_HEIGHTMAP_NAME :{BLACK}Kõrgusekaardi nimi:
+STR_HEIGHTMAP_SIZE :{BLACK}Suurus: {ORANGE}{NUM} x {NUM}
+STR_GENERATION_WORLD :{WHITE}Maailma genereerimine...
+STR_GENERATION_ABORT :{BLACK}Loobu
+STR_GENERATION_ABORT_CAPTION :{WHITE}Loobu Maailma Genereerimisest
+STR_GENERATION_ABORT_MESSAGE :{YELLOW}Kas sa tõesti tahad loobuda genereerimisest?
+STR_PROGRESS :{WHITE}{NUM}% valmis
+STR_GENERATION_PROGRESS :{BLACK}{NUM} / {NUM}
+STR_WORLD_GENERATION :{BLACK}Maailma genereerimine
+STR_TREE_GENERATION :{BLACK}Puude genereerimine
+STR_UNMOVABLE_GENERATION :{BLACK}Liigutamatu tekitamine
+STR_CLEARING_TILES :{BLACK}Mägise ja kivise maaala tegemine
+STR_SETTINGUP_GAME :{BLACK}Mängu seadistamine
+STR_PREPARING_TILELOOP :{BLACK}Klotsisilmuse täitmine
+STR_PREPARING_GAME :{BLACK}Mängu valmistamine
+STR_DIFFICULTY_TO_CUSTOM :{WHITE}See tegevus muutis raskusastme erilise peale
+STR_SE_FLAT_WORLD :{WHITE}Tasane maa
+STR_SE_FLAT_WORLD_TIP :{BLACK}Genereeri tasane maapind
+STR_SE_RANDOM_LAND :{WHITE}Suvaline maa
+STR_SE_NEW_WORLD :{BLACK}Alusta uut stsenaariumit
+STR_SE_CAPTION :{WHITE}Stsenaariumi tüüp
+STR_FLAT_WORLD_HEIGHT_DOWN :{BLACK}Liiguta lameda maa kõrgus ühe võrra alla
+STR_FLAT_WORLD_HEIGHT_UP :{BLACK}Liiguta lameda maa kõrgus ühe võrra üles
+STR_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Muuda maa kõrgust lamedal maal
+STR_FLAT_WORLD_HEIGHT :{BLACK}Lameda maa kõrgus:
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+STR_SMALLMAP_CENTER :{BLACK}Vii väikekaart praegusele asukohale
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}Väike
+STR_CITY_AIRPORT :{BLACK}Linn
+STR_METRO_AIRPORT :{BLACK}Metropoli lennujaam
+STR_INTERNATIONAL_AIRPORT :{BLACK}Rahvusvaheline lennujaam
+STR_COMMUTER_AIRPORT :{BLACK}Turisti
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Ãœlemaailmne lennujaam
+STR_HELIPORT :{BLACK}Helikopteri jaam
+STR_HELIDEPOT :{BLACK}Helikopteri depoo
+STR_HELISTATION :{BLACK}Helijaam
+
+STR_SMALL_AIRPORTS :{BLACK}Väikesed lennujaamad
+STR_LARGE_AIRPORTS :{BLACK}Suured lennujaamad
+STR_HUB_AIRPORTS :{BLACK}Suured lennujaamad
+STR_HELIPORTS :{BLACK}Helikopteri lennujaamad
+
+############ Tooltip measurment
+
+STR_MEASURE_LENGTH :{BLACK}Pikkus: {NUM}
+STR_MEASURE_AREA :{BLACK}Pindala: {NUM} x {NUM}
+STR_MEASURE_LENGTH_HEIGHTDIFF :{BLACK}Pikkus: {NUM}{}Kürguste erinevusj: {NUM} m
+STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}Pindala: {NUM} x {NUM}{}Kõrguste erinevus: {NUM} m
+
+########
diff --git a/src/lang/finnish.txt b/src/lang/finnish.txt
new file mode 100644
index 000000000..99de13d43
--- /dev/null
+++ b/src/lang/finnish.txt
@@ -0,0 +1,3111 @@
+##name Finnish
+##ownname Suomi
+##isocode fi_FI.UTF-8
+##plural 0
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Kartan reunan ulkopuolella.
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Liian lähellä kartan reunaa.
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Käteinen ei riitä - tarvitaan {CURRENCY}.
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Tarvitaan tasaista maata.
+STR_0008_WAITING :{BLACK}Lähdössä: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (matkalla:
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Vastaanottaa: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Vastaanottaa: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :Matkustajia
+STR_0010_COAL :Kivihiiltä
+STR_0011_MAIL :Postia
+STR_0012_OIL :Öljyä
+STR_0013_LIVESTOCK :Karjaa
+STR_0014_GOODS :Tavaroita
+STR_0015_GRAIN :Viljaa
+STR_0016_WOOD :Puutavaraa
+STR_0017_IRON_ORE :Rautamalmia
+STR_0018_STEEL :Terästä
+STR_0019_VALUABLES :Arvotavaroita
+STR_001A_COPPER_ORE :Kuparimalmia
+STR_001B_MAIZE :Maissia
+STR_001C_FRUIT :Hedelmiä
+STR_001D_DIAMONDS :Jalokiviä
+STR_001E_FOOD :Ruokaa
+STR_001F_PAPER :Paperia
+STR_0020_GOLD :Kultaa
+STR_0021_WATER :Vettä
+STR_0022_WHEAT :Vehnää
+STR_0023_RUBBER :Kumia
+STR_0024_SUGAR :Sokeria
+STR_0025_TOYS :Leluja
+STR_0026_CANDY :Karkkia
+STR_0027_COLA :Limsaa
+STR_0028_COTTON_CANDY :Hattaraa
+STR_0029_BUBBLES :Kuplia
+STR_002A_TOFFEE :Toffeeta
+STR_002B_BATTERIES :Pattereita
+STR_002C_PLASTIC :Muovia
+STR_002D_FIZZY_DRINKS :Sihijuomaa
+STR_002E :
+STR_002F_PASSENGER :Matkustaja
+STR_0030_COAL :Kivihiili
+STR_0031_MAIL :Posti
+STR_0032_OIL :Öljy
+STR_0033_LIVESTOCK :Karja
+STR_0034_GOODS :Tavara
+STR_0035_GRAIN :Vilja
+STR_0036_WOOD :Puutavara
+STR_0037_IRON_ORE :Rautamalmi
+STR_0038_STEEL :Teräs
+STR_0039_VALUABLES :Arvotavara
+STR_003A_COPPER_ORE :Kuparimalmi
+STR_003B_MAIZE :Maissi
+STR_003C_FRUIT :Hedelmä
+STR_003D_DIAMOND :Jalokivi
+STR_003E_FOOD :Ruoka
+STR_003F_PAPER :Paperi
+STR_0040_GOLD :Kulta
+STR_0041_WATER :Vesi
+STR_0042_WHEAT :Vehnä
+STR_0043_RUBBER :Kumi
+STR_0044_SUGAR :Sokeri
+STR_0045_TOY :Lelu
+STR_0046_CANDY :Karkki
+STR_0047_COLA :Limsa
+STR_0048_COTTON_CANDY :Hattara
+STR_0049_BUBBLE :Kupla
+STR_004A_TOFFEE :Toffee
+STR_004B_BATTERY :Paristo
+STR_004C_PLASTIC :Muovi
+STR_004D_FIZZY_DRINK :Sihijuoma
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} matkustaja{P "" a}
+STR_QUANTITY_COAL :{WEIGHT} kivihiiltä
+STR_QUANTITY_MAIL :{COMMA} säkki{P "" ä} postia
+STR_QUANTITY_OIL :{VOLUME} öljyä
+STR_QUANTITY_LIVESTOCK :{COMMA} erä{P "" ä} karjaa
+STR_QUANTITY_GOODS :{COMMA} laatikko{P "" a} tavaraa
+STR_QUANTITY_GRAIN :{WEIGHT} viljaa
+STR_QUANTITY_WOOD :{WEIGHT} puutavaraa
+STR_QUANTITY_IRON_ORE :{WEIGHT} rautamalmia
+STR_QUANTITY_STEEL :{WEIGHT} terästä
+STR_QUANTITY_VALUABLES :{COMMA} säkki{P "" ä} arvotavaraa
+STR_QUANTITY_COPPER_ORE :{WEIGHT} kuparimalmia
+STR_QUANTITY_MAIZE :{WEIGHT} maissia
+STR_QUANTITY_FRUIT :{WEIGHT} hedelmiä
+STR_QUANTITY_DIAMONDS :{COMMA} säkki{P "" ä} timantteja
+STR_QUANTITY_FOOD :{WEIGHT} ruokaa
+STR_QUANTITY_PAPER :{WEIGHT} paperia
+STR_QUANTITY_GOLD :{COMMA} säkki{P "" ä} kultaa
+STR_QUANTITY_WATER :{VOLUME} vettä
+STR_QUANTITY_WHEAT :{WEIGHT} vehnää
+STR_QUANTITY_RUBBER :{VOLUME} kumia
+STR_QUANTITY_SUGAR :{WEIGHT} sokeria
+STR_QUANTITY_TOYS :{COMMA} lelu{P "" a}
+STR_QUANTITY_SWEETS :{COMMA} säkki{P "" ä} karkkia
+STR_QUANTITY_COLA :{VOLUME} limsaa
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} hattaraa
+STR_QUANTITY_BUBBLES :{COMMA} kupla{P "" a}
+STR_QUANTITY_TOFFEE :{WEIGHT} toffeeta
+STR_QUANTITY_BATTERIES :{COMMA} paristo{P "" a}
+STR_QUANTITY_PLASTIC :{VOLUME} muovia
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} sihijuoma{P "" a}
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}MA
+STR_ABBREV_COAL :{TINYFONT}HL
+STR_ABBREV_MAIL :{TINYFONT}SP
+STR_ABBREV_OIL :{TINYFONT}ÖL
+STR_ABBREV_LIVESTOCK :{TINYFONT}KA
+STR_ABBREV_GOODS :{TINYFONT}TA
+STR_ABBREV_GRAIN :{TINYFONT}VL
+STR_ABBREV_WOOD :{TINYFONT}PT
+STR_ABBREV_IRON_ORE :{TINYFONT}RM
+STR_ABBREV_STEEL :{TINYFONT}TR
+STR_ABBREV_VALUABLES :{TINYFONT}AT
+STR_ABBREV_COPPER_ORE :{TINYFONT}KM
+STR_ABBREV_MAIZE :{TINYFONT}MS
+STR_ABBREV_FRUIT :{TINYFONT}HE
+STR_ABBREV_DIAMONDS :{TINYFONT}TI
+STR_ABBREV_FOOD :{TINYFONT}RU
+STR_ABBREV_PAPER :{TINYFONT}PA
+STR_ABBREV_GOLD :{TINYFONT}KU
+STR_ABBREV_WATER :{TINYFONT}VS
+STR_ABBREV_WHEAT :{TINYFONT}VH
+STR_ABBREV_RUBBER :{TINYFONT}KI
+STR_ABBREV_SUGAR :{TINYFONT}SK
+STR_ABBREV_TOYS :{TINYFONT}LL
+STR_ABBREV_SWEETS :{TINYFONT}KR
+STR_ABBREV_COLA :{TINYFONT}LM
+STR_ABBREV_CANDYFLOSS :{TINYFONT}HT
+STR_ABBREV_BUBBLES :{TINYFONT}KP
+STR_ABBREV_TOFFEE :{TINYFONT}TF
+STR_ABBREV_BATTERIES :{TINYFONT}PT
+STR_ABBREV_PLASTIC :{TINYFONT}MV
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}SJ
+STR_ABBREV_NONE :{TINYFONT}EI
+STR_ABBREV_ALL :{TINYFONT}KAIKKI
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Kartta - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Pelin asetukset
+STR_00B2_MESSAGE :{YELLOW}Viesti
+STR_00B3_MESSAGE_FROM :{YELLOW}Viesti: {STRING}
+STR_POPUP_CAUTION_CAPTION :{WHITE}Varoitus!
+STR_00B4_CAN_T_DO_THIS :{WHITE}Ei onnistu....
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Aluetta ei voi tyhjentää....
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Alkuperäiset oikeudet {COPYRIGHT} 1995 Chris Sawyer, kaikki oikeudet pidätetään
+STR_00B7_VERSION :{BLACK}OpenTTD-versio {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 The OpenTTD team
+STR_TRANSLATED_BY :{BLACK} Kääntäjä(t) -
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Sulje
+STR_00C8_YES :{BLACK}Kyllä
+STR_00C9_NO :{BLACK}Ei
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Lopetetaanko peli ja palataan {STRING}-järjestelmään?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Ei mitään
+STR_00D1_DARK_BLUE :Tummansininen
+STR_00D2_PALE_GREEN :Vaaleanvihreä
+STR_00D3_PINK :Vaaleanpunainen
+STR_00D4_YELLOW :Keltainen
+STR_00D5_RED :Punainen
+STR_00D6_LIGHT_BLUE :Vaaleansininen
+STR_00D7_GREEN :Vihreä
+STR_00D8_DARK_GREEN :Tummanvihreä
+STR_00D9_BLUE :Sininen
+STR_00DA_CREAM :Kerma
+STR_00DB_MAUVE :Malvanvärinen
+STR_00DC_PURPLE :Violetti
+STR_00DD_ORANGE :Oranssi
+STR_00DE_BROWN :Ruskea
+STR_00DF_GREY :Harmaa
+STR_00E0_WHITE :Valkoinen
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Liian monta ajoneuvoa pelissä.
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Sijainti
+STR_00E5_CONTOURS :Korkeuserot
+STR_00E6_VEHICLES :Liikennevälineet
+STR_00E7_INDUSTRIES :Teollisuus
+STR_00E8_ROUTES :Reitit
+STR_00E9_VEGETATION :Kasvillisuus
+STR_00EA_OWNERS :Omistajat
+STR_00EB_ROADS :{BLACK}{TINYFONT}Tie
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Rautatie
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Asemat/lentokentät/satamat
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Rakennus
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Liikennevälineet
+STR_00F0_100M :{BLACK}{TINYFONT}100 m
+STR_00F1_200M :{BLACK}{TINYFONT}200 m
+STR_00F2_300M :{BLACK}{TINYFONT}300 m
+STR_00F3_400M :{BLACK}{TINYFONT}400 m
+STR_00F4_500M :{BLACK}{TINYFONT}500 m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Junat
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Ajoneuvot
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Laivat
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Lentokoneet
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Kuljetusreitit
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Hiilikaivos
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Voimala
+STR_00FC_FOREST :{BLACK}{TINYFONT}Metsä
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}Saha
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Öljynjalostamo
+STR_00FF_FARM :{BLACK}{TINYFONT}Maatila
+STR_0100_FACTORY :{BLACK}{TINYFONT}Tehdas
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Kirjapaino
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Öljykenttä
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Rautakaivos
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Teräsvalimo
+STR_0105_BANK :{BLACK}{TINYFONT}Pankki
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Paperitehdas
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Kultakaivos
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Ruoanjalostamo
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Timanttikaivos
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Kuparikaivos
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Hedelmäviljelmä
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Kumiviljelmä
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Lähde
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Vesitorni
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}Hakkuualue
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Hattarametsä
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Karkkitehdas
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Paristomaatila
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Limsakenttä
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Lelukauppa
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Lelutehdas
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Muovilähde
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Sihijuomatehdas
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Kuplageneraattori
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Toffeelouhos
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Sokerikaivos
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Rautatieasema
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Lastauslaituri
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Linja-autoasema
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Lento-/helikopterikenttä
+STR_011F_DOCK :{BLACK}{TINYFONT}Satama
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Kumpuilevaa maata
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Ruohikkoa
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Paljasta maata
+STR_0123_FIELDS :{BLACK}{TINYFONT}Peltoja
+STR_0124_TREES :{BLACK}{TINYFONT}Puita
+STR_0125_ROCKS :{BLACK}{TINYFONT}Kiviä
+STR_0126_WATER :{BLACK}{TINYFONT}Vettä
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Ei omistajaa
+STR_0128_TOWNS :{BLACK}{TINYFONT}Kaupunkeja
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Teollisuutta
+STR_012A_DESERT :{BLACK}{TINYFONT}Autiomaata
+STR_012B_SNOW :{BLACK}{TINYFONT}Lunta
+STR_012C_MESSAGE :{WHITE}Viesti
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Peruuta
+STR_012F_OK :{BLACK}OK
+STR_0130_RENAME :{BLACK}Nimeä uud.
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Liian monta nimeä määritelty
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Nimi on jo käytössä
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS{NBSP}X{NBSP}
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...omistaja: {STRING}
+STR_013C_CARGO :{BLACK}Rahti
+STR_013D_INFORMATION :{BLACK}Tietoa
+STR_013E_CAPACITIES :{BLACK}Kapasiteetit
+STR_013E_TOTAL_CARGO :{BLACK}Rahtia yhteensä
+STR_013F_CAPACITY :{BLACK}Kapaisteetti: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}Kapasiteetti: {LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Kokonaisrahtikapasiteetti:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}Uusi peli
+STR_0141_LOAD_GAME :{BLACK}Lataa peli
+STR_SINGLE_PLAYER :{BLACK}Yksinpeli
+STR_MULTIPLAYER :{BLACK}Moninpeli
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Kartan koko:
+STR_BY :{BLACK}×
+STR_0148_GAME_OPTIONS :{BLACK}Pelin asetukset
+
+STR_0150_SOMEONE :joku{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Maailmankartta
+STR_0152_TOWN_DIRECTORY :Kaupunkihakemisto
+STR_0153_SUBSIDIES :Tukiaiset
+
+STR_UNITS_IMPERIAL :Englantilainen
+STR_UNITS_METRIC :Metrinen
+STR_UNITS_SI :SI
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} mph
+STR_UNITS_VELOCITY_METRIC :{COMMA} km/h
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}hv
+STR_UNITS_POWER_METRIC :{COMMA}hv
+STR_UNITS_POWER_SI :{COMMA}kW
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} ton
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} tonni{P "" a}
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} kg
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}gal
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}l
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}m³
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} gallona{P "" a}
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} litra{P "" a}
+STR_UNITS_VOLUME_LONG_SI :{COMMA} m³
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10³ lbf
+STR_UNITS_FORCE_METRIC :{COMMA} tf
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Liikevoitto
+STR_0155_INCOME_GRAPH :Tulot
+STR_0156_DELIVERED_CARGO_GRAPH :Kuljetettu rahti
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Suoritehistoria
+STR_0158_COMPANY_VALUE_GRAPH :Yhtiön arvo
+STR_0159_CARGO_PAYMENT_RATES :Rahtimaksutaksat
+STR_015A_COMPANY_LEAGUE_TABLE :Yhtiökilpataulukko
+STR_PERFORMANCE_DETAIL_MENU :Suoritearviointi
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}Tietoa OpenTTD:stä
+STR_015C_SAVE_GAME :Tallenna peli
+STR_015D_LOAD_GAME :Lataa peli
+STR_015E_QUIT_GAME :Lopeta peli
+STR_015F_QUIT :Poistu
+STR_ABANDON_GAME_QUERY :{YELLOW}Lopetetaanko peli?
+STR_0161_QUIT_GAME :{WHITE}Lopeta peli
+STR_SORT_ORDER_TIP :{BLACK}Valitse järjestys (laskeva/nouseva).
+STR_SORT_CRITERIA_TIP :{BLACK}Valitse järjestyskriteeri.
+STR_SORT_BY :{BLACK}Lajittele
+
+STR_SORT_BY_POPULATION :{BLACK}Asukasluku
+STR_SORT_BY_PRODUCTION :{BLACK}Tuotto
+STR_SORT_BY_TYPE :{BLACK}Tyyppi
+STR_SORT_BY_TRANSPORTED :{BLACK}Kuljetettu
+STR_SORT_BY_NAME :{BLACK}Nimi
+STR_SORT_BY_DROPDOWN_NAME :Nimi
+STR_SORT_BY_DATE :{BLACK}Päiväys
+STR_SORT_BY_NUMBER :Numero
+STR_SORT_BY_PROFIT_LAST_YEAR :Tuottoa viime vuonna
+STR_SORT_BY_PROFIT_THIS_YEAR :Tuottoa tänä vuonna
+STR_SORT_BY_AGE :Ikä
+STR_SORT_BY_RELIABILITY :Toimintavarmuus
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Kokonaiskapasiteetti/rahtityyppi
+STR_SORT_BY_MAX_SPEED :Huippunopeus
+STR_SORT_BY_MODEL :Malli
+STR_SORT_BY_VALUE :Arvo
+STR_SORT_BY_FACILITY :Asematyyppi
+STR_SORT_BY_WAITING :Odottavan lastin arvo
+STR_SORT_BY_RATING_MAX :Rahtauksen arvosana
+STR_ENGINE_SORT_ENGINE_ID :VeturiD (perinteinen lajittelu)
+STR_ENGINE_SORT_COST :Hinta
+STR_ENGINE_SORT_POWER :Teho
+STR_ENGINE_SORT_INTRO_DATE :Julkaisupäivä
+STR_ENGINE_SORT_RUNNING_COST :Käyttökustannukset
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Teho-hyötysuhde
+STR_ENGINE_SORT_CARGO_CAPACITY :Rahtikapasiteetti
+STR_NO_WAITING_CARGO :{BLACK}Minkäänlaista lastia ei ole odottamassa
+STR_SELECT_ALL_FACILITIES :{BLACK}Valitse kaikki laitteet
+STR_SELECT_ALL_TYPES :{BLACK}Valitse kaikki lastityypit (myös odottava lasti)
+STR_MANAGE_LIST :{BLACK}Muokkaa listaa
+STR_MANAGE_LIST_TIP :{BLACK}Ohjaa kaikkia listan ajoneuvoja
+STR_REPLACE_VEHICLES :Korvaa liikennevälineitä
+STR_SEND_TRAIN_TO_DEPOT :Lähetä varikolle
+STR_SEND_ROAD_VEHICLE_TO_DEPOT :Lähetä varikolle
+STR_SEND_SHIP_TO_DEPOT :Lähetä varikolle
+STR_SEND_AIRCRAFT_TO_HANGAR :Lähetä varikolle
+STR_SEND_FOR_SERVICING :Lähetä huollettavaksi
+
+############ range for months starts
+STR_0162_JAN :01.
+STR_0163_FEB :02.
+STR_0164_MAR :03.
+STR_0165_APR :04.
+STR_0166_MAY :05.
+STR_0167_JUN :06.
+STR_0168_JUL :07.
+STR_0169_AUG :08.
+STR_016A_SEP :09.
+STR_016B_OCT :10.
+STR_016C_NOV :11.
+STR_016D_DEC :12.
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Tauko
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Pelin tallennus, hylkääminen ja lopetus.
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Näytä luettelo yhtiön asemista.
+STR_0174_DISPLAY_MAP :{BLACK}Näytä kartta.
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Näytä kartta, kaupunkihakemisto.
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Näytä kaupunkihakemisto.
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Näytä yhtiön taloustiedot.
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Näytä yhtiön yleiset tiedot.
+STR_0179_DISPLAY_GRAPHS :{BLACK}Näytä kuvaajat.
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Näytä yhtiökilpataulukko.
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Näytä luettelo yhtiön junista.
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Näytä luettelo yhtiön ajoneuvoista.
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Näytä luettelo yhtiön laivoista.
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Näytä luettelo yhtiön lentokoneista.
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Lähennä näkymää.
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Loitonna näkymää.
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Rakenna rautateitä.
+STR_0182_BUILD_ROADS :{BLACK}Rakenna teitä.
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Rakenna satamia.
+STR_0184_BUILD_AIRPORTS :{BLACK}Rakenna lentokenttiä.
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Istuta puita, asenna kylttejä, jne.
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Maa-aluetiedot
+STR_0187_OPTIONS :{BLACK}Asetukset
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Huoltoväliä ei voi muuttaa.
+STR_018B_CLOSE_WINDOW :{BLACK}Sulje ikkuna
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Ikkunan otsake - vedä tästä siirtääksesi ikkunaa
+STR_STICKY_BUTTON :{BLACK}Merkitse ikkuna tahmeaksi; 'Sulje kaikki ikkunat'-nappi ei vaikuta tahmeisiin ikkunoihin.
+STR_RESIZE_BUTTON :{BLACK}Napsauta ja vedä muuttaaksesi tämän ikkunan kokoa.
+STR_SAVELOAD_HOME_BUTTON :{BLACK}Siirry tallennusten oletuskansioon napsauttamalla tätä
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Tuhoa ruudulla olevat rakennukset, puut, jne.
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Madalla ruudun kulmausta.
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Korota ruudun kulmausta.
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Vierityspalkki - luettelon vieritys ylös/alas
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Vierityspalkki - luettelon vieritys vasemmalle/oikealle.
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Näytä korkeuserot kartalla.
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Näytä liikennevälineet kartalla.
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Näytä teollisuuus kartalla.
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Näytä kuljetusreitit kartalla.
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Näytä kasvillisuus kartalla.
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Näytä maanomistajat kartalla.
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Kaupunkien nimet kartalla.
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Voittoa tänä vuonna: {CURRENCY} (viime vuonna: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} vuo{P si tta} ({COMMA})
+STR_AGE_RED :{RED}{COMMA} vuo{P si tta} ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Ajoneuvo
+STR_019D_AIRCRAFT :Lentokone
+STR_019E_SHIP :Laiva
+STR_019F_TRAIN :Juna
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} vanhenee.
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} on todella vanha.
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} on todella vanha ja täytyy korvata pikaisesti.
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Maa-aluetiedot
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Puhdistuksen hinta: {LTBLUE}-
+STR_01A5_COST_TO_CLEAR :{BLACK}Puhdistuksen hinta: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :-
+STR_01A7_OWNER :{BLACK}Omistaja: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Kunta: {LTBLUE}{STRING}
+STR_01A9_NONE :Ei mitään
+STR_01AA_NAME :{BLACK}Nimi
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1.
+STR_01AD_2ND :2.
+STR_01AE_3RD :3.
+STR_01AF_4TH :4.
+STR_01B0_5TH :5.
+STR_01B1_6TH :6.
+STR_01B2_7TH :7.
+STR_01B3_8TH :8.
+STR_01B4_9TH :9.
+STR_01B5_10TH :10.
+STR_01B6_11TH :11.
+STR_01B7_12TH :12.
+STR_01B8_13TH :13.
+STR_01B9_14TH :14.
+STR_01BA_15TH :15.
+STR_01BB_16TH :16.
+STR_01BC_17TH :17.
+STR_01BD_18TH :18.
+STR_01BE_19TH :19.
+STR_01BF_20TH :20.
+STR_01C0_21ST :21.
+STR_01C1_22ND :22.
+STR_01C2_23RD :23.
+STR_01C3_24TH :24.
+STR_01C4_25TH :25.
+STR_01C5_26TH :26.
+STR_01C6_27TH :27.
+STR_01C7_28TH :28.
+STR_01C8_29TH :29.
+STR_01C9_30TH :30.
+STR_01CA_31ST :31.
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Vastaanottaa rahtia: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Jazz-jukeboksi
+STR_01D3_SOUND_MUSIC :Ääni/musiikki
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Näytä ääni- ja musiikkiasetukset
+STR_01D5_ALL :{TINYFONT}Kaikki
+STR_01D6_OLD_STYLE :{TINYFONT}Vanha tyyli
+STR_01D7_NEW_STYLE :{TINYFONT}Uusi tyyli
+STR_01D8_EZY_STREET :{TINYFONT}Ezy Street
+STR_01D9_CUSTOM_1 :{TINYFONT}Oma 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Oma 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Musiikin voimakkuus
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Äänitehosteiden voimakkuus
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MIN ' ' ' ' ' ' MAX
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Hyppää edelliseen raitaan.
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Hyppää seuraavaan raitaan.
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Pysäytä musiikki.
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Aloita musiikki.
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Aseta liukusäätimillä sopiva äänenvoimakkuus musiikille ja tehosteille.
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Raita{SETX 88}Nimi
+STR_01E9_SHUFFLE :{TINYFONT}Sekoita
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Soittolista
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Soittolistan valinta
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Raita
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Soittolista - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}Tyhjennä
+STR_01F1_SAVE :{TINYFONT}{BLACK}Tallenna
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Nykyinen soittolista
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Valitse 'kaikki raidat'
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Valitse 'vanhan tyylin musiikki'
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Valitse 'uuden tyylin musiikki'
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Valitse 'oma 1' (käyttäjän määritettävissä)
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Valitse 'oma 2' (käyttäjän määritettävissä)
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Tyhjennä nykyinen soittolista (vain Oma1 tai Oma2)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Tallenna musiikkiasetukset
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Valitse musiikkiraita lisätäksesi sen nykyiseen soittolistaan (vain Oma1 tai Oma2).
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Klikkaa raitaa poistaaksesi se nykyisestä ohjelmasta (ainoastaan Custom1 tai Custom2)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Sekoittaminen päälle/pois
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Näytä musiikkiraitojen valintaikkuna
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Napsauta palvelussa keskittääksesi näkymän teollisuuteen/kaupunkiin.
+STR_01FE_DIFFICULTY :{BLACK}Vaikeusaste: ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Viimeisin viesti/uutisraportti
+STR_0201_MESSAGE_SETTINGS :Viestiasetukset
+STR_MESSAGE_HISTORY_MENU :Viestihistoria
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Näytä viimeisin viesti/uutisraportti, näytä viestiasetukset.
+STR_0204_MESSAGE_OPTIONS :{WHITE}Viestiasetukset
+STR_0205_MESSAGE_TYPES :{BLACK}Viestityypit:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Ensimmäinen ajoneuvo saapuu pelaajan asemalle.
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Ensimmäinen ajoneuvo saapuu kilpailijan asemalle.
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Vahingot/onnettomuudet
+STR_0209_COMPANY_INFORMATION :{YELLOW}Yhtiön tiedot
+STR_020A_ECONOMY_CHANGES :{YELLOW}Talouden muutokset
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Neuvoja/tietoja pelaajan ajoneuvoista
+STR_020C_NEW_VEHICLES :{YELLOW}Uudet ajoneuvot
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Rahdin vastaanottamisen muutokset
+STR_020E_SUBSIDIES :{YELLOW}Tuet
+STR_020F_GENERAL_INFORMATION :{YELLOW}Yleistä tietoa
+STR_MESSAGES_ALL :{YELLOW}Asetukset kaikille viestityypeille (pois/tiivistelmä/täysi)
+STR_MESSAGE_SOUND :{YELLOW}Soita ääni tiivistetyn uutisviestin kohdalla
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...liian kaukana edellisestä määränpäästä
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Parhaat yhtiöt, jotka saavuttivat vuoden {NUM}{}(taso: {STRING})
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Yhtiökilpailutaulukko vuonna {NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Liikemies
+STR_0214_ENTREPRENEUR :Yrittäjä
+STR_0215_INDUSTRIALIST :Teollisuusmies
+STR_0216_CAPITALIST :Kapitalisti
+STR_0217_MAGNATE :Magnaatti
+STR_0218_MOGUL :Moguli
+STR_0219_TYCOON_OF_THE_CENTURY :Vuosisadan pohatta
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} saavuttaa arvon '{STRING}'!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} yhtiöstä {COMPANY} saavuttaa arvon '{STRING}'!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Luo skenaario
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Skenaariomuokkain
+STR_0223_LAND_GENERATION :{WHITE}Maanrakennus
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Satunnainen maa
+STR_0227_RESET_LAND :{BLACK}Nollaa maa
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Suurenna madallettavan/korotettavan maa-alueen kokoa.
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Pienennä madallettavan/korotettavan maa-alueen kokoa.
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Luo satunnainen maa
+STR_022B_RESET_LANDSCAPE :{BLACK}Nollaa maasto
+STR_022C_RESET_LANDSCAPE :{WHITE}Nollaa maasto
+STR_LOAD_GAME_HEIGHTMAP :{WHITE}Käytä korkeuskarttaa
+STR_LOAD_SCEN_HEIGHTMAP :{BLACK}Käytä korkeuskarttaa
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Nollataanko maasto?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Luo maasto
+STR_022F_TOWN_GENERATION :{BLACK}Luo kaupunkeja
+STR_0230_INDUSTRY_GENERATION :{BLACK}Luo teollisuutta
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Rakenna teitä
+STR_0233_TOWN_GENERATION :{WHITE}Luo kaupunkeja
+STR_0234_NEW_TOWN :{BLACK}Uusi kaupunki
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Rakenna uusi kaupunki
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Kaupunkia ei voi rakentaa tähän...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...liian lähellä kartan reunaa.
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...liian lähellä toista kaupunkia.
+STR_0239_SITE_UNSUITABLE :{WHITE}...maasto on sopimaton.
+STR_023A_TOO_MANY_TOWNS :{WHITE}...liian monta kaupunkia.
+STR_CANNOT_GENERATE_TOWN :{WHITE}Kaupunkeja ei voi rakentaa
+STR_NO_SPACE_FOR_TOWN :{WHITE}...kartalla ei ole enää tilaa
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Suurenna kaupunkia
+STR_023C_EXPAND :{BLACK}Laajenna
+STR_023D_RANDOM_TOWN :{BLACK}Satunnainen kaupunki
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Rakenna kaupunki satunnaiseen paikkaan
+STR_023F_INDUSTRY_GENERATION :{WHITE}Luo teollisuutta
+STR_0240_COAL_MINE :{BLACK}Hiilikaivos
+STR_0241_POWER_STATION :{BLACK}Voimala
+STR_0242_SAWMILL :{BLACK}Saha
+STR_0243_FOREST :{BLACK}Metsä
+STR_0244_OIL_REFINERY :{BLACK}Öljynjalostamo
+STR_0245_OIL_RIG :{BLACK}Öljylautta
+STR_0246_FACTORY :{BLACK}Tehdas
+STR_0247_STEEL_MILL :{BLACK}Teräsvalimo
+STR_0248_FARM :{BLACK}Maatila
+STR_0249_IRON_ORE_MINE :{BLACK}Rautakaivos
+STR_024A_OIL_WELLS :{BLACK}Öljykenttä
+STR_024B_BANK :{BLACK}Pankki
+STR_024C_PAPER_MILL :{BLACK}Paperitehdas
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Ruoanjalostamo
+STR_024E_PRINTING_WORKS :{BLACK}Kirjapaino
+STR_024F_GOLD_MINE :{BLACK}Kultakaivos
+STR_0250_LUMBER_MILL :{BLACK}Hakkuualue
+STR_0251_FRUIT_PLANTATION :{BLACK}Hedelmäviljelmä
+STR_0252_RUBBER_PLANTATION :{BLACK}Kumiviljelmä
+STR_0253_WATER_SUPPLY :{BLACK}Lähde
+STR_0254_WATER_TOWER :{BLACK}Vesitorni
+STR_0255_DIAMOND_MINE :{BLACK}timanttikaivos
+STR_0256_COPPER_ORE_MINE :{BLACK}Kuparikaivos
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Hattarametsä
+STR_0258_CANDY_FACTORY :{BLACK}Karkkitehdas
+STR_0259_BATTERY_FARM :{BLACK}Paristomaatila
+STR_025A_COLA_WELLS :{BLACK}Limsakenttä
+STR_025B_TOY_SHOP :{BLACK}Lelukauppa
+STR_025C_TOY_FACTORY :{BLACK}Lelutehdas
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Muovikaivo
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Sihijuomatehdas
+STR_025F_BUBBLE_GENERATOR :{BLACK}Kuplageneraattori
+STR_0260_TOFFEE_QUARRY :{BLACK}Toffeelouhos
+STR_0261_SUGAR_MINE :{BLACK}Sokerikaivos
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Rakenna hiilikaivos.
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Rakenna sähkölaitos.
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Rakenna saha.
+STR_0265_PLANT_FOREST :{BLACK}Istuta metsä.
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Rakenna öljynjalostamo.
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Rakenna öljylautta (voidaan rakentaa vain kartan reunojen läheisyyteen).
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Rakenna tehdas.
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Rakenna teräsvalimo.
+STR_026A_CONSTRUCT_FARM :{BLACK}Rakenna maatila.
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Rakenna rautakaivos.
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Rakenna öljykenttä.
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Rakenna pankki (voidaan rakentaa vain kaupunkiin, jonka väkiluku on suurempi kuin 1200).
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Rakenna paperitehdas.
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Rakenna ruoanjalostamo.
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Rakenna kirjapaino.
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Rakenna kultakaivos.
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Rakenna pankki (voidaan rakentaa vain kaupunkeihin).
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Rakenna hakkuualue (sademetsän kaatamiseen ja puuntuottoon).
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Istuta hedelmäviljelmä.
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Istuta kumiviljelmä.
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Rakenna lähde.
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Rakenna vesitorni (voidaan rakentaa vain kaupunkeihin).
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Rakenna timanttikaivos.
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Rakenna kuparikaivos.
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Istuta hattarametsä.
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Rakenna karkkitehdas.
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Rakenna paristomaatila.
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Rakenna limsakenttä.
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Rakenna karkkikauppa.
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Rakenna karkkitehdas.
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Rakenna muovikaivo.
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Rakenna sihijuomatehdas.
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Rakenna kuplageneraattori.
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Rakenna toffeelouhos.
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Rakenna sokerikaivos.
+STR_0285_CAN_T_BUILD_HERE :{WHITE}{STRING}: tähän ei voi rakentaa...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...kaupunki pitää rakentaa ensin.
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...vain yksi on sallittu kaupunkia kohden.
+STR_0288_PLANT_TREES :{BLACK}Istuta puita.
+STR_0289_PLACE_SIGN :{BLACK}Sijoita kyltti.
+STR_028A_RANDOM_TREES :{BLACK}Satunnaisia puita.
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Istuta puita satunnaisesti maastoon.
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Sijoita kallioisia alueita maastoon.
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Sijoita majakka.
+STR_028E_PLACE_TRANSMITTER :{BLACK}Sijoita lähetin.
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Määrittele aavikon alue.{}Paina ja pidä pohjassa CTRL-nappia poistaaksesi aavikkoa.
+STR_CREATE_LAKE :{BLACK}Määrittele veden alue.{}Vesi tulvii ympäröivään maastoon, jos se on merenpinnan tasolla.
+STR_0290_DELETE :{BLACK}Poista
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Poista tämä kaupunki kokonaan.
+STR_0292_SAVE_SCENARIO :Tallenna skenaario
+STR_0293_LOAD_SCENARIO :Lataa skenaario
+STR_0294_QUIT_EDITOR :Sulje muokkain
+STR_0295 :
+STR_0296_QUIT :Sulje
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Tallenna skenaario, lataa skenaario, hylkää skenaariomuokkain, lopeta.
+STR_0298_LOAD_SCENARIO :{WHITE}Lataa skenaario
+STR_0299_SAVE_SCENARIO :{WHITE}Tallenna skenaario
+STR_029A_PLAY_SCENARIO :{BLACK}Pelaa skenaariota
+STR_PLAY_HEIGHTMAP :{BLACK}Pelaa korkeuskartta
+STR_PLAY_HEIGHTMAP_HINT :{BLACK}Aloita uusi peli, käyttäen korkeuskarttaa maastona
+STR_QUIT_SCENARIO_QUERY :{YELLOW}Lopetetaanko skenaario?
+STR_029C_QUIT_EDITOR :{WHITE}Sulje muokkain
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...voidaan rakentaa vain kaupunkeihin, joissa on yli 1200 asukasta.
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Siirrä aloituspäivää vuodella taaksepäin.
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Siirrä aloituspäivää vuodella eteenpäin.
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...sillan molempien päiden pitää sijaita maalla.
+STR_02A1_SMALL :{BLACK}Pieni
+STR_02A2_MEDIUM :{BLACK}Keskisuuri
+STR_02A3_LARGE :{BLACK}Suuri
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Valitse kaupungin koko.
+STR_02A5_TOWN_SIZE :{YELLOW}Kaupungin koko:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Näytä viimeisin viesti tai uutisraportti.
+STR_OFF :Pois
+STR_SUMMARY :Tiivistelmä
+STR_FULL :Täysi
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Kaupunkihakemisto
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Liikennevälineiden mallien nimet
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Oletus
+STR_02BF_CUSTOM :Oma
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Tallenna kustomoidut nimet.
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Liikennevälineiden mallinimien valinta.
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Tallenna omat liikennevälineiden mallien nimet levylle.
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Pelin asetukset
+STR_02C5_DIFFICULTY_SETTINGS :Vaikeusasetukset
+STR_02C7_CONFIG_PATCHES :Muokkaa paikkauksia
+STR_NEWGRF_SETTINGS :Newgrf-asetukset
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Kaupunkien nimet näkyvissä
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Asemien nimet näkyvissä
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Kyltit näkyvissä
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Rastit näkyvissä
+STR_02D0_FULL_ANIMATION :{SETX 12}Täysi animointi
+STR_02D2_FULL_DETAIL :{SETX 12}Kaikki yksityiskohdat
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Läpinäkyvät rakennukset
+STR_TRANSPARENT_SIGNS :{SETX 12}Läpinäkyvät asemakyltit
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Maa-alueen tiedot
+STR_02D6 :
+STR_CONSOLE_SETTING :Konsoli
+STR_02D7_SCREENSHOT_CTRL_S :Kuvakaappaus (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Valtava kuvakaapp. (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :Tietoja "OpenTTD":stä
+############ range ends here
+
+STR_02DB_OFF :{BLACK}pois
+STR_02DA_ON :{BLACK}päällä
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Näytä tukitarjoukset
+STR_02DD_SUBSIDIES :Tuet
+STR_02DE_MAP_OF_WORLD :Maailmankartta
+STR_EXTRA_VIEW_PORT :Lisänäkymä
+STR_SIGN_LIST :Kylttilista
+STR_02DF_TOWN_DIRECTORY :Kaupunkihakemisto
+STR_TOWN_POPULATION :{BLACK}Maailman asukasluku: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Näkymä {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Kopioi näkymään
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Kopioi päänäkymän sijainti tähän näkymään
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Liitä näkymästä
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Liitä sijainti tästä näkymästä päänäkymään
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Rahayksikkö
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Rahayksikön valinta.
+STR_MEASURING_UNITS :{BLACK}Mittayksiköt
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Mittayksiköiden valinta
+STR_02E6_ROAD_VEHICLES :{BLACK}Ajoneuvot
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Valitse, kummalla puolella tietä ajetaan.
+STR_02E9_DRIVE_ON_LEFT :Vasemmalla kaistalla
+STR_02EA_DRIVE_ON_RIGHT :Oikealla kaistalla
+STR_02EB_TOWN_NAMES :{BLACK}Kaupunkien nimet
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Valitse tyyli kaupunkien nimille.
+
+STR_02F4_AUTOSAVE :{BLACK}Automaattitallennus
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Valitse aikaväli automaattisille pelitallennuksille.
+STR_02F7_OFF :Pois
+STR_02F8_EVERY_3_MONTHS :Joka 3. kuukausi
+STR_02F9_EVERY_6_MONTHS :Joka 6. kuukausi
+STR_02FA_EVERY_12_MONTHS :Joka 12. kuukausi
+STR_02FB_START_A_NEW_GAME :{BLACK}Aloita uusi peli.
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Lataa tallennettu peli.
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Luo oma pelimaailma/skenaario.
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Valitse yksinpeli.
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Valitse 2-8 pelaajan moninpeli.
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Näytä peliasetukset.
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Näytä vaikeusasetukset.
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Aloita uusi peli käyttäen omaa skenaariota.
+STR_0304_QUIT :{BLACK}Sulje
+STR_0305_QUIT_OPENTTD :{BLACK}Sulje "OpenTTD".
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...voidaan rakentaa vain kaupunkeihin.
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Valitse 'lauhkea' ilmasto.
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Valitse 'pohjoinen' ilmasto.
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Valitse 'subtrooppinen' ilmasto.
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Valitse 'lelumaan' ilmasto.
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Rahoita uuden teollisuuden rakentamista.
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Teollisuushakemisto
+STR_0313_FUND_NEW_INDUSTRY :Rakenna uutta teollisuutta
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Rakenna uutta teollisuutta
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...voidaan rakentaa vain kaupunkeihin.
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...voidaan rakentaa vain sademetsäalueisiin.
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...voidaan rakentaa vain aavikkoalueisiin.
+STR_0319_PAUSED :{YELLOW}* * TAUKO * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Kuvankaappaus tallennettu levyllä nimellä '{STRING}'.
+STR_031C_SCREENSHOT_FAILED :{WHITE}Kuvakaappaus epäonnistui!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Osta maata tulevaa käyttöä varten.
+STR_032F_AUTOSAVE :{RED}AUTOMAATTITALLENNUS
+STR_SAVING_GAME :{RED}* * TALLENNETAAN PELIÄ * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}Tallentaminen käynnissä,{}odota, kunnes se päättyy!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Valitse 'Ezy Street'.
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :Englantilainen
+STR_TOWNNAME_FRENCH :Ranskalainen
+STR_TOWNNAME_GERMAN :Saksalainen
+STR_TOWNNAME_ADDITIONAL_ENGLISH :Englantilainen 2
+STR_TOWNNAME_LATIN_AMERICAN :Latinalais-Amerikkalainen
+STR_TOWNNAME_SILLY :Hassu
+STR_TOWNNAME_SWEDISH :Ruotsalainen
+STR_TOWNNAME_DUTCH :Hollantilainen
+STR_TOWNNAME_FINNISH :Suomalainen
+STR_TOWNNAME_POLISH :Puolalainen
+STR_TOWNNAME_SLOVAKISH :Slovakialainen
+STR_TOWNNAME_NORWEGIAN :Norjalainen
+STR_TOWNNAME_HUNGARIAN :Unkarilainen
+STR_TOWNNAME_AUSTRIAN :Itävaltalainen
+STR_TOWNNAME_ROMANIAN :Romanialainen
+STR_TOWNNAME_CZECH :Tsekkiläinen
+STR_TOWNNAME_SWISS :Sveitsiläinen
+STR_TOWNNAME_DANISH :Tanskalainen
+STR_TOWNNAME_TURKISH :turkkilainen
+STR_TOWNNAME_ITALIAN :Italialainen
+STR_TOWNNAME_CATALAN :Katalonialainen
+############ end of townname region
+
+STR_CURR_GBP :Punta (£)
+STR_CURR_USD :Dollari ($)
+STR_CURR_EUR :Euro (€)
+STR_CURR_YEN :Jeni (Â¥)
+STR_CURR_ATS :Itävallan shillinki (ATS)
+STR_CURR_BEF :Belgian frangi (BEF)
+STR_CURR_CHF :Sveitsin frangi (CHF)
+STR_CURR_CZK :Tsekin koruna (CZK)
+STR_CURR_DEM :Saksan markka (DEM)
+STR_CURR_DKK :Tanskan kruunu (DKK)
+STR_CURR_ESP :Peseta (ESP)
+STR_CURR_FIM :Suomen markka (FIM)
+STR_CURR_FRF :Frangi (FRF)
+STR_CURR_GRD :Kreikan drakma (GRD)
+STR_CURR_HUF :Unkarin forintti (HUF)
+STR_CURR_ISK :Islannin kruunu (ISK)
+STR_CURR_ITL :Italian liira (ITL)
+STR_CURR_NLG :Hollannin guildeni (NLG)
+STR_CURR_NOK :Norjan kruunu (NOK)
+STR_CURR_PLN :Puolan zloty (PLN)
+STR_CURR_ROL :Romanian leu (ROL)
+STR_CURR_RUR :Venjän rupla (RUR)
+STR_CURR_SIT :Slovenian tolari (SIT)
+STR_CURR_SEK :Ruotsin kruunu (SEK)
+STR_CURR_YTL :Turkin liira (YTL)
+STR_CURR_SKK :Slovakian koruna (SKK)
+STR_CURR_BRR :Brasilian reali (BRL)
+
+STR_CURR_CUSTOM :Oma...
+
+STR_OPTIONS_LANG :{BLACK}Kieli
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Valitse käyttöliittymän kieli.
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Koko näyttö
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}Laita rasti ruutuun pelataksesi kokoruututilassa.
+
+STR_OPTIONS_RES :{BLACK}Ruudun erottelukyky
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Valitse ruudun erottelukyky.
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Kuvakaappauksen muoto
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Valitse kuvankaappauksen muoto.
+
+STR_AUTOSAVE_1_MONTH :Kuukausittain
+STR_AUTOSAVE_FAILED :{WHITE}Automaattitallennus epäonnistui.
+
+STR_MONTH_JAN :Tammikuu
+STR_MONTH_FEB :Helmikuu
+STR_MONTH_MAR :Maaliskuu
+STR_MONTH_APR :Huhtikuu
+STR_MONTH_MAY :Toukokuu
+STR_MONTH_JUN :Kesäkuu
+STR_MONTH_JUL :Heinäkuu
+STR_MONTH_AUG :Elokuu
+STR_MONTH_SEP :Syyskuu
+STR_MONTH_OCT :Lokakuu
+STR_MONTH_NOV :Marraskuu
+STR_MONTH_DEC :Joulukuu
+
+STR_HEADING_FOR_STATION :{LTBLUE}Suuntana {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}Suuntana {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Ei pysähdyksiä
+STR_NO_ORDERS_VEL :{LTBLUE}Ei pysähdyksiä, {VELOCITY}
+
+STR_PASSENGERS :matkustajaa
+STR_BAGS :säkkiä
+STR_TONS :tonnia
+STR_LITERS :litraa
+STR_ITEMS :erää
+STR_CRATES :laatikkoa
+STR_RES_OTHER :muut
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Aikataulua ei voi jakaa...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Aikataulua ei voi kopioida...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - jaetun aikataulun loppu - -
+
+STR_TRAIN_IS_LOST :{WHITE}Juna {COMMA} on eksynyt.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}Junan {COMMA} tuotto viime vuonna oli {CURRENCY}.
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}Euroopan unionin talous- ja rahaliitto!{}{}Euro otetaan käyttöön maan ainoaksi valuutaksi päivittäisiin liiketapahtumiin!
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Junan {COMMA} aikataulussa on liian vähän pysähdyksiä.
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}Junan {COMMA} aikataulussa on epäkelpo pysähdys.
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}Junan {COMMA} määräyksissä on kaksi kertaa sama kohta.
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}Junan {COMMA} käskyissä on virheellinen asema.
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}Ajoneuvon {COMMA} aikataulussa on liian vähän pysähdyksiä.
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}Ajoneuvon {COMMA} aikataulussa on epäkelpo pysähdys.
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}Ajoneuvon {COMMA} määräyksissä on kaksi kertaa sama kohta.
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}Ajoneuvon {COMMA} käskyissä on laiton asema.
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}Laivan {COMMA} aikataulussa on liian vähän pysähdyksiä.
+STR_SHIP_HAS_VOID_ORDER :{WHITE}Laivan {COMMA} aikataulussa on epäkelpo pysähdys.
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}Laivan {COMMA} määräyksissä on kaksi kertaa sama kohta.
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}Laivan {COMMA} käskyissä on laiton asema.
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}Lentokoneen {COMMA} aikataulussa on liian vähän pysähdyksiä.
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}Lentokoneen {COMMA} aikataulussa on epäkelpo pysähdys.
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}Lentokoneen {COMMA} määräyksissä on kaksi kertaa sama kohta.
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}Lentokoneen {COMMA} käskyissä on laiton asema.
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}Junan {COMMA} itseuudistus epäonnistui (rahoitusraja).
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}Ajoneuvon {COMMA} itseuudistus epäonnistui (rahoitusraja).
+STR_SHIP_AUTORENEW_FAILED :{WHITE}Laivan {COMMA} itseuudistus epäonnistui (rahoitusraja).
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}Lentokoneen {COMMA} itseuudistus epäonnistui (rahoitusraja).
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}Juna {COMMA} kasvaisi liian pitkäksi
+
+STR_CONFIG_PATCHES :{BLACK}Muokkaa paikkauksia
+STR_CONFIG_PATCHES_TIP :{BLACK}Muokkaa paikkauksia.
+STR_CONFIG_PATCHES_CAPTION :{WHITE}Muokkaa paikkauksia
+
+STR_CONFIG_PATCHES_OFF :pois
+STR_CONFIG_PATCHES_ON :päällä
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Ajoneuvon nopeus tilapalkissa: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Rakentaminen rinteisiin ja rannikolle sallittu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Realistisemman kokoiset vaikutusalueet: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Kaupungin omistamien teiden, siltojen, jne. raivaaminen sallittu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Erittäin pitkien junien rakentaminen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Junat kiihdyttävät realistisesti: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Junat ja laivat: ei 90-asteen käännöksiä: {ORANGE}{STRING} {LTBLUE} (vaatii: NPF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Yhdistä vierekkäiset rautatieasemat: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Jätä asema, kun mikä tahansa rahti on täysi, jos 'täysi lastaus': {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Käytä kehittyneempää lastausalgoritmia: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GRADUAL_LOADING :{LTBLUE}Lataa kulkuneuvot vähitellen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Inflaatio: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Kuljeta rahti asemalle vain, kun on kysyntää: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Erittäin pitkien siltojen rakentaminen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Varikollemenomääräykset: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Raaka-aineteollisuuden rakentaminen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Kaupungissa voi olla useita samanlaisia teollisuustyyppejä: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Samantyyppistä teollisuutta voidaan rakentaa lähekkäin: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Näytä aina koko päiväys tilapalkissa: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Näytä opastimet ajokaistalla: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Näytä rahoitusikkuna vuoden lopussa: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}TTDPatch: Junat pysähtyvät vain aikataulun asemilla: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Ajoneuvojonotus (kvanttitehostein): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Vieritä ikkunaa, kun hiiri osuu reunaan: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Salli viranomaisten lahjominen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Epäyhtenäiset asemat: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Uusi globaali tienhakualgor. (NPF, korvaa NTP:n): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FREIGHT_TRAINS :{LTBLUE}Kerroin rahdin painolle raskaiden junien simuilointiin: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Salli aina pienet lentokentät: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Varoita jos juna menetetään: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Tarkista ajoneuvojen pysähdykset: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :ei
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :kyllä, mutta ei pysäytetyille
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :kaikille ajoneuvoille
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Varoita, jos junan tuotto on negatiivinen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Ajoneuvot eivät vanhene: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Itseuudista ajoneuvo, kun se vanhenee
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Itseuudista {ORANGE}{STRING}{LTBLUE} kuukautta ennen/jälkeen enimmäisiän
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Pienin tarvittava rahamäärä itseuudistukseen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Virheilmoituksen kesto: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Näytä kaupungin asukasluku kaupungin nimessä: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Näkymättömät puut (läpinäkyvillä rakennuksilla): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Maa generaattori: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :Alkuperäinen
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis
+STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}Suurin etäisyys reunasta öljyjalostamolle{ORANGE}{STRING}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Lumirajan korkeus: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN :{LTBLUE}Maaston epätasaisuus (vain TerraGenesis) : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Erittäin tasainen
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH :Tasainen (sileä)
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH :Epätasainen
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :Erittäin epätasainen
+STR_CONFIG_PATCHES_TREE_PLACER :{LTBLUE}Puiden sijainti algoritmi: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TREE_PLACER_NONE :Ei mitään
+STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL :Alkuperäinen
+STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED :Kehitetty
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION :{LTBLUE}Korkeuskartan pyöritys:{ORANGE}{STRING}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Vastapäivään
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE :Myötäpäivään
+STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT :{LTBLUE}Litteälle maisemalle annettava korkeus: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Suurin aseman levittäytyminen: {ORANGE}{STRING} {RED}Huom: korkea asetus hidastaa peliä
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Huolla helikopterit helikopterialustoilla automaattisesti: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Kiinnitä maastonmuokkauspalkki rakentamistyökalupalkkeihin: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Käänteinen vierityssuunta: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Näytä mittauksen työkaluvihje, kun käytetään rakennustyökaluja: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Näytä yrityksen tunnukset: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES_NONE :Ei yhtään
+STR_CONFIG_PATCHES_LIVERIES_OWN :Oma yritys
+STR_CONFIG_PATCHES_LIVERIES_ALL :Kaikki yritykset
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Junia/pelaaja: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Ajoneuvoja/pelaaja: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}Lentokoneita/pelaaja: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}Laivoja/pelaaja: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Tietokoneella ei ole junia: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Tietokoneella ei ole ajoneuvoja: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Tietokoneella ei ole lentokoneita: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Tietokoneella ei ole laivoja: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Ota käyttöön uusi AI (alpha): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Salli tekoälyt moninpelissä (kokeellinen): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Oletushuoltoväli junille: {ORANGE}{STRING} päivää
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Oletushuoltoväli junille: {ORANGE}pois päältä
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Oletushuoltoväli ajoneuvoille: {ORANGE}{STRING} päivää
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Oletushuoltoväli ajoneuvoille: {ORANGE}pois päältä
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Oletushuoltoväli lentokoneille: {ORANGE}{STRING} päivää
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Oletushuoltoväli lentokoneille: {ORANGE}pois päältä
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Oletushuoltoväli laivoille: {ORANGE}{STRING} päivää
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Oletushuoltoväli laivoille: {ORANGE}pois päältä
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Huollot pois käytöstä, kun rikkoutumiset on pois: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Ota käyttöön vaunujen nopeusrajoitukset: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}Poista sähköradat käytöstä: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Värjätyt uutiset: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Aloitusvuosi: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}Lopetusvuosi: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Tasainen talous (enemmän pieniä muutoksia)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Salli osakkeiden ostaminen muista yhtiöistä
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Vedettäessä aseta opastimien väleiksi: {ORANGE}{STRING} ruutu(a)
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Päätyökalupalkin sijainti: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :vasen
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :keskellä
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :oikea
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Ikkunan kiinniottosäde: {ORANGE}{STRING} piks.
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Ikkunan kiinniottosäde: {ORANGE}pois päältä
+
+STR_CONFIG_PATCHES_GUI :{BLACK}Käyttöliittymä
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Rakentaminen
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Ajoneuvot
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Asemat
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Talous
+STR_CONFIG_PATCHES_AI :{BLACK}Kilpailijat
+
+STR_CONFIG_PATCHES_DISABLED :pois käytöstä
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Muuta asetusarvo
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Osa allaolevista oletushuoltoväleistä ei ole yhteensopivia valitun asetuksen kanssa! 5-90{NBSP}% ja 30-800 päivää ovat oikein.
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}Käytä uutta reitinetsijää (YAPF) laivoille: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}Käytä uutta reitinetsijää (YAPF) autoille: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}Käytä uutta reitinetsijää (YAPF) junille: {ORANGE}{STRING}
+
+STR_TEMPERATE_LANDSCAPE :lauhkea maasto
+STR_SUB_ARCTIC_LANDSCAPE :pohjoinen maasto
+STR_SUB_TROPICAL_LANDSCAPE :subtrooppinen maasto
+STR_TOYLAND_LANDSCAPE :Lelumaan maasto
+
+STR_CHEATS :{WHITE}Huijaukset
+STR_CHEATS_TIP :{BLACK}Valintaruudut osoittavat, oletko käyttänyt huijausta aiemmin.
+STR_CHEATS_WARNING :{BLACK}Varoitus! Olet juuri pettämässä kanssakilpailijoitasi. Pidä mielessä, että tällainen häväistys pidetään mielessä ikuisuuden ajan.
+STR_CHEAT_MONEY :{LTBLUE}Anna lisää rahaa: {CURRENCY64}
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Pelaa pelaajana: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Taikapuskutraktori (siirrä teollisuutta yms.): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Tunnelit voivat mennä ristiin: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Rakenna tauon aikana: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Suihkukoneet eivät syöksy (usein) pienille lentokentille: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Vaihda ilmastoa: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Muuta päiväystä: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}Muuntuvat tuotantoarvot: {ORANGE}{STRING}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}Kohde: {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Kohde: {WAYPOINT}, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :Kierrä reittipisteen {WAYPOINT} kautta
+STR_GO_NON_STOP_TO_WAYPOINT :Mene pysäht. pisteen {WAYPOINT} kautta
+
+STR_WAYPOINTNAME_CITY :Reittipiste: {TOWN}
+STR_WAYPOINTNAME_CITY_SERIAL :Reittipiste: {TOWN} #{COMMA}
+STR_LANDINFO_WAYPOINT :Reittipiste
+
+STR_WAYPOINT :{WHITE}Reittipiste
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Valitse reittipisteen tyyppi
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}Muokkaa reittipisteen nimeä
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Reittipisteen nimeä ei voi muuttaa...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Muunna raide reittipisteeksi.
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Junien reittipistettä ei voi rakentaa tähän...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Junien reittipistettä ei voi poistaa...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Rakenna rautatiet käyttäen Autorail-tilaa.
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}...tässä skenaariossa ei ole kaupunkeja.
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}Haluatko todella luoda satunnaisen maaston?
+STR_MANY_RANDOM_TOWNS :{BLACK}Monta satunnaista kaupunkia
+STR_RANDOM_TOWNS_TIP :{BLACK}Peitä kartta satunnaisesti sijoitetuilla kaupungeilla.
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Monta satunnaista teollisuusaluetta
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Peitä kartta satunnaisesti sijoitetuilla teollisuusalueilla.
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Teollisuusaluetta ei voi luoda...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Avaa maastonmuokkaustyökalupalkki maan kohottamiseen/madaltamiseen, puiden istuttamiseen, jne.
+STR_LANDSCAPING_TOOLBAR :{WHITE}Maastonmuokkaus
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Tasoita maata
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Sattumanvaraisia puita
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}Aseta sattumanvaraisia puita
+
+STR_CANT_BUILD_CANALS :{WHITE}Kanaalia ei voi rakentaa tähän...
+STR_BUILD_CANALS_TIP :{BLACK}Rakenna kanaali
+STR_LANDINFO_CANAL :Kanaali
+
+STR_CANT_BUILD_LOCKS :{WHITE}Sulkua ei voi rakentaa tähän...
+STR_BUILD_LOCKS_TIP :{BLACK}Rakenna sulku
+STR_LANDINFO_LOCK :Sulku
+
+STR_BUOY_IS_IN_USE :{WHITE}...poiju on käytössä!
+
+STR_LANDINFO_COORDS :{BLACK}Koordinaatit: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Aseman osaa ei voi poistaa...
+STR_CANT_CONVERT_RAIL :{WHITE}Raidetyyppiä ei voi muuntaa...
+STR_CONVERT_RAIL_TIP :{BLACK}Muunna/päivitä raidetyyppi.
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Vedä junan veturi tähän myydäksesi koko junan.
+
+STR_DRAG_DROP :{BLACK}Vedä&pudota
+STR_STATION_DRAG_DROP :{BLACK}Rakenna asema vetämällä ja pudottamalla.
+STR_SELECT_STATION_CLASS_TIP :{BLACK}Valitse asemaluokka
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Valitse asematyyppi
+
+STR_FAST_FORWARD :{BLACK}Nopeuta peliä
+STR_MESSAGE_HISTORY :{WHITE}Viestihistoria
+STR_MESSAGE_HISTORY_TIP :{BLACK}Lista viimeisimmistä uutisviesteistä.
+STR_MESSAGES_DISABLE_ALL :{BLACK}Kaikki pois päältä
+STR_MESSAGES_ENABLE_ALL :{BLACK}Kaikki päälle
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Rakenna hiilikaivos.
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Istuta metsä.
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Rakenna öljylautta.
+STR_CONSTRUCT_FARM_TIP :{BLACK}Rahoita maatila.
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Rakenna kuparikaivos.
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Poraa öljyä.
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Rakenna kultakaivos.
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Rakenna timanttikaivos.
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Rakenna rautakaivos.
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Rahoita hedelmäviljelmää.
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Rahoita kumiviljelmää.
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Rahoita lähdettä.
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Istuta hattarametsä.
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}Rahoita paristomaatila.
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Poraa limsaa.
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Rahoita muovilähteitä.
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Rakenna kuplageneraattori.
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Rahoita toffeelouhosta.
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Rakenna sokerikaivos.
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Teollisuusala
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA}{NBSP}% kuljetettu)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA}%/{COMMA}% kuljetettu)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}...liian lähellä toista teollisuutta.
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Sovita juna kuljettamaan erityyppistä rahtia.
+STR_RAIL_REFIT_VEHICLE :{BLACK}Sovita juna
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Valitse junan rahtityyppi
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Sovita juna kuljettamaan valittua rahtityyppiä.
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Junaa ei voi sovittaa...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Huoltovälit ovat prosentteina: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Aloita tuotanto
+
+TEMP_AI_IN_PROGRESS :{WHITE}Tervetuloa käyttämään uutta tekoälyä (kehitysversio). Ongelmia voi esiintyä, ja kun sellainen tulee vastaan, ota kuvankaappaus ja lähetä se keskustelualueelle. Pidä hauskaa!
+TEMP_AI_ACTIVATED :{WHITE}Varoitus: uusi tekoäly on vielä alpha-koodia! Tällä hetkellä vain rekat ja linja-autot toimivat!
+TEMP_AI_MULTIPLAYER :{WHITE}Varoitus: toteutus on edelleen kokeellinen (käyttää uutta tekoälyä). Ongelmailmoitukset: truelight@openttd.org.
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Moninpeli
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Pelaajan nimi
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}Pelaajat tunnistetaan ja erotetaan toisistaan nimien avulla.
+STR_NETWORK_CONNECTION :{BLACK}Yhteys:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Valitse Internet-peli tai paikallisverkkopeli
+
+STR_NETWORK_START_SERVER :{BLACK}Käynnistä palvelin
+STR_NETWORK_START_SERVER_TIP :{BLACK}Käynnistä oma palvelin.
+
+STR_NETWORK_GAME_NAME :{BLACK}Nimi
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Pelin nimi.
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Kieli, palvelimen versio, jne.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Napsauta peliä luettelossa valitaksesi
+
+STR_NETWORK_FIND_SERVER :{BLACK}Etsi palvelin
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Etsi palvelin verkosta.
+STR_NETWORK_ADD_SERVER :{BLACK}Lisää palvelin
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Lisää palvelin listaan, joka käydään läpi aina uusia pelejä haettaessa.
+STR_NETWORK_ENTER_IP :{BLACK}Syötä palvelimen IP-osoite
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Pelaajia
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Pelaajia pelissä/enintään.
+STR_NETWORK_GAME_INFO :{SILVER}PELITIEDOT
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Pelaajat: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Kieli: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Ruudusto: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Kartan koko: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}Palvelimen versio: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}Palvelimen osoite: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Aloitusvuosi: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Päivämäärä: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Salasanasuojattu!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}PALVELIN KIINNI
+STR_NETWORK_SERVER_FULL :{SILVER}PALVELIN TÄYNNÄ
+STR_NETWORK_VERSION_MISMATCH :{SILVER}VERSIO EI TÄSMÄÄ
+
+STR_NETWORK_JOIN_GAME :{BLACK}Liity peliin
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}Aloita uusi peli
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Pelin nimi:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}Nimi näytetään muille pelaajille moninpelivalikossa.
+STR_NETWORK_SET_PASSWORD :{BLACK}Aseta salasana
+STR_NETWORK_PASSWORD_TIP :{BLACK}Jos peliin ei halua ulkopuolisia, voi sen suojata salasanalla.
+STR_NETWORK_SELECT_MAP :{BLACK}Valitse kartta:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}Mitä karttaa haluat pelata?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}Pelaajien enimmäismäärä:
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Pelaajien enimmäismäärä. Pelissä voi olla myös vähemmän pelaajia.
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :Lähiverkko
+STR_NETWORK_INTERNET :Internet
+STR_NETWORK_LAN_INTERNET :Lähiverkko/Internet
+STR_NETWORK_INTERNET_ADVERTISE :Internet (mainosta)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 pelaajaa
+STR_NETWORK_1_PLAYERS :1 pelaaja
+STR_NETWORK_2_PLAYERS :2 pelaajaa
+STR_NETWORK_3_PLAYERS :3 pelaajaa
+STR_NETWORK_4_PLAYERS :4 pelaajaa
+STR_NETWORK_5_PLAYERS :5 pelaajaa
+STR_NETWORK_6_PLAYERS :6 pelaajaa
+STR_NETWORK_7_PLAYERS :7 pelaajaa
+STR_NETWORK_8_PLAYERS :8 pelaajaa
+STR_NETWORK_9_PLAYERS :9 pelaajaa
+STR_NETWORK_10_PLAYERS :10 pelaajaa
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}Yhtiöiden enimmäismäärä:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Rajoita yhtiöiden määrää palvelimella
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}Katsojien enimmäismäärä:
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Rajoita katsojien määrää palvelimella
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Puhuttu kieli:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Toiset pelaajat tietävät tästä, mitä kieltä palvelimella puhutaan.
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}Aloita peli
+STR_NETWORK_START_GAME_TIP :{BLACK}Aloita uusi verkkopeli skenaariolla tai satunnaisella kartalla.
+STR_NETWORK_LOAD_GAME :{BLACK}Lataa peli
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Jatka aiemmin tallennettua moninpeliä (muista liittyä oikeana pelaajana).
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :mikä tahansa
+STR_NETWORK_LANG_ENGLISH :englanti
+STR_NETWORK_LANG_GERMAN :saksa
+STR_NETWORK_LANG_FRENCH :ranska
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Moninpeliaula
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Valmistaudu yhdistämään: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}Lista pelissä olevista yhtiöistä. Voit joko liittyä yhteen tai perustaa omasi.
+STR_NETWORK_NEW_COMPANY :{BLACK}Uusi yhtiö
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Perusta uusi yhtiö.
+STR_NETWORK_SPECTATE_GAME :{BLACK}Seuraa peliä
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Seuraa pelin kulkua.
+STR_NETWORK_JOIN_COMPANY :{BLACK}Liity yhtiöön
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Auta tämän yhtiön hallinnassa.
+STR_NETWORK_REFRESH :{BLACK}Päivitä
+STR_NETWORK_REFRESH_TIP :{BLACK}Päivitä palvelintiedot.
+
+STR_NETWORK_COMPANY_INFO :{SILVER}YHTIÖN TIEDOT
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Yhtiön nimi: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}Perustettu: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}Yhtiön arvo: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Nykyinen kate: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Viime vuoden tulot: {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}Suorite: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}Liikenneväl.: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Asemat: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Pelaajat: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}Yhdistetään...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) Yhdistetään...
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Valtuutetaan..
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Odotetaan..
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Ladataan karttaa..
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Muokataan dataa..
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) Rekisteröidään..
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Haetaan pelitiedot..
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Haetaan yhtiötiedot...
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} pelaaja{P "" a} jonossa
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} kt ladattu
+
+STR_NETWORK_DISCONNECT :{BLACK}Pura yhteys
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Syötä annettava rahamäärä
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Palvelin on suojattu. Anna salasana
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Yhtiö on suojattu. Anna salasana
+STR_NETWORK_CLIENT_LIST :{WHITE}Asiakaslista
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE} Verkkolaitteita ei löytynyt tai käännetty ilman ENABLE_NETWORK-valintaa.
+STR_NETWORK_ERR_NOSERVER :{WHITE} Verkkopelejä ei löytynyt.
+STR_NETWORK_ERR_NOCONNECTION :{WHITE} Palvelin ei vastannut pyyntöön.
+STR_NETWORK_ERR_DESYNC :{WHITE} Verkkopelin tahdistus epäonnistui.
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} Verkkopeliyhteys katkesi.
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} Palvelimen pelitallennetta ei voi ladata.
+STR_NETWORK_ERR_SERVER_START :{WHITE} Palvelinta ei voitu käynnistää.
+STR_NETWORK_ERR_CLIENT_START :{WHITE} Yhdistäminen ei onnistunut.
+STR_NETWORK_ERR_TIMEOUT :{WHITE} Yhteys #{NUM} aikakatkaistiin.
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE} Teimme protokollavirheen ja yhteys katkesi.
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE} Tämän asiakkaan revisio ei vastaa palvelimen revisiota.
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} Väärä salasana.
+STR_NETWORK_ERR_SERVER_FULL :{WHITE} Palvelin on täynnä.
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} Sinut on suljettu pois palvelimelta.
+STR_NETWORK_ERR_KICKED :{WHITE} Sinut potkittiin pihalle palvelimelta.
+STR_NETWORK_ERR_CHEATER :{WHITE} Huijaaminen ei ole sallittua tällä palvelimella.
+
+STR_NETWORK_ERR_LEFT :poistui pelistä
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :yleinen virhe
+STR_NETWORK_ERR_CLIENT_DESYNC :tahdistusvirhe
+STR_NETWORK_ERR_CLIENT_SAVEGAME :karttaa ei voitu ladata
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :yhteys katkesi
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :protokollavirhe
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :ei valtuutettu
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :vastaanotettiin omituinen paketti
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :väärä revisio
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :nimi on jo käytössä
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :väärä pelisalasana
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :väärä player-id DoCommand:ssa
+STR_NETWORK_ERR_CLIENT_KICKED :palvelin potki pihalle
+STR_NETWORK_ERR_CLIENT_CHEATER :yritti käyttää huijausta
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :palvelin täynnä
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :liittyi peliin
+STR_NETWORK_GIVE_MONEY :antoi yhtiöllesi rahaa ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :annoit rahaa toiselle pelaajalle ({STRING}, {CURRENCY})
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Joukkue] :
+STR_NETWORK_CHAT_COMPANY :[Joukkue] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Joukkue] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[Yksityinen] :
+STR_NETWORK_CHAT_CLIENT :[Yksityinen] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[Yksityinen] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[Kaikki] :
+STR_NETWORK_CHAT_ALL :[Kaikki] {STRING}: {GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :vaihtoi nimensä:
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE} Palvelin sulki istunnon
+STR_NETWORK_SERVER_REBOOT :{WHITE} Palvelin käynnistyy uudelleen...{}Odota, ole hyvä...
+
+STR_NETWORK_SERVER :Palvelin
+STR_NETWORK_CLIENT :Pelaaja
+STR_NETWORK_SPECTATORS :Katsojat
+
+STR_NETWORK_CLIENTLIST_NONE :(tyhjä)
+STR_NETWORK_CLIENTLIST_KICK :Potkaise
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Anna rahaa
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Puhu kaikille
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Puhu yhtiölle
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Yksityinen viesti
+
+
+STR_NETWORK_SEND :{BLACK}Lähetä
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}Kartan x-koko: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Kartan y-koko: {ORANGE}{STRING}
+
+
+##### PNG-MAP-Loader
+
+STR_PNGMAP_ERROR :{WHITE}Maastoa ei voida ladata PNG-tiedostosta...
+STR_PNGMAP_ERR_FILE_NOT_FOUND :{WHITE}...tiedostoa ei löydy.
+STR_PNGMAP_ERR_IMAGE_TYPE :{WHITE}...kuvan tyyppiä ei voida muuttaa. Tarvitaan 8- tai 24-bittinen PNG-kuva.
+STR_PNGMAP_ERR_MISC :{WHITE}...tapahtui tunnistamaton virhe. (todennäköisesti viallinen tiedosto)
+
+STR_BMPMAP_ERROR :{WHITE}Maastoa ei voida ladata BMP:stä...
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}...kuvan tyyppiä ei voida muuntaa.
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Kustannus: {CURRENCY}
+STR_0801_COST :{RED}Kustannus: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Tulo: {CURRENCY}
+STR_0803_INCOME :{GREEN}Tulo: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Siirrä: {CURRENCY}
+STR_FEEDER :{YELLOW}Siirrä: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Arvioitu kustannus: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Arvioitu tulo: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Maata ei voi korottaa...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Maata ei voi madaltaa...
+STR_080A_ROCKS :Kalliota
+STR_080B_ROUGH_LAND :Epätasaista maata
+STR_080C_BARE_LAND :Paljasta maata
+STR_080D_GRASS :Ruohikkoa
+STR_080E_FIELDS :Peltoja
+STR_080F_SNOW_COVERED_LAND :Lumenpeittämää maata
+STR_0810_DESERT :Aavikkoa
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Maa viettää väärään suuntaan.
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Mahdoton ratayhdistelmä.
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}Kaivuualue vahingoittaisi tunnelia.
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Merenpinta on jo saavutettu.
+STR_1004_TOO_HIGH :{WHITE}Liian korkea.
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Ei kelvollista rautatietä.
+STR_1007_ALREADY_BUILT :{WHITE}...se on jo rakennettu.
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Rautatie pitää poistaa ensin.
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Rautatien rakentaminen
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Sähköradan rakentaminen
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Yksiraiteisen rakentaminen
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}MagLevin rakentaminen
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Valitse rautatiesilta.
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Veturitallia ei voi rakentaa...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Rautatieasemaa ei voi rakentaa...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Opastinta ei voi rakentaa...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Rautatietä ei voi rakentaa...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Rautatietä ei voi poistaa tästä...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Opastinta ei voi poistaa tästä...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Veturitallin suunta
+STR_1015_RAILROAD_CONSTRUCTION :Rautatien rakentaminen
+STR_TOOLB_ELRAIL_CONSTRUCTION :Sähköradan rakentaminen
+STR_1016_MONORAIL_CONSTRUCTION :Yksiraiteisen rakentaminen
+STR_1017_MAGLEV_CONSTRUCTION :MagLevin rakentaminen
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Rakenna rautateitä.
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Rakenna veturitalli (junien rakentamista ja huoltoa varten).
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Rakenna rautatieasema.
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Rakenna rautatieopastimia.
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Rakenna rautatiesilta.
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Rakenna rautatietunneli.
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Rautatien ja opastimien rakentaminen/poisto päälle/pois.
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Sillan valinta - napsauta valittua siltaa rakentaaksesi sen.
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Valitse veturitallin suunta.
+STR_1021_RAILROAD_TRACK :Rautatie
+STR_1023_RAILROAD_TRAIN_DEPOT :Veturitalli
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...alueen omistaa toinen yhtiö.
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :Rautatie tavallisin opastimin
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :Rautatie esiopastimin
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :Rautatie poistumisopastimin
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :Rautatie yhdistetyin opastimin
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Tie pitää siirtää ensin.
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Tietyöt ovat käynnissä.
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Tien rakentaminen
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Valitse maantiesilta
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Tietä ei voi rakentaa...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Tietä ei voi poistaa tästä...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Huoltoaseman suunta
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Huoltoasemaa ei voi rakentaa...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Linja-autoasemaa ei voi rakentaa...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Lastauslaituria ei voi rakentaa...
+STR_180A_ROAD_CONSTRUCTION :Tien rakentaminen
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Rakenna tieosuus.
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Rakenna huoltoasema (ajoneuvojen rakentamista ja huoltoa varten)
+STR_180D_BUILD_BUS_STATION :{BLACK}Rakenna linja-autoasema
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Rakenna lastauslaituri
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Rakenna maantiesilta
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Rakenna maantietunneli
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Tien rakentaminen/siirtäminen päälle/pois
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Valitse huoltoaseman suunta.
+STR_1814_ROAD :Tie
+STR_1815_ROAD_WITH_STREETLIGHTS :Tie katuvaloilla
+STR_1816_TREE_LINED_ROAD :Puilla reunustettu tie
+STR_1817_ROAD_VEHICLE_DEPOT :Huoltoasema
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :Tasoristeys
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Kaupungit
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Rakennus täytyy tuhota ensin.
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}Asukasluku: {ORANGE}{COMMA}{BLACK} Taloja: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Nimeä kaupunki
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Kaupunkia ei voi uudelleennimetä...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN}: paikallisviranomaiset kieltäytyvät.
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Kaupunkien nimet - napsauta nimeä keskittääksesi päänäkymän kaupunkiin.
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Keskitä päänäkymä kaupungin sijaintiin.
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Vaihda kaupungin nimeä.
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Matkustajia viime kuussa: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Postia viime kuussa: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Korkea toimistorakennus
+STR_2010_OFFICE_BLOCK :Tomistorakennus
+STR_2011_SMALL_BLOCK_OF_FLATS :Pienasuntokortteli
+STR_2012_CHURCH :Kirkko
+STR_2013_LARGE_OFFICE_BLOCK :Suuri toimistorakennus
+STR_2014_TOWN_HOUSES :Kaupungin talot
+STR_2015_HOTEL :Hotelli
+STR_2016_STATUE :Patsas
+STR_2017_FOUNTAIN :Suihkulähde
+STR_2018_PARK :Puisto
+STR_2019_OFFICE_BLOCK :Toimistorakennus
+STR_201A_SHOPS_AND_OFFICES :Kauppoja ja toimistoja
+STR_201B_MODERN_OFFICE_BUILDING :Nykyaikainen toimistorakennus
+STR_201C_WAREHOUSE :Varasto
+STR_201D_OFFICE_BLOCK :Toimistorakennus
+STR_201E_STADIUM :Stadion
+STR_201F_OLD_HOUSES :Vanhoja taloja
+STR_2020_LOCAL_AUTHORITY :{BLACK}Viranomaiset
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Näytä tietoja paikallisviranomaisista.
+STR_2022_LOCAL_AUTHORITY :{WHITE}{TOWN}: viranomaiset
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Kuljetusyhtiön arvioinnit:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Tuet
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Tarjolla olevat tuet:
+STR_2027_FROM_TO :{ORANGE}{STRING} välille {STRING}-{STRING}
+STR_2028_BY :{YELLOW} ({DATE_SHORT})
+STR_202A_NONE :{ORANGE}Ei mitään
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Käytetyt tuet-
+STR_202C_FROM_TO :{ORANGE}{STRING} välille {STATION}-{STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, {DATE_SHORT} asti)
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}Tuki päättynyt:{}{}{STRING} väli {STRING} - {STRING} ei sisällä enää tukia.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Tuki vedetty pois:{}{}{STRING} kuljetuspalvelu välille {STATION}-{STATION} ei ole enää tuettu.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Tuki tarjottu:{}{}Ensimmäinen {STRING}kuljetus välillä {STRING} - {STRING} saa vuoden mittaisen tuen paikallisviranomaisilta!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Tuki myönnetty yhtiölle {COMPANY}!{}{}{STRING}kuljetus välillä {STATION}-{STATION} tuottaa 50{NBSP}% enemmän seuraavan vuoden ajan!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Tuki myönnetty yhtiölle {COMPANY}!{}{}{STRING}kuljetus välillä {STATION}-{STATION} tuottaa tuplaten seuraavan vuoden ajan!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Tuki myönnetty yhtiölle {COMPANY}!{}{}{STRING}kuljetus välillä {STATION}-{STATION} tuottaa kolminkertaisesti seuraavan vuoden ajan!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Tuki myönnetty yhtiölle {COMPANY}!{}{}{STRING}kuljetus välillä {STATION}-{STATION} tuottaa nelinkertaisesti seuraavan vuoden ajan!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN}: paikallisviranomaiset eivät salli toisen lentokentän rakentamista tähän kaupunkiin.
+STR_2036_COTTAGES :Mökkiä
+STR_2037_HOUSES :Taloa
+STR_2038_FLATS :Asuntoa
+STR_2039_TALL_OFFICE_BLOCK :Korkeata toimistorakennusta
+STR_203A_SHOPS_AND_OFFICES :Kauppaa ja toimistoa
+STR_203B_SHOPS_AND_OFFICES :Kauppaa ja toimistoa
+STR_203C_THEATER :Teatteri
+STR_203D_STADIUM :Stadion
+STR_203E_OFFICES :Toimistoa
+STR_203F_HOUSES :Taloa
+STR_2040_CINEMA :Elokuvateatteri
+STR_2041_SHOPPING_MALL :Kauppakeskus
+STR_2042_DO_IT :{BLACK}Sijoita
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}Luettelo kaupungissa tehtävistä asioista - napsauta kohdetta saadaksesi lisätietoja.
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Suorita valittu toiminto.
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Saatavilla olevat toiminnot:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Pieni mainoskampanja
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Keskikokoinen mainoskampanja
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Suuri mainoskampanja
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Rahoita paikallista tienrakentamista
+STR_204A_BUILD_STATUE_OF_COMPANY :Rakenna patsas yhtiön omistajasta
+STR_204B_FUND_NEW_BUILDINGS :Rahoita uusia rakennuksia
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Osta yksinoikeudet kuljetuksiin
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Lahjo viranomaisia
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Tee aloite pienestä mainoskampanjasta hoikutellaksesi lisää matkustajia ja rahtia kuljetuspalveluihisi.{} Kustannus: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Tee aloite keskikokoisesta mainoskampanjasta hoikutellaksesi lisää matkustajia ja rahtia kuljetuspalveluihisi.{} Kustannus: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Tee aloite suuresta mainoskampanjasta hoikutellaksesi lisää matkustajia ja rahtia kuljetuspalveluihisi.{} Kustannus: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} Rahoita kaupungin tieverkon rakentamista. Aiheuttaa huomattavaa häiriötä tieliikenteessä kuuden kuukauden ajan.{} Kustannus: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Rakenna patsas yhtiösi kunniaksi.{} Kustannus: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Rahoita uusien kaupparakennusten rakentamista kaupungissa.{} Kustannus: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Osta vuoden yksinoikeudet kaupungin liikennöintiin. Paikallisviranomaiset eivät salli muiden yhtiöiden kuljettaa matkustajia ja rahtia.{} Kustannus: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Lahjo viranomaisia lisätäksesi arviotasi; rangaistus voi olla kuitenkin suuri, jos jäät kiinni.{} Kulu: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}{TOWN}: liikenne on kaaoksessa!{}{}{COMPANY} rahoittaa katujen kunnostuksen; autoilijoille odotettavissa kuusi kuukautta kurjuutta!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (rakennusvaiheessa)
+STR_2059_IGLOO :Iglu
+STR_205A_TEPEES :Tiipiitä
+STR_205B_TEAPOT_HOUSE :Teesalonki
+STR_205C_PIGGY_BANK :Säästöpossu
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN} ({STRING})
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Maastonmuokkaus
+STR_2800_PLANT_TREES :Istuta puita
+STR_2801_PLACE_SIGN :Aseta kyltti
+STR_2802_TREES :{WHITE}Puita
+STR_2803_TREE_ALREADY_HERE :{WHITE}...puu on jo tässä.
+STR_2804_SITE_UNSUITABLE :{WHITE}...paikka sopimaton.
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Puuta ei voi istuttaa...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...liian monta kylttiä.
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Kylttiä ei voi sijoittaa...
+STR_280A_SIGN :Kyltti
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Muokkaa kyltin tekstiä.
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Kyltin nimeä ei voi muuttaa...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Valitse istutettava puutyyppi.
+STR_280E_TREES :Puita
+STR_280F_RAINFOREST :Sademetsää
+STR_2810_CACTUS_PLANTS :Kaktuksia
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Rautatieaseman valinta
+STR_3001_AIRPORT_SELECTION :{WHITE}Lentokentän valinta
+STR_3002_ORIENTATION :{BLACK}Suunta
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Ratojen määrä
+STR_3004_PLATFORM_LENGTH :{BLACK}Asemalaiturin pituus
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Liian lähellä toista rautatieasemaa.
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Liitä yhteen useampi kuin yksi olemassaoleva asema/lastausalue.
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}Liian monta asemaa/lastausaluetta kaupungissa.
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}Liian monta asemaa/lastausaluetta.
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Liian monta linja-autopysäkkiä.
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}Liian monta lastauslaituria.
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Liian lähellä toista asemaa/lastausaluetta.
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Rautatieasema pitää tuhota ensin.
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Liian lähellä toista lentokenttää.
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Lentokenttä pitää tuhota ensin.
+
+STR_3030_RENAME_STATION_LOADING :Nimeä asema/lastausalue
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Asemaa ei voi nimetä uudelleen...
+STR_3032_RATINGS :{BLACK}Arviot
+STR_3033_ACCEPTS :{BLACK}Ottaa vastaan
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}Paikallinen arvio kuljetuspalvelusta:
+
+############ range for rating starts
+STR_3035_APPALLING :Tyrmistyttävä
+STR_3036_VERY_POOR :Hyvin kehno
+STR_3037_POOR :Kehno
+STR_3038_MEDIOCRE :Keskinkertainen
+STR_3039_GOOD :Hyvä
+STR_303A_VERY_GOOD :Oikein hyvä
+STR_303B_EXCELLENT :Mainio
+STR_303C_OUTSTANDING :Loistava
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}{NBSP}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} ei enää ota vastaan {STRING}.
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} ei enää ota vastaan {STRING} tai {STRING}.
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} ottaa nyt vastaan {STRING}.
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} ottaa nyt vastaan {STRING} ja {STRING}.
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Linja-autoaseman suunta
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Lastauslaiturin suunta
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Linja-autoasema pitää tuhota ensin.
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Lastauslaituri pitää tuhota ensin.
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} asema{P "" a}
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Ei mitään -
+STR_304B_SITE_UNSUITABLE :{WHITE}...paikka sopimaton.
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Liian lähellä toista satamaa.
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Satama pitää tuhota ensin.
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Valitse rautatieaseman suunta.
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Valitse asemalaiturien määrä rautatieasemalle.
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Valitse rautatieaseman pituus.
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Valitse linja-autoaseman suunta.
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Valitse lastauslaiturin suunta.
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Keskitä näkymä aseman sijaintiin.
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Näytä aseman arviot.
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Muuta aseman nimi.
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Näytä luettelo vastaanotettavasta rahdista.
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Asemien nimet - napsauta nimeä keskittääksesi näkymän asemaan.
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Valitse lentokentän koko/tyyppi.
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :Rautatieasema
+STR_305F_AIRCRAFT_HANGAR :Lentokonesuoja
+STR_3060_AIRPORT :Lentokenttä
+STR_3061_TRUCK_LOADING_AREA :Lastauslaituri
+STR_3062_BUS_STATION :Linja-autoasema
+STR_3063_SHIP_DOCK :Satama
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Korosta ehdotetun tontin vaikutusalue.
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Älä korosta ehdotetun tontin vaikutusaluetta.
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Vaikutusalueen korostus
+STR_3068_DOCK :{WHITE}Satama
+STR_3069_BUOY :Poiju
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...poiju on tiellä.
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...asema liian levittäytynyt.
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...epäyhdenmukaiset asemat poissa käytöstä.
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Pidä CTRL painettuna valitaksesi enemmän kuin yhden tavaran
+
+STR_UNDEFINED :(määrittelemätön)
+STR_STAT_CLASS_DFLT :Oletusasema
+STR_STAT_CLASS_WAYP :Rastit
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Telakan suunn.
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...se pitää rakentaa veteen.
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Telakkaa ei voi rakentaa...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Valitse telakan suunta
+STR_3804_WATER :Vettä
+STR_3805_COAST_OR_RIVERBANK :Rannikko tai joenpenkka
+STR_3806_SHIP_DEPOT :Telakka
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...veteen ei voi rakentaa.
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Tallenna peli
+STR_4001_LOAD_GAME :{WHITE}Lataa peli
+STR_4002_SAVE :{BLACK}Tallenna
+STR_4003_DELETE :{BLACK}Poista
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} megatavu{P "" a} vapaana
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Asemaa ei voi lukea.
+STR_4007_GAME_SAVE_FAILED :{WHITE}Tallennus epäonnistui.
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Tiedostoa ei voi poistaa.
+STR_4009_GAME_LOAD_FAILED :{WHITE}Lataus epäonnistui.
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}Lista asemista, hakemistoista ja tallennetuista peleistä.
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Valittu nimi pelitallenteelle.
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Poista valittu pelitallenne.
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Tallenna nykyinen peli käyttäen valittua nimeä.
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Valitse uusi pelityyppi
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Valitse skenaario (vihreä), alkuasetettu peli (sininen) tai satunnainen peli.
+STR_4010_GENERATE_RANDOM_NEW_GAME :Luo uusi satunnainen peli
+STR_4011_LOAD_HEIGHTMAP :{WHITE}Lataa korkeuskartta
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} on tiellä.
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :Hiilikaivos
+STR_4803_POWER_STATION :Sähkölaitos
+STR_4804_SAWMILL :Saha
+STR_4805_FOREST :Metsä
+STR_4806_OIL_REFINERY :Öljynjalostamo
+STR_4807_OIL_RIG :Öljylautta
+STR_4808_FACTORY :Tehdas
+STR_4809_PRINTING_WORKS :Kirjapaino
+STR_480A_STEEL_MILL :Teräsvalimo
+STR_480B_FARM :Maatila
+STR_480C_COPPER_ORE_MINE :Kuparikaivos
+STR_480D_OIL_WELLS :Öljykenttä
+STR_480E_BANK :Pankki
+STR_480F_FOOD_PROCESSING_PLANT :Ruoanjalostamo
+STR_4810_PAPER_MILL :Paperitehdas
+STR_4811_GOLD_MINE :Kultakaivos
+STR_4812_BANK :Pankki
+STR_4813_DIAMOND_MINE :Jalokivikaivos
+STR_4814_IRON_ORE_MINE :Rautakaivos
+STR_4815_FRUIT_PLANTATION :Hedelmäviljelmä
+STR_4816_RUBBER_PLANTATION :Kumiviljelmä
+STR_4817_WATER_SUPPLY :Lähde
+STR_4818_WATER_TOWER :Vesitorni
+STR_4819_FACTORY :Tehdas
+STR_481A_FARM :Maatila
+STR_481B_LUMBER_MILL :Hakkuualue
+STR_481C_COTTON_CANDY_FOREST :Hattarametsä
+STR_481D_CANDY_FACTORY :Karkkitehdas
+STR_481E_BATTERY_FARM :Paristomaatila
+STR_481F_COLA_WELLS :Limsakenttä
+STR_4820_TOY_SHOP :Lelukauppa
+STR_4821_TOY_FACTORY :Lelutehdas
+STR_4822_PLASTIC_FOUNTAINS :Muovilähteet
+STR_4823_FIZZY_DRINK_FACTORY :Sihijuomatehdas
+STR_4824_BUBBLE_GENERATOR :Kuplageneraattori
+STR_4825_TOFFEE_QUARRY :Toffeelouhos
+STR_4826_SUGAR_MINE :Sokerikaivos
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Tarvitsee: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Tarvitsee: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Tarvitsee: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Tuotto viime kuussa:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}{NBSP}% kuljetettu)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Keskitä päänäkymä teollisuuden sijaintiin.
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Uusi {STRING} rakennetaan kaupungin {TOWN} lähistölle!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Uusi {STRING} istutetaan kaupungin {TOWN} lähistölle!
+STR_482F_COST :{BLACK}Kustannus: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Teollisuustyyppiä ei voi rakentaa tähän...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...metsää voi istuttaa vain lumirajan yläpuolelle.
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY}: sulkeminen uhkaavan lähellä!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}{INDUSTRY}: toimitusongelmista johtuen sulkeminen uhkaavan lähellä!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}{INDUSTRY}: puiden puutteesta johtuen sulkeminen uhkaavan lähellä!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY}: tuotantoa lisätään!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}{INDUSTRY}: uusi hiilijuonne löytynyt!{}Tuotannon odotetaan kaksinkertaistuvan!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}{INDUSTRY}: uusia öljyvaroja löydetty!{}Tuotannon odotetaan kaksinkertaistuvan!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}{INDUSTRY}: viljelytapoja parannettu! Tuotannon odotetaan kaksinkertaistuvan!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}{INDUSTRY}: tuotanto vähenee 50{NBSP}%:lla.
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}{INDUSTRY}: hyönteisparvet aiheuttavat tuhoa!{}Tuotanto vähenee 50{NBSP}%:lla.
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...voidaan asettaa vain kartan reunoille.
+STR_INDUSTRY_PROD_GOUP ::{BLACK}{BIGFONT}{1:INDUSTRY} tuottaa {0:STRING} {2:COMMA}{NBSP}% entistä enemmän!
+STR_INDUSTRY_PROD_GODOWN ::{BLACK}{BIGFONT}{1:INDUSTRY} tuottaa {0:STRING} {2:COMMA}{NBSP}% entistä vähemmän!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Juna on tunnelissa.
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Ajoneuvo on tunnelissa.
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Toinen tunneli on tiellä.
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Maata ei voi kaivaa tunnelin toisessa päässä.
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Tunneli pitää tuhota ensin.
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Silta pitää tuhota ensin.
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Ei voi aloittaa ja lopettaa samasta paikkasta.
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Sillan alla pitää olla tasaista maata tai vettä.
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}Alku- ja päätepisteen pitää olla linjassa.
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Tontti on sopimaton tunnelinsuulle.
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Riippusilta, terästä
+STR_500F_GIRDER_STEEL :Palkki, terästä
+STR_5010_CANTILEVER_STEEL :Ulokepalkki, terästä
+STR_5011_SUSPENSION_CONCRETE :Riippusilta, betonia
+STR_5012_WOODEN :Puuta
+STR_5013_CONCRETE :Betonia
+STR_5014_TUBULAR_STEEL :Putkirakenne, terästä
+STR_BRIDGE_TUBULAR_SILICON :Putkirakenne, piitä
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Siltaa ei voi rakentaa...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Tunnelia ei voi rakentaa...
+STR_5017_RAILROAD_TUNNEL :Rautatietunneli
+STR_5018_ROAD_TUNNEL :Maantietunneli
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Teräksinen rautatieriippusilta
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Teräksinen rautatiepalkkisilta
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Teräksinen rautatieulokepalkkisilta
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Vahvennettu betoninen rautatieriippusilta
+STR_501F_WOODEN_RAIL_BRIDGE :Puinen rautatiesilta
+STR_5020_CONCRETE_RAIL_BRIDGE :Betoninen rautatiesilta
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Teräksinen maantieriippusilta
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Teräksinen maantiepalkkisilta
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Teräksinen maantieulokepalkkisilta
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Vahvennettu betoninen maantieriippusilta
+STR_5025_WOODEN_ROAD_BRIDGE :Puinen maantiesilta
+STR_5026_CONCRETE_ROAD_BRIDGE :Betoninen maantiesilta
+STR_5027_TUBULAR_RAIL_BRIDGE :Putkirakenteinen rautatiesilta
+STR_5028_TUBULAR_ROAD_BRIDGE :Putkirakenteinen maantiesilta
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Objekti on tiellä.
+STR_5801_TRANSMITTER :Lähetin
+STR_5802_LIGHTHOUSE :Majakka
+STR_5803_COMPANY_HEADQUARTERS :Yhtiön päärakennus
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...yhtiön päärakennus on tiellä.
+STR_5805_COMPANY_OWNED_LAND :Yhtiön omistamaa maata
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Maa-aluetta ei voi hankkia...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...omistat sen jo!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Nimetön
+STR_SV_TRAIN_NAME :Juna {COMMA}
+STR_SV_ROADVEH_NAME :Ajoneuvo {COMMA}
+STR_SV_SHIP_NAME :Laiva {COMMA}
+STR_SV_AIRCRAFT_NAME :Lentokone {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :Pohjois-{STRING}
+STR_SV_STNAME_SOUTH :Etelä-{STRING}
+STR_SV_STNAME_EAST :Itä-{STRING}
+STR_SV_STNAME_WEST :Länsi-{STRING}
+STR_SV_STNAME_CENTRAL :Keski-{STRING}
+STR_SV_STNAME_TRANSFER :{STRING}, vaihtoasema
+STR_SV_STNAME_HALT :{STRING}, seisake
+STR_SV_STNAME_VALLEY :{STRING}, laakso
+STR_SV_STNAME_HEIGHTS :{STRING}, kukkulat
+STR_SV_STNAME_WOODS :{STRING}, metsä
+STR_SV_STNAME_LAKESIDE :{STRING}, järvenranta
+STR_SV_STNAME_EXCHANGE :{STRING}, vaihde ##
+STR_SV_STNAME_AIRPORT :{STRING}, lentokenttä
+STR_SV_STNAME_OILFIELD :{STRING}, öljykenttä
+STR_SV_STNAME_MINES :{STRING}, kaivokset
+STR_SV_STNAME_DOCKS :{STRING}, satama
+STR_SV_STNAME_BUOY_1 :{STRING}, poiju 1
+STR_SV_STNAME_BUOY_2 :{STRING}, poiju 2
+STR_SV_STNAME_BUOY_3 :{STRING}, poiju 3
+STR_SV_STNAME_BUOY_4 :{STRING}, poiju 4
+STR_SV_STNAME_BUOY_5 :{STRING}, poiju 5
+STR_SV_STNAME_BUOY_6 :{STRING}, poiju 6
+STR_SV_STNAME_BUOY_7 :{STRING}, poiju 7
+STR_SV_STNAME_BUOY_8 :{STRING}, poiju 8
+STR_SV_STNAME_BUOY_9 :{STRING}, poiju 9
+STR_SV_STNAME_ANNEXE :{STRING}, sivuasema
+STR_SV_STNAME_SIDINGS :{STRING}, sivuraide
+STR_SV_STNAME_BRANCH :{STRING}, haarautuma
+STR_SV_STNAME_UPPER :Ylä-{STRING}
+STR_SV_STNAME_LOWER :Ala-{STRING}
+STR_SV_STNAME_HELIPORT :{STRING}, helikopterikenttä
+STR_SV_STNAME_FOREST :{STRING}, metsä
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Vaikeusaste
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Tallenna
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Helppo
+STR_6802_MEDIUM :{BLACK}Keskitaso
+STR_6803_HARD :{BLACK}Vaikea
+STR_6804_CUSTOM :{BLACK}Oma
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}Vastustajien enimmäismäärä: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Vastustajien aloitusaika: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}Kaupunkien määrä: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}Teollisuuden määrä: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Lainan enimmäismäärä alussa: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Korko alussa: {ORANGE}{COMMA}{NBSP}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Ajoneuvojen käyttökustannukset: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Vastustajien rakennusnopeus: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Vastustajien älykkyys: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Ajoneuvojen hajoaminen: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Tukikerroin: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Rakentamisen kustannus: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Maaston tyyppi: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Meren/järvien määrä: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Talous: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Junien peruutus: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Onnettomuudet: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Kaupunginvaltuuston asenne alueen uudelleenjärjestelyyn: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :Ei mitään
+STR_6816_LOW :Matala
+STR_6817_NORMAL :Normaali
+STR_6818_HIGH :Korkea
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Hyvin hidas
+STR_681C_SLOW :Hidas
+STR_681D_MEDIUM :Keskitaso
+STR_681E_FAST :Nopea
+STR_681F_VERY_FAST :Hyvin nopea
+STR_VERY_LOW :Hyvin matala
+STR_6820_LOW :Matala
+STR_6821_MEDIUM :Keskitaso
+STR_6822_HIGH :Korkea
+STR_6823_NONE :Ei mitään
+STR_6824_REDUCED :Vähennetty
+STR_6825_NORMAL :Tavallinen
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Hyvin tasainen
+STR_682B_FLAT :Tasainen
+STR_682C_HILLY :Kukkulainen
+STR_682D_MOUNTAINOUS :Vuoristoinen
+STR_682E_STEADY :Vakaa
+STR_682F_FLUCTUATING :Vaihteleva
+STR_6830_IMMEDIATE :Välitön
+STR_6831_3_MONTHS_AFTER_PLAYER :3 kuukautta pelaajan jälkeen
+STR_6832_6_MONTHS_AFTER_PLAYER :6 kuukautta pelaajan jälkeen
+STR_6833_9_MONTHS_AFTER_PLAYER :9 kuukautta pelaajan jälkeen
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :Radan päässä ja asemilla
+STR_6835_AT_END_OF_LINE_ONLY :Vain radan päässä
+STR_6836_OFF :Päällä
+STR_6837_ON :Pois
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Näytä pistetaulukko
+STR_6839_PERMISSIVE :Salliva
+STR_683A_TOLERANT :Suvaitseva
+STR_683B_HOSTILE :Vihamielinen
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Pelaaja {COMMA})
+STR_7004_NEW_FACE :{BLACK}Uudet kasvot
+STR_7005_COLOR_SCHEME :{BLACK}Väriteema
+STR_7006_COLOR_SCHEME :{GOLD}Väriteema:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Uusi tunnusväri
+STR_7008_COMPANY_NAME :{BLACK}Yhtiön nimi
+STR_7009_PRESIDENT_NAME :{BLACK}Pääjohtajan nimi
+STR_700A_COMPANY_NAME :Yhtiön nimi
+STR_700B_PRESIDENT_S_NAME :Pääjohtajan nimi
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Yhtiön nimeä ei voi muuttaa...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Pääjohtajan nimeä ei voi muuttaa...
+STR_700E_FINANCES :{WHITE}Talous, {COMPANY} {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Menot/tulot
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Rakentaminen
+STR_7012_NEW_VEHICLES :{GOLD}Uudet ajoneuvot
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Junien käyttökust.
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Autojen käyttökust.
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Lentokoneiden käyttökust.
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Laivojen käyttökust.
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Omaisuudenhallinta
+STR_7018_TRAIN_INCOME :{GOLD}Junien tulot
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Ajoneuvojen tulot
+STR_701A_AIRCRAFT_INCOME :{GOLD}Lentokoneiden tulot
+STR_701B_SHIP_INCOME :{GOLD}Laivojen tulot
+STR_701C_LOAN_INTEREST :{GOLD}Lainan korko
+STR_701D_OTHER :{GOLD}Muuta
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Yhteensä:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Tulokuvaaja
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Käyttökatekuvaaja
+STR_7026_BANK_BALANCE :{WHITE}Tilin saldo
+STR_7027_LOAN :{WHITE}Laina
+STR_MAX_LOAN :{WHITE}Laina enimmillään: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}Lainaa {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Lyhennä lainaa {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...suurin sallittu lainan suuruus on {CURRENCY}.
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Lisälainan otto ei onnistu...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...ei lainaa maksettavana.
+STR_702E_REQUIRED :{WHITE}...tarvitaan {CURRENCY}.
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Lainaa ei voi lyhentää...
+STR_INSUFFICIENT_FUNDS :{WHITE}Pankista lainattua rahaa ei voi antaa pois...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Valitse uudet kasvot pääjohtajalle.
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Muuta yhtiön ajoneuvoammattikuntaa.
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Muuta pääjohtajan nimeä.
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Muuta yhtiön nimeä.
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Valitse tunnusväri.
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Ota lisää lainaa.
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Lyhennä lainaa.
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(pääjohtaja)
+STR_7038_INAUGURATED :{GOLD}Avattu: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Liikennevälineet:
+STR_TRAINS :{WHITE}{COMMA} juna{P "" a}
+STR_ROAD_VEHICLES :{WHITE}{COMMA} ajoneuvo{P "" a}
+STR_AIRCRAFT :{WHITE}{COMMA} lentokone{P "" tta}
+STR_SHIPS :{WHITE}{COMMA} laiva{P "" a}
+STR_7042_NONE :{WHITE}Ei mitään
+STR_7043_FACE_SELECTION :{WHITE}Kasvojen valinta
+STR_7044_MALE :{BLACK}Mies
+STR_7045_FEMALE :{BLACK}Nainen
+STR_7046_NEW_FACE :{BLACK}Uudet kasvot
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Peruuta uusien kasvojen valinta.
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Hyväksy uusien kasvojen valinta.
+STR_7049_SELECT_MALE_FACES :{BLACK}Valitse miehen kasvot.
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Valitse naisen kasvot.
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Luo satunnaiset kasvot.
+STR_704C_KEY :{BLACK}Selite
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Näytä kuvaajan selite
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Selite yhtiön kuvaajiin
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Napsauta tässä laittaaksesi yhtiön merkinnän graafissa päälle/pois.
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Rahtia kuljetettu (yksikköä)
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Yhtiön suoritearvio (enimmäisarvio=1000)
+STR_7052_COMPANY_VALUES :{WHITE}Yhtiöiden arvot
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Yhtiökilpataulukko
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}Kuljetusyhtiö vaikeuksissa!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} myydään tai julistetaan konkurssiin, ellei suorituskyky lisäänny pian!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(pääjohtaja)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Kuljetusyhtiöiden sulautuminen!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} on myyty yhtiölle {COMPANY} hintaan {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Etsimme kuljetusyhtiötä, joka ottaisi haltuunsa yhtiömme{}{}Haluatko ostaa yhtiön {COMPANY} hintaan {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Konkurssi!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} on suljettu velkojien toimesta ja kaikki omaisuus on myyty pois!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}Uusi kuljetusyhtiö perustettu!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} aloittaa rakentamisen kaupugin {TOWN} lähistölle!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Yhtiötä ei voi ostaa...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Rahtimaksutaksat
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Päivää kauttakulussa
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Maksu 10 yksikön (tai 10.000 litran) rahdin kuljettamisesta 20 ruudun päähän.
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Rahtityypin kuvaaja päälle/pois
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Insinööri
+STR_7067_TRAFFIC_MANAGER :Liikennepäällikkö
+STR_7068_TRANSPORT_COORDINATOR :Kuljetusjohtaja
+STR_7069_ROUTE_SUPERVISOR :Reittityönjohtaja
+STR_706A_DIRECTOR :Johtaja
+STR_706B_CHIEF_EXECUTIVE :Osastopäällikkö
+STR_706C_CHAIRMAN :Puheenjohtaja
+STR_706D_PRESIDENT :Pääjohtaja
+STR_706E_TYCOON :Pohatta
+STR_706F_BUILD_HQ :{BLACK}Rakenna päämaja
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Rakenna yhtiön päärakennus / näytä yhtiön päärakennus.
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Rakenna yhtiön päärakennus muualle, hintana 1{NBSP}% yhtiön arvosta.
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Yhtiön päärakennusta ei voi rakentaa...
+STR_7072_VIEW_HQ :{BLACK}Näytä päämaja
+STR_RELOCATE_HQ :{BLACK}Sijoita päämaja
+STR_COMPANY_PASSWORD :{BLACK}Salasana
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Salasanalla voit suojata yhtiösi, jotta kukaan vieras ei pääse liittymään.
+STR_SET_COMPANY_PASSWORD :Aseta yhtiön salasana
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}Maailmanlaajuinen laskukausi!{}{}Rahoitusasiantuntijat pelkäävät pahinta talouden laskiessa!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Laskukausi ohi!{}{}Kaupankäynnin käänne parempaan lisää luottamusta teollisuuteen talouden vahvistuessa!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Suuri/pieni ikkunan koko
+STR_7076_COMPANY_VALUE :{GOLD}Yhtiön arvo: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Osta 25{NBSP}%:n osuus yhtiöstä
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Myy 25{NBSP}%:n osuus yhtiöstä
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Osta 25{NBSP}%:n osuus tästä yhtiöstä
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Myy 25{NBSP}%:n osuus tästä yhtiöstä
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Tästä yhtiöstä ei voi ostaa 25{NBSP}%:n osuutta...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}Tästä yhtiöstä ei voi myydä 25{NBSP}%:n osuutta...
+STR_707D_OWNED_BY :{WHITE}({COMMA}{NBSP}%:n omistus: {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}{NBSP}%:n omistus: {COMPANY}{} {COMMA}{NBSP}%:n omistus {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}Yhtiön {COMPANY} on ottanut haltuun {COMPANY}!
+STR_7080_PROTECTED :{WHITE}Tällä yhtiöllä ei ole vielä osakkeita...
+
+STR_LIVERY_DEFAULT :
+STR_LIVERY_STEAM :Höyryveturi
+STR_LIVERY_DIESEL :Dieselveturi
+STR_LIVERY_ELECTRIC :Sähköveturi
+STR_LIVERY_MONORAIL :Yksiraiteinen veturi
+STR_LIVERY_MAGLEV :Maglev-veturi
+STR_LIVERY_DMU :DMU
+STR_LIVERY_EMU :EMU
+STR_LIVERY_PASSENGER_WAGON_STEAM :Matkustajavaunu (höyry)
+STR_LIVERY_PASSENGER_WAGON_DIESEL :Matkustajavaunu (diesel)
+STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Matkustajavaunu (sähkö)
+STR_LIVERY_FREIGHT_WAGON :Rahtivaunu
+STR_LIVERY_BUS :Linja-auto
+STR_LIVERY_TRUCK :Kuorma-auto
+STR_LIVERY_PASSENGER_SHIP :Matkustajalautta
+STR_LIVERY_FREIGHT_SHIP :Rahtilaiva
+STR_LIVERY_HELICOPTER :Helikopteri
+STR_LIVERY_SMALL_PLANE :Pieni lentokone
+STR_LIVERY_LARGE_PLANE :Suuri lentokone
+
+STR_LIVERY_GENERAL_TIP :{BLACK}Näytä yleiset väriteemat
+STR_LIVERY_TRAIN_TIP :{BLACK}Näytä junan väriteemat
+STR_LIVERY_ROADVEH_TIP :{BLACK}Näytä tieajoneuvojen väriteemat
+STR_LIVERY_SHIP_TIP :{BLACK}Näytä laivojen väriteemat
+STR_LIVERY_AIRCRAFT_TIP :{BLACK}Näytä lentokoneiden väriteemat
+STR_LIVERY_PRIMARY_TIP :{BLACK}Valitse valitulle teemalle ensisijainen väri
+STR_LIVERY_SECONDARY_TIP :{BLACK}Valitse valitulle teemalle toissijainen väri
+STR_LIVERY_PANEL_TIP :{BLACK}Valitse muutettava väriteema, tai valitse useita CTRL pohjassa. Paina valintalaatikkoa valitaksesi teeman
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (höyry)
+STR_8001_MJS_250_DIESEL :MJS 250 (diesel)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut Diesel
+STR_8006_POWERNAUT_DIESEL :Powernaut Diesel
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (höyry)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (höyry)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (höyry)
+STR_800A_SH_8P_STEAM :SH '8P' (höyry)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (diesel)
+STR_800C_DASH_DIESEL :'Dash' (diesel)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (diesel)
+STR_800E_UU_37_DIESEL :UU '37' (diesel)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (diesel)
+STR_8010_CS_4000_DIESEL :CS 4000 (diesel)
+STR_8011_CS_2400_DIESEL :CS 2400 (diesel)
+STR_8012_CENTENNIAL_DIESEL :Centennial (diesel)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (diesel)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (diesel)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (diesel)
+STR_8016_SH_125_DIESEL :SH '125' (diesel)
+STR_8017_SH_30_ELECTRIC :SH '30' (sähkö)
+STR_8018_SH_40_ELECTRIC :SH '40' (sähkö)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (sähkö)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (sähkö)
+STR_801B_PASSENGER_CAR :Matkustajavaunu
+STR_801C_MAIL_VAN :Postivaunu
+STR_801D_COAL_CAR :Kivihiilivaunu
+STR_801E_OIL_TANKER :Öljyvaunu
+STR_801F_LIVESTOCK_VAN :Karjavaunu
+STR_8020_GOODS_VAN :Tavaravaunu
+STR_8021_GRAIN_HOPPER :Viljavaunu
+STR_8022_WOOD_TRUCK :Raakapuuvaunu
+STR_8023_IRON_ORE_HOPPER :Malmivaunu
+STR_8024_STEEL_TRUCK :Teräskelavaunu
+STR_8025_ARMORED_VAN :Panssaroitu vaunu
+STR_8026_FOOD_VAN :Ruokavaunu
+STR_8027_PAPER_TRUCK :Paperivaunu
+STR_8028_COPPER_ORE_HOPPER :Malmivaunu
+STR_8029_WATER_TANKER :Vesivaunu
+STR_802A_FRUIT_TRUCK :Hedelmävaunu
+STR_802B_RUBBER_TRUCK :Kumivaunu
+STR_802C_SUGAR_TRUCK :Sokerivaunu
+STR_802D_COTTON_CANDY_HOPPER :Hattaravaunu
+STR_802E_TOFFEE_HOPPER :Toffeevaunu
+STR_802F_BUBBLE_VAN :Kuplavaunu
+STR_8030_COLA_TANKER :Limsavaunu
+STR_8031_CANDY_VAN :Karkkivaunu
+STR_8032_TOY_VAN :Leluvaunu
+STR_8033_BATTERY_TRUCK :Paristovaunu
+STR_8034_FIZZY_DRINK_TRUCK :Sihijuomavaunu
+STR_8035_PLASTIC_TRUCK :Muovivaunu
+STR_8036_X2001_ELECTRIC :'X2001' (sähkö)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (sähkö)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :Matkustajavaunu
+STR_803A_MAIL_VAN :Postivaunu
+STR_803B_COAL_CAR :Hiilivaunu
+STR_803C_OIL_TANKER :Öljyvaunu
+STR_803D_LIVESTOCK_VAN :Karjavaunu
+STR_803E_GOODS_VAN :Tavaravaunu
+STR_803F_GRAIN_HOPPER :Viljavaunu
+STR_8040_WOOD_TRUCK :Raakapuuvaunu
+STR_8041_IRON_ORE_HOPPER :Malmivaunu
+STR_8042_STEEL_TRUCK :Teräskelavaunu
+STR_8043_ARMORED_VAN :Panssaroitu vaunu
+STR_8044_FOOD_VAN :Ruokavaunu
+STR_8045_PAPER_TRUCK :Paperivaunu
+STR_8046_COPPER_ORE_HOPPER :Malmivaunu
+STR_8047_WATER_TANKER :Vesivaunu
+STR_8048_FRUIT_TRUCK :Hedelmävaunu
+STR_8049_RUBBER_TRUCK :Kumivaunu
+STR_804A_SUGAR_TRUCK :Sokerivaunu
+STR_804B_COTTON_CANDY_HOPPER :Hattaravaunu
+STR_804C_TOFFEE_HOPPER :Toffeevaunu
+STR_804D_BUBBLE_VAN :Kuplavaunu
+STR_804E_COLA_TANKER :Limsavaunu
+STR_804F_CANDY_VAN :Karkkivaunu
+STR_8050_TOY_VAN :Leluvaunu
+STR_8051_BATTERY_TRUCK :Paristovaunu
+STR_8052_FIZZY_DRINK_TRUCK :Sihijuomavaunu
+STR_8053_PLASTIC_TRUCK :Muovivaunu
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (sähkö)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (sähkö)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (sähkö)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (sähkö)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :Matkustajavaunu
+STR_805A_MAIL_VAN :Postivaunu
+STR_805B_COAL_CAR :Hiilivaunu
+STR_805C_OIL_TANKER :Öljyvaunu
+STR_805D_LIVESTOCK_VAN :Karjavaunu
+STR_805E_GOODS_VAN :Tavaravaunu
+STR_805F_GRAIN_HOPPER :Viljavaunu
+STR_8060_WOOD_TRUCK :Raakapuuvaunu
+STR_8061_IRON_ORE_HOPPER :Malmivaunu
+STR_8062_STEEL_TRUCK :Teräskela
+STR_8063_ARMORED_VAN :Panssaroitu vaunu
+STR_8064_FOOD_VAN :Ruokavaunu
+STR_8065_PAPER_TRUCK :Paperivaunu
+STR_8066_COPPER_ORE_HOPPER :Malmivaunu
+STR_8067_WATER_TANKER :Vesivaunu
+STR_8068_FRUIT_TRUCK :Hedelmävaunu
+STR_8069_RUBBER_TRUCK :Kumivaunu
+STR_806A_SUGAR_TRUCK :Sokerivaunu
+STR_806B_COTTON_CANDY_HOPPER :Hattaravaunu
+STR_806C_TOFFEE_HOPPER :Toffeevaunu
+STR_806D_BUBBLE_VAN :Kuplavaunu
+STR_806E_COLA_TANKER :Limsavaunu
+STR_806F_CANDY_VAN :Karkkivaunu
+STR_8070_TOY_VAN :Leluvaunu
+STR_8071_BATTERY_TRUCK :Paristovaunu
+STR_8072_FIZZY_DRINK_TRUCK :Sihijuomavaunu
+STR_8073_PLASTIC_TRUCK :Muovivaunu
+STR_8074_MPS_REGAL_BUS :MPS Regal -linja-auto
+STR_8075_HEREFORD_LEOPARD_BUS :Hereford Leopard -linja-auto
+STR_8076_FOSTER_BUS :Foster-linja-auto
+STR_8077_FOSTER_MKII_SUPERBUS :Foster MkII -superlinja-auto
+STR_8078_PLODDYPHUT_MKI_BUS :Ploddyphut MkI -linja-auto
+STR_8079_PLODDYPHUT_MKII_BUS :Ploddyphut MkII -linja-auto
+STR_807A_PLODDYPHUT_MKIII_BUS :Ploddyphut MkIII -linja-auto
+STR_807B_BALOGH_COAL_TRUCK :Balogh-hiilirekka
+STR_807C_UHL_COAL_TRUCK :Uhl-hiilirekka
+STR_807D_DW_COAL_TRUCK :DW-hiilirekka
+STR_807E_MPS_MAIL_TRUCK :MPS-postirekka
+STR_807F_REYNARD_MAIL_TRUCK :Reynard-postirekka
+STR_8080_PERRY_MAIL_TRUCK :Perry-postirekka
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :MightyMover-postirekka
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Powernaught-postirekka
+STR_8083_WIZZOWOW_MAIL_TRUCK :Wizzowow-postirekka
+STR_8084_WITCOMBE_OIL_TANKER :Witcombe-öljysäiliörekka
+STR_8085_FOSTER_OIL_TANKER :Foster-öljysäiliörekka
+STR_8086_PERRY_OIL_TANKER :Perry-öljysäiliörekka
+STR_8087_TALBOTT_LIVESTOCK_VAN :Talbott-karjarekka
+STR_8088_UHL_LIVESTOCK_VAN :Uhl-karjarekka
+STR_8089_FOSTER_LIVESTOCK_VAN :Foster-karjarekka
+STR_808A_BALOGH_GOODS_TRUCK :Balogh-tavararekka
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Craighead-tavararekka
+STR_808C_GOSS_GOODS_TRUCK :Goss-tavararekka
+STR_808D_HEREFORD_GRAIN_TRUCK :Hereford-viljarekka
+STR_808E_THOMAS_GRAIN_TRUCK :Thomas-viljarekka
+STR_808F_GOSS_GRAIN_TRUCK :Goss-viljarekka
+STR_8090_WITCOMBE_WOOD_TRUCK :Witcombe-tukkirekka
+STR_8091_FOSTER_WOOD_TRUCK :Foster-tukkirekka
+STR_8092_MORELAND_WOOD_TRUCK :Moreland-tukkirekka
+STR_8093_MPS_IRON_ORE_TRUCK :MPS-rautamalmirekka
+STR_8094_UHL_IRON_ORE_TRUCK :Uhl-rautamalmirekka
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Chippy-rautamalmirekka
+STR_8096_BALOGH_STEEL_TRUCK :Balogh-teräsrekka
+STR_8097_UHL_STEEL_TRUCK :Uhl-teräsrekka
+STR_8098_KELLING_STEEL_TRUCK :Kelling-teräsrekka
+STR_8099_BALOGH_ARMORED_TRUCK :Balogh-panssarirekka
+STR_809A_UHL_ARMORED_TRUCK :Uhl-panssarirekka
+STR_809B_FOSTER_ARMORED_TRUCK :Foster-panssarirekka
+STR_809C_FOSTER_FOOD_VAN :Foster-ruokarekka
+STR_809D_PERRY_FOOD_VAN :Perry-ruokarekka
+STR_809E_CHIPPY_FOOD_VAN :Chippy-ruokarekka
+STR_809F_UHL_PAPER_TRUCK :Uhl-paperirekka
+STR_80A0_BALOGH_PAPER_TRUCK :Balogh-paperirekka
+STR_80A1_MPS_PAPER_TRUCK :MPS-paperirekka
+STR_80A2_MPS_COPPER_ORE_TRUCK :MPS-kuparirekka
+STR_80A3_UHL_COPPER_ORE_TRUCK :Uhl-kuparirekka
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Goss-kuparirekka
+STR_80A5_UHL_WATER_TANKER :Uhl-vesisäiliörekka
+STR_80A6_BALOGH_WATER_TANKER :Balogh-vesisäiliörekka
+STR_80A7_MPS_WATER_TANKER :MPS-vesisäiliörekka
+STR_80A8_BALOGH_FRUIT_TRUCK :Balogh-hedelmärekka
+STR_80A9_UHL_FRUIT_TRUCK :Uhl-hedelmärekka
+STR_80AA_KELLING_FRUIT_TRUCK :Kelling-hedelmärekka
+STR_80AB_BALOGH_RUBBER_TRUCK :Balogh-kumirekka
+STR_80AC_UHL_RUBBER_TRUCK :Uhl-kumirekka
+STR_80AD_RMT_RUBBER_TRUCK :RMT-kumirekka
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :MightyMover-sokerirekka
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Powernaught-sokerirekka
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Wizzowow-sokerirekka
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :MightyMover-kolarekka
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Powernaught-kolarekka
+STR_80B3_WIZZOWOW_COLA_TRUCK :Wizzowow-kolarekka
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :MightyMover-hattararekka
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Powernaught-hattararekka
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Wizzowow-hattararekka
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :MightyMover-toffeerekka
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Powernaught-toffeerekka
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Wizzowow-toffeerekka
+STR_80BA_MIGHTYMOVER_TOY_VAN :MightyMover-lelupakettirekka
+STR_80BB_POWERNAUGHT_TOY_VAN :Powernaught-lelupakettirekka
+STR_80BC_WIZZOWOW_TOY_VAN :Wizzowow-lelupakettirekka
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :MightyMover-lelurekka
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Powernaught-lelurekka
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Wizzowow-lelurekka
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :MightyMover-paristorekka
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Powernaught-paristorekka
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Wizzowow-paristorekka
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :MightyMover-sihijuomarekka
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Powernaught-sihijuomarekka
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Wizzowow-sihijuomarekka
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :MightyMover-muovirekka
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Powernaught-muovirekka
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Wizzowow-muovirekka
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :MightyMover-kuplarekka
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Powernaught-kuplarekka
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Wizzowow-kuplarekka
+STR_80CC_MPS_OIL_TANKER :MPS-öljytankkeri
+STR_80CD_CS_INC_OIL_TANKER :CS-Inc.-öljytankkeri
+STR_80CE_MPS_PASSENGER_FERRY :MPS-matkustajalautta
+STR_80CF_FFP_PASSENGER_FERRY :FFP-matkustajalautta
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Bakewell 300 -ilmatyynyalus
+STR_80D1_CHUGGER_CHUG_PASSENGER :Chugger-Chug -matkustajalautta
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Shivershake-matkustajalautta
+STR_80D3_YATE_CARGO_SHIP :Yate-rahtilaiva
+STR_80D4_BAKEWELL_CARGO_SHIP :Bakewell-rahtilaiva
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Mightymover-rahtilaiva
+STR_80D6_POWERNAUT_CARGO_SHIP :Powernaut-rahtilaiva
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Tricario -helikopteri
+STR_80FE_GURU_X2_HELICOPTER :Guru X2 -helikopteri
+STR_80FF_POWERNAUT_HELICOPTER :Powernaut-helikopteri
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Viesti ajoneuvovalmistajalta
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}Olemme juuri suunnitelleet uuden {STRING} - oletteko kiinnostunut vuoden yksinoikeutetusta kokeilusta, jotta näemme, miten tuote suoriutuu, ennen kuin julkistamme sen yleiseen käyttöön?
+STR_8102_RAILROAD_LOCOMOTIVE :veturin
+STR_8103_ROAD_VEHICLE :ajoneuvon
+STR_8104_AIRCRAFT :lentokoneen
+STR_8105_SHIP :laivan
+STR_8106_MONORAIL_LOCOMOTIVE :yksiraiteisen veturin
+STR_8107_MAGLEV_LOCOMOTIVE :maglev-veturin
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}{TOWN}: veturitalli
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Kaupungilaiset juhlivat . . .{}Ensimmäinen juna saapuu asemalle ({STATION})!
+STR_8802_DETAILS :{WHITE}{STRING} (yksityiskohdat)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Juna on tiellä.
+STR_8804 :{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8806_GO_TO :Asemalle {STATION}
+STR_8807_GO_TO_TRANSFER :Mene asemalle {STATION} (Siirrä ja ota rahti)
+STR_8808_GO_TO_UNLOAD :Mene asemalle {STATION} (Pura rahti)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Mene asemalle {STATION} (Siirrä ja jätä tyhjäksi)
+STR_880A_GO_TO_LOAD :Mene asemalle {STATION} (Lastaa)
+STR_880B_GO_TO_TRANSFER_LOAD :Mene asemalle {STATION} (Siirrä ja odota täyttä rahtia)
+STR_880C_GO_NON_STOP_TO :Mene tauotta asemalle {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Mene tauotta asemalle {STATION} (Siirrä ja ota rahti)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Mene tauotta asemalle {STATION} (Pura rahti)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Mene tauotta asemalle {STATION} (Siirrä ja jätä tyhjäksi)
+STR_8810_GO_NON_STOP_TO_LOAD :Mene tauotta asemalle {STATION} (Lastaa)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Mene tauotta asemalle {STATION} (Siirrä ja odota täyttä rahtia)
+STR_GO_TO_TRAIN_DEPOT :Mene kaupungin {TOWN} veturitalliin
+STR_SERVICE_AT_TRAIN_DEPOT :Huolto veturitallilla ({TOWN})
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Mene pysähtymättä veturitalliin ({TOWN})
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Huolto pysähtymättä veturitallilla ({TOWN})
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}Suuntana veturitalli ({TOWN})
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}Suuntana veturitalli ({TOWN}), {VELOCITY}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE :{LTBLUE}Huolto {TOWN} Varikko
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE_VEL :{LTBLUE}Huolto{TOWN} Varikko, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (virheellinen käsky)
+
+STR_UNKNOWN_DESTINATION :tuntematon päämäärä
+STR_8812_EMPTY :{LTBLUE}Tyhjä
+STR_8813_FROM :{LTBLUE}{CARGO} asemalta {STATION}
+STR_FROM_MULT :{LTBLUE}{CARGO} asemalta {STATION} (x{NUM})
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}Juna {COMMA} odottaa veturitallilla
+STR_8815_NEW_VEHICLES :{BLACK}Uusia liikennevälineitä
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Juna on liian pitkä.
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Junia voi muunnella vain, kun ne ovat pysähdyksissä veturitallilla.
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} junaa
+
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Uusi juna
+STR_NEW_ELRAIL_VEHICLES :{WHITE}Uusi sähköjuna
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Uusi yksiraidejuna
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Uusi MagLev-juna
+STR_ALL_AVAIL_RAIL_VEHICLES :{WHITE}Ratakulkuneuvot
+
+STR_881F_BUILD_VEHICLE :{BLACK}Rakenna yksikkö
+STR_CLONE_ROAD_VEHICLE :{BLACK}Kloonaa ajoneuvo
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}Tämä rakentaa kopion ajoneuvosta. Control-click jakaa komennot
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Tämä rakentaa kopion ajoneuvosta. Paina tätä nappia ja sen jälkeen ajoneuvoa varikon sisä- tai ulkopuolella. Control-click jakaa komennot
+STR_CLONE_TRAIN :{BLACK}Kloonaa juna
+STR_CLONE_TRAIN_INFO :{BLACK}Tämä rakentaa kopion junasta ja kaikista sen vaunuista. Control-click jakaa komennot
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}Tämä rakentaa kopion junasta ja kaikista sen vaunuista. Paina tätä nappia ja sen jälkeen junaa varikon sisä- tai ulkopuolella. Control-click jakaa komennot
+STR_8820_RENAME :{BLACK}Nimeä
+STR_8823_SKIP :{BLACK}Ohita
+STR_8824_DELETE :{BLACK}Poista
+STR_8825_NON_STOP :{BLACK}Tauotta
+STR_8826_GO_TO :{BLACK}Mene
+STR_8827_FULL_LOAD :{BLACK}Täysi lasti
+STR_8828_UNLOAD :{BLACK}Pura lasti
+STR_REFIT :{BLACK}Sovita
+STR_REFIT_TIP :{BLACK}Valitse rahdin tyyppi jolla tämä käsky uudistetaan. CTRL+klikkaus poistaa uudistuksen
+STR_REFIT_ORDER :(Sovita {STRING})
+STR_8829_ORDERS :{WHITE}{VEHICLE} (aikataulu)
+STR_882A_END_OF_ORDERS :{SETX 10}- - aikataulun loppu - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}Huolto
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Yksikköä ei voi rakentaa...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Rakennettu: {LTBLUE}{NUM}{BLACK} Arvo: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Arvo: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}Lastataan/puretaan
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}Juna täytyy pysäyttää veturitallin sisällä
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Junan lähettäminen veturitalliin ei onnistu...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Ei enää tilaa pysähdyksille.
+STR_8832_TOO_MANY_ORDERS :{WHITE}Liian monta pysähdystä.
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Uutta pysähdystä ei voi lisätä...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Pysähdystä ei voi poistaa...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Pysähdystä ei voi muokata...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Liikennevälinettä ei voi poistaa...
+STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}Moottorivaunun takaosa seuraa aina etuosaansa
+STR_8838_N_A :-{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Yksikköä ei voi myydä...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Reittiä paikalliselle veturitallille ei löydy.
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Junaa ei voi pysäyttää/lähettää...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Huoltoväli: {LTBLUE}{COMMA} päivää{BLACK} Viimeisin huolto: {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Huoltoväli: {LTBLUE}{COMMA}%{BLACK} Viime huolto: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Junat - napsauta junaa saadaksesi tietoja.
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Rakenna uusia junia (tarvitaan veturitalli).
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Junat - napsauta junaa saadaksesi tietoja, vedä vaunu lisätäksesi/poistaaksesi junasta.
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Rakenna uusi yksikkö.
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Vedä yksikkö tähän myydäksesi sen.
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Keskitä näkymä veturitallin sijaintiin.
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Yksikön valintalista - napsauta kohteita saadaksesi tietoja.
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Rakenna valittu yksikkö.
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Nimeä yksikön tyyppi uudelleen.
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Valitun junan toiminnot - napsauta tässä pysäyttääksesi/lähettääksesi.
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Näytä junan aikataulu.
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Keskitä näkymä junan sijaintiin.
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Lähetä juna veturitalliin.
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Anna junalle lupa ohittaa punainen opastin.
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Käännä junan suunta.
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Näytä junan tiedot.
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Kasvata huoltoväliä.
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Pienennä huoltoväliä.
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Näytä kuljetettavan rahdin tiedot.
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Näytä yksikön tiedot.
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Näytä kunkin ajoneuvon kapasiteetti.
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Näytä junan kokonaiskapasiteetti, eritelty rahtityypin mukaan.
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Aikataulu - napsauta määräystä korostaaksesi.
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}Ohita nykyinen pysähdys ja aloita seuraava.
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Poista korostettu määräys.
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Tee korostetusta pysäkistä pysähtymätön.
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Lisää uusi pysähdys ennen valittua, tai lisää listan viimeiseksi.
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Aseta korostettu pysähdys pakottamaan ajoneuvon odottamaan täyttä lastausta.
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Aseta korostettu pysähdys pakottamaan ajoneuvo odottamaan purkua.
+STR_SERVICE_HINT :{BLACK}Ohita tämä määräys, ellei palvelua tarvita.
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}Uusi {STRING} saatavilla!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Kulu: {CURRENCY} Paino: {WEIGHT_S}{}Nopeus: {VELOCITY} Teho: {POWER}{}Käyttökustannukset: {CURRENCY}/vuosi{}Kapasiteetti: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}Rikki
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}Ikä: {LTBLUE}{STRING}{BLACK} Käyttökustannukset: {LTBLUE}{CURRENCY}/vuosi
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Paino: {LTBLUE}{WEIGHT_S} {BLACK}Teho: {LTBLUE}{POWER}{BLACK} Huippunopeus: {LTBLUE}{VELOCITY}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Tuotto tänä vuonna: {LTBLUE}{CURRENCY} (viime vuonna: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}Luotettavuus: {LTBLUE}{COMMA}% {BLACK}Hajoamisia viime huollon jälkeen: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Pysäytetty
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Junaa ei voi pakottaa jatkamaan opastimen ohi vaaratilanteessa...
+STR_8863_CRASHED :{RED}Kolaroitu!
+
+STR_8865_NAME_TRAIN :{WHITE}Nimeä juna
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}Junaa ei voi nimetä...
+STR_8867_NAME_TRAIN :{BLACK}Nimeä juna
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Junakolari!{}{COMMA} kuolee törmäyksen jälkeisessä tulipallossa.
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Junan suuntaa ei voi kääntää...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Nimeä juna(vaunu)n tyyppi uudelleen.
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Juna(vaunu)n tyyppiä ei voi uudelleennimetä...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Pakottaa tyhjentämään rahdin valitulla pysäkillä
+STR_886F_TRANSFER :{BLACK}Siirrä
+
+STR_TRAIN_STOPPING :{RED}Pysäytetään
+STR_TRAIN_STOPPING_VEL :{RED}Pysäytetään, {VELOCITY}
+STR_INCOMPATIBLE_RAIL_TYPES :Raiteet eivät ole yhteensopivia
+STR_TRAIN_NO_POWER :{RED}Ei virtaa
+STR_TRAIN_START_NO_CATENARY :Radasta puuttuu "catenary"; junaa ei voi käynnistää
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Ajoneuvo tiellä.
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} ajoneuvoa
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}{TOWN} huoltoasema
+STR_9004_NEW_VEHICLES :{BLACK}Uusia ajoneuvoja
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}Uusia ajoneuvoja
+STR_9007_BUILD_VEHICLE :{BLACK}Rakenna ajoneuvo
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Ajoneuvoa ei voi rakentaa...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (yksityiskohdat)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}Ikä: {LTBLUE}{STRING}{BLACK} Käyttökustanukset: {LTBLUE}{CURRENCY}/vuosi
+STR_900E_MAX_SPEED :{BLACK}Huippunopeus: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Tuottoa tänä vuonna: {LTBLUE}{CURRENCY} (viime vuonna: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}Toimintavarmuus: {LTBLUE}{COMMA}% {BLACK}Hajoamisia viime huollon jälkeen: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Rakennettu: {LTBLUE}{NUM}{BLACK} Arvo: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Kapasiteetti: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}...sen pitää olla pysähtyneenä huoltoasemalle.
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Ajoneuvoa ei voi myydä...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Ajoneuvoa ei voi pysäyttää/laitta liikkeelle...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}Ajoneuvo {COMMA} odottaa huoltoasemalla.
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}Suuntana huoltoasema, {TOWN}.
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}Suuntana huoltoasema, {TOWN}, {VELOCITY}.
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE :{LTBLUE}Huolto {TOWN} Varikko
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE_VEL :{LTBLUE}Huolto {TOWN} Varikko, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Ajoneuvon lähettäminen huoltoasemalle ei onnistu...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Paikallista huoltoasemaa ei löydy.
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Ajoneuvot - napsauta ajoneuvoja saadaksesi tietoja.
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Rakenna uusi ajoneuvo (tarvitaan huoltoasema).
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Nykyisen ajoneuvon toiminnot - napsauta tässä pysäyttääksesi/laittaaksesi liikkeelle.
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Näytä ajoneuvon aikataulu.
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Keskitä näkymä ajoneuvon sijaintiin.
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Lähetä ajoneuvo huoltoasemalle.
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Pakota ajoneuvo kääntymään ympäri.
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Näytä ajoneuvon tiedot.
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Ajoneuvot - napsauta ajoneuvoa saadaksesi tietoja.
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Rakenna uusi ajoneuvo.
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Vedä ajoneuvo tähän myydäksesi sen.
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Keskitä päänäkymä huoltoaseman sijaintiin.
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Ajoneuvon valintalista - napsauta ajoneuvoa saadaksesi tietoja.
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Rakenna valittu ajoneuvo.
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}Uusi ajoneuvo on saatavilla!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Kulu: {CURRENCY}{}Nopeus: {VELOCITY}{}Käyttökustannukset: {CURRENCY}/vuosi{}Kapasiteetti: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Nimeä ajoneuvo
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Ajoneuvoa ei voi nimetä...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Nimeä ajoneuvo
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Kaupunkilaiset juhlivat . . .{}Ensimmäinen linja-auto saapuu asemalle {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Kaupunkilaiset juhlivat . . .{}Ensimmäinen kuorma-auto saapuu asemalle {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}Ajoneuvokolari!{}Kuljettaja kuolee junaan törmäyksen jälkeisessä tulipallossa
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}Ajoneuvokolari!{}{COMMA} kuolee junaan törmäyksen jälkeisessä tulipallossa
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Ajoneuvoa ei voi pakottaa kääntymään ympäri...
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}Ei voi kääntää moniosaista ajoneuvoa
+STR_9034_RENAME :{BLACK}Nimeä
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Nimeä ajoneuvon tyyppi uudelleen
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Nimeä ajoneuvon tyyppi uudelleen
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Ajoneuvotyyppiä ei voi uudelleennimetä...
+STR_9038_GO_TO_ROADVEH_DEPOT :Aseta kohteeksi huoltoasema, {TOWN}
+STR_SERVICE_AT_ROADVEH_DEPOT :Huolto, kohteena huoltoasema, {TOWN}
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Muuta ajoneuvo rahtaamaan muuta rahtityyppiä.
+STR_REFIT_ROAD_VEHICLE :{BLACK}Korjaa ajoneuvo.
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Muuta ajoneuvo rahtaamaan korostettua rahtityyppiä.
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Ajoneuvoa ei voida korjata.
+STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Valitse ajoneuvolla ajettava rahti
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Sataman rakentaminen
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Sataman rakentaminen
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Satamaa ei voi rakentaa tähän...
+STR_9803_SHIP_DEPOT :{WHITE}{TOWN}, telakka
+STR_9804_NEW_SHIPS :{BLACK}Uusia laivoja
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} laivaa
+STR_9808_NEW_SHIPS :{WHITE}Uusia laivoja
+STR_9809_BUILD_SHIP :{BLACK}Rakenna laiva
+STR_CLONE_SHIP :{BLACK}Kloonaa laiva
+STR_CLONE_SHIP_INFO :{BLACK}Tämä rakentaa kopion laivasta. Control-click jakaa komennot
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}Tämä rakentaa kopion laivasta. Paina tätä nappia ja sen jälkeen laivaa telakan sisä- tai ulkopuolella. Control-click jakaa komennot##
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}Laivan pitää olla pysähdyksissä telakalla.
+STR_980C_CAN_T_SELL_SHIP :{WHITE}Laivaa ei voi myydä...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Laivaa ei voi rakentaa...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Laiva on tiellä.
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (tiedot)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}Ikä: {LTBLUE}{STRING}{BLACK} Käyttökustannukset: {LTBLUE}{CURRENCY}/vuosi
+STR_9813_MAX_SPEED :{BLACK}Huippunopeus: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Tuottoa tänä vuonna: {LTBLUE}{CURRENCY} (viime vuonna: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}Toimintavarmuus: {LTBLUE}{COMMA}% {BLACK}Hajoamisia viime huollon jälkeen: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Rakennettu: {LTBLUE}{NUM}{BLACK} Arvo: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}Kapasiteetti: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}Laivaa ei voi pysäyttää/laittaa liikkeelle...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Laivaa ei voi lähettää telakalle...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Paikallista telakkaa ei löydy
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}Suuntana telakka, {TOWN}
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}Suuntana telakka, {TOWN}, {VELOCITY}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE :{LTBLUE}Huolto{TOWN} Telakka
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE_VEL :{LTBLUE}Huolto {TOWN} Telakka, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}Laiva {COMMA} odottaa telakalla.
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Rakenna satama
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Rakenna telakka (laivojen rakentamista ja huoltamista varten).
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Laivat - napsauta laivaa saadaksesi tietoja.
+STR_9820_BUILD_NEW_SHIP :{BLACK}Rakenna uusi laiva
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Vedä laiva tähän myydäksesi sen.
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Keskitä näkymä telakan sijaintiin.
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Laivat - napsauta laivaa saadaksesi tietoja.
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Rakenna uusia laivoja (tarvitaan telakka).
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}Laivan valintalista - napsauta laivaa saadaksesi tietoja.
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Rakenna valittu laiva
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Nykyisen laivat toiminnot - napsauta tässä pysäyttääksesi/laittaaksesi liikkeelle.
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Näytä laivan aikataulu.
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Keskitä näkymä laivan sijaintiin.
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Lähetä laiva telakalle.
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Näytä laivan tiedot.
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}Uusi laiva saatavilla!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Kulu: {CURRENCY} Huippunopeus: {VELOCITY}{}Kapasiteetti: {CARGO}{}Käyttökustannukset: {CURRENCY}/vuosi
+STR_982F_NAME_SHIP :{BLACK}Nimeä laiva
+
+STR_9831_NAME_SHIP :{WHITE}Nimeä laiva
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Laivaa ei voi nimetä...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Kaupunkilaiset juhlivat . . .{}Ensimmäinen laiva saapuu asemalle {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Sijoita poiju; sitä voidaan käyttää ylimääräisenä opasteena.
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Poijua ei voi sijoittaa tähän...
+STR_9836_RENAME :{BLACK}Nimeä
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Nimeä laivatyyppi uudelleen.
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Nimeä laivatyyppi uudelleen.
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Laivatyyppin uudelleennimeäminen ei onnistu...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Sovita rahtilaiva eri rahtityypille.
+STR_983B_REFIT :{WHITE}{VEHICLE} (sovita)
+STR_983C_REFIT_SHIP :{BLACK}Sovita laiva
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Valitse laivan kuljettama rahtityyppi.
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Sovita laiva korostetulle rahtityypille.
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Valitse kuljetettava rahtityyppi:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Uusi kapasiteetti: {GOLD}{CARGO}{}{BLACK}Sovituksen kustannus: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Laivaa ei voi sovittaa...
+STR_9842_REFITTABLE :(sovitettava)
+STR_GO_TO_SHIP_DEPOT :Aseta kohteeksi telakka, {TOWN}
+SERVICE_AT_SHIP_DEPOT :Huolto, kohteena telakka, {TOWN}
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Lentokentät
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Lentokenttää ei voi rakentaa...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}Lentokonehalli, {STATION}
+STR_A003_NEW_AIRCRAFT :{BLACK}Uusi lentokone
+STR_CLONE_AIRCRAFT :{BLACK}Kloonaa lentokone
+STR_CLONE_AIRCRAFT_INFO :{BLACK}Tämä rakentaa kopion lentokoneesta. Control-klikkaus jakaa komennot
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Tämä rakentaa kopion lentokoneesta. Paina tätä nappia ja sen jälkeen lentokonetta lentokonehallin sisä- tai ulkopuolella. Control-click jakaa komennot ##
+STR_A005_NEW_AIRCRAFT :{WHITE}Uusi lentokone
+STR_A006_BUILD_AIRCRAFT :{BLACK}Rakenna lentokone
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Lentokonetta ei voi rakentaa...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} lentokonetta
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (aikataulu)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (tiedot)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Ikä: {LTBLUE}{STRING}{BLACK} Käyttökustannuket: {LTBLUE}{CURRENCY}/vuosi
+STR_A00E_MAX_SPEED :{BLACK}Huippunopeus: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Tuotto tänä vuonna: {LTBLUE}{CURRENCY} (viime vuonna: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}Luotettavuus: {LTBLUE}{COMMA}% {BLACK}Hajoamisia viime huollon jälkeen: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Rakennettu: {LTBLUE}{NUM}{BLACK} Arvo: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Lentokonetta ei voi lähettää lentokonehalliin...
+STR_HEADING_FOR_HANGAR :{ORANGE}Suuntana lentokonehalli, {STATION}
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}Suuntana lentokonehalli, {STATION}, {VELOCITY}
+STR_HEADING_FOR_HANGAR_SERVICE :{LTBLUE}Huolto {STATION} Halli
+STR_HEADING_FOR_HANGAR_SERVICE_VEL :{LTBLUE}Huolto {STATION} Halli, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}Lentokone {COMMA} odottaa lentokonehallissa.
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Lentokone on tiellä.
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Lentokonetta ei voi pysäyttää/laittaa liikkeelle...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Lentokone on lennossa.
+STR_A019_CAPACITY :{BLACK}Kapasiteetti: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Kapasiteetti: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}Lentokoneen pitää olla pysähdyksissä lentokonehallissa.
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Lentokonetta ei voi myydä...
+STR_A01D_AIRPORT_CONSTRUCTION :Lentokentän rakentaminen
+STR_A01E_BUILD_AIRPORT :{BLACK}Rakenna lentokenttä
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Lentokoneet - napsauta lentokonetta saadaksesi tietoja.
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Rakenna uusi lentokone (tarvitaan lentokenttä lentokonehallilla).
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Lentokoneet - napsauta lentokonetta saadaksesi tietoja.
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Rakenna uusi lentokone
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}Vedä lentokone tähän myydäksesi sen.
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Keskitä näkymä lentokonehallin sijaintiin.
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Lentokonevalintalista - napsauta lentokonetta saadaksesi tietoja.
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Rakenna korostettu lentokone
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Nykyisen lentokoneen toiminnot - napsauta tässä pysäyttääksesi/laittaaksesi liikkeelle.
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Näytä lentokoneen aikataulu.
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Keskitä näkymä lentokoneen sijaintiin.
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Lähetä lentokone lentokonehalliin.
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Näytä lentokoneen tiedot.
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}Uusi lentokone saatavilla!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Kulu: {CURRENCY} Huippunopeus: {VELOCITY}{}Kapasiteetti: {COMMA} matkustajaa, {COMMA} säkkiä postia{}Käyttökustannus: {CURRENCY}/vuosi
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Nimeä lentokone
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Lentokonetta ei voi nimetä...
+STR_A032_NAME_AIRCRAFT :{BLACK}Nimeä lentokone
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Kaupunkilaiset juhlivat . . .{}Ensimmäinen lentokone saapuu asemalle {STATION}!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Lento-onnettomuus!{}{COMMA} kuolee tulipallossa asemalla {STATION}.
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Lento-onnettomuus!{}Lentokoneelta loppui polttoaine, {COMMA} kuolee tulipallossa!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Nimeä
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Nimeä lentokonetyyppi uudelleen.
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Nimeä lentokonetyyppi uudelleen.
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Lentokonetyyppiä ei voi uudelleennimetä...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Sovita lentokone eri rahtityypille.
+STR_A03C_REFIT :{WHITE}{VEHICLE} (sovita)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Sovita lentokone
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Valitse kuljetettavan rahdin tyyppi.
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Sovita lentokone kuljettamaan valittua rahtityyppiä.
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Valitse kuljetettava rahtityyppi:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Uusi kapasiteetti: {GOLD}{STRING}{}{BLACK}Sovituksen kustannus: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Lentokonetta ei voi sovittaa...
+STR_GO_TO_AIRPORT_HANGAR :Aseta kohteeksi lentokonehalli, {STATION}
+SERVICE_AT_AIRPORT_HANGAR :Huolto, kohteena lentokonehalli, {STATION}
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}{STATION}: Ilmalaivaonnettomuus!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Ajoneuvo tuhoitui törmäyksessä UFO:n kanssa!
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}{TOWN}: Öljynjalostamon räjähdys!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}{TOWN}: Tehdas tuhoutunut epäilyttävissä olosuhteissa!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}{TOWN}: 'UFO' laskeutuu!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}{TOWN}: Hiilikaivoksen vajoaminen jättää tuhon jälkiä!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Tulvia!{}Ainakin {COMMA} oletettavasti kadoksissa tai kuollut tappavan tulvan jälkeen!
+
+STR_BRIBE_FAILED :{WHITE}Yleinen syyttäjä on saanut selville
+STR_BRIBE_FAILED_2 :{WHITE}lahjontayrityksesi.
+STR_BUILD_DATE :{BLACK}Rakennettu: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Yksityiskohtainen suoritearvio
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}Yksityiskohta
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Liikennevälineitä:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Asemia:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Vähimmäistuotto:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Vähimmäistulo:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Enimmäistulo:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Kuljetettu:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Rahti:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Raha:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Laina:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Yhteensä:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Liikennevälineiden määrä. Tähän kuuluvat ajoneuvot, junat, laivat ja lentokoneet.
+STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}Asemien osien määrä. Kaikki osat asemista (esim. rautatieasema, bussipysäkki, lentokenttä) lasketaan, vaikka ne olisivat yhdistettynä yhdeksi asemaksi.
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}Vähätuottoisimman ajoneuvon tulo (kaikkien yli 2 vuotta vanhojen ajoneuvojen)
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Viimeisen 12 neljänneksen vähätuottoisimman kuun käteistuoton määrä
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Viimeisen 12 neljänneksen korkeatuottoisimman kuun käteistuoton määrä
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}Viimeisen neljän neljänneksen kuljetetun rahdin määrä
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}Viimeisen neljänneksen kuljetetun rahdin tyyppi
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Käteisvarat
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}Tämän yhtiön ottaman lainan määrä
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Summa kaikista mahdollisista pisteistä.
+
+STR_NEWGRF_SETTINGS_BUTTON :{BLACK}NewGRF-asetukset
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}Newgrf-asetukset
+STR_NEWGRF_APPLY_CHANGES :{BLACK}Ota käyttöön
+STR_NEWGRF_SET_PARAMETERS :{BLACK}Aseta parametrit
+STR_NEWGRF_TIP :{BLACK}Lista kaikista asennetuista Newgrf-paketeista. Napsauta pakettia muuttaaksesi asetuksia.
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}Yhtään Newgrf-tiedostoa ei ole asennettuna! Lue manuaalista ohjeet uusien grafiikoiden asentamiseksi.
+STR_NEWGRF_FILENAME :{BLACK}Tiedostonimi: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
+STR_NEWGRF_MD5SUM :{BLACK}MD5-summa: {SILVER}{STRING}
+STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}Olet tekemässä muutoksia käynnissä olevaan peliin. OpenTTD voi kaatua.{}Oletko varma?
+
+STR_NEWGRF_ADD :{BLACK}Lisää
+STR_NEWGRF_ADD_TIP :{BLACK}Lisää NewGRF-tiedosto listaan
+STR_NEWGRF_REMOVE :{BLACK}Poista
+STR_NEWGRF_REMOVE_TIP :{BLACK}Poista valittu NewGRF-tiedosto listalta
+STR_NEWGRF_MOVEUP :{BLACK}Siirrä ylös
+STR_NEWGRF_MOVEUP_TIP :{BLACK}Siirrä valittua NewGRF-tiedostoa listassa ylöspäin
+STR_NEWGRF_MOVEDOWN :{BLACK}Siirrä alas
+STR_NEWGRF_MOVEDOWN_TIP :{BLACK}Siirrä valittua NewGRF-tiedostoa listassa alaspäin
+STR_NEWGRF_FILE_TIP :{BLACK}Lista asennetuista NewGRF-tiedostoista. Valitse tiedosto muokataksesi sen parametreja.
+STR_NEWGRF_PARAMETER :{BLACK}Parametrit: {SILVER}{STRING}
+STR_NEWGRF_PARAMETER_QUERY :{BLACK}Anna NewGRF-parametrit
+STR_NEWGRF_NO_INFO :{BLACK}Ei tietoa
+
+STR_NEWGRF_ADD_CAPTION :{WHITE}NewGRF-tiedostot
+STR_NEWGRF_ADD_FILE :{BLACK}Lisää valintaan
+STR_NEWGRF_ADD_FILE_TIP :{BLACK}Lisää valittu NewGRF-tiedosto peliin
+STR_NEWGRF_RESCAN_FILES :{BLACK}Päivitä
+STR_NEWGRF_RESCAN_FILES_TIP :{BLACK}Päivitä saatavilla olevien NewGRF-tiedostojen lista
+STR_NEWGRF_DUPLICATE_GRFID :{WHITE}Ei voi lisätä tiedostoa: duplicate GRF ID
+
+STR_NEWGRF_NOT_FOUND :{RED}Sopivaa tiedostoa ei löydy
+STR_NEWGRF_DISABLED :{RED}Ei käytössä
+
+STR_CURRENCY_WINDOW :{WHITE}Oma valuutta
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Vaihtokurssi: {ORANGE}{CURRENCY} = £ {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Välimerkki:
+STR_CURRENCY_PREFIX :{LTBLUE}Etuliite:
+STR_CURRENCY_SUFFIX :{LTBLUE}Jälkiliite:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Vaihda euroon: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Vaihda euroon: {ORANGE}ei koskaan
+STR_CURRENCY_PREVIEW :{LTBLUE}Esikatselu: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Vaihda oman valuutan parametria.
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} junaa
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} autoa
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} lentokonetta
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} laivaa
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Näytä kaikki junat, joilla on asema aikataulussaan.
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Näytä kaikki autot, joilla on asema aikataulussaan.
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Näytä kaikki lentokoneet, joilla on asema aikataulussaan.
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Näytä kaikki laivat, joilla on asema aikataulussaan.
+
+STR_VEH_WITH_SHARED_ORDERS_LIST :{WHITE}Shared orders of {COMMA} Ajoneuvo{P "" s}
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}Näytä kaikki ajoneuvot, joilla on sama aikataulu
+
+### depot strings
+STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Olet myymässä kaikki varikon ajoneuvot. Oletko varma?
+
+STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP :{BLACK}Myy kaikki varikolla olevat junat
+STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP :{BLACK}Myy kaikki varikolla olevat ajoneuvot
+STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP :{BLACK}Myy kaikki telakalla olevat laivat
+STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP :{BLACK}Myy kaikki hallissa olevat ilma-alukset
+
+STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP :{BLACK}Näytä tällä asemalla olevien junien käskyt
+STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP :{BLACK}Näytä tässä terminaalissa olevien ajoneuvojen käskyt
+STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP :{BLACK}Näytä tässä terminaalissa olevien laivojen käskyt
+STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP :{BLACK}Näytä tämän lentokentän ilma-alusten käskyistä hallista riippumatta
+
+STR_DEPOT_AUTOREPLACE_TRAIN_TIP :{BLACK}Korvaa kaikki varikolla olevat junat automaattisesti
+STR_DEPOT_AUTOREPLACE_ROADVEH_TIP :{BLACK}Korvaa kaikki varikolla olevat ajoneuvot automaattisesti
+STR_DEPOT_AUTOREPLACE_SHIP_TIP :{BLACK}Korvaa kaikki telakalla olevat laivat automaattisesti
+STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP :{BLACK}Korvaa kaikki hallissa olevat lento-alukset automaattisesti
+
+STR_VEHICLE_LIST_TRAIN_DEPOT :{BLACK}{STRING} - {COMMA} Juna{P "" s}
+STR_VEHICLE_LIST_ROADVEH_DEPOT :{BLACK}{STRING} - {COMMA} Maa-ajoneuvo{P "" s}
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} Laiva{P "" s}
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} Ilma-alus
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}Korvaa {STRING}
+STR_REPLACE_VEHICLES_START :{BLACK}Aloita ajoneuvojen korvaaminen
+STR_REPLACE_VEHICLES_STOP :{BLACK}Lopeta ajoneuvojen korvaaminen
+STR_NOT_REPLACING :{BLACK}Ei korvata
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Ei liikennevälinettä valittuna
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Valitse korvattava veturityyppi.
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Valitse vasemmalla näkyvän veturityypinn korvaava uusi veturityyppi.
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Napsauta pysäyttääksesi vasemmalta valitun veturityypin korvauksen.
+STR_REPLACE_HELP_START_BUTTON :{BLACK}Napsauta aloittaaksesi vasemmalta valitun veturityypin korvauksen oikealta valitulla veturityypillä.
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Valitse rautatietyyppi, jolle veturikorvaukset tehdään.
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Näyttää, millä vasemmalta valittu veturi korvataan, jos millään.
+STR_REPLACE_HELP :{BLACK}Tällä voit korvata yhden veturityypin toisella, kun alkuperäisen tyypin junat menevät varikolle.
+STR_REPLACE_REMOVE_WAGON :{BLACK}Vaunun poisto: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Automaattikorvaus pitäköön junan vakiopituisena poistamalla vaunuja (edestä) jos veturi pidentäisi junaa.
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}Korvataan: {ORANGE}{SKIP}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} ERIKOIS OMINAISUUS {} Vaihda toiseen korvausikkunaan. {} Vaunu vaihdetaan ainoastaan jos uusi vaunu kuljettaa samaa rahtia. Tämä tarkistetaan, joka kerta kun vaunu korvataan.
+STR_ENGINE_NOT_BUILDABLE :{WHITE}Veturi ei ole rakennettavissa
+
+STR_ENGINES :Veturit
+STR_WAGONS :Vaunut
+
+STR_MASS_STOP_DEPOT_TRAIN_TIP :{BLACK}Pysäytä kaikki varikolla olevat junat klikkaamalla
+STR_MASS_STOP_DEPOT_ROADVEH_TIP :{BLACK}Pysäytä kaikki varikolla olevat ajoneuvot klikkaamalla
+STR_MASS_STOP_DEPOT_SHIP_TIP :{BLACK}Pysäytä kaikki telakalla olevat laivat klikkaamalla
+STR_MASS_STOP_HANGAR_TIP :{BLACK}Pysäytä kaikki hallissa olevat ilma-alukset klikkaamalla
+
+STR_MASS_START_DEPOT_TRAIN_TIP :{BLACK}Käynnistä kaikki varikolla olevat junat klikkaamalla
+STR_MASS_START_DEPOT_ROADVEH_TIP :{BLACK}Käynnistä kaikki varikolla olevat ajoneuvot klikkaamalla
+STR_MASS_START_DEPOT_SHIP_TIP :{BLACK}Käynnistä kaikki telakalla olevat laivat klikkaamalla
+STR_MASS_START_HANGAR_TIP :{BLACK}Käynnistä kaikki hallissa olevat ilma-alukset klikkaamalla
+
+STR_MASS_STOP_LIST_TIP :{BLACK}Pysäytä kaikki listalla olevat kulkuneuvot klikkaamalla
+STR_MASS_START_LIST_TIP :{BLACK}Käynnistä kaikki listalla olevat ajoneuvot klikkaamalla
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}Kylttilista - {COMMA} kylttiä
+
+STR_ORDER_REFIT_FAILED :{WHITE}Käskyn uudelleensovitus pysähtyi virheeseen {STRING} {COMMA}
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :Rautatiejunat
+STR_ELRAIL_VEHICLES :Sähköjunat
+STR_MONORAIL_VEHICLES :Yksiraiteiset
+STR_MAGLEV_VEHICLES :Maglev-junat
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Kulu: {GOLD}{CURRENCY}{BLACK} Paino: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Nopeus: {GOLD}{VELOCITY}{BLACK} Teho: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}Nopeus: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Käyttökukustannus: {GOLD}{CURRENCY}/vuosi
+STR_PURCHASE_INFO_CAPACITY :{BLACK}Kapasiteetti: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Suunniteltu: {GOLD}{NUM}{BLACK} Elinikä: {GOLD}{COMMA} vuotta
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}Enimmäisluotettavuus: {GOLD}{COMMA}%
+STR_PURCHASE_INFO_COST :{BLACK}Kulu: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Paino: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Kulu: {GOLD}{CURRENCY}{BLACK} Nopeus: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Kapasiteetti: {GOLD}{COMMA} matkustajaa, {COMMA} säkkiä postia
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Moottoroidut vaunut: {GOLD}+{POWER}{BLACK} Paino: {GOLD}+{WEIGHT_S}
+STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Sovitettavissa: {GOLD}
+STR_PURCHASE_INFO_ALL_TYPES :Kaikki rahtityypit
+STR_PURCHASE_INFO_ALL_BUT :Kaikki paitsi {GOLD}
+
+########### String for New Landscape Generator
+
+STR_GENERATE :{WHITE}Generoi
+STR_RANDOM :{BLACK}Satunnainen
+STR_RANDOM_HELP :{BLACK}Vaihda maaston luomisessa käytettävä satunnaisluku-siemen
+STR_WORLD_GENERATION_CAPTION :{WHITE}Maailman luominen
+STR_RANDOM_SEED :{BLACK}Satunnaisluku-siemen:
+STR_RANDOM_SEED_HELP :{BLACK}Klikkaa antaaksesi satunnaisluku-siemen
+STR_LAND_GENERATOR :{BLACK}Maageneraattori:
+STR_TREE_PLACER :{BLACK}Puiden algoritmi:
+STR_HEIGHTMAP_ROTATION :{BLACK}Korkeuskartan kierto:
+STR_TERRAIN_TYPE :{BLACK}Maaston tyyppi:
+STR_QUANTITY_OF_SEA_LAKES :{BLACK}Merenpinta:
+STR_SMOOTHNESS :{BLACK}Tasaisuus:
+STR_SNOW_LINE_HEIGHT :{BLACK}Lumilinjan korkeus:
+STR_DATE :{BLACK}Päivämäärä:
+STR_NUMBER_OF_TOWNS :{BLACK}Kaupungit:
+STR_NUMBER_OF_INDUSTRIES :{BLACK}Teollisuus:
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_SNOW_LINE_UP :{BLACK}Siirrä lumilinjaa yksi ylöspäin
+STR_SNOW_LINE_DOWN :{BLACK}Siirrä lumilinjan korkeutta yksi alaspäin
+STR_SNOW_LINE_QUERY_CAPT :{WHITE}Vaihda lumilinjan korkeutta
+STR_START_DATE_QUERY_CAPT :{WHITE}Vaihda aloitusvuosi
+STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Mittakaava-varoitus
+STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Lähdekartan koon liiallinen muuttaminen ei ole suositeltavaa. Haluatko jatkaa?
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_HEIGHTMAP_NAME :{BLACK}Korkeuskartan nimi:
+STR_HEIGHTMAP_SIZE :{BLACK}Koko: {ORANGE}{NUM} x {NUM}
+STR_GENERATION_WORLD :{WHITE}Maailmaa luodaan...
+STR_GENERATION_ABORT :{BLACK}Peruuta
+STR_GENERATION_ABORT_CAPTION :{WHITE}Keskeytä maan luominen
+STR_GENERATION_ABORT_MESSAGE :{YELLOW}Haluatko varmasti keskeyttää maan luomisen?
+STR_PROGRESS :{WHITE}{NUM}% valmiina
+STR_GENERATION_PROGRESS :{BLACK}{NUM} / {NUM}
+STR_WORLD_GENERATION :{BLACK}Maailman luominen
+STR_TREE_GENERATION :{BLACK}Puiden luominen
+STR_UNMOVABLE_GENERATION :{BLACK}Siirtämättömän luominen
+STR_CLEARING_TILES :{BLACK}Karun ja kivisen alueen luominen
+STR_SETTINGUP_GAME :{BLACK}Valmistellaan peliä
+STR_PREPARING_TILELOOP :{BLACK}Ajetaan tile-loop
+STR_PREPARING_GAME :{BLACK}Valmistellaan peliä
+STR_DIFFICULTY_TO_CUSTOM :{WHITE}Tehty toiminto vaihtoi vaikeustason mukautetuksi
+STR_SE_FLAT_WORLD :{WHITE}Tasainen maa
+STR_SE_FLAT_WORLD_TIP :{BLACK}Luo tasainen maa
+STR_SE_RANDOM_LAND :{WHITE}Satunnainen maa
+STR_SE_NEW_WORLD :{BLACK}Luo uusi skenaario
+STR_SE_CAPTION :{WHITE}Skenaarion tyyppi
+STR_FLAT_WORLD_HEIGHT_DOWN :{BLACK}Siirrä tasaista maata yksi alaspäin
+STR_FLAT_WORLD_HEIGHT_UP :{BLACK}Siirrä tasaista maata yksi ylöspäin
+STR_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Vaihda tasaisen maan korkeutta
+STR_FLAT_WORLD_HEIGHT :{BLACK}Tasaisen maan korkeus:
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+STR_SMALLMAP_CENTER :{BLACK}Keskitä pieni kartta tähän paikkaan
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}Pieni
+STR_CITY_AIRPORT :{BLACK}Kaupunki
+STR_METRO_AIRPORT :{BLACK}Suurkaupungin lentokenttä
+STR_INTERNATIONAL_AIRPORT :{BLACK}Kansainvälinen lentokenttä
+STR_COMMUTER_AIRPORT :{BLACK}Työmatkalainen
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Mannertenvälinen
+STR_HELIPORT :{BLACK}Helikopterikenttä
+STR_HELIDEPOT :{BLACK}Helikopterihalli
+STR_HELISTATION :{BLACK}Helikopteriasema
+
+STR_SMALL_AIRPORTS :{BLACK}Pienet lentokentät
+STR_LARGE_AIRPORTS :{BLACK}Isot lentokentät
+STR_HUB_AIRPORTS :{BLACK}Keskuslentokenttä
+STR_HELIPORTS :{BLACK}Helikopteri lentokenttä
+
+############ Tooltip measurment
+
+STR_MEASURE_LENGTH :{BLACK}Pituus: {NUM}
+STR_MEASURE_AREA :{BLACK}Pinta-ala: {NUM} x {NUM}
+STR_MEASURE_LENGTH_HEIGHTDIFF :{BLACK}Pituus: {NUM}{}Korkeusero: {NUM} m
+STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}Pinta-ala: {NUM} x {NUM}{}Korkeusero: {NUM} m
+
+########
diff --git a/src/lang/french.txt b/src/lang/french.txt
new file mode 100644
index 000000000..2a54e96c9
--- /dev/null
+++ b/src/lang/french.txt
@@ -0,0 +1,3117 @@
+##name French
+##ownname Français
+##isocode fr_FR.UTF-8
+##plural 2
+##gender m m2 f
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Hors limites
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Trop près des bords de la carte
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Fonds insuffisants{}Somme de {CURRENCY} requise
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Terrain plat requis
+STR_0008_WAITING :{BLACK}En attente: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (venant de
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Accepte: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Accepte: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :Passagers
+STR_0010_COAL :Charbon
+STR_0011_MAIL :Courrier
+STR_0012_OIL :Pétrole
+STR_0013_LIVESTOCK :Bétail
+STR_0014_GOODS :Biens
+STR_0015_GRAIN :Grain
+STR_0016_WOOD :Bois
+STR_0017_IRON_ORE :Fer
+STR_0018_STEEL :Acier
+STR_0019_VALUABLES :Objets de valeur
+STR_001A_COPPER_ORE :Cuivre
+STR_001B_MAIZE :Maïs
+STR_001C_FRUIT :Fruits
+STR_001D_DIAMONDS :Diamants
+STR_001E_FOOD :Nourriture
+STR_001F_PAPER :Papier
+STR_0020_GOLD :Or
+STR_0021_WATER :Eau
+STR_0022_WHEAT :Blé
+STR_0023_RUBBER :Caoutchouc
+STR_0024_SUGAR :Sucre
+STR_0025_TOYS :Jouets
+STR_0026_CANDY :Sucreries
+STR_0027_COLA :Cola
+STR_0028_COTTON_CANDY :Barbe à Papa
+STR_0029_BUBBLES :Bulles
+STR_002A_TOFFEE :Caramel
+STR_002B_BATTERIES :Batteries
+STR_002C_PLASTIC :Plastique
+STR_002D_FIZZY_DRINKS :Boissons Gazeuses
+STR_002E :
+STR_002F_PASSENGER :Passager
+STR_0030_COAL :Charbon
+STR_0031_MAIL :Courrier
+STR_0032_OIL :Pétrole
+STR_0033_LIVESTOCK :Bétail
+STR_0034_GOODS :Biens
+STR_0035_GRAIN :Grain
+STR_0036_WOOD :Bois
+STR_0037_IRON_ORE :Fer
+STR_0038_STEEL :Acier
+STR_0039_VALUABLES :Objets de valeur
+STR_003A_COPPER_ORE :Cuivre
+STR_003B_MAIZE :Maïs
+STR_003C_FRUIT :Fruit
+STR_003D_DIAMOND :Diamant
+STR_003E_FOOD :Nourriture
+STR_003F_PAPER :Papier
+STR_0040_GOLD :Or
+STR_0041_WATER :Eau
+STR_0042_WHEAT :Blé
+STR_0043_RUBBER :Caoutchouc
+STR_0044_SUGAR :Sucre
+STR_0045_TOY :Jouet
+STR_0046_CANDY :Sucrerie
+STR_0047_COLA :Cola
+STR_0048_COTTON_CANDY :Barbe à Papa
+STR_0049_BUBBLE :Bulle
+STR_004A_TOFFEE :Caramel
+STR_004B_BATTERY :Batterie
+STR_004C_PLASTIC :Plastique
+STR_004D_FIZZY_DRINK :Boisson Gazeuse
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} passager{P "" s}
+STR_QUANTITY_COAL :{WEIGHT} de charbon
+STR_QUANTITY_MAIL :{COMMA} sac{P "" s} posta{P l ux}
+STR_QUANTITY_OIL :{VOLUME} de pétrole
+STR_QUANTITY_LIVESTOCK :{COMMA} tête{P "" s} de bétail
+STR_QUANTITY_GOODS :{COMMA} caisse{P "" s} de biens
+STR_QUANTITY_GRAIN :{WEIGHT} de grains
+STR_QUANTITY_WOOD :{WEIGHT} de bois
+STR_QUANTITY_IRON_ORE :{WEIGHT} de fer
+STR_QUANTITY_STEEL :{WEIGHT} d'acier
+STR_QUANTITY_VALUABLES :{COMMA} sac{P "" s} d'objets de valeur
+STR_QUANTITY_COPPER_ORE :{WEIGHT} de cuivre
+STR_QUANTITY_MAIZE :{WEIGHT} de maïs
+STR_QUANTITY_FRUIT :{WEIGHT} de fruits
+STR_QUANTITY_DIAMONDS :{COMMA} sac{P "" s} de diamants
+STR_QUANTITY_FOOD :{WEIGHT} de nourriture
+STR_QUANTITY_PAPER :{WEIGHT} de papier
+STR_QUANTITY_GOLD :{COMMA} sac{P "" s} d'or
+STR_QUANTITY_WATER :{VOLUME} d'eau
+STR_QUANTITY_WHEAT :{WEIGHT} de blé
+STR_QUANTITY_RUBBER :{VOLUME} de caoutchouc
+STR_QUANTITY_SUGAR :{WEIGHT} de sucre
+STR_QUANTITY_TOYS :{COMMA} jouet{P "" s}
+STR_QUANTITY_SWEETS :{COMMA} sac{P "" s} de jouets
+STR_QUANTITY_COLA :{VOLUME} de cola
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} de barbe à papa
+STR_QUANTITY_BUBBLES :{COMMA} bulle{P "" s}
+STR_QUANTITY_TOFFEE :{WEIGHT} de caramel
+STR_QUANTITY_BATTERIES :{COMMA} batterie{P "" s}
+STR_QUANTITY_PLASTIC :{VOLUME} de plastique
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} boisson{P "" s} gazeuse{P "" s}
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}PS
+STR_ABBREV_COAL :{TINYFONT}CH
+STR_ABBREV_MAIL :{TINYFONT}CO
+STR_ABBREV_OIL :{TINYFONT}PT
+STR_ABBREV_LIVESTOCK :{TINYFONT}BT
+STR_ABBREV_GOODS :{TINYFONT}BN
+STR_ABBREV_GRAIN :{TINYFONT}GR
+STR_ABBREV_WOOD :{TINYFONT}BO
+STR_ABBREV_IRON_ORE :{TINYFONT}FE
+STR_ABBREV_STEEL :{TINYFONT}AC
+STR_ABBREV_VALUABLES :{TINYFONT}VL
+STR_ABBREV_COPPER_ORE :{TINYFONT}CV
+STR_ABBREV_MAIZE :{TINYFONT}MS
+STR_ABBREV_FRUIT :{TINYFONT}FT
+STR_ABBREV_DIAMONDS :{TINYFONT}DM
+STR_ABBREV_FOOD :{TINYFONT}NR
+STR_ABBREV_PAPER :{TINYFONT}PR
+STR_ABBREV_GOLD :{TINYFONT}OR
+STR_ABBREV_WATER :{TINYFONT}EA
+STR_ABBREV_WHEAT :{TINYFONT}BL
+STR_ABBREV_RUBBER :{TINYFONT}CA
+STR_ABBREV_SUGAR :{TINYFONT}SU
+STR_ABBREV_TOYS :{TINYFONT}JT
+STR_ABBREV_SWEETS :{TINYFONT}BB
+STR_ABBREV_COLA :{TINYFONT}CL
+STR_ABBREV_CANDYFLOSS :{TINYFONT}BP
+STR_ABBREV_BUBBLES :{TINYFONT}BU
+STR_ABBREV_TOFFEE :{TINYFONT}CM
+STR_ABBREV_BATTERIES :{TINYFONT}BA
+STR_ABBREV_PLASTIC :{TINYFONT}PL
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}GZ
+STR_ABBREV_NONE :{TINYFONT}NO
+STR_ABBREV_ALL :{TINYFONT}ALL
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Carte - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Options
+STR_00B2_MESSAGE :{YELLOW}Message
+STR_00B3_MESSAGE_FROM :{YELLOW}Message de {STRING}
+STR_POPUP_CAUTION_CAPTION :{WHITE}Attention!
+STR_00B4_CAN_T_DO_THIS :{WHITE}Impossible d'exécuter....
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Impossible de balayer....
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Copyright original {COPYRIGHT} 1995 Chris Sawyer, Tous droits réservés
+STR_00B7_VERSION :{BLACK}OpenTTD version {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 L'équipe OpenTTD
+STR_TRANSLATED_BY :{BLACK} Traducteur(s) -
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Quitter
+STR_00C8_YES :{BLACK}Oui
+STR_00C9_NO :{BLACK}Non
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Êtes vous sur de vouloir abandonner cette partie et retourner à {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Rien
+STR_00D1_DARK_BLUE :Bleu foncé
+STR_00D2_PALE_GREEN :Vert pâle
+STR_00D3_PINK :Rose
+STR_00D4_YELLOW :Jaune
+STR_00D5_RED :Rouge
+STR_00D6_LIGHT_BLUE :Bleu pâle
+STR_00D7_GREEN :Vert
+STR_00D8_DARK_GREEN :Vert foncé
+STR_00D9_BLUE :Bleu
+STR_00DA_CREAM :Beige
+STR_00DB_MAUVE :Mauve
+STR_00DC_PURPLE :Violet
+STR_00DD_ORANGE :Orange
+STR_00DE_BROWN :Brun
+STR_00DF_GREY :Gris
+STR_00E0_WHITE :Blanc
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Trop de véhicules en jeu
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Emplacement
+STR_00E5_CONTOURS :Relief
+STR_00E6_VEHICLES :Véhicules
+STR_00E7_INDUSTRIES :Industries
+STR_00E8_ROUTES :Routes
+STR_00E9_VEGETATION :Végétation
+STR_00EA_OWNERS :Propriétaires
+STR_00EB_ROADS :{BLACK}{TINYFONT}Routes
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Voies ferrées
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Gares/Aéroports/Ports
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Édifices/Industries
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Véhicules
+STR_00F0_100M :{BLACK}{TINYFONT}100m
+STR_00F1_200M :{BLACK}{TINYFONT}200m
+STR_00F2_300M :{BLACK}{TINYFONT}300m
+STR_00F3_400M :{BLACK}{TINYFONT}400m
+STR_00F4_500M :{BLACK}{TINYFONT}500m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Trains
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Véhicules routiers
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Navires
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Aéronefs
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Routes de Transport
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Mine de Charbon
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Centrale Électrique
+STR_00FC_FOREST :{BLACK}{TINYFONT}Forêt
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}Scierie
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Raffinerie pétrolière
+STR_00FF_FARM :{BLACK}{TINYFONT}Ferme
+STR_0100_FACTORY :{BLACK}{TINYFONT}Usine
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Imprimerie
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Puits de pétrole
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Mine de fer
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Aciérie
+STR_0105_BANK :{BLACK}{TINYFONT}Banque
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Papeterie
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Mine d'Or
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Usine Agroalimentaire
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Mine de Diamant
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Mine de Cuivre
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Plantation de Fruits
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Plantation de Caoutchouc
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Source d'eau
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Château d'eau
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}Scierie
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Forêt de Barbe à Papa
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Usine de Sucreries
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Ferme de Batteries
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Puits de Cola
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Boutique de Jouets
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Usine de Jouets
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Fontaines de Plastique
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Usine de Boissons Gazeuses
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Générateur de Bulles
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Carrière de Caramel
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Mine de Sucre
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Gare ferroviaire
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Zone de Chargement
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Arrêt d'autobus
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Aéroport/Héliport
+STR_011F_DOCK :{BLACK}{TINYFONT}Port
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Terre en friche
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Herbe
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Terre nue
+STR_0123_FIELDS :{BLACK}{TINYFONT}Champs
+STR_0124_TREES :{BLACK}{TINYFONT}Arbres
+STR_0125_ROCKS :{BLACK}{TINYFONT}Roches
+STR_0126_WATER :{BLACK}{TINYFONT}Eau
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Sans Propriétaire
+STR_0128_TOWNS :{BLACK}{TINYFONT}Villes
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Industries
+STR_012A_DESERT :{BLACK}{TINYFONT}Désert
+STR_012B_SNOW :{BLACK}{TINYFONT}Neige
+STR_012C_MESSAGE :{WHITE}Message
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Annuler
+STR_012F_OK :{BLACK}OK
+STR_0130_RENAME :{BLACK}Renommer
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Trop de noms déjà définis
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Ce nom est déjà utilisé
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...appartient à {STRING}
+STR_013C_CARGO :{BLACK}Cargaison
+STR_013D_INFORMATION :{BLACK}Information
+STR_013E_CAPACITIES :{BLACK}Capacités
+STR_013E_TOTAL_CARGO :{BLACK}Charge totale
+STR_013F_CAPACITY :{BLACK}Capacité: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}Capacité: {LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Capacité totale de ce train:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}Nouvelle Partie
+STR_0141_LOAD_GAME :{BLACK}Charger une Partie
+STR_SINGLE_PLAYER :{BLACK}Un joueur
+STR_MULTIPLAYER :{BLACK}Multijoueurs
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Taille de la carte :
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Options
+
+STR_0150_SOMEONE :quelqu'un{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Carte du monde
+STR_0152_TOWN_DIRECTORY :Annuaire des Villes
+STR_0153_SUBSIDIES :Subventions
+
+STR_UNITS_IMPERIAL :Impérial
+STR_UNITS_METRIC :Métrique
+STR_UNITS_SI :SI
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} mph
+STR_UNITS_VELOCITY_METRIC :{COMMA} km/h
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}hp
+STR_UNITS_POWER_METRIC :{COMMA}hp
+STR_UNITS_POWER_SI :{COMMA}kW
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} tonne{P "" s}
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} tonne{P "" s}
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} kg
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}gal
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}l
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}m³
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} gallon{P "" s}
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} litre{P "" s}
+STR_UNITS_VOLUME_LONG_SI :{COMMA} m³
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10³ lbf
+STR_UNITS_FORCE_METRIC :{COMMA} ton-force
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Profit d'opération
+STR_0155_INCOME_GRAPH :Revenu
+STR_0156_DELIVERED_CARGO_GRAPH :Cargaison livrée
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Historique de performance
+STR_0158_COMPANY_VALUE_GRAPH :Valeur de la compagnie
+STR_0159_CARGO_PAYMENT_RATES :Valeur des marchandises
+STR_015A_COMPANY_LEAGUE_TABLE :Classement des compagnies
+STR_PERFORMANCE_DETAIL_MENU :Détail des performances
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}OpenTTD
+STR_015C_SAVE_GAME :Sauvegarder la partie
+STR_015D_LOAD_GAME :Charger une partie
+STR_015E_QUIT_GAME :Abandonner la partie
+STR_015F_QUIT :Quitter le jeu
+STR_ABANDON_GAME_QUERY :{YELLOW}Êtes vous sur de vouloir abandonner cette partie?
+STR_0161_QUIT_GAME :{WHITE}Abandonner
+STR_SORT_ORDER_TIP :{BLACK}Choisir l'ordre de tri croissant/décroissant
+STR_SORT_CRITERIA_TIP :{BLACK}Choisir le critère de tri
+STR_SORT_BY :{BLACK}Trier par
+
+STR_SORT_BY_POPULATION :{BLACK}Population
+STR_SORT_BY_PRODUCTION :{BLACK}Production
+STR_SORT_BY_TYPE :{BLACK}Type
+STR_SORT_BY_TRANSPORTED :{BLACK}Transporté
+STR_SORT_BY_NAME :{BLACK}Nom
+STR_SORT_BY_DROPDOWN_NAME :Nom
+STR_SORT_BY_DATE :{BLACK}Date
+STR_SORT_BY_NUMBER :Numéro
+STR_SORT_BY_PROFIT_LAST_YEAR :Profit l'an dernier
+STR_SORT_BY_PROFIT_THIS_YEAR :Profit cette année
+STR_SORT_BY_AGE :Âge
+STR_SORT_BY_RELIABILITY :Fiabilité
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Capacité totale par cargo
+STR_SORT_BY_MAX_SPEED :Vitesse maximum
+STR_SORT_BY_MODEL :Modèle
+STR_SORT_BY_VALUE :Valeur
+STR_SORT_BY_FACILITY :Type de station
+STR_SORT_BY_WAITING :Marchandise en attente
+STR_SORT_BY_RATING_MAX :Notation
+STR_ENGINE_SORT_ENGINE_ID :ID Engin (tri classique)
+STR_ENGINE_SORT_COST :Prix
+STR_ENGINE_SORT_POWER :Puissance
+STR_ENGINE_SORT_INTRO_DATE :Date d'introduction
+STR_ENGINE_SORT_RUNNING_COST :Coût d'entretien
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Puissance/Coût d'entretien
+STR_ENGINE_SORT_CARGO_CAPACITY :Capacité
+STR_NO_WAITING_CARGO :{BLACK}Pas de marchandises en attente
+STR_SELECT_ALL_FACILITIES :{BLACK}Tous les types de station
+STR_SELECT_ALL_TYPES :{BLACK}Tous les types de marchandise (y compris pas en attente)
+STR_AVAILABLE_ENGINES_TIP :{BLACK}Voir la liste des modèles disponibles pour ce type de véhicules.
+STR_MANAGE_LIST :{BLACK}Gérer la liste
+STR_MANAGE_LIST_TIP :{BLACK}Envoyer les instructions à tous les véhicules de cette liste
+STR_REPLACE_VEHICLES :Remplacer véhicules
+STR_SEND_TRAIN_TO_DEPOT :Envoyer au dépôt
+STR_SEND_ROAD_VEHICLE_TO_DEPOT :Envoyer au dépôt
+STR_SEND_SHIP_TO_DEPOT :Envoyer au dépôt
+STR_SEND_AIRCRAFT_TO_HANGAR :Envoyer au hangar
+STR_SEND_FOR_SERVICING :Envoyer en entretien
+
+############ range for months starts
+STR_0162_JAN :Jan
+STR_0163_FEB :Fév
+STR_0164_MAR :Mar
+STR_0165_APR :Avr
+STR_0166_MAY :Mai
+STR_0167_JUN :Jun
+STR_0168_JUL :Jul
+STR_0169_AUG :Aut
+STR_016A_SEP :Sep
+STR_016B_OCT :Oct
+STR_016C_NOV :Nov
+STR_016D_DEC :Déc
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Suspendre la partie
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Sauvegarder, abandonner, quitter
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Afficher la liste des stations de la compagnie
+STR_0174_DISPLAY_MAP :{BLACK}Afficher la carte
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Afficher la carte, annuaire des villes
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Afficher l'annuaire des villes
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Afficher les informations financières
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Afficher les informations générales
+STR_0179_DISPLAY_GRAPHS :{BLACK}Afficher les graphiques
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Afficher le tableau de classement des compagnies
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Afficher la liste des trains
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Afficher la liste des véhicules routiers
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Afficher la liste des navires
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Afficher la liste des aéronefs
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Zoom avant
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Zoom arrière
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Construction ferroviaire
+STR_0182_BUILD_ROADS :{BLACK}Construction routière
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Construction navale
+STR_0184_BUILD_AIRPORTS :{BLACK}Construction aéronautique
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Planter des arbres
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Outil d'Inspection
+STR_0187_OPTIONS :{BLACK}Options
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Impossible de modifier l'intervalle de service...
+STR_018B_CLOSE_WINDOW :{BLACK}Fermer la fenêtre
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Titre de fenêtre - Faire Glisser pour déplacer la fenêtre
+STR_STICKY_BUTTON :{BLACK}Marquer cette fenêtre comme ineffaçable pour la touche 'Fermer toutes les fenêtres'
+STR_RESIZE_BUTTON :{BLACK}Cliquer et faire glisse pour redimensionner la fenêtre
+STR_SAVELOAD_HOME_BUTTON :{BLACK}Cliquer ici pour passer au répertoire par défaut courant de charge/sauvegarde
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Démolir les constructions sur un carré de terrain
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Abaisser le terrain
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Élever le terrain
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Barre de défilement - Défile la liste de bas en haut
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Barre de défilement - Défile la liste de gauche à droite
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Afficher le relief sur la carte
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Afficher les véhicules sur la carte
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Afficher les industries sur la carte
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Afficher les routes de transport sur la carte
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Afficher la végétation sur la carte
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Afficher les propriétaires sur la carte
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Afficher le nom des villes sur la carte
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Profit cette année: {CURRENCY} (l'an dernier: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} an{P "" nées} ({COMMA})
+STR_AGE_RED :{RED}{COMMA} an{P "" nées} ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Véhicule routier
+STR_019D_AIRCRAFT :Aéronef
+STR_019E_SHIP :Navire
+STR_019F_TRAIN :Train
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} devient vieux
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} devient très vieux
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} devient très vieux et doit être remplacé d'urgence
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Information sur le Terrain
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Coût du balayage: {LTBLUE}N/D
+STR_01A5_COST_TO_CLEAR :{BLACK}Coût du balayage: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :N/D
+STR_01A7_OWNER :{BLACK}Propriétaire: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Municipalité: {LTBLUE}{STRING}
+STR_01A9_NONE :Aucun
+STR_01AA_NAME :{BLACK}Nom
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1er
+STR_01AD_2ND :2
+STR_01AE_3RD :3
+STR_01AF_4TH :4
+STR_01B0_5TH :5
+STR_01B1_6TH :6
+STR_01B2_7TH :7
+STR_01B3_8TH :8
+STR_01B4_9TH :9
+STR_01B5_10TH :10
+STR_01B6_11TH :11
+STR_01B7_12TH :12
+STR_01B8_13TH :13
+STR_01B9_14TH :14
+STR_01BA_15TH :15
+STR_01BB_16TH :16
+STR_01BC_17TH :17
+STR_01BD_18TH :18
+STR_01BE_19TH :19
+STR_01BF_20TH :20
+STR_01C0_21ST :21
+STR_01C1_22ND :22
+STR_01C2_23RD :23
+STR_01C3_24TH :24
+STR_01C4_25TH :25
+STR_01C5_26TH :26
+STR_01C6_27TH :27
+STR_01C7_28TH :28
+STR_01C8_29TH :29
+STR_01C9_30TH :30
+STR_01CA_31ST :31
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Cargaison acceptée: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Jukebox Jazz
+STR_01D3_SOUND_MUSIC :Son/musique
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Options son et musique
+STR_01D5_ALL :{TINYFONT}Tout
+STR_01D6_OLD_STYLE :{TINYFONT}Ancien Style
+STR_01D7_NEW_STYLE :{TINYFONT}Nouveau Style
+STR_01D8_EZY_STREET :{TINYFONT}Ezy Street
+STR_01D9_CUSTOM_1 :{TINYFONT}Personnalisé 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Personnalisé 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Volume Musique
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Volume Effets Sonores
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MIN ' ' ' ' ' ' MAX
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Sauter à la piste précédente dans la sélection
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Sauter à la piste suivante dans la sélection
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Arrêter la musique
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Démarrer la musique
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Faire glisser les curseurs pour changer le volume
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Piste{SETX 88}Titre
+STR_01E9_SHUFFLE :{TINYFONT}Aléatoire
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Programme
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Sélection du Programme Musical
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Index de Piste
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Programme - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}Balayer
+STR_01F1_SAVE :{TINYFONT}{BLACK}Sauvegarder
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Programme musical courrant
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Choisir le programme 'tout'
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Choisir le programme 'ancien style musical'
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Choisir le programme 'nouveau style musical'
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Choisir le programme personnalisé 'Personnalisé 1'
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Choisir le programme personnalisé 'Personnalisé 2'
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Balayer le programme courrant (Personnalisé 1 ou Personnalisé 2 seulement)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Sauver les paramètres musicaux
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Cliquer sur une piste pour l'ajouter au programme courant (Personnalisé 1 ou Personnalisé 2 seulement)
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Cliquer sur une piste pour la retirer du programme courant (Personnalisé 1 ou Personnalisé 2 seulement)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Active/Désactive le mode aléatoire
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Afficher la fenêtre de sélection de pistes
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Cliquer sur le service pour centrer la vue sur l'industrie ou la ville
+STR_01FE_DIFFICULTY :{BLACK}Difficulté ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Message/Bulletin précédent
+STR_0201_MESSAGE_SETTINGS :Options de messagerie
+STR_MESSAGE_HISTORY_MENU :Historique des Messages
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Afficher le dernier message/bulletin, afficher les options des messages
+STR_0204_MESSAGE_OPTIONS :{WHITE}Options des messages
+STR_0205_MESSAGE_TYPES :{BLACK}Types de message:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}1er véhicule dans la station du joueur
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}1er véhicule dans la station d'un competiteur
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Accidents / désastres
+STR_0209_COMPANY_INFORMATION :{YELLOW}Informations corporatives
+STR_020A_ECONOMY_CHANGES :{YELLOW}Changements économiques
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Conseils / information sur les véhicules du joueur
+STR_020C_NEW_VEHICLES :{YELLOW}Nouveaux véhicules
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Changements d'acceptation de marchandises
+STR_020E_SUBSIDIES :{YELLOW}Subventions
+STR_020F_GENERAL_INFORMATION :{YELLOW}Information génerale
+STR_MESSAGES_ALL :{YELLOW}Pour tout types de messages (aucun/sommaire/complet)
+STR_MESSAGE_SOUND :{YELLOW}Émettre son pour les bulletins sommaires
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...trop loin de la destination précédente
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Meilleures compagnies, qui ont atteint {NUM}{}(Niveau {STRING})
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Tableau du Championnat des compagnies en {NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Homme d'affaires
+STR_0214_ENTREPRENEUR :Entrepreneur
+STR_0215_INDUSTRIALIST :Industriel
+STR_0216_CAPITALIST :Capitaliste
+STR_0217_MAGNATE :Magnat
+STR_0218_MOGUL :Grand ponte
+STR_0219_TYCOON_OF_THE_CENTURY :Tycoon du Siècle
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} atteint le niveau de '{STRING}' !
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} de {COMPANY} atteint le niveau de '{STRING}' !
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Créer Scénario
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Éditeur de Scénario
+STR_0223_LAND_GENERATION :{WHITE}Génération de terrain
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Générer un terrain
+STR_0227_RESET_LAND :{BLACK}RAZ du terrain
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Augmenter la quantité de terre à modifier
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Diminuer la quantité de terre à modifier
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Générer une terre aléatoire
+STR_022B_RESET_LANDSCAPE :{BLACK}Réinitialiser le terrain
+STR_022C_RESET_LANDSCAPE :{WHITE}Réinitialiser le terrain
+STR_LOAD_GAME_HEIGHTMAP :{WHITE}Carte d'altitude
+STR_LOAD_SCEN_HEIGHTMAP :{BLACK}Utiliser une carte d'altitude
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Voulez-vous vraiment réinitialiser le terrain?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Créer le terrain
+STR_022F_TOWN_GENERATION :{BLACK}Créer les villes
+STR_0230_INDUSTRY_GENERATION :{BLACK}Créer les industries
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Construction routière
+STR_0233_TOWN_GENERATION :{WHITE}Créer les villes
+STR_0234_NEW_TOWN :{BLACK}Nouvelle ville
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Construire une nouvelle ville
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Impossible de construire une ville ici...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...trop près du bord de la carte
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...trop près d'une autre ville
+STR_0239_SITE_UNSUITABLE :{WHITE}...site non convenable
+STR_023A_TOO_MANY_TOWNS :{WHITE}...trop de villes
+STR_CANNOT_GENERATE_TOWN :{WHITE}Ne peut plus bâtir de villes
+STR_NO_SPACE_FOR_TOWN :{WHITE}...Il n'y a plus d'emplacement sur la carte
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Augmenter la taille de la ville
+STR_023C_EXPAND :{BLACK}Agrandir
+STR_023D_RANDOM_TOWN :{BLACK}Générer une ville
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Construire une ville dans un emplacement aléatoire
+STR_023F_INDUSTRY_GENERATION :{WHITE}Créer les industries
+STR_0240_COAL_MINE :{BLACK}Mine de Charbon
+STR_0241_POWER_STATION :{BLACK}Centrale Électrique
+STR_0242_SAWMILL :{BLACK}Scierie
+STR_0243_FOREST :{BLACK}Forêt
+STR_0244_OIL_REFINERY :{BLACK}Raffinerie pétrolière
+STR_0245_OIL_RIG :{BLACK}Plate-forme pétrolière
+STR_0246_FACTORY :{BLACK}Usine
+STR_0247_STEEL_MILL :{BLACK}Aciérie
+STR_0248_FARM :{BLACK}Ferme
+STR_0249_IRON_ORE_MINE :{BLACK}Mine de fer
+STR_024A_OIL_WELLS :{BLACK}Puits de pétrole
+STR_024B_BANK :{BLACK}Banque
+STR_024C_PAPER_MILL :{BLACK}Usine papetière
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Usine Agroalimentaire
+STR_024E_PRINTING_WORKS :{BLACK}Imprimerie
+STR_024F_GOLD_MINE :{BLACK}Mine d'Or
+STR_0250_LUMBER_MILL :{BLACK}Scierie
+STR_0251_FRUIT_PLANTATION :{BLACK}Plantation de Fruits
+STR_0252_RUBBER_PLANTATION :{BLACK}Plantation de Caoutchouc
+STR_0253_WATER_SUPPLY :{BLACK}Source d'eau
+STR_0254_WATER_TOWER :{BLACK}Château d'eau
+STR_0255_DIAMOND_MINE :{BLACK}Mine de Diamant
+STR_0256_COPPER_ORE_MINE :{BLACK}Mine de Cuivre
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Forêt de Barbe à Papa
+STR_0258_CANDY_FACTORY :{BLACK}Usine de Sucreries
+STR_0259_BATTERY_FARM :{BLACK}Ferme de Batteries
+STR_025A_COLA_WELLS :{BLACK}Puits de Cola
+STR_025B_TOY_SHOP :{BLACK}Boutique de Jouets
+STR_025C_TOY_FACTORY :{BLACK}Usine de Jouets
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Fontaines de Plastique
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Usine de Boissons Gazeuses
+STR_025F_BUBBLE_GENERATOR :{BLACK}Générateur de Bulles
+STR_0260_TOFFEE_QUARRY :{BLACK}Carrière de Caramel
+STR_0261_SUGAR_MINE :{BLACK}Mine de Sucre
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Construire Mine de Charbon
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Construire Centrale Électrique
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Construire Scierie
+STR_0265_PLANT_FOREST :{BLACK}Planter une Forêt
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Construire une raffinerie pétrolière
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}La construire d'une plate-forme pétrolière ne peut se faire qu'aux bords de la carte
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Construire Usine
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Construire Aciérie
+STR_026A_CONSTRUCT_FARM :{BLACK}Construire Ferme
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Construire Mine de Fer
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Construire puits de pétrole
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Construire Banque (Peut seulement être construite dans les villes ayant plus de 1200 habitants)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Construire Usine papetière
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Construire Usine Agroalimentaire
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Construire Imprimerie
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Construire Mine d'Or
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Construire Banque (Peut seulement être construite en ville)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Construire Scierie (pour la coupe de forêt tropicale et la production de Bois)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Semer une Plantation de Fruits
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Semer une Plantation de Caoutchouc
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Construire Source d'eau
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Construire Château d'eau (Peut seulement être construite en ville)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Construire Mine de Diamant
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Construire Mine de Cuivre
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Semer une Forêt de Barbe à Papa
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Construire Usine de Sucreries
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Construire Ferme de Batteries
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Construire Puits de Cola
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Construire Boutique de Jouets
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Construire Usine de Jouets
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Construire Fontaines de Plastique
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Construire Usine de Boissons Gazeuses
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Construire Générateur de Bulles
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Construire Carrière de Caramel
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Construire Mine de Sucre
+STR_0285_CAN_T_BUILD_HERE :{WHITE}Impossible de construire {STRING} ici...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...doit d'abord construire une ville
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...Droit à un par ville seulement
+STR_0288_PLANT_TREES :{BLACK}Semer des arbres
+STR_0289_PLACE_SIGN :{BLACK}Placer un panneau
+STR_028A_RANDOM_TREES :{BLACK}Générer des arbres
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Semer des arbres sur l'ensemble du terrain de façon aléatoire
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Placer des endroits rocheux sur le terrain
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Placer un Phare
+STR_028E_PLACE_TRANSMITTER :{BLACK}Placer un Transmetteur
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Définir une zone désertique.{}Garder Ctrl enfoncé pour retrait
+STR_CREATE_LAKE :{BLACK}Définir une zone d'eau.{}Inondera ses abords si au niveau de la mer
+STR_0290_DELETE :{BLACK}Supprimer
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Supprimer complètement cette ville
+STR_0292_SAVE_SCENARIO :Sauvegarder scénario
+STR_0293_LOAD_SCENARIO :Charger scénario
+STR_0294_QUIT_EDITOR :Quitter éditeur
+STR_0295 :
+STR_0296_QUIT :Quitter
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Sauvegarder scénario, charger scénario, abandonner éditeur de scénario, quitter
+STR_0298_LOAD_SCENARIO :{WHITE}Charger Scénario
+STR_0299_SAVE_SCENARIO :{WHITE}Sauvegarder Scénario
+STR_029A_PLAY_SCENARIO :{BLACK}Jouer Scénario
+STR_PLAY_HEIGHTMAP :{BLACK}Jouer une carte d'altitude
+STR_PLAY_HEIGHTMAP_HINT :{BLACK}Démarrer une nouvelle partie, utilisant une carte d'altitude comme paysage
+STR_QUIT_SCENARIO_QUERY :{YELLOW}Voulez-vous vraiment quitter ce scénario ?
+STR_029C_QUIT_EDITOR :{WHITE}Quitter Éditeur
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...peut seulement être construit dans des villes ayant une population d'au moins 1200 habitants
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Reculer la date de départ d'un an
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Avancer la date de départ d'un an
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...les deux extrémités du pont doivent être sur la terre ferme
+STR_02A1_SMALL :{BLACK}Petite
+STR_02A2_MEDIUM :{BLACK}Moyenne
+STR_02A3_LARGE :{BLACK}Grande
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Sélectionner la taille de la ville
+STR_02A5_TOWN_SIZE :{YELLOW}Taille:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Afficher le dernier message ou bulletin
+STR_OFF :Aucun
+STR_SUMMARY :Sommaire
+STR_FULL :Complet
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Annuaire des villes
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Noms de conception des Véhicules
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Par Défaut
+STR_02BF_CUSTOM :Personnalisé
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Sauver les noms personnalisés
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Sélection des noms de conception de véhicule
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Sauvegarder noms personnalisés de conception de véhicule
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Options du Jeu
+STR_02C5_DIFFICULTY_SETTINGS :Niveau de Difficulté
+STR_02C7_CONFIG_PATCHES :Configuration Avancée
+STR_NEWGRF_SETTINGS :Paramètres Newgrf
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Afficher le nom des villes
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Afficher le nom des stations
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Afficher les panneaux
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Afficher les pts de contrôle
+STR_02D0_FULL_ANIMATION :{SETX 12}Animation complète
+STR_02D2_FULL_DETAIL :{SETX 12}Détails maximums
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Édifices transparents
+STR_TRANSPARENT_SIGNS :{SETX 12}Nom de station transparent
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Outil d'Inspection
+STR_02D6 :
+STR_CONSOLE_SETTING :Inverser Console
+STR_02D7_SCREENSHOT_CTRL_S :Copie d'écran (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Copie géante d'écran (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :À Propos de 'OpenTTD'
+############ range ends here
+
+STR_02DB_OFF :{BLACK}Inactif
+STR_02DA_ON :{BLACK}Actif
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Afficher les subventions
+STR_02DD_SUBSIDIES :Subventions
+STR_02DE_MAP_OF_WORLD :Carte du monde
+STR_EXTRA_VIEW_PORT :Vue supplémentaire
+STR_SIGN_LIST :Liste des panneaux
+STR_02DF_TOWN_DIRECTORY :Annuaire des villes
+STR_TOWN_POPULATION :{BLACK}Population mondiale : {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Vue {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Copier vers la vue
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Copie l'emplacement de la vue globale vers cette vue
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Coller depuis la vue
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Colle l'emplacement de cette vue vers la vue globale
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Unité monétaire
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Sélectionner l'unité monétaire
+STR_MEASURING_UNITS :{BLACK}Unité de mesure
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Sélectionner l'unité de mesure
+STR_02E6_ROAD_VEHICLES :{BLACK}Véhicules routiers
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Choisir le sens de conduite routière
+STR_02E9_DRIVE_ON_LEFT :Conduire à gauche
+STR_02EA_DRIVE_ON_RIGHT :Conduire à droite
+STR_02EB_TOWN_NAMES :{BLACK}Nom des villes
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Sélectionner le style des noms de ville
+
+STR_02F4_AUTOSAVE :{BLACK}Sauvegarde automatique
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Sélectionner l'intervalle de temps entre les sauvegardes automatiques
+STR_02F7_OFF :Inactif
+STR_02F8_EVERY_3_MONTHS :Tous les 3 mois
+STR_02F9_EVERY_6_MONTHS :Tous les 6 mois
+STR_02FA_EVERY_12_MONTHS :Tous les 12 mois
+STR_02FB_START_A_NEW_GAME :{BLACK}Commencer une nouvelle partie
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Charger une partie sauvée
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Créer un monde/scénario de jeu personnalisé
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Sélectionner mode joueur simple
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Sélectionnner une partie multi-joueurs de 2 à 8 joueurs
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Afficher les options du jeu
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Afficher les options de niveau de difficulté
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Débuter une nouvelle partie à partir d'un scénario
+STR_0304_QUIT :{BLACK}Quitter
+STR_0305_QUIT_OPENTTD :{BLACK}Quitter 'OpenTTD'
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...peut seulement être construit en ville
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Sélectionner l'environnement 'Tempéré'
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Sélectionner l'environnement 'Arctique'
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Sélectionner l'environnement 'Tropical'
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Sélectionner l'environnement 'Jouets'
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Financer la construction de nouvelles industries
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Annuaire des industries
+STR_0313_FUND_NEW_INDUSTRY :Financer une nouvelle industrie
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Financer une nouvelle industrie
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...peut seulement être construit en ville
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...peut seulement être construit en forêt tropicale
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...peut seulement être construit dans les endroits désertiques
+STR_0319_PAUSED :{YELLOW}* * SUSPENDU * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Copie d'écran enregistrée avec succès sous '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}Copie d'écran a échoué!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Acheter le terrain pour une utilisation ultérieure
+STR_032F_AUTOSAVE :{RED}ENREGISTREMENT AUTOMATIQUE
+STR_SAVING_GAME :{RED}* * Partie en Sauvegarde * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}Sauvegarde en cours,{}Veuillez attendre la fin du processus!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Sélectionner programme de musique 'Ezy Street'
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :Anglais (Originaux)
+STR_TOWNNAME_FRENCH :Français
+STR_TOWNNAME_GERMAN :Allemand
+STR_TOWNNAME_ADDITIONAL_ENGLISH :Anglais (Additionels)
+STR_TOWNNAME_LATIN_AMERICAN :Latino-Americain
+STR_TOWNNAME_SILLY :Drôles
+STR_TOWNNAME_SWEDISH :Suédois
+STR_TOWNNAME_DUTCH :Hollandais
+STR_TOWNNAME_FINNISH :Finnish
+STR_TOWNNAME_POLISH :Polonais
+STR_TOWNNAME_SLOVAKISH :Slovaques
+STR_TOWNNAME_NORWEGIAN :Norvégiens
+STR_TOWNNAME_HUNGARIAN :Hongrois
+STR_TOWNNAME_AUSTRIAN :Autrichiens
+STR_TOWNNAME_ROMANIAN :Roumain
+STR_TOWNNAME_CZECH :Tchèques
+STR_TOWNNAME_SWISS :Suisse
+STR_TOWNNAME_DANISH :Danois
+STR_TOWNNAME_TURKISH :Turques
+STR_TOWNNAME_ITALIAN :Italien
+STR_TOWNNAME_CATALAN :Catalan
+############ end of townname region
+
+STR_CURR_GBP :Livre (£)
+STR_CURR_USD :Dollar ($)
+STR_CURR_EUR :Euro (€)
+STR_CURR_YEN :Yen (Â¥)
+STR_CURR_ATS :Shiling Australien (ATS)
+STR_CURR_BEF :Franc Belge (BEF)
+STR_CURR_CHF :Franc Suisse (CHF)
+STR_CURR_CZK :Couronne Tchèque (CZK)
+STR_CURR_DEM :Mark Allemand (DEM)
+STR_CURR_DKK :Couronne Danoise (DKK)
+STR_CURR_ESP :Peseta (ESP)
+STR_CURR_FIM :Mark Finlandais (FIM)
+STR_CURR_FRF :Franc Français (FRF)
+STR_CURR_GRD :Drachme Grec (GRD)
+STR_CURR_HUF :Florint Hongrois (HUF)
+STR_CURR_ISK :Couronne Islandaise (ISK)
+STR_CURR_ITL :Lire Italienne (ITL)
+STR_CURR_NLG :Florint Hollandais (NLG)
+STR_CURR_NOK :Courronne Norvégienne (NOK)
+STR_CURR_PLN :Nouv. Zloty Polonais (PLN)
+STR_CURR_ROL :Leu Roumain (ROL)
+STR_CURR_RUR :Rouble Russe (RUR)
+STR_CURR_SIT :Tolar Slovénien (SIT)
+STR_CURR_SEK :Couronne Suédoise (SEK)
+STR_CURR_YTL :Lire Turque (YTL)
+STR_CURR_SKK :Couronne Slovaque (SKK)
+STR_CURR_BRR :Réal Brésilien (BRL)
+
+STR_CURR_CUSTOM :Personnalisée...
+
+STR_OPTIONS_LANG :{BLACK}Langue
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Sélectionner la langue d'interface à utiliser
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Plein écran
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}Cocher cette case pour jouer à OpenTTD plein écran
+
+STR_OPTIONS_RES :{BLACK}Résolution
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Sélectionner la résolution d'écran à utiliser
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Format de la copie d'écran
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Choisir le format de la copie d'écran
+
+STR_AUTOSAVE_1_MONTH :Tous les mois
+STR_AUTOSAVE_FAILED :{WHITE}Enregistrement automatique échoué
+
+STR_MONTH_JAN :Janvier
+STR_MONTH_FEB :Février
+STR_MONTH_MAR :Mars
+STR_MONTH_APR :Avril
+STR_MONTH_MAY :Mai
+STR_MONTH_JUN :Juin
+STR_MONTH_JUL :Juillet
+STR_MONTH_AUG :Août
+STR_MONTH_SEP :Septembre
+STR_MONTH_OCT :Octobre
+STR_MONTH_NOV :Novembre
+STR_MONTH_DEC :Décembre
+
+STR_HEADING_FOR_STATION :{LTBLUE}En route pour {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}En route pour {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Aucun ordre
+STR_NO_ORDERS_VEL :{LTBLUE}Aucun ordre, {VELOCITY}
+
+STR_PASSENGERS :passagers
+STR_BAGS :sacs
+STR_TONS :tonnes
+STR_LITERS :litres
+STR_ITEMS :items
+STR_CRATES :caisses
+STR_RES_OTHER :autre
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Impossible de partager les ordres...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Impossible de copier les ordres...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - Fin des ordres partagés - -
+
+STR_TRAIN_IS_LOST :{WHITE}Train {COMMA} est perdu.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}Train {COMMA} a eu un profit de {CURRENCY} l'an dernier
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}Union Monétaire Européenne !{}{}L'Euro est introduit en tant que monnaie unique pour les transactions dans votre pays !
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Train {COMMA} a trop peu d'ordres dans son itinéraire
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}Train {COMMA} a un ordre vide
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}Train {COMMA} a des ordres en double
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}Train {COMMA} a une station invalide dans ses ordres
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}Véhicule {COMMA} a trop peu d'ordres dans son programme
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}Véhicule {COMMA} a un ordre vide
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}Véhicule {COMMA} a des ordres en double
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}Véhicule {COMMA} a une station invalide dans ses ordres
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}Navire {COMMA} a trop peu d'ordres dans son programme
+STR_SHIP_HAS_VOID_ORDER :{WHITE}Navire {COMMA} a un ordre vide
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}Navire {COMMA} a des ordres en double
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}Navire {COMMA} a une station invalide dans ses ordres
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}Aéronef {COMMA} a trop peu d'ordres dans son programme
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}Aéronef {COMMA} a un ordre vide
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}Aéronef {COMMA} a des ordres en double
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}Aéronef {COMMA} a une station invalide dans ses ordres
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}Le renouvellement automatique a échoué sur Train {COMMA} (limite d'argent)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}Le renouvellement automatique a échoué sur Véhicule {COMMA} (limite d'argent)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}Le renouvellement automatique a échoué sur Navire {COMMA} (limite d'argent)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}Le renouvellement automatique a échoué sur Aéronef {COMMA} (limite d'argent)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}Train {COMMA} est trop long après remplacement
+
+STR_CONFIG_PATCHES :{BLACK}Options Avancées
+STR_CONFIG_PATCHES_TIP :{BLACK}Configurer les options avancées
+STR_CONFIG_PATCHES_CAPTION :{WHITE}Options Avancées
+
+STR_CONFIG_PATCHES_OFF :Inactif
+STR_CONFIG_PATCHES_ON :Actif
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Afficher vitesse du véhicule dans la barre d'état: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Construction côtière et sur pentes: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Autoriser des zones de désserte plus réalistes : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Permettre le retrait de plus d'éléments possédés par une ville: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Permettre les trains plus longs: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Permettre les accélérations réalistes pour les trains: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Interdire aux trains et navires les virages à 90° : {ORANGE}{STRING} {LTBLUE} (Nécessite le NPF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Joindre les gares juxtaposées: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Pleine cargaison par un seul type, si 'chargement complet': {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Utiliser l'algorithme amélioré de chargement : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GRADUAL_LOADING :{LTBLUE}Charger les véhicules graduellement: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Inflation: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Livrer cargaison seulement sur demande: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Permettre la construction de longs ponts: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Permettre l'ordre d'aller au dépôt: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Permettre la construction de ressources primaires: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Permettre plusieurs industries similaires par ville: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Permettre plusieurs industries similaires à proximité: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Afficher la date complète dans la barre d'état: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Signaux ferroviaires du côté du sens de conduite: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Afficher le bilan de finances en fin d'année: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}Compatibilité TTDPatch "nonstop handling": {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Mise en file Véhicules Routiers (+ effets quantiques): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Défiler la vue horizontalement avec le pointeur: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Permettre la corruption de la municipalité: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Gares non uniformes: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Nouvelle recherche de chemin globale (NPF, écrase NTP): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FREIGHT_TRAINS :{LTBLUE}Multiplieur de poids pour le fret (simule les trains lourds): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Toujours permettre les petits aéroports: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Avertir si le train est perdu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Vérification des ordres des véhicules : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :non
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :de tous, sauf ceux stoppés
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :de tous les véhicules
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Alerte en cas de profit négatif pour un train: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Les véhicules n'expirent jamais: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Renouveler automatiquement les véhicules quand ils sont vieux
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Auto-renouveler les véhicules {ORANGE}{STRING}{LTBLUE} mois avant/après l'âge maximum
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Argent nécessaire pour l'auto-renouvelement : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Temps d'affichage des messages d'erreur: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Afficher la population d'une ville dans son label : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Arbres invisibles (quand les bâtiments sont transparents) : {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Générateur de terrain : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :Original
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis
+STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}Distances max depuis les bords pour les Raffineries {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Altitude d'enneigement: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN :{LTBLUE}Rugosité du terrain (TerraGenesis seulement) : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Très lisse
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH :Lisse
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH :Rugueux
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :Très rugueux
+STR_CONFIG_PATCHES_TREE_PLACER :{LTBLUE}Algorithme de placement des arbres: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TREE_PLACER_NONE :Aucun
+STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL :Original
+STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED :Amélioré
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION :{LTBLUE}Rotation de la carte d'altitude: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Anti-horaire
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE :Horaire
+STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT :{LTBLUE}Le terrain d'un scénario plat a pour altitude : {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Etendue max. des stations: {ORANGE}{STRING} {RED}Attention: Valeur élevée = jeu lent
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Entretenir automatiquement les hélicoptères à l'héliport: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Relier la barre d'outils Paysage avec celle des rails/routes/eau et aéroport: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Inverser la direction lors du défilement avec la souris : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Montrer une infobulle de mesure lors de l'utilisation de divers outils de construction: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Affichage des livrées de compagnie : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES_NONE :Aucune
+STR_CONFIG_PATCHES_LIVERIES_OWN :Propre compagnie
+STR_CONFIG_PATCHES_LIVERIES_ALL :Toutes les compagnies
+STR_CONFIG_PATCHES_PREFER_TEAMCHAT :{LTBLUE}Préférer le chat d'équipe avec <ENTER>: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Nombre de trains max. par joueur: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Nombre de véhicules routiers max. par joueur: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}Nombre d'aéronefs max. par joueur: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}Nombre de navires max. par joueur: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Désactiver les trains pour l'ordinateur: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Désactiver les véhicules routiers pour l'ordinateur: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Désactiver les aéronefs pour l'ordinateur: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Désactiver les navires pour l'ordinateur: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Activer la nouvelle IA (alpha): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Permettre les IA en multi-joueurs (expérimental): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Entretien des trains tous les: {ORANGE}{STRING} jours
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Entretien des trains tous les: {ORANGE}inactif
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Entretien des véhicules routiers tous les: {ORANGE}{STRING} jours
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Entretien des véhicules routiers tous les: {ORANGE}inactif
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Entretien des aéronefs tous les: {ORANGE}{STRING} jours
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Entretien des aéronefs tous les: {ORANGE}inactif
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Entretien des navires tous les: {ORANGE}{STRING} jours
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Entretien des navires tous les: {ORANGE}inactif
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Désactiver les réparations quand les pannes sont inactives: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Permettre vitesse limite des Wagons: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}Désactiver les rails électriques: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Les journaux en couleur apparaissent en: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Année de départ: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}Année de fin: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Permettre une économie stable (plus de petits changements)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Permettre d'acheter des actions d'autres compagnies
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Espacements des signaux en mode drag & drop : {ORANGE}{STRING} case(s)
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Position de la barre d'outils principale: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :À gauche
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Centrée
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :À droite
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Rayon d'attraction des fenêtres : {ORANGE}{STRING} px
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Rayon d'attraction des fenêtres : {ORANGE}inactif
+
+STR_CONFIG_PATCHES_GUI :{BLACK}Interface
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Construction
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Véhicules
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Stations
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Economie
+STR_CONFIG_PATCHES_AI :{BLACK}Compétiteurs
+
+STR_CONFIG_PATCHES_DISABLED :inactif
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Changer valeur du paramètre
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Un ou plusieurs intervalles de service par défaut ci-dessous sont incompatibles avec le paramètre choisi! 5-90% et 30-800 jours sont valides
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}Utiliser YAPF pour les navires: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}Utiliser YAPF pour les véhicules routiers: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}Utiliser YAPF pour les trains: {ORANGE}{STRING}
+
+STR_TEMPERATE_LANDSCAPE :environnement 'Tempéré'
+STR_SUB_ARCTIC_LANDSCAPE :environnement 'Arctique'
+STR_SUB_TROPICAL_LANDSCAPE :environnement 'Tropical'
+STR_TOYLAND_LANDSCAPE :environnement 'Jouets'
+
+STR_CHEATS :{WHITE}Triches
+STR_CHEATS_TIP :{BLACK}Les cases à cocher indiquent que vous avez déjà utilisé cette triche auparavant
+STR_CHEATS_WARNING :{BLACK}Attention ! Vous êtes sur le point de trahir vos adversaires. Gardez en tête qu'une telle honte sera gardée en mémoire pour l'éternité.
+STR_CHEAT_MONEY :{LTBLUE}Augmenter l'argent de {CURRENCY64}
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Jouer en tant que joueur n°: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Bulldozer magique (enlèvement industries et objets fixes): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Les tunnels peuvent se croiser: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Construire pendant le mode pause: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Les jets ne s'écrasent plus (fréquemment) sur les petits aéroports: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Changer de climat : {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Changer la date: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}Permettre la modification des valeurs de production : {ORANGE}{STRING}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}En route pour {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}En route pour {WAYPOINT}, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :Passant par {WAYPOINT}
+STR_GO_NON_STOP_TO_WAYPOINT :Aller sans-arrêt via {WAYPOINT}
+
+STR_WAYPOINTNAME_CITY :Point de contrôle {TOWN}
+STR_WAYPOINTNAME_CITY_SERIAL :Point de contrôle {TOWN} #{COMMA}
+STR_LANDINFO_WAYPOINT :Point de contrôle
+
+STR_WAYPOINT :{WHITE}Point de passage
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Choisir le type de point de passage
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}Modifier nom du point de contrôle
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Impossible de modifier le nom du point de contrôle...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Construire un point de contrôle sur les rails
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Impossible de construire point de contrôle ici...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Impossible de retirer point de contrôle ici...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Construire les rails avec le mode AutoRail
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}...il n'y a pas de ville dans ce scenario
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}Etes-vous sûr de vouloir créer un terrain aléatoire?
+STR_MANY_RANDOM_TOWNS :{BLACK}Beaucoup de villes au hasard
+STR_RANDOM_TOWNS_TIP :{BLACK}Couvrir la carte avec des villes placées aléatoirement
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Beaucoup d'industries au hasard
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Couvrir la carte avec des industries placées au hasard
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Ne peut pas générer les industries...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Ouvre la barre d'outils du paysagement pour monter/descendre du terrain, planter des arbres, etc.
+STR_LANDSCAPING_TOOLBAR :{WHITE}Manipulation du paysage
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Niveler le terrain
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Au hasard
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}Planter des arbres de types choisis au hasard
+
+STR_CANT_BUILD_CANALS :{WHITE}Impossible de construire un canal ici...
+STR_BUILD_CANALS_TIP :{BLACK}Construire des canaux. Appuyer sur Ctrl pour placer de l'eau non canalisée (seulement au niveau de la mer).
+STR_LANDINFO_CANAL :Canal
+
+STR_CANT_BUILD_LOCKS :{WHITE}Impossible de construire un écluse ici...
+STR_BUILD_LOCKS_TIP :{BLACK}Construire des écluses
+STR_LANDINFO_LOCK :Ecluse
+
+STR_BUOY_IS_IN_USE :{WHITE}... bouée utilisée !
+
+STR_LANDINFO_COORDS :{BLACK}Coordonnées: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Impossible de supprimer une partie de la gare...
+STR_CANT_CONVERT_RAIL :{WHITE}Impossible de convertir le type de rail...
+STR_CONVERT_RAIL_TIP :{BLACK}Convertir/Améliorer le type de rail
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Faire Glisser la locomotive ici pour vendre tout le train
+
+STR_DRAG_DROP :{BLACK}Glisser/déposer
+STR_STATION_DRAG_DROP :{BLACK}Construire une gare avec le glisser/déposer
+STR_SELECT_STATION_CLASS_TIP :{BLACK}Choisir la classe de station à afficher
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Choisir le type de station à construire
+
+STR_FAST_FORWARD :{BLACK}Avance rapide du jeu
+STR_MESSAGE_HISTORY :{WHITE}Historique des Messages
+STR_MESSAGE_HISTORY_TIP :{BLACK}Liste des messages récents
+STR_MESSAGES_DISABLE_ALL :{BLACK}Tous en sommaire
+STR_MESSAGES_ENABLE_ALL :{BLACK}Tous en complet
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Construire une mine de charbon
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Planter une forêt
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Construire une plateforme pétrolière
+STR_CONSTRUCT_FARM_TIP :{BLACK}Financer une ferme
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Construire une mine de cuivre
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Forer pour trouver du pétrole
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Construire une mine d'or
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Construire une mine de diamants
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Construire une mine de fer
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Financer une plantation de fruits
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Financer une plantation de caoutchouc
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Financer la construction d'une Source d'eau
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Planter une forêt de barbe à papa
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}Financer une ferme de piles
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Forer pour trouver du cola
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Financer des fontaines à plastique
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Construire un générateur de bulles
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Construire une carrière de caramel
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Construire une mine de sucre
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Industries
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA}% transporté)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA}%/{COMMA}% transporté)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}...trop proche d'une autre industrie
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Réaménager le train pour transporter une cargaison différente
+STR_RAIL_REFIT_VEHICLE :{BLACK}Réaménager le train
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Choisir le type de cargaison à transporter
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Réaménager le train pour transporter la cargaison sélectionnée
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Impossible de réaménager le train...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Les intervalles de service sont en pourcentage: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Changer la production
+
+TEMP_AI_IN_PROGRESS :{WHITE}Bienvenue dans la nouvelle IA, en élaboration. Copiez l'écran des problèmes et postez-le sur le forum. Bonne partie!
+TEMP_AI_ACTIVATED :{WHITE}Attention: cette nouvelle IA est en version alpha ! Pour le moment seuls les camions et les bus fonctionnent !
+TEMP_AI_MULTIPLAYER :{WHITE}Attention: cette fonction est encore expérimentale. Veuillez en rapporter les problèmes à truelight@openttd.org.
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Multijoueur
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Nom du joueur:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}Ceci est le nom avec lequel les autres joueurs pourront vous identifier
+STR_NETWORK_CONNECTION :{BLACK}Connection :
+STR_NETWORK_CONNECTION_TIP :{BLACK}Choisir entre un jeu Internet ou sur réseau local
+
+STR_NETWORK_START_SERVER :{BLACK}Démarrer le serveur
+STR_NETWORK_START_SERVER_TIP :{BLACK}Démarre son propre serveur
+
+STR_NETWORK_GAME_NAME :{BLACK}Nom
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Nom de la partie
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Langage, version du serveur, etc.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Cliquer sur une partie de la liste pour la sélectionner
+
+STR_NETWORK_FIND_SERVER :{BLACK}Trouver un serveur
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Cherche sur le réseau un serveur
+STR_NETWORK_ADD_SERVER :{BLACK}Ajouter un serveur
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Ajouter à la liste un serveur où le jeu cherchera toujours des parties en cours.
+STR_NETWORK_ENTER_IP :{BLACK}Saisir l'adresse IP du serveur
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Clients
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Clients en ligne / clients max
+STR_NETWORK_GAME_INFO :{SILVER}INFO DE LA PARTIE
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Clients: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Langue: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Terrain: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Taille de la carte : {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}Version du serveur : {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}Adresse du serveur : {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Date de début : {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Date courante : {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Protégée par mot de passe !
+STR_NETWORK_SERVER_OFFLINE :{SILVER}SERVEUR HORS-LIGNE
+STR_NETWORK_SERVER_FULL :{SILVER}SERVEUR PLEIN
+STR_NETWORK_VERSION_MISMATCH :{SILVER}VERSION NON CORRESPONDANTE
+STR_NETWORK_GRF_MISMATCH :{SILVER}NEWGRF DIFFERENTS
+
+STR_NETWORK_JOIN_GAME :{BLACK}Rejoindre la partie
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}Commencer une nouvelle partie
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Nom de la partie:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}Le nom de la partie sera affiché aux autres joueurs dans le menu de sélection de partie multijoueur
+STR_NETWORK_SET_PASSWORD :{BLACK}Choisir le mot de passe
+STR_NETWORK_PASSWORD_TIP :{BLACK}Protéger votre partie avec un mot de passe si vous ne souhaitez pas que d'autres l'utilisent
+STR_NETWORK_SELECT_MAP :{BLACK}Choisir une carte:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}Sur quelle carte désirez-vous jouer?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}Nombre de clients max. :
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Choisir un nombre maximum de clients. Tous les emplacements n'auront pas besoin d'être remplis.
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :LAN
+STR_NETWORK_INTERNET :Internet
+STR_NETWORK_LAN_INTERNET :LAN / Internet
+STR_NETWORK_INTERNET_ADVERTISE :Internet (publier)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 joueur
+STR_NETWORK_1_PLAYERS :1 joueur
+STR_NETWORK_2_PLAYERS :2 joueurs
+STR_NETWORK_3_PLAYERS :3 joueurs
+STR_NETWORK_4_PLAYERS :4 joueurs
+STR_NETWORK_5_PLAYERS :5 joueurs
+STR_NETWORK_6_PLAYERS :6 joueurs
+STR_NETWORK_7_PLAYERS :7 joueurs
+STR_NETWORK_8_PLAYERS :8 joueurs
+STR_NETWORK_9_PLAYERS :9 joueurs
+STR_NETWORK_10_PLAYERS :10 joueurs
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}Max compagnies:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Limiter le serveur à un certain nombre de compagnies
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}Max spectateurs:
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Limiter le serveur à un certain nombre de spectateurs
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Langue parlée :
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Les autres joueurs sauront quelle langue est parlée sur ce serveur.
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}Démarrer la partie
+STR_NETWORK_START_GAME_TIP :{BLACK}Démarrer une nouvelle partie réseau à partir d'une carte aléatoire ou d'un scénario
+STR_NETWORK_LOAD_GAME :{BLACK}Charger une partie
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Continuer une partie multijoueur sauvée précédemment (attention à reprendre le même joueur)
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Peu importe
+STR_NETWORK_LANG_ENGLISH :Anglais
+STR_NETWORK_LANG_GERMAN :Allemand
+STR_NETWORK_LANG_FRENCH :Français
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Chat d'avant jeu
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Se prépare à rejoindre : {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}Liste des compagnies présentes dans le jeu. Vous pouvez soit en rejoindre une, soit en créer une.
+STR_NETWORK_NEW_COMPANY :{BLACK}Nouvelle compagnie
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Crée une nouvelle compagnie
+STR_NETWORK_SPECTATE_GAME :{BLACK}Observer une partie
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Permet d'observer une partie en tant que spectateur
+STR_NETWORK_JOIN_COMPANY :{BLACK}Rejoindre la compagnie
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Aider à gérer cette compagnie
+STR_NETWORK_REFRESH :{BLACK}Rafraîchir
+STR_NETWORK_REFRESH_TIP :{BLACK}Rafraîchir les infos à propos du serveur
+
+STR_NETWORK_COMPANY_INFO :{SILVER}INFO DE LA COMPAGNIE
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Nom de la compagnie : {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}Inauguration : {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}Valeur de la compagnie : {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Argent courant : {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Revenus de l'année dernière : {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}Performance : {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}Véhicules : {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Stations : {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Joueurs : {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}Connection en cours...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) Connection en cours..
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Autorisation en cours..
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Attente..
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Téléchargement de la carte..
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Traitement des données..
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) Enregistrement..
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Rapatriement des infos sur le jeu..
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Rapatriement des infos sur la compagnie..
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} client{P "" s} avant nous
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} ko déjà téléchargés
+
+STR_NETWORK_DISCONNECT :{BLACK}Déconnecter
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Saisir le montant d'argent que vous désirez transférer
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Le serveur est protégé. Entrez le mot de passe
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}La compagnie est protégée. Entrez le mot de passe
+STR_NETWORK_CLIENT_LIST :{WHITE}Liste des clients
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE} Aucun périphérique réseau trouvé ou programme compilé sans ENABLE_NETWORK
+STR_NETWORK_ERR_NOSERVER :{WHITE} Aucune partie réseau n'a été trouvée
+STR_NETWORK_ERR_NOCONNECTION :{WHITE} Le serveur n'a pas répondu à la requête
+STR_NETWORK_ERR_DESYNC :{WHITE} La synchronisation de la partie réseau a échouée.
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} La connection de la partie réseau a été perdue.
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} La sauvegarde serveur n'a pas pu être chargée.
+STR_NETWORK_ERR_SERVER_START :{WHITE} Le serveur n'a pas pu être démarré.
+STR_NETWORK_ERR_CLIENT_START :{WHITE} Connection échouée.
+STR_NETWORK_ERR_TIMEOUT :{WHITE} La connection #{NUM} a dépassé le temps d'attente.
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE} Il y a eu une erreur de protocole et la connection est donc fermée.
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE} La révision de ce client ne correspond pas à celle du serveur.
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} Mot de passe incorrect.
+STR_NETWORK_ERR_SERVER_FULL :{WHITE} Le serveur est plein
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} Vous êtes bannis de ce serveur
+STR_NETWORK_ERR_KICKED :{WHITE} Vous avez été exclu de la partie
+STR_NETWORK_ERR_CHEATER :{WHITE} Tricher n'est pas autorisé sur ce serveur
+
+STR_NETWORK_ERR_LEFT :a quitté la partie
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :erreur générale
+STR_NETWORK_ERR_CLIENT_DESYNC :erreur de désynchronisation
+STR_NETWORK_ERR_CLIENT_SAVEGAME :chargement de la carte impossible
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :connection perdue
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :erreur de protocole
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :non autorisé
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :paquet étrange reçu
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :révision incorrecte
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :nom déjà utilisé
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :mot de passe de partie incorrect
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :mauvais player-id dans DoCommand
+STR_NETWORK_ERR_CLIENT_KICKED :jeté par le serveur
+STR_NETWORK_ERR_CLIENT_CHEATER :a tenté de tricher
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :Serveur complet
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :a rejoint la partie
+STR_NETWORK_GIVE_MONEY :vous a donné un peu d'argent ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :Vous avez envoyé à {STRING} la somme de ({CURRENCY})
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Equipe] :
+STR_NETWORK_CHAT_COMPANY :[Equipe] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Equipe] A {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[Privé] :
+STR_NETWORK_CHAT_CLIENT :[Privé] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[Privé] A {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[Tous] :
+STR_NETWORK_CHAT_ALL :[Tous] {STRING}: {GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :a changé son nom pour
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE} Le serveur a fermé la session
+STR_NETWORK_SERVER_REBOOT :{WHITE} Le serveur redémarre...{}Veuillez patienter...
+
+STR_NETWORK_SERVER :Serveur
+STR_NETWORK_CLIENT :Client
+STR_NETWORK_SPECTATORS :Spectateurs
+
+STR_NETWORK_CLIENTLIST_NONE :(aucun)
+STR_NETWORK_CLIENTLIST_KICK :Jeter
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Donner de l'argent
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Parler à tous
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Parler à la compagnie
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Message privé
+
+
+STR_NETWORK_SEND :{BLACK}Envoyer
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}Taille X de la carte : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Taille Y de la carte : {ORANGE}{STRING}
+
+
+##### PNG-MAP-Loader
+
+STR_PNGMAP_ERROR :{WHITE}Chargement du paysage depuis PNG impossible...
+STR_PNGMAP_ERR_FILE_NOT_FOUND :{WHITE}...fichier non trouvé.
+STR_PNGMAP_ERR_IMAGE_TYPE :{WHITE}...ne peut pas convertir le type d'image. Image PNG 8 ou 24-bit nécessaire.
+STR_PNGMAP_ERR_MISC :{WHITE}...quelque chose s'est mal passé. Désolé. (le fichier est probablement corrompu)
+
+STR_BMPMAP_ERROR :{WHITE}Chargement du paysage depuis BMP impossible...
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}...ne peut pas convertir le type d'image.
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Coût: {CURRENCY}
+STR_0801_COST :{RED}Coût: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Revenu: {CURRENCY}
+STR_0803_INCOME :{GREEN}Revenu: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Transfert: {CURRENCY}
+STR_FEEDER :{YELLOW}Transfert: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Coût Estimé: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Revenu Estimé: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Impossible d'élever le terrain ici...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Impossible d'abaisser le terrain ici...
+STR_080A_ROCKS :Roches
+STR_080B_ROUGH_LAND :Terre en friche
+STR_080C_BARE_LAND :Terre nue
+STR_080D_GRASS :Herbe
+STR_080E_FIELDS :Champs
+STR_080F_SNOW_COVERED_LAND :Terre enneigée
+STR_0810_DESERT :Désert
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Terrain en pente dans la mauvaise direction
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Combinaison de rail impossible
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}L'excavation endommagerait le tunnel
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Déjà au niveau de la mer
+STR_1004_TOO_HIGH :{WHITE}Trop élevé
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Aucuns rails convenables
+STR_1007_ALREADY_BUILT :{WHITE}...déjà construit
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Doit d'abord enlever les rails
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Construction de voie ferrée
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Construction de voie ferrée électrifiée
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Construction de Monorail
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}Construction de MagLev
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Choisir Pont Ferroviaire
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Impossible de construire un dépôt ferroviaire ici...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Impossible de construire la gare ici...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Impossible de construire des signaux ici...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Impossible de construire des rails ici...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Impossible de retirer les rails d'ici...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Impossible de retirer les signaux d'ici...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Orientation du Dépôt
+STR_1015_RAILROAD_CONSTRUCTION :Construction de voie ferrée
+STR_TOOLB_ELRAIL_CONSTRUCTION :Construction de voie ferrée électrifiée
+STR_1016_MONORAIL_CONSTRUCTION :Construction de Monorail
+STR_1017_MAGLEV_CONSTRUCTION :Construction de MagLev
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Construire des rails
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Construire un dépôt ferroviaire (pour construire et entretenir les trains)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Construire une gare
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Construire des signaux
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Construire un pont ferroviaire
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Construire un tunnel ferroviaire
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Basculer construire/retirer pour rails et signaux
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Sélection de Pont - cliquer sur le type de pont désiré pour le construire
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Choisir l'orientation du dépôt ferroviaire
+STR_1021_RAILROAD_TRACK :Rails
+STR_1023_RAILROAD_TRAIN_DEPOT :Dépôt ferroviaire
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...appartient à une autre compagnie
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :Rails avec des signaux normaux
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :Rails avec des pré-signaux
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :Rails avec des signaux de sortie
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :Rails avec des signaux combinés
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Doit d'abord retirer la route
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Route en travaux
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Construction routière
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Choisir Pont Routier
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Impossible de construire la route ici...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Impossible de retirer la route ici...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Orientation du dépôt
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Impossible de construire un dépôt routier ici...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Impossible de construire un arrêt d'autobus...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Impossible de construire une station de camions...
+STR_180A_ROAD_CONSTRUCTION :Construction routière
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Construire une section de route
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Construire un dépôt routier (pour construire et entretenir les véhicules routiers)
+STR_180D_BUILD_BUS_STATION :{BLACK}Construire un arrêt d'autobus
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Construire une station de camions
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Construire un pont routier
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Construire un tunnel routier
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Basculer construire/détruire routes
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Choisir orientation du dépôt routier
+STR_1814_ROAD :Route
+STR_1815_ROAD_WITH_STREETLIGHTS :Route avec lampadaires
+STR_1816_TREE_LINED_ROAD :Route avec lignée d'arbustres
+STR_1817_ROAD_VEHICLE_DEPOT :Dépôt de véhicules routiers
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :Route/rail Croisement à niveau
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Villes
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}L'édifice doit d'abord être démolit
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}Population: {ORANGE}{COMMA}{BLACK} Maisons: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Renommer Ville
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Impossible de renommer la ville...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}La municipalité de {TOWN} refuse cette opération
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Noms des villes - Cliquer sur un nom pour défiler à l'emplacement
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centrer la vue sur la ville
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Renommer la ville
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passagers le mois dernier : {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Courrier le mois dernier : {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Grand immeuble de bureaux
+STR_2010_OFFICE_BLOCK :Immeuble de bureaux
+STR_2011_SMALL_BLOCK_OF_FLATS :Petit immeuble résidentiel
+STR_2012_CHURCH :Eglise
+STR_2013_LARGE_OFFICE_BLOCK :Gros immeuble de bureau
+STR_2014_TOWN_HOUSES :Bâtiments municipaux
+STR_2015_HOTEL :Hôtel
+STR_2016_STATUE :Statue
+STR_2017_FOUNTAIN :Fontaine
+STR_2018_PARK :Parc
+STR_2019_OFFICE_BLOCK :Immeuble de bureaux
+STR_201A_SHOPS_AND_OFFICES :Commerces et bureaux
+STR_201B_MODERN_OFFICE_BUILDING :Immeuble moderne de bureaux
+STR_201C_WAREHOUSE :Entrepôt
+STR_201D_OFFICE_BLOCK :Immeuble de bureaux
+STR_201E_STADIUM :Stade
+STR_201F_OLD_HOUSES :Vieilles maisons
+STR_2020_LOCAL_AUTHORITY :{BLACK}Municipalité
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Afficher des informations sur la municipalité
+STR_2022_LOCAL_AUTHORITY :{WHITE}Municipalité de {TOWN}
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Notation de la compagnie de transport:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Subventions
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Offres de subvention pour le transport de:
+STR_2027_FROM_TO :{ORANGE}{STRING} de {STRING} à {STRING}
+STR_2028_BY :{YELLOW} (avant {DATE_SHORT})
+STR_202A_NONE :{ORANGE}Aucune
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Subventions déjà accordées:
+STR_202C_FROM_TO :{ORANGE}{STRING} de {STATION} à {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, jusqu'à {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}Offre de subvention expirée:{}{}Le transport de {STRING} entre {STRING} et {STRING} n'est désormais plus subventionné.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Abandon de la subvention:{}{}Le transport de {STRING} entre {STATION} et {STATION} n'est plus subventionné.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Offre de subvention:{}{}Le premier service de {STRING} entre {STRING} et {STRING} sera subventionné pendant un an!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subvention accordée à {COMPANY}!{}{}Le transport de {STRING} entre {STATION} et {STATION} rapportera 50% de plus l'année prochaine!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subvention accordée à {COMPANY}!{}{}Le transport de {STRING} entre {STATION} et {STATION} rapportera double l'année prochaine!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subvention accordée à {COMPANY}!{}{}Le transport de {STRING} entre {STATION} et {STATION} rapportera triple l'année prochaine!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subvention accordée à {COMPANY}!{}{}Le transport de {STRING} entre {STATION} et {STATION} rapportera quadruple l'année prochaine!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}La municipalité de {TOWN} refuse la construction d'un autre aéroport dans la ville
+STR_2036_COTTAGES :Petites maisons
+STR_2037_HOUSES :Maisons
+STR_2038_FLATS :Appartements
+STR_2039_TALL_OFFICE_BLOCK :Grand immeuble de bureau
+STR_203A_SHOPS_AND_OFFICES :Commerces et bureaux
+STR_203B_SHOPS_AND_OFFICES :Commerces et bureaux
+STR_203C_THEATER :Théâtre
+STR_203D_STADIUM :Stade
+STR_203E_OFFICES :Bureaux
+STR_203F_HOUSES :Maisons
+STR_2040_CINEMA :Cinéma
+STR_2041_SHOPPING_MALL :Centre commercial
+STR_2042_DO_IT :{BLACK}Lancer cette action
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}Liste des actions à entreprendre dans cette ville - Cliquer sur une action pour obtenir des détails
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Lancer l'action sélectionnée ci-dessus
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Actions disponibles:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Petite campagne de publicité
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Moyenne campagne de publicitié
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Grande campagne de publicité
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Financer la reconstruction du réseau routier local
+STR_204A_BUILD_STATUE_OF_COMPANY :Construire une statue à votre effigie
+STR_204B_FUND_NEW_BUILDINGS :Financer de nouveaux bâtiments
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Acheter les droits de transports exclusifs
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Corrompre la municipalité
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Lancer une petite campagne de publicité, pour attirer plus de voyageurs et de marchandises sur vos lignes.{} Coût: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Lancer une campagne de publicité moyenne, pour attirer plus de voyageurs et de marchandises sur vos lignes.{} Coût: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Lancer une grande campagne de publicité, pour attirer plus de voyageurs et de marchandises sur vos lignes.{} Coût: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} Financer la reconstruction du réseau routier local. Provoque de nombreux problèmes de traffic routier pendant 6 mois.{} Coût: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Construire une statue en l'honneur de votre compagnie.{} Coût: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Financer la construction de nouveaux immeubles commerciaux.{} Coût: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Acheter les droits de transports exclusifs dans cette ville pour 1 an. Seules vos ligness seront autorisées dans la ville.{} Coût: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Corrompre la municipalité pour améliorer votre réputation. Risque de pénalisation si le pot-de-vin est dévoilé.{} Coût: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}Problèmes de traffic à {TOWN}!{}{}La reconstruction des routes financée par {COMPANY} provoque 6 mois de problèmes aux automobilistes!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (en contruction)
+STR_2059_IGLOO :Iglou
+STR_205A_TEPEES :Tipis
+STR_205B_TEAPOT_HOUSE :Salon de thé
+STR_205C_PIGGY_BANK :Tirelire
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN} {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Modification du paysage
+STR_2800_PLANT_TREES :Planter des arbres
+STR_2801_PLACE_SIGN :Placer un panneau
+STR_2802_TREES :{WHITE}Arbres
+STR_2803_TREE_ALREADY_HERE :{WHITE}...il y a déjà des arbres
+STR_2804_SITE_UNSUITABLE :{WHITE}...l'endroit ne convient pas
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Plantation impossible...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...trop de panneaux
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Place du panneau impossible...
+STR_280A_SIGN :Panneau
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Editer le texte du panneau
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Impossible d'éditer le texte...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Choix du type d'arbre
+STR_280E_TREES :Arbres
+STR_280F_RAINFOREST :Forêt tropicale
+STR_2810_CACTUS_PLANTS :Cactus
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Choix de la gare
+STR_3001_AIRPORT_SELECTION :{WHITE}Choix de l'aéroport
+STR_3002_ORIENTATION :{BLACK}Orientation
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Nombre de voies
+STR_3004_PLATFORM_LENGTH :{BLACK}Longueur du quai
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Trop près d'une autre gare
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Ajouter une ou plusieurs gares
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}Trop de gares dans cette ville
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}Trop de gares
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Trop d'arrêts d'autobus
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}Trop d'aires de chargement
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Trop près d'une autre gare
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Vous devez d'abord détruire la gare
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Trop près d'un autre aéroport
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Vous devez d'abord détruire l'aéroport
+
+STR_3030_RENAME_STATION_LOADING :Renommer la gare
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Impossible de renommer la gare...
+STR_3032_RATINGS :{BLACK}Notations
+STR_3033_ACCEPTS :{BLACK}Accepte
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}Notation du service de transport:
+
+############ range for rating starts
+STR_3035_APPALLING :Épouvantable
+STR_3036_VERY_POOR :Très pauvre
+STR_3037_POOR :Pauvre
+STR_3038_MEDIOCRE :Médiocre
+STR_3039_GOOD :Bon
+STR_303A_VERY_GOOD :Très bon
+STR_303B_EXCELLENT :Excellent
+STR_303C_OUTSTANDING :Exceptionnel
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} n'accepte plus: {STRING}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} n'accepte plus: {STRING} ou {STRING}
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} accepte désormais: {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} accepte désormais: {STRING} et {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Arrêt d'autobus
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Station de camions
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Détruire d'abord l'arrêt d'autobus
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Détruisez d'abord la station
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Station{P "" s}
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Aucun -
+STR_304B_SITE_UNSUITABLE :{WHITE}...l'endroit ne convient pas
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Trop près d'un autre port
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Détruisez d'abord le port
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Choisir l'orientation de la gare ferroviaire
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Choix du nombre de voies
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Choisir la longueur de la gare
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Choisir l'orientation de l'arrêt d'autobus
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Choix de l'orientation de l'aire de chargement
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Centrer la vue sur la station
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Afficher la notation de la station
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Renommer la station
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Afficher les marchandises acceptées
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Nom des stations - Cliquer sur un nom pour centrer la vue
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Choix du type & taille de l'aéroport
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :Gare ferroviaire
+STR_305F_AIRCRAFT_HANGAR :Hangar d'aéronefs
+STR_3060_AIRPORT :Aéroport
+STR_3061_TRUCK_LOADING_AREA :Aire de chargement
+STR_3062_BUS_STATION :Arrêt d'autobus
+STR_3063_SHIP_DOCK :Port
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Afficher la zone couverte
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Ne pas afficher la zone couverte
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Afficher la zone couverte
+STR_3068_DOCK :{WHITE}Port
+STR_3069_BUOY :Bouée
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...bouée présente
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...gare trop étendue
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...stations non-uniformes désactivées
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Cliquer avec Ctrl pour sélectionner plus d'un élément
+
+STR_UNDEFINED :(chaîne non définie)
+STR_STAT_CLASS_DFLT :Station par défaut
+STR_STAT_CLASS_WAYP :Points de passage
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Orientation du dépot naval
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...doit être construit sur l'eau
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Impossible de construire le dépôt naval ici...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Choisir l'orientation du dépôt naval
+STR_3804_WATER :Eau
+STR_3805_COAST_OR_RIVERBANK :Rivage ou berge
+STR_3806_SHIP_DEPOT :Dépôt naval
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...Impossible de construire sur l'eau
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Sauvegarder la partie
+STR_4001_LOAD_GAME :{WHITE}Charger une partie
+STR_4002_SAVE :{BLACK}Sauvegarder
+STR_4003_DELETE :{BLACK}Supprimer
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} Mo libres
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Impossible d'accéder au disque
+STR_4007_GAME_SAVE_FAILED :{WHITE}La sauvegarde à échoué
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Impossible de supprimer le fichier
+STR_4009_GAME_LOAD_FAILED :{WHITE}Le chargement à échoué
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}Liste des disques, répertoires, et fichiers de sauvegarde
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Nom sélectionné pour la sauvegarde
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Supprime la sauvegarde sélectionnée
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Sauvegarde la partie avec le nom choisi
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Choix du type de partie
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Choisir un scénario (vert), une partie préparée (bleu), ou une partie aléatoire
+STR_4010_GENERATE_RANDOM_NEW_GAME :Générer une partie aléatoirement
+STR_4011_LOAD_HEIGHTMAP :{WHITE}Charger une carte d'altitude
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} présente
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :{G=f}Mine de charbon
+STR_4803_POWER_STATION :{G=f}Centrale électrique
+STR_4804_SAWMILL :{G=f}Scierie
+STR_4805_FOREST :{G=f}Forêt
+STR_4806_OIL_REFINERY :{G=f}Raffinerie pétrolière
+STR_4807_OIL_RIG :{G=f}Plate-forme pétrolière
+STR_4808_FACTORY :{G=f}Usine
+STR_4809_PRINTING_WORKS :{G=f}Imprimerie
+STR_480A_STEEL_MILL :{G=f}Aciérie
+STR_480B_FARM :{G=f}Ferme
+STR_480C_COPPER_ORE_MINE :{G=f}Mine de cuivre
+STR_480D_OIL_WELLS :{G=m}Puits de pétrole
+STR_480E_BANK :{G=f}Banque
+STR_480F_FOOD_PROCESSING_PLANT :{G=f}Usine alimentaire
+STR_4810_PAPER_MILL :{G=f}Usine papetière
+STR_4811_GOLD_MINE :{G=f}Mine d'or
+STR_4812_BANK :{G=f}Banque
+STR_4813_DIAMOND_MINE :{G=f}Mine de diamants
+STR_4814_IRON_ORE_MINE :{G=f}Mine de fer
+STR_4815_FRUIT_PLANTATION :{G=f}Plantation de fruits
+STR_4816_RUBBER_PLANTATION :{G=f}Plantation de caoutchouc
+STR_4817_WATER_SUPPLY :{G=m}Réservoir d'eau
+STR_4818_WATER_TOWER :{G=m}Château d'eau
+STR_4819_FACTORY :{G=f}Usine
+STR_481A_FARM :{G=f}Ferme
+STR_481B_LUMBER_MILL :{G=f}Scierie
+STR_481C_COTTON_CANDY_FOREST :{G=f}Forêt de Barbe à Papa
+STR_481D_CANDY_FACTORY :{G=f}Usine de Sucreries
+STR_481E_BATTERY_FARM :{G=f}Ferme de Batteries
+STR_481F_COLA_WELLS :{G=m}Puits de Cola
+STR_4820_TOY_SHOP :{G=f}Boutique de Jouets
+STR_4821_TOY_FACTORY :{G=f}Usine de Jouets
+STR_4822_PLASTIC_FOUNTAINS :{G=f}Fontaines de plastique
+STR_4823_FIZZY_DRINK_FACTORY :{G=f}Usine de Boissons Gazeuses
+STR_4824_BUBBLE_GENERATOR :{G=m}Générateur de Bulles
+STR_4825_TOFFEE_QUARRY :{G=f}Carrière de caramel
+STR_4826_SUGAR_MINE :{G=f}Mine de sucre
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Nécessite: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Nécessite: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Nécessite: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Production le mois dernier:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% transporté)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centrer la vue sur l'industrie
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Un{G "" "" e} nouv{G eau el elle} {STRING} en construction près de {TOWN}!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Un{G "" "" e} nouv{G eau el elle} {STRING} s'implante près de {TOWN}!
+STR_482F_COST :{BLACK}Prix: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Impossible de construire cette industrie ici...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...les forêts ne peuvent pas être plantées sur de la neige
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} annonce une fermeture imminente!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}Des problèmes d'approvisionnement forcent {INDUSTRY} à fermer bientôt!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}Le manque d'arbres proches force {INDUSTRY} à fermer bientôt!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} augmente la production!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}Nouveau filon de charbon trouvé à {INDUSTRY}!{}La production devrait doubler!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}Nouveaux gisements pétrolifères découverts à {INDUSTRY}!{}La production devrait doubler!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}De nouvelles méthodes d'élevage à {INDUSTRY} permettent de doubler la production!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}{INDUSTRY} : production en baisse de 50%
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}Invasion d'insectes à {INDUSTRY}!{}Production en baisse de 50%
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...positionnement uniquement sur les bords de la carte
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}La production de {STRING} à {INDUSTRY} augmente de {COMMA}%!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}La production de {STRING} à {INDUSTRY} diminue de {COMMA}%!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Train dans le tunnel
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Véhicule dans le tunnel
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Autre tunnel présent
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Impossible de creuser pour faire déboucher le tunnel
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Vous devez démolir le tunnel avant
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Vous devez d'abord démolir le pont
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Impossible de commencer et de terminer au même endroit
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Crevasse ou eau requise sous le pont
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}Le début et la fin doivent être alignés
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Le site pour l'entrée du tunnel ne convient pas
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Suspendu en acier
+STR_500F_GIRDER_STEEL :À poutres en Acier
+STR_5010_CANTILEVER_STEEL :Porte-à-faux en acier
+STR_5011_SUSPENSION_CONCRETE :Suspendu en béton
+STR_5012_WOODEN :En Bois
+STR_5013_CONCRETE :Béton
+STR_5014_TUBULAR_STEEL :À Tubes en Acier
+STR_BRIDGE_TUBULAR_SILICON :À Tubes en Silicone
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Impossible de construire un pont ici...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Impossible de construire un tunnel ici...
+STR_5017_RAILROAD_TUNNEL :Tunnel ferroviaire
+STR_5018_ROAD_TUNNEL :Tunnel routier
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Pont ferroviaire suspendu en acier
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Pont ferroviaire à poutres en acier
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Pont ferroviaire à porte-à-faux en acier
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Pont ferroviaire suspendu renforcé en béton
+STR_501F_WOODEN_RAIL_BRIDGE :Pont ferroviaire en bois
+STR_5020_CONCRETE_RAIL_BRIDGE :Pont ferroviaire en béton
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Pont routier suspendu en acier
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Pont routier à poutres en acier
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Pont routier à porte-à-faux en acier
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Pont routier suspendu renforcé en béton
+STR_5025_WOODEN_ROAD_BRIDGE :Pont routier en bois
+STR_5026_CONCRETE_ROAD_BRIDGE :Pont routier en béton
+STR_5027_TUBULAR_RAIL_BRIDGE :Pont ferroviaire à tubes
+STR_5028_TUBULAR_ROAD_BRIDGE :Pont ferroviaire à tubes en acier
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Objet présent
+STR_5801_TRANSMITTER :Transmetteur
+STR_5802_LIGHTHOUSE :Phare
+STR_5803_COMPANY_HEADQUARTERS :Siège de la compagnie
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...siège de la compagnie présent
+STR_5805_COMPANY_OWNED_LAND :Terrain appartenant à une compagnie
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Impossible d'acheter ce terrain...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...il vous appartient déjà!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Non nommé
+STR_SV_TRAIN_NAME :Train {COMMA}
+STR_SV_ROADVEH_NAME :Véhicule {COMMA}
+STR_SV_SHIP_NAME :Navire {COMMA}
+STR_SV_AIRCRAFT_NAME :Aéronef {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :{STRING} Nord
+STR_SV_STNAME_SOUTH :{STRING} Sud
+STR_SV_STNAME_EAST :{STRING} Est
+STR_SV_STNAME_WEST :{STRING} Ouest
+STR_SV_STNAME_CENTRAL :{STRING} Central
+STR_SV_STNAME_TRANSFER :{STRING} Transfert
+STR_SV_STNAME_HALT :{STRING} Halte
+STR_SV_STNAME_VALLEY :{STRING} Vallée
+STR_SV_STNAME_HEIGHTS :{STRING} Hauteurs
+STR_SV_STNAME_WOODS :{STRING} Bois
+STR_SV_STNAME_LAKESIDE :{STRING} Bords de lac
+STR_SV_STNAME_EXCHANGE :{STRING} Echange
+STR_SV_STNAME_AIRPORT :{STRING} Aéroport
+STR_SV_STNAME_OILFIELD :{STRING} Gisement pétrolifère
+STR_SV_STNAME_MINES :{STRING} Mines
+STR_SV_STNAME_DOCKS :{STRING} Docks
+STR_SV_STNAME_BUOY_1 :{STRING} Bouée 1
+STR_SV_STNAME_BUOY_2 :{STRING} Bouée 2
+STR_SV_STNAME_BUOY_3 :{STRING} Bouée 3
+STR_SV_STNAME_BUOY_4 :{STRING} Bouée 4
+STR_SV_STNAME_BUOY_5 :{STRING} Bouée 5
+STR_SV_STNAME_BUOY_6 :{STRING} Bouée 6
+STR_SV_STNAME_BUOY_7 :{STRING} Bouée 7
+STR_SV_STNAME_BUOY_8 :{STRING} Bouée 8
+STR_SV_STNAME_BUOY_9 :{STRING} Bouée 9
+STR_SV_STNAME_ANNEXE :{STRING} Annexe
+STR_SV_STNAME_SIDINGS :{STRING} Voies de garage
+STR_SV_STNAME_BRANCH :{STRING} Embranchement
+STR_SV_STNAME_UPPER :Haut {STRING}
+STR_SV_STNAME_LOWER :Bas {STRING}
+STR_SV_STNAME_HELIPORT :{STRING} Héliport
+STR_SV_STNAME_FOREST :{STRING} Forêt
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Niveau de difficulté
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Sauver
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Facile
+STR_6802_MEDIUM :{BLACK}Moyen
+STR_6803_HARD :{BLACK}Difficile
+STR_6804_CUSTOM :{BLACK}Personnalisé
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}Nombre maximum de compétiteurs: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Arrivée des compétiteurs: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}Nombre de villes: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}Nombre d'industries: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Prêt initial maximum: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Taux d'interêt initial: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Coûts d'entretien: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Vitesse de développement des compétiteurs: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Intelligence des compétiteurs: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Pannes des véhicules: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Multiplicateur de subvention: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Coût des constructions: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Type de terrain: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Quantité de mer/lacs: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Economie: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Demi-tour des trains: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Désastres: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Attitude de l'hotel de ville face au repaysagement : {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :Aucune
+STR_6816_LOW :Bas
+STR_6817_NORMAL :Normal
+STR_6818_HIGH :Élevé
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Très Lent
+STR_681C_SLOW :Lent
+STR_681D_MEDIUM :Moyen
+STR_681E_FAST :Rapide
+STR_681F_VERY_FAST :Très Rapide
+STR_VERY_LOW :Très bas
+STR_6820_LOW :Bas
+STR_6821_MEDIUM :Moyen
+STR_6822_HIGH :Élevé
+STR_6823_NONE :Aucune
+STR_6824_REDUCED :Réduites
+STR_6825_NORMAL :Normales
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Très plat
+STR_682B_FLAT :Plat
+STR_682C_HILLY :Collines
+STR_682D_MOUNTAINOUS :Montagneux
+STR_682E_STEADY :Stable
+STR_682F_FLUCTUATING :Fluctuant
+STR_6830_IMMEDIATE :Immédiat
+STR_6831_3_MONTHS_AFTER_PLAYER :3 mois après le joueur
+STR_6832_6_MONTHS_AFTER_PLAYER :6 mois après le joueur
+STR_6833_9_MONTHS_AFTER_PLAYER :9 mois après le joueur
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :À la fin de la ligne et aux gares
+STR_6835_AT_END_OF_LINE_ONLY :A la fin de la ligne seulement
+STR_6836_OFF :Inactif
+STR_6837_ON :Actif
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Afficher le tableau des scores
+STR_6839_PERMISSIVE :Laxiste
+STR_683A_TOLERANT :Tolérant
+STR_683B_HOSTILE :Hostile
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Joueur {COMMA})
+STR_7004_NEW_FACE :{BLACK}Nouveau visage
+STR_7005_COLOR_SCHEME :{BLACK}Couleur
+STR_7006_COLOR_SCHEME :{GOLD}Couleur:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Nouvelle couleur
+STR_7008_COMPANY_NAME :{BLACK}Nom de la société
+STR_7009_PRESIDENT_NAME :{BLACK}Nom du P.D.G.
+STR_700A_COMPANY_NAME :Nom de la société
+STR_700B_PRESIDENT_S_NAME :Nom du P.D.G.
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Impossible de changer le nom de compagnie...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Impossible de changer le nom du P.D.G. ...
+STR_700E_FINANCES :{WHITE}Finances: {COMPANY} {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Dépenses/Revenus
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Construction
+STR_7012_NEW_VEHICLES :{GOLD}Nouveaux Véhicules
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Entretien des trains
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Entretien des véhicules
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Entretien des aéronefs
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Entretien des navires
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Entretien de la propriété
+STR_7018_TRAIN_INCOME :{GOLD}Revenu ferroviaire
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Revenu routier
+STR_701A_AIRCRAFT_INCOME :{GOLD}Revenu aérien
+STR_701B_SHIP_INCOME :{GOLD}Revenu naval
+STR_701C_LOAN_INTEREST :{GOLD}Intérêts du prêt
+STR_701D_OTHER :{GOLD}Autres
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Total:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Graphique du Revenu
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Graphique du profit d'opération
+STR_7026_BANK_BALANCE :{WHITE}Equilibre bancaire
+STR_7027_LOAN :{WHITE}Prêt
+STR_MAX_LOAN :{WHITE}Emprunt maximum : {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}Emprunter {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Rembourser {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...le prêt maximum est de {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Impossible d'emprunter plus...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...Prêt déjà remboursé
+STR_702E_REQUIRED :{WHITE}...{CURRENCY} nécessaires
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Impossible de rembourser...
+STR_INSUFFICIENT_FUNDS :{WHITE}On ne peut pas distribuer de l'argent qui est emprunté à la banque...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Choix d'un nouveau visage pour le P.D.G.
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Change la couleur des véhicules
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Change le nom du président directeur général
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Change le nom de la compagnie
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Cliquer pour choisir une couleur
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Augmenter le prêt
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Rembourser une partie du prêt
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(Président)
+STR_7038_INAUGURATED :{GOLD}Inauguré en: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Véhicules:
+STR_TRAINS :{WHITE}{COMMA} train{P "" s}
+STR_ROAD_VEHICLES :{WHITE}{COMMA} véhicule{P "" s}
+STR_AIRCRAFT :{WHITE}{COMMA} aéronef{P "" s}
+STR_SHIPS :{WHITE}{COMMA} navire{P "" s}
+STR_7042_NONE :{WHITE}Aucun
+STR_7043_FACE_SELECTION :{WHITE}Sélection du visage
+STR_7044_MALE :{BLACK}Homme
+STR_7045_FEMALE :{BLACK}Femme
+STR_7046_NEW_FACE :{BLACK}Nouveau visage
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Annuler le choix du nouveau visage
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Valider le nouveau visage
+STR_7049_SELECT_MALE_FACES :{BLACK}Choisir un visage masculin
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Choisir un visage féminin
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Génère un visage au hasard
+STR_704C_KEY :{BLACK}Légende
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Affiche la légende
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Légende du graphique des compagnies
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Cliquer ici pour activer/désactiver l'affichage de la compagnie
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Cargaison livrée
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Historique de performace (performance max=1000)
+STR_7052_COMPANY_VALUES :{WHITE}Valeur de la compagnie
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Classement des compagnies
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}La compagnie de transport à des ennuis!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} va être en banqueroute si ses performances ne s'améliorent pas!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(Président)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Fusion de compagnies de transport!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} à été vendue à {COMPANY} pour {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Nous sommes à la recherche d'un acheteur pour notre compagnie{}{}Voulez vous acheter {COMPANY} pour {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Banqueroute!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} à été fermée par ses créanciers et tous ses actifs vendus!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}Fondation d'une nouvelle compagnie de transport!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} commence à construire près de {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Impossible d'acheter la compagnie...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Valeur des marchandises
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Jours de transit
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Prix payé pour livrer 10 unités (ou 10000 litres) à 20 carrés de distance
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Afficher/cacher le type de marchandise
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Ingénieur
+STR_7067_TRAFFIC_MANAGER :Gestionnaire de traffic
+STR_7068_TRANSPORT_COORDINATOR :Coordinateur de trafic
+STR_7069_ROUTE_SUPERVISOR :Superviseur de route
+STR_706A_DIRECTOR :Directeur
+STR_706B_CHIEF_EXECUTIVE :Directeur Général
+STR_706C_CHAIRMAN :Vice-président
+STR_706D_PRESIDENT :Président
+STR_706E_TYCOON :Tycoon
+STR_706F_BUILD_HQ :{BLACK}Const. siège
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Contruire/voir le Siège Social
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Reconstruit le quartier général de la compagnie ailleurs pour le prix de 1% de la valeur de la compagnie
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Impossible de construire le siège...
+STR_7072_VIEW_HQ :{BLACK}Voir le siège
+STR_RELOCATE_HQ :{BLACK}Déménager le QG
+STR_COMPANY_PASSWORD :{BLACK}Mot de passe
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Permet de protéger par mot de passe votre compagnie pour empêcher des utilisateurs non-autorisés de rejoindre. Utilisez '*' pour vider le mot de passe.
+STR_SET_COMPANY_PASSWORD :Choisir le mot de passe de la compagnie
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}Récession mondiale!{}{}Les experts financiers craignent le pire!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Fin de la récession!{}{}La reprise redonne confiance aux industries!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Bascule entre une grande/petite fenêtre
+STR_7076_COMPANY_VALUE :{GOLD}Valeur de la compagnie : {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Acheter 25% de la compagnie
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Vendre 25% de la compagnie
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Acheter 25% de la compagnie
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Vendre 25% de la compagnie
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Impossible d'acheter des parts...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}Impossible de vendre des parts...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% détenus par {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% détenus par {COMPANY}{} {COMMA}% détenus par {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} a été rachetée par {COMPANY}!
+STR_7080_PROTECTED :{WHITE}Cette compagnie ne vend pas d'actions pour le moment...
+
+STR_LIVERY_DEFAULT :Livrée standard
+STR_LIVERY_STEAM :Locomotive à vapeur
+STR_LIVERY_DIESEL :Locomotive Diesel
+STR_LIVERY_ELECTRIC :Locomotive électrique
+STR_LIVERY_MONORAIL :Locomotive Monorail
+STR_LIVERY_MAGLEV :Locomotive Maglev
+STR_LIVERY_DMU :DMU
+STR_LIVERY_EMU :EMU
+STR_LIVERY_PASSENGER_WAGON_STEAM :Voiture (Vapeur)
+STR_LIVERY_PASSENGER_WAGON_DIESEL :Voiture (Diesel)
+STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Voiture (Electrique)
+STR_LIVERY_FREIGHT_WAGON :Wagon
+STR_LIVERY_BUS :Bus
+STR_LIVERY_TRUCK :Camion
+STR_LIVERY_PASSENGER_SHIP :Ferry
+STR_LIVERY_FREIGHT_SHIP :Navire de fret
+STR_LIVERY_HELICOPTER :Hélicoptère
+STR_LIVERY_SMALL_PLANE :Petit porteur
+STR_LIVERY_LARGE_PLANE :Gros porteur
+
+STR_LIVERY_GENERAL_TIP :{BLACK}Montrer les livrées générales
+STR_LIVERY_TRAIN_TIP :{BLACK}Montrer les livrées de trains
+STR_LIVERY_ROADVEH_TIP :{BLACK}Montrer les livrées de véhicules routiers
+STR_LIVERY_SHIP_TIP :{BLACK}Montrer les livrées de navires
+STR_LIVERY_AIRCRAFT_TIP :{BLACK}Montrer les livrées des aéronefs
+STR_LIVERY_PRIMARY_TIP :{BLACK}Choisir la couleur primaire de la livrée sélectionnée
+STR_LIVERY_SECONDARY_TIP :{BLACK}Choisir la couleur secondaire de la livrée sélectionnée
+STR_LIVERY_PANEL_TIP :{BLACK}Sélectionner la livrée à modifier, ou plusieurs par Ctrl-clic. Cliquer sur la case pour en intervertir l'utilisation
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (Vapeur)
+STR_8001_MJS_250_DIESEL :MJS 250 (Diesel)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut Diesel
+STR_8006_POWERNAUT_DIESEL :Powernaut Diesel
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (Vapeur)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (Vapeur)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (Vapeur)
+STR_800A_SH_8P_STEAM :SH '8P' (Vapeur)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (Diesel)
+STR_800C_DASH_DIESEL :'Dash' (Diesel)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (Diesel)
+STR_800E_UU_37_DIESEL :UU '37' (Diesel)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (Diesel)
+STR_8010_CS_4000_DIESEL :CS 4000 (Diesel)
+STR_8011_CS_2400_DIESEL :CS 2400 (Diesel)
+STR_8012_CENTENNIAL_DIESEL :Centennial (Diesel)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (Diesel)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (Diesel)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (Diesel)
+STR_8016_SH_125_DIESEL :SH '125' (Diesel)
+STR_8017_SH_30_ELECTRIC :SH '30' (Electrique)
+STR_8018_SH_40_ELECTRIC :SH '40' (Electrique)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (Electrique)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (Electrique)
+STR_801B_PASSENGER_CAR :Wagon de voyageurs
+STR_801C_MAIL_VAN :Wagon de courrier
+STR_801D_COAL_CAR :Wagon de charbon
+STR_801E_OIL_TANKER :Wagon-citerne de pétrole
+STR_801F_LIVESTOCK_VAN :Wagon à bétail
+STR_8020_GOODS_VAN :Wagon de biens
+STR_8021_GRAIN_HOPPER :Wagon à grain
+STR_8022_WOOD_TRUCK :Wagon à bois
+STR_8023_IRON_ORE_HOPPER :Wagon à fer
+STR_8024_STEEL_TRUCK :Wagon à acier
+STR_8025_ARMORED_VAN :Wagon blindé
+STR_8026_FOOD_VAN :Wagon de nourriture
+STR_8027_PAPER_TRUCK :Wagon à papier
+STR_8028_COPPER_ORE_HOPPER :Wagon à cuivre
+STR_8029_WATER_TANKER :Wagon-citerne d'eau
+STR_802A_FRUIT_TRUCK :Wagon à fruits
+STR_802B_RUBBER_TRUCK :Wagon à caoutchouc
+STR_802C_SUGAR_TRUCK :Wagon à sucre
+STR_802D_COTTON_CANDY_HOPPER :Wagon à barbe à papa
+STR_802E_TOFFEE_HOPPER :Wagon à caramel
+STR_802F_BUBBLE_VAN :Wagon à bulles
+STR_8030_COLA_TANKER :Wagon-citerne de cola
+STR_8031_CANDY_VAN :Wagon à sucreries
+STR_8032_TOY_VAN :Wagon à jouets
+STR_8033_BATTERY_TRUCK :Wagon à batteries
+STR_8034_FIZZY_DRINK_TRUCK :Wagon à boisson gazeuses
+STR_8035_PLASTIC_TRUCK :Wagon à plastique
+STR_8036_X2001_ELECTRIC :'X2001' (Electrique)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Electrique)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :Wagon de voyageurs
+STR_803A_MAIL_VAN :Wagon de courrier
+STR_803B_COAL_CAR :Wagon de charbon
+STR_803C_OIL_TANKER :Wagon-citerne de pétrole
+STR_803D_LIVESTOCK_VAN :Wagon à bétail
+STR_803E_GOODS_VAN :Wagon de biens
+STR_803F_GRAIN_HOPPER :Wagon à grain
+STR_8040_WOOD_TRUCK :Wagon à bois
+STR_8041_IRON_ORE_HOPPER :Wagon à fer
+STR_8042_STEEL_TRUCK :Wagon à acier
+STR_8043_ARMORED_VAN :Wagon blindé
+STR_8044_FOOD_VAN :Wagon de nourriture
+STR_8045_PAPER_TRUCK :Wagon à papier
+STR_8046_COPPER_ORE_HOPPER :Wagon à cuivre
+STR_8047_WATER_TANKER :Wagon-citerne d'eau
+STR_8048_FRUIT_TRUCK :Wagon à fruits
+STR_8049_RUBBER_TRUCK :Wagon à caoutchouc
+STR_804A_SUGAR_TRUCK :Wagon à sucre
+STR_804B_COTTON_CANDY_HOPPER :Wagon à barbe à papa
+STR_804C_TOFFEE_HOPPER :Wagon à caramel
+STR_804D_BUBBLE_VAN :Wagon à bulles
+STR_804E_COLA_TANKER :Wagon-citerne de cola
+STR_804F_CANDY_VAN :Wagon à sucreries
+STR_8050_TOY_VAN :Wagon à jouets
+STR_8051_BATTERY_TRUCK :Wagon à batteries
+STR_8052_FIZZY_DRINK_TRUCK :Wagon à boisson gazeuses
+STR_8053_PLASTIC_TRUCK :Wagon à plastique
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (Electrique)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (Electrique)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (Electrique)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (Electrique)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :Wagon de voyageurs
+STR_805A_MAIL_VAN :Wagon de courrier
+STR_805B_COAL_CAR :Wagon de charbon
+STR_805C_OIL_TANKER :Wagon-citerne de pétrole
+STR_805D_LIVESTOCK_VAN :Wagon à bétail
+STR_805E_GOODS_VAN :Wagon de biens
+STR_805F_GRAIN_HOPPER :Wagon à grain
+STR_8060_WOOD_TRUCK :Wagon à bois
+STR_8061_IRON_ORE_HOPPER :Wagon à fer
+STR_8062_STEEL_TRUCK :Wagon à acier
+STR_8063_ARMORED_VAN :Wagon blindé
+STR_8064_FOOD_VAN :Wagon de nourriture
+STR_8065_PAPER_TRUCK :Wagon à papier
+STR_8066_COPPER_ORE_HOPPER :Wagon à cuivre
+STR_8067_WATER_TANKER :Wagon-citerne d'eau
+STR_8068_FRUIT_TRUCK :Wagon à fruits
+STR_8069_RUBBER_TRUCK :Wagon à caoutchouc
+STR_806A_SUGAR_TRUCK :Wagon à sucre
+STR_806B_COTTON_CANDY_HOPPER :Wagon à barbe à papa
+STR_806C_TOFFEE_HOPPER :Wagon à caramel
+STR_806D_BUBBLE_VAN :Wagon à bulles
+STR_806E_COLA_TANKER :Wagon-citerne de cola
+STR_806F_CANDY_VAN :Wagon à sucreries
+STR_8070_TOY_VAN :Wagon à jouets
+STR_8071_BATTERY_TRUCK :Wagon à batteries
+STR_8072_FIZZY_DRINK_TRUCK :Wagon à boisson gazeuses
+STR_8073_PLASTIC_TRUCK :Wagon à plastique
+STR_8074_MPS_REGAL_BUS :Autobus MPS Regal
+STR_8075_HEREFORD_LEOPARD_BUS :Autobus Hereford Leopard
+STR_8076_FOSTER_BUS :Autobus Foster
+STR_8077_FOSTER_MKII_SUPERBUS :Superbus Foster MkII
+STR_8078_PLODDYPHUT_MKI_BUS :Autobus Ploddyphut MkI
+STR_8079_PLODDYPHUT_MKII_BUS :Autobus Ploddyphut MkII
+STR_807A_PLODDYPHUT_MKIII_BUS :Autobus Ploddyphut MkIII
+STR_807B_BALOGH_COAL_TRUCK :Camion à charbon Balogh
+STR_807C_UHL_COAL_TRUCK :Camion à charbon Uhl
+STR_807D_DW_COAL_TRUCK :Camion à charbon DW
+STR_807E_MPS_MAIL_TRUCK :Fourgon postal MPS
+STR_807F_REYNARD_MAIL_TRUCK :Fourgon postal Reynard
+STR_8080_PERRY_MAIL_TRUCK :Fourgon postal Perry
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :Fourgon postal MightyMover
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Fourgon postal Powernaught
+STR_8083_WIZZOWOW_MAIL_TRUCK :Fourgon postal Wizzowow
+STR_8084_WITCOMBE_OIL_TANKER :Camion-citerne de pétrole Witcombe
+STR_8085_FOSTER_OIL_TANKER :Camion-citerne de pétrole Foster
+STR_8086_PERRY_OIL_TANKER :Camion-citerne de pétrole Perry
+STR_8087_TALBOTT_LIVESTOCK_VAN :Camion à bétail Talbott
+STR_8088_UHL_LIVESTOCK_VAN :Camion à bétail Uhl
+STR_8089_FOSTER_LIVESTOCK_VAN :Camion à bétail Foster
+STR_808A_BALOGH_GOODS_TRUCK :Camion de biens Balogh
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Camion de biens Craighead
+STR_808C_GOSS_GOODS_TRUCK :Camion de biens Goss
+STR_808D_HEREFORD_GRAIN_TRUCK :Camion à grain Hereford
+STR_808E_THOMAS_GRAIN_TRUCK :Camion à grain Thomas
+STR_808F_GOSS_GRAIN_TRUCK :Camion à grain Goss
+STR_8090_WITCOMBE_WOOD_TRUCK :Camion à bois Witcombe
+STR_8091_FOSTER_WOOD_TRUCK :Camion à bois Foster
+STR_8092_MORELAND_WOOD_TRUCK :Camion à bois Moreland
+STR_8093_MPS_IRON_ORE_TRUCK :Camion de fer MPS
+STR_8094_UHL_IRON_ORE_TRUCK :Camion de fer Uhl
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Camion de fer Chippy
+STR_8096_BALOGH_STEEL_TRUCK :Camion d'acier Balogh
+STR_8097_UHL_STEEL_TRUCK :Camion d'acier Uhl
+STR_8098_KELLING_STEEL_TRUCK :Camion d'acier Kelling
+STR_8099_BALOGH_ARMORED_TRUCK :Balogh Fourgon blindé
+STR_809A_UHL_ARMORED_TRUCK :Uhl Fourgon blindé
+STR_809B_FOSTER_ARMORED_TRUCK :Foster Fourgon blindé
+STR_809C_FOSTER_FOOD_VAN :Camion de nourriture Foster
+STR_809D_PERRY_FOOD_VAN :Camion de nourriture Perry
+STR_809E_CHIPPY_FOOD_VAN :Camion de nourriture Chippy
+STR_809F_UHL_PAPER_TRUCK :Camion de papier Uhl
+STR_80A0_BALOGH_PAPER_TRUCK :Camion de papier Balogh
+STR_80A1_MPS_PAPER_TRUCK :Camion de papier MPS
+STR_80A2_MPS_COPPER_ORE_TRUCK :Camion de cuivre MPS
+STR_80A3_UHL_COPPER_ORE_TRUCK :Uhl Camion de cuivre
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Goss Camion de cuivre
+STR_80A5_UHL_WATER_TANKER :Camion-citerne d'eau Uhl
+STR_80A6_BALOGH_WATER_TANKER :Camion-citerne d'eau Balogh
+STR_80A7_MPS_WATER_TANKER :Camion-citerne d'eau MPS
+STR_80A8_BALOGH_FRUIT_TRUCK :Camion de fruits Balogh
+STR_80A9_UHL_FRUIT_TRUCK :Camion de fruits Uhl
+STR_80AA_KELLING_FRUIT_TRUCK :Camion de fruits Kelling
+STR_80AB_BALOGH_RUBBER_TRUCK :Camion de caoutchouc Balogh
+STR_80AC_UHL_RUBBER_TRUCK :Camion de caoutchouc Uhl
+STR_80AD_RMT_RUBBER_TRUCK :Camion de caoutchouc RMT
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :Camion de sucre MightyMover
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Camion de sucre Powernaught
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Camion de sucre Wizzowow
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :Camion de Cola MightyMover
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Camion de Cola Powernaught
+STR_80B3_WIZZOWOW_COLA_TRUCK :Camion de Cola Wizzowow
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :Camion de barbe à papa MightyMover
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Camion de barbe à papa Powernaught
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Camion de barbe à papa Wizzowow
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :Camion de caramel MightyMover
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Camion de caramel Powernaught
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Camion de sucreries Wizzowow
+STR_80BA_MIGHTYMOVER_TOY_VAN :Camion de jouets MightyMover
+STR_80BB_POWERNAUGHT_TOY_VAN :Camion de jouets Powernaught
+STR_80BC_WIZZOWOW_TOY_VAN :Camion de jouets Wizzowow
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :Camion de sucreries MightyMover
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Camion de sucreries Powernaught
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Camion de sucreries Wizzowow
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :Camion de batteries MightyMover
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Camion de batteries Powernaught
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Camion de batteries Wizzowow
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :Camion de boissons gazeuses MightyMover
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Camion de boissons gazeuses Powernaught
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Camion de boissons gazeuses Wizzowow
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :Camion de plastique MightyMover
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Camion de plastique Powernaught
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Camion de plastique Wizzowow
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :Camion de bulles MightyMover
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Camion de bulles Powernaught
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Camion de bulles Wizzowow
+STR_80CC_MPS_OIL_TANKER :Pétrolier MPS
+STR_80CD_CS_INC_OIL_TANKER :Pétrolier CS-Inc.
+STR_80CE_MPS_PASSENGER_FERRY :Ferry de voyageurs MPS
+STR_80CF_FFP_PASSENGER_FERRY :Ferry de voyageurs FFP
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Bakewell 300 Aéroglisseur
+STR_80D1_CHUGGER_CHUG_PASSENGER :Ferry de voyageurs Chugger-Chug
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Ferry de voyageurs Shivershake
+STR_80D3_YATE_CARGO_SHIP :Navire cargo Yate
+STR_80D4_BAKEWELL_CARGO_SHIP :Navire cargo Bakewell
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Navire cargo Mightymover
+STR_80D6_POWERNAUT_CARGO_SHIP :Navire cargo Powernaut
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Hélicoptère Tricario
+STR_80FE_GURU_X2_HELICOPTER :Hélicoptère Guru X2
+STR_80FF_POWERNAUT_HELICOPTER :Hélicoptère Powernaut
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Communiqué du fabriquant d'engins
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}Nous venons juste d'inventer: {STRING} - Voulez vous l'exclusivité de ce véhicule pendant un an, afin que nous puissions le tester avant sa mise sur le marché ?
+STR_8102_RAILROAD_LOCOMOTIVE :{G=f}locomotive
+STR_8103_ROAD_VEHICLE :{G=m}véhicule
+STR_8104_AIRCRAFT :{G=m2}aéronef
+STR_8105_SHIP :{G=m}navire
+STR_8106_MONORAIL_LOCOMOTIVE :{G=f}locomotive monorail
+STR_8107_MAGLEV_LOCOMOTIVE :{G=f}locomotive magnétique
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}{TOWN} Dépôt ferroviaire
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Les habitants célèbrent . . .{}Arrivée du premier train à {STATION}!
+STR_8802_DETAILS :{WHITE}{STRING} (Détails)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Train présent
+STR_8804 :{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8806_GO_TO :Aller à {STATION}
+STR_8807_GO_TO_TRANSFER :Aller à {STATION} (Transférer et charger)
+STR_8808_GO_TO_UNLOAD :Aller à {STATION} (Décharger)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Aller à {STATION} (Transférer et laisser vide)
+STR_880A_GO_TO_LOAD :Aller à {STATION} (Charger)
+STR_880B_GO_TO_TRANSFER_LOAD :Aller à {STATION} (Transférer et attendre pleine charge)
+STR_880C_GO_NON_STOP_TO :Aller sans s'arrêter à {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Aller sans s'arrêter à {STATION} (Transférer et charger)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Aller sans s'arrêter à {STATION} (Décharger)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Aller sans s'arrêter à {STATION} (Transférer et laisser vide)
+STR_8810_GO_NON_STOP_TO_LOAD :Aller sans s'arrêter à {STATION} (Charger)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Aller sans s'arrêter à {STATION} (Transférer et attendre pleine charge)
+STR_GO_TO_TRAIN_DEPOT :Aller au dépot de {TOWN}
+STR_SERVICE_AT_TRAIN_DEPOT :Entretien au dépôt de {TOWN}
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Aller sans s'arrêter au dépôt de {TOWN}
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Aller faire l'entretien sans s'arrêter au dépôt de {TOWN}
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}En route pour le dépôt de {TOWN}
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}En route pour le dépôt de {TOWN}, {VELOCITY}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE :{LTBLUE}Entretien au dépôt de {TOWN}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE_VEL :{LTBLUE}Entretien au dépôt de {TOWN}, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (Ordre invalide)
+
+STR_UNKNOWN_DESTINATION :destination inconnue
+STR_8812_EMPTY :{LTBLUE}Vide
+STR_8813_FROM :{LTBLUE}{CARGO} de {STATION}
+STR_FROM_MULT :{LTBLUE}{CARGO} de {STATION} (x{NUM})
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}Le train {COMMA} est en attente au dépôt
+STR_8815_NEW_VEHICLES :{BLACK}Nouveaux véhicules
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Train trop long
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Les trains peuvent être manipulés qu'une fois stoppés au dépôt
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} Train{P "" s}
+
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Nouveaux véhicules ferroviaires
+STR_NEW_ELRAIL_VEHICLES :{WHITE}Nouveaux véhicules ferroviaires électriques
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Nouveaux véhicules monorail
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Nouveaux véhicules magnétiques
+STR_ALL_AVAIL_RAIL_VEHICLES :{WHITE}Véhicules sur rail
+
+STR_881F_BUILD_VEHICLE :{BLACK}Construire
+STR_CLONE_ROAD_VEHICLE :{BLACK}Copier Véhicule
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}Effectuer la copie d'un véhicule routier. Ctrl-clic partagera les ordres
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Effectuer la copie d'un véhicule routier. Cliquer ici puis sur un véhicule routier dans ou hors d'un dépôt. Ctrl-clic partagera les ordres
+STR_CLONE_TRAIN :{BLACK}Copier Train
+STR_CLONE_TRAIN_INFO :{BLACK}Effectuer la copie d'un train et ses wagons. Ctrl-clic partagera les ordres
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}Effectuer la copie d'un train et ses wagons. Cliquer ici puis sur un train dans ou hors d'un dépôt. Ctrl-clic partagera les ordres
+STR_8820_RENAME :{BLACK}Renommer
+STR_8823_SKIP :{BLACK}Suivant
+STR_8824_DELETE :{BLACK}Supprimer
+STR_8825_NON_STOP :{BLACK}Sans-arrêt
+STR_8826_GO_TO :{BLACK}Aller à
+STR_8827_FULL_LOAD :{BLACK}Charger
+STR_8828_UNLOAD :{BLACK}Décharger
+STR_REFIT :{BLACK}Réaménager
+STR_REFIT_TIP :{BLACK}Choisir pour quelle cargaison réaménager pour cet ordre. Ctrl-clic pour retirer l'instruction de réaménagement
+STR_REFIT_ORDER :(Réaménager pour {STRING})
+STR_8829_ORDERS :{WHITE}{VEHICLE} (Ordres)
+STR_882A_END_OF_ORDERS :{SETX 10}- - Fin des ordres - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}Entretien
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Impossible de construire le véhicule ferroviaire...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Construit en: {LTBLUE}{NUM}{BLACK} Valeur: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Valeur: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}Chargement/déchargement
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}Le train doit être stoppé dans un dépôt
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Impossible d'envoyer le train au dépôt...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Plus de places pour les ordres
+STR_8832_TOO_MANY_ORDERS :{WHITE}Trop d'ordres
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Impossible d'insérer un nouvel ordre...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Impossible de supprimer cet ordre...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Impossible de modifier cet ordre...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Impossible de déplacer le véhicule...
+STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}L'engin de queue suivra toujours sa contre-partie avant
+STR_8838_N_A :N/D{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Impossible de vendre le véhicule ferroviaire...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Impossible de trouver la route jusqu'au dépôt
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Impossible de démarrer/stopper le train...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Intervalle d'entretien: {LTBLUE}{COMMA}jours{BLACK} , dernier le : {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Intervalle d'entretien: {LTBLUE}{COMMA}%{BLACK} , dernier le : {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Trains - Cliquer sur un train pour obtenir des informations
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Contruire de nouveaux trains (nécessite un dépôt ferroviaire)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Trains - Cliquer sur un train pour obtenir des informations, glisser le wagon pour l'ajouter/le supprimer du train
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Construire un nouveau train/wagon
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Glisser le véhicule ici pour le vendre
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centrer la vue sur le dépôt
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Sélection du véhicule - Cliquer pour obtenir des informations
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Construire le véhicule sélectionné
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Renommer le type du véhicule
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Action courante du train - cliquer pour le démarrer/l'arrêter
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Afficher les ordres du train
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centrer la vue sur le train
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Envoyer le train au dépôt. Ctrl-clic pour entretien seul
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Forcer le train à continuer sans tenir compte des feux
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Faire faire demi-tour au train
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Afficher les détails
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Augmenter l'intervalle d'entretien
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Diminuer l'intervalle d'entretien
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Afficher des informations sur les marchandises transportées
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Afficher des informations sur les wagons
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Afficher la capacité de chaque wagon
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Afficher la capacité totale du train, par type de cargaison
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Liste des ordres - Cliquer sur un ordre pour le sélectionner. Cliquer avec Ctrl déplace la vue sur la station
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}Sauter l'ordre courant, et enchaîner sur le suivant
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Supprime l'ordre sélectionné
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Transformer l'ordre sélectionné en Sans-Arrêt
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Insérer un nouvel ordre
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Forcer le véhicule à attendre un chargement complet pour l'ordre sélectionné
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Forcer le véhicule à attendre un déchargement complet pour l'ordre sélectionné
+STR_SERVICE_HINT :{BLACK}Sauter cet ordre tant qu'aucun entretien n'est requis
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}Nouv{G eau el elle} {STRING} disponible!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Prix: {CURRENCY} Poids: {WEIGHT_S}{}Vitesse: {VELOCITY} Puissance: {POWER}{}Coût d'entretien: {CURRENCY}/an{}Capacité: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}En panne
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}Âge: {LTBLUE}{STRING}{BLACK} Coût d'entretien: {LTBLUE}{CURRENCY}/an
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Poids: {LTBLUE}{WEIGHT_S} {BLACK}Puissance: {LTBLUE}{POWER}{BLACK} Vitesse max.: {LTBLUE}{VELOCITY}
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Poids: {LTBLUE}{WEIGHT_S} {BLACK}Puissance: {LTBLUE}{POWER}{BLACK} Vitesse max.: {LTBLUE}{VELOCITY} {BLACK}E.T. max.: {LTBLUE}{FORCE}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit cette année: {LTBLUE}{CURRENCY} (année précédente: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}Fiabilité: {LTBLUE}{COMMA}% {BLACK}Pannes depuis le dernier entretien: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Stoppé
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Impossible de forcer le train à avancer sous le danger...
+STR_8863_CRASHED :{RED}Crashé!
+
+STR_8865_NAME_TRAIN :{WHITE}Renommer le train
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}Impossible de renommer le train...
+STR_8867_NAME_TRAIN :{BLACK}Renommer le train
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Tragédie ferroviaire!{}{COMMA} mort{P "" s} brûlé{P "" s} vif{P "" s} dans la collision
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Impossible de faire faire demi-tour...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Renommer le type de train
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Impossible de renommer le type de train...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Forcer le véhicule à vider sa cargaison pour l'ordre sélectionné
+STR_886F_TRANSFER :{BLACK}Transfert
+
+STR_TRAIN_STOPPING :{RED}Ralentit
+STR_TRAIN_STOPPING_VEL :{RED}Ralentit, {VELOCITY}
+STR_INCOMPATIBLE_RAIL_TYPES :Types de rail incompatibles
+STR_TRAIN_NO_POWER :{RED}Pas de puissance
+STR_TRAIN_START_NO_CATENARY :Cette voie n'a pas de caténaire, le train ne peut pas démarrer
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Véhicule Routier présent
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} Véhicule{P "" s} routier{P "" s}
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}Dépôt routier de {TOWN}
+STR_9004_NEW_VEHICLES :{BLACK}Nouveaux Véhicules
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}Nouveaux véhicules
+STR_9007_BUILD_VEHICLE :{BLACK}Construire
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Impossible de construire le véhicule...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (Détails)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}Âge: {LTBLUE}{STRING}{BLACK} Coût d'entretien: {LTBLUE}{CURRENCY}/an
+STR_900E_MAX_SPEED :{BLACK}Vitesse max.: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit de cette année: {LTBLUE}{CURRENCY} (année dernière: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}Fiabilité: {LTBLUE}{COMMA}% {BLACK}Pannes depuis le dernier entretien: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Construit en: {LTBLUE}{NUM}{BLACK} Valeur: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Capacité: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}...doit être à l'arrêt dans un dépôt routier
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Impossible de vendre le véhicule...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Impossible de démarrer/stopper le véhicule...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}Le véhicule {COMMA} attend au dépôt
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}En route pour le dépôt de {TOWN}
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}En route pour le dépôt de {TOWN}, {VELOCITY}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE :{LTBLUE}Entretien au dépôt de {TOWN}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE_VEL :{LTBLUE}Entretien au dépôt de {TOWN}, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Impossible d'envoyer le véhicule au dépôt...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Impossible de trouver le dépôt
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Véhicules - Cliquer sur un véhicule pour obtenir des informations
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Construire de nouveaux véhicules (nécessite un dépôt routier)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Comportement courant du véhicule - cliquer pour le démarrer/l'arrêter
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Afficher les ordres
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Centre la vue sur le véhicule
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Envoie le véhicule au dépôt. Ctrl-clic pour entretien seul
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Force le véhicule à faire demi-tour
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Affiche les détails
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Véhicules - cliquer pour obtenir des informations
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Construire un nouveau véhicule
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Glisser un véhicule jusqu'ici pour le vendre
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Centre la vue sur le dépôt
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Choix du véhicule - cliquer sur un véhicule pour obtenir des informations
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Construire le véhicule sélectionné
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}Nouveau véhicule disponible!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Prix: {CURRENCY}{}Vitesse: {VELOCITY}{}Coût d'entretien: {CURRENCY}/an{}Capacité: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Renommer le véhicule
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Impossible de renommer le véhicule...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Renommer le véhicule
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Les habitants célèbrent . . .{}Le premier bus arrive à {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Les habitants célèbrent . . .{}Le premier camion arrive à {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}Tragédie routière!{}Un automobiliste meurt brûlé vif lors d'une collision avec un train
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}Tragédie routière!{}{COMMA} morts, brûlés vifs lors d'une collision avec un train
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Impossible de faire faire demi-tour au véhicule...
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}Impossible de faire faire demi-tour aux unités multiples
+STR_9034_RENAME :{BLACK}Renommer
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Renommer type de véhicule routier
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Renommer type de véhicule routier
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Impossible de renommer type de véhicule routier...
+STR_9038_GO_TO_ROADVEH_DEPOT :Aller à {TOWN} Dépôt Routier
+STR_SERVICE_AT_ROADVEH_DEPOT :Entretien au dépôt de {TOWN}
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Réaménager le véhicule routier pour transporter une cargaison différente
+STR_REFIT_ROAD_VEHICLE :{BLACK}Réaménager le véhicule routier
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Réaménager le véhicule routier pour transporter la cargaison sélectionnée
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Impossible de réaménager le véhicule routier...
+STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Choisir le type de cargaison à transporter
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Construction Portuaire
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Construction Portuaire
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Impossible de construire port ici...
+STR_9803_SHIP_DEPOT :{WHITE}{TOWN} Dépôt naval
+STR_9804_NEW_SHIPS :{BLACK}Nouveaux navires
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} Navire{P "" s}
+STR_9808_NEW_SHIPS :{WHITE}Nouveaux navires
+STR_9809_BUILD_SHIP :{BLACK}Construire navire
+STR_CLONE_SHIP :{BLACK}Copier Navire
+STR_CLONE_SHIP_INFO :{BLACK}Effectuer la copie d'un navire. Ctrl-clic partagera les ordres
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}Effectuer la copie d'un navire. Cliquer ici puis sur un navire dans ou hors d'un dépôt. Ctrl-clic partagera les ordres
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}Navire doit être arrêté au dépôt
+STR_980C_CAN_T_SELL_SHIP :{WHITE}Impossible de vendre navire...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Impossible de construire navire...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Navire présent
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Détails)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}Âge: {LTBLUE}{STRING}{BLACK} Coût d'entretien: {LTBLUE}{CURRENCY}/an
+STR_9813_MAX_SPEED :{BLACK}Vitesse max.: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit cette année: {LTBLUE}{CURRENCY} (l'an dernier: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}Fiabilité: {LTBLUE}{COMMA}% {BLACK}Pannes depuis le dernier entretien: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Construit: {LTBLUE}{NUM}{BLACK} Valeur: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}Capacité: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}Impossible d'arrêter/démarrer le navire...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Impossible d'envoyer le navire au dépôt...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Impossible de trouver dépôt local
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}En route pour le dépôt naval de {TOWN}
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}En route pour le dépôt naval de {TOWN}, {VELOCITY}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE :{LTBLUE}Entretien au dépôt naval de {TOWN}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE_VEL :{LTBLUE}Entretien au dépôt naval de {TOWN}, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}Navire {COMMA} est en attente au dépôt
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Construire un port
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Construire un dépôt naval (pour construire et entretenir les navires)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Navires - cliquer sur un navire pour informations
+STR_9820_BUILD_NEW_SHIP :{BLACK}Construire nouveau navire
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Glisse le navire jusqu'ici pour le vendre
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centrer la vue sur emplacement du dépôt naval
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Navires - cliquer sur un navire pour informations
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Construire nouveaux navires (nécessite un dépôt naval)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}Liste de sélection de navire - cliquer sur un navire pour informations
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Construire le navire surligné
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Action courante du navire - cliquer pour le démarrer/l'arrêter
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Afficher les ordres du navire
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centrer la vue sur l'emplacement du navire
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Envoyer le navire au dépôt. Ctrl-clic pour entretien seul
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Afficher détails du navire
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}Nouveau navire maintenant disponible!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Prix: {CURRENCY} Vitesse max.: {VELOCITY}{}Capacité: {CARGO}{}Coût d'entretien: {CURRENCY}/an
+STR_982F_NAME_SHIP :{BLACK}Nommer navire
+
+STR_9831_NAME_SHIP :{WHITE}Nommer navire
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Impossible de nommer le navire...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Les habitants célèbrent . . .{}Arrivée du premier navire à {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Placer une bouée, peut servir de guide aux navires
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Impossible de placer une bouée ici...
+STR_9836_RENAME :{BLACK}Renommer
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Renommer type de navire
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Renommer type de navire
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Impossbile de renommer type de navire...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Réaménager le navire pour transporter une cargaison différente
+STR_983B_REFIT :{WHITE}{VEHICLE} (Réaménager)
+STR_983C_REFIT_SHIP :{BLACK}Réaménager navire
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Choisir le type de cargaison à transporter
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Réaménager le navire pour transporter la cargaison sélectionnée
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Choisir le type de cargaison à transporter:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nouvelle capacité: {GOLD}{CARGO}{}{BLACK}Prix du réaménagement: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Impossible de réaménager le navire...
+STR_9842_REFITTABLE :(réaménageable)
+STR_GO_TO_SHIP_DEPOT :Aller au dépôt naval de {TOWN}
+SERVICE_AT_SHIP_DEPOT :Entretien au dépôt naval de {TOWN}
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Aéroports
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Impossible de construire un aéroport ici...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}Hangar à {STATION}
+STR_A003_NEW_AIRCRAFT :{BLACK}Nouvel aéronef
+STR_CLONE_AIRCRAFT :{BLACK}Copier aéronef
+STR_CLONE_AIRCRAFT_INFO :{BLACK}Effectuer une copie de l'aéronef. Ctrl-clic partagera les ordres
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Effectuer la copie d'un aéronef. Cliquer ici puis sur un aéronef dans ou hors d'un hangar. Ctrl-clic partagera les ordres
+STR_A005_NEW_AIRCRAFT :{WHITE}Nouvel Aéronef
+STR_A006_BUILD_AIRCRAFT :{BLACK}Construire aéronef
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Impossible de construire l'aéronef...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} Aéronef{P "" s}
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (Ordres)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (Détails)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Âge: {LTBLUE}{STRING}{BLACK} Coût d'entretien: {LTBLUE}{CURRENCY}/an
+STR_A00E_MAX_SPEED :{BLACK}Vitesse max.: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profits cette année: {LTBLUE}{CURRENCY} (l'an dernier: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}Fiabilité: {LTBLUE}{COMMA}% {BLACK}Cafouillages depuis le dernier service: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Construit: {LTBLUE}{NUM}{BLACK} Valeur: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Impossible d'envoyer l'aéronef au hangar...
+STR_HEADING_FOR_HANGAR :{ORANGE}En route pour le hangar de {STATION}
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}En route pour le hangar de {STATION}, {VELOCITY}
+STR_HEADING_FOR_HANGAR_SERVICE :{LTBLUE}Entretien au hangar de {STATION}
+STR_HEADING_FOR_HANGAR_SERVICE_VEL :{LTBLUE}Entretien au hangar de {STATION} , {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}Aéronef {COMMA} est en attente au hangar
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Aéronef présent
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Impossible d'arrêter/démarrer aéronef...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}L'aéronef est en vol
+STR_A019_CAPACITY :{BLACK}Capacité: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Capacité: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}Aéronef doit être arrêté au hangar
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Impossible de vendre l'aéronef...
+STR_A01D_AIRPORT_CONSTRUCTION :Construction d'aéroport
+STR_A01E_BUILD_AIRPORT :{BLACK}Construire un aéroport
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Aéronef - cliquer sur l'aéronef pour informations
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Construire un nouvel aéronef (nécessite un aéroport avec hangar)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Aéronef - cliquer sur l'aéronef pour informations
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Construire nouvel aéronef
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}Glisser l'aéronef jusqu'ici ici pour le vendre
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Centrer la vue principale sur l'emplacement du hangar
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Liste de sélection d'aéronef - cliquer sur les aéronefs pour de plus amples informations
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Construire l'aéronef sélectionné
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Action courante de l'aéronef - cliquer pour le démarrer/l'arrêter
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Afficher les ordres de l'aéronef
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Centrer la vue principale sur l'emplacement de l'aéronef
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Envoyer l'aéronef au hangar. Ctrl-clic pour entretien seul
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Afficher détails de l'aéronef
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}Nouvel aéronef maintenant disponible!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Prix: {CURRENCY} Vitesse max.: {VELOCITY}{}Capacité: {COMMA} passagers, {COMMA} sacs de courrier{}Coût d'entretien: {CURRENCY}/an
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Nommer l'aéronef
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Impossible de nommer l'aéronef...
+STR_A032_NAME_AIRCRAFT :{BLACK}Nommer l'aéronef
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Les habitants célèbrent . . .{}Arrivée du premier aéronef à {STATION}!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Tragédie aérienne!{}{COMMA} morts brûlés vifs à {STATION}
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Tragédie aérienne !{}L'aéronef n'avait plus de carburant, {COMMA} passagers meurent dans l'incendie!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Renommer
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Renommer type d'aéronef
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Renommer type d'aéronef
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Impossible de renommer type d'aéronef...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Réaménager l'aéronef pour transporter une cargaison différente
+STR_A03C_REFIT :{WHITE}{VEHICLE} (Réaménager)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Réaménager aéronef
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Choisir le type de cargaison à transporter
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Réaménager l'aéronef pour transporter la cargaison sélectionnée
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Choisir le type de cargaison à transporter:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nouvelle capacité: {GOLD}{STRING}{}{BLACK}Prix du réaménagement: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Impossible de réaménager l'aéronef...
+STR_GO_TO_AIRPORT_HANGAR :Aller au hangar {STATION}
+SERVICE_AT_AIRPORT_HANGAR :Entretien au hangar {STATION}
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}Désastre impliquant un Zeppelin à {STATION}!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Véhicule routier détruit dans use collision avec un 'OVNI'!
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}Explosion d'une raffinerie pétrolière près de {TOWN}!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}Usine détruite dans des circonstances suspectes près de {TOWN}!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}Un 'OVNI' attérit près de {TOWN}!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}Affaissement d'une veine de charbon entraîne la desctruction de la mine de {TOWN}!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Inondations!{}Au moins {COMMA} présumés manquants ou morts après des inondations meurtrières!
+
+STR_BRIBE_FAILED :{WHITE}Votre tentative de corruption à été
+STR_BRIBE_FAILED_2 :{WHITE}révélée à la presse par un journaliste régional.
+STR_BUILD_DATE :{BLACK}Construit le: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Détail de l'évaluation de la performance
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}Détail
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Véhicules :
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Stations :
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Profit min. :
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Revenu min. :
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Revenu max. :
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Livré :
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Cargo :
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Argent :
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Prêt :
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Total :
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Nombre de véhicules. Ceci inclut les véhicules routiers, les trains, les navies et les aéronefs.
+STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}Nombre de parties de stations. Chaque partie d'une station (i.e. gare, arrêt de bus, [aéro]port) est comptée, même si elles sont connectées à une seule station.
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}Le profit du véhicule ayant le revenu le plus bas (de tous les véhicules ayant plus de 2 année d'existence)
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Quantité d'argent fait dans le mois ayant le plus bas profit des trois dernières années.
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Quantité d'argent fait dans le mois ayant le plus haut profit des trois dernières années.
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}Unités de cargo livrées durant les 4 derniers trimestres.
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}Types de cargo livrés durant le dernier trimestre.
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Quantité d'argent disponible.
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}Le montant emprunté par cette compagnie
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Total des points par rapport aux points possibles.
+
+STR_NEWGRF_SETTINGS_BUTTON :{BLACK}Paramètres NewGRF
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}Paramètres Newgrf
+STR_NEWGRF_APPLY_CHANGES :{BLACK}Appliquer les changements
+STR_NEWGRF_SET_PARAMETERS :{BLACK}Changer les paramètres
+STR_NEWGRF_TIP :{BLACK}Une liste de tous les sets Newgrf installés. Cliquer un set pour changer les paramètres.
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}Il n'y a actuellement aucun fichier Newgrf installé ! Veuillez vous référer au manuel pour des instructions sur l'installation de nouveaux graphiques.
+STR_NEWGRF_FILENAME :{BLACK}Nom de fichier: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
+STR_NEWGRF_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING}
+STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}Vous êtes sur le point de faire des changements dans une partie en cours; cela peut faire planter OpenTTD.{}Etes-vous absolument sûr ?
+
+STR_NEWGRF_ADD :{BLACK}Ajouter
+STR_NEWGRF_ADD_TIP :{BLACK}Ajouter un fichier NewGRF à la liste
+STR_NEWGRF_REMOVE :{BLACK}Retirer
+STR_NEWGRF_REMOVE_TIP :{BLACK}Retirer le fichier NewGRF sélectionné de la liste
+STR_NEWGRF_MOVEUP :{BLACK}Monter
+STR_NEWGRF_MOVEUP_TIP :{BLACK}Monter le fichier NewGRG sélectionné dans la liste
+STR_NEWGRF_MOVEDOWN :{BLACK}Descendre
+STR_NEWGRF_MOVEDOWN_TIP :{BLACK}Descendre le fichier NewGRG sélectionné dans la liste
+STR_NEWGRF_FILE_TIP :{BLACK}Liste des fichiers NewGRF installés. Cliquer sur un fichier pour modifier ses paramètres
+STR_NEWGRF_PARAMETER :{BLACK}Paramètres: {SILVER}{STRING}
+STR_NEWGRF_PARAMETER_QUERY :{BLACK}Entrer les paramètres NewGRF
+STR_NEWGRF_NO_INFO :{BLACK}Pas d'informations disponibles
+
+STR_NEWGRF_ADD_CAPTION :{WHITE}Fichier NewGRF disponibles
+STR_NEWGRF_ADD_FILE :{BLACK}Ajouter à la sélection
+STR_NEWGRF_ADD_FILE_TIP :{BLACK}Ajouter le fichier NewGRF sélectionné à votre configuration
+STR_NEWGRF_RESCAN_FILES :{BLACK}Re-scanner les fichiers
+STR_NEWGRF_RESCAN_FILES_TIP :{BLACK}Mettre à jour la liste des fichiers NewGRF disponibles
+STR_NEWGRF_DUPLICATE_GRFID :{WHITE}Ajout impossible: GRF ID en double
+
+STR_NEWGRF_NOT_FOUND :{RED}Fichier correspondant non trouvé
+STR_NEWGRF_DISABLED :{RED}Désactivé
+
+STR_CURRENCY_WINDOW :{WHITE}Devise personnalisée
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Taux de change : {ORANGE}{CURRENCY} = £ {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Séparateur :
+STR_CURRENCY_PREFIX :{LTBLUE}Préfixe :
+STR_CURRENCY_SUFFIX :{LTBLUE}Suffixe :
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Passer à l'Euro : {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Passer à l'Euro : {ORANGE}jamais
+STR_CURRENCY_PREVIEW :{LTBLUE}Prévisualisation : {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Changer les paramètres de devises personnalisées
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} Train{P "" s}
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} Véhicule{P "" s} routier{P "" s}
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} Aéronef{P "" s}
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} Navire{P "" s}
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Afficher les trains ayant cette station dans leurs ordres
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Afficher les véhicules routiers ayant cette station dans leurs ordres
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Afficher les aéronefs ayant cette station dans leurs ordres
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Afficher les navires ayant cette station dans leurs ordres
+
+STR_VEH_WITH_SHARED_ORDERS_LIST :{WHITE}Ordres partagés de {COMMA} véhicule{P "" s}
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}Afficher tous les véhicules partageant ce programme
+
+### depot strings
+STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Vous êtes sur le point de vendre tous les véhicules du dépôt. Etes-vous sûr ?
+
+STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP :{BLACK}Vendre tous les trains du dépôt
+STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP :{BLACK}Vendre tous les véhicules routiers du dépôt
+STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP :{BLACK}Vendre tous les navires du dépôt
+STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP :{BLACK}Vendre tous les aéronefs du hangar
+
+STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP :{BLACK}Afficher les trains ayant ce dépôt dans leurs ordres
+STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP :{BLACK}Afficher les véhicules routiers ayant ce dépôt dans leurs ordres
+STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP :{BLACK}Afficher les navires ayant ce dépôt dans leurs ordres
+STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP :{BLACK}Afficher les aéronefs ayant ce dépôt dans leurs ordres
+
+STR_DEPOT_AUTOREPLACE_TRAIN_TIP :{BLACK}Autoremplacer tous les trains du dépôt
+STR_DEPOT_AUTOREPLACE_ROADVEH_TIP :{BLACK}Autoremplacer tous les véhicules routiers du dépôt
+STR_DEPOT_AUTOREPLACE_SHIP_TIP :{BLACK}Autoremplacer tous les navires du dépôt
+STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP :{BLACK}Autoremplacer tous les aéronefs du hangar
+
+STR_VEHICLE_LIST_TRAIN_DEPOT :{BLACK}{STRING} - {COMMA} Train{P "" s}
+STR_VEHICLE_LIST_ROADVEH_DEPOT :{BLACK}{STRING} - {COMMA} Véhicule{P "" s} Routier{P "" s}
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} Navire{P "" s}
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} Aéronef{P "" s}
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}Remplacer {STRING}
+STR_REPLACE_VEHICLES_START :{BLACK}Démarrer le remplacement
+STR_REPLACE_VEHICLES_STOP :{BLACK}Stopper le remplacement
+STR_NOT_REPLACING :{BLACK}Pas en cours de remplacement
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Aucun véhicule sélectionné
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Choisir le type de locomotive à remplacer
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Choisir le nouveau type de locomotive devant remplacer le type de locomotive sélectionné à gauche
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Appuyer sur ce bouton pour arrêter le remplacement du type locomotive sélectionné à gauche
+STR_REPLACE_HELP_START_BUTTON :{BLACK}Appuyer sur ce bouton pour commencer le remplacement du type locomotive sélectionné à gauche avec la sélection de droite
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Choisir un type de rail pour le remplacement de locomotives
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Ceci affiche par quelle locomotive celle qui est sélectionnée à gauche sera remplacée
+STR_REPLACE_HELP :{BLACK}Cette caractéristique permet de choisir un type de locomotive et de le remplacer par un autre. Ceci sera fait automatiquement quand le véhicule rentre dans un dépôt
+STR_REPLACE_REMOVE_WAGON :{BLACK}Retrait de wagon: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}L'autoremplacement conserve la même longueur du train en retirant des wagons (d'abord par la tête), si le remplacement fait en sorte que le train ne devienne plus long.
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}En Remplacement: {ORANGE}{SKIP}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} FONCTION EXPERIMENTALE {}Passer à la fenêtre de remplacement de locomotives/wagons.{}Le remplacement de wagon ne se fera que si le nouveau wagon peut être réaménagé pour le même type de cargaison que l'ancien. Ceci est vérifié pour chaque wagon lors du remplacement.
+STR_ENGINE_NOT_BUILDABLE :{WHITE}Ce véhicule ne peut pas être construit
+
+STR_ENGINES :Locomotives
+STR_WAGONS :Wagons
+
+STR_MASS_STOP_DEPOT_TRAIN_TIP :{BLACK}Cliquer pour arrêter tous les trains du dépôt
+STR_MASS_STOP_DEPOT_ROADVEH_TIP :{BLACK}Cliquer pour arrêter tous les véhicules routiers du dépôt
+STR_MASS_STOP_DEPOT_SHIP_TIP :{BLACK}Cliquer pour arrêter tous les navires du dépôt
+STR_MASS_STOP_HANGAR_TIP :{BLACK}Cliquer pour arrêter tous les aéronefs du hangar
+
+STR_MASS_START_DEPOT_TRAIN_TIP :{BLACK}Cliquer pour démarrer tous les trains du dépôt
+STR_MASS_START_DEPOT_ROADVEH_TIP :{BLACK}Cliquer pour démarrer tous les véhicules routiers du dépôt
+STR_MASS_START_DEPOT_SHIP_TIP :{BLACK}Cliquer pour démarrer tous les navires du dépôt
+STR_MASS_START_HANGAR_TIP :{BLACK}Cliquer pour démarrer tous les aéronefs du hangar
+
+STR_MASS_STOP_LIST_TIP :{BLACK}Cliquer pour arrêter tous les véhicules de la liste
+STR_MASS_START_LIST_TIP :{BLACK}Cliquer pour démarrer tous les véhicules de la liste
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}Liste des panneaux - {COMMA} panneau{P "" x}
+
+STR_ORDER_REFIT_FAILED :{WHITE}L'échec du réaménagement a stoppé {STRING} {COMMA}
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :Véhicules sur rail
+STR_ELRAIL_VEHICLES :Vehicule électriques sur rail
+STR_MONORAIL_VEHICLES :Véhicules sur monorail
+STR_MAGLEV_VEHICLES :Véhicules sur Maglev
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Prix: {GOLD}{CURRENCY}{BLACK} Poids: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Vitesse: {GOLD}{VELOCITY}{BLACK} Puissance: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}Vitesse: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Coût d'entretien: {GOLD}{CURRENCY}/an
+STR_PURCHASE_INFO_CAPACITY :{BLACK}Capacité: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Concu en: {GOLD}{NUM}{BLACK}Durée de vie: {GOLD}{COMMA} ans
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}Fiabilité Max.: {GOLD}{COMMA}%
+STR_PURCHASE_INFO_COST :{BLACK}Prix: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Poids: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Prix: {GOLD}{CURRENCY}{BLACK} Vitesse: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Capacité: {GOLD}{COMMA} passagers, {COMMA} sacs de courrier
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Wagons Motorisés: {GOLD}+{POWER}{BLACK} Poids: {GOLD}+{WEIGHT_S}
+STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Réaménageable pour: {GOLD}
+STR_PURCHASE_INFO_ALL_TYPES :Tous les types de cargaison
+STR_PURCHASE_INFO_ALL_BUT :Tous sauf {GOLD}
+STR_PURCHASE_INFO_MAX_TE :{BLACK}Effort de traction max.: {GOLD}{FORCE}
+
+########### String for New Landscape Generator
+
+STR_GENERATE :{WHITE}Générer
+STR_RANDOM :{BLACK}Nouvelle Amorce
+STR_RANDOM_HELP :{BLACK}Modifer l'amorce utilisée pour la Génération du Terrain
+STR_WORLD_GENERATION_CAPTION :{WHITE}Génération du terrain
+STR_RANDOM_SEED :{BLACK}Amorce :
+STR_RANDOM_SEED_HELP :{BLACK}Cliquer pour saisir une amorce
+STR_LAND_GENERATOR :{BLACK}Générateur :
+STR_TREE_PLACER :{BLACK}Placement arbres :
+STR_HEIGHTMAP_ROTATION :{BLACK}Rotation de la carte d'altitude :
+STR_TERRAIN_TYPE :{BLACK}Type de terrain :
+STR_QUANTITY_OF_SEA_LAKES :{BLACK}Niveau de la mer :
+STR_SMOOTHNESS :{BLACK}Lissage :
+STR_SNOW_LINE_HEIGHT :{BLACK}Alt. d'enneigement :
+STR_DATE :{BLACK}Date:
+STR_NUMBER_OF_TOWNS :{BLACK}No. de villes :
+STR_NUMBER_OF_INDUSTRIES :{BLACK}No. d'industries :
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_SNOW_LINE_UP :{BLACK}Augmenter l'altitude d'enneigement
+STR_SNOW_LINE_DOWN :{BLACK}Baisser l'altitude d'enneigement
+STR_SNOW_LINE_QUERY_CAPT :{WHITE}Modifier l'altitude d'enneigement
+STR_START_DATE_QUERY_CAPT :{WHITE}Modifier l'année de départ
+STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Avertissement de redimensionnement
+STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Trop redimensionner la carte source n'est pas recommandé. Continuer la génération ?
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_HEIGHTMAP_NAME :{BLACK}Nom de la carte d'altitude :
+STR_HEIGHTMAP_SIZE :{BLACK}Taille: {ORANGE}{NUM} x {NUM}
+STR_GENERATION_WORLD :{WHITE}Génération du terrain...
+STR_GENERATION_ABORT :{BLACK}Annuler
+STR_GENERATION_ABORT_CAPTION :{WHITE}Annuler la génération du terrain
+STR_GENERATION_ABORT_MESSAGE :{YELLOW}Voulez-vous vraiment annuler la génération ?
+STR_PROGRESS :{WHITE}{NUM}% terminé
+STR_GENERATION_PROGRESS :{BLACK}{NUM} / {NUM}
+STR_WORLD_GENERATION :{BLACK}Génération du terrain
+STR_TREE_GENERATION :{BLACK}Génération des arbres
+STR_UNMOVABLE_GENERATION :{BLACK}Génération des non-déplacables
+STR_CLEARING_TILES :{BLACK}Génération des zones rugueuses et pierreuses
+STR_SETTINGUP_GAME :{BLACK}Configuration du jeu
+STR_PREPARING_TILELOOP :{BLACK}Rafraîchissement du terrain
+STR_PREPARING_GAME :{BLACK}Préparation du jeu
+STR_DIFFICULTY_TO_CUSTOM :{WHITE}Cette action a modifié le niveau de difficulté en personnalisé
+STR_SE_FLAT_WORLD :{WHITE}Terrain plat
+STR_SE_FLAT_WORLD_TIP :{BLACK}Générer un terrain plat
+STR_SE_RANDOM_LAND :{WHITE}Terrain aléatoire
+STR_SE_NEW_WORLD :{BLACK}Nouveau scénario
+STR_SE_CAPTION :{WHITE}Type de scénario
+STR_FLAT_WORLD_HEIGHT_DOWN :{BLACK}Diminuer l'altitude du terrain plat
+STR_FLAT_WORLD_HEIGHT_UP :{BLACK}Augmenter l'altitude du terrain plat
+STR_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Modifier l'altitude du terrain plat
+STR_FLAT_WORLD_HEIGHT :{BLACK}Altitude du terrain plat :
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+STR_SMALLMAP_CENTER :{BLACK}Centrer la carte sur la position actuelle
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}Petit
+STR_CITY_AIRPORT :{BLACK}Urbain
+STR_METRO_AIRPORT :{BLACK}Aéroport métropolitain
+STR_INTERNATIONAL_AIRPORT :{BLACK}International
+STR_COMMUTER_AIRPORT :{BLACK}de Banlieue
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Intercontinental
+STR_HELIPORT :{BLACK}Hélitour
+STR_HELIDEPOT :{BLACK}Hélidépôt
+STR_HELISTATION :{BLACK}Hélistation
+
+STR_SMALL_AIRPORTS :{BLACK}Petits aéroports
+STR_LARGE_AIRPORTS :{BLACK}Grands aéroports
+STR_HUB_AIRPORTS :{BLACK}Aéroports Internodaux
+STR_HELIPORTS :{BLACK}Héliports
+
+############ Tooltip measurment
+
+STR_MEASURE_LENGTH :{BLACK}Longueur: {NUM}
+STR_MEASURE_AREA :{BLACK}Région: {NUM} x {NUM}
+STR_MEASURE_LENGTH_HEIGHTDIFF :{BLACK}Longueur: {NUM}{}Ecart d'altitude: {NUM} m
+STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}Région: {NUM} x {NUM}{}Ecart d'altitude: {NUM} m
+
+########
diff --git a/src/lang/galician.txt b/src/lang/galician.txt
new file mode 100644
index 000000000..c5c258457
--- /dev/null
+++ b/src/lang/galician.txt
@@ -0,0 +1,2985 @@
+##name Galician
+##ownname Galego
+##isocode gl_ES.UTF-8
+##plural 0
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Fora do borde do mapa
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Demasiado cerca do borde do mapa
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Diñeiro insuficiente - necesitas {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Necesitas terreo chan
+STR_0008_WAITING :{BLACK}Esperando: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (en ruta dende
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Acepta: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Acepta: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :Pasaxeiros
+STR_0010_COAL :Carbón
+STR_0011_MAIL :Correo
+STR_0012_OIL :Petróleo
+STR_0013_LIVESTOCK :Gando
+STR_0014_GOODS :Mercadorías
+STR_0015_GRAIN :Gran
+STR_0016_WOOD :Madeira
+STR_0017_IRON_ORE :Hematita
+STR_0018_STEEL :Aceiro
+STR_0019_VALUABLES :Valores
+STR_001A_COPPER_ORE :Mineral de Cobre
+STR_001B_MAIZE :Millo
+STR_001C_FRUIT :Froita
+STR_001D_DIAMONDS :Diamantes
+STR_001E_FOOD :Comida
+STR_001F_PAPER :Papel
+STR_0020_GOLD :Ouro
+STR_0021_WATER :Auga
+STR_0022_WHEAT :Trigo
+STR_0023_RUBBER :Caucho
+STR_0024_SUGAR :Azucre
+STR_0025_TOYS :Xoguetes
+STR_0026_CANDY :Caramelo
+STR_0027_COLA :Cola
+STR_0028_COTTON_CANDY :Algodón de Azucre
+STR_0029_BUBBLES :Burbullas
+STR_002A_TOFFEE :Toffee
+STR_002B_BATTERIES :Baterías
+STR_002C_PLASTIC :Plástico
+STR_002D_FIZZY_DRINKS :Bebidas Gaseosas
+STR_002E :
+STR_002F_PASSENGER :Pasaxeiro
+STR_0030_COAL :Carbón
+STR_0031_MAIL :Correo
+STR_0032_OIL :Petróleo
+STR_0033_LIVESTOCK :Gando
+STR_0034_GOODS :Mercadorías
+STR_0035_GRAIN :Gran
+STR_0036_WOOD :Madeira
+STR_0037_IRON_ORE :Hematita
+STR_0038_STEEL :Aceiro
+STR_0039_VALUABLES :Valores
+STR_003A_COPPER_ORE :Mineral de Cobre
+STR_003B_MAIZE :Millo
+STR_003C_FRUIT :Froita
+STR_003D_DIAMOND :Diamante
+STR_003E_FOOD :Comida
+STR_003F_PAPER :Papel
+STR_0040_GOLD :Ouro
+STR_0041_WATER :Auga
+STR_0042_WHEAT :Trigo
+STR_0043_RUBBER :Caucho
+STR_0044_SUGAR :Azucre
+STR_0045_TOY :Xoguete
+STR_0046_CANDY :Caramelo
+STR_0047_COLA :Cola
+STR_0048_COTTON_CANDY :Algodón de Azucre
+STR_0049_BUBBLE :Burbulla
+STR_004A_TOFFEE :Toffee
+STR_004B_BATTERY :Batería
+STR_004C_PLASTIC :Plástico
+STR_004D_FIZZY_DRINK :Bebida Gaseosa
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} pasaxeiro{P "" s}
+STR_QUANTITY_COAL :{WEIGHT} de carbón
+STR_QUANTITY_MAIL :{COMMA} saco{P "" s} de correo
+STR_QUANTITY_OIL :{VOLUME} de petróleo
+STR_QUANTITY_LIVESTOCK :{COMMA} item{P "" s} de gando
+STR_QUANTITY_GOODS :{COMMA} caixón{P "" s} de mercadorías
+STR_QUANTITY_GRAIN :{WEIGHT} de gran
+STR_QUANTITY_WOOD :{WEIGHT} de madeira
+STR_QUANTITY_IRON_ORE :{WEIGHT} de hematita
+STR_QUANTITY_STEEL :{WEIGHT} de aceiro
+STR_QUANTITY_VALUABLES :{COMMA} saco{P "" s} de valores
+STR_QUANTITY_COPPER_ORE :{WEIGHT} de mineral de cobre
+STR_QUANTITY_MAIZE :{WEIGHT} de millo
+STR_QUANTITY_FRUIT :{WEIGHT} de froita
+STR_QUANTITY_DIAMONDS :{COMMA} saco{P "" s} de diamantes
+STR_QUANTITY_FOOD :{WEIGHT} de comida
+STR_QUANTITY_PAPER :{WEIGHT} de papel
+STR_QUANTITY_GOLD :{COMMA} saco{P "" s} de ouro
+STR_QUANTITY_WATER :{VOLUME} de auga
+STR_QUANTITY_WHEAT :{WEIGHT} de trigo
+STR_QUANTITY_RUBBER :{VOLUME} de caucho
+STR_QUANTITY_SUGAR :{WEIGHT} de azucre
+STR_QUANTITY_TOYS :{COMMA} xoguete{P "" s}
+STR_QUANTITY_SWEETS :{COMMA} saco{P "" s} de caramelo
+STR_QUANTITY_COLA :{VOLUME} de cola
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} de algodón de azucre
+STR_QUANTITY_BUBBLES :{COMMA} burbulla{P "" s}
+STR_QUANTITY_TOFFEE :{WEIGHT} de toffee
+STR_QUANTITY_BATTERIES :{COMMA} batería{P "" s}
+STR_QUANTITY_PLASTIC :{VOLUME} de plástico
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} bebida{P "" s} gaseosa{P "" s}
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}PS
+STR_ABBREV_COAL :{TINYFONT}CL
+STR_ABBREV_MAIL :{TINYFONT}ML
+STR_ABBREV_OIL :{TINYFONT}OL
+STR_ABBREV_LIVESTOCK :{TINYFONT}LV
+STR_ABBREV_GOODS :{TINYFONT}GD
+STR_ABBREV_GRAIN :{TINYFONT}GR
+STR_ABBREV_WOOD :{TINYFONT}WD
+STR_ABBREV_IRON_ORE :{TINYFONT}OR
+STR_ABBREV_STEEL :{TINYFONT}ST
+STR_ABBREV_VALUABLES :{TINYFONT}VL
+STR_ABBREV_COPPER_ORE :{TINYFONT}CO
+STR_ABBREV_MAIZE :{TINYFONT}MZ
+STR_ABBREV_FRUIT :{TINYFONT}FT
+STR_ABBREV_DIAMONDS :{TINYFONT}DM
+STR_ABBREV_FOOD :{TINYFONT}FD
+STR_ABBREV_PAPER :{TINYFONT}PR
+STR_ABBREV_GOLD :{TINYFONT}GD
+STR_ABBREV_WATER :{TINYFONT}WR
+STR_ABBREV_WHEAT :{TINYFONT}WH
+STR_ABBREV_RUBBER :{TINYFONT}RB
+STR_ABBREV_SUGAR :{TINYFONT}SG
+STR_ABBREV_TOYS :{TINYFONT}TY
+STR_ABBREV_SWEETS :{TINYFONT}SW
+STR_ABBREV_COLA :{TINYFONT}CL
+STR_ABBREV_CANDYFLOSS :{TINYFONT}CF
+STR_ABBREV_BUBBLES :{TINYFONT}BU
+STR_ABBREV_TOFFEE :{TINYFONT}TF
+STR_ABBREV_BATTERIES :{TINYFONT}BA
+STR_ABBREV_PLASTIC :{TINYFONT}PL
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}FZ
+STR_ABBREV_NONE :{TINYFONT}NON
+STR_ABBREV_ALL :{TINYFONT}TODO
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Mapa - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Opcións da Partida
+STR_00B2_MESSAGE :{YELLOW}Mensaxe
+STR_00B3_MESSAGE_FROM :{YELLOW}Mensaxe de {STRING}
+STR_00B4_CAN_T_DO_THIS :{WHITE}Non podes facer eso....
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Non podes limpar esta área....
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Copyright Orixinal {COPYRIGHT} 1995 Chris Sawyer, Tódolos dereitos reservados
+STR_00B7_VERSION :{BLACK}OpenTTD versión {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 O Equipo de OpenTTD
+STR_TRANSLATED_BY :{BLACK} Traductor(es) -
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Saír
+STR_00C8_YES :{BLACK}Si
+STR_00C9_NO :{BLACK}Non
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}¿Estás seguro de querer saír e volver a {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Nada
+STR_00D1_DARK_BLUE :Azul Escuro
+STR_00D2_PALE_GREEN :Verde Claro
+STR_00D3_PINK :Rosa
+STR_00D4_YELLOW :Amarelo
+STR_00D5_RED :Vermello
+STR_00D6_LIGHT_BLUE :Azul Claro
+STR_00D7_GREEN :Verde
+STR_00D8_DARK_GREEN :Verde Escuro
+STR_00D9_BLUE :Azul
+STR_00DA_CREAM :Crema
+STR_00DB_MAUVE :Malva
+STR_00DC_PURPLE :Morado
+STR_00DD_ORANGE :Laranxa
+STR_00DE_BROWN :Marrón
+STR_00DF_GREY :Gris
+STR_00E0_WHITE :Branco
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Hay demasiados vehículos na partida
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Situación
+STR_00E5_CONTOURS :Contorno
+STR_00E6_VEHICLES :Vehículos
+STR_00E7_INDUSTRIES :Industrias
+STR_00E8_ROUTES :Rutas
+STR_00E9_VEGETATION :Vexetación
+STR_00EA_OWNERS :Propietarios
+STR_00EB_ROADS :{BLACK}{TINYFONT}Estradas
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Ferrocarrís
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Estacións/Aeroportos/Portos
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Edificios/Industrias
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Vehículos
+STR_00F0_100M :{BLACK}{TINYFONT}100m
+STR_00F1_200M :{BLACK}{TINYFONT}200m
+STR_00F2_300M :{BLACK}{TINYFONT}300m
+STR_00F3_400M :{BLACK}{TINYFONT}400m
+STR_00F4_500M :{BLACK}{TINYFONT}500m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Trens
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Camións/Buses
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Navíos
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Aeronaves
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Rutas De Transporte
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Mina de Carbón
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Estación Enerxética
+STR_00FC_FOREST :{BLACK}{TINYFONT}Bosque
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}Serradeiro
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Ref. de Petróleo
+STR_00FF_FARM :{BLACK}{TINYFONT}Granxa
+STR_0100_FACTORY :{BLACK}{TINYFONT}Factoría
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Imprenta
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Pozo Petrolífero
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Mina de Hematita
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Siderúrxica
+STR_0105_BANK :{BLACK}{TINYFONT}Banco
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Fábrica de Papel
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Mina de Ouro
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Planta de Proc. de Comida
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Mina de Diamantes
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Mina de Mineral de Cobre
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Plantación de Froita
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Plant. de Ãrbores de Caucho
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Acuífero
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Torre de Auga
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}Fábrica de Táboas
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Bosque de Algodón de Azucre
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Fábrica de Caramelos
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Granxa de Baterías
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Fontes de Cola
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Xoguetería
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Fábrica de Xoguetes
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Fontes de Plástico
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Fábrica de Bebidas Gaseosas
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Xerador de Burbullas
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Canteira de Toffee
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Mina de Azucre
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Estación de Ferrocarril
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Bahía de Carga de Camións
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Estación de Autobús
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Aerporto/Heliporto
+STR_011F_DOCK :{BLACK}{TINYFONT}Peirao
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Terra Quebrada
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Terra con Herba
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Terra Deserta
+STR_0123_FIELDS :{BLACK}{TINYFONT}Campos
+STR_0124_TREES :{BLACK}{TINYFONT}Ãrbores
+STR_0125_ROCKS :{BLACK}{TINYFONT}Rochas
+STR_0126_WATER :{BLACK}{TINYFONT}Auga
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Sen Propietario
+STR_0128_TOWNS :{BLACK}{TINYFONT}Cidades
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Industrias
+STR_012A_DESERT :{BLACK}{TINYFONT}Deserto
+STR_012B_SNOW :{BLACK}{TINYFONT}Neve
+STR_012C_MESSAGE :{WHITE}Mensaxe
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Cancelar
+STR_012F_OK :{BLACK}OK
+STR_0130_RENAME :{BLACK}Renomear
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Hay demasiados nomes definidos
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}O nome elixido xa está en uso
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...É propiedade de {STRING}
+STR_013C_CARGO :{BLACK}Carga
+STR_013D_INFORMATION :{BLACK}Información
+STR_013E_CAPACITIES :{BLACK}Capacidades
+STR_013E_TOTAL_CARGO :{BLACK}Carga Total
+STR_013F_CAPACITY :{BLACK}Capacidade: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}Capacidade: {LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Carga total (capacidade) deste tren:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}Nova Partida
+STR_0141_LOAD_GAME :{BLACK}Cargar Partida
+STR_SINGLE_PLAYER :{BLACK}Un Xogador
+STR_MULTIPLAYER :{BLACK}Multixogador
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Tamaño do mapa:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Opcións da Partida
+
+STR_0150_SOMEONE :alguén{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Mapa do mundo
+STR_0152_TOWN_DIRECTORY :Directorio de cidades
+STR_0153_SUBSIDIES :Subsidios
+
+STR_UNITS_IMPERIAL :Imperial
+STR_UNITS_METRIC :Métrico
+STR_UNITS_SI :SI
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} mph
+STR_UNITS_VELOCITY_METRIC :{COMMA} km/h
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}cv
+STR_UNITS_POWER_METRIC :{COMMA}cv
+STR_UNITS_POWER_SI :{COMMA}kW
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} ton{P "" s}
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} tonelada{P "" s}
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} kg
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}gal
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}l
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}m³
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} galóns{P "" s}
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} litro{P "" s}
+STR_UNITS_VOLUME_LONG_SI :{COMMA} m³
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10³ lbf
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :G. beneficios operativos
+STR_0155_INCOME_GRAPH :Gráfica de ingresos
+STR_0156_DELIVERED_CARGO_GRAPH :Gráfica de carga entregada
+STR_0157_PERFORMANCE_HISTORY_GRAPH :G. historial de Rendemento
+STR_0158_COMPANY_VALUE_GRAPH :Gráfica do Valor da Compañía
+STR_0159_CARGO_PAYMENT_RATES :Taxas de pago polas cargas
+STR_015A_COMPANY_LEAGUE_TABLE :Táboa da Liga de compañías
+STR_PERFORMANCE_DETAIL_MENU :Puntuación de rendemento detallado
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}Acerca de OpenTTD
+STR_015C_SAVE_GAME :Grabar Partida
+STR_015D_LOAD_GAME :Cargar Partida
+STR_015E_QUIT_GAME :Saír ó menu principal
+STR_015F_QUIT :Saír do programa
+STR_ABANDON_GAME_QUERY :{YELLOW}¿Está seguro de que desexa saír da partida?
+STR_0161_QUIT_GAME :{WHITE}Saír ó menú principal
+STR_SORT_ORDER_TIP :{BLACK}Selecciona o modo de ordeamento(descendente/ascendente)
+STR_SORT_CRITERIA_TIP :{BLACK}Selecciona o criterio de orde
+STR_SORT_BY :{BLACK}Ordear por
+
+STR_SORT_BY_POPULATION :{BLACK}Poboación
+STR_SORT_BY_PRODUCTION :{BLACK}Producción
+STR_SORT_BY_TYPE :{BLACK}Tipo
+STR_SORT_BY_TRANSPORTED :{BLACK}Transportado
+STR_SORT_BY_NAME :{BLACK}Nome
+STR_SORT_BY_DROPDOWN_NAME :Nome
+STR_SORT_BY_DATE :{BLACK}Data
+STR_SORT_BY_NUMBER :Número
+STR_SORT_BY_PROFIT_LAST_YEAR :Beneficio último ano
+STR_SORT_BY_PROFIT_THIS_YEAR :Beneficio este ano
+STR_SORT_BY_AGE :Idade
+STR_SORT_BY_RELIABILITY :Rendabilidade
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Capacidade total por tipo de carga
+STR_SORT_BY_MAX_SPEED :Velocidade Máxima
+STR_SORT_BY_MODEL :Modelo
+STR_SORT_BY_VALUE :Valor
+STR_SORT_BY_FACILITY :Tipo de estación
+STR_ENGINE_SORT_COST :Coste
+STR_ENGINE_SORT_POWER :Potencia
+STR_ENGINE_SORT_INTRO_DATE :Data de Presentación
+STR_ENGINE_SORT_RUNNING_COST :Coste Mantemento
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Potencia/Coste Mantemento
+STR_ENGINE_SORT_CARGO_CAPACITY :Capacidade De Carga
+STR_NO_WAITING_CARGO :{BLACK}Non queda ningún tipo de carga en espera
+STR_MANAGE_LIST :{BLACK}Xestionar lista
+STR_REPLACE_VEHICLES :Reemplazar Vehículos
+STR_SEND_TRAIN_TO_DEPOT :Enviar o Depósito
+STR_SEND_ROAD_VEHICLE_TO_DEPOT :Enviar o Depósito
+STR_SEND_SHIP_TO_DEPOT :Enviar o Depósito
+STR_SEND_AIRCRAFT_TO_HANGAR :Enviar o Hangar
+
+############ range for months starts
+STR_0162_JAN :Xan
+STR_0163_FEB :Feb
+STR_0164_MAR :Mar
+STR_0165_APR :Abr
+STR_0166_MAY :Mai
+STR_0167_JUN :Xuñ
+STR_0168_JUL :Xul
+STR_0169_AUG :Ago
+STR_016A_SEP :Set
+STR_016B_OCT :Out
+STR_016C_NOV :Nov
+STR_016D_DEC :Dec
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Pausar Partida
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Grabar partida, abandonar partida, saír
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Amosa-la lista das estacións da compañía
+STR_0174_DISPLAY_MAP :{BLACK}Amosa-lo mapa
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Amosa-lo mapa, directorio de cidades
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Amosa-lo directorio de cidades
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Amosa-la información das finanzas da compañía
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Amosa-la información xeral da compañía
+STR_0179_DISPLAY_GRAPHS :{BLACK}Amosa-las gráficas
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Amosa-la táboa da liga de compañías
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Amosa-la lista dos trens da compañía
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Amosa-la lista dos vehículos de estrada da compañía
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Amosa-la lista dos barcos da compañía
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Amosa-la lista das aeronaves da compañía
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Achega-la vista
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Alonxa-la vista
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Construír elementos do ferrocarril
+STR_0182_BUILD_ROADS :{BLACK}Construír elementos das estradas
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Construír elementos para barcos
+STR_0184_BUILD_AIRPORTS :{BLACK}Construír aeroportos
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Plantar árbores, situar sinais, etc.
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Información dunha área de terreo
+STR_0187_OPTIONS :{BLACK}Opcións
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Non se pode cambia-lo intervalo de servicio...
+STR_018B_CLOSE_WINDOW :{BLACK}Pechar fiestra
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Título da fiestra - arrástrao para move-la fiestra
+STR_STICKY_BUTTON :{BLACK}Marcar esta fiestra coma non pechable pola tecla de 'Pechar tódalas fiestras'
+STR_RESIZE_BUTTON :{BLACK}Pincha e arrastra para redimensiona-la fiestra
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Demoler edificios, etc. nun cadrado de terreo
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Baixar unha esquina de terreo
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Elevar unha esquina de terreo
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Barra de desprazamento - despraza a lista hacia arriba/abaixo
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Barra de desprazamento - despraza a lista a esquerda/dereita
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Amosa-los contornos do terreo no mapa
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Amosa-los vehículos no mapa
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Amosa-las industrias no mapa
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Amosa-las rutas de transporte no mapa
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Amosa-la vexetación no mapa
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Amosa-los propietarios do terreo no mapa
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Amosar/agochar nomes das cidades no mapa
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Beneficio este ano: {CURRENCY} (ano pasado: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} ano{P "" s} ({COMMA})
+STR_AGE_RED :{RED}{COMMA} ano{P "" s} ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Vehículo de estrada
+STR_019D_AIRCRAFT :Aeronave
+STR_019E_SHIP :Barco
+STR_019F_TRAIN :Tren
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} estase volvendo vello
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} estase volvendo moi vello
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} estase volvendo moi vello e debe ser substituído urxentemente
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Información dunha área de terreo
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Coste de limpar: {LTBLUE}N/D
+STR_01A5_COST_TO_CLEAR :{BLACK}Coste de limpar: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :N/D
+STR_01A7_OWNER :{BLACK}Propietario: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Autoridade local: {LTBLUE}{STRING}
+STR_01A9_NONE :Ningún
+STR_01AA_NAME :{BLACK}Nome
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1º
+STR_01AD_2ND :2º
+STR_01AE_3RD :3º
+STR_01AF_4TH :4º
+STR_01B0_5TH :5º
+STR_01B1_6TH :6º
+STR_01B2_7TH :7º
+STR_01B3_8TH :8º
+STR_01B4_9TH :9º
+STR_01B5_10TH :10º
+STR_01B6_11TH :11º
+STR_01B7_12TH :12º
+STR_01B8_13TH :13º
+STR_01B9_14TH :14º
+STR_01BA_15TH :15º
+STR_01BB_16TH :16º
+STR_01BC_17TH :17º
+STR_01BD_18TH :18º
+STR_01BE_19TH :19º
+STR_01BF_20TH :20º
+STR_01C0_21ST :21º
+STR_01C1_22ND :22º
+STR_01C2_23RD :23º
+STR_01C3_24TH :24º
+STR_01C4_25TH :25º
+STR_01C5_26TH :26º
+STR_01C6_27TH :27º
+STR_01C7_28TH :28º
+STR_01C8_29TH :29º
+STR_01C9_30TH :30º
+STR_01CA_31ST :31º
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Carga aceptada: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Jazz Jukebox
+STR_01D3_SOUND_MUSIC :Son/música
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Amosa-la fiestra de son/música
+STR_01D5_ALL :{TINYFONT}Todo
+STR_01D6_OLD_STYLE :{TINYFONT}Vello Estilo
+STR_01D7_NEW_STYLE :{TINYFONT}Novo Estilo
+STR_01D8_EZY_STREET :{TINYFONT}Ezy Street
+STR_01D9_CUSTOM_1 :{TINYFONT}Persoal 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Persoal 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Volume da Música
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Volume dos Efectos de Son
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MÃN ' ' ' ' ' ' MÃX
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Saltar á pista anterior da selección
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Saltar a pista seguinte da selección
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Para-la reproducción de música
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Comeza-la reproducción da música
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Arrastra os deslizadores para configura-los volumes da música e dos efectos de son
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Pista{SETX 88}Título
+STR_01E9_SHUFFLE :{TINYFONT}Mezclar
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Programa
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Selección do Programa de Música
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Ãndice de Pistas
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Programa - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}Limpar
+STR_01F1_SAVE :{TINYFONT}{BLACK}Grabar
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Programa actual de pistas musicais
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Selecciona-lo programa 'Tódalas pistas'
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Selecciona-lo programa 'Música vello estilo'
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Selecciona-lo programa 'Música novo estilo'
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Selecciona-lo programa 'Persoal 1'
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Selecciona-lo programa 'Persoal 2'
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Limpa-lo programa actual(Só Persoalizado 1 e Persoalizado 2)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Graba-la configuración da música
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Pincha nunha pista de música para engadi-la ó programa actual(Sólo Persoal 1 e Persoal 2)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Activar/desactivar programa aleatorio
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Mostra-la pista musical na fiestra de selección
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Pincha no servicio para centra-la vista na industria/cidade
+STR_01FE_DIFFICULTY :{BLACK}Dificultade ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Última mensaxe/noticia
+STR_0201_MESSAGE_SETTINGS :Configuración das Mensaxes
+STR_MESSAGE_HISTORY_MENU :Historial de Mensaxes
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Amosa-la última mensaxe/noticia, amosa-las opcións das mensaxes
+STR_0204_MESSAGE_OPTIONS :{WHITE}Opcións das mensaxes
+STR_0205_MESSAGE_TYPES :{BLACK}Tipos de mensaxes:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Chegada do 1º vehículo a estación do xogador
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Chegada do 1º vehículo a estación dun oponente
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Accidentes / desastres
+STR_0209_COMPANY_INFORMATION :{YELLOW}Información da compañía
+STR_020A_ECONOMY_CHANGES :{YELLOW}Cambios económicos
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Consellos/información sobre os teus vehículos
+STR_020C_NEW_VEHICLES :{YELLOW}Novos vehículos
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Cambios na aceptación de carga
+STR_020E_SUBSIDIES :{YELLOW}Subsidios
+STR_020F_GENERAL_INFORMATION :{YELLOW}Información xeral
+STR_MESSAGES_ALL :{YELLOW}Configuración para tódolos tipos de mesaxes (off/sumario/completo)
+STR_MESSAGE_SOUND :{YELLOW}Reproducir son para mensaxes de noticias resumidas
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...demasiado lonxe do destino anterior
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Mellores compañías que chegaron ó {NUM}{}(Nivel {STRING})
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Táboa da Liga de Compañías en {NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Home de negocios
+STR_0214_ENTREPRENEUR :Empresario
+STR_0215_INDUSTRIALIST :Industrial
+STR_0216_CAPITALIST :Capitalista
+STR_0217_MAGNATE :Magnate
+STR_0218_MOGUL :Mogul
+STR_0219_TYCOON_OF_THE_CENTURY :Magnate da Centuria
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}¡{COMPANY} logra o status de '{STRING}'!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}¡{PLAYERNAME} de {COMPANY} logra o status '{STRING}'!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Crear Escenario
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Editor de Escenario
+STR_0223_LAND_GENERATION :{WHITE}Xeración de Terreo
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Terreo Aleatorio
+STR_0227_RESET_LAND :{BLACK}Reiniciar Terreo
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Aumenta-lo tamaño de terreo a baixar/subir
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Disminuí-lo tamaño de terreo a baixar/subir
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Xerar terreo aleatorio
+STR_022B_RESET_LANDSCAPE :{BLACK}Reiniciar paisaxe
+STR_022C_RESET_LANDSCAPE :{WHITE}Reiniciar paisaxe
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}¿Está seguro de querer reinicia-la paisaxe?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Xeración de paisaxe
+STR_022F_TOWN_GENERATION :{BLACK}Xeración de cidades
+STR_0230_INDUSTRY_GENERATION :{BLACK}Xeración de industrias
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Construcción de estradas
+STR_0233_TOWN_GENERATION :{WHITE}Xeración de Cidades
+STR_0234_NEW_TOWN :{BLACK}Nova Cidade
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Construír nova cidade
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Non se pode construí-la cidade aí...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...demasiado cerca do borde do mapa
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...demasiado cerca doutra cidade
+STR_0239_SITE_UNSUITABLE :{WHITE}...emprazamento inadecuado
+STR_023A_TOO_MANY_TOWNS :{WHITE}...hai demasiadas cidades
+STR_CANNOT_GENERATE_TOWN :{WHITE}Non se pode construír cidades
+STR_NO_SPACE_FOR_TOWN :{WHITE}...non queda máis espacio no mapa
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Incrementa-lo tamaño da cidade
+STR_023C_EXPAND :{BLACK}Expandir
+STR_023D_RANDOM_TOWN :{BLACK}Cidade Aleatoria
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Construír cidade en emprazamento aleatorio
+STR_023F_INDUSTRY_GENERATION :{WHITE}Xeración de Industrias
+STR_0240_COAL_MINE :{BLACK}Mina de Carbón
+STR_0241_POWER_STATION :{BLACK}Estación Enerxética
+STR_0242_SAWMILL :{BLACK}Serradeiro
+STR_0243_FOREST :{BLACK}Bosque
+STR_0244_OIL_REFINERY :{BLACK}Ref. de Petróleo
+STR_0245_OIL_RIG :{BLACK}Torre Petrolífera
+STR_0246_FACTORY :{BLACK}Factoría
+STR_0247_STEEL_MILL :{BLACK}Siderúrxica
+STR_0248_FARM :{BLACK}Granxa
+STR_0249_IRON_ORE_MINE :{BLACK}Mina de Hematita
+STR_024A_OIL_WELLS :{BLACK}Pozo Petrolífero
+STR_024B_BANK :{BLACK}Banco
+STR_024C_PAPER_MILL :{BLACK}Fábrica de Papel
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Planta de Proc. de Comida
+STR_024E_PRINTING_WORKS :{BLACK}Imprenta
+STR_024F_GOLD_MINE :{BLACK}Mina de Ouro
+STR_0250_LUMBER_MILL :{BLACK}Fábrica de Madeiros
+STR_0251_FRUIT_PLANTATION :{BLACK}Plantación de Froitas
+STR_0252_RUBBER_PLANTATION :{BLACK}Plant. Ãrbores de Caucho
+STR_0253_WATER_SUPPLY :{BLACK}Acuífero
+STR_0254_WATER_TOWER :{BLACK}Torre de Auga
+STR_0255_DIAMOND_MINE :{BLACK}Mina de Diamantes
+STR_0256_COPPER_ORE_MINE :{BLACK}Mina de Mineral de Cobre
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Bosque de Algodón de Azucre
+STR_0258_CANDY_FACTORY :{BLACK}Fábrica de Caramelos
+STR_0259_BATTERY_FARM :{BLACK}Granxa de Baterías
+STR_025A_COLA_WELLS :{BLACK}Fontes de Cola
+STR_025B_TOY_SHOP :{BLACK}Tenda de Xoguetes
+STR_025C_TOY_FACTORY :{BLACK}Fábrica de Xoguetes
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Fontes de Plástico
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Fábrica de Bebidas Gaseosas
+STR_025F_BUBBLE_GENERATOR :{BLACK}Xerador de Burbullas
+STR_0260_TOFFEE_QUARRY :{BLACK}Canteira de Toffee
+STR_0261_SUGAR_MINE :{BLACK}Mina de Azucre
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Construír Mina de Carbón
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Construír Estación Enerxética
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Construír Serradeiro
+STR_0265_PLANT_FOREST :{BLACK}Plantar Bosque
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Construír Ref. de Petróleo
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Construí Torre Petrolífera (Só se pode construír cerca dos bordes do mapa)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Construír Factoría
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Construír Siderúrxica
+STR_026A_CONSTRUCT_FARM :{BLACK}Construír Granxa
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Construír Mina de Hematita
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Construír Pozo Petrolífero
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Construír Banco (Só se pode construír en cidades con máis de 1200 hab.)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Construír Fábrica de Papel
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Construír Planta de Procesamiento de Comida
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Construír Imprenta
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Construír Mina de Ouro
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Construír Banco (Só se pode construír en cidades)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Construír Fábrica de Madeiros (para limpa-los bosques e producir madeira)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Plantar Plantación de Froitas
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Plantar Plant. de Ãrbores de Caucho
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Construír Acuífero
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Construír Torre de Auga (Só se pode construír en cidades)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Construír Mina de Diamantes
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Construír Mina de Mineral de Cobre
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Plantar Bosque de Algodón de Azucre
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Construír Fábrica de Caramelos
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Construír Granxa de Baterías
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Construír Fontes de Cola
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Construír Xoguetería
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Construír Fábrica de Xoguetes
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Construír Fontes de Plástico
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Construír Fábrica de Bebidas Gaseosas
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Construír Xerador de Burbullas
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Construír Canteira de Toffee
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Construír Mina de Azucre
+STR_0285_CAN_T_BUILD_HERE :{WHITE}Non se pode construír {STRING} aquí...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...debes construír unha cidade primeiro
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...soamente se permite un/unha por cidade
+STR_0288_PLANT_TREES :{BLACK}Plantar árbores
+STR_0289_PLACE_SIGN :{BLACK}Colocar sinal
+STR_028A_RANDOM_TREES :{BLACK}Ãrbores aleatorias
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Plantar árbores aleatoriamente sobre a paisaxe
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Colocar áreas rocosas na paisaxe
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Colocar faro
+STR_028E_PLACE_TRANSMITTER :{BLACK}Colocar transmisor
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Definir área de deserto
+STR_CREATE_LAKE :{BLACK}Definir área de auga.{}Inundará os arredores se está a nivel do mar
+STR_0290_DELETE :{BLACK}Borrar
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Borrar completamente esta cidade
+STR_0292_SAVE_SCENARIO :Grabar Escenario
+STR_0293_LOAD_SCENARIO :Cargar Escenario
+STR_0294_QUIT_EDITOR :Saír do editor
+STR_0295 :
+STR_0296_QUIT :Saír
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Grabar escenario, cargar scenario, abandonar editor de escenarios, saír
+STR_0298_LOAD_SCENARIO :{WHITE}Cargar Escenario
+STR_0299_SAVE_SCENARIO :{WHITE}Grabar Escenario
+STR_029A_PLAY_SCENARIO :{BLACK}Xogar Escenario
+STR_QUIT_SCENARIO_QUERY :{YELLOW}¿Estás seguro de que desexas saír deste escenario?
+STR_029C_QUIT_EDITOR :{WHITE}Saír do Editor
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...só se pode construír en cidades con polo menos 1200 hab.
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Move-lo ano de comezo un ano hacia atrás
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Move-lo ano de comezo un ano hacia adiante
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...os finais da ponte deben estar ambos en terra
+STR_02A1_SMALL :{BLACK}Pequeno
+STR_02A2_MEDIUM :{BLACK}Mediano
+STR_02A3_LARGE :{BLACK}Grande
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Selecciona o tamaño da cidade:
+STR_02A5_TOWN_SIZE :{YELLOW}Tamaño da cidade:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Amosa-la última mesaxe ou noticia
+STR_OFF :Apagado
+STR_SUMMARY :Sumario
+STR_FULL :Completo
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Directorio de cidades
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Nomes dos deseños dos vehículos
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Defecto
+STR_02BF_CUSTOM :Persoalizado
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Graba-los nomes persoalizados
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Selección de nomes dos deseños dos vehículos
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Graba-los nomes dos deseños dos vehículos persoalizados no disco
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Opcións da Partida
+STR_02C5_DIFFICULTY_SETTINGS :Configuración de Dificultade
+STR_02C7_CONFIG_PATCHES :Configuración dos Parches
+STR_NEWGRF_SETTINGS :Configuración de Newgrf
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Amosar nomes de cidades
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Amosae nomes de estacións
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Amosa-los sinais
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Amosar puntos de control
+STR_02D0_FULL_ANIMATION :{SETX 12}Animación completa
+STR_02D2_FULL_DETAIL :{SETX 12}Detalle completo
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Edificios transparentes
+STR_TRANSPARENT_SIGNS :{SETX 12}Sinais de estación transparentes
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Información de área de terreo
+STR_02D6 :
+STR_CONSOLE_SETTING :Des/Activar Consola
+STR_02D7_SCREENSHOT_CTRL_S :Captura de Pantalla (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Capt.Pant. Xigante (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :Acerca de 'OpenTTD'
+############ range ends here
+
+STR_02DB_OFF :{BLACK}Off
+STR_02DA_ON :{BLACK}On
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Amosa-los subsidios
+STR_02DD_SUBSIDIES :Subsidios
+STR_02DE_MAP_OF_WORLD :Mapa do Mundo
+STR_EXTRA_VIEW_PORT :Fiestra Extra
+STR_SIGN_LIST :Lista de sinais
+STR_02DF_TOWN_DIRECTORY :Directorio de cidades
+STR_TOWN_POPULATION :{BLACK}Poboación mundial: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Vista {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Copiar a vista
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Copia a sitaución da vista global nesta vista
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Pega a situación desta vista na vista global
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Unidades monetarias
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Selección de unidades monetarias
+STR_MEASURING_UNITS :{BLACK}Unidades de medida
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Selección das unidades de medida
+STR_02E6_ROAD_VEHICLES :{BLACK}Vehículos de estrada
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Selecciona o lado da estrada polo que rodarán os vehículos
+STR_02E9_DRIVE_ON_LEFT :Conducir pola esquerda
+STR_02EA_DRIVE_ON_RIGHT :Conducir pola dereita
+STR_02EB_TOWN_NAMES :{BLACK}Nomes das cidades
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Selecciona o estilo dos nomes das cidades
+
+STR_02F4_AUTOSAVE :{BLACK}Autograbado
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Selecciona o intervalo entre autograbados
+STR_02F7_OFF :Apagado
+STR_02F8_EVERY_3_MONTHS :Cada 3 meses
+STR_02F9_EVERY_6_MONTHS :Cada 6 meses
+STR_02FA_EVERY_12_MONTHS :Cada 12 meses
+STR_02FB_START_A_NEW_GAME :{BLACK}Comezar nova partida
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Cargar unha partida
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Crear un mundo/escenario persoalizado
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Partida para un Xogador
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Seleccionar partida multixogador de 2-8 xogadores
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Amosa-las opcións do xogo
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Amosa-las opcións de dificultade
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Comezar unha nova partida, usando un escenario persoalizado
+STR_0304_QUIT :{BLACK}Saír
+STR_0305_QUIT_OPENTTD :{BLACK}Saír 'OpenTTD'
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...só se pode construír en cidades
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Selecciona-lo estilo da paisaxe 'Templado'
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Selecciona-lo estilo da paisaxe 'Subártico'
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Selecciona-lo estilo da paisaxe 'Subtropical'
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Selecciona-lo estilo da paisaxe 'Xoguetelandia'
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Fundar unha nova industria
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Directorio de Industrias
+STR_0313_FUND_NEW_INDUSTRY :Fundar unha nova industria
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Fundar unha nova industria
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...só se pode construír en cidades
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...só se pode construír en zonas de selva tropical
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...só se pode construír en zonas desérticas
+STR_0319_PAUSED :{YELLOW}* * EN PAUSA * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Captura de pantalla grabada con éxito no disco como '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}¡Captura de pantalla fallida!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Comprar terreo para futuro uso
+STR_032F_AUTOSAVE :{RED}AUTOGUARDADO
+STR_SAVING_GAME :{RED}* * GRABANDO PARTIDA * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}¡Grabación en progreso,{}por favor espera ata que termine!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Selecciona-lo programa 'Música Estilo Ezy Street'
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :Inglés
+STR_TOWNNAME_FRENCH :Francés
+STR_TOWNNAME_GERMAN :Alemán
+STR_TOWNNAME_ADDITIONAL_ENGLISH :Inglés (Adicional)
+STR_TOWNNAME_LATIN_AMERICAN :Latino-Americano
+STR_TOWNNAME_SILLY :Estúpido
+STR_TOWNNAME_SWEDISH :Sueco
+STR_TOWNNAME_DUTCH :Holandés
+STR_TOWNNAME_FINNISH :Finés
+STR_TOWNNAME_POLISH :Polaco
+STR_TOWNNAME_SLOVAKISH :Eslovaco
+STR_TOWNNAME_NORWEGIAN :Noruegués
+STR_TOWNNAME_HUNGARIAN :Húngaro
+STR_TOWNNAME_AUSTRIAN :Austríaco
+STR_TOWNNAME_ROMANIAN :Rumano
+STR_TOWNNAME_CZECH :Checo
+STR_TOWNNAME_SWISS :Suízo
+STR_TOWNNAME_DANISH :Danés
+STR_TOWNNAME_TURKISH :Turco
+STR_TOWNNAME_ITALIAN :Italiano
+STR_TOWNNAME_CATALAN :Catalán
+############ end of townname region
+
+STR_CURR_GBP :Libras (£)
+STR_CURR_USD :Dólares ($)
+STR_CURR_EUR :Euro (€)
+STR_CURR_YEN :Yen (Â¥)
+STR_CURR_ATS :Chelín Austríaco (ATS)
+STR_CURR_BEF :Franco Belga (BEF)
+STR_CURR_CHF :Franco Suizo (CHF)
+STR_CURR_CZK :Corona Checa (CZK)
+STR_CURR_DEM :Marcos Alemáns (DEM)
+STR_CURR_DKK :Corona Danesa (DKK)
+STR_CURR_ESP :Peseta (ESP)
+STR_CURR_FIM :Marco Finés (FIM)
+STR_CURR_FRF :Franco (FRF)
+STR_CURR_GRD :Dracma Grego (GRD)
+STR_CURR_HUF :Forinto Húngaro (HUF)
+STR_CURR_ISK :Corona Islandesa (ISK)
+STR_CURR_ITL :Lira Italiana (ITL)
+STR_CURR_NLG :Florín Holandés (NLG)
+STR_CURR_NOK :Corona Noruguesa (NOK)
+STR_CURR_PLN :Zloty Polaco (PLN)
+STR_CURR_ROL :Leu Rumano (ROL)
+STR_CURR_RUR :Rublo Ruso (RUR)
+STR_CURR_SIT :Tolar Esloveno (SIT)
+STR_CURR_SEK :Corona Sueca(SEK)
+STR_CURR_YTL :Lira Turca (YTL)
+STR_CURR_BRR :Real Brasileño (BRL)
+
+STR_CURR_CUSTOM :Persoal...
+
+STR_OPTIONS_LANG :{BLACK}Idioma
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Selecciona o idioma para utilizar na interface
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Pantalla Completa
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}Marca nesta caixa para xogar a OpenTTD en modo de pantalla completa
+
+STR_OPTIONS_RES :{BLACK}Resolución da pantalla
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Selecciona a resolución de pantalla a utilizar
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Formato capturas de pantalla
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Selecciona o formato a utilizar nas capturas de pantalla
+
+STR_AUTOSAVE_1_MONTH :Cada mes
+STR_AUTOSAVE_FAILED :{WHITE}Autograbado fallido
+
+STR_MONTH_JAN :Xaneiro
+STR_MONTH_FEB :Febreiro
+STR_MONTH_MAR :Marzo
+STR_MONTH_APR :Abril
+STR_MONTH_MAY :Maio
+STR_MONTH_JUN :Xuño
+STR_MONTH_JUL :Xullo
+STR_MONTH_AUG :Agosto
+STR_MONTH_SEP :Setembro
+STR_MONTH_OCT :Outubro
+STR_MONTH_NOV :Novembro
+STR_MONTH_DEC :Decembro
+
+STR_HEADING_FOR_STATION :{LTBLUE}Diríxese a {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}Diríxese a {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Sen ordes
+STR_NO_ORDERS_VEL :{LTBLUE}Sen ordes, {VELOCITY}
+
+STR_PASSENGERS :pasaxeiros
+STR_BAGS :sacos
+STR_TONS :tons
+STR_LITERS :litros
+STR_ITEMS :items
+STR_CRATES :caixóns
+STR_RES_OTHER :outro
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Non se pode comparti-la lista de ordes...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Non se pode copia-la lista de ordes...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - Fin das ordes compartidas - -
+
+STR_TRAIN_IS_LOST :{WHITE}Perdiches o tren {COMMA}.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}O beneficio para o tren {COMMA} o ano pasado foi de {CURRENCY}
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}¡Unión Monetaria Europea!{}{}¡O Euro introdúcese como a única moeda para as transaccións diarias no teu país!
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}O tren {COMMA} ten moi poucas ordes no seu programa
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}O tren {COMMA} ten unha orde inválida
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}O tren {COMMA} ten ordes duplicadas
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}O tren {COMMA} ten unha estación non válida nas ordes
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}O vehículo de estrada {COMMA} ten moi poucas ordes no seu programa
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}O vehículo de estrada {COMMA} ten unha orde inválida
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}O vehículo de estrada {COMMA} ten ordes duplicadas
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}O vehículo de Estrada {COMMA} ten unha estación non válida nas ordes
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}O barco {COMMA} ten moi poucas ordes no seu programa
+STR_SHIP_HAS_VOID_ORDER :{WHITE}O barco {COMMA} ten unha orde inválida
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}O barco {COMMA} ten ordes duplicadas
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}O Barco {COMMA} ten unha estación non válida nas ordes
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}A aeronave {COMMA} ten moi poucas ordes no seu programa
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}A aeronave {COMMA} ten unha orde inválida
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}A aeronave {COMMA} ten ordes duplicadas
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}A aeronave {COMMA} ten unha estación non válida nas ordes
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}Autorenovación fallida para o tren {COMMA} (límite de diñeiro)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}Autorenovación fallida para o vehículo de estrada {COMMA} (límite de diñeiro)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}Autorenovación fallida para o barco {COMMA} (límite de diñeiro)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}Autorenovación fallida para a aeronave {COMMA} (límite de diñeiro)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}O tren {COMMA} e demasiado longo despois de substituír
+
+STR_CONFIG_PATCHES :{BLACK}Configuración dos Parches
+STR_CONFIG_PATCHES_TIP :{BLACK}Configura-los parches
+STR_CONFIG_PATCHES_CAPTION :{WHITE}Configuración dos Parches
+
+STR_CONFIG_PATCHES_OFF :Off
+STR_CONFIG_PATCHES_ON :On
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Mostra-la velocidade do vehículo na barra de estado: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Permiti-la construción en rampas e costas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Permitir áreas de captura máis realistas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Permiti-la eliminación de máis estradas, etc... das cidades: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Permiti-la construcción de trens moi largos: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Habilita-la aceleración realista nos trens: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Prohibir os trens e os barcos facer xiros de 90 graos: {ORANGE}{STRING} {LTBLUE} (require NPF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Xunta-las estacións construídas xuntas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Saír se calquera carga está chea,cando 'Carga chea': {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Usa-lo algoritmo de carga mellorado: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Inflación: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Descarga-la carga só cando haxa demanda: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Permiti-la construcción de pontes moi longas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Permiti-las ordes de ir ó depósito: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Permiti-la construccion de industrias de materiales: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Permitir múltiples industrias similares en cada cidade: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Permiti-la construcción de industrias iguais cercanas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Mostrar sempre a data longa na barra de estado: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Mostrar sinais no lado de conducción: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Mostra-la fiestra de finanzas ó final do ano: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}Manexo de nonstop compatible con TTDPatch: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Cola para vehículos de estrada (con efectos cuánticos): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Desplaza-la fiestra cando o ratón esté no borde: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Permiti-la chantaxe as autoridades locales: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Estacións non uniformes: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Nova búsqueda de ruta global (NPF, invalida NTP): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Permitir sempre aeroportos pequenos: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Revisa-las ordes do vehículo: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :no
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :si, pero exclúe os vehículos parados
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :de tódolos vehículos
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Advertir se os ingresos dun tren son negativos: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Os vehículos nunca caducan: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Autorenova-los vehículos cando envellezan
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Autorenovar {ORANGE}{STRING}{LTBLUE} meses antes/despois da idade máxima
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Diñeiro mínimo necesario para a autorenovación: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Duración das mensaxes de error: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Mostra-la poboación da cidade na etiqueta: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Ãrbores invisibles (con edificios transparentes): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Xerador de mapas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :Orixinal
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Altura da liña de neve: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TREE_PLACER :{LTBLUE}Algoritmo de colocación de árbores: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TREE_PLACER_NONE :Ningún
+STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL :Orixinal
+STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED :Mellorado
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Extensión Max. Estación: {ORANGE}{STRING} {RED}Aviso: Valores altos reducen rendemento
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Face-lo servicio os helicópteros no heliporto automáticam.: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Inverti-la dirección de desplazamento: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES_NONE :Ningunha
+STR_CONFIG_PATCHES_LIVERIES_ALL :Tódalas compañías
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Nº máximo de trens por xogador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Nº máximo de vehículos de estrada por xogador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}Nº máximo de aeronaves por xogador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}Nº máximo de barcos por xogador: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Deshabilita-los trens para o ordenador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Deshabilita-los vehículos de estrada para o ordenador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Deshabilita-las aeronaves para o ordenador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Deshabilita-los barcos para o ordenador: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Activar nova AI (alpha): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Permitir IAs en multixogador (experimental): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Intervalo de servicio para os trens: {ORANGE}{STRING} días
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Intervalo de servicio para os trens: {ORANGE}deshabilitado
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Intervalo de servicio para os vehículos de estrada: {ORANGE}{STRING} días
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Intervalo de servicio para os vehículos de estrada: {ORANGE}deshabilitado
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Intervalo de servicio para as aeronaves: {ORANGE}{STRING} días
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Intervalo de servicio para as aeronaves: {ORANGE}deshabilitado
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Intervalo de servicio para os barcos: {ORANGE}{STRING} días
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Intervalo de servicio para os barcos: {ORANGE}deshabilitado
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Deshabilita-lo servicio cando as roturas están a ningún: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Data de aparición das noticias en color: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Data de comezo: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}Terminar partida en: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Habilita-la economía "suave"(máis cambios, pero máis pequenos)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Permiti-la compra de accións por outras compañías
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Cando se arrastre, colocar siniais cada: {ORANGE}{STRING} cadrado(s)
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Posición da barra de ferramentas principal: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Esquerda
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Centro
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Dereita
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Radio de captura da fiestra: {ORANGE}{STRING} px
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Radio de agarre da fiestra: {ORANGE}desactivado
+
+STR_CONFIG_PATCHES_GUI :{BLACK}Interface
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Construcción
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Vehículos
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Estacións
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Economía
+STR_CONFIG_PATCHES_AI :{BLACK}Competidores
+
+STR_CONFIG_PATCHES_DISABLED :deshabilitado
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Cambia-lo valor
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}¡Algún ou tódolos intervalo(s) de servicio por defecto son incompatibles coa opción elixida! 5-90% e 30-800 días son válidos
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}Usar YAPF para barcos: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}Usar YAPF para vehículos de estrada: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}Usar YAPF para os trens: {ORANGE}{STRING}
+
+STR_TEMPERATE_LANDSCAPE :escenario templado
+STR_SUB_ARCTIC_LANDSCAPE :escenario sub-ártico
+STR_SUB_TROPICAL_LANDSCAPE :escenario sub-tropical
+STR_TOYLAND_LANDSCAPE :escenario xoguetelandia
+
+STR_CHEATS :{WHITE}Trampas
+STR_CHEATS_TIP :{BLACK}As caixas de confirmación indican se usaches esta trampa antes
+STR_CHEATS_WARNING :{BLACK}¡Advertencia! Estás a piques de traizoa-los teus oponentes. Ten en conta que unha desgracia coma esta se lembrará eternamente.
+STR_CHEAT_MONEY :{LTBLUE}Incrementa-lo diñeiro en {CURRENCY64}
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Xogar coma xogador: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Escavadora máxica(Elimina industrias, non eliminables): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Os tuneis poden cruzarse entre eles: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Permiti-la construcción en modo pausa: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Os avíons de jet no se estrelarán (frecuentemente) nos aeroportos pequenos: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Cambiar clima: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Cambiar data: {ORANGE} {DATE_SHORT}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}Diríxese a {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Diríxese a {WAYPOINT}, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :Ir vía {WAYPOINT}
+STR_GO_NON_STOP_TO_WAYPOINT :Ir sen parar vía {WAYPOINT}
+
+STR_WAYPOINTNAME_CITY :Punto de Control {TOWN}
+STR_WAYPOINTNAME_CITY_SERIAL :Punto de control {TOWN} #{COMMA}
+STR_LANDINFO_WAYPOINT :Punto de control
+
+STR_WAYPOINT :{WHITE}Punto de ruta
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Selecciona-lo tipo de punto de ruta
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}Edita-lo nome do punto de control
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Non se pode cambia-lo nome do punto de control...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Convertir raíl a punto de control
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Non se pode construír un punto de control de tren aí...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Non se pode eliminar-lo punto de control...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Construí-la vía de ferrocarril usando o modo Autoraíl
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}...non hai cidades neste escenario
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}¿Estás seguro de querer crear unha paisaxe aleatoria?
+STR_MANY_RANDOM_TOWNS :{BLACK}Varias cidades aleatorias
+STR_RANDOM_TOWNS_TIP :{BLACK}Cubri-lo mapa con cidades colocadas aleatoriamente
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Varias industrias aleatorias
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Cubri-lo mapa con industrias colocadas aleatoriamente
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Non se poden xera-las industrias...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Abri-la ferramenta de terreo para subir/baixar terreo, plantar árbores, etc.
+STR_LANDSCAPING_TOOLBAR :{WHITE}Modifica-lo terreo
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Nivelar terreo
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Ãrbores aleatorias
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}Colocar árbores dun tipo aleatorio
+
+STR_CANT_BUILD_CANALS :{WHITE}Non se pode construí-los canais aí...
+STR_BUILD_CANALS_TIP :{BLACK}Construír canais
+STR_LANDINFO_CANAL :Canal
+
+STR_CANT_BUILD_LOCKS :{WHITE}Non se pode construí-lo peche aí...
+STR_BUILD_LOCKS_TIP :{BLACK}Construír peches
+STR_LANDINFO_LOCK :Peche
+
+STR_BUOY_IS_IN_USE :{WHITE}...a boia está en uso!
+
+STR_LANDINFO_COORDS :{BLACK}Coordenadas: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Non se pode eliminar parte da estación...
+STR_CANT_CONVERT_RAIL :{WHITE}Non se pode converti-lo tipo de vía aí...
+STR_CONVERT_RAIL_TIP :{BLACK}Convertir/actualizar tipo de vía
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Arrastra a máquina do tren aquí para vender todo o tren
+
+STR_DRAG_DROP :{BLACK}Arrastrar e Soltar
+STR_STATION_DRAG_DROP :{BLACK}Construír estación arrastrando e soltando
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Selecciona o tipo da estación a construir
+
+STR_FAST_FORWARD :{BLACK}Avance rápido da partida
+STR_MESSAGE_HISTORY :{WHITE}Historial de Mensaxes
+STR_MESSAGE_HISTORY_TIP :{BLACK}Unha lista das mensaxes e noticias recentes
+STR_MESSAGES_DISABLE_ALL :{BLACK}Desactivar todo
+STR_MESSAGES_ENABLE_ALL :{BLACK}Activar todo
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Construír Mina de Carbón
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Plantar Bosque
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Construír Torre Petrolífera
+STR_CONSTRUCT_FARM_TIP :{BLACK}Fundar granxa
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Construír Mina de Mineral de Cobre
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Perforar para buscar Petróleo
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Construír Mina de Ouro
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Construír Mina de Diamantes
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Construír Mina de Hematita
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Fundar Plantación de Froita
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Fundar Plant. de Ãrbores de Caucho
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Fundar Acuífero
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Plantar Bosque de Algodón de Azucre
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}Fundar Granxa de Baterías
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Perforar para buscar Cola
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Fundar Fontes de Plástico
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Construír Xerador de Burbullas
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Fundar Canteira de Toffee
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Construír Mina de Azucre
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Industrias
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA}% transportado)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA}%/{COMMA}% transportado)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}...demasiado cerca doutra industria
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Reaxusta-lo tren para un tipo de carga diferente
+STR_RAIL_REFIT_VEHICLE :{BLACK}Reaxustar tren
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Selecciona o tipo de carga que levará o tren
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Reaxusta-lo tren para o tipo de carga seleccionado
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}No se pode reaxusta-lo tren...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Intervalos de servicio en porcentaxes: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Cambiar producción
+
+TEMP_AI_ACTIVATED :{WHITE}¡Advertencia: esta nova AI esta en estado alfa! ¡ Neste momento só funcionan os camións e os buses!
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Multixogador
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Nome do xogador:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}Este é o nome polo que te identificarán os outros xogadores
+STR_NETWORK_CONNECTION :{BLACK}Conexión:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Escolle entre unha partida en InterNet ou unha partida na rede de área local
+
+STR_NETWORK_START_SERVER :{BLACK}Iniciar servidor
+STR_NETWORK_START_SERVER_TIP :{BLACK}Comezar un servidor propio
+
+STR_NETWORK_GAME_NAME :{BLACK}Nome
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Nome da partida
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Idioma, versión do servidor, etc.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Pincha nunha partida da lista para seleccionala
+
+STR_NETWORK_FIND_SERVER :{BLACK}Buscar servidor
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Buscar un servidor na rede
+STR_NETWORK_ADD_SERVER :{BLACK}Engadir servidor
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Engade un servidor á lista que será comprobado sempre para buscar partidas.
+STR_NETWORK_ENTER_IP :{BLACK}Introduce a dirección IP do servidor
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Clientes
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Clientes conectador / clients máximos
+STR_NETWORK_GAME_INFO :{SILVER}INFORMACIÓN DA PARTIDA
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Clientes: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Idioma: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Set de Terreo: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Tamaño: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}Versión do servidor: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}Dirección do servidor: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Data de comezo: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Data actual: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}¡Protexido con clave!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}SERVIDOR DESCONECTADO
+STR_NETWORK_SERVER_FULL :{SILVER}SERVIDOR CHEO
+STR_NETWORK_VERSION_MISMATCH :{SILVER}VERSION INCORRECTA
+
+STR_NETWORK_JOIN_GAME :{BLACK}Unirse á partida
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}Comezar nova partida
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Nome:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}O nome da partida mostraráse ó outros xogadores no menú de selección de partida multixogador
+STR_NETWORK_SET_PASSWORD :{BLACK}Establecer clave
+STR_NETWORK_PASSWORD_TIP :{BLACK}Protexe a túa partida cun contrasinal se non queres que outras persoas se unan
+STR_NETWORK_SELECT_MAP :{BLACK}Selecciona un mapa:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}¿Que mapa queres xogar?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}Máximo de clientes permitidos:
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Escolle o máximo número de clientes. Non tódolas liñas teñen que estar cubertas
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :LAN
+STR_NETWORK_INTERNET :Internet
+STR_NETWORK_LAN_INTERNET :LAN / Internet
+STR_NETWORK_INTERNET_ADVERTISE :Internet (anunciar)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 xogadores
+STR_NETWORK_1_PLAYERS :1 xogador
+STR_NETWORK_2_PLAYERS :2 xogadores
+STR_NETWORK_3_PLAYERS :3 xogadores
+STR_NETWORK_4_PLAYERS :4 xogadores
+STR_NETWORK_5_PLAYERS :5 xogadores
+STR_NETWORK_6_PLAYERS :6 xogadores
+STR_NETWORK_7_PLAYERS :7 xogadores
+STR_NETWORK_8_PLAYERS :8 xogadores
+STR_NETWORK_9_PLAYERS :9 xogadores
+STR_NETWORK_10_PLAYERS :10 xogadores
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}Nº máx. de compañías:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Limita-lo servidor a unha certa cantidade de compañías
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}Nº máx. de espectadores:
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Limita-lo servidor a unha certa cantidade de espectadores
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Idioma falado:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Outros xogadores sabrán cal é o idioma que se fala no servidor
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}Iniciar Partida
+STR_NETWORK_START_GAME_TIP :{BLACK}Comezar unha nova partida en rede a partires dun mapa aleatorio, ou un escenario
+STR_NETWORK_LOAD_GAME :{BLACK}Cargar Partida
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Resumir unha partida multixogador anterior (asegúrate de conectarte coma o xogador correcto)
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Calquera
+STR_NETWORK_LANG_ENGLISH :Inglés
+STR_NETWORK_LANG_GERMAN :Alemán
+STR_NETWORK_LANG_FRENCH :Francés
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Sala de espera de partida multixogador
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Preparando para unirse: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}Unha lista de tódalas compañías nesta patida. Podes unirte a unha ou empezar unha nova se hai algún lugar libre
+STR_NETWORK_NEW_COMPANY :{BLACK}Nova compañía
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Abrir unha nova compañía
+STR_NETWORK_SPECTATE_GAME :{BLACK}Observar partida
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Observa-la partida coma espectador
+STR_NETWORK_JOIN_COMPANY :{BLACK}Unirse a compañía
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Axudar a manexar compañía
+STR_NETWORK_REFRESH :{BLACK}Actualizar servidor
+STR_NETWORK_REFRESH_TIP :{BLACK}Actualiza-la información do servidor
+
+STR_NETWORK_COMPANY_INFO :{SILVER}INFORMACIÓN DA COMPAÑÃA
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Nome da compañía: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}Inauguración: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}Valor da compañía: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Balance actual: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Ingresos do ano pasado: {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}Rendemento: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}Vehículos: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Estacións: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Xogadores: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}Conectando...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) Conectando..
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Autorizando..
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Esperando..
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Descargando mapa..
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Procesando datos..
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) Rexistrando..
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Descargando información da partida..
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Descargando información da compañía..
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} cliente{P "" s} diante túa
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} kbytes descargados
+
+STR_NETWORK_DISCONNECT :{BLACK}Desconectar
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Introduce a cantidade de diñeiro a dar
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}O servidor está protexido. Introduce clave
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}A comañía está protexida. Introduce clave
+STR_NETWORK_CLIENT_LIST :{WHITE}Lista de Clientes
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE} Non se atoparon dispositivos de rede ou compilouse sen ENABLE_NETWORK
+STR_NETWORK_ERR_NOSERVER :{WHITE} Non se atoparon xogos en rede
+STR_NETWORK_ERR_NOCONNECTION :{WHITE} O servidor non respondeu á solicitude
+STR_NETWORK_ERR_DESYNC :{WHITE} Sincronización da partida en rede fallida
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} Perdeuse a conexión da partida en rede
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} Non se pode carga-la partida
+STR_NETWORK_ERR_SERVER_START :{WHITE} Non se pode arrinca-lo servidor
+STR_NETWORK_ERR_CLIENT_START :{WHITE} Non se pode conectar
+STR_NETWORK_ERR_TIMEOUT :{WHITE} Conexión #{NUM} fora de tempo
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE} Produciuse un erro de protocolo e pechouse a conexión
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE} A revisión deste cliente no e igual ca revisión do servidor.
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} Contrasinal errónea
+STR_NETWORK_ERR_SERVER_FULL :{WHITE} O servidor está cheo
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} Fuches
+STR_NETWORK_ERR_KICKED :{WHITE} Fuches pateado da partida
+STR_NETWORK_ERR_CHEATER :{WHITE} Non se permite facer trampas neste servidor
+
+STR_NETWORK_ERR_LEFT :saíu da partida
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :error xeral
+STR_NETWORK_ERR_CLIENT_DESYNC :error de descincronización
+STR_NETWORK_ERR_CLIENT_SAVEGAME :no se pode carga-lo mapa
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :coneción perdida
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :error de protocolo
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :Non Autorizado
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :recibiuse un paquete extraño
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :revisión errónea
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :o nome xa está en uso
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :contrasinal incorrecta
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :id de xogador errónea en DoCommand
+STR_NETWORK_ERR_CLIENT_KICKED :pateado polo servidor
+STR_NETWORK_ERR_CLIENT_CHEATER :intentaba usar un truco
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :servidor cheo
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :uniuse á partida
+STR_NETWORK_GIVE_MONEY :deu a túa compañía algún diñeiro ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :diches a {STRING} algún diñeiro ({CURRENCY})
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Equipo] :
+STR_NETWORK_CHAT_COMPANY :[Equipo] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Equipo] A {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[Privado] :
+STR_NETWORK_CHAT_CLIENT :[Privado] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[Privado] A {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[Todos] :
+STR_NETWORK_CHAT_ALL :[Todos] {STRING}: {GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :cambiou o seu nome por
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE} O servidor pechou a conexión
+STR_NETWORK_SERVER_REBOOT :{WHITE} O servidor estase a reiniciar...{}Espera por favor...
+
+STR_NETWORK_SERVER :Servidor
+STR_NETWORK_CLIENT :Cliente
+STR_NETWORK_SPECTATORS :Espectadores
+
+STR_NETWORK_CLIENTLIST_NONE :(ningún)
+STR_NETWORK_CLIENTLIST_KICK :Patear
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Dar diñeiro
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Falar a todos
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Falar con compañía
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Mensaxe privada
+
+
+STR_NETWORK_SEND :{BLACK}Enviar
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}Tamaño X do mapa: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Tamaño Y do mapa: {ORANGE}{STRING}
+
+
+##### PNG-MAP-Loader
+
+STR_PNGMAP_ERROR :{WHITE}Non se pode cargar o mapa do PNG...
+STR_PNGMAP_ERR_FILE_NOT_FOUND :{WHITE}...arquivo non atopado.
+STR_PNGMAP_ERR_IMAGE_TYPE :{WHITE}...non se puido convertir o tipo de imaxe. Necesítase unha imaxe PNG de 8 ou 24 bit.
+
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Coste: {CURRENCY}
+STR_0801_COST :{RED}Coste: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Ingreso: {CURRENCY}
+STR_0803_INCOME :{GREEN}Ingreso: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Transferir: {CURRENCY}
+STR_FEEDER :{YELLOW}Transferir: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Estimated Coste: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Ingreso Estimado: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Non se pode subi-lo terreo aí...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Non se pode baixa-lo terreo aí...
+STR_080A_ROCKS :Rochas
+STR_080B_ROUGH_LAND :Terra Quebrada
+STR_080C_BARE_LAND :Terra Deserta
+STR_080D_GRASS :Herba
+STR_080E_FIELDS :Campos
+STR_080F_SNOW_COVERED_LAND :Terra cuberta de neve
+STR_0810_DESERT :Deserto
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Terreo inclinado na direccion incorrecta
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Combinación de pistas imposible
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}A excavación danaría un tunel
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Xa está a nivel do mar
+STR_1004_TOO_HIGH :{WHITE}Demasiado alto
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Non hay vía de ferrocarril adecuada
+STR_1007_ALREADY_BUILT :{WHITE}...xa está construído
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Debes elimina-la pistad e ferrocarril primeiro
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Construcción de Ferrocarrís
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Construcción de Monorraíl
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}Construcción de MagLev
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Selecciona a Ponte do Ferrocarril
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Non se pode construír un depósito aí...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Non se pode construí-la estación de ferrorcarril aí...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Non se poden construí-los sinais aí...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Non se pode construí-la pista do ferrocarril aí...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Non se pode elimina-la pista de ferrocarril de aí...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Non se pode elimina-los sinais de aí...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Orient. do Dep. de Trens
+STR_1015_RAILROAD_CONSTRUCTION :Construcción de Ferrocarrís
+STR_1016_MONORAIL_CONSTRUCTION :Construcción de Monorraíl
+STR_1017_MAGLEV_CONSTRUCTION :Construcción de MagLev
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Construír vía de ferrocarril
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Construír depósito de trens (para construír e dar servicio os trens)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Construír estación de ferrocarril
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Construír sinais de ferrocaril
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Construír ponte de ferrocaril
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Construír túnel de ferocarril
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Intecambiar construír/eliminar para vías e sinais de ferrocarril
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Selección de pontes - picha na ponte seleccionada para construíla
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Selecciona-la orientación do depósito de ferrocarrís
+STR_1021_RAILROAD_TRACK :Vía de ferrocarril
+STR_1023_RAILROAD_TRAIN_DEPOT :Depósito para trens
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...a área é propiedade doutra compañía
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :Vía de ferrocarril con sinais normais
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :Vía de ferrocarril con pre-sinais
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :vía de ferrocarril con sinais de saída
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :Via de ferrocarril con sinais combinados
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Debes elimina-la estrada primeiro
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Construcción de Estradas
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Selecciona a Ponte
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Non se pode construí-la estrada aí...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Non se pode elimina-la estrada aí...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Orient. do Depósito
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Non se pode construí-lo depósito aí...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Non se pode construí-la estación de autobús...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Non se pode construí-la estacion de camións...
+STR_180A_ROAD_CONSTRUCTION :Construcción de Estrada
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Construír unha sección de estrada
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Construír depósito de vehículos de estrada (para construír e dar servicio os vehículos de estrada)
+STR_180D_BUILD_BUS_STATION :{BLACK}Construír estación de autobús
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Construír bahía de carga de camións
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Construír ponte de estrada
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Construír túnel de estrada
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Intecambiar construír/eliminar para construír estradas
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Seleciona-la orientación do depósito de vehículos de estrada
+STR_1814_ROAD :Estrada
+STR_1815_ROAD_WITH_STREETLIGHTS :Estrada con iluminación
+STR_1816_TREE_LINED_ROAD :Estrada con árbores
+STR_1817_ROAD_VEHICLE_DEPOT :Depósito de vehículos de estrada
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :Paso a nivel para estrada/ferrocarril
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Cidades
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Debes demole-lo edificio primeiro
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}Poboación: {ORANGE}{COMMA}{BLACK} Casas: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Renomear cidade
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Non se pode renomea-la cidade...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN}: a autoridade local négase a permitilo
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Nomes de cidades - pincha no nome para centra-la vista principal na cidade
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centra-la vista principal na situación da cidade
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Cambia-lo nome da cidade
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Pasaxeiros último mes: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Correo último mes: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Bloque alto de oficinas
+STR_2010_OFFICE_BLOCK :Bloque de oficinas
+STR_2011_SMALL_BLOCK_OF_FLATS :Bloque pequeno de apartamentos
+STR_2012_CHURCH :Igrexa
+STR_2013_LARGE_OFFICE_BLOCK :Bloque grande de oficinas
+STR_2014_TOWN_HOUSES :Casas de cidade
+STR_2015_HOTEL :Hotel
+STR_2016_STATUE :Estatua
+STR_2017_FOUNTAIN :Fonte
+STR_2018_PARK :Parque
+STR_2019_OFFICE_BLOCK :Bloque de Oficinas
+STR_201A_SHOPS_AND_OFFICES :Tendas e oficinas
+STR_201B_MODERN_OFFICE_BUILDING :Edifcio moderno de oficinas
+STR_201C_WAREHOUSE :Almacén
+STR_201D_OFFICE_BLOCK :Bloque de oficinas
+STR_201E_STADIUM :Estadio
+STR_201F_OLD_HOUSES :Casas antigas
+STR_2020_LOCAL_AUTHORITY :{BLACK}Aut. Local
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Mostra-la información sobre a autoridade local
+STR_2022_LOCAL_AUTHORITY :{WHITE}Autoridade local de {TOWN}
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Puntuacións das compañías de transporte:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Subsidios
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Sibsidios en oferta para sevicios que transporten:
+STR_2027_FROM_TO :{ORANGE}{STRING} dende {STRING} ata {STRING}
+STR_2028_BY :{YELLOW} (antes de {DATE_SHORT})
+STR_202A_NONE :{ORANGE}Ningún
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Servicios que xa teñen subsidio:
+STR_202C_FROM_TO :{ORANGE}{STRING} dende {STATION} ata {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, ata {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}Oferta de subsidio esgotada:{}{}{STRING} dende {STRING} ata {STRING} non será subsidiada.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Subsidio retirado:{}{}O servicio de transporte de {STRING} dende {STATION} ata {STATION} xa non ten subsidio.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}¡Oferta de subsidio:{}{}O primeiro servicio de transporte de {STRING} dende {STRING} ata {STRING} será subsidiado pola autoridade local!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}¡Subsidio concedido a {COMPANY}!{}{}Polo servicio de transporte de {STRING} dende {STATION} ata {STATION} pagarase un 50% máis durante o próximo ano!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}¡Subsidio concedido a {COMPANY}!{}{}Polo servicio de transporte de {STRING} dende {STATION} ata {STATION} pagarase o dobre durante o próximo ano!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}¡Subsidio concedido a {COMPANY}!{}{}Polo servicio de transporte de {STRING} dende {STATION} ata {STATION} pagarase o triple durante o próximo ano!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}¡Subsidio concedido a {COMPANY}!{}{}Polo servicio de transporte de {STRING} dende {STATION} ata {STATION} pagarase o cuádruple durante o próximo ano!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}A autoridade local de {TOWN} négase a permiti-la construcción doutro aeroporto
+STR_2036_COTTAGES :Casiñas de campo
+STR_2037_HOUSES :Casas
+STR_2038_FLATS :Apartamentos
+STR_2039_TALL_OFFICE_BLOCK :Bloque alto de oficinas
+STR_203A_SHOPS_AND_OFFICES :Tendas e oficinas
+STR_203B_SHOPS_AND_OFFICES :Tendas e oficinas
+STR_203C_THEATER :Teatro
+STR_203D_STADIUM :Estadio
+STR_203E_OFFICES :Oficinas
+STR_203F_HOUSES :Casas
+STR_2040_CINEMA :Cine
+STR_2041_SHOPPING_MALL :Centro comercial
+STR_2042_DO_IT :{BLACK}Faino
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}Lista de cousas para facer nesta cidade - pincha nun item para máis detalles
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Executa-la acción marcada na lista superior
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Accións dispoñibles:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Campaña publicitaria pequena
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Campaña publicitaria mediana
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Gan campaña publicitaria
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Subvenciona-la reconstrucción das estradas da cidade
+STR_204A_BUILD_STATUE_OF_COMPANY :Construír unha estatua do propietario da compañía
+STR_204B_FUND_NEW_BUILDINGS :Subvencionar novos edificios
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Compra-los dereitos de transporte exclusivos
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Soborna-la autoridade local
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Iniciar unha campaña de publicidade pequena, para atraer máis pasaxeiros e mercadorías os teus servicios de transporte.{} Coste: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Iniciar unha campaña de publicidade mediana, para atraer máis pasaxeiros e mercadorías os teus servicios de transporte.{} Coste: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Iniciar unha gran campaña de publicidade, para atraer máis pasaxeiros e mercadorías os teus servicios de transporte.{} Coste: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} Subvenciona-la reconstrucción da rede de estradas urbanas. Provoca unha considerable interrupción no tráfico durante seis meses.{} Coste: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Construír unha estatua en honor a túa compañía.{} Coste: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Subvencina-la construcción de novos edificios comerciais na cidade.{} Coste: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Compra-los dereitos exclusivos de transporte na cidade durante 1 ano. A autoridade só permitirá que os pasaxeiros e as mercadorías usen as estacións da túa compañía.{} Coste: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Suborna-la autoridade local para mellora-la túa puntuación, co risco dunha gran penalización se o descobren.{} Cost: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}¡Caos no tráfico de {TOWN}!{}{}¡O programa de reconstrucción das estradas subvencionado por {COMPANY} trae 6 meses de miseria para os motoristas!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (en construcción)
+STR_2059_IGLOO :Iglú
+STR_205A_TEPEES :Tipis
+STR_205B_TEAPOT_HOUSE :Casa Tetera
+STR_205C_PIGGY_BANK :Banco Porquiño
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN}: {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Modifica-lo terreo
+STR_2800_PLANT_TREES :Plantar árbores
+STR_2801_PLACE_SIGN :Colocar sinal
+STR_2802_TREES :{WHITE}Ãrbores
+STR_2803_TREE_ALREADY_HERE :{WHITE}...Xa hai unha árbore aí
+STR_2804_SITE_UNSUITABLE :{WHITE}...emprazamento inadecuado
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Non se pode plantar unha árbore aí...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...demasiados sinais
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Non se pode situa-lo sinal aí...
+STR_280A_SIGN :Sinal
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Edita lo texto do sinal
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Non se pode cambia-lo nome do sinal...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Selecciona-lo tipo de árbore a plantar
+STR_280E_TREES :Ãrbores
+STR_280F_RAINFOREST :Selva tropical
+STR_2810_CACTUS_PLANTS :Plantas cactus
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Config. da Estación
+STR_3001_AIRPORT_SELECTION :{WHITE}Selección de aeroporto
+STR_3002_ORIENTATION :{BLACK}Orientación
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Lonxitude da plataforma
+STR_3004_PLATFORM_LENGTH :{BLACK}Número de vías
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Demasiado cerca doutra estación de ferrocarril
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Xunta máis dunha estación/área de carga existente
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}Hay demasiadas estacións/áreas de carga nesta cidade
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}Hay demasiadas estacións/áreas de carga
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Demasiadas paradas de bus
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}Demasiadas estacions de camións
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Demasiado cerca doutra estación ou área de carga
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Debes demole-la estación de ferrocarril primeiro
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Demasiado cerca doutro aeroporto
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Debes demole-lo aeroporto primeiro
+
+STR_3030_RENAME_STATION_LOADING :Renomear estación/área de carga
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Non se pode renomea-la estación...
+STR_3032_RATINGS :{BLACK}Puntuacións:
+STR_3033_ACCEPTS :{BLACK}Acepta
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}Puntuación local para o servicio de transporte:
+
+############ range for rating starts
+STR_3035_APPALLING :Pésima
+STR_3036_VERY_POOR :Moi Pobre
+STR_3037_POOR :Pobre
+STR_3038_MEDIOCRE :Mediocre
+STR_3039_GOOD :Boa
+STR_303A_VERY_GOOD :Moi Boa
+STR_303B_EXCELLENT :Excelente
+STR_303C_OUTSTANDING :Excepcional
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} xa non acepta {STRING}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} xa non acepta {STRING} ou {STRING}
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} agora acepta {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} agora acepta {STRING} e {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Orientación da Estación
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Orientación da Estación
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Debes demole-la estación de autobús primeiro
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Debes demole-la estación de camións primeiro
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Estacións
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Ningún -
+STR_304B_SITE_UNSUITABLE :{WHITE}...emprazamento inadecuado
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Demasiado cerca doutro peirao
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Debes demole-lo peirao primeiro
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Selecciona-la orientación da estación de ferrocarril
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Selecciona-lo número de platafomas da estación de ferrocarrilrailroad station
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Selecciona-la lonxitude da estación de ferrocarril
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Selecciona-la orientación da estación de autobús
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Selecciona-la orientación da bahía de carga de camións
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Centra-la vista principal na situación da estación
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Mostra-las puntuacións da estación
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Cambia-lo nome da estación
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Mostra-la lista da carga aceptada
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Nomes das estacións - pinga nun nome para centra-la vista principal na estación
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Selecciona o tamaño/tipo de aeroporto
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :Estación de ferrocarril
+STR_305F_AIRCRAFT_HANGAR :Hangar de aeronaves
+STR_3060_AIRPORT :Aeroporto
+STR_3061_TRUCK_LOADING_AREA :Ãrea de carga de camións
+STR_3062_BUS_STATION :Estación de autobús
+STR_3063_SHIP_DOCK :Peirao para barco
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Resalta-la área de cobertura do sitio proposto
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Non resalta-la área de cobertura do sitio proposto
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Resaltar área de cobertura
+STR_3068_DOCK :{WHITE}Peirao
+STR_3069_BUOY :Boia
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...boia no camiño
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...a estación ocupa demasiado
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...estacións non uniformes deshabilitadas
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Presiona CTRL para seleccionar máis dun ítem
+
+STR_UNDEFINED :(cadea indefinida)
+STR_STAT_CLASS_DFLT :Estación por defecto
+STR_STAT_CLASS_WAYP :Puntos de ruta
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Orient. do Depósito de Barcos
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...debes construí-lo na auga
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Non se pode construí-lo depósito de barcos aí...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Selecciona-la orientación do depósito de barcos
+STR_3804_WATER :Auga
+STR_3805_COAST_OR_RIVERBANK :Costa ou beiramar
+STR_3806_SHIP_DEPOT :Depósito de barcos
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...Non se pode construír na auga
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Grabar Partida
+STR_4001_LOAD_GAME :{WHITE}Cargar Partida
+STR_4002_SAVE :{BLACK}Grabar
+STR_4003_DELETE :{BLACK}Borrar
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} megabytes libres
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}No se pode lee-la unidade
+STR_4007_GAME_SAVE_FAILED :{WHITE}Grabación da partida fallida
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Non se pode borra-lo arquivo
+STR_4009_GAME_LOAD_FAILED :{WHITE}Carga da partida fallida
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}Lista de unidades, directorios e arquivos de partida
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Nome seleccionado actualmente para o arquivo
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Borra-lo arquivo que está seleccionado
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Salva-la partida actual, usando o nome seleccionado
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Selecciona o tipo de partida a empezar
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Selecciona escenario(verde), partida pre-consigurada (azul), ou partida aleatoria
+STR_4010_GENERATE_RANDOM_NEW_GAME :Xerar unha nova partida aleatoriamente
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} en camiño
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :Mina de Carbón
+STR_4803_POWER_STATION :Estación Enerxética
+STR_4804_SAWMILL :Serradeiro
+STR_4805_FOREST :Bosque
+STR_4806_OIL_REFINERY :Ref. de Petróleo
+STR_4807_OIL_RIG :Torre Petrolífera
+STR_4808_FACTORY :Factoría
+STR_4809_PRINTING_WORKS :Imprenta
+STR_480A_STEEL_MILL :Siderúrxica
+STR_480B_FARM :Granxa
+STR_480C_COPPER_ORE_MINE :Mina de Mineral de Cobre
+STR_480D_OIL_WELLS :Pozo Petrolífero
+STR_480E_BANK :Banco
+STR_480F_FOOD_PROCESSING_PLANT :Planta de Proc. de Comida
+STR_4810_PAPER_MILL :Fábrica de Papel
+STR_4811_GOLD_MINE :Mina de Ouro
+STR_4812_BANK :Banco
+STR_4813_DIAMOND_MINE :Mina de Diamantes
+STR_4814_IRON_ORE_MINE :Mina de Hematita
+STR_4815_FRUIT_PLANTATION :Plantación de Froita
+STR_4816_RUBBER_PLANTATION :Plant. de Ãrbores de Caucho
+STR_4817_WATER_SUPPLY :Acuífero
+STR_4818_WATER_TOWER :Torre de Auga
+STR_4819_FACTORY :Factoría
+STR_481A_FARM :Granxa
+STR_481B_LUMBER_MILL :Frábrica de Madeiros
+STR_481C_COTTON_CANDY_FOREST :Bosque de Algodón de Azucre
+STR_481D_CANDY_FACTORY :Fábrica de Caramelos
+STR_481E_BATTERY_FARM :Granxa de Baterías
+STR_481F_COLA_WELLS :Fontes de Cola
+STR_4820_TOY_SHOP :Xoguetería
+STR_4821_TOY_FACTORY :Fábrica de Xoguetes
+STR_4822_PLASTIC_FOUNTAINS :Fontes de Plástico
+STR_4823_FIZZY_DRINK_FACTORY :Fábrica de Bebidas Gaseosas
+STR_4824_BUBBLE_GENERATOR :Xerador de Burbullas
+STR_4825_TOFFEE_QUARRY :Canteira de Toffee
+STR_4826_SUGAR_MINE :Mina de Azucre
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Require: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Require: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Require: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Producción no último mes:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% transportado)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centra-la vista principal na situación da industria
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}¡Nova {STRING} en construcción cerca de {TOWN}!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}¡Nova {STRING} cerca de {TOWN}!
+STR_482F_COST :{BLACK}Coste: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Non se pode construír ese tipo de industria aí...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...o bosqur só se pode plantar sobre a liña de neve
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}¡{INDUSTRY} anuncia o seu peche inminente!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}¡Problemas de suministro en {INDUSTRY} provocan o seu peche inminente!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}¡A falta de árbores provoca que {INDUSTRY} anuncie o peche inminente!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}¡{INDUSTRY} incrementa a súa producción!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}¡Nova veta de carbón atopada en {INDUSTRY}!{}¡Espérase que a producción dóbrese!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}¡Novas reservas de petróleo atopadas en {INDUSTRY}!{}¡Espérase que a producción dóbrese!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}¡Espérase que a producción se dobre en {INDUSTRY} debido a métodos de cultivo mellorados!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}{INDUSTRY} baixa a producción nun 50%
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}¡Infestación de insectos causa estragos en {INDUSTRY}!{}A producción baixa un 50%
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...só se pode emprazar cerca dos bordes do mapa
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}¡A producción de {STRING} en {INDUSTRY} sube un {COMMA}%!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}¡A producción de {STRING} en {INDUSTRY} baixa un {COMMA}%!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Hai un tren no túnel
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}HAi un vehículo de estrada no túnel
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Hai outro túnel no camiño
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Non se pode excava-lo terreo no outro lado do túnel
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Debes demole-lo túnel primeiro
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Debes demole-la ponte primeiro
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Non pode empezar e rematar na mesma posición
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Necesítase terreo nivelado ou auga baixo a ponte
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}O inicio e o final deben estar aliñados
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Emprazamento inadecuado para a entrada do túnel
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Colgante, Aceiro
+STR_500F_GIRDER_STEEL :Vigas, Aceiro
+STR_5010_CANTILEVER_STEEL :Voladizo, Aceiro
+STR_5011_SUSPENSION_CONCRETE :Colgante, Cemento
+STR_5012_WOODEN :Madeira
+STR_5013_CONCRETE :Cemento
+STR_5014_TUBULAR_STEEL :Tubular, Aceiro
+STR_BRIDGE_TUBULAR_SILICON :Tubular, Silicona
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}No se pode construí-la ponte aí...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Non se pode construí-lo túnel ahí...
+STR_5017_RAILROAD_TUNNEL :Túnel de ferrocarril
+STR_5018_ROAD_TUNNEL :Túnel de estrada
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Ponte colgante de aceiro para ferrocarrís
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Ponte de vigas de aceiro para ferrocarrís
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Ponte voladiza de aceiro para ferrocarrís
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Ponte colgante de cemento reforzado para ferrocarrís
+STR_501F_WOODEN_RAIL_BRIDGE :Ponte de madeira para ferrocarrís
+STR_5020_CONCRETE_RAIL_BRIDGE :Ponte de cemento para ferrocarrís
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Ponte colgante de aceiro para estradas
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Ponte de vigas de aceiro para estradas
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Ponte voladiza de aceiro para estradas
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Ponte colgante de cemento reforzado para estradas
+STR_5025_WOODEN_ROAD_BRIDGE :Ponte de madeira para estradas
+STR_5026_CONCRETE_ROAD_BRIDGE :Ponte de cemento para estradas
+STR_5027_TUBULAR_RAIL_BRIDGE :Ponte tubular para ferrocarrís
+STR_5028_TUBULAR_ROAD_BRIDGE :Ponte tubular para estradas
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Hai un obxecto no camiño
+STR_5801_TRANSMITTER :Transmisor
+STR_5802_LIGHTHOUSE :Faro
+STR_5803_COMPANY_HEADQUARTERS :Cuartel Xeral de Compañía
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...hai un cuartel xeral no camiño
+STR_5805_COMPANY_OWNED_LAND :Terreo propiedade dunha compañía
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Non se pode compra-la área de terreo...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...¡xa é da túa propiedade!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Sen Nome
+STR_SV_TRAIN_NAME :Tren {COMMA}
+STR_SV_ROADVEH_NAME :Vehículo de estrada {COMMA}
+STR_SV_SHIP_NAME :Barco {COMMA}
+STR_SV_AIRCRAFT_NAME :Aeronave {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :{STRING} Norte
+STR_SV_STNAME_SOUTH :{STRING} Sur
+STR_SV_STNAME_EAST :{STRING} Este
+STR_SV_STNAME_WEST :{STRING} Oeste
+STR_SV_STNAME_CENTRAL :{STRING} Central
+STR_SV_STNAME_TRANSFER :{STRING} Transferencia
+STR_SV_STNAME_HALT :{STRING} Alto
+STR_SV_STNAME_VALLEY :{STRING} Val
+STR_SV_STNAME_HEIGHTS :{STRING} Lombas
+STR_SV_STNAME_WOODS :{STRING} Bosques
+STR_SV_STNAME_LAKESIDE :{STRING} Ribeira de lago
+STR_SV_STNAME_EXCHANGE :{STRING} Cambio
+STR_SV_STNAME_AIRPORT :Aeroporto de {STRING}
+STR_SV_STNAME_OILFIELD :{STRING} Campo de petróleo
+STR_SV_STNAME_MINES :{STRING} Minas
+STR_SV_STNAME_DOCKS :Peirao de {STRING}
+STR_SV_STNAME_BUOY_1 :{STRING} Boia 1
+STR_SV_STNAME_BUOY_2 :{STRING} Boia 2
+STR_SV_STNAME_BUOY_3 :{STRING} Boia 3
+STR_SV_STNAME_BUOY_4 :{STRING} Boia 4
+STR_SV_STNAME_BUOY_5 :{STRING} Boia 5
+STR_SV_STNAME_BUOY_6 :{STRING} Boia 6
+STR_SV_STNAME_BUOY_7 :{STRING} Boia 7
+STR_SV_STNAME_BUOY_8 :{STRING} Boia 8
+STR_SV_STNAME_BUOY_9 :{STRING} Boia 9
+STR_SV_STNAME_ANNEXE :{STRING} Anexo
+STR_SV_STNAME_SIDINGS :{STRING} Apartadeiro
+STR_SV_STNAME_BRANCH :{STRING} Rama
+STR_SV_STNAME_UPPER :Superior {STRING}
+STR_SV_STNAME_LOWER :Inferior {STRING}
+STR_SV_STNAME_HELIPORT :{STRING} Heliporto
+STR_SV_STNAME_FOREST :{STRING} Bosque
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Nivel de Dificultade
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Grabar
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Fácil
+STR_6802_MEDIUM :{BLACK}Medio
+STR_6803_HARD :{BLACK}Difícil
+STR_6804_CUSTOM :{BLACK}Persoal
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}Nº máximo de oponentes: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Data de comezo dos oponentes: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}Nº de cidades: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}Nº de industrias: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Crédito máximo inicial: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Taxa de interés inicial: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Coste de mantemento dos vehículos: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Velocidade de construcción dos oponentes: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Intelixencia dos oponentes: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Averías nos vehículos: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Multiplicador de subsidio: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Costes de construcción: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Tipo de Terreo: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Cantidade de mares/lagos: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Economía: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Inverti-lo sentido do tren: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Desastres: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Actitude do consello sobre a reestructuración de áreas: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :Ningún
+STR_6816_LOW :Baixo
+STR_6817_NORMAL :Normal
+STR_6818_HIGH :Alto
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Moi Lento
+STR_681C_SLOW :Lento
+STR_681D_MEDIUM :Medio
+STR_681E_FAST :Rápido
+STR_681F_VERY_FAST :Moi Rápido
+STR_VERY_LOW :Moi Baixo
+STR_6820_LOW :Baixo
+STR_6821_MEDIUM :Medio
+STR_6822_HIGH :Alto
+STR_6823_NONE :Ningún
+STR_6824_REDUCED :Reducido
+STR_6825_NORMAL :Normal
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Moi chan
+STR_682B_FLAT :Chan
+STR_682C_HILLY :Accidentado
+STR_682D_MOUNTAINOUS :Montañoso
+STR_682E_STEADY :Estable
+STR_682F_FLUCTUATING :Variable
+STR_6830_IMMEDIATE :Inmediato
+STR_6831_3_MONTHS_AFTER_PLAYER :3 meses despois do xogador
+STR_6832_6_MONTHS_AFTER_PLAYER :6 meses despois do xogador
+STR_6833_9_MONTHS_AFTER_PLAYER :9 meses despois do xogador
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :Ó final da liña, e nas estacións
+STR_6835_AT_END_OF_LINE_ONLY :Só ó final da liña
+STR_6836_OFF :Off
+STR_6837_ON :On
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Mostra-la lista das mellores puntuacións
+STR_6839_PERMISSIVE :Permisivo
+STR_683A_TOLERANT :Tolerante
+STR_683B_HOSTILE :Hostil
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Xogador {COMMA})
+STR_7004_NEW_FACE :{BLACK}Nova Cara
+STR_7005_COLOR_SCHEME :{BLACK}Esquema de Cor
+STR_7006_COLOR_SCHEME :{GOLD}Esquema de Cor:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Novo Esquema de Cor
+STR_7008_COMPANY_NAME :{BLACK}Nome Compañía
+STR_7009_PRESIDENT_NAME :{BLACK}Nome Presidente
+STR_700A_COMPANY_NAME :Nome da Compañía
+STR_700B_PRESIDENT_S_NAME :Nome Do Presidente
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Non se pode cambia-lo nome da compañía...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Non se pode cambia-lo nome do presidente...
+STR_700E_FINANCES :{WHITE}{COMPANY} Finanzas {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Gastos/Ingresos
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Construccción
+STR_7012_NEW_VEHICLES :{GOLD}Novos Vehículos
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Mantemento dos Trens
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Mantemento dos Vehículos
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Mantemendo das Aeronaves
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Mantemento dos Barcos
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Mantemento das Propiedades
+STR_7018_TRAIN_INCOME :{GOLD}Ingresos dos Trens
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Ingresos dos Vehículos
+STR_701A_AIRCRAFT_INCOME :{GOLD}Ingresos das Aeronaves
+STR_701B_SHIP_INCOME :{GOLD}Ingresos dos Barcos
+STR_701C_LOAN_INTEREST :{GOLD}Interese do Préstamo
+STR_701D_OTHER :{GOLD}Outros
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Total:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Gráfico de Ingresos
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Gráfica de Beneficios Operativos
+STR_7026_BANK_BALANCE :{WHITE}Balance do Banco
+STR_7027_LOAN :{WHITE}Préstamo
+STR_MAX_LOAN :{WHITE}Préstamo Max: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}Solicitar {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Devolver {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...O tamaño máximo do préstamo permitido e de {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Non se pode solicitar máis diñeiro...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...non queda préstamo a pagar
+STR_702E_REQUIRED :{WHITE}...necesitas {CURRENCY}
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Non se pode paga-lo préstamo...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Selecciona-la nova cara do presidente
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Cambia-la libra dos vehículos da compañía
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Cambia-lo nome do presidente
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Cambia-lo nome da compañía
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Pincha no novo esquema de cor
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Incrementa-lo préstamo
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Pagar parte do préstamo
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(Presidente)
+STR_7038_INAUGURATED :{GOLD}Inaugurado: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Vehículos:
+STR_TRAINS :{WHITE}{COMMA} tren{P "" s}
+STR_ROAD_VEHICLES :{WHITE}{COMMA} vehículo{P "" s} de estrada
+STR_AIRCRAFT :{WHITE}Aeronaves {COMMA}
+STR_SHIPS :{WHITE}{COMMA} barco{P "" s}
+STR_7042_NONE :{WHITE}Ningún
+STR_7043_FACE_SELECTION :{WHITE}Selecció de cara
+STR_7044_MALE :{BLACK}Home
+STR_7045_FEMALE :{BLACK}Muller
+STR_7046_NEW_FACE :{BLACK}Nova cara
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Cancela-la selección dunha nova cara
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Acepta-la selección da nova cara
+STR_7049_SELECT_MALE_FACES :{BLACK}Seleccionar caras masculinas
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Seleccionar caras femininas
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Xerar unha nova cara aleatoriamente
+STR_704C_KEY :{BLACK}Chave
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Mostra-la chave das gráficas
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Chave das gráficas da compañía
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Pincha aquí para amosar/ocultar a entrada da compañía na gráfica
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Unidades de carga transportadas
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Puntuación de rendemento da compañía (Máximo=1000)
+STR_7052_COMPANY_VALUES :{WHITE}Valor da Compañía
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Tabla da Liga de Compañías
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}¡Compañía de transporte en problemas!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} vai ser vendida ou declarada en bancarrota se non mellora o seu rendemento pronto!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(Presidente)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}¡Fusión de compañías de transporte!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} foi vendida a {COMPANY} por {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Buscamos unha compañía de transporte para adquiri-la nosa compañía{}{}¿Queres comprar {COMPANY} por {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}¡Bancarrota!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} foi pechada polos acreedores e vendéronse tódalas posesións!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}¡Lanzada unha nova compañía de transporte!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} comeza a construcción cerca de {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Non se pode compra-la compañía...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Taxas de Pagamento por Carga
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Días en tránsito
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Pagamento por transportar 10 unidades (ou 1.000 litros) de carga unha distancia de 20 cadros
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Amosar/ocultar gráfica para o tipo de carga
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Enxeñeiro
+STR_7067_TRAFFIC_MANAGER :Xestor de Tráfico
+STR_7068_TRANSPORT_COORDINATOR :Coordinador de Transporte
+STR_7069_ROUTE_SUPERVISOR :Supervisor de Ruta
+STR_706A_DIRECTOR :Director
+STR_706B_CHIEF_EXECUTIVE :Xefe Executivo
+STR_706C_CHAIRMAN :Director
+STR_706D_PRESIDENT :Presidente
+STR_706E_TYCOON :Magnate
+STR_706F_BUILD_HQ :{BLACK}Construír CX
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Construír/ver cuartel xeral da compañía
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Recontruí-lo cuartel xeral da compañía en calquer lugar cun coste do 1% do valor da compañía
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Non se pode construí-lo cuartel xeral...
+STR_7072_VIEW_HQ :{BLACK}Ve-lo CX
+STR_RELOCATE_HQ :{BLACK}Reposicionar CX
+STR_COMPANY_PASSWORD :{BLACK}Contrasinal
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Protexe a atúa compañía cun contrasinal para evitar que usuarios non autorizados se unan
+STR_SET_COMPANY_PASSWORD :Establece o contrasinal da compañía
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}¡Recesión Mundial!{}{}¡Os expertos en finanzas témense o peor a medida que a economía afúndese!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}¡Fin da Recesión!{}{}¡A mellora no comercio inspira confianza nas industrias a media que a economía reforzase!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Intercambiar entre fiestra grande/pequena
+STR_7076_COMPANY_VALUE :{GOLD}Valor da Compañía: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Comprar un 25% das accións da compañía
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Vender un 25% das accións da compañía
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Comprar un 25% das accións nesta compañía
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Vender un 25% das accións desta compañía
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Non se pode comprar un 25% das accións nesta compañía...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}Non se pode vender un 25% das accións desta compañía...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% propiedade de {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% propiedade de {COMPANY}{} {COMMA}% propiedade de {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} comprada por {COMPANY}!
+STR_7080_PROTECTED :{WHITE}Esta compañía todavía non comercia con accións...
+
+STR_LIVERY_STEAM :Máquina de Vapor
+STR_LIVERY_DIESEL :Máquina Diésel
+STR_LIVERY_ELECTRIC :Máquina Eléctrica
+STR_LIVERY_MONORAIL :Máquina Monorraíl
+STR_LIVERY_MAGLEV :Máquina Maglev
+STR_LIVERY_DMU :DMU
+STR_LIVERY_EMU :EMU
+STR_LIVERY_PASSENGER_WAGON_STEAM :Vagón De Pasaxeiros (Vapor)
+STR_LIVERY_PASSENGER_WAGON_DIESEL :Vagón De Pasaxeiros (Diésel)
+STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Vagón De Pasaxeiros (Eléctrico)
+STR_LIVERY_FREIGHT_WAGON :Vagón de Carga
+STR_LIVERY_BUS :Autobús
+STR_LIVERY_TRUCK :Camión
+STR_LIVERY_PASSENGER_SHIP :Barco de Pasaxeiros
+STR_LIVERY_FREIGHT_SHIP :Barco de Carga
+STR_LIVERY_HELICOPTER :Helicóptero
+STR_LIVERY_SMALL_PLANE :Aeronave Pequena
+STR_LIVERY_LARGE_PLANE :Aeronave Grande
+
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (Vapor)
+STR_8001_MJS_250_DIESEL :MJS 250 (Diesel)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut Diesel
+STR_8006_POWERNAUT_DIESEL :Powernaut Diesel
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (Vapor)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (Vapor)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (Vapor)
+STR_800A_SH_8P_STEAM :SH '8P' (Vapor)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (Diesel)
+STR_800C_DASH_DIESEL :'Dash' (Diesel)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (Diesel)
+STR_800E_UU_37_DIESEL :UU '37' (Diesel)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (Diesel)
+STR_8010_CS_4000_DIESEL :CS 4000 (Diesel)
+STR_8011_CS_2400_DIESEL :CS 2400 (Diesel)
+STR_8012_CENTENNIAL_DIESEL :Centennial (Diesel)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (Diesel)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (Diesel)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (Diesel)
+STR_8016_SH_125_DIESEL :SH '125' (Diesel)
+STR_8017_SH_30_ELECTRIC :SH '30' (Eléctrica)
+STR_8018_SH_40_ELECTRIC :SH '40' (Eléctrica)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (Eléctrica)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (Eléctrica)
+STR_801B_PASSENGER_CAR :Coche de Pasaxeiros
+STR_801C_MAIL_VAN :Furgón de Correo
+STR_801D_COAL_CAR :Coche de Carbón
+STR_801E_OIL_TANKER :Tanque de Petróleo
+STR_801F_LIVESTOCK_VAN :Furgón de Gando
+STR_8020_GOODS_VAN :Furgón de Mercadorías
+STR_8021_GRAIN_HOPPER :Tolva de Gran
+STR_8022_WOOD_TRUCK :Vagón de Madeira
+STR_8023_IRON_ORE_HOPPER :Tolva de Hematita
+STR_8024_STEEL_TRUCK :Vagón de Aceiro
+STR_8025_ARMORED_VAN :Furgón Blindado
+STR_8026_FOOD_VAN :Furgón de Comida
+STR_8027_PAPER_TRUCK :Vagón de Papel
+STR_8028_COPPER_ORE_HOPPER :Tolva de Mineral de Cobre
+STR_8029_WATER_TANKER :Tanque de Auga
+STR_802A_FRUIT_TRUCK :Vagón de Froitas
+STR_802B_RUBBER_TRUCK :Vagón de Caucho
+STR_802C_SUGAR_TRUCK :Vagón de Azucre
+STR_802D_COTTON_CANDY_HOPPER :Tolva de Algodón de Azucre
+STR_802E_TOFFEE_HOPPER :Tolva de Toffee
+STR_802F_BUBBLE_VAN :Furgón de Burbullas
+STR_8030_COLA_TANKER :Tanque de Cola
+STR_8031_CANDY_VAN :Furgón de Caramelos
+STR_8032_TOY_VAN :Furgón de Xoguetes
+STR_8033_BATTERY_TRUCK :Vagón de Baterías
+STR_8034_FIZZY_DRINK_TRUCK :Vagón de Bebidas Gaseosas
+STR_8035_PLASTIC_TRUCK :Vagón de Plástico
+STR_8036_X2001_ELECTRIC :'X2001' (Eléctrica)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Eléctrica)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :Coche de Pasaxeiros
+STR_803A_MAIL_VAN :Furgón de Correo
+STR_803B_COAL_CAR :Coche de Carbón
+STR_803C_OIL_TANKER :Tanque de Petróleo
+STR_803D_LIVESTOCK_VAN :Furgón de Gando
+STR_803E_GOODS_VAN :Furgón de Mercadorías
+STR_803F_GRAIN_HOPPER :Tolva de Gran
+STR_8040_WOOD_TRUCK :Vagón de Madeira
+STR_8041_IRON_ORE_HOPPER :Tolva de Hematita
+STR_8042_STEEL_TRUCK :Vagón de Aceiro
+STR_8043_ARMORED_VAN :Furgón Blindado
+STR_8044_FOOD_VAN :Furgón de Comida
+STR_8045_PAPER_TRUCK :Vagón de Papel
+STR_8046_COPPER_ORE_HOPPER :Tolva de Mineral de Cobre
+STR_8047_WATER_TANKER :Tanque de Auga
+STR_8048_FRUIT_TRUCK :Vagón de Froitas
+STR_8049_RUBBER_TRUCK :Vagón de Caucho
+STR_804A_SUGAR_TRUCK :Vagón de Azucre
+STR_804B_COTTON_CANDY_HOPPER :Tolva de Algodón de Azucre
+STR_804C_TOFFEE_HOPPER :Tolva de Toffee
+STR_804D_BUBBLE_VAN :Furgón de Burbullas
+STR_804E_COLA_TANKER :Tanque de Cola
+STR_804F_CANDY_VAN :Furgón de Caramelos
+STR_8050_TOY_VAN :Furgón de Xoguetes
+STR_8051_BATTERY_TRUCK :Vagón de Baterías
+STR_8052_FIZZY_DRINK_TRUCK :Vagón de Bebidas Gaseosas
+STR_8053_PLASTIC_TRUCK :Vagón de Plástico
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (Eléctrica)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (Eléctrica)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (Eléctrica)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (Eléctrica)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :Coche de Pasaxeiros
+STR_805A_MAIL_VAN :Furgón de Correo
+STR_805B_COAL_CAR :Coche de Carbón
+STR_805C_OIL_TANKER :Tanque de Petróleo
+STR_805D_LIVESTOCK_VAN :Furgón de Gando
+STR_805E_GOODS_VAN :Furgón de Mercadorías
+STR_805F_GRAIN_HOPPER :Tolva de Gran
+STR_8060_WOOD_TRUCK :Vagón de Madeira
+STR_8061_IRON_ORE_HOPPER :Tolva de Hematita
+STR_8062_STEEL_TRUCK :Vagón de Aceiro
+STR_8063_ARMORED_VAN :Furgón Blindado
+STR_8064_FOOD_VAN :Furgón de Comida
+STR_8065_PAPER_TRUCK :Vagón de Papel
+STR_8066_COPPER_ORE_HOPPER :Tolva de Mineral de Cobre
+STR_8067_WATER_TANKER :Tanque de Auga
+STR_8068_FRUIT_TRUCK :Vagón de Froitas
+STR_8069_RUBBER_TRUCK :Vagón de Caucho
+STR_806A_SUGAR_TRUCK :Vagón de Azucre
+STR_806B_COTTON_CANDY_HOPPER :Tolva de Algodón de Azucre
+STR_806C_TOFFEE_HOPPER :Tolva de Toffee
+STR_806D_BUBBLE_VAN :Furgón de Burbullas
+STR_806E_COLA_TANKER :Tanque de Cola
+STR_806F_CANDY_VAN :Furgón de Caramelos
+STR_8070_TOY_VAN :Furgón de Xoguetes
+STR_8071_BATTERY_TRUCK :Vagón de Baterías
+STR_8072_FIZZY_DRINK_TRUCK :Vagón de Bebidas Gaseosas
+STR_8073_PLASTIC_TRUCK :Vagón de Plástico
+STR_8074_MPS_REGAL_BUS :Autobús Real MPS
+STR_8075_HEREFORD_LEOPARD_BUS :Autobús Leopardo Hereford
+STR_8076_FOSTER_BUS :Autobús Foster
+STR_8077_FOSTER_MKII_SUPERBUS :Superautobús Foster MkII
+STR_8078_PLODDYPHUT_MKI_BUS :Autobús Ploddyphut MkI
+STR_8079_PLODDYPHUT_MKII_BUS :Autobús Ploddyphut MkII
+STR_807A_PLODDYPHUT_MKIII_BUS :Autobús Ploddyphut MkIII
+STR_807B_BALOGH_COAL_TRUCK :Camión de Carbón Balogh
+STR_807C_UHL_COAL_TRUCK :Camión de Carbón Uhl
+STR_807D_DW_COAL_TRUCK :Camión de Carbón DW
+STR_807E_MPS_MAIL_TRUCK :Camión de Correo MPS
+STR_807F_REYNARD_MAIL_TRUCK :Camión de Correo Reynard
+STR_8080_PERRY_MAIL_TRUCK :Camión de Correo Perry
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :Camión de Correo MightyMover
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Camión de Correo Powernaught
+STR_8083_WIZZOWOW_MAIL_TRUCK :Camión de Correo Wizzowow
+STR_8084_WITCOMBE_OIL_TANKER :Tanque de Petróleo Witcombe
+STR_8085_FOSTER_OIL_TANKER :Tanque de Petróleo Foster
+STR_8086_PERRY_OIL_TANKER :Tanque de Petróleo Perry
+STR_8087_TALBOTT_LIVESTOCK_VAN :Furgón de Gando Talbott
+STR_8088_UHL_LIVESTOCK_VAN :Furgón de Gando Uhl
+STR_8089_FOSTER_LIVESTOCK_VAN :Furgón de Gando Foster
+STR_808A_BALOGH_GOODS_TRUCK :Camión de Mercadorías Balogh
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Camión de Mercadorías Craighead
+STR_808C_GOSS_GOODS_TRUCK :Camión de Mercadorías Goss
+STR_808D_HEREFORD_GRAIN_TRUCK :Camión de Gran Hereford
+STR_808E_THOMAS_GRAIN_TRUCK :Camión de Gran Thomas
+STR_808F_GOSS_GRAIN_TRUCK :Camión de Gran Goss
+STR_8090_WITCOMBE_WOOD_TRUCK :Camión de Madeira Witcombe
+STR_8091_FOSTER_WOOD_TRUCK :Camión de Madeira Foster
+STR_8092_MORELAND_WOOD_TRUCK :Camión de Madeira Moreland
+STR_8093_MPS_IRON_ORE_TRUCK :Camión de Hematita MPS
+STR_8094_UHL_IRON_ORE_TRUCK :Camión de Hematita Uhl
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Camión de Hematita Chippy
+STR_8096_BALOGH_STEEL_TRUCK :Camión de Aceiro Balogh
+STR_8097_UHL_STEEL_TRUCK :Camión de Aceiro Uhl
+STR_8098_KELLING_STEEL_TRUCK :Camión de Aceiro Kelling
+STR_8099_BALOGH_ARMORED_TRUCK :Camión Blindado Balogh
+STR_809A_UHL_ARMORED_TRUCK :Camión Blindado Uhl
+STR_809B_FOSTER_ARMORED_TRUCK :Camión Blindado Foster
+STR_809C_FOSTER_FOOD_VAN :Furgón de Comida Foster
+STR_809D_PERRY_FOOD_VAN :Furgón de Comida Perry
+STR_809E_CHIPPY_FOOD_VAN :Furgón de Comida Chippy
+STR_809F_UHL_PAPER_TRUCK :Camión de Papel Uhl
+STR_80A0_BALOGH_PAPER_TRUCK :Camión de Papel Balogh
+STR_80A1_MPS_PAPER_TRUCK :Camión de Papel MPS
+STR_80A2_MPS_COPPER_ORE_TRUCK :Camión de Mineral de Cobre MPS
+STR_80A3_UHL_COPPER_ORE_TRUCK :Camión de Mineral de Cobre Uhl
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Camión de Mineral de Cobre Goss
+STR_80A5_UHL_WATER_TANKER :Tanque de Auga Uhl
+STR_80A6_BALOGH_WATER_TANKER :Tanque de Auga Balogh
+STR_80A7_MPS_WATER_TANKER :Tanque de Auga MPS
+STR_80A8_BALOGH_FRUIT_TRUCK :Camión de Froita Balogh
+STR_80A9_UHL_FRUIT_TRUCK :Camión de Froita Uhl
+STR_80AA_KELLING_FRUIT_TRUCK :Camión de Froita Kelling
+STR_80AB_BALOGH_RUBBER_TRUCK :Camión de Caucho Balogh
+STR_80AC_UHL_RUBBER_TRUCK :Camión de Caucho Uhl
+STR_80AD_RMT_RUBBER_TRUCK :Camión de Caucho RMT
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :Camión de Azucre MightyMover
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Camión de Azucre Powernaught
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Camión de Azucre Wizzowow
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :Camión de Cola MightyMover
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Camión de Cola Powernaught
+STR_80B3_WIZZOWOW_COLA_TRUCK :Camión de Cola Wizzowow
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :Cam. Alg. Azucre MightyMover
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Cam. de Algodón de Azucre Powernaught
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Camión de Algodón de Azucre Wizzowow
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :Camión de Tofee MightyMover
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Camión de Tofee Powernaught
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Camión de Tofee Wizzowow
+STR_80BA_MIGHTYMOVER_TOY_VAN :Furgón de Xoguetes MightyMover
+STR_80BB_POWERNAUGHT_TOY_VAN :Furgón de Xoguetes Powernaught
+STR_80BC_WIZZOWOW_TOY_VAN :Furgón de Xoguetes Wizzowow
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :Cam. de Caramelos MightyMover
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Camión de Caramelos Powernaught
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Camión de Caramelos Wizzowow
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :Camión de Baterías MightyMover
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Camión de Baterías Powernaught
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Camión de Baterías Wizzowow
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :Cam. Beb. Gaseosas MightyMover
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Cam. de Bebidas Gaseosas Powernaught
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Cam. de Bebidas Gaseosas Wizzowow
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :Camión de Plástico MightyMover
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Camión de Plástico Powernaught
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Camión de Plástico Wizzowow
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :Camión de Burbullas MightyMover
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Camión de Burbullas Powernaught
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Camión de Burbullas Wizzowow
+STR_80CC_MPS_OIL_TANKER :Petroleiro MPS
+STR_80CD_CS_INC_OIL_TANKER :Petroleíro CS-Inc.
+STR_80CE_MPS_PASSENGER_FERRY :Barca de Pasaxeiros MPS
+STR_80CF_FFP_PASSENGER_FERRY :Barca de Pasaxeiros FFP
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Aerodeslizador Bakewell 300
+STR_80D1_CHUGGER_CHUG_PASSENGER :Barca Pasaxeiros Chugger-Chug
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Barca de Pasaxeiros Shivershake
+STR_80D3_YATE_CARGO_SHIP :Barco de Mercadorías Yate
+STR_80D4_BAKEWELL_CARGO_SHIP :Barco de Mercadorías Bakewell
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Barco Mercadorías Mightymover
+STR_80D6_POWERNAUT_CARGO_SHIP :Barco de Mercadorías Powernaut
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Helicóptero Tricario
+STR_80FE_GURU_X2_HELICOPTER :Helicóptero Guru X2
+STR_80FF_POWERNAUT_HELICOPTER :Helicóptero Powernaut
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Mensaxe dun fabricante de vehículos
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}Rematamo-lo deseño dun/dunha nov@ {STRING} - ¿Interésache probar este vehículo en exclusiva durante un ano, para comproba-lo seu rendemento antes de facelo dispoñible para todos?
+STR_8102_RAILROAD_LOCOMOTIVE :locomotora de ferrocarril
+STR_8103_ROAD_VEHICLE :vehículo de estrada
+STR_8104_AIRCRAFT :aeronave
+STR_8105_SHIP :barco
+STR_8106_MONORAIL_LOCOMOTIVE :locomotora de monoraíl
+STR_8107_MAGLEV_LOCOMOTIVE :locomotora de maglev
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}Depósito de Tren de {TOWN}
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Celebración cidadá . . .{}Chega o primeiro tren a {STATION}!
+STR_8802_DETAILS :{WHITE}{STRING} (Detalles)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Hai un tren no camiño
+STR_8804 :{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8806_GO_TO :Ir a {STATION}
+STR_8807_GO_TO_TRANSFER :Ir a {STATION} (Transferir e coller carga)
+STR_8808_GO_TO_UNLOAD :Ir a {STATION} (Descargar)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Ir a {STATION} (Transferir e sair valeiro)
+STR_880A_GO_TO_LOAD :Ir a {STATION} (Cargar)
+STR_880B_GO_TO_TRANSFER_LOAD :Ir a {STATION} (Transferir e esperar a cargar)
+STR_880C_GO_NON_STOP_TO :Ir sen parar a {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Ir sen parar a {STATION} (Transferir e coller carga)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Ir sen parar a {STATION} (Descargar)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Ir sen parar a {STATION} (Descargar e saír baleiro)
+STR_8810_GO_NON_STOP_TO_LOAD :Ir sen parar a {STATION} (Cargar)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Ir sen parar a {STATION} (Transferir e esperar a cargar)
+STR_GO_TO_TRAIN_DEPOT :Ir o Depósito De Trens de {TOWN}
+STR_SERVICE_AT_TRAIN_DEPOT :Face-lo servicio no Depósito de Trens de {TOWN}
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Ir sen paradas o Depósito de Trens de {TOWN}
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Face-lo servicio sen paradas no Depósito de Trens de {TOWN}
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}En camiño ó Depósito de {TOWN}
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}En camiño ó Depósito de {TOWN}, {VELOCITY}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE :{LTBLUE}Servicio no Depósito de {TOWN}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE_VEL :{LTBLUE}Servicio no Depósito de {TOWN}, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (Orde Inválida)
+
+STR_UNKNOWN_DESTINATION :destino descoñecido
+STR_8812_EMPTY :{LTBLUE}Valeiro
+STR_8813_FROM :{LTBLUE}{CARGO} de {STATION}
+STR_FROM_MULT :{LTBLUE}{CARGO} desde {STATION} (x{NUM})
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}O tren {COMMA} está a esperar no depósito
+STR_8815_NEW_VEHICLES :{BLACK}Novos Vehículos
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}O tren é demasiado longo
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Os trens só se poden alterar cando estean parados nunha estación
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} Trens
+
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Novos Vehículos de Ferrocarril
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Novos Vehículos de Monorraíl
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Novos Vehículos de Maglev
+
+STR_881F_BUILD_VEHICLE :{BLACK}Construír Vehículo
+STR_CLONE_ROAD_VEHICLE :{BLACK}Clonar Vehículo
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}Esto construíra unha copia do vehículo. CTRL+Click compartirá as ordes
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Esto construíra unha copia do vehículo. Pincha neste botón e despois nun vehículo dentro ou fora do depósito. CTRL+Click compartirá as ordes
+STR_CLONE_TRAIN :{BLACK}Clonar Tren
+STR_CLONE_TRAIN_INFO :{BLACK}Esto construirá unha copia do tren incluídos os vagóns. CTRL+Click compartirá as ordes
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}Esto construirá unha copia do tren incluídos os vagóns. Pincha neste botón e despois nun tren dentro ou fora do depósito. CTRL+Click compartirá as ordes
+STR_8820_RENAME :{BLACK}Renomear
+STR_8823_SKIP :{BLACK}Saltar
+STR_8824_DELETE :{BLACK}Borrar
+STR_8825_NON_STOP :{BLACK}Non Parar
+STR_8826_GO_TO :{BLACK}Ir a
+STR_8827_FULL_LOAD :{BLACK}Cargar
+STR_8828_UNLOAD :{BLACK}Descarga
+STR_8829_ORDERS :{WHITE}{VEHICLE} (Ordes)
+STR_882A_END_OF_ORDERS :{SETX 10}- - Fin das Ordes - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}Servicio
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}No se pode construí-lo vehículo de ferrocarril...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Construído: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Valor: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}Cargando / Descargando
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}O tren debe estar parado nun depósito
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}No se pode envía-lo tren o depósito...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Non haí espacio para máis ordes
+STR_8832_TOO_MANY_ORDERS :{WHITE}Demasiadas ordes
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}No se pode inserta-la nova orde...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Non se pode borrar esta orde...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Non se pode modificar esta orde...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}No se pode move-lo vehículo...
+STR_8838_N_A :N/D{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Non se pode vende-lo vehículo de ferrocarril...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}No se pode atopar unha ruta a un depósito local
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}No se pode para/arrinca-lo tren...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Intervalo de Servicio: {LTBLUE}{COMMA}days{BLACK} Último Servicio: {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Intervalo servicio: {LTBLUE}{COMMA}%{BLACK} Ult. Servicio: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Trens - pincha nun tren para información
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Construír novos trens (é necesarió un depósito)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Trens - pincha nun tren para información, arrastra o vehículo para engadi/remove-lo do tren
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Construír novo vehículo de ferrocarril
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Arrastra un vehículo do tren aquí para vendelo
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centra-la vista principal na situación do depósito de trens
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Lista de selección de vehículos para trens - pincha nun vehículo para máis información
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Construílo vehículo de ferrocarril seleccionado
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Renomea-lo tipo de vehículo de ferrocarril
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Tarea actual do tren - pincha aquí para parar/arrincar o tren
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Mostra-las ordes do tren
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centra-al vista principal la situación do tren
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Enviar tren ó depósito
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Obliga-lo tren a continuar sen esperar a que o sinal o indique
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Invertí-lo sentido do tren
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Mostra-los detalles do tren
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Incrementa-lo intervalo dos servicios
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Disminuí-lo intervalo dos servicios
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Mostra-los detalles das mercadorías transportadas
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Mostra-los detalles dos vehículos do tren
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Mostra-la capacidade de cada vehículo
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Mostra-la capacidade total do tren, dividida por tipos de carga
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Lista de Ordes - Pincha nunha orde para seleccionala
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}Salta-la orde actual, e comezar coa seguinte
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Borra-la orde seleccionada
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Facer que a orde seleccionada sexa de Non Parar
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Insertar unha nova orde despois da seleccionada, o insertar unha nova orde ó final da lista
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}A orde seleccionada forzará o vehículo a esperar ata que a carga estea completa
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}A orde seleccionada forzará o vehículo a descargar
+STR_SERVICE_HINT :{BLACK}saltar esta orde a non ser que sexa necesario o servicio
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}¡Nov@ {STRING} dispoñible!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Coste: {CURRENCY} Peso: {WEIGHT_S}{}Velocidade: {VELOCITY} Potencia: {POWER}{}Coste de Mantemento: {CURRENCY}/ano{}Capacidade: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}Roto
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}Idade: {LTBLUE}{STRING}{BLACK} Coste de Mantemento: {LTBLUE}{CURRENCY}/ano
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Peso: {LTBLUE}{WEIGHT_S} {BLACK}Potencia: {LTBLUE}{POWER}{BLACK} Velocidade Máx.: {LTBLUE}{VELOCITY}
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Peso: {LTBLUE}{WEIGHT_S} {BLACK}Potencia: {LTBLUE}{POWER}{BLACK} Vel. máx.: {LTBLUE}{VELOCITY} {BLACK}T.E. Máx.: {LTBLUE}{FORCE}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Beneficios este ano: {LTBLUE}{CURRENCY} (último ano: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}Fiabilidade: {LTBLUE}{COMMA}% {BLACK}Roturas dende o último servicio: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Parado
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Non se pode face-lo tren pasar unha sinal de perigo...
+STR_8863_CRASHED :{RED}¡Estrelado!
+
+STR_8865_NAME_TRAIN :{WHITE}Renomear tren
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}No se pode renomea-lo tren...
+STR_8867_NAME_TRAIN :{BLACK}Renomear tren
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}¡Accidente Ferroviario!{}{COMMA} mortos na explosión trala colisión
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}No se pode cambia-lo sentido do tren...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Renomea-lo tipo de vehículo de ferrocarril
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Non se pode renome-lo tipo de vehículo de ferrocarril...
+STR_886F_TRANSFER :{BLACK}Transferir
+
+STR_TRAIN_STOPPING :{RED}Parando
+STR_TRAIN_STOPPING_VEL :{RED}Parando, {VELOCITY}
+STR_TRAIN_NO_POWER :{RED}Sen enerxía
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Haí un vehículo de estrada no camiño
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} Vehículos de Estrada
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}Depósito de Vehículos de Estrada de {TOWN}
+STR_9004_NEW_VEHICLES :{BLACK}Novos Vehículos
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}Novos Vehículos de Estrada
+STR_9007_BUILD_VEHICLE :{BLACK}Construír Vehículo
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}No se pode construí-lo vehículo de estrada...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (Detalles)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}Idade: {LTBLUE}{STRING}{BLACK} Coste de Mantemento: {LTBLUE}{CURRENCY}/ano
+STR_900E_MAX_SPEED :{BLACK}Velocidade Máx.: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Beneficio este ano: {LTBLUE}{CURRENCY} (último ano: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}Fiabilidade: {LTBLUE}{COMMA}% {BLACK}Roturas dende o último servicio: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Construído: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Capacidade: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}...debe estar parado dentro dun depósito de vehículos de estrada
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Non se pode vende-lo vehículo de estrada...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}No se pode parar/arrincar o vehículo de estrada...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}O vehículo de estrada {COMMA} está a esperar no depósito
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}Diríxese o depósito de {TOWN}
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}Diríxese o depósito de {TOWN}, {VELOCITY}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE :{LTBLUE}Servicio no Depósito de {TOWN}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE_VEL :{LTBLUE}Servicio no Depósito de {TOWN}, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Non se pode envia-lo vehículo ó depósito de estrada...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}No se pode atopar unha ruta o depósito local
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Vehículos de estrada - pincha nun vehículo para máis información
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Construír novos vehículos de estrada (necesitas un depósito de vehículos de estrada)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Tarea actual do vehículo - pincha aquí para parar/arrincar o vehículo
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Mostra-las ordes do vehículo
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Centra-la vista principal na situación do vehículo
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Envia-lo vehículo ó depósito
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Forza-lo vehículo a da-la volta
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Mostra-los detalles do vehículo de estrada
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Vehículos - pincha nun vehículo para máis información
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Construír vehículo de estrada
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Arrastra un vehículo de estrada aquí para vendelo
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Centra-la vista principal na situación do depósito de vehículos de estrada
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Lista de selección de vehículos de estrada - pincha nun vehículo para máis información
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Construí-lo vehículo de estrada seleccionado
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}¡Novo vehículo de estrada dispoñible!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Coste: {CURRENCY}{}Velocidade: {VELOCITY}{}Coste de Mantemento: {CURRENCY}/ano{}Capacidade: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Renomear vehículo de estrada
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Non se pode renomea-lo vehículo de estrada...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Renomear vehículo de estrada
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Celebración cidadá . . .{}¡Chega o primeiro autobús a {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Celebración cidadá . . .{}¡Chega o primeiro camión a {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}¡Accidente de Tráfico!{}O conductor morre na explosión producida tra-la colisión cun tren
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}¡Accidente de Tráfico!{}{COMMA} morren na explosión producida tra-la colisión cun tren
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}No se pode dacer que o vehículo de volta...
+STR_9034_RENAME :{BLACK}Renomear
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Renomea-lo tipo de vehículo de estrada
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Renomea-lo tipo de vehículo de estrada
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Non se pode renomea-lo tipo de vehículo de estrada...
+STR_9038_GO_TO_ROADVEH_DEPOT :Ir ó Depósito de Vehículos de Estrada de {TOWN}
+STR_SERVICE_AT_ROADVEH_DEPOT :Servicio no Depósito de Vehículos de Estrada de {TOWN}
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Reaxustar vehículo para levar un tipo diferente de carga
+STR_REFIT_ROAD_VEHICLE :{BLACK}Reparar vehículo
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Reaxustar vehículo para levar o tipo de carga seleccionado
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Non se pode repara-lo vehículo
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Construcción de Peiraos
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Construcción de Peiraos
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Non se pode construí-lo peirao aí...
+STR_9803_SHIP_DEPOT :{WHITE}Depósito de Barcos de {TOWN}
+STR_9804_NEW_SHIPS :{BLACK}Novos Barcos
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} Barcos
+STR_9808_NEW_SHIPS :{WHITE}Novos Barcos
+STR_9809_BUILD_SHIP :{BLACK}Construír Barco
+STR_CLONE_SHIP :{BLACK}Clonar Barco
+STR_CLONE_SHIP_INFO :{BLACK}Esto construíra unha copia do barco. CTRL+Click compartirá as ordes
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}Esto construíra unha copia do barco. Pincha neste botón e despois nun barco dentro ou fora do depósito. CTRL+Click compartirá as ordes
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}O barco debe estar parado no depósito
+STR_980C_CAN_T_SELL_SHIP :{WHITE}No se pode vende-lo barco...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Non se construí-lo barco...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Hay un barco no camiño
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Detalles)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}Idade: {LTBLUE}{STRING}{BLACK} Coste de Mantemento: {LTBLUE}{CURRENCY}/ano
+STR_9813_MAX_SPEED :{BLACK}Velodidade Máx.: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Beneficio este ano: {LTBLUE}{CURRENCY} (último ano: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}Fiabilidade: {LTBLUE}{COMMA}% {BLACK}Roturas dende o último servicio: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Construído: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}Capacidade: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}Non se pode parar/arrincar o barco...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Non se pode envia-lo barco o depósito...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}No se pode atopar unha ruta ó depósito local
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}Diríxese o Depósito de Barcos de {TOWN}
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}Diríxese o Depósito de Barcos de {TOWN}, {VELOCITY}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE :{LTBLUE}Servicio no Depósito de Barcos de {TOWN}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE_VEL :{LTBLUE}Servicio no Depósito de Barcos de {TOWN}, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}O barco {COMMA} esta a esperar no depósito
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Construír peirao para barcos
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Construír depósito para barcos (para construír e dar servicio os barcos)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Barcos - pincha nun barco para máis información
+STR_9820_BUILD_NEW_SHIP :{BLACK}Costruír novo barco
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Arrastra o barco aquí para vendelo
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centra-la vista principal na situación do depósito de barcos
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Barcos - pincha no barco para máis información
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Construír novos barcos (necesitas un depósito de barcos)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}Lista de selección de barcos - pincha nun barco para máis información
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Construí-lo barco seleccionado
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Tarea actual do barco - pincha aquí para parar/arrincar o barco
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Mostra-las ordes do barco
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centra-la vista principal na situación do barco
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Envia-lo barco o depósito
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Mostra-los detalles do barco
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}¡Novo barco dispoñible!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Coste: {CURRENCY} Velocidade Máx: {VELOCITY}{}Capacidade: {CARGO}{}Coste de Mantemento: {CURRENCY}/ano
+STR_982F_NAME_SHIP :{BLACK}Renomear barco
+
+STR_9831_NAME_SHIP :{WHITE}Renomear barco
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Non se pode renomea-lo barco
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Celebración cidadá . . .{}¡Chega o primeiro barco a {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Boia de posición, pódese utilizar para marcar puntos de ruta adicionais
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Non se pode coloca-la boia aquí...
+STR_9836_RENAME :{BLACK}Renomear
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Renomear tipo de barco
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Renomear tipo de barco
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Non se pode renomear-lo tipo de barco...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Reaxusta-lo barco para levar un tipo diferente de mercadoría
+STR_983B_REFIT :{WHITE}{VEHICLE} (Reaxustar)
+STR_983C_REFIT_SHIP :{BLACK}Reaxustar barco
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Selecciona o tipo de mercadoría que vai levar
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Reaxusta-lo barco para leva-lo tipo de mercacdoría seleccionada
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Selecciona-lo tipo de carga a levar:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nova Capacidade: {GOLD}{CARGO}{}{BLACK}Coste do reaxuste: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Non se pode reaxusta-lo barco...
+STR_9842_REFITTABLE :(reax.)
+STR_GO_TO_SHIP_DEPOT :Ir ó Depósito de Barcos de {TOWN}
+SERVICE_AT_SHIP_DEPOT :Face-lo servicio no Depósito de Barcos de {TOWN}
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Aeroportos
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Nonse pode construí-lo aeroporto aí...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}Hangar de Aeronaves de {STATION}
+STR_A003_NEW_AIRCRAFT :{BLACK}Nova Aeronave
+STR_CLONE_AIRCRAFT :{BLACK}Clonar Aeronave
+STR_CLONE_AIRCRAFT_INFO :{BLACK}Esto construirá una copia da aeronave. CTRL-Click compartirá as ordes
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Esto construirá unha copia da aeronave. Pincha neste botón e nunha aeronave que estea dentro ou fora do hangar. Control-Click compartirá as ordes
+STR_A005_NEW_AIRCRAFT :{WHITE}Nova Aeronave
+STR_A006_BUILD_AIRCRAFT :{BLACK}Construír Aeronave
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Non se pode construí-lo avíon...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} Aeronave
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (Ordes)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (Detalles)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Idade: {LTBLUE}{STRING}{BLACK} Coste de Mantemento: {LTBLUE}{CURRENCY}/ano
+STR_A00E_MAX_SPEED :{BLACK}Velocidade Máx.: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Beneficio este ano: {LTBLUE}{CURRENCY} (último ano: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}Fiabilidade: {LTBLUE}{COMMA}% {BLACK}Roturas dende o último servicio: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Construído: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Non se pode envia-la aeronave ó hangar...
+STR_HEADING_FOR_HANGAR :{ORANGE}Diríxese ó hangar de {STATION}
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}Diríxese ó hangar de {STATION}, {VELOCITY}
+STR_HEADING_FOR_HANGAR_SERVICE :{LTBLUE}Servicio no Hangar de {STATION}
+STR_HEADING_FOR_HANGAR_SERVICE_VEL :{LTBLUE}Servicio no Hangar de {STATION}, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}A aeronave {COMMA} está a esperar no hangar
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Aeronave no camiño
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Non se pode parar/arrincar a aeronave...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}A aeronave esta voando
+STR_A019_CAPACITY :{BLACK}Capacidade: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Capacidade: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}A aeronave debe estar parada no hangar
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Non se pode vende-la aeronave...
+STR_A01D_AIRPORT_CONSTRUCTION :Construcción de Aeroporto
+STR_A01E_BUILD_AIRPORT :{BLACK}Construír aeroporto
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Aeronaves - pincha na aeronave para máis información
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Construír nova aeronave (necesitas un aeroporto con hangar)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Aeronaves - pincha na aeronave para máis información
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Construír nova aeronave
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}Arrastra a aeronave aquí para vendela
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}centra-la vista principal na situación do hangar
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Lista de selección de aeronaves - pincha nunha aeronave para máis información
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Construí-la aeronave seleccionado
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Tarea actual da aeronave - pincha aquí para parar/arrincar a aeronave
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Mostra-las ordes do avíon
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Centra-la vista principal na situación da aeronave
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Envia-la aeronave ó hangar
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Mostra-los detalles da aeronave
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}¡Nova aeronave dispoñible!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Coste: {CURRENCY} Velocidade Máx.: {VELOCITY}{}Capacidade: {COMMA} pasaxeiros, {COMMA} sacos de correo{}Coste de Mantemento: {CURRENCY}/ano
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Cambia-lo nome da aeronave
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Non se pode renomea-la aeronave...
+STR_A032_NAME_AIRCRAFT :{BLACK}Cambia-lo nome da aeronave
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Celebración cidadá . . .{}¡Chega a primeira aeronave a {STATION}!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}¡Accidente Aéreo!{}{COMMA} morren na bola de lume en {STATION}
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}¡Accidente de Aeronave!¡A aeronave {} quedou sen combustible, hai {COMMA} mortos na explosión!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Renomear
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Renomea-lo tipo de aeronave
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Renomea-lo tipo de aeronave
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Non se pode renomea-lo tipo de aeronave...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Reaxusta-la aeronave para levar un tipo distinto de carga
+STR_A03C_REFIT :{WHITE}{VEHICLE} (Reaxustar)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Reaxustar aeronave
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Selecciona o tipo de carga que levará
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Reaxusta-la aeronave para levar o tipo de carga seleccionada
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Selecciona o tipo de carga a levar:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nova capacidade: {GOLD}{STRING}{}{BLACK}Cose do reaxuste: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Non se pode reaxusta-la aeronave...
+STR_GO_TO_AIRPORT_HANGAR :Ir ó hangar de {STATION}
+SERVICE_AT_AIRPORT_HANGAR :Face-lo servicio no hangar de {STATION}
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}¡Desastre cun Zeppelin en {STATION}!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}¡Vehículo de estrada destruído tras colisionar cun 'OVNI'!
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}¡Explosión dunha refinería de petróleo cerca de {TOWN}!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}¡Factoría destruida en circunstancias sospeitosas cerca de {TOWN}!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}¡Aterrizaxe dun 'OVNI cerca de {TOWN}!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}¡Afundimento dunha Mina de Carbón deixa un rastro de destrucción cerca de {TOWN}!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}¡Inundacións!{}¡Hay polo menos {COMMA} desaparecidos, presuntamente mortos tras unha grande inundación!
+
+STR_BRIBE_FAILED :{WHITE}O tento de suborno foi
+STR_BRIBE_FAILED_2 :{WHITE}descuberto por un investigador rexional.
+STR_BUILD_DATE :{BLACK}construído: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Punt. rendemento detallada
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}Detalle
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Vehículos:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Estacións:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Beneficio min.:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Ingreso min.:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Ingreso max.:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Entregado:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Carga:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Diñeiro:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Crédito:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Total:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Número de vehículos; inclúe camións/buses, trens, barcos e aeronaves
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}Beneficio do vehículo con menos ingresos (de tódolos vehículos de máis de 2 anos)
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}Unidades de carga levadas nos últimos catro quartos
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}Número de tipos de carga levados no último cuarto
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Amount of cash on hand
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}Valor do préstamo que ten a compañía
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Puntos totais de puntos posibles
+
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}Configuración Newgrf
+STR_NEWGRF_APPLY_CHANGES :{BLACK}Aplica-los cambios
+STR_NEWGRF_SET_PARAMETERS :{BLACK}Conf. parámetros
+STR_NEWGRF_TIP :{BLACK}Unha lista de tódolos sets Newgrf que tes instalados. Pincha nun set para cambia-la configuración
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}¡Non hai ficheiros newgrf instalados! Consulta no manual as instruccións para instalar novos gráficos
+STR_NEWGRF_FILENAME :{BLACK}Ficheiro: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
+STR_NEWGRF_MD5SUM :{BLACK}Suma MD5: {SILVER}{STRING}
+
+STR_NEWGRF_ADD :{BLACK}Engadir
+STR_NEWGRF_REMOVE :{BLACK}Eliminar
+STR_NEWGRF_REMOVE_TIP :{BLACK}Elimina-lo arquivo NewGRF seleccionado da lista
+STR_NEWGRF_MOVEUP :{BLACK}Mover Arriba
+STR_NEWGRF_MOVEUP_TIP :{BLACK}Move-lo arquivo NewGRF seleccionado arriba na lista
+STR_NEWGRF_MOVEDOWN :{BLACK}Mover Abaixo
+STR_NEWGRF_MOVEDOWN_TIP :{BLACK}Move-lo arquivo NewGRF seleccionado abaixo na lista
+STR_NEWGRF_PARAMETER :{BLACK}Parámetros: {SILVER}{STRING}
+
+
+STR_NEWGRF_DISABLED :{RED}Desactivado
+
+STR_CURRENCY_WINDOW :{WHITE}Moeda persoalizada
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Taxa de cambio: {ORANGE}{CURRENCY} = £ {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Separador:
+STR_CURRENCY_PREFIX :{LTBLUE}Prefixo:
+STR_CURRENCY_SUFFIX :{LTBLUE}Sufixo:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Cambiar a Euro: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Camiar a Euro: {ORANGE}nunca
+STR_CURRENCY_PREVIEW :{LTBLUE}Vista previa: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Cambia-lo parámetro de moeda personalizada
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} Trens
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} Camións/Buses
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} Aeronaves
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} Navíos
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Mostrar tódolos trens que teñen esta estación nas súas ordes
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Mostrar tódolos vehículos de estrada que teñen esta estación nas súas ordes
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Mostrar tódolas aeronaves que teñen esta estación nas súas ordes
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Mostrar tódolos barcos que teñen esta estación nas súas ordes
+
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}Mostrar tódolos vehículos que comparte esta planificación
+
+### depot strings
+
+STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP :{BLACK}Vender tódolos trens do depósito
+STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP :{BLACK}Vender tódolos barcos no depósito
+STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP :{BLACK}Vender tódalas aeronaves do hangar
+
+
+STR_DEPOT_AUTOREPLACE_TRAIN_TIP :{BLACK}Autorreemprazar tódolos trens no depósito
+STR_DEPOT_AUTOREPLACE_ROADVEH_TIP :{BLACK}Autorreemprazar tódolos vehículos no depósito
+STR_DEPOT_AUTOREPLACE_SHIP_TIP :{BLACK}Autorreemprazar tódolos barcos no depósito
+STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP :{BLACK}Autorreemprazar tódolas aeronaves no hangar
+
+STR_VEHICLE_LIST_TRAIN_DEPOT :{BLACK}{STRING} - {COMMA} Tren{P "" s}
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} Barco{P "" s}
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} Aeronave
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}Reemplazar {STRING}
+STR_REPLACE_VEHICLES_START :{BLACK}Comezar a Reemplazar Vehículos
+STR_REPLACE_VEHICLES_STOP :{BLACK}Parar de Reemplazar Vehículos
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Non hai vehículos seleccionados
+STR_REPLACE_HELP :{BLACK}Permíteche reemplazar untipo de máquina cunha doutro tipo, cando trens do tipo orixinal entran nun depósito
+STR_REPLACE_REMOVE_WAGON :{BLACK}Eliminar os vagóns: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}Reemprazando: {ORANGE}{SKIP}{SKIP}{STRING}
+
+STR_ENGINES :Máquinas
+STR_WAGONS :Vagóns
+
+STR_MASS_STOP_DEPOT_TRAIN_TIP :{BLACK}Pincha para parar tódolos trens que hai no depósito
+STR_MASS_STOP_DEPOT_ROADVEH_TIP :{BLACK}Pincha para parar tódolos vehículos que hai no depósito
+STR_MASS_STOP_DEPOT_SHIP_TIP :{BLACK}Pincha para parar tódolos barcos que hai no depósito
+STR_MASS_STOP_HANGAR_TIP :{BLACK}Pincha para parar tódalas aeronaves que hai no hangar
+
+STR_MASS_START_DEPOT_TRAIN_TIP :{BLACK}Pincha para iniciar tódolos trens que hai no depósito
+STR_MASS_START_DEPOT_ROADVEH_TIP :{BLACK}Pincha para iniciar tódolos vehículos que hai no depósito
+STR_MASS_START_DEPOT_SHIP_TIP :{BLACK}Pincha para iniciar tódolos barcos que hai no depósito
+STR_MASS_START_HANGAR_TIP :{BLACK}Pincha para iniciar tódalas aeronaves que hai no hangar
+
+STR_MASS_STOP_LIST_TIP :{BLACK}Pincha para parar tódolos vehículos da lista
+STR_MASS_START_LIST_TIP :{BLACK}Pincha para iniciar tódolos vehículos da lista
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}Lista de Sinais - {COMMA} Sinais
+
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :Vehículos Raíl
+STR_MONORAIL_VEHICLES :Vehículos Monoraíl
+STR_MAGLEV_VEHICLES :Vehículos Maglev
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Coste: {GOLD}{CURRENCY}{BLACK} Peso: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Velocidade: {GOLD}{VELOCITY}{BLACK} Potencia: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}Velocidade: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Mantemento: {GOLD}{CURRENCY}/ano
+STR_PURCHASE_INFO_CAPACITY :{BLACK}Capacidade: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Deseñado: {GOLD}{NUM}{BLACK} Vida: {GOLD}{COMMA} anos
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}Fiabilidade Max.: {GOLD}{COMMA}%
+STR_PURCHASE_INFO_COST :{BLACK}Coste: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Peso: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Coste: {GOLD}{CURRENCY}{BLACK} Velocidade: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Capacidade: {GOLD}{COMMA} pasaxeiros, {COMMA} sacos de correo
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Vagóns tractores: {GOLD}+{POWER}{BLACK} Peso: {GOLD}+{WEIGHT_S}
+STR_PURCHASE_INFO_ALL_BUT :Todo excepto {GOLD}
+
+########### String for New Landscape Generator
+
+STR_GENERATE :{WHITE}Xerar
+STR_RANDOM :{BLACK}Aleatorio
+STR_WORLD_GENERATION_CAPTION :{WHITE}Xeración do mundo
+STR_RANDOM_SEED :{BLACK}Semilla Aleatoria:
+STR_RANDOM_SEED_HELP :{BLACK}Pincha para introducir unha semilla
+STR_LAND_GENERATOR :{BLACK}Xerador de terreo:
+STR_TERRAIN_TYPE :{BLACK}Tipo de terreo:
+STR_QUANTITY_OF_SEA_LAKES :{BLACK}Nivel do mar:
+STR_SMOOTHNESS :{BLACK}Suavidade:
+STR_SNOW_LINE_HEIGHT :{BLACK}Altura da liña de neve:
+STR_DATE :{BLACK}Data:
+STR_NUMBER_OF_TOWNS :{BLACK}Num. de cidades:
+STR_NUMBER_OF_INDUSTRIES :{BLACK}Num. de industrias:
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_START_DATE_QUERY_CAPT :{WHITE}Cambia-lo ano de inicio
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_HEIGHTMAP_SIZE :{BLACK}Tamaño: {ORANGE}{NUM} x {NUM}
+STR_GENERATION_WORLD :{WHITE}Xerando mundo...
+STR_GENERATION_ABORT :{BLACK}Cancelar
+STR_GENERATION_ABORT_CAPTION :{WHITE}Cancelar Xeración De Mundo
+STR_GENERATION_ABORT_MESSAGE :{YELLOW}¿Estás seguro de querer terminar a xeración?
+STR_PROGRESS :{WHITE}{NUM}% completado
+STR_GENERATION_PROGRESS :{BLACK}{NUM} / {NUM}
+STR_WORLD_GENERATION :{BLACK}Xeración do mundo
+STR_SETTINGUP_GAME :{BLACK}Configurando partida
+STR_PREPARING_GAME :{BLACK}Preparando partida
+STR_SE_FLAT_WORLD :{WHITE}Terreo Chan
+STR_SE_NEW_WORLD :{BLACK}Crear novo escenario
+STR_SE_CAPTION :{WHITE}Tipo de escenario
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+STR_SMALLMAP_CENTER :{BLACK}Centra-lo mapa pequeno na posición actual
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}Pequeno
+STR_CITY_AIRPORT :{BLACK}Cidade
+STR_METRO_AIRPORT :{BLACK}Aeroporto metropolitano
+STR_INTERNATIONAL_AIRPORT :{BLACK}Aeroporto Internacional
+STR_COMMUTER_AIRPORT :{BLACK}Conmutador
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Intercontinental
+STR_HELIPORT :{BLACK}Heliporto
+STR_HELIDEPOT :{BLACK}Helidepósito
+STR_HELISTATION :{BLACK}Heliporto
+
+STR_SMALL_AIRPORTS :{BLACK}Aeroportos pequenos
+STR_LARGE_AIRPORTS :{BLACK}Aeroportos grandes
+STR_HELIPORTS :{BLACK}Aeroportos para helicópteros
+
+############ Tooltip measurment
+
+STR_MEASURE_LENGTH :{BLACK}Lonxitude: {NUM}
+STR_MEASURE_AREA :{BLACK}Ãrea: {NUM} x {NUM}
+STR_MEASURE_LENGTH_HEIGHTDIFF :{BLACK}Lonxitude: {NUM}{}Diferencia de altura: {NUM} m
+STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}Ãrea: {NUM} x {NUM}{}Diferencia de altura: {NUM} m
+
+########
diff --git a/src/lang/german.txt b/src/lang/german.txt
new file mode 100644
index 000000000..f07130d75
--- /dev/null
+++ b/src/lang/german.txt
@@ -0,0 +1,3117 @@
+##name German
+##ownname Deutsch
+##isocode de_DE.UTF-8
+##plural 0
+##gender m w n
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Zu weit vom Kartenrand entfernt
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Zu nahe am Kartenrand
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Nicht genug Geld - {CURRENCY} benötigt!
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Ebenes Land erforderlich
+STR_0008_WAITING :{BLACK}Wartend: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (unterwegs von
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Akzeptiert: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Akzeptiert: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :Passagiere
+STR_0010_COAL :Kohle
+STR_0011_MAIL :Post
+STR_0012_OIL :Öl
+STR_0013_LIVESTOCK :Vieh
+STR_0014_GOODS :Waren
+STR_0015_GRAIN :Getreide
+STR_0016_WOOD :Holz
+STR_0017_IRON_ORE :Eisenerz
+STR_0018_STEEL :Stahl
+STR_0019_VALUABLES :Wertsachen
+STR_001A_COPPER_ORE :Kupfererz
+STR_001B_MAIZE :Mais
+STR_001C_FRUIT :Früchte
+STR_001D_DIAMONDS :Diamanten
+STR_001E_FOOD :Nahrungsmittel
+STR_001F_PAPER :Papier
+STR_0020_GOLD :Gold
+STR_0021_WATER :Wasser
+STR_0022_WHEAT :Weizen
+STR_0023_RUBBER :Kautschuk
+STR_0024_SUGAR :Zucker
+STR_0025_TOYS :Spielwaren
+STR_0026_CANDY :Bonbons
+STR_0027_COLA :Cola
+STR_0028_COTTON_CANDY :Zuckerwatte
+STR_0029_BUBBLES :Luftblasen
+STR_002A_TOFFEE :Karamell
+STR_002B_BATTERIES :Batterien
+STR_002C_PLASTIC :Plastik
+STR_002D_FIZZY_DRINKS :Limonaden
+STR_002E :
+STR_002F_PASSENGER :Passagier
+STR_0030_COAL :Kohle
+STR_0031_MAIL :Post
+STR_0032_OIL :Öl
+STR_0033_LIVESTOCK :Vieh
+STR_0034_GOODS :Waren
+STR_0035_GRAIN :Getreide
+STR_0036_WOOD :Holz
+STR_0037_IRON_ORE :Eisenerz
+STR_0038_STEEL :Stahl
+STR_0039_VALUABLES :Wertsachen
+STR_003A_COPPER_ORE :Kupfererz
+STR_003B_MAIZE :Mais
+STR_003C_FRUIT :Früchte
+STR_003D_DIAMOND :Diamanten
+STR_003E_FOOD :Nahrungsmittel
+STR_003F_PAPER :Papier
+STR_0040_GOLD :Gold
+STR_0041_WATER :Wasser
+STR_0042_WHEAT :Weizen
+STR_0043_RUBBER :Kautschuk
+STR_0044_SUGAR :Zucker
+STR_0045_TOY :Spielware
+STR_0046_CANDY :Bonbon
+STR_0047_COLA :Cola
+STR_0048_COTTON_CANDY :Zuckerwatte
+STR_0049_BUBBLE :Luftblase
+STR_004A_TOFFEE :Karamell
+STR_004B_BATTERY :Batterie
+STR_004C_PLASTIC :Plastik
+STR_004D_FIZZY_DRINK :Limonade
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} Passagier{P "" e}
+STR_QUANTITY_COAL :{WEIGHT} Kohle
+STR_QUANTITY_MAIL :{COMMA} Posts{P ack äcke}
+STR_QUANTITY_OIL :{VOLUME} Öl
+STR_QUANTITY_LIVESTOCK :{COMMA} Stück Vieh
+STR_QUANTITY_GOODS :{COMMA} Warenkiste{P "" n}
+STR_QUANTITY_GRAIN :{WEIGHT} Getreide
+STR_QUANTITY_WOOD :{WEIGHT} Holz
+STR_QUANTITY_IRON_ORE :{WEIGHT} Eisenerz
+STR_QUANTITY_STEEL :{WEIGHT} Stahl
+STR_QUANTITY_VALUABLES :{COMMA} {P Sack Säcke} mit Wertsachen
+STR_QUANTITY_COPPER_ORE :{WEIGHT} Kupfererz
+STR_QUANTITY_MAIZE :{WEIGHT} Mais
+STR_QUANTITY_FRUIT :{WEIGHT} Früchte
+STR_QUANTITY_DIAMONDS :{COMMA} {P Sack Säcke} mit Diamanten
+STR_QUANTITY_FOOD :{WEIGHT} Nahrungsmittel
+STR_QUANTITY_PAPER :{WEIGHT} Papier
+STR_QUANTITY_GOLD :{COMMA} {P Sack Säcke} mit Gold
+STR_QUANTITY_WATER :{VOLUME} Wasser
+STR_QUANTITY_WHEAT :{WEIGHT} Weizen
+STR_QUANTITY_RUBBER :{VOLUME} Kautschuk
+STR_QUANTITY_SUGAR :{WEIGHT} Zucker
+STR_QUANTITY_TOYS :{COMMA} Spielzeug{P "" e}
+STR_QUANTITY_SWEETS :{COMMA} {P Sack Säcke} mit Bonbons
+STR_QUANTITY_COLA :{VOLUME} Cola
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} Zuckerwatte
+STR_QUANTITY_BUBBLES :{COMMA} Luftblase{P "" n}
+STR_QUANTITY_TOFFEE :{WEIGHT} Karamell
+STR_QUANTITY_BATTERIES :{COMMA} Batterie{P "" n}
+STR_QUANTITY_PLASTIC :{VOLUME} Plastik
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} Limonade{P "" n}
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}PS
+STR_ABBREV_COAL :{TINYFONT}KL
+STR_ABBREV_MAIL :{TINYFONT}PO
+STR_ABBREV_OIL :{TINYFONT}ÖL
+STR_ABBREV_LIVESTOCK :{TINYFONT}VI
+STR_ABBREV_GOODS :{TINYFONT}WK
+STR_ABBREV_GRAIN :{TINYFONT}GT
+STR_ABBREV_WOOD :{TINYFONT}HO
+STR_ABBREV_IRON_ORE :{TINYFONT}EE
+STR_ABBREV_STEEL :{TINYFONT}ST
+STR_ABBREV_VALUABLES :{TINYFONT}WE
+STR_ABBREV_COPPER_ORE :{TINYFONT}KU
+STR_ABBREV_MAIZE :{TINYFONT}MA
+STR_ABBREV_FRUIT :{TINYFONT}FR
+STR_ABBREV_DIAMONDS :{TINYFONT}DI
+STR_ABBREV_FOOD :{TINYFONT}NM
+STR_ABBREV_PAPER :{TINYFONT}PA
+STR_ABBREV_GOLD :{TINYFONT}GD
+STR_ABBREV_WATER :{TINYFONT}WA
+STR_ABBREV_WHEAT :{TINYFONT}WZ
+STR_ABBREV_RUBBER :{TINYFONT}KA
+STR_ABBREV_SUGAR :{TINYFONT}ZU
+STR_ABBREV_TOYS :{TINYFONT}SP
+STR_ABBREV_SWEETS :{TINYFONT}BO
+STR_ABBREV_COLA :{TINYFONT}CO
+STR_ABBREV_CANDYFLOSS :{TINYFONT}ZW
+STR_ABBREV_BUBBLES :{TINYFONT}LB
+STR_ABBREV_TOFFEE :{TINYFONT}KM
+STR_ABBREV_BATTERIES :{TINYFONT}BA
+STR_ABBREV_PLASTIC :{TINYFONT}PL
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}LI
+STR_ABBREV_NONE :{TINYFONT}KEINE
+STR_ABBREV_ALL :{TINYFONT}ALLE
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Karte - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Spieleinstellungen
+STR_00B2_MESSAGE :{YELLOW}Nachricht
+STR_00B3_MESSAGE_FROM :{YELLOW}Nachricht von {STRING}
+STR_POPUP_CAUTION_CAPTION :{WHITE}Achtung!
+STR_00B4_CAN_T_DO_THIS :{WHITE}Kann dies nicht tun....
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Kann das Gebiet nicht räumen....
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Original copyright {COPYRIGHT} 1995 Chris Sawyer, Alle Rechte vorbehalten
+STR_00B7_VERSION :{BLACK}OpenTTD Version {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 OpenTTD-Team
+STR_TRANSLATED_BY :{BLACK} Ãœbersetzer -
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Verlassen
+STR_00C8_YES :{BLACK}Ja
+STR_00C9_NO :{BLACK}Nein
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Bist du sicher, dass du das Spiel abbrechen und zu {STRING} zurückkehren willst?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Nichts
+STR_00D1_DARK_BLUE :Dunkelblau
+STR_00D2_PALE_GREEN :Hellgrün
+STR_00D3_PINK :Rosa
+STR_00D4_YELLOW :Gelb
+STR_00D5_RED :Rot
+STR_00D6_LIGHT_BLUE :Hellblau
+STR_00D7_GREEN :Grün
+STR_00D8_DARK_GREEN :Dunkelgrün
+STR_00D9_BLUE :Blau
+STR_00DA_CREAM :Beige
+STR_00DB_MAUVE :Helllila
+STR_00DC_PURPLE :Lila
+STR_00DD_ORANGE :Orange
+STR_00DE_BROWN :Braun
+STR_00DF_GREY :Grau
+STR_00E0_WHITE :Weiß
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Zu viele Fahrzeuge im Spiel
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Standort
+STR_00E5_CONTOURS :Umrisse
+STR_00E6_VEHICLES :Fahrzeuge
+STR_00E7_INDUSTRIES :Industrie
+STR_00E8_ROUTES :Strecken
+STR_00E9_VEGETATION :Vegetation
+STR_00EA_OWNERS :Eigentümer
+STR_00EB_ROADS :{BLACK}{TINYFONT}Straßen
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Gleise
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Bahnhöfe/Flughäfen/Häfen
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Gebäude/Industrien
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Fahrzeuge
+STR_00F0_100M :{BLACK}{TINYFONT}100m
+STR_00F1_200M :{BLACK}{TINYFONT}200m
+STR_00F2_300M :{BLACK}{TINYFONT}300m
+STR_00F3_400M :{BLACK}{TINYFONT}400m
+STR_00F4_500M :{BLACK}{TINYFONT}500m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Züge
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Fahrzeuge
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Schiffe
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Flugzeuge
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Transportstrecken
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Kohlebergwerk
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Kraftwerk
+STR_00FC_FOREST :{BLACK}{TINYFONT}Wald
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}Sägewerk
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Ölraffinerie
+STR_00FF_FARM :{BLACK}{TINYFONT}Bauernhof
+STR_0100_FACTORY :{BLACK}{TINYFONT}Fabrik
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Druckerei
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Ölquellen
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Eisenerzmine
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Stahlfabrik
+STR_0105_BANK :{BLACK}{TINYFONT}Bank
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Papiermühle
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Goldmine
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Nahrungsmittelfabrik
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Diamantenmine
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Kupfermine
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Fruchtplantage
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Kautschukplantage
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Wasserquelle
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Wasserturm
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}Holzmühle
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Zuckerwattewald
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Bonbonfabrik
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Batterieplantage
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Colaquellen
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Spielwarengeschäft
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Spielwarenfabrik
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Plastikbrunnen
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Limonadenfabrik
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Luftblasengenerator
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Karamellgrube
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Zuckerbergwerk
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Bahnhof
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Lkw-Ladestation
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Busbahnhof
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Flughafen / Heliport
+STR_011F_DOCK :{BLACK}{TINYFONT}Hafen
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Unebenes Land
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Wiesen
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Kahles Land
+STR_0123_FIELDS :{BLACK}{TINYFONT}Felder
+STR_0124_TREES :{BLACK}{TINYFONT}Bäume
+STR_0125_ROCKS :{BLACK}{TINYFONT}Felsen
+STR_0126_WATER :{BLACK}{TINYFONT}Wasser
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Kein Eigentümer
+STR_0128_TOWNS :{BLACK}{TINYFONT}Städte
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Industrien
+STR_012A_DESERT :{BLACK}{TINYFONT}Wüste
+STR_012B_SNOW :{BLACK}{TINYFONT}Schnee
+STR_012C_MESSAGE :{WHITE}Mitteilung
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Abbrechen
+STR_012F_OK :{BLACK}OK
+STR_0130_RENAME :{BLACK}Umbenennen
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Zu viele Namen definiert
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Gewählter Name existiert bereits
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...Eigentum von {STRING}
+STR_013C_CARGO :{BLACK}Fracht
+STR_013D_INFORMATION :{BLACK}Information
+STR_013E_CAPACITIES :{BLACK}Kapazitäten
+STR_013E_TOTAL_CARGO :{BLACK}Frachtübersicht
+STR_013F_CAPACITY :{BLACK}Kapazität: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}Kapazität: {LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Frachtkapazität dieses Zuges:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}{CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}Neues Spiel
+STR_0141_LOAD_GAME :{BLACK}Spiel laden
+STR_SINGLE_PLAYER :{BLACK}Einzelspieler
+STR_MULTIPLAYER :{BLACK}Mehrspieler
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Kartengröße:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Spieleinstellungen
+
+STR_0150_SOMEONE :Jemand{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Weltkarte
+STR_0152_TOWN_DIRECTORY :Städteverzeichnis
+STR_0153_SUBSIDIES :Subventionen
+
+STR_UNITS_IMPERIAL :US-Maße
+STR_UNITS_METRIC :metrisch
+STR_UNITS_SI :SI-Basiseinheiten
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} mph
+STR_UNITS_VELOCITY_METRIC :{COMMA} km/h
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}PS
+STR_UNITS_POWER_METRIC :{COMMA}PS
+STR_UNITS_POWER_SI :{COMMA}kW
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} Tonne{P "" n}
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} Tonne{P "" n}
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} kg
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}gal
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}l
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}m³
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} Gallone{P "" n}
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} Liter
+STR_UNITS_VOLUME_LONG_SI :{COMMA} m³
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10³ lbf
+STR_UNITS_FORCE_METRIC :{COMMA} t Zugkraft
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Betriebsgewinndiagramm
+STR_0155_INCOME_GRAPH :Einkommensdiagramm
+STR_0156_DELIVERED_CARGO_GRAPH :Frachtlieferungsdiagramm
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Leistungskurvendiagramm
+STR_0158_COMPANY_VALUE_GRAPH :Firmenwertdiagramm
+STR_0159_CARGO_PAYMENT_RATES :Frachtratendiagramm
+STR_015A_COMPANY_LEAGUE_TABLE :Firmentabelle
+STR_PERFORMANCE_DETAIL_MENU :Leistungsaufschlüsselung
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}OpenTTD
+STR_015C_SAVE_GAME :Spiel speichern
+STR_015D_LOAD_GAME :Spiel laden
+STR_015E_QUIT_GAME :Spiel beenden
+STR_015F_QUIT :Beenden
+STR_ABANDON_GAME_QUERY :{YELLOW}Bist du sicher, dass du das Spiel beenden willst?
+STR_0161_QUIT_GAME :{WHITE}Spiel beenden
+STR_SORT_ORDER_TIP :{BLACK}Sortierreihenfolge auswählen (absteigend/aufsteigend)
+STR_SORT_CRITERIA_TIP :{BLACK}Sortierkriterium auswählen
+STR_SORT_BY :{BLACK}Sortieren nach
+
+STR_SORT_BY_POPULATION :{BLACK}Bevölkerung
+STR_SORT_BY_PRODUCTION :{BLACK}Produktion
+STR_SORT_BY_TYPE :{BLACK}Typ
+STR_SORT_BY_TRANSPORTED :{BLACK}Transportiert
+STR_SORT_BY_NAME :{BLACK}Name
+STR_SORT_BY_DROPDOWN_NAME :Name
+STR_SORT_BY_DATE :{BLACK}Datum
+STR_SORT_BY_NUMBER :Nummer
+STR_SORT_BY_PROFIT_LAST_YEAR :Profit letztes Jahr
+STR_SORT_BY_PROFIT_THIS_YEAR :Profit dieses Jahr
+STR_SORT_BY_AGE :Alter
+STR_SORT_BY_RELIABILITY :Zuverlässigkeit
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Gesamtkapazität pro Fracht
+STR_SORT_BY_MAX_SPEED :Höchstgeschwindigkeit
+STR_SORT_BY_MODEL :Bauart
+STR_SORT_BY_VALUE :Wert
+STR_SORT_BY_FACILITY :Stationsart
+STR_SORT_BY_WAITING :Menge der wartenden Fracht
+STR_SORT_BY_RATING_MAX :Frachtbewertung
+STR_ENGINE_SORT_ENGINE_ID :Baureihe
+STR_ENGINE_SORT_COST :Kosten
+STR_ENGINE_SORT_POWER :Leistung
+STR_ENGINE_SORT_INTRO_DATE :Einführungsdatum
+STR_ENGINE_SORT_RUNNING_COST :Betriebskosten
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Leistung/Betriebskosten
+STR_ENGINE_SORT_CARGO_CAPACITY :Frachtkapazität
+STR_NO_WAITING_CARGO :{BLACK}Keine Fracht wartet
+STR_SELECT_ALL_FACILITIES :{BLACK}Wähle alle Anlagen
+STR_SELECT_ALL_TYPES :{BLACK}Wähle alle Frachtarten (einschließlich ohne wartender Fracht)
+STR_AVAILABLE_ENGINES_TIP :{BLACK}Zeige eine Liste von verfügbaren Fahrzeugen für diesen Fahrzeugtyp
+STR_MANAGE_LIST :{BLACK}Verwalte die Liste
+STR_MANAGE_LIST_TIP :{BLACK}Aufträge an alle Fahrzeuge in der Liste verschicken
+STR_REPLACE_VEHICLES :Ersetze Fahrzeuge
+STR_SEND_TRAIN_TO_DEPOT :Sende nach Depot
+STR_SEND_ROAD_VEHICLE_TO_DEPOT :Sende nach Depot
+STR_SEND_SHIP_TO_DEPOT :Sende nach Depot
+STR_SEND_AIRCRAFT_TO_HANGAR :Sende nach Hangar
+STR_SEND_FOR_SERVICING :Zur Wartung schicken
+
+############ range for months starts
+STR_0162_JAN :Jan
+STR_0163_FEB :Feb
+STR_0164_MAR :Mär
+STR_0165_APR :Apr
+STR_0166_MAY :Mai
+STR_0167_JUN :Jun
+STR_0168_JUL :Jul
+STR_0169_AUG :Aug
+STR_016A_SEP :Sep
+STR_016B_OCT :Okt
+STR_016C_NOV :Nov
+STR_016D_DEC :Dez
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Spiel anhalten
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Spiel speichern, Spiel laden, Spiel verlassen, Beenden
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Liste der Firmenbahnhöfe anzeigen
+STR_0174_DISPLAY_MAP :{BLACK}Weltkarte anzeigen
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Weltkarte anzeigen, Städteverzeichnis
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Städteverzeichnis anzeigen
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Firmenfinanzen anzeigen
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Allgemeine Firmeninformationen anzeigen
+STR_0179_DISPLAY_GRAPHS :{BLACK}Diagramm anzeigen
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Firmentabelle anzeigen
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Zuglisten der Firmen
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Fahrzeuglisten der Firmen
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Schiffslisten der Firmen
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Flugzeuglisten der Firmen
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Heranzoomen (vergrößern)
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Wegzoomen (verkleinern)
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Gleise legen
+STR_0182_BUILD_ROADS :{BLACK}Straßen bauen
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Hafen bauen
+STR_0184_BUILD_AIRPORTS :{BLACK}Flughafen bauen
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Bäume pflanzen, Schilder aufstellen usw.
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Gebietsinformation
+STR_0187_OPTIONS :{BLACK}Einstellungen
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Das Wartungsintervall kann nicht geändert werden...
+STR_018B_CLOSE_WINDOW :{BLACK}Fenster schließen
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Titelleiste verschieben um das Fenster zu bewegen
+STR_STICKY_BUTTON :{BLACK}Fenster wird nicht durch die "schließe alle Fenster"-Taste geschlossen
+STR_RESIZE_BUTTON :{BLACK}Klicken und Ziehen zum Größe ändern
+STR_SAVELOAD_HOME_BUTTON :{BLACK}Hier klicken, um zum Standardspielstandsverzeichnis zu gehen
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Gebäude usw. auf einem Planquadrat abreißen
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Land absenken
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Land anheben
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Scrollbalken - Liste auf- und abwärts blättern
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Scrollbalken - Liste nach links und rechts blättern
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Höhenlinien auf der Karte anzeigen
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Fahrzeuge auf der Karte anzeigen
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Industrien auf der Karte anzeigen
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Transportwege auf der Karte anzeigen
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Vegetation auf der Karte anzeigen
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Landeigentümer auf der Karte anzeigen
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Stadtnamen anzeigen an/aus
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Profit laufendes Jahr: {CURRENCY} (vorheriges Jahr: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} Jahr{P "" e} ({COMMA})
+STR_AGE_RED :{RED}{COMMA} Jahr{P "" e} ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Fahrzeug
+STR_019D_AIRCRAFT :Flugzeug
+STR_019E_SHIP :Schiff
+STR_019F_TRAIN :Zug
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} kommt in die Jahre
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} ist veraltet
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} ist völlig veraltet und sollte ersetzt werden
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Gebietsinformation
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Räumungskosten: {LTBLUE}k.A.
+STR_01A5_COST_TO_CLEAR :{BLACK}Räumungskosten: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :k.A.
+STR_01A7_OWNER :{BLACK}Eigentümer: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Gehört zur Gemeinde: {LTBLUE}{STRING}
+STR_01A9_NONE :Keine
+STR_01AA_NAME :{BLACK}Name
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1.
+STR_01AD_2ND :2.
+STR_01AE_3RD :3.
+STR_01AF_4TH :4.
+STR_01B0_5TH :5.
+STR_01B1_6TH :6.
+STR_01B2_7TH :7.
+STR_01B3_8TH :8.
+STR_01B4_9TH :9.
+STR_01B5_10TH :10.
+STR_01B6_11TH :11.
+STR_01B7_12TH :12.
+STR_01B8_13TH :13.
+STR_01B9_14TH :14.
+STR_01BA_15TH :15.
+STR_01BB_16TH :16.
+STR_01BC_17TH :17.
+STR_01BD_18TH :18.
+STR_01BE_19TH :19.
+STR_01BF_20TH :20.
+STR_01C0_21ST :21.
+STR_01C1_22ND :22.
+STR_01C2_23RD :23.
+STR_01C3_24TH :24.
+STR_01C4_25TH :25.
+STR_01C5_26TH :26.
+STR_01C6_27TH :27.
+STR_01C7_28TH :28.
+STR_01C8_29TH :29.
+STR_01C9_30TH :30.
+STR_01CA_31ST :31.
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Akzeptierte Fracht: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Musikbox
+STR_01D3_SOUND_MUSIC :Sound / Musik
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Zeige Sound- / Musikfenster
+STR_01D5_ALL :{TINYFONT}Alle
+STR_01D6_OLD_STYLE :{TINYFONT}Traditionell
+STR_01D7_NEW_STYLE :{TINYFONT}Modern
+STR_01D8_EZY_STREET :{TINYFONT}Ezy Street
+STR_01D9_CUSTOM_1 :{TINYFONT}Individuell 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Individuell 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Musiklautstärke
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Soundlautstärke
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MIN ' ' ' ' ' ' MAX
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Springe zum vorherigen Titel
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Springe zum nächsten Titel
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Wiedergabe anhalten
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Wiedergabe starten
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Schieberegler für Musik- / Soundlautstärke
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Track{SETX 88}Titel
+STR_01E9_SHUFFLE :{TINYFONT}Mischen
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Programm
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Musik-Programmauswahl
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Track Inhalt
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Programm - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}Bereinigen
+STR_01F1_SAVE :{TINYFONT}{BLACK}Speichern
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}laufendes Musikprogramm
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Programm 'Alle Titel' wählen
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Programm 'Traditionell' wählen
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Programm 'Modern' wählen
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Programm 'Individuell 1' (benutzerdefiniert) wählen
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Programm 'Individuell 2' (benutzerdefiniert) wählen
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Lösche laufendes Programm (nur für Individuell 1 und Individuell 2)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Musikeinstellungen speichern
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Klicke auf den Musiktitel, um ihn in das laufende Programm zu übernehmen (nur für Individuell 1 und Individuell 2)
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Klicke auf einen Musiktitel, um ihn aus der aktuellen Liste zu entfernen(Custom1 or Custom2 only)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Schalte Programmauswahl an/aus
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Zeige Musiktitelauswahl
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Anklicken, um die Ansicht auf die Industrie/Stadt zu zentrieren
+STR_01FE_DIFFICULTY :{BLACK}Schwierigkeit ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Letzte Mitteilung / Nachricht
+STR_0201_MESSAGE_SETTINGS :Nachrichtenoptionen
+STR_MESSAGE_HISTORY_MENU :Vergangene Nachrichten
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Zeige letzte Mitteilung / Nachricht, Nachrichtenoptionen anzeigen
+STR_0204_MESSAGE_OPTIONS :{WHITE}Nachrichtenoptionen
+STR_0205_MESSAGE_TYPES :{BLACK}Nachrichtenart:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Ankunft des ersten Fahrzeugs in einer Station des Spielers
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Ankunft des ersten Fahrzeugs in einer Station eines Gegners
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Unfälle / Katastrophen
+STR_0209_COMPANY_INFORMATION :{YELLOW}Firmendaten
+STR_020A_ECONOMY_CHANGES :{YELLOW}Änderungen der Wirtschaftslage
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Rat / Informationen zu Fahrzeugen des Spielers
+STR_020C_NEW_VEHICLES :{YELLOW}Neue Fahrzeuge
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Änderungen akzeptierter Fracht
+STR_020E_SUBSIDIES :{YELLOW}Subventionen
+STR_020F_GENERAL_INFORMATION :{YELLOW}Allgemeine Nachrichten
+STR_MESSAGES_ALL :{YELLOW}Einstellung für alle Nachrichtenarten (an/aus/Ticker)
+STR_MESSAGE_SOUND :{YELLOW}Sound für Tickermeldungen abspielen
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...zu weit vom vorherigen Bestimmungsort entfernt
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Beste Unternehmen, die {NUM} erreichten{}(Schwierigkeitsgrad {STRING})
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Firmentabelle in {NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Geschäftsmann
+STR_0214_ENTREPRENEUR :Unternehmer
+STR_0215_INDUSTRIALIST :Industrieller
+STR_0216_CAPITALIST :Kapitalist
+STR_0217_MAGNATE :Magnat
+STR_0218_MOGUL :Mogul
+STR_0219_TYCOON_OF_THE_CENTURY :Tycoon des Jahrhunderts
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} erreicht '{STRING}' Status!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} von {COMPANY} erreicht '{STRING}' Status!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Szenario erstellen
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Szenario bearbeiten
+STR_0223_LAND_GENERATION :{WHITE}Land erstellen
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Zufälliges Land
+STR_0227_RESET_LAND :{BLACK}Land wiederherstellen
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Landfläche zum Anheben / Absenken vergrößern
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Landfläche zum Anheben / Absenken verkleinern
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Erzeuge Land durch Zufall
+STR_022B_RESET_LANDSCAPE :{BLACK}Landfläche wiederherstellen
+STR_022C_RESET_LANDSCAPE :{WHITE}Landfläche wiederherstellen
+STR_LOAD_GAME_HEIGHTMAP :{WHITE}Reliefkarte nutzen
+STR_LOAD_SCEN_HEIGHTMAP :{BLACK}Reliefkarte nutzen
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Bist du sicher, dass die Landschaft zurückgesetzt werden soll?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Landfläche erzeugen
+STR_022F_TOWN_GENERATION :{BLACK}Stadt errichten
+STR_0230_INDUSTRY_GENERATION :{BLACK}Industrie errichten
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Straße bauen
+STR_0233_TOWN_GENERATION :{WHITE}Stadt errichten
+STR_0234_NEW_TOWN :{BLACK}Neue Stadt
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Neue Stadt errichten
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Kann hier keine Stadt errichten...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...zu dicht am Kartenrand
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...zu dicht an einer anderen Stadt
+STR_0239_SITE_UNSUITABLE :{WHITE}...ungeeigneter Standort
+STR_023A_TOO_MANY_TOWNS :{WHITE}...zu viele Städte
+STR_CANNOT_GENERATE_TOWN :{WHITE}Bau von Städten unmöglich
+STR_NO_SPACE_FOR_TOWN :{WHITE}...es ist kein Platz mehr auf der Karte.
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Vergrößere die Stadt
+STR_023C_EXPAND :{BLACK}Ausdehnen
+STR_023D_RANDOM_TOWN :{BLACK}Zufällige Stadt
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Stadt an zufälligem Platz errichten
+STR_023F_INDUSTRY_GENERATION :{WHITE}Industrie errichten
+STR_0240_COAL_MINE :{BLACK}Kohlebergwerk
+STR_0241_POWER_STATION :{BLACK}Kraftwerk
+STR_0242_SAWMILL :{BLACK}Sägewerk
+STR_0243_FOREST :{BLACK}Wald
+STR_0244_OIL_REFINERY :{BLACK}Ölraffinerie
+STR_0245_OIL_RIG :{BLACK}Ölbohrinsel
+STR_0246_FACTORY :{BLACK}Fabrik
+STR_0247_STEEL_MILL :{BLACK}Stahlwerk
+STR_0248_FARM :{BLACK}Bauernhof
+STR_0249_IRON_ORE_MINE :{BLACK}Eisenerzmine
+STR_024A_OIL_WELLS :{BLACK}Ölquellen
+STR_024B_BANK :{BLACK}Bank
+STR_024C_PAPER_MILL :{BLACK}Papiermühle
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Nahrungsmittelfabrik
+STR_024E_PRINTING_WORKS :{BLACK}Druckerei
+STR_024F_GOLD_MINE :{BLACK}Goldmine
+STR_0250_LUMBER_MILL :{BLACK}Holzmühle
+STR_0251_FRUIT_PLANTATION :{BLACK}Fruchtplantage
+STR_0252_RUBBER_PLANTATION :{BLACK}Kautschukplantage
+STR_0253_WATER_SUPPLY :{BLACK}Wasserquelle
+STR_0254_WATER_TOWER :{BLACK}Wasserturm
+STR_0255_DIAMOND_MINE :{BLACK}Diamantenmine
+STR_0256_COPPER_ORE_MINE :{BLACK}Kupfermine
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Zuckerwattewald
+STR_0258_CANDY_FACTORY :{BLACK}Bonbonfabrik
+STR_0259_BATTERY_FARM :{BLACK}Batterieplantage
+STR_025A_COLA_WELLS :{BLACK}Colaquellen
+STR_025B_TOY_SHOP :{BLACK}Spielwarengeschäft
+STR_025C_TOY_FACTORY :{BLACK}Spielwarenfabrik
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Plastikbrunnen
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Limonadenfabrik
+STR_025F_BUBBLE_GENERATOR :{BLACK}Luftblasengenerator
+STR_0260_TOFFEE_QUARRY :{BLACK}Karamellgrube
+STR_0261_SUGAR_MINE :{BLACK}Zuckerbergwerk
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Kohlebergwerk errichten
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Kraftwerk errichten
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Sägewerk errichten
+STR_0265_PLANT_FOREST :{BLACK}Wald aufforsten
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Ölraffinerie errichten
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Ölbohrinsel errichten (Kann nur am Kartenrand erfolgen)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Fabrik errichten
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Stahlwerk errichten
+STR_026A_CONSTRUCT_FARM :{BLACK}Bauernhof errichten
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Eisenerzmine errichten
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Ölquellen errichten
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Bank errichten (Nur in Städten mit mehr als 1200 Einwohnern möglich)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Papiermühle errichten
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Nahrungsmittelfabrik errichten
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Druckerei errichten
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Goldmine errichten
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Bank errichten (Kann nur in Städten errichtet werden)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Holzmühle errichten (Zur Säuberung des Regenwaldes und zur Holzproduktion)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Fruchtplantage aufforsten
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Kautschukplantage aufforsten
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Wasserquelle errichten
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Wasserturm errichten (Kann nur in Städten errichtet werden)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Diamantenmine errichten
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Kupfermine errichten
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Zuckerwattewald aufforsten
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Bonbonfabrik errichten
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Batterieplantage errichten
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Colaquellen errichten
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Spielwarengeschäft errichten
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Spielwarenfabrik errichten
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Plastikbrunnen errichten
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Limonadenfabrik errichten
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Luftblasengenerator errichten
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Karamellgrube errichten
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Zuckerbergwerk errichten
+STR_0285_CAN_T_BUILD_HERE :{WHITE}Kann {STRING} hier nicht bauen...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...erst muss eine Stadt errichtet werden
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...pro Stadt nur einmal erlaubt
+STR_0288_PLANT_TREES :{BLACK}Bäume pflanzen
+STR_0289_PLACE_SIGN :{BLACK}Schild aufstellen
+STR_028A_RANDOM_TREES :{BLACK}Zufällige Bäume
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Bäume zufällig über die Landschaft verteilen
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Felsige Gebiete in der Landschaft platzieren
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Leuchtturm errichten
+STR_028E_PLACE_TRANSMITTER :{BLACK}Sender errichten
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Lege Wüstengebiet an.{}STRG drücken zum entfernen
+STR_CREATE_LAKE :{BLACK}Gebiet fluten.{}Auf Meereshöhe entsteht ein Gewässer
+STR_0290_DELETE :{BLACK}Löschen
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Diese Stadt vollständig löschen
+STR_0292_SAVE_SCENARIO :Szenario speichern
+STR_0293_LOAD_SCENARIO :Szenario laden
+STR_0294_QUIT_EDITOR :Editor verlassen
+STR_0295 :
+STR_0296_QUIT :Beenden
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Szenario speichern, Szenario laden, Szenariobearbeitung beenden, Beenden
+STR_0298_LOAD_SCENARIO :{WHITE}Szenario laden
+STR_0299_SAVE_SCENARIO :{WHITE}Szenario speichern
+STR_029A_PLAY_SCENARIO :{BLACK}Szenario spielen
+STR_PLAY_HEIGHTMAP :{BLACK}Reliefkarte spielen
+STR_PLAY_HEIGHTMAP_HINT :{BLACK}Ein neues Spiel mit Reliefkarte als Landschaft starten
+STR_QUIT_SCENARIO_QUERY :{YELLOW}Bist du dir sicher, dass du das Szenario verlassen willst?
+STR_029C_QUIT_EDITOR :{WHITE}Bearbeitung beenden
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...kann nur in Städten mit mehr als 1200 Einwohnern gebaut werden
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Startdatum auf 1 Jahr früher setzen
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Startdatum auf 1 Jahr später setzen
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...Brücke muss an beiden Seiten auf dem Land enden
+STR_02A1_SMALL :{BLACK}Klein
+STR_02A2_MEDIUM :{BLACK}Mittel
+STR_02A3_LARGE :{BLACK}Groß
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Stadtgröße bestimmen
+STR_02A5_TOWN_SIZE :{YELLOW}Stadtgröße:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Letzte Nachricht oder letzten Bericht anzeigen
+STR_OFF :Aus
+STR_SUMMARY :Ticker
+STR_FULL :Zeitung
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Städteverzeichnis
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Fahrzeugnamen
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Standard
+STR_02BF_CUSTOM :Eigene
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Angepasste Namen speichern
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Auswahl der Fahrzeugnamen
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Eigene Namen abspeichern
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Spieleinstellungen
+STR_02C5_DIFFICULTY_SETTINGS :Schwierigkeitsgrad
+STR_02C7_CONFIG_PATCHES :Einstellungen der Patches
+STR_NEWGRF_SETTINGS :Newgrf-Einstellungen
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Städtenamen anzeigen
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Stationsnamen anzeigen
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Schilder anzeigen
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Wegpunkte anzeigen
+STR_02D0_FULL_ANIMATION :{SETX 12}Vollständige Animation
+STR_02D2_FULL_DETAIL :{SETX 12}Vollständige Detailansicht
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Durchsichtige Gebäude
+STR_TRANSPARENT_SIGNS :{SETX 12}Durchsichtige Stationsnamen
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Gebietsinformation
+STR_02D6 :
+STR_CONSOLE_SETTING :Konsole öffnen/schließen
+STR_02D7_SCREENSHOT_CTRL_S :Screenshot (Strg-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Riesiger Screenshot (Strg-G)
+STR_02D9_ABOUT_OPENTTD :Ãœber 'OpenTTD'
+############ range ends here
+
+STR_02DB_OFF :{BLACK}aus
+STR_02DA_ON :{BLACK}an
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Subventionen anzeigen
+STR_02DD_SUBSIDIES :Subventionen
+STR_02DE_MAP_OF_WORLD :Weltkarte
+STR_EXTRA_VIEW_PORT :Zusatzansicht
+STR_SIGN_LIST :Schilderliste
+STR_02DF_TOWN_DIRECTORY :Städteverzeichnis
+STR_TOWN_POPULATION :{BLACK}Weltbevölkerung: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Ansicht {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}In Zusatzansicht
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Kopieren der Position im Hauptfenster in diese Zusatzansicht
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Aus Zusatzansicht
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Kopieren der Position dieser Zusatzansicht ins Hauptfenster
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Währung
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Währung auswählen
+STR_MEASURING_UNITS :{BLACK}Maßeinheiten
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Auswahl der Maßeinheiten
+STR_02E6_ROAD_VEHICLES :{BLACK}Fahrzeuge
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Wähle auf welcher Straßenseite der Verkehr fahren soll
+STR_02E9_DRIVE_ON_LEFT :Linksverkehr
+STR_02EA_DRIVE_ON_RIGHT :Rechtsverkehr
+STR_02EB_TOWN_NAMES :{BLACK}Städtenamen
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Wähle die Sprache für die Städtenamen aus
+
+STR_02F4_AUTOSAVE :{BLACK}Autosicherung
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Abstand zwischen den automatischen Spielesicherungen wählen
+STR_02F7_OFF :Aus
+STR_02F8_EVERY_3_MONTHS :Alle 3 Monate
+STR_02F9_EVERY_6_MONTHS :Alle 6 Monate
+STR_02FA_EVERY_12_MONTHS :Alle 12 Monate
+STR_02FB_START_A_NEW_GAME :{BLACK}Ein neues Spiel beginnen
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Ein gespeichertes Spiel laden
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Eine eigene Spielwelt / Szenario kreieren
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Einspielermodus wählen
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Mehrspielerspiel mit 2-8 Spielern wählen
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Spieleinstellungen anzeigen
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Schwierigkeitsgrad anzeigen
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Starte ein neues Spiel in einem eigenen Szenario
+STR_0304_QUIT :{BLACK}Beenden
+STR_0305_QUIT_OPENTTD :{BLACK}'OpenTTD' beenden
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...kann nur in Städten gebaut werden
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}'gemäßigte' Landschaft auswählen
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}'subarktische' Landschaft auswählen
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}'subtropische' Landschaft auswählen
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}'fantastische' Landschaft auswählen
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Errichtung und Finanzierung einer neuen Industrie
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Industrieverzeichnis
+STR_0313_FUND_NEW_INDUSTRY :Neue Industrie finanzieren
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Neue Industrie finanzieren
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...kann nur in Städten errichtet werden
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...kann nur im Regenwaldgebiet errichtet werden
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...kann nur im Wüstengebiet errichtet werden
+STR_0319_PAUSED :{YELLOW}* * ANGEHALTEN * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Screenshot ist gespeichert als '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}Screenshot misslungen!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Land für künftige Nutzung kaufen
+STR_032F_AUTOSAVE :{RED}Autosicherung
+STR_SAVING_GAME :{RED}* * SPEICHERE SPIEL * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}Speichern läuft,{}bitte warten bis beendet!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Wähle 'Ezy Street style music'-Programm
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :Englisch
+STR_TOWNNAME_FRENCH :Französisch
+STR_TOWNNAME_GERMAN :Deutsch
+STR_TOWNNAME_ADDITIONAL_ENGLISH :Englisch (Zusätzlich)
+STR_TOWNNAME_LATIN_AMERICAN :Lateinamerikanisch
+STR_TOWNNAME_SILLY :Verrückt
+STR_TOWNNAME_SWEDISH :Schwedisch
+STR_TOWNNAME_DUTCH :Niederländisch
+STR_TOWNNAME_FINNISH :Finnisch
+STR_TOWNNAME_POLISH :Polnisch
+STR_TOWNNAME_SLOVAKISH :Slovakisch
+STR_TOWNNAME_NORWEGIAN :Norwegisch
+STR_TOWNNAME_HUNGARIAN :Ungarisch
+STR_TOWNNAME_AUSTRIAN :Österreichisch
+STR_TOWNNAME_ROMANIAN :Rumänisch
+STR_TOWNNAME_CZECH :Tschechisch
+STR_TOWNNAME_SWISS :Schweizerisch
+STR_TOWNNAME_DANISH :Dänisch
+STR_TOWNNAME_TURKISH :Türkisch
+STR_TOWNNAME_ITALIAN :italienisch
+STR_TOWNNAME_CATALAN :Katalanisch
+############ end of townname region
+
+STR_CURR_GBP :Pfund (£)
+STR_CURR_USD :Dollar ($)
+STR_CURR_EUR :Euro (€)
+STR_CURR_YEN :Yen (Â¥)
+STR_CURR_ATS :Österreich. Schilling (ATS)
+STR_CURR_BEF :Belgische Franc (BEF)
+STR_CURR_CHF :Schweizer Franken (CHF)
+STR_CURR_CZK :Tschechische Kronen (CZK)
+STR_CURR_DEM :Deutsche Mark (DEM)
+STR_CURR_DKK :Dänische Kronen (DKK)
+STR_CURR_ESP :Peseta (ESP)
+STR_CURR_FIM :Finnmark (FIM)
+STR_CURR_FRF :Franc (FRF)
+STR_CURR_GRD :Griech. Drachmen (GRD)
+STR_CURR_HUF :Ungarische Forint (HUF)
+STR_CURR_ISK :Isländische Krona (ISK)
+STR_CURR_ITL :Italienische Lira (ITL)
+STR_CURR_NLG :Niederländ. Gulden (NLG)
+STR_CURR_NOK :Norwegische Kronen (NOK)
+STR_CURR_PLN :Polnische Zloty (PLN)
+STR_CURR_ROL :RumÀnische Lei (ROL)
+STR_CURR_RUR :Russische Rubel (RUR)
+STR_CURR_SIT :Slovenischer Tolar (SIT)
+STR_CURR_SEK :Schwedische Kronen (SEK)
+STR_CURR_YTL :türkische Lira (YTL)
+STR_CURR_SKK :Slowakische Krone
+STR_CURR_BRR :Brasilianischer Real
+
+STR_CURR_CUSTOM :Eigene...
+
+STR_OPTIONS_LANG :{BLACK}Sprache
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Sprache für die Oberfläche aussuchen
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Vollbild
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}OpenTTD im Vollbildmodus spielen
+
+STR_OPTIONS_RES :{BLACK}Bildschirmauflösung
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Bildschirmauflösung auswählen
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Screenshotformat
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Wähle das zu benutzende Screenshotformat aus
+
+STR_AUTOSAVE_1_MONTH :Jeden Monat
+STR_AUTOSAVE_FAILED :{WHITE}Autosicherung fehlgeschlagen
+
+STR_MONTH_JAN :Januar
+STR_MONTH_FEB :Februar
+STR_MONTH_MAR :März
+STR_MONTH_APR :April
+STR_MONTH_MAY :Mai
+STR_MONTH_JUN :Juni
+STR_MONTH_JUL :Juli
+STR_MONTH_AUG :August
+STR_MONTH_SEP :September
+STR_MONTH_OCT :Oktober
+STR_MONTH_NOV :November
+STR_MONTH_DEC :Dezember
+
+STR_HEADING_FOR_STATION :{LTBLUE}Unterwegs zu {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}Unterwegs zu {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Keine Aufträge
+STR_NO_ORDERS_VEL :{LTBLUE}Keine Aufträge, {VELOCITY}
+
+STR_PASSENGERS :Passagiere
+STR_BAGS :Säcke
+STR_TONS :Tonnen
+STR_LITERS :Liter
+STR_ITEMS :Stück
+STR_CRATES :Kisten
+STR_RES_OTHER :Andere
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Der Fahrplan kann nicht gemeinsam benutzt werden...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Kann Fahrplan nicht kopieren...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - Ende des gemeinsamen Fahrplans - -
+
+STR_TRAIN_IS_LOST :{WHITE}Zug {COMMA} findet den Weg nicht.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}Einkommen von Zug {COMMA} war letztes Jahr {CURRENCY}
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}Europäische Währungsunion!{}{}Der Euro wird einzige Währung für alltägliche Zahlungsvorgänge.
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Zug {COMMA} hat zu wenige Aufträge im Fahrplan
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}Zug {COMMA} hat einen leeren Auftrag
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}Zug {COMMA} hat doppelte Aufträge
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}Zug {COMMA} hat einen ungültigen Stationsnamen im Fahrplan
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}Fahrzeug {COMMA} hat zu wenige Aufträge im Fahrplan
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}Fahrzeug {COMMA} hat einen leeren Auftrag
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}Fahrzeug {COMMA} hat doppelte Aufträge
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}Fahrzeug {COMMA} hat einen ungültigen Stationsnamen im Fahrplan
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}Schiff {COMMA} hat zu wenige Aufträge im Fahrplan
+STR_SHIP_HAS_VOID_ORDER :{WHITE}Schiff {COMMA} hat einen leeren Auftrag
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}Schiff {COMMA} hat doppelte Aufträge
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}Schiff {COMMA} hat einen ungültigen Stationsnamen im Fahrplan
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}Flugzeug {COMMA} hat zu wenige Aufträge im Flugplan
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}Flugzeug {COMMA} hat einen leeren Auftrag
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}Flugzeug {COMMA} hat doppelte Aufträge
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}Flugzeug {COMMA} hat einen ungültigen Stationsnamen im Fahrplan
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}Zug {COMMA} kann nicht erneuert werden (Geld fehlt)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}Fahrzeug {COMMA} kann nicht erneuert werden (Geld fehlt)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}Schiff {COMMA} kann nicht erneuert werden (Geld fehlt)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}Flugzeug {COMMA} kann nicht erneuert werden (Geld fehlt)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}Zug {COMMA} nach Ersetzung zu lang
+
+STR_CONFIG_PATCHES :{BLACK}Einstellungen der Patches
+STR_CONFIG_PATCHES_TIP :{BLACK}Einstellungen der Patches
+STR_CONFIG_PATCHES_CAPTION :{WHITE}Einstellungen der Patches
+
+STR_CONFIG_PATCHES_OFF :Aus
+STR_CONFIG_PATCHES_ON :An
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Zeige Fahrzeuggeschwindigkeit in der Statusleiste: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Erlaube das Bauen an Hängen und Küsten: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Aktiviere realistische Einzugsgebiete: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Erlaube die Entfernung von Industrien, weiteren Straßen usw.: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Erlaube das Bauen von sehr langen Zügen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Realistische Zugbeschleunigung aktivieren: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Verbiete Zügen und Schiffen 90 Grad Kurven: {ORANGE}{STRING} {LTBLUE} (erfordert NWF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Bahnhöfe vereinigen, die nebeneinander gebaut werden: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Verlasse die Station, wenn eine Fracht vollgeladen ist: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Verbessertes Beladeverfahren nutzen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GRADUAL_LOADING :{LTBLUE}Fahrzeuge schrittweise beladen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Inflation: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Liefere Fracht nur, wenn die Station diese annimmt: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Erlaube das Bauen von sehr langen Brücken: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Erlaube "Gehe zum Depot"-Aufträge im Fahrplan: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Erlaube das Bauen von rohstoffproduzierenden Industrien: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Erlaube mehrere gleichartige Industrien pro Stadt: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Gleiche Industrien können nahe beieinander gebaut werden: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Lange Datumsanzeige in der Statusleiste (links unten): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Zeige Signale auf der selben Seite wie den Straßenverkehr: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Zeige Firmenfinanzen am Ende des Jahres: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}TTDPatch kompatibles "Nonstop"-Verhalten: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Fahrzeugwarteschlange (mit Ãœberlagerung): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Karte scrollen, wenn die Maus am Bildrand anstößt: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Bestechen der Stadtverwaltung erlauben: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Ungleichmäßige Bahnhöfe: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Neue globale Wegfindung für alle Fahrzeuge: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FREIGHT_TRAINS :{LTBLUE}Frachtgewicht erhöhen um schwere Züge zu simulieren: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Kleine Flughäfen immer erlauben: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Warnung wenn der Zug verloren ist: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Fahrpläne prüfen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :nein
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :ja, aber ohne gestoppte Fahrzeuge
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :für alle Fahrzeuge
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Warnung anzeigen, wenn ein Zug negative Einnahmen hat: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Fahrzeuge veralten nie: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Fahrzeug erneuern, wenn es veraltet
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Erneuere Fahrzeug {ORANGE}{STRING}{LTBLUE} Monate vor/nach Maximalalter
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Minimaler Kontostand für automatisches Erneuern: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Dauer der Fehlermeldungen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Zeige die Einwohnerzahl der Stadt im Label: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Unsichtbare Bäume (bei transparenten Gebäuden): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Land Generator: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :Original
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis
+STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}Maximaler Abstand der Ölraffinerien vom Kartenrand{ORANGE}{STRING}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Schneegrenze auf: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN :{LTBLUE}Rauhheit (nur TerraGenesis) : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Sehr sanft
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH :Sanft
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH :Rauh
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :Sehr rauh
+STR_CONFIG_PATCHES_TREE_PLACER :{LTBLUE}Baumplazierungsalgorithmus: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TREE_PLACER_NONE :Keiner
+STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL :Original
+STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED :Verbessert
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION :{LTBLUE}Drehung der Reliefkarte: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :links
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE :rechts
+STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT :{LTBLUE}Höhenstufe der Karte eines flachen Szenarios: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Maximale Stationsgröße: {ORANGE}{STRING} {RED}Achtung: Große Werte verlangsamen das Spiel
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Hubschrauber auf Helipads automatisch warten: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Landschaftsbau-Toolbar an Eisenbahn/Straßen/Hafen/Flughafen-Toolbar binden: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Beim Verschieben mit der Maus die Ansicht in die Gegenrichtung verschieben: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Zeige Tooltip mit Abmessungen bei verschiedenen Bauwerkzeugen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Anzeigen der Firmenlackierungen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES_NONE :Keine
+STR_CONFIG_PATCHES_LIVERIES_OWN :Eigene Firma
+STR_CONFIG_PATCHES_LIVERIES_ALL :Alle Firmen
+STR_CONFIG_PATCHES_PREFER_TEAMCHAT :{LTBLUE}Bevorzuge Teamchat mit <ENTER>: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Maximale Anzahl der Züge pro Spieler: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Maximale Anzahl der Straßenfahrzeuge pro Spieler: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}Maximale Anzahl der Flugzeuge pro Spieler: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}Maximale Anzahl der Schiffe pro Spieler: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Züge für den Computer abschalten: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Straßenfahrzeuge für den Computer abschalten: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Flugzeuge für den Computer abschalten: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Schiffe für den Computer abschalten: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Aktiviere neue KI (alpha): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Erlaube KI im Mehrspielermodus (experimentell): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Vorgegebener Wartungsintervall für Züge: {ORANGE}{STRING} Tage
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Vorgegebener Wartungsintervall für Züge: {ORANGE}abgeschaltet
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Vorgegebener Wartungsintervall für Straßenfahrzeuge: {ORANGE}{STRING} Tage
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Vorgegebener Wartungsintervall für Fahrzeuge: {ORANGE}abgeschaltet
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Vorgegebener Wartungsintervall für Flugzeuge: {ORANGE}{STRING} Tage
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Vorgegebener Wartungsintervall für Flugzeuge: {ORANGE}abgeschaltet
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Vorgegebener Wartungsintervall für Schiffe: {ORANGE}{STRING} Tage
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Vorgegebener Wartungsintervall für Schiffe: {ORANGE}abgeschaltet
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Wartung deaktivieren, wenn Pannen abgeschaltet: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Berücksichtige Waggonhöchstgeschwindigkeit: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}Deaktiviere elektrifizierte Strecken: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Farbige Nachrichten erscheinen ab: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Startdatum: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}Spiel beenden: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Feinere Wirtschaft aktivieren (mehrere, kleinere Veränderungen)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Erlaube Anteile an anderen Firmen zu kaufen
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Errichte Signale alle {ORANGE}{STRING} Felder beim Ziehen mit der Maus
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Position der Werkzeugleiste: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Links
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Mitte
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Rechts
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Fenster schnappen aneinander, wenn näher als: {ORANGE}{STRING} px
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Fenster schnappen aneinander, wenn näher als: {ORANGE}ausgeschaltet
+
+STR_CONFIG_PATCHES_GUI :{BLACK}Oberfläche
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Konstruktion
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Fahrzeuge
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Bahnhöfe
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Wirtschaft
+STR_CONFIG_PATCHES_AI :{BLACK}Gegenspieler
+
+STR_CONFIG_PATCHES_DISABLED :ausgeschaltet
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Einstellungswert ändern
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Einige oder alle dieser Standardwartungsintervalle sind inkompatibel mit den gewählten Einstellungen! 5-90% und 30-800 Tage sind gültig.
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}BenutzeYAPF für Schiffe: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}Benutze YAPF für Fahrzeuge: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}Benutze YAPF für Züge: {ORANGE}{STRING}
+
+STR_TEMPERATE_LANDSCAPE :Gemäßigt
+STR_SUB_ARCTIC_LANDSCAPE :Subarktisch
+STR_SUB_TROPICAL_LANDSCAPE :Subtropisch
+STR_TOYLAND_LANDSCAPE :Fantastisch
+
+STR_CHEATS :{WHITE}Cheats
+STR_CHEATS_TIP :{BLACK}Kontrollfelder zeigen, ob du diesen Cheat schonmal benutzt hast.
+STR_CHEATS_WARNING :{BLACK}Achtung! Du bist im Begriff, deine Mitspieler zu betrügen. Denke daran, dass dies niemals vergessen werden wird.
+STR_CHEAT_MONEY :{LTBLUE}Kontostand um {CURRENCY64} erhöhen
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Folgenden Spieler steuern: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Mächtigeres Abrisswerkzeug: {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Tunnel dürfen sich kreuzen {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Bauen im Pausenmodus: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Flugzeuge stürzen auf kleinen Flughäfen nicht häufiger ab: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Wechsle Klima: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Ändere Datum: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}Aktiviere Veränderung der Produktionswerte: {ORANGE}{STRING}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}Fahre zu {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Fahre zu {WAYPOINT}, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :Fahre über {WAYPOINT}
+STR_GO_NON_STOP_TO_WAYPOINT :Fahre ohne Halt über {WAYPOINT}
+
+STR_WAYPOINTNAME_CITY :Wegpunkt {TOWN}
+STR_WAYPOINTNAME_CITY_SERIAL :Wegpunkt {TOWN} #{COMMA}
+STR_LANDINFO_WAYPOINT :Wegpunkt
+
+STR_WAYPOINT :{WHITE}Wegpunkt
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Wegpunkttyp auswählen
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}Wegpunktename ändern
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Kann Wegpunktname nicht ändern...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Ändere Schiene in einen Wegpunkt
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Kann Wegpunkt hier nicht bauen...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Kann Wegpunkt hier nicht entfernen...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Bauen von Schienen unter Verwendung des Autoschienenmodus
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}...in diesem Szenario gibt es keine Stadt
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}Soll wirklich eine zufällige Landschaft erzeugt werden?
+STR_MANY_RANDOM_TOWNS :{BLACK}Viele zufällige Städte
+STR_RANDOM_TOWNS_TIP :{BLACK}Bedecke die Karte mit zufällig platzierten Städten
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Viele zufällige Industrien
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Bedecke die Karte mit zufällig platzierten Industrien
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Kann keine Industrie erzeugen...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Öffne die Landschaftsbau-Toolbar, um Land zu senken/heben, Bäume zu pflanzen, etc.
+STR_LANDSCAPING_TOOLBAR :{WHITE}Landschaftsbau
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Land ausgleichen
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Zufällige Baumart
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}Zufällige Baumart pflanzen
+
+STR_CANT_BUILD_CANALS :{WHITE}Kann hier keinen Kanal bauen...
+STR_BUILD_CANALS_TIP :{BLACK}Kanal bauen
+STR_LANDINFO_CANAL :Kanal
+
+STR_CANT_BUILD_LOCKS :{WHITE}Kann hier keine Schleuse bauen...
+STR_BUILD_LOCKS_TIP :{BLACK}Schleusen bauen
+STR_LANDINFO_LOCK :Schleuse
+
+STR_BUOY_IS_IN_USE :{WHITE}... Boje wird genutzt!
+
+STR_LANDINFO_COORDS :{BLACK}Koordinaten: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Kann den Teil des Bahnhofs nicht entfernen...
+STR_CANT_CONVERT_RAIL :{WHITE}Kann Gleistyp hier nicht verändern...
+STR_CONVERT_RAIL_TIP :{BLACK}Konvertiere / Erweitere den Typ des Gleises
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Lok hierher ziehen, um den ganzen Zug zu verkaufen
+
+STR_DRAG_DROP :{BLACK}Drag & Drop
+STR_STATION_DRAG_DROP :{BLACK}Bahnhof mittels 'Drag & Drop' bauen
+STR_SELECT_STATION_CLASS_TIP :{BLACK}Wähle eine Stationsart zum anzeigen
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Wähle die Stationsart aus, die gebaut werden soll
+
+STR_FAST_FORWARD :{BLACK}Spiel vorspulen
+STR_MESSAGE_HISTORY :{WHITE}Vorhergehende Nachrichten
+STR_MESSAGE_HISTORY_TIP :{BLACK}Eine Liste der aktuellen Nachrichten
+STR_MESSAGES_DISABLE_ALL :{BLACK}Alles deaktivieren
+STR_MESSAGES_ENABLE_ALL :{BLACK}Alles aktivieren
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Kohlebergwerk errichten
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Wald aufforsten
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Ölbohrinsel errichten
+STR_CONSTRUCT_FARM_TIP :{BLACK}Bauernhof errichten
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Kupfermine errichten
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Nach Öl bohren
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Goldmine errichten
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Diamantenmine errichten
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Eisenerzmine errichten
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Fruchtplantage aufforsten
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Kautschukplantage aufforsten
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Wasserquelle errichten
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Zuckerwattewald anbauen
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}Batteriefarm anbauen
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Nach Cola bohren
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Plastikbrunnen anbauen
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Luftblasengenerator errichten
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Karamellgrube anbauen
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Zuckermine errichten
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Industrien
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA}% transportiert)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA}%/{COMMA}% transportiert)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}...zu nah an einer anderen Industrie
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Umrüstung des Zuges zur Beförderung anderer Frachten
+STR_RAIL_REFIT_VEHICLE :{BLACK}Zug umrüsten
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Wähle die Frachten aus, die der Zug befördern soll
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Umrüstung des Zuges auf die ausgewählte Frachtart
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Kann den Zug nicht umrüsten...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Wartungsintervalle in Prozent: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Produktion ändern
+
+TEMP_AI_IN_PROGRESS :{WHITE}Willkommen bei der neuen KI. Erwarte Fehler. Falls du einen findest, mache einen Screenshot und berichte im Forum. Viel Spaß!
+TEMP_AI_ACTIVATED :{WHITE}Achtung: Die neue KI ist noch im Alpha-Stadium. Derzeit funktionieren nur Straßenfahrzeuge.
+TEMP_AI_MULTIPLAYER :{WHITE}Warnung: Diese Funktion ist noch experimentell. Bitte melde jedwede Probleme damit an truelight@openttd.org.
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Mehrspieler
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Spielername:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}Mit diesem Namen identifizieren dich andere Spieler
+STR_NETWORK_CONNECTION :{BLACK}Verbindung:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Wähle zwischen Internet oder LAN-Verbindung aus
+
+STR_NETWORK_START_SERVER :{BLACK}Server Starten
+STR_NETWORK_START_SERVER_TIP :{BLACK}Einen eigenen Server starten
+
+STR_NETWORK_GAME_NAME :{BLACK}Name
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Name des Spiels
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Sprache, Server-Version, etc.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Ein Spiel der Liste durch Anklicken wählen
+
+STR_NETWORK_FIND_SERVER :{BLACK}Server suchen
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Netzwerk nach einem Server durchsuchen
+STR_NETWORK_ADD_SERVER :{BLACK}Server hinzufügen
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Fügt einen Server zu der Liste von Servern hinzu, die immer nach laufenden Spielen kontrolliert werden.
+STR_NETWORK_ENTER_IP :{BLACK}IP Adresse des Servers eingeben
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Teilnehmer
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Teilnehmer anwesend / max.
+STR_NETWORK_GAME_INFO :{SILVER}SPIEL-INFO
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Teilnehmer: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Sprache: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Landschaft: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Kartengröße: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}Serverversion: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}Serveradresse: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Startdatum: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Aktuelles Datum: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Passwortgeschützt!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}SERVER OFFLINE
+STR_NETWORK_SERVER_FULL :{SILVER}SERVER VOLL
+STR_NETWORK_VERSION_MISMATCH :{SILVER}Versionskonflikt festgestellt
+STR_NETWORK_GRF_MISMATCH :{SILVER}NEWGRF KONFLIKT
+
+STR_NETWORK_JOIN_GAME :{BLACK}Spiel betreten
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}Neues Spiel beginnen
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Spielname:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}Der Name des Spieles wird anderen Spielern im Mehrspielerdialog angezeigt
+STR_NETWORK_SET_PASSWORD :{BLACK}Passwort setzen
+STR_NETWORK_PASSWORD_TIP :{BLACK}Vergebe ein Passwort, um zu verhindern, dass unbefugte Leute beitreten können
+STR_NETWORK_SELECT_MAP :{BLACK}Karte auswählen:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}Welche Karte möchtest du spielen?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}Max. Teilnehmeranzahl:
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Wählt die max. Anzahl an Teilnehmern aus. Nicht alle Slots müssen belegt werden.
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :LAN
+STR_NETWORK_INTERNET :Internet
+STR_NETWORK_LAN_INTERNET :LAN / Internet
+STR_NETWORK_INTERNET_ADVERTISE :Internet (ankündigen)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 Spieler
+STR_NETWORK_1_PLAYERS :1 Spieler
+STR_NETWORK_2_PLAYERS :2 Spieler
+STR_NETWORK_3_PLAYERS :3 Spieler
+STR_NETWORK_4_PLAYERS :4 Spieler
+STR_NETWORK_5_PLAYERS :5 Spieler
+STR_NETWORK_6_PLAYERS :6 Spieler
+STR_NETWORK_7_PLAYERS :7 Spieler
+STR_NETWORK_8_PLAYERS :8 Spieler
+STR_NETWORK_9_PLAYERS :9 Spieler
+STR_NETWORK_10_PLAYERS :10 Spieler
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}Max. Firmenanzahl:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Begrenzt den Server auf eine gewisse Anzahl an Firmen
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}Max. Beobachteranzahl:
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Begrenzt den Server auf eine gewisse Anzahl an Beobachter
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Gesprochene Sprachen:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Damit andere Spieler wissen, welche Sprache auf diesem Server gesprochen wird.
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}Spiel beginnen
+STR_NETWORK_START_GAME_TIP :{BLACK}Startet ein neues Mehrspielerspiel auf einer Zufallskarte oder einem Szenario
+STR_NETWORK_LOAD_GAME :{BLACK}Spiel Laden
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Lädt ein gespeichertes Spiel
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Egal
+STR_NETWORK_LANG_ENGLISH :Englisch
+STR_NETWORK_LANG_GERMAN :Deutsch
+STR_NETWORK_LANG_FRENCH :Französisch
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Mehrspielerlobby
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Spieleintritt vorbereiten: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}Eine Liste aller Firmen, die sich im Spiel befinden. Du kannst einer Firma beitreten oder eine eigene Firma gründen, sofern ein Platz frei ist.
+STR_NETWORK_NEW_COMPANY :{BLACK}Neues Unternehmen
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Ein neues Unternehmen gründen
+STR_NETWORK_SPECTATE_GAME :{BLACK}Beim Spiel zusehen
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Als Zuschauer dem Spiel zusehen
+STR_NETWORK_JOIN_COMPANY :{BLACK}Firma beitreten
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Beim Verwalten der Firma helfen
+STR_NETWORK_REFRESH :{BLACK}Aktualisieren
+STR_NETWORK_REFRESH_TIP :{BLACK}Aktualisiert die Serverinformationen
+
+STR_NETWORK_COMPANY_INFO :{SILVER}Firmenprofil
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Firmenname: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}Gründung: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}Firmenwert: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Kontostand: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Einkommen (letzes Jahr): {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}Leistung: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}Fahrzeuge: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Stationen: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Spieler: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}Verbinden...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) Verbinden...
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Autorisieren...
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Warten...
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Herunterladen der Karte..
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Spieldaten verarbeiten...
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) Registrieren...
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Spielinformationen holen...
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Firmeninformationen holen...
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} Teilnehmer vor dir
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} KB bisher heruntergeladen
+
+STR_NETWORK_DISCONNECT :{BLACK}Trennen
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Gib an, wieviel Geld du geben möchtest
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Server ist geschützt. Gib das Passwort ein
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Firma ist geschützt! Passwort eingeben
+STR_NETWORK_CLIENT_LIST :{WHITE}Teilnehmerliste
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE}Keine Netzwerkschnittstellen gefunden oder ohne ENABLE_NETWORK kompiliert
+STR_NETWORK_ERR_NOSERVER :{WHITE}Keine Netzwerkspiele gefunden
+STR_NETWORK_ERR_NOCONNECTION :{WHITE}Der Server antwortete nicht auf die Anfrage
+STR_NETWORK_ERR_DESYNC :{WHITE}Synchronisation des Netzwerkspiels fehlgeschlagen
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE}Verbindung zum Netzwerkspiel verloren
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE}Spielstand konnte nicht vom Server geladen werden
+STR_NETWORK_ERR_SERVER_START :{WHITE}Server konnte nicht gestartet werden
+STR_NETWORK_ERR_CLIENT_START :{WHITE}Verbindung konnte nicht hergestellt werden
+STR_NETWORK_ERR_TIMEOUT :{WHITE}Verbindung #{NUM} abgelaufen
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE}Protokollfehler: Die Verbindung musste getrennt werden
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE}Ihre Version entspricht nicht der Serverversion
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE}Falsches Passwort
+STR_NETWORK_ERR_SERVER_FULL :{WHITE}Der Server ist voll
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE}Du bist von diesem Server verbannt
+STR_NETWORK_ERR_KICKED :{WHITE}Du wurdest vom Server gekickt
+STR_NETWORK_ERR_CHEATER :{WHITE}Mogeln ist auf diesem Server nicht erlaubt
+
+STR_NETWORK_ERR_LEFT :hat das Spiel verlassen
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :Allgemeiner Fehler
+STR_NETWORK_ERR_CLIENT_DESYNC :Synchronisationsfehler
+STR_NETWORK_ERR_CLIENT_SAVEGAME :Karte konnte nicht geladen werden.
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :Verbindung verloren
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :Protokollfehler
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :nicht authorisiert
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :Unerwartetes Paket empfangen
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :Falsche Version
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :Name wird bereits verwendet
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :Falsches Spielpasswort
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :Falsche-SpielerID in DoCommand (Verarbeitungsfehler)
+STR_NETWORK_ERR_CLIENT_KICKED :gekickt
+STR_NETWORK_ERR_CLIENT_CHEATER :versuchte einen Cheat zu nutzen
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :Server voll
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :hat das Spiel betreten
+STR_NETWORK_GIVE_MONEY :gab dir etwas Geld ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :Du hast {STRING} etwas Geld gegeben ({CURRENCY})
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Team] :
+STR_NETWORK_CHAT_COMPANY :[Team] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Team] An {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[Privat] :
+STR_NETWORK_CHAT_CLIENT :[Privat] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[Privat] An {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[Alle] :
+STR_NETWORK_CHAT_ALL :[Alle] {STRING}: {GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :hat seinen Namen geändert zu
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE}Der Server hat das Spiel beendet
+STR_NETWORK_SERVER_REBOOT :{WHITE}Der Server startet neu...{}Bitte warten...
+
+STR_NETWORK_SERVER :Server
+STR_NETWORK_CLIENT :Teilnehmer
+STR_NETWORK_SPECTATORS :Zuschauer
+
+STR_NETWORK_CLIENTLIST_NONE :(keiner)
+STR_NETWORK_CLIENTLIST_KICK :Kicken
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Geld geben
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Mit allen sprechen
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Mit eigener Firma sprechen
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Private Nachricht
+
+
+STR_NETWORK_SEND :{BLACK}Senden
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}X-Abmessung der Karte: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Y-Abmessung der Karte: {ORANGE}{STRING}
+
+
+##### PNG-MAP-Loader
+
+STR_PNGMAP_ERROR :{WHITE}Kann Landschaft nicht aus PNG-Datei laden...
+STR_PNGMAP_ERR_FILE_NOT_FOUND :{WHITE}...Datei nicht gefunden.
+STR_PNGMAP_ERR_IMAGE_TYPE :{WHITE}...kann Grafik-Typ nicht umwandeln. 8- oder 24-bit PNG Datei erforderlich.
+STR_PNGMAP_ERR_MISC :{WHITE}...irgend etwas ging schief. Sorry. (Vielleicht eine kaputte Datei)
+
+STR_BMPMAP_ERROR :{WHITE}Kann Landschaft nicht aus BMP-Datei laden...
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}...kann Bildtyp nicht umwandeln.
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Kosten: {CURRENCY}
+STR_0801_COST :{RED}Kosten: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Einnahmen: {CURRENCY}
+STR_0803_INCOME :{GREEN}Einnahmen: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Umladen: {CURRENCY}
+STR_FEEDER :{YELLOW}Umladen: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Geschätzte Kosten: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Geschätzte Einnahmen: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Kann das Land nicht anheben...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Kann das Land nicht absenken...
+STR_080A_ROCKS :Gebirge
+STR_080B_ROUGH_LAND :Unebenes Land
+STR_080C_BARE_LAND :Kahles Land
+STR_080D_GRASS :Gras
+STR_080E_FIELDS :Felder
+STR_080F_SNOW_COVERED_LAND :Schneebedecktes Land
+STR_0810_DESERT :Wüste
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Das Land neigt sich in die falsche Richtung
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Unmögliche Gleisverbindung
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}Die Ausschachtung würde den Tunnel zerstören
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Ist bereits auf Meereshöhe
+STR_1004_TOO_HIGH :{WHITE}Zu hoch
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Keine geeigneten Gleise
+STR_1007_ALREADY_BUILT :{WHITE}...ist bereits gebaut
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Gleise müssen erst entfernt werden
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Gleis- / Bahnhofsbau
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Bau elektrifizierter Strecken
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Einschienenbahnbau
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}Magnetschwebebahnbau
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Eisenbahnbrücke auswählen
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Kann hier kein Zugdepot bauen...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Kann hier keinen Bahnhof bauen...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Kann hier kein Signal aufstellen...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Kann hier keine Gleise legen...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Gleise können nicht abgerissen werden...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Kann die Signale hier nicht entfernen...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Zugdepotausrichtung
+STR_1015_RAILROAD_CONSTRUCTION :Eisenbahnbau
+STR_TOOLB_ELRAIL_CONSTRUCTION :Bau elektrifizierter Strecken
+STR_1016_MONORAIL_CONSTRUCTION :Einschienenbahnbau
+STR_1017_MAGLEV_CONSTRUCTION :Magnetschwebebahnbau
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Gleise legen
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Zugdepot bauen (zum Bau und zur Wartung von Zügen)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Bahnhof bauen
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Signale errichten
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Eisenbahnbrücke bauen
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Eisenbahntunnel bauen
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Umschalter für Bau/Abriss von Gleisen und Signalen
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Brückenauswahl - klicke auf die gewünschte Brücke, um sie zu bauen
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Ausrichtung des Zugdepots auswählen
+STR_1021_RAILROAD_TRACK :Gleis
+STR_1023_RAILROAD_TRAIN_DEPOT :Zugdepot
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...Gelände gehört jemand anderem
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :Gleis mit normalen Signalen
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :Gleis mit Vorsignalen
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :Gleis mit Ausfahrsignalen
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :Gleis mit kombinierten Vor-/Ausfahrsignalen
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Straße muss erst entfernt werden
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Straßenarbeiten sind im Gange
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Straßenbau
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Brücke wählen
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Kann hier keine Straße bauen...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Kann diese Straße nicht entfernen...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Fahrzeugdepot-Ausr.
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Kann Fahrzeugdepot hier nicht bauen...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Kann Busbahnhof nicht bauen...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Kann Lkw-Ladeplatz nicht bauen...
+STR_180A_ROAD_CONSTRUCTION :Straßenbau
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Straße bauen
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Fahrzeugdepot bauen (zum Bau und zur Wartung von Fahrzeugen)
+STR_180D_BUILD_BUS_STATION :{BLACK}Busbahnhof bauen
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Lkw-Ladeplatz bauen
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Straßenbrücke bauen
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Straßentunnel bauen
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Zwischen Bau/Abriss der Straße umschalten
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Ausrichtung des Fahrzeugdepots wählen
+STR_1814_ROAD :Straße
+STR_1815_ROAD_WITH_STREETLIGHTS :Straße mit Laternen
+STR_1816_TREE_LINED_ROAD :Straße mit Bäumen
+STR_1817_ROAD_VEHICLE_DEPOT :Fahrzeugdepot
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :Bahnübergang
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Städte
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Gebäude muss erst abgerissen werden
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}Bevölkerung: {ORANGE}{COMMA}{BLACK} Häuser: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Stadt umbenennen
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Die Stadt kann nicht umbenannt werden...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}Die Stadtverwaltung von {TOWN} erteilt keine Genehmigung
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Städtenamen - klicke auf den Namen, um die Stadt anzuzeigen
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Ansicht auf Stadt zentrieren
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Stadt umbenennen
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passagiere letzten Monat: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Postsäcke letzten Monat: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Hohes Geschäftshaus
+STR_2010_OFFICE_BLOCK :Geschäftshaus
+STR_2011_SMALL_BLOCK_OF_FLATS :Kleines Wohnhaus
+STR_2012_CHURCH :Kirche
+STR_2013_LARGE_OFFICE_BLOCK :Großes Geschäftshaus
+STR_2014_TOWN_HOUSES :Stadthaus
+STR_2015_HOTEL :Hotel
+STR_2016_STATUE :Statue
+STR_2017_FOUNTAIN :Springbrunnen
+STR_2018_PARK :Park
+STR_2019_OFFICE_BLOCK :Geschäftshaus
+STR_201A_SHOPS_AND_OFFICES :Läden und Büros
+STR_201B_MODERN_OFFICE_BUILDING :Modernes Geschäftshaus
+STR_201C_WAREHOUSE :Kaufhaus
+STR_201D_OFFICE_BLOCK :Geschäftshaus
+STR_201E_STADIUM :Stadion
+STR_201F_OLD_HOUSES :Alte Häuser
+STR_2020_LOCAL_AUTHORITY :{BLACK}Stadtverwaltung
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Zeige Einzelheiten der Stadtverwaltung
+STR_2022_LOCAL_AUTHORITY :{WHITE}Stadtverwaltung {TOWN}
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Bewertung der Transportfirma:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Subventionen
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Subventionsangebot für:
+STR_2027_FROM_TO :{ORANGE}{STRING} von {STRING} nach {STRING}
+STR_2028_BY :{YELLOW} (bis {DATE_SHORT})
+STR_202A_NONE :{ORANGE}Keine
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Bereits vergebene Subventionen:
+STR_202C_FROM_TO :{ORANGE}{STRING} von {STATION} nach {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, bis {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}Subventionsangebot abgelaufen:{}{}{STRING} von {STRING} nach {STRING} wird nicht mehr subventioniert.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Subventionsende: {}{}{STRING} Dienstleistung von {STATION} nach {STATION} wird nicht mehr subventioniert.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Subventionsangebot {}{}Erster {STRING}transport von {STRING} nach {STRING} wird ein Jahr von der Stadtverwaltung subventioniert!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subvention wird vergeben an {COMPANY}!{}{}{STRING}transport von {STATION} nach {STATION} bringt im nächsten Jahr einen 50% höheren Frachtpreis!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subvention wird vergeben an {COMPANY}!{}{}{STRING}transport von {STATION} nach {STATION} bringt im nächsten Jahr den doppelten Frachtpreis!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subvention wird vergeben an {COMPANY}!{}{}{STRING}transport von {STATION} nach {STATION} bringt im nächsten Jahr den dreifachen Frachtpreis!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subvention wird vergeben an {COMPANY}!{}{}{STRING}transport von {STATION} nach {STATION} bringt im nächsten Jahr den vierfachen Frachtpreis!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}Die Stadtverwaltung {TOWN} erlaubt nicht den Bau eines weiteren Flughafens in der Stadt
+STR_2036_COTTAGES :Landhaus
+STR_2037_HOUSES :Haus
+STR_2038_FLATS :Wohnhaus
+STR_2039_TALL_OFFICE_BLOCK :Hohes Geschäftshaus
+STR_203A_SHOPS_AND_OFFICES :Läden und Büros
+STR_203B_SHOPS_AND_OFFICES :Läden und Büros
+STR_203C_THEATER :Theater
+STR_203D_STADIUM :Stadion
+STR_203E_OFFICES :Büros
+STR_203F_HOUSES :Häuser
+STR_2040_CINEMA :Kino
+STR_2041_SHOPPING_MALL :Einkaufszentrum
+STR_2042_DO_IT :{BLACK}Tu es
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}Liste der verfügbaren Handlungen in dieser Stadt - klicke hier für Einzelheiten
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Ausführung der markierten Handlung
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Verfügbare Handlungen:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Kleine Werbekampagne
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Mittlere Werbekampagne
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Große Werbekampagne
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Straßenreparaturen des Ortes finanzieren
+STR_204A_BUILD_STATUE_OF_COMPANY :Statue des Firmeneigentümers finanzieren
+STR_204B_FUND_NEW_BUILDINGS :Neue Gebäude finanzieren
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Exklusive Transportrechte kaufen
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Die Stadtverwaltung bestechen
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW}Führen Sie im Ort eine kleine Werbekampagne durch, um mehr Passagier- und Frachtaufträge für das Unternehmen zu gewinnen.{}Kosten: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW}Führen Sie im Ort eine mittlere Werbekampagne durch, um mehr Passagier- und Frachtaufträge für das Unternehmen zu gewinnen.{}Kosten: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW}Führen Sie im Ort eine große Werbekampagne durch, um mehr Passagier- und Frachtaufträge für das Unternehmen zu gewinnen.{}Kosten: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW}Finanzieren Sie die örtlichen Straßenreparaturen. Der Straßenverkehr wird bis zu 6 Monate beeinträchtigt.{}Kosten: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW}Errichten Sie eine Statue in Ehre an den Transporteigentümer.{}Kosten: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW}Finanzieren Sie den Bau kommerzieller Gebäude im Ort.{}Kosten: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW}Kaufen Sie für 1 Jahre die exklusiven Transportrechte der Stadt. Die Stadtverwaltung erlaubt nur Passagier- und Frachttransporte Ihres Unternehmens.{}Kosten: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW}Bestechen Sie die Stadtverwaltung, um Ihre Bewertung zu verbessern. Dabei riskieren Sie allerdings eine harte Strafe, falls Sie ertappt werden.{}Kosten: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}Verkehrschaos in {TOWN}!{}{}Straßensanierungsprogramm finanziert durch {COMPANY} wird 6 Monate lang Verzögerungen im Verkehr bewirken!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (im Bau)
+STR_2059_IGLOO :Iglu
+STR_205A_TEPEES :Zelt
+STR_205B_TEAPOT_HOUSE :Teekannenhaus
+STR_205C_PIGGY_BANK :Sparschwein
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN} {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Landschaftsbau
+STR_2800_PLANT_TREES :Bäume pflanzen
+STR_2801_PLACE_SIGN :Schild aufstellen
+STR_2802_TREES :{WHITE}Bäume
+STR_2803_TREE_ALREADY_HERE :{WHITE}...hier sind bereits Bäume
+STR_2804_SITE_UNSUITABLE :{WHITE}...ungeeignetes Gelände
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Baum kann hier nicht gepflanzt werden...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...zu viele Schilder
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Schild kann hier nicht aufgestellt werden...
+STR_280A_SIGN :Schild
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Schildtext ändern
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Kann Schildnamen nicht ändern...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Wähle die zu pflanzende Baumart
+STR_280E_TREES :Bäume
+STR_280F_RAINFOREST :Regenwald
+STR_2810_CACTUS_PLANTS :Kakteen
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Bahnhof bauen
+STR_3001_AIRPORT_SELECTION :{WHITE}Flughafen bauen
+STR_3002_ORIENTATION :{BLACK}Ausrichtung
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Anzahl der Gleise
+STR_3004_PLATFORM_LENGTH :{BLACK}Bahnsteiglänge
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Zu nah an einem anderen Bahnhof
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Grenzt an mehr als eine vorhandene Station/Ladeplatz
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}Zu viele Stationen/Ladeplätze im Stadtgebiet
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}Zu viele Stationen/Ladeplätze im Umkreis
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Zu viele Busbahnhöfe
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}Zu viele Lkw-Ladeplätze
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Stationen/Ladeplätze liegen zu dicht beisammen
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Bahnhof muss erst abgerissen werden
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Zu dicht an einem anderen Flughafen
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Flughafen muss erst abgerissen werden
+
+STR_3030_RENAME_STATION_LOADING :Station/Ladeplatz umbenennen
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Kann die Station nicht umbenennen...
+STR_3032_RATINGS :{BLACK}Einschätzung
+STR_3033_ACCEPTS :{BLACK}Akzeptiert
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}Örtliche Bewertung der Transportunternehmen:
+
+############ range for rating starts
+STR_3035_APPALLING :Furchtbar
+STR_3036_VERY_POOR :Sehr schlecht
+STR_3037_POOR :Schlecht
+STR_3038_MEDIOCRE :Mittelmäßig
+STR_3039_GOOD :Gut
+STR_303A_VERY_GOOD :Sehr gut
+STR_303B_EXCELLENT :Ausgezeichnet
+STR_303C_OUTSTANDING :Hervorragend
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} akzeptiert keine {STRING} mehr
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} akzeptiert keine {STRING} oder {STRING} mehr
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} akzeptiert jetzt {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} akzeptiert jetzt {STRING} und {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Busbahnhof-Ausr.
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Lkw-Ladeplatz-Ausr.
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Der Busbahnhof muss erst abgerissen werden
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Der Lkw-Ladeplatz muss erst abgerissen werden
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Haltestelle{P "" n}
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Keine -
+STR_304B_SITE_UNSUITABLE :{WHITE}...Gelände ungeeignet
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Zu dicht an einem anderen Hafen
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Hafen muss erst entfernt werden
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Bahnhofsausrichtung auswählen
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Anzahl der Bahnsteige wählen
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Bahnsteiglänge wählen
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Busbahnhofsausrichtung wählen
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Ladeplatzausrichtung wählen
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Ansicht auf die Station zentrieren
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Stationsbewertung anzeigen
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Name der Station ändern
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Zeige Liste der akzeptierten Frachten
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Stationsnamen - Klicke auf den Namen, um die Station anzuzeigen
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Wähle die Größe/Art des Flughafens
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :Bahnhof
+STR_305F_AIRCRAFT_HANGAR :Flugzeughangar
+STR_3060_AIRPORT :Flughafen
+STR_3061_TRUCK_LOADING_AREA :Lkw-Ladeplatz
+STR_3062_BUS_STATION :Busbahnhof
+STR_3063_SHIP_DOCK :Schiffshafen
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Einzugsgebiet angezeigen
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Einzugsgebiet nicht angezeigen
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Zeige Einzugsgebiet
+STR_3068_DOCK :{WHITE}Hafen
+STR_3069_BUOY :Boje
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...Boje ist im Weg
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...Bahnhof ist zu groß
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...ungleichförmige Stationen deaktiviert
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}STRG gedrückt halten um mehrere Einträge auszuwählen
+
+STR_UNDEFINED :(nicht definierter Wert)
+STR_STAT_CLASS_DFLT :Standardstation
+STR_STAT_CLASS_WAYP :Wegpunkte
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Werftausrichtung
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...muss auf Wasser gebaut werden
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Kann hier keine Werft bauen...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Werftausrichtung auswählen
+STR_3804_WATER :Wasser
+STR_3805_COAST_OR_RIVERBANK :Küste oder Flussufer
+STR_3806_SHIP_DEPOT :Werft
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...kann nicht auf Wasser gebaut werden
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Spiel speichern
+STR_4001_LOAD_GAME :{WHITE}Spiel laden
+STR_4002_SAVE :{BLACK}Speichern
+STR_4003_DELETE :{BLACK}Löschen
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} Megabyte{P "" s} frei
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Kann vom Laufwerk nicht lesen
+STR_4007_GAME_SAVE_FAILED :{WHITE}Spielspeicherung fehlgeschlagen
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Datei kann nicht gelöscht werden
+STR_4009_GAME_LOAD_FAILED :{WHITE}Laden des Spieles fehlgeschlagen
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}Liste der Laufwerke, Verzeichnisse und gespeicherten Spiele
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Ausgewählter Spielname
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Lösche gewählten Spielstand
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Speichere das Spiel unter dem gewählten Namen
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Neues Spiel auswählen
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Wähle Szenario (grün), vorgegebens Spiel (blau), oder ein Spiel nach dem Zufallsprinzip
+STR_4010_GENERATE_RANDOM_NEW_GAME :Spiel nach Zufallsprinzip erstellen
+STR_4011_LOAD_HEIGHTMAP :{WHITE}Reliefkarte laden
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} im Weg
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :{G=n}Kohlebergwerk
+STR_4803_POWER_STATION :{G=n}Kraftwerk
+STR_4804_SAWMILL :{G=n}Sägewerk
+STR_4805_FOREST :{G=m}Wald
+STR_4806_OIL_REFINERY :{G=w}Ölraffinerie
+STR_4807_OIL_RIG :{G=w}Ölbohrinsel
+STR_4808_FACTORY :{G=w}Fabrik
+STR_4809_PRINTING_WORKS :{G=w}Druckerei
+STR_480A_STEEL_MILL :{G=n}Stahlwerk
+STR_480B_FARM :{G=m}Bauernhof
+STR_480C_COPPER_ORE_MINE :{G=w}Kupfermine
+STR_480D_OIL_WELLS :{G=w}Ölquellen
+STR_480E_BANK :{G=w}Bank
+STR_480F_FOOD_PROCESSING_PLANT :{G=w}Nahrungsmittelfabrik
+STR_4810_PAPER_MILL :{G=w}Papiermühle
+STR_4811_GOLD_MINE :{G=w}Goldmine
+STR_4812_BANK :{G=w}Bank
+STR_4813_DIAMOND_MINE :{G=w}Diamantenmine
+STR_4814_IRON_ORE_MINE :{G=w}Eisenerzmine
+STR_4815_FRUIT_PLANTATION :{G=w}Fruchtplantage
+STR_4816_RUBBER_PLANTATION :{G=w}Kautschukplantage
+STR_4817_WATER_SUPPLY :{G=w}Wasserquelle
+STR_4818_WATER_TOWER :{G=m}Wasserturm
+STR_4819_FACTORY :{G=w}Fabrik
+STR_481A_FARM :{G=m}Bauernhof
+STR_481B_LUMBER_MILL :{G=w}Holzmühle
+STR_481C_COTTON_CANDY_FOREST :{G=m}Zuckerwattewald
+STR_481D_CANDY_FACTORY :{G=w}Bonbonfabrik
+STR_481E_BATTERY_FARM :{G=w}Batterieplantage
+STR_481F_COLA_WELLS :{G=w}Colaquellen
+STR_4820_TOY_SHOP :{G=n}Spielwarengeschäft
+STR_4821_TOY_FACTORY :{G=w}Spielwarenfabrik
+STR_4822_PLASTIC_FOUNTAINS :{G=m}Plastikbrunnen
+STR_4823_FIZZY_DRINK_FACTORY :{G=w}Limonadenfabrik
+STR_4824_BUBBLE_GENERATOR :{G=m}Luftblasengenerator
+STR_4825_TOFFEE_QUARRY :{G=w}Karamellgrube
+STR_4826_SUGAR_MINE :{G=w}Zuckermine
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Benötigt: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Benötigt: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Benötigt: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Produktion im letzten Monat:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% befördert)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Zentriere die Ansicht auf das Industriegebiet
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Neue{G r "" s} {STRING} wird nahe {TOWN} gebaut!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Neue{G r "" s} {STRING} wird nahe {TOWN} aufgeforstet!
+STR_482F_COST :{BLACK}Kosten: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Kann diese Industrie hier nicht bauen...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...Wald kann nur oberhalb der Schneegrenze gepflanzt werden
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} gibt bevorstehende Schließung bekannt!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}Wegen fehlender Rohstoffe kündigt {INDUSTRY} die drohende Schließung an!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}Wegen Holzmangel gibt {INDUSTRY} die bevorstehende Schließung bekannt!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} erhöht die Produktion!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}Neue Kohlevorkommen bei {INDUSTRY} gefunden!{}Förderung verdoppelt!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}Neue Ölfunde bei {INDUSTRY}!{}Förderung wird vermutlich verdoppelt!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}Neue Getreideanbaumethoden bei {INDUSTRY} werden Erträge verdoppeln!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}{INDUSTRY} Produktion sinkt um 50%
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}Insektenplage bei {INDUSTRY} verursacht Schaden!{}Produktion sinkt um 50%
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...kann nur in der Nähe des Kartenrandes errichtet werden
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}{STRING}produktion bei {INDUSTRY} erhöht sich um {COMMA}%!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}{STRING}produktion bei {INDUSTRY} verringert sich um {COMMA}%!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Zug im Tunnel
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Fahrzeug im Tunnel
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Ein anderer Tunnel ist im Weg
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Kann das Land am anderen Ende des Tunnels nicht anheben
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Der Tunnel muss zuerst abgerissen werden
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Die Brücke muss erst abgerissen werden
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Anfang und Ende können nicht im selben Feld liegen
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Ebenes Land oder Wasser muss unter der Brücke sein
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}Anfang und Ende müssen auf einer Ebene liegen
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Platz ist nicht für einen Tunnel geeignet
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Stahlhängebrücke
+STR_500F_GIRDER_STEEL :Stahlträgerbrücke
+STR_5010_CANTILEVER_STEEL :Selbsttragende Stahlbrücke
+STR_5011_SUSPENSION_CONCRETE :Betonhängebrücke
+STR_5012_WOODEN :Holzbrücke
+STR_5013_CONCRETE :Betonbrücke
+STR_5014_TUBULAR_STEEL :Rundstahlbrücke
+STR_BRIDGE_TUBULAR_SILICON :Siliziumrundbrücke
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Kann die Brücke hier nicht bauen...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Kann den Tunnel hier nicht bauen...
+STR_5017_RAILROAD_TUNNEL :Eisenbahntunnel
+STR_5018_ROAD_TUNNEL :Straßentunnel
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Stahlhängebrücke
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Stahlträgerbrücke
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Selbsttragende Stahlbrücke
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Stahlbetonbrücke
+STR_501F_WOODEN_RAIL_BRIDGE :Holzbrücke
+STR_5020_CONCRETE_RAIL_BRIDGE :Betonbrücke
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Stahlhängebrücke
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Stahlträgerbrücke
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Selbsttragende Stahlbrücke
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Stahlbetonbrücke
+STR_5025_WOODEN_ROAD_BRIDGE :Holzbrücke
+STR_5026_CONCRETE_ROAD_BRIDGE :Betonbrücke
+STR_5027_TUBULAR_RAIL_BRIDGE :Rundstahlbrücke
+STR_5028_TUBULAR_ROAD_BRIDGE :Rundstahlbrücke
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Gegenstand im Weg
+STR_5801_TRANSMITTER :Sender
+STR_5802_LIGHTHOUSE :Leuchtturm
+STR_5803_COMPANY_HEADQUARTERS :Firmensitz
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...Firmensitz ist im Weg
+STR_5805_COMPANY_OWNED_LAND :Firmeneigenes Gelände
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Das Land kann nicht erworben werden...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...Sie besitzen es bereits!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Unbenannt
+STR_SV_TRAIN_NAME :Zug {COMMA}
+STR_SV_ROADVEH_NAME :Fahrzeug {COMMA}
+STR_SV_SHIP_NAME :Schiff {COMMA}
+STR_SV_AIRCRAFT_NAME :Flugzeug {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :{STRING} Nord
+STR_SV_STNAME_SOUTH :{STRING} Süd
+STR_SV_STNAME_EAST :{STRING} Ost
+STR_SV_STNAME_WEST :{STRING} West
+STR_SV_STNAME_CENTRAL :{STRING} Zentrum
+STR_SV_STNAME_TRANSFER :{STRING} Transfer
+STR_SV_STNAME_HALT :{STRING} Halt
+STR_SV_STNAME_VALLEY :{STRING} Tal
+STR_SV_STNAME_HEIGHTS :{STRING} Höhe
+STR_SV_STNAME_WOODS :{STRING} Wald
+STR_SV_STNAME_LAKESIDE :{STRING} Seeblick
+STR_SV_STNAME_EXCHANGE :{STRING} Zentrum
+STR_SV_STNAME_AIRPORT :{STRING} Flughafen
+STR_SV_STNAME_OILFIELD :{STRING} Ölfeld
+STR_SV_STNAME_MINES :{STRING} Mine
+STR_SV_STNAME_DOCKS :{STRING} Hafen
+STR_SV_STNAME_BUOY_1 :{STRING} Boje 1
+STR_SV_STNAME_BUOY_2 :{STRING} Boje 2
+STR_SV_STNAME_BUOY_3 :{STRING} Boje 3
+STR_SV_STNAME_BUOY_4 :{STRING} Boje 4
+STR_SV_STNAME_BUOY_5 :{STRING} Boje 5
+STR_SV_STNAME_BUOY_6 :{STRING} Boje 6
+STR_SV_STNAME_BUOY_7 :{STRING} Boje 7
+STR_SV_STNAME_BUOY_8 :{STRING} Boje 8
+STR_SV_STNAME_BUOY_9 :{STRING} Boje 9
+STR_SV_STNAME_ANNEXE :{STRING} Anbau
+STR_SV_STNAME_SIDINGS :{STRING} Nebengleis
+STR_SV_STNAME_BRANCH :{STRING} Zweig
+STR_SV_STNAME_UPPER :Ober-{STRING}
+STR_SV_STNAME_LOWER :Unter-{STRING}
+STR_SV_STNAME_HELIPORT :{STRING} Heliport
+STR_SV_STNAME_FOREST :{STRING} Wald
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Schwierigkeitsgrad
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Speichern
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Leicht
+STR_6802_MEDIUM :{BLACK}Normal
+STR_6803_HARD :{BLACK}Schwer
+STR_6804_CUSTOM :{BLACK}Individuell
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}Max. Gegenspielerzahl: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Gegenspielerstartzeit: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}Städteanzahl: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}Industriedichte: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Höhe des Anfangskredites: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Kreditzinsen: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Fahrzeugbetriebskosten: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Baugeschwindigkeit der Gegenspieler: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Intelligenz der Gegenspieler: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Fahrzeugpannen: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Subventionsmultiplikator: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Baukosten: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Landschaftsform: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Wasseranteil: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Wirtschaft: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Zug umkehren: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Katastrophen: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Haltung der Stadtverwaltung zum Landschaftsbau: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :Keine
+STR_6816_LOW :Niedrig
+STR_6817_NORMAL :Normal
+STR_6818_HIGH :Hoch
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Sehr langsam
+STR_681C_SLOW :Langsam
+STR_681D_MEDIUM :Mittel
+STR_681E_FAST :Schnell
+STR_681F_VERY_FAST :Sehr schnell
+STR_VERY_LOW :Sehr niedrig
+STR_6820_LOW :Niedrig
+STR_6821_MEDIUM :Mittel
+STR_6822_HIGH :Hoch
+STR_6823_NONE :Keine
+STR_6824_REDUCED :Verringert
+STR_6825_NORMAL :Normal
+STR_6826_X1_5 :x1,5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Sehr flach
+STR_682B_FLAT :Flach
+STR_682C_HILLY :Hügelig
+STR_682D_MOUNTAINOUS :Bergig
+STR_682E_STEADY :Ruhig
+STR_682F_FLUCTUATING :Schwankend
+STR_6830_IMMEDIATE :Zusammen mit dem Spieler
+STR_6831_3_MONTHS_AFTER_PLAYER :3 Monate nach dem Spieler
+STR_6832_6_MONTHS_AFTER_PLAYER :6 Monate nach dem Spieler
+STR_6833_9_MONTHS_AFTER_PLAYER :9 Monate nach dem Spieler
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :Am Streckenende und in Bahnhöfen
+STR_6835_AT_END_OF_LINE_ONLY :Nur am Streckenende
+STR_6836_OFF :Aus
+STR_6837_ON :An
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Highscoretabelle zeigen
+STR_6839_PERMISSIVE :Zustimmend
+STR_683A_TOLERANT :Akzeptierend
+STR_683B_HOSTILE :Feindlich
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Spieler {COMMA})
+STR_7004_NEW_FACE :{BLACK}Neues Gesicht
+STR_7005_COLOR_SCHEME :{BLACK}Farbauswahl
+STR_7006_COLOR_SCHEME :{GOLD}Farbauswahl:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Neue Farbauswahl
+STR_7008_COMPANY_NAME :{BLACK}Firmenname
+STR_7009_PRESIDENT_NAME :{BLACK}Managername
+STR_700A_COMPANY_NAME :Firmenname
+STR_700B_PRESIDENT_S_NAME :Name des Managers
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Firmenname kann nicht geändert werden...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Managername kann nicht geändert werden...
+STR_700E_FINANCES :{WHITE}{COMPANY} Finanzen {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Ausgaben / Einnahmen
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Baukosten
+STR_7012_NEW_VEHICLES :{GOLD}Neue Fahrzeuge
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Zugbetriebskosten
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Fahrzeugbetriebskosten
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Flugzeugbetriebskosten
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Schiffbetriebskosten
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Betriebskosten Gebäude
+STR_7018_TRAIN_INCOME :{GOLD}Einnahmen Züge
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Einnahmen Fahrzeuge
+STR_701A_AIRCRAFT_INCOME :{GOLD}Einnahmen Flugzeuge
+STR_701B_SHIP_INCOME :{GOLD}Einnahmen Schiffe
+STR_701C_LOAN_INTEREST :{GOLD}Kreditzinsen
+STR_701D_OTHER :{GOLD}Sonstiges
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Gesamt:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Einkommensdiagramm
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Betriebsgewinndiagramm
+STR_7026_BANK_BALANCE :{WHITE}Kontostand
+STR_7027_LOAN :{WHITE}Kredit
+STR_MAX_LOAN :{WHITE}Maximaler Kredit: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}Leihen {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Rückzahlen {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...Maximaler Kredit ist {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Kann keinen weiteren Kredit aufnehmen ...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...Kredit bereits zurückgezahlt
+STR_702E_REQUIRED :{WHITE}...{CURRENCY} benötigt
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Kredit kann nicht getilgt werden...
+STR_INSUFFICIENT_FUNDS :{WHITE}Von der Bank geliehenes Geld kann nicht abgegeben werden...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Neues Profil für Manager aussuchen
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Firmenfarbe ändern
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Managername ändern
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Firmenname ändern
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Auf die gewünschte Farbe klicken
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Kredit aufnehmen
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Kredit abzahlen
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(Manager)
+STR_7038_INAUGURATED :{GOLD}Gegründet: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Fahrzeuge:
+STR_TRAINS :{WHITE}{COMMA} Z{P ug üge}
+STR_ROAD_VEHICLES :{WHITE}{COMMA} Fahrzeug{P "" e}
+STR_AIRCRAFT :{WHITE}{COMMA} Flugzeug{P "" e}
+STR_SHIPS :{WHITE}{COMMA} Schiff{P "" e}
+STR_7042_NONE :{WHITE}Keine
+STR_7043_FACE_SELECTION :{WHITE}Gesicht auswählen
+STR_7044_MALE :{BLACK}Männlich
+STR_7045_FEMALE :{BLACK}Weiblich
+STR_7046_NEW_FACE :{BLACK}Neues Gesicht
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Gesichtswahl abbrechen
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Gesichtswahl übernehmen
+STR_7049_SELECT_MALE_FACES :{BLACK}Wähle männliches Gesicht aus
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Wähle weibliches Gesicht aus
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Wähle zufälliges neues Gesicht
+STR_704C_KEY :{BLACK}Schlüssel
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Aufschlüsselung des Diagramms
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Schlüssel des Firmendiagramms
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Graph der Firma ein-/ausblenden
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Beförderte Frachteinheiten
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Bewertung der Firmenleistung (Höchstwert = 1000)
+STR_7052_COMPANY_VALUES :{WHITE}Firmenwertdiagramm
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Firmentabelle
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}Transportfirma in der Krise!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} Falls die Firmenleitung sich nicht bessert, wird der Verkauf oder die Insolvenz eingeleitet!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(Manager)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Transportfirmen fusionieren!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} ist verkauft worden an {COMPANY} für {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Wir suchen jemanden, der die Firma übernimmt.{}{}Nehmen Sie das Angebot an und kaufen {COMPANY} für {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Insolvenz!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} ist von den Gläubigern geschlossen worden, alles Vermögen wurde veräussert!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}Neue Transportfirma gegründet!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} startet bei {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Kann die Firma nicht kaufen...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Frachtbeförderungspreise
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Tage unterwegs
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Zahlung für 10 gelieferte Einheiten (oder 10.000 Liter) Fracht über eine Strecke von 20 Feldern
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Diagrammschalter für Frachttyp ein/aus
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Ingenieur
+STR_7067_TRAFFIC_MANAGER :Verkehrsmanager
+STR_7068_TRANSPORT_COORDINATOR :Fuhrparkleiter
+STR_7069_ROUTE_SUPERVISOR :Streckenmanager
+STR_706A_DIRECTOR :Direktor
+STR_706B_CHIEF_EXECUTIVE :Geschäftsführer
+STR_706C_CHAIRMAN :Vorsitzender
+STR_706D_PRESIDENT :Manager
+STR_706E_TYCOON :Tycoon
+STR_706F_BUILD_HQ :{BLACK}Firmensitz bauen
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Firmensitz bauen / anzeigen
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Errichte Firmensitz für 1% des Firmenwertes an anderer Stelle neu.
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Kann keinen Firmensitz bauen ...
+STR_7072_VIEW_HQ :{BLACK}Zeige Firmensitz
+STR_RELOCATE_HQ :{BLACK}Firmensitz verlegen
+STR_COMPANY_PASSWORD :{BLACK}Passwort
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Schütze deine Firma mit einem Passwort, um unautorisierten Spielern den Beitritt zu verwehren.
+STR_SET_COMPANY_PASSWORD :Firmenpasswort setzen
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}Weltwirtschaftskrise!{}{}Finanzexperten befürchten schlimmsten Zusammenbruch der Wirtschaft!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Wirtschaftskrise beendet!{}{}Aufschwung des Handels gibt Vertrauen in die Industrie und stärkt die Wirtschaft!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Schalter für großes/kleines Fenster
+STR_7076_COMPANY_VALUE :{GOLD}Firmenwert: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Kaufe 25% Anteil an Firma
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Verkaufe 25% Anteil an Firma
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Kaufe 25% Anteil an dieser Firma
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Verkaufe 25% Anteil an dieser Firma
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Kann 25% Anteil an dieser Firma nicht kaufen...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}Kann 25% Anteil an dieser Firma nicht verkaufen...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% Eigentum von {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% Eigentum von {COMPANY}{} {COMMA}% Eigentum von {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} wurde von {COMPANY} übernommen!
+STR_7080_PROTECTED :{WHITE}Dieses Unternehmen handelt noch nicht mit Anteilen...
+
+STR_LIVERY_DEFAULT :Standard Lackierung
+STR_LIVERY_STEAM :Dampflok
+STR_LIVERY_DIESEL :Diesellok
+STR_LIVERY_ELECTRIC :E-Lok
+STR_LIVERY_MONORAIL :Einschienenbahn
+STR_LIVERY_MAGLEV :Magnetschwebebahn
+STR_LIVERY_DMU :VT
+STR_LIVERY_EMU :ET
+STR_LIVERY_PASSENGER_WAGON_STEAM :Passagierwagen (Dampf)
+STR_LIVERY_PASSENGER_WAGON_DIESEL :Passagierwagen (Diesel)
+STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Passagierwagen (elektrisch)
+STR_LIVERY_FREIGHT_WAGON :Güterwagen
+STR_LIVERY_BUS :Bus
+STR_LIVERY_TRUCK :Lastwagen
+STR_LIVERY_PASSENGER_SHIP :Passagierfähre
+STR_LIVERY_FREIGHT_SHIP :Frachter
+STR_LIVERY_HELICOPTER :Helikopter
+STR_LIVERY_SMALL_PLANE :Kleines Flugzeug
+STR_LIVERY_LARGE_PLANE :Großraumflugzeug
+
+STR_LIVERY_GENERAL_TIP :{BLACK}Allgemeines Farbschema anzeigen
+STR_LIVERY_TRAIN_TIP :{BLACK}Zugfarbschema anzeigen
+STR_LIVERY_ROADVEH_TIP :{BLACK}Fahrzeugfarbschema anzeigen
+STR_LIVERY_SHIP_TIP :{BLACK}Schiffsfarbschema anzeigen
+STR_LIVERY_AIRCRAFT_TIP :{BLACK}Flugzeugfarbschema anzeigen
+STR_LIVERY_PRIMARY_TIP :{BLACK}Wähle die Hauptfarbe für das gewählte Schema aus.
+STR_LIVERY_SECONDARY_TIP :{BLACK}Wähle die Nebenfarbe für das ausgewählte Schema.
+STR_LIVERY_PANEL_TIP :{BLACK}Wähle ein Farbschema oder mehrere Farbschemen(mit STRG+Klick) aus, um diese zu ändern. Klicke in das Kästchen um ein Schema zu aktivieren.
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (Dampf)
+STR_8001_MJS_250_DIESEL :MJS 250 (Diesel)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut Diesel
+STR_8006_POWERNAUT_DIESEL :Powernaut Diesel
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (Dampf)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (Dampf)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (Dampf)
+STR_800A_SH_8P_STEAM :SH '8P' (Dampf)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel VT (Diesel)
+STR_800C_DASH_DIESEL :'Dash' (Diesel)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (Diesel)
+STR_800E_UU_37_DIESEL :UU '37' (Diesel)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (Diesel)
+STR_8010_CS_4000_DIESEL :CS 4000 (Diesel)
+STR_8011_CS_2400_DIESEL :CS 2400 (Diesel)
+STR_8012_CENTENNIAL_DIESEL :Centennial (Diesel)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (Diesel)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (Diesel)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (Diesel)
+STR_8016_SH_125_DIESEL :SH '125' (Diesel)
+STR_8017_SH_30_ELECTRIC :SH '30' (Elektrisch)
+STR_8018_SH_40_ELECTRIC :SH '40' (Elektrisch)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (Elektrisch)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (Elektrisch)
+STR_801B_PASSENGER_CAR :Passagierwagen
+STR_801C_MAIL_VAN :Postwagen
+STR_801D_COAL_CAR :Kohlenwagen
+STR_801E_OIL_TANKER :Öltanker
+STR_801F_LIVESTOCK_VAN :Viehtransporter
+STR_8020_GOODS_VAN :Güterwagen
+STR_8021_GRAIN_HOPPER :Getreidetransporter
+STR_8022_WOOD_TRUCK :Holzwagen
+STR_8023_IRON_ORE_HOPPER :Eisenerzwagen
+STR_8024_STEEL_TRUCK :Stahltransporter
+STR_8025_ARMORED_VAN :Sicherheitstransporter
+STR_8026_FOOD_VAN :Lebensmitteltransporter
+STR_8027_PAPER_TRUCK :Papiertransporter
+STR_8028_COPPER_ORE_HOPPER :Kupfererzwagen
+STR_8029_WATER_TANKER :Wassertanker
+STR_802A_FRUIT_TRUCK :Fruchttransporter
+STR_802B_RUBBER_TRUCK :Kautschukwagen
+STR_802C_SUGAR_TRUCK :Zuckerlaster
+STR_802D_COTTON_CANDY_HOPPER :Zuckerwattewagen
+STR_802E_TOFFEE_HOPPER :Karamellwagen
+STR_802F_BUBBLE_VAN :Luftblasentransporter
+STR_8030_COLA_TANKER :Colatanker
+STR_8031_CANDY_VAN :Bonbontransporter
+STR_8032_TOY_VAN :Spielwarentransporter
+STR_8033_BATTERY_TRUCK :Batterielaster
+STR_8034_FIZZY_DRINK_TRUCK :Limonadentransporter
+STR_8035_PLASTIC_TRUCK :Plastiklaster
+STR_8036_X2001_ELECTRIC :'X2001' (Elektrisch)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Elektrisch)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :Passagierwagen
+STR_803A_MAIL_VAN :Postwagen
+STR_803B_COAL_CAR :Kohlewagen
+STR_803C_OIL_TANKER :Öltanker
+STR_803D_LIVESTOCK_VAN :Viehtransporter
+STR_803E_GOODS_VAN :Güterwagen
+STR_803F_GRAIN_HOPPER :Getreidewagen
+STR_8040_WOOD_TRUCK :Holzwagen
+STR_8041_IRON_ORE_HOPPER :Eisenerzwagen
+STR_8042_STEEL_TRUCK :Stahltransporter
+STR_8043_ARMORED_VAN :Sicherheitstransporter
+STR_8044_FOOD_VAN :Lebensmitteltransporter
+STR_8045_PAPER_TRUCK :Papiertransporter
+STR_8046_COPPER_ORE_HOPPER :Kupfererzwagen
+STR_8047_WATER_TANKER :Wassertanker
+STR_8048_FRUIT_TRUCK :Fruchttransporter
+STR_8049_RUBBER_TRUCK :Kautschuktransporter
+STR_804A_SUGAR_TRUCK :Zuckertransporter
+STR_804B_COTTON_CANDY_HOPPER :Zuckerwattewagen
+STR_804C_TOFFEE_HOPPER :Karamelltransporter
+STR_804D_BUBBLE_VAN :Luftblasentransporter
+STR_804E_COLA_TANKER :Colatransporter
+STR_804F_CANDY_VAN :Bonbontransporter
+STR_8050_TOY_VAN :Spielwarentransporter
+STR_8051_BATTERY_TRUCK :Batterietransporter
+STR_8052_FIZZY_DRINK_TRUCK :Limonadetransporter
+STR_8053_PLASTIC_TRUCK :Plastikwagen
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (Elektrisch)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (Elektrisch)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (Elektrisch)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (Elektrisch)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :Passagierwagen
+STR_805A_MAIL_VAN :Postwagen
+STR_805B_COAL_CAR :Kohlewagen
+STR_805C_OIL_TANKER :Öltanker
+STR_805D_LIVESTOCK_VAN :Viehtransporter
+STR_805E_GOODS_VAN :Warenwagen
+STR_805F_GRAIN_HOPPER :Getreidetransporter
+STR_8060_WOOD_TRUCK :Holzwagen
+STR_8061_IRON_ORE_HOPPER :Eisenerzwagen
+STR_8062_STEEL_TRUCK :Stahltransporter
+STR_8063_ARMORED_VAN :Sicherheitstransporter
+STR_8064_FOOD_VAN :Lebensmitteltransporter
+STR_8065_PAPER_TRUCK :Papiertransporter
+STR_8066_COPPER_ORE_HOPPER :Kupfererzwagen
+STR_8067_WATER_TANKER :Wassertanker
+STR_8068_FRUIT_TRUCK :Fruchttransporter
+STR_8069_RUBBER_TRUCK :Kautschukwagen
+STR_806A_SUGAR_TRUCK :Zuckertransporter
+STR_806B_COTTON_CANDY_HOPPER :Zuckerwattewagen
+STR_806C_TOFFEE_HOPPER :Karamelltransporter
+STR_806D_BUBBLE_VAN :Luftblasentransporter
+STR_806E_COLA_TANKER :Colatransporter
+STR_806F_CANDY_VAN :Bonbontransporter
+STR_8070_TOY_VAN :Spielwarentransporter
+STR_8071_BATTERY_TRUCK :Batterielaster
+STR_8072_FIZZY_DRINK_TRUCK :Limonadetransporter
+STR_8073_PLASTIC_TRUCK :Plastikwagen
+STR_8074_MPS_REGAL_BUS :MPS Regal Bus
+STR_8075_HEREFORD_LEOPARD_BUS :Hereford Leopard Bus
+STR_8076_FOSTER_BUS :Foster Bus
+STR_8077_FOSTER_MKII_SUPERBUS :Foster MkII Superbus
+STR_8078_PLODDYPHUT_MKI_BUS :Ploddyphut MkI Bus
+STR_8079_PLODDYPHUT_MKII_BUS :Ploddyphut MkII Bus
+STR_807A_PLODDYPHUT_MKIII_BUS :Ploddyphut MkIII Bus
+STR_807B_BALOGH_COAL_TRUCK :Balogh Kohlelaster
+STR_807C_UHL_COAL_TRUCK :Uhl Kohlelaster
+STR_807D_DW_COAL_TRUCK :DW Kohlelaster
+STR_807E_MPS_MAIL_TRUCK :MPS Postwagen
+STR_807F_REYNARD_MAIL_TRUCK :Reynard Postwagen
+STR_8080_PERRY_MAIL_TRUCK :Perry Postwagen
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :MightyMover Postwagen
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Powernaught Postwagen
+STR_8083_WIZZOWOW_MAIL_TRUCK :Wizzowow Postwagen
+STR_8084_WITCOMBE_OIL_TANKER :Witcombe Öltanker
+STR_8085_FOSTER_OIL_TANKER :Foster Öltanker
+STR_8086_PERRY_OIL_TANKER :Perry Öltanker
+STR_8087_TALBOTT_LIVESTOCK_VAN :Talbott Viehtransporter
+STR_8088_UHL_LIVESTOCK_VAN :Uhl Viehtransporter
+STR_8089_FOSTER_LIVESTOCK_VAN :Foster Viehtransporter
+STR_808A_BALOGH_GOODS_TRUCK :Balogh Gütertransporter
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Craighead Gütertransporter
+STR_808C_GOSS_GOODS_TRUCK :Goss Gütertransporter
+STR_808D_HEREFORD_GRAIN_TRUCK :Hereford Getreidetransporter
+STR_808E_THOMAS_GRAIN_TRUCK :Thomas Getreidetransporter
+STR_808F_GOSS_GRAIN_TRUCK :Goss Getreidetransporter
+STR_8090_WITCOMBE_WOOD_TRUCK :Witcombe Holzlaster
+STR_8091_FOSTER_WOOD_TRUCK :Foster Holzlaster
+STR_8092_MORELAND_WOOD_TRUCK :Moreland Holzlaster
+STR_8093_MPS_IRON_ORE_TRUCK :MPS Eisenerzlaster
+STR_8094_UHL_IRON_ORE_TRUCK :Uhl Eisenerzlaster
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Chippy Eisenerzlaster
+STR_8096_BALOGH_STEEL_TRUCK :Balogh Stahltransporter
+STR_8097_UHL_STEEL_TRUCK :Uhl Stahltransporter
+STR_8098_KELLING_STEEL_TRUCK :Kelling Stahltransporter
+STR_8099_BALOGH_ARMORED_TRUCK :Balogh Sicherheitstransporter
+STR_809A_UHL_ARMORED_TRUCK :Uhl Sicherheitstransporter
+STR_809B_FOSTER_ARMORED_TRUCK :Foster Sicherheitstransporter
+STR_809C_FOSTER_FOOD_VAN :Foster Nahrungstransporter
+STR_809D_PERRY_FOOD_VAN :Perry Nahrungstransporter
+STR_809E_CHIPPY_FOOD_VAN :Chippy Nahrungstransporter
+STR_809F_UHL_PAPER_TRUCK :Uhl Papierlaster
+STR_80A0_BALOGH_PAPER_TRUCK :Balogh Papierlaster
+STR_80A1_MPS_PAPER_TRUCK :MPS Papierlaster
+STR_80A2_MPS_COPPER_ORE_TRUCK :MPS Kupfererzlaster
+STR_80A3_UHL_COPPER_ORE_TRUCK :Uhl Kupfererzlaster
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Goss Kupfererzlaster
+STR_80A5_UHL_WATER_TANKER :Uhl Wassertankwagen
+STR_80A6_BALOGH_WATER_TANKER :Balogh Wassertankwagen
+STR_80A7_MPS_WATER_TANKER :MPS Wassertankwagen
+STR_80A8_BALOGH_FRUIT_TRUCK :Balogh Früchtetransporter
+STR_80A9_UHL_FRUIT_TRUCK :Uhl Früchtetransporter
+STR_80AA_KELLING_FRUIT_TRUCK :Kelling Früchtetransporter
+STR_80AB_BALOGH_RUBBER_TRUCK :Balogh Kautschuklaster
+STR_80AC_UHL_RUBBER_TRUCK :Uhl Kautschuklaster
+STR_80AD_RMT_RUBBER_TRUCK :RMT Kautschuklaster
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :MightyMover Zuckertransporter
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Powernaught Zuckertransporter
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Wizzowow Zuckertransporter
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :MightyMover Cola-Tankwagen
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Powernaught Cola-Tankwagen
+STR_80B3_WIZZOWOW_COLA_TRUCK :Wizzowow Cola-Tankwagen
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :MightyMover Zuckerwattelaster
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Powernaught Zuckerwattelaster
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Wizzowow Zuckerwattelaster
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :MightyMover Karamelllaster
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Powernaught Karamelllaster
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Wizzowow Karamelllaster
+STR_80BA_MIGHTYMOVER_TOY_VAN :MightyMover Spielwarentransporter
+STR_80BB_POWERNAUGHT_TOY_VAN :Powernaught Spielwarentransporter
+STR_80BC_WIZZOWOW_TOY_VAN :Wizzowow Spielwarentransporter
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :MightyMover Bonbontransporter
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Powernaught Bonbontransporter
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Wizzowow Bonbontransporter
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :MightyMover Batterielaster
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Powernaught Batterielaster
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Wizzowow Batterielaster
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :MightyMover Limonadentanker
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Powernaught Limonadentanker
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Wizzowow Limonadentanker
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :MightyMover Plastiktransporter
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Powernaught Plastiktransporter
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Wizzowow Plastiktransporter
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :MightyMover Luftblasenlaster
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Powernaught Luftblasenlaster
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Wizzowow Luftblasenlaster
+STR_80CC_MPS_OIL_TANKER :MPS Öltanker
+STR_80CD_CS_INC_OIL_TANKER :CS-Inc. Öltanker
+STR_80CE_MPS_PASSENGER_FERRY :MPS Passagierschiff
+STR_80CF_FFP_PASSENGER_FERRY :FFP Passagierschiff
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Bakewell 300 Luftkissenboot
+STR_80D1_CHUGGER_CHUG_PASSENGER :Chugger-Chug Passagierschiff
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Shivershake Passagierschiff
+STR_80D3_YATE_CARGO_SHIP :Yate Frachter
+STR_80D4_BAKEWELL_CARGO_SHIP :Bakewell Frachter
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Mightymover Frachter
+STR_80D6_POWERNAUT_CARGO_SHIP :Powernaut Frachter
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Tricario Hubschrauber
+STR_80FE_GURU_X2_HELICOPTER :Guru X2 Hubschrauber
+STR_80FF_POWERNAUT_HELICOPTER :Powernaut Hubschrauber
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Nachricht vom Fahrzeughersteller
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}Wir haben ein{G en e ""} neue{G n "" s} {STRING} entwickelt. {}Sind Sie daran interessiert, das Fahrzeug ein Jahr lang exklusiv zu nutzen, so dass wir die Funktionen testen können, bevor es allgemein zur Verfügung gestellt wird?
+STR_8102_RAILROAD_LOCOMOTIVE :{G=w}Lokomotive
+STR_8103_ROAD_VEHICLE :{G=n}Fahrzeug
+STR_8104_AIRCRAFT :{G=n}Flugzeug
+STR_8105_SHIP :{G=n}Schiff
+STR_8106_MONORAIL_LOCOMOTIVE :{G=w}Einschienenbahn
+STR_8107_MAGLEV_LOCOMOTIVE :{G=w}Magnetschwebebahn
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}{TOWN} Zugdepot
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Die Stadt feiert . . .{}Der erste Zug erreicht {STATION}!
+STR_8802_DETAILS :{WHITE}{STRING} (Details)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Zug ist im Weg
+STR_8804 :{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8806_GO_TO :Fahre nach {STATION}
+STR_8807_GO_TO_TRANSFER :Fahre nach {STATION} (Umladen und beladen)
+STR_8808_GO_TO_UNLOAD :Fahre nach {STATION} (Entladen)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Fahre nach {STATION} (Umladen und leer verlassen)
+STR_880A_GO_TO_LOAD :Fahre nach {STATION} (Beladen)
+STR_880B_GO_TO_TRANSFER_LOAD :Fahre nach {STATION} (Umladen und voll beladen)
+STR_880C_GO_NON_STOP_TO :Fahre ohne Halt nach {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Fahre ohne Halt nach {STATION} (Umladen und beladen)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Fahre ohne Halt nach {STATION} (Entladen)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Fahre nach {STATION} (Umladen und leer verlassen)
+STR_8810_GO_NON_STOP_TO_LOAD :Fahre ohne Halt nach {STATION} (Beladen)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Fahre ohne Halt nach {STATION} (Umladen und voll beladen)
+STR_GO_TO_TRAIN_DEPOT :Fahre zum {TOWN} Zugdepot
+STR_SERVICE_AT_TRAIN_DEPOT :Wartung bei {TOWN} Zugdepot
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Fahre ohne Halt zu {TOWN} Zugdepot
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Wartung (ohne Halt) bei {TOWN} Zugdepot
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}Unterwegs zu {TOWN} Zugdepot
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}Unterwegs zu {TOWN} Zugdepot, {VELOCITY}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE :{LTBLUE}Wartung in {TOWN} Zugdepot
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE_VEL :{LTBLUE}Wartung in {TOWN} Zugdepot, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (Ungültiger Auftrag)
+
+STR_UNKNOWN_DESTINATION :unbekanntes Ziel
+STR_8812_EMPTY :{LTBLUE}Leer
+STR_8813_FROM :{LTBLUE}{CARGO} von {STATION}
+STR_FROM_MULT :{LTBLUE}{CARGO} von {STATION} (x{NUM})
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}Zug {COMMA} wartet im Depot
+STR_8815_NEW_VEHICLES :{BLACK}Neue Fahrzeuge
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Zug zu lang
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Züge können nur verändert werden, wenn sie im Depot halten
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} Z{P ug üge}
+
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Neues Schienenfahrzeug
+STR_NEW_ELRAIL_VEHICLES :{WHITE}Neue E-Loks
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Neue Einschienenbahnzüge
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Neue Magnetzüge
+STR_ALL_AVAIL_RAIL_VEHICLES :{WHITE}Eisenbahnfahrzeuge
+
+STR_881F_BUILD_VEHICLE :{BLACK}Fahrzeug bauen
+STR_CLONE_ROAD_VEHICLE :{BLACK}Fahrzeug duplizieren
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}Baut eine Kopie des Fahrzeuges. Strg+Klick erzeugt gemeinsamen Fahrplan
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Baut eine Kopie des Fahrzeuges. Klicke diese Schaltfläche und dann auf ein Fahrzeug innerhalb oder außerhalb des Depots. Strg+Klick erzeugt gemeinsamen Fahrplan
+STR_CLONE_TRAIN :{BLACK}Zug duplizieren
+STR_CLONE_TRAIN_INFO :{BLACK}Baut eine Kopie des Zuges mit allen Waggons. Strg+Klick erzeugt gemeinsamen Fahrplan
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}Baut eine Kopie des Zuges mit allen Waggons. Klicke diese Schaltfläche und dann auf einen Zug innerhalb oder außerhalb des Depots. Strg+Klick erzeugt gemeinsamen Fahrplan
+STR_8820_RENAME :{BLACK}Umbenennen
+STR_8823_SKIP :{BLACK}Ãœbergehen
+STR_8824_DELETE :{BLACK}Löschen
+STR_8825_NON_STOP :{BLACK}ohne Halt
+STR_8826_GO_TO :{BLACK}Nach
+STR_8827_FULL_LOAD :{BLACK}Beladen
+STR_8828_UNLOAD :{BLACK}Entladen
+STR_REFIT :{BLACK}Ersetzen
+STR_REFIT_TIP :{BLACK}Wähle welche Frachtart du ersetzen möchtest. STRG+Klick um die Auswahl rückgängig zu machen
+STR_REFIT_ORDER :(Ersetzen zu {STRING})
+STR_8829_ORDERS :{WHITE}{VEHICLE} (Aufträge)
+STR_882A_END_OF_ORDERS :{SETX 10}- - Ende der Aufträge - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}Wartung
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Kann Schienenfahrzeug nicht bauen...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Gebaut: {LTBLUE}{NUM}{BLACK} Wert: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Wert: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}Laden / Entladen
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}Zug muss im Depot angehalten sein
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Kann den Zug nicht ins Depot schicken...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Kein Platz für weitere Aufträge
+STR_8832_TOO_MANY_ORDERS :{WHITE}Zu viele Aufträge
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Kann keinen neuen Auftrag hinzufügen...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Kann den Auftrag nicht löschen...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Kann den Auftrag nicht bearbeiten...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Kann das Fahrzeug nicht bewegen...
+STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}Hintere Lok folgt immer der vorderen Lok
+STR_8838_N_A :k.A.{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Kann Schienenfahrzeug nicht verkaufen...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Kann keinen weg zum Depot finden
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Kann den Zug nicht anhalten/starten ...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Wartungsintervall: {LTBLUE}{COMMA}Tage {BLACK} Letzte Wartung: {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Wartungsintervall: {LTBLUE}{COMMA}%{BLACK} Letzte Wartung: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Züge - für Einzelheiten auf den jeweiligen Zug klicken
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Neue Züge bauen (setzt Zugdepot voraus)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Züge - für Einzelheiten auf den Zug klicken; Waggon ziehen, um ihn an-/abzukoppeln
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Baue neues Schienenfahrzeug
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Schienenfahrzeug hierher ziehen, um es zu verkaufen
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Ansicht auf das Zugdepot zentrieren
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Zugfahrzeugliste - Einzelheiten durch Anklicken des Fahrzeuges
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Baue das angewählte Fahrzeug
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Umbenennen der Waggontypen
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Laufende Zugbewegung - Klicke hier, um den Zug anzuhalten / zu starten
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Anzeige der Zugaufträge
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Ansicht auf den Zug zentrieren
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Zug ins Depot schicken
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Zug zur Weiterfahrt zwingen, ohne das Signal zu beachten
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Zug umkehren
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Zeige Einzelheiten des Zuges
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Wartungsintervall erhöhen
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Wartungsintervall verringern
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Zeige Einzelheiten zur geladenen Fracht
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Zeige Einzelheiten zu den Schienenfahrzeugen
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Zeige Kapazität jedes Fahrzeugs
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Frachtübersicht des Zuges anzeigen, aufgeteilt nach Frachttyp
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Auftragsliste - zum Markieren hier anklicken
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}Übergehe den laufenden Auftrag, und starte den nächsten
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Lösche den markierten Auftrag
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Führe den markierten Auftrag ohne Halt durch
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Füge einen neuen Auftrag vor dem markierten Auftrag ein, oder setze ihn ans Ende der Liste
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Der markierte Auftrag wird nur nach voller Beladung ausgeführt
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Beim markierten Auftrag wird die volle Entladung veranlasst
+STR_SERVICE_HINT :{BLACK}Überspringe diesen Auftrag, sofern keine Wartung benötigt wird
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}Neue {STRING} ist jetzt verfügbar!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Kosten: {CURRENCY} Gewicht: {WEIGHT_S}{}Geschwindigk.: {VELOCITY} Leistung: {POWER}{}Betriebskosten: {CURRENCY}/Jahr{}Kapazität: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}Panne
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}Alter: {LTBLUE}{STRING}{BLACK} Betriebskosten: {LTBLUE}{CURRENCY}/Jahr
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Gewicht: {LTBLUE}{WEIGHT_S} {BLACK}Leistung: {LTBLUE}{POWER}{BLACK} Höchstgeschwindigk.: {LTBLUE}{VELOCITY}
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Gewicht: {LTBLUE}{WEIGHT_S} {BLACK}Leistung: {LTBLUE}{POWER}{BLACK} Höchstgeschw.: {LTBLUE}{VELOCITY} {BLACK}Max. Zugkraft: {LTBLUE}{FORCE}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit lfd. Jahr: {LTBLUE}{CURRENCY} (letztes Jahr: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}Zuverlässigkeit: {LTBLUE}{COMMA}% {BLACK}Ausfälle seit letzter Wartung: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Angehalten
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Der Zug kann das Signal nicht ohne Gefahr passieren...
+STR_8863_CRASHED :{RED}Zusammenstoß!
+
+STR_8865_NAME_TRAIN :{WHITE}Name des Zuges
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}Kann den Zug nicht benennen...
+STR_8867_NAME_TRAIN :{BLACK}Name des Zuges
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Zugunglück!{}{COMMA} sterben in einem Feuerball nach Zusammenstoß
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Die Zugbewegung kann nicht umgekehrt werden...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Zugtyp umbenennen
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Zugtyp kann nicht umbenannt werden...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Beim markierten Eintrag wird die Ladung in den Bahnhof entladen (für späteren Weitertransport)
+STR_886F_TRANSFER :{BLACK}Umladen
+
+STR_TRAIN_STOPPING :{RED}Halte an
+STR_TRAIN_STOPPING_VEL :{RED}Halte an, {VELOCITY}
+STR_INCOMPATIBLE_RAIL_TYPES :inkompatible Gleistypen
+STR_TRAIN_NO_POWER :{RED}Keine Energie
+STR_TRAIN_START_NO_CATENARY :Wegen fehlender Oberleitung kann der Zug nicht starten.
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Fahrzeug ist im Weg
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} Fahrzeug{P "" e}
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}{TOWN} Fahrzeugdepot
+STR_9004_NEW_VEHICLES :{BLACK}Neue Fahrzeuge
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}Neue Fahrzeuge
+STR_9007_BUILD_VEHICLE :{BLACK}Baue Fahrzeug
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Kann das Fahrzeug nicht bauen...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (Einzelheiten)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}Alter: {LTBLUE}{STRING}{BLACK} Betriebskosten: {LTBLUE}{CURRENCY}/Jahr
+STR_900E_MAX_SPEED :{BLACK}Höchstgeschwindigk.: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit lfd. Jahr: {LTBLUE}{CURRENCY} (letztes Jahr: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}Zuverlässigkeit: {LTBLUE}{COMMA}% {BLACK}Pannen seit letzter Wartung: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Gebaut: {LTBLUE}{NUM}{BLACK} Wert: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Kapazität: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}...muss in einem Fahrzeugdepot angehalten werden
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Kann das Fahrzeug nicht verkaufen...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Kann das Fahrzeug nicht anhalten/starten...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}Fahrzeug {COMMA} wartet im Depot
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}Unterwegs zu {TOWN} Fahrzeugdepot
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}Unterwegs zu {TOWN} Fahrzeugdepot, {VELOCITY}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE :{LTBLUE}Wartung in {TOWN} Fahrzeugdepot
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE_VEL :{LTBLUE}Wartung in {TOWN} Fahrzeugdepot, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Kann das Fahrzeug nicht zum Depot schicken...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Kann kein Fahrzeugdepot finden
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Straßenfahrzeuge - für Einzelheiten auf das Fahrzeug klicken
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Baue neues Fahrzeug (setzt Fahrzeugdepot voraus)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Laufende Fahrzeugbewegung - Klicke hier, um das Fahrzeug anzuhalten / zu starten
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Zeige Aufträge für das Fahrzeug
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Ansicht auf das Fahrzeug zentrieren
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Schicke das Fahrzeug ins Depot
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Das Fahrzeug zur Umkehr zwingen
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Zeige Einzelheiten des Fahrzeuges
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Straßenfahrzeuge - für Einzelheiten auf das Fahrzeug klicken
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Baue neues Fahrzeug
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Ziehe Fahrzeug hierher, um es zu verkaufen
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Ansicht auf das Fahrzeugdepot zentrieren
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Fahrzeugauswahlliste - Klicke auf ein Fahrzeug für Einzelheiten
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Baue das ausgewählte Fahrzeug
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}Neues Fahrzeug jetzt erhältlich!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Kosten: {CURRENCY}{}Geschwindigk.: {VELOCITY}{}Betriebskosten: {CURRENCY}/Jahr{}Ladevermögen: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Name des Fahrzeuges
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Kann das Fahrzeug nicht benennen...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Name des Fahrzeuges
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Die Stadt feiert . . .{}Der erste Bus erreicht {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Die Stadt feiert . . .{}Der erste Lkw erreicht {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}Fahrzeug verunglückt!{}Fahrer stirbt in einem Feuerball nach Zusammenstoß mit einem Zug
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}Fahrzeug verunglückt!{}{COMMA} sterben nach Zusammenstoß mit einem Zug im Feuerball
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Das Fahrzeug kann nicht gewendet werden...
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}Fahrzeuge die aus mehreren Einheiten bestehen, können nicht gedreht werden.
+STR_9034_RENAME :{BLACK}Umbenennen
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Fahrzeug umbenennen
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Fahrzeug umbenennen
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Kann das Fahrzeug nicht umbenennen...
+STR_9038_GO_TO_ROADVEH_DEPOT :Fahre zu {TOWN} Fahrzeugdepot
+STR_SERVICE_AT_ROADVEH_DEPOT :Wartung bei {TOWN} Fahrzeugdepot
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Straßenfahrzeug für den Transport anderer Güter ausrüsten
+STR_REFIT_ROAD_VEHICLE :{BLACK}Erneuere Straßenfahrzeug
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Straßenfahrzeug für den Transport des markierten Gutes ausrüsten
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Kann Straßenfahrzeug nicht erneuern...
+STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Wähle die Frachtart aus, die vom Straßenfahrzeug transportiert werden soll
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Hafenanlage bauen
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Hafenanlage bauen
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Kann den Hafen hier nicht bauen...
+STR_9803_SHIP_DEPOT :{WHITE}{TOWN} Werft
+STR_9804_NEW_SHIPS :{BLACK}Neue Schiffe
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} Schiff{P "" e}
+STR_9808_NEW_SHIPS :{WHITE}Neue Schiffe
+STR_9809_BUILD_SHIP :{BLACK}Baue Schiff
+STR_CLONE_SHIP :{BLACK}Schiff duplizieren
+STR_CLONE_SHIP_INFO :{BLACK}Baut eine Kopie des Schiffes. Strg+Klick erzeugt gemeinsamen Fahrplan
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}Baut eine Kopie des Schiffes. Klicke diese Schaltfläche und dann auf eine Schiff innerhalb oder außerhalb des Depots. Strg+Klick erzeugt gemeinsamen Fahrplan
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}Schiff muss in der Werft angehalten werden
+STR_980C_CAN_T_SELL_SHIP :{WHITE}Kann das Schiff nicht verkaufen...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Kann das Schiff nicht bauen...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Schiff ist im Weg
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Einzelheiten)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}Alter: {LTBLUE}{STRING}{BLACK} Betriebskosten: {LTBLUE}{CURRENCY}/Jahr
+STR_9813_MAX_SPEED :{BLACK}Höchstgeschwindigk.: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit lfd. Jahr: {LTBLUE}{CURRENCY} (letztes Jahr: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}Zuverlässigkeit: {LTBLUE}{COMMA}% {BLACK}Pannen seit letzter Wartung: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Gebaut: {LTBLUE}{NUM}{BLACK} Wert: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}Kapazität: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}Kann das Schiff nicht anhalten/starten...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Kann das Schiff nicht in die Werft schicken...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Kann keine Werft finden
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}Unterwegs zu {TOWN} Werft
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}Unterwegs zu {TOWN} Werft, {VELOCITY}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE :{LTBLUE}Wartung in {TOWN} Werft
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE_VEL :{LTBLUE}Wartung in {TOWN} Werft, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}Schiff {COMMA} wartet in der Werft
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Hafen bauen
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Werft bauen (für den Bau und die Wartung von Schiffen)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Schiffe - für Einzelheiten auf das Schiff klicken
+STR_9820_BUILD_NEW_SHIP :{BLACK}Neues Schiff bauen
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Ziehe Schiff hierher, um es zu verkaufen
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Ansicht auf die Werft zentrieren
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Schiffe - für Einzelheiten auf das Schiff klicken
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Baue neues Schiff (setzt Werft voraus)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}Schiffauswahliste - für Einzelheiten auf das Schiff klicken
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Baue das ausgewählte Schiff
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Laufende Schiffsbewegung - Klicke hier, um das Schiff anzuhalten / zu starten
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Aufträge des Schiffes
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Anzeige auf das Schiff zentrieren
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Schicke das Schiff zur Werft
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Zeige Einzelheiten des Schiffes
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}Neues Schiff ist erhältlich!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Kosten: {CURRENCY} Höchstgeschwindigk.: {VELOCITY}{}Kapazität: {CARGO}{}Betriebskosten: {CURRENCY}/Jahr
+STR_982F_NAME_SHIP :{BLACK}Schiffsname
+
+STR_9831_NAME_SHIP :{WHITE}Schiffsname
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Kann Schiffsnamen nicht vergeben...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Die Stadt feiert . . .{}Das erste Schiff erreicht {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Positionsboje, wird als Wegpunkt benötigt
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Kann die Boje hier nicht plazieren...
+STR_9836_RENAME :{BLACK}Umbenennen
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Schiff umbenennen
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Schiff umbenennen
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Kann das Schiff nicht umbenennen...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Umrüstung des Schiffes zur Beförderung anderer Frachtarten
+STR_983B_REFIT :{WHITE}{VEHICLE} (Umrüsten)
+STR_983C_REFIT_SHIP :{BLACK}Schiff umrüsten
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Wähle die Frachtart aus, die das Schiff befördern soll
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Umrüstung des Schiffes auf die ausgewählte Frachtart
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Wähle Frachtart für die Beförderung:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Neue Kapazität: {GOLD}{CARGO}{}{BLACK}Kosten der Umrüstung: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Kann das Schiff nicht umrüsten...
+STR_9842_REFITTABLE :(umrüstbar)
+STR_GO_TO_SHIP_DEPOT :Fahre zu {TOWN} Schiffswerft
+SERVICE_AT_SHIP_DEPOT :Wartung in der {TOWN} Schiffswerft
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Flughäfen
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Flughafen kann hier nicht gebaut werden...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} Flugzeughangar
+STR_A003_NEW_AIRCRAFT :{BLACK}Neues Flugzeug
+STR_CLONE_AIRCRAFT :{BLACK}Flugzeug duplizieren
+STR_CLONE_AIRCRAFT_INFO :{BLACK}Baut eine Kopie des Flugzeuges. Strg+Klick erzeugt gemeinsamen Fahrplan
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Baut eine Kopie des Flugzeuges. Klicke auf diese Schaltfläche und dann auf ein Flugzeug innerhalb oder außerhalb des Depots. Strg+Klick erzeugt gemeinsamen Fahrplan
+STR_A005_NEW_AIRCRAFT :{WHITE}Neues Flugzeug
+STR_A006_BUILD_AIRCRAFT :{BLACK}Flugzeug bauen
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Kann das Flugzeug nicht bauen...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} Flugzeug{P "" e}
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (Aufträge)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (Einzelheiten)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Alter: {LTBLUE}{STRING}{BLACK} Betriebskosten: {LTBLUE}{CURRENCY}/Jahr
+STR_A00E_MAX_SPEED :{BLACK}Höchstgeschwindigk.: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit lfd. Jahr: {LTBLUE}{CURRENCY} (letztes Jahr: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}Zuverlässigkeit: {LTBLUE}{COMMA}% {BLACK}Pannen seit letzter Wartung: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Gebaut: {LTBLUE}{NUM}{BLACK} Wert: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Kann das Flugzeug nicht in den Hangar schicken...
+STR_HEADING_FOR_HANGAR :{ORANGE}Unterwegs zu {STATION} Hangar
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}Unterwegs zu {STATION} Hangar, {VELOCITY}
+STR_HEADING_FOR_HANGAR_SERVICE :{LTBLUE}Wartung in {STATION} Hangar
+STR_HEADING_FOR_HANGAR_SERVICE_VEL :{LTBLUE}Wartung in {STATION} Hangar, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}Flugzeug {COMMA} wartet im Hangar
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Flugzeug ist auf dem Weg
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Kann das Flugzeug nicht anhalten/starten...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Das Flugzeug ist in der Luft
+STR_A019_CAPACITY :{BLACK}Kapazität: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Kapazität: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}Flugzeug muss im Hangar angehalten werden
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Kann das Flugzeug nicht verkaufen...
+STR_A01D_AIRPORT_CONSTRUCTION :Flughafenbau
+STR_A01E_BUILD_AIRPORT :{BLACK}Baue Flughafen
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Flugzeuge - für Einzelheiten auf das Flugzeug klicken
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Baue neues Flugzeug (setzt Flughafen mit Hangar voraus)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Flugzeuge - für Einzelheiten auf das Flugzeug klicken
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Baue neues Flugzeug
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}Zum Verkauf des Flugzeuges hierher ziehen
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Ansicht auf den Hangar zentrieren
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Flugzeugauswahlliste - Klicke auf das Flugzeug für weitere Einzelheiten
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Baue das augewählte Flugzeug
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Laufende Flugzeugbewegung - Klicke hier, um das Flugzeug anzuhalten / zu starten
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Zeige Aufträge für das Flugzeug
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Ansicht auf das Flugzeug zentrieren
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Schicke das Flugzeug in den Hangar
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Zeige Einzelheiten des Flugzeuges
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}Neues Flugzeug ist jetzt verfügbar!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Kosten: {CURRENCY} Höchstgeschwindigk.: {VELOCITY}{}Kapazität: {COMMA} Passagiere, {COMMA} Postsäcke{}Betriebskosten: {CURRENCY}/Jahr
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Flugzeugname
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Kann Flugzeugname nicht vergeben...
+STR_A032_NAME_AIRCRAFT :{BLACK}Flugzeugname
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Die Stadt feiert . . .{}Erstes Flugzeug landet auf {STATION}!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Flugzeugabsturz!{}{COMMA} sterben in einem Feuerball auf {STATION}
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Flugzeugabsturz!{}Dem Flugzeug ging der Treibstoff aus, {COMMA} sterben in einem Feuerball!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Umbenennen
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Flugzeug umbenennen
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Flugzeug umbenennen
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Kann das Flugzeug nicht umbenennen...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Umrüstung des Flugzeuges zum Transport anderer Frachten
+STR_A03C_REFIT :{WHITE}{VEHICLE} (Umrüstung)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Flugzeug umrüsten
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Wähle die Fracht, die das Flugzeug transportieren soll
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Umrüstung des Flugzeuges auf die ausgewählte Frachtart
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Wähle Frachtart für Umrüstung aus:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Neue Kapazität: {GOLD}{STRING}{}{BLACK}Kosten der Umrüstung: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Kann das Flugzeug nicht umrüsten...
+STR_GO_TO_AIRPORT_HANGAR :Fliege zu {STATION} Hangar
+SERVICE_AT_AIRPORT_HANGAR :Wartung im {STATION} Hangar
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}Zeppelinabsturz bei {STATION}!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Fahrzeug bei Zusammenstoß mit einem 'UFO' zerstört!
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}Explosion einer Ölraffinerie nahe {TOWN}!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}Fabrik nahe {TOWN} unter mysteriösen Umständen zerstört!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}'UFO' landet bei {TOWN}!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}Stolleneinbruch hinterläßt einen Pfad der Zerstörung bei {TOWN}!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Hochwasser!{}Mindestens {COMMA} Mensch{P "" en} vermisst oder tot nach schwerer Flut!
+
+STR_BRIBE_FAILED :{WHITE}Ihr Bestechungsversuch wurde
+STR_BRIBE_FAILED_2 :{WHITE}von einem regionalen Untersuchungsbeamten aufgedeckt.
+STR_BUILD_DATE :{BLACK}Errichtet am: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Leistungsaufschlüsselung
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}Details
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Fahrzeuge:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Stationen:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Min. Profit:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Min. Einkom.:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Max. Einkom.:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Geliefert:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Fracht:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Geld:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Kredit:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Gesamt:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Anzahl an Fahrzeugen (Straßenfahrzeuge, Züge, Schiffe und Flugzeuge/Helikopter)
+STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}Anzahl an Stationen (Jeder Teil einer Station zählt einzeln: Bahnhof, Ladeplatz, Busbahnhof, Flugplatz)
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}Geringster Profit der Fahrzeuge, die älter als 2 Jahre sind
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Geringste Monatseinnahmen in den letzten 12 Quartalen
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Höchste Monatseinnahmen in den letzten 12 Quartalen
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}In den letzten 4 Quartalen gelieferte Frachteinheiten
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}Im letzten Quartal gelieferte Frachttypen
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Bargeld
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}Schuldenfalle?
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Erreichte Punkte von der maximal erreichbaren Anzahl
+
+STR_NEWGRF_SETTINGS_BUTTON :{BLACK}NewGRF Einstellungen
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}Newgrf Einstellungen
+STR_NEWGRF_APPLY_CHANGES :{BLACK}Änderungen anwenden
+STR_NEWGRF_SET_PARAMETERS :{BLACK}Parameter setzen
+STR_NEWGRF_TIP :{BLACK}Eine Liste aller Newgrf-Sets, die installiert sind. Per Klick auswählen.
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}Keine Newgrf-Dateien installiert. Bitte Installationsanleitung im Handbuch nachschlagen.
+STR_NEWGRF_FILENAME :{BLACK}Dateiname: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
+STR_NEWGRF_MD5SUM :{BLACK}MD5-Summe: {SILVER}{STRING}
+STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}Du bist dabei Änderungen während eines laufenden Spiels zu machen. Dies kann zum Absturz von OpenTTD führen.{}Bist du Dir wirklich sicher?
+
+STR_NEWGRF_ADD :{BLACK}Hinzufügen
+STR_NEWGRF_ADD_TIP :{BLACK}Füge eine neue NewGRF Datei zu Liste hinzu
+STR_NEWGRF_REMOVE :{BLACK}Entfernen
+STR_NEWGRF_REMOVE_TIP :{BLACK}Entferne die ausgewählte NewGRF Datei von der Liste
+STR_NEWGRF_MOVEUP :{BLACK}Nach oben
+STR_NEWGRF_MOVEUP_TIP :{BLACK}Schiebe die ausgewählte NewGRF Datei in der Liste nach oben
+STR_NEWGRF_MOVEDOWN :{BLACK}Nach unten
+STR_NEWGRF_MOVEDOWN_TIP :{BLACK}Schiebe die ausgewählte NewGRF Datei in der Liste nach unten
+STR_NEWGRF_FILE_TIP :{BLACK}Eine Liste der installierten NewGRF Dateien. Wähle eine Datei und verändere deren Parameter
+STR_NEWGRF_PARAMETER :{BLACK}Parameter: {SILVER}{STRING}
+STR_NEWGRF_PARAMETER_QUERY :{BLACK}Schreibe neue NewGRF Parameter
+STR_NEWGRF_NO_INFO :{BLACK}Keine Informationen verfügbar
+
+STR_NEWGRF_ADD_CAPTION :{WHITE}Verfügbare NewGRF Dateien
+STR_NEWGRF_ADD_FILE :{BLACK}Zur Auswahl hinzufügen
+STR_NEWGRF_ADD_FILE_TIP :{BLACK}Füge die ausgewählte NewGRF Datei zu deiner Konfiguration hinzu
+STR_NEWGRF_RESCAN_FILES :{BLACK}Aktualisiere Dateiliste
+STR_NEWGRF_RESCAN_FILES_TIP :{BLACK}Aktualisiere die Liste der verfügbaren NewGRF Dateien
+STR_NEWGRF_DUPLICATE_GRFID :{WHITE}Kann die Datei nicht hinzufügen: doppelte GRF ID
+
+STR_NEWGRF_NOT_FOUND :{RED}Zugehörige Datei nicht gefunden
+STR_NEWGRF_DISABLED :{RED}Ausgeschaltet
+
+STR_CURRENCY_WINDOW :{WHITE}Eigene Währung
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Wechselkurs: {ORANGE}{CURRENCY} = £ {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Trennsymbol:
+STR_CURRENCY_PREFIX :{LTBLUE}Präfix:
+STR_CURRENCY_SUFFIX :{LTBLUE}Suffix:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Umstellung auf Euro: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Umstellung auf Euro: {ORANGE}nie
+STR_CURRENCY_PREVIEW :{LTBLUE}Vorschau: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Parameter für eigene Währung ändern
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} Z{P ug üge}
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} Straßenfahrzeug{P "" e}
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} Flugzeug{P "" e}
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} Schiff{P "" e}
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Zeige alle Züge, die diesen Bahnhof anfahren
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Zeige alle Fahrzeuge, die diese Station anfahren
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Zeige alle Flugzeuge, die diesen Flughafen anfliegen
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Zeige alle Schiffe, die diesen Hafen ansteuern
+
+STR_VEH_WITH_SHARED_ORDERS_LIST :{WHITE}Gemeinsamer Fahrplan von {COMMA} Fahrzeug{P "" en}
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}Zeige alle Fahrzeuge mit demselben Fahrplan
+
+### depot strings
+STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Möchtest du alle Fahrzeuge in diesem Depot verkaufen?
+
+STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP :{BLACK}Verkaufe alle Züge im Depot
+STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP :{BLACK}Verkaufe alle Fahrzeuge im Depot
+STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP :{BLACK}Verkaufe alle Schiffe in der Werft
+STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP :{BLACK}Verkaufe alle Flugzeuge im Hangar
+
+STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP :{BLACK}Zeige eine Liste mit allen Zügen, die dieses Depot anfahren
+STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP :{BLACK}Zeige eine Liste mit allen Fahrzeugen, die dieses Depot anfahren
+STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP :{BLACK}Zeige eine Liste mit allen Schiffen, die diese Werft anfahren
+STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP :{BLACK}Zeige alle Flugzeuge mit irgendeinem Hangar dieses Flughafens in ihrem Flugplan
+
+STR_DEPOT_AUTOREPLACE_TRAIN_TIP :{BLACK}Ersetze alle Züge im Depot automatisch
+STR_DEPOT_AUTOREPLACE_ROADVEH_TIP :{BLACK}Ersetze alle Fahrzeuge im Depot automatisch
+STR_DEPOT_AUTOREPLACE_SHIP_TIP :{BLACK}Ersetze alle Schiffe in der Werft automatisch
+STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP :{BLACK}Ersetze alle Flugzeuge im Hangar automatisch
+
+STR_VEHICLE_LIST_TRAIN_DEPOT :{BLACK}{STRING} - {COMMA} {P Zug Züge}
+STR_VEHICLE_LIST_ROADVEH_DEPOT :{BLACK}{STRING} - {COMMA} Fahrzeug{P "" e}
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} Schiff{P "" e}
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} Flugzeug
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}Ersetze {STRING}
+STR_REPLACE_VEHICLES_START :{BLACK}Fahrzeugersetzung aktivieren
+STR_REPLACE_VEHICLES_STOP :{BLACK}Fahrzeugersetzung deaktivieren
+STR_NOT_REPLACING :{BLACK}Keine Ersetzung
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Kein Fahrzeug gewählt
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Wähle das zu ersetzende Fahrzeug
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Wähle den Fahrzeugtyp, der anstelle des links gewählten Fahrzeugs verwendet werden soll
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Drücke diesen Button, wenn das Fahrzeug auf der linken Seite nicht ersetzt werden soll
+STR_REPLACE_HELP_START_BUTTON :{BLACK}Drücke diesen Button, wenn das Fahrzeug auf der linken Seite durch das auf der rechten Seite gewählte ersetzt werden soll
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Wähle einen Schienentyp für den Loks ersetzt werden sollen
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Hier wird angezeigt, gegen welches Fahrzeug das auf der linken Seite gewählte ersetzt wird
+STR_REPLACE_HELP :{BLACK}Dieses Feature ermöglicht es, einen Fahrzeugtyp auszuwählen und ihn durch einen anderen ersetzen zu lassen. Dies geschieht automatisch, wenn das Fahrzeug regulär das Depot besucht.
+STR_REPLACE_REMOVE_WAGON :{BLACK}Waggon-Entfernung: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Zwinge das automatische Ersetzen die Länge eines Zuges beizubehalten, indem (vorne beginnend) Waggons entfernt werden, falls das Ersetzen der Lokomotive den Zug verlängern würde.
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}Ersetze: {ORANGE}{SKIP}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} EXPERIMENTELLE FUNKTION {}Umschalter für Lok- oder Waggonersetzung{}Waggons werden nur ersetzt, wenn der neue Waggon den selben Warentyp transportieren kann wie der alte. Dies wird beim Ersetzen eines jeden Waggons einzeln geprüft.
+STR_ENGINE_NOT_BUILDABLE :{WHITE}Lokomotive ist nicht baubar
+
+STR_ENGINES :Loks
+STR_WAGONS :Waggons
+
+STR_MASS_STOP_DEPOT_TRAIN_TIP :{BLACK}Hier klicken um alle Züge im Depot anzuhalten
+STR_MASS_STOP_DEPOT_ROADVEH_TIP :{BLACK}Hier klicken um alle Fahrzeuge im Depot anzuhalten
+STR_MASS_STOP_DEPOT_SHIP_TIP :{BLACK}Hier klicken um alle Schiffe in der Werft anzuhalten
+STR_MASS_STOP_HANGAR_TIP :{BLACK}Hier klicken um alle Flugzeuge im Hangar anzuhalten
+
+STR_MASS_START_DEPOT_TRAIN_TIP :{BLACK}Hier klicken um alle Züge im Depot zu starten
+STR_MASS_START_DEPOT_ROADVEH_TIP :{BLACK}Hier klicken um alle Fahrzeuge im Depot zu starten
+STR_MASS_START_DEPOT_SHIP_TIP :{BLACK}Hier klicken um alle Schiffe in der Werft zu starten
+STR_MASS_START_HANGAR_TIP :{BLACK}Hier klicken um alle Flugzeuge im Hangar zu starten
+
+STR_MASS_STOP_LIST_TIP :{BLACK}Hier klicken um alle Fahrzeuge in der Liste anzuhalten
+STR_MASS_START_LIST_TIP :{BLACK}Hier klicken um alle Fahrzeuge in der Liste zu starten
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}Schilderliste - {COMMA} Schild{P "" er}
+
+STR_ORDER_REFIT_FAILED :{WHITE}{STRING} {COMMA} wurde wegen Problemen beim Umrüsten angehalten
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :Eisenbahn
+STR_ELRAIL_VEHICLES :E-Loks
+STR_MONORAIL_VEHICLES :Einschienenbahn
+STR_MAGLEV_VEHICLES :Magnetschwebebahn
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Kosten: {GOLD}{CURRENCY}{BLACK} Gewicht: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Geschwindigk.: {GOLD}{VELOCITY}{BLACK} Leistung: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}Geschwindigkeit: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Betriebskosten: {GOLD}{CURRENCY}/Jahr
+STR_PURCHASE_INFO_CAPACITY :{BLACK}Kapazität: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Entwurf: {GOLD}{NUM}{BLACK} Lebensdauer: {GOLD}{COMMA} Jahre
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}Max. Zuverlässigkeit: {GOLD}{COMMA}%
+STR_PURCHASE_INFO_COST :{BLACK}Kosten: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Gewicht: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Kosten: {GOLD}{CURRENCY}{BLACK} Geschwindigk.: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Kapazität: {GOLD}{COMMA} Passagiere, {COMMA} Postsäcke
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Angetriebene Waggons: {GOLD}+{POWER}{BLACK} Gewicht: {GOLD}+{WEIGHT_S}
+STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Umrüstbar auf: {GOLD}
+STR_PURCHASE_INFO_ALL_TYPES :Alle Frachtarten
+STR_PURCHASE_INFO_ALL_BUT :Alles außer {GOLD}
+STR_PURCHASE_INFO_MAX_TE :{BLACK}Max. Zugkraft: {GOLD}{FORCE}
+
+########### String for New Landscape Generator
+
+STR_GENERATE :{WHITE}Erzeugen
+STR_RANDOM :{BLACK}Zufällig
+STR_RANDOM_HELP :{BLACK}Ändere den Zufallsstartwert für die Landschaftsgenerierung
+STR_WORLD_GENERATION_CAPTION :{WHITE}Welterstellung
+STR_RANDOM_SEED :{BLACK}Zufallsstartwert:
+STR_RANDOM_SEED_HELP :{BLACK}Gib einen Zufallsstartwert ein
+STR_LAND_GENERATOR :{BLACK}Landgenerator:
+STR_TREE_PLACER :{BLACK}Baumalgorithmus
+STR_HEIGHTMAP_ROTATION :{BLACK}Kartendrehung:
+STR_TERRAIN_TYPE :{BLACK}Landschaftstyp:
+STR_QUANTITY_OF_SEA_LAKES :{BLACK}Gewässermenge:
+STR_SMOOTHNESS :{BLACK}Weichheit:
+STR_SNOW_LINE_HEIGHT :{BLACK}Schneegrenze
+STR_DATE :{BLACK}Datum:
+STR_NUMBER_OF_TOWNS :{BLACK}Städteanzahl:
+STR_NUMBER_OF_INDUSTRIES :{BLACK}Industriedichte:
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_SNOW_LINE_UP :{BLACK}Höhenstufe der Schneegrenze um eins erhöhen
+STR_SNOW_LINE_DOWN :{BLACK}Höhenstufe der Schneegrenze um eins reduzieren
+STR_SNOW_LINE_QUERY_CAPT :{WHITE}Ändere die Höhe der Schneegrenze
+STR_START_DATE_QUERY_CAPT :{WHITE}Ändere Startjahr
+STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Skalierungswarnung
+STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Zu starke Skalierung der Karte ist nicht empfohlen. Trotzdem Generierung fortsetzen?
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_HEIGHTMAP_NAME :{BLACK}Reliefkartenname:
+STR_HEIGHTMAP_SIZE :{BLACK}Größe: {ORANGE}{NUM} x {NUM}
+STR_GENERATION_WORLD :{WHITE}Generiere Welt...
+STR_GENERATION_ABORT :{BLACK}Abbrechen
+STR_GENERATION_ABORT_CAPTION :{WHITE}Weltgenerierung abbrechen
+STR_GENERATION_ABORT_MESSAGE :{YELLOW}Soll die Weltgenerierung wirklich abgebrochen werden?
+STR_PROGRESS :{WHITE}{NUM}% abgeschlossen
+STR_GENERATION_PROGRESS :{BLACK}{NUM} / {NUM}
+STR_WORLD_GENERATION :{BLACK}Welterstellung
+STR_TREE_GENERATION :{BLACK}Baumerzeugung
+STR_UNMOVABLE_GENERATION :{BLACK}Erzeuge unbewegbare Objekte
+STR_CLEARING_TILES :{BLACK}Erzeuge leere, felsige Landschaft
+STR_SETTINGUP_GAME :{BLACK}Bereite Spiel vor
+STR_PREPARING_TILELOOP :{BLACK}Belebe Welt
+STR_PREPARING_GAME :{BLACK}Bereite Spiel vor
+STR_DIFFICULTY_TO_CUSTOM :{WHITE}Diese Aktion änderte den Schwierigkeitsgrad zu individuell
+STR_SE_FLAT_WORLD :{WHITE}Flache Landschaft
+STR_SE_FLAT_WORLD_TIP :{BLACK}Erzeuge flache Landschaft
+STR_SE_RANDOM_LAND :{WHITE}Zufällige Landschaft
+STR_SE_NEW_WORLD :{BLACK}Erzeuge neues Szenario
+STR_SE_CAPTION :{WHITE}Szenariotyp
+STR_FLAT_WORLD_HEIGHT_DOWN :{BLACK}Höhenstufe des flachen Landes um eins reduzieren
+STR_FLAT_WORLD_HEIGHT_UP :{BLACK}Höhenstufe das flachen Landes um eins erhöhen
+STR_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Ändere die Höhenstufe des flachen Landes
+STR_FLAT_WORLD_HEIGHT :{BLACK}Höhe des Flachlands:
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+STR_SMALLMAP_CENTER :{BLACK}Zentriere Zusatzansicht auf akutelle Position
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}klein
+STR_CITY_AIRPORT :{BLACK}Stadt
+STR_METRO_AIRPORT :{BLACK}städtischer Flughafen
+STR_INTERNATIONAL_AIRPORT :{BLACK}internationaler Flughafen
+STR_COMMUTER_AIRPORT :{BLACK}Nahverkehr
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Interkontinental
+STR_HELIPORT :{BLACK}Hubschrauberlandeplatz
+STR_HELIDEPOT :{BLACK}Hubschrauberhalle
+STR_HELISTATION :{BLACK}Hubschrauberstation
+
+STR_SMALL_AIRPORTS :{BLACK}kleine Flughäfen
+STR_LARGE_AIRPORTS :{BLACK}große Flughäfen
+STR_HUB_AIRPORTS :{BLACK}Großflughäfen
+STR_HELIPORTS :{BLACK}Flughäfen für Hubschrauber
+
+############ Tooltip measurment
+
+STR_MEASURE_LENGTH :{BLACK}Länge: {NUM}
+STR_MEASURE_AREA :{BLACK}Gebiet: {NUM} x {NUM}
+STR_MEASURE_LENGTH_HEIGHTDIFF :{BLACK}Länge: {NUM}{}Höhenunterschied: {NUM} m
+STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}Gebiet: {NUM} x {NUM}{}Höhenunterschied: {NUM} m
+
+########
diff --git a/src/lang/hungarian.txt b/src/lang/hungarian.txt
new file mode 100644
index 000000000..df4ca5a67
--- /dev/null
+++ b/src/lang/hungarian.txt
@@ -0,0 +1,3217 @@
+##name Hungarian
+##ownname Magyar
+##isocode hu_HU.UTF-8
+##plural 1
+##case t ba
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Kilóg a térképről
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Túl közel van a térkép széléhez
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Nincs elég pénzed - {CURRENCY} kellene
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Sima talaj szükséges
+STR_0008_WAITING :{BLACK}Várakozik: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (elvitelre
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Elfogad:{WHITE}
+STR_000D_ACCEPTS :{BLACK}Elfogad:{GOLD}
+STR_000E :
+STR_000F_PASSENGERS :Utas
+STR_000F_PASSENGERS.t :Utast
+STR_0010_COAL :Szén
+STR_0010_COAL.ba :Szénbe
+STR_0010_COAL.t :Szenet
+STR_0011_MAIL :Levél
+STR_0011_MAIL.t :Levelet
+STR_0012_OIL :Olaj
+STR_0012_OIL.t :Olajat
+STR_0013_LIVESTOCK :Ãllat
+STR_0013_LIVESTOCK.t :Ãllatot
+STR_0014_GOODS :Ãru
+STR_0014_GOODS.t :Ãrut
+STR_0015_GRAIN :Búza
+STR_0015_GRAIN.t :Búzát
+STR_0016_WOOD :Fa
+STR_0016_WOOD.t :Fát
+STR_0017_IRON_ORE :Vasérc
+STR_0017_IRON_ORE.t :Vasércet
+STR_0018_STEEL :Acél
+STR_0018_STEEL.t :Acélt
+STR_0019_VALUABLES :Értéktárgyak
+STR_0019_VALUABLES.t :Értéktárgyakat
+STR_001A_COPPER_ORE :Rézérc
+STR_001A_COPPER_ORE.t :Rézércet
+STR_001B_MAIZE :Kukorica
+STR_001B_MAIZE.t :Kukoricát
+STR_001C_FRUIT :Gyümölcs
+STR_001C_FRUIT.t :Gyümölcsöt
+STR_001D_DIAMONDS :Gyémánt
+STR_001D_DIAMONDS.t :Gyémántot
+STR_001E_FOOD :Étel
+STR_001E_FOOD.t :Ételt
+STR_001F_PAPER :Papír
+STR_001F_PAPER.t :Papírt
+STR_0020_GOLD :Arany
+STR_0020_GOLD.t :Aranyat
+STR_0021_WATER :Víz
+STR_0021_WATER.t :Vízet
+STR_0022_WHEAT :Búza
+STR_0022_WHEAT.t :Búzát
+STR_0023_RUBBER :Gumi
+STR_0023_RUBBER.t :Gumit
+STR_0024_SUGAR :Cukor
+STR_0024_SUGAR.t :Cukort
+STR_0025_TOYS :Játék
+STR_0025_TOYS.t :Játékot
+STR_0026_CANDY :Cukorka
+STR_0026_CANDY.t :Cukorkát
+STR_0027_COLA :Kóla
+STR_0027_COLA.t :Kólát
+STR_0028_COTTON_CANDY :Vattacukor
+STR_0028_COTTON_CANDY.t :Vattacukrot
+STR_0029_BUBBLES :Buborék
+STR_0029_BUBBLES.t :Buborékot
+STR_002A_TOFFEE :Tejkaramella
+STR_002A_TOFFEE.t :Tejkaramellát
+STR_002B_BATTERIES :Elem
+STR_002B_BATTERIES.t :Elemet
+STR_002C_PLASTIC :Műanyag
+STR_002C_PLASTIC.t :Műanyagot
+STR_002D_FIZZY_DRINKS :Szénsavas ital
+STR_002D_FIZZY_DRINKS.t :Szénsavas italt
+STR_002E :
+STR_002F_PASSENGER :utas
+STR_0030_COAL :szén
+STR_0031_MAIL :levél
+STR_0032_OIL :olaj
+STR_0033_LIVESTOCK :állat
+STR_0034_GOODS :áru
+STR_0035_GRAIN :búza
+STR_0036_WOOD :fa
+STR_0037_IRON_ORE :vasérc
+STR_0038_STEEL :acél
+STR_0039_VALUABLES :értéktárgy
+STR_003A_COPPER_ORE :rézérc
+STR_003B_MAIZE :kukorica
+STR_003C_FRUIT :gyümölcs
+STR_003D_DIAMOND :gyémánt
+STR_003E_FOOD :étel
+STR_003F_PAPER :papír
+STR_0040_GOLD :arany
+STR_0041_WATER :víz
+STR_0042_WHEAT :búza
+STR_0043_RUBBER :gumi
+STR_0044_SUGAR :cukor
+STR_0045_TOY :játék
+STR_0046_CANDY :cukorka
+STR_0047_COLA :kóla
+STR_0048_COTTON_CANDY :vattacukor
+STR_0049_BUBBLE :buborék
+STR_004A_TOFFEE :tejkaramella
+STR_004B_BATTERY :elem
+STR_004C_PLASTIC :műanyag
+STR_004D_FIZZY_DRINK :szénsavas ital
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} utas
+STR_QUANTITY_COAL :{WEIGHT} szén
+STR_QUANTITY_MAIL :{COMMA} csomag levél
+STR_QUANTITY_OIL :{VOLUME} olaj
+STR_QUANTITY_LIVESTOCK :{COMMA} állat
+STR_QUANTITY_GOODS :{COMMA} láda áru
+STR_QUANTITY_GRAIN :{WEIGHT} búza
+STR_QUANTITY_WOOD :{WEIGHT} fa
+STR_QUANTITY_IRON_ORE :{WEIGHT} vasérc
+STR_QUANTITY_STEEL :{WEIGHT} acél
+STR_QUANTITY_VALUABLES :{COMMA} csomag értéktárgy
+STR_QUANTITY_COPPER_ORE :{WEIGHT} rézérc
+STR_QUANTITY_MAIZE :{WEIGHT} kukorica
+STR_QUANTITY_FRUIT :{WEIGHT} gyümölcs
+STR_QUANTITY_DIAMONDS :{COMMA} zsák gyémánt
+STR_QUANTITY_FOOD :{WEIGHT} étel
+STR_QUANTITY_PAPER :{WEIGHT} papír
+STR_QUANTITY_GOLD :{COMMA} zsák arany
+STR_QUANTITY_WATER :{VOLUME} víz
+STR_QUANTITY_WHEAT :{WEIGHT} búza
+STR_QUANTITY_RUBBER :{VOLUME} gumi
+STR_QUANTITY_SUGAR :{WEIGHT} cukor
+STR_QUANTITY_TOYS :{COMMA} játék
+STR_QUANTITY_SWEETS :{COMMA} zsák cukorka
+STR_QUANTITY_COLA :{VOLUME} kóla
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} vattacukor
+STR_QUANTITY_BUBBLES :{COMMA} buborék
+STR_QUANTITY_TOFFEE :{WEIGHT} tejkaramella
+STR_QUANTITY_BATTERIES :{COMMA} elem
+STR_QUANTITY_PLASTIC :{VOLUME} műanyag
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} szénsavas ital
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}UT
+STR_ABBREV_COAL :{TINYFONT}SZ
+STR_ABBREV_MAIL :{TINYFONT}LV
+STR_ABBREV_OIL :{TINYFONT}OL
+STR_ABBREV_LIVESTOCK :{TINYFONT}ÃL
+STR_ABBREV_GOODS :{TINYFONT}ÃR
+STR_ABBREV_GRAIN :{TINYFONT}BZ
+STR_ABBREV_WOOD :{TINYFONT}FA
+STR_ABBREV_IRON_ORE :{TINYFONT}VÉ
+STR_ABBREV_STEEL :{TINYFONT}AC
+STR_ABBREV_VALUABLES :{TINYFONT}ÉP
+STR_ABBREV_COPPER_ORE :{TINYFONT}RÉ
+STR_ABBREV_MAIZE :{TINYFONT}KU
+STR_ABBREV_FRUIT :{TINYFONT}GÜ
+STR_ABBREV_DIAMONDS :{TINYFONT}GM
+STR_ABBREV_FOOD :{TINYFONT}ÉT
+STR_ABBREV_PAPER :{TINYFONT}PR
+STR_ABBREV_GOLD :{TINYFONT}AR
+STR_ABBREV_WATER :{TINYFONT}VZ
+STR_ABBREV_WHEAT :{TINYFONT}BZ
+STR_ABBREV_RUBBER :{TINYFONT}GM
+STR_ABBREV_SUGAR :{TINYFONT}CU
+STR_ABBREV_TOYS :{TINYFONT}JT
+STR_ABBREV_SWEETS :{TINYFONT}CK
+STR_ABBREV_COLA :{TINYFONT}KL
+STR_ABBREV_CANDYFLOSS :{TINYFONT}VC
+STR_ABBREV_BUBBLES :{TINYFONT}BB
+STR_ABBREV_TOFFEE :{TINYFONT}TK
+STR_ABBREV_BATTERIES :{TINYFONT}EL
+STR_ABBREV_PLASTIC :{TINYFONT}MA
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}SS
+STR_ABBREV_NONE :{TINYFONT}SÃ
+STR_ABBREV_ALL :{TINYFONT}ÖS
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Térkép - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Beállítások
+STR_00B2_MESSAGE :{YELLOW}Ãœzenet
+STR_00B3_MESSAGE_FROM :{YELLOW}{STRING} üzenete
+STR_POPUP_CAUTION_CAPTION :{WHITE}Figyelem!
+STR_00B4_CAN_T_DO_THIS :{WHITE}Nem teheted ezt...
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Nem tisztíthatod meg a területet...
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Copyright {COPYRIGHT} 1995 Chris Sawyer, Minden jog fenntartva
+STR_00B7_VERSION :{BLACK}OpenTTD version {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 Az OpenTTD csapat
+STR_TRANSLATED_BY :{BLACK} Fordítók -
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Kilépés
+STR_00C8_YES :{BLACK}Igen
+STR_00C9_NO :{BLACK}Nem
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Biztosan bezárod ezt a programot és kilépsz a {STRING}ba ?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :semmi
+STR_00D1_DARK_BLUE :Sötétkék
+STR_00D2_PALE_GREEN :Halványzöld
+STR_00D3_PINK :Rózsaszín
+STR_00D4_YELLOW :Sárga
+STR_00D5_RED :Piros
+STR_00D6_LIGHT_BLUE :Világoskék
+STR_00D7_GREEN :Zöld
+STR_00D8_DARK_GREEN :Sötétzöld
+STR_00D9_BLUE :Kék
+STR_00DA_CREAM :Krémszín
+STR_00DB_MAUVE :Mályvaszín
+STR_00DC_PURPLE :Lila
+STR_00DD_ORANGE :Narancssárga
+STR_00DE_BROWN :Barna
+STR_00DF_GREY :Szürke
+STR_00E0_WHITE :Fehér
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Túl sok jármű van a játékban
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Megnéz
+STR_00E5_CONTOURS :Domborzat
+STR_00E6_VEHICLES :Járművek
+STR_00E7_INDUSTRIES :Gazdaság
+STR_00E8_ROUTES :Utak
+STR_00E9_VEGETATION :Növényzet
+STR_00EA_OWNERS :Tulajdonosok
+STR_00EB_ROADS :{BLACK}{TINYFONT}Út
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Vasút
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Ãllomás/Reptér/KikötÅ‘
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Épület/Gazdasági épület
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Jármű
+STR_00F0_100M :{BLACK}{TINYFONT}100m
+STR_00F1_200M :{BLACK}{TINYFONT}200m
+STR_00F2_300M :{BLACK}{TINYFONT}300m
+STR_00F3_400M :{BLACK}{TINYFONT}400m
+STR_00F4_500M :{BLACK}{TINYFONT}500m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Vonat
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Közúti jármű
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Hajó
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Repülőgép
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Szállítási útvonal
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}szénbánya
+STR_00FA_COAL_MINE.t :{BLACK}{TINYFONT}szénbányát
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}erőmű
+STR_00FB_POWER_STATION.t :{BLACK}{TINYFONT}erőművet
+STR_00FC_FOREST :{BLACK}{TINYFONT}erdő
+STR_00FC_FOREST.t :{BLACK}{TINYFONT}erdőt
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}fűrésztelep
+STR_00FD_SAWMILL.t :{BLACK}{TINYFONT}fűrésztelepet
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}olajfinomító
+STR_00FE_OIL_REFINERY.t :{BLACK}{TINYFONT}olajfinomítót
+STR_00FF_FARM :{BLACK}{TINYFONT}farm
+STR_00FF_FARM.t :{BLACK}{TINYFONT}farmot
+STR_0100_FACTORY :{BLACK}{TINYFONT}gyár
+STR_0100_FACTORY.t :{BLACK}{TINYFONT}gyárat
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}nyomda
+STR_0101_PRINTING_WORKS.t :{BLACK}{TINYFONT}nyomdát
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}olajkút
+STR_0102_OIL_WELLS.t :{BLACK}{TINYFONT}olajkútat
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}vasércbánya
+STR_0103_IRON_ORE_MINE.t :{BLACK}{TINYFONT}vasércbányát
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}acélöntő
+STR_0104_STEEL_MILL.t :{BLACK}{TINYFONT}acélöntőt
+STR_0105_BANK :{BLACK}{TINYFONT}bank
+STR_0105_BANK.t :{BLACK}{TINYFONT}bankot
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}papírgyár
+STR_0106_PAPER_MILL.t :{BLACK}{TINYFONT}papírgyárat
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}aranybánya
+STR_0107_GOLD_MINE.t :{BLACK}{TINYFONT}aranybányát
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}konzervgyár
+STR_0108_FOOD_PROCESSING_PLANT.t :{BLACK}{TINYFONT}konzervgyárat
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}gyémántbánya
+STR_0109_DIAMOND_MINE.t :{BLACK}{TINYFONT}gyémántbányát
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}rézércbánya
+STR_010A_COPPER_ORE_MINE.t :{BLACK}{TINYFONT}rézércbányát
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}gyümölcsültetvény
+STR_010B_FRUIT_PLANTATION.t :{BLACK}{TINYFONT}gyümölcsültetvényt
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}gumiültetvény
+STR_010C_RUBBER_PLANTATION.t :{BLACK}{TINYFONT}gumiültetvényt
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}vízforrás
+STR_010D_WATER_SUPPLY.t :{BLACK}{TINYFONT}vízforrást
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}víztorony
+STR_010E_WATER_TOWER.t :{BLACK}{TINYFONT}víztornyot
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}favágó
+STR_010F_LUMBER_MILL.t :{BLACK}{TINYFONT}favágót
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}vattacukor-erdő
+STR_0110_COTTON_CANDY_FOREST.t :{BLACK}{TINYFONT}vattacukor-erdőt
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}cukorkagyár
+STR_0111_CANDY_FACTORY.t :{BLACK}{TINYFONT}cukorkagyárat
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}elemfarm
+STR_0112_BATTERY_FARM.t :{BLACK}{TINYFONT}elemfarmot
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}kólakút
+STR_0113_COLA_WELLS.t :{BLACK}{TINYFONT}kólakútat
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}játékbolt
+STR_0114_TOY_SHOP.t :{BLACK}{TINYFONT}játékboltot
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}játékgyár
+STR_0115_TOY_FACTORY.t :{BLACK}{TINYFONT}játékgyárat
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}műanyagforrás
+STR_0116_PLASTIC_FOUNTAINS.t :{BLACK}{TINYFONT}műanyagforrást
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}üdítőital-gyár
+STR_0117_FIZZY_DRINK_FACTORY.t :{BLACK}{TINYFONT}üdítőital-gyárat
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}buborékgenerátor
+STR_0118_BUBBLE_GENERATOR.t :{BLACK}{TINYFONT}buborékgenerátort
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}tejkaramella fejtő
+STR_0119_TOFFEE_QUARRY.t :{BLACK}{TINYFONT}tejkaramella fejtőt
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}cukorbánya
+STR_011A_SUGAR_MINE.t :{BLACK}{TINYFONT}cukorbányát
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Vasútállomás
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Teherautó-rakodóhely
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Buszmegálló
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Repülőtér/Helikopter-leszálló
+STR_011F_DOCK :{BLACK}{TINYFONT}Kikötő
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Göröngyös talaj
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Füves talaj
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Csupasz föld
+STR_0123_FIELDS :{BLACK}{TINYFONT}Szántóföld
+STR_0124_TREES :{BLACK}{TINYFONT}Fa
+STR_0125_ROCKS :{BLACK}{TINYFONT}KÅ‘
+STR_0126_WATER :{BLACK}{TINYFONT}Víz
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Nincs tulajdonos
+STR_0128_TOWNS :{BLACK}{TINYFONT}Város
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Gazdasági épület
+STR_012A_DESERT :{BLACK}{TINYFONT}Sivatag
+STR_012B_SNOW :{BLACK}{TINYFONT}Hó
+STR_012C_MESSAGE :{WHITE}Ãœzenet
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Mégsem
+STR_012F_OK :{BLACK}OK
+STR_0130_RENAME :{BLACK}Ãtnevez
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Túl sok név van megadva
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}A megadott név már használatban van
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}... {STRING} tulajdona
+STR_013C_CARGO :{BLACK}Rakomány
+STR_013D_INFORMATION :{BLACK}Információ
+STR_013E_CAPACITIES :{BLACK}Kapacitás
+STR_013E_TOTAL_CARGO :{BLACK}Teljes rakomány
+STR_013F_CAPACITY :{BLACK}Kapacitás: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}Kapacitás: {LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Teljes rakománya (kapacitása) ennek a vonatnak:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}Új játék
+STR_0141_LOAD_GAME :{BLACK}Játék betöltése
+STR_SINGLE_PLAYER :{BLACK}Egyjátékos
+STR_MULTIPLAYER :{BLACK}Hálózati játék
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Méret:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Beállítások
+
+STR_0150_SOMEONE :valaki{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Világtérkép
+STR_0152_TOWN_DIRECTORY :Városlista
+STR_0153_SUBSIDIES :Támogatások
+
+STR_UNITS_IMPERIAL :Brit
+STR_UNITS_METRIC :Metrikus
+STR_UNITS_SI :SI
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} mf/h
+STR_UNITS_VELOCITY_METRIC :{COMMA} km/h
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}lóerő
+STR_UNITS_POWER_METRIC :{COMMA}lóerő
+STR_UNITS_POWER_SI :{COMMA}kW
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} tonna
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} tonna
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} kg
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}gal
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}l
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}m³
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} gallon
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} liter
+STR_UNITS_VOLUME_LONG_SI :{COMMA} köbméter
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10³ lbf
+STR_UNITS_FORCE_METRIC :{COMMA} 9.81*10³ N
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Működési nyereség grafikon
+STR_0155_INCOME_GRAPH :Jövedelem grafikon
+STR_0156_DELIVERED_CARGO_GRAPH :Elszállított rakomány grafikon
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Teljesítmény grafikon
+STR_0158_COMPANY_VALUE_GRAPH :Vállalat értéke grafikon
+STR_0159_CARGO_PAYMENT_RATES :Rakományok szállítási díja
+STR_015A_COMPANY_LEAGUE_TABLE :A cégek helyezése
+STR_PERFORMANCE_DETAIL_MENU :Teljesítményértékelések részletezése
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}OpenTTD
+STR_015C_SAVE_GAME :Játék mentése
+STR_015D_LOAD_GAME :Jaték betöltése
+STR_015E_QUIT_GAME :Kilépés a játékból
+STR_015F_QUIT :Kilépés
+STR_ABANDON_GAME_QUERY :{YELLOW}Biztosan kilépsz ebből a játékból ?
+STR_0161_QUIT_GAME :{WHITE}Kilépés a játékból
+STR_SORT_ORDER_TIP :{BLACK}Csökkenő/növekvő sorbarendezés
+STR_SORT_CRITERIA_TIP :{BLACK}Sorbarendezési kritérium
+STR_SORT_BY :{BLACK}Rendezés
+
+STR_SORT_BY_POPULATION :{BLACK}Lakosság
+STR_SORT_BY_PRODUCTION :{BLACK}Termelés
+STR_SORT_BY_TYPE :{BLACK}Típus
+STR_SORT_BY_TRANSPORTED :{BLACK}Elszállítás
+STR_SORT_BY_NAME :{BLACK}Név
+STR_SORT_BY_DROPDOWN_NAME :Név
+STR_SORT_BY_DATE :{BLACK}Dátum
+STR_SORT_BY_NUMBER :Szám
+STR_SORT_BY_PROFIT_LAST_YEAR :Tavalyi profit
+STR_SORT_BY_PROFIT_THIS_YEAR :Idei profit
+STR_SORT_BY_AGE :Életkor
+STR_SORT_BY_RELIABILITY :Megbízhatóság
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Rakomány szerinti összkapacitás
+STR_SORT_BY_MAX_SPEED :Maximum sebesség
+STR_SORT_BY_MODEL :Modell
+STR_SORT_BY_VALUE :Érték
+STR_SORT_BY_FACILITY :Ãllomás típus
+STR_SORT_BY_WAITING :Várakozó rakomány értéke
+STR_SORT_BY_RATING_MAX :Várakozó rakomány
+STR_ENGINE_SORT_ENGINE_ID :MozdonyID
+STR_ENGINE_SORT_COST :Ãr
+STR_ENGINE_SORT_POWER :Telj.
+STR_ENGINE_SORT_INTRO_DATE :Bevezetési dátum
+STR_ENGINE_SORT_RUNNING_COST :Üzemeltetési k.
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Telj./Üzemeltetési k.
+STR_ENGINE_SORT_CARGO_CAPACITY :Teherkapacitás
+STR_NO_WAITING_CARGO :{BLACK}Semmilyen áru nem várakozik
+STR_SELECT_ALL_FACILITIES :{BLACK}Minden szállítóegység kiválasztása
+STR_SELECT_ALL_TYPES :{BLACK}Minden rakománytípus mutatása (beleértve ha nincs várakozó rakomány)
+STR_MANAGE_LIST :{BLACK}Lista kezelése
+STR_MANAGE_LIST_TIP :{BLACK}A listán szereplő járműveknek utasítás küldése
+STR_REPLACE_VEHICLES :Járművek lecserélése
+STR_SEND_TRAIN_TO_DEPOT :Elküldi depóba
+STR_SEND_ROAD_VEHICLE_TO_DEPOT :Elküldi depóba
+STR_SEND_SHIP_TO_DEPOT :Elküldi dokkba
+STR_SEND_AIRCRAFT_TO_HANGAR :Elküldi hangárba
+STR_SEND_FOR_SERVICING :Javításra küld
+
+############ range for months starts
+STR_0162_JAN :jan
+STR_0163_FEB :feb
+STR_0164_MAR :már
+STR_0165_APR :ápr
+STR_0166_MAY :máj
+STR_0167_JUN :jún
+STR_0168_JUL :júl
+STR_0169_AUG :aug
+STR_016A_SEP :sze
+STR_016B_OCT :okt
+STR_016C_NOV :nov
+STR_016D_DEC :dec
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Játék szüneteltetése
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Játék mentése, kilépés a játékból, kilépés
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Ãllomások listája
+STR_0174_DISPLAY_MAP :{BLACK}Térkép
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Térkép, városlista
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Városlista
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Pénzügyi adatok
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Ãltalános adatok
+STR_0179_DISPLAY_GRAPHS :{BLACK}Grafikonok
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}A cégek helyezése
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Vonatok listája
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Közúti járművek listája
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Hajók listája
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Repülőgépek listája
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Közelítés
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Távolítás
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Vasúti sín lerakása
+STR_0182_BUILD_ROADS :{BLACK}Út építése
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Kikötő építése
+STR_0184_BUILD_AIRPORTS :{BLACK}Repülőtér építése
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Faültetés, feliratok lerakása stb.
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Terület-információ
+STR_0187_OPTIONS :{BLACK}Beállítások
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Nem változtathatod meg a javítási időközt...
+STR_018B_CLOSE_WINDOW :{BLACK}Az ablak bezárása
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Az ablak címsora - húzd ezt a mozgatáshoz
+STR_STICKY_BUTTON :{BLACK}Ez az ablak akkor se legyen becsukható ha az összes ablakot bezárjuk (Delete gomb)
+STR_RESIZE_BUTTON :{BLACK}Fogd és húzd hogy átméretezd az ablakot
+STR_SAVELOAD_HOME_BUTTON :{BLACK}Kattints ide az aktuális mentési könyvtárra való ugráshoz
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Tárgyak lerombolása egy mezőről
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Egy pont lesüllyesztése
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Egy pont megemelése
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Görgetősáv - fel/le görgeti a listát
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Görgetősáv - jobbra/balra görgeti a listát
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Domborzat mutatása a térképen
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Járművek mutatása a térképen
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Gazdasági épületek mutatása a térképen
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Szállítási útvonalak mutatása a térképen
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Növényzet mutatása a térképen
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Tulajdonosok mutatása a térképen
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Városnevek ki/be
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Idei nyereség: {CURRENCY} (Tavalyi: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} év ({COMMA})
+STR_AGE_RED :{RED}{COMMA} év ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :közúti jármű
+STR_019D_AIRCRAFT :repülőgép
+STR_019E_SHIP :hajó
+STR_019F_TRAIN :vonat
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} kezd elöregedni
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} kezd nagyon elöregedni
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} nagyon öreg és sürgősen ki kell cserélni
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Terület-információ
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}{LTBLUE}Nem lehet lerombolni
+STR_01A5_COST_TO_CLEAR :{BLACK}A megtisztítás költsége: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :Nincs
+STR_01A7_OWNER :{BLACK}Tulajdonos: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Helyi önkormányzat: {LTBLUE}{STRING}
+STR_01A9_NONE :Nincs
+STR_01AA_NAME :{BLACK}Név
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1.
+STR_01AD_2ND :2.
+STR_01AE_3RD :3.
+STR_01AF_4TH :4.
+STR_01B0_5TH :5.
+STR_01B1_6TH :6.
+STR_01B2_7TH :7.
+STR_01B3_8TH :8.
+STR_01B4_9TH :9.
+STR_01B5_10TH :10.
+STR_01B6_11TH :11.
+STR_01B7_12TH :12.
+STR_01B8_13TH :13.
+STR_01B9_14TH :14.
+STR_01BA_15TH :15.
+STR_01BB_16TH :16.
+STR_01BC_17TH :17.
+STR_01BD_18TH :18.
+STR_01BE_19TH :19.
+STR_01BF_20TH :20.
+STR_01C0_21ST :21.
+STR_01C1_22ND :22.
+STR_01C2_23RD :23.
+STR_01C3_24TH :24.
+STR_01C4_25TH :25.
+STR_01C5_26TH :26.
+STR_01C6_27TH :27.
+STR_01C7_28TH :28.
+STR_01C8_29TH :29.
+STR_01C9_30TH :30.
+STR_01CA_31ST :31.
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Elfogad: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Jazz zenegép
+STR_01D3_SOUND_MUSIC :Hang/zene
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Hang/zene beállítás
+STR_01D5_ALL :{TINYFONT}Mind
+STR_01D6_OLD_STYLE :{TINYFONT}Régi stílus
+STR_01D7_NEW_STYLE :{TINYFONT}Új stílus
+STR_01D8_EZY_STREET :{TINYFONT}Szép az élet
+STR_01D9_CUSTOM_1 :{TINYFONT}Saját 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Saját 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Zene hangereje
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Hangok hangereje
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MIN ' ' ' ' ' ' MAX
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Előző szám
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Következő szám
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Zene leállítása
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Zene elindítása
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}A csúszkákkal beállíthatod a zene és a hanghatások hangerejét
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Szám{SETX 88}Cím
+STR_01E9_SHUFFLE :{TINYFONT}Kever
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Műsor
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Zenei műsor kiválasztása
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Számlista
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}"{STRING}" műsora
+STR_01F0_CLEAR :{TINYFONT}{BLACK}Törlés
+STR_01F1_SAVE :{TINYFONT}{BLACK}Mentés
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Az aktuális műsor számai
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}A 'minden szám' műsor kiválasztása
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}A 'régi stílus' zenei műsor kiválasztása
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Az 'új stílus' zenei program kiválasztása
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}A 'Saját 1' (felhasználói) zenei műsor kiválasztása
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}A 'Saját 2' (felhasználói) zenei műsor kiválasztása
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Az aktuális műsor kiürítése (csak Saját 1 és Saját 2)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Zenei beállítások elmentése
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Egy számra kattintva hozzáadod azt a kiválasztott zenei műsorhoz (csak Saját 1 és Saját 2)
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Kattints a zeneszámra annak aktuális listából való eltávolításához (Custom1 és Custom2 esetén csak)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}A műsor megkeverése be/ki
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}A zenekiválasztó ablak megjelenítése
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Kattints egy sorra a város/gazdasági épület megnézéséhez
+STR_01FE_DIFFICULTY :{BLACK}Nehézség ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Legutóbbi üzenet/újsághír
+STR_0201_MESSAGE_SETTINGS :Üzenetek beállításai
+STR_MESSAGE_HISTORY_MENU :Előző üzenetek
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Legutóbbi üzenet/újsághír, üzenetek beállításai
+STR_0204_MESSAGE_OPTIONS :{WHITE}Üzenetek beállításai
+STR_0205_MESSAGE_TYPES :{BLACK}Üzenetfajták:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Első jármű megérkezése a játékos megállójába
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Első jármű megérkezése az ellenfél megállójába
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Balesetek / természeti csapások
+STR_0209_COMPANY_INFORMATION :{YELLOW}Céginformációk
+STR_020A_ECONOMY_CHANGES :{YELLOW}Gazdasági változások
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Tanácsok / információk a játékos járműveiről
+STR_020C_NEW_VEHICLES :{YELLOW}Új járművek
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Ãruk elfogadásának változásai
+STR_020E_SUBSIDIES :{YELLOW}Támogatások
+STR_020F_GENERAL_INFORMATION :{YELLOW}Ãltalános információk
+STR_MESSAGES_ALL :{YELLOW}Összes üzenettípus beállítása (be/rövid/ki)
+STR_MESSAGE_SOUND :{YELLOW}Figyelmeztető hang lejátszása rövid üzenetnél
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...túl távol van az előző céltól
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Legjobb cégek melyek elérték a {NUM}{}({STRING} Szintet)
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Cégdicsőség tábla {NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Ãœzletember
+STR_0214_ENTREPRENEUR :Vállalkozó
+STR_0215_INDUSTRIALIST :Iparos
+STR_0216_CAPITALIST :Tőkés
+STR_0217_MAGNATE :Mágnás
+STR_0218_MOGUL :Fejes
+STR_0219_TYCOON_OF_THE_CENTURY :Az évszázad iparmágnása
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} elérte a '{STRING}' rangot!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} - {COMPANY} elérte a '{STRING}' rangot!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Saját pálya készítése
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}pályaszerkesztő
+STR_0223_LAND_GENERATION :{WHITE}Táj szerkesztése
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Véletlenszerű táj
+STR_0227_RESET_LAND :{BLACK}Táj törlése
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Az emelendő/süllyesztendő földterület növelése
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Az emelendő/süllyesztendő földterület csökkentése
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Véletlenszerű táj készítése
+STR_022B_RESET_LANDSCAPE :{BLACK}A táj törlése
+STR_022C_RESET_LANDSCAPE :{WHITE}Táj törlése
+STR_LOAD_GAME_HEIGHTMAP :{WHITE}Magasságtérkép használata
+STR_LOAD_SCEN_HEIGHTMAP :{BLACK}Magasságtérkép használata
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Biztosan le akarod törölni az egész tájat?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Táj szerkesztése
+STR_022F_TOWN_GENERATION :{BLACK}Városkészítés
+STR_0230_INDUSTRY_GENERATION :{BLACK}Gazdasági épület készítése
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Útépítés
+STR_0233_TOWN_GENERATION :{WHITE}Városkészítés
+STR_0234_NEW_TOWN :{BLACK}Új város
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Új város építése
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Nem építhetsz ide várost...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...túl közel van a térkép széléhez
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...túl közel van egy másik városhoz
+STR_0239_SITE_UNSUITABLE :{WHITE}...nem alkalmas rá a hely
+STR_023A_TOO_MANY_TOWNS :{WHITE}...túl sok a város
+STR_CANNOT_GENERATE_TOWN :{WHITE}Nem lehet több várost építeni
+STR_NO_SPACE_FOR_TOWN :{WHITE}...nincs több hely a térképen
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}A város méretének növelése
+STR_023C_EXPAND :{BLACK}Növel
+STR_023D_RANDOM_TOWN :{BLACK}Véletlenszerű város
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Város építése véletlenszerű helyre
+STR_023F_INDUSTRY_GENERATION :{WHITE}Gazdasági épület készítése
+STR_0240_COAL_MINE :{BLACK}Szénbánya
+STR_0241_POWER_STATION :{BLACK}Erőmű
+STR_0242_SAWMILL :{BLACK}Fűrésztelep
+STR_0243_FOREST :{BLACK}Erdő
+STR_0244_OIL_REFINERY :{BLACK}Olajfinomító
+STR_0245_OIL_RIG :{BLACK}Olajfúró torony
+STR_0246_FACTORY :{BLACK}Gyár
+STR_0247_STEEL_MILL :{BLACK}Acélöntő
+STR_0248_FARM :{BLACK}Farm
+STR_0249_IRON_ORE_MINE :{BLACK}Vasércbánya
+STR_024A_OIL_WELLS :{BLACK}Olajkút
+STR_024B_BANK :{BLACK}Bank
+STR_024C_PAPER_MILL :{BLACK}Papírgyár
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Konzervgyár
+STR_024E_PRINTING_WORKS :{BLACK}Nyomda
+STR_024F_GOLD_MINE :{BLACK}Aranybánya
+STR_0250_LUMBER_MILL :{BLACK}Favágó
+STR_0251_FRUIT_PLANTATION :{BLACK}Gyümölcsültetvény
+STR_0252_RUBBER_PLANTATION :{BLACK}Gumiültetvény
+STR_0253_WATER_SUPPLY :{BLACK}Vízforrás
+STR_0254_WATER_TOWER :{BLACK}Víztorony
+STR_0255_DIAMOND_MINE :{BLACK}Gyémántbánya
+STR_0256_COPPER_ORE_MINE :{BLACK}Rézércbánya
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Vattacukor-erdő
+STR_0258_CANDY_FACTORY :{BLACK}Cukorkagyár
+STR_0259_BATTERY_FARM :{BLACK}Elemfarm
+STR_025A_COLA_WELLS :{BLACK}Kólakút
+STR_025B_TOY_SHOP :{BLACK}Játékbolt
+STR_025C_TOY_FACTORY :{BLACK}Játékgyár
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Műanyagforrás
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Üdítőital-gyár
+STR_025F_BUBBLE_GENERATOR :{BLACK}Buborékgenerátor
+STR_0260_TOFFEE_QUARRY :{BLACK}Tejkaramella-fejtő
+STR_0261_SUGAR_MINE :{BLACK}Cukorbánya
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Szénbánya építése
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Erőmű építése
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Fűrésztelep építése
+STR_0265_PLANT_FOREST :{BLACK}Erdő ültetése
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Olajfinomító építése
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Olajfúró torony építése (csak a térkép széléhez közel építhető)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Gyár építése
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Acélöntő építése
+STR_026A_CONSTRUCT_FARM :{BLACK}Farm építése
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Vasércbánya építése
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Olajkút építése
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Bank építése (csak 1200-nál nagyobb lakosságú városokban építhető)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Papírgyár építése
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Konzervgyár építése
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Nyomda építése
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Aranybánya építése
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Bank építése (csak városokba építhető)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Favágó építése (az esőerdő kivágására és fa termelésére)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Gyümölcsültetvény ültetése
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Gumiültetvény ültetése
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Vízforrás építése
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Víztorony építése (csak városokban építhető)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Gyémántbánya építése
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Rézércbánya építése
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Vattacukor-erdő ültetése
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Cukorkagyár építése
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Elemfarm építése
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Kólakút építése
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Játékbolt építése
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Játékgyár építése
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Műanyagforrás építése
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Üdítőital-gyár építése
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Buborékgenerátor építése
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Tejkaramella-fejtő építése
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Cukorbánya építése
+STR_0285_CAN_T_BUILD_HERE :{WHITE}Nem építhető ide {STRING}...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...előbb várost kell építened
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...városonként csak egy lehet
+STR_0288_PLANT_TREES :{BLACK}Faültetés
+STR_0289_PLACE_SIGN :{BLACK}Felirat lerakása
+STR_028A_RANDOM_TREES :{BLACK}Véletlenszerű fák
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Véletlenszerűen fákat ültet a térképre
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Sziklás területek elhelyezése a térképen
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Világítótorony építése
+STR_028E_PLACE_TRANSMITTER :{BLACK}Rádióadó építése
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Sivatagot hoz létre.{}Nyomj CTRL-t az eltávolításához
+STR_CREATE_LAKE :{BLACK}Vizet hoz létre.{}A tengerszinten lévő elemeket elárasztja
+STR_0290_DELETE :{BLACK}Töröl
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}A város teljes eltüntetése
+STR_0292_SAVE_SCENARIO :Pálya mentése
+STR_0293_LOAD_SCENARIO :Pálya betöltése
+STR_0294_QUIT_EDITOR :Kilépés a szerkesztőből
+STR_0295 :
+STR_0296_QUIT :Kilépés
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Pálya betöltése, mentése, kilépés a szerkesztőből, kilépés
+STR_0298_LOAD_SCENARIO :{WHITE}Pálya betöltése
+STR_0299_SAVE_SCENARIO :{WHITE}Pálya mentése
+STR_029A_PLAY_SCENARIO :{BLACK}Játék saját pályán
+STR_PLAY_HEIGHTMAP :{BLACK}Játék magasságtérképen
+STR_PLAY_HEIGHTMAP_HINT :{BLACK}Új játékot kezd egy magasságtérkép alapján
+STR_QUIT_SCENARIO_QUERY :{YELLOW}Biztosan abba akarod hagyni a pálya szerkesztését ?
+STR_029C_QUIT_EDITOR :{WHITE}Kilépés a szerkesztőből
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...csak 1200-nál nagyobb lakosságú városokba építhető
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}A kezdődátum visszább állítása egy évvel
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}A kezdődátum előrébb állítása egy évvel
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...a híd mindkét végének szárazföldön kell lennie
+STR_02A1_SMALL :{BLACK}Kicsi
+STR_02A2_MEDIUM :{BLACK}Közepes
+STR_02A3_LARGE :{BLACK}Nagy
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}A város méretének kiválasztása
+STR_02A5_TOWN_SIZE :{YELLOW}A város mérete:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Utolsó üzenet vagy újsághír megmutatása
+STR_OFF :Ki
+STR_SUMMARY :Kivonat
+STR_FULL :Teljes
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Városlista
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Járművek márkanevei
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Alap
+STR_02BF_CUSTOM :Saját
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Saját nevek mentése
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}A járművek márkanevének kiválasztása
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}A saját jármű-márkanevek elmentése lemezre
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Beállítások
+STR_02C5_DIFFICULTY_SETTINGS :Nehézségi beállítások
+STR_02C7_CONFIG_PATCHES :Foltok beállítása
+STR_NEWGRF_SETTINGS :Newgrf beállítások
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Városnevek mutatása
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Ãllomásnevek mutatása
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Feliratok mutatása
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Ellenőrző pontok mutatása
+STR_02D0_FULL_ANIMATION :{SETX 12}Teljes animáció
+STR_02D2_FULL_DETAIL :{SETX 12}Minden részlet
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Ãtlátszó épületek
+STR_TRANSPARENT_SIGNS :{SETX 12}Ãllomásnevek keret nélkül
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Terület-információ
+STR_02D6 :
+STR_CONSOLE_SETTING :Ãtváltás Konzolra
+STR_02D7_SCREENSHOT_CTRL_S :Képmentés (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Óriás képmentés (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :Az 'OpenTTD'-ről
+############ range ends here
+
+STR_02DB_OFF :{BLACK}Ki
+STR_02DA_ON :{BLACK}Be
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Ãllami támogatások
+STR_02DD_SUBSIDIES :Támogatások
+STR_02DE_MAP_OF_WORLD :Világtérkép
+STR_EXTRA_VIEW_PORT :Extra látkép
+STR_SIGN_LIST :Feliratok listája
+STR_02DF_TOWN_DIRECTORY :Városlista
+STR_TOWN_POPULATION :{BLACK}Világnépesség: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}{COMMA}. látkép
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Látkép aktualizálása
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Beállítja a globális látkép pozicióját erre a látképre
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Látkép visszatöltése
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}A látkép pozicióját beállítja a globális látképre
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Pénznem
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}A használt pénznem kiválasztása
+STR_MEASURING_UNITS :{BLACK}Mértékegységek
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Mértékegység választás
+STR_02E6_ROAD_VEHICLES :{BLACK}Közúti járművek
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Válaszd ki,az út melyik oldalán haladjanak a közúti járművek
+STR_02E9_DRIVE_ON_LEFT :Balra hajts
+STR_02EA_DRIVE_ON_RIGHT :Jobbra hajts
+STR_02EB_TOWN_NAMES :{BLACK}Városnevek
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}A városnevek stílusának kiválasztása
+
+STR_02F4_AUTOSAVE :{BLACK}Automatikus mentés
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Az automatikus mentések közötti időtartam kiválasztása
+STR_02F7_OFF :Nincs
+STR_02F8_EVERY_3_MONTHS :3 havonta
+STR_02F9_EVERY_6_MONTHS :6 havonta
+STR_02FA_EVERY_12_MONTHS :12 havonta
+STR_02FB_START_A_NEW_GAME :{BLACK}Új játék kezdése
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Mentett játék betöltése
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Testreszabott pálya készítése
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Egy játékos játék kiválasztása
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Hálózati játék választása 2-8 játékosig
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}A játék beállításainak megmutatása
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}A nehézségi beállítások megmutatása
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Új játék kezdése saját pályán
+STR_0304_QUIT :{BLACK}Kilépés
+STR_0305_QUIT_OPENTTD :{BLACK}Kilépés az OpenTTD-ből
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...csak városban építhető
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Mérsékelt táj kiválasztása
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Szubarktikus táj kiválasztása
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Szubtrópusi táj kiválasztása
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Játékvilág táj kiválasztása
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Gazdasági épület építése
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Gazdasági épületek listája
+STR_0313_FUND_NEW_INDUSTRY :Új gazdasági épület építése
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Új gazdasági épület
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...csak városban építhető
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...csak esőerdőben építhető
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...csak sivatagban építhető
+STR_0319_PAUSED :{YELLOW}* * SZÃœNET * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}A képernyő elmentve '{STRING}' néven
+STR_031C_SCREENSHOT_FAILED :{WHITE}A képmentés nem sikerült!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Föld megvétele későbbi használatra
+STR_032F_AUTOSAVE :{RED}Automatikus mentés
+STR_SAVING_GAME :{RED}* * JÃTÉK MENTÉSE * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}A mentés még tart,{}kérlek várd meg a végét!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}A 'szép az élet' zenei műsor kiválasztása
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :Angol (Eredeti)
+STR_TOWNNAME_FRENCH :Francia
+STR_TOWNNAME_GERMAN :Német
+STR_TOWNNAME_ADDITIONAL_ENGLISH :Angol (További)
+STR_TOWNNAME_LATIN_AMERICAN :Latin-Amerikai
+STR_TOWNNAME_SILLY :Komolytalan
+STR_TOWNNAME_SWEDISH :Svéd
+STR_TOWNNAME_DUTCH :Holland
+STR_TOWNNAME_FINNISH :Finn
+STR_TOWNNAME_POLISH :Lengyel
+STR_TOWNNAME_SLOVAKISH :Szlovák
+STR_TOWNNAME_NORWEGIAN :Norvég
+STR_TOWNNAME_HUNGARIAN :Magyar
+STR_TOWNNAME_AUSTRIAN :Osztrák
+STR_TOWNNAME_ROMANIAN :Romániai
+STR_TOWNNAME_CZECH :Cseh
+STR_TOWNNAME_SWISS :Svájci
+STR_TOWNNAME_DANISH :Dán
+STR_TOWNNAME_TURKISH :Török
+STR_TOWNNAME_ITALIAN :Olasz
+STR_TOWNNAME_CATALAN :Katalán
+############ end of townname region
+
+STR_CURR_GBP :Font (£)
+STR_CURR_USD :Dollár ($)
+STR_CURR_EUR :Euró (€)
+STR_CURR_YEN :Jen (Â¥)
+STR_CURR_ATS :Osztrák Shilling (ATS)
+STR_CURR_BEF :Belga Frank (BEF)
+STR_CURR_CHF :Svájci Frank (CHF)
+STR_CURR_CZK :Cseh Korona (CZK)
+STR_CURR_DEM :Német márka (DEM)
+STR_CURR_DKK :Dán Korona (DKK)
+STR_CURR_ESP :Pezeta (ESP)
+STR_CURR_FIM :Finn Márka (FIM)
+STR_CURR_FRF :Franc (FRF)
+STR_CURR_GRD :Görög Drachma (GRD)
+STR_CURR_HUF :Magyar Forint (HUF)
+STR_CURR_ISK :Izlandi Korona (ISK)
+STR_CURR_ITL :Olasz Líra (ITL)
+STR_CURR_NLG :Holland Guilder (NLG)
+STR_CURR_NOK :Norvég Korona (NOK)
+STR_CURR_PLN :Legyel Zlotyi (PLN)
+STR_CURR_ROL :Román Lej (ROL)
+STR_CURR_RUR :Orosz Rubel (RUR)
+STR_CURR_SIT :Szlovén Tolár (SIT)
+STR_CURR_SEK :Svéd Korona (SEK)
+STR_CURR_YTL :Török Lira (YTL)
+STR_CURR_SKK :Szlovák korona (SKK)
+STR_CURR_BRR :Brazil Real (BRL)
+
+STR_CURR_CUSTOM :Saját...
+
+STR_OPTIONS_LANG :{BLACK}Nyelv
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Válassz nyelvet
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Teljes képernyő
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}Jelöld be ezt, ha teljes képernyős módban szeretnél OpenTTD-zni
+
+STR_OPTIONS_RES :{BLACK}A képernyő felbontása
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Válaszd ki, milyen felbontást szeretnél a játékhoz
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Képmentés formátuma
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Válaszd ki milyen formátumú képmentést szeretnél
+
+STR_AUTOSAVE_1_MONTH :Minden hónapban
+STR_AUTOSAVE_FAILED :{WHITE}Automatikus mentés sikertelen
+
+STR_MONTH_JAN :január
+STR_MONTH_FEB :február
+STR_MONTH_MAR :március
+STR_MONTH_APR :április
+STR_MONTH_MAY :május
+STR_MONTH_JUN :június
+STR_MONTH_JUL :július
+STR_MONTH_AUG :augusztus
+STR_MONTH_SEP :szeptember
+STR_MONTH_OCT :október
+STR_MONTH_NOV :november
+STR_MONTH_DEC :december
+
+STR_HEADING_FOR_STATION :{LTBLUE}{STATION} állomás felé
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}{STATION} állomás felé, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Nincs menetrend
+STR_NO_ORDERS_VEL :{LTBLUE}Nincs menetrend, {VELOCITY}
+
+STR_PASSENGERS :utas
+STR_BAGS :táska
+STR_TONS :tonna
+STR_LITERS :liter
+STR_ITEMS :darab
+STR_CRATES :láda
+STR_RES_OTHER :egyéb
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Nem lehet megosztani a menetrendet...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Nem lehet másolni a menetrendet...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - Megosztott menetrend vége - -
+
+STR_TRAIN_IS_LOST :{WHITE}{COMMA}. vonat eltévedt.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}{COMMA}. vonat profitja az elmúlt évben: {CURRENCY}
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}Európai Pénzügyi Únió!{}{}Az Euro bevezetésre került mint egyedüli valuta a mindennapi pénzügyi tranzakciókra az országodban!
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}A(z) {COMMA}. vonatnak túl rövid a menetrendje
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}A(z) {COMMA}. vonatnak üres a menetrendje
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}A(z) {COMMA}. vonatnak duplikált utasításai vannak
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}A(z) {COMMA}. vonatnak nemlétező állomás van a menetrendjében
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}A(z) {COMMA}. közúti járműnek túl kevés a teendője
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}A(z) {COMMA}. közúti járműnek nincs teendője
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}A(z) {COMMA}. köyúti járműnek duplikált utasításai vannak
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}A(z) {COMMA}. közúti járműnek nemlétező állomás van a menetrendjében
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}A(z) {COMMA}. hajónak túl rövid a menetrendje
+STR_SHIP_HAS_VOID_ORDER :{WHITE}A(z) {COMMA}. hajónak üres a menetrendje
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}A(z) {COMMA}. hajónak duplikált utasításai vannak
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}A(z) {COMMA}. hajónak nemlétező állomás van a menetrendjében
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}A(z) {COMMA}. repülőnek túl rövid a menetrendje
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}A(z) {COMMA}. repülőnek üres a menetrendje
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}A(z) {COMMA}. repülőnek duplikált utasitásai vannak
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}A(z) {COMMA}. repülőnek nemlétező állomás van a menetrendjében
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}Autorenew sikertelen a(z) {COMMA}. vonaton (pénzlimit)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}Autorenew sikertelen a(z) {COMMA}. közúti járművön (pénzlimit)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}Autorenew sikertelen a(z) {COMMA}. hajón (pénzlimit)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}Autorenew sikertelen a(z) {COMMA}. repülőn (pénzlimit)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}A {COMMA}. vonat túl hosszú a csere után
+
+STR_CONFIG_PATCHES :{BLACK}Foltok beállítása
+STR_CONFIG_PATCHES_TIP :{BLACK}Foltok beállítása
+STR_CONFIG_PATCHES_CAPTION :{WHITE}Foltok beállítása
+
+STR_CONFIG_PATCHES_OFF :Ki
+STR_CONFIG_PATCHES_ON :Be
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Járművek sebességének kijelzése: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Lejtőre es partokra építés: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Élethűbben méretezett befogadókörzetek bekapcsolása: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Engedélyezi az ipari létesítmények és utak rombolását, stb: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Óriásvonatok engedélyezése: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Vonatok valósághű gyorsulása: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}A vonatok és a hajók nem tesznek 90 fokos kanyart: {ORANGE}{STRING} {LTBLUE} (csak NPF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Egymás mellé építhető vonatállomások: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Bármelyik rakomány telipakolása esetén induljon a jármű: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}A továbbfejlesztett betöltés használata: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GRADUAL_LOADING :{LTBLUE}Járművek fokozatos rakodása: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Infláció: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Csak akkor szállítson árut az állomásra, ha ott van rá kereslet: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Nagyon hosszú hidak engedélyezése: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}'Menj a garázsba' engedélyezés a menetrendben: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Nyersanyagtermelő ipari épületek építési lehetősége: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Több hasonló ipari épület egy városon belül: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Több ugyanolyan gyár építhető közel egymáshoz: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Mindig teljes dátum a képernyőn: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Közlekedési lámpák a menetirány szerinti oldalon legyenek: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Pénzügyi összesítés minden év végén: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}TTDPatch kompatibilis nonstop kezelés: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Közúti járművek sorbanállása (quantum effektektus): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Ablakmozgatás, ha az egér a képernyő szélén van: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Önkormányzatok lefizethetősége: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Különböző vágánytípusok engedélyezése egy állomáson: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Új útvonalkereső (NPF, felülbírálja az NTP-t): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FREIGHT_TRAINS :{LTBLUE}Tömegszorzó tehervonatoknak (szimulációs célból): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Mindig engedélyezze a kis repülőtereket: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Figyelmeztet ha a vonat eltévedt: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Járművek menetrendjének ellenőrzése: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :nem
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :igen, de nem az álló járművekre
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :minden járműre
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Figyelmeztetés, ha a vonat veszteséges: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Járművek sose avuljanak el: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Automatán felújítja a járművet ha elöregedik
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Automatán felújítja a járművet {ORANGE}{STRING}{LTBLUE} hónappal a max életkora előtt/után
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Automata megújításhoz szükséges minimális pénz: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Hibaüzenetek megjelenítési ideje: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Mutassa a lakosságot a feliratban: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Láthatatlan fák (átlátszó épületekkel): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Térkép generálás: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :Eredeti
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis
+STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}Olajfinomítók max távolsága a szélektől {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Hóhatár magassága: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN :{LTBLUE}A terep durvasága (csak TerraGenesisnél) : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Nagyon sima
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH :Sima
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH :Durva
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :Nagyon durva
+STR_CONFIG_PATCHES_TREE_PLACER :{LTBLUE}Fa-elhelyező módszer: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TREE_PLACER_NONE :Nincs
+STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL :Eredeti
+STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED :Javított
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION :{LTBLUE}Magasságtérkép forgatása: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Órairánnyal szemben
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE :Órairányban
+STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT :{LTBLUE}A sima térképhez hozzáadandó magasság: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Ãllomások legnagyobb kiterjedése: {ORANGE}{STRING} {RED}Figyelem: magas érték lelassítja a játékot
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Helikopterek automatikus javítása a helikopter-leszállókon: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Tájrendező eszköztár megnyitása a közúti/vasúti/vízi/légi eszköztárakkal: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Egeres mozgáskor a táj a másik irányba mozdul el: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Építési eszközök használata esetén területinformációk mutatása: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Cégek járműveinek mutatása: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES_NONE :Egyikét sem
+STR_CONFIG_PATCHES_LIVERIES_OWN :Csak a sajátét
+STR_CONFIG_PATCHES_LIVERIES_ALL :Minden cégét
+STR_CONFIG_PATCHES_PREFER_TEAMCHAT :{LTBLUE}Alapesetben csapatban beszélsz <ENTER>-re: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Maximum vonat játékosonként: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Maximum közúti jármű játékosonként: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}Maximum repülőgép játékosonként: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}Maximum hajó játékosonként: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Vonatok tiltása a gépi ellenfeleknek: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Közúti járművek tiltása a gépi ellenfeleknek: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Repülőgépek tiltása a gépi ellenfeleknek: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Hajók tiltása a gépi ellenfeleknek: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Új gépi ellenfél (csak buszt épít): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Számítógépes ellenfelek a hálózati játékokban (béta): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Alapértelmezett szervízelés vonatoknak: {ORANGE}{STRING} naponta
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Alap szervízelési idő a vonatokra: {ORANGE}kikapcsolva
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Alapértelmezett szervízelés közúti járműveknek: {ORANGE}{STRING} naponta
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Alap szervízelési idő a köyúti járművekre: {ORANGE}kikapcsolva
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Alapértelmezett szervízelés repülőgépeknek: {ORANGE}{STRING} naponta
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Alap szervízelési idő a repülőkre: {ORANGE}kikapcsolva
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Alapértelmezett szervízelés hajóknak: {ORANGE}{STRING} naponta
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Alap szervízelési idő a hajókra: {ORANGE}kikapcsolva
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Ne legyen szervízelés ha lerobbanások sincsenek: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}A vagonok sebessége korlátozható: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}Elektromos vágányok letiltása: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Színes újságcikkek megjelenése: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Játék induló dátuma: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}Játék befejezésének az éve: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Egyenletes gazdaság (több, kisebb változás)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Másik cégekből részvényt lehet vásárolni
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Amikor megragadom helyezzen lámpákat minden {ORANGE}{STRING}. mezőre
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}A fő eszközsor helye: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Balra
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Középen
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Jobbra
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Ablakigazítás kiterjedése: {ORANGE}{STRING} képpont
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Ablakigazítás kiterjedése: {ORANGE}letiltva
+
+STR_CONFIG_PATCHES_GUI :{BLACK}Megjelenítés
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Építkezés
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Járművek
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Ãllomások
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Gazdaság
+STR_CONFIG_PATCHES_AI :{BLACK}Ellenfelek
+
+STR_CONFIG_PATCHES_DISABLED :kikapcsolva
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Válassz beállítási értéket
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}A lenti alap szervíz intervallum beállítások némelyike/mindegyike inkompatibilis a választott beállítással! Csak 5-90% és 30-800 napig elfogadható.
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}YAPF használata hajóknál: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}YAPF használata közutakon: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}YAPF használata vonatokhoz: {ORANGE}{STRING}
+
+STR_TEMPERATE_LANDSCAPE :mérsékelt táj
+STR_SUB_ARCTIC_LANDSCAPE :sarkköri táj
+STR_SUB_TROPICAL_LANDSCAPE :trópusi táj
+STR_TOYLAND_LANDSCAPE :játék táj
+
+STR_CHEATS :{WHITE}Csalások
+STR_CHEATS_TIP :{BLACK}A kijelölőnégyzetek jelzik a csalások eddigi használtságát
+STR_CHEATS_WARNING :{BLACK}Figyelem! Te épp a versenytársaidat készülöd elárulni. Sose felejtsd el, hogy egy ilyen szégyenletes tett sose merül feledésbe.
+STR_CHEAT_MONEY :{LTBLUE}Tőkeemelés {CURRENCY64}
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Játszani mint játékos #{ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Csodabuldózer (lerombol gazdasági épületeket, stb): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}A csatornák keresztezhessék egymást: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Építés szünet módban: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Jet-repülőgépek nem fognak (gyakran) lezuhanni a kisebb repülőtereken: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Klíma változtatás: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Dátum módosítás: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}A nyersanyagüzemek termelése változtatható: {ORANGE}{STRING}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}Úton {WAYPOINT} felé
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Úton {WAYPOINT} felé, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :{WAYPOINT}on át
+STR_GO_NON_STOP_TO_WAYPOINT :Úton {WAYPOINT} ellenőrző ponton át
+
+STR_WAYPOINTNAME_CITY :{TOWN}i ellenőrző pont
+STR_WAYPOINTNAME_CITY_SERIAL :{TOWN}i {COMMA}. ellenőrző pont
+STR_LANDINFO_WAYPOINT :Ellenőrző pont
+
+STR_WAYPOINT :{WHITE}Ellenőrző pont
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Válassz ellenőrző-pont tipust
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}Módosítd az ellenőrző pont nevét
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Nem lehet megváltoztatni az ellenőrző pont nevét...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Sín átalakítása ellenőrző ponttá
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Nem lehet vonat ellenőrző pontot építeni ide...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Nem lehet eltávolítani az ellenőrző pontot...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Sín építése egyszerűsített módón
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}...nincs város ezen a pályán
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}Biztos vagy benne hogy véletlen tájképet akarsz létrehozni?
+STR_MANY_RANDOM_TOWNS :{BLACK}Sok véletlen város
+STR_RANDOM_TOWNS_TIP :{BLACK}Elhelyez a térképen véletlenszerüen sok várost.
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Sok véletlen gazdasági épület
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Elhelyez a térképen véletlenszerüen sok gazdasági épületet
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Nem tudok gazdasági épületet generálni...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Nyisd meg a tájrendező ablakot a talaj növeléshez/csökkentéshez, faültetéshez, stb.
+STR_LANDSCAPING_TOOLBAR :{WHITE}Tájrendezés
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Talajszint
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Véletlenszerű fafélék
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}Véletlenszerűen kiválasztott fákat helyez el
+
+STR_CANT_BUILD_CANALS :{WHITE}Nem lehet csatornát építeni ide...
+STR_BUILD_CANALS_TIP :{BLACK}Csatorna építése. Nyomj CTRL-t hogy tengert csinálj (tengerszinten csak).
+STR_LANDINFO_CANAL :Csatorna
+
+STR_CANT_BUILD_LOCKS :{WHITE}Nem lehet zsilipet építeni ide...
+STR_BUILD_LOCKS_TIP :{BLACK}Zsilip építése
+STR_LANDINFO_LOCK :Zsilip
+
+STR_BUOY_IS_IN_USE :{WHITE}... a bóját használják!
+
+STR_LANDINFO_COORDS :{BLACK}Koordináták: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Nem lehet eltávolítani az állomás részét...
+STR_CANT_CONVERT_RAIL :{WHITE}Itt nem lehet átalakítani a sínt...
+STR_CONVERT_RAIL_TIP :{BLACK}Sínek átalakítása a kiválasztott típusra
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Húzd ide a mozdonyt a teljes vonat eladásához
+
+STR_DRAG_DROP :{BLACK}Fogd és dobd
+STR_STATION_DRAG_DROP :{BLACK}Ãllomás építése fogd és dobd módon
+STR_SELECT_STATION_CLASS_TIP :{BLACK}Válasz egy megjelenítendő állomásfajtát
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Válaszd ki a megépítendő állomásfajtát
+
+STR_FAST_FORWARD :{BLACK}Játék gyorsítása
+STR_MESSAGE_HISTORY :{WHITE}Előző üzenetek
+STR_MESSAGE_HISTORY_TIP :{BLACK}Az előző hírüzenetek listája
+STR_MESSAGES_DISABLE_ALL :{BLACK}Kikapcsol mind
+STR_MESSAGES_ENABLE_ALL :{BLACK}Bekapcsol mind
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Szénbánya építése
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Erdő ültetése
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Olajfúró torony építése
+STR_CONSTRUCT_FARM_TIP :{BLACK}Farm építése
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Rézércbánya építése
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Olajkút építése
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Aranybánya építése
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Gyémántbánya építése
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Vasércbánya építése
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Gyümölcsültetvény telepítése
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Gumiültetvény telepítése
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Vízforrás építése
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Vattacukor-erdő telepítése
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}Elemfarm építése
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Kólakút építése
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Műanyagforrás építése
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Buborékgenerátor építése
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Tejkaramella fejtő építése
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Cukorbánya építése
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Gazdasági épületek
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA}% elszállítva)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA}%/{COMMA}% elszállítva)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}...túl közel egy másik gazdasági épülethez
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}A vonat átalakítása másfajta áru szállítására
+STR_RAIL_REFIT_VEHICLE :{BLACK}Vonat átalakítása
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Válaszd ki, milyen árut szállítson a vonat
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}A vonat átalakítása a kijelölt áru szállítására
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Nem alakíthatod át a vonatot...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Szervízintervallumok százalékban: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Termelés megváltoztatása
+
+TEMP_AI_IN_PROGRESS :{WHITE}Üdv, ez itt az új, fejlesztés alatt álló MI. Előfordulhatnak gondok, problémák. Ha belefutsz egybe, kérlek készíts képernyőmentést küld be a fórumra. Jó játékot!
+TEMP_AI_ACTIVATED :{WHITE}Figyelem: az új MI fejlesztés alatt áll! Jelenleg csak a teherautók és a buszok működnek!
+TEMP_AI_MULTIPLAYER :{WHITE}Figyelem: ez a funckió még béta állapotú. A hibajelentéseket küldd légyszi a truelight@openttd.org címre.
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Hálózati játék
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Játékos neve:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}A többi játékos ilyen nével fog ismerni Téged.
+STR_NETWORK_CONNECTION :{BLACK}Kapcsolat:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Válassz az internetes vagy helyi hálózati játék közül
+
+STR_NETWORK_START_SERVER :{BLACK}Szerver indítása
+STR_NETWORK_START_SERVER_TIP :{BLACK}Saját szervert indít
+
+STR_NETWORK_GAME_NAME :{BLACK}Név
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Játék neve
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Nyelv, szerver verzió, stb.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Kattints a listában a jatékra hogy kiválaszd
+
+STR_NETWORK_FIND_SERVER :{BLACK}Szerver keresése
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Szerver keresése a hálózaton
+STR_NETWORK_ADD_SERVER :{BLACK}Szerver hozzáadása
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Hozzáadja a szervert a listához, így később gyorsabban tudsz hozzá csatlakozni
+STR_NETWORK_ENTER_IP :{BLACK}Ãrd be a szerver IP címét
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Kliens
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Kliens online / kliens max
+STR_NETWORK_GAME_INFO :{SILVER}JÃTÉK INFÓ
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Játékos: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Nyelv: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Tájtípus: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}A pálya nagysága: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}Szerver verzió: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}A szerver címe: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Kezdési dátum: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Jelenlegi dátum: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Jelszóval védve!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}SZERVER OFFLINE
+STR_NETWORK_SERVER_FULL :{SILVER}SZERVER TELE
+STR_NETWORK_VERSION_MISMATCH :{SILVER}VERZIÓ ELTÉRÉS
+STR_NETWORK_GRF_MISMATCH :{SILVER}NEWGRF ELTÉRÉS
+
+STR_NETWORK_JOIN_GAME :{BLACK}Csatlakozás
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}Új játékot kezd
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Játék neve:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}A játék neve fog megjelenni a többi játékosnak a többjátékos menüben
+STR_NETWORK_SET_PASSWORD :{BLACK}Jelszó beállítása
+STR_NETWORK_PASSWORD_TIP :{BLACK}Védd le a játékodat jelszóval ha nem akarod hogy mások csatlakozzanak
+STR_NETWORK_SELECT_MAP :{BLACK}Válassz egy térképet:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}Melyik terképen akarsz játszani?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}Maximum hány játékos lehet:
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Válaszd ki hány játékos kapcsolódhat maximum. Nem szükséges pont ennyi embernek éppen kapcsolódva lennie.
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :Helyi hálózat
+STR_NETWORK_INTERNET :Internet
+STR_NETWORK_LAN_INTERNET :Hálózat / Internet
+STR_NETWORK_INTERNET_ADVERTISE :Internet (reklámoz)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 játékos
+STR_NETWORK_1_PLAYERS :1 játékos
+STR_NETWORK_2_PLAYERS :2 játékos
+STR_NETWORK_3_PLAYERS :3 játékos
+STR_NETWORK_4_PLAYERS :4 játékos
+STR_NETWORK_5_PLAYERS :5 játékos
+STR_NETWORK_6_PLAYERS :6 játékos
+STR_NETWORK_7_PLAYERS :7 játékos
+STR_NETWORK_8_PLAYERS :8 játékos
+STR_NETWORK_9_PLAYERS :9 játékos
+STR_NETWORK_10_PLAYERS :10 játékos
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}Max cégszám:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}A cégek maximális száma
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}Max megfigyelő:
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}A megfigyelők maximális száma
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Beszélt nyelv:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}A többi játékos megtudhatja milyen nyelven beszélnek a szerveren.
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}Játék elindítása
+STR_NETWORK_START_GAME_TIP :{BLACK}Új hálózati játék kezdése véletlen térképpel vagy misszióval
+STR_NETWORK_LOAD_GAME :{BLACK}Játék betöltése
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Korábban elmentett többfelhasználós játék folytatása (győződj meg, hogy megfelelő játékosként kapcsolódtál)
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Bármilyen
+STR_NETWORK_LANG_ENGLISH :Angol
+STR_NETWORK_LANG_GERMAN :Német
+STR_NETWORK_LANG_FRENCH :Francia
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Hálózati-játék lobby
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Készülődés a kapcsolódáshoz: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}Egy lista az összes cégről aki játékban van. Beléphetsz egybe, vagy kezdhetsz egy
+STR_NETWORK_NEW_COMPANY :{BLACK}Új vállalat
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Új vállalatot nyit
+STR_NETWORK_SPECTATE_GAME :{BLACK}Játék megvizsgálása
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Megtekinted a játékot mint vizsgálóbiztos
+STR_NETWORK_JOIN_COMPANY :{BLACK}Belépés a cégbe
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Segítesz valakinek egy cégénél (többen 1 céget)
+STR_NETWORK_REFRESH :{BLACK}Szerver frissítése
+STR_NETWORK_REFRESH_TIP :{BLACK}Szerver infó frissítése
+
+STR_NETWORK_COMPANY_INFO :{SILVER}CÉG INFÓ
+
+STR_NETWORK_COMPANY_NAME :{SILVER}A cég neve: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}Beiktatás: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}A cég értéke: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Jelelegi összeg: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Előző évi bevétel: {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}Teljesítmény: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}Járművek: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Ãllomások: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Játékosok: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}Kapcsolódás...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) Kapcsolódás..
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Engedélyezés..
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Várakozás..
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Térkép letöltése..
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Adatfeldolgozás..
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) Regisztrálás..
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Játékinfó lekérése..
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Céginfó lekérése..
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} kliensre várunk, hogy befejezze
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} kilobájt lett eddig letöltve
+
+STR_NETWORK_DISCONNECT :{BLACK}Lebontás
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Ãrd be mennyi pénzt akarsz adományozni
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}A szerver jelszóval van védve. Ãrd be
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}A cég jelszóval van védve. Ãrd be
+STR_NETWORK_CLIENT_LIST :{WHITE}Kliens lista
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE} Nem található a hálózati csatoló, vagy nincs hálózati támogatás (ENABLE_NETWORK)
+STR_NETWORK_ERR_NOSERVER :{WHITE} Nem található semmilyen hálózati játék
+STR_NETWORK_ERR_NOCONNECTION :{WHITE} A szerver nem reagált a kérésre
+STR_NETWORK_ERR_DESYNC :{WHITE} Hálózat - Játék szinkronizáció sikertelen.
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} Hálózat - Játék kapcsolat elveszett.
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} Nem sikerült a szerver játékmentés betöltése.
+STR_NETWORK_ERR_SERVER_START :{WHITE} Nem tudtam elindítani a szervert.
+STR_NETWORK_ERR_CLIENT_START :{WHITE} Nem tudtam kapcsolódni.
+STR_NETWORK_ERR_TIMEOUT :{WHITE} A(z) {NUM}. játékos kapcsolata elveszett.
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE} Protokoll-hibát csináltunk, és megszakadt a kapcsolat.
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE} A te gépeden lévő és a szerveren lévő programnak nem egyezik meg a verziója.
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} Rossz jelszó.
+STR_NETWORK_ERR_SERVER_FULL :{WHITE} A szerver tele van
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} Ki vagy tiltva erről a szerverről
+STR_NETWORK_ERR_KICKED :{WHITE} Ki lettél rúgva a szerverről
+STR_NETWORK_ERR_CHEATER :{WHITE} Ez a szerver nem engedi a csalást
+
+STR_NETWORK_ERR_LEFT :elhagyta a játékot
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :általános hiba
+STR_NETWORK_ERR_CLIENT_DESYNC :szinkronizálási hiba
+STR_NETWORK_ERR_CLIENT_SAVEGAME :térkép betöltési hiba
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :elveszett a kapcsolat
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :protokoll hiba
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :nem engedélyezett
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :ismeretlen csomag érkezett
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :rossz verzió
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :a név már használva van
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :rossz játék-jelszó
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :rossz játékos-id a DoCommand-ban
+STR_NETWORK_ERR_CLIENT_KICKED :a szerver kirúgott
+STR_NETWORK_ERR_CLIENT_CHEATER :csalni próbált
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :a szerver megtelt
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :belépett a játékba
+STR_NETWORK_GIVE_MONEY :adott egy kis pénzt ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :{STRING} játékosnak adományoztál ({CURRENCY}) összeget
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Csapat] :
+STR_NETWORK_CHAT_COMPANY :[Csapat] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Csapat] {STRING} számára: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[Privát] :
+STR_NETWORK_CHAT_CLIENT :[Privát] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[Privát] {STRING} számára: {GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[Mindenkinek] :
+STR_NETWORK_CHAT_ALL :[Mindenkinek] {STRING}: {GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :megváltoztatta a nevét erre:
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE} A szerver leállította a játékot
+STR_NETWORK_SERVER_REBOOT :{WHITE} A szerver újraindul...{}Türelem...
+
+STR_NETWORK_SERVER :Szerver
+STR_NETWORK_CLIENT :Kliens
+STR_NETWORK_SPECTATORS :Megfigyelők
+
+STR_NETWORK_CLIENTLIST_NONE :(nincs)
+STR_NETWORK_CLIENTLIST_KICK :Kirúgás
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Pénz adományozása
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Ãœzenet mindenkinek
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Üzenet a cégnek
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Privát üzenet
+
+
+STR_NETWORK_SEND :{BLACK}Elküld
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}ÉK-DNY térképszélesség: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}ÉNY-DK térképszélesség: {ORANGE}{STRING}
+
+
+##### PNG-MAP-Loader
+
+STR_PNGMAP_ERROR :{WHITE}Nem tudom a térképet betölteni a PNG-ből...
+STR_PNGMAP_ERR_FILE_NOT_FOUND :{WHITE}...fájl nem található.
+STR_PNGMAP_ERR_IMAGE_TYPE :{WHITE}...nem tudtam konverálni a kép típusát. 8 vagy 24-bites PNG kép kell.
+STR_PNGMAP_ERR_MISC :{WHITE}...valami nem igazán sikerült. Bocs. (talán sérült a fájl)
+
+STR_BMPMAP_ERROR :{WHITE}Nem sikerült a térkép betöltése a BMP-ből...
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}...nem sikerült a képtípust konvertálni.
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}{CURRENCY} kiadás
+STR_0801_COST :{RED}{CURRENCY} kiadás
+STR_0802_INCOME :{TINYFONT}{GREEN}{CURRENCY} bevétel
+STR_0803_INCOME :{GREEN}{CURRENCY} bevétel
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Elszállít: {CURRENCY}
+STR_FEEDER :{YELLOW}Elszállít: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Becsült ár: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Becsült bevétel: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Nem emelheted fel itt a földet...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Nem süllyesztheted le itt a földet...
+STR_080A_ROCKS :Kövek
+STR_080B_ROUGH_LAND :Durva föld
+STR_080C_BARE_LAND :Csupasz föld
+STR_080D_GRASS :Fű
+STR_080E_FIELDS :Szántóföld
+STR_080F_SNOW_COVERED_LAND :Havas föld
+STR_0810_DESERT :Sivatag
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Rossz irányba lejt a föld
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Nem lehetséges sínösszetétel
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}Az ásás megsértené az alagutat
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Már tengerszinten van
+STR_1004_TOO_HIGH :{WHITE}Túl magas
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Nincs megfelelő sín
+STR_1007_ALREADY_BUILT :{WHITE}...már van itt
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Előbb le kell rombolnod a sínt
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Vasútépítés
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Elektromos-vasút építés
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Egysínű vasút építése
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}MagLev vasút építése
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Válassz egy vasúti hidat
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Nem építhetsz ide járműtelepet...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Nem építhetsz ide vasútállomást...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Nem rakhatsz ide szemafort...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Nem rakhatsz ide sínt...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Nem szedheted fel innen a sínt...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Nem veheted le innen a szemafort...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Járműtelep helyzete
+STR_1015_RAILROAD_CONSTRUCTION :Vasútépítés
+STR_TOOLB_ELRAIL_CONSTRUCTION :Elektromos-vasút építés
+STR_1016_MONORAIL_CONSTRUCTION :Egysínű vasút építése
+STR_1017_MAGLEV_CONSTRUCTION :MagLev vasút építése
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Sín lerakása
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Járműtelep építése (vonatok vételére és karbantartására)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Vasútállomás építése
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Szemafor lerakása
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Vasúti híd építése
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Vasúti alagút építése
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Felszedés/lerakás közötti váltás síneknél és szemafornál
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Híd kiválasztása - kattints arra a hídra, amit meg akarsz építeni
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Válaszd ki a járműtelep helyzetét
+STR_1021_RAILROAD_TRACK :Vasúti sín
+STR_1023_RAILROAD_TRAIN_DEPOT :Járműtelep
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...a terület más cégé
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :Vasúti sin szemaforral
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :Vasúti sin előrejelző szemaforral
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :Vasúti sin kijáratjelző szemaforral
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :Vasúti sin vegyes szemaforral
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Előbb le kell rombolnod az utat
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Útkarbantartás folyamatban
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Útépítés
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Közúti híd építése
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Nem építhetsz ide utat...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Nem rombolhatod le innen az utat...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Garázs helyzete
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Nem építhetsz ide garázst...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Nem építhetsz ide buszmegállót...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Nem építhetsz ide teherautó-rakodóhelyet...
+STR_180A_ROAD_CONSTRUCTION :Útépítés
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Út építése
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Garázs építése (járművek vételére és karbantartására)
+STR_180D_BUILD_BUS_STATION :{BLACK}Buszmegálló építése
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Teherautó-rakodóhely építése
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Közúti híd építése
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Közúti alagút építése
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Építés/felszedés közötti váltás utaknál
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Válaszd ki a garázs helyzetét
+STR_1814_ROAD :Út
+STR_1815_ROAD_WITH_STREETLIGHTS :Út lámpákkal
+STR_1816_TREE_LINED_ROAD :Fával szegélyezett út
+STR_1817_ROAD_VEHICLE_DEPOT :Garázs
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :Út/vasút kereszteződés
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Városok
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Előbb le kell rombolnod az épületet
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}Lakosság: {ORANGE}{COMMA}{BLACK} Házak: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Város átnevezése
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Nem nevezheted át a várost...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} önkormányzata nem engedélyezi
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Városnevek - kattints egy névre a város megnézéséhez
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}A fő nézetet a városra állítja
+STR_200C_CHANGE_TOWN_NAME :{BLACK}A város nevének megváltoztatása
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Utasok az előző hónapban: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Levélcsomagok az előző hónapban: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Magas irodaház
+STR_2010_OFFICE_BLOCK :Irodaház
+STR_2011_SMALL_BLOCK_OF_FLATS :Kis bérház
+STR_2012_CHURCH :Templom
+STR_2013_LARGE_OFFICE_BLOCK :Nagy irodaház
+STR_2014_TOWN_HOUSES :Városi házak
+STR_2015_HOTEL :Szálloda
+STR_2016_STATUE :Szobor
+STR_2017_FOUNTAIN :Szökőkút
+STR_2018_PARK :Park
+STR_2019_OFFICE_BLOCK :Irodaház
+STR_201A_SHOPS_AND_OFFICES :Boltok és irodák
+STR_201B_MODERN_OFFICE_BUILDING :Modern irodaház
+STR_201C_WAREHOUSE :Közraktár
+STR_201D_OFFICE_BLOCK :Irodaház
+STR_201E_STADIUM :Stadion
+STR_201F_OLD_HOUSES :Régi házak
+STR_2020_LOCAL_AUTHORITY :{BLACK}Önkormányzat
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Az önkormányzat adatainak megmutatása
+STR_2022_LOCAL_AUTHORITY :{WHITE}{TOWN} önkormányzata
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Vélemény a szállítási cégekről:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Támogatások
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Támogatás jár
+STR_2027_FROM_TO :{ORANGE}{STRING} szállításáért {STRING} és {STRING} között
+STR_2028_BY :{YELLOW} ({DATE_SHORT}ig)
+STR_202A_NONE :{ORANGE}---
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Már támogatást kap
+STR_202C_FROM_TO :{ORANGE}{STRING} szállításáért {STATION} és {STATION} között {YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW} ({DATE_SHORT}ig)
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}A támogatás határideje lejárt:{}{}{STRING} szállításáért {STRING} és {STRING} között már nem jár támogatás.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Támogatás visszavonva:{}{}{STRING} szállítása {STATION} és {STATION} között már nem támogatott.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Támogatási ajánlat:{}{}Az első {STRING} szállító {STRING} és {STRING} között egy éves támogatást kap a helyi önkormányzattól!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}{COMPANY} támogatást kapott!{}{}Ãgy {STRING} szállítása {STATION} és {STATION} között másfélszeres hasznot hoz neki!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}{COMPANY} támogatást kapott!{}{}Ãgy {STRING} szállítása {STATION} és {STATION} között kétszeres hasznot hoz neki!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}{COMPANY} támogatást kapott!{}{}Ãgy {STRING} szállítása {STATION} és {STATION} között háromszoros hasznot hoz neki!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}{COMPANY} támogatást kapott!{}{}Ãgy {STRING} szállítása {STATION} és {STATION} között négyszeres hasznot hoz neki!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} önkormányzata nem engedélyez új repteret a városban
+STR_2036_COTTAGES :Vidéki házak
+STR_2037_HOUSES :Házak
+STR_2038_FLATS :Bérház
+STR_2039_TALL_OFFICE_BLOCK :Magas irodaház
+STR_203A_SHOPS_AND_OFFICES :Boltok és irodák
+STR_203B_SHOPS_AND_OFFICES :Boltok és irodák
+STR_203C_THEATER :Színház
+STR_203D_STADIUM :Stadion
+STR_203E_OFFICES :Irodák
+STR_203F_HOUSES :Házak
+STR_2040_CINEMA :Mozi
+STR_2041_SHOPPING_MALL :Bevásárlóközpont
+STR_2042_DO_IT :{BLACK}Tedd meg
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}A várossal tehető dolgok listája - kattints egy elemre a részletekhez
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}A fenti listában kijelölt intézkedés végrehajtása
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Lehetséges intézkedések:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Kis reklámhadjárat
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Közepes reklámhadjárat
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Nagy reklámhadjárat
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :A helyi utak helyreállíttatása
+STR_204A_BUILD_STATUE_OF_COMPANY :Szobor építtetése a cég tulajdonosának
+STR_204B_FUND_NEW_BUILDINGS :Új épületek építésének támogatása
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Kizárólagos szállítási jogok vétele
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Az önkormányzat megvesztegetése
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Kis helyi reklámhadjárat indítása, hogy több utast és árut vonzz a megállóidba.{} Ãra: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Közepes helyi reklámhadjárat indítása, hogy több utast és árut vonzz a megállóidba.{} Ãra: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Nagy helyi reklámhadjárat indítása, hogy több utast és árut vonzz a megállóidba.{} Ãra: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} A városi úthálózat helyreállításának támogatása. Több, mint hat hónapig jelentÅ‘sen összezavarja a közúti forgalmat.{} Ãra: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Szobor építése a vállalatod tiszteletére.{} Ãra: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Új kereskedelmi épületek építésének támogatása a városban.{} Ãra: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Egy éves kizárólagos szállítási jogok vétele a városban. Az önkormányzat csak a te állomásaid használatát engedi meg az utasoknak és az áruknak.{} Ãra: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} A megítélésed növelése az önkormányzat megvesztegetésével, komoly büntetést kockáztatva, ha ez kiderül.{} Ãra: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}Közlekedési zűrzavar {TOWN} városában!{}{}{COMPANY} által indított útjavítás keseríti meg hat hónapig az autóvezetők életét!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (építés alatt)
+STR_2059_IGLOO :Jégkunyhó
+STR_205A_TEPEES :Indiánsátor
+STR_205B_TEAPOT_HOUSE :Teáskanna-ház
+STR_205C_PIGGY_BANK :Malacpersely
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN}i {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Tájrendezés
+STR_2800_PLANT_TREES :Faültetés
+STR_2801_PLACE_SIGN :Felirat lerakása
+STR_2802_TREES :{WHITE}Fák
+STR_2803_TREE_ALREADY_HERE :{WHITE}...már van itt
+STR_2804_SITE_UNSUITABLE :{WHITE}...nem alkalmas rá a hely
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Nem ültethetsz ide fát...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...túl sok a felirat
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Nem rakhatsz ide feliratot...
+STR_280A_SIGN :Felirat
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Felirat szerkesztése
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Nem változtathatod meg a feliratot...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Válaszd ki, melyik fát ülteted
+STR_280E_TREES :Fák
+STR_280F_RAINFOREST :Esőerdő
+STR_2810_CACTUS_PLANTS :Kaktusz
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Vasútállomás beállítása
+STR_3001_AIRPORT_SELECTION :{WHITE}Repülőtér beállítása
+STR_3002_ORIENTATION :{BLACK}Helyzet
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Vágányok száma
+STR_3004_PLATFORM_LENGTH :{BLACK}Vágányok hossza
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Túl közel van egy másik vasútállomáshoz
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Több állomással/rakodóhellyel érintkezik
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}Túl sok állomás/rakodóhely van ebben a városban
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}Túl sok az állomás/rakodóhely
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Túl sok buszmegálló
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}Túl sok kamion megálló
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Túl közel van egy másik állomáshoz/rakodóhelyhez
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Előbb le kell rombolnod a vasútállomást
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Túl közel van egy másik repülőtérhez
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Előbb le kell rombolnod a repülőteret
+
+STR_3030_RENAME_STATION_LOADING :Ãllomás/rakodóhely átnevezése
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Nem nevezheted át az állomást...
+STR_3032_RATINGS :{BLACK}Vélemény
+STR_3033_ACCEPTS :{BLACK}Elfogadás
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}A szállítás helyi megítélése:
+
+############ range for rating starts
+STR_3035_APPALLING :szörnyű
+STR_3036_VERY_POOR :nagyon rossz
+STR_3037_POOR :rossz
+STR_3038_MEDIOCRE :közepes
+STR_3039_GOOD :jó
+STR_303A_VERY_GOOD :nagyon jó
+STR_303B_EXCELLENT :kiváló
+STR_303C_OUTSTANDING :kimagasló
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} többé nem fogad el {STRING}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} többé nem fogad el {STRING} és {STRING}
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} most már elfogad {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} most már elfogad {STRING} és {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Buszmegálló helyzete
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Rakodóhely helyzete
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Előbb le kell rombolnod a buszmegállót
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Előbb le kell rombolnod a teherautó-rakodóhelyet
+STR_3048_STATIONS :{WHITE}{COMPANY} állomásai - {COMMA}
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Nincs -
+STR_304B_SITE_UNSUITABLE :{WHITE}...nem alkalmas rá a hely
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Túl közel van egy másik kikötőhöz
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Előbb le kell rombolnod a kikötőt
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Vasútállomás helyzetének kiválasztása
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}A vasútállomás vágányainak száma
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}A vasútállomás hossza
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Buszmegálló helyzetének kiválasztása
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Teherautó-rakodó helyzetének kiválasztása
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}A fő nézetet az állomásra állítja
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Vélemény megmutatása az állomásról
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Az állomás nevének megváltoztatása
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Az elfogadott áruk listájának mutatása
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Ãllomásnevek - kattints egy névre az állomás megnézéséhez
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Repülőtér méretének/típusának kiválasztása
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :Vasútállomás
+STR_305F_AIRCRAFT_HANGAR :Reptéri hangár
+STR_3060_AIRPORT :Repülőtér
+STR_3061_TRUCK_LOADING_AREA :Teherautó-rakodóhely
+STR_3062_BUS_STATION :Buszmegálló
+STR_3063_SHIP_DOCK :Kikötő
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}A kiválasztott helyen lefedett terület mutatása
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}A kiválasztott helyen lefedett terület elrejtése
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Lefedett terület mutatása:
+STR_3068_DOCK :{WHITE}Kikötő
+STR_3069_BUOY :Bója
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...bója van az útban
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...az állomás túl kiterjedt
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...csak egyféle vágánytípusú állomások lehetnek
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Több elem kiválasztásához tartsd lenyomva a CTRL-t
+
+STR_UNDEFINED :(nem definiált string)
+STR_STAT_CLASS_DFLT :Alapértelmezett állomás
+STR_STAT_CLASS_WAYP :Útipontok
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Dokk helyzete
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...csak vízen építhető
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Nem építhetsz ide dokkot...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Válaszd ki a dokk helyzetét
+STR_3804_WATER :Víz
+STR_3805_COAST_OR_RIVERBANK :Tenger- vagy folyópart
+STR_3806_SHIP_DEPOT :Dokk
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...nem építhető vízen
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Játék mentése
+STR_4001_LOAD_GAME :{WHITE}Játék betöltése
+STR_4002_SAVE :{BLACK}Ment
+STR_4003_DELETE :{BLACK}Töröl
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} megabájt szabad
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Nem olvasható a meghajtó
+STR_4007_GAME_SAVE_FAILED :{WHITE}A mentés nem sikerült
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Nem sikerült törölni a fájlt
+STR_4009_GAME_LOAD_FAILED :{WHITE}A betöltés nem sikerült
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}Meghajtók, könyvtárak és mentések listája
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}A mentés neve
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}A kijelölt mentés törlése
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}A játék elmentése a választott néven
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Az új játék típusa
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Válassz egy pályát (zöld), előre beállított játékot (kék) vagy véletlenszerű új játékot
+STR_4010_GENERATE_RANDOM_NEW_GAME :Véletlenszerű új játék
+STR_4011_LOAD_HEIGHTMAP :{WHITE}Magasságtérkép betöltése
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}...{STRING} van az útban
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :szénbánya
+STR_4802_COAL_MINE.t :szénbányát
+STR_4803_POWER_STATION :erőmű
+STR_4803_POWER_STATION.t :erőművet
+STR_4804_SAWMILL :fűrésztelep
+STR_4804_SAWMILL.t :fűrésztelepet
+STR_4805_FOREST :erdő
+STR_4805_FOREST.t :erdőt
+STR_4806_OIL_REFINERY :olajfinomító
+STR_4806_OIL_REFINERY.t :olajfinomítót
+STR_4807_OIL_RIG :olajfúró torony
+STR_4807_OIL_RIG.t :olajfúró tornyot
+STR_4808_FACTORY :gyár
+STR_4808_FACTORY.t :gyárat
+STR_4809_PRINTING_WORKS :nyomda
+STR_4809_PRINTING_WORKS.t :nyomdát
+STR_480A_STEEL_MILL :acélöntő
+STR_480A_STEEL_MILL.t :acélöntőt
+STR_480B_FARM :farm
+STR_480B_FARM.t :farmot
+STR_480C_COPPER_ORE_MINE :rézércbánya
+STR_480C_COPPER_ORE_MINE.t :rézércbányát
+STR_480D_OIL_WELLS :olajkút
+STR_480D_OIL_WELLS.t :olajkútat
+STR_480E_BANK :bank
+STR_480E_BANK.t :bankot
+STR_480F_FOOD_PROCESSING_PLANT :konzervgyár
+STR_480F_FOOD_PROCESSING_PLANT.t :konzervgyárat
+STR_4810_PAPER_MILL :papírgyár
+STR_4810_PAPER_MILL.t :papírgyárat
+STR_4811_GOLD_MINE :aranybánya
+STR_4811_GOLD_MINE.t :aranybányát
+STR_4812_BANK :bank
+STR_4812_BANK.t :bankot
+STR_4813_DIAMOND_MINE :gyémántbánya
+STR_4813_DIAMOND_MINE.t :gyémántbányát
+STR_4814_IRON_ORE_MINE :vasércbánya
+STR_4814_IRON_ORE_MINE.t :vasércbányát
+STR_4815_FRUIT_PLANTATION :gyümölcsültetvény
+STR_4815_FRUIT_PLANTATION.t :gyümölcsültetvényt
+STR_4816_RUBBER_PLANTATION :gumiültetvény
+STR_4816_RUBBER_PLANTATION.t :gumiültetvényt
+STR_4817_WATER_SUPPLY :vízforrás
+STR_4817_WATER_SUPPLY.t :vízforrást
+STR_4818_WATER_TOWER :víztorony
+STR_4818_WATER_TOWER.t :víztornyot
+STR_4819_FACTORY :gyár
+STR_4819_FACTORY.t :gyárat
+STR_481A_FARM :farm
+STR_481A_FARM.t :farmot
+STR_481B_LUMBER_MILL :favágó
+STR_481B_LUMBER_MILL.t :favágót
+STR_481C_COTTON_CANDY_FOREST :vattacukor-erdő
+STR_481C_COTTON_CANDY_FOREST.t :vattacukor-erdőt
+STR_481D_CANDY_FACTORY :cukorkagyár
+STR_481D_CANDY_FACTORY.t :cukorkagyárat
+STR_481E_BATTERY_FARM :elemfarm
+STR_481E_BATTERY_FARM.t :elemfarmot
+STR_481F_COLA_WELLS :kólakút
+STR_481F_COLA_WELLS.t :kólakútat
+STR_4820_TOY_SHOP :játékbolt
+STR_4820_TOY_SHOP.t :játékboltot
+STR_4821_TOY_FACTORY :játékgyár
+STR_4821_TOY_FACTORY.t :játékgyárat
+STR_4822_PLASTIC_FOUNTAINS :műanyagforrás
+STR_4822_PLASTIC_FOUNTAINS.t :műanyagforrást
+STR_4823_FIZZY_DRINK_FACTORY :üdítőital-gyár
+STR_4823_FIZZY_DRINK_FACTORY.t :üdítőital-gyárat
+STR_4824_BUBBLE_GENERATOR :buborékgenerátor
+STR_4824_BUBBLE_GENERATOR.t :buborékgenerátort
+STR_4825_TOFFEE_QUARRY :tejkaramella fejtő
+STR_4825_TOFFEE_QUARRY.t :tejkaramella fejtőt
+STR_4826_SUGAR_MINE :cukorbánya
+STR_4826_SUGAR_MINE.t :cukorbányát
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Felhasznál: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Felhasznál: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Felhasznál: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Múlt havi termelés:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% elszállítva)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}A fő nézetet a gazdasági épületre állítja
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Új {STRING.t} építenek {TOWN} közelében!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Új {STRING.t} ültettek {TOWN} közelében!
+STR_482F_COST :{BLACK}Ãr: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Nem építheted ide ezt a gazdasági épületet...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...erdő csak a hóhatár fölé ültethető
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} bejelentette, hogy hamarosan bezár!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}{INDUSTRY} bejelentette, hogy ellátási gondok miatt hamarosan bezár!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}{INDUSTRY} bejelentette, hogy a közeli fák hiánya miatt hamarosan bezár!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} növeli a termelését!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}Új szénréteget találtak {INDUSTRY}ban!{}A termelés megkétszereződik!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}Új olajtartalékokat találtak {INDUSTRY} alatt!{}A termelés megkétszereződik!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}{INDUSTRY} haladó gazdálkodási módszerekkel megkétszerezi termelését!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}{INDUSTRY} termelése a felére csökkent
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}Egy rovaráradat {INDUSTRY} pusztulását okozta!{}A termelés a felére csökkent
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...csak a térkép széléhez közel építhető
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}{STRING} termelés nőtt! {INDUSTRY} mostantól {COMMA}%-al többet termel!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}{STRING} termelés csökkent! {INDUSTRY} mostantól {COMMA}%-al kevesebbet termel!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Vonat van az alagútban
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Közúti jármű van az alagútban
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Másik alagút van az útban
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Nem lehet kiásni a földet az alagút túloldalán
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Előbb le kell rombolnod az alagutat
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Előbb le kell rombolnod a hidat
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Nem kezdődhet és végződhet ugyanott
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Sima talaj vagy víz kell, hogy legyen a híd alatt
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}A kezdetének és a végének egy vonalban kell lennie
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Nem alkalmas a hely alagút bejáratának
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Függő, acél
+STR_500F_GIRDER_STEEL :Gerendás, acél
+STR_5010_CANTILEVER_STEEL :Konzolos, acél
+STR_5011_SUSPENSION_CONCRETE :Függő, beton
+STR_5012_WOODEN :Fa
+STR_5013_CONCRETE :Beton
+STR_5014_TUBULAR_STEEL :Cső, acél
+STR_BRIDGE_TUBULAR_SILICON :Cső, Szilikon
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Nem építhetsz ide hidat...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Nem áshatsz ide alagutat...
+STR_5017_RAILROAD_TUNNEL :Vasúti alagút
+STR_5018_ROAD_TUNNEL :Közúti alagút
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Acél függő vasúti híd
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Gerendás acél vasúti híd
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Konzolos acél vasúti híd
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Vasbeton függő vasúti híd
+STR_501F_WOODEN_RAIL_BRIDGE :Fa vasúti híd
+STR_5020_CONCRETE_RAIL_BRIDGE :Beton vasúti híd
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Acél függő közúti híd
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Gerendás acél közúti híd
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Konzolos acél közúti híd
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Vasbeton függő közúti híd
+STR_5025_WOODEN_ROAD_BRIDGE :Fa közúti híd
+STR_5026_CONCRETE_ROAD_BRIDGE :Beton közúti híd
+STR_5027_TUBULAR_RAIL_BRIDGE :Cső vasúti híd
+STR_5028_TUBULAR_ROAD_BRIDGE :Cső közúti híd
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Tárgy van az útban
+STR_5801_TRANSMITTER :Rádióadó
+STR_5802_LIGHTHOUSE :Világítótorony
+STR_5803_COMPANY_HEADQUARTERS :Vállalat székháza
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...vállalat székháza van az útban
+STR_5805_COMPANY_OWNED_LAND :Cég által lefoglalt föld
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Nem veheted meg ezt a földterületet...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...már a tiéd!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Névtelen
+STR_SV_TRAIN_NAME :Vonat {COMMA}
+STR_SV_ROADVEH_NAME :Közúti jármű {COMMA}
+STR_SV_SHIP_NAME :Hajó {COMMA}
+STR_SV_AIRCRAFT_NAME :Repülő {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :Észak-{STRING}
+STR_SV_STNAME_SOUTH :Dél-{STRING}
+STR_SV_STNAME_EAST :Kelet-{STRING}
+STR_SV_STNAME_WEST :Nyugat-{STRING}
+STR_SV_STNAME_CENTRAL :{STRING} i központ
+STR_SV_STNAME_TRANSFER :{STRING}i átszálló
+STR_SV_STNAME_HALT :{STRING}i megálló
+STR_SV_STNAME_VALLEY :{STRING}i völgy
+STR_SV_STNAME_HEIGHTS :{STRING}i hegy
+STR_SV_STNAME_WOODS :{STRING}i erdő
+STR_SV_STNAME_LAKESIDE :{STRING}i tópart
+STR_SV_STNAME_EXCHANGE :{STRING} csere
+STR_SV_STNAME_AIRPORT :{STRING}i reptér
+STR_SV_STNAME_OILFIELD :{STRING}i olajmező
+STR_SV_STNAME_MINES :{STRING}i bánya
+STR_SV_STNAME_DOCKS :{STRING}i kikötő
+STR_SV_STNAME_BUOY_1 :{STRING}i bója 1
+STR_SV_STNAME_BUOY_2 :{STRING}i bója 2
+STR_SV_STNAME_BUOY_3 :{STRING}i bója 3
+STR_SV_STNAME_BUOY_4 :{STRING}i bója 4
+STR_SV_STNAME_BUOY_5 :{STRING}i bója 5
+STR_SV_STNAME_BUOY_6 :{STRING}i bója 6
+STR_SV_STNAME_BUOY_7 :{STRING}i bója 7
+STR_SV_STNAME_BUOY_8 :{STRING}i bója 8
+STR_SV_STNAME_BUOY_9 :{STRING}i bója 9
+STR_SV_STNAME_ANNEXE :{STRING} mellék
+STR_SV_STNAME_SIDINGS :{STRING} oldal
+STR_SV_STNAME_BRANCH :{STRING} mellékág
+STR_SV_STNAME_UPPER :{STRING}-felső
+STR_SV_STNAME_LOWER :{STRING}-alsó
+STR_SV_STNAME_HELIPORT :{STRING}i helikopter-leszálló
+STR_SV_STNAME_FOREST :{STRING}i erdőség
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Nehézségi szint
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Ment
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Könnyű
+STR_6802_MEDIUM :{BLACK}Közepes
+STR_6803_HARD :{BLACK}Nehéz
+STR_6804_CUSTOM :{BLACK}Egyéni
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}Ellenfelek száma legfeljebb: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Ellenfelek kezdésének ideje: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}Városok száma: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}Gazdasági épületek száma: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Max. kezdeti kölcsön: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Éves kamatláb: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Jármű fenntartási költség: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Ellenfelek építkezési sebessége: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Ellenfelek intelligenciája: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Járművek lerobbanása: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Támogatások szorzója: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Építkezés költsége: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Terep típusa: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Tenger/tavak mennyisége: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Gazdasági élet: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Vonatok fordítása: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Katasztrófák: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}A városi tanács hozzáállása a területrendezéshez: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :Egyiksem
+STR_6816_LOW :Kevés
+STR_6817_NORMAL :Normál
+STR_6818_HIGH :Sok
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Nagyon lassú
+STR_681C_SLOW :Lassú
+STR_681D_MEDIUM :Közepes
+STR_681E_FAST :Gyors
+STR_681F_VERY_FAST :Nagyon gyors
+STR_VERY_LOW :Nagyon alacsony
+STR_6820_LOW :Alacsony
+STR_6821_MEDIUM :Közepes
+STR_6822_HIGH :Magas
+STR_6823_NONE :Nincs
+STR_6824_REDUCED :Ritka
+STR_6825_NORMAL :Normál
+STR_6826_X1_5 :1,5x
+STR_6827_X2 :2x
+STR_6828_X3 :3x
+STR_6829_X4 :4x
+STR_682A_VERY_FLAT :Nagyon sík
+STR_682B_FLAT :Sík
+STR_682C_HILLY :Dombos
+STR_682D_MOUNTAINOUS :Hegyes
+STR_682E_STEADY :Stabil
+STR_682F_FLUCTUATING :Változó
+STR_6830_IMMEDIATE :Azonnal
+STR_6831_3_MONTHS_AFTER_PLAYER :3 hónappal utánad
+STR_6832_6_MONTHS_AFTER_PLAYER :6 hónappal utánad
+STR_6833_9_MONTHS_AFTER_PLAYER :9 hónappal utánad
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :Vonal végén és állomásokon
+STR_6835_AT_END_OF_LINE_ONLY :Csak vonal végén
+STR_6836_OFF :Ki
+STR_6837_ON :Be
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Legjobb pontok
+STR_6839_PERMISSIVE :Engedékeny
+STR_683A_TOLERANT :Toleráns
+STR_683B_HOSTILE :Ellenséges
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :({COMMA}. játékos)
+STR_7004_NEW_FACE :{BLACK}Új arc
+STR_7005_COLOR_SCHEME :{BLACK}Szín váltása
+STR_7006_COLOR_SCHEME :{GOLD}Szín:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Új szín
+STR_7008_COMPANY_NAME :{BLACK}Vállalat neve
+STR_7009_PRESIDENT_NAME :{BLACK}Elnök neve
+STR_700A_COMPANY_NAME :A vállalat neve
+STR_700B_PRESIDENT_S_NAME :Az elnök neve
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Nem változtathatod meg a cég nevét...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Nem változtathatod meg az elnök nevét...
+STR_700E_FINANCES :{WHITE}{COMPANY} pénzügyei {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Kiadás/Bevétel
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Építkezés
+STR_7012_NEW_VEHICLES :{GOLD}Új járművek
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Vonat működtetési költség
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Közúti jármű műk. költség
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Repülőgép műk. költség
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Hajó működtetési költség
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Tulajdon fenntartása
+STR_7018_TRAIN_INCOME :{GOLD}Vonatok bevétele
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Közúti járművek bevétele
+STR_701A_AIRCRAFT_INCOME :{GOLD}Repülőgépek bevétele
+STR_701B_SHIP_INCOME :{GOLD}Hajók bevétele
+STR_701C_LOAN_INTEREST :{GOLD}Kölcsön kamata
+STR_701D_OTHER :{GOLD}Egyéb
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Összesen:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Jövedelem grafikon
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Működési nyereség grafikon
+STR_7026_BANK_BALANCE :{WHITE}Banki egyenleg
+STR_7027_LOAN :{WHITE}Kölcsön
+STR_MAX_LOAN :{WHITE}Max. kölcsön: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}Kölcsönkér {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Visszafizet {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...{CURRENCY} a megengedett legnagyobb kölcsön
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Nem kölcsönözhetsz több pénzt...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...már letörlesztetted az összeset
+STR_702E_REQUIRED :{WHITE}...{CURRENCY} kellene hozzá
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Nem törleszthetsz a kölcsönből...
+STR_INSUFFICIENT_FUNDS :{WHITE}Nem tudod a banktól kölcsönkapott pénzt továbbadni...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Új arc választása az elnöknek
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}A cég járművei színének megváltoztatása
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Az elnök nevének megváltoztatása
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}A cég nevének megváltoztatása
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Kattints az új színre
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}A kölcsön növelése
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}A kölcsön egy részének törlesztése
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(Elnök)
+STR_7038_INAUGURATED :{GOLD}Alapítás éve: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Járművek:
+STR_TRAINS :{WHITE}{COMMA} vonat
+STR_ROAD_VEHICLES :{WHITE}{COMMA} közúti jármű
+STR_AIRCRAFT :{WHITE}{COMMA} repülőgép
+STR_SHIPS :{WHITE}{COMMA} hajó
+STR_7042_NONE :{WHITE}Nincs
+STR_7043_FACE_SELECTION :{WHITE}Arcválasztás
+STR_7044_MALE :{BLACK}Férfi
+STR_7045_FEMALE :{BLACK}NÅ‘
+STR_7046_NEW_FACE :{BLACK}Új arc
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Új arc elvetése
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Új arc elfogadása
+STR_7049_SELECT_MALE_FACES :{BLACK}Férfi arcok kiválasztása
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Női arcok kiválasztása
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Véletlenszerű új arc létrehozása
+STR_704C_KEY :{BLACK}Jelkulcs
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}A grafikonok jelmagyarázata
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Jelmagyarázat a grafikonokhoz
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}A vállalat adatainak mutatása/elrejtése a grafikonon
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Elszállított áruk mennyisége
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Cégek teljesítménye (legjobb teljesítmény=1000)
+STR_7052_COMPANY_VALUES :{WHITE}Vállalatok értéke
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}A cégek helyezése
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}Egy szállítási cég bajban van!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} csődöt jelent vagy el kell adni, ha teljesítménye nem nő hamarosan!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME} {}(Elnök)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Szállítási cégek egyesülése!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} céget felvásárolta {COMPANY} {CURRENCY}-ért!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Egy olyan szállítási céget keresünk, aki tovább vezetné a cégünket{}{}Megveszed {COMPANY} céget {CURRENCY}-ért?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Csőd!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} céget bezáratták a hitelezői és minden vagyonát elárverezték!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}Új szállítási vállalatot alapítottak!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} {TOWN} közelében kezd építkezni!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Nem veheted meg a céget...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Rakományok szállítási díja
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Úton töltött napok
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Fizetség 10 egység (vagy 10000 liter) áru 20 négyzetre való szállításáért
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Az adott áru grafikonjának mutatása be/ki
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Mérnök
+STR_7067_TRAFFIC_MANAGER :Forgalomigazgató
+STR_7068_TRANSPORT_COORDINATOR :Szállításszervező
+STR_7069_ROUTE_SUPERVISOR :Útfelügyelő
+STR_706A_DIRECTOR :Igazgató
+STR_706B_CHIEF_EXECUTIVE :Főigazgató
+STR_706C_CHAIRMAN :Alelnök
+STR_706D_PRESIDENT :Elnök
+STR_706E_TYCOON :Nagytőkés
+STR_706F_BUILD_HQ :{BLACK}Székház építése
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}A cég székházának megépítése/ megnézése
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}A cég főhadiszállásának újraépítése másutt a cég értékének 1%-áért
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Nem építheted ide a székházadat...
+STR_7072_VIEW_HQ :{BLACK}Székház
+STR_RELOCATE_HQ :{BLACK}FH áthelyezése
+STR_COMPANY_PASSWORD :{BLACK}Jelszó
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Védd le a vállalatodat jelszóval ha nem akarod hogy mások csatlakozzanak hozzá.
+STR_SET_COMPANY_PASSWORD :Vállalati jelszó beállítása
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}Gazdasági visszaesés!{}{}A közgazdászok gazdasági válságtól tartanak!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Vége a visszaesésnek!{}{}A kereskedelem fellendül, ami önbizalmat ad az iparnak, és erősödik a gazdaság!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Kicsi/nagy ablakméret közötti váltás
+STR_7076_COMPANY_VALUE :{GOLD}Cég értéke: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}25% megvétele a cégből
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}25% eladása a cégből
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}25% megvétele ebből a cégből
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}25% eladása ebből a cégből
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Nem vehetsz 25%-ot ebből a cégből...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}Nem adhatsz el 25%-ot ebből a cégből...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% {COMPANY} tulajdona)
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% {COMPANY} tulajdona{} {COMMA}% {COMPANY} tulajdona)
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} céget felvásárolta {COMPANY}!
+STR_7080_PROTECTED :{WHITE}Ez a cég egyelőre még nem rendelkezik részvényekkel...
+
+STR_LIVERY_DEFAULT :Alapértelmezett
+STR_LIVERY_STEAM :GÅ‘zmozdony
+STR_LIVERY_DIESEL :Dízel mozdony
+STR_LIVERY_ELECTRIC :Elektromos mozdony
+STR_LIVERY_MONORAIL :Egysínű mozdony
+STR_LIVERY_MAGLEV :Maglev mozdony
+STR_LIVERY_DMU :DMU
+STR_LIVERY_EMU :EMU
+STR_LIVERY_PASSENGER_WAGON_STEAM :Utasszállító kocsi (gőz)
+STR_LIVERY_PASSENGER_WAGON_DIESEL :Utasszállító kocsi (dízeles)
+STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Utasszállító kocsi (elektromos)
+STR_LIVERY_FREIGHT_WAGON :Tehervagon
+STR_LIVERY_BUS :Busz
+STR_LIVERY_TRUCK :Teherautó
+STR_LIVERY_PASSENGER_SHIP :Utasszállító komp
+STR_LIVERY_FREIGHT_SHIP :Teherhajó
+STR_LIVERY_HELICOPTER :Helikopter
+STR_LIVERY_SMALL_PLANE :Kis repülőgép
+STR_LIVERY_LARGE_PLANE :Nagy repülőgép
+
+STR_LIVERY_GENERAL_TIP :{BLACK}Ãltalános szinsémák mutatása
+STR_LIVERY_TRAIN_TIP :{BLACK}Vonat szinsémák mutatása
+STR_LIVERY_ROADVEH_TIP :{BLACK}Mutasd a közúti járművek szinsémáit
+STR_LIVERY_SHIP_TIP :{BLACK}Hajó szinsémák mutatása
+STR_LIVERY_AIRCRAFT_TIP :{BLACK}Repülőgép szinsémák mutatása
+STR_LIVERY_PRIMARY_TIP :{BLACK}Válassz egy elsődleges szint a kiválasztott sémához
+STR_LIVERY_SECONDARY_TIP :{BLACK}Válassz egy másodlagos szint a kiválasztott sémához
+STR_LIVERY_PANEL_TIP :{BLACK}Válassz megváltoztatandó szinsémát, vagy szinsémákat a CTRL+kattintással. Kattints a dobozra a szinséma használat váltásához.
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (GÅ‘z)
+STR_8001_MJS_250_DIESEL :MJS 250 (Dízel)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Cammogó Csi-hu-hu
+STR_8003_POWERNAUT_CHOO_CHOO :SemmiErő Csi-hu-hu
+STR_8004_MIGHTYMOVER_CHOO_CHOO :ErőGép Csi-hu-hu
+STR_8005_PLODDYPHUT_DIESEL :Cammogó Dízel
+STR_8006_POWERNAUT_DIESEL :SemmiErő Dízel
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (GÅ‘z)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (GÅ‘z)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (GÅ‘z)
+STR_800A_SH_8P_STEAM :SH '8P' (GÅ‘z)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (Dízel)
+STR_800C_DASH_DIESEL :'Dash' (Dízel)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (Dízel)
+STR_800E_UU_37_DIESEL :UU '37' (Dízel)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (Dízel)
+STR_8010_CS_4000_DIESEL :CS 4000 (Dízel)
+STR_8011_CS_2400_DIESEL :CS 2400 (Dízel)
+STR_8012_CENTENNIAL_DIESEL :Centennial (Dízel)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (Dízel)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (Dízel)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (Dízel)
+STR_8016_SH_125_DIESEL :SH '125' (Dízel)
+STR_8017_SH_30_ELECTRIC :SH '30' (Elektromos)
+STR_8018_SH_40_ELECTRIC :SH '40' (Elektromos)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (Elektromos)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (Elektromos)
+STR_801B_PASSENGER_CAR :Személyvagon
+STR_801C_MAIL_VAN :Levélszállító vagon
+STR_801D_COAL_CAR :Szénszállító vagon
+STR_801E_OIL_TANKER :Olajszállító vagon
+STR_801F_LIVESTOCK_VAN :Ãllatszállító vagon
+STR_8020_GOODS_VAN :Ãruszállító vagon
+STR_8021_GRAIN_HOPPER :Gabonaszállító vagon
+STR_8022_WOOD_TRUCK :Faszállító vagon
+STR_8023_IRON_ORE_HOPPER :Vasércszállító vagon
+STR_8024_STEEL_TRUCK :Acélszállító vagon
+STR_8025_ARMORED_VAN :Páncélozott vagon
+STR_8026_FOOD_VAN :Ételszállító vagon
+STR_8027_PAPER_TRUCK :Papírszállító vagon
+STR_8028_COPPER_ORE_HOPPER :Rézércszállító vagon
+STR_8029_WATER_TANKER :Vízszállító vagon
+STR_802A_FRUIT_TRUCK :Gyümölcsszállító vagon
+STR_802B_RUBBER_TRUCK :Gumiszállító vagon
+STR_802C_SUGAR_TRUCK :Cukorszállító vagon
+STR_802D_COTTON_CANDY_HOPPER :Vattacukorszállító vagon
+STR_802E_TOFFEE_HOPPER :Tejkaramella-szállító vagon
+STR_802F_BUBBLE_VAN :Buborékszállító vagon
+STR_8030_COLA_TANKER :Kólaszállító vagon
+STR_8031_CANDY_VAN :Cukorkaszállító vagon
+STR_8032_TOY_VAN :Játékszállító vagon
+STR_8033_BATTERY_TRUCK :Elemszállító vagon
+STR_8034_FIZZY_DRINK_TRUCK :Szénsavasital-szállító vagon
+STR_8035_PLASTIC_TRUCK :Műanyagszállító vagon
+STR_8036_X2001_ELECTRIC :'X2001' (Elektromos)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Elektromos)
+STR_8038_WIZZOWOW_Z99 :ZummDeGyors Z99
+STR_8039_PASSENGER_CAR :Személyvagon
+STR_803A_MAIL_VAN :Levélszállító vagon
+STR_803B_COAL_CAR :Szénszállító vagon
+STR_803C_OIL_TANKER :Olajszállító vagon
+STR_803D_LIVESTOCK_VAN :Ãllatszállító vagon
+STR_803E_GOODS_VAN :Ãruszállító vagon
+STR_803F_GRAIN_HOPPER :Gabonaszállító vagon
+STR_8040_WOOD_TRUCK :Faszállító vagon
+STR_8041_IRON_ORE_HOPPER :Vasércszállító vagon
+STR_8042_STEEL_TRUCK :Acélszállító vagon
+STR_8043_ARMORED_VAN :Páncélozott vagon
+STR_8044_FOOD_VAN :Ételszállító vagon
+STR_8045_PAPER_TRUCK :Papírszállító vagon
+STR_8046_COPPER_ORE_HOPPER :Rézércszállító vagon
+STR_8047_WATER_TANKER :Vízszállító vagon
+STR_8048_FRUIT_TRUCK :Gyümölcsszállító vagon
+STR_8049_RUBBER_TRUCK :Gumiszállító vagon
+STR_804A_SUGAR_TRUCK :Cukorszállító vagon
+STR_804B_COTTON_CANDY_HOPPER :Vattacukorszállító vagon
+STR_804C_TOFFEE_HOPPER :Tejkaramella-szállító vagon
+STR_804D_BUBBLE_VAN :Buborékszállító vagon
+STR_804E_COLA_TANKER :Kólaszállító vagon
+STR_804F_CANDY_VAN :Cukorkaszállító vagon
+STR_8050_TOY_VAN :Játékszállító vagon
+STR_8051_BATTERY_TRUCK :Elemszállító vagon
+STR_8052_FIZZY_DRINK_TRUCK :Szénsavasital-szállító vagon
+STR_8053_PLASTIC_TRUCK :Műanyagszállító vagon
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviátán' (Elektromos)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Küklopsz' (Elektromos)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegazus' (Elektromos)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Kiméra' (Elektromos)
+STR_8058_WIZZOWOW_ROCKETEER :ZummDeGyors Rakéta
+STR_8059_PASSENGER_CAR :Személyvagon
+STR_805A_MAIL_VAN :Levélszállító vagon
+STR_805B_COAL_CAR :Szénszállító vagon
+STR_805C_OIL_TANKER :Olajszállító vagon
+STR_805D_LIVESTOCK_VAN :Ãllatszállító vagon
+STR_805E_GOODS_VAN :Ãruszállító vagon
+STR_805F_GRAIN_HOPPER :Gabonaszállító vagon
+STR_8060_WOOD_TRUCK :Faszállító vagon
+STR_8061_IRON_ORE_HOPPER :Vasércszállító vagon
+STR_8062_STEEL_TRUCK :Acélszállító vagon
+STR_8063_ARMORED_VAN :Páncélozott vagon
+STR_8064_FOOD_VAN :Ételszállító vagon
+STR_8065_PAPER_TRUCK :Papírszállító vagon
+STR_8066_COPPER_ORE_HOPPER :Rézércszállító vagon
+STR_8067_WATER_TANKER :Vízszállító vagon
+STR_8068_FRUIT_TRUCK :Gyümölcsszállító vagon
+STR_8069_RUBBER_TRUCK :Gumiszállító vagon
+STR_806A_SUGAR_TRUCK :Cukorszállító vagon
+STR_806B_COTTON_CANDY_HOPPER :Vattacukorszállító vagon
+STR_806C_TOFFEE_HOPPER :Tejkaramella-szállító vagon
+STR_806D_BUBBLE_VAN :Buborékszállító vagon
+STR_806E_COLA_TANKER :Kólaszállító vagon
+STR_806F_CANDY_VAN :Cukorkaszállító vagon
+STR_8070_TOY_VAN :Játékszállító vagon
+STR_8071_BATTERY_TRUCK :Elemszállító vagon
+STR_8072_FIZZY_DRINK_TRUCK :Szénsavasital-szállító vagon
+STR_8073_PLASTIC_TRUCK :Műanyagszállító vagon
+STR_8074_MPS_REGAL_BUS :MPS királyi busz
+STR_8075_HEREFORD_LEOPARD_BUS :Hereford leopárd busz
+STR_8076_FOSTER_BUS :Foster busz
+STR_8077_FOSTER_MKII_SUPERBUS :Foster MkII szuperbusz
+STR_8078_PLODDYPHUT_MKI_BUS :Cammogó MkI busz
+STR_8079_PLODDYPHUT_MKII_BUS :Cammogó MkII busz
+STR_807A_PLODDYPHUT_MKIII_BUS :Cammogó MkIII busz
+STR_807B_BALOGH_COAL_TRUCK :Balogh szénszállító autó
+STR_807C_UHL_COAL_TRUCK :Uhl szénszállító
+STR_807D_DW_COAL_TRUCK :DW szénszállító
+STR_807E_MPS_MAIL_TRUCK :MPS levélszállító
+STR_807F_REYNARD_MAIL_TRUCK :Reynard levélszállító
+STR_8080_PERRY_MAIL_TRUCK :Perry levélszállító
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :ErőGép levélszállító
+STR_8082_POWERNAUGHT_MAIL_TRUCK :SemmiErő levélszállító
+STR_8083_WIZZOWOW_MAIL_TRUCK :ZummDeGyors levélszállító
+STR_8084_WITCOMBE_OIL_TANKER :Witcombe olajszállító
+STR_8085_FOSTER_OIL_TANKER :Foster olajszállító
+STR_8086_PERRY_OIL_TANKER :Perry olajszállító
+STR_8087_TALBOTT_LIVESTOCK_VAN :Talbott állatszállító
+STR_8088_UHL_LIVESTOCK_VAN :Uhl állatszállító
+STR_8089_FOSTER_LIVESTOCK_VAN :Foster állatszállító
+STR_808A_BALOGH_GOODS_TRUCK :Balogh áruszállító
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Craighead áruszállító
+STR_808C_GOSS_GOODS_TRUCK :Goss áruszállító
+STR_808D_HEREFORD_GRAIN_TRUCK :Hereford gabonaszállító
+STR_808E_THOMAS_GRAIN_TRUCK :Thomas gabonaszállító
+STR_808F_GOSS_GRAIN_TRUCK :Goss gabonaszállító
+STR_8090_WITCOMBE_WOOD_TRUCK :Witcombe faszállító
+STR_8091_FOSTER_WOOD_TRUCK :Foster faszállító
+STR_8092_MORELAND_WOOD_TRUCK :Moreland faszállító
+STR_8093_MPS_IRON_ORE_TRUCK :MPS vasércszállító
+STR_8094_UHL_IRON_ORE_TRUCK :Uhl vasércszállító
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Chippy vasércszállító
+STR_8096_BALOGH_STEEL_TRUCK :Balogh acélszállító
+STR_8097_UHL_STEEL_TRUCK :Uhl acélszállító
+STR_8098_KELLING_STEEL_TRUCK :Kelling acélszállító
+STR_8099_BALOGH_ARMORED_TRUCK :Balogh páncélkocsi
+STR_809A_UHL_ARMORED_TRUCK :Uhl páncélkocsi
+STR_809B_FOSTER_ARMORED_TRUCK :Foster páncélkocsi
+STR_809C_FOSTER_FOOD_VAN :Foster ételszállító
+STR_809D_PERRY_FOOD_VAN :Perry ételszállító
+STR_809E_CHIPPY_FOOD_VAN :Chippy ételszállító
+STR_809F_UHL_PAPER_TRUCK :Uhl papírszállító
+STR_80A0_BALOGH_PAPER_TRUCK :Balogh papírszállító
+STR_80A1_MPS_PAPER_TRUCK :MPS papírszállító
+STR_80A2_MPS_COPPER_ORE_TRUCK :MPS rézércszállító
+STR_80A3_UHL_COPPER_ORE_TRUCK :Uhl rézércszállító
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Goss rézércszállító
+STR_80A5_UHL_WATER_TANKER :Uhl vízszállító
+STR_80A6_BALOGH_WATER_TANKER :Balogh vízszállító
+STR_80A7_MPS_WATER_TANKER :MPS vízszállító
+STR_80A8_BALOGH_FRUIT_TRUCK :Balogh gyümölcsszállító
+STR_80A9_UHL_FRUIT_TRUCK :Uhl gyümölcsszállító
+STR_80AA_KELLING_FRUIT_TRUCK :Kelling gyümölcsszállító
+STR_80AB_BALOGH_RUBBER_TRUCK :Balogh gumiszállító
+STR_80AC_UHL_RUBBER_TRUCK :Uhl gumiszállító
+STR_80AD_RMT_RUBBER_TRUCK :RMT gumiszállító
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :SemmiErő cukorszállító
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :ErőGép cukorszállító
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :ZummDeGyors cukorszállító
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :SemmiErő kólaszállító
+STR_80B2_POWERNAUGHT_COLA_TRUCK :ErőGép kólaszállító
+STR_80B3_WIZZOWOW_COLA_TRUCK :ZummDeGyors kólaszállító
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :SemmiErő vattacukor-sz.
+STR_80B5_POWERNAUGHT_COTTON_CANDY :ErőGép vattacukor-sz.
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :ZummDeGyors vattacukor-sz.
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :SemmiErő tejkaramella-sz.
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :ErőGép tejkaramella-sz.
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :ZummDeGyors tejkaramella-sz.
+STR_80BA_MIGHTYMOVER_TOY_VAN :SemmiErő játékszállító
+STR_80BB_POWERNAUGHT_TOY_VAN :ErőGép játékszállító
+STR_80BC_WIZZOWOW_TOY_VAN :ZummDeGyors játékszállító
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :SemmiErő cukorkaszállító
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :ErőGép cukorkaszállító
+STR_80BF_WIZZOWOW_CANDY_TRUCK :ZummDeGyors cukorkaszállító
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :SemmiErő elemszállító
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :ErőGép elemszállító
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :ZummDeGyors elemszállító
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :SemmiErő szénsavasital-sz.
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :ErőGép szénsavasital-sz.
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :ZummDeGyors szénsavasital-sz.
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :SemmiErő műanyagszállító
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :ErőGép műanyagszállító
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :ZummDeGyors műanyagszállító
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :SemmiErő buborékszállító
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :ErőGép buborékszállító
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :ZummDeGyors buborékszállító
+STR_80CC_MPS_OIL_TANKER :MPS olajszállító hajó
+STR_80CD_CS_INC_OIL_TANKER :CS-Inc. olajszállító hajó
+STR_80CE_MPS_PASSENGER_FERRY :MPS komp
+STR_80CF_FFP_PASSENGER_FERRY :FFP komp
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Bakewell 300 légpárnás hajó
+STR_80D1_CHUGGER_CHUG_PASSENGER :Zity-zöty komp
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :SzétRáz komp
+STR_80D3_YATE_CARGO_SHIP :Yate teherhajó
+STR_80D4_BAKEWELL_CARGO_SHIP :Bakewell teherhajó
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :ErőGép teherhajó
+STR_80D6_POWERNAUT_CARGO_SHIP :SemmiErő teherhajó
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dárda
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxis
+STR_80E9_AIRTAXI_A21 :Légitaxi A21
+STR_80EA_AIRTAXI_A31 :Légitaxi A31
+STR_80EB_AIRTAXI_A32 :Légitaxi A32
+STR_80EC_AIRTAXI_A33 :Légitaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :Légitaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hiperdárda 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Cammogó 100
+STR_80F9_PLODDYPHUT_500 :Cammogó 500
+STR_80FA_FLASHBANG_X1 :BummSzáguld X1
+STR_80FB_JUGGERPLANE_M1 :LégiHáz M1
+STR_80FC_FLASHBANG_WIZZER :CsíkHúzó
+STR_80FD_TRICARIO_HELICOPTER :Tricario Helikopter
+STR_80FE_GURU_X2_HELICOPTER :Guru X2 Helikopter
+STR_80FF_POWERNAUT_HELICOPTER :SemmiErő Helikopter
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Üzenet egy járműgyártótól
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}Most készültek el egy új {STRING} tervei - érdekelne a jármű egy éves kizárólagos használata, hogy megnézhessük a képességeit, mielőtt mindenki számára elérhetővé tesszük ?
+STR_8102_RAILROAD_LOCOMOTIVE :vasúti mozdony
+STR_8103_ROAD_VEHICLE :közúti jármű
+STR_8104_AIRCRAFT :repülőgép
+STR_8105_SHIP :hajó
+STR_8106_MONORAIL_LOCOMOTIVE :egysínű mozdony
+STR_8107_MAGLEV_LOCOMOTIVE :MagLev mozdony
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}{TOWN}i járműtelep
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Az emberek ünnepelnek . . .{}Megérkezett az első vonat {STATION} állomásra!
+STR_8802_DETAILS :{WHITE}{STRING} adatai
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Vonat van az útban
+STR_8804 :{SETX 10}{COMMA}: {STRING}{STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING}{STRING}
+STR_8806_GO_TO :Menj {STATION} állomásra
+STR_8807_GO_TO_TRANSFER :Menj {STATION} (odaszállít és felvesz rakományt)
+STR_8808_GO_TO_UNLOAD :Menj {STATION} (lepakol)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Menj {STATION} (odaszállít és üresen továbbmegy)
+STR_880A_GO_TO_LOAD :Menj {STATION} (felpakol)
+STR_880B_GO_TO_TRANSFER_LOAD :Menj {STATION} (odaszállít és teljes rakományra vár)
+STR_880C_GO_NON_STOP_TO :Megállás nélkül menj {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Megállás nélkül menj {STATION} (odaszállít és felvesz rakományt)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Megállás nélkül menj {STATION} (lepakol)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Megállás nélkül menj {STATION} (odaszállít és üresen távozik)
+STR_8810_GO_NON_STOP_TO_LOAD :Megállás nélkül menj {STATION} (felpakol)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Megállás nélkül menj {STATION} (odaszállít és teljes rakományra vár)
+STR_GO_TO_TRAIN_DEPOT :Menj {TOWN} jármütelepre
+STR_SERVICE_AT_TRAIN_DEPOT :Javítsd a vonatot a {TOWN}i járműtelepen
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Menj megállás nélkül {TOWN}i járműtelepre
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Mindig javítsd a vonatot a {TOWN}i járműtelepen
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}Úton {TOWN} járműtelepére
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}Úton {TOWN} járműtelepére, {VELOCITY}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE :{LTBLUE}Javítás {TOWN} depójában
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE_VEL :{LTBLUE}Javítás {TOWN} depójában, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (Hibás menetrend)
+
+STR_UNKNOWN_DESTINATION :ismeretlen célpont
+STR_8812_EMPTY :{LTBLUE}Ãœres
+STR_8813_FROM :{LTBLUE}{CARGO} {STATION} állomásról
+STR_FROM_MULT :{LTBLUE}{CARGO} {STATION} állomásról (x{NUM})
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}{COMMA}. vonat a járműtelepen várakozik
+STR_8815_NEW_VEHICLES :{BLACK}Új járművek
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Túl hosszú a vonat
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Csak a járműtelepen álló vonatokat lehet megváltoztatni
+STR_881B_TRAINS :{WHITE}{COMPANY} vonatai - {COMMA}
+
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Új vasúti járművek
+STR_NEW_ELRAIL_VEHICLES :{WHITE}Új elektromos vasúti járművek
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Új egysínű járművek
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Új MagLev járművek
+STR_ALL_AVAIL_RAIL_VEHICLES :{WHITE}Vasúti járművek
+
+STR_881F_BUILD_VEHICLE :{BLACK}Megvesz
+STR_CLONE_ROAD_VEHICLE :{BLACK}Jármű másolása
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}Ide kattintva ezen jármű másolatát készítheted el. Control+kattintás esetén a menetrendet is megosztja
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Ide kattintve elkészítheted egy közúti jármű másolatát. Kattints ide, majd a másolandó járműre. Control+kattintás esetén a menetrendet is megosztod
+STR_CLONE_TRAIN :{BLACK}Vonat másolása
+STR_CLONE_TRAIN_INFO :{BLACK}Ide kattintva a teljes vonat másolatát készítheted el. Control+kattintás esetén a menetrendet is megosztod
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}Ide kattintva egy teljes vonat másolatát készítheted el. Kattints ide majd a másolandó vonatra. Control+kattintás esetén a menetrendet is megoszthatod
+STR_8820_RENAME :{BLACK}Ãtnevez
+STR_8823_SKIP :{BLACK}Kihagy
+STR_8824_DELETE :{BLACK}Töröl
+STR_8825_NON_STOP :{BLACK}Non-stop
+STR_8826_GO_TO :{BLACK}Új cél
+STR_8827_FULL_LOAD :{BLACK}Telepakol
+STR_8828_UNLOAD :{BLACK}Lepakol
+STR_REFIT :{BLACK}Ãtalakít
+STR_REFIT_TIP :{BLACK}Válaszd ki minek a szállítására álljunk át. Ctrl+kattintással eltávolítod az átalakítási utasítást.
+STR_8829_ORDERS :{WHITE}{VEHICLE} menetrendje
+STR_882A_END_OF_ORDERS :{SETX 10}- - Menetrend vége - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}Javítás
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Nem veheted meg a vasúti járművet...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Vásárlás éve: {LTBLUE}{NUM}{BLACK} Érték: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Érték: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}Felpakol / Lepakol
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}A remízben kellene állnia ehhez
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Nem küldheted a vonatot a járműtelepre...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Nincs több hely új célpontnak
+STR_8832_TOO_MANY_ORDERS :{WHITE}Túl sok a célpont
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Nem adhatsz meg új célpontot...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Nem törölheted ezt a célpontot...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Nem módosíthatod ezt a célpontot...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Nem mozgathatod a járművet...
+STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}A mozdony első felének mindig elöl kell lennie
+STR_8838_N_A :Nincs{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Nem adhatod el a vasúti járművet...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Nem találok utat a helyi járműtelepre
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Nem indíthatod el/ állíthatod meg a vonatot...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Javítási időköz: {LTBLUE}{COMMA} nap{BLACK} Utolsó javítás: {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Szervíz-intervallum: {LTBLUE}{COMMA}%{BLACK} Utolsó szervíz: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Vonatok - kattints egy vonatra az adataihoz
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Új vonatok vásárlása (járműtelep szükséges hozzá)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Vonatok - kattints egy vonatra az adataihoz, húzással áthelyezheted a járműveket
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Új vasúti jármű vásárlása
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Dobj ide egy járművet az eladásához
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}A fő nézetet a járműtelepre állítja
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Vasúti jármű kiválasztása - kattints egy járműre az adataihoz
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}A kijelölt vasúti jármű megvétele
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}A vasúti jármű márkanevének megváltoztatása
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Aktuális vonatesemény - kattints ide a vonat elindításához/megállításához
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}A vonat menetrendjének megmutatása
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}A fő nézetet a vonatra állítja
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}A járműtelepre küldi a vonatot
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}A vonat rákényszerítése, hogy ne várja meg a szemafor zöld jelzését
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}A vonat megfordítása
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}A vonat adatai
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Javítási időköz növelése
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Javítási időköz csökkentése
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}A szállított rakomány részletei
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}A vonat kocsiainak részletei
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}A kocsik kapacitása
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Megmutatja a vonat teljes kapacitását, rakománytípusokra lebontva
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Menetrend - kattints egy célpontra a kijelöléséhez
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}Az aktuális célpont kihagyása és ugrás a következőre
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}A kijelölt célpont törlése
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}A kijelölt célpont felé megállás nélkül kell haladni
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Új célpont beillesztése a kijelölt elé vagy a lista végére
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}A kijelölt célponton meg kell várni, amíg telerakják a járművet
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}A kijelölt célponton le kell pakolni a rakományt
+STR_SERVICE_HINT :{BLACK}Célpont kihagyása, ha javítás szükséges
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}Új {STRING} használható!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Ãr: {CURRENCY} Súly: {WEIGHT_S}{}Sebesség: {VELOCITY} Teljesítmény: {POWER}{}Működtetési költség: {CURRENCY}/év{}Kapacitás: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}Lerobbant
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}Kor: {LTBLUE}{STRING}{BLACK} Működtetési költség: {LTBLUE}{CURRENCY}/év
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Súly: {LTBLUE}{WEIGHT_S} {BLACK}Teljesítmény: {LTBLUE}{POWER}{BLACK} Végsebesség: {LTBLUE} {VELOCITY}
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Súly: {LTBLUE}{WEIGHT_S} {BLACK}Telj.: {LTBLUE}{POWER}{BLACK} Max. seb.: {LTBLUE}{VELOCITY} {BLACK}Max. húzóerő: {LTBLUE}{FORCE}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Idei haszon: {LTBLUE}{CURRENCY} (tavalyi: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}Megbízhatóság: {LTBLUE}{COMMA}% {BLACK}Lerobbanások az utolsó javítás óta: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Ãll
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Nem indíthatod el a vonatot veszélyben...
+STR_8863_CRASHED :{RED}Balesetet szenvedett!
+
+STR_8865_NAME_TRAIN :{WHITE}Vonat átnevezése
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}Nem nevezheted át a vonatot...
+STR_8867_NAME_TRAIN :{BLACK}Vonat átnevezése
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Vonatbaleset!{}{COMMA} ember halt meg az ütközésnél
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Nem fordíthatod meg a vonatot...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Márkanév megváltoztatása
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Nem változtathatod meg a márkanevet...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}A kiválasztott állomásnál a jármű a rakományt leteszi
+STR_886F_TRANSFER :{BLACK}Elszállít
+
+STR_TRAIN_STOPPING :{RED}Lassít
+STR_TRAIN_STOPPING_VEL :{RED}Lassít, {VELOCITY}
+STR_INCOMPATIBLE_RAIL_TYPES :inkompatibilis sintípusok
+STR_TRAIN_NO_POWER :{RED}Nincs áram
+STR_TRAIN_START_NO_CATENARY :Ennek a sínnek nincs felsővezetéke, a vonat nem tud indulni
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Közúti jármű van az útban
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} közúti járművei - {COMMA}
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}{TOWN}i garázs
+STR_9004_NEW_VEHICLES :{BLACK}Új járművek
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}Új közúti járművek
+STR_9007_BUILD_VEHICLE :{BLACK}Megvesz
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Nem veheted meg a közúti járművet...
+STR_900C_DETAILS :{WHITE}{VEHICLE} adatai
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}Kor: {LTBLUE}{STRING}{BLACK} Működtetési költség: {LTBLUE}{CURRENCY}/év
+STR_900E_MAX_SPEED :{BLACK}Végsebesség: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Idei haszon: {LTBLUE}{CURRENCY} (tavalyi: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}Megbízhatóság: {LTBLUE}{COMMA}% {BLACK}Lerobbanások az utolsó javítás óta: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Vásárlás éve: {LTBLUE}{NUM}{BLACK} Érték: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Kapacitás: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}...garázsban kellene állnia ehhez
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Nem adhatod el a közúti járművet...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Nem indíthatod el/ állíthatod meg a közúti járművet...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}{COMMA}. közúti jármű a garázsban várakozik
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}Úton {TOWN} garázsába
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}Úton {TOWN} garázsába, {VELOCITY}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE :{LTBLUE}Javítás {TOWN} autószervízében
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE_VEL :{LTBLUE}Javítás {TOWN} autószervízében, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Nem küldheted a járművet a garázsba...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Nem találom a helyi garázst
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Közúti járművek - kattints egy járműre az adataihoz
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Új közúti járművek vásárlása (garázs kell hozzá)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Aktuális járműesemény - kattints ide a jármű elindításához/ megállításához
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}A jármű menetrendjének megmutatása
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}A fő nézetet a járműre állítja
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Garázsba küldi a járművet
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Visszafordítja a járművet
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}A közúti jármű adatai
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Járművek - kattints egy járműre az adataihoz
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Új közúti jármű vásárlása
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Dobj ide egy járművet az eladásához
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}A fő nézetet a garázsra állítja
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Közúti jármű kiválasztása - kattints egy járműre az adataihoz
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}A kijelölt közúti jármű megvétele
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}Új közúti jármű használható!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Ãr: {CURRENCY}{}Sebesség: {VELOCITY}{}Működtetési költség: {CURRENCY}/év{}Kapacitás: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Közúti jármű átnevezése
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Nem nevezheted át a közúti járművet...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Közúti jármű átnevezése
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Az emberek ünnepelnek . . .{}Megérkezett az első busz {STATION} állomásra!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Az emberek ünnepelnek . . .{}Megérkezett az első teherautó {STATION} állomásra!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}Közúti baleset!{}A vezető meghalt a vonattal való ütközéskor
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}Közúti baleset!{}{COMMA} ember meghalt a vonattal való ütközéskor
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Nem fordíthatod vissza a járművet...
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}Több részből álló járművet nem lehet megfordítani
+STR_9034_RENAME :{BLACK}Ãtnevez
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}A közúti jármű márkanevének megváltoztatása
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Márkanév megváltoztatása
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Nem változtathatod meg a márkanevet...
+STR_9038_GO_TO_ROADVEH_DEPOT :Menj a {TOWN}i garázsba
+STR_SERVICE_AT_ROADVEH_DEPOT :Javítsd a járművet a {TOWN}i garázsban
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Teherautó átalakítása hogy mást is tudjon szállítani
+STR_REFIT_ROAD_VEHICLE :{BLACK}Teherautó átalakítása
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Teherautó átalakítása a kijelölt áru szállíthatóságáért
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Nem lehet átalakítani a teherautót...
+STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Válaszd ki a közúti jármű által szállítandó rakományt
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Kikötőépítés
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Kikötőépítés
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Nem építhetsz ide kikötőt...
+STR_9803_SHIP_DEPOT :{WHITE}{TOWN}i dokk
+STR_9804_NEW_SHIPS :{BLACK}Új hajók
+STR_9805_SHIPS :{WHITE}{COMPANY} hajói - {COMMA}
+STR_9808_NEW_SHIPS :{WHITE}Új hajók
+STR_9809_BUILD_SHIP :{BLACK}Megvesz
+STR_CLONE_SHIP :{BLACK}Hajó másolása
+STR_CLONE_SHIP_INFO :{BLACK}Ide kattintva egy hajó másolatát készítheted el. Control+kattintás esetén a menetrendet is megoszthatod
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}Ide kattintva egy vonat másolatát készítheted el. Kattints ide majd a másolandó vonatra. Control+kattintás esetén a menetrendet is megoszthatod
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}A dokkban kellene állnia ehhez
+STR_980C_CAN_T_SELL_SHIP :{WHITE}Nem adhatod el a hajót...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Nem veheted meg a hajót...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Hajó van az útban
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} adatai
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}Kor: {LTBLUE}{STRING}{BLACK} Működtetési költség: {LTBLUE}{CURRENCY}/év
+STR_9813_MAX_SPEED :{BLACK}Végsebesség: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Idei haszon: {LTBLUE}{CURRENCY} (tavalyi: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}Megbízhatóság: {LTBLUE}{COMMA}% {BLACK}Lerobbanások az utolsó javítás óta: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Vásárlás éve: {LTBLUE}{NUM}{BLACK} Érték: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}Kapacitás: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}Nem indíthatod el/ állíthatod meg a hajót...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Nem küldheted a hajót a dokkba...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Nem találom a helyi dokkot
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}Úton {TOWN} dokkjába
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}Úton {TOWN} dokkjába, {VELOCITY}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE :{LTBLUE}Javítás {TOWN} hajódepójában
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE_VEL :{LTBLUE}Javítás {TOWN} hajódepójában, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}{COMMA}. hajó a dokkban várakozik
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Kikötő építése
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Dokk építése (hajók vételére és karbantartására)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Hajók - kattints egy hajóra az adataihoz
+STR_9820_BUILD_NEW_SHIP :{BLACK}Új hajó vásárlása
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Dobj ide egy hajót az eladásához
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}A fő nézetet a dokkra állítja
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Hajók - kattints egy hajóra az adataihoz
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Új hajók vásárlása (dokk szükséges hozzá)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}Hajó kiválasztása - kattints egy hajóra az adataihoz
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}A kijelölt hajó megvétele
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Aktuális hajóesemény - kattints ide a hajó elindításhoz/megállításhoz
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}A hajó menetrendjének megmutatása
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}A fő nézetet a hajóra állítja
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Dokkba küldi a hajót
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}A hajó adatai
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}Új hajó használható!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Ãr: {CURRENCY} Végsebesség: {VELOCITY}{}Kapacitás: {CARGO}{}Működtetési költség: {CURRENCY}/év
+STR_982F_NAME_SHIP :{BLACK}Hajó átnevezése
+
+STR_9831_NAME_SHIP :{WHITE}Hajó átnevezése
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Nem nevezheted át a hajót...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Az emberek ünnepelnek . . .{}Megérkezett az első hajó {STATION} állomásra!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Bója lerakása, ami az útvonal pontosítására használható
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Nem rakhatsz ide bóját...
+STR_9836_RENAME :{BLACK}Ãtnevez
+STR_9837_RENAME_SHIP_TYPE :{BLACK}A hajó márkanevének megváltoztatása
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Márkanév megváltoztatása
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Nem változtathatod meg a márkanevet...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}A hajó átalakítása másfajta rakomány szállítására
+STR_983B_REFIT :{WHITE}{VEHICLE} átalakítása
+STR_983C_REFIT_SHIP :{BLACK}Hajó átalakítása
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Válaszd ki, milyen árut szállítson a hajó
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}A hajó átalakítása a kijelölt áru szállítására
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Ãtalakítás, hogy szállíthasson:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Új kapacitás: {GOLD}{CARGO}{}{BLACK}Ãtalakítás költsége: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Nem alakíthatod át a hajót...
+STR_9842_REFITTABLE :(átalakítható)
+STR_GO_TO_SHIP_DEPOT :Menj a {TOWN}i kikötőbe
+SERVICE_AT_SHIP_DEPOT :Javítás a(z) {TOWN} hajókikötőben
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Repterek
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Nem építhetsz ide repülőteret...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} hangárja
+STR_A003_NEW_AIRCRAFT :{BLACK}Új repülőgépek
+STR_CLONE_AIRCRAFT :{BLACK}Repülőgép másolása
+STR_CLONE_AIRCRAFT_INFO :{BLACK}Ezzel a repülőgép másolatát készítheted el. Control+kattintás esetén a menetrendet is megoszthatod.
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Ide kattintva egy repülőgép másolatát készítheted el. Kattints ide majd a másolandó repülőgépre. Control+kattintás esetén a menetrendet is megoszthatod.
+STR_A005_NEW_AIRCRAFT :{WHITE}Új repülőgépek
+STR_A006_BUILD_AIRCRAFT :{BLACK}Megvesz
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Nem veheted meg a repülőgépet...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} repülőgépei - {COMMA}
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} menetrendje
+STR_A00C_DETAILS :{WHITE}{VEHICLE} adatai
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Kor: {LTBLUE}{STRING}{BLACK} Működtetési költség: {LTBLUE}{CURRENCY}/év
+STR_A00E_MAX_SPEED :{BLACK}Végsebesség: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Idei haszon: {LTBLUE}{CURRENCY} (tavalyi: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}Megbízhatóság: {LTBLUE}{COMMA}% {BLACK}Lerobbanások az utolsó javítás óta: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Vásárlás éve: {LTBLUE}{NUM}{BLACK} Érték: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Nem küldheted a repülőgépet a hangárba...
+STR_HEADING_FOR_HANGAR :{ORANGE}Úton {STATION} hangárjába
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}Úton {STATION} hangárjába, {VELOCITY}
+STR_HEADING_FOR_HANGAR_SERVICE :{LTBLUE}Javítás {STATION} hangárjában
+STR_HEADING_FOR_HANGAR_SERVICE_VEL :{LTBLUE}Javítás {STATION} hangárjában, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}{COMMA}. repülőgép a hangárban várakozik
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Repülőgép van az útban
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Nem indíthatod el/ állíthatod meg a repülőgépet...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}... a levegőben van
+STR_A019_CAPACITY :{BLACK}Kapacitás: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Kapacitás: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}A hangárban kellene állnia ehhez
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Nem adhatod el a repülőgépet...
+STR_A01D_AIRPORT_CONSTRUCTION :Repülőtér építése
+STR_A01E_BUILD_AIRPORT :{BLACK}Repülőtér építése
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Repülőgépek - kattints egy repülőgépre az adataihoz
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Új repülőgépek vásárlása (hangár szükséges hozzá)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Repülőgépek - kattints egy repülőgépre az adataihoz
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Új repülőgépek vásárlása
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}Dobj ide egy repülőgépet az eladásához
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}A fő nézetet a hangárra állítja
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Repülőgép kiválasztása - kattints egy repülőgépre az adataihoz
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}A kijelölt repülőgép megvétele
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Aktuális repülőgépesemény - kattints ide a repülőgép elindításához/megállításához
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}A repülőgép menetrendjének megmutatása
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}A fő nézetet a repülőgépre állítja
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Hangárba küldi a repülőgépet
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}A repülőgép adatai
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}Új repülőgép használható!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Ãr: {CURRENCY} Végsebesség: {VELOCITY}{}Kapacitás: {COMMA} utas, {COMMA} csomag levél{}Működtetési költség: {CURRENCY}/év
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Repülőgép átnevezése
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Nem nevezheted át a repülőgépet...
+STR_A032_NAME_AIRCRAFT :{BLACK}Repülőgép átnevezése
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Az emberek ünnepelnek . . .{}Megérkezett az első repülőgép {STATION} állomásra!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Lezuhant egy repülőgép!{}{COMMA} ember halt meg a zuhanás után {STATION} állomáson
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Repülő baleset!{}A repülőnek elfogyott az üzemanyaga, {COMMA} ember halt meg a zuhanásban!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Ãtnevez
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}A repülőgép márkanevének megváltoztatása
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Márkanév megváltoztatása
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Nem változtathatod meg a márkanevet...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}A repülőgép átalakítása másfajta rakomány szállítására
+STR_A03C_REFIT :{WHITE}{VEHICLE} átalakítása
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Repülőgép átalakítása
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Válaszd ki, milyen árut szállítson a repülőgép
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}A repülőgép átalakítása a kijelölt áru szállítására
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Ãtalakítás, hogy szállíthasson:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Új kapacitás: {GOLD}{STRING}{}{BLACK}Ãtalakítás költsége: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Nem alakíthatod át a repülőgépet...
+STR_GO_TO_AIRPORT_HANGAR :Menj a {STATION} repülőtér hangárjába
+SERVICE_AT_AIRPORT_HANGAR :Javítás a(z) {STATION} hangárban
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}Zeppelinbaleset {STATION} közelében!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}'UFO' ütközés pusztított el egy közúti járművet!
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}Olajfinomító robbant fel {TOWN} közelében!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}Gyanús körülmények között felrobbant egy gyár {TOWN} közelében!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}'UFO' szállt le {TOWN} közelében!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}Egy szénbánya lesüllyedése földcsuszamlást okozott {TOWN} közelében!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Ãradás!{}Legalább {COMMA} ember meghalt vagy eltünt a halálos áradás következtében!
+
+STR_BRIBE_FAILED :{WHITE}A megvesztegetési kísérleted
+STR_BRIBE_FAILED_2 :{WHITE}lefülelte egy helyi nyomozó!
+STR_BUILD_DATE :{BLACK}Építve: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Teljesítményértékelések részletezése
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}Részletek
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Járművek:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Ãllomások:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Min. profit:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Min. bevétel:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Max. bevétel:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Elszállítás:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Rakomány:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Pénz:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Kölcsön:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Összesen:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Járművek száma. Beleértendőek a közúti járművek, a vonatok, hajók és repülők.
+STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}Ãllomásrészek száma. Minden rész számít (pl. vasútállomás, buszmegálló, repülÅ‘tér), még akkor is, ha egy állomáshoz tartoznak is.
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}A két évesnél idősebb vonatok minimális profitja
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Az utóbbi 12 negyedév legalacsonyabb havi profitja
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Az utóbbi 12 negyedév legjövedelmezőbb havi profitja
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}Utolsó négy negyedévben elszállított rakomány.
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}Az utolsó negyedévben elszállított árúk típusa.
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Elérhető készpénz
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}Magas kölcsönöd van?
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Megszerzett pontok az elérhető pontokból
+
+STR_NEWGRF_SETTINGS_BUTTON :{BLACK}NewGRF beállítások
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}Newgrf beállítások
+STR_NEWGRF_APPLY_CHANGES :{BLACK}Alkalmazás
+STR_NEWGRF_SET_PARAMETERS :{BLACK}Paraméterek beállítása
+STR_NEWGRF_TIP :{BLACK}Az általad felinstallált newgrf csomagok listája. Kattints a csomagra a beállítások módosításához.
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}Jelenleg nincsennek newgrf csomagok felinstallálva. Olvasd el a manuálban, hogyan kell installálni az új grafikákat.
+STR_NEWGRF_FILENAME :{BLACK}Fájlnév: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
+STR_NEWGRF_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING}
+STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}Te éppen a jelenleg futó játékot akarod megváltoztatni; ettől elszállhat az OpenTTD.{}Teljesen biztos vagy benne, hogy ezt akarod?
+
+STR_NEWGRF_ADD :{BLACK}Hozzáad
+STR_NEWGRF_ADD_TIP :{BLACK}A NewGRF-et hozzáadja a listához
+STR_NEWGRF_REMOVE :{BLACK}Eltávolít
+STR_NEWGRF_REMOVE_TIP :{BLACK}Eltávolítja a kiválasztott NewGRF-et a listáról
+STR_NEWGRF_MOVEUP :{BLACK}Fel
+STR_NEWGRF_MOVEUP_TIP :{BLACK}A kiválasztott NewGRF-et felfelé mozgatja a listán
+STR_NEWGRF_MOVEDOWN :{BLACK}Le
+STR_NEWGRF_MOVEDOWN_TIP :{BLACK}A kiválasztott NewGRF-et lefelé mozgatja a listán
+STR_NEWGRF_FILE_TIP :{BLACK}A feltelepített NewGRF-ek listája. Kattints a fileokra azok beállításához
+STR_NEWGRF_PARAMETER :{BLACK}Paraméterek: {SILVER}{STRING}
+STR_NEWGRF_PARAMETER_QUERY :{BLACK}Add meg a NewGRF paramétereket
+STR_NEWGRF_NO_INFO :{BLACK}Nem érhető el információ
+
+STR_NEWGRF_ADD_CAPTION :{WHITE}Elérhető NewGRF fileok
+STR_NEWGRF_ADD_FILE :{BLACK}Kiválasztáshoz hozzáad
+STR_NEWGRF_ADD_FILE_TIP :{BLACK}A kiválasztott NewGRF filet hozzáadja a konfigurációdhoz
+STR_NEWGRF_RESCAN_FILES :{BLACK}Fileok újraellenőrzése
+STR_NEWGRF_RESCAN_FILES_TIP :{BLACK}Az elérhető NewGRF fileok listájának frissítése
+STR_NEWGRF_DUPLICATE_GRFID :{WHITE}Nem lehetséges a file hozzáadása: duplikált GRF azonosító
+
+STR_NEWGRF_NOT_FOUND :{RED}File nem található
+STR_NEWGRF_DISABLED :{RED}Kikapcsolva
+
+STR_CURRENCY_WINDOW :{WHITE}Saját pénznem
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Értékarány: {ORANGE}{CURRENCY} = £ {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Elválasztó:
+STR_CURRENCY_PREFIX :{LTBLUE}Előtag:
+STR_CURRENCY_SUFFIX :{LTBLUE}Előtag:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Euróra váltás: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Euróra váltás: {ORANGE}soha
+STR_CURRENCY_PREVIEW :{LTBLUE}Előnézet: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}A saját pénznem paramétereinek megváltoztatása
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} Vonatok
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} Közúti járművek
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} Repülőgépek
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} Hajók
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Kilistázza az összes vonatot, aminek a menetrendjében szerepel ez az állomás
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Kilistázza az összes közúti járművet, aminek a menetrendjében szerepel ez az állomás
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Kilistázza az összes repülőt, aminek a menetrendjében szerepel ez az állomás
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Kilistázza az összes hajót, aminek a menetrendjében szerepel ez az állomás
+
+STR_VEH_WITH_SHARED_ORDERS_LIST :{WHITE}{COMMA} jármű megosztott menetrendje
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}Megmutatja az összes járművet, aminek ugyanaz a menetrendje
+
+### depot strings
+STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Biztosan eladod a depóban lévő összes járművet?
+
+STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP :{BLACK}Összes depóbeli vonat eladása
+STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP :{BLACK}Összes depóbeli jármű eladása
+STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP :{BLACK}Összes dokkbeli hajó eladása
+STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP :{BLACK}Összes hangárbéli repülő eladása
+
+STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP :{BLACK}Az összes, ezen depotot menetrendszerüen látogató vonat listájának összeállítása
+STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP :{BLACK}Az összes, ezen hangárt menetrendszerüen látogató jármű listájának összeállítása
+STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP :{BLACK}Az összes, ezen dokkot menetrendszerüen látogató hajó listájának összeállítása
+STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP :{BLACK}Az összes, itteni hangárt menetrendszerüen látogató repülőgép listájának összeállítása
+
+STR_DEPOT_AUTOREPLACE_TRAIN_TIP :{BLACK}A depóban lévő összes vonat automatikus cseréje
+STR_DEPOT_AUTOREPLACE_ROADVEH_TIP :{BLACK}A depóben lévő összes jármű automatikus cseréje
+STR_DEPOT_AUTOREPLACE_SHIP_TIP :{BLACK}A dokkban lévő összes hajó automatikus cseréje
+STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP :{BLACK}A hangárban lévő összes repülő automatikus cseréje
+
+STR_VEHICLE_LIST_TRAIN_DEPOT :{BLACK}{STRING} - {COMMA} vonat
+STR_VEHICLE_LIST_ROADVEH_DEPOT :{BLACK}{STRING} - {COMMA} közúti jármű
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} hajó
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} repülőgép
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}Lecserél {STRING}
+STR_REPLACE_VEHICLES_START :{BLACK}Járműcsere elkezdése
+STR_REPLACE_VEHICLES_STOP :{BLACK}Járműcsere befejezése
+STR_NOT_REPLACING :{BLACK}Nem cserélendő
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Nincs kiválasztva jármű
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Válaszd ki mely mozdonyokat cseréljük
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}A bal oldalon kiválasztott mozdonyok ilyen típusuakra lesznek lecserélve
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Nyomd meg ezt a gombot, ha nem akarod kicserélni a mozdonyt a bal oldalon kiválasztottakra
+STR_REPLACE_HELP_START_BUTTON :{BLACK}Nyomd meg ezt a gombot hogy a bal oldalon kiválasztott mozdonyokat lecseréld a jobb oldalon kiválasztottra
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Válaszd ki a cserélendő vasúttípust
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Megmutatja, hogy melyik bal oldali mozdonyt akarod kicserélni
+STR_REPLACE_HELP :{BLACK}Ez az opció lehetőve teszi, hogy kiválassz mozdonytípust és lecseréld másfajtára. Ez aztán automatikusan fog megtörténni, amikor a jármű karbantartásra a depóba megy
+STR_REPLACE_REMOVE_WAGON :{BLACK}Vagon törlés: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Az automatikus cserénél a szerelvény hosszának a megtartása kocsik lekapcsolásával (előröl kezdve), ha a csere után a mozdony hosszabb lenne.
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}Lecserél: {ORANGE}{SKIP}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} KISÉRLETI TULAJDONSÃG {}Váltás a mozdony és a vasúti-kocsi cserélÅ‘ ablak között.{}A vagonok cseréje csak akkor történik meg, ha az új vagon átalakítható ugyanolyan típusú teher szállítására. Ez minden vagoncserénél ellenÅ‘rzÅ‘dik.
+STR_ENGINE_NOT_BUILDABLE :{WHITE}A mozdony így nem építhető meg
+
+STR_ENGINES :Mozdonyok
+STR_WAGONS :Vagonok
+
+STR_MASS_STOP_DEPOT_TRAIN_TIP :{BLACK}Kattints ide az összes depóbeli vonat leállításához
+STR_MASS_STOP_DEPOT_ROADVEH_TIP :{BLACK}Kattints ide az összes depóbeli közúti jármű leállításához
+STR_MASS_STOP_DEPOT_SHIP_TIP :{BLACK}Kattints ide az összes dokkbeli hajó leállításához
+STR_MASS_STOP_HANGAR_TIP :{BLACK}Kattints ide az összes hangárbeli repülő leállításához
+
+STR_MASS_START_DEPOT_TRAIN_TIP :{BLACK}Kattints ide az összes depóbeli vonat elindításához
+STR_MASS_START_DEPOT_ROADVEH_TIP :{BLACK}Kattints ide az összes depóbeli közúti jármű elindításához
+STR_MASS_START_DEPOT_SHIP_TIP :{BLACK}Kattints ide az összes dokkbeli hajó elindításához
+STR_MASS_START_HANGAR_TIP :{BLACK}Kattints ide az összes hangárbeli repülő elindításához
+
+STR_MASS_STOP_LIST_TIP :{BLACK}Kattints ide a listán lévő összes jármű leállításához
+STR_MASS_START_LIST_TIP :{BLACK}Kattints ide a listán lévő összes jármű elindításához
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}Feliratok listája ({COMMA} db)
+
+STR_ORDER_REFIT_FAILED :{WHITE}Ãtalakítási hiba miatt megállt: {STRING} {COMMA}
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :Normál Vasutak
+STR_ELRAIL_VEHICLES :Elektromos-vasúti járművek
+STR_MONORAIL_VEHICLES :Egysínű Vasutak
+STR_MAGLEV_VEHICLES :Maglev Vasutak
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Ãr: {GOLD}{CURRENCY}{BLACK} Súly: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Sebesség: {GOLD}{VELOCITY}{BLACK} Telj.: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}Sebesség: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Üzemeltetés: {GOLD}{CURRENCY}/év
+STR_PURCHASE_INFO_CAPACITY :{BLACK}Kapacitás: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Kifejlesztve: {GOLD}{NUM}{BLACK} Élettartam: {GOLD}{COMMA} év
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}Max. üzemképesség: {GOLD}{COMMA}%
+STR_PURCHASE_INFO_COST :{BLACK}Ãr: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Súly: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Ãr: {GOLD}{CURRENCY}{BLACK} Sebesség: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Kapacitás: {GOLD}{COMMA} utas, {COMMA} csomag levél
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Meghajtott vagonok: {GOLD}+{POWER}{BLACK} Súly: {GOLD}+{WEIGHT_S}
+STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Ãtalakítható: {GOLD}
+STR_PURCHASE_INFO_ALL_TYPES :Minden szállítmány típusra
+STR_PURCHASE_INFO_ALL_BUT :Mindenre, kivéve {GOLD}
+STR_PURCHASE_INFO_MAX_TE :{BLACK}Maximális húzó erő: {GOLD}{FORCE}
+
+########### String for New Landscape Generator
+
+STR_GENERATE :{WHITE}Generál
+STR_RANDOM :{BLACK}Véletlenszerűen
+STR_RANDOM_HELP :{BLACK}Megváltoztatja a térképgenerálásnál használt véletlen alapszámot
+STR_WORLD_GENERATION_CAPTION :{WHITE}Térkép létrehozása
+STR_RANDOM_SEED :{BLACK}Véletlen alapszám:
+STR_RANDOM_SEED_HELP :{BLACK}Kattints ide a véletlen alapszám beírásához
+STR_LAND_GENERATOR :{BLACK}Térkép generátor:
+STR_TREE_PLACER :{BLACK}Fa algoritmus:
+STR_HEIGHTMAP_ROTATION :{BLACK}Magasságtérkép elforgatása:
+STR_TERRAIN_TYPE :{BLACK}Tereptípus:
+STR_QUANTITY_OF_SEA_LAKES :{BLACK}Tengerszint:
+STR_SMOOTHNESS :{BLACK}Simaság:
+STR_SNOW_LINE_HEIGHT :{BLACK}Hóhatár:
+STR_DATE :{BLACK}Dátum:
+STR_NUMBER_OF_TOWNS :{BLACK}Várossűrűség:
+STR_NUMBER_OF_INDUSTRIES :{BLACK}Iparsűrűség:
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_SNOW_LINE_UP :{BLACK}A hóhatár eggyel megnövelése
+STR_SNOW_LINE_DOWN :{BLACK}A hóhatár eggyel csökkentése
+STR_SNOW_LINE_QUERY_CAPT :{WHITE}Hóhatár megváltoztatása
+STR_START_DATE_QUERY_CAPT :{WHITE}Kezdő év megváltoztatása
+STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Ãtméretezési figyelmeztetés
+STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}A forrás térkép túlságosan nagy mértékű átméretezése nem javasolt. Folytatod mégis?
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_HEIGHTMAP_NAME :{BLACK}Magasságtérkép neve:
+STR_HEIGHTMAP_SIZE :{BLACK}Méret: {ORANGE}{NUM} x {NUM}
+STR_GENERATION_WORLD :{WHITE}Térkép létrehozása...
+STR_GENERATION_ABORT :{BLACK}Félbeszakít
+STR_GENERATION_ABORT_CAPTION :{WHITE}Megszakítja a térkép létrehozását
+STR_GENERATION_ABORT_MESSAGE :{YELLOW}Tényleg meg akarod szakítani a térkép generálását?
+STR_PROGRESS :{WHITE}{NUM}% kész
+STR_GENERATION_PROGRESS :{BLACK}{NUM} / {NUM}
+STR_WORLD_GENERATION :{BLACK}Térkép létrehozása
+STR_TREE_GENERATION :{BLACK}Fák generálás
+STR_UNMOVABLE_GENERATION :{BLACK}Világítótornyok létrehozása
+STR_CLEARING_TILES :{BLACK}Durva és köves területek generálása
+STR_SETTINGUP_GAME :{BLACK}Játék beállítása
+STR_PREPARING_TILELOOP :{BLACK}Mezők véglegesítése
+STR_PREPARING_GAME :{BLACK}Játék előkészítése
+STR_DIFFICULTY_TO_CUSTOM :{WHITE}Ez a módosítás megváltoztatta a nehézségi szintet egyedire.
+STR_SE_FLAT_WORLD :{WHITE}Lapos térkép
+STR_SE_FLAT_WORLD_TIP :{BLACK}Lapos térképet generál
+STR_SE_RANDOM_LAND :{WHITE}Véletlen térkép
+STR_SE_NEW_WORLD :{BLACK}Új küldetés létrehozása
+STR_SE_CAPTION :{WHITE}Küldetés típusa
+STR_FLAT_WORLD_HEIGHT_DOWN :{BLACK}Csökkenti eggyel a sima terep magasságát
+STR_FLAT_WORLD_HEIGHT_UP :{BLACK}Növeli eggyel a sima terep magasságát
+STR_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Sima terem magasságát változtatja
+STR_FLAT_WORLD_HEIGHT :{BLACK}Sima terep magassága:
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+STR_SMALLMAP_CENTER :{BLACK}A kistérkép közepét a jelenlegi helyre állítja
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}Kicsi
+STR_CITY_AIRPORT :{BLACK}Városi
+STR_METRO_AIRPORT :{BLACK}Nagyvárosi reptér
+STR_INTERNATIONAL_AIRPORT :{BLACK}Nemzetközi reptér
+STR_COMMUTER_AIRPORT :{BLACK}Bejáró
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Interkontinentális
+STR_HELIPORT :{BLACK}Helileszálló
+STR_HELIDEPOT :{BLACK}Helidepó
+STR_HELISTATION :{BLACK}Heliállomás
+
+STR_SMALL_AIRPORTS :{BLACK}Kis repterek
+STR_LARGE_AIRPORTS :{BLACK}Nagy repterek
+STR_HUB_AIRPORTS :{BLACK}Hub repterek
+STR_HELIPORTS :{BLACK}Helikopter repterek
+
+############ Tooltip measurment
+
+STR_MEASURE_LENGTH :{BLACK}Távolság: {NUM}
+STR_MEASURE_AREA :{BLACK}Terület: {NUM} x {NUM}
+STR_MEASURE_LENGTH_HEIGHTDIFF :{BLACK}Távolság: {NUM}{}Magasságkülönbség: {NUM} m
+STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}Terület: {NUM} x {NUM}{}Magasságkülönbség: {NUM} m
+
+########
diff --git a/src/lang/icelandic.txt b/src/lang/icelandic.txt
new file mode 100644
index 000000000..a44f198d6
--- /dev/null
+++ b/src/lang/icelandic.txt
@@ -0,0 +1,2900 @@
+##name Icelandic
+##ownname Ãslenska
+##isocode is_IS.UTF-8
+##plural 0
+##gender karlkyn kvenkyn hvorugkyn
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Brún kortsins
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Of nálægt brún kortsins
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Ekki nógu mikið reiðufé - þarf {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Sléttlendi nauðsynlegt
+STR_0008_WAITING :{BLACK}Bíður: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (á leið frá
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Tekur við: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Tekur við: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :Farþegar
+STR_0010_COAL :Kol
+STR_0011_MAIL :Póstur
+STR_0012_OIL :Olía
+STR_0013_LIVESTOCK :Búfé
+STR_0014_GOODS :Vörur
+STR_0015_GRAIN :Korn
+STR_0016_WOOD :Timbur
+STR_0017_IRON_ORE :Járngrýti
+STR_0018_STEEL :Stál
+STR_0019_VALUABLES :Verðmæti
+STR_001A_COPPER_ORE :Kopar
+STR_001B_MAIZE :Maís
+STR_001C_FRUIT :Ãvextir
+STR_001D_DIAMONDS :Demantar
+STR_001E_FOOD :Matvæli
+STR_001F_PAPER :Pappír
+STR_0020_GOLD :Gull
+STR_0021_WATER :Vatn
+STR_0022_WHEAT :Hveiti
+STR_0023_RUBBER :Gúmmí
+STR_0024_SUGAR :Sykur
+STR_0025_TOYS :Leikföng
+STR_0026_CANDY :Sælgæti
+STR_0027_COLA :Kóladrykkir
+STR_0028_COTTON_CANDY :Sykurfrauð
+STR_0029_BUBBLES :Kúlur
+STR_002A_TOFFEE :Toffý
+STR_002B_BATTERIES :Rafhlöður
+STR_002C_PLASTIC :Plast
+STR_002D_FIZZY_DRINKS :Gosdrykkir
+STR_002E :
+STR_002F_PASSENGER :Farþega
+STR_0030_COAL :Kola
+STR_0031_MAIL :Póst
+STR_0032_OIL :Olíu
+STR_0033_LIVESTOCK :Búfé
+STR_0034_GOODS :Vöru
+STR_0035_GRAIN :Korn
+STR_0036_WOOD :Timbur
+STR_0037_IRON_ORE :Járngrýtis
+STR_0038_STEEL :Stál
+STR_0039_VALUABLES :Verðmæta
+STR_003A_COPPER_ORE :Kopargrýtis
+STR_003B_MAIZE :Maís
+STR_003C_FRUIT :Ãvaxta
+STR_003D_DIAMOND :Demanta
+STR_003E_FOOD :Matvæla
+STR_003F_PAPER :Pappírs
+STR_0040_GOLD :Gull
+STR_0041_WATER :Vatns
+STR_0042_WHEAT :Hveitis
+STR_0043_RUBBER :Gúmmí
+STR_0044_SUGAR :Sykur
+STR_0045_TOY :Leikfanga
+STR_0046_CANDY :Sælgætis
+STR_0047_COLA :Kóladrykkja
+STR_0048_COTTON_CANDY :Sykurfrauðs
+STR_0049_BUBBLE :Kúlu
+STR_004A_TOFFEE :Toffý
+STR_004B_BATTERY :Rafhlöðu
+STR_004C_PLASTIC :Plast
+STR_004D_FIZZY_DRINK :Gosdrykkja
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} farþeg{P i ar}
+STR_QUANTITY_COAL :{WEIGHT} af kolum
+STR_QUANTITY_MAIL :{COMMA} pokar af pósti
+STR_QUANTITY_OIL :{VOLUME} af olíu
+STR_QUANTITY_LIVESTOCK :{COMMA} grip{P u i}r
+STR_QUANTITY_GOODS :{COMMA} kass{P i ar} af vörum
+STR_QUANTITY_GRAIN :{WEIGHT} af korni
+STR_QUANTITY_WOOD :{WEIGHT} af timbri
+STR_QUANTITY_IRON_ORE :{WEIGHT} af járngrýti
+STR_QUANTITY_STEEL :{WEIGHT} af stáli
+STR_QUANTITY_VALUABLES :{COMMA} pok{P i ar} af verðmætum
+STR_QUANTITY_COPPER_ORE :{WEIGHT} af kopar
+STR_QUANTITY_MAIZE :{WEIGHT} af maís
+STR_QUANTITY_FRUIT :{WEIGHT} af ávöxtum
+STR_QUANTITY_DIAMONDS :{COMMA} pok{P i ar} af demöntum
+STR_QUANTITY_FOOD :{WEIGHT} af matvælum
+STR_QUANTITY_PAPER :{WEIGHT} af pappír
+STR_QUANTITY_GOLD :{COMMA} pok{P i ar} af gulli
+STR_QUANTITY_WATER :{VOLUME} af vatni
+STR_QUANTITY_WHEAT :{WEIGHT} af hveiti
+STR_QUANTITY_RUBBER :{VOLUME} af gúmmíi
+STR_QUANTITY_SUGAR :{WEIGHT} af sykri
+STR_QUANTITY_TOYS :{COMMA} leikf{P a ö}ng
+STR_QUANTITY_SWEETS :{COMMA} pok{P i ar} af sælgæti
+STR_QUANTITY_COLA :{VOLUME} af kóladrykk
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} af sykurfrauði
+STR_QUANTITY_BUBBLES :{COMMA} kúl{P a ur}
+STR_QUANTITY_TOFFEE :{WEIGHT} af toffý
+STR_QUANTITY_BATTERIES :{COMMA} rafhl{P aða öður}
+STR_QUANTITY_PLASTIC :{VOLUME} af plasti
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} gosdrykk{P u i}r
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}PS
+STR_ABBREV_COAL :{TINYFONT}CL
+STR_ABBREV_MAIL :{TINYFONT}ML
+STR_ABBREV_OIL :{TINYFONT}OL
+STR_ABBREV_LIVESTOCK :{TINYFONT}LV
+STR_ABBREV_GOODS :{TINYFONT}GD
+STR_ABBREV_GRAIN :{TINYFONT}GR
+STR_ABBREV_WOOD :{TINYFONT}WD
+STR_ABBREV_IRON_ORE :{TINYFONT}OR
+STR_ABBREV_STEEL :{TINYFONT}ST
+STR_ABBREV_VALUABLES :{TINYFONT}VL
+STR_ABBREV_COPPER_ORE :{TINYFONT}CO
+STR_ABBREV_MAIZE :{TINYFONT}MZ
+STR_ABBREV_FRUIT :{TINYFONT}FT
+STR_ABBREV_DIAMONDS :{TINYFONT}DM
+STR_ABBREV_FOOD :{TINYFONT}FD
+STR_ABBREV_PAPER :{TINYFONT}PR
+STR_ABBREV_GOLD :{TINYFONT}GD
+STR_ABBREV_WATER :{TINYFONT}WR
+STR_ABBREV_WHEAT :{TINYFONT}WH
+STR_ABBREV_RUBBER :{TINYFONT}RB
+STR_ABBREV_SUGAR :{TINYFONT}SG
+STR_ABBREV_TOYS :{TINYFONT}TY
+STR_ABBREV_SWEETS :{TINYFONT}SW
+STR_ABBREV_COLA :{TINYFONT}CL
+STR_ABBREV_CANDYFLOSS :{TINYFONT}CF
+STR_ABBREV_BUBBLES :{TINYFONT}BU
+STR_ABBREV_TOFFEE :{TINYFONT}TF
+STR_ABBREV_BATTERIES :{TINYFONT}BA
+STR_ABBREV_PLASTIC :{TINYFONT}PL
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}FZ
+STR_ABBREV_NONE :{TINYFONT}EKKERT
+STR_ABBREV_ALL :{TINYFONT}ALLT
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Kort - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Stillingar
+STR_00B2_MESSAGE :{YELLOW}Skilaboð
+STR_00B3_MESSAGE_FROM :{YELLOW}Skilaboð frá {STRING}
+STR_00B4_CAN_T_DO_THIS :{WHITE}Get ekki gert þetta....
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Get ekki hreinsað þetta svæði....
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Upphaflegur höfundarréttur {COPYRIGHT} 1995 Chris Sawyer, Öll réttindi áskilin
+STR_00B7_VERSION :{BLACK}OpenTTD útgáfa {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 OpenTTD hópurinn
+STR_TRANSLATED_BY :{BLACK} Þýðendur -
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Hætta
+STR_00C8_YES :{BLACK}Já
+STR_00C9_NO :{BLACK}Nei
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Ertu viss um að þú viljir hætta í OpenTTD og fara aftur í {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Ekkert
+STR_00D1_DARK_BLUE :Dökkblár
+STR_00D2_PALE_GREEN :Fölgrænn
+STR_00D3_PINK :Bleikur
+STR_00D4_YELLOW :Gulur
+STR_00D5_RED :Rauður
+STR_00D6_LIGHT_BLUE :Ljósblár
+STR_00D7_GREEN :Grænn
+STR_00D8_DARK_GREEN :Dökkgrænn
+STR_00D9_BLUE :Blár
+STR_00DA_CREAM :Andlitslitur
+STR_00DB_MAUVE :Silfur
+STR_00DC_PURPLE :Fjólublár
+STR_00DD_ORANGE :Appelsínugulur
+STR_00DE_BROWN :Brúnn
+STR_00DF_GREY :Grár
+STR_00E0_WHITE :Hvítur
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Of mörg farartæki í leiknum
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Staður
+STR_00E5_CONTOURS :Útlínur
+STR_00E6_VEHICLES :Farartæki
+STR_00E7_INDUSTRIES :Iðnaðir
+STR_00E8_ROUTES :Leiðir
+STR_00E9_VEGETATION :Uppskera
+STR_00EA_OWNERS :Eigendur
+STR_00EB_ROADS :{BLACK}{TINYFONT}Vegir
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Járnbrautir
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Stöðvar/Flugvellir/Hafnir
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Byggingar/Iðnaðir
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Farartæki
+STR_00F0_100M :{BLACK}{TINYFONT}100m
+STR_00F1_200M :{BLACK}{TINYFONT}200m
+STR_00F2_300M :{BLACK}{TINYFONT}300m
+STR_00F3_400M :{BLACK}{TINYFONT}400m
+STR_00F4_500M :{BLACK}{TINYFONT}500m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Lestar
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Bifreiðir
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Skip
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Flugvélar
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Flutningarleiðir
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Kolanáma
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Rafmagnsstöð
+STR_00FC_FOREST :{BLACK}{TINYFONT}Skógur
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}Timburverksmiðja
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Olíuhreinsunarstöð
+STR_00FF_FARM :{BLACK}{TINYFONT}Býli
+STR_0100_FACTORY :{BLACK}{TINYFONT}Verksmiðja
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Prentsmiðja
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Olíulindir
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Járnnáma
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Stálbræðsla
+STR_0105_BANK :{BLACK}{TINYFONT}Banki
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Pappírsverksmiðja
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Gullnáma
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Matvinnslufyrirtæki
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Demantanáma
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Koparnáma
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Ãvaxtaplantekra
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Gúmmíplantekra
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Vatnsbirgi
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Vatnsturn
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}Timburverksmiðja
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Sykurfrauðsskógur
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Sælgætisverksmiðja
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Rafhlöðubýli
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Kólalindir
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Leikfangabúð
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Leikfangaverksmiðja
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Plastbrunnir
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Gosdrykkjaverksmiðja
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Kúluframkallari
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Toffýæð
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Sykurnáma
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Lestarstöð
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Vörubílastöð
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Strætóstoppistöð
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Flugvöllur/Þyrlupallur
+STR_011F_DOCK :{BLACK}{TINYFONT}Bryggja
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Hrjúft land
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Graslendi
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Bert land
+STR_0123_FIELDS :{BLACK}{TINYFONT}Akrir
+STR_0124_TREES :{BLACK}{TINYFONT}Tré
+STR_0125_ROCKS :{BLACK}{TINYFONT}Klettar
+STR_0126_WATER :{BLACK}{TINYFONT}Vatn
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Enginn eigandi
+STR_0128_TOWNS :{BLACK}{TINYFONT}Bæir
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Iðnaðir
+STR_012A_DESERT :{BLACK}{TINYFONT}Eyðimörk
+STR_012B_SNOW :{BLACK}{TINYFONT}Snjór
+STR_012C_MESSAGE :{WHITE}Skilaboð
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Hætta við
+STR_012F_OK :{BLACK}Ã lagi
+STR_0130_RENAME :{BLACK}Endurnefna
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Of mörg nöfn skilgreint
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Valið nafn er þegar í notkun
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...í eigu {STRING}
+STR_013C_CARGO :{BLACK}Farmur
+STR_013D_INFORMATION :{BLACK}Upplýsingar
+STR_013E_CAPACITIES :{BLACK}Burðargeta
+STR_013E_TOTAL_CARGO :{BLACK}Heildarfarmur
+STR_013F_CAPACITY :{BLACK}Burðargeta: {LTBLUE}{CARGO}
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Farmur alls (burðargeta) þessarar lestar:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_0140_NEW_GAME :{BLACK}Nýr leikur
+STR_0141_LOAD_GAME :{BLACK}Opna leik
+STR_SINGLE_PLAYER :{BLACK}Einspilun
+STR_MULTIPLAYER :{BLACK}Fjölspilun
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Kortastærð:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Stillingar
+
+STR_0150_SOMEONE :einhver{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Heimskort
+STR_0152_TOWN_DIRECTORY :Bæjarmappa
+STR_0153_SUBSIDIES :Samstarfssamningar
+
+STR_UNITS_IMPERIAL :Amerískt kerfi
+STR_UNITS_METRIC :Metrakerfi
+STR_UNITS_SI :SI kerfi
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} mílur/klst
+STR_UNITS_VELOCITY_METRIC :{COMMA} km/klst
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}hestöfl
+STR_UNITS_POWER_METRIC :{COMMA}hestöfl
+STR_UNITS_POWER_SI :{COMMA}kW
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}tonn
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}tonn
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} tonn
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} tonn
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} kg
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}gal
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}l
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}m³
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} gallon
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} lítr{P i ar}
+STR_UNITS_VOLUME_LONG_SI :{COMMA} m³
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10³ pundkraftur
+STR_UNITS_FORCE_METRIC :{COMMA} tonnkraftur
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Línurit: Rekstrarhagnaður
+STR_0155_INCOME_GRAPH :Línurit: Tekjur
+STR_0156_DELIVERED_CARGO_GRAPH :Línurit: Fluttur farmur
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Línurit: Vísitala fyrirtækis
+STR_0158_COMPANY_VALUE_GRAPH :Línurit: Verðmæti fyrirtækis
+STR_0159_CARGO_PAYMENT_RATES :Línurit: Flutningsgróði
+STR_015A_COMPANY_LEAGUE_TABLE :Stigatafla fyrirtækja
+STR_PERFORMANCE_DETAIL_MENU :Nákvæm frammistöðumæling
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}Um OpenTTD
+STR_015C_SAVE_GAME :Vista leik
+STR_015D_LOAD_GAME :Opna leik
+STR_015E_QUIT_GAME :Hætta leik
+STR_015F_QUIT :Hætta
+STR_ABANDON_GAME_QUERY :{YELLOW}Ertu viss um að þú viljir hætta í þessum leik ?
+STR_0161_QUIT_GAME :{WHITE}Hætta leik
+STR_SORT_ORDER_TIP :{BLACK}Velja uppröðun (minnkandi/stækkandi)
+STR_SORT_CRITERIA_TIP :{BLACK}Velja uppröðun
+STR_SORT_BY :{BLACK}Flokka eftir
+
+STR_SORT_BY_POPULATION :{BLACK}Fólksfjöldi
+STR_SORT_BY_PRODUCTION :{BLACK}Framleiðsla
+STR_SORT_BY_TYPE :{BLACK}Tegund
+STR_SORT_BY_TRANSPORTED :{BLACK}Flutt
+STR_SORT_BY_NAME :{BLACK}Nafn
+STR_SORT_BY_DROPDOWN_NAME :Nafn
+STR_SORT_BY_DATE :{BLACK}Dagsetning
+STR_SORT_BY_NUMBER :Númer
+STR_SORT_BY_PROFIT_LAST_YEAR :Hagnaður síðasta árs
+STR_SORT_BY_PROFIT_THIS_YEAR :Hagnaður þessa árs
+STR_SORT_BY_AGE :Aldur
+STR_SORT_BY_RELIABILITY :Ãreiðanleiki
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Burðargeta alls á hverja tegund farms
+STR_SORT_BY_MAX_SPEED :Hámarkshraði
+STR_SORT_BY_MODEL :Týpa
+STR_SORT_BY_VALUE :Virði
+STR_SORT_BY_FACILITY :Tegund stöðvar
+STR_SORT_BY_WAITING :Verðgildi farms á stöð
+STR_SORT_BY_RATING_MAX :Flutningur farms
+STR_NO_WAITING_CARGO :{BLACK}Enginn farmur bíður
+STR_SELECT_ALL_FACILITIES :{BLACK}Velja allar gerðir
+STR_SELECT_ALL_TYPES :{BLACK}Velja allar tegundir farms (einnig þær sem ekki bíða)
+STR_REPLACE_VEHICLES :Skipta út vögnum
+
+############ range for months starts
+STR_0162_JAN :Jan
+STR_0163_FEB :Feb
+STR_0164_MAR :Mar
+STR_0165_APR :Apr
+STR_0166_MAY :Maí
+STR_0167_JUN :Jún
+STR_0168_JUL :Júl
+STR_0169_AUG :Ãgú
+STR_016A_SEP :Sep
+STR_016B_OCT :Okt
+STR_016C_NOV :Nóv
+STR_016D_DEC :Des
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Stöðva leik
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Vista leik, hætta í leik, hætta
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Sýna lista yfir stöðvar fyrirtækis
+STR_0174_DISPLAY_MAP :{BLACK}Sýna kort
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Sýna kort, bæjarmöppu
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Sýna bæjarmöppu
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Sýna fjárhagsupplýsingar fyrirtækis
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Sýna almennar upplýsingar um fyrirtæki
+STR_0179_DISPLAY_GRAPHS :{BLACK}Sýna línurit
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Sýna stigatöflu fyrirtækja
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Sýna lista yfir lestar fyrirtækis
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Sýna lista yfir götufarartæki fyrirtækis
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Sýna lista yfir skip fyrirtækis
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Sýna lista yfir flugvélar fyrirtækis
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Þrengja sýnishorn
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Víkka sýnishorn
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Leggja lestartein
+STR_0182_BUILD_ROADS :{BLACK}Leggja veg
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Byggja höfn
+STR_0184_BUILD_AIRPORTS :{BLACK}Byggja flugvöll
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Gróðursetja tré, setja skilti o.s.frv.
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Landssvæðisupplýsingar
+STR_0187_OPTIONS :{BLACK}Stillingar
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Get ekki breytt viðgerðarmillibili...
+STR_018B_CLOSE_WINDOW :{BLACK}Loka glugga
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Haus glugga - dragðu með músinni til að færa gluggann
+STR_STICKY_BUTTON :{BLACK}Merkja þennan glugga sem ólokanlegan fyrir
+STR_RESIZE_BUTTON :{BLACK}Ãttu og dragðu til að breyta stærð gluggans
+STR_SAVELOAD_HOME_BUTTON :{BLACK}Smelltu hér til að opna möppu fyrir vistaða leiki
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Eyða byggingum o.s.frv. á lóðarreiti
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Lækka horn af landssvæði
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Lyfta horni af landssvæði
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Skrunslá - færir lista upp/niður
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Rennislá - rennir lista til vinstri/hægri
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Sýna útlínur lands á korti
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Sýna farartæki á korti
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Sýna iðnaði á korti
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Sýna flutningsleiðir á korti
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Sýna uppskerur á korti
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Sýna lóðareigendur á korti
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Sýna/fela bæjarnöfn á korti
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Hagnaður þetta ár: {CURRENCY} (síðasta ár: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} ár ({COMMA})
+STR_AGE_RED :{RED}{COMMA} ár ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Bifreið
+STR_019D_AIRCRAFT :Flugvél
+STR_019E_SHIP :Skip
+STR_019F_TRAIN :Lest
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} er að eldast
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} er að eldast um of
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} er að eldast um of og þarfnast nauðsynlega endurnýjunar
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Landsvæðisupplýsingar
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Kostnaður við hreinsun: {LTBLUE}N/A
+STR_01A5_COST_TO_CLEAR :{BLACK}Kostnaður við hreinsun: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :Enginn
+STR_01A7_OWNER :{BLACK}Eigandi: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Bæjaryfirvöld: {LTBLUE}{STRING}
+STR_01A9_NONE :Enginn
+STR_01AA_NAME :{BLACK}Nafn
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1.
+STR_01AD_2ND :2.
+STR_01AE_3RD :3
+STR_01AF_4TH :4.
+STR_01B0_5TH :5.
+STR_01B1_6TH :6.
+STR_01B2_7TH :7.
+STR_01B3_8TH :8.
+STR_01B4_9TH :9.
+STR_01B5_10TH :10.
+STR_01B6_11TH :11.
+STR_01B7_12TH :12.
+STR_01B8_13TH :13.
+STR_01B9_14TH :14.
+STR_01BA_15TH :15.
+STR_01BB_16TH :16.
+STR_01BC_17TH :17.
+STR_01BD_18TH :18.
+STR_01BE_19TH :19.
+STR_01BF_20TH :20.
+STR_01C0_21ST :21.
+STR_01C1_22ND :22.
+STR_01C2_23RD :23.
+STR_01C3_24TH :24.
+STR_01C4_25TH :25.
+STR_01C5_26TH :26.
+STR_01C6_27TH :27.
+STR_01C7_28TH :28.
+STR_01C8_29TH :29.
+STR_01C9_30TH :30.
+STR_01CA_31ST :31.
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Tekið á móti: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Jazz glymskratti
+STR_01D3_SOUND_MUSIC :Hljóð/tónlist
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Sýna hljóð/tónlistar glugga
+STR_01D5_ALL :{TINYFONT}Allt
+STR_01D6_OLD_STYLE :{TINYFONT}Gamalt
+STR_01D7_NEW_STYLE :{TINYFONT}Móðins
+STR_01D8_EZY_STREET :{TINYFONT}Ezy gata
+STR_01D9_CUSTOM_1 :{TINYFONT}Sérval 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Sérval 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Tónlistarstyrkur
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Hljóðstyrkur
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}LÃG ' ' ' ' ' ' HÃM
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Skipta yfir í fyrra lag
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Skipta yfir í næsta lag
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Hætta að spila tónlist
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Byrja að spila tónlist
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Dragðu sleðana til að stilla hljóð/tónlistar styrkinn
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Lag{SETX 88}Titill
+STR_01E9_SHUFFLE :{TINYFONT}Stokka
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Listar
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Lagalistar
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Laganúmer
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Listi - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}Hreinsa
+STR_01F1_SAVE :{TINYFONT}{BLACK}Vista
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Núverandi lagalisti
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Velja 'öll lög' listann
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Velja 'gamli stíll' listann
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Velja 'nýi stíll' listann
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Velja 'Sérval 1' (valið af notanda) listann
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Velja 'Sérval 2' (valið af notanda) listann
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Hreinsa núverandi lista (aðeins Sérval1 eða Sérval2)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Vista tónlistarstillingar
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Veldu lag til að bæta í núverandi lista (aðeins Sérval1 eða Sérval2)
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Smelltu á lag til að fjarlægja það úr listanum (á aðeins við um Sérvalið1 og Sérvalið2)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Kveikja/slökkva á stokkun
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Sýna lagalista
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Ãttu á þjónustu til að færa sýnishorn á tiltekinn iðnað/bæ
+STR_01FE_DIFFICULTY :{BLACK}Erfiðleikastig ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Síðustu skilaboð/frétt
+STR_0201_MESSAGE_SETTINGS :Skilaboðastillingar
+STR_MESSAGE_HISTORY_MENU :Saga skilaboða
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Sýna síðustu skilaboð/fréttatilkynningu, sýna skilaboðastillingar
+STR_0204_MESSAGE_OPTIONS :{WHITE}Skilaboðastillingar
+STR_0205_MESSAGE_TYPES :{BLACK}Skilaboðategundir:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Aðkoma fyrsta farartækis á stöð leikmanns
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Aðkoma fyrsta farartækis á stöð andstæðings
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Slys / hamfarir
+STR_0209_COMPANY_INFORMATION :{YELLOW}Fyrirtækisupplýsingar
+STR_020A_ECONOMY_CHANGES :{YELLOW}Efnahagsbreytingar
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Ráð / upplýsingar um farartæki leikmanns
+STR_020C_NEW_VEHICLES :{YELLOW}Ný farartæki
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Breyting á viðtöku farms
+STR_020E_SUBSIDIES :{YELLOW}Samstarfssamningar
+STR_020F_GENERAL_INFORMATION :{YELLOW}Almennar upplýsingar
+STR_MESSAGES_ALL :{YELLOW}Stillingar fyrir allar gerðir skilaboða (á/af/úrtak)
+STR_MESSAGE_SOUND :{YELLOW}Spila hljóð með fréttaúrtaki
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...of langt frá fyrri stað
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Efstu fyrirtæki sem náðu {NUM}{}({STRING} stig)
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Sambandstafla fyrirtækis í {NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Viðskiptamaður
+STR_0214_ENTREPRENEUR :Athafnamaður
+STR_0215_INDUSTRIALIST :Iðnjöfur
+STR_0216_CAPITALIST :Kapítalisti
+STR_0217_MAGNATE :Ãhrifamaður
+STR_0218_MOGUL :Stórlax
+STR_0219_TYCOON_OF_THE_CENTURY :Viðskiptajöfur aldarinnar
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} öðlast '{STRING}' titil!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} úr {COMPANY} öðlast '{STRING}' titil!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Búa til kort
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Kortagerð
+STR_0223_LAND_GENERATION :{WHITE}Landslagsgerð
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Handahófskennt land
+STR_0227_RESET_LAND :{BLACK}Eyða landi
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Stækka svæði til að lækka/hækka
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Minnka svæði til að lækka/hækka
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Mynda til land af handahófi
+STR_022B_RESET_LANDSCAPE :{BLACK}Eyða landi
+STR_022C_RESET_LANDSCAPE :{WHITE}Eyða landi
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Ertu viss um að þú viljir eyða landinu?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Landslagsgerð
+STR_022F_TOWN_GENERATION :{BLACK}Bæjargerð
+STR_0230_INDUSTRY_GENERATION :{BLACK}Iðnaðargerð
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Vegagerð
+STR_0233_TOWN_GENERATION :{WHITE}Bæjargerð
+STR_0234_NEW_TOWN :{BLACK}Nýr bær
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Byggja nýjan bæ
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Get ekki byggt bæ hér...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...of nálægt brún kortsins
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...of nálægt öðrum bæ
+STR_0239_SITE_UNSUITABLE :{WHITE}...óhentugur staður
+STR_023A_TOO_MANY_TOWNS :{WHITE}...of margir bæir
+STR_CANNOT_GENERATE_TOWN :{WHITE}Get ekki stofnað nýja borg
+STR_NO_SPACE_FOR_TOWN :{WHITE}...það er ekkert laust svæði á kortinu
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Stækka bæ
+STR_023C_EXPAND :{BLACK}Stækka
+STR_023D_RANDOM_TOWN :{BLACK}Handahófskenndur bær
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Byggja bæ á handahófskenndum stað
+STR_023F_INDUSTRY_GENERATION :{WHITE}Iðnaðargerð
+STR_0240_COAL_MINE :{BLACK}Kolanáma
+STR_0241_POWER_STATION :{BLACK}Rafmagnsstöð
+STR_0242_SAWMILL :{BLACK}Timburverksmiðja
+STR_0243_FOREST :{BLACK}Skógur
+STR_0244_OIL_REFINERY :{BLACK}Olíuhreinsunarstöð
+STR_0245_OIL_RIG :{BLACK}Olíuborpallur
+STR_0246_FACTORY :{BLACK}Verskmiðja
+STR_0247_STEEL_MILL :{BLACK}Stálbræðsla
+STR_0248_FARM :{BLACK}Býli
+STR_0249_IRON_ORE_MINE :{BLACK}Járnnáma
+STR_024A_OIL_WELLS :{BLACK}Olíulindir
+STR_024B_BANK :{BLACK}Banki
+STR_024C_PAPER_MILL :{BLACK}Pappírsverksmiðja
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Matvinnslufyrirtæki
+STR_024E_PRINTING_WORKS :{BLACK}Prentsmiðja
+STR_024F_GOLD_MINE :{BLACK}Gullnáma
+STR_0250_LUMBER_MILL :{BLACK}Timburverksmiðja
+STR_0251_FRUIT_PLANTATION :{BLACK}Ãvaxtaplantekra
+STR_0252_RUBBER_PLANTATION :{BLACK}Gúmmíplantekra
+STR_0253_WATER_SUPPLY :{BLACK}Vatnsbirgi
+STR_0254_WATER_TOWER :{BLACK}Vatnsturn
+STR_0255_DIAMOND_MINE :{BLACK}Demantanáma
+STR_0256_COPPER_ORE_MINE :{BLACK}Koparnáma
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Sykurfrauðsskógur
+STR_0258_CANDY_FACTORY :{BLACK}Sælgætisverksmiðja
+STR_0259_BATTERY_FARM :{BLACK}Rafhlöðubýli
+STR_025A_COLA_WELLS :{BLACK}Kólalindir
+STR_025B_TOY_SHOP :{BLACK}Leikfangabúð
+STR_025C_TOY_FACTORY :{BLACK}Leikfangaverksmiðja
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Plastbrunnir
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Gosdrykkjaverksmiðja
+STR_025F_BUBBLE_GENERATOR :{BLACK}Kúluframkallari
+STR_0260_TOFFEE_QUARRY :{BLACK}Toffýæð
+STR_0261_SUGAR_MINE :{BLACK}Sykurnáma
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Byggja Kolanámu
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Byggja Rafmagnsstöð
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Reisa Timburverksmiðju
+STR_0265_PLANT_FOREST :{BLACK}Gróðursetja Skóg
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Byggja Olíuhreinsunarstöð
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Byggja Olíuborpall (aðeins hægt að byggja við brúnir kortsins)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Byggja Verksmiðju
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Byggja Stálbræðslu
+STR_026A_CONSTRUCT_FARM :{BLACK}Byggja Býli
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Grafa Járnnámu
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Byggja Olíulindir
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Byggja Banka (aðeins hægt að byggja í bæjum með fleiri en 1200 íbúum)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Reisa pappírsverksmiðju
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Reisa Matvinnslufyrirtæki
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Byggja Prentsmiðju
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Byggja Gullnámu
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Byggja Banka (aðeins hægt að byggja í bæjum)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Reisa timburverksmiðju (til að fella regnskóga og framleiða timbur)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Gróðursetja Ãvexti
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Gróðursetja Gúmmí
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Reisa Vatnsbirgi
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Byggja Vatnsturn (aðeins hægt að byggja í bæjum)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Byggja Demantanámu
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Byggja Koparnámu
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Gróðursetja sykurfrauðsskóg
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Byggja Sælgætisverksmiðju
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Byggja Rafhlöðubýli
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Byggja Kólalindir
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Byggja Leikfangabúð
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Byggja Leikfangaverksmiðju
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Byggja Plastbrunni
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Byggja Gosdrykkjaverksmiðju
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Byggja Kúluframkallara
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Byggja Toffýæð
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Byggja Sykurnámu
+STR_0285_CAN_T_BUILD_HERE :{WHITE}Get ekki byggt {STRING} hérna...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...verður að byggja bæ first
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...aðeins eitt stykki á hvern bæ
+STR_0288_PLANT_TREES :{BLACK}Gróðursetja tré
+STR_0289_PLACE_SIGN :{BLACK}Setja skilti
+STR_028A_RANDOM_TREES :{BLACK}Tré af handahófi
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Gróðursetja tré af handahófi á landið
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Setja klettasvæði á landið
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Setja vita
+STR_028E_PLACE_TRANSMITTER :{BLACK}Setja sendi
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Afmarkaðu eyðimörk.{}Smelltu og haltu CTRL til að fjarlægja hana
+STR_CREATE_LAKE :{BLACK}Afmarkaðu vantssvæði.{}Það mun flæða yfir aðlægt svæði ef það er við sjávarmál
+STR_0290_DELETE :{BLACK}Eyða
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Eyða þessum bæ algjörlega
+STR_0292_SAVE_SCENARIO :Vista kort
+STR_0293_LOAD_SCENARIO :Opna kort
+STR_0294_QUIT_EDITOR :Hætta í kortagerð
+STR_0295 :
+STR_0296_QUIT :Hætta
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Vista kort, opna kort, hætta í kortagerð, hætta í OpenTTD
+STR_0298_LOAD_SCENARIO :{WHITE}Opna kort
+STR_0299_SAVE_SCENARIO :{WHITE}Vista kort
+STR_029A_PLAY_SCENARIO :{BLACK}Spila kort
+STR_QUIT_SCENARIO_QUERY :{YELLOW}Ertu viss um að þú viljir hætta í þessu korti ?
+STR_029C_QUIT_EDITOR :{WHITE}Hætta í kortagerð
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...aðeins hægt að byggja í bæjum með fleiri en 1200 íbúum
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Færa byrjunardagsetninguna aftur um 1 ár
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Færa byrjunardagsetninguna fram um 1 ár
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...báðir endar brúarinnar verða að vera á landi
+STR_02A1_SMALL :{BLACK}Lítill
+STR_02A2_MEDIUM :{BLACK}Miðlungs
+STR_02A3_LARGE :{BLACK}Stór
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Velja stærð bæjar
+STR_02A5_TOWN_SIZE :{YELLOW}Stærð bæjar:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Sýna seinustu skilaboð eða fréttatilkynningu
+STR_OFF :Af
+STR_SUMMARY :Úrtak
+STR_FULL :Allt
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Bæjarmappa
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Tegundanöfn farartækja
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Upphafleg
+STR_02BF_CUSTOM :Breytt
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Geyma breytt nöfn
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Nöfn farartækja
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Vista breytt tegundanöfn farartækja
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Stillingar
+STR_02C5_DIFFICULTY_SETTINGS :Erfiðleikastig
+STR_02C7_CONFIG_PATCHES :Viðbætur
+STR_NEWGRF_SETTINGS :Nýgrf stillingar
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Bæjarnöfn sýnd
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Stöðvarnöfn sýnd
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Skilti sýnd
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Millistöðvar sýndar
+STR_02D0_FULL_ANIMATION :{SETX 12}Fullar myndhreyfingar
+STR_02D2_FULL_DETAIL :{SETX 12}Full nákvæmni
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Gegnsæjar byggingar
+STR_TRANSPARENT_SIGNS :{SETX 12}Gegnsæ stöðvanöfn
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Landssvæðisupplýsingar
+STR_02D6 :
+STR_CONSOLE_SETTING :Kveikja á stjórnborði
+STR_02D7_SCREENSHOT_CTRL_S :Skjámynd (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Risa skjámynd (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :Um 'OpenTTD'
+############ range ends here
+
+STR_02DB_OFF :{BLACK}Fela
+STR_02DA_ON :{BLACK}Sýna
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Sýna samstarfssamninga
+STR_02DD_SUBSIDIES :Samstarfssamningar
+STR_02DE_MAP_OF_WORLD :Heimskort
+STR_EXTRA_VIEW_PORT :Auka sjónarhorn
+STR_SIGN_LIST :Skiltalisti
+STR_02DF_TOWN_DIRECTORY :Bæjarmappa
+STR_TOWN_POPULATION :{BLACK}Heildaríbúafjöldi: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Sjónarhorn {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Afrita í sjónarhorn
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Afrita aðalsjónarhornið í sjónarhornsrammann
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Afrita frá sjónarhorni
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Afrita sjónarhornið í rammanum í aðalsjónarhornið
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Gjaldmiðill
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Val á gjaldmiðli
+STR_MEASURING_UNITS :{BLACK}Mælieiningar
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Kerfi mælieininga
+STR_02E6_ROAD_VEHICLES :{BLACK}Aksturstefna
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Aksturstefna bifreiða
+STR_02E9_DRIVE_ON_LEFT :Vinstristefna
+STR_02EA_DRIVE_ON_RIGHT :Hægristefna
+STR_02EB_TOWN_NAMES :{BLACK}Bæjarnöfn
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Tungumál bæjarnafna
+
+STR_02F4_AUTOSAVE :{BLACK}Sjálfvirk vistun
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Tíðni sjálfvirkra vistana
+STR_02F7_OFF :Aldrei
+STR_02F8_EVERY_3_MONTHS :Ãrsfjórðungslega
+STR_02F9_EVERY_6_MONTHS :Hálfsárslega
+STR_02FA_EVERY_12_MONTHS :Ãrlega
+STR_02FB_START_A_NEW_GAME :{BLACK}Hefja nýjan leik
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Opna vistaðan leik
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Búa til eigið land
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Velja einspilunarleik
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Velja 2-8 leikmanna fjölspilunarleik
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Stilla OpenTTD
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Stilla erfiðleikastig
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Hefja nýjan leik í sérvöldu korti
+STR_0304_QUIT :{BLACK}Hætta
+STR_0305_QUIT_OPENTTD :{BLACK}Hætta í OpenTTD
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...aðeins hægt að byggja í bæjum
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Temprað landslag
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Heimskautalandslag
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Velja eyðimerkurlandslag
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Leikfangalandslag
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Fjármagna byggingu nýs iðnaðars
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Iðnaðalisti
+STR_0313_FUND_NEW_INDUSTRY :Fjármagna nýjan iðnað
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Fjármagna nýjan iðnað
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...aðeins hægt að byggja í bæjum
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...aðeins hægt að byggja á regnskógasvæðum
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...aðeins hægt að byggja í eyðimörk
+STR_0319_PAUSED :{YELLOW}* * STÖÃVAÃUR * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Skjámynd vistuð sem '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}Ekki tókst að taka skjámynd!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Kaupa landssvæði til notkunar síðar
+STR_032F_AUTOSAVE :{RED}SJÃLFVIRK VISTUN
+STR_SAVING_GAME :{RED}* * VISTA LEIK * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}Vistun er enn í gangi,{}vinsamlegast bíddu á meðan hún klárst!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Velja 'Ezy gata' listann
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :Ensk (Upphafleg)
+STR_TOWNNAME_FRENCH :Frönsk
+STR_TOWNNAME_GERMAN :Þýsk
+STR_TOWNNAME_ADDITIONAL_ENGLISH :Ensk (Aukaleg)
+STR_TOWNNAME_LATIN_AMERICAN :Rómönsk-Amerísk
+STR_TOWNNAME_SILLY :Fáránleg
+STR_TOWNNAME_SWEDISH :Sænsk
+STR_TOWNNAME_DUTCH :Hollensk
+STR_TOWNNAME_FINNISH :Finnsk
+STR_TOWNNAME_POLISH :Pólsk
+STR_TOWNNAME_SLOVAKISH :Slóvakísk
+STR_TOWNNAME_NORWEGIAN :Norsk
+STR_TOWNNAME_HUNGARIAN :Ungversk
+STR_TOWNNAME_AUSTRIAN :Austurrísk
+STR_TOWNNAME_ROMANIAN :Rúmensk
+STR_TOWNNAME_CZECH :Tékknesk
+STR_TOWNNAME_SWISS :Svissnesk
+STR_TOWNNAME_DANISH :Dönsk
+STR_TOWNNAME_TURKISH :Tyrknesk
+STR_TOWNNAME_ITALIAN :Ãtölsk
+############ end of townname region
+
+STR_CURR_GBP :Pund (£)
+STR_CURR_USD :Bandaríkjadalur ($)
+STR_CURR_EUR :Evra (€)
+STR_CURR_YEN :Jen (Â¥)
+STR_CURR_ATS :Austurrískur skildingur (ATS)
+STR_CURR_BEF :Belgískur franki (BEF)
+STR_CURR_CHF :Svissneskur franki (CHF)
+STR_CURR_CZK :Tékknesk kóróna (CZK)
+STR_CURR_DEM :Þýskt mark (DEM)
+STR_CURR_DKK :Dönsk króna (DKK)
+STR_CURR_ESP :Pesetar (ESP)
+STR_CURR_FIM :Finnskt mark (FIM)
+STR_CURR_FRF :Franki (FRF)
+STR_CURR_GRD :Grísk drakma (GRD)
+STR_CURR_HUF :Ungversk forinta (HUF)
+STR_CURR_ISK :Ãslensk króna (ISK)
+STR_CURR_ITL :Ãtölsk líra (ITL)
+STR_CURR_NLG :Hollensk gyllini (NLG)
+STR_CURR_NOK :Norsk króna (NOK)
+STR_CURR_PLN :Pólsk zloty (PLN)
+STR_CURR_ROL :Rúmensk leu (ROL)
+STR_CURR_RUR :Rússnesk rúbla (RUR)
+STR_CURR_SEK :Sænsk króna (SEK)
+
+STR_CURR_CUSTOM :Sérvalið...
+
+STR_OPTIONS_LANG :{BLACK}Tungumál
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Tungumál viðmóts
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Fylla út í skjá
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}Smelltu hér til að OpenTTD fylli út í skjáinn
+
+STR_OPTIONS_RES :{BLACK}Skjáupplausn
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Stilla skjáupplausn
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Snið skjámynda
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Snið á skjámyndaskrám
+
+STR_AUTOSAVE_1_MONTH :Mánaðarlega
+STR_AUTOSAVE_FAILED :{WHITE}Sjálfvirk vistun mistókst
+
+STR_MONTH_JAN :Janúar
+STR_MONTH_FEB :Febrúar
+STR_MONTH_MAR :Mars
+STR_MONTH_APR :Apríl
+STR_MONTH_MAY :Maí
+STR_MONTH_JUN :Júní
+STR_MONTH_JUL :Júlí
+STR_MONTH_AUG :Ãgúst
+STR_MONTH_SEP :September
+STR_MONTH_OCT :Október
+STR_MONTH_NOV :Nóvember
+STR_MONTH_DEC :Desember
+
+STR_HEADING_FOR_STATION :{LTBLUE}Stefnir að {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}Stefnir að {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Engar skipanir
+STR_NO_ORDERS_VEL :{LTBLUE}Engar skipanir, {VELOCITY}
+
+STR_PASSENGERS :farþegar
+STR_BAGS :pokar
+STR_TONS :tonn
+STR_LITERS :lítrar
+STR_ITEMS :hlutir
+STR_CRATES :kassar
+STR_RES_OTHER :annað
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Get ekki deilt áætlun...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Get ekki afritað áætlun...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - Endi sameiginlegra skipana - -
+
+STR_TRAIN_IS_LOST :{WHITE}Lest {COMMA} er týnd.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}Hagnaður lestar {COMMA} á síðasta ári var {CURRENCY}
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}Gjaldeyrissameining í Evrópu!{}{}Evran er nú eini gjaldeyririnn fyrir öll viðskipti í þínu landi!
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Lest {COMMA} hefur of fáar skipanir á áætluninni
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}Lest {COMMA} hefur tóma skipun
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}Lest {COMMA} hefur tvöfaldar skipanir
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}Lest {COMMA} hefur ógilda stöð í áætluninni
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}Bifreið {COMMA} hefur of fáar skipanir á áætluninni
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}Bifreið {COMMA} hefur tóma skipun
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}Bifreið {COMMA} hefur tvöfaldar skipanir
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}Bifreið {COMMA} hefur ógilda stöð í áætluninni
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}Skip {COMMA} hefur of fáar skipanir á áætluninni
+STR_SHIP_HAS_VOID_ORDER :{WHITE}Skip {COMMA} hefur tóma skipun
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}Skip {COMMA} hefur tvöfaldar skipanir
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}Skip {COMMA} hefur ógilda stöð í áætluninni
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}Flugvél {COMMA} hefur of fáar skipanir á áætluninni
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}Flugvél {COMMA} hefur tóma skipun
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}Flugvél {COMMA} hefur tvöfaldar skipanir
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}Flugvél {COMMA} hefur ógilda stöð í áætluninni
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}Sjálfvirk uppfæring lestar {COMMA} mistókst (takmarkað fjármagn)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}Sjálfvirk uppfæring bifreiðar {COMMA} mistókst (takmarkað fjármagn)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}Sjálfvirk uppfæring skips {COMMA} mistókst (takmarkað fjármagn)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}Sjálfvirk uppfæring flugvélar {COMMA} mistókst (takmarkað fjármagn)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}Lest {COMMA} er of löng eftir endurnýjun
+
+STR_CONFIG_PATCHES :{BLACK}Viðbætur
+STR_CONFIG_PATCHES_TIP :{BLACK}Stilla viðbætur
+STR_CONFIG_PATCHES_CAPTION :{WHITE}Viðbætur
+
+STR_CONFIG_PATCHES_OFF :Nei
+STR_CONFIG_PATCHES_ON :Já
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Sýna hraða farartækis í upplýsingaslá: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Leyfilegt að byggja í halla og á strönd: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Raunverulegri stærð svæðis sem stöðvar ná yfir: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Leyfa meiri eyðingu vega, brúa, gangna o.s.frv. í eigu bæjar: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Leyfa byggingu mjög langra lesta: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Raunveruleg hröðun lesta: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Banna lestum og skipum að taka 90° beygjur: {ORANGE}{STRING} {LTBLUE} (þarfnast NPF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Sameina lestarstöðvar sem byggðar eru samsíða: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Yfirgefa stöð þegar einn farmur er fullfermdur, ef valið er 'fullferma': {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Nota endurbættan algóriþma við hleðslu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Verðbólga: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Aðeins afhlaða farmi á stöðvum þar sem er eftirspurn: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Leyfa byggingu mjög langra brúa: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Skýli má vera á áætlun lesta: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Leyfa byggingu hráefnaframleiðsluiðnaðar: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Leyfa marga svipaða iðnaði í sama bæ: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Má byggja iðnaði af sömu gerð nálægt hvor öðrum: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Sýna alltaf fulla dagsetningu í upplýsingaslá: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Sýna umferðarljós akstursmegin: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Sýna fjármálaglugga í lok árs: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}TTDPatch samhæfð meðhöndlun stansleysu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Bifreiðir fara í biðraðir (með stórvægilegum aukaverkunum): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Færa sjónarhorn þegar músin nálgast brún gluggans: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Leyfilegt að múta bæjaryfirvöldum: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Órétthyrndar lestarstöðvar leyfðar: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Nýtt heildar-leiðarkerfi (NPF, yfirtekur NTP): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Alltaf leyfa litla flugvelli: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Endurskoða skipanir farartækis: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :nei
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :já, en útiloka kyrrstæð farartæki
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :allra farartækja
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Gera viðvart ef lest skilar tapi: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Farartæki úreldast aldrei: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Uppfæra faratæki sjálfvirkt þegar það eldist
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Uppfæra farartæki sjálfkrafa {ORANGE}{STRING}{LTBLUE} mánuðum fyrir/eftir hámarksaldur þess
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Lægsta upphæð peninga sem þörf er á fyrir sjálfvirka uppfæringu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Birtingartími villuskilaboða: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Sýna íbúafjölda í bæjarmerki: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Ósýnileg tré (með gagnsæjum byggingum): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Landslagsmótun: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :Upphafleg
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Hæð snjólínu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION :{LTBLUE}Snúningur hæðakorts: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Rangsælis
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE :Réttsælis
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Dreyfing stöðva mest: {ORANGE}{STRING} {RED}Ath.: Há stilling hægir á leiknum
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Skoða þyrlur sjálfvirkt á þyrlupalli: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Opna landmótunarglugga samhliða lestar-, vegar-, hafnar- og flugvallarframkvæmdarglugga: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Færa sjónarhorn í öfuga átt miðað við mús: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Lestir á leikmann mest: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Bifreiðir á leikmann mest: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}Flugvélar á leikmann mest: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}Skip á leikmann mest: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Útiloka lestir fyrir tölvu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Útiloka bifreiðir fyrir tölvu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Útiloka flugvélar fyrir tölvu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Útiloka skip fyrir tölvu: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Virkja nýja gervigreind (alfa): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Leyfa gervigreind í fjölspilunarleik (á tilraunastigi): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Bið milli skoðana á lestum: {ORANGE}{STRING} dagar/%
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Bið milli skoðana á lestum: {ORANGE}óvirkt
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Bið milli skoðana á bílum: {ORANGE}{STRING} dagar/%
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Bið milli skoðana á bílum: {ORANGE}óvrikt
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Bið milli skoðana á flugvélum: {ORANGE}{STRING} dagar/%
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Bið milli skoðana á flugvélum: {ORANGE}óvrikt
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Bið milli skoðana á skipum: {ORANGE}{STRING} dagar/%
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Bið milli skoðana á skipum: {ORANGE}óvirkt
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Hætta skoðunum þegar bilanir eru afvirktar: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Leyfa hraðatakmarkanir vagna: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Fréttir birtast í lit: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Upphafsár: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}Enda leik árið: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Virkja jafnan efnahag (fleiri og minni breytingar)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Leyfa hlutabréfakaup í öðrum fyrirtækjum
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Þegar dregið er, setja skilti á: {ORANGE}{STRING} hvern reit
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Staðsetning tækjasláar: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Vinstri
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Miðjað
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Hægri
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Gluggar smella saman við: {ORANGE}{STRING} punkta radíus
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Gluggar smella: {ORANGE}ekki saman
+
+STR_CONFIG_PATCHES_GUI :{BLACK}Viðmót
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Bygging
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Farartæki
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Stöðvar
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Efnahagur
+STR_CONFIG_PATCHES_AI :{BLACK}Mótherji
+
+STR_CONFIG_PATCHES_DISABLED :óvirkt
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Breyta gildi stillingar
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Einhver eða öll bil milli skoðana hér fyrir neðan eru ósamhæfanleg við valdar stillingar! 5-90% og 30-800 dagar er leyfilegt
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}Nota YAPF fyrir skip: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}Nota YAPF fyrir bifreiðar: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}Nota YAPF fyrir lestir: {ORANGE}{STRING}
+
+STR_TEMPERATE_LANDSCAPE :Temprað landslag
+STR_SUB_ARCTIC_LANDSCAPE :Heimskautalandslag
+STR_SUB_TROPICAL_LANDSCAPE :Miðjarðarlandslag
+STR_TOYLAND_LANDSCAPE :Leikfangalandslag
+
+STR_CHEATS :{WHITE}Svindl
+STR_CHEATS_TIP :{BLACK}Valreitur segir til um ef þú hefur notað þetta svindl áður
+STR_CHEATS_WARNING :{BLACK}Aðvörun! Þú ert í þann mund að svíkja keppinauta þína. Hafðu í huga að þess lags svívirðing mun ætíð höfð í minnum.
+STR_CHEAT_MONEY :{LTBLUE}Auka pening um {CURRENCY64}
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Spila sem leikmaður: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Töfrajarðýta (eyða iðnaði og óeyðanlegu): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Göng mega skerast: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Byggja í bið: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Þotur brotlenda ekki (oft) á litlum flugvöllum: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Skipta um loftslag: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Breyta dagsetningu: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}Leyfa breytingar á verðmæti framleiðslu: {ORANGE}{STRING}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}à leiðinni til {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}à leiðinni til {WAYPOINT}, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :Fara með {WAYPOINT}
+STR_GO_NON_STOP_TO_WAYPOINT :Ekki stöðva á {WAYPOINT}
+
+STR_WAYPOINTNAME_CITY :Millistöð {TOWN}
+STR_WAYPOINTNAME_CITY_SERIAL :Millistöð {TOWN} #{COMMA}
+STR_LANDINFO_WAYPOINT :Millistöð
+
+STR_WAYPOINT :{WHITE}Leiðarvísir
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Velja tegund leiðarvísis
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}Breyta nafni millistöðvar
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Get ekki breytt nafni millistöðvar...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Breyta teini í millistöð
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Get ekki byggt lestarmillistöð hér...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Get ekki fjarlægt lestarmillistöð héðan...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Byggja lestartein í Sjálfvirkum ham
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}...það er enginn bær í þessu landi
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}Ertu viss um að þú viljir búa til handahófskennt land?
+STR_MANY_RANDOM_TOWNS :{BLACK}Búa til marga bæi
+STR_RANDOM_TOWNS_TIP :{BLACK}Þekja landið með bæjum
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Búa til marga iðnaði
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Þekja kortið mörgum handahófskenndum iðnöðum
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Get ekki búið til iðnað...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Opna landslags verkfæraslána til að hækka/lækka land, gróðursetja tré o.s.frv.
+STR_LANDSCAPING_TOOLBAR :{WHITE}Mótun lands
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Jafna land
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Tré af handahófskenndri gerð
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}Gróðursetja tré af handahófskenndri gerð
+
+STR_CANT_BUILD_CANALS :{WHITE}Ekki hægt að grafa skipaskurð hér...
+STR_BUILD_CANALS_TIP :{BLACK}Grafa skipaskurð
+STR_LANDINFO_CANAL :Skipaskurður
+
+STR_CANT_BUILD_LOCKS :{WHITE}Ekki hægt að gera skurðgátt hér
+STR_BUILD_LOCKS_TIP :{BLACK}Grafa skruðgátt
+STR_LANDINFO_LOCK :Skurðgátt
+
+STR_BUOY_IS_IN_USE :{WHITE}... bauja í notkun!
+
+STR_LANDINFO_COORDS :{BLACK}Hnit: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Get ekki fjarlægt hluta af stöð...
+STR_CANT_CONVERT_RAIL :{WHITE}Get ekki breytt lestarteini...
+STR_CONVERT_RAIL_TIP :{BLACK}Breyta/Uppfæra gerð af lestarteini
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Dragðu eimreið hingað til að selja alla lestina
+
+STR_DRAG_DROP :{BLACK}Draga & Sleppa
+STR_STATION_DRAG_DROP :{BLACK}Byggja lestarstöð með 'draga og sleppa' aðferðinni
+STR_SELECT_STATION_CLASS_TIP :{BLACK}Veldu flokk stöðva sem á að sýna
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Veldu tegund stöðvar til að reisa
+
+STR_FAST_FORWARD :{BLACK}Spóla leikinn áfram
+STR_MESSAGE_HISTORY :{WHITE}Saga skilaboða
+STR_MESSAGE_HISTORY_TIP :{BLACK}Listi yfir nýlegar fréttir
+STR_MESSAGES_DISABLE_ALL :{BLACK}Óvirkja allt
+STR_MESSAGES_ENABLE_ALL :{BLACK}Virkja allt
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Grafa Kolanámu
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Gróðursetja Skóg
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Reisa Olíuborpall
+STR_CONSTRUCT_FARM_TIP :{BLACK}Koma á fót Bóndabýli
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Grafa Koparnámu
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Bora eftir Olíu
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Grafa Gullnámu
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Grafa Demantanámu
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Grafa Járnnámu
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Rækta Ãvaxtaplantekru
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Rækta Gúmmíplantekru
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Koma á fót Vatnsbirgi
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Gróðursetja Sykurfrauðsskóg
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}Koma á fót Rafhlöðubýli
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Bora eftir kóla
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Grafa Plastbrunna
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Reisa Kúluframleiðslu
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Grafa Karamellunámu
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Grafa Sykurnámu
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Iðnaðir
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA}% flutt)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA}%/{COMMA}% flutt)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}...of nálægt öðrum iðnaði
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Breyta lest svo hún flytji annan farm
+STR_RAIL_REFIT_VEHICLE :{BLACK}Breyta lest
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Veldu hvernig farm lestin á að flytja
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Breyta lest svo hún flytji valinn farm
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Get ekki breytt lest...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Bil milli skoðana er í hundraðshlutum: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Breyta framleiðslu
+
+TEMP_AI_IN_PROGRESS :{WHITE}Velkomin/n í nýju gervigreindina, verk í vinnslu. Þú mátt búast við vandamálum, og þegar þau koma upp skaltu taktu skjámynd þegar og senda á spjallborðið. Njóttu!
+TEMP_AI_ACTIVATED :{WHITE}Ath.: nýja gervigreindin er ennþá alfa! à augnablikinu virka aðeins vörubílar og strætisvagnar!
+TEMP_AI_MULTIPLAYER :{WHITE}Viðvörun: þessi eiginleiki er á tilraunastigi. Vinsamlegast tilkynnið vandamál tengd honum til truelight@openttd.org.
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Fjölspilun
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Nafn leikmanns:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}Þetta er nafnið sem aðrir leikmenn munu þekkja þig undir
+STR_NETWORK_CONNECTION :{BLACK}Tenging:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Veldu milli internetleiks eða staðarnetleiks
+
+STR_NETWORK_START_SERVER :{BLACK}Hefja þjón
+STR_NETWORK_START_SERVER_TIP :{BLACK}Hefja eigin þjón
+
+STR_NETWORK_GAME_NAME :{BLACK}Nafn
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Nafn leiksins
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Tungumál, útgáfa þjóns o.s.frv.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Ãttu á leik á listanum til að velja hann
+
+STR_NETWORK_FIND_SERVER :{BLACK}Finna þjón
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Leita að þjónum á neti
+STR_NETWORK_ADD_SERVER :{BLACK}Bæta við þjóni
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Bætir þjóni við listann sem mun alltaf sýna leiki í spilun
+STR_NETWORK_ENTER_IP :{BLACK}Sláðu inn IP tölu þjónsins
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Notendur
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Tengdir notendur / hámarksfjöldi notenda
+STR_NETWORK_GAME_INFO :{SILVER}UPPLÃSINGAR UM LEIK
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Notendur: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Tungumál: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Landslag: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Stærð: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}Útgáfa þjóns: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}Veffang þjóns: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Upphafsdagsetning: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Núverandi dagsetning: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Varið með lykilorði!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}ÞJÓNN AFTENGDUR
+STR_NETWORK_SERVER_FULL :{SILVER}ÞJÓNN FULLUR
+STR_NETWORK_VERSION_MISMATCH :{SILVER}ÚTGÃFA STEMMIR EKKI
+
+STR_NETWORK_JOIN_GAME :{BLACK}Tengjast leik
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}Hefja nýjan fjölspilunarleik
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Nafn leiks:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}Nafn leiksins mun vera sýnilegt öðrum leikmönnum í fjölspilunarvalmyndinni
+STR_NETWORK_SET_PASSWORD :{BLACK}Veldu lykilorð
+STR_NETWORK_PASSWORD_TIP :{BLACK}Verndaðu leikinn þinn með lykilorði ef þú vilt ekki að óboðnir tengist honum
+STR_NETWORK_SELECT_MAP :{BLACK}Veldu kort:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}Hvaða kort viltu spila?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}Hámarksfjöldi notenda:
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Veldu hámarksfjölda notenda. Ekki þarf að fylla öll pláss
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :Staðarnet
+STR_NETWORK_INTERNET :Internet
+STR_NETWORK_LAN_INTERNET :Staðarnet / Internet
+STR_NETWORK_INTERNET_ADVERTISE :Internet (auglýsa)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 leikmenn
+STR_NETWORK_1_PLAYERS :1 leikmaður
+STR_NETWORK_2_PLAYERS :2 leikmenn
+STR_NETWORK_3_PLAYERS :3 leikmenn
+STR_NETWORK_4_PLAYERS :4 leikmenn
+STR_NETWORK_5_PLAYERS :5 leikmenn
+STR_NETWORK_6_PLAYERS :6 leikmenn
+STR_NETWORK_7_PLAYERS :7 leikmenn
+STR_NETWORK_8_PLAYERS :8 leikmenn
+STR_NETWORK_9_PLAYERS :9 leikmenn
+STR_NETWORK_10_PLAYERS :10 leikmenn
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}Hámarksfjöldi fyrirtækja:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Takmarka fjölda fyrirtækja á vefþjóni
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}Hámarksfjöldi áhorfanda:
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Takmarka fjölda áhorfanda á vefþjóninum
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Tungumál:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Aðrir notendur munu vita hvaða tungumál er talað á þjóninum
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}Hefja leik
+STR_NETWORK_START_GAME_TIP :{BLACK}Hefja nýjan netleik í sérvöldu korti eða landslagi af handahófi
+STR_NETWORK_LOAD_GAME :{BLACK}Hlaða leik
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Hefja aftur vistaðan fjölspilunarleik (vertu viss um að tengjast sem réttur leikmaður)
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Hvað sem er
+STR_NETWORK_LANG_ENGLISH :Enska
+STR_NETWORK_LANG_GERMAN :Þýska
+STR_NETWORK_LANG_FRENCH :Franska
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Anddyri fjölspilunarleiks
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Undirbý tengingu við: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}Listi yfir öll fyrirtæki í leiknum. Þú getur annað hvort gengið í lið með einu eða komið á fót nýju ef pláss er fyrir nýtt
+STR_NETWORK_NEW_COMPANY :{BLACK}Nýtt fyrirtæki
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Koma á fót nýju fyrirtæki
+STR_NETWORK_SPECTATE_GAME :{BLACK}Fylgjast með leik
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Fylgjast með leiknum sem áhorfandi
+STR_NETWORK_JOIN_COMPANY :{BLACK}Ganga í lið með fyrirtæki
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Hjálpa við stjórnun þessa fyrirtækis
+STR_NETWORK_REFRESH :{BLACK}Endurnýja þjón
+STR_NETWORK_REFRESH_TIP :{BLACK}Endurnýja upplýsingar um þjón
+
+STR_NETWORK_COMPANY_INFO :{SILVER}UPPLÃSINGAR UM FYRIRTÆKI
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Nafn fyrirtækis: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}Upphaf: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}Heildarverðmæti fyrirtækis: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Núverandi staða: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Innkoma síðasta árs: {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}Frammistaða: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}Farartæki: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Stöðvar: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Leikmenn: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}Tengist...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) Tengist..
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Staðfesti..
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Bíð..
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Hala niður korti..
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Vinn úr gögnum..
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) Skrái..
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Næ í upplýsingar um leik..
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Næ í upplýsingar um fyrirtæki..
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} þjónar fyrir framan þig
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} kílóbæti niðurhöluð hingaðtil
+
+STR_NETWORK_DISCONNECT :{BLACK}Aftengjast
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Sláðu inn upphæð fjár sem þú villt gefa
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Þjónn er varinn. Sláðu inn lykilorð
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Fyrirtæki er varið. Sláðu inn lykilorð
+STR_NETWORK_CLIENT_LIST :{WHITE}Listi yfir leikmenn
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE} Enginn netbúnaður fannst eða vistþýtt án ENABLE_NETWORK
+STR_NETWORK_ERR_NOSERVER :{WHITE} Fann enga netleiki
+STR_NETWORK_ERR_NOCONNECTION :{WHITE} Þjóninn svaraði ekki fyrirspurninni
+STR_NETWORK_ERR_DESYNC :{WHITE} Samstilling netleiks mistókst.
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} Tenging við netleik glataðist.
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} Gat ekki hlaðið vistuðum leik af þjóni.
+STR_NETWORK_ERR_SERVER_START :{WHITE} Gat ekki ræst þjón
+STR_NETWORK_ERR_CLIENT_START :{WHITE} Gat ekki tengst
+STR_NETWORK_ERR_TIMEOUT :{WHITE} Tenging #{NUM} fjaraði út.
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE} Villa varð í samskiptum og tengingu var lokað
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE} Útgáfa biðils er ekki sama og útgáfa þjóns
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} Rangt lykilorð
+STR_NETWORK_ERR_SERVER_FULL :{WHITE} Þjónninn er fullur
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} Þú ert bannaður/bönnuð á þessum þjóni
+STR_NETWORK_ERR_KICKED :{WHITE} Þér var hent út úr leiknum
+STR_NETWORK_ERR_CHEATER :{WHITE} Svindl er ekki leyft á þessum þjóni
+
+STR_NETWORK_ERR_LEFT :hefur hætt í leiknum
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :almenn villa
+STR_NETWORK_ERR_CLIENT_DESYNC :samstillingarvilla
+STR_NETWORK_ERR_CLIENT_SAVEGAME :gat ekki opnað kort
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :tenging rofnaði
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :samskiptavilla
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :Ekki leyfilegt
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :tók á móti undarlegum pakka
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :röng útgáfa
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :nafn nú þegar í notkun
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :rangt leikjalykilorð
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :rangt notandanúmer í DoCommand
+STR_NETWORK_ERR_CLIENT_KICKED :hent út af þjón
+STR_NETWORK_ERR_CLIENT_CHEATER :reyndi að svindla
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :vefþjónn fullur
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :hefur bæst við leikinn
+STR_NETWORK_GIVE_MONEY :gaf fyrirtækinu þínu pening ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :þú gafst {STRING} pening ({CURRENCY})
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Team] :
+STR_NETWORK_CHAT_COMPANY :[Team] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Team] Til {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[Private] :
+STR_NETWORK_CHAT_CLIENT :[Private] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[Private] Til {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[All] :
+STR_NETWORK_CHAT_ALL :[All] {STRING}: {GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :hefur breytt nafni sínu í
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE} Þjónninn sleit tengingunni
+STR_NETWORK_SERVER_REBOOT :{WHITE} Verið er að endurræsa þjóninn...{}Vinsamlega bíðið...
+
+STR_NETWORK_SERVER :Þjónn
+STR_NETWORK_CLIENT :Notandi
+
+STR_NETWORK_CLIENTLIST_NONE :(ekkert)
+STR_NETWORK_CLIENTLIST_KICK :Sparka
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Gefa pening
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Tala við alla
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Tala við fyrirtæki
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Einkaskilaboð
+
+
+STR_NETWORK_SEND :{BLACK}Senda
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}Lengd korts: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Breidd korts: {ORANGE}{STRING}
+
+
+##### PNG-MAP-Loader
+
+
+STR_BMPMAP_ERROR :{WHITE}Get ekki hlaðið landslagi úr BMP skrá...
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}... gat ekki breytt myndsniði.
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Kostnaður: {CURRENCY}
+STR_0801_COST :{RED}Kostnaður: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Tekjur: {CURRENCY}
+STR_0803_INCOME :{GREEN}Tekjur: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Yfirfæra: {CURRENCY}
+STR_FEEDER :{YELLOW}Yfirfæra: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Ãætlaður kostnaður: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Ãætlaðar tekjur: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Get ekki lyft landssvæði hér...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Get ekki lækkað landssvæði hér...
+STR_080A_ROCKS :Klettar
+STR_080B_ROUGH_LAND :Hrjúft land
+STR_080C_BARE_LAND :Bert land
+STR_080D_GRASS :Gras
+STR_080E_FIELDS :Akrir
+STR_080F_SNOW_COVERED_LAND :Snjóþekið land
+STR_0810_DESERT :Eyðimörk
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Landssvæði hallar í ranga átt
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Ómöguleg lestarteinasamstæða
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}Framkvæmdin myndi skemma göng
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Nú þegar við sjávarmál
+STR_1004_TOO_HIGH :{WHITE}Of hátt
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Enginn hentugur lestarteinn
+STR_1007_ALREADY_BUILT :{WHITE}...nú þegar byggt
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Verður að fjarlægja lestartein fyrst
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Járnbrautarlestarframkvæmdir
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Raflestaframkvæmdir
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Einteinungsframkvæmdir
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}MagLev framkvæmdir
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Veldu tegund brúar
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Get ekki byggt lestarskýli hér...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Get ekki byggt lestarstöð hér...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Get ekki byggt umferðarljós hér...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Get ekki byggt lestartein hér...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Get ekki fjarlægt lestartein héðan...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Get ekki fjarlægt umferðarljós héðan...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Lega lestarskýlis
+STR_1015_RAILROAD_CONSTRUCTION :Járnbrautarlestarframkvæmdir
+STR_TOOLB_ELRAIL_CONSTRUCTION :Raflestarramkvæmdir
+STR_1016_MONORAIL_CONSTRUCTION :Einteinungsframkvæmdir
+STR_1017_MAGLEV_CONSTRUCTION :MagLev framkvæmdir
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Leggja lestartein
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Byggja lestarskýli (til að byggja og gera við lestar)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Byggja lestarstöð
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Byggja lestarljós
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Byggja lestarbrú
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Byggja lestargöng
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Skipta á milli byggja/fjarlægja lestarteina og lestarljós
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Brúarval - veldu brú til að byggja
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Veldu legu lestarskýlis
+STR_1021_RAILROAD_TRACK :Lestarteinn
+STR_1023_RAILROAD_TRAIN_DEPOT :Lestarskýli
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...svæðið er í eigu annars fyrirtækis
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :Lestarteinn með venjulegum ljósum
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :Lestarteinn með forljósum
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :Lestarteinn með útljósum
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :Lestarteinn með samljósum
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Verður að fjarlægja veg fyrst
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Vegaframkvæmdir standa yfir
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Vegagerð
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Veldu vegabrú
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Get ekki lagt veg hér...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Get ekki fjarlægt veg héðan...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Bifreiðaskýli
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Get ekki fjarlægt bifreiðaskýli héðan...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Get ekki byggt strætóstoppistöð...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Get ekki byggt flutningabílastöð...
+STR_180A_ROAD_CONSTRUCTION :Vegagerð
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Leggja veg
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Byggja bifreiðaskýli (til að byggja og gera við bifreiðir)
+STR_180D_BUILD_BUS_STATION :{BLACK}Byggja strætóstoppistöð
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Byggja flutningabílastöð
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Byggja vegabrú
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Byggja göng
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Skipta á milli byggja/fjarlægja fyrir vegagerð
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Veldu legu bifreiðaskýlis
+STR_1814_ROAD :Vegur
+STR_1815_ROAD_WITH_STREETLIGHTS :Vegur með umferðarljósum
+STR_1816_TREE_LINED_ROAD :Trjáskreyttur vegur
+STR_1817_ROAD_VEHICLE_DEPOT :Bifreiðaskýli
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :Vega/lestar gatnamót
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Bæir
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Verður að eyða byggingu fyrst
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}Ãbúafjöldi: {ORANGE}{COMMA}{BLACK} Hús: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Endurskíra bæ
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Get ekki endurskírt bæ...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} bæjaryfirvöld leyfa þetta ekki
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Bæjarnöfn - ýttu á nafn til að færa sjónarhorn að viðkomandi bæ
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Færa sjónarhorn á staðsetningu bæjar
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Breyta nafni bæjar
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Farþegar síðasta mánaðar: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Póstur síðasta mánaðar: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Há skrifstofubygging
+STR_2010_OFFICE_BLOCK :Skrifstofubygging
+STR_2011_SMALL_BLOCK_OF_FLATS :Lítil íbúðarbygging
+STR_2012_CHURCH :Kirkja
+STR_2013_LARGE_OFFICE_BLOCK :Stór skrifstofubygging
+STR_2014_TOWN_HOUSES :Ãbúarhús
+STR_2015_HOTEL :Hótel
+STR_2016_STATUE :Stytta
+STR_2017_FOUNTAIN :Gosbrunnur
+STR_2018_PARK :Almenningsgarður
+STR_2019_OFFICE_BLOCK :Skrifstofubygging
+STR_201A_SHOPS_AND_OFFICES :Verslanir og skrifstofur
+STR_201B_MODERN_OFFICE_BUILDING :Nútímaleg skrifstofubygging
+STR_201C_WAREHOUSE :Vöruskemma
+STR_201D_OFFICE_BLOCK :Skrifstofubygging
+STR_201E_STADIUM :Leikvangur
+STR_201F_OLD_HOUSES :Gömul hús
+STR_2020_LOCAL_AUTHORITY :{BLACK}Bæjaryfirvöld
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Sýna upplýsingar um bæjaryfirvöld
+STR_2022_LOCAL_AUTHORITY :{WHITE}Bæjaryfirvöld {TOWN}
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Einkunnir flutningsfyrirtækis:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Samstarfssamningar
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Samstarfssamningar í boði fyrir eftirfarandi þjónustur:
+STR_2027_FROM_TO :{ORANGE}{STRING} frá {STRING} til {STRING}
+STR_2028_BY :{YELLOW} (til {DATE_SHORT})
+STR_202A_NONE :{ORANGE}Enginn
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Samningar þegar í gildi:
+STR_202C_FROM_TO :{ORANGE}{STRING} frá {STATION} til {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, þangað til {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}Tilboð til samstarfssamnings runnið út:{}{}{STRING} frá {STRING} til {STRING} mun ekki vera samningsbundið.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Samsarfssamningur gerður ógildur:{}{} {STRING}flutningur frá {STATION} til {STATION} er ekki lengur samningsbundinn.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Nýtt tilboð til samstarfssamnings: {}{}Fyrsti {STRING}flutningur frá {STRING} til {STRING} mun stofna til eins árs samstarfssamnings við bæjaryfirvöld!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Samstarfssamningur gerður við {COMPANY}!{}{}{STRING}flutningur frá {STATION} til {STATION} mun borga 50% aukalega í heilt ár!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Samstarfssamningur gerður við {COMPANY}!{}{}{STRING}flutningur frá {STATION} til {STATION} mun borga tvöfalt í heilt ár!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Samstarfssamningur gerður við {COMPANY}!{}{}{STRING}flutningur frá {STATION} til {STATION} mun borga þrefalt í heilt ár!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Samstarfssamningur gerður við {COMPANY}!{}{}{STRING}flutningur frá {STATION} til {STATION} mun borga fjórfalt í heilt ár!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}Bæjaryfirvöld {TOWN} leyfa ekki byggingu annars flugvallar nærliggjandi bænum
+STR_2036_COTTAGES :Einbýlishús
+STR_2037_HOUSES :Hús
+STR_2038_FLATS :Ãbúðir
+STR_2039_TALL_OFFICE_BLOCK :Há skrifstofubygging
+STR_203A_SHOPS_AND_OFFICES :Verslanir og skrifstofur
+STR_203B_SHOPS_AND_OFFICES :Verslanir og skrifstofur
+STR_203C_THEATER :Leikhús
+STR_203D_STADIUM :Leikvangur
+STR_203E_OFFICES :Skrifstofur
+STR_203F_HOUSES :Hús
+STR_2040_CINEMA :Kvikmyndahús
+STR_2041_SHOPPING_MALL :Verslunarmiðstöð
+STR_2042_DO_IT :{BLACK}Gera það
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}Listi yfir hluti sem hægt er að gera í þessum bæ - ýttu á viðkomandi hlut fyrir upplýsingar
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Framkvæma völdu aðgerðina í listanum að ofan
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Aðgerðir:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Lítil auglýsingaherferð
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Meðalstór auglýsingaherferð
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Stór auglýsingarherferð
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Fjármagna endurbyggingu vegakerfis
+STR_204A_BUILD_STATUE_OF_COMPANY :Byggja styttu af eiganda fyrirtækis
+STR_204B_FUND_NEW_BUILDINGS :Fjármagna nýjar byggingar
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Kaupa einkarétt á flutningi
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Múta bæjaryfirvöldum
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Hleypa af stokkunum lítilli auglýsingaherferð til að laða að fleiri farþega og meiri farm til að flytja.{} Cost: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Hleypa af stokkunum miðlungs auglýsingaherferð til að laða að fleiri farþega og meiri farm til að flytja.{} Cost: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Hleypa af stokkunum mikilli auglýsingaherferð til að laða að fleiri farþega og meiri farm til að flytja.{} Kostnaður: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} Kosta endurbætur á vegakerfi úthverfanna. Veldur töluverðri röskun á umferð í allt að 6 mánuði.{} Kostnaður: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Byggja styttu til heiðurs fyrirtækinu þínu.{} Kostnaður: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Kosta byggingu verslunarhúsnæðis í bænum.{} Kostnaður: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Kaupa 1 árs flutningsrétt í þessum bæ. Bæjaryfirvöld munu aðeins leyfa notkun á þínum flutningsleiðum.{} Kostnaður: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Múta bæjaryfirvöldum til að auka við fylgi þitt, með hættu á þungri refsingu komist það upp.{} Kostnaður: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}Glundroði í umferð {TOWN}!{}{}Uppbygging vega kostuð af {COMPANY} veldur 6 mánaða vesæld meðal ökumanna!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (í byggingu)
+STR_2059_IGLOO :Snjóhús
+STR_205A_TEPEES :Indíánatjald
+STR_205B_TEAPOT_HOUSE :Teketilshús
+STR_205C_PIGGY_BANK :Svínabanki
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN} {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Mótun lands
+STR_2800_PLANT_TREES :Gróðursetja tré
+STR_2801_PLACE_SIGN :Setja skilti
+STR_2802_TREES :{WHITE}Tré
+STR_2803_TREE_ALREADY_HERE :{WHITE}...hér er nú þegar tré
+STR_2804_SITE_UNSUITABLE :{WHITE}...óhentugur staður
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Ekki hægt að gróðursetja tré hér...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...of mörg skilti
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Ekki hægt að setja tré hér...
+STR_280A_SIGN :Skilti
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Breyta texta skiltis
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Get ekki breytt nafni skiltis...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Veldu trjátegund sem á að gróðursetja
+STR_280E_TREES :Tré
+STR_280F_RAINFOREST :Regnskógar
+STR_2810_CACTUS_PLANTS :Kaktus
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Lestarstöðvastillingar
+STR_3001_AIRPORT_SELECTION :{WHITE}Flugvallastillingar
+STR_3002_ORIENTATION :{BLACK}Staða
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Fjöldi lestarspora
+STR_3004_PLATFORM_LENGTH :{BLACK}Lengd lestarstöðvar
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Of nálægt annarri lestarstöð
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Tengist fleiri en einni annarri stöð
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}Of margar stöðvar/lestunarsvæði í þessum bæ
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}Of margar stöðvar/lestunarsvæði
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Of margar strætisvagnastöðvar
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}Of margar vörubílastöðvar
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Of nálægt annarri stöð/lestunarsvæði
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Þarf fyrst að rífa lestarstöð
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Of nálægt öðrum flugvelli
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Þarf fyrst að rífa flugvöll
+
+STR_3030_RENAME_STATION_LOADING :Endurnefna stöð/lestunarsvæði
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Get ekki endurnefnt stöð...
+STR_3032_RATINGS :{BLACK}Einkunn
+STR_3033_ACCEPTS :{BLACK}Tekur við
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}Staðbundin einkunn flutningsþjónustu:
+
+############ range for rating starts
+STR_3035_APPALLING :Hræðilegur
+STR_3036_VERY_POOR :Mjög glataður
+STR_3037_POOR :Glataður
+STR_3038_MEDIOCRE :Ãgætur
+STR_3039_GOOD :Góður
+STR_303A_VERY_GOOD :Mjög góður
+STR_303B_EXCELLENT :Frábær
+STR_303C_OUTSTANDING :Framúrskarandi
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} tekur ekki lengur við {STRING}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} tekur ekki lengur við {STRING} eða {STRING}
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} tekur nú við {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} tekur nú við {STRING} og {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Staða strætisvagnastöðvar
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Staða póstvagnsstöðvar
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Verður að eyða strætisvagnastöðinni fyrst
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Verður að eyða póstvagnsstöðinni fyrst
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Stöðvar
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Ekkert -
+STR_304B_SITE_UNSUITABLE :{WHITE}...óhentug staðsetning
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Of nálægt annarri höfn
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Verður að eyða höfn fyrst
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Veldu stöðu lestarstöðvar
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Veldu fjölda lestarspora á lestarstöð
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Veldu lengd lestarstöðvar
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Veldu stöðu strætisvagnastöðvar
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Veldu stöðu póstvagnsstöðvar
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Færa miðju sýnishorns á staðsetningu stöðvar
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Sýna einkunn stöðvar
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Breyta nafni stöðvar
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Sýna lista yfir móttækilegan varning
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Nöfn stöðva - ýttu á nafn til að færa miðju sjónarhorns á stöð
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Veldu stærð/tegund flugvallar
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :Lestarstöð
+STR_305F_AIRCRAFT_HANGAR :Flugskýli
+STR_3060_AIRPORT :Flugvöllur
+STR_3061_TRUCK_LOADING_AREA :Vörubílastöð
+STR_3062_BUS_STATION :Strætisvagnastöð
+STR_3063_SHIP_DOCK :Skipahöfn
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Sýna svæði sem tilheyrir stöð
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Ekki sýna svæði sem tilheyrir stöð
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Svæði sem tilheyrir stöð
+STR_3068_DOCK :{WHITE}Höfn
+STR_3069_BUOY :Bauja
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...bauja fyrir
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...stöð of dreyfð
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...óregluleg lögun lestarstöðva bönnuð
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Haltu CTRL inni til að velja fleiri en eitt
+
+STR_UNDEFINED :(óskilgreindur strengur)
+STR_STAT_CLASS_DFLT :Sjálfgefin stöð
+STR_STAT_CLASS_WAYP :Millistöð
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Staða skipaslipps
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...verður að byggjast á vatni
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Get ekki byggt skipaslipp hér...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Velja stöðu skipaslipps
+STR_3804_WATER :Vatn
+STR_3805_COAST_OR_RIVERBANK :Strönd
+STR_3806_SHIP_DEPOT :Skipaslippur
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...Get ekki byggt á vatni
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Vista leik
+STR_4001_LOAD_GAME :{WHITE}Opna leik
+STR_4002_SAVE :{BLACK}Vista
+STR_4003_DELETE :{BLACK}Eyða
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} megabæti laus
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Get ekki lesið af drifi
+STR_4007_GAME_SAVE_FAILED :{WHITE}Vistun leiks mistókst
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Get ekki eytt skrá
+STR_4009_GAME_LOAD_FAILED :{WHITE}Mistókst að opna leik
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}Listi yfir drif, möppur og vistaða leiki
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Nafn fyrir vistun leiks
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Eyða nafninu
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Vista leikinn undir þessu nafni
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Velja tegund leiks
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Velja landslag (grænt), forstilltan leik (blátt) eða handahófskenndan leik
+STR_4010_GENERATE_RANDOM_NEW_GAME :Búa til nýjan leik
+STR_4011_LOAD_HEIGHTMAP :{WHITE}Hlaða hæðakorti
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} er fyrir
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :Kolanáma
+STR_4803_POWER_STATION :Rafmagnsstöð
+STR_4804_SAWMILL :Timburverksmiðja
+STR_4805_FOREST :Skógur
+STR_4806_OIL_REFINERY :Olíuhreinsunarstöð
+STR_4807_OIL_RIG :Olíuborpallur
+STR_4808_FACTORY :Verksmiðja
+STR_4809_PRINTING_WORKS :Prentsmiðja
+STR_480A_STEEL_MILL :Stálbræðsla
+STR_480B_FARM :Bóndabýli
+STR_480C_COPPER_ORE_MINE :Koparnáma
+STR_480D_OIL_WELLS :Olíulindir
+STR_480E_BANK :Banki
+STR_480F_FOOD_PROCESSING_PLANT :Matvælaframleiðsla
+STR_4810_PAPER_MILL :Pappírsverksmiðja
+STR_4811_GOLD_MINE :Gullnáma
+STR_4812_BANK :Banki
+STR_4813_DIAMOND_MINE :Demantanáma
+STR_4814_IRON_ORE_MINE :Járnnáma
+STR_4815_FRUIT_PLANTATION :Ãvaxtaplantekra
+STR_4816_RUBBER_PLANTATION :Gúmmíplantekra
+STR_4817_WATER_SUPPLY :Vatnsbyrgi
+STR_4818_WATER_TOWER :Vatnsturn
+STR_4819_FACTORY :Verksmiðja
+STR_481A_FARM :Bóndabýli
+STR_481B_LUMBER_MILL :Timburverksmiðja
+STR_481C_COTTON_CANDY_FOREST :Sykurfrauðsskógur
+STR_481D_CANDY_FACTORY :Sælgætisverksmiðja
+STR_481E_BATTERY_FARM :Rafhlöðubýli
+STR_481F_COLA_WELLS :Kólalindir
+STR_4820_TOY_SHOP :Leikfangabúð
+STR_4821_TOY_FACTORY :Leikfangaverksmiðja
+STR_4822_PLASTIC_FOUNTAINS :Plastbrunnar
+STR_4823_FIZZY_DRINK_FACTORY :Gosdrykkjaverksmiðja
+STR_4824_BUBBLE_GENERATOR :Kúluframleiðsla
+STR_4825_TOFFEE_QUARRY :Karamellunáma
+STR_4826_SUGAR_MINE :Sykurnáma
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Tekur við: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Tekur við: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Tekur við: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Framleiðsla síðasta mánaðar:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% flutt)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Miðja aðalsjónarhorn á iðnað
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Ný {STRING} í byggingu við {TOWN}!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Ný {STRING} er að rísa við {TOWN}!
+STR_482F_COST :{BLACK}Kostnaður: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Get ekki reist þennan iðnað hér...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...skógur getur aðeins verið gróðursettur yfir snjólínu
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} tilkynnir yfirvofandi lokun!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}Birgðavandamál knýja {INDUSTRY} til að tilkynna yfirvofandi lokun!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}Skortur á nálægum trjám knýr {INDUSTRY} til að tilkynna yfirvofandi lokun!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} eykur framleiðsluna!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}Nýtt kolalag fanns í {INDUSTRY}!{}Tvöföldun í framleiðslu væntanleg!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}Meri olía finnst við {INDUSTRY}!{}Tvöföldun í framleiðslu væntanleg!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}Búist er við að endurbættar aðferðir á {INDUSTRY} muni skila tvöfaldri framleiðslu!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}50% samdráttur í framleiðslu hjá {INDUSTRY}
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}Skordýraplága veldur tjóni á {INDUSTRY}!{}Framleiðsla minnkar um 50%
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...getur aðeins verið staðsett nálægt brún kortsins
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}{STRING}framleiðsla í {INDUSTRY} eykst um {COMMA}%!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}{STRING}framleiðsla í {INDUSTRY} minnkar um {COMMA}%!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Lest í göngunum
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Bifreið í göngunum
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Önnur göng fyrir
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Get ekki breytt landi fyrir hinn enda gangnanna
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Verður að eyða göngum fyrst
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Verður að eyða brú fyrst
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Getur ekki byrjað og endað á sama stað
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Sléttlendi eða vatn nauðsynlegt undir brú
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}Verður að byrja og enda í sömu línu
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Óhentug staðsetning fyrir enda gangnanna
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Hengibrú, stál
+STR_500F_GIRDER_STEEL :Burðarbitabrú, stál
+STR_5010_CANTILEVER_STEEL :Svifbitabrú, stál
+STR_5011_SUSPENSION_CONCRETE :Hengibrú, steypa
+STR_5012_WOODEN :Viðarbrú
+STR_5013_CONCRETE :Steypubrú
+STR_5014_TUBULAR_STEEL :Rörabrú, stál
+STR_BRIDGE_TUBULAR_SILICON :Rörabrú, kísill
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Get ekki reist brú hér...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Get ekki grafið göng hér...
+STR_5017_RAILROAD_TUNNEL :Lestagöng
+STR_5018_ROAD_TUNNEL :Vegagöng
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Stálhengibrú, lestir
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Stálburðarbitabrú, lestir
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Stálsvifbitabrú, lestir
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Styrkt steypuhengirbú, lestir
+STR_501F_WOODEN_RAIL_BRIDGE :Viðarbrú, lestir
+STR_5020_CONCRETE_RAIL_BRIDGE :Steypubrú, lestir
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Stálhengibrú, vegur
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Stálburðarbitabrú, vegur
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Stálsvifbitabrú, vegur
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Styrkt steypuhengibrú, vegur
+STR_5025_WOODEN_ROAD_BRIDGE :Viðarbrú, vegur
+STR_5026_CONCRETE_ROAD_BRIDGE :Stepubrú, vegur
+STR_5027_TUBULAR_RAIL_BRIDGE :Rörabrú, lest
+STR_5028_TUBULAR_ROAD_BRIDGE :Rörabrú, vegur
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Hluturinn er fyrir
+STR_5801_TRANSMITTER :Sendir
+STR_5802_LIGHTHOUSE :Viti
+STR_5803_COMPANY_HEADQUARTERS :Höfuðstöðvar fyritækis
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...höfuðstöðvar fyrirtækis eru fyrir
+STR_5805_COMPANY_OWNED_LAND :Land í eigu fyrirtækis
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Þú getur ekki keypt þetta land...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...þú átt það nú þegar!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Ónefnt
+STR_SV_TRAIN_NAME :Lest {COMMA}
+STR_SV_ROADVEH_NAME :Bifreið {COMMA}
+STR_SV_SHIP_NAME :Skip {COMMA}
+STR_SV_AIRCRAFT_NAME :Flugvél {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :{STRING} Norður
+STR_SV_STNAME_SOUTH :{STRING} Suður
+STR_SV_STNAME_EAST :{STRING} Austur
+STR_SV_STNAME_WEST :{STRING} Vestur
+STR_SV_STNAME_CENTRAL :{STRING} Miðstöð
+STR_SV_STNAME_TRANSFER :{STRING} Flutningur
+STR_SV_STNAME_HALT :{STRING} Stans
+STR_SV_STNAME_VALLEY :{STRING} Dalir
+STR_SV_STNAME_HEIGHTS :{STRING} Hæðir
+STR_SV_STNAME_WOODS :{STRING} Skógar
+STR_SV_STNAME_LAKESIDE :{STRING} Lækjarbakki
+STR_SV_STNAME_EXCHANGE :{STRING} Skipti
+STR_SV_STNAME_AIRPORT :{STRING} Flugvöllur
+STR_SV_STNAME_OILFIELD :{STRING} Olíulendi
+STR_SV_STNAME_MINES :{STRING} Náma
+STR_SV_STNAME_DOCKS :{STRING} Höfn
+STR_SV_STNAME_BUOY_1 :{STRING} Bauja 1
+STR_SV_STNAME_BUOY_2 :{STRING} Bauja 2
+STR_SV_STNAME_BUOY_3 :{STRING} Bauja 3
+STR_SV_STNAME_BUOY_4 :{STRING} Bauja 4
+STR_SV_STNAME_BUOY_5 :{STRING} Bauja 5
+STR_SV_STNAME_BUOY_6 :{STRING} Bauja 6
+STR_SV_STNAME_BUOY_7 :{STRING} Bauja 7
+STR_SV_STNAME_BUOY_8 :{STRING} Bauja 8
+STR_SV_STNAME_BUOY_9 :{STRING} Bauja 9
+STR_SV_STNAME_ANNEXE :{STRING} Annáll
+STR_SV_STNAME_SIDINGS :{STRING} Hliðrun
+STR_SV_STNAME_BRANCH :{STRING} Grein
+STR_SV_STNAME_UPPER :Efri {STRING}
+STR_SV_STNAME_LOWER :Neðri {STRING}
+STR_SV_STNAME_HELIPORT :{STRING} Þyrlupallur
+STR_SV_STNAME_FOREST :{STRING} Skógur
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Erfiðleikastig
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Vista
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Auðvelt
+STR_6802_MEDIUM :{BLACK}Miðlungs
+STR_6803_HARD :{BLACK}Erfitt
+STR_6804_CUSTOM :{BLACK}Sérsniðið
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}Hámarksfjöldi keppinauta: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Byrjunartími keppinauta: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}Fjöldi bæja: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}Fjöldi iðnaða: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Hámarkslán í upphafi: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Vextir í upphafi: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Rekstrarkostnaður farartækja: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Byggingarhraði keppinauta: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Hæfni keppinauta: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Bilanatíðni farartækja: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Margföldun ríkisstyrks: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Byggingarkostnaður: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Gerð landslags: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Magn sjávar/lækja: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Efnahagur: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Snúningur lestar: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Hrakföll: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Afstaða borgaryfirvalda til landmótunar: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :Engin
+STR_6816_LOW :Lág
+STR_6817_NORMAL :Venjuleg
+STR_6818_HIGH :Há
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Mjög hægt
+STR_681C_SLOW :Hægt
+STR_681D_MEDIUM :Miðlungs
+STR_681E_FAST :Hratt
+STR_681F_VERY_FAST :Mjög hratt
+STR_VERY_LOW :Mjög lágt
+STR_6820_LOW :Lágt
+STR_6821_MEDIUM :Miðlungs
+STR_6822_HIGH :Hátt
+STR_6823_NONE :Ekkert
+STR_6824_REDUCED :Minnkað
+STR_6825_NORMAL :Venjulegt
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Mjög flatt
+STR_682B_FLAT :Flatt
+STR_682C_HILLY :Hæðótt
+STR_682D_MOUNTAINOUS :Fjallótt
+STR_682E_STEADY :Stöðugur
+STR_682F_FLUCTUATING :Óstöðugur
+STR_6830_IMMEDIATE :Undir eins
+STR_6831_3_MONTHS_AFTER_PLAYER :eftir 3 mánaða spilun
+STR_6832_6_MONTHS_AFTER_PLAYER :eftir 6 mánaða spilun
+STR_6833_9_MONTHS_AFTER_PLAYER :eftir 9 mánaða spilun
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :à enda brautar, og á lestarstöðvum
+STR_6835_AT_END_OF_LINE_ONLY :Aðeins á enda brautar
+STR_6836_OFF :Ekki á
+STR_6837_ON :Ã
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Sýna topplistann
+STR_6839_PERMISSIVE :Eftirgefin
+STR_683A_TOLERANT :Umburðarlynd
+STR_683B_HOSTILE :Fjandsamleg
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Leikmaður {COMMA})
+STR_7004_NEW_FACE :{BLACK}Nýtt Andlit
+STR_7005_COLOR_SCHEME :{BLACK}Litaskema
+STR_7006_COLOR_SCHEME :{GOLD}Litaskema:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Nýtt Litaskema
+STR_7008_COMPANY_NAME :{BLACK}Nafn fyrirtækis
+STR_7009_PRESIDENT_NAME :{BLACK}Nafn forstöðumanns
+STR_700A_COMPANY_NAME :Nafn Fyrirtækis
+STR_700B_PRESIDENT_S_NAME :Nafn forstöðumanns
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Ekki hægt að breyta nafni fyrirtækis...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Ekki hægt að breyta nafni forstöðumanns...
+STR_700E_FINANCES :{WHITE}{COMPANY} Fjármál {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Útgjöld/Tekjur
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Bygging
+STR_7012_NEW_VEHICLES :{GOLD}Kaupa bifreiðar
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Rekstrarkostnaður lesta
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Rekstrarkostnaður bifreiða
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Rekstrarkostnaður flugvéla
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Rekstrarkostnaður skipa
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Viðhald eigna
+STR_7018_TRAIN_INCOME :{GOLD}Tekjur vegna lesta
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Tekjur vegna bifreiða
+STR_701A_AIRCRAFT_INCOME :{GOLD}Tekjur vegna flugvéla
+STR_701B_SHIP_INCOME :{GOLD}Tekjur vegna skipa
+STR_701C_LOAN_INTEREST :{GOLD}Lánsvextir
+STR_701D_OTHER :{GOLD}Annað
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Summa:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Tekjulínurit
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Resktrartekju línurit
+STR_7026_BANK_BALANCE :{WHITE}Bankainnistæða
+STR_7027_LOAN :{WHITE}Lán
+STR_MAX_LOAN :{WHITE}Hámarkslán: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}Taka lán {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Borga lán {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...hámarksleyfi á láni er {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Ekki hægt að fá meiri pening lánaðan...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...ekkert lán til að borga
+STR_702E_REQUIRED :{WHITE}...{CURRENCY} vantar
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Getur ekki borgað lán...
+STR_INSUFFICIENT_FUNDS :{WHITE}Það er ekki hægt að gefa peninga sem teknir eru að láni frá bankanum...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Velja nýtt andlit á forstöðumanninn
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Breyta útliti á farartækjum fyrirtækisins
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Breyta nafni forstöðumanns
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Breyta nafni fyrirtækisins
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Smelltu á litinn sem þú vilt
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Auka lán
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Borga til baka hluta af láni
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(Manager)
+STR_7038_INAUGURATED :{GOLD}Hafið: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Farartæki:
+STR_TRAINS :{WHITE}{COMMA} lest{P "" ir}
+STR_ROAD_VEHICLES :{WHITE}{COMMA} bíl{P l ar}
+STR_AIRCRAFT :{WHITE}{COMMA} flugvél{P "" ar}
+STR_SHIPS :{WHITE}{COMMA} skip
+STR_7042_NONE :{WHITE}Engin
+STR_7043_FACE_SELECTION :{WHITE}Andlitsval
+STR_7044_MALE :{BLACK}Karlmaður
+STR_7045_FEMALE :{BLACK}Kvenmaður
+STR_7046_NEW_FACE :{BLACK}Nýtt Andlit
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Hætta við andlitsval
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Samþykkja andlitsval
+STR_7049_SELECT_MALE_FACES :{BLACK}Velja karlmannsandlit
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Velja kvenmannsandlit
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Mynda andlit af handahófi
+STR_704C_KEY :{BLACK}Lykill
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Sýna lykilmynd
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Lykilmynd fyrir fyrirtækjagröf
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Smelltu hér til að taka út/setja inn graf þessa fyrirtækis
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Fluttar einingar af farmi
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Einkunn fyrirtækis (hámarkseinkunn=1000)
+STR_7052_COMPANY_VALUES :{WHITE}Fyrirtækisvirði
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Fyrirtækjalisti
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}Flutningsfyrirtæki í vandræðum!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} mun vera selt eða skráð gjaldþrota nema það fari að taka sig á sem fyrst!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(Forstöðumaður)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Samruni flutningsfyrirtækja!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} hefur verið selt {COMPANY} fyrir {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Við erum að leita að flutningsfyrirtæki til að taka yfir okkar rekstri.{}{}Viltu kaupa {COMPANY} fyrir {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Gjaldþrota!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} hefur verið lokað af bankanum og allar eignir seldar!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}Nýtt flutningsfyrirtæki stofnað!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} hefur byggingu nálægt {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Get ekki keypt fyrirtæki...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Farmgjöld
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Dagar í flutningi
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Laun fyrir flutning á 10 einingum (eða 10,000 lítra) af farmi um 20 reiti
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Taka út/setja inn graf fyrir farmgerðir
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Verkfræðingur
+STR_7067_TRAFFIC_MANAGER :Umferðarstjórnandi
+STR_7068_TRANSPORT_COORDINATOR :Flutningaskipuleggjandi
+STR_7069_ROUTE_SUPERVISOR :Leiðarumsjónarmaður
+STR_706A_DIRECTOR :Farmstjóri
+STR_706B_CHIEF_EXECUTIVE :Höfuðákvarðanarmaður
+STR_706C_CHAIRMAN :Sætisherra
+STR_706D_PRESIDENT :Forseti
+STR_706E_TYCOON :Auðkýfingur
+STR_706F_BUILD_HQ :{BLACK}Byggja HS
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Byggja höfuðstöðvar fyrirtækisins / skoða höfuðstöðvar fyrirtækisins
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Endurreisa höfuðstöðvarnar annarsstaðar fyrir 1% af verðmæti fyrirtækis
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Ekki hægt að byggja höfuðstöðvar...
+STR_7072_VIEW_HQ :{BLACK}Skoða HS
+STR_RELOCATE_HQ :{BLACK}Flytja HS
+STR_COMPANY_PASSWORD :{BLACK}Lykilorð
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Til að vernda fyrirtæki þitt frá óboðnum notendum geturðu sett lykilorð á það
+STR_SET_COMPANY_PASSWORD :Setja lykilorð á fyrirtæki
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}Heimssamdráttur!{}{}Hagfræðingar hræddir um efnahagshrun!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Samdráttur!{}{}Uppslag í viðskiptum gefur bjartari von um betri efnahag!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Stækka/smækka gluggastærð
+STR_7076_COMPANY_VALUE :{GOLD}Heildarverðmæti fyrirtækis: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Kaupa 25% hlut í fyrirtæki
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Selja 25% hlut í fyrirtæki
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Kaupa 25% hlut í þessu fyrirtæki
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Selja 25% hlut í þessu fyrirtæki
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Get ekki keypt 25% hlut í þessu fyrirtæki...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}Get ekki selt 25% hlut í þessu fyrirtæki...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% í eigu {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% í eigu {COMPANY}{} {COMMA}% í eigu {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} hefur verið yfirtekið af {COMPANY}!
+STR_7080_PROTECTED :{WHITE}Þetta fyrirtæki er ekki nógu gamalt til að versla með hluti ...
+
+
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (Gufu)
+STR_8001_MJS_250_DIESEL :MJS 250 (Dísel)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut Dísel
+STR_8006_POWERNAUT_DIESEL :Powernaut Dísel
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (Gufu)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (Gufu)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (Gufu)
+STR_800A_SH_8P_STEAM :SH '8P' (Gufu)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (Dísel)
+STR_800C_DASH_DIESEL :'Dash' (Dísel)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (Dísel)
+STR_800E_UU_37_DIESEL :UU '37' (Dísel)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (Dísel)
+STR_8010_CS_4000_DIESEL :CS 4000 (Dísel)
+STR_8011_CS_2400_DIESEL :CS 2400 (Dísel)
+STR_8012_CENTENNIAL_DIESEL :Centennial (Dísel)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (Dísel)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (Dísel)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (Dísel)
+STR_8016_SH_125_DIESEL :SH '125' (Dísel)
+STR_8017_SH_30_ELECTRIC :SH '30' (Rafmagns)
+STR_8018_SH_40_ELECTRIC :SH '40' (Rafmagns)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (Rafmagns)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (Rafmagns)
+STR_801B_PASSENGER_CAR :Fólks
+STR_801C_MAIL_VAN :Póst Geymsla
+STR_801D_COAL_CAR :Kola Pallur
+STR_801E_OIL_TANKER :Olíu Tankur
+STR_801F_LIVESTOCK_VAN :Búfénaðsvagn
+STR_8020_GOODS_VAN :Gæðavöru Geymsla
+STR_8021_GRAIN_HOPPER :Hveiti Pallur
+STR_8022_WOOD_TRUCK :Viðar Pallur
+STR_8023_IRON_ORE_HOPPER :Járn Pallur
+STR_8024_STEEL_TRUCK :Stál Pallur
+STR_8025_ARMORED_VAN :Brynvarin Geymsla
+STR_8026_FOOD_VAN :Matar Geymsla
+STR_8027_PAPER_TRUCK :Pappírs Geymsla
+STR_8028_COPPER_ORE_HOPPER :Kopar Pallur
+STR_8029_WATER_TANKER :Vatns Tankur
+STR_802A_FRUIT_TRUCK :Ãvaxta Pallur
+STR_802B_RUBBER_TRUCK :Gúmmi Pallur
+STR_802C_SUGAR_TRUCK :Sykur Pallur
+STR_802D_COTTON_CANDY_HOPPER :Kandífloss Pallur
+STR_802E_TOFFEE_HOPPER :Karamellu Pallur
+STR_802F_BUBBLE_VAN :Sápukúlu Geymsla
+STR_8030_COLA_TANKER :Kók Tankur
+STR_8031_CANDY_VAN :Sætinda Geymsla
+STR_8032_TOY_VAN :Dóta Geymsla
+STR_8033_BATTERY_TRUCK :Rafhlöðu Pallur
+STR_8034_FIZZY_DRINK_TRUCK :Fizzy Drykkja Pallur
+STR_8035_PLASTIC_TRUCK :Plast Pallur
+STR_8036_X2001_ELECTRIC :'X2001' (Rafmagns)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Rafmagns)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :Fólks bifreið
+STR_803A_MAIL_VAN :Póst geymsl
+STR_803B_COAL_CAR :Kola trukkure
+STR_803C_OIL_TANKER :Olíu Tankur
+STR_803D_LIVESTOCK_VAN :Búfénaðsvagn
+STR_803E_GOODS_VAN :Gæðavöru Geymsla
+STR_803F_GRAIN_HOPPER :Hveiti Pallur
+STR_8040_WOOD_TRUCK :Viðar Pallur
+STR_8041_IRON_ORE_HOPPER :Járn Pallur
+STR_8042_STEEL_TRUCK :Stál Pallur
+STR_8043_ARMORED_VAN :Brynvarin Geymsla
+STR_8044_FOOD_VAN :Matar Geymsla
+STR_8045_PAPER_TRUCK :Pappírs Pallur
+STR_8046_COPPER_ORE_HOPPER :Kopar Pallur
+STR_8047_WATER_TANKER :Vatns Tankur
+STR_8048_FRUIT_TRUCK :Ãvaxta Pallur
+STR_8049_RUBBER_TRUCK :Gúmmí Pallur
+STR_804A_SUGAR_TRUCK :Sykur Pallur
+STR_804B_COTTON_CANDY_HOPPER :Kandífloss Pallur
+STR_804C_TOFFEE_HOPPER :Karamellu Pallur
+STR_804D_BUBBLE_VAN :Sápukúlu Geymsla
+STR_804E_COLA_TANKER :Kók Tankur
+STR_804F_CANDY_VAN :Sælgætis Geymsla
+STR_8050_TOY_VAN :Leikfanga Geymsla
+STR_8051_BATTERY_TRUCK :Rafhlöðu Pallur
+STR_8052_FIZZY_DRINK_TRUCK :Fizzy Drykkjar Pallur
+STR_8053_PLASTIC_TRUCK :Plast Pallur
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (Rafmagns)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (Rafmagns)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (Rafmagns)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (Rafmagns)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :Fólks Bifreið
+STR_805A_MAIL_VAN :Póst Geymsla
+STR_805B_COAL_CAR :Kola Pallur
+STR_805C_OIL_TANKER :Olíu Tankur
+STR_805D_LIVESTOCK_VAN :Búfénaðsvagn
+STR_805E_GOODS_VAN :Gæðavöru Geymsla
+STR_805F_GRAIN_HOPPER :Hveiti Pallur
+STR_8060_WOOD_TRUCK :Viðar Pallur
+STR_8061_IRON_ORE_HOPPER :Járn Pallur
+STR_8062_STEEL_TRUCK :Stál Pallur
+STR_8063_ARMORED_VAN :Brynvarin Geymsla
+STR_8064_FOOD_VAN :Matar Geymsla
+STR_8065_PAPER_TRUCK :Pappírs Pallur
+STR_8066_COPPER_ORE_HOPPER :Kopar Pallur
+STR_8067_WATER_TANKER :Vatns Tankur
+STR_8068_FRUIT_TRUCK :Ãvaxta Pallur
+STR_8069_RUBBER_TRUCK :Gúmmí Pallur
+STR_806A_SUGAR_TRUCK :Sykur Pallur
+STR_806B_COTTON_CANDY_HOPPER :Kandífloss Pallur
+STR_806C_TOFFEE_HOPPER :Karamellu Pallur
+STR_806D_BUBBLE_VAN :Sápukúlu Geymsla
+STR_806E_COLA_TANKER :Kók Tankur
+STR_806F_CANDY_VAN :Sælgætis Geymsla
+STR_8070_TOY_VAN :Leikfanga Geymsla
+STR_8071_BATTERY_TRUCK :Rafhlöðu Pallur
+STR_8072_FIZZY_DRINK_TRUCK :Fizzy Drykkjar Pallur
+STR_8073_PLASTIC_TRUCK :Plast Pallur
+STR_8074_MPS_REGAL_BUS :MPS Regal Strætó
+STR_8075_HEREFORD_LEOPARD_BUS :Hereford Leopard Strætó
+STR_8076_FOSTER_BUS :Foster Strætó
+STR_8077_FOSTER_MKII_SUPERBUS :Foster MkII Ofurstrætó
+STR_8078_PLODDYPHUT_MKI_BUS :Ploddyphut MkI Strætó
+STR_8079_PLODDYPHUT_MKII_BUS :Ploddyphut MkII Strætó
+STR_807A_PLODDYPHUT_MKIII_BUS :Ploddyphut MkIII Strætó
+STR_807B_BALOGH_COAL_TRUCK :Balogh Kolabíll
+STR_807C_UHL_COAL_TRUCK :Uhl Kolabíll
+STR_807D_DW_COAL_TRUCK :DW Kolabíll
+STR_807E_MPS_MAIL_TRUCK :MPS Póstbíll
+STR_807F_REYNARD_MAIL_TRUCK :Reynard Póstbíll
+STR_8080_PERRY_MAIL_TRUCK :Perry Póstbíll
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :MightyMover Póstbíll
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Powernaught Póstbíll
+STR_8083_WIZZOWOW_MAIL_TRUCK :Wizzowow Póstbíll
+STR_8084_WITCOMBE_OIL_TANKER :Witcombe Olíubíll
+STR_8085_FOSTER_OIL_TANKER :Foster Olíubíll
+STR_8086_PERRY_OIL_TANKER :Perry Olíubíll
+STR_8087_TALBOTT_LIVESTOCK_VAN :Talbott búfénaðsbíll
+STR_8088_UHL_LIVESTOCK_VAN :Uhl búfénaðsbíll
+STR_8089_FOSTER_LIVESTOCK_VAN :Foster búfénaðsbíll
+STR_808A_BALOGH_GOODS_TRUCK :Balogh Gæðavörubíll
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Craighead Gæðavörubíll
+STR_808C_GOSS_GOODS_TRUCK :Goss Gæðavörubíll
+STR_808D_HEREFORD_GRAIN_TRUCK :Hereford Hveitibíll
+STR_808E_THOMAS_GRAIN_TRUCK :Thomas Hveitibíll
+STR_808F_GOSS_GRAIN_TRUCK :Goss Hveitibíll
+STR_8090_WITCOMBE_WOOD_TRUCK :Witcombe Viðarbíll
+STR_8091_FOSTER_WOOD_TRUCK :Foster Viðarbíll
+STR_8092_MORELAND_WOOD_TRUCK :Moreland Viðarbíll
+STR_8093_MPS_IRON_ORE_TRUCK :MPS Járngrýtisbíll
+STR_8094_UHL_IRON_ORE_TRUCK :Uhl Járngrýtisbíll
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Chippy Járngrýtisbíll
+STR_8096_BALOGH_STEEL_TRUCK :Balogh Stálbíll
+STR_8097_UHL_STEEL_TRUCK :Uhl Stálbíll
+STR_8098_KELLING_STEEL_TRUCK :Kelling Stálbíll
+STR_8099_BALOGH_ARMORED_TRUCK :Balogh Brynvarinn Bíll
+STR_809A_UHL_ARMORED_TRUCK :Uhl Brynvarinn Bíll
+STR_809B_FOSTER_ARMORED_TRUCK :Foster Brynvarinn Bíll
+STR_809C_FOSTER_FOOD_VAN :Foster Matarbíll
+STR_809D_PERRY_FOOD_VAN :Perry Matarbíll
+STR_809E_CHIPPY_FOOD_VAN :Chippy Matarbíll
+STR_809F_UHL_PAPER_TRUCK :Uhl Pappírsbíll
+STR_80A0_BALOGH_PAPER_TRUCK :Balogh Pappírsbíll
+STR_80A1_MPS_PAPER_TRUCK :MPS Pappírsbíll
+STR_80A2_MPS_COPPER_ORE_TRUCK :MPS Koparbíll
+STR_80A3_UHL_COPPER_ORE_TRUCK :Uhl Koparbíll
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Goss Koparbíll
+STR_80A5_UHL_WATER_TANKER :Uhl Vatnsbíll
+STR_80A6_BALOGH_WATER_TANKER :Balogh Vatnsbíll
+STR_80A7_MPS_WATER_TANKER :MPS Vatnsbíll
+STR_80A8_BALOGH_FRUIT_TRUCK :Balogh Vatnsbíll
+STR_80A9_UHL_FRUIT_TRUCK :Uhl Ãvaxtabíll
+STR_80AA_KELLING_FRUIT_TRUCK :Kelling Ãvaxtabíll
+STR_80AB_BALOGH_RUBBER_TRUCK :Balogh Gúmmíbíll
+STR_80AC_UHL_RUBBER_TRUCK :Uhl Gúmmíbíll
+STR_80AD_RMT_RUBBER_TRUCK :RMT Gúmmíbíll
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :MightyMover Sykurbíll
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Powernaught Sykurbíll
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Wizzowow Sykurbíll
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :MightyMover Kóladrykkjarbíll
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Powernaught Kóladrykkjabíll
+STR_80B3_WIZZOWOW_COLA_TRUCK :Wizzowow Kóladrykkjarbíll
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :MightyMover Kandíflossbíll
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Powernaught Kandíflossbíll
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Wizzowow Kandíflossbíll
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :MightyMover Karamellubíll
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Powernaught Karamellubíll
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Wizzowow Karamellubíll
+STR_80BA_MIGHTYMOVER_TOY_VAN :MightyMover Leikfangabíll
+STR_80BB_POWERNAUGHT_TOY_VAN :Powernaught Leikfangabíll
+STR_80BC_WIZZOWOW_TOY_VAN :Wizzowow Leikfangabíll
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :MightyMover Sælgætisbíll
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Powernaught Sælgætisbíll
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Wizzowow Sælgætisbíll
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :MightyMover Rafhlöðubíll
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Powernaught Rafhlöðubíll
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Wizzowow Rafhlöðubíll
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :MightyMover Fizzy Drykkjarbíll
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Powernaught Fizzy Drykkjarbíll
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Wizzowow Fizzy Drykkjarbíll
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :MightyMover Plastbíll
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Powernaught Plastbíll
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Wizzowow Plastbíll
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :MightyMover Sápukúlubíll
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Powernaught Sápukúlubíll
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Wizzowow Sápukúlubíll
+STR_80CC_MPS_OIL_TANKER :MPS Olíuskip
+STR_80CD_CS_INC_OIL_TANKER :CS-Inc. Olíuskip
+STR_80CE_MPS_PASSENGER_FERRY :MPS Farþegaferja
+STR_80CF_FFP_PASSENGER_FERRY :FFP Farþegaferja
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Bakewell 300 Svifnökkvi
+STR_80D1_CHUGGER_CHUG_PASSENGER :Chugger-Chug Farþegaferja
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Shivershake Farþegaferja
+STR_80D3_YATE_CARGO_SHIP :Yate Farmskip
+STR_80D4_BAKEWELL_CARGO_SHIP :Bakewell Farmskip
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Mightymover Farmskip
+STR_80D6_POWERNAUT_CARGO_SHIP :Powernaut Farmskip
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Skutla
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Ofurpíla 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Tricario Þyrla
+STR_80FE_GURU_X2_HELICOPTER :Guru X2 Þyrla
+STR_80FF_POWERNAUT_HELICOPTER :Powernaut Þyrla
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Skilaboð frá farartækisframleiðanda
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}Við höfum hannað nýja {STRING} - hefðir þú áhuga á árs einkaleyfi á notkun þessa farartækis, svo að við getum athugað frammistöðu þess?
+STR_8102_RAILROAD_LOCOMOTIVE :lest
+STR_8103_ROAD_VEHICLE :bifreið
+STR_8104_AIRCRAFT :flugvél
+STR_8105_SHIP :sjóferju
+STR_8106_MONORAIL_LOCOMOTIVE :einteinungslest
+STR_8107_MAGLEV_LOCOMOTIVE :segul lest
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}{TOWN} Lestar Bygging
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Bæjarbúar fagna . . .{}Fyrsta lest kemur við á {STATION}!
+STR_8802_DETAILS :{WHITE}{STRING} (Upplýsingar)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Lest fyrir
+STR_8804 :{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8806_GO_TO :Fer til {STATION}
+STR_8807_GO_TO_TRANSFER :Fer til {STATION} (Yfirfæra og ferma)
+STR_8808_GO_TO_UNLOAD :Fer til {STATION} (Afferma)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Fer til {STATION} (Yfirfæra og yfirgefa tóm)
+STR_880A_GO_TO_LOAD :Fer til {STATION} (Fullferma)
+STR_880B_GO_TO_TRANSFER_LOAD :Fer til {STATION} (Yfirfæra og fullferma)
+STR_880C_GO_NON_STOP_TO :Fer viðstöðulaust til {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Fer viðstöðulaust til {STATION} (Yfirfæra og ferma)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Fer viðstöðulaust til {STATION} (Afferma)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Fer viðstöðulaust til {STATION} (Yfirfæra og yfirgefa tóm)
+STR_8810_GO_NON_STOP_TO_LOAD :Fer viðstöðulaust til {STATION} (Fullferma)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Fer viðstöðulaust til {STATION} (Yfirfæra og fullferma)
+STR_GO_TO_TRAIN_DEPOT :Fer til {TOWN} Lestaskýli
+STR_SERVICE_AT_TRAIN_DEPOT :Viðgerð í {TOWN} Lestar Byggingu
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Fer viðstöðulaust til {TOWN} Lestar Byggingar
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Viðgerð viðstöðulaust í {TOWN} Lestar Byggingu
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}à leið í {TOWN} Lestar Byggingu
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}à leið í {TOWN} Lestar Byggingu, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (Ógild Skipun)
+
+STR_UNKNOWN_DESTINATION :óþekktur áfangastaður
+STR_8812_EMPTY :{LTBLUE}Tómt
+STR_8813_FROM :{LTBLUE}{CARGO} frá {STATION}
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}Lest {COMMA} bíður í skýli
+STR_8815_NEW_VEHICLES :{BLACK}Ný faratæki
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Lestin er of löng
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Aðeins er hægt að eiga við lestir þegar þær bíða í skýli
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} Lestir
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Nýir lestarvagnar
+STR_NEW_ELRAIL_VEHICLES :{WHITE}Nýjir rafdrifnir lestarvagnar
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Nýir einteingungsvagnar
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Nýir segullestarvagnar
+STR_881F_BUILD_VEHICLE :{BLACK}Smíða vagn
+STR_CLONE_ROAD_VEHICLE :{BLACK}Afrita bifreið
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}Þetta býr til aðra eins bifreið. Control smelltu til að deila áætlun
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Þetta býr til aðra bifreið sem er eins og sú sem þú velur, hvort heldur sem er innan eða utan skýlisins. Smelltu á takkann og svo á bifreiðina. Control smelltu til að deila áætlun
+STR_CLONE_TRAIN :{BLACK}Afrita lest
+STR_CLONE_TRAIN_INFO :{BLACK}Þetta býr til aðra eins lest að tengivögnunum meðtöldum. Control smelltu til að deila áætlun
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}Þetta býr til aðra lest að tengivögnunum meðtöldum sem er eins og sú sem þú velur, hvort heldur sem er innan eða utan skýlisins. Smelltu á takkann og svo á lestina. Control smelltu til að deila áætlun
+STR_8820_RENAME :{BLACK}Endurnefna
+STR_8823_SKIP :{BLACK}Sleppa
+STR_8824_DELETE :{BLACK}Eyða
+STR_8825_NON_STOP :{BLACK}Viðstöðulaust
+STR_8826_GO_TO :{BLACK}Fara að
+STR_8827_FULL_LOAD :{BLACK}Fullferma
+STR_8828_UNLOAD :{BLACK} Afferma
+STR_8829_ORDERS :{WHITE}{VEHICLE} (Skipanir)
+STR_882A_END_OF_ORDERS :{SETX 10}- - Endi skipana - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}Skoðun
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Get ekki byggt lest...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Framleitt: {LTBLUE}{NUM}{BLACK} Virði: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Virði: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}Fermandi / Affermandi
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}Lest þarf að vera stöðvuð í skýli
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Get ekki sent lest í skýli...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Ekki pláss fyrir fleiri skipanir
+STR_8832_TOO_MANY_ORDERS :{WHITE}Of margar skipanir
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Get ekki bætt við nýrri skipun...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Get ekki eytt þessari skipun...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Get ekki breytt þessari skipun...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Get ekki fært farartæki...
+STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}Aftari dráttarvagn fylgir alltaf fremri hluta
+STR_8838_N_A :N/A{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Get ekki selt lest...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Get ekki fundið leit til staðbundins skýlis
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Get ekki ræst/stöðva lest...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Skoðanamillibil: {LTBLUE}{COMMA}dagar{BLACK} Seinasta skoðun: {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Skoðanamillibil: {LTBLUE}{COMMA}%{BLACK} Seinasta skoðun: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Lestir - smelltu á lest fyrir nánari upplýsingar
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Búa til nýjar lestir (þarfnast lestarskýlis)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Lestir - ýttu á lest fyrir uppl., dragðu farartæki til að bæta við/fjarlægja úr lest
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Byggja nýja lest
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Dragðu lestarvagn hingað til að selja hann
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Miðstilla sjónarhorn á staðsetningu lestarskýlis
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Lestarlisti - smelltu á farartæki fyrir meiri upplýsingar
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Búa til valinn lestarvagn
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Endurnefna lestarvagnstegund
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Núverandi aðgerð lestar - smelltu hér til að stöðva/ræsa lestina
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Sýna lestarskipanir
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Miðstilla sjónarhorn á staðsetningu lestar
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Senda lest í skýli
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Neyða lest til að halda áfram án þess að bíða eftir réttu ljósi
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Breyta stefnu lestar
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Sýna nánari upplýsingar um lest
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Lengja skoðanamillibil
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Stytta skoðanamillibil
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Sýna nánari upplýsingar um núverandi farm
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Sýna nánari upplýsingar um lestir
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Sýna burðargetu hvers farartækis
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Sýna heildar burðargetu lestar, raðar eftir tegund farms
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Ãætlun - smelltu til að velja stöð. CTRL + músartakki færir sjónarhorn að stöðinni
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}Sleppa núverandi skipun, og byrja á næstu
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Eyða valdri skipun
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Gera valda skipun viðstöðulausa
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Skeyta inn nýrri skipun á undan valdri skipun, eða bæta við á enda listans
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Neyða lest til að bíða eftir fullum farmi í valdri skipun
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Neyða lest til að afferma sig í valdri skipun
+STR_SERVICE_HINT :{BLACK}Sleppa þessarri skipun nema þörf sé á viðgerð
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}Ný {STRING} er nú fáanleg!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Verð: {CURRENCY} Þyngd: {WEIGHT_S}{}Hraði: {VELOCITY} Hestöfl: {POWER}{}Rekstrarkostnaður: {CURRENCY} á ári{}Burðargeta: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}Bilaður
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}Aldur: {LTBLUE}{STRING}{BLACK} Rekstrarkostnaður: {LTBLUE}{CURRENCY} á ári
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Þyngd: {LTBLUE}{WEIGHT_S} {BLACK}Hestöfl: {LTBLUE}{POWER}{BLACK} Hámarkshraði: {LTBLUE}{VELOCITY}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Hagnaður á þessu ári: {LTBLUE}{CURRENCY} (síðasta ár: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}Ãreiðanleiki: {LTBLUE}{COMMA}% {BLACK}Bilanir frá síðustu viðgerð: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Stöðvaður
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Get ekki látið lest fara framhjá hættumerki...
+STR_8863_CRASHED :{RED}Ãrekstur!
+
+STR_8865_NAME_TRAIN :{WHITE}Skírðu lestina
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}Get ekki skírt lest...
+STR_8867_NAME_TRAIN :{BLACK}Skýrðu lestina
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Lestarslys!{}{COMMA} deyja í sprengingu eftir árekstur
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Get ekki snúið lest við...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Endurskíra lestargerð
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Get ekki endurskírt lestargerð...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Lætur lestina losa farminn á valinni skipun
+STR_886F_TRANSFER :{BLACK}Yfirfæra
+
+STR_TRAIN_STOPPING :{RED}Stöðva
+STR_TRAIN_STOPPING_VEL :{RED}Stöðva, {VELOCITY}
+STR_INCOMPATIBLE_RAIL_TYPES :Ósamstæðir lestarteinar
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Bíll fyrir
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} Bílar
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}{TOWN} Bílastöð
+STR_9004_NEW_VEHICLES :{BLACK}Kaupa bifreiðar
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}Nýjir bílar
+STR_9007_BUILD_VEHICLE :{BLACK}Kaupa bifreið
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Get ekki byggt bíl...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (Upplýsingar)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}Aldur: {LTBLUE}{STRING}{BLACK} Rekstrarkostnaður: {LTBLUE}{CURRENCY} á ári
+STR_900E_MAX_SPEED :{BLACK}Hámarkshraði: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Hagnaður á þessu ári: {LTBLUE}{CURRENCY} (síðasta ár: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}Ãreiðanleiki: {LTBLUE}{COMMA}% {BLACK}Bilanir frá síðustu viðgerð: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Byggður: {LTBLUE}{NUM}{BLACK} Virði: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Burðargeta: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}...verður að stöðvast í bifreiðaskýli
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Get ekki selt bifreið...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Get ekki stöðvað/ræst bifreið...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}Bifreið {COMMA} bíður nú í skýli
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}Er á leið til bifreiðaskýlis {TOWN}
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}Er á leið til bifreiðaskýlis {TOWN}, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Get ekki sent bifreið í skýli...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Finnur ekkert nálægt skýli
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Bifreið - smelltu á bifreið fyrir nánari upplýsingar
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Smíða nýja bifreið (þarfnast bifreiðaskýlis)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Núverandi aðgerð bifreiðar - smelltu hér til að stöðva/ræsa bifreið
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Sýna skipanir bifreiðar
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Miðja aðalsjónarhornið á bifreið
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Senda bifreið í skýli
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Þvinga bifreið til að snúa við
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Sýna upplýsingar um bifreið
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Bifreið - smelltu á bifreið fyrir nánari upplýsingar
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Smíða nýja bifreið
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Dragðu bifreið hingað til að selja hana
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Miðja aðalsjónarhorn á bifreiðaskýli
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Bifreiðalisti - ýttu á bifreið fyrir nánari upplýsingar
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Smíða valda bifreið
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}Ný bifreið fáanleg!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Verð: {CURRENCY}{}Hraði: {VELOCITY}{}Rekstrarkostnaður: {CURRENCY} á ári{}Burðargeta: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Nefna bifreið
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Get ekki nefnt bifreið...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Nefna bifreið
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Bæjarbúar fagna . . .{}Fyrsti strætisvagn kemur við á {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Bæjarbúar fagna . . .{}Fyrsti vörubíll kemur við á {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}Bílslys!{}Bílstjóri deyr í sprengingu eftir árekstur við lest
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}Bílslys!{}{COMMA} deyja í sprengingu eftir árekstur við lest
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Get ekki snúið bifreið við...
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}Get ekki snúið vögnum sem tilheyra vagnapari
+STR_9034_RENAME :{BLACK}Endurnefna
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Endurnefna tegund bifreiðar
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Endurnefna tegund bifreiðar
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE} Get ekki endurnefnat tegund bifreiðar...
+STR_9038_GO_TO_ROADVEH_DEPOT :Fara í {TOWN} bifreiðaskýli
+STR_SERVICE_AT_ROADVEH_DEPOT :Skoða í {TOWN} bifreiðaskýli
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Breyta bifreið svo hún flytji annan farm
+STR_REFIT_ROAD_VEHICLE :{BLACK}Breyta bifreið
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Breyta bifreið svo hún flytji valinn farm
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Get ekki breytt bifreið...
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Hafnarframkvæmdir
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Hafnarframkvæmdir
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Get ekki byggt höfn hér...
+STR_9803_SHIP_DEPOT :{WHITE}{TOWN} Slippur
+STR_9804_NEW_SHIPS :{BLACK}Ný skip
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} Skip
+STR_9808_NEW_SHIPS :{WHITE}Ný skip
+STR_9809_BUILD_SHIP :{BLACK}Smíða skip
+STR_CLONE_SHIP :{BLACK}Afrita skip
+STR_CLONE_SHIP_INFO :{BLACK}Þetta býr til annað eins skip. Control smelltu til að deila áætlun
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}Þetta býr til annað skip sem er eins og það sem þú velur, hvort heldur sem er innan eða utan skýlisins. Smelltu á takkann og svo á skipið. Control smelltu til að deila áætlun
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}Skip verður að vera stöðvað í skýli
+STR_980C_CAN_T_SELL_SHIP :{WHITE}Get ekki selt skip...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Get ekki smíðað skip...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Skip er fyrir
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Upplýsingar)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}Aldur: {LTBLUE}{STRING}{BLACK} Rekstrarkostnaður: {LTBLUE}{CURRENCY}á ári
+STR_9813_MAX_SPEED :{BLACK}Hámarkshraði: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Tekjur þessa árs: {LTBLUE}{CURRENCY} (síðasta ár: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}Ãreiðanleiki: {LTBLUE}{COMMA}% {BLACK}Bilanir frá síðustu skoðun: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Smíðað: {LTBLUE}{NUM}{BLACK} Verðmæti: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}Burðargeta: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}Get ekki stöðvað/ræst skip...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Get ekki sent skip í skýli...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Finnur ekkert nálægt skýli
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}Stefnir að {TOWN} skipaskýlinu
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}Stefnir að {TOWN} skipaskýlinu, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}Skip {COMMA} bíður í skýli
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Byggja höfn
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Reisa skipaskýli (til að smíða og skoða skip)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Skip - smelltu á skip fyrir nánari upplýsingar
+STR_9820_BUILD_NEW_SHIP :{BLACK}Smíða nýtt skip
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Dragðu skip hingað til að selja það
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Miðja aðalsjónarhorn á skipaskýli
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Skip - smelltu fyrir nánari upplýsingar
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Smíða nýtt skip (þarfnast skipaskýlis)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}Skipalisti - smelltu á skip fyrir nánari upplýsingar
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Smíða valið skip
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Núverandi aðgerð skips - smelltu hér til að stöðva/ræsa skipið
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Sýna skipanir skips
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Miðja aðalsjónarhorn á staðsetningu skips
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Senda skipið í skipaskýli
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Sýna nánari upplýsingar um skip
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}Nýtt skip fáanlegt!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Verð: {CURRENCY} Hámarkshraði: {VELOCITY}{}Burðargeta: {CARGO}{}Rekstrarkostnaður: {CURRENCY}á ári
+STR_982F_NAME_SHIP :{BLACK}Nefna skip
+
+STR_9831_NAME_SHIP :{WHITE}Nefna skip
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Get ekki nefnt skip...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Bæjarbúar fagna . . .{}Fyrsta skip kemur við á {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Setja niður bauju sem hægt er að nota sem leiðarvísi fyrir skip
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Get ekki sett bauju hér...
+STR_9836_RENAME :{BLACK}Endurnefna
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Endurnefna skipategund
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Endurnefna skipategund
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Get ekki endurnefnt skipategund...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Breyta vöruflutningaskipum svo þau flytji annan farm
+STR_983B_REFIT :{WHITE}{VEHICLE} (Breyta)
+STR_983C_REFIT_SHIP :{BLACK}Breyta skipi
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Veldu hvernig farm skipið á að flytja
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Breyta skipi svo það flytji valinn farm
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Veldu farm sem á að flytja:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Ný burðargeta: {GOLD}{CARGO}{}{BLACK}Breytingarkostnaður: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Get ekki breytt skipi...
+STR_9842_REFITTABLE :(breytanlegt)
+STR_GO_TO_SHIP_DEPOT :Fara í {TOWN} Skipaskýli
+SERVICE_AT_SHIP_DEPOT :Skoða í {TOWN} Skipaskýli
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Flugvellir
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Get ekki byggt flugvöll hér...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} Flugskýli
+STR_A003_NEW_AIRCRAFT :{BLACK}Nýja flugvél
+STR_CLONE_AIRCRAFT :{BLACK}Afrita flugvél
+STR_CLONE_AIRCRAFT_INFO :{BLACK}Þetta býr til aðra eins flugvél. Control smelltu til að deila áætlun
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Þetta býr til aðra flugvél sem er eins og sú sem þú velur, hvort heldur sem er innan eða utan skýlisins. Smelltu á takkann og svo á flugvélina. Control smelltu til að deila áætlun
+STR_A005_NEW_AIRCRAFT :{WHITE}Ný flugvél
+STR_A006_BUILD_AIRCRAFT :{BLACK}Smíða flugvél
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Get ekki smíðað flugvél...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} Flugvél
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (Skipanir)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (Upplýsingar)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Aldur: {LTBLUE}{STRING}{BLACK} Rekstrarkostnaður: {LTBLUE}{CURRENCY}á ári
+STR_A00E_MAX_SPEED :{BLACK}Hámarkshraði: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Hagnaður í ár: {LTBLUE}{CURRENCY} (í fyrra: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}Ãreiðanleiki: {LTBLUE}{COMMA}% {BLACK}Bilanir frá síðustu skoðun: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Smíðuð: {LTBLUE}{NUM}{BLACK} Virði: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Get ekki sent flugvél í flugskýli...
+STR_HEADING_FOR_HANGAR :{ORANGE}Stefnir á {STATION} flugskýli
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}Stefnir á {STATION} flugskýli, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}Flugvél {COMMA} bíður í flugskýli
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Flugvél er fyrir
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Get ekki stöðvað/ræst flugvél...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}flugvélin er á flugi
+STR_A019_CAPACITY :{BLACK}Burðargeta: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Burðargeta: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}Flugvélin verður að vera stöðvuð í flugskýli
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Get ekki selt flugvélina...
+STR_A01D_AIRPORT_CONSTRUCTION :Flugvallarframkvæmdir
+STR_A01E_BUILD_AIRPORT :{BLACK}Byggja flugvöll
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Flugvélar - smelltu á flugvél fyrir nánari upplýsingar
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Smíða nýja flugvél (þarfnast flugvallar með flugskýli)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Flugvélar - smelltu á flugvél fyrir nánari upplýsingar
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Smíða nýja flugvél
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}Dragðu flugvél hingað til að selja hana
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Miðja aðalsjónarhorn á flugskýli
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Flugvélalisti - smelltu á flugvél fyrir nánari upplýsingar
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Smíða valda flugvél
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Núverandi aðgerð - smelltu hér til að stöðva/ræsa flugvél
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Sýna skipanir flugvélar
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Miðja aðalsjónarhorn á flugvélina
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Senda flugvélina i flugskýli
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Sýna nánari upplýsingar um skip
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}Ný flugvél nú fáanleg!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Verð: {CURRENCY} Hámarkshraði: {VELOCITY}{}Burðargeta: {COMMA} farþegar, {COMMA} pokar af pósti{}Rekstrarkostnaður: {CURRENCY}á ári
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Nefna flugvélina
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Get ekki nefnt flugvélina...
+STR_A032_NAME_AIRCRAFT :{BLACK}Nefna flugvélina
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Bæjarbúar fagna . . .{}Fyrsta flugvél kemur við á {STATION}!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Flugslys!{}{COMMA} deyja í sprengingu á {STATION}
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Flugslys!{}Flugvél varð eldsneytislaus, {COMMA} deyja í sprengingu!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Endurnefna
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Endurnefna tegund flugvélar
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Endurnefna tegund flugvélar
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Get ekki endurnefnt tegund flugvélarinnar...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Breyta flugvél svo hún flytji annan farm
+STR_A03C_REFIT :{WHITE}{VEHICLE} (Breya)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Breyta flugvél
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Veldu farm sem flugvél á að flytja
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Breyta flugvél svo hún flytji valinn farm
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Veldu farm sem á að flytja:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Ný burðargeta: {GOLD}{STRING}{}{BLACK}Breytingarkostnaður: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Get ekki breytt flugvél...
+STR_GO_TO_AIRPORT_HANGAR :Fara í {STATION} flugskýli
+SERVICE_AT_AIRPORT_HANGAR :Skoða í {STATION} flugskýli
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}Loftskipaslys á {STATION}!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Bifreið eyðilagðist í árekstri við FFH
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}Sprenging í olíuhreinsistöð nálægt {TOWN}!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}Verksmiðja eyðilegst við grunsamlegar kringumstæður nálægt {TOWN}!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}FFH lendir rétt hjá {TOWN}!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}Hrun í kolanámu veldur eyðileggingu nálægt {TOWN}!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Flóð!{}Að minnsta kosti {COMMA} er saknað og eru taldir af eftir gífurleg flóð!
+
+STR_BRIBE_FAILED :{WHITE}Tilraun þín til múturs var
+STR_BRIBE_FAILED_2 :{WHITE}uppgvötuð af héraðsrannsóknarmanni
+STR_BUILD_DATE :{BLACK}Byggt: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Nákvæm frammistöðumæling
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}Upplýsingar
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Farartæki:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Stöðvar:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Lágmarkshagnaður:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Lágmarkstekjur:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Hámarkstekjur:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Flutt:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Farmur:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Reiðufé:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Lán:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Alls:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Fjöldi farartækja; inniheldur fjölda bifreiða, lesta, skipa og flugvéla
+STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}Fjöldi stöðvarhluta. Hver hluti stöðvar (t.d. lestarstöð, strætóstöð, flugvöllur) er talinn, jafnvel þótt þeir séu tengdir sem ein stöð.
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}Hagnaður tekjulægsta farartækisins (sem er eldra en 2 ára)
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Afkoma mánaðarins með minnsta hagnaðinn síðustu 12 ársfjórðunga
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Afkoma mánaðarins með mesta hagnaðinn síðustu 12 ársfjórðunga
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}Einingar farms sem fluttar hafa verið síðasta árið
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}Fjöldi farmgerða sem fluttar voru í síðasta ársfjórðungi
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Peningar sem þetta fyrirtæki á í bankanum
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}Peningar sem þetta fyrirtæki hefur tekið að láni
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Heildarpunktar af mögulegum punktum
+
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}Nýgrf stillingar
+STR_NEWGRF_APPLY_CHANGES :{BLACK}Virkja breytingar
+STR_NEWGRF_SET_PARAMETERS :{BLACK}Stilla breytur
+STR_NEWGRF_TIP :{BLACK}Listi yfir öll nýgrf sett sem þú hefur sett inn. Smelltu til að breyta stillingunum
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}Það eru engar nýgrf skrár innsettar! Vinsamlegast skoðaðu leiðbeiningarnar fyrir upplýsingar um hvernig setja á inn nýja grafík
+STR_NEWGRF_FILENAME :{BLACK}Skráarnafn: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}GRF einkenni: {SILVER}{STRING}
+
+STR_CURRENCY_WINDOW :{WHITE}Sérvalinn gjaldeyrir
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Gengi: {ORANGE}{CURRENCY} = £ {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Aðskilnaðarmerki:
+STR_CURRENCY_PREFIX :{LTBLUE}Forskeyti:
+STR_CURRENCY_SUFFIX :{LTBLUE}Viðskeyti:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Skipta í Evrur: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Skipta í Evrur: {ORANGE}aldrei
+STR_CURRENCY_PREVIEW :{LTBLUE}Dæmi: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Breyta sérvöldum gjaldeyri
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} Lestir
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} Bifreiðir
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} Flugvélar
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} Skip
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Sýna allar lestir sem hafa þessa stöð á áætlun
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Sýna allar bifreiðir sem hafa þessa stöð á áætlun
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Sýna allar flugvélar sem hafa þessa stöð á áætlun
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Sýna öll skip sem hafa þessa stöð á áætlun
+
+
+
+
+
+### depot strings
+
+
+
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}Endurnýja {STRING}
+STR_REPLACE_VEHICLES_START :{BLACK}Hefja skipti
+STR_REPLACE_VEHICLES_STOP :{BLACK}Stöðva skipti
+STR_NOT_REPLACING :{BLACK}Skipti ekki
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Enginn vagn valinn
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Veldu vagntegund til að skipta út
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Velja vagntegund sem þú myndir vilja nota í staðin fyrir vagntegundina sem valinn er vinstra megin
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Smelltu til að stöðva skipti á vagntegundinni sem valin er vinstra megin
+STR_REPLACE_HELP_START_BUTTON :{BLACK}Smelltu til að hefja skipti á vagntegundinni sem valin er til vinstri með vagntegundinni sem valin er til hægri
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Veldu hvernig lestir þú skipta út
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Sýnir hvaða vagn kemur í stað þess sem valinn er vinstra megin
+STR_REPLACE_HELP :{BLACK}Þetta gerir þér kleift að skipta út öllum vögum af einni tegund með annarri, þegar þeir fara í lestarskýli
+STR_REPLACE_REMOVE_WAGON :{BLACK}Selja lestarvagna: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Heldur lengd lestar með því að fjarlægja vagna (framan frá) ef útskipting dráttarvagna myndi lengja hana.
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}Skipti út: {ORANGE}{SKIP}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} TILRAUNAEIGINLEIKI {}Skipta á milli útskiptiglugga dráttar- og flutningavagna.{}Útskipting vagna fer aðeins fram ef hægt er að breyta nýju vögnunum til að flytja sama farm og þeir gömlu. Það er kannað fyrir hvern vagn þegar útskipting á honum fer fram.
+STR_ENGINE_NOT_BUILDABLE :{WHITE}Ekki hægt að smíða dráttarvagn
+
+STR_ENGINES :Dráttarvagnar
+STR_WAGONS :Vagnar
+
+
+
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}Merkjalisti - {COMMA} merki
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :Járnbrautavagnar
+STR_ELRAIL_VEHICLES :Rafdrifnir lestarvagnar
+STR_MONORAIL_VEHICLES :Einteinungsvagnar
+STR_MAGLEV_VEHICLES :Segulsvifvagnar
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Verð: {GOLD}{CURRENCY}{BLACK} Þyngd: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Hámarkshraði: {GOLD}{VELOCITY}{BLACK} Hestöfl: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}Hraði: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Rekstrarkostnaður: {GOLD}{CURRENCY} á ári
+STR_PURCHASE_INFO_CAPACITY :{BLACK}Burðargeta: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Hönnun: {GOLD}{NUM}{BLACK} Endingartími: {GOLD}{COMMA} ár
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}Hámarks áreiðanleiki: {GOLD}{COMMA}%
+STR_PURCHASE_INFO_COST :{BLACK}Verð: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Þyngd: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Verð: {GOLD}{CURRENCY}{BLACK} Hámarkshraði: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Burðargeta: {GOLD}{COMMA} farþegar, {COMMA} pokar af pósti
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Drifvagnar: {GOLD}+{POWER}{BLACK} Þyngd: {GOLD}+{WEIGHT_S}
+
+########### String for New Landscape Generator
+
+STR_CLEARING_TILES :{BLACK}Hrjúft og grýtt landslag
+
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}Lítill flugvöllur
+STR_CITY_AIRPORT :{BLACK}Borgarflugvöllur
+STR_METRO_AIRPORT :{BLACK}Stórborgarflugvöllur
+STR_INTERNATIONAL_AIRPORT :{BLACK}Alþjóðaflugvöllur
+STR_COMMUTER_AIRPORT :{BLACK}Innanlandsflugvöllur
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Meginlandsflugvöllur
+STR_HELIPORT :{BLACK}Þyrlupallur
+STR_HELIDEPOT :{BLACK}Þyrluskýli
+STR_HELISTATION :{BLACK}Þyrlustöð
+
+STR_SMALL_AIRPORTS :{BLACK}Litlir flugvellir
+STR_LARGE_AIRPORTS :{BLACK}Stórir flugvellir
+STR_HUB_AIRPORTS :{BLACK}Háannaflugvellir
+STR_HELIPORTS :{BLACK}Þyrluflugvellir
+########
diff --git a/src/lang/italian.txt b/src/lang/italian.txt
new file mode 100644
index 000000000..99a11242b
--- /dev/null
+++ b/src/lang/italian.txt
@@ -0,0 +1,3116 @@
+##name Italian
+##ownname Italian (IT)
+##isocode it_IT.UTF-8
+##plural 0
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Fuori dal bordo della mappa
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Troppo vicino al bordo della mappa
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Denaro insufficiente - richiesto {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Richiesto terreno piano
+STR_0008_WAITING :{BLACK}In attesa: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (in viaggio da
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Accettati: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Accettati: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :Passeggeri
+STR_0010_COAL :Carbone
+STR_0011_MAIL :Posta
+STR_0012_OIL :Petrolio
+STR_0013_LIVESTOCK :Bestiame
+STR_0014_GOODS :Beni
+STR_0015_GRAIN :Grano
+STR_0016_WOOD :Legname
+STR_0017_IRON_ORE :Minerale Ferroso
+STR_0018_STEEL :Acciaio
+STR_0019_VALUABLES :Valori
+STR_001A_COPPER_ORE :Minerale di Rame
+STR_001B_MAIZE :Mais
+STR_001C_FRUIT :Frutta
+STR_001D_DIAMONDS :Diamanti
+STR_001E_FOOD :Cibo
+STR_001F_PAPER :Carta
+STR_0020_GOLD :Oro
+STR_0021_WATER :Acqua
+STR_0022_WHEAT :Frumento
+STR_0023_RUBBER :Gomma
+STR_0024_SUGAR :Zucchero
+STR_0025_TOYS :Giocattoli
+STR_0026_CANDY :Caramelle
+STR_0027_COLA :Cola
+STR_0028_COTTON_CANDY :Cotone Candito
+STR_0029_BUBBLES :Bolle
+STR_002A_TOFFEE :Toffee
+STR_002B_BATTERIES :Batterie
+STR_002C_PLASTIC :Plastica
+STR_002D_FIZZY_DRINKS :Bibite Frizzanti
+STR_002E :
+STR_002F_PASSENGER :Passeggeri
+STR_0030_COAL :Carbone
+STR_0031_MAIL :Posta
+STR_0032_OIL :Petrolio
+STR_0033_LIVESTOCK :Bestiame
+STR_0034_GOODS :Beni
+STR_0035_GRAIN :Grano
+STR_0036_WOOD :Legname
+STR_0037_IRON_ORE :Minerale Ferroso
+STR_0038_STEEL :Acciaio
+STR_0039_VALUABLES :Valori
+STR_003A_COPPER_ORE :Minerale di Rame
+STR_003B_MAIZE :Mais
+STR_003C_FRUIT :Frutta
+STR_003D_DIAMOND :Diamanti
+STR_003E_FOOD :Cibo
+STR_003F_PAPER :Carta
+STR_0040_GOLD :Oro
+STR_0041_WATER :Acqua
+STR_0042_WHEAT :Frumento
+STR_0043_RUBBER :Gomma
+STR_0044_SUGAR :Zucchero
+STR_0045_TOY :Giocattolo
+STR_0046_CANDY :Caramelle
+STR_0047_COLA :Cola
+STR_0048_COTTON_CANDY :Cotone Candito
+STR_0049_BUBBLE :Bolle
+STR_004A_TOFFEE :Toffee
+STR_004B_BATTERY :Batterie
+STR_004C_PLASTIC :Plastica
+STR_004D_FIZZY_DRINK :Bevande Frizzanti
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} passegger{P o i}
+STR_QUANTITY_COAL :{WEIGHT} di carbone
+STR_QUANTITY_MAIL :{COMMA} sacc{P o hi} postal{P e i}
+STR_QUANTITY_OIL :{VOLUME} di petrolio
+STR_QUANTITY_LIVESTOCK :{COMMA} cap{P o i} di bestiame
+STR_QUANTITY_GOODS :{COMMA} cass{P a e} di beni
+STR_QUANTITY_GRAIN :{WEIGHT} di grano
+STR_QUANTITY_WOOD :{WEIGHT} di legname
+STR_QUANTITY_IRON_ORE :{WEIGHT} di mineral{P e i} ferros{P o i}
+STR_QUANTITY_STEEL :{WEIGHT} di acciaio
+STR_QUANTITY_VALUABLES :{COMMA} bors{P a e} di valori
+STR_QUANTITY_COPPER_ORE :{WEIGHT} di mineral{P e i} di rame
+STR_QUANTITY_MAIZE :{WEIGHT} di mais
+STR_QUANTITY_FRUIT :{WEIGHT} di frutta
+STR_QUANTITY_DIAMONDS :{COMMA} bors{P a e} di diamanti
+STR_QUANTITY_FOOD :{WEIGHT} di cibo
+STR_QUANTITY_PAPER :{WEIGHT} di carta
+STR_QUANTITY_GOLD :{COMMA} bors{P a e} d'oro
+STR_QUANTITY_WATER :{VOLUME} di acqua
+STR_QUANTITY_WHEAT :{WEIGHT} di frumento
+STR_QUANTITY_RUBBER :{VOLUME} di gomma
+STR_QUANTITY_SUGAR :{WEIGHT} di zucchero
+STR_QUANTITY_TOYS :{COMMA} giocattol{P o i}
+STR_QUANTITY_SWEETS :{COMMA} bust{P a e} di caramelle
+STR_QUANTITY_COLA :{VOLUME} di cola
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} di cotone candito
+STR_QUANTITY_BUBBLES :{COMMA} boll{P a e}
+STR_QUANTITY_TOFFEE :{WEIGHT} di toffee
+STR_QUANTITY_BATTERIES :{COMMA} batteri{P a e}
+STR_QUANTITY_PLASTIC :{VOLUME} di plastica
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} bibite frizzanti
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}PS
+STR_ABBREV_COAL :{TINYFONT}CL
+STR_ABBREV_MAIL :{TINYFONT}ML
+STR_ABBREV_OIL :{TINYFONT}OL
+STR_ABBREV_LIVESTOCK :{TINYFONT}LV
+STR_ABBREV_GOODS :{TINYFONT}GD
+STR_ABBREV_GRAIN :{TINYFONT}GR
+STR_ABBREV_WOOD :{TINYFONT}WD
+STR_ABBREV_IRON_ORE :{TINYFONT}OR
+STR_ABBREV_STEEL :{TINYFONT}ST
+STR_ABBREV_VALUABLES :{TINYFONT}VL
+STR_ABBREV_COPPER_ORE :{TINYFONT}CO
+STR_ABBREV_MAIZE :{TINYFONT}MZ
+STR_ABBREV_FRUIT :{TINYFONT}FT
+STR_ABBREV_DIAMONDS :{TINYFONT}DM
+STR_ABBREV_FOOD :{TINYFONT}FD
+STR_ABBREV_PAPER :{TINYFONT}PR
+STR_ABBREV_GOLD :{TINYFONT}GD
+STR_ABBREV_WATER :{TINYFONT}WR
+STR_ABBREV_WHEAT :{TINYFONT}WH
+STR_ABBREV_RUBBER :{TINYFONT}RB
+STR_ABBREV_SUGAR :{TINYFONT}SG
+STR_ABBREV_TOYS :{TINYFONT}TY
+STR_ABBREV_SWEETS :{TINYFONT}SW
+STR_ABBREV_COLA :{TINYFONT}CL
+STR_ABBREV_CANDYFLOSS :{TINYFONT}CF
+STR_ABBREV_BUBBLES :{TINYFONT}BU
+STR_ABBREV_TOFFEE :{TINYFONT}TF
+STR_ABBREV_BATTERIES :{TINYFONT}BA
+STR_ABBREV_PLASTIC :{TINYFONT}PL
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}FZ
+STR_ABBREV_NONE :{TINYFONT}NO
+STR_ABBREV_ALL :{TINYFONT}ALL
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Mappa - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Opzioni di gioco
+STR_00B2_MESSAGE :{YELLOW}Messaggio
+STR_00B3_MESSAGE_FROM :{YELLOW}Messaggio da {STRING}
+STR_POPUP_CAUTION_CAPTION :{WHITE}Attenzione!
+STR_00B4_CAN_T_DO_THIS :{WHITE}Non puoi fare questo....
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Non puoi ripulire l'area....
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Copyright Originale{COPYRIGHT} 1995 Chris Sawyer, Tutti i diritti riservati
+STR_00B7_VERSION :{BLACK}OpenTTD versione {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 Il OpenTTD team
+STR_TRANSLATED_BY :{BLACK} Traduttore/i -
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Esci
+STR_00C8_YES :{BLACK}Sì
+STR_00C9_NO :{BLACK}No
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Sei sicuro di voler uscire dal gioco e tornare a {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Nulla
+STR_00D1_DARK_BLUE :Blu scuro
+STR_00D2_PALE_GREEN :Verde pallido
+STR_00D3_PINK :Rosa
+STR_00D4_YELLOW :Giallo
+STR_00D5_RED :Rosso
+STR_00D6_LIGHT_BLUE :Azzurro
+STR_00D7_GREEN :Verde
+STR_00D8_DARK_GREEN :Verde scuro
+STR_00D9_BLUE :Blu
+STR_00DA_CREAM :Crema
+STR_00DB_MAUVE :Malva
+STR_00DC_PURPLE :Porpora
+STR_00DD_ORANGE :Arancio
+STR_00DE_BROWN :Marrone
+STR_00DF_GREY :Grigio
+STR_00E0_WHITE :Bianco
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Troppi veicoli nel gioco
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Locazione
+STR_00E5_CONTOURS :Contorni
+STR_00E6_VEHICLES :Veicoli
+STR_00E7_INDUSTRIES :Industrie
+STR_00E8_ROUTES :Percorsi
+STR_00E9_VEGETATION :Vegetazione
+STR_00EA_OWNERS :Proprietari
+STR_00EB_ROADS :{BLACK}{TINYFONT}Strade
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Ferrovie
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Stazioni/Aeroporti/Moli
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Edifici/Industrie
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Veicoli
+STR_00F0_100M :{BLACK}{TINYFONT}100m
+STR_00F1_200M :{BLACK}{TINYFONT}200m
+STR_00F2_300M :{BLACK}{TINYFONT}300m
+STR_00F3_400M :{BLACK}{TINYFONT}400m
+STR_00F4_500M :{BLACK}{TINYFONT}500m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Treni
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Veicoli Stradali
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Navi
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Aereo
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Percorsi di trasporto
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Miniera di Carbone
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Centrale Elettrica
+STR_00FC_FOREST :{BLACK}{TINYFONT}Foresta
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}Segheria
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Raffineria
+STR_00FF_FARM :{BLACK}{TINYFONT}Fattoria
+STR_0100_FACTORY :{BLACK}{TINYFONT}Fabbrica
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Stamperia
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Pozzi Petroliferi
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Miniera di Ferro
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Acciaieria
+STR_0105_BANK :{BLACK}{TINYFONT}Banca
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Cartiera
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Miniera d'Oro
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Azienda Alimentare
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Miniera di Diamanti
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Miniera di Rame
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Piantagione di Frutta
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Piantagione di Gomma
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Falda Acquifera
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Cisterna d'Acqua
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}Falegnameria
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Foresta di Cotone Candito
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Fabbrica di Caramelle
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Fattoria delle Batterie
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Pozzi di Cola
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Negozio di Giocattoli
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Fabbrica di Giocattoli
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Sorgenti di Plastica
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Fabbrica di Bevande Friz.
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Generatore di Bolle
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Estrattore di Toffee
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Miniera di Zucchero
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Stazione Ferroviaria
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Area di carico per Camion
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Stazione Bus
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Aeroporto/Eliporto
+STR_011F_DOCK :{BLACK}{TINYFONT}Molo
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Terreno Accidentato
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Terreno Erboso
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Terreno Spoglio
+STR_0123_FIELDS :{BLACK}{TINYFONT}Campi
+STR_0124_TREES :{BLACK}{TINYFONT}Alberi
+STR_0125_ROCKS :{BLACK}{TINYFONT}Roccie
+STR_0126_WATER :{BLACK}{TINYFONT}Acqua
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Senza Proprietario
+STR_0128_TOWNS :{BLACK}{TINYFONT}Città
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Industrie
+STR_012A_DESERT :{BLACK}{TINYFONT}Deserto
+STR_012B_SNOW :{BLACK}{TINYFONT}Neve
+STR_012C_MESSAGE :{WHITE}Messaggio
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Annulla
+STR_012F_OK :{BLACK}OK
+STR_0130_RENAME :{BLACK}Rinomina
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Troppi nomi definiti
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Il nome scelto è già in uso
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...posseduto da {STRING}
+STR_013C_CARGO :{BLACK}Carichi
+STR_013D_INFORMATION :{BLACK}Informazioni
+STR_013E_CAPACITIES :{BLACK}Capienza
+STR_013E_TOTAL_CARGO :{BLACK}Carico totale
+STR_013F_CAPACITY :{BLACK}Capacità: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}Capacità: {LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Carico totale (capacità) di questo treno:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}Nuovo Gioco
+STR_0141_LOAD_GAME :{BLACK}Carica Gioco
+STR_SINGLE_PLAYER :{BLACK}Giocatore singolo
+STR_MULTIPLAYER :{BLACK}Multiplayer
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Dimensioni mappa:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Opzioni di gioco
+
+STR_0150_SOMEONE :qualcuno{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Mappa del mondo
+STR_0152_TOWN_DIRECTORY :Elenco città
+STR_0153_SUBSIDIES :Sussidi
+
+STR_UNITS_IMPERIAL :Imperiale
+STR_UNITS_METRIC :Metrico
+STR_UNITS_SI :SI
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} mph
+STR_UNITS_VELOCITY_METRIC :{COMMA} km/h
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}hp
+STR_UNITS_POWER_METRIC :{COMMA}hp
+STR_UNITS_POWER_SI :{COMMA}kW
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} tonnellat{P a e}
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} tonnellat{P a e}
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} kg
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}gal
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}l
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}m³
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} gallon{P e i}
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} litr{P o i}
+STR_UNITS_VOLUME_LONG_SI :{COMMA} m³
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10³ lbf
+STR_UNITS_FORCE_METRIC :{COMMA} ton. forza
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Grafico profitto operativo
+STR_0155_INCOME_GRAPH :Grafico incassi
+STR_0156_DELIVERED_CARGO_GRAPH :Grafico merce consegnata
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Grafico storico prestazioni
+STR_0158_COMPANY_VALUE_GRAPH :Grafico valore società
+STR_0159_CARGO_PAYMENT_RATES :Grafico % pagamento merce
+STR_015A_COMPANY_LEAGUE_TABLE :Classifica società
+STR_PERFORMANCE_DETAIL_MENU :Dettagli prestazionali
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}Informazioni su OpenTTD
+STR_015C_SAVE_GAME :Salva partita
+STR_015D_LOAD_GAME :Carica partita
+STR_015E_QUIT_GAME :Abbandona partita
+STR_015F_QUIT :Esci
+STR_ABANDON_GAME_QUERY :{YELLOW}Sei sicuro di voler abbandonare la partita in corso?
+STR_0161_QUIT_GAME :{WHITE}Abbandona partita
+STR_SORT_ORDER_TIP :{BLACK}Seleziona ordinamento (discendente/ascendente)
+STR_SORT_CRITERIA_TIP :{BLACK}Seleziona il criterio d'ordinamento
+STR_SORT_BY :{BLACK}Ordina per
+
+STR_SORT_BY_POPULATION :{BLACK}Popolazione
+STR_SORT_BY_PRODUCTION :{BLACK}Produzione
+STR_SORT_BY_TYPE :{BLACK}Tipo
+STR_SORT_BY_TRANSPORTED :{BLACK}Trasportato
+STR_SORT_BY_NAME :{BLACK}Nome
+STR_SORT_BY_DROPDOWN_NAME :Nome
+STR_SORT_BY_DATE :{BLACK}Data
+STR_SORT_BY_NUMBER :Numero
+STR_SORT_BY_PROFIT_LAST_YEAR :Profitto dell'anno scorso
+STR_SORT_BY_PROFIT_THIS_YEAR :Profitto di quest'anno
+STR_SORT_BY_AGE :Età
+STR_SORT_BY_RELIABILITY :Affidabilità
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Tot. capacità per tipo di carico
+STR_SORT_BY_MAX_SPEED :Velocità massima
+STR_SORT_BY_MODEL :Modello
+STR_SORT_BY_VALUE :Valore
+STR_SORT_BY_FACILITY :Tipo di stazione
+STR_SORT_BY_WAITING :Valore merce in attesa
+STR_SORT_BY_RATING_MAX :Rating di merce
+STR_ENGINE_SORT_ENGINE_ID :EngineID (ord. classico)
+STR_ENGINE_SORT_COST :Costo
+STR_ENGINE_SORT_POWER :Potenza
+STR_ENGINE_SORT_INTRO_DATE :Data Introduzione
+STR_ENGINE_SORT_RUNNING_COST :Costi di uso
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Potenza/Costi di uso
+STR_ENGINE_SORT_CARGO_CAPACITY :Capacità Cargo
+STR_NO_WAITING_CARGO :{BLACK}Non c'è nessun tipo di merce in attesa
+STR_SELECT_ALL_FACILITIES :{BLACK}Seleziona tuti i fabbricati
+STR_SELECT_ALL_TYPES :{BLACK}Seleziona tutti i tipi di merce (comprese le merci non in attesa)
+STR_AVAILABLE_ENGINES_TIP :{BLACK}Mostra una lista di motrici disponibili per quel tipo di veicolo
+STR_MANAGE_LIST :{BLACK}Gestisci lista
+STR_MANAGE_LIST_TIP :{BLACK}Manda istruzioni a tutti i veicoli in questa lista
+STR_REPLACE_VEHICLES :Rimpiazza Veicoli
+STR_SEND_TRAIN_TO_DEPOT :Manda al deposito
+STR_SEND_ROAD_VEHICLE_TO_DEPOT :Manda al deposito
+STR_SEND_SHIP_TO_DEPOT :Manda al deposito
+STR_SEND_AIRCRAFT_TO_HANGAR :Manda all'hangar
+STR_SEND_FOR_SERVICING :Manda per manutenzione
+
+############ range for months starts
+STR_0162_JAN :Gen
+STR_0163_FEB :Feb
+STR_0164_MAR :Mar
+STR_0165_APR :Apr
+STR_0166_MAY :Mag
+STR_0167_JUN :Giu
+STR_0168_JUL :Lug
+STR_0169_AUG :Ago
+STR_016A_SEP :Set
+STR_016B_OCT :Ott
+STR_016C_NOV :Nov
+STR_016D_DEC :Dic
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Pausa
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Salva partita, abandona la partita, esci
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Mostra elenco delle stazioni delle società
+STR_0174_DISPLAY_MAP :{BLACK}Mostra mappa
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Mostra mappa, elenco Città
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Mostra elenco città
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Mostra info finanziarie delle società
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Mostra info generali sulle società
+STR_0179_DISPLAY_GRAPHS :{BLACK}Mostra grafici
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Mostra classifica della società
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Mostra elenco dei treni delle società
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Mostra elenco dei veicoli stradali delle società
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Mostra elenco delle navi delle società
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Mostra lista degli aerei delle società
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Avvicina visuale
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Allontana visuale
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Costruisci ferrovie
+STR_0182_BUILD_ROADS :{BLACK}Costruisci strade
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Costruisci moli
+STR_0184_BUILD_AIRPORTS :{BLACK}Costruisci aeroporti
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Pianta alberi, posiziona cartelli ecc...
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Informazioni area terreno
+STR_0187_OPTIONS :{BLACK}Opzioni
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Non puoi cambiare l'intervallo di manutenzione...
+STR_018B_CLOSE_WINDOW :{BLACK}Chiudi finestra
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Nome finestra - trascinala per muovere la finestra
+STR_STICKY_BUTTON :{BLACK} Marca questa finestra come inchiudibile con il tasto 'Chiudi TUTTE le finestre'
+STR_RESIZE_BUTTON :{BLACK}Clicca e trascina per ridimensionare la finestra
+STR_SAVELOAD_HOME_BUTTON :{BLACK}Clicca qui per saltare alla cartella salva/carica di default
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Demolisci edifici ecc... su una casella del terreno
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Abbassa un angolo del terreno
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Alza un angolo del terreno
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Barra di scorrimento - scorre la lista sù/giù
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Barra di scorrimento - scorre la lista sinistra/destra
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Mostra contorni dei terreni sulla mappa
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Mostra veicoli sulla mappa
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Mostra industrie sulla mappa
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Mostra percorsi di viaggio sulla mappa
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Mostra vegetazione sulla mappa
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Mostra proprietari dei terreni sulla mappa
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Visualizza nomi delle città sulla mappa (on/off)
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Profitto quest'anno: {CURRENCY} (anno scorso: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} ann{P o i} ({COMMA})
+STR_AGE_RED :{RED}{COMMA} ann{P o i} ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Veicolo stradale
+STR_019D_AIRCRAFT :Aereo
+STR_019E_SHIP :Nave
+STR_019F_TRAIN :Treno
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} sta diventando vecchio
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} sta diventando molto vecchio
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} è troppo vecchio e necessita di essere rimpiazzato urgentemente
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Info sull'area di terreno
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Costo per ripulirlo: {LTBLUE}N/A
+STR_01A5_COST_TO_CLEAR :{BLACK}Costo per ripulirlo: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :N/A
+STR_01A7_OWNER :{BLACK}Proprietario: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Autorità locale: {LTBLUE}{STRING}
+STR_01A9_NONE :Nessuno
+STR_01AA_NAME :{BLACK}Nome
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1
+STR_01AD_2ND :2
+STR_01AE_3RD :3
+STR_01AF_4TH :4
+STR_01B0_5TH :5
+STR_01B1_6TH :6
+STR_01B2_7TH :7
+STR_01B3_8TH :8
+STR_01B4_9TH :9
+STR_01B5_10TH :10
+STR_01B6_11TH :11
+STR_01B7_12TH :12
+STR_01B8_13TH :13
+STR_01B9_14TH :14
+STR_01BA_15TH :15
+STR_01BB_16TH :16
+STR_01BC_17TH :17
+STR_01BD_18TH :18
+STR_01BE_19TH :19
+STR_01BF_20TH :20
+STR_01C0_21ST :21
+STR_01C1_22ND :22
+STR_01C2_23RD :23
+STR_01C3_24TH :24
+STR_01C4_25TH :25
+STR_01C5_26TH :26
+STR_01C6_27TH :27
+STR_01C7_28TH :28
+STR_01C8_29TH :29
+STR_01C9_30TH :30
+STR_01CA_31ST :31
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Merci accettate: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Jazz Jukebox
+STR_01D3_SOUND_MUSIC :Suoni/musica
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Mostra finestra suoni/musica
+STR_01D5_ALL :{TINYFONT}Tutte
+STR_01D6_OLD_STYLE :{TINYFONT}Vecchio Stile
+STR_01D7_NEW_STYLE :{TINYFONT}Nuovo Stile
+STR_01D8_EZY_STREET :{TINYFONT}Ezy Street
+STR_01D9_CUSTOM_1 :{TINYFONT}Personaliz. 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Personaliz. 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Volume Musica
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Volume Effetti
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MIN ' ' ' ' ' ' MAX
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Torna al brano precedente
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Passa al brano successivo
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Ferma la musica
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Avvia la musica
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Trascina le barre scorrevoli per regolare il volume
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Brano{SETX 88}Titolo
+STR_01E9_SHUFFLE :{TINYFONT}Casuale
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Programma
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Selezione programma musicale
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Indice brani
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Programma - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}Elimina
+STR_01F1_SAVE :{TINYFONT}{BLACK}Salva
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Attuale programma musicale
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Seleziona progrmma 'Tutti i brani'
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Seleziona programma 'vecchio style'
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Seleziona programma 'nuovo style'
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Seleziona programma 'Personaliz. 1' (definito dall'utente)
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Seleziona programma 'Personaliz. 2' (definito dall'utente)
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Elimina programmazioni attuali (solo personalizzato 1 o personalizzato 2)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Salva le impostazioni musicali
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Clicca sul brano per aggiungerlo al programma corrente (solamente personallizzato 1 o personalizzato 2)
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Clicca sul brano per cancellarlo dal programma corrente (solamente personalizzato 1 o personalizzato 2)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Seleziona programmazione casuale on/off
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Mostra finestra 'selezione brani'
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Clicca sul servizio per vedere l'industria/città
+STR_01FE_DIFFICULTY :{BLACK}Difficoltà ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Ultimi messaggi/nuovi rapporti
+STR_0201_MESSAGE_SETTINGS :Impostazioni messaggi
+STR_MESSAGE_HISTORY_MENU :Cronologia messaggi
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Mostra ultimo messaggio/rapporto, mostra impostazione messaggi
+STR_0204_MESSAGE_OPTIONS :{WHITE}Impostazione messaggi
+STR_0205_MESSAGE_TYPES :{BLACK}Tipi di messaggio:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Arrivo del primo veicolo alle stazioni del giocatore
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Arrivo del primo veicolo alle stazioni della concorrenza
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Incidenti / disastri
+STR_0209_COMPANY_INFORMATION :{YELLOW}Informazioni sulle società
+STR_020A_ECONOMY_CHANGES :{YELLOW}Cambiamenti economici
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Avvisi / informazioni sui veicoli del giocatore
+STR_020C_NEW_VEHICLES :{YELLOW}Nuovi veicoli
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Cambiamenti della merce accettata
+STR_020E_SUBSIDIES :{YELLOW}Sussidi
+STR_020F_GENERAL_INFORMATION :{YELLOW}Informazioni generali
+STR_MESSAGES_ALL :{YELLOW}Impostazione per tutti i tipi di messaggio (on/off/sommario)
+STR_MESSAGE_SOUND :{YELLOW}Esegui un suono per i messaggi sommarizzati
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...troppo lontano dalla destinazione precedente
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Le maggiori compagnie che hanno raggiunto il livello {NUM}{}({STRING})
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Classifica società del{NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Uomo d'affari
+STR_0214_ENTREPRENEUR :Imprenditore
+STR_0215_INDUSTRIALIST :Industriale
+STR_0216_CAPITALIST :Capitalista
+STR_0217_MAGNATE :Magnate
+STR_0218_MOGUL :Mogul
+STR_0219_TYCOON_OF_THE_CENTURY :Magnate del secolo
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} raggiunge lo status di '{STRING}'!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} di {COMPANY} raggiunge lo status di '{STRING}'!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Crea Scenario
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Editor Scenario
+STR_0223_LAND_GENERATION :{WHITE}Genera Terreno
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Terreno Casuale
+STR_0227_RESET_LAND :{BLACK}Resetta Terreno
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Aumenta ampiezza del terreno da abbassare/alzare
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Decrementa ampiezza del terreno da abbassare/alzare
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Genera terreno casuale
+STR_022B_RESET_LANDSCAPE :{BLACK}Resetta paesaggio
+STR_022C_RESET_LANDSCAPE :{WHITE}Resetta Paesaggio
+STR_LOAD_GAME_HEIGHTMAP :{WHITE}Usa Heightmap
+STR_LOAD_SCEN_HEIGHTMAP :{BLACK}Usa Heightmap
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Sei sicuro di voler resettare il paesaggio?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Generazione paesaggio
+STR_022F_TOWN_GENERATION :{BLACK}Generazione città
+STR_0230_INDUSTRY_GENERATION :{BLACK}Generazione industrie
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Costruzioni stradali
+STR_0233_TOWN_GENERATION :{WHITE}Generazione Città
+STR_0234_NEW_TOWN :{BLACK}Nuova Città
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Costruisci nuova città
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Non puoi costruire una città qui...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...troppo vicino al bordo della mappa
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...troppo vicino ad un'altra città
+STR_0239_SITE_UNSUITABLE :{WHITE}...sito inadatto
+STR_023A_TOO_MANY_TOWNS :{WHITE}...troppe città
+STR_CANNOT_GENERATE_TOWN :{WHITE}Non puoi costruire nessuna città
+STR_NO_SPACE_FOR_TOWN :{WHITE}...nella mappa non c'è altro spazio
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Incrementa dimensione della città
+STR_023C_EXPAND :{BLACK}Espandi
+STR_023D_RANDOM_TOWN :{BLACK}Città Casuale
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Costruisci città in un luogo casuale
+STR_023F_INDUSTRY_GENERATION :{WHITE}Generazione Industrie
+STR_0240_COAL_MINE :{BLACK}Miniera di Carbone
+STR_0241_POWER_STATION :{BLACK}Centrale Elettrica
+STR_0242_SAWMILL :{BLACK}Segheria
+STR_0243_FOREST :{BLACK}Foresta
+STR_0244_OIL_REFINERY :{BLACK}Raffineria
+STR_0245_OIL_RIG :{BLACK}Piattaforma Petrolifera
+STR_0246_FACTORY :{BLACK}Fabbrica
+STR_0247_STEEL_MILL :{BLACK}Acciaieria
+STR_0248_FARM :{BLACK}Fattoria
+STR_0249_IRON_ORE_MINE :{BLACK}Miniera di Ferro
+STR_024A_OIL_WELLS :{BLACK}Pozzi petroliferi
+STR_024B_BANK :{BLACK}Banca
+STR_024C_PAPER_MILL :{BLACK}Cartiera
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Azienda Alimentare
+STR_024E_PRINTING_WORKS :{BLACK}Tipografia
+STR_024F_GOLD_MINE :{BLACK}Miniera d'Oro
+STR_0250_LUMBER_MILL :{BLACK}Falegnameria
+STR_0251_FRUIT_PLANTATION :{BLACK}Piantagione di Frutta
+STR_0252_RUBBER_PLANTATION :{BLACK}Piantagione di Gomma
+STR_0253_WATER_SUPPLY :{BLACK}Falda Acquifera
+STR_0254_WATER_TOWER :{BLACK}Cisterna d'Acqua
+STR_0255_DIAMOND_MINE :{BLACK}Miniera di Diamanti
+STR_0256_COPPER_ORE_MINE :{BLACK}Miniera di Rame
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Foresta di Cotone Candito
+STR_0258_CANDY_FACTORY :{BLACK}Fabbrica Caramelle
+STR_0259_BATTERY_FARM :{BLACK}Fattoria delle batterie
+STR_025A_COLA_WELLS :{BLACK}Pozzi di Cola
+STR_025B_TOY_SHOP :{BLACK}Negozio di Giocattoli
+STR_025C_TOY_FACTORY :{BLACK}Fabbrica di Giocattoli
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Sorgenti di Plastica
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Fabbrica Bibite Frizzanti
+STR_025F_BUBBLE_GENERATOR :{BLACK}Generatore di Bolle
+STR_0260_TOFFEE_QUARRY :{BLACK}Estrattore di Toffee
+STR_0261_SUGAR_MINE :{BLACK}Miniera di Zucchero
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Costruisci Miniera di Carbone
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Costruisci Centrale Elettrica
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Costruisci Segheria
+STR_0265_PLANT_FOREST :{BLACK}Pianta Foresta
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Costruisci Raffineria
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Costruisci Piattaforma Petrolifera (può essere costruita soltanto vicino al bordo della mappa)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Costruisci Fabbrica
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Costruisci Acciaieria
+STR_026A_CONSTRUCT_FARM :{BLACK}Costruisci Fattoria
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Costruisci Miniera di Ferro
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Costruisci Pozzo Petrolifero
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Costruisci Banca (può essere costruita solo in città con una popolazione maggiori di 1200)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Costruisci Cartiera
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Costruisci Azienda Alimentare
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Costruisci Tipografia
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Costruisci Miniera d'Oro
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Costruisci Banca (può essere costruita solo nelle città)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Costruisci Falegnameria (per tagliare la foresta pluviale e produrre legna)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Pianta Piantagione di Frutta
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Pianta Piantagione di Gomma
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Costruisci Falda Acquifera
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Costruisci Cisterna d'Acqua (può essere costruita solo nelle città)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Costruisci Miniera di Diamanti
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Costruisci Miniera di Rame
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Costruisci Foresta di Cotone Candito
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Costruisci Fabbrica di Caramelle
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Costruisci Fattoria delle Batterie
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Costruisci Pozzi di Cola
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Costruisci Negozio di Giocattoli
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Costruisci Fabbrica di Giocattoli
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Costruisci Sorgenti di Plastica
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Costruisci Fabbrica Bibite Frizzanti
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Costruisci Generatore di Bolle
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Costruisci Estrattore di Toffee
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Costruisci Miniera di Zucchero
+STR_0285_CAN_T_BUILD_HERE :{WHITE}Non puoi costruire {STRING} qui...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...devi costruire prima una città
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...ammessa solo una per città
+STR_0288_PLANT_TREES :{BLACK}Pianta alberi
+STR_0289_PLACE_SIGN :{BLACK}Posiziona cartello
+STR_028A_RANDOM_TREES :{BLACK}Alberi Casuali
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Pianta alberi casualmente nel paesaggio
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Piazza terreno roccioso nel paesaggio
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Piazza faro
+STR_028E_PLACE_TRANSMITTER :{BLACK}Piazza trasmettitore
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Definisce area desertica.{}Clicca premendo CTRL per rimuoverla
+STR_CREATE_LAKE :{BLACK}Definisce area d'acqua.{}Si espande se definita a livello del mare
+STR_0290_DELETE :{BLACK}Elimina
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Elimina completamente questa città
+STR_0292_SAVE_SCENARIO :Salva scenario
+STR_0293_LOAD_SCENARIO :Carica scenario
+STR_0294_QUIT_EDITOR :Esci dall'editor
+STR_0295 :
+STR_0296_QUIT :Esci
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Salva scenario, carica scenario, abbandona l'editore di scenari, esci
+STR_0298_LOAD_SCENARIO :{WHITE}Carica Scenario
+STR_0299_SAVE_SCENARIO :{WHITE}Salva Scenario
+STR_029A_PLAY_SCENARIO :{BLACK}Gioca Scenario
+STR_PLAY_HEIGHTMAP :{BLACK}Gioca Heightmap
+STR_PLAY_HEIGHTMAP_HINT :{BLACK}Inizia un nuovo gioco usando la heightmap come terreno
+STR_QUIT_SCENARIO_QUERY :{YELLOW}Sei sicuro di voler abbondonare questo scenario?
+STR_029C_QUIT_EDITOR :{WHITE}Esci dall'editor
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...può essere costruita solo in città con una popolazione di almeno 1200
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Sposta la data d'inizio indietro di un'anno
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Sposta la data d'inizio avanti di un'anno
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...gli estremi del ponte devono toccare entrambi il terreno
+STR_02A1_SMALL :{BLACK}Piccola
+STR_02A2_MEDIUM :{BLACK}Media
+STR_02A3_LARGE :{BLACK}Grande
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Seleziona dimensione città
+STR_02A5_TOWN_SIZE :{YELLOW}Dimensione città:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Mostra ultimo messaggio o un report
+STR_OFF :No
+STR_SUMMARY :Sommario
+STR_FULL :Completo
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Elenco città
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Nomi veicoli
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Predefiniti
+STR_02BF_CUSTOM :Personalizzati
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Salva i nomi personalizzati
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Selezione nomi personalizzati
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Salva nomi personalizzati dei veicoli
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Opzioni gioco
+STR_02C5_DIFFICULTY_SETTINGS :Impostazioni difficoltà
+STR_02C7_CONFIG_PATCHES :Configura patch
+STR_NEWGRF_SETTINGS :Impostazioni Newgrf
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Mostra nomi città
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Mostra nomi stazioni
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Mostra cartelli
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Waypoints mostrati
+STR_02D0_FULL_ANIMATION :{SETX 12}Animazione completa
+STR_02D2_FULL_DETAIL :{SETX 12}Massimo dettaglio
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Edifici trasparenti
+STR_TRANSPARENT_SIGNS :{SETX 12}Nomi stazioni trasparenti
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Informazioni sull'area
+STR_02D6 :
+STR_CONSOLE_SETTING :Linea di comando
+STR_02D7_SCREENSHOT_CTRL_S :Screenshot (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Screenshot Gigante (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :Info su 'OpenTTD'
+############ range ends here
+
+STR_02DB_OFF :{BLACK}Off
+STR_02DA_ON :{BLACK}On
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Mostra sussidi
+STR_02DD_SUBSIDIES :Sussidi
+STR_02DE_MAP_OF_WORLD :Mappa del mondo
+STR_EXTRA_VIEW_PORT :Mini visuale extra
+STR_SIGN_LIST :Lista cartelli
+STR_02DF_TOWN_DIRECTORY :Elenco città
+STR_TOWN_POPULATION :{BLACK}Popolazione mondiale: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Mini visuale {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Copia nella mini visuale
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Copia la posizione dalla finestra principale alla mini visuale
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Copia dalla mini visuale
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Copia la posizione dalla mini visuale alla finestra principale
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Valuta
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Selezione valuta
+STR_MEASURING_UNITS :{BLACK}Unità di misura
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Selezione unità di misura
+STR_02E6_ROAD_VEHICLES :{BLACK}Veicoli stradali con
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Seleziona lato della strada sul quale devono guidare i veicoli stradali
+STR_02E9_DRIVE_ON_LEFT :Guida a sinistra
+STR_02EA_DRIVE_ON_RIGHT :Guida a destra
+STR_02EB_TOWN_NAMES :{BLACK}Nomi città
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Seleziona il tipo di stile per i nomi delle città
+
+STR_02F4_AUTOSAVE :{BLACK}Salvataggi automatici
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Seleziona intervallo salvataggi automatici
+STR_02F7_OFF :No
+STR_02F8_EVERY_3_MONTHS :Ogni 3 mesi
+STR_02F9_EVERY_6_MONTHS :Ogni 6 mesi
+STR_02FA_EVERY_12_MONTHS :Ogni 12 mesi
+STR_02FB_START_A_NEW_GAME :{BLACK}Inizia un nuovo gioco
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Carica un gioco salvato
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Crea uno scenario personalizzato
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Seleziona giocatore singolo
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Seleziona un gioco multiplayer da 2-8 giocatori
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Mostra opzioni di gioco
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Mostra opzioni difficoltà
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Inizia una partita con uno scenario personalizzato
+STR_0304_QUIT :{BLACK}Esci
+STR_0305_QUIT_OPENTTD :{BLACK}Esci 'OpenTTD'
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...può essere costruito solo in città
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Seleziona paesaggio 'temperato'
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Seleziona paesaggio 'sub-artico'
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Seleziona paesaggio 'sub-tropicale'
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Seleziona paesaggio 'Città dei Giocattoli'
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Finanzia la costruzione di nuove industrie
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Elenco Industrie
+STR_0313_FUND_NEW_INDUSTRY :Finanzia nuove industrie
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Finanzia nuove industrie
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...può essere costruito solo in città
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...può essere costruito solo nella foresta pluviale
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...può essere costruito solo in aree desertiche
+STR_0319_PAUSED :{YELLOW}* * IN PAUSA * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Screenshot salvato con successo come '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}Screenshot non riuscito!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Compra terreno per usi futuri
+STR_032F_AUTOSAVE :{RED}SALVATAGGIO AUTOMATICO...
+STR_SAVING_GAME :{RED}* * SALVATAGGIO PARTITA * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}Salvataggio in corso,{}prego attenderne la fine!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Seleziona il programma 'Ezy Street'
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :Inglese
+STR_TOWNNAME_FRENCH :Francese
+STR_TOWNNAME_GERMAN :Tedesco
+STR_TOWNNAME_ADDITIONAL_ENGLISH :Inglese (Aggiuntivo)
+STR_TOWNNAME_LATIN_AMERICAN :Latino-Americano
+STR_TOWNNAME_SILLY :Stupidi
+STR_TOWNNAME_SWEDISH :Svedese
+STR_TOWNNAME_DUTCH :Olandese
+STR_TOWNNAME_FINNISH :Finlandese
+STR_TOWNNAME_POLISH :Polacco
+STR_TOWNNAME_SLOVAKISH :Slovacco
+STR_TOWNNAME_NORWEGIAN :Norvegese
+STR_TOWNNAME_HUNGARIAN :Ungherese
+STR_TOWNNAME_AUSTRIAN :Austriaci
+STR_TOWNNAME_ROMANIAN :Rumeni
+STR_TOWNNAME_CZECH :Cechi
+STR_TOWNNAME_SWISS :Svizzero
+STR_TOWNNAME_DANISH :Danese
+STR_TOWNNAME_TURKISH :Turco
+STR_TOWNNAME_ITALIAN :Italiano
+STR_TOWNNAME_CATALAN :Catalano
+############ end of townname region
+
+STR_CURR_GBP :Sterlina (£)
+STR_CURR_USD :Dollaro USA ($)
+STR_CURR_EUR :Euro (€)
+STR_CURR_YEN :Yen (Â¥)
+STR_CURR_ATS :Scellino Austriano (ATS)
+STR_CURR_BEF :Franco Belga (BEF)
+STR_CURR_CHF :Franco Svizzero (CHF)
+STR_CURR_CZK :Corona Ceca (CZK)
+STR_CURR_DEM :Marco Tedesco (DEM)
+STR_CURR_DKK :Corona Danese (DKK)
+STR_CURR_ESP :Peseta Spagnola (ESP)
+STR_CURR_FIM :Marco Finlandese(FIM)
+STR_CURR_FRF :Franco Francese(FRF)
+STR_CURR_GRD :Drachma Greca (GRD)
+STR_CURR_HUF :Forint Ungherese (HUF)
+STR_CURR_ISK :Corona Islandese (ISK)
+STR_CURR_ITL :Lira Italiana (ITL)
+STR_CURR_NLG :Fiorino olandese (NLG)
+STR_CURR_NOK :Corona Norvegese (NOK)
+STR_CURR_PLN :Zloty Polacco (PLN)
+STR_CURR_ROL :Leu Rumeno (ROL)
+STR_CURR_RUR :Rublo Russo (RUR)
+STR_CURR_SIT :Tolar Sloveno (SIT)
+STR_CURR_SEK :Corona Svedese (SEK)
+STR_CURR_YTL :Lira Turca (YTL)
+STR_CURR_SKK :Corona Slovacca (SKK)
+STR_CURR_BRR :Real Brasiliano (BRL)
+
+STR_CURR_CUSTOM :Personalizza...
+
+STR_OPTIONS_LANG :{BLACK}Lingua
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Seleziona la lingua da utilizzare
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Schermo intero
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}Barra questa casella per giocare a OpenTTD a schermo intero
+
+STR_OPTIONS_RES :{BLACK}Risoluzione video
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Seleziona la risoluzione video da utilizzare
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Formato screenshot
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Selezionare il formato da usare per le screenshot
+
+STR_AUTOSAVE_1_MONTH :Ogni mese
+STR_AUTOSAVE_FAILED :{WHITE}Salvataggio automatico fallito.
+
+STR_MONTH_JAN :Gennaio
+STR_MONTH_FEB :Febbraio
+STR_MONTH_MAR :Marzo
+STR_MONTH_APR :Aprile
+STR_MONTH_MAY :Maggio
+STR_MONTH_JUN :Giugno
+STR_MONTH_JUL :Luglio
+STR_MONTH_AUG :Agosto
+STR_MONTH_SEP :Settembre
+STR_MONTH_OCT :Ottobre
+STR_MONTH_NOV :Novembre
+STR_MONTH_DEC :Dicembre
+
+STR_HEADING_FOR_STATION :{LTBLUE}Direzione {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}Direzione {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Nessun ordine
+STR_NO_ORDERS_VEL :{LTBLUE}Nessun ordine, {VELOCITY}
+
+STR_PASSENGERS :passeggeri
+STR_BAGS :borse
+STR_TONS :tonnellate
+STR_LITERS :litri
+STR_ITEMS :oggetti
+STR_CRATES :casse
+STR_RES_OTHER :altro
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Non puoi condividere lista ordini...
+STR_CANT_COPY_ORDER_LIST :{WHITE}non puoi copiare la lista ordini...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - Fine degli Ordini Condivisi - -
+
+STR_TRAIN_IS_LOST :{WHITE}Il Treno {COMMA} si è perso.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}Il profitto del treno {COMMA} per l'anno scorso è stato {CURRENCY}
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}Unione Monetaria Europea!{}{}E' stato introdotto l'euro come unica moneta per qualsiasi transazione del tuo Paese!
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Il treno {COMMA} non ha sufficienti ordini pianificati
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}Il treno {COMMA} non ha alcun ordine
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}Il treno {COMMA} ha alcuni ordini duplicati
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}Il treno {COMMA} ha una stazione non valida negli ordini
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}Il veicolo {COMMA} non ha sufficienti ordini pianificati
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}Il veicolo {COMMA} non ha alcun ordine
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}Il veicolo {COMMA} ha alcuni ordini duplicati
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}Il veicolo {COMMA} ha una stazione non valida negli ordini
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}La nave {COMMA} non ha sufficienti ordini pianificati
+STR_SHIP_HAS_VOID_ORDER :{WHITE}La nave {COMMA} non ha alcun ordine
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}La nave {COMMA} ha alcuni ordini duplicati
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}La nave {COMMA} ha un porto non valido negli ordini
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}L'aereo {COMMA} non ha abbastanza ordini pianificati
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}L'aereo {COMMA} ha un ordine vuoto nella lista
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}L'aereo {COMMA} ha alcuni ordini duplicati
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}L'aereo {COMMA} ha un aeroporto non valido negli ordini
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}Rinnovo automatico fallito per il treno {COMMA} (limite fondi)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}Rinnovo automatico fallito per il veicolo {COMMA} (limite fondi)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}Rinnovo automatico fallito per la nave {COMMA} (limite fondi)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}Rinnovo automatico fallito per l'aereo {COMMA} (limite fondi)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}Il treno {COMMA} dopo la sostituzione è diventato troppo lungo
+
+STR_CONFIG_PATCHES :{BLACK}Configura Patch
+STR_CONFIG_PATCHES_TIP :{BLACK}Configura le patch
+STR_CONFIG_PATCHES_CAPTION :{WHITE}Configura Patch
+
+STR_CONFIG_PATCHES_OFF :No
+STR_CONFIG_PATCHES_ON :Si
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Mostra velocità veicoli sulla barra di stato: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Consenti la costruzione sui pendii e coste: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Permetti aree di carico/scarico più realistiche: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Permetti la rimozione di strade, ponti, ecc. appartenuti alle città: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Consenti la costruzione di treni molto lunghi: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Abilita accelerazione realistica per i treni: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Vieta ai treni e navi di fare curve di 90°: {ORANGE}{STRING} {LTBLUE} (Richiede YAPF o NPF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Unisci stazioni ferroviarie quando sono vicine: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Lascia stazione quanto uno dei tipi di merce è a pieno carico: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Usa l'algoritmo di caricamento migliorato: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GRADUAL_LOADING :{LTBLUE}Carica i veicoli gradualmente: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Inflazione: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Scarica le merci in una stazione solo se richieste: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Consenti la costruzione di ponti molto lunghi: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Consenti gli ordini 'vai al deposito': {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Consenti la costruzione di industrie produttrici di materia prima: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Consenti la costruzione di più industrie simili per città: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Consenti la costruzione di industrie uguali anche se molto vicine: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Mostra sempre formato esteso della data nella barra di stato: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Mostra segnali sul lato guida: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Mostra finestra info finanziare alla fine di ogni anno: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}Gestisci funzione 'non-stop' come TTDPatch: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Accoda veicoli stradali quando l'area di carico è occupata: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Scorri orizzontalmente la visuale se il mouse è agli angoli: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Consenti corruzione autorità locale: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Stazioni non uniformi: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Nuovo pathfinding globale (NPF, sovrascrive NTP): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FREIGHT_TRAINS :{LTBLUE}Moltiplicatore di peso per simulare treni pesanti: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Consenti la costruzione piccoli aeroporti: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Avvisa se un treno si è perso: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Controlla gli ordini dei veicoli: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :disabilitato
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :si, ma escludi i veicoli fermi
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :per tutti i veicoli
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Avvisa se i guadagni di un treno sono in negativo: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}I veicoli non invecchiano mai: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Rinnova un veicolo quando diventa datato
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Rinnova un veicolo quando è {ORANGE}{STRING}{LTBLUE} mesi fuori età massima
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Rinnova solo se disponibile il fondo minimo di: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Durata visualizzazione messaggio di errore: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Mostra la popolazione di un paese nell'etichetta: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Alberi invisibili (se edifici trasparenti): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Generatore terreni: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :Originale
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis
+STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}Massima distanza dal bordo per le Raffinerie {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Altezza limite delle nevi perenni: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN :{LTBLUE}Ruvidità del terreno (solo TerraGenesis) : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Molto Morbido
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH :Morbido
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH :Ruvido
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :Molto Ruvido
+STR_CONFIG_PATCHES_TREE_PLACER :{LTBLUE}Algoritmo per il piazzamento di alberi: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TREE_PLACER_NONE :Nessuno
+STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL :Originale
+STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED :Aggiornato
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION :{LTBLUE}Rotazione heightmap: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Antiorario
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE :Orario
+STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT :{LTBLUE}La curva di livello della mappa di uno scenario piano ha : {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Dispersione max. stazione: {ORANGE}{STRING} {RED}Nota: Valore alto rallenta il gioco
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Manutenzione elicotteri direttamente all'eliporto: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Apri strumenti terreno assieme a quelli di costruzione: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Scorri mappa nella direzione opposta a quella del mouse: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Mostra un tooltip di misura durante la costruzione: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Mostra le livree della società: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES_NONE :Nessuna
+STR_CONFIG_PATCHES_LIVERIES_OWN :Propria società
+STR_CONFIG_PATCHES_LIVERIES_ALL :Tutte le società
+STR_CONFIG_PATCHES_PREFER_TEAMCHAT :{LTBLUE}Preferisce team chat con <ENTER>: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Max treni per giocatore: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Max veicoli stradali per giocatore: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}Max aeroplani per giocatore: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}Max navi per giocatore: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Disabilita treni: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Disabilita veicoli stradali: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Disabilita aerei: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Disabilita navi: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Abilita la nuova IA (alpha): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Permetti AI in multiplayer (sperimentale): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Intervallo di servizio predefinito per i treni: {ORANGE}{STRING} giorni
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Intervallo di servizio predefinito per i treni: {ORANGE}disabilitato
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Intervallo di servizio predefinito per i veicoli stradali: {ORANGE}{STRING} giorni
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Intervallo di servizio predefinito per i veicoli stradali: {ORANGE}disabilitato
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Intervallo di servizio predefinito per gli aerei: {ORANGE}{STRING} giorni
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Intervallo di servizio predefinito per gli aerei: {ORANGE}disabilitato
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Intervallo di servizio predefinito per le navi: {ORANGE}{STRING} giorni
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Intervallo di servizio predefinito per le navi: {ORANGE}disabilitato
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Disabilità servicing quando i guasti sono "nessuno": {ORANGE}{STRING}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Abilita limite velocità vagoni: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}Disabilita ferrovie elettrificate: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Notizie colorate appaiono dal: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Data di inizio: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}Concludi il gioco il: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Abilita economia fluida (cambiamenti piccoli e frequenti)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Permetti l'acquisto di azioni da altre compagnie
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Trascinando il cursore costruisci i semafori ogni: {ORANGE}{STRING} quadrato/i
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Posizione barra degli strumenti principale: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Sinistra
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Centro
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Destra
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Raggio di snap delle finestre: {ORANGE}{STRING} px
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Raggio di snap delle finestre: {ORANGE}disabilitato
+
+STR_CONFIG_PATCHES_GUI :{BLACK}Interfaccia
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Costruzione
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Veicoli
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Stazioni
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Economia
+STR_CONFIG_PATCHES_AI :{BLACK}Avversari
+
+STR_CONFIG_PATCHES_DISABLED :disabilitato
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Cambia valori impostazioni
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Alcuni o tutti gli intervalli di servizio predefiniti sottostanti sono incompatibili con le impostazioni scelte! 5-90% e 30-800 giorni sono valori validi
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}Usa YAPF per le navi: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}Usa YAPF per i veicoli stradali: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}Usa YAPF per i treni: {ORANGE}{STRING}
+
+STR_TEMPERATE_LANDSCAPE :paesaggio 'temperato'
+STR_SUB_ARCTIC_LANDSCAPE :paesaggio 'sub-artico'
+STR_SUB_TROPICAL_LANDSCAPE :paesaggio 'sub-tropicale'
+STR_TOYLAND_LANDSCAPE :paesaggio 'Città dei Giocattoli'
+
+STR_CHEATS :{WHITE}Trucchi
+STR_CHEATS_TIP :{BLACK}Le caselle indicano se hai già utilizzato questo trucco in passato
+STR_CHEATS_WARNING :{BLACK}Attenzione! Stai per tradire i tuoi avversari. Ricordati che un così grande disonore verrà ricordato per l'eternità.
+STR_CHEAT_MONEY :{LTBLUE}Aumenta soldi di {CURRENCY64}
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Gioca come giocatore: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Bulldozer magico (rimuove industrie e altri): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}I tunnel possono incrociarsi tra loro: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Consenti costruzione in pausa: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}I jet non si schiantano troppo di frequente nei piccoli aeroporti: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Cambia paesaggio: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Cambia data: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}Permetti la modifica dei valori di produzione: {ORANGE}{STRING}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}Direzione {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Direzione {WAYPOINT}, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :Vai al {WAYPOINT}
+STR_GO_NON_STOP_TO_WAYPOINT :Procedi non-stop per {WAYPOINT}
+
+STR_WAYPOINTNAME_CITY :Waypoint {TOWN}
+STR_WAYPOINTNAME_CITY_SERIAL :Waypoint {TOWN} #{COMMA}
+STR_LANDINFO_WAYPOINT :Waypoint
+
+STR_WAYPOINT :{WHITE}Waypoint
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Seleziona il tipo di waypoint
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}Cambia il nome al waypoint
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Impossibile cambiare il nome al waypoint...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Trasforma la ferrovia in un waypoint
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Impossibile costruire un waypoint ferroviario qui...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Impossibile demolire un waypoint ferroviario qui...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Costruisci binario usando la modalità automatica
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}...non ci sono città in questo scenario
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}Sei sicuro di voler creare un terreno casuale?
+STR_MANY_RANDOM_TOWNS :{BLACK}Alcune città casuali
+STR_RANDOM_TOWNS_TIP :{BLACK}Copri la mappa con città costruite casualmente
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Alcune industrie casuali
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Copri la mappa con industrie costruite casualmente
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Impossibile generare le industrie...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Apri la barra 'Modellazione terreno' per alzare/abbassare il terreno, piantare alberi, ecc.
+STR_LANDSCAPING_TOOLBAR :{WHITE}Modella terreno
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Livella terreno
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Alberi casuali
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}Pianta alberi di tipo casuale
+
+STR_CANT_BUILD_CANALS :{WHITE}Impossibile costruire un canale qui...
+STR_BUILD_CANALS_TIP :{BLACK}Costruisci canali
+STR_LANDINFO_CANAL :Canale
+
+STR_CANT_BUILD_LOCKS :{WHITE}Impossibile costruire una chiusa qui...
+STR_BUILD_LOCKS_TIP :{BLACK}Costruisci chiusa
+STR_LANDINFO_LOCK :Chiusa
+
+STR_BUOY_IS_IN_USE :{WHITE}...la boa è in uso!
+
+STR_LANDINFO_COORDS :{BLACK}Coordinate: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Impossibile demolire una porzione di stazione...
+STR_CANT_CONVERT_RAIL :{WHITE}Impossibile convertire il tipo di rotaie...
+STR_CONVERT_RAIL_TIP :{BLACK}Converti/aggiorna il tipo di rotaie
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Trascina qui la locomotiva per vendere l'intero treno
+
+STR_DRAG_DROP :{BLACK}Drag & Drop
+STR_STATION_DRAG_DROP :{BLACK}Costruisci una stazione con il drag & drop
+STR_SELECT_STATION_CLASS_TIP :{BLACK}Seleziona un tipo di classe di stazione per mostrare
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Scegli il tipo di stazione da costruire
+
+STR_FAST_FORWARD :{BLACK}Aumenta la velocità di gioco
+STR_MESSAGE_HISTORY :{WHITE}Cronologia messaggi
+STR_MESSAGE_HISTORY_TIP :{BLACK}Elenco delle notizie recenti
+STR_MESSAGES_DISABLE_ALL :{BLACK}Disabilita tutti
+STR_MESSAGES_ENABLE_ALL :{BLACK}Abilita tutti
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Costruisci Miniera di Carbone
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Pianta Foresta
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Costruisci Piattaforma Petrolifera
+STR_CONSTRUCT_FARM_TIP :{BLACK}Fonda Fattoria
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Costruisci Miniera di Rame
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Costruisci Pozzo Petrolifero
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Costruisci Miniera d'Oro
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Costruisci Miniera di Diamanti
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Costruisci Miniera di Ferro
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Fonda Piantagione di Frutta
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Fonda Piantagione di Gomma
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Fonda Sorgente di Acqua
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Pianta Foresta di Cotton Candy
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}Fonda Fabbrica di Batterie
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Pozzi di Cola
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Fonda Fontane di Plastica
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Costruisci Generatore di Bolle
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Fonda Toffee Quarry
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Costruisci Raffineria di Zucchero
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Industrie
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA}% trasportato)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA}%/{COMMA}% trasportate)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}...troppo vicina ad un'altra industria.
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Riadatta il treno per trasportare un differente tipo di carico
+STR_RAIL_REFIT_VEHICLE :{BLACK}Riadatta treno
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Seleziona tipo di carico per il treno
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Riadatta il treno per trasportare il tipo di carico selezionato
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Impossibile riadattare il treno...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Gli intervalli di servizio sono in percentuale: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Cambia produzione
+
+TEMP_AI_IN_PROGRESS :{WHITE}Benvenuto nella nuova IA, in sviluppo. Puoi aspettarti dei problemi. Quando succede, fai uno screenshot e invialo sul forum. Divertiti!
+TEMP_AI_ACTIVATED :{WHITE}Attenzione: la nuova IA è ancora in alpha! Solo i Camion e i Bus funzionano, per ora!
+TEMP_AI_MULTIPLAYER :{WHITE}Attenzione: questa funzione è sperimentale. Siete pregati di segnalare i relativi probemi a: truelight@openttd.org.
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Multiplayer
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Nome giocatore:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}Questo è il nome con cui gli altri giocatori ti identificheranno
+STR_NETWORK_CONNECTION :{BLACK}Connessione:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Scegli tra un gioco internet e un gioco in LAN (Local Area Network)
+
+STR_NETWORK_START_SERVER :{BLACK}Avvia server
+STR_NETWORK_START_SERVER_TIP :{BLACK}Avvia il tuo server
+
+STR_NETWORK_GAME_NAME :{BLACK}Nome
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Nome del gioco
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Lingua, versione server, ecc.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Clicca su un nome della lista per selezionarlo
+
+STR_NETWORK_FIND_SERVER :{BLACK}Trova server
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Cerca nella rete un server
+STR_NETWORK_ADD_SERVER :{BLACK}Aggiungi server
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Aggiungi un server alla lista che verrà sempre controllata per giochi attivi.
+STR_NETWORK_ENTER_IP :{BLACK}Digita indirizzo IP del server
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Clients
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Clients online / clients max
+STR_NETWORK_GAME_INFO :{SILVER}INFORMAZIONI PARTITA
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Clients: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Lingua: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Ambiente: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Dimens: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}Versione server: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}Indirizzo del server: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Data di inizio: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Data corrente: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Protetto da password!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}SERVER OFFLINE
+STR_NETWORK_SERVER_FULL :{SILVER}SERVER PIENO
+STR_NETWORK_VERSION_MISMATCH :{SILVER}VERSIONE DIFFERENTE
+STR_NETWORK_GRF_MISMATCH :{SILVER}NEWGRF DISALLINEATA
+
+STR_NETWORK_JOIN_GAME :{BLACK}Entra nel gioco
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}Avvia nuovo gioco
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Nome gioco:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}Il nome della partita verrà visualizzato dagli altri giocatori nel menu di selezione del gioco
+STR_NETWORK_SET_PASSWORD :{BLACK}Imposta password
+STR_NETWORK_PASSWORD_TIP :{BLACK}Proteggi il tuo gioco con una password se non vuoi che altre persone vi entrino
+STR_NETWORK_SELECT_MAP :{BLACK}Seleziona una mappa:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}Con quale mappa vuoi giocare?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}Massimo numero di clients:
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Imposta il numero massimo di clients. Non tutti devono essere riempiti
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :LAN
+STR_NETWORK_INTERNET :Internet
+STR_NETWORK_LAN_INTERNET :LAN / Internet
+STR_NETWORK_INTERNET_ADVERTISE :Internet (avvisa)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 giocatore
+STR_NETWORK_1_PLAYERS :1 giocatore
+STR_NETWORK_2_PLAYERS :2 giocatori
+STR_NETWORK_3_PLAYERS :3 giocatori
+STR_NETWORK_4_PLAYERS :4 giocatori
+STR_NETWORK_5_PLAYERS :5 giocatori
+STR_NETWORK_6_PLAYERS :6 giocatori
+STR_NETWORK_7_PLAYERS :7 giocatori
+STR_NETWORK_8_PLAYERS :8 giocatori
+STR_NETWORK_9_PLAYERS :9 giocatori
+STR_NETWORK_10_PLAYERS :10 giocatori
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}Massimo ditte:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Limitare il server ad un certo numero di ditte
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}Massimo spettatori:
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Limitare il server ad un certo numero di spettatori
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Lingua parlata:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Gli altri giocatori sapranno quale lingua viene parlata sul server
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}Avvia gioco
+STR_NETWORK_START_GAME_TIP :{BLACK}Inizia una nuova partita in rete partendo da una mappa random o da uno scenario
+STR_NETWORK_LOAD_GAME :{BLACK}Carica Gioco
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Riprendi una partita salvata in precedenza (Assicurati di connetterti come il giocatore corretto)
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Qualsiasi
+STR_NETWORK_LANG_ENGLISH :Inglese
+STR_NETWORK_LANG_GERMAN :Tedesco
+STR_NETWORK_LANG_FRENCH :Francese
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Stanza di gioco multiplayer
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}In procinto di entrare: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}Lista di tutte le compagnie attualmente nel gioco. Puoi usare una di queste o fondarne una se c'è un posto libero
+STR_NETWORK_NEW_COMPANY :{BLACK}Nuova compagnia
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Apri una nuova compagnia
+STR_NETWORK_SPECTATE_GAME :{BLACK}Assisti alla partita
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Assisti al gioco come spettatore
+STR_NETWORK_JOIN_COMPANY :{BLACK}Usa compagnia
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Aiuta a controllare questa compagnia
+STR_NETWORK_REFRESH :{BLACK}Ricarica server
+STR_NETWORK_REFRESH_TIP :{BLACK}Ricarica informazioni del server
+
+STR_NETWORK_COMPANY_INFO :{SILVER}INFORMAZIONI COMPAGNIA
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Nome compagnia: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}Inaugurazione: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}Valore compagnia: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Bilancio corrente: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Entrate dell'ultimo anno: {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}Prestazioni: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}Veicoli: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Stazioni: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Giocatori: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}Connessione in corso...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) Connessione..
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Autorizzazione..
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Attendere prego..
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Download mappa..
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Caricamento dei dati..
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) Registrazione..
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Ricezione informazioni gioco..
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Ricezione informazioni compagnia..
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} clients in attesa
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} kbytes scaricati fin'ora
+
+STR_NETWORK_DISCONNECT :{BLACK}Disconnessione
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Inserisci l'ammontare di denaro che vuoi donare
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Server protetto. Inserisci la password
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Compagnia protetta. Inserisci la password
+STR_NETWORK_CLIENT_LIST :{WHITE}Lista dei clients
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE} Nessun dispositivo di rete trovato o compilato senza ENABLE_NETWORK
+STR_NETWORK_ERR_NOSERVER :{WHITE} Impossibile trovare partite in rete
+STR_NETWORK_ERR_NOCONNECTION :{WHITE} Il server non ha risposto alla richiesta
+STR_NETWORK_ERR_DESYNC :{WHITE} Sincronizzazione alla partita in rete fallita.
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} Connessione alla partita in rete persa.
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} Impossibile caricare il savegame dal server.
+STR_NETWORK_ERR_SERVER_START :{WHITE} Impossibile inizializzare il server
+STR_NETWORK_ERR_CLIENT_START :{WHITE} Impossibile connettersi
+STR_NETWORK_ERR_TIMEOUT :{WHITE} Connessione #{NUM} time-out.
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE} Un errore di protocollo ha chiuso la connessione
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE} La revision del client non è la stessa di quella del server
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} Password Errata
+STR_NETWORK_ERR_SERVER_FULL :{WHITE} Il server è pieno
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} Sei stato bannato da questo server
+STR_NETWORK_ERR_KICKED :{WHITE} Sei stato espulso dal gioco
+STR_NETWORK_ERR_CHEATER :{WHITE} I trucchi non sono ammessi su questo server
+
+STR_NETWORK_ERR_LEFT :ha lasciato il gioco
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :errore generale
+STR_NETWORK_ERR_CLIENT_DESYNC :errore di sincronizzazione
+STR_NETWORK_ERR_CLIENT_SAVEGAME :Impossibile caricare la mappa
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :Connessione perduta
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :errore di protocollo
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :Non Autorizzato
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :ricevuto uno strano pacchetto
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :revisione errata
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :nome già in uso
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :game-password errata
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :player-id errato in DoCommand
+STR_NETWORK_ERR_CLIENT_KICKED :Espulso dal server
+STR_NETWORK_ERR_CLIENT_CHEATER :ha provato a usare un trucco
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :server pieno
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :è entrato nel gioco
+STR_NETWORK_GIVE_MONEY :ha donato alla tua compagnia del denaro ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :hai donato a {STRING} del denaro ({CURRENCY})
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Team] :
+STR_NETWORK_CHAT_COMPANY :[Gruppo] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Gruppo] A {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[Privato] :
+STR_NETWORK_CHAT_CLIENT :[Privato] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[Privato] A {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[Tutti] :
+STR_NETWORK_CHAT_ALL :[Tutti] {STRING}: {GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :ha cambiato il suo nome in
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE} Il server ha chiuso la sessione
+STR_NETWORK_SERVER_REBOOT :{WHITE} Il server si sta riavviando...{}Attendere prego...
+
+STR_NETWORK_SERVER :Server
+STR_NETWORK_CLIENT :Client
+STR_NETWORK_SPECTATORS :Spettatori
+
+STR_NETWORK_CLIENTLIST_NONE :(niente)
+STR_NETWORK_CLIENTLIST_KICK :Espelli
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Dona denaro
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Parla a tutti
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Parla alla compagnia
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Messaggio privato
+
+
+STR_NETWORK_SEND :{BLACK}Invia
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}X della mappa: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Y della mappa: {ORANGE}{STRING}
+
+
+##### PNG-MAP-Loader
+
+STR_PNGMAP_ERROR :{WHITE}Non posso caricare il terreno dal PNG...
+STR_PNGMAP_ERR_FILE_NOT_FOUND :{WHITE}...file non trovato.
+STR_PNGMAP_ERR_IMAGE_TYPE :{WHITE}...non posso convertire il tipo di immagine. Richiede immagine PNG 8 o 24-bit.
+STR_PNGMAP_ERR_MISC :{WHITE}...qualcosa è andato male. Spiacente. (probabilimente il file è corrotto)
+
+STR_BMPMAP_ERROR :{WHITE}Non posso caricare il terreno da BMP...
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}...non posso convertire il tipo di immagine.
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Costo: {CURRENCY}
+STR_0801_COST :{RED}Costo: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Incasso: {CURRENCY}
+STR_0803_INCOME :{GREEN}Incasso: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Trasferisci: {CURRENCY}
+STR_FEEDER :{YELLOW}Trasferisci: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Costo Stimato: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Incasso Stimato: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Non puoi alzare terreno qui...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Non puoi abbassare terreno qui...
+STR_080A_ROCKS :Roccie
+STR_080B_ROUGH_LAND :Terreno accidentato
+STR_080C_BARE_LAND :Terreno spoglio
+STR_080D_GRASS :Erba
+STR_080E_FIELDS :Campi
+STR_080F_SNOW_COVERED_LAND :Terreno innevato
+STR_0810_DESERT :Deserto
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Terreno inclinato nella direzione errata
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Combinazione di binari impossibile
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}Gli scavi danneggerebbero la galleria
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Già al livello del mare
+STR_1004_TOO_HIGH :{WHITE}Troppo alto
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Tipo di binari non adatti
+STR_1007_ALREADY_BUILT :{WHITE}...già costruito
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Devi demolire prima i binari
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Costruzione Ferrovie
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Costruzione Ferrovie Elettrificate
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Costruzione Monorotaia
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}Costruzione MagLev
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Seleziona Ponte Ferroviario
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Non puoi costruire deposito qui...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Non puoi costruire stazione qui...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Non puoi piazzare segnali qui..
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Non puoi costruire i binari qui...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Non puoi demolire da qui i binari...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Non puoi rimuovere da qui i segnali...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Orientamento Deposito
+STR_1015_RAILROAD_CONSTRUCTION :Costruzione ferrovie
+STR_TOOLB_ELRAIL_CONSTRUCTION :Costruzione ferrovie elettrificate
+STR_1016_MONORAIL_CONSTRUCTION :Costruzione monorotaia
+STR_1017_MAGLEV_CONSTRUCTION :Costruzione maglev
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Costruisci binari
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Costruisci deposito treni (per costruzione e manutenzione)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Costruisci stazione ferroviaria
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Costruisci segnale ferroviario
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Costruisci ponte ferroviario
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Costruisci tunnel ferroviario
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Seleziona costruisci/demolisci per binari e segnali
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Selezione ponte - clicca sul ponte selezionato per costruirlo
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Seleziona orientamento deposito ferroviario
+STR_1021_RAILROAD_TRACK :Binari
+STR_1023_RAILROAD_TRAIN_DEPOT :Deposito ferroviario
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...area di proprietà di un altra società
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :Binario ferroviario con segnali normali
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :Binario ferroviario con presegnali
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :Binario ferroviario con segnali di uscita
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :Binario ferroviario con segnali combinati
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Devi demolire prima la strada
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Lavori stradali in progresso
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Costruzione Strade
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Seleziona ponte stradale
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Non puoi costruire strada da qui...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Non puoi demolire da qui la strada...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Orientamento Deposito
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Non puoi costruire deposito stradale qui...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Non puoi costruire fermata bus...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Non puoi costruire stazione di carico...
+STR_180A_ROAD_CONSTRUCTION :Costruzione strade
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Costruisci sezione stradale
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Costruisci deposito veicoli stradali (per costruzione e manutenzione)
+STR_180D_BUILD_BUS_STATION :{BLACK}Costruisci fermata bus
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Costruisci stazione di carico
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Costruisci ponte stradale
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Costruisci tunnel stradale
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Seleziona costruisci/demolisci per le costruzioni stradali
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Seleziona orientamento deposito veicoli stradali
+STR_1814_ROAD :Strada
+STR_1815_ROAD_WITH_STREETLIGHTS :Strada con lampioni
+STR_1816_TREE_LINED_ROAD :Strada alberata
+STR_1817_ROAD_VEHICLE_DEPOT :Deposito Veicoli
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :Passaggio a livello
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Città
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}E' necessario demolire prima l'edificio
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}Popolazione: {ORANGE}{COMMA}{BLACK} Case: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Rinomina città
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Non puoi rinominare la città...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}L'autorità locale di {TOWN} non ti autorizza a farlo
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Elenco città - clicca sul nome per centrare la visuale sulla città
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centra la visuale sulla città
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Cambia nome alla città
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passeggeri il mese scorso: {ORANGE}{COMMA}{BLACK} massimo: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Posta il mese scorso: {ORANGE}{COMMA}{BLACK} massimo: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Blocco di uffici alto
+STR_2010_OFFICE_BLOCK :Blocco di uffici
+STR_2011_SMALL_BLOCK_OF_FLATS :Piccolo blocco di appartamenti
+STR_2012_CHURCH :Chiesa
+STR_2013_LARGE_OFFICE_BLOCK :Blocco di uffici grande
+STR_2014_TOWN_HOUSES :Case
+STR_2015_HOTEL :Hotel
+STR_2016_STATUE :Statua
+STR_2017_FOUNTAIN :Fountana
+STR_2018_PARK :Parco
+STR_2019_OFFICE_BLOCK :Blocco di uffici
+STR_201A_SHOPS_AND_OFFICES :Negozi e uffici
+STR_201B_MODERN_OFFICE_BUILDING :Uffici moderni
+STR_201C_WAREHOUSE :Magazzino
+STR_201D_OFFICE_BLOCK :Blocco di uffici
+STR_201E_STADIUM :Stadio
+STR_201F_OLD_HOUSES :Case antiche
+STR_2020_LOCAL_AUTHORITY :{BLACK}Autorità locale
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Mostra informazioni sull'autorità locale
+STR_2022_LOCAL_AUTHORITY :{WHITE}Autorità locale di {TOWN}
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Valutazione servizi di trasporto delle società:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Sussidi
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Sussidi offerti per il servizio:
+STR_2027_FROM_TO :{ORANGE}{STRING} da {STRING} a {STRING}
+STR_2028_BY :{YELLOW} (del {DATE_SHORT})
+STR_202A_NONE :{ORANGE}Nessuno
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Servizi già sussidiati:
+STR_202C_FROM_TO :{ORANGE}{STRING} da {STATION} a {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, fino al {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}Offerta di sussidio scaduta:{}{}{STRING} da {STRING} a {STRING} non sarà più sovvenzionato.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Sussidio terminato:{}{}servizio di {STRING} da {STATION} a {STATION} non è più sovvenzionato.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Offerta di sussidio:{}{}Primo servizio di {STRING} da {STRING} a {STRING} riceverà un'anno di sussidio dall'autorità locale!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Sussidio aggiudicato da {COMPANY}!{}{}servizio di {STRING} da {STATION} a {STATION} verrà pagato il 50% in più per il prossimo anno!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Sussidio aggiudicato da {COMPANY}!{}{}servizio di {STRING} da {STATION} a {STATION} verrà pagato il doppio per il prossimo anno!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Sussidio aggiudicato da {COMPANY}!{}{}servizio di {STRING} da {STATION} a {STATION} verrà pagato il triplo per il prossimo anno!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Sussidio aggiudicato da {COMPANY}!{}{}servizio di {STRING} da {STATION} a {STATION} verrà pagato il quadruplo per il prossimo anno!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}L'autorita locale di {TOWN} rifiuta la costruzione di un altro areoporto nella città
+STR_2036_COTTAGES :Cottage
+STR_2037_HOUSES :Case
+STR_2038_FLATS :Appartamenti
+STR_2039_TALL_OFFICE_BLOCK :Blocco di uffici alto
+STR_203A_SHOPS_AND_OFFICES :Negozi e uffici
+STR_203B_SHOPS_AND_OFFICES :Negozi e uffici
+STR_203C_THEATER :Teatro
+STR_203D_STADIUM :Stadio
+STR_203E_OFFICES :Offici
+STR_203F_HOUSES :Case
+STR_2040_CINEMA :Cinema
+STR_2041_SHOPPING_MALL :Centro commerciale
+STR_2042_DO_IT :{BLACK}Fallo!
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}Lista azioni eseguibili in questa città - clicca sopra per i dettagli
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Trascina l'azione evidenziata nella lista sovrastante
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Azioni disponibili:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Piccola campagna pubblicitaria
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Campagna pubblicitaria media
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Grande campagna pubblicitaria
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Finanzia ricostruzione delle strade locali
+STR_204A_BUILD_STATUE_OF_COMPANY :Costruisci statua del proprietario della società
+STR_204B_FUND_NEW_BUILDINGS :Finanzia nuove costruzioni
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Compra l'esclusiva sui trasporti
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Corrompi l'autorità locale
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Inizia una piccola campagnia pubblicitaria per attirare più gente e merci ai tuoi servizi di trasporto.{} Costo: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Inizia una media campagnia pubblicitaria per attirare più gente e merci ai tuoi servizi di trasporto.{} Costo: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Inizia una grande campagnia pubblicitaria per attirare più gente e cargo ai tuoi servizi di trasporto.{} Costo: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} Finanzia la ricostruzione della rete stradale cittadina. Causa un cosiderabile disagio al traffico stradale per 6 mesi.{} Costo: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Costruisci una statua in onore della tua società.{} Costo: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Finanzia la costruzione di nuove strutture commerciali nella città.{} Costo: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Compra un anno di esclusiva sui trasporti nella città. Compra 1 anno di esclusiva sui diritti di trasporto in città. L'autorità cittadina autorizzerà passeggeri e merci a usare solo le tue stazioni.{} Costo: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Corrompi l'autorità locale per incrementare la tua valutazione con il rischio di una severa multa se scoperto.{} Costo: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}Traffico nel caos a {TOWN}!{}{}La ricostruzione stradale finanziata da {COMPANY} porterà 6 mesi di disagio agli automobilisti!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (in costruzione)
+STR_2059_IGLOO :Igloo
+STR_205A_TEPEES :Tepees
+STR_205B_TEAPOT_HOUSE :Casa-teiera
+STR_205C_PIGGY_BANK :Banca-porcellino
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN} {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Modellazione terreno
+STR_2800_PLANT_TREES :Pianta alberi
+STR_2801_PLACE_SIGN :Posiziona cartello
+STR_2802_TREES :{WHITE}Alberi
+STR_2803_TREE_ALREADY_HERE :{WHITE}...albero già qui
+STR_2804_SITE_UNSUITABLE :{WHITE}...sito inadatto
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Non puoi piantare albero qui...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...troppi cartelli
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Non puoi piazzare un cartello qui...
+STR_280A_SIGN :Cartello
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Modifica testo del cartello
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Non puoi modificare il testo del cartello...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Seleziona il tipo di albero da piantare
+STR_280E_TREES :Alberi
+STR_280F_RAINFOREST :Foresta pluviale
+STR_2810_CACTUS_PLANTS :Cactus
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Selezione Stazione
+STR_3001_AIRPORT_SELECTION :{WHITE}Selezione Aeroporto
+STR_3002_ORIENTATION :{BLACK}Orientamento
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Numero binari
+STR_3004_PLATFORM_LENGTH :{BLACK}Lunghezza
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Troppo vicino a un'altra stazione
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Unisci stazione esistente/area di carico
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}Troppe stazioni/aree di carico in questa città
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}Troppe stazioni/aree di carico
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Troppe fermate dell'autobus
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}Troppe stazioni merci
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Troppo vicino ad un'altra stazione/Area di carico
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Devi demolire prima la stazione ferroviaria
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Troppo vicino ad un altro aeroporto
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Devi demolire prima l'aeroporto
+
+STR_3030_RENAME_STATION_LOADING :Rinomina stazione/area di carico
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Non puoi rinominare stazione...
+STR_3032_RATINGS :{BLACK}Valutazione
+STR_3033_ACCEPTS :{BLACK}Accetta
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}Valutazione del servizio trasporti locale
+
+############ range for rating starts
+STR_3035_APPALLING :Terribile
+STR_3036_VERY_POOR :Molto scarso
+STR_3037_POOR :Scarso
+STR_3038_MEDIOCRE :Mediocre
+STR_3039_GOOD :Buono
+STR_303A_VERY_GOOD :Molto buono
+STR_303B_EXCELLENT :Eccellente
+STR_303C_OUTSTANDING :Eccezionale
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} non accetta più {STRING}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} non accetta più {STRING} o {STRING}
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} adesso accetta {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} adesso accetta {STRING} e {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Orientamento fermata
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Orient. Stazione Camion
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Devi demolire prima la stazione bus
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Devi demolire prima la stazione camion
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Stazion{P e i}
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Nulla -
+STR_304B_SITE_UNSUITABLE :{WHITE}...sito inadatto
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Troppo vicino a un'altro molo
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Devi demolire il molo prima
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Seleziona orientamento della stazione ferroviaria
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Seleziona numero di binari della stazione
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Seleziona lunghezza della stazione
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Seleziona orientamento stazione bus
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Seleziona orientamento stazione camion
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Centra visuale sulla stazione
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Mostra valutazione servizio
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Cambia il nome della stazione
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Mostra la lista delle merci accettate
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Nomi stazioni - clicca sul nome per centrare la visuale sulla stazione
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Seleziona dimensione/tipo di aeroporto
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :Stazione ferroviaria
+STR_305F_AIRCRAFT_HANGAR :Hangar
+STR_3060_AIRPORT :Aeroporto
+STR_3061_TRUCK_LOADING_AREA :Area di carico per camion
+STR_3062_BUS_STATION :Fermata bus
+STR_3063_SHIP_DOCK :Molo
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Evidenzia l'area di copertura del sito proposto
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Non evidenziare l'area di copertura del sito proposto
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Evidenzia area coperta
+STR_3068_DOCK :{WHITE}Molo
+STR_3069_BUOY :Boa
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...boa in mezzo
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...stazione troppo estesa
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...stazioni non uniformi disabilitate
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Tenere premuto CTRL per scegliere più di un oggetto
+
+STR_UNDEFINED :(stringa non definita)
+STR_STAT_CLASS_DFLT :Stazione predefinita
+STR_STAT_CLASS_WAYP :Waypoint
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Orientamento Deposito Navale
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...deve essere costruito sull'acqua
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Non puoi costruire deposito navale qui...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Seleziona orientamento del deposito navale
+STR_3804_WATER :Acqua
+STR_3805_COAST_OR_RIVERBANK :Costa
+STR_3806_SHIP_DEPOT :Deposito navale
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...non puoi costruire sull'acqua
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Salva partita
+STR_4001_LOAD_GAME :{WHITE}Carica partita
+STR_4002_SAVE :{BLACK}Salva
+STR_4003_DELETE :{BLACK}Elimina
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} megabyte liberi
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Impossibile leggere dal disco
+STR_4007_GAME_SAVE_FAILED :{WHITE}Salvataggio fallito
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Impossibile eliminare il file
+STR_4009_GAME_LOAD_FAILED :{WHITE}Caricamento fallito
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}Elenco unità disco, cartelle e file save-game
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Nome correntemente scelto per il salvataggio
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Elimina il gioco salvato selezionato
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}salva il gioco corrente usando il nome selezionato
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Selezione il tipo di gioco
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Seleziona scenario (verde), Partita pre-impostata (blu),Scenario casuale
+STR_4010_GENERATE_RANDOM_NEW_GAME :Crea partita casuale
+STR_4011_LOAD_HEIGHTMAP :{WHITE}Carica Heightmap
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} in mezzo
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :Miniera di Carbone
+STR_4803_POWER_STATION :Centrale Elettrica
+STR_4804_SAWMILL :Segheria
+STR_4805_FOREST :Foresta
+STR_4806_OIL_REFINERY :Raffineria
+STR_4807_OIL_RIG :Piattaforma Petrolifera
+STR_4808_FACTORY :Fabbrica
+STR_4809_PRINTING_WORKS :Tipografia
+STR_480A_STEEL_MILL :Acciaieria
+STR_480B_FARM :Fattoria
+STR_480C_COPPER_ORE_MINE :Miniera di Rame
+STR_480D_OIL_WELLS :Pozzi Petroliferi
+STR_480E_BANK :Banca
+STR_480F_FOOD_PROCESSING_PLANT :Azienda Alimentare
+STR_4810_PAPER_MILL :Cartiera
+STR_4811_GOLD_MINE :Miniera d'Oro
+STR_4812_BANK :Banca
+STR_4813_DIAMOND_MINE :Miniera di Diamanti
+STR_4814_IRON_ORE_MINE :Miniera di Ferro
+STR_4815_FRUIT_PLANTATION :Piantagione di Frutta
+STR_4816_RUBBER_PLANTATION :Piantagione di Gomma
+STR_4817_WATER_SUPPLY :Falda Acquifera
+STR_4818_WATER_TOWER :Cisterna d'Acqua
+STR_4819_FACTORY :Fabbrica
+STR_481A_FARM :Fattoria
+STR_481B_LUMBER_MILL :Falegnameria
+STR_481C_COTTON_CANDY_FOREST :Foresta Cotone Candito
+STR_481D_CANDY_FACTORY :Fabbrica Caramelle
+STR_481E_BATTERY_FARM :Fattoria delle Batterie
+STR_481F_COLA_WELLS :Pozzi di Cola
+STR_4820_TOY_SHOP :Negozio di Giocattoli
+STR_4821_TOY_FACTORY :Fabbrica di Giocattoli
+STR_4822_PLASTIC_FOUNTAINS :Sorgenti di Plastica
+STR_4823_FIZZY_DRINK_FACTORY :Fabbrica Bevande Frizzanti
+STR_4824_BUBBLE_GENERATOR :Generatore di Bolle
+STR_4825_TOFFEE_QUARRY :Estrattore di Toffee
+STR_4826_SUGAR_MINE :Miniera di Zucchero
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Richiede: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Richiede: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Richiede: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Produzione ultimo mese:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% trasportato)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centra visule sull'industria
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Nuova {STRING} in costruzione vicino a {TOWN}!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Nuova {STRING} è stata piantata vicino a {TOWN}!
+STR_482F_COST :{BLACK}Costo: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Non puoi costruire tipo di industria qui...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...la foresta può essere piantata solo in una zona innevata
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} annuncia imminente chiusura!!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}Per problemi di rifornimenti {INDUSTRY} annuncia imminente chiusura!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}La mancanza di alberi vicini costringe {INDUSTRY} ad imminente chiusura!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} incrementa la produzione!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}Nuovo giacimento di carbone trovato a {INDUSTRY}!{}Produzione destinata a duplicare!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}Nuovo giacimento di petrolio trovato a {INDUSTRY}!{}Produzione destinata a duplicare!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}Metodi di coltivazione migliorati a {INDUSTRY} produzione destinata a duplicare!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}{INDUSTRY} produzione scesa del 50%
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}Invasione d'insetti causa devastazione a {INDUSTRY}!{}Produzione scesa del 50%
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...può essere posizionata solo vicino al bordo della mappa
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}La produzione di {STRING} a {INDUSTRY} è aumentata del {COMMA}%!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}La produzione di {STRING} a {INDUSTRY} è diminuita del {COMMA}%!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Treno nel tunnel
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Veicolo nel tunnel
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Altro tunnel in mezzo
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Impossibile scavare l'uscita del tunnel
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Devi demolire il tunnel prima
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Devi demolire il ponte prima
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Non si può partire e finire nello stesso punto
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Sotto i ponti è richiesto terreno piano o acqua
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}Inizio e fine devono essere allineati
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Sito inadatto per l'entrata del tunnel
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Sospeso in Acciaio
+STR_500F_GIRDER_STEEL :In Acciaio
+STR_5010_CANTILEVER_STEEL :In travi d'acciaio
+STR_5011_SUSPENSION_CONCRETE :Sospeso in Cemento
+STR_5012_WOODEN :Di legno
+STR_5013_CONCRETE :In cemento
+STR_5014_TUBULAR_STEEL :Tubolare, Acciaio
+STR_BRIDGE_TUBULAR_SILICON :Tubolare, Silicio
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Non puoi costruire ponte qui...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Non puoi costruire tunnel qui...
+STR_5017_RAILROAD_TUNNEL :Tunnel ferroviario
+STR_5018_ROAD_TUNNEL :Tunnel stradale
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Ponte ferroviario sospeso in acciaio
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Ponte ferroviario in acciaio
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Ponte ferroviario in travi d'acciaio
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Ponte ferroviario sospeso in cemento armato
+STR_501F_WOODEN_RAIL_BRIDGE :Ponte ferroviario in legno
+STR_5020_CONCRETE_RAIL_BRIDGE :Ponte ferroviario in cemento
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Ponte stradale sopeso in acciaio
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Ponte stradale in acciaio
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Ponte stradale in travi d'acciaio
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Ponte stradale sospeso in cemento armato
+STR_5025_WOODEN_ROAD_BRIDGE :Ponte stradale in legno
+STR_5026_CONCRETE_ROAD_BRIDGE :Ponte stradale in cemento
+STR_5027_TUBULAR_RAIL_BRIDGE :Ponte ferroviario tubolare
+STR_5028_TUBULAR_ROAD_BRIDGE :Ponte stradale tubolare
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Oggetto in mezzo
+STR_5801_TRANSMITTER :Trasmettitore
+STR_5802_LIGHTHOUSE :Faro
+STR_5803_COMPANY_HEADQUARTERS :Sede della società
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...Sede principale della società in mezzo
+STR_5805_COMPANY_OWNED_LAND :Terreno posseduto dalla società
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Non puoi acquistare questo terreno...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...lo possiedi già!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Senza nome
+STR_SV_TRAIN_NAME :Treno {COMMA}
+STR_SV_ROADVEH_NAME :Veicolo Stradale {COMMA}
+STR_SV_SHIP_NAME :Nave {COMMA}
+STR_SV_AIRCRAFT_NAME :Aereo {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :{STRING} Nord
+STR_SV_STNAME_SOUTH :{STRING} Sud
+STR_SV_STNAME_EAST :{STRING} Est
+STR_SV_STNAME_WEST :{STRING} Ovest
+STR_SV_STNAME_CENTRAL :{STRING} Centrale
+STR_SV_STNAME_TRANSFER :{STRING} Interscambio
+STR_SV_STNAME_HALT :{STRING} Fermata
+STR_SV_STNAME_VALLEY :{STRING} Valle
+STR_SV_STNAME_HEIGHTS :{STRING} Altura
+STR_SV_STNAME_WOODS :{STRING} Bosco
+STR_SV_STNAME_LAKESIDE :{STRING} Lago
+STR_SV_STNAME_EXCHANGE :{STRING} Scambio
+STR_SV_STNAME_AIRPORT :{STRING} Aeroporto
+STR_SV_STNAME_OILFIELD :{STRING} Campo Petrolifero
+STR_SV_STNAME_MINES :{STRING} Miniere
+STR_SV_STNAME_DOCKS :{STRING} Molo
+STR_SV_STNAME_BUOY_1 :{STRING} Boa 1
+STR_SV_STNAME_BUOY_2 :{STRING} Boa 2
+STR_SV_STNAME_BUOY_3 :{STRING} Boa 3
+STR_SV_STNAME_BUOY_4 :{STRING} Boa 4
+STR_SV_STNAME_BUOY_5 :{STRING} Boa 5
+STR_SV_STNAME_BUOY_6 :{STRING} Boa 6
+STR_SV_STNAME_BUOY_7 :{STRING} Boa 7
+STR_SV_STNAME_BUOY_8 :{STRING} Boa 8
+STR_SV_STNAME_BUOY_9 :{STRING} Boa 9
+STR_SV_STNAME_ANNEXE :{STRING} Annesso
+STR_SV_STNAME_SIDINGS :{STRING} Raccordo
+STR_SV_STNAME_BRANCH :{STRING} Ramo
+STR_SV_STNAME_UPPER :Alta {STRING}
+STR_SV_STNAME_LOWER :Bassa {STRING}
+STR_SV_STNAME_HELIPORT :{STRING} Eliporto
+STR_SV_STNAME_FOREST :{STRING} Foresta
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Livello di difficoltà
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Salva
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Facile
+STR_6802_MEDIUM :{BLACK}Medio
+STR_6803_HARD :{BLACK}Difficile
+STR_6804_CUSTOM :{BLACK}Personalizzato
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}Numero max di avversari: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Partenza avversari: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}Num. di città: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}Num. di industrie: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Prestito iniziale massimo: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Tasso d'interesse iniziale: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Costi di uso dei veicoli: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Velocità di costruzione degli avversari: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Intelligenza degli avversari: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Guasti dei veicoli: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Moltiplicatore sussidi: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Costi di costruzione: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Tipo di terreno: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Quantità mare/laghi: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Economia: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Inversione treni: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Disastri: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Atteggiamento delle città alle modifiche: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :Nessuno
+STR_6816_LOW :Basso
+STR_6817_NORMAL :Normale
+STR_6818_HIGH :Alto
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Molto lenta
+STR_681C_SLOW :Lenta
+STR_681D_MEDIUM :Media
+STR_681E_FAST :Veloce
+STR_681F_VERY_FAST :Molto veloce
+STR_VERY_LOW :Molto basso
+STR_6820_LOW :Basso
+STR_6821_MEDIUM :Medio
+STR_6822_HIGH :Alto
+STR_6823_NONE :Nessuno
+STR_6824_REDUCED :Ridotto
+STR_6825_NORMAL :Normale
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Molto pianeggiante
+STR_682B_FLAT :Pianeggiante
+STR_682C_HILLY :Collinoso
+STR_682D_MOUNTAINOUS :Montagnoso
+STR_682E_STEADY :Stabile
+STR_682F_FLUCTUATING :Fluttuante
+STR_6830_IMMEDIATE :Immediatamente
+STR_6831_3_MONTHS_AFTER_PLAYER :3 mesi dopo il giocatore
+STR_6832_6_MONTHS_AFTER_PLAYER :6 mesi dopo il giocatore
+STR_6833_9_MONTHS_AFTER_PLAYER :9 mesi dopo il giocatore
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :Alla fine della linea, e alle stazioni
+STR_6835_AT_END_OF_LINE_ONLY :Solo alla fine della linea
+STR_6836_OFF :No
+STR_6837_ON :Si
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Mostra punteggi migliori
+STR_6839_PERMISSIVE :Permissivo
+STR_683A_TOLERANT :Tollerante
+STR_683B_HOSTILE :Ostile
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Giocatore {COMMA})
+STR_7004_NEW_FACE :{BLACK}Nuova Faccia
+STR_7005_COLOR_SCHEME :{BLACK}Colore Società
+STR_7006_COLOR_SCHEME :{GOLD}Colore Società:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Nuovo Colore Società
+STR_7008_COMPANY_NAME :{BLACK}Nome Società
+STR_7009_PRESIDENT_NAME :{BLACK}Nome Presidente
+STR_700A_COMPANY_NAME :Nome della società
+STR_700B_PRESIDENT_S_NAME :Nome del presidente
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Non puoi cambiare il nome della società...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Non puoi cambiare in nome del presidente...
+STR_700E_FINANCES :{WHITE}{COMPANY} Finanze {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Spese/Ricavi
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Costruzioni
+STR_7012_NEW_VEHICLES :{GOLD}Nuovi Veicoli
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Costi Uso Treni
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Costi Uso Veicoli
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Costi Uso Aerei
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Costi Uso Navi
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Manutenzione Proprietà
+STR_7018_TRAIN_INCOME :{GOLD}Ricavi Treni
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Ricavi Veicoli
+STR_701A_AIRCRAFT_INCOME :{GOLD}Ricavi Aerei
+STR_701B_SHIP_INCOME :{GOLD}Ricavi Navi
+STR_701C_LOAN_INTEREST :{GOLD}Interessi sul Prestito
+STR_701D_OTHER :{GOLD}Altro
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Totale:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Grafico Incassi
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Grafico Profitti Operativi
+STR_7026_BANK_BALANCE :{WHITE}Bilancio Bancario
+STR_7027_LOAN :{WHITE}Prestito
+STR_MAX_LOAN :{WHITE}Prestito Massimo: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}Richiedi {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Ripaga {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...il prestito massimo concesso è di {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Non puoi chiedere altro denaro...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...debito già estinto
+STR_702E_REQUIRED :{WHITE}...{CURRENCY} richiesti
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Non puoi ripagare il debito...
+STR_INSUFFICIENT_FUNDS :{WHITE}Non è possibile donare denaro, è in prestito dalla banca
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Seleziona una nuova faccia per il presidente
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Cambia colore dei veicoli della società
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Cambia il nome del presidente
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Cambia il nome della compagnia
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Fare clic per selezionare il nuovo colore
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Aumenta dimensioni del debito
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Ripaga parte del debito
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(President)
+STR_7038_INAUGURATED :{GOLD}Inaugurata: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Veicoli:
+STR_TRAINS :{WHITE}{COMMA} tren{P o i}
+STR_ROAD_VEHICLES :{WHITE}{COMMA} veicol{P o i} stradal{P e i}
+STR_AIRCRAFT :{WHITE}{COMMA} aere{P o i}
+STR_SHIPS :{WHITE}{COMMA} nav{P e i}
+STR_7042_NONE :{WHITE}Nessuno
+STR_7043_FACE_SELECTION :{WHITE}Seleziona Faccia
+STR_7044_MALE :{BLACK}Maschio
+STR_7045_FEMALE :{BLACK}Femmina
+STR_7046_NEW_FACE :{BLACK}Nuova Faccia
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Annulla selezione Faccia
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Accetta nuova Faccia
+STR_7049_SELECT_MALE_FACES :{BLACK}Seleziona volti maschili
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Seleziona volti femminili
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Genera faccia a caso
+STR_704C_KEY :{BLACK}Chiavi
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Mostra chiave del grafico
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Chiave del grafico società
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Clicca qui per selezionare entrata nel grafico della società on/off
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Unità di merce trasportata
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Valutazione prestazioni società (Massima valutazione=1000)
+STR_7052_COMPANY_VALUES :{WHITE}Valore della società
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Classifica società
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}Società di trasporti in difficolta!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} verrà venduta o dichiarerà bancarotta a meno che le prestazioni non miglioreranno presto!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(Presidente)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Fusione tra società di trasporti
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} è stata venduta a {COMPANY} per {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Stiamo cercando una società di trasporti per vendere la nostra società.{}{} Vorrebbe acquistare {COMPANY} per {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Bancarotta!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} è stata chiusa dai creditori e tutti i suoi beni venduti!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}Lanciata nuova società di trasporti!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} inizia a costruire vicino a {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Non puoi comprare la società...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Percentuale Pagamento Merci
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Giorni di viaggio
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Pagamento per la consegna di dieci unità (o 10,000 litri) di merce alla distanza di 20 quadrati
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Seleziona grafico tipo di merce on/off
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Ingegnere
+STR_7067_TRAFFIC_MANAGER :Direttore del traffico
+STR_7068_TRANSPORT_COORDINATOR :Coordinatore dei Trasporti
+STR_7069_ROUTE_SUPERVISOR :Supervisore dei Percorsi
+STR_706A_DIRECTOR :Direttore
+STR_706B_CHIEF_EXECUTIVE :Amministratore Delegato
+STR_706C_CHAIRMAN :Direttore Esecutivo
+STR_706D_PRESIDENT :Presidente
+STR_706E_TYCOON :Magnate
+STR_706F_BUILD_HQ :{BLACK}Costr. Sede
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Costruisci/Guarda la sede della società
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Sposta la sede della compagnia pagando 1% del valore societario
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Non puoi costruire la sede della compagnia...
+STR_7072_VIEW_HQ :{BLACK}Guarda Sede
+STR_RELOCATE_HQ :{BLACK}Sposta Sede
+STR_COMPANY_PASSWORD :{BLACK}Password
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Protegge la tuo compagnia con una password per impedire accessi non autorizzati.
+STR_SET_COMPANY_PASSWORD :Imposta password della compagnia
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}Recessione Mondiale!{}{}Gli esperti finanziari temono la peggior crisi economica!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Recessione Finita!{}{}Rialzo negli scambi dà fiducia alle industrie per un rafforzamento economico!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Seleziona dimensione grande/piccola della finestra
+STR_7076_COMPANY_VALUE :{GOLD}Valore società: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Compra il 25% delle azioni
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Vendi il 25% delle azioni
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Compra il 25% delle azioni della società
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Vendi il 25% delle azioni della società
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Non puoi comprare il 25% delle azioni della società...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}Non puoi vendere il 25% delle azioni della società...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% posseduto da {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% posseduto da {COMPANY}{} {COMMA}% posseduto da {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} è stata rilevata da {COMPANY}!
+STR_7080_PROTECTED :{WHITE}Questa compagnia non è abbastanza vecchia per scambiare azioni...
+
+STR_LIVERY_DEFAULT :Livrea Standard
+STR_LIVERY_STEAM :Locomotiva a Vapore
+STR_LIVERY_DIESEL :Locomotiva Diesel
+STR_LIVERY_ELECTRIC :Locomotore Elettrico
+STR_LIVERY_MONORAIL :Monorotaia
+STR_LIVERY_MAGLEV :Maglev
+STR_LIVERY_DMU :DMU
+STR_LIVERY_EMU :EMU
+STR_LIVERY_PASSENGER_WAGON_STEAM :Carrozza Passeggeri (Vapore)
+STR_LIVERY_PASSENGER_WAGON_DIESEL :Carrozza Passeggeri (Diesel)
+STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Carrozza Passeggeri (Elettrico)
+STR_LIVERY_FREIGHT_WAGON :Vagone Merci
+STR_LIVERY_BUS :Autobus
+STR_LIVERY_TRUCK :Autocarro
+STR_LIVERY_PASSENGER_SHIP :Traghetto
+STR_LIVERY_FREIGHT_SHIP :Nave Mercantile
+STR_LIVERY_HELICOPTER :Elicottero
+STR_LIVERY_SMALL_PLANE :Aeroplano (S)
+STR_LIVERY_LARGE_PLANE :Aeroplano (L)
+
+STR_LIVERY_GENERAL_TIP :{BLACK}Mostra schemi colore generale
+STR_LIVERY_TRAIN_TIP :{BLACK}Mostra schemi colore treni
+STR_LIVERY_ROADVEH_TIP :{BLACK}Mostra schemi colore veicoli
+STR_LIVERY_SHIP_TIP :{BLACK}Mostra schemi colore navi
+STR_LIVERY_AIRCRAFT_TIP :{BLACK}Mostra schemi colore aerei
+STR_LIVERY_PRIMARY_TIP :{BLACK}Scegli il colore primario per lo schema selezionato
+STR_LIVERY_SECONDARY_TIP :{BLACK}Scegli il colore secondario per lo schema selezionato
+STR_LIVERY_PANEL_TIP :{BLACK}Scegli uno schema colori per cambiare, o schemi multipli con CTRL + click. Clicca sul box per attivare/disattivare lo schema
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (Vapore)
+STR_8001_MJS_250_DIESEL :MJS 250 (Diesel)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut Diesel
+STR_8006_POWERNAUT_DIESEL :Powernaut Diesel
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (Vapore)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (Vapore)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (Vapore)
+STR_800A_SH_8P_STEAM :SH '8P' (Vapore)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (Diesel)
+STR_800C_DASH_DIESEL :'Dash' (Diesel)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (Diesel)
+STR_800E_UU_37_DIESEL :UU '37' (Diesel)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (Diesel)
+STR_8010_CS_4000_DIESEL :CS 4000 (Diesel)
+STR_8011_CS_2400_DIESEL :CS 2400 (Diesel)
+STR_8012_CENTENNIAL_DIESEL :Centennial (Diesel)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (Diesel)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (Diesel)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (Diesel)
+STR_8016_SH_125_DIESEL :SH '125' (Diesel)
+STR_8017_SH_30_ELECTRIC :SH '30' (Elettrica)
+STR_8018_SH_40_ELECTRIC :SH '40' (Elettrica)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (Elettrica)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (Elettrica)
+STR_801B_PASSENGER_CAR :Carrozza Passeggeri
+STR_801C_MAIL_VAN :Vagone Postale
+STR_801D_COAL_CAR :Vagone Carbone
+STR_801E_OIL_TANKER :Vagone Cisterna
+STR_801F_LIVESTOCK_VAN :Vano Bestiame
+STR_8020_GOODS_VAN :Vano Beni
+STR_8021_GRAIN_HOPPER :Vagone Grano
+STR_8022_WOOD_TRUCK :Vagone Legname
+STR_8023_IRON_ORE_HOPPER :Vagone Ferro
+STR_8024_STEEL_TRUCK :Vagone Acciaio
+STR_8025_ARMORED_VAN :Vagone Blindato
+STR_8026_FOOD_VAN :Vano Alimentari
+STR_8027_PAPER_TRUCK :Vagone Carta
+STR_8028_COPPER_ORE_HOPPER :Vagone Rame
+STR_8029_WATER_TANKER :Cisterna Acqua
+STR_802A_FRUIT_TRUCK :Vagone Frutta
+STR_802B_RUBBER_TRUCK :Vagone Gomma
+STR_802C_SUGAR_TRUCK :Vagone Zucchero
+STR_802D_COTTON_CANDY_HOPPER :Vagone Cotone Cand.
+STR_802E_TOFFEE_HOPPER :Vano Toffee
+STR_802F_BUBBLE_VAN :Vano Bolle
+STR_8030_COLA_TANKER :Cisterna Cola
+STR_8031_CANDY_VAN :Vano Dolciumi
+STR_8032_TOY_VAN :Vano Giocattoli
+STR_8033_BATTERY_TRUCK :Vagone Batterie
+STR_8034_FIZZY_DRINK_TRUCK :Vagone Bibite Friz.
+STR_8035_PLASTIC_TRUCK :Vagone Plastica
+STR_8036_X2001_ELECTRIC :'X2001' (Elettrica)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Elettrica)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :Carrozza Passeggeri
+STR_803A_MAIL_VAN :Vagone Postale
+STR_803B_COAL_CAR :Vagone Carbone
+STR_803C_OIL_TANKER :Vagone Cisterna
+STR_803D_LIVESTOCK_VAN :Vano Bestiame
+STR_803E_GOODS_VAN :Vano Beni
+STR_803F_GRAIN_HOPPER :Vagone Grano
+STR_8040_WOOD_TRUCK :Vagone Legname
+STR_8041_IRON_ORE_HOPPER :Vagone Ferro
+STR_8042_STEEL_TRUCK :Vagone Acciaio
+STR_8043_ARMORED_VAN :Vagone Blindato
+STR_8044_FOOD_VAN :Vano Alimentari
+STR_8045_PAPER_TRUCK :Vagone Carta
+STR_8046_COPPER_ORE_HOPPER :Vagone Rame
+STR_8047_WATER_TANKER :Cisterna Acqua
+STR_8048_FRUIT_TRUCK :Vagone Frutta
+STR_8049_RUBBER_TRUCK :Vagone Gomma
+STR_804A_SUGAR_TRUCK :Vagone Zucchero
+STR_804B_COTTON_CANDY_HOPPER :Vagone Cotone Cand.
+STR_804C_TOFFEE_HOPPER :Vano Toffee
+STR_804D_BUBBLE_VAN :Vano Bolle
+STR_804E_COLA_TANKER :Cisterna Cola
+STR_804F_CANDY_VAN :Vano Dolciumi
+STR_8050_TOY_VAN :Vano Giocattoli
+STR_8051_BATTERY_TRUCK :Vagone Batterie
+STR_8052_FIZZY_DRINK_TRUCK :Vagone Bibite Friz.
+STR_8053_PLASTIC_TRUCK :Vagone Plastica
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (Elettrica)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (Elettrica)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (Elettrica)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (Elettrica)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :Carrozza Passeggeri
+STR_805A_MAIL_VAN :Vagone Postale
+STR_805B_COAL_CAR :Vagone Carbone
+STR_805C_OIL_TANKER :Vagone Cisterna
+STR_805D_LIVESTOCK_VAN :Vano Bestiame
+STR_805E_GOODS_VAN :Vano Beni
+STR_805F_GRAIN_HOPPER :Vagone Grano
+STR_8060_WOOD_TRUCK :Vagone Legname
+STR_8061_IRON_ORE_HOPPER :Vagone Ferro
+STR_8062_STEEL_TRUCK :Vagone Acciaio
+STR_8063_ARMORED_VAN :Vagone Blindato
+STR_8064_FOOD_VAN :Vano Alimentari
+STR_8065_PAPER_TRUCK :Vagone Carta
+STR_8066_COPPER_ORE_HOPPER :Vagone Rame
+STR_8067_WATER_TANKER :Cisterna Acqua
+STR_8068_FRUIT_TRUCK :Vagone Frutta
+STR_8069_RUBBER_TRUCK :Vagone Gomma
+STR_806A_SUGAR_TRUCK :Vagone Zucchero
+STR_806B_COTTON_CANDY_HOPPER :Vagone Cotone Cand.
+STR_806C_TOFFEE_HOPPER :Vano Toffee
+STR_806D_BUBBLE_VAN :Vano Bolle
+STR_806E_COLA_TANKER :Cisterna Cola
+STR_806F_CANDY_VAN :Vano Dolciumi
+STR_8070_TOY_VAN :Vano Giocattoli
+STR_8071_BATTERY_TRUCK :Vagone Batterie
+STR_8072_FIZZY_DRINK_TRUCK :Vagone Bibite Friz.
+STR_8073_PLASTIC_TRUCK :Vagone Plastica
+STR_8074_MPS_REGAL_BUS :Bus MPS Regal
+STR_8075_HEREFORD_LEOPARD_BUS :Bus Hereford Leopard
+STR_8076_FOSTER_BUS :Bus Foster
+STR_8077_FOSTER_MKII_SUPERBUS :Superbus Foster MkII
+STR_8078_PLODDYPHUT_MKI_BUS :Bus Ploddyphut MkI
+STR_8079_PLODDYPHUT_MKII_BUS :Bus Ploddyphut MkII
+STR_807A_PLODDYPHUT_MKIII_BUS :Bus Ploddyphut MkIII
+STR_807B_BALOGH_COAL_TRUCK :Camion Carbone Balogh
+STR_807C_UHL_COAL_TRUCK :Camion Carbone Uhl
+STR_807D_DW_COAL_TRUCK :Camion Carbone DW
+STR_807E_MPS_MAIL_TRUCK :Furgone Postale MPS
+STR_807F_REYNARD_MAIL_TRUCK :Furgone Postale Reynard
+STR_8080_PERRY_MAIL_TRUCK :Furgone Postale Perry
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :Furg. Postale MightyMover
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Furg. Postale Powernaught
+STR_8083_WIZZOWOW_MAIL_TRUCK :Furgone Postale Wizzowow
+STR_8084_WITCOMBE_OIL_TANKER :Autocisterna Witcombe
+STR_8085_FOSTER_OIL_TANKER :Autocisterna Foster
+STR_8086_PERRY_OIL_TANKER :Autocisterna Perry
+STR_8087_TALBOTT_LIVESTOCK_VAN :Furgone Bestiame Talbott
+STR_8088_UHL_LIVESTOCK_VAN :Furgone Bestiame Uhl
+STR_8089_FOSTER_LIVESTOCK_VAN :Furgone Bestiame Foster
+STR_808A_BALOGH_GOODS_TRUCK :Camion Beni Balogh
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Camion Beni Craighead
+STR_808C_GOSS_GOODS_TRUCK :Camion Beni Goss
+STR_808D_HEREFORD_GRAIN_TRUCK :Camion Grano Hereford
+STR_808E_THOMAS_GRAIN_TRUCK :Camion Grano Thomas
+STR_808F_GOSS_GRAIN_TRUCK :Camion Grano Goss
+STR_8090_WITCOMBE_WOOD_TRUCK :Camion Legname Witcombe
+STR_8091_FOSTER_WOOD_TRUCK :Camion Legname Foster
+STR_8092_MORELAND_WOOD_TRUCK :Camion Legname Moreland
+STR_8093_MPS_IRON_ORE_TRUCK :Camion Ferro MPS
+STR_8094_UHL_IRON_ORE_TRUCK :Camion Ferro Uhl
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Camion Ferro Chippy
+STR_8096_BALOGH_STEEL_TRUCK :Camion Acciaio Balogh
+STR_8097_UHL_STEEL_TRUCK :Camion Acciaio Uhl
+STR_8098_KELLING_STEEL_TRUCK :Camion Acciaio Kelling
+STR_8099_BALOGH_ARMORED_TRUCK :Autoblindo Balogh
+STR_809A_UHL_ARMORED_TRUCK :Autoblindo Uhl
+STR_809B_FOSTER_ARMORED_TRUCK :Autoblindo Foster
+STR_809C_FOSTER_FOOD_VAN :Furg. Alimentari Foster
+STR_809D_PERRY_FOOD_VAN :Furg. Alimentari Perry
+STR_809E_CHIPPY_FOOD_VAN :Furg. Alimentari Chippy
+STR_809F_UHL_PAPER_TRUCK :Camion Carta Uhl
+STR_80A0_BALOGH_PAPER_TRUCK :Camion Carta Balogh
+STR_80A1_MPS_PAPER_TRUCK :Camion Carta MPS
+STR_80A2_MPS_COPPER_ORE_TRUCK :Camion Rame MPS
+STR_80A3_UHL_COPPER_ORE_TRUCK :Camion Rame Uhl
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Camion Rame Goss
+STR_80A5_UHL_WATER_TANKER :Autobotte Uhl
+STR_80A6_BALOGH_WATER_TANKER :Autobotte Balogh
+STR_80A7_MPS_WATER_TANKER :Autobotte MPS
+STR_80A8_BALOGH_FRUIT_TRUCK :Camion Frutta Balogh
+STR_80A9_UHL_FRUIT_TRUCK :Camion Frutta Uhl
+STR_80AA_KELLING_FRUIT_TRUCK :Camion Frutta Kelling
+STR_80AB_BALOGH_RUBBER_TRUCK :Camion Gomma Balogh
+STR_80AC_UHL_RUBBER_TRUCK :Camion Gomma Uhl
+STR_80AD_RMT_RUBBER_TRUCK :Camion Gomma RMT
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :Camion Zucchero MightyMover
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Camion Zucchero Powernaught
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Camion Zucchero Wizzowow
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :Autobotte-Cola MightyMover
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Autobotte-Cola Powernaught
+STR_80B3_WIZZOWOW_COLA_TRUCK :Autobotte-Cola Wizzowow
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :Camion Cotone Can. MightyMover
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Camion Cotone Can. Powernaught
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Camion Cotone Can. Wizzowow
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :Camion Toffee MightyMover
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Camion Toffee Powernaught
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Camion Toffee Wizzowow
+STR_80BA_MIGHTYMOVER_TOY_VAN :Furgone Giocattoli MightyMover
+STR_80BB_POWERNAUGHT_TOY_VAN :Furgone Giocattoli Powernaught
+STR_80BC_WIZZOWOW_TOY_VAN :Furgone Giocattoli Wizzowow
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :Camion Dolci MightyMover
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Camion Dolci Powernaught
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Camion Dolci Wizzowow
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :Camion Batterie MightyMover
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Camion Batterie Powernaught
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Camion Batterie Wizzowow
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :Camion Bibite Friz.MightyMover
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :camion Bibite Friz.Powernaught
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Camion Bibite Friz.Wizzowow
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :Camion Plastica MightyMover
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Camion Plastica Powernaught
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Camion Plastica Wizzowow
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :Camion Bolle MightyMover
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Camion Bolle Powernaught
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Camion Bolle Wizzowow
+STR_80CC_MPS_OIL_TANKER :Petroliera MPS
+STR_80CD_CS_INC_OIL_TANKER :Petroliera CS-Inc.
+STR_80CE_MPS_PASSENGER_FERRY :Traghetto FFP
+STR_80CF_FFP_PASSENGER_FERRY :Traghetto FFP
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Hovercraft Bakewell 300
+STR_80D1_CHUGGER_CHUG_PASSENGER :Traghetto Chugger-Chug
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Traghetto Shivershake
+STR_80D3_YATE_CARGO_SHIP :Nave Mercantile Yate
+STR_80D4_BAKEWELL_CARGO_SHIP :Nave Mercantile Bakewell
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Nave Mercantile Mightymover
+STR_80D6_POWERNAUT_CARGO_SHIP :Name Mercantile Powernaut
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Elicottero Tricario
+STR_80FE_GURU_X2_HELICOPTER :Elicottero Guru X2
+STR_80FF_POWERNAUT_HELICOPTER :Elicottero Powernaut
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Messaggio dal fornitore del veicolo
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}Abbiamo appena progettato un nuovo {STRING} - Le interessa un'anno di esclusiva sull'uso del veicolo? Così possiamo vedere come va prima di renderlo disponibile al mercato?
+STR_8102_RAILROAD_LOCOMOTIVE :locomotiva
+STR_8103_ROAD_VEHICLE :veicolo stradale
+STR_8104_AIRCRAFT :aereo
+STR_8105_SHIP :nave
+STR_8106_MONORAIL_LOCOMOTIVE :motrice monorotaia
+STR_8107_MAGLEV_LOCOMOTIVE :motrice maglev
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}{TOWN} Deposito Treni
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}I cittadini festeggiano . . .{}Primo treno arrivato a {STATION}!
+STR_8802_DETAILS :{WHITE}{STRING} (Details)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Treno in mezzo
+STR_8804 :{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8806_GO_TO :Vai a {STATION}
+STR_8807_GO_TO_TRANSFER :Vai a {STATION} (Trasferisci e carica)
+STR_8808_GO_TO_UNLOAD :Vai a {STATION} (Scarica)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Vai a {STATION} (Trasferisci e non caricare)
+STR_880A_GO_TO_LOAD :Vai a {STATION} (Carica)
+STR_880B_GO_TO_TRANSFER_LOAD :Vai a {STATION} (Trasferisci e aspetta carico completo)
+STR_880C_GO_NON_STOP_TO :Vai non-stop a {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Vai non-stop a {STATION} (Trasferisci e carica)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Vai non-stop a {STATION} (Scarica)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Vai non-stop a {STATION} (Trasferisci e non caricare)
+STR_8810_GO_NON_STOP_TO_LOAD :Vai non-stop a {STATION} (Carica)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Vai non-stop a {STATION} (Trasferisci e aspetta carico completo)
+STR_GO_TO_TRAIN_DEPOT :Vai a {TOWN} Deposito Treni
+STR_SERVICE_AT_TRAIN_DEPOT :Manutenzione a {TOWN} Deposito Ferroviario
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Vai non-stop a {TOWN} Deposito Ferroviario
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Manutenzione non-stop a {TOWN} Deposito Ferroviario
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}Direzione per {TOWN} Deposito Treni
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}Direzione per {TOWN} Deposito Treni, {VELOCITY}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE :{LTBLUE}Servizio a {TOWN} Deposito Treni
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE_VEL :{LTBLUE}Servizio a {TOWN} Deposito Treni, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (Ordine non Valido)
+
+STR_UNKNOWN_DESTINATION :destinazione sconosciuta
+STR_8812_EMPTY :{LTBLUE}Vuoto
+STR_8813_FROM :{LTBLUE}{CARGO} da {STATION}
+STR_FROM_MULT :{LTBLUE}{CARGO} da {STATION} (x{NUM})
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}Treno {COMMA} sta aspettando nel deposito
+STR_8815_NEW_VEHICLES :{BLACK}Nuovi Veicoli
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Treno troppo lungo
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Un treno può essere modificato solo quando è fermo nel deposito
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} Tren{P o i}
+
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Nuovo Veicolo Ferroviario
+STR_NEW_ELRAIL_VEHICLES :{WHITE}Nuovi Veicoli Ferroviari Elettrici
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Nuovo Veicolo Monorotaia
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Nuovo Veicolo Maglev
+STR_ALL_AVAIL_RAIL_VEHICLES :{WHITE}Veicoli su rotaia
+
+STR_881F_BUILD_VEHICLE :{BLACK}Costruisci Veicolo
+STR_CLONE_ROAD_VEHICLE :{BLACK}Clona Veicolo
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}Costruisce una copia del veicolo stradale. Premere contemporaneamente Control per condividere gli ordini
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Costruisce una copia di un veicolo stradale. Cliccare su questo pulsante e poi sul veicolo stradale (dentro o fuori dal deposito) da copiare. Premere contemporaneamente Control per condividere gli ordini
+STR_CLONE_TRAIN :{BLACK}Clona Treno
+STR_CLONE_TRAIN_INFO :{BLACK}Costruisce una copia del treno, vagoni inclusi. Premere contemporaneamente Control per condividere gli ordini
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}Costruisce una copia di un treno, vagoni inclusi. Cliccare su questo pulsante e poi sul treno (dentro o fuori dal deposito) da copiare. Premere contemporaneamente Control per condividere gli ordini
+STR_8820_RENAME :{BLACK}Rinomina
+STR_8823_SKIP :{BLACK}Salta
+STR_8824_DELETE :{BLACK}Elimina
+STR_8825_NON_STOP :{BLACK}Non-Stop
+STR_8826_GO_TO :{BLACK}Vai a
+STR_8827_FULL_LOAD :{BLACK}Carica
+STR_8828_UNLOAD :{BLACK}Scarica
+STR_REFIT :{BLACK}Modifica
+STR_REFIT_TIP :{BLACK}Scegli iltipo di merce da modificare in questo ordine. CTRL+click per togliere l'istruzione di modifica
+STR_REFIT_ORDER :(Modifica a {STRING})
+STR_8829_ORDERS :{WHITE}{VEHICLE} (Ordini)
+STR_882A_END_OF_ORDERS :{SETX 10}- - Fine degli Ordini - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}Manutenzione
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Non puoi costruire veicolo ferroviario...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Costr. nel: {LTBLUE}{NUM}{BLACK} Valore: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Valore: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}Carica / Scarica
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}Il treno deve essere fermato nel deposito
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Non puoi mandare treno al deposito...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Spazio per gli ordini terminato
+STR_8832_TOO_MANY_ORDERS :{WHITE}Troppi ordini
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Non puoi inserire nuovo ordine...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Non puoi cancellare quest'ordine...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Non puoi modificare quest'ordine...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Non puoi spostare il veicolo...
+STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}La locomotiva di coda seguirà sempre quella di testa
+STR_8838_N_A :N/A{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Non puoi vendere veicolo ferroviario...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Non riesce a trovare il deposito locale
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Non puoi far fermare/ripartire il treno...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Intervallo Manutenz.: {LTBLUE}{COMMA}giorni{BLACK} Ultima Manut.: {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Intervallo Manutenz.: {LTBLUE}{COMMA}%{BLACK} Ultima Manut.: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Treni - fai clic sul treno per le informazioni
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Costruisci nuovi treni (Necessario deposito)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Treni - fai clic sul treno per le informazioni, trascina i veicoli per aggiungerli/rimuoverli dal treno
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Costruisci nuovo veicolo ferroviario
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Trascina veicolo qui per venderlo
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centra visuale sul deposito ferroviario
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Lista treni - fai clic sul veicolo per le informazioni
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Costruisci veicolo ferroviario evidenziato
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Rinomina tipo di veicolo
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Azione corrente del treno - Clicca qui per fermarlo/farlo partire
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Mostra ordini del treno
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centra visuale sul treno
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Manda treno al deposito
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Forza il treno a proseguire senza aspettare il segnale
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Inverti direzione del treno
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Mostra dettagli del treno
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Aumenta intervallo di manutenzione
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Riduci intervallo di manutenzione
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Mostra dettagli del carico trasportato
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Mostra dettagli di ogni veicolo
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Mostra capienza di ogni veicolo
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Mostra la capacità massima del treno per tipo di carico
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Lista ordini - fai clic sull'ordine per evidenziarlo
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}Salta l'ordine corrente e inizia il successivo
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Elimina l'ordine evidenziato
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Fai diventare l'ordine evidenziato 'non-stop'
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Aggiungi un nuovo ordine prima di quello evidenziato o aggiungilo alla fine della lista
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Fai diventare l'ordine evidenziato 'forza il veicolo ad attendere il carico completo'
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Fai diventare l'ordine evidenziato 'forza il veicolo a scaricare'
+STR_SERVICE_HINT :{BLACK}Ignora l'ordine finché non sia necessaria la manutenzione
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}Nuova {STRING} ora disponibile!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Costo: {CURRENCY} Peso: {WEIGHT_S}{}Velocità: {VELOCITY} Potenza: {POWER}{}Consumi: {CURRENCY}/anno{}Capienza: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}Guasto!
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}Età: {LTBLUE}{STRING}{BLACK} Consumi: {LTBLUE}{CURRENCY}/anno
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Peso: {LTBLUE}{WEIGHT_S} {BLACK}Potenza: {LTBLUE}{POWER}{BLACK} Velocità Max: {LTBLUE}{VELOCITY}
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Peso: {LTBLUE}{WEIGHT_S} {BLACK}Potenza: {LTBLUE}{POWER}{BLACK} Vel. Max: {LTBLUE}{VELOCITY} {BLACK}Sforzo Trazione Max.: {LTBLUE}{FORCE}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profitto quest'anno: {LTBLUE}{CURRENCY} (anno scorso: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}Affidabilità: {LTBLUE}{COMMA}% {BLACK}Guasti dall'ultima manutenzione: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Fermato
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Non puoi fargli passare i segnali al rischio di...
+STR_8863_CRASHED :{RED}Distrutto!
+
+STR_8865_NAME_TRAIN :{WHITE}Nome Treno
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}Non puoi rinominare il treno...
+STR_8867_NAME_TRAIN :{BLACK}Nome Treno
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Treno schiantato!{}{COMMA} morti in una palla di fuoco dopo la collisione
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Non puoi invertire la direzione del treno...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Rinomina il tipo di veicolo
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Non puoi rinominare tipo di veicolo...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Fai diventare l'ordine evidenziato 'forza il veicolo a trasferire il carico'
+STR_886F_TRANSFER :{BLACK}Trasferisci
+
+STR_TRAIN_STOPPING :{RED}In frenata
+STR_TRAIN_STOPPING_VEL :{RED}In frenata, {VELOCITY}
+STR_INCOMPATIBLE_RAIL_TYPES :Tipo binario incompatibile
+STR_TRAIN_NO_POWER :{RED}Nessuna potenza
+STR_TRAIN_START_NO_CATENARY :Questo tratto manca la catenaria, per questo il treno non può partire
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Veicolo in mezzo
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} Veicol{P o i} stradal{P e i}
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}{TOWN} Deposito Veicoli Stradali
+STR_9004_NEW_VEHICLES :{BLACK}Nuovi Veicoli
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}Nuovi Veicoli Stradali
+STR_9007_BUILD_VEHICLE :{BLACK}Costruisci Veicolo
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Non puoi costruire veicolo...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (Dettagli)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}Età: {LTBLUE}{STRING}{BLACK} Consumi: {LTBLUE}{CURRENCY}/anno
+STR_900E_MAX_SPEED :{BLACK}Velocità Max: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profitto quest'anno: {LTBLUE}{CURRENCY} (anno scorso: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}Affidabilità: {LTBLUE}{COMMA}% {BLACK}Guasti dall'ultima manutenz.: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Costr. nel: {LTBLUE}{NUM}{BLACK} Valore: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Capienza: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}...deve essere fermo nel deposito
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Non puoi vendere veicolo
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Non puoi far fermare/avviare veicolo...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}Veicolo stradale {COMMA} stà aspettando nel deposito
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}Direzione per {TOWN} Deposito Veicoli
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}Direzione per {TOWN} Deposito Veicoli, {VELOCITY}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE :{LTBLUE}Servizio a {TOWN} Deposito Veicoli
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE_VEL :{LTBLUE}Servizio a {TOWN} Deposito Veicoli, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Non puoi mandare il veicolo al deposito...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Non riesce a trovare il deposito locale
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Veicoli stradali - clicca sul veicolo per le informazioni
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Costruisci nuovi veicoli stradali (richiesto deposito veicoli stradali)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Azione corrente del veicolo - fai clic qui per far fermare/ripartire il veicolo
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Mostra ordini del veicolo
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Centra visuale sul veicolo
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Manda veicolo al deposito
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Fai girare il veicolo
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Mostra dettagli del veicolo
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Veicoli - fai clic sul veicolo per le informazioni
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Costruisci nuovo veicolo stradale
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Trascina veicolo stradale qui per venderlo
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Centra visuale sul deposito
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Lista veicoli - fai clic sul veicolo per le informazioni
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Costruisci veicolo stradale evidenziato
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}Nuovo veicolo stradale disponibile!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Costo: {CURRENCY}{}Velocità: {VELOCITY}{}Consumi: {CURRENCY}/anno{}Capienza: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Nome Veicolo
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Non puoi rinominare automezzo...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Nome veicolo
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}I cittadini festeggiano . . .{}Primo bus arrivato a {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}I cittadini festeggiano. . .{}Primo camion arrivato a {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}Veicolo distrutto!{}Il conducente muore in una palla di fuoco dopo la collisione
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}Veicolo distrutto!{}{COMMA} morti in una palla di fuoco dopo la collisione col treno
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Non puoi far girare il veicolo...
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}Non posso invertire veicoli composti da unità multiple
+STR_9034_RENAME :{BLACK}Rinomina
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Rinomina tipo di veicolo
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Rinomina tipo di veicolo
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Non puoi rinominare tipo di veicolo...
+STR_9038_GO_TO_ROADVEH_DEPOT :Vai a {TOWN} Deposito Veicoli
+STR_SERVICE_AT_ROADVEH_DEPOT :Manutenzione a {TOWN} Deposito Stradale
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Riadatta il veicolo stradale per trasportare un tipo di merce differente
+STR_REFIT_ROAD_VEHICLE :{BLACK}Riadatta il veicolo stradale
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Riadatta il veicolo stradale tper trasportare il tipo di merce selezionato
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Non posso riadattare il veicolo...
+STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Scegli il tipo di merce da caricare sul veicolo stradale
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Costruzione moli
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Costruzione moli
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Non puoi costruire molo qui...
+STR_9803_SHIP_DEPOT :{WHITE}{TOWN} Deposito Navale
+STR_9804_NEW_SHIPS :{BLACK}Nuove Navi
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} Nav{P e i}
+STR_9808_NEW_SHIPS :{WHITE}Nuove Navi
+STR_9809_BUILD_SHIP :{BLACK}Costruisci Nave
+STR_CLONE_SHIP :{BLACK}Clona Nave
+STR_CLONE_SHIP_INFO :{BLACK}Costruisce una copia della nave. Premere contemporaneamente Control per condividere gli ordini
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}Costruisce una copia di una nave. Cliccare su questo pulsante e poi sulla nave (dentro o fuori dal deposito) da copiare. Premere contemporaneamente Control per condividere gli ordini
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}La nave deve essere ferma nel deposito
+STR_980C_CAN_T_SELL_SHIP :{WHITE}Non puoi vendere la nave...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Non puoi costruire nave...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Nave in mezzo
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Dettagli)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}Età: {LTBLUE}{STRING}{BLACK} Consumi: {LTBLUE}{CURRENCY}/anno
+STR_9813_MAX_SPEED :{BLACK}Velocità Max: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profitto quest'anno: {LTBLUE}{CURRENCY} (anno scorso: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}Affidabilità: {LTBLUE}{COMMA}% {BLACK}Guasti dall'ultima manutenz.: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Costr. nel: {LTBLUE}{NUM}{BLACK} Valore: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}Capienza: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}Non puoi far fermare/ripartire la nave...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Non puoi mandare nave al deposito...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Non riesce a trovare il deposito locale
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}Direzione per {TOWN} Deposito Navale
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}Direzione per {TOWN} Deposito Navale, {VELOCITY}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE :{LTBLUE}Servizio a {TOWN} Deposito Navale
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE_VEL :{LTBLUE}Servizio a {TOWN} Deposito Navale, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}Nave {COMMA} stà aspettano nel deposito
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Costruisci molo
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Costruisci deposito navale (per costruzione e manutenzione)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Navi - fai clic sulla nave per le informazioni
+STR_9820_BUILD_NEW_SHIP :{BLACK}Costruisci una nuova nave
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Trascina qui una nave per venderla
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centra la visuale sul deposito
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Navi - fai clic sulla nave per le informazioni
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Costruisci nuove navi (richiede un deposito navale)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}Lista navi - fai clic sulla nave per le informazioni
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Costruisci la nave evidenziata
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Azione della nave corrente - fai clic qui per farla fermare/ripartire
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Mostra gli ordini della nave
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centra la visuale sulla nave
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Manda la nave al deposito
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Mostra dettagli sulla nave
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}E' disponibile una nuova nave!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Costo: {CURRENCY} Velocità Max: {VELOCITY}{}Capienza: {CARGO}{}Consumi: {CURRENCY}/anno
+STR_982F_NAME_SHIP :{BLACK}Nome Nave
+
+STR_9831_NAME_SHIP :{WHITE}Nome Nave
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Non puoi rinominare il nome della nave...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}I cittadini festeggiano . . .{}Prima nave arrivata a {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Posiziona boa, può essere usata come way point.
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Non puoi posizionare una boa qui...
+STR_9836_RENAME :{BLACK}Rinomina
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Rinomina il tipo di nave
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Rinomina il tipo di nave
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Non puoi rinominare il tipo di nave...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Converti la nave per caricare un tipo di merce diversa
+STR_983B_REFIT :{WHITE}{VEHICLE} (Converti)
+STR_983C_REFIT_SHIP :{BLACK}Converti nave
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Seleziona tipo di merce da caricare
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Converti la nave per trasportare il tipo di merce evidenziata
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Seleziona il tipo di merce da caricare:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nuova Capienza: {GOLD}{CARGO}{}{BLACK}Costo conversione: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Non puoi convertire la nave...
+STR_9842_REFITTABLE :(convertibile)
+STR_GO_TO_SHIP_DEPOT :Vai a {TOWN} Deposito Navale
+SERVICE_AT_SHIP_DEPOT :Manutenzione a {TOWN} Deposito Navale
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Aeroporti
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Non puoi costruire un aeroporto qui...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} Hangar
+STR_A003_NEW_AIRCRAFT :{BLACK}Nuovo Aereo
+STR_CLONE_AIRCRAFT :{BLACK}Clona Aereo
+STR_CLONE_AIRCRAFT_INFO :{BLACK}Costruisce una copia dell'aereo. Premere contemporaneamente Control per condividere gli ordini
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Costruisce una copia di un aereo. Cliccare su questo pulsante e poi sull'aereo (dentro o fuori dal deposito) da copiare. Premere contemporaneamente Control per condividere gli ordini
+STR_A005_NEW_AIRCRAFT :{WHITE}Nuovo Aereo
+STR_A006_BUILD_AIRCRAFT :{BLACK}Construisci Aereo
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Non puoi costruire l'aereo
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} Aereo
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (Ordini)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (Dettagli)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Età: {LTBLUE}{STRING}{BLACK} Consumi: {LTBLUE}{CURRENCY}/anno
+STR_A00E_MAX_SPEED :{BLACK}Velocità Max: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profitto quest'anno: {LTBLUE}{CURRENCY} (anno scorso: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}Affidabilità: {LTBLUE}{COMMA}% {BLACK}Guasti dall'ultima manutenz.: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Costr. nel: {LTBLUE}{NUM}{BLACK} Valore: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Non puoi mandare l'aereo nell'hangar...
+STR_HEADING_FOR_HANGAR :{ORANGE}Direzione per {STATION} Hangar
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}Direzione per {STATION} Hangar, {VELOCITY}
+STR_HEADING_FOR_HANGAR_SERVICE :{LTBLUE}Servizio a {STATION} Hangar
+STR_HEADING_FOR_HANGAR_SERVICE_VEL :{LTBLUE}Servizio a {STATION} Hangar, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}Aereo {COMMA} sta aspettano nell'hangar
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Aereo in mezzo
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Non puoi far fermare/ripartire l'aereo...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Aereo in volo
+STR_A019_CAPACITY :{BLACK}Capienza: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Capienza: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}Dev'essere fermo nell'hangar
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Non puoi vendere l'aereo...
+STR_A01D_AIRPORT_CONSTRUCTION :Costruzioni areoporto
+STR_A01E_BUILD_AIRPORT :{BLACK}Costruisci aeroporto
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Aereo - fai clic sull'aereo per le informazioni
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Costruisci un nuovo aereo (richiesto aeroporto con hangar)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Aereo - clicca sull'aereo per le informazioni
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Costruisci un nuovo aereo
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}Trascina qui l'aereo per venderlo
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Centra visuale sull'hangar
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Lista aerei - fai clic sull'aereo per le informazioni
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Costruisci l'aereo evidenziato
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Azione corrente dell'aereo - fai clic qui per far fermare/ripartire l'aereo
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Mostra ordini dell'aereo
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Centra visuale sull'aereo
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Manda l'aereo all'hangar
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Mostra dettagli dell'aereo
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}E' disponibile un nuovo aereo!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Costo: {CURRENCY} Velocità Max: {VELOCITY}{}Capienza: {COMMA} passeggeri, {COMMA} sacchi postali{}Consumi: {CURRENCY}/anno
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Nome aereo
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Non puoi dare un nome all'aereo...
+STR_A032_NAME_AIRCRAFT :{BLACK}Nome aereo
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}I cittadini festeggiano . . .{}Primo aereo atterrato a {STATION}!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Aereo precipitato!{}{COMMA} morti in una palla di fuoco a {STATION}
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Incidente aereo!{}L'aereo ha esaurito il carburante, {COMMA} morti in una palla di fuoco!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Rinomina
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Rinomina il tipo di aereo
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Rinomina il tipo di aereo
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Non puoi rinominare il tipo di aereo...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Converti l'aereo per trasportare un tipo di merce diversa
+STR_A03C_REFIT :{WHITE}{VEHICLE} (Converti)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Converti l'aereo
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Seleziona il tipo di merce da caricare
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Converti l'aereo per trasportare il tipo di merce evidenziata
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Seleziona il tipo di merce da caricare:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nuova capacità: {GOLD}{STRING}{}{BLACK}Costo conversione: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Non puoi convertire l'aereo...
+STR_GO_TO_AIRPORT_HANGAR :Vai a {STATION} Hangar
+SERVICE_AT_AIRPORT_HANGAR :Manutenzione a {STATION} Hangar
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}Disastro Zeppelin a {STATION}!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Veicolo distrutto in una collisione con un 'UFO'
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}Esplosione in una raffineria vicino a {TOWN}!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}Fabbrica distrutta in circostanze sospette vicino a {TOWN}!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}'UFO' atterra vicino a {TOWN}!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}Cedimento in una miniera di carbone lascia tracce di distruzione vicino a {TOWN}!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Alluvione!{}{COMMA} distrutto o disperso a seguito di una mortale alluvione!
+
+STR_BRIBE_FAILED :{WHITE}Il tentativo di corruzione è stato
+STR_BRIBE_FAILED_2 :{WHITE}scoperto dalla guardia di finanzia regionale.
+STR_BUILD_DATE :{BLACK}Realizzato il: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Dettagli valutazione delle prestazioni
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}Dettagli
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Veicoli:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Stazioni:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Profitto Min.:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Incasso Min.:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Incasso Max.:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Trasportati:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Carichi:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Denaro:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Prestito:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Totale:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Numero di veicoli. Include Veicoli Stradali, Treni, Navi e Aerei.
+STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}Numero di blocchi stazione. Ogni parte di una stazione (e.g. stazione ferroviaria, fermata dell'autobus, aeroporti) viene contata, anche se insieme formano un'unica stazione.
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}Profitto del veicolo con l'incasso minore (tra tutti i veicoli più vecchi di 2 anni)
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Ammontare di denaro guadagnato nel mese con il minimo profitto degli ultimi 12 quarti
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Ammontare di denaro guadagnato nel mese con il massimo profitto degli ultimi 12 quarti
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}Unità di merce trasportata nell'ultimo quarto.
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}Tipi di merci trasportate nell'ultimo quarto.
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Ammontare di denaro in tasca
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}Hai preso un prestito troppo elevato?
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Totale dei punti rispetto ad un massimo di punti possibili
+
+STR_NEWGRF_SETTINGS_BUTTON :{BLACK}Settaggi NewGRF
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}Impostazioni newgrf
+STR_NEWGRF_APPLY_CHANGES :{BLACK}Applica cambiamenti
+STR_NEWGRF_SET_PARAMETERS :{BLACK}Imposta parametri
+STR_NEWGRF_TIP :{BLACK}Una lista di tutti i Newgrf che hai installato. Cliccane uno per cambiarne le impostazioni
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}Non ci sono attualmente file newgrf installati! Fare riferimento al manuale per installarne di nuovi
+STR_NEWGRF_FILENAME :{BLACK}Nome file: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
+STR_NEWGRF_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING}
+STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}Stai per fare cambiamenti a una partita in corso; questo pu• crashare OpenTTD.{}Sei assolutamente sicuro di farlo?
+
+STR_NEWGRF_ADD :{BLACK}Aggiungi
+STR_NEWGRF_ADD_TIP :{BLACK}Aggiungi un file NewGRF alla lista
+STR_NEWGRF_REMOVE :{BLACK}Togli
+STR_NEWGRF_REMOVE_TIP :{BLACK}Togli il file NewGRF selezionato dalla lista
+STR_NEWGRF_MOVEUP :{BLACK}Sposta su
+STR_NEWGRF_MOVEUP_TIP :{BLACK}Sposta su il file NewGRF selezionato nella lista
+STR_NEWGRF_MOVEDOWN :{BLACK}Sposta giù
+STR_NEWGRF_MOVEDOWN_TIP :{BLACK}Sposta giù il file NewGRF selezionato nella lista
+STR_NEWGRF_FILE_TIP :{BLACK}Una lista dei file NewGRF installati. Clicca un file per cambiare i parametri
+STR_NEWGRF_PARAMETER :{BLACK}Parametri: {SILVER}{STRING}
+STR_NEWGRF_PARAMETER_QUERY :{BLACK}Immetti i parametri NewGRF
+STR_NEWGRF_NO_INFO :{BLACK}Informazioni non disponibili
+
+STR_NEWGRF_ADD_CAPTION :{WHITE}File NewGRF disponibili
+STR_NEWGRF_ADD_FILE :{BLACK}Aggiungi alla selezione
+STR_NEWGRF_ADD_FILE_TIP :{BLACK}Aggiungi il file NewGRF selezionato nella vostra configurazione
+STR_NEWGRF_RESCAN_FILES :{BLACK}Aggiorna file
+STR_NEWGRF_RESCAN_FILES_TIP :{BLACK}Aggiorna la lista dei file NewGRF disponibili
+STR_NEWGRF_DUPLICATE_GRFID :{WHITE}Non posso aggiungere un altro file: GRF ID esistente
+
+STR_NEWGRF_NOT_FOUND :{RED}File simile non trovato
+STR_NEWGRF_DISABLED :{RED}Disabilitato
+
+STR_CURRENCY_WINDOW :{WHITE}Valuta personalizzata
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Cambio: {ORANGE}{CURRENCY} = £ {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Separatore:
+STR_CURRENCY_PREFIX :{LTBLUE}Prefisso:
+STR_CURRENCY_SUFFIX :{LTBLUE}Suffisso:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Passa agli Euro: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Passa agli Euro: {ORANGE}mai
+STR_CURRENCY_PREVIEW :{LTBLUE}Anteprima: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Cambia i parametri della valuta personalizzata
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} Treni
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} Veicoli
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} Aerei
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} Navi
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Mostra tutti i treni che hanno questa stazione tra gli ordini
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Mostra tutti i veicoli che hanno questa stazione tra gli ordini
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Mostra tutti gli aerei che hanno questa stazione tra gli ordini
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Mostra tutte le navi che hanno questo porto tra gli ordini
+
+STR_VEH_WITH_SHARED_ORDERS_LIST :{WHITE}Ordini comuni di {COMMA} Veicol{P o i}
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}Mostra tutti i veicoli con la stessa lista ordini
+
+### depot strings
+STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Stai per vendere tutti i veicoli nel deposito. Sei sicuro?
+
+STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP :{BLACK}Vendi tutti i treni nel deposito
+STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP :{BLACK}Vendi tutti i veicoli nel deposito
+STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP :{BLACK}Vendi tute le navi nel deposito
+STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP :{BLACK}Vendi tutti gli aerei nell'hangar
+
+STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP :{BLACK}Lista tutti i treni che hanno questo deposito negli ordini
+STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP :{BLACK}Lista tutti i veicoli stradali che hanno questo deposito negli ordini
+STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP :{BLACK}Lista tutte le navi che hanno questo deposito negli ordini
+STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP :{BLACK}Lista tutti gli aerei che usano gli hangar di questo aeroporto negli ordini
+
+STR_DEPOT_AUTOREPLACE_TRAIN_TIP :{BLACK}Sostituisci automaticamente tutti i treni nel deposito
+STR_DEPOT_AUTOREPLACE_ROADVEH_TIP :{BLACK}Sostituisci automaticamente tutti i veicoli nel deposito
+STR_DEPOT_AUTOREPLACE_SHIP_TIP :{BLACK}Sostituisci automaticamente tutte le navi nel deposito
+STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP :{BLACK}Sostituisci automaticamente tutti gli aerei nell'hangar
+
+STR_VEHICLE_LIST_TRAIN_DEPOT :{BLACK}{STRING} - {COMMA} Tren{P o i}
+STR_VEHICLE_LIST_ROADVEH_DEPOT :{BLACK}{STRING} - {COMMA} Veicol{P o i} stradal{P e i}
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} Nav{P e i}
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} Aere{P o i}
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}Rimpiazza {STRING}
+STR_REPLACE_VEHICLES_START :{BLACK}Inizia Rimpiazzo Veicoli
+STR_REPLACE_VEHICLES_STOP :{BLACK}Finisci Rimpiazzo Veicoli
+STR_NOT_REPLACING :{BLACK}Nessun rimpiazzo
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Nessun veicolo selezionato
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Seleziona il tipo di locomotore da rimpiazzare
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Seleziona quale locomotore usare al posto di quello selezionato a sinistra
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Premi per fermare il rimpiazzo dei locomotori del tipo selezionato a sinistra
+STR_REPLACE_HELP_START_BUTTON :{BLACK}Premi per iniziare il rimpiazzo dei locomotori del tipo selezionato a sinistra con quello selezionato a destra
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Seleziona il tipo di ferrovia per la quale vuoi rimpiazzare i locomotori
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Mostra con quale locomotore verrà rimpiazzato il tipo selezionato a sinistra, se alcuno
+STR_REPLACE_HELP :{BLACK}Permette di rimpiazzare un locomotere con uno di un'altro tipo, quando il treno entra in un deposito
+STR_REPLACE_REMOVE_WAGON :{BLACK}Rimozione vagoni: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}La autosostituzione mantiene la lunghezza del treno togliendo vagoni (iniziando dalla testa), se la sostituzione della locomotiva lo farebbe piu lungo.
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}Sostituzione: {ORANGE}{SKIP}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} FEATURE SPERIMENTALE {}Scambia tra loro le finestre di sostituizione locomotive e vagoni. {}La sostituizione del vagone avverrà solo se il nuovo vagone può essere convertito nello stesso tipo di merce del vecchio vagone. Questo controllo viene fatto per ogni vagone sostituito.
+STR_ENGINE_NOT_BUILDABLE :{WHITE}Non puoi costruire la locomotiva
+
+STR_ENGINES :Locomotive
+STR_WAGONS :Vagoni
+
+STR_MASS_STOP_DEPOT_TRAIN_TIP :{BLACK}Clicca per fermare tutti i treni dentro il deposito
+STR_MASS_STOP_DEPOT_ROADVEH_TIP :{BLACK}Clicca per fermare tutti i veicoli stradali dentro il deposito
+STR_MASS_STOP_DEPOT_SHIP_TIP :{BLACK}Clicca per fermare tutte le navi dentro il deposito
+STR_MASS_STOP_HANGAR_TIP :{BLACK}Clicca per fermare tutti gli aerei dentro l'hangar
+
+STR_MASS_START_DEPOT_TRAIN_TIP :{BLACK}Clicca per avviare tutti i treni dentro il deposito
+STR_MASS_START_DEPOT_ROADVEH_TIP :{BLACK}Clicca per avviare tutti i veicoli stradali dentro il deposito
+STR_MASS_START_DEPOT_SHIP_TIP :{BLACK}Clicca per avviare tutte le navi dentro il deposito
+STR_MASS_START_HANGAR_TIP :{BLACK}Clicca per avviare tutti gli aerei dentro l'hangar
+
+STR_MASS_STOP_LIST_TIP :{BLACK}Clicca per fermare tutti i veicoli nella lista
+STR_MASS_START_LIST_TIP :{BLACK}Clicca per far partire i veicoli nella lista
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}Lista dei Cartelli - {COMMA} Cartelli
+
+STR_ORDER_REFIT_FAILED :{WHITE}Ordine fermato per modifica fallita {STRING} {COMMA}
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :Veicoli Ferroviari
+STR_ELRAIL_VEHICLES :Veicoli Ferrovie Elettrificate
+STR_MONORAIL_VEHICLES :Veicoli Monorotaia
+STR_MAGLEV_VEHICLES :Veicoli Maglev
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Costo: {GOLD}{CURRENCY}{BLACK} Peso: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Velocità: {GOLD}{VELOCITY}{BLACK} Potenza: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}Velocità: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Costi d'esercizio: {GOLD}{CURRENCY}/anno
+STR_PURCHASE_INFO_CAPACITY :{BLACK}Capienza: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Progettato nel: {GOLD}{NUM}{BLACK} Vita: {GOLD}{COMMA} anni
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}Max. Affidabilità: {GOLD}{COMMA}%
+STR_PURCHASE_INFO_COST :{BLACK}Costo: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Peso: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Costo: {GOLD}{CURRENCY}{BLACK} Velocità: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Capienza: {GOLD}{COMMA} passeggeri, {COMMA} sacchi postali
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Potenza Vagone: {GOLD}+{POWER}{BLACK} Peso: {GOLD}+{WEIGHT_S}
+STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Modificabile a: {GOLD}
+STR_PURCHASE_INFO_ALL_TYPES :Tutti i tipi di merci
+STR_PURCHASE_INFO_ALL_BUT :Tutti meno {GOLD}
+STR_PURCHASE_INFO_MAX_TE :{BLACK}Sforzo Trazione Max: {GOLD}{FORCE}
+
+########### String for New Landscape Generator
+
+STR_GENERATE :{WHITE}Genera
+STR_RANDOM :{BLACK}Randomizza
+STR_RANDOM_HELP :{BLACK}Cambia il seme casuale usato per la generazione del terreno.
+STR_WORLD_GENERATION_CAPTION :{WHITE}Generazione mondo
+STR_RANDOM_SEED :{BLACK}Seme Casuale:
+STR_RANDOM_SEED_HELP :{BLACK}Clicca per inserire un seme casuale
+STR_LAND_GENERATOR :{BLACK}Generatore terreno:
+STR_TREE_PLACER :{BLACK}Algoritmo alberi:
+STR_HEIGHTMAP_ROTATION :{BLACK}Rotazione Heightmap:
+STR_TERRAIN_TYPE :{BLACK}Tipo terreno:
+STR_QUANTITY_OF_SEA_LAKES :{BLACK}Livello mare:
+STR_SMOOTHNESS :{BLACK}Levigatezza:
+STR_SNOW_LINE_HEIGHT :{BLACK}Altezza nevi perenni:
+STR_DATE :{BLACK}Data:
+STR_NUMBER_OF_TOWNS :{BLACK}Num. of città:
+STR_NUMBER_OF_INDUSTRIES :{BLACK}Num. di industrie:
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_SNOW_LINE_UP :{BLACK}Sposta su di uno l'altezza delle nevi perenni
+STR_SNOW_LINE_DOWN :{BLACK}Sposta giù di uno l'altezza delle nevi perenni
+STR_SNOW_LINE_QUERY_CAPT :{WHITE}Cambia l'altezza delle nevi perenni
+STR_START_DATE_QUERY_CAPT :{WHITE}Cambia l'anno di partenza
+STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Avviso scala
+STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Ridimenzionare di molto la mappa sorgente non è consigliabile. Continuo con la generazione?
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_HEIGHTMAP_NAME :{BLACK}Nome Heightmap:
+STR_HEIGHTMAP_SIZE :{BLACK}Dim.: {ORANGE}{NUM} x {NUM}
+STR_GENERATION_WORLD :{WHITE}Generazione del mondo..
+STR_GENERATION_ABORT :{BLACK}Abortisci
+STR_GENERATION_ABORT_CAPTION :{WHITE}Abortisci Generazione Mondo
+STR_GENERATION_ABORT_MESSAGE :{YELLOW}Vuoi veramente abortire la generazione?
+STR_PROGRESS :{WHITE}{NUM}% completo
+STR_GENERATION_PROGRESS :{BLACK}{NUM} / {NUM}
+STR_WORLD_GENERATION :{BLACK}Generazione mondo
+STR_TREE_GENERATION :{BLACK}Generazione alberi
+STR_UNMOVABLE_GENERATION :{BLACK}Generazione oggetti non spostabili
+STR_CLEARING_TILES :{BLACK}generazione aree brulle e rocciose
+STR_SETTINGUP_GAME :{BLACK}Settaggio del gioco
+STR_PREPARING_TILELOOP :{BLACK}Loop generazione tile del terreno
+STR_PREPARING_GAME :{BLACK}Preparazione del gioco
+STR_DIFFICULTY_TO_CUSTOM :{WHITE}Questa azione cambia il livello di difficolta a custom
+STR_SE_FLAT_WORLD :{WHITE}Terreno piatto
+STR_SE_FLAT_WORLD_TIP :{BLACK}Genera un terreno piatto
+STR_SE_RANDOM_LAND :{WHITE}Terreno casuale
+STR_SE_NEW_WORLD :{BLACK}Crea nuovo scenario
+STR_SE_CAPTION :{WHITE}Tipo Scenario
+STR_FLAT_WORLD_HEIGHT_DOWN :{BLACK}Sposta giù di uno l'altezza del terreno
+STR_FLAT_WORLD_HEIGHT_UP :{BLACK}Sposta su di uno l'altezza del terreno
+STR_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Cambia l'altezza del terreno
+STR_FLAT_WORLD_HEIGHT :{BLACK}Altezza del terreno:
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+STR_SMALLMAP_CENTER :{BLACK}Centra la minimappa sulla posizione corrente
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}Piccolo
+STR_CITY_AIRPORT :{BLACK}Cittadino
+STR_METRO_AIRPORT :{BLACK}Metropolitano
+STR_INTERNATIONAL_AIRPORT :{BLACK}Internazionale
+STR_COMMUTER_AIRPORT :{BLACK}Commuter
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Intercontinentale
+STR_HELIPORT :{BLACK}Eliporto
+STR_HELIDEPOT :{BLACK}Elideposito
+STR_HELISTATION :{BLACK}Elistatione
+
+STR_SMALL_AIRPORTS :{BLACK}Aeroporti piccoli
+STR_LARGE_AIRPORTS :{BLACK}Aeroporti grandi
+STR_HUB_AIRPORTS :{BLACK}Aeroporti Hub
+STR_HELIPORTS :{BLACK}Eliporti
+
+############ Tooltip measurment
+
+STR_MEASURE_LENGTH :{BLACK}Lunghezza: {NUM}
+STR_MEASURE_AREA :{BLACK}Area: {NUM} x {NUM}
+STR_MEASURE_LENGTH_HEIGHTDIFF :{BLACK}Lunghezza: {NUM}{}Differenza in altezza: {NUM} m
+STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}Area: {NUM} x {NUM}{}Differenza in altezza: {NUM} m
+
+########
diff --git a/src/lang/norwegian.txt b/src/lang/norwegian.txt
new file mode 100644
index 000000000..6f24029c6
--- /dev/null
+++ b/src/lang/norwegian.txt
@@ -0,0 +1,3114 @@
+##name Norwegian
+##ownname Norsk, bokmål
+##isocode nb_NO.UTF-8
+##plural 0
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Utenfor kartet
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}For nært kanten av kartet
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Du har ikke nok penger - du trenger {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Flatt land er nødvendig
+STR_0008_WAITING :{BLACK}Venter: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (på vei fra
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Godtar: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Godtar: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :Passasjerer
+STR_0010_COAL :Kull
+STR_0011_MAIL :Post
+STR_0012_OIL :Olje
+STR_0013_LIVESTOCK :Buskap
+STR_0014_GOODS :Gods
+STR_0015_GRAIN :Korn
+STR_0016_WOOD :Tømmer
+STR_0017_IRON_ORE :Jernmalm
+STR_0018_STEEL :Stål
+STR_0019_VALUABLES :Verdisaker
+STR_001A_COPPER_ORE :Kobbermalm
+STR_001B_MAIZE :Mais
+STR_001C_FRUIT :Frukt
+STR_001D_DIAMONDS :Diamanter
+STR_001E_FOOD :Mat
+STR_001F_PAPER :Papir
+STR_0020_GOLD :Gull
+STR_0021_WATER :Vann
+STR_0022_WHEAT :Hvete
+STR_0023_RUBBER :Gummi
+STR_0024_SUGAR :Sukker
+STR_0025_TOYS :Leketøy
+STR_0026_CANDY :Søtsaker
+STR_0027_COLA :Cola
+STR_0028_COTTON_CANDY :Sukkerspinn
+STR_0029_BUBBLES :Bobler
+STR_002A_TOFFEE :Karamell
+STR_002B_BATTERIES :Batterier
+STR_002C_PLASTIC :Plast
+STR_002D_FIZZY_DRINKS :Brus
+STR_002E :
+STR_002F_PASSENGER :Passasjer
+STR_0030_COAL :Kull
+STR_0031_MAIL :Post
+STR_0032_OIL :Olje
+STR_0033_LIVESTOCK :Buskap
+STR_0034_GOODS :Gods
+STR_0035_GRAIN :Korn
+STR_0036_WOOD :Tømmer
+STR_0037_IRON_ORE :Jernmalm
+STR_0038_STEEL :Stål
+STR_0039_VALUABLES :Verdisaker
+STR_003A_COPPER_ORE :Kobbermalm
+STR_003B_MAIZE :Mais
+STR_003C_FRUIT :Frukt
+STR_003D_DIAMOND :Diamant
+STR_003E_FOOD :Mat
+STR_003F_PAPER :Papir
+STR_0040_GOLD :Gull
+STR_0041_WATER :Vann
+STR_0042_WHEAT :Hvete
+STR_0043_RUBBER :Gummi
+STR_0044_SUGAR :Sukker
+STR_0045_TOY :Leketøy
+STR_0046_CANDY :Søtsak
+STR_0047_COLA :Cola
+STR_0048_COTTON_CANDY :Sukkerspinn
+STR_0049_BUBBLE :Boble
+STR_004A_TOFFEE :Karamell
+STR_004B_BATTERY :Batteri
+STR_004C_PLASTIC :Plast
+STR_004D_FIZZY_DRINK :Brus
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} passasjer{P "" er}
+STR_QUANTITY_COAL :{WEIGHT} kull
+STR_QUANTITY_MAIL :{COMMA} postsekk{P "" er}
+STR_QUANTITY_OIL :{VOLUME} olje
+STR_QUANTITY_LIVESTOCK :{COMMA} enhet{P "" er} buskap
+STR_QUANTITY_GOODS :{COMMA} kasse{P "" r} gods
+STR_QUANTITY_GRAIN :{WEIGHT} korn
+STR_QUANTITY_WOOD :{WEIGHT} tømmer
+STR_QUANTITY_IRON_ORE :{WEIGHT} jernmalm
+STR_QUANTITY_STEEL :{WEIGHT} stål
+STR_QUANTITY_VALUABLES :{COMMA} sekk{P "" er} med verdisaker
+STR_QUANTITY_COPPER_ORE :{WEIGHT} kobbermalm
+STR_QUANTITY_MAIZE :{WEIGHT} mais
+STR_QUANTITY_FRUIT :{WEIGHT} frukt
+STR_QUANTITY_DIAMONDS :{COMMA} sekk{P "" er} med diamanter
+STR_QUANTITY_FOOD :{WEIGHT} mat
+STR_QUANTITY_PAPER :{WEIGHT} papir
+STR_QUANTITY_GOLD :{COMMA} sekk{P "" er} med gull
+STR_QUANTITY_WATER :{VOLUME} vann
+STR_QUANTITY_WHEAT :{WEIGHT} hvete
+STR_QUANTITY_RUBBER :{VOLUME} gummi
+STR_QUANTITY_SUGAR :{WEIGHT} sukker
+STR_QUANTITY_TOYS :{COMMA} leke{P "" r}
+STR_QUANTITY_SWEETS :{COMMA} sekk{P "" er} med søtsaker
+STR_QUANTITY_COLA :{VOLUME} cola
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} sukkerspinn
+STR_QUANTITY_BUBBLES :{COMMA} boble{P "" r}
+STR_QUANTITY_TOFFEE :{WEIGHT} karamell
+STR_QUANTITY_BATTERIES :{COMMA} batteri{P "" er}
+STR_QUANTITY_PLASTIC :{VOLUME} plast
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} brus
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}PS
+STR_ABBREV_COAL :{TINYFONT}KL
+STR_ABBREV_MAIL :{TINYFONT}PT
+STR_ABBREV_OIL :{TINYFONT}OL
+STR_ABBREV_LIVESTOCK :{TINYFONT}BS
+STR_ABBREV_GOODS :{TINYFONT}GD
+STR_ABBREV_GRAIN :{TINYFONT}KN
+STR_ABBREV_WOOD :{TINYFONT}VD
+STR_ABBREV_IRON_ORE :{TINYFONT}JM
+STR_ABBREV_STEEL :{TINYFONT}ST
+STR_ABBREV_VALUABLES :{TINYFONT}VS
+STR_ABBREV_COPPER_ORE :{TINYFONT}KM
+STR_ABBREV_MAIZE :{TINYFONT}MS
+STR_ABBREV_FRUIT :{TINYFONT}FT
+STR_ABBREV_DIAMONDS :{TINYFONT}DM
+STR_ABBREV_FOOD :{TINYFONT}MT
+STR_ABBREV_PAPER :{TINYFONT}PR
+STR_ABBREV_GOLD :{TINYFONT}GL
+STR_ABBREV_WATER :{TINYFONT}VN
+STR_ABBREV_WHEAT :{TINYFONT}HV
+STR_ABBREV_RUBBER :{TINYFONT}GM
+STR_ABBREV_SUGAR :{TINYFONT}SK
+STR_ABBREV_TOYS :{TINYFONT}LT
+STR_ABBREV_SWEETS :{TINYFONT}SS
+STR_ABBREV_COLA :{TINYFONT}CL
+STR_ABBREV_CANDYFLOSS :{TINYFONT}SP
+STR_ABBREV_BUBBLES :{TINYFONT}BO
+STR_ABBREV_TOFFEE :{TINYFONT}KM
+STR_ABBREV_BATTERIES :{TINYFONT}BA
+STR_ABBREV_PLASTIC :{TINYFONT}PL
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}MV
+STR_ABBREV_NONE :{TINYFONT}NE
+STR_ABBREV_ALL :{TINYFONT}ALL
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Kart - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Spillinnstillinger
+STR_00B2_MESSAGE :{YELLOW}Melding
+STR_00B3_MESSAGE_FROM :{YELLOW}Melding fra {STRING}
+STR_POPUP_CAUTION_CAPTION :{WHITE}Advarsel!
+STR_00B4_CAN_T_DO_THIS :{WHITE}Kan ikke gjøre dette...
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Kan ikke rydde dette området...
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Opprinnelig opphavsbeskyttet {COPYRIGHT} 1995 Chris Sawyer, Alle rettigheter reservert
+STR_00B7_VERSION :{BLACK}OpenTTD versjon {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 OpenTTD-teamet
+STR_TRANSLATED_BY :{BLACK} Oversetter(e) -
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Avslutt
+STR_00C8_YES :{BLACK}Ja
+STR_00C9_NO :{BLACK}Nei
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Er du sikker på at du vil avslutte og gå tilbake til {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Ingenting
+STR_00D1_DARK_BLUE :Mørkeblå
+STR_00D2_PALE_GREEN :Lysegrønn
+STR_00D3_PINK :Rosa
+STR_00D4_YELLOW :Gul
+STR_00D5_RED :Rød
+STR_00D6_LIGHT_BLUE :Lyseblå
+STR_00D7_GREEN :Grønn
+STR_00D8_DARK_GREEN :Mørkegrønn
+STR_00D9_BLUE :Blå
+STR_00DA_CREAM :Kremgul
+STR_00DB_MAUVE :Fiolett
+STR_00DC_PURPLE :Lilla
+STR_00DD_ORANGE :Oransje
+STR_00DE_BROWN :Brun
+STR_00DF_GREY :Grå
+STR_00E0_WHITE :Hvit
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}For mange kjøretøy i spillet
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Sted
+STR_00E5_CONTOURS :Konturer
+STR_00E6_VEHICLES :Kjøretøy
+STR_00E7_INDUSTRIES :Industrier
+STR_00E8_ROUTES :Ruter
+STR_00E9_VEGETATION :Vegetasjon
+STR_00EA_OWNERS :Eiere
+STR_00EB_ROADS :{BLACK}{TINYFONT}Veier
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Jernbaner
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Stasjoner/Flyplasser/Havner
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Bygninger/Industribygg
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Kjøretøy
+STR_00F0_100M :{BLACK}{TINYFONT}100 m
+STR_00F1_200M :{BLACK}{TINYFONT}200 m
+STR_00F2_300M :{BLACK}{TINYFONT}300 m
+STR_00F3_400M :{BLACK}{TINYFONT}400 m
+STR_00F4_500M :{BLACK}{TINYFONT}500 m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Tog
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Kjøretøy
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Skip
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Fly
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Transportruter
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Kullgruve
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Kraftverk
+STR_00FC_FOREST :{BLACK}{TINYFONT}Skog
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}Sagbruk
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Oljeraffineri
+STR_00FF_FARM :{BLACK}{TINYFONT}GÃ¥rd
+STR_0100_FACTORY :{BLACK}{TINYFONT}Fabrikk
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Trykkeri
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Oljebrønn
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Jerngruve
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Smelteverk
+STR_0105_BANK :{BLACK}{TINYFONT}Bank
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Papirfabrikk
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Gullgruve
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Matforedlingsfabrikk
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Diamantgruve
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Kobbergruve
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Fruktplantasje
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Gummiplantasje
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Vannkilde
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Vanntårn
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}Sagbruk
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Sukkerspinnskog
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Godterifabrikk
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Batterifarm
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Colabrønner
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Lekebutikk
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Lekefabrikk
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Plastfontener
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Brusfabrikk
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Boblegenerator
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Karamellbrudd
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Sukkergruve
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Jernbanestasjon
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Lasteterminal
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Busstasjon
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Flyplass/Helikopterstasjon
+STR_011F_DOCK :{BLACK}{TINYFONT}Kai
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Utmark
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Gress
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Bart land
+STR_0123_FIELDS :{BLACK}{TINYFONT}Jorder
+STR_0124_TREES :{BLACK}{TINYFONT}Trær
+STR_0125_ROCKS :{BLACK}{TINYFONT}Steiner
+STR_0126_WATER :{BLACK}{TINYFONT}Vann
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Ingen eier
+STR_0128_TOWNS :{BLACK}{TINYFONT}Byer
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Industrier
+STR_012A_DESERT :{BLACK}{TINYFONT}Ørken
+STR_012B_SNOW :{BLACK}{TINYFONT}Snø
+STR_012C_MESSAGE :{WHITE}Melding
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Avbryt
+STR_012F_OK :{BLACK}OK
+STR_0130_RENAME :{BLACK}Gi nytt navn
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}For mange navn oppgitt
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Navnet er allerede i bruk
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...eies av {STRING}
+STR_013C_CARGO :{BLACK}Last
+STR_013D_INFORMATION :{BLACK}Informasjon
+STR_013E_CAPACITIES :{BLACK}Kapasitet
+STR_013E_TOTAL_CARGO :{BLACK}Total last
+STR_013F_CAPACITY :{BLACK}Kapasitet: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}Kapasitet: {LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Total kapasitet på dette toget:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}Nytt spill
+STR_0141_LOAD_GAME :{BLACK}Last inn spill
+STR_SINGLE_PLAYER :{BLACK}Énspiller
+STR_MULTIPLAYER :{BLACK}Flerspiller
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Kartstørrelse:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Spillinnstillinger
+
+STR_0150_SOMEONE :noen{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Verdenskart
+STR_0152_TOWN_DIRECTORY :Bykatalog
+STR_0153_SUBSIDIES :Subsidier
+
+STR_UNITS_IMPERIAL :Imperiell
+STR_UNITS_METRIC :Metrisk
+STR_UNITS_SI :SI
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} mpt
+STR_UNITS_VELOCITY_METRIC :{COMMA} km/t
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA} hk
+STR_UNITS_POWER_METRIC :{COMMA} hk
+STR_UNITS_POWER_SI :{COMMA} kW
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA} t
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA} t
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA} kg
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} britisk tonn
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} tonn
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} kg
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA} gal
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA} l
+STR_UNITS_VOLUME_SHORT_SI :{COMMA} m³
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} gallon{P "" s}
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} liter
+STR_UNITS_VOLUME_LONG_SI :{COMMA} m³
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10³ lbf
+STR_UNITS_FORCE_METRIC :{COMMA} tonn kraft
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Fortjenestegraf
+STR_0155_INCOME_GRAPH :Inntektsgraf
+STR_0156_DELIVERED_CARGO_GRAPH :Graf over leverte varer
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Prestasjonhistorikk
+STR_0158_COMPANY_VALUE_GRAPH :Graf over firmaverdi
+STR_0159_CARGO_PAYMENT_RATES :Prisliste for varer
+STR_015A_COMPANY_LEAGUE_TABLE :Firmarangeringstabell
+STR_PERFORMANCE_DETAIL_MENU :Detaljert prestasjonsnivå
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}Om OpenTTD
+STR_015C_SAVE_GAME :Lagre spill
+STR_015D_LOAD_GAME :Last inn spill
+STR_015E_QUIT_GAME :Avslutt gjeldende spill
+STR_015F_QUIT :Avslutt OpenTTD
+STR_ABANDON_GAME_QUERY :{YELLOW}Er du sikker på du vil avslutte dette spillet ?
+STR_0161_QUIT_GAME :{WHITE}Avslutt spill
+STR_SORT_ORDER_TIP :{BLACK}Velg sorteringsrekkefølge (synkende/stigende)
+STR_SORT_CRITERIA_TIP :{BLACK}Velg sorteringskriterier
+STR_SORT_BY :{BLACK}Sorter etter
+
+STR_SORT_BY_POPULATION :{BLACK}Innbyggertall
+STR_SORT_BY_PRODUCTION :{BLACK}Produksjon
+STR_SORT_BY_TYPE :{BLACK}Type
+STR_SORT_BY_TRANSPORTED :{BLACK}Transportert
+STR_SORT_BY_NAME :{BLACK}Navn
+STR_SORT_BY_DROPDOWN_NAME :Navn
+STR_SORT_BY_DATE :{BLACK}Dato
+STR_SORT_BY_NUMBER :Nummer
+STR_SORT_BY_PROFIT_LAST_YEAR :Fortjeneste forrige år
+STR_SORT_BY_PROFIT_THIS_YEAR :Fortjeneste i år
+STR_SORT_BY_AGE :Alder
+STR_SORT_BY_RELIABILITY :PÃ¥litelighet
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Total kapasitet per varetype
+STR_SORT_BY_MAX_SPEED :Maksimal fart
+STR_SORT_BY_MODEL :Modell
+STR_SORT_BY_VALUE :Verdi
+STR_SORT_BY_FACILITY :Stasjonstype
+STR_SORT_BY_WAITING :Verdi av ventende last
+STR_SORT_BY_RATING_MAX :Vurdering av last
+STR_ENGINE_SORT_ENGINE_ID :MaskinID (klassisk type)
+STR_ENGINE_SORT_COST :Kostnad
+STR_ENGINE_SORT_POWER :Kraft
+STR_ENGINE_SORT_INTRO_DATE :Introduksjonsdato
+STR_ENGINE_SORT_RUNNING_COST :Driftskostnad
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Kraft/Driftskostnad
+STR_ENGINE_SORT_CARGO_CAPACITY :Lastkapasitet
+STR_NO_WAITING_CARGO :{BLACK}Ingen last venter
+STR_SELECT_ALL_FACILITIES :{BLACK}Velg alle anlegg
+STR_SELECT_ALL_TYPES :{BLACK}Velg alle lasttyper (inkludert last som ikke venter)
+STR_AVAILABLE_ENGINES_TIP :{BLACK}Se en liste over tilgjengelige maskindesigner for dette kjøretøyet.
+STR_MANAGE_LIST :{BLACK}Behandl liste
+STR_MANAGE_LIST_TIP :{BLACK}Send instruksjoner til alle kjøretøyer i denne listen
+STR_REPLACE_VEHICLES :Bytt ut kjøretøy
+STR_SEND_TRAIN_TO_DEPOT :Send til depoet
+STR_SEND_ROAD_VEHICLE_TO_DEPOT :Send til depoet
+STR_SEND_SHIP_TO_DEPOT :Send til depoet
+STR_SEND_AIRCRAFT_TO_HANGAR :Send til hangar
+STR_SEND_FOR_SERVICING :Send til vedlikehold
+
+############ range for months starts
+STR_0162_JAN :Jan
+STR_0163_FEB :Feb
+STR_0164_MAR :Mar
+STR_0165_APR :Apr
+STR_0166_MAY :Mai
+STR_0167_JUN :Jun
+STR_0168_JUL :Jul
+STR_0169_AUG :Aug
+STR_016A_SEP :Sep
+STR_016B_OCT :Okt
+STR_016C_NOV :Nov
+STR_016D_DEC :Des
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Pause
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Lagre spill, avbryt spillet, avslutte
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Vis liste over firmaets stasjoner
+STR_0174_DISPLAY_MAP :{BLACK}Vis kart
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Vis kart og byoversikt
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Vis byoversikt
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Vis firmaets økonomiske data
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Vis firmaets generelle data
+STR_0179_DISPLAY_GRAPHS :{BLACK}Vis grafer
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Vis firmarangeringstabell
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Vis liste over firmaets tog
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Vis liste over firmaets biler
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Vis liste over firmaets skip
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Vis liste over firmaets fly
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Zoom inn
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Zoom ut
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Bygg jernbanespor
+STR_0182_BUILD_ROADS :{BLACK}Bygg vei
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Bygg kaier
+STR_0184_BUILD_AIRPORTS :{BLACK}Bygg flyplasser
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Plant trær, skilt, o.l.
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Informasjon om felt
+STR_0187_OPTIONS :{BLACK}Innstillinger
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Kan ikke endre serviceintervall...
+STR_018B_CLOSE_WINDOW :{BLACK}Lukk vindu
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Vindustittel - dra her for å flytte vindu
+STR_STICKY_BUTTON :{BLACK}Beskytt dette vinduet mot 'Lukk alle vinduer'-knappen
+STR_RESIZE_BUTTON :{BLACK}Klikk og dra for å endre størrelsen på vinduet
+STR_SAVELOAD_HOME_BUTTON :{BLACK}Klikk her for å komme til standardmappen for lagring og lasting
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Riv bygninger o.l.
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Senk et hjørne av et landstykke
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Hev et hjørne av et landstykke
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Scroll bar - scroller listen opp/ned
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Rullefelt - ruller listen til venstre/høyre
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Vis landkonturer på kartet
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Vis kjøretøy på kartet
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Vis industri på kartet
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Vis transportruter på kartet
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Vis vegetasjon på kartet
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Vis landeiere på kartet
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Skru av/på bynavn på kartet
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Fortjeneste i år: {CURRENCY} (sist år: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} år ({COMMA})
+STR_AGE_RED :{RED}{COMMA} år ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Kjøretøy
+STR_019D_AIRCRAFT :Fly
+STR_019E_SHIP :Skip
+STR_019F_TRAIN :Tog
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} er gammel
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} er veldig gammel
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} er veldig gammel og må byttes ut snarest
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Informasjon om felt
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Fjerningskostnad: {LTBLUE}N/A
+STR_01A5_COST_TO_CLEAR :{BLACK}Fjerningskostnad: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :N/A
+STR_01A7_OWNER :{BLACK}Eier: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Lokal myndighet: {LTBLUE}{STRING}
+STR_01A9_NONE :Ingen
+STR_01AA_NAME :{BLACK}Navn
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1.
+STR_01AD_2ND :2.
+STR_01AE_3RD :3.
+STR_01AF_4TH :4.
+STR_01B0_5TH :5.
+STR_01B1_6TH :6.
+STR_01B2_7TH :7.
+STR_01B3_8TH :8.
+STR_01B4_9TH :9.
+STR_01B5_10TH :10.
+STR_01B6_11TH :11.
+STR_01B7_12TH :12.
+STR_01B8_13TH :13.
+STR_01B9_14TH :14.
+STR_01BA_15TH :15.
+STR_01BB_16TH :16.
+STR_01BC_17TH :17.
+STR_01BD_18TH :18.
+STR_01BE_19TH :19.
+STR_01BF_20TH :20.
+STR_01C0_21ST :21.
+STR_01C1_22ND :22.
+STR_01C2_23RD :23.
+STR_01C3_24TH :24.
+STR_01C4_25TH :25.
+STR_01C5_26TH :26.
+STR_01C6_27TH :27.
+STR_01C7_28TH :28.
+STR_01C8_29TH :29.
+STR_01C9_30TH :30.
+STR_01CA_31ST :31.
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Godtatte varer: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Jazz-jukeboks
+STR_01D3_SOUND_MUSIC :Lyd/musikk
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Vis lyd-/musikkinnstillinger
+STR_01D5_ALL :{TINYFONT}Alle
+STR_01D6_OLD_STYLE :{TINYFONT}Gamle slagere
+STR_01D7_NEW_STYLE :{TINYFONT}Nye godbiter
+STR_01D8_EZY_STREET :{TINYFONT}Ezy Street
+STR_01D9_CUSTOM_1 :{TINYFONT}Egendefinert 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Egendefinert 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Musikkvolum
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Lydeffektvolum
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MIN ' ' ' ' ' ' MAX
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Spill forrige spor
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Spill neste spor
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Stopp musikken
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Start musikken
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Dra for å endre volum på musikk og lydeffekter
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Spor{SETX 88}Tittel
+STR_01E9_SHUFFLE :{TINYFONT}Tilfeldig
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Program
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Musikkprogram
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Sporregister
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Program - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}Tøm
+STR_01F1_SAVE :{TINYFONT}{BLACK}Lagre
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Gjeldene program for musikkspor
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Velg alle spor
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Velg 'old style music'-program
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Velg 'new style music'-program
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Velg 'Egendefinert 1'-program
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Velg 'Egendefinert 2'-program
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Slett gjeldende program (Gjelder bare Egendefinert 1 og 2)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Lagre musikkvalg
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Klikk på musikkspor for å legge til gjeldene program (Gjelder bare egendefinert 1 og 2)
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Klikk på et musikkspor for å fjerne det fra nåværende program (Gjelder bare egendefinert 1 og 2)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Skru tilfeldig program av/på
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Vis musikkspormeny
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Trykk for å sentere bildet rundt industri/by
+STR_01FE_DIFFICULTY :{BLACK}Vanskelighetsgrad ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Siste melding/nyhet
+STR_0201_MESSAGE_SETTINGS :Meldingsinnstillinger
+STR_MESSAGE_HISTORY_MENU :Tidligere meldinger
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Vis siste melding/nyhet, vis meldingsinnstillinger
+STR_0204_MESSAGE_OPTIONS :{WHITE}Meldingsinnstillinger
+STR_0205_MESSAGE_TYPES :{BLACK}Meldingstyper:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Ankommst av første kjøretøy på spillers stasjon
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Ankommst av første kjøretøy på motstanders stasjon
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Ulykker/katastrofer
+STR_0209_COMPANY_INFORMATION :{YELLOW}Firmainformasjon
+STR_020A_ECONOMY_CHANGES :{YELLOW}Økonomiske endringer
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Råd/informasjon om spillers kjøretøy
+STR_020C_NEW_VEHICLES :{YELLOW}Nye kjøretøy
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Endringer i godtatte varer
+STR_020E_SUBSIDIES :{YELLOW}Subsidier
+STR_020F_GENERAL_INFORMATION :{YELLOW}Generell informasjon
+STR_MESSAGES_ALL :{YELLOW}Innstilling for alle meldingstyper (på/av/sammendrag)
+STR_MESSAGE_SOUND :{YELLOW}Spill av lyd for nyhetssammendrag
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...for langt i fra forrige destinasjon
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Beste firma som nådde {NUM}{}({STRING} Nivå)
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Firmarangering i {NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Forretningsmann
+STR_0214_ENTREPRENEUR :Entreprenør
+STR_0215_INDUSTRIALIST :Industrialist
+STR_0216_CAPITALIST :Kapitalist
+STR_0217_MAGNATE :Magnat
+STR_0218_MOGUL :Mogul
+STR_0219_TYCOON_OF_THE_CENTURY :Ã…rhundrets finansfyrste
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} oppnår '{STRING}'-status!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} fra {COMPANY} oppnår '{STRING}'-status!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Lag scenario
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Scenarioredigerer
+STR_0223_LAND_GENERATION :{WHITE}Landgenerering
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Tilfeldig landforming
+STR_0227_RESET_LAND :{BLACK}Tilbakestill land
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Øk størrelse av landareal å heve/senke
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Mink størrelse av landareal å heve/senke
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Generer tilfeldig landskap
+STR_022B_RESET_LANDSCAPE :{BLACK}Tilbakestill landskap
+STR_022C_RESET_LANDSCAPE :{WHITE}Tilbakestill landskap
+STR_LOAD_GAME_HEIGHTMAP :{WHITE}Bruk høydekart
+STR_LOAD_SCEN_HEIGHTMAP :{BLACK}Bruk høydekart
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Er du sikkert på du vil tilbakestille landskapet?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Landskapsgenerering
+STR_022F_TOWN_GENERATION :{BLACK}Bygenerering
+STR_0230_INDUSTRY_GENERATION :{BLACK}Industrigenerering
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Veibygging
+STR_0233_TOWN_GENERATION :{WHITE}Bygenerering
+STR_0234_NEW_TOWN :{BLACK}Ny by
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Grunnlegg en ny by
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Kan ikke grunnlegge by her...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...for nært kanten av kartet
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...for nært en annen by
+STR_0239_SITE_UNSUITABLE :{WHITE}...feltet er uskikket
+STR_023A_TOO_MANY_TOWNS :{WHITE}...for mange byer
+STR_CANNOT_GENERATE_TOWN :{WHITE}Kan ikke bygge byer
+STR_NO_SPACE_FOR_TOWN :{WHITE}...der er ikke mer plass på kartet
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Øk bystørrelse
+STR_023C_EXPAND :{BLACK}Utvid
+STR_023D_RANDOM_TOWN :{BLACK}Lag tilfeldig by
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Grunnlegg by et tilfeldig sted
+STR_023F_INDUSTRY_GENERATION :{WHITE}Industrigenerering
+STR_0240_COAL_MINE :{BLACK}Kullgruve
+STR_0241_POWER_STATION :{BLACK}Kraftstasjon
+STR_0242_SAWMILL :{BLACK}Sagbruk
+STR_0243_FOREST :{BLACK}Skog
+STR_0244_OIL_REFINERY :{BLACK}Oljeraffineri
+STR_0245_OIL_RIG :{BLACK}Oljeplatform
+STR_0246_FACTORY :{BLACK}Fabrikk
+STR_0247_STEEL_MILL :{BLACK}Smelteverk
+STR_0248_FARM :{BLACK}GÃ¥rd
+STR_0249_IRON_ORE_MINE :{BLACK}Jerngruve
+STR_024A_OIL_WELLS :{BLACK}Oljebrønner
+STR_024B_BANK :{BLACK}Bank
+STR_024C_PAPER_MILL :{BLACK}Papirfabrikk
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Matforedlingsfabrikk
+STR_024E_PRINTING_WORKS :{BLACK}Trykkeri
+STR_024F_GOLD_MINE :{BLACK}Gullgruve
+STR_0250_LUMBER_MILL :{BLACK}Sagbruk
+STR_0251_FRUIT_PLANTATION :{BLACK}Fruktplantasje
+STR_0252_RUBBER_PLANTATION :{BLACK}Gummiplantasje
+STR_0253_WATER_SUPPLY :{BLACK}Vannreservoar
+STR_0254_WATER_TOWER :{BLACK}Vanntårn
+STR_0255_DIAMOND_MINE :{BLACK}Diamantgruve
+STR_0256_COPPER_ORE_MINE :{BLACK}Kobbergruve
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Sukkerspinnskog
+STR_0258_CANDY_FACTORY :{BLACK}Søtsakfabrikk
+STR_0259_BATTERY_FARM :{BLACK}Batterigård
+STR_025A_COLA_WELLS :{BLACK}Colabrønner
+STR_025B_TOY_SHOP :{BLACK}Leketøysbutikk
+STR_025C_TOY_FACTORY :{BLACK}Leketøysfabrikk
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Plastfontener
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Mineralvannfabrikk
+STR_025F_BUBBLE_GENERATOR :{BLACK}Boblegenerator
+STR_0260_TOFFEE_QUARRY :{BLACK}Karamellbrudd
+STR_0261_SUGAR_MINE :{BLACK}Sukkergruve
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Bygg kullgruve
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Bygg kraftstasjon
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Bygg sagbruk
+STR_0265_PLANT_FOREST :{BLACK}Plant skog
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Bygg oljeraffineri
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Bygg oljeplatform (kan kun bygges nær kanten av kartet)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Bygg fabrikk
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Bygg smelteverk
+STR_026A_CONSTRUCT_FARM :{BLACK}Bygg gård
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Bygg jerngruve
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Bygg oljebrønn
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Bygg bank (kan kun bygges i byer med flere enn 1200 innbyggere)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Bygg papirfabrikk
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Bygg matforedlingsfabrikk
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Bygg trykkeri
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Bygg gullgruve
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Bygg bank (kan kun bygges i byer)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Bygg sagbruk (fjerner regnskog og produserer tømmer)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Plant fruktplantasje
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Plant gummiplantasje
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Bygg vannreservoar
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Bygg vanntårn (kan kun bygges i byer)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Bygg diamantgruve
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Bygg kobbergruve
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Plant sukkerspinnskog
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Bygg søtsakfabrikk
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Bygg batterigård
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Bygg colabrønn
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Bygg leketøysbutikk
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Bygg leketøysfabrikk
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Bygg plastfontener
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Bygg mineralvannfabrikk
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Bygg boblegenerator
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Bygg karamellbrudd
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Bygg sukkergruve
+STR_0285_CAN_T_BUILD_HERE :{WHITE}Kan ikke bygge {STRING} her...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...må bygge en by først
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...kun én er tillatt per by
+STR_0288_PLANT_TREES :{BLACK}Plant trær
+STR_0289_PLACE_SIGN :{BLACK}Plasser skilt
+STR_028A_RANDOM_TREES :{BLACK}Plant trær tilfeldig
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Plasser trær tilfeldig i landskapet
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Plasser steinete felt i landskapet
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Plasser fyrtårn
+STR_028E_PLACE_TRANSMITTER :{BLACK}Plasser radiosender
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Definer ørkenområde.{}Trykk og hold inne CTRL for å fjerne den
+STR_CREATE_LAKE :{BLACK}Definer vannområde.{}Det vil oversvømme området rundt hvis det er på sjønivå
+STR_0290_DELETE :{BLACK}Slett
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Slett denne byen fullstendig
+STR_0292_SAVE_SCENARIO :Lagre scenario
+STR_0293_LOAD_SCENARIO :Last inn scenario
+STR_0294_QUIT_EDITOR :Avslutt redigeringsprogram
+STR_0295 :
+STR_0296_QUIT :Avslutt
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Lagre scenario, laste inn scenario, forlate redigeringsprogrammet, avslutte
+STR_0298_LOAD_SCENARIO :{WHITE}Last inn scenario
+STR_0299_SAVE_SCENARIO :{WHITE}Lagre scenario
+STR_029A_PLAY_SCENARIO :{BLACK}Spill scenario
+STR_PLAY_HEIGHTMAP :{BLACK}Spill høydekart
+STR_PLAY_HEIGHTMAP_HINT :{BLACK}Start et nytt spill, bruk et høydekart som landskap
+STR_QUIT_SCENARIO_QUERY :{YELLOW}Er du sikker på du vil forlate dette scenariet?
+STR_029C_QUIT_EDITOR :{WHITE}Avslutt redigeringsprogrammet
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...kan kun bygges i byer med mer en 1200 innbyggere
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Flytt startdatoen tilbake ett år
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Flytt startdatoen frem ett år
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...broens ender må være på land
+STR_02A1_SMALL :{BLACK}Liten
+STR_02A2_MEDIUM :{BLACK}Middels
+STR_02A3_LARGE :{BLACK}Stor
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Velg bystørrelse
+STR_02A5_TOWN_SIZE :{YELLOW}Bystørrelse:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Vis siste melding eller nyhetsrapport
+STR_OFF :Av
+STR_SUMMARY :Sammendrag
+STR_FULL :Fullt
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Byoversikt
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Navn på kjøretøy
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Standard
+STR_02BF_CUSTOM :Egendefinert
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Lagre egendefinerte navn
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Velg navn på kjøretøy
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Lagre egendefinerte navn på kjøretøy
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Spillinnstillinger
+STR_02C5_DIFFICULTY_SETTINGS :Vanskelighetsgrad
+STR_02C7_CONFIG_PATCHES :Konfigurer patcher
+STR_NEWGRF_SETTINGS :Innstillinger for ny grafikk
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Vis bynavn
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Vis stasjonsnavn
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Vis skilt
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Vis kontrollpunkt
+STR_02D0_FULL_ANIMATION :{SETX 12}Fullstending animasjon
+STR_02D2_FULL_DETAIL :{SETX 12}Maksimalt med detaljer
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Gjennomsiktige bygninger
+STR_TRANSPARENT_SIGNS :{SETX 12}Gjennomsiktige stasjonsnavn
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Informasjon om felt
+STR_02D6 :
+STR_CONSOLE_SETTING :Vis/skjul konsoll
+STR_02D7_SCREENSHOT_CTRL_S :Skjermdump (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Stor skjermdump (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :Om 'OpenTTD'
+############ range ends here
+
+STR_02DB_OFF :{BLACK}Av
+STR_02DA_ON :{BLACK}PÃ¥
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Vis subsidier
+STR_02DD_SUBSIDIES :Subsidier
+STR_02DE_MAP_OF_WORLD :Verdenskart
+STR_EXTRA_VIEW_PORT :Ekstra vindu
+STR_SIGN_LIST :Skiltliste
+STR_02DF_TOWN_DIRECTORY :Byoversikt
+STR_TOWN_POPULATION :{BLACK}Verdensbefolkning: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Vindu {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Kopier til vindu
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Kopier stedet til den globale synsvinkelen til dette vinduet
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Kopier fra vindu
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Kopier stedet til dette vinduet til den globale synsvinkelen
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Valutaenhet
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Velg valutaenhet
+STR_MEASURING_UNITS :{BLACK}Oppmålingsenheter
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Oppmålingsenhetsutvelging
+STR_02E6_ROAD_VEHICLES :{BLACK}Kjøreretning
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Velg kjøreretning
+STR_02E9_DRIVE_ON_LEFT :Kjør på venstre side
+STR_02EA_DRIVE_ON_RIGHT :Kjør på høyre side
+STR_02EB_TOWN_NAMES :{BLACK}Bynavn
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Velg bynavntype
+
+STR_02F4_AUTOSAVE :{BLACK}Automatisk lagring
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Velg intervall for automatisk lagring
+STR_02F7_OFF :Av
+STR_02F8_EVERY_3_MONTHS :Hver 3. måned
+STR_02F9_EVERY_6_MONTHS :Hver 6. måned
+STR_02FA_EVERY_12_MONTHS :Hver 12. måned
+STR_02FB_START_A_NEW_GAME :{BLACK}Start nytt spill
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Last inn et lagret spill
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Spesiallag en spillverden eller et scenario
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Velg énspiller-modus
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Velg flerspiller-spill med 2-8 spillere
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Vis spillinnstillinger
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Vis vanskelighetsgrad
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Start et nytt spill som bruker et scenario
+STR_0304_QUIT :{BLACK}Avslutt
+STR_0305_QUIT_OPENTTD :{BLACK}Avslutt 'OpenTTD'
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...kan kun bygges i byer
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Velg temperert miljø
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Velg subartisk miljø
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Velg subtropisk miljø
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Velg leketøyland-miljø
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Finansier bygging av ny industri
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Oversikt over industrier
+STR_0313_FUND_NEW_INDUSTRY :Finansier ny industri
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Finansier ny industri
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...kan kun bygges i byer
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...kan kun bygges i regnskogområder
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...kan kun bygges i ørkenområder
+STR_0319_PAUSED :{YELLOW}* * PAUSE * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Skjermdumpen ble lagret som '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}Skjermdump mislyktes!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Kjøp land for fremtidig bruk
+STR_032F_AUTOSAVE :{RED}AUTOLAGRING
+STR_SAVING_GAME :{RED}* * LAGRER SPILL * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}Lagring foregår enda,{}vennligst vent til det er ferdig!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Velg 'Ezy style music'-program
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :Engelsk
+STR_TOWNNAME_FRENCH :Fransk
+STR_TOWNNAME_GERMAN :Tysk
+STR_TOWNNAME_ADDITIONAL_ENGLISH :Engelsk (utvidet)
+STR_TOWNNAME_LATIN_AMERICAN :Latinamerikansk
+STR_TOWNNAME_SILLY :TÃ¥pelige
+STR_TOWNNAME_SWEDISH :Svensk
+STR_TOWNNAME_DUTCH :Nederlandsk
+STR_TOWNNAME_FINNISH :Finsk
+STR_TOWNNAME_POLISH :Polsk
+STR_TOWNNAME_SLOVAKISH :Slovakisk
+STR_TOWNNAME_NORWEGIAN :Norsk
+STR_TOWNNAME_HUNGARIAN :Ungarsk
+STR_TOWNNAME_AUSTRIAN :Østerriksk
+STR_TOWNNAME_ROMANIAN :Rumensk
+STR_TOWNNAME_CZECH :Tsjekkisk
+STR_TOWNNAME_SWISS :Sveitsisk
+STR_TOWNNAME_DANISH :Dansk
+STR_TOWNNAME_TURKISH :Tyrkisk
+STR_TOWNNAME_ITALIAN :Italiensk
+STR_TOWNNAME_CATALAN :Katalansk
+############ end of townname region
+
+STR_CURR_GBP :Pund (£)
+STR_CURR_USD :Dollar ($)
+STR_CURR_EUR :Euro (€)
+STR_CURR_YEN :Yen (Â¥)
+STR_CURR_ATS :Østerriksk shilling (ATS)
+STR_CURR_BEF :Belgisk franc (BEF)
+STR_CURR_CHF :Sveitsisk franc (CHF)
+STR_CURR_CZK :Tsjekkisk koruna (CZK)
+STR_CURR_DEM :Tyske mark (DEM)
+STR_CURR_DKK :Dansk krone (DKK)
+STR_CURR_ESP :Pesetas (ESP)
+STR_CURR_FIM :Finske mark (FIM)
+STR_CURR_FRF :Frank (FRF)
+STR_CURR_GRD :Gresk drakme (GRD)
+STR_CURR_HUF :Ungarsk forint (HUF)
+STR_CURR_ISK :Islandsk krone (ISK)
+STR_CURR_ITL :Italiensk lire (ITL)
+STR_CURR_NLG :Hollandsk guilder (NLG)
+STR_CURR_NOK :Norsk krone (NOK)
+STR_CURR_PLN :Polsk zloty (PLN)
+STR_CURR_ROL :Rumensk leu (ROL)
+STR_CURR_RUR :Russisk rubel (RUR)
+STR_CURR_SIT :Slovensk tolar (SIT)
+STR_CURR_SEK :Svensk krone (SEK)
+STR_CURR_YTL :Tyrkiske lire (YTL)
+STR_CURR_SKK :Slovakisk Koruna (SKK)
+STR_CURR_BRR :Brasiliansk Real (BRL)
+
+STR_CURR_CUSTOM :Egendefinert...
+
+STR_OPTIONS_LANG :{BLACK}Språk
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Velg språk som skal brukes
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Fullskjerm
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}Kryss av i denne boksen for å spille OpenTTD i fullskjermmodus
+
+STR_OPTIONS_RES :{BLACK}Skjermoppløsning
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Velg skjermoppløsningen som skal brukes
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Filformat for skjermdump
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Velg hvilket format skjermdumpet skal lagers i
+
+STR_AUTOSAVE_1_MONTH :Hver måned
+STR_AUTOSAVE_FAILED :{WHITE}Autolagring feilet
+
+STR_MONTH_JAN :januar
+STR_MONTH_FEB :februar
+STR_MONTH_MAR :mars
+STR_MONTH_APR :april
+STR_MONTH_MAY :mai
+STR_MONTH_JUN :juni
+STR_MONTH_JUL :juli
+STR_MONTH_AUG :august
+STR_MONTH_SEP :september
+STR_MONTH_OCT :oktober
+STR_MONTH_NOV :november
+STR_MONTH_DEC :desember
+
+STR_HEADING_FOR_STATION :{LTBLUE}PÃ¥ vei til {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}PÃ¥ vei til {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Ingen ordre
+STR_NO_ORDERS_VEL :{LTBLUE}Ingen ordre, {VELOCITY}
+
+STR_PASSENGERS :passasjerer
+STR_BAGS :sekker
+STR_TONS :tonn
+STR_LITERS :liter
+STR_ITEMS :enheter
+STR_CRATES :kasser
+STR_RES_OTHER :annet
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Kan ikke dele ordre liste...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Kan ikke kopiere ordreliste...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - Slutt på delte ordre - -
+
+STR_TRAIN_IS_LOST :{WHITE}Tog {COMMA} har kjørt seg vill.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}Tog {COMMA}s fortjeneste sist år var {CURRENCY}
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}Europeisk valutunion!{}{} Euro er introdusert som den utelukkede valuttaen for hverdagslige forretninger i landet ditt!
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Tog {COMMA} har for få ordrer i kjøreplanen
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}Tog {COMMA} har en tom ordre
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}Tog {COMMA} har to like ordrer
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}Tog {COMMA} har en ugyldig stasjon i ordrene
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}Kjøretøy {COMMA} har for få ordre i kjøreplanen
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}Kjøretøy {COMMA} har en tom ordre
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}Kjøretøy {COMMA} har to like ordrer
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}Kjøretøy {COMMA} har en ugyldig stasjon i ordrene
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}Skip {COMMA} har for få ordrer i kjøreplanen
+STR_SHIP_HAS_VOID_ORDER :{WHITE}Skip {COMMA} har en tom ordre
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}Ship {COMMA} har to like ordrer
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}Skip {COMMA} har en ugyldig stasjon i ordrene
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}Fly {COMMA} har for få ordrer i kjøreplanen
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}Fly {COMMA} har en tom ordre
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}Fly {COMMA} har to like ordrer
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}Fly {COMMA} har en ugyldig stasjon i ordrene
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}Autoforny feilet på tog {COMMA} (money limit)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}Autoforny feilet på kjøretøy {COMMA} (pengegrense)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}Autoforny feilet på skip {COMMA} (pengegrense)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}Autoforny feilet på fly {COMMA} (pengegrense)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}Toget {COMMA} er for langt etter erstatting
+
+STR_CONFIG_PATCHES :{BLACK}Patchinnstillinger
+STR_CONFIG_PATCHES_TIP :{BLACK}Endre patchinnstillinger
+STR_CONFIG_PATCHES_CAPTION :{WHITE}Patchinstillinger
+
+STR_CONFIG_PATCHES_OFF :Av
+STR_CONFIG_PATCHES_ON :PÃ¥
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Vis kjøretøyets hastighet på statuslinja: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Tillat bygging på skråninger og i vannkanten: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Mer realistisk størrelse på oppfangingsområder: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Tillat riving av industri, mer vei, etc: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Tillat bygging av veldig lange tog : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Realistisk akslerasjon for tog: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Forby tog og skip mot å gjøre 90-graders svinger: {ORANGE}{STRING} {LTBLUE} (trenger NGR)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Slå sammen stasjoner som blir bygget på siden av hverandre: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Forlat stasjonen når én type varevogn er full, hvis 'full last' er på: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Bruk forbedret lastingsalgoritme: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GRADUAL_LOADING :{LTBLUE}Last kjøretøy gradvis: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Inflasjon: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Lever varer til en stasjon bare når varen trengs: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Tillat bygging av veldig lange broer: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Tillat 'gå til jernbanestall'-ordre: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Tillat bygging av anlegg som produserer råmaterialer: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Tillat flere like industrier i samme by: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Industrier av samme type kan bygges nær hverandre: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Vis alltid lang dato på statuslinjen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Vis jernbanesignaler på samme side som kjøreretningen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Vis regnskap ved nyttår: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}TTDPatch-kompatibel nonstop-håndtering: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Kjøretøykø (med kvantumseffekter): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Flytt på bildet hvis pilen er nær ytterkantene av skjermen: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Tillat bestikkelser av bystyret: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Ikke-ensartede stasjoner: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Ny global rutesøking (NGR, overstyrer NTK): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FREIGHT_TRAINS :{LTBLUE}Vektmultiplikator for frakt til å simulere tunge tog: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Alltid tillat bygging av små flyplasser: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Vis en advarsel hvis et tog har kjørt seg vill{ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Inspiser kjøretøyenes ordrer: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :nei
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :ja, men ekskluder stoppede kjøretøy
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :av alle kjøretøy
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Advar hvis et tog går i underskudd: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Kjøretøy utgår aldri: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Bytt automatisk ut kjøretøy når det blir gammelt:
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Autoforny når kjøretøy er {ORANGE}{STRING}{LTBLUE} måneder før/etter maks alder
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Autoforny minimum penger trengst for fornying: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Varighet til feilmelding: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Vis byers befolkning i tittel: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Usynlige trær (med gjennomsiktige bygninger): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Landskapsgenerator: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :Orginal
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis
+STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}Maksimum avstand fra kartkant for oljerafinerier {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Snøhøyde: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN :{LTBLUE}Ulendthet på terreng (kun TerraGenesis): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Veldig levnt
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH :Jevnt
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH :Ulendt
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :Veldig ulendt
+STR_CONFIG_PATCHES_TREE_PLACER :{LTBLUE}Treplasseringalgoritme: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TREE_PLACER_NONE :Ingen
+STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL :Original
+STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED :Forbedret
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION :{LTBLUE}Høydekartrotering: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Mot klokka
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE :Med klokka
+STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT :{LTBLUE}Høyden et flatt scenariokart får: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Maks stasjonspedning: {ORANGE}{STRING} {RED}Advarsel: Høy instilling gir tregere spill
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Utfør vedlikehold på helikopter automatisk på helikopterlandingsteder: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Koble landskapsverktøylinja til tog-/vei-/vann- og flyplassverktøylinjene: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Ved rulling med musen, flytt synsvinkelen i den motsatte retning: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Vis et målings-verktøytips når forskjellige "build-tools" brukes: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Vis firmaovertakelser: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES_NONE :Ingen
+STR_CONFIG_PATCHES_LIVERIES_OWN :Eget firma
+STR_CONFIG_PATCHES_LIVERIES_ALL :Alle firmaer
+STR_CONFIG_PATCHES_PREFER_TEAMCHAT :{LTBLUE}Foretrekk lagchat med <ENTER>: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Maks antall tog per spiller: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Maks antall kjøretøy per spiller: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}Maks antall fly per spiller: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}Maks antall skip per spiller: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Hindre datamaskinen i å bygge tog: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Hindre datamaskinen i å bygge kjøretøy: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Hindre datamaskinen i å bygge fly: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Hindre datamaskinen i å bygge skip: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Aktiver ny AI (alfa): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Tillat AI-spillere i flerspillermodus (eksperimentelt): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Standard vedlikeholdsintervall for tog: {ORANGE}{STRING} dager
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Standard vedlikeholdsintervall for tog: {ORANGE}deaktivert
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Standard vedlikeholdsintervall for kjøretøy: {ORANGE}{STRING} dager
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Standard vedlikeholdsintervall for kjøretøy: {ORANGE}deaktivert
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Standard vedlikeholdintervall for fly: {ORANGE}{STRING} dager
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Standard vedlikeholdintervall for kjøretøy: {ORANGE}deaktivert
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Standard vedlikeholdsintervall for båter: {ORANGE}{STRING} dager
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Standard vedlikeholdsintervall for skip: {ORANGE}deaktivert
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Deaktiver vedlikehold når havarier er slått av: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Aktiver fartsgrenser for vogner: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}Deaktiver elektriske tog: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Farge i avisen kommer i: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Start spillet i år: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}Spillet slutter {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Jevn økonomi (flere mindre endringer)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Tillat kjøping av aksjer i andre selskaper
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Ved opptrekking plasser signal hver: {ORANGE}{STRING} rute(r)
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Plassering av hovedverktøylinje: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Venstre
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Midtstilt
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Høyre
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Knipseradius for vindu: {ORANGE}{STRING} px
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Knipseradius for vindu: {ORANGE}deaktivert
+
+STR_CONFIG_PATCHES_GUI :{BLACK}Grensesnitt
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Konstruksjon
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Kjøretøy
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Statsjoner
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Økonomi
+STR_CONFIG_PATCHES_AI :{BLACK}Motstandere
+
+STR_CONFIG_PATCHES_DISABLED :slått av
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Endre innstillingsverdi
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Noen eller alle av standard vedlikeholdsintervall(ene) under er inkompatible med valgte instillinger! 5-90 % og 30-800 dager er gyldige
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}Skip skal bruke YAPF: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}Kjøretøy skal bruke YAPF: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}Tog skal bruke YAPF: {ORANGE}{STRING}
+
+STR_TEMPERATE_LANDSCAPE :Temperert landskap
+STR_SUB_ARCTIC_LANDSCAPE :subarktisk landskap
+STR_SUB_TROPICAL_LANDSCAPE :subtropisk landskap
+STR_TOYLAND_LANDSCAPE :lekeland landskap
+
+STR_CHEATS :{WHITE}Juks
+STR_CHEATS_TIP :{BLACK}Avkrysningsbokser indikerer at du har brukt denne juksekoden tidligere.
+STR_CHEATS_WARNING :{BLACK}Advarsel! Vær klar over at du er i ferd med å bedra dine motstandere og at straffen for slike handlinger er evig tid i skjærsilden.
+STR_CHEAT_MONEY :{LTBLUE}Øk pengebeholdningen med {CURRENCY64}
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Spiller som spiller: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Magisk bulldoser (fjern industrier, ufjernbare ting): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Tuneller kan krysse hverandre: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Tillat bygging i pausemodus: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Jetfly vil ikke krasje (hele tiden) på små flyplasser: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Bytt klima: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Bytt dato: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}Tillat endring av produksjonsmengder: {ORANGE}{STRING}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}Har kurs mot {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Har kurs mot {WAYPOINT}, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :Kjør via {WAYPOINT}
+STR_GO_NON_STOP_TO_WAYPOINT :GÃ¥ uten stopp via {WAYPOINT}
+
+STR_WAYPOINTNAME_CITY :{TOWN} kontrollpunkt
+STR_WAYPOINTNAME_CITY_SERIAL :{TOWN} kontrollpunkt nr. {COMMA}
+STR_LANDINFO_WAYPOINT :Kontrollpunkt
+
+STR_WAYPOINT :{WHITE}Kontrollpunkt
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Velg kontrollpunkttype
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}Endre navn på kontrollpunkt...
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Kan ikke endre navnet til kontrollpunktet...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Gjør om jernbane til kontrollpunkt
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Kan ikke bygge kontrollpunkt for tog her...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Kan ikke fjerne kontrollpunktet...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Bygg jernbane ved hjelp av autobanemodusen
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}...det er ingen byer i dette scenarioet
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}Er du sikker på at du vil lage et tilfeldig generert landskap?
+STR_MANY_RANDOM_TOWNS :{BLACK}Mange tilfeldige byer
+STR_RANDOM_TOWNS_TIP :{BLACK}Dekk kartet med tilfeldig plasserte byer
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Mange tilfeldige industrier
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Dekk kartet med tilfeldig plasserte industrier
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Kan ikke generere industrier...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Åpne verktøylinjen for å heve/senke land, plante trær, osv.
+STR_LANDSCAPING_TOOLBAR :{WHITE}Landskaping
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Utjevn land
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Trær av tilfeldig type
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}Plasser trær av tilfeldig type
+
+STR_CANT_BUILD_CANALS :{WHITE}Kan ikke bygge kanaler her...
+STR_BUILD_CANALS_TIP :{BLACK}Bygg kanaler. Trykk CTRL for å plassere sjøområder (kun på havnivå).
+STR_LANDINFO_CANAL :Kanal
+
+STR_CANT_BUILD_LOCKS :{WHITE}Kan ikke bygge sluser her...
+STR_BUILD_LOCKS_TIP :{BLACK}Bygg sluser
+STR_LANDINFO_LOCK :Sluse
+
+STR_BUOY_IS_IN_USE :{WHITE}...bøye er i bruk!
+
+STR_LANDINFO_COORDS :{BLACK}Koordinater: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Kan ikke fjerne del av stasjonen...
+STR_CANT_CONVERT_RAIL :{WHITE}Kan ikke konvertere jernbanetype her...
+STR_CONVERT_RAIL_TIP :{BLACK}Gjør om/oppgrader jernbanetypen
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Dra lokomotivet hit for å selge hele toget.
+
+STR_DRAG_DROP :{BLACK}Dra og slipp
+STR_STATION_DRAG_DROP :{BLACK}Bygg stasjon med dra og slipp
+STR_SELECT_STATION_CLASS_TIP :{BLACK}Velg en stasjonstypen å vise
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Velg stasjonen du vil bygge
+
+STR_FAST_FORWARD :{BLACK}Hurtig tid
+STR_MESSAGE_HISTORY :{WHITE}Tidligere meldinger
+STR_MESSAGE_HISTORY_TIP :{BLACK}En liste over nylige nyhetsmeldinger
+STR_MESSAGES_DISABLE_ALL :{BLACK}Deaktiver alle
+STR_MESSAGES_ENABLE_ALL :{BLACK}Aktiver alle
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Bygg kullgruve
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Plant skog
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Bygg oljeplatform
+STR_CONSTRUCT_FARM_TIP :{BLACK}Finansier gård
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Bygg kobbergruve
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Bygg oljebrønn
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Bygg gullgruve
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Bygg diamantgruve
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Bygg jerngruve
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Finansier fruktplantasje
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Finansier gummiplantasje
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Finansier vannreservoar
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Plant sukkerspinnskog
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}Finansier batterigård
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Bygg colabrønn
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Finasier plastikkfontener
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Bygg boblegenerator
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Finansier karamellbrudd
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Bygg sukkergruve
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Industrier
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA} % transportert)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA} %/{COMMA} % transportert)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}...for nært en annen industri
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Bygg om et lokomotiv til å ta en annen type last
+STR_RAIL_REFIT_VEHICLE :{BLACK}Bygg om lokomotivet
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Velg hvilken last lokomotivet skal ta
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Bygg om lokomotivet til å frakte den valgte varetypen
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Kan ikke bygge om lokomotiv...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Vedlikeholdsintervaller er i prosent: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Endre produksjon
+
+TEMP_AI_IN_PROGRESS :{WHITE}Velkommen til denne nye AI, under konstruksjon. Du kan vente deg problemer. NÃ¥r du finner ett problem, lag ett skjermbilde av det og post det i forumet. Mor deg!
+TEMP_AI_ACTIVATED :{WHITE}Advarsel: denne nye AI er fremdeles alfa! Akkurat nå virker kun lastebiler og busser!
+TEMP_AI_MULTIPLAYER :{WHITE}Advarsel: dette er fortsatt eksperimentelt. Vennligst rapporter problemer til truelight@openttd.org.
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Flerspiller
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Spillernavn:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}Dette er navnet andre spillere vil identifisere deg med
+STR_NETWORK_CONNECTION :{BLACK}Forbindelse:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Velg mellom å spille på internett eller i lokalt nettverk (LAN)
+
+STR_NETWORK_START_SERVER :{BLACK}Start tjener
+STR_NETWORK_START_SERVER_TIP :{BLACK}Start en egen tjener
+
+STR_NETWORK_GAME_NAME :{BLACK}Navn
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Navn på spillet
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Språk, tjenerversjon, etc.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Klikk på et spill på listen for å velge det
+
+STR_NETWORK_FIND_SERVER :{BLACK}Finn server
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Søk på nettverket etter en server
+STR_NETWORK_ADD_SERVER :{BLACK}Legg til tjener
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Legger til en tjener i listen over tjenere som alltid vil bli skjekket for aktive spill.
+STR_NETWORK_ENTER_IP :{BLACK}Skriv inn IP-adressen til serveren
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Klienter
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Klienter på nett / maks. antall klienter{}Firmaer på nett / maks. antall firmaer
+STR_NETWORK_GAME_INFO :{SILVER}SPILLOVERSIKT
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Klienter: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Språk: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Brikkesett: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Kartstørrelse: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}Tjenerversjon: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}Server addresse: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Startet: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Nettverksdato: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Passordbeskyttet!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}TJENEREN ER KOBLET AV
+STR_NETWORK_SERVER_FULL :{SILVER}TJENEREN ER FULL
+STR_NETWORK_VERSION_MISMATCH :{SILVER}DU HAR EN ANNEN VERSJON EN TJENEREN
+
+STR_NETWORK_JOIN_GAME :{BLACK}Bli med på spill
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}Start et nytt flerspillerspill
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Spillnavn:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}Spillnavnet vil bli vist til andre spillere i flerspillermenyen
+STR_NETWORK_SET_PASSWORD :{BLACK}Sett passord
+STR_NETWORK_PASSWORD_TIP :{BLACK}Beskytt ditt spill med et passord hvis du ikke vil at hvem som helst skal bli med på det
+STR_NETWORK_SELECT_MAP :{BLACK}Velg et kart:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}Hvilket kart vil du spille?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}Maksimalt antall tillatte klienter
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Velg maksimalt antall klienter. Alle plassene trenger ikke bli tatt.
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :LAN
+STR_NETWORK_INTERNET :Internett
+STR_NETWORK_LAN_INTERNET :LAN / Internett
+STR_NETWORK_INTERNET_ADVERTISE :Internett (annonser)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 spillere
+STR_NETWORK_1_PLAYERS :1 spiller
+STR_NETWORK_2_PLAYERS :2 spillere
+STR_NETWORK_3_PLAYERS :3 spillere
+STR_NETWORK_4_PLAYERS :4 spillere
+STR_NETWORK_5_PLAYERS :5 spillere
+STR_NETWORK_6_PLAYERS :6 spillere
+STR_NETWORK_7_PLAYERS :7 spillere
+STR_NETWORK_8_PLAYERS :8 spillere
+STR_NETWORK_9_PLAYERS :9 spillere
+STR_NETWORK_10_PLAYERS :10 spillere
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}Maks. antall firmaer:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Begrens tjeneren til et bestemt antall firmaer
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}Maks antall tilskuere
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Begrens tjeneren til et bestemt antall tilskuere
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Språk snakket på tjeneren:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Andre spillere skal kunne vite hvilket språk man snakker på denne tjeneren.
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}Start spill
+STR_NETWORK_START_GAME_TIP :{BLACK}Start et nytt nettverksspill fra en tilfeldig bane, eller scenario
+STR_NETWORK_LOAD_GAME :{BLACK}Last spill
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Fortsette et tidligere lagret flerspillere spill (vær sikker på å koble til som den korrekte spilleren)
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Hva som helst
+STR_NETWORK_LANG_ENGLISH :Engelsk
+STR_NETWORK_LANG_GERMAN :Tysk
+STR_NETWORK_LANG_FRENCH :Fransk
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Flerspillere spill lobby
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Prøver å koble til: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}En liste over firma i spillet. Du kan enten bli med i ett eller starte et nytt.
+STR_NETWORK_NEW_COMPANY :{BLACK}Nytt firma
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Start et nytt firma
+STR_NETWORK_SPECTATE_GAME :{BLACK}Se på spill
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Vær tilskuer til spillet
+STR_NETWORK_JOIN_COMPANY :{BLACK}Bli med i firmaet
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Hjelp å styre dette firmaet
+STR_NETWORK_REFRESH :{BLACK}Oppdater tjener
+STR_NETWORK_REFRESH_TIP :{BLACK}Oppdater tjenerinfo
+
+STR_NETWORK_COMPANY_INFO :{SILVER}FIRMAOVERSIKT
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Firmaname: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}Innviet: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}Firmaverdi: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Balanse nå: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Inntekt i fjor: {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}Nettverksytelse: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}Kjøretøy: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Stasjoner: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Spillere: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}Kobler på...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) Kobler på..
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Autoriserer..
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Venter..
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Laster ned kart..
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Behandler data..
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) Registrerer..
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Henter spilloversikt..
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Henter firmaoversikt..
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} klient{P "" er} foran oss
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} KB lastet ned så langt
+
+STR_NETWORK_DISCONNECT :{BLACK}Koble fra
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Skriv inn hvor mye penger du vil gi
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Tjeneren er beskyttet. Skriv inn passord
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Firmaet er beskyttet. Skriv inn passord
+STR_NETWORK_CLIENT_LIST :{WHITE}Liste over klienter
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE} Ingen nettverksadapter funnet eller kompilert uten ENABLE_NETWORK
+STR_NETWORK_ERR_NOSERVER :{WHITE} Kunne ikke finne noen nettverksspill
+STR_NETWORK_ERR_NOCONNECTION :{WHITE} Tjeneren svarte ikke på forespørselen
+STR_NETWORK_ERR_DESYNC :{WHITE} Nettverksspill synkronisering feilet.
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} Nettverksspill tilkobling mistet
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} Kunne ikke laste server-lagret spill
+STR_NETWORK_ERR_SERVER_START :{WHITE} Klarte ikke å starte tjeneren.
+STR_NETWORK_ERR_CLIENT_START :{WHITE} Klarte ikke å opprette forbindelse.
+STR_NETWORK_ERR_TIMEOUT :{WHITE} Tilkobling nr. {NUM} ble tidsavbrutt.
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE} Det skjedde en protokoll-feil, så forbindelsen er brutt
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE} Klientversjonen er ikke den samme som tjenerversjonen.
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} Feil passord.
+STR_NETWORK_ERR_SERVER_FULL :{WHITE} Tjeneren er full
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} Du er bannlyst fra denne tjeneren
+STR_NETWORK_ERR_KICKED :{WHITE} Du ble sparket ut av tjeneren
+STR_NETWORK_ERR_CHEATER :{WHITE} Juksing er forbudt på denne serveren
+
+STR_NETWORK_ERR_LEFT :har forlatt spillet
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :generell feil
+STR_NETWORK_ERR_CLIENT_DESYNC :synkroniseringsfeil
+STR_NETWORK_ERR_CLIENT_SAVEGAME :klarte ikke å åpne kartet
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :forbindelsen ble brutt
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :protokollfeil
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :ikke autorisert
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :mottok merkelig pakke
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :feil versjon
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :navnet er brukt av noen andre
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :feil passord til spillet
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :feil spiller-id i DoCommand
+STR_NETWORK_ERR_CLIENT_KICKED :sparket ut av tjeneren
+STR_NETWORK_ERR_CLIENT_CHEATER :prøvde å jukse
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :serveren er full
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :har blitt med i spillet
+STR_NETWORK_GIVE_MONEY :gav deg penger ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :Du gav {STRING} noen penger ({CURRENCY})
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Lag] :
+STR_NETWORK_CHAT_COMPANY :[Lag] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Lag] Til {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[Privat] :
+STR_NETWORK_CHAT_CLIENT :[Privat] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[Privat] Til {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[Alle] :
+STR_NETWORK_CHAT_ALL :[Alle] {STRING}: {GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :har skiftet navn til
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE} Tjeneren avsluttet spillet
+STR_NETWORK_SERVER_REBOOT :{WHITE} Tjeneren starter på nytt...{}Vennligst vent
+
+STR_NETWORK_SERVER :Server
+STR_NETWORK_CLIENT :Klient
+STR_NETWORK_SPECTATORS :Tilskuere
+
+STR_NETWORK_CLIENTLIST_NONE :(ingen)
+STR_NETWORK_CLIENTLIST_KICK :Kast ut
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Gi penger
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Snakk til alle
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Snakk til firma
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Privat beskjed
+
+
+STR_NETWORK_SEND :{BLACK}Send
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}X-størrelse på kart: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Y-størrelse på kart: {ORANGE}{STRING}
+
+
+##### PNG-MAP-Loader
+
+STR_PNGMAP_ERROR :{WHITE}Kan ikke laste landskapet fra PNG...
+STR_PNGMAP_ERR_FILE_NOT_FOUND :{WHITE}...fant ingen fil.
+STR_PNGMAP_ERR_IMAGE_TYPE :{WHITE}...kunne ikke konvertere bildetypen. Et 8- eller 24-bits bilde trengs.
+STR_PNGMAP_ERR_MISC :{WHITE}...noe gikk akkurat galt. Beklager. (Sannsynligvis en ødelagt fil.)
+
+STR_BMPMAP_ERROR :{WHITE}Kan ikke laste landskap fra BMP...
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}...kan ikke konvertere bildetype.
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Kostnad: {CURRENCY}
+STR_0801_COST :{RED}Kostnad: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Inntekt: {CURRENCY}
+STR_0803_INCOME :{GREEN}Inntekt: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Overføring: {CURRENCY}
+STR_FEEDER :{YELLOW}Overføring: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Anslått kostand: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Anslått inntekt: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Kan ikke heve land her...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Kan ikke senke land her...
+STR_080A_ROCKS :Steiner
+STR_080B_ROUGH_LAND :Ulendt terreng
+STR_080C_BARE_LAND :Bart land
+STR_080D_GRASS :Gress
+STR_080E_FIELDS :Jorder
+STR_080F_SNOW_COVERED_LAND :Snødekket land
+STR_0810_DESERT :Ørken
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Landet heller i feil retning
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Umulig kombinasjon av spor
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}Utgraving vil skade tunnel
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Allerede på havnivå
+STR_1004_TOO_HIGH :{WHITE}For høyt
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Upassende jernbanespor
+STR_1007_ALREADY_BUILT :{WHITE}...allerede bygget
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Må fjerne jernbanespor først
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Bygg jernbane
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Elektrisk jernbane-konstruksjon
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Bygg Monorail
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}Bygg MagLev
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Velg jernbanebrotype
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Kan ikke bygge togstall her...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Kan ikke bygge jernbanestasjon her
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Kan ikke bygge signallykter her...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Kan ikke bygge jernbanespor her...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Kan ikke fjerne jernbanespor herfra...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Kan ikke fjerne signallykter herfra...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Togstallens retning
+STR_1015_RAILROAD_CONSTRUCTION :Bygg jernbane
+STR_TOOLB_ELRAIL_CONSTRUCTION :Elektrisk jernbane-konstruksjon
+STR_1016_MONORAIL_CONSTRUCTION :Bygg monorail
+STR_1017_MAGLEV_CONSTRUCTION :Bygg maglev
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Bygg jernbanespor
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Bygg togstall (trengs for bygging og vedlikehold av tog)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Bygg jernbanestasjon
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Bygg signallykter
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Bygg jernbanebro
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Bygg jernbanetunnel
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Velg mellom bygging/fjerning for jernbanespor og signallykter
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Brovalg - trykk på broen du vil ha for å bygge den.
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Velg togstallens retning
+STR_1021_RAILROAD_TRACK :Jernbanespor
+STR_1023_RAILROAD_TRAIN_DEPOT :Togstall
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...felt eies av et annet firma
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :Jernbanespor med normale signaler
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :Jernbanespor med for-signaler
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :Jernbanespor med forlat-signaler
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :Jernbanespor med kombinerte signaler
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Må fjerne vei først
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Veiarbeid i gang
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Bygg vei
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Velg brotype
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Kan ikke bygge vei her
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Kan ikke fjerne vei herfra...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Retning for garasje
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Kan ikke bygge garasje her...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Kan ikke bygge busstatsjon...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Kan ikke bygge lasteterminal...
+STR_180A_ROAD_CONSTRUCTION :Bygg vei
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Bygg vei
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Bygg garasje (trengs for bygging og vedlikehold av kjøretøy)
+STR_180D_BUILD_BUS_STATION :{BLACK}Bygg bussstasjon
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Bygg lasteterminal
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Bygg bro
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Bygg tunnel
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Velg mellom bygging/fjerning for veibygging
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Velg garasjens retning
+STR_1814_ROAD :Vei
+STR_1815_ROAD_WITH_STREETLIGHTS :Vei med gatelykter
+STR_1816_TREE_LINED_ROAD :Aveny
+STR_1817_ROAD_VEHICLE_DEPOT :Garasje
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :Jernbaneovergang
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Byer
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Bygningen må rives først
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}Innbyggertall: {ORANGE}{COMMA}{BLACK} Antall hus: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Bytt navn
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Kan ikke bytte navn på byen...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN}s bystyre nekter deg å gjøre dette.
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Bynavn - trykk på by navnet for å se på byen
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Sentrer bildet rundt byen
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Bytt navn på byen
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passasjerer forrige måned: {ORANGE}{COMMA}{BLACK} maks: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Post forrige måned: {ORANGE}{COMMA}{BLACK} maks: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Høyhus
+STR_2010_OFFICE_BLOCK :Kontorblokk
+STR_2011_SMALL_BLOCK_OF_FLATS :Leilighetsblokk
+STR_2012_CHURCH :Kirke
+STR_2013_LARGE_OFFICE_BLOCK :Stor kontorblokk
+STR_2014_TOWN_HOUSES :Byhus
+STR_2015_HOTEL :Hotell
+STR_2016_STATUE :Statue
+STR_2017_FOUNTAIN :Fontene
+STR_2018_PARK :Park
+STR_2019_OFFICE_BLOCK :Kontorblokk
+STR_201A_SHOPS_AND_OFFICES :Butikker og kontorer
+STR_201B_MODERN_OFFICE_BUILDING :Moderne kontorblokk
+STR_201C_WAREHOUSE :Varehus
+STR_201D_OFFICE_BLOCK :Kontorblokk
+STR_201E_STADIUM :Stadion
+STR_201F_OLD_HOUSES :Gamle hus
+STR_2020_LOCAL_AUTHORITY :{BLACK}Bystyre
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Vis informasjon om bystyret
+STR_2022_LOCAL_AUTHORITY :{WHITE}{TOWN}s bystyre
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Vurdering av transportfirma:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Subsidier
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Tilbudte subsidier:
+STR_2027_FROM_TO :{ORANGE}{STRING} fra {STRING} til {STRING}
+STR_2028_BY :{YELLOW} (innen {DATE_SHORT})
+STR_202A_NONE :{ORANGE}Ingen
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Tjenester som allerede er subsidiert:
+STR_202C_FROM_TO :{ORANGE}{STRING} fra {STATION} til {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, inntil {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}Tilbud om subsidie har gått ut:{}{}{STRING} fra {STRING} til {STRING} vil ikke lenger være subsidiert.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Subsidie trukket tilbake:{}{}Transport av {STRING} fra {STATION} til {STATION} er ikke lenger subsidiert.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Subsidie-tilbud:{}{}Første transport av {STRING} fra {STRING} til {STRING} vil være subsidiert i et år av bystyret!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subsidie gitt til {COMPANY}!{}{}Transport av {STRING} fra {STATION} til {STATION} vil gi 50% mer inntekt i løpet av ett år!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subsidie gitt til {COMPANY}!{}{}Transport av {STRING} fra {STATION} til {STATION} vil gi dobbelt så mye inntekt i løpet av et år!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subsidie gitt til {COMPANY}!{}{}Transport av {STRING} fra {STATION} til {STATION} vil gi tippelt så mye inntekt i løpet av et år!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subsidie gitt til {COMPANY}!{}{}Transport av {STRING} fra {STATION} til {STATION} vil gi fire ganger så mye inntekt i løpet av et år!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN}s bystyre tillater ikke flere flyplasser i denne byen
+STR_2036_COTTAGES :Hytter
+STR_2037_HOUSES :Hus
+STR_2038_FLATS :Leiligheter
+STR_2039_TALL_OFFICE_BLOCK :Høy kontroblokk
+STR_203A_SHOPS_AND_OFFICES :Butikker og kontorer
+STR_203B_SHOPS_AND_OFFICES :Butikker og kontorer
+STR_203C_THEATER :Teater
+STR_203D_STADIUM :Stadion
+STR_203E_OFFICES :Kontorer
+STR_203F_HOUSES :Hus
+STR_2040_CINEMA :Kino
+STR_2041_SHOPPING_MALL :Kjøpesenter
+STR_2042_DO_IT :{BLACK}Gjør det
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}Liste over ting som kan gjøres for/i byen - trykk på valg for mer informasjon
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Utfør den gjeldene handlingen valgt i listen over.
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Handlinger tilgjengelig:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Liten reklamekampanje
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Middels stor reklamekampanje
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Stor reklamekampanje
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Finansier lokal ombygging av veinettet
+STR_204A_BUILD_STATUE_OF_COMPANY :Bygg statue av firmaets grunnlegger
+STR_204B_FUND_NEW_BUILDINGS :Finansier nye bygninger
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Kjøp eksklusive transportrettigheter
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Bestikk bystyret
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Start en liten lokal reklamekampanje for å tiltrekke deg flere passasjerer og mer varer til dine transporttjenester.{} Koster: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Start en middels stor lokal reklamekampanje for å tiltrekke deg flere passasjerer og mer varer til dine transporttjenester.{} Koster: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Start en stor lokal reklamekampanje for å tiltrekke deg flere passasjerer og mer varer til dine transporttjenester.{} Koster: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} Finansier ombygging av det lokale veinettet. Fører til veiproblemer i seks måneder.{} Koster: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Bygg en statue for å ære firmaet.{} Cost: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Finasier byggingen av nye forretningsbygninger i byen .{} Koster: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Kjøp ett års ekslusive transportrettigheter i byen. Bystyret vil kun tillate passasjerer og varer å bruke dine transporttjenester.{} Koster: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Bestikk bystyret til å forbedre vurderingen av firmaet, men du riskerer å bli bøtlagt hvis du blir oppdaget.{} Koster: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}Traffkkaos i {TOWN}!{}{}Ombygging av veien, finasiert av {COMPANY}, fører med seg seks måneders veiproblemer.
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (under bygging)
+STR_2059_IGLOO :Iglo
+STR_205A_TEPEES :Indianertelt
+STR_205B_TEAPOT_HOUSE :Tekjelehus
+STR_205C_PIGGY_BANK :Sparebøsse
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN} {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Landskapsverktøy
+STR_2800_PLANT_TREES :Plant trær
+STR_2801_PLACE_SIGN :Plasser skilt
+STR_2802_TREES :{WHITE}Trær
+STR_2803_TREE_ALREADY_HERE :{WHITE}...det er allerede et tre her
+STR_2804_SITE_UNSUITABLE :{WHITE}...upassende område
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Kan ikke plante trær her...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...for mange skilt
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Kan ikke plassere skilt her...
+STR_280A_SIGN :Skilt
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Endre teksten på skiltet
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Kan ikke endre teksten på skiltet...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Velg typen tre som skal plantes
+STR_280E_TREES :Trær
+STR_280F_RAINFOREST :Regnskog
+STR_2810_CACTUS_PLANTS :Kaktusplanter
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Velg jernbanestasjontype
+STR_3001_AIRPORT_SELECTION :{WHITE}Velg flyplasstype
+STR_3002_ORIENTATION :{BLACK}Retning
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Antall spor
+STR_3004_PLATFORM_LENGTH :{BLACK}Platformlengde
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}For nær en annen jernbanestasjon
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Grenser til mer enn én eksiterende stasjon/lasteterminal
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}For mange stasjoner/lasteterminaler i byen
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}For mange stasjoner/lasteterminaler
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}For mange bussholdeplasser
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}For mange lasteterminaler
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}For nær en annen jernbanestasjon/lasteterminal
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Må rive eksiterende jernbanestasjon først
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}For nær en annen flyplass
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Må rive eksisterende flyplass først
+
+STR_3030_RENAME_STATION_LOADING :Endre navnet til stasjon/lasteterminal
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Kan ikke endre navnet til stasjonen...
+STR_3032_RATINGS :{BLACK}Vurderinger
+STR_3033_ACCEPTS :{BLACK}Aksepterer
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}Lokal vurdering av transporttjenester:
+
+############ range for rating starts
+STR_3035_APPALLING :Forferdelig
+STR_3036_VERY_POOR :Veldig dårlig
+STR_3037_POOR :DÃ¥rlig
+STR_3038_MEDIOCRE :Middels
+STR_3039_GOOD :God
+STR_303A_VERY_GOOD :Veldig god
+STR_303B_EXCELLENT :Utmerket
+STR_303C_OUTSTANDING :Fremragende
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} godtar ikke lenger {STRING}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} godtar ikke lenger {STRING} eller {STRING}
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} godtar nå {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} godtar nå {STRING} og {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Retning på bussterminal
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Retning på lasteterminal
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Må rive bussterminal først
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Må rive lasteterminal først
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Stasjoner
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Ingen -
+STR_304B_SITE_UNSUITABLE :{WHITE}...upassende område
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}For nærme enn annen havn
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Må rive havn først
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Velg jernbanestasjonens retning
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Velg antall spor stasjonen skal ha
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Velg hvor lang stasjonen skal være
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Velg retning på bussterminal
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Velg retning på lasteterminal
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Sentrer bildet på stasjonen
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Vis stasjonsvurdering
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Endre navnet til stasjonen
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Vis liste over godtatte varer
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Stasjonsnavn - Trykk på navnet for å sentrere bildet på stasjonen
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Velg størrelse/type flyplass
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :Jernbanestasjon
+STR_305F_AIRCRAFT_HANGAR :Hangar
+STR_3060_AIRPORT :Flyplass
+STR_3061_TRUCK_LOADING_AREA :Lasteterminal
+STR_3062_BUS_STATION :Bussterminal
+STR_3063_SHIP_DOCK :Havn
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Vis dekningsområdet til den foreslåtte plasseringen
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Ikke vis dekningsområdet til den foreslåtte plasseringen
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Dekningsområde
+STR_3068_DOCK :{WHITE}Havn
+STR_3069_BUOY :Bøye
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...bøyen er i veien
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...stasjonen er spredd for mye
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...ikke-ensartede stasjoner deaktivert
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Hold nede CTRL for å velge mer en en ting
+
+STR_UNDEFINED :(udefinert streng)
+STR_STAT_CLASS_DFLT :Standard stasjon
+STR_STAT_CLASS_WAYP :Lokalstasjoner
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Skipdepotets retning
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...må bygges i sjøen
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Kan ikke bygge skipsdepot her...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Velg skipsdepotets retning
+STR_3804_WATER :Vann
+STR_3805_COAST_OR_RIVERBANK :Kyst eller elvebredd
+STR_3806_SHIP_DEPOT :Skipsdepot
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...Kan ikke bygge på vann
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Lagre spill
+STR_4001_LOAD_GAME :{WHITE}Last inn spill
+STR_4002_SAVE :{BLACK}Lagre
+STR_4003_DELETE :{BLACK}Slett
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} megabyte ledig
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Kan ikke lese fra disk
+STR_4007_GAME_SAVE_FAILED :{WHITE}Lagring av spillet mislyktes
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Kan ikke slette fil
+STR_4009_GAME_LOAD_FAILED :{WHITE}Feil ved fremhenting av spill
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}Liste over disker, mapper og lagrede spill
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Gjeldende navn for valgt lagret spill
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Slett valgte lagring
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Lagre gjeldende spill ved å bruke navnet som er valgt
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Velg ny spilltype
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Velg scenario (grønn), forhåndsatte spill (blått), eller nytt tilfeldig spill
+STR_4010_GENERATE_RANDOM_NEW_GAME :Lag et tilfeldig spill
+STR_4011_LOAD_HEIGHTMAP :{WHITE}Last høydekart
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} er i veien
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :Kullgruve
+STR_4803_POWER_STATION :Kraftstasjon
+STR_4804_SAWMILL :Sagbruk
+STR_4805_FOREST :Skog
+STR_4806_OIL_REFINERY :Oljeraffineri
+STR_4807_OIL_RIG :Oljeplatform
+STR_4808_FACTORY :Fabrikk
+STR_4809_PRINTING_WORKS :Trykkeri
+STR_480A_STEEL_MILL :Smelteverk
+STR_480B_FARM :GÃ¥rd
+STR_480C_COPPER_ORE_MINE :Kobbergruve
+STR_480D_OIL_WELLS :Oljebrønn
+STR_480E_BANK :Bank
+STR_480F_FOOD_PROCESSING_PLANT :Matforedlingsfabrikk
+STR_4810_PAPER_MILL :Papirfabrikk
+STR_4811_GOLD_MINE :Gullgruve
+STR_4812_BANK :Bank
+STR_4813_DIAMOND_MINE :Diamantgruve
+STR_4814_IRON_ORE_MINE :Jerngruve
+STR_4815_FRUIT_PLANTATION :Fruktplantasje
+STR_4816_RUBBER_PLANTATION :Gummiplantasje
+STR_4817_WATER_SUPPLY :Vannreservoar
+STR_4818_WATER_TOWER :Vanntårn
+STR_4819_FACTORY :Fabrikk
+STR_481A_FARM :GÃ¥rd
+STR_481B_LUMBER_MILL :Sagbruk
+STR_481C_COTTON_CANDY_FOREST :Sukkerspinnskog
+STR_481D_CANDY_FACTORY :Søtsakfabrikk
+STR_481E_BATTERY_FARM :Batterigård
+STR_481F_COLA_WELLS :Colabrønner
+STR_4820_TOY_SHOP :Leketøysbutikk
+STR_4821_TOY_FACTORY :Leketøysfabrikk
+STR_4822_PLASTIC_FOUNTAINS :Plastfontener
+STR_4823_FIZZY_DRINK_FACTORY :Mineralvannfabrikk
+STR_4824_BUBBLE_GENERATOR :Boblegenerator
+STR_4825_TOFFEE_QUARRY :Karamellbrudd
+STR_4826_SUGAR_MINE :Sukkergruve
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Trenger: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Trenger: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Trenger: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Produksjon forrige måned:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA} % transportert)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Sentrer bildet på industriområdet
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Ny {STRING} under bygging i nærheten av {TOWN}!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Ny {STRING} plantes i nærheten av {TOWN}!
+STR_482F_COST :{BLACK}Koster: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Kan ikke bygge denne typen industri her...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...skog kan bare plantes over snøgrensen
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} offentliggjør umiddelbar nedleggelse!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}Leveringsproblemer forårsaker {INDUSTRY} til å offentliggjøre umiddelbar nedleggelse!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}Mangel på trær i nærheten får {INDUSTRY} til å offentliggjøre umiddelbar nedleggelse!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} øker produksjonen!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}Ny kullåre funnet i {INDUSTRY}!{}En dobling i produksjonen er ventet!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}Nye oljereserver funnet i {INDUSTRY}!{}En dobling i produksjonen er ventet!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}Forbedring i gårdbruksmetoder på {INDUSTRY} er forventet å doble produksjonen!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}{INDUSTRY} sin produksjon har sunket med 50 %
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}Insektinvasjon på {INDUSTRY}!{}Produksjonen synker med 50 %
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...kan kun plasseres i nærheten av kartkanten
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}Produksjonen av {STRING} ved {INDUSTRY} øker med {COMMA} %!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}Produksjonen av {STRING} ved {INDUSTRY} synker med {COMMA} %!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Tog i tunnelen
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Kjøretøy i tunnelen
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Annen tunnel i veien
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Kan ikke grave ut land til den andre tunnelutgangen
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Må rive tunnel først
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Må rive bro først
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Kan ikke starte og slutte på samme felt
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Flatt land eller vann trengs under broen
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}Start og slutt må være på linje
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Feltet er upassende for tunnelinngang
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Hengebro, stål
+STR_500F_GIRDER_STEEL :Bjelker, stål
+STR_5010_CANTILEVER_STEEL :Frittbærende, stål
+STR_5011_SUSPENSION_CONCRETE :Hengebro, betong
+STR_5012_WOODEN :Tre
+STR_5013_CONCRETE :Betong
+STR_5014_TUBULAR_STEEL :Rørformet, stål
+STR_BRIDGE_TUBULAR_SILICON :Rørformet, silikon
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Kan ikke bygge bro her...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Kan ikke bygge tunnel her...
+STR_5017_RAILROAD_TUNNEL :Jernbanetunnel
+STR_5018_ROAD_TUNNEL :Veitunnel
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Hengebro av stål (jernbane)
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Bjelkebro av stål (jernbane)
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Frittbærende bro av stål (jernbane)
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Hengebro av armert betong (jernbane)
+STR_501F_WOODEN_RAIL_BRIDGE :Trebro (jernbane)
+STR_5020_CONCRETE_RAIL_BRIDGE :Betongbro (jernbane)
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Hengebro av stål (vei)
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Bjelkebro av stål (vei)
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Frittbærende bro av stål (vei)
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Hengebro av armert betong (vei)
+STR_5025_WOODEN_ROAD_BRIDGE :Trebro (vei)
+STR_5026_CONCRETE_ROAD_BRIDGE :Betongbro (vei)
+STR_5027_TUBULAR_RAIL_BRIDGE :Rørformet bro (jernbane)
+STR_5028_TUBULAR_ROAD_BRIDGE :Rørformet bro (vei)
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Objekt er i veien
+STR_5801_TRANSMITTER :Radiosender
+STR_5802_LIGHTHOUSE :Fyrtårn
+STR_5803_COMPANY_HEADQUARTERS :Hovedkontor til firma
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...hovedkontor til firma er i veien
+STR_5805_COMPANY_OWNED_LAND :Feltet eies av et firma
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Kan ikke kjøpe dette feltet...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...du eier det allerede!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Uten navn
+STR_SV_TRAIN_NAME :Tog {COMMA}
+STR_SV_ROADVEH_NAME :Kjøretøy {COMMA}
+STR_SV_SHIP_NAME :Skip {COMMA}
+STR_SV_AIRCRAFT_NAME :Fly {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :{STRING} nord
+STR_SV_STNAME_SOUTH :{STRING} sør
+STR_SV_STNAME_EAST :{STRING} øst
+STR_SV_STNAME_WEST :{STRING} vest
+STR_SV_STNAME_CENTRAL :{STRING} sentrum
+STR_SV_STNAME_TRANSFER :{STRING}ruta
+STR_SV_STNAME_HALT :{STRING} holdeplass
+STR_SV_STNAME_VALLEY :{STRING}dalen
+STR_SV_STNAME_HEIGHTS :{STRING}toppen
+STR_SV_STNAME_WOODS :{STRING} skogholt
+STR_SV_STNAME_LAKESIDE :{STRING}sjøen
+STR_SV_STNAME_EXCHANGE :{STRING}krysset
+STR_SV_STNAME_AIRPORT :{STRING} flyplass
+STR_SV_STNAME_OILFIELD :{STRING} oljefelt
+STR_SV_STNAME_MINES :{STRING} gruvestasjon
+STR_SV_STNAME_DOCKS :{STRING} havn
+STR_SV_STNAME_BUOY_1 :{STRING} bøye 1
+STR_SV_STNAME_BUOY_2 :{STRING} bøye 2
+STR_SV_STNAME_BUOY_3 :{STRING} bøye 3
+STR_SV_STNAME_BUOY_4 :{STRING} bøye 4
+STR_SV_STNAME_BUOY_5 :{STRING} bøye 5
+STR_SV_STNAME_BUOY_6 :{STRING} bøye 6
+STR_SV_STNAME_BUOY_7 :{STRING} bøye 7
+STR_SV_STNAME_BUOY_8 :{STRING} bøye 8
+STR_SV_STNAME_BUOY_9 :{STRING} bøye 9
+STR_SV_STNAME_ANNEXE :{STRING} anneks
+STR_SV_STNAME_SIDINGS :{STRING}veien
+STR_SV_STNAME_BRANCH :{STRING} gren
+STR_SV_STNAME_UPPER :Øvre {STRING}
+STR_SV_STNAME_LOWER :Nedre {STRING}
+STR_SV_STNAME_HELIPORT :{STRING} helikopterstasjon
+STR_SV_STNAME_FOREST :{STRING}skogen
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Vanskelighetsgrad
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Lagre
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Lett
+STR_6802_MEDIUM :{BLACK}Middels
+STR_6803_HARD :{BLACK}Vanskelig
+STR_6804_CUSTOM :{BLACK}Egendefinert
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maks. antall konkurrenter: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Konkurrentenes starttidspunkt: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}Antall byer: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}Antall industrier: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Maksimalt startlån: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Startrente: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Driftskostnader for kjøretøy: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Konstruksjonshastighet hos konkurrenter: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Konkurrentenes intelligens: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Kjøretøyhavarier: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Subisidiemultiplikator: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Konstruksjonskosnader: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Terrengtype: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Mengde sjø/innsjøer: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Økonomi: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Togreversering: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Katastrofer: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Bystyrets holdning mot ombygging av felt: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :Ingen
+STR_6816_LOW :Lite
+STR_6817_NORMAL :Normal
+STR_6818_HIGH :Høyt
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Veldig sent
+STR_681C_SLOW :Sent
+STR_681D_MEDIUM :Middels
+STR_681E_FAST :Rask
+STR_681F_VERY_FAST :Veldig rask
+STR_VERY_LOW :Veldig lavt
+STR_6820_LOW :Lavt
+STR_6821_MEDIUM :Middels
+STR_6822_HIGH :Høyt
+STR_6823_NONE :Ingen
+STR_6824_REDUCED :Redusert
+STR_6825_NORMAL :Normalt
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Veldig flatt
+STR_682B_FLAT :Flatt
+STR_682C_HILLY :Ã…slendt
+STR_682D_MOUNTAINOUS :Berglendt
+STR_682E_STEADY :Stødig
+STR_682F_FLUCTUATING :Flytende
+STR_6830_IMMEDIATE :Øyeblikkelig
+STR_6831_3_MONTHS_AFTER_PLAYER :3 måneder etter spiller
+STR_6832_6_MONTHS_AFTER_PLAYER :6 måneder etter spiller
+STR_6833_9_MONTHS_AFTER_PLAYER :9 måneder etter spiller
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :Ved linjeslutt og på stasjoner
+STR_6835_AT_END_OF_LINE_ONLY :Bare ved linjeslutt
+STR_6836_OFF :Av
+STR_6837_ON :PÃ¥
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Vis rekorder
+STR_6839_PERMISSIVE :Tillatende
+STR_683A_TOLERANT :Tolerant
+STR_683B_HOSTILE :Fientlig
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Spiller {COMMA})
+STR_7004_NEW_FACE :{BLACK}Nytt ansikt
+STR_7005_COLOR_SCHEME :{BLACK}Firmafarge
+STR_7006_COLOR_SCHEME :{GOLD}Firmafarge:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Ny firmafarge
+STR_7008_COMPANY_NAME :{BLACK}Firmanavn
+STR_7009_PRESIDENT_NAME :{BLACK}Sjefens navn
+STR_700A_COMPANY_NAME :Firmanavn
+STR_700B_PRESIDENT_S_NAME :Sjefens navn
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Kan ikke endre firmanavn...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Kan ikke bytte navn på sjefen...
+STR_700E_FINANCES :{WHITE}{COMPANY}s regnskap{BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Kostnader/inntekter
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Konstruksjon
+STR_7012_NEW_VEHICLES :{GOLD}Nye kjøretøy
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Driftkostnader på tog
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Driftkostnader på kjøretøy
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Driftkostnader på fly
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Driftkostnader på skip
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Vedlikehold av eiendom
+STR_7018_TRAIN_INCOME :{GOLD}Inntekter fra tog
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Inntekter fra kjøretøy
+STR_701A_AIRCRAFT_INCOME :{GOLD}Inntekter fra fly
+STR_701B_SHIP_INCOME :{GOLD}Inntekter fra skip
+STR_701C_LOAN_INTEREST :{GOLD}Renter
+STR_701D_OTHER :{GOLD}Annet
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Totalt:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Inntektsgraf
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Overskuddsgraf
+STR_7026_BANK_BALANCE :{WHITE}Saldo
+STR_7027_LOAN :{WHITE}LÃ¥n
+STR_MAX_LOAN :{WHITE}Maks lån: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}LÃ¥ne mer ({SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY})
+STR_702A_REPAY :{BLACK}Betale tilbake ({SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY})
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...maksimalt lån er {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Kan ikke låne mer penger...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...lånet er allerede betalt tilbake
+STR_702E_REQUIRED :{WHITE}...du trenger {CURRENCY}
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Kan ikke betale tilbake lån...
+STR_INSUFFICIENT_FUNDS :{WHITE}Kan ikke gi vekk penger som er lånt fra banken...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Velg nytt utsende på sjefen
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Endre firmafarge
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Endre navnet til sjefen
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Endre firmanavnet
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Trykk på fargen du har valgt
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Øk størrelsen på lånet
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Betal tilbake en del av lånet
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(Sjef)
+STR_7038_INAUGURATED :{GOLD}Grunnlagt: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Kjøretøy:
+STR_TRAINS :{WHITE}{COMMA} tog
+STR_ROAD_VEHICLES :{WHITE}{COMMA} kjøretøy
+STR_AIRCRAFT :{WHITE}{COMMA} fly
+STR_SHIPS :{WHITE}{COMMA} skip
+STR_7042_NONE :{WHITE}Ingen
+STR_7043_FACE_SELECTION :{WHITE}Velg utseende
+STR_7044_MALE :{BLACK}Mann
+STR_7045_FEMALE :{BLACK}Kvinne
+STR_7046_NEW_FACE :{BLACK}Nytt ansikt
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Avbryt utseendevalg
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Godta nytt utseende
+STR_7049_SELECT_MALE_FACES :{BLACK}Velg mannsansikt
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Velg kvinneansikt
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Lag et tilfeldig ansikt
+STR_704C_KEY :{BLACK}Nøkkel
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Vis oversikt over grafvalg
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Vis oversikt over firmagrafvalg
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Trykk her for å vise/skjule et firma
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Antall varer levert
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Prestasjonsvudering av firma (maks poeng=1000)
+STR_7052_COMPANY_VALUES :{WHITE}Firmaverdi
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Firmarangering
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}Transportfirma har problemer!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} vil bli solgt eller nedlagt, hvis ikke firmaets økonomi tar seg opp!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(Sjef)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Transportfirma fusjonerer!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} har blitt solgt til {COMPANY} for {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Vi ser etter et firma som er villig til å overta oss.{}{}Vil du kjøpe {COMPANY} for {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Konkurs!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} har blitt stengt av kreditorer og alt av verdi har blitt solgt!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}Nytt transportfirma startet!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} starter bygging i nærheten av {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Kan ikke kjøpe firma...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Betalingstakst for varer
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Dager i transport
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Betaling for levering av ti enheter (eller 10,000 liter) over en distanse på 20 ruter
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Skru av/på graf for en bestemt varetype
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Ingeniør
+STR_7067_TRAFFIC_MANAGER :Trafikkleder
+STR_7068_TRANSPORT_COORDINATOR :Transportkoordinator
+STR_7069_ROUTE_SUPERVISOR :Oppsynsmann
+STR_706A_DIRECTOR :Direktør
+STR_706B_CHIEF_EXECUTIVE :Sjefsleder
+STR_706C_CHAIRMAN :Formann
+STR_706D_PRESIDENT :President
+STR_706E_TYCOON :Finansfyrste
+STR_706F_BUILD_HQ :{BLACK}Bygg hovedkontor
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Bygg firmaets hovedkontor/se firmaets hovedkontor
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Gjenoppbygg spelskapets hovedkvarter en annen plass for 1 % av selskapsverdien
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Kan ikke bygge hovedkontor...
+STR_7072_VIEW_HQ :{BLACK}Se hovedkontor
+STR_RELOCATE_HQ :{BLACK}Omplasser hovedkvarter
+STR_COMPANY_PASSWORD :{BLACK}Passord
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Passordbeskytt ditt firma for å forhindre uautoriserte brukere fra å bli med. Bruk '*' for å tømme passord.
+STR_SET_COMPANY_PASSWORD :Velg firmapassord
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}Verdenskrise!{}{}Økonomer frykter det verste. Nedgangstider i møte.
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Verdenskrise over!{}{}Opptur i markedet gir industrien selvsikkerheten tilbake.
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Bytte mellom stor/liten vindustørrelse
+STR_7076_COMPANY_VALUE :{GOLD}Firmaverdi: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Kjøp 25 % av aksjene i firmaet
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Selg 25 % av aksjene du eier
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Kjøp 25 % av aksjene i firmaet
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Selg 25% av aksjene du eier
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Kan ikke kjøpe 25 % av aksjene...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}Kan ikke selge 25 % av aksjene...
+STR_707D_OWNED_BY :{WHITE}({COMMA} % eies av {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA} % eies av {COMPANY}{} {COMMA} % eies av {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} har blitt kjøpt opp av {COMPANY}!
+STR_7080_PROTECTED :{WHITE}Dette selskapet selger ikke aksjer enda...
+
+STR_LIVERY_DEFAULT :Standardovertakelse
+STR_LIVERY_STEAM :Damplokomotiv
+STR_LIVERY_DIESEL :Dieselmotor
+STR_LIVERY_ELECTRIC :Elektrisk motor
+STR_LIVERY_MONORAIL :Monorailmotor
+STR_LIVERY_MAGLEV :Maglevmotor
+STR_LIVERY_DMU :DMU
+STR_LIVERY_EMU :EMU
+STR_LIVERY_PASSENGER_WAGON_STEAM :Passasjervogn (damp)
+STR_LIVERY_PASSENGER_WAGON_DIESEL :Passasjervogn (diesel)
+STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Passasjervogn (elektrisk)
+STR_LIVERY_FREIGHT_WAGON :Fraktvogn
+STR_LIVERY_BUS :Buss
+STR_LIVERY_TRUCK :Lastebil
+STR_LIVERY_PASSENGER_SHIP :Passasjerferje
+STR_LIVERY_FREIGHT_SHIP :Fraktskip
+STR_LIVERY_HELICOPTER :Helikopter
+STR_LIVERY_SMALL_PLANE :Lite fly
+STR_LIVERY_LARGE_PLANE :Stort fly
+
+STR_LIVERY_GENERAL_TIP :{BLACK}Vis generelle fargetemaer
+STR_LIVERY_TRAIN_TIP :{BLACK}Vis togfargetemaer
+STR_LIVERY_ROADVEH_TIP :{BLACK}Vis bilfargetemaer
+STR_LIVERY_SHIP_TIP :{BLACK}Vis skipsfargetemaer
+STR_LIVERY_AIRCRAFT_TIP :{BLACK}Vis flyfarger
+STR_LIVERY_PRIMARY_TIP :{BLACK}Velg en primærfarge for valgte tema
+STR_LIVERY_SECONDARY_TIP :{BLACK}Velg sekundærfarge for valgte tema
+STR_LIVERY_PANEL_TIP :{BLACK}Velg et fargetema å endre, eller flere fargetemaer med CTRL-klikk. Klikk på boksen for å vise bruken av fargetemaene
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (damp)
+STR_8001_MJS_250_DIESEL :MJS 250 (diesel)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut Diesel
+STR_8006_POWERNAUT_DIESEL :Powernaut Diesel
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (damp)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (damp)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (damp)
+STR_800A_SH_8P_STEAM :SH '8P' (damp)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (diesel)
+STR_800C_DASH_DIESEL :'Dash' (diesel)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (diesel)
+STR_800E_UU_37_DIESEL :UU '37' (diesel)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (diesel)
+STR_8010_CS_4000_DIESEL :CS 4000 (diesel)
+STR_8011_CS_2400_DIESEL :CS 2400 (diesel)
+STR_8012_CENTENNIAL_DIESEL :Centennial (diesel)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (diesel)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (diesel)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (diesel)
+STR_8016_SH_125_DIESEL :SH '125' (diesel)
+STR_8017_SH_30_ELECTRIC :SH '30' (elektrisk)
+STR_8018_SH_40_ELECTRIC :SH '40' (elektrisk)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (elektrisk)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (elektrisk)
+STR_801B_PASSENGER_CAR :Passasjervogn
+STR_801C_MAIL_VAN :Postvogn
+STR_801D_COAL_CAR :Kullvogn
+STR_801E_OIL_TANKER :Oljetankvogn
+STR_801F_LIVESTOCK_VAN :Buskapvogn
+STR_8020_GOODS_VAN :Godsvogn
+STR_8021_GRAIN_HOPPER :Kornvogn
+STR_8022_WOOD_TRUCK :Tømmervogn
+STR_8023_IRON_ORE_HOPPER :Jernmalmvogn
+STR_8024_STEEL_TRUCK :Stålvogn
+STR_8025_ARMORED_VAN :Armert vogn
+STR_8026_FOOD_VAN :Matvogn
+STR_8027_PAPER_TRUCK :Papirvogn
+STR_8028_COPPER_ORE_HOPPER :Kobbermalmvogn
+STR_8029_WATER_TANKER :Vannvogn
+STR_802A_FRUIT_TRUCK :Fruktvogn
+STR_802B_RUBBER_TRUCK :Gummivogn
+STR_802C_SUGAR_TRUCK :Sukkervogn
+STR_802D_COTTON_CANDY_HOPPER :Sukkerspinnvogn
+STR_802E_TOFFEE_HOPPER :Karamellvogn
+STR_802F_BUBBLE_VAN :Boblevogn
+STR_8030_COLA_TANKER :Colavogn
+STR_8031_CANDY_VAN :Søtsakvogn
+STR_8032_TOY_VAN :Leketøyvogn
+STR_8033_BATTERY_TRUCK :Batterivogn
+STR_8034_FIZZY_DRINK_TRUCK :Mineralvannvogn
+STR_8035_PLASTIC_TRUCK :Plastvogn
+STR_8036_X2001_ELECTRIC :'X2001' (elektrisk)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (elektrisk)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :Passasjervogn
+STR_803A_MAIL_VAN :Postvogn
+STR_803B_COAL_CAR :Kullvogn
+STR_803C_OIL_TANKER :Oljetankvogn
+STR_803D_LIVESTOCK_VAN :Buskapvogn
+STR_803E_GOODS_VAN :Godsvogn
+STR_803F_GRAIN_HOPPER :Kornvogn
+STR_8040_WOOD_TRUCK :Tømmervogn
+STR_8041_IRON_ORE_HOPPER :Jernmalmvogn
+STR_8042_STEEL_TRUCK :Stålvogn
+STR_8043_ARMORED_VAN :Armert vogn
+STR_8044_FOOD_VAN :Matvogn
+STR_8045_PAPER_TRUCK :Papirvogn
+STR_8046_COPPER_ORE_HOPPER :Kobbermalmvogn
+STR_8047_WATER_TANKER :Vannvogn
+STR_8048_FRUIT_TRUCK :Fruktvogn
+STR_8049_RUBBER_TRUCK :Gummivogn
+STR_804A_SUGAR_TRUCK :Sukkervogn
+STR_804B_COTTON_CANDY_HOPPER :Sukkerspinnvogn
+STR_804C_TOFFEE_HOPPER :Karamellvogn
+STR_804D_BUBBLE_VAN :Boblevogn
+STR_804E_COLA_TANKER :Colavogn
+STR_804F_CANDY_VAN :Søtsakvogn
+STR_8050_TOY_VAN :Leketøyvogn
+STR_8051_BATTERY_TRUCK :Batterivogn
+STR_8052_FIZZY_DRINK_TRUCK :Mineralvannvogn
+STR_8053_PLASTIC_TRUCK :Plastvogn
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (elektrisk)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (elektrisk)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (elektrisk)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (elektrisk)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :Passasjervogn
+STR_805A_MAIL_VAN :Postvogn
+STR_805B_COAL_CAR :Kullvogn
+STR_805C_OIL_TANKER :Oljetankvogn
+STR_805D_LIVESTOCK_VAN :Buskapvogn
+STR_805E_GOODS_VAN :Godsvogn
+STR_805F_GRAIN_HOPPER :Kornvogn
+STR_8060_WOOD_TRUCK :Tømmervogn
+STR_8061_IRON_ORE_HOPPER :Jernmalmvogn
+STR_8062_STEEL_TRUCK :Stålvogn
+STR_8063_ARMORED_VAN :Armert vogn
+STR_8064_FOOD_VAN :Matvogn
+STR_8065_PAPER_TRUCK :Papirvogn
+STR_8066_COPPER_ORE_HOPPER :Kobbermalmvogn
+STR_8067_WATER_TANKER :Vannvogn
+STR_8068_FRUIT_TRUCK :Fruktvogn
+STR_8069_RUBBER_TRUCK :Gummivogn
+STR_806A_SUGAR_TRUCK :Sukkervogn
+STR_806B_COTTON_CANDY_HOPPER :Sukkerspinnvogn
+STR_806C_TOFFEE_HOPPER :Karamellvogn
+STR_806D_BUBBLE_VAN :Boblevogn
+STR_806E_COLA_TANKER :Colavogn
+STR_806F_CANDY_VAN :Søtsakvogn
+STR_8070_TOY_VAN :Leketøyvogn
+STR_8071_BATTERY_TRUCK :Batterivogn
+STR_8072_FIZZY_DRINK_TRUCK :Mineralvannvogn
+STR_8073_PLASTIC_TRUCK :Plastikkvogn
+STR_8074_MPS_REGAL_BUS :MPS Regal-buss
+STR_8075_HEREFORD_LEOPARD_BUS :Hereford Leopard-buss
+STR_8076_FOSTER_BUS :Foster-buss
+STR_8077_FOSTER_MKII_SUPERBUS :Foster MkII-superbuss
+STR_8078_PLODDYPHUT_MKI_BUS :Ploddyphut MkI-buss
+STR_8079_PLODDYPHUT_MKII_BUS :Ploddyphut MkII-buss
+STR_807A_PLODDYPHUT_MKIII_BUS :Ploddyphut MkIII-buss
+STR_807B_BALOGH_COAL_TRUCK :Balogh-kullbil
+STR_807C_UHL_COAL_TRUCK :Uhl-kullbil
+STR_807D_DW_COAL_TRUCK :DW-kullbil
+STR_807E_MPS_MAIL_TRUCK :MPS-postbil
+STR_807F_REYNARD_MAIL_TRUCK :Reynard-postbil
+STR_8080_PERRY_MAIL_TRUCK :Perry-postbil
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :MightyMover-postbil
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Powernaught-postbil
+STR_8083_WIZZOWOW_MAIL_TRUCK :Wizzowow-postbil
+STR_8084_WITCOMBE_OIL_TANKER :Witcombe-tankbil for olje
+STR_8085_FOSTER_OIL_TANKER :Foster-tankbil for olje
+STR_8086_PERRY_OIL_TANKER :Perry-tankbil for olje
+STR_8087_TALBOTT_LIVESTOCK_VAN :Talbott-lastebil for buskap
+STR_8088_UHL_LIVESTOCK_VAN :Uhl-lastebil for buskap
+STR_8089_FOSTER_LIVESTOCK_VAN :Foster-lastebil for buskap
+STR_808A_BALOGH_GOODS_TRUCK :Balogh-lastebil for gods
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Craighead-lastebil for gods
+STR_808C_GOSS_GOODS_TRUCK :Goss-lastebil for gods
+STR_808D_HEREFORD_GRAIN_TRUCK :Hereford--lastebil for korn
+STR_808E_THOMAS_GRAIN_TRUCK :Thomas-lastebil for korn
+STR_808F_GOSS_GRAIN_TRUCK :Goss-lastebil for korn
+STR_8090_WITCOMBE_WOOD_TRUCK :Witcombe-tømmerbil
+STR_8091_FOSTER_WOOD_TRUCK :Foster-tømmerbil
+STR_8092_MORELAND_WOOD_TRUCK :Moreland-tømmerbil
+STR_8093_MPS_IRON_ORE_TRUCK :MPS-lastebil for jernmalm
+STR_8094_UHL_IRON_ORE_TRUCK :Uhl-lastebil for jernmalm
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Chippy-lastebil for jernmalm
+STR_8096_BALOGH_STEEL_TRUCK :Balogh-lastebil for stål
+STR_8097_UHL_STEEL_TRUCK :Uhl-lastebil for stål
+STR_8098_KELLING_STEEL_TRUCK :Kelling-lastebil for stål
+STR_8099_BALOGH_ARMORED_TRUCK :Armert Balogh-bil
+STR_809A_UHL_ARMORED_TRUCK :Armert Uhl-bil
+STR_809B_FOSTER_ARMORED_TRUCK :Armert Foster-bil
+STR_809C_FOSTER_FOOD_VAN :Foster-lastebil for mat
+STR_809D_PERRY_FOOD_VAN :Perry-lastebil for mat
+STR_809E_CHIPPY_FOOD_VAN :Chippy-lastebil for mat
+STR_809F_UHL_PAPER_TRUCK :Uhl-lastebil for papir
+STR_80A0_BALOGH_PAPER_TRUCK :Balogh-lastebil for papir
+STR_80A1_MPS_PAPER_TRUCK :MPS-lastebil for papir
+STR_80A2_MPS_COPPER_ORE_TRUCK :MPS-lastebil for kobbermalm
+STR_80A3_UHL_COPPER_ORE_TRUCK :Uhl-lastebil for kobbermalm
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Goss-lastebil for kobbermalm
+STR_80A5_UHL_WATER_TANKER :Uhl-tankbil for vann
+STR_80A6_BALOGH_WATER_TANKER :Balogh-tankbil for vann
+STR_80A7_MPS_WATER_TANKER :MPS-tankbil for vann
+STR_80A8_BALOGH_FRUIT_TRUCK :Balogh-lastebil for frukt
+STR_80A9_UHL_FRUIT_TRUCK :Uhl-lastebil for frukt
+STR_80AA_KELLING_FRUIT_TRUCK :Kelling-lastebil for frukt
+STR_80AB_BALOGH_RUBBER_TRUCK :Balogh-lastebil for gummi
+STR_80AC_UHL_RUBBER_TRUCK :Uhl-lastebil for gummi
+STR_80AD_RMT_RUBBER_TRUCK :RMT-lastebil for gummi
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :MightyMover-lastebil for sukker
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Powernaught-lastebil for sukker
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Wizzowow-lastebil for sukker
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :MightyMover-lastebil for cola
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Powernaught-lastebil for cola
+STR_80B3_WIZZOWOW_COLA_TRUCK :Wizzowow-lastebil for cola
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :MightyMover-lastebil for sukkerspinn
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Powernaught-lastebil for sukkerspinn
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Wizzowow-lastebil for sukkerspinn
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :MightyMover-lastebil for karamell
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Powernaught-lastebil for karamell
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Wizzowow-lastebil for karamell
+STR_80BA_MIGHTYMOVER_TOY_VAN :MightyMover-lastebil for leketøy
+STR_80BB_POWERNAUGHT_TOY_VAN :Powernaught-lastebil for leketøy
+STR_80BC_WIZZOWOW_TOY_VAN :Wizzowow-lastebil for leketøy
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :MightyMover-lastebil for søtsaker
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Powernaught-lastebil for søtsaker
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Wizzowow-lastebil for søtsaker
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :MightyMover-lastebil for batteri
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Powernaught-lastebil for batteri
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Wizzowow-lastebil for batteri
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :MightyMover-tankbil for mineralvann
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Powernaught-tankbil for mineralvann
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Wizzowow-tankbil for mineralvann
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :MightyMover-lastebil for plast
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Powernaught-lastebil for plast
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Wizzowow-lastebil for plast
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :MightyMover-lastebil for bobler
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Powernaught-lastebil for bobler
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Wizzowow-lastebil for bobler
+STR_80CC_MPS_OIL_TANKER :MPS-oljetanker
+STR_80CD_CS_INC_OIL_TANKER :CS-Inc.-oljetanker
+STR_80CE_MPS_PASSENGER_FERRY :MPS-passasjerferje
+STR_80CF_FFP_PASSENGER_FERRY :FFP-passasjerferje
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Bakewell 300-luftputebåt
+STR_80D1_CHUGGER_CHUG_PASSENGER :Chugger-Chug-passasjerferje
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Shivershake-passasjerferje
+STR_80D3_YATE_CARGO_SHIP :Yate-konteinerskip
+STR_80D4_BAKEWELL_CARGO_SHIP :Bakewell-konteinerskip
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Mightymover-konteinerskip
+STR_80D6_POWERNAUT_CARGO_SHIP :Powernaut-konteinerskip
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Tricario-helikopter
+STR_80FE_GURU_X2_HELICOPTER :Guru X2-helikopter
+STR_80FF_POWERNAUT_HELICOPTER :Powernaut-helikopter
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Melding fra kjøretøysprodusent
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}Vi har nettopp designet et nytt {STRING} - er du interessert i ett års ekslusivt bruk av dette, slik vi kan se hvordan det virker før det blir allment tilgjengelig?
+STR_8102_RAILROAD_LOCOMOTIVE :lokomotiv
+STR_8103_ROAD_VEHICLE :kjøretøy
+STR_8104_AIRCRAFT :fly
+STR_8105_SHIP :skip
+STR_8106_MONORAIL_LOCOMOTIVE :monorail-lokomotiv
+STR_8107_MAGLEV_LOCOMOTIVE :maglev-lokomotiv
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}{TOWN} togstall
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Innbyggerne jubler . . .{}Første tog ankommer {STATION}!
+STR_8802_DETAILS :{WHITE}{STRING} (Detaljer)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Tog i veien
+STR_8804 :{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8806_GO_TO :Kjør til {STATION}
+STR_8807_GO_TO_TRANSFER :Gå til {STATION} (overfør og ta last)
+STR_8808_GO_TO_UNLOAD :GÃ¥ til {STATION} (last av)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Gå til {STATION} (overfør og forlat som tom)
+STR_880A_GO_TO_LOAD :GÃ¥ til {STATION} (last)
+STR_880B_GO_TO_TRANSFER_LOAD :Gå til {STATION} (overfør og vent på full last)
+STR_880C_GO_NON_STOP_TO :GÃ¥ uten stopp til {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Gå uten stopp til {STATION} (overfør og ta last)
+STR_880E_GO_NON_STOP_TO_UNLOAD :GÃ¥ uten stopp til {STATION} (last av)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Gå uten stopp {STATION} (overfør og forlat som tom)
+STR_8810_GO_NON_STOP_TO_LOAD :GÃ¥ uten stopp til {STATION} (last)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Gå uten stopp til {STATION} (overfør og vent på full last)
+STR_GO_TO_TRAIN_DEPOT :GÃ¥ til {TOWN} togdepot
+STR_SERVICE_AT_TRAIN_DEPOT :Velikehold ved {TOWN} togstall
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Kjør uten å stoppe til {TOWN} togstall
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Vedlikehold (uten å stoppe) ved {TOWN} togstall
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}Er på vei til {TOWN} togstall
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}Er på vei til {TOWN} togstall, {VELOCITY}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE :{LTBLUE}Vedlikehold ved {TOWN} togstall
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE_VEL :{LTBLUE}Vedlikehold ved {TOWN} togstall, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (Ugyldig ordre)
+
+STR_UNKNOWN_DESTINATION :ukjent destinasjon
+STR_8812_EMPTY :{LTBLUE}Tom
+STR_8813_FROM :{LTBLUE}{CARGO} fra {STATION}
+STR_FROM_MULT :{LTBLUE}{CARGO} fra {STATION} (x{NUM})
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}Tog {COMMA} venter i togstallen
+STR_8815_NEW_VEHICLES :{BLACK}Nye tog/vogner
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Toget er for langt
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Tog kan kun endres når det står stille i togstallen
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} Tog
+
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Nye tog/vogner for jernbane
+STR_NEW_ELRAIL_VEHICLES :{WHITE}Nytt elektrisk tog
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Nye tog/vogner for monorail
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Nye tog/vogner for maglev
+STR_ALL_AVAIL_RAIL_VEHICLES :{WHITE}Skinnekjøretøy
+
+STR_881F_BUILD_VEHICLE :{BLACK}Kjøp tog/vogn
+STR_CLONE_ROAD_VEHICLE :{BLACK}Klon et kjøretøy
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}Dette vil skape en kopi av et kjøretøy. CTRL-klikk vil også sørge for delte ordrer
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Dette vil skape en kopi av et kjøretøy. Klikk denne knappen og deretter på et hvilket som helst kjøretøy. CTRL-klikk vil sørge for delte ordrer
+STR_CLONE_TRAIN :{BLACK}Klon tog
+STR_CLONE_TRAIN_INFO :{BLACK}Dette vil skape en kopi av et lokomotiv inkludert alle vogner. CTRL-klikk vil også sørge for delte ordrer
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}Dette vil skape en kopi av et lokomotiv inkludert alle vogner. Trykk denne knappen og så på et hvilket som helst tog. CTRL-klikk vil også sørge for delte ordrer
+STR_8820_RENAME :{BLACK}Endre navn
+STR_8823_SKIP :{BLACK}Hopp over
+STR_8824_DELETE :{BLACK}Slett
+STR_8825_NON_STOP :{BLACK}Uten stopp
+STR_8826_GO_TO :{BLACK}Kjør til
+STR_8827_FULL_LOAD :{BLACK}Last fullt
+STR_8828_UNLOAD :{BLACK}Last av
+STR_REFIT :{BLACK}Bygg om
+STR_REFIT_TIP :{BLACK}Velg varetypen det skal endres til. CTRL-klikk for å omgjøre.
+STR_REFIT_ORDER :(Bygg om til {STRING})
+STR_8829_ORDERS :{WHITE}{VEHICLE} (Ordre)
+STR_882A_END_OF_ORDERS :{SETX 10}- - Slutt på ordre - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}Vedlikehold
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Kan ikke bygge jernbanekjøretøy...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Bygget: {LTBLUE}{NUM}{BLACK} Verdi: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Verdi: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}Laster på/av
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}Toget må være stoppet i togstallen
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Kan ikke sende tog til togstall...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Ikke plass til flere ordrer
+STR_8832_TOO_MANY_ORDERS :{WHITE}For mange ordrer
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Kan ikke sette inn ny ordre...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Kan ikke slette denne ordren...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Kan ikke endre denne ordren...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Kan ikke flytte kjøretøy...
+STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}Bakmaskinen vil alltid følge det fremste motstykket
+STR_8838_N_A :N/A{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Kan ikke selge jernbanekjøretøy...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Kan ikke finne en togstall i nærheten
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Kan ikke stoppe/starte tog...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Vedlikeholdsintervall: {LTBLUE}{COMMA}dager{BLACK} Forrige vedlikehold: {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Vedlikeholdsintervall: {LTBLUE}{COMMA} %{BLACK} Forrige vedlikehold: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Tog - trykk på tog for mer informasjon
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Bygg nye tog (trenger en togstall)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Tog - trykk på tog for mer info. Dra vogn for å legge til/fjerne fra tog
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Bygg nytt tog (vogn)
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Dra tog (vogn) her for å selge
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Vis stedet togstallen ligger på
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Liste over tog/vogner - trykk på tog/vogn for mer informasjon
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Bygg den valgte enheten
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Endre navnet til den valgte enheten
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Gjeldende togstatus - trykk her for å stoppe/starte tog
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Vis togets ordrer
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Vis togets gjeldene posisjon
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Send toget til en togstall. CTRL-klikk for kun å utføre vedlikehold
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Tving toget til å kjøre på rødt lys
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Bytt kjøreretning
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Vis detaljer om toget
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Øk vedlikeholdsintervall
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Reduser verlikeholdsintervall
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Vis detaljer om innholdet i vognene
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Vis detaljer om tog/vogner
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Vis kapasiteten til vognene
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Vis en total kapasitet på togene oppdelt etter godstype
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Ordreliste - trykk på en ordre for å velge den
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}Hopper over gjeldende ordre, og forsett på neste
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Slett den valgte ordren
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Gjør den valgte ordren om til en
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Sett inn en ordre før den valgte ordren, eller i slutten av listen.
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Fyll alltid kjøretøyet ved valgte stasjon
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Tøm alltid kjøretøyet ved valgte stasjon
+STR_SERVICE_HINT :{BLACK}Hopp over ordren med mindre vedlikehold trengs.
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}Nytt {STRING} er nå tilgjengelig!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Koster: {CURRENCY} Vekt: {WEIGHT_S}{}Fart: {VELOCITY} Kraft: {POWER}{}Driftkostnader: {CURRENCY}/Ã¥r{}Kapasitet: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}Havarert
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}Alder: {LTBLUE}{STRING}{BLACK} Driftkostnad: {LTBLUE}{CURRENCY}/Ã¥r
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Vekt: {LTBLUE}{WEIGHT_S} {BLACK}Kraft: {LTBLUE}{POWER}{BLACK} Maks. fart: {LTBLUE}{VELOCITY}
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Vekt: {LTBLUE}{WEIGHT_S} {BLACK}Kraft: {LTBLUE}{POWER}{BLACK} Høyeste fart: {LTBLUE}{VELOCITY} {BLACK}Høyeste hastighet.: {LTBLUE}{FORCE}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Inntekt i år: {LTBLUE}{CURRENCY} (sist år: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}PÃ¥litelighet: {LTBLUE}{COMMA} % {BLACK}Havarier siden forrige vedlikehold: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Stoppet
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Kan ikke tvinge tog til å kjøre på rødt lys ved fare...
+STR_8863_CRASHED :{RED}Krasjet
+
+STR_8865_NAME_TRAIN :{WHITE}Navngi tog
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}Kan ikke navngi tog...
+STR_8867_NAME_TRAIN :{BLACK}Navngi tog
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Togkrasj!{}{COMMA} dør i kollisjonen
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Kan ikke snu toget...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Gi tog/vogn nytt navn
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Kan ikke gi tog/vogn nytt navn...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Få den merkede ordren til å tvinge kjøretøyet til å dumpe lasten
+STR_886F_TRANSFER :{BLACK}Overfør
+
+STR_TRAIN_STOPPING :{RED}Stopper
+STR_TRAIN_STOPPING_VEL :{RED}Stopper, {VELOCITY}
+STR_INCOMPATIBLE_RAIL_TYPES :Inkompatible jernbanetyper
+STR_TRAIN_NO_POWER :{RED}Ingen strøm
+STR_TRAIN_START_NO_CATENARY :Dette sporet mangler et kjede, så toget kan ikke starte
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Kjøretøy i veien
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} kjøretøy
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}{TOWN} Garasje
+STR_9004_NEW_VEHICLES :{BLACK}Nye kjøretøy
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}Nye kjøretøy
+STR_9007_BUILD_VEHICLE :{BLACK}Kjøp kjøretøy
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Kan ikke kjøpe kjøretøy...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (detaljer)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}Alder: {LTBLUE}{STRING}{BLACK} Driftkostnader: {LTBLUE}{CURRENCY}/Ã¥r
+STR_900E_MAX_SPEED :{BLACK}Maks. fart: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Inntekt i år: {LTBLUE}{CURRENCY} (sist år: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}PÃ¥litelighet: {LTBLUE}{COMMA} % {BLACK}Havarier siden forrige vedlikehold: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Bygget: {LTBLUE}{NUM}{BLACK} Verdi: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Kapasitet: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}...må være stoppet i en garasje
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Kan ikke selge kjøretøy...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Kan ikke starte/stoppe kjøretøy...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}Kjøretøy {COMMA} er i garasjen
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}Er på vei til {TOWN} garasje
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}Er på vei til {TOWN} garasje, {VELOCITY}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE :{LTBLUE}Vedlikehold ved {TOWN} garasje
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE_VEL :{LTBLUE}Vedlikehold ved {TOWN} garasje, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Kan ikke sende kjøretøy til garasje...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Kan ikke finne en garasje i nærheten
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Kjøretøy - trykk på kjøretøy for informasjon
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Bygg nye kjøretøy (krever en garasje)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Gjeldende kjøretøystatus - trykk her for å stoppe/starte kjøretøy
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Vis kjøretøyets ordreliste
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Vis kjøretøyets gjeldende posisjon
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Send kjøretøyet til en garasje
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Bytt kjøreretning
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Vis detaljer om kjøretøyet
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Kjøretøyliste - trykk på kjøretøy for mer informasjon
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Bygg nytt kjøretøy
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Dra kjøretøy her for å selge det
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Vis hvor garasjen ligger
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Kjøretøyliste - trykk på kjøretøy for mer informasjon
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Bygg det valgte kjøretøyet
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}Nytt kjøretøy er nå tilgjengelig!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Koster: {CURRENCY}{}Fart: {VELOCITY}{}Driftkostnader: {CURRENCY}/Ã¥r{}Kapasitet: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Navngi kjøretøy
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Kan ikke navngi kjøretøy...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Navngi kjøretøy
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Innbyggerne jubler . . .{}Første buss ankommer {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Innbyggerne jubler . . .{}Første lastebil ankommer {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}Kollisjon!{}Sjåfør dør etter kollisjon med tog
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}Kollisjon!{}{COMMA} dør etter kollisjon med tog
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Kan ikke snu...
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}Kan ikke snu kjøretøy som består av flere deler
+STR_9034_RENAME :{BLACK}Endre navn
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Endre navnet til kjøretøytypen
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Endre navnet til kjøretøytypen
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Kan ikke endre navnet til kjøretøytypen...
+STR_9038_GO_TO_ROADVEH_DEPOT :Kjør til {TOWN} garasje
+STR_SERVICE_AT_ROADVEH_DEPOT :Vedlikehold ved {TOWN} garasje
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Bygg om kjøretøyet til å ta en annen type last
+STR_REFIT_ROAD_VEHICLE :{BLACK}Bygg om bil
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Bygg om kjøretøyet til å ta den valgte lasten
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Kan ikke bygge om bil...
+STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Velg en type varer som kjøretøyet skal lastes med
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Bygg havn
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Bygg havn
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Kan ikke bygge havn her...
+STR_9803_SHIP_DEPOT :{WHITE}{TOWN} skipsdepot
+STR_9804_NEW_SHIPS :{BLACK}Nye skip
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} skip
+STR_9808_NEW_SHIPS :{WHITE}Nye skip
+STR_9809_BUILD_SHIP :{BLACK}Bygg skip
+STR_CLONE_SHIP :{BLACK}Klon skip
+STR_CLONE_SHIP_INFO :{BLACK}Dette vil skape en kopi av et skip. CTRL-klikk vil også sørge for delte ordrer
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}Dette vil skape en kopi av et lokomotiv inkludert alle vogner. Trykk på denne knappen og så på et hvilket som helst skip. CTRL-klikk vil også sørge for delte ordrer
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}Må være stoppet i depotet
+STR_980C_CAN_T_SELL_SHIP :{WHITE}Kan ikke selge skip...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Kan ikke bygge skip...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Det er et skip i veien
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Detaljer)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}Alder: {LTBLUE}{STRING}{BLACK} Driftkostnader: {LTBLUE}{CURRENCY}/Ã¥r
+STR_9813_MAX_SPEED :{BLACK}Maks. fart: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Inntekt i år: {LTBLUE}{CURRENCY} (sist år: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}PÃ¥litelighet: {LTBLUE}{COMMA} % {BLACK}Havarier siden forrige vedlikehold: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Bygget: {LTBLUE}{NUM}{BLACK} Verdi: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}Kapasitet: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}Kan ikke starte/stoppe skip...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Kan ikke sende skip til depotet...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Kan ikke finne et depot i nærheten
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}Er på vei til {TOWN} skipsdepot
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}Er på vei mot {TOWN} skipsdepot, {VELOCITY}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE :{LTBLUE}Vedlikehold ved {TOWN} skipsdepot
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE_VEL :{LTBLUE}Vedlikehold ved {TOWN} skipsdepot, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}Skip {COMMA} venter i depotet
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Bygg havn
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Bygg skipsdepot (trengs for bygging og vedlikehold av skip)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Skip - trykk på skip for mer informasjon
+STR_9820_BUILD_NEW_SHIP :{BLACK}Bygg nytt skip
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Dra skip hit for å selge det
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Vis hvor depotet ligger
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Skip - trykk på skip for mer informasjon
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Bygg nytt skip (trenger et skipsdepot)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}Skipsliste - trykk på skip for mer informasjon
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Bygg det valgte skipet
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Gjeldende skipsstatus - trykk her for å stoppe/starte skip
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Vis skipets ordrer
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Vis skipets gjeldende posisjon
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Send skipet til depotet
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Vis detaljer om skipet
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}Nytt skip er nå tilgjengelig!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Koster: {CURRENCY} Maks. fart: {VELOCITY}{}Kapasitet: {CARGO}{}Driftkostnader: {CURRENCY}/Ã¥r
+STR_982F_NAME_SHIP :{BLACK}Navngi skip
+
+STR_9831_NAME_SHIP :{WHITE}Navngi skip
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Kan ikke navngi skip...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Innbyggerne jubler . . .{}Første skip ankommer {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Plasser bøye, kan brukes til å danne kontrollpunkter
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Kan ikke plassere bøye her...
+STR_9836_RENAME :{BLACK}Endre navn
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Endre navnet til skipstypen
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Endre navnet til skipstypen
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Kan ikke endre navnet til skipstypen...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Bygg om et konteinerskip til å ta en annen type last
+STR_983B_REFIT :{WHITE}{VEHICLE} (bygg om)
+STR_983C_REFIT_SHIP :{BLACK}Bygg om skip
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Velg hvilken last skipet skal ta
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Bygg om skip til å frakte den valgte varetypen
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Velg varetype:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Ny kapasitet: {GOLD}{CARGO}{}{BLACK}Kostnad for ombygging: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Kan ikke bygge om skip...
+STR_9842_REFITTABLE :(ombyggbart)
+STR_GO_TO_SHIP_DEPOT :Seil til {TOWN} skipsdepot
+SERVICE_AT_SHIP_DEPOT :Vedlikehold ved {TOWN} skipsdepot
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Flyplasser
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Kan ikke bygge flyplass her...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} hangar
+STR_A003_NEW_AIRCRAFT :{BLACK}Nytt fly
+STR_CLONE_AIRCRAFT :{BLACK}Klon fly
+STR_CLONE_AIRCRAFT_INFO :{BLACK}Dette vil skape en kopi av et fly. CTRL-klikk vil også sørge for delte ordrer
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Dette vil skape en kopi av et fly. Trykk denne knappen og så på et hvilket som helst fly. CTRL-klikk vil også sørge for delte ordrer
+STR_A005_NEW_AIRCRAFT :{WHITE}Nytt fly
+STR_A006_BUILD_AIRCRAFT :{BLACK}Bygg fly
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Kan ikke bygge fly...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} fly
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (ordre)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (detaljer)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Alder: {LTBLUE}{STRING}{BLACK} Driftkostnader: {LTBLUE}{CURRENCY}/Ã¥r
+STR_A00E_MAX_SPEED :{BLACK}Maks. fart: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Inntekt i år: {LTBLUE}{CURRENCY} (forrige år: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}PÃ¥litelighet: {LTBLUE}{COMMA} % {BLACK}Havarier siden forrige vedlikehold: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Bygget: {LTBLUE}{NUM}{BLACK} Verdi: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Kan ikke sende fly til hangar...
+STR_HEADING_FOR_HANGAR :{ORANGE}Er på vei til {STATION} hangar
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}Er på vei til {STATION} hangar, {VELOCITY}
+STR_HEADING_FOR_HANGAR_SERVICE :{LTBLUE}Vedlikehold ved {STATION} hangar
+STR_HEADING_FOR_HANGAR_SERVICE_VEL :{LTBLUE}Vedlikehold ved {STATION} hangar, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}Fly {COMMA} venter i hangaren
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Det er et fly i veien
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Kan ikke stoppe/starte flyet...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Flyet er i luften
+STR_A019_CAPACITY :{BLACK}Kapasitet: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Kapasitet: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}Må stå i en hangar
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Kan ikke selge fly...
+STR_A01D_AIRPORT_CONSTRUCTION :Bygg flyplass
+STR_A01E_BUILD_AIRPORT :{BLACK}Bygg flyplass
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Fly - trykk på fly for mer informasjon
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Bygg nytt fly (krever flyplass med hangar)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Fly - trykk på fly for mer informasjon
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Bygg nytt fly
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}Dra fly hit for å selge
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Vis hvor hangaren ligger
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Flyliste - trykk på fly for mer informasjon
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Bygg det valge flyet
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Gjeldende flystatus - trykk her for å stoppe/starte fly
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Vis flyets ordrer
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Vis flyets gjeldende posisjon
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Send fly til hangar. CTRL-klikk for kun å utføre vedlikehold
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Vis detaljer om flyet
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}Nytt fly er nå tilgjengelig
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Koster: {CURRENCY} Maks. fart: {VELOCITY}{}Kapasitet: {COMMA} passasjerer, {COMMA} sekker post {}Driftkostnader: {CURRENCY}/Ã¥r
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Navngi fly
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Kan ikke navngi fly...
+STR_A032_NAME_AIRCRAFT :{BLACK}Navngi fly
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Innbyggerne jubler . . .{}Første fly ankommer {STATION}!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Flykrasj!{}{COMMA} dør ved {STATION}
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Flystyrt!{}Fly gikk tom for drivstoff, {COMMA} døde i eksplosjon!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Endre navn
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Endre navn til flytype
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Endre navn til flytype
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Kan ikke endre navn...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Bygg om et fly til å ta en annen type last
+STR_A03C_REFIT :{WHITE}{VEHICLE} (bygg om)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Bygg om fly
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Velg hvilken last skipet skal ta
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Bygg om skip til å frakte den valgte varetypen
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Velg varetype:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Ny kapasitet: {GOLD}{STRING}{}{BLACK}Kostnad for ombygging: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Kan ikke bygge om flyet...
+STR_GO_TO_AIRPORT_HANGAR :Fly til {STATION} hangar
+SERVICE_AT_AIRPORT_HANGAR :Vedlikehold ved {STATION} hangar
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}Zeppelinulykke på {STATION}!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Kjøretøy ødelagt i UFO-kollisjon!
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}Eksplosjon på oljeraffineri i nærheten av {TOWN}!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}Fabrikk ødelagt på mistenkeligvis i nærheten av {TOWN}!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}UFO lander i nærheten av {TOWN}!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}Gruvegangkollaps fører til store ødeleggelser i nærheten av {TOWN}!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Flyter over!{}Minst {COMMA} antatt fortapt{P "" e} eller død{P "" s} etter dødlig flom!
+
+STR_BRIBE_FAILED :{WHITE}Ditt forsøk på bestikkelser
+STR_BRIBE_FAILED_2 :{WHITE}har blitt oppdaget av en regional inspektør.
+STR_BUILD_DATE :{BLACK}Byggt: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Detaljert prestasjonsnivå
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}Detalj
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM} %
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Kjøretøy:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Stasjoner:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Min. gevinst:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Min. inntekt:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Maks. inntekt:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Levert:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Frakt:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Penger:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}LÃ¥n:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Totalt:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Antall kjøretøy. Dette inkluderer vei kjøretøy, tog, skip og flymaskiner.
+STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}Antall stasjonsdeler. Hver del av en stasjon (eks. tog stasjon, buss stop, flyplass) er talt, selv om de er tilkoblet til en stasjon.
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}Gevinsten av kjøretøyene med lavest inntekt (av alle kjøretøy eldre enn 2 år)
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Penger tjent i måneden med lavest gevinst av de 12 siste kvartalene
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Penger tjent i måneden med høyest gevinst i de siste 12 kvartalene
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}Enheter med frakt, levert i de siste fire kvartalene.
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}Typer av frakt, levert i de siste fire kvartalene.
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Hvor mye penger dette firmaet har i banken
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}Størrelsen på firmaets lån
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Total poeng av mulige poeng
+
+STR_NEWGRF_SETTINGS_BUTTON :{BLACK}NewGRF Instillinger
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}Innstillinger for ny grafikk
+STR_NEWGRF_APPLY_CHANGES :{BLACK}Bruk forandringene
+STR_NEWGRF_SET_PARAMETERS :{BLACK}Sett parametre
+STR_NEWGRF_TIP :{BLACK}En liste over alle de nye grafikkpakkene du har installert. Klikk på en pakke for å forandre innstillingene.
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}Der er for tiden ikke noen nye grafikkfiler installert! Manualen inneholder instruksjoner for installering av ny grafikk
+STR_NEWGRF_FILENAME :{BLACK}Filnavn: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
+STR_NEWGRF_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING}
+STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}Du er i ferd med å gjøre forandringer i et kjørende spill; Dette kan krasje OpenTTD.{}Er du helt sikker på at du vil gjøre dette?
+
+STR_NEWGRF_ADD :{BLACK}Legg til
+STR_NEWGRF_ADD_TIP :{BLACK}Legg en ny NewGRF-fil til listen
+STR_NEWGRF_REMOVE :{BLACK}Fjern
+STR_NEWGRF_REMOVE_TIP :{BLACK}Fjern den valgte NewGRF filen fra listen
+STR_NEWGRF_MOVEUP :{BLACK}Flytt opp
+STR_NEWGRF_MOVEUP_TIP :{BLACK}Flytt den valgte NewGRF-filen oppover listen
+STR_NEWGRF_MOVEDOWN :{BLACK}Flytt ned
+STR_NEWGRF_MOVEDOWN_TIP :{BLACK}Flytt den valgte NewGRF-filen nedover listen
+STR_NEWGRF_FILE_TIP :{BLACK}En liste over NewGRF-filene som er installert. Klikk på en fil for å forandre parameterene
+STR_NEWGRF_PARAMETER :{BLACK}Parametere: {SILVER}{STRING}
+STR_NEWGRF_PARAMETER_QUERY :{BLACK}Skriv NewGRF parameterene
+STR_NEWGRF_NO_INFO :{BLACK}Ingen informasjon tilgjengelig
+
+STR_NEWGRF_ADD_CAPTION :{WHITE}Tilgjengelige NewGRF-filer
+STR_NEWGRF_ADD_FILE :{BLACK}Legg til i seleksjonen
+STR_NEWGRF_ADD_FILE_TIP :{BLACK}Legg den valgte NewGRF filen til i konfigurasjonen din
+STR_NEWGRF_RESCAN_FILES :{BLACK}Søk på nytt
+STR_NEWGRF_RESCAN_FILES_TIP :{BLACK}Oppdater listen over tilgjengelige NewGRF filer
+STR_NEWGRF_DUPLICATE_GRFID :{WHITE}Kan ikke legge til fil: to eller flere GFR ID-er
+
+STR_NEWGRF_NOT_FOUND :{RED}Ingen passende fil funnet
+STR_NEWGRF_DISABLED :{RED}Deaktivert
+
+STR_CURRENCY_WINDOW :{WHITE}Vanlig valuta
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Valutakurs: {ORANGE}{CURRENCY} = £ {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Deler:
+STR_CURRENCY_PREFIX :{LTBLUE}Prefiks:
+STR_CURRENCY_SUFFIX :{LTBLUE}Suffiks:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Bytt til euro: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Bytt til euro: {ORANGE}aldri
+STR_CURRENCY_PREVIEW :{LTBLUE}Forhåndsvis: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Bytt vanlig valutagrense
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} tog
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} kjøretøy
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} Fly
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} skip
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Vis alle tog som har denne stasjonen på deres timeplan
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Vis alle kjøretøy som har denne stasjonen på deres timeplan
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Vis alle fly som har denne stasjonen på deres timeplan
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Vis alle skip som har denne stasjonen på deres timeplan
+
+STR_VEH_WITH_SHARED_ORDERS_LIST :{WHITE}Delte ordre av {COMMA} kjøretøy
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}Vis alle kjøretøy som har samme ruteplan
+
+### depot strings
+STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Du er nå i ferd med å selge alle kjøretøyene i depoet. Er du sikker på at du vil dette?
+
+STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP :{BLACK}Selg alle tog i depodet
+STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP :{BLACK}Selg alle kjøretøy i garasjen
+STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP :{BLACK}Selg alle skip i depotet
+STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP :{BLACK}Selg alle fly i hangaren
+
+STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP :{BLACK}FÃ¥ en liste over alle tog med dette depotet i sine ordre
+STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP :{BLACK}Få en liste over alle kjøretøy med denne garasjen i sine ordre
+STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP :{BLACK}FÃ¥ en liste over alle skip med dette depotet i sine ordre
+STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP :{BLACK}FÃ¥ en liste over alle fly med denne hangaren i sine ordre
+
+STR_DEPOT_AUTOREPLACE_TRAIN_TIP :{BLACK}Autoerstatt alle tog i depotet
+STR_DEPOT_AUTOREPLACE_ROADVEH_TIP :{BLACK}Autoerstatt all kjøretøy i hangaren
+STR_DEPOT_AUTOREPLACE_SHIP_TIP :{BLACK}Autoerstatt all skip i depotet
+STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP :{BLACK}Autoerstatt alle fly i hangaren
+
+STR_VEHICLE_LIST_TRAIN_DEPOT :{BLACK}{STRING} - {COMMA} tog
+STR_VEHICLE_LIST_ROADVEH_DEPOT :{BLACK}{STRING} - {COMMA} kjøretøy
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} skip
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} fly
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}Erstatte {STRING}
+STR_REPLACE_VEHICLES_START :{BLACK}Begynn å bytte ut kjøretøy
+STR_REPLACE_VEHICLES_STOP :{BLACK}Slutt å bytte ut kjøretøy
+STR_NOT_REPLACING :{BLACK}Byttes ikke ut
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Inget lokomotiv valgt
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Velg lokomotivtype å bytte ut
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Velg den nye lokomotivtypen du vil skal ta over for den du har valgt til venstre
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Klikk denne knappen hvis du ikke vil bytte ut lokomotivet som er valgt på venstresiden
+STR_REPLACE_HELP_START_BUTTON :{BLACK}Klikk denne knappen hvis du vil bytte ut det valgte lokomotivet på venstresiden med det valgte lokomotivet på høyresiden
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Velg jernbanetypen du vil velge lokomotiv fra
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Dette viser hvilket lokomotiv som overtar for det valgte lokomotivet på venstresiden
+STR_REPLACE_HELP :{BLACK}Dette verktøyet lar deg bytte ut en type lokomotiv med en annen. Dette blir gjort neste gang lokomotivet er innom et depot.
+STR_REPLACE_REMOVE_WAGON :{BLACK}Vognfjerning: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}La den automatiske utskiftningen beholde lengen på toget ved å fjerne vogner (fra første vogn), hvis utskiftningen gjør toget lenger.
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}Erstatter: {ORANGE}{SKIP}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} Eksperimentell del {}Skift mellom tog- og vognvinduet.{}Vognutskiftningen vil bare bli utført hvis den nye vognen kan ha samme last som den gamle. Dette blir sjekket når utskiftingen finner sted.
+STR_ENGINE_NOT_BUILDABLE :{WHITE}Motoren kan ikke bygges
+
+STR_ENGINES :Motorer
+STR_WAGONS :Vogner
+
+STR_MASS_STOP_DEPOT_TRAIN_TIP :{BLACK}Klikk for å stoppe alle togene i depodet
+STR_MASS_STOP_DEPOT_ROADVEH_TIP :{BLACK}Klikk for å stoppe alle kjøretøyene i garasjen
+STR_MASS_STOP_DEPOT_SHIP_TIP :{BLACK}Klikk for å stoppe alle skipene i depodet
+STR_MASS_STOP_HANGAR_TIP :{BLACK}Klikk for å stoppe alle flyene i hangaren
+
+STR_MASS_START_DEPOT_TRAIN_TIP :{BLACK}Klikk for å starte alle togene i depodet
+STR_MASS_START_DEPOT_ROADVEH_TIP :{BLACK}Klikk for å starte kjøretøyet inne i garasjen
+STR_MASS_START_DEPOT_SHIP_TIP :{BLACK}Klikk for å starte alle skipene i depodet
+STR_MASS_START_HANGAR_TIP :{BLACK}Klikk for å starte alle flyene i hangaren
+
+STR_MASS_STOP_LIST_TIP :{BLACK}Klikk for å stoppe alle kjøretøyene i listen
+STR_MASS_START_LIST_TIP :{BLACK}Klikk for å starte alle kjøretøyene i listen
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}Skiltliste - {COMMA} skilt
+
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :Jernbanelokomotiv
+STR_ELRAIL_VEHICLES :Elektriske tog
+STR_MONORAIL_VEHICLES :Monoraillokomotiv
+STR_MAGLEV_VEHICLES :Maglevlokomotiv
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Kostnad: {GOLD}{CURRENCY}{BLACK} Vekt: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Hastighet: {GOLD}{VELOCITY}{BLACK} Effekt: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}Hastighet: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Driftskostnad: {GOLD}{CURRENCY}/Ã¥r
+STR_PURCHASE_INFO_CAPACITY :{BLACK}Kapasitet: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Markedsintrodusert: {GOLD}{NUM}{BLACK} Levetid: {GOLD}{COMMA} år
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}Maks pålitelighet: {GOLD}{COMMA} %
+STR_PURCHASE_INFO_COST :{BLACK}Kostnad: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Vekt: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Kostnad: {GOLD}{CURRENCY}{BLACK} Hastighet: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Kapasitet: {GOLD}{COMMA} passasjerer, {COMMA} sekker post
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Lokomotivvogner: {GOLD}+{POWER}{BLACK} Vekt: {GOLD}+{WEIGHT_S}
+STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Utstyrbart til: {GOLD}
+STR_PURCHASE_INFO_ALL_TYPES :Alle varetyper
+STR_PURCHASE_INFO_ALL_BUT :Alt utenom {GOLD}
+STR_PURCHASE_INFO_MAX_TE :{BLACK}Maks. trekkraft: {GOLD}{FORCE}
+
+########### String for New Landscape Generator
+
+STR_GENERATE :{WHITE}Generer
+STR_RANDOM :{BLACK}Tilfeldiggjør
+STR_RANDOM_HELP :{BLACK}Endre tilfeldig-nummer som brukes for terreng-generering
+STR_WORLD_GENERATION_CAPTION :{WHITE}Generer en verden
+STR_RANDOM_SEED :{BLACK}Tilfeldig nummer:
+STR_RANDOM_SEED_HELP :{BLACK}Trykk her for å taste inn et tilfeldig nummer
+STR_LAND_GENERATOR :{BLACK}Landskapsgenerator
+STR_TREE_PLACER :{BLACK}Trealgoritme:
+STR_HEIGHTMAP_ROTATION :{BLACK}Høydekartrotering:
+STR_TERRAIN_TYPE :{BLACK}Terrengtype
+STR_QUANTITY_OF_SEA_LAKES :{BLACK}Havflate:
+STR_SMOOTHNESS :{BLACK}Glatthet:
+STR_SNOW_LINE_HEIGHT :{BLACK}Høyde på snøgrensen:
+STR_DATE :{BLACK}Dato:
+STR_NUMBER_OF_TOWNS :{BLACK}Antall byer:
+STR_NUMBER_OF_INDUSTRIES :{BLACK}Antall industrier:
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_SNOW_LINE_UP :{BLACK}Flytt høyden på snøgrensen ett hakk opp
+STR_SNOW_LINE_DOWN :{BLACK}Flytt høyden på snøgrensen ett hakk ned
+STR_SNOW_LINE_QUERY_CAPT :{WHITE}Skift høyden på snøgrensen
+STR_START_DATE_QUERY_CAPT :{WHITE}Endre startår
+STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Skalaadvarsel
+STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Å endre kildemapstørrelsen for mye er ikke anbefalt. Fortsette generering?
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_HEIGHTMAP_NAME :{BLACK}Høydekartnavn:
+STR_HEIGHTMAP_SIZE :{BLACK}Størrelse: {ORANGE}{NUM} x {NUM}
+STR_GENERATION_WORLD :{WHITE}Genererer verden...
+STR_GENERATION_ABORT :{BLACK}Avbryt
+STR_GENERATION_ABORT_CAPTION :{WHITE}Avbryt verdensgenerering
+STR_GENERATION_ABORT_MESSAGE :{YELLOW}Vil du virkelig avbryte verdensgenereringen?
+STR_PROGRESS :{WHITE}{NUM} % ferdig
+STR_GENERATION_PROGRESS :{BLACK}{NUM} / {NUM}
+STR_WORLD_GENERATION :{BLACK}Generer en verden
+STR_TREE_GENERATION :{BLACK}Tregenerering
+STR_UNMOVABLE_GENERATION :{BLACK}Ikke-flyttbar generering
+STR_CLEARING_TILES :{BLACK}Generering av ulendt og steinete område
+STR_SETTINGUP_GAME :{BLACK}Klargjør spillet
+STR_PREPARING_TILELOOP :{BLACK}Kjører tile-loop
+STR_PREPARING_GAME :{BLACK}Gjør klart spillet
+STR_DIFFICULTY_TO_CUSTOM :{WHITE}Denne handlingen endret vanskelighetsgraden til egendefinert
+STR_SE_FLAT_WORLD :{WHITE}Flatt land
+STR_SE_FLAT_WORLD_TIP :{BLACK}Generer et flatt landskap
+STR_SE_RANDOM_LAND :{WHITE}Tilfeldig landskap
+STR_SE_NEW_WORLD :{BLACK}Generer et nytt scenario
+STR_SE_CAPTION :{WHITE}Scenariotype
+STR_FLAT_WORLD_HEIGHT_DOWN :{BLACK}Flytt landhøyden ett nivå ned
+STR_FLAT_WORLD_HEIGHT_UP :{BLACK}Flytt høyden på flagg land ett nivå opp
+STR_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Endre høyden på flatt land
+STR_FLAT_WORLD_HEIGHT :{BLACK}Høyde av flatt land:
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+STR_SMALLMAP_CENTER :{BLACK}Midstill oversiktskartet på den gjeldende posisjonen
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}Liten
+STR_CITY_AIRPORT :{BLACK}By
+STR_METRO_AIRPORT :{BLACK}Metropolflypklass
+STR_INTERNATIONAL_AIRPORT :{BLACK}Internasjonal flyplass
+STR_COMMUTER_AIRPORT :{BLACK}Pendler
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Interkontinental
+STR_HELIPORT :{BLACK}Helikopterlufthavn
+STR_HELIDEPOT :{BLACK}Helikopterdepot
+STR_HELISTATION :{BLACK}Helikopterstasjon
+
+STR_SMALL_AIRPORTS :{BLACK}Små flyplasser
+STR_LARGE_AIRPORTS :{BLACK}Store flyplasser
+STR_HUB_AIRPORTS :{BLACK}Sentrumsflyplasser
+STR_HELIPORTS :{BLACK}Helikopterlufthavner
+
+############ Tooltip measurment
+
+STR_MEASURE_LENGTH :{BLACK}Lengde: {NUM}
+STR_MEASURE_AREA :{BLACK}Område: {NUM} x {NUM}
+STR_MEASURE_LENGTH_HEIGHTDIFF :{BLACK}Lengde: {NUM}{}Høydeforskjell: {NUM} m
+STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}Område: {NUM} x {NUM}{}Høydeforskjell: {NUM} m
+
+########
diff --git a/src/lang/origveh.txt b/src/lang/origveh.txt
new file mode 100644
index 000000000..cf22c2df6
--- /dev/null
+++ b/src/lang/origveh.txt
@@ -0,0 +1,261 @@
+##name Original vehicle names (ENG)
+##ownname Original vehicle names (ENG)
+##isocode xx.UTF-8
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Collett Pannier Tank (Steam)
+STR_8001_MJS_250_DIESEL :MJS 250 (Diesel)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut Diesel
+STR_8006_POWERNAUT_DIESEL :Powernaut Diesel
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (Steam)
+STR_8008_CHANEY_JUBILEE_STEAM :Stanier 'Jubilee' (Steam)
+STR_8009_GINZU_A4_STEAM :Gresley 'A4' (Steam)
+STR_800A_SH_8P_STEAM :BR '8P' (Steam)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Metro Cammell DMU (Diesel)
+STR_800C_DASH_DIESEL :'Sprinter' (Diesel)
+STR_800D_SH_HENDRY_25_DIESEL :BR/Sulzer '25' (Diesel)
+STR_800E_UU_37_DIESEL :EE '37'
+STR_800F_FLOSS_47_DIESEL :Brush '47' (Diesel)
+STR_8010_CS_4000_DIESEL :CS 4000 (Diesel)
+STR_8011_CS_2400_DIESEL :CS 2400 (Diesel)
+STR_8012_CENTENNIAL_DIESEL :Centennial (Diesel)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (Diesel)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (Diesel)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (Diesel)
+STR_8016_SH_125_DIESEL :BR 'IC125' (Diesel)
+STR_8017_SH_30_ELECTRIC :BR '86' (Electric)
+STR_8018_SH_40_ELECTRIC :BR '87' (Electric)
+STR_8019_T_I_M_ELECTRIC :'T.G.V.' (Electric)
+STR_801A_ASIASTAR_ELECTRIC :'Eurostar' (Electric)
+STR_801B_PASSENGER_CAR :Passenger Carriage
+STR_801C_MAIL_VAN :Mail Van
+STR_801D_COAL_CAR :Coal Truck
+STR_801E_OIL_TANKER :Oil Tanker
+STR_801F_LIVESTOCK_VAN :Livestock Van
+STR_8020_GOODS_VAN :Goods Van
+STR_8021_GRAIN_HOPPER :Grain Hopper
+STR_8022_WOOD_TRUCK :Wood Truck
+STR_8023_IRON_ORE_HOPPER :Iron Ore Hopper
+STR_8024_STEEL_TRUCK :Steel Truck
+STR_8025_ARMORED_VAN :Armoured Van
+STR_8026_FOOD_VAN :Food Van
+STR_8027_PAPER_TRUCK :Paper Truck
+STR_8028_COPPER_ORE_HOPPER :Copper Ore Hopper
+STR_8029_WATER_TANKER :Water Tanker
+STR_802A_FRUIT_TRUCK :Fruit Truck
+STR_802B_RUBBER_TRUCK :Rubber Truck
+STR_802C_SUGAR_TRUCK :Sugar Truck
+STR_802D_COTTON_CANDY_HOPPER :Candyfloss Hopper
+STR_802E_TOFFEE_HOPPER :Toffee Hopper
+STR_802F_BUBBLE_VAN :Bubble Van
+STR_8030_COLA_TANKER :Cola Tanker
+STR_8031_CANDY_VAN :Sweets Van
+STR_8032_TOY_VAN :Toy Van
+STR_8033_BATTERY_TRUCK :Battery Truck
+STR_8034_FIZZY_DRINK_TRUCK :Fizzy Drink Truck
+STR_8035_PLASTIC_TRUCK :Plastic Truck
+STR_8036_X2001_ELECTRIC :'X2001' (Electric)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Electric)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :Passenger Carriage
+STR_803A_MAIL_VAN :Mail Van
+STR_803B_COAL_CAR :Coal Truck
+STR_803C_OIL_TANKER :Oil Tanker
+STR_803D_LIVESTOCK_VAN :Livestock Van
+STR_803E_GOODS_VAN :Goods Van
+STR_803F_GRAIN_HOPPER :Grain Hopper
+STR_8040_WOOD_TRUCK :Wood Truck
+STR_8041_IRON_ORE_HOPPER :Iron Ore Hopper
+STR_8042_STEEL_TRUCK :Steel Truck
+STR_8043_ARMORED_VAN :Armoured Van
+STR_8044_FOOD_VAN :Food Van
+STR_8045_PAPER_TRUCK :Paper Truck
+STR_8046_COPPER_ORE_HOPPER :Copper Ore Hopper
+STR_8047_WATER_TANKER :Water Tanker
+STR_8048_FRUIT_TRUCK :Fruit Truck
+STR_8049_RUBBER_TRUCK :Rubber Truck
+STR_804A_SUGAR_TRUCK :Sugar Truck
+STR_804B_COTTON_CANDY_HOPPER :Candyfloss Hopper
+STR_804C_TOFFEE_HOPPER :Toffee Hopper
+STR_804D_BUBBLE_VAN :Bubble Van
+STR_804E_COLA_TANKER :Cola Tanker
+STR_804F_CANDY_VAN :Sweets Van
+STR_8050_TOY_VAN :Toy Van
+STR_8051_BATTERY_TRUCK :Battery Truck
+STR_8052_FIZZY_DRINK_TRUCK :Fizzy Drink Truck
+STR_8053_PLASTIC_TRUCK :Plastic Truck
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (Electric)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (Electric)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (Electric)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (Electric)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :Passenger Car
+STR_805A_MAIL_VAN :Mail Van
+STR_805B_COAL_CAR :Coal Car
+STR_805C_OIL_TANKER :Oil Tanker
+STR_805D_LIVESTOCK_VAN :Livestock Van
+STR_805E_GOODS_VAN :Goods Van
+STR_805F_GRAIN_HOPPER :Grain Hopper
+STR_8060_WOOD_TRUCK :Wood Truck
+STR_8061_IRON_ORE_HOPPER :Iron Ore Hopper
+STR_8062_STEEL_TRUCK :Steel Truck
+STR_8063_ARMORED_VAN :Armored Van
+STR_8064_FOOD_VAN :Food Van
+STR_8065_PAPER_TRUCK :Paper Truck
+STR_8066_COPPER_ORE_HOPPER :Copper Ore Hopper
+STR_8067_WATER_TANKER :Water Tanker
+STR_8068_FRUIT_TRUCK :Fruit Truck
+STR_8069_RUBBER_TRUCK :Rubber Truck
+STR_806A_SUGAR_TRUCK :Sugar Truck
+STR_806B_COTTON_CANDY_HOPPER :Candyfloss Hopper
+STR_806C_TOFFEE_HOPPER :Toffee Hopper
+STR_806D_BUBBLE_VAN :Bubble Van
+STR_806E_COLA_TANKER :Cola Tanker
+STR_806F_CANDY_VAN :Sweets Van
+STR_8070_TOY_VAN :Toy Van
+STR_8071_BATTERY_TRUCK :Battery Truck
+STR_8072_FIZZY_DRINK_TRUCK :Fizzy Drink Truck
+STR_8073_PLASTIC_TRUCK :Plastic Truck
+STR_8074_MPS_REGAL_BUS :AEC Regal Bus
+STR_8075_HEREFORD_LEOPARD_BUS :Leyland Leopard Bus
+STR_8076_FOSTER_BUS :Volvo Bus
+STR_8077_FOSTER_MKII_SUPERBUS :Volvo MkII Superbus
+STR_8078_PLODDYPHUT_MKI_BUS :Ploddyphut MkI Bus
+STR_8079_PLODDYPHUT_MKII_BUS :Ploddyphut MkII Bus
+STR_807A_PLODDYPHUT_MKIII_BUS :Ploddyphut MkIII Bus
+STR_807B_BALOGH_COAL_TRUCK :Bedford Coal Lorry
+STR_807C_UHL_COAL_TRUCK :Ford Coal Lorry
+STR_807D_DW_COAL_TRUCK :DW Coal Lorry
+STR_807E_MPS_MAIL_TRUCK :AEC Mail Truck
+STR_807F_REYNARD_MAIL_TRUCK :Renault Mail Truck
+STR_8080_PERRY_MAIL_TRUCK :Perry Mail Truck
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :MightyMover Mail Truck
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Powernaught Mail Truck
+STR_8083_WIZZOWOW_MAIL_TRUCK :Wizzowow Mail Truck
+STR_8084_WITCOMBE_OIL_TANKER :Scammell Oil Tanker
+STR_8085_FOSTER_OIL_TANKER :Volvo Oil Tanker
+STR_8086_PERRY_OIL_TANKER :Perry Oil Tanker
+STR_8087_TALBOTT_LIVESTOCK_VAN :Dennis Livestock Van
+STR_8088_UHL_LIVESTOCK_VAN :Ford Livestock Van
+STR_8089_FOSTER_LIVESTOCK_VAN :Foster Livestock Van
+STR_808A_BALOGH_GOODS_TRUCK :Bedford Goods Lorry
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Fiat Goods Lorry
+STR_808C_GOSS_GOODS_TRUCK :Goss Goods Lorry
+STR_808D_HEREFORD_GRAIN_TRUCK :Leyland Grain Truck
+STR_808E_THOMAS_GRAIN_TRUCK :Peugeot Grain Truck
+STR_808F_GOSS_GRAIN_TRUCK :Goss Grain Truck
+STR_8090_WITCOMBE_WOOD_TRUCK :Scammell Wood Truck
+STR_8091_FOSTER_WOOD_TRUCK :Volvo Wood Truck
+STR_8092_MORELAND_WOOD_TRUCK :Moreland Wood Truck
+STR_8093_MPS_IRON_ORE_TRUCK :AEC Iron Ore Truck
+STR_8094_UHL_IRON_ORE_TRUCK :Ford Iron Ore Truck
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Chippy Iron Ore Truck
+STR_8096_BALOGH_STEEL_TRUCK :Bedford Steel Truck
+STR_8097_UHL_STEEL_TRUCK :Ford Steel Truck
+STR_8098_KELLING_STEEL_TRUCK :Kelling Steel Truck
+STR_8099_BALOGH_ARMORED_TRUCK :Bedford Armoured Truck
+STR_809A_UHL_ARMORED_TRUCK :Ford Armoured Truck
+STR_809B_FOSTER_ARMORED_TRUCK :Foster Armored Truck
+STR_809C_FOSTER_FOOD_VAN :Foster Food Van
+STR_809D_PERRY_FOOD_VAN :Perry Food Van
+STR_809E_CHIPPY_FOOD_VAN :Chippy Food Van
+STR_809F_UHL_PAPER_TRUCK :Uhl Paper Truck
+STR_80A0_BALOGH_PAPER_TRUCK :Balogh Paper Truck
+STR_80A1_MPS_PAPER_TRUCK :MPS Paper Truck
+STR_80A2_MPS_COPPER_ORE_TRUCK :MPS Copper Ore Truck
+STR_80A3_UHL_COPPER_ORE_TRUCK :Uhl Copper Ore Truck
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Goss Copper Ore Truck
+STR_80A5_UHL_WATER_TANKER :Uhl Water Tanker
+STR_80A6_BALOGH_WATER_TANKER :Balogh Water Tanker
+STR_80A7_MPS_WATER_TANKER :MPS Water Tanker
+STR_80A8_BALOGH_FRUIT_TRUCK :Balogh Fruit Truck
+STR_80A9_UHL_FRUIT_TRUCK :Uhl Fruit Truck
+STR_80AA_KELLING_FRUIT_TRUCK :Kelling Fruit Truck
+STR_80AB_BALOGH_RUBBER_TRUCK :Balogh Rubber Truck
+STR_80AC_UHL_RUBBER_TRUCK :Uhl Rubber Truck
+STR_80AD_RMT_RUBBER_TRUCK :RMT Rubber Truck
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :MightyMover Sugar Truck
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Powernaught Sugar Truck
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Wizzowow Sugar Truck
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :MightyMover Cola Truck
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Powernaught Cola Truck
+STR_80B3_WIZZOWOW_COLA_TRUCK :Wizzowow Cola Truck
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :MightyMover Candyfloss Truck
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Powernaught Candyfloss Truck
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Wizzowow Candyfloss Truck
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :MightyMover Toffee Truck
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Powernaught Toffee Truck
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Wizzowow Toffee Truck
+STR_80BA_MIGHTYMOVER_TOY_VAN :MightyMover Toy Van
+STR_80BB_POWERNAUGHT_TOY_VAN :Powernaught Toy Van
+STR_80BC_WIZZOWOW_TOY_VAN :Wizzowow Toy Van
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :MightyMover Sweet Lorry
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Powernaught Sweet Lorry
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Wizzowow Sweet Lorry
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :MightyMover Battery Truck
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Powernaught Battery Truck
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Wizzowow Battery Truck
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :MightyMover Fizzy Drink Truck
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Powernaught Fizzy Drink Truck
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Wizzowow Fizzy Drink Truck
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :MightyMover Plastic Truck
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Powernaught Plastic Truck
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Wizzowow Plastic Truck
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :MightyMover Bubble Truck
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Powernaught Bubble Truck
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Wizzowow Bubble Truck
+STR_80CC_MPS_OIL_TANKER :MPS Oil Tanker
+STR_80CD_CS_INC_OIL_TANKER :CS-Inc. Oil Tanker
+STR_80CE_MPS_PASSENGER_FERRY :MPS Passenger Ferry
+STR_80CF_FFP_PASSENGER_FERRY :FFP Passenger Ferry
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Bakewell 300 Hovercraft
+STR_80D1_CHUGGER_CHUG_PASSENGER :Chugger-Chug Passenger Ferry
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Shivershake Passenger Ferry
+STR_80D3_YATE_CARGO_SHIP :Yate Cargo ship
+STR_80D4_BAKEWELL_CARGO_SHIP :Bakewell Cargo ship
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Mightymover Cargo ship
+STR_80D6_POWERNAUT_CARGO_SHIP :Powernaut Cargo ship
+STR_80D7_SAMPSON_U52 :Junkers JU52
+STR_80D8_COLEMAN_COUNT :Vickers Viscount
+STR_80D9_FFP_DART :Aërospatiale SE-310 Caravelle
+STR_80DA_YATE_HAUGAN :BAC-Aërospatiale Concorde
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Douglas DC-3 Dakota
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :McDonnell Douglas DC-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :McDonnell Douglas DC-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :McDonnell Douglas MD80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :McDonnell Douglas DC-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :McDonnell Douglas MD-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :British Aerospace BAC 1-11
+STR_80E2_DARWIN_100 :Boeing 727
+STR_80E3_DARWIN_200 :Boeing 737
+STR_80E4_DARWIN_300 :Boeing 747
+STR_80E5_DARWIN_400 :Boeing 757
+STR_80E6_DARWIN_500 :Boeing 767
+STR_80E7_DARWIN_600 :Boeing 777
+STR_80E8_GURU_GALAXY :Lockheed Tristar
+STR_80E9_AIRTAXI_A21 :Airbus A300
+STR_80EA_AIRTAXI_A31 :Airbus A310
+STR_80EB_AIRTAXI_A32 :Airbus A320
+STR_80EC_AIRTAXI_A33 :Airbus A330
+STR_80ED_YATE_AEROSPACE_YAE46 :British Aerospace BAe46
+STR_80EE_DINGER_100 :Fokker 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Sikorsky Helicopter
+STR_80FE_GURU_X2_HELICOPTER :Guru X2 Helicopter
+STR_80FF_POWERNAUT_HELICOPTER :Powernaut Helicopter
diff --git a/src/lang/polish.txt b/src/lang/polish.txt
new file mode 100644
index 000000000..c5c919458
--- /dev/null
+++ b/src/lang/polish.txt
@@ -0,0 +1,3245 @@
+##name Polish
+##ownname Polski
+##isocode pl_PL.UTF-8
+##plural 7
+##case d c b n m w
+##gender m f n
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Poza krawędzią mapy
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Zbyt blisko krawędzi mapy
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Za mało pieniędzy - wymagane {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Wymagany płaski teren
+STR_0008_WAITING :{BLACK}Czeka: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (w drodze z
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Akceptuje: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Akceptuje: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :Pasażerowie
+STR_000F_PASSENGERS.d :pasażerów
+STR_0010_COAL :Węgiel
+STR_0010_COAL.d :węgla
+STR_0011_MAIL :Poczta
+STR_0011_MAIL.d :poczty
+STR_0012_OIL :Ropa
+STR_0012_OIL.d :ropy
+STR_0013_LIVESTOCK :Żywiec
+STR_0013_LIVESTOCK.d :żywca
+STR_0014_GOODS :Towary
+STR_0014_GOODS.d :towarów
+STR_0015_GRAIN :Zboże
+STR_0015_GRAIN.d :zboża
+STR_0016_WOOD :Drewno
+STR_0016_WOOD.d :drewna
+STR_0017_IRON_ORE :Ruda Żelaza
+STR_0017_IRON_ORE.d :rudy żelaza
+STR_0018_STEEL :Stal
+STR_0018_STEEL.d :stali
+STR_0019_VALUABLES :Kosztowności
+STR_0019_VALUABLES.d :kosztowności
+STR_001A_COPPER_ORE :Ruda Miedzi
+STR_001A_COPPER_ORE.d :rudy miedzi
+STR_001B_MAIZE :Kukurydza
+STR_001B_MAIZE.d :kukurydzy
+STR_001C_FRUIT :Owoce
+STR_001C_FRUIT.d :owoców
+STR_001D_DIAMONDS :Diamenty
+STR_001D_DIAMONDS.d :diamentów
+STR_001E_FOOD :Żywność
+STR_001E_FOOD.d :żywności
+STR_001F_PAPER :Papier
+STR_001F_PAPER.d :papieru
+STR_0020_GOLD :Iloto
+STR_0020_GOLD.d :złota
+STR_0021_WATER :Woda
+STR_0021_WATER.d :wody
+STR_0022_WHEAT :Pszenica
+STR_0022_WHEAT.d :pszenicy
+STR_0023_RUBBER :Kauczuk
+STR_0023_RUBBER.d :kauczuku
+STR_0024_SUGAR :Cukier
+STR_0024_SUGAR.d :cukru
+STR_0025_TOYS :Zabawki
+STR_0025_TOYS.d :zabawek
+STR_0026_CANDY :SÅ‚odycze
+STR_0026_CANDY.d :słodyczy
+STR_0027_COLA :Cola
+STR_0027_COLA.d :coli
+STR_0028_COTTON_CANDY :Wata cukrowa
+STR_0028_COTTON_CANDY.d :waty cukrowej
+STR_0029_BUBBLES :BÄ…belki
+STR_0029_BUBBLES.d :bąbelków
+STR_002A_TOFFEE :Toffi
+STR_002A_TOFFEE.d :toffi
+STR_002B_BATTERIES :Baterie
+STR_002B_BATTERIES.d :baterii
+STR_002C_PLASTIC :Plastik
+STR_002C_PLASTIC.d :plastiku
+STR_002D_FIZZY_DRINKS :Napoje gazowane
+STR_002D_FIZZY_DRINKS.d :napoi gazowanych
+STR_002E :
+STR_002F_PASSENGER :Pasażerowie
+STR_002F_PASSENGER.d :pasażerów
+STR_0030_COAL :Węgiel
+STR_0031_MAIL :Poczta
+STR_0032_OIL :Ropa
+STR_0033_LIVESTOCK :Żywiec
+STR_0034_GOODS :Towary
+STR_0035_GRAIN :Zboże
+STR_0036_WOOD :Drewno
+STR_0037_IRON_ORE :Ruda żelaza
+STR_0038_STEEL :Stal
+STR_0039_VALUABLES :Kosztowności
+STR_003A_COPPER_ORE :Ruda miedzi
+STR_003B_MAIZE :Kukurydza
+STR_003C_FRUIT :Owoce
+STR_003D_DIAMOND :Diamenty
+STR_003E_FOOD :Żywność
+STR_003F_PAPER :Papier
+STR_0040_GOLD :ZÅ‚oto
+STR_0041_WATER :Woda
+STR_0042_WHEAT :Pszenica
+STR_0043_RUBBER :Kauczuk
+STR_0043_RUBBER.d :kauczuku
+STR_0044_SUGAR :Cukier
+STR_0045_TOY :Zabawki
+STR_0045_TOY.d :zabawek
+STR_0046_CANDY :SÅ‚odycze
+STR_0046_CANDY.d :słodyczy
+STR_0047_COLA :Cola
+STR_0047_COLA.d :coli
+STR_0048_COTTON_CANDY :Wata Cukrowa
+STR_0048_COTTON_CANDY.d :waty cukrowej
+STR_0049_BUBBLE :Babelki
+STR_0049_BUBBLE.d :bąbelków
+STR_004A_TOFFEE :Toffi
+STR_004A_TOFFEE.d :toffi
+STR_004B_BATTERY :Baterie
+STR_004B_BATTERY.d :baterii
+STR_004C_PLASTIC :Plastik
+STR_004C_PLASTIC.d :plastiku
+STR_004D_FIZZY_DRINK :Napoje Gazowane
+STR_004D_FIZZY_DRINK.d :napoi gazowanych
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} pasażer{P "" ów ów}
+STR_QUANTITY_COAL :{WEIGHT} węgla
+STR_QUANTITY_MAIL :{COMMA} pacz{P ka ki ek} poczty
+STR_QUANTITY_OIL :{VOLUME} ropy
+STR_QUANTITY_LIVESTOCK :{COMMA} sztuk{P a i ""} żywca
+STR_QUANTITY_GOODS :{COMMA} towarów
+STR_QUANTITY_GRAIN :{WEIGHT} zboża
+STR_QUANTITY_WOOD :{WEIGHT} drewna
+STR_QUANTITY_IRON_ORE :{WEIGHT} rudy żelaza
+STR_QUANTITY_STEEL :{WEIGHT} stali
+STR_QUANTITY_VALUABLES :{COMMA} pacz{P ka ki ek} kosztowności
+STR_QUANTITY_COPPER_ORE :{WEIGHT} rudy miedzi
+STR_QUANTITY_MAIZE :{WEIGHT} kukurydzy
+STR_QUANTITY_FRUIT :{WEIGHT} owoców
+STR_QUANTITY_DIAMONDS :{COMMA} pacz{P ka ki ek} diamentów
+STR_QUANTITY_FOOD :{WEIGHT} żywności
+STR_QUANTITY_PAPER :{WEIGHT} papieru
+STR_QUANTITY_GOLD :{COMMA} pacz{P ka ki ek} złota
+STR_QUANTITY_WATER :{VOLUME} wody
+STR_QUANTITY_WHEAT :{WEIGHT} pszenicy
+STR_QUANTITY_RUBBER :{VOLUME} kauczuku
+STR_QUANTITY_SUGAR :{WEIGHT} cukru
+STR_QUANTITY_TOYS :{COMMA} zabaw{P ka ki ek}
+STR_QUANTITY_SWEETS :{COMMA} pacz{P ka ki ek} słodyczy
+STR_QUANTITY_COLA :{VOLUME} coli
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} waty cukrowej
+STR_QUANTITY_BUBBLES :{COMMA} bąbel{P ek ki ków}
+STR_QUANTITY_TOFFEE :{WEIGHT} Toffi
+STR_QUANTITY_BATTERIES :{COMMA} bateri{P a e i}
+STR_QUANTITY_PLASTIC :{VOLUME} plastiku
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} napo{P j je i} gazowan{P y e ych}
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}PS
+STR_ABBREV_COAL :{TINYFONT}CL
+STR_ABBREV_MAIL :{TINYFONT}ML
+STR_ABBREV_OIL :{TINYFONT}OL
+STR_ABBREV_LIVESTOCK :{TINYFONT}LV
+STR_ABBREV_GOODS :{TINYFONT}GD
+STR_ABBREV_GRAIN :{TINYFONT}GR
+STR_ABBREV_WOOD :{TINYFONT}WD
+STR_ABBREV_IRON_ORE :{TINYFONT}OR
+STR_ABBREV_STEEL :{TINYFONT}ST
+STR_ABBREV_VALUABLES :{TINYFONT}VL
+STR_ABBREV_COPPER_ORE :{TINYFONT}CO
+STR_ABBREV_MAIZE :{TINYFONT}MZ
+STR_ABBREV_FRUIT :{TINYFONT}FT
+STR_ABBREV_DIAMONDS :{TINYFONT}DM
+STR_ABBREV_FOOD :{TINYFONT}FD
+STR_ABBREV_PAPER :{TINYFONT}PR
+STR_ABBREV_GOLD :{TINYFONT}GD
+STR_ABBREV_WATER :{TINYFONT}WR
+STR_ABBREV_WHEAT :{TINYFONT}WH
+STR_ABBREV_RUBBER :{TINYFONT}RB
+STR_ABBREV_SUGAR :{TINYFONT}SG
+STR_ABBREV_TOYS :{TINYFONT}TY
+STR_ABBREV_SWEETS :{TINYFONT}SW
+STR_ABBREV_COLA :{TINYFONT}CL
+STR_ABBREV_CANDYFLOSS :{TINYFONT}CF
+STR_ABBREV_BUBBLES :{TINYFONT}BU
+STR_ABBREV_TOFFEE :{TINYFONT}TF
+STR_ABBREV_BATTERIES :{TINYFONT}BA
+STR_ABBREV_PLASTIC :{TINYFONT}PL
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}FZ
+STR_ABBREV_NONE :{TINYFONT}0
+STR_ABBREV_ALL :{TINYFONT}+
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Mapa - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Opcje Gry
+STR_00B2_MESSAGE :{YELLOW}Wiadomość
+STR_00B3_MESSAGE_FROM :{YELLOW}Wiadomość od {STRING}
+STR_POPUP_CAUTION_CAPTION :{WHITE}Uwaga!
+STR_00B4_CAN_T_DO_THIS :{WHITE}Nie można tego zrobić...
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Nie można wyczyścić terenu...
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Prawa Autorskie {COPYRIGHT} 1995 Chris Sawyer, Wszelkie Prawa Zastrzeżone
+STR_00B7_VERSION :{BLACK}OpenTTD wersja {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 Zespól OpenTTD
+STR_TRANSLATED_BY :{BLACK} TÅ‚umacz(e) - : Tom PolPot Spooqy MeusH
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Wyjście
+STR_00C8_YES :{BLACK}Tak
+STR_00C9_NO :{BLACK}Nie
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Jesteś pewien że chcesz zakończyć tę grę i wrócić do {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Nic
+STR_00D1_DARK_BLUE :Ciemnoniebieski
+STR_00D2_PALE_GREEN :Bladozielony
+STR_00D3_PINK :Różowy
+STR_00D4_YELLOW :Żółty
+STR_00D5_RED :Czerwony
+STR_00D6_LIGHT_BLUE :Jasnoniebieski
+STR_00D7_GREEN :Zielony
+STR_00D8_DARK_GREEN :Ciemnozielony
+STR_00D9_BLUE :Niebieski
+STR_00DA_CREAM :Kremowy
+STR_00DB_MAUVE :Fiołkowo różowy
+STR_00DC_PURPLE :Purpurowy
+STR_00DD_ORANGE :Pomarańczowy
+STR_00DE_BROWN :BrÄ…zowy
+STR_00DF_GREY :Szary
+STR_00E0_WHITE :Biały
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Za dużo pojazdów w grze
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Lokalizacja
+STR_00E5_CONTOURS :Ukształtowanie
+STR_00E6_VEHICLES :Pojazdy
+STR_00E7_INDUSTRIES :Przedsiębiorstwa
+STR_00E8_ROUTES :Trasy
+STR_00E9_VEGETATION :Roślinność
+STR_00EA_OWNERS :Właściciele
+STR_00EB_ROADS :{BLACK}{TINYFONT}Drogi
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Koleje
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Stacje/Lotniska/Porty
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Budynki/Przedsiębiorstwa
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Pojazdy
+STR_00F0_100M :{BLACK}{TINYFONT}100m
+STR_00F1_200M :{BLACK}{TINYFONT}200m
+STR_00F2_300M :{BLACK}{TINYFONT}300m
+STR_00F3_400M :{BLACK}{TINYFONT}400m
+STR_00F4_500M :{BLACK}{TINYFONT}500m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}PociÄ…gi
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Samochody
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Statki
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Samoloty
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Trasy transportowe
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}{G=f}Kopalnia węgla
+STR_00FA_COAL_MINE.d :{BLACK}{TINYFONT}{G=f}Kopalni węgla
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}{G=f}Elektrownia
+STR_00FB_POWER_STATION.d :{BLACK}{TINYFONT}{G=f}Elektrowni
+STR_00FC_FOREST :{BLACK}{TINYFONT}{G=m}Las
+STR_00FC_FOREST.d :{BLACK}{TINYFONT}{G=m}Lasu
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}{G=m}Tartak
+STR_00FD_SAWMILL.d :{BLACK}{TINYFONT}{G=m}Tartaku
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}{G=f}Rafineria
+STR_00FE_OIL_REFINERY.d :{BLACK}{TINYFONT}{G=f}Rafinerii
+STR_00FF_FARM :{BLACK}{TINYFONT}{G=f}Farma
+STR_00FF_FARM.d :{BLACK}{TINYFONT}{G=f}Farmy
+STR_0100_FACTORY :{BLACK}{TINYFONT}{G=f}Fabryka
+STR_0100_FACTORY.d :{BLACK}{TINYFONT}{G=f}Fabryki
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}{G=f}Drukarnia
+STR_0101_PRINTING_WORKS.d :{BLACK}{TINYFONT}{G=f}Drukarnii
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}{G=m}Pole naftowe
+STR_0102_OIL_WELLS.d :{BLACK}{TINYFONT}{G=m}Pola naftowego
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}{G=f}Kopalnia rudy żelaza
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}{G=f}Huta
+STR_0105_BANK :{BLACK}{TINYFONT}{G=m}Bank
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}{G=m}Zakłady papiernicze
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}{G=f}Kopalnia złota
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}{G=f}Przetwórnia jedzenia
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}{G=f}Kopalnia diamentów
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}{G=f}Kopalnia rudy miedzi
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}{G=f}Plantacja owoców
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}{G=f}Plantacja kauczuku
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}{G=n}Ujęcie wody
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}{G=f}Wieża ciśnień
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}{G=m}Tartak
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}{G=m}Las waty cukrowej
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}{G=m}Zakład cukierniczy
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}{G=f}Farma baterii
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}{G=f}Studnie coli
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}{G=m}Sklep z zabawkami
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}{G=f}Fabryka zabawek
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}{G=f}Fontanny plastiku
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}{G=f}Fabryka napojów gazowanych
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}{G=m}Generator bąbelków
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}{G=f}Odkrywka Toffi
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}{G=f}Kopalnia cukru
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Stacja kolejowa
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Załadunek ciężarówek
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Przystanek
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Lotnisko
+STR_011F_DOCK :{BLACK}{TINYFONT}Port
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Wyboisty teren
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Trawa
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Odsłonięta ziemia
+STR_0123_FIELDS :{BLACK}{TINYFONT}Pola
+STR_0124_TREES :{BLACK}{TINYFONT}Drzewa
+STR_0125_ROCKS :{BLACK}{TINYFONT}Skały
+STR_0126_WATER :{BLACK}{TINYFONT}Woda
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Brak właściciela
+STR_0128_TOWNS :{BLACK}{TINYFONT}Miasta
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Przedsiębiorstwa
+STR_012A_DESERT :{BLACK}{TINYFONT}Pustynia
+STR_012B_SNOW :{BLACK}{TINYFONT}Åšnieg
+STR_012C_MESSAGE :{WHITE}Wiadomość
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Anuluj
+STR_012F_OK :{BLACK}OK
+STR_0130_RENAME :{BLACK}Zmień nazwę
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Za dużo zdefiniowanych nazw
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Nazwa jest już używana
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...w posiadaniu {STRING}
+STR_013C_CARGO :{BLACK}Åadunek
+STR_013D_INFORMATION :{BLACK}Informacja
+STR_013E_CAPACITIES :{BLACK}Pojemność
+STR_013E_TOTAL_CARGO :{BLACK}Całkowity ładunek
+STR_013F_CAPACITY :{BLACK}Pojemność: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}Pojemność: {LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Calkowita pojemność tego pociągu:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}Nowa Gra
+STR_0141_LOAD_GAME :{BLACK}Wczytaj GrÄ™
+STR_SINGLE_PLAYER :{BLACK}Gra Jednoosobowa
+STR_MULTIPLAYER :{BLACK}Gra Wieloosobowa
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Rozmiar Mapy:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Opcje Gry
+
+STR_0150_SOMEONE :ktoÅ›{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Mapa świata
+STR_0152_TOWN_DIRECTORY :Lista miast
+STR_0153_SUBSIDIES :Subsydia
+
+STR_UNITS_IMPERIAL :Anglosaskie
+STR_UNITS_METRIC :Metryczne
+STR_UNITS_SI :SI
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} mph
+STR_UNITS_VELOCITY_METRIC :{COMMA} km/h
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}KM
+STR_UNITS_POWER_METRIC :{COMMA}KM
+STR_UNITS_POWER_SI :{COMMA}kW
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} ton{P a y ""}
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} ton{P a y ""}
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} kg
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}gal
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}l
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}m³
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} galon{P "" y ów}
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} litr{P "" y ów}
+STR_UNITS_VOLUME_LONG_SI :{COMMA} m³
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10³ lbf
+STR_UNITS_FORCE_METRIC :{COMMA} kilonewtony
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Wykres obrotu
+STR_0155_INCOME_GRAPH :Wykres przychodów
+STR_0156_DELIVERED_CARGO_GRAPH :Wykres przewożonego ładunku
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Ocena działalności firmy
+STR_0158_COMPANY_VALUE_GRAPH :Wykres wartości firmy
+STR_0159_CARGO_PAYMENT_RATES :Stawki za Å‚adunek
+STR_015A_COMPANY_LEAGUE_TABLE :Wykres Ligi Firm
+STR_PERFORMANCE_DETAIL_MENU :Szczegółowa tabela efektywności
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}OpenTTD
+STR_015C_SAVE_GAME :Zapisz grÄ™
+STR_015D_LOAD_GAME :Wczytaj grÄ™
+STR_015E_QUIT_GAME :Opuść grę
+STR_015F_QUIT :Wyjście
+STR_ABANDON_GAME_QUERY :{YELLOW}Jesteś pewien że chcesz skończyć grę?
+STR_0161_QUIT_GAME :{WHITE}Wyjście
+STR_SORT_ORDER_TIP :{BLACK}Wybierz porzÄ…dek sortowania (malejÄ…co/rosnÄ…co)
+STR_SORT_CRITERIA_TIP :{BLACK}Wybierz kryterium sortowania
+STR_SORT_BY :{BLACK}Sortuj wg
+
+STR_SORT_BY_POPULATION :{BLACK}Populacja
+STR_SORT_BY_PRODUCTION :{BLACK}Produkcja
+STR_SORT_BY_TYPE :{BLACK}Typ
+STR_SORT_BY_TRANSPORTED :{BLACK}Przetransportowano
+STR_SORT_BY_NAME :{BLACK}Nazwa
+STR_SORT_BY_DROPDOWN_NAME :Nazwa
+STR_SORT_BY_DATE :{BLACK}Data
+STR_SORT_BY_NUMBER :Numer
+STR_SORT_BY_PROFIT_LAST_YEAR :Zysk w ostatnim roku
+STR_SORT_BY_PROFIT_THIS_YEAR :Zysk w tym roku
+STR_SORT_BY_AGE :Wiek
+STR_SORT_BY_RELIABILITY :Niezawodność
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Całkowita pojemność typu towaru
+STR_SORT_BY_MAX_SPEED :Prędkość maks.
+STR_SORT_BY_MODEL :Model
+STR_SORT_BY_VALUE :Wartość
+STR_SORT_BY_FACILITY :Typ stacji
+STR_SORT_BY_WAITING :Wartość czekającego towaru
+STR_SORT_BY_RATING_MAX :Ocena towaru
+STR_ENGINE_SORT_ENGINE_ID :ID pojazdu
+STR_ENGINE_SORT_COST :Cena
+STR_ENGINE_SORT_POWER :Moc
+STR_ENGINE_SORT_INTRO_DATE :Data wprowadzenia
+STR_ENGINE_SORT_RUNNING_COST :Koszty użytkowania
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Moc/Koszty użytkowania
+STR_ENGINE_SORT_CARGO_CAPACITY :Pojemność
+STR_NO_WAITING_CARGO :{BLACK}Nie ma żadnego czekającego towaru
+STR_SELECT_ALL_FACILITIES :{BLACK}Zaznacz wszystkie typy stacji
+STR_SELECT_ALL_TYPES :{BLACK}Zaznacz wszystkie typy towaru (oraz brak czekajÄ…cego towaru)
+STR_AVAILABLE_ENGINES_TIP :{BLACK}Zobacz listę dostępnych wyglądów lokomotywy dla tego typu pojazdu
+STR_MANAGE_LIST :{BLACK}ZarzÄ…dzaj listÄ…
+STR_MANAGE_LIST_TIP :{BLACK}Wyślij instrukcje wszystkim pojazdom na tej liĹ›cie
+STR_REPLACE_VEHICLES :ZastÄ…p pojazdy
+STR_SEND_TRAIN_TO_DEPOT :Wyślij do Zajezdni
+STR_SEND_ROAD_VEHICLE_TO_DEPOT :Wyślij do Zajezdni
+STR_SEND_SHIP_TO_DEPOT :Wyślij do Stoczni
+STR_SEND_AIRCRAFT_TO_HANGAR :Wyślij do Hangaru
+STR_SEND_FOR_SERVICING :Wyślij do Serwisu
+
+############ range for months starts
+STR_0162_JAN :Sty
+STR_0163_FEB :Lut
+STR_0164_MAR :Mar
+STR_0165_APR :Kwi
+STR_0166_MAY :Maj
+STR_0167_JUN :Cze
+STR_0168_JUL :Lip
+STR_0169_AUG :Sie
+STR_016A_SEP :Wrz
+STR_016B_OCT :Paź
+STR_016C_NOV :Lis
+STR_016D_DEC :Gru
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Pauza
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Zapis gry, opuszczenie gry, wyjście
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Wyświetl listę stacji firmy
+STR_0174_DISPLAY_MAP :{BLACK}Wyświetl mapę
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Wyświetl mapę, listę miast
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Wyświetl listę miast
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Wyświetl informacje finansowe firmy
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Wyświetl informacje ogólne firmy
+STR_0179_DISPLAY_GRAPHS :{BLACK}Wyświetl wykresy
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Wyświetl tabele firm
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Wyświetl listę pociągów firmy
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Wyświetl listę samochodów firmy
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Wyświetl listę statków firmy
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Wyświetl listę samolotów firmy
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Przybliżenie
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Oddalenie
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Budowa torów kolejowych
+STR_0182_BUILD_ROADS :{BLACK}Budowa dróg
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Budowa portów
+STR_0184_BUILD_AIRPORTS :{BLACK}Budowa lotnisk
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Umieść drzewa, napisy, itp.
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Informacje o terenie
+STR_0187_OPTIONS :{BLACK}Opcje
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Nie można zmienić okresu między serwisowaniem...
+STR_018B_CLOSE_WINDOW :{BLACK}Zamknięcie okna
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Tytuł okna - przeciągnij aby przesunąć okno
+STR_STICKY_BUTTON :{BLACK}Zaznacza to okno jako niezamykane dla funkcji 'Zamknij wszystkie okna'
+STR_RESIZE_BUTTON :{BLACK}Kliknij i przeciągnij by zmienić rozmiar okna
+STR_SAVELOAD_HOME_BUTTON :{BLACK}Kliknij tutaj aby przejść do domyślnego katalogu
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Niszczenie budynków itp. w danym kwadracie terenu
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Obniżenie narożnika terenu
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Podwyższenie narożnika terenu
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Suwak - przesuwa listę w górę i w dół
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Pasek przewijania - przewija listÄ™ prawo/lewo
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Pokaż zarysy lądu na mapie
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Pokaż pojazdy na mapie
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Pokaż przedsiębiorstwa na mapie
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Pokaż drogi na mapie
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Pokaż roślinność na mapie
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Pokaż teren mający właściciela
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Pokaż nazwy miast na mapie
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Zysk w tym roku: {CURRENCY} (ostatni rok: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} {P rok lata lat} ({COMMA})
+STR_AGE_RED :{RED}{COMMA} {P rok lata lat} ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Samochód
+STR_019D_AIRCRAFT :Samolot
+STR_019E_SHIP :Statek
+STR_019F_TRAIN :PociÄ…g
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} jest stary
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} jest bardzo stary
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} jest bardzo stary i natychmiast wymaga wymiany
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Informacja o terenie
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Koszt czyszczenia: {LTBLUE}N/D
+STR_01A5_COST_TO_CLEAR :{BLACK}Koszt czyszczenia: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :Brak
+STR_01A7_OWNER :{BLACK}Właściciel: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Lokalne władze: {LTBLUE}{STRING}
+STR_01A9_NONE :Brak
+STR_01AA_NAME :{BLACK}Nazwa
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1szy
+STR_01AD_2ND :2gi
+STR_01AE_3RD :3ci
+STR_01AF_4TH :4ty
+STR_01B0_5TH :5ty
+STR_01B1_6TH :6ty
+STR_01B2_7TH :7my
+STR_01B3_8TH :8my
+STR_01B4_9TH :9ty
+STR_01B5_10TH :10ty
+STR_01B6_11TH :11ty
+STR_01B7_12TH :12ty
+STR_01B8_13TH :13ty
+STR_01B9_14TH :14ty
+STR_01BA_15TH :15ty
+STR_01BB_16TH :16ty
+STR_01BC_17TH :17ty
+STR_01BD_18TH :18ty
+STR_01BE_19TH :19ty
+STR_01BF_20TH :20ty
+STR_01C0_21ST :21szy
+STR_01C1_22ND :22gi
+STR_01C2_23RD :23ci
+STR_01C3_24TH :24ty
+STR_01C4_25TH :25ty
+STR_01C5_26TH :26ty
+STR_01C6_27TH :27my
+STR_01C7_28TH :28my
+STR_01C8_29TH :29ty
+STR_01C9_30TH :30ty
+STR_01CA_31ST :31szy
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Akceptowany Å‚adunek: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Jazz Jukebox
+STR_01D3_SOUND_MUSIC :Dźwięk/muzyka
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Pokaż okno dźwięk/muzyka
+STR_01D5_ALL :{TINYFONT}Wszystko
+STR_01D6_OLD_STYLE :{TINYFONT}Stary styl
+STR_01D7_NEW_STYLE :{TINYFONT}Nowy styl
+STR_01D8_EZY_STREET :{TINYFONT}Ezy Street
+STR_01D9_CUSTOM_1 :{TINYFONT}WÅ‚asny 1
+STR_01DA_CUSTOM_2 :{TINYFONT}WÅ‚asny 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Głośność muzyki
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Głośność efektów
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MIN ' ' ' ' ' ' MAX
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Przejdź do następnej ścieżki
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Przejdź do następnej ścieżki
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Zatrzymaj muzykÄ™
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Odgrywaj muzykÄ™
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Przesuń suwaki żeby ustawić głośność dźwięków i muzyki
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Ścieżka{SETX 88}Tytuł
+STR_01E9_SHUFFLE :{TINYFONT}Przypadkowo
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Program
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Wybór Programu
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Wykaz ścieżek
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Programuj - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}Wyczyść
+STR_01F1_SAVE :{TINYFONT}{BLACK}Zapisz
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Obecny program ścieżek
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Wybierz program 'Wszystko'
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Wybierz program 'Stary styl'
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Wybierz program 'Nowy styl'
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Wybierz program 'WÅ‚asny 1' (definiowany)
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Wybierz program 'WÅ‚asny 2' (definiowany)
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Wyczyść obecny program (tylko Wlasny1 lub Wlasny2)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Zapisz ustawienia muzyki
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Klik na ścieżce aby dodać do obecnego programu (Wlasny1 i Wlasny2)
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Kliknij na ścieżce muzycznej aby usunąć ją z wybranego programu (Wlasny1 lub Wlasny2)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Przełącz losowe odtwarzanie wł./wył.
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Pokaż okno wyboru ścieżek
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Klik na usłudze żeby wyśrodkować widok na Fabrykę/Miasto
+STR_01FE_DIFFICULTY :{BLACK}Trudność ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Ostatnia wiadomość/ogłoszenie
+STR_0201_MESSAGE_SETTINGS :Ustawienia wiadomości
+STR_MESSAGE_HISTORY_MENU :Poprzednie wiadomości
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Pokaż ostatnią wiadomość/ogłoszenie, pokaż ustawienia wiadomości
+STR_0204_MESSAGE_OPTIONS :{WHITE}Opcje wiadomości
+STR_0205_MESSAGE_TYPES :{BLACK}Typy wiadomości:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Przybycie pierwszego pojazdu do stacji gracza
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Przybycie pierwszego pojazdu do stacji przeciwnika
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Wypadki / klęski
+STR_0209_COMPANY_INFORMATION :{YELLOW}Informacja firmy
+STR_020A_ECONOMY_CHANGES :{YELLOW}Zmiany ekonomiczne
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Porady / informacje o pojazdach gracza
+STR_020C_NEW_VEHICLES :{YELLOW}Nowe pojazdy
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Zamiany w akceptowaniu Å‚adunku
+STR_020E_SUBSIDIES :{YELLOW}Subsydia
+STR_020F_GENERAL_INFORMATION :{YELLOW}Ogólne informacje
+STR_MESSAGES_ALL :{YELLOW}Ustaw wszystkie typy wiadomości: Wyl / Sumaryczne / Pełne
+STR_MESSAGE_SOUND :{YELLOW}Graj dźwięki przy sumarycznych wiadomościach
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...zbyt daleko od poprzedniego celu
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Ranking firm, które osiągnęły rok {NUM}{}(Poziom {STRING})
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Tabela Ligi Firm w {NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Biznesmen
+STR_0214_ENTREPRENEUR :Przedsiębiorca
+STR_0215_INDUSTRIALIST :Przemysłowiec
+STR_0216_CAPITALIST :Kapitalista
+STR_0217_MAGNATE :Magnat
+STR_0218_MOGUL :Potentat
+STR_0219_TYCOON_OF_THE_CENTURY :Tycoon Stulecia
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} osiÄ…ga status: '{STRING}'!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} z {COMPANY} osiągnęło status '{STRING}'!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Tworzenie Scenariusza
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Edytor Scenariuszy
+STR_0223_LAND_GENERATION :{WHITE}Tworzenie terenu
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Przypadkowy lÄ…d
+STR_0227_RESET_LAND :{BLACK}Kasowanie lÄ…du
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Zwiększ powierzchnie do podwyższenia/obniżenia
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Zmniejsz powierzchnie do podwyższenia/obniżenia
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Tworzenie przypadkowego lÄ…du
+STR_022B_RESET_LANDSCAPE :{BLACK}Resetuj krajobraz
+STR_022C_RESET_LANDSCAPE :{WHITE}Resetuj krajobraz
+STR_LOAD_GAME_HEIGHTMAP :{WHITE}Użyj mapy wysokości
+STR_LOAD_SCEN_HEIGHTMAP :{BLACK}Użyj mapy wysokości
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Jesteś pewien że chcesz zrestartować krajobraz?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Tworzenie krajobrazu
+STR_022F_TOWN_GENERATION :{BLACK}Tworzenie miast
+STR_0230_INDUSTRY_GENERATION :{BLACK}Tworzenie przedsiębiorstw
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Konstrukcja dróg
+STR_0233_TOWN_GENERATION :{WHITE}Tworzenie miast
+STR_0234_NEW_TOWN :{BLACK}Nowe miasto
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Zbuduj nowe miasto
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Nie można tutaj zbudować miasta...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...zbyt blisko krawędzi mapy
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...zbyt blisko innego miasta
+STR_0239_SITE_UNSUITABLE :{WHITE}...niewłaściwa parcela
+STR_023A_TOO_MANY_TOWNS :{WHITE}...zbyt wiele miast
+STR_CANNOT_GENERATE_TOWN :{WHITE}Nie można wybudować żadnego miasta
+STR_NO_SPACE_FOR_TOWN :{WHITE}...nie ma więcej miejsca na mapie
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Zwiększ rozmiar miasta
+STR_023C_EXPAND :{BLACK}Rozszerz
+STR_023D_RANDOM_TOWN :{BLACK}Dowolne miasto
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Budowanie miasta w losowym miejscu
+STR_023F_INDUSTRY_GENERATION :{WHITE}Tworzenie przedsiębiorstw
+STR_0240_COAL_MINE :{BLACK}{G=f}Kopalnia Węgla
+STR_0240_COAL_MINE.d :{BLACK}{G=f}kopalni węgla
+STR_0241_POWER_STATION :{BLACK}{G=f}Elektrownia
+STR_0241_POWER_STATION.d :{BLACK}{G=f}elektrowni
+STR_0242_SAWMILL :{BLACK}{G=m}Tartak
+STR_0242_SAWMILL.d :{BLACK}{G=m}tartaku
+STR_0243_FOREST :{BLACK}{G=m}Las
+STR_0243_FOREST.d :{BLACK}{G=m}lasu
+STR_0244_OIL_REFINERY :{BLACK}{G=f}Rafineria
+STR_0244_OIL_REFINERY.d :{BLACK}{G=f}rafinerii
+STR_0245_OIL_RIG :{BLACK}{G=f}Platforma Wiertnicza
+STR_0245_OIL_RIG.d :{BLACK}{G=f}platformy wiertniczej
+STR_0246_FACTORY :{BLACK}{G=f}Fabryka
+STR_0246_FACTORY.d :{BLACK}{G=f}fabryki
+STR_0247_STEEL_MILL :{BLACK}{G=f}Huta
+STR_0247_STEEL_MILL.d :{BLACK}{G=f}huty
+STR_0248_FARM :{BLACK}{G=f}Farma
+STR_0248_FARM.d :{BLACK}{G=f}farmy
+STR_0249_IRON_ORE_MINE :{BLACK}{G=f}Kopalnia Rudy Żelaza
+STR_0249_IRON_ORE_MINE.d :{BLACK}{G=f}kopalni rudy żelaza
+STR_024A_OIL_WELLS :{BLACK}{G=m}Pole Naftowe
+STR_024A_OIL_WELLS.d :{BLACK}{G=m}pola naftowego
+STR_024B_BANK :{BLACK}{G=m}Bank
+STR_024B_BANK.d :{BLACK}{G=m}banku
+STR_024C_PAPER_MILL :{BLACK}{G=m}Zakłady Papiernicze
+STR_024C_PAPER_MILL.d :{BLACK}{G=m}zakładów papierniczych
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}{G=f}Przetwórnia Żywności
+STR_024D_FOOD_PROCESSING_PLANT.d :{BLACK}{G=f}przetwórni żywności
+STR_024E_PRINTING_WORKS :{BLACK}{G=f}Drukarnia
+STR_024E_PRINTING_WORKS.d :{BLACK}{G=f}drukarni
+STR_024F_GOLD_MINE :{BLACK}{G=f}Kopalnia ZÅ‚ota
+STR_024F_GOLD_MINE.d :{BLACK}{G=f}kopalni złota
+STR_0250_LUMBER_MILL :{BLACK}{G=m}Tartak
+STR_0250_LUMBER_MILL.d :{BLACK}{G=m}tartaku
+STR_0251_FRUIT_PLANTATION :{BLACK}{G=f}Plantacja owoców
+STR_0251_FRUIT_PLANTATION.d :{BLACK}{G=f}plantacji owoców
+STR_0252_RUBBER_PLANTATION :{BLACK}{G=f}Plantacja Kauczuku
+STR_0252_RUBBER_PLANTATION.d :{BLACK}{G=f}plantacji kauczuku
+STR_0253_WATER_SUPPLY :{BLACK}{G=n}Ujęcie Wody
+STR_0253_WATER_SUPPLY.d :{BLACK}{G=n}ujęcia wody
+STR_0254_WATER_TOWER :{BLACK}{G=f}Wieża Ciśnień
+STR_0254_WATER_TOWER.d :{BLACK}{G=f}wieży ciśnień
+STR_0255_DIAMOND_MINE :{BLACK}{G=f}Kopalnia Diamentów
+STR_0255_DIAMOND_MINE.d :{BLACK}{G=f}kopalni diamentów
+STR_0256_COPPER_ORE_MINE :{BLACK}{G=f}Kopalnia Rudy Miedzi
+STR_0256_COPPER_ORE_MINE.d :{BLACK}{G=f}kopalni rudy miedzi
+STR_0257_COTTON_CANDY_FOREST :{BLACK}{G=m}Las Waty Cukrowej
+STR_0257_COTTON_CANDY_FOREST.d :{BLACK}{G=m}lasu waty cukrowej
+STR_0258_CANDY_FACTORY :{BLACK}{G=m}Zakład Cukierniczy
+STR_0258_CANDY_FACTORY.d :{BLACK}{G=m}zakładu cukierniczego
+STR_0259_BATTERY_FARM :{BLACK}{G=f}Farma Baterii
+STR_0259_BATTERY_FARM.d :{BLACK}{G=f}farmy baterii
+STR_025A_COLA_WELLS :{BLACK}{G=f}Studnie Coli
+STR_025A_COLA_WELLS.d :{BLACK}{G=f}studni coli
+STR_025B_TOY_SHOP :{BLACK}{G=m}Sklep z zabawkami
+STR_025B_TOY_SHOP.d :{BLACK}{G=m}sklepu z zabawkami
+STR_025C_TOY_FACTORY :{BLACK}{G=f}Fabryka Zabawek
+STR_025C_TOY_FACTORY.d :{BLACK}{G=f}fabryki zabawek
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}{G=f}Fontanny Plastiku
+STR_025D_PLASTIC_FOUNTAINS.d :{BLACK}{G=f}fontann plastiku
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}{G=f}Fabryka Napojów Gazowanych
+STR_025E_FIZZY_DRINK_FACTORY.d :{BLACK}{G=f}fabryki napojów gazowanych
+STR_025F_BUBBLE_GENERATOR :{BLACK}{G=m}Generator Bąbelków
+STR_025F_BUBBLE_GENERATOR.d :{BLACK}{G=m}generatora bąbelków
+STR_0260_TOFFEE_QUARRY :{BLACK}{G=f}Odkrywka Toffi
+STR_0260_TOFFEE_QUARRY.d :{BLACK}{G=f}odkrywki toffi
+STR_0261_SUGAR_MINE :{BLACK}{G=f}Kopalnia Cukru
+STR_0261_SUGAR_MINE.d :{BLACK}{G=f}kopalni cukru
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Zbuduj Kopalnię Węgla
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Zbuduj Elektrownie
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Zbuduj Tartak
+STR_0265_PLANT_FOREST :{BLACK}Posadź Las
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Zbuduj Rafinerie
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Zbuduj Platformę Wiertniczą (Można zbudowac tylko przy krawedzi mapy)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Zbuduj FabrykÄ™
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Zbuduj HutÄ™
+STR_026A_CONSTRUCT_FARM :{BLACK}Zbuduj FarmÄ™
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Zbuduj Kopalnię Rudy Żelaza
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Zbuduj Pole naftowe
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Zbuduj Bank (Można zbudować tylko w miastach z populacją wiekszą niż 1200)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Zbuduj Zakłady Papiernicze
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Zbuduj Przetwórnię Żywności
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Zbuduj DrukarniÄ™
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Zbuduj KopalniÄ™ ZÅ‚ota
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Zbuduj Bank (Można zbudować tylko w miastach)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Zbuduj Tartak (aby ścinać las deszczowy i wyprodukować drewno)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Posadź Plantację Owoców
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Posadź Plantację kauczuku
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Zbuduj Ujęcie wody
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Zbuduj Wieżę Ciśnień (Można zbudować tylko w miastach)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Zbuduj Kopalnię Diamentów
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Zbuduj KopalniÄ™ Rudy Miedzi
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Posadź Las Waty Cukrowej
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Zbuduj CukierniÄ™
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Zbuduj FarmÄ™ Baterii
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Zbuduj Studnie Coli
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Zbuduj Sklep z zabawkami
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Zbuduj FabrykÄ™ Zabawek
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Zbuduj Fontanny Plastiku
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Zbuduj Fabrykę Napojów Gazowanych
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Zbuduj Generator Bąbelków
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Zbuduj OdkrywkÄ™ Toffi
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Zbuduj KopalniÄ™ cukru
+STR_0285_CAN_T_BUILD_HERE :{WHITE}Nie można tutaj wybudować: {STRING}...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...najpierw trzeba wybudować miasto
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...dozwolone jedno na miasto
+STR_0288_PLANT_TREES :{BLACK}Posadź drzewa
+STR_0289_PLACE_SIGN :{BLACK}Umieść napis
+STR_028A_RANDOM_TREES :{BLACK}Dowolne drzewa
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Pokryj krajobraz losowymi drzewami
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Umieść kamieniste tereny
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Umieść latarnię morską
+STR_028E_PLACE_TRANSMITTER :{BLACK}Umieść nadajnik
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Definiuj obszar pustyni.{}Wciśnij i trzymaj CTRL by usunąć
+STR_CREATE_LAKE :{BLACK}Definiuj akwen wodny.{}Okolice będą zalane jeśli są na poziomie morza
+STR_0290_DELETE :{BLACK}Skasuj
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Skasuj to miasto
+STR_0292_SAVE_SCENARIO :Zapisz scenariusz
+STR_0293_LOAD_SCENARIO :Wczytaj scenariusz
+STR_0294_QUIT_EDITOR :Wyjdź z edytora
+STR_0295 :
+STR_0296_QUIT :Wyjście
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Zapis scenariusza, wczytanie scenariusza, wyjście z edytora, wyjście
+STR_0298_LOAD_SCENARIO :{WHITE}Wczytaj Scenariusz
+STR_0299_SAVE_SCENARIO :{WHITE}Zapisz scenariusz
+STR_029A_PLAY_SCENARIO :{BLACK}Zagraj Scenariusz
+STR_PLAY_HEIGHTMAP :{BLACK}Zagraj z mapy wysokości
+STR_PLAY_HEIGHTMAP_HINT :{BLACK}Rozpocznij nowa grę używając mapy wysokości jako krajobrazu
+STR_QUIT_SCENARIO_QUERY :{YELLOW}Jesteś pewien że chcesz opuścić scenariusz?
+STR_029C_QUIT_EDITOR :{WHITE}Wyjście z edytora
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...można zbudować jedynie w miastach o populacji przynajmniej 1200
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Zmień datę początkową do tyłu o 1 rok
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Zmień datę początkawą do przodu o 1 rok
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...końce mostu muszą znajdować się na lądzie
+STR_02A1_SMALL :{BLACK}Male
+STR_02A2_MEDIUM :{BLACK}Åšrednie
+STR_02A3_LARGE :{BLACK}Duże
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Wybierz wielkość miasta
+STR_02A5_TOWN_SIZE :{YELLOW}Wielkość miasta:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Pokaż ostatnią wiadomość lub ogłoszenie
+STR_OFF :Wyłączone
+STR_SUMMARY :Sumaryczne
+STR_FULL :Pełne
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Lista miast
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Nazwy pojazdów
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Domyślne
+STR_02BF_CUSTOM :WÅ‚asne
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Zapisz własne nazwy
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Wybór nazw pojazdów
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Zapisz niestandardowe nazwy pojazdów na dysk
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Opcje gry
+STR_02C5_DIFFICULTY_SETTINGS :Ustawienia trudności
+STR_02C7_CONFIG_PATCHES :Konfiguracja wtyczek
+STR_NEWGRF_SETTINGS :Ustawienia newgrf
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Wyświetlanie nazw miast
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Wyświetlanie nazw stacji
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Wyświetlanie znaków
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Wyświetlanie punktów kontrolnych
+STR_02D0_FULL_ANIMATION :{SETX 12}Pełna animacja
+STR_02D2_FULL_DETAIL :{SETX 12}Wszystkie detale
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Przezroczyste budynki
+STR_TRANSPARENT_SIGNS :{SETX 12}Przezroczyste nazwy stacji
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Info o terenie
+STR_02D6 :
+STR_CONSOLE_SETTING :Przełącz konsolę
+STR_02D7_SCREENSHOT_CTRL_S :Zrzut ekranu (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Gigantyczny zrzut(Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :Info o 'OpenTTD'
+############ range ends here
+
+STR_02DB_OFF :{BLACK}Wył.
+STR_02DA_ON :{BLACK}WÅ‚.
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Wyświetl subsydia
+STR_02DD_SUBSIDIES :Subsydia
+STR_02DE_MAP_OF_WORLD :Mapa świata
+STR_EXTRA_VIEW_PORT :Dodatkowy podglÄ…d
+STR_SIGN_LIST :Lista tablic
+STR_02DF_TOWN_DIRECTORY :Lista miast
+STR_TOWN_POPULATION :{BLACK}Populacja świata: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}PodglÄ…d {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Kopiuj do podglÄ…du
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Kopiuj obecna pozycje z głównego okna do podglądu
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Wstaw z podglÄ…du
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Ustawia okno główne na pozycje z podglądu
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Waluta
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Wybór waluty
+STR_MEASURING_UNITS :{BLACK}Jednostki miar
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Wybór jednostek miar
+STR_02E6_ROAD_VEHICLES :{BLACK}Pojazdy drogowe
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Wybierz stronę po której mają jeździć samochody
+STR_02E9_DRIVE_ON_LEFT :Jazda po lewej
+STR_02EA_DRIVE_ON_RIGHT :Jazda po prawej
+STR_02EB_TOWN_NAMES :{BLACK}Nazwy miast
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Wybierz styl nazw miast
+
+STR_02F4_AUTOSAVE :{BLACK}Autozapis
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Wybierz przerwy pomiędzy autozapisami
+STR_02F7_OFF :Wył.
+STR_02F8_EVERY_3_MONTHS :Co 3 miesiÄ…ce
+STR_02F9_EVERY_6_MONTHS :Co 6 miesięcy
+STR_02FA_EVERY_12_MONTHS :Co 12 miesięcy
+STR_02FB_START_A_NEW_GAME :{BLACK}Rozpocznij nowÄ… grÄ™
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Wczytaj zapisanÄ… grÄ™
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Stwórz własny świat/scenariusz
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Wybór jednego gracza
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Wybierz grÄ™ wieloosobowÄ… dla 2-8 graczy
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Wyświetl opcje gry
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Wyświetl ustawienia trudności
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Rozpocznij grę używając własnego scenariusza
+STR_0304_QUIT :{BLACK}Wyjście
+STR_0305_QUIT_OPENTTD :{BLACK}Wyjdź z 'OpenTTD'
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...może być wybudowane tylko w mieście
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Wybierz krajobraz 'Umiarkowany'
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Wybierz krajobraz 'Arktyczny'
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Wybierz krajobraz 'Tropikalny'
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Wybierz krajobraz 'Zabawkowy'
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Ufunduj budowę nowego przedsiębiorstwa
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Katalog przedsiębiorstw
+STR_0313_FUND_NEW_INDUSTRY :Ufunduj nowe przedsięb.
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Ufunduj nowe przedsięb.
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...może być wybudowane tylko w mieście
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...może być wybudowane tylko w lasach deszczowych
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...może być wybudowane tylko na pustyni
+STR_0319_PAUSED :{YELLOW}* * PAUZA * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Zrzut ekranu zapisany na dysk z powodzeniem {STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}BÅ‚Ä…d zrzutu ekranu!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Nabyj teren do przyszłego użycia
+STR_032F_AUTOSAVE :{RED}AUTOZAPIS
+STR_SAVING_GAME :{RED}* * ZAPISYWANIE GRY * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}Zapisywanie trwa,{}proszę zaczekać do zakończenia!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Wybierz program 'Ezy Street'
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :Angielskie (Oryginalne)
+STR_TOWNNAME_FRENCH :Francuskie
+STR_TOWNNAME_GERMAN :Niemieckie
+STR_TOWNNAME_ADDITIONAL_ENGLISH :Angielskie (Rozszerzone)
+STR_TOWNNAME_LATIN_AMERICAN :Południowoamerykańskie
+STR_TOWNNAME_SILLY :Åšmieszne
+STR_TOWNNAME_SWEDISH :Szwedzkie
+STR_TOWNNAME_DUTCH :Holenderskie
+STR_TOWNNAME_FINNISH :Fińskie
+STR_TOWNNAME_POLISH :Polskie
+STR_TOWNNAME_SLOVAKISH :SÅ‚owackie
+STR_TOWNNAME_NORWEGIAN :Norweskie
+STR_TOWNNAME_HUNGARIAN :Węgierskie
+STR_TOWNNAME_AUSTRIAN :Austriackie
+STR_TOWNNAME_ROMANIAN :Rumuńskie
+STR_TOWNNAME_CZECH :Czeskie
+STR_TOWNNAME_SWISS :Szwajcarskie
+STR_TOWNNAME_DANISH :Duńskie
+STR_TOWNNAME_TURKISH :Tureckie
+STR_TOWNNAME_ITALIAN :WÅ‚oskie
+STR_TOWNNAME_CATALAN :Katalońskie
+############ end of townname region
+
+STR_CURR_GBP :Funty (ÂÅ)
+STR_CURR_USD :Dolar ($)
+STR_CURR_EUR :Euro (€)
+STR_CURR_YEN :Jeny (ÂĄ)
+STR_CURR_ATS :Szyling austriacki (ATS)
+STR_CURR_BEF :Frank belgijski (BEF)
+STR_CURR_CHF :Frank szwajcarski (CHF)
+STR_CURR_CZK :Korona czeska (CZK)
+STR_CURR_DEM :Marki niemieckie (DEM)
+STR_CURR_DKK :Korona duńska (DKK)
+STR_CURR_ESP :Peseta hiszpanska (ESP)
+STR_CURR_FIM :Marka fińska (FIM)
+STR_CURR_FRF :Frank francuski (FRF)
+STR_CURR_GRD :Drachma grecka (GRD)
+STR_CURR_HUF :Forint wegierski (HUF)
+STR_CURR_ISK :Korona islandzcka (ISK)
+STR_CURR_ITL :Lira włoska (ITL)
+STR_CURR_NLG :Gulden holenderski (NLG)
+STR_CURR_NOK :Korona norweska (NOK)
+STR_CURR_PLN :ZÅ‚oty polski (PLN)
+STR_CURR_ROL :Lewy rumuńskie (ROL)
+STR_CURR_RUR :Rubel rosyjski (RUR)
+STR_CURR_SIT :Tolar słowenski (SIT)
+STR_CURR_SEK :Korona szwedzka (SEK)
+STR_CURR_YTL :Lira turecka (YTL)
+STR_CURR_SKK :Korona słowacka (SKK)
+STR_CURR_BRR :Real brazylijski (BRL)
+
+STR_CURR_CUSTOM :Wlasna...
+
+STR_OPTIONS_LANG :{BLACK}Język
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Wybierz język interfejsu
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Pełny ekran
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}Zaznacz to jeśli chcesz grać w OpenTTD w trybie pełnoekranowym
+
+STR_OPTIONS_RES :{BLACK}Rozdzielczość ekranu
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Wybierz rozdzielczość ekranu
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Format zrzutu ekranu
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Wybierz format zrzutu ekranu
+
+STR_AUTOSAVE_1_MONTH :Co 1 miesiÄ…c
+STR_AUTOSAVE_FAILED :{WHITE}BÅ‚Ä…d autozapisu
+
+STR_MONTH_JAN :Styczeń
+STR_MONTH_FEB :Luty
+STR_MONTH_MAR :Marzec
+STR_MONTH_APR :Kwiecień
+STR_MONTH_MAY :Maj
+STR_MONTH_JUN :Czerwiec
+STR_MONTH_JUL :Lipiec
+STR_MONTH_AUG :Sierpień
+STR_MONTH_SEP :Wrzesień
+STR_MONTH_OCT :Październik
+STR_MONTH_NOV :Listopad
+STR_MONTH_DEC :Grudzień
+
+STR_HEADING_FOR_STATION :{LTBLUE}Zmierza do {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}Zmierza do {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Bez poleceń
+STR_NO_ORDERS_VEL :{LTBLUE}Bez poleceń, {VELOCITY}
+
+STR_PASSENGERS :pasażerów
+STR_BAGS :worków
+STR_TONS :ton
+STR_LITERS :litrów
+STR_ITEMS :sztuk
+STR_CRATES :skrzyń
+STR_RES_OTHER :inna
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Nie można współdzielić poleceń...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Nie można skopiować listy poleceń...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - Koniec współdzielonych poleceń - -
+
+STR_TRAIN_IS_LOST :{WHITE}Pociąg {COMMA} zabłądził.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}Pociąg {COMMA} zarobił w zeszłym roku {CURRENCY}
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}Europejska Unia Monetarna!{}{}Euro zostało wprowadzone jako jedyna waluta do wszystkich transakcji w twoim kraju!
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Pociąg {COMMA} ma za mało poleceń w rozkładzie
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}PociÄ…g {COMMA} ma puste polecenie
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}PociÄ…g {COMMA} ma zduplikowane polecenia
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}Pociąg {COMMA} ma nieodpowiednią stację w rozkładzie
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}Samochód {COMMA} ma za mało poleceń w rozkładzie
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}Samochód {COMMA} ma puste polecenie
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}Samochód {COMMA} ma zduplikowane polecenia
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}Samochód {COMMA} ma nieodpowiednią stację w rozkładzie
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}Statek {COMMA} ma za mało poleceń w rozkładzie
+STR_SHIP_HAS_VOID_ORDER :{WHITE}Statek {COMMA} ma puste polecenie
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}Statek {COMMA} ma zduplikowane polecenia
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}Statek {COMMA} ma nieodpowiednią stację w rozkładzie
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}Samolot {COMMA} ma za mało poleceń w rozkładzie
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}Samolot {COMMA} ma puste polecenie
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}Samolot {COMMA} ma zduplikowane polecenia
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}Samolot {COMMA} ma nieodpowiednią stację w rozkładzie
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}BÅ‚Ä…d autoodnowienia pociÄ…gu {COMMA} (limit funduszy)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}BÅ‚Ä…d autoodnowienia samochodu {COMMA} (limit funduszy)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}BÅ‚Ä…d autoodnowienia statku {COMMA} (limit funduszy)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}BÅ‚Ä…d autoodnowienia samolotu {COMMA} (limit funduszy)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}Pociąg {COMMA} jest za długi po zamianie
+
+STR_CONFIG_PATCHES :{BLACK}Konfiguracja wtyczek
+STR_CONFIG_PATCHES_TIP :{BLACK}Konfiguracja wtyczek
+STR_CONFIG_PATCHES_CAPTION :{WHITE}Konfiguracja wtyczek
+
+STR_CONFIG_PATCHES_OFF :wył.
+STR_CONFIG_PATCHES_ON :wł.
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Pokazuj prędkość pojazdów w pasku statusu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Pozwól budować na pochyłościach i wybrzeżach: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Zezwól na bardziej realistyczny zasięg obejmowania: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Pozwól usuwać drogi, mosty, tunele, itp. należące do miasta: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Pozwól budować bardzo długie pociągi: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Realistyczne przyspieszenie pociągów: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Zabroń pociągom i statkom skręcać o 90st: {ORANGE}{STRING} {LTBLUE} (wymaga NPF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Połącz stacje budowane jedna obok drugiej: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Opuść stację gdy dowolny towar jest pełny, gdy 'Załadunek': {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Użyj ulepszonego algorytmu załadunku: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GRADUAL_LOADING :{LTBLUE}Stopniowy załadunek pojazdów: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Inflacja: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Dostarcz ładunek na stację tylko jeśli jest zapotrzebowanie: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Pozwól budować bardzo długie mosty: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Zezwalaj na wysyłanie do zajezdni: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Pozwól budować przedsiębiorstwa produkujące surowce: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Pozwól na wiele podobnych przedsiębiorstw w mieście: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Przedsiębiorstwa jednego typu mogą być bud. obok siebie: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Zawsze pokazuj datę w długim formacie w pasku statusu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Pokazuj sygnały po stronie jazdy: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Pokazuj okno finansów na koniec roku: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}Kompatybilność obsługi NONSTOP z TTDPatch: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Ustawianie się samochodów w kolejkach (z efektem quantum): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Przesuń okno, kiedy kursor jest przy krawędzi: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Pozwól dawać łapówki lokalnym władzom: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Niejednolite stacje: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Nowe szukanie drogi (NPF, zastępuje NTP): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FREIGHT_TRAINS :{LTBLUE}Mnożnik wagi dla symulacji ciężkich pociągów towarowych: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Zawsze zezwalaj budować małe lotniska: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Ostrzegaj jeśli pociąg się zgubi: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Kontroluj polecenia pojazdów: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :nie
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :tak, ale wyklucz zatrzymane
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :wszystkich pojazdów
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Ostrzegaj, jeśli pociąg przynosi straty: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Pojazdy nigdy nie sÄ… wycofywane: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Autoodnowienie pojazdu gdy staje siÄ™ stary
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Autoodnowienie następuje {ORANGE}{STRING}{LTBLUE} miesięcy przed/po maks. wieku
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Min. ilość pieniędzy potrzebna do autoodnowienia: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Czas trwania komunikatu o błędzie: {ORANGE}{STRING} sekund{P a y ""}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Pokaż populację miasta w jego nazwie: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Niewidoczne drzewa (w trybie przezroczystych budynków): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Generator krajobrazu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :Oryginalny
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis
+STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}Maksymalna odległość rafinerii od brzegu mapy {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Wysokość granicy wiecznych śniegów: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN :{LTBLUE}Wyboistość terenu (w TerraGenesis) : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Bardzo Å‚agodny
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH :Åagodny
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH :Wyboisty
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :Bardzo wyboisty
+STR_CONFIG_PATCHES_TREE_PLACER :{LTBLUE}Algorytm rozmieszczenia drzew: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TREE_PLACER_NONE :Brak
+STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL :Oryginalny
+STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED :Ulepszony
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION :{LTBLUE}Obrót mapy wysokości: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Przec. do wsk. zegara
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE :Zg. ze wsk. zegara
+STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT :{LTBLUE}Wysokość jaką dostaje płaska mapa: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Maks. wielkość stacji: {ORANGE}{STRING} {RED}Uwaga: Duże wartości spowalniają grę
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Automatycznie serwisuj helikoptery na lÄ…dowiskach: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Przyłącz okno narzędzi krajobrazu do okien środków transportu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Przewijaj obraz myszka w przeciwnym kierunku: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Pokaż dymek z pomiarem podczas używania rożnych narzędzi: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Pokaż poboczne schematy koloru: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES_NONE :Żadne
+STR_CONFIG_PATCHES_LIVERIES_OWN :WÅ‚asnej firmy
+STR_CONFIG_PATCHES_LIVERIES_ALL :Wszystkich firm
+STR_CONFIG_PATCHES_PREFER_TEAMCHAT :{LTBLUE}Preferuj czat drużynowy po użyciu <ENTER> lub <T>: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Maks. liczba pociągów na gracza: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Maks. liczba samochodów na gracza: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}Maks. liczba samolotów na gracza: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}Maks. liczba statków na gracza: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Pociągi niedostępne dla komputera: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Samochody niedostępne dla komputera: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Samoloty niedostępne dla komputera: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Statki niedostępne dla komputera: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Dostępne nowe AI (alpha): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Pozwól na AI w grze wieloosobowej (testowe): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Domyślny okres między serwis. dla pociągów: {ORANGE}{STRING} dni
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Domyślny okres między serwis. dla pociągów: {ORANGE}niedostępne
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Domyślny okres między serwis. dla samochodów: {ORANGE}{STRING} dni
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Domyślny okres między serwis. dla samochodów: {ORANGE}niedostępne
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Domyślny okres między serwis. dla samolotów: {ORANGE}{STRING} dni
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Domyślny okres między serwis. dla samolotów: {ORANGE}niedostępne
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Domyślny okres między serwis. dla statków: {ORANGE}{STRING} dni
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Domyślny okres między serwis. dla statków: {ORANGE}niedostępne
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Wyłącz serwisowanie jeśli awarie pojazdów są wyłączone: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Włącz limity prędkości wagonów: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}Zabroń korzystanie z kolei elektrycznych: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Pojawianie się kolorowych wiadomości w: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Data rozpoczęcia gry: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}Data zakończenia gry: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Pozwól na łagodną ekonomię (więcej małych zmian)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Pozwól kupować odziały w innych firmach
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}W trakcie przeciągania ustaw sygnały co: {ORANGE}{STRING} kratk{P e i ek}
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Pozycja głównego paska narzędzi: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Z lewej strony
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Wyśrodkowane
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Z prawej strony
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Strefa przyciÄ…gania okien: {ORANGE}{STRING} pkt
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Strefa przyciągania okien: {ORANGE}niedostępne
+
+STR_CONFIG_PATCHES_GUI :{BLACK}Interfejs
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Konstrukcje
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Pojazdy
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Stacje
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Ekonomia
+STR_CONFIG_PATCHES_AI :{BLACK}Zawodnicy
+
+STR_CONFIG_PATCHES_DISABLED :niedostępne
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Zmiana wartości
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Niektóre lub wszystkie domyślne okresy między serwisowania są sprzeczne z wybranymi! 5-90% i 30-800 dni są poprawne
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}Używaj YAPF dla statków: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}Używaj YAPF dla samochodów: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}Używaj YAPF dla pociągów: {ORANGE}{STRING}
+
+STR_TEMPERATE_LANDSCAPE :Krajobraz umiarkowany
+STR_SUB_ARCTIC_LANDSCAPE :Krajobraz arktyczny
+STR_SUB_TROPICAL_LANDSCAPE :Krajobraz tropikalny
+STR_TOYLAND_LANDSCAPE :Krajobraz zabawkowy
+
+STR_CHEATS :{WHITE}Oszukiwanie
+STR_CHEATS_TIP :{BLACK}Checkboxy pokazują czy używano już tego oszustwa
+STR_CHEATS_WARNING :{BLACK}Uwaga! Właśnie chcesz zdradzić swoich wspólników.{}Miej na uwadze, że zostanie to zapamiętane na wieki!
+STR_CHEAT_MONEY :{LTBLUE}Zwiększ ilość pieniędzy o {CURRENCY64}
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Graj jako gracz: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Magiczny buldożer (usuwanie przedsiębiorstw, itp.): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Tunele mogą się krzyżować: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Budowanie w czasie pauzy: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Odrzutowce nie będą się często rozbijać na małych lotniskach: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Zmień klimat: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Zmień datę: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}Pozwól modyfikować wielkość produkcji przedsiębiorstw: {ORANGE}{STRING}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}Zmierza do {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Zmierza do {WAYPOINT}, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :Idź przez {WAYPOINT}
+STR_GO_NON_STOP_TO_WAYPOINT :Idź bez zatrzymywania przez {WAYPOINT}
+
+STR_WAYPOINTNAME_CITY :Pkt. kontrolny {TOWN}
+STR_WAYPOINTNAME_CITY_SERIAL :Pkt. kontrolny {TOWN} #{COMMA}
+STR_LANDINFO_WAYPOINT :Pkt. kontrolny
+
+STR_WAYPOINT :{WHITE}Pkt kontrolny
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Wybierz typ pkt kontrolnego
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}Edytuj nazwÄ™ pkt. kontrolnego
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Nie można zmienić nazwy pkt. kontrolnego...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Zmiana torów na pkt. kontrolny
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Nie można tutaj zbudować pkt. kontolnego...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Nie można usunąć pkt. kontrolnego z tego miejsca...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Budowanie torów używając trybu Autorail
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}...nie ma żadnego miasta w scenariuszu
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}Jesteś pewien że chcesz stworzyć losowy krajobraz?
+STR_MANY_RANDOM_TOWNS :{BLACK}Wiele losowych miast
+STR_RANDOM_TOWNS_TIP :{BLACK}Pokryj mapę losowo położonymi miastami
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Wiele losowych przedsiębiorstw
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Pokryj mapę losowo położonymi przedsiębiorstwami
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Nie można stworzyć przedsiębiorstw...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Zmiana terenu, podwyższanie/obniżanie lądu, sadzenie drzew, itp.
+STR_LANDSCAPING_TOOLBAR :{WHITE}Krajobraz
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Wyrównaj teren
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Drzewa rożnych rodzajów
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}Sadzenie drzew rożnych rodzajów
+
+STR_CANT_BUILD_CANALS :{WHITE}Nie można tutaj wybudować kanału...
+STR_BUILD_CANALS_TIP :{BLACK}Buduj kanały
+STR_LANDINFO_CANAL :Kanał
+
+STR_CANT_BUILD_LOCKS :{WHITE}Nie można tutaj wybudować śluzy...
+STR_BUILD_LOCKS_TIP :{BLACK}Buduj śluzy
+STR_LANDINFO_LOCK :Åšluza
+
+STR_BUOY_IS_IN_USE :{WHITE}...boja w użyciu!
+
+STR_LANDINFO_COORDS :{BLACK}Pozycja: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Nie można usunąć części stacji...
+STR_CANT_CONVERT_RAIL :{WHITE}Nie można zmienić typu torów w tym miejscu...
+STR_CONVERT_RAIL_TIP :{BLACK}Zamiana typu torów
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Przeciągnij tutaj lokomotywę by sprzedać cały pociąg
+
+STR_DRAG_DROP :{BLACK}Przeciągnij i upuść
+STR_STATION_DRAG_DROP :{BLACK}Budowanie stacji używając przeciągnij i upuść
+STR_SELECT_STATION_CLASS_TIP :{BLACK}Wybierz rodzaj stacji do pokazania
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Wybierz typ stacji do zbudowania
+
+STR_FAST_FORWARD :{BLACK}Szybkie przemijanie czasu w grze
+STR_MESSAGE_HISTORY :{WHITE}Poprzednie wiadomości
+STR_MESSAGE_HISTORY_TIP :{BLACK}Lista ostatnich wiadomości
+STR_MESSAGES_DISABLE_ALL :{BLACK}Wyłącz wszystko
+STR_MESSAGES_ENABLE_ALL :{BLACK}WÅ‚Ä…cz wszystko
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Zbuduj kopalnię węgla
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Posadź las
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Zbuduj platformÄ™ wiertniczÄ…
+STR_CONSTRUCT_FARM_TIP :{BLACK}Zbuduj farmÄ™
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Zbuduj kopalniÄ™ rudy miedzi
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Odwiert do ropy
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Zbuduj kopalnię złota
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Zbuduj kopalnię diamentów
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Zbuduj kopalnię rudy żelaza
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Posadź plantację owoców
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Posadź plantację kauczuku
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Zbuduj Ujęcie wody
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Posadź las waty cukrowej
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}Zbuduj farmÄ™ baterii
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Odwiert do coli
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Zbuduj fontanny plastiku
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Zbuduj generator bąbelków
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Zbuduj OdkrywkÄ™ Toffi
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Zbuduj kopalniÄ™ cukru
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Przemysł
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} (przetransportowano {COMMA}%)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} (przetransportowano {COMMA}%/{COMMA}%)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}...zbyt blisko innego przedsiębiorstwa
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Przebudowa pociÄ…gu do przewozu innego typu towaru
+STR_RAIL_REFIT_VEHICLE :{BLACK}Przebudowa pociÄ…gu
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Wybierz jaki ładunek ma przewozić pociąg
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Przebuduj pociÄ…g do przewozu zaznaczonego typu towaru
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Nie można przebudować pociągu...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Okres między serwisowaniami w procentach: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Zmiana produkcji
+
+TEMP_AI_IN_PROGRESS :{WHITE}Witamy w nowym AI. Jeśli natkniesz się na problem, wykonaj zrzut ekranu i wyślij go na forum. Powodzenia!
+TEMP_AI_ACTIVATED :{WHITE}Ostrzeżenie: nowe AI jest ciągle w wersji alpha! Obecnie działa tylko dla samochodów!
+TEMP_AI_MULTIPLAYER :{WHITE}Uwaga: Ta funkcja jest ciągle w fazie testów. Proszę zgłaszać wszelkie problemy pod adresem truelight@openttd.org.
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Gra Wieloosobowa
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Nazwa gracza:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}To jest nazwa pod którą będą Cię widzieć inni gracze
+STR_NETWORK_CONNECTION :{BLACK}Połączenie:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Wybierz między grą w internecie a grą w sieci lokalnej
+
+STR_NETWORK_START_SERVER :{BLACK}Uruchomienie serwera
+STR_NETWORK_START_SERVER_TIP :{BLACK}Uruchomienie własnego serwera
+
+STR_NETWORK_GAME_NAME :{BLACK}Nazwa
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Nazwa gry
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Język, wersja serwera, itp.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Kliknij na grze z listy by ją wybrać
+
+STR_NETWORK_FIND_SERVER :{BLACK}Szukanie serwera
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Przeszukuje siec w poszukiwaniu serwera
+STR_NETWORK_ADD_SERVER :{BLACK}Dodaj serwer
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Dodaj serwer do listy, która będzie przeszukiwana w poszukiwaniu uruchomionych gier.
+STR_NETWORK_ENTER_IP :{BLACK}Wpisz adres IP serwera
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Klientów
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Klientów podłączonych / maks.{}Firm podłączonych / maks.
+STR_NETWORK_GAME_INFO :{SILVER}INFO O GRZE
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Klienci: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Język: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Krajobraz: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Rozmiar mapy: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}Wersja serwera: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}Adres serwera: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Data uruchomienia: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Bieżąca data: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Chronione hasłem!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}SERWER WYÅÄ„CZONY
+STR_NETWORK_SERVER_FULL :{SILVER}SERWER PEÅNY
+STR_NETWORK_VERSION_MISMATCH :{SILVER}NIEZGODNA WERSJA
+STR_NETWORK_GRF_MISMATCH :{SILVER}NIEZGODNE NEWGRF
+
+STR_NETWORK_JOIN_GAME :{BLACK}Przyłącz się do gry
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}Rozpocznij nowa grÄ™
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Nazwa gry:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}Nazwa gry będzie wyświetlana u innych graczy w menu gry wieloosobowej
+STR_NETWORK_SET_PASSWORD :{BLACK}Ustaw hasło
+STR_NETWORK_PASSWORD_TIP :{BLACK}Zabezpiecz grę hasłem jeśli nie chcesz, by była publicznie dostępna
+STR_NETWORK_SELECT_MAP :{BLACK}Wybierz mapÄ™:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}Na której mapie chcesz grac?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}Dopuszczalna ilość klientów:
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Ustaw maksymalną liczbę klientów. Nie wszystkie pola muszą być wypełnione.
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :LAN
+STR_NETWORK_INTERNET :Internet
+STR_NETWORK_LAN_INTERNET :LAN / Internet
+STR_NETWORK_INTERNET_ADVERTISE :Internet (publiczny)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 graczy
+STR_NETWORK_1_PLAYERS :1 gracz
+STR_NETWORK_2_PLAYERS :2 graczy
+STR_NETWORK_3_PLAYERS :3 graczy
+STR_NETWORK_4_PLAYERS :4 graczy
+STR_NETWORK_5_PLAYERS :5 graczy
+STR_NETWORK_6_PLAYERS :6 graczy
+STR_NETWORK_7_PLAYERS :7 graczy
+STR_NETWORK_8_PLAYERS :8 graczy
+STR_NETWORK_9_PLAYERS :9 graczy
+STR_NETWORK_10_PLAYERS :10 graczy
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}Maksymalna ilość firm:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Ogranicz serwer do określonej ilości firm
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}Maksymalna ilość widzów:
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Ogranicz serwer do określonej ilości widzów
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Wzywany język w grze:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Inni gracze będą poinformowani jaki język jest używany na serwerze
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}Rozpocznij grÄ™
+STR_NETWORK_START_GAME_TIP :{BLACK}Uruchom nowÄ… grÄ™ sieciowÄ… z losowÄ… mapÄ… lub scenariuszem
+STR_NETWORK_LOAD_GAME :{BLACK}Wczytaj GrÄ™
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Przywróć wcześniej zapisaną grę wieloosobową (upewnij się, że połączyłeś się jako odpowiedni gracz)
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Dowolny
+STR_NETWORK_LANG_ENGLISH :Angielski
+STR_NETWORK_LANG_GERMAN :Niemiecki
+STR_NETWORK_LANG_FRENCH :Francuski
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Lobby gry wieloosobowej
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Przygotowanie do połączenia: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}Lista wszystkich firm w grze. Możesz przyłączyć się do jednej z nich lub założyć nowa
+STR_NETWORK_NEW_COMPANY :{BLACK}Nowa firma
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Rozpoczęcie działalności nowej firmy
+STR_NETWORK_SPECTATE_GAME :{BLACK}Gra obserwowana
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}OglÄ…daj grÄ™ jako widz
+STR_NETWORK_JOIN_COMPANY :{BLACK}Połącz z firmą
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Pomóż zarządzać tą firmą
+STR_NETWORK_REFRESH :{BLACK}Odśwież serwer
+STR_NETWORK_REFRESH_TIP :{BLACK}Odśwież informacje o serwerze
+
+STR_NETWORK_COMPANY_INFO :{SILVER}INFO O FIRMIE
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Nazwa firmy: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}Inauguracja: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}Wartość firmy: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Bieżący bilans: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Przychód w ostatnim roku: {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}Wydajność: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}Pojazdy: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Stacje: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Gracze: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}ÅÄ…czenie...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) ÅÄ…czenie..
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Autoryzacja..
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Oczekiwanie..
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Pobieranie mapy..
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Przetwarzanie danych..
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) Rejestracja..
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Uzyskiwanie informacji o grze..
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Uzyskiwanie informacji o firmach..
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} klient{P "" ów ów} chce się przyłączyć
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} kB dotÄ…d pobranych
+
+STR_NETWORK_DISCONNECT :{BLACK}Rozłączony
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Wprowadź ilość pieniędzy jaką chcesz przekazać
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Serwer jest chroniony. Wprowadź hasło
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Firma jest chroniona. Wprowadź hasło
+STR_NETWORK_CLIENT_LIST :{WHITE}Lista klientów
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE} Brak interface'u sieciowego lub skompilowane bez opcji ENABLE_NETWORK
+STR_NETWORK_ERR_NOSERVER :{WHITE} Nie można znaleźć żadnej gry w sieci
+STR_NETWORK_ERR_NOCONNECTION :{WHITE} Serwer nie odpowiada
+STR_NETWORK_ERR_DESYNC :{WHITE} BÅ‚Ä…d synchronizacji gry sieciowej.
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} Połączenie utracone w grze sieciowej.
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} Nie można wczytać zapisanej gry z serwera.
+STR_NETWORK_ERR_SERVER_START :{WHITE} Nie można uruchomić serwera
+STR_NETWORK_ERR_CLIENT_START :{WHITE} Nie można połączyć
+STR_NETWORK_ERR_TIMEOUT :{WHITE} Przekroczony limit czasu dla połączenia #{NUM}
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE} Błąd protokołu, połączenie zostało przerwane.
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE} Wersja gry nie zgadza siÄ™ z wersjÄ… gry na serwerze
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} Złe hasło
+STR_NETWORK_ERR_SERVER_FULL :{WHITE} Serwer jest pełny
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} Masz zabroniony dostęp do tego serwera
+STR_NETWORK_ERR_KICKED :{WHITE} Zostałeś wyrzucony z serwera
+STR_NETWORK_ERR_CHEATER :{WHITE} UÅ‚atwienia sÄ… niedozwolone na tym serwerze
+
+STR_NETWORK_ERR_LEFT :opuścił grę
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :błąd ogólny
+STR_NETWORK_ERR_CLIENT_DESYNC :błąd synchronizacji
+STR_NETWORK_ERR_CLIENT_SAVEGAME :nie można załadować mapy
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :połączenie utracone
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :błąd protokołu
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :nie autoryzowane
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :odebrany nieznany pakiet
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :zła wersja
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :nazwa już w użyciu
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :złe hasło gry
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :błędne id gracza w DoCommand
+STR_NETWORK_ERR_CLIENT_KICKED :wyrzucony przez serwer
+STR_NETWORK_ERR_CLIENT_CHEATER :probował użyć ułatwień
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :serwer jest pełny
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :przyłączył się do gry
+STR_NETWORK_GIVE_MONEY :dał Ci trochę pieniędzy ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :przekazałeś {STRING} trochę pieniędzy ({CURRENCY})
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Zespół] :
+STR_NETWORK_CHAT_COMPANY :[Zespół] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Zespół] do {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[Prywatna] :
+STR_NETWORK_CHAT_CLIENT :[Prywatna] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[Prywatna] do {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[Wszyscy] :
+STR_NETWORK_CHAT_ALL :[Wszyscy] {STRING}: {GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :zmienił/-a swoją nazwę na
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE} Serwer zamknÄ…Å‚ sesjÄ™
+STR_NETWORK_SERVER_REBOOT :{WHITE} Restart serwera...{}Proszę czekać...
+
+STR_NETWORK_SERVER :Serwer
+STR_NETWORK_CLIENT :Klient
+STR_NETWORK_SPECTATORS :Widzowie
+
+STR_NETWORK_CLIENTLIST_NONE :(brak)
+STR_NETWORK_CLIENTLIST_KICK :Wyrzuć
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Przekazanie pieniędzy
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Mów do wszystkich
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Mów do firmy
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Prywatna wiadomość
+
+
+STR_NETWORK_SEND :{BLACK}Wyślij
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}Rozmiar mapy X: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Rozmiar mapy Y: {ORANGE}{STRING}
+
+
+##### PNG-MAP-Loader
+
+STR_PNGMAP_ERROR :{WHITE}Nie można wczytać krajobrazu z PNG...
+STR_PNGMAP_ERR_FILE_NOT_FOUND :{WHITE}...nie znaleziono pliku.
+STR_PNGMAP_ERR_IMAGE_TYPE :{WHITE}...nie można konwertować typu obrazu. Wymagany 8- lub 24-bitowy PNG.
+STR_PNGMAP_ERR_MISC :{WHITE}...coś poszło nie tak. Przepraszam. (prawdopodobnie zepsuty plik)
+
+STR_BMPMAP_ERROR :{WHITE}Nie można wczytać krajobrazu z BMP...
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}...nie można konwertować typu obrazu.
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Koszt: {CURRENCY}
+STR_0801_COST :{RED}Koszt: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Przychód: {CURRENCY}
+STR_0803_INCOME :{GREEN}Przychód: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Transfer: {CURRENCY}
+STR_FEEDER :{YELLOW}Transfer: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Szacowany koszt: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Szacowany przychód: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Nie można tutaj podnieść lądu...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Nie można tutaj obniżyć lądu...
+STR_080A_ROCKS :Skały
+STR_080B_ROUGH_LAND :Wyboisty teren
+STR_080C_BARE_LAND :Odkryty teren
+STR_080D_GRASS :Trawa
+STR_080E_FIELDS :Pola
+STR_080F_SNOW_COVERED_LAND :Zaśnieżony teren
+STR_0810_DESERT :Pustynia
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Teren pochylony w złym kierunku
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Niemożliwa kombinacja torów
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}Wykop zniszczyłby tunel
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Już na poziome morza
+STR_1004_TOO_HIGH :{WHITE}Zbyt wysoko
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Nieodpowiednie tory
+STR_1007_ALREADY_BUILT :{WHITE}...już zbudowano
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Najpierw trzeba usunąć tory
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Konstrukcja torowiska
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Konstrukcja elektryfikowanego torowiska
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Konstrukcja torowiska jednoszynowego
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}Konstrukcja torowiska MagLev
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Wybierz rodzaj mostu kolejowego
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Nie można tutaj wybudować zajezdni...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Nie można tutaj wybudować stacji...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Nie można tutaj postawić sygnałów...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Nie można tutaj ułożyć torów...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Nie można stąd usunąć torów...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Nie można stąd usunąć sygnałów...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Orientacja zajezdni
+STR_1015_RAILROAD_CONSTRUCTION :Konstrukcja torowiska
+STR_TOOLB_ELRAIL_CONSTRUCTION :Konstrukcja elektryfikowanego torowiska
+STR_1016_MONORAIL_CONSTRUCTION :Konstrukcja torowiska jednoszynowego
+STR_1017_MAGLEV_CONSTRUCTION :Konstrukcja torowiska MagLev
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Budowa torów
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Budowa zajezdni (w celu budowy i serwisowania pociągów)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Budowa stacji kolejowej
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Budowa sygnałów
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Budowa mostu kolejowego
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Budowa tunelu kolejowego
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Przełącz buduj/usuń dla torów i semaforów
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Wybór mostu - klik na wybranym moście aby go zbudować
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Wybierz orientacje zajezdni kolejowej
+STR_1021_RAILROAD_TRACK :Tory
+STR_1023_RAILROAD_TRAIN_DEPOT :Zajezdnia kolejowa
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...teren jest własnością innej firmy
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :Tory kolejowe ze zwykłą sygnalizacją
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :Tory kolejowe z pre-sygnałami
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :Tory kolejowe z sygnalizacjÄ… wyjsciowÄ…
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :Tory kolejowe z sygnalizacja combo
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Trzeba najpierw usunąć drogę
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}TrwajÄ… roboty drogowe
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Tworzenie dróg
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Wybierz most drogowy
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Nie można tutaj zbudować drogi...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Nie można usunąć drogi z tego miejsca...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Orientacja zajezdni samochodowej
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Nie można tutaj zbudować zajezdni...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Nie można zbudować przystanku...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Nie można zbudować stacji ciężarówek...
+STR_180A_ROAD_CONSTRUCTION :Budowa drogi
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Sekcja budowy dróg
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Zbuduj zajezdnie samochodową (do budowania i serwisowania pojazdów)
+STR_180D_BUILD_BUS_STATION :{BLACK}Budowa przystanku
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Zbuduj stację załadunku ciężarówek
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Budowa mostu drogowego
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Budowa tunelu drogowego
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Przełącz buduj/usuń dla konstrukcji dróg
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Wybierz umiejscowienie zajezdni samochodowej
+STR_1814_ROAD :Droga
+STR_1815_ROAD_WITH_STREETLIGHTS :Droga z oświetleniem ulicznym
+STR_1816_TREE_LINED_ROAD :Droga z drzewami
+STR_1817_ROAD_VEHICLE_DEPOT :Zajezdnia samochodowa
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :Przejazd kolejowy
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Miasta
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Budynek musi być najpierw zburzony
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}Populacja: {ORANGE}{COMMA}{BLACK} Domów: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Zmień nazwę miasta
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Nie można zmienić nazwy miasta...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}Lokalne władze {TOWN} nie pozwalają na to
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Nazwy miast - klik na nazwie aby wycentrować widok na mieście
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centruj główny widok na mieście
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Zmień nazwę miasta
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Pasażerów w zeszłym miesiącu: {ORANGE}{COMMA}{BLACK} maks: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Poczta w zeszłym miesiącu: {ORANGE}{COMMA}{BLACK} maks: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Wysoki biurowiec
+STR_2010_OFFICE_BLOCK :Biurowiec
+STR_2011_SMALL_BLOCK_OF_FLATS :Mały blok mieszkalny
+STR_2012_CHURCH :Kościół
+STR_2013_LARGE_OFFICE_BLOCK :Duży biurowiec
+STR_2014_TOWN_HOUSES :Domki miejskie
+STR_2015_HOTEL :Hotel
+STR_2016_STATUE :Pomnik
+STR_2017_FOUNTAIN :Fontanna
+STR_2018_PARK :Park
+STR_2019_OFFICE_BLOCK :Biurowiec
+STR_201A_SHOPS_AND_OFFICES :Sklepy i biura
+STR_201B_MODERN_OFFICE_BUILDING :Nowoczesny biurowiec
+STR_201C_WAREHOUSE :Magazyny
+STR_201D_OFFICE_BLOCK :Biurowiec
+STR_201E_STADIUM :Stadion
+STR_201F_OLD_HOUSES :Stare domy
+STR_2020_LOCAL_AUTHORITY :{BLACK}Lokalne władze
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Pokaż informacje o lokalnych władzach
+STR_2022_LOCAL_AUTHORITY :{WHITE}{TOWN} lokalne władze
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Ocena transportu firmy:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Subsydia
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Oferta subsydiów dla usługi przewozu:
+STR_2027_FROM_TO :{ORANGE}{STRING} z {STRING} do {STRING}
+STR_2028_BY :{YELLOW} (do {DATE_SHORT})
+STR_202A_NONE :{ORANGE}Żadne
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Usługi już subsydiowane:
+STR_202C_FROM_TO :{ORANGE}{STRING} z {STATION} do {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, do {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}Subsydiowanie wygasło:{}{}{STRING} z {STRING} do {STRING} już nie będzie dotowane.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Koniec dotacji:{}{}Przewóz {STRING.d} z {STATION} do {STATION} już nie jest subsydiowany.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Oferta usługi dotowanej:{}{}Pierwszy przewóz {STRING.d} z {STRING} do {STRING} będzie dotowany przez rok przez lokalne władze!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Przyznano subsydia dla {COMPANY}!{}{}Przewóz {STRING.d} z {STATION} do {STATION} będzie opłacany o 50% więcej przez następny rok!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Przyznano subsydia dla {COMPANY}!{}{}Przewóz {STRING.d} z {STATION} do {STATION} będzie opłacany podwójnie przez następny rok!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Przyznano subsydia dla {COMPANY}!{}{}Przewóz {STRING.d} z {STATION} do {STATION} będzie opłacany potrójnie przez następny rok!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Przyznano subsydia dla {COMPANY}!{}{}Przewóz {STRING.d} z {STATION} do {STATION} będzie opłacany poczwórnie przez następny rok!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}Lokalne władze {TOWN} nie pozwalają na budowę kolejnego lotniska w tym mieście
+STR_2036_COTTAGES :Domki
+STR_2037_HOUSES :Domy
+STR_2038_FLATS :Mieszkania
+STR_2039_TALL_OFFICE_BLOCK :Wysoki biurowiec
+STR_203A_SHOPS_AND_OFFICES :Sklepy i biura
+STR_203B_SHOPS_AND_OFFICES :Sklepy i biura
+STR_203C_THEATER :Teatr
+STR_203D_STADIUM :Stadion
+STR_203E_OFFICES :Biura
+STR_203F_HOUSES :Domy
+STR_2040_CINEMA :Kino
+STR_2041_SHOPPING_MALL :Centrum handlowe
+STR_2042_DO_IT :{BLACK}Wykonaj
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}Lista rzeczy do zrobienia w tym mieście - klik po więcej detali
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Wykonaj podświetloną akcję z poniższej listy
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Możliwe działanie:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Mała kampania reklamowa
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Åšrednia kampania reklamowa
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Duża kampania reklamowa
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Ufunduj rekonstrukcję dróg
+STR_204A_BUILD_STATUE_OF_COMPANY :Zbuduj statuę właściciela
+STR_204B_FUND_NEW_BUILDINGS :Ufunduj nowe budynki
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Kup wyłączność transportową
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Daj łapówkę lokalnym władzom
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Rozpocznij małą kampanię reklamową aby zachęcić pasażerów i fabryki do Twoich usług.{} Koszt: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Rozpocznij średnią kampanię reklamową aby zachęcić więcej pasażerów i fabryk do Twoich usług transportowych.{} Koszt: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Rozpocznij dużą kampanię reklamową aby zachęcić więcej pasażerów i fabryk do Twoich usług transportowych.{} Koszt: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} Ufunduj remont sieci dróg. Powoduje zakłócenia w ruchu ulicznym do 6 miesięcy.{} Koszt: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Zbuduj pomnij dla uczczenia Twojej firmy.{} Koszt: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Ufundowanie nowych budynków komercyjnych w mieście.{} Koszt: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Kup roczną wyłączność na prawa transportowe w mieście. Lokalne władze pozwolą korzystać tylko z usług Twojej firmy.{} Koszt: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Daj łapówkę lokalnym władzom, powiększ Swoją ocenę, ryzykując poważne kary w razie złapania.{} Koszt: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}Chaos na drogach w {TOWN}!{}{}Program przebudowy dróg ufundowany przez {COMPANY} przynosi 6 miesięcy męki dla kierowców!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (w budowie)
+STR_2059_IGLOO :Igloo
+STR_205A_TEPEES :Tipi
+STR_205B_TEAPOT_HOUSE :Dom-Czajniczek
+STR_205C_PIGGY_BANK :Åšwinka-skarbonka
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN} {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Krajobraz
+STR_2800_PLANT_TREES :Posadź drzewa
+STR_2801_PLACE_SIGN :Umieść napis
+STR_2802_TREES :{WHITE}Drzewa
+STR_2803_TREE_ALREADY_HERE :{WHITE}...drzewo już tu jest
+STR_2804_SITE_UNSUITABLE :{WHITE}...niewłaściwe miejsce
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Nie można posadzić drzewa...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...zbyt wiele napisów
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Nie można umieścić napisu...
+STR_280A_SIGN :Napis
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Edycja tekstu napisu
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Nie możesz zmienić nazwy napisu...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Wybierz typ drzew do sadzenia
+STR_280E_TREES :Drzewa
+STR_280F_RAINFOREST :Las deszczowy
+STR_2810_CACTUS_PLANTS :Kaktusy
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Wybór stacji
+STR_3001_AIRPORT_SELECTION :{WHITE}Wybór lotniska
+STR_3002_ORIENTATION :{BLACK}Orientacja
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Ilość peronów
+STR_3004_PLATFORM_LENGTH :{BLACK}Długość peronu
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Zbyt blisko innej stacji
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Przylega do więcej niż jednej stacji
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}Za dużo stacji w tym mieście
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}Za duzo stacji
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Za dużo wiele przystankow autobusowych
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}Za dużo wiele stacji załadunku ciężarówek
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Zbyt blisko innej stacji
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Najpierw musisz zniszczyć stację
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Zbyt blisko innego lotniska
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Najpierw musisz zniszczyć lotnisko
+
+STR_3030_RENAME_STATION_LOADING :Zmień nazwę stacji
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Nie można zmienić nazwy.
+STR_3032_RATINGS :{BLACK}Oceny
+STR_3033_ACCEPTS :{BLACK}Akceptuje
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}Lokalna ocena usług transportowych:
+
+############ range for rating starts
+STR_3035_APPALLING :Beznadziejne
+STR_3036_VERY_POOR :Bardzo słabe
+STR_3037_POOR :SÅ‚abe
+STR_3038_MEDIOCRE :Åšrednie
+STR_3039_GOOD :Dobre
+STR_303A_VERY_GOOD :Bardzo dobre
+STR_303B_EXCELLENT :Wyśmienite
+STR_303C_OUTSTANDING :Bezkonkurencyjne
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} już nie akceptuje {STRING.d}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} już nie akceptuje {STRING.d} ani {STRING.d}
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} już akceptuje {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} już akceptuje {STRING} i {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Orientacja przystanku
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Orientacja st. załadunku
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Najpierw musisz zniszczyć przystanek
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Najpierw musisz zniszczyć stację załadunku ciężarówek
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA}
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Nic -
+STR_304B_SITE_UNSUITABLE :{WHITE}...niewłaściwe miejsce
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Zbyt blisko innego portu
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Najpierw musisz zniszczyć port
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Wybierz orientacje stacji
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Wybierz ilość peronów na stacji
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Wybierz długość stacji
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Wybierz orientacje przystanku
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Orientacja stacji załadunku ciężarówek
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Centruj główny widok na stacji
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Pokaż ocenę stacji
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Zmień nazwę stacji
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Pokaż listę akceptowanych towarów
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Nazwa stacji - kliknij na nazwie aby wycentrować główny widok na stacji
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Wybierz wielkość/typ lotniska
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :Stacja kolejowa
+STR_305F_AIRCRAFT_HANGAR :Hangar
+STR_3060_AIRPORT :Lotnisko
+STR_3061_TRUCK_LOADING_AREA :Stacja załadunku ciężarówek
+STR_3062_BUS_STATION :Przystanek
+STR_3063_SHIP_DOCK :Port
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Podświetl zasięg projektowanej stacji
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Nie podświetlaj zasięgu projektowanej stacji
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Podświetlaj zasięg
+STR_3068_DOCK :{WHITE}Port
+STR_3069_BUOY :Boja
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...boja na drodze
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...stacja zbyt rozległa
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...niejednorodne są niedostępne
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Przytrzymaj CTRL aby zaznaczyć więcej niż jedną opcję
+
+STR_UNDEFINED :(nieokreślony tekst)
+STR_STAT_CLASS_DFLT :Typowa stacja
+STR_STAT_CLASS_WAYP :Pkt. kontrolne
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Orientacja stoczni
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...musi być wybudowane na wodzie
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Nie można tutaj wybudować stoczni...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}wybierz orientacjÄ™ stoczni
+STR_3804_WATER :Woda
+STR_3805_COAST_OR_RIVERBANK :Wybrzeże lub brzeg rzeki
+STR_3806_SHIP_DEPOT :Stocznia
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...Nie można wybudować na wodzie
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Zapisz grÄ™
+STR_4001_LOAD_GAME :{WHITE}Wczytaj grÄ™
+STR_4002_SAVE :{BLACK}Zapisz
+STR_4003_DELETE :{BLACK}Usuń
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} MB wolnego miejsca
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Nie można odczytać napędu
+STR_4007_GAME_SAVE_FAILED :{WHITE}Nie można zapisać gry
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Nie można usunąć pliku
+STR_4009_GAME_LOAD_FAILED :{WHITE}Nie można wczytać gry
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}Lista napędów, katalogów i zapisanych gier
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Obecnie zaznaczona nazwa dla zapisanej gry
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Skasuj zaznaczonÄ… zapisanÄ… grÄ™
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Zapisz bieżącą grę używając wybranej nazwy
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Wybierz nowy typ gry
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Wybierz scenariusz (zielony), ustawionÄ… grÄ™ (niebieski), lub losowÄ… nowÄ… grÄ™
+STR_4010_GENERATE_RANDOM_NEW_GAME :Tworzenie losowej nowej gry
+STR_4011_LOAD_HEIGHTMAP :{WHITE}Wczytaj mapę wysokości
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} na drodze
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :{G=f}Kopalnia Węgla
+STR_4802_COAL_MINE.d :{G=f}kopalni węgla
+STR_4803_POWER_STATION :{G=f}Elektrownia
+STR_4803_POWER_STATION.d :{G=f}elektrowni
+STR_4804_SAWMILL :{G=m}Tartak
+STR_4804_SAWMILL.d :{G=m}tartaku
+STR_4805_FOREST :{G=m}Las
+STR_4805_FOREST.d :{G=m}lasu
+STR_4806_OIL_REFINERY :{G=f}Rafineria
+STR_4806_OIL_REFINERY.d :{G=f}rafinerii
+STR_4807_OIL_RIG :{G=f}Platforma Wiertnicza
+STR_4807_OIL_RIG.d :{G=f}platformy wiertniczej
+STR_4808_FACTORY :{G=f}Fabryka
+STR_4808_FACTORY.d :{G=f}fabryki
+STR_4809_PRINTING_WORKS :{G=f}Drukarnia
+STR_4809_PRINTING_WORKS.d :{G=f}drukarni
+STR_480A_STEEL_MILL :{G=f}Huta
+STR_480A_STEEL_MILL.d :{G=f}huty
+STR_480B_FARM :{G=f}Farma
+STR_480B_FARM.d :{G=f}farmy
+STR_480C_COPPER_ORE_MINE :{G=f}Kopalnia Rudy Miedzi
+STR_480C_COPPER_ORE_MINE.d :{G=f}kopalni rudy miedzi
+STR_480D_OIL_WELLS :{G=m}Pole Naftowe
+STR_480D_OIL_WELLS.d :{G=m}pola naftowego
+STR_480E_BANK :{G=m}Bank
+STR_480E_BANK.d :{G=m}banku
+STR_480F_FOOD_PROCESSING_PLANT :{G=f}Przetwórnia Żywności
+STR_4810_PAPER_MILL :{G=m}Zakład Papierniczy
+STR_4810_PAPER_MILL.d :{G=m}zakładu papierniczego
+STR_4811_GOLD_MINE :{G=f}Kopalnia ZÅ‚ota
+STR_4811_GOLD_MINE.d :{G=f}kopalni złota
+STR_4812_BANK :{G=m}Bank
+STR_4812_BANK.d :{G=m}banku
+STR_4813_DIAMOND_MINE :{G=f}Kopalnia Diamentów
+STR_4813_DIAMOND_MINE.d :{G=f}kopalni diamentów
+STR_4814_IRON_ORE_MINE :{G=f}Kopalnia Rudy Żelaza
+STR_4814_IRON_ORE_MINE.d :{G=f}kopalni rudy żelaza
+STR_4815_FRUIT_PLANTATION :{G=f}Plantacja Owoców
+STR_4815_FRUIT_PLANTATION.d :{G=f}plantacji owoców
+STR_4816_RUBBER_PLANTATION :{G=f}Plantacja Kauczuku
+STR_4816_RUBBER_PLANTATION.d :{G=f}plantacji kauczuku
+STR_4817_WATER_SUPPLY :{G=n}Ujęcie Wody
+STR_4817_WATER_SUPPLY.d :{G=n}ujęcia wody
+STR_4818_WATER_TOWER :{G=f}Wieża Ciśnień
+STR_4818_WATER_TOWER.d :{G=f}wieży ciśnień
+STR_4819_FACTORY :{G=f}Fabryka
+STR_4819_FACTORY.d :{G=f}fabryki
+STR_481A_FARM :{G=f}Farma
+STR_481A_FARM.d :{G=f}farmy
+STR_481B_LUMBER_MILL :{G=m}Tartak
+STR_481B_LUMBER_MILL.d :{G=m}tartaku
+STR_481C_COTTON_CANDY_FOREST :{G=m}Las Waty Cukrowej
+STR_481C_COTTON_CANDY_FOREST.d :{G=m}lasu waty cukrowej
+STR_481D_CANDY_FACTORY :{G=m}Zakład Cukierniczy
+STR_481D_CANDY_FACTORY.d :{G=m}zakładu cukierniczego
+STR_481E_BATTERY_FARM :{G=f}Farma Baterii
+STR_481E_BATTERY_FARM.d :{G=f}farmy baterii
+STR_481F_COLA_WELLS :{G=f}Studnia Coli
+STR_481F_COLA_WELLS.d :{G=f}studni coli
+STR_4820_TOY_SHOP :{G=m}Sklep z Zabawkami
+STR_4820_TOY_SHOP.d :{G=m}sklepu z zabawkami
+STR_4821_TOY_FACTORY :{G=f}Fabryka Zabawek
+STR_4821_TOY_FACTORY.d :{G=f}fabryki zabawek
+STR_4822_PLASTIC_FOUNTAINS :{G=f}Fontanny Plastiku
+STR_4822_PLASTIC_FOUNTAINS.d :{G=f}fontann plastiku
+STR_4823_FIZZY_DRINK_FACTORY :{G=f}Fabryka Napojów Gazowanych
+STR_4823_FIZZY_DRINK_FACTORY.d :{G=f}fabryki napojów gazowanych
+STR_4824_BUBBLE_GENERATOR :{G=m}Generator Bąbelków
+STR_4824_BUBBLE_GENERATOR.d :{G=m}generatora bąbelków
+STR_4825_TOFFEE_QUARRY :{G=f}Odkrywka Toffi
+STR_4825_TOFFEE_QUARRY.d :{G=f}odkrywkÄ™ toffi
+STR_4826_SUGAR_MINE :{G=f}Kopalnia Cukru
+STR_4826_SUGAR_MINE.d :{G=f}kopalni cukru
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Wymaga: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Wymaga: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Wymaga: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Wyprodukowano w ostatnim miesiÄ…cu:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% przetransportowano)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centruj główny widok na przedsiębiorstwie
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Rozpoczęto budowę nowe{G go j go} {STRING.d} blisko {TOWN}!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Now{G y a e} {STRING} został{G "" a o} posadzon{G y a e} blisko {TOWN}!
+STR_482F_COST :{BLACK}Koszt: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Nie można tutaj wybudować tego przedsiębiorstwa...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...las może być posadzony tylko powyżej linii śniegu
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} ogłasza bliskie zamkniecie!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}Problemy z zaopatrzeniem {INDUSTRY} powodują ogłoszenie zamknięcia!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}Niedobór drzew powoduje ogłoszenie zamknięcia {INDUSTRY}!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} zwiększa produkcję!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}Odkryto nowy pokład węgla w {INDUSTRY}!{} Podwojenie produkcji!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}Odkryte nowe rezerwy ropy w {INDUSTRY}!{} Podwojenie produkcji!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}Polepszone metody rolne w {INDUSTRY} spowodujÄ… podwojenie produkcji!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}produkcja w {INDUSTRY} maleje o 50%
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}Plaga insektów w {INDUSTRY}!{}Produkcja maleje o 50%
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...może być usytuowane tylko blisko krawędzi mapy
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}Produkcja {STRING.d} w {INDUSTRY} wzrasta o {COMMA}%!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}Produkcja {STRING.d} w {INDUSTRY} maleje o {COMMA}%!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}PociÄ…g w tunelu
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Samochód w tunelu
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Inny tunel na drodze
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Nie można wydrążyć drugiego końca tunelu
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Trzeba najpierw zniszczyć tunel
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Trzeba najpierw zniszczyć most
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Nie można zaczynać i kończyć w tym samym miejscu
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Wymagany równy ląd lub woda pod mostem
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}Początek i koniec muszą być w jednej linii
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Nieodpowiednie miejsce na wejście tunelu
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Podwieszany, Stalowy
+STR_500F_GIRDER_STEEL :Dźwigarowy, Stalowy
+STR_5010_CANTILEVER_STEEL :Wspornikowy, Stalowy
+STR_5011_SUSPENSION_CONCRETE :Podwieszany, Betonowy
+STR_5012_WOODEN :Drewniany
+STR_5013_CONCRETE :Betonowy
+STR_5014_TUBULAR_STEEL :Cylindryczny, Stalowy
+STR_BRIDGE_TUBULAR_SILICON :Cylindryczny, Krzemowy
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Nie można tutaj wybudować mostu...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Nie można tutaj wybudować tunelu...
+STR_5017_RAILROAD_TUNNEL :Tunel kolejowy
+STR_5018_ROAD_TUNNEL :Tunel samochodowy
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Stalowy most kolejowy podwieszany
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Stalowy dźwigarowy most kolejowy
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Stalowy wspornikowy most kolejowy
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Wzmocniony betonem podwieszany most kolejowy
+STR_501F_WOODEN_RAIL_BRIDGE :Drewniany most kolejowy
+STR_5020_CONCRETE_RAIL_BRIDGE :Betonowy most kolejowy
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Stalowy most drogowy podwieszany
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Stalowy dźwigarowy most drogowy
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Stalowy wspornikowy most drogowy
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Wzmocniony betonem podwieszany most drogowy
+STR_5025_WOODEN_ROAD_BRIDGE :Drewniany most drogowy
+STR_5026_CONCRETE_ROAD_BRIDGE :Betonowy most drogowy
+STR_5027_TUBULAR_RAIL_BRIDGE :Cylindryczny most kolejowy
+STR_5028_TUBULAR_ROAD_BRIDGE :Cylindryczny most drogowy
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Obiekt na drodze
+STR_5801_TRANSMITTER :Nadajnik
+STR_5802_LIGHTHOUSE :Latarnia
+STR_5803_COMPANY_HEADQUARTERS :Siedziba firmy
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...siedziba firmy na drodze
+STR_5805_COMPANY_OWNED_LAND :Teren w posiadaniu firmy
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Nie możesz nabyć tego terenu...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...to już jest Twoje!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Bez nazwy
+STR_SV_TRAIN_NAME :PociÄ…g {COMMA}
+STR_SV_ROADVEH_NAME :Samochód {COMMA}
+STR_SV_SHIP_NAME :Statek {COMMA}
+STR_SV_AIRCRAFT_NAME :Samolot {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :{STRING} Północ
+STR_SV_STNAME_SOUTH :{STRING} Południe
+STR_SV_STNAME_EAST :{STRING} Wschód
+STR_SV_STNAME_WEST :{STRING} Zachód
+STR_SV_STNAME_CENTRAL :{STRING} Główny
+STR_SV_STNAME_TRANSFER :{STRING} Transfer
+STR_SV_STNAME_HALT :{STRING} Przedmieście
+STR_SV_STNAME_VALLEY :{STRING} Dolina
+STR_SV_STNAME_HEIGHTS :{STRING} Wzgórza
+STR_SV_STNAME_WOODS :{STRING} Las
+STR_SV_STNAME_LAKESIDE :{STRING} Jezioro
+STR_SV_STNAME_EXCHANGE :{STRING} Wymiana
+STR_SV_STNAME_AIRPORT :Lotnisko {STRING}
+STR_SV_STNAME_OILFIELD :{STRING} Pole naftowe
+STR_SV_STNAME_MINES :{STRING} Kopalnia
+STR_SV_STNAME_DOCKS :{STRING} Port
+STR_SV_STNAME_BUOY_1 :{STRING} Boja 1
+STR_SV_STNAME_BUOY_2 :{STRING} Boja 2
+STR_SV_STNAME_BUOY_3 :{STRING} Boja 3
+STR_SV_STNAME_BUOY_4 :{STRING} Boja 4
+STR_SV_STNAME_BUOY_5 :{STRING} Boja 5
+STR_SV_STNAME_BUOY_6 :{STRING} Boja 6
+STR_SV_STNAME_BUOY_7 :{STRING} Boja 7
+STR_SV_STNAME_BUOY_8 :{STRING} Boja 8
+STR_SV_STNAME_BUOY_9 :{STRING} Boja 9
+STR_SV_STNAME_ANNEXE :{STRING} Pawilon
+STR_SV_STNAME_SIDINGS :{STRING} Bocznica
+STR_SV_STNAME_BRANCH :{STRING} Rozjazd
+STR_SV_STNAME_UPPER :{STRING} Górny
+STR_SV_STNAME_LOWER :{STRING} Dolny
+STR_SV_STNAME_HELIPORT :{STRING} LÄ…dowisko
+STR_SV_STNAME_FOREST :{STRING} Las
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Poziom Trudności
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Zapisz
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Åatwy
+STR_6802_MEDIUM :{BLACK}Åšredni
+STR_6803_HARD :{BLACK}Trudny
+STR_6804_CUSTOM :{BLACK}WÅ‚asny
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maksymalna ilość przeciwników: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Przeciwnik zaczyna grÄ™: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}Ilość miast: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}Ilość przedsiębiorstw: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Maksymalna początkowa pożyczka: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Początkowe oprocentowanie pożyczki: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Koszt utrzymania pojazdów: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Szybkość budowania przez przeciwników: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Poziom inteligencji przeciwników: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Uszkodzenia pojazdów: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Współczynnik subsydiów: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Koszt konstrukcji: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Typ terenu: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Ilość mórz/jezior: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Ekonomia: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Zawracanie pociągów: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Katastrofy: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Nastawienie władz do zmian okolicznych terenów: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :Brak
+STR_6816_LOW :Mało
+STR_6817_NORMAL :Åšrednio
+STR_6818_HIGH :Dużo
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Bardzo wolno
+STR_681C_SLOW :Wolno
+STR_681D_MEDIUM :Åšrednio
+STR_681E_FAST :Szybko
+STR_681F_VERY_FAST :Bardzo szybko
+STR_VERY_LOW :Bardzo niski
+STR_6820_LOW :Niski
+STR_6821_MEDIUM :Åšredni
+STR_6822_HIGH :Wysoki
+STR_6823_NONE :Brak
+STR_6824_REDUCED :Zredukowane
+STR_6825_NORMAL :Normalne
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Bardzo płaski
+STR_682B_FLAT :PÅ‚aski
+STR_682C_HILLY :Pagórkowaty
+STR_682D_MOUNTAINOUS :Górski
+STR_682E_STEADY :Stabilna
+STR_682F_FLUCTUATING :Zmienna
+STR_6830_IMMEDIATE :Natychmiast
+STR_6831_3_MONTHS_AFTER_PLAYER :3 miesiÄ…ce po graczu
+STR_6832_6_MONTHS_AFTER_PLAYER :6 miesięcy po graczu
+STR_6833_9_MONTHS_AFTER_PLAYER :9 miesięcy po graczu
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :Na końcu trasy i na stacjach
+STR_6835_AT_END_OF_LINE_ONLY :Tylko na końcu trasy
+STR_6836_OFF :Wyłączone
+STR_6837_ON :WÅ‚Ä…czone
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Pokaż Najlepsze Wyniki
+STR_6839_PERMISSIVE :Przyjazne
+STR_683A_TOLERANT :Tolerancyjne
+STR_683B_HOSTILE :Wrogie
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Gracz {COMMA})
+STR_7004_NEW_FACE :{BLACK}Nowa Twarz
+STR_7005_COLOR_SCHEME :{BLACK}Schemat Koloru
+STR_7006_COLOR_SCHEME :{GOLD}Schemat koloru:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Nowy schemat koloru
+STR_7008_COMPANY_NAME :{BLACK}Nazwa Firmy
+STR_7009_PRESIDENT_NAME :{BLACK}Prezes
+STR_700A_COMPANY_NAME :Nazwa firmy
+STR_700B_PRESIDENT_S_NAME :Nazwisko prezesa
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Nie można zmienić nazwy firmy...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Nie można zmienić nazwiska prezesa...
+STR_700E_FINANCES :{WHITE}{COMPANY} Finanse {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Wydatki/Przychody
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Konstrukcje
+STR_7012_NEW_VEHICLES :{GOLD}Nowe pojazdy
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Utrzymanie pociągów
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Utrzymanie samochodów
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Utrzymanie samolotów
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Utrzymanie statków
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Utrzymywanie własności
+STR_7018_TRAIN_INCOME :{GOLD}Przychód z pociągów
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Przychód z samochodów
+STR_701A_AIRCRAFT_INCOME :{GOLD}Przychód z samolotów
+STR_701B_SHIP_INCOME :{GOLD}Przychód ze statków
+STR_701C_LOAN_INTEREST :{GOLD}Odsetki od pożyczki
+STR_701D_OTHER :{GOLD}Inne
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}ÅÄ…cznie:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Wykres przychodów
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Wykres obrotów
+STR_7026_BANK_BALANCE :{WHITE}Bilans bankowy
+STR_7027_LOAN :{WHITE}Pożyczka
+STR_MAX_LOAN :{WHITE}Maks. pożyczka: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}Pożyczka {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Zwrot {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...maksymalna dozwolona pożyczka wynosi {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Nie można pożyczyć więcej pieniędzy...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...pożyczka już jest spłacona
+STR_702E_REQUIRED :{WHITE}...{CURRENCY} wymagane
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Nie można zwrócić pożyczki...
+STR_INSUFFICIENT_FUNDS :{WHITE}Nie możesz wydać pieniędzy, które są pożyczone z banku...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Wybierz nowa twarz prezesa
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Zmień kolor pojazdów firmy
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Zmień imię prezesa
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Zmień nazwę firmy
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Kliknij na nowym schemacie kolorów
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Zwiększ wielkość pożyczki
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Zwróć cześć pożyczki
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(Prezes)
+STR_7038_INAUGURATED :{GOLD}Inauguracja: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Pojazdy:
+STR_TRAINS :{WHITE}{COMMA} pociąg{P "" i ów}
+STR_ROAD_VEHICLES :{WHITE}{COMMA} pojazd{P "" y ów}
+STR_AIRCRAFT :{WHITE}{COMMA} samolot{P "" y ów}
+STR_SHIPS :{WHITE}{COMMA} stat{P ek ki ków}
+STR_7042_NONE :{WHITE}Brak
+STR_7043_FACE_SELECTION :{WHITE}Wybór twarzy
+STR_7044_MALE :{BLACK}Mężczyzna
+STR_7045_FEMALE :{BLACK}Kobieta
+STR_7046_NEW_FACE :{BLACK}Nowa Twarz
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Anuluj wybór nowej twarzy
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Zatwierdź wybór nowej twarzy
+STR_7049_SELECT_MALE_FACES :{BLACK}Wybierz męską twarz
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Wybierz kobieca twarz
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Stwórz nową losową twarz
+STR_704C_KEY :{BLACK}Legenda
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Pokaż legendę na wykresie
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Legenda do wykresów firm
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Kliknij tutaj aby wł./wył. wyświetlanie danych firmy na wykresie
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Dostarczonych jednostek Å‚adunku
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Ocena działalności firmy (max. ocena=1000)
+STR_7052_COMPANY_VALUES :{WHITE}Wartości firm
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Tabela Ligi Firm
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}Firma ma problemy!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} będzie odsprzedane lub ogłoszone upadłym jeżeli zysk firmy nie wzrośnie!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(Prezes)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Połączenie firm transportowych!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} został sprzedany {COMPANY} za {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Szukamy firmy transportowej która przejęłaby naszą firmę{}{}Czy chcesz kupić {COMPANY} za {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Bankrut!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} zostaje zamknięty przez wierzycieli i wszystkie udziały zostają sprzedane!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}Nowa firma rozpoczęła działalność!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} rozpoczyna budowÄ™ niedaleko {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Nie można kupić firmy...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Stawki za Åadunek
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Dni w transporcie
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Oplata za przewóz 10 jednostek (lub 10,000 litrów) towaru na odległość 20 pól
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Przełącznik wykresu ładunku wł./wył.
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Inżynier
+STR_7067_TRAFFIC_MANAGER :Administrator Ruchu
+STR_7068_TRANSPORT_COORDINATOR :Koordynator Transportu
+STR_7069_ROUTE_SUPERVISOR :Nadzorca Dróg
+STR_706A_DIRECTOR :Dyrektor
+STR_706B_CHIEF_EXECUTIVE :Dyrektor Wykonawczy
+STR_706C_CHAIRMAN :PrzewodniczÄ…cy
+STR_706D_PRESIDENT :Prezes
+STR_706E_TYCOON :Magnat
+STR_706F_BUILD_HQ :{BLACK}Budowa Siedziby
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Buduj siedzibę główną / zobacz siedzibę główną
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Zbuduj siedzibę główna w innym miejscu za cenę 1% wartości firmy
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Nie można zbudować siedziby firmy...
+STR_7072_VIEW_HQ :{BLACK}Zobacz SG
+STR_RELOCATE_HQ :{BLACK}PrzenieÅ› SG
+STR_COMPANY_PASSWORD :{BLACK}Hasło
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Ochrona hasłem Twojej firmy zapobiega nieautoryzowanemu przyłączeniu się
+STR_SET_COMPANY_PASSWORD :Ustaw hasło firmy
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}Åšwiatowa recesja!{}{}Eksperci finansowi obawiajÄ… siÄ™ najgorszego z powodu kryzysu!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Koniec recesji!{}{}Polepszenie się transakcji handlowych daje pewność przedsiębiorstwom dzięki umacniającej się ekonomii!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Przełącz duży/mały rozmiar okna
+STR_7076_COMPANY_VALUE :{GOLD}Wartość firmy: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Kup 25% udziałów w firmie
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Sprzedaj 25% udziałów w firmie
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Kup 25% udziałów w tej firmie
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Sprzedaj 25% udziałów tej firmy
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Nie można kupić 25% udziałów w tej firmie...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}nie można sprzedać 25% udziałów tej firmy...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% w posiadaniu przez {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% w posiadaniu przez {COMPANY}{} {COMMA}% w posiadaniu przez {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} zostało przejęte przez {COMPANY}!
+STR_7080_PROTECTED :{WHITE}Ta firma jeszcze nie sprzedaje akcji...
+
+STR_LIVERY_DEFAULT :Standardowy wyglÄ…d
+STR_LIVERY_STEAM :Parowóz
+STR_LIVERY_DIESEL :Lokomotywa spalinowa
+STR_LIVERY_ELECTRIC :Lokomotywa elektryczna
+STR_LIVERY_MONORAIL :Lokomotywa jednoszynowa
+STR_LIVERY_MAGLEV :Lokomotywa MagLev
+STR_LIVERY_DMU :DMU
+STR_LIVERY_EMU :EMU
+STR_LIVERY_PASSENGER_WAGON_STEAM :Wagon pasażerski (parowóz)
+STR_LIVERY_PASSENGER_WAGON_DIESEL :Wagon pasażerski (spalinowy)
+STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Wagon pasażerski (elektryczny)
+STR_LIVERY_FREIGHT_WAGON :Wagon towarowy
+STR_LIVERY_BUS :Autobus
+STR_LIVERY_TRUCK :Ciężarówka
+STR_LIVERY_PASSENGER_SHIP :Prom pasażerski
+STR_LIVERY_FREIGHT_SHIP :Statek towarowy
+STR_LIVERY_HELICOPTER :Helikopter
+STR_LIVERY_SMALL_PLANE :Mały samolot
+STR_LIVERY_LARGE_PLANE :Duży samolot
+
+STR_LIVERY_GENERAL_TIP :{BLACK}Pokaż ogólne schematy koloru
+STR_LIVERY_TRAIN_TIP :{BLACK}Pokaż schematy koloru pociągów
+STR_LIVERY_ROADVEH_TIP :{BLACK}Pokaż schematy koloru samochodów
+STR_LIVERY_SHIP_TIP :{BLACK}Pokaż schematy koloru statków
+STR_LIVERY_AIRCRAFT_TIP :{BLACK}Pokaż schematy koloru samolotów
+STR_LIVERY_PRIMARY_TIP :{BLACK}Wybierz pierwszy kolor dla wybranego schematu
+STR_LIVERY_SECONDARY_TIP :{BLACK}Wybierz drugi kolor dla wybranego schematu
+STR_LIVERY_PANEL_TIP :{BLACK}Wybierz schemat kolorów do zmiany, albo wiele schematów z CTRL+klik. Kliknij na okienku aby wł./wył. używanie schematu.
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (Parowóz)
+STR_8001_MJS_250_DIESEL :MJS 250 (Diesel)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut Diesel
+STR_8006_POWERNAUT_DIESEL :Powernaut Diesel
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (Parowóz)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (Parowóz)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (Parowóz)
+STR_800A_SH_8P_STEAM :SH '8P' (Parowóz)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (Diesel)
+STR_800C_DASH_DIESEL :'Dash' (Diesel)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (Diesel)
+STR_800E_UU_37_DIESEL :UU '37' (Diesel)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (Diesel)
+STR_8010_CS_4000_DIESEL :CS 4000 (Diesel)
+STR_8011_CS_2400_DIESEL :CS 2400 (Diesel)
+STR_8012_CENTENNIAL_DIESEL :Centennial (Diesel)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (Diesel)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (Diesel)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (Diesel)
+STR_8016_SH_125_DIESEL :SH '125' (Diesel)
+STR_8017_SH_30_ELECTRIC :SH '30' (Elektrowóz)
+STR_8018_SH_40_ELECTRIC :SH '40' (Elektrowóz)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (Elektrowóz)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (Elektrowóz)
+STR_801B_PASSENGER_CAR :Wagon pasażerski
+STR_801C_MAIL_VAN :Wagon pocztowy
+STR_801D_COAL_CAR :Wagon na węgiel
+STR_801E_OIL_TANKER :Cysterna
+STR_801F_LIVESTOCK_VAN :Wagon na żywiec
+STR_8020_GOODS_VAN :Wagon towarowy
+STR_8021_GRAIN_HOPPER :Wagon na ziarno
+STR_8022_WOOD_TRUCK :Wagon na drewno
+STR_8023_IRON_ORE_HOPPER :Wagon na rudę żelaza
+STR_8024_STEEL_TRUCK :Wagon na stal
+STR_8025_ARMORED_VAN :Wagon opancerzony
+STR_8026_FOOD_VAN :Wagon na żywność
+STR_8027_PAPER_TRUCK :Wagon na papier
+STR_8028_COPPER_ORE_HOPPER :Wagon na rude miedzi
+STR_8029_WATER_TANKER :Cysterna na wodÄ™
+STR_802A_FRUIT_TRUCK :Wagon na owoce
+STR_802B_RUBBER_TRUCK :Wagon na kauczuk
+STR_802C_SUGAR_TRUCK :Wagon na cukier
+STR_802D_COTTON_CANDY_HOPPER :Wagon na watÄ™ cukrowÄ…
+STR_802E_TOFFEE_HOPPER :Wagon na Toffi
+STR_802F_BUBBLE_VAN :Wagon na bÄ…belki
+STR_8030_COLA_TANKER :Cysterna na cole
+STR_8031_CANDY_VAN :Wagon na cukierki
+STR_8032_TOY_VAN :Wagon na zabawki
+STR_8033_BATTERY_TRUCK :Wagon na baterie
+STR_8034_FIZZY_DRINK_TRUCK :Wagon na napoje gazowane
+STR_8035_PLASTIC_TRUCK :Wagon na plastik
+STR_8036_X2001_ELECTRIC :'X2001' (Elektrowóz)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Elektrowóz)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :Wagon pasażerski
+STR_803A_MAIL_VAN :Wagon pocztowy
+STR_803B_COAL_CAR :Wagon na węgiel
+STR_803C_OIL_TANKER :Cysterna
+STR_803D_LIVESTOCK_VAN :Wagon na żywiec
+STR_803E_GOODS_VAN :Wagon towarowy
+STR_803F_GRAIN_HOPPER :Wagon na ziarno
+STR_8040_WOOD_TRUCK :Wagon na drewno
+STR_8041_IRON_ORE_HOPPER :Wagon na rudę żelaza
+STR_8042_STEEL_TRUCK :Wagon na stal
+STR_8043_ARMORED_VAN :Wagon opancerzony
+STR_8044_FOOD_VAN :Wagon na żywność
+STR_8045_PAPER_TRUCK :Wagon na papier
+STR_8046_COPPER_ORE_HOPPER :Wagon na rude miedzi
+STR_8047_WATER_TANKER :Cysterna na wodÄ™
+STR_8048_FRUIT_TRUCK :Wagon na owoce
+STR_8049_RUBBER_TRUCK :Wagon na kauczuk
+STR_804A_SUGAR_TRUCK :Wagon na cukier
+STR_804B_COTTON_CANDY_HOPPER :Wagon na watÄ™ cukrowÄ…
+STR_804C_TOFFEE_HOPPER :Wagon na Toffi
+STR_804D_BUBBLE_VAN :Wagon na bÄ…belki
+STR_804E_COLA_TANKER :Cysterna na Cole
+STR_804F_CANDY_VAN :Wagon na cukierki
+STR_8050_TOY_VAN :Wagon na zabawki
+STR_8051_BATTERY_TRUCK :Wagon na baterie
+STR_8052_FIZZY_DRINK_TRUCK :Wagon na napoje gazowane
+STR_8053_PLASTIC_TRUCK :Wagon na plastik
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (Elektrowóz)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (Elektrowóz)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (Elektrowóz)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (Elektrowóz)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :Wagon pasażerski
+STR_805A_MAIL_VAN :Wagon pocztowy
+STR_805B_COAL_CAR :Wagon na węgiel
+STR_805C_OIL_TANKER :Cysterna
+STR_805D_LIVESTOCK_VAN :Wagon na żywiec
+STR_805E_GOODS_VAN :Wagon towarowy
+STR_805F_GRAIN_HOPPER :Wagon na ziarno
+STR_8060_WOOD_TRUCK :Wagon na drewno
+STR_8061_IRON_ORE_HOPPER :Wagon na rudę żelaza
+STR_8062_STEEL_TRUCK :Wagon na stal
+STR_8063_ARMORED_VAN :Wagon opancerzony
+STR_8064_FOOD_VAN :Wagon na żywność
+STR_8065_PAPER_TRUCK :Wagon na papier
+STR_8066_COPPER_ORE_HOPPER :Wagon na rude miedzi
+STR_8067_WATER_TANKER :Cysterna na wodÄ™
+STR_8068_FRUIT_TRUCK :Wagon na owoce
+STR_8069_RUBBER_TRUCK :Wagon na kauczuk
+STR_806A_SUGAR_TRUCK :Wagon na cukier
+STR_806B_COTTON_CANDY_HOPPER :Wagon na watÄ™ cukrowÄ…
+STR_806C_TOFFEE_HOPPER :Wagon na Toffi
+STR_806D_BUBBLE_VAN :Wagon na bÄ…belki
+STR_806E_COLA_TANKER :Cysterna na Cole
+STR_806F_CANDY_VAN :Wagon na cukierki
+STR_8070_TOY_VAN :Wagon na zabawki
+STR_8071_BATTERY_TRUCK :Wagon na baterie
+STR_8072_FIZZY_DRINK_TRUCK :Wagon na napoje gazowane
+STR_8073_PLASTIC_TRUCK :Wagon na plastik
+STR_8074_MPS_REGAL_BUS :Autobus MPS Regal
+STR_8075_HEREFORD_LEOPARD_BUS :Autobus Hereford Leopard
+STR_8076_FOSTER_BUS :Autobus Foster
+STR_8077_FOSTER_MKII_SUPERBUS :Foster MkII Superbus
+STR_8078_PLODDYPHUT_MKI_BUS :Autobus Ploddyphut MkI
+STR_8079_PLODDYPHUT_MKII_BUS :Autobus Ploddyphut MkII
+STR_807A_PLODDYPHUT_MKIII_BUS :Autobus Ploddyphut MkIII
+STR_807B_BALOGH_COAL_TRUCK :Ciężarówka na węgiel Balogh
+STR_807C_UHL_COAL_TRUCK :Ciężarówka na węgiel Uhl
+STR_807D_DW_COAL_TRUCK :Ciężarówka na węgiel DW
+STR_807E_MPS_MAIL_TRUCK :Ciężarówka pocztowa MPS
+STR_807F_REYNARD_MAIL_TRUCK :Ciężarówka pocztowa Reynard
+STR_8080_PERRY_MAIL_TRUCK :Ciężarówka pocztowa Perry
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :Ciężarówka pocztowa na MightyMover
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Ciężarówka pocztowa Powernaught
+STR_8083_WIZZOWOW_MAIL_TRUCK :Ciężarówka pocztowa Wizzowow
+STR_8084_WITCOMBE_OIL_TANKER :Cysterna Witcombe
+STR_8085_FOSTER_OIL_TANKER :Cysterna Foster
+STR_8086_PERRY_OIL_TANKER :Cysterna Perry
+STR_8087_TALBOTT_LIVESTOCK_VAN :Ciężarówka na żywiec Talbott
+STR_8088_UHL_LIVESTOCK_VAN :Ciężarówka na żywiec Uhl
+STR_8089_FOSTER_LIVESTOCK_VAN :Ciężarówka na żywiec Foster
+STR_808A_BALOGH_GOODS_TRUCK :Ciężarówka towarowy Balogh
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Ciężarówka towarowa Craighead
+STR_808C_GOSS_GOODS_TRUCK :Ciężarówka towarowa Goss
+STR_808D_HEREFORD_GRAIN_TRUCK :Ciężarówka na ziarno Hereford
+STR_808E_THOMAS_GRAIN_TRUCK :Ciężarówka na ziarno Thomas
+STR_808F_GOSS_GRAIN_TRUCK :Ciężarówka na ziarno Goss
+STR_8090_WITCOMBE_WOOD_TRUCK :Ciężarówka na drewno Witcombe
+STR_8091_FOSTER_WOOD_TRUCK :Ciężarówka na drewno Foster
+STR_8092_MORELAND_WOOD_TRUCK :Ciężarówka na drewno Moreland
+STR_8093_MPS_IRON_ORE_TRUCK :Ciężarówka na rudę żelaza MPS
+STR_8094_UHL_IRON_ORE_TRUCK :Ciężarówka na rudę żelaza Uhl
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Ciężarówka na rudę żelaza Chippy
+STR_8096_BALOGH_STEEL_TRUCK :Ciężarówka na stal Balogh
+STR_8097_UHL_STEEL_TRUCK :Ciężarówka na stal Uhl
+STR_8098_KELLING_STEEL_TRUCK :Ciężarówka na stal Kelling
+STR_8099_BALOGH_ARMORED_TRUCK :Ciężarówka opancerzona Balogh
+STR_809A_UHL_ARMORED_TRUCK :Ciężarówka opancerzona Uhl
+STR_809B_FOSTER_ARMORED_TRUCK :Ciężarówka opancerzona Foster
+STR_809C_FOSTER_FOOD_VAN :Ciężarówka na żywność Foster
+STR_809D_PERRY_FOOD_VAN :Ciężarówka na żywność Perry
+STR_809E_CHIPPY_FOOD_VAN :Ciężarówka na żywność Chippy
+STR_809F_UHL_PAPER_TRUCK :Ciężarówka na papier Uhl
+STR_80A0_BALOGH_PAPER_TRUCK :Ciężarówka na papier Balogh
+STR_80A1_MPS_PAPER_TRUCK :Ciężarówka na papier MPS
+STR_80A2_MPS_COPPER_ORE_TRUCK :Ciężarówka na rudę miedzi MPS
+STR_80A3_UHL_COPPER_ORE_TRUCK :Ciężarówka na rudę miedzi Uhl
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Ciężarówka na rudę miedzi Goss
+STR_80A5_UHL_WATER_TANKER :Cysterna na wodÄ™ Uhl
+STR_80A6_BALOGH_WATER_TANKER :Cysterna na wodÄ™ Balogh
+STR_80A7_MPS_WATER_TANKER :Cysterna na wodÄ™ MPS
+STR_80A8_BALOGH_FRUIT_TRUCK :Ciężarówka na owoce Balogh
+STR_80A9_UHL_FRUIT_TRUCK :Ciężarówka na owoce Uhl
+STR_80AA_KELLING_FRUIT_TRUCK :Ciężarówka na owoce Kelling
+STR_80AB_BALOGH_RUBBER_TRUCK :Ciężarówka na kauczuk Balogh
+STR_80AC_UHL_RUBBER_TRUCK :Ciężarówka na kauczuk Uhl
+STR_80AD_RMT_RUBBER_TRUCK :Ciężarówka na kauczuk RMT
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :Ciężarówka na cukier MightyMover
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Ciężarówka na cukier Powernaught
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Ciężarówka do cukier Wizzowow
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :Cysterna na ColÄ™ MightyMover
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Cysterna na ColÄ™ Powernaught
+STR_80B3_WIZZOWOW_COLA_TRUCK :Cysterna na ColÄ™ Wizzowow
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :Ciężarówka na watę cukrową MightyMover
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Ciężarówka na watę cukrową Powernaught
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Ciężarówka na watę cukrową Wizzowow
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :Ciężarówka na Toffi MightyMover
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Ciężarówka na Toffi Powernaught
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Ciężarówka na Toffi Wizzowow
+STR_80BA_MIGHTYMOVER_TOY_VAN :Ciężarówka na zabawki MightyMover
+STR_80BB_POWERNAUGHT_TOY_VAN :Ciężarówka na zabawki Powernaught
+STR_80BC_WIZZOWOW_TOY_VAN :Ciężarówka na zabawki Wizzowow
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :Ciężarówka na cukierki MightyMover
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Ciężarówka na cukierki Powernaught
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Ciężarówka na cukierki Wizzowow
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :Ciężarówka na baterie MightyMover
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Ciężarówka na baterie Powernaught
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Ciężarówka na baterie Wizzowow
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :Cysterna na napoje gazowane MightyMover
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Cysterna na napoje gazowane Powernaught
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Cysterna na napoje gazowane Wizzowow
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :Ciężarówka na plastik MightyMover
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Ciężarówka na plastik Powernaught
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Ciężarówka na plastik Wizzowow
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :Ciężarówka na bąbelki MightyMover
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Ciężarówka na bąbelki Powernaught
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Ciężarówka do bąbelki Wizzowow
+STR_80CC_MPS_OIL_TANKER :Tankowiec MPS
+STR_80CD_CS_INC_OIL_TANKER :Tankowiec CS-Inc.
+STR_80CE_MPS_PASSENGER_FERRY :Liniowiec MPS
+STR_80CF_FFP_PASSENGER_FERRY :Liniowiec FFP
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Wodolot Bakewell 300
+STR_80D1_CHUGGER_CHUG_PASSENGER :Liniowiec Chugger-Chug
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Liniowiec Shivershake
+STR_80D3_YATE_CARGO_SHIP :Drobnicowiec Yate
+STR_80D4_BAKEWELL_CARGO_SHIP :Drobnicowiec Bakewell
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Drobnicowiec MightyMover
+STR_80D6_POWERNAUT_CARGO_SHIP :Drobnicowiec Powernaut
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Helikopter Tricario
+STR_80FE_GURU_X2_HELICOPTER :Helikopter Guru X2
+STR_80FF_POWERNAUT_HELICOPTER :Helikopter Powernaut
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Wiadomość od producenta pojazdów
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}Właśnie zaprojektowaliśmy now{G y ą e} {STRING.b} - czy jesteś zainteresowany w rocznej wyłączności na użycie tego pojazdu, żebyśmy mogli zobaczyć przed wypuszczeniem na rynek jak się sprawuje?
+STR_8102_RAILROAD_LOCOMOTIVE :{G=f}lokomotywa
+STR_8102_RAILROAD_LOCOMOTIVE.b :{G=f}lokomotywÄ™
+STR_8103_ROAD_VEHICLE :{G=m}samochód
+STR_8103_ROAD_VEHICLE.b :{G=m}samochód
+STR_8104_AIRCRAFT :{G=m}samolot
+STR_8104_AIRCRAFT.b :{G=m}samolot
+STR_8105_SHIP :{G=m}statek
+STR_8105_SHIP.b :{G=m}statek
+STR_8106_MONORAIL_LOCOMOTIVE :{G=f}lokomotywa jednoszynowa
+STR_8106_MONORAIL_LOCOMOTIVE.b :{G=f}lokomotywÄ™ jednoszynowÄ…
+STR_8107_MAGLEV_LOCOMOTIVE :{G=f}lokomotywa MagLev
+STR_8107_MAGLEV_LOCOMOTIVE.b :{G=f}lokomotywÄ™ MagLev
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}Zajezdnia w {TOWN}
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Mieszkańcy świętują . . .{}Pierwszy pociąg przybył do {STATION}!
+STR_8802_DETAILS :{WHITE}{STRING} (Szczegóły)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}PociÄ…g na drodze
+STR_8804 :{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8806_GO_TO :Idź do {STATION}
+STR_8807_GO_TO_TRANSFER :Idź do {STATION} (Przewieź i weź towar)
+STR_8808_GO_TO_UNLOAD :Idź do {STATION} (Wyładunek)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Idź do {STATION} (Przewieź i nie bierz towaru)
+STR_880A_GO_TO_LOAD :Idź do {STATION} (Załadunek)
+STR_880B_GO_TO_TRANSFER_LOAD :Idź do {STATION} (Przewieź i czekaj na pełen załadunek)
+STR_880C_GO_NON_STOP_TO :Idź bez zatrzymywania do {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Idź bez zatrzymywania do {STATION} (Przewieź i weź towar)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Idź bez zatrzymywania do {STATION} (Wyładunek)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Idź bez zatrzymywania do {STATION} (Przewieź i nie bierz towaru)
+STR_8810_GO_NON_STOP_TO_LOAD :Idź bez zatrzymywania do {STATION} (Załadunek)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Idź bez zatrzymywania do {STATION} (Przewieź i czekaj na pełen załadunek)
+STR_GO_TO_TRAIN_DEPOT :Idź do zajezdni w {TOWN}
+STR_SERVICE_AT_TRAIN_DEPOT :Serwisuj w zajezdni w {TOWN}
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Idź bez zatrzymywania do zajezdni w {TOWN}
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Idź bez zatrzymywania do serwisu w zajezdni w {TOWN}
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}Zmierza do zajezdni w {TOWN}
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}Zmierza do zajezdni w {TOWN}, {VELOCITY}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE :{LTBLUE}Serwisuj w Zajezdni w {TOWN}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE_VEL :{LTBLUE}Serwisuj w Zajezdni w {TOWN}, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (Błędne polecenie)
+
+STR_UNKNOWN_DESTINATION :nieznany cel
+STR_8812_EMPTY :{LTBLUE}Pusty
+STR_8813_FROM :{LTBLUE}{CARGO} z {STATION}
+STR_FROM_MULT :{LTBLUE}{CARGO} z {STATION} (x{NUM})
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}PociÄ…g {COMMA} czeka w zajezdni
+STR_8815_NEW_VEHICLES :{BLACK}Nowe pojazdy
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Pociąg jest zbyt długi
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Pociąg może być modyfikowany tylko gdy jest zatrzymany w zajezdni
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} Pociąg{P "" i ów}
+
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Nowe pociÄ…gi
+STR_NEW_ELRAIL_VEHICLES :{WHITE}Nowe lokomotywy elektryczne
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Nowe pociÄ…gi jednoszynowe
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Nowe pociÄ…gi MagLev
+STR_ALL_AVAIL_RAIL_VEHICLES :{WHITE}PociÄ…gi
+
+STR_881F_BUILD_VEHICLE :{BLACK}Buduj pojazd
+STR_CLONE_ROAD_VEHICLE :{BLACK}Klonuj pojazd
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}Spowoduje zbudowanie kopii pojazdu. CTRL+klik spowoduje współdzielenie poleceń
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Spowoduje zbudowanie kopii pojazdu. Kliknij na przycisk a następnie na pojazd wewnątrz lub na zewnątrz zajezdni. CTRL+klik spowoduje współdzielenie poleceń
+STR_CLONE_TRAIN :{BLACK}Klonuj pociÄ…g
+STR_CLONE_TRAIN_INFO :{BLACK}Spowoduje wybudowanie kopii pociągu wraz ze wszystkimi wagonami. CTRL+klik spowoduje współdzielenie poleceń
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}Spowoduje wybudowanie kopii pociągu wraz z wszystkimi wagonami. Kliknij na przycisk a następnie na pociąg wewnątrz lub na zewnątrz zajezdni. CTRL+klik spowoduje współdzielenie poleceń
+STR_8820_RENAME :{BLACK}Zmień nazwę
+STR_8823_SKIP :{BLACK}Pomiń
+STR_8824_DELETE :{BLACK}Usuń
+STR_8825_NON_STOP :{BLACK}Non-Stop
+STR_8826_GO_TO :{BLACK}Idź do
+STR_8827_FULL_LOAD :{BLACK}Załadunek
+STR_8828_UNLOAD :{BLACK}Wyładunek
+STR_REFIT :{BLACK}Przebuduj
+STR_REFIT_TIP :{BLACK}Wybierz do przewozu jakiego towaru przebudować pojazd w tym zadaniu. CTRL+klik usuwa polecenie przebudowy
+STR_REFIT_ORDER :(Przebuduj na {STRING})
+STR_8829_ORDERS :{WHITE}{VEHICLE} (Polecenia)
+STR_882A_END_OF_ORDERS :{SETX 10}- - Koniec poleceń - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}Serwis
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Nie można wybudować lokomotywy...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Budowa: {LTBLUE}{NUM}{BLACK} Wartość: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Wartość: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}Załadunek / Wyładunek
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}Pociąg musi być zatrzymany w zajezdni
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Nie można wysłać pociągu do zajezdni...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Brak miejsca na polecenia
+STR_8832_TOO_MANY_ORDERS :{WHITE}Zbyt wiele poleceń
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Nie można wstawić polecenia...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Nie można usunąć tego polecenia...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Nie można zmodyfikować tego polecenia...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Nie można ruszyć pojazdem...
+STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}Tylna lokomotywa zawsze porusza siÄ™ razem z przedniÄ…
+STR_8838_N_A :N/D{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Nie można sprzedać lokomotywy...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Nie można znaleźć drogi do zajezdni.
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Nie można zatrzymać/ruszyć pociagu...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Okres między serwisowaniem: {LTBLUE}{COMMA}dni{BLACK} Ostatni serwis: {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Okres między serwisowaniem: {LTBLUE}{COMMA}%{BLACK} Ostatni serwis: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Pociągi - klik na pojeździe aby uzyskać informacje
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Budowa nowych pociągów (wymaga zajezdni)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Pociągi - klik na pociągu po info, przeciągnij pojazd/wagon aby dodać
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Buduj nowy pociÄ…g
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Przeciągnij tutaj pociąg aby go sprzedać
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centrowanie głównego okna na pozycji zajezdni
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Lista wyboru pociągów - klik na pojeździe aby uzyskać informacje
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Zbuduj wybrany pojazd
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Zmiana nazwy typu pociÄ…gu
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Obecny stan pociągu - klik tutaj aby zatrzymać/ruszyć pociąg
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Pokaż polecenia dla pociągu
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centrowanie głównego okna na pozycji pociągu
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Wyślij pociąg do zajezdni
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Wymuszony start pociągu bez czekania na sygnał
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Odwróć kierunek jazdy pociągu
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Pokaż szczegóły pociągu
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Zwiększ okres między serwisowaniem
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Zmniejsz okres między serwisowaniem
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Pokaż szczegóły przewożonych towarów
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Pokaż szczegóły pociągu
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Pokaż pojemność każdego wagonu
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Pokaż całkowitą pojemność pociągu, według typu ładunku
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Lista poleceń - klik na poleceniu aby zaznaczyć. CTRL + klik przenosi do stacji
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}Pomiń obecne polecenie i zacznij następne
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Usuń podświetlone polecenie
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Zrób z tego polecenia 'non-stop'
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Wstaw nowe polecenie na końcu listy lub przed zaznaczonym poleceniem
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Spraw aby zaznaczone polecenie zmusiło pojazd do czekania na pełny załadunek
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Spraw aby zaznaczone polecenie zmusiło pojazd do wyładunku
+STR_SERVICE_HINT :{BLACK}Pomiń to polecenie jesli serwis nie jest wymagany
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}Dostępna nowa {STRING}!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Koszt: {CURRENCY} Waga: {WEIGHT_S}{}Prędkość: {VELOCITY} Moc: {POWER}{}Utrzymanie: {CURRENCY}/rok{}Pojemność: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}Awaria
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}Wiek: {LTBLUE}{STRING}{BLACK} Utrzymanie: {LTBLUE}{CURRENCY}/rok
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Waga: {LTBLUE}{WEIGHT_S} {BLACK}Moc: {LTBLUE}{POWER}{BLACK} Max. prędkość: {LTBLUE}{VELOCITY}
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Waga: {LTBLUE}{WEIGHT_S} {BLACK}Moc: {LTBLUE}{POWER}{BLACK} Max. prędkość: {LTBLUE}{VELOCITY} {BLACK}Max. S.P.: {LTBLUE}{FORCE}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Zysk w tym roku: {LTBLUE}{CURRENCY} (w ostatnim roku: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}Niezawodność: {LTBLUE}{COMMA}% {BLACK}Awarie od ostatniego serwisowania: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Zatrzymany
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Nie można przepościć pociągu za sygnał, niebezpieczeństwo...
+STR_8863_CRASHED :{RED}Wypadek!
+
+STR_8865_NAME_TRAIN :{WHITE}Nazwa pociÄ…gu
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}Nie można zmienić nazwy pociągu...
+STR_8867_NAME_TRAIN :{BLACK}Nazwa pociÄ…gu
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Wypadek kolejowy!{}{COMMA} ofiar{P a y ""} w kolizji
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Nie można odwrócić kierunku jazdy pociągu...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Zmiana nazwy typu pociÄ…gu
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Nie można zmienić nazwy typu pojazdu...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Spraw by w zaznaczonym poleceniu pojazd był zmuszony do pozostawienia towaru dla kolejnego pojazdu
+STR_886F_TRANSFER :{BLACK}Przewieź
+
+STR_TRAIN_STOPPING :{RED}Hamowanie
+STR_TRAIN_STOPPING_VEL :{RED}Hamowanie, {VELOCITY}
+STR_INCOMPATIBLE_RAIL_TYPES :Niezgodne typy szyn
+STR_TRAIN_NO_POWER :{RED}Brak zasilania
+STR_TRAIN_START_NO_CATENARY :Ta trasa nie jest zelektryfikowana, wiec pociÄ…g nie wystartuje
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Samochód na drodze
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} Samoch{P ód ody odów}
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE} Zajezdnia samochodowa w {TOWN}
+STR_9004_NEW_VEHICLES :{BLACK}Nowe pojazdy
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}Nowy Samochód
+STR_9007_BUILD_VEHICLE :{BLACK}Zbuduj pojazd
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Nie można zbudować samochodu...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (Szczegóły)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}Wiek: {LTBLUE}{STRING}{BLACK} Utrzymanie: {LTBLUE}{CURRENCY}/rok
+STR_900E_MAX_SPEED :{BLACK}Max. prędkość: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Zysk w tym roku: {LTBLUE}{CURRENCY} (ostatni rok: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}Niezawodność: {LTBLUE}{COMMA}% {BLACK}Awarie od ostatniego serwisowania: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Zbudowany: {LTBLUE}{NUM}{BLACK} Wartość: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Pojemność: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}...musi być zatrzymany w zajezdni samochodowej
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Nie można sprzedać samochodu...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Nie można zatrzymać/ruszyć samochodu...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}Samochód {COMMA} czeka w zajezdni
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}Zmierza do zajezdni sam. w {TOWN}
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}Zmierza do zajezdni sam. w {TOWN}, {VELOCITY}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE :{LTBLUE}Serwisuj w Zajezdni w {TOWN}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE_VEL :{LTBLUE}Serwisuj w Zajezdni w {TOWN}, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Nie można wysłać samochodu do zajezdni...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Nie można znaleźć zajezdni
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Samochody - klik na pojeździe po więcej informacji
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Zbuduj nowe samochody (wymaga zajezdni)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Obecny stan pojazdu - klik tutaj aby zatrzymać/ruszyć pojazd
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Pokaż polecenia pojazdu
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Centruj główne okno na pozycji pojazdu
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Wyślij pojazd do zajezdni
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Zmuś pojazd do zawrócenia
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Pokaż detale samochodu
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Pojazdy - klik na pojeździe po więcej informacji
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Zbuduj nowy samochód
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Przeciągnij tutaj samochód aby go sprzedać
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Centruj główne okno na pozycji zajezdni samochodowej
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Lista wyboru samochodów - klik na pojeździe po więcej informacji
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Zbuduj wybrany samochód
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}Dostępny nowy samochód!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Koszt: {CURRENCY}{}Prędkość: {VELOCITY}{}Utrzymanie: {CURRENCY}/rok{}Pojemność: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Nazwij samochód
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Nie można nazwać samochodu...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Nazwij samochód
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Mieszkańcy świętują . . .{}Pierwszy autobus przybył do {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Mieszkańcy świętują . . .{}Pierwsza ciężarówka przybyła do {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}Wypadek samochodowy!{}Kierowca zginÄ…Å‚ w zderzeniu z pociÄ…giem
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}Wypadek samochodowy!{}{COMMA} ofiar{P a y ""} zderzenia z pociÄ…giem
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Nie można zawrócić samochodu...
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}Nie można obracać pociągów z podwójnymi lokomotywami
+STR_9034_RENAME :{BLACK}Zmień nazwę
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Zmień nazwę typu samochodu
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Zmień nazwę typu samochodu
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Nie można zmienić nazwy typu samochodu...
+STR_9038_GO_TO_ROADVEH_DEPOT :Idź do zajezdni sam. w {TOWN}
+STR_SERVICE_AT_ROADVEH_DEPOT :Serwisuj w zajezdni sam. w {TOWN}
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Przebudowa samochodu do przewozu innego typu towaru
+STR_REFIT_ROAD_VEHICLE :{BLACK}Przebudowa samochodu
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Przebuduj samochód do przewozu zaznaczonego typu towaru
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Nie można przebudować samochodu...
+STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Wybierz ładunek jaki ma przewozić ten samochód
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Konstrukcje portowe
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Konstrukcje portowe
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Nie można tutaj wybudować portu...
+STR_9803_SHIP_DEPOT :{WHITE}Stocznia w {TOWN}
+STR_9804_NEW_SHIPS :{BLACK}Nowe statki
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} Stat{P ek ki ów}
+STR_9808_NEW_SHIPS :{WHITE}Nowe statki
+STR_9809_BUILD_SHIP :{BLACK}Budowa statku
+STR_CLONE_SHIP :{BLACK}Klonuj statek
+STR_CLONE_SHIP_INFO :{BLACK}Spowoduje wybudowanie kopii statku. Control+klik spowoduje współdzielenie poleceń
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}Spowoduje wybudowanie kopii statku. Kliknij na przycisk a następnie na statek wewnątrz lub na zewnątrz stoczni. Control+klik spowoduje współdzielenie poleceń
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}Statek musi być zatrzymany w stoczni
+STR_980C_CAN_T_SELL_SHIP :{WHITE}Nie można sprzedać statku...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Nie można wybudować statku...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Statek na drodze
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Szczegóły)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}Wiek: {LTBLUE}{STRING}{BLACK} Utrzymanie: {LTBLUE}{CURRENCY}/rok
+STR_9813_MAX_SPEED :{BLACK}Max. prędkość: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Zysk w tym roku: {LTBLUE}{CURRENCY} (w ostatnim roku: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}Niezawodność: {LTBLUE}{COMMA}% {BLACK}Awarie od ostatniego serwisowania: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Wybudowany: {LTBLUE}{NUM}{BLACK} Wartość: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}Pojemność: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}Nie można zatrzymać/ruszyć statku...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Nie można wysłać statku do stoczni...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Nie można znaleźć stoczni
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}Zmierza do stoczni w {TOWN}
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}Zmierza do stoczni w {TOWN}, {VELOCITY}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE :{LTBLUE}Serwisuj w Stoczni w {TOWN}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE_VEL :{LTBLUE}Serwisuj w Stoczni w {TOWN}, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}Statek {COMMA} czeka w stoczni
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Budowa portu
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Budowa stoczni (do budowy i serwisowania statków)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Statki - kliknij aby uzyskać informacje o statku
+STR_9820_BUILD_NEW_SHIP :{BLACK}Budowa nowego statku
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Przeciągnij tutaj statek aby go sprzedać
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centruj główne okno na pozycji stoczni
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Statki - kliknij aby uzyskać informacje o statku
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Budowa nowych statków (wymaga stoczni)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}Lista wyboru statków - klik na statku aby uzyskać informacje
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Zbuduj wybrany statek
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Obecny stan statku - klik aby zatrzymać/ruszyć statek
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Pokaż polecenia statku
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centruj główne okno na pozycji statku
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Wyślij statek do stoczni
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Pokaż szczegóły statku
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}Dostępny nowy statek!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Koszt: {CURRENCY} Max. Prędkość: {VELOCITY}{}Pojemność: {CARGO}{}Utrzymanie: {CURRENCY}/rok
+STR_982F_NAME_SHIP :{BLACK}Nazwa statku
+
+STR_9831_NAME_SHIP :{WHITE}Nazwa statku
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Nie można zmienić nazwy statku...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Mieszkańcy świętują . . .{}Pierwszy statek przybył do {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Ustaw boję, która może być użyta jako punkt kontrolny
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Nie można tutaj ustawić boi...
+STR_9836_RENAME :{BLACK}Zmień nazwę
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Zmień nazwę typu statku
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Zmień nazwę typu statku
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Nie można zmienić nazwy typu statku...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Przebudowa statku do przewozu innego typu towaru
+STR_983B_REFIT :{WHITE}{VEHICLE} (Przebudowa)
+STR_983C_REFIT_SHIP :{BLACK}Przebudowa statku
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Wybierz jaki ładunek ma przewozić statek
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Przebuduj statek do przewozu zaznaczonego typu towaru
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Wybierz typ Å‚adunku do przewozu:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nowa pojemność: {GOLD}{CARGO}{}{BLACK}Koszt przebudowy: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Nie można przebudować statku...
+STR_9842_REFITTABLE :(przebudowalny)
+STR_GO_TO_SHIP_DEPOT :Idź do stoczni w {TOWN}
+SERVICE_AT_SHIP_DEPOT :Serwisuj w stoczni w {TOWN}
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Lotniska
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Nie można tutaj wybudować lotniska...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}Hangar na {STATION}
+STR_A003_NEW_AIRCRAFT :{BLACK}Nowy samolot
+STR_CLONE_AIRCRAFT :{BLACK}Klonuj samolot
+STR_CLONE_AIRCRAFT_INFO :{BLACK}Spowoduje wybudowanie kopii samolotu. Control+klik spowoduje współdzielenie poleceń
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Spowoduje wybudowanie kopii samolotu. Kliknij na przycisk a następnie na samolot wewnątrz lub na zewnątrz hangaru. Control+klik spowoduje współdzielenie poleceń
+STR_A005_NEW_AIRCRAFT :{WHITE}Nowy samolot
+STR_A006_BUILD_AIRCRAFT :{BLACK}Budowa samolotu
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Nie można zbudować samolotu...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} Samolot
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (Polecenia)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (Szczegóły)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Wiek: {LTBLUE}{STRING}{BLACK} Utrzymanie: {LTBLUE}{CURRENCY}/rok
+STR_A00E_MAX_SPEED :{BLACK}Max. prędkość: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Zysk w tym roku: {LTBLUE}{CURRENCY} (w ostatnim roku: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}Niezawodność: {LTBLUE}{COMMA}% {BLACK}Awarie od ostatniego serwisowania: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Zbudowany: {LTBLUE}{NUM}{BLACK} Wartość: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Nie można wysłać samolotu do hangaru...
+STR_HEADING_FOR_HANGAR :{ORANGE}Zmierza do hangaru w {STATION}
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}Zmierza do hangaru w {STATION}, {VELOCITY}
+STR_HEADING_FOR_HANGAR_SERVICE :{LTBLUE}Serwisuj w Hangarze na {STATION}
+STR_HEADING_FOR_HANGAR_SERVICE_VEL :{LTBLUE}Serwisuj w Hangarze na {STATION}, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}Samolot {COMMA} czeka w hangarze
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Samolot jest na drodze
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Nie można zatrzymać/ruszyć samolotu
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Samolot jest w locie
+STR_A019_CAPACITY :{BLACK}Pojemność: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Pojemność: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}Samolot musi być zatrzymany w hangarze
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Nie można sprzedać samolotu...
+STR_A01D_AIRPORT_CONSTRUCTION :Konstrukcje lotnicze
+STR_A01E_BUILD_AIRPORT :{BLACK}Budowa lotniska
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Samolot - klik na samolocie aby uzyskać informacje
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Budowa samolotu (wymaga lotniska z hangarem)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Samolot - klik na samolocie aby uzyskać informacje
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Budowa nowego samolotu
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}Przeciągnij tutaj samolot aby go sprzedać
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Centruj główne okno na pozycji hangaru
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Lista wyboru samolotów - klik na samolocie aby uzyskać informacje
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Zbuduj wybrany samolot
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Obecny stan samolotu - klik aby zatrzymać/ruszyć samolot
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Pokaż polecenia samolotu
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Centruj główne okno na pozycji samolotu
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Wyślij samolot do hangaru
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Pokaż szczegóły samolotu
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}Dostępny nowy samolot!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Koszt: {CURRENCY} Max. Prędkość: {VELOCITY}{}Pojemność: {COMMA} pasażerów, {COMMA} paczek poczty{}Utrzymanie: {CURRENCY}/rok
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Nazwa samolotu
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Nie można zmienić nazwy samolotu...
+STR_A032_NAME_AIRCRAFT :{BLACK}Nazwa samolotu
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Mieszkańcy świętują . . .{}Pierwszy samolot przyleciał na {STATION}!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Katastrofa lotnicza!{}{COMMA} ofiar{P a y ""} na {STATION}
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Wypadek lotniczy!{}Samolot rozbił się z powodu braku paliwa, zginęło {COMMA} osób!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Zmień nazwę
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Zmień nazwę typu samolotu
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Zmień nazwę typu samolotu
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Nie można zmienić nazwy typu samolotu...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Przebudowa samolotu do przewozu innego typu towaru
+STR_A03C_REFIT :{WHITE}{VEHICLE} (Przebudowa)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Przebudowa samolotu
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Wybierz jaki ładunek ma przenosić samolot
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Przebuduj samolot do przewozu zaznaczonego typu towaru
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Wybierz typ towaru do przewozu:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nowa pojemność: {GOLD}{STRING}{}{BLACK}Koszt przebudowy: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Nie można przebudować samolotu...
+STR_GO_TO_AIRPORT_HANGAR :Idź do hangaru na {STATION}
+SERVICE_AT_AIRPORT_HANGAR :Serwisuj w hangarze na {STATION}
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}Katastrofa Zeppelina na {STATION}!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Samochód zniszczony w kolizji z 'UFO'!
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}Eksplozja rafinerii blisko {TOWN}!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}Fabryka zniszczona w podejrzanych okolicznościach w pobliżu {TOWN}!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}'UFO' wylądowało blisko {TOWN}!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}Tąpnięcie przy kopalni pozostawiło pas zniszczenia blisko {TOWN}!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Powódź!{}Przynajmniej {COMMA} zaginęło lub utonęło w czasie powodzi!
+
+STR_BRIBE_FAILED :{WHITE}Twoja próba wręczenia łapówki została
+STR_BRIBE_FAILED_2 :{WHITE}wykryta przez lokalnych badaczy.
+STR_BUILD_DATE :{BLACK}Zbudowano: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Szczegóły oceny działalności
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}Szczegóły
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Pojazdy:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Min. zysk:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Min. przychód:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Maks. przychód:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Przewieziono:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Towar:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}PieniÄ…dze:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Pożyczka:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}ÅÄ…cznie:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Liczba pojazdów. Ujęte są pociągi, samochody, statki i samoloty.
+STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}Liczba stacji. Wliczany jest każdy element stacji (np. dworzec, przystanek, lotnisko), nawet jeśli są połączone w jedną stację
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}Minimalny zysk spośród wszystkich pojazdów, które mają conajmniej 2 lata.
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Ilość pieniędzy zarobiona w miesiącu z najmniejszym zyskiem w ostatnich 12 kwartałach
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Ilość pieniędzy zarobiona w miesiącu z największym zyskiem w ostatnich 12 kwartałach
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}Ilość towaru przewieziona w poprzednich 4 kwartałach
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}Ilość rożnych towarów przewiezionych w ostatnim kwartale
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Ilość pieniędzy w ręku
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}Wielkość pożyczki wziętej przez firmę
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Suma przyznanych punktów
+
+STR_NEWGRF_SETTINGS_BUTTON :{BLACK}Ustawienia NewGRF
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}Ustawienia NewGRF
+STR_NEWGRF_APPLY_CHANGES :{BLACK}Zastosuj zmiany
+STR_NEWGRF_SET_PARAMETERS :{BLACK}Ustaw parametry
+STR_NEWGRF_TIP :{BLACK}Lista plików NewGRF jakie są zainstalowane. Kliknij na ustawienia aby zmienić
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}Obecnie nie ma zainstalowanych żadnych plików NewGRF! Proszę sprawdzić instrukcję jak zainstalować nowe grafiki
+STR_NEWGRF_FILENAME :{BLACK}Nazwa pliku: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
+STR_NEWGRF_MD5SUM :{BLACK}suma MD5: {SILVER}{STRING}
+STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}Zamierzasz wprowadzić zmiany do gry w toku; to może zawiesić OpenTTD.{}Czy jesteś całkowicie pewien?
+
+STR_NEWGRF_ADD :{BLACK}Dodaj
+STR_NEWGRF_ADD_TIP :{BLACK}Dodaj plik NewGRF do listy
+STR_NEWGRF_REMOVE :{BLACK}Usuń
+STR_NEWGRF_REMOVE_TIP :{BLACK}Usuń zaznaczony plik NewGRF z listy
+STR_NEWGRF_MOVEUP :{BLACK}Do góry
+STR_NEWGRF_MOVEUP_TIP :{BLACK}Przesuń zaznaczony plik NewGRF w górę listy
+STR_NEWGRF_MOVEDOWN :{BLACK}Na dół
+STR_NEWGRF_MOVEDOWN_TIP :{BLACK}Przesuń zaznaczony plik NewGRF na dół listy
+STR_NEWGRF_FILE_TIP :{BLACK}Lista zainstalowanych plików NewGRF. Kliknij na pliku aby zmienić jego parametry
+STR_NEWGRF_PARAMETER :{BLACK}Parametry: {SILVER}{STRING}
+STR_NEWGRF_PARAMETER_QUERY :{BLACK}Wprowadź parametry NewGRF
+STR_NEWGRF_NO_INFO :{BLACK}Brak dostępnych informacji
+
+STR_NEWGRF_ADD_CAPTION :{WHITE}Dostępne pliki NewGRF
+STR_NEWGRF_ADD_FILE :{BLACK}Dodaj do listy
+STR_NEWGRF_ADD_FILE_TIP :{BLACK}Dodaj zaznaczony plik NewGRF do Twojego ustawienia
+STR_NEWGRF_RESCAN_FILES :{BLACK}Przeskanuj pliki
+STR_NEWGRF_RESCAN_FILES_TIP :{BLACK}Odśwież listę dostępnych plików NewGRF
+STR_NEWGRF_DUPLICATE_GRFID :{WHITE}Nie można dodać pliku: taki sam GRF ID
+
+STR_NEWGRF_NOT_FOUND :{RED}Nie znaleziono pasujÄ…cego pliku
+STR_NEWGRF_DISABLED :{RED}Niedostępny
+
+STR_CURRENCY_WINDOW :{WHITE}WÅ‚asna waluta
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Współczynnik wymiany: {ORANGE}{CURRENCY} = £ {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Separator:
+STR_CURRENCY_PREFIX :{LTBLUE}Prefiks:
+STR_CURRENCY_SUFFIX :{LTBLUE}Sufiks:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Przejście na Euro: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Przejście na Euro: {ORANGE}nigdy
+STR_CURRENCY_PREVIEW :{LTBLUE}PodglÄ…d: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Zmień parametr własnej waluty
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} Pociąg{P "" i ów}
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} Samoch{P ód ody odów}
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} Samolot{P "" y ów}
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} Stat{P ek ki ków}
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Pokazuje wszystkie pociągi, które mają tę stację w swoim rozkładzie
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Pokazuje wszystkie samochody, ktore majÄ… tÄ™ stacjÄ™ w swoim rozkladzie
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Pokazuje wszystkie samoloty, ktore majÄ… tÄ™ stacjÄ™ w swoim rozkladzie
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Pokazuje wszystkie statki, ktore majÄ… tÄ™ stacjÄ™ w swoim rozkladzie
+
+STR_VEH_WITH_SHARED_ORDERS_LIST :{WHITE}Wspoldzielone polecenia {COMMA} pojazd{P u ow ow}
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}Pokaż wszystkie pojazdy współdzielące te polecenia
+
+### depot strings
+STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Sprzedasz wszystkie pojazdy z zajezdni. JesteÅ› pewien?
+
+STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP :{BLACK}Sprzedaj wszystkie pociÄ…gi z zajezdni
+STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP :{BLACK}Sprzedaj wszystkie samochody z zajezdni
+STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP :{BLACK}Sprzedaj wszystkie statki ze stoczni
+STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP :{BLACK}Sprzedaj wszystkie samoloty z hangaru
+
+STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP :{BLACK}Pokaż listę wszystkich pociągów z tą zajezdnia w swoich poleceniach
+STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP :{BLACK}Pokaż listę wszystkich samochodów z tą zajezdnia w swoich poleceniach
+STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP :{BLACK}Pokaż listę wszystkich statków z tą stocznia w swoich poleceniach
+STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP :{BLACK}Pokaż listę wszystkich samolotów z hangarem na tym lotnisku w swoich poleceniach
+
+STR_DEPOT_AUTOREPLACE_TRAIN_TIP :{BLACK}Zamień wszystkie pociągi w zajezdni
+STR_DEPOT_AUTOREPLACE_ROADVEH_TIP :{BLACK}Zamień wszystkie samochody w zajezdni
+STR_DEPOT_AUTOREPLACE_SHIP_TIP :{BLACK}Zamień wszystkie statki w stoczni
+STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP :{BLACK}Zamień wszystkie samoloty w hangarze
+
+STR_VEHICLE_LIST_TRAIN_DEPOT :{BLACK}{STRING} - {COMMA} Pociąg{P "" i ów}
+STR_VEHICLE_LIST_ROADVEH_DEPOT :{BLACK}{STRING} - {COMMA} Samoch{P ód ody odów}
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} Stat{P ek ki ków}
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} Samolot{P "" y ów}
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}ZastÄ…p {STRING}
+STR_REPLACE_VEHICLES_START :{BLACK}Rozpocznij zastępowanie
+STR_REPLACE_VEHICLES_STOP :{BLACK}Zatrzymaj zastępowanie
+STR_NOT_REPLACING :{BLACK}Nie zastępowane
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Brak zaznaczonych pojazdów
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Wybierz typ pojazdu do zamiany
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Wybierz typ pojazdu jakim chcesz zastąpić pojazd zaznaczony po lewej stronie
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Wciśnij ten przycisk jeśli nie chcesz zmieniać pojazdu zaznaczone po lewej stronie
+STR_REPLACE_HELP_START_BUTTON :{BLACK}Naciśnij jeśli chcesz zastąpić pojazd zaznaczony po lewej stronie wybranym pojazdem po prawej stronie
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Wybierz dla jakiego typu szyn chcesz zastąpić pojazdy
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Wyświetla typ pojazdu na jaki będzie zastąpiony pojazd zaznaczony po lewej stronie
+STR_REPLACE_HELP :{BLACK}Ta funkcja pozwala zastąpić pojazd innym. Będzie się to odbywać w momencie gdy pociąg zjedzie do zajezdni
+STR_REPLACE_REMOVE_WAGON :{BLACK}Usunięcie wagonów: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Autowymiana zachowuje długość pociągu poprzez usuwanie wagonów (począwszy od początku), jeśli wymiana lokomotywy spowoduje wydłużenie pociągu.
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}Zastępowanie: {ORANGE}{SKIP}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} EKSPERYMENTALNE NARZEDZIE {}Przejdź pomiędzy oknami zamiany lokomotyw i wagonów.{}Wymiana wagonu nastąpi tylko jeśli nowy wagon może być przebudowany do przewożenia tego samego towaru co poprzedni. Każdy wagon pociągu jest sprawdzany podczas procesu zamiany.
+STR_ENGINE_NOT_BUILDABLE :{WHITE}Lokomotywa nie może być zbudowana
+
+STR_ENGINES :Lokomotywy
+STR_WAGONS :Wagony
+
+STR_MASS_STOP_DEPOT_TRAIN_TIP :{BLACK}Kliknij aby zatrzymać wszystkie pociągi w zajezdni
+STR_MASS_STOP_DEPOT_ROADVEH_TIP :{BLACK}Kliknij aby zatrzymać wszystkie samochody w zajezdni
+STR_MASS_STOP_DEPOT_SHIP_TIP :{BLACK}Kliknij aby zatrzymać wszystkie statki w stoczni
+STR_MASS_STOP_HANGAR_TIP :{BLACK}Kliknij aby zatrzymać wszystkie samoloty w hangarze
+
+STR_MASS_START_DEPOT_TRAIN_TIP :{BLACK}Kliknij aby wystartować wszystkie pociągi w zajezdni
+STR_MASS_START_DEPOT_ROADVEH_TIP :{BLACK}Kliknij aby wystartować wszystkie samochody w zajezdni
+STR_MASS_START_DEPOT_SHIP_TIP :{BLACK}Kliknij aby wystartować wszystkie statki w stoczni
+STR_MASS_START_HANGAR_TIP :{BLACK}Kliknij aby wystartować wszystkie samoloty w hangarze
+
+STR_MASS_STOP_LIST_TIP :{BLACK}Kliknij aby zatrzymać wszystkie pojazdy na liście
+STR_MASS_START_LIST_TIP :{BLACK}Kliknij aby wystartować wszystkie pojazdy na liście
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}Lista tablic - {COMMA} Tablice
+
+STR_ORDER_REFIT_FAILED :{WHITE}Niepowodzenie zadania przebudowy zatrzymało {STRING} {COMMA}
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :Kolej
+STR_ELRAIL_VEHICLES :Kolej elektryczna
+STR_MONORAIL_VEHICLES :Kolej jednoszynowa
+STR_MAGLEV_VEHICLES :Kolej Maglev
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Koszt: {GOLD}{CURRENCY}{BLACK} Waga: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Prędkość: {GOLD}{VELOCITY}{BLACK} Moc: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}Prędkość: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Koszty użytkowania: {GOLD}{CURRENCY}/rok
+STR_PURCHASE_INFO_CAPACITY :{BLACK}Pojemność: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Zaprojektowany: {GOLD}{NUM}{BLACK} Żywotność: {GOLD}{COMMA} lat
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}Maksymalna niezawodność: {GOLD}{COMMA}%
+STR_PURCHASE_INFO_COST :{BLACK}Koszt: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Waga: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Koszt: {GOLD}{CURRENCY}{BLACK} Prędkość: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Pojemność: {GOLD}{COMMA} pasażerów, {COMMA} paczek poczty
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Moc: {GOLD}+{POWER}{BLACK} Waga: {GOLD}+{WEIGHT_S}
+STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Można przebudować na: {GOLD}
+STR_PURCHASE_INFO_ALL_TYPES :Wszystkie typy towarów
+STR_PURCHASE_INFO_ALL_BUT :Wszystko oprócz {GOLD}}
+STR_PURCHASE_INFO_MAX_TE :{BLACK}Max. Siła Pociągowa: {GOLD}{FORCE}
+
+########### String for New Landscape Generator
+
+STR_GENERATE :{WHITE}Stwórz
+STR_RANDOM :{BLACK}Losuj
+STR_RANDOM_HELP :{BLACK}Zmień losowy numer używany przy tworzeniu terenu
+STR_WORLD_GENERATION_CAPTION :{WHITE}Tworzenie świata
+STR_RANDOM_SEED :{BLACK}Losowy numer:
+STR_RANDOM_SEED_HELP :{BLACK}Kliknij aby wpisać losowy numer
+STR_LAND_GENERATOR :{BLACK}Generator terenu:
+STR_TREE_PLACER :{BLACK}Algorytm drzew:
+STR_HEIGHTMAP_ROTATION :{BLACK}Obrót mapy wysokości:
+STR_TERRAIN_TYPE :{BLACK}Typ terenu:
+STR_QUANTITY_OF_SEA_LAKES :{BLACK}Poziom wody:
+STR_SMOOTHNESS :{BLACK}Gładkość:
+STR_SNOW_LINE_HEIGHT :{BLACK}Wysokość śniegu:
+STR_DATE :{BLACK}Data:
+STR_NUMBER_OF_TOWNS :{BLACK}Ilość miast:
+STR_NUMBER_OF_INDUSTRIES :{BLACK}Ilość przedsiębiorstw
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_SNOW_LINE_UP :{BLACK}Podnieś wysokość śniegu o jeden w górę
+STR_SNOW_LINE_DOWN :{BLACK}Obniż wysokość śniegu o jeden w dół
+STR_SNOW_LINE_QUERY_CAPT :{WHITE}Zmień wysokość śniegu
+STR_START_DATE_QUERY_CAPT :{WHITE}Zmień datę rozpoczęcia
+STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Ostrzeżenie o skali
+STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Nie zaleca się zbyt dużej zmiany wielkości mapy źrodłowej. Kontynuować tworzenie?
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_HEIGHTMAP_NAME :{BLACK}Nazwa mapy wysokosci:
+STR_HEIGHTMAP_SIZE :{BLACK}Rozmiar: {ORANGE}{NUM} x {NUM}
+STR_GENERATION_WORLD :{WHITE}Tworzenie świata...
+STR_GENERATION_ABORT :{BLACK}Przerwij
+STR_GENERATION_ABORT_CAPTION :{WHITE}Przerwij tworzenie świata
+STR_GENERATION_ABORT_MESSAGE :{YELLOW}Czy na pewno chcesz przerwać tworzenie?
+STR_PROGRESS :{WHITE}gotowe w {NUM} %
+STR_GENERATION_PROGRESS :{BLACK}{NUM} / {NUM}
+STR_WORLD_GENERATION :{BLACK}Tworzenie świata
+STR_TREE_GENERATION :{BLACK}Tworzenie drzew
+STR_UNMOVABLE_GENERATION :{BLACK}Tworzenie obiektów
+STR_CLEARING_TILES :{BLACK}Generowanie skał i nierowności
+STR_SETTINGUP_GAME :{BLACK}Ustawianie gry
+STR_PREPARING_TILELOOP :{BLACK}Uaktywnianie pól
+STR_PREPARING_GAME :{BLACK}Przygotowywanie gry
+STR_DIFFICULTY_TO_CUSTOM :{WHITE}Ta akcja zmieniła poziom trudności na "własny"
+STR_SE_FLAT_WORLD :{WHITE}Płaski świat
+STR_SE_FLAT_WORLD_TIP :{BLACK}Stwórz płaski świat
+STR_SE_RANDOM_LAND :{WHITE}Losowy teren
+STR_SE_NEW_WORLD :{BLACK}Stwórz nowy scenariusz
+STR_SE_CAPTION :{WHITE}Typ scenariusza
+STR_FLAT_WORLD_HEIGHT_DOWN :{BLACK}Obniż wysokość terenu o jeden w dół
+STR_FLAT_WORLD_HEIGHT_UP :{BLACK}Podnieś wysokość terenu o jeden w górę
+STR_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Zmień wysokość płaskiego świata
+STR_FLAT_WORLD_HEIGHT :{BLACK}Wysokość płaskiego świata:
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+STR_SMALLMAP_CENTER :{BLACK}Wyśrodkuj mapę na aktualnej lokalizacji
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}Małe
+STR_CITY_AIRPORT :{BLACK}Miejskie
+STR_METRO_AIRPORT :{BLACK}Stołeczne
+STR_INTERNATIONAL_AIRPORT :{BLACK}Międzynarodowe
+STR_COMMUTER_AIRPORT :{BLACK}Lokalne
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Międzykontynentalne
+STR_HELIPORT :{BLACK}Klasyczne
+STR_HELIDEPOT :{BLACK}Serwisowe
+STR_HELISTATION :{BLACK}Stacja
+
+STR_SMALL_AIRPORTS :{BLACK}Małe lotniska
+STR_LARGE_AIRPORTS :{BLACK}Duże lotniska
+STR_HUB_AIRPORTS :{BLACK}Główne lotniska
+STR_HELIPORTS :{BLACK}LÄ…dowiska
+
+############ Tooltip measurment
+
+STR_MEASURE_LENGTH :{BLACK}Długość: {NUM}
+STR_MEASURE_AREA :{BLACK}Obszar: {NUM} x {NUM}
+STR_MEASURE_LENGTH_HEIGHTDIFF :{BLACK}Długość: {NUM}{}Różnica wysokości: {NUM} m
+STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}Obszar: {NUM} x {NUM}{}Różnica wysokości: {NUM} m
+
+########
diff --git a/src/lang/portuguese.txt b/src/lang/portuguese.txt
new file mode 100644
index 000000000..3d500b654
--- /dev/null
+++ b/src/lang/portuguese.txt
@@ -0,0 +1,3116 @@
+##name Portuguese
+##ownname Português
+##isocode pt_PT.UTF-8
+##plural 0
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Fora da borda do mapa
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Muito perto da borda do mapa
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Dinheiro insuficiente - necessário {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}É necessário terreno plano
+STR_0008_WAITING :{BLACK}Em espera: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (em rota de
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Aceita: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Aceita: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :Passageiros
+STR_0010_COAL :Carvão
+STR_0011_MAIL :Correio
+STR_0012_OIL :Petróleo
+STR_0013_LIVESTOCK :Gado
+STR_0014_GOODS :Bens
+STR_0015_GRAIN :Cereais
+STR_0016_WOOD :Madeira
+STR_0017_IRON_ORE :Minério de Ferro
+STR_0018_STEEL :Aço
+STR_0019_VALUABLES :Valores
+STR_001A_COPPER_ORE :Minério de Cobre
+STR_001B_MAIZE :Milho
+STR_001C_FRUIT :Fruta
+STR_001D_DIAMONDS :Diamantes
+STR_001E_FOOD :Comida
+STR_001F_PAPER :Papel
+STR_0020_GOLD :Ouro
+STR_0021_WATER :Ãgua
+STR_0022_WHEAT :Trigo
+STR_0023_RUBBER :Borracha
+STR_0024_SUGAR :Açúcar
+STR_0025_TOYS :Brinquedos
+STR_0026_CANDY :Doces
+STR_0027_COLA :Cola
+STR_0028_COTTON_CANDY :Algodão Doce
+STR_0029_BUBBLES :Bolhas
+STR_002A_TOFFEE :Caramelo
+STR_002B_BATTERIES :Baterias
+STR_002C_PLASTIC :Plástico
+STR_002D_FIZZY_DRINKS :Bebidas Gasosas
+STR_002E :
+STR_002F_PASSENGER :Passageiro
+STR_0030_COAL :Carvão
+STR_0031_MAIL :Correio
+STR_0032_OIL :Petróleo
+STR_0033_LIVESTOCK :Gado
+STR_0034_GOODS :Bens
+STR_0035_GRAIN :Cereais
+STR_0036_WOOD :Madeira
+STR_0037_IRON_ORE :Minério de Ferro
+STR_0038_STEEL :Aço
+STR_0039_VALUABLES :Valores
+STR_003A_COPPER_ORE :Minério de Cobre
+STR_003B_MAIZE :Milho
+STR_003C_FRUIT :Fruta
+STR_003D_DIAMOND :Diamantes
+STR_003E_FOOD :Comida
+STR_003F_PAPER :Papel
+STR_0040_GOLD :Ouro
+STR_0041_WATER :Ãgua
+STR_0042_WHEAT :Trigo
+STR_0043_RUBBER :Borracha
+STR_0044_SUGAR :Açúcar
+STR_0045_TOY :Brinquedos
+STR_0046_CANDY :Doces
+STR_0047_COLA :Cola
+STR_0048_COTTON_CANDY :Algodão Doce
+STR_0049_BUBBLE :Bolhas
+STR_004A_TOFFEE :Caramelo
+STR_004B_BATTERY :Baterias
+STR_004C_PLASTIC :Plástico
+STR_004D_FIZZY_DRINK :Bebidas Gasosas
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} passageiro{P "" s}
+STR_QUANTITY_COAL :{WEIGHT} de carvão
+STR_QUANTITY_MAIL :{COMMA} saco{P "" s} de correio
+STR_QUANTITY_OIL :{VOLUME} de petróleo
+STR_QUANTITY_LIVESTOCK :{COMMA} ite{P m ns} de gado
+STR_QUANTITY_GOODS :{COMMA} caixa{P "" s} de bens
+STR_QUANTITY_GRAIN :{WEIGHT} de cereais
+STR_QUANTITY_WOOD :{WEIGHT} de madeira
+STR_QUANTITY_IRON_ORE :{WEIGHT} de minério de ferro
+STR_QUANTITY_STEEL :{WEIGHT} de aço
+STR_QUANTITY_VALUABLES :{COMMA} saco{P "" s} de valores
+STR_QUANTITY_COPPER_ORE :{WEIGHT} de minério de cobre
+STR_QUANTITY_MAIZE :{WEIGHT} de milho
+STR_QUANTITY_FRUIT :{WEIGHT} de fruta
+STR_QUANTITY_DIAMONDS :{COMMA} saco{P "" s} de diamantes
+STR_QUANTITY_FOOD :{WEIGHT} de comida
+STR_QUANTITY_PAPER :{WEIGHT} de papel
+STR_QUANTITY_GOLD :{COMMA} saco{P "" s} de ouro
+STR_QUANTITY_WATER :{VOLUME} de água
+STR_QUANTITY_WHEAT :{WEIGHT} de trigo
+STR_QUANTITY_RUBBER :{VOLUME} de borracha
+STR_QUANTITY_SUGAR :{WEIGHT} de açúcar
+STR_QUANTITY_TOYS :{COMMA} brinquedo{P "" s}
+STR_QUANTITY_SWEETS :{COMMA} saco{P "" s} de doces
+STR_QUANTITY_COLA :{VOLUME} de cola
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} de algodão doce
+STR_QUANTITY_BUBBLES :{COMMA} bolha{P "" s}
+STR_QUANTITY_TOFFEE :{WEIGHT} de caramelo
+STR_QUANTITY_BATTERIES :{COMMA} pilh{P y as}
+STR_QUANTITY_PLASTIC :{VOLUME} de plástico
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} bebida{P "" s} gasosa{P "" s}
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}PS
+STR_ABBREV_COAL :{TINYFONT}CL
+STR_ABBREV_MAIL :{TINYFONT}ML
+STR_ABBREV_OIL :{TINYFONT}OL
+STR_ABBREV_LIVESTOCK :{TINYFONT}LV
+STR_ABBREV_GOODS :{TINYFONT}GD
+STR_ABBREV_GRAIN :{TINYFONT}GR
+STR_ABBREV_WOOD :{TINYFONT}WD
+STR_ABBREV_IRON_ORE :{TINYFONT}OR
+STR_ABBREV_STEEL :{TINYFONT}ST
+STR_ABBREV_VALUABLES :{TINYFONT}VL
+STR_ABBREV_COPPER_ORE :{TINYFONT}CO
+STR_ABBREV_MAIZE :{TINYFONT}MZ
+STR_ABBREV_FRUIT :{TINYFONT}FT
+STR_ABBREV_DIAMONDS :{TINYFONT}DM
+STR_ABBREV_FOOD :{TINYFONT}FD
+STR_ABBREV_PAPER :{TINYFONT}PR
+STR_ABBREV_GOLD :{TINYFONT}GD
+STR_ABBREV_WATER :{TINYFONT}WR
+STR_ABBREV_WHEAT :{TINYFONT}WH
+STR_ABBREV_RUBBER :{TINYFONT}RB
+STR_ABBREV_SUGAR :{TINYFONT}SG
+STR_ABBREV_TOYS :{TINYFONT}TY
+STR_ABBREV_SWEETS :{TINYFONT}SW
+STR_ABBREV_COLA :{TINYFONT}CL
+STR_ABBREV_CANDYFLOSS :{TINYFONT}CF
+STR_ABBREV_BUBBLES :{TINYFONT}BU
+STR_ABBREV_TOFFEE :{TINYFONT}TF
+STR_ABBREV_BATTERIES :{TINYFONT}BA
+STR_ABBREV_PLASTIC :{TINYFONT}PL
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}FZ
+STR_ABBREV_NONE :{TINYFONT}NÃO
+STR_ABBREV_ALL :{TINYFONT}TODOS
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Mapa - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Opções do Jogo
+STR_00B2_MESSAGE :{YELLOW}Mensagem
+STR_00B3_MESSAGE_FROM :{YELLOW}Mensagem de {STRING}
+STR_POPUP_CAUTION_CAPTION :{WHITE}Cuidado!
+STR_00B4_CAN_T_DO_THIS :{WHITE}Não é possível fazer isto....
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Não é possível limpar esta área....
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Copyright original {COPYRIGHT} 1995 Chris Sawyer, Todos os direitos reservados
+STR_00B7_VERSION :{BLACK}OpenTTD versão {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 A equipa do OpenTTD
+STR_TRANSLATED_BY :{BLACK} Tradutor(es) -
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Sair
+STR_00C8_YES :{BLACK}Sim
+STR_00C9_NO :{BLACK}Não
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Tem a certeza que deseja abandonar este jogo e voltar ao {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Nada
+STR_00D1_DARK_BLUE :Azul Escuro
+STR_00D2_PALE_GREEN :Verde Claro
+STR_00D3_PINK :Rosa
+STR_00D4_YELLOW :Amarelo
+STR_00D5_RED :Vermelho
+STR_00D6_LIGHT_BLUE :Azul Claro
+STR_00D7_GREEN :Verde
+STR_00D8_DARK_GREEN :Verde Escuro
+STR_00D9_BLUE :Azul
+STR_00DA_CREAM :Creme
+STR_00DB_MAUVE :Malva
+STR_00DC_PURPLE :Roxo
+STR_00DD_ORANGE :Laranja
+STR_00DE_BROWN :Castanho
+STR_00DF_GREY :Cinzento
+STR_00E0_WHITE :Branco
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Existem muitos veículos em jogo
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Localização
+STR_00E5_CONTOURS :Contornos
+STR_00E6_VEHICLES :Veículos
+STR_00E7_INDUSTRIES :Indústrias
+STR_00E8_ROUTES :Rotas
+STR_00E9_VEGETATION :Vegetação
+STR_00EA_OWNERS :Proprietários
+STR_00EB_ROADS :{BLACK}{TINYFONT}Estradas
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Caminhos-de-ferro
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Estações/Aeroportos/Docas
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Edifícios/Indústrias
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Veículos
+STR_00F0_100M :{BLACK}{TINYFONT}100m
+STR_00F1_200M :{BLACK}{TINYFONT}200m
+STR_00F2_300M :{BLACK}{TINYFONT}300m
+STR_00F3_400M :{BLACK}{TINYFONT}400m
+STR_00F4_500M :{BLACK}{TINYFONT}500m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Comboios
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Veículos de Estrada
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Barcos
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Aeronaves
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Rotas de Transporte
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Mina de Carvão
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Central eléctrica
+STR_00FC_FOREST :{BLACK}{TINYFONT}Floresta
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}Serração
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Refinaria de Petróleo
+STR_00FF_FARM :{BLACK}{TINYFONT}Quinta
+STR_0100_FACTORY :{BLACK}{TINYFONT}Fábrica
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Tipografia
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Poços de Petróleo
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Mina de Ferro
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Siderurgia
+STR_0105_BANK :{BLACK}{TINYFONT}Banco
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Fábrica de Papel
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Mina de Ouro
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Companhia Alimentar
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Mina de Diamantes
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Mina de Cobre
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Plantação de Fruta
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Plantação de Ãrvores da Borracha
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Abastecimento de Ãgua
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Depósito de Ãgua
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}Fábrica de Madeiras
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Floresta de Algodão Doce
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Fábrica de Doces
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Campo de Baterias
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Poços de Cola
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Loja de Brinquedos
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Fábrica de Brinquedos
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Fontes de Plástico
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Fábrica de Bebidas Gasosas
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Produtor de Bolhas
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Extracção de Caramelo
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Mina de Açúcar
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Estação Ferroviária
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Ãrea de Carregamento de Camiões
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Estação de Autocarros
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Aeroporto/Heliporto
+STR_011F_DOCK :{BLACK}{TINYFONT}Doca
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Terreno Irregular
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Terreno de Prados
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Terreno Deserto
+STR_0123_FIELDS :{BLACK}{TINYFONT}Campos
+STR_0124_TREES :{BLACK}{TINYFONT}Ãrvores
+STR_0125_ROCKS :{BLACK}{TINYFONT}Rochas
+STR_0126_WATER :{BLACK}{TINYFONT}Ãgua
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Sem Proprietário
+STR_0128_TOWNS :{BLACK}{TINYFONT}Cidades
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Indústrias
+STR_012A_DESERT :{BLACK}{TINYFONT}Deserto
+STR_012B_SNOW :{BLACK}{TINYFONT}Neve
+STR_012C_MESSAGE :{WHITE}Mensagem
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Cancelar
+STR_012F_OK :{BLACK}OK
+STR_0130_RENAME :{BLACK}Renomear
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Demasiados nomes definidos
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}O nome escolhido já está a ser usado
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :SO/2
+
+STR_013B_OWNED_BY :{WHITE}...propriedade de {STRING}
+STR_013C_CARGO :{BLACK}Carga
+STR_013D_INFORMATION :{BLACK}Informação
+STR_013E_CAPACITIES :{BLACK}Capacidades
+STR_013E_TOTAL_CARGO :{BLACK}Carga Total
+STR_013F_CAPACITY :{BLACK}Capacidade: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}Capacidade: {LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Carga total (capacidade) deste comboio:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}Novo Jogo
+STR_0141_LOAD_GAME :{BLACK}Abrir Jogo
+STR_SINGLE_PLAYER :{BLACK}1 jogador
+STR_MULTIPLAYER :{BLACK}Multi-jogador
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Dimensões do mapa:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Opções do Jogo
+
+STR_0150_SOMEONE :alguém{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Mapa do mundo
+STR_0152_TOWN_DIRECTORY :Lista de cidades
+STR_0153_SUBSIDIES :Subsídios
+
+STR_UNITS_IMPERIAL :Anglo-Saxónico
+STR_UNITS_METRIC :Métrico
+STR_UNITS_SI :Sistema Internacional
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} mph
+STR_UNITS_VELOCITY_METRIC :{COMMA} km/h
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}cv
+STR_UNITS_POWER_METRIC :{COMMA}cv
+STR_UNITS_POWER_SI :{COMMA}kW
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} tonelada{P "" s}
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} tonelada{P "" s}
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} kg
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}gal
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}l
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}m³
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} gal{P ão ões}
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} litro{P "" s}
+STR_UNITS_VOLUME_LONG_SI :{COMMA} m³
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10³ lbf
+STR_UNITS_FORCE_METRIC :{COMMA} ton force
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Benefícios operativos
+STR_0155_INCOME_GRAPH :Rendimentos
+STR_0156_DELIVERED_CARGO_GRAPH :Carga entregue
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Histórico de rendimentos
+STR_0158_COMPANY_VALUE_GRAPH :Valor da empresa
+STR_0159_CARGO_PAYMENT_RATES :Tarifas por carga
+STR_015A_COMPANY_LEAGUE_TABLE :Classificação de empresas
+STR_PERFORMANCE_DETAIL_MENU :Avaliação detalhada
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}Sobre o OpenTTD...
+STR_015C_SAVE_GAME :Guardar jogo
+STR_015D_LOAD_GAME :Abrir jogo
+STR_015E_QUIT_GAME :Abandonar jogo
+STR_015F_QUIT :Sair
+STR_ABANDON_GAME_QUERY :{YELLOW}Tem a certeza que deseja abandonar este jogo?
+STR_0161_QUIT_GAME :{WHITE}Abandonar jogo
+STR_SORT_ORDER_TIP :{BLACK}Seleccione forma de ordenação (descendente/ascendente)
+STR_SORT_CRITERIA_TIP :{BLACK}Seleccione critério de ordenação
+STR_SORT_BY :{BLACK}Ordenar por
+
+STR_SORT_BY_POPULATION :{BLACK}População
+STR_SORT_BY_PRODUCTION :{BLACK}Produção
+STR_SORT_BY_TYPE :{BLACK}Tipo
+STR_SORT_BY_TRANSPORTED :{BLACK}Transportado
+STR_SORT_BY_NAME :{BLACK}Nome
+STR_SORT_BY_DROPDOWN_NAME :Nome
+STR_SORT_BY_DATE :{BLACK}Data
+STR_SORT_BY_NUMBER :Número
+STR_SORT_BY_PROFIT_LAST_YEAR :Lucros do último ano
+STR_SORT_BY_PROFIT_THIS_YEAR :Lucros deste ano
+STR_SORT_BY_AGE :Idade
+STR_SORT_BY_RELIABILITY :Fiabilidade
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Capacidade total por tipo de carga
+STR_SORT_BY_MAX_SPEED :Velocidade máxima
+STR_SORT_BY_MODEL :Modelo
+STR_SORT_BY_VALUE :Valor
+STR_SORT_BY_FACILITY :Tipo de Estação
+STR_SORT_BY_WAITING :Valor da carga em espera
+STR_SORT_BY_RATING_MAX :Avaliação de carga
+STR_ENGINE_SORT_ENGINE_ID :Ordenação clássica
+STR_ENGINE_SORT_COST :Custo
+STR_ENGINE_SORT_POWER :Potência
+STR_ENGINE_SORT_INTRO_DATE :Data de Introdução
+STR_ENGINE_SORT_RUNNING_COST :Custo de circulação
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Potência/Custo de circulação
+STR_ENGINE_SORT_CARGO_CAPACITY :Capacidade de Carga
+STR_NO_WAITING_CARGO :{BLACK}Nenhuma carga em espera
+STR_SELECT_ALL_FACILITIES :{BLACK}Seleccionar todas as acções
+STR_SELECT_ALL_TYPES :{BLACK}Seleccionar todos os tipos de carga (incluindo carga sem espera)
+STR_AVAILABLE_ENGINES_TIP :{BLACK}Ver lista de designs disponíveis de locomotivas para este tipo de veículo.
+STR_MANAGE_LIST :{BLACK}Gerir lista
+STR_MANAGE_LIST_TIP :{BLACK}Enviar instruções a todos os veículos desta lista
+STR_REPLACE_VEHICLES :Substituir Veículos
+STR_SEND_TRAIN_TO_DEPOT :Enviar para Depósito
+STR_SEND_ROAD_VEHICLE_TO_DEPOT :Enviar para Depósito
+STR_SEND_SHIP_TO_DEPOT :Enviar para Depósito
+STR_SEND_AIRCRAFT_TO_HANGAR :Enviar para Hangar
+STR_SEND_FOR_SERVICING :Enviar para Serviço
+
+############ range for months starts
+STR_0162_JAN :Jan
+STR_0163_FEB :Fev
+STR_0164_MAR :Mar
+STR_0165_APR :Abr
+STR_0166_MAY :Mai
+STR_0167_JUN :Jun
+STR_0168_JUL :Jul
+STR_0169_AUG :Ago
+STR_016A_SEP :Set
+STR_016B_OCT :Out
+STR_016C_NOV :Nov
+STR_016D_DEC :Dez
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Pausa
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Guardar jogo, abandonar jogo, sair
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Mostrar lista de estações da empresa
+STR_0174_DISPLAY_MAP :{BLACK}Mostrar mapa
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Mostrar mapa, lista de cidades
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Mostrar lista de cidades
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Mostrar informações financeiras da empresa
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Mostrar informações gerais da empresa
+STR_0179_DISPLAY_GRAPHS :{BLACK}Mostrar gráficos
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Mostrar tabela de classificação de empresas
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Mostrar lista de comboios da empresa
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Mostrar lista de veículos de estrada da empresa
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Mostrar lista de barcos da empresa
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Mostrar lista de aeronaves da empresa
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Ampliar
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Reduzir
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Construir caminhos-de-ferro
+STR_0182_BUILD_ROADS :{BLACK}Construir estradas
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Construir docas para barcos
+STR_0184_BUILD_AIRPORTS :{BLACK}Construir aeroportos
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Plantar árvores, colocar indicações, etc...
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Informações do terreno
+STR_0187_OPTIONS :{BLACK}Opções
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Não é possível alterar o intervalo de serviço...
+STR_018B_CLOSE_WINDOW :{BLACK}Fechar janela
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Título da janela - arraste isto para mover a janela
+STR_STICKY_BUTTON :{BLACK}Marcar esta janela como não-encerrável pela tecla 'Fechar Todas as Janelas'
+STR_RESIZE_BUTTON :{BLACK}Clique e arraste para reajustar janela
+STR_SAVELOAD_HOME_BUTTON :{BLACK}Carregue aqui para saltar para a directoria de gravação/carregamento por defeito
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Demolir edifícios, etc. num quadrado de terreno
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Baixar um canto do terreno
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Levantar um canto do terreno
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Barra de rolamento - rola a lista acima/abaixo
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Barra de deslize - desloca a lista para a esquerda/direita
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Mostrar contornos do terreno no mapa
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Mostrar veículos no mapa
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Mostrar indústrias no mapa
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Mostrar rotas de transporte no mapa
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Mostrar vegetação no mapa
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Mostrar proprietários do terreno no mapa
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Mostrar nomes das cidades no mapa
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Lucro deste ano: {CURRENCY} (último ano: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} ano{P "" s} ({COMMA})
+STR_AGE_RED :{RED}{COMMA} ano{P "" s} ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Veículo de estrada
+STR_019D_AIRCRAFT :Aeronave
+STR_019E_SHIP :Barco
+STR_019F_TRAIN :Comboio
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} está a ficar velho
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} está a ficar muito velho
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} está a ficar muito velho e necessita de ser substituído urgentemente
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Informações do Terreno
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Custo para limpar: {LTBLUE}N/D
+STR_01A5_COST_TO_CLEAR :{BLACK}Custo para limpar: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :N/D
+STR_01A7_OWNER :{BLACK}Proprietário: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Autoridade local: {LTBLUE}{STRING}
+STR_01A9_NONE :Nenhum
+STR_01AA_NAME :{BLACK}Nome
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1
+STR_01AD_2ND :2
+STR_01AE_3RD :3
+STR_01AF_4TH :4
+STR_01B0_5TH :5
+STR_01B1_6TH :6
+STR_01B2_7TH :7
+STR_01B3_8TH :8
+STR_01B4_9TH :9
+STR_01B5_10TH :10
+STR_01B6_11TH :11
+STR_01B7_12TH :12
+STR_01B8_13TH :13
+STR_01B9_14TH :14
+STR_01BA_15TH :15
+STR_01BB_16TH :16
+STR_01BC_17TH :17
+STR_01BD_18TH :18
+STR_01BE_19TH :19
+STR_01BF_20TH :20
+STR_01C0_21ST :21
+STR_01C1_22ND :22
+STR_01C2_23RD :23
+STR_01C3_24TH :24
+STR_01C4_25TH :25
+STR_01C5_26TH :26
+STR_01C6_27TH :27
+STR_01C7_28TH :28
+STR_01C8_29TH :29
+STR_01C9_30TH :30
+STR_01CA_31ST :31
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Carga aceite: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Jazz Jukebox
+STR_01D3_SOUND_MUSIC :Som/música
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Mostrar janela som/música
+STR_01D5_ALL :{TINYFONT}Todos
+STR_01D6_OLD_STYLE :{TINYFONT}Antigo
+STR_01D7_NEW_STYLE :{TINYFONT}Moderno
+STR_01D8_EZY_STREET :{TINYFONT}Ezy Street
+STR_01D9_CUSTOM_1 :{TINYFONT}Personaliz. 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Personaliz. 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Volume da Música
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Volume dos efeitos
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MIN ' ' ' ' ' ' MAX
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Mudar para a faixa anterior da selecção
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Mudar para a faixa seguinte da selecção
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Parar a reprodução de música
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Iniciar reprodução de música
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Arraste os cursores para ajustar o volume da música e efeitos sonoros
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}'{STRING}'
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Faixa{SETX 88}Título
+STR_01E9_SHUFFLE :{TINYFONT}Baralhar
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Programa
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Programação Musical
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} '{STRING}'
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} '{STRING}'
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Ãndice de faixas
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Programa - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}Limpar
+STR_01F1_SAVE :{TINYFONT}{BLACK}Guardar
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Programa actual de faixas de música
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Seleccionar programa 'todas as faixas'
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Seleccionar programa 'estilo antigo'
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Seleccionar programa 'estilo moderno'
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Seleccionar programa 'Personalizado 1'
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Seleccionar programa 'Personalizado 2'
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Limpar programa actual (somente Personaliz. 1 ou Personaliz. 2)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Gravar configuração de música
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Clique na faixa de música para a adicionar ao programa actual (somente Personaliz. 1 ou Personaliz. 2)
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Faça clique numa faixa para a remover da lista (Personaliz. 1 ou Personaliz. 2 apenas)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Ligar/Desligar programa aleatório
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Mostrar janela de selecção de faixas de música
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Clique num serviço para centrar a visualização numa indústria/cidade
+STR_01FE_DIFFICULTY :{BLACK}Dificuldade ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Última mensagem/notícia
+STR_0201_MESSAGE_SETTINGS :Opções de mensagens
+STR_MESSAGE_HISTORY_MENU :Histórico de Mensagens
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Mostrar última mensagem/notícia, mostrar opções de mensagens
+STR_0204_MESSAGE_OPTIONS :{WHITE}Opções de Mensagens
+STR_0205_MESSAGE_TYPES :{BLACK}Tipos de mensagens:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Chegada do primeiro veículo à estação do jogador
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Chegada do primeiro veículo à estação de um oponente
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Acidentes / desastres
+STR_0209_COMPANY_INFORMATION :{YELLOW}Informações da empresa
+STR_020A_ECONOMY_CHANGES :{YELLOW}Alterações económicas
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Avisos / informações dos veículos do jogador
+STR_020C_NEW_VEHICLES :{YELLOW}Novos veículos
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Alterações de aceitação de carga
+STR_020E_SUBSIDIES :{YELLOW}Subsídios
+STR_020F_GENERAL_INFORMATION :{YELLOW}Informações gerais
+STR_MESSAGES_ALL :{YELLOW}Configuração para todos os tipos de mensagens (ligado/desligado/resumo)
+STR_MESSAGE_SOUND :{YELLOW}Alerta sonoro para resumos de mensagens noticiosas
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...Muito distante do destino anterior
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Top de companhias que chegaram a {NUM}{}({STRING} Nivél)
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Tabela de Liga de Companhias em {NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Negociante
+STR_0214_ENTREPRENEUR :Empresário
+STR_0215_INDUSTRIALIST :Industrial
+STR_0216_CAPITALIST :Capitalista
+STR_0217_MAGNATE :Magnate
+STR_0218_MOGUL :Grande magnate
+STR_0219_TYCOON_OF_THE_CENTURY :Magnate do século
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} conquista '{STRING}' desempenho!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} de {COMPANY} conquista '{STRING}' desempenho!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Criar Cenário
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Editor de Cenário
+STR_0223_LAND_GENERATION :{WHITE}Gerar Terreno
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Terreno Aleatório
+STR_0227_RESET_LAND :{BLACK}Repor Terreno
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Aumentar área de terreno a baixar/levantar
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Diminuir área de terreno a baixar/levantar
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Gerar terreno aleatório
+STR_022B_RESET_LANDSCAPE :{BLACK}Repor terreno
+STR_022C_RESET_LANDSCAPE :{WHITE}Repor Terreno
+STR_LOAD_GAME_HEIGHTMAP :{WHITE}Usar mapa de alturas
+STR_LOAD_SCEN_HEIGHTMAP :{BLACK}Usar mapa de alturas
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Tem a certeza que deseja repor o terreno?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}A gerar terreno
+STR_022F_TOWN_GENERATION :{BLACK}A gerar cidades
+STR_0230_INDUSTRY_GENERATION :{BLACK}A gerar indústrias
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Construir estradas
+STR_0233_TOWN_GENERATION :{WHITE}Gerar Cidades
+STR_0234_NEW_TOWN :{BLACK}Nova Cidade
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Construir nova cidade
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Não é possível construir uma cidade aqui...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...muito perto da borda do mapa
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...muito perto de outra cidade
+STR_0239_SITE_UNSUITABLE :{WHITE}...sítio inadequado
+STR_023A_TOO_MANY_TOWNS :{WHITE}...demasiadas cidades
+STR_CANNOT_GENERATE_TOWN :{WHITE}Não é possível construir cidades
+STR_NO_SPACE_FOR_TOWN :{WHITE}...não existe mais espaço no mapa
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Aumentar o tamanho da cidade
+STR_023C_EXPAND :{BLACK}Expandir
+STR_023D_RANDOM_TOWN :{BLACK}Cidade Aleatória
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Construir uma cidade num local aleatório
+STR_023F_INDUSTRY_GENERATION :{WHITE}Gerar Indústrias
+STR_0240_COAL_MINE :{BLACK}Mina de Carvão
+STR_0241_POWER_STATION :{BLACK}Central Eléctrica
+STR_0242_SAWMILL :{BLACK}Serração
+STR_0243_FOREST :{BLACK}Floresta
+STR_0244_OIL_REFINERY :{BLACK}Refinaria de Petróleo
+STR_0245_OIL_RIG :{BLACK}Plataforma Petrolífera
+STR_0246_FACTORY :{BLACK}Fábrica
+STR_0247_STEEL_MILL :{BLACK}Siderurgia
+STR_0248_FARM :{BLACK}Quinta
+STR_0249_IRON_ORE_MINE :{BLACK}Mina de Ferro
+STR_024A_OIL_WELLS :{BLACK}Poços de Petróleo
+STR_024B_BANK :{BLACK}Banco
+STR_024C_PAPER_MILL :{BLACK}Fábrica de Papel
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Companhia Alimentar
+STR_024E_PRINTING_WORKS :{BLACK}Tipografia
+STR_024F_GOLD_MINE :{BLACK}Mina de Ouro
+STR_0250_LUMBER_MILL :{BLACK}Fábrica de Madeiras
+STR_0251_FRUIT_PLANTATION :{BLACK}Plantação de Fruta
+STR_0252_RUBBER_PLANTATION :{BLACK}Plantação de Ãrvores da Borracha
+STR_0253_WATER_SUPPLY :{BLACK}Abastecimento de Ãgua
+STR_0254_WATER_TOWER :{BLACK}Depósito de Ãgua
+STR_0255_DIAMOND_MINE :{BLACK}Mina de Diamantes
+STR_0256_COPPER_ORE_MINE :{BLACK}Mina de Cobre
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Floresta de Algodão Doce
+STR_0258_CANDY_FACTORY :{BLACK}Fábrica de Doces
+STR_0259_BATTERY_FARM :{BLACK}Campo de Baterias
+STR_025A_COLA_WELLS :{BLACK}Poços de Cola
+STR_025B_TOY_SHOP :{BLACK}Loja de Brinquedos
+STR_025C_TOY_FACTORY :{BLACK}Fábrica de Brinquedos
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Fontes de Plástico
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Fontes de Bebidas Gasosas
+STR_025F_BUBBLE_GENERATOR :{BLACK}Produtor de Bolhas
+STR_0260_TOFFEE_QUARRY :{BLACK}Extracção de Caramelo
+STR_0261_SUGAR_MINE :{BLACK}Mina de Açúcar
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Construir Mina de Carvão
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Construir Central Eléctrica
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Construir Serração
+STR_0265_PLANT_FOREST :{BLACK}Plantar Floresta
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Construir Refinaria de Petróleo
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Construir Plataforma de Petróleo (só pode ser construída perto das bordas do mapa)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Construir Fábrica
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Construir Siderurgia
+STR_026A_CONSTRUCT_FARM :{BLACK}Construir Quinta
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Construir Mina de Ferro
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Construir Poços de Petróleo
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Construir Banco (só pode ser construído em cidades com mais de 1200 habitantes)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Construir Fábrica de Papel
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Construir Companhia Alimentar
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Construir Tipografia
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Construir Mina de Ouro
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Construir Banco (só pode ser construído em cidades)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Construir Fábrica de Madeiras (para limpar a floresta e produzir Madeira)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Criar Plantação de Fruta
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Criar Plantação de Ãrvores da Borracha
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Construir Abastecimento de Ãgua
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Construir Depósito de Ãgua (só pode ser construído em cidades)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Construir Mina de Diamantes
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Construir Mina de Cobre
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Plantar Floresta de Algodão Doce
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Construir Fábrica de Doces
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Construir Campo de Baterias
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Construir Poços de Cola
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Construir Loja de Brinquedos
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Construir Fábrica de Brinquedos
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Construir Fontes de Plástico
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Construir Fábrica de Bebidas Gasosas
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Construir Produtor de Bolhas
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Construir Extracção de Caramelo
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Construir Mina de Açúcar
+STR_0285_CAN_T_BUILD_HERE :{WHITE}Não é possível construir {STRING} aqui...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...é necessário construir uma cidade primeiro
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...só é permitido uma por cidade
+STR_0288_PLANT_TREES :{BLACK}Plantar árvores
+STR_0289_PLACE_SIGN :{BLACK}Colocar indicações
+STR_028A_RANDOM_TREES :{BLACK}Plantar Aleatoriamente
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Plantar árvores aleatoriamente no terreno
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Colocar áreas rochosas no terreno
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Colocar farol
+STR_028E_PLACE_TRANSMITTER :{BLACK}Colocar transmissor
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Definir área de deserto.{}Manter a tecla CTRL pressionada para remover
+STR_CREATE_LAKE :{BLACK}Definir área de água.{}A área adjacente será inundada se estiver ao nível do mar
+STR_0290_DELETE :{BLACK}Apagar
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Apagar completamente esta cidade
+STR_0292_SAVE_SCENARIO :Guardar cenário
+STR_0293_LOAD_SCENARIO :Abrir cenário
+STR_0294_QUIT_EDITOR :Sair do editor
+STR_0295 :
+STR_0296_QUIT :Sair
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Guardar cenário, abrir cenário, abandonar editor de cenário, sair
+STR_0298_LOAD_SCENARIO :{WHITE}Abrir Cenário
+STR_0299_SAVE_SCENARIO :{WHITE}Guardar Cenário
+STR_029A_PLAY_SCENARIO :{BLACK}Jogar Cenário
+STR_PLAY_HEIGHTMAP :{BLACK}Jogar mapa de alturas
+STR_PLAY_HEIGHTMAP_HINT :{BLACK}Iniciar novo jogo, usando um mapa de alturas como paisagem
+STR_QUIT_SCENARIO_QUERY :{YELLOW}Tem a certeza que deseja abandonar este cenário ?
+STR_029C_QUIT_EDITOR :{WHITE}Sair do Editor
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...só pode ser construído em cidades com pelo menos 1200 habitantes
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Retroceder data de inicio 1 ano
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Avançar data de inicio 1 ano
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...ambos os extremos da ponte devem estar em terra
+STR_02A1_SMALL :{BLACK}Pequena
+STR_02A2_MEDIUM :{BLACK}Média
+STR_02A3_LARGE :{BLACK}Grande
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Seleccione o tamanho da cidade
+STR_02A5_TOWN_SIZE :{YELLOW}Tamanho da cidade:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Mostrar a última mensagem ou notícia
+STR_OFF :Desligado
+STR_SUMMARY :Resumo
+STR_FULL :Completo
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Lista de cidades
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Nomes dos veículos
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Predefinição
+STR_02BF_CUSTOM :Personalizado
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Gravar nomes personalizados
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Selecção de nomes dos veículos
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Guardar nomes dos veículos personalizados no disco
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Opções do Jogo
+STR_02C5_DIFFICULTY_SETTINGS :Configurações de dificuldade
+STR_02C7_CONFIG_PATCHES :Configurar correcções
+STR_NEWGRF_SETTINGS :Definições Newgrf
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Mostrar nomes de cidades
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Mostrar nomes de estações
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Mostrar indicações
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Mostrar pontos de passagem
+STR_02D0_FULL_ANIMATION :{SETX 12}Animação completa
+STR_02D2_FULL_DETAIL :{SETX 12}Máximo de detalhes
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Edifícios transparentes
+STR_TRANSPARENT_SIGNS :{SETX 12}Sinais transparentes nas estações
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Informações do terreno
+STR_02D6 :
+STR_CONSOLE_SETTING :Activar Consola
+STR_02D7_SCREENSHOT_CTRL_S :Captura de ecrã (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Captura gigante (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :Sobre o OpenTTD...
+############ range ends here
+
+STR_02DB_OFF :{BLACK}Off
+STR_02DA_ON :{BLACK}On
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Mostrar subsídios
+STR_02DD_SUBSIDIES :Subsídios
+STR_02DE_MAP_OF_WORLD :Mapa do mundo
+STR_EXTRA_VIEW_PORT :Visualizador extra
+STR_SIGN_LIST :Lista de sinais
+STR_02DF_TOWN_DIRECTORY :Lista de cidades
+STR_TOWN_POPULATION :{BLACK}População Mundial: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Visualizador {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Copiar para o visualizador
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Copiar a localização do visualizador global para este visualizador
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Colar do visualizador
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Colar a localização deste visualizador para o visualizador global
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Unidades monetárias
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Selecção de unidades monetárias
+STR_MEASURING_UNITS :{BLACK}Unidades de medida
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Selecção de unidades de medida
+STR_02E6_ROAD_VEHICLES :{BLACK}Veículos de estrada
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Seleccione o lado da estrada por onde os veículos deverão andar
+STR_02E9_DRIVE_ON_LEFT :Andar pela esquerda
+STR_02EA_DRIVE_ON_RIGHT :Andar pela direita
+STR_02EB_TOWN_NAMES :{BLACK}Nomes das cidades
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Seleccionar o estilo dos nomes das cidades
+
+STR_02F4_AUTOSAVE :{BLACK}Guardar automaticamente
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Seleccionar o intervalo para guardar automático
+STR_02F7_OFF :Desactivado
+STR_02F8_EVERY_3_MONTHS :Cada 3 meses
+STR_02F9_EVERY_6_MONTHS :Cada 6 meses
+STR_02FA_EVERY_12_MONTHS :Cada 12 meses
+STR_02FB_START_A_NEW_GAME :{BLACK}Iniciar um novo jogo
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Carregar um jogo gravado
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Criar um cenário de jogo personalizado
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Seleccionar jogo de 1 jogador
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Seleccione jogo múltiple de 2 a 8 jogadores
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Mostrar opções de jogo
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Mostrar opções de dificuldade
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Iniciar um novo jogo, utilizando um cenário personalizado guardado no disco
+STR_0304_QUIT :{BLACK}Sair
+STR_0305_QUIT_OPENTTD :{BLACK}Sair de 'OpenTTD'
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...só se pode construir em cidades
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Seleccionar cenário do estilo 'temperado'
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Seleccionar cenário do estilo 'subárctico'
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Seleccionar cenário do estilo 'subtropical'
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Seleccionar cenário do estilo 'toyland'
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Financiar a construção de uma nova indústria
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Lista de Indústrias
+STR_0313_FUND_NEW_INDUSTRY :Financiar nova indústria
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Financiar nova indústria
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...só se pode construir em cidades
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...só se pode construir em zonas de floresta
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...só se pode construir em zonas de deserto
+STR_0319_PAUSED :{YELLOW}* * EM PAUSA * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Captura de ecrã gravada para o disco como '{STRING}' com sucesso
+STR_031C_SCREENSHOT_FAILED :{WHITE}Captura de ecrã falhada!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Comprar terreno para uso futuro
+STR_032F_AUTOSAVE :{RED}AUTOGUARDADO
+STR_SAVING_GAME :{RED}* * GRAVANDO JOGO * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}Gravação ainda em curso,{}por favor aguarde!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Seleccionar programa 'Ezy Street'
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :Inglês
+STR_TOWNNAME_FRENCH :Francês
+STR_TOWNNAME_GERMAN :Alemão
+STR_TOWNNAME_ADDITIONAL_ENGLISH :Inglês (Adicional)
+STR_TOWNNAME_LATIN_AMERICAN :Latino-Americano
+STR_TOWNNAME_SILLY :Absurdo
+STR_TOWNNAME_SWEDISH :Sueco
+STR_TOWNNAME_DUTCH :Holandês
+STR_TOWNNAME_FINNISH :Finlandês
+STR_TOWNNAME_POLISH :Polaco
+STR_TOWNNAME_SLOVAKISH :Eslovaco
+STR_TOWNNAME_NORWEGIAN :Noreguês
+STR_TOWNNAME_HUNGARIAN :Húngaro
+STR_TOWNNAME_AUSTRIAN :Austríaco
+STR_TOWNNAME_ROMANIAN :Romeno
+STR_TOWNNAME_CZECH :Checo
+STR_TOWNNAME_SWISS :Suiça
+STR_TOWNNAME_DANISH :Dinamarquês
+STR_TOWNNAME_TURKISH :Turco
+STR_TOWNNAME_ITALIAN :Italiano
+STR_TOWNNAME_CATALAN :Catalão
+############ end of townname region
+
+STR_CURR_GBP :Libras (£)
+STR_CURR_USD :Dólar ($)
+STR_CURR_EUR :Euro (€)
+STR_CURR_YEN :Yen (Â¥)
+STR_CURR_ATS :Shilling Austríaco (ATS)
+STR_CURR_BEF :Franco Belga (BEF)
+STR_CURR_CHF :Franco Suíço (CHF)
+STR_CURR_CZK :Coroa Checa (CZK)
+STR_CURR_DEM :Marco Alemão (DEM)
+STR_CURR_DKK :Coroa Dinamarquesa (DKK)
+STR_CURR_ESP :Peseta (ESP)
+STR_CURR_FIM :Marco Finlandês (FIM)
+STR_CURR_FRF :Franco (FRF)
+STR_CURR_GRD :Dracma Grego (GRD)
+STR_CURR_HUF :Forint Húngaro (HUF)
+STR_CURR_ISK :Coroa Islandesa (ISK)
+STR_CURR_ITL :Lira Italiana (ITL)
+STR_CURR_NLG :Guilda Holandesa (NLG)
+STR_CURR_NOK :Coroa Norueguesa (NOK)
+STR_CURR_PLN :Zloty Polaco (PLN)
+STR_CURR_ROL :Lei Romeno (ROL)
+STR_CURR_RUR :Rublo Russo (RUR)
+STR_CURR_SIT :Tolar Esloveno (SIT)
+STR_CURR_SEK :Coroa Sueca (SEK)
+STR_CURR_YTL :Lira Turca (YTL)
+STR_CURR_SKK :Koruna Eslovaco (SKK)
+STR_CURR_BRR :Real Brasileiro (BRL)
+
+STR_CURR_CUSTOM :Personalizado...
+
+STR_OPTIONS_LANG :{BLACK}Idioma
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Seleccionar o idioma da interface do jogo
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Ecrã Inteiro
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}Seleccione esta opção para jogar o OpenTTD em modo de ecrã inteiro
+
+STR_OPTIONS_RES :{BLACK}Resolução do ecrã
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Seleccione a resolução do ecrã que deseja utilizar
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Formato da captura de ecrã
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Seleccione o formato de captura de ecrã que deseja utilizar
+
+STR_AUTOSAVE_1_MONTH :Cada mês
+STR_AUTOSAVE_FAILED :{WHITE}Falha ao guardar automaticamente
+
+STR_MONTH_JAN :Janeiro
+STR_MONTH_FEB :Fevereiro
+STR_MONTH_MAR :Março
+STR_MONTH_APR :Abril
+STR_MONTH_MAY :Maio
+STR_MONTH_JUN :Junho
+STR_MONTH_JUL :Julho
+STR_MONTH_AUG :Agosto
+STR_MONTH_SEP :Setembro
+STR_MONTH_OCT :Outubro
+STR_MONTH_NOV :Novembro
+STR_MONTH_DEC :Dezembro
+
+STR_HEADING_FOR_STATION :{LTBLUE}Dirige-se para {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}Dirige-se a {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Sem ordens
+STR_NO_ORDERS_VEL :{LTBLUE}Sem ordens, {VELOCITY}
+
+STR_PASSENGERS :passageiros
+STR_BAGS :sacos
+STR_TONS :toneladas
+STR_LITERS :litros
+STR_ITEMS :itens
+STR_CRATES :caixas
+STR_RES_OTHER :outros
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Não é possível partilhar a lista de ordens...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Não é possível copiar a lista de ordens...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - Fim de Ordens Partilhadas - -
+
+STR_TRAIN_IS_LOST :{WHITE}Comboio {COMMA} está perdido.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}O lucro do comboio {COMMA} no último ano foi de {CURRENCY}
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}União Monetária Europeia!{}{}O Euro é introduzido como moeda única para todas as transacções no seu país!
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}O comboio {COMMA} tem muito poucas ordens definidas
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}O comboio {COMMA} tem uma ordem inválida
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}O comboio {COMMA} tem ordens duplicadas
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}O comboio {COMMA} tem uma estação inválida nas suas ordens
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}O veículo de estrada {COMMA} tem muito poucas ordens definidas
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}O veículo de estrada {COMMA} tem uma ordem inválida
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}O veículo de estrada {COMMA} tem ordens duplicadas
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}O veículo de estrada {COMMA} tem uma estação inválida nas suas ordens
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}O barco {COMMA} tem muito poucas ordens definidas
+STR_SHIP_HAS_VOID_ORDER :{WHITE}O barco {COMMA} tem uma ordem inválida
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}O barco {COMMA} tem ordens duplicadas
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}O barco {COMMA} tem uma estação inválida nas suas ordens
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}A aeronave {COMMA} tem muito poucas ordens definidas
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}A aeronave {COMMA} tem uma ordem inválida
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}A aeronave {COMMA} tem ordens duplicadas
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}A aeronave {COMMA} tem uma estação inválida nas suas ordens
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}A auto-renovação do comboio {COMMA} falhou (limite de dinheiro)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}A auto-renovação do veículo de estrada {COMMA} falhou (limite de dinheiro)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}A auto-renovação do barco {COMMA} falhou (limite de dinheiro)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}A auto-renovação da aeronave {COMMA} falhou (limite de dinheiro)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}Combóio {COMMA} ficou demasiado longo após substituição
+
+STR_CONFIG_PATCHES :{BLACK}Configurar Correcções
+STR_CONFIG_PATCHES_TIP :{BLACK}Configurar as correcções
+STR_CONFIG_PATCHES_CAPTION :{WHITE}Configurar Correcções
+
+STR_CONFIG_PATCHES_OFF :Desligado
+STR_CONFIG_PATCHES_ON :Ligado
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Mostrar velocidade do veículo na barra de estado: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Permitir a construção em declives e encostas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Dimensionamento mais realista de áreas de abrangência: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Permitir remoção de mais estradas, pontes, etc: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Permitir a construção de comboios muito longos: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Activar aceleração realista para comboios: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Proibir comboios e barcos de virar a 90 graus: {ORANGE}{STRING} {LTBLUE} (req. NPF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Juntar estações ferroviárias construídas pegadas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Deixar estação quando uma das cargas esteja completa: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Usar algoritmo de carregamento melhorado: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GRADUAL_LOADING :{LTBLUE}Carregar veículos gradualmente: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Inflação: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Entregar carga a uma estação só quando houver procura: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Permitir a construção de pontes muito longas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Permitir ordens de ir para o depósito: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Permitir construção de produções de matérias-primas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Permitir várias indústrias semelhantes por cidade: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Indústrias do mesmo tipo podem ser construídas perto: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Mostrar sempre a data completa na barra de estado: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Mostrar sinais no lado da circulação: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Mostrar janela das finanças no fim do ano: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}Função non-stop compatível com TTDPatch: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Fila de veículos de estrada (com efeitos de quantidade): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Deslocar janela quando o rato está na borda do mapa: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Permitir o suborno da autoridade local: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Estações não uniformes: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Nova procura de caminho global (NPF, overrides NTP): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FREIGHT_TRAINS :{LTBLUE}Multiplicador de peso para simular comboios pesados: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Permitir sempre aeroportos pequenos: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Avisar quando comboios andam perdidos: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Analisar ordens dos veículos: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :Não
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :Sim, mas excluir veículos parados
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :de todos os veículos
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Avisar se o lucro de um comboio for negativo: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Veículos nunca expiram: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Auto-renovação de veículos quando ficam velhos
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Auto-renovação do veículo {ORANGE}{STRING}{LTBLUE} meses antes/depois da idade máx.
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Dinheiro mínimo para fazer auto-renovação: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Duração das mensagens de erro: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Mostra população da cidade na janela da cidade: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Ãrvores invisíveis (com edifícios transparentes): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Gerador de terra: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :Original
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis
+STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}Distância máxima dos limites do mapa para Refinarias {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Altura da linha de neve: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN :{LTBLUE}Rudeza do terreno (apenas TerraGenesis) : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Muito suave
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH :Suave
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH :Acidentado
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :Muito acidentado
+STR_CONFIG_PATCHES_TREE_PLACER :{LTBLUE}Algoritmo de colocação de árvores: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TREE_PLACER_NONE :Nenhum
+STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL :Original
+STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED :Melhorada
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION :{LTBLUE}Rotação mapa de alt.: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Sentido anti-horário
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE :Sentido horário
+STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT :{LTBLUE}Altura com que um cenário plano fica: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Tamanho máx. de estações: {ORANGE}{STRING} {RED}Valores altos tornam o jogo lento!
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Manutenção automática de helicópteros em heliportos: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Ligar ferramentas de paisagem com as de construção: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Ao deslizar com o rato, mover a vista na direcção oposta: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Mostrar medidas ao usar ferramentas de construção: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Mostrar estampagens da companhia: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES_NONE :Nenhum
+STR_CONFIG_PATCHES_LIVERIES_OWN :Própria companhia
+STR_CONFIG_PATCHES_LIVERIES_ALL :Todas as companhias
+STR_CONFIG_PATCHES_PREFER_TEAMCHAT :{LTBLUE}Escolher chat de equipa com <ENTER>: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Máximo de comboios por jogador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Máximo de veículos de estrada por jogador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}Máximo de aeronaves por jogador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}Máximo de barcos por jogador: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Desactivar comboios para o computador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Desactivar veículos de estrada para o computador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Desactivar aeronaves para o computador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Desactivar barcos para o computador: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Activar nova IA (alpha): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Permitir IA em modo multi-jogador (experimental): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Intervalo de serviço predefinido para comboios: {ORANGE}{STRING} dias
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Intervalo de serviço predefinido para comboios: {ORANGE}desactivado
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Intervalo de serviço predefinido para veículos de estrada: {ORANGE}{STRING} dias
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Intervalo de serviço predefinido para veículos de estrada: {ORANGE}desactivado
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Intervalo de serviço predefinido para aeronaves: {ORANGE}{STRING} dias
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Intervalo de serviço predefinido para aeronaves: {ORANGE}desactivado
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Intervalo de serviço predefinido para barcos: {ORANGE}{STRING} dias
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Intervalo de serviço predefinido para barcos: {ORANGE}desactivado
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Não fazer manutenção se avarias desactivadas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Activar limites de velocidade para vagões: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}Desactivar carris electrificados: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Noticias a cores aparecem em: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Data de início: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}Terminar jogo em: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Activar economia regular (alterações menores)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Permite comprar acções de outras companhias
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Ao arrastar colocar sinais a cada: {ORANGE}{STRING} quadrado(s)
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Posição da barra de ferramentas principal: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Esquerda
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Centro
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Direita
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Raio de atracção de janelas: {ORANGE}{STRING} px
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Raio de atracção de janelas: {ORANGE}desactivado
+
+STR_CONFIG_PATCHES_GUI :{BLACK}Interface
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Construção
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Veículos
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Estações
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Economia
+STR_CONFIG_PATCHES_AI :{BLACK}Oponentes
+
+STR_CONFIG_PATCHES_DISABLED :desactivado
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Alterar valor
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Alguns ou todos os intervalo(s) de serviço predefinidos abaixo são incompatíveis com o valor escolhido! São válidos 5-90% e 30-800 dias
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}Usar YAPF para navios: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}Usar YAPF para veículos de estrada: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}Usar YAPF para comboios: {ORANGE}{STRING}
+
+STR_TEMPERATE_LANDSCAPE :Terreno temperado
+STR_SUB_ARCTIC_LANDSCAPE :terreno subárctico
+STR_SUB_TROPICAL_LANDSCAPE :terreno subtropical
+STR_TOYLAND_LANDSCAPE :terreno 'toyland'
+
+STR_CHEATS :{WHITE}Truques
+STR_CHEATS_TIP :{BLACK}As caixas de verificação indicam se já usou este truque antes
+STR_CHEATS_WARNING :{BLACK}Atenção! Está prestes a trair os seus oponentes. Tenha em conta que isto ficará registado para sempre.
+STR_CHEAT_MONEY :{LTBLUE}Aumentar dinheiro em {CURRENCY64}
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Jogar pelo jogador: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Bulldozer mágico (destrói indústrias, etc.): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Os túneis poderão cruzar-se: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Permitir construção quando em pausa: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Aviões a jacto não irão ter acidentes em aeroportos pequenos: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Mudar de clima: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Alterar data: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}Activar modificação de valores de produção: {ORANGE}{STRING}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}Dirige-se a {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Dirige-se a {WAYPOINT}, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :Ir via {WAYPOINT}
+STR_GO_NON_STOP_TO_WAYPOINT :Ir sem parar via {WAYPOINT}
+
+STR_WAYPOINTNAME_CITY :Ponto de passagem {TOWN}
+STR_WAYPOINTNAME_CITY_SERIAL :Ponto de passagem {TOWN} #{COMMA}
+STR_LANDINFO_WAYPOINT :Ponto de passagem
+
+STR_WAYPOINT :{WHITE}Ponto de passagem
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Seleccione um tipo de ponto de passagem
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}Editar nome do ponto de passagem
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Não é possível alterar o nome do ponto de passagem...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Converter linha em ponto de passagem
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Não é possível construir ponto de passagem de comboio aqui...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Não é possível remover ponto de passagem de comboio aqui...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Construir caminhos-de-ferro usando o modo automático
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}...não existe nenhuma cidade neste cenário
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}Tem a certeza que deseja criar um terreno aleatório?
+STR_MANY_RANDOM_TOWNS :{BLACK}Várias cidades aleatórias
+STR_RANDOM_TOWNS_TIP :{BLACK}Cobrir o mapa com cidades colocadas aleatoriamente
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Várias indústrias aleatórias
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Cobrir o mapa com indústrias colocadas aleatoriamente
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Não é possível gerar indústrias...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Abra a barra de modelação ambiental para elevar ou baixar terreno, plantar árvores, etc.
+STR_LANDSCAPING_TOOLBAR :{WHITE}Terreno
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Nivelar terreno
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Ãrvores de tipo aleatório
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}Colocar árvores de tipo aleatório
+
+STR_CANT_BUILD_CANALS :{WHITE}Não é possível construir canais aqui...
+STR_BUILD_CANALS_TIP :{BLACK}Construir canais
+STR_LANDINFO_CANAL :Canal
+
+STR_CANT_BUILD_LOCKS :{WHITE}Não é possível construir diques aqui...
+STR_BUILD_LOCKS_TIP :{BLACK}Construir diques
+STR_LANDINFO_LOCK :Dique
+
+STR_BUOY_IS_IN_USE :{WHITE}...boia está em uso!
+
+STR_LANDINFO_COORDS :{BLACK}Coordenadas: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Não é possível remover parte da estação...
+STR_CANT_CONVERT_RAIL :{WHITE}Não é possível converter o tipo de linha aqui...
+STR_CONVERT_RAIL_TIP :{BLACK}Converter/Actualizar tipo de linha
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Arrastar locomotiva para aqui para vender todo o comboio
+
+STR_DRAG_DROP :{BLACK}Arrastar
+STR_STATION_DRAG_DROP :{BLACK}Construir estação arrastando
+STR_SELECT_STATION_CLASS_TIP :{BLACK}Escolher a classe da estação a mostrar
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Escolher o tipo de estação a construir
+
+STR_FAST_FORWARD :{BLACK}Aumentar velocidade do jogo
+STR_MESSAGE_HISTORY :{WHITE}Histórico de Mensagens
+STR_MESSAGE_HISTORY_TIP :{BLACK}Lista de notícias recentes
+STR_MESSAGES_DISABLE_ALL :{BLACK}Desactivar tudo
+STR_MESSAGES_ENABLE_ALL :{BLACK}Activar tudo
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Construir Mina de Carvão
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Plantar Floresta
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Construir Plataforma de Petróleo
+STR_CONSTRUCT_FARM_TIP :{BLACK}Construir Quinta
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Construir Mina de Cobre
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Construir Poços de Petróleo
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Construir Mina de Ouro
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Construir Mina de Diamantes
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Construir Mina de Ferro
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Criar Plantação de Fruta
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Criar Plantação de Ãrvores da Borracha
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Construir Abastecimento de Ãgua
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Plantar Floresta de Algodão Doce
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}Construir Campo de Baterias
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Construir Poços de Cola
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Construir Fontes de Plástico
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Construir Produtor de Bolhas
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Construir Extracção de Caramelo
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Construir Mina de Açúcar
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Indústrias
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA}% transportado)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA}%/{COMMA}% transportado)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}...muito perto de outra indústria
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Adaptar comboio para um tipo de carga diferente
+STR_RAIL_REFIT_VEHICLE :{BLACK}Adaptar comboio
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Seleccionar tipo de carga do comboio
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Adaptar comboio para transportar a carga seleccionada
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Não é possível ajustar comboio...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Os intervalos de serviço são em percentagem: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Modificar produção
+
+TEMP_AI_IN_PROGRESS :{WHITE}Bem-vindo à nova IA, ainda em desenvolvimento. Pode encontrar problemas. Neste caso faça uma captura de ecrã e coloque-a no fórum. Divirta-se!
+TEMP_AI_ACTIVATED :{WHITE}Atenção: esta nova IA está ainda em versão alpha! Actualmente, só funcionam camiões e autocarros!
+TEMP_AI_MULTIPLAYER :{WHITE}Atenção: esta funcionalidade é experimental. Por favor reporte os problemas que detectar para truelight@openttd.org.
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Multi-jogador
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Nome do jogador:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}Este é o nome pelo qual os outros jogadores o irão identificar
+STR_NETWORK_CONNECTION :{BLACK}Conexão:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Escolha entre um jogo pela Internet ou pela rede local
+
+STR_NETWORK_START_SERVER :{BLACK}Iniciar servidor
+STR_NETWORK_START_SERVER_TIP :{BLACK}Iniciar um servidor próprio
+
+STR_NETWORK_GAME_NAME :{BLACK}Nome
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Nome do jogo
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Idioma, versão do servidor, etc.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Clique num jogo da lista para o seleccionar
+
+STR_NETWORK_FIND_SERVER :{BLACK}Localizar servidor
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Pesquisar por um servidor na rede
+STR_NETWORK_ADD_SERVER :{BLACK}Adicionar servidor
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Adiciona um servidor à lista que será sempre verificado se existem jogos a decorrer.
+STR_NETWORK_ENTER_IP :{BLACK}Introduza o endereço IP do servidor
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Clientes
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Clientes ligados / max. clientes
+STR_NETWORK_GAME_INFO :{SILVER}INFORMAÇÃO DE JOGO
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Clientes: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Idioma: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Conjunto de blocos: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Tamanho do Mapa: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}Versão do servidor: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}Endereço do servidor: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Data de início: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Data actual: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Protegido por password!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}SERVIDOR DESLIGADO
+STR_NETWORK_SERVER_FULL :{SILVER}SERVIDOR CHEIO
+STR_NETWORK_VERSION_MISMATCH :{SILVER}VERSÃO INCOMPATÃVEL
+STR_NETWORK_GRF_MISMATCH :{SILVER}NEWGRF INCOMPATÃVEL
+
+STR_NETWORK_JOIN_GAME :{BLACK}Juntar-se ao jogo
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}Iniciar novo jogo
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Nome do jogo:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}O nome do jogo será mostrado aos outros jogadores no menu de selecção de jogos multi-jogador
+STR_NETWORK_SET_PASSWORD :{BLACK}Definir password
+STR_NETWORK_PASSWORD_TIP :{BLACK}Proteja o jogo com uma senha se não desejar que pessoas indesejadas se juntem
+STR_NETWORK_SELECT_MAP :{BLACK}Seleccione um mapa:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}Em que mapa deseja jogar?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}Máximo de clientes:
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Escolha o número máximo de clientes. Não necessitam estar todos presentes.
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :Rede Local
+STR_NETWORK_INTERNET :Internet
+STR_NETWORK_LAN_INTERNET :Rede Local / Internet
+STR_NETWORK_INTERNET_ADVERTISE :Internet (divulgar)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 jogadores
+STR_NETWORK_1_PLAYERS :1 jogador
+STR_NETWORK_2_PLAYERS :2 jogadores
+STR_NETWORK_3_PLAYERS :3 jogadores
+STR_NETWORK_4_PLAYERS :4 jogadores
+STR_NETWORK_5_PLAYERS :5 jogadores
+STR_NETWORK_6_PLAYERS :6 jogadores
+STR_NETWORK_7_PLAYERS :7 jogadores
+STR_NETWORK_8_PLAYERS :8 jogadores
+STR_NETWORK_9_PLAYERS :9 jogadores
+STR_NETWORK_10_PLAYERS :10 jogadores
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}Máximo de Companhias:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Limitar o servidor a um certo número de Companhias
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}Máximo de espectadores:
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Limitar o servidor a um certo número de espectadores
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Idioma falado:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Outros jogadores ficarão a conhecer o idioma utilizado no servidor.
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}Iniciar Jogo
+STR_NETWORK_START_GAME_TIP :{BLACK}Iniciar um novo jogo em rede de um mapa aleatório, ou cenário
+STR_NETWORK_LOAD_GAME :{BLACK}Abrir Jogo
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Continuar um jogo multi-jogador anteriormente guardado (assegure-se de conectar com o jogador correcto)
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Qualquer
+STR_NETWORK_LANG_ENGLISH :Inglês
+STR_NETWORK_LANG_GERMAN :Alemão
+STR_NETWORK_LANG_FRENCH :Francês
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Sala de espera de jogo multi-jogador
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Preparando para juntar: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}Lista das companhias activas neste jogo. Pode juntar-se a uma delas ou iniciar uma nova companhia.
+STR_NETWORK_NEW_COMPANY :{BLACK}Nova empresa
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Criar uma nova empresa
+STR_NETWORK_SPECTATE_GAME :{BLACK}Observar jogo
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Ver jogo como um espectador
+STR_NETWORK_JOIN_COMPANY :{BLACK}Juntar a companhia
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Auxiliar na gestão desta companhia
+STR_NETWORK_REFRESH :{BLACK}Renovar servidor
+STR_NETWORK_REFRESH_TIP :{BLACK}Renovar a informação do servidor
+
+STR_NETWORK_COMPANY_INFO :{SILVER}INFORMAÇÃO DA COMPANHIA
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Nome da empresa: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}Inauguração: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}Valor da Companhia: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Balanço actual: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Rendimento do último ano: {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}Desempenho: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}Veículos: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Estações: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Jogadores: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}A ligar...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) A ligar..
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Autorizando..
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Em espera..
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) A obter mapa..
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Processando dados..
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) A registar..
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}A obter a informação de jogo..
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}A obter a informação da Companhia..
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} cliente{P "" s} à sua frente
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} kbytes obtidos até agora
+
+STR_NETWORK_DISCONNECT :{BLACK}Desligar
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Introduza o valor do dinheiro que pretende dar
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Servidor protegido. Introduza palavra-chave
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Companhia protegida. Introduza palavra-chave
+STR_NETWORK_CLIENT_LIST :{WHITE}Lista de clientes
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE} Não foram encontradas interfaces de rede ou o jogo foi compilado sem ENABLE_NETWORK
+STR_NETWORK_ERR_NOSERVER :{WHITE} Não foram encontrados jogos de rede
+STR_NETWORK_ERR_NOCONNECTION :{WHITE} O servidor não respondeu ao pedido
+STR_NETWORK_ERR_DESYNC :{WHITE} A sincronização do jogo de rede falhou.
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} A conexão do jogo de rede perdeu-se.
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} Não foi possível abrir o jogo.
+STR_NETWORK_ERR_SERVER_START :{WHITE} Não foi possível iniciar o servidor
+STR_NETWORK_ERR_CLIENT_START :{WHITE} Não foi possível estabelecer ligação
+STR_NETWORK_ERR_TIMEOUT :{WHITE} Tempo de espera esgotado na conexão #{NUM}.
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE} Ocorreu um erro de protocolo e a ligação foi encerrada
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE} A revisão deste cliente não condiz com a revisão do servidor
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} Palavra-chave incorrecta
+STR_NETWORK_ERR_SERVER_FULL :{WHITE} Servidor cheio
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} Foi banido deste SERVIDOR
+STR_NETWORK_ERR_KICKED :{WHITE} Você foi expulso do jogo
+STR_NETWORK_ERR_CHEATER :{WHITE} Batotas não são permitidas neste servidor
+
+STR_NETWORK_ERR_LEFT :deixou o jogo
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :erro geral
+STR_NETWORK_ERR_CLIENT_DESYNC :erro de dessincronização
+STR_NETWORK_ERR_CLIENT_SAVEGAME :não foi possível carregar o mapa
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :ligação perdida
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :erro de protocolo
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :Não autorizado
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :recebido um pacote estranho
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :revisão incorrecta
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :nome já está a ser utilizado
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :palavra-chave do jogo está incorrecta
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :id do jogador incorrecta em DoCommand
+STR_NETWORK_ERR_CLIENT_KICKED :avisado pelo servidor
+STR_NETWORK_ERR_CLIENT_CHEATER :estava a tentar usar batota
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :servidor cheio
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :entrou no jogo
+STR_NETWORK_GIVE_MONEY :deu à sua empresa algum dinheiro ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :você deu {STRING} algum dinheiro ({CURRENCY})
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Equipa] :
+STR_NETWORK_CHAT_COMPANY :[Equipa] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Equipa] Para {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[Privado] :
+STR_NETWORK_CHAT_CLIENT :[Privado] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[Privado] Para {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[Todos] :
+STR_NETWORK_CHAT_ALL :[Todos] {STRING}: {GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :mudou o nome dele/dela para
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE} O servidor fechou a sessão
+STR_NETWORK_SERVER_REBOOT :{WHITE} O servidor está a reiniciar...{}Por favor espere...
+
+STR_NETWORK_SERVER :Servidor
+STR_NETWORK_CLIENT :Cliente
+STR_NETWORK_SPECTATORS :Espectadores
+
+STR_NETWORK_CLIENTLIST_NONE :(nenhum)
+STR_NETWORK_CLIENTLIST_KICK :Banir
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Dar dinheiro
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Falar com todos
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Falar com a empresa
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Mensagem privada
+
+
+STR_NETWORK_SEND :{BLACK}Enviar
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}X-tamanho do mapa: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Y-tamanho do mapa: {ORANGE}{STRING}
+
+
+##### PNG-MAP-Loader
+
+STR_PNGMAP_ERROR :{WHITE}Impossível carregar paisagem de PNG...
+STR_PNGMAP_ERR_FILE_NOT_FOUND :{WHITE}...ficheiro não encontrado.
+STR_PNGMAP_ERR_IMAGE_TYPE :{WHITE}...impossível converter imagem. Necessário PNG de 8 ou 24 bits.
+STR_PNGMAP_ERR_MISC :{WHITE}...alguma coisa correu mal. Desculpe. (provavelmente um ficheiro corrompido)
+
+STR_BMPMAP_ERROR :{WHITE}Impossível carregar paisagem de BMP...
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}...impossível converter tipo de imagem.
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Custo: {CURRENCY}
+STR_0801_COST :{RED}Custo: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Lucro: {CURRENCY}
+STR_0803_INCOME :{GREEN}Lucro: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Transferir: {CURRENCY}
+STR_FEEDER :{YELLOW}Transferir: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Custo Estimado: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Lucro Estimado: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Não é possível levantar terreno aqui...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Não é possível baixar terreno aqui...
+STR_080A_ROCKS :Rochas
+STR_080B_ROUGH_LAND :Terreno Irregular
+STR_080C_BARE_LAND :Terreno Deserto
+STR_080D_GRASS :Terreno de Prados
+STR_080E_FIELDS :Campos
+STR_080F_SNOW_COVERED_LAND :Neve
+STR_0810_DESERT :Deserto
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Terreno inclinado na direcção incorrecta
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Combinação de linhas impossível
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}A escavação estragaria o túnel
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Já está ao nível do mar
+STR_1004_TOO_HIGH :{WHITE}Demasiado alto
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Tipo de linha não apropriado
+STR_1007_ALREADY_BUILT :{WHITE}...já construído
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Deverá remover a linha férrea primeiro
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Construir caminhos-de-ferro
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Construir Via Férrea Electrificada
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Construir monocarril
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}Construir MagLev
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Seleccione Ponte Ferroviária
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Não é possível construir depósito aqui...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Não é possível construir estação ferroviária aqui...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Não é possível construir sinais aqui...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Não é possível construir linha férrea aqui...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Não é possível remover linha férrea daqui...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Não é possível remover sinais daqui...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Orientação do Depósito
+STR_1015_RAILROAD_CONSTRUCTION :Construir caminhos-de-ferro
+STR_TOOLB_ELRAIL_CONSTRUCTION :Construir Via Férrea Electrificada
+STR_1016_MONORAIL_CONSTRUCTION :Construir monocarril
+STR_1017_MAGLEV_CONSTRUCTION :Construir MagLev
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Construir linha férrea
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Construir depósito (para criação e manutenção de comboios)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Construir estação ferroviária
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Construir sinais ferroviários
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Construir ponte ferroviária
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Construir túnel ferroviário
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Alternar entre construir/remover linha férrea e sinais
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Selecção de ponte - clique na ponte desejada para a construir
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Seleccionar a orientação do depósito
+STR_1021_RAILROAD_TRACK :Caminhos-de-ferro
+STR_1023_RAILROAD_TRAIN_DEPOT :Depósito ferroviário
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...a área é propriedade de outra empresa
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :Caminhos-de-ferro com sinais normais
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :Caminhos-de-ferro com pre-sinais
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :Caminhos-de-ferro com sinais de saída
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :Caminhos-de-ferro com sinais combinados
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Deverá remover a estrada primeiro
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Trabalhos na estrada em curso
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Construir Estradas
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Seleccionar Ponte de Estrada
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Não é possível construir estrada aqui...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Não é possível remover estrada daqui...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Orientação do Depósito
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Não é possível construir depósito de veículos de estrada aqui...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Não é possível construir estação de autocarros...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Não é possível construir estação de carregamento de camiões...
+STR_180A_ROAD_CONSTRUCTION :Construir estradas
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Construir estradas
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Construir depósito (para criação e manutenção de veículos de estrada)
+STR_180D_BUILD_BUS_STATION :{BLACK}Construir estação de autocarros
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Construir área de carregamento de camiões
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Construir ponte de estrada
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Construir túnel de estrada
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Alternar entre construir/remover estradas
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Seleccionar a orientação do depósito
+STR_1814_ROAD :Estrada
+STR_1815_ROAD_WITH_STREETLIGHTS :Estrada com iluminação
+STR_1816_TREE_LINED_ROAD :Estrada com árvores
+STR_1817_ROAD_VEHICLE_DEPOT :Depósito de veículos de estrada
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :Passagem de nível
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Cidades
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}O edifício deve ser demolido primeiro
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}População: {ORANGE}{COMMA}{BLACK} Casas: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Renomear Cidade
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Não é possível renomear cidade...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}A autoridade local de {TOWN} não autoriza
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Nomes das cidades - clique no nome para centrar a visualização na cidade
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centrar visualização na cidade
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Alterar o nome da cidade
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passageiros no último mês: {ORANGE}{COMMA}{BLACK} máx: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Correio no último mês: {ORANGE}{COMMA}{BLACK} máx: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Edifício alto de escritórios
+STR_2010_OFFICE_BLOCK :Edifício de escritórios
+STR_2011_SMALL_BLOCK_OF_FLATS :Edifício de apartamentos grande
+STR_2012_CHURCH :Igreja
+STR_2013_LARGE_OFFICE_BLOCK :Edifício de escritórios grande
+STR_2014_TOWN_HOUSES :Casas
+STR_2015_HOTEL :Hotel
+STR_2016_STATUE :Estátua
+STR_2017_FOUNTAIN :Fonte
+STR_2018_PARK :Parque
+STR_2019_OFFICE_BLOCK :Edifício de escritórios
+STR_201A_SHOPS_AND_OFFICES :Lojas e escritórios
+STR_201B_MODERN_OFFICE_BUILDING :Edifício de escritórios moderno
+STR_201C_WAREHOUSE :Armazém
+STR_201D_OFFICE_BLOCK :Edifício de escritórios
+STR_201E_STADIUM :Estádio
+STR_201F_OLD_HOUSES :Casas velhas
+STR_2020_LOCAL_AUTHORITY :{BLACK}Autoridade local
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Ver informações sobre a autoridade local
+STR_2022_LOCAL_AUTHORITY :{WHITE}{TOWN} autoridade local
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Avaliações da companhia de transporte
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Subsídios
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Oferta de subsídios para os serviços:
+STR_2027_FROM_TO :{ORANGE}{STRING} de {STRING} para {STRING}
+STR_2028_BY :{YELLOW} (por {DATE_SHORT})
+STR_202A_NONE :{ORANGE}Nenhum
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Serviços já subsidiados:
+STR_202C_FROM_TO :{ORANGE}{STRING} de {STATION} para {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, até {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}A oferta do subsídio expirou:{}{}{STRING} de {STRING} para {STRING} já não é subsidiado.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Subsídio retirado:{}{}serviço de transporte de {STRING} de {STATION} para {STATION} já não é subsidiado.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Subsídio de ligação oferecido:{}{}Primeiro serviço de {STRING} de {STRING} para {STRING} atrairá o subsídio de um ano da autoridade local!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subsídio de ligação concedido a {COMPANY}!{}{}{STRING} ligação de {STATION} para {STATION} pagará 50% extra durante o próximo ano!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subsídio de ligação concedido a {COMPANY}!{}{}{STRING} ligação de {STATION} para {STATION} pagará a dobrar durante o próximo ano!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subsídio de ligação concedido a {COMPANY}!{}{}{STRING} ligação de {STATION} para {STATION} pagará a triplicar durante o próximo ano!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subsídio de ligação concedido a {COMPANY}!{}{}{STRING} ligação de {STATION} para {STATION} pagará a quadruplicar durante o próximo ano!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} a autoridade local recusa permitir que outro aeroporto seja construído nesta cidade
+STR_2036_COTTAGES :Casas de campo
+STR_2037_HOUSES :Casas
+STR_2038_FLATS :Apartamentos
+STR_2039_TALL_OFFICE_BLOCK :Prédio de escritórios alto
+STR_203A_SHOPS_AND_OFFICES :Lojas e escritórios
+STR_203B_SHOPS_AND_OFFICES :Lojas e escritórios
+STR_203C_THEATER :Teatro
+STR_203D_STADIUM :Estádio
+STR_203E_OFFICES :Escritórios
+STR_203F_HOUSES :Casas
+STR_2040_CINEMA :Cinema
+STR_2041_SHOPPING_MALL :Centro Comercial
+STR_2042_DO_IT :{BLACK}Aplicar
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}Lista de acções disponíveis nesta cidade - fazer clique no item para mais detalhes
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Realizar a acção destacada na lista acima
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Acções disponíveis:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Pequena campanha publicitária
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Média campanha publicitária
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Grande campanha publicitária
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Financiar a reconstrução das estradas locais
+STR_204A_BUILD_STATUE_OF_COMPANY :Construir estátua do proprietário da companhia
+STR_204B_FUND_NEW_BUILDINGS :Financiar novos edifícios
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Comprar exclusividade da rede de transportes
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Subornar a autoridade local
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Iniciar uma campanha publicitária pequena, para atrair mais passageiros e carga à sua companhia.{} Custo: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Iniciar uma campanha publicitária média, para atrair mais passageiros e carga à sua companhia.{} Custo: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Iniciar uma campanha publicitária grande, para atrair mais passageiros e carga à sua companhia.{} Custo: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} Financiar a reconstrução da rede rodoviária urbana. Causa engarrafamentos consideráveis ao tráfego até 6 meses.{} Custo: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Construir uma estátua em honra da sua companhia.{} Custo: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Financiar a construção de edifícios comerciais novos na cidade.{} Custo: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Comprar a exclusividade dos serviços durante 1 ano na cidade. A autoridade da cidade permitirá que os passageiros e a carga usem somente estações da sua companhia.{} Custo: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Subornar a autoridade local para aumentar a sua avaliação, correndo o risco de uma penalidade severa se apanhado.{} Custo: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}Tráfego caótico em {TOWN}!{}{}Programa de reconstrução de estradas financiado por {COMPANY} provoca 6 meses de miséria aos condutores!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (em construção)
+STR_2059_IGLOO :Igloo
+STR_205A_TEPEES :Tepees
+STR_205B_TEAPOT_HOUSE :Casa-bule
+STR_205C_PIGGY_BANK :Mealheiro
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN} {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Paisagem
+STR_2800_PLANT_TREES :Plantar árvores
+STR_2801_PLACE_SIGN :Colocar sinal
+STR_2802_TREES :{WHITE}Ãrvores
+STR_2803_TREE_ALREADY_HERE :{WHITE}...árvore já plantada aqui
+STR_2804_SITE_UNSUITABLE :{WHITE}...local impróprio
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Impossível plantar árvore aqui...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...demasiados sinais
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Não pode colocar um sinal aqui...
+STR_280A_SIGN :Sinal
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Editar texto do sinal
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Não pode alterar o nome do sinal...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Escolha um tipo de árvore para plantar
+STR_280E_TREES :Ãrvores
+STR_280F_RAINFOREST :Floresta Tropical
+STR_2810_CACTUS_PLANTS :Cactos
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Selecção de Estação
+STR_3001_AIRPORT_SELECTION :{WHITE}Selecção de Aeroporto
+STR_3002_ORIENTATION :{BLACK}Orientação
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Número de linhas
+STR_3004_PLATFORM_LENGTH :{BLACK}Tamanho da plataforma
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Demasiado perto de outra estação ferroviária
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Muito junto de uma estação/local de carga já existente
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}Demasiadas estações/locais de carga nesta cidade
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}Demasiadas estações/locais de carga
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Demasiadas paragens de autocarro
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}Demasiadas estações de carga
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Muito junto de uma estação/local de carga
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Precisa de demolir a estação primeiro
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Demasiado perto de outro aeroporto
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Precisa de demolir o aeroporto primeiro
+
+STR_3030_RENAME_STATION_LOADING :Alterar nome de estação/local de carga
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Não pode alterar o nome da estação...
+STR_3032_RATINGS :{BLACK}Avaliações
+STR_3033_ACCEPTS :{BLACK}Aceita
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}Avaliação local do serviço de transporte:
+
+############ range for rating starts
+STR_3035_APPALLING :Inexistente
+STR_3036_VERY_POOR :Muito Fraco
+STR_3037_POOR :Fraco
+STR_3038_MEDIOCRE :Medíocre
+STR_3039_GOOD :Bom
+STR_303A_VERY_GOOD :Muito Bom
+STR_303B_EXCELLENT :Excelente
+STR_303C_OUTSTANDING :Proeminente
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} não aceita mais {STRING}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} não aceita mais {STRING} ou {STRING}
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} agora aceita {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} agora aceita {STRING} e {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Orientação da estação de autocarros
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Orientação da estação de carga
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Precisa de demolir a estação de autocarros primeiro
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Precisa de demolir a estação de carga primeiro
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Estações
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Nenhuma -
+STR_304B_SITE_UNSUITABLE :{WHITE}...sítio inadequado
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Muito perto de outra doca
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Deverá demolir a doca primeiro
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Seleccionar a orientação da estação ferroviária
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Seleccionar o número de linhas da estação ferroviária
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Seleccionar o tamanho da estação ferroviária
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Seleccionar a orientação da estação de autocarros
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Seleccionar a orientação da estação de carregamento de camiões
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Centrar visualização no local estação
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Mostrar avaliações da estação
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Alterar o nome da estação
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Mostrar lista de carga aceite
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Nome da estação - clique no nome para centrar a visualização na estação
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Seleccionar tamanho/tipo de aeroporto
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :Estação ferroviária
+STR_305F_AIRCRAFT_HANGAR :Hangar
+STR_3060_AIRPORT :Aeroporto
+STR_3061_TRUCK_LOADING_AREA :Ãrea de carregamento de camiões
+STR_3062_BUS_STATION :Estação de autocarros
+STR_3063_SHIP_DOCK :Doca
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Evidenciar área de cobertura do sítio proposto
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Não evidenciar área de cobertura do sítio proposto
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Evidenciar cobertura
+STR_3068_DOCK :{WHITE}Doca
+STR_3069_BUOY :Bóia
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...bóia no caminho
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...estação muito extensa
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...estações não-uniformes desactivadas
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Manter CTRL premido para seleccionar mais do que um item
+
+STR_UNDEFINED :(frase indefinida)
+STR_STAT_CLASS_DFLT :Estação por defeito
+STR_STAT_CLASS_WAYP :Pontos de passagem
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Orientação do Depósito
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...deverá ser construído na água
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Não é possível construir depósito naval aqui...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Seleccione a orientação do depósito naval
+STR_3804_WATER :Ãgua
+STR_3805_COAST_OR_RIVERBANK :Costa ou margem
+STR_3806_SHIP_DEPOT :Depósito naval
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...Não é possível construir na água
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Guardar Jogo
+STR_4001_LOAD_GAME :{WHITE}Abrir Jogo
+STR_4002_SAVE :{BLACK}Guardar
+STR_4003_DELETE :{BLACK}Eliminar
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} megabytes livres
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Não é possível ler unidade
+STR_4007_GAME_SAVE_FAILED :{WHITE}Falha ao Guardar Jogo
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Não é possível eliminar ficheiro
+STR_4009_GAME_LOAD_FAILED :{WHITE}Falha ao Abrir Jogo
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}Lista de unidades, directorias e ficheiros de jogos guardados
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Nome escolhido para guardar o jogo
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Eliminar o jogo guardado seleccionado
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Guardar o jogo actual, usando o nome escolhido
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Seleccionar Novo Tipo de Jogo
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Seleccionar cenário (verde), jogo pré-programado (azul), ou novo jogo aleatório
+STR_4010_GENERATE_RANDOM_NEW_GAME :Gerar novo jogo aleatório
+STR_4011_LOAD_HEIGHTMAP :{WHITE}Carregar mapa de alturas
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} no caminho
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :Mina de Carvão
+STR_4803_POWER_STATION :Central Eléctrica
+STR_4804_SAWMILL :Serração
+STR_4805_FOREST :Floresta
+STR_4806_OIL_REFINERY :Refinaria de Petróleo
+STR_4807_OIL_RIG :Plataforma Petrolífera
+STR_4808_FACTORY :Fábrica
+STR_4809_PRINTING_WORKS :Tipografia
+STR_480A_STEEL_MILL :Siderurgia
+STR_480B_FARM :Quinta
+STR_480C_COPPER_ORE_MINE :Mina de Cobre
+STR_480D_OIL_WELLS :Poços de Petróleo
+STR_480E_BANK :Banco
+STR_480F_FOOD_PROCESSING_PLANT :Companhia Alimentar
+STR_4810_PAPER_MILL :Fábrica de Papel
+STR_4811_GOLD_MINE :Mina de Ouro
+STR_4812_BANK :Banco
+STR_4813_DIAMOND_MINE :Mina de Diamantes
+STR_4814_IRON_ORE_MINE :Mina de Ferro
+STR_4815_FRUIT_PLANTATION :Plantação de Fruta
+STR_4816_RUBBER_PLANTATION :Plantação de Ãrvores da Borracha
+STR_4817_WATER_SUPPLY :Abastecimento de Ãgua
+STR_4818_WATER_TOWER :Depósito de Ãgua
+STR_4819_FACTORY :Fábrica
+STR_481A_FARM :Quinta
+STR_481B_LUMBER_MILL :Fábrica de Madeiras
+STR_481C_COTTON_CANDY_FOREST :Floresta de Algodão Doce
+STR_481D_CANDY_FACTORY :Fábrica de Doces
+STR_481E_BATTERY_FARM :Campo de Baterias
+STR_481F_COLA_WELLS :Poços de Cola
+STR_4820_TOY_SHOP :Loja de Brinquedos
+STR_4821_TOY_FACTORY :Fábrica de Brinquedos
+STR_4822_PLASTIC_FOUNTAINS :Fontes de Plástico
+STR_4823_FIZZY_DRINK_FACTORY :Fábrica de Bebidas Gasosas
+STR_4824_BUBBLE_GENERATOR :Produtor de Bolhas
+STR_4825_TOFFEE_QUARRY :Extracção de Caramelo
+STR_4826_SUGAR_MINE :Mina de Açúcar
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Necessário: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Necessário: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Necessário: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Produção no último mês:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% transportado)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centrar visualização na localização da indústria
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Nova {STRING} em construção em {TOWN}!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Nova {STRING} está a ser plantada em {TOWN}!
+STR_482F_COST :{BLACK}Custo: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Não é possível construir este tipo de indústria aqui...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...a floresta só pode ser plantada acima do nível de neve
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} anuncia fecho iminente!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}Problemas no abastecimento levam {INDUSTRY} a anunciar fecho iminente!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}Escassez de árvores nas proximidades leva {INDUSTRY} a anunciar fecho iminente!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} aumenta a produção
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}Novo filão de carvão encontrado em {INDUSTRY}!{}Produção deverá duplicar!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}Novas reservas de petróleo encontradas em {INDUSTRY}!{}Produção deverá duplicar!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}Prática de agricultura inovadora duplica a produção em {INDUSTRY}!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}Produção de {INDUSTRY} reduzida em 50%
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}Praga de insectos em {INDUSTRY}!{}Produção diminui 50%
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...só pode ser colocado perto das bordas do mapa
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}Produção de {STRING} em {INDUSTRY} aumenta {COMMA}%!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}Produção de {STRING} em {INDUSTRY} diminui {COMMA}%!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Há um comboio no túnel
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Há um veículo de estrada no túnel
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Há outro túnel no caminho
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Não é possível escavar o terreno para o outro lado do túnel
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Deverá demolir o túnel primeiro
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Deverá demolir a ponte primeiro
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Não é posível iniciar e finalizar no mesmo ponto
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Debaixo da ponte é necessário terreno plano ou água
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}Inicio e fim devem estar alinhados
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}O sítio não é adequado para a entrada do túnel
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Suspensa, Aço
+STR_500F_GIRDER_STEEL :Vigas, Aço
+STR_5010_CANTILEVER_STEEL :Cantilever, Aço
+STR_5011_SUSPENSION_CONCRETE :Suspensa, Betão
+STR_5012_WOODEN :De madeira
+STR_5013_CONCRETE :Betão
+STR_5014_TUBULAR_STEEL :Tubular, Aço
+STR_BRIDGE_TUBULAR_SILICON :Tubular, Silício
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Não é possível construir ponte aqui...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Não é possível construir túnel aqui...
+STR_5017_RAILROAD_TUNNEL :Túnel ferroviário
+STR_5018_ROAD_TUNNEL :Túnel de estrada
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Ponte ferroviária suspensa em aço
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Ponte ferroviária com vigas em aço
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Ponte ferroviária cantilever em aço
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Ponte ferroviária suspensa de betão reforçado
+STR_501F_WOODEN_RAIL_BRIDGE :Ponte ferroviária de madeira
+STR_5020_CONCRETE_RAIL_BRIDGE :Ponte ferroviária de betão
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Ponte de estrada suspensa em aço
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Ponte de estrada com vigas em aço
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Ponte de estrada cantilever em aço
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Ponte de estrada suspensa de betão reforçado
+STR_5025_WOODEN_ROAD_BRIDGE :Ponte de estrada de madeira
+STR_5026_CONCRETE_ROAD_BRIDGE :Ponte de estrada de betão
+STR_5027_TUBULAR_RAIL_BRIDGE :Ponte de estrada tubular
+STR_5028_TUBULAR_ROAD_BRIDGE :Ponte de estrada tubular
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Objecto no caminho
+STR_5801_TRANSMITTER :Transmissor
+STR_5802_LIGHTHOUSE :Farol
+STR_5803_COMPANY_HEADQUARTERS :Sede de Empresa
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...sede de empresa no caminho
+STR_5805_COMPANY_OWNED_LAND :Terreno propriedade de uma empresa
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Não é possível comprar esta área de terreno...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...já a possui!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Sem nome
+STR_SV_TRAIN_NAME :Comboio {COMMA}
+STR_SV_ROADVEH_NAME :Veículo de Estrada {COMMA}
+STR_SV_SHIP_NAME :Barco {COMMA}
+STR_SV_AIRCRAFT_NAME :Aeronave {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :{STRING} Norte
+STR_SV_STNAME_SOUTH :{STRING} Sul
+STR_SV_STNAME_EAST :{STRING} Este
+STR_SV_STNAME_WEST :{STRING} Oeste
+STR_SV_STNAME_CENTRAL :{STRING} Central
+STR_SV_STNAME_TRANSFER :{STRING} Transporte
+STR_SV_STNAME_HALT :{STRING} Paragem
+STR_SV_STNAME_VALLEY :Vale de {STRING}
+STR_SV_STNAME_HEIGHTS :Montes de {STRING}
+STR_SV_STNAME_WOODS :Floresta de {STRING}
+STR_SV_STNAME_LAKESIDE :Lago de {STRING}
+STR_SV_STNAME_EXCHANGE :{STRING} Intercâmbio
+STR_SV_STNAME_AIRPORT :Aeroporto de {STRING}
+STR_SV_STNAME_OILFIELD :Petrolífera de {STRING}
+STR_SV_STNAME_MINES :Minas de {STRING}
+STR_SV_STNAME_DOCKS :Docas de {STRING}
+STR_SV_STNAME_BUOY_1 :{STRING} Bóia 1
+STR_SV_STNAME_BUOY_2 :{STRING} Bóia 2
+STR_SV_STNAME_BUOY_3 :{STRING} Bóia 3
+STR_SV_STNAME_BUOY_4 :{STRING} Bóia 4
+STR_SV_STNAME_BUOY_5 :{STRING} Bóia 5
+STR_SV_STNAME_BUOY_6 :{STRING} Bóia 6
+STR_SV_STNAME_BUOY_7 :{STRING} Bóia 7
+STR_SV_STNAME_BUOY_8 :{STRING} Bóia 8
+STR_SV_STNAME_BUOY_9 :{STRING} Bóia 9
+STR_SV_STNAME_ANNEXE :{STRING} Anexo
+STR_SV_STNAME_SIDINGS :Desvio de {STRING}
+STR_SV_STNAME_BRANCH :Ramal de {STRING}
+STR_SV_STNAME_UPPER :{STRING} de cima
+STR_SV_STNAME_LOWER :{STRING} de baixo
+STR_SV_STNAME_HELIPORT :Heliporto de {STRING}
+STR_SV_STNAME_FOREST :Floresta de {STRING}
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :Nível de Dificuldade{WHITE}
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Guardar
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Fácil
+STR_6802_MEDIUM :{BLACK}Médio
+STR_6803_HARD :{BLACK}Difícil
+STR_6804_CUSTOM :{BLACK}Personalizado
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}Número máximo de oponentes: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Data de início dos oponentes: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}Número de cidades: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}Número de indústrias: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Empréstimo máximo inicial: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Taxa de interesse inicial: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Custos de circulação dos veículos: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Velocidade de construção dos oponentes: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Inteligência dos oponentes: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Avarias nos veículos: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Multiplicador de subsídio: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Custos de construção: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Tipo de terreno: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Quantidade de mar/lagos: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Economia: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Inverter comboio: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Desastres: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Atitude das autoridades sobre reestruturamentos: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :Nenhum
+STR_6816_LOW :Baixo
+STR_6817_NORMAL :Normal
+STR_6818_HIGH :Alto
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Muito Lento
+STR_681C_SLOW :Lento
+STR_681D_MEDIUM :Médio
+STR_681E_FAST :Rápido
+STR_681F_VERY_FAST :Muito Rápido
+STR_VERY_LOW :Muito Baixo
+STR_6820_LOW :Baixo
+STR_6821_MEDIUM :Médio
+STR_6822_HIGH :Alto
+STR_6823_NONE :Nenhum
+STR_6824_REDUCED :Reduzido
+STR_6825_NORMAL :Normal
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Muito Plano
+STR_682B_FLAT :Plano
+STR_682C_HILLY :Acidentado
+STR_682D_MOUNTAINOUS :Montanhoso
+STR_682E_STEADY :Estável
+STR_682F_FLUCTUATING :Flutuante
+STR_6830_IMMEDIATE :Imediato
+STR_6831_3_MONTHS_AFTER_PLAYER :3 meses depois do jogador
+STR_6832_6_MONTHS_AFTER_PLAYER :6 meses depois do jogador
+STR_6833_9_MONTHS_AFTER_PLAYER :9 meses depois do jogador
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :No fim da linha e em estações
+STR_6835_AT_END_OF_LINE_ONLY :Só no fim da linha
+STR_6836_OFF :Off
+STR_6837_ON :On
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Mostrar melhores pontuações
+STR_6839_PERMISSIVE :Permissivo
+STR_683A_TOLERANT :Tolerante
+STR_683B_HOSTILE :Hostil
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Jogador {COMMA})
+STR_7004_NEW_FACE :{BLACK}Nova Cara
+STR_7005_COLOR_SCHEME :{BLACK}Cores
+STR_7006_COLOR_SCHEME :{GOLD}Cores:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Novo Esquema de Cores
+STR_7008_COMPANY_NAME :{BLACK}Empresa
+STR_7009_PRESIDENT_NAME :{BLACK}Presidente
+STR_700A_COMPANY_NAME :Nome da Empresa
+STR_700B_PRESIDENT_S_NAME :Nome do Presidente
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Não é possível alterar o nome da empresa...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Não é possível alterar o nome do presidente...
+STR_700E_FINANCES :{WHITE}{COMPANY} Finanças {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Despesas/Lucros
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Construção
+STR_7012_NEW_VEHICLES :{GOLD}Novos Veículos
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Circulação de Comboios
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Circulação de Veículos
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Circulação de Aeronaves
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Circulação de Barcos
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Manutenção de Propriedades
+STR_7018_TRAIN_INCOME :{GOLD}Lucros dos Comboios
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Lucros dos Veículos
+STR_701A_AIRCRAFT_INCOME :{GOLD}Lucros das Aeronaves
+STR_701B_SHIP_INCOME :{GOLD}Lucros dos Barcos
+STR_701C_LOAN_INTEREST :{GOLD}Juros do Empréstimo
+STR_701D_OTHER :{GOLD}Outros
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Total:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Gráfico de Rendimentos
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Gráfico de Benefícios Operativos
+STR_7026_BANK_BALANCE :{WHITE}Balanço Bancário
+STR_7027_LOAN :{WHITE}Empréstimo
+STR_MAX_LOAN :{WHITE}Empréstimo Máximo: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}Pedir emprestado {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Pagar empréstimo {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...o empréstimo máximo permitido é de {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Não é possível pedir mais dinheiro emprestado...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...não há empréstimo para pagar
+STR_702E_REQUIRED :{WHITE}...necessário {CURRENCY}
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Não é possível pagar empréstimo...
+STR_INSUFFICIENT_FUNDS :{WHITE}Não é possível ceder capital proveniente de empréstimo bancário...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Seleccione uma nova cara para o presidente
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Alterar cores dos veículos
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Alterar nome do presidente
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Alterar nome da empresa
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Clique no novo esquema de cor
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Aumentar empréstimo
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Pagar parte do empréstimo
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(Presidente)
+STR_7038_INAUGURATED :{GOLD}Inaugurado: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Veículos:
+STR_TRAINS :{WHITE}{COMMA} comboio{P "" s}
+STR_ROAD_VEHICLES :{WHITE}{COMMA} veículo{P "" s} de estrada
+STR_AIRCRAFT :{WHITE}{COMMA} aeronave{P "" s}
+STR_SHIPS :{WHITE}{COMMA} barco{P "" s}
+STR_7042_NONE :{WHITE}Nenhum
+STR_7043_FACE_SELECTION :{WHITE}Selecção de Cara
+STR_7044_MALE :{BLACK}Masculino
+STR_7045_FEMALE :{BLACK}Feminino
+STR_7046_NEW_FACE :{BLACK}Nova Cara
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Cancelar selecção da nova cara
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Aceitar selecção da nova cara
+STR_7049_SELECT_MALE_FACES :{BLACK}Seleccionar caras masculinas
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Seleccionar caras femininas
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Gerar nova cara aleatoriamente
+STR_704C_KEY :{BLACK}Chave
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Mostrar chave dos gráficos
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Chave dos gráficos da empresa
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Clique aqui para mostrar/ocultar companhia no gráfico
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Unidades de carga entregues
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Avaliações da empresa (máximo=1000)
+STR_7052_COMPANY_VALUES :{WHITE}Valor da empresa
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Classificação de Empresas
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}Empresa de transportes em dificuldades!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} será vendida ou declarada falida a menos que melhore os seus rendimentos em breve!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(Presidente)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Fusão de empresa de transportes!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} foi vendida a {COMPANY} por {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Estamos à procura de uma empresa de transportes para comprar a nossa empresa{}{}Deseja comprar {COMPANY} por {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Falida!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} foi fechada pelos credores e todos os seus bens foram vendidos!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}Nova empresa de transportes!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} inicia construção em {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Não é possível comprar empresa...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Tarifas por carga
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Dias em trânsito
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Pagamento por entregar 10 unidades (ou 10 000 litros) de carga numa distância de 20 quadrados
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Mostrar/ocultar gráfico para o tipo de carga
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Engenheiro
+STR_7067_TRAFFIC_MANAGER :Gestor de Tráfego
+STR_7068_TRANSPORT_COORDINATOR :Coordenador de Transportes
+STR_7069_ROUTE_SUPERVISOR :Supervisor de Rotas
+STR_706A_DIRECTOR :Director
+STR_706B_CHIEF_EXECUTIVE :Chefe Executivo
+STR_706C_CHAIRMAN :Director Executivo
+STR_706D_PRESIDENT :Presidente
+STR_706E_TYCOON :Magnate
+STR_706F_BUILD_HQ :{BLACK}Construir sede
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Construir sede da empresa / ver sede da empresa
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Reconstruir sede da empresa noutro sítio por 1% do valor da empresa
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Não é possível construir sede da empresa...
+STR_7072_VIEW_HQ :{BLACK}Ver sede
+STR_RELOCATE_HQ :{BLACK}Mover sede
+STR_COMPANY_PASSWORD :{BLACK}Palavra passe
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Usar palavra passe na empresa para prevenir utilizadores não autorizados.
+STR_SET_COMPANY_PASSWORD :Definir palavra passe da empresa
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}Retrocesso Mundial!{}{}Especialistas financeiros temem crise económica!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Fim do retrocesso!{}{}Melhoras no comércio inspiram confiança nas indústrias à medida que a economia se fortalece!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Alternar entre janela grande/pequena
+STR_7076_COMPANY_VALUE :{GOLD}Valor da empresa: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Comprar 25% de acções
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Vender 25% de acções
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Comprar 25% de acções nesta empresa
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Vender 25% de acções nesta empresa
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Não é possível comprar 25% de acções nesta empresa...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}Não é possível vender 25% de acções nesta empresa...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% propriedade de {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% propriedade de {COMPANY}{} {COMMA}% propriedade de {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} foi comprada por {COMPANY}!
+STR_7080_PROTECTED :{WHITE}Esta empresa ainda não troca acções...
+
+STR_LIVERY_DEFAULT :Estampagem Padrão
+STR_LIVERY_STEAM :Motor a Vapor
+STR_LIVERY_DIESEL :Motor Diesel
+STR_LIVERY_ELECTRIC :Motor Eléctrico
+STR_LIVERY_MONORAIL :Motor Monocarril
+STR_LIVERY_MAGLEV :Motor de Levitação Magnética
+STR_LIVERY_DMU :DMU
+STR_LIVERY_EMU :EMU
+STR_LIVERY_PASSENGER_WAGON_STEAM :Carruagem de Passageiros (Vapor)
+STR_LIVERY_PASSENGER_WAGON_DIESEL :Carruagem de Passageiros (Diesel)
+STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Carruagem de Passageiros (Eléctrica)
+STR_LIVERY_FREIGHT_WAGON :Vagão de Carga
+STR_LIVERY_BUS :Autocarro
+STR_LIVERY_TRUCK :Veículo de Mercadorias
+STR_LIVERY_PASSENGER_SHIP :Navio de Passageiros
+STR_LIVERY_FREIGHT_SHIP :Navio Cargueiro
+STR_LIVERY_HELICOPTER :Helicóptero
+STR_LIVERY_SMALL_PLANE :Aeronave de Pequenas Dimensões
+STR_LIVERY_LARGE_PLANE :Aeronave de Grandes Dimensões
+
+STR_LIVERY_GENERAL_TIP :{BLACK}Exibir esquema de cores geral
+STR_LIVERY_TRAIN_TIP :{BLACK}Exibir esquemas de cores dos combóios
+STR_LIVERY_ROADVEH_TIP :{BLACK}Exibir esquemas de cores dos veículos de estrada
+STR_LIVERY_SHIP_TIP :{BLACK}Exibir esquemas de cores dos navios
+STR_LIVERY_AIRCRAFT_TIP :{BLACK}Exibir esquema de cores da aeronave
+STR_LIVERY_PRIMARY_TIP :{BLACK}Seleccione a cor primária para o veículo seleccionado
+STR_LIVERY_SECONDARY_TIP :{BLACK}Seleccione a cor secundária para o esquema seleccionado
+STR_LIVERY_PANEL_TIP :{BLACK}Seleccione o esquema de cores a alterar (ou esquemas múltiplos utilzando a tecla CTRL e botão esquerdo do rato). Marque a caixa para comutar a utilização do esquema de cores
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (Vapor)
+STR_8001_MJS_250_DIESEL :MJS 250 (Diesel)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut Diesel
+STR_8006_POWERNAUT_DIESEL :Powernaut Diesel
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (Vapor)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (Vapor)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (Vapor)
+STR_800A_SH_8P_STEAM :SH '8P' (Vapor)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (Diesel)
+STR_800C_DASH_DIESEL :'Dash' (Diesel)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (Diesel)
+STR_800E_UU_37_DIESEL :UU '37' (Diesel)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (Diesel)
+STR_8010_CS_4000_DIESEL :CS 4000 (Diesel)
+STR_8011_CS_2400_DIESEL :CS 2400 (Diesel)
+STR_8012_CENTENNIAL_DIESEL :Centennial (Diesel)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (Diesel)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (Diesel)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (Diesel)
+STR_8016_SH_125_DIESEL :SH '125' (Diesel)
+STR_8017_SH_30_ELECTRIC :SH '30' (Eléctrico)
+STR_8018_SH_40_ELECTRIC :SH '40' (Eléctrico)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (Eléctrico)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (Eléctrico)
+STR_801B_PASSENGER_CAR :Carruagem de Passageiros
+STR_801C_MAIL_VAN :Vagão de Correio
+STR_801D_COAL_CAR :Vagão de Carvão
+STR_801E_OIL_TANKER :Cisterna de Petróleo
+STR_801F_LIVESTOCK_VAN :Vagão de Gado
+STR_8020_GOODS_VAN :Vagão de Bens
+STR_8021_GRAIN_HOPPER :Vagão de Cereais
+STR_8022_WOOD_TRUCK :Vagão de Madeira
+STR_8023_IRON_ORE_HOPPER :Vagão de Minério de Ferro
+STR_8024_STEEL_TRUCK :Vagão de Aço
+STR_8025_ARMORED_VAN :Vagão Blindado
+STR_8026_FOOD_VAN :Vagão de Comida
+STR_8027_PAPER_TRUCK :Vagão de Papel
+STR_8028_COPPER_ORE_HOPPER :Vagão de Minério de Cobre
+STR_8029_WATER_TANKER :Cisterna de Ãgua
+STR_802A_FRUIT_TRUCK :Vagão de Fruta
+STR_802B_RUBBER_TRUCK :Vagão de Borracha
+STR_802C_SUGAR_TRUCK :Vagão de Açúcar
+STR_802D_COTTON_CANDY_HOPPER :Vagão de Algodão Doce
+STR_802E_TOFFEE_HOPPER :Vagão de Caramelo
+STR_802F_BUBBLE_VAN :Vagão de Bolhas
+STR_8030_COLA_TANKER :Cisterna de Cola
+STR_8031_CANDY_VAN :Vagão de Doces
+STR_8032_TOY_VAN :Vagão de Brinquedos
+STR_8033_BATTERY_TRUCK :Vagão de Baterias
+STR_8034_FIZZY_DRINK_TRUCK :Vagão de Bebidas Gasosas
+STR_8035_PLASTIC_TRUCK :Vagão de Plástico
+STR_8036_X2001_ELECTRIC :'X2001' (Eléctrico)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Eléctrico)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :Carruagem de Passageiros
+STR_803A_MAIL_VAN :Vagão de Correio
+STR_803B_COAL_CAR :Vagão de Carvão
+STR_803C_OIL_TANKER :Cisterna de Petróleo
+STR_803D_LIVESTOCK_VAN :Vagão de Gado
+STR_803E_GOODS_VAN :Vagão de Bens
+STR_803F_GRAIN_HOPPER :Vagão de Cereais
+STR_8040_WOOD_TRUCK :Vagão de Madeira
+STR_8041_IRON_ORE_HOPPER :Vagão de Minério de Ferro
+STR_8042_STEEL_TRUCK :Vagão de Aço
+STR_8043_ARMORED_VAN :Vagão Blindado
+STR_8044_FOOD_VAN :Vagão de Comida
+STR_8045_PAPER_TRUCK :Vagão de Papel
+STR_8046_COPPER_ORE_HOPPER :Vagão de Minério de Cobre
+STR_8047_WATER_TANKER :Cisterna de Ãgua
+STR_8048_FRUIT_TRUCK :Vagão de Fruta
+STR_8049_RUBBER_TRUCK :Vagão de Borracha
+STR_804A_SUGAR_TRUCK :Vagão de Açúcar
+STR_804B_COTTON_CANDY_HOPPER :Vagão de Algodão Doce
+STR_804C_TOFFEE_HOPPER :Vagão de Caramelo
+STR_804D_BUBBLE_VAN :Vagão de Bolhas
+STR_804E_COLA_TANKER :Cisterna de Cola
+STR_804F_CANDY_VAN :Vagão de Doces
+STR_8050_TOY_VAN :Vagão de Brinquedos
+STR_8051_BATTERY_TRUCK :Vagão de Baterias
+STR_8052_FIZZY_DRINK_TRUCK :Vagão de Bebidas Gasosas
+STR_8053_PLASTIC_TRUCK :Vagão de Plástico
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (Eléctrico)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (Eléctrico)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (Eléctrico)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (Eléctrico)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :Carruagem de Passageiros
+STR_805A_MAIL_VAN :Vagão de Correio
+STR_805B_COAL_CAR :Vagão de Carvão
+STR_805C_OIL_TANKER :Cisterna de Petróleo
+STR_805D_LIVESTOCK_VAN :Vagão de Gado
+STR_805E_GOODS_VAN :Vagão de Bens
+STR_805F_GRAIN_HOPPER :Vagão de Cereais
+STR_8060_WOOD_TRUCK :Vagão de Madeira
+STR_8061_IRON_ORE_HOPPER :Vagão de Minério de Ferro
+STR_8062_STEEL_TRUCK :Vagão de Aço
+STR_8063_ARMORED_VAN :Vagão Blindado
+STR_8064_FOOD_VAN :Vagão de Comida
+STR_8065_PAPER_TRUCK :Vagão de Papel
+STR_8066_COPPER_ORE_HOPPER :Vagão de Minério de Cobre
+STR_8067_WATER_TANKER :Cisterna de Ãgua
+STR_8068_FRUIT_TRUCK :Vagão de Fruta
+STR_8069_RUBBER_TRUCK :Vagão de Borracha
+STR_806A_SUGAR_TRUCK :Vagão de Açúcar
+STR_806B_COTTON_CANDY_HOPPER :Vagão de Algodão Doce
+STR_806C_TOFFEE_HOPPER :Vagão de Caramelo
+STR_806D_BUBBLE_VAN :Vagão de Bolhas
+STR_806E_COLA_TANKER :Cisterna de Cola
+STR_806F_CANDY_VAN :Vagão de Doces
+STR_8070_TOY_VAN :Vagão de Brinquedos
+STR_8071_BATTERY_TRUCK :Vagão de Baterias
+STR_8072_FIZZY_DRINK_TRUCK :Vagão de Bebidas Gasosas
+STR_8073_PLASTIC_TRUCK :Vagão de Plástico
+STR_8074_MPS_REGAL_BUS :Autocarro MPS Regal
+STR_8075_HEREFORD_LEOPARD_BUS :Autocarro Hereford Leopard
+STR_8076_FOSTER_BUS :Autocarro Foster
+STR_8077_FOSTER_MKII_SUPERBUS :Autocarro Foster MkII
+STR_8078_PLODDYPHUT_MKI_BUS :Autocarro Ploddyphut MkI
+STR_8079_PLODDYPHUT_MKII_BUS :Autocarro Ploddyphut MkII
+STR_807A_PLODDYPHUT_MKIII_BUS :Autocarro Ploddyphut MkIII
+STR_807B_BALOGH_COAL_TRUCK :Camião de Carvão Balogh
+STR_807C_UHL_COAL_TRUCK :Camião de Carvão Uhl
+STR_807D_DW_COAL_TRUCK :Camião de Carvão DW
+STR_807E_MPS_MAIL_TRUCK :Camião de Correio MPS
+STR_807F_REYNARD_MAIL_TRUCK :Camião de Correio Reynard
+STR_8080_PERRY_MAIL_TRUCK :Camião de Correio Perry
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :Camião de Correio MightyMover
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Camião de Correio Powernaught
+STR_8083_WIZZOWOW_MAIL_TRUCK :Camião de Correio Wizzowow
+STR_8084_WITCOMBE_OIL_TANKER :Cisterna de Petróleo Witcombe
+STR_8085_FOSTER_OIL_TANKER :Cisterna de Petróleo Foster
+STR_8086_PERRY_OIL_TANKER :Cisterna de Petróleo Perry
+STR_8087_TALBOTT_LIVESTOCK_VAN :Camião de Gado Talbott
+STR_8088_UHL_LIVESTOCK_VAN :Camião de Gado Uhl
+STR_8089_FOSTER_LIVESTOCK_VAN :Camião de Gado Foster
+STR_808A_BALOGH_GOODS_TRUCK :Camião de Bens Balogh
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Camião de Bens Craighead
+STR_808C_GOSS_GOODS_TRUCK :Camião de Bens Goss
+STR_808D_HEREFORD_GRAIN_TRUCK :Camião de Cereais Hereford
+STR_808E_THOMAS_GRAIN_TRUCK :Camião de Cereais Thomas
+STR_808F_GOSS_GRAIN_TRUCK :Camião de Cereais Goss
+STR_8090_WITCOMBE_WOOD_TRUCK :Camião de Madeira Witcombe
+STR_8091_FOSTER_WOOD_TRUCK :Camião de Madeira Foster
+STR_8092_MORELAND_WOOD_TRUCK :Camião de Madeira Moreland
+STR_8093_MPS_IRON_ORE_TRUCK :Camião de Minério de Ferro MPS
+STR_8094_UHL_IRON_ORE_TRUCK :Camião de Minério de Ferro Uhl
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Camião de Minério de Ferro Chippy
+STR_8096_BALOGH_STEEL_TRUCK :Camião de Aço Balogh
+STR_8097_UHL_STEEL_TRUCK :Camião de Aço Uhl
+STR_8098_KELLING_STEEL_TRUCK :Camião de Aço Kelling
+STR_8099_BALOGH_ARMORED_TRUCK :Camião Blindado Balogh
+STR_809A_UHL_ARMORED_TRUCK :Camião Blindado Uhl
+STR_809B_FOSTER_ARMORED_TRUCK :Camião Blindado Foster
+STR_809C_FOSTER_FOOD_VAN :Camião de Comida Foster
+STR_809D_PERRY_FOOD_VAN :Camião de Comida Perry
+STR_809E_CHIPPY_FOOD_VAN :Camião de Comida Chippy
+STR_809F_UHL_PAPER_TRUCK :Camião de Papel Uhl
+STR_80A0_BALOGH_PAPER_TRUCK :Camião de Papel Balogh
+STR_80A1_MPS_PAPER_TRUCK :Camião de Papel MPS
+STR_80A2_MPS_COPPER_ORE_TRUCK :Camião de Minério de Cobre MPS
+STR_80A3_UHL_COPPER_ORE_TRUCK :Camião de Minério de Cobre Uhl
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Camião de Minério de Cobre Goss
+STR_80A5_UHL_WATER_TANKER :Cisterna de Ãgua Uhl
+STR_80A6_BALOGH_WATER_TANKER :Cisterna de Ãgua Balogh
+STR_80A7_MPS_WATER_TANKER :Cisterna de Ãgua MPS
+STR_80A8_BALOGH_FRUIT_TRUCK :Camião de Fruta Balogh
+STR_80A9_UHL_FRUIT_TRUCK :Camião de Fruta Uhl
+STR_80AA_KELLING_FRUIT_TRUCK :Camião de Fruta Kelling
+STR_80AB_BALOGH_RUBBER_TRUCK :Camião de Borracha Balogh
+STR_80AC_UHL_RUBBER_TRUCK :Camião de Borracha Uhl
+STR_80AD_RMT_RUBBER_TRUCK :Camião de Borracha RMT
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :Camião de Açúcar MightyMover
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Camião de Açúcar Powernaught
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Camião de Açúcar Wizzowow
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :Camião de Cola MightyMover
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Camião de Cola Powernaught
+STR_80B3_WIZZOWOW_COLA_TRUCK :Camião de Cola Wizzowow
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :Camião de Algodão Doce MightyMover
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Camião de Algodão Doce Powernaught
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Camião de Algodão Doce Wizzowow
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :Camião de Caramelo MightyMover
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Camião de Caramelo Powernaught
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Camião de Caramelo Wizzowow
+STR_80BA_MIGHTYMOVER_TOY_VAN :Camião de Brinquedos MightyMover
+STR_80BB_POWERNAUGHT_TOY_VAN :Camião de Brinquedos Powernaught
+STR_80BC_WIZZOWOW_TOY_VAN :Camião de Brinquedos Wizzowow
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :Camião de Doces MightyMover
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Camião de Doces Powernaught
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Camião de Doces Wizzowow
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :Camião de Baterias MightyMover
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Camião de Baterias Powernaught
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Camião de Baterias Wizzowow
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :Camião de Bebidas Gasosas MightyMover
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Camião de Bebidas Gasosas Powernaught
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Camião de Bebidas Gasosas Wizzowow
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :Camião de Plástico MightyMover
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Camião de Plástico Powernaught
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Camião de Plástico Wizzowow
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :Camião de Bolhas MightyMover
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Camião de Bolhas Powernaught
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Camião de Bolhas Wizzowow
+STR_80CC_MPS_OIL_TANKER :Cisterna de Petróleo MPS
+STR_80CD_CS_INC_OIL_TANKER :Cisterna de Petróleo CS-Inc.
+STR_80CE_MPS_PASSENGER_FERRY :Barco de Passageiros MPS
+STR_80CF_FFP_PASSENGER_FERRY :Barco de Passageiros FFP
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Hovercraft Bakewell 300
+STR_80D1_CHUGGER_CHUG_PASSENGER :Barco de Passageiros Chugger-Chug
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Barco de Passageiros Shivershake
+STR_80D3_YATE_CARGO_SHIP :Barco de Mercadorias Yate
+STR_80D4_BAKEWELL_CARGO_SHIP :Barco de Mercadorias Bakewell
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Barco de Mercadorias Mightymover
+STR_80D6_POWERNAUT_CARGO_SHIP :Barco de Mercadorias Powernaut
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Helicóptero Tricario
+STR_80FE_GURU_X2_HELICOPTER :Helicóptero Guru X2
+STR_80FF_POWERNAUT_HELICOPTER :Helicóptero Powernaut
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Mensagem de um fabricante de veículos
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}Projectámos um novo {STRING} - gostaria de ter um ano de exclusividade de uso deste veículo, de modo a que possamos avaliar a sua performance antes de o disponibilizar para todos ?
+STR_8102_RAILROAD_LOCOMOTIVE :locomotiva ferroviária
+STR_8103_ROAD_VEHICLE :veículo de estrada
+STR_8104_AIRCRAFT :aeronave
+STR_8105_SHIP :barco
+STR_8106_MONORAIL_LOCOMOTIVE :locomotiva monocarril
+STR_8107_MAGLEV_LOCOMOTIVE :locomotiva maglev
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}{TOWN} Depósito Ferroviário
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Cidadãos celebram . . .{}Primeiro comboio chega a {STATION}!
+STR_8802_DETAILS :{WHITE}{STRING} (Detalhes)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Comboio no caminho
+STR_8804 :{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8806_GO_TO :Ir para {STATION}
+STR_8807_GO_TO_TRANSFER :Ir para {STATION} (Transferir e levar carga)
+STR_8808_GO_TO_UNLOAD :Ir para {STATION} (Descarregar)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Ir para {STATION} (Transferir e deixar vazio)
+STR_880A_GO_TO_LOAD :Ir para {STATION} (Carregar)
+STR_880B_GO_TO_TRANSFER_LOAD :Ir para {STATION} (Transferir e aguardar carga completa)
+STR_880C_GO_NON_STOP_TO :Ir sem parar para {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Ir sem parar para {STATION} (Transfer ir e levar carga)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Ir sem parar para {STATION} (Descarregar)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Ir sem parar para {STATION} (Transferir e deixar vazio)
+STR_8810_GO_NON_STOP_TO_LOAD :Ir sem parar para {STATION} (Carregar)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Ir sem parar para {STATION} (Transferir e aguardar carga completa)
+STR_GO_TO_TRAIN_DEPOT :Ir para o depósito de {TOWN}
+STR_SERVICE_AT_TRAIN_DEPOT :Manutenção no depósito de {TOWN}
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Ir sem parar para o depósito de {TOWN}
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Manutenção no depósito de {TOWN} sem parar
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}Dirige-se ao depósito de {TOWN}
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}Dirige-se ao depósito de {TOWN}, {VELOCITY}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE :{LTBLUE}Serviço no depósito de {TOWN}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE_VEL :{LTBLUE}Serviço no depósito de {TOWN}, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (Ordem Inválida)
+
+STR_UNKNOWN_DESTINATION :destino desconhecido
+STR_8812_EMPTY :{LTBLUE}Vazio
+STR_8813_FROM :{LTBLUE}{CARGO} de {STATION}
+STR_FROM_MULT :{LTBLUE}{CARGO} de {STATION} (x{NUM})
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}Comboio {COMMA} está a aguardar no depósito
+STR_8815_NEW_VEHICLES :{BLACK}Novos Veículos
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Comboio muito longo
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Os comboios só podem ser alterados quando parados num depósito
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} Comboios
+
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Novos Veículos Ferroviários
+STR_NEW_ELRAIL_VEHICLES :{WHITE}Novos comboios para carris electrificados
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Novos Veículos Monocarril
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Novos Veículos Maglev
+STR_ALL_AVAIL_RAIL_VEHICLES :{WHITE}Veículos sobre carris
+
+STR_881F_BUILD_VEHICLE :{BLACK}Construir Veículo
+STR_CLONE_ROAD_VEHICLE :{BLACK}Clonar Veículo
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}Esta acção criará uma cópia do veículo. Pressione Ctrl enquanto clica, para partilhar as ordens
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Esta acção criará uma cópia de um veículo. Clique neste botão e, de seguida, num veículo que se encontre dentro ou fora do depósito. Pressione Ctrl enquanto clica para partilhar as ordens
+STR_CLONE_TRAIN :{BLACK}Clonar Comboio
+STR_CLONE_TRAIN_INFO :{BLACK}Esta acção criará uma cópia do comboio, incluindo as carruagens. Pressione Ctrl enquanto clica, para partilhar as ordens
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}Esta acção criará uma cópia de um comboio, incluindo as carruagens. Clique neste botão e, de seguida, num comboio que se encontre dentro ou fora do depósito. Pressione Ctrl enquanto clica para partilhar as ordens
+STR_8820_RENAME :{BLACK}Renomear
+STR_8823_SKIP :{BLACK}Saltar
+STR_8824_DELETE :{BLACK}Eliminar
+STR_8825_NON_STOP :{BLACK}Sem parar
+STR_8826_GO_TO :{BLACK}Ir Para
+STR_8827_FULL_LOAD :{BLACK}Carga
+STR_8828_UNLOAD :{BLACK}Descarga
+STR_REFIT :{BLACK}Reconverter
+STR_REFIT_TIP :{BLACK}Escolha o tipo de carga para reconverter nesta ordem. Control click para remover a instrução de reconversão
+STR_REFIT_ORDER :(Reconverter para {STRING})
+STR_8829_ORDERS :{WHITE}{VEHICLE} (Ordens)
+STR_882A_END_OF_ORDERS :{SETX 10}- - Fim de Ordens - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}Manutenção
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Não é possível construir veículo ferroviário...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Construído: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Valor: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}A carregar / descarregar
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}Comboio tem que estar parado dentro do depósito
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Não é possível mandar o comboio para o depósito...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Não há espaço para mais ordens
+STR_8832_TOO_MANY_ORDERS :{WHITE}Demasiadas ordens
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Não é possível inserir nova ordem...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Não é possível eliminar esta ordem...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Não é possível modificar esta ordem...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Não é possível mover veículo...
+STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}A locomotiva traseira seguirá sempre a sua parceira frontal
+STR_8838_N_A :N/D{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Não é possível vender veículo ferroviário...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Não é possível encontrar rota para o depósito local
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Não é possível iniciar/parar comboio...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Intervalo de serviço: {LTBLUE}{COMMA}dias{BLACK} Último serviço: {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Intervalo de serviço: {LTBLUE}{COMMA}%{BLACK} Último serviço: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Comboios - clique num comboio para informações
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Construir novos comboios (necessita de depósito de comboios)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Comboios - clique num comboio para informações, arraste um veículo para o adicionar/remover ao comboio
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Construir novo veículo ferroviário
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Arraste o veículo ferroviário para aqui para o vender
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centrar visualização na localização de um depósito ferroviário
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Lista de veículos ferroviários - clique num veículo para informações
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Construir o veículo ferroviário seleccionado
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Renomear tipo de veículo ferroviário
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Tarefa actual do comboio - clique aqui para iniciar/parar comboio
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Mostrar ordens do comboio
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centrar visualização na localização do comboio
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Mandar comboio para o depósito
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Forçar comboio a prosseguir sem esperar pelo sinal
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Inverter direcção do comboio
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Mostrar detalhes do comboio
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Aumentar intervalo de serviço
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Diminuir intervalo de serviço
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Mostrar detalhes da carga transportada
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Mostrar detalhes dos veículos
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Mostrar capacidades de cada veículo
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Mostrar capacidade total do comboio, dividir por tipo de carga
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Lista de ordens - clique numa ordem para a seleccionar
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}Saltar a ordem actual, e iniciar a próxima
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Eliminar a ordem seleccionada
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}A ordem seleccionada fará com que o veículo não para noutras estações pelo caminho
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Inserir nova ordem antes da ordem seleccionada, ou adicionar ao fim da lista
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}A ordem seleccionada fará com que o veículo espere carregar completamente
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}A ordem seleccionada forçará o veículo a descarregar
+STR_SERVICE_HINT :{BLACK}Saltar esta ordem a menos que seja necessário manutenção
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}Novo {STRING} disponível!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Custo: {CURRENCY} Peso: {WEIGHT_S}{}Velocidade: {VELOCITY} Potência: {POWER}{}Custo de circulação: {CURRENCY}/ano{}Capacidade: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}Avariado
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}Idade: {LTBLUE}{STRING}{BLACK} Custo de circulação: {LTBLUE}{CURRENCY}/ano
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Peso: {LTBLUE}{WEIGHT_S} {BLACK}Potência: {LTBLUE}{POWER}{BLACK} Velocidade Máx.: {LTBLUE}{VELOCITY}
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Peso: {LTBLUE}{WEIGHT_S} {BLACK}Potência: {LTBLUE}{POWER}{BLACK} Veloc. máx.: {LTBLUE}{VELOCITY} {BLACK}F. Trac. Máx.: {LTBLUE}{FORCE}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Lucros deste ano: {LTBLUE}{CURRENCY} (último ano: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}Fiabilidade: {LTBLUE}{COMMA}% {BLACK}Avarias desde a última manutenção: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Parado
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Não é possível fazer o comboio passar o sinal de perigo...
+STR_8863_CRASHED :{RED}Acidentado!
+
+STR_8865_NAME_TRAIN :{WHITE}Renomear comboio
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}Não é possível renomear comboio...
+STR_8867_NAME_TRAIN :{BLACK}Renomear comboio
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Acidente Ferroviário!{}{COMMA} mortos numa explosão após a colisão
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Não é possível inverter a direcção do comboio...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Renomear tipo de veículo ferroviário
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Não é possível renomear tipo de veículo ferroviário...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}A ordem seleccionada forçará o veículo a largar a carga
+STR_886F_TRANSFER :{BLACK}Transferir
+
+STR_TRAIN_STOPPING :{RED}A Parar
+STR_TRAIN_STOPPING_VEL :{RED}A Parar, {VELOCITY}
+STR_INCOMPATIBLE_RAIL_TYPES :Vias férreas incompatíveis
+STR_TRAIN_NO_POWER :{RED}Sem energia
+STR_TRAIN_START_NO_CATENARY :Esta linha não tem catenária, o comboio não pode arrancar
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Veículo de estrada no caminho
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} Veículos de Estrada
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}{TOWN} Depósito de Veículos de Estrada
+STR_9004_NEW_VEHICLES :{BLACK}Novos Veículos
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}Novos Veículos de Estrada
+STR_9007_BUILD_VEHICLE :{BLACK}Construir Veículo
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Não é possível construir veículo de estrada...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (Detalhes)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}Idade: {LTBLUE}{STRING}{BLACK} Custo de circulação: {LTBLUE}{CURRENCY}/ano
+STR_900E_MAX_SPEED :{BLACK}Velocidade Máx.: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Lucros deste ano: {LTBLUE}{CURRENCY} (último ano: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}Fiabilidade: {LTBLUE}{COMMA}% {BLACK}Avarias desde a última manutenção: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Construído: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Capacidade: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}...deve estar parado num depósito de veículos de estrada
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Não é possível vender veículo de estrada...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Não é possível iniciar/parar veículo de estrada...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}Veículo de Estrada {COMMA} está a aguardar no depósito
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}Dirige-se ao depósito de {TOWN}
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}Dirige-se ao depósito de {TOWN}, {VELOCITY}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE :{LTBLUE}Serviço no depósito de {TOWN}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE_VEL :{LTBLUE}Serviço no depósito de {TOWN}, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Não é possível mandar o veículo para o depósito...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Não é possível encontrar o depósito local
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Veículos de estrada - clique num veículo para informações
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Construir novos veículos de estrada (necessita de depósito de veículos de estrada)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Tarefa actual do veículo - clique aqui para iniciar/parar veículo
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Mostrar ordens do veículo
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Centrar visualização na localização do veículo
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Mandar veículo para o depósito
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Forçar veículo a dar a volta
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Mostrar detalhes do veículo de estrada
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Veículos - clique num veículo para informações
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Construir novo veículo de estrada
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Arraste o veículo de estrada para aqui para o vender
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Centrar visualização na localização do depósito de veículos de estrada
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Lista de veículos de estrada - clique num veículo para informações
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Construir o veículo de estrada seleccionado
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}Novo veículo de estrada disponível!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Custo: {CURRENCY}{}Velocidade: {VELOCITY}{}Custo de circulação: {CURRENCY}/ano{}Capacidade: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Renomear veículo de estrada
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Não é possível renomear veículo de estrada...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Renomear veículo de estrada
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Cidadãos celebram . . .{}Primeiro autocarro chega a {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Cidadãos celebram . . .{}Primeiro camião chega a {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}Acidente de Veículo de Estrada!{}Condutor morre na explosão após a colisão com um comboio
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}Acidente de Veículo de Estrada!{}{COMMA} morrem na explosão após a colisão com um comboio
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Não é possível fazer o veículo dar a volta...
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}Não é possível virar comboios compostos por unidades múltiplas
+STR_9034_RENAME :{BLACK}Renomear
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Renomear tipo de veículo de estrada
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Renomear tipo de veículo de estrada
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Não é possível renomear tipo de veículo de estrada...
+STR_9038_GO_TO_ROADVEH_DEPOT :Ir para o depósito de {TOWN}
+STR_SERVICE_AT_ROADVEH_DEPOT :Manutenção no depósito de {TOWN}
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Reconverter veículo para transportar outro tipo de carga
+STR_REFIT_ROAD_VEHICLE :{BLACK}Reconverter veiculo
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Reconverter veículo para transportar o tipo de carga seleccionado
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Não é possível reconverter veículo
+STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Seleccione o tipo de carga para o veículo
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Construir docas
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Construir docas
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Não é possível construir doca aqui...
+STR_9803_SHIP_DEPOT :{WHITE}{TOWN} Depósito Naval
+STR_9804_NEW_SHIPS :{BLACK}Novos Barcos
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} Barcos
+STR_9808_NEW_SHIPS :{WHITE}Novos Barcos
+STR_9809_BUILD_SHIP :{BLACK}Construir Barco
+STR_CLONE_SHIP :{BLACK}Clonar Navio
+STR_CLONE_SHIP_INFO :{BLACK}Esta acção criará uma cópia do navio. Pressione Ctrl enquanto clica, para partilhar as ordens
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}Esta acção criará uma cópia de um navio. Clique neste botão e, de seguida, num navio que se encontre dentro ou fora do depósito. Pressione Ctrl enquanto clica para partilhar as ordens
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}O barco deverá estar parado no depósito
+STR_980C_CAN_T_SELL_SHIP :{WHITE}Não é possível vender barco...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Não é possível construir barco...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Barco no caminho
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Detalhes)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}Idade: {LTBLUE}{STRING}{BLACK} Custo de circulação: {LTBLUE}{CURRENCY}/ano
+STR_9813_MAX_SPEED :{BLACK}Velocidade Máx.: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Lucros deste ano: {LTBLUE}{CURRENCY} (último ano: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}Fiabilidade: {LTBLUE}{COMMA}% {BLACK}Avarias desde a última manutenção: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Construído: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}Capacidade: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}Não é possível iniciar/parar barco...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Não é possível mandar barco para o depósito...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Não é possível encontrar depósito local
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}Dirige-se ao depósito de {TOWN}
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}Dirige-se ao depósito de {TOWN}, {VELOCITY}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE :{LTBLUE}Serviço no depósito de {TOWN}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE_VEL :{LTBLUE}Serviço no depósito de {TOWN}, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}Barco {COMMA} está a aguardar no depósito
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Construir doca naval
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Construir depósito (para criação e manutenção de barcos)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Barcos - clique num barco para informações
+STR_9820_BUILD_NEW_SHIP :{BLACK}Construir novo barco
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Arraste o barco para aqui para o vender
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centrar visualização na localização do depósito naval
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Barcos - clique num barco para informações
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Construir novos barcos (necessita de depósito naval)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}Lista de barcos - clique num barco para informações
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Construir barco seleccionado
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Tarefa actual do barco - clique aqui para iniciar/parar barco
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Mostrar ordens do barco
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centrar visualização na localização do barco
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Mandar barco para o depósito
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Mostrar detalhes do barco
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}Novo barco disponível!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Custo: {CURRENCY} Velocidade Máx.: {VELOCITY}{}Capacidade: {CARGO}{}Custo de circulação: {CURRENCY}/ano
+STR_982F_NAME_SHIP :{BLACK}Renomear barco
+
+STR_9831_NAME_SHIP :{WHITE}Renomear barco
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Não é possível renomear barco...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Cidadãos celebram . . .{}Primeiro barco chega a {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Bóia de posição, que pode ser usada para marcar pontos de rota adicionais
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Não é possível posicionar bóia aqui...
+STR_9836_RENAME :{BLACK}Renomear
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Renomear tipo de barco
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Renomear tipo de barco
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Não é possível renomear tipo de barco...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Adaptar barco de mercadorias para um tipo de carga diferente
+STR_983B_REFIT :{WHITE}{VEHICLE} (Adaptar)
+STR_983C_REFIT_SHIP :{BLACK}Adaptar barco
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Seleccionar tipo de carga do barco
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Adaptar barco para transportar a carga seleccionada
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Seleccionar tipo de carga:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nova capacidade: {GOLD}{CARGO}{}{BLACK}Custo da adaptação: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Não é possível adaptar barco...
+STR_9842_REFITTABLE :(adaptável)
+STR_GO_TO_SHIP_DEPOT :Ir para o depósito naval de {TOWN}
+SERVICE_AT_SHIP_DEPOT :Manutenção no depósito de {TOWN}
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Aeroportos
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Não é possível construir aeroporto aqui...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} Hangar
+STR_A003_NEW_AIRCRAFT :{BLACK}Nova Aeronave
+STR_CLONE_AIRCRAFT :{BLACK}Clonar Aeronave
+STR_CLONE_AIRCRAFT_INFO :{BLACK}Esta acção criará uma cópia da aeronave. Pressione Ctrl enquanto clica, para partilhar as ordens
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Esta acção criará uma cópia de uma aeronave. Clique neste botão e, de seguida, numa aeronave que se encontre dentro ou fora do hangar. Pressione Ctrl enquanto clica para partilhar as ordens
+STR_A005_NEW_AIRCRAFT :{WHITE}Nova Aeronave
+STR_A006_BUILD_AIRCRAFT :{BLACK}Construir Aeronave
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Não é possível construir aeronave...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} Aeronaves
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (Ordens)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (Detalhes)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Idade: {LTBLUE}{STRING}{BLACK} Custo de circulação: {LTBLUE}{CURRENCY}/ano
+STR_A00E_MAX_SPEED :{BLACK}Velocidade Máx.: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Lucros deste ano: {LTBLUE}{CURRENCY} (último ano: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}Fiabilidade: {LTBLUE}{COMMA}% {BLACK}Avarias desde a última manutenção: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Construído: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Não é possível mandar aeronave para o hangar...
+STR_HEADING_FOR_HANGAR :{ORANGE}Dirige-se ao hangar de {STATION}
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}Dirige-se ao hangar de {STATION}, {VELOCITY}
+STR_HEADING_FOR_HANGAR_SERVICE :{LTBLUE}Serviço no hangar de {STATION}
+STR_HEADING_FOR_HANGAR_SERVICE_VEL :{LTBLUE}Serviço no hangar de {STATION}, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}Aeronave {COMMA} está a aguardar no hangar
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Aeronave no caminho
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Não é possível iniciar/parar aeronave...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Aeronave está em voo
+STR_A019_CAPACITY :{BLACK}Capacidade: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Capacidade: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}A aeronave deverá estar parada no hangar
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Não é possível vender aeronave...
+STR_A01D_AIRPORT_CONSTRUCTION :Construir aeroporto
+STR_A01E_BUILD_AIRPORT :{BLACK}Construir aeroporto
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Aeronave - clique na aeronave para informações
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Construir nova aeronave (necessita de aeroporto com hangar)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Aeronave - clique na aeronave para informações
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Construir nova aeronave
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}Arraste a aeronave para aqui para a vender
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Centrar visualização na localização do hangar
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Lista de aeronaves - clique na aeronave para informações
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Construir aeronave seleccionada
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Tarefa actual da aeronave - clique aqui para iniciar/parar a aeronave
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Mostrar ordens da aeronave
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Centrar visualização na localização da aeronave
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Mandar aeronave para o hangar
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Mostrar detalhes da aeronave
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}Nova aeronave disponível!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Custo: {CURRENCY} Velocidade Máx.: {VELOCITY}{}Capacidade: {COMMA} passageiros, {COMMA} sacos de correio{}Custo de circulação: {CURRENCY}/ano
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Renomear aeronave
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Não é possível renomear aeronave...
+STR_A032_NAME_AIRCRAFT :{BLACK}Renomear aeronave
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Cidadãos celebram . . .{}Primeira aeronave chega a {STATION}!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Acidente de Avião!{}{COMMA} morrem na explosão em {STATION}
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Desastre de Avião!{}Avião ficou sem combustivél, {COMMA} morreram em incêndiol!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Renomear
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Renomear tipo de aeronave
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Renomear tipo de aeronave
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Não é possível renomear tipo de aeronave...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Adaptar aeronave para um tipo de carga diferente
+STR_A03C_REFIT :{WHITE}{VEHICLE} (Adaptar)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Adaptar aeronave
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Seleccionar tipo de carga da aeronave
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Adaptar aeronave para transportar a carga seleccionada
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Seleccionar tipo de carga:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nova capacidade: {GOLD}{STRING}{}{BLACK}Custo da adaptação: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Não é possível adaptar aeronave...
+STR_GO_TO_AIRPORT_HANGAR :Ir para o hangar de {STATION}
+SERVICE_AT_AIRPORT_HANGAR :Manutenção no hangar de {STATION}
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}Acidente de Zepelim em {STATION}!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Veículo de estrada destruído em colisão com OVNI!
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}Explosão na refinaria de petróleo em {TOWN}!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}Fábrica destruída em circunstâncias suspeitas em {TOWN}!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}OVNI pousa em {TOWN}!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}Afundamento de mina de carvão deixa um rasto de destruição em {TOWN}!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Inundações!{}Pelo menos {COMMA} perdidos ou mortos após terríveis inundações!
+
+STR_BRIBE_FAILED :{WHITE}A sua tentativa de suborno foi
+STR_BRIBE_FAILED_2 :{WHITE}descoberta por um investigador regional
+STR_BUILD_DATE :{BLACK}Construído: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Detalhes de rendimentos
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}Detalhes
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Veículos:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Estações:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Min. lucros:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Min. rendimentos:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Máx. rendimentos:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Entregue:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Carga:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Dinheiro:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Empréstimo:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Total:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Número de veículos. Incluindo veículos de estrada, comboios, barcos e aeronaves.
+STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}Número de segmentos de estação. Cada parte de uma estação (ex. estação ferroviária, paragem de autocarro, aeroporto) é contabilizado, mesmo se eles estiverem ligados a uma estação.
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}O lucro do veículo com o rendimento menor (de todos os veículos com mais de 2 anos)
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Dinheiro conseguido no mês com os lucros mais baixos dos últimos 12 trimestres
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Dinheiro conseguido no mês com os lucros mais altos dos últimos 12 trimestres
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}Unidades de carga entregues nos últimos 4 trimestres.
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}Tipos de carga entregues no último trimestre.
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Dinheiro 'em mãos'
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}Tem um empréstimo muito elevado?
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Total de pontos sobre o máximo de pontos
+
+STR_NEWGRF_SETTINGS_BUTTON :{BLACK}Definições NewGRF
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}Definições Newgrf
+STR_NEWGRF_APPLY_CHANGES :{BLACK}Aplicar alterações
+STR_NEWGRF_SET_PARAMETERS :{BLACK}Definir parâmetros
+STR_NEWGRF_TIP :{BLACK}Lista de todos os conjuntos Newgrf que instalou. Clique num conjunto para alterar as definições.
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}Não existem ficheiros newgrf actualmente instalados! Por favor consulte o manual para instruções sobre instalar novos gráficos.
+STR_NEWGRF_FILENAME :{BLACK}Nome do ficheiro: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
+STR_NEWGRF_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING}
+STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}Vai alterar um jogo em andamento; o OpenTTD pode terminar abruptamente.{}Tem a certeza que quer continuar?
+
+STR_NEWGRF_ADD :{BLACK}Adicionar
+STR_NEWGRF_ADD_TIP :{BLACK}Adicionar um ficheiro NewGRF à lista
+STR_NEWGRF_REMOVE :{BLACK}Remover
+STR_NEWGRF_REMOVE_TIP :{BLACK}Remover o ficheiro NewGRF seleccionado da lista
+STR_NEWGRF_MOVEUP :{BLACK}Para Cima
+STR_NEWGRF_MOVEUP_TIP :{BLACK}Mover o ficheiro NewGRF seleccionado para cima na lista
+STR_NEWGRF_MOVEDOWN :{BLACK}Para Baixo
+STR_NEWGRF_MOVEDOWN_TIP :{BLACK}Mover o ficheiro NewGRF seleccionado para baixo na lista
+STR_NEWGRF_FILE_TIP :{BLACK}Lista dos ficheiros NewGRF instalados. Clique num ficheiro para alterar os seus parâmetros
+STR_NEWGRF_PARAMETER :{BLACK}Parâmetros: {SILVER}{STRING}
+STR_NEWGRF_PARAMETER_QUERY :{BLACK}Insira parâmetros do NewGRF
+STR_NEWGRF_NO_INFO :{BLACK}Sem informação disponível
+
+STR_NEWGRF_ADD_CAPTION :{WHITE}Ficheiros NewGRF disponíveis
+STR_NEWGRF_ADD_FILE :{BLACK}Adicionar à selecção
+STR_NEWGRF_ADD_FILE_TIP :{BLACK}Adicionar o ficheiro NewGRF seleccionado à configuração
+STR_NEWGRF_RESCAN_FILES :{BLACK}Reler ficheiros
+STR_NEWGRF_RESCAN_FILES_TIP :{BLACK}Actualizar a lista de ficheiros NewGRF disponíveis
+STR_NEWGRF_DUPLICATE_GRFID :{WHITE}Impossível adicionar ficheiro: GRF ID duplicado
+
+STR_NEWGRF_NOT_FOUND :{RED}Ficheiro correspondente não encontrado
+STR_NEWGRF_DISABLED :{RED}Desactivado
+
+STR_CURRENCY_WINDOW :{WHITE}Moeda Modificada
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Taxa de troca: {ORANGE}{CURRENCY} = £ {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Separador:
+STR_CURRENCY_PREFIX :{LTBLUE}Prefixo:
+STR_CURRENCY_SUFFIX :{LTBLUE}Sufixo:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Mudar para Euro: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Mudar para Euro: {ORANGE}nunca
+STR_CURRENCY_PREVIEW :{LTBLUE}Prevêr: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Mudar parametro de moeda modificada
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} Comboios
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} Veiculos de Estrada
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} Aviões
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} Barcos
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Mostrar todos os comboios que têm esta estação nas ordens de serviço
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Mostrar todos os veiculos de estrada que têm esta estação nas ordens de serviço
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Mostrar todos os aviões que têm esta estação nas ordens de serviço
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Mostrar todos os navios de cujo itinerário esta estação faz parte
+
+STR_VEH_WITH_SHARED_ORDERS_LIST :{WHITE}Ordens partilhadas de {COMMA} veículo{P "" s}
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}Mostra todos os veículos que seguem o mesmo trajecto
+
+### depot strings
+STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Está prestes a vender todos os veículos no depósito. Tem a certeza?
+
+STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP :{BLACK}Vender todos os combóios no depósito
+STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP :{BLACK}Vender todos os veículos no depósito
+STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP :{BLACK}Vender todos os navios no depósito
+STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP :{BLACK}Vender todos os aviões no hangar
+
+STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP :{BLACK}Obter uma lista de todos os combóios em cujas ordens conste este depósito
+STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP :{BLACK}Obter uma lista de todos os veículos em cujas ordens conste este depósito
+STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP :{BLACK}Obter uma lista de todos os navios em cujas ordens conste este depósito
+STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP :{BLACK}Obter uma lista de todas as aeronaves em cujas ordens conste um hangar deste aeroporto
+
+STR_DEPOT_AUTOREPLACE_TRAIN_TIP :{BLACK}Autosubstituir todos os comboios no depósito
+STR_DEPOT_AUTOREPLACE_ROADVEH_TIP :{BLACK}Autosubstituir todos os veículos de estrada no depósito
+STR_DEPOT_AUTOREPLACE_SHIP_TIP :{BLACK}Autosubstituir todos os barcos no depósito
+STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP :{BLACK}Autosubstituir todas as aeronaves no depósito
+
+STR_VEHICLE_LIST_TRAIN_DEPOT :{BLACK}{STRING} - {COMMA} Comboio{P "" s}
+STR_VEHICLE_LIST_ROADVEH_DEPOT :{BLACK}{STRING} - {COMMA} Veículo{P "" s} de Estrada
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} Barco{P "" s}
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} Aeronave{P "" s}
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}Substituir {STRING}
+STR_REPLACE_VEHICLES_START :{BLACK}Iniciar Substituição de Veículos
+STR_REPLACE_VEHICLES_STOP :{BLACK}Parar Substituição de Veículos
+STR_NOT_REPLACING :{BLACK}Não substituindo
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Nenhum veículo seleccionado
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Seleccione o tipo de motor a substituir
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Seleccione o novo tipo de motor para substituir o que seleccionou à esquerda
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Pressione para parar a subsituição do tipo de motor que seleccionou à esquerda
+STR_REPLACE_HELP_START_BUTTON :{BLACK}Pressione para iniciar a substituição do tipo de motor que seleccionou à esquerda, com o tipo de motor seleccionado à direita
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Seleccione o tipo de carril para o qual deseja efectuar a substituição dos motores
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Exibe o tipo de motor que substituirá o que está seleccionado à esquerda, se algum
+STR_REPLACE_HELP :{BLACK}Permite a substiuição de um tipo de motor por outro, quando comboios do tipo original entram num depósito
+STR_REPLACE_REMOVE_WAGON :{BLACK}Remover vagões: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Forçar a substituição automática a manter o comprimento do comboio, removendo vagões (do início), nas situações em que a substituição da locomotiva resultar num comboio maior.
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}Trocando: {ORANGE}{SKIP}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} FUNCIONALIDADE EXPERIMENTAL{}Alternar entre a janela de substituição de locomotivas e a janela de substituição de vagões.{}A substituição de vagões só ocorrerá se o novo vagão puder ser reconvertido para o mesmo tipo de carga que o vagão antigo. Esta verificação ocorre para cada vagão, durante a substituição.
+STR_ENGINE_NOT_BUILDABLE :{WHITE}Locomotiva não construível
+
+STR_ENGINES :Locomotivas
+STR_WAGONS :Vagões
+
+STR_MASS_STOP_DEPOT_TRAIN_TIP :{BLACK}Pressione botão esquerdo do rato para imobilizar todos os combóios no depósito
+STR_MASS_STOP_DEPOT_ROADVEH_TIP :{BLACK}Pressione botão esquerdo do rato para imobilizar todos os veículos no depósito
+STR_MASS_STOP_DEPOT_SHIP_TIP :{BLACK}Pressione botão esquerdo do rato para imobilizar todos os navios no depósito
+STR_MASS_STOP_HANGAR_TIP :{BLACK}Pressione botão esquerdo do rato para imobilizar todas as aeronaves no hangar
+
+STR_MASS_START_DEPOT_TRAIN_TIP :{BLACK}Pressione botão esquerdo do rato para iniciar todos os combóios no depósito
+STR_MASS_START_DEPOT_ROADVEH_TIP :{BLACK}Pressione botão esquerdo do rato para iniciar todos os veículos de estrada no depósito
+STR_MASS_START_DEPOT_SHIP_TIP :{BLACK}Pressione botão esquerdo do rato para iniciar todos os navios no depósito
+STR_MASS_START_HANGAR_TIP :{BLACK}Pressione botão esquerdo do rato para iniciar todas as aeronaves no hangar
+
+STR_MASS_STOP_LIST_TIP :{BLACK}Pressione botão esquerdo do rato para imobilizar todos os veículos na lista
+STR_MASS_START_LIST_TIP :{BLACK}Pressione botão esquerdo do rato para iniciar todos os veículos na lista
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}Lista de sinais - {COMMA} Sinais
+
+STR_ORDER_REFIT_FAILED :{WHITE}Erro na ordem de reconversão {STRING} {COMMA}
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :Comboios
+STR_ELRAIL_VEHICLES :Combóios para carris electrificados
+STR_MONORAIL_VEHICLES :Monocarris
+STR_MAGLEV_VEHICLES :Maglevs
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Custo: {GOLD}{CURRENCY}{BLACK} Peso: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Velocidade: {GOLD}{VELOCITY}{BLACK} Potência: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}Velocidade: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Custo de manutenção: {GOLD}{CURRENCY}/ano
+STR_PURCHASE_INFO_CAPACITY :{BLACK}Capacidade: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Concebido: {GOLD}{NUM}{BLACK} Vida útil: {GOLD}{COMMA} anos
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}Fiabilidade máxima: {GOLD}{COMMA}%
+STR_PURCHASE_INFO_COST :{BLACK}Custo: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Peso: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Custo: {GOLD}{CURRENCY}{BLACK} Velocidade: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Capacidade: {GOLD}{COMMA} passageiros, {COMMA} sacos de correio
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Vagões Motorizados: {GOLD}+{POWER}{BLACK} Peso: {GOLD}+{WEIGHT_S}
+STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Reconvertível em: {GOLD}
+STR_PURCHASE_INFO_ALL_TYPES :Todos os tipos de carga
+STR_PURCHASE_INFO_ALL_BUT :Todas menos {GOLD}
+STR_PURCHASE_INFO_MAX_TE :{BLACK}Máx. Força de Tracção: {GOLD}{FORCE}
+
+########### String for New Landscape Generator
+
+STR_GENERATE :{WHITE}Criar
+STR_RANDOM :{BLACK}Gerar aleatório
+STR_RANDOM_HELP :{BLACK}Mudar a semente aleatória para a criação do terreno
+STR_WORLD_GENERATION_CAPTION :{WHITE}Geração do mundo
+STR_RANDOM_SEED :{BLACK}Semente aleatória:
+STR_RANDOM_SEED_HELP :{BLACK}Clique para inserir uma semente aleatória
+STR_LAND_GENERATOR :{BLACK}Criação do terreno:
+STR_TREE_PLACER :{BLACK}Colocação árvores:
+STR_HEIGHTMAP_ROTATION :{BLACK}Rotação mapa alt.:
+STR_TERRAIN_TYPE :{BLACK}Tipo de terreno:
+STR_QUANTITY_OF_SEA_LAKES :{BLACK}Nível do mar:
+STR_SMOOTHNESS :{BLACK}Suavidade:
+STR_SNOW_LINE_HEIGHT :{BLACK}Altura linha neve:
+STR_DATE :{BLACK}Data:
+STR_NUMBER_OF_TOWNS :{BLACK}Num. de cidades:
+STR_NUMBER_OF_INDUSTRIES :{BLACK}Num. de indústrias:
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_SNOW_LINE_UP :{BLACK}Mover a linha de neve um nível acima
+STR_SNOW_LINE_DOWN :{BLACK}Mover a linha de neve um nível abaixo
+STR_SNOW_LINE_QUERY_CAPT :{WHITE}Mudar a altura da linha de neve
+STR_START_DATE_QUERY_CAPT :{WHITE}Mudar ano de início
+STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Aviso de redimensionamento
+STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Redimensionar muito o mapa não é recomendado. Continuar com a criação?
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_HEIGHTMAP_NAME :{BLACK}Nome mapa de alt.:
+STR_HEIGHTMAP_SIZE :{BLACK}Tamanho: {ORANGE}{NUM} x {NUM}
+STR_GENERATION_WORLD :{WHITE}A gerar mundo...
+STR_GENERATION_ABORT :{BLACK}Cancelar
+STR_GENERATION_ABORT_CAPTION :{WHITE}Cancelar criação do mundo
+STR_GENERATION_ABORT_MESSAGE :{YELLOW}Quer mesmo cancelar a criação?
+STR_PROGRESS :{WHITE}{NUM}% completo
+STR_GENERATION_PROGRESS :{BLACK}{NUM} / {NUM}
+STR_WORLD_GENERATION :{BLACK}A gerar mundo
+STR_TREE_GENERATION :{BLACK}A gerar árvores
+STR_UNMOVABLE_GENERATION :{BLACK}Geração inamovível
+STR_CLEARING_TILES :{BLACK}A gerar zonas rochosas e montanhosas
+STR_SETTINGUP_GAME :{BLACK}Definindo jogo
+STR_PREPARING_TILELOOP :{BLACK}A preparar o terreno
+STR_PREPARING_GAME :{BLACK}A preparar jogo
+STR_DIFFICULTY_TO_CUSTOM :{WHITE}Esta acção mudou o nível de dificuldade para Personalizado
+STR_SE_FLAT_WORLD :{WHITE}Terra plana
+STR_SE_FLAT_WORLD_TIP :{BLACK}Criar terra plana
+STR_SE_RANDOM_LAND :{WHITE}Terra aleatória
+STR_SE_NEW_WORLD :{BLACK}Criar novo cenário
+STR_SE_CAPTION :{WHITE}Tipo de cenário
+STR_FLAT_WORLD_HEIGHT_DOWN :{BLACK}Mover altura da terra plana um nível abaixo
+STR_FLAT_WORLD_HEIGHT_UP :{BLACK}Mover altura da terra plana um nível acima
+STR_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Mudar altura da terra plana
+STR_FLAT_WORLD_HEIGHT :{BLACK}Altura da terra plana:
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+STR_SMALLMAP_CENTER :{BLACK}Centrar o mapa na posição actual
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}Pequeno
+STR_CITY_AIRPORT :{BLACK}Cidade
+STR_METRO_AIRPORT :{BLACK}Aeroporto metropolitano
+STR_INTERNATIONAL_AIRPORT :{BLACK}Aeroporto internacional
+STR_COMMUTER_AIRPORT :{BLACK}Transbordo
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Intercontinental
+STR_HELIPORT :{BLACK}Heliporto
+STR_HELIDEPOT :{BLACK}Heli-oficina
+STR_HELISTATION :{BLACK}Heli-estação
+
+STR_SMALL_AIRPORTS :{BLACK}Aeroportos pequenos
+STR_LARGE_AIRPORTS :{BLACK}Aeroportos grandes
+STR_HUB_AIRPORTS :{BLACK}Aeroporto de ligação/transbordo
+STR_HELIPORTS :{BLACK}Heliportos
+
+############ Tooltip measurment
+
+STR_MEASURE_LENGTH :{BLACK}Tamanho: {NUM}
+STR_MEASURE_AREA :{BLACK}Ãrea: {NUM} x {NUM}
+STR_MEASURE_LENGTH_HEIGHTDIFF :{BLACK}Comprimento: {NUM}{}Diferença de altura: {NUM} m
+STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}Ãrea: {NUM} x {NUM}{}Diferença de altura: {NUM} m
+
+########
diff --git a/src/lang/romanian.txt b/src/lang/romanian.txt
new file mode 100644
index 000000000..9d4326238
--- /dev/null
+++ b/src/lang/romanian.txt
@@ -0,0 +1,3116 @@
+##name Romanian
+##ownname Românã
+##isocode ro_RO.UTF-8
+##plural 0
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Depãseste limita hãrtii
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Prea aproape de marginea hãrtii
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Nu ai destui bani - îti trebuie {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Necesitã teren plat
+STR_0008_WAITING :{BLACK}ÃŽn asteptare: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (plecat de la
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Acceptã: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Acceptã: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :cãlãtori
+STR_0010_COAL :cãrbuni
+STR_0011_MAIL :colete postale
+STR_0012_OIL :petrol
+STR_0013_LIVESTOCK :animale
+STR_0014_GOODS :bunuri
+STR_0015_GRAIN :cereale
+STR_0016_WOOD :lemne
+STR_0017_IRON_ORE :minereu de fier
+STR_0018_STEEL :otel
+STR_0019_VALUABLES :valori
+STR_001A_COPPER_ORE :minereu de cupru
+STR_001B_MAIZE :porumb
+STR_001C_FRUIT :fructe
+STR_001D_DIAMONDS :diamante
+STR_001E_FOOD :alimente
+STR_001F_PAPER :hârtie
+STR_0020_GOLD :aur
+STR_0021_WATER :apã
+STR_0022_WHEAT :grâu
+STR_0023_RUBBER :cauciuc
+STR_0024_SUGAR :zahãr
+STR_0025_TOYS :jucãrii
+STR_0026_CANDY :bomboane
+STR_0027_COLA :cola
+STR_0028_COTTON_CANDY :vatã de zahãr
+STR_0029_BUBBLES :balonase
+STR_002A_TOFFEE :caramel
+STR_002B_BATTERIES :baterii
+STR_002C_PLASTIC :plastic
+STR_002D_FIZZY_DRINKS :sucuri
+STR_002E :
+STR_002F_PASSENGER :cãlãtori
+STR_0030_COAL :cãrbuni
+STR_0031_MAIL :colete postale
+STR_0032_OIL :petrol
+STR_0033_LIVESTOCK :animale
+STR_0034_GOODS :bunuri
+STR_0035_GRAIN :cereale
+STR_0036_WOOD :lemne
+STR_0037_IRON_ORE :minereu de fier
+STR_0038_STEEL :otel
+STR_0039_VALUABLES :valori
+STR_003A_COPPER_ORE :minereu de cupru
+STR_003B_MAIZE :porumb
+STR_003C_FRUIT :fructe
+STR_003D_DIAMOND :diamante
+STR_003E_FOOD :alimente
+STR_003F_PAPER :hârtie
+STR_0040_GOLD :aur
+STR_0041_WATER :apã
+STR_0042_WHEAT :grâu
+STR_0043_RUBBER :cauciuc
+STR_0044_SUGAR :zahãr
+STR_0045_TOY :jucãrii
+STR_0046_CANDY :bomboane
+STR_0047_COLA :cola
+STR_0048_COTTON_CANDY :vatã de zahãr
+STR_0049_BUBBLE :balonase
+STR_004A_TOFFEE :caramel
+STR_004B_BATTERY :baterii
+STR_004C_PLASTIC :plastic
+STR_004D_FIZZY_DRINK :suc
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} cãlãtor{P "" i}
+STR_QUANTITY_COAL :{WEIGHT} de cãrbune
+STR_QUANTITY_MAIL :{COMMA} sac{P "" i} cu colete postale
+STR_QUANTITY_OIL :{VOLUME} de petrol
+STR_QUANTITY_LIVESTOCK :{COMMA} animal{P "" e}
+STR_QUANTITY_GOODS :{COMMA} pachet{P "" e} de bunuri
+STR_QUANTITY_GRAIN :{WEIGHT} de cereale
+STR_QUANTITY_WOOD :{WEIGHT} de lemne
+STR_QUANTITY_IRON_ORE :{WEIGHT} de minereu de fier
+STR_QUANTITY_STEEL :{WEIGHT} de otel
+STR_QUANTITY_VALUABLES :{COMMA} cuti{P e i} de valori
+STR_QUANTITY_COPPER_ORE :{WEIGHT} de minereu de cupru
+STR_QUANTITY_MAIZE :{WEIGHT} de porumb
+STR_QUANTITY_FRUIT :{WEIGHT} de fructe
+STR_QUANTITY_DIAMONDS :{COMMA} sac{P "" i} cu diamante
+STR_QUANTITY_FOOD :{WEIGHT} de alimente
+STR_QUANTITY_PAPER :{WEIGHT} de hârtie
+STR_QUANTITY_GOLD :{COMMA} sac{P "" i} cu aur
+STR_QUANTITY_WATER :{VOLUME} de apã
+STR_QUANTITY_WHEAT :{WEIGHT} de grâu
+STR_QUANTITY_RUBBER :{VOLUME} de cauciuc
+STR_QUANTITY_SUGAR :{WEIGHT} de zahãr
+STR_QUANTITY_TOYS :{COMMA} sac{P "" i} cu jucãrii
+STR_QUANTITY_SWEETS :{COMMA} sac{P "" i} cu bomboane
+STR_QUANTITY_COLA :{VOLUME} de cola
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} de vatã de zahãr
+STR_QUANTITY_BUBBLES :{COMMA} balonas{P "" e}
+STR_QUANTITY_TOFFEE :{WEIGHT} de caramel
+STR_QUANTITY_BATTERIES :{COMMA} bateri{P e i}
+STR_QUANTITY_PLASTIC :{VOLUME} de plastic
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} bido{P n ane} cu suc
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}CL
+STR_ABBREV_COAL :{TINYFONT}CB
+STR_ABBREV_MAIL :{TINYFONT}PO
+STR_ABBREV_OIL :{TINYFONT}PT
+STR_ABBREV_LIVESTOCK :{TINYFONT}AN
+STR_ABBREV_GOODS :{TINYFONT}BN
+STR_ABBREV_GRAIN :{TINYFONT}CR
+STR_ABBREV_WOOD :{TINYFONT}LM
+STR_ABBREV_IRON_ORE :{TINYFONT}FE
+STR_ABBREV_STEEL :{TINYFONT}OT
+STR_ABBREV_VALUABLES :{TINYFONT}VL
+STR_ABBREV_COPPER_ORE :{TINYFONT}CU
+STR_ABBREV_MAIZE :{TINYFONT}PR
+STR_ABBREV_FRUIT :{TINYFONT}FR
+STR_ABBREV_DIAMONDS :{TINYFONT}DM
+STR_ABBREV_FOOD :{TINYFONT}AL
+STR_ABBREV_PAPER :{TINYFONT}HR
+STR_ABBREV_GOLD :{TINYFONT}AU
+STR_ABBREV_WATER :{TINYFONT}AP
+STR_ABBREV_WHEAT :{TINYFONT}GR
+STR_ABBREV_RUBBER :{TINYFONT}CU
+STR_ABBREV_SUGAR :{TINYFONT}ZH
+STR_ABBREV_TOYS :{TINYFONT}JC
+STR_ABBREV_SWEETS :{TINYFONT}BB
+STR_ABBREV_COLA :{TINYFONT}CO
+STR_ABBREV_CANDYFLOSS :{TINYFONT}VZ
+STR_ABBREV_BUBBLES :{TINYFONT}BL
+STR_ABBREV_TOFFEE :{TINYFONT}CM
+STR_ABBREV_BATTERIES :{TINYFONT}BA
+STR_ABBREV_PLASTIC :{TINYFONT}PL
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}SC
+STR_ABBREV_NONE :{TINYFONT}NU
+STR_ABBREV_ALL :{TINYFONT}TOATE
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Harta - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Optiuni
+STR_00B2_MESSAGE :{YELLOW}Mesaj
+STR_00B3_MESSAGE_FROM :{YELLOW}Mesaj de la {STRING}
+STR_POPUP_CAUTION_CAPTION :{WHITE}Atentie!
+STR_00B4_CAN_T_DO_THIS :{WHITE}Nu pot face asta....
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Nu pot curãta terenul....
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Copyright original {COPYRIGHT} 1995 Chris Sawyer, toate drepturile rezervate
+STR_00B7_VERSION :{BLACK}OpenTTD versiunea {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 Echipa OpenTTD
+STR_TRANSLATED_BY :{BLACK} Translator(i) -
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Iesire din joc
+STR_00C8_YES :{BLACK}Da
+STR_00C9_NO :{BLACK}Nu
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Esti sigur cã vrei sã abandonezi jocul curent si sã revii în {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :nimic
+STR_00D1_DARK_BLUE :Albastru închis
+STR_00D2_PALE_GREEN :Verde pal
+STR_00D3_PINK :Roz
+STR_00D4_YELLOW :Galben
+STR_00D5_RED :Rosu
+STR_00D6_LIGHT_BLUE :Albastru deschis
+STR_00D7_GREEN :Verde
+STR_00D8_DARK_GREEN :Verde închis
+STR_00D9_BLUE :Albastru
+STR_00DA_CREAM :Crem
+STR_00DB_MAUVE :Mov
+STR_00DC_PURPLE :Purpuriu
+STR_00DD_ORANGE :Portocaliu
+STR_00DE_BROWN :Maro
+STR_00DF_GREY :Gri
+STR_00E0_WHITE :Alb
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Prea multe vehicule în joc
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Locatie
+STR_00E5_CONTOURS :Relief
+STR_00E6_VEHICLES :Vehicule
+STR_00E7_INDUSTRIES :Industrii
+STR_00E8_ROUTES :Rute
+STR_00E9_VEGETATION :Vegetatie
+STR_00EA_OWNERS :Proprietari
+STR_00EB_ROADS :{BLACK}{TINYFONT}Strãzi
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Cãi ferate
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Statii/Aeroporturi/Porturi
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Clãdiri/Industrii
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Vehicule
+STR_00F0_100M :{BLACK}{TINYFONT}100m
+STR_00F1_200M :{BLACK}{TINYFONT}200m
+STR_00F2_300M :{BLACK}{TINYFONT}300m
+STR_00F3_400M :{BLACK}{TINYFONT}400m
+STR_00F4_500M :{BLACK}{TINYFONT}500m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Trenuri
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Autovehicule
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Nave
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Aeronave
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Rute de transport
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Minã de cãrbune
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Termocentralã
+STR_00FC_FOREST :{BLACK}{TINYFONT}Pãdure
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}Exploatatie forestierã
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Rafinãrie
+STR_00FF_FARM :{BLACK}{TINYFONT}Fermã
+STR_0100_FACTORY :{BLACK}{TINYFONT}Fabricã de conserve
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Tipografie
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Sonde
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Minã de fier
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Otelãrie
+STR_0105_BANK :{BLACK}{TINYFONT}Bancã
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Fabricã de hârtie
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Minã de aur
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Combinat alimentar
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Minã de diamante
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Minã de cupru
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Livadã
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Plantatie de cauciuc
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Rezervor de apã
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Turn de apã
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}Fabricã de cherestea
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Pãdure de vatã de zahãr
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Fabricã de bomboane
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Fermã de baterii
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Fântâni de cola
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Magazin de jucãrii
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Fabricã de jucãrii
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Fântâni de plastic
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Fabricã de sucuri
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Generator de balonase
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Carierã de caramel
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Minã de zahãr
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Garã
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Loc încãrcare camioane
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Statie de autobuz
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Aeroport/Heliport
+STR_011F_DOCK :{BLACK}{TINYFONT}Port
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Teren pietros
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Pajiste
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Teren viran
+STR_0123_FIELDS :{BLACK}{TINYFONT}Teren agricol
+STR_0124_TREES :{BLACK}{TINYFONT}Copaci
+STR_0125_ROCKS :{BLACK}{TINYFONT}Pietre
+STR_0126_WATER :{BLACK}{TINYFONT}Apã
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Fãrã proprietar
+STR_0128_TOWNS :{BLACK}{TINYFONT}Orase
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Industrii
+STR_012A_DESERT :{BLACK}{TINYFONT}Desert
+STR_012B_SNOW :{BLACK}{TINYFONT}Zãpadã
+STR_012C_MESSAGE :{WHITE}Mesaj
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Anuleazã
+STR_012F_OK :{BLACK}OK
+STR_0130_RENAME :{BLACK}Redenumeste
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Prea multe nume definite
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Numele ales este deja folosit
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...apartine companiei {STRING}
+STR_013C_CARGO :{BLACK}Încãrcãturã
+STR_013D_INFORMATION :{BLACK}Informatii
+STR_013E_CAPACITIES :{BLACK}Capacitãti
+STR_013E_TOTAL_CARGO :{BLACK}Încãrcãturi
+STR_013F_CAPACITY :{BLACK}Capacitate: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}Capacitate: {LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Încãrcãtura totalã (capacitatea) acestui tren:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}Joc nou
+STR_0141_LOAD_GAME :{BLACK}Încarcã joc
+STR_SINGLE_PLAYER :{BLACK}Un singur jucãtor
+STR_MULTIPLAYER :{BLACK}Multiplayer
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Marime harta:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Optiuni
+
+STR_0150_SOMEONE :cineva{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Harta lumii
+STR_0152_TOWN_DIRECTORY :Lista cu orase
+STR_0153_SUBSIDIES :Subventii
+
+STR_UNITS_IMPERIAL :Imperial
+STR_UNITS_METRIC :Metric
+STR_UNITS_SI :SI
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} mph
+STR_UNITS_VELOCITY_METRIC :{COMMA} km/h
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}hp
+STR_UNITS_POWER_METRIC :{COMMA}hp
+STR_UNITS_POWER_SI :{COMMA}kW
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} tone imperiale{P "" s}
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} tone{P "" s}
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} kg
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}gal
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}l
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}m³
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} galoane{P "" s}
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} litri{P "" s}
+STR_UNITS_VOLUME_LONG_SI :{COMMA} m³
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10³ lbf
+STR_UNITS_FORCE_METRIC :{COMMA} tone fortã
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Profitul operational
+STR_0155_INCOME_GRAPH :Cifra de afaceri
+STR_0156_DELIVERED_CARGO_GRAPH :Numãr încãrcãturi livrate
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Evolutia performantei
+STR_0158_COMPANY_VALUE_GRAPH :Valoarea companiei
+STR_0159_CARGO_PAYMENT_RATES :Valorile plãtilor pe încãrcãturi
+STR_015A_COMPANY_LEAGUE_TABLE :Clasamentul companiilor
+STR_PERFORMANCE_DETAIL_MENU :Rating de performantã detaliat
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}Despre OpenTTD
+STR_015C_SAVE_GAME :Salveazã jocul (F3)
+STR_015D_LOAD_GAME :Încarcã joc
+STR_015E_QUIT_GAME :Iesire în meniul principal
+STR_015F_QUIT :Iesire din joc
+STR_ABANDON_GAME_QUERY :{YELLOW}Esti sigur cã vrei sã renunti la acest joc?
+STR_0161_QUIT_GAME :{WHITE}Iesire din joc
+STR_SORT_ORDER_TIP :{BLACK}Alegeti ordinea de sortare ascendenta/descendenta
+STR_SORT_CRITERIA_TIP :{BLACK}Alegeti criteriul de sortare
+STR_SORT_BY :{BLACK}Ordoneaza dupa
+
+STR_SORT_BY_POPULATION :{BLACK}Populatia
+STR_SORT_BY_PRODUCTION :{BLACK}Productie
+STR_SORT_BY_TYPE :{BLACK}Tip
+STR_SORT_BY_TRANSPORTED :{BLACK}Transportat
+STR_SORT_BY_NAME :{BLACK}Nume
+STR_SORT_BY_DROPDOWN_NAME :Nume
+STR_SORT_BY_DATE :{BLACK}Datã
+STR_SORT_BY_NUMBER :Numar
+STR_SORT_BY_PROFIT_LAST_YEAR :Profit anul trecut
+STR_SORT_BY_PROFIT_THIS_YEAR :Profit anul acesta
+STR_SORT_BY_AGE :Vechime
+STR_SORT_BY_RELIABILITY :Eficienta
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Capacitatea totala in functie de incarcatura
+STR_SORT_BY_MAX_SPEED :Viteza maxima
+STR_SORT_BY_MODEL :Model
+STR_SORT_BY_VALUE :Valoare
+STR_SORT_BY_FACILITY :Tipul de statie
+STR_SORT_BY_WAITING :In asteptarea valorii încãrcãturii
+STR_SORT_BY_RATING_MAX :Evaluare încãrcãturã
+STR_ENGINE_SORT_ENGINE_ID :IDMotor (model clasic)
+STR_ENGINE_SORT_COST :Cost
+STR_ENGINE_SORT_POWER :Putere
+STR_ENGINE_SORT_INTRO_DATE :Data lansarii
+STR_ENGINE_SORT_RUNNING_COST :Cost exploatare
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Cost exploatare/putere
+STR_ENGINE_SORT_CARGO_CAPACITY :Cargo Capacity
+STR_NO_WAITING_CARGO :{BLACK}Nu este în asteptare nici un fel de încãrcãturã
+STR_SELECT_ALL_FACILITIES :{BLACK}Alege toate facilitãtile
+STR_SELECT_ALL_TYPES :{BLACK}Alege toate tipurile de încãrcãturi (inclusiv încãrcãturile care nu sunt în asteptare)
+STR_AVAILABLE_ENGINES_TIP :{BLACK}Vezi o lista de proiecte disponibile de motoare pentru acest tip de vehicul.
+STR_MANAGE_LIST :{BLACK}Gestioneaza lista
+STR_MANAGE_LIST_TIP :{BLACK}Trimite instructiunile tuturor vehiculelor din aceasta lista
+STR_REPLACE_VEHICLES :Inlocuieste vehiculele
+STR_SEND_TRAIN_TO_DEPOT :Trimite la depou
+STR_SEND_ROAD_VEHICLE_TO_DEPOT :Trimite la depou
+STR_SEND_SHIP_TO_DEPOT :Trimite la depou
+STR_SEND_AIRCRAFT_TO_HANGAR :Trimite la hangar
+STR_SEND_FOR_SERVICING :Trimite in service
+
+############ range for months starts
+STR_0162_JAN :Ian
+STR_0163_FEB :Feb
+STR_0164_MAR :Mar
+STR_0165_APR :Apr
+STR_0166_MAY :Mai
+STR_0167_JUN :Iun
+STR_0168_JUL :Iul
+STR_0169_AUG :Aug
+STR_016A_SEP :Sep
+STR_016B_OCT :Oct
+STR_016C_NOV :Nov
+STR_016D_DEC :Dec
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Pauzã joc (F1)
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Salvare/abandon/iesire joc
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Afiseazã lista cu statiile companiei
+STR_0174_DISPLAY_MAP :{BLACK}Afiseazã harta (F4)
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Afiseazã harta, lista cu orase
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Afiseazã lista cu orasele de pe hartã (F5)
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Afiseazã informatiile financiare ale companiei
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Afiseazã datele generale despre companie
+STR_0179_DISPLAY_GRAPHS :{BLACK}Afiseazã graficele
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Afiseazã clasamentul companiilor
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Afiseazã lista cu trenurile companiei
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Afiseazã lista cu autovehiculele companiei
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Afiseazã lista cu navele companiei
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Afiseazã lista cu aeronavele companiei
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Mãreste imaginea
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Micsoreazã imaginea
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Construieste cãi ferate
+STR_0182_BUILD_ROADS :{BLACK}Construieste strãzi
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Construieste porturi
+STR_0184_BUILD_AIRPORTS :{BLACK}Construieste aeroporturi
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Planteazã arbori, plaseazã semne, etc.
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Informatii despre teren
+STR_0187_OPTIONS :{BLACK}Optiuni
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Nu pot schimba intervalul de service...
+STR_018B_CLOSE_WINDOW :{BLACK}ÃŽnchide fereastra
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Titlul ferestrei - trage de aici pentru a muta fereastra
+STR_STICKY_BUTTON :{BLACK}Mark this window as undeletable for the 'Close All Windows' key
+STR_RESIZE_BUTTON :{BLACK}Click&trage pt redimensionarea ferestrei
+STR_SAVELOAD_HOME_BUTTON :{BLACK}Click aici pentru a ajunge la directorul predefinit pentru salvari
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Demoleazã clãdiri, strãzi, etc. pe un pãtrat de teren
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Scade altitudinea unui vârf de teren
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Mãreste altitudinea unui vârf de teren
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Bara de defilare - defileazã în listã sus/jos
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Bara de defilare - stanga/dreapta
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Aratã relieful pe hartã
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Aratã vehiculele pe hartã
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Aratã industriile pe hartã
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Aratã rutele de transport pe hartã
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Aratã vegetatia pe hartã
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Aratã proprietãtile pe hartã
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Activeazã afisarea numelor oraselor pe hartã
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Profit anul acesta: {CURRENCY} (anul trecut: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} an{P "" i} ({COMMA})
+STR_AGE_RED :{RED}{COMMA} an{P "" i} ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Autovehicolul
+STR_019D_AIRCRAFT :Aeronava
+STR_019E_SHIP :Nava
+STR_019F_TRAIN :Trenul
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} este vechi
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} este foarte vechi
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} este foarte vechi si trebuie înlocuit urgent
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Informatii teren
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Costul demolãrii: {LTBLUE}N/A
+STR_01A5_COST_TO_CLEAR :{BLACK}Costul demolãrii: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :N/A
+STR_01A7_OWNER :{BLACK}Proprietar: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Autoritatea localã: {LTBLUE}{STRING}
+STR_01A9_NONE :nici una
+STR_01AA_NAME :{BLACK}Nume
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1
+STR_01AD_2ND :2
+STR_01AE_3RD :3
+STR_01AF_4TH :4
+STR_01B0_5TH :5
+STR_01B1_6TH :6
+STR_01B2_7TH :7
+STR_01B3_8TH :8
+STR_01B4_9TH :9
+STR_01B5_10TH :10
+STR_01B6_11TH :11
+STR_01B7_12TH :12
+STR_01B8_13TH :13
+STR_01B9_14TH :14
+STR_01BA_15TH :15
+STR_01BB_16TH :16
+STR_01BC_17TH :17
+STR_01BD_18TH :18
+STR_01BE_19TH :19
+STR_01BF_20TH :20
+STR_01C0_21ST :21
+STR_01C1_22ND :22
+STR_01C2_23RD :23
+STR_01C3_24TH :24
+STR_01C4_25TH :25
+STR_01C5_26TH :26
+STR_01C6_27TH :27
+STR_01C7_28TH :28
+STR_01C8_29TH :29
+STR_01C9_30TH :30
+STR_01CA_31ST :31
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Încãrcãturi acceptate: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Tonomatul cu jazz
+STR_01D3_SOUND_MUSIC :Sunet/muzicã
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Afiseazã fereastra pentru configurarea sunetului/muzicii
+STR_01D5_ALL :{TINYFONT}Toate
+STR_01D6_OLD_STYLE :{TINYFONT}Oldies
+STR_01D7_NEW_STYLE :{TINYFONT}Moderne
+STR_01D8_EZY_STREET :{TINYFONT}Ezy Street
+STR_01D9_CUSTOM_1 :{TINYFONT}Personale 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Personale 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Volumul muzicii
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Volumul efectelor sonore
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MIN ' ' ' ' ' ' MAX
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Sãri la piesa precedentã din selectie
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Sãri la piesa urmãtoare din selectie
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Opreste muzica
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Porneste muzica
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Foloseste acest indicator pentru a regla volumul muzicii si al efectelor sonore
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Piesa nr: {SETX 88}Titlul
+STR_01E9_SHUFFLE :{TINYFONT}Amestecã
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Program
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Programare piese muzicale
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Lista melodiilor
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Program - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}Sterge
+STR_01F1_SAVE :{TINYFONT}{BLACK}Salveazã
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Programul current al pieselor muzicale
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Selecteazã programul 'toate melodiile'
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Selecteazã programul 'oldies'
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Selecteazã programul 'modern'
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Selecteazã programul personal 1
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Selecteazã programul personal 2
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Sterge programul curent (doar pentru cele personale)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Salveaza setarile pentru muzica
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Click pe o melodie pentru a adãuga-o in programul personal curent
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Apasa pe pista audio pentru a o elimina din programul actual (doar Custom1 sau Custom2)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Comutator pentru amestecarea melodiilor (da/nu)
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Afiseaza fereastra pentru selectia melodiilor
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Click pe informatie pentru a centra imaginea pe industrie/oras
+STR_01FE_DIFFICULTY :{BLACK}Nivel dificultate ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Ultimul mesaj/ultima stire
+STR_0201_MESSAGE_SETTINGS :Setãri mesaje
+STR_MESSAGE_HISTORY_MENU :Lista ultimelor mesaje
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Afiseaza ultimul mesaj (ultima stire) si optiunile pentru mesaje
+STR_0204_MESSAGE_OPTIONS :{WHITE}Optiuni mesaje
+STR_0205_MESSAGE_TYPES :{BLACK}Tipuri mesaje:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Sosirea primului vehicul la una din statiile tale
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Sosirea primului vehicul la una din statiile competitorilor
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Accidente/dezastre
+STR_0209_COMPANY_INFORMATION :{YELLOW}Informatii despre companie
+STR_020A_ECONOMY_CHANGES :{YELLOW}Schimbãri economice
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Sfaturi/informatii despre vehiculele tale
+STR_020C_NEW_VEHICLES :{YELLOW}Vehicule noi
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Schimbãri ale acceptãrii mãrfurilor
+STR_020E_SUBSIDIES :{YELLOW}Subventii
+STR_020F_GENERAL_INFORMATION :{YELLOW}Informatii generale
+STR_MESSAGES_ALL :{YELLOW}Setare pentru tipurile de mesaje (da/nu/rezumat)
+STR_MESSAGE_SOUND :{YELLOW}Sunet pentru mesajele-stiri
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...prea departe de destinatia precedentã
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Primele companii care au atins {NUM}{}(Nivelul {STRING})
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Clasamentul companiilor in {NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Om de afaceri
+STR_0214_ENTREPRENEUR :Întreprinzãtor
+STR_0215_INDUSTRIALIST :Industrias
+STR_0216_CAPITALIST :Capitalist
+STR_0217_MAGNATE :Magnat
+STR_0218_MOGUL :Mogul
+STR_0219_TYCOON_OF_THE_CENTURY :Magnatul Secolului
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} a dobandit titlul de '{STRING}'!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} al {COMPANY} dobandeste titlul de '{STRING}'!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Creeazã scenariu
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Editor scenarii
+STR_0223_LAND_GENERATION :{WHITE}Generator suprafatã uscat
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Uscat aleatoriu
+STR_0227_RESET_LAND :{BLACK}Reseteazã terenul
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Mãreste aria de editare a terenului
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Micsoreazã aria de editare a terenului
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Genereazã teren aleator
+STR_022B_RESET_LANDSCAPE :{BLACK}Reseteazã peisajul
+STR_022C_RESET_LANDSCAPE :{WHITE}Resetare peisaj
+STR_LOAD_GAME_HEIGHTMAP :{WHITE}Foloseste harta de inaltimi
+STR_LOAD_SCEN_HEIGHTMAP :{BLACK}Foloseste harta inaltimi
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Esti sigur cã vrei sa resetezi peisajul?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Generare peisaj
+STR_022F_TOWN_GENERATION :{BLACK}Generare oras
+STR_0230_INDUSTRY_GENERATION :{BLACK}Generare industrii
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Constructii rutiere
+STR_0233_TOWN_GENERATION :{WHITE}Generare oras
+STR_0234_NEW_TOWN :{BLACK}Oras nou
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Construieste un oras nou
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Nu pot construi un oras aici...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...prea aproape de marginea hãrtii
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...prea aproape de alt oras
+STR_0239_SITE_UNSUITABLE :{WHITE}...locatie nepotrivitã
+STR_023A_TOO_MANY_TOWNS :{WHITE}...prea multe orase
+STR_CANNOT_GENERATE_TOWN :{WHITE}Nu pot construi nici un oras
+STR_NO_SPACE_FOR_TOWN :{WHITE}...nu mai este loc pe hartã
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Mãreste dimensiunile orasului
+STR_023C_EXPAND :{BLACK}Extinde
+STR_023D_RANDOM_TOWN :{BLACK}Oras aleator
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Construieste un oras într-o locatie aleatoare
+STR_023F_INDUSTRY_GENERATION :{WHITE}Generare industrii
+STR_0240_COAL_MINE :{BLACK}Minã de cãrbune
+STR_0241_POWER_STATION :{BLACK}Termocentralã
+STR_0242_SAWMILL :{BLACK}Exploatatie forestierã
+STR_0243_FOREST :{BLACK}Pãdure
+STR_0244_OIL_REFINERY :{BLACK}Rafinãrie
+STR_0245_OIL_RIG :{BLACK}Platformã petrolierã
+STR_0246_FACTORY :{BLACK}Fabricã de conserve
+STR_0247_STEEL_MILL :{BLACK}Otelãrie
+STR_0248_FARM :{BLACK}Fermã
+STR_0249_IRON_ORE_MINE :{BLACK}Minã de fier
+STR_024A_OIL_WELLS :{BLACK}Sonde
+STR_024B_BANK :{BLACK}Bancã
+STR_024C_PAPER_MILL :{BLACK}Fabricã de hârtie
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Combinat alimentar
+STR_024E_PRINTING_WORKS :{BLACK}Tipografie
+STR_024F_GOLD_MINE :{BLACK}Minã de aur
+STR_0250_LUMBER_MILL :{BLACK}Fabricã de cherestea
+STR_0251_FRUIT_PLANTATION :{BLACK}Livadã
+STR_0252_RUBBER_PLANTATION :{BLACK}Plantatie de cauciuc
+STR_0253_WATER_SUPPLY :{BLACK}Rezervor de apã
+STR_0254_WATER_TOWER :{BLACK}Turn de apã
+STR_0255_DIAMOND_MINE :{BLACK}Minã de diamante
+STR_0256_COPPER_ORE_MINE :{BLACK}Minã de cupru
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Pãdure de vatã de zahãr
+STR_0258_CANDY_FACTORY :{BLACK}Fabricã de bomboane
+STR_0259_BATTERY_FARM :{BLACK}Fermã de baterii
+STR_025A_COLA_WELLS :{BLACK}Fântâni de cola
+STR_025B_TOY_SHOP :{BLACK}Magazin de jucãrii
+STR_025C_TOY_FACTORY :{BLACK}Fabricã de jucãrii
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Fântâni de plastic
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Fabricã de sucuri
+STR_025F_BUBBLE_GENERATOR :{BLACK}Generator de balonase
+STR_0260_TOFFEE_QUARRY :{BLACK}Carierã de caramel
+STR_0261_SUGAR_MINE :{BLACK}Minã de zahãr
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Construieste minã de cupru
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Construieste termocentralã
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Înfiinteazã exploatatie forestierã
+STR_0265_PLANT_FOREST :{BLACK}Planteazã pãdure
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Construieste rafinãrie
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Construieste platformã petrolierã (doar în apropierea marginilor hãrtii)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Construieste fabricã de conserve
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Construieste otelãrie
+STR_026A_CONSTRUCT_FARM :{BLACK}Înfiinteazã fermã
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Construieste minã de fier
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Construieste sonde
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Construieste bancã (doar în orasele cu o populatie de cel putin 1200 locuitori)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Construieste fabricã de hârtie
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Construieste combinat alimentar
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Construieste tipografie
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Construieste minã de aur
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Construieste bancã (doar în orase)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Construieste fabricã de cherestea (taie arborii din jur pentru a produce lemne)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Planteazã livadã
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Înfiinteazã plantatie de cauciuc
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Construieste rezervor de apã
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Construieste turn de apã (doar în orase)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Construieste minã de diamante
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Construieste minã de cupru
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Planteazã pãdure de vatã de zahãr
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Construieste fabricã de bomboane
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Înfiinteazã fermã de baterii
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Construieste fântâni de cola
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Construieste magazin de jucãrii
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Construieste fabricã de jucãrii
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Construieste fântþni de plastic
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Construieste fabricã de sucuri
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Construieste generator de balonase
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Construieste carierã de caramel
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Construieste minã de zahãr
+STR_0285_CAN_T_BUILD_HERE :{WHITE}Nu pot construi {STRING} aici...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...mai intâi trebuie creat un oras
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...un singur obiectiv de acest tip este permis intr-un oras
+STR_0288_PLANT_TREES :{BLACK}Planteazã arbori
+STR_0289_PLACE_SIGN :{BLACK}Plaseazã semn
+STR_028A_RANDOM_TREES :{BLACK}Arbori aleatori
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Planteazã aleator arbori pe uscat
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Plaseaza formatiuni pietroase
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Plaseazã far
+STR_028E_PLACE_TRANSMITTER :{BLACK}Plaseazã transmitãtor
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Defineste suprafata de desert.{}Apasã si mentine apasat CTRL pentru a o sterge
+STR_CREATE_LAKE :{BLACK}Defineste suprafata cu apã.{}Împrejurimile aflate la acelasi nivel vor fi inundate
+STR_0290_DELETE :{BLACK}Sterge
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Sterge acest oras
+STR_0292_SAVE_SCENARIO :Salveazã scenariul
+STR_0293_LOAD_SCENARIO :Încarcã scenariu
+STR_0294_QUIT_EDITOR :Iesire din editor
+STR_0295 :
+STR_0296_QUIT :Iesire din joc
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Salveazã/încarcã scenariu, abandoneazã editorul, iesire din joc
+STR_0298_LOAD_SCENARIO :{WHITE}Încarcã scenariu
+STR_0299_SAVE_SCENARIO :{WHITE}Salveazã scenariu
+STR_029A_PLAY_SCENARIO :{BLACK}Joacã scenariu
+STR_PLAY_HEIGHTMAP :{BLACK}Reda harta inaltimi
+STR_PLAY_HEIGHTMAP_HINT :{BLACK}Porneste un nou joc, folosind o scara de inaltimi ca peisaj
+STR_QUIT_SCENARIO_QUERY :{YELLOW}Esti sigur cã vrei sã renunti la acest scenariu?
+STR_029C_QUIT_EDITOR :{WHITE}Iesire din editor
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...Se poate construi doar in orase cu populatia de cel putin 1200
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Schimbã data de start cu un an în urmã
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Schimbã data de start înainte cu un an
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...ambele capete ale podului trebuie sã se situeze pe uscat
+STR_02A1_SMALL :{BLACK}Mic
+STR_02A2_MEDIUM :{BLACK}Mediu
+STR_02A3_LARGE :{BLACK}Mare
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Alege mãrimea orasului
+STR_02A5_TOWN_SIZE :{YELLOW}Mãrime oras:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Re-afiseazã ultimul mesaj
+STR_OFF :Oprit
+STR_SUMMARY :Pe scurt
+STR_FULL :Pe larg
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Lista oraselor (F5)
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Numele vehiculelor si modelelor
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Prestabilit
+STR_02BF_CUSTOM :Propriu
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Salveaza numele proprii
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Selecteazã numele modelelor
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Salveazã pe disc numele personalizate de mãrci si modele
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Optiunile jocului (F2)
+STR_02C5_DIFFICULTY_SETTINGS :Setãri dificultate
+STR_02C7_CONFIG_PATCHES :Configurare patch
+STR_NEWGRF_SETTINGS :Setari Newgrf
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Afiseazã numele oraselor
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Afiseazã numele statiilor
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Afiseazã semnele de pe hartã
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Afisare puncte de tranzit
+STR_02D0_FULL_ANIMATION :{SETX 12}Animatie completã
+STR_02D2_FULL_DETAIL :{SETX 12}Detalii grafice complete
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Peisaj transparent (X)
+STR_TRANSPARENT_SIGNS :{SETX 12}Numele statiilor transparente
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Informatii despre teren
+STR_02D6 :
+STR_CONSOLE_SETTING :Consola On/Off
+STR_02D7_SCREENSHOT_CTRL_S :Screenshot (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Screenshot gigant(Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :Despre 'OpenTTD'
+############ range ends here
+
+STR_02DB_OFF :{BLACK}inactiv
+STR_02DA_ON :{BLACK}activ
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Afiseazã subventiile (F6)
+STR_02DD_SUBSIDIES :Subventii (F6)
+STR_02DE_MAP_OF_WORLD :Harta lumii (F4)
+STR_EXTRA_VIEW_PORT :Extra ecran
+STR_SIGN_LIST :Lista de semne
+STR_02DF_TOWN_DIRECTORY :Lista oraselor
+STR_TOWN_POPULATION :{BLACK}Populatia totala: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Ecran{COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Copiaza pe ecranul principal
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Copiaza locatia ecranului principal in acest ecran
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Importa din ecran
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Importa locatia acestui ecran in ecranul principal
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Unitãti monetare
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Alege unitatea monetarã
+STR_MEASURING_UNITS :{BLACK}Unitãti de mãsurã
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Selectie unitãti de mãsurã
+STR_02E6_ROAD_VEHICLES :{BLACK}Autovehiculele circulã..
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Alege partea strãzii pe care se circulã
+STR_02E9_DRIVE_ON_LEFT :Pe partea stângã
+STR_02EA_DRIVE_ON_RIGHT :Pe partea dreaptã
+STR_02EB_TOWN_NAMES :{BLACK}Numele oraselor
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Alege nationalitatea numelor oraselor
+
+STR_02F4_AUTOSAVE :{BLACK}Salvare automatã
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Alege intervalul scurs între salvãrile automate
+STR_02F7_OFF :Dezactivatã
+STR_02F8_EVERY_3_MONTHS :La fiecare 3 luni
+STR_02F9_EVERY_6_MONTHS :La fiecare 6 luni
+STR_02FA_EVERY_12_MONTHS :La fiecare 12 luni
+STR_02FB_START_A_NEW_GAME :{BLACK}ÃŽncepere joc nou
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Incarca un joc salvat
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Creeazã un joc/scenariu propriu
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Alege un joc cu un singur jucãtor
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Alege un joc multiplayer cu 2-8 jucatori
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Afiseazã optiunile jocului
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Afiseaza optiunile pentru alegerea dificultãtii
+STR_0303_START_A_NEW_GAME_USING :{BLACK}ÃŽnceperea unui joc nou folosind un scenariu deja existent
+STR_0304_QUIT :{BLACK}Iesire
+STR_0305_QUIT_OPENTTD :{BLACK}Iesi din 'OpenTTD'
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...se poate construi doar în orase
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Alege peisajul 'climã temperatã'
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Alege peisajul 'climã sub-arcticã'
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Alege peisajul 'climã sub-tropicalã'
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Alege peisajul 'tara jucãriilor'
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Finanteazã constructia de industrii noi
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Lista industriilor
+STR_0313_FUND_NEW_INDUSTRY :Obiectiv industrial nou
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Construieste un nou obiectiv ind.
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...se poate construi doar in orase
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...se poate construi doar in padurile ecuatoriale
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...se poate construi doar in zonele de desert
+STR_0319_PAUSED :{YELLOW}* * PAUZÃ (F1) * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Screenshot salvat cu succes pe disc în fisierul '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}Screenshot nerealizat!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Cumpãrã teren pentru folosire ulterioarã
+STR_032F_AUTOSAVE :{RED}SALVARE AUTOMATÃ
+STR_SAVING_GAME :{RED}* * SALVARE JOC * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}Salvarea se efectueaza încã,{}vã rugãm asteptati pânã se încheie!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Selecteazã programul muzical 'Ezy Street'
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :Engleza (Original)
+STR_TOWNNAME_FRENCH :Frantuzesti
+STR_TOWNNAME_GERMAN :Germane
+STR_TOWNNAME_ADDITIONAL_ENGLISH :Engleza (Aditional)
+STR_TOWNNAME_LATIN_AMERICAN :Latino-Americane
+STR_TOWNNAME_SILLY :Amuzante (englezã)
+STR_TOWNNAME_SWEDISH :Suedeze
+STR_TOWNNAME_DUTCH :Olandeze
+STR_TOWNNAME_FINNISH :Finlandeze
+STR_TOWNNAME_POLISH :Poloneze
+STR_TOWNNAME_SLOVAKISH :Slovace
+STR_TOWNNAME_NORWEGIAN :Norvegian
+STR_TOWNNAME_HUNGARIAN :Unguresti
+STR_TOWNNAME_AUSTRIAN :Austriece
+STR_TOWNNAME_ROMANIAN :Romanesti
+STR_TOWNNAME_CZECH :Cehe
+STR_TOWNNAME_SWISS :Elvetian
+STR_TOWNNAME_DANISH :Danezã
+STR_TOWNNAME_TURKISH :Turcã
+STR_TOWNNAME_ITALIAN :Italian
+STR_TOWNNAME_CATALAN :Catalan
+############ end of townname region
+
+STR_CURR_GBP :Lira sterlina (£)
+STR_CURR_USD :Dolar ($)
+STR_CURR_EUR :Euro (€)
+STR_CURR_YEN :Yen japonez (Â¥)
+STR_CURR_ATS :Siling austriac (ATS)
+STR_CURR_BEF :Franc belgian (BEF)
+STR_CURR_CHF :Franc elvetian (CHF)
+STR_CURR_CZK :Coroanã cehã (CZK)
+STR_CURR_DEM :Marca germana (DEM)
+STR_CURR_DKK :Coroanã danezã (DKK)
+STR_CURR_ESP :Peseta (ESP)
+STR_CURR_FIM :Marcã finlandezã (FIM)
+STR_CURR_FRF :Franc (FRF)
+STR_CURR_GRD :Drahmã greceascã (GRD)
+STR_CURR_HUF :Forint (HUF)
+STR_CURR_ISK :Coroanã islandezã (ISK)
+STR_CURR_ITL :Lirã italianã (ITL)
+STR_CURR_NLG :Gulden olandez (NLG)
+STR_CURR_NOK :Coroanã norvegianã (NOK)
+STR_CURR_PLN :Zlot (PLN)
+STR_CURR_ROL :Leu românesc (ROL)
+STR_CURR_RUR :Rublã ruseascã (RUR)
+STR_CURR_SIT :Tolar Sloven (SIT)
+STR_CURR_SEK :Coroanã suedezã (SEK)
+STR_CURR_YTL :Lira Turceasca (YTL)
+STR_CURR_SKK :Coroana Slovaca (SKK)
+STR_CURR_BRR :Real Brazilian (BRL)
+
+STR_CURR_CUSTOM :Propriu...
+
+STR_OPTIONS_LANG :{BLACK}Limba
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Alege limba în care doresti afisatã interfata
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Mod
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}Bifeaza aceasta casuta pentru a juca in modul
+
+STR_OPTIONS_RES :{BLACK}Rezolutia ecranului
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Alege rezolutia doritã pentru joc
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Formatul capturii de ecran
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Alege tipul fisierului în care se salveazã captura de ecran (screenshot)
+
+STR_AUTOSAVE_1_MONTH :În fiecare lunã
+STR_AUTOSAVE_FAILED :{WHITE}Auto-salvarea a esuat
+
+STR_MONTH_JAN :ianuarie
+STR_MONTH_FEB :februarie
+STR_MONTH_MAR :martie
+STR_MONTH_APR :aprilie
+STR_MONTH_MAY :mai
+STR_MONTH_JUN :iunie
+STR_MONTH_JUL :iulie
+STR_MONTH_AUG :august
+STR_MONTH_SEP :septembrie
+STR_MONTH_OCT :octombrie
+STR_MONTH_NOV :noiembrie
+STR_MONTH_DEC :decembrie
+
+STR_HEADING_FOR_STATION :{LTBLUE}Spre {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}Spre {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Fãrã rutã
+STR_NO_ORDERS_VEL :{LTBLUE}Fãrã rutã, {VELOCITY}
+
+STR_PASSENGERS :cãlãtori
+STR_BAGS :saci
+STR_TONS :tone
+STR_LITERS :litri
+STR_ITEMS :bucãti
+STR_CRATES :pachete
+STR_RES_OTHER :altele
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Nu pot construi lista de comenzi comune...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Nu pot copia lista de comenzi...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - Sfârsitul comenzilor comune - -
+
+STR_TRAIN_IS_LOST :{WHITE}Trenul {COMMA} s-a rãtãcit.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}Profitul trenului {COMMA} a fost anul trecut de {CURRENCY}
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}Uniunea Monetarã Europeanã!{}{}Euro este introdus în tarã ca monedã unicã de folosintã în tranzactiile zilnice!
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Trenul {COMMA} are prea putine comenzi în listã
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}Trenul {COMMA} nu are comenzi
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}Trenul {COMMA} are comenzi repetate
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}Trenul {COMMA} are o statie inexistentã în comenzi
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}Autovehiculul {COMMA} are prea putine comenzi în listã
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}Autovehiculul {COMMA} nu are comenzi
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}Autovehiculul {COMMA} are comenzi repetate
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}Autovehiculul {COMMA} are o statie inexistentã în comenzi
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}Nava {COMMA} are prea putine comenzi în listã
+STR_SHIP_HAS_VOID_ORDER :{WHITE}Nava {COMMA} nu are comenzi
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}Nava {COMMA} are comenzi repetate
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}Nava {COMMA} are o statie inexistentã în comenzi
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}Aeronava {COMMA} are prea putine comenzi în listã
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}Aeronava {COMMA} nu are comenzi
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}Aeronava {COMMA} are comenzi repetate
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}Aeronava {COMMA} are o statie inexistentã în comenzi
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}ÃŽnnoirea trenului {COMMA} a esuat (fonduri limitate)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}ÃŽnnoirea autovehiculului {COMMA} a esuat (fonduri limitate)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}ÃŽnnoirea navei {COMMA} a esuat (fonduri limitate)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}ÃŽnnoirea aeronavei {COMMA} a esuat (fonduri limitate)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}Trenul {COMMA} este prea lung dupa inlocuire
+
+STR_CONFIG_PATCHES :{BLACK}Configurare patch
+STR_CONFIG_PATCHES_TIP :{BLACK}Configureazã patch-urile OpenTTD
+STR_CONFIG_PATCHES_CAPTION :{WHITE}Configurare patch
+
+STR_CONFIG_PATCHES_OFF :inactiv
+STR_CONFIG_PATCHES_ON :activ
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Afiseazã viteza vehiculelor in bara de jos: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Permite construirea pe coastã si in pantã: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Permite arii de cuprindere mai realistice: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Permite demolarea unui nr. mai mare constructii: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Permite constructia de trenuri foarte lungi: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Permite acceleratie realisticã pentru trenuri: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Interzice trenurilor si navelor sa faca intoarceri de 90 de grade: {ORANGE}{STRING} {LTBLUE} (necesita NPF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Uneste gãrile alãturate: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Pãrãseste statia când orice tip de marfã este 'full load': {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Foloseste algoritmul de LOAD imbunatatit: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GRADUAL_LOADING :{LTBLUE}Incarca vehiculele gradual: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Inflatia: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Livreazã marfa doar in statiile unde aceasta este ceruta: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Permite constructia de poduri foarte lungi: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Permite ordine de tipul "mergi la depou": {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Permite constructia de industrii pentru materii prime: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Permite mai multe industrii similare in acelasi oras: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Industrii identice pot fi construite aproape una de cealaltã: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Afiseazã intotdeauna data in format lung in bara de stare: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Afiseazã semnalele pe partea de circulatie: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Afiseazã finantele la sfârsitul fiecãrui an: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}Utilizeazã o metodã gen TTDPatch pentru 'non stop': {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Autovehiculele formeazã o coadã (cu efecte cuantice): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Mutã imaginea când mouse-ul este la marginea ecranului: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Permite mituirea autoritãtilor locale: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Statii neuniforme: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Nou pathfinding global(NPF, dezactiveaza NTP): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FREIGHT_TRAINS :{LTBLUE}Multiplicator greutate pt marfar pt simularea trenurilor grele: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Permite întotdeauna aeroporturi mici: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Avertizeaza daca trenul este pierdut: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Verificarea ordinelor vehiculelor: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :nu
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :da, dar exclude vehiculele oprite
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :pentru toate vehiculele
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Avertizare in cazul in care un tren are profit negativ: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Vehiculele nu expirã niciodatã: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Înnoire automatã pentru vehiculele învechite
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Înnoire automatã cu {ORANGE}{STRING}{LTBLUE} luni pânã la/dupã atingerea vechimii max.
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Fonduri minime pentru înnoire automatã: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Durata mesajelor de eroare: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Afiseaza populatia unui oras langa nume: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Ascunde arborii la alegerea optiunii 'clãdiri transparente': {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Generator teren: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :Original
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :TerraGeneza
+STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}Distanta maxima de la margine pt Rafinariile de petrol {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Altitudinea de înzãpezire: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN :{LTBLUE}Duritatea terenului (Doar pt TerraGeneza) : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Foarte fin
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH :Fin
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH :Dur
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :Foarte dur
+STR_CONFIG_PATCHES_TREE_PLACER :{LTBLUE}Algoritm amplasare arbori: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TREE_PLACER_NONE :Niciunul
+STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL :Original
+STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED :Imbunatatit
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION :{LTBLUE}Rotatie harta inaltimiHeightmap rotation: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :In sens invers al acelor de ceasornic
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE :In sensul acelor de ceasornic
+STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT :{LTBLUE}Nivelul inaltimii atins de o harta plana: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Mãrimea maximã a statiilor: {ORANGE}{STRING} {RED}(valorile mari încetinesc jocul!)
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Service automat pentru elicoptere la helipaduri: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Conecteaza bara de instrumente pentru peisaj cu cea de constructii feroviare/auto/aeriane: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Cand faci scroll cu mouse-ul muta ecranul in directia opusã: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Arata o bara de unelte de masuratori la folosirea uneltelor de constructie: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Arata unifromete companiilor: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES_NONE :Niciunul
+STR_CONFIG_PATCHES_LIVERIES_OWN :Propria companie
+STR_CONFIG_PATCHES_LIVERIES_ALL :Toate companiile
+STR_CONFIG_PATCHES_PREFER_TEAMCHAT :{LTBLUE}Echipa preferata pentru chat <ENTER>: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Nr. max. de trenuri pentru un jucãtor: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Nr. max. de autovehicule pentru un jucãtor: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}Nr. max. de aeronave pentru un jucãtor: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}Nr. max. de nave pentru un jucãtor: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Dezactiveazã trenurile pentru jucãtorii PC: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Dezactiveazã autovehiculele pentru jucãtorii PC: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Dezactiveazã aeronavele pentru jucãtorii PC: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Dezactiveazã navele pentru jucãtorii PC: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Foloseste noul AI (versiune alfa): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Permite AI în multiplayer (experimental): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Intervalul de service presetat pentru trenuri: {ORANGE}{STRING} zile
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Intervalul de service presetat pentru trenuri: {ORANGE}dezactivat
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Intervalul de service presetat pentru autovehicule: {ORANGE}{STRING} zile
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Intervalul de service presetat pentru autovehicule: {ORANGE}dezactivat
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Intervalul de service presetat pentru aeronave: {ORANGE}{STRING} zile
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Intervalul de service presetat pentru aeronave: {ORANGE}dezactivat
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Intervalul de service presetat pentru nave: {ORANGE}{STRING} zile
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Intervalul de service presetat pentru nave: {ORANGE}dezactivat
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Deactivare service cand defectiunile sunt anulate: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Activeazã limite de vitezã pt. vagoane: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}Dezactiveaza sinele electrice: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Stirile în culori apar în anul: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Anul de început a jocului: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}Termina jocul in: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Economie cu schimbãri de productie mai reduse, dar mai frecvente
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Permite cumpararea de actiuni de la alte companii
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Plasare automatã a semnalelor la fiecare: {ORANGE}{STRING} pãtrãtele
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Pozitia listei cu instrumente: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :stânga
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :centru
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :dreapta
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Distanta de 'snap' pentru ferestre: {ORANGE}{STRING} px
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Distanta de 'snap' pentru ferestre: {ORANGE}dezactivata
+
+STR_CONFIG_PATCHES_GUI :{BLACK}Interfatã
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Constructie
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Vehicule
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Statii
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Economie
+STR_CONFIG_PATCHES_AI :{BLACK}Concurenti
+
+STR_CONFIG_PATCHES_DISABLED :dezactivat
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Schimbã valoarea setãrii
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Unele sau toate din intervalurile de service alese sunt incompatibile cu setarea aleasa! Valorile valide sunt cuprinse intre 5-90% si 30-800 zile
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}Foloseste YAPF pentru nave: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}Foloseste YAPF pentru autoveh: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}Foloseste YAPF pentru trenuri: {ORANGE}{STRING}
+
+STR_TEMPERATE_LANDSCAPE :peisajul temperat
+STR_SUB_ARCTIC_LANDSCAPE :peisajul sub-arctic
+STR_SUB_TROPICAL_LANDSCAPE :peisajul sub-tropical
+STR_TOYLAND_LANDSCAPE :peisajul 'tara jucãriilor'
+
+STR_CHEATS :{WHITE}Cheat-uri
+STR_CHEATS_TIP :{BLACK}Checkbox-urile aratã un cheat folosit anterior
+STR_CHEATS_WARNING :{BLACK}Atentie! Esti pe cale sã-ti trãdezi colegii de joc! Nu uita cã aceastã rusine va rãmâne înregistratã pentru totdeauna!
+STR_CHEAT_MONEY :{LTBLUE}Mãreste fondurile cu {CURRENCY64}
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Joacã în locul jucãtorului: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Buldozer magic (demoleazã industrii si lucruri amovibile): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Tunelele se pot intersecta: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Construieste în modul pauzã: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Avioanele cu reactie nu se vor prãbusi (frecvent) pe aeroporturile mici: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Schimbã peisajul: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Schimbã data: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}Activeaza accesul la valorile de productie: {ORANGE}{STRING}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}Merge spre {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Merge spre {WAYPOINT}, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :Mergi via {WAYPOINT}
+STR_GO_NON_STOP_TO_WAYPOINT :Mergi non-stop via {WAYPOINT}
+
+STR_WAYPOINTNAME_CITY :Halta {TOWN}
+STR_WAYPOINTNAME_CITY_SERIAL :Halta {TOWN} #{COMMA}
+STR_LANDINFO_WAYPOINT :Haltã de miscare
+
+STR_WAYPOINT :{WHITE}Punct de tranzit
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Alege tipul de punct de tranzit
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}Editeazã numele haltei
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Nu pot schimba numele haltei...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Converteste linia în haltã de miscare (waypoint)
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Nu pot plasa o haltã aici...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Nu pot sterge halta de aici...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Construieste cale feratã în modul automat
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}...în acest scenariu nu existã nici un oras
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}Esti sigur cã vrei sã creezi un peisaj aleator?
+STR_MANY_RANDOM_TOWNS :{BLACK}Mai multe orase aleatoare
+STR_RANDOM_TOWNS_TIP :{BLACK}Umple harta cu orase generate aleator
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Multe industrii aleatoare
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Umple harta cu industrii generate aleator
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Nu pot genera industrii...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Afiseaza instrumentele pentru modelarea terenului, plantarea copacilor, etc.
+STR_LANDSCAPING_TOOLBAR :{WHITE}Modificare peisaj
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Niveleazã terenul
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Arbori din specii aleatoare
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}Planteazã arbori din diverse specii la întâmplare
+
+STR_CANT_BUILD_CANALS :{WHITE}Nu pot construi un canal aici...
+STR_BUILD_CANALS_TIP :{BLACK}Construieste canale
+STR_LANDINFO_CANAL :Canal
+
+STR_CANT_BUILD_LOCKS :{WHITE}Nu pot construi o ecluzã aici...
+STR_BUILD_LOCKS_TIP :{BLACK}Construieste ecluzã
+STR_LANDINFO_LOCK :Ecluzã
+
+STR_BUOY_IS_IN_USE :{WHITE}... baliza in uz!
+
+STR_LANDINFO_COORDS :{BLACK}Coordonate: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Nu pot demola o parte din statie...
+STR_CANT_CONVERT_RAIL :{WHITE}Nu pot converti linia aici...
+STR_CONVERT_RAIL_TIP :{BLACK}Converteste tipul de cale feratã
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Trage locomotiva aici pentru a vinde întregul tren
+
+STR_DRAG_DROP :{BLACK}Drag & Drop
+STR_STATION_DRAG_DROP :{BLACK}Construieste o statie prin drag & drop
+STR_SELECT_STATION_CLASS_TIP :{BLACK}Alege o clasã de statii pentru afisare
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Alege tipul de statie pentru constructie
+
+STR_FAST_FORWARD :{BLACK}Mãreste viteza de trecere a timpului (TAB)
+STR_MESSAGE_HISTORY :{WHITE}Cronologia mesajelor
+STR_MESSAGE_HISTORY_TIP :{BLACK}O listã a celor mai recente mesaje
+STR_MESSAGES_DISABLE_ALL :{BLACK}Dezactiveazã toate
+STR_MESSAGES_ENABLE_ALL :{BLACK}Activeazã toate
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Construieste minã de cãrbune
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Planteazã pãdure
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Construieste platformã petrolierã
+STR_CONSTRUCT_FARM_TIP :{BLACK}Înfiinteazã fermã
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Construieste minã de cupru
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Foreazã dupã petrol
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Construieste minã de aur
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Construieste minã de diamante
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Construieste minã de fier
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Planteazã livadã
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Înfiinteazã plantatie de cauciuc
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Construieste rezervor de apã
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Planteazã pãdure de vatã de zahãr
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}Planteazã pãdure de baterii
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Foreazã dupã cola
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Construieste fântâni de plastic
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Construieste generator de balonase
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Construieste carierã de caramel
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Construieste minã de zahãr
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Industrii
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA}% transportat)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA}%/{COMMA}% transportat)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}...prea aproape de altã industrie
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Schimba tipul încãrcãturii cãratã de acest tren
+STR_RAIL_REFIT_VEHICLE :{BLACK}Modificã încãrcãturã
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Alege tipul de marfã transportat de tren
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Modificã trenul pentru a transporta marfa aleasã
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Nu pot modifica trenul...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Intervaluri de service in procente: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Schimba productia
+
+TEMP_AI_IN_PROGRESS :{WHITE}Salut! Sunt noul algoritm AI, încã în teste. Dacã apar probleme, salveazã un screenshot si pune-l pe forum. Baftã!
+TEMP_AI_ACTIVATED :{WHITE}Atentie: algoritmul AI este în stadiul alfa! Momentan este valabil doar pentru autovehicule!
+TEMP_AI_MULTIPLAYER :{WHITE}Atentie: aceastã functiune este încã experimentalã. Vã rugãm sã raportati orice problemã la adresa truelight@openttd.org
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Multiplayer
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Numele jucãtorului:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}Acesta este numele prin care te vor identifica ceilalti
+STR_NETWORK_CONNECTION :{BLACK}Conexiune:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Alege intre un joc pe internet si unul pe LAN
+
+STR_NETWORK_START_SERVER :{BLACK}Porneste serverul
+STR_NETWORK_START_SERVER_TIP :{BLACK}Porneste un server propriu
+
+STR_NETWORK_GAME_NAME :{BLACK}Nume
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Numele jocului
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Limba, versiunea serverului, etc.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Click pe un joc din listã pentru a-l selecta
+
+STR_NETWORK_FIND_SERVER :{BLACK}Cautã server
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Cautã un server în retea
+STR_NETWORK_ADD_SERVER :{BLACK}Adauga un server
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Adauga un server pe lista care va fi verificata pentru jocuri active
+STR_NETWORK_ENTER_IP :{BLACK}Introdu IP-ul serverului
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Clienti
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Clienti online / Nr. max. clienti
+STR_NETWORK_GAME_INFO :{SILVER}INFO JOC
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Clienti: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Limba: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Tileset: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Marimea hartii: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}Versiune server: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}Adresa serverului: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Data de inceput: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Data curenta: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Protejat cu parola!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}SERVER OFFLINE
+STR_NETWORK_SERVER_FULL :{SILVER}SERVER PLIN
+STR_NETWORK_VERSION_MISMATCH :{SILVER}VERSIUNE DIFERITA
+STR_NETWORK_GRF_MISMATCH :{SILVER}NEWGRF NEPOTRIVIRE
+
+STR_NETWORK_JOIN_GAME :{BLACK}Intrã în joc
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}ÃŽncepe un joc nou
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Nume joc:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}Numele jocului va fi afisat celorlalti în meniul de selectare al jocurilor multiplayer
+STR_NETWORK_SET_PASSWORD :{BLACK}Pune parola
+STR_NETWORK_PASSWORD_TIP :{BLACK}Protejeazã-ti jocul cu o parolã dacã nu vrei sã intre jucãtori neautorizati
+STR_NETWORK_SELECT_MAP :{BLACK}Alege o hartã:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}Ce hartã doresti sa joci?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}Numar maxim de clienti
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Alege un numar maxim de clienti. Nu trebuie ocupate toate locurile.
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :LAN
+STR_NETWORK_INTERNET :Internet
+STR_NETWORK_LAN_INTERNET :LAN / Internet
+STR_NETWORK_INTERNET_ADVERTISE :Internet (fa reclama)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 jucãtori
+STR_NETWORK_1_PLAYERS :1 jucãtor
+STR_NETWORK_2_PLAYERS :2 jucãtori
+STR_NETWORK_3_PLAYERS :3 jucãtori
+STR_NETWORK_4_PLAYERS :4 jucãtori
+STR_NETWORK_5_PLAYERS :5 jucãtori
+STR_NETWORK_6_PLAYERS :6 jucãtori
+STR_NETWORK_7_PLAYERS :7 jucãtori
+STR_NETWORK_8_PLAYERS :8 jucãtori
+STR_NETWORK_9_PLAYERS :9 jucãtori
+STR_NETWORK_10_PLAYERS :10 jucãtori
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}Maximum companii:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Limiteazã serverle la un anumit numãr companii
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}Maxim spectatori:
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Limiteazã serverul la un anumit numãr de spectatori
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Limba vorbita:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Ceilalti jucatori vor sti in ce limba se discuta per server.
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}ÃŽncepe jocul
+STR_NETWORK_START_GAME_TIP :{BLACK}Incepe un joc nou in retea cu o harta aleatoare sau intr-un scenariu
+STR_NETWORK_LOAD_GAME :{BLACK}Incarca joc
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Reia un joc multiplayer salvat anterior (asigura-te ca s-au conectat jucatorii corespunzatori)
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Oricare
+STR_NETWORK_LANG_ENGLISH :Engleza
+STR_NETWORK_LANG_GERMAN :Germana
+STR_NETWORK_LANG_FRENCH :Franceza
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Chatul jocului multiplayer
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}In pregatire pentru joc: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}Lista companiilor din jocul curent. Poti colabora cu o companie sau sa infiintezi una
+STR_NETWORK_NEW_COMPANY :{BLACK}Companie nouã
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Fondeazã o nouã companie
+STR_NETWORK_SPECTATE_GAME :{BLACK}Modul spectator
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Vizioneazã un joc din pozitia unui spectator
+STR_NETWORK_JOIN_COMPANY :{BLACK}Alatura-te companiei
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Ajuta la conducerea acestei companii
+STR_NETWORK_REFRESH :{BLACK}Actualizeaza serverul
+STR_NETWORK_REFRESH_TIP :{BLACK}Actualizeaza informatiile despre server
+
+STR_NETWORK_COMPANY_INFO :{SILVER}INFO COMPANIE
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Numele companiei: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}Inaugurarea: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}Valoarea companiei: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Balanta curenta: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Venituri anul trecut: {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}Performanta: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}Vehicule: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Statii: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Jucatori: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}Conectare...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) Conectare..
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Authorizare..
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Asteptati..
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Descarcare harta..
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Prelucrare date..
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) Inregistrare...
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Preluare info joc..
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Preluare info companie..
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} client{P "" i} inaintea noastra
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} kbytes descarcati pana acum
+
+STR_NETWORK_DISCONNECT :{BLACK}Deconectare
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Introdu suma de bani pe care vrei sa o cedezi
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Server protejat. Introdu parola
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Companie protejata. Introdu parola
+STR_NETWORK_CLIENT_LIST :{WHITE}Lista de clienti
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE}Nu a fost detectatã o placã de retea valabilã
+STR_NETWORK_ERR_NOSERVER :{WHITE}Nu a fost gãsit nici un joc în retea
+STR_NETWORK_ERR_NOCONNECTION :{WHITE}Serverul nu a rãspuns cererii
+STR_NETWORK_ERR_DESYNC :{WHITE} Sincronizarea jocului in retea a esuat.
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} Conexiunea jocului in reatea a fost intrerupta.
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} Nu am reusit sa incarc jocul-server salvat.
+STR_NETWORK_ERR_SERVER_START :{WHITE}Nu pot porni serverul.
+STR_NETWORK_ERR_CLIENT_START :{WHITE}Nu pot efectua conectarea.
+STR_NETWORK_ERR_TIMEOUT :{WHITE} Conexiunea #{NUM} a expirat.
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE}Eroare de protocol. Conexiunea a fost inchisa.
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE}Versiunea acestui client este diferita de cea a serverului.
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE}Parola gresita.
+STR_NETWORK_ERR_SERVER_FULL :{WHITE}Serverul este plin
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} Acessul tau este interzis pe acest server
+STR_NETWORK_ERR_KICKED :{WHITE}Ai fost dat afara de pe server
+STR_NETWORK_ERR_CHEATER :{WHITE} Cheat-urile nu sunt permise pe acest server
+
+STR_NETWORK_ERR_LEFT :a parasit jocul
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :eroare generala
+STR_NETWORK_ERR_CLIENT_DESYNC :eroare de desincronizare
+STR_NETWORK_ERR_CLIENT_SAVEGAME :nu pot incarca harta
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :conexiune pierduta
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :eroare de protocol
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :neautorizat
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :primit pachet ciudat
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :versiune incorecta
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :nume folosit deja
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :parola gresita
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :player-id in DoCommand gresit
+STR_NETWORK_ERR_CLIENT_KICKED :dat afara de pe server
+STR_NETWORK_ERR_CLIENT_CHEATER :a incercat sa foloseasca un cheat
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :server plin
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :a intrat in joc
+STR_NETWORK_GIVE_MONEY :ti-a dat o suma de bani ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :ai donat o suma de bani companiei {STRING} ({CURRENCY})
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Team] :
+STR_NETWORK_CHAT_COMPANY :[Team] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Team] To {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[Private] :
+STR_NETWORK_CHAT_CLIENT :[Private] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[Private] pentru {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[All] :
+STR_NETWORK_CHAT_ALL :[All] {STRING}: {GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :si-a schimbat numele in
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE}Serverul a inchis conexiunea
+STR_NETWORK_SERVER_REBOOT :{WHITE}Serverul este repornit...{}Va rugam asteptati...
+
+STR_NETWORK_SERVER :Server
+STR_NETWORK_CLIENT :Client
+STR_NETWORK_SPECTATORS :Spectatori
+
+STR_NETWORK_CLIENTLIST_NONE :(none)
+STR_NETWORK_CLIENTLIST_KICK :Kick
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Doneaza bani
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Vorbeste catre toti
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Vorbeste catre companie
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Mesaj privat
+
+
+STR_NETWORK_SEND :{BLACK}Trimite
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}Marimea X a hartii: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Marimea Y a hartii: {ORANGE}{STRING}
+
+
+##### PNG-MAP-Loader
+
+STR_PNGMAP_ERROR :{WHITE}Nu pot incarca peisajul din PNG...
+STR_PNGMAP_ERR_FILE_NOT_FOUND :{WHITE}...fisierul lipseste.
+STR_PNGMAP_ERR_IMAGE_TYPE :{WHITE}...nu am reusit conversia tipului de imagine. Introdu un imagine PNG 8 sau 24-bit.
+STR_PNGMAP_ERR_MISC :{WHITE}...ceva a mers gresit. Scuze. (probabil fisierul este defect)
+
+STR_BMPMAP_ERROR :{WHITE}Nu pot incarca peisajul din BMP...
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}...nu am putut converti tipul de imagine.
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Cheltuieli: {CURRENCY}
+STR_0801_COST :{RED}Cheltuieli: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Încasãri: {CURRENCY}
+STR_0803_INCOME :{GREEN}Încasãri: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Transferã: {CURRENCY}
+STR_FEEDER :{YELLOW}Transferã: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Cost estimat: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Venit estimat: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Nu pot înãlta terenul...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Nu pot sãpa terenul...
+STR_080A_ROCKS :Stânci
+STR_080B_ROUGH_LAND :Teren pietros
+STR_080C_BARE_LAND :Teren viran
+STR_080D_GRASS :Verdeatã
+STR_080E_FIELDS :Teren agricol
+STR_080F_SNOW_COVERED_LAND :Zãpadã
+STR_0810_DESERT :Desert
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Terenul are o înclinatie nepotrivitã
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Combinatie de linii imposibilã
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}Sãpãturile ar afecta tunelul
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Te afli deja la nivelul mãrii
+STR_1004_TOO_HIGH :{WHITE}Prea înalt
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Cale feratã nepotrivitã
+STR_1007_ALREADY_BUILT :{WHITE}...deja construit
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Mai intâi trebuie demolatã calea feratã
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Constructii feroviare
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Constructie Cale Feratã Electrificatã
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Constructii monorail
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}Constructii maglev
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Alege podul de cale feratã
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Nu pot construi un depou aici...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Nu pot construi o garã aici...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Nu pot plasa semnale aici...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Nu pot construi cale feratã aici...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Nu pot demola calea feratã...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Nu pot demola semnalele de aici...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Orientarea depoului
+STR_1015_RAILROAD_CONSTRUCTION :Constructii feroviare
+STR_TOOLB_ELRAIL_CONSTRUCTION :Constructie cale feratã electrificatã
+STR_1016_MONORAIL_CONSTRUCTION :Constructii monorail
+STR_1017_MAGLEV_CONSTRUCTION :Constructii maglev
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Construieste cale feratã
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Construieste un depou feroviar (pentru construire/service trenuri)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Construieste garã
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Plaseazã semnale feroviare
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Construieste pod de cale feratã
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Construieste tunel feroviar
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Comutator pentru constructie/demolare cãi ferate si semnale
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Alegere pod - clic pe podul selectat pentru a-l construi
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Alege orientarea depoului
+STR_1021_RAILROAD_TRACK :Cale feratã
+STR_1023_RAILROAD_TRAIN_DEPOT :Depou de cale feratã
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...terenul se aflã in posesia altei companii
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :Cale feratã cu semnale normale
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :Cale feratã cu pre-semnalizare
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :Cale feratã cu semnale de iesire
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :Cale feratã cu semnale combinate
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Mai întâi trebuie demolatã soseaua
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Lucrari la drum in curs de desfasurare
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Constructii rutiere
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Alege pod rutier
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Nu pot construi sosea aici...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Nu pot demola soseaua...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Orientarea autobazei
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Nu pot construi autobazã aici...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Nu pot construi statie de autobuz...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Nu pot construi platformã pentru camioane...
+STR_180A_ROAD_CONSTRUCTION :Constructii rutiere
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Construieste sectiune de sosea
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Construieste o autobazã (pentru construire/service autovehicule)
+STR_180D_BUILD_BUS_STATION :{BLACK}Plaseazã statie de autobuz
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Construieste platformã pentru camioane
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Construieste pod rutier
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Construieste tunel rutier
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Comutator pentru constructie/demolare sosele
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Alege orientarea autobazei
+STR_1814_ROAD :Stradã
+STR_1815_ROAD_WITH_STREETLIGHTS :Stradã iluminatã
+STR_1816_TREE_LINED_ROAD :Stradã cu copaci pe margine
+STR_1817_ROAD_VEHICLE_DEPOT :Autobazã
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :Traversare la nivel cu calea feratã
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Orase
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Mai întâi trebuie sã demolezi clãdirea
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}Populatia: {ORANGE}{COMMA}{BLACK} Locuinte: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Redenumire
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Nu pot redenumi orasul...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}Autoritãtile locale din {TOWN} refuzã sã permitã acest lucru
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Numele oraselor - clic pe un nume pentru a centra imaginea pe orasul respectiv
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Mutã imaginea pe locatia orasului
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Schimbã numele orasului
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Calatori luna trecuta: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Colete postale luna trecuta: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Clãdire înaltã de birouri
+STR_2010_OFFICE_BLOCK :Clãdire de birouri
+STR_2011_SMALL_BLOCK_OF_FLATS :Clãdire micã de birouri
+STR_2012_CHURCH :Bisericã
+STR_2013_LARGE_OFFICE_BLOCK :Clãdire mare de birouri
+STR_2014_TOWN_HOUSES :Case
+STR_2015_HOTEL :Hotel
+STR_2016_STATUE :Statuie
+STR_2017_FOUNTAIN :Fântânã
+STR_2018_PARK :Parc
+STR_2019_OFFICE_BLOCK :Clãdire de birouri
+STR_201A_SHOPS_AND_OFFICES :Magazine si birouri
+STR_201B_MODERN_OFFICE_BUILDING :Clãdire modernã de birouri
+STR_201C_WAREHOUSE :Depozit
+STR_201D_OFFICE_BLOCK :Bloc de birouri
+STR_201E_STADIUM :Stadion
+STR_201F_OLD_HOUSES :Case vechi
+STR_2020_LOCAL_AUTHORITY :{BLACK}Autoritate loc.
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Afiseazã informatii referitoare la autoritatea localã
+STR_2022_LOCAL_AUTHORITY :{WHITE}Autoritatea localã din {TOWN}
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Ratingul companiilor de transport:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Subventii (F6)
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Subventii disponibile:
+STR_2027_FROM_TO :{ORANGE}- {STRING} de la {STRING} la {STRING}
+STR_2028_BY :{YELLOW} (data limitã: {DATE_SHORT})
+STR_202A_NONE :{ORANGE}- nici una
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Subventii acordate la ora actualã:
+STR_202C_FROM_TO :{ORANGE}- {STRING} de la {STATION} la {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, pânã în {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}Ofertã expiratã:{}{}Transportul de {STRING} de la {STRING} la {STRING} nu va mai fi subventionat
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Ofertã închisã:{}{}Transportul de {STRING} de la {STATION} la {STATION} nu va mai fi subventionat
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Subventie oferitã:{}{}Primul transport de {STRING} de la {STRING} la {STRING} va atrage subventionarea pe un an din partea autoritãtilor locale
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subventie acordatã companiei {COMPANY}!{}{}Transportul de {STRING} de la {STATION} la {STATION} va aduce încasãri cu 50% mai mari timp de un an!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subventie acordatã companiei {COMPANY}!{}{}Transportul de {STRING} de la {STATION} la {STATION} va aduce încasãri duble timp de un an!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subventie acordatã companiei {COMPANY}!{}{}Transportul de {STRING} de la {STATION} la {STATION} va aduce încasãri triple timp de un an!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subventie acordatã companiei {COMPANY}!{}{}Transportul de {STRING} de la {STATION} la {STATION} va aduce încasãri de patru ori mai mari timp de un an!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}Autoritatea localã din {TOWN} refuzã sã permitã construirea unui nou aeroport în acest oras
+STR_2036_COTTAGES :Cãsute
+STR_2037_HOUSES :Case
+STR_2038_FLATS :Blocuri
+STR_2039_TALL_OFFICE_BLOCK :Clãdire înaltã de birouri
+STR_203A_SHOPS_AND_OFFICES :Magazine si birouri
+STR_203B_SHOPS_AND_OFFICES :Magazine si birouri
+STR_203C_THEATER :Teatru
+STR_203D_STADIUM :Stadion
+STR_203E_OFFICES :Birouri
+STR_203F_HOUSES :Case
+STR_2040_CINEMA :Cinema
+STR_2041_SHOPPING_MALL :Centru comercial
+STR_2042_DO_IT :{BLACK}Alege
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}Lista de actiuni disponibile pentru acest oras - clic pe fiecare pentru mai multe detalii
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Activeazã actiunea selectatã din listã
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Actiuni disponibile:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Campanie publicitarã micã
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Campanie publicitarã medie
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Campanie publicitarã mare
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Finanteazã reconstructia strãzilor
+STR_204A_BUILD_STATUE_OF_COMPANY :Ridicã un monument dedicat presedintelui companiei
+STR_204B_FUND_NEW_BUILDINGS :Finanteazã constructia de noi clãdiri
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Cumpãrã drepturile exclusive de transport
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Mituieste autoritatea localã
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Initiazã o campanie publicitarã micã pentru a atrage mai multi pasageri si mai multe mãrfuri spre compania ta.{} Cost: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Initiazã o campanie publicitarã medie pentru a atrage mai multi pasageri si mai multe mãrfuri spre compania ta.{} Cost: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Initiazã o mare campanie publicitarã pentru a atrage mai multi pasageri si mai multe mãrfuri spre compania ta.{} Cost: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} Finanteazã reconstructia strãzilor locale. Acest lucru cauzeazã devieri majore ale traficului rutier timp de 6 luni.{} Cost: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Înaltã o statuie în cinstea companiei tale.{} Cost: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Finanteazã constructia de noi clãdiri comerciale în oras.{} Cost: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Cumpãrã drepturile exclusive în acest oras pe o perioadã de un an. Autoritãtile locale vor folosi doar compania ta pentru transportul de pasageri si mãrfuri.{} Cost: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Mituieste autoritãtile locale pentru a-ti îmbunãtãti ratingul, dar cu riscul de a fi prins si de a plãti amenzi serioase.{} Cost: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}Haos pe strãzile din {TOWN}!{}{}Programul finantat de {COMPANY} pentru reconstructia strãzilor, aduce 6 luni de haos participantilor la trafic!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (în constructie)
+STR_2059_IGLOO :Iglu
+STR_205A_TEPEES :Corturi
+STR_205B_TEAPOT_HOUSE :Casã-ceainic
+STR_205C_PIGGY_BANK :Pusculitã
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN} {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Modificare peisaj
+STR_2800_PLANT_TREES :Planteazã arbori
+STR_2801_PLACE_SIGN :Plaseazã semn
+STR_2802_TREES :{WHITE}Arbori
+STR_2803_TREE_ALREADY_HERE :{WHITE}...sunt deja plantati arbori
+STR_2804_SITE_UNSUITABLE :{WHITE}...locatie nepotrivitã
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Nu pot planta arbori aici...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...prea multe semne
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Nu pot plasa un semn aici...
+STR_280A_SIGN :Semn
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Editeazã textul semnului
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Nu pot schimba numele semnului...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Alege specia de arbori plantati
+STR_280E_TREES :Arbori
+STR_280F_RAINFOREST :Pãdure tropicalã
+STR_2810_CACTUS_PLANTS :Cactusi
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Alege tipul de garã
+STR_3001_AIRPORT_SELECTION :{WHITE}Alege tipul de aeroport
+STR_3002_ORIENTATION :{BLACK}Orientarea
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Numãr de linii
+STR_3004_PLATFORM_LENGTH :{BLACK}Lungimea liniilor
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Prea aproape de altã garã
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Este adiacentã mai multor statii
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}Prea multe statii in acest oras
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}Prea multe statii
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Prea multe statii de autobuz
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}Prea multe statii de camion
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Prea aproape de altã statie
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Mai întâi trebuie demolatã gara
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Prea aproape de alt aeroport
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Mai întâi trebuie demolat aeroportul
+
+STR_3030_RENAME_STATION_LOADING :Redenumeste statia
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Nu pot redenumi statia...
+STR_3032_RATINGS :{BLACK}Ratinguri
+STR_3033_ACCEPTS :{BLACK}Acceptã
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}Ratingul serviciilor de transport local:
+
+############ range for rating starts
+STR_3035_APPALLING :Deplorabil
+STR_3036_VERY_POOR :Foarte scãzut
+STR_3037_POOR :Slab
+STR_3038_MEDIOCRE :Mediocru
+STR_3039_GOOD :Bun
+STR_303A_VERY_GOOD :Foarte bun
+STR_303B_EXCELLENT :Excelent
+STR_303C_OUTSTANDING :Fantastic
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} nu mai acceptã {STRING}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} nu mai acceptã {STRING} sau {STRING}
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} acceptã acum {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} acceptã acum {STRING} si {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Orientarea statiei
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Orientarea statiei
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Mai intâi trebuie demolatã statia de autbuz
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Mai intâi trebuie demolatã platforma pentru camioane
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Statii
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Nici una -
+STR_304B_SITE_UNSUITABLE :{WHITE}...locatie nepotrivitã
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Prea aproape de alt port
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Mai intai trebuie demolat portul
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Alege orientarea gãrii
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Alege numãrul de linii al gãrii
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Alege lungimea liniilor gãrii
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Alege orientarea statiei de autobuz
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Alege orientarea platformei pentru camioane
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Centreazã imaginea pe locatia statiei
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Afiseazã ratingurile statiei
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Schimbã numele statiei
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Afiseazã lista de încarcãturi acceptate
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Numele statiilor - clic pe un nume pentru a centra imaginea pe statia respectivã
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Alege tipul de aeroport
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :Garã
+STR_305F_AIRCRAFT_HANGAR :Hangar
+STR_3060_AIRPORT :Aeroport
+STR_3061_TRUCK_LOADING_AREA :Platformã pentru camioane
+STR_3062_BUS_STATION :Statie de autobuz
+STR_3063_SHIP_DOCK :Port
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Aratã aria de acoperire a locatiei propuse
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Nu arãta aria de acoperire a locatiei propuse
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Aratã aria de acoperire
+STR_3068_DOCK :{WHITE}Port
+STR_3069_BUOY :Balizã
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...balizã în cale
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...statie prea mare
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...statii neuniforme dezactivat
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Tine apãsat CTRL pentru a alege mai mult decât un obiect
+
+STR_UNDEFINED :(sir nedefinit)
+STR_STAT_CLASS_DFLT :Statie implicitã
+STR_STAT_CLASS_WAYP :Punct itinerar
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Orientarea santierului naval
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...trebuie construit pe apã
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Nu pot construi un santier naval aici...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Alege orientarea santierului naval
+STR_3804_WATER :Apã
+STR_3805_COAST_OR_RIVERBANK :Mal/Coastã
+STR_3806_SHIP_DEPOT :Santier naval
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...Nu pot construi pe apã
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Salveazã joc
+STR_4001_LOAD_GAME :{WHITE}Încarcã joc
+STR_4002_SAVE :{BLACK}Salveazã
+STR_4003_DELETE :{BLACK}Sterge
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} megabytes liberi
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Nu pot citi acest drive
+STR_4007_GAME_SAVE_FAILED :{WHITE}Salvarea jocului esuatã
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Stergerea jocului esuatã
+STR_4009_GAME_LOAD_FAILED :{WHITE}Încãrcarea jocului esuatã
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}Lista de drive-uri, directoare si fisiere cu jocuri salvate
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Numele selectat pentru un joc salvat
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Sterge jocul salvat selectat
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Salveazã cu numele selectat jocul curent
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Alege tipul noului joc
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Alege un scenariu (verde), joc predefinit (albastru) sau o hartã aleatoare
+STR_4010_GENERATE_RANDOM_NEW_GAME :Genereazã o hartã aleatoare
+STR_4011_LOAD_HEIGHTMAP :{WHITE}Incarca harta inaltimilor
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} în cale
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :Minã de cãrbune
+STR_4803_POWER_STATION :Termocentralã
+STR_4804_SAWMILL :Exploatatie forestierã
+STR_4805_FOREST :Pãdure
+STR_4806_OIL_REFINERY :Rafinãrie
+STR_4807_OIL_RIG :Platformã petrolierã
+STR_4808_FACTORY :Fabricã de conserve
+STR_4809_PRINTING_WORKS :Tipografie
+STR_480A_STEEL_MILL :Otelãrie
+STR_480B_FARM :Fermã
+STR_480C_COPPER_ORE_MINE :Minã de cupru
+STR_480D_OIL_WELLS :Sonde
+STR_480E_BANK :Bancã
+STR_480F_FOOD_PROCESSING_PLANT :Combinat alimentar
+STR_4810_PAPER_MILL :Fabricã de hârtie
+STR_4811_GOLD_MINE :Minã de aur
+STR_4812_BANK :Bancã
+STR_4813_DIAMOND_MINE :Minã de diamante
+STR_4814_IRON_ORE_MINE :Minã de fier
+STR_4815_FRUIT_PLANTATION :Livadã
+STR_4816_RUBBER_PLANTATION :Plantatie de cauciuc
+STR_4817_WATER_SUPPLY :Rezervor
+STR_4818_WATER_TOWER :Turn de apã
+STR_4819_FACTORY :Fabricã de conserve
+STR_481A_FARM :Fermã
+STR_481B_LUMBER_MILL :Fabricã de cherestea
+STR_481C_COTTON_CANDY_FOREST :Pãdure de vatã de zahãr
+STR_481D_CANDY_FACTORY :Fabricã de bomboane
+STR_481E_BATTERY_FARM :Fermã de baterii
+STR_481F_COLA_WELLS :Fântâni de cola
+STR_4820_TOY_SHOP :Magazin de jucãrii
+STR_4821_TOY_FACTORY :Fabricã de jucãrii
+STR_4822_PLASTIC_FOUNTAINS :Fântâni de plastic
+STR_4823_FIZZY_DRINK_FACTORY :Fabricã de sucuri
+STR_4824_BUBBLE_GENERATOR :Generator de balonase
+STR_4825_TOFFEE_QUARRY :Carierã de caramel
+STR_4826_SUGAR_MINE :Minã de zahãr
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Are nevoie de: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Are nevoie de: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Are nevoie de: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Productia luna trecutã:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% transportat)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centreazã imaginea pe locatia industriei
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Un nou obiectiv industrial ({STRING}) se construieste lângã {TOWN}!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}O nouã {STRING} se planteazã lângã {TOWN}!
+STR_482F_COST :{BLACK}Cost: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Acest tip de industrie nu se poate construi aici...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...pãdurile pot fi plantate doar in zonele inzãpezite
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} anuntã inchiderea iminentã!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}Problemele de aprovizionare provoacã închiderea {INDUSTRY}!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}Lipsa de teren împãdurit provoacã închiderea {INDUSTRY}!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} mãreste productia!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}Rezerve noi de cãrbune la {INDUSTRY}!{}Se asteaptã dublarea productiei!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}Rezerve noi de petrol la {INDUSTRY}!{}Se asteaptã dublarea productiei!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}Noile tehnologii folosite la {INDUSTRY} vor aduce dublarea productiei!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}{INDUSTRY} scade productia cu 50%
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}Insectele cauzeazã distrugeri masive la {INDUSTRY}!{}Productia scade cu 50%
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...se poate construi doar la marginea hãrtii
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}Productia de {STRING} de la {INDUSTRY} creste cu {COMMA}%!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}Productia de {STRING} de la {INDUSTRY} scade cu {COMMA}%!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Tren în tunel
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Autovehicul în tunnel
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Intersectare cu alt tunel
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Terenul de la celãlalt capãt al tunelului este imposibil de excavat
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Mai intâi trebuie demolat tunelul
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Mai intâi trebuie demolat podul
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Cele douã capete nu se pot situa în acelasi loc
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Sub pod trebuie sã existe teren nivelat
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}Cele douã capete trebuie sã se situeze în linie
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Loc nepotrivit pentru intrarea într-un tunel
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Suspensie (otel)
+STR_500F_GIRDER_STEEL :Grindã (otel)
+STR_5010_CANTILEVER_STEEL :Arc (otel)
+STR_5011_SUSPENSION_CONCRETE :Suspensie (beton)
+STR_5012_WOODEN :Lemn
+STR_5013_CONCRETE :Beton
+STR_5014_TUBULAR_STEEL :Tubular (otel)
+STR_BRIDGE_TUBULAR_SILICON :Tubular (silicon)
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Nu pot construi pod aici...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Nu pot construi tunel aici...
+STR_5017_RAILROAD_TUNNEL :Tunel feroviar
+STR_5018_ROAD_TUNNEL :Tunel rutier
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Pod feroviar suspendat din otel
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Pod feroviar tip grindã din otel
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Pod feroviar tip arc din otel
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Pod feroviar suspendat din beton
+STR_501F_WOODEN_RAIL_BRIDGE :Pod feroviar din lemn
+STR_5020_CONCRETE_RAIL_BRIDGE :Pod feroviar din beton
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Pod rutier suspendat din otel
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Pod rutier tip grindã din otel
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Pod rutier tip arc din otel
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Pod rutier suspendat din beton
+STR_5025_WOODEN_ROAD_BRIDGE :Pod rutier din lemn
+STR_5026_CONCRETE_ROAD_BRIDGE :Pod rutier din beton
+STR_5027_TUBULAR_RAIL_BRIDGE :Pod feroviar tubular
+STR_5028_TUBULAR_ROAD_BRIDGE :Pod rutier tubular
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Obiect in cale
+STR_5801_TRANSMITTER :Transmitãtor
+STR_5802_LIGHTHOUSE :Far
+STR_5803_COMPANY_HEADQUARTERS :Sediu companie
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...sediu de companie in cale
+STR_5805_COMPANY_OWNED_LAND :Teren in posesia unei companii
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Nu poti cumpãra teren aici...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...este deja in posesia ta!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :NoName
+STR_SV_TRAIN_NAME :Trenul {COMMA}
+STR_SV_ROADVEH_NAME :Autovehiculul {COMMA}
+STR_SV_SHIP_NAME :Nava {COMMA}
+STR_SV_AIRCRAFT_NAME :Aeronava {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :{STRING} Nord
+STR_SV_STNAME_SOUTH :{STRING} Sud
+STR_SV_STNAME_EAST :{STRING} Est
+STR_SV_STNAME_WEST :{STRING} Vest
+STR_SV_STNAME_CENTRAL :{STRING} Centru
+STR_SV_STNAME_TRANSFER :{STRING} Transfer
+STR_SV_STNAME_HALT :Popasul {STRING}
+STR_SV_STNAME_VALLEY :Valea {STRING}
+STR_SV_STNAME_HEIGHTS :Dealurile {STRING}
+STR_SV_STNAME_WOODS :Pãdurea {STRING}
+STR_SV_STNAME_LAKESIDE :Lacul {STRING}
+STR_SV_STNAME_EXCHANGE :Piata {STRING}
+STR_SV_STNAME_AIRPORT :Aeroportul {STRING}
+STR_SV_STNAME_OILFIELD :Platforma {STRING}
+STR_SV_STNAME_MINES :Minele {STRING}
+STR_SV_STNAME_DOCKS :Portul {STRING}
+STR_SV_STNAME_BUOY_1 :{STRING} Balizã 1
+STR_SV_STNAME_BUOY_2 :{STRING} Balizã 2
+STR_SV_STNAME_BUOY_3 :{STRING} Balizã 3
+STR_SV_STNAME_BUOY_4 :{STRING} Balizã 4
+STR_SV_STNAME_BUOY_5 :{STRING} Balizã 5
+STR_SV_STNAME_BUOY_6 :{STRING} Balizã 6
+STR_SV_STNAME_BUOY_7 :{STRING} Balizã 7
+STR_SV_STNAME_BUOY_8 :{STRING} Balizã 8
+STR_SV_STNAME_BUOY_9 :{STRING} Balizã 9
+STR_SV_STNAME_ANNEXE :Anexa {STRING}
+STR_SV_STNAME_SIDINGS :{STRING} Belvedere
+STR_SV_STNAME_BRANCH :Ramura {STRING}
+STR_SV_STNAME_UPPER :{STRING} de Sus
+STR_SV_STNAME_LOWER :{STRING} de Jos
+STR_SV_STNAME_HELIPORT :Heliportul {STRING}
+STR_SV_STNAME_FOREST :Pãdurea {STRING}
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Nivel de dificultate
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Salveazã
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Usor
+STR_6802_MEDIUM :{BLACK}Mediu
+STR_6803_HARD :{BLACK}Greu
+STR_6804_CUSTOM :{BLACK}Propriu
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}Numãrul maxim de companii concurente: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Când intrã concurentii pe piatã: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}Numãrul de orase de pe hartã: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}Numãrul de obiective industriale: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Valoarea maximã a împrumutului initial: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Rata initialã a dobânzii: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Costul de exploatare al vehiculelor: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Viteza de constructie a concurentilor: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Gradul de inteligentã al concurentilor: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Defectiunile vehiculelor: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Multiplicarea veniturilor subventionate: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Costul constructiilor: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Tipul de teren: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Volumul de apã pe hartã: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Economie: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Trenurile întorc: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Dezastre: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Reactia autoritãtilor la modificãrea mediului: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :zero
+STR_6816_LOW :scãzut
+STR_6817_NORMAL :normal
+STR_6818_HIGH :ridicat
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :foarte incet
+STR_681C_SLOW :Incet
+STR_681D_MEDIUM :mediu
+STR_681E_FAST :repede
+STR_681F_VERY_FAST :foarte repede
+STR_VERY_LOW :foarte scãzut
+STR_6820_LOW :scãzut
+STR_6821_MEDIUM :mediu
+STR_6822_HIGH :ridicat
+STR_6823_NONE :deloc
+STR_6824_REDUCED :rare
+STR_6825_NORMAL :frecventã normalã
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :foarte plat
+STR_682B_FLAT :plat
+STR_682C_HILLY :deluros
+STR_682D_MOUNTAINOUS :muntos
+STR_682E_STEADY :stabilã
+STR_682F_FLUCTUATING :fluctuantã
+STR_6830_IMMEDIATE :imediat
+STR_6831_3_MONTHS_AFTER_PLAYER :la 3 luni dupã jucãtor
+STR_6832_6_MONTHS_AFTER_PLAYER :la 6 luni dupã jucãtor
+STR_6833_9_MONTHS_AFTER_PLAYER :la 9 luni dupã jucãtor
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :la capãt de linie si în garã
+STR_6835_AT_END_OF_LINE_ONLY :doar la capãt de linie
+STR_6836_OFF :inactiv
+STR_6837_ON :activ
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Afiseazã clasamentul celor mai bune punctaje
+STR_6839_PERMISSIVE :permisivã
+STR_683A_TOLERANT :tolerantã
+STR_683B_HOSTILE :ostilã
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Jucãtorul {COMMA})
+STR_7004_NEW_FACE :{BLACK}Schimbã foto
+STR_7005_COLOR_SCHEME :{BLACK}Culoare
+STR_7006_COLOR_SCHEME :{GOLD}Culoare:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Alege noua culoare
+STR_7008_COMPANY_NAME :{BLACK}Nume companie
+STR_7009_PRESIDENT_NAME :{BLACK}Presedinte
+STR_700A_COMPANY_NAME :Noul nume al companiei
+STR_700B_PRESIDENT_S_NAME :Numele noului presedinte
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Nu pot schimba numele companiei...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Nu pot schimba numele presedintelui...
+STR_700E_FINANCES :{WHITE}Situatia financiarã a companiei {COMPANY} {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Cheltuieli/Venituri
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Constructii
+STR_7012_NEW_VEHICLES :{GOLD}Vehicule noi
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Costuri trenuri
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Costuri autovehicule
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Costuri aeronave
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Costuri nave
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Întretinere proprietãti
+STR_7018_TRAIN_INCOME :{GOLD}Venituri trenuri
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Venituri autovehicule
+STR_701A_AIRCRAFT_INCOME :{GOLD}Venituri aeronave
+STR_701B_SHIP_INCOME :{GOLD}Venituri nave
+STR_701C_LOAN_INTEREST :{GOLD}Dobânda la credit
+STR_701D_OTHER :{GOLD}Altele
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Total:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Graficul veniturilor
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Graficul profitului din operare
+STR_7026_BANK_BALANCE :{WHITE}Balantã curentã
+STR_7027_LOAN :{WHITE}Credite
+STR_MAX_LOAN :{WHITE}Limita credite: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}Împrumutã {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Plãteste înapoi {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...creditul maxim permis este de {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Nu mai poti imprumuta bani...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...nu ai nici un credit de plãtit
+STR_702E_REQUIRED :{WHITE}...ai nevoie de {CURRENCY}
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Nu poti plãti creditul...
+STR_INSUFFICIENT_FUNDS :{WHITE}Nu poti dona din banii împrumutati de bancã...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Alege o nouã fotografie a presedintelui
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Schimbã culoarea care îti reprezintã compania
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Schimbã numele presedintelui
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Schimbã numele companiei
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Clic pe culoarea selectatã
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Împrumutã o nouã sumã de bani
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Plãteste inapoi o parte din credite
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(Presedinte)
+STR_7038_INAUGURATED :{GOLD}Anul înfiintãrii: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Vehicule:
+STR_TRAINS :{WHITE}{COMMA} tren{P "" uri}
+STR_ROAD_VEHICLES :{WHITE}{COMMA} autovehicul{P "" e}
+STR_AIRCRAFT :{WHITE}{COMMA} aeronav{P ã e}
+STR_SHIPS :{WHITE}{COMMA} nav{P ã e}
+STR_7042_NONE :{WHITE}Nici unul
+STR_7043_FACE_SELECTION :{WHITE}Alegerea fotografiei
+STR_7044_MALE :{BLACK}Bãrbat
+STR_7045_FEMALE :{BLACK}Femeie
+STR_7046_NEW_FACE :{BLACK}Foto nouã
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Anuleazã alegerea unei noi fotografii
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Acceptã fotografia selectatã
+STR_7049_SELECT_MALE_FACES :{BLACK}Alege figurã masculinã
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Alege figurã femininã
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Genereazã foto aleatoare
+STR_704C_KEY :{BLACK}Legenda
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Afiseazã legenda graficelor
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Legenda graficelor
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Clic aici pentru a comuta afisarea informatiilor despre companie
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Unitãti de marfã livratã
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Ratingul performantelor companiilor (rating maxim=1000)
+STR_7052_COMPANY_VALUES :{WHITE}Valorile companiilor
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Clasamentul companiilor
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}Companie de transport cu probleme!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} va fi vândutã dacã situatia nu se va îmbunãtãti curând!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(Presedinte)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Fuziune între companiile de transport!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} a fost vândutã companiei {COMPANY} la pretul de {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Cãutãm o companie de transport care sã preia societatea noastrã {}{}Doriti sã cumpãrati {COMPANY} la pretul de {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Faliment!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}Compania {COMPANY} a fost închisã si toate activele au fost valorificate de creditori!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}A apãrut o nouã companie!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} si-a stabilit sediul lângã {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Nu pot cumpãra compania...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Preturile transportului de cãlãtori si mãrfuri
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Zile în tranzit
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Plata pentru livrarea a 10 unitãti (sau 10,000 de litri) de marfã pe o distantã de 20 de pãtrãtele
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Comutator pentru afisarea graficului pentru marfã
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Inginer
+STR_7067_TRAFFIC_MANAGER :Manager de trafic
+STR_7068_TRANSPORT_COORDINATOR :Coordonator transporturi
+STR_7069_ROUTE_SUPERVISOR :Supervizor
+STR_706A_DIRECTOR :Director
+STR_706B_CHIEF_EXECUTIVE :Director executiv
+STR_706C_CHAIRMAN :Director general
+STR_706D_PRESIDENT :Presedinte
+STR_706E_TYCOON :Magnat
+STR_706F_BUILD_HQ :{BLACK}Constr. sediu
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Construieste/aratã sediul companiei
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Muta sediul companiei (costa 1% din valoarea companiei)
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Nu pot construi sediul...
+STR_7072_VIEW_HQ :{BLACK}Vezi sediul
+STR_RELOCATE_HQ :{BLACK}Muta sediu
+STR_COMPANY_PASSWORD :{BLACK}Parola
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Protejeaza-ti compania cu o parola pentru a preveni accesul neautorizat.
+STR_SET_COMPANY_PASSWORD :Alege parola companiei
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}Recesiune mondialã!{}{}Expertii financiari se tem de ceea ce e mai rãu odatã cu prãbusirea economicã!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Recesiunea s-a încheiat!{}{}Cresterea comertului dã încredere industriei, iar economia se redreseazã!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Comutator pentru mãrimea ferestrei
+STR_7076_COMPANY_VALUE :{GOLD}Valoarea companiei: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Cumpãrã 25% din companie
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Vinde 25% din companie
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Cumpãrã 25% din actiunile aceste companii
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Vinde 25% din actiunile aceste companii
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Nu pot cumpãra 25% din aceastã companie...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}Nu pot vinde 25% din aceastã companie...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% detinute de {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% detinute de {COMPANY}{} {COMMA}% detinute de {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} a fost preluatã de {COMPANY}!
+STR_7080_PROTECTED :{WHITE}Aceasta companie inca nu vinde actiuni...
+
+STR_LIVERY_DEFAULT :Uniforma standard
+STR_LIVERY_STEAM :Motor cu abur
+STR_LIVERY_DIESEL :Motor diesel
+STR_LIVERY_ELECTRIC :Motor electric
+STR_LIVERY_MONORAIL :Motor monosina
+STR_LIVERY_MAGLEV :Motor Maglev
+STR_LIVERY_DMU :DMU
+STR_LIVERY_EMU :EMU
+STR_LIVERY_PASSENGER_WAGON_STEAM :Trasura de pasageri (Aburi)
+STR_LIVERY_PASSENGER_WAGON_DIESEL :Trasura de pasageri (Diesel)
+STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Trasura de pasageri (Electrica)
+STR_LIVERY_FREIGHT_WAGON :Vagon de marfa
+STR_LIVERY_BUS :Autobus
+STR_LIVERY_TRUCK :Camion
+STR_LIVERY_PASSENGER_SHIP :Bac
+STR_LIVERY_FREIGHT_SHIP :Vas comercial
+STR_LIVERY_HELICOPTER :Elicopter
+STR_LIVERY_SMALL_PLANE :Aeroplan mic
+STR_LIVERY_LARGE_PLANE :Aeroplan mare
+
+STR_LIVERY_GENERAL_TIP :{BLACK}Afiseaza schemele generale de culori
+STR_LIVERY_TRAIN_TIP :{BLACK}Arata schemele de culori pentru trenuri
+STR_LIVERY_ROADVEH_TIP :{BLACK}Arata schemele de culori pentru autovehiculele rutiere
+STR_LIVERY_SHIP_TIP :{BLACK}Arata schemele de culori pentru vase
+STR_LIVERY_AIRCRAFT_TIP :{BLACK}Arata schemele de culori pentru avioane
+STR_LIVERY_PRIMARY_TIP :{BLACK}Alege culoarea primara pentru schema selectata
+STR_LIVERY_SECONDARY_TIP :{BLACK}Alege culoarea secundara pentru schema selectata
+STR_LIVERY_PANEL_TIP :{BLACK}Alege o schema de culori pentru modificare sau mai multe scheme, folosind CTRL+click. Apasa pe casuta pentru a comuta schema
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (Aburi)
+STR_8001_MJS_250_DIESEL :MJS 250 (Diesel)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut Diesel
+STR_8006_POWERNAUT_DIESEL :Powernaut Diesel
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (Aburi)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (Aburi)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (Aburi)
+STR_800A_SH_8P_STEAM :SH '8P' (Aburi)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (Diesel)
+STR_800C_DASH_DIESEL :'Dash' (Diesel)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (Diesel)
+STR_800E_UU_37_DIESEL :UU '37' (Diesel)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (Diesel)
+STR_8010_CS_4000_DIESEL :CS 4000 (Diesel)
+STR_8011_CS_2400_DIESEL :CS 2400 (Diesel)
+STR_8012_CENTENNIAL_DIESEL :Centennial (Diesel)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (Diesel)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (Diesel)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (Diesel)
+STR_8016_SH_125_DIESEL :SH '125' (Diesel)
+STR_8017_SH_30_ELECTRIC :SH '30' (Electric)
+STR_8018_SH_40_ELECTRIC :SH '40' (Electric)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (Electric)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (Electric)
+STR_801B_PASSENGER_CAR :Vagon pentru cãlãtori
+STR_801C_MAIL_VAN :Vagon pentru postã
+STR_801D_COAL_CAR :Vagon pentru cãrbuni
+STR_801E_OIL_TANKER :Cisternã pentru petrol
+STR_801F_LIVESTOCK_VAN :Vagon pentru animale
+STR_8020_GOODS_VAN :Vagon pentru bunuri
+STR_8021_GRAIN_HOPPER :Vagon pentru cereale
+STR_8022_WOOD_TRUCK :Vagon pentru lemne
+STR_8023_IRON_ORE_HOPPER :Vagon pentru minereu de fier
+STR_8024_STEEL_TRUCK :Vagon pentru otel
+STR_8025_ARMORED_VAN :Vagon blindat
+STR_8026_FOOD_VAN :Vagon pentru alimente
+STR_8027_PAPER_TRUCK :Vagon pentru hârtie
+STR_8028_COPPER_ORE_HOPPER :Vagon pentru minereu de cupru
+STR_8029_WATER_TANKER :Cisternã pentru apã
+STR_802A_FRUIT_TRUCK :Vagon penru fructe
+STR_802B_RUBBER_TRUCK :Vagon pentru cauciuc
+STR_802C_SUGAR_TRUCK :Vagon pentru zahãr
+STR_802D_COTTON_CANDY_HOPPER :Vagon pentru vatã de zahãr
+STR_802E_TOFFEE_HOPPER :Vagon pentru caramel
+STR_802F_BUBBLE_VAN :Vagon pentru balonase
+STR_8030_COLA_TANKER :Cisternã pentru cola
+STR_8031_CANDY_VAN :Vagon pentru bomboane
+STR_8032_TOY_VAN :Vagon pentru jucãrii
+STR_8033_BATTERY_TRUCK :Vagon pentru baterii
+STR_8034_FIZZY_DRINK_TRUCK :Vagon pentru sucuri
+STR_8035_PLASTIC_TRUCK :Vagon pentru plastic
+STR_8036_X2001_ELECTRIC :'X2001' (Electric)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Electric)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :Vagon pentru cãlãtori
+STR_803A_MAIL_VAN :Vagon pentru postã
+STR_803B_COAL_CAR :Vagon pentru cãrbuni
+STR_803C_OIL_TANKER :Cisternã pentru petrol
+STR_803D_LIVESTOCK_VAN :Vagon pentru animale
+STR_803E_GOODS_VAN :Vagon pentru bunuri
+STR_803F_GRAIN_HOPPER :Vagon pentru cereale
+STR_8040_WOOD_TRUCK :Vagon pentru lemne
+STR_8041_IRON_ORE_HOPPER :Vagon pentru minereu de fier
+STR_8042_STEEL_TRUCK :Vagon pentru otel
+STR_8043_ARMORED_VAN :Vagon blindat
+STR_8044_FOOD_VAN :Vagon pentru alimente
+STR_8045_PAPER_TRUCK :Vagon pentru hârtie
+STR_8046_COPPER_ORE_HOPPER :Vagon pentru minereu de cupru
+STR_8047_WATER_TANKER :Cisternã pentru apã
+STR_8048_FRUIT_TRUCK :Vagon pentru fructe
+STR_8049_RUBBER_TRUCK :Vagon pentru cauciuc
+STR_804A_SUGAR_TRUCK :Vagon pentru zahãr
+STR_804B_COTTON_CANDY_HOPPER :Vagon pentru vatã de zahãr
+STR_804C_TOFFEE_HOPPER :Vagon pentru caramel
+STR_804D_BUBBLE_VAN :Vagon pentru balonase
+STR_804E_COLA_TANKER :Cisternã pentru cola
+STR_804F_CANDY_VAN :Vagon pentru bomboane
+STR_8050_TOY_VAN :Vagon pentru jucãrii
+STR_8051_BATTERY_TRUCK :Vagon pentru baterii
+STR_8052_FIZZY_DRINK_TRUCK :Vagon pentru sucuri
+STR_8053_PLASTIC_TRUCK :Vagon pentru plastic
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (Electric)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (Electric)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (Electric)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (Electric)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :Vagon pentru cãlãtori
+STR_805A_MAIL_VAN :Vagon pentru postã
+STR_805B_COAL_CAR :Vagon pentru cãrbuni
+STR_805C_OIL_TANKER :Cisternã pentru petrol
+STR_805D_LIVESTOCK_VAN :Vagon pentru animale
+STR_805E_GOODS_VAN :Vagon pentru bunuri
+STR_805F_GRAIN_HOPPER :Vagon pentru cereale
+STR_8060_WOOD_TRUCK :Vagon pentru lemne
+STR_8061_IRON_ORE_HOPPER :Vagon pentru minereu de fier
+STR_8062_STEEL_TRUCK :Vagon pentru otel
+STR_8063_ARMORED_VAN :Vagon blindat
+STR_8064_FOOD_VAN :Vagon pentru alimente
+STR_8065_PAPER_TRUCK :Vagon pentru hârtie
+STR_8066_COPPER_ORE_HOPPER :Vagon pentru minereu de cupru
+STR_8067_WATER_TANKER :Cisternã pentru apã
+STR_8068_FRUIT_TRUCK :Vagon pentru fructe
+STR_8069_RUBBER_TRUCK :Vagon pentru cauciuc
+STR_806A_SUGAR_TRUCK :Vagon pentru zahãr
+STR_806B_COTTON_CANDY_HOPPER :Vagon pentru vatã de zahãr
+STR_806C_TOFFEE_HOPPER :Vagon pentru caramel
+STR_806D_BUBBLE_VAN :Vagon pentru balonase
+STR_806E_COLA_TANKER :Cisternã pentru cola
+STR_806F_CANDY_VAN :Vagon pentru bomboane
+STR_8070_TOY_VAN :Vagon pentru jucãrii
+STR_8071_BATTERY_TRUCK :Vagon pentru baterii
+STR_8072_FIZZY_DRINK_TRUCK :Vagon pentru sucuri
+STR_8073_PLASTIC_TRUCK :Vagon pentru plastic
+STR_8074_MPS_REGAL_BUS :Autobuz MPS Regal
+STR_8075_HEREFORD_LEOPARD_BUS :Autobuz Hereford Leopard
+STR_8076_FOSTER_BUS :Autobuz Foster
+STR_8077_FOSTER_MKII_SUPERBUS :Autobuz Foster MkII Superbus
+STR_8078_PLODDYPHUT_MKI_BUS :Autobuz Ploddyphut MkI
+STR_8079_PLODDYPHUT_MKII_BUS :Autobuz Ploddyphut MkII
+STR_807A_PLODDYPHUT_MKIII_BUS :Autobuz Ploddyphut MkIII
+STR_807B_BALOGH_COAL_TRUCK :Camion pentru cãrbuni Balogh
+STR_807C_UHL_COAL_TRUCK :Camion pentru cãrbuni Uhl
+STR_807D_DW_COAL_TRUCK :Camion pentru cãrbuni DW
+STR_807E_MPS_MAIL_TRUCK :Camion postal MPS
+STR_807F_REYNARD_MAIL_TRUCK :Camion postal Reynard
+STR_8080_PERRY_MAIL_TRUCK :Camion postal Perry
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :Camion postal MightyMover
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Camion postal Powernaught
+STR_8083_WIZZOWOW_MAIL_TRUCK :Camion postal Wizzowow
+STR_8084_WITCOMBE_OIL_TANKER :Cisternã pentru petrol Witcombe
+STR_8085_FOSTER_OIL_TANKER :Cisternã pentru petrol Foster
+STR_8086_PERRY_OIL_TANKER :Cisternã pentru petrol Perry
+STR_8087_TALBOTT_LIVESTOCK_VAN :Camion pentru animale Talbott
+STR_8088_UHL_LIVESTOCK_VAN :Camion pentru animale Uhl
+STR_8089_FOSTER_LIVESTOCK_VAN :Camion pentru animale Foster
+STR_808A_BALOGH_GOODS_TRUCK :Camion pentru bunuri Balogh
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Camion pentru bunuri Craighead
+STR_808C_GOSS_GOODS_TRUCK :Camion pentru bunuri Goss
+STR_808D_HEREFORD_GRAIN_TRUCK :Camion pentru cereale Hereford
+STR_808E_THOMAS_GRAIN_TRUCK :Camion pentru cereale Thomas
+STR_808F_GOSS_GRAIN_TRUCK :Camion pentru cereale Goss
+STR_8090_WITCOMBE_WOOD_TRUCK :Camion pentru lemne Witcombe
+STR_8091_FOSTER_WOOD_TRUCK :Camion pentru lemne Foster
+STR_8092_MORELAND_WOOD_TRUCK :Camion pentru lemne Moreland
+STR_8093_MPS_IRON_ORE_TRUCK :Camion pentru fier MPS
+STR_8094_UHL_IRON_ORE_TRUCK :Camion pentru fier Uhl
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Camion pentru fier Chippy
+STR_8096_BALOGH_STEEL_TRUCK :Camion pentru otel Balogh
+STR_8097_UHL_STEEL_TRUCK :Camion pentru otel Uhl
+STR_8098_KELLING_STEEL_TRUCK :Camion pentru otel Kelling
+STR_8099_BALOGH_ARMORED_TRUCK :Camion blindat Balogh
+STR_809A_UHL_ARMORED_TRUCK :Camion blindat Uhl
+STR_809B_FOSTER_ARMORED_TRUCK :Camion blindat Foster
+STR_809C_FOSTER_FOOD_VAN :Camion pentru alimente Foster
+STR_809D_PERRY_FOOD_VAN :Camion pentru alimente Perry
+STR_809E_CHIPPY_FOOD_VAN :Camion pentru alimente Chippy
+STR_809F_UHL_PAPER_TRUCK :Camion pentru hârtie Uhl
+STR_80A0_BALOGH_PAPER_TRUCK :Camion pentru hârtie Balogh
+STR_80A1_MPS_PAPER_TRUCK :Camion pentru hârtie MPS
+STR_80A2_MPS_COPPER_ORE_TRUCK :Camion pentru cupru MPS
+STR_80A3_UHL_COPPER_ORE_TRUCK :Camion pentru cupru Uhl
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Camion pentru cupru Goss
+STR_80A5_UHL_WATER_TANKER :Cisternã pentru apã Uhl
+STR_80A6_BALOGH_WATER_TANKER :Cisternã pentru apã Balogh
+STR_80A7_MPS_WATER_TANKER :Cisternã pentru apã MPS
+STR_80A8_BALOGH_FRUIT_TRUCK :Camion pentru fructe Balogh
+STR_80A9_UHL_FRUIT_TRUCK :Camion pentru fructe Uhl
+STR_80AA_KELLING_FRUIT_TRUCK :Camion pentru fructe Kelling
+STR_80AB_BALOGH_RUBBER_TRUCK :Camion pentru cauciuc Balogh
+STR_80AC_UHL_RUBBER_TRUCK :Camion pentru cauciuc Uhl
+STR_80AD_RMT_RUBBER_TRUCK :Camion pentru cauciuc RMT
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :Camion pt. zahãr MightyMover
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Camion pt. zahãr Powernaught
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Camion pentru zahãr Wizzowow
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :Cola Camion MightyMover
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Cola Camion Powernaught
+STR_80B3_WIZZOWOW_COLA_TRUCK :Cola Camion Wizzowow
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :Camion pt. vatã zahãr MightyMover
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Camion pt. vatã zahãr Powernaught
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Camion pt. vatã zahãr Wizzowow
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :Camion pt. caramel MightyMover
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Camion pt. caramel Powernaught
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Camion pentru caramel Wizzowow
+STR_80BA_MIGHTYMOVER_TOY_VAN :Camion pt. jucãrii MightyMover
+STR_80BB_POWERNAUGHT_TOY_VAN :Camion pt. jucãrii Powernaught
+STR_80BC_WIZZOWOW_TOY_VAN :Camion pentru jucãrii Wizzowow
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :Camion pt. bomboane MightyMover
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Camion pt. bomboane Powernaught
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Camion pentru bomboane Wizzowow
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :Camion pt. baterii MightyMover
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Camion pt. baterii Powernaught
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Camion pentru baterii Wizzowow
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :Camion pt. sucuri MightyMover
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Camion pt. sucuri Powernaught
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Camion pentru sucuri Wizzowow
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :Camion pt. plastic MightyMover
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Camion pt. plastic Powernaught
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Camion pentru plastic Wizzowow
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :Camion pt. balonase MightyMover
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Camion pt. balonase Powernaught
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Camion pentru balonase Wizzowow
+STR_80CC_MPS_OIL_TANKER :Tanc petrolier MPS
+STR_80CD_CS_INC_OIL_TANKER :Tanc petrolier CS-Inc.
+STR_80CE_MPS_PASSENGER_FERRY :Vas de pasageri MPS
+STR_80CF_FFP_PASSENGER_FERRY :Vas de pasageri FFP
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Vas de pasageri Bakewell 300
+STR_80D1_CHUGGER_CHUG_PASSENGER :Vas de pasageri Chugger-Chug
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Vas de pasageri Shivershake
+STR_80D3_YATE_CARGO_SHIP :Navã de marfã Yate Cargo
+STR_80D4_BAKEWELL_CARGO_SHIP :Navã de marfã Bakewell
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Navã de marfã Mightymover
+STR_80D6_POWERNAUT_CARGO_SHIP :Navã de marfã Powernaut
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Elicopter Tricario
+STR_80FE_GURU_X2_HELICOPTER :Elicopter Guru X2
+STR_80FF_POWERNAUT_HELICOPTER :Elicopter Powernaut
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Mesaj de la producãtorul de vehicule
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}Am creat un nou tip de {STRING}. Ati fi interesati de folosirea exclusivã pentru un an a acestui vehicul, astfel ca noi sa putem observa rezultatele înaintea lansãrii oficiale?
+STR_8102_RAILROAD_LOCOMOTIVE :vehicul feroviar
+STR_8103_ROAD_VEHICLE :autovehicul
+STR_8104_AIRCRAFT :aeronavã
+STR_8105_SHIP :navã
+STR_8106_MONORAIL_LOCOMOTIVE :vehicul monorail
+STR_8107_MAGLEV_LOCOMOTIVE :vehicul maglev
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}Depoul {TOWN}
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Cetãtenii sãrbãtoresc {}sosirea primului tren la {STATION}!
+STR_8802_DETAILS :{WHITE}{STRING} (Detalii)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Tren în drum
+STR_8804 :{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8806_GO_TO :Mergi la {STATION}
+STR_8807_GO_TO_TRANSFER :Mergi la {STATION} (Transferã si preia încãrcãtura)
+STR_8808_GO_TO_UNLOAD :Mergi la {STATION} (Descarcã)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Mergi la {STATION} (Transferã si lasã descãrcat)
+STR_880A_GO_TO_LOAD :Mergi la {STATION} (Încarcã)
+STR_880B_GO_TO_TRANSFER_LOAD :Mergi la {STATION} (Transferã si încarcã 100%)
+STR_880C_GO_NON_STOP_TO :Mergi non-stop la {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Mergi non-stop la {STATION} (Transferã si ia încãrcãtura)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Mergi non-stop la {STATION} (Descarcã)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Mergi non-stop la {STATION} (Transferã si lasã descãrcat)
+STR_8810_GO_NON_STOP_TO_LOAD :Mergi non-stop la {STATION} (Încarcã)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Mergi non-stop la {STATION} (Transferã si încarcã 100%)
+STR_GO_TO_TRAIN_DEPOT :Mergi la depoul {TOWN}
+STR_SERVICE_AT_TRAIN_DEPOT :Service la Depoul {TOWN}
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Mergi non-stop la Depoul {TOWN}
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Non-stop pt. service la Depoul {TOWN}
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}Merge la Depoul {TOWN}
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}Merge la Depoul {TOWN}, {VELOCITY}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE :{LTBLUE}Service la Depoul {TOWN}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE_VEL :{LTBLUE}Service la Depoul {TOWN}, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (Comenzi eronate)
+
+STR_UNKNOWN_DESTINATION :destinatie necunoscutã
+STR_8812_EMPTY :{LTBLUE}Gol
+STR_8813_FROM :{LTBLUE}{CARGO} de la {STATION}
+STR_FROM_MULT :{LTBLUE}{CARGO} de la {STATION} (x{NUM})
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}Trenul {COMMA} asteaptã în depou
+STR_8815_NEW_VEHICLES :{BLACK}Vehicule noi
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Tren prea lung
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Trenurile pot fi modificate doar când se aflã într-un depou
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} Trenuri
+
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Noi vehicule feroviare
+STR_NEW_ELRAIL_VEHICLES :{WHITE}Noi Vehicule Electrice pe Sine
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Noi vehicule monorail
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Noi vehicule maglev
+STR_ALL_AVAIL_RAIL_VEHICLES :{WHITE}Vehicule pe sine
+
+STR_881F_BUILD_VEHICLE :{BLACK}Cumpãrã vehicul
+STR_CLONE_ROAD_VEHICLE :{BLACK}Cloneazã vehiculul
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}Acest buton va crea o copie a autovehiculului. Control+click pentru comenzi comune
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Acest buton va crea o copie a autovehiculului. Apasã acest buton, apoi fã click pe un autovehicul de pe hartã. Control+click pentru a-i da ordine comune
+STR_CLONE_TRAIN :{BLACK}Cloneazã trenul
+STR_CLONE_TRAIN_INFO :{BLACK}Acest buton va crea o copie a întregului tren. Control+click pentru comenzi comune
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}Acest buton va crea o copie a întregului tren. Apasã acest buton, apoi fã click pe un tren de pe hartã. Control+click pentru a-i da ordine comune
+STR_8820_RENAME :{BLACK}Redenumeste
+STR_8823_SKIP :{BLACK}Sãri peste
+STR_8824_DELETE :{BLACK}Sterge
+STR_8825_NON_STOP :{BLACK}Non-stop
+STR_8826_GO_TO :{BLACK}Mergi la
+STR_8827_FULL_LOAD :{BLACK}Full-load
+STR_8828_UNLOAD :{BLACK}Descãrcare
+STR_REFIT :{BLACK}Rearanjeaza
+STR_REFIT_TIP :{BLACK}Alege tipul de marfa pentru rearanjare. Control+click pt a anula rearanjarea
+STR_REFIT_ORDER :(Rearanjeaza in {STRING})
+STR_8829_ORDERS :{WHITE}{VEHICLE} (Comenzi)
+STR_882A_END_OF_ORDERS :{SETX 10}- - Sfârsitul comenzilor - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}Service
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Nu pot construi vehiculul...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Cumpãrat: {LTBLUE}{NUM}{BLACK} Valoare: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Valoare: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}Încarcã / Descarcã
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}Trenul trebuie oprit intr-un depou
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Nu pot trimite trenul la depou...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Nu mai este loc pentru comenzi
+STR_8832_TOO_MANY_ORDERS :{WHITE}Prea multe comenzi
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Nu pot adãuga o comandã nouã...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Nu pot sterge aceastã comandã...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Nu pot modifica aceastã comandã...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Nu pot muta vehiculul...
+STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}Al doilea vagon+motor va avea mereu aceeasi destinatie ca si primul
+STR_8838_N_A :N/A{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Nu pot vinde vehiculul...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Nu pot gãsi un drum spre un depou local
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Nu pot opri-porni trenul...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Intervalul pt. service: {LTBLUE}{COMMA}zile{BLACK} Ultimul service: {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Intervalul de service: {LTBLUE}{COMMA}%{BLACK} Ultimul service: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Trenuri - apasã aici pentru informatii despre trenuri
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Cumpãrã trenuri noi (necesitã un depou)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Trenuri - clic pe tren pentru informatii, mutã vehiculele pentru adaugare scoatere din tren
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Construieste un nou vehicul feroviar
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Mutã un vehicul aici pentru a-l vinde
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centreazã imaginea pe locatia depoului
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Lista de selectie a componentelor trenului - clic pe vehicule pt. informatii
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Cumpãrã vehiculul selectat
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Redenumeste modelul vehiculului
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Comanda curentã a trenului - apasã aici pentru a porni/opri trenul
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Afiseazã comenzile trenului
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centreazã imaginea pe locatia curentã a trenului
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Trimite trenul într-un depou
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Forteazã trenul sã ignore semnalulizarea de oprire
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Schimbã sensul de circulatie al trenului
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Afiseazã detaliile trenului
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Mãreste intervalul de service
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Micsoreazã intervalul de service
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Afiseazã detalii despre încãrcãtura transportatã
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Afiseazã detalii despre componentele trenului
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Afiseazã capacitãtile componentelor trenului
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Afiseazã capacitãtile totale ale trenului, diferentiate pe tip de încãrcãturã
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Lista de comenzi - clic pe comandã pentru a o selecta
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}Sãri peste comanda curentã si treci la urmãtoarea
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Sterge comanda selectatã
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Mergi non-stop pânã la destinatia din comanda selectatã
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Introdu o comandã înaintea celei selectate sau adaugã o comandã la sfârsitul listei
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Forteazã trenul sã astepte la destinatia selectatã pânã la umplerea la capacitate maximã
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Forteazã trenul sã descarce marfa la destinatia selectatã
+STR_SERVICE_HINT :{BLACK}Sãri peste aceastã comandã dacã nu este necesar un service
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}Stiri: {STRING} este acum disponibil!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Cost: {CURRENCY} Greutate: {WEIGHT_S}{}Vitezã: {VELOCITY} Putere: {POWER}{}Cost de rulare: {CURRENCY}/an{}Capacitate: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}Defectiune
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}Vechimea: {LTBLUE}{STRING}{BLACK} Cost de rulare: {LTBLUE}{CURRENCY}/an
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Greutate: {LTBLUE}{WEIGHT_S} {BLACK}Putere: {LTBLUE}{POWER}{BLACK} Vitezã max.: {LTBLUE}{VELOCITY}
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Greutate: {LTBLUE}{WEIGHT_S} {BLACK}Putere: {LTBLUE}{POWER}{BLACK} Viteza max.: {LTBLUE}{VELOCITY} {BLACK}E.T. max.: {LTBLUE}{FORCE}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit anul acesta: {LTBLUE}{CURRENCY} (anul trecut: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}Eficientã: {LTBLUE}{COMMA}% {BLACK}Defectiuni de la ultimul service: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Oprit
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Nu pot permite trenului sã treacã în caz de pericol...
+STR_8863_CRASHED :{RED}Accident!
+
+STR_8865_NAME_TRAIN :{WHITE}Numele trenului
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}Nu pot redenumi trenul...
+STR_8867_NAME_TRAIN :{BLACK}Numele trenului
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Accident feroviar!{}{COMMA} victime în urma unei coliziuni
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Nu pot schimba sensul de mers al trenului...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Redenumeste modelul vehiculului feroviar
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Nu pot redenumi modelul acestui vehicul...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Comanda selectatã forteazã vehiculul sã arunce încãrcãtura
+STR_886F_TRANSFER :{BLACK}Transferã
+
+STR_TRAIN_STOPPING :{RED}Oprire
+STR_TRAIN_STOPPING_VEL :{RED}Oprire, {VELOCITY}
+STR_INCOMPATIBLE_RAIL_TYPES :Tipuri de sine incompatibile
+STR_TRAIN_NO_POWER :{RED}Fara curent
+STR_TRAIN_START_NO_CATENARY :Aceasta sina nu este electrificata, deci trenul nu poate porni
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Autovehicul in cale
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA}Autovehicule
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}Autobaza {TOWN}
+STR_9004_NEW_VEHICLES :{BLACK}Autovehicule noi
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}Autovehicule noi
+STR_9007_BUILD_VEHICLE :{BLACK}Cumpãrã vehicul
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Nu pot cumpãra autovehicul...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (Detalii)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}Vârsta: {LTBLUE}{STRING}{BLACK} Cost de rulare: {LTBLUE}{CURRENCY}/an
+STR_900E_MAX_SPEED :{BLACK}Vitezã max.: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit anul acesta: {LTBLUE}{CURRENCY} (anul trecut: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}Eficientã: {LTBLUE}{COMMA}% {BLACK}Defectiuni de la ultimul service: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Cumpãrat: {LTBLUE}{NUM}{BLACK} Valoare: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Capacitate: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}...trebuie oprit intr-o autobazã
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Nu pot vinde autovehiculul...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Nu pot opri/porni autovehiculul...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}Autovehiculul {COMMA} e parcat la autobazã
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}Merge la Autobaza {TOWN}
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}Merge la Autobaza {TOWN}, {VELOCITY}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE :{LTBLUE}Service la Autobaza {TOWN}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE_VEL :{LTBLUE}Service la Autobaza {TOWN}, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Nu pot trimite autovehiculul la autobazã...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Nu pot gãsi un drum spre o autobazã localã
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Autovehicule - clic pe vehicul pentru informatii
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Cumpãrã un nou autovehicul (ai nevoie de o autobazã)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Comanda curentã a autovehiculului - clic aici pentru a opri/porni autovehiculul
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Afiseazã comenzile autovehiculului
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Centreazã imaginea pe locatia curentã a autovehiculului
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Trimite autovehiculul la o autobazã
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Forteazã vehiculul sã întoarcã
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Afiseazã detaliile autovehiculului
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Autovehicule - clic pe vehicul pentru informatii
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Cumpãrã un autovehicul
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Mutã un autovehicul aici pentru a-l vinde
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Centreazã imaginea pe locatia acestei autobaze
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Road vehicle selection list - click on vehicle for information
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Cumpãrã autovehiculul selectat
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}Un nou autovehicul disponibil!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Pret: {CURRENCY}{}Vitezã: {VELOCITY}{}Cost de rulare: {CURRENCY}/an{}Capacitate: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Numele autovehiculului
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Nu pot redenumi autovehiculul...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Numele autovehiculului
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Cetãtenii sãrbãtoresc{}sosirea primului autobuz la {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Cetãtenii sãrbãtoresc{}sosirea primului camion la {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}Accident rutier!{}Soferul decedat in urma coliziunii cu un tren
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}Accident rutier!{}{COMMA} victime in urma coliziunii cu un tren
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Nu pot schimba întoarce autvehiculul...
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}Nu pot întoarce vehiculele alcãtuite din mai multe unitãti
+STR_9034_RENAME :{BLACK}Redenumeste
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Redenumeste modelul de autovehicul
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Redenumeste modelul autovehiculului
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Nu pot redenumi modelul acestui autovehicul...
+STR_9038_GO_TO_ROADVEH_DEPOT :Mergi la Autobaza {TOWN}
+STR_SERVICE_AT_ROADVEH_DEPOT :Service la Autobaza {TOWN}
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Adapteaza autovehiculul pentru o incarcatura diferita
+STR_REFIT_ROAD_VEHICLE :{BLACK}Adaptare autovehicul
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Adapteaza autovehiculul pentru transportul incarcaturii evidentiate
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Nu pot adapta autovehiculul...
+STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Alege tipul de marfa pentru transport cu autovehiculul
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Constructii navale
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Constructie port
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Nu pot construi port aici...
+STR_9803_SHIP_DEPOT :{WHITE}Santierul Naval {TOWN}
+STR_9804_NEW_SHIPS :{BLACK}Nave noi
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA}Nave
+STR_9808_NEW_SHIPS :{WHITE}Nave noi
+STR_9809_BUILD_SHIP :{BLACK}Construieste navã
+STR_CLONE_SHIP :{BLACK}Cloneaz? nava
+STR_CLONE_SHIP_INFO :{BLACK}Acest buton va crea o copie a navei. Control+click pentru comenzi comune
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}Acest buton va crea o copie a navei. Apasã acest buton, apoi fã click pe o nav? de pe hartã. Control+click pentru a-i da ordine comune
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}Nava trebuie sã fie stationatã într-un santier
+STR_980C_CAN_T_SELL_SHIP :{WHITE}Nu pot vinde nava...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Nu pot construi nava...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Navã în cale
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Detalii)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}Vârsta: {LTBLUE}{STRING}{BLACK} Cost de rulare: {LTBLUE}{CURRENCY}/an
+STR_9813_MAX_SPEED :{BLACK}Viteza max.: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit anul acesta: {LTBLUE}{CURRENCY} (anul trecut: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}Eficientã: {LTBLUE}{COMMA}% {BLACK}Defectiuni de la ultimul service: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Construit: {LTBLUE}{NUM}{BLACK} Valoare: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}Capacitate: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}Nu pot opri/porni nava...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Nu pot trimite nava în santier...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Nu pot gãsi un santier apropiat
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}Merge la Santierul {TOWN}
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}Merge la Santierul {TOWN}, {VELOCITY}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE :{LTBLUE}Service la Santierul Naval {TOWN}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE_VEL :{LTBLUE}Service la Santierul Naval {TOWN}, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}Nava {COMMA} este stationatã în santier
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Construieste port
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Constructie santier naval (pentru construirea si repararea navelor)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Nave - clic pe o navã pentru informatii
+STR_9820_BUILD_NEW_SHIP :{BLACK}Construieste o nouã navã
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Trage nava aici pentru a o vinde
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centreazã imaginea pe locatia santierului
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Nave - click pe navã pentru informatii
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Construieste nave noi (necesitã cel putin un santier naval)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}Lista de selectie a navelor - click pe o navã pentru informatii
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Construieste nava selectatã
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Comanda curentã a navei - clic aici pentru a porni/opri nava
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Afiseazã comenzile navei
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centreazã imaginea pe locatia curentã a navei
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Trimite nava într-un santier
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Afiseazã detaliile navei
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}O nouã navã este disponibilã!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Cost: {CURRENCY} Viteza max.: {VELOCITY}{}Capacitate: {CARGO}{}Cost de rulare: {CURRENCY}/an
+STR_982F_NAME_SHIP :{BLACK}Alege un nume pentru aceastã navã
+
+STR_9831_NAME_SHIP :{WHITE}Alege un nume pentru aceastã navã
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Nu pot redenumi nava...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Cetãtenii sãrbãtoresc{}Sosirea primei nave la {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Plaseazã o balizã ce poate fi utilizatã pentru directionare
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Nu pot plasa o balizã aici...
+STR_9836_RENAME :{BLACK}Redenumeste
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Redenumeste modelul navei
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Redenumeste modelul navei
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Nu pot schimba numele modelului acestei nave...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Schimbã tipul de marfã transportat
+STR_983B_REFIT :{WHITE}{VEHICLE} (Schimb marfã)
+STR_983C_REFIT_SHIP :{BLACK}Schimbã marfa transportatã
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Alege tipul de încãrcãturã ce va fi transportat de navã
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Schimbã tipul de încãrcãturã al acestei nave
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Alege tipul încãrcãturii:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Noua capacitate: {GOLD}{CARGO}{}{BLACK}Costul transformãrii: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Nu pot schimba tipul navei...
+STR_9842_REFITTABLE :(suportã alte mãrfuri)
+STR_GO_TO_SHIP_DEPOT :Mergi la Santierul Naval {TOWN}
+SERVICE_AT_SHIP_DEPOT :Service la Santierul Naval {TOWN}
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Airoporturi
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Nu pot construi un aeroport aici...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} Hangar
+STR_A003_NEW_AIRCRAFT :{BLACK}Aeronavã nouã
+STR_CLONE_AIRCRAFT :{BLACK}Clonare aeronavã
+STR_CLONE_AIRCRAFT_INFO :{BLACK}Acest buton va crea o copie a aeronavei. Control+click pentru comenzi comune
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Acest buton va crea o copie a aeronavei. Apasã acest buton, apoi fã click pe o aeronav? de pe hartã. Control+click pentru a-i da ordine comune
+STR_A005_NEW_AIRCRAFT :{WHITE}Aeronavã nouã
+STR_A006_BUILD_AIRCRAFT :{BLACK}Cumpãrã aeronavã
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Nu pot cumpãra aeronava...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} Aeronave
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (Comenzi)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (Detalii)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Vârstã: {LTBLUE}{STRING}{BLACK} Cost de rulare: {LTBLUE}{CURRENCY}/an
+STR_A00E_MAX_SPEED :{BLACK}Vitezã max.: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit anul acesta: {LTBLUE}{CURRENCY} (anul trecut: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}Eficientã: {LTBLUE}{COMMA}% {BLACK}Defectiuni de la ultimul service: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Cumpãrat în: {LTBLUE}{NUM}{BLACK} Valoare: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Nu pot trimite nava într+un hangar...
+STR_HEADING_FOR_HANGAR :{ORANGE}Merge la Hangarul {STATION}
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}Merge la Hangarul {STATION}, {VELOCITY}
+STR_HEADING_FOR_HANGAR_SERVICE :{LTBLUE}Service la Hangarul {STATION}
+STR_HEADING_FOR_HANGAR_SERVICE_VEL :{LTBLUE}Service la Hangarul {STATION}, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}Aeronava {COMMA} se aflã în hangar
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Aeronavã în cale
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Nu pot opri/porni aeronava...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Aeronavã se aflã în zbor
+STR_A019_CAPACITY :{BLACK}Capacitate: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Capacitate: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}Aeronava trebuie sã se afle într-un hangar
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Nu pot vinde aeronava...
+STR_A01D_AIRPORT_CONSTRUCTION :Constructie aeroport
+STR_A01E_BUILD_AIRPORT :{BLACK}Constr. aeroport
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Aeronavã - clic pe aeronavã pentru informatii
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Cumpãrã o nouã aeronavã (necesitã un aeroport)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Aeronavã - clic pe aeronavã pentru informatii
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Cumpãrã o aeronavã
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}Trage aeronava aici pentru a o vinde
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Centreazã imaginea pe locatia hangarului
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Lista de selectie a aeronavelor - clic pe o aeronavã pentru informatii
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Cumpãrã aeronava selectatã
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Comanda curentã a aeronavei - click aici pentru a porni/opri aeronava
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Afiseazã comenzile aeronavei
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Centreazã imaginea pe locatia curentã a aeronavei
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Trimite aeronava într-un hangar
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Afiseazã detaliile aeronavei
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}Un nou tip de aeronavã disponibil!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Pret: {CURRENCY} Viteza max.: {VELOCITY}{}Capacitate: {COMMA} cãlãtori, {COMMA} saci de postã{}Cost de rulare: {CURRENCY}/an
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Redenumeste aeronava
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Nu pot redenumi aeronava...
+STR_A032_NAME_AIRCRAFT :{BLACK}Redenumeste aeronava
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Cetãtenii sãrbãtoresc {}sosirea primei aeronave la {STATION}!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Accident aviatic!{}{COMMA} victime în urma prãbusirii de la {STATION}
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Accident aerian!{}Aeronava in pana de combustibil, {COMMA} victime in urma dezastrulu!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Redenumire
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Redenumeste modelul aeronavei
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Redenumeste modelul aeronavei
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Nu pot schimba numele aceste aeronave...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Schimbã tipul de încãrcãturã transportat
+STR_A03C_REFIT :{WHITE}{VEHICLE} (Schimbã încãrcãtura)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Schimbã tipul de încãrcãturã transportat
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Alege marfa care doresti sã fie transportatã
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Schimbã tipul de încãrcãturã al acestei aeronave
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Alege marfa de transportat:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Noua capacitate: {GOLD}{STRING}{}{BLACK}Costul transformãrii: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Nu pot schimba tipul de încãrcãturã...
+STR_GO_TO_AIRPORT_HANGAR :Mergi la Hangarul {STATION}
+SERVICE_AT_AIRPORT_HANGAR :Service la Hangarul {STATION}
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}Accident de zepelin la{STATION}!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Autovehicul distrus în urma coliziunii cu un OZN!
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}Explozie la o rafinãrie de lângã {TOWN}!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}Fabricã de conserve distrusã în conditii misterioase lângã {TOWN}!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}Un OZN a aterizat lângã {TOWN}!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}Prãbusirea unei mine de cupru lângã {TOWN} provoacã daune majore!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Inundatii!{}Se estimeaza cel putin {COMMA} victime!
+
+STR_BRIBE_FAILED :{WHITE}ÃŽncercarea ta de mituire
+STR_BRIBE_FAILED_2 :{WHITE}a fost descoperitã de un procuror local
+STR_BUILD_DATE :{BLACK}Data constructiei: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Ratingul de performantã detaliat
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}Detalii
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Vehicule:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Statii:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Profit minim:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Venit minim:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Venit maxim:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Livrãri:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Mãrfuri:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Cont curent:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Credite:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Total:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Numãrul de vehicule. Include autovehicule, trenuri, nave si aeronave.
+STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}Numãrul statiilor. Se numãrã fiecare componentã în cazul unor statii compuse din gãri, aeroporturi, porturi, statii de autobuz, etc.
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}Profitul vehiculului cu cel mai mic venit (dintre toate vehiculele mai vechi de 2 ani).
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Suma de bani obtinutã în luna cu cel mai mic profit din ultimele 36 de luni.
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Suma de bani obtinutã în luna cu cel mai mare profit din ultimele 36 de luni.
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}Numãrul de încãrcãturi transportate în ultimele 12 luni.
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}Tipuri de mãrfuri transportate în ultimele 3 luni.
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Balanta curentã
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}Ponderea creditelor
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Punctajul total din numãrul maxim posibil
+
+STR_NEWGRF_SETTINGS_BUTTON :{BLACK}Setari NewGRF
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}Setari Newgrf
+STR_NEWGRF_APPLY_CHANGES :{BLACK}Aplica schimbarile
+STR_NEWGRF_SET_PARAMETERS :{BLACK}Seteaza parametri
+STR_NEWGRF_TIP :{BLACK}Lista tuturor setarilor Newgrf pe care le-ai instalat. Click pentru a schimba setarile.
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}Nu exista fisiere newgrf instalate! Citeste manualul pentru instructiunile de instalare a fisierelor grafice noi.
+STR_NEWGRF_FILENAME :{BLACK}Nume fisier: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}ID GRF: {SILVER}{STRING}
+STR_NEWGRF_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING}
+STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}Esti pe cale sa faci modificari intr-un joc activ. Aceasta poate destabiliza OpenTTD.{}Esti absolut sigur ca vrei sa faci asta?
+
+STR_NEWGRF_ADD :{BLACK}Adauga
+STR_NEWGRF_ADD_TIP :{BLACK}Adauga un fisier NewGRF in lista
+STR_NEWGRF_REMOVE :{BLACK}Elimina
+STR_NEWGRF_REMOVE_TIP :{BLACK}Elimina fisierul NewGRF ales din lista
+STR_NEWGRF_MOVEUP :{BLACK}Muta Sus
+STR_NEWGRF_MOVEUP_TIP :{BLACK}Muta fisierul NewGRF ales mai sus in lista
+STR_NEWGRF_MOVEDOWN :{BLACK}Muta Jos
+STR_NEWGRF_MOVEDOWN_TIP :{BLACK}Muta fisierul NewGRF ales mai jos in lista
+STR_NEWGRF_FILE_TIP :{BLACK}O lista a fisierelor NewGRF instalate. Fa click pe un fisier pt a-i modifica parameterii
+STR_NEWGRF_PARAMETER :{BLACK}Parametri: {SILVER}{STRING}
+STR_NEWGRF_PARAMETER_QUERY :{BLACK}Introdu parametrii NewGRF
+STR_NEWGRF_NO_INFO :{BLACK}Nici o informatie disponibila
+
+STR_NEWGRF_ADD_CAPTION :{WHITE}Fisiere NewGRF disponibile
+STR_NEWGRF_ADD_FILE :{BLACK}Adauga la selectie
+STR_NEWGRF_ADD_FILE_TIP :{BLACK}Adauga fisierul NewGRF ales in configuratie
+STR_NEWGRF_RESCAN_FILES :{BLACK}Redetecteaza fisierele
+STR_NEWGRF_RESCAN_FILES_TIP :{BLACK}Actualizeaza lista de fisiere NewGRF disponibile
+STR_NEWGRF_DUPLICATE_GRFID :{WHITE}Nu pot adauga fisierul: ID GRF duplicat
+
+STR_NEWGRF_NOT_FOUND :{RED}Nici un fisier potrivit
+STR_NEWGRF_DISABLED :{RED}Dezactivat
+
+STR_CURRENCY_WINDOW :{WHITE}Moneda proprie
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Curs de schimb: {ORANGE}{CURRENCY} = £ {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Separator:
+STR_CURRENCY_PREFIX :{LTBLUE}Prefix:
+STR_CURRENCY_SUFFIX :{LTBLUE}Sufix:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Adera la Euro: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Adera la Euro: {ORANGE}niciodata
+STR_CURRENCY_PREVIEW :{LTBLUE}Previzualizare: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Schimba un parametru al monedei proprii
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} Trenuri
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} Autovehicule
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} Aeronave
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} Nave
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Afiseaza toate trenurile care opresc in aceasta statie
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Afiseaza toate autovehiculele care opresc in aceasta statie
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Afiseaza toate aeronavele care opresc in aceasta statie
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Afiseaza toate navele care opresc in aceasta statie
+
+STR_VEH_WITH_SHARED_ORDERS_LIST :{WHITE}Comenzi comune ale {COMMA} Vehicul{P "" s}
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}Arata toate vehiculele care se incadreaza in acest program
+
+### depot strings
+STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Esti pe cale sa vinzi toate vehiculele din depou. Esti sigur?
+
+STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP :{BLACK}Vinde toate trenurile din the depou
+STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP :{BLACK}Vinde toate autovehiculele din depou
+STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP :{BLACK}Vinde toate vasele din depou
+STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP :{BLACK}Vinde toate aeronavele din hangar
+
+STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP :{BLACK}Obtine o lista ordonata a tuturor trenurilor din depoul actual
+STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP :{BLACK}Obtine o lista ordonata a tuturor autovehiculelor din depoul actual
+STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP :{BLACK}Obtine o lista ordonata a tuturor vaselor din depoul actual
+STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP :{BLACK}Obtine o lista ordonata a tuturor aeronavelor din orice hangar al acestui aeroport
+
+STR_DEPOT_AUTOREPLACE_TRAIN_TIP :{BLACK}Inlocuieste automat toate trenurile din depou
+STR_DEPOT_AUTOREPLACE_ROADVEH_TIP :{BLACK}Inlocuieste automat toate autovehiculele din depou
+STR_DEPOT_AUTOREPLACE_SHIP_TIP :{BLACK}Inlocuieste automat toate vasele din depou
+STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP :{BLACK}Inlocuieste automat toate aeronavele din hangar
+
+STR_VEHICLE_LIST_TRAIN_DEPOT :{BLACK}{STRING} - {COMMA} Tren{P "" s}
+STR_VEHICLE_LIST_ROADVEH_DEPOT :{BLACK}{STRING} - {COMMA} Autovehicul{P "" s}
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} Vas{P "" s}
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} Aeronava
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}ÃŽnlocuieste {STRING}
+STR_REPLACE_VEHICLES_START :{BLACK}Incepere inlocuire vehicule
+STR_REPLACE_VEHICLES_STOP :{BLACK}Oprire inlocuire vehicuke
+STR_NOT_REPLACING :{BLACK}Neinlocuire
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Nici un vehicul selectat
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Alege tipul de vehicul pentru inlocuire
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Alege noul tip de vehicul cu care doresti sa inlocuiesti tipul de vehicul din stanga
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Apasa acest buton daca nu doresti sa inlocuiesti vehiculele selectate in stanga
+STR_REPLACE_HELP_START_BUTTON :{BLACK}Apasa acest buton daca doresti sa inlocuiesti vehiculele selectate in stanga cu cele selectate in dreapta
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Alege un tip de cale ferata pentru care sa selectezi vehiculele
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Afiseaza cu ce model vor fi inlocuite vehiculele din stanga
+STR_REPLACE_HELP :{BLACK}Aceasta functie iti permite sa selectezi un model de vehicul si sa-l inlocuiesti cu altul. Schimbarea se va efectua automat la intrarea vehiculului intr-un depou.
+STR_REPLACE_REMOVE_WAGON :{BLACK}Retragere vagoane: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Fã optiunea de autoînlocuire sã pãstreze identicã lungimea unui tren prin eliminarea vagoanelor (începând din fatã), dacã înlocuirea motorului ar face trenul mai lung.
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}ÃŽnlocuire: {ORANGE}{SKIP}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} ELEMENT EXPERIMENTAL {}Comutã între ferestrele de ]nlocuire motoare si vagoane.{}Înlocuirea de vagoane va fi efectuatã numai dacã noul vagon poate transporta acelasi tip de încãrcãturã ca cel vechi. Aceast lucru este verificat pentru fiecare vagon atunci când este fãcutã înlocuirea efectivã.
+STR_ENGINE_NOT_BUILDABLE :{WHITE}Motorul nu poate fi construit
+
+STR_ENGINES :Motoare
+STR_WAGONS :Vagoane
+
+STR_MASS_STOP_DEPOT_TRAIN_TIP :{BLACK}Click pt oprirea tuturor trenurilor din depou
+STR_MASS_STOP_DEPOT_ROADVEH_TIP :{BLACK}Click pt oprirea tuturor autovehiculelor din depou
+STR_MASS_STOP_DEPOT_SHIP_TIP :{BLACK}Click pt oprirea tuturor vaselor din depou
+STR_MASS_STOP_HANGAR_TIP :{BLACK}Click pt oprirea tuturor aeronavelor din hangar
+
+STR_MASS_START_DEPOT_TRAIN_TIP :{BLACK}Click pt pornirea tuturor trenurilor din depou
+STR_MASS_START_DEPOT_ROADVEH_TIP :{BLACK}Click pt pornirea tuturor autovehiculelor din depou
+STR_MASS_START_DEPOT_SHIP_TIP :{BLACK}Click pt pornirea tuturor vaselor din depou
+STR_MASS_START_HANGAR_TIP :{BLACK}Click pt pornirea tuturor aeronavelor din hangar
+
+STR_MASS_STOP_LIST_TIP :{BLACK}Click pt oprirea tuturor vehiculelor din lista
+STR_MASS_START_LIST_TIP :{BLACK}Apasa pentru pornirea tuturor vehiclulelor din lista
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}Lista de semne - {COMMA} Semne
+
+STR_ORDER_REFIT_FAILED :{WHITE}Comanda oprirea rearanjarilor esuate {STRING} {COMMA}
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :Vehicule feroviare
+STR_ELRAIL_VEHICLES :Vehicule Electrificate pe Sine
+STR_MONORAIL_VEHICLES :Vehicule Monorail
+STR_MAGLEV_VEHICLES :Vehicule Maglev
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Cost: {GOLD}{CURRENCY}{BLACK} Greutate: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Viteza: {GOLD}{VELOCITY}{BLACK} Putere: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}Viteza: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Cost de rulare: {GOLD}{CURRENCY}/an
+STR_PURCHASE_INFO_CAPACITY :{BLACK}Capacitate: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}An aparitie: {GOLD}{NUM}{BLACK} Durata de viata: {GOLD}{COMMA} years
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}Eficienta max.: {GOLD}{COMMA}%
+STR_PURCHASE_INFO_COST :{BLACK}Cost: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Greutate: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Cost: {GOLD}{CURRENCY}{BLACK} Viteza: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Capacitate: {GOLD}{COMMA} calatori, {COMMA} saci de posta
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Vagoane electrificate: {GOLD}+{POWER}{BLACK} Greutate: {GOLD}+{WEIGHT_S}
+STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Rearanjabil in: {GOLD}
+STR_PURCHASE_INFO_ALL_TYPES :Toate tipurile de incarcaturi
+STR_PURCHASE_INFO_ALL_BUT :Toate, cu exceptia {GOLD}
+STR_PURCHASE_INFO_MAX_TE :{BLACK}Efort tractor max.: {GOLD}{FORCE}
+
+########### String for New Landscape Generator
+
+STR_GENERATE :{WHITE}Genereaza
+STR_RANDOM :{BLACK}Aleator
+STR_RANDOM_HELP :{BLACK}Modifica parametrul aleator folosit la Generarea lumii
+STR_WORLD_GENERATION_CAPTION :{WHITE}Generare lume
+STR_RANDOM_SEED :{BLACK}Parametru aleator:
+STR_RANDOM_SEED_HELP :{BLACK}Click pt introducerea unui parametru aleator
+STR_LAND_GENERATOR :{BLACK}Generator de teren:
+STR_TREE_PLACER :{BLACK}Algoritm arbore:
+STR_HEIGHTMAP_ROTATION :{BLACK}Rotatie harta inaltimi:
+STR_TERRAIN_TYPE :{BLACK}Tip teren:
+STR_QUANTITY_OF_SEA_LAKES :{BLACK}Nivelul marii:
+STR_SMOOTHNESS :{BLACK}Netezime:
+STR_SNOW_LINE_HEIGHT :{BLACK}Inaltimea zapezii:
+STR_DATE :{BLACK}Data:
+STR_NUMBER_OF_TOWNS :{BLACK}Nr. de orase:
+STR_NUMBER_OF_INDUSTRIES :{BLACK}Nr. de industrii:
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_SNOW_LINE_UP :{BLACK}Muta linia zapezii cu un punct in sus
+STR_SNOW_LINE_DOWN :{BLACK}Muta linia zapezii cu un punct in jos
+STR_SNOW_LINE_QUERY_CAPT :{WHITE}Nu pot modifica inaltimea zapezii
+STR_START_DATE_QUERY_CAPT :{WHITE}Modifica inceputul anului
+STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Avertisment de scala
+STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Redimensionarea excesiva a hartii nu este recomandata. Continui cu generarea?
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_HEIGHTMAP_NAME :{BLACK}Nume harta inaltimi:
+STR_HEIGHTMAP_SIZE :{BLACK}Dimensiune: {ORANGE}{NUM} x {NUM}
+STR_GENERATION_WORLD :{WHITE}Generez lumea...
+STR_GENERATION_ABORT :{BLACK}Anuleaza
+STR_GENERATION_ABORT_CAPTION :{WHITE}Anuleaza Generarea Lumii
+STR_GENERATION_ABORT_MESSAGE :{YELLOW}Sigur doresti sa anulezi generarea?
+STR_PROGRESS :{WHITE}{NUM}% efectuat
+STR_GENERATION_PROGRESS :{BLACK}{NUM} / {NUM}
+STR_WORLD_GENERATION :{BLACK}Generare lume
+STR_TREE_GENERATION :{BLACK}Generare arbori
+STR_UNMOVABLE_GENERATION :{BLACK}Generare fixa
+STR_CLEARING_TILES :{BLACK}Generare zona dura si pietroasa
+STR_SETTINGUP_GAME :{BLACK}Fac setarile jocului
+STR_PREPARING_TILELOOP :{BLACK}Initializez ciclul dalelor
+STR_PREPARING_GAME :{BLACK}Pregatesc jocul
+STR_DIFFICULTY_TO_CUSTOM :{WHITE}Aceasta actiune a modificat nivelul de difficultate la custom
+STR_SE_FLAT_WORLD :{WHITE}Teren plat
+STR_SE_FLAT_WORLD_TIP :{BLACK}Genereaza un teren plat
+STR_SE_RANDOM_LAND :{WHITE}Teren aleator
+STR_SE_NEW_WORLD :{BLACK}Creeaza o harta noua
+STR_SE_CAPTION :{WHITE}Tip harta
+STR_FLAT_WORLD_HEIGHT_DOWN :{BLACK}Muta in jos, cu o unitate, inaltimea terenului plan
+STR_FLAT_WORLD_HEIGHT_UP :{BLACK}Muta in sus, cu o unitate, inaltimea terenului plan
+STR_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Modifica inaltimea terenului plan
+STR_FLAT_WORLD_HEIGHT :{BLACK}Inaltimea terenului plat:
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+STR_SMALLMAP_CENTER :{BLACK}Centreaza harta mica la pozitia actuala
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}Mic
+STR_CITY_AIRPORT :{BLACK}Oras
+STR_METRO_AIRPORT :{BLACK}Aeroporturi metropolitane
+STR_INTERNATIONAL_AIRPORT :{BLACK}Aeroport international
+STR_COMMUTER_AIRPORT :{BLACK}Comutator
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Intercontinental
+STR_HELIPORT :{BLACK}Helidrom
+STR_HELIDEPOT :{BLACK}Hangar elicoptere
+STR_HELISTATION :{BLACK}Baza elicoptere
+
+STR_SMALL_AIRPORTS :{BLACK}Aeroporturi mici
+STR_LARGE_AIRPORTS :{BLACK}Aeroporturi mari
+STR_HUB_AIRPORTS :{BLACK}Aeroporturi centrale
+STR_HELIPORTS :{BLACK}Aeroporturi elicoptere
+
+############ Tooltip measurment
+
+STR_MEASURE_LENGTH :{BLACK}Lungime: {NUM}
+STR_MEASURE_AREA :{BLACK}Suprafata: {NUM} x {NUM}
+STR_MEASURE_LENGTH_HEIGHTDIFF :{BLACK}Lungime: {NUM}{}Diferenta inaltime: {NUM} m
+STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}Suprafata: {NUM} x {NUM}{}Diferenta inaltime: {NUM} m
+
+########
diff --git a/src/lang/russian.txt b/src/lang/russian.txt
new file mode 100644
index 000000000..1cafa7ada
--- /dev/null
+++ b/src/lang/russian.txt
@@ -0,0 +1,3115 @@
+##name Russian
+##ownname РуÑÑкий
+##isocode ru_RU.UTF-8
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Край карты
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Слишком близко к краю карты
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Ðе доÑтаточно денег - требуетÑÑ {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Ðеобходимо ровное меÑто
+STR_0008_WAITING :{BLACK}Ожидает: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (привезено из
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}ПринимаютÑÑ: {WHITE}
+STR_000D_ACCEPTS :{BLACK}ПринимаютÑÑ: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :ПаÑÑажиры
+STR_0010_COAL :Уголь
+STR_0011_MAIL :Почта
+STR_0012_OIL :Ðефть
+STR_0013_LIVESTOCK :Скот
+STR_0014_GOODS :Товары
+STR_0015_GRAIN :Зерно
+STR_0016_WOOD :Дерево
+STR_0017_IRON_ORE :Ð–ÐµÐ»ÐµÐ·Ð½Ð°Ñ Ñ€ÑƒÐ´Ð°
+STR_0018_STEEL :Сталь
+STR_0019_VALUABLES :ДрагоценноÑти
+STR_001A_COPPER_ORE :ÐœÐµÐ´Ð½Ð°Ñ Ñ€ÑƒÐ´Ð°
+STR_001B_MAIZE :Кукуруза
+STR_001C_FRUIT :Фрукты
+STR_001D_DIAMONDS :Бриллианты
+STR_001E_FOOD :Еда
+STR_001F_PAPER :Бумага
+STR_0020_GOLD :Золото
+STR_0021_WATER :Вода
+STR_0022_WHEAT :Пшеница
+STR_0023_RUBBER :Резина
+STR_0024_SUGAR :Сахар
+STR_0025_TOYS :Игрушки
+STR_0026_CANDY :Конфеты
+STR_0027_COLA :Кола
+STR_0028_COTTON_CANDY :Ð¡Ð°Ñ…Ð°Ñ€Ð½Ð°Ñ Ð²Ð°Ñ‚Ð°
+STR_0029_BUBBLES :Пузырьки
+STR_002A_TOFFEE :ИриÑки
+STR_002B_BATTERIES :Батарейки
+STR_002C_PLASTIC :ПлаÑтик
+STR_002D_FIZZY_DRINKS :Газировка
+STR_002E :
+STR_002F_PASSENGER :ПаÑÑажир
+STR_0030_COAL :Уголь
+STR_0031_MAIL :Почта
+STR_0032_OIL :Ðефть
+STR_0033_LIVESTOCK :Скот
+STR_0034_GOODS :Товар
+STR_0035_GRAIN :Зерно
+STR_0036_WOOD :Дерево
+STR_0037_IRON_ORE :Ð–ÐµÐ»ÐµÐ·Ð½Ð°Ñ Ñ€ÑƒÐ´Ð°
+STR_0038_STEEL :Сталь
+STR_0039_VALUABLES :ДрагоценноÑти
+STR_003A_COPPER_ORE :ÐœÐµÐ´Ð½Ð°Ñ Ñ€ÑƒÐ´Ð°
+STR_003B_MAIZE :Кукуруза
+STR_003C_FRUIT :Фрукты
+STR_003D_DIAMOND :Бриллианты
+STR_003E_FOOD :Еда
+STR_003F_PAPER :Бумага
+STR_0040_GOLD :Золото
+STR_0041_WATER :Вода
+STR_0042_WHEAT :Пшеница
+STR_0043_RUBBER :Резина
+STR_0044_SUGAR :Сахар
+STR_0045_TOY :Игрушки
+STR_0046_CANDY :Конфеты
+STR_0047_COLA :Кола
+STR_0048_COTTON_CANDY :Ð¡Ð°Ñ…Ð°Ñ€Ð½Ð°Ñ Ð²Ð°Ñ‚Ð°
+STR_0049_BUBBLE :Пузырьки
+STR_004A_TOFFEE :ИриÑки
+STR_004B_BATTERY :Батарейки
+STR_004C_PLASTIC :ПлаÑтик
+STR_004D_FIZZY_DRINK :Газировка
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} паÑÑажиров
+STR_QUANTITY_COAL :{WEIGHT} углÑ
+STR_QUANTITY_MAIL :{COMMA} мешков почты
+STR_QUANTITY_OIL :{VOLUME} нефти
+STR_QUANTITY_LIVESTOCK :{COMMA} голов домашнего Ñкота
+STR_QUANTITY_GOODS :{COMMA} единиц товара
+STR_QUANTITY_GRAIN :{WEIGHT} зерна
+STR_QUANTITY_WOOD :{WEIGHT} дерева
+STR_QUANTITY_IRON_ORE :{WEIGHT} железной руды
+STR_QUANTITY_STEEL :{WEIGHT} Ñтали
+STR_QUANTITY_VALUABLES :{COMMA} мешков драгоценноÑтей
+STR_QUANTITY_COPPER_ORE :{WEIGHT} медной руды
+STR_QUANTITY_MAIZE :{WEIGHT} кукурузы
+STR_QUANTITY_FRUIT :{WEIGHT} фруктов
+STR_QUANTITY_DIAMONDS :{COMMA} мешков алмазов
+STR_QUANTITY_FOOD :{WEIGHT} еды
+STR_QUANTITY_PAPER :{WEIGHT} бумаги
+STR_QUANTITY_GOLD :{COMMA} мешков золота
+STR_QUANTITY_WATER :{VOLUME} воды
+STR_QUANTITY_WHEAT :{WEIGHT} пшеницы
+STR_QUANTITY_RUBBER :{VOLUME} резины
+STR_QUANTITY_SUGAR :{WEIGHT} Ñахара
+STR_QUANTITY_TOYS :{COMMA} игрушек
+STR_QUANTITY_SWEETS :{COMMA} мешков конфет
+STR_QUANTITY_COLA :{VOLUME} колы
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} Ñахарной ваты
+STR_QUANTITY_BUBBLES :{COMMA} пузырьков
+STR_QUANTITY_TOFFEE :{WEIGHT} ириÑок
+STR_QUANTITY_BATTERIES :{COMMA} батареек
+STR_QUANTITY_PLASTIC :{VOLUME} плаÑтика
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} газировки
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}PS
+STR_ABBREV_COAL :{TINYFONT}CL
+STR_ABBREV_MAIL :{TINYFONT}ML
+STR_ABBREV_OIL :{TINYFONT}OL
+STR_ABBREV_LIVESTOCK :{TINYFONT}LV
+STR_ABBREV_GOODS :{TINYFONT}GD
+STR_ABBREV_GRAIN :{TINYFONT}GR
+STR_ABBREV_WOOD :{TINYFONT}WD
+STR_ABBREV_IRON_ORE :{TINYFONT}OR
+STR_ABBREV_STEEL :{TINYFONT}ST
+STR_ABBREV_VALUABLES :{TINYFONT}VL
+STR_ABBREV_COPPER_ORE :{TINYFONT}CO
+STR_ABBREV_MAIZE :{TINYFONT}MZ
+STR_ABBREV_FRUIT :{TINYFONT}FT
+STR_ABBREV_DIAMONDS :{TINYFONT}DM
+STR_ABBREV_FOOD :{TINYFONT}FD
+STR_ABBREV_PAPER :{TINYFONT}PR
+STR_ABBREV_GOLD :{TINYFONT}GD
+STR_ABBREV_WATER :{TINYFONT}WR
+STR_ABBREV_WHEAT :{TINYFONT}WH
+STR_ABBREV_RUBBER :{TINYFONT}RB
+STR_ABBREV_SUGAR :{TINYFONT}SG
+STR_ABBREV_TOYS :{TINYFONT}TY
+STR_ABBREV_SWEETS :{TINYFONT}SW
+STR_ABBREV_COLA :{TINYFONT}CL
+STR_ABBREV_CANDYFLOSS :{TINYFONT}CF
+STR_ABBREV_BUBBLES :{TINYFONT}BU
+STR_ABBREV_TOFFEE :{TINYFONT}TF
+STR_ABBREV_BATTERIES :{TINYFONT}BA
+STR_ABBREV_PLASTIC :{TINYFONT}PL
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}FZ
+STR_ABBREV_NONE :{TINYFONT}ÐЕТ
+STR_ABBREV_ALL :{TINYFONT}Ð’Ñе
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Карта - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Параметры
+STR_00B2_MESSAGE :{YELLOW}Сообщение
+STR_00B3_MESSAGE_FROM :{YELLOW}Сообщение из {STRING}
+STR_POPUP_CAUTION_CAPTION :{WHITE}ОÑторожно!
+STR_00B4_CAN_T_DO_THIS :{WHITE}Это невозможно
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Ðевозможно очиÑтить
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Оригинальные авторÑкие права {COPYRIGHT} 1995 Chris Sawyer, Ð’Ñе права защищены
+STR_00B7_VERSION :{BLACK}OpenTTD v{REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 Команда разработчиков OpenTTD
+STR_TRANSLATED_BY :{BLACK} Переводчики - Ðазаров Дмитрий (aka Smoky555), Олег Попков (aka Oleg) - http://forums.ttdrussia.net
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Выход
+STR_00C8_YES :{BLACK}Да
+STR_00C9_NO :{BLACK}Ðет
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Ð’Ñ‹ уверены что хотите прервать игру и вернутьÑÑ Ð² {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Ðичего
+STR_00D1_DARK_BLUE :Темно-Ñиний
+STR_00D2_PALE_GREEN :Светло-зеленый
+STR_00D3_PINK :Розовый
+STR_00D4_YELLOW :Желтый
+STR_00D5_RED :КраÑный
+STR_00D6_LIGHT_BLUE :Светло-Ñиний
+STR_00D7_GREEN :Зеленый
+STR_00D8_DARK_GREEN :Темно-зеленый
+STR_00D9_BLUE :Синий
+STR_00DA_CREAM :Кремовый
+STR_00DB_MAUVE :Лиловый
+STR_00DC_PURPLE :Пурпурный
+STR_00DD_ORANGE :Оранжевый
+STR_00DE_BROWN :Коричневый
+STR_00DF_GREY :Серый
+STR_00E0_WHITE :Белый
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Слишком много транÑпорта в игре
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}ПозициÑ
+STR_00E5_CONTOURS :Контуры
+STR_00E6_VEHICLES :ТранÑпорт
+STR_00E7_INDUSTRIES :ПромышленноÑÑ‚ÑŒ
+STR_00E8_ROUTES :Маршруты
+STR_00E9_VEGETATION :РаÑтительноÑÑ‚ÑŒ
+STR_00EA_OWNERS :Владельцы
+STR_00EB_ROADS :{BLACK}{TINYFONT}Дороги
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Железные дороги
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Станции/ÐÑропорты/Доки
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}СтроениÑ/ПредприÑтиÑ
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}ТранÑпорт
+STR_00F0_100M :{BLACK}{TINYFONT}100м
+STR_00F1_200M :{BLACK}{TINYFONT}200м
+STR_00F2_300M :{BLACK}{TINYFONT}300м
+STR_00F3_400M :{BLACK}{TINYFONT}400м
+STR_00F4_500M :{BLACK}{TINYFONT}500м
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Поезда
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}ÐвтотранÑпорт
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Суда
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}ÐвиатранÑпорт
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Маршруты ТранÑпорта
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Ð£Ð³Ð¾Ð»ÑŒÐ½Ð°Ñ ÑˆÐ°Ñ…Ñ‚Ð°
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}ЭлектроÑтанциÑ
+STR_00FC_FOREST :{BLACK}{TINYFONT}ЛеÑ
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}ЛеÑопилка
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Ðефтеперегонный завод
+STR_00FF_FARM :{BLACK}{TINYFONT}Ферма
+STR_0100_FACTORY :{BLACK}{TINYFONT}Завод
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}ТипографиÑ
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}ÐефтÑÐ½Ð°Ñ Ñкважина
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Шахта железной руды
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Сталелитейный завод
+STR_0105_BANK :{BLACK}{TINYFONT}Банк
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Целлюлозно-бумажный комбинат
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Золотой прииÑк
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Пищевой завод
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}ÐÐ»Ð¼Ð°Ð·Ð½Ð°Ñ ÑˆÐ°Ñ…Ñ‚Ð°
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}ÐœÐµÐ´Ð½Ð°Ñ ÑˆÐ°Ñ…Ñ‚Ð°
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Фруктовые плантации
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}ÐŸÐ»Ð°Ð½Ñ‚Ð°Ñ†Ð¸Ñ Ñ€ÐµÐ·Ð¸Ð½Ñ‹
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Водокачка
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Ð’Ð¾Ð´Ð¾Ð½Ð°Ð¿Ð¾Ñ€Ð½Ð°Ñ Ð±Ð°ÑˆÐ½Ñ
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}ЛеÑопилка
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Ð›ÐµÑ Ñахарной ваты
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Завод ÑладоÑтей
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Ферма батареек
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}ÐаÑÐ¾Ñ ÐºÐ¾Ð»Ñ‹
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Магазин игрушек
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Завод игрушек
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Фонтаны плаÑтика
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Завод шипучки
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Генератор пузырьков
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Карьер ириÑок
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Шахта Ñахара
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Ж/Д ÑтанциÑ
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}ÐвтоÑтанциÑ
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}ÐвтобуÑÐ½Ð°Ñ ÑтанциÑ
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}ÐÑропорт/Вертодром
+STR_011F_DOCK :{BLACK}{TINYFONT}Док
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}КамениÑÑ‚Ð°Ñ Ð¿Ð¾Ñ‡Ð²Ð°
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Трава
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Почва
+STR_0123_FIELDS :{BLACK}{TINYFONT}ПолÑ
+STR_0124_TREES :{BLACK}{TINYFONT}ДеревьÑ
+STR_0125_ROCKS :{BLACK}{TINYFONT}Скалы
+STR_0126_WATER :{BLACK}{TINYFONT}Вода
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Ðет владельца
+STR_0128_TOWNS :{BLACK}{TINYFONT}Города
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}ПредприÑтиÑ
+STR_012A_DESERT :{BLACK}{TINYFONT}ПуÑтынÑ
+STR_012B_SNOW :{BLACK}{TINYFONT}Снег
+STR_012C_MESSAGE :{WHITE}Сообщение
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Отмена
+STR_012F_OK :{BLACK}Да
+STR_0130_RENAME :{BLACK}Переимен.
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Слишком много имен определено
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Выбранное Ð¸Ð¼Ñ ÑƒÐ¶Ðµ иÑпользуетÑÑ
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix/Linux
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...принадлежащий {STRING}
+STR_013C_CARGO :{BLACK}Груз
+STR_013D_INFORMATION :{BLACK}ИнформациÑ
+STR_013E_CAPACITIES :{BLACK}ВмеÑтимоÑÑ‚ÑŒ
+STR_013E_TOTAL_CARGO :{BLACK}Общий груз
+STR_013F_CAPACITY :{BLACK}ВмеÑтимоÑÑ‚ÑŒ: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}ЕмкоÑÑ‚ÑŒ: {LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}ÐžÐ±Ñ‰Ð°Ñ Ð·Ð°Ð³Ñ€ÑƒÐ¶ÐµÐ½Ð½Ð¾ÑÑ‚ÑŒ Ñтого транÑпорта:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}ÐÐ¾Ð²Ð°Ñ Ð˜Ð³Ñ€Ð°
+STR_0141_LOAD_GAME :{BLACK}Загрузить Игру
+STR_SINGLE_PLAYER :{BLACK}Один игрок
+STR_MULTIPLAYER :{BLACK}Ð¡ÐµÑ‚ÐµÐ²Ð°Ñ Ð¸Ð³Ñ€Ð°
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Размер карты:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}ÐаÑтройки Игры
+
+STR_0150_SOMEONE :кто-нибудь{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Карта
+STR_0152_TOWN_DIRECTORY :СпиÑок городов
+STR_0153_SUBSIDIES :СубÑидии
+
+STR_UNITS_IMPERIAL :Имперкие
+STR_UNITS_METRIC :МетричеÑкаÑ
+STR_UNITS_SI :СИ
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} миль/ч
+STR_UNITS_VELOCITY_METRIC :{COMMA} км/ч
+STR_UNITS_VELOCITY_SI :{COMMA} м/Ñ
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}лÑ
+STR_UNITS_POWER_METRIC :{COMMA}лÑ
+STR_UNITS_POWER_SI :{COMMA}кВатт
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}Ñ‚
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}Ñ‚
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}кг
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} тонн
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} тонн
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} кг
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}гал.
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}л
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}м³
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} галлонов
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} литров
+STR_UNITS_VOLUME_LONG_SI :{COMMA} м³
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10³ lbf
+STR_UNITS_FORCE_METRIC :{COMMA} тонн Ñилы
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Текущий график доходов
+STR_0155_INCOME_GRAPH :График дохода
+STR_0156_DELIVERED_CARGO_GRAPH :ДоÑтавленные грузы
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Рейтинг
+STR_0158_COMPANY_VALUE_GRAPH :СтоимоÑÑ‚ÑŒ компании
+STR_0159_CARGO_PAYMENT_RATES :Оплата перевозок
+STR_015A_COMPANY_LEAGUE_TABLE :ПорÑÐ´ÐºÐ¾Ð²Ð°Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° компаний
+STR_PERFORMANCE_DETAIL_MENU :Подробные данные
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}Об OpenTTD
+STR_015C_SAVE_GAME :Сохранить игру
+STR_015D_LOAD_GAME :Загрузить игру
+STR_015E_QUIT_GAME :В главное меню
+STR_015F_QUIT :Выход
+STR_ABANDON_GAME_QUERY :{YELLOW}Ð’Ñ‹ дейÑтвительно хотите выйти из игры?
+STR_0161_QUIT_GAME :{WHITE}В главное меню
+STR_SORT_ORDER_TIP :{BLACK}Выбор Ð½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñортировки (убывание/возраÑтание)
+STR_SORT_CRITERIA_TIP :{BLACK}Выбор ÐºÑ€Ð¸Ñ‚ÐµÑ€Ð¸Ñ Ñортировки
+STR_SORT_BY :{BLACK}Сортировать по
+
+STR_SORT_BY_POPULATION :{BLACK}наÑелению
+STR_SORT_BY_PRODUCTION :{BLACK}кол-ву продукции
+STR_SORT_BY_TYPE :{BLACK}типу
+STR_SORT_BY_TRANSPORTED :{BLACK}перевезенной прод.
+STR_SORT_BY_NAME :{BLACK}имени
+STR_SORT_BY_DROPDOWN_NAME :названию
+STR_SORT_BY_DATE :{BLACK}дате
+STR_SORT_BY_NUMBER :номеру
+STR_SORT_BY_PROFIT_LAST_YEAR :Прибыль в прошлом году
+STR_SORT_BY_PROFIT_THIS_YEAR :Прибыль в Ñтом году
+STR_SORT_BY_AGE :возраÑту
+STR_SORT_BY_RELIABILITY :ÐадежноÑÑ‚ÑŒ
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :вмеÑтимоÑти грузов
+STR_SORT_BY_MAX_SPEED :макÑ. ÑкороÑти
+STR_SORT_BY_MODEL :модели
+STR_SORT_BY_VALUE :значению
+STR_SORT_BY_FACILITY :типу Ñтанции
+STR_SORT_BY_WAITING :кол-ву товара на Ñтанции
+STR_SORT_BY_RATING_MAX :Рейтинг
+STR_ENGINE_SORT_ENGINE_ID :Ðазвание
+STR_ENGINE_SORT_COST :Цена
+STR_ENGINE_SORT_POWER :МощноÑÑ‚ÑŒ
+STR_ENGINE_SORT_INTRO_DATE :Дата поÑтройки
+STR_ENGINE_SORT_RUNNING_COST :СтоимоÑÑ‚ÑŒ обÑлуж.
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Мощн./Стоим. обÑлуж.
+STR_ENGINE_SORT_CARGO_CAPACITY :ВмеÑтимоÑÑ‚ÑŒ
+STR_NO_WAITING_CARGO :{BLACK}Ðа Ñтанции нет грузов, ожидающих погрузки
+STR_SELECT_ALL_FACILITIES :{BLACK}Выбрать вÑе уÑтройÑтва
+STR_SELECT_ALL_TYPES :{BLACK}Выбрать вÑе типы грузов
+STR_AVAILABLE_ENGINES_TIP :{BLACK}СпиÑок доÑтупного транÑпорта.
+STR_MANAGE_LIST :{BLACK}Редакт. ÑпиÑок
+STR_MANAGE_LIST_TIP :{BLACK}ПоÑлать инÑтрукции вÑему транÑпорту в ÑпиÑке
+STR_REPLACE_VEHICLES :Замена ТранÑпорта
+STR_SEND_TRAIN_TO_DEPOT :ПоÑлать в Депо
+STR_SEND_ROAD_VEHICLE_TO_DEPOT :ПоÑлать в гараж
+STR_SEND_SHIP_TO_DEPOT :ПоÑлать в Док
+STR_SEND_AIRCRAFT_TO_HANGAR :ПоÑлать в Ðнгар
+STR_SEND_FOR_SERVICING :ПоÑлать на обÑлуживание
+
+############ range for months starts
+STR_0162_JAN :Янв
+STR_0163_FEB :Фев
+STR_0164_MAR :Мар
+STR_0165_APR :Ðпр
+STR_0166_MAY :Май
+STR_0167_JUN :Июн
+STR_0168_JUL :Июл
+STR_0169_AUG :Ðвг
+STR_016A_SEP :Сен
+STR_016B_OCT :Окт
+STR_016C_NOV :ÐоÑ
+STR_016D_DEC :Дек
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}ПÐУЗÐ
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Сохранение игры, Главное меню, Выход
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Показать ÑпиÑок Ñтанций компании
+STR_0174_DISPLAY_MAP :{BLACK}Показать карту
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Показать карту, ÑпиÑок городов
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Показать ÑпиÑок городов
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Показать финанÑовую информацию компании
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Показать оÑновную информацию о компании
+STR_0179_DISPLAY_GRAPHS :{BLACK}Показать графики
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Показать таблицу лиги компании
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Показать ÑпиÑок поездов компании
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Показать ÑпиÑок автотранÑпорта компании
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Показать ÑпиÑок кораблей компании
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Показать ÑпиÑок авиатранÑпорта компании
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Приблизить
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Уменьшить
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}ПоÑтроить железнодорожные пути
+STR_0182_BUILD_ROADS :{BLACK}ПоÑтроить автодороги
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}ПоÑтроить морÑкие коммуникации
+STR_0184_BUILD_AIRPORTS :{BLACK}ПоÑтроить воздушные коммуникации
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Ð’Ñ‹Ñадить деревьÑ, поÑтавить знак и Ñ‚.д.
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ земле
+STR_0187_OPTIONS :{BLACK}ÐаÑтройки
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Ðевозможно изменить ÑервиÑный интервал...
+STR_018B_CLOSE_WINDOW :{BLACK}Закрыть Окно
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Заголовок окна - Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð¾ÐºÐ½Ð° тащить за него
+STR_STICKY_BUTTON :{BLACK}Пометить Ñто окно как незакрываемое Ð´Ð»Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ¸ 'Закрыть вÑе Окна'
+STR_RESIZE_BUTTON :{BLACK}Ðажмите и тащите Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€Ð° окна
+STR_SAVELOAD_HOME_BUTTON :{BLACK}Кликните, чтобы перейти к текущей папке загрузки/ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¿Ð¾ умолчанию
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Уничтожить поÑтройки и Ñ‚.п. в квадрате земли
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}ОпуÑтить угол земли
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}ПоднÑÑ‚ÑŒ угол земли
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Прокрутка вверх/вниз
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Прокрутка влево/вправо
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Показать контуры земли на карте
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Показать транÑпорт на карте
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Показать промышленноÑÑ‚ÑŒ на карте
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Показать маршруты на карте
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Показать раÑтительноÑÑ‚ÑŒ на карте
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Показать владельцев земли на карте
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Включить/выключить Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ð³Ð¾Ñ€Ð¾Ð´Ð¾Ð²
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Прибыль в Ñтом году: {CURRENCY} (прошлый год: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} лет ({COMMA})
+STR_AGE_RED :{RED}{COMMA} лет ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :ÐвтотранÑпорт
+STR_019D_AIRCRAFT :Воздушный транÑпорт
+STR_019E_SHIP :Корабли
+STR_019F_TRAIN :Поезда
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} уÑтарел
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} Ñильно уÑтарел
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} Ñильно уÑтарел и требует замены
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± учаÑтке земли
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Чтобы очиÑтить, надо: {LTBLUE}(нет данных)
+STR_01A5_COST_TO_CLEAR :{BLACK}Чтобы очиÑтить, надо: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :нет данных
+STR_01A7_OWNER :{BLACK}Владелец: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}ÐдминиÑтрациÑ: {LTBLUE}{STRING}
+STR_01A9_NONE :Ðет
+STR_01AA_NAME :{BLACK}ИмÑ
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1ое
+STR_01AD_2ND :2ое
+STR_01AE_3RD :3е
+STR_01AF_4TH :4ое
+STR_01B0_5TH :5ое
+STR_01B1_6TH :6ое
+STR_01B2_7TH :7ое
+STR_01B3_8TH :8ое
+STR_01B4_9TH :9ое
+STR_01B5_10TH :10ое
+STR_01B6_11TH :11ое
+STR_01B7_12TH :12ое
+STR_01B8_13TH :13ое
+STR_01B9_14TH :14ое
+STR_01BA_15TH :15ое
+STR_01BB_16TH :16ое
+STR_01BC_17TH :17ое
+STR_01BD_18TH :18ое
+STR_01BE_19TH :19ое
+STR_01BF_20TH :20ое
+STR_01C0_21ST :21ое
+STR_01C1_22ND :22ое
+STR_01C2_23RD :23е
+STR_01C3_24TH :24ое
+STR_01C4_25TH :25ое
+STR_01C5_26TH :26ое
+STR_01C6_27TH :27ое
+STR_01C7_28TH :28ое
+STR_01C8_29TH :29ое
+STR_01C9_30TH :30ое
+STR_01CA_31ST :31ое
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Грузов принÑто: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Музыкальный Ðвтомат
+STR_01D3_SOUND_MUSIC :Звук/музыка
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Показать окно
+STR_01D5_ALL :{TINYFONT}Ð’Ñе
+STR_01D6_OLD_STYLE :{TINYFONT}Старый Стиль
+STR_01D7_NEW_STYLE :{TINYFONT}Ðовый Стиль
+STR_01D8_EZY_STREET :{TINYFONT}Уличный Стиль
+STR_01D9_CUSTOM_1 :{TINYFONT}Пользоват. 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Пользоват. 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}ГромкоÑÑ‚ÑŒ музыки
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}ГромкоÑÑ‚ÑŒ звука
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}МИР' ' ' ' ' ' ÐœÐКС
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Играть предыдущий трек в программе
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Играть Ñледующий трек в программе
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}ОÑтановить воÑпроизведение
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Ðачать
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Перемещайте ползунки Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð³Ñ€Ð¾Ð¼ÐºÐ¾Ñти
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Дорожка{SETX 88}Ðазвание
+STR_01E9_SHUFFLE :{TINYFONT}Мешать
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Программа
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Выбор программы воÑпроизведениÑ
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Ðомер трека
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Программа - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}ОчиÑтить
+STR_01F1_SAVE :{TINYFONT}{BLACK}Сохранить
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Ð¢ÐµÐºÑƒÑ‰Ð°Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ð° музыкальных треков
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Выбор программы 'Ð’Ñе треки'
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Выбор программы 'Старый Ñтиль музыки'
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Выбор программы 'Ðовый Ñтиль музыки'
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Выбор программы 'Пользоват. 1'
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Выбор программы 'Пользоват. 2'
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}ОчиÑтка пользовательÑкой программы
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Сохранить наÑтройки музыки
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Кликните по названию трека Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð² пользовательÑкую программу
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Выберите трек Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ ÐµÐ³Ð¾ из данной программы (только пользовательÑкие)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Вкл./Выкл. Ñлучайный выбор програмы
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Показать окно выбора музыкальных треков
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Ðажмите на маршрут Ð´Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¿Ñ€ÐµÐ´Ð¿Ñ€Ð¸ÑтиÑ/города
+STR_01FE_DIFFICULTY :{BLACK}СложноÑÑ‚ÑŒ ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :ПоÑледнÑÑ Ð½Ð¾Ð²Ð¾ÑÑ‚ÑŒ
+STR_0201_MESSAGE_SETTINGS :ÐаÑтройки Ñообщений
+STR_MESSAGE_HISTORY_MENU :ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ñообщений
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Показать поÑледнее Ñобщение, наÑтройки Ñообщений
+STR_0204_MESSAGE_OPTIONS :{WHITE}ÐаÑтройки Ñообщений
+STR_0205_MESSAGE_TYPES :{BLACK}Типы Ñообщений:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Первое транÑп. ÑредÑтво игрока на Ñтанции
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Первое транÑп. ÑредÑтво противника на Ñтанции
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Ðварии/КатаÑтрофы
+STR_0209_COMPANY_INFORMATION :{YELLOW}Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ Компании
+STR_020A_ECONOMY_CHANGES :{YELLOW}Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² Ñкономике
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Ð¡Ð¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¾ транÑпорте игрока
+STR_020C_NEW_VEHICLES :{YELLOW}Ðовый транÑпорт
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² ÑпиÑке принимаемых грузов
+STR_020E_SUBSIDIES :{YELLOW}СубÑидии
+STR_020F_GENERAL_INFORMATION :{YELLOW}ÐžÐ±Ñ‰Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ
+STR_MESSAGES_ALL :{YELLOW}УÑтановить вÑе ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð² Выкл./Кратко/Полно
+STR_MESSAGE_SOUND :{YELLOW}Проигрывать звук при получении новых Ñообщений
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...Ñлишком далеко от предыдущей точки
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}ТОП-компании, доÑтигшие {NUM}{}({STRING} уровнÑ)
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}ПорÑÐ´ÐºÐ¾Ð²Ð°Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° компаний в {NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :БизнеÑмен
+STR_0214_ENTREPRENEUR :Предприниматель
+STR_0215_INDUSTRIALIST :Промышленник
+STR_0216_CAPITALIST :КапиталиÑÑ‚
+STR_0217_MAGNATE :Магнат
+STR_0218_MOGUL :ТранÑпортный король
+STR_0219_TYCOON_OF_THE_CENTURY :Магнат Века
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} доÑтиг ÑтатуÑа '{STRING}'!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} из {COMPANY} доÑтиг ÑтатуÑа '{STRING}'!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Создать Сценарий
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Редактор СценариÑ
+STR_0223_LAND_GENERATION :{WHITE}Генератор карты
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Ð¡Ð»ÑƒÑ‡Ð°Ð¹Ð½Ð°Ñ ÐšÐ°Ñ€Ñ‚Ð°
+STR_0227_RESET_LAND :{BLACK}СброÑить карту
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Увеличить площадь Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñ€ÐµÐ»ÑŒÐµÑ„Ð°
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Уменьшить площадь Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñ€ÐµÐ»ÑŒÐµÑ„Ð°
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Создать Ñлучайную карту
+STR_022B_RESET_LANDSCAPE :{BLACK}СброÑить карту
+STR_022C_RESET_LANDSCAPE :{WHITE}СброÑить карту
+STR_LOAD_GAME_HEIGHTMAP :{WHITE}ИÑп. РЕЛЬЕФ
+STR_LOAD_SCEN_HEIGHTMAP :{BLACK}ИÑп. РЕЛЬЕФ
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Ð’Ñ‹ уверены что хотите ÑброÑить землю?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Создание ландшафта
+STR_022F_TOWN_GENERATION :{BLACK}Создание города
+STR_0230_INDUSTRY_GENERATION :{BLACK}Создание промышленноÑти
+STR_0231_ROAD_CONSTRUCTION :{BLACK}СтроительÑтво дорог
+STR_0233_TOWN_GENERATION :{WHITE}Создание Города
+STR_0234_NEW_TOWN :{BLACK}Ðовый Город
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}ПоÑтроить новый город
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Ðевозможно поÑтроить город здеÑÑŒ...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...Ñлишком близко к краю карты
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...Ñлишком близко к другому городу
+STR_0239_SITE_UNSUITABLE :{WHITE}...неподходÑщее меÑто
+STR_023A_TOO_MANY_TOWNS :{WHITE}...Ñлишком много городов
+STR_CANNOT_GENERATE_TOWN :{WHITE}Ðевозможно поÑтроить еще города
+STR_NO_SPACE_FOR_TOWN :{WHITE}...больше нет меÑта на карте
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Увеличенить размер города
+STR_023C_EXPAND :{BLACK}РаÑширить
+STR_023D_RANDOM_TOWN :{BLACK}Случайный город
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Создать город в Ñлучайном меÑте
+STR_023F_INDUSTRY_GENERATION :{WHITE}Создание ПредприÑтий
+STR_0240_COAL_MINE :{BLACK}Ð£Ð³Ð¾Ð»ÑŒÐ½Ð°Ñ ÑˆÐ°Ñ…Ñ‚Ð°
+STR_0241_POWER_STATION :{BLACK}ЭлектроÑтанциÑ
+STR_0242_SAWMILL :{BLACK}ЛеÑопилка
+STR_0243_FOREST :{BLACK}ЛеÑ
+STR_0244_OIL_REFINERY :{BLACK}Ðефтеобраб. завод
+STR_0245_OIL_RIG :{BLACK}Ð‘ÑƒÑ€Ð¾Ð²Ð°Ñ Ð²Ñ‹ÑˆÐºÐ°
+STR_0246_FACTORY :{BLACK}Фабрика
+STR_0247_STEEL_MILL :{BLACK}Сталеплавильный завод
+STR_0248_FARM :{BLACK}Ферма
+STR_0249_IRON_ORE_MINE :{BLACK}Ð–ÐµÐ»ÐµÐ·Ð½Ð¾Ñ€ÑƒÐ´Ð½Ð°Ñ ÑˆÐ°Ñ…Ñ‚Ð°
+STR_024A_OIL_WELLS :{BLACK}ÐефтÑÐ½Ð°Ñ Ñкважина
+STR_024B_BANK :{BLACK}Банк
+STR_024C_PAPER_MILL :{BLACK}Ð‘ÑƒÐ¼Ð°Ð¶Ð½Ð°Ñ Ñ„Ð°Ð±Ñ€Ð¸ÐºÐ°
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}ÐŸÐ¸Ñ‰ÐµÐ²Ð°Ñ Ñ„Ð°Ð±Ñ€Ð¸ÐºÐ°
+STR_024E_PRINTING_WORKS :{BLACK}ТипографиÑ
+STR_024F_GOLD_MINE :{BLACK}Ð—Ð¾Ð»Ð¾Ñ‚Ð°Ñ ÑˆÐ°Ñ…Ñ‚Ð°
+STR_0250_LUMBER_MILL :{BLACK}ЛеÑопилка
+STR_0251_FRUIT_PLANTATION :{BLACK}ÐŸÐ»Ð°Ð½Ñ‚Ð°Ñ†Ð¸Ñ Ñ„Ñ€ÑƒÐºÑ‚Ð¾Ð²
+STR_0252_RUBBER_PLANTATION :{BLACK}ÐŸÐ»Ð°Ð½Ñ‚Ð°Ñ†Ð¸Ñ Ñ€ÐµÐ·Ð¸Ð½Ñ‹
+STR_0253_WATER_SUPPLY :{BLACK}Водокачка
+STR_0254_WATER_TOWER :{BLACK}Ð’Ð¾Ð´Ð¾Ð½Ð°Ð¿Ð¾Ñ€Ð½Ð°Ñ Ð±Ð°ÑˆÐ½Ñ
+STR_0255_DIAMOND_MINE :{BLACK}Ðлмазные копи
+STR_0256_COPPER_ORE_MINE :{BLACK}ÐœÐµÐ´Ð½Ð°Ñ ÑˆÐ°Ñ…Ñ‚Ð°
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Ð›ÐµÑ Ñахарной ваты
+STR_0258_CANDY_FACTORY :{BLACK}Фабрика ÑладоÑтей
+STR_0259_BATTERY_FARM :{BLACK}Фабрика батареек
+STR_025A_COLA_WELLS :{BLACK}Завод колы
+STR_025B_TOY_SHOP :{BLACK}Магазин игрушек
+STR_025C_TOY_FACTORY :{BLACK}Фабрика игрушек
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Фонтан плаÑтика
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Завод шипучки
+STR_025F_BUBBLE_GENERATOR :{BLACK}Генератор пузырьков
+STR_0260_TOFFEE_QUARRY :{BLACK}Карьер ириÑок
+STR_0261_SUGAR_MINE :{BLACK}Ð¡Ð°Ñ…Ð°Ñ€Ð½Ð°Ñ ÑˆÐ°Ñ…Ñ‚Ð°
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}ПоÑтроить Угольную шахту
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}ПоÑтроить ЭлектроÑтанцию
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}ПоÑтроить ЛеÑопилку
+STR_0265_PLANT_FOREST :{BLACK}ПоÑадить ЛеÑ
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}ПоÑтроить нефтеперераб. завод
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}ПоÑтроить буровую платформу (возможно только у ÐºÑ€Ð°Ñ ÐºÐ°Ñ€Ñ‚Ñ‹)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}ПоÑтроить Фабрику
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}ПоÑтроить Сталелитейный завод
+STR_026A_CONSTRUCT_FARM :{BLACK}ПоÑтроить Ферму
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}ПоÑтроить шахту железной руды
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}ПоÑтроить ÐефтÑные Ñкважины
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}ПоÑтроить Банк (Возможно только в городе Ñ Ð½Ð°Ñелением более 1200)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}ПоÑтроить ЦБК
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}ПоÑтроить Пищевой завод
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}ПоÑтроить Типографию
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}ПоÑтроить Золотой прииÑк
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}ПоÑтроить Банк (Возможно только в городе)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}ПоÑтроить ЛеÑопилку (уничтожает джунгли и производит дерево)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Создать фруктовую плантацию
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Создать плантацию резины
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}ПоÑтроить водокачку
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}ПоÑтроить водонапорную башню (только в городе)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}ПоÑтроить Ðлмазную шахту
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}ПоÑтроить шахту медной руды
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}ПоÑадить Ð›ÐµÑ Ñахарной ваты
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}ПоÑтроить Конфетную фабрику
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}ПоÑтроить Фабрику батареек
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}ПоÑтроить Колодцы колы
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}ПоÑтроить Магазин игрушек
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}ПоÑтроить Фабрику игрушек
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}ПоÑтроить Фонтаны плаÑтика
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}ПоÑтроить завод газировки
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}ПоÑтроить Генератор пузырьков
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}ПоÑтроить Карьер ириÑок
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}ПоÑтроить Сахарную шахту
+STR_0285_CAN_T_BUILD_HERE :{WHITE}ЗдеÑÑŒ Ð½ÐµÐ»ÑŒÐ·Ñ Ñоздать {STRING} ...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...Ñначала поÑтройте город
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...такой объект уже еÑÑ‚ÑŒ в городе
+STR_0288_PLANT_TREES :{BLACK}Сажать деревьÑ
+STR_0289_PLACE_SIGN :{BLACK}ПомеÑтить знак
+STR_028A_RANDOM_TREES :{BLACK}Случайные деревьÑ
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}РазмеÑтить Ñлучайные Ð´ÐµÑ€ÐµÐ²ÑŒÑ Ð½Ð° карте
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}РазмеÑтить Ñкалы на карте
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}ПоÑтавить маÑк
+STR_028E_PLACE_TRANSMITTER :{BLACK}ПоÑтавить передатчик
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Задать площадь пуÑтыни.{}Ðажмите и держите CTRL Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ
+STR_CREATE_LAKE :{BLACK}Определить водный проÑтор.{} Затопит землю еÑли на уровне морÑ
+STR_0290_DELETE :{BLACK}Уничтожить
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}ПолноÑтью уничтожить Ñтот город
+STR_0292_SAVE_SCENARIO :Сохранить Ñценарий
+STR_0293_LOAD_SCENARIO :Загрузить Ñценарий
+STR_0294_QUIT_EDITOR :Выйти из редактора
+STR_0295 :
+STR_0296_QUIT :Выход
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Сохранить, загрузить Ñценарий, выход из редактора
+STR_0298_LOAD_SCENARIO :{WHITE}Загрузить Сценарий
+STR_0299_SAVE_SCENARIO :{WHITE}Сохранить Сценарий
+STR_029A_PLAY_SCENARIO :{BLACK}Играть Сценарий
+STR_PLAY_HEIGHTMAP :{BLACK}Играть РЕЛЬЕФ
+STR_PLAY_HEIGHTMAP_HINT :{BLACK}Ðачать новую игру, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð Ð•Ð›Ð¬Ð•Ð¤ в качеÑтве шаблона карты
+STR_QUIT_SCENARIO_QUERY :{YELLOW}Ð’Ñ‹ уверены что хотите выйти из Ñтого ÑÑ†ÐµÐ½Ð°Ñ€Ð¸Ñ ?
+STR_029C_QUIT_EDITOR :{WHITE}Выход из Редактора
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...может быть поÑтроен только в городах Ñ Ð½Ð°Ñелением не менее 1200
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Уменьшить год начала игры на 1
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Увеличить год начала игры на 1
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...оба конца моÑта должны опиратьÑÑ Ð½Ð° землю
+STR_02A1_SMALL :{BLACK}Малый
+STR_02A2_MEDIUM :{BLACK}Средний
+STR_02A3_LARGE :{BLACK}Большой
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Выбор размера города
+STR_02A5_TOWN_SIZE :{YELLOW}Размер города:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Показать поÑледнее Ñообщение или новоÑÑ‚ÑŒ
+STR_OFF :Выкл
+STR_SUMMARY :Кратко
+STR_FULL :Полно
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :СпиÑок городов
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}ÐÐ°Ð·Ð²Ð°Ð½Ð¸Ñ Ñ‚Ñ€Ð°Ð½Ñпорта
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :По умолчанию
+STR_02BF_CUSTOM :ПользовательÑкие
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Сохранить Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ñ‚Ñ€Ð°Ð½Ñпорта
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Выбор Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ñ‚Ñ€Ð°Ð½Ñпортных ÑредÑтв
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Сохранить пользовательÑкие Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ñ‚Ñ€Ð°Ð½Ñпорта
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Опции игры
+STR_02C5_DIFFICULTY_SETTINGS :Опции ÑложноÑти
+STR_02C7_CONFIG_PATCHES :ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð¿Ð°Ñ‚Ñ‡ÐµÐ¹
+STR_NEWGRF_SETTINGS :ÐаÑтройки NewGRF
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Показ названий городов
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Показ названий Ñтанций
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Показ знаков
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Вид Точки пути
+STR_02D0_FULL_ANIMATION :{SETX 12}ÐŸÐ¾Ð»Ð½Ð°Ñ Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ
+STR_02D2_FULL_DETAIL :{SETX 12}ÐŸÐ¾Ð»Ð½Ð°Ñ Ð´ÐµÑ‚Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Прозрачные зданиÑ
+STR_TRANSPARENT_SIGNS :{SETX 12}Прозрачный фон названий Ñтанций
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ земле
+STR_02D6 :
+STR_CONSOLE_SETTING :Переключатель КонÑоли
+STR_02D7_SCREENSHOT_CTRL_S :Снимок Ñкрана (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Полный Ñнимок Ñкрана (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :Об игре
+############ range ends here
+
+STR_02DB_OFF :{BLACK}Выкл
+STR_02DA_ON :{BLACK}Вкл
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Отображать ÑубÑидии
+STR_02DD_SUBSIDIES :СубÑидии
+STR_02DE_MAP_OF_WORLD :Карта мира
+STR_EXTRA_VIEW_PORT :Доп. окно проÑмотра
+STR_SIGN_LIST :СпиÑок меток
+STR_02DF_TOWN_DIRECTORY :СпиÑок городов
+STR_TOWN_POPULATION :{BLACK}ÐаÑеление: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Окно проÑмотра {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Скопировать позицию в окно проÑмотра
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Скопировать Ñту позицию в окно проÑмотра
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Ð’Ñтавить позицию из окна проÑмотра
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Ð’Ñтавить Ñту позицию из окна проÑмотра
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Денежные единицы
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Выбор валюты
+STR_MEASURING_UNITS :{BLACK}Единицы измерениÑ
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Выбор единиц измерениÑ
+STR_02E6_ROAD_VEHICLES :{BLACK}Ðаправление движениÑ
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Выберите тип движениÑ
+STR_02E9_DRIVE_ON_LEFT :ЛевоÑтороннее
+STR_02EA_DRIVE_ON_RIGHT :ПравоÑтороннее
+STR_02EB_TOWN_NAMES :{BLACK}ÐÐ°Ð·Ð²Ð°Ð½Ð¸Ñ Ð³Ð¾Ñ€Ð¾Ð´Ð¾Ð²
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Выбор ÑÑ‚Ð¸Ð»Ñ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ð³Ð¾Ñ€Ð¾Ð´Ð¾Ð²
+
+STR_02F4_AUTOSAVE :{BLACK}ÐвтоÑохранение
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Выбор интервала автоматичеÑкого ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¸Ð³Ñ€Ñ‹
+STR_02F7_OFF :Ðе ÑохранÑÑ‚ÑŒ
+STR_02F8_EVERY_3_MONTHS :Каждые 3 меÑÑца
+STR_02F9_EVERY_6_MONTHS :Каждые 6 меÑÑцев
+STR_02FA_EVERY_12_MONTHS :Каждый год
+STR_02FB_START_A_NEW_GAME :{BLACK}ÐÐ¾Ð²Ð°Ñ Ð¸Ð³Ñ€Ð°
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Загрузить игру
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Создать ÑобÑтвенную карту/Ñценарий
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Выбор одиночной игры
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Выбор Ñетевой игры 2-8 игроков
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Показать наÑтройки игры
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Показать наÑтройки ÑложноÑти
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Ðачать новую игру, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ñценарий
+STR_0304_QUIT :{BLACK}Выход
+STR_0305_QUIT_OPENTTD :{BLACK}Выход из 'OpenTTD'
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...можно Ñтроить только в городах
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Выбрать умеренный климат
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Выбрать арктичеÑкий климат
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Выбрать ÑубтропичеÑкий климат
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Выбрать игрушечный климат
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}ПрофинанÑировать Ñоздание нового предприÑтиÑ
+
+############ range for menu starts
+STR_INDUSTRY_DIR :СпиÑок предприÑтий
+STR_0313_FUND_NEW_INDUSTRY :Создать новое предприÑтие
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Создать новое предприÑтие
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...можно Ñтроить только в городах
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...можно Ñтроить только в тропиках
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...можно Ñтроить только в пуÑтыне
+STR_0319_PAUSED :{YELLOW}* * ПÐУЗР* *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Скриншот Ñохранен как '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}Ðе удалоÑÑŒ Ñохранить Ñкриншот
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Купить землю
+STR_032F_AUTOSAVE :{RED}ÐвтоÑохранение
+STR_SAVING_GAME :{RED}* * СОХРÐÐЯЮ ИГРУ * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}Сохранение вÑе еще идет,{}пожалуйÑта дождитеÑÑŒ завершениÑ!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Выбрать музыкальную программу
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :ÐнглийÑкие (Ориг.)
+STR_TOWNNAME_FRENCH :Французкие
+STR_TOWNNAME_GERMAN :ГерманÑкие
+STR_TOWNNAME_ADDITIONAL_ENGLISH :ÐнглийÑкие (Доп.)
+STR_TOWNNAME_LATIN_AMERICAN :Латино-ÐмериканÑкие
+STR_TOWNNAME_SILLY :Шуточные
+STR_TOWNNAME_SWEDISH :ШведÑкие
+STR_TOWNNAME_DUTCH :Ðемецкие
+STR_TOWNNAME_FINNISH :ФинÑкие
+STR_TOWNNAME_POLISH :ПольÑкие
+STR_TOWNNAME_SLOVAKISH :Словацкие
+STR_TOWNNAME_NORWEGIAN :ÐорвежÑкие
+STR_TOWNNAME_HUNGARIAN :ВенгерÑкие
+STR_TOWNNAME_AUSTRIAN :ÐвÑтрийÑкие
+STR_TOWNNAME_ROMANIAN :РимÑкие
+STR_TOWNNAME_CZECH :ЧешÑкие
+STR_TOWNNAME_SWISS :ШвейцарÑкие
+STR_TOWNNAME_DANISH :ДатÑкие
+STR_TOWNNAME_TURKISH :Турецкие
+STR_TOWNNAME_ITALIAN :ИтальÑнÑкие
+STR_TOWNNAME_CATALAN :КаталанÑкие
+############ end of townname region
+
+STR_CURR_GBP :Фунт (£)
+STR_CURR_USD :Доллар ($)
+STR_CURR_EUR :Евро (€)
+STR_CURR_YEN :Йена (¥)
+STR_CURR_ATS :ÐвÑтрийÑкий шиллинг (ATS)
+STR_CURR_BEF :БельгийÑкий Франк (BEF)
+STR_CURR_CHF :ШвейцарÑкий Форинт (CHF)
+STR_CURR_CZK :ЧешÑÐºÐ°Ñ ÐšÑ€Ð¾Ð½Ð° (CZK)
+STR_CURR_DEM :ÐÐµÐ¼ÐµÑ†ÐºÐ°Ñ ÐœÐ°Ñ€ÐºÐ° (DEM)
+STR_CURR_DKK :ДатÑÐºÐ°Ñ ÐšÑ€Ð¾Ð½Ð° (DKK)
+STR_CURR_ESP :ПеÑета (ESP)
+STR_CURR_FIM :ФинÑÐºÐ°Ñ ÐœÐ°Ñ€ÐºÐ° (FIM)
+STR_CURR_FRF :Франк (FRF)
+STR_CURR_GRD :ГречеÑÐºÐ°Ñ Ð”Ñ€Ð°Ñ…Ð¼Ð° (GRD)
+STR_CURR_HUF :ВенгерÑкий Форинт (HUF)
+STR_CURR_ISK :ИÑландÑÐºÐ°Ñ ÐšÑ€Ð¾Ð½Ð° (ISK)
+STR_CURR_ITL :ИтальÑнÑÐºÐ°Ñ Ð›Ð¸Ñ€Ð° (ITL)
+STR_CURR_NLG :Ðемецкий гульден (NLG)
+STR_CURR_NOK :ÐорвежÑÐºÐ°Ñ ÐšÑ€Ð¾Ð½Ð° (NOK)
+STR_CURR_PLN :ПольÑÐºÐ°Ñ Ð—ÐµÐ»Ð¾Ñ‚Ð° (PLN)
+STR_CURR_ROL :РимÑÐºÐ°Ñ Ð›ÐµÑ (ROL)
+STR_CURR_RUR :РоÑÑийÑкий Рубль (RUR)
+STR_CURR_SIT :СловенÑкий талер(SIT)
+STR_CURR_SEK :ШведÑÐºÐ°Ñ ÐšÑ€Ð¾Ð½Ð° (SEK)
+STR_CURR_YTL :Ð¢ÑƒÑ€ÐµÑ†ÐºÐ°Ñ Ð»Ð¸Ñ€Ð° (YTL)
+STR_CURR_SKK :Ð¡Ð»Ð¾Ð²Ð°Ñ†ÐºÐ°Ñ ÐºÐ¾Ñ€ÑƒÐ½Ð° (SKK)
+STR_CURR_BRR :БразильÑкий реал (BRL)
+
+STR_CURR_CUSTOM :Ручной...
+
+STR_OPTIONS_LANG :{BLACK}Язык
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Выбор Ñзыка интерфейÑа
+
+STR_OPTIONS_FULLSCREEN :{BLACK}ПолноÑкранный
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}Выберите Ð´Ð»Ñ Ð¸Ð³Ñ€Ñ‹ в полноÑкранном режиме (проверьте параметр display_hz в конфиге Ð´Ð»Ñ ÑƒÑтановки чаÑтоты Ñкрана в Ñтом режиме)
+
+STR_OPTIONS_RES :{BLACK}Разрешение Ñкрана
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Выбор Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ñкрана
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Формат Ñкриншота
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Выбор формата Ñкриншота
+
+STR_AUTOSAVE_1_MONTH :Каждый меÑÑц
+STR_AUTOSAVE_FAILED :{WHITE}Ошибка автоÑохранениÑ
+
+STR_MONTH_JAN :Январь
+STR_MONTH_FEB :Февраль
+STR_MONTH_MAR :Март
+STR_MONTH_APR :Ðпрель
+STR_MONTH_MAY :Май
+STR_MONTH_JUN :Июнь
+STR_MONTH_JUL :Июль
+STR_MONTH_AUG :ÐвгуÑÑ‚
+STR_MONTH_SEP :СентÑрь
+STR_MONTH_OCT :ОктÑбрь
+STR_MONTH_NOV :ÐоÑбрь
+STR_MONTH_DEC :Декабрь
+
+STR_HEADING_FOR_STATION :{LTBLUE}Идет к {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}Идет к {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Ðет заданий
+STR_NO_ORDERS_VEL :{LTBLUE}Ðет заданий, {VELOCITY}
+
+STR_PASSENGERS :паÑÑажиров
+STR_BAGS :багажа
+STR_TONS :тонн
+STR_LITERS :литров
+STR_ITEMS :штук
+STR_CRATES :мешков
+STR_RES_OTHER :прочее
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Ðевозможно Ñкопировать ÑпиÑок заданий...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Ðевозможно Ñкопировать ÑпиÑок заданий...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - Конец ÑпиÑка заданий - -
+
+STR_TRAIN_IS_LOST :{WHITE}Поезд {COMMA} не находит путь ...
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}Доход поезда {COMMA} за прошлый год ÑоÑтавил {CURRENCY}
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}Создана зона евро!{}{}Теперь в вашей Ñтране в качеÑтве единой валюты иÑпользуетÑÑ ÐµÐ²Ñ€Ð¾!
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Только одно задание в ÑпиÑке заданий Ð´Ð»Ñ Ð¿Ð¾ÐµÐ·Ð´Ð° {COMMA}
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}У поезда {COMMA} нет заданий
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}У поезда {COMMA} дублируютÑÑ Ð·Ð°Ð´Ð°Ð½Ð¸Ñ
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}У поезда {COMMA} неправильное меÑто назначениÑ
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}Только одно задание в ÑпиÑке заданий Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾ {COMMA}
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}У авто {COMMA} нет заданий
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}У Ð°Ð²Ñ‚Ð¾Ð¼Ð¾Ð±Ð¸Ð»Ñ {COMMA} дублируютÑÑ Ð·Ð°Ð´Ð°Ð½Ð¸Ñ
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}Ðеправильное задание в ÑпиÑке заданий у автомашины {COMMA}
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}Только одно задание в ÑпиÑке заданий Ð´Ð»Ñ ÐºÐ¾Ñ€Ð°Ð±Ð»Ñ {COMMA}
+STR_SHIP_HAS_VOID_ORDER :{WHITE}У ÐºÐ¾Ñ€Ð°Ð±Ð»Ñ {COMMA} нет заданий
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}У ÐºÐ¾Ñ€Ð°Ð±Ð»Ñ {COMMA} дублируютÑÑ Ð·Ð°Ð´Ð°Ð½Ð¸Ñ
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}У ÐºÐ¾Ñ€Ð°Ð±Ð»Ñ {COMMA} неправильное меÑто назначениÑ
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}Слишком мало заданий у {COMMA}
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}У транÑпорта {COMMA} нет заданий
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}У транÑпорта {COMMA} дублируютÑÑ Ð·Ð°Ð´Ð°Ð½Ð¸Ñ
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}У транÑпорта {COMMA} неправильное меÑто назначениÑ
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}Ошибка Ð°Ð²Ñ‚Ð¾Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð¿Ð¾ÐµÐ·Ð´Ð° {COMMA} (денег мало)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}Ошибка Ð°Ð²Ñ‚Ð¾Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ñ‚Ñ€Ð°Ð½Ñпорта {COMMA} (денег мало)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}Ошибка Ð°Ð²Ñ‚Ð¾Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð»Ñ ÐºÐ¾Ñ€Ð°Ð±Ð»Ñ {COMMA} (денег мало)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}Ошибка Ð°Ð²Ñ‚Ð¾Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð»Ñ {COMMA} (денег мало)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}Поезд {COMMA} Ñлишком длинный поÑле автозамены
+
+STR_CONFIG_PATCHES :{BLACK}ÐаÑтройка патчей
+STR_CONFIG_PATCHES_TIP :{BLACK}ÐаÑтройка патчей
+STR_CONFIG_PATCHES_CAPTION :{WHITE}ÐаÑтройка патчей
+
+STR_CONFIG_PATCHES_OFF :Выкл
+STR_CONFIG_PATCHES_ON :Вкл
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}СкороÑÑ‚ÑŒ транÑпорта в Ñтроке ÑтатуÑа: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Разрешить ÑтроительÑтво на Ñклонах и берегу: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Разрешить более реалиÑтичные зоны покрытиÑ: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Разрешить удалÑÑ‚ÑŒ больше дорог, моÑтов, Ñ‚.п.: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}ИÑпользовать очень длинные поезда: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Разрешить реалиÑтичное уÑкорение: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Запретить повороты на 90 град.: {ORANGE}{STRING} {LTBLUE} (требуетÑÑ NPF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}ОбъединÑÑ‚ÑŒ Ñтанции: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}При вкл. полной загрузке отправлÑÑ‚ÑŒÑÑ, когда заполнен один тип вагонов: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Улучшенный алгоритм загрузки: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GRADUAL_LOADING :{LTBLUE}ПоÑÑ‚ÐµÐ¿ÐµÐ½Ð½Ð°Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ° транÑпорта: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}ИнфлÑциÑ: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}ДоÑтавлÑÑ‚ÑŒ груз на Ñтанцию, только еÑли она его принимает: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Строить очень длинные моÑÑ‚Ñ‹: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}ДобавлÑÑ‚ÑŒ депо в раÑпиÑание: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Разрешить ÑтроительÑтво Ñырьевых предприÑтий: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Строить неÑк. предприÑтий 1 типа в одном городе: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Одинаковые предприÑÑ‚Ð¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ Ñтроить Ñ€Ñдом: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Ð’Ñегда отобр. длинную дату в Ñтроке ÑоÑтоÑниÑ: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Сигналы на Ñтороне движениÑ: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Отображать фин. информацию в конце года: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}Приказ без оÑтановки в Ñтиле TTDPatch: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Разрешить ожидание въезда на автоÑтанцию: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}ÐвтоÑкроллинг: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Разрешить взÑтку меÑтной админиÑтрации: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Станции могут быть разной формы: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Ðовый поиÑк пути (NPF, без NTP): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FREIGHT_TRAINS :{LTBLUE}КоÑÑ„. ÑƒÐ²ÐµÐ»Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð²ÐµÑа груза: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Ð’Ñегда разрешать малые аÑропорты: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Предупреждать, еÑли поезд не находит дороги: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}ПереÑмотреть раÑпиÑаниÑ: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :нет
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :да, кроме оÑтановленных транÑп. ÑредÑтв
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :вÑего транÑпорта
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Предупреждать, что транÑп. ÑредÑтво приноÑит убыток: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}ТранÑпорт никогда не уÑтаревает: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}ÐвтоматичеÑки обновлÑÑ‚ÑŒ уÑтаревший транÑпорт
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Обновить транÑпорт за (через) {ORANGE}{STRING}{LTBLUE} меÑ. поÑле уÑтареваниÑ
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Минимум денег Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}ДлительноÑÑ‚ÑŒ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¾Ð± ошибке: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Показ. кол-во наÑеление вмеÑте Ñ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸ÐµÐ¼ города: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Ðевидимые Ð´ÐµÑ€ÐµÐ²ÑŒÑ (Ñ Ð¿Ñ€Ð¾Ð·Ñ€Ð°Ñ‡Ð½Ñ‹Ð¼Ð¸ зданиÑми): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Генератор земли: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :Оригинальный
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis
+STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}МакÑ. диÑÑ‚Ð°Ð½Ñ†Ð¸Ñ Ð¾Ñ‚ ÐºÑ€Ð°Ñ ÐºÐ°Ñ€Ñ‚Ñ‹ до Ðефтепер. завода {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Ð’Ñ‹Ñота "Ñнежной" линии: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN :{LTBLUE}ÐеровноÑÑ‚ÑŒ земли (только Ð´Ð»Ñ TerraGenesis) : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Очень гладкий
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH :Гладкий
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH :Грубый
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :Очень грубый
+STR_CONFIG_PATCHES_TREE_PLACER :{LTBLUE}Ðлгоритм раÑÑадки деревьев: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TREE_PLACER_NONE :Ðет
+STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL :Оригинальный
+STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED :Продвинутый
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION :{LTBLUE}Вращение ЛÐÐДШÐФТÐ: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Против чаÑовой
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE :По чаÑовой
+STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT :{LTBLUE}Уровень выÑоты Ð´Ð»Ñ ÐºÐ°Ñ€Ñ‚ Ñ Ð¿Ð»Ð¾Ñким рельефом: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}МакÑ. площадь Ñтанции : {ORANGE}{STRING} {RED}Большие Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð·Ð°Ð¼ÐµÐ´Ð»ÑÑŽÑ‚ игру
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}ÐвтоматичеÑки обÑлуживать вертолеты в вертопортах: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}"Прилепить" ландшафтную панель к транÑп. панелÑм: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Обратить направление Ñкроллинга: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Показывать размеры ÑтроительÑтва в подÑказке: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Показывать цвета компаний: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES_NONE :Ðет
+STR_CONFIG_PATCHES_LIVERIES_OWN :Ð¡Ð²Ð¾Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ñ
+STR_CONFIG_PATCHES_LIVERIES_ALL :Ð’Ñе компании
+STR_CONFIG_PATCHES_PREFER_TEAMCHAT :{LTBLUE}Командный чат по <ENTER>: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}МакÑ. кол-во поездов у игрока: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}МакÑ. кол-во автотранÑпорта у игрока: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}МакÑ. кол-во авиатранÑпорта у игрока: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}МакÑ. кол-во кораблей у игрока: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Отключить поезда Ð´Ð»Ñ ÐºÐ¾Ð¼Ð¿ÑŒÑŽÑ‚ÐµÑ€Ð°: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Отключить машины Ð´Ð»Ñ ÐºÐ¾Ð¼Ð¿ÑŒÑŽÑ‚ÐµÑ€Ð°: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Отключить Ñамолеты Ð´Ð»Ñ ÐºÐ¾Ð¼Ð¿ÑŒÑŽÑ‚ÐµÑ€Ð°: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Отключить корабли Ð´Ð»Ñ ÐºÐ¾Ð¼Ð¿ÑŒÑŽÑ‚ÐµÑ€Ð°: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Включить новый ИИ (ИИ альфа): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Разрешить ИИ в Ñетевой игре (теÑÑ‚): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Интервал обÑÐ»ÑƒÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾ÐµÐ·Ð´Ð¾Ð²: {ORANGE}{STRING} дней/%
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Интервал обÑÐ»ÑƒÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾ÐµÐ·Ð´Ð¾Ð²: {ORANGE}отключено
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Интервал обÑÐ»ÑƒÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð°Ð²Ñ‚Ð¾Ð¼Ð¾Ð±Ð¸Ð»ÐµÐ¹: {ORANGE}{STRING} дней/%
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Интервал обÑÐ»ÑƒÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð°Ð²Ñ‚Ð¾Ð¼Ð¾Ð±Ð¸Ð»ÐµÐ¹: {ORANGE}отключено
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Интервал обÑÐ»ÑƒÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ñамолетов: {ORANGE}{STRING} дней/%
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Интервал обÑÐ»ÑƒÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ñамолетов: {ORANGE}отключено
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Интервал обÑÐ»ÑƒÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ ÐºÐ¾Ñ€Ð°Ð±Ð»ÐµÐ¹: {ORANGE}{STRING} дней/%
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Интервал обÑÐ»ÑƒÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ ÐºÐ¾Ñ€Ð°Ð±Ð»ÐµÐ¹: {ORANGE}отключено
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Ðе обÑлуживать, еÑли поломки выкл. : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Включить ограничение ÑкороÑти вагонов: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}Откл. Ñлектрофицир. ЖД: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}"Цветные" новоÑти поÑвл. в : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Год начала игры: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}Год Ð¾ÐºÐ¾Ð½Ñ‡Ð°Ð½Ð¸Ñ Ð¸Ð³Ñ€Ñ‹: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Включить плавную Ñкономику (более мелкие изменениÑ)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Разрешить покупать акции других компаний
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}При перетаÑкивании Ñтавить Ñигналы каждые : {ORANGE}{STRING} клетки
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Положение главной панели инÑтрументов: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Лево
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Центр
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Право
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Ð Ð°Ð´Ð¸ÑƒÑ Ð¿Ñ€Ð¸Ð»Ð¸Ð¿Ð°Ð½Ð¸Ñ Ð¾ÐºÐ¾Ð½: {ORANGE}{STRING} пиÑкелей
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Ð Ð°Ð´Ð¸ÑƒÑ Ð¿Ñ€Ð¸Ð»Ð¸Ð¿Ð°Ð½Ð¸Ñ Ð¾ÐºÐ¾Ð½: {ORANGE}отключено
+
+STR_CONFIG_PATCHES_GUI :{BLACK}ИнтерфейÑ
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}СтроительÑтво
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}ТранÑпорт
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Станции
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Экономика
+STR_CONFIG_PATCHES_AI :{BLACK}Противники
+
+STR_CONFIG_PATCHES_DISABLED :отключено
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Изменить значение
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Ðекоторые из выбранных интервалов обÑÐ»ÑƒÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ ÑовмеÑтимы Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð¾Ð¹ уÑтановкой. ДопуÑкаютÑÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸ 5-90% или 30-800 дней.
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}ИÑп. YAPF Ð´Ð»Ñ ÐºÐ¾Ñ€Ð°Ð±Ð»ÐµÐ¹: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}ИÑп. YAPF Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}ИÑп. YAPF Ð´Ð»Ñ Ð¿Ð¾ÐµÐ·Ð´Ð¾Ð²: {ORANGE}{STRING}
+
+STR_TEMPERATE_LANDSCAPE :Умеренный ландшафт
+STR_SUB_ARCTIC_LANDSCAPE :СубарктичеÑкий ландшафт
+STR_SUB_TROPICAL_LANDSCAPE :СубтропичеÑкий ландшафт
+STR_TOYLAND_LANDSCAPE :Игрушечный ландшафт
+
+STR_CHEATS :{WHITE}ЧИТЫ
+STR_CHEATS_TIP :{BLACK}Галочка показывает иÑпользовали ли Ð’Ñ‹ Ñтот ЧИТ раньше
+STR_CHEATS_WARNING :{BLACK}Внимание, вы ÑобираетеÑÑŒ предать Ñвоих Ñоперников! Этого вам никогда не проÑÑ‚ÑÑ‚!
+STR_CHEAT_MONEY :{LTBLUE}Увеличение денег на {CURRENCY64}
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}УправлÑÑ‚ÑŒ игроком: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Волшебный бульдозер (удалÑет промышленноÑÑ‚ÑŒ и Ñ‚.п.): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Туннели могут переÑекатьÑÑ: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Строить в режиме паузы: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Большие Ñамолеты не будут чаÑто разбиватьÑÑ Ð² маленьких аÑропортах: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Сменить климат на: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Изменение даты: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}Разрешить изменение производительноÑти: {ORANGE}{STRING}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}Следует к {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Следует к {WAYPOINT}, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :Идти через {WAYPOINT}
+STR_GO_NON_STOP_TO_WAYPOINT :Идти б/оÑтан. через {WAYPOINT}
+
+STR_WAYPOINTNAME_CITY :Точка пути {TOWN}
+STR_WAYPOINTNAME_CITY_SERIAL :Точка пути {TOWN} #{COMMA}
+STR_LANDINFO_WAYPOINT :Точка пути
+
+STR_WAYPOINT :{WHITE}Точка пути
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Выбор типа Точки пути
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}Переименовать точку пути
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Ðевозможно переименовать точку пути...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Превратить рельÑÑ‹ в точку пути
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Ðевозможно поÑтроить точку пути здеÑÑŒ...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Ðевозможно удалить точку пути здеÑÑŒ...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Строить ж/д путь, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ñ€ÐµÐ¶Ð¸Ð¼ ÐвторельÑа
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}...в Ñтом Ñценарии нет никакого города
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}Ð’Ñ‹ уверены что хотите Ñоздать Ñлучайную землю?
+STR_MANY_RANDOM_TOWNS :{BLACK}Много Ñлучайных городов
+STR_RANDOM_TOWNS_TIP :{BLACK}Случайно размеÑтить на карте города
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Много произвольных промышленноÑтей
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Случайно размеÑтить предприÑÑ‚Ð¸Ñ Ð½Ð° карте
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Ðевозможно Ñоздать промышленноÑÑ‚ÑŒ...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Открыть панель ландшафта Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñ€ÐµÐ»ÑŒÐµÑ„Ð°, поÑадки деревьев и Ñ‚.д.
+STR_LANDSCAPING_TOOLBAR :{WHITE}Ландшафт
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Ð Ð¾Ð²Ð½Ð°Ñ Ð·ÐµÐ¼Ð»Ð¸
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Ð”ÐµÑ€ÐµÐ²ÑŒÑ Ñлучайного типа
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}РазмеÑтить Ð´ÐµÑ€ÐµÐ²ÑŒÑ Ñлучайного типа
+
+STR_CANT_BUILD_CANALS :{WHITE}Ðевозможно поÑтроить канал здеÑÑŒ...
+STR_BUILD_CANALS_TIP :{BLACK}Проложить канал.
+STR_LANDINFO_CANAL :Канал
+
+STR_CANT_BUILD_LOCKS :{WHITE}Ðевозможно поÑтроить шлюз здеÑÑŒ...
+STR_BUILD_LOCKS_TIP :{BLACK}ПоÑтроить шлюзы
+STR_LANDINFO_LOCK :Шлюз
+
+STR_BUOY_IS_IN_USE :{WHITE}...Ñтот буй иÑпользуетÑÑ!
+
+STR_LANDINFO_COORDS :{BLACK}Координаты: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Ðевозможно удалить чаÑÑ‚ÑŒ Ñтанции...
+STR_CANT_CONVERT_RAIL :{WHITE}Ðевозможно преобразовать тип рельÑа здеÑÑŒ...
+STR_CONVERT_RAIL_TIP :{BLACK}Преобразовать/Модернизировать тип рельÑов
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Перетащите Ñюда локомотив Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð°Ð¶Ð¸ вÑего поезда
+
+STR_DRAG_DROP :{BLACK}ПеретаÑкивание
+STR_STATION_DRAG_DROP :{BLACK}Строить Ñтанцию иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð¿ÐµÑ€ÐµÑ‚Ð°Ñкивание
+STR_SELECT_STATION_CLASS_TIP :{BLACK}Выберите клаÑÑ Ñтанций Ð´Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Выберите тип Ñтанции Ð´Ð»Ñ Ð¿Ð¾Ñтройки
+
+STR_FAST_FORWARD :{BLACK}УÑкорить игры
+STR_MESSAGE_HISTORY :{WHITE}ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ð¡Ð¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ð¹
+STR_MESSAGE_HISTORY_TIP :{BLACK}СпиÑок недавних новоÑтей
+STR_MESSAGES_DISABLE_ALL :{BLACK}Выключить вÑе
+STR_MESSAGES_ENABLE_ALL :{BLACK}Включить вÑе
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}ПоÑтроить Угольную Шахту
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Ð’Ñ‹Ñадить ЛеÑ
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}ПоÑтроить нефтеперераб. завод
+STR_CONSTRUCT_FARM_TIP :{BLACK}ПрофинанÑировать ферму
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}ПоÑтроить шахту медной руды
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Пробурить нефт. Ñкважину
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}ПоÑтроить золотую шахту
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}ПоÑтроить алмазные копи
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}ПоÑтроить шахту жел. руды
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}ПрофинанÑировать плантации фруктов
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Ð’Ñ‹Ñадить плантации резины
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}ПрофинанÑировать вододобычу
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Ð’Ñ‹Ñадить Ð›ÐµÑ Ð¡Ð°Ñ…Ð°Ñ€Ð½Ð¾Ð¹ Ваты
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}СпонÑировать ферму батареек
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Вырыть колодцы колы
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}ПоÑтроить фонтаны плаÑтика
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}ПоÑтроить Генератор Пузырьков
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}ПрофинанÑировать Карьер ИриÑок
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}ПоÑтроить шахту Ñахара
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}ПромышленноÑÑ‚ÑŒ
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA}% перевезено)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA}%/{COMMA}% перевезено)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}...Ñлишком близко к другому предприÑтию
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Переоборудование поезда Ð´Ð»Ñ Ð¸Ð½Ð¾Ð³Ð¾ типа груза
+STR_RAIL_REFIT_VEHICLE :{BLACK}Переоборудовать поезда
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Выбор типа груза Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ð¾Ð·ÐºÐ¸
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Переоборудование поезда Ð´Ð»Ñ Ð²Ñ‹Ð´ÐµÐ»ÐµÐ½Ð½Ð¾Ð³Ð¾ типа груза
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Ðе могу переоборуд. поезд...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Интервал обÑÐ»ÑƒÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð² процентах: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Изменить производительноÑÑ‚ÑŒ
+
+TEMP_AI_IN_PROGRESS :{WHITE}Добро пожаловать в новый ИИ, он ÑовершенÑтвуетÑÑ. Ð’Ñ‹ должны быть готовы к проблемам. Когда Ñто ÑлучитÑÑ Ñделайте Ñнимок и отправьте на форум. ÐаÑлаждайтеÑÑŒ!
+TEMP_AI_ACTIVATED :{WHITE}Внимание: Ñто новый ИИ еще теÑтируетÑÑ! Ð’ наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ð°ÐµÑ‚ только Ñ Ð³Ñ€ÑƒÐ·Ð¾Ð²Ð¸ÐºÐ°Ð¼Ð¸ и автобуÑами!
+TEMP_AI_MULTIPLAYER :{WHITE}Внимание: теÑтовое иÑпользование (новый ИИ). ПожалуйÑта Ñообщайте обо вÑех проблемах на truelight@openttd.org.
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Ð¡ÐµÑ‚ÐµÐ²Ð°Ñ Ð¸Ð³Ñ€Ð°
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Ð˜Ð¼Ñ Ð¸Ð³Ñ€Ð¾ÐºÐ°:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}Это Ð¸Ð¼Ñ Ð¿Ð¾ которому другие игроки определÑÑŽÑ‚ ваÑ
+STR_NETWORK_CONNECTION :{BLACK}Соединение:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Выбор между Интернет игрой или игрой в Локальной Сети (СЕТЬ)
+
+STR_NETWORK_START_SERVER :{BLACK}ЗапуÑк Ñервера
+STR_NETWORK_START_SERVER_TIP :{BLACK}ЗапуÑк Ñвоего Ñервера
+
+STR_NETWORK_GAME_NAME :{BLACK}Ðазвание
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Ðазвание игры
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Язык, верÑÐ¸Ñ Ñервера, и Ñ‚.п.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Выберите игру из ÑпиÑка
+
+STR_NETWORK_FIND_SERVER :{BLACK}Ðайти Ñервер
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Ðайти Ñервер в Ñети
+STR_NETWORK_ADD_SERVER :{BLACK}Добавить Ñервер
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Добавить Ñервер в ÑпиÑок, который будет вÑегда проверÑÑ‚ÑŒÑÑ Ð¿Ñ€Ð¸ запуÑке игр.
+STR_NETWORK_ENTER_IP :{BLACK}ВвеÑти Ð°Ð´Ñ€ÐµÑ Ñервера
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Клиенты
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Клиентов ÑейчаÑ/макÑ. {}Компаний ÑейчаÑ/макÑ.
+STR_NETWORK_GAME_INFO :{SILVER}ИÐФОРМÐЦИЯ ОБ ИГРЕ
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Клиенты: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Язык: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Климат: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Размер карты: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}ВерÑÐ¸Ñ Ñервера: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}ÐÐ´Ñ€ÐµÑ Ñервера: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Дата начала: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Ð¢ÐµÐºÑƒÑ‰Ð°Ñ Ð´Ð°Ñ‚Ð°: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Защищено паролем!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}СЕРВЕР ОТКЛЮЧЕÐ
+STR_NETWORK_SERVER_FULL :{SILVER}СЕРВЕР ЗÐПОЛÐЕÐ
+STR_NETWORK_VERSION_MISMATCH :{SILVER}ВЕРСИЯ ÐЕ ПОДХОДИТ
+STR_NETWORK_GRF_MISMATCH :{SILVER}ÐЕ СОВПÐДÐЕТ ÐÐБОР NEWGRF
+
+STR_NETWORK_JOIN_GAME :{BLACK}ПриÑоединитьÑÑ Ðº игре
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}ЗапуÑк новой Ñетевой игры
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Ðазвание игры:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}Ðазвание игры будет показано другим игрокам в меню выбора ÑÐµÑ‚ÐµÐ²Ð°Ñ Ð¸Ð³Ñ€Ð°
+STR_NETWORK_SET_PASSWORD :{BLACK}Задать пароль
+STR_NETWORK_PASSWORD_TIP :{BLACK}Защитите вашу игру паролем еÑли не хотите Ñвободного доÑтупа
+STR_NETWORK_SELECT_MAP :{BLACK}Выбор карты:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}Какую карту вы хотите играть?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}МакÑ. клиентов:
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Выбор макÑимального чиÑла клиентов. Ðе вÑе меÑта должны быть занÑÑ‚Ñ‹
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :Ð›Ð¾ÐºÐ°Ð»ÑŒÐ½Ð°Ñ Ñеть
+STR_NETWORK_INTERNET :Интернет
+STR_NETWORK_LAN_INTERNET :СЕТЬ / Интернет
+STR_NETWORK_INTERNET_ADVERTISE :Интернет (объÑвленный)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 игроков
+STR_NETWORK_1_PLAYERS :1 игрок
+STR_NETWORK_2_PLAYERS :2 игрока
+STR_NETWORK_3_PLAYERS :3 игрока
+STR_NETWORK_4_PLAYERS :4 игрока
+STR_NETWORK_5_PLAYERS :5 игроков
+STR_NETWORK_6_PLAYERS :6 игроков
+STR_NETWORK_7_PLAYERS :7 игроков
+STR_NETWORK_8_PLAYERS :8 игроков
+STR_NETWORK_9_PLAYERS :9 игроков
+STR_NETWORK_10_PLAYERS :10 игроков
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}МакÑ. компаний:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Ограничить макÑимальное чиÑло компаний на Ñервере
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}МакÑ. наблюдателей:
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Ограничить макÑимальное количеÑтво наблюдателей на Ñервере
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Язык общениÑ:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Другие игроки будут знать, на каком Ñзыке говорÑÑ‚ на Ñервере
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}ЗапуÑк Игры
+STR_NETWORK_START_GAME_TIP :{BLACK}ЗапуÑк новой Ñетевой игры Ñ Ð¿Ñ€Ð¾Ð¸Ð·Ð²Ð¾Ð»ÑŒÐ½Ð¾Ð¹ карты или ÑценариÑ
+STR_NETWORK_LOAD_GAME :{BLACK}Загрузка Игры
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Продолжить ранее Ñохраненную Ñетевую игру (проверьте что подÑоединилиÑÑŒ прежним игроком)
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Любой
+STR_NETWORK_LANG_ENGLISH :ÐнглийÑкий
+STR_NETWORK_LANG_GERMAN :Ðемецкий
+STR_NETWORK_LANG_FRENCH :ФранцузÑкий
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}СоÑтоÑние Ñетевой игры
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Подготовка ÑоединениÑ: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}СпиÑок компаний в игре. Ð’Ñ‹ можете приÑоединитьÑÑ Ðº ÑущеÑтвующией или оÑновать новую, еÑли еÑÑ‚ÑŒ Ñ‚Ð°ÐºÐ°Ñ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ÑŒ
+STR_NETWORK_NEW_COMPANY :{BLACK}ÐÐ¾Ð²Ð°Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ñ
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Создать новую компанию
+STR_NETWORK_SPECTATE_GAME :{BLACK}Ðаблюдать игру
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Быть в роли наблюдателÑ
+STR_NETWORK_JOIN_COMPANY :{BLACK}ПриÑоединитьÑÑ Ðº компании
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Помочь управлением Ñтой компании
+STR_NETWORK_REFRESH :{BLACK}Обновить Ñервер
+STR_NETWORK_REFRESH_TIP :{BLACK}Обновить информацию о Ñервера
+
+STR_NETWORK_COMPANY_INFO :{SILVER}ИÐФОРМÐЦИЯ О КОМПÐÐИИ
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Ð˜Ð¼Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ð¸: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}ОÑнована: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}Капитал компании: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Текущий баланÑ: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Доход прошлого года: {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}ПроизводительноÑÑ‚ÑŒ: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}ТранÑпорт: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Станции: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Игроки: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}СоединÑÑŽÑÑŒ...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) СоединÑÑŽÑÑŒ..
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) ПредÑтавлÑÑŽÑÑŒ..
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Ожидаю..
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Загружаю карту..
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Передача данных..
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) РегиÑтрируюÑÑŒ..
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Получаю информацию игры..
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Получаю информацию о компании..
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}готовитÑÑ Ð¿Ñ€Ð¸ÑоединитьÑÑ {NUM} клиентов
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} кбайт загружено
+
+STR_NETWORK_DISCONNECT :{BLACK}ОтключитьÑÑ
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Сумма денег, которую хотите передать
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Сервер защищен. Введите пароль
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}ÐšÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ñ Ð·Ð°Ñ‰Ð¸Ñ‰ÐµÐ½Ð°. Введите пароль
+STR_NETWORK_CLIENT_LIST :{WHITE}СпиÑок Клиентов
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE} Ðе найдено Ñетевых уÑтройÑтв или игра Ñкомпилирована без ENABLE_NETWORK (поддержки Ñети)
+STR_NETWORK_ERR_NOSERVER :{WHITE} Ðе Ñмог найти Ñетевые игры
+STR_NETWORK_ERR_NOCONNECTION :{WHITE} Сервер не ответил на запроÑ
+STR_NETWORK_ERR_DESYNC :{WHITE} Ð¡Ð¸Ð½Ñ…Ñ€Ð¾Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ Ñетевой игры не удалаÑÑŒ
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} Соединение Ñетевой игры потерÑно
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} Ðе Ñмог загрузить Ñохранение
+STR_NETWORK_ERR_SERVER_START :{WHITE} Ðе Ñмог запуÑтить Ñервер
+STR_NETWORK_ERR_CLIENT_START :{WHITE} Ðе Ñмог ÑоединитьÑÑ
+STR_NETWORK_ERR_TIMEOUT :{WHITE} Тайм-аут Ð´Ð»Ñ ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ #{NUM}
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE} Произошла ошибка протокола и Ñоединение было закрыто
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE} ВерÑÐ¸Ñ Ñтого клиента не ÑовмеÑтима Ñ Ð²ÐµÑ€Ñией Ñервера
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} Ðеверный пароль
+STR_NETWORK_ERR_SERVER_FULL :{WHITE} Сервер переполнен
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} Ð’Ñ‹ забанены на Ñтом Ñервере
+STR_NETWORK_ERR_KICKED :{WHITE} Вы выкинуты из игры
+STR_NETWORK_ERR_CHEATER :{WHITE} Чит-коды не разрешены на Ñтом Ñервере
+
+STR_NETWORK_ERR_LEFT :покинул игру
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :Ð¾Ð±Ñ‰Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°
+STR_NETWORK_ERR_CLIENT_DESYNC :ошибка Ñинхронизации
+STR_NETWORK_ERR_CLIENT_SAVEGAME :не Ñмог загрузить карту
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :Ñоединение потерÑно
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :ошибка протокола
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :не авторизован
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :получен Ñтранный пакет
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :верÑии не Ñовпадают
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :Ð¸Ð¼Ñ ÑƒÐ¶Ðµ иÑпользуетÑÑ
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :неверный пароль
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :неверный id-игрока в DoCommand
+STR_NETWORK_ERR_CLIENT_KICKED :выкинут Ñервером
+STR_NETWORK_ERR_CLIENT_CHEATER :пробовал читерить
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :Ñервер переполнен
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :приÑоединилÑÑ Ðº игре
+STR_NETWORK_GIVE_MONEY :передал вашей компании немного денег ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :вы передали {STRING} немного денег ({CURRENCY})
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Команда] :
+STR_NETWORK_CHAT_COMPANY :[Команде] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Команде] К {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[Лично] :
+STR_NETWORK_CHAT_CLIENT :[Лично] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[Лично] К {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[Ð’Ñем] :
+STR_NETWORK_CHAT_ALL :[Ð’Ñем] {STRING}: {GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :изменил его/ее Ð¸Ð¼Ñ Ð½Ð°
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE} Сервер закрыл ÑеÑÑию
+STR_NETWORK_SERVER_REBOOT :{WHITE} Сервер перезапуÑкаетÑÑ...{}ПожалуйÑта ждите...
+
+STR_NETWORK_SERVER :Сервер
+STR_NETWORK_CLIENT :Клиент
+STR_NETWORK_SPECTATORS :Ðаблюдатели
+
+STR_NETWORK_CLIENTLIST_NONE :(пуÑто)
+STR_NETWORK_CLIENTLIST_KICK :Выкинуть
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Передать денег
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Сказать вÑем
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Говорить Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸ÐµÐ¹
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Личное Ñообщение
+
+
+STR_NETWORK_SEND :{BLACK}ПоÑлать
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}Горизонтальный размер карты: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Вертикальный размер карты: {ORANGE}{STRING}
+
+
+##### PNG-MAP-Loader
+
+STR_PNGMAP_ERROR :{WHITE}Ðе могу загрузить ландшафт из PNG...
+STR_PNGMAP_ERR_FILE_NOT_FOUND :{WHITE}...файл не найден.
+STR_PNGMAP_ERR_IMAGE_TYPE :{WHITE}...не могу преобразовать тип изображениÑ. Треб. PNG 8 или 24-bit глубины цвета.
+STR_PNGMAP_ERR_MISC :{WHITE}...что-то пошло не так. Извините. (возможно файл поврежден)
+
+STR_BMPMAP_ERROR :{WHITE}Ðе могу загрузить ЛÐÐДШÐФТ из BMP...
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}...невозможно преобразовать тип изображениÑ.
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Цена: {CURRENCY}
+STR_0801_COST :{RED}Цена: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Доход: {CURRENCY}
+STR_0803_INCOME :{GREEN}Доход: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}ТранÑфер: {CURRENCY}
+STR_FEEDER :{YELLOW}ТранÑфер: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}ÐŸÑ€ÐµÐ´Ð¿Ð¾Ð»Ð°Ð³Ð°ÐµÐ¼Ð°Ñ Ñ†ÐµÐ½Ð°: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Предполагаемый Доход: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Ðевозможно повыÑить уровень земли здеÑÑŒ ...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Ðевозможно понизить уровень земли здеÑÑŒ ...
+STR_080A_ROCKS :Скалы
+STR_080B_ROUGH_LAND :Ð“Ñ€ÑƒÐ±Ð°Ñ Ð·ÐµÐ¼Ð»Ñ
+STR_080C_BARE_LAND :Ð“Ð¾Ð»Ð°Ñ Ð·ÐµÐ¼Ð»Ñ
+STR_080D_GRASS :Трава
+STR_080E_FIELDS :ПолÑ
+STR_080F_SNOW_COVERED_LAND :ЗаÑÐ½ÐµÐ¶ÐµÐ½Ð½Ð°Ñ Ð·ÐµÐ¼Ð»Ñ
+STR_0810_DESERT :ПуÑтынÑ
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Ðеверный уклон земли
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}ÐÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð°Ñ ÐºÐ¾Ð¼Ð±Ð¸Ð½Ð°Ñ†Ð¸Ñ Ð¿ÑƒÑ‚ÐµÐ¹
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}ЗемлÑные работы разрушат туннель
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Уже на уровне морÑ
+STR_1004_TOO_HIGH :{WHITE}Слишком выÑоко
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Ðет подходÑщих рельÑов
+STR_1007_ALREADY_BUILT :{WHITE}...уже поÑтроено
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Сначала надо удалить рельÑÑ‹
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Железные дороги
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}СтроительÑтво Ñлектрофиц. ЖД
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}МонорельÑÑ‹
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}Магнитные поезда
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Выберите железнодорожный моÑÑ‚
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Ðевозможно поÑтроить депо здеÑÑŒ...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Ðевозможно поÑтроить Ñтанцию здеÑÑŒ...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Ðевозможно поÑтроить Ñветофор здеÑÑŒ...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Ðевозможно проложить здеÑÑŒ рельÑÑ‹...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Ðевозможно удалить рельÑÑ‹...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Ðевозможно удалить Ñветофор...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Выбрать направление депо
+STR_1015_RAILROAD_CONSTRUCTION :СтроительÑтво ЖД
+STR_TOOLB_ELRAIL_CONSTRUCTION :СтроительÑтво Ñлектрофиц. ЖД
+STR_1016_MONORAIL_CONSTRUCTION :СтроительÑтво монорельÑа
+STR_1017_MAGLEV_CONSTRUCTION :СтроительÑтво магнитного транÑпорта
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Проложить рельÑÑ‹
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}ПоÑтроить депо (Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð¾Ð±Ñ€ÐµÑ‚ÐµÐ½Ð¸Ñ Ð¸ обÑÐ»ÑƒÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾ÐµÐ·Ð´Ð¾Ð²)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}ПоÑтроить новую Ñтанцию
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}УÑтановить Ñигналы
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}ПоÑтроить железнодорожный моÑÑ‚
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Строить железнодорожный туннель
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Переключение ÑтроительÑва/ÑƒÐ½Ð¸Ñ‡Ñ‚Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð–Ð” путей и Ñигналов
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}ПоÑтройки моÑта - кликните на том изображении моÑта, который вы хотите поÑтроить
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Выбор направление депо
+STR_1021_RAILROAD_TRACK :РельÑÑ‹
+STR_1023_RAILROAD_TRAIN_DEPOT :Ж/Д депо
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...облаÑÑ‚ÑŒ занÑта другой компанией
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :Ж/Д путь Ñ Ð¾Ð±Ñ‹Ñ‡Ð½Ñ‹Ð¼ Ñигналом
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :Ж/Д путь Ñ Ð¿Ñ€ÐµÑигналами
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :Ж/Д путь Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð½Ñ‹Ð¼Ð¸ Ñигналами
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :Ж/Д путь Ñ ÐºÐ¾Ð¼Ð±Ð¸Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ñ‹Ð¼Ð¸ Ñигналами
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Сначала удалите дорогу
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Идут дорожные работы ...
+STR_1802_ROAD_CONSTRUCTION :{WHITE}СтроительÑтво дорог
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Выберите тип моÑта
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Ðе могу проложить дорогу здеÑÑŒ...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Ðе могу удалить дорогу...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Ðаправление гаража
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Ðевозможно поÑтроить здеÑÑŒ гараж...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Ðевозможно поÑтроить оÑтановку здеÑÑŒ...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Ðе могу поÑтроить грузовую Ñтанцию...
+STR_180A_ROAD_CONSTRUCTION :СтроительÑтво дорог
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Проложить дорогу
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}ПоÑтроить гараж (Ð´Ð»Ñ Ð·Ð°ÐºÑƒÐ¿ÐºÐ¸ и обÑÐ»ÑƒÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð°Ð²Ñ‚Ð¾)
+STR_180D_BUILD_BUS_STATION :{BLACK}ПоÑтроить автобуÑную оÑтановку
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}ПоÑтроить погрузочную Ñтанцию
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}ПоÑтроить моÑÑ‚ (авто)
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}ПоÑтроить туннель (авто)
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Переключение ÑтроительÑтва/ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð°Ð²Ñ‚Ð¾Ð¼Ð¾Ð±Ð¸Ð»ÑŒÐ½Ð¾Ð¹ инфраÑтруктуры
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Выбор ориентации гаража
+STR_1814_ROAD :Дорога
+STR_1815_ROAD_WITH_STREETLIGHTS :Дорога Ñ ÑƒÐ»Ð¸Ñ‡Ð½Ñ‹Ð¼ оÑвещением
+STR_1816_TREE_LINED_ROAD :ШоÑÑе
+STR_1817_ROAD_VEHICLE_DEPOT :Гараж
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :Железнодорожный переезд
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Города
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Сначала надо уничтожить зданиÑ
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}ÐаÑеление: {ORANGE}{COMMA}{BLACK} Зданий: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Переименовать Город
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Ðе могу переименовать город...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} меÑÑ‚Ð½Ð°Ñ Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð½Ðµ дает
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}ÐÐ°Ð·Ð²Ð°Ð½Ð¸Ñ Ð³Ð¾Ñ€Ð¾Ð´Ð¾Ð² - кликните на названии Ð´Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð³Ð¾Ñ€Ð¾Ð´Ð°
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Отцентрировать оÑновное окно по городу
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Переименовать город
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}ПаÑÑажиров за прошлый меÑÑц: {ORANGE}{COMMA}{BLACK} макÑ.: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Почты за прошлый меÑÑц: {ORANGE}{COMMA}{BLACK} макÑ.: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Ð’Ñ‹Ñотное офиÑное здание
+STR_2010_OFFICE_BLOCK :ОфиÑное здание
+STR_2011_SMALL_BLOCK_OF_FLATS :Жилой дом
+STR_2012_CHURCH :Церковь
+STR_2013_LARGE_OFFICE_BLOCK :Большое офиÑное здание
+STR_2014_TOWN_HOUSES :ГородÑкие зданиÑ
+STR_2015_HOTEL :Отель
+STR_2016_STATUE :СтатуÑ
+STR_2017_FOUNTAIN :Фонтан
+STR_2018_PARK :Парк
+STR_2019_OFFICE_BLOCK :ОфиÑ
+STR_201A_SHOPS_AND_OFFICES :Магазины и офиÑÑ‹
+STR_201B_MODERN_OFFICE_BUILDING :Современный деловой центр
+STR_201C_WAREHOUSE :Склад
+STR_201D_OFFICE_BLOCK :ОфиÑ
+STR_201E_STADIUM :Стадион
+STR_201F_OLD_HOUSES :Трущобы
+STR_2020_LOCAL_AUTHORITY :{BLACK}МеÑтные влаÑти
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ меÑтных влаÑÑ‚ÑÑ…
+STR_2022_LOCAL_AUTHORITY :{WHITE}{TOWN} меÑтные влаÑти
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Рейтинг транÑпортной компании
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}СубÑидии
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Свободные ÑубÑидии
+STR_2027_FROM_TO :{ORANGE}{STRING} по маршруту из {STRING} в {STRING}
+STR_2028_BY :{YELLOW} (по {DATE_SHORT})
+STR_202A_NONE :{ORANGE}нет
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}СубÑидируемые маршруты:
+STR_202C_FROM_TO :{ORANGE}{STRING} по мршруту из {STATION} в {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, до {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}Предложение ÑубÑидии иÑтекло:{}{}{STRING} по маршруту {STRING} - {STRING} ÑубÑидироватьÑÑ Ð½Ðµ будет.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Срок ÑубÑидии иÑтек:{}{}{STRING} по маршруту {STATION} - {STATION} больше не ÑубÑидируетÑÑ.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Предложена ÑубÑидиÑ:{}{}ÐŸÐµÑ€Ð²Ð°Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ñ, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ð¾Ð²ÐµÐ·ÐµÑ‚ {STRING} по маршруту {STRING} - {STRING} получит годовую ÑубÑидию от меÑтных влаÑтей!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}ÐšÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ñ {COMPANY} получает ÑубÑидию!{}{}{STRING} по маршруту {STATION} - {STATION} оплачиваетÑÑ Ð½Ð° 50% больше в Ñледующем году!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}ÐšÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ñ {COMPANY}получает ÑубÑидию!{}{}{STRING} по маршруту {STATION} - {STATION} оплачиваетÑÑ Ð²Ð´Ð²Ð¾Ð¹Ð½Ðµ в Ñледующем году!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}КомпаниÑ{COMPANY} получает ÑубÑидию!{}{}{STRING} по маршруту {STATION} - {STATION} оплачиваетÑÑ Ð²Ñ‚Ñ€Ð¾Ð¹Ð½Ðµ в Ñледующем году!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}ÐšÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ñ {COMPANY} получает ÑубÑидию!{}{}{STRING} по маршруту {STATION} в {STATION} оплачиваетÑÑ Ð²Ñ‡ÐµÑ‚Ð²ÐµÑ€Ð¾ в Ñледующем году!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} меÑÑ‚Ð½Ð°Ñ Ð²Ð»Ð°ÑÑ‚ÑŒ запрещает поÑтройку другого аÑропорта в городе
+STR_2036_COTTAGES :Коттеджи
+STR_2037_HOUSES :Дома
+STR_2038_FLATS :Квартиры
+STR_2039_TALL_OFFICE_BLOCK :Ð’Ñ‹Ñотный офиÑ
+STR_203A_SHOPS_AND_OFFICES :Магазины и офиÑÑ‹
+STR_203B_SHOPS_AND_OFFICES :Магазины и офиÑÑ‹
+STR_203C_THEATER :Театр
+STR_203D_STADIUM :Стадион
+STR_203E_OFFICES :ОфиÑÑ‹
+STR_203F_HOUSES :Дома
+STR_2040_CINEMA :Кинотеатр
+STR_2041_SHOPPING_MALL :Торговый центр
+STR_2042_DO_IT :{BLACK}ДÐÐ’ÐЙ!
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}То, что можно Ñделать в Ñтом городе - кликните Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð´Ð¾Ð¿. Ñведений
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Выполнить выделенное дейÑтвие в ÑпиÑке выше
+STR_2045_ACTIONS_AVAILABLE :{BLACK}ДоÑтупные дейÑтвиÑ:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :ÐœÐ°Ð»Ð°Ñ Ñ€ÐµÐºÐ»Ð°Ð¼Ð½Ð°Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ñ
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :СреднÑÑ Ñ€ÐµÐºÐ»Ð°Ð¼Ð½Ð°Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ñ
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Ð‘Ð¾Ð»ÑŒÑˆÐ°Ñ Ñ€ÐµÐºÐ»Ð°Ð¼Ð½Ð°Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ñ
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :ПрофинанÑировать ремонт городÑких дорог
+STR_204A_BUILD_STATUE_OF_COMPANY :ПоÑтроить Ñтатую владельца компании
+STR_204B_FUND_NEW_BUILDINGS :ПрофинанÑировать ÑтроительÑтво новых зданий
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Купить ÑкÑклюзивные транÑпортные права
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Дать взÑтку меÑтной админиÑтрации
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} ПровеÑти малую рекламную кампанию Ð´Ð»Ñ ÑƒÐ²ÐµÐ»Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð³Ñ€ÑƒÐ·Ð¾- и паÑÑажиропотока на ваших ÑтанциÑÑ….{} Цена: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} ПровеÑти Ñреднюю рекламную кампанию Ð´Ð»Ñ ÑƒÐ²ÐµÐ»Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð³Ñ€ÑƒÐ·Ð¾- и паÑÑажиропотока на ваших ÑтанциÑÑ….{} Цена: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} ПровеÑти большую рекламную кампанию Ð´Ð»Ñ ÑƒÐ²ÐµÐ»Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð³Ñ€ÑƒÐ·Ð¾- и паÑÑажиропотока на ваших ÑтанциÑÑ….{} Цена: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} ПрофинанÑировать реконÑтрукцию городÑкой дорожной Ñети. Вызывает большие Ð½Ð°Ñ€ÑƒÑˆÐµÐ½Ð¸Ñ Ñ‚Ñ€Ð°Ñ„Ð¸ÐºÐ° на Ñрок до 6-ти меÑÑцев.{} Цена: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} УÑтановить Ñтатую в чеÑÑ‚ÑŒ вашей компании.{} Цена: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} ПрофинанÑировать ÑтроительтÑво новых коммерчеÑких зданий в городе.{} Цена: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Купить годовые ÑкÑклюзивные права на транÑпортные перевозки в городе. ГородÑÐºÐ°Ñ Ð²Ð»Ð°ÑÑ‚ÑŒ разрешает пользоватьÑÑ Ð¢ÐžÐ›Ð¬ÐšÐž вашими ÑтанциÑми.{} Цена: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Дать взÑтку городÑкой влаÑти Ð´Ð»Ñ Ð¿Ð¾Ð²Ñ‹ÑˆÐµÐ½Ð¸Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ рейтинга. СущеÑтвует риÑк Ñанкций, еÑли факт взÑтки раÑкроетÑÑ{} Цена: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}Ð¥Ð°Ð¾Ñ Ð½Ð° дорогах города {TOWN}!{}{}РеконÑÑ‚Ñ€ÑƒÐºÑ†Ð¸Ñ Ð´Ð¾Ñ€Ð¾Ð³, профинанÑÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð°Ñ {COMPANY} принеÑла 6 меÑÑцев пробок на дорогах!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (на реконÑтрукции)
+STR_2059_IGLOO :Иглу
+STR_205A_TEPEES :Хижины
+STR_205B_TEAPOT_HOUSE :Домик-Чайник
+STR_205C_PIGGY_BANK :Хрюшка-Копилка
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN} {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Ландшафт
+STR_2800_PLANT_TREES :Ð’Ñ‹Ñадить деревьÑ
+STR_2801_PLACE_SIGN :ПоÑтавить знак
+STR_2802_TREES :{WHITE}ДеревьÑ
+STR_2803_TREE_ALREADY_HERE :{WHITE}...уже еÑÑ‚ÑŒ дерево
+STR_2804_SITE_UNSUITABLE :{WHITE}...неподходÑщее меÑто
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Ðевозможно выÑадить деревьÑ...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...Ñлишком много знаков
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Ðевозможно уÑтановить знак...
+STR_280A_SIGN :Знак
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Редактировать надпиÑÑŒ на знаке
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Ðевозможно изменить надпиÑÑŒ на знаке...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Выбор типа деревьев Ð´Ð»Ñ Ð¿Ð¾Ñадки
+STR_280E_TREES :ДеревьÑ
+STR_280F_RAINFOREST :Джунгли
+STR_2810_CACTUS_PLANTS :КактуÑÑ‹
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Выбор Ж/Д Станции
+STR_3001_AIRPORT_SELECTION :{WHITE}Выбор ÐÑропорта
+STR_3002_ORIENTATION :{BLACK}Ðаправление
+STR_3003_NUMBER_OF_TRACKS :{BLACK}ЧиÑло путей
+STR_3004_PLATFORM_LENGTH :{BLACK}Длина платформы
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Слишком близко к другой Ñтанции
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}ПриÑоединÑетÑÑ Ð±Ð¾Ð»ÐµÐµ чем к одной ÑущеÑтвующей Ñтанции
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}Слишком много Ñтанций и оÑтановок в Ñтом городе. Переименуйте ÑущеÑтвующие.
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}Слишком много Ñтанций и оÑтановок
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Слишком много автобуÑных оÑтановок
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}Слишком много погрузочных Ñтанций
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Слишком близко к другой Ñтанции
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Сначала нужно удалить ж/д Ñтанцию
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Слишком близко к другому аÑропорту
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Сначала удалите аÑропорт
+
+STR_3030_RENAME_STATION_LOADING :Переименовать Ñтанцию
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Ðе могу переименовать Ñтанцию...
+STR_3032_RATINGS :{BLACK}Рейтинг
+STR_3033_ACCEPTS :{BLACK}Принимает
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}МеÑтный рейтинг транÑпортной компании:
+
+############ range for rating starts
+STR_3035_APPALLING :УжаÑный
+STR_3036_VERY_POOR :Очень плохой
+STR_3037_POOR :Плохой
+STR_3038_MEDIOCRE :ПоÑредÑтвенный
+STR_3039_GOOD :Хороший
+STR_303A_VERY_GOOD :Очень хороший
+STR_303B_EXCELLENT :Великолепный
+STR_303C_OUTSTANDING :Отличный
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} больше не принимает {STRING}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} больше не принимает {STRING} или {STRING}
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} теперь принимает {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} теперь принимает {STRING} и {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Ðаправление оÑтановки
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}ÐžÑ€Ð¸ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ Ñтанции
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Сначала удалите автобуÑную оÑтановку
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Сначала удалите грузовой терминал
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Станции
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Ðет -
+STR_304B_SITE_UNSUITABLE :{WHITE}...неподходÑщее меÑто
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Слишком близко к другому доку
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Сначала удалите док
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Выберите направление ж/д Ñтанции
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Выберите чиÑло платформ ж/д Ñтанции
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Выберите длину ж/д Ñтанции
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Выберите направление автобуÑной оÑтановки
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Выберите направление погрузочной Ñтанции
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Показать Ñтанцию в оÑновном окне
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Показать рейтинг Ñтанции
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Переименовать Ñтанцию
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Показать ÑпиÑок принÑÑ‚Ñ‹Ñ… грузов
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}ÐÐ°Ð·Ð²Ð°Ð½Ð¸Ñ Ñтанций - кликните Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, чтобы показать Ñтанцию в оÑновном окне
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Выберите размер/тип аÑропорта
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :Ж/Д ÑтанциÑ
+STR_305F_AIRCRAFT_HANGAR :Ðнгар
+STR_3060_AIRPORT :ÐÑропорт
+STR_3061_TRUCK_LOADING_AREA :ÐŸÐ¾Ð³Ñ€ÑƒÐ·Ð¾Ñ‡Ð½Ð°Ñ Ð¿Ð»Ð°Ñ‚Ñ„Ð¾Ñ€Ð¼Ð°
+STR_3062_BUS_STATION :ОÑтановка
+STR_3063_SHIP_DOCK :ПриÑтань
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Показывать зону покрытиÑ
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Ðе показывать зону покрытиÑ
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}ПодÑветка зоны покрытиÑ
+STR_3068_DOCK :{WHITE}Док
+STR_3069_BUOY :Буй
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...буй на пути
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...ÑÑ‚Ð°Ð½Ñ†Ð¸Ñ Ñлишком большаÑ
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...иÑпользование непрÑмоугольных Ñтанций запрещено
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Ðажмите и держите CTRL Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° более одного варианта
+
+STR_UNDEFINED :(неопределено)
+STR_STAT_CLASS_DFLT :По умолчанию
+STR_STAT_CLASS_WAYP :Точки пути
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Ðаправление дока
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...должно быть поÑтроено на воде
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Ðевозможно поÑтроить док здеÑÑŒ...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Выберите направление дока
+STR_3804_WATER :Вода
+STR_3805_COAST_OR_RIVERBANK :МорÑкой или речной берег
+STR_3806_SHIP_DEPOT :Верфь
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...Ðевозможно поÑтроить на воде
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Сохранить игру
+STR_4001_LOAD_GAME :{WHITE}Загрузить игру
+STR_4002_SAVE :{BLACK}Сохранить
+STR_4003_DELETE :{BLACK}Удалить
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} Мб Ñвободно
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Ðе удалоÑÑŒ прочитать диÑк
+STR_4007_GAME_SAVE_FAILED :{WHITE}Ðевозможно Ñохранить игру
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Ðевозможно удалить файл
+STR_4009_GAME_LOAD_FAILED :{WHITE}Ðевозможно загрузить игру
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}СпиÑок диÑков, папок и Ñохраненных игр
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Текущее выбранное Ð¸Ð¼Ñ Ð´Ð»Ñ ÑохранениÑ
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Удалить выбранную Ñохраненную игру
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Сохранить текущую игру, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð¾Ðµ название
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Выбрать тип новой игры
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Выбрать Ñценарий(зеленый), предуÑтановленную новую игру (Ñиний) или Ñлучайную новую игру
+STR_4010_GENERATE_RANDOM_NEW_GAME :Сгенерировать Ñлучайную карту
+STR_4011_LOAD_HEIGHTMAP :{WHITE}Загруз. ЛÐÐДШÐФТ
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} на пути
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :Ð£Ð³Ð¾Ð»ÑŒÐ½Ð°Ñ ÑˆÐ°Ñ…Ñ‚Ð°
+STR_4803_POWER_STATION :ЭлектроÑтанциÑ
+STR_4804_SAWMILL :ЛеÑопилка
+STR_4805_FOREST :ЛеÑ
+STR_4806_OIL_REFINERY :Ðефтеперерабат. завод
+STR_4807_OIL_RIG :Ð‘ÑƒÑ€Ð¾Ð²Ð°Ñ Ð²Ñ‹ÑˆÐºÐ°
+STR_4808_FACTORY :Завод
+STR_4809_PRINTING_WORKS :ТипографиÑ
+STR_480A_STEEL_MILL :Сталелитейный завод
+STR_480B_FARM :Ферма
+STR_480C_COPPER_ORE_MINE :Шахта медной руды
+STR_480D_OIL_WELLS :ÐефтÑÐ½Ð°Ñ Ð¿Ð»Ð°Ñ‚Ñ„Ð¾Ñ€Ð¼Ð°
+STR_480E_BANK :Банк
+STR_480F_FOOD_PROCESSING_PLANT :ÐŸÐ¸Ñ‰ÐµÐ²Ð°Ñ Ñ„Ð°Ð±Ñ€Ð¸ÐºÐ°
+STR_4810_PAPER_MILL :Ð‘ÑƒÐ¼Ð°Ð¶Ð½Ð°Ñ Ñ„Ð°Ð±Ñ€Ð¸ÐºÐ°
+STR_4811_GOLD_MINE :Ð—Ð¾Ð»Ð¾Ñ‚Ð°Ñ ÑˆÐ°Ñ…Ñ‚Ð°
+STR_4812_BANK :Банк
+STR_4813_DIAMOND_MINE :Ðлмазные копи
+STR_4814_IRON_ORE_MINE :Шахта железной руды
+STR_4815_FRUIT_PLANTATION :ÐŸÐ»Ð°Ð½Ñ‚Ð°Ñ†Ð¸Ñ Ñ„Ñ€ÑƒÐºÑ‚Ð¾Ð²
+STR_4816_RUBBER_PLANTATION :ÐŸÐ»Ð°Ð½Ñ‚Ð°Ñ†Ð¸Ñ Ñ€ÐµÐ·Ð¸Ð½Ñ‹
+STR_4817_WATER_SUPPLY :Ð’Ð¾Ð´Ð½Ð°Ñ Ñкважина
+STR_4818_WATER_TOWER :Ð’Ð¾Ð´Ð¾Ð½Ð°Ð¿Ð¾Ñ€Ð½Ð°Ñ Ð±Ð°ÑˆÐ½Ñ
+STR_4819_FACTORY :Завод
+STR_481A_FARM :Ферма
+STR_481B_LUMBER_MILL :ЛеÑопилка
+STR_481C_COTTON_CANDY_FOREST :Ð›ÐµÑ Ñахарной ваты
+STR_481D_CANDY_FACTORY :Завод ÑладоÑтей
+STR_481E_BATTERY_FARM :Фабрика батареек
+STR_481F_COLA_WELLS :Колодцы колы
+STR_4820_TOY_SHOP :Магазин игрушек
+STR_4821_TOY_FACTORY :Завод игрушек
+STR_4822_PLASTIC_FOUNTAINS :Фонтаны плаÑтика
+STR_4823_FIZZY_DRINK_FACTORY :Завод газировки
+STR_4824_BUBBLE_GENERATOR :Генератор пузырьков
+STR_4825_TOFFEE_QUARRY :Карьер ириÑок
+STR_4826_SUGAR_MINE :Ð¡Ð°Ñ…Ð°Ñ€Ð½Ð°Ñ ÑˆÐ°Ñ…Ñ‚Ð°
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}ТребуетÑÑ: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}ТребуетÑÑ: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}ТребуетÑÑ: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Произведено за прошлый меÑÑц:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% перевезено)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Показать предприÑтие в оÑновном окне
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Ðовое предприÑтие - {STRING} ÑтроитÑÑ Ð²Ð¾Ð·Ð»Ðµ г. {TOWN}!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Ðовое предприÑте - {STRING} заложен возле г. {TOWN}!
+STR_482F_COST :{BLACK}Цена: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Ðевозможно поÑтроить Ñто предприÑтие здеÑÑŒ...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...Ð»ÐµÑ Ð¼Ð¾Ð¶Ð½Ð¾ Ñажать только выше линии Ñнега
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} объÑвлÑет о немедленном закрытии!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}Проблемы Ñ Ð¿Ð¾Ñтавками вынуждают {INDUSTRY} объÑвить о неизбежном закрытии!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}ÐедоÑтаток деревьев в округе вынуждает {INDUSTRY} объÑвить о неизбежном закрытии!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} увеличивает объемы производÑтва!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}Ðайден новый угольный плаÑÑ‚ в {INDUSTRY}!{}Добыча увеличена вдвое!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}Обнаружены новые запаÑÑ‹ нефти на {INDUSTRY} !{}Добыча увеличена вдвое!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}Внедрение новых методов позволÑет поднÑÑ‚ÑŒ производÑтво вдвое на {INDUSTRY}!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}{INDUSTRY} производÑтво упало на 50%
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}{INDUSTRY}: ÐашеÑтвие вредителей, {}производÑтво упало на 50%
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...может находитьÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ на краю карты
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}{STRING} производительноÑÑ‚ÑŒ {INDUSTRY} увеличилаÑÑŒ на {COMMA}%!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}{STRING} производительноÑÑ‚ÑŒ {INDUSTRY} уменьшилаÑÑŒ на {COMMA}%!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Поезд в туннеле
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Машина в туннеле
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Другой туннель на пути
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Ðевозможно поднÑÑ‚ÑŒ/опуÑтить землю Ð´Ð»Ñ Ð´Ñ€ÑƒÐ³Ð¾Ð³Ð¾ конца туннелÑ
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Сначала удалите туннель
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Сначала удалите моÑÑ‚
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Ðе может начинатьÑÑ Ð¸ заканчиватьÑÑ Ð² той же точке
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Более низкий уровень земли или воды должен быть под моÑтом
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}Ðачало и конец должны быть на одной линии
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}ÐеподходÑщее меÑто Ð´Ð»Ñ ÑтроительÑтва туннелÑ
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :ПодвеÑной, Стальной
+STR_500F_GIRDER_STEEL :Балочный, Стальной
+STR_5010_CANTILEVER_STEEL :КонÑольный, Стальной
+STR_5011_SUSPENSION_CONCRETE :ПодвеÑной, Бетонный
+STR_5012_WOODEN :ДеревÑнный
+STR_5013_CONCRETE :Бетонный
+STR_5014_TUBULAR_STEEL :Трубчатый, Стальной
+STR_BRIDGE_TUBULAR_SILICON :Трубчатый, Силиконовый
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Ðе могу поÑтроить моÑÑ‚ здеÑÑŒ...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Ðе могу поÑтроить туннель здеÑÑŒ...
+STR_5017_RAILROAD_TUNNEL :Железнодорожный туннель
+STR_5018_ROAD_TUNNEL :Ðвтомобильный туннель
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Стальной подвеÑной ж/д моÑÑ‚
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Стальной балочный ж/д моÑÑ‚
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Стальной конÑольный ж/д моÑÑ‚
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Укрепленный подвеÑной железобетонный ж/д моÑÑ‚
+STR_501F_WOODEN_RAIL_BRIDGE :ДеревÑнный ж/д моÑÑ‚
+STR_5020_CONCRETE_RAIL_BRIDGE :Бетонный ж/д моÑÑ‚
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Стальной подвеÑной моÑÑ‚
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Стальной балочный моÑÑ‚
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Стальной конÑольный моÑÑ‚
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Укрепленный подвеÑной железобетонный моÑÑ‚
+STR_5025_WOODEN_ROAD_BRIDGE :ДеревÑнный моÑÑ‚
+STR_5026_CONCRETE_ROAD_BRIDGE :Бетонный моÑÑ‚
+STR_5027_TUBULAR_RAIL_BRIDGE :Трубчатый ж/д моÑÑ‚
+STR_5028_TUBULAR_ROAD_BRIDGE :Трубчатый автомобильный моÑÑ‚
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Объект в пути
+STR_5801_TRANSMITTER :Передатчик
+STR_5802_LIGHTHOUSE :МаÑк
+STR_5803_COMPANY_HEADQUARTERS :Штаб-квартира компании
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...штаб-квартира компании на пути
+STR_5805_COMPANY_OWNED_LAND :Ð—ÐµÐ¼Ð»Ñ Ð² ÑобÑтвенноÑти компании
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Ðевозможно купить Ñту землю...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...вы и так уже владеете Ñтим!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Без имени
+STR_SV_TRAIN_NAME :Поезд {COMMA}
+STR_SV_ROADVEH_NAME :Машина {COMMA}
+STR_SV_SHIP_NAME :Корабль {COMMA}
+STR_SV_AIRCRAFT_NAME :Самолет {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :{STRING} СевернаÑ
+STR_SV_STNAME_SOUTH :{STRING} ЮжнаÑ
+STR_SV_STNAME_EAST :{STRING} ВоÑточнаÑ
+STR_SV_STNAME_WEST :{STRING} ЗападнаÑ
+STR_SV_STNAME_CENTRAL :{STRING} ЦентральнаÑ
+STR_SV_STNAME_TRANSFER :Платформа {STRING}
+STR_SV_STNAME_HALT :ПолуÑтанок {STRING}
+STR_SV_STNAME_VALLEY :{STRING} Долина
+STR_SV_STNAME_HEIGHTS :{STRING} Ð’Ñ‹ÑотнаÑ
+STR_SV_STNAME_WOODS :{STRING} ЛеÑнаÑ
+STR_SV_STNAME_LAKESIDE :{STRING} ОзернаÑ
+STR_SV_STNAME_EXCHANGE :{STRING} СортировочнаÑ
+STR_SV_STNAME_AIRPORT :{STRING} ÐÑропорт
+STR_SV_STNAME_OILFIELD :ÐефтÑное поле {STRING}
+STR_SV_STNAME_MINES :{STRING} Шахты
+STR_SV_STNAME_DOCKS :ПриÑтань {STRING}
+STR_SV_STNAME_BUOY_1 :{STRING} Буй 1
+STR_SV_STNAME_BUOY_2 :{STRING} Буй 2
+STR_SV_STNAME_BUOY_3 :{STRING} Буй 3
+STR_SV_STNAME_BUOY_4 :{STRING} Буй 4
+STR_SV_STNAME_BUOY_5 :{STRING} Буй 5
+STR_SV_STNAME_BUOY_6 :{STRING} Буй 6
+STR_SV_STNAME_BUOY_7 :{STRING} Буй 7
+STR_SV_STNAME_BUOY_8 :{STRING} Буй 8
+STR_SV_STNAME_BUOY_9 :{STRING} Буй 9
+STR_SV_STNAME_ANNEXE :{STRING} ДополнительнаÑ
+STR_SV_STNAME_SIDINGS :{STRING} ЗапаÑнаÑ
+STR_SV_STNAME_BRANCH :{STRING} БереговаÑ
+STR_SV_STNAME_UPPER :{STRING} ВерхнÑÑ
+STR_SV_STNAME_LOWER :{STRING} ÐижнÑÑ
+STR_SV_STNAME_HELIPORT :Площадка {STRING}
+STR_SV_STNAME_FOREST :{STRING} ЛеÑ
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Уровень ÑложноÑти
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Сохранить
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Легкий
+STR_6802_MEDIUM :{BLACK}Средний
+STR_6803_HARD :{BLACK}ТÑжелый
+STR_6804_CUSTOM :{BLACK}Пользоват.
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}МакÑимальное чиÑло противников: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Ðачало игры противников: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}КоличеÑтво городов: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}КоличеÑтво предприÑтий: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ ÑÑуда: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}ÐÐ°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ Ð¿Ñ€Ð¾Ñ†ÐµÐ½Ñ‚Ð½Ð°Ñ Ñтавка: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Затраты на Ñодержание транÑпорта: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}СкороÑÑ‚ÑŒ ÑтроительÑтва конкурентов: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Интеллект конкурентов: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Поломки транÑпорта: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Множитель дохода от ÑубÑидии: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Затраты на ÑтроительÑтво: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Тип меÑтноÑти: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}КоличеÑтво морей и озер: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Экономика: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Разворот поездов: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}БедÑтвиÑ: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Отношение влаÑтей к изменению территорий: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :Ðичего
+STR_6816_LOW :Мало
+STR_6817_NORMAL :Ðормально
+STR_6818_HIGH :Много
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Очень Медленно
+STR_681C_SLOW :Медленно
+STR_681D_MEDIUM :Средне
+STR_681E_FAST :БыÑтро
+STR_681F_VERY_FAST :Очень БыÑтро
+STR_VERY_LOW :Очень Ðизко
+STR_6820_LOW :Ðизкий
+STR_6821_MEDIUM :Средний
+STR_6822_HIGH :Ð’Ñ‹Ñокий
+STR_6823_NONE :Ðет
+STR_6824_REDUCED :Уменьшенное
+STR_6825_NORMAL :Ðормальное
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Очень плоÑкий
+STR_682B_FLAT :ПлоÑкий
+STR_682C_HILLY :ХолмиÑтый
+STR_682D_MOUNTAINOUS :ГориÑтый
+STR_682E_STEADY :СтабильнаÑ
+STR_682F_FLUCTUATING :ИзменчиваÑ
+STR_6830_IMMEDIATE :Ðемедленно
+STR_6831_3_MONTHS_AFTER_PLAYER :через 3 меÑÑца
+STR_6832_6_MONTHS_AFTER_PLAYER :через полгода
+STR_6833_9_MONTHS_AFTER_PLAYER :через 9 меÑÑцев
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :Ð’ конце линии, и на Ñтанции
+STR_6835_AT_END_OF_LINE_ONLY :Только в конце линии
+STR_6836_OFF :Выкл
+STR_6837_ON :Вкл
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Показать таблицу рекордов
+STR_6839_PERMISSIVE :ДопуÑтимое
+STR_683A_TOLERANT :Терпимое
+STR_683B_HOSTILE :Отрицательное
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Игрок {COMMA})
+STR_7004_NEW_FACE :{BLACK}Ðовое Лицо
+STR_7005_COLOR_SCHEME :{BLACK}Цвет
+STR_7006_COLOR_SCHEME :{GOLD}Цвет:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Ðовый Цвет
+STR_7008_COMPANY_NAME :{BLACK}Ðазвание фирмы
+STR_7009_PRESIDENT_NAME :{BLACK}Ð˜Ð¼Ñ Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð°
+STR_700A_COMPANY_NAME :КомпаниÑ
+STR_700B_PRESIDENT_S_NAME :Ð˜Ð¼Ñ Ð”Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð°
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Ðевозможно изменить название компании...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Ðевозможно изменить Ð¸Ð¼Ñ Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð°...
+STR_700E_FINANCES :{WHITE}{COMPANY} Денежные ÑредÑтва {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Статьи раÑхода/дохода
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}СтроительÑтво
+STR_7012_NEW_VEHICLES :{GOLD}ÐÐ¾Ð²Ð°Ñ Ñ‚ÐµÑ…Ð½Ð¸ÐºÐ°
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}ОбÑлуживание ЖД
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}ОбÑлуживание авто
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}ОбÑлуживание авиа
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}ОбÑлуживание кораблей
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}ОбÑлуж. ÑобÑтвенноÑти
+STR_7018_TRAIN_INCOME :{GOLD}Доход от ЖД
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Доход от автотранÑпорта
+STR_701A_AIRCRAFT_INCOME :{GOLD}Доход от авиации
+STR_701B_SHIP_INCOME :{GOLD}Доход от водн. транÑпорта
+STR_701C_LOAN_INTEREST :{GOLD}Проценты по займу
+STR_701D_OTHER :{GOLD}Другое
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}ИТОГО:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}График Доходов
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}График прибыли от оÑновной деÑтельноÑти
+STR_7026_BANK_BALANCE :{WHITE}БаланÑ
+STR_7027_LOAN :{WHITE}СÑуда
+STR_MAX_LOAN :{WHITE}МакÑ. СÑуда: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}ЗанÑÑ‚ÑŒ {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Отдать {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...макÑимально допуÑтимый размер ÑÑуды {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Ðевозможно занÑÑ‚ÑŒ больше денег...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...нет ÑÑуды Ð´Ð»Ñ Ð²Ñ‹Ð¿Ð»Ð°Ñ‡Ð¸Ð²Ð°Ð½Ð¸Ñ
+STR_702E_REQUIRED :{WHITE}...{CURRENCY} надо
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Ðевозможно погаÑить ÑÑуду...
+STR_INSUFFICIENT_FUNDS :{WHITE}Ðевозможно отдать ÑÑуженные банком деньги...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Выбрать новое лицо управлÑющего
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Измененить цвет транÑпортных ÑредÑтв компании
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Изменение имени управлÑющего
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Изменение Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ð¸
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Выберите цветовую Ñхему
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}ВзÑÑ‚ÑŒ/увеличить кредит
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Вернуть чаÑÑ‚ÑŒ ÑÑуды
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(УправлÑющий)
+STR_7038_INAUGURATED :{GOLD}Ð’ должноÑти Ñ: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}ТранÑпорта:
+STR_TRAINS :{WHITE}{COMMA} поезда
+STR_ROAD_VEHICLES :{WHITE}{COMMA} машины
+STR_AIRCRAFT :{WHITE}{COMMA} авиатранÑпорт
+STR_SHIPS :{WHITE}{COMMA} корабли
+STR_7042_NONE :{WHITE}Ðет
+STR_7043_FACE_SELECTION :{WHITE}Выбор Лица
+STR_7044_MALE :{BLACK}МужÑкое
+STR_7045_FEMALE :{BLACK}ЖенÑкое
+STR_7046_NEW_FACE :{BLACK}Ðовое Лицо
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Отменить выбор нового лица
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}ПринÑÑ‚ÑŒ выбор нового лица
+STR_7049_SELECT_MALE_FACES :{BLACK}Выбор мужÑких лиц
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Выбор женÑких лиц
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Получить любое новое лицо
+STR_704C_KEY :{BLACK}Легенда
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Показать легенду к графикам
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Легенда
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Включить/выключить отображение компании на графике
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}ДоÑтавлено грузов
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Рейтинг деÑтельноÑти компании (макÑ=1000)
+STR_7052_COMPANY_VALUES :{WHITE}СтоимоÑÑ‚ÑŒ активов компании
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Ð¡Ñ€Ð°Ð²Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° компаний
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}ТранÑÐ¿Ð¾Ñ€Ñ‚Ð½Ð°Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ñ Ð² опаÑном положении!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT} {COMPANY} будет продана или объÑвлена банкротом, еÑли ÑÐ¸Ñ‚ÑƒÐ°Ñ†Ð¸Ñ Ð½Ðµ изменитÑÑ!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(УправлÑющий)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Объединение компаний!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} продана {COMPANY} за {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Мы ищем транÑпортную компанию Ð´Ð»Ñ Ð¿Ñ€Ð¸ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ðº ней.{}{}Ð’Ñ‹ хотите купить {COMPANY} за {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Банкрот!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} была закрыта кредиторами! Ð’Ñе активы раÑпроданы!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}ОÑнована Ð½Ð¾Ð²Ð°Ñ Ñ‚Ñ€Ð°Ð½ÑÐ¿Ð¾Ñ€Ñ‚Ð½Ð°Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ñ!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} начинает ÑтроительÑтво около {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Ðевозможно приобреÑти компанию...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Оплата за перевозку грузов
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Дней в транзите
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Оплата за доÑтавку 10 единиц (10 000 литров) груза на раÑÑтоÑние в 20 клеток
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Включить/выключить отображение груза на графике
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :МашиниÑÑ‚
+STR_7067_TRAFFIC_MANAGER :Регулировщик
+STR_7068_TRANSPORT_COORDINATOR :ДиÑпетчер
+STR_7069_ROUTE_SUPERVISOR :Координатор
+STR_706A_DIRECTOR :Директор
+STR_706B_CHIEF_EXECUTIVE :Топ-менеджер
+STR_706C_CHAIRMAN :ПредÑедатель
+STR_706D_PRESIDENT :Президент
+STR_706E_TYCOON :Магнат
+STR_706F_BUILD_HQ :{BLACK}ПоÑтроить штаб-квартиру
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}ПоÑтроить/проÑмотреть штаб-квартиру компании
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}ПереÑтроить штаб компании в другом меÑте за 1% ÑтоимоÑÑ‚ÑŒ от капитала компании
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Ðевозможно поÑтроить штаб-квартиру компании...
+STR_7072_VIEW_HQ :{BLACK}ПоÑмотреть штаб
+STR_RELOCATE_HQ :{BLACK}ПеремеÑÑ‚. ШК
+STR_COMPANY_PASSWORD :{BLACK}Пароль
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Защитить вашу компанию паролем, чтобы неавторизованные пользователи не могли приÑоединитьÑÑ
+STR_SET_COMPANY_PASSWORD :УÑтановить пароль компании
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}Мировой Ñпад{}{}ФинанÑовые ÑкÑперты дают ужаÑные прогнозы в ÑвÑзи Ñ ÐºÑ€Ð¸Ð·Ð¸Ñом Ñкономики!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Спад закончилÑÑ!{}{}Увеличение объемов торговли внушает уверенноÑÑ‚ÑŒ владельцам предприÑтий. Экономика укреплÑет Ñвои позиции.
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Большое/маленькое окно
+STR_7076_COMPANY_VALUE :{GOLD}СтоимоÑÑ‚ÑŒ компании: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Купить 25% акций компании
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Продать 25% акций компании
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Купить 25% акций Ñтой компании
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Продать 25% акций Ñтой компании
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Ðе могу купить 25% акций Ñтой компании...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}Ðе могу продать 25% акций Ñтой компании...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% владеет {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% владеет {COMPANY}{} {COMMA}% владеет {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} выкуплена {COMPANY}!
+STR_7080_PROTECTED :{WHITE}Эта ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ñ ÐµÑ‰Ðµ не может торговать акциÑми...
+
+STR_LIVERY_DEFAULT :Стандарт. раÑкраÑка
+STR_LIVERY_STEAM :Паровоз
+STR_LIVERY_DIESEL :Дизель
+STR_LIVERY_ELECTRIC :Электропоезд
+STR_LIVERY_MONORAIL :МонорельÑ
+STR_LIVERY_MAGLEV :Маглев
+STR_LIVERY_DMU :DMU
+STR_LIVERY_EMU :EMU
+STR_LIVERY_PASSENGER_WAGON_STEAM :ПаÑÑажирÑкий вагон (паровоз)
+STR_LIVERY_PASSENGER_WAGON_DIESEL :ПаÑÑажирÑкий вагон (дизель)
+STR_LIVERY_PASSENGER_WAGON_ELECTRIC :ПаÑÑажирÑкий вагон (Ñлектро)
+STR_LIVERY_FREIGHT_WAGON :Грузовой вагон
+STR_LIVERY_BUS :ÐвтобуÑ
+STR_LIVERY_TRUCK :Грузовое авто
+STR_LIVERY_PASSENGER_SHIP :ПаÑÑажирÑкое Ñудно
+STR_LIVERY_FREIGHT_SHIP :Грузовое Ñудно
+STR_LIVERY_HELICOPTER :Вертолет
+STR_LIVERY_SMALL_PLANE :Малый Ñамолет
+STR_LIVERY_LARGE_PLANE :Большой Ñамолет
+
+STR_LIVERY_GENERAL_TIP :{BLACK}Показ. оÑновную цветовую Ñхему
+STR_LIVERY_TRAIN_TIP :{BLACK}Показ. цветовую Ñхему поездов
+STR_LIVERY_ROADVEH_TIP :{BLACK}Показ. цветовую Ñхему авто
+STR_LIVERY_SHIP_TIP :{BLACK}Показ. цветовую Ñхему Ñудов
+STR_LIVERY_AIRCRAFT_TIP :{BLACK}Показ. цветовую Ñхему авиатранÑпорта
+STR_LIVERY_PRIMARY_TIP :{BLACK}Выберите оÑновной цвет Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ Ñхемы
+STR_LIVERY_SECONDARY_TIP :{BLACK}Выберите вторичный цыет Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ Ñхемы
+STR_LIVERY_PANEL_TIP :{BLACK}Выберите цветовую Ñхему Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ, либо неÑколько Ñхем Ñ CTRL. Кликните на Ñ‡ÐµÐºÐ±Ð¾ÐºÑ Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð¾Ð¹ Ñхемы.
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Паровоз Kirby Paul
+STR_8001_MJS_250_DIESEL :Дизель MJS 250
+STR_8002_PLODDYPHUT_CHOO_CHOO :Паровоз Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Паровоз Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Паровоз Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Дизель Ploddyphut
+STR_8006_POWERNAUT_DIESEL :Дизель Powernaut
+STR_8007_WILLS_2_8_0_STEAM :Паровоз Wills 2-8-0
+STR_8008_CHANEY_JUBILEE_STEAM :Паровоз Chaney 'Jubilee'
+STR_8009_GINZU_A4_STEAM :Паровоз Ginzu 'A4'
+STR_800A_SH_8P_STEAM :Паровоз SH '8P'
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Дизель Manley-Morel DMU
+STR_800C_DASH_DIESEL :Дизель 'Dash'
+STR_800D_SH_HENDRY_25_DIESEL :Дизель SH/Hendry '25'
+STR_800E_UU_37_DIESEL :Дизель UU '37'
+STR_800F_FLOSS_47_DIESEL :Дизель Floss '47'
+STR_8010_CS_4000_DIESEL :Дизель CS 4000
+STR_8011_CS_2400_DIESEL :Дизель CS 2400
+STR_8012_CENTENNIAL_DIESEL :Дизель Centennial
+STR_8013_KELLING_3100_DIESEL :Дизель Kelling 3100
+STR_8014_TURNER_TURBO_DIESEL :Дизель Turner Turbo
+STR_8015_MJS_1000_DIESEL :Дизель MJS 1000
+STR_8016_SH_125_DIESEL :Дизель SH '125'
+STR_8017_SH_30_ELECTRIC :Электро SH '30'
+STR_8018_SH_40_ELECTRIC :Электро SH '40'
+STR_8019_T_I_M_ELECTRIC :Электро 'T.I.M.'
+STR_801A_ASIASTAR_ELECTRIC :Электро 'AsiaStar'
+STR_801B_PASSENGER_CAR :ПаÑÑажирÑкий вагон
+STR_801C_MAIL_VAN :Почтовый вагон
+STR_801D_COAL_CAR :Ð£Ð³Ð¾Ð»ÑŒÐ½Ð°Ñ Ð¿Ð»Ð°Ñ‚Ñ„Ð¾Ñ€Ð¼Ð°
+STR_801E_OIL_TANKER :ÐефтÑÐ½Ð°Ñ Ñ†Ð¸Ñтерна
+STR_801F_LIVESTOCK_VAN :Вагон Ð´Ð»Ñ Ñкота
+STR_8020_GOODS_VAN :Товарный вагон
+STR_8021_GRAIN_HOPPER :Хоппер
+STR_8022_WOOD_TRUCK :Вагон Ð´Ð»Ñ Ð´ÐµÑ€ÐµÐ²Ð°
+STR_8023_IRON_ORE_HOPPER :Вагон Ð´Ð»Ñ Ð¶ÐµÐ». руды
+STR_8024_STEEL_TRUCK :Вагон Ð´Ð»Ñ Ñтали
+STR_8025_ARMORED_VAN :Бронированный вагон
+STR_8026_FOOD_VAN :Рефрижератор (еда)
+STR_8027_PAPER_TRUCK :Вагон Ð´Ð»Ñ Ð±ÑƒÐ¼Ð°Ð³Ð¸
+STR_8028_COPPER_ORE_HOPPER :Вагон Ð´Ð»Ñ Ð¼ÐµÐ´Ð½Ð¾Ð¹ руды
+STR_8029_WATER_TANKER :Ð’Ð¾Ð´Ð½Ð°Ñ Ñ†Ð¸Ñтерна
+STR_802A_FRUIT_TRUCK :Рефрижератор (фрукты)
+STR_802B_RUBBER_TRUCK :Вагон Ð´Ð»Ñ Ñ€ÐµÐ·Ð¸Ð½Ñ‹
+STR_802C_SUGAR_TRUCK :Вагон Ð´Ð»Ñ Ñахара
+STR_802D_COTTON_CANDY_HOPPER :Хоппер (Ñахар. вата)
+STR_802E_TOFFEE_HOPPER :Хоппер (ириÑки)
+STR_802F_BUBBLE_VAN :Вагон (пузырьки)
+STR_8030_COLA_TANKER :ЦиÑтерна (кола)
+STR_8031_CANDY_VAN :Вагон (конфеты)
+STR_8032_TOY_VAN :Вагон (игрушки)
+STR_8033_BATTERY_TRUCK :Платформа (батарейки)
+STR_8034_FIZZY_DRINK_TRUCK :Платформа (газировка)
+STR_8035_PLASTIC_TRUCK :Платформа (плаÑтик)
+STR_8036_X2001_ELECTRIC :Электро 'X2001'
+STR_8037_MILLENNIUM_Z1_ELECTRIC :Электро 'Millennium Z1'
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :ПаÑÑажирÑкий вагон
+STR_803A_MAIL_VAN :Почтовый вагон
+STR_803B_COAL_CAR :Ð£Ð³Ð¾Ð»ÑŒÐ½Ð°Ñ Ð¿Ð»Ð°Ñ‚Ñ„Ð¾Ñ€Ð¼Ð°
+STR_803C_OIL_TANKER :ÐефтÑÐ½Ð°Ñ Ñ†Ð¸Ñтерна
+STR_803D_LIVESTOCK_VAN :Вагон Ð´Ð»Ñ Ñкота
+STR_803E_GOODS_VAN :Товарный вагон
+STR_803F_GRAIN_HOPPER :Хоппер
+STR_8040_WOOD_TRUCK :Вагон Ð´Ð»Ñ Ð´ÐµÑ€ÐµÐ²Ð°
+STR_8041_IRON_ORE_HOPPER :Вагон Ð´Ð»Ñ Ð¶ÐµÐ». руды
+STR_8042_STEEL_TRUCK :Вагон Ð´Ð»Ñ Ñтали
+STR_8043_ARMORED_VAN :Бронированный вагон
+STR_8044_FOOD_VAN :Рефрижератор (еда)
+STR_8045_PAPER_TRUCK :Вагон Ð´Ð»Ñ Ð±ÑƒÐ¼Ð°Ð³Ð¸
+STR_8046_COPPER_ORE_HOPPER :Вагон Ð´Ð»Ñ Ð¼ÐµÐ´Ð½Ð¾Ð¹ руды
+STR_8047_WATER_TANKER :Ð’Ð¾Ð´Ð½Ð°Ñ Ñ†Ð¸Ñтерна
+STR_8048_FRUIT_TRUCK :Рефрижератор (фрукты)
+STR_8049_RUBBER_TRUCK :Вагон Ð´Ð»Ñ Ñ€ÐµÐ·Ð¸Ð½Ñ‹
+STR_804A_SUGAR_TRUCK :Вагон Ð´Ð»Ñ Ñахара
+STR_804B_COTTON_CANDY_HOPPER :Вагон Ð´Ð»Ñ Ñах. ваты
+STR_804C_TOFFEE_HOPPER :Вагон Ð´Ð»Ñ Ð¸Ñ€Ð¸Ñок
+STR_804D_BUBBLE_VAN :Вагон Ð´Ð»Ñ Ð¿ÑƒÐ·Ñ‹Ñ€ÑŒÐºÐ¾Ð²
+STR_804E_COLA_TANKER :ЦиÑтерна колы
+STR_804F_CANDY_VAN :Вагон Ð´Ð»Ñ ÐºÐ¾Ð½Ñ„ÐµÑ‚
+STR_8050_TOY_VAN :Вагон Ð´Ð»Ñ Ð¸Ð³Ñ€ÑƒÑˆÐµÐº
+STR_8051_BATTERY_TRUCK :Вагон Ð´Ð»Ñ Ð±Ð°Ñ‚Ð°Ñ€ÐµÐµÐº
+STR_8052_FIZZY_DRINK_TRUCK :Вагон Ð´Ð»Ñ Ð³Ð°Ð·Ð¸Ñ€Ð¾Ð²ÐºÐ¸
+STR_8053_PLASTIC_TRUCK :Вагон Ð´Ð»Ñ Ð¿Ð»Ð°Ñтика
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (Электро)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Электро Lev2 'Cyclops'
+STR_8056_LEV3_PEGASUS_ELECTRIC :Электро Lev3 'Pegasus'
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Электро Lev4 'Chimaera'
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :ПаÑÑажирÑкий вагон
+STR_805A_MAIL_VAN :Почтовый вагон
+STR_805B_COAL_CAR :Ð£Ð³Ð¾Ð»ÑŒÐ½Ð°Ñ Ð¿Ð»Ð°Ñ‚Ñ„Ð¾Ñ€Ð¼Ð°
+STR_805C_OIL_TANKER :ÐефтÑÐ½Ð°Ñ Ñ†Ð¸Ñтерна
+STR_805D_LIVESTOCK_VAN :Вагон Ð´Ð»Ñ Ñкота
+STR_805E_GOODS_VAN :Товарный вагон
+STR_805F_GRAIN_HOPPER :Хоппер
+STR_8060_WOOD_TRUCK :Вагон Ð´Ð»Ñ Ð»ÐµÑа
+STR_8061_IRON_ORE_HOPPER :Вагон Ð´Ð»Ñ Ð¶ÐµÐ». руды
+STR_8062_STEEL_TRUCK :Вагон Ð´Ð»Ñ Ñтали
+STR_8063_ARMORED_VAN :Бронированный вагон
+STR_8064_FOOD_VAN :Рефрижератор (еда)
+STR_8065_PAPER_TRUCK :Вагон Ð´Ð»Ñ Ð±ÑƒÐ¼Ð°Ð³Ð¸
+STR_8066_COPPER_ORE_HOPPER :Вагон Ð´Ð»Ñ Ð¼ÐµÐ´Ð½Ð¾Ð¹ руды
+STR_8067_WATER_TANKER :Ð’Ð¾Ð´Ð½Ð°Ñ Ñ†Ð¸Ñтерна
+STR_8068_FRUIT_TRUCK :Рефрижератор (фрукты)
+STR_8069_RUBBER_TRUCK :Вагон Ð´Ð»Ñ Ñ€ÐµÐ·Ð¸Ð½Ñ‹
+STR_806A_SUGAR_TRUCK :Вагон Ð´Ð»Ñ Ñахара
+STR_806B_COTTON_CANDY_HOPPER :Вагон Ð´Ð»Ñ Ñахар. ваты
+STR_806C_TOFFEE_HOPPER :Вагон Ð´Ð»Ñ Ð¸Ñ€Ð¸Ñок
+STR_806D_BUBBLE_VAN :Вагон Ð´Ð»Ñ Ð¿ÑƒÐ·Ñ‹Ñ€ÑŒÐºÐ¾Ð²
+STR_806E_COLA_TANKER :ЦиÑтерна колы
+STR_806F_CANDY_VAN :Вагон Ð´Ð»Ñ ÐºÐ¾Ð½Ñ„ÐµÑ‚
+STR_8070_TOY_VAN :Вагон Ð´Ð»Ñ Ð¸Ð³Ñ€ÑƒÑˆÐµÐº
+STR_8071_BATTERY_TRUCK :Вагон Ð´Ð»Ñ Ð±Ð°Ñ‚Ð°Ñ€ÐµÐµÐº
+STR_8072_FIZZY_DRINK_TRUCK :Вагон Ð´Ð»Ñ Ð³Ð°Ð·Ð¸Ñ€Ð¾Ð²ÐºÐ¸
+STR_8073_PLASTIC_TRUCK :Вагон Ð´Ð»Ñ Ð¿Ð»Ð°Ñтика
+STR_8074_MPS_REGAL_BUS :ÐÐ²Ñ‚Ð¾Ð±ÑƒÑ MPS Regal
+STR_8075_HEREFORD_LEOPARD_BUS :ÐÐ²Ñ‚Ð¾Ð±ÑƒÑ Hereford Leopard
+STR_8076_FOSTER_BUS :ÐÐ²Ñ‚Ð¾Ð±ÑƒÑ Foster
+STR_8077_FOSTER_MKII_SUPERBUS :ÐÐ²Ñ‚Ð¾Ð±ÑƒÑ Foster MkII
+STR_8078_PLODDYPHUT_MKI_BUS :ÐÐ²Ñ‚Ð¾Ð±ÑƒÑ Ploddyphut MkI
+STR_8079_PLODDYPHUT_MKII_BUS :ÐÐ²Ñ‚Ð¾Ð±ÑƒÑ Ploddyphut MkII
+STR_807A_PLODDYPHUT_MKIII_BUS :ÐÐ²Ñ‚Ð¾Ð±ÑƒÑ Ploddyphut MkIII
+STR_807B_BALOGH_COAL_TRUCK :Грузовик Balogh (уголь)
+STR_807C_UHL_COAL_TRUCK :Грузовик Uhl (уголь)
+STR_807D_DW_COAL_TRUCK :Грузовик DW (уголь)
+STR_807E_MPS_MAIL_TRUCK :Грузовик MPS (уголь)
+STR_807F_REYNARD_MAIL_TRUCK :Почтовый фургон Reynard
+STR_8080_PERRY_MAIL_TRUCK :Почтовый фургон Perry
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :Почтовый фургон MightyMover
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Почтовый фургон Powernaught
+STR_8083_WIZZOWOW_MAIL_TRUCK :Почтовый фургон Wizzowow
+STR_8084_WITCOMBE_OIL_TANKER :ЦиÑтерна Witcombe (нефть)
+STR_8085_FOSTER_OIL_TANKER :ЦиÑтерна Foster (нефть)
+STR_8086_PERRY_OIL_TANKER :ЦиÑтерна Perry (нефть)
+STR_8087_TALBOTT_LIVESTOCK_VAN :Скотовозка Talbott
+STR_8088_UHL_LIVESTOCK_VAN :Скотовозка Uhl
+STR_8089_FOSTER_LIVESTOCK_VAN :Скотовозка Foster
+STR_808A_BALOGH_GOODS_TRUCK :Грузовик Balogh (товары)
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Грузовик Craighead (товары)
+STR_808C_GOSS_GOODS_TRUCK :Грузовик Goss (товары)
+STR_808D_HEREFORD_GRAIN_TRUCK :Зерновозка Hereford
+STR_808E_THOMAS_GRAIN_TRUCK :Зерновозка Thomas
+STR_808F_GOSS_GRAIN_TRUCK :Зерновозка Goss
+STR_8090_WITCOMBE_WOOD_TRUCK :Грузовик Witcombe (дерево)
+STR_8091_FOSTER_WOOD_TRUCK :Грузовик Foster (дерево)
+STR_8092_MORELAND_WOOD_TRUCK :Грузовик Moreland (дерево)
+STR_8093_MPS_IRON_ORE_TRUCK :Грузовик MPS (жел. руда)
+STR_8094_UHL_IRON_ORE_TRUCK :Грузовик Uhl (жел. руда)
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Грузовик Chippy (жел. руда)
+STR_8096_BALOGH_STEEL_TRUCK :Грузовик Balogh (Ñталь)
+STR_8097_UHL_STEEL_TRUCK :Грузовик Uhl (Ñталь)
+STR_8098_KELLING_STEEL_TRUCK :Грузовик Kelling (Ñталь)
+STR_8099_BALOGH_ARMORED_TRUCK :Броневик Balogh
+STR_809A_UHL_ARMORED_TRUCK :Броневик Uhl
+STR_809B_FOSTER_ARMORED_TRUCK :Броневик Foster
+STR_809C_FOSTER_FOOD_VAN :Рефрижератор Foster (еда)
+STR_809D_PERRY_FOOD_VAN :Рефрижератор Perry (еда)
+STR_809E_CHIPPY_FOOD_VAN :Рефрижератор Chippy (еда)
+STR_809F_UHL_PAPER_TRUCK :Грузовик Uhl (бумага)
+STR_80A0_BALOGH_PAPER_TRUCK :Грузовик Balogh (бумага)
+STR_80A1_MPS_PAPER_TRUCK :Грузовик MPS (бумага)
+STR_80A2_MPS_COPPER_ORE_TRUCK :Грузовик MPS (медн. руда)
+STR_80A3_UHL_COPPER_ORE_TRUCK :Грузовик Uhl (медн. руда)
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Грузовик Goss (медн. руда)
+STR_80A5_UHL_WATER_TANKER :Ð’Ð¾Ð´Ð½Ð°Ñ Ñ†Ð¸Ñтерна Uhl
+STR_80A6_BALOGH_WATER_TANKER :Ð’Ð¾Ð´Ð½Ð°Ñ Ñ†Ð¸Ñтерна Balogh
+STR_80A7_MPS_WATER_TANKER :Ð’Ð¾Ð´Ð½Ð°Ñ Ñ†Ð¸Ñтерна MPS
+STR_80A8_BALOGH_FRUIT_TRUCK :Рефрижератор Balogh (фрукты)
+STR_80A9_UHL_FRUIT_TRUCK :Рефрижератор Uhl (фрукты)
+STR_80AA_KELLING_FRUIT_TRUCK :Рефрижератор Kelling (фрукты)
+STR_80AB_BALOGH_RUBBER_TRUCK :Грузовик Balogh (резина)
+STR_80AC_UHL_RUBBER_TRUCK :Грузовик Uhl (резина)
+STR_80AD_RMT_RUBBER_TRUCK :Грузовик RMT (резина)
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :Грузовик MightyMover (Ñахар)
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Грузовик Powernaught (Ñахар)
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Грузовик Wizzowow (Ñахар)
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :Грузовик MightyMover (кола)
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Грузовик Powernaught (кола)
+STR_80B3_WIZZOWOW_COLA_TRUCK :Грузовик Wizzowow (кола)
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :Грузовик MightyMover (Ñах. вата)
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Грузовик Powernaught (Ñах. вата)
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Грузовик Wizzowow (Ñах. вата)
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :Грузовик MightyMover (ириÑки)
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Грузовик Powernaught (ириÑки)
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Грузовик Wizzowow (ириÑки)
+STR_80BA_MIGHTYMOVER_TOY_VAN :Грузовик MightyMover (игрушки)
+STR_80BB_POWERNAUGHT_TOY_VAN :Грузовик Powernaught (игрушки)
+STR_80BC_WIZZOWOW_TOY_VAN :Грузовик Wizzowow (игрушки)
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :Грузовик MightyMover (конфеты)
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Powernaught Грузовик конфет
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Грузовик Wizzowow (конфеты)
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :Грузовик MightyMover (батарейки)
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Грузовик Powernaught (батарейки)
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Грузовик Wizzowow (батарейки)
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :Грузовик MightyMover (шипучка)
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Грузовик Powernaught (шипучка)
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Грузовик Wizzowow (шипучка)
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :Грузовик MightyMover (плаÑтик)
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Грузовик Powernaught (плаÑтик)
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Грузовик Wizzowow (плаÑтик)
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :Грузовик MightyMover (пузырьки)
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Грузовик Powernaught (пузырьки)
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Грузовик Wizzowow (пузырьки)
+STR_80CC_MPS_OIL_TANKER :Ðефт. танкер MPS
+STR_80CD_CS_INC_OIL_TANKER :Ðефт. танкер CS-Inc.
+STR_80CE_MPS_PASSENGER_FERRY :ПаÑÑажир. Ñудно MPS
+STR_80CF_FFP_PASSENGER_FERRY :ПаÑÑажир. Ñудно FFP
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Судно на возд. подушке Bakewell 300
+STR_80D1_CHUGGER_CHUG_PASSENGER :Chugger-Chug ПаÑÑажирÑкий паром
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :ПаÑÑажир. Ñудно Shivershake
+STR_80D3_YATE_CARGO_SHIP :Сухогруз Yate
+STR_80D4_BAKEWELL_CARGO_SHIP :Сухогруз Bakewell
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Сухогруз Mightymover
+STR_80D6_POWERNAUT_CARGO_SHIP :Сухогруз Powernaut
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Вертолет Tricario
+STR_80FE_GURU_X2_HELICOPTER :Вертолет Guru X2
+STR_80FF_POWERNAUT_HELICOPTER :Вертолет Powernaut
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Сообщение от Ð¿Ñ€Ð¾Ð¸Ð·Ð²Ð¾Ð´Ð¸Ñ‚ÐµÐ»Ñ Ñ‚Ñ€Ð°Ð½Ñпорта
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}Мы Ñоздали новую модель: {STRING}. ЗаинтереÑованы ли вы в его годовом ÑкÑклюзивном иÑпользовании Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ перед запуÑком в Ñерийное производÑтво?
+STR_8102_RAILROAD_LOCOMOTIVE :ж/д локомотив
+STR_8103_ROAD_VEHICLE :автомобиль
+STR_8104_AIRCRAFT :воздушное Ñудно
+STR_8105_SHIP :корабль
+STR_8106_MONORAIL_LOCOMOTIVE :монорельÑ
+STR_8107_MAGLEV_LOCOMOTIVE :магниторельÑ
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE} Депо {TOWN}
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Жители празднуют . . .{}Первый поезд прибыл на Ñтанцию {STATION}!
+STR_8802_DETAILS :{WHITE}{STRING} (Детали)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Впереди поезд
+STR_8804 :{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8806_GO_TO :Ехать к ÑÑ‚. {STATION}
+STR_8807_GO_TO_TRANSFER :Ехать к ÑÑ‚. {STATION} (Отдать и забрать груз)
+STR_8808_GO_TO_UNLOAD :Ехать к ÑÑ‚. {STATION} (Разгрузка)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Ехать к ÑÑ‚. {STATION} (РазгрузитьÑÑ Ð¸ уехать пуÑтым)
+STR_880A_GO_TO_LOAD :Ехать к ÑÑ‚. {STATION} (ЗагрузитьÑÑ)
+STR_880B_GO_TO_TRANSFER_LOAD :Ехать к ÑÑ‚. {STATION} (Отдать и ждать полной загрузки)
+STR_880C_GO_NON_STOP_TO :Ехать без оÑÑ‚. на {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Ехать без оÑÑ‚. на {STATION} (Отдать и забрать груз)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Ехать без оÑÑ‚. на {STATION} (Разгрузка)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Ехать без оÑÑ‚. на {STATION} (РазгрузитьÑÑ Ð¸ уехать пуÑтым)
+STR_8810_GO_NON_STOP_TO_LOAD :Ехать без оÑÑ‚. на {STATION} (ЗагрузитьÑÑ)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Ехать без оÑÑ‚. на {STATION} (Отдать и ждать полной загрузки)
+STR_GO_TO_TRAIN_DEPOT :Идти в Депо {TOWN}
+STR_SERVICE_AT_TRAIN_DEPOT :ОбÑлуж. в депо {TOWN}
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Ехать без оÑÑ‚. в Депо {TOWN}
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :ОбÑлуж. без оÑÑ‚. в депо {TOWN}
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}Следует в депо {TOWN}
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}Следует в Депо {TOWN}, {VELOCITY}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE :{LTBLUE}ОбÑлуж. в депо {TOWN}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE_VEL :{LTBLUE}ОбÑлуж. в депо {TOWN}, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (Ðеверный Маршрут)
+
+STR_UNKNOWN_DESTINATION :неизвеÑтно назначение
+STR_8812_EMPTY :{LTBLUE}ПуÑто
+STR_8813_FROM :{LTBLUE}{CARGO} из {STATION}
+STR_FROM_MULT :{LTBLUE}{CARGO} из {STATION} (x{NUM})
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}Поезд {COMMA} ждет в депо
+STR_8815_NEW_VEHICLES :{BLACK}Ðовый ТранÑпорт
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Поезд Ñлишком длинный
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Структуру поезда можно менÑÑ‚ÑŒ только в депо
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} Поезда
+
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Ðовый поезд
+STR_NEW_ELRAIL_VEHICLES :{WHITE}Ðовый Ñлектропоезд
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Ðовый монорельÑ
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Ðовый магниторельÑ
+STR_ALL_AVAIL_RAIL_VEHICLES :{WHITE}Поезда
+
+STR_881F_BUILD_VEHICLE :{BLACK}ПоÑтроить
+STR_CLONE_ROAD_VEHICLE :{BLACK}Копировать транÑпорт
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}Создает копию автомобилÑ. Control-щелчок копирует заданиÑ
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Создает копию автомобилÑ. Щелкнуть на кнопке и затем на машине внутри или Ñнаружи гаража. Control-щелчок копирует и заданиÑ
+STR_CLONE_TRAIN :{BLACK}Копировать ÑоÑтав
+STR_CLONE_TRAIN_INFO :{BLACK}Создает копию поезда, Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Ð²Ñе вагоны. Control-клик копирует заданиÑ
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}Создает копию поезда, Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Ð²Ñе вагоны. Щелкнуть на кнопке и затем на поезде внутри или Ñнаружи депо. Control-клик копирует заданиÑ
+STR_8820_RENAME :{BLACK}Переимен.
+STR_8823_SKIP :{BLACK}ПропуÑк
+STR_8824_DELETE :{BLACK}Удалить
+STR_8825_NON_STOP :{BLACK}Б/оÑтанов.
+STR_8826_GO_TO :{BLACK}Ехать
+STR_8827_FULL_LOAD :{BLACK}Загрузка
+STR_8828_UNLOAD :{BLACK}Разгрузка
+STR_REFIT :{BLACK}Переоборуд.
+STR_REFIT_TIP :{BLACK}Выберите тип грузов Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¾Ð±Ð¾Ñ€ÑƒÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ. CTRL+клик - Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ.
+STR_REFIT_ORDER :(Переоборуд. Ð´Ð»Ñ {STRING})
+STR_8829_ORDERS :{WHITE}{VEHICLE} (ЗаданиÑ)
+STR_882A_END_OF_ORDERS :{SETX 10}- - Конец ÑпиÑка заданий - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}ОбÑлуживание
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Ðевозможно поÑтроить ж/д транÑпорт...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} ПоÑтроен: {LTBLUE}{NUM}{BLACK} СтоимоÑÑ‚ÑŒ: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} СтоимоÑÑ‚ÑŒ: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}Разгрузка/Погрузка
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}Поезд должен быть оÑтановлен в депо
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Ðевозможно отправить поезд в депо...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Ðет больше меÑта Ð´Ð»Ñ Ð·Ð°Ð´Ð°Ð½Ð¸Ð¹
+STR_8832_TOO_MANY_ORDERS :{WHITE}Слишком много заданий
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Ðевозможно вÑтавить новое задание...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Ðевозможно удалить Ñто задание...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Ðевозможно изменить Ñто задание...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Ðевозможно перемеÑтить транÑп. ÑредÑтво...
+STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}Тыловой локомотив вÑегда Ñледует за его передней чаÑтью
+STR_8838_N_A :недоÑтупно{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Ðевозможно продать рельÑовый транÑпорт...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Ðевозможно найти дорогу к депо
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Ðевозможно оÑтановить/запуÑтить поезд...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}ОÑмотр каждые: {LTBLUE}{COMMA}дней{BLACK} ПоÑледний раз: {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Интервал обÑлуж.: {LTBLUE}{COMMA}%{BLACK} ПоÑледний раз: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Поезда - нажмите Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñправки
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}ПоÑтроить новые поезда (Ñначала требуетÑÑ Ð¿Ð¾Ñтроить депо)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Поезда - кликните Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ð¸, иÑпользуйте перетаÑкивание Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÑоÑтава
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}ПоÑтроить новый поезд
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Перетащите вагон Ñюда, чтобы продать его
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Показать депо в оÑновном окне
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Выбор вагонов - кликните Ð´Ð»Ñ Ñправки
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}ПоÑтроить выделенный вагон
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Переименовать тип вагона
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Текущее дейÑтвие, кликните, чтобы оÑтановить/запуÑтить поезд
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Показать ÑпиÑок заданий
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Показать поезд в оÑновном окне
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Отправить поезд в депо
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Принудительно заÑтавить поезд игнорировать краÑный Ñвет Ñветофора
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Развернуть поезд
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Показать информацию о поезде
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Увеличить интервал обÑлуживаниÑ
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Уменьшить интервал обÑлуживаниÑ
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Показать ÑÐ²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ перевозимых грузах
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Показать ÑÐ²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ вагонах
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Показать вмеÑтимоÑÑ‚ÑŒ вагонов
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Показать общую вмеÑтимоÑÑ‚ÑŒ поезда по типам грузов
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Показать ÑпиÑок заданий - кликните Ð´Ð»Ñ Ð²Ñ‹Ð´ÐµÐ»ÐµÐ½Ð¸Ñ. CTRL+клик - переход к Ñтанции.
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}ПропуÑтить текущее задание и перейти к Ñледующему
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Удалить выделенное задание
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Ехать по выбранному заданию без оÑтановки
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Ð’Ñтавить новое задание перед выделенным или в конец ÑпиÑка
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Задать ожидание полной загрузки
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Задание ожидание полной разгрузки
+STR_SERVICE_HINT :{BLACK}ПропуÑтить Ñто задание, еÑли обÑлуживание не требуетÑÑ
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}Теперь доÑтупно {STRING}!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Цена: {CURRENCY} ВеÑ: {WEIGHT_S}{}СкороÑÑ‚ÑŒ: {VELOCITY} МощноÑÑ‚ÑŒ: {POWER}{}Цена обÑлуж.: {CURRENCY}/год{}ЕмкоÑÑ‚ÑŒ: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}Поломка
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}ВозраÑÑ‚: {LTBLUE}{STRING}{BLACK} СтоимоÑÑ‚ÑŒ обÑлуживаниÑ: {LTBLUE}{CURRENCY}/год
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}ВеÑ: {LTBLUE}{WEIGHT_S} {BLACK}МощноÑÑ‚ÑŒ: {LTBLUE}{POWER}{BLACK} МакÑ. ÑкороÑÑ‚ÑŒ: {LTBLUE}{VELOCITY}
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}ВеÑ: {LTBLUE}{WEIGHT_S} {BLACK}МощноÑÑ‚ÑŒ: {LTBLUE}{POWER}{BLACK} МакÑ. ÑкороÑÑ‚ÑŒ: {LTBLUE}{VELOCITY} {BLACK}МакÑ. ТÑговое УÑилие: {LTBLUE}{FORCE}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Прибыль в Ñтом году: {LTBLUE}{CURRENCY} (прошлый год: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}ÐадежноÑÑ‚ÑŒ: {LTBLUE}{COMMA}% {BLACK}Поломок Ñ Ð¿Ð¾Ñледнего ремонта: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}ОÑтановлен
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Ðевозможно игнорировать Ñигнал. ОпаÑно ...
+STR_8863_CRASHED :{RED}Потерпел крушение!
+
+STR_8865_NAME_TRAIN :{WHITE}Ðазвать поезд
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}Ðевозможно назвать поезд...
+STR_8867_NAME_TRAIN :{BLACK}Ðазвать поезд
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Крушение поезда!{}{COMMA} чел. погибло в огне!
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Ðевозможно развернуть поезд...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Переименовать тип вагона
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Ðевозможно переименовать тип вагона ...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}По выделенному приказу произойдет Ð¿Ñ€Ð¸Ð½ÑƒÐ´Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ñ€Ð°Ð·Ð³Ñ€ÑƒÐ·ÐºÐ° транÑпортного ÑредÑтва
+STR_886F_TRANSFER :{BLACK}ТранÑфер
+
+STR_TRAIN_STOPPING :{RED}ОÑтановлен
+STR_TRAIN_STOPPING_VEL :{RED}ОÑтанавливаю, {VELOCITY}
+STR_INCOMPATIBLE_RAIL_TYPES :IÐеÑовмеÑтимый тип рельÑов
+STR_TRAIN_NO_POWER :{RED}Ðет тока.
+STR_TRAIN_START_NO_CATENARY :Кто-то украл вÑе провода, поезд не может ехать ...
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Машина на пути
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} Ðвтомашин
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}{TOWN} Гараж
+STR_9004_NEW_VEHICLES :{BLACK}ÐÐ¾Ð²Ð°Ñ ÐœÐ°ÑˆÐ¸Ð½Ð°
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}ÐÐ¾Ð²Ð°Ñ ÐœÐ°ÑˆÐ¸Ð½Ð°
+STR_9007_BUILD_VEHICLE :{BLACK}ПоÑтроить
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Ðевозможно поÑтроить машину...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (Детали)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}ВозраÑÑ‚: {LTBLUE}{STRING}{BLACK} Цена обÑлуживаниÑ: {LTBLUE}{CURRENCY}/год
+STR_900E_MAX_SPEED :{BLACK}МакÑ. ÑкороÑÑ‚ÑŒ: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Прибыль в Ñтом году: {LTBLUE}{CURRENCY} (прошлый год: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}ÐадежноÑÑ‚ÑŒ: {LTBLUE}{COMMA}% {BLACK}Поломок Ñ Ð¿Ð¾Ñледнего ремонта: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} ПоÑтроено: {LTBLUE}{NUM}{BLACK} Цена: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}ЕмкоÑÑ‚ÑŒ: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}...должен быть оÑтановлен в гараже
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Ðевозможно продать автомобиль...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Ðевозможно оÑтановить/пуÑтить автомобиль...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}Машина {COMMA} ждет в гараже
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}Следует в Гараж {TOWN}
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}Следует в гараж {TOWN}, {VELOCITY}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE :{LTBLUE}ОбÑлуж. в гараже {TOWN}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE_VEL :{LTBLUE}ОбÑлуж. в гараже {TOWN}, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Ðевозможно отправить машину в гараж...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Ðевозможно найти гараж
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Ðвтомобили - кликните Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð¾Ð¹ информации
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}ПоÑтроить новые автомобили (требуетÑÑ Ð³Ð°Ñ€Ð°Ð¶)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Текущее задание автомобилÑ, кликните, чтобы оÑтановить/запуÑтить его
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Показать заданиÑ
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Показать автомобиль в главном окне
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Отправить автомобиль в гараж. CTRL+клик - только Ð´Ð»Ñ Ð¾Ð±ÑлуживаниÑ.
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Принудительно развернуть автомобиль
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Показать информацию об автомобиле
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Ðвтомобили - кликните Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñправки
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}ПоÑтроить новый автомобиль
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Перетащить автомобиль Ñюда Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Показать гараж в главном окне
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}СпиÑок автомобилей - кликните Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ð¸
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}ПоÑтроить выделенный автомобиль
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}ДоÑтупна Ð½Ð¾Ð²Ð°Ñ Ð¼Ð¾Ð´ÐµÐ»ÑŒ автомобилÑ!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Цена: {CURRENCY}{}СкороÑÑ‚ÑŒ: {VELOCITY}{}СтоимоÑÑ‚ÑŒ обÑлуж.: {CURRENCY}/год{}ЕмкоÑÑ‚ÑŒ: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Ðазвать автомобиль
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Ðевозможно переименовать автомобиль ...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Ðазвать автомобиль
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Жители празднуют . . .{}Первый Ð°Ð²Ñ‚Ð¾Ð±ÑƒÑ Ð¿Ñ€Ð¸Ð±Ñ‹Ð» на оÑтановку {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Жители празднуют . . .{}Первый грузовик прибыл на Ñтанцию {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}ÐÐ’ÐРИЯ!{}Водитель погиб при Ñтолкновении Ñ Ð¿Ð¾ÐµÐ·Ð´Ð¾Ð¼
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}ÐÐ’ÐРИЯ!{}{COMMA} человек погибло в Ñтолкновении Ñ Ð¿Ð¾ÐµÐ·Ð´Ð¾Ð¼
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Ðевозможно развернуть автомобиль ...
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}Ðевозможно развернуть многоÑоÑтавной транÑпорт
+STR_9034_RENAME :{BLACK}Переимен.
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Переименовать автомобиль
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Переименовать автомобиль
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Ðевозможно переименовать автомобиль ...
+STR_9038_GO_TO_ROADVEH_DEPOT :Ехать в гараж {TOWN}
+STR_SERVICE_AT_ROADVEH_DEPOT :ОбÑлуж. в гараже {TOWN}
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Переоборуд. авто Ð´Ð»Ñ Ð´Ð¾Ñтавки разных видов грузов.
+STR_REFIT_ROAD_VEHICLE :{BLACK}Переоборуд. авто
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Переоборуд авто Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ð¾Ð·ÐºÐ¸ доÑтупных видов грузов
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Ðевозмжно переоборуд. авто...
+STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Выберите тип грузов Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ð¾Ð·ÐºÐ¸
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :СтроительÑтво РЕКÐ-МОРЕ
+STR_9801_DOCK_CONSTRUCTION :{WHITE}СтроительÑтво РЕКÐ-МОРЕ
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Ðевозможно поÑтроить приÑтань здеÑÑŒ...
+STR_9803_SHIP_DEPOT :{WHITE}{TOWN} ДОК
+STR_9804_NEW_SHIPS :{BLACK}Ðовые корабли
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} Корабли
+STR_9808_NEW_SHIPS :{WHITE}Ðовые корабли
+STR_9809_BUILD_SHIP :{BLACK}Купить Корабль
+STR_CLONE_SHIP :{BLACK}Копировать Судно
+STR_CLONE_SHIP_INFO :{BLACK}Создает копию кораблÑ. Control-клик копирует заданиÑ
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}Создает копию кораблÑ. Щелкнуть на кнопке и затем на корабле внутри или Ñнаружи дока. Control-клик копирует заданиÑ
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}Корабль должен быть оÑтановлен в доке
+STR_980C_CAN_T_SELL_SHIP :{WHITE}Ðевозможно продать корабль...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Ðевозможно поÑтроить корабль...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Корабль на пути
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Детали)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}ВозраÑÑ‚: {LTBLUE}{STRING}{BLACK} СтоимоÑÑ‚ÑŒ обÑлуж.: {LTBLUE}{CURRENCY}/год
+STR_9813_MAX_SPEED :{BLACK}МакÑ. ÑкороÑÑ‚ÑŒ: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Прибыль в Ñтом году: {LTBLUE}{CURRENCY} (прошлый год: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}ÐадежноÑÑ‚ÑŒ: {LTBLUE}{COMMA}% {BLACK}Поломок Ñ Ð¿Ð¾Ñледнего обÑлуж.: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} ПоÑтроено: {LTBLUE}{NUM}{BLACK} СтоимоÑÑ‚ÑŒ: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}ЕмкоÑÑ‚ÑŒ: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}Ðе могу оÑтановть/запуÑтить корабль...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Ðе могу отправить корабль в док...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Ðевозможно найти док
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}Следует в док {TOWN}
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}Следует в док {TOWN}, {VELOCITY}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE :{LTBLUE}ОбÑлуж. в доке {TOWN}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE_VEL :{LTBLUE}ОбÑлуж. в доке {TOWN}, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}Корабль {COMMA} ожидает в доке
+STR_981D_BUILD_SHIP_DOCK :{BLACK}ПоÑтроить док
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}ПоÑтроить док (Ð´Ð»Ñ Ð¾Ð±ÑÐ»ÑƒÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð¸ ремонта кораблей)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Корабли - нажмите Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñправки
+STR_9820_BUILD_NEW_SHIP :{BLACK}ПоÑтроить новый корабль
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Перетащите корабль Ñюда Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð°Ð¶Ð¸
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Показать док в оÑновном окне
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Корабли - нажмите Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñправки
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}ПоÑтроить новый корабль (требуетÑÑ Ð´Ð¾Ðº)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}СпиÑок кораблей - нажмите Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñправки
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}ПоÑтроить выбранный корабль
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Текущее задание ÐºÐ¾Ñ€Ð°Ð±Ð»Ñ - кликните Ð´Ð»Ñ Ð·Ð°Ð¿ÑƒÑка/оÑтановки
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Показать заданиÑ
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Показать корабль в главном окне
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Отправить корабль в док. CTRL+клик - только Ð´Ð»Ñ Ð¾Ð±ÑлуживаниÑ
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Показать информацию о корабле
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}ДоÑтупен новый корабль!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Цена: {CURRENCY} МакÑ. СкороÑÑ‚ÑŒ: {VELOCITY}{}ЕмкоÑÑ‚ÑŒ: {CARGO}{}СтоимоÑÑ‚ÑŒ обÑлуж.: {CURRENCY}/год
+STR_982F_NAME_SHIP :{BLACK}Ðазвание кораблÑ
+
+STR_9831_NAME_SHIP :{WHITE}Ðазвание кораблÑ
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Ðе могу назвать корабль...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Жители празднуют . . .{}Первый корабль причалил к {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}ПоÑтройте буй, чтобы иÑпользовать его как точку маршрута
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Ðе могу поÑтроить буй здеÑÑŒ...
+STR_9836_RENAME :{BLACK}Переимен.
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Переименовать
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Переименовать
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Ðевозможно переименовать Ñудно...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Переоборудовать корабль Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ð¾Ð·ÐºÐ¸ других грузов
+STR_983B_REFIT :{WHITE}{VEHICLE} (Переоборудовать)
+STR_983C_REFIT_SHIP :{BLACK}Переоборудовать корабль
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Выберите тип груза Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ð¾Ð·ÐºÐ¸
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Переоборудовать корабль Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ð¾Ð·ÐºÐ¸ выбранного груза
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Выборите тип груза Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ð¾Ð·ÐºÐ¸:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}ÐÐ¾Ð²Ð°Ñ ÐµÐ¼ÐºÐ¾ÑÑ‚ÑŒ: {GOLD}{CARGO}{}{BLACK}СтоимоÑÑ‚ÑŒ переоборуд.: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Ðе могу переоборуд. корабль......
+STR_9842_REFITTABLE :(переоборудование)
+STR_GO_TO_SHIP_DEPOT :Плыть в Док {TOWN}
+SERVICE_AT_SHIP_DEPOT :ОбÑлуживание в доке {TOWN}
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}ÐÑропорты
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Ðевозможно поÑтроить аÑропорт здеÑÑŒ...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} Ðнгар
+STR_A003_NEW_AIRCRAFT :{BLACK}Ðовый
+STR_CLONE_AIRCRAFT :{BLACK}Копировать транÑпорт
+STR_CLONE_AIRCRAFT_INFO :{BLACK}Создает копию Ñамолета. Control-клик - копируе заданиÑ
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}ПоÑтроить копию возд. Ñудна. Ðажмите на кнопку, а потом на возд. Ñудно в/вне ангара. CTRL+click - также Ñкопирует и задание.
+STR_A005_NEW_AIRCRAFT :{WHITE}Ðовый
+STR_A006_BUILD_AIRCRAFT :{BLACK}ПоÑтроить
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Ðевозможно поÑтроить возд. транÑпорт...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} ÐвиатранÑпорт
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (ЗаданиÑ)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (Детали)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}ВозраÑÑ‚: {LTBLUE}{STRING}{BLACK} СтоимоÑÑ‚ÑŒ обÑлуж.: {LTBLUE}{CURRENCY}/год
+STR_A00E_MAX_SPEED :{BLACK}МакÑ. ÑкороÑÑ‚ÑŒ: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Прибыль в Ñтом году: {LTBLUE}{CURRENCY} (прошлый год: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}ÐадежноÑÑ‚ÑŒ: {LTBLUE}{COMMA}% {BLACK}Поломок Ñ Ð¿Ð¾Ñледнего ремонта: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} ПоÑтроено: {LTBLUE}{NUM}{BLACK} Цена: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Ðевозможно отправить его в ангар...
+STR_HEADING_FOR_HANGAR :{ORANGE}Летит в Ðнгар {STATION}
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}Следует в Ðнгар {STATION}, {VELOCITY}
+STR_HEADING_FOR_HANGAR_SERVICE :{LTBLUE}ОбÑлуж. в ангаре {STATION}
+STR_HEADING_FOR_HANGAR_SERVICE_VEL :{LTBLUE}ОбÑлуж. в ангаре {STATION}, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}ТранÑпорт {COMMA} ждет в ангаре
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}ОРЛЕТИТ!
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Ðевозможно оÑтановить/запуÑтить транÑпорт...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Самолет в полете
+STR_A019_CAPACITY :{BLACK}ЕмкоÑÑ‚ÑŒ: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}ЕмкоÑÑ‚ÑŒ: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}Самолет должен быть оÑтановлен в ангаре
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Ðе могу продать Ñамолет...
+STR_A01D_AIRPORT_CONSTRUCTION :СтроительÑтво аÑропорта
+STR_A01E_BUILD_AIRPORT :{BLACK}ПоÑтроить аÑропорт
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}ÐвиатранÑпорт - нажмите Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñправки
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}ПоÑтроить новый авиатранÑпорт (нужен аÑропорт Ñ Ð°Ð½Ð³Ð°Ñ€Ð¾Ð¼)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}ÐвиатранÑпорт - нажмите Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñправки
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}ПоÑтроить новый авиатранÑпорт
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}Перетащите транÑпорт Ñюда Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð°Ð¶Ð¸
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Показать ангар в главном окне
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}ÐвиатранÑпорт - нажмите Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñправки
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}ПоÑтроить выделенный авиатранÑпорт
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Текущее задание, кликните Ð´Ð»Ñ Ð·Ð°Ð¿ÑƒÑка/оÑтановки авиатранÑпорта
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Показать заданиÑ
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Показать транÑпорт в главном окне
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}ПоÑлать авиатранÑпорт в ангар. CTRL+клик - только Ð´Ð»Ñ Ð¾Ð±ÑлуживаниÑ.
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Показать ÑÐ²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾Ð± авиатранÑпорте.
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}Ðовое воздушное Ñудно!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Цена: {CURRENCY} МакÑ. СкороÑÑ‚ÑŒ: {VELOCITY}{}ЕмкоÑÑ‚ÑŒ: {COMMA} паÑÑажиров, {COMMA} почты{}Цена обÑлуж.: {CURRENCY}/год
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Ðазвание Ñамолета
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Ðе могу назвать Ñамолет...
+STR_A032_NAME_AIRCRAFT :{BLACK}Ðазвание Ñамолета
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Жители празднуют . . .{}Первый Ñамолет прибыл в {STATION}!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}ÐвиакатаÑтрофа!{}{COMMA} человек погибло в огне в {STATION}
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}ÐвиакатаÑтрофа{}Ð’ Ñамолете закончилоÑÑŒ топливо, {COMMA} человек погибли при Ñтолкновении Ñ Ð·ÐµÐ¼Ð»ÐµÐ¹!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Переимен.
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Переименовать
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Переименовать
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Ðевозможно переименовать...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Переоборудовать транÑпорт Ð´Ð»Ñ Ð´Ñ€ÑƒÐ³Ð¸Ñ… грузов
+STR_A03C_REFIT :{WHITE}{VEHICLE} (Переоборуд.)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Переоборудовать
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Выберите тип грузов Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ð¾Ð·ÐºÐ¸
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Переоборудовать транÑпорт Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ð¾Ð·ÐºÐ¸ выбранного типа груза
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Выберите тип груза Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ð¾Ð·ÐºÐ¸:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}ÐÐ¾Ð²Ð°Ñ ÐµÐ¼ÐºÐ¾ÑÑ‚ÑŒ: {GOLD}{STRING}{}{BLACK}СтоимоÑÑ‚ÑŒ переоборуд.: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Ðевозможно переоборудовать...
+STR_GO_TO_AIRPORT_HANGAR :Лететь в Ðнгар {STATION}
+SERVICE_AT_AIRPORT_HANGAR :Ð¡ÐµÑ€Ð²Ð¸Ñ Ð² ангаре {STATION}
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}Крушение Ð´Ð¸Ñ€Ð¸Ð¶Ð°Ð±Ð»Ñ Ð² {STATION}!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Ðвтомобиль уничтожен при Ñтолкновении Ñ ÐЛО!
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}Взрыв нефтеперегонного завода вблизи {TOWN}!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}Взрыв завода при подозрительных обÑтоÑтельÑтвах вблизи {TOWN}!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}ÐЛО приземлилоÑÑŒ возле {TOWN}!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}Обвал на угольной шахте вызывает оползень около {TOWN}!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}ÐÐВОДÐЕÐИЕ!{}По крайней мере {COMMA} Ñкорее вÑего погибли при наводнении!
+
+STR_BRIBE_FAILED :{WHITE}Ваша попытка дать взÑтку была
+STR_BRIBE_FAILED_2 :{WHITE}обнаружена региональным Ñледователем
+STR_BUILD_DATE :{BLACK}ПоÑтроено: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Подробные данные
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}Детали
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}ТранÑпорта:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Станции:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Мин. прибыль:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Мин. доход:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}МакÑ. доход:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}ДоÑтавлено:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Груз:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Деньги:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Займ:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Ð’Ñего:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}ЧиÑло транÑпорта; Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Ð¼Ð°ÑˆÐ¸Ð½Ñ‹, поезда, корабли и Ñамолеты
+STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}ЧиÑло чаÑтей Ñтанции. ÐšÐ°Ð¶Ð´Ð°Ñ Ñ‡Ð°ÑÑ‚ÑŒ Ñтанции (Ñ‚.е. ЖД Ñтанции, оÑтановки, аÑропорт) подÑчитана, даже еÑли они ÑвÑзаны как одна ÑтанциÑ
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}Прибыль транÑпорта Ñ Ñамым низким доходом (из вÑех транÑпортных ÑредÑтв, Ñтарше чем 2 года)
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Сумма наличных, ÑÐ´ÐµÐ»Ð°Ð½Ð½Ð°Ñ Ð² меÑÑце Ñ Ñамой низкой прибылью за поÑледние 12 кварталов
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Сумма наличных, ÑÐ´ÐµÐ»Ð°Ð½Ð½Ð°Ñ Ð² меÑÑце Ñ Ñамой выÑокой прибылью за поÑледние 12 кварталов
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}Кол-во груза, доÑтавленного за поÑледние 4 квартала
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}КоличеÑтво типов груза, доÑтавленных за поÑледний квартал
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Сумма денег Ñтой компании имеющихÑÑ Ð² банке
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}Сумма денег Ñтой компании взÑтые взаймы
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Ð’Ñего пунктов из общего количеÑтва возможных
+
+STR_NEWGRF_SETTINGS_BUTTON :{BLACK}ÐаÑтройки NewGRF
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}ÐаÑтройки NewGRF
+STR_NEWGRF_APPLY_CHANGES :{BLACK}Применить изменениÑ
+STR_NEWGRF_SET_PARAMETERS :{BLACK}Параметры
+STR_NEWGRF_TIP :{BLACK}СпиÑок вÑех NewGRF ÑÑтов, которые у Ð²Ð°Ñ ÑƒÑтановлены. Выбрать Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½Ð°Ñтроек
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}Ð’ наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð½ÐµÑ‚ никаких уÑтановленных NEWGRF файлов! ПожалуйÑта обратитеÑÑŒ к опиÑанию Ð´Ð»Ñ Ð¸Ð½Ñтрукций Ð´Ð»Ñ ÑƒÑтановки Ðовой Графики
+STR_NEWGRF_FILENAME :{BLACK}Ð˜Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
+STR_NEWGRF_MD5SUM :{BLACK}Сумма MD5: {SILVER}{STRING}
+STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}Ð’Ñ‹ хотите Ñделать Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² уже запущенной игре - Ñто может привеÑти к ошибке игры, и ее вылету.{}Ð’Ñ‹ абÑолютно уверены в том, что хотите Ñделать?
+
+STR_NEWGRF_ADD :{BLACK}Добавить
+STR_NEWGRF_ADD_TIP :{BLACK}Добавить NewGRF файл в ÑпиÑок
+STR_NEWGRF_REMOVE :{BLACK}Удалить
+STR_NEWGRF_REMOVE_TIP :{BLACK}Удалить выбранный NewGRF файл из ÑпиÑка
+STR_NEWGRF_MOVEUP :{BLACK}Вверх
+STR_NEWGRF_MOVEUP_TIP :{BLACK}ПеремеÑтить выбранный NewGRF файл выше
+STR_NEWGRF_MOVEDOWN :{BLACK}Вниз
+STR_NEWGRF_MOVEDOWN_TIP :{BLACK}ПеремеÑтить выбранный NewGRF файл ниже
+STR_NEWGRF_FILE_TIP :{BLACK}СпиÑок уÑтановленных NewGRF файлов. Выберите файл Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÐµÐ³Ð¾ параметров.
+STR_NEWGRF_PARAMETER :{BLACK}Параметры: {SILVER}{STRING}
+STR_NEWGRF_PARAMETER_QUERY :{BLACK}Введите параметры NewGRF
+STR_NEWGRF_NO_INFO :{BLACK}Ðет доÑтупной информации
+
+STR_NEWGRF_ADD_CAPTION :{WHITE}ДоÑтупные NewGRF файлы
+STR_NEWGRF_ADD_FILE :{BLACK}Добавить выбранное
+STR_NEWGRF_ADD_FILE_TIP :{BLACK}Добавить выбранный NewGRF файл в вашу конфигурацию.
+STR_NEWGRF_RESCAN_FILES :{BLACK}Обновить
+STR_NEWGRF_RESCAN_FILES_TIP :{BLACK}Обновить ÑпиÑок доÑтупных NewGRF файлов
+STR_NEWGRF_DUPLICATE_GRFID :{WHITE}Ðевозможно добавить файл - дублируютÑÑ GRF ID
+
+STR_NEWGRF_NOT_FOUND :{RED}Файл не найден
+STR_NEWGRF_DISABLED :{RED}Отключено
+
+STR_CURRENCY_WINDOW :{WHITE}Валюта
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Обменный курÑ: {ORANGE}{CURRENCY} = Ј {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Разделитель:
+STR_CURRENCY_PREFIX :{LTBLUE}ПрефикÑ:
+STR_CURRENCY_SUFFIX :{LTBLUE}СуффикÑ:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Переход на Евро: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Переход на Евро: {ORANGE}never
+STR_CURRENCY_PREVIEW :{LTBLUE}Образец: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Изменить параметр валюты
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} Поезда
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} Машины
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} Самолеты
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} Корабли
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Показать вÑе поезда, в раÑпиÑании которых еÑÑ‚ÑŒ Ñта ÑтанциÑ
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Показать вÑе автомашины, в раÑпиÑании которых еÑÑ‚ÑŒ Ñта ÑтанциÑ/оÑтановка
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Показать веÑÑŒ авиатранÑпорт, в раÑпиÑании которого еÑÑ‚ÑŒ Ñтот аÑропорт
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Показать вÑе корабли, в раÑпиÑании которых еÑÑ‚ÑŒ Ñта приÑтань
+
+STR_VEH_WITH_SHARED_ORDERS_LIST :{WHITE}Общие Ð·Ð°Ð´Ð°Ð½Ð¸Ñ Ð´Ð»Ñ {COMMA} ед. транÑпорта
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}Показать веÑÑŒ транÑпорт Ñ Ñтим раÑпиÑанием
+
+### depot strings
+STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}ВеÑÑŒ транÑпорт в депо будет продан. Ð’Ñ‹ уверены?
+
+STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP :{BLACK}Продать вÑе поезда в депо
+STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP :{BLACK}Продать вÑе авто в гараже
+STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP :{BLACK}Продать вÑе Ñуда в доке
+STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP :{BLACK}Продать веÑÑŒ авиатранÑпорт в ангаре
+
+STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP :{BLACK}Получить ÑпиÑок поездов, у которых в заданиÑÑ… еÑÑ‚ÑŒ Ñто депо
+STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP :{BLACK}Получить ÑпиÑок авто, у которых в заданиÑÑ… еÑÑ‚ÑŒ Ñтот гараж
+STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP :{BLACK}Получить ÑпиÑок Ñудов, у которых в заданиÑÑ… еÑÑ‚ÑŒ Ñтот док
+STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP :{BLACK}Получить ÑпиÑок авиатранÑпорта, у которого в заданиÑÑ… еÑÑ‚ÑŒ Ñтот ангар
+
+STR_DEPOT_AUTOREPLACE_TRAIN_TIP :{BLACK}Ðвтозамена вÑех поездов в депо
+STR_DEPOT_AUTOREPLACE_ROADVEH_TIP :{BLACK}Ðвтозамена вÑех авто в гараже
+STR_DEPOT_AUTOREPLACE_SHIP_TIP :{BLACK}Ðвтозамена вÑех Ñудов в доке
+STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP :{BLACK}Ðвтозамена вÑего авиатранÑпорта в ангаре
+
+STR_VEHICLE_LIST_TRAIN_DEPOT :{BLACK}{STRING} - {COMMA} поездов
+STR_VEHICLE_LIST_ROADVEH_DEPOT :{BLACK}{STRING} - {COMMA} автомобилей
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} кораблей
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} авиатранÑпорта
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}Замена {STRING}
+STR_REPLACE_VEHICLES_START :{BLACK}ПуÑк Замены ТранÑпорта
+STR_REPLACE_VEHICLES_STOP :{BLACK}Стоп Замены ТранÑпорта
+STR_NOT_REPLACING :{BLACK}Ðе заменÑÑ‚ÑŒ
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Ðе выбран транÑпорт
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Выбор типа транÑпорта Ð´Ð»Ñ Ð·Ð°Ð¼ÐµÐ½Ñ‹
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Выбор нового типа машин, который хотелоÑÑŒ бы иÑпользовать вмеÑто выбранного Ñлева типа транÑпорта
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Ð”Ð»Ñ Ð¾Ñтановки замены типа машин выбранного Ñлева нажать
+STR_REPLACE_HELP_START_BUTTON :{BLACK}Ðажать Ð´Ð»Ñ Ð½Ð°Ñ‡Ð°Ð»Ð° замены выбранного Ñлева типа на выбранный Ñправа тип
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Выберите тип рельÑового транÑпорта, который вы желаете заменить
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Показывает, на какой локомотив заменÑетÑÑ Ð»Ð¾ÐºÐ¾Ð¼Ð¾Ñ‚Ð¸Ð², выбранный Ñлева.
+STR_REPLACE_HELP :{BLACK}Это позволит заменить один тип транÑпорта на другой, когда поезд заходит в депо
+STR_REPLACE_REMOVE_WAGON :{BLACK}Удаление вагона: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Разрешить при автозамене ÑохранÑÑ‚ÑŒ длину поездов удалением вагонов (Ð½Ð°Ñ‡Ð¸Ð½Ð°Ñ Ñ Ð³Ð¾Ð»Ð¾Ð²Ñ‹ поезда), еÑли при автозамене увеличитÑÑ Ð´Ð»Ð¸Ð½Ð° поезда.
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}ЗаменÑем: {ORANGE}{SKIP}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}ЭКСПЕРИМЕÐТÐЛЬÐО {}Переключение между окнами замены локомотивов и вагонов.{}Ðвтозамена вагонов производитÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ в том Ñлучае, еÑли Ñовпадает тип перевозимых грузов. Эта проверка производитÑÑ Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ вагона во Ð²Ñ€ÐµÐ¼Ñ Ð°Ð²Ñ‚Ð¾Ð·Ð°Ð¼ÐµÐ½Ñ‹.
+STR_ENGINE_NOT_BUILDABLE :{WHITE}ÐÐµÐ»ÑŒÐ·Ñ Ð¿Ð¾Ñтроить локомотив
+
+STR_ENGINES :Локомотивы
+STR_WAGONS :Вагоны
+
+STR_MASS_STOP_DEPOT_TRAIN_TIP :{BLACK}Ðажмите Ð´Ð»Ñ Ð¾Ñтановки вÑех поездов в депо
+STR_MASS_STOP_DEPOT_ROADVEH_TIP :{BLACK}Ðажмите Ð´Ð»Ñ Ð¾Ñтановки вÑех авто в гараже
+STR_MASS_STOP_DEPOT_SHIP_TIP :{BLACK}Ðажмите Ð´Ð»Ñ Ð¾Ñтановки вÑех кораблей в доке
+STR_MASS_STOP_HANGAR_TIP :{BLACK}Ðажмите Ð´Ð»Ñ Ð¾Ñтановки вÑего авиатранÑпорта в ангаре
+
+STR_MASS_START_DEPOT_TRAIN_TIP :{BLACK}Ðажмите Ð´Ð»Ñ Ð·Ð°Ð¿ÑƒÑка вÑех поездов в депо
+STR_MASS_START_DEPOT_ROADVEH_TIP :{BLACK}Ðажмите Ð´Ð»Ñ Ð·Ð°Ð¿ÑƒÑка вÑех авто в гараже
+STR_MASS_START_DEPOT_SHIP_TIP :{BLACK}Ðажмите Ð´Ð»Ñ Ð·Ð°Ð¿ÑƒÑка вÑех Ñудов в доке
+STR_MASS_START_HANGAR_TIP :{BLACK}Ðажмите Ð´Ð»Ñ Ð·Ð°Ð¿ÑƒÑка вÑего авиатранÑпорта в ангаре
+
+STR_MASS_STOP_LIST_TIP :{BLACK}Ðажмите Ð´Ð»Ñ Ð¾Ñтановки вÑего транÑпорта в ÑпиÑке
+STR_MASS_START_LIST_TIP :{BLACK}Ðажмите Ð´Ð»Ñ Ð·Ð°Ð¿ÑƒÑка вÑего транÑпорта в ÑпиÑке
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}СпиÑок меток - {COMMA} Метки
+
+STR_ORDER_REFIT_FAILED :{WHITE}Ошибка Ð·Ð°Ð´Ð°Ð½Ð¸Ñ Ð¿ÐµÑ€ÐµÐ¾Ð±Ð¾Ñ€ÑƒÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ {STRING} {COMMA}
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :ЖД ТранÑпорт
+STR_ELRAIL_VEHICLES :Элетропоезда
+STR_MONORAIL_VEHICLES :МонорельÑовый ТранÑпорт
+STR_MAGLEV_VEHICLES :Магнитный ТранÑпорт
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Цена: {GOLD}{CURRENCY}{BLACK} ВеÑ: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}СкороÑÑ‚ÑŒ: {GOLD}{VELOCITY}{BLACK} МощноÑÑ‚ÑŒ: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}СкороÑÑ‚ÑŒ: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}СтоимоÑÑ‚ÑŒ обÑлуж.: {GOLD}{CURRENCY}/год
+STR_PURCHASE_INFO_CAPACITY :{BLACK}ЕмкоÑÑ‚ÑŒ: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Разработано в: {GOLD}{NUM}{BLACK} Срок работы: {GOLD}{COMMA} лет
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}МакÑ. надежноÑÑ‚ÑŒ: {GOLD}{COMMA}%
+STR_PURCHASE_INFO_COST :{BLACK}Цена: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}ВеÑ: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Цена: {GOLD}{CURRENCY}{BLACK} СкороÑÑ‚ÑŒ: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}ЕмкоÑÑ‚ÑŒ: {GOLD}{COMMA} паÑÑажиров, {COMMA} мешков почты
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Ведущие вагоны: {GOLD}+{POWER}{BLACK} ВеÑ: {GOLD}+{WEIGHT_S}
+STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Переоборуд. длÑ: {GOLD}
+STR_PURCHASE_INFO_ALL_TYPES :Ð’Ñех типов грузов
+STR_PURCHASE_INFO_ALL_BUT :Ð’Ñе, кроме {GOLD}
+STR_PURCHASE_INFO_MAX_TE :{BLACK}МакÑ. ТÑговое УÑилие: {GOLD}{FORCE}
+
+########### String for New Landscape Generator
+
+STR_GENERATE :{WHITE}Создать
+STR_RANDOM :{BLACK}Случайно
+STR_RANDOM_HELP :{BLACK}Изменить Ñлучайный номер, иÑпользуемый Генератором ландшафта.
+STR_WORLD_GENERATION_CAPTION :{WHITE}Создание мира
+STR_RANDOM_SEED :{BLACK}Случ. номер:
+STR_RANDOM_SEED_HELP :{BLACK}Ðажмите Ð´Ð»Ñ Ð²Ð²Ð¾Ð´Ð° Ñлучайного номера
+STR_LAND_GENERATOR :{BLACK}Генератор ландш.:
+STR_TREE_PLACER :{BLACK}Генератор леÑов:
+STR_HEIGHTMAP_ROTATION :{BLACK}Поворот РЕЛЬЕФÐ:
+STR_TERRAIN_TYPE :{BLACK}Тип ландшафта:
+STR_QUANTITY_OF_SEA_LAKES :{BLACK}Уровень морÑ:
+STR_SMOOTHNESS :{BLACK}ГладкоÑÑ‚ÑŒ:
+STR_SNOW_LINE_HEIGHT :{BLACK}"СнежнаÑ" линиÑ:
+STR_DATE :{BLACK}Дата:
+STR_NUMBER_OF_TOWNS :{BLACK}ЧиÑло городов:
+STR_NUMBER_OF_INDUSTRIES :{BLACK}ЧиÑло промышл.:
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_SNOW_LINE_UP :{BLACK}ПоднÑÑ‚ÑŒ "Ñнежную" линию на 1
+STR_SNOW_LINE_DOWN :{BLACK}ОпуÑтить "Ñнежную" линию на 1
+STR_SNOW_LINE_QUERY_CAPT :{WHITE}Изменить уровень "Ñнежной" линии
+STR_START_DATE_QUERY_CAPT :{WHITE}Изменить год начала игры
+STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Выход за пределы доÑтупных значений
+STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Увеличение карты до таких размеров не рекомендуетÑÑ. Продолжить?
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_HEIGHTMAP_NAME :{BLACK}Ð˜Ð¼Ñ Ð Ð•Ð›Ð¬Ð•Ð¤Ð:
+STR_HEIGHTMAP_SIZE :{BLACK}Размер: {ORANGE}{NUM} x {NUM}
+STR_GENERATION_WORLD :{WHITE}Создание мира...
+STR_GENERATION_ABORT :{BLACK}Отмена
+STR_GENERATION_ABORT_CAPTION :{WHITE}Прервать Ñоздание игрового мира
+STR_GENERATION_ABORT_MESSAGE :{YELLOW}Ð’Ñ‹ Ñерьезно хотите прервать Ñоздание мира?
+STR_PROGRESS :{WHITE}{NUM}% готово
+STR_GENERATION_PROGRESS :{BLACK}{NUM} / {NUM}
+STR_WORLD_GENERATION :{BLACK}Создание мира
+STR_TREE_GENERATION :{BLACK}Ð’Ñ‹Ñадка леÑов
+STR_UNMOVABLE_GENERATION :{BLACK}Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ Ð½ÐµÐ´Ð²Ð¸Ð¶Ð¸Ð¼Ð¾Ñти
+STR_CLEARING_TILES :{BLACK}Ð’Ñ€ÐµÐ¼Ñ Ñ€Ð°Ð·Ð±Ñ€Ð°Ñывать камни ...
+STR_SETTINGUP_GAME :{BLACK}ÐаÑтройка
+STR_PREPARING_TILELOOP :{BLACK}ВыполнÑем цикл
+STR_PREPARING_GAME :{BLACK}Подготовка игры
+STR_DIFFICULTY_TO_CUSTOM :{WHITE}ЗдеÑÑŒ можно изменить уровень ÑложноÑти
+STR_SE_FLAT_WORLD :{WHITE}Ð Ð¾Ð²Ð½Ð°Ñ Ð·ÐµÐ¼Ð»Ñ
+STR_SE_FLAT_WORLD_TIP :{BLACK}Создать ровную землю
+STR_SE_RANDOM_LAND :{WHITE}Ð¡Ð»ÑƒÑ‡Ð°Ð¹Ð½Ð°Ñ Ð·ÐµÐ¼Ð»Ñ
+STR_SE_NEW_WORLD :{BLACK}Создать новый Ñценарий
+STR_SE_CAPTION :{WHITE}Тип ÑценариÑ
+STR_FLAT_WORLD_HEIGHT_DOWN :{BLACK}ПоднÑÑ‚ÑŒ уровень ровной земли на 1
+STR_FLAT_WORLD_HEIGHT_UP :{BLACK}ОпуÑтить уровень ровной земли на 1
+STR_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Изменить выÑоту ровной земли
+STR_FLAT_WORLD_HEIGHT :{BLACK}Ð’Ñ‹Ñота над уровнем морÑ:
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+STR_SMALLMAP_CENTER :{BLACK}Центрировать миникарту по Ñтой позиции
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}Малый аÑропорт
+STR_CITY_AIRPORT :{BLACK}ГородÑкой аÑропорт
+STR_METRO_AIRPORT :{BLACK}Федеральный аÑропорт
+STR_INTERNATIONAL_AIRPORT :{BLACK}Международный аÑропорт
+STR_COMMUTER_AIRPORT :{BLACK}Пригородный аÑропорт
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Межконтинентальный аÑропорт
+STR_HELIPORT :{BLACK}Вертопорт
+STR_HELIDEPOT :{BLACK}ВертоДепо
+STR_HELISTATION :{BLACK}ВертоÑтанциÑ
+
+STR_SMALL_AIRPORTS :{BLACK}Малые аÑропорты
+STR_LARGE_AIRPORTS :{BLACK}Большие аÑропорты
+STR_HUB_AIRPORTS :{BLACK}Базовые аÑропорты
+STR_HELIPORTS :{BLACK}Вертопорты
+
+############ Tooltip measurment
+
+STR_MEASURE_LENGTH :{BLACK}Длина: {NUM}
+STR_MEASURE_AREA :{BLACK}Площадь: {NUM} x {NUM}
+STR_MEASURE_LENGTH_HEIGHTDIFF :{BLACK}Длина: {NUM}{}Разница выÑоты: {NUM} м
+STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}Площадь: {NUM} x {NUM}{}Разница выÑот: {NUM} м
+
+########
diff --git a/src/lang/slovak.txt b/src/lang/slovak.txt
new file mode 100644
index 000000000..d6c30cb2a
--- /dev/null
+++ b/src/lang/slovak.txt
@@ -0,0 +1,3180 @@
+##name Slovak
+##ownname Slovensky
+##isocode sk_SK.UTF-8
+##plural 6
+##case g
+##gender m z s
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Za okrajom mapy
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Prilis blizko okraja mapy
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Mala hotovost - potrebna {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Potrebny rovny teren
+STR_0008_WAITING :{BLACK}Caka: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (na ceste z
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Prijima: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Prijima: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :Cestujucich
+STR_000F_PASSENGERS.g :cestujucich
+STR_0010_COAL :Uhlie
+STR_0010_COAL.g :uhlia
+STR_0011_MAIL :Postu
+STR_0011_MAIL.g :posty
+STR_0012_OIL :Ropu
+STR_0012_OIL.g :ropy
+STR_0013_LIVESTOCK :Dobytok
+STR_0013_LIVESTOCK.g :dobytka
+STR_0014_GOODS :Tovar
+STR_0014_GOODS.g :tovaru
+STR_0015_GRAIN :Obilie
+STR_0015_GRAIN.g :obilia
+STR_0016_WOOD :Drevo
+STR_0016_WOOD.g :dreva
+STR_0017_IRON_ORE :Zeleznu rudu
+STR_0017_IRON_ORE.g :zeleznej rudy
+STR_0018_STEEL :Ocel
+STR_0018_STEEL.g :ocele
+STR_0019_VALUABLES :Cennosti
+STR_0019_VALUABLES.g :cennosti
+STR_001A_COPPER_ORE :Medenna ruda
+STR_001A_COPPER_ORE.g :medennej rudy
+STR_001B_MAIZE :Kukuricu
+STR_001B_MAIZE.g :kukurice
+STR_001C_FRUIT :Ovocie
+STR_001C_FRUIT.g :ovocia
+STR_001D_DIAMONDS :Diamanty
+STR_001D_DIAMONDS.g :diamantov
+STR_001E_FOOD :Jedlo
+STR_001E_FOOD.g :jedla
+STR_001F_PAPER :Papier
+STR_001F_PAPER.g :papiera
+STR_0020_GOLD :Zlato
+STR_0020_GOLD.g :zlata
+STR_0021_WATER :Vodu
+STR_0021_WATER.g :vody
+STR_0022_WHEAT :Psenicu
+STR_0022_WHEAT.g :psenice
+STR_0023_RUBBER :Kaucuk
+STR_0023_RUBBER.g :kaucuku
+STR_0024_SUGAR :Cukor
+STR_0024_SUGAR.g :cukru
+STR_0025_TOYS :Hracky
+STR_0025_TOYS.g :hraciek
+STR_0026_CANDY :Cukriky
+STR_0026_CANDY.g :cukrikov
+STR_0027_COLA :Kofolu
+STR_0027_COLA.g :kofoly
+STR_0028_COTTON_CANDY :Cukrovu vatu
+STR_0028_COTTON_CANDY.g :cukrovej vaty
+STR_0029_BUBBLES :Bublin
+STR_0029_BUBBLES.g :bublin
+STR_002A_TOFFEE :Karamelky
+STR_002A_TOFFEE.g :karameliek
+STR_002B_BATTERIES :Baterie
+STR_002B_BATTERIES.g :baterii
+STR_002C_PLASTIC :Zuvaciek
+STR_002C_PLASTIC.g :zuvaciek
+STR_002D_FIZZY_DRINKS :Sumienku
+STR_002D_FIZZY_DRINKS.g :sumienky
+STR_002E :
+STR_002F_PASSENGER :Cestujuci
+STR_002F_PASSENGER.g :cestujucich
+STR_0030_COAL :Uhlie
+STR_0030_COAL.g :uhlia
+STR_0031_MAIL :Posta
+STR_0031_MAIL.g :posty
+STR_0032_OIL :Ropa
+STR_0032_OIL.g :ropy
+STR_0033_LIVESTOCK :Dobytok
+STR_0033_LIVESTOCK.g :dobytka
+STR_0034_GOODS :Tovar
+STR_0034_GOODS.g :tovaru
+STR_0035_GRAIN :Obilie
+STR_0035_GRAIN.g :obilia
+STR_0036_WOOD :Drevo
+STR_0036_WOOD.g :dreva
+STR_0037_IRON_ORE :Zelezna ruda
+STR_0037_IRON_ORE.g :zeleznej rudy
+STR_0038_STEEL :Ocel
+STR_0038_STEEL.g :ocele
+STR_0039_VALUABLES :Cennosti
+STR_0039_VALUABLES.g :cennosti
+STR_003A_COPPER_ORE :Medenna ruda
+STR_003A_COPPER_ORE.g :medennej rudy
+STR_003B_MAIZE :Kukurica
+STR_003B_MAIZE.g :kukurice
+STR_003C_FRUIT :Ovocie
+STR_003C_FRUIT.g :ovocia
+STR_003D_DIAMOND :Diamant
+STR_003D_DIAMOND.g :diamantov
+STR_003E_FOOD :Jedlo
+STR_003E_FOOD.g :jedla
+STR_003F_PAPER :Papier
+STR_003F_PAPER.g :papiera
+STR_0040_GOLD :Zlato
+STR_0040_GOLD.g :zlata
+STR_0041_WATER :Voda
+STR_0041_WATER.g :vody
+STR_0042_WHEAT :Psenica
+STR_0042_WHEAT.g :psenice
+STR_0043_RUBBER :Kaucuk
+STR_0043_RUBBER.g :kaucuku
+STR_0044_SUGAR :Cukor
+STR_0044_SUGAR.g :cukru
+STR_0045_TOY :Hracky
+STR_0045_TOY.g :hraciek
+STR_0046_CANDY :Cukriky
+STR_0046_CANDY.g :cukrikov
+STR_0047_COLA :Kofola
+STR_0047_COLA.g :kofoly
+STR_0048_COTTON_CANDY :Cukrova vata
+STR_0048_COTTON_CANDY.g :cukrovej vaty
+STR_0049_BUBBLE :Bubliny
+STR_0049_BUBBLE.g :bublin
+STR_004A_TOFFEE :Karamel
+STR_004A_TOFFEE.g :karamelu
+STR_004B_BATTERY :Baterie
+STR_004B_BATTERY.g :baterii
+STR_004C_PLASTIC :Zuvacky
+STR_004C_PLASTIC.g :zuvaciek
+STR_004D_FIZZY_DRINK :Sumienka
+STR_004D_FIZZY_DRINK.g :sumienky
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} cestujuci{P "" "" ch}
+STR_QUANTITY_COAL :{WEIGHT} uhlia
+STR_QUANTITY_MAIL :{COMMA} balik{P "" y ov} posty
+STR_QUANTITY_OIL :{VOLUME} ropy
+STR_QUANTITY_LIVESTOCK :{COMMA} kus{P "" y ov} dobytka
+STR_QUANTITY_GOODS :{COMMA} deb{P na ny ien} tovaru
+STR_QUANTITY_GRAIN :{WEIGHT} obilia
+STR_QUANTITY_WOOD :{WEIGHT} dreva
+STR_QUANTITY_IRON_ORE :{WEIGHT} zeleznej rudy
+STR_QUANTITY_STEEL :{WEIGHT} ocele
+STR_QUANTITY_VALUABLES :{COMMA} vr{P ece ecia iec} cennosti
+STR_QUANTITY_COPPER_ORE :{WEIGHT} medennej rudy
+STR_QUANTITY_MAIZE :{WEIGHT} kukurice
+STR_QUANTITY_FRUIT :{WEIGHT} ovocia
+STR_QUANTITY_DIAMONDS :{COMMA} deb{P na ny ien} diamantov
+STR_QUANTITY_FOOD :{WEIGHT} jedla
+STR_QUANTITY_PAPER :{WEIGHT} papiera
+STR_QUANTITY_GOLD :{COMMA} deb{P na ny ien} zlata
+STR_QUANTITY_WATER :{VOLUME} voda
+STR_QUANTITY_WHEAT :{WEIGHT} psenice
+STR_QUANTITY_RUBBER :{VOLUME} kaucuk
+STR_QUANTITY_SUGAR :{WEIGHT} cukru
+STR_QUANTITY_TOYS :{COMMA} hrac{P ka ky iek}
+STR_QUANTITY_SWEETS :{COMMA} deb{P na ny ien} cukrikov
+STR_QUANTITY_COLA :{VOLUME} kofoly
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} cukrovej vaty
+STR_QUANTITY_BUBBLES :{COMMA} bublin{P a y ""}
+STR_QUANTITY_TOFFEE :{WEIGHT} karamelu
+STR_QUANTITY_BATTERIES :{COMMA} bateri{P a e i}
+STR_QUANTITY_PLASTIC :{VOLUME} zuvacka
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} sumien{P ka ky ok}
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}CE
+STR_ABBREV_COAL :{TINYFONT}UH
+STR_ABBREV_MAIL :{TINYFONT}PO
+STR_ABBREV_OIL :{TINYFONT}RO
+STR_ABBREV_LIVESTOCK :{TINYFONT}DO
+STR_ABBREV_GOODS :{TINYFONT}TO
+STR_ABBREV_GRAIN :{TINYFONT}OB
+STR_ABBREV_WOOD :{TINYFONT}DR
+STR_ABBREV_IRON_ORE :{TINYFONT}ZR
+STR_ABBREV_STEEL :{TINYFONT}OC
+STR_ABBREV_VALUABLES :{TINYFONT}CE
+STR_ABBREV_COPPER_ORE :{TINYFONT}MR
+STR_ABBREV_MAIZE :{TINYFONT}KU
+STR_ABBREV_FRUIT :{TINYFONT}OV
+STR_ABBREV_DIAMONDS :{TINYFONT}DI
+STR_ABBREV_FOOD :{TINYFONT}JE
+STR_ABBREV_PAPER :{TINYFONT}PA
+STR_ABBREV_GOLD :{TINYFONT}ZL
+STR_ABBREV_WATER :{TINYFONT}VO
+STR_ABBREV_WHEAT :{TINYFONT}PS
+STR_ABBREV_RUBBER :{TINYFONT}KA
+STR_ABBREV_SUGAR :{TINYFONT}CU
+STR_ABBREV_TOYS :{TINYFONT}HR
+STR_ABBREV_SWEETS :{TINYFONT}CK
+STR_ABBREV_COLA :{TINYFONT}KO
+STR_ABBREV_CANDYFLOSS :{TINYFONT}CV
+STR_ABBREV_BUBBLES :{TINYFONT}BU
+STR_ABBREV_TOFFEE :{TINYFONT}KR
+STR_ABBREV_BATTERIES :{TINYFONT}BT
+STR_ABBREV_PLASTIC :{TINYFONT}ZU
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}SU
+STR_ABBREV_NONE :{TINYFONT}NIC
+STR_ABBREV_ALL :{TINYFONT}VS.
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Mapa - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Nastavenia hry
+STR_00B2_MESSAGE :{YELLOW}Sprava
+STR_00B3_MESSAGE_FROM :{YELLOW}Sprava od {STRING}
+STR_POPUP_CAUTION_CAPTION :{WHITE}Upozornenie!
+STR_00B4_CAN_T_DO_THIS :{WHITE}Nie je mozne vykonat ...
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Oblast nie je mozne vycistit ...
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Povodny copyright: {COPYRIGHT} 1995 Chris Sawyer, vsetky prava vyhradene
+STR_00B7_VERSION :{BLACK}OpenTTD verzia {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 team OpenTTD
+STR_TRANSLATED_BY :{BLACK} Preklad - Lukas Lengyel & gpsoft
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Koniec
+STR_00C8_YES :{BLACK}Ano
+STR_00C9_NO :{BLACK}Nie
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Si si isty ze chces ukoncit hru a vratit sa do {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Nic
+STR_00D1_DARK_BLUE :Tmavomodra
+STR_00D2_PALE_GREEN :Svetlozelena
+STR_00D3_PINK :Ruzova
+STR_00D4_YELLOW :Zlta
+STR_00D5_RED :Cervena
+STR_00D6_LIGHT_BLUE :Svetlomodra
+STR_00D7_GREEN :Zelena
+STR_00D8_DARK_GREEN :Tmavozelena
+STR_00D9_BLUE :Modra
+STR_00DA_CREAM :Kremova
+STR_00DB_MAUVE :Ruzova
+STR_00DC_PURPLE :Fialova
+STR_00DD_ORANGE :Oranzova
+STR_00DE_BROWN :Hneda
+STR_00DF_GREY :Seda
+STR_00E0_WHITE :Biela
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}V hre je prilis vela dopravnych prostriedkov
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Pozicia
+STR_00E5_CONTOURS :Vrstevnice
+STR_00E6_VEHICLES :Dopravne Prostriedky
+STR_00E7_INDUSTRIES :Priemysel
+STR_00E8_ROUTES :Trasy
+STR_00E9_VEGETATION :Vegetacia
+STR_00EA_OWNERS :Vlastnici
+STR_00EB_ROADS :{BLACK}{TINYFONT}Cesty
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Zeleznicne drahy
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Stanice/Letiska/Pristavy
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Budovy/Tovarne
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Dopravne Prostriedky
+STR_00F0_100M :{BLACK}{TINYFONT}100m
+STR_00F1_200M :{BLACK}{TINYFONT}200m
+STR_00F2_300M :{BLACK}{TINYFONT}300m
+STR_00F3_400M :{BLACK}{TINYFONT}400m
+STR_00F4_500M :{BLACK}{TINYFONT}500m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Vlaky
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Auta
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Lode
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Lietadla
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Dopravne Trasy
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Uholna bana
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Elektraren
+STR_00FC_FOREST :{BLACK}{TINYFONT}Les
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}Pila
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Ropna rafineria
+STR_00FF_FARM :{BLACK}{TINYFONT}Farma
+STR_0100_FACTORY :{BLACK}{TINYFONT}Tovaren
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Tlaciaren
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Ropny vrt
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Zelezorudna bana
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Oceliaren
+STR_0105_BANK :{BLACK}{TINYFONT}Banka
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Vyroba papiera
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Zlata bana
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Vyroba potravin
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Diamantova bana
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Medenna bana
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Ovocny sad
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Kaucukova plantaz
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Vodny zdroj
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Vodojem
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}Pila
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Les cukrovej vaty
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Cukrovar
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Vyroba baterii
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Vyroba kofoly
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Hrackarstvo
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Vyroba hraciek
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Zuvackova fontana
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Vyroba sumienky
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Bublifuk
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Karamelovy lom
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Cukrova bana
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Zeleznicna stanica
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Nakladacia rampa
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Autobusova zastavka
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Letisko
+STR_011F_DOCK :{BLACK}{TINYFONT}Pristav
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Hruby teren
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Travnaty teren
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Holy teren
+STR_0123_FIELDS :{BLACK}{TINYFONT}Polia
+STR_0124_TREES :{BLACK}{TINYFONT}Lesy
+STR_0125_ROCKS :{BLACK}{TINYFONT}Skaly
+STR_0126_WATER :{BLACK}{TINYFONT}Voda
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Bez vlastnika
+STR_0128_TOWNS :{BLACK}{TINYFONT}Mesta
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Priemysel
+STR_012A_DESERT :{BLACK}{TINYFONT}Pust
+STR_012B_SNOW :{BLACK}{TINYFONT}Sneh
+STR_012C_MESSAGE :{WHITE}Sprava
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Zrusit
+STR_012F_OK :{BLACK}OK
+STR_0130_RENAME :{BLACK}Premenovat
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Pouzitych prilis vela mien
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Vybrane meno je uz pouzite
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...vlastnik {STRING}
+STR_013C_CARGO :{BLACK}Naklad
+STR_013D_INFORMATION :{BLACK}Informacie
+STR_013E_CAPACITIES :{BLACK}Kapacita
+STR_013E_TOTAL_CARGO :{BLACK}Celkovy naklad
+STR_013F_CAPACITY :{BLACK}Kapacita: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}Kapacita: {LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Celkovy naklad (kapacita) tohoto vlaku:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}Nová hra
+STR_0141_LOAD_GAME :{BLACK}Nahrat hru
+STR_SINGLE_PLAYER :{BLACK}Jeden hrac
+STR_MULTIPLAYER :{BLACK}Viacero hrácov
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Velkost mapy:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Nastavenia hry
+
+STR_0150_SOMEONE :niekto{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Mapa sveta
+STR_0152_TOWN_DIRECTORY :Zoznam miest
+STR_0153_SUBSIDIES :Dotacie
+
+STR_UNITS_IMPERIAL :Imperialne
+STR_UNITS_METRIC :Metricke
+STR_UNITS_SI :SI
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} mph
+STR_UNITS_VELOCITY_METRIC :{COMMA} km/h
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}hp
+STR_UNITS_POWER_METRIC :{COMMA}hp
+STR_UNITS_POWER_SI :{COMMA}kW
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} ton
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} ton
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} kg
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}gal
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}l
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}m³
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} galon{P "" y ov}
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} lit{P er re rov}
+STR_UNITS_VOLUME_LONG_SI :{COMMA} m³
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10³ lbf
+STR_UNITS_FORCE_METRIC :{COMMA} megapond{P "" y ov}
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Graf prevadzkoveho zisku
+STR_0155_INCOME_GRAPH :Graf trzieb
+STR_0156_DELIVERED_CARGO_GRAPH :Graf prepraveneho nakladu
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Graf hodnotenia vykonu
+STR_0158_COMPANY_VALUE_GRAPH :Graf hodnoty spolocnosti
+STR_0159_CARGO_PAYMENT_RATES :Ceny prepravy
+STR_015A_COMPANY_LEAGUE_TABLE :Hodnotenie spolocnosti
+STR_PERFORMANCE_DETAIL_MENU :Detailny rating vykonu
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}OpenTTD
+STR_015C_SAVE_GAME :Ulozit hru
+STR_015D_LOAD_GAME :Nahrat hru
+STR_015E_QUIT_GAME :Ukoncit hru
+STR_015F_QUIT :Ukoncit OpenTTD
+STR_ABANDON_GAME_QUERY :{YELLOW}Si si isty ze chces ukoncit tuto hru ?
+STR_0161_QUIT_GAME :{WHITE}Ukoncit hru
+STR_SORT_ORDER_TIP :{BLACK}Vyber sposob triedenia (zostupny/vzostupny)
+STR_SORT_CRITERIA_TIP :{BLACK}Vyber kriterium triedenia
+STR_SORT_BY :{BLACK}Usporiadat
+
+STR_SORT_BY_POPULATION :{BLACK}Populacia
+STR_SORT_BY_PRODUCTION :{BLACK}Produkcia
+STR_SORT_BY_TYPE :{BLACK}Typ
+STR_SORT_BY_TRANSPORTED :{BLACK}Prepravene
+STR_SORT_BY_NAME :{BLACK}Nazov
+STR_SORT_BY_DROPDOWN_NAME :Nazov
+STR_SORT_BY_DATE :{BLACK}Datum
+STR_SORT_BY_NUMBER :Cislo
+STR_SORT_BY_PROFIT_LAST_YEAR :Zisk v poslednom roku
+STR_SORT_BY_PROFIT_THIS_YEAR :Zisk v tomto roku
+STR_SORT_BY_AGE :Vek
+STR_SORT_BY_RELIABILITY :Spolahlivost
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Uplna kapacita podla typu nakladu
+STR_SORT_BY_MAX_SPEED :Maximalna rychlost
+STR_SORT_BY_MODEL :Model
+STR_SORT_BY_VALUE :Hodnota
+STR_SORT_BY_FACILITY :Typ stanice
+STR_SORT_BY_WAITING :Mnozstvo cakajuceho nakladu
+STR_SORT_BY_RATING_MAX :Hodnotenie prepravy
+STR_ENGINE_SORT_ENGINE_ID :EngineID (netriedené)
+STR_ENGINE_SORT_COST :Cena
+STR_ENGINE_SORT_POWER :Výkon
+STR_ENGINE_SORT_INTRO_DATE :Uvedenie na trh
+STR_ENGINE_SORT_RUNNING_COST :Náklady na prevádzku
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Výkon/Náklady na prevádzku
+STR_ENGINE_SORT_CARGO_CAPACITY :Kapacita nákladu
+STR_NO_WAITING_CARGO :{BLACK}Necaka ziadny typ nakladu
+STR_SELECT_ALL_FACILITIES :{BLACK}Oznacit vsetky moznosti
+STR_SELECT_ALL_TYPES :{BLACK}Oznacit vsetky druhy nakladu (vratane druhu, kt. necaka na prepravu)
+STR_AVAILABLE_ENGINES_TIP :{BLACK}Zobrazit zoznam dostupných dizajnov rušňov pre tento typ.
+STR_MANAGE_LIST :{BLACK}Možnosti
+STR_MANAGE_LIST_TIP :{BLACK}Zadat príkazy všetkým vozidlám v zozname
+STR_REPLACE_VEHICLES :Vymena vozidiel
+STR_SEND_TRAIN_TO_DEPOT :Poslat do depa
+STR_SEND_ROAD_VEHICLE_TO_DEPOT :Poslat do garáže
+STR_SEND_SHIP_TO_DEPOT :Poslat do lodenice
+STR_SEND_AIRCRAFT_TO_HANGAR :Poslat do hangáru
+STR_SEND_FOR_SERVICING :Vykonat servis
+
+############ range for months starts
+STR_0162_JAN :Jan
+STR_0163_FEB :Feb
+STR_0164_MAR :Mar
+STR_0165_APR :Apr
+STR_0166_MAY :Maj
+STR_0167_JUN :Jun
+STR_0168_JUL :Jul
+STR_0169_AUG :Aug
+STR_016A_SEP :Sep
+STR_016B_OCT :Okt
+STR_016C_NOV :Nov
+STR_016D_DEC :Dec
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Pauza
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Ulozit hru, opustit hru, ukoncit program
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Zoznam stanic spolocnosti
+STR_0174_DISPLAY_MAP :{BLACK}Zobrazit mapu
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Zobrazit mapu, zoznam miest
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Zobrazit zoznam miest
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Financne informacie o spolocnosti
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Informacie o spolocnosti
+STR_0179_DISPLAY_GRAPHS :{BLACK}Grafy
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Hodnotenie spolocnosti
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Zoznam vlakov
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Zoznam automobilov
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Zoznam lodi
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Zoznam lietadiel
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Priblizit
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Oddialit
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Vystavba zeleznice
+STR_0182_BUILD_ROADS :{BLACK}Vystavba ciest
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Vystavba pristavov
+STR_0184_BUILD_AIRPORTS :{BLACK}Vystavba letisk
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Vysadba stromov, rezervacia pozemku
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Informacie o pozemku
+STR_0187_OPTIONS :{BLACK}Nastavenia
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Nieje mozne zmenit servisny interval...
+STR_018B_CLOSE_WINDOW :{BLACK}Zavriet okno
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Nadpis okna - potiahni pre posun okna
+STR_STICKY_BUTTON :{BLACK}Oznacit toto okno, aby sa nedalo zatvorit klavesou 'Zavri vsetky okna'
+STR_RESIZE_BUTTON :{BLACK}Uchop a tahaj pre zmenu velkosti okna
+STR_SAVELOAD_HOME_BUTTON :{BLACK}Kliknutim sem sa presuniete do sucasneho vychodzieho adresara pre ukladanie
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Zburanie budov, cistenie terenu
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Znizit roh terenu
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Zvysit roh terenu
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Navigacna lista
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Navigacna lista - posuva vypis dolava/doprava
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Zobrazit vrstevnice na mape
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Zobrazit dopravne prostriedky na mape
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Zobrazit priemysel na mape
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Zobrazit dopravne trasy na mape
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Zobrazit vegetaciu na mape
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Zobrazit vlastnikov pozemkov na mape
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Zapnut / Vypnut nazvy miest na mape
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Zisk tento rok: {CURRENCY} (posledny rok: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} rok{P "" y ov} ({COMMA})
+STR_AGE_RED :{RED}{COMMA} rok{P "" y ov} ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :{G=m}Automobil
+STR_019D_AIRCRAFT :{G=s}Lietadlo
+STR_019E_SHIP :{G=z}Lod
+STR_019F_TRAIN :{G=m}Vlak
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} je star{G y a e}
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} je velmi star{G y a e}
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} je velmi star{G y a e} a potrebuje vymenit
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Informacie o pozemku
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Naklady na odstranenie: {LTBLUE}N/A
+STR_01A5_COST_TO_CLEAR :{BLACK}Naklady na odstranenie: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :Nezname
+STR_01A7_OWNER :{BLACK}Vlastnik: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Miestna sprava: {LTBLUE}{STRING}
+STR_01A9_NONE :Nezname
+STR_01AA_NAME :{BLACK}Meno
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1
+STR_01AD_2ND :2
+STR_01AE_3RD :3
+STR_01AF_4TH :4
+STR_01B0_5TH :5
+STR_01B1_6TH :6
+STR_01B2_7TH :7
+STR_01B3_8TH :8
+STR_01B4_9TH :9
+STR_01B5_10TH :10
+STR_01B6_11TH :11
+STR_01B7_12TH :12
+STR_01B8_13TH :13
+STR_01B9_14TH :14
+STR_01BA_15TH :15
+STR_01BB_16TH :16
+STR_01BC_17TH :17
+STR_01BD_18TH :18
+STR_01BE_19TH :19
+STR_01BF_20TH :20
+STR_01C0_21ST :21
+STR_01C1_22ND :22
+STR_01C2_23RD :23
+STR_01C3_24TH :24
+STR_01C4_25TH :25
+STR_01C5_26TH :26
+STR_01C6_27TH :27
+STR_01C7_28TH :28
+STR_01C8_29TH :29
+STR_01C9_30TH :30
+STR_01CA_31ST :31
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Prijma naklad: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Jukebox
+STR_01D3_SOUND_MUSIC :Zvuk/Hudba
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Zobraz okno zvuku a hudby
+STR_01D5_ALL :{TINYFONT}Vsetko
+STR_01D6_OLD_STYLE :{TINYFONT}Stary styl
+STR_01D7_NEW_STYLE :{TINYFONT}Novy styl
+STR_01D8_EZY_STREET :{TINYFONT}Ezy Street
+STR_01D9_CUSTOM_1 :{TINYFONT}Vlastne 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Vlastne 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Hlasitost hudby
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Hlasitost zvuk. efektov
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MIN ' ' ' ' ' ' MAX
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Predchadzajuca stopa
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Nasledujuca stopa
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Zastavit prehravanie hudby
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Spustit prehravanie hudby
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Tahat posuvace pre zmenu hlasitosti
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Stopa{SETX 88}Title
+STR_01E9_SHUFFLE :{TINYFONT}Nahodne
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Program
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Vyber hudobneho programu
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Cislo stopy
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Program - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}Zmazat
+STR_01F1_SAVE :{TINYFONT}{BLACK}Ulozit
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Aktualny program
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Vybrat 'Vsetko'
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Vybrat 'Stary styl'
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Vybrat 'Novy styl'
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Vybrat 'Vlastny 1' (uzivatelom definovany) program
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Vybrat 'Vlastny 2' (uzivatelom definovany) program
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Vymazat aktualny program (len Vlastny 1 a Vlastny 2 program)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Ulozit nastavenie hudby
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Kliknut na stopu pre ulozenie (len Vlastny 1 a Vlastny 2 program)
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Kliknite na hudobnu stopu pre jej odstranenie z programu (len Vlastny1 alebo Vlastny2)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Zapnut / Vypnut nahodny vyber
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Zobrazit okno pre vyber hudobnych stop
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Kliknut na trasu pre centrovanie pohladu na tovaren/mesto
+STR_01FE_DIFFICULTY :{BLACK}Obtiažnost ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Zobrazit poslednu spravu
+STR_0201_MESSAGE_SETTINGS :Nastavenia sprav
+STR_MESSAGE_HISTORY_MENU :Archiv sprav
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Zobrazit poslednu spravu/novinku, nastavenia sprav
+STR_0204_MESSAGE_OPTIONS :{WHITE}Nastavenia sprav
+STR_0205_MESSAGE_TYPES :{BLACK}Typ sprav:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Prijazd prveho vozidla do stanice hraca
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Prijazd prveho vozidla do stanice konkurencie
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Havarie / Katastrofy
+STR_0209_COMPANY_INFORMATION :{YELLOW}Informacie o spolocnosti
+STR_020A_ECONOMY_CHANGES :{YELLOW}Zmeny v ekonomike
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Oznamenia / Informacie o vozidlach hraca
+STR_020C_NEW_VEHICLES :{YELLOW}Nove vozidla
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Zmeny prijmu nakladu
+STR_020E_SUBSIDIES :{YELLOW}Dotacie
+STR_020F_GENERAL_INFORMATION :{YELLOW}Hlavne informacie
+STR_MESSAGES_ALL :{YELLOW}Nastavenie vs. typov sprav (vypnute/strucne/zapnute)
+STR_MESSAGE_SOUND :{YELLOW}Prehrat zvuk pre strucne novinove spravy
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...prilis daleko z predchadzajuceho ciela
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Najlepsie spolocnosti, ktore dosiahli {NUM}{}({STRING} uroven)
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Tabulka spolocnosti v roku {NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Obchodnik
+STR_0214_ENTREPRENEUR :Podnikatel
+STR_0215_INDUSTRIALIST :Priemyselnik
+STR_0216_CAPITALIST :Kapitalista
+STR_0217_MAGNATE :Magnat
+STR_0218_MOGUL :Mogul
+STR_0219_TYCOON_OF_THE_CENTURY :Tycoon
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} ziskal oznacenie '{STRING}' !
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} z {COMPANY} ziskal oznacenie '{STRING}' !
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Vytvorit scenar
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Editor scenarov
+STR_0223_LAND_GENERATION :{WHITE}Generovanie uzemia
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Nahodne uzemie
+STR_0227_RESET_LAND :{BLACK}Zresetovat uzemie
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Pre zvysenie/znizenie oblasti je potrebne zvacsit uzemie
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Pre zvysenie/znizenie oblasti je potrebne zmensit uzemie
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Vygenerovat nahodne uzemie
+STR_022B_RESET_LANDSCAPE :{BLACK}Zresetovat uzemie
+STR_022C_RESET_LANDSCAPE :{WHITE}Zresetovat Uzemie
+STR_LOAD_GAME_HEIGHTMAP :{WHITE}Pouzit vyskovu mapu
+STR_LOAD_SCEN_HEIGHTMAP :{BLACK}Pouzit vyskovu mapu
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Si si isty ze chces zresetovat uzemie ?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Vytvorenie uzemia
+STR_022F_TOWN_GENERATION :{BLACK}Vytvorenie mesta
+STR_0230_INDUSTRY_GENERATION :{BLACK}Vytvorenie priemyslu
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Stavba cesty
+STR_0233_TOWN_GENERATION :{WHITE}Vytvorenie mesta
+STR_0234_NEW_TOWN :{BLACK}Nove mesto
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Stavat nove mesto
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Tu sa mesto neda postavit...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...prilis blizko okraja mapy
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...prilis blizko ineho mesta
+STR_0239_SITE_UNSUITABLE :{WHITE}...miesto je nepouzitelne
+STR_023A_TOO_MANY_TOWNS :{WHITE}...prilis vela miest
+STR_CANNOT_GENERATE_TOWN :{WHITE}Nie je mozne postavit viac miest
+STR_NO_SPACE_FOR_TOWN :{WHITE}... nie je dalsie miesto na mape
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Zvacsit velkost mesta
+STR_023C_EXPAND :{BLACK}Rozsirit
+STR_023D_RANDOM_TOWN :{BLACK}Nahodne mesto
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Postavit mesto na nahodnej pozicii
+STR_023F_INDUSTRY_GENERATION :{WHITE}Vytvorenie priemyslu
+STR_0240_COAL_MINE :{BLACK}Uholna bana
+STR_0241_POWER_STATION :{BLACK}Elektraren
+STR_0242_SAWMILL :{BLACK}Pila
+STR_0243_FOREST :{BLACK}Les
+STR_0244_OIL_REFINERY :{BLACK}Ropna rafineria
+STR_0245_OIL_RIG :{BLACK}Vrtna plosina
+STR_0246_FACTORY :{BLACK}Tovaren
+STR_0247_STEEL_MILL :{BLACK}Oceliaren
+STR_0248_FARM :{BLACK}Farma
+STR_0249_IRON_ORE_MINE :{BLACK}Zelezorudna bana
+STR_024A_OIL_WELLS :{BLACK}Vrtna veza
+STR_024B_BANK :{BLACK}Banka
+STR_024C_PAPER_MILL :{BLACK}Vyroba papiera
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Vyroba jedla
+STR_024E_PRINTING_WORKS :{BLACK}Tlaciaren
+STR_024F_GOLD_MINE :{BLACK}Zlata bana
+STR_0250_LUMBER_MILL :{BLACK}Pila
+STR_0251_FRUIT_PLANTATION :{BLACK}Ovocny sad
+STR_0252_RUBBER_PLANTATION :{BLACK}Kaucukova plantaz
+STR_0253_WATER_SUPPLY :{BLACK}Vodny zdroj
+STR_0254_WATER_TOWER :{BLACK}Vodojem
+STR_0255_DIAMOND_MINE :{BLACK}Diamantova bana
+STR_0256_COPPER_ORE_MINE :{BLACK}Medenna bana
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Les cukrovej vaty
+STR_0258_CANDY_FACTORY :{BLACK}Cukrovar
+STR_0259_BATTERY_FARM :{BLACK}Vyroba baterii
+STR_025A_COLA_WELLS :{BLACK}Vyroba kofoly
+STR_025B_TOY_SHOP :{BLACK}Hrackarstvo
+STR_025C_TOY_FACTORY :{BLACK}Vyroba hraciek
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Zuvackova fontana
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Vyroba sumienky
+STR_025F_BUBBLE_GENERATOR :{BLACK}Bublifuk
+STR_0260_TOFFEE_QUARRY :{BLACK}Karamelovy lom
+STR_0261_SUGAR_MINE :{BLACK}Cukrova bana
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Postavit uholnu banu
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Postavit elektraren
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Postavit pilu
+STR_0265_PLANT_FOREST :{BLACK}Vysadit les
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Postavit ropnu rafineriu
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Postavit vrtnu plosinu (da sa postavit len blizko kraja mapy)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Postavit tovaren
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Postavit oceliaren
+STR_026A_CONSTRUCT_FARM :{BLACK}Postavit farmu
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Postavit zelezorudnu banu
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Postavit ropny vrt
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Postavit banku (len v mestach kde je populacia vacsia ako 1200)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Postavit vyrobu papiera
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Postavit vyrobu jedla
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Postavit tlaciaren
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Postavit zlatu banu
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Postavit banku (len v mestach)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Postavit pilu (na cistenie dazdoveho pralesa a produkciu dreva)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Postavit ovocny sad
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Postavit kaucukovu plantaz
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Postavit vodny zdroj
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Postavit vodojem (len v mestach)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Postavit diamantovu banu
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Postavit medennu banu
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Vysadit les cukrovej vaty
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Postavit cukrovar
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Postavit vyrobu baterii
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Postavit vyrobu kofoly
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Postavit hrackarstvo
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Postavit vyrobu hraciek
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Postavit zuvackovu fontanu
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Postavit vyrobu sumienky
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Postavit bublifuk
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Postavit karamelovy lom
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Postavit cukrovu banu
+STR_0285_CAN_T_BUILD_HERE :{WHITE}{STRING} sa tu neda postavit...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...najskor treba postavit mesto...
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...povolene len jedno pre mesto...
+STR_0288_PLANT_TREES :{BLACK}Zasadit stromy
+STR_0289_PLACE_SIGN :{BLACK}Umiestnit popis
+STR_028A_RANDOM_TREES :{BLACK}Nahodne stromy
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Zasadit nahodne stromy
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Umiestnit nahodne skaly
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Umiestnit majak
+STR_028E_PLACE_TRANSMITTER :{BLACK}Umiestnit vysielac
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Vytvorit oblast puste.{}Drzanim CTRL ju odstranite
+STR_CREATE_LAKE :{BLACK}Vytvorit oblast vody.{}Okolie bude tiez zaplavene, ak je na urovni mora
+STR_0290_DELETE :{BLACK}Vymazat
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Kompletne vymazat toto mesto
+STR_0292_SAVE_SCENARIO :Ulozit scenar
+STR_0293_LOAD_SCENARIO :Nahrat scenár
+STR_0294_QUIT_EDITOR :Ukoncit editor
+STR_0295 :
+STR_0296_QUIT :Ukoncit program
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Ulozit scenar, nahrat scenar, ukoncit editor scenara, ukoncit program
+STR_0298_LOAD_SCENARIO :{WHITE}Nahrat scenár
+STR_0299_SAVE_SCENARIO :{WHITE}Ulozit scenar
+STR_029A_PLAY_SCENARIO :{BLACK}Hrat scenar
+STR_PLAY_HEIGHTMAP :{BLACK}Hrat vyskovu mapu
+STR_PLAY_HEIGHTMAP_HINT :{BLACK}Zacat novu hru s pouzitim vyskovej mapy ako krajiny
+STR_QUIT_SCENARIO_QUERY :{YELLOW}Si si isty ze chces ukoncit tento scenar ?
+STR_029C_QUIT_EDITOR :{WHITE}Ukoncit Editor
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...moze byt postavene v mestach z populaciou vacsou ako 1200
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Posunut zaciatok o rok dozadu
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Posunut zaciatok o rok dopredu
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...konce mostu musia byt na pevnine
+STR_02A1_SMALL :{BLACK}Male
+STR_02A2_MEDIUM :{BLACK}Stredne
+STR_02A3_LARGE :{BLACK}Velke
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Vyber velkost mesta
+STR_02A5_TOWN_SIZE :{YELLOW}Velkost mesta:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Zobrazit poslednu spravu alebo novinku
+STR_OFF :Vypnute
+STR_SUMMARY :Obsah
+STR_FULL :Plne
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Zoznam miest
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Nazvy vozidiel
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Vychodzie
+STR_02BF_CUSTOM :Vlastne
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Ulozit vlastne nazvy
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Vyber nazvu vozidiel
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Ulozit vlastne nazvy vozidiel na disk
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Nastavenia hry
+STR_02C5_DIFFICULTY_SETTINGS :Nastavenia obtiaznosti
+STR_02C7_CONFIG_PATCHES :Nastavenia patchov
+STR_NEWGRF_SETTINGS :Nastavenie newgrf
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Zobrazit nazvy miest
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Zobrazit nazvy stanic
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Zobrazit popisy
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Zobrazit navigacne body
+STR_02D0_FULL_ANIMATION :{SETX 12}Plna animacia
+STR_02D2_FULL_DETAIL :{SETX 12}Plne detaily
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Priesvitne budovy
+STR_TRANSPARENT_SIGNS :{SETX 12}Transparentne nazvy stanic
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Informacie o pozemku
+STR_02D6 :
+STR_CONSOLE_SETTING :Zobrazit / skryt konzolu
+STR_02D7_SCREENSHOT_CTRL_S :ScreenShot (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Velky ScreenShot (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :O hre 'OpenTTD'
+############ range ends here
+
+STR_02DB_OFF :{BLACK}Vyp.
+STR_02DA_ON :{BLACK}Zap.
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Zobrazit dotacie
+STR_02DD_SUBSIDIES :Dotacie
+STR_02DE_MAP_OF_WORLD :Mapa sveta
+STR_EXTRA_VIEW_PORT :Dalsi pohlad
+STR_SIGN_LIST :Zoznam popisov
+STR_02DF_TOWN_DIRECTORY :Zoznam miest
+STR_TOWN_POPULATION :{BLACK}Svetova populacia: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Pohlad {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Pohlad podla mapy
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Nastavit pohlad podla hlavneho pohladu
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Mapa podla pohladu
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Nastavit hlavny pohlad na mapu podla tohto pohladu
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Mena
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Vyber meny
+STR_MEASURING_UNITS :{BLACK}Jednotky vzdialenosti
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Výber jednotiek vzdialenosti
+STR_02E6_ROAD_VEHICLES :{BLACK}Cestne vozidla
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Strana po ktorej jazdia cestne vozidla
+STR_02E9_DRIVE_ON_LEFT :Jazdia nalavo
+STR_02EA_DRIVE_ON_RIGHT :Jazdia napravo
+STR_02EB_TOWN_NAMES :{BLACK}Nazvy miest
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Vyber styl nazvov miest
+
+STR_02F4_AUTOSAVE :{BLACK}Automaticke ukladanie
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Vyber interval automatickeho ukladania
+STR_02F7_OFF :Vypnute
+STR_02F8_EVERY_3_MONTHS :Kazde 3 mesiace
+STR_02F9_EVERY_6_MONTHS :Kazdych 6 mesiacov
+STR_02FA_EVERY_12_MONTHS :Kazdych 12 mesiacov
+STR_02FB_START_A_NEW_GAME :{BLACK}Spustit novu hru
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Nahrat ulozenú hru
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Vytvorit vlastny svet / scenar
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Vyberte hru pre 1 hraca
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Vyberte hru pre 2-8 hracov
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Zobraz nastavenia hry
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Zobraz nastavenia obtiaznosti
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Spustit novu hru s pouzitim vlastneho scenara
+STR_0304_QUIT :{BLACK}Ukoncit program
+STR_0305_QUIT_OPENTTD :{BLACK}Ukoncit 'OpenTTD'
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}... moze byt postavene len v meste
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Krajina mierneho pasma
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Subarkticka krajina
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Subtropicka krajina
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Detska krajina
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Financovat vystavbu noveho priemyslu
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Zoznam priemyslu
+STR_0313_FUND_NEW_INDUSTRY :Financovat novy priemysel
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Financovat novy priemysel
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}... moze byt postavene len v meste
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}... moze byt postavene len v dazdovom pralese
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}... moze byt postavene len v pusti
+STR_0319_PAUSED :{YELLOW}* * ZASTAVENE * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Screenshot bol ulozeny na disk ako '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}Ulozenie screeshotu zlyhalo!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Zakupit pozemok pre buduce pouzitie
+STR_032F_AUTOSAVE :{RED}AUTOULOZENIE
+STR_SAVING_GAME :{RED}* * HRA SA UKLADA * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}Ukladanie hry este bezi,{}pockajte prosim na dokoncenie!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Vyber 'Ezy Street style music' program
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :Anglicke
+STR_TOWNNAME_FRENCH :Francuzke
+STR_TOWNNAME_GERMAN :Nemecke
+STR_TOWNNAME_ADDITIONAL_ENGLISH :Anglicke (Dalsie)
+STR_TOWNNAME_LATIN_AMERICAN :Latinsko-Americke
+STR_TOWNNAME_SILLY :Hlupe (anglicky)
+STR_TOWNNAME_SWEDISH :Svedske
+STR_TOWNNAME_DUTCH :Holandske
+STR_TOWNNAME_FINNISH :Finske
+STR_TOWNNAME_POLISH :Polske
+STR_TOWNNAME_SLOVAKISH :Slovenske
+STR_TOWNNAME_NORWEGIAN :Norske
+STR_TOWNNAME_HUNGARIAN :Madarske
+STR_TOWNNAME_AUSTRIAN :Rakuske
+STR_TOWNNAME_ROMANIAN :Rumunske
+STR_TOWNNAME_CZECH :Ceske
+STR_TOWNNAME_SWISS :Svajciarske
+STR_TOWNNAME_DANISH :Danske
+STR_TOWNNAME_TURKISH :Turecké
+STR_TOWNNAME_ITALIAN :Talianske
+STR_TOWNNAME_CATALAN :Katalanske
+############ end of townname region
+
+STR_CURR_GBP :Libry (£)
+STR_CURR_USD :Dolare ($)
+STR_CURR_EUR :Euro (€)
+STR_CURR_YEN :Jeny (Â¥)
+STR_CURR_ATS :Rakuske Silingy (ATS)
+STR_CURR_BEF :Belgicke Franky (BEF)
+STR_CURR_CHF :Svajciarske Franky (CHF)
+STR_CURR_CZK :Ceske Koruny (CZK)
+STR_CURR_DEM :Nemecke marky(DEM)
+STR_CURR_DKK :Danske Koruny (DKK)
+STR_CURR_ESP :Pesety (ESP)
+STR_CURR_FIM :Finske Marky (FIM)
+STR_CURR_FRF :Franky (FRF)
+STR_CURR_GRD :Grecke Drachny (GRD)
+STR_CURR_HUF :Madarske Forinty (HUF)
+STR_CURR_ISK :Islandske Koruny (ISK)
+STR_CURR_ITL :Talianske Liry (ITL)
+STR_CURR_NLG :Danske Guldeny (NLG)
+STR_CURR_NOK :Norske Koruny (NOK)
+STR_CURR_PLN :Polske Zloty (PLN)
+STR_CURR_ROL :Rumunske Lei (ROL)
+STR_CURR_RUR :Ruske Ruble (RUR)
+STR_CURR_SIT :Slovinske Toliare (SIT)
+STR_CURR_SEK :Svedske Koruny (SEK)
+STR_CURR_YTL :Turecke Liry (YTL)
+STR_CURR_SKK :Slovenske Koruny (SKK)
+STR_CURR_BRR :Brazílske Realy (BRL)
+
+STR_CURR_CUSTOM :Vlastna ...
+
+STR_OPTIONS_LANG :{BLACK}Jazyk
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Vyber jazyka rozhrania
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Cela obrazovka
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}Zaskrtnite, ak chcete hrat OpenTTD na celej obrazovke
+
+STR_OPTIONS_RES :{BLACK}Rozlisenie obrazovky
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Vyber rozlisenia obrazovky
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Format screenshotov
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Vyber format screenshotov
+
+STR_AUTOSAVE_1_MONTH :Kazdy mesiac
+STR_AUTOSAVE_FAILED :{WHITE}Autoulozenie zlyhalo
+
+STR_MONTH_JAN :Januar
+STR_MONTH_FEB :Februar
+STR_MONTH_MAR :Marec
+STR_MONTH_APR :April
+STR_MONTH_MAY :Maj
+STR_MONTH_JUN :Jun
+STR_MONTH_JUL :Jul
+STR_MONTH_AUG :August
+STR_MONTH_SEP :September
+STR_MONTH_OCT :Oktober
+STR_MONTH_NOV :November
+STR_MONTH_DEC :December
+
+STR_HEADING_FOR_STATION :{LTBLUE}Smeruje do {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}Smeruje do {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Bez urcenia
+STR_NO_ORDERS_VEL :{LTBLUE}Bez urcenia, {VELOCITY}
+
+STR_PASSENGERS :cestujucich
+STR_BAGS :vriec
+STR_TONS :ton
+STR_LITERS :litrov
+STR_ITEMS :kusov
+STR_CRATES :debien
+STR_RES_OTHER :ine
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Nemozno zdielat zoznam smerov ...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Nemozno kopirovat zoznam prikazov ...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - Koniec zdielanych prikazov - -
+
+STR_TRAIN_IS_LOST :{WHITE}Vlak {COMMA} sa stratil.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}Zisk vlaku {COMMA} za posledny rok bol {CURRENCY}
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}Europska Menova Unia!{}{}Euro bolo uvedene ako hlavna mena pre bezne pouzivanie v tejto krajine.
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Vlak {COMMA} ma malo prikazov
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}Vlak {COMMA} ma prazdny prikaz
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}Vlak {COMMA} ma zdvojene prikazy
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}Vlak {COMMA} ma neplatnu stanicu v prikazoch
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}Vozidlo {COMMA} ma malo prikazov
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}Vozidlo {COMMA} ma prazdny prikaz
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}Vozidlo {COMMA} ma zdvojene prikazy
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}Vozidlo {COMMA} ma neplatnu stanicu v prikazoch
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}Lod {COMMA} ma malo prikazov
+STR_SHIP_HAS_VOID_ORDER :{WHITE}Lod {COMMA} ma prazdny prikaz
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}Lod {COMMA} ma zdvojene prikazy
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}Lod {COMMA} ma neplatnu stanicu v prikazoch
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}Lietadlo {COMMA} ma malo prikazov
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}Lietadlo {COMMA} ma prazdny prikaz
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}Lietadlo {COMMA} ma zdvojene prikazy
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}Lietadlo {COMMA} ma neplatnu stanicu v prikazoch
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}Zlyhalo obnovenie vlaku {COMMA} (finacny limit)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}Zlyhalo obnovenie automobilu {COMMA} (finacny limit)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}Zlyhalo obnovenie lode {COMMA} (financny limit)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}Zlyhalo obnovenie lietadla {COMMA} (finacny limit)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}Vlak {COMMA} je po vymene prilis dlhy
+
+STR_CONFIG_PATCHES :{BLACK}Nastavenia patchov
+STR_CONFIG_PATCHES_TIP :{BLACK}Nastavenia patchov
+STR_CONFIG_PATCHES_CAPTION :{WHITE}Nastavenia patchov
+
+STR_CONFIG_PATCHES_OFF :Vyp.
+STR_CONFIG_PATCHES_ON :Zap.
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Zobrazit rychlost vozidla v stavovej liste: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Umoznit vystavbu na svahoch a na pobrezi: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Povolit realistickejsiu velkost oblasti pokrytia: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Umoznit odstranenie viacerych mestskych ciest, mostov, ... : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Umoznit stavbu dlhych vlakov: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Zapnut realnu akceleraciu vlakov: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Zakazat vlakom a lodiam otacanie o 90 st.: {ORANGE}{STRING} {LTBLUE} (vyzaduje NPF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Umoznit spajanie stanic: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Opustit stanicu ked jeden z nakladov je plny, pri 'plne naloz': {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Pouzit vylepseny algoritmus nakladania: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GRADUAL_LOADING :{LTBLUE}Postupné nakladanie vozidiel: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Inflacia: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Vykladat tovar len v stanici kde je dopyt: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Umoznit stavbu dlhych mostov: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Umoznit zaradenie depa do zoznamu prikazov: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Umoznit vystavbu priemyslu produkujuceho suroviny: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Umoznit viac priemyslu rovnakeho typu v jednom meste: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Rovnaky priemysel moze byt stavany blizko seba: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Zobrazit dlhy format datumu v stavovej liste: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Zobrazit zel. signaly na strane, kde jazdia vozidla: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Zobrazit rozpocet na konci roku: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}TTDPatch kompatibilna interpretacia prikazu nonstop: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Radenie cestnych vozidiel (podla mnozstva tovaru): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Posuvat okno ked je kurzor mysi na jeho okraji: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Umoznit podplacanie miestnej spravy: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Roznorode stanice: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Novy globalny algoritmus hladania cesty (NPF namiesto NTP): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FREIGHT_TRAINS :{LTBLUE}Váhový násobok pre nákladné vlaky: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Vzdy povolit stavbu malych letisk: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Upozornit na stratu vlaku: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Obnovenie prikazov vozidla: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :nie
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :ano, okrem zastavenych vozidiel
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :ano, u vsetkych vozidiel
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Upozornit ak je vlak stratovy: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Nikdy neprestat s vyrobou starych vozidiel: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Automaticka obnova dopravnych prostriedkov, ked su stare
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Obnovit vozidlo {ORANGE}{STRING}{LTBLUE} mesiacov pred/po dosiahnuti max. veku
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Min. mnozstvo penazi pre aut. obnovovanie vozidiel: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Dlzka zobrazenia chybovej spravy: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Zobrazit pocet obyvatelov mesta v jeho nazve: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Neviditelne stromy (pri priesvitnych budovach): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Generator uzemia: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :Povodny
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis
+STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}Max. vzdialenost ropnych rafinerii od okraja mapy: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Uroven ciary snehu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN :{LTBLUE}Clenitost terenu (len pre TerraGenesis) : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Velmi rovny
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH :Rovny
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH :Clenity
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :Velmi clenity
+STR_CONFIG_PATCHES_TREE_PLACER :{LTBLUE}Algoritmus umiestnovania stromov: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TREE_PLACER_NONE :Ziadny
+STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL :Povodny
+STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED :Vylepseny
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION :{LTBLUE}Orientacia vyskovej mapy: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Proti smeru hodinovych ruciciek
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE :V smere hodinovych ruciciek
+STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT :{LTBLUE}Vyskova uroven pre rovinaty scenar: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Max. rozsah stanice: {ORANGE}{STRING} {RED}Pozor: Vysoke hodnoty spomaluju hru
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Automaticke opravy vrtulnikov v heliporte: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Otvarat panel uprav terenu s panelom stavby trati, ciest, ... : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Pri posuvani mapy mysou posuvat opacnym smerom: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Zobrazit info o rozmerom pri vystavbe: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Zobrazit farebne schemy spolocnosti: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES_NONE :Ziadne
+STR_CONFIG_PATCHES_LIVERIES_OWN :Vlastna spolocnost
+STR_CONFIG_PATCHES_LIVERIES_ALL :Vsetky spolocnosti
+STR_CONFIG_PATCHES_PREFER_TEAMCHAT :{LTBLUE}Preferovaný teamový chat: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Maximalny pocet vlakov hraca: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Maximalny pocet automobilov hraca: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}Maximalny pocet lietadiel hraca: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}Maximalny pocet lodi hraca: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Zakazat vlaky pre pocitac: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Zakazat automobily pre pocitac: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Zakazat lietadla pre pocitac: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Zakazat lode pre pocitac: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Povolit nove AI (alpha verzia): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Povolit AI v multiplayeri (experimentalne): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Implicitny servisny interval pre vlaky: {ORANGE}{STRING} dni
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Implicitny servisny interval pre vlaky: {ORANGE}vypnuty
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Implicitny servisny interval pre automobily: {ORANGE}{STRING} dni/%
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Implicitny servisny interval pre automobily: {ORANGE}vypnuty
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Implicitny servisny interval pre lietadla: {ORANGE}{STRING} dni/%
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Implicitny servisny interval pre lietadla: {ORANGE}vypnuty
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Implicitny servisny interval pre lode: {ORANGE}{STRING} dni/%
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Implicitny servisny interval pre lode: {ORANGE}vypnuty
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Vypnut servisy, ak su vypnute poruchy: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Obmedzenie rychlosti pre vagony: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}Zakázat elektrifikovanú železnicu: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Farebne spravy sa prvykrat objavia v roku: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Zaciatok hry v roku: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}Koniec hry v roku: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Mierne zmeny ekonomiky (viac mensich zmien)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Povolit nakup akcii ostatnych spolocnosti
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Pri stavbe tahanim umiestnit semafory na kazde: {ORANGE}{STRING}. pole
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Pozicia hlavneho menu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Nalavo
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :V strede
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Napravo
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Vzdialenost pre prichytenie okna: {ORANGE}{STRING} bodov
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Vzdialenost pre prichytenie okna: {ORANGE}vypnute
+
+STR_CONFIG_PATCHES_GUI :{BLACK}Rozhranie
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Vystavba
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Vozidla
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Stanice
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Ekonomika
+STR_CONFIG_PATCHES_AI :{BLACK}Protivnici
+
+STR_CONFIG_PATCHES_DISABLED :zakazane
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Zmenit hodnotu nastavenia
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Niektore alebo vsetky implicitne servisne intervaly su nekompatibilne s vybranym nastavenim. 5-90% a 30-800 dni su platne.
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}Pouzit YAPF pre lode: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}Pouzit YAPF pre vozidla: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}Pouzit YAPF pre vlaky: {ORANGE}{STRING}
+
+STR_TEMPERATE_LANDSCAPE :krajina mierneho pasma
+STR_SUB_ARCTIC_LANDSCAPE :subarkticka krajina
+STR_SUB_TROPICAL_LANDSCAPE :subtropicka krajina
+STR_TOYLAND_LANDSCAPE :krajina hraciek
+
+STR_CHEATS :{WHITE}Cheaty
+STR_CHEATS_TIP :{BLACK}Checkbox indikuje opakovane pouzite cheatu
+STR_CHEATS_WARNING :{BLACK}Varovanie! Chcete podviest vasich protihracov. Tento podvod sa navzdy zapameta.
+STR_CHEAT_MONEY :{LTBLUE}Zvysit hotovost o {CURRENCY64}
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Hrat ako hrac: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Magicky buldozer (odstrani priemysel, budovy): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Tunely sa mozu navzajom krizit: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Umoznit vystavbu v pauze: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Prudove lietadla nehavaruju (tak casto) na malych letiskach: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Zmenit klimu: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Zmenit datum: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}Povolit zmenu objemu vyroby: {ORANGE}{STRING}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}Smeruje do {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Smeruje do {WAYPOINT}, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :Chod cez {WAYPOINT}
+STR_GO_NON_STOP_TO_WAYPOINT :Chod bez zastavky cez {WAYPOINT}
+
+STR_WAYPOINTNAME_CITY :Smerovy bod {TOWN}
+STR_WAYPOINTNAME_CITY_SERIAL :Smerovy bod {TOWN} #{COMMA}
+STR_LANDINFO_WAYPOINT :Smerovy bod
+
+STR_WAYPOINT :{WHITE}Smerovy bod
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Vyber typ kontrolneho bodu
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}Upravit nazvy smerovych bodov
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Nazov smeroveho bodu sa neda zmenit ...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Konvertovat zeleznicu na smerove body
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Tu nie je mozne postavit zeleznicny smerovy bod ...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Tu nie je mozne odstranit zeleznicny smerovy bod ...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Automaticka stavba zeleznicnych kolaji
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}... v tomto scenari nie je ziadne mesto
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}Si si isty, ze chces vytvorit nahodny teren?
+STR_MANY_RANDOM_TOWNS :{BLACK}Vela nahodnych miest
+STR_RANDOM_TOWNS_TIP :{BLACK}Pokryt mapu nahodne umiestnenymi mestami
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Vela nahodneho priemyslu
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Pokryt mapu nahodne umiestnenym priemyslom
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Nemozno vygenerovat priemysel ...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Otvorit panel nastrojov pre upravy terenu, vysadbu stromov, ...
+STR_LANDSCAPING_TOOLBAR :{WHITE}Uprava terenu
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Vyrovnat teren
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Nahodne stromy
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}Umiestnit nahodne stromy
+
+STR_CANT_BUILD_CANALS :{WHITE}Tu sa neda postavit prieplav ...
+STR_BUILD_CANALS_TIP :{BLACK}Postavit prieplavy
+STR_LANDINFO_CANAL :Prieplav
+
+STR_CANT_BUILD_LOCKS :{WHITE}Tu sa neda postavit stavidlo ...
+STR_BUILD_LOCKS_TIP :{BLACK}Postavit stavidla ...
+STR_LANDINFO_LOCK :Stavidlo
+
+STR_BUOY_IS_IN_USE :{WHITE}... boja sa pouziva!
+
+STR_LANDINFO_COORDS :{BLACK}Suradnice: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Nemozno odstranit cast stanice ...
+STR_CANT_CONVERT_RAIL :{WHITE}Tu nemozno zkonvertovat typ zeleznice ...
+STR_CONVERT_RAIL_TIP :{BLACK}Konvertovat/vylepsit typ zeleznice
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Presun lokomotivu sem, pre predaj celeho vlaku
+
+STR_DRAG_DROP :{BLACK}Automaticky
+STR_STATION_DRAG_DROP :{BLACK}Automaticky postavit stanicu podla oznaceneho bloku terenu
+STR_SELECT_STATION_CLASS_TIP :{BLACK}Vyberte druh stanice pre zobrazenie
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Vyberte typ stanice pre vystavbu
+
+STR_FAST_FORWARD :{BLACK}Rychle posunutie hry do predu
+STR_MESSAGE_HISTORY :{WHITE}Archiv sprav
+STR_MESSAGE_HISTORY_TIP :{BLACK}Zoznam poslednych sprav
+STR_MESSAGES_DISABLE_ALL :{BLACK}Zakazat vsetky
+STR_MESSAGES_ENABLE_ALL :{BLACK}Povolit vsetky
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Postavit uholnu banu
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Vysadit les
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Postavit vrtnu plosinu
+STR_CONSTRUCT_FARM_TIP :{BLACK}Financovat farmu
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Postavit medennu banu
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Postavit ropny vrt
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Postavit zlatu banu
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Postavit diamantovu banu
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Postavit zelezorudnu banu
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Financovat ovocnu plantaz
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Financovat kaucukovu plantaz
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Financovat vodny zdroj
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Vysadit les na cukrovu vatu
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}Postavit vyrobu baterii
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Postavit vyrobu kofoly
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Financovat zuvackovu fontanu
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Postavit bublifuk
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Postavit karamelovy lom
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Postavit cukrovu banu
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Priemysel
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA}% prepravenych)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA}%/{COMMA}% prepravenych)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}... prilis blizko ineho priemyslu
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Prestavat vlak na prepravu ineho nakladu
+STR_RAIL_REFIT_VEHICLE :{BLACK}Prestavat vlak
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Vybrat typ prepravovaneho nakladu
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Prestavat vlak na prepravu vybraneho nakladu
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Nemozno prestavat vlak ...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Servisne intervaly v percentach: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Zmenit produkciu
+
+TEMP_AI_IN_PROGRESS :{WHITE}Vitajte v novom AI. Mozete ocakavat problemy. Ak by nejake nastali urobte screenshot a poslite ho na forum.
+TEMP_AI_ACTIVATED :{WHITE}Varovanie: toto nove AI je iba alpha verzia! Momentalne iba automobily funguju!
+TEMP_AI_MULTIPLAYER :{WHITE}Varovanie: tato funkcia je stale experimentalna. Prosim ohlaste akekolvek problemy na truelight@openttd.org.
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Hra pre viac hrácov
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Meno hraca:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}Toto je meno podla ktoreho vas ostatny identifikuju
+STR_NETWORK_CONNECTION :{BLACK}Pripojenie:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Vyber si medzi hrou na internete alebo na lokalnej sieti
+
+STR_NETWORK_START_SERVER :{BLACK}Spustit server
+STR_NETWORK_START_SERVER_TIP :{BLACK}Spustit vlastny server
+
+STR_NETWORK_GAME_NAME :{BLACK}Nazov
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Nazov hry
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Jazyk, verzia serveru, atd.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Vyberte hru zo zoznamu
+
+STR_NETWORK_FIND_SERVER :{BLACK}Najst server
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Hladat po sieti servery
+STR_NETWORK_ADD_SERVER :{BLACK}Pridat server
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Prida server do zoznamu, v ktorom sa automaticky budu hladat beziacie hry.
+STR_NETWORK_ENTER_IP :{BLACK}Zadajte IP adresu serveru
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Klienti
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Klienti online / klienti max
+STR_NETWORK_GAME_INFO :{SILVER}INFO O HRE
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Klienti: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Jazyk: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Prostredie: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Velkost mapy: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}Verzia servera: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}Adresa servera: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Datum zaciatku: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Aktualny datum: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Heslo:
+STR_NETWORK_SERVER_OFFLINE :{SILVER}SERVER JE OFFLINE
+STR_NETWORK_SERVER_FULL :{SILVER}SERVER JE PLNY
+STR_NETWORK_VERSION_MISMATCH :{SILVER}ROZNE VERZIE
+STR_NETWORK_GRF_MISMATCH :{SILVER}NEWGRF Chyba
+
+STR_NETWORK_JOIN_GAME :{BLACK}Pripojit sa
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}Zacat novu hru pre viac hracov
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Nazov hry:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}Nazov hry, ktory uvidia ostatni v zozname sietovych hier
+STR_NETWORK_SET_PASSWORD :{BLACK}Nastavit heslo
+STR_NETWORK_PASSWORD_TIP :{BLACK}Ochran hru heslom, ak nechcec aby sa pripajali ostatni ludia
+STR_NETWORK_SELECT_MAP :{BLACK}Vyber mapu:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}Ktoru mapu chces hrat?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}Maximalny pocet klientov:
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Zvol maximalny pocet klientov. Moze sa ich pripojit aj menej.
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :LAN
+STR_NETWORK_INTERNET :Internet
+STR_NETWORK_LAN_INTERNET :LAN / Internet
+STR_NETWORK_INTERNET_ADVERTISE :Internet (oznamit)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 hracov
+STR_NETWORK_1_PLAYERS :1 hrac
+STR_NETWORK_2_PLAYERS :2 hráci
+STR_NETWORK_3_PLAYERS :3 hráci
+STR_NETWORK_4_PLAYERS :4 hráci
+STR_NETWORK_5_PLAYERS :5 hrácov
+STR_NETWORK_6_PLAYERS :6 hrácov
+STR_NETWORK_7_PLAYERS :7 hrácov
+STR_NETWORK_8_PLAYERS :8 hrácov
+STR_NETWORK_9_PLAYERS :9 hrácov
+STR_NETWORK_10_PLAYERS :10 hrácov
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}Max. pocet spolocnosti:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Obmedzi maximalny pocet spolocnosti na serveri
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}Max. pocet divakov:
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Omedzi maximalny pocet divakov na serveri
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Jazyk hracov:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Aby ostatni hraci vedeli, akym jazykom sa bude hovorit na serveri.
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}Spustit hru
+STR_NETWORK_START_GAME_TIP :{BLACK}Zacat sietovu hru z nahodnej mapy alebo scenara
+STR_NETWORK_LOAD_GAME :{BLACK}Nahrat hru
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Pokracovat v ulozenej hre (uistite sa, ze sa pripojite ako spravny hrac)
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Lubovolny
+STR_NETWORK_LANG_ENGLISH :Anglicky
+STR_NETWORK_LANG_GERMAN :Nemecky
+STR_NETWORK_LANG_FRENCH :Francuzsky
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Sietova hra - lobby
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Pripravuje sa k vstupu: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}Aktualny zoznam spolocnosti v tejto hre. Bud mozes do jednej vstupit, alebo zalozit novu spolocnost.
+STR_NETWORK_NEW_COMPANY :{BLACK}Nová spolocnost
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Zalozit novu spolocnost
+STR_NETWORK_SPECTATE_GAME :{BLACK}Sledovat hru
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Sledovat hru len ako divak
+STR_NETWORK_JOIN_COMPANY :{BLACK}Vstupit do spolocnosti
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Pomoct viest tuto spolocnost
+STR_NETWORK_REFRESH :{BLACK}Obnovit server
+STR_NETWORK_REFRESH_TIP :{BLACK}Obnovit info o serveri
+
+STR_NETWORK_COMPANY_INFO :{SILVER}INFO O SPOLOCNOSTI
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Nazov spolocnosti: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}Zalozene: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}Hodnota spolocnosti: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Stav uctu: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Zisk v minulom roku: {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}Vykon: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}Vozidla: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Stanice: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Hraci: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}Pripajam sa ...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) Pripajam sa ..
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Overovanie ..
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Cakam ..
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Stahovanie mapy..
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Spracovanie dat ..
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) Registracia ..
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Prijem informacii o hre..
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Prijem informacii o spolocnosti..
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} klient{P "" e i} pred nami
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} kB stiahnute
+
+STR_NETWORK_DISCONNECT :{BLACK}Odpojit sa
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Napis sumu, ktoru chces poskytnut
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Server je chraneny. Zadaj heslo
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Spolocnost je chranena. Zadaj heslo
+STR_NETWORK_CLIENT_LIST :{WHITE}Zoznam klientov
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE} Nie su ziadne sietove zariadenie alebo hra je kompilovana bez ENABLE_NETWORK
+STR_NETWORK_ERR_NOSERVER :{WHITE} Nebola najdena ziadna sietova hra
+STR_NETWORK_ERR_NOCONNECTION :{WHITE} Server neodpoveda na ziadost
+STR_NETWORK_ERR_DESYNC :{WHITE} Siet - Chyba synchronizacie hry
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} Siet - Stratene spojenie
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} Nedokazem nahrat hru zo servera
+STR_NETWORK_ERR_SERVER_START :{WHITE} Nemozem spustit server.
+STR_NETWORK_ERR_CLIENT_START :{WHITE} Nemozem sa pripojit.
+STR_NETWORK_ERR_TIMEOUT :{WHITE} Vyprsal casovy limit pre spojenie #{NUM}.
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE} Chyba vznikla v protokole a spojenie je zatvorene.
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE} Revizia hry u tohto klienta nezodpoveda revizii hry na serveri.
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} Nespravne heslo.
+STR_NETWORK_ERR_SERVER_FULL :{WHITE} Server je plny
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} Si zablokovany na tomto serveri
+STR_NETWORK_ERR_KICKED :{WHITE} Bol si vyhodeny z hry
+STR_NETWORK_ERR_CHEATER :{WHITE} Cheatovanie nie je povolene na tomto serveri
+
+STR_NETWORK_ERR_LEFT :opustil hru
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :generalna chyba
+STR_NETWORK_ERR_CLIENT_DESYNC :chyba synchronizacie
+STR_NETWORK_ERR_CLIENT_SAVEGAME :neviem nahrat mapu
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :spojenie prerusene
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :chyba protokolu
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :overenie odmietnute
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :neplatny packet prijaty
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :chybna revizia hry
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :meno sa uz pouziva
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :nespravne heslo
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :chybne id hraca v DoCommand
+STR_NETWORK_ERR_CLIENT_KICKED :vyhodeny zo servera
+STR_NETWORK_ERR_CLIENT_CHEATER :sa pokusal cheatovat
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :server je plny
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :vstupil do hry
+STR_NETWORK_GIVE_MONEY :ti poslal peniaze ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :poslal si {STRING} penazie ({CURRENCY})
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Tim] :
+STR_NETWORK_CHAT_COMPANY :[Tim] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Tim] pre {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[Privany] :
+STR_NETWORK_CHAT_CLIENT :[Osobny] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[Privatny] pre {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[Vsetci] :
+STR_NETWORK_CHAT_ALL :[Vsetci] {STRING}: {GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :si zmenil meno na
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE} Server ukoncil relaciu
+STR_NETWORK_SERVER_REBOOT :{WHITE} Server sa restartuje ...{}Cakajte prosim ...
+
+STR_NETWORK_SERVER :Server
+STR_NETWORK_CLIENT :Klient
+STR_NETWORK_SPECTATORS :Pozorovatelia
+
+STR_NETWORK_CLIENTLIST_NONE :(nikto)
+STR_NETWORK_CLIENTLIST_KICK :Vyhodit
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Previest peniaze
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Napisat vsetkym
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Napisat spolocnosti
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Privatna sprava
+
+
+STR_NETWORK_SEND :{BLACK}Poslat
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}X-rozmer mapy: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Y-rozmer mapy: {ORANGE}{STRING}
+
+
+##### PNG-MAP-Loader
+
+STR_PNGMAP_ERROR :{WHITE}Nie je mozne nahrat povrch z PNG suboru ...
+STR_PNGMAP_ERR_FILE_NOT_FOUND :{WHITE}... subor nenajdeny.
+STR_PNGMAP_ERR_IMAGE_TYPE :{WHITE}...nie je mozne zkonvertovat format obrazku. Potrebne 8 alebo 24 bitove PNG.
+STR_PNGMAP_ERR_MISC :{WHITE}... neocakavana chyba (pravdepodobne poskodeny subor)
+
+STR_BMPMAP_ERROR :{WHITE}Nie je možné nahrat povrch z BMP suboru ...
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}...nie je mozne zkonvertovat format obrazku.
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Cena: {CURRENCY}
+STR_0801_COST :{RED}Cena: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Zisk: {CURRENCY}
+STR_0803_INCOME :{GREEN}Zisk: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Prekladka: {CURRENCY}
+STR_FEEDER :{YELLOW}Prekladka: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Priblizna cena: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Priblizny zisk: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Tu nemozno zdvihnut teren ...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Tu nemozno znizit teren ...
+STR_080A_ROCKS :Skaly
+STR_080B_ROUGH_LAND :Nerovny teren
+STR_080C_BARE_LAND :Holy teren
+STR_080D_GRASS :Travnaty teren
+STR_080E_FIELDS :Polia
+STR_080F_SNOW_COVERED_LAND :Zasnezeny teren
+STR_0810_DESERT :Pust
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Teren ma nevhodny sklon
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Nemozna kombinacia trate
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}Vyhlbenie by poskodilo tunel
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Na urovni mora
+STR_1004_TOO_HIGH :{WHITE}Prilis vysoko
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Ziadne pouzitelne zeleznicne kolaje
+STR_1007_ALREADY_BUILT :{WHITE}... uz bolo vytvorene
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Najskor treba odstranit zeleznicne kolaje
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Zeleznica
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Elektrifikovana železnica
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Jednokolajka - Monorail
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}Magneticka draha - MagLev
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Vyber zeleznicny most
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Tu nemoze byt postavene depo ...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Tu nemoze byt postavena zeleznicna stanica ...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Tu sa nedaju stavat semafory ...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Tu sa nedaju stavat zeleznicne kolaje ...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Tu nemozno odstranit zeleznicne kolaje ...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Tu nemozno odstranit semafory ...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Orientacia depa
+STR_1015_RAILROAD_CONSTRUCTION :Zeleznica
+STR_TOOLB_ELRAIL_CONSTRUCTION :Elektrifikovana železnica
+STR_1016_MONORAIL_CONSTRUCTION :Jednokolajka - Monorail
+STR_1017_MAGLEV_CONSTRUCTION :Magneticka draha - MagLev
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Postavit zeleznicne kolaje
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Postavit zeleznicne depo (pre vyrobu a opravu vlakov)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Postavit zeleznicnu stanicu
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Postavit zeleznicne semafory
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Postavit zeleznicny most
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Postavit zeleznicny tunel
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Prepnut stavbu/odstranenie zeleznicnych kolaji a semaforov
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Vyber mostu - kliknut na vybrany most
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Vyber orientacie depa
+STR_1021_RAILROAD_TRACK :Zeleznicne kolaje
+STR_1023_RAILROAD_TRAIN_DEPOT :Zeleznicne depo
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}... oblast vlastni ina spolocnost
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :Zeleznicne kolaje so standartnym semaforom
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :Zeleznicne kolaje s pre-signami
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :Zeleznicne kolaje s exit-signalmi
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :Zeleznicne kolaje s combo-signalmi
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Cesta musi byt najskor odstranena
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Prebiehaju cestne prace
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Vystavba cesty
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Vyber cestny most
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Tu sa neda postavit cesta ...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Tu sa neda odstranit cesta ...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Orientacia garaze
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Tu sa neda postavit garaz ...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Nemozno postavit autobusovu zastavku ...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Nemozno postavit vykladku ...
+STR_180A_ROAD_CONSTRUCTION :Vystavba cesty
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Postavit cast cesty
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Postavit garaz (na vyroby a opravy automobilov)
+STR_180D_BUILD_BUS_STATION :{BLACK}Postavit autobusovu zastavku
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Postavit vykladku
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Postavit cestny most
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Postavit cestny tunel
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Prepnut stavbu/odstranovanie cesty
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Vybrat orientaciu garaze
+STR_1814_ROAD :Cesta
+STR_1815_ROAD_WITH_STREETLIGHTS :Cesta s lampami
+STR_1816_TREE_LINED_ROAD :Cesta v aleji
+STR_1817_ROAD_VEHICLE_DEPOT :Garaz
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :Zeleznicne priecestie
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Mesta
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Budova sa musi zburat
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}Obyvatelstvo: {ORANGE}{COMMA}{BLACK} Domov: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Premenovat mesto
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Mesto nemoze byt odstranene ...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} miestna sprava to nedovoli
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Nazvy miest - kliknut na meno pre pohlad na stred mesta
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Pohlad na stred mesta
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Zmenit nazov mesta
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Cestujuci posledny mesiac: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Posta posledny mesiac: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Administrativa
+STR_2010_OFFICE_BLOCK :Kancelarie
+STR_2011_SMALL_BLOCK_OF_FLATS :Maly bytovy blok
+STR_2012_CHURCH :Kostol
+STR_2013_LARGE_OFFICE_BLOCK :Ministerstvo
+STR_2014_TOWN_HOUSES :Mestske domy
+STR_2015_HOTEL :Hotel
+STR_2016_STATUE :Socha
+STR_2017_FOUNTAIN :Fontana
+STR_2018_PARK :Park
+STR_2019_OFFICE_BLOCK :Kancelarie
+STR_201A_SHOPS_AND_OFFICES :Obchody a kancelarie
+STR_201B_MODERN_OFFICE_BUILDING :Moderna administrativna budova
+STR_201C_WAREHOUSE :Sklad
+STR_201D_OFFICE_BLOCK :Kancelarie
+STR_201E_STADIUM :Stadion
+STR_201F_OLD_HOUSES :Stare domy
+STR_2020_LOCAL_AUTHORITY :{BLACK}Miestna sprava
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Zobrazit informacie o miestnej sprave
+STR_2022_LOCAL_AUTHORITY :{WHITE}Miestna sprava {TOWN}
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Hodnotenie dopravnych spolocnosti:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Dotacie
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Ponuknute dotacie:
+STR_2027_FROM_TO :{ORANGE}{STRING} z {STRING} do {STRING}
+STR_2028_BY :{YELLOW} ({DATE_SHORT})
+STR_202A_NONE :{ORANGE}Ziadne
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}V sucasnosti poskytovane dotacie:
+STR_202C_FROM_TO :{ORANGE}{STRING} z {STATION} do {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, do {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}Ponuka dotacie skoncila:{}{}Preprava {STRING.g} z {STRING} do {STRING} uz nebude dotovana.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Dotacia ukoncena:{}{}Preprava {STRING.g} z {STATION} do {STATION} uz viac nebude dotovana.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Ponuka dotacie:{}{}Prva preprava {STRING.g} z {STRING} do {STRING} bude dotovana miestnou spravou!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Dotacia udelena spolocnosti {COMPANY}!{}{}Preprava {STRING.g} z {STATION} do {STATION} bude buduci rok o 50% vynosnejsia!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Dotacia udelena spolocnosti {COMPANY}!{}{}Preprava {STRING.g} z {STATION} to {STATION} bude buduci rok 2x vynosejnsia!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Dotacia udelena spolocnosti {COMPANY}!{}{}Preprava {STRING.g} z {STATION} do {STATION} bude buduci rok 3x vynosnejsia!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Dotacia udelena spolocnosti {COMPANY}!{}{}Preprava {STRING.g} z {STATION} do {STATION} bude buduci rok 4x vynosnejsia!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}Miestna sprava {TOWN} odmietla stavbu letiska v tomto meste
+STR_2036_COTTAGES :Chaty
+STR_2037_HOUSES :Domy
+STR_2038_FLATS :Byty
+STR_2039_TALL_OFFICE_BLOCK :Administrativa
+STR_203A_SHOPS_AND_OFFICES :Obchody a kancelarie
+STR_203B_SHOPS_AND_OFFICES :Obchody a kancelarie
+STR_203C_THEATER :Divadlo
+STR_203D_STADIUM :Stadion
+STR_203E_OFFICES :Kancelarie
+STR_203F_HOUSES :Domy
+STR_2040_CINEMA :Kino
+STR_2041_SHOPPING_MALL :Obchodny dom
+STR_2042_DO_IT :{BLACK}Vykonat
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}Co sa da urobit v tomto meste - kliknut na polozku pre detaily
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Vykonat vybranu cinnost
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Dostupne cinnosti:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Mala reklamna kampan
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Stredna reklamna kampan
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Velka reklamna kampan
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Financovat rekonstrukciu ciest
+STR_204A_BUILD_STATUE_OF_COMPANY :Postavit sochu majitela spolocnosti
+STR_204B_FUND_NEW_BUILDINGS :Financovat vystavbu budov
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Zakupit exkluzivne dopravne prava
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Podplatit miestnu spravu
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Spustit malu reklamnu kampan vasich dopravnych sluzieb.{} Cena: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Spustit strednu reklamnu kampan vasich dopravnych sluzieb.{} Cena: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Spustit velku reklamnu kampan vasich dopravnych sluzieb.{} Cena: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} Financovat rekonstrukciu a vystavbu cesty. Sposobi dopravny chaos a zapchy trvajuce dalsich 6 mesiacov.{} Cena: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Postavit sochu na oslavu vasej spolocnosti.{} Cena: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Financovat vystavbu administrativnych a obchodnych budov.{} Cena: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Zakupit exkluzivne dopravne prava na 1 rok pre vasu spolocnost. Miestna sprava vam zaruci vyuzivanie len dopravnych sluzieb vasej spolocnosti.{} Cena: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Podplatit miestnu spravu pre zvysenie hodnotenia vasej spolocnosti, s rizikom tazkeho postihu pri odhaleni!{} Cena: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}V meste {TOWN} zavladol dopravny chaos!{}{}Rekonstrukcia ciest financovana {COMPANY} prinesie 6 mesiacov utrpenia pre motoristov!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (v rekonstrukcii)
+STR_2059_IGLOO :Iglu
+STR_205A_TEPEES :Vigvam
+STR_205B_TEAPOT_HOUSE :Kaviaren
+STR_205C_PIGGY_BANK :Mala Banka
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{1:STRING} {0:TOWN}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Uprava terenu
+STR_2800_PLANT_TREES :Vysadba stromov
+STR_2801_PLACE_SIGN :Umiestnenie popisu
+STR_2802_TREES :{WHITE}Stromy
+STR_2803_TREE_ALREADY_HERE :{WHITE}... strom tu uz je
+STR_2804_SITE_UNSUITABLE :{WHITE}... nevhodne miesto
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Tu sa strom neda zasadit ...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}... prilis vela popisov
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Tu sa neda dat popis ...
+STR_280A_SIGN :Popis
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Upravit text popisu
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Nemozno zmenit text popisu ...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Vybrat typ stromu pre sadenie
+STR_280E_TREES :Stromy
+STR_280F_RAINFOREST :Dazdovy prales
+STR_2810_CACTUS_PLANTS :Kaktusy
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Vyber zeleznicnej stanice
+STR_3001_AIRPORT_SELECTION :{WHITE}Vyber letiska
+STR_3002_ORIENTATION :{BLACK}Orientacia
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Pocet kolaji
+STR_3004_PLATFORM_LENGTH :{BLACK}Dlzka nastupista
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Prilis blizko inej zeleznicnej stanice
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Susedi z viacerymi stanicami/vykladkami
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}Prilis vela stanic/vykladok v tomto meste
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}Prilis vela stanic/vykladok
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Prilis vela autobusovych zastavok
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}Prilis vela zastavok nakladnych automobilov
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Prilis blizko inej stanice/vykladky
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Zeleznicna stanica sa musi naskor zburat
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Prilis blizko ineho letiska
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Letisko sa musi najskor zburat
+
+STR_3030_RENAME_STATION_LOADING :Premenovat stanicu/vykladku
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Stanica sa neda premenovat ...
+STR_3032_RATINGS :{BLACK}Hodnotenie
+STR_3033_ACCEPTS :{BLACK}Prijima
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}Hodnotenie prepravy:
+
+############ range for rating starts
+STR_3035_APPALLING :Hrozne
+STR_3036_VERY_POOR :Velmi zle
+STR_3037_POOR :Zle
+STR_3038_MEDIOCRE :Priemerne
+STR_3039_GOOD :Dobre
+STR_303A_VERY_GOOD :Velmi dobre
+STR_303B_EXCELLENT :Vyborne
+STR_303C_OUTSTANDING :Perfektne
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} uz neprijima {STRING}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} uz neprijima {STRING} alebo {STRING}
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} teraz prijima {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} teraz prijima {STRING} a {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Orientacia stanice
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Orientacia vykladky
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Stanica musi byt najskor zburana
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Vykladka musi byt najskor zburana
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Stanic{P a e ""}
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Ziadne -
+STR_304B_SITE_UNSUITABLE :{WHITE}... miesto je nepouzitelne
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Priliz blizko ineho pristavu
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Pristav musi byt najskor zburany
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Vybrat orientaciu zeleznicnej stanice
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Pocet kolaji zeleznicnej stanice
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Dlzka zeleznicnej stanice
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Vybrat orientaciu stanice
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Vybrat orientaciu vykladky
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Vycentrovat pohlad na poziciu stanice
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Zobrazit hodnotenie stanice
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Zmenit nazov stanice
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Zobrazit zoznam prijimaneho nakladu
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Nazvy stanic - kliknut pre vycentrovanie pohladu na poziciu stanice
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Vybrat velkost/typ letiska
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :Zeleznicna stanica
+STR_305F_AIRCRAFT_HANGAR :Letecky hangar
+STR_3060_AIRPORT :Letisko
+STR_3061_TRUCK_LOADING_AREA :Vykladka
+STR_3062_BUS_STATION :Stanica
+STR_3063_SHIP_DOCK :Pristav
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Zobrazit oblast pokrytia stavanej plochy
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Nezobrazit oblast pokrytia stavanej plochy
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Ukazat oblast pokrytia
+STR_3068_DOCK :{WHITE}Molo
+STR_3069_BUOY :Boja
+STR_306A_BUOY_IN_THE_WAY :{WHITE}... boja v ceste
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}... stanica je prilis velka
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}... roznorode stanice nie su povolene
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Podrzte CTRL pre vyber viacerych poloziek
+
+STR_UNDEFINED :(nedefinovaný retezec)
+STR_STAT_CLASS_DFLT :Pôvodná stanica
+STR_STAT_CLASS_WAYP :Smerove body
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Orientacia lodenice
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}... musi byt postavene na vode
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Lodenica sa tu neda postavit
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Vyber orientaciu pristavu
+STR_3804_WATER :Voda
+STR_3805_COAST_OR_RIVERBANK :Pobrezie alebo nabrezie
+STR_3806_SHIP_DEPOT :Lodenica
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}... nemoze byt postavene na vode
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Ulozit hru
+STR_4001_LOAD_GAME :{WHITE}Nahrat hru
+STR_4002_SAVE :{BLACK}Ulozit
+STR_4003_DELETE :{BLACK}Vymazat
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} megabajtov volnych
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Zariadenie je necitatelne
+STR_4007_GAME_SAVE_FAILED :{WHITE}Ulozenie hry zlyhalo
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Subor sa neda vymazat
+STR_4009_GAME_LOAD_FAILED :{WHITE}Nahratie hry zlyhalo
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}Zoznam diskov, adresarov a subory ulozenych hier
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Vybrany nazov pre ulozenie hry
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Vymazat vybranu ulozenu hru
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Ulozit aktualnu hru s pouzitim vybraneho mena
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Vyber typ novej hry
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Vyber scenar (zeleny), prednastavenu hra (modra), alebo nahodnu hru
+STR_4010_GENERATE_RANDOM_NEW_GAME :Vygenerovat nahodnu novu hru
+STR_4011_LOAD_HEIGHTMAP :{WHITE}Nahrat výškovú mapu
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} v ceste
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :Uholna bana
+STR_4803_POWER_STATION :Elektraren
+STR_4804_SAWMILL :Pila
+STR_4805_FOREST :Les
+STR_4806_OIL_REFINERY :Ropna rafineria
+STR_4807_OIL_RIG :Ropny vrt
+STR_4808_FACTORY :Tovaren
+STR_4809_PRINTING_WORKS :Tlaciaren
+STR_480A_STEEL_MILL :Oceliaren
+STR_480B_FARM :Farma
+STR_480C_COPPER_ORE_MINE :Medenna bana
+STR_480D_OIL_WELLS :Ropna plosina
+STR_480E_BANK :Banka
+STR_480F_FOOD_PROCESSING_PLANT :Vyroba jedla
+STR_4810_PAPER_MILL :Vyroba papiera
+STR_4811_GOLD_MINE :Zlata bana
+STR_4812_BANK :Banka
+STR_4813_DIAMOND_MINE :Diamantova bana
+STR_4814_IRON_ORE_MINE :Zelezorudna bana
+STR_4815_FRUIT_PLANTATION :Ovocny sad
+STR_4816_RUBBER_PLANTATION :Kaucukova plantaz
+STR_4817_WATER_SUPPLY :Vodny zdroj
+STR_4818_WATER_TOWER :Vodojem
+STR_4819_FACTORY :Tovaren
+STR_481A_FARM :Farma
+STR_481B_LUMBER_MILL :Pila
+STR_481C_COTTON_CANDY_FOREST :Les cukrovej vaty
+STR_481D_CANDY_FACTORY :Cukrovar
+STR_481E_BATTERY_FARM :Vyroba baterii
+STR_481F_COLA_WELLS :Vyroba kofoly
+STR_4820_TOY_SHOP :Hrackarstvo
+STR_4821_TOY_FACTORY :Vyroba hraciek
+STR_4822_PLASTIC_FOUNTAINS :Zuvackova fontana
+STR_4823_FIZZY_DRINK_FACTORY :Vyroba sumienky
+STR_4824_BUBBLE_GENERATOR :Bublifuk
+STR_4825_TOFFEE_QUARRY :Karamelovy lom
+STR_4826_SUGAR_MINE :Cukrova bana
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Potrebuje: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Potrebuje: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Potrebuje: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Produkcia za posledny mesiac:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% prepravenych)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Vycentrovanie pohladu na poziciu tovarne
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}{STRING} sa zacina stavat nedaleko mesta {TOWN}!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}{STRING} sa vysadza nedaleko mesta {TOWN}!
+STR_482F_COST :{BLACK}Cena: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Tento typ priemyslu sa tu neda postavit ...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... les sa moze sadit len pod ciarou snehu
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} oznamuje skore uzavretie!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}Zasobovacie problemy donutili {INDUSTRY} oznamit skore uzavretie!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}Nedostatok dostupnej drevnej suroviny donutil {INDUSTRY} oznamit skore uzavretie!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} zvyšuje produkciu!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}Nove nalezisko uhlia sa objavilo v {INDUSTRY}!{}Ocakava sa zdvojnasobenie produkcie!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}Nove nalezisko ropy sa objavilo na {INDUSTRY}!{}Ocakava sa zdvojnasobenie produkcie!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}Na {INDUSTRY} zlepsili pouzivane metody!Ocakava sa zdvojnasobenie produkcie!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}{INDUSTRY} znižuje produkciu o 50%
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}Premnozenie skodcov sposobilo znicenie urody na {INDUSTRY}!{}Produkcia sa znizila o 50%
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}... moze byt umiestnene len pri okraji mapy
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}{1:INDUSTRY} zvyšuje produkciu {0:STRING.g} o {2:COMMA}%!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}{1:INDUSTRY} znižuje produkciu {0:STRING.g} o {2:COMMA}%!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Vlak v tuneli
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Automobil v tuneli
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Iny tunel v ceste
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Nemozno zarovnat teren na druhej strane tunela
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Tunel musi byt najskor zburany
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Most musi byt najskor zburany
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Nemozno zacat a skoncit na tom istom mieste
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Pod mostom je potrebna voda alebo udolie
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}Zaciatok a koniec musi byt v rovine
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}To miesto je nepouzitelne ako vstup do tunela
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Zavesny ocelovy
+STR_500F_GIRDER_STEEL :Pilierovy ocelovy
+STR_5010_CANTILEVER_STEEL :Visuty ocelovy
+STR_5011_SUSPENSION_CONCRETE :Zavesny betonovy
+STR_5012_WOODEN :Dreveny
+STR_5013_CONCRETE :Betonovy
+STR_5014_TUBULAR_STEEL :Kryty ocelovy
+STR_BRIDGE_TUBULAR_SILICON :Kryty plastovy
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Tu sa neda postavit most ...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Tu sa neda postavit tunel ...
+STR_5017_RAILROAD_TUNNEL :Zeleznicny tunel
+STR_5018_ROAD_TUNNEL :Cestny tunel
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Ocelovy zavesny zeleznicny most
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Ocelovy pilierovy zeleznicny most
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Ocelovy visuty zeleznicny most
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Vystuzeny zavesny betonovy zeleznicny most
+STR_501F_WOODEN_RAIL_BRIDGE :Dreveny zeleznicny most
+STR_5020_CONCRETE_RAIL_BRIDGE :Betonovy zeleznicny most
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Ocelovy zavesny cestny most
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Ocelovy pilierovy cestny most
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Ocelovy visuty cestny most
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Vystuzeny zavesny betonovy cestny most
+STR_5025_WOODEN_ROAD_BRIDGE :Dreveny cestny most
+STR_5026_CONCRETE_ROAD_BRIDGE :Betonovy cestny most
+STR_5027_TUBULAR_RAIL_BRIDGE :Kryty zeleznicny most
+STR_5028_TUBULAR_ROAD_BRIDGE :Kryty cestny most
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}V ceste je prekazka
+STR_5801_TRANSMITTER :Vysielac
+STR_5802_LIGHTHOUSE :Majak
+STR_5803_COMPANY_HEADQUARTERS :Sidlo firmy
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}... sidlo firmy v ceste
+STR_5805_COMPANY_OWNED_LAND :Spolocnostou vlastneny pozemok
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Tento pozemok nie je mozne kupit ...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}... uz to vlastnis!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Bez mena
+STR_SV_TRAIN_NAME :Vlak {COMMA}
+STR_SV_ROADVEH_NAME :Automobil {COMMA}
+STR_SV_SHIP_NAME :Lod {COMMA}
+STR_SV_AIRCRAFT_NAME :Lietadlo {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :{STRING} Sever
+STR_SV_STNAME_SOUTH :{STRING} Juh
+STR_SV_STNAME_EAST :{STRING} Vychod
+STR_SV_STNAME_WEST :{STRING} Zapad
+STR_SV_STNAME_CENTRAL :{STRING} Centrum
+STR_SV_STNAME_TRANSFER :{STRING} Razcestie
+STR_SV_STNAME_HALT :{STRING} Za horou
+STR_SV_STNAME_VALLEY :{STRING} Udolie
+STR_SV_STNAME_HEIGHTS :{STRING} Na kopci
+STR_SV_STNAME_WOODS :{STRING} Lesy
+STR_SV_STNAME_LAKESIDE :{STRING} Jazera
+STR_SV_STNAME_EXCHANGE :{STRING} Predmestie
+STR_SV_STNAME_AIRPORT :{STRING} Letisko
+STR_SV_STNAME_OILFIELD :{STRING} Vrtna plosina
+STR_SV_STNAME_MINES :{STRING} Bane
+STR_SV_STNAME_DOCKS :{STRING} Pristav
+STR_SV_STNAME_BUOY_1 :{STRING} Boja 1
+STR_SV_STNAME_BUOY_2 :{STRING} Boja 2
+STR_SV_STNAME_BUOY_3 :{STRING} Boja 3
+STR_SV_STNAME_BUOY_4 :{STRING} Boja 4
+STR_SV_STNAME_BUOY_5 :{STRING} Boja 5
+STR_SV_STNAME_BUOY_6 :{STRING} Boja 6
+STR_SV_STNAME_BUOY_7 :{STRING} Boja 7
+STR_SV_STNAME_BUOY_8 :{STRING} Boja 8
+STR_SV_STNAME_BUOY_9 :{STRING} Boja 9
+STR_SV_STNAME_ANNEXE :{STRING} Zastavka
+STR_SV_STNAME_SIDINGS :{STRING} Vidiek
+STR_SV_STNAME_BRANCH :{STRING} Konecna
+STR_SV_STNAME_UPPER :Horny {STRING}
+STR_SV_STNAME_LOWER :Dolny {STRING}
+STR_SV_STNAME_HELIPORT :{STRING} Heliport
+STR_SV_STNAME_FOREST :{STRING} Les
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Uroven obtiaznosti
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Ulozit
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Lahka
+STR_6802_MEDIUM :{BLACK}Stredna
+STR_6803_HARD :{BLACK}Tazka
+STR_6804_CUSTOM :{BLACK}Vlastna
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}Max. pocet konkurentov: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Zaciatok konkurencie: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}Pocet miest: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}Pocet priemyslu: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Maximalny prvotny uver: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Pociatocny urok: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Naklady na prevadzku vozidiel: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Rychlost konkurencie: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Inteligencia konkurencie: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Poruchy vozidiel: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Nasobok dotacii: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Naklady na vystavbu: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Typ terenu: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Rozsah oceanov/jazier: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Ekonomika: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Otacanie vlakov: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Havarie: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Postoj miestnej spravy k stavebnym upravam mesta: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :Ziadny
+STR_6816_LOW :Nizke
+STR_6817_NORMAL :Normalne
+STR_6818_HIGH :Vysoke
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Velmi Pomale
+STR_681C_SLOW :Pomale
+STR_681D_MEDIUM :Stredne
+STR_681E_FAST :Rychle
+STR_681F_VERY_FAST :Velmi rychle
+STR_VERY_LOW :Velmi nizke
+STR_6820_LOW :Nizke
+STR_6821_MEDIUM :Stredne
+STR_6822_HIGH :Vysoke
+STR_6823_NONE :Ziadne
+STR_6824_REDUCED :Znizene
+STR_6825_NORMAL :Normalne
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Velmi rovny
+STR_682B_FLAT :Rovny
+STR_682C_HILLY :Kopcovity
+STR_682D_MOUNTAINOUS :Horsky
+STR_682E_STEADY :Stabilna
+STR_682F_FLUCTUATING :Kolisava
+STR_6830_IMMEDIATE :Ihned
+STR_6831_3_MONTHS_AFTER_PLAYER :3 mesiace po hracovi
+STR_6832_6_MONTHS_AFTER_PLAYER :6 mesiacov po hracovi
+STR_6833_9_MONTHS_AFTER_PLAYER :9 mesiacov po hracovi
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :Na konci trate a v stanicach
+STR_6835_AT_END_OF_LINE_ONLY :Len na konci trate
+STR_6836_OFF :Vyp.
+STR_6837_ON :Zap.
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Zobrazit tabulku najlepsich
+STR_6839_PERMISSIVE :Pozitivny
+STR_683A_TOLERANT :Tolerantny
+STR_683B_HOSTILE :Odmietavy
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Hrac {COMMA})
+STR_7004_NEW_FACE :{BLACK}Nová tvár
+STR_7005_COLOR_SCHEME :{BLACK}Farebna schema
+STR_7006_COLOR_SCHEME :{GOLD}Farebna schema:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Nová farebná schéma
+STR_7008_COMPANY_NAME :{BLACK}Nazov spolocnosti
+STR_7009_PRESIDENT_NAME :{BLACK}Meno prezidenta
+STR_700A_COMPANY_NAME :Nazov spolocnosti
+STR_700B_PRESIDENT_S_NAME :Meno prezidenta
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Nazov spolocnosti sa neda zmenit...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Meno prezidenta sa neda zmenit...
+STR_700E_FINANCES :{WHITE}{COMPANY} Financie {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Vydavky/Prijmy
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Vystavba
+STR_7012_NEW_VEHICLES :{GOLD}Nove vozidla
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Prevadzka vlakov
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Prevadzka automobilov
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Prevadzka lietadiel
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Prevadzka lodi
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Udrzba majetku
+STR_7018_TRAIN_INCOME :{GOLD}Trzby vlakov
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Trzby automobilov
+STR_701A_AIRCRAFT_INCOME :{GOLD}Trzby lietadiel
+STR_701B_SHIP_INCOME :{GOLD}Trzby lodi
+STR_701C_LOAN_INTEREST :{GOLD}Uroky
+STR_701D_OTHER :{GOLD}Ostatne
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Spolu:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Graf zisku
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Graf prevadzkoveho zisku
+STR_7026_BANK_BALANCE :{WHITE}Zostatok v banke
+STR_7027_LOAN :{WHITE}Uver
+STR_MAX_LOAN :{WHITE}Uverovy limit: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}Pozicat {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Splatit {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}... uverovy limit je {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Nemozno pozicat viac penazi ...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}... uver uz bol splateny
+STR_702E_REQUIRED :{WHITE}... {CURRENCY} potrebne
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Uver sa neda splatit ...
+STR_INSUFFICIENT_FUNDS :{WHITE}Nie je mozne poskytnut peniaze, ktore su pozicane z banky ...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Vybrat novu tvar prezidenta
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Zmenit vzhlad spolocnosti
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Zmenit meno prezidenta
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Zmenit nazov spolocnosti
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Kliknut pre vyber novej farby
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Zvysit velkost uveru
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Splatit cast uveru
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(Prezident)
+STR_7038_INAUGURATED :{GOLD}Zvoleny: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Stroje:
+STR_TRAINS :{WHITE}{COMMA} vlak{P "" y ov}
+STR_ROAD_VEHICLES :{WHITE}{COMMA} automobil{P "" y ov}
+STR_AIRCRAFT :{WHITE}{COMMA} lietad{P lo la iel}
+STR_SHIPS :{WHITE}{COMMA} lod{P "" e i}
+STR_7042_NONE :{WHITE}Ziadne
+STR_7043_FACE_SELECTION :{WHITE}Vyber tvare
+STR_7044_MALE :{BLACK}Muz
+STR_7045_FEMALE :{BLACK}Zena
+STR_7046_NEW_FACE :{BLACK}Nová tvár
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Zrusit vyber novej tvare
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Potvrdit vyber tvare
+STR_7049_SELECT_MALE_FACES :{BLACK}Vyber muzskych tvari
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Vyber zenskych tvari
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Nahodna nova tvar
+STR_704C_KEY :{BLACK}Vyb.
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Vybrat polozky na grafe
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Vyber poloziek na grafe
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Kliknut pre zobrazenie tejto polozky na grafe
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Dopravenych jednotiek nakladu
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Hodnotenie produktivity spolocnosti (maximalna produktivita je 1000)
+STR_7052_COMPANY_VALUES :{WHITE}Hodnota spolocnosti
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Hodnotenie spolocnosti
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}Dopravna spolocnost ma problemy!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} bude predana alebo vyhlasi bankrot pokial coskoro nezvysi produktivitu!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(Prezident)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Dopravne spolocnosti sa zlucili!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} bola predana {COMPANY} za {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Hladame zaujemcu na kupu nasej spolocnosti{}{}Chcete kupit nasu spolocnost {COMPANY} za {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Bankrot!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} bola zavreta veritelmi a cely majetok bol rozpredany!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}Zalozena nova dopravna spolocnost!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} zacina stavat nedaleko mesta {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Spolocnost nie je mozne kupit ...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Ceny prepravy
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Pocet dni transportu
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Platba za prepravenie 10 jednotiek (alebo 10,000 litrov) nakladu cez 20 stvorcov terenu
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Graf pre typ nakladu zap./vyp.
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Inzinier
+STR_7067_TRAFFIC_MANAGER :Manazer dopravy
+STR_7068_TRANSPORT_COORDINATOR :Koordinator dopravy
+STR_7069_ROUTE_SUPERVISOR :Cestny inspektor
+STR_706A_DIRECTOR :Riaditel
+STR_706B_CHIEF_EXECUTIVE :Vykonny riaditel
+STR_706C_CHAIRMAN :Predseda
+STR_706D_PRESIDENT :Prezident
+STR_706E_TYCOON :Tycoon
+STR_706F_BUILD_HQ :{BLACK}Postavit sidlo
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Postavit sidlo spolocnosti / pozriet sidlo spolocnosti
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Sidlo spolocnosti je mozne premiestnit za 1% hodnoty spolocnosti
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Sidlo spolocnosti sa neda postavit ...
+STR_7072_VIEW_HQ :{BLACK}Pozriet sidlo
+STR_RELOCATE_HQ :{BLACK}Premiestnit sidlo
+STR_COMPANY_PASSWORD :{BLACK}Heslo
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Heslo-ochrana vasej spolocnosti proti neautorizovanemu pripojeniu hracov
+STR_SET_COMPANY_PASSWORD :Nastavte heslo spolocnosti
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}Svetova kriza!{}{}Financni experti maju obavy z prepadu ekonomiky!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Koniec krizy!{}{}Ocakava sa vzostup predaja a posilnenie ekonomiky!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Prepnut velkost okna
+STR_7076_COMPANY_VALUE :{GOLD}Hodnota spolocnosti: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Kupit 25% podiel v spolocnosti
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Predat 25% podiel v spolocnosti
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Kupit 25% podiel v tejto spolocnosti
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Predat 25% podiel v tejto spolocnosti
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}25% podiel v tejto spolocnosti sa neda kupit ...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}25% podiel v tejto spolocnosti sa neda predat ...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% vlastnene {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% vlastnene {COMPANY}{} {COMMA}% vlastnene {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} bola kupena spolocnostou {COMPANY}!
+STR_7080_PROTECTED :{WHITE}S akciami tejto spolocnosti nie je zatial mozne obchodovat ...
+
+STR_LIVERY_DEFAULT :Standardna schema
+STR_LIVERY_STEAM :Parny rusen
+STR_LIVERY_DIESEL :Dieslovy rusen
+STR_LIVERY_ELECTRIC :Elektricky rusen
+STR_LIVERY_MONORAIL :Rusen pre Monorail
+STR_LIVERY_MAGLEV :Rusen pre MagLev
+STR_LIVERY_DMU :DMU
+STR_LIVERY_EMU :EMU
+STR_LIVERY_PASSENGER_WAGON_STEAM :Osobny vozen (Parny)
+STR_LIVERY_PASSENGER_WAGON_DIESEL :Osobny vozen (Diesel)
+STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Osobny vozen (Elektricky)
+STR_LIVERY_FREIGHT_WAGON :Nakladny vagon
+STR_LIVERY_BUS :Autobus
+STR_LIVERY_TRUCK :Nakladny automobil
+STR_LIVERY_PASSENGER_SHIP :Trajekt pre cestujucich
+STR_LIVERY_FREIGHT_SHIP :Nakladna lod
+STR_LIVERY_HELICOPTER :Helikoptera
+STR_LIVERY_SMALL_PLANE :Male lietadlo
+STR_LIVERY_LARGE_PLANE :Velke lietadlo
+
+STR_LIVERY_GENERAL_TIP :{BLACK}Zobrazit všeobecné farebné schémy
+STR_LIVERY_TRAIN_TIP :{BLACK}Zobrazit farebné schémy pre vlaky
+STR_LIVERY_ROADVEH_TIP :{BLACK}Zobrazit farebné schémy pre cestné vozidlá
+STR_LIVERY_SHIP_TIP :{BLACK}Zobrazit farebné schémy pre lode
+STR_LIVERY_AIRCRAFT_TIP :{BLACK}Zobrazit farebné schémy pre lietadlá
+STR_LIVERY_PRIMARY_TIP :{BLACK}Vyberte primárnu farbu pre vybranú farebnú schému
+STR_LIVERY_SECONDARY_TIP :{BLACK}Vybrat sekundárnu farbu pre vybranú farebnú schému
+STR_LIVERY_PANEL_TIP :{BLACK}Vybrat farebnú schému na zmenenie (pre viacero schém použite CTRL+klik). Kliknite na štvorec pre prepnutie používania schémy
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (Parny)
+STR_8001_MJS_250_DIESEL :MJS 250 (Diesel)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut Diesel
+STR_8006_POWERNAUT_DIESEL :Powernaut Diesel
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (Parny)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (Parny)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (Parny)
+STR_800A_SH_8P_STEAM :SH '8P' (Parny)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (Diesel)
+STR_800C_DASH_DIESEL :'Dash' (Diesel)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (Diesel)
+STR_800E_UU_37_DIESEL :UU '37' (Diesel)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (Diesel)
+STR_8010_CS_4000_DIESEL :CS 4000 (Diesel)
+STR_8011_CS_2400_DIESEL :CS 2400 (Diesel)
+STR_8012_CENTENNIAL_DIESEL :Centennial (Diesel)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (Diesel)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (Diesel)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (Diesel)
+STR_8016_SH_125_DIESEL :SH '125' (Diesel)
+STR_8017_SH_30_ELECTRIC :SH '30' (Elektricky)
+STR_8018_SH_40_ELECTRIC :SH '40' (Elektricky)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (Elektricky)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (Elektricky)
+STR_801B_PASSENGER_CAR :Vagon pre cestujucich
+STR_801C_MAIL_VAN :Postovy vagon
+STR_801D_COAL_CAR :Vagon na uhlie
+STR_801E_OIL_TANKER :Vagon na ropu
+STR_801F_LIVESTOCK_VAN :Vagon na dobytok
+STR_8020_GOODS_VAN :Vagon na tovar
+STR_8021_GRAIN_HOPPER :Vagon na obilie
+STR_8022_WOOD_TRUCK :Vagon na drevo
+STR_8023_IRON_ORE_HOPPER :Vagon na zeleznu rudu
+STR_8024_STEEL_TRUCK :Vagon na ocel
+STR_8025_ARMORED_VAN :Obrneny vagon
+STR_8026_FOOD_VAN :Vagon na jedlo
+STR_8027_PAPER_TRUCK :Vagon na papier
+STR_8028_COPPER_ORE_HOPPER :Vagon na medennu rudu
+STR_8029_WATER_TANKER :Vagon na vodu
+STR_802A_FRUIT_TRUCK :Vagon na ovocie
+STR_802B_RUBBER_TRUCK :Vagon na kaucuk
+STR_802C_SUGAR_TRUCK :Vagon na cukor
+STR_802D_COTTON_CANDY_HOPPER :Vagon na cukrovu vatu
+STR_802E_TOFFEE_HOPPER :Vagon na karamel
+STR_802F_BUBBLE_VAN :Vagon na bubliny
+STR_8030_COLA_TANKER :Vagon na kofolu
+STR_8031_CANDY_VAN :Vagon na cukriky
+STR_8032_TOY_VAN :Vagon na hracky
+STR_8033_BATTERY_TRUCK :Vagon na baterie
+STR_8034_FIZZY_DRINK_TRUCK :Vagon na sumienku
+STR_8035_PLASTIC_TRUCK :Vagon na zuvacky
+STR_8036_X2001_ELECTRIC :'X2001' (Elektricky)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Elektricky)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :Vagon pre cestujucich
+STR_803A_MAIL_VAN :Postovy vagon
+STR_803B_COAL_CAR :Vagon na uhlie
+STR_803C_OIL_TANKER :Vagon na ropu
+STR_803D_LIVESTOCK_VAN :Vagon na dobytok
+STR_803E_GOODS_VAN :Vagon na tovar
+STR_803F_GRAIN_HOPPER :Vagon na obilie
+STR_8040_WOOD_TRUCK :Vagon na drevo
+STR_8041_IRON_ORE_HOPPER :Vagon na zeleznu rudu
+STR_8042_STEEL_TRUCK :Vagon na ocel
+STR_8043_ARMORED_VAN :Obrneny vagon
+STR_8044_FOOD_VAN :Vagon na jedlo
+STR_8045_PAPER_TRUCK :Vagon na papier
+STR_8046_COPPER_ORE_HOPPER :Vagon na medennu rudu
+STR_8047_WATER_TANKER :Vagon na vodu
+STR_8048_FRUIT_TRUCK :Vagon na ovocie
+STR_8049_RUBBER_TRUCK :Vagon na kaucuk
+STR_804A_SUGAR_TRUCK :Vagon na cukor
+STR_804B_COTTON_CANDY_HOPPER :Vagon na cukrovu vatu
+STR_804C_TOFFEE_HOPPER :Vagon na karamel
+STR_804D_BUBBLE_VAN :Vagon na bubliny
+STR_804E_COLA_TANKER :Vagon na kofolu
+STR_804F_CANDY_VAN :Vagon na cukriky
+STR_8050_TOY_VAN :Vagon na hracky
+STR_8051_BATTERY_TRUCK :Vagon na baterie
+STR_8052_FIZZY_DRINK_TRUCK :Vagon na sumienku
+STR_8053_PLASTIC_TRUCK :Vagon na zuvacky
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (Elektricky)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (Elektricky)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (Elektricky)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (Elektricky)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :Vagon pre cestujucich
+STR_805A_MAIL_VAN :Postovy vagon
+STR_805B_COAL_CAR :Vagon na uhlie
+STR_805C_OIL_TANKER :Vagon na ropu
+STR_805D_LIVESTOCK_VAN :Vagon na dobytok
+STR_805E_GOODS_VAN :Vagon na tovar
+STR_805F_GRAIN_HOPPER :Vagon na obilie
+STR_8060_WOOD_TRUCK :Vagon na drevo
+STR_8061_IRON_ORE_HOPPER :Vagon na zeleznu rudu
+STR_8062_STEEL_TRUCK :Vagon na ocel
+STR_8063_ARMORED_VAN :Obrneny vagon
+STR_8064_FOOD_VAN :Vagon na jedlo
+STR_8065_PAPER_TRUCK :Vagon na papier
+STR_8066_COPPER_ORE_HOPPER :Vagon na medennu rudu
+STR_8067_WATER_TANKER :Vagon na vodu
+STR_8068_FRUIT_TRUCK :Vagon na ovocie
+STR_8069_RUBBER_TRUCK :Vagon na kaucuk
+STR_806A_SUGAR_TRUCK :Vagon na cukor
+STR_806B_COTTON_CANDY_HOPPER :Vagon na cukrovu vatu
+STR_806C_TOFFEE_HOPPER :Vagon na karamel
+STR_806D_BUBBLE_VAN :Vagon na bubliny
+STR_806E_COLA_TANKER :Vagon na kofolu
+STR_806F_CANDY_VAN :Vagon na cukriky
+STR_8070_TOY_VAN :Vagon na hracky
+STR_8071_BATTERY_TRUCK :Vagon na baterie
+STR_8072_FIZZY_DRINK_TRUCK :Vagon na sumienku
+STR_8073_PLASTIC_TRUCK :Vagon na zuvacky
+STR_8074_MPS_REGAL_BUS :MPS Regal Autobus
+STR_8075_HEREFORD_LEOPARD_BUS :Hereford Leopard Autobus
+STR_8076_FOSTER_BUS :Foster Autobus
+STR_8077_FOSTER_MKII_SUPERBUS :Foster MkII Autobus
+STR_8078_PLODDYPHUT_MKI_BUS :Ploddyphut MkI Autobus
+STR_8079_PLODDYPHUT_MKII_BUS :Ploddyphut MkII Autobus
+STR_807A_PLODDYPHUT_MKIII_BUS :Ploddyphut MkIII Autobus
+STR_807B_BALOGH_COAL_TRUCK :Balogh - Uhlie
+STR_807C_UHL_COAL_TRUCK :Uhl - Uhlie
+STR_807D_DW_COAL_TRUCK :DW - Uhlie
+STR_807E_MPS_MAIL_TRUCK :MPS - Posta
+STR_807F_REYNARD_MAIL_TRUCK :Reynard - Posta
+STR_8080_PERRY_MAIL_TRUCK :Perry - Posta
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :MightyMover - Posta
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Powernaught - Posta
+STR_8083_WIZZOWOW_MAIL_TRUCK :Wizzowow - Posta
+STR_8084_WITCOMBE_OIL_TANKER :Witcombe - Ropa
+STR_8085_FOSTER_OIL_TANKER :Foster - Ropa
+STR_8086_PERRY_OIL_TANKER :Perry - Ropa
+STR_8087_TALBOTT_LIVESTOCK_VAN :Talbott - Dobytok
+STR_8088_UHL_LIVESTOCK_VAN :Uhl - Dobytok
+STR_8089_FOSTER_LIVESTOCK_VAN :Foster - Dobytok
+STR_808A_BALOGH_GOODS_TRUCK :Balogh - Tovar
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Craighead - Tovar
+STR_808C_GOSS_GOODS_TRUCK :Goss - Tovar
+STR_808D_HEREFORD_GRAIN_TRUCK :Hereford - Obilie
+STR_808E_THOMAS_GRAIN_TRUCK :Thomas - Obilie
+STR_808F_GOSS_GRAIN_TRUCK :Goss - Obilie
+STR_8090_WITCOMBE_WOOD_TRUCK :Witcombe - Drevo
+STR_8091_FOSTER_WOOD_TRUCK :Foster - Drevo
+STR_8092_MORELAND_WOOD_TRUCK :Moreland - Drevo
+STR_8093_MPS_IRON_ORE_TRUCK :MPS - Zelezna ruda
+STR_8094_UHL_IRON_ORE_TRUCK :Uhl - Zelezna ruda
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Chippy - Zelezna ruda
+STR_8096_BALOGH_STEEL_TRUCK :Balogh - Ocel
+STR_8097_UHL_STEEL_TRUCK :Uhl - Ocel
+STR_8098_KELLING_STEEL_TRUCK :Kelling - Ocel
+STR_8099_BALOGH_ARMORED_TRUCK :Balogh - Obrnene vozidlo
+STR_809A_UHL_ARMORED_TRUCK :Uhl - Obrnene vozidlo
+STR_809B_FOSTER_ARMORED_TRUCK :Foster - Obrnene vozidlo
+STR_809C_FOSTER_FOOD_VAN :Foster - Jedlo
+STR_809D_PERRY_FOOD_VAN :Perry - Jedlo
+STR_809E_CHIPPY_FOOD_VAN :Chippy - Jedlo
+STR_809F_UHL_PAPER_TRUCK :Uhl - Papier
+STR_80A0_BALOGH_PAPER_TRUCK :Balogh - Papier
+STR_80A1_MPS_PAPER_TRUCK :MPS - Papier
+STR_80A2_MPS_COPPER_ORE_TRUCK :MPS - Medenna ruda
+STR_80A3_UHL_COPPER_ORE_TRUCK :Uhl - Medenna ruda
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Goss - Medenna ruda
+STR_80A5_UHL_WATER_TANKER :Uhl - Voda
+STR_80A6_BALOGH_WATER_TANKER :Balogh - Voda
+STR_80A7_MPS_WATER_TANKER :MPS - Voda
+STR_80A8_BALOGH_FRUIT_TRUCK :Balogh - Ovocie
+STR_80A9_UHL_FRUIT_TRUCK :Uhl - Ovocie
+STR_80AA_KELLING_FRUIT_TRUCK :Kelling - Ovocie
+STR_80AB_BALOGH_RUBBER_TRUCK :Balogh - Kaucuk
+STR_80AC_UHL_RUBBER_TRUCK :Uhl - Kaucuk
+STR_80AD_RMT_RUBBER_TRUCK :RMT - Kaucuk
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :MightyMover - Cukor
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Powernaught - Cukor
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Wizzowow - Cukor
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :MightyMover - Kofola
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Powernaught - Kofola
+STR_80B3_WIZZOWOW_COLA_TRUCK :Wizzowow - Kofola
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :MightyMover - Cukrova vata
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Powernaught - Cukrova vata
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Wizzowow - Cukrova vata
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :MightyMover - Karamel
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Powernaught - Karamel
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Wizzowow - Karamel
+STR_80BA_MIGHTYMOVER_TOY_VAN :MightyMover - Hracky
+STR_80BB_POWERNAUGHT_TOY_VAN :Powernaught - Hracky
+STR_80BC_WIZZOWOW_TOY_VAN :Wizzowow - Hracky
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :MightyMover - Cukriky
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Powernaught - Cukriky
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Wizzowow - Cukriky
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :MightyMover - Baterie
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Powernaught - Baterie
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Wizzowow - Baterie
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :MightyMover - Sumienka
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Powernaught - Sumienka
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Wizzowow - Sumienka
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :MightyMover - Zuvacky
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Powernaught - Zuvacky
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Wizzowow - Zuvacky
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :MightyMover - Bubliny
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Powernaught - Bubliny
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Wizzowow - Bubliny
+STR_80CC_MPS_OIL_TANKER :MPS - Ropa
+STR_80CD_CS_INC_OIL_TANKER :CS-Inc. - Ropa
+STR_80CE_MPS_PASSENGER_FERRY :MPS Trajekt
+STR_80CF_FFP_PASSENGER_FERRY :FFP Trajekt
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Bakewell 300 Vznasadlo
+STR_80D1_CHUGGER_CHUG_PASSENGER :Chugger-Chug Trajekt
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Shivershake Trajekt
+STR_80D3_YATE_CARGO_SHIP :Yate Nakladna lod
+STR_80D4_BAKEWELL_CARGO_SHIP :Bakewell Nakladna lod
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Mightymover Nakladna lod
+STR_80D6_POWERNAUT_CARGO_SHIP :Powernaut Nakladna lod
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Tricario Helicopter
+STR_80FE_GURU_X2_HELICOPTER :Guru X2 Helicopter
+STR_80FF_POWERNAUT_HELICOPTER :Powernaut Helicopter
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Sprava od vyrobcu dopravnych prostriedkov
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}Prave sme vyrobili {STRING} - mate zaujem o pravo exkluzivneho pouzivania na 1 rok? Chceme otestovat vlastnosti tohto vyrobku pred jeho uvedenim na trh.
+STR_8102_RAILROAD_LOCOMOTIVE :zeleznicna lokomotiva
+STR_8103_ROAD_VEHICLE :automobil
+STR_8104_AIRCRAFT :lietadlo
+STR_8105_SHIP :lod
+STR_8106_MONORAIL_LOCOMOTIVE :jednokolajova lokomotiva
+STR_8107_MAGLEV_LOCOMOTIVE :magneticka lokomotiva
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}{TOWN} Depo
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Mesto oslavuje . . .{}Prvy vlak dorazil do stanice {STATION}!
+STR_8802_DETAILS :{WHITE}{STRING} (Detaily)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Vlak v ceste
+STR_8804 :{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8806_GO_TO :Chod do {STATION}
+STR_8807_GO_TO_TRANSFER :Chod do {STATION} (prelozit a nalozit iny naklad)
+STR_8808_GO_TO_UNLOAD :Chod do {STATION} (vylozit)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Chod do {STATION} (prelozit a nechat prazdne)
+STR_880A_GO_TO_LOAD :Chod do {STATION} (nalozit)
+STR_880B_GO_TO_TRANSFER_LOAD :Chod do {STATION} (prelozit a plne nalozit)
+STR_880C_GO_NON_STOP_TO :Chod bez zastavenia do {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Chod bez zastavenia do {STATION} (prelozit a nalozit iny naklad)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Chod bez zastavenia do {STATION} (vylozit)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Chod bez zastavenia do {STATION} (prelozit a nechat prazdne)
+STR_8810_GO_NON_STOP_TO_LOAD :Chod bez zastavenia do {STATION} (nalozit)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Chod bez zastavenia do {STATION} (prelozit a plne nalozit)
+STR_GO_TO_TRAIN_DEPOT :Chod do depa {TOWN}
+STR_SERVICE_AT_TRAIN_DEPOT :Opravit v {TOWN} Vlakovom Depe
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Chod bez zastavenia do depa {TOWN}
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Opravovat bez zastavenia v depe {TOWN}
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}Smeruje do {TOWN} depa
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}Smeruje do {TOWN} depa, {VELOCITY}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE :{LTBLUE}Servis v depe {TOWN}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE_VEL :{LTBLUE}Servis v depe {TOWN}, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (Neplatny prikaz)
+
+STR_UNKNOWN_DESTINATION :neznamy ciel
+STR_8812_EMPTY :{LTBLUE}Prazdny
+STR_8813_FROM :{LTBLUE}{CARGO} z {STATION}
+STR_FROM_MULT :{LTBLUE}{CARGO} from {STATION} (x{NUM})
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}Vlak {COMMA} caka v depe
+STR_8815_NEW_VEHICLES :{BLACK}Nove vozidla
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Vlak je prilis dlhy
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Vlaky sa daju nahradit len v depe
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} Vlak{P "" y ov}
+
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Nove vlaky
+STR_NEW_ELRAIL_VEHICLES :{WHITE}Nové elektrické lokomotívy a vagóny
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Nove jednokolajove vlaky
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Nove magneticke vlaky
+STR_ALL_AVAIL_RAIL_VEHICLES :{WHITE}Železnicne vozidlá
+
+STR_881F_BUILD_VEHICLE :{BLACK}Zakupit vozidlo
+STR_CLONE_ROAD_VEHICLE :{BLACK}Klonovat vozidlo
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}Vytvori kopiu cestneho vozidla. Stlacenim Control budu prikazy zdielane
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Vytvori kopiu cestneho vozidla. Klikni na toto tlacidlo a potom na vozidlo v garazi alebo mimo nej. Stlacenim Control budu prikazy zdielane
+STR_CLONE_TRAIN :{BLACK}Klonovat vlak
+STR_CLONE_TRAIN_INFO :{BLACK}Vytvori kopiu vlaku vratane voznov. Stlacenim Control budu prikazy zdielane
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}Vytvori kopiu vlaku vratane voznov. Klikni na toto tlacidlo a potom na vlak v depe alebo mimo neho. Stlacenim Control budu prikazy zdielane
+STR_8820_RENAME :{BLACK}Premenovat
+STR_8823_SKIP :{BLACK}Preskocit
+STR_8824_DELETE :{BLACK}Vynechat
+STR_8825_NON_STOP :{BLACK}Non-Stop
+STR_8826_GO_TO :{BLACK}Chod do
+STR_8827_FULL_LOAD :{BLACK}Plne naloz
+STR_8828_UNLOAD :{BLACK}Vylozit
+STR_REFIT :{BLACK}Prestavba
+STR_REFIT_TIP :{BLACK}Vyberte typ nákladu na prestavbu v tomto poradí. CTRL+klik na odstránenie príkazu prestavby
+STR_REFIT_ORDER :(Prestavba na {STRING})
+STR_8829_ORDERS :{WHITE}{VEHICLE} (Prikazy)
+STR_882A_END_OF_ORDERS :{SETX 10}- - Koniec prikazov - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}Oprava
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Nemozno kupit vlak...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Vyrobene: {LTBLUE}{NUM}{BLACK} cena: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Hodnota: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}Naklada/Vyklada
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}Vlak musi byt zastaveny v depe
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Vlak sa neda poslat do depa...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Nemozno zadat dalsie prikazy
+STR_8832_TOO_MANY_ORDERS :{WHITE}Prilis vela prikazov
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Nemozno vlozit novy prikaz...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Nemozno vymazat tebnto prikaz ...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Nemozno zmenit tento prikaz ...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Nemozno posuvat vozdlo ...
+STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}Zadný stroj vždy doprevádza svoj druhý stroj vpredu
+STR_8838_N_A :Nie je{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Nemozno predat automobil ...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Nemoze najst cestu do depa
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Nemozno zastavit/spustit vlak ...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Servisny interval: {LTBLUE}{COMMA}dni{BLACK} Posledny servis: {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Servisny interval: {LTBLUE}{COMMA}%{BLACK} Posledny servis: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Vlaky - kliknut na vlak pre informacie
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Kupit nove vlaky (potrebne depo)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Vlaky - kliknut na vlak pre informacie, potiahni pre zmenu pozicie
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Kupit novy vlak
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Pre predaj vlaku ho potiahni sem
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Vycentrovat pohlad na poziciu depa
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Vyber vlakov - kliknut na vlak pre informacie
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Kupit vybrany vlak
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Premenovat vlak
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Aktualna cinnost vlaku - kliknut pre zastavenie/spustenie
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Zobrazit cestovne prikazy vlakov
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Vycentrovat pohlad na poziciu vlaku
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Poslat vlak do depa
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Poslat vlak na cervenu
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Obratit vlak
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Zobrazit detaily o vlaku
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Predlzit servisny interval
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Skratit servisny interval
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Zobrazit detaily o prevezenom naklade
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Zobrazit detaily o vlaku
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Zobrazit kapacitu kazdeho vozidla
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Zobrazit celkovu kapacitu vlaku, rozdelenu podla typu nakladu
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Zoznam prikazov - kliknut na prikaz pre oznacenie
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}Vynechat aktualny prikaz - preskocit na dalsi
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Vymazat oznaceny prikaz
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Oznaceny prikaz bude prevedeny bez zastavenia
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Vlozit novy prikaz pred oznaceny prikaz, alebo na koniec zoznamu
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Na oznacenom prikaze bude vozidlo cakat na plne nalozenie
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Na oznacenom prikaze bude vozidlo uplne vylozene
+STR_SERVICE_HINT :{BLACK}Vynechat tento prikaz pokial nie je potrebna oprava
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}Nove {STRING} je uz dostupne!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Cena: {CURRENCY} Nosnost: {WEIGHT_S}{}Rychlost: {VELOCITY} Vykon: {POWER}{}Naklady na prevadzku: {CURRENCY}/rok{}Kapacita: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}Pokazene
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}Vek: {LTBLUE}{STRING}{BLACK} Naklady na prevadzku: {LTBLUE}{CURRENCY}/rok
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Nosnost: {LTBLUE}{WEIGHT_S} {BLACK}Vykon: {LTBLUE}{POWER}{BLACK} Max. rychlost: {LTBLUE}{VELOCITY}
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Hmotnost: {LTBLUE}{WEIGHT_S} {BLACK}Výkon: {LTBLUE}{POWER}{BLACK} Max. rýchlost: {LTBLUE}{VELOCITY} {BLACK}Max. T.S.: {LTBLUE}{FORCE}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Zisk tento rok: {LTBLUE}{CURRENCY} (predchadzajuci rok: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}Spolahlivost: {LTBLUE}{COMMA}% {BLACK}Pocet poruch od posledneho servisu: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Zastavene
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Nemozno pustit vlak na cervenu ked hrozi nebezpecenstvo...
+STR_8863_CRASHED :{RED}Znicene!
+
+STR_8865_NAME_TRAIN :{WHITE}Pomenovat vlak
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}Vlak nemozno pomenovat ...
+STR_8867_NAME_TRAIN :{BLACK}Pomenovat vlak
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Vlakove nestastie!{}{COMMA} mrtv{P i i ych} pri poziari po kolizii
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Nemozno zmenit smer vlaku ...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Premenovat typ vlaku
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Typ vlaku nemoze byt premenovany ...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}U vyznaceneho prikazu musi vozidlo vylozit naklad
+STR_886F_TRANSFER :{BLACK}Prekladka
+
+STR_TRAIN_STOPPING :{RED}Zastavuje
+STR_TRAIN_STOPPING_VEL :{RED}Zastavuje, {VELOCITY}
+STR_INCOMPATIBLE_RAIL_TYPES :Nekompatibilne typy kolaji
+STR_TRAIN_NO_POWER :{RED}Nie je prud
+STR_TRAIN_START_NO_CATENARY :Vlak nemoze nastartovat, pretoze trat nie je pripojena
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Automobil v ceste
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} Automobil{P "" y ov}
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}{TOWN} Garaz
+STR_9004_NEW_VEHICLES :{BLACK}Nove vozidla
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}Nove automobily
+STR_9007_BUILD_VEHICLE :{BLACK}Zakupit vozidlo
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Nie je mozne zakupit automobil ...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (Detaily)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}Vek: {LTBLUE}{STRING}{BLACK} Naklady na prevadzku: {LTBLUE}{CURRENCY}/rok
+STR_900E_MAX_SPEED :{BLACK}Max. rychlost: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Zisk tento rok: {LTBLUE}{CURRENCY} (posledny rok: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}Spolahlivost: {LTBLUE}{COMMA}% {BLACK}Pocet poruch od posledneho servisu: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Vyrobene: {LTBLUE}{NUM}{BLACK} Hodnota: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Kapacita: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}... musi byt zastaveny v garazi
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Nemozno predat automobil ...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Nemozno zastavit/spustit automobil ...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}Automobil {COMMA} caka v garazi
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}Smeruje do {TOWN} garaze
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}smeruje do {TOWN} garaze, {VELOCITY}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE :{LTBLUE}Servis v garazi {TOWN}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE_VEL :{LTBLUE}Servis v garazi {TOWN}, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Nemozno poslat automobil do garaze ...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Nemozno najst miestnu garaz
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Automobily - kliknut pre detaily
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Zakupit novy automobil (potrebna garaz)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Aktualna cinnost vozidla - kliknut pre zastavenie/spustenie
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Zobrazit cestovne prikazy
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Vycentrovat pohlad na vozidlo
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Poslat vozidlo do depa
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Otocit vozidlo
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Zobrazit detaily o automobile
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Vozidla - kliknut pre detaily
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Zakupit novy automobil
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Potiahni sem pre predaj automobilu
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Centrovat pohlad na poziciu garaze
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Vyber vozidiel - kliknut pre detaily
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Zakupit vybrany automobil
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}Novy automobil dostupny!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Cena: {CURRENCY}{}Rychlost: {VELOCITY}{}Naklady na prevadzku: {CURRENCY}/rok{}Kapacita: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Pomenovat automobil
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Nemozno pomenovat automobil ...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Pomenovat automobil
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Mesto oslavuje . . .{}Prvy autobus dorazil do {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Mesto oslavuje . . .{}Prvy automobil dorazil do {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}Dopravna nehoda!{}Vodic zahynul po kolizii s vlakom
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}Dopravna nehoda!{}{COMMA} mrtvych po kolizii s vlakom
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Nemozno otocit vozidlo ...
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}Nie je mozne otacat vozidla zlozené z viacerych jednotiek
+STR_9034_RENAME :{BLACK}Premenovat
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Premenovat typ automobilu
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Premenovat typ automobilu
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Nemozno premenovat typ automobilu ...
+STR_9038_GO_TO_ROADVEH_DEPOT :Chod do {TOWN} garaze
+STR_SERVICE_AT_ROADVEH_DEPOT :Opravit v {TOWN} garazi
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Prestavat vozidlo na prepravu ineho druhu nakladu
+STR_REFIT_ROAD_VEHICLE :{BLACK}Prestavat vozidlo
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Prestavat vozidlo na prepravu vyznaceneho druhu nakladu
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Prestavba vozidla nie je mozna ...
+STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Vyberte požadovaný typ nákladu pre cestné vozidlo
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Stavba pristavu
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Stavba pristavu
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Tu nemozno postavit pristav ...
+STR_9803_SHIP_DEPOT :{WHITE}{TOWN} Lodenica
+STR_9804_NEW_SHIPS :{BLACK}Nove lode
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} Lod{P "" e i}
+STR_9808_NEW_SHIPS :{WHITE}Nove lode
+STR_9809_BUILD_SHIP :{BLACK}Vyrobit lod
+STR_CLONE_SHIP :{BLACK}Klonovat lod
+STR_CLONE_SHIP_INFO :{BLACK}Vytvori kopiu lode. Stlacenim Control budu prikazy zdielane
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}Vytvori kopiu lode. Klikni na toto tlacidlo a potom na lod v depe alebo mimo neho. Stlacenim Control budu prikazy zdielane
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}Lod musi byt zastavena v lodenici
+STR_980C_CAN_T_SELL_SHIP :{WHITE}Nemozno predat lod ...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Nemozno vyrobit lod...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Lod v ceste
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Detaily)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}Vek: {LTBLUE}{STRING}{BLACK} Naklady na prevadzku: {LTBLUE}{CURRENCY}/rok
+STR_9813_MAX_SPEED :{BLACK}Max. rychlost: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Zisk tento rok: {LTBLUE}{CURRENCY} (posledny rok: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}Spolahlivost: {LTBLUE}{COMMA}% {BLACK}Pocet poruch od posledneho servisu: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Vyrobene: {LTBLUE}{NUM}{BLACK} Hodnota: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}Kapacita: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}Nemozno zastavit/spustit lod ...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Nemozno poslat lod do lodenice ...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Nemozno najst miestnu lodenicu
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}Smeruje do {TOWN} lodenice
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}Smeruje do {TOWN} lodenice, {VELOCITY}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE :{LTBLUE}Servis v lodenici {TOWN}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE_VEL :{LTBLUE}Servis v lodenici {TOWN}, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}Lod {COMMA} caka v lodenici
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Postavit lodenicu
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Postavit lodenicu (pre vyrobu a opravy lodi)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Lode - kliknut pre informacie
+STR_9820_BUILD_NEW_SHIP :{BLACK}Vyrobit novu lod
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Potiahnut lod sem, na predaj
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Vycentrovat pohlad na lodenicu
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Lode - kliknut pre informacie
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Vyrobit nove lode (potrebna lodenica)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}Vyber lodi - kliknut pre informacie
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Vyrobit vybranu lod
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Atualna cinnost lode - klini pre zastavenie/spustenie
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Zobrazit cestovne prikazy lodi
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Vycentrovat pohlad na lod
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Poslat lod do lodenice
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Zobrazit detaily o lodi
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}Nová lod je dostupná!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Cena: {CURRENCY} Max. rychlost: {VELOCITY}{}Kapacita: {CARGO}{}Naklady na prevadzku: {CURRENCY}/rok
+STR_982F_NAME_SHIP :{BLACK}Pomenovat lod
+
+STR_9831_NAME_SHIP :{WHITE}Pomenovat lod
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Nemozno pomenovat lod ...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Mesto oslavuje . . .{}Prva lod dorazila do {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Postavit boju pouzitelnu pre vyznacenie trasy
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Tu nemozno postavit boju ...
+STR_9836_RENAME :{BLACK}Premenovat
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Premenovat typ lode
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Premenovat typ lode
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Nemozno premenovat typ lode ...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Prestavat lod na iny typ nakladu
+STR_983B_REFIT :{WHITE}{VEHICLE} (Prestavat)
+STR_983C_REFIT_SHIP :{BLACK}Prestavat lod
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Vybrat typ nakladu pre lod
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Prestavat lod na vybrany typ nakladu
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Vyber typ nakladu:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nová kapacita: {GOLD}{CARGO}{}{BLACK}Cena prestavby: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Nemozno prestavat lod...
+STR_9842_REFITTABLE :(mozna prestavba)
+STR_GO_TO_SHIP_DEPOT :Chod do {TOWN} Lodenice
+SERVICE_AT_SHIP_DEPOT :Opravit v {TOWN} Lodenici
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Letiska
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Tu sa letisko neda postavit ...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} Hangar
+STR_A003_NEW_AIRCRAFT :{BLACK}Nove Lietadlo
+STR_CLONE_AIRCRAFT :{BLACK}Klonovat lietadlo
+STR_CLONE_AIRCRAFT_INFO :{BLACK}Vytvori kopiu lietadla. Stlacenim Control budu prikazy zdielane
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Vytvori kopiu lietadla. Klikni na toto tlacidlo a potom na lietadlo v hangari alebo mimo neho. Stlacenim Control budu prikazy zdielane
+STR_A005_NEW_AIRCRAFT :{WHITE}Nove Lietadlo
+STR_A006_BUILD_AIRCRAFT :{BLACK}Vyrobit lietadlo
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Nemozno vyrobit lietadlo...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} Lietad{P lo la iel}
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (Prikazy)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (Detaily)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Vek: {LTBLUE}{STRING}{BLACK} Naklady na prevadzku: {LTBLUE}{CURRENCY}/rok
+STR_A00E_MAX_SPEED :{BLACK}Max. rychlost: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Zisk tento rok: {LTBLUE}{CURRENCY} (posledny rok: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}Spolahlivost: {LTBLUE}{COMMA}% {BLACK}Pocet poruch od posledneho servisu: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Vyrobene: {LTBLUE}{NUM}{BLACK} Hodnota: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Nemozno poslat lietadlo do hangaru ...
+STR_HEADING_FOR_HANGAR :{ORANGE}Smeruje do {STATION} hangaru
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}Smeruje do {STATION} hangaru, {VELOCITY}
+STR_HEADING_FOR_HANGAR_SERVICE :{LTBLUE}Servis v hangari {STATION}
+STR_HEADING_FOR_HANGAR_SERVICE_VEL :{LTBLUE}Servis v hangari {STATION}, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}Lietadlo {COMMA} caka v hangare
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Lietadlo v ceste
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Nemozno zastavit/spustit lietadlo ...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Lietadlo je vo vzduchu
+STR_A019_CAPACITY :{BLACK}Kapacita: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Kapacita: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}Lietadlo musi byt zastavene v hangari
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Nie je mozne predat lietadlo ...
+STR_A01D_AIRPORT_CONSTRUCTION :Vystavba letiska
+STR_A01E_BUILD_AIRPORT :{BLACK}Postavit letisko
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Lietadlo - kliknut pre informacie
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Vyrobit nove lietadlo (potrebne letisko z hangarom)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Lietadlo - kliknut pre informacie
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Vyrobit nove lietadlo
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}Potiahni lietadlo sem pre predaj
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Vycentrovat pohlad na hangar
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Vyber lietadiel - kliknut pre vyber
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Vyrobit vybrane lietadlo
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Aktualna cinnost lietadla - klini pre zastavenie/spustenie
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Zobrazit cestovne prikazy lietadla
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Vycentrovat pohlad na lietadlo
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Poslat lietadlo do hangaru
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Zobrazit detaily o lietadle
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}Nove lietadlo dostupne!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Cena: {CURRENCY} Max. rychlost: {VELOCITY}{}Kapacita: {COMMA} cestujucich, {COMMA} balikov posty{}Naklady na prevadzku: {CURRENCY}/rok
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Pomenovat lietadlo
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Nie je mozne pomenovat lietadlo ...
+STR_A032_NAME_AIRCRAFT :{BLACK}Pomenovat lietadlo
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Mesto oslavuje . . .{}Prve lietadlo pristalo na {STATION}!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Letecke nestastie!{}{COMMA} mrtv{P y i ych} po poziari na {STATION}
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Letecke nestastie!{}Lietadlu doslo palivo, {COMMA} mrtvych pri poziari!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Premenovat
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Premenovat typ lietadla
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Premenovat typ lietadla
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Nie je mozne premenovat typ lietadla ...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Prestavat lietadlo na iny typ nakladu
+STR_A03C_REFIT :{WHITE}{VEHICLE} (Prestavat)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Prestavat lietadlo
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Vyber novy typ nakladu
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Prestavat lietadlo na novy typ nakladu
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Vybrat typ noveho nakladu:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nová kapacita: {GOLD}{STRING}{}{BLACK}Náklady na prestavbu: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Nie je mozne prestavat na novy typ nakladu ...
+STR_GO_TO_AIRPORT_HANGAR :Chod do {STATION} Hangaru
+SERVICE_AT_AIRPORT_HANGAR :Opravit v {STATION} Hangare
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}Zeppelin zniceny pri nehode na {STATION}!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Automobil bol zniceny pri kolizii s 'UFO'
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}Ropna rafineria explodovala nedaleko mesta {TOWN}!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}Za nejasnych okolnost bola znicena tovaren nedaleko mesta {TOWN}!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}'UFO' pristalo nedaleko mesta {TOWN}!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}Zaval v uholnej bani nedaleko mesta {TOWN}!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Povoden!{}Najmenej {COMMA} ludi je nezvestnych alebo mrtvych po obrovskych zaplavach!
+
+STR_BRIBE_FAILED :{WHITE}Vas pokus o uplatok bol odhaleny
+STR_BRIBE_FAILED_2 :{WHITE}miestnym vysetrovatelom.
+STR_BUILD_DATE :{BLACK}Postavene: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Detailny rating vykonu
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}Podrobne
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Vozidla:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Stanice:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Min. zisk:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Min. prijem:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Max. prijem:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Prepravene:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Naklad:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Hotovost:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Uver:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Spolu:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Pocet vozidiel (automobilov, vlakov, lodi a lietadiel).
+STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}Pocet casti stanic. Kazda cast stanice (napr. zeleznicna stanica, autobusova zastavka, letisko) je zapocitana, aj ked su spojene do jednej stanice.
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}Zisk vozidla s najnizsim prijmom (zo vsetkych vozidiel starsich ako 2 roky)
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Mnozstvo penazi zarobenych v mesiaci s najmensim ziskom v poslednych 12 kvartaloch
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Mnozstvo penazi zarobenych v mesiaci s najvacsim ziskom v poslednych 12 kvartaloch
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}Pocet jednotiek nakladu prepravenych v poslednych styroch kvartaloch.
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}Pocet druhov nakladu prepraveneho v poslednom kvartali.
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Mnozstvo penazi k dispozicii
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}Vyska uveru spolocnosti
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Celkove body z vsetkych moznych
+
+STR_NEWGRF_SETTINGS_BUTTON :{BLACK}Nastavenia NewGRF
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}Nastavenie novych grafickych suborov
+STR_NEWGRF_APPLY_CHANGES :{BLACK}Potvrdit zmeny
+STR_NEWGRF_SET_PARAMETERS :{BLACK}Nastavit parametre
+STR_NEWGRF_TIP :{BLACK}Zoznam vsetkych sad nainstalovanych novych grafik. Nastavenie zmenite kliknutim na set.
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}Nie sú nainštalované žiadne súbory s novou grafikou. Postup inštalácie nových grafík nájdete v manuály.
+STR_NEWGRF_FILENAME :{BLACK}Názov súboru: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}ID GRF: {SILVER}{STRING}
+STR_NEWGRF_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING}
+STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}Chystáte sa vykonat zmeny v spustenej hre, co može sposobit pád hry.{}Naozaj ich chcete vykonat?
+
+STR_NEWGRF_ADD :{BLACK}Pridat
+STR_NEWGRF_ADD_TIP :{BLACK}Pridat NewGRF súbor do zoznamu
+STR_NEWGRF_REMOVE :{BLACK}Odstrániť
+STR_NEWGRF_REMOVE_TIP :{BLACK}Odstrániť vybraný NewGRF súbor zo zoznamu
+STR_NEWGRF_MOVEUP :{BLACK}Vyššie
+STR_NEWGRF_MOVEUP_TIP :{BLACK}Posunút vybraný NewGRF súbor v zozname vyššie
+STR_NEWGRF_MOVEDOWN :{BLACK}Nižšie
+STR_NEWGRF_MOVEDOWN_TIP :{BLACK}Posunút vybraný NewGRF súbor v zozname nižšie
+STR_NEWGRF_FILE_TIP :{BLACK}Zoznam inštalovaných NewGRF súborov. Kliknite na súbor pre zmenu jeho parametrov.
+STR_NEWGRF_PARAMETER :{BLACK}Parametre: {SILVER}{STRING}
+STR_NEWGRF_PARAMETER_QUERY :{BLACK}Zadajte NewGRF parametre
+STR_NEWGRF_NO_INFO :{BLACK}Žiadne dostupné informácie
+
+STR_NEWGRF_ADD_CAPTION :{WHITE}Dostupné NewGRF súbory
+STR_NEWGRF_ADD_FILE :{BLACK}Pridat do výberu
+STR_NEWGRF_ADD_FILE_TIP :{BLACK}Pridat vybraný NewGRF súbor do konfigurácie
+STR_NEWGRF_RESCAN_FILES :{BLACK}Obnovit zoznam súborov
+STR_NEWGRF_RESCAN_FILES_TIP :{BLACK}Obnovit zoznam dostupných NewGRF súborov
+STR_NEWGRF_DUPLICATE_GRFID :{WHITE}Nie je možné pridat súbor: duplicitné GRF ID
+
+STR_NEWGRF_NOT_FOUND :{RED}Príslušný súbor nenájdený
+STR_NEWGRF_DISABLED :{RED}Nedostupný
+
+STR_CURRENCY_WINDOW :{WHITE}Vlastná mena
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Kurz meny: {ORANGE}{CURRENCY} = £ {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Oddelovac:
+STR_CURRENCY_PREFIX :{LTBLUE}Predpona:
+STR_CURRENCY_SUFFIX :{LTBLUE}Prípona:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Prechod na Euro: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Prechod na Euro: {ORANGE}nikdy
+STR_CURRENCY_PREVIEW :{LTBLUE}Nahlad: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Zmenit parametre vlastnej meny
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} Vlak{P "" y ov}
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} Aut{P o a ""}
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} Lietad{P lo la iel}
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} Lod{P "" e i}
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Zobrazit vsetky vlaky, ktore maju tuto stanicu v cestovnom poriadku
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Zobrazit vsetky auta, ktore maju tuto stanicu v cestovnom poriadku
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Zobrazit vsetky lietadla, ktore maju tuto stanicu v cestovnom poriadku
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Zobrazit vsetky lode, ktore maju tuto stanicu v cestovnom poriadku
+
+STR_VEH_WITH_SHARED_ORDERS_LIST :{WHITE}Zdielane prikazy {COMMA} vozid{P la iel iel}
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}Zobrazit vsetky vozidla s rovnakym zoznamom prikazov
+
+### depot strings
+STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Chystáte sa predat všetky vozidlá v depe. Ste si isý?
+
+STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP :{BLACK}Predat všetky vlaky v depe
+STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP :{BLACK}Predat všetky vozidlá v garáži
+STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP :{BLACK}Predat všetky lode v lodenici
+STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP :{BLACK}Predat všetky lietadlá v hangári
+
+STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP :{BLACK}Zobrazit zoznam všetkých vlakov, ktoré majú toto depo v zozname príkazov
+STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP :{BLACK}Zobrazit zoznam všetkých vozidiel, ktoré majú túto garáž v zozname príkazov
+STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP :{BLACK}Zobrazit zoznam všetkých lodí, ktoré majú túto lodenicu v zozname príkazov
+STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP :{BLACK}Zobrazit zoznam všetkých lietadiel, ktoré majú toto letisko v zozname príkazov
+
+STR_DEPOT_AUTOREPLACE_TRAIN_TIP :{BLACK}Automaticky nahradit všetky vlaky v depe
+STR_DEPOT_AUTOREPLACE_ROADVEH_TIP :{BLACK}Automaticky nahradit všetky vozidlá v garáži
+STR_DEPOT_AUTOREPLACE_SHIP_TIP :{BLACK}Automaticky nahradit všetky lode v lodenici
+STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP :{BLACK}Automaticky nahradit všetky lietadlá v hangári
+
+STR_VEHICLE_LIST_TRAIN_DEPOT :{BLACK}{STRING} - {COMMA} Vlak{P "" y ov}
+STR_VEHICLE_LIST_ROADVEH_DEPOT :{BLACK}{STRING} - {COMMA} Vozid{P lo lá iel}
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} Lod{P "" e í}
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} Lietad{P lo lá iel}
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}Vymena {STRING}
+STR_REPLACE_VEHICLES_START :{BLACK}Zacat vymenu vozidiel
+STR_REPLACE_VEHICLES_STOP :{BLACK}Zastavit vymenu vozidiel
+STR_NOT_REPLACING :{BLACK}Nevymiena sa
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Nie je oznacene vozidlo
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Vyber typ lokomotivy na vymenu
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Vyber typ novej lokomotivy, ktoru chces pouzit namiesto typu v zozname nalavo
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Stlac toto tlacidlo, ak nechces vymienat typ lokomotivy vybrany v lavom zozname
+STR_REPLACE_HELP_START_BUTTON :{BLACK}Stlac toto tlacidlo, ak chces zacat vymienat typ lokomotivy v lavom zozname za typ lokomotivy v pravom zozname
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Vyber typ kolajnic, pre ktore chces vymienat lokomotivy
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Zobrazenie za ktoru lokomotivu sa lokomotiva v zozname nalavo zamiena
+STR_REPLACE_HELP :{BLACK}Umoznuje vybrat typ lokomotivy, ktory sa automaticky zameni za iny typ, ak sa vlaky s takouto lokomotivou zastavia v depe
+STR_REPLACE_REMOVE_WAGON :{BLACK}Odstranenie vagonu: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Funkcia automatickeho vylepsovania vlakov moze udrzovat rovnaku dlzku vlakov odstranovanim vagonov (od zaciatku vlakov), pokial by zmena rusna vlak predlzila.
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}Vymena: {ORANGE}{SKIP}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} EXPERIMENTALNA VLASTNOST {}Prepne medzi oknami na vymenu lokomotiv a vagonov.{}Vagon sa vymeni, len ked je nový vagon schopny vozit rovnaky naklad, ako ten stary. Toto sa overuje pre kazdy vagon.
+STR_ENGINE_NOT_BUILDABLE :{WHITE}Lokomotiva sa nevyraba
+
+STR_ENGINES :Lokomotívy
+STR_WAGONS :Vagonov
+
+STR_MASS_STOP_DEPOT_TRAIN_TIP :{BLACK}Kliknite pre zastavenie všetkých vlakov v depe
+STR_MASS_STOP_DEPOT_ROADVEH_TIP :{BLACK}Kliknite pre zastavenie všetkých vozidiel v garáži
+STR_MASS_STOP_DEPOT_SHIP_TIP :{BLACK}Kliknite pre zastavenie všetkých lodí v lodenici
+STR_MASS_STOP_HANGAR_TIP :{BLACK}Kliknite pre zastavenie všetkých lietadiel v hangári
+
+STR_MASS_START_DEPOT_TRAIN_TIP :{BLACK}Kliknite pre spustenie všetkých vlakov v depe
+STR_MASS_START_DEPOT_ROADVEH_TIP :{BLACK}Kliknite pre spustenie všetkých vozidiel v garáži
+STR_MASS_START_DEPOT_SHIP_TIP :{BLACK}Kliknite pre spustenie všetkých lodí v lodenici
+STR_MASS_START_HANGAR_TIP :{BLACK}Kliknite pre spustenie všetkých lietadiel v hangári
+
+STR_MASS_STOP_LIST_TIP :{BLACK}Kliknite pre zastavenie všetkých vozidiel v zozname
+STR_MASS_START_LIST_TIP :{BLACK}Kliknite pre spustenie všetkých vozidiel v zozname
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}Zoznam popisov - {COMMA} popis{P "" y ov}
+
+STR_ORDER_REFIT_FAILED :{WHITE}Zlyhala prestavba {STRING} {COMMA}
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :Lokomotiva pre zeleznicu
+STR_ELRAIL_VEHICLES :Elektrické lokomotívy
+STR_MONORAIL_VEHICLES :Lokomotiva pre jednokolajovku
+STR_MAGLEV_VEHICLES :Lokomotiva pre magneticku drahu
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Cena: {GOLD}{CURRENCY}{BLACK} Hmotnost: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Rychlost: {GOLD}{VELOCITY}{BLACK} Vykon: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}Rychlost: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Naklady na prevadzku: {GOLD}{CURRENCY}/rok
+STR_PURCHASE_INFO_CAPACITY :{BLACK}Kapacita: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Vyrobene: {GOLD}{NUM}{BLACK} Zivotnost: {GOLD}{COMMA} rokov
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}Max. spolahlivost: {GOLD}{COMMA}%
+STR_PURCHASE_INFO_COST :{BLACK}Cena: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Hmotnost: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Cena: {GOLD}{CURRENCY}{BLACK} Rychlost: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Kapacita: {GOLD}{COMMA} cestujucich, {COMMA} balikov posty
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Pohanane vagony: {GOLD}+{POWER}{BLACK} Hmotnost: {GOLD}+{WEIGHT_S}
+STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Prestavatelne na: {GOLD}
+STR_PURCHASE_INFO_ALL_TYPES :Všetky druhy nákladu
+STR_PURCHASE_INFO_ALL_BUT :VÅ¡etko okrem {GOLD}
+STR_PURCHASE_INFO_MAX_TE :{BLACK}Max. trakcna sila: {GOLD}{FORCE}
+
+########### String for New Landscape Generator
+
+STR_GENERATE :{WHITE}Generovat
+STR_RANDOM :{BLACK}Novy kod
+STR_RANDOM_HELP :{BLACK}Zmenit nahodny kod pre generovanie terenu
+STR_WORLD_GENERATION_CAPTION :{WHITE}Generovanie krajiny
+STR_RANDOM_SEED :{BLACK}Nahodny kod:
+STR_RANDOM_SEED_HELP :{BLACK}Kliknite pre zadanie nahodneho kodu
+STR_LAND_GENERATOR :{BLACK}Generator krajiny:
+STR_TREE_PLACER :{BLACK}Generator stromov:
+STR_HEIGHTMAP_ROTATION :{BLACK}Orientacia vyskovej mapy:
+STR_TERRAIN_TYPE :{BLACK}Typ terenu:
+STR_QUANTITY_OF_SEA_LAKES :{BLACK}Mnozstvo jazier:
+STR_SMOOTHNESS :{BLACK}Clenitost:
+STR_SNOW_LINE_HEIGHT :{BLACK}Vyska linie snehu:
+STR_DATE :{BLACK}Rok:
+STR_NUMBER_OF_TOWNS :{BLACK}Pocet miest:
+STR_NUMBER_OF_INDUSTRIES :{BLACK}Pocet priemyslu:
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_SNOW_LINE_UP :{BLACK}Zvysit vysku snehovej ciary o jedno
+STR_SNOW_LINE_DOWN :{BLACK}Znizit vysku snehovej ciary o jedno
+STR_SNOW_LINE_QUERY_CAPT :{WHITE}Zmenit vysku snehovej ciary
+STR_START_DATE_QUERY_CAPT :{WHITE}Zmenit rok zaciatku hry
+STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Upozornenie na stupnicu
+STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Prilis velka zmena velkosti zdrojovej mapy sa neodporuca. Pokracovat s generovanim?
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_HEIGHTMAP_NAME :{BLACK}Nazov vyskovej mapy:
+STR_HEIGHTMAP_SIZE :{BLACK}Velkost: {ORANGE}{NUM} x {NUM}
+STR_GENERATION_WORLD :{WHITE}Generujem krajinu ...
+STR_GENERATION_ABORT :{BLACK}Ukoncit
+STR_GENERATION_ABORT_CAPTION :{WHITE}Ukoncit generovanie krajiny
+STR_GENERATION_ABORT_MESSAGE :{YELLOW}Skutocne chcete ukoncit generovanie?
+STR_PROGRESS :{WHITE}{NUM}% hotovych
+STR_GENERATION_PROGRESS :{BLACK}{NUM} / {NUM}
+STR_WORLD_GENERATION :{BLACK}Generovanie krajiny
+STR_TREE_GENERATION :{BLACK}Generovanie stromov
+STR_UNMOVABLE_GENERATION :{BLACK}Nepohyblive generovanie
+STR_CLEARING_TILES :{BLACK}Generovanie nerovnosti a skal
+STR_SETTINGUP_GAME :{BLACK}Nastavovanie hry
+STR_PREPARING_TILELOOP :{BLACK}Spustam tile-loop
+STR_PREPARING_GAME :{BLACK}Priprava hry
+STR_DIFFICULTY_TO_CUSTOM :{WHITE}Obtiažnost sa zmenila na vlastnú
+STR_SE_FLAT_WORLD :{WHITE}Rovna krajina
+STR_SE_FLAT_WORLD_TIP :{BLACK}Generovat rovnu krajinu
+STR_SE_RANDOM_LAND :{WHITE}Nahodna krajina
+STR_SE_NEW_WORLD :{BLACK}Vytvorit novy scenar
+STR_SE_CAPTION :{WHITE}Typ scenara
+STR_FLAT_WORLD_HEIGHT_DOWN :{BLACK}Znizit vysku rovnej krajiny o jedno
+STR_FLAT_WORLD_HEIGHT_UP :{BLACK}Zvysit vysku rovnej krajiny o jedno
+STR_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Zmenit vysku rovnej krajiny
+STR_FLAT_WORLD_HEIGHT :{BLACK}Vyska rovnej krajiny:
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+STR_SMALLMAP_CENTER :{BLACK}Vycentrovat malu mapu na aktualnu poziciu
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}Male
+STR_CITY_AIRPORT :{BLACK}Mestske
+STR_METRO_AIRPORT :{BLACK}Metropolitne
+STR_INTERNATIONAL_AIRPORT :{BLACK}Medzinarodne
+STR_COMMUTER_AIRPORT :{BLACK}Vnutrostatne
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Medzikontinentalne
+STR_HELIPORT :{BLACK}Heliport
+STR_HELIDEPOT :{BLACK}Heliport s hangarom
+STR_HELISTATION :{BLACK}Velky heliport
+
+STR_SMALL_AIRPORTS :{BLACK}Male letiska
+STR_LARGE_AIRPORTS :{BLACK}Velke letiska
+STR_HUB_AIRPORTS :{BLACK}Najvacsie letiska
+STR_HELIPORTS :{BLACK}Heliporty
+
+############ Tooltip measurment
+
+STR_MEASURE_LENGTH :{BLACK}Dlžka: {NUM}
+STR_MEASURE_AREA :{BLACK}Plocha: {NUM} x {NUM}
+STR_MEASURE_LENGTH_HEIGHTDIFF :{BLACK}Dlžka: {NUM}{}Výškový rozdiel: {NUM} m
+STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}Plocha: {NUM} x {NUM}{}Výškový rozdiel: {NUM} m
+
+########
diff --git a/src/lang/spanish.txt b/src/lang/spanish.txt
new file mode 100644
index 000000000..4792f5e25
--- /dev/null
+++ b/src/lang/spanish.txt
@@ -0,0 +1,3117 @@
+##name Spanish
+##ownname Español (ES)
+##isocode es_ES.UTF-8
+##plural 0
+##gender masculino femenino
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Fuera del borde del mapa
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Demasiado cerca del borde del mapa
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}No hay suficiente dinero - se requiere {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Se requiere terreno llano
+STR_0008_WAITING :{BLACK}Esperando: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (en ruta desde
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Acepta: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Acepta: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :Pasajeros
+STR_0010_COAL :Carbón
+STR_0011_MAIL :Correo
+STR_0012_OIL :Petróleo
+STR_0013_LIVESTOCK :Ganado
+STR_0014_GOODS :Mercancías
+STR_0015_GRAIN :Grano
+STR_0016_WOOD :Madera
+STR_0017_IRON_ORE :Mineral de hierro
+STR_0018_STEEL :Acero
+STR_0019_VALUABLES :Objetos de valor
+STR_001A_COPPER_ORE :Mineral de cobre
+STR_001B_MAIZE :Maíz
+STR_001C_FRUIT :Fruta
+STR_001D_DIAMONDS :Diamantes
+STR_001E_FOOD :Alimento
+STR_001F_PAPER :Papel
+STR_0020_GOLD :Oro
+STR_0021_WATER :Agua
+STR_0022_WHEAT :Trigo
+STR_0023_RUBBER :Caucho
+STR_0024_SUGAR :Azúcar
+STR_0025_TOYS :Juguetes
+STR_0026_CANDY :Dulces
+STR_0027_COLA :Cola
+STR_0028_COTTON_CANDY :Algodón de azúcar
+STR_0029_BUBBLES :Burbujas
+STR_002A_TOFFEE :Caramelo
+STR_002B_BATTERIES :Baterías
+STR_002C_PLASTIC :Plástico
+STR_002D_FIZZY_DRINKS :Refrescos
+STR_002E :
+STR_002F_PASSENGER :Pasajero
+STR_0030_COAL :Carbón
+STR_0031_MAIL :Correo
+STR_0032_OIL :Petróleo
+STR_0033_LIVESTOCK :Ganado
+STR_0034_GOODS :Mercancías
+STR_0035_GRAIN :Grano
+STR_0036_WOOD :Madera
+STR_0037_IRON_ORE :Mineral de hierro
+STR_0038_STEEL :Acero
+STR_0039_VALUABLES :Objetos de valor
+STR_003A_COPPER_ORE :Mineral de cobre
+STR_003B_MAIZE :Maíz
+STR_003C_FRUIT :Fruta
+STR_003D_DIAMOND :Diamantes
+STR_003E_FOOD :Alimento
+STR_003F_PAPER :Papel
+STR_0040_GOLD :Oro
+STR_0041_WATER :Agua
+STR_0042_WHEAT :Trigo
+STR_0043_RUBBER :Caucho
+STR_0044_SUGAR :Azúcar
+STR_0045_TOY :Juguete
+STR_0046_CANDY :Dulce
+STR_0047_COLA :Cola
+STR_0048_COTTON_CANDY :Algodón de azúcar
+STR_0049_BUBBLE :Burbuja
+STR_004A_TOFFEE :Caramelo
+STR_004B_BATTERY :Pilas
+STR_004C_PLASTIC :Plástico
+STR_004D_FIZZY_DRINK :Refresco
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} pasajero{P "" s}
+STR_QUANTITY_COAL :{WEIGHT} de carbón
+STR_QUANTITY_MAIL :{COMMA} saca{P "" s} de correo
+STR_QUANTITY_OIL :{VOLUME} de petróleo
+STR_QUANTITY_LIVESTOCK :{COMMA} cabeza{P "" s} de ganado
+STR_QUANTITY_GOODS :{COMMA} caja{P "" s} de mercancía{P "" s}
+STR_QUANTITY_GRAIN :{WEIGHT} de grano
+STR_QUANTITY_WOOD :{WEIGHT} de madera
+STR_QUANTITY_IRON_ORE :{WEIGHT} de mineral de hierro
+STR_QUANTITY_STEEL :{WEIGHT} de acero
+STR_QUANTITY_VALUABLES :{COMMA} bolsa{P "" s} de objetos de valor
+STR_QUANTITY_COPPER_ORE :{WEIGHT} de mineral de cobre
+STR_QUANTITY_MAIZE :{WEIGHT} de maíz
+STR_QUANTITY_FRUIT :{WEIGHT} de fruta
+STR_QUANTITY_DIAMONDS :{COMMA} bolsa{P "" s} de diamantes
+STR_QUANTITY_FOOD :{WEIGHT} de alimento
+STR_QUANTITY_PAPER :{WEIGHT} de papel
+STR_QUANTITY_GOLD :{COMMA} bolsa{P "" s} de oro
+STR_QUANTITY_WATER :{VOLUME} de agua
+STR_QUANTITY_WHEAT :{WEIGHT} de trigo
+STR_QUANTITY_RUBBER :{VOLUME} de caucho
+STR_QUANTITY_SUGAR :{WEIGHT} de azucar
+STR_QUANTITY_TOYS :{COMMA} juguete{P "" s}
+STR_QUANTITY_SWEETS :{COMMA} bolsa{P "" s} de dulces
+STR_QUANTITY_COLA :{VOLUME} de cola
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} de algodón de azúcar
+STR_QUANTITY_BUBBLES :{COMMA} burbuja{P "" s}
+STR_QUANTITY_TOFFEE :{WEIGHT} de caramelo{P "" s}
+STR_QUANTITY_BATTERIES :{COMMA} pila{P "" s}
+STR_QUANTITY_PLASTIC :{VOLUME} de plástico
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} refresco{P "" s}
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}PS
+STR_ABBREV_COAL :{TINYFONT}CL
+STR_ABBREV_MAIL :{TINYFONT}ML
+STR_ABBREV_OIL :{TINYFONT}OL
+STR_ABBREV_LIVESTOCK :{TINYFONT}LV
+STR_ABBREV_GOODS :{TINYFONT}GD
+STR_ABBREV_GRAIN :{TINYFONT}GR
+STR_ABBREV_WOOD :{TINYFONT}WD
+STR_ABBREV_IRON_ORE :{TINYFONT}OR
+STR_ABBREV_STEEL :{TINYFONT}ST
+STR_ABBREV_VALUABLES :{TINYFONT}VL
+STR_ABBREV_COPPER_ORE :{TINYFONT}CO
+STR_ABBREV_MAIZE :{TINYFONT}MZ
+STR_ABBREV_FRUIT :{TINYFONT}FT
+STR_ABBREV_DIAMONDS :{TINYFONT}DM
+STR_ABBREV_FOOD :{TINYFONT}FD
+STR_ABBREV_PAPER :{TINYFONT}PR
+STR_ABBREV_GOLD :{TINYFONT}GD
+STR_ABBREV_WATER :{TINYFONT}WR
+STR_ABBREV_WHEAT :{TINYFONT}WH
+STR_ABBREV_RUBBER :{TINYFONT}RB
+STR_ABBREV_SUGAR :{TINYFONT}SG
+STR_ABBREV_TOYS :{TINYFONT}TY
+STR_ABBREV_SWEETS :{TINYFONT}SW
+STR_ABBREV_COLA :{TINYFONT}CL
+STR_ABBREV_CANDYFLOSS :{TINYFONT}CF
+STR_ABBREV_BUBBLES :{TINYFONT}BU
+STR_ABBREV_TOFFEE :{TINYFONT}TF
+STR_ABBREV_BATTERIES :{TINYFONT}BA
+STR_ABBREV_PLASTIC :{TINYFONT}PL
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}FZ
+STR_ABBREV_NONE :{TINYFONT}NO
+STR_ABBREV_ALL :{TINYFONT}TODOS
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Mapa - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Opciones del juego
+STR_00B2_MESSAGE :{YELLOW}Mensaje
+STR_00B3_MESSAGE_FROM :{YELLOW}Mensaje de {STRING}
+STR_POPUP_CAUTION_CAPTION :{WHITE}Precaución!
+STR_00B4_CAN_T_DO_THIS :{WHITE}No se puede hacer eso....
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}No se puede desbrozar esta zona....
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Copyright Original {COPYRIGHT} 1995 Chris Sawyer, Todos los derechos reservados
+STR_00B7_VERSION :{BLACK}OpenTTD versión {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 El equipo OpenTTD
+STR_TRANSLATED_BY :{BLACK} Traductor(es) -
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Salir
+STR_00C8_YES :{BLACK}Si
+STR_00C9_NO :{BLACK}No
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}¿Está seguro de abandonar y regresar a {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Nada
+STR_00D1_DARK_BLUE :Azul oscuro
+STR_00D2_PALE_GREEN :Verde pálido
+STR_00D3_PINK :Rosa
+STR_00D4_YELLOW :Amarillo
+STR_00D5_RED :Rojo
+STR_00D6_LIGHT_BLUE :Azul claro
+STR_00D7_GREEN :Verde
+STR_00D8_DARK_GREEN :Verde oscuro
+STR_00D9_BLUE :Azul
+STR_00DA_CREAM :Crema
+STR_00DB_MAUVE :Malva
+STR_00DC_PURPLE :Morado
+STR_00DD_ORANGE :Naranja
+STR_00DE_BROWN :Marrón
+STR_00DF_GREY :Gris
+STR_00E0_WHITE :Blanco
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Demasiados vehículos en el juego
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Sitio
+STR_00E5_CONTOURS :Contornos
+STR_00E6_VEHICLES :Vehículos
+STR_00E7_INDUSTRIES :Industrias
+STR_00E8_ROUTES :Rutas
+STR_00E9_VEGETATION :Vegetación
+STR_00EA_OWNERS :Propietarios
+STR_00EB_ROADS :{BLACK}{TINYFONT}Carreteras
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Ferrocarriles
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Estaciones/Aerop./Puertos
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Edifícios/Industrias
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Vehículos
+STR_00F0_100M :{BLACK}{TINYFONT}100m
+STR_00F1_200M :{BLACK}{TINYFONT}200m
+STR_00F2_300M :{BLACK}{TINYFONT}300m
+STR_00F3_400M :{BLACK}{TINYFONT}400m
+STR_00F4_500M :{BLACK}{TINYFONT}500m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Trenes
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Vehículos de carretera
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Barcos
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Aeronaves
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Rutas de transporte
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Mina de carbón
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Central eléctica
+STR_00FC_FOREST :{BLACK}{TINYFONT}Bosque
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}Aserradero
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Refinería
+STR_00FF_FARM :{BLACK}{TINYFONT}Granja
+STR_0100_FACTORY :{BLACK}{TINYFONT}Fábrica
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Imprenta
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Pozos de petróleo
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Mina de hierro
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Altos hornos
+STR_0105_BANK :{BLACK}{TINYFONT}Banco
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Papelera
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Mina de oro
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Planta procesadora de alimento
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Mina de diamantes
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Mina de cobre
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Plantación de fruta
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Plantación de caucho
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Abastecimiento de agua
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Torre de agua
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}Aserradero
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Bosque de algodón de azúcar
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Fábrica de dulces
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Granja de pilas
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Pozos de cola
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Juguetería
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Fábrica de juguetes
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Fuentes de plástico
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Fábrica de refrescos
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Generador de burbujas
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Cantera de caramelos
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Mina de azúcar
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Estación de ferrocarril
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Muelle de carga de camiones
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Estación de autobuses
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Aeropuerto/Helipuerto
+STR_011F_DOCK :{BLACK}{TINYFONT}Muelle
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Terreno complicado
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Terreno de prados
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Terreno árido
+STR_0123_FIELDS :{BLACK}{TINYFONT}Campos
+STR_0124_TREES :{BLACK}{TINYFONT}Ãrboles
+STR_0125_ROCKS :{BLACK}{TINYFONT}Rocas
+STR_0126_WATER :{BLACK}{TINYFONT}Agua
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Sin propietario
+STR_0128_TOWNS :{BLACK}{TINYFONT}Poblaciones
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Industrias
+STR_012A_DESERT :{BLACK}{TINYFONT}Desierto
+STR_012B_SNOW :{BLACK}{TINYFONT}Nieve
+STR_012C_MESSAGE :{WHITE}Mensaje
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Cancelar
+STR_012F_OK :{BLACK}OK
+STR_0130_RENAME :{BLACK}Renombrar
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Demasiados nombres definidos
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}El nombre elegido está en uso
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...propiedad de {STRING}
+STR_013C_CARGO :{BLACK}Carga
+STR_013D_INFORMATION :{BLACK}Información
+STR_013E_CAPACITIES :{BLACK}Capacidades
+STR_013E_TOTAL_CARGO :{BLACK}Carga total
+STR_013F_CAPACITY :{BLACK}Capacidad: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}Capacidad: {LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Carga total (capacidad) de este tren:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}Nuevo Juego
+STR_0141_LOAD_GAME :{BLACK}Cargar Juego
+STR_SINGLE_PLAYER :{BLACK}Un jugador
+STR_MULTIPLAYER :{BLACK}Multijugador
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Tamaño del mapa:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Opciones de Juego
+
+STR_0150_SOMEONE :alguien{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Mapa del mundo
+STR_0152_TOWN_DIRECTORY :Listado de poblaciones
+STR_0153_SUBSIDIES :Subvenciones
+
+STR_UNITS_IMPERIAL :Imperial
+STR_UNITS_METRIC :Métrico
+STR_UNITS_SI :SI
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} mph
+STR_UNITS_VELOCITY_METRIC :{COMMA} km/h
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}hp
+STR_UNITS_POWER_METRIC :{COMMA}hp
+STR_UNITS_POWER_SI :{COMMA}kW
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} tonelada{P "" s}
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} tonelada{P "" s}
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} kg
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}gal
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}l
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}m³
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} galón{P "" s}
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} litro{P "" s}
+STR_UNITS_VOLUME_LONG_SI :{COMMA} m³
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10³ lbf
+STR_UNITS_FORCE_METRIC :{COMMA} ton. fuerza
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Gráfico de benefício operativo
+STR_0155_INCOME_GRAPH :Gráfico de ingresos
+STR_0156_DELIVERED_CARGO_GRAPH :Gráfico de carga entregada
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Gráfico de rendimiento
+STR_0158_COMPANY_VALUE_GRAPH :Gráfico del valor de la empresa
+STR_0159_CARGO_PAYMENT_RATES :Tarifas de pagos por carga
+STR_015A_COMPANY_LEAGUE_TABLE :Tabla de ranking de empresas
+STR_PERFORMANCE_DETAIL_MENU :Detalles del rendimiento
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}Acerca de OpenTTD
+STR_015C_SAVE_GAME :Guardar juego
+STR_015D_LOAD_GAME :Cargar juego
+STR_015E_QUIT_GAME :Abandonar juego
+STR_015F_QUIT :Salir
+STR_ABANDON_GAME_QUERY :{YELLOW}¿Estás seguro que deseas abandonar este juego?
+STR_0161_QUIT_GAME :{WHITE}Abandonar Juego
+STR_SORT_ORDER_TIP :{BLACK}Seleccione ordenación (descendiente/ascendinte)
+STR_SORT_CRITERIA_TIP :{BLACK}Seleccione criterio de orden
+STR_SORT_BY :{BLACK}Ordenar por
+
+STR_SORT_BY_POPULATION :{BLACK}Población
+STR_SORT_BY_PRODUCTION :{BLACK}Producción
+STR_SORT_BY_TYPE :{BLACK}Tipo
+STR_SORT_BY_TRANSPORTED :{BLACK}Transportado
+STR_SORT_BY_NAME :{BLACK}Nombre
+STR_SORT_BY_DROPDOWN_NAME :Nombre
+STR_SORT_BY_DATE :{BLACK}Fecha
+STR_SORT_BY_NUMBER :Número
+STR_SORT_BY_PROFIT_LAST_YEAR :Beneficio año pasado
+STR_SORT_BY_PROFIT_THIS_YEAR :Beneficio año actual
+STR_SORT_BY_AGE :Edad
+STR_SORT_BY_RELIABILITY :Fiabilidad
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Capacidad por tipo de carga
+STR_SORT_BY_MAX_SPEED :Velocidad máxima
+STR_SORT_BY_MODEL :Modelo
+STR_SORT_BY_VALUE :Valor
+STR_SORT_BY_FACILITY :Tipo de estación
+STR_SORT_BY_WAITING :Esperando valor de la carga
+STR_SORT_BY_RATING_MAX :Clasificación de la carga
+STR_ENGINE_SORT_ENGINE_ID :ID Locomotora (ordenación clásia)
+STR_ENGINE_SORT_COST :Coste
+STR_ENGINE_SORT_POWER :Potencia
+STR_ENGINE_SORT_INTRO_DATE :Fecha Introducción
+STR_ENGINE_SORT_RUNNING_COST :Coste Operación
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Potencia/Coste Operación
+STR_ENGINE_SORT_CARGO_CAPACITY :Capacidad de carga
+STR_NO_WAITING_CARGO :{BLACK}Ningún tipo de carga está esperando
+STR_SELECT_ALL_FACILITIES :{BLACK}Seleccionar todas las facilidades
+STR_SELECT_ALL_TYPES :{BLACK}Seleccionar todos los tipos de carga (incluidas las que no están en espera)
+STR_AVAILABLE_ENGINES_TIP :{BLACK}Ver la lista de los motores disponibles para este tipo de vehículo.
+STR_MANAGE_LIST :{BLACK}Administrar lista
+STR_MANAGE_LIST_TIP :{BLACK}Enviar instrucciones a todos los vehículos de la lista
+STR_REPLACE_VEHICLES :Reemplazar vehículos
+STR_SEND_TRAIN_TO_DEPOT :Enviar a Depósito
+STR_SEND_ROAD_VEHICLE_TO_DEPOT :Enviar a Depósito
+STR_SEND_SHIP_TO_DEPOT :Enviar a Depósito
+STR_SEND_AIRCRAFT_TO_HANGAR :Enviar al Hangar
+STR_SEND_FOR_SERVICING :Enviar para Servicio
+
+############ range for months starts
+STR_0162_JAN :Ene
+STR_0163_FEB :Feb
+STR_0164_MAR :Mar
+STR_0165_APR :Abr
+STR_0166_MAY :May
+STR_0167_JUN :Jun
+STR_0168_JUL :Jul
+STR_0169_AUG :Ago
+STR_016A_SEP :Sep
+STR_016B_OCT :Oct
+STR_016C_NOV :Nov
+STR_016D_DEC :Dic
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Pausar juego
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Guardar juego, abandonar juego, salir
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Mostrar lista de estaciones
+STR_0174_DISPLAY_MAP :{BLACK}Mostrar mapa
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Mostrar mapa, guía de poblaciones
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Mostrar guía de poblaciones
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Mostrar información financiera de la empresa
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Mostrar información general de la empresa
+STR_0179_DISPLAY_GRAPHS :{BLACK}Mostrar gráficos
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Mostrar tabla de ranking de empresas
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Mostrar lista de trenes de la empresa
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Mostrar lista de vehículos de carretera de la empresa
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Mostrar lista de barcos de la empresa
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Mostrar lista de aeronaves de la empresa
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Acercar vista
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Alejar vista
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Construir vías de ferrocarril
+STR_0182_BUILD_ROADS :{BLACK}Construir carreteras
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Construir muelles para barcos
+STR_0184_BUILD_AIRPORTS :{BLACK}Construir aeropuertos
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Plantar árboles
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Consultar bloque de terreno
+STR_0187_OPTIONS :{BLACK}Opciones
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}No es posible cambiar el intervalo del mantenimiento
+STR_018B_CLOSE_WINDOW :{BLACK}Cerrar ventana
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Título de la ventana - arrastrelo para mover la ventana
+STR_STICKY_BUTTON :{BLACK}Marcar esta ventana como no borrable para el comando de 'Cerrar Todas las Ventanas'
+STR_RESIZE_BUTTON :{BLACK}Pulse y arrastre para redimensionar la ventana
+STR_SAVELOAD_HOME_BUTTON :{BLACK}Pulsa aquí para ir al directorio por defecto de guardado
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Demoler edificios, etc. en un bloque de terreno
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Bajar una esquina del terreno
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Subir una esquina del terreno
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Barra de scroll - mueve la lista arriba/abajo
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Barra de scroll - mueve la lista izquierda/derecha
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Mostrar contorno del terreno en el mapa
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Mostrar vehículos en el mapa
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Mostrar industrias en el mapa
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Mostrar rutas de transporte en el mapa
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Mostrar vegetación en el mapa
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Mostrar propietarios de terrenos en el mapa
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Poner/quitar nombres de poblaciones en el mapa
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Benefício este año: {CURRENCY} (año anterior: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} año{P "" s} ({COMMA})
+STR_AGE_RED :{RED}{COMMA} año{P "" s} ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Vehículo de carretera
+STR_019D_AIRCRAFT :Aeronave
+STR_019E_SHIP :Barco
+STR_019F_TRAIN :Tren
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} se está volviendo viejo
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} se está volviendo muy viejo
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} se está volviendo demasiado viejo y requiere de ser reemplazado urgentemente
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Información sobre el terreno
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Coste de desbroce: {LTBLUE}N/D
+STR_01A5_COST_TO_CLEAR :{BLACK}Coste de desbroce: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :N/D
+STR_01A7_OWNER :{BLACK}Propietario: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Autoridad local: {LTBLUE}{STRING}
+STR_01A9_NONE :Ninguna
+STR_01AA_NAME :{BLACK}Nombre
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1
+STR_01AD_2ND :2
+STR_01AE_3RD :3
+STR_01AF_4TH :4
+STR_01B0_5TH :5
+STR_01B1_6TH :6
+STR_01B2_7TH :7
+STR_01B3_8TH :8
+STR_01B4_9TH :9
+STR_01B5_10TH :10
+STR_01B6_11TH :11
+STR_01B7_12TH :12
+STR_01B8_13TH :13
+STR_01B9_14TH :14
+STR_01BA_15TH :15
+STR_01BB_16TH :16
+STR_01BC_17TH :17
+STR_01BD_18TH :18
+STR_01BE_19TH :19
+STR_01BF_20TH :20
+STR_01C0_21ST :21
+STR_01C1_22ND :22
+STR_01C2_23RD :23
+STR_01C3_24TH :24
+STR_01C4_25TH :25
+STR_01C5_26TH :26
+STR_01C6_27TH :27
+STR_01C7_28TH :28
+STR_01C8_29TH :29
+STR_01C9_30TH :30
+STR_01CA_31ST :31
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Carga aceptada: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Selección de Jazz
+STR_01D3_SOUND_MUSIC :Sonido/música
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Mostrar ventana de sonido/música
+STR_01D5_ALL :{TINYFONT}Todo
+STR_01D6_OLD_STYLE :{TINYFONT}Antigüo
+STR_01D7_NEW_STYLE :{TINYFONT}Moderno
+STR_01D8_EZY_STREET :{TINYFONT}Ezy Street
+STR_01D9_CUSTOM_1 :{TINYFONT}Personal 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Personal 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Volumen música
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Volumen efectos
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MIN ' ' ' ' ' ' MAX
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Pasar a pista anterior de la selección
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Pasar a siguiente pista de la selección
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Detener música
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Comenzar música
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Mueva los cursores para fijar volumen de música y efectos
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Pista{SETX 88}Título
+STR_01E9_SHUFFLE :{TINYFONT}Mezclar
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Programa
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Selección del programa de música
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Ãndice de pistas
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Programa - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}Borrar
+STR_01F1_SAVE :{TINYFONT}{BLACK}Guardar
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Programa actual de pistas de música
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Seleccionar programa 'todas las pistas'
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Seleccionar programa 'estilo antigüo'
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Seleccionar programa 'estilo moderno'
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Seleccionar programa 'Personal 1' (definido por el usuario)
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Seleccionar programa 'Personal 2' (definido por el usuario)
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Borrar programa actual (solo Personal 1 y Personal 2)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Guardar configuración de música
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Pulse sobre la pista de música para añadirla al programa actual (solo Personal 1 y Personal 2)
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Pulsa sobre la canción para quitarla del programa actual (Solo Personalizado1 y Personalizado2)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Encender/apagar mezclador
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Mostrar ventana de selección de pistas musicales
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Haga click sobre el servicio para centrar la vista en la industria/población
+STR_01FE_DIFFICULTY :{BLACK}Dificultad ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Último mensaje/noticia
+STR_0201_MESSAGE_SETTINGS :Opciones de mensajes
+STR_MESSAGE_HISTORY_MENU :Historial de mensajes
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Mostrar último mensaje/noticia, mostrar opciones de mensajes
+STR_0204_MESSAGE_OPTIONS :{WHITE}Opciones de Mensajes
+STR_0205_MESSAGE_TYPES :{BLACK}Tipos de mensaje:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Llegada del 1er veh. estación del jugador
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Llegada del 1er veh. estación de la competencia
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Accidentes / desastres
+STR_0209_COMPANY_INFORMATION :{YELLOW}Información de la empresa
+STR_020A_ECONOMY_CHANGES :{YELLOW}Cambios en la economía
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Sugerencias/info. sobre vehículos del jugador
+STR_020C_NEW_VEHICLES :{YELLOW}Nuevos vehículos
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Cambios en la aceptación de carga
+STR_020E_SUBSIDIES :{YELLOW}Subvenciones
+STR_020F_GENERAL_INFORMATION :{YELLOW}Información general
+STR_MESSAGES_ALL :{YELLOW}Configuración para todos los mensajes (si/no/resumen)
+STR_MESSAGE_SOUND :{YELLOW}Reproducir sonido para resumen de noticias
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...demasiado lejano del destino anterior
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Top de empresas que han alcanzado {NUM}{}(Nivel {STRING})
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Tabla clasificatoria de empresas en {NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Hombre de negocios
+STR_0214_ENTREPRENEUR :Empresario
+STR_0215_INDUSTRIALIST :Industrial
+STR_0216_CAPITALIST :Capitalista
+STR_0217_MAGNATE :Magnate
+STR_0218_MOGUL :Mogul
+STR_0219_TYCOON_OF_THE_CENTURY :Magnate del siglo
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} logra el estado '{STRING}'!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} de {COMPANY} logra el estado '{STRING}'!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Crear Escenario
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Editor de escenarios
+STR_0223_LAND_GENERATION :{WHITE}Generación de terrenos
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Terreno al azar
+STR_0227_RESET_LAND :{BLACK}Reponer terreno
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Aumentar el tamaño del bloque de terreno a bajar/subir
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Reducir tamaño del bloque de terreno a bajar/subir
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Generar terreno al azar
+STR_022B_RESET_LANDSCAPE :{BLACK}Hacer reset del paisaje
+STR_022C_RESET_LANDSCAPE :{WHITE}Hacer reset del paisaje
+STR_LOAD_GAME_HEIGHTMAP :{WHITE}Usar Mapa de alturas
+STR_LOAD_SCEN_HEIGHTMAP :{BLACK}Usar Mapa de alturas
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}¿Está seguro que desea realizar un reset al paisaje?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Generación de paisaje
+STR_022F_TOWN_GENERATION :{BLACK}Generación de poblaciones
+STR_0230_INDUSTRY_GENERATION :{BLACK}Generación de industria
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Construcción de carreteras
+STR_0233_TOWN_GENERATION :{WHITE}Generación de poblaciones
+STR_0234_NEW_TOWN :{BLACK}Nueva población
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Construir nueva población
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}No se puede construir una población aquí...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...demasiado cercano al borde del mapa
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...demasiado cercano a otra población
+STR_0239_SITE_UNSUITABLE :{WHITE}...lugar no apropiado
+STR_023A_TOO_MANY_TOWNS :{WHITE}...demasiadas poblaciones
+STR_CANNOT_GENERATE_TOWN :{WHITE}No se puede construir ninguna ciudad
+STR_NO_SPACE_FOR_TOWN :{WHITE}...no hay más espacio en el mapa
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Aumentar tamaño de la población
+STR_023C_EXPAND :{BLACK}Aumentar
+STR_023D_RANDOM_TOWN :{BLACK}Población al azar
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Construir población en sitio al azar
+STR_023F_INDUSTRY_GENERATION :{WHITE}Generación de industria
+STR_0240_COAL_MINE :{BLACK}Mina de Carbón
+STR_0241_POWER_STATION :{BLACK}Cental Eléctrica
+STR_0242_SAWMILL :{BLACK}Aserradero
+STR_0243_FOREST :{BLACK}Bosque
+STR_0244_OIL_REFINERY :{BLACK}Refinería
+STR_0245_OIL_RIG :{BLACK}Plataforma Petrolífera
+STR_0246_FACTORY :{BLACK}Fábrica
+STR_0247_STEEL_MILL :{BLACK}Altos Hornos
+STR_0248_FARM :{BLACK}Granja
+STR_0249_IRON_ORE_MINE :{BLACK}Mina de Hierro
+STR_024A_OIL_WELLS :{BLACK}Pozos de Petróleo
+STR_024B_BANK :{BLACK}Banco
+STR_024C_PAPER_MILL :{BLACK}Papelera
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Planta procesadora de alimentos
+STR_024E_PRINTING_WORKS :{BLACK}Imprenta
+STR_024F_GOLD_MINE :{BLACK}Mina de Oro
+STR_0250_LUMBER_MILL :{BLACK}Aserradero
+STR_0251_FRUIT_PLANTATION :{BLACK}Plantación de Fruta
+STR_0252_RUBBER_PLANTATION :{BLACK}Plantación de Trigo
+STR_0253_WATER_SUPPLY :{BLACK}Abastecimiento de Agua
+STR_0254_WATER_TOWER :{BLACK}Torre de Agua
+STR_0255_DIAMOND_MINE :{BLACK}Mina de Diamantes
+STR_0256_COPPER_ORE_MINE :{BLACK}Mina de Cobre
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Bosque de Algodón de azúcar
+STR_0258_CANDY_FACTORY :{BLACK}Fábrica de Dulces
+STR_0259_BATTERY_FARM :{BLACK}Granja de Pilas
+STR_025A_COLA_WELLS :{BLACK}Pozos de Cola
+STR_025B_TOY_SHOP :{BLACK}Juguetería
+STR_025C_TOY_FACTORY :{BLACK}Fábrica de juguetes
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Fuentes de plástico
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Fábrica de refrescos
+STR_025F_BUBBLE_GENERATOR :{BLACK}Generador de burbujas
+STR_0260_TOFFEE_QUARRY :{BLACK}Cantera de caramelos
+STR_0261_SUGAR_MINE :{BLACK}Mina de azúcar
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Construir Mina de Carbón
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Construir Central Eléctrica
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Construir Sawmill
+STR_0265_PLANT_FOREST :{BLACK}Plantar Bosque
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Construir Refinería
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Construir Plataforma Petrolífera (Solo puede ser construir cerca del borde del mapa)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Construir Fábrica
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Construir Altos Hornos
+STR_026A_CONSTRUCT_FARM :{BLACK}Construir Granja
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Construir Mina de Hierro
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Construir Pozos de Petróleo
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Construir Banco (Solo puede ser construido en poblaciones con más de 1200 habitantes)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Construir Papelera
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Construir Planta procesadora de Alimentos
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Construir Imprenta
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Construir Mina de Oro
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Construir Banco (Solo puede ser construido en poblaciones)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Construir Aserradero (para talar la selva y producir madera)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Plantar fruta
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Plantar trigo
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Construir Abastecimiento de agua
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Construir Torre de Agua Tower (Solo puede ser construido en poblaciones)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Construir Mina de Diamantes
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Construir Mina de Cobre
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Plantar Bosque de Algodón de azúcar
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Construir Fábrica de Dulces
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Construir Granja de Pilas
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Construir Pozos de Cola
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Construir Juguetería
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Construir Fábrica de Juguetes
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Construir Fuentes de Plástico
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Construir Fábrica de Refrescos
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Construir Generador de Burbujas
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Construir cantera de caramelos
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Construir Mina de Azúcar
+STR_0285_CAN_T_BUILD_HERE :{WHITE}No se puede construir {STRING} aquí...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...debe constuirse la población primero
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...solo se permite uno por población
+STR_0288_PLANT_TREES :{BLACK}Plantar árboles
+STR_0289_PLACE_SIGN :{BLACK}Colocar señal
+STR_028A_RANDOM_TREES :{BLACK}Ãrboles al azar
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Planta árboles al azar sobre el paisaje
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Coloca zonas rocosas sobre el paisaje
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Colocar faro
+STR_028E_PLACE_TRANSMITTER :{BLACK}Colocar transmisor
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Define área desertica.{}Pulsa y mantén CTRL para quitarla
+STR_CREATE_LAKE :{BLACK}Define zona de água.{}Inundará los alrededores hasta nivel del mar
+STR_0290_DELETE :{BLACK}Borrar
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Borrar esta población completamente
+STR_0292_SAVE_SCENARIO :Guardar escenario
+STR_0293_LOAD_SCENARIO :Cargar escenario
+STR_0294_QUIT_EDITOR :Salir del editor
+STR_0295 :
+STR_0296_QUIT :Salir
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Guardar escenario, cargar escenario, cargar escenario, abandonar editor, salir
+STR_0298_LOAD_SCENARIO :{WHITE}Cargar Escenario
+STR_0299_SAVE_SCENARIO :{WHITE}Guardar Escenario
+STR_029A_PLAY_SCENARIO :{BLACK}Jugar Escenario
+STR_PLAY_HEIGHTMAP :{BLACK}Jugar Mapa de alturas
+STR_PLAY_HEIGHTMAP_HINT :{BLACK}Empezar juego nuevo, usando mapa de altura como terreno
+STR_QUIT_SCENARIO_QUERY :{YELLOW}¿Está seguro de que desea salir de este escenario?
+STR_029C_QUIT_EDITOR :{WHITE}Salir del Editor
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...solo puede ser construido en poblaciones con una población superior a 1200
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Retrocede la fecha de inicio en 1 año
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Avanza la fecha de inicio en 1 año
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...los dos extremos de un puente han de estar sobre tierra
+STR_02A1_SMALL :{BLACK}Pequeña
+STR_02A2_MEDIUM :{BLACK}Mediana
+STR_02A3_LARGE :{BLACK}Grande
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Selecciona el tamaño de la población
+STR_02A5_TOWN_SIZE :{YELLOW}Tamaño población:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Mostrar último mensaje/noticia
+STR_OFF :Apagado
+STR_SUMMARY :Resumen
+STR_FULL :Completo
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Directorio de poblaciones
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Nombres de diseño de vehículos
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Por defecto
+STR_02BF_CUSTOM :Personalizado
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Guardar nombres personalizados
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Selección de nombres de diseño de vehículos
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Guardar nombres personalizados en disco
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Opciones de juego
+STR_02C5_DIFFICULTY_SETTINGS :Configuración de dificultad
+STR_02C7_CONFIG_PATCHES :Configurar parches
+STR_NEWGRF_SETTINGS :Configuración Newgrf
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Ver nombres de poblaciones
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Ver nombres de estaciones
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Ver señales
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Ver puntos de comprobación
+STR_02D0_FULL_ANIMATION :{SETX 12}Animación completa
+STR_02D2_FULL_DETAIL :{SETX 12}Detalle completo
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Edificios transparentes
+STR_TRANSPARENT_SIGNS :{SETX 12}Señales transparentes
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Información sobre terreno
+STR_02D6 :
+STR_CONSOLE_SETTING :Activar consola
+STR_02D7_SCREENSHOT_CTRL_S :Captura de pantalla (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Captura Gigante (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :Acerca de 'OpenTTD'
+############ range ends here
+
+STR_02DB_OFF :{BLACK}Apagado
+STR_02DA_ON :{BLACK}Encendido
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Mostras subvenciones
+STR_02DD_SUBSIDIES :Subvenciones
+STR_02DE_MAP_OF_WORLD :Mapa del mundo
+STR_EXTRA_VIEW_PORT :Punto de vista extra
+STR_SIGN_LIST :Lista de señales
+STR_02DF_TOWN_DIRECTORY :Listado de poblaciones
+STR_TOWN_POPULATION :{BLACK}Población mundial: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Vista {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Copiar punto de vista
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Copia la localización de la vista global a este punto de vista
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Pegar punto de vista
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Pega la localización de este punto de vista a la global
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Unidades de moneda
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Selección de unidades de moneda
+STR_MEASURING_UNITS :{BLACK}Medir unidades
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Medir unidades seleccionadas
+STR_02E6_ROAD_VEHICLES :{BLACK}Vehículos de carretera
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Selecciona a qué lado de la carretera se debe conducir
+STR_02E9_DRIVE_ON_LEFT :Conducir por la izquierda
+STR_02EA_DRIVE_ON_RIGHT :Conducir por la derecha
+STR_02EB_TOWN_NAMES :{BLACK}Nombres de las poblaciones
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Selección del estilo del nombre de las poblaciones
+
+STR_02F4_AUTOSAVE :{BLACK}Autoguardado
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Selección del intervalo entre grabados automáticos del juego
+STR_02F7_OFF :Apagado
+STR_02F8_EVERY_3_MONTHS :Cada 3 meses
+STR_02F9_EVERY_6_MONTHS :Cada 6 meses
+STR_02FA_EVERY_12_MONTHS :Cada 12 meses
+STR_02FB_START_A_NEW_GAME :{BLACK}Comenzar nuevo juego
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Cargar un juego guardado
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Crear un mundo/escenario de juego personalizado
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Selecciona juego para un solo jugador
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Seleccionar juego multijugador para 2-8 jugadores
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Muestra las opciones del juego
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Muestra las opciones de dificultad
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Comienza un nuevo juego, usando un escenario personalizado desde el disco
+STR_0304_QUIT :{BLACK}Salir
+STR_0305_QUIT_OPENTTD :{BLACK}Salir de 'OpenTTD'
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...solo puede ser construido en poblaciones
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Elegir estilo de escenario 'templado'
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Elegir estilo de escenario 'sub-ártico'
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Elegir estilo de escenario 'sub-tropical'
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Elegir estilo de escenario 'fantasía'
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Aportar fondos para construir una nueva industria
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Directorio de Industrias
+STR_0313_FUND_NEW_INDUSTRY :Fundar nueva industria
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Fundar nueva industria
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...sólo se puede construir en poblaciones
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...sólo se puede construir en áreas de selva
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...sólo se puede construir en áreas desérticas
+STR_0319_PAUSED :{YELLOW}* * PAUSADO * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Captura de pantalla realizada con éxito en '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}¡Captura de pantalla fallida!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Comprar tierra para usos futuros
+STR_032F_AUTOSAVE :{RED}AUTOGUARDADO
+STR_SAVING_GAME :{RED}* * GUARDANDO JUEGO * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}El grabado está en progreso,{}por favor espere hasta que termine!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Elegir el programa musical de estilo 'Ezy Street'
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :Inglés
+STR_TOWNNAME_FRENCH :Francés
+STR_TOWNNAME_GERMAN :Alemán
+STR_TOWNNAME_ADDITIONAL_ENGLISH :Inglés (Adicional)
+STR_TOWNNAME_LATIN_AMERICAN :Latinoamericano
+STR_TOWNNAME_SILLY :Tontos
+STR_TOWNNAME_SWEDISH :Sueco
+STR_TOWNNAME_DUTCH :Holandés
+STR_TOWNNAME_FINNISH :Finlandés
+STR_TOWNNAME_POLISH :Polaco
+STR_TOWNNAME_SLOVAKISH :Eslovaco
+STR_TOWNNAME_NORWEGIAN :Noruego
+STR_TOWNNAME_HUNGARIAN :Húngaro
+STR_TOWNNAME_AUSTRIAN :Austríaco
+STR_TOWNNAME_ROMANIAN :Rumano
+STR_TOWNNAME_CZECH :Checo
+STR_TOWNNAME_SWISS :Suizo
+STR_TOWNNAME_DANISH :Danes
+STR_TOWNNAME_TURKISH :Turco
+STR_TOWNNAME_ITALIAN :Italiano
+STR_TOWNNAME_CATALAN :Catalán
+############ end of townname region
+
+STR_CURR_GBP :Libras (£)
+STR_CURR_USD :Dólares ($)
+STR_CURR_EUR :Euro (€)
+STR_CURR_YEN :Yen (Â¥)
+STR_CURR_ATS :Chelín Austriaco (ATS)
+STR_CURR_BEF :Franco Belga (BEF)
+STR_CURR_CHF :Franco Suizo (CHF)
+STR_CURR_CZK :Corona Checa (CZK)
+STR_CURR_DEM :Marcos (DEM)
+STR_CURR_DKK :Corona Danesa (DKK)
+STR_CURR_ESP :Pesetas (ESP)
+STR_CURR_FIM :Markka Finlandés (FIM)
+STR_CURR_FRF :Francos (FRF)
+STR_CURR_GRD :Dracma Griego (GRD)
+STR_CURR_HUF :Florines Hungaros (HUF)
+STR_CURR_ISK :Corona de Islandia (ISK)
+STR_CURR_ITL :Lira Italiana (ITL)
+STR_CURR_NLG :Florín Holandés (NLG)
+STR_CURR_NOK :Corona Noruega(NOK)
+STR_CURR_PLN :Zloty Polaco (PLN)
+STR_CURR_ROL :Leu Rumano (ROL)
+STR_CURR_RUR :Rublo Ruso (RUR)
+STR_CURR_SIT :Tolar Eslovenio (SIT)
+STR_CURR_SEK :Corona Sueca (SEK)
+STR_CURR_YTL :Lira Turca (YTL)
+STR_CURR_SKK :Corona Eslovaca
+STR_CURR_BRR :Real Brasileño (BRL)
+
+STR_CURR_CUSTOM :Personalizado...
+
+STR_OPTIONS_LANG :{BLACK}Idioma
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Seleccione el idioma para el interfaz del juego
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Pantalla completa
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}Marca esta opción para jugar OpenTTD a pantalla completa
+
+STR_OPTIONS_RES :{BLACK}Resolución de pantalla
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Seleccine la resolución de pantalla a utilizar
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Formato de captura de pantalla
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Seleccione el formato de captura de pantalla a utilizar
+
+STR_AUTOSAVE_1_MONTH :Cada mes
+STR_AUTOSAVE_FAILED :{WHITE}Error en Autoguardado
+
+STR_MONTH_JAN :Enero
+STR_MONTH_FEB :Febrero
+STR_MONTH_MAR :Marzo
+STR_MONTH_APR :Abril
+STR_MONTH_MAY :Mayo
+STR_MONTH_JUN :Junio
+STR_MONTH_JUL :Julio
+STR_MONTH_AUG :Agosto
+STR_MONTH_SEP :Septiembre
+STR_MONTH_OCT :Octubre
+STR_MONTH_NOV :Noviembre
+STR_MONTH_DEC :Diciembre
+
+STR_HEADING_FOR_STATION :{LTBLUE}Hacia {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}Hacia {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Sin órdenes
+STR_NO_ORDERS_VEL :{LTBLUE}Sin órdenes, {VELOCITY}
+
+STR_PASSENGERS :pasajeros
+STR_BAGS :bolsas
+STR_TONS :toneladas
+STR_LITERS :litros
+STR_ITEMS :artículos
+STR_CRATES :cajones
+STR_RES_OTHER :Otras
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}No se puede compartir la lista de órdenes...
+STR_CANT_COPY_ORDER_LIST :{WHITE}No se puede copiar la lista de órdenes...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - Fin de órdenes compartidas - -
+
+STR_TRAIN_IS_LOST :{WHITE}Tren {COMMA} está perdido.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}El beneficio del tren {COMMA} para el pasado año fué {CURRENCY}
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}¡Unión Monetaria Europea!{}{}El Euro es introducido como la moneda oficial para todas las transacciones de su país!
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}El tren {COMMA} tienes muy pocas órdenes en su calendario
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}El tren {COMMA} tiene una orden vacía
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}El tren {COMMA} tiene órdenes duplicadas
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}El tren {COMMA} tiene una estación no válida en sus órdenes
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}El vehículo de carretera {COMMA} tienes muy pocas órdenes en su calendario
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}El vehículo de carretera {COMMA} tiene una orden vacía
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}El vehículo de carretera {COMMA} tiene órdenes duplicadas
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}El vehículo de carretera {COMMA} tiene una estación no válida en sus órdenes
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}El barco {COMMA} tienes muy pocas órdenes en su calendario
+STR_SHIP_HAS_VOID_ORDER :{WHITE}Ship {COMMA} tiene una orden vacía
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}Ship {COMMA} tiene órdenes duplicadas
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}Ship {COMMA} tiene una estación no válida en sus órdenes
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}La aeronave {COMMA} tiene muy pocas órdenes en su calendario
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}La aeronave {COMMA} tiene una orden vacía
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}La aeronave {COMMA} tiene órdenes duplicadas
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}La aeronave {COMMA} tiene una estación no válida en sus órdenes
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}Auto renovar ha fallado con el tren {COMMA} (límite de dinero)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}AAuto renovar ha fallado con el vehículo de carretera {COMMA} (límite de dinero)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}Auto renovar ha fallado con el barco {COMMA} (límite de dinero)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}Auto renovar ha fallado con la aeronave {COMMA} (límite de dinero)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}El tren {COMMA} es demasiado largo tras el cambio
+
+STR_CONFIG_PATCHES :{BLACK}Configurar Parches
+STR_CONFIG_PATCHES_TIP :{BLACK}Configurar los parches
+STR_CONFIG_PATCHES_CAPTION :{WHITE}Configurar Parches
+
+STR_CONFIG_PATCHES_OFF :No
+STR_CONFIG_PATCHES_ON :Sí
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Mostrar velocidad del vehículo en la barra de estado: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Permitir la construcción en cuestas y orillas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Permitir tamaño del área de captación más realista: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Permitir demoler más propiedades de poblaciones: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Permitir la construcción de trenes muy largos: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Activar aceleración realista de trenes: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Prohibir a trenes/barcos giros de 90 grados: {ORANGE}{STRING} {LTBLUE} (requiere NPF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Unir estaciones de tren unas junto a otras: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Abandona est. con alguna carga completa, en 'carga completa': {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Usar algoritmo mejorado de carga: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GRADUAL_LOADING :{LTBLUE}Cargar vehículos gradualmente: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Inflacción: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Entregar mercancía a una estación sólo si hay demanda: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Permitir la construcción de puentes muy largos: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Permitir órdenes de ir a depósito: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Construcción de material en bruto usando industrias: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Construcción de más de una industria similar por población: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Industrias mismo tipo pueden construirse unas junto a otras: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Mostrar siempre fecha larga en la barra de estado: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Mostrar señales en el lado de conducción: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Mostrar ventana de finanzas al final del año: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}Manejo sin parada compatible con TTDPatch: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Cola de vehículos de carretera (con efecto cuantificador): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Desplazar ventana mediante el cursor en los bordes: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Permitir sobornos a la autoridad local: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Estaciones no uniformes: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Nuevo sistema de busq. de rutas global (NPF, anula a NTP): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FREIGHT_TRAINS :{LTBLUE}Carga el multiplicador de peso para simular trenes pesados: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Permitir siempre aeropuertos pequeños: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Avisar si el tren se pierde: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Revisar ordenes de los vehículos: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :no
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :si, pero excluye los detenidos
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :de todos los vehículos
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Avisar si los ingresos de un tren son negativos: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Los vehículos nunca caducan: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Renovación automática de vehículos cuando se vuelven viejos
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Renovación aut. si tiene {ORANGE}{STRING}{LTBLUE} meses antes/después edad máx.
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Renovar auto. usando la menor cantidad de dinero: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Duración del mensaje de error: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Muestra la población de esta población en esta etiqueta: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Ãrboles invisibles (con edificios transparentes): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Generador terreno: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :Original
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis
+STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}Max distancia desde los bordes para las Refinerías de Petroleo {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Altura línea nieve: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN :{LTBLUE}Aspereza del terreno (Solo TerraGenesis) : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Muy Suave
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH :Suave
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH :Ãspero
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :Muy Ãspero
+STR_CONFIG_PATCHES_TREE_PLACER :{LTBLUE}Algoritmo de colocación de árboles: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TREE_PLACER_NONE :Ninguno
+STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL :Original
+STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED :Mejorado
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION :{LTBLUE}Rotación de Mapa de altura: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :A la izquierda
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE :Sentido horario
+STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT :{LTBLUE}El nivel de la altura del mapa plano tiene: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Expansión máxima de est.: {ORANGE}{STRING} {RED}Atención: Valores altos relantizan
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Mantener los helicópteros en helipuertos automáticamente: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Une la caja de paisaje a la barra de rail/carretera...: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}El scroll de ratón mueve la vista en dirección opuesta: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Muestra información de medidas cuando usamos herramientras construcción: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Ver estaciones de la empresa: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES_NONE :Ninguno
+STR_CONFIG_PATCHES_LIVERIES_OWN :Propia empresa
+STR_CONFIG_PATCHES_LIVERIES_ALL :Todas las empresas
+STR_CONFIG_PATCHES_PREFER_TEAMCHAT :{LTBLUE}Charla de equipo preferida con <ENTER>: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Máx trenes por jugador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Máx vehículos de carretera por jugador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}Máx aeroplanos por jugador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}Máx barcos por jugador: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Desactivar trenes para el ordenador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Desactivar vehículos de carretera para el ordenador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Desactivar aeroplanos para el ordenador: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Desactivar barcos para el ordenador: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Activar nueva IA (alpha): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Permitir IA en multijugador (experimental): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Intervalo de despacho por defecto para trenes: {ORANGE}{STRING} días
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Intervalo de despacho por defecto para trenes: {ORANGE}no
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Intervalo de despacho por defecto para veh. de carretera: {ORANGE}{STRING} días
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Intervalo de despacho por defecto para veh. de carretera: {ORANGE}no
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Intervalo de despacho por defecto para aeroplanos: {ORANGE}{STRING} días
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Intervalo de despacho por defecto para aviones: {ORANGE}no
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Intervalo de despacho por defecto para barcos: {ORANGE}{STRING} días
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Intervalo de despacho por defecto para barcos: {ORANGE}no
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Desactivar servicio cuando las averías están desactivadas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Activar límites de velocidad en vagones: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}Desactivar railes electricos: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Noticias en color aparecen en: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Fecha de inicio: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}Fin del juego en: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Activar economía suave (cambios más pequeños)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Permitir comprar acciones de otras empresas
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Cuando arrastre colocar señales cada: {ORANGE}{STRING} casilla(s)
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Posición de la barra de herramientas principal: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Izquierda
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Centro
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Derecha
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Radio de snap de ventana: {ORANGE}{STRING} px
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Radio de snap de ventana: {ORANGE}desactivado
+
+STR_CONFIG_PATCHES_GUI :{BLACK}Interfaz
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Construcción
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Vehículos
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Estaciones
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Economía
+STR_CONFIG_PATCHES_AI :{BLACK}Competidores
+
+STR_CONFIG_PATCHES_DISABLED :desactivado
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Cambiar valor de la opción
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Alguno o todos los intervalos de servicio por defecto mostrados son incompatibles con la configuración elegida! 5-90% y 30-800 días son válidos
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}Usar YAPF para barcos: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}Usar YAPF para vehículos de carretera: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}Usar YAPF para trenes: {ORANGE}{STRING}
+
+STR_TEMPERATE_LANDSCAPE :Paisaje templado
+STR_SUB_ARCTIC_LANDSCAPE :Paisaje sub-ártico
+STR_SUB_TROPICAL_LANDSCAPE :Paisaje sub-tropical
+STR_TOYLAND_LANDSCAPE :Paisaje fantasía
+
+STR_CHEATS :{WHITE}Trucos
+STR_CHEATS_TIP :{BLACK}Las casillas indican si ha usado este truco antes
+STR_CHEATS_WARNING :{BLACK}Atención! Usted está a punto de traicionar a sus competidores. Tenga presente que tal deshonra será recordada para toda la eternidad.
+STR_CHEAT_MONEY :{LTBLUE}Incrementar dinero en {CURRENCY64}
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Jugar como el jugador: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Bulldozer mágico (elimina industrias, etc.): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Los túneles pueden cruzarse: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Construir mientras se está en pausa: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Los Jets no se estrellarán (frecuentemente) en aeropuertos pequeños: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Cambiar clima: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Cambiar fecha: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}Activar modificación de los valores de producción: {ORANGE}{STRING}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}Hacia {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Hacia {WAYPOINT}, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :Ir vía {WAYPOINT}
+STR_GO_NON_STOP_TO_WAYPOINT :Ir directo via {WAYPOINT}
+
+STR_WAYPOINTNAME_CITY :Punto de paso {TOWN}
+STR_WAYPOINTNAME_CITY_SERIAL :Punto de paso {TOWN} #{COMMA}
+STR_LANDINFO_WAYPOINT :Punto de paso
+
+STR_WAYPOINT :{WHITE}Punto de paso
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Seleccione tipo de punto de paso
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}Editar nombre del punto de paso
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}No se puede cambiar el nombre del punto de paso...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Convertir raíl a punto de paso
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}No se puede construir punto de paso para trenes aquí...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}No se puede retirar punto de paso aquí...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Construir tramos de ferrocarril usando modo Autorraíl
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}...no hay poblaciones en este escenario
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}¿Está seguro de generar un paisaje al azar?
+STR_MANY_RANDOM_TOWNS :{BLACK}Varias poblaciones al azar
+STR_RANDOM_TOWNS_TIP :{BLACK}Cubre el mapa con poblaciones colocadas al azar
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Varias industrias al azar
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Cubre el mapa con industrias colocadas al azar
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}No se pueden crear industrias...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Abre la herramienta de paisaje para nivelar/elevar terrenos, plantar árboles, etc.
+STR_LANDSCAPING_TOOLBAR :{WHITE}Paisaje
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Nivelar terreno
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Ãrboles al azar
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}Colocar distintos árboles al azar
+
+STR_CANT_BUILD_CANALS :{WHITE}No se pueden construir canales aquí...
+STR_BUILD_CANALS_TIP :{BLACK}Construir canales
+STR_LANDINFO_CANAL :Canal
+
+STR_CANT_BUILD_LOCKS :{WHITE}No se pueden construir dársenas aquí...
+STR_BUILD_LOCKS_TIP :{BLACK}Constuir dársenas
+STR_LANDINFO_LOCK :Dársena
+
+STR_BUOY_IS_IN_USE :{WHITE}...boya en uso!
+
+STR_LANDINFO_COORDS :{BLACK}Coordenadas: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}No se puede retirar parte de la estación...
+STR_CANT_CONVERT_RAIL :{WHITE}No se puede convertir tipo de raíl aquí...
+STR_CONVERT_RAIL_TIP :{BLACK}Convertir/Actualizar tipo de raíl
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Arrastrar la locomotora aquí para vender el tren entero
+
+STR_DRAG_DROP :{BLACK}Drag & Drop
+STR_STATION_DRAG_DROP :{BLACK}Construir una estación con arrastrar & soltar
+STR_SELECT_STATION_CLASS_TIP :{BLACK}Selecciona el tipo de estación a mostrar
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Selecciona el tipo de estación a construir
+
+STR_FAST_FORWARD :{BLACK}Avanzar el juego rápidamente
+STR_MESSAGE_HISTORY :{WHITE}Historial de mensajes
+STR_MESSAGE_HISTORY_TIP :{BLACK}Listado de los mensajes más recientes
+STR_MESSAGES_DISABLE_ALL :{BLACK}Desactivar todo
+STR_MESSAGES_ENABLE_ALL :{BLACK}Activar todo
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Construir mina de carbón
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Plantar bosque
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Construir plataforma petrolífera
+STR_CONSTRUCT_FARM_TIP :{BLACK}Fundar granja
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Construir mina de cobre
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Taladrar para buscar petróleo
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Construir mina de oro
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Construir mina de diamantes
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Construir mina de hierro
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Fundar plantación de frutas
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Fundar plantación de caucho
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Fundar suministro de agua
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Plantar bosque de Algodón de azúcar
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}Fundar granja de pilas
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Taladrar para buscar cola
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Fundar fuentes de plástico
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Construir generador de burbujas
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Fundar cantera de caramelos
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Construir mina de azúcar
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Industrias
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA}% transportado)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA}%/{COMMA}% transportado)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}...demasiado cercano a otra industria
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Reformar tren para transportar otro tipo de carga
+STR_RAIL_REFIT_VEHICLE :{BLACK}Reformar tren
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Elegir tipo de carga para que el tren lleve
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Reformar tren para transportar mercancía resaltada
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}No se puede reformar tren...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Intervalo de despachos en porcentajes: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Cambiar producción
+
+TEMP_AI_IN_PROGRESS :{WHITE}Bienvenido a esta nueva IA, en progreso. Puede esperar problemas. Cuando los encuentres, haz una captura de pantalla y envíala al foro. Disfruta!
+TEMP_AI_ACTIVATED :{WHITE}Atención: esta nueva IA está en fase alpha! Actualmente, solo los camiones y autobuses funcionan!
+TEMP_AI_MULTIPLAYER :{WHITE}Atención: esta función es todavía experimental. Comunique cualquier problema a truelight@openttd.org.
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Multijugador
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Nombre Jugad.:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}Este es el nombre con el que otros jugadores le identificarán
+STR_NETWORK_CONNECTION :{BLACK}Conexión:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Seleccione entre un juego en Internet o en una Red de Ãrea Local
+
+STR_NETWORK_START_SERVER :{BLACK}Comenzar servidor
+STR_NETWORK_START_SERVER_TIP :{BLACK}Comenzar un nuevo servidor
+
+STR_NETWORK_GAME_NAME :{BLACK}Nombre
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Nombre del juego
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Idioma, versión del servidor, etc.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Pulse en un juego de la lista para seleccionarlo
+
+STR_NETWORK_FIND_SERVER :{BLACK}Buscar servidor
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Buscar en la red servidores
+STR_NETWORK_ADD_SERVER :{BLACK}Añadir servidor
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Añade un servidor a la lista que será siempre consultada para ver juegos en ejecución.
+STR_NETWORK_ENTER_IP :{BLACK}Introduce la dirección IP del servidor
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Clientes
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Clientes online / máx clientes{}Compañías online / máximo compañías
+STR_NETWORK_GAME_INFO :{SILVER}INFO JUEGO
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Clientes: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Idioma: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Escenario: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Tamaño Mapa: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}Versión servidor: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}Dirección servidor: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Fecha inicio: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Fecha actual: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Protegido por contraseña!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}SERVIDOR APAGADO
+STR_NETWORK_SERVER_FULL :{SILVER}SERVIDOR LLENO
+STR_NETWORK_VERSION_MISMATCH :{SILVER}INCOMPATIBILIDAD DE VERSIONES
+STR_NETWORK_GRF_MISMATCH :{SILVER}PROBLEMA CON NEWGRF
+
+STR_NETWORK_JOIN_GAME :{BLACK}Unirme al juego
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}Empezar nuevo juego multijugador
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Nombre del juego:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}El nombre del juego será mostrado a otros jugadores en el menu de selección de juego multijugador
+STR_NETWORK_SET_PASSWORD :{BLACK}Establecer contraseña
+STR_NETWORK_PASSWORD_TIP :{BLACK}Proteje tu juego con una contraseña si no quieres que otras personas se unan a él
+STR_NETWORK_SELECT_MAP :{BLACK}Selecciona mapa:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}¿En qué mapa desea jugar?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}Máx. clientes permitidos:
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Seleccione un número máximo de clientes. No todos los slots serán ocupados.
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :LAN
+STR_NETWORK_INTERNET :Internet
+STR_NETWORK_LAN_INTERNET :LAN / Internet
+STR_NETWORK_INTERNET_ADVERTISE :Internet (anuncio)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 jugadores
+STR_NETWORK_1_PLAYERS :1 jugador
+STR_NETWORK_2_PLAYERS :2 jugadores
+STR_NETWORK_3_PLAYERS :3 jugadores
+STR_NETWORK_4_PLAYERS :4 jugadores
+STR_NETWORK_5_PLAYERS :5 jugadores
+STR_NETWORK_6_PLAYERS :6 jugadores
+STR_NETWORK_7_PLAYERS :7 jugadores
+STR_NETWORK_8_PLAYERS :8 jugadores
+STR_NETWORK_9_PLAYERS :9 jugadores
+STR_NETWORK_10_PLAYERS :10 jugadores
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}Máximo compañías:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Limitar el servidor a un cierto número de compañías
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}Espectadores máximos
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Limitar el servidor a un cierto número de espectadores
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Idioma hablado:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Otros jugadores sabrán cual es el idioma hablado en este servidor.
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}Empezar Juego
+STR_NETWORK_START_GAME_TIP :{BLACK}Empezar un nuevo juego en red desde un mapa al azar o escenario
+STR_NETWORK_LOAD_GAME :{BLACK}Cargar Juego
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Continúa un juego multijugador guardado (asegúrese de conectar con el jugador correcto)
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Cualquiera
+STR_NETWORK_LANG_ENGLISH :Inglés
+STR_NETWORK_LANG_GERMAN :Alemán
+STR_NETWORK_LANG_FRENCH :Francés
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Sala de estar del juego multijugador
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Preparando para unirse: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}Un listado de empresas actualmente en el juego. Puede unirse a una o emprezarla.
+STR_NETWORK_NEW_COMPANY :{BLACK}Nueva empresa
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Abre una nueva empresa
+STR_NETWORK_SPECTATE_GAME :{BLACK}Observar juego
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Observar un juego como espectador
+STR_NETWORK_JOIN_COMPANY :{BLACK}Unirse a empresa
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Ayudar a dirigir esta empresa
+STR_NETWORK_REFRESH :{BLACK}Recargar servidor
+STR_NETWORK_REFRESH_TIP :{BLACK}Recargar información del servidor
+
+STR_NETWORK_COMPANY_INFO :{SILVER}INFO EMPRESA
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Nombre empresa: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}Inauguración: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}Valor empresa: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Balance actual: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Ingresos último año: {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}Rendimiento: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}Vehículos: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Estaciones: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Jugadores: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}Conectando...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) Conectando..
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Autorizando..
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Esperando..
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Descargando mapa..
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Procesando datos..
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) Registrando..
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Recibiendo información del juego..
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Recibiendo información empresa..
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} cliente{P "" s} delante de usted
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} kbytes descargados
+
+STR_NETWORK_DISCONNECT :{BLACK}Desconectado
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Introduce la cantidad de dinero que desea dar
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Servidor protegido. Teclee la contraseña
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Empresa protegida. Introduce contraseña
+STR_NETWORK_CLIENT_LIST :{WHITE}Lista de clientes
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE} No se han encontrado dispositivos de red o juego compilado sin ENABLE_NETWORK
+STR_NETWORK_ERR_NOSERVER :{WHITE} No se puede encontrar ningún juego en red
+STR_NETWORK_ERR_NOCONNECTION :{WHITE} El servidor no responde a la petición
+STR_NETWORK_ERR_DESYNC :{WHITE} La sincronización del juego ha fallado.
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} La conexión con el juego en red se ha perdido.
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} No es posible cargar el juego multijugador.
+STR_NETWORK_ERR_SERVER_START :{WHITE} No se puede iniciar el servidor.
+STR_NETWORK_ERR_CLIENT_START :{WHITE} No se puede conectar.
+STR_NETWORK_ERR_TIMEOUT :{WHITE} Tiempo de espera agotado en conexión #{NUM}.
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE} Se ha producido un error de protocolo y la conexión ha sido cerrada.
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE} La versión de este cliente no corresponde con la versión de este servidor.
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} Contraseña incorrecta.
+STR_NETWORK_ERR_SERVER_FULL :{WHITE} El servidor está lleno
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} Has sido baneado de este servidor
+STR_NETWORK_ERR_KICKED :{WHITE} Has sido expulsado de este servidor
+STR_NETWORK_ERR_CHEATER :{WHITE} Los cheats (trucos) no son permitidos en este servidor
+
+STR_NETWORK_ERR_LEFT :ha abandonado el juego
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :error general
+STR_NETWORK_ERR_CLIENT_DESYNC :error de desync
+STR_NETWORK_ERR_CLIENT_SAVEGAME :no se puede cargar el mapa
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :conexión perdida
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :error protocolo
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :no autorizado
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :recibido paquete extraño
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :versión incorrecta
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :este nombre ya está en uso
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :contraseña de juego incorrecta
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :id de jugador incorrecto en DoCommand
+STR_NETWORK_ERR_CLIENT_KICKED :expulsado por el servidor
+STR_NETWORK_ERR_CLIENT_CHEATER :ha intentado usar un cheat (truco)
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :servidor lleno
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :se ha unido al juego
+STR_NETWORK_GIVE_MONEY :te ha enviado dinero ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :das a {STRING} algo de dinero ({CURRENCY})
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Equipo] :
+STR_NETWORK_CHAT_COMPANY :[Equipo] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Equipo] a {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[Privado] :
+STR_NETWORK_CHAT_CLIENT :[Privado] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[Privado] a {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[Todos] :
+STR_NETWORK_CHAT_ALL :[Todos] {STRING}: {GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :ha cambiado su nombre a
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE} El servidor ha cerrado la sesión
+STR_NETWORK_SERVER_REBOOT :{WHITE} Se está reiniciando el servidor...{}Espere por favor...
+
+STR_NETWORK_SERVER :Servidor
+STR_NETWORK_CLIENT :Cliente
+STR_NETWORK_SPECTATORS :Espectadores
+
+STR_NETWORK_CLIENTLIST_NONE :(ninguno)
+STR_NETWORK_CLIENTLIST_KICK :Expulsar
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Dar dinero
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Hablar a todos
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Hablar a empresa
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Mensaje privado
+
+
+STR_NETWORK_SEND :{BLACK}Enviar
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}Tamaño X del mapa: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Tamaño Y del mapa: {ORANGE}{STRING}
+
+
+##### PNG-MAP-Loader
+
+STR_PNGMAP_ERROR :{WHITE}No se pudo cargar mapa de altura desde el PNG...
+STR_PNGMAP_ERR_FILE_NOT_FOUND :{WHITE}...fichero no encontrado.
+STR_PNGMAP_ERR_IMAGE_TYPE :{WHITE}...no se pudo convertir tipo de imagen. Se requiere imagenes PNG de 8 o 24-bits.
+STR_PNGMAP_ERR_MISC :{WHITE}...algo ha salido mal. Lo siento (posiblemente el fichero esté corrupto)
+
+STR_BMPMAP_ERROR :{WHITE}No se puede cargar el paisaje desde el BMP...
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}...no se puede convertir el tipo de imagen.
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Coste: {CURRENCY}
+STR_0801_COST :{RED}Coste: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Ingreso: {CURRENCY}
+STR_0803_INCOME :{GREEN}Ingreso: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Transferir: {CURRENCY}
+STR_FEEDER :{YELLOW}Transferir: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Coste estimado: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Ingreso estimado: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}No se puede realzar tierra aquí...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}No se puede rebajar tierra aquí...
+STR_080A_ROCKS :Rocas
+STR_080B_ROUGH_LAND :Tierra árida
+STR_080C_BARE_LAND :Tierra desnuda
+STR_080D_GRASS :Césped
+STR_080E_FIELDS :Campos
+STR_080F_SNOW_COVERED_LAND :Tierra cubierta por nieve
+STR_0810_DESERT :Desierto
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Tierra inclinada en dirección errónea
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Combinación de tramos imposible
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}La excavación dañaría el túnel
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Ya está al nivel del mar
+STR_1004_TOO_HIGH :{WHITE}Demasiado alto
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Tramo de vía no apropiado
+STR_1007_ALREADY_BUILT :{WHITE}...ya construído
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Se debe retirar primero tramo de vía
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Construcción de ferrocarril
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Construcciòn Línea Eléctrica de Ferrocarril
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Construcción de monorraíl
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}Construcción de tren de levitación magnética
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Seleccione puente de raíl
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}No se puede construir depósito aquí...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}No se puede construir estación de tren aquí...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}No se pueden construir señales aquí...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}No se pueden construir vías del tren aquí...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}No se pueden retirar vías del tren aquí...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}No se pueden retirar señales de aquí...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Orientación del depósito
+STR_1015_RAILROAD_CONSTRUCTION :Construcción de ferrocarril
+STR_TOOLB_ELRAIL_CONSTRUCTION :Construcción Línea Eléctrica de Ferrocarril
+STR_1016_MONORAIL_CONSTRUCTION :Construcción de monorraíl
+STR_1017_MAGLEV_CONSTRUCTION :Construcción de maglev
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Construir tramo de ferrocarril
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Construir depósito de trenes (para construir y despachar trenes)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Construir estación de ferrocarril
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Construir señales de ferrocarril
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Construir puente de ferrocarril
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Construir túnel ferroviario
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Cambiar entre construir/retirar tramos y señales de ferrocarril
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Selección de puente - click en el puente elegido para construirlo
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Seleccione la orientación del depósito de trenes
+STR_1021_RAILROAD_TRACK :Vía del tren
+STR_1023_RAILROAD_TRAIN_DEPOT :Depósito de trenes
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...otra compañía posee el área
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :Vía del tren con señales normales
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :Vía del tren con pre-señales
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :Vía del tren con señales de salida
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :Vía del tren con señales combo
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Ha de retirar carretera primero
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Trabajos en la carretera en progreso
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Construcción de carretera
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Elige puente de carretera
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}No se puede construir carretera aquí...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}No se puede retirar carretera de aquí...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Orientación del depósito
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}No se puede construir depósito de carretera aquí...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}No se puede construir estación de autobuses...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}No se puede construir estación de camiones...
+STR_180A_ROAD_CONSTRUCTION :Construcción de carretera
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Construir sección de carretera
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Construir depósito de carretera (para construir y despachar vehículos)
+STR_180D_BUILD_BUS_STATION :{BLACK}Construir estación de autobús
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Construir estación de carga para camiones
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Construir puente de carretera
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Construir túnel de carretera
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Cambiar entre construir/retirar carretera
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Elegir orientación del depósito de carretera
+STR_1814_ROAD :Road
+STR_1815_ROAD_WITH_STREETLIGHTS :Carretera con farolas
+STR_1816_TREE_LINED_ROAD :Carretera arbolada
+STR_1817_ROAD_VEHICLE_DEPOT :Depósito de carretera
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :Paso a nivel
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Poblaciones
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}El edificio debe demolerse primero
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}Habitantes: {ORANGE}{COMMA}{BLACK} Casas: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Renombrar población
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}No se puede renombrar población...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} las autoridades locales rechazan esto
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Nombres de población - haga click sobre el nombre para centrar la vista en la población
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centrar la vista sobre la población
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Cambiar nombre de la población
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Pasajeros último mes: {ORANGE}{COMMA}{BLACK} máx: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Correo último mes: {ORANGE}{COMMA}{BLACK} máx: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Bloque alto de oficinas
+STR_2010_OFFICE_BLOCK :Bloque de oficinas
+STR_2011_SMALL_BLOCK_OF_FLATS :Bloque de viviendas pequeño
+STR_2012_CHURCH :Iglesia
+STR_2013_LARGE_OFFICE_BLOCK :Gran bloque de oficinas
+STR_2014_TOWN_HOUSES :Casas de la población
+STR_2015_HOTEL :Hotel
+STR_2016_STATUE :Estatua
+STR_2017_FOUNTAIN :Fuente
+STR_2018_PARK :Parque
+STR_2019_OFFICE_BLOCK :Bloque de oficinas
+STR_201A_SHOPS_AND_OFFICES :Tiendas y oficinas
+STR_201B_MODERN_OFFICE_BUILDING :Edifício de oficinas moderno
+STR_201C_WAREHOUSE :Almacén
+STR_201D_OFFICE_BLOCK :Bloque de oficinas
+STR_201E_STADIUM :Estadio
+STR_201F_OLD_HOUSES :Casas viejas
+STR_2020_LOCAL_AUTHORITY :{BLACK}Autoridad local
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Mostrar información sobre autoridades locales
+STR_2022_LOCAL_AUTHORITY :{WHITE}{TOWN} autoridad local
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Ranking de empresas de transporte:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Subvenciones
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Se ofrecen subvenciones por llevar:
+STR_2027_FROM_TO :{ORANGE}{STRING} desde {STRING} a {STRING}
+STR_2028_BY :{YELLOW} (antes de {DATE_SHORT})
+STR_202A_NONE :{ORANGE}Ninguna
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Líneas ya subvencionadas:
+STR_202C_FROM_TO :{ORANGE}{STRING} desde {STATION} a {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, hasta {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}Oferta de subsidio caducada:{}{}{STRING} de {STRING} a {STRING} ya no conlleva una subvención.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Subvención retirada:{}{}Servicio de {STRING} desde {STATION} a {STATION} ya no está subvencionado.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Se ofrece subvención en la línea:{}{}El primer {STRING} que cubra la línea desde {STRING} a {STRING} recibirá una subvención durante un año por parte de las autoridades locales!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}¡Subvención otorgada a {COMPANY}!{}{}¡Servicio de {STRING} desde {STATION} a {STATION} pagará el 50% más durante un año!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}¡Subvención otorgada a {COMPANY}!{}{}¡Servicio de {STRING} desde {STATION} a {STATION} pagará tasa doble durante un año!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}¡Subvención otorgada a {COMPANY}!{}{}¡Servicio de {STRING} desde {STATION} a {STATION} pagará tasa triple durante un año!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}¡Subvención otorgada a {COMPANY}!{}{}¡Servicio de {STRING} desde {STATION} a {STATION} pagará tasa cuádruple durante un año!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} la autoridad local rechaza la construcción de otro aeropuerto en esta población
+STR_2036_COTTAGES :Cabañas
+STR_2037_HOUSES :Casas
+STR_2038_FLATS :Apartamentos
+STR_2039_TALL_OFFICE_BLOCK :Bloque alto de oficinas
+STR_203A_SHOPS_AND_OFFICES :Tiendas y oficinas
+STR_203B_SHOPS_AND_OFFICES :Tiendas y oficinas
+STR_203C_THEATER :Teatro
+STR_203D_STADIUM :Estadio
+STR_203E_OFFICES :Oficinas
+STR_203F_HOUSES :Casas
+STR_2040_CINEMA :Cine
+STR_2041_SHOPPING_MALL :Centro comercial
+STR_2042_DO_IT :{BLACK}Hágalo
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}Lista de cosas a hacer en esta población - pulse sobre cada línea para obtener más detalles
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Hacer lo que se ha marcado en la opción anterior
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Acciones disponibles:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Pequeña campaña publicitaria
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Mediana campaña publicitaria
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Gran campaña publicitaria
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Pagar la reconstrucción de las carreteras locales
+STR_204A_BUILD_STATUE_OF_COMPANY :Poner una estatua al dueño de la empresa
+STR_204B_FUND_NEW_BUILDINGS :Pagar la construcción de nuevos edificios
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Comprar la exclusiva de los servicios de transporte
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Sobornar la autoridad local
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Iniciar una pequeña campaña publicitaria local, para atraer más pasajeros y carga a sus servicios de transporte.{} Coste: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Iniciar una mediana campaña publicitaria local, para atraer más pasajeros y carga a sus servicios de transporte.{} Coste: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Iniciar una gran campaña publicitaria local, para atraer más pasajeros y carga a sus servicios de transporte.{} Coste: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} Pagar la reconstrucción de las carreteras locales. Causa una considerable complicación del tráfico durante 6 meses.{} Coste: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Construye una estatua en honor a su empresa.{} Coste: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Pagar la construcción de nuevos edificios comerciales en la población.{} Coste: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Compre la exclusiva durante 1 año de los derechos de transporte en esta población. Las autoridades solo permitirán el uso de las estaciones de su empresa.{} Coste: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Soborne a las autoridades locales para aumentar su ranking, con el riesgo de una severa penalización si es descubierto.{} Coste: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}Colapso circulatorio en {TOWN}!{}{}¡Programa de reconstrucción de carreteras patrocinado por {COMPANY} causa 6 meses de problemas a los conductores!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (bajo construcción)
+STR_2059_IGLOO :Iglú
+STR_205A_TEPEES :Tipis
+STR_205B_TEAPOT_HOUSE :Casa de Té
+STR_205C_PIGGY_BANK :Banco Cerdito
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN}, {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Paisaje
+STR_2800_PLANT_TREES :Plantar árboles
+STR_2801_PLACE_SIGN :Colocar señal
+STR_2802_TREES :{WHITE}Ãrboles
+STR_2803_TREE_ALREADY_HERE :{WHITE}...ya hay árboles aquí
+STR_2804_SITE_UNSUITABLE :{WHITE}...sitio no apropiado
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}No se pueden plantar árboles aquí...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...demasiadas señales
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}No se puede colocar una señal aquí...
+STR_280A_SIGN :Sign
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Editar texto de la señal
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}No se puede cambiar el nombre de la señal...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Seleccione el tipo de árboles a plantar
+STR_280E_TREES :Ãrboles
+STR_280F_RAINFOREST :Selváticos
+STR_2810_CACTUS_PLANTS :Cactus
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Selección de estación de tren
+STR_3001_AIRPORT_SELECTION :{WHITE}Selección de aeropuerto
+STR_3002_ORIENTATION :{BLACK}Orientación
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Número de andenes
+STR_3004_PLATFORM_LENGTH :{BLACK}Longitud de andén
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Demasiado cerca de otra estación de tren
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}djunta más de una estación/zona de carga existente
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}Demasiadas estaciones/zonas de carga en esta población
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}Demasiadas estaciones/zonas de carga
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Demasiadas paradas de Autobús
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}Demasiadas zonas de carga
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Demasiado cerca de otra estación/zona de carga
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Primero debe demolerse estación de tren
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Demasiado cerca de otro aeropuerto
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Primero debe demolerse el aeropuerto
+
+STR_3030_RENAME_STATION_LOADING :Renombrar estación/zona de carga
+STR_3031_CAN_T_RENAME_STATION :{WHITE}No se puede renombrar estación...
+STR_3032_RATINGS :{BLACK}Ranking
+STR_3033_ACCEPTS :{BLACK}Acepta
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}Ranking local de servicios de transporte:
+
+############ range for rating starts
+STR_3035_APPALLING :Espantoso
+STR_3036_VERY_POOR :Muy pobre
+STR_3037_POOR :Pobre
+STR_3038_MEDIOCRE :Mediocre
+STR_3039_GOOD :Bueno
+STR_303A_VERY_GOOD :Muy bueno
+STR_303B_EXCELLENT :Excelente
+STR_303C_OUTSTANDING :Excepcional
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} ya no acepta {STRING}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} ya no acepta {STRING} ni {STRING}
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} acepta ahora {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} acepta ahora {STRING} y {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Or. estación de autobús
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Or. estación de camiones
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Primero debe demolerse estación de autobús
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Primero debe demolerse estación de camiones
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Estaciones
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Ninguna -
+STR_304B_SITE_UNSUITABLE :{WHITE}...lugar inapropiado
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Demasiado cerca de otro muelle
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Primero debe demolerse el muelle
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Elige orientación de la estación de tren
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Elige número de andenes de la estación de tren
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Elige longitud de la estación de tren
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Elige la orientación de la estación de autobús
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Elige la orientación de la estación de camiones
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Centrar vista en la posición de la estación
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Ver calificación de la estación
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Cambiar nombre de la estación
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Mostrar lista de carga aceptada
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Nombres de estación - click en nombre para centrar vista en la estación
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Elige tamaño/tipo de aeropuerto
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :Estación de tren
+STR_305F_AIRCRAFT_HANGAR :Hangar de aeroplanos
+STR_3060_AIRPORT :Aeropuerto
+STR_3061_TRUCK_LOADING_AREA :Zona de carga de camiones
+STR_3062_BUS_STATION :Estación de autobús
+STR_3063_SHIP_DOCK :Muelle
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Iluminar área de alcance del lugar propuesto
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}No iluminar área de alcance del lugar propuesto
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Iluminar área de alcance
+STR_3068_DOCK :{WHITE}Muelle
+STR_3069_BUOY :Boya
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...boya en medio
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...estación demasiado extendida
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...desactivada estaciones no uniformes
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Manten pulsado CTRL para seleccionar varios elementos
+
+STR_UNDEFINED :(cadena sin determinar)
+STR_STAT_CLASS_DFLT :Estación por defecto
+STR_STAT_CLASS_WAYP :Puntos de paso
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Orientación del astillero
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...debe ser construida sobre el agua
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}No se puede contruir un astillero aquí...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Selecciona orientación del astillero
+STR_3804_WATER :Agua
+STR_3805_COAST_OR_RIVERBANK :Costa o rivera
+STR_3806_SHIP_DEPOT :Astillero
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...No se puede construir sobre el agua
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Guardar Juego
+STR_4001_LOAD_GAME :{WHITE}Cargar Juego
+STR_4002_SAVE :{BLACK}Guardar
+STR_4003_DELETE :{BLACK}Borrar
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} megabytes libres
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}No es posible leer la unidad
+STR_4007_GAME_SAVE_FAILED :{WHITE}Error guardando juego
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}No es posible borrar el fichero
+STR_4009_GAME_LOAD_FAILED :{WHITE}Carga de juego erronea
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}Listado de unidades, directorios y juegos guardados
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Nombre seleccionado actualmente para el juego guardado
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Borrar el juego guardado seleccionado
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Guarda el juego actual, usando el nombre seleccionado
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Seleccione Nuevo Tipo de Juego
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Seleccione escenario (verde), juegos preestablecidos-set (azul), o juego al azar
+STR_4010_GENERATE_RANDOM_NEW_GAME :Generar juego nuevo al azar
+STR_4011_LOAD_HEIGHTMAP :{WHITE}Cargar Mapas de altura
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} en medio
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :Mina de Carbón
+STR_4803_POWER_STATION :Central Eléctrica
+STR_4804_SAWMILL :Aserradero
+STR_4805_FOREST :Bosque
+STR_4806_OIL_REFINERY :Refinería
+STR_4807_OIL_RIG :Torre Petrolera
+STR_4808_FACTORY :Fábrica
+STR_4809_PRINTING_WORKS :Imprenta
+STR_480A_STEEL_MILL :Acería
+STR_480B_FARM :Granja
+STR_480C_COPPER_ORE_MINE :Mina de Cobre
+STR_480D_OIL_WELLS :Pozos Petrolíferos
+STR_480E_BANK :Banco
+STR_480F_FOOD_PROCESSING_PLANT :Planta Procesadora de Alimentos
+STR_4810_PAPER_MILL :Papelera
+STR_4811_GOLD_MINE :Mina de Oro
+STR_4812_BANK :Banco
+STR_4813_DIAMOND_MINE :Mina de Diamantes
+STR_4814_IRON_ORE_MINE :Mina de Hierro
+STR_4815_FRUIT_PLANTATION :Platanción de frutas
+STR_4816_RUBBER_PLANTATION :Plantación de Caucho
+STR_4817_WATER_SUPPLY :Suministro de Agua
+STR_4818_WATER_TOWER :Torre de Agua
+STR_4819_FACTORY :Fábrica
+STR_481A_FARM :Granja
+STR_481B_LUMBER_MILL :Aserradero
+STR_481C_COTTON_CANDY_FOREST :Bosque de Algodón de azúcar
+STR_481D_CANDY_FACTORY :Fábrica de Dulces
+STR_481E_BATTERY_FARM :Granja de Pilas
+STR_481F_COLA_WELLS :Pozos de Cola
+STR_4820_TOY_SHOP :Tienda de Juguete
+STR_4821_TOY_FACTORY :Fábrica de Juguetes
+STR_4822_PLASTIC_FOUNTAINS :Fuestes de Plástico
+STR_4823_FIZZY_DRINK_FACTORY :Fábrica de Refrescos
+STR_4824_BUBBLE_GENERATOR :Generador de Burbujas
+STR_4825_TOFFEE_QUARRY :Cantera de caramelos
+STR_4826_SUGAR_MINE :Mina de Azúcar
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Requiere: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Requiere: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Requiere: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Producción mes anterior:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% transportado)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centrar la vista sobre la industria
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Nuevo {STRING} bajo construcción cerca de {TOWN}!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Nuevo {STRING} está siendo plantado cerca de {TOWN}!
+STR_482F_COST :{BLACK}Coste: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}No se puede construir este tipo de industria aquí...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...sólo se puede plantar un bosque sobre la línea nevada
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}¡La industria de {INDUSTRY} anuncia cierre inminente!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}Problemas con el suministro causa que {INDUSTRY} anuncie su cierre inminente!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}¡La falta de árboles cercanos causa que {INDUSTRY} anuncie su cierre inmediato!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}¡{INDUSTRY} incrementa su producción!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}¡Nueva veta de carbón encontrada en {INDUSTRY}!{}¡Se espera doblar la producción!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}¡Nuevas reservas de petróleo encontradas en {INDUSTRY}!{}¡Se espera doblar la producción!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}¡Nuevos métodos agrícolas en {INDUSTRY} esperan doblar la producción!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}La producción de {INDUSTRY} desciende un 50%
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}¡Plaga de insectos causa estragos en {INDUSTRY}!{}Producción por debajo del 50%
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...sólo se puede colocar cerca de los bordes del mapa
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}¡La producción de {STRING} en {INDUSTRY} sube un {COMMA}%!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}¡La producción de {STRING} en {INDUSTRY} desciende un {COMMA}%!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Tren en túnel
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Vehículo de carretera en túnel
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Otro túnel en el camino
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}No se puede excavar en la tierra al otro lado del túnel
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Primero debe demolerse el túnel
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Primero debe demolerse el puente
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}No se puede comenzar y acabar en la misma posición
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Se requiere tierra a nivel o agua bajo el puente
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}Comienzo y final deben estar en línea
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Lugar inapropiado para entrada de túnel
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Suspensión, Acero
+STR_500F_GIRDER_STEEL :Tirantes, Acero
+STR_5010_CANTILEVER_STEEL :Colgante, Acero
+STR_5011_SUSPENSION_CONCRETE :Suspensión, Hormigón
+STR_5012_WOODEN :Madera
+STR_5013_CONCRETE :Hormigón
+STR_5014_TUBULAR_STEEL :Tubular, Acero
+STR_BRIDGE_TUBULAR_SILICON :Tubular, Silicio
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}No se puede construir puente aquí...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}No se puede construir túnel aquí...
+STR_5017_RAILROAD_TUNNEL :Túnel de tren
+STR_5018_ROAD_TUNNEL :Túnel de carretera
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Puente de tren de acero suspendido
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Puente de tren de acero con tirantes
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Puente de tren colgante de acero
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Puente de tren de hormigón suspendido reforzado
+STR_501F_WOODEN_RAIL_BRIDGE :Puente de tren de madera
+STR_5020_CONCRETE_RAIL_BRIDGE :Puente de tren de hormigón
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Puente de carretera de acero suspendido
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Puente de carretera de acero con tirantes
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Puente de carretera colgante de acero
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Puente de carretera de hormigón suspendido reforzado
+STR_5025_WOODEN_ROAD_BRIDGE :Puente de carretera de madera
+STR_5026_CONCRETE_ROAD_BRIDGE :Puente de carretera de hormigón
+STR_5027_TUBULAR_RAIL_BRIDGE :Puente de tren tubular
+STR_5028_TUBULAR_ROAD_BRIDGE :Puente de carretera tubular
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Objeto en medio
+STR_5801_TRANSMITTER :Transmisor
+STR_5802_LIGHTHOUSE :Faro
+STR_5803_COMPANY_HEADQUARTERS :Sede de la empresa
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...la sede de la empresa está en medio
+STR_5805_COMPANY_OWNED_LAND :Terreno propiedad de una empresa
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}No es posible comprar este terreno...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...ya es de su propiedad!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Sin nombre
+STR_SV_TRAIN_NAME :Tren {COMMA}
+STR_SV_ROADVEH_NAME :Vehículo de carretera {COMMA}
+STR_SV_SHIP_NAME :Barco {COMMA}
+STR_SV_AIRCRAFT_NAME :Aeronave {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :{STRING} Norte
+STR_SV_STNAME_SOUTH :{STRING} Sur
+STR_SV_STNAME_EAST :{STRING} Este
+STR_SV_STNAME_WEST :{STRING} Oeste
+STR_SV_STNAME_CENTRAL :{STRING} Central
+STR_SV_STNAME_TRANSFER :{STRING} Intercambio
+STR_SV_STNAME_HALT :{STRING} Parada
+STR_SV_STNAME_VALLEY :Valle de {STRING}
+STR_SV_STNAME_HEIGHTS :Cumbres de {STRING}
+STR_SV_STNAME_WOODS :Arboleda de {STRING}
+STR_SV_STNAME_LAKESIDE :Lago de {STRING}
+STR_SV_STNAME_EXCHANGE :{STRING} Intercambio
+STR_SV_STNAME_AIRPORT :Aeropuerto de {STRING}
+STR_SV_STNAME_OILFIELD :Campo petrolífero de {STRING}
+STR_SV_STNAME_MINES :Minas de {STRING}
+STR_SV_STNAME_DOCKS :Muelles de {STRING}
+STR_SV_STNAME_BUOY_1 :{STRING} Boya 1
+STR_SV_STNAME_BUOY_2 :{STRING} Boya 2
+STR_SV_STNAME_BUOY_3 :{STRING} Boya 3
+STR_SV_STNAME_BUOY_4 :{STRING} Boya 4
+STR_SV_STNAME_BUOY_5 :{STRING} Boya 5
+STR_SV_STNAME_BUOY_6 :{STRING} Boya 6
+STR_SV_STNAME_BUOY_7 :{STRING} Boya 7
+STR_SV_STNAME_BUOY_8 :{STRING} Boya 8
+STR_SV_STNAME_BUOY_9 :{STRING} Boya 9
+STR_SV_STNAME_ANNEXE :{STRING} Anexo
+STR_SV_STNAME_SIDINGS :Proximidades de {STRING}
+STR_SV_STNAME_BRANCH :Ramal de {STRING}
+STR_SV_STNAME_UPPER :{STRING} Alto
+STR_SV_STNAME_LOWER :{STRING} Bajo
+STR_SV_STNAME_HELIPORT :Helipuerto de {STRING}
+STR_SV_STNAME_FOREST :Bosque de {STRING}
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Nivel de dificultad
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Guardar
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Fácil
+STR_6802_MEDIUM :{BLACK}Media
+STR_6803_HARD :{BLACK}Difícil
+STR_6804_CUSTOM :{BLACK}Personalizada
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}Nº Máximo de jugadores: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Tiempo de inicio de la competencia: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}Nº. de poblaciones: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}Nº. de industrias: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Préstamo inicial máximo: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Tasa de interés inicial: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Costes de Operación de Vehículo: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Velocidad de construcción de la competencia: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Inteligencia de la competencia: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Averías de Vehículos: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Multiplicador de Subvenciones: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Coste de la construcción: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Tipo de terreno: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Cantidad de mar/lagos: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Economía: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Marcha atrás trenes: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Desastres: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Actitud de la autoridades sobre reestructuraciones: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :Ninguno
+STR_6816_LOW :Baja
+STR_6817_NORMAL :Normal
+STR_6818_HIGH :Alta
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Muy lenta
+STR_681C_SLOW :Lenta
+STR_681D_MEDIUM :Media
+STR_681E_FAST :Rápida
+STR_681F_VERY_FAST :Muy rápida
+STR_VERY_LOW :Muy bajo
+STR_6820_LOW :Baja
+STR_6821_MEDIUM :Media
+STR_6822_HIGH :Alta
+STR_6823_NONE :Ninguna
+STR_6824_REDUCED :Reducidas
+STR_6825_NORMAL :Normales
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Muy llano
+STR_682B_FLAT :Llano
+STR_682C_HILLY :Ondulado
+STR_682D_MOUNTAINOUS :Montañoso
+STR_682E_STEADY :Estable
+STR_682F_FLUCTUATING :Fluctuante
+STR_6830_IMMEDIATE :Inmediatamente
+STR_6831_3_MONTHS_AFTER_PLAYER :3 meses después del jugador
+STR_6832_6_MONTHS_AFTER_PLAYER :6 meses después del jugador
+STR_6833_9_MONTHS_AFTER_PLAYER :9 meses después del jugador
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :Al final de la línea y estaciones
+STR_6835_AT_END_OF_LINE_ONLY :Solo al final de la línea
+STR_6836_OFF :No
+STR_6837_ON :Si
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Ver gráfica de altas puntuaciones
+STR_6839_PERMISSIVE :Permisiva
+STR_683A_TOLERANT :Tolerante
+STR_683B_HOSTILE :Hostil
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Jugador {COMMA})
+STR_7004_NEW_FACE :{BLACK}Nueva Cara
+STR_7005_COLOR_SCHEME :{BLACK}Esquema Color
+STR_7006_COLOR_SCHEME :{GOLD}Esquema color:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Nuevo esquema de colores
+STR_7008_COMPANY_NAME :{BLACK}Nombre Empresa
+STR_7009_PRESIDENT_NAME :{BLACK}Nombre Presid.
+STR_700A_COMPANY_NAME :Nombre Empresa
+STR_700B_PRESIDENT_S_NAME :Nombre del Presidente
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}No se puede cambiar el nombre de la empresa...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}No se puede cambiar el nombre del presidente...
+STR_700E_FINANCES :{WHITE}{COMPANY} Finanzas {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Gastos/Ingresos
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Construcción
+STR_7012_NEW_VEHICLES :{GOLD}Nuevos vehículos
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Coste operación Trenes
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Coste operación Vehículos
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Coste operación Aeroplanos
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Coste operación Barcos
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Mantenimiento de inmuebles
+STR_7018_TRAIN_INCOME :{GOLD}Ingresos Trenes
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Ingresos Vehículos
+STR_701A_AIRCRAFT_INCOME :{GOLD}Ingresos Aeroplanos
+STR_701B_SHIP_INCOME :{GOLD}Ingresos Barcos
+STR_701C_LOAN_INTEREST :{GOLD}Intereses de Préstamo
+STR_701D_OTHER :{GOLD}Otros
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Total:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Gráfico de Ingresos
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Gráfico de Beneficio Operativo
+STR_7026_BANK_BALANCE :{WHITE}Saldo en Banco
+STR_7027_LOAN :{WHITE}Préstamo
+STR_MAX_LOAN :{WHITE}Préstamo Máx: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}Pedir Préstamo {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Pagar Préstamo {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...máxima cantidad de préstamo permitida es {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}No se puede pedir más prestamo...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...no hay préstamo que pagar
+STR_702E_REQUIRED :{WHITE}...{CURRENCY} requerido
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}No es posible pagar préstamo...
+STR_INSUFFICIENT_FUNDS :{WHITE}No se puede dar dinero que ha sido prestado de un banco...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Selecciona nueva cara para el presidente
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Cambiar los colores de la empresa
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Cambiar el nombre del presidente
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Cambiar el nombre de la empresa
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Click en esquema de color elegido
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Incrementar préstamo
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Pagar parte del préstamo
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(Presidente)
+STR_7038_INAUGURATED :{GOLD}Inaugurado: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Vehiculos:
+STR_TRAINS :{WHITE}{COMMA} tren{P "" es}
+STR_ROAD_VEHICLES :{WHITE}{COMMA} veh{P "" s}. carret{P er ""}a
+STR_AIRCRAFT :{WHITE}{COMMA} aeroplano{P "" s}
+STR_SHIPS :{WHITE}{COMMA} barco{P "" s}
+STR_7042_NONE :{WHITE}Ninguno
+STR_7043_FACE_SELECTION :{WHITE}Selección de cara
+STR_7044_MALE :{BLACK}Hombre
+STR_7045_FEMALE :{BLACK}Mujer
+STR_7046_NEW_FACE :{BLACK}Cara Nueva
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Cancelar selección de nueva cara
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Aceptar selección de nueca cara
+STR_7049_SELECT_MALE_FACES :{BLACK}Selecciona cara másculina
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Selecciona cara femenina
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Generar cara al azar
+STR_704C_KEY :{BLACK}Clave
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Mostrar clave en gráficos
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Clave de los gráficos
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Click aquí para intercambiar la entrada de la compañía
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Unidades de carga entregadas
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Calificaciones de actuación de compañías (tasa máx.=1000)
+STR_7052_COMPANY_VALUES :{WHITE}Valores de las empresas
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Ranking de Empresas
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}¡Empresa en problemas!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} debe ser vendida o declarada en bancarrota a no ser que mejore su actuación!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(Presidente)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}¡Absorción de empresa de transportes!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}¡{COMPANY} ha sido vendida a {COMPANY} por {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Estamos buscando una empresa de transportes para adquirir la nuestra{}{}¿Deseas comprar {COMPANY} por {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}¡Bancarrota!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} ha sido cerrada por acreedores y todos sus activos se han vendido!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}¡Nueva empresa de transportes!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} comienza su construcción cerca de {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}No se puede comprar la empresa...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Tasas de pago por carga
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Días en tránsito
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Pago por entregar 10 unidades (o 1,000 litros) de mercancía a una distancia de 20 cuadros
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Intercambiar gráfico para tipo de carga
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Ingeniero
+STR_7067_TRAFFIC_MANAGER :Gerente de tráfico
+STR_7068_TRANSPORT_COORDINATOR :Coordinador de transporte
+STR_7069_ROUTE_SUPERVISOR :Supervisor de ruta
+STR_706A_DIRECTOR :Director
+STR_706B_CHIEF_EXECUTIVE :Jefe ejecutivo
+STR_706C_CHAIRMAN :Director general
+STR_706D_PRESIDENT :Presidente
+STR_706E_TYCOON :Magnate
+STR_706F_BUILD_HQ :{BLACK}Construir Sede
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Construir sede de la empresa / ver sede de la empresa
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Reubica la sede de la empresa a cualquier otro lugar, con el coste del 1% del valor total de la empresa
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}No se puede construir la sede de la empresa...
+STR_7072_VIEW_HQ :{BLACK}Ver Sede
+STR_RELOCATE_HQ :{BLACK}Reubicar Sede
+STR_COMPANY_PASSWORD :{BLACK}Contraseña
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Protege por contraseña tu empresa para prevenir que usuarios no autorizados se unan a ella.
+STR_SET_COMPANY_PASSWORD :Configurar contraseña de empresa
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}¡Recesión Mundial!{}{}¡Los expertos financieros son pesimistas mientras la economía se hunde!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}¡Fin de la Recesión!{}{}¡Mejora en el comercio da ánimos a las industrias mientras la economía se fortalece!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Cambiar entre tamaño de ventana grande/pequeño
+STR_7076_COMPANY_VALUE :{GOLD}Valor de la empresa: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Comprar un 25% de sus acciones
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Vender 25% de acciones
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Comprar 25% de acciones de esta empresa
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Vender 25% acciones de esta empresa
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}No se puede comprar el 25% de acciones...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}No se puede vender el 25% de acciones...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% propiedad de {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% propiedad de {COMPANY}{} {COMMA}% propiedad de {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} ha sido comprada por {COMPANY}!
+STR_7080_PROTECTED :{WHITE}Esta empresa todavía no dispone acciones a la venta...
+
+STR_LIVERY_DEFAULT :Estación normal
+STR_LIVERY_STEAM :Locomotora a Vapor
+STR_LIVERY_DIESEL :Locomotora Diesel
+STR_LIVERY_ELECTRIC :Locomotora Eléctrica
+STR_LIVERY_MONORAIL :Locomotora Monorail
+STR_LIVERY_MAGLEV :Locomotora Maglev
+STR_LIVERY_DMU :DMU
+STR_LIVERY_EMU :EMU
+STR_LIVERY_PASSENGER_WAGON_STEAM :Vagón Pasajeros (Vapor)
+STR_LIVERY_PASSENGER_WAGON_DIESEL :Vagón Pasajeros (Diesel)
+STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Vagón Pasajeros (Electrico)
+STR_LIVERY_FREIGHT_WAGON :Vagón de Carga
+STR_LIVERY_BUS :Bus
+STR_LIVERY_TRUCK :Camión
+STR_LIVERY_PASSENGER_SHIP :Ferry de Pasajeros
+STR_LIVERY_FREIGHT_SHIP :Barco de Carga
+STR_LIVERY_HELICOPTER :Helicoptero
+STR_LIVERY_SMALL_PLANE :Aeroplano Pequeño
+STR_LIVERY_LARGE_PLANE :Aeroplano Grande
+
+STR_LIVERY_GENERAL_TIP :{BLACK}Mostrar esquema de colores general
+STR_LIVERY_TRAIN_TIP :{BLACK}Ver esquema de color de los trenes
+STR_LIVERY_ROADVEH_TIP :{BLACK}Ver esquema de color de los vehículos de carretera
+STR_LIVERY_SHIP_TIP :{BLACK}Ver esquema de color de los barcos
+STR_LIVERY_AIRCRAFT_TIP :{BLACK}Mostrar esquema de color de aeronaves
+STR_LIVERY_PRIMARY_TIP :{BLACK}Selecciona el color primario para el esquema seleccionado
+STR_LIVERY_SECONDARY_TIP :{BLACK}Selecciona el color secundario para el esquema seleccionado
+STR_LIVERY_PANEL_TIP :{BLACK}Selecciona un esquema de color para cambiarlo, o selecciona varios pulsandoh CTRL+click. Pulsa en la caja para cambiar el uso del esquema
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (Vapor)
+STR_8001_MJS_250_DIESEL :MJS 250 (Diesel)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut Diésel
+STR_8006_POWERNAUT_DIESEL :Powernaut Diésel
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (Vapor)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (Vapor)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (Vapor)
+STR_800A_SH_8P_STEAM :SH '8P' (Vapor)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (Diésel)
+STR_800C_DASH_DIESEL :'Dash' (Diesel)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (Diésel)
+STR_800E_UU_37_DIESEL :UU '37' (Diésel)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (Diésel)
+STR_8010_CS_4000_DIESEL :CS 4000 (Diésel)
+STR_8011_CS_2400_DIESEL :CS 2400 (Diésel)
+STR_8012_CENTENNIAL_DIESEL :Centennial (Diésel)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (Diésel)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (Diésel)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (Diésel)
+STR_8016_SH_125_DIESEL :SH '125' (Diésel)
+STR_8017_SH_30_ELECTRIC :SH '30' (Eléctrica)
+STR_8018_SH_40_ELECTRIC :SH '40' (Eléctrica)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (Eléctrica)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (Eléctrica)
+STR_801B_PASSENGER_CAR :Vagón de Pasajeros
+STR_801C_MAIL_VAN :Furgón de Correos
+STR_801D_COAL_CAR :Vagón de Carbón
+STR_801E_OIL_TANKER :Cisterna de Petróleo
+STR_801F_LIVESTOCK_VAN :Vagón de Ganado
+STR_8020_GOODS_VAN :Vagón de Mercancía
+STR_8021_GRAIN_HOPPER :Vagoneta de Grano
+STR_8022_WOOD_TRUCK :Vagón de Madera
+STR_8023_IRON_ORE_HOPPER :Vagoneta de Mineral de Hierro
+STR_8024_STEEL_TRUCK :Vagón de Acero
+STR_8025_ARMORED_VAN :Vagón Blindado
+STR_8026_FOOD_VAN :Vagón de Alimento
+STR_8027_PAPER_TRUCK :Vagón de Papel
+STR_8028_COPPER_ORE_HOPPER :Vagoneta de Mineral de Cobre
+STR_8029_WATER_TANKER :Cisterna de Agua
+STR_802A_FRUIT_TRUCK :Vagón de Fruta
+STR_802B_RUBBER_TRUCK :Vagón de Caucho
+STR_802C_SUGAR_TRUCK :Vagón de Azúcar
+STR_802D_COTTON_CANDY_HOPPER :Vagoneta de Algodón de azúcar
+STR_802E_TOFFEE_HOPPER :Vagoneta de caramelos
+STR_802F_BUBBLE_VAN :Vagón de Burbujas
+STR_8030_COLA_TANKER :Cisterna de Cola
+STR_8031_CANDY_VAN :Vagón de Dulces
+STR_8032_TOY_VAN :Vagón de Juguetes
+STR_8033_BATTERY_TRUCK :Vagón de Pilas
+STR_8034_FIZZY_DRINK_TRUCK :Vagón de Refrescos
+STR_8035_PLASTIC_TRUCK :Vagón de Plásticos
+STR_8036_X2001_ELECTRIC :'X2001' (Electrico)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Electrico)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :Vagón de Pasajeros
+STR_803A_MAIL_VAN :Furgón de Correos
+STR_803B_COAL_CAR :Vagón de Carbón
+STR_803C_OIL_TANKER :Cisterna de Petróleo
+STR_803D_LIVESTOCK_VAN :Vagón de Ganado
+STR_803E_GOODS_VAN :Vagón de Mercancía
+STR_803F_GRAIN_HOPPER :Vagoneta de Grano
+STR_8040_WOOD_TRUCK :Vagón de Madera
+STR_8041_IRON_ORE_HOPPER :Vagoneta de Mineral de Hierro
+STR_8042_STEEL_TRUCK :Vagón de Acero
+STR_8043_ARMORED_VAN :Vagón de Blindado
+STR_8044_FOOD_VAN :Vagón de Alimento
+STR_8045_PAPER_TRUCK :Vagón de Papel
+STR_8046_COPPER_ORE_HOPPER :Vagoneta de Mineral de Cobre
+STR_8047_WATER_TANKER :Cisterna de Agua
+STR_8048_FRUIT_TRUCK :Vagón de Fruta
+STR_8049_RUBBER_TRUCK :Vagón de Caucho
+STR_804A_SUGAR_TRUCK :Vagón de Azúcar
+STR_804B_COTTON_CANDY_HOPPER :Vagoneta de Algodón de azúcar
+STR_804C_TOFFEE_HOPPER :Vagoneta de caramelos
+STR_804D_BUBBLE_VAN :Vagón de Burbujas
+STR_804E_COLA_TANKER :Cisterna de Cola
+STR_804F_CANDY_VAN :Vagón de Dulces
+STR_8050_TOY_VAN :Vagón de Juguetes
+STR_8051_BATTERY_TRUCK :Vagón de Pilas
+STR_8052_FIZZY_DRINK_TRUCK :Vagón de Refrescos
+STR_8053_PLASTIC_TRUCK :Vagón de Plásticos
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (Eléctrica)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (Eléctrica)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (Eléctrica)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (Eléctrica)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :Vagón de Pasajeros
+STR_805A_MAIL_VAN :Furgón de Correos
+STR_805B_COAL_CAR :Vagón de Carbón
+STR_805C_OIL_TANKER :Cisterna de Petróleo
+STR_805D_LIVESTOCK_VAN :Vagón de Ganado
+STR_805E_GOODS_VAN :Vagón de Mercancía
+STR_805F_GRAIN_HOPPER :Vagoneta de Grano
+STR_8060_WOOD_TRUCK :Vagón de Madera
+STR_8061_IRON_ORE_HOPPER :Vagoneta de Mineral de Hierro
+STR_8062_STEEL_TRUCK :Vagón de Acero
+STR_8063_ARMORED_VAN :Vagón de Blindado
+STR_8064_FOOD_VAN :Vagón de Alimento
+STR_8065_PAPER_TRUCK :Vagón de Papel
+STR_8066_COPPER_ORE_HOPPER :Vagoneta de Mineral de Cobre
+STR_8067_WATER_TANKER :Cisterna de Agua
+STR_8068_FRUIT_TRUCK :Vagón de Fruta
+STR_8069_RUBBER_TRUCK :Vagón de Caucho
+STR_806A_SUGAR_TRUCK :Vagón de Azúcar
+STR_806B_COTTON_CANDY_HOPPER :Vagoneta de Algodón de azúcar
+STR_806C_TOFFEE_HOPPER :Vagoneta de caramelos
+STR_806D_BUBBLE_VAN :Vagón de Burbujas
+STR_806E_COLA_TANKER :Cisterna de Cola
+STR_806F_CANDY_VAN :Vagón de Dulces
+STR_8070_TOY_VAN :Vagón de Juguetes
+STR_8071_BATTERY_TRUCK :Vagón de Pilas
+STR_8072_FIZZY_DRINK_TRUCK :Vagón de Refrescos
+STR_8073_PLASTIC_TRUCK :Vagón de Plásticos
+STR_8074_MPS_REGAL_BUS :MPS Regal Bus
+STR_8075_HEREFORD_LEOPARD_BUS :Hereford Leopard Bus
+STR_8076_FOSTER_BUS :Foster Bus
+STR_8077_FOSTER_MKII_SUPERBUS :Foster MkII Superbus
+STR_8078_PLODDYPHUT_MKI_BUS :Ploddyphut MkI Bus
+STR_8079_PLODDYPHUT_MKII_BUS :Ploddyphut MkII Bus
+STR_807A_PLODDYPHUT_MKIII_BUS :Ploddyphut MkIII Bus
+STR_807B_BALOGH_COAL_TRUCK :Balogh Camión carbonero
+STR_807C_UHL_COAL_TRUCK :Uhl Camión carbonero
+STR_807D_DW_COAL_TRUCK :DW Camión carbonero
+STR_807E_MPS_MAIL_TRUCK :MPS Camión correo
+STR_807F_REYNARD_MAIL_TRUCK :Reynard Camión correo
+STR_8080_PERRY_MAIL_TRUCK :Perry Camión correo
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :MightyMover Camión correo
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Powernaught Camión correo
+STR_8083_WIZZOWOW_MAIL_TRUCK :Wizzowow Camión correo
+STR_8084_WITCOMBE_OIL_TANKER :Witcombe Cisterna de aceites
+STR_8085_FOSTER_OIL_TANKER :Foster Cisterna de aceites
+STR_8086_PERRY_OIL_TANKER :Perry Cisterna de aceites
+STR_8087_TALBOTT_LIVESTOCK_VAN :Talbott Camión de ganado
+STR_8088_UHL_LIVESTOCK_VAN :Uhl Camión de ganado
+STR_8089_FOSTER_LIVESTOCK_VAN :Foster Camión de ganado
+STR_808A_BALOGH_GOODS_TRUCK :Balogh Camión de mercancías
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Craighead Camión de mercancías
+STR_808C_GOSS_GOODS_TRUCK :Goss Camión de mercancías
+STR_808D_HEREFORD_GRAIN_TRUCK :Hereford Camión granero
+STR_808E_THOMAS_GRAIN_TRUCK :Thomas Camión granero
+STR_808F_GOSS_GRAIN_TRUCK :Goss Camión granero
+STR_8090_WITCOMBE_WOOD_TRUCK :Witcombe Camión maderero
+STR_8091_FOSTER_WOOD_TRUCK :Foster Camión maderero
+STR_8092_MORELAND_WOOD_TRUCK :Moreland Camión maderero
+STR_8093_MPS_IRON_ORE_TRUCK :MPS Camión de hierro
+STR_8094_UHL_IRON_ORE_TRUCK :Uhl Camión de hierro
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Chippy Camión de hierro
+STR_8096_BALOGH_STEEL_TRUCK :Balogh Camión de acero
+STR_8097_UHL_STEEL_TRUCK :Uhl Camión de acero
+STR_8098_KELLING_STEEL_TRUCK :Kelling Camión de acero
+STR_8099_BALOGH_ARMORED_TRUCK :Balogh Furgón blindado
+STR_809A_UHL_ARMORED_TRUCK :Uhl Furgón blindado
+STR_809B_FOSTER_ARMORED_TRUCK :Foster Furgón blindado
+STR_809C_FOSTER_FOOD_VAN :Foster Furgón de comida
+STR_809D_PERRY_FOOD_VAN :Perry Furgón de comida
+STR_809E_CHIPPY_FOOD_VAN :Chippy Furgón de comida
+STR_809F_UHL_PAPER_TRUCK :Uhl Camión de papel
+STR_80A0_BALOGH_PAPER_TRUCK :Balogh Camión de papel
+STR_80A1_MPS_PAPER_TRUCK :MPS Camión de papel
+STR_80A2_MPS_COPPER_ORE_TRUCK :MPS Camión de cobre
+STR_80A3_UHL_COPPER_ORE_TRUCK :Uhl Camión de cobre
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Goss Camión de cobre
+STR_80A5_UHL_WATER_TANKER :Uhl Cisterna de agua
+STR_80A6_BALOGH_WATER_TANKER :Balogh Cisterna de agua
+STR_80A7_MPS_WATER_TANKER :MPS Cisterna de agua
+STR_80A8_BALOGH_FRUIT_TRUCK :Balogh Camión de fruta
+STR_80A9_UHL_FRUIT_TRUCK :Uhl Camión de fruta
+STR_80AA_KELLING_FRUIT_TRUCK :Kelling Camión de fruta
+STR_80AB_BALOGH_RUBBER_TRUCK :Balogh Camión de caucho
+STR_80AC_UHL_RUBBER_TRUCK :Uhl Camión de caucho
+STR_80AD_RMT_RUBBER_TRUCK :RMT Camión de caucho
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :MightyMover Camión de azúcar
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Powernaught Camión de azúcar
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Wizzowow Camión de azúcar
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :MightyMover Camión de cola
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Powernaught Camión de cola
+STR_80B3_WIZZOWOW_COLA_TRUCK :Wizzowow Camión de cola
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :MightyMover Camión de Algodón de azúcar
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Powernaught Camión de Algodón de azúcar
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Wizzowow Camión de Algodón de azúcar
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :MightyMover Camión de caramelos
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Powernaught Camión de caramelos
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Wizzowow Camión de caramelos
+STR_80BA_MIGHTYMOVER_TOY_VAN :MightyMover Furgón de juguetes
+STR_80BB_POWERNAUGHT_TOY_VAN :Powernaught Furgón de juguetes
+STR_80BC_WIZZOWOW_TOY_VAN :Wizzowow Furgón de juguetes
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :MightyMover Camión de dulces
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Powernaught Camión de dulces
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Wizzowow Camión de dulces
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :MightyMover Camión de pilas
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Powernaught Camión de pilas
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Wizzowow Camión de pilas
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :MightyMover Camión de refrescos
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Powernaught Camión de refrescos
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Wizzowow Camión de refrescos
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :MightyMover Camión de plástico
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Powernaught Camión de plástico
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Wizzowow Camión de plástico
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :MightyMover Camión de burbujas
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Powernaught Camión de burbujas
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Wizzowow Camión de burbujas
+STR_80CC_MPS_OIL_TANKER :MPS Cisterna de petróleo
+STR_80CD_CS_INC_OIL_TANKER :CS-Inc. Cisterna de petróleo
+STR_80CE_MPS_PASSENGER_FERRY :MPS Ferry de pasajeros
+STR_80CF_FFP_PASSENGER_FERRY :FFP Ferry de pasajeros
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Bakewell 300 Hovercraft
+STR_80D1_CHUGGER_CHUG_PASSENGER :Chugger-Chug Ferry de pasajeros
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Shivershake Ferry de pasajeros
+STR_80D3_YATE_CARGO_SHIP :Yate Barco de mercancías
+STR_80D4_BAKEWELL_CARGO_SHIP :Bakewell Barco de mercancías
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Mightymover Barco de mercancías
+STR_80D6_POWERNAUT_CARGO_SHIP :Powernaut Barco de mercancías
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Tricario Helicóptero
+STR_80FE_GURU_X2_HELICOPTER :Guru X2 Helicóptero
+STR_80FF_POWERNAUT_HELICOPTER :Powernaut Helicóptero
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Mensaje del fabricante de vehículos
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}WHemos diseñado un nuevo vehículo: {STRING} - ¿estás interesado en el uso exclusivo por un año de este vehículo, para que podamos ver cómo rinde antes de ponerlo universalmente disponible?
+STR_8102_RAILROAD_LOCOMOTIVE :locomotora
+STR_8103_ROAD_VEHICLE :vehículo de carretera
+STR_8104_AIRCRAFT :aeronave
+STR_8105_SHIP :barco
+STR_8106_MONORAIL_LOCOMOTIVE :locomotora de monorraíl
+STR_8107_MAGLEV_LOCOMOTIVE :locomotora maglev
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}{TOWN}, Depósito de tren
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Los ciudadanos celebran . . .{}¡Primer tren llega a {STATION}!
+STR_8802_DETAILS :{WHITE}{STRING} (Detalles)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Tren en camino
+STR_8804 :{SETX 10}{COMMA}: {STRING}{STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING}{STRING}
+STR_8806_GO_TO :Ir a {STATION}
+STR_8807_GO_TO_TRANSFER :Ir a {STATION} (Transferir y cargar)
+STR_8808_GO_TO_UNLOAD :Ir a {STATION} (Descargar)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Ir a {STATION} (Transferir y dejar vacío)
+STR_880A_GO_TO_LOAD :Ir a {STATION} (Cargar)
+STR_880B_GO_TO_TRANSFER_LOAD :Ir a {STATION} (Transferir y esperar a carga completa)
+STR_880C_GO_NON_STOP_TO :Ir sin paradas a {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Ir sin paradas a {STATION} (Transferir y cargar)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Ir sin paradas a {STATION} (Descargar)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Ir sin paradas a {STATION} (Transferir y dejar vacío)
+STR_8810_GO_NON_STOP_TO_LOAD :Ir sin paradas a {STATION} (Cargar)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Ir sin paradas a {STATION} (Transferir y esperar a carga completa)
+STR_GO_TO_TRAIN_DEPOT :Ir al depósito del tren de {TOWN}
+STR_SERVICE_AT_TRAIN_DEPOT :Ir al depósito de {TOWN} para mantenimiento
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Ir sin parar al depósito de {TOWN}
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Ir sin parar al depósito de {TOWN} para mantenimiento
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}Hacia el depósito de {TOWN}
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}Hacia el depósito de {TOWN}, {VELOCITY}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE :{LTBLUE}Servicio en el depósito de trenes de {TOWN}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE_VEL :{LTBLUE}Servicio en el depósito de trenes de {TOWN}, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (Orden inválida)
+
+STR_UNKNOWN_DESTINATION :destino desconocido
+STR_8812_EMPTY :{LTBLUE}Vacío
+STR_8813_FROM :{LTBLUE}{CARGO} desde {STATION}
+STR_FROM_MULT :{LTBLUE}{CARGO} desde {STATION} (x{NUM})
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}El tren {COMMA} está esperando en el depósito
+STR_8815_NEW_VEHICLES :{BLACK}Nuevos Vehículos
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Tren demasiado largo
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Los trenes únicamente puede ser modificados en el interior de los depósitos
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} Trenes
+
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Nuevos vehículos de raíl
+STR_NEW_ELRAIL_VEHICLES :{WHITE}Nuevo Vehículo Eléctrico de Railes
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Nuevos vehículos de monorraíl
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Nuevos vehículos de levitación magnética
+STR_ALL_AVAIL_RAIL_VEHICLES :{WHITE}Vehículos de Rail
+
+STR_881F_BUILD_VEHICLE :{BLACK}Contruir Vehículo
+STR_CLONE_ROAD_VEHICLE :{BLACK}Clonar vehículo
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}Esto construirá una copia del vehículo. Control-click compartirá las ordenes
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Esto construirá una copia del vehículo. Pulsa este botón y después el vehículo dentro o fuera del depósito. Control-click compartirá las ordenes
+STR_CLONE_TRAIN :{BLACK}Clonar tren
+STR_CLONE_TRAIN_INFO :{BLACK}Esto copiará el tren incluido sus vagones. Control-click compartirá las ordenes
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}Esto construirá una copia del tren. Pulsa este botón y después el tren dentro o fuera del depósito. Control-click compartirá las ordenes
+STR_8820_RENAME :{BLACK}Renombrar
+STR_8823_SKIP :{BLACK}Saltarse
+STR_8824_DELETE :{BLACK}Borrar
+STR_8825_NON_STOP :{BLACK}Sin parar
+STR_8826_GO_TO :{BLACK}Ir a
+STR_8827_FULL_LOAD :{BLACK}Carga
+STR_8828_UNLOAD :{BLACK}Descarga
+STR_REFIT :{BLACK}Recargar
+STR_REFIT_TIP :{BLACK}Selecciona el tipo de carga a recargar en esta orden. Control+click para quitar la orden de recargar
+STR_REFIT_ORDER :(Recargar en {STRING})
+STR_8829_ORDERS :{WHITE}{VEHICLE} (Órdenes)
+STR_882A_END_OF_ORDERS :{SETX 10}- - Fin de pedidos - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}Servicio
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}No se puede construir vehículo...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Construido: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Valor: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}Cargando / Descargando
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}El tren debe pararse dentro del depósito
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}No se puede enviar el tren al depósito...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}No hay más lugar para pedidos
+STR_8832_TOO_MANY_ORDERS :{WHITE}Demasiados pedidos
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}No se puede insertar un nuevo pedido...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}No se puede borrar este pedido...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}No se puede modificar este pedido...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}No se puede mover vehículo...
+STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}El motor posterior seguirá siempre su contraparte delantera
+STR_8838_N_A :N/D{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}No se puede vender tren...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}No se puede encontrar ruta al depósito
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}No se puede parar/arrancar tren...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Intervalo de despacho: {LTBLUE}{COMMA}días{BLACK} Último servicio: {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Intervalo de despacho: {LTBLUE}{COMMA}%{BLACK} Último servicio: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Trenes - click en tren para información
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Construir nuevos trenes (requiere depósito)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Trenes - click en tren para info., arrastrar vehículo para añadir/retirar del tren
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Construir nuevo vehículo de tren
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Arrastrar aquí vehículo para venderlo
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centrar vista en posición del depósito
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Lista de selección de vehículo - click en vehículo para información
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Construir el vehículo resaltado
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Renombrar tipo de vehículo
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Acción actual del tren - click aquí para detener/arrancar el tren
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Ver órdenes del tren
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centrar vista en posición del tren
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Mandar tren al depósito
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Forzar al tren a proceder sin esperar a la apertura de señal
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Revertir dirección del tren
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Ver detalles del tren
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Incrementar intervalo de despacho
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Decrementar intervalo de despacho
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Mostrar detalles de mercancía transportada
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Mostrar detalles de los vehículos
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Mostrar capacidades de cada vehículo
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Mostrar capacidad total del tren, dividida por tipo de carga
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Lista de órdenes - click en orden para resaltarla
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}Saltar orden actual y comenzar la siguiente
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Borrar orden resaltada
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Hacer la orden resaltada sin parada
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Añadir nueva orden antes de la orden resaltada, o añadirla al final de la lista
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Hacer que en la orden resaltada, el vehículo espere a carga completa
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Hacer que en la orden resaltada, el vehículo espere a descargar completamente
+STR_SERVICE_HINT :{BLACK}Saltar esta orden a menos que el servicio sea necesario
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}Nuevo {STRING} ahora disponible!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Coste: {CURRENCY} Peso: {WEIGHT_S}{}Velocidad: {VELOCITY} Potencia: {POWER}{}Coste Operativo: {CURRENCY}/año{}Capacidad: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}Averiado
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}Edad: {LTBLUE}{STRING}{BLACK} Coste Operativo: {LTBLUE}{CURRENCY}/año
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Peso: {LTBLUE}{WEIGHT_S} {BLACK}Potencia: {LTBLUE}{POWER}{BLACK} Velocidad Máx.: {LTBLUE}{VELOCITY}
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Peso: {LTBLUE}{WEIGHT_S} {BLACK}Potencia: {LTBLUE}{POWER}{BLACK} Max. velocidad: {LTBLUE}{VELOCITY} {BLACK}Max. T.E.: {LTBLUE}{FORCE}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Beneficio este año: {LTBLUE}{CURRENCY} (último año: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}Fiabilidad: {LTBLUE}{COMMA}% {BLACK}Averías desde último mantenimiento: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Parado
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}No se puede pasar la señal en peligro al tren...
+STR_8863_CRASHED :{RED}¡Siniestrado!
+
+STR_8865_NAME_TRAIN :{WHITE}Nombrar tren
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}No se puede nombrar tren...
+STR_8867_NAME_TRAIN :{BLACK}Nombrar tren
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}¡Siniestro ferroviario!{}{COMMA} fallecidos en la explosión de la colisión
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}No se puede revertir la dirección...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Renombrar tipo de vehículo
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}No se puede renombrar tipo de vehículo...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Hacer que la orden marcada fuerce al vehículo a descargar
+STR_886F_TRANSFER :{BLACK}Transferir
+
+STR_TRAIN_STOPPING :{RED}Parándose
+STR_TRAIN_STOPPING_VEL :{RED}Parándose, {VELOCITY}
+STR_INCOMPATIBLE_RAIL_TYPES :Tipo de vía incompatible
+STR_TRAIN_NO_POWER :{RED}Sin potencia
+STR_TRAIN_START_NO_CATENARY :Esta vía carece la catenaria, así que el tren no puede comenzar
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Vehículo de carretera en camino
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} Vehículos de Carretera
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}{TOWN} Depósito de vehículos
+STR_9004_NEW_VEHICLES :{BLACK}Nuevos vehículos
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}Nuevos vehículos
+STR_9007_BUILD_VEHICLE :{BLACK}Construir vehículo
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}CNo se puede construir vehículo...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (Detalles)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}Edad: {LTBLUE}{STRING}{BLACK} Coste Operativo: {LTBLUE}{CURRENCY}/año
+STR_900E_MAX_SPEED :{BLACK}Velocidad Máx.: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Beneficio este año: {LTBLUE}{CURRENCY} (último año: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}Fiabilidad: {LTBLUE}{COMMA}% {BLACK}Averías desde último despacho: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Const.: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Capacidad: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}...debe estar detenido dentro de un depósito
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}No se puede vender vehículo...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}No se puede detener/arrancar vehículo...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}Vehículo de carretera {COMMA} espera en depósito
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}Hacia el depósito de {TOWN}
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}Hacia el depósito de {TOWN}, {VELOCITY}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE :{LTBLUE}Dirigiendose al Depósito de {TOWN}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE_VEL :{LTBLUE}Servicio en el depósito de {TOWN}, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}No se puede enviar vehículo al depósito...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}No se puede encontrar ruta al depósito
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Vehículos de carretera - click en vehículo para información
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Construir nuevos vehículos (requiere depósito)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Acción actual del vehículo - click aquí para detener/arrancar vehículo
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Ver órdenes del vehículo
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Centrar vista en posición del vehículo
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Mandar vehículo al depósito
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Forzar vehículo a girar
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Mostrar detalles del vehículo
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Vehículos - click en vehículo para información
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Construir nuevo vehículo
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Arrastra aquí el vehículo para venderlo
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Centrar vista en posición del depósito
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Lista de selección de vehículos - click en vehículo para información
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Construir el vehículo resaltado
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}¡Nuevo vehículo de carretera disponible!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Coste: {CURRENCY}{}Velocidad: {VELOCITY}{}Coste Operativo: {CURRENCY}/año{}Capacidad: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Nombrar vehículo
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}No se puede nombrar vehículo...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Nombrar vehículo
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Los ciudadanos celebran . . .{}¡Primer autobús llega a {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Los ciudadanos celebran . . .{}¡Primer camión llega a {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}¡Accidente de tráfico!{}El conductor fallece en la explosión tras la colisión con el tren
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}Accidente de tráfico!{}{COMMA} fallecidos en la explosión tras la colisión con el tren
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}No se puede hacer girar al vehículo...
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}No se pude dar la vuelta a un vehículo compuesto por múltiples unidades
+STR_9034_RENAME :{BLACK}Renombrar
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Renombrar tipo de vehículo
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Renombrar tipo de vehículo
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}No se puede renombrar tipo de vehículo....
+STR_9038_GO_TO_ROADVEH_DEPOT :Ir al depósito de {TOWN}
+STR_SERVICE_AT_ROADVEH_DEPOT :Ir al depósito de {TOWN} para mantenimiento
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Reparar vehículo de carretera para transportar otro tipo de cargas
+STR_REFIT_ROAD_VEHICLE :{BLACK}Reparar vehículo de carretera
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Reparar vehículo de carretera para transportar la carga seleccionada
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}No se puede reparar vehículo de carretera
+STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Selecciona tipo de carga que transportará el vehículo de carretera
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Construir muelles
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Construir muelles
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}No se pueden construir muelles aquí...
+STR_9803_SHIP_DEPOT :{WHITE}Astillero de {TOWN}
+STR_9804_NEW_SHIPS :{BLACK}Nuevos barcos
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} Barcos
+STR_9808_NEW_SHIPS :{WHITE}Nuevos barcos
+STR_9809_BUILD_SHIP :{BLACK}Construir barco
+STR_CLONE_SHIP :{BLACK}Clonar barco
+STR_CLONE_SHIP_INFO :{BLACK}Esto copiará el barco. Control-click compartirá las ordenes
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}Esto construirá una copia del barco. Pulsa este botón y después el barco dentro o fuera del muelle. Control-click compartirá las ordenes
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}Barco debe estar detenido en astillero
+STR_980C_CAN_T_SELL_SHIP :{WHITE}No se puede vender barco...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}No se puede construir barco...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Barco en camino
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Detalles)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}Edad: {LTBLUE}{STRING}{BLACK} Coste Operativo: {LTBLUE}{CURRENCY}/año
+STR_9813_MAX_SPEED :{BLACK}Velocidad Máx.: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Beneficio este año: {LTBLUE}{CURRENCY} (año anterior: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}Fiabilidad: {LTBLUE}{COMMA}% {BLACK}Averías desde último despacho: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Const.: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}Capacidad: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}No se puede detener/arrancar barco...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}No se puede mandar barco a astillero...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}No se puede encontrar ruta al astillero
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}Hacia el astillero de {TOWN}
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}Hacia el astillero de {TOWN}, {VELOCITY}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE :{LTBLUE}Servicio en el embarcadero de {TOWN}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE_VEL :{LTBLUE}Servicio en el embarcadero de {TOWN}, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}Barco {COMMA} esperando en astilleros
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Construir muelles
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Construir astillero (para construir y despachar barcos)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Barcos - click en barco para información
+STR_9820_BUILD_NEW_SHIP :{BLACK}Construir nuevo barco
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Arrastra barco aquí para venderlo
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centrar vista en posición del astillero
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Barcos - click en barco para información
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Construir nuevos barcos (requiere astillero)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}Lista de selección de barcos - click en barco para información
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Construir el barco resaltado
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Acción actual del barco - click aquí para detener/arrancar barco
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Ver órdenes del barco
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centrar vista en posición del barco
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Mandar barco al astillero
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Mostrar detalles del barco
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}¡Nuevo barco ya disponible!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Coste: {CURRENCY} Velocidad Máx.: {VELOCITY}{}Capacidad: {CARGO}{}Coste Operativo: {CURRENCY}/año
+STR_982F_NAME_SHIP :{BLACK}Nombrar barco
+
+STR_9831_NAME_SHIP :{WHITE}Nombrar barco
+STR_9832_CAN_T_NAME_SHIP :{WHITE}No se puede nombrar barco...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}os ciudadanos celebran . . .{}¡Primer barco llega a {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Boya de posición, que puede usarse como itinerarios adicionales
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}No se puede colocar boya aquí...
+STR_9836_RENAME :{BLACK}Renombrar
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Renombrar tipo de barco
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Renombrar tipo de barco
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}No se puede renombrar tipo de barco...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Reformar barco de carga para que transporte otro tipo de carga
+STR_983B_REFIT :{WHITE}{VEHICLE} (Reformar)
+STR_983C_REFIT_SHIP :{BLACK}Reformar barco
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Seleccione tipo de carga para que el barco la lleve
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Reformar barco para que transporte el tipo de carga resaltado
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Seleccione tipo de carga a llevar:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nueva capacidad: {GOLD}{CARGO}{}{BLACK}Coste de reforma: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}No se puede reformar barco...
+STR_9842_REFITTABLE :(reformable)
+STR_GO_TO_SHIP_DEPOT :Ir al astillero de {TOWN}
+SERVICE_AT_SHIP_DEPOT :Ir al astillero de {TOWN} para mantenimiento
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Aeropuertos
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}No se puede construir aeropuerto aquí...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} Hangar de aeroplanos
+STR_A003_NEW_AIRCRAFT :{BLACK}Nueva aeronave
+STR_CLONE_AIRCRAFT :{BLACK}Clonar aeronave
+STR_CLONE_AIRCRAFT_INFO :{BLACK}Esto copiará la aeronave. Control-click compartirá las ordenes
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Esto construirá una copia de la aeronave. Pulsa este botón y después la aeronave dentro o fuera del hangar. Control-click compartirá las ordenes
+STR_A005_NEW_AIRCRAFT :{WHITE}Nuevo avilón
+STR_A006_BUILD_AIRCRAFT :{BLACK}Construir aeronave
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}No se puede construir aeronave...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} Aeronave
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (Órdenes)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (Detalles)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Edad: {LTBLUE}{STRING}{BLACK} Coste Operativo: {LTBLUE}{CURRENCY}/año
+STR_A00E_MAX_SPEED :{BLACK}Velocidad Máx.: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Beneficio este año: {LTBLUE}{CURRENCY} (año anterior: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}Fiabilidad: {LTBLUE}{COMMA}% {BLACK}Averías desde último despacho: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Const.: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}No se puede enviar la aeronave al hangar
+STR_HEADING_FOR_HANGAR :{ORANGE}Ir al hangar de {STATION}
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}Ir al hangar de {STATION}, {VELOCITY}
+STR_HEADING_FOR_HANGAR_SERVICE :{LTBLUE}Dirigiendose al Hangar de {STATION}
+STR_HEADING_FOR_HANGAR_SERVICE_VEL :{LTBLUE}Dirigiendose al Hangar de {STATION}, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}La aeronave {COMMA} está esperando en el hangar
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Aeronave en camino
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}No se puede detener/arrancar aeronave...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}La aeronave está en vuelo
+STR_A019_CAPACITY :{BLACK}Capacidad: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Capacidad: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}La aeronave debe estar parada en hangar
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}No se puede vender la aeronave...
+STR_A01D_AIRPORT_CONSTRUCTION :Construir aeropuerto
+STR_A01E_BUILD_AIRPORT :{BLACK}Construir aeropuerto
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}La aeronave - click en la aeronave para información
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Construir nueva aeronave (requiere aeropuerto con hangar)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Aeronave - click en la aeronave para información
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Construir aeronave
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}Arrastra aeronave aquí para venderla
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Centrar vista en posición del hangar
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Lista de selección de aeronaves- click en aeronave para información
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Construir la aeronave resaltada
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Acción actual de la aeronave - click aquí para detener/arrancar aeronaves
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Ver órdenes de la aeronave
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Centrar vista en posición de la aeronave
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Enviar aeronave al hangar
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Mostrar detalles de la aeronave
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}¡Nueva aeronave ya disponible!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Coste: {CURRENCY} Velocidad Máx.: {VELOCITY}{}Capacidad: {COMMA} pasajeros, {COMMA} sacas de correo{}Coste Operativo: {CURRENCY}/año
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Nombrar aeronave
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}No se puede nombrar aeronave...
+STR_A032_NAME_AIRCRAFT :{BLACK}Nombrar aeronave
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Los ciudadanos celebran . . .{}¡Primera aeronave llega a {STATION}!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}¡Avión siniestrado!{}{COMMA} fallecidos en la explosión en {STATION}
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Accidente aéreo!{}La aeronave se quedó sin combustible, {COMMA} personas mueren en la tragedia!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Renombrar
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Renombrar tipo de aeronave
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Renombrar tipo de aeronave
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}No se puede renombrar el tipo de aeronave...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Reformar aeronave para llevar otro tipo de carga
+STR_A03C_REFIT :{WHITE}{VEHICLE} (Reformar)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Reformar aeronave
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Seleccione tipo de carga para que la aeronave la lleve
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Reformar aeronave para que lleve el tipo de carga resaltado
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Elige tipo de carga para llevar:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nueva capacidad: {GOLD}{STRING}{}{BLACK}Coste de reforma: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}No se puede reformar aeronave...
+STR_GO_TO_AIRPORT_HANGAR :Ir al hangar de {STATION}
+SERVICE_AT_AIRPORT_HANGAR :Ir al hangar de {STATION} para mantenimiento
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}¡Desastre de zepelín en {STATION}!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}¡Vehículo terrestre destruído en colisión con OVNI!
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}¡Explosión de refinería cerca de {TOWN}!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}¡Fábrica destruída en sospechosas circunstancias cerca de {TOWN}!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}¡OVNI aterriza cerca de {TOWN}!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}¡Hundimiento de mina de carbón deja ola de destrucción en {TOWN}!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}¡Inundación!{}Al menos {COMMA} desaparecidos o muertos después de las terribles inundaciones!
+
+STR_BRIBE_FAILED :{WHITE}Su intento de soborno ha sido
+STR_BRIBE_FAILED_2 :{WHITE}descubierto por un investigador regional.
+STR_BUILD_DATE :{BLACK}Construido: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Detalle de rendimiento
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}Detalle
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Vehículos:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Estaciones:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Benefício Min.:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Ingreso Min.:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Ingreso Máx.:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Entregado:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Carga:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Dinero:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Préstamo:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Total:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Cantidad de vehículos. Incluye vehículos de carretera, trenes, barcos y aeroplanos.
+STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}Cantidad de segmentos de estaciones. Cada segmento de una estación (ej. estaciones de tren, paradas de autobús, aeropuertos, etc) es contabilizado, incluso si está conectado a una estación.
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}El beneficio del vehículo con menores ingresos (de todos los vehículos mayores de 2 años)
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Cantidad de dinero ganado en un mes con el beneficio más bajo en los pasados 12 cuartos
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Cantidad de dinero ganado en un mes con el beneficio más alto en los pasados 12 cuartos
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}Unidades de carga entregadas en los pasados cuatro cuartos.
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}Tipos de carga entregada en el último cuarto.
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Cantidad de dinero en mano
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}¿Tienes un préstamo muy elevado?
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Total de puntos ganados del máximo posible
+
+STR_NEWGRF_SETTINGS_BUTTON :{BLACK}Configuración NewGRF
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}Configuración de Newgrf
+STR_NEWGRF_APPLY_CHANGES :{BLACK}Aplicar cambios
+STR_NEWGRF_SET_PARAMETERS :{BLACK}Establecer parámetros
+STR_NEWGRF_TIP :{BLACK}Un listado de todos los Newgrf que tiene instalados. Haga click para cambiar las opciones.
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}¡No tiene ningún fichero newgrf instalado! Por favor, lea las instrucciones en el manual para instalar nuevos gráficos.
+STR_NEWGRF_FILENAME :{BLACK}Fichero: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}ID GRF: {SILVER}{STRING}
+STR_NEWGRF_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING}
+STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}Se van a realizar cambios a un juego en ejecución; esto puede cerrar OpenTTD.{}¿Estás completamente seguro de realizar esto?
+
+STR_NEWGRF_ADD :{BLACK}Añadir
+STR_NEWGRF_ADD_TIP :{BLACK}Añadir un NewGRF a la lista
+STR_NEWGRF_REMOVE :{BLACK}Quitar
+STR_NEWGRF_REMOVE_TIP :{BLACK}Quitar el NewGRF seleccionado de la lista
+STR_NEWGRF_MOVEUP :{BLACK}Mover Arriba
+STR_NEWGRF_MOVEUP_TIP :{BLACK}Mueve el NewGRF seleccionado arriba en la lista
+STR_NEWGRF_MOVEDOWN :{BLACK}Mover Abajo
+STR_NEWGRF_MOVEDOWN_TIP :{BLACK}Mueve el NewGRF seleccionado abajo en la lista
+STR_NEWGRF_FILE_TIP :{BLACK}Una lista de los NewGRF instalados. Pulsa en el fichero para cambiar sus parámetros
+STR_NEWGRF_PARAMETER :{BLACK}Parametros: {SILVER}{STRING}
+STR_NEWGRF_PARAMETER_QUERY :{BLACK}Introduce los parámetros del NewGRF
+STR_NEWGRF_NO_INFO :{BLACK}No tiene información disponible
+
+STR_NEWGRF_ADD_CAPTION :{WHITE}Ficheros NewGRF disponibles
+STR_NEWGRF_ADD_FILE :{BLACK}Añadir a la selección
+STR_NEWGRF_ADD_FILE_TIP :{BLACK}Añade el NewGRF seleccionado a tu configuración
+STR_NEWGRF_RESCAN_FILES :{BLACK}Actualizar ficheros
+STR_NEWGRF_RESCAN_FILES_TIP :{BLACK}Actualiza la lista de ficheros NewGRF disponibles
+STR_NEWGRF_DUPLICATE_GRFID :{WHITE}No se puede añadir: GRF ID duplicado
+
+STR_NEWGRF_NOT_FOUND :{RED}Fichero no encontrado
+STR_NEWGRF_DISABLED :{RED}Desactivado
+
+STR_CURRENCY_WINDOW :{WHITE}Moneda personalizada
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Tasa de cambio: {ORANGE}{CURRENCY} = £ {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Separador:
+STR_CURRENCY_PREFIX :{LTBLUE}Prefijo:
+STR_CURRENCY_SUFFIX :{LTBLUE}Sufijo:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Cambio al Euro: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Cambio al Euro: {ORANGE}nunca
+STR_CURRENCY_PREVIEW :{LTBLUE}Previa: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Cambiar parámetro de moneda personalizada
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} Trenes
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} Vehículos de carretera
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} Aeronaves
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} Barcos
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Mostrar todos los trenes que tienen esta estación en su horario
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Mostrar todos los vehículos de carretera que tienen esta estación en su horario
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Mostrar todos las aeronaves que tienen esta estación en su horario
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Mostrar todos los barcos que tienen esta estación en su horario
+
+STR_VEH_WITH_SHARED_ORDERS_LIST :{WHITE}Ordenes compartidas de {COMMA} Vehículo{P "" s}
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}Ver todos los vehículos que tienen el mismo calendario
+
+### depot strings
+STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Vas a vender todos los vehículos que tienes en el depósito. ¿Estás seguro?
+
+STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP :{BLACK}Vender todos los trenes del depósito
+STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP :{BLACK}Vender todos los vehículos del depósito
+STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP :{BLACK}Vender todos los barcos del depósito
+STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP :{BLACK}Vender todas las aeronaves del hangar
+
+STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP :{BLACK}Obtener lista de todos los trenes de este depósito y sus ordenes
+STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP :{BLACK}Obtener lista de todos los vehículos del depósito actual y sus ordenes
+STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP :{BLACK}Obtener lista de todos los barcos de este depósito y sus ordenes
+STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP :{BLACK}Obtener lista de todas las aeronaves de cualquier hangar de este aeropuerto y sus ordenes
+
+STR_DEPOT_AUTOREPLACE_TRAIN_TIP :{BLACK}Cambia automáticamente todos los trenes del depósito
+STR_DEPOT_AUTOREPLACE_ROADVEH_TIP :{BLACK}Cambia automáticamente todos los vehículos del depósito
+STR_DEPOT_AUTOREPLACE_SHIP_TIP :{BLACK}Cambia automáticamente todos los barcos del depósito
+STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP :{BLACK}Cambia automáticamente todas las aeronaves del hangar
+
+STR_VEHICLE_LIST_TRAIN_DEPOT :{BLACK}{STRING} - {COMMA} Tren{P "" s}
+STR_VEHICLE_LIST_ROADVEH_DEPOT :{BLACK}{STRING} - {COMMA} Vehículo Carretera{P "" s}
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} Barco{P "" s}
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} Aeronave
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}Reemplazar {STRING}
+STR_REPLACE_VEHICLES_START :{BLACK}Empezar a reemplazar vehículos
+STR_REPLACE_VEHICLES_STOP :{BLACK}Parar de reemplazar vehículos
+STR_NOT_REPLACING :{BLACK}No reemplazar
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}No hay vehículos seleccionados
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Seleccione tipo de locomotora a reemplazar
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Seleccione nuevo tipo de locomotora a usar en vez de la locomotora seleccionada a la izquierda
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Presiona este botón si no quieres reemplazar la locomotora seleccionada en la izquierda
+STR_REPLACE_HELP_START_BUTTON :{BLACK}Presiona este botón si quieres reemplazar la locomotora seleccionada a la izquierda por la seleccionada en la derecha
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Seleccione tipo de rail para seleccionar locomotoras para ese tipo
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Muestra que locomotora será reemplazada
+STR_REPLACE_HELP :{BLACK}Esta función permite seleccionar un tipo de locomotora y reemplazarla por otra. El cambio se realizará cuando el vehículo llegue al depósito
+STR_REPLACE_REMOVE_WAGON :{BLACK}Quitar vagón: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Hacer que el cambio automático mantenga la longitud del tren quitando vagones (empezando por adelante), si el cambio de locomotora produce un tren más largo.
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}Reemplazando: {ORANGE}{SKIP}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} FUNCIÓN EXPERIMENTAL {}Cambia entre las ventanas de cambio de vagón y locomotora.{}Los cambios de vagón solo se harán si el nuevo vagón puede ser reparado para transportar el mismo tipo de carga que el anterior. Está marcado para cada vagón cuando el cambio actual se realiza.
+STR_ENGINE_NOT_BUILDABLE :{WHITE}No es posible construir este motor
+
+STR_ENGINES :Motores
+STR_WAGONS :Vagones
+
+STR_MASS_STOP_DEPOT_TRAIN_TIP :{BLACK}Pulsa para parar todos los trenes dentro del depósito
+STR_MASS_STOP_DEPOT_ROADVEH_TIP :{BLACK}Pulsa para parar todos los vehículos dentro del depósito
+STR_MASS_STOP_DEPOT_SHIP_TIP :{BLACK}Pulsa para parar todos los barcos dentro del depósito
+STR_MASS_STOP_HANGAR_TIP :{BLACK}Pulsa para parar todas las aeronaves dentro del hangar
+
+STR_MASS_START_DEPOT_TRAIN_TIP :{BLACK}Pulsa para arrancar todos los trenes dentro del depósito
+STR_MASS_START_DEPOT_ROADVEH_TIP :{BLACK}Pulsa para arrancar todos los vehículos dentro del depósito
+STR_MASS_START_DEPOT_SHIP_TIP :{BLACK}Pulsa para arrancar todos los barcos dentro del depósito
+STR_MASS_START_HANGAR_TIP :{BLACK}Pulsa para arrancar todas las aeronaves dentro del hangar
+
+STR_MASS_STOP_LIST_TIP :{BLACK}Pulsa para parar todos los vehículos de la lista
+STR_MASS_START_LIST_TIP :{BLACK}Pulsa para arrancar todos los vehículos de la lista
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}Lista de señales - {COMMA} Señales
+
+STR_ORDER_REFIT_FAILED :{WHITE}La orden de recarga ha fallado {STRING} {COMMA}
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :Vehículos de rail
+STR_ELRAIL_VEHICLES :Vehícules de Rail Eléctrico
+STR_MONORAIL_VEHICLES :Vehículos monorail
+STR_MAGLEV_VEHICLES :Vehículos de Lev. Mag.
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Coste: {GOLD}{CURRENCY}{BLACK} Peso: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Velocidad: {GOLD}{VELOCITY}{BLACK} Potencia: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}Velocidad: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Coste de operación: {GOLD}{CURRENCY}/año
+STR_PURCHASE_INFO_CAPACITY :{BLACK}Capacidad: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Diseñado: {GOLD}{NUM}{BLACK} Vida: {GOLD}{COMMA} años
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}Fiabilidad máxima: {GOLD}{COMMA}%
+STR_PURCHASE_INFO_COST :{BLACK}Coste: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Peso: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Coste: {GOLD}{CURRENCY}{BLACK} Velocidad: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Capacidad: {GOLD}{COMMA} pasajeros, {COMMA} sacas de correo
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Vagones con motor: {GOLD}+{POWER}{BLACK} Peso: {GOLD}+{WEIGHT_S}
+STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Convertible a: {GOLD}
+STR_PURCHASE_INFO_ALL_TYPES :Todos los tipos de carga
+STR_PURCHASE_INFO_ALL_BUT :Todo excepto {GOLD}
+STR_PURCHASE_INFO_MAX_TE :{BLACK}Max. Esfuerzo de Tracción {GOLD}{FORCE}
+
+########### String for New Landscape Generator
+
+STR_GENERATE :{WHITE}Generar
+STR_RANDOM :{BLACK}Aleatorio
+STR_RANDOM_HELP :{BLACK}Cambiar la semilla aleatoria usada por el Generador de Terrenos
+STR_WORLD_GENERATION_CAPTION :{WHITE}Generación de mundo
+STR_RANDOM_SEED :{BLACK}Semilla Aleatoria:
+STR_RANDOM_SEED_HELP :{BLACK}Pulsa para introducir la semilla aleatoria
+STR_LAND_GENERATOR :{BLACK}Generador terreno:
+STR_TREE_PLACER :{BLACK}Algoritmo árboles:
+STR_HEIGHTMAP_ROTATION :{BLACK}Rotación mapa de alturas:
+STR_TERRAIN_TYPE :{BLACK}Tipo de terreno
+STR_QUANTITY_OF_SEA_LAKES :{BLACK}Nivel del mar:
+STR_SMOOTHNESS :{BLACK}Suavidad:
+STR_SNOW_LINE_HEIGHT :{BLACK}Altura línea nieve
+STR_DATE :{BLACK}Fecha:
+STR_NUMBER_OF_TOWNS :{BLACK}No. de ciudades:
+STR_NUMBER_OF_INDUSTRIES :{BLACK}No. de industrias:
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_SNOW_LINE_UP :{BLACK}Mover la línea de nieve una arriba
+STR_SNOW_LINE_DOWN :{BLACK}Mover la línea de nieve una abajo
+STR_SNOW_LINE_QUERY_CAPT :{WHITE}Cambiar altura de la línea de nieve
+STR_START_DATE_QUERY_CAPT :{WHITE}Cambiar año de inicio
+STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Alerta de escala
+STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Cambiar demasiado el tamaño del mapa de origen no está recomendado. ¿Desea continuar con la generación?
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_HEIGHTMAP_NAME :{BLACK}Nombre del mapa de alturas:
+STR_HEIGHTMAP_SIZE :{BLACK}Tamaño: {ORANGE}{NUM} x {NUM}
+STR_GENERATION_WORLD :{WHITE}Generando mundo...
+STR_GENERATION_ABORT :{BLACK}Abortar
+STR_GENERATION_ABORT_CAPTION :{WHITE}Abortar Generación del Mundo
+STR_GENERATION_ABORT_MESSAGE :{YELLOW}¿Desea realmente abortar la generación?
+STR_PROGRESS :{WHITE}{NUM}% completado
+STR_GENERATION_PROGRESS :{BLACK}{NUM} / {NUM}
+STR_WORLD_GENERATION :{BLACK}Generación de mundo
+STR_TREE_GENERATION :{BLACK}Generación de árboles
+STR_UNMOVABLE_GENERATION :{BLACK}Generación inamovible
+STR_CLEARING_TILES :{BLACK}Generación de area áspera y rocosa
+STR_SETTINGUP_GAME :{BLACK}Setting up game
+STR_PREPARING_TILELOOP :{BLACK}Ejecutar tile-loop
+STR_PREPARING_GAME :{BLACK}Preparando juego
+STR_DIFFICULTY_TO_CUSTOM :{WHITE}Esta acción cambia el nivel de dificultad a personalizado
+STR_SE_FLAT_WORLD :{WHITE}Tierra llana
+STR_SE_FLAT_WORLD_TIP :{BLACK}Generar una tierra llana
+STR_SE_RANDOM_LAND :{WHITE}Tierra aleatoria
+STR_SE_NEW_WORLD :{BLACK}Crear nuevo escenario
+STR_SE_CAPTION :{WHITE}Tipo de escenario
+STR_FLAT_WORLD_HEIGHT_DOWN :{BLACK}Mueve la altura de la tierra llana uno abajo
+STR_FLAT_WORLD_HEIGHT_UP :{BLACK}Mueve la altura de la tierra llana uno arriba
+STR_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Cambia la altura de la tierra llana
+STR_FLAT_WORLD_HEIGHT :{BLACK}Altura tierra llana:
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+STR_SMALLMAP_CENTER :{BLACK}Centrar el mapa pequeño a la posición actual
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}Pequeño
+STR_CITY_AIRPORT :{BLACK}Ciudad
+STR_METRO_AIRPORT :{BLACK}Aeropuerto metropolitano
+STR_INTERNATIONAL_AIRPORT :{BLACK}Aeropuerto internacional
+STR_COMMUTER_AIRPORT :{BLACK}Viajero
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Intercontinental
+STR_HELIPORT :{BLACK}Helipuerto
+STR_HELIDEPOT :{BLACK}Helihangar
+STR_HELISTATION :{BLACK}Heliestación
+
+STR_SMALL_AIRPORTS :{BLACK}Aeropuerto pequeño
+STR_LARGE_AIRPORTS :{BLACK}Aeropuerto grande
+STR_HUB_AIRPORTS :{BLACK}Centro del aeropuerto
+STR_HELIPORTS :{BLACK}Aeropuerto helicopteros
+
+############ Tooltip measurment
+
+STR_MEASURE_LENGTH :{BLACK}Longitud: {NUM}
+STR_MEASURE_AREA :{BLACK}Ãrea: {NUM} x {NUM}
+STR_MEASURE_LENGTH_HEIGHTDIFF :{BLACK}Longitud: {NUM}{}Diferencia altura: {NUM} m
+STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}Ãrea: {NUM} x {NUM}{}Diferencia altura: {NUM} m
+
+########
diff --git a/src/lang/swedish.txt b/src/lang/swedish.txt
new file mode 100644
index 000000000..aa789d533
--- /dev/null
+++ b/src/lang/swedish.txt
@@ -0,0 +1,3116 @@
+##name Swedish
+##ownname Svenska
+##isocode sv_SE.UTF-8
+##plural 0
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Utanför kanten
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}För nära kanten av kartan
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Inte tillräckligt med pengar - krävs {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Platt mark krävs
+STR_0008_WAITING :{BLACK}Väntar: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (på väg från
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Accepterar: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Accepterar: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :Passagerare
+STR_0010_COAL :Kol
+STR_0011_MAIL :Post
+STR_0012_OIL :Olja
+STR_0013_LIVESTOCK :Boskap
+STR_0014_GOODS :Gods
+STR_0015_GRAIN :Spannmål
+STR_0016_WOOD :Timmer
+STR_0017_IRON_ORE :Järnmalm
+STR_0018_STEEL :Stål
+STR_0019_VALUABLES :Värdesaker
+STR_001A_COPPER_ORE :Kopparmalm
+STR_001B_MAIZE :Majs
+STR_001C_FRUIT :Frukt
+STR_001D_DIAMONDS :Diamanter
+STR_001E_FOOD :Mat
+STR_001F_PAPER :Papper
+STR_0020_GOLD :Guld
+STR_0021_WATER :Vatten
+STR_0022_WHEAT :Vete
+STR_0023_RUBBER :Gummi
+STR_0024_SUGAR :Socker
+STR_0025_TOYS :Leksaker
+STR_0026_CANDY :Godis
+STR_0027_COLA :Kola
+STR_0028_COTTON_CANDY :Sockervadd
+STR_0029_BUBBLES :Bubblor
+STR_002A_TOFFEE :Knäck
+STR_002B_BATTERIES :Batterier
+STR_002C_PLASTIC :Plast
+STR_002D_FIZZY_DRINKS :Läsk
+STR_002E :
+STR_002F_PASSENGER :Passagerare
+STR_0030_COAL :Kol
+STR_0031_MAIL :Post
+STR_0032_OIL :Olja
+STR_0033_LIVESTOCK :Boskap
+STR_0034_GOODS :Gods
+STR_0035_GRAIN :Vete
+STR_0036_WOOD :Timmer
+STR_0037_IRON_ORE :Järnmalm
+STR_0038_STEEL :Stål
+STR_0039_VALUABLES :Värdesaker
+STR_003A_COPPER_ORE :Kopparmalm
+STR_003B_MAIZE :Majs
+STR_003C_FRUIT :Frukt
+STR_003D_DIAMOND :Diamanter
+STR_003E_FOOD :Mat
+STR_003F_PAPER :Papper
+STR_0040_GOLD :Guld
+STR_0041_WATER :Vatten
+STR_0042_WHEAT :Vete
+STR_0043_RUBBER :Gummi
+STR_0044_SUGAR :Socker
+STR_0045_TOY :Leksaker
+STR_0046_CANDY :Godis
+STR_0047_COLA :Kola
+STR_0048_COTTON_CANDY :Sockervadd
+STR_0049_BUBBLE :Bubblor
+STR_004A_TOFFEE :Knäck
+STR_004B_BATTERY :Batterier
+STR_004C_PLASTIC :Plast
+STR_004D_FIZZY_DRINK :Läsk
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} passagerare
+STR_QUANTITY_COAL :{WEIGHT} kol
+STR_QUANTITY_MAIL :{COMMA} postsäck{P "" ar}
+STR_QUANTITY_OIL :{VOLUME} olja
+STR_QUANTITY_LIVESTOCK :{COMMA} boskap
+STR_QUANTITY_GOODS :{COMMA} låd{P a or} gods
+STR_QUANTITY_GRAIN :{WEIGHT} spannmål
+STR_QUANTITY_WOOD :{WEIGHT} timmer
+STR_QUANTITY_IRON_ORE :{WEIGHT} järnmalm
+STR_QUANTITY_STEEL :{WEIGHT} stål
+STR_QUANTITY_VALUABLES :{COMMA} värdesäck{P "" ar}
+STR_QUANTITY_COPPER_ORE :{WEIGHT} kopparmalm
+STR_QUANTITY_MAIZE :{WEIGHT} majs
+STR_QUANTITY_FRUIT :{WEIGHT} frukt
+STR_QUANTITY_DIAMONDS :{COMMA} diamantsäck{P "" ar}
+STR_QUANTITY_FOOD :{WEIGHT} mat
+STR_QUANTITY_PAPER :{WEIGHT} papper
+STR_QUANTITY_GOLD :{COMMA} guldsäck{P "" ar}
+STR_QUANTITY_WATER :{VOLUME} vatten
+STR_QUANTITY_WHEAT :{WEIGHT} vete
+STR_QUANTITY_RUBBER :{VOLUME} gummi
+STR_QUANTITY_SUGAR :{WEIGHT} socker
+STR_QUANTITY_TOYS :{COMMA} leksak{P "" er}
+STR_QUANTITY_SWEETS :{COMMA} godispås{P e ar}
+STR_QUANTITY_COLA :{VOLUME} kola
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} sockervadd
+STR_QUANTITY_BUBBLES :{COMMA} bubbl{P a or}
+STR_QUANTITY_TOFFEE :{WEIGHT} knäck
+STR_QUANTITY_BATTERIES :{COMMA} batteri{P "" er}
+STR_QUANTITY_PLASTIC :{VOLUME} plast
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} läsk
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}PS
+STR_ABBREV_COAL :{TINYFONT}KL
+STR_ABBREV_MAIL :{TINYFONT}PO
+STR_ABBREV_OIL :{TINYFONT}OL
+STR_ABBREV_LIVESTOCK :{TINYFONT}BO
+STR_ABBREV_GOODS :{TINYFONT}GD
+STR_ABBREV_GRAIN :{TINYFONT}SP
+STR_ABBREV_WOOD :{TINYFONT}TI
+STR_ABBREV_IRON_ORE :{TINYFONT}JÄ
+STR_ABBREV_STEEL :{TINYFONT}ST
+STR_ABBREV_VALUABLES :{TINYFONT}VÄ
+STR_ABBREV_COPPER_ORE :{TINYFONT}KO
+STR_ABBREV_MAIZE :{TINYFONT}MA
+STR_ABBREV_FRUIT :{TINYFONT}FR
+STR_ABBREV_DIAMONDS :{TINYFONT}DI
+STR_ABBREV_FOOD :{TINYFONT}MT
+STR_ABBREV_PAPER :{TINYFONT}PA
+STR_ABBREV_GOLD :{TINYFONT}GL
+STR_ABBREV_WATER :{TINYFONT}VA
+STR_ABBREV_WHEAT :{TINYFONT}VE
+STR_ABBREV_RUBBER :{TINYFONT}GU
+STR_ABBREV_SUGAR :{TINYFONT}SO
+STR_ABBREV_TOYS :{TINYFONT}LE
+STR_ABBREV_SWEETS :{TINYFONT}GO
+STR_ABBREV_COLA :{TINYFONT}KA
+STR_ABBREV_CANDYFLOSS :{TINYFONT}SS
+STR_ABBREV_BUBBLES :{TINYFONT}BU
+STR_ABBREV_TOFFEE :{TINYFONT}KN
+STR_ABBREV_BATTERIES :{TINYFONT}BA
+STR_ABBREV_PLASTIC :{TINYFONT}PL
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}LÄ
+STR_ABBREV_NONE :{TINYFONT}NEJ
+STR_ABBREV_ALL :{TINYFONT}ALLA
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Karta - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Spelinställningar
+STR_00B2_MESSAGE :{YELLOW}Meddelande
+STR_00B3_MESSAGE_FROM :{YELLOW}Meddelande från {STRING}
+STR_POPUP_CAUTION_CAPTION :{WHITE}Varning!
+STR_00B4_CAN_T_DO_THIS :{WHITE}Kan inte utföra detta...
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Kan inte röja området...
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Ursprunglig äganderätt {COPYRIGHT} 1995 Chris Sawyer, Alla rättigheter reserverade
+STR_00B7_VERSION :{BLACK}OpenTTD version {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 OpenTTD-teamet
+STR_TRANSLATED_BY :{BLACK} Översättare -
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Avsluta
+STR_00C8_YES :{BLACK}Ja
+STR_00C9_NO :{BLACK}Nej
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Vill du verkligen avsluta spelet och återvända till {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Inget
+STR_00D1_DARK_BLUE :Mörkblå
+STR_00D2_PALE_GREEN :Mattgrön
+STR_00D3_PINK :Rosa
+STR_00D4_YELLOW :Gul
+STR_00D5_RED :Röd
+STR_00D6_LIGHT_BLUE :Ljusblå
+STR_00D7_GREEN :Grön
+STR_00D8_DARK_GREEN :Mörkgrön
+STR_00D9_BLUE :Blå
+STR_00DA_CREAM :Gräddvit
+STR_00DB_MAUVE :Lila
+STR_00DC_PURPLE :Purpur
+STR_00DD_ORANGE :Orange
+STR_00DE_BROWN :Brun
+STR_00DF_GREY :Grå
+STR_00E0_WHITE :Vit
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}För många fordon i spelet
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Plats
+STR_00E5_CONTOURS :Konturer
+STR_00E6_VEHICLES :Fordon
+STR_00E7_INDUSTRIES :Industrier
+STR_00E8_ROUTES :Rutter
+STR_00E9_VEGETATION :Vegetation
+STR_00EA_OWNERS :Ägare
+STR_00EB_ROADS :{BLACK}{TINYFONT}Vägar
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Järnvägar
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Stationer/Flygplatser/Hamnar
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Byggnader/Industrier
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Fordon
+STR_00F0_100M :{BLACK}{TINYFONT}100m
+STR_00F1_200M :{BLACK}{TINYFONT}200m
+STR_00F2_300M :{BLACK}{TINYFONT}300m
+STR_00F3_400M :{BLACK}{TINYFONT}400m
+STR_00F4_500M :{BLACK}{TINYFONT}500m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}TÃ¥g
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Vägfordon
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Skepp
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Flygplan
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Transportrutter
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Kolgruva
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Kraftstation
+STR_00FC_FOREST :{BLACK}{TINYFONT}Skog
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}SÃ¥gverk
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Oljeraffinaderi
+STR_00FF_FARM :{BLACK}{TINYFONT}Bondgård
+STR_0100_FACTORY :{BLACK}{TINYFONT}Fabrik
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Tryckeri
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Oljekälla
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Järnmalmsgruva
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Stålverk
+STR_0105_BANK :{BLACK}{TINYFONT}Bank
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Pappersbruk
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Guldgruva
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Livsmedelsfabrik
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Diamantgruva
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Koppargruva
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Fruktplantage
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Gummiplantage
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Vattentillgång
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Vattentorn
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}SÃ¥gverk
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Sockervadd-skog
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Godisfabrik
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Batteribondgård
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Kolakälla
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Leksaksaffär
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Leksaksfabrik
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Plastfontäner
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Läskfabrik
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Bubbelgenerator
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Knäckbrott
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Sockergruva
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Järnvägsstation
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Lastbilsbrygga
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Busshållplats
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Flygplats/Helikopterplats
+STR_011F_DOCK :{BLACK}{TINYFONT}Hamn
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Obearbetad mark
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Gräsmark
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Barmark
+STR_0123_FIELDS :{BLACK}{TINYFONT}Fält
+STR_0124_TREES :{BLACK}{TINYFONT}Träd
+STR_0125_ROCKS :{BLACK}{TINYFONT}Stenar
+STR_0126_WATER :{BLACK}{TINYFONT}Vatten
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Ingen ägare
+STR_0128_TOWNS :{BLACK}{TINYFONT}Städer
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Industrier
+STR_012A_DESERT :{BLACK}{TINYFONT}Öken
+STR_012B_SNOW :{BLACK}{TINYFONT}Snö
+STR_012C_MESSAGE :{WHITE}Meddelande
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Avbryt
+STR_012F_OK :{BLACK}OK
+STR_0130_RENAME :{BLACK}Byt namn
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}För många namn definerade
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Namnet används redan
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...ägs av {STRING}
+STR_013C_CARGO :{BLACK}Gods
+STR_013D_INFORMATION :{BLACK}Information
+STR_013E_CAPACITIES :{BLACK}Kapaciteter
+STR_013E_TOTAL_CARGO :{BLACK}Gods Totalt
+STR_013F_CAPACITY :{BLACK}Kapacitet: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}Kapacitet: {LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}TÃ¥gets totala kapacitet:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}{CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}Nytt spel
+STR_0141_LOAD_GAME :{BLACK}Ladda spel
+STR_SINGLE_PLAYER :{BLACK}En spelare
+STR_MULTIPLAYER :{BLACK}Flera spelare
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Kartstorlek:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Spelinställningar
+
+STR_0150_SOMEONE :någon{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Världskarta
+STR_0152_TOWN_DIRECTORY :Stadslista
+STR_0153_SUBSIDIES :Subventioner
+
+STR_UNITS_IMPERIAL :Engelsk
+STR_UNITS_METRIC :Metrisk
+STR_UNITS_SI :SI
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} mph
+STR_UNITS_VELOCITY_METRIC :{COMMA} km/h
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}hk
+STR_UNITS_POWER_METRIC :{COMMA}hk
+STR_UNITS_POWER_SI :{COMMA}kW
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}T
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} ton{P "" s}
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} ton{P "" s}
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} kg
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}gal
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}l
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}m³
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} gallon{P "" s}
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} liter{P "" s}
+STR_UNITS_VOLUME_LONG_SI :{COMMA} m³
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10^3 lbf
+STR_UNITS_FORCE_METRIC :{COMMA} ton
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Graf över gångbar inkomst
+STR_0155_INCOME_GRAPH :Graf över inkomster
+STR_0156_DELIVERED_CARGO_GRAPH :Graf över levererat gods
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Graf över prestationshistorik
+STR_0158_COMPANY_VALUE_GRAPH :Graf över företagets värde
+STR_0159_CARGO_PAYMENT_RATES :Fraktförtjänster
+STR_015A_COMPANY_LEAGUE_TABLE :Tabell över ledande företag
+STR_PERFORMANCE_DETAIL_MENU :Detaljerade prestandabetyg
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}OpenTTD
+STR_015C_SAVE_GAME :Spara spelet
+STR_015D_LOAD_GAME :Ladda ett spel
+STR_015E_QUIT_GAME :Avsluta spelet
+STR_015F_QUIT :Avsluta
+STR_ABANDON_GAME_QUERY :{YELLOW}Vill du verkligen avsluta spelet?
+STR_0161_QUIT_GAME :{WHITE}Avsluta spelet
+STR_SORT_ORDER_TIP :{BLACK}Välj sorteringsordning (fallande/stigande)
+STR_SORT_CRITERIA_TIP :{BLACK}Välj sortering
+STR_SORT_BY :{BLACK}Sortera efter
+
+STR_SORT_BY_POPULATION :{BLACK}Befolkning
+STR_SORT_BY_PRODUCTION :{BLACK}Produktion
+STR_SORT_BY_TYPE :{BLACK}Typ
+STR_SORT_BY_TRANSPORTED :{BLACK}Transporterat
+STR_SORT_BY_NAME :{BLACK}Namn
+STR_SORT_BY_DROPDOWN_NAME :Namn
+STR_SORT_BY_DATE :{BLACK}Datum
+STR_SORT_BY_NUMBER :Nummer
+STR_SORT_BY_PROFIT_LAST_YEAR :Vinst förra året
+STR_SORT_BY_PROFIT_THIS_YEAR :Vinst i år
+STR_SORT_BY_AGE :Ã…lder
+STR_SORT_BY_RELIABILITY :PÃ¥litlighet
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Total kapacitet per godstyp
+STR_SORT_BY_MAX_SPEED :Maximal hastighet
+STR_SORT_BY_MODEL :
+STR_SORT_BY_VALUE :
+STR_SORT_BY_FACILITY :Stationstyp
+STR_SORT_BY_WAITING :Väntande last-värde
+STR_SORT_BY_RATING_MAX :Last Värdering
+STR_ENGINE_SORT_ENGINE_ID :MotorID (Klassisk Sort)
+STR_ENGINE_SORT_COST :Kostnad
+STR_ENGINE_SORT_POWER :Elektriskt
+STR_ENGINE_SORT_INTRO_DATE :Introduktionsdatum
+STR_ENGINE_SORT_RUNNING_COST :Driftkostnad
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Kraft/Driftkostnad
+STR_ENGINE_SORT_CARGO_CAPACITY :Lastkapacitet
+STR_NO_WAITING_CARGO :{BLACK}Ingen sorts last väntar
+STR_SELECT_ALL_FACILITIES :{BLACK}Markera alla inrättningar
+STR_SELECT_ALL_TYPES :{BLACK}Välj alla last-typer (inklusive icke väntande last)
+STR_AVAILABLE_ENGINES_TIP :{BLACK}Se lista med tillgängliga motordesigner för denna fordonstyp
+STR_MANAGE_LIST :{BLACK}Behandlingslista
+STR_MANAGE_LIST_TIP :{BLACK}Skicka instruktioner till alla fordon på denna lista
+STR_REPLACE_VEHICLES :Byt ut fordon
+STR_SEND_TRAIN_TO_DEPOT :Skicka till Depå
+STR_SEND_ROAD_VEHICLE_TO_DEPOT :Skicka till Depå
+STR_SEND_SHIP_TO_DEPOT :Skicka till Depå
+STR_SEND_AIRCRAFT_TO_HANGAR :Skicka till Hangar
+STR_SEND_FOR_SERVICING :Skicka till Service
+
+############ range for months starts
+STR_0162_JAN :jan
+STR_0163_FEB :feb
+STR_0164_MAR :mar
+STR_0165_APR :apr
+STR_0166_MAY :maj
+STR_0167_JUN :jun
+STR_0168_JUL :jul
+STR_0169_AUG :aug
+STR_016A_SEP :sep
+STR_016B_OCT :okt
+STR_016C_NOV :nov
+STR_016D_DEC :dec
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Pausa spelet
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Spara spelet, avbryt spelet, avsluta spelet
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Visa lista över företagets stationer
+STR_0174_DISPLAY_MAP :{BLACK}Visa karta
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Visa karta, lista av städer
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Visa lista av städer
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Visa finansinformation för företaget
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Visa allmän företagsinformation
+STR_0179_DISPLAY_GRAPHS :{BLACK}Visa grafer
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Visa ledande företag
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Visa lista av företagets tåg
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Visa lista av företagagets vägfordon
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Visa lista av företagets skepp
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Visa lista av företagets flygplan
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Zooma in
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Zooma ut
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Bygg järnväg
+STR_0182_BUILD_ROADS :{BLACK}Bygg vägar
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Bygg hamnar
+STR_0184_BUILD_AIRPORTS :{BLACK}Bygg flygplatser
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Plantera träd, placera skyltar etc.
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Markinformation
+STR_0187_OPTIONS :{BLACK}Inställningar
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Kan inte ändra service-intervall...
+STR_018B_CLOSE_WINDOW :{BLACK}Stäng fönster
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Fönstertitel - dra för att flytta fönstret
+STR_STICKY_BUTTON :{BLACK}Markera detta fönster så att det finns kvar även fast man använder 'Stäng alla fönster' knappen
+STR_RESIZE_BUTTON :{BLACK}Klicka och dra för att förstora fönstret
+STR_SAVELOAD_HOME_BUTTON :{BLACK}Klicka här för att gå till standardkatalogen för spara/ladda.
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Riv ned byggnader etc. på en ruta mark
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Sänk ett hörn av marken
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Höj upp ett hörn av marken
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Scrollbar - scrolla listan upp/ned
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Rullningslist - rullar listan höger/vänster
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Visa markkonturer på kartan
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Visa fordon på kartan
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Visa industrier på kartan
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Visa transportrutter på kartan
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Visa vegetation på kartan
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Visa markägare på kartan
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Växla stadsnamn av/på på kartan
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Vinst detta år: {CURRENCY} (förra året: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} år ({COMMA})
+STR_AGE_RED :{RED}{COMMA} år ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Vägfordon
+STR_019D_AIRCRAFT :Flygplan
+STR_019E_SHIP :Skepp
+STR_019F_TRAIN :TÃ¥g
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} börjar bli gammal
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} börjar bli väldigt gammal
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} börjar bli väldigt gammal och måste bytas ut
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Markinformation
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Kostnad att röja: {LTBLUE}N/A
+STR_01A5_COST_TO_CLEAR :{BLACK}Kostnad att röja: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :Otillgänglig
+STR_01A7_OWNER :{BLACK}Ägare: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Lokala myndigheter: {LTBLUE}{STRING}
+STR_01A9_NONE :Ingen
+STR_01AA_NAME :{BLACK}Namn
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1
+STR_01AD_2ND :2
+STR_01AE_3RD :3
+STR_01AF_4TH :4
+STR_01B0_5TH :5
+STR_01B1_6TH :6
+STR_01B2_7TH :7
+STR_01B3_8TH :8
+STR_01B4_9TH :9
+STR_01B5_10TH :10
+STR_01B6_11TH :11
+STR_01B7_12TH :12
+STR_01B8_13TH :13
+STR_01B9_14TH :14
+STR_01BA_15TH :15
+STR_01BB_16TH :16
+STR_01BC_17TH :17
+STR_01BD_18TH :18
+STR_01BE_19TH :19
+STR_01BF_20TH :20
+STR_01C0_21ST :21
+STR_01C1_22ND :22
+STR_01C2_23RD :23
+STR_01C3_24TH :24
+STR_01C4_25TH :25
+STR_01C5_26TH :26
+STR_01C6_27TH :27
+STR_01C7_28TH :28
+STR_01C8_29TH :29
+STR_01C9_30TH :30
+STR_01CA_31ST :31
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Accepterat gods: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Jazz Jukebox
+STR_01D3_SOUND_MUSIC :Ljud/musik
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Visa ljud-/musikfönster
+STR_01D5_ALL :{TINYFONT}Alla
+STR_01D6_OLD_STYLE :{TINYFONT}Gammaldags
+STR_01D7_NEW_STYLE :{TINYFONT}Modern
+STR_01D8_EZY_STREET :{TINYFONT}Ezy Street
+STR_01D9_CUSTOM_1 :{TINYFONT}Personlig 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Personlig 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Musikvolym
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Effektvolym
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MIN ' ' ' ' ' ' MAX
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Byt till föregående spår
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Byt till nästa spår
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Sluta spela musik
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Börja spela musik
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Dra för att ändra musik- och ljudvolym
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Spår{SETX 88}Titel
+STR_01E9_SHUFFLE :{TINYFONT}Slumpa
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Program
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Musikprogram
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Spårindex
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Program - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}Töm
+STR_01F1_SAVE :{TINYFONT}{BLACK}Spara
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Nuvarande program av musik
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Välj spellistan 'alla'
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Välj spellistan 'gammaldags'
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Välj spellistan 'modern'
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Välj spellistan 'Personlig 1' (användardefinerad)
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Välj spellistan 'Personlig 2' (användardefinerad)
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Töm aktuellt program (Enbart Personlig1 eller Personlig2)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Spara ljudinställningar
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Klicka på ett spår för att lägga till den till spellistan (Enbart Personlig1 eller Personlig2)
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Klicka på musikstycket för att ta bort det från den aktuella listan (endast Personlig1 och Personlig2)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Växla slumpning av/på
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Visa fönstret för val av musikspår
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Klicka för att centrera vyn ovanför industrin/staden
+STR_01FE_DIFFICULTY :{BLACK}Svårighetsgrad ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Senaste meddelandet/nyheten
+STR_0201_MESSAGE_SETTINGS :Meddelandeinställningar
+STR_MESSAGE_HISTORY_MENU :Meddelandehistorik
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Visa senaste meddelandet/nyheten, visa meddelandeinställningar
+STR_0204_MESSAGE_OPTIONS :{WHITE}Meddelandeinställningar
+STR_0205_MESSAGE_TYPES :{BLACK}Meddelandetyper:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Ankomst av första fordonet vid spelarens stn.
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Ankomst av första fordonet vid konkurrenternas stn.
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Olyckor / katastrofer
+STR_0209_COMPANY_INFORMATION :{YELLOW}Företagsinformation
+STR_020A_ECONOMY_CHANGES :{YELLOW}Förändringar av ekonomin
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}RÃ¥d / information om spelarens fordon
+STR_020C_NEW_VEHICLES :{YELLOW}Nya fordon
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Ändringar i godsacceptans
+STR_020E_SUBSIDIES :{YELLOW}Subventioner
+STR_020F_GENERAL_INFORMATION :{YELLOW}Generell information
+STR_MESSAGES_ALL :{YELLOW}Inställning för alla meddelandetyper (på/av/summarisk)
+STR_MESSAGE_SOUND :{YELLOW}Spela upp ljud för summariska nyhetsmeddelanden
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...för långt från föregående destination
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}De bästa företagen som nådde {NUM}{}(nivå {STRING})
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Företagslista för {NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Affärsman
+STR_0214_ENTREPRENEUR :Entreprenör
+STR_0215_INDUSTRIALIST :Industrialist
+STR_0216_CAPITALIST :Kapitalist
+STR_0217_MAGNATE :Magnat
+STR_0218_MOGUL :Mogul
+STR_0219_TYCOON_OF_THE_CENTURY :Ã…rhundradets Tycoon
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} uppnår '{STRING}' status!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} från {COMPANY} uppnår '{STRING}' status!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Nytt scenario
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Scenario-editor
+STR_0223_LAND_GENERATION :{WHITE}Skapa mark
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Slumpmässig mark
+STR_0227_RESET_LAND :{BLACK}Återställ mark
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Öka storlek av yta att höja/sänka
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Minska storlek av yta att höja/sänka
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Generera slumpmässig mark
+STR_022B_RESET_LANDSCAPE :{BLACK}Återställ landskapet
+STR_022C_RESET_LANDSCAPE :{WHITE}Återställ landskapet
+STR_LOAD_GAME_HEIGHTMAP :{WHITE}Använd höjdkarta
+STR_LOAD_SCEN_HEIGHTMAP :{BLACK}Använd höjdkarta
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Vill du verkligen återställa landskapet?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Skapa landskap
+STR_022F_TOWN_GENERATION :{BLACK}Bygg städer
+STR_0230_INDUSTRY_GENERATION :{BLACK}Bygg industrier
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Bygg vägar
+STR_0233_TOWN_GENERATION :{WHITE}Skapa städer
+STR_0234_NEW_TOWN :{BLACK}Ny stad
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Bygg ny stad
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Kan inte bygga stad här...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...för nära kartans kant
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...för nära en annan stad
+STR_0239_SITE_UNSUITABLE :{WHITE}...platsen passar inte
+STR_023A_TOO_MANY_TOWNS :{WHITE}...för många städer
+STR_CANNOT_GENERATE_TOWN :{WHITE}Kan inte bygga några städer.
+STR_NO_SPACE_FOR_TOWN :{WHITE}...det finns ingen plats kvar på kartan
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Öka stadens storlek
+STR_023C_EXPAND :{BLACK}Utöka
+STR_023D_RANDOM_TOWN :{BLACK}Slumpmässig stad
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Bygg stad på slumpmässig plats
+STR_023F_INDUSTRY_GENERATION :{WHITE}Bygg industrier
+STR_0240_COAL_MINE :{BLACK}Kolgruva
+STR_0241_POWER_STATION :{BLACK}Kraftstation
+STR_0242_SAWMILL :{BLACK}SÃ¥gverk
+STR_0243_FOREST :{BLACK}Skog
+STR_0244_OIL_REFINERY :{BLACK}Oljeraffinaderi
+STR_0245_OIL_RIG :{BLACK}Oljerigg
+STR_0246_FACTORY :{BLACK}Fabrik
+STR_0247_STEEL_MILL :{BLACK}Stålverk
+STR_0248_FARM :{BLACK}Bondgård
+STR_0249_IRON_ORE_MINE :{BLACK}Järnmalmsgruva
+STR_024A_OIL_WELLS :{BLACK}Oljekälla
+STR_024B_BANK :{BLACK}Bank
+STR_024C_PAPER_MILL :{BLACK}Pappersbruk
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Livsmedelsfabrik
+STR_024E_PRINTING_WORKS :{BLACK}Tryckeri
+STR_024F_GOLD_MINE :{BLACK}Guldgruva
+STR_0250_LUMBER_MILL :{BLACK}SÃ¥gverk
+STR_0251_FRUIT_PLANTATION :{BLACK}Fruktplantage
+STR_0252_RUBBER_PLANTATION :{BLACK}Gummiplantage
+STR_0253_WATER_SUPPLY :{BLACK}Vattentillgång
+STR_0254_WATER_TOWER :{BLACK}Vattentorn
+STR_0255_DIAMOND_MINE :{BLACK}Diamantgruva
+STR_0256_COPPER_ORE_MINE :{BLACK}Koppargruva
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Sockervaddskog
+STR_0258_CANDY_FACTORY :{BLACK}Godisfabrik
+STR_0259_BATTERY_FARM :{BLACK}Batteribondgård
+STR_025A_COLA_WELLS :{BLACK}Kolakälla
+STR_025B_TOY_SHOP :{BLACK}Leksaksaffär
+STR_025C_TOY_FACTORY :{BLACK}Leksaksfabrik
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Plastfontäner
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Läskfabrik
+STR_025F_BUBBLE_GENERATOR :{BLACK}Bubbelgenerator
+STR_0260_TOFFEE_QUARRY :{BLACK}Knäckbrott
+STR_0261_SUGAR_MINE :{BLACK}Sockergruva
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Bygg kolgruva
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Bygg kraftstation
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Bygg sågverk
+STR_0265_PLANT_FOREST :{BLACK}Plantera skog
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Bygg oljeraffinaderi
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Bygg oljerigg (Kan bara byggas nära kartans kant)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Bygg fabrik
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Bygg stålverk
+STR_026A_CONSTRUCT_FARM :{BLACK}Bygg bondgård
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Bygg järnmalmsgruva
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Bygg oljekälla
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Bygg bank (Kan bara byggas i städer med fler än 1200 invånare)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Bygg pappersbruk
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Bygg livsmedelsfabrik
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Bygg tryckeri
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Bygg guldgruva
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Bygg bank (Kan bara byggas i städer)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Bygg sågverk (För att hugga ned skog och producera timmer)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Plantera fruktplantage
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Plantera gummiplantage
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Bygg vattentillgång
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Bygg vattentorn (Kan bara byggas i städer)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Bygg diamantgruva
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Bygg koppargruva
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Plantera Sockervaddskog
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Bygg godisfabrik
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Bygg batteribondgård
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Bygg kolakälla
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Bygg leksaksaffär
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Bygg leksaksfabrik
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Bygg plastfontäner
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Bygg läskfabrik
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Bygg bubbelgenerator
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Bygg knäckbrott
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Bygg sockergruva
+STR_0285_CAN_T_BUILD_HERE :{WHITE}Kan inte bygga {STRING} här...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...måste bygga stad först
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...endast en per stad
+STR_0288_PLANT_TREES :{BLACK}Plantera träd
+STR_0289_PLACE_SIGN :{BLACK}Placera skylt
+STR_028A_RANDOM_TREES :{BLACK}Slumpmässigt träd
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Plantera träd slumpmässigt över landskapet
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Placera stenar i landskapet
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Placera fyrtorn
+STR_028E_PLACE_TRANSMITTER :{BLACK}Placera radiosändare
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Definiera ökenområde.{}Tryck och håll CTRL för att ta bort
+STR_CREATE_LAKE :{BLACK}Definiera vattenområde.{}Den fyller närområdet om det ligger i sjönivå
+STR_0290_DELETE :{BLACK}Ta bort
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Ta bort staden helt och hållet
+STR_0292_SAVE_SCENARIO :Spara scenario
+STR_0293_LOAD_SCENARIO :Öppna scenario
+STR_0294_QUIT_EDITOR :Avsluta editor
+STR_0295 :
+STR_0296_QUIT :Avsluta
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Spara scenario, öppna scenario, avbryt scenarioeditor, avsluta
+STR_0298_LOAD_SCENARIO :{WHITE}Öppna scenario
+STR_0299_SAVE_SCENARIO :{WHITE}Spara scenario
+STR_029A_PLAY_SCENARIO :{BLACK}Spela scenario
+STR_PLAY_HEIGHTMAP :{BLACK}Spela höjdkarta
+STR_PLAY_HEIGHTMAP_HINT :{BLACK}Starta ett nytt spel, och använd en höjdkarta som landskap
+STR_QUIT_SCENARIO_QUERY :{YELLOW}Vill du verkligen avsluta detta scenario?
+STR_029C_QUIT_EDITOR :{WHITE}Avsluta editor
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...kan bara byggas i städer med minst 1200 invånare
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Flytta startdatumet 1 år bakåt
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Flytta startdatumet 1 år framåt
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...brons ändar måste båda vara på land
+STR_02A1_SMALL :{BLACK}Liten
+STR_02A2_MEDIUM :{BLACK}Mellan
+STR_02A3_LARGE :{BLACK}Stor
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Välj stadsstorlek
+STR_02A5_TOWN_SIZE :{YELLOW}Stadsstorlek:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Visa senaste meddelande eller nyhet
+STR_OFF :Av
+STR_SUMMARY :Summering
+STR_FULL :Full
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Lista med städer
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Fordonens modellnamn
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Original
+STR_02BF_CUSTOM :Egna
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Spara egna namn
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Fordonens modellnamnssortiment
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Spara egna modellnamn för fordon till disk
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Spelinställningar
+STR_02C5_DIFFICULTY_SETTINGS :Svårighetsgrad
+STR_02C7_CONFIG_PATCHES :Ändra Patchar
+STR_NEWGRF_SETTINGS :Newgrf inställningar
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Stadsnamn visas
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Stationsnamn visas
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Skyltar visas
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Kontrollstationer visas
+STR_02D0_FULL_ANIMATION :{SETX 12}Full animation
+STR_02D2_FULL_DETAIL :{SETX 12}Full detaljnivå
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Genomskinliga byggnader
+STR_TRANSPARENT_SIGNS :{SETX 12}Genomskinliga stationsskyltar
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Information om mark
+STR_02D6 :
+STR_CONSOLE_SETTING :Visa/dölj konsolen
+STR_02D7_SCREENSHOT_CTRL_S :Screenshot (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Gigantisk Screenshot (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :Om 'OpenTTD'
+############ range ends here
+
+STR_02DB_OFF :{BLACK}Av
+STR_02DA_ON :{BLACK}PÃ¥
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Visa subventioner
+STR_02DD_SUBSIDIES :Subventioner
+STR_02DE_MAP_OF_WORLD :Världskarta
+STR_EXTRA_VIEW_PORT :Nytt vy fönster
+STR_SIGN_LIST :Skyltlista
+STR_02DF_TOWN_DIRECTORY :Stadslista
+STR_TOWN_POPULATION :{BLACK}Världsbefolkning: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Vy fönster {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Kopiera till vy
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Kopiera kartans position till detta Vyfönster
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Klistra in vyn
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Flytta kartans position till den här vyn
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Valutaenheter
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Välj valutaenhet
+STR_MEASURING_UNITS :{BLACK}Mätenheter
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Val av mätenheter
+STR_02E6_ROAD_VEHICLES :{BLACK}Vägfordon
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Välj sida av vägen som fordonen kör på
+STR_02E9_DRIVE_ON_LEFT :Kör på vänster sida
+STR_02EA_DRIVE_ON_RIGHT :Kör på höger sida
+STR_02EB_TOWN_NAMES :{BLACK}Stadsnamn
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Välj typ av stadsnamn
+
+STR_02F4_AUTOSAVE :{BLACK}Autosparning
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Välj intervall mellan automatiskt sparande
+STR_02F7_OFF :Avstängd
+STR_02F8_EVERY_3_MONTHS :Var 3:e månad
+STR_02F9_EVERY_6_MONTHS :Var 6:e månad
+STR_02FA_EVERY_12_MONTHS :Var 12:e månad
+STR_02FB_START_A_NEW_GAME :{BLACK}Starta ett nytt spel
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Ladda ett sparat spel
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Skapa en egen spelvärld/scenario
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Välj Single-Player spel
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Välj nätverksspel med 2-8 spelare
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Visa spelinställningar
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Visa inställningar för svårighetsgrad
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Starta nytt spel, som använder ett eget scenario
+STR_0304_QUIT :{BLACK}Avsluta
+STR_0305_QUIT_OPENTTD :{BLACK}Avsluta 'OpenTTD'
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...kan bara byggas i städer
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Välj 'tempererad' typ av landskap
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Välj 'sub-arktiskt' typ av landskap
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Välj 'sub-tropiskt' typ av landskap
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Välj 'leksaksland' som typ av landskap
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Bekosta bygget av en ny industri
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Industriförteckning
+STR_0313_FUND_NEW_INDUSTRY :Bekosta ny industri
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Bekosta ny industri
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...kan bara byggas i städer
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...kan bara byggas i regnskog
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...kan bara byggas i öken
+STR_0319_PAUSED :{YELLOW}* * PAUSAD * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Screenshot sparades som '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}Screenshot misslyckades!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Köp mark för framtida användning
+STR_032F_AUTOSAVE :{RED}AUTOSPARNING
+STR_SAVING_GAME :{RED}* * SPARAR SPEL * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}Sparar fortfarande,{}vänta tills det är slutfört!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Välj 'Ezy Street style music'-program
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :Engelska
+STR_TOWNNAME_FRENCH :Franska
+STR_TOWNNAME_GERMAN :Tyska
+STR_TOWNNAME_ADDITIONAL_ENGLISH :Engelska (Extra)
+STR_TOWNNAME_LATIN_AMERICAN :Latinamerikanska
+STR_TOWNNAME_SILLY :Löjliga
+STR_TOWNNAME_SWEDISH :Svenska
+STR_TOWNNAME_DUTCH :Hollänska
+STR_TOWNNAME_FINNISH :Finska
+STR_TOWNNAME_POLISH :Polska
+STR_TOWNNAME_SLOVAKISH :Slovakiska
+STR_TOWNNAME_NORWEGIAN :Norska
+STR_TOWNNAME_HUNGARIAN :Hungarianska
+STR_TOWNNAME_AUSTRIAN :Australienska
+STR_TOWNNAME_ROMANIAN :Rumänska
+STR_TOWNNAME_CZECH :Tjeckiska
+STR_TOWNNAME_SWISS :Schweiziska
+STR_TOWNNAME_DANISH :Danska
+STR_TOWNNAME_TURKISH :Turkiska
+STR_TOWNNAME_ITALIAN :Italienska
+STR_TOWNNAME_CATALAN :Katalan
+############ end of townname region
+
+STR_CURR_GBP :Pund (£)
+STR_CURR_USD :Dollar ($)
+STR_CURR_EUR :Euro (€)
+STR_CURR_YEN :Yen (Â¥)
+STR_CURR_ATS :Österrikiska shilling (ATS)
+STR_CURR_BEF :Belgiska franc (BEF)
+STR_CURR_CHF :Schweiziska franc (CHF)
+STR_CURR_CZK :Tjeckiska kronor (CZK)
+STR_CURR_DEM :Tyska mark (DEM)
+STR_CURR_DKK :Danska kronor (DKK)
+STR_CURR_ESP :Peseta (ESP)
+STR_CURR_FIM :Finska mark (FIM)
+STR_CURR_FRF :Franc (FRF)
+STR_CURR_GRD :Grekiska drachmer (GRD)
+STR_CURR_HUF :Ungerska Forint (HUF)
+STR_CURR_ISK :Isländska kronor (ISK)
+STR_CURR_ITL :Italienska lire (ITL)
+STR_CURR_NLG :Holländska guilder (NLG)
+STR_CURR_NOK :Norska kronor (NOK)
+STR_CURR_PLN :Polska Zloty (PLN)
+STR_CURR_ROL :RumÀnsk Leu (ROL)
+STR_CURR_RUR :Ryska rubel (RUR)
+STR_CURR_SIT :Slovenska Tolar (SIT)
+STR_CURR_SEK :Svenska kronor (SEK)
+STR_CURR_YTL :Turkisk Lire (YTL)
+STR_CURR_SKK :Slovakisk Koruna (SKK)
+STR_CURR_BRR :Brasiliansk Real (BRL)
+
+STR_CURR_CUSTOM :Egen...
+
+STR_OPTIONS_LANG :{BLACK}Språk
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Välj språk att använda
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Helskärm
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}Kryssa i den här rutan för att spela OpenTTD i helskärmsläge
+
+STR_OPTIONS_RES :{BLACK}Skärmupplösning
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Välj skärmupplösning att använda
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Skärmdumpsformat
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Välj filformat för skärmdump
+
+STR_AUTOSAVE_1_MONTH :Varje månad
+STR_AUTOSAVE_FAILED :{WHITE}Autosparning misslyckades
+
+STR_MONTH_JAN :januari
+STR_MONTH_FEB :februari
+STR_MONTH_MAR :mars
+STR_MONTH_APR :april
+STR_MONTH_MAY :maj
+STR_MONTH_JUN :juni
+STR_MONTH_JUL :juli
+STR_MONTH_AUG :augusti
+STR_MONTH_SEP :september
+STR_MONTH_OCT :oktober
+STR_MONTH_NOV :november
+STR_MONTH_DEC :december
+
+STR_HEADING_FOR_STATION :{LTBLUE}På väg mot {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}På väg mot {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Inga order
+STR_NO_ORDERS_VEL :{LTBLUE}Inga order, {VELOCITY}
+
+STR_PASSENGERS :passagerare
+STR_BAGS :väskor
+STR_TONS :ton
+STR_LITERS :liter
+STR_ITEMS :föremål
+STR_CRATES :lådor
+STR_RES_OTHER :annan
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Kan inte dela orderlistan...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Kan inte kopiera orderlistan...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - Slut på delade order - -
+
+STR_TRAIN_IS_LOST :{WHITE}TÃ¥g {COMMA} har tappat bort sig.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}Tåg {COMMA}s vinst förra året var {CURRENCY}
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}Europeiska Valutasystemet!{}{}Euron introduceras och ditt land går över till den som dess enda valuta!
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Tåg {COMMA} har för få destinationer
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}TÃ¥g {COMMA} har en bruten destination
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}TÃ¥g {COMMA} har dubblerade destinationer
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}TÃ¥g {COMMA} har en felaktig station ibland destinationerna
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}Vägfordon {COMMA} har för få destinationer
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}Vägfordon {COMMA} har en bruten destination
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}Vägfordon {COMMA} har dubblerade destinationer
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}Vägfordon {COMMA} har en felaktig station ibland destinationerna
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}Skepp {COMMA} har för få destinationer
+STR_SHIP_HAS_VOID_ORDER :{WHITE}Skepp {COMMA} har en bruten destination
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}Skepp {COMMA} har dubblerade destinationer
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}Skepp {COMMA} har en felaktig station ibland destinationerna
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}Flygplan {COMMA} har för få destinationer
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}Flygplan {COMMA} har en bruten destination
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}Flygplan {COMMA} har dubblerade destinationer
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}Flygplan {COMMA} har en felaktig station ibland destinationerna
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}Automatiska förnyandet av tåg {COMMA} misslyckades (inte tillräckligt med pengar)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}Automatiska förnyandet av vägfordon {COMMA} misslyckades (otillräckligt med pengar)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}Automatiska förnyandet av skepp {COMMA} misslyckades (otillräckligt med pengar)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}Automatiska förnyandet av flygplan {COMMA} misslyckades (inte tillräckligt med pengar)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}Tåg {COMMA} är för långt efter förnyandet
+
+STR_CONFIG_PATCHES :{BLACK}Konfigurera patchar
+STR_CONFIG_PATCHES_TIP :{BLACK}Konfigurera patcharna
+STR_CONFIG_PATCHES_CAPTION :{WHITE}Konfigurera patchar
+
+STR_CONFIG_PATCHES_OFF :Av
+STR_CONFIG_PATCHES_ON :PÃ¥
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Visa fordonshastighet i statusfältet: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Tillåt byggnation på sluttningar och kuster: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Tillåt mer realistiska uppsamlingsområden för stationer: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Tillåt borttagning av mera stadsägda vägar etc.: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Tillåt väldigt långa tåg: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Aktivera realistisk acceleration för tåg: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Förbjud tåg och skepp att göra 90° svängar: {ORANGE}{STRING} {LTBLUE} (kräver NPF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Kombinera tågstationer som byggs bredvid varandra: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Lämna stationen när något gods är fullt, om 'full load': {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Använd förbättrad algoritm: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GRADUAL_LOADING :{LTBLUE}Lasta fordon gradvis: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Inflation: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Leverera gods till en station enbart om någon frågar efter det: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Tillåt väldigt långa broar: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Tillåt order att gå till depå/bussgarage: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Tillåt byggnation av råmaterialsproducerande industrier: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Tillåt flera industrier av samma typ per stad: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Industrier av samma typ kan byggas nära varandra: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Visa alltid långt datum i statusfältet: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Visa signaler på körsidan: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Visa finansfönstret vid slutet av året: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}TTDPatch-kompatibel nonstop-hantering: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Vägfordonsköer (med kvanteffekter): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Scrolla vyn när musen är vid kanten: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Tillåt mutning av de lokala myndigheterna: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Icke-rektangulära stationer: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Ny globalt sätt att hitta rutt (NPF, åsidosätter NTP): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FREIGHT_TRAINS :{LTBLUE}Godsfaktor för att simulera tunga tåg: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Tillåt alltid små flygplatser: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Varna om tåg åker vilse: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Granska fordonens destinationer: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :nej
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :ja, förutom stannade fordon
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :ja, på alla fordon
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Varna om ett tågs inkomst är negativ: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Fordon blir aldrig gamla: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Förnya fordon automatiskt när dom blir gamla
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Förnya automatiskt fordon {ORANGE}{STRING}{LTBLUE} månader före/efter maximal ålder
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Minst mängd pengar för auto-förnyelse av fordon: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Hur länge felmeddelanden visas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Visa befolkningsmängd i stadsnamnet: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Osynliga träd (när genomskinliga byggnader är valt): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Land generator: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :Original
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis
+STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}Max avstånd ifrån kanten för oljeraffinaderier {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Snölinjeshöjd: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN :{LTBLUE}Terrängens svårhetsgrad (TerraGenesis endast) : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Väldigt lätt
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH :Lätt
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH :Svår
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :Väldigt svår
+STR_CONFIG_PATCHES_TREE_PLACER :{LTBLUE}Trädplacerings-algoritm: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TREE_PLACER_NONE :Inget
+STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL :Original
+STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED :Förbättrad
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION :{LTBLUE}Höjkartans rotation: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Motsols
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE :Medsols
+STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT :{LTBLUE}Vilken nivåhöjd en platt scenario-karta får: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Max spridning av station: {ORANGE}{STRING} {RED}Varning: Hög inställning slöar ner spelet
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Serva helikoptrar vid landningplattor automatiskt: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Koppla landskapsverktyget till övriga verktygsfält: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Omvänd scrollriktning: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Visa måtthjälptext vid användning av byggverktyg: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Visa färgschema för företag: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES_NONE :Inga
+STR_CONFIG_PATCHES_LIVERIES_OWN :Egna företaget
+STR_CONFIG_PATCHES_LIVERIES_ALL :Alla företag
+STR_CONFIG_PATCHES_PREFER_TEAMCHAT :{LTBLUE}Prioritera lagchat med <ENTER>: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Max antal tåg per spelare: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Max antal vägfordon per spelare: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}Max antal flygplan per spelare: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}Max antal skepp per spelare: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Förbjud tåg för datorn: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Förbjud vägfordon för datorn: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Förbjud flygplan för datorn: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Förbjud skepp för datorn: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Dator med ny AI (alpha): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Tillåt AI i multiplayer (expermientellt): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Standard serviceintervall för tåg: {ORANGE}{STRING} dagar/%
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Standard serviceintervall för tåg: {ORANGE}av
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Standard serviceintervall för vägfordon: {ORANGE}{STRING} dagar/%
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Standard serviceintervall för vägfordon: {ORANGE}av
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Standard serviceintervall för flygplan: {ORANGE}{STRING} dagar/%
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Standard serviceintervall för flygplan: {ORANGE}av
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Standard serviceintervall för skepp: {ORANGE}{STRING} dagar/%
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Standard serviceintervall för skepp: {ORANGE}av
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Avaktivera service när motorstopp är av: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Använd hastighetsbegränsningar för tågvagnar: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}Stäng av elektriska spår: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Färgade nyheter visas i: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Startdatum: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}Avsluta spelet år: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Lugn ekonomi (flera små ändringar)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Tillåt inköp av aktier från andra företag
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Vid utdragning av signaler, placera en signal var: {ORANGE}{STRING} ruta
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Position av verktygsraden: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Vänster
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Centrerad
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Höger
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Fönstersnäppsradie: {ORANGE}{STRING} px
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Fönstersnäppsradie: {ORANGE}avaktiverad
+
+STR_CONFIG_PATCHES_GUI :{BLACK}Gränssnitt
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Konstruktion
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Fordon
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Stationer
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Ekonomi
+STR_CONFIG_PATCHES_AI :{BLACK}Motståndare
+
+STR_CONFIG_PATCHES_DISABLED :Avaktiverat
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Ändra inställningsvärde
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Några eller alla av standard serviceintervalls-inställningarna är felaktiga! (5-90% och 30-800 dagar är giltiga inställningar)
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}Använd YAPF för skepp: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}Använd YAPF för fordon: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}Använd YAPF för tåg: {ORANGE}{STRING}
+
+STR_TEMPERATE_LANDSCAPE :Tempererat landskap
+STR_SUB_ARCTIC_LANDSCAPE :Sub-arktiskt landskap
+STR_SUB_TROPICAL_LANDSCAPE :Sub-tropiskt landskap
+STR_TOYLAND_LANDSCAPE :Leksakslandskap
+
+STR_CHEATS :{WHITE}Fusk
+STR_CHEATS_TIP :{BLACK}Checkboxar indikerar om du använt det här fusket förut
+STR_CHEATS_WARNING :{BLACK}Varning! Du är på väg att förråda dina motståndare. Kom ihåg att detta inte kommer glömmas.
+STR_CHEAT_MONEY :{LTBLUE}Öka pengar med {CURRENCY64}
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Spela som Spelare: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Magisk Bulldozer (ta bort industrier, fyrar etc.): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Tunnlar kan korsa varandra: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Bygga i pause-läge: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Jetplan kommer inte att störta (frekvent) på små flygplatser: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Byt klimat: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Byt datum: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}Aktivera modifierande produceringsvärden: {ORANGE}{STRING}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}På väg mot {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}På väg mot {WAYPOINT}, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :GÃ¥ via {WAYPOINT}
+STR_GO_NON_STOP_TO_WAYPOINT :GÃ¥ via {WAYPOINT} utan att stanna
+
+STR_WAYPOINTNAME_CITY :Kontrollstation {TOWN}
+STR_WAYPOINTNAME_CITY_SERIAL :Kontrollstation {TOWN} #{COMMA}
+STR_LANDINFO_WAYPOINT :Kontrollpunkt
+
+STR_WAYPOINT :{WHITE}Kontrollstation
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Välj kontrollstationstyp
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}Ändra namn på kontrollstation
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Kan inte ändra kontrollstationens namn...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Ändra räls till kontrollstation
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Kan inte bygga tågkontrollstation här...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Kan inte ta bort tågkontrollstation här...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Bygg järnvägspår genom att använda Autorail-funktionen
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}...det finns ingen stad i detta scenario
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}Är du säker på att du vill generera ett slumpmässigt landskap?
+STR_MANY_RANDOM_TOWNS :{BLACK}Många slumpmässiga städer
+STR_RANDOM_TOWNS_TIP :{BLACK}Täck kartan med slumpmässigt placerade städer
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Många slumpmässiga industrier
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Täck kartan med slumpmässigt placerade industrier
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Kan inte generera industrier...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Öppna landskapsarkitektursverktygen för att bla höja/sänka land, plantera träd, osv
+STR_LANDSCAPING_TOOLBAR :{WHITE}Landskapsarkitektur
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Utjämna land
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Träd av olika typ
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}Placera träd av olika typ
+
+STR_CANT_BUILD_CANALS :{WHITE}Kan inte bygga kanaler här...
+STR_BUILD_CANALS_TIP :{BLACK}Bygg kanaler. Håll ner CTRL för att bygga vid angränsande vatten.
+STR_LANDINFO_CANAL :Kanal
+
+STR_CANT_BUILD_LOCKS :{WHITE}Kan inte bygga slussar här...
+STR_BUILD_LOCKS_TIP :{BLACK}Bygg slussar
+STR_LANDINFO_LOCK :Sluss
+
+STR_BUOY_IS_IN_USE :{WHITE}... bojen används!
+
+STR_LANDINFO_COORDS :{BLACK}Koordinater: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Kan ej ta bort del av station...
+STR_CANT_CONVERT_RAIL :{WHITE}Kan inte konvertera spårtyp här...
+STR_CONVERT_RAIL_TIP :{BLACK}Konvertera/Uppgradera spårtyp
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Drag loket här för att sälja hela tåget
+
+STR_DRAG_DROP :{BLACK}Drag & Släpp
+STR_STATION_DRAG_DROP :{BLACK}Bygg en station genom drag & släpp
+STR_SELECT_STATION_CLASS_TIP :{BLACK}Välj vilken stationsklass som ska visas
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Välj stationstyp att bygga
+
+STR_FAST_FORWARD :{BLACK}Snabbspola spelet
+STR_MESSAGE_HISTORY :{WHITE}Meddelandehistorik
+STR_MESSAGE_HISTORY_TIP :{BLACK}En lista av dom senaste nyheterna
+STR_MESSAGES_DISABLE_ALL :{BLACK}Avaktivera alla
+STR_MESSAGES_ENABLE_ALL :{BLACK}Aktivera alla
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Bygg kolgruva
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Plantera skog
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Bygg oljerigg
+STR_CONSTRUCT_FARM_TIP :{BLACK}Bygg farm
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Bygg koppargruva
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Bygg oljekälla
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Bygg guldgruva
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Bygg diamantgruva
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Bygg järnmalmsgruva
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Plantera fruktplantage
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Plantera gummiplantage
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Bygg vattentillgång
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Plantera sockervaddskog
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}Bygg batteribondgård
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Bygg kolakälla
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Bygg plastfontäner
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Bygg bubbelgenerator
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Bygg knäckbrott
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Bygg sockergruva
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Industrier
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA}% transporterat)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA}%/{COMMA}% transporterat)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}... för nära en annan industri
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Anpassa tåg för att bära annan godstyp
+STR_RAIL_REFIT_VEHICLE :{BLACK}Anpassa tåg
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Välj godstyp för tåget att bära
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Anpassa tåg för att bära vald godstyp
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Kan ej anpassa tåg...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Visa serviceintervall i procent: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Ändra produktion
+
+TEMP_AI_IN_PROGRESS :{WHITE}Välkommen till denna nya AI, under uppbyggnad. Du kan räkna med att det finns problem med den. När något sådant händer, ta en skärmdump och lägg ut den på forumet. Mycket nöje!
+TEMP_AI_ACTIVATED :{WHITE}Varning: den nya AI:n är fortfarande i alpha-stadiet! Just nu funkar bara vägfordon!
+TEMP_AI_MULTIPLAYER :{WHITE}Varning: implementeringen är fortfarande experimentell (vid användandet den nya AI:n). Vänligen rapportera alla problem till truelight@openttd.org.
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Flera spelare
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Spelarnamn:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}Namnet som andra spelare kommer se dig under
+STR_NETWORK_CONNECTION :{BLACK}Anslutning:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Välj mellan att spela över internet eller det lokala nätverket
+
+STR_NETWORK_START_SERVER :{BLACK}Starta server
+STR_NETWORK_START_SERVER_TIP :{BLACK}Starta en server för andra att ansluta till
+
+STR_NETWORK_GAME_NAME :{BLACK}Namn
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Namn på nätverksspelet
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Språk, server version, mm
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Klicka på ett spel från listan för att välja det
+
+STR_NETWORK_FIND_SERVER :{BLACK}Leta server
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Leta på nätverket efter en server
+STR_NETWORK_ADD_SERVER :{BLACK}Lägg till server
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Lägg till en server till listan som alltid kommer kontrolleras för aktiva spel.
+STR_NETWORK_ENTER_IP :{BLACK}IP-adressen till servern
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Klienter
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Klienter online / Klienter max
+STR_NETWORK_GAME_INFO :{SILVER}SPELINFO
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Klienter: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Språk: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Klimat: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Kartstorlek: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}Serverversion: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}Server adress: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Startdatum: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Nuvarande datum: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Lösenordsskyddad!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}SERVER AVSTÄNGD
+STR_NETWORK_SERVER_FULL :{SILVER}SERVER FULL
+STR_NETWORK_VERSION_MISMATCH :{SILVER}VERSIONERNA FUNKAR INTE IHOP
+STR_NETWORK_GRF_MISMATCH :{SILVER}NewGRF Matchar Ej
+
+STR_NETWORK_JOIN_GAME :{BLACK}GÃ¥ med i spelet
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}Starta ett nytt multiplayer spel
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Namn:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}Namnet på nätverksspelet kommer att synas för andra spelare i multiplayer menyn
+STR_NETWORK_SET_PASSWORD :{BLACK}Ange lösenord
+STR_NETWORK_PASSWORD_TIP :{BLACK}Skydda spelet med ett lösenord så att inte andra än dom som har lösenordet kan gå med i spelet
+STR_NETWORK_SELECT_MAP :{BLACK}Välj karta:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}Vilken karta vill du spela?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}Max antal tillåtna klienter:
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Välj max antal tillåtna klienter. Alla platser måste inte fyllas.
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :LAN
+STR_NETWORK_INTERNET :Internet
+STR_NETWORK_LAN_INTERNET :LAN / Internet
+STR_NETWORK_INTERNET_ADVERTISE :Internet (publik)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 spelare
+STR_NETWORK_1_PLAYERS :1 spelare
+STR_NETWORK_2_PLAYERS :2 spelare
+STR_NETWORK_3_PLAYERS :3 spelare
+STR_NETWORK_4_PLAYERS :4 spelare
+STR_NETWORK_5_PLAYERS :5 spelare
+STR_NETWORK_6_PLAYERS :6 spelare
+STR_NETWORK_7_PLAYERS :7 spelare
+STR_NETWORK_8_PLAYERS :8 spelare
+STR_NETWORK_9_PLAYERS :9 spelare
+STR_NETWORK_10_PLAYERS :10 spelare
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}Max företag:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Begränsa antalet företag på servern
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}Max observatörer:
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Begränsa antalet observatörer på servern
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Språk som talas:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Andra spelare kommer vara medvetna vilket språk som talas på servern.
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}Starta spelet
+STR_NETWORK_START_GAME_TIP :{BLACK}Starta ett nytt spel med en slumpmässig karta eller från ett scenario
+STR_NETWORK_LOAD_GAME :{BLACK}Ladda spel
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Återuppta ett tidigare sparat spel för flera spelare (tänk på att välja rätt spelare vid start)
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Valfritt
+STR_NETWORK_LANG_ENGLISH :Engelska
+STR_NETWORK_LANG_GERMAN :Tyska
+STR_NETWORK_LANG_FRENCH :Franska
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Nätverksspel
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Förbereder att ansluta: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}En lista på alla nuvarande företag som är i spelet. Du kan antingen ansluta till ett befintligt eller starta ett nytt på en ledig plats
+STR_NETWORK_NEW_COMPANY :{BLACK}Nytt företag
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Starta ett nytt företag
+STR_NETWORK_SPECTATE_GAME :{BLACK}Titta på spelet
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Titta på spelet som en åskådare
+STR_NETWORK_JOIN_COMPANY :{BLACK}Anslut till företag
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Hjälp till att styra detta företag
+STR_NETWORK_REFRESH :{BLACK}Uppdatera server
+STR_NETWORK_REFRESH_TIP :{BLACK}Uppdatera server info
+
+STR_NETWORK_COMPANY_INFO :{SILVER}FÖRETAGSINFO
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Företagsnamn: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}Etableringsår: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}Företagsvärde: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Nuvarande saldo: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Förra årets inkomst: {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}Prestandabetyg: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}Fordon: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Stationer: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Spelare: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}Ansluter...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) Ansluter..
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Godkänner..
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Väntar..
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Laddar hem karta..
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Behandlar data..
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) Registrerar..
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Hämtar spelinfo..
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Hämtar företagsinfo..
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} klient{P "" er} före oss
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} kbyte nerladdat hittills
+
+STR_NETWORK_DISCONNECT :{BLACK}Frånkopplad
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Ange beloppet du vill ge
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Servern är skyddad. Ange lösenord
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Företaget är skyddat. Ange lösenord
+STR_NETWORK_CLIENT_LIST :{WHITE}Klientlista
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE}Inget nätverkskort funnet eller så är spelet kompilerat utan ENABLE_NETWORK
+STR_NETWORK_ERR_NOSERVER :{WHITE}Kunde inte hitta några nätverksspel
+STR_NETWORK_ERR_NOCONNECTION :{WHITE}Servern svarade inte på förfrågan
+STR_NETWORK_ERR_DESYNC :{WHITE}Nätverk, Spelsynkronisering misslyckades
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE}Nätverk, koppling förlorad
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE}Kunde inte ladda det sparade spelet från servern
+STR_NETWORK_ERR_SERVER_START :{WHITE} Kunde inte starta servern.
+STR_NETWORK_ERR_CLIENT_START :{WHITE} Kunde inte ansluta.
+STR_NETWORK_ERR_TIMEOUT :{WHITE}Nätverkskoppling #{NUM} förlorad (klient slutade svara)
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE} Ett protokollfel uppstod och anslutningen stängdes.
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE} Servern har en annan version än denna klient.
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} Fel lösenord.
+STR_NETWORK_ERR_SERVER_FULL :{WHITE} Servern är full
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} Du är bannlyst från den här servern
+STR_NETWORK_ERR_KICKED :{WHITE} Du är utkastad från servern
+STR_NETWORK_ERR_CHEATER :{WHITE} Fusk är inte tillåtet på denna server
+
+STR_NETWORK_ERR_LEFT :har lämnat spelet
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :allmänt fel
+STR_NETWORK_ERR_CLIENT_DESYNC :synkroniseringsfel
+STR_NETWORK_ERR_CLIENT_SAVEGAME :kunde inte ladda kartan
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :anslutning förlorad
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :protokollfel
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :inte godkänd
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :mottog konstigt paket
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :fel revision
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :namnet används redan
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :fel lösenord
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :fel spelar-id i DoCommand
+STR_NETWORK_ERR_CLIENT_KICKED :utkastad av servern
+STR_NETWORK_ERR_CLIENT_CHEATER :försökte fuska
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :servern är full
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :har anslutit till spelet
+STR_NETWORK_GIVE_MONEY :gav dig en del pengar ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :Du gav {STRING} en del pengar ({CURRENCY})
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Företaget] :
+STR_NETWORK_CHAT_COMPANY :[Företaget] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Företaget] Till {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[Privat] :
+STR_NETWORK_CHAT_CLIENT :[Privat] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[Privat] Till {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[Alla] :
+STR_NETWORK_CHAT_ALL :[Alla] {STRING}: {GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :har ändrat sitt namn till
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE} Servern avslutade sessionen
+STR_NETWORK_SERVER_REBOOT :{WHITE} Servern startar om...{}Var vänlig vänta...
+
+STR_NETWORK_SERVER :Server
+STR_NETWORK_CLIENT :Klient
+STR_NETWORK_SPECTATORS :Åskådare
+
+STR_NETWORK_CLIENTLIST_NONE :(ingen)
+STR_NETWORK_CLIENTLIST_KICK :Kasta ut
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Ge pengar
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Prata med alla
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Prata med alla i företaget
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Privat meddelande
+
+
+STR_NETWORK_SEND :{BLACK}Skicka
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}X-storleken på kartan: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Y-storleken på kartan: {ORANGE}{STRING}
+
+
+##### PNG-MAP-Loader
+
+STR_PNGMAP_ERROR :{WHITE}Kan inte ladda landskap från PNG...
+STR_PNGMAP_ERR_FILE_NOT_FOUND :{WHITE}...hittar inte filen.
+STR_PNGMAP_ERR_IMAGE_TYPE :{WHITE}...kunde inte konvertera bildtyp. 8 eller 24-bitars PNG-bild krävs.
+STR_PNGMAP_ERR_MISC :{WHITE}...nånting gick fel. Ursäkta. (förmodligen korumperad fil)
+
+STR_BMPMAP_ERROR :{WHITE}Kan inte ladda landskap ifrån BMP...
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}...kunde inte konvertera bildformat.
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Kostnad: {CURRENCY}
+STR_0801_COST :{RED}Kostnad: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Inkomst: {CURRENCY}
+STR_0803_INCOME :{GREEN}Inkomst: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Omlastning: {CURRENCY}
+STR_FEEDER :{YELLOW}Omlastning: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Uppskattad kostnad: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Uppskattad inkomst: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Kan inte höja marken här...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Kan inte sänka marken här...
+STR_080A_ROCKS :Stenar
+STR_080B_ROUGH_LAND :Ojämn mark
+STR_080C_BARE_LAND :Barmark
+STR_080D_GRASS :Gräs
+STR_080E_FIELDS :Fält
+STR_080F_SNOW_COVERED_LAND :Snötäckt land
+STR_0810_DESERT :Öken
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Marken lutar åt fel håll
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Omöjlig kombination av spår
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}Utgrävning skulle förstöra tunnel
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Redan på havsnivå
+STR_1004_TOO_HIGH :{WHITE}För hög
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Inget passande järnvägsspår
+STR_1007_ALREADY_BUILT :{WHITE}...redan byggd
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Måste ta bort järnväg först
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Bygg järnväg
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Elektrifierad järnvägskonstruktion
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Bygg monorail
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}Bygg MagLev
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Välj järnvägsbro
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Kan inte bygga depå här...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Kan inte bygga järnvägsstation här...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Kan inte bygga signaler här...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Kan inte bygga järnvägsspår här...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Kan inte ta bort järnvägspår här...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Kan inte ta bort signaler här...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Riktning för depå
+STR_1015_RAILROAD_CONSTRUCTION :Bygg järnväg
+STR_TOOLB_ELRAIL_CONSTRUCTION :Elektrifierad järnvägskonstruktion
+STR_1016_MONORAIL_CONSTRUCTION :Bygg monorail
+STR_1017_MAGLEV_CONSTRUCTION :Bygg MagLev
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Bygg järnväg
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Bygg depå (för att bygga eller reparera tåg)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Bygg järnvägsstation
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Bygg järnvägssignaler
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Bygg järnvägsbro
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Bygg järnvägstunnel
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Växla mellan att bygga/ta bort järnväg och signaler
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Välj bro - klicka på vald bro för att bygga den
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Välj riktning för depå
+STR_1021_RAILROAD_TRACK :Järnvägsspår
+STR_1023_RAILROAD_TRAIN_DEPOT :Järnvägsdepå
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...området ägs av ett annat företag
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :Järnväg med vanliga signaler
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :Järnväg med för-signaler
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :Järnväg med exit-signaler
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :Järnväg med kombinerade signaler
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Måste ta bort väg först
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Vägarbete pågår
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Bygg väg
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Välj vägbro
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Kan inte bygga väg här...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Kan inte ta bort väg här...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Riktning för bussgarage
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Kan inte bygga bussgarage här...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Kan inte bygga busshållplats...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Kan inte bygga lastbilsstation...
+STR_180A_ROAD_CONSTRUCTION :Bygg väg
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Bygg väg
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Bygg bussgarage (för att bygga eller reparera vägfordon)
+STR_180D_BUILD_BUS_STATION :{BLACK}Bygg busshållplats
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Bygg lastbilsstation
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Bygg vägbro
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Bygg vägtunnel
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Växla mellan att bygga/ta bort väg
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Välj riktning för bussgarage
+STR_1814_ROAD :Väg
+STR_1815_ROAD_WITH_STREETLIGHTS :Väg med gatubelysning
+STR_1816_TREE_LINED_ROAD :Väg med träd
+STR_1817_ROAD_VEHICLE_DEPOT :Bussgarage
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :Väg-/Järnvägskorsning
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Städer
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Byggnad måste rivas först
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}Invånare: {ORANGE}{COMMA}{BLACK} Hus: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Byt namn på stad
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Kan inte byta namn på stad...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} de lokala myndigheterna tillåter inte detta
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Stadsnamn - klicka på ett namn för att centrera vyn på staden
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centrera vyn på staden
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Byt namn på staden
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passagerare förra månaden: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Post förra månaden: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Högt kontor
+STR_2010_OFFICE_BLOCK :Kontor
+STR_2011_SMALL_BLOCK_OF_FLATS :Små lägenheter
+STR_2012_CHURCH :Kyrka
+STR_2013_LARGE_OFFICE_BLOCK :Stora kontor
+STR_2014_TOWN_HOUSES :Småhus
+STR_2015_HOTEL :Hotell
+STR_2016_STATUE :Staty
+STR_2017_FOUNTAIN :Fontän
+STR_2018_PARK :Park
+STR_2019_OFFICE_BLOCK :Kontorslokaler
+STR_201A_SHOPS_AND_OFFICES :Affärer och kontor
+STR_201B_MODERN_OFFICE_BUILDING :Modern kontorsbyggnad
+STR_201C_WAREHOUSE :Varuhus
+STR_201D_OFFICE_BLOCK :Kontorsbyggnad
+STR_201E_STADIUM :Arena
+STR_201F_OLD_HOUSES :Gamla hus
+STR_2020_LOCAL_AUTHORITY :{BLACK}Lokala myndigheter
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Visa information om de lokala myndigheterna
+STR_2022_LOCAL_AUTHORITY :{WHITE}{TOWN} lokala myndigheter
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Transportföretags värderingar:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Subventioner
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Aktuella subventioner:
+STR_2027_FROM_TO :{ORANGE}{STRING} från {STRING} till {STRING}
+STR_2028_BY :{YELLOW} (tills {DATE_SHORT})
+STR_202A_NONE :{ORANGE}Inga
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Redan subventionerade rutter:
+STR_202C_FROM_TO :{ORANGE}{STRING} från {STATION} till {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, tills {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}Subventionen har gått ut:{}{}{STRING} från {STRING} till {STRING} är inte längre subventionerad
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Subventionen gäller inte mer:{}{}{STRING} från {STATION} till {STATION} är inte längre subventionerad
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Ny subvention:{}{}Första transporten av {STRING} från {STRING} till {STRING} får ett års subvention från kommunen!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subvention tilldelad {COMPANY}!{}{}{STRING} från {STATION} till {STATION} ger 50% extra nästa år!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subvention tilldelad {COMPANY}!{}{}{STRING} från {STATION} till {STATION} ger dubbelt så mycket nästa år!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subvention tilldelad {COMPANY}!{}{}{STRING} från {STATION} till {STATION} ger tre gånger så mycket nästa år!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subvention tilldelad {COMPANY}!{}{}{STRING} från {STATION} till {STATION} ger fyra gånger så mycket nästa år!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} de lokala myndigheterna tillåter inte att en ny flygplats byggs i staden
+STR_2036_COTTAGES :Stuga
+STR_2037_HOUSES :Hus
+STR_2038_FLATS :Lägenheter
+STR_2039_TALL_OFFICE_BLOCK :Hög kontorsbyggnad
+STR_203A_SHOPS_AND_OFFICES :Affärer och kontor
+STR_203B_SHOPS_AND_OFFICES :Affärer och kontor
+STR_203C_THEATER :Biograf
+STR_203D_STADIUM :Arena
+STR_203E_OFFICES :Kontor
+STR_203F_HOUSES :Hus
+STR_2040_CINEMA :Biograf
+STR_2041_SHOPPING_MALL :Shoppingcentra
+STR_2042_DO_IT :{BLACK}Utför
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}Lista av åtgärder att utföra i staden - klicka på en rad för ytterligare detaljer
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Utför markerad åtgärd i ovanstående lista
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Tillgängliga åtgärder:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Liten reklamkampanj
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Mellanstor reklamkampanj
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Stor reklamkampanj
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Bekosta ombyggnation av vägar
+STR_204A_BUILD_STATUE_OF_COMPANY :Bygg staty över företagets ägare
+STR_204B_FUND_NEW_BUILDINGS :Bekosta nya byggnader
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Köp exklusiva transporträttigheter
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Muta de lokala myndigheterna
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Starta en liten lokal reklamkampanj, för att attrahera fler passagerare och gods till dina tranporttjänster.{} Kostnad: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Starta en mellanstor lokal reklamkampanj, för att attrahera fler passagerare och gods till dina tranporttjänster.{} Kostnad: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Starta en stor lokal reklamkampanj, för att attrahera fler passagerare och gods till dina tranporttjänster.{} Kostnad: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} Bekosta ombyggnad av stadens vägnätverk. Orsakar ansenlig splittring för vägtrafik upp till 6 månader.{} Kostnad: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Bygg en staty i ditt företags ära.{} Kostnad: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Bekosta uppbyggnad av nya kommersiella byggnader i staden.{} Kostnad: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Köp 1 års exklusiv transporträttighet i staden. Stadens myndigheter kommer bara tillåta passagerare och gods till användning för ditt företags stationer.{} Kostnad: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Muta de lokala myndigheterna för att öka din värdering, på risken av att få höga böter om du blir upptäckt.{} Kostnad: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}Trafikkaos i {TOWN}!{}{}Vägombyggnadsprogram bekostat av {COMPANY} medför 6 månader av elände för bilister!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (under byggnation)
+STR_2059_IGLOO :Igloo
+STR_205A_TEPEES :KÃ¥tor
+STR_205B_TEAPOT_HOUSE :Tekanne-Hus
+STR_205C_PIGGY_BANK :Spargris
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN} {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Landskapsarkitektur
+STR_2800_PLANT_TREES :Plantera träd
+STR_2801_PLACE_SIGN :Placera skylt
+STR_2802_TREES :{WHITE}Träd
+STR_2803_TREE_ALREADY_HERE :{WHITE}...träd redan här
+STR_2804_SITE_UNSUITABLE :{WHITE}...plats olämplig
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Kan inte plantera träd här...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...för många skyltar
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Kan inte placera skylt här...
+STR_280A_SIGN :Skylt
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Ändra skylttext
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Kan inte ändra skyltnamn...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Välj trädtyp att plantera
+STR_280E_TREES :Träd
+STR_280F_RAINFOREST :Regnskog
+STR_2810_CACTUS_PLANTS :Kaktusplantor
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Val av tågstation
+STR_3001_AIRPORT_SELECTION :{WHITE}Val av flygplats
+STR_3002_ORIENTATION :{BLACK}Riktning
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Antal spår
+STR_3004_PLATFORM_LENGTH :{BLACK}Längd på plattform
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}För nära en annan järnvägsstation
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Angränsar till mer än en station/hållplats
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}För många stationer/hållplatser i staden
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}För många stationer/hållplatser
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}För många busshållplatser
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}För många lastbilsstationer
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}För nära en annan stationer/hållplatser
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Måste riva järnvägsstation först
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}För nära en annan flygplats
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Måste riva flygplats först
+
+STR_3030_RENAME_STATION_LOADING :Byt namn på station
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Kan inte byta namn på station...
+STR_3032_RATINGS :{BLACK}Värderingar
+STR_3033_ACCEPTS :{BLACK}Accepterar
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}Lokal värdering av transporttjänster:
+
+############ range for rating starts
+STR_3035_APPALLING :Hemskt DÃ¥lig
+STR_3036_VERY_POOR :Väldigt dålig
+STR_3037_POOR :DÃ¥lig
+STR_3038_MEDIOCRE :Medelmåttig
+STR_3039_GOOD :Bra
+STR_303A_VERY_GOOD :Väldigt bra
+STR_303B_EXCELLENT :Utmärkt
+STR_303C_OUTSTANDING :Enastående
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} tar inte längre emot {STRING}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} tar inte längre emot {STRING} och {STRING}
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} tar nu emot {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} tar nu emot {STRING} och {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Busshållplatsriktning
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Lastbilsbryggsriktning
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Måste riva busshållplats först
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Måste riva lastbilsbrygga först
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Station{P "" er}
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Inga -
+STR_304B_SITE_UNSUITABLE :{WHITE}...plats olämplig
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}För nära en annan hamn
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Måste riva hamn först
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Välj riktning för järnvägsstation
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Välj antal plattformar för järnvägsstation
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Välj längden på järnvägsstation
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Välj riktning för busshållplats
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Välj riktning för lastbilsbrygga
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Centrera vyn på stationen
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Visa stationens klassificering
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Byt namn på stationen
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Visa lista av accepterat gods
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Stationsnamn - klicka på ett namn för att centrera vyn på stationen
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Välj storlek/typ av flygplats
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :Järnvägsstation
+STR_305F_AIRCRAFT_HANGAR :Flygplanshangar
+STR_3060_AIRPORT :Flygplats
+STR_3061_TRUCK_LOADING_AREA :Lastbrygga
+STR_3062_BUS_STATION :Busshållplats
+STR_3063_SHIP_DOCK :Hamn
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Markera täckande yta för stationen
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Markera inte täckande yta för stationen
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Markera täckande yta
+STR_3068_DOCK :{WHITE}Hamn
+STR_3069_BUOY :Boj
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...boj i vägen
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...station för utspridd
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...ej enhetliga stationer inaktiverade
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Håll nere CTRL för att markera mer än en sak
+
+STR_UNDEFINED :(oidentifierad sträng)
+STR_STAT_CLASS_DFLT :Grundinställd station
+STR_STAT_CLASS_WAYP :Vägpunkter
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Skeppsdepå riktning
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...måste byggas på vatten
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Kan inte bygga skeppsdepå här...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Välj skeppsdepåns riktning
+STR_3804_WATER :Vatten
+STR_3805_COAST_OR_RIVERBANK :Kust eller flodbank
+STR_3806_SHIP_DEPOT :Skeppsdepå
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...Kan inte bygga på vatten
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Spara spel
+STR_4001_LOAD_GAME :{WHITE}Ladda spel
+STR_4002_SAVE :{BLACK}Spara
+STR_4003_DELETE :{BLACK}Ta bort
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} megabyte{P "" s} ledigt
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Kan inte läsa från disk
+STR_4007_GAME_SAVE_FAILED :{WHITE}Sparandet av spelet misslyckades
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Kan inte ta bort filen
+STR_4009_GAME_LOAD_FAILED :{WHITE}Läsningen av spelet misslyckades
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}Listar enheter, kataloger och sparade spel
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Valt namn för spelet
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Ta bort markerat sparat spel
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Spara spelet med valt namn
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Välj typ av nytt spel
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Välj scenario (grön), förbestämt spel (blå), eller slumpmässigt nytt spel
+STR_4010_GENERATE_RANDOM_NEW_GAME :Skapa slumpmässigt nytt spel
+STR_4011_LOAD_HEIGHTMAP :{WHITE}Läs höjdkarta
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} i vägen
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :Kolgruva
+STR_4803_POWER_STATION :Kraftstation
+STR_4804_SAWMILL :SÃ¥gverk
+STR_4805_FOREST :Skog
+STR_4806_OIL_REFINERY :Oljeraffinaderi
+STR_4807_OIL_RIG :Oljerigg
+STR_4808_FACTORY :Fabrik
+STR_4809_PRINTING_WORKS :Tryckeri
+STR_480A_STEEL_MILL :Stålverk
+STR_480B_FARM :Bondgård
+STR_480C_COPPER_ORE_MINE :Koppargruva
+STR_480D_OIL_WELLS :Oljekälla
+STR_480E_BANK :Bank
+STR_480F_FOOD_PROCESSING_PLANT :Livsmedelsfabrik
+STR_4810_PAPER_MILL :Pappersbruk
+STR_4811_GOLD_MINE :Guldgruva
+STR_4812_BANK :Bank
+STR_4813_DIAMOND_MINE :Diamantgruva
+STR_4814_IRON_ORE_MINE :Järnmalmsgruva
+STR_4815_FRUIT_PLANTATION :Fruktplantage
+STR_4816_RUBBER_PLANTATION :Gummiplantage
+STR_4817_WATER_SUPPLY :Vattentillgång
+STR_4818_WATER_TOWER :Vattentorn
+STR_4819_FACTORY :Fabrik
+STR_481A_FARM :Bondgård
+STR_481B_LUMBER_MILL :SÃ¥gverk
+STR_481C_COTTON_CANDY_FOREST :Sockervaddskog
+STR_481D_CANDY_FACTORY :Godisfabrik
+STR_481E_BATTERY_FARM :Batteribondgård
+STR_481F_COLA_WELLS :Kolakälla
+STR_4820_TOY_SHOP :Leksaksaffär
+STR_4821_TOY_FACTORY :Leksaksfabrik
+STR_4822_PLASTIC_FOUNTAINS :Plastfontäner
+STR_4823_FIZZY_DRINK_FACTORY :Läskfabrik
+STR_4824_BUBBLE_GENERATOR :Bubbelgenerator
+STR_4825_TOFFEE_QUARRY :Knäckbrott
+STR_4826_SUGAR_MINE :Sockergruva
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Kräver: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Kräver: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Kräver: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Produktion förra månaden:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% transporterat)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centrera vyn ovanför industrin
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Ny {STRING} under byggnation nära {TOWN}!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Ny {STRING} planteras nära {TOWN}!
+STR_482F_COST :{BLACK}Kostnad: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Kan inte bygga denna typ av industri här...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...skog kan bara planteras ovanför snölinjen
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} meddelar att de stänger ner snarast!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}Leveransproblem får {INDUSTRY} att meddela att de stänger ner snarast!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}Avsaknad av träd får {INDUSTRY} att meddela att de stänger ner snarast!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} ökar produktionen!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}Nytt lager av kol funnet vid {INDUSTRY}!{}Produktionen fördubblas!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}Nya oljereserver funna vid {INDUSTRY}!{}Produktionen fördubblas!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}Nya jordbruksmetoder vid {INDUSTRY} ger fördubblad produktion!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}Produktionen vid {INDUSTRY} går ned med 50%
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}Problem med insekter orsakar kris vid {INDUSTRY}!{}Produktionen ned med 50%
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...kan bara placeras nära kartans kant
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}Produktionen av {STRING} vid {INDUSTRY} upp med {COMMA}%!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}Produktionen av {STRING} vid {INDUSTRY} ned med {COMMA}%!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}TÃ¥g i tunnel
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Vägfordon i tunnel
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}En annan tunnel i vägen
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Kan inte gräva till marken på andra sidan av tunneln
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Måste riva tunnel först
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Måste riva bro först
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Kan inte börja och sluta på samma plats
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Platt land eller vatten krävs under bro
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}Start- och slutpunkt måste ligga i linje
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Platsen passar inte för tunnelentré
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Upphängd, Stål
+STR_500F_GIRDER_STEEL :Balkbro, Stål
+STR_5010_CANTILEVER_STEEL :Cantilever, Stål
+STR_5011_SUSPENSION_CONCRETE :Upphängd, Betong
+STR_5012_WOODEN :Trä
+STR_5013_CONCRETE :Betong
+STR_5014_TUBULAR_STEEL :Rör, Stål
+STR_BRIDGE_TUBULAR_SILICON :Rör, Silikon
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Kan inte bygga bro här...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Kan inte bygga tunnel här...
+STR_5017_RAILROAD_TUNNEL :Järnvägstunnel
+STR_5018_ROAD_TUNNEL :Vägtunnel
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Upphängd järnvägsbro av stål
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Järnvägsbro med stålbalkar
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Järnvägsbro med utskjutande stålstöd
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Järnvägsbro med förstärkt betongupphängning
+STR_501F_WOODEN_RAIL_BRIDGE :Järnvägsbro av trä
+STR_5020_CONCRETE_RAIL_BRIDGE :Järnvägsbro av betong
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Vägbro med stålupphängning
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Vägbro med stålbalkar
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Vägbro med utskjutande stålstöd
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Vägbro med förstärkt betongupphängning
+STR_5025_WOODEN_ROAD_BRIDGE :Vägbro av trä
+STR_5026_CONCRETE_ROAD_BRIDGE :Vägbro av betong
+STR_5027_TUBULAR_RAIL_BRIDGE :Järnvägsrörbro
+STR_5028_TUBULAR_ROAD_BRIDGE :Rörbro
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Objekt i vägen
+STR_5801_TRANSMITTER :Radiosändare
+STR_5802_LIGHTHOUSE :Fyrtorn
+STR_5803_COMPANY_HEADQUARTERS :Företagets huvudkontor
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...företagets huvudkontor i vägen
+STR_5805_COMPANY_OWNED_LAND :Mark som ägs av företag
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Kan inte köpa denna mark...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...du äger den redan!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Inget namn
+STR_SV_TRAIN_NAME :TÃ¥g {COMMA}
+STR_SV_ROADVEH_NAME :Vägfordon {COMMA}
+STR_SV_SHIP_NAME :Skepp {COMMA}
+STR_SV_AIRCRAFT_NAME :Flygplan {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :{STRING} norr
+STR_SV_STNAME_SOUTH :{STRING} söder
+STR_SV_STNAME_EAST :{STRING} öster
+STR_SV_STNAME_WEST :{STRING} väster
+STR_SV_STNAME_CENTRAL :{STRING} central
+STR_SV_STNAME_TRANSFER :{STRING} transfer
+STR_SV_STNAME_HALT :{STRING} stopp
+STR_SV_STNAME_VALLEY :{STRING} dalgång
+STR_SV_STNAME_HEIGHTS :{STRING} höjder
+STR_SV_STNAME_WOODS :{STRING} skogar
+STR_SV_STNAME_LAKESIDE :{STRING} sjö
+STR_SV_STNAME_EXCHANGE :{STRING} växel
+STR_SV_STNAME_AIRPORT :{STRING} flygplats
+STR_SV_STNAME_OILFIELD :{STRING} oljefält
+STR_SV_STNAME_MINES :{STRING} gruva
+STR_SV_STNAME_DOCKS :{STRING} Hamnar
+STR_SV_STNAME_BUOY_1 :{STRING} boj 1
+STR_SV_STNAME_BUOY_2 :{STRING} boj 2
+STR_SV_STNAME_BUOY_3 :{STRING} boj 3
+STR_SV_STNAME_BUOY_4 :{STRING} boj 4
+STR_SV_STNAME_BUOY_5 :{STRING} boj 5
+STR_SV_STNAME_BUOY_6 :{STRING} boj 6
+STR_SV_STNAME_BUOY_7 :{STRING} boj 7
+STR_SV_STNAME_BUOY_8 :{STRING} boj 8
+STR_SV_STNAME_BUOY_9 :{STRING} boj 9
+STR_SV_STNAME_ANNEXE :{STRING} annex
+STR_SV_STNAME_SIDINGS :{STRING} sida
+STR_SV_STNAME_BRANCH :{STRING} område
+STR_SV_STNAME_UPPER :Övre {STRING}
+STR_SV_STNAME_LOWER :Nedre {STRING}
+STR_SV_STNAME_HELIPORT :{STRING} Helikopterplats
+STR_SV_STNAME_FOREST :{STRING} Skog
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Svårighetsgrad
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Spara
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Lätt
+STR_6802_MEDIUM :{BLACK}Mellan
+STR_6803_HARD :{BLACK}Svår
+STR_6804_CUSTOM :{BLACK}Valfri
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}Max antal motståndare: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Startpunkt för motståndare: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}Antal städer: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}Antal industrier: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Maxstorlek på lån: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Initial ränta: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Löpande kostnader för fordon: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Bygghastighet för motståndare: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Intelligens hos motståndare: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Motorstopp för fordon: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Subventionsmultiplikator: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Kostnad för byggnation: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Typ av terräng: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Mängd sjöar/hav: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Ekonomi: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Tåg kan vända: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Katastrofer: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Stadens attityd mot områdesombyggnad: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :Ingen
+STR_6816_LOW :LÃ¥g
+STR_6817_NORMAL :Normal
+STR_6818_HIGH :Hög
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Väldigt långsam
+STR_681C_SLOW :LÃ¥ngsam
+STR_681D_MEDIUM :Mellan
+STR_681E_FAST :Snabb
+STR_681F_VERY_FAST :Väldigt snabb
+STR_VERY_LOW :Väldigt låg
+STR_6820_LOW :LÃ¥g
+STR_6821_MEDIUM :Mellan
+STR_6822_HIGH :Hög
+STR_6823_NONE :Ingen
+STR_6824_REDUCED :Reducerad
+STR_6825_NORMAL :Normal
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Väldigt platt
+STR_682B_FLAT :Platt
+STR_682C_HILLY :Kullig
+STR_682D_MOUNTAINOUS :Bergig
+STR_682E_STEADY :Stabil
+STR_682F_FLUCTUATING :Fluktuerande
+STR_6830_IMMEDIATE :Omedelbart
+STR_6831_3_MONTHS_AFTER_PLAYER :3 månader efter spelaren
+STR_6832_6_MONTHS_AFTER_PLAYER :6 månader efter spelaren
+STR_6833_9_MONTHS_AFTER_PLAYER :9 månader efter spelaren
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :Vid slut på linjen och vid stationer
+STR_6835_AT_END_OF_LINE_ONLY :Enbart vid slut på linjen
+STR_6836_OFF :Av
+STR_6837_ON :PÃ¥
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Visa highscore-lista
+STR_6839_PERMISSIVE :Eftergiven
+STR_683A_TOLERANT :Tolerant
+STR_683B_HOSTILE :Fientlig
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Spelare {COMMA})
+STR_7004_NEW_FACE :{BLACK}Nytt ansikte
+STR_7005_COLOR_SCHEME :{BLACK}Färgval
+STR_7006_COLOR_SCHEME :{GOLD}Färgval:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Nytt färgval
+STR_7008_COMPANY_NAME :{BLACK}Företagsnamn
+STR_7009_PRESIDENT_NAME :{BLACK}Namn på VD
+STR_700A_COMPANY_NAME :Företagsnamn
+STR_700B_PRESIDENT_S_NAME :Namn på VD
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Kan inte ändra företagsnamn...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Kan inte ändra namnet på VD:n...
+STR_700E_FINANCES :{WHITE}{COMPANY} Budget {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Utgifter/inkomster
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Konstruktioner
+STR_7012_NEW_VEHICLES :{GOLD}Nya fordon
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Kostnad för tåg
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Kostnad för vägfordon
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Kostnad för flygplan
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Kostnad för skepp
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Underhåll av egendomar
+STR_7018_TRAIN_INCOME :{GOLD}Inkomst från tåg
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Inkomst från vägfordon
+STR_701A_AIRCRAFT_INCOME :{GOLD}Inkomst från flygplan
+STR_701B_SHIP_INCOME :{GOLD}Inkomst från skepp
+STR_701C_LOAN_INTEREST :{GOLD}Ränta på lån
+STR_701D_OTHER :{GOLD}Övrigt
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Totalt:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Graf över inkomster
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Graf över vinst
+STR_7026_BANK_BALANCE :{WHITE}Banksaldo
+STR_7027_LOAN :{WHITE}LÃ¥n
+STR_MAX_LOAN :{WHITE}Maxlån: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}LÃ¥na {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Ã…terbetala {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...maximal storlek på lånet är {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Kan inte låna mer pengar...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...lånet redan återbetalt
+STR_702E_REQUIRED :{WHITE}...{CURRENCY} krävs
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Kan inte återbetala lånet...
+STR_INSUFFICIENT_FUNDS :{WHITE}Kan inte ge bort pengar som är lånade från banken...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Välj nytt ansikte på VD:n
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Byt färg på företaget
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Byt VD:ns namn
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Byt företagets namn
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Fälj ny färg
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Öka lånets storlek
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Återbetala en del av lånet
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(VD)
+STR_7038_INAUGURATED :{GOLD}Etablerades: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Fordon:
+STR_TRAINS :{WHITE}{COMMA} tåg
+STR_ROAD_VEHICLES :{WHITE}{COMMA} vägfordon
+STR_AIRCRAFT :{WHITE}{COMMA} flygplan
+STR_SHIPS :{WHITE}{COMMA} skepp
+STR_7042_NONE :{WHITE}Inga
+STR_7043_FACE_SELECTION :{WHITE}Välj ansikte
+STR_7044_MALE :{BLACK}Man
+STR_7045_FEMALE :{BLACK}Kvinna
+STR_7046_NEW_FACE :{BLACK}Nytt ansikte
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Avbryt val av ansikte
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Acceptera nytt ansikte
+STR_7049_SELECT_MALE_FACES :{BLACK}Välj manliga ansikten
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Välj kvinnliga ansikten
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Slumpa fram nytt ansikte
+STR_704C_KEY :{BLACK}Nyckel
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Visa nyckel till grafer
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Nyckel till företagsgrafer
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Klicka här för att visa/dölja företaget i grafen
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Enheter levererat gods
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Företagets prestationsvärderingar (maxvärdering=1000)
+STR_7052_COMPANY_VALUES :{WHITE}Företagsvärde
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Företagstabell
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}Transportföretag har problem!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} kommer att säljas eller gå bankrutt om det inte går bättre snart!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(VD)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Transportföretag slås ihop!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} har sålts till {COMPANY} för {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Vi letar efter någon som vill köpa och ta över vårt företag{}{}Vill du köpa {COMPANY} för {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Bankrutt!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} har avvecklats av investerarna och tillgångarna har sålts ut!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}Nytt transportföretag startat!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} börjar bygga nära {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Kan inte köpa företag...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Fraktförtjänster
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Dagar i transit
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Betalning för leverans 10 enheter (eller 10,000 liter) gods ett avstånd på 20 rutor
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Växla graf för godstyp av/på
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Ingenjör
+STR_7067_TRAFFIC_MANAGER :Trafikledare
+STR_7068_TRANSPORT_COORDINATOR :Transportkoordinator
+STR_7069_ROUTE_SUPERVISOR :Ruttkontrollant
+STR_706A_DIRECTOR :Direktör
+STR_706B_CHIEF_EXECUTIVE :Versktällande chef
+STR_706C_CHAIRMAN :Ordförande
+STR_706D_PRESIDENT :Verkställande direktör
+STR_706E_TYCOON :Tycoon
+STR_706F_BUILD_HQ :{BLACK}Bygg Högkvarter
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Bygg huvudkontor / visa företagets huvudkontor
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Bygg om huvudkontor på annan plats (kostar 1% av företagets värde)
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Kan inte bygga huvudkontor här...
+STR_7072_VIEW_HQ :{BLACK}Visa högkvarter
+STR_RELOCATE_HQ :{BLACK}Flytta huvudkontoret
+STR_COMPANY_PASSWORD :{BLACK}Lösenord
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Lösenordsskydda ditt företag för att förhindra att obehöriga spelare ansluter.
+STR_SET_COMPANY_PASSWORD :Ange företagets lösenord
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}Lågkonjuktur!{}{}Finansexperter befarar det värsta när ekonomin sjunker!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Lågkonjuktur Över!{}{}Uppsving i byteshandeln ger tillförsikt till industrier när ekonomin stärks!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Växla stor/liten fönsterstorlek
+STR_7076_COMPANY_VALUE :{GOLD}Företagets värde: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Köp 25% andelar i företaget
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Sälj 25% andelar i företaget
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Köp 25% andelar i detta företag
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Sälj 25% andelar i detta företag
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Kan inte köpa 25% andelar i detta företag...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}Kan inte sälja 25% andelar i detta företag...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% ägs av {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% ägs av {COMPANY}{} {COMMA}% ägs av {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} har tagits över av {COMPANY}!
+STR_7080_PROTECTED :{WHITE}Det här företaget bedriver inte aktiehandel ännu....
+
+STR_LIVERY_DEFAULT :Normalt Färgschema
+STR_LIVERY_STEAM :Ã…nglok
+STR_LIVERY_DIESEL :Dieseltåg
+STR_LIVERY_ELECTRIC :Elektriskt tåg
+STR_LIVERY_MONORAIL :Monorail-TÃ¥g
+STR_LIVERY_MAGLEV :Maglev-TÃ¥g
+STR_LIVERY_DMU :DMU
+STR_LIVERY_EMU :EMU
+STR_LIVERY_PASSENGER_WAGON_STEAM :Passagerarvagn (Ã…nga)
+STR_LIVERY_PASSENGER_WAGON_DIESEL :Passagervagn (Diesel)
+STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Passagerarvagn (Elektricitet)
+STR_LIVERY_FREIGHT_WAGON :Fraktvagn
+STR_LIVERY_BUS :Buss
+STR_LIVERY_TRUCK :Lastbil
+STR_LIVERY_PASSENGER_SHIP :Passagerarfärja
+STR_LIVERY_FREIGHT_SHIP :Fraktskepp
+STR_LIVERY_HELICOPTER :Helikopter
+STR_LIVERY_SMALL_PLANE :Litet flygplan
+STR_LIVERY_LARGE_PLANE :Stort Flygplan
+
+STR_LIVERY_GENERAL_TIP :{BLACK}Visa generellt färgschema
+STR_LIVERY_TRAIN_TIP :{BLACK}Visa färgscheman för tåg
+STR_LIVERY_ROADVEH_TIP :{BLACK}Visa färgscheman för vägfordon
+STR_LIVERY_SHIP_TIP :{BLACK}Visa färgscheman för skepp
+STR_LIVERY_AIRCRAFT_TIP :{BLACK}Visa färgschema för flygplan
+STR_LIVERY_PRIMARY_TIP :{BLACK}Välj huvudfärg för det aktuella schemat
+STR_LIVERY_SECONDARY_TIP :{BLACK}Välj andravalsfärgen för det aktuella schemat
+STR_LIVERY_PANEL_TIP :{BLACK}Välj en färg att ändra eller välj flera genom CTRL+klick. Bocka för rutan för att använda scheman
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (Ã…nga)
+STR_8001_MJS_250_DIESEL :MJS 250 (Diesel)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut Diesel
+STR_8006_POWERNAUT_DIESEL :Powernaut Diesel
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (Ã…nga)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (Ã…nga)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (Ã…nga)
+STR_800A_SH_8P_STEAM :SH '8P' (Ã…nga)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (Diesel)
+STR_800C_DASH_DIESEL :'Dash' (Diesel)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (Diesel)
+STR_800E_UU_37_DIESEL :UU '37' (Diesel)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (Diesel)
+STR_8010_CS_4000_DIESEL :CS 4000 (Diesel)
+STR_8011_CS_2400_DIESEL :CS 2400 (Diesel)
+STR_8012_CENTENNIAL_DIESEL :Centennial (Diesel)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (Diesel)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (Diesel)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (Diesel)
+STR_8016_SH_125_DIESEL :SH '125' (Diesel)
+STR_8017_SH_30_ELECTRIC :SH '30' (Elektricitet)
+STR_8018_SH_40_ELECTRIC :SH '40' (Elektricitet)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (Elektricitet)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (Elektricitet)
+STR_801B_PASSENGER_CAR :Passagerarvagn
+STR_801C_MAIL_VAN :Postvagn
+STR_801D_COAL_CAR :Kolvagn
+STR_801E_OIL_TANKER :Oljetank
+STR_801F_LIVESTOCK_VAN :Boskapsvagn
+STR_8020_GOODS_VAN :Godsvagn
+STR_8021_GRAIN_HOPPER :Spannmålsvagn
+STR_8022_WOOD_TRUCK :Timmervagn
+STR_8023_IRON_ORE_HOPPER :Järnmalmsvagn
+STR_8024_STEEL_TRUCK :Stålvagn
+STR_8025_ARMORED_VAN :Bepansrad vagn
+STR_8026_FOOD_VAN :Matvagn
+STR_8027_PAPER_TRUCK :Pappersvagn
+STR_8028_COPPER_ORE_HOPPER :Kopparmalmsvagn
+STR_8029_WATER_TANKER :Vattentank
+STR_802A_FRUIT_TRUCK :Fruktvagn
+STR_802B_RUBBER_TRUCK :Gummivagn
+STR_802C_SUGAR_TRUCK :Sockervagn
+STR_802D_COTTON_CANDY_HOPPER :Sockervaddsvagn
+STR_802E_TOFFEE_HOPPER :Knäckvagn
+STR_802F_BUBBLE_VAN :Bubbelvagn
+STR_8030_COLA_TANKER :Kolatank
+STR_8031_CANDY_VAN :Godisvagn
+STR_8032_TOY_VAN :Leksaksvagn
+STR_8033_BATTERY_TRUCK :Batterivagn
+STR_8034_FIZZY_DRINK_TRUCK :Läskvagn
+STR_8035_PLASTIC_TRUCK :Plastvagn
+STR_8036_X2001_ELECTRIC :'X2001' (Elektricitet)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Elektricitet)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :Passagerarvagn
+STR_803A_MAIL_VAN :Postvagn
+STR_803B_COAL_CAR :Kolvagn
+STR_803C_OIL_TANKER :Oljetank
+STR_803D_LIVESTOCK_VAN :Boskapsvagn
+STR_803E_GOODS_VAN :Godsvagn
+STR_803F_GRAIN_HOPPER :Spannmålsvagn
+STR_8040_WOOD_TRUCK :Timmervagn
+STR_8041_IRON_ORE_HOPPER :Järnmalmsvagn
+STR_8042_STEEL_TRUCK :Stålvagn
+STR_8043_ARMORED_VAN :Bepansrad vagn
+STR_8044_FOOD_VAN :Matvagn
+STR_8045_PAPER_TRUCK :Pappersvagn
+STR_8046_COPPER_ORE_HOPPER :Kopparmalmsvagn
+STR_8047_WATER_TANKER :Vattentank
+STR_8048_FRUIT_TRUCK :Frukvagn
+STR_8049_RUBBER_TRUCK :Gummivagn
+STR_804A_SUGAR_TRUCK :Sockervagn
+STR_804B_COTTON_CANDY_HOPPER :Sockervaddsvagn
+STR_804C_TOFFEE_HOPPER :Knäckvagn
+STR_804D_BUBBLE_VAN :Bubblevagn
+STR_804E_COLA_TANKER :Kolatank
+STR_804F_CANDY_VAN :Godisvagn
+STR_8050_TOY_VAN :Leksaksvagn
+STR_8051_BATTERY_TRUCK :Batterivagn
+STR_8052_FIZZY_DRINK_TRUCK :Läskvagn
+STR_8053_PLASTIC_TRUCK :Plastvagn
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (Elektricitet)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (Elektricitet)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (Elektricitet)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (Elektricitet)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :Passagerarbil
+STR_805A_MAIL_VAN :Postvagn
+STR_805B_COAL_CAR :Kolvagn
+STR_805C_OIL_TANKER :Oljetank
+STR_805D_LIVESTOCK_VAN :Boskapsvagn
+STR_805E_GOODS_VAN :Godsvagn
+STR_805F_GRAIN_HOPPER :Spannmålsvagn
+STR_8060_WOOD_TRUCK :Timmervagn
+STR_8061_IRON_ORE_HOPPER :Järnmalmsvagn
+STR_8062_STEEL_TRUCK :Stållastvagn
+STR_8063_ARMORED_VAN :Bepansrad vagn
+STR_8064_FOOD_VAN :Matvagn
+STR_8065_PAPER_TRUCK :Pappersvagn
+STR_8066_COPPER_ORE_HOPPER :Kopparmalmsvagn
+STR_8067_WATER_TANKER :Vattentank
+STR_8068_FRUIT_TRUCK :Fruktvagn
+STR_8069_RUBBER_TRUCK :Gummilastvagn
+STR_806A_SUGAR_TRUCK :Sockerlastvagn
+STR_806B_COTTON_CANDY_HOPPER :Sockervaddsvagn
+STR_806C_TOFFEE_HOPPER :Knäckvagn
+STR_806D_BUBBLE_VAN :Bubbelvagn
+STR_806E_COLA_TANKER :Kolatank
+STR_806F_CANDY_VAN :Godisvagn
+STR_8070_TOY_VAN :Leksaksvagn
+STR_8071_BATTERY_TRUCK :Batterivagn
+STR_8072_FIZZY_DRINK_TRUCK :Läskvagn
+STR_8073_PLASTIC_TRUCK :Plastvagn
+STR_8074_MPS_REGAL_BUS :MPS Regal Buss
+STR_8075_HEREFORD_LEOPARD_BUS :Hereford Leopard Buss
+STR_8076_FOSTER_BUS :Foster Buss
+STR_8077_FOSTER_MKII_SUPERBUS :Foster MkII Super Buss
+STR_8078_PLODDYPHUT_MKI_BUS :Ploddyphut MkI Buss
+STR_8079_PLODDYPHUT_MKII_BUS :Ploddyphut MkII Buss
+STR_807A_PLODDYPHUT_MKIII_BUS :Ploddyphut MkIII Buss
+STR_807B_BALOGH_COAL_TRUCK :Balogh Koldumper
+STR_807C_UHL_COAL_TRUCK :Uhl Koldumper
+STR_807D_DW_COAL_TRUCK :DW Koldumper
+STR_807E_MPS_MAIL_TRUCK :MPS Postbil
+STR_807F_REYNARD_MAIL_TRUCK :Reynard Postbil
+STR_8080_PERRY_MAIL_TRUCK :Perry Postbil
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :MightyMover Postbil
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Powernaught Postbil
+STR_8083_WIZZOWOW_MAIL_TRUCK :Wizzowow Postbil
+STR_8084_WITCOMBE_OIL_TANKER :Witcombe Oljetanker
+STR_8085_FOSTER_OIL_TANKER :Foster Oljetanker
+STR_8086_PERRY_OIL_TANKER :Perry Oljetanker
+STR_8087_TALBOTT_LIVESTOCK_VAN :Talbott Boskapsbil
+STR_8088_UHL_LIVESTOCK_VAN :Uhl Boskapsbil
+STR_8089_FOSTER_LIVESTOCK_VAN :Foster Boskapsbil
+STR_808A_BALOGH_GOODS_TRUCK :Balogh Godslastbil
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Craighead Godslastbil
+STR_808C_GOSS_GOODS_TRUCK :Goss Godslastbil
+STR_808D_HEREFORD_GRAIN_TRUCK :Hereford Spannmålslastare
+STR_808E_THOMAS_GRAIN_TRUCK :Thomas Spannmålslastare
+STR_808F_GOSS_GRAIN_TRUCK :Goss Spannmålslastare
+STR_8090_WITCOMBE_WOOD_TRUCK :Witcombe Timmerlastare
+STR_8091_FOSTER_WOOD_TRUCK :Foster Timmerlastare
+STR_8092_MORELAND_WOOD_TRUCK :Moreland Timmerlastare
+STR_8093_MPS_IRON_ORE_TRUCK :MPS Järnmalmsdumper
+STR_8094_UHL_IRON_ORE_TRUCK :Uhl Järnmalmsdumper
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Chippy Järnmalmsdumper
+STR_8096_BALOGH_STEEL_TRUCK :Balogh Ståldumper
+STR_8097_UHL_STEEL_TRUCK :Uhl Ståldumper
+STR_8098_KELLING_STEEL_TRUCK :Kelling Ståldumper
+STR_8099_BALOGH_ARMORED_TRUCK :Balogh Bepansrad lastbil
+STR_809A_UHL_ARMORED_TRUCK :Uhl Bepansrad lastbil
+STR_809B_FOSTER_ARMORED_TRUCK :Foster Bepansrad lastbil
+STR_809C_FOSTER_FOOD_VAN :Foster Matbil
+STR_809D_PERRY_FOOD_VAN :Perry Matbil
+STR_809E_CHIPPY_FOOD_VAN :Chippy Matbil
+STR_809F_UHL_PAPER_TRUCK :Uhl Papperlastare
+STR_80A0_BALOGH_PAPER_TRUCK :Balogh Papperslastare
+STR_80A1_MPS_PAPER_TRUCK :MPS Papperslastare
+STR_80A2_MPS_COPPER_ORE_TRUCK :MPS Kopparmalmsdumper
+STR_80A3_UHL_COPPER_ORE_TRUCK :Uhl Kopparmalmsdumper
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Goss Kopparmalmsdumper
+STR_80A5_UHL_WATER_TANKER :Uhl Vattentanker
+STR_80A6_BALOGH_WATER_TANKER :Balogh Vattentanker
+STR_80A7_MPS_WATER_TANKER :MPS Vattentanker
+STR_80A8_BALOGH_FRUIT_TRUCK :Balogh Fruktlastare
+STR_80A9_UHL_FRUIT_TRUCK :Uhl Fruktlastare
+STR_80AA_KELLING_FRUIT_TRUCK :Kelling Fruktlastare
+STR_80AB_BALOGH_RUBBER_TRUCK :Balogh Gummidumper
+STR_80AC_UHL_RUBBER_TRUCK :Uhl Gummidumper
+STR_80AD_RMT_RUBBER_TRUCK :RMT Gummidumper
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :MightyMover Sockerlastare
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Powernaught Sockerlastare
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Wizzowow Sockerlastare
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :MightyMover Kolalastare
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Powernaught Kolalastare
+STR_80B3_WIZZOWOW_COLA_TRUCK :Wizzowow Kolalastare
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :MightyMover Sockervaddslastare
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Powernaught Sockervaddslastare
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Wizzowow Sockervaddslastare
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :MightyMover Knäcklastare
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Powernaught Knäcklastare
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Wizzowow Knäcklastare
+STR_80BA_MIGHTYMOVER_TOY_VAN :MightyMover Leksaksbil
+STR_80BB_POWERNAUGHT_TOY_VAN :Powernaught Leksaksbil
+STR_80BC_WIZZOWOW_TOY_VAN :Wizzowow Leksaksbil
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :MightyMover Godislastare
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Powernaught Godislastare
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Wizzowow Godislastare
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :MightyMover Batterilastare
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Powernaught Batterilastare
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Wizzowow Batterilastare
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :MightyMover Läsklastbil
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Powernaught Läsklastbil
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Wizzowow Läsklastbil
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :MightyMover Plastlastare
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Powernaught Plastlastare
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Wizzowow Plastlastbil
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :MightyMover Bubbellastbil
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Powernaught Bubbellastbil
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Wizzowow Bubbellastbil
+STR_80CC_MPS_OIL_TANKER :MPS Oljetanker
+STR_80CD_CS_INC_OIL_TANKER :CS-Inc. Oljetanker
+STR_80CE_MPS_PASSENGER_FERRY :MPS Passagerarfärja
+STR_80CF_FFP_PASSENGER_FERRY :FFP Passagerarfärja
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Bakewell 300 svävfarkost
+STR_80D1_CHUGGER_CHUG_PASSENGER :Chugger-Chug Passagerarfärja
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Shivershake Passagerarfärja
+STR_80D3_YATE_CARGO_SHIP :Yate Godsskepp
+STR_80D4_BAKEWELL_CARGO_SHIP :Bakewell Godsskepp
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Mightymover Godsskepp
+STR_80D6_POWERNAUT_CARGO_SHIP :Powernaut Godsskepp
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Tricario Helicopter
+STR_80FE_GURU_X2_HELICOPTER :Guru X2 Helikopter
+STR_80FF_POWERNAUT_HELICOPTER :Powernaut Helikopter
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Meddelande från fordonstillverkare
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}Vi har just designat ett nytt {STRING} - är du intresserad av ett års exklusiv användning av detta fordon, så vi kan se hur det fungerar innan vi släpper det på marknaden?
+STR_8102_RAILROAD_LOCOMOTIVE :järnvägslokomotiv
+STR_8103_ROAD_VEHICLE :vägfordon
+STR_8104_AIRCRAFT :flygplan
+STR_8105_SHIP :skepp
+STR_8106_MONORAIL_LOCOMOTIVE :monorail-lokomotiv
+STR_8107_MAGLEV_LOCOMOTIVE :maglev-lokomotiv
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}{TOWN} tågdepå
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Invånarna firar . . .{}Första tåget ankommer till {STATION}!
+STR_8802_DETAILS :{WHITE}{STRING} (Details)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Tåg i vägen
+STR_8804 :{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8806_GO_TO :Ã…k till {STATION}
+STR_8807_GO_TO_TRANSFER :Åk till {STATION} (Lasta om och på)
+STR_8808_GO_TO_UNLOAD :Ã…k till {STATION} (Lasta av)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Åk till {STATION} (Lasta om men inte på)
+STR_880A_GO_TO_LOAD :Åk till {STATION} (Lasta på)
+STR_880B_GO_TO_TRANSFER_LOAD :Åk till {STATION} (Lasta om och vänta på full last)
+STR_880C_GO_NON_STOP_TO :Ã…k nonstop till {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Åk nonstop till {STATION} (Lasta om och på)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Ã…k nonstop till {STATION} (Lasta av)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Åk nonstop till {STATION} (Lasta om men inte på)
+STR_8810_GO_NON_STOP_TO_LOAD :Åk nonstop till {STATION} (Lasta på)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Åk nonstop till {STATION} (Lasta om och vänta på full last)
+STR_GO_TO_TRAIN_DEPOT :Åk till {TOWN}s tågdepå
+STR_SERVICE_AT_TRAIN_DEPOT :Servning vid {TOWN} tågdepå
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Åk non-stop till {TOWN}s tågdepå
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Servning non-stop {TOWN} tågdepå
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}På väg mot {TOWN}s tågdepå
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}På väg mot {TOWN}s tågdepå, {VELOCITY}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE :{LTBLUE}Service vid {TOWN}s tågdepå
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE_VEL :{LTBLUE}Service vid {TOWN}s tågdepå, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (Ogiltig order)
+
+STR_UNKNOWN_DESTINATION :okänd destination
+STR_8812_EMPTY :{LTBLUE}Tom
+STR_8813_FROM :{LTBLUE}{CARGO} från {STATION}
+STR_FROM_MULT :{LTBLUE}{CARGO} från {STATION} (x{NUM})
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}Tåg {COMMA} väntar i depå
+STR_8815_NEW_VEHICLES :{BLACK}Nytt fordon
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Tåg för långt
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Tåg kan bara ändras när det står still inuti en depå
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} TÃ¥g
+
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Nytt tågfordon
+STR_NEW_ELRAIL_VEHICLES :{WHITE}Nya elektriska järnvägsfordon
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Nytt monorail-fordon
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Nytt maglevfordon
+STR_ALL_AVAIL_RAIL_VEHICLES :{WHITE}Rälsfordon
+
+STR_881F_BUILD_VEHICLE :{BLACK}Bygg fordon
+STR_CLONE_ROAD_VEHICLE :{BLACK}Klona fordon
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}Det här bygger en kopia av fordonet. Control-klickning gör så att de delar order
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Det här bygger en kopia av ett fordon. Tryck på den här knappen och sen på ett vägfordon inuti eller utanför depån. Control-klickning gör så att de delar order
+STR_CLONE_TRAIN :{BLACK}Klona tåg
+STR_CLONE_TRAIN_INFO :{BLACK}Det här bygger en kopia av tåget inklusive alla vagnar. Control-klickning gör så att de delar order
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}Det här bygger en kopia av ett tåg inklusive alla vagnar. Tryck på den här knappen och sen på ett tåg inuti eller utanför depån. Control-klickning gör så att de delar order
+STR_8820_RENAME :{BLACK}Byt namn på
+STR_8823_SKIP :{BLACK}Skippa
+STR_8824_DELETE :{BLACK}Ta bort
+STR_8825_NON_STOP :{BLACK}Non-stop
+STR_8826_GO_TO :{BLACK}GÃ¥ Till
+STR_8827_FULL_LOAD :{BLACK}Lasta
+STR_8828_UNLOAD :{BLACK}Lasta av
+STR_REFIT :{BLACK}Anpassa
+STR_REFIT_TIP :{BLACK}Välj vilken godstyp anpassningen ska göras i denna order. CTRL+ klicka för att ta bort anpassningsordern
+STR_REFIT_ORDER :(Anpassa för {STRING})
+STR_8829_ORDERS :{WHITE}{VEHICLE} (Order)
+STR_882A_END_OF_ORDERS :{SETX 10}- - Slut på order - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}Servning
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Kan inte bygga järnvägfordon...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Byggt: {LTBLUE}{NUM}{BLACK} Värde: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Värde: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}Lastar / lastar av
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}Tåget måste stoppas inne i depån
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Kan inte skicka tåg till depå...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Ingen mer plats för order
+STR_8832_TOO_MANY_ORDERS :{WHITE}För många order
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Kan inte sätta in ny order...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Kan inte ta bort denna order...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Kan inte ändra denna order...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Kan inte flytta fordon...
+STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}Det bakre loket kommer alltid följa med det tillhörande främre loket
+STR_8838_N_A :N/A{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Kan inte sälja järnvägfordon...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Kan inte hitta vägen till närmaste depå
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Kan inte stoppa/starta tåg...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Serviceintervall: {LTBLUE}{COMMA}dagar{BLACK} Senaste service: {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Serviceintervall: {LTBLUE}{COMMA}%{BLACK} Senaste service: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Tåg - klicka på tåg för information
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Bygg nytt tåg (kräver depå)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Tåg - klicka på tåg för info, drag vagn för att lägga till/ta bort från tåg
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Bygg ny tågvagn
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Dra tågvagn hit för att sälja den
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centrera vyn på depån
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Lista av tågvagnar - klicka på tågvagn för information
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Bygg markerad tågvagn
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Byt namn på tågvagn
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Aktuell tågorder - klicka här för att stoppa/starta tåg
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Visa tågets order
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centrera vyn ovanför tåget
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Skicka tåg till depå
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Tvinga tåg att fortsätta utan att vänta på signal
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Byt tågets riktning
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Visa tågdetaljer
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Öka serviceintervall
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Minska serviceintervall
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Visa detaljer för lastat gods
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Visa detaljer för tågfordon
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Visa kapaciteter för varje fordon
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Visa tågets totala kapacitet, separera för typ av gods
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Orderlista - klicka på order för att markera det
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}Skippa nuvararande order och börja med nästa
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Ta bort markerad order
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Gör markerad order non-stop
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Infoga ny order före markerad order, eller lägg till i slutet av listan
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Gör markerad order att tvinga fordonet att vänta på full last
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Gör markerad order att tvinga fordonet att vänta på tom last
+STR_SERVICE_HINT :{BLACK}Skippa den här ordern om inte servning behövs
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}Nytt {STRING} nu tillgängligt!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Kostnad: {CURRENCY} Vikt: {WEIGHT_S}{}Hastighet: {VELOCITY} Effekt: {POWER}{}Löpande kostnad: {CURRENCY}/år{}Kapacitet: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}Motorstopp
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}Ålder: {LTBLUE}{STRING}{BLACK} Löpande kostnad: {LTBLUE}{CURRENCY}/år
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Vikt: {LTBLUE}{WEIGHT_S} {BLACK}Effekt: {LTBLUE}{POWER}{BLACK} Tophastighet: {LTBLUE}{VELOCITY}
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Vikt: {LTBLUE}{WEIGHT_S} {BLACK}Kraft: {LTBLUE}{POWER}{BLACK} Maxhastighet: {LTBLUE}{VELOCITY} {BLACK}Maximal Dragkraft: {LTBLUE}{FORCE}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Vinst detta år: {LTBLUE}{CURRENCY} (förra året: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}Tillförlitlighet: {LTBLUE}{COMMA}% {BLACK}Motorstopp sedan senaste service: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Stoppat
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Kan inte tillåta tåg att passera signal under fara...
+STR_8863_CRASHED :{RED}Kraschad!
+
+STR_8865_NAME_TRAIN :{WHITE}Byt namn på tåg
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}Kan inte byta namn på tåg...
+STR_8867_NAME_TRAIN :{BLACK}Byt namn på tåg
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}TÃ¥gkrash!{}{COMMA} dog i eldklot efter kollision
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Kan inte byta tågets riktning...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Byt namn på tågets fordonstyp
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Kan inte byta namn på tågets fordonstyp...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Gör så att den markerade ordern tvingar fordonet att lasta av
+STR_886F_TRANSFER :{BLACK}Lasta om
+
+STR_TRAIN_STOPPING :{RED}Stannar
+STR_TRAIN_STOPPING_VEL :{RED}Stannar, {VELOCITY}
+STR_INCOMPATIBLE_RAIL_TYPES :Fel järnvägstyp
+STR_TRAIN_NO_POWER :{RED}Ingen Kraft
+STR_TRAIN_START_NO_CATENARY :Loket kan inte starta för att detta spår saknar elledningar
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Vägfordon i vägen
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} Vägfordon
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}{TOWN} Vägfordon Depå
+STR_9004_NEW_VEHICLES :{BLACK}Nytt Fordon
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}Nytt Vägfordon
+STR_9007_BUILD_VEHICLE :{BLACK}Bygg Fordon
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Kan inte bygga vägfordon...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (Detaljer)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}Ålder: {LTBLUE}{STRING}{BLACK} Löpande kostnad: {LTBLUE}{CURRENCY}/år
+STR_900E_MAX_SPEED :{BLACK}Tophastighet: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Vinst detta år: {LTBLUE}{CURRENCY} (förra året: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}Tillförlitlighet: {LTBLUE}{COMMA}% {BLACK}Motorstopp sedan senaste service: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Byggt: {LTBLUE}{NUM}{BLACK} Värde: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Kapacitet: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}...måste stoppas inuti ett bussgarage
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Kan inte sälja vägfordon...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Kan inte stoppa/starta vägfordon...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}Vägfordon {COMMA} väntar i depån
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}På väg mot {TOWN}s vägdepå
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}På väg mot {TOWN}s vägdepå, {VELOCITY}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE :{LTBLUE}Service vid {TOWN}s vägdepå
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE_VEL :{LTBLUE}Service vid {TOWN}s vägdepå, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Kan inte skicka fordon till depå...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Kan inte hitta till lokal depå
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Vägfordon - klicka på fordon för information
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Bygg nytt vägfordon (kräver bussgarage)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Nuvarande fordonsaktivitet - Klicka här till stoppa/starta fordon
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Visa fordonets order
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Centrera vyn ovanför fordonet
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Skicka fordon till depå. CTRL + klick servar endast
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Tvinga fordonet att vända om
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Visa vägfordonsdetaljer
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Fordon - klicka på fordon för information
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Bygg nytt vägfordon
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Dra vägfordon hit för att sälja det
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Centrera vyn ovanför bussgaraget
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Vägfordonslista - klicka på fordon för information
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Bygg markerat vägfordon
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}Nytt vägfordon tillgängligt!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Kostnad: {CURRENCY}{}Hastighet: {VELOCITY}{}Löpande kostnad: {CURRENCY}/år{}Kapacitet: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Byt namn på vägfordon
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Kan inte byta namn på vägfordon...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Byt namn på vägfordon
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Invånarna firar . . .{}Första bussen ankommer till {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Invånarna firar . . .{}Första lastbilen ankommer till {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}Vägfordonskrash!{}förare dör i eldklot efter kollision med tåg
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}Vägfordonskrash!{}{COMMA} dör i eldklot efter kollision med tåg
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Kan inte tvinga fordonet att vända om...
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}Kan inte vända fordon bestående av flera delar
+STR_9034_RENAME :{BLACK}Byt namn på
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Byt namn på vägfordon typ
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Byt namn på vägfordon typ
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Kan inte byta namn på vägfordon typ...
+STR_9038_GO_TO_ROADVEH_DEPOT :Gå till {TOWN} vägfordonsdepå
+STR_SERVICE_AT_ROADVEH_DEPOT :Servning vid {TOWN} vägfordonsdepå Depot
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Anpassa vägfordon till att bära en annan sorts last
+STR_REFIT_ROAD_VEHICLE :{BLACK}Anpassa Vägfordon
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Anpassa vägfordon till att bära markerad last
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Kan inte anpassa vägfordon...
+STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Välj lasttyp för fordon
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Hamnbyggnation
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Hamnbyggnation
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Kan inte bygga hamn här...
+STR_9803_SHIP_DEPOT :{WHITE}{TOWN} skeppsdepå
+STR_9804_NEW_SHIPS :{BLACK}Nytt skepp
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} skepp
+STR_9808_NEW_SHIPS :{WHITE}Nytt skepp
+STR_9809_BUILD_SHIP :{BLACK}Bygg skepp
+STR_CLONE_SHIP :{BLACK}Klona skepp
+STR_CLONE_SHIP_INFO :{BLACK}Det här bygger en kopia av skeppet. Control-klickning gör så att de delar order
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}Det här bygger en kopia av ett skepp. Tryck på den här och sedan på ett skepp inuti eller utanför depån. Control-klickning gör att de delar order
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}Skepp måste vara stoppat i depå
+STR_980C_CAN_T_SELL_SHIP :{WHITE}Kan inte sälja skepp...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Kan inte bygga skepp...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Skepp i vägen
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Detaljer)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}Ålder: {LTBLUE}{STRING}{BLACK} Löpande kostnad: {LTBLUE}{CURRENCY}/år
+STR_9813_MAX_SPEED :{BLACK}Tophastighet: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Vinst detta år: {LTBLUE}{CURRENCY} (förra år: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}Tillförlitlighet: {LTBLUE}{COMMA}% {BLACK}Motorstopp sedan senaste service: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Byggt: {LTBLUE}{NUM}{BLACK} Värde: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}Kapacitet: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}Kan inte stoppa/starta skepp...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Kan inte skicka skepp till depå...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Kan inte finna en lokal depå
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}På väg mot {TOWN}s Skeppsdepå
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}På väg mot {TOWN}s Skeppsdepå, {VELOCITY}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE :{LTBLUE}Service vid {TOWN}s skeppsdepå
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE_VEL :{LTBLUE}Service vid {TOWN}s skeppsdepå, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}Skepp {COMMA} väntar i depå
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Bygg hamn
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Bygg skeppsdepå (för byggnad och lagning av skepp)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Skepp - klicka på skepp för information
+STR_9820_BUILD_NEW_SHIP :{BLACK}Bygg nytt skepp
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Dra skepp hit för att sälja det
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centrera vyn ovanför skeppets depot
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Skepp - klicka på skepp för information
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Bygg nytt skepp (kräver skeppsdepå)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}Skeppslista - klicka på skepp för information
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Bygg markerat skepp
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Nuvarande skeppsaktion - Klicka här till stoppa/starta skepp
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Visa skeppets order
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Centrera vyn ovanför skeppet
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Skicka skepp till depå. CTRL + klick servar endast
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Visa skeppdetaljer
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}Nytt skepp tillgängligt!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Kostnad: {CURRENCY} Tophastighet: {VELOCITY}{}Kapacitet: {CARGO}{}Löpande kostnad: {CURRENCY}/år
+STR_982F_NAME_SHIP :{BLACK}Byt namn på skepp
+
+STR_9831_NAME_SHIP :{WHITE}Byt namn på skepp
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Kan inte byta namn på skepp...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Invånarna firar . . .{}Första skeppet ankommer till {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Positionsboj, som kan som kan användas för ytterligare vägpunkter
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Kan inte placera boj här...
+STR_9836_RENAME :{BLACK}Byt namn på
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Byt namn på skeppstyp
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Byt namn på skeppstyp
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Kan inte byta namn på skeppstyp...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Anpassa godsskepp att frakta en annan godstyp
+STR_983B_REFIT :{WHITE}{VEHICLE} (Anpassa)
+STR_983C_REFIT_SHIP :{BLACK}Anpassa skepp
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Välj typ av gods för skepp att frakta
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Anpassa skepp att frakta markerad godstyp
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Välj godstyp att frakta:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Ny kapacitet: {GOLD}{CARGO}{}{BLACK}Anpassningens kostnad: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Kan inte anpassa skepp...
+STR_9842_REFITTABLE :(anpassningsbart)
+STR_GO_TO_SHIP_DEPOT :Åk till {TOWN}s båtdepå
+SERVICE_AT_SHIP_DEPOT :Service vid {TOWN} båtdepå
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Flygplatser
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Kan inte bygga flygplats här...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} flygplanshangar
+STR_A003_NEW_AIRCRAFT :{BLACK}Nytt flygplan
+STR_CLONE_AIRCRAFT :{BLACK}Klona flygplan
+STR_CLONE_AIRCRAFT_INFO :{BLACK}Det här bygger en kopia av flygplanet. Control-klickning gör så de delar order
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Det här bygger en kopia av ett flygplan. Tryck på den här knappen och sedan på ett flygplan inuti eller utanför hangaren. Control-klickning gör så de delar order
+STR_A005_NEW_AIRCRAFT :{WHITE}Nytt flygplan
+STR_A006_BUILD_AIRCRAFT :{BLACK}Bygg flygplan
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Kan inte bygga flygplan...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} flygplan
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (Order)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (Detaljer)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Ålder: {LTBLUE}{STRING}{BLACK} Löpande kostnad: {LTBLUE}{CURRENCY}/år
+STR_A00E_MAX_SPEED :{BLACK}Tophastighet: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Vinst detta år: {LTBLUE}{CURRENCY} (förra året: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}Tillförlitlighet: {LTBLUE}{COMMA}% {BLACK}Motorstopp sedan senaste service: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Byggt: {LTBLUE}{NUM}{BLACK} Värde: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Kan inte skicka flygplan till hangar...
+STR_HEADING_FOR_HANGAR :{ORANGE}På väg mot {STATION}s hangar
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}På väg mot {STATION}s hangar, {VELOCITY}
+STR_HEADING_FOR_HANGAR_SERVICE :{LTBLUE}Service vid {STATION}s hangar
+STR_HEADING_FOR_HANGAR_SERVICE_VEL :{LTBLUE}Service vid {STATION}s hangar, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}Flygplan {COMMA} väntar i flygplanshangar
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Flygplan i vägen
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Kan inte stoppa/starta flygplan...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Flygplan är i luften
+STR_A019_CAPACITY :{BLACK}Kapacitet: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Kapacitet: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}Flygplan måste stoppas i hangar
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Kan inte sälja flygplan...
+STR_A01D_AIRPORT_CONSTRUCTION :Flygplatsbyggnation
+STR_A01E_BUILD_AIRPORT :{BLACK}Bygg flygplats
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Flygplan - Klicka på flygplan för information
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Bygg nytt flygplan (kräver flygplats med hangar)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Flygplan - Klicka på flygplan för information
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Bygg nytt flygplan
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}Dra flygplan hit för att sälja det
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Centrera vyn ovanför hangaren
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Flygplanslista - Klicka på flygplan för information
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Bygg markerat flygplan
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Nuvarande flygplansaktion - Klicka här till stoppa/starta flygplan
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Visa flygplanets order
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Centrera vyn ovanför flygplanet
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Skicka flygplan till hangar. CTRL + klick servar endast
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Visa flygplan detaljer
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}Nytt flygplan tillgängligt!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Kostnad: {CURRENCY} Tophastighet: {VELOCITY}{}Kapacitet: {COMMA} passagerare, {COMMA} postsäckar{}Löpande kostnad: {CURRENCY}/år
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Byt namn på flygplan
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Kan inte byta namn på flygplan...
+STR_A032_NAME_AIRCRAFT :{BLACK}Byt namn på flygplan
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Invånarna firar . . .{}Första flygplanet ankommer till {STATION}!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Flygplanskrasch!{}{COMMA} dör i eldklot på {STATION}
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Flygplanskrasch!{}Flygplanet fick slut på bränsle, {COMMA} dör i eldklot!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Byt namn på
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Byt namn på flygplanstyp
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Byt namn på flygplanstyp
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Kan inte byta namn på flygplanstyp...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Anpassa flygplan att frakta en annan godstyp
+STR_A03C_REFIT :{WHITE}{VEHICLE} (Anpassa)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Anpassa flygplan
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Välj godstyp för flygplan att frakta
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Anpassa flygplan att frakta markerad godstyp
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Välj godstyp att frakta:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Ny kapacitet: {GOLD}{STRING}{}{BLACK}Kostnad av anpassning: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Kan inte anpassa flygplan...
+STR_GO_TO_AIRPORT_HANGAR :GÃ¥ till {STATION}s hangar
+SERVICE_AT_AIRPORT_HANGAR :Service vid {STATION} hangar
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}Zeppelinare-katastrof på {STATION}!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Vägfordon förstört i 'UFO'-kollision!
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}Oljeraffinaderi exploderade nära {TOWN}!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}Fabrik förstörd i misstänkta omständigheter nära {TOWN}!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}'UFO' landar nära {TOWN}!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}Kolgruva sjunker - lämnar spår av katastrof nära {TOWN}!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Översvämning!{}Minst {COMMA} förmodas saknade eller döda efter dödlig översvämning!
+
+STR_BRIBE_FAILED :{WHITE}Ditt mutningsförsök har blivit
+STR_BRIBE_FAILED_2 :{WHITE}uppdagat av en regional utredare.
+STR_BUILD_DATE :{BLACK}Byggt: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Detaljerade prestandabetyg
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}Detaljer
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Vägfordon:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Stationer:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Min. vinst:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Min. inkomst:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Max. inkomst:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Levererat:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Gods:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Pengar:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}LÃ¥n:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Totalt:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Totalt antal fordon. Inkluderar vägfordon, tåg, skepp och flygplan.
+STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}Antalet stationsdelar. Varje del av en station (ex: tågstation, bushållplats, flygplats) är räknad, även om dom är ihopkopplade till en station.
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}Vinsten för det fordon med lägst inkomst (av alla fordon äldre än 2 år).
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Mängden tjänade pengar den månad med lägst vinst de senaste 12 kvartalen.
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Mängden tjänade pengar den månad med högsta vinsten de senaste 12 kvartalen.
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}Enheter av gods levererat de senaste fyra kvartalen.
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}Typer av gods levererat det senaste kvartalet.
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Mängden pengar på hand
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}Har du ett stort lån?
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Totalt antal poäng utav möjligt antal poäng
+
+STR_NEWGRF_SETTINGS_BUTTON :{BLACK}NewGRF Inställningar
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}Newgrf inställningar
+STR_NEWGRF_APPLY_CHANGES :{BLACK}Spara ändringar
+STR_NEWGRF_SET_PARAMETERS :{BLACK}Parametrar
+STR_NEWGRF_TIP :{BLACK}En lista av alla Newgrf som du har installerade. Clicka på en för att ändra inställningar.
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}Det finns för närvarande inga newgrf filer installerade! Vänligen kolla manualen hur man installerar ny grafik.
+STR_NEWGRF_FILENAME :{BLACK}Filnamn: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
+STR_NEWGRF_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING}
+STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}Du håller på att göra ändringar i ett spel som används; detta kan krascha OpenTTD.{}Är du helt säker på detta?
+
+STR_NEWGRF_ADD :{BLACK}Lägg till
+STR_NEWGRF_ADD_TIP :{BLACK}Lägg till en ny NewGRF-fil till listan
+STR_NEWGRF_REMOVE :{BLACK}Ta bort
+STR_NEWGRF_REMOVE_TIP :{BLACK}Ta bort den markerade NewGRF-filen från listan
+STR_NEWGRF_MOVEUP :{BLACK}Flytta upp
+STR_NEWGRF_MOVEUP_TIP :{BLACK}Flytta upp den markerade NewGRF-filen i listan
+STR_NEWGRF_MOVEDOWN :{BLACK}Fytta ned
+STR_NEWGRF_MOVEDOWN_TIP :{BLACK}Flytta ner den markerade NewGRF-filen i listan
+STR_NEWGRF_FILE_TIP :{BLACK}En lista med installerade NewGRF-filer . Välj en fil för att ändra dess parametrar
+STR_NEWGRF_PARAMETER :{BLACK}Paramerar: {SILVER}{STRING}
+STR_NEWGRF_PARAMETER_QUERY :{BLACK}Skriv NewGRF parameterar
+STR_NEWGRF_NO_INFO :{BLACK}Ingen information tillgänglig
+
+STR_NEWGRF_ADD_CAPTION :{WHITE}Tillgängliga NewGRF filer
+STR_NEWGRF_ADD_FILE :{BLACK}Lägg till markering
+STR_NEWGRF_ADD_FILE_TIP :{BLACK}Lägg till den markerade NewGRF-filen till din konfiguration
+STR_NEWGRF_RESCAN_FILES :{BLACK}Läs om filer
+STR_NEWGRF_RESCAN_FILES_TIP :{BLACK}Uppdatera listan med tillgängliga NewGRF-filer
+STR_NEWGRF_DUPLICATE_GRFID :{WHITE}Kan inte lägga till filen: redan existerande GRF ID
+
+STR_NEWGRF_NOT_FOUND :{RED}Matchande fil hittades ej
+STR_NEWGRF_DISABLED :{RED}Avstängd
+
+STR_CURRENCY_WINDOW :{WHITE}Egen valuta
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Växlingskurs: {ORANGE}{CURRENCY} = £ {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Avskiljare:
+STR_CURRENCY_PREFIX :{LTBLUE}Prefix:
+STR_CURRENCY_SUFFIX :{LTBLUE}Suffix:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Går över till Euro: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Går över till Euro: {ORANGE}aldrig
+STR_CURRENCY_PREVIEW :{LTBLUE}Förhandsgranska: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Ändra valutaparametrar
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} TÃ¥g
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} Vägfordon
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} Flygplan
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} Skepp
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Visa alla tåg där denna station finns med i rutten
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Visa alla vägfordon där denna station finns med i rutten
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Visa alla flygplan där denna station finns med i rutten
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Visa alla skepp där denna station finns med i rutten
+
+STR_VEH_WITH_SHARED_ORDERS_LIST :{WHITE}Delade instruktioner med {COMMA} Fordon{P "" s}
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}Visa alla fordon som har samma schema
+
+### depot strings
+STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Du är på väg att sälja alla fordon i depån. Är du säker?
+
+STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP :{BLACK}Sälj alla tåg i depån
+STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP :{BLACK}Sälj alla vägfordon i depån
+STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP :{BLACK}Sälj alla skepp i depån
+STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP :{BLACK}Sälj alla flygplan i hangaren
+
+STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP :{BLACK}Ge en lista av alla tåg som har denna depå i dess körschema
+STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP :{BLACK}Ge en lista av alla fordon som har denna depå i dess körschema
+STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP :{BLACK}Ge en lista av alla fartyg som har denna depå i dess körschema
+STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP :{BLACK}Ge en lista av alla flygplan som har denna flygplats-hangar i dess körschema
+
+STR_DEPOT_AUTOREPLACE_TRAIN_TIP :{BLACK}Byt ut alla tåg i depån
+STR_DEPOT_AUTOREPLACE_ROADVEH_TIP :{BLACK}Byt ut alla vägfordon i depån
+STR_DEPOT_AUTOREPLACE_SHIP_TIP :{BLACK}Byt ut alla skepp i depån
+STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP :{BLACK}Byt ut alla flygplan i hangaren
+
+STR_VEHICLE_LIST_TRAIN_DEPOT :{BLACK}{STRING} - {COMMA} TÃ¥g
+STR_VEHICLE_LIST_ROADVEH_DEPOT :{BLACK}{STRING} - {COMMA} Vägfordon
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} Skepp
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} Flygplan
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}Byt ut {STRING}
+STR_REPLACE_VEHICLES_START :{BLACK}Börja byta ut fordon
+STR_REPLACE_VEHICLES_STOP :{BLACK}Sluta byta ut fordon
+STR_NOT_REPLACING :{BLACK}Byter inte ut
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Inget fordon valt
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Välj fordonstyp att byta ut
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Välj den nya fordonstyp du vill använda i stället för den till vänster valda typen
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Tryck för att sluta byta ut fordonstypen vald på vänster sida
+STR_REPLACE_HELP_START_BUTTON :{BLACK}Tryck för att börja byta ut fordonstypen vald på vänster sida med fordonstypen på höger sida
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Välj järnvägstyp för att byta ut fordon
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Visa vilket fordon, det vänstra fordonet byts ut till, om något
+STR_REPLACE_HELP :{BLACK}Detta gör det möjligt att byta ut en fordonstyp med en annan typ, när tågen av den ursprungliga typen anländer till en depå
+STR_REPLACE_REMOVE_WAGON :{BLACK}Vagnborttagning: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Gör så att automatiskt utbytning behåller ett tågs längd genom att ta bort vagnar (med början längst fram) om utbytandet av loket skulle göra tåget längre.
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}Ersätter: {ORANGE}{SKIP}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} EXPERIMENTIELL FEATURE {}Välj mellan lok och vagn ersättnings-fönster.{}Vagns-ersättning kommer endast ske om den nya vagnen kan bli omrustad till att bära samma typ av last som den gamla. Detta kollas för varje vagn när den faktiska ersättningen sker
+STR_ENGINE_NOT_BUILDABLE :{WHITE}Loket går inte att bygga
+
+STR_ENGINES :Lok
+STR_WAGONS :Vagnar
+
+STR_MASS_STOP_DEPOT_TRAIN_TIP :{BLACK}Klicka för att stanna alla tåg i depån
+STR_MASS_STOP_DEPOT_ROADVEH_TIP :{BLACK}Klicka för att stanna alla fordon i depån
+STR_MASS_STOP_DEPOT_SHIP_TIP :{BLACK}Klicka för att stanna alla skepp i depån
+STR_MASS_STOP_HANGAR_TIP :{BLACK}Klicka för att stanna alla flygplan i hangaren
+
+STR_MASS_START_DEPOT_TRAIN_TIP :{BLACK}Klicka för att starta alla tåg i depån
+STR_MASS_START_DEPOT_ROADVEH_TIP :{BLACK}Klicka för att starta alla fordon i depån
+STR_MASS_START_DEPOT_SHIP_TIP :{BLACK}Klicka för att starta alla skepp i depån
+STR_MASS_START_HANGAR_TIP :{BLACK}Klicka för att starta alla skepp i depån
+
+STR_MASS_STOP_LIST_TIP :{BLACK}Klicka för att stoppa alla fordon i listan
+STR_MASS_START_LIST_TIP :{BLACK}Klicka för att starta alla fordon i listan
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}Skyltlista - {COMMA} Skylt{P "" ar}
+
+STR_ORDER_REFIT_FAILED :{WHITE}Misslyckande av anpassning stoppat {STRING} {COMMA}
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :Järnvägsfordon
+STR_ELRAIL_VEHICLES :Elektriska järnvägsfordon
+STR_MONORAIL_VEHICLES :Monorail-fordon
+STR_MAGLEV_VEHICLES :Maglevfordon
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Kostnad: {GOLD}{CURRENCY}{BLACK} Vikt: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Hastighet: {GOLD}{VELOCITY}{BLACK} Effekt: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}Hastighet: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Driftkostnader: {GOLD}{CURRENCY}/Ã¥r
+STR_PURCHASE_INFO_CAPACITY :{BLACK}Kapacitet: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Designår: {GOLD}{NUM}{BLACK} Livslängd: {GOLD}{COMMA} år
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}Max. tillförlitlighet: {GOLD}{COMMA} %
+STR_PURCHASE_INFO_COST :{BLACK}Kostnad: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Vikt: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Kostnad: {GOLD}{CURRENCY}{BLACK} Hastighet: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Kapacitet: {GOLD}{COMMA} passagerare, {COMMA} säckar post
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Motoriserade vagnar: {GOLD}+{POWER}{BLACK} Vikt: {GOLD}+{WEIGHT_S}
+STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Upprustningsbar till: {GOLD}
+STR_PURCHASE_INFO_ALL_TYPES :Alla typer av last
+STR_PURCHASE_INFO_ALL_BUT :Alla utom {GOLD}
+STR_PURCHASE_INFO_MAX_TE :{BLACK}Maximal Dragkraft: {GOLD}{FORCE}
+
+########### String for New Landscape Generator
+
+STR_GENERATE :{WHITE}Generera
+STR_RANDOM :{BLACK}Slumpa
+STR_RANDOM_HELP :{BLACK}Ändra slump-nummer som används för terräng-generering
+STR_WORLD_GENERATION_CAPTION :{WHITE}Generera Värld
+STR_RANDOM_SEED :{BLACK}Slump-nummer:
+STR_RANDOM_SEED_HELP :{BLACK}Klicka för att mata in ett slump-nummer
+STR_LAND_GENERATOR :{BLACK}Landgenerator:
+STR_TREE_PLACER :{BLACK}Träd Algoritm:
+STR_HEIGHTMAP_ROTATION :{BLACK}Rotation på höjdkarta:
+STR_TERRAIN_TYPE :{BLACK}Terrängtyp:
+STR_QUANTITY_OF_SEA_LAKES :{BLACK}Havsnivå
+STR_SMOOTHNESS :{BLACK}Jämnhet:
+STR_SNOW_LINE_HEIGHT :{BLACK}Snölinjens höjd:
+STR_DATE :{BLACK}Datum:
+STR_NUMBER_OF_TOWNS :{BLACK}Antal städer:
+STR_NUMBER_OF_INDUSTRIES :{BLACK}Antal industrier:
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_SNOW_LINE_UP :{BLACK}Höj snölinjens höjd ett upp
+STR_SNOW_LINE_DOWN :{BLACK}Sänk snölinjens höjd ett ner
+STR_SNOW_LINE_QUERY_CAPT :{WHITE}Ändra snölinjens höjd
+STR_START_DATE_QUERY_CAPT :{WHITE}Ändra Startår
+STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Skala-varning
+STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}För stora storleksändringar av källkarta är inte rekomenderat. Fortsätt med generering?
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_HEIGHTMAP_NAME :{BLACK}Namn på höjdkarta:
+STR_HEIGHTMAP_SIZE :{BLACK}Storlek: {ORANGE}{NUM} x {NUM}
+STR_GENERATION_WORLD :{WHITE}Genererar värld...
+STR_GENERATION_ABORT :{BLACK}Avbryt
+STR_GENERATION_ABORT_CAPTION :{WHITE}Avbryt generering av världen
+STR_GENERATION_ABORT_MESSAGE :{YELLOW}Vill du verkligen avbryta genereringen?
+STR_PROGRESS :{WHITE}{NUM}% färdigt
+STR_GENERATION_PROGRESS :{BLACK}{NUM} / {NUM}
+STR_WORLD_GENERATION :{BLACK}Generera Värld
+STR_TREE_GENERATION :{BLACK}Generera Träd
+STR_UNMOVABLE_GENERATION :{BLACK}Icke flyttbar generering
+STR_CLEARING_TILES :{BLACK}Svår och stenig markgenerering
+STR_SETTINGUP_GAME :{BLACK}Ställer in spel
+STR_PREPARING_TILELOOP :{BLACK}Kör tile-loop
+STR_PREPARING_GAME :{BLACK}Förbereder spel
+STR_DIFFICULTY_TO_CUSTOM :{WHITE}Denna åtgärd ändrade svårighetsgraden till egen-inställd
+STR_SE_FLAT_WORLD :{WHITE}Plant land
+STR_SE_FLAT_WORLD_TIP :{BLACK}Generera ett plant land
+STR_SE_RANDOM_LAND :{WHITE}Slumpat land
+STR_SE_NEW_WORLD :{BLACK}Skapa ett nytt scenario
+STR_SE_CAPTION :{WHITE}Scenarotyp
+STR_FLAT_WORLD_HEIGHT_DOWN :{BLACK}Sänk höjden av platt land ett ner
+STR_FLAT_WORLD_HEIGHT_UP :{BLACK}Öka höjden av platt land ett upp
+STR_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Ändra höjd av platt land
+STR_FLAT_WORLD_HEIGHT :{BLACK}Höjd av platt land:
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+STR_SMALLMAP_CENTER :{BLACK}Centrera den lilla kartan på den nuvarande positionen
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}Liten
+STR_CITY_AIRPORT :{BLACK}Stad
+STR_METRO_AIRPORT :{BLACK}Storstads-Flygplats
+STR_INTERNATIONAL_AIRPORT :{BLACK}Internationell Flygplats
+STR_COMMUTER_AIRPORT :{BLACK}Pendlare
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Jättestor flygplats
+STR_HELIPORT :{BLACK}Helikopterplatta
+STR_HELIDEPOT :{BLACK}Helikopterhangar
+STR_HELISTATION :{BLACK}Helikopterstation
+
+STR_SMALL_AIRPORTS :{BLACK}Små flygfält
+STR_LARGE_AIRPORTS :{BLACK}Stora Flygplatser
+STR_HUB_AIRPORTS :{BLACK}Centrala Flygplatser
+STR_HELIPORTS :{BLACK}Helikopterfält
+
+############ Tooltip measurment
+
+STR_MEASURE_LENGTH :{BLACK}Längd: {NUM}
+STR_MEASURE_AREA :{BLACK}Yta: {NUM} x {NUM}
+STR_MEASURE_LENGTH_HEIGHTDIFF :{BLACK}Längd: {NUM}{}Höjdskillnad: {NUM} m
+STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}Yta: {NUM} x {NUM}{}Höjdskillnad: {NUM} m
+
+########
diff --git a/src/lang/turkish.txt b/src/lang/turkish.txt
new file mode 100644
index 000000000..bc8b70546
--- /dev/null
+++ b/src/lang/turkish.txt
@@ -0,0 +1,3114 @@
+##name Turkish
+##ownname Türkçe
+##isocode tr_TR.UTF-8
+##plural 1
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Harita kenarında
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Sınıra çok yakın
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Para Yetersiz - ÅŸu kadar gerekli: {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Yerin düzleştirilmesi lazım
+STR_0008_WAITING :{BLACK}Bekleyen: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (aktarma:
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Ä°stenen: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Ä°stenen: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :Yolcu
+STR_0010_COAL :Kömür
+STR_0011_MAIL :Posta
+STR_0012_OIL :Petrol
+STR_0013_LIVESTOCK :Hayvan
+STR_0014_GOODS :EÅŸya
+STR_0015_GRAIN :Tahıl
+STR_0016_WOOD :Odun
+STR_0017_IRON_ORE :Demir
+STR_0018_STEEL :Çelik
+STR_0019_VALUABLES :Mücevher
+STR_001A_COPPER_ORE :Bakır
+STR_001B_MAIZE :Mısır
+STR_001C_FRUIT :Meyve
+STR_001D_DIAMONDS :Elmas
+STR_001E_FOOD :Yiyecek
+STR_001F_PAPER :Kağıt
+STR_0020_GOLD :Altın
+STR_0021_WATER :Su
+STR_0022_WHEAT :Un
+STR_0023_RUBBER :Kauçuk
+STR_0024_SUGAR :Åžeker
+STR_0025_TOYS :Oyuncak
+STR_0026_CANDY :Tatlı
+STR_0027_COLA :Kola
+STR_0028_COTTON_CANDY :Pamukhelva
+STR_0029_BUBBLES :Balon
+STR_002A_TOFFEE :Bonbon
+STR_002B_BATTERIES :Pil
+STR_002C_PLASTIC :Plastik
+STR_002D_FIZZY_DRINKS :İçecek
+STR_002E :
+STR_002F_PASSENGER :Yolcu
+STR_0030_COAL :Kömür
+STR_0031_MAIL :Posta
+STR_0032_OIL :Petrol
+STR_0033_LIVESTOCK :Hayvan
+STR_0034_GOODS :EÅŸya
+STR_0035_GRAIN :Tahıl
+STR_0036_WOOD :Odun
+STR_0037_IRON_ORE :Demir
+STR_0038_STEEL :Çelik
+STR_0039_VALUABLES :Mücevher
+STR_003A_COPPER_ORE :Bakır
+STR_003B_MAIZE :Mısır
+STR_003C_FRUIT :Meyve
+STR_003D_DIAMOND :Elmas
+STR_003E_FOOD :Yiyecek
+STR_003F_PAPER :Kağıt
+STR_0040_GOLD :Altın
+STR_0041_WATER :Su
+STR_0042_WHEAT :Un
+STR_0043_RUBBER :Kauçuk
+STR_0044_SUGAR :Åžeker
+STR_0045_TOY :Oyuncak
+STR_0046_CANDY :Tatlı
+STR_0047_COLA :Kola
+STR_0048_COTTON_CANDY :Pamukhelva
+STR_0049_BUBBLE :Balon
+STR_004A_TOFFEE :Bonbon
+STR_004B_BATTERY :Pil
+STR_004C_PLASTIC :Plastik
+STR_004D_FIZZY_DRINK :İçecek
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} yolcu
+STR_QUANTITY_COAL :{WEIGHT} kömür
+STR_QUANTITY_MAIL :{COMMA} çanta posta
+STR_QUANTITY_OIL :{VOLUME} petrol
+STR_QUANTITY_LIVESTOCK :{COMMA} tane hayvan
+STR_QUANTITY_GOODS :{COMMA} kasa eÅŸya
+STR_QUANTITY_GRAIN :{WEIGHT} tahıl
+STR_QUANTITY_WOOD :{WEIGHT} odun
+STR_QUANTITY_IRON_ORE :{WEIGHT} demir
+STR_QUANTITY_STEEL :{WEIGHT} çelik
+STR_QUANTITY_VALUABLES :{COMMA} çanta mücevher
+STR_QUANTITY_COPPER_ORE :{WEIGHT} bakır
+STR_QUANTITY_MAIZE :{WEIGHT} mısır
+STR_QUANTITY_FRUIT :{WEIGHT} meyve
+STR_QUANTITY_DIAMONDS :{COMMA} çanta elmas
+STR_QUANTITY_FOOD :{WEIGHT} yiyecek
+STR_QUANTITY_PAPER :{WEIGHT} kağıt
+STR_QUANTITY_GOLD :{COMMA} çanta altın
+STR_QUANTITY_WATER :{VOLUME} su
+STR_QUANTITY_WHEAT :{WEIGHT} un
+STR_QUANTITY_RUBBER :{VOLUME} kauçuk
+STR_QUANTITY_SUGAR :{WEIGHT} ÅŸeker
+STR_QUANTITY_TOYS :{COMMA} oyuncak
+STR_QUANTITY_SWEETS :{COMMA} çanta tatlı
+STR_QUANTITY_COLA :{VOLUME} kola
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} pamukhelva
+STR_QUANTITY_BUBBLES :{COMMA} balon
+STR_QUANTITY_TOFFEE :{WEIGHT} bonbon
+STR_QUANTITY_BATTERIES :{COMMA} pil
+STR_QUANTITY_PLASTIC :{VOLUME} plastik
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} içecek
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}YL
+STR_ABBREV_COAL :{TINYFONT}KÖ
+STR_ABBREV_MAIL :{TINYFONT}PO
+STR_ABBREV_OIL :{TINYFONT}PE
+STR_ABBREV_LIVESTOCK :{TINYFONT}HV
+STR_ABBREV_GOODS :{TINYFONT}ES
+STR_ABBREV_GRAIN :{TINYFONT}TH
+STR_ABBREV_WOOD :{TINYFONT}OD
+STR_ABBREV_IRON_ORE :{TINYFONT}DM
+STR_ABBREV_STEEL :{TINYFONT}ÇE
+STR_ABBREV_VALUABLES :{TINYFONT}MÜ
+STR_ABBREV_COPPER_ORE :{TINYFONT}BK
+STR_ABBREV_MAIZE :{TINYFONT}MS
+STR_ABBREV_FRUIT :{TINYFONT}MV
+STR_ABBREV_DIAMONDS :{TINYFONT}EL
+STR_ABBREV_FOOD :{TINYFONT}YE
+STR_ABBREV_PAPER :{TINYFONT}KA
+STR_ABBREV_GOLD :{TINYFONT}ES
+STR_ABBREV_WATER :{TINYFONT}SU
+STR_ABBREV_WHEAT :{TINYFONT}UN
+STR_ABBREV_RUBBER :{TINYFONT}KA
+STR_ABBREV_SUGAR :{TINYFONT}SK
+STR_ABBREV_TOYS :{TINYFONT}OY
+STR_ABBREV_SWEETS :{TINYFONT}TA
+STR_ABBREV_COLA :{TINYFONT}KO
+STR_ABBREV_CANDYFLOSS :{TINYFONT}PH
+STR_ABBREV_BUBBLES :{TINYFONT}BA
+STR_ABBREV_TOFFEE :{TINYFONT}PH
+STR_ABBREV_BATTERIES :{TINYFONT}PI
+STR_ABBREV_PLASTIC :{TINYFONT}PL
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}İÇ
+STR_ABBREV_NONE :{TINYFONT}YOK
+STR_ABBREV_ALL :{TINYFONT}HEPSI
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Harita - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Seçenekler
+STR_00B2_MESSAGE :{YELLOW}Mesaj
+STR_00B3_MESSAGE_FROM :{YELLOW}Mesaj: {STRING}
+STR_POPUP_CAUTION_CAPTION :{WHITE}Uyarı!
+STR_00B4_CAN_T_DO_THIS :{WHITE}Yapılamaz....
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Burası temizlenemez....
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Orjinal kopyalama hakkı {COPYRIGHT} 1995 Chris Sawyer, Her Hakkı Saklıdır
+STR_00B7_VERSION :{BLACK}OpenTTD sürüm {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 OpenTTD takımı
+STR_TRANSLATED_BY :{BLACK} Çevirenler -
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Çıkış
+STR_00C8_YES :{BLACK}Evet
+STR_00C9_NO :{BLACK}Hayır
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Oyundan çıkıp {STRING} sisteminize dönmek istediğinizden emin misiniz?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Hiçbir şey
+STR_00D1_DARK_BLUE :Koyu Mavi
+STR_00D2_PALE_GREEN :Soluk YeÅŸil
+STR_00D3_PINK :Pembe
+STR_00D4_YELLOW :Sarı
+STR_00D5_RED :Kırmızı
+STR_00D6_LIGHT_BLUE :Açık Mavi
+STR_00D7_GREEN :YeÅŸil
+STR_00D8_DARK_GREEN :Koyu YeÅŸil
+STR_00D9_BLUE :Mavi
+STR_00DA_CREAM :Krem
+STR_00DB_MAUVE :Leylak
+STR_00DC_PURPLE :Mor
+STR_00DD_ORANGE :Turuncu
+STR_00DE_BROWN :Kahverengi
+STR_00DF_GREY :Gri
+STR_00E0_WHITE :Beyaz
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Oyunda çok fazla araç var
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Göster
+STR_00E5_CONTOURS :Dış Hatlar
+STR_00E6_VEHICLES :Araçlar
+STR_00E7_INDUSTRIES :Fabrikalar
+STR_00E8_ROUTES :Rotalar
+STR_00E9_VEGETATION :Bitkiler
+STR_00EA_OWNERS :Sahipler
+STR_00EB_ROADS :{BLACK}{TINYFONT}Yollar
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Raylar
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Garlar/Havalimanları/Limanlar
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Binalar/Fabrikalar
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Araçlar
+STR_00F0_100M :{BLACK}{TINYFONT}100m
+STR_00F1_200M :{BLACK}{TINYFONT}200m
+STR_00F2_300M :{BLACK}{TINYFONT}300m
+STR_00F3_400M :{BLACK}{TINYFONT}400m
+STR_00F4_500M :{BLACK}{TINYFONT}500m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Trenler
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Karayolu Taşıtları
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Gemiler
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Uçaklar
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Taşıma Rotaları
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Kömür Madeni
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Elektrik Santrali
+STR_00FC_FOREST :{BLACK}{TINYFONT}Orman
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}Keresteci
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Petrol Rafinerisi
+STR_00FF_FARM :{BLACK}{TINYFONT}Çiftlik
+STR_0100_FACTORY :{BLACK}{TINYFONT}Fabrika
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Basımevi
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Petrol Kuyuları
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Demir Madeni
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Çelik Fabrikası
+STR_0105_BANK :{BLACK}{TINYFONT}Banka
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Kağıt Fabrikası
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Altın Madeni
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Yemek Fabrikası
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Elmas Madeni
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Bakır Madeni
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Meyve Ağaçları
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Kauçuk Bahçesi
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Su Kaynağı
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Su Kulesi
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}Keresteci
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Pamukhelva Ormanı
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Tatlı Fabrikası
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Pil Çiftliği
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Kola Kuyuları
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Oyuncakçı
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Oyuncak Fabrikası
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Plastik Fıskiyesi
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}İçecek Fabrikası
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Balon Yapıcı
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Bonbon Madeni
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Åžeker Madeni
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Tren istasyonu
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Kamyon Yükleme Yeri
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Otobüs Durağı
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Havalimanı/Heliport
+STR_011F_DOCK :{BLACK}{TINYFONT}Ä°skele
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Engebeli Yer
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Çimlik Yer
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Çıplak Yer
+STR_0123_FIELDS :{BLACK}{TINYFONT}Meralar
+STR_0124_TREES :{BLACK}{TINYFONT}Ağaçlar
+STR_0125_ROCKS :{BLACK}{TINYFONT}Kayalar
+STR_0126_WATER :{BLACK}{TINYFONT}Su
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Sahipsiz
+STR_0128_TOWNS :{BLACK}{TINYFONT}Åžehirler
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Fabrikalar
+STR_012A_DESERT :{BLACK}{TINYFONT}Çöl
+STR_012B_SNOW :{BLACK}{TINYFONT}Karlı
+STR_012C_MESSAGE :{WHITE}Mesaj
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Ä°ptal
+STR_012F_OK :{BLACK}Tamam
+STR_0130_RENAME :{BLACK}Yeni ad
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Çok fazla adlandırma
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Seçilen isim kullanımda
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...sahibi {STRING}
+STR_013C_CARGO :{BLACK}Kargo
+STR_013D_INFORMATION :{BLACK}Bilgi
+STR_013E_CAPACITIES :{BLACK}Kapasite
+STR_013E_TOTAL_CARGO :{BLACK}Toplam Kargo
+STR_013F_CAPACITY :{BLACK}Kapasite: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}Kapasite: {LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Bu trenin toplam kapasitesi:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}Yeni Oyun
+STR_0141_LOAD_GAME :{BLACK}Oyun Yükle
+STR_SINGLE_PLAYER :{BLACK}Tek Oyunculu
+STR_MULTIPLAYER :{BLACK}Çok Oyunculu
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Harita boyutu:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Seçenekler
+
+STR_0150_SOMEONE :birisi{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Dünya haritası
+STR_0152_TOWN_DIRECTORY :Åžehir Listesi
+STR_0153_SUBSIDIES :Ä°haleler
+
+STR_UNITS_IMPERIAL :Amerikan
+STR_UNITS_METRIC :Metrik
+STR_UNITS_SI :SI
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} mil/s
+STR_UNITS_VELOCITY_METRIC :{COMMA} km/s
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}bg
+STR_UNITS_POWER_METRIC :{COMMA}bg
+STR_UNITS_POWER_SI :{COMMA}kW
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} ton
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} ton
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} kg
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}gal
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}l
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}m
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} galon
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} litre
+STR_UNITS_VOLUME_LONG_SI :{COMMA} m
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10³ lbf
+STR_UNITS_FORCE_METRIC :{COMMA} ton
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Kar grafiÄŸi
+STR_0155_INCOME_GRAPH :Gelir grafiÄŸi
+STR_0156_DELIVERED_CARGO_GRAPH :Taşınan kargo grafiği
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Performans tarihi grafiÄŸi
+STR_0158_COMPANY_VALUE_GRAPH :Åžirket deÄŸeri grafiÄŸi
+STR_0159_CARGO_PAYMENT_RATES :Kargo ödeme tablosu
+STR_015A_COMPANY_LEAGUE_TABLE :Åžirketler ligi
+STR_PERFORMANCE_DETAIL_MENU :Ayrıntılı Performans
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}OpenTTD Hakkinda
+STR_015C_SAVE_GAME :Kaydet
+STR_015D_LOAD_GAME :Yükle
+STR_015E_QUIT_GAME :Bitir
+STR_015F_QUIT :Çıkış
+STR_ABANDON_GAME_QUERY :{YELLOW}Oyunu bitirmek istediÄŸinizden emin misiniz?
+STR_0161_QUIT_GAME :{WHITE}Oyunu Bitir
+STR_SORT_ORDER_TIP :{BLACK}Sıralama türü seçin (azalan/artan)
+STR_SORT_CRITERIA_TIP :{BLACK}Sıralama kriteri seçin
+STR_SORT_BY :{BLACK}Sırala
+
+STR_SORT_BY_POPULATION :{BLACK}Nüfus
+STR_SORT_BY_PRODUCTION :{BLACK}Ãœretim
+STR_SORT_BY_TYPE :{BLACK}Tür
+STR_SORT_BY_TRANSPORTED :{BLACK}Taşınan
+STR_SORT_BY_NAME :{BLACK}Ä°sim
+STR_SORT_BY_DROPDOWN_NAME :Ä°sim
+STR_SORT_BY_DATE :{BLACK}Tarih
+STR_SORT_BY_NUMBER :Numara
+STR_SORT_BY_PROFIT_LAST_YEAR :Geçen seneki kâr
+STR_SORT_BY_PROFIT_THIS_YEAR :Bu seneki kâr
+STR_SORT_BY_AGE :YaÅŸ
+STR_SORT_BY_RELIABILITY :Güvenilirlik
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Her kargo için toplam kapasite
+STR_SORT_BY_MAX_SPEED :En yüksek hız
+STR_SORT_BY_MODEL :Model
+STR_SORT_BY_VALUE :Fiyat
+STR_SORT_BY_FACILITY :İstasyon türü
+STR_SORT_BY_WAITING :Bekleyen kargo deÄŸeri
+STR_SORT_BY_RATING_MAX :Kargo reytingi
+STR_ENGINE_SORT_ENGINE_ID :Lokoismi (klasik sira)
+STR_ENGINE_SORT_COST :Fiyat
+STR_ENGINE_SORT_POWER :Güç
+STR_ENGINE_SORT_INTRO_DATE :Piyasaya GiriÅŸi
+STR_ENGINE_SORT_RUNNING_COST :Bakım Gideri
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Güç/Bakım Gideri
+STR_ENGINE_SORT_CARGO_CAPACITY :Kapasite
+STR_NO_WAITING_CARGO :{BLACK}Hiç kargo yok
+STR_SELECT_ALL_FACILITIES :{BLACK}Tüm türleri seç
+STR_SELECT_ALL_TYPES :{BLACK}Tüm kargo türlerini seç (hiç beklemeyenler dahil)
+STR_AVAILABLE_ENGINES_TIP :{BLACK}Bu araç türü için mümkün olan lokomotif tasarimlari
+STR_MANAGE_LIST :{BLACK}Listeyi yönet
+STR_MANAGE_LIST_TIP :{BLACK}Listedeki tüm araçlara komut ver
+STR_REPLACE_VEHICLES :Araçları Değiştir
+STR_SEND_TRAIN_TO_DEPOT :Gara Gönder
+STR_SEND_ROAD_VEHICLE_TO_DEPOT :Garaja Gönder
+STR_SEND_SHIP_TO_DEPOT :Tersaneye Gönder
+STR_SEND_AIRCRAFT_TO_HANGAR :Hangara Gönder
+STR_SEND_FOR_SERVICING :Bakıma İçin Gönder
+
+############ range for months starts
+STR_0162_JAN :Oca
+STR_0163_FEB :Åžub
+STR_0164_MAR :Mar
+STR_0165_APR :Nis
+STR_0166_MAY :May
+STR_0167_JUN :Haz
+STR_0168_JUL :Tem
+STR_0169_AUG :AÄŸu
+STR_016A_SEP :Eyl
+STR_016B_OCT :Eki
+STR_016C_NOV :Kas
+STR_016D_DEC :Ara
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Duraklat
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Kaydet, bitir, çık
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Şirket istasyonlarının listesini göster
+STR_0174_DISPLAY_MAP :{BLACK}Haritayı göster
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Haritayı, şehir listesini göster
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Şehir listesini göster
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Şirket ekonomisini göster
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Genel şirket bilgisi göster
+STR_0179_DISPLAY_GRAPHS :{BLACK}Grafikleri göster
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Şirket ligini göster
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Tren listesini göster
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Karayolu taşıtı listesini göster
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Gemi listesini göster
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Uçak listesini göster
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}YaklaÅŸ
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}UzaklaÅŸ
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Ray yapımı
+STR_0182_BUILD_ROADS :{BLACK}Yol yapımı
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}İskele yapımı
+STR_0184_BUILD_AIRPORTS :{BLACK}Havalimanı yapımı
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}AÄŸac dik, tabela koy vs.
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Yer bilgisi
+STR_0187_OPTIONS :{BLACK}Seçenekler
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Servis gecikmesini deÄŸiÅŸtiremiyor...
+STR_018B_CLOSE_WINDOW :{BLACK}Pencereyi kapat
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Pencere başlığı - pencereyi götürmek için sürükle
+STR_STICKY_BUTTON :{BLACK}'Tüm pencereleri kapat' tuşuyla kapanmasın
+STR_RESIZE_BUTTON :{BLACK}Pencereyi boyutlandirmak için tıklayıp sürükle
+STR_SAVELOAD_HOME_BUTTON :{BLACK}Su anki varsayılan kayıt/yükleme dizinine gitmek için tıklayın
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Bir karedeki binaları vb. yık
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Bir köşeyi alçalt
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Bir köşeyi yükselt
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Kaydırma çubuğu - listeyi aşağı/yukarı kaydır
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Kaydırma çubuğu - listeyi sağa/sola kaydır
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Haritanın anahatlarını göster
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Haritada araçları göster
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Haritada fabrikaları göster
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Haritada taşıma rotalarını göster
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Haritada bitkileri göster
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Haritada arsa sahiplerini göster
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Haritada şehir isimlerini aç/kapa
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Bu seneki kâr: {CURRENCY} (geçen sene: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} sene ({COMMA})
+STR_AGE_RED :{RED}{COMMA} sene ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Karayolu taşıtı
+STR_019D_AIRCRAFT :Uçak
+STR_019E_SHIP :Gemi
+STR_019F_TRAIN :Tren
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} eskidi
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} çok eskidi
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} çok eskidi, artık hurdaya ayrılması gerekiyor
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Yer Bilgisi
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Temizleme fiyatı: {LTBLUE}Yok
+STR_01A5_COST_TO_CLEAR :{BLACK}Temizleme fiyatı: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :Yok
+STR_01A7_OWNER :{BLACK}Sahibi: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Belediyesi: {LTBLUE}{STRING}
+STR_01A9_NONE :Hiçbiri
+STR_01AA_NAME :{BLACK}Ä°sim
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1
+STR_01AD_2ND :2
+STR_01AE_3RD :3
+STR_01AF_4TH :4
+STR_01B0_5TH :5
+STR_01B1_6TH :6
+STR_01B2_7TH :7
+STR_01B3_8TH :8
+STR_01B4_9TH :9
+STR_01B5_10TH :10
+STR_01B6_11TH :11
+STR_01B7_12TH :12
+STR_01B8_13TH :13
+STR_01B9_14TH :14
+STR_01BA_15TH :15
+STR_01BB_16TH :16
+STR_01BC_17TH :17
+STR_01BD_18TH :18
+STR_01BE_19TH :19
+STR_01BF_20TH :20
+STR_01C0_21ST :21
+STR_01C1_22ND :22
+STR_01C2_23RD :23
+STR_01C3_24TH :24
+STR_01C4_25TH :25
+STR_01C5_26TH :26
+STR_01C6_27TH :27
+STR_01C7_28TH :28
+STR_01C8_29TH :29
+STR_01C9_30TH :30
+STR_01CA_31ST :31
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Ä°stenen: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Caz Paketi
+STR_01D3_SOUND_MUSIC :Ses/müzik
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Ses/müzik penceresini göster
+STR_01D5_ALL :{TINYFONT}Hepsi
+STR_01D6_OLD_STYLE :{TINYFONT}Eski Stil
+STR_01D7_NEW_STYLE :{TINYFONT}Yeni Stil
+STR_01D8_EZY_STREET :{TINYFONT}Ezy Sokağı
+STR_01D9_CUSTOM_1 :{TINYFONT}Özel 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Özel 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Müzik Sesi
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Efekt Sesi
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}Düşük ' ' ' ' ' ' Yüksek
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Önceki şarkı
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Sonraki şarkı
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Müziği kes
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Müziği çal
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Sesi ayarlamak için sürükleyin
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Sarki{SETX 88}Başlığı
+STR_01E9_SHUFFLE :{TINYFONT}Rastgele
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Program
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Müzik Programi Seçimi
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Parça Listesi
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Program - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}Temizle
+STR_01F1_SAVE :{TINYFONT}{BLACK}Kaydet
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Åžu anki program
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}'tüm şarkılar' programını seç
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}'eski stil' programını seç
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}'yeni stil' programını seç
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}'Özel 1' (kullanıcı-tanımlı) programı seç
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}'Özel 2' (kullanıcı-tanımlı) programı seç
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Şimdiki programı temizle (Sadece özel1 ve özel2 için)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Müzik ayarlarıni kaydet
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Su anki programa eklenecek müzige tıklayın (Sadece özel1 ve özel2 için)
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Kullanilan programdan kaldırilacak müzige tıklayın(Custom1 veya Custom2 için geçerli)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Rastgele programı aç/kapa
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Şarki seçim penceresini göster
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Görüntüyü ortalamak için servisi tıklayın
+STR_01FE_DIFFICULTY :{BLACK}Zorluk ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Son mesaj/haber
+STR_0201_MESSAGE_SETTINGS :Mesaj ayarları
+STR_MESSAGE_HISTORY_MENU :Mesaj Geçmişi
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Son mesajı/haberi göster, mesaj ayarlarını göster
+STR_0204_MESSAGE_OPTIONS :{WHITE}Mesaj Seçenekleri
+STR_0205_MESSAGE_TYPES :{BLACK}Mesaj türleri:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Oyuncunun durağına ilk aracın gelişi
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Rakibin durağına ilk aracın gelişi
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Kazalar / felaketler
+STR_0209_COMPANY_INFORMATION :{YELLOW}Åžirket bilgisi
+STR_020A_ECONOMY_CHANGES :{YELLOW}Ekonomi deÄŸiÅŸimleri
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Oyuncunun araçlarıyla ilgili ögüt / bilgi
+STR_020C_NEW_VEHICLES :{YELLOW}Yeni araçlar
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Kargo isteÄŸindeki deÄŸiÅŸiklik
+STR_020E_SUBSIDIES :{YELLOW}Ä°haleler
+STR_020F_GENERAL_INFORMATION :{YELLOW}Genel bilgiler
+STR_MESSAGES_ALL :{YELLOW}Tüm mesajlar (kapalı/özet/tam)
+STR_MESSAGE_SOUND :{YELLOW}Özet geçerken ses çıkar
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...önceki hedeften çok uzak
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK} {NUM}{} yılına kalan en iyi şirketler ({STRING} Seviye)
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK} {NUM} senesindeki ÅŸirket ligi
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :İşadamı
+STR_0214_ENTREPRENEUR :GiriÅŸimci
+STR_0215_INDUSTRIALIST :Sanayici
+STR_0216_CAPITALIST :Kapitalist
+STR_0217_MAGNATE :Patron
+STR_0218_MOGUL :Uzman işadamı
+STR_0219_TYCOON_OF_THE_CENTURY :Asrın En Büyük işadamı
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} '{STRING}' ünvanını kazandı!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} - {COMPANY} '{STRING}' unvanını kazandı!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Senaryo Yap
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Senaryo Editörü
+STR_0223_LAND_GENERATION :{WHITE}Yer Yapımı
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Rastgele Yerler
+STR_0227_RESET_LAND :{BLACK}Yerleri Sıfırla
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}yükseltme/alçaltma alanını arttır
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}yükseltme/alçaltma alanını arttır
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Rastgele harita yap
+STR_022B_RESET_LANDSCAPE :{BLACK}Haritayı sıfırla
+STR_022C_RESET_LANDSCAPE :{WHITE}Haritayı Sıfırla
+STR_LOAD_GAME_HEIGHTMAP :{WHITE}Yükseklik Haritasi Kullan
+STR_LOAD_SCEN_HEIGHTMAP :{BLACK}Yükseklik Haritasi Kullan
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Her taraf su olsun mu?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Harita yapımı
+STR_022F_TOWN_GENERATION :{BLACK}Şehir yapımı
+STR_0230_INDUSTRY_GENERATION :{BLACK}Fabrika yapımı
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Yol yapımı
+STR_0233_TOWN_GENERATION :{WHITE}Şehir yapımı
+STR_0234_NEW_TOWN :{BLACK}Yeni Åžehir
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Yeni ÅŸehir yap
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Buraya şehir yapılamıyor...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...haritanin kenarına çok yakın
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...başka bir şehre çok yakın
+STR_0239_SITE_UNSUITABLE :{WHITE}...yer uygun deÄŸil
+STR_023A_TOO_MANY_TOWNS :{WHITE}...çok fazla şehir var
+STR_CANNOT_GENERATE_TOWN :{WHITE}Åžehir kurulamaz
+STR_NO_SPACE_FOR_TOWN :{WHITE}...haritada boÅŸ yer yok
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Şehrin boyutunu büyült
+STR_023C_EXPAND :{BLACK}GeniÅŸlet
+STR_023D_RANDOM_TOWN :{BLACK}Rastgele Åžehir
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Rastgele bir yere ÅŸehir yap
+STR_023F_INDUSTRY_GENERATION :{WHITE}Fabrika Yapımı
+STR_0240_COAL_MINE :{BLACK}Kömür Madeni
+STR_0241_POWER_STATION :{BLACK}Elektrik Santrali
+STR_0242_SAWMILL :{BLACK}Keresteci
+STR_0243_FOREST :{BLACK}Orman
+STR_0244_OIL_REFINERY :{BLACK}Petrol Rafinerisi
+STR_0245_OIL_RIG :{BLACK}Petrol Platformu
+STR_0246_FACTORY :{BLACK}Fabrika
+STR_0247_STEEL_MILL :{BLACK}Çelik Fabrikası
+STR_0248_FARM :{BLACK}Çiftlik
+STR_0249_IRON_ORE_MINE :{BLACK}Demir Madeni
+STR_024A_OIL_WELLS :{BLACK}Petrol Kuyusu
+STR_024B_BANK :{BLACK}Banka
+STR_024C_PAPER_MILL :{BLACK}Kağıt Fabrikası
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Yemek Fabrikası
+STR_024E_PRINTING_WORKS :{BLACK}Basımevi
+STR_024F_GOLD_MINE :{BLACK}Altın Madeni
+STR_0250_LUMBER_MILL :{BLACK}Oduncu
+STR_0251_FRUIT_PLANTATION :{BLACK}Mehve Bahçesi
+STR_0252_RUBBER_PLANTATION :{BLACK}Kauçuk Bahçesi
+STR_0253_WATER_SUPPLY :{BLACK}Su Kaynağı
+STR_0254_WATER_TOWER :{BLACK}Su Kulesi
+STR_0255_DIAMOND_MINE :{BLACK}Gümüs Madeni
+STR_0256_COPPER_ORE_MINE :{BLACK}Bakır Madeni
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Pamukhelva Ormanı
+STR_0258_CANDY_FACTORY :{BLACK}Tatlı Fabrikası
+STR_0259_BATTERY_FARM :{BLACK}Pil Çiftliği
+STR_025A_COLA_WELLS :{BLACK}Kola Kuyusu
+STR_025B_TOY_SHOP :{BLACK}Oyuncakçı
+STR_025C_TOY_FACTORY :{BLACK}Oyuncak Fabrikası
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Plastik Fıskiyesi
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}İçecek Fabrikası
+STR_025F_BUBBLE_GENERATOR :{BLACK}Balon Yapıcı
+STR_0260_TOFFEE_QUARRY :{BLACK}Bonbon Madeni
+STR_0261_SUGAR_MINE :{BLACK}Åžeker Madeni
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Kömür Madeni Yap
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Elektrik Santrali Yap
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Keresteci Yap
+STR_0265_PLANT_FOREST :{BLACK}Orman Yap
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Petrol Rafinerisi Yap
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Petrol Platformu Yap (Haritanın köselerine yapılabilir)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Fabrika Yap
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Çelik Fabrikası Yap
+STR_026A_CONSTRUCT_FARM :{BLACK}Çiftlik Yap
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Demir Mdeni Yap
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Petrol Kuyusu Aç
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Banka Kur (Nüfusu 1200'den fazla olan şehirlerde kurulabilir)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Kağıt Fabrikası Yap
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Yemek Fabrikası Yap
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Basımevi Yap
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Altın Madeni Yap
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Banka Kur (Sadece ÅŸehirlerde kurulabilir)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Oduncu Yap (yagmurormanlarından odun yapar)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Mehve Bahçesi Aç
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Kauçuk Bahçesi Yap
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Su Kaynağı Yap
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Su Kulesi Yap (Sadece şehirlere yapılabilir)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Elmas Madeni Yap
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Bakır Mdeni Yap
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Pamukhelva Ormanı Yap
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Tatlı Fabrikası Yap
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Pil Çiftliği Kur
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Kola Kuyusu Aç
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Oyuncakçı Aç
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Oyuncak Fabrikası Kur
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Plastik Fıskiyesi Yap
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}İçecek Fabrikası Kur
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Balon Yapıcı Kur
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Bonbon Madeni Aç
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Şeker Madeni Aç
+STR_0285_CAN_T_BUILD_HERE :{WHITE}Buraya {STRING} yapılamaz...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...önce şehir yapılmali
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...her ÅŸehirde bir tane olabilir
+STR_0288_PLANT_TREES :{BLACK}Ağaç dik
+STR_0289_PLACE_SIGN :{BLACK}Tabela Koy
+STR_028A_RANDOM_TREES :{BLACK}Rastgele ağaçlar
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Haritaya rastgele ağaç dik
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Haritaya kayalik koy
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Deniz feneri koy
+STR_028E_PLACE_TRANSMITTER :{BLACK}Verici koy
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Çöl yap, kaldırmak için CTRL'ye basılı tut
+STR_CREATE_LAKE :{BLACK}Su yap, deniz seviyesindeki yerler suyla dolar
+STR_0290_DELETE :{BLACK}Sil
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Sehri tamamen sil
+STR_0292_SAVE_SCENARIO :Kaydet
+STR_0293_LOAD_SCENARIO :Yükle
+STR_0294_QUIT_EDITOR :Editörden Çık
+STR_0295 :
+STR_0296_QUIT :Oyundan Çık
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Senaryo kaydet, senaryo yükle, editörden çık, oyundan çık
+STR_0298_LOAD_SCENARIO :{WHITE}Senaryo Yükle
+STR_0299_SAVE_SCENARIO :{WHITE}Senaryo Kaydet
+STR_029A_PLAY_SCENARIO :{BLACK}Senaryo Oyna
+STR_PLAY_HEIGHTMAP :{BLACK}Yükseklik Haritası Oyna
+STR_PLAY_HEIGHTMAP_HINT :{BLACK}Yükseklik haritasını kullanarak yeni oyun başlat
+STR_QUIT_SCENARIO_QUERY :{YELLOW}Bu senaryodan çıkmak istediğinizden emin misiniz ?
+STR_029C_QUIT_EDITOR :{WHITE}Editörden Çık
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...nüfusu en az 1200 olan şehirlere yapılabilir
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Başlama yılını düşür
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Başlama yılını arttır
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...köprünün uçları karada olmalı
+STR_02A1_SMALL :{BLACK}Küçük
+STR_02A2_MEDIUM :{BLACK}Orta
+STR_02A3_LARGE :{BLACK}Büyük
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Şehir büyüklüğü seç
+STR_02A5_TOWN_SIZE :{YELLOW}Şehir büyüklüğü:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Son mesajı ya da haberi göster
+STR_OFF :Kapalı
+STR_SUMMARY :Özet
+STR_FULL :Tam
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Åžehir listesi
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Araç isimleri
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Varsayılan
+STR_02BF_CUSTOM :Özel
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Özel isimleri kaydet
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Araç isimleri seçimi
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Özelleştirilmiş araç isimlerini kaydet
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Seçenekler
+STR_02C5_DIFFICULTY_SETTINGS :Zorluk Ayarları
+STR_02C7_CONFIG_PATCHES :Yamaları Düzenle
+STR_NEWGRF_SETTINGS :Newgrf ayarları
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Şehir isimlerini göster
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}İstasyon isimlerini göster
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Tabelaları göster
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Yolimlerini göster
+STR_02D0_FULL_ANIMATION :{SETX 12}Tam hareketli
+STR_02D2_FULL_DETAIL :{SETX 12}Tam detay
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Transparan binalar
+STR_TRANSPARENT_SIGNS :{SETX 12}Transparan istasyon tabelaları
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Arazi bilgisi
+STR_02D6 :
+STR_CONSOLE_SETTING :Konsol Aç/Kapa
+STR_02D7_SCREENSHOT_CTRL_S :Ekran Görüntüsü (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Dev Ekran Görüntüsü (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :'OpenTTD' Hakkında
+############ range ends here
+
+STR_02DB_OFF :{BLACK}Kapalı
+STR_02DA_ON :{BLACK}Açık
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}İhaleleri göster
+STR_02DD_SUBSIDIES :Ä°haleler
+STR_02DE_MAP_OF_WORLD :Dünya haritası
+STR_EXTRA_VIEW_PORT :Ekstra görünüm
+STR_SIGN_LIST :Tabela listesi
+STR_02DF_TOWN_DIRECTORY :Åžehir listesi
+STR_TOWN_POPULATION :{BLACK}Dünya nüfusu: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Görünüm {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Görünümü kopyala
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Küresel görünümü buraya kopyala
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Görünümü yapıştır
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Bu görünümü küresel görünüme yapıştır
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Para birimleri
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Para birimi seçimi
+STR_MEASURING_UNITS :{BLACK}Ölçü Birimleri
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Ölçü birimi seçimi
+STR_02E6_ROAD_VEHICLES :{BLACK}Karayolu taşıtları
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Trafik akış yönünü seçin
+STR_02E9_DRIVE_ON_LEFT :Soldan gidiÅŸli
+STR_02EA_DRIVE_ON_RIGHT :SaÄŸdan gidiÅŸli
+STR_02EB_TOWN_NAMES :{BLACK}Åžehir isimleri
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Şehir isimleri stilini seçin
+
+STR_02F4_AUTOSAVE :{BLACK}Otokaydet
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Otokaydetme aralığını seçin
+STR_02F7_OFF :Kapalı
+STR_02F8_EVERY_3_MONTHS :3 ay
+STR_02F9_EVERY_6_MONTHS :6 ay
+STR_02FA_EVERY_12_MONTHS :12 ay
+STR_02FB_START_A_NEW_GAME :{BLACK}Yeni oyuna baÅŸla
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Oyun yükle
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Kendi dünyani/senoryonu yap
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Tek kişilik bir oyun seçin
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}2-8 oyunculu bir oyun seçin
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Seçenekleri göster
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Zorluk ayarlarını göster
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Özel bir senaryo kullanarak yeni oyun başlat
+STR_0304_QUIT :{BLACK}Çıkış
+STR_0305_QUIT_OPENTTD :{BLACK}'OpenTTD' den çık
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...sadece şehirde yapılabilir
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}'ılıman' yer stilini seç
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}'soğuk' yer stilini seç
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}'tropik' yer stilini seç
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}'oyuncak' yer stilini seç
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Yeni bir fabrika aç
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Fabrika Listesi
+STR_0313_FUND_NEW_INDUSTRY :Yeni fabrika aç
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Yeni fabrika aç
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...sadece şehirlere yapılabilir
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...sadece yağmur ormanlarına yapılabilir
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...sadece çöllere yapılabilir
+STR_0319_PAUSED :{YELLOW}* * DURAKLATILDI * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Ekran görüntüsü '{STRING}' olarak kaydedildi
+STR_031C_SCREENSHOT_FAILED :{WHITE}Ekran görüntüsü alınamadı!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Gelecek için arazi al
+STR_032F_AUTOSAVE :{RED}OTOKAYDET
+STR_SAVING_GAME :{RED}* * KAYDEDiYOR * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}Kayıt işlemi sürüyor,{}lütfen bitene kadar bekleyin!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}'Ezy Sokagi stili muzik' programını seç
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :Ä°ngilizce (Orjinal)
+STR_TOWNNAME_FRENCH :Fransizca
+STR_TOWNNAME_GERMAN :Almanca
+STR_TOWNNAME_ADDITIONAL_ENGLISH :Ä°ngilizce (Modifiye)
+STR_TOWNNAME_LATIN_AMERICAN :Latin-Amerikanca
+STR_TOWNNAME_SILLY :Saçma İngilizce
+STR_TOWNNAME_SWEDISH :İsveççe
+STR_TOWNNAME_DUTCH :Hollandaca
+STR_TOWNNAME_FINNISH :Fince
+STR_TOWNNAME_POLISH :Polonca
+STR_TOWNNAME_SLOVAKISH :Slovakça
+STR_TOWNNAME_NORWEGIAN :Norveççe
+STR_TOWNNAME_HUNGARIAN :Macarca
+STR_TOWNNAME_AUSTRIAN :Avusturyaca
+STR_TOWNNAME_ROMANIAN :Romanca
+STR_TOWNNAME_CZECH :Çekçe
+STR_TOWNNAME_SWISS :İsviçrece
+STR_TOWNNAME_DANISH :Danimarkaca
+STR_TOWNNAME_TURKISH :Türkçe
+STR_TOWNNAME_ITALIAN :Italyanca
+STR_TOWNNAME_CATALAN :Katalanca
+############ end of townname region
+
+STR_CURR_GBP :Sterlin (£)
+STR_CURR_USD :Dolar ($)
+STR_CURR_EUR :Euro (€)
+STR_CURR_YEN :Yen (Â¥)
+STR_CURR_ATS :Avusturya Åžilini (ATS)
+STR_CURR_BEF :Belcika Frangı (BEF)
+STR_CURR_CHF :İsviçre Frangı (CHF)
+STR_CURR_CZK :Çek Koruna (CZK)
+STR_CURR_DEM :Alman markı (DEM)
+STR_CURR_DKK :Danimarka Kronu (DKK)
+STR_CURR_ESP :Peseta (ESP)
+STR_CURR_FIM :Fin Markka (FIM)
+STR_CURR_FRF :Frank (FRF)
+STR_CURR_GRD :Yunan Drachma (GRD)
+STR_CURR_HUF :Macar Forinti (HUF)
+STR_CURR_ISK :Iceland Kronasi (ISK)
+STR_CURR_ITL :Ä°talyan Lirasi (ITL)
+STR_CURR_NLG :Hollanda Guilder (NLG)
+STR_CURR_NOK :Norweç Krone (NOK)
+STR_CURR_PLN :Polon Zilotu (PLN)
+STR_CURR_ROL :Romanya Leusu (ROL)
+STR_CURR_RUR :Rus Rublesi (RUR)
+STR_CURR_SIT :Slovenya Toları (SIT)
+STR_CURR_SEK :İsveç Kronasi (SEK)
+STR_CURR_YTL :Türk Lirasi (YTL)
+STR_CURR_SKK :Slovak Korunasi (SKK)
+STR_CURR_BRR :Brezilya Reali (BRL)
+
+STR_CURR_CUSTOM :Özel...
+
+STR_OPTIONS_LANG :{BLACK}Dil
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Görünen dili seçin
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Tam ekran
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}Tam ekran oynamak için bunu isaretleyin
+
+STR_OPTIONS_RES :{BLACK}Ekran Çözünürlüğü
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Kullanılacak ekran çözünürlüğünü seçin
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Ekran görüntüsü biçimi
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Kullanılacak ekran görüntüsü biçimini seçin
+
+STR_AUTOSAVE_1_MONTH :Her ay
+STR_AUTOSAVE_FAILED :{WHITE}Otokayıt başarısız
+
+STR_MONTH_JAN :Ocak
+STR_MONTH_FEB :Subat
+STR_MONTH_MAR :Mart
+STR_MONTH_APR :Nisan
+STR_MONTH_MAY :Mayis
+STR_MONTH_JUN :Haziran
+STR_MONTH_JUL :Temmuz
+STR_MONTH_AUG :AÄŸustos
+STR_MONTH_SEP :Eylül
+STR_MONTH_OCT :Ekim
+STR_MONTH_NOV :Kasım
+STR_MONTH_DEC :Aralik
+
+STR_HEADING_FOR_STATION :{LTBLUE}Gidiyor {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}Gidiyor {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Talimat yok
+STR_NO_ORDERS_VEL :{LTBLUE}Talimat yok, {VELOCITY}
+
+STR_PASSENGERS :yolcu
+STR_BAGS :çanta
+STR_TONS :ton
+STR_LITERS :litre
+STR_ITEMS :tane
+STR_CRATES :kasa
+STR_RES_OTHER :diÄŸer
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Talimat listesi paylasilamiyor...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Talimat listesi kopyalanamiyor...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - Paylaşılmış talimat sonu - -
+
+STR_TRAIN_IS_LOST :{WHITE}Train {COMMA} yolunu bulamıyor.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}Train {COMMA} aracının geçen seneki kârı {CURRENCY}
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}Avrupa Birliği Karar Aldı!{}{}Artık ülkemizde para birimi olarak Euro kullanılacak!
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Train {COMMA} çok az talimat almış
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}Train {COMMA} geçersiz bir talimat almış
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}Train {COMMA} çifte talimat almış
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}Train {COMMA} talimatlarında geçersiz bir istasyon adı var
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}Araba {COMMA} çok az talimat almış
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}Araba {COMMA} geçersiz bir talimat almış
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}Araba {COMMA} çifte talimat almış
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}Araba {COMMA} talimatlarında geçersiz bir istasyon adı var
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}Ship {COMMA} çok az talimat almış
+STR_SHIP_HAS_VOID_ORDER :{WHITE}Ship {COMMA} geçersiz bir talimat almış
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}Ship {COMMA} çifte talimat almış
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}Ship {COMMA} talimatlarında geçersiz bir istasyon adı var
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}Aircraft {COMMA} çok az talimat almış
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}Aircraft {COMMA} geçersiz bir talimat almış
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}Aircraft {COMMA} çifte talimat almış
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}Aircraft {COMMA} talimatlarında geçersiz bir istasyon adı var
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}Åžu tren yenilenemedi: {COMMA} (para yetmedi)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}Şu taşıt yenilenemedi: {COMMA} (para yetmedi)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}Åžu gemi yenilenemedi: {COMMA} (para yetmedi)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}Şu uçak yenilenemedi: {COMMA} (para yetmedi)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}Tren {COMMA} değiştirildikten sonra uzadı
+
+STR_CONFIG_PATCHES :{BLACK}Yamaları Düzenle
+STR_CONFIG_PATCHES_TIP :{BLACK}Yamaları Düzenle
+STR_CONFIG_PATCHES_CAPTION :{WHITE}Yamaları Düzenle
+
+STR_CONFIG_PATCHES_OFF :Kapalı
+STR_CONFIG_PATCHES_ON :Açık
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Durum çubuğunda arabanın hızını göster: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Sahile ve eÄŸimli araziye inÅŸaat: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Daha gerçekçi kapsama alanı: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Şehrin yollarını, köprülerini yıkma izinli: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Çok uzun trenlere izin ver: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Gerçekçi tren hızlanması: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Tren ve gemilerin 90 derece dönmesini yasakla: {ORANGE}{STRING} {LTBLUE} (NPF gerektirir)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Yan yana yapılan tren istasyonlarını birleştir: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}'tam doldur' etkinse istasyonu tam dolunca terket: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Geliştirilmiş yükleme algoritması kullan: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GRADUAL_LOADING :{LTBLUE}Araçlar yavaş yavaş dolsun: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Enflasyon: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Sadece istek varsa kargo kabul edilsin: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Çok uzun köprülere izin ver: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Garaja git talimati etkin: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Hammadde üreten tesisleri açmak izinli: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Bir şehirde birden fazla aynı fabrika olması izinli: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Aynı tür fabrikalar yan yana yapılabilir: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Durum çubuğunda uzun tarih göster: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Sinyalizasyon sürüş yönünde olsun: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Sene sonunda ekonomik durumu göster: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}TTDPatch uyumlu ekspress trenler: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Karayolu taşıtları kuyruğa girsin (içiçe geçerek): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Fare kenardayken pencere etkin: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Belediye rüşveti izinli: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Özel istasyonlar: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Yeni evrensel yol bulma (NPF, NTP üzerinde): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FREIGHT_TRAINS :{LTBLUE}Ağır yük trenleri için ağırlık çarpanı: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Küçük havalimanı her zaman etkin: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Tren kaybolunca uyar: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Arac talimatlarını önizle: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :hayır
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :evet, ama durmuş araçlar hariç
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :tüm araçlar için
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Tren para kaybediyorsa uyar: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Eski araçlar sürekli üretilsin: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Araç eskiyince otomatik olarak yenile
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Araç ömrüne su kadar ay yaklaşınca yenile: {ORANGE}{STRING}{LTBLUE}
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Yenileme icin gerekli en az parayı otomatik yenile: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Hata mesajı görünme süresi: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Şehir nüfusunu isminin yanına yaz: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Görünmez ağaçlar (şeffaf binalarla): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Arazi üretici: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :Özgün
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis
+STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}Petrol Rafinerilerinin kenardan mak. uzaklığı{ORANGE}{STRING}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Kar kalınlığı: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN :{LTBLUE}Arazinin engebesi (sadece TerraGenesis) : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Dümdüz
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH :Düzgün
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH :Engebeli
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :Çok Engebeli
+STR_CONFIG_PATCHES_TREE_PLACER :{LTBLUE}Ağaç üretme algoritmasi: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TREE_PLACER_NONE :Hiçbiri
+STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL :Özgün
+STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED :GeliÅŸmiÅŸ
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION :{LTBLUE}Yükseklik haritasını döndür: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Saat yönünün tersi
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE :Saat yönü
+STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT :{LTBLUE}Düzlük bir senaryonun yükseklik seviyesi: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}İstasyon genişleme sınırı: {ORANGE}{STRING} {RED}Uyarı: Yüksek değerler oyunu yavaşlatır
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Helikopterler helipadlerde otomatik servise girsin: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Arazi araç çubuğunu diğer araç çubuklarına bağla: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Fareyle kaydırma hareketini ters çevir: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}İnşa araçları kullanılırken ölçüm ipucu göster: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Şirketin renklerini göster: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES_NONE :Hiçbiri
+STR_CONFIG_PATCHES_LIVERIES_OWN :Åžirketi al
+STR_CONFIG_PATCHES_LIVERIES_ALL :Tüm şirketler
+STR_CONFIG_PATCHES_PREFER_TEAMCHAT :{LTBLUE}<ENTER> tuşu takım içi sohbette kullanılsın: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Her oyuncu için en fazla tren: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Her oyuncu için en fazla araba: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}Her oyuncu için en fazla uçak: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}Her oyuncu için en fazla gemi: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Bilgisayar tren kullanmasın: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Bilgisayar araba kullanmasın: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Bilgisayar uçak kullanmasın: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Bilgisayar gemi kullanmasın: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Yeni yapay zekâ etkin (alfa): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Çok oyunculuda yapay zekâ olsun (denemede): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Trenler için varsayılan servis gecikmesi: {ORANGE}{STRING} gün/%
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Trenler için varsayılan servis gecikmesi: {ORANGE}kapalı
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Arabalar için varsayılan servis gecikmesi:: {ORANGE}{STRING} gün/%
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Arabalar için varsayılan servis gecikmesi:: {ORANGE}kapalı
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Uçaklar için varsayılan servis gecikmesi: {ORANGE}{STRING} gün/%
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Uçaklar için varsayılan servis gecikmesi: {ORANGE}kapalı
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Gemiler için varsayılan servis gecikmesi: {ORANGE}{STRING} gün/%
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Gemiler için varsayılan servis gecikmesi: {ORANGE}kapalı
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Bozulmalar kapalıysa sevisler kapalı olsun: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Vagonların treni yavaşlatması izinli: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}Elektrikli rayları iptal et: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Renkli gazete şu senede çıksın: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Başlangıç tarihi: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}BitiÅŸ tarihi: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Yüzeysel ekonomi (daha çok ve küçük çapta değişiklikler)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Diğer şirketlerin hisseleri alınabilsin
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Sürüklerken her: {ORANGE}{STRING} karede bir sinyal koy
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Ana araç çubuğu pozisyonu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Sol
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Orta
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :SaÄŸ
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Pencere yapışma yarıçapı: {ORANGE}{STRING} piksel
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Pencere yapışma yarıçapı: {ORANGE}kapalı
+
+STR_CONFIG_PATCHES_GUI :{BLACK}Arayüz
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Ä°nÅŸaat
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Araçlar
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Ä°stasyonlar
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Ekonomi
+STR_CONFIG_PATCHES_AI :{BLACK}Rakipler
+
+STR_CONFIG_PATCHES_DISABLED :kapalı
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Ayar deÄŸerini deÄŸiÅŸtir
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Bazi servis gecikmeleri aralık dışında: %5-%90 veya 30-800 gün arasında olmalı
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}Gemiler için YAPF kullan: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}Arabalar için YAPF kullan: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}Trenler için YAPF kullan: {ORANGE}{STRING}
+
+STR_TEMPERATE_LANDSCAPE :Ilıman iklim
+STR_SUB_ARCTIC_LANDSCAPE :SoÄŸuk iklim
+STR_SUB_TROPICAL_LANDSCAPE :Tropik iklim
+STR_TOYLAND_LANDSCAPE :Oyun bahçesi
+
+STR_CHEATS :{WHITE}Hileler
+STR_CHEATS_TIP :{BLACK}Onay kutuları bu hilenin daha önce kullanılıp kullanmadığını bildirir.
+STR_CHEATS_WARNING :{BLACK}Uyarı! Rakiplerine ihanet etmek üzeresin. Böyle bir davranışı sonsuza dek unutmayacaklarını akılda tut.
+STR_CHEAT_MONEY :{LTBLUE}Parayı {CURRENCY64} kadar arttır
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Oyuncunun yerine geçme: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Sihirli buldözer (normalde silinemeyen binaları siler): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Tüneller kesişebilir: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Duraklama zamanında inşaat yap: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Jetler kücük havalimanlarında düşmesin: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Ä°klimi deÄŸiÅŸtir: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Tarihi deÄŸiÅŸtir: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}Ãœretim deÄŸerlerini deÄŸiÅŸtir: {ORANGE}{STRING}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}Gidiyor -> {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Gidiyor -> {WAYPOINT}, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :{WAYPOINT} üzerinden git
+STR_GO_NON_STOP_TO_WAYPOINT :{WAYPOINT} üzerinden durmaksızın git
+
+STR_WAYPOINTNAME_CITY :Yerimi {TOWN}
+STR_WAYPOINTNAME_CITY_SERIAL :Yerimi {TOWN} #{COMMA}
+STR_LANDINFO_WAYPOINT :Yerimi
+
+STR_WAYPOINT :{WHITE}Yerimi
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Yerimi türü seç
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}Yerimi adını değiştir
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Yerimi adı değiştirilemedi...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Rayı yerimine çevir
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Buraya tren yerimi yapılamaz...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Tren yerimi kaldırılamaz...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Otoray modunda ray yap
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}...Bu senaryoda hiç şehir yok
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}Arazinin rasgele düzenlenmesini istediğinizden emin misiniz?
+STR_MANY_RANDOM_TOWNS :{BLACK}Birçok rastgele şehir
+STR_RANDOM_TOWNS_TIP :{BLACK}Haritayı rastgele şehirlerle doldur
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Birçok rastgele fabrika
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Haritayı rastgele fabrikalarla doldur
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Fabrika yapılamıyor...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Arazi düzenleme araç çubuğunu aç (ağaç dikme, alçaltma/yükseltme vb. için).
+STR_LANDSCAPING_TOOLBAR :{WHITE}Arazi düzenleme
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Düzleştir
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Rastgele türde ağaçlar
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}Rastgele türde ağaçlar koy
+
+STR_CANT_BUILD_CANALS :{WHITE}Buraya kanal yapılamaz...
+STR_BUILD_CANALS_TIP :{BLACK}Kanal Yap
+STR_LANDINFO_CANAL :Kanal
+
+STR_CANT_BUILD_LOCKS :{WHITE}Buraya kilit yapılamaz...
+STR_BUILD_LOCKS_TIP :{BLACK}Kilit yap
+STR_LANDINFO_LOCK :Kilit
+
+STR_BUOY_IS_IN_USE :{WHITE}...samandıra kullanımda!
+
+STR_LANDINFO_COORDS :{BLACK}Koordinatlar: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}İstasyonun parçasi kaldırılamaz...
+STR_CANT_CONVERT_RAIL :{WHITE}Ray türü değiştirilemiyor...
+STR_CONVERT_RAIL_TIP :{BLACK}Ray türünü dönüştür/geliştir
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Trenin hepsini satmak için lokomotifi buraya sürükle
+
+STR_DRAG_DROP :{BLACK}Sürükle Bırak
+STR_STATION_DRAG_DROP :{BLACK}Sürükle bırak tekniğiyle istasyon kur
+STR_SELECT_STATION_CLASS_TIP :{BLACK}Görüntülenecek istasyon türünü seçin
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Yapılacak istasyon türünü seçin
+
+STR_FAST_FORWARD :{BLACK}Oyunu hızlandır
+STR_MESSAGE_HISTORY :{WHITE}Mesaj Geçmişi
+STR_MESSAGE_HISTORY_TIP :{BLACK}En son haberlerin özetleri
+STR_MESSAGES_DISABLE_ALL :{BLACK}Hepsini kapa
+STR_MESSAGES_ENABLE_ALL :{BLACK}Hepsini aç
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Kömür Madeni Aç
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Orman Kur
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Petrol Kuyusu Aç (denizde)
+STR_CONSTRUCT_FARM_TIP :{BLACK}Çiftlik işlet
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Bakır Madeni Aç
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Petrol Kuyusu aç
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Altın Madeni Aç
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Elmas Madeni Aç
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Demir Madeni Aç
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Meyve Bahçesi Aç
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Kauçuk Bahçesi Yap
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Su Kaynağı islet
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Pamukhelvasi Ormanı Kur
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}Pil Çiftliği Kur
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Kola Kuyusu Aç
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Plastik Fıskiyesi Kur
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Balon Yapıcı Kur
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Bonbon Madeni Kur
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Åžeker Madeni Kur
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Fabrikalar
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} (%{COMMA} tasindi)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} (%{COMMA}/%{COMMA} tasindi)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}...başka bir fabrikaya çok yakın
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Treni başka bir kargo taşıması için modifiye et
+STR_RAIL_REFIT_VEHICLE :{BLACK}Modifiye
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Trenin taşıyacağı kargo türünü seçin
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Treni seçilen kargoyu taşıyacak şekilde modifiye et
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Modifiye edilemiyor...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Servis gecikmeleri yüzde ile: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Ãœretimi deÄŸiÅŸtir
+
+TEMP_AI_IN_PROGRESS :{WHITE}Yeni yapay zekaya hoş geldiniz, henüz devam etmekte olan bir iş. Mutlaka sorunlar yaşayacaksınız. İlginç bir şey görürseniz fotosunu foruma göndermeyi unutmayın. Hadi iyi oyunlar!
+TEMP_AI_ACTIVATED :{WHITE}Uyarı: Yeni yapay zeka henüz alfa sürümünde! Şu an sadece kamyonlar ve otobüsler çalışabilir!
+TEMP_AI_MULTIPLAYER :{WHITE}Uyarı: Bu özellik henüz deneme aşamasındadır. Lütfen ilgili sorunlarınızı truelight@openttd.org adresine bildirin.
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Çok Oyunculu
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Oyuncu adı:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}Oyuncuların görecegi adınızı seçin
+STR_NETWORK_CONNECTION :{BLACK}Bağlantı:
+STR_NETWORK_CONNECTION_TIP :{BLACK}İnternet ya da yerel ağ bağlantısı (LAN) oyunundan birini seçin
+
+STR_NETWORK_START_SERVER :{BLACK}Sunucu baÅŸlat
+STR_NETWORK_START_SERVER_TIP :{BLACK}Kendi sunucunu baÅŸlat
+
+STR_NETWORK_GAME_NAME :{BLACK}Ä°sim
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Oyunun ismi
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Dil, sunucu sürümü, vb.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Seçmek için listeden bir oyun tıklayın
+
+STR_NETWORK_FIND_SERVER :{BLACK}Sunucu bul
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Sunucu bulmak için bir agi ara
+STR_NETWORK_ADD_SERVER :{BLACK}Sunucu ekle
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Her zaman çalışan oyunlarına bakabilmek için bir sunucu ekle.
+STR_NETWORK_ENTER_IP :{BLACK}Sunucunun ip'sini ve portunu girin
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Oyuncular
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Bağlı oyuncular / en fazla oyuncu
+STR_NETWORK_GAME_INFO :{SILVER}OYUN BÄ°LGÄ°SÄ°
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Ä°stemciler: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Dil: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Set: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Harita boyutu: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}Sunucu sürümü: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}Sunucu adresi: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}BaÅŸlama tarihi: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Åžimdiki tarih: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Şifre korumalı!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}SUNUCU KAPALI
+STR_NETWORK_SERVER_FULL :{SILVER}SUNUCU DOLU
+STR_NETWORK_VERSION_MISMATCH :{SILVER}SÃœRÃœM UYUÅžMAZLIÄžI
+STR_NETWORK_GRF_MISMATCH :{SILVER}NEWGRF UYUÅžMAZLIÄžI
+
+STR_NETWORK_JOIN_GAME :{BLACK}Oyuna gir
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}Yeni çok oyunculu oyun başlat
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Oyun adı:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}Bu oyun adı diğer oyuncuların server listesinde görünecek
+STR_NETWORK_SET_PASSWORD :{BLACK}Parola koy
+STR_NETWORK_PASSWORD_TIP :{BLACK}Erişimi kısıtlamak için oyuna parola koy
+STR_NETWORK_SELECT_MAP :{BLACK}Harita seç:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}Hangi haritada oynamak istiyorsun?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}Ä°zin verilen en fazla oyuncu:
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}İzin verilen en fazla oyuncu sayısını seç. Her yerin dolması gerekmez
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :LAN
+STR_NETWORK_INTERNET :Ä°nternet
+STR_NETWORK_LAN_INTERNET :LAN / internet
+STR_NETWORK_INTERNET_ADVERTISE :Ä°nternet (reklam vererek)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 oyuncu
+STR_NETWORK_1_PLAYERS :1 oyuncu
+STR_NETWORK_2_PLAYERS :2 oyuncu
+STR_NETWORK_3_PLAYERS :3 oyuncu
+STR_NETWORK_4_PLAYERS :4 oyuncu
+STR_NETWORK_5_PLAYERS :5 oyuncu
+STR_NETWORK_6_PLAYERS :6 oyuncu
+STR_NETWORK_7_PLAYERS :7 oyuncu
+STR_NETWORK_8_PLAYERS :8 oyuncu
+STR_NETWORK_9_PLAYERS :9 oyuncu
+STR_NETWORK_10_PLAYERS :10 oyuncu
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}En fazla ÅŸirket:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Sunucudaki şirket sayısını sınırla
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}En fazla izleyici:
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Sunucudaki izleyici sayısını sınırla
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}KonuÅŸulan dil:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Diğer oyuncular sunucuda hangi dilin konuşulacağını bilecek
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}Oyunu BaÅŸlat
+STR_NETWORK_START_GAME_TIP :{BLACK}Rastgele harita ya da senaryoda network oyunu aç
+STR_NETWORK_LOAD_GAME :{BLACK}Oyun Yükle
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Kayıtlı oyunu devam ettir (doğru oyuncu olarak bağlandığından emin ol)
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Farketmez
+STR_NETWORK_LANG_ENGLISH :Ä°ngilizce
+STR_NETWORK_LANG_GERMAN :Almanca
+STR_NETWORK_LANG_FRENCH :Fransızca
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Çok oyunculu oyun lobisi
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Katılmaya hazırlanıyor: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}Oyundaki tüm şirketlerin listesi. Birine katılabilir ya da boş yer varsa yeni bir tane açabilirsiniz
+STR_NETWORK_NEW_COMPANY :{BLACK}Yeni ÅŸirket
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Yeni bir ÅŸirket kur
+STR_NETWORK_SPECTATE_GAME :{BLACK}Oyunu izle
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Oyuna izlemek için katıl
+STR_NETWORK_JOIN_COMPANY :{BLACK}Åžirkete Katil
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Şirket yönetimine yardım et
+STR_NETWORK_REFRESH :{BLACK}Sunucuyu tazele
+STR_NETWORK_REFRESH_TIP :{BLACK}Sunucu bilgisini tazele
+
+STR_NETWORK_COMPANY_INFO :{SILVER}ŞİRKET BİLGİSİ
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Şirket adı: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}Kurulus: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}Åžirket deÄŸeri: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Åžimdiki dengesi: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Geçen seneki geliri: {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}Performans: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}Araçlar: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Ä°stasyon: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Oyuncular: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}Bağlanıyor...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) Bağlanıyor..
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Onaylanıyor..
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Bekliyor..
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Harita indiriliyor..
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Veriler iÅŸleniyor..
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) Kaydolunuyor..
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Oyun bilgisi aliniyor..
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Åžirket bilgisi aliniyor..
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} -> önünde olan oyuncular
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} KB indirildi
+
+STR_NETWORK_DISCONNECT :{BLACK}Bağlantıyı kes
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Vereceğiniz para miktarını girin
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Sunucu korumalı. Parola girin
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Şirket korumalı. Parola girin
+STR_NETWORK_CLIENT_LIST :{WHITE}Oyuncu listesi
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE} Network aygıtı bulunamadı veya ENABLE_NETWORK olmadan derlendi
+STR_NETWORK_ERR_NOSERVER :{WHITE} Network oyunu bulunamadı
+STR_NETWORK_ERR_NOCONNECTION :{WHITE} Sunucu isteÄŸe cevap vermedi
+STR_NETWORK_ERR_DESYNC :{WHITE} Network-Oyunu senkronizasyonu başarısız
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} Network-Oyunu bağlatısı düştü
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} Kayıtlı oyun yüklenemedi
+STR_NETWORK_ERR_SERVER_START :{WHITE} Sunucu başlatılamadı
+STR_NETWORK_ERR_CLIENT_START :{WHITE} Bağlanamadı
+STR_NETWORK_ERR_TIMEOUT :{WHITE} Bağlantı #{NUM} zaman aşımına uğradı
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE} Protokol hatası yapıldı ve bağlantı koparıldı
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE} Bu istemcinin düzeltmesi sunucununkiyle aynı değil
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} Yanlış parola
+STR_NETWORK_ERR_SERVER_FULL :{WHITE} Sunucu dolu
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} Sunucuya girmeniz yasaklandı
+STR_NETWORK_ERR_KICKED :{WHITE} Oyundan atıldınız
+STR_NETWORK_ERR_CHEATER :{WHITE} Bu sunucuda hileler kapalı
+
+STR_NETWORK_ERR_LEFT :oyundan çıktı
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :genel hata
+STR_NETWORK_ERR_CLIENT_DESYNC :desync hatası
+STR_NETWORK_ERR_CLIENT_SAVEGAME :harita yüklenemiyor
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :bağlantı kaybedildi
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :protokol hatası
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :izin Verilmedi
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :ilginç paket alındı
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :yanlış düzeltme
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :isim kullanımda
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :yanlış oyun-parola
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :DoCommand'da yanlış oyuncu bilgisi
+STR_NETWORK_ERR_CLIENT_KICKED :sunucu tarafından atıldı
+STR_NETWORK_ERR_CLIENT_CHEATER :hile yapmaya çalıştı
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :sunucu dolu
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :oyuna katıldı
+STR_NETWORK_GIVE_MONEY :sana para verdi ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :para gönderildi: {STRING} <-- ({CURRENCY})
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Takım] :
+STR_NETWORK_CHAT_COMPANY :[Takım] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Takım] -> {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[Özel] :
+STR_NETWORK_CHAT_CLIENT :[Özel] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[Özel] -> {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[Herkes] :
+STR_NETWORK_CHAT_ALL :[Herkes] {STRING}: {GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :ismini deÄŸiÅŸtirdi:
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE} Sunucu kapandı
+STR_NETWORK_SERVER_REBOOT :{WHITE} Sunucu baştan başlatılıyor...{}Lütfen bekleyin...
+
+STR_NETWORK_SERVER :Sunucu
+STR_NETWORK_CLIENT :Ä°stemci
+STR_NETWORK_SPECTATORS :Ä°zleyiciler
+
+STR_NETWORK_CLIENTLIST_NONE :(yok)
+STR_NETWORK_CLIENTLIST_KICK :At
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Para ver
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Herkesle konuÅŸ
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Åžirketle konuÅŸ
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Özel mesaj
+
+
+STR_NETWORK_SEND :{BLACK}Gönder
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}Haritanın genişliği: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Haritanın yuksekliği: {ORANGE}{STRING}
+
+
+##### PNG-MAP-Loader
+
+STR_PNGMAP_ERROR :{WHITE}PNG'den yükseklik haritası yüklenemedi...
+STR_PNGMAP_ERR_FILE_NOT_FOUND :{WHITE}...dosya bulunamadı.
+STR_PNGMAP_ERR_IMAGE_TYPE :{WHITE}...resim türü işlenemiyor. 8 veya 24-bit PNG resmi gerekli.
+STR_PNGMAP_ERR_MISC :{WHITE}...yanlış bir şeyler oldu. (dosya bozuk olabilir)
+
+STR_BMPMAP_ERROR :{WHITE}arazi BMP'den yüklenemedi...
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}...resim türü çevrilemedi.
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Gider: {CURRENCY}
+STR_0801_COST :{RED}Gider: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Gelir: {CURRENCY}
+STR_0803_INCOME :{GREEN}Gelir: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Gönder: {CURRENCY}
+STR_FEEDER :{YELLOW}Gönder: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Beklenen Gider: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Beklenen Gelir: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Burası yükseltilemez...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Burası alçaltılamaz...
+STR_080A_ROCKS :Kayalar
+STR_080B_ROUGH_LAND :Engebeli arazi
+STR_080C_BARE_LAND :Çıplak arazi
+STR_080D_GRASS :Otlak
+STR_080E_FIELDS :Mera
+STR_080F_SNOW_COVERED_LAND :Karlı arazi
+STR_0810_DESERT :Çöl
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Arazi meyilli
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Ä°mkansiz ray birleÅŸimi
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}Kazı tünele hasar verebilir
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Zaten deniz seviyesinde
+STR_1004_TOO_HIGH :{WHITE}Çok yüksek
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Uygun ray yok
+STR_1007_ALREADY_BUILT :{WHITE}...zaten yapıldı
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Önce ray kaldırılmalı
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Demiryolu Yapımı
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Elektrikli Ray Yapımı
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Monoray Yapımı
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}MagLev Yapımı
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Tren köprüsü seç
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Buraya tren garı yapılamıyor...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Buraya tren istasyonu yapılamıyor...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Buraya sinyal yapılamıyor...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Buraya ray yapılamıyor...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Ray kaldırılamıyor...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Sinyaller kaldırılamıyor...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Tren Garı Yönü
+STR_1015_RAILROAD_CONSTRUCTION :Demiryolu yapımı
+STR_TOOLB_ELRAIL_CONSTRUCTION :Elektrikli Ray Yapımı
+STR_1016_MONORAIL_CONSTRUCTION :Monoray yapımı
+STR_1017_MAGLEV_CONSTRUCTION :MagLev yapımı
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Ray yap
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Tren garı yap (tren yapımı ve bakımı için)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Tren istasyonu yap
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Demiryolu sinyali yap
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Demiryolu köprüsü yap
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Demiryolu tüneli yap
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Trenyolu yapımında sil/yap arasında geçiş
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Köprü seçimi - yapacağınız köprüyü seçin
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Tren garı yönünü seçin
+STR_1021_RAILROAD_TRACK :Ray
+STR_1023_RAILROAD_TRAIN_DEPOT :Tren garı
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...alan baÅŸka bir ÅŸirkete ait
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :Normal sinyalli ray
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :Ön-sinayalli ray
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :Çıkış-sinyalli ray
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :Ön+çikis-sinyalli ray
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Önce yol silinmeli
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Yol çalışmaları
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Yol Yapımı
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Köprü Seç
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Yol yapılamıyor...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Yol kaldırılamıyor...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Garaj Yönü
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Buraya Garaj yapılamaz...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Otobüs durağı yapılamaz...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Kamyon durağı yapılamaz...
+STR_180A_ROAD_CONSTRUCTION :Yol yapımı
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Yol bölmesi yap
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Garaj yap (araç alımı ve bakımlar için)
+STR_180D_BUILD_BUS_STATION :{BLACK}Otobüs durağı yap
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Kamyon yükleme bölgesi yap
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Köprü yap
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Tünel Yap
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Yol yap/sil arasında geçiş yap
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Garaj yönünü seç
+STR_1814_ROAD :Yol
+STR_1815_ROAD_WITH_STREETLIGHTS :Lambali yol
+STR_1816_TREE_LINED_ROAD :Ağaçli yol
+STR_1817_ROAD_VEHICLE_DEPOT :Araba garı
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :Hemzemin geçit
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Åžehirler
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Önce bina yıkılmalı
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}Nüfus: {ORANGE}{COMMA}{BLACK} Ev: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Ä°sim deÄŸiÅŸtir
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Ä°sim deÄŸiÅŸtirilemiyor...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} belediyesi izin vermiyor
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Şehir isimleri - şehre bakmak için ismine tıklayın
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Ana görüntüyü şehrin üzerine ortala
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Åžehrin ismini deÄŸiÅŸtir
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Geçen ayki yolcular: {ORANGE}{COMMA}{BLACK} mak: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Geçen ayki posta: {ORANGE}{COMMA}{BLACK} mak: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Yüksek ofis binasi
+STR_2010_OFFICE_BLOCK :Ofis binasi
+STR_2011_SMALL_BLOCK_OF_FLATS :Küçük apartman
+STR_2012_CHURCH :Kilise
+STR_2013_LARGE_OFFICE_BLOCK :GeniÅŸ ofis binasi
+STR_2014_TOWN_HOUSES :Evler
+STR_2015_HOTEL :Otel
+STR_2016_STATUE :Heykel
+STR_2017_FOUNTAIN :Fıskiye
+STR_2018_PARK :Park
+STR_2019_OFFICE_BLOCK :Ofis binasi
+STR_201A_SHOPS_AND_OFFICES :Dükkanlar ve ofisler
+STR_201B_MODERN_OFFICE_BUILDING :Modern ofis binasi
+STR_201C_WAREHOUSE :Depo
+STR_201D_OFFICE_BLOCK :Ofis binasi
+STR_201E_STADIUM :Stadyum
+STR_201F_OLD_HOUSES :Eski evler
+STR_2020_LOCAL_AUTHORITY :{BLACK}Belediye
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Belediye hakkında bilgi göster
+STR_2022_LOCAL_AUTHORITY :{WHITE}{TOWN} belediyesi
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Taşıma şirketi reytingleri:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Ä°haleler
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Beklenen ihaleler:
+STR_2027_FROM_TO :{ORANGE}{STRING} {STRING} -> {STRING}
+STR_2028_BY :{YELLOW} ({DATE_SHORT})
+STR_202A_NONE :{ORANGE}Yok
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Verilen ihaleler:
+STR_202C_FROM_TO :{ORANGE}{STRING} {STATION} -> {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}İhale zamanı doldu: {}{}{STRING} {STRING} -> {STRING} artık fazla gelir getirmeyecek.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}İhale geri çekildi:{}{}{STRING} servisi {STATION} -> {STATION} arasında fazla gelir getirmeyecek.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Servis ihalesi önerildi: {}{} ilk {STRING} servisi {STRING} -> {STRING} arasında belediyeden prim alacak!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}İhale {COMPANY} şirketine verildi!{}{}{STRING} servisi {STATION} -> {STATION} aralığında bir yıl boyunca %50 fazla gelir sağlayacak!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}İhale {COMPANY} şirketine verildi!{}{}{STRING} servisi {STATION} -> {STATION} aralığında bir yıl boyunca iki kat fazla gelir sağlayacak!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}İhale {COMPANY} şirketine verildi!{}{}{STRING} servisi {STATION} -> {STATION} aralığında bir yıl boyunca üç kat fazla gelir sağlayacak!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}İhale {COMPANY} şirketine verildi!{}{}{STRING} servisi {STATION} -> {STATION} aralığında bir yıl boyunca dört kat fazla gelir sağlayacak!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} belediyesi bu şehir için başka havalimanına izin vermiyor
+STR_2036_COTTAGES :Kulübe
+STR_2037_HOUSES :Evler
+STR_2038_FLATS :Apartman
+STR_2039_TALL_OFFICE_BLOCK :Yüksek ofis binasi
+STR_203A_SHOPS_AND_OFFICES :Dükkan ve ofisler
+STR_203B_SHOPS_AND_OFFICES :Dükkan ve ofisler
+STR_203C_THEATER :Tiyatro
+STR_203D_STADIUM :Stadyum
+STR_203E_OFFICES :Ofisler
+STR_203F_HOUSES :Evler
+STR_2040_CINEMA :Sinema
+STR_2041_SHOPPING_MALL :Alışveriş merkezi
+STR_2042_DO_IT :{BLACK}Yap
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}Bu şehirde yapılabileceklerin listesi - ayrıntılar için üzerine tıklayın
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Seçilen şeyi yap
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Yapılabilecekler:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Küçük reklam kampanyası
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Orta reklam kampanyası
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Büyük reklam kampanyası
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Yol tamirleri için para bağışla
+STR_204A_BUILD_STATUE_OF_COMPANY :Åžirket sahibinin heykelini dik
+STR_204B_FUND_NEW_BUILDINGS :Yeni binalar yapılması için para ver
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Ulaşım haklarını satın al
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Belediyeye rüşvet ver
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Müsteri çekmek için duvarlara poster yapıştır.{} Fiyat: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Müsteri çekmek için radyoya reklam ver.{} Fiyat: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Müsteri çekmek için televizyona reklam ver.{} Fiyat: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} Yol tamirleri için belediyeye bağış yap. 6 ay boyunca şehrin yolları kullanılamaz.{} Fiyat: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Şirket sahibinin heykelini dik.{} Fiyatı: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Şehirde ticari binaların yapımı için bağış yap.{} Fiyatı: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Bir yıllık nakliyat haklarını satın al. Belediye sadece senin şirkete izin verir.{} Fiyat: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Yakalanma riskini göze alarak belediyeye rüşvet ver.{} Fiyat: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK} {TOWN} şehrinde trafik durdu!{}{} {COMPANY} şirketinin yol yapım çalışmaları başladı!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (inÅŸa halinde)
+STR_2059_IGLOO :Eskimo Evi
+STR_205A_TEPEES :Çadır
+STR_205B_TEAPOT_HOUSE :Çaydanlık ev
+STR_205C_PIGGY_BANK :Domuz bankası
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN} {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Arazi
+STR_2800_PLANT_TREES :Ağaç dik
+STR_2801_PLACE_SIGN :Tabela dik
+STR_2802_TREES :{WHITE}Ağaçlar
+STR_2803_TREE_ALREADY_HERE :{WHITE}...burada zaten ağaç var
+STR_2804_SITE_UNSUITABLE :{WHITE}...yer uygun deÄŸil
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Buraya ağaç dikilemez...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...çok fazla tabela
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Buraya tabela konulamiyor...
+STR_280A_SIGN :Tabela
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Tabelayı değiştir
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Tabela adı değiştirilemiyor...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Dikilecek ağaç türünü seçin
+STR_280E_TREES :Ağaçlar
+STR_280F_RAINFOREST :Yağmur Ormanı
+STR_2810_CACTUS_PLANTS :Kaktüs Bitkileri
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Tren istasyonu Seçimi
+STR_3001_AIRPORT_SELECTION :{WHITE}Havalimanı seçimi
+STR_3002_ORIENTATION :{BLACK}Yön
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Ray sayısı
+STR_3004_PLATFORM_LENGTH :{BLACK}Platform uzunluÄŸu
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Başka tren istasyonuna çok yakın
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Birden fazla istasyona bitiÅŸik
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}Bu şehirde çok fazla istasyon var
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}Haritada çok fazla istasyon var
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Çok fazla durak var
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}Çok fazla kamyon yükleme yeri var
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Başka bir istasyona çok yakın
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Önce tren istasyonu yıkılmalı
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Başka bir havalimanına çok yakın
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Önce havalimanı yıkılmalı
+
+STR_3030_RENAME_STATION_LOADING :İstasyonu yeniden adlandır
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Ä°sim deÄŸiÅŸtirilemiyor...
+STR_3032_RATINGS :{BLACK}Reyting
+STR_3033_ACCEPTS :{BLACK}Ä°stenen
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}Yerel nakliyat reyitngleri:
+
+############ range for rating starts
+STR_3035_APPALLING :Berbat
+STR_3036_VERY_POOR :Çok kötü
+STR_3037_POOR :Kötü
+STR_3038_MEDIOCRE :Normal
+STR_3039_GOOD :Ä°yi
+STR_303A_VERY_GOOD :Çok iyi
+STR_303B_EXCELLENT :Harika
+STR_303C_OUTSTANDING :Mükemmel
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} artık {STRING} istemiyor
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} artık {STRING} ve {STRING} istemiyor
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} artık {STRING} istiyor
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} artık {STRING} ve {STRING} istiyor
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Otobüs Durağı Yönü
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Kamyon Durağı Yönü
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Önce otobüs durağı yıkılmalı
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Önce kamyon durağı yıkılmalı
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} istasyonları
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Yok -
+STR_304B_SITE_UNSUITABLE :{WHITE}...yer uygun deÄŸil
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Başka bir limana çok yakın
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Önce liman yıkılmalı
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Tren istasyonu yönünü seç
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Tren istasyonu için peron sayısı seç
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Tren istasyonu uzunluğu seç
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Otobüs durağı yönünü seç
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Kamyon durağı yönünü seç
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Durağın oldugu yere git
+STR_3054_SHOW_STATION_RATINGS :{BLACK}İstasyonun reytinglerini göster
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Ä°stasyonun ismini deÄŸiÅŸtir
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}İstenen kargoların listesini göster
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}İstasyon isimleri - gitmek için istasyon ismini tıklayın
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Havalimanı boyutunu seç
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :Tren istasyonu
+STR_305F_AIRCRAFT_HANGAR :Hangar
+STR_3060_AIRPORT :Havalimanı
+STR_3061_TRUCK_LOADING_AREA :Kamyon durağı
+STR_3062_BUS_STATION :Otobüs durağı
+STR_3063_SHIP_DOCK :Ä°skele
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Kapsama alanını göster
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Kapsama alanını gösterme
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Kapsama alanı
+STR_3068_DOCK :{WHITE}Ä°skele
+STR_3069_BUOY :Şamandıra
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...yolda şamandıra var
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...istasyon çok yayılmış
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...özel istasyon ayarı kapalı
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Birden fazla şey seçmek için CTRL'yi basılı tutun
+
+STR_UNDEFINED :(tanımlanmamış sözcük)
+STR_STAT_CLASS_DFLT :Varsayılan istasyon
+STR_STAT_CLASS_WAYP :Yerimleri
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Tersane Yönü
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...suya yapılmali
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Buraya tersane yapılamaz...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}İmalathane yönünü seç
+STR_3804_WATER :Su
+STR_3805_COAST_OR_RIVERBANK :Sahil veya göl kenarı
+STR_3806_SHIP_DEPOT :Tersane
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...Suya yapılamaz
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Kaydet
+STR_4001_LOAD_GAME :{WHITE}Yükle
+STR_4002_SAVE :{BLACK}Kaydet
+STR_4003_DELETE :{BLACK}Sil
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} MB bos
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Sürücü okunamıyor
+STR_4007_GAME_SAVE_FAILED :{WHITE}Oyun kaydedilemedi
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Dosya silinemedi
+STR_4009_GAME_LOAD_FAILED :{WHITE}Dosya yüklenemedi
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}Sürücü, klasör ve kayıtli oyun listesi
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Kaydetmek için kullanılacak dosya adı
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Seçili oyunu sil
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Oyunu seçilen isimle kaydet
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Yeni oyun türü seç
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Senaryo (yeşil), kurulu oyun (mavi) veya yeni oyun seç
+STR_4010_GENERATE_RANDOM_NEW_GAME :Rastgele haritada oyna
+STR_4011_LOAD_HEIGHTMAP :{WHITE}Yükseklik haritası yükle
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}yolda {STRING} var
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :Kömür Madeni
+STR_4803_POWER_STATION :Elektrik Santrali
+STR_4804_SAWMILL :Kerestecisi
+STR_4805_FOREST :Ormanı
+STR_4806_OIL_REFINERY :Petrol Rafinerisi
+STR_4807_OIL_RIG :Petrol Platformu
+STR_4808_FACTORY :Fabrikası
+STR_4809_PRINTING_WORKS :Basımevi
+STR_480A_STEEL_MILL :Çelik Fabrikası
+STR_480B_FARM :Çiftliği
+STR_480C_COPPER_ORE_MINE :Bakır Madeni
+STR_480D_OIL_WELLS :Petrol Kuyuları
+STR_480E_BANK :Bankası
+STR_480F_FOOD_PROCESSING_PLANT :Yemek Fabrikası
+STR_4810_PAPER_MILL :Kağıt Fabrikası
+STR_4811_GOLD_MINE :Altın Madeni
+STR_4812_BANK :Bankası
+STR_4813_DIAMOND_MINE :Elmas Madeni
+STR_4814_IRON_ORE_MINE :Demir Madeni
+STR_4815_FRUIT_PLANTATION :Meyve Bahçesi
+STR_4816_RUBBER_PLANTATION :Kauçuk Bahçesi
+STR_4817_WATER_SUPPLY :Su Kaynağı
+STR_4818_WATER_TOWER :Su Kulesi
+STR_4819_FACTORY :Fabrikası
+STR_481A_FARM :Çiftliği
+STR_481B_LUMBER_MILL :Oduncusu
+STR_481C_COTTON_CANDY_FOREST :Pamukhelva Ormanı
+STR_481D_CANDY_FACTORY :Tatlı Fabrikası
+STR_481E_BATTERY_FARM :Pil Çiftliği
+STR_481F_COLA_WELLS :Kola Kuyuları
+STR_4820_TOY_SHOP :Oyuncakçısı
+STR_4821_TOY_FACTORY :Oyuncak Fabrikası
+STR_4822_PLASTIC_FOUNTAINS :Plastik Fıskiyesi
+STR_4823_FIZZY_DRINK_FACTORY :İçecek Fabrikası
+STR_4824_BUBBLE_GENERATOR :Balon Yapıcısi
+STR_4825_TOFFEE_QUARRY :Bonbon Madeni
+STR_4826_SUGAR_MINE :Åžeker Madeni
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Ä°stenen: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Ä°stenenler: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Ä°stenenler: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Geçen ayki üretim:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} (%{COMMA} tasindi)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Fabrikaya git
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Yeni bir {STRING}, {TOWN} şehri yakınlarında kuruldu!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Yeni bir {STRING}, {TOWN} şehri yakınlarında kuruldu!
+STR_482F_COST :{BLACK}Fiyat: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Buraya bu fabrikadan yapılamaz...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...Orman sadece kar sınırı üzerinde olabilir
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} tükendi, kapaniyor!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}{INDUSTRY} kaynak sorunları yüzünden kapaniyor!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}Yakında ağaç olmadığı için {INDUSTRY} kapanıyor!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} üretimi arttırdi!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}{INDUSTRY}nde yeni kömür tabakasi bulundu!{} Üretimin ikiye katlanması bekleniyor!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}{INDUSTRY}nda yeni petrol rezervi bulundu!{} Üretimin ikiye katlanması bekleniyor!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}{INDUSTRY}ndeki yeni tarim tekniklerinin üretimi ikiye katlamasi bekleniyor!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}{INDUSTRY} üretimi %50 düşürdü
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}{INDUSTRY} bölgesine böcek sürüsü girdi !{} Üretim %50 düştü
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...sadece haritanin kenarlarına yapılabilir
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}{STRING} üretimi şurada arttı: {INDUSTRY} > %{COMMA}!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}{STRING} üretimi şurada düştü: {INDUSTRY} > %{COMMA}!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Tünelde tren var
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Tünelde taşıt var
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Yolda başka bir tünel var
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Tünelin diğer ucunda düzeltme yapılmasi gerekiyor
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Önce tünel yıkılmalı
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Önce köprü yıkılmalı
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Aynı noktada başlayıp bitemez
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Köprü altınin düz olması gerekiyor
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}Başlangıç ve bitiş aynı çizgi üzerinde olmalı
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Yer tünel girişi için uygun değil
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Çelik, Asma
+STR_500F_GIRDER_STEEL :Çelik, Kirişli
+STR_5010_CANTILEVER_STEEL :Çelik, Ağ
+STR_5011_SUSPENSION_CONCRETE :Beton, Asma
+STR_5012_WOODEN :Odun
+STR_5013_CONCRETE :Beton
+STR_5014_TUBULAR_STEEL :Çelik, Tüplü
+STR_BRIDGE_TUBULAR_SILICON :Silikon, Tüplü
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Buraya köprü yapılamaz...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Buraya tünel yapılamaz...
+STR_5017_RAILROAD_TUNNEL :Demiryolu Tüneli
+STR_5018_ROAD_TUNNEL :Karayolu Tüneli
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Çelik asma demiryolu köprüsü
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Çelik kirişli demiryolu köprüsü
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Çelik ağ demiryolu köprüsü
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Destekli beton asma demiryolu köprüsü
+STR_501F_WOODEN_RAIL_BRIDGE :Odun demiryolu köprüsü
+STR_5020_CONCRETE_RAIL_BRIDGE :Beton demiryolu köprüsü
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Çelik asma karayolu köprüsü
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Çelik kirişli karayolu köprüsü
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Çelik ağ karayolu köprüsü
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Destekli beton asma karayolu köprüsü
+STR_5025_WOODEN_ROAD_BRIDGE :Odun karayolu köprüsü
+STR_5026_CONCRETE_ROAD_BRIDGE :Beton karayolu köprüsü
+STR_5027_TUBULAR_RAIL_BRIDGE :Tüplü demiryolu köprüsü
+STR_5028_TUBULAR_ROAD_BRIDGE :Tüplü karayolu köprüsü
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Yolda birsey var
+STR_5801_TRANSMITTER :Verici
+STR_5802_LIGHTHOUSE :Fener
+STR_5803_COMPANY_HEADQUARTERS :Åžirket binasi
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...yolda ÅŸirket binasi var
+STR_5805_COMPANY_OWNED_LAND :Satın alınmış alan
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Burası satın alınamaz...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...zaten senin!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Ä°simsiz
+STR_SV_TRAIN_NAME :Tren {COMMA}
+STR_SV_ROADVEH_NAME :Araba {COMMA}
+STR_SV_SHIP_NAME :Gemi {COMMA}
+STR_SV_AIRCRAFT_NAME :Uçak {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :{STRING} Kuzey
+STR_SV_STNAME_SOUTH :{STRING} Güney
+STR_SV_STNAME_EAST :{STRING} DoÄŸu
+STR_SV_STNAME_WEST :{STRING} Batı
+STR_SV_STNAME_CENTRAL :{STRING} Merkez
+STR_SV_STNAME_TRANSFER :{STRING} Transfer
+STR_SV_STNAME_HALT :{STRING} Asağısı
+STR_SV_STNAME_VALLEY :{STRING} Vadisi
+STR_SV_STNAME_HEIGHTS :{STRING} Tepesi
+STR_SV_STNAME_WOODS :{STRING} KoruluÄŸu
+STR_SV_STNAME_LAKESIDE :{STRING} Gölü
+STR_SV_STNAME_EXCHANGE :{STRING} Santrali
+STR_SV_STNAME_AIRPORT :{STRING} Havalimanı
+STR_SV_STNAME_OILFIELD :{STRING} Kuyusu
+STR_SV_STNAME_MINES :{STRING} Madeni
+STR_SV_STNAME_DOCKS :{STRING} Ä°skelesi
+STR_SV_STNAME_BUOY_1 :{STRING} Şamandıra 1
+STR_SV_STNAME_BUOY_2 :{STRING} Şamandıra 2
+STR_SV_STNAME_BUOY_3 :{STRING} Şamandıra 3
+STR_SV_STNAME_BUOY_4 :{STRING} Şamandıra 4
+STR_SV_STNAME_BUOY_5 :{STRING} Şamandıra 5
+STR_SV_STNAME_BUOY_6 :{STRING} Şamandıra 6
+STR_SV_STNAME_BUOY_7 :{STRING} Şamandıra 7
+STR_SV_STNAME_BUOY_8 :{STRING} Şamandıra 8
+STR_SV_STNAME_BUOY_9 :{STRING} Şamandıra 9
+STR_SV_STNAME_ANNEXE :{STRING} Eklemesi
+STR_SV_STNAME_SIDINGS :{STRING} Kenarı
+STR_SV_STNAME_BRANCH :{STRING} Kolu
+STR_SV_STNAME_UPPER :Yukarı {STRING}
+STR_SV_STNAME_LOWER :Asağı {STRING}
+STR_SV_STNAME_HELIPORT :{STRING} Heliport
+STR_SV_STNAME_FOREST :{STRING} Ormanı
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Zorluk seviyesi
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Kaydet
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Kolay
+STR_6802_MEDIUM :{BLACK}Orta
+STR_6803_HARD :{BLACK}Zor
+STR_6804_CUSTOM :{BLACK}Özel
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}En fazla rakip: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Rakip başlangıcı: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}Åžehirler: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}Sanayi: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}En fazla kredi: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Başlangıç faizi: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Bakım ücretleri: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Rakip inşa hızı: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Rakip zekâsı: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Araç bozulmaları: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}İhale çarpanı: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}İnşa fiyatları: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Yer tipi: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Su miktarı: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Ekonomi: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Tren ters dönüşü: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Felaketler: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Belediyenin töleransi: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :Hiç
+STR_6816_LOW :Düşük
+STR_6817_NORMAL :Normal
+STR_6818_HIGH :Yüksek
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Çok Yavas
+STR_681C_SLOW :Yavas
+STR_681D_MEDIUM :Orta
+STR_681E_FAST :Hizli
+STR_681F_VERY_FAST :Çok Hizli
+STR_VERY_LOW :Çok Düşük
+STR_6820_LOW :Düşük
+STR_6821_MEDIUM :Orta
+STR_6822_HIGH :Yüksek
+STR_6823_NONE :Hiç
+STR_6824_REDUCED :Azaltılmış
+STR_6825_NORMAL :Normal
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Çok Düzgün
+STR_682B_FLAT :Düzgün
+STR_682C_HILLY :Tepeli
+STR_682D_MOUNTAINOUS :Dağlık
+STR_682E_STEADY :Durgun
+STR_682F_FLUCTUATING :DeÄŸiÅŸken
+STR_6830_IMMEDIATE :Hemen
+STR_6831_3_MONTHS_AFTER_PLAYER :3 ay sonra
+STR_6832_6_MONTHS_AFTER_PLAYER :6 ay sonra
+STR_6833_9_MONTHS_AFTER_PLAYER :9 ay sonra
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :Ray Sonunda ve Duraklarda
+STR_6835_AT_END_OF_LINE_ONLY :Sadece Ray Sonunda
+STR_6836_OFF :Kapalı
+STR_6837_ON :Açik
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Punaları Göster
+STR_6839_PERMISSIVE :Ä°zin verici
+STR_683A_TOLERANT :Töleransli
+STR_683B_HOSTILE :Katı
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Oyuncu {COMMA})
+STR_7004_NEW_FACE :{BLACK}Yeni Surat
+STR_7005_COLOR_SCHEME :{BLACK}Renkler
+STR_7006_COLOR_SCHEME :{GOLD}Renk:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Yeni Renk
+STR_7008_COMPANY_NAME :{BLACK}Åžirket ismi
+STR_7009_PRESIDENT_NAME :{BLACK}Müdür ismi
+STR_700A_COMPANY_NAME :Åžirketin ismi
+STR_700B_PRESIDENT_S_NAME :Yöneticinin ismi
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Åžirket ismi deÄŸiÅŸtirilemez...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Yönetici ismi degitirilemez...
+STR_700E_FINANCES :{WHITE}{COMPANY} Hesaplar {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Gider/Gelir
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Ä°nÅŸaat
+STR_7012_NEW_VEHICLES :{GOLD}Yeni araçlar
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Tren Bakımları
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Araba Bakımları
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Uçak Bakımları
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Gemi Bakımları
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}İnşaat bakımları
+STR_7018_TRAIN_INCOME :{GOLD}Tren Geliri
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Araba Geliri
+STR_701A_AIRCRAFT_INCOME :{GOLD}Uçak Geliri
+STR_701B_SHIP_INCOME :{GOLD}Gemi Geliri
+STR_701C_LOAN_INTEREST :{GOLD}Kredi Faizi
+STR_701D_OTHER :{GOLD}DiÄŸer
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Toplam:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Gelir GrafiÄŸi
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Çalıştirma Geliri Grafiği
+STR_7026_BANK_BALANCE :{WHITE}Banka Hesabı
+STR_7027_LOAN :{WHITE}Kredi
+STR_MAX_LOAN :{WHITE}Mak Kredi: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}Ödünç al {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Öde {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...maksimum kredi miktarı {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Daha fazla kredi alınamaz...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...ödenecek kredi yok
+STR_702E_REQUIRED :{WHITE}...{CURRENCY} gerekli
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Kredi ödenemiyor...
+STR_INSUFFICIENT_FUNDS :{WHITE}Bankadan ödünç alınan para verilemez...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Müdür için yeni surat seç
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Araç renklerini değiştir
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Müdürün ismini değiştir
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Åžirket ismini deÄŸiÅŸtir
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}İstediginiz rengi seçin
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Kredi ödünç al
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Krediyi öde
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(Manager)
+STR_7038_INAUGURATED :{GOLD}KuruluÅŸ: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Araçlar:
+STR_TRAINS :{WHITE}{COMMA} tren
+STR_ROAD_VEHICLES :{WHITE}{COMMA} araba
+STR_AIRCRAFT :{WHITE}{COMMA} uçak
+STR_SHIPS :{WHITE}{COMMA} gemi
+STR_7042_NONE :{WHITE}Yok
+STR_7043_FACE_SELECTION :{WHITE}Surat Seçimi
+STR_7044_MALE :{BLACK}Erkek
+STR_7045_FEMALE :{BLACK}Bayan
+STR_7046_NEW_FACE :{BLACK}Yeni Surat
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Seçimi iptal et
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Seçimi Kabul et
+STR_7049_SELECT_MALE_FACES :{BLACK}Erkek suratlarıni seç
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Bayan suratlarıni seç
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Rastgele surat yap
+STR_704C_KEY :{BLACK}Anahtar
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Grafik anahtarını göster
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Åžirket grafikleri anahtari
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Grafikte şirketi göstermek/gizlemek için tıkla
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Taşınan kargo
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Performans (en fazla=1000)
+STR_7052_COMPANY_VALUES :{WHITE}Åžirket DeÄŸerleri
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Åžirketler Ligi
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}Åžirket tehlikede!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY}, performansı artmazsa satılacak ya da yok olacak!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(Manager)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Åžirketler birleÅŸti!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY}, {COMPANY} tarafından {CURRENCY} fiyatıyla alındı!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Şirketimizi satın alacak birilerini arıyoruz.{}{} {COMPANY} şirketini şu fiyata almak ister misiniz: {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Ä°flas!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} iflas etti ve kapatıldı!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}Yeni ÅŸirket kuruldu!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY}, {TOWN} yakınlarında inşaata başladı!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Şirket satın alınamaz...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Kargo ödemeleri
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Taşıma süresi
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}20 karelik yolda 10 birim için ödeme (ya da 10,000 litre)
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Kargo türünü göster/gizle
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Mühendis
+STR_7067_TRAFFIC_MANAGER :Trafik Müdürü
+STR_7068_TRANSPORT_COORDINATOR :Nakliyeci
+STR_7069_ROUTE_SUPERVISOR :Rota Yöneticisi
+STR_706A_DIRECTOR :Yönetmen
+STR_706B_CHIEF_EXECUTIVE :Baş Yönetici
+STR_706C_CHAIRMAN :BaÅŸkan
+STR_706D_PRESIDENT :BaÅŸbakan
+STR_706E_TYCOON :Kodaman(Tycoon)
+STR_706F_BUILD_HQ :{BLACK}Bina Yap
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Åžirket binasi yap / ÅŸirket binasina bak
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Şirket değerinin %1'i karşılığında binanın yerini değiştir
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Şirket binasi yapılamaz...
+STR_7072_VIEW_HQ :{BLACK}Binaya Bak
+STR_RELOCATE_HQ :{BLACK}Binayı Taşı
+STR_COMPANY_PASSWORD :{BLACK}Parola
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Başkalarınin girmemesi için parola koy.
+STR_SET_COMPANY_PASSWORD :Şirket parolası
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}Dünyada Kriz!{}{}Çok büyük bir ekonomik kriz yaşanacağı öngörüldü!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Kriz Atlatıldı!{}{}Ekonomi yine eski güzel günlerine döndü!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Pencere boyutunu büyült/küçült
+STR_7076_COMPANY_VALUE :{GOLD}Åžirket deÄŸeri: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}%25'ini satın al
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}%25'ini geri ver
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Åžirketin %25 hissesini al
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Åžirketin %25 hissesini sat
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Şirketin %25'i alınamıyor...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}Şirketin %25'i satılamıyor...
+STR_707D_OWNED_BY :{WHITE}(%{COMMA} ortağı {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}(%{COMMA} ortağı {COMPANY}{} %{COMMA} ortağı {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY}, {COMPANY} tarafından alındı!
+STR_7080_PROTECTED :{WHITE}Bu ÅŸirket hisselerini satacak kadar eski deÄŸil...
+
+STR_LIVERY_DEFAULT :Åžirket Rengi
+STR_LIVERY_STEAM :Buharlı Lokomotif
+STR_LIVERY_DIESEL :Dizel Lokomotif
+STR_LIVERY_ELECTRIC :Elektrikli Lokomotif
+STR_LIVERY_MONORAIL :Monoray Lokomotifi
+STR_LIVERY_MAGLEV :Maglev Lokomotifi
+STR_LIVERY_DMU :DMU
+STR_LIVERY_EMU :EMU
+STR_LIVERY_PASSENGER_WAGON_STEAM :Tramvay (Buhar)
+STR_LIVERY_PASSENGER_WAGON_DIESEL :Tramvay (Dizel)
+STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Tramvay (Elektrik)
+STR_LIVERY_FREIGHT_WAGON :Yük Vagonu
+STR_LIVERY_BUS :Otobüs
+STR_LIVERY_TRUCK :Kamyon
+STR_LIVERY_PASSENGER_SHIP :Yolcu Vapuru
+STR_LIVERY_FREIGHT_SHIP :Yük Gemisi
+STR_LIVERY_HELICOPTER :Helikopter
+STR_LIVERY_SMALL_PLANE :Küçük Uçak
+STR_LIVERY_LARGE_PLANE :Büyük Uçak
+
+STR_LIVERY_GENERAL_TIP :{BLACK}Genel renk şemalarını göster
+STR_LIVERY_TRAIN_TIP :{BLACK}Tren renk düzenlerini göster
+STR_LIVERY_ROADVEH_TIP :{BLACK}Araba renk düzenlerini göster
+STR_LIVERY_SHIP_TIP :{BLACK}Gemi renk düzenlerini göster
+STR_LIVERY_AIRCRAFT_TIP :{BLACK}Uçakların renk şemalarını göster
+STR_LIVERY_PRIMARY_TIP :{BLACK}Seçili düzen için birincil rengi seç
+STR_LIVERY_SECONDARY_TIP :{BLACK}Seçili düzen için ikincil rengi seç
+STR_LIVERY_PANEL_TIP :{BLACK}Rengini değiştirmek için bir araç türü seçin. CTRL+tıklama birden fazla araç seçebilir. Rengi kullanmak için kutucukları içaretleyin
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (Buhar)
+STR_8001_MJS_250_DIESEL :MJS 250 (Dizel)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut Dizel
+STR_8006_POWERNAUT_DIESEL :Powernaut Dizel
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (Buhar)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (Buhar)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (Buhar)
+STR_800A_SH_8P_STEAM :SH '8P' (Buhar)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (Dizel)
+STR_800C_DASH_DIESEL :'Dash' (Dizel)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (Dizel)
+STR_800E_UU_37_DIESEL :UU '37' (Dizel)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (Dizel)
+STR_8010_CS_4000_DIESEL :CS 4000 (Dizel)
+STR_8011_CS_2400_DIESEL :CS 2400 (Dizel)
+STR_8012_CENTENNIAL_DIESEL :Centennial (Dizel)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (Dizel)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (Dizel)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (Dizel)
+STR_8016_SH_125_DIESEL :SH '125' (Dizel)
+STR_8017_SH_30_ELECTRIC :SH '30' (Elektrik)
+STR_8018_SH_40_ELECTRIC :SH '40' (Elektrik)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (Elektrik)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (Elektrik)
+STR_801B_PASSENGER_CAR :Yolcu Vagonu
+STR_801C_MAIL_VAN :Posta Vagonu
+STR_801D_COAL_CAR :Kömür Vagonu
+STR_801E_OIL_TANKER :Petrol Tankeri
+STR_801F_LIVESTOCK_VAN :Hayvan Vagonu
+STR_8020_GOODS_VAN :EÅŸya Vagonu
+STR_8021_GRAIN_HOPPER :Tahıl Vagonu
+STR_8022_WOOD_TRUCK :Odun Vagonu
+STR_8023_IRON_ORE_HOPPER :Demir Vagonu
+STR_8024_STEEL_TRUCK :Çelik Vagonu
+STR_8025_ARMORED_VAN :Zirhli Vagon
+STR_8026_FOOD_VAN :Yiyecek Vagonu
+STR_8027_PAPER_TRUCK :Kağıt Vagonu
+STR_8028_COPPER_ORE_HOPPER :Bakır Vagonu
+STR_8029_WATER_TANKER :Su Vagonu
+STR_802A_FRUIT_TRUCK :Meyve Vagonu
+STR_802B_RUBBER_TRUCK :Kauçuk Vagonu
+STR_802C_SUGAR_TRUCK :Åžeker Vagonu
+STR_802D_COTTON_CANDY_HOPPER :Pamukhelva Vagonu
+STR_802E_TOFFEE_HOPPER :Bonbon Vagonu
+STR_802F_BUBBLE_VAN :Balon Vagonu
+STR_8030_COLA_TANKER :Kola Tankeri
+STR_8031_CANDY_VAN :Tatlı Vagonu
+STR_8032_TOY_VAN :Oyuncak Vagonu
+STR_8033_BATTERY_TRUCK :Pil Vagonu
+STR_8034_FIZZY_DRINK_TRUCK :İçecek Vagonu
+STR_8035_PLASTIC_TRUCK :Plastik Vagonu
+STR_8036_X2001_ELECTRIC :'X2001' (Elektrik)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Elektrik)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :Yolcu Vagonu
+STR_803A_MAIL_VAN :Posta Vagonu
+STR_803B_COAL_CAR :Kömür Vagonu
+STR_803C_OIL_TANKER :Petrol Tankeri
+STR_803D_LIVESTOCK_VAN :Hayvan Vagonu
+STR_803E_GOODS_VAN :EÅŸya Vagonu
+STR_803F_GRAIN_HOPPER :Tahıl Vagonu
+STR_8040_WOOD_TRUCK :Odun Vagonu
+STR_8041_IRON_ORE_HOPPER :Demir Vagonu
+STR_8042_STEEL_TRUCK :Çelik Vagonu
+STR_8043_ARMORED_VAN :Zirhli Vagon
+STR_8044_FOOD_VAN :Yiyecek Vagonu
+STR_8045_PAPER_TRUCK :Kağıt Vagonu
+STR_8046_COPPER_ORE_HOPPER :Bakır Vagonu
+STR_8047_WATER_TANKER :Su Tankeri
+STR_8048_FRUIT_TRUCK :Meyve Vagonu
+STR_8049_RUBBER_TRUCK :Kauçuk Vagonu
+STR_804A_SUGAR_TRUCK :Åžeker Vagonu
+STR_804B_COTTON_CANDY_HOPPER :Pamukhelva Vagonu
+STR_804C_TOFFEE_HOPPER :Bonbon Vagonu
+STR_804D_BUBBLE_VAN :Balon Vagonu
+STR_804E_COLA_TANKER :Kola Tankeri
+STR_804F_CANDY_VAN :Tatlı Vagonu
+STR_8050_TOY_VAN :Oyuncak Vagonu
+STR_8051_BATTERY_TRUCK :Pil Vagonu
+STR_8052_FIZZY_DRINK_TRUCK :İçecek Vagonu
+STR_8053_PLASTIC_TRUCK :Plastik Vagonu
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (Elektrik)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (Elektrik)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (Elektrik)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (Elektrik)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :Yolcu Vagonu
+STR_805A_MAIL_VAN :Posta Vagonu
+STR_805B_COAL_CAR :Kömür Vagonu
+STR_805C_OIL_TANKER :Petrol Tankeri
+STR_805D_LIVESTOCK_VAN :Hayvan Vagonu
+STR_805E_GOODS_VAN :EÅŸya Vagonu
+STR_805F_GRAIN_HOPPER :Tahıl Vagonu
+STR_8060_WOOD_TRUCK :Odun Vagonu
+STR_8061_IRON_ORE_HOPPER :Demir Vagonu
+STR_8062_STEEL_TRUCK :Çelik Vagonu
+STR_8063_ARMORED_VAN :Zirhli Vagon
+STR_8064_FOOD_VAN :Yiyecek Vagonu
+STR_8065_PAPER_TRUCK :Kağıt Vagonu
+STR_8066_COPPER_ORE_HOPPER :Bakır Vagonu
+STR_8067_WATER_TANKER :Su Tankeri
+STR_8068_FRUIT_TRUCK :Meyve Vagonu
+STR_8069_RUBBER_TRUCK :Kauçuk Vagonu
+STR_806A_SUGAR_TRUCK :Åžeker Vagonu
+STR_806B_COTTON_CANDY_HOPPER :Pamukhelva Vagonu
+STR_806C_TOFFEE_HOPPER :Bonbon Vagonu
+STR_806D_BUBBLE_VAN :Balon Vagonu
+STR_806E_COLA_TANKER :Kola Tankeri
+STR_806F_CANDY_VAN :Tatlı Vagonu
+STR_8070_TOY_VAN :Oyuncak Vagonu
+STR_8071_BATTERY_TRUCK :Pil Vagonu
+STR_8072_FIZZY_DRINK_TRUCK :İçecek Tankeri
+STR_8073_PLASTIC_TRUCK :Plastik Vagonu
+STR_8074_MPS_REGAL_BUS :MPS Regal Otobüs
+STR_8075_HEREFORD_LEOPARD_BUS :Hereford Leopard Otobüs
+STR_8076_FOSTER_BUS :Foster Otobüs
+STR_8077_FOSTER_MKII_SUPERBUS :Foster MkII Süperbüs
+STR_8078_PLODDYPHUT_MKI_BUS :Ploddyphut MkI Otobüs
+STR_8079_PLODDYPHUT_MKII_BUS :Ploddyphut MkII Otobüs
+STR_807A_PLODDYPHUT_MKIII_BUS :Ploddyphut MkIII Otobüs
+STR_807B_BALOGH_COAL_TRUCK :Balogh Kömür Kamyonu
+STR_807C_UHL_COAL_TRUCK :Uhl Kömür Kamyonu
+STR_807D_DW_COAL_TRUCK :DW Kömür Kamyonu
+STR_807E_MPS_MAIL_TRUCK :MPS Posta Arabası
+STR_807F_REYNARD_MAIL_TRUCK :Reynard Posta Arabası
+STR_8080_PERRY_MAIL_TRUCK :Perry Posta Arabası
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :MightyMover Posta Arabası
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Powernaught Posta Arabası
+STR_8083_WIZZOWOW_MAIL_TRUCK :Wizzowow Posta Arabası
+STR_8084_WITCOMBE_OIL_TANKER :Witcombe Petrol Tankeri
+STR_8085_FOSTER_OIL_TANKER :Foster Petrol Tankeri
+STR_8086_PERRY_OIL_TANKER :Perry Petrol Tankeri
+STR_8087_TALBOTT_LIVESTOCK_VAN :Talbott Hayvan Kamyonu
+STR_8088_UHL_LIVESTOCK_VAN :Uhl Hayvan Kamyonu
+STR_8089_FOSTER_LIVESTOCK_VAN :Foster Hayvan Kamyonu
+STR_808A_BALOGH_GOODS_TRUCK :Balogh EÅŸya Kamyonu
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Craighead EÅŸya Kamyonu
+STR_808C_GOSS_GOODS_TRUCK :Goss EÅŸya Kamyonu
+STR_808D_HEREFORD_GRAIN_TRUCK :Hereford Tahıl Kamyonu
+STR_808E_THOMAS_GRAIN_TRUCK :Thomas Tahıl Kamyonu
+STR_808F_GOSS_GRAIN_TRUCK :Goss Tahıl Kamyonu
+STR_8090_WITCOMBE_WOOD_TRUCK :Witcombe Odun Kamyonu
+STR_8091_FOSTER_WOOD_TRUCK :Foster Odun Kamyonu
+STR_8092_MORELAND_WOOD_TRUCK :Moreland Odun Kamyonu
+STR_8093_MPS_IRON_ORE_TRUCK :MPS Demir Kamyonu
+STR_8094_UHL_IRON_ORE_TRUCK :Uhl Demir Kamyonu
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Chippy Demir Kamyonu
+STR_8096_BALOGH_STEEL_TRUCK :Balogh Çelik Kamyonu
+STR_8097_UHL_STEEL_TRUCK :Uhl Çelik Kamyonu
+STR_8098_KELLING_STEEL_TRUCK :Kelling Çelik Kamyonu
+STR_8099_BALOGH_ARMORED_TRUCK :Balogh Zirhli Araç
+STR_809A_UHL_ARMORED_TRUCK :Uhl Zirhli Araç
+STR_809B_FOSTER_ARMORED_TRUCK :Foster Zirhli Araç
+STR_809C_FOSTER_FOOD_VAN :Foster Yiyecek Arabası
+STR_809D_PERRY_FOOD_VAN :Perry Yiyecek Arabası
+STR_809E_CHIPPY_FOOD_VAN :Chippy Yiyecek Arabası
+STR_809F_UHL_PAPER_TRUCK :Uhl Kağıt Kamyonu
+STR_80A0_BALOGH_PAPER_TRUCK :Balogh Kağıt Kamyonu
+STR_80A1_MPS_PAPER_TRUCK :MPS Kağıt Kamyonu
+STR_80A2_MPS_COPPER_ORE_TRUCK :MPS Bakır Kamyonu
+STR_80A3_UHL_COPPER_ORE_TRUCK :Uhl Bakır Kamyonu
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Goss Bakır Kamyonu
+STR_80A5_UHL_WATER_TANKER :Uhl Su Tankeri
+STR_80A6_BALOGH_WATER_TANKER :Balogh Su Tankeri
+STR_80A7_MPS_WATER_TANKER :MPS Su Tankeri
+STR_80A8_BALOGH_FRUIT_TRUCK :Balogh Meyve Kamyonu
+STR_80A9_UHL_FRUIT_TRUCK :Uhl Meyve Kamyonu
+STR_80AA_KELLING_FRUIT_TRUCK :Kelling Meyve Kamyonu
+STR_80AB_BALOGH_RUBBER_TRUCK :Balogh Kauçuk Kamyonu
+STR_80AC_UHL_RUBBER_TRUCK :Uhl Kauçuk Kamyonu
+STR_80AD_RMT_RUBBER_TRUCK :RMT Kauçuk Kamyonu
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :MightyMover Åžeker Kamyonu
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Powernaught Åžeker Kamyonu
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Wizzowow Åžeker Kamyonu
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :MightyMover Kola Kamyonu
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Powernaught Kola Kamyonu
+STR_80B3_WIZZOWOW_COLA_TRUCK :Wizzowow Kola Kamyonu
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :MightyMover Pamukhelva Kamyonu
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Powernaught Pamukhelva Kamyonu
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Wizzowow Pamukhelva Kamyonu
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :MightyMover Bonbon Kamyonu
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Powernaught Bonbon Kamyonu
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Wizzowow Bonbon Kamyonu
+STR_80BA_MIGHTYMOVER_TOY_VAN :MightyMover Oyuncak Kamyonu
+STR_80BB_POWERNAUGHT_TOY_VAN :Powernaught Oyuncak Kamyonu
+STR_80BC_WIZZOWOW_TOY_VAN :Wizzowow Oyuncak Kamyonu
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :MightyMover Tatlı Kamyonu
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Powernaught Tatlı Kamyonu
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Wizzowow Tatlı Kamyonu
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :MightyMover Pil Kamyonu
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Powernaught Pil Kamyonu
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Wizzowow Pil Kamyonu
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :MightyMover içecek Tankeri
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Powernaught içecek Tankeri
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Wizzowow içecek Tankeri
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :MightyMover Plastik Kamyonu
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Powernaught Plastik Kamyonu
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Wizzowow Plastik Kamyonu
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :MightyMover Balon Kamyonu
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Powernaught Balon Kamyonu
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Wizzowow Balon Kamyonu
+STR_80CC_MPS_OIL_TANKER :MPS Petrol Tankeri
+STR_80CD_CS_INC_OIL_TANKER :CS-Inc. Petrol Tankeri
+STR_80CE_MPS_PASSENGER_FERRY :MPS Yolcu Vapuru
+STR_80CF_FFP_PASSENGER_FERRY :FFP Yolcu Vapuru
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Bakewell 300 Hoverkraft
+STR_80D1_CHUGGER_CHUG_PASSENGER :Chugger-Chug Deniz otobüsü
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Shivershake Deniz otobüsü
+STR_80D3_YATE_CARGO_SHIP :Yate Kargo gemisi
+STR_80D4_BAKEWELL_CARGO_SHIP :Bakewell Kargo gemisi
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Mightymover Kargo gemisi
+STR_80D6_POWERNAUT_CARGO_SHIP :Powernaut Kargo gemisi
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Tricario Helikopter
+STR_80FE_GURU_X2_HELICOPTER :Guru X2 Helikopter
+STR_80FF_POWERNAUT_HELICOPTER :Powernaut Helikopter
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Araç yapimcisindan mesaj
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}Yeni bir araç dizayn ettik: {STRING} - bizim için bunu bir yıl denemeyi kabul ediyor musunuz?
+STR_8102_RAILROAD_LOCOMOTIVE :lokomotif
+STR_8103_ROAD_VEHICLE :araba
+STR_8104_AIRCRAFT :uçak
+STR_8105_SHIP :gemi
+STR_8106_MONORAIL_LOCOMOTIVE :monoray lokomotifi
+STR_8107_MAGLEV_LOCOMOTIVE :maglev lokomotifi
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}{TOWN} Tren Garaji
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Kutlama Yapıldı . . .{} {STATION} istasyonuna ilk kez tren geldi!
+STR_8802_DETAILS :{WHITE}{STRING} (Detaylar)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Yolda tren var
+STR_8804 :{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8806_GO_TO :Git: {STATION}
+STR_8807_GO_TO_TRANSFER :Aktar: {STATION} (Kargoyu al)
+STR_8808_GO_TO_UNLOAD :Git: {STATION} (BoÅŸalt)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Aktar: {STATION} (Boş dön)
+STR_880A_GO_TO_LOAD :Git: {STATION} (Doldur)
+STR_880B_GO_TO_TRANSFER_LOAD :Aktar: {STATION} (Tam doldur)
+STR_880C_GO_NON_STOP_TO :Durmadan git: {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Durmadan aktar: {STATION} (Kargoyu al)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Durmadan git: {STATION} (BoÅŸalt)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Durmadan aktar: {STATION} (Boş dön)
+STR_8810_GO_NON_STOP_TO_LOAD :Durmadan git: {STATION} (Doldur)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Durmadan aktar: {STATION} (Tam doldur)
+STR_GO_TO_TRAIN_DEPOT :Git: {TOWN} Tren Garı
+STR_SERVICE_AT_TRAIN_DEPOT :Bakıma git: {TOWN} Tren Garı
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Durmadan git: {TOWN} Tren Garı
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Durmadan bakıma git: {TOWN} Tren Garı
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}{TOWN} Tren Garına gidiyor
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}{TOWN} Tren Garına gidiyor, {VELOCITY}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE :{LTBLUE}{TOWN} Garında Bakım
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE_VEL :{LTBLUE}{TOWN} Garında Bakım, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (Hatalı talimat)
+
+STR_UNKNOWN_DESTINATION :bilinmeyen hedef
+STR_8812_EMPTY :{LTBLUE}BoÅŸ
+STR_8813_FROM :{LTBLUE}{CARGO} - {STATION}
+STR_FROM_MULT :{LTBLUE}{CARGO} geldiÄŸi yer: {STATION} (x{NUM})
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}Tren {COMMA} garda bekliyor
+STR_8815_NEW_VEHICLES :{BLACK}Yeni Araç
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Tren çok uzun
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Sadece garda durdurulmuş trenler üzerinde işlem yapılabilir
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} Tren
+
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Yeni Tren
+STR_NEW_ELRAIL_VEHICLES :{WHITE}Yeni Elektrikli Trenler
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Yeni Monoray
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Yeni Maglev
+STR_ALL_AVAIL_RAIL_VEHICLES :{WHITE}Trenler
+
+STR_881F_BUILD_VEHICLE :{BLACK}Satın Al
+STR_CLONE_ROAD_VEHICLE :{BLACK}Arabayı kopyala
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}Arabanın bir kopyasını yapar. CTRL-tıklama talimatları paylaştırır
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Arabanın bir kopyasını yapar. Önce bu düğmeye sonra da garın içindeki veya dışındaki bir araca tıklayın. CTRL-tıklama talimatları paylaştırır
+STR_CLONE_TRAIN :{BLACK}Treni kopyala
+STR_CLONE_TRAIN_INFO :{BLACK}Tüm vagonlarla birlikte treni kopyalar. CTRL-tıklama talimatları paylaştırır
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}Tüm vagonlarla birlikte treni kopyalar. Önce bu düğmeye sonra da garın içindeki veya dışındaki bir araca tıklayın. CTRL-tıklama talimatları paylaştırır
+STR_8820_RENAME :{BLACK}Yeni isim
+STR_8823_SKIP :{BLACK}Atla
+STR_8824_DELETE :{BLACK}Sil
+STR_8825_NON_STOP :{BLACK}Durmadan
+STR_8826_GO_TO :{BLACK}Git
+STR_8827_FULL_LOAD :{BLACK}Doldur
+STR_8828_UNLOAD :{BLACK}BoÅŸalt
+STR_REFIT :{BLACK}Modifiye
+STR_REFIT_ORDER :(Moifiye ile > {STRING})
+STR_8829_ORDERS :{WHITE}{VEHICLE} (Komutlar)
+STR_882A_END_OF_ORDERS :{SETX 10}- - Komutların Sonu - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}Bakım
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Tren satın alınamaz...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Tarih: {LTBLUE}{NUM}{BLACK} DeÄŸeri: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} DeÄŸeri: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}Yükleme / Boşaltma
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}Tren garda durdurulmalı
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Tren gara gönderilemiyor...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Çok fazla talimat var
+STR_8832_TOO_MANY_ORDERS :{WHITE}Çok fazla talimat
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Yeni talimat verilemiyor...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Bu talimat silinemez...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Bu talimat deÄŸiÅŸtirilemez...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Araç hareket edemiyor...
+STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}Arkadaki lokomotif daima önündekini takip edecek
+STR_8838_N_A :yok{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Tren satılamaz...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Yakındaki bir gara gidecek yol yok
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Tren durdurulamaz/başlatılamaz...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Bakım zamanı: {LTBLUE}{COMMA}günde bir{BLACK} Son bakım: {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Bakım zamanı: {LTBLUE}%{COMMA}{BLACK} Son bakım: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Trenlar - daha fazla bilgi için trene tıklayın
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Tren satın al (tren garı gerekli)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Trenlar - bilgi için trene tıklayın., trene vagon eklemek/kaldırmak için sürükleyin
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Yeni tren satın al
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Satmak için aracı buraya sürükleyin
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Tren garini göster
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Tren seçim listesi - daha fazla bilgi için araca tıklayın
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Seçili treni satın al
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Treni yeniden adlandır
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Tren durumu - treni durdurmak/başlatmak için buraya tıklayın
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Trenin talimatlarıni göster
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Treni göster
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Treni gara gönder
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Treni sinyale uymadan ilerlemeye zorla
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Treni ters çevir
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Tren ayrıntılarını göster
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Bakım zamanını ertele
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Bakım zamanını azalt
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Taşınan kargonun ayrıntıları
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Trenin ayrıntıları
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Her aracın kapasitesi
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Trenin kargo türlerine ayrilmis toplam kapasitesini göster
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Komut listesi - seçmek için komutu tıklayın. CTRL + tıklama istasyona kaydırir
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}Şimdiki komutu atlayıp sıradakine geç
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Seçili komutu sil
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Seçili komutu durmadan yap
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Seçili komutun önüne ya da listenin sonuna komut ekle
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Seçili komutu yaparken tren dolana kadar beklesin
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Seçili komutu yaparken tren mutlaka yükünü boşaltsın
+STR_SERVICE_HINT :{BLACK}Bakım gerekmiyorsa bunu atla
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}Yeni bir araç üretildi: {STRING}
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Fiyat: {CURRENCY} Ağırlık: {WEIGHT_S}{}Hız: {VELOCITY} Güç: {POWER}{}Bakım: {CURRENCY}/sene{}Kapasite: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}Bozuldu
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}Yaş: {LTBLUE}{STRING}{BLACK} Bakım: {LTBLUE}{CURRENCY}/sene
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Ağırlık: {LTBLUE}{WEIGHT_S} {BLACK}Güç: {LTBLUE}{POWER}{BLACK} Mak. hız: {LTBLUE}{VELOCITY}
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Ağırlık: {LTBLUE}{WEIGHT_S} {BLACK}Güç: {LTBLUE}{POWER}{BLACK} Mak. hız: {LTBLUE}{VELOCITY} {BLACK}Max. Ç.G.: {LTBLUE}{FORCE}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Bu seneki kâr: {LTBLUE}{CURRENCY} (geçen sene: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}güvenilirlik: {LTBLUE}%{COMMA} {BLACK}Son servisteki bozulmalar: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Durdu
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Tehlikedeki tren sinyali geçemez...
+STR_8863_CRASHED :{RED}Çarptı!
+
+STR_8865_NAME_TRAIN :{WHITE}Treni adlandır
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}Tren adlandırılamıyor...
+STR_8867_NAME_TRAIN :{BLACK}Treni adlandır
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Tren Kazasi!{}{COMMA} ölü var.
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Tren çevrilemez...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Tren yeniden adlandırılamaz
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Tren yeniden adlandırılamaz...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Seçili talimatta aracı kargoyu boşaltmaya zorla
+STR_886F_TRANSFER :{BLACK}Aktar
+
+STR_TRAIN_STOPPING :{RED}Frenliyor
+STR_TRAIN_STOPPING_VEL :{RED}Frenliyor, {VELOCITY}
+STR_INCOMPATIBLE_RAIL_TYPES :Uyumsuz ray türleri
+STR_TRAIN_NO_POWER :{RED}Elektrik yok
+STR_TRAIN_START_NO_CATENARY :Bu rayda elektrik olmadiği için bu tren çalışamaz
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Yolda araba var
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} Arabalar
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}{TOWN} Araba Garaji
+STR_9004_NEW_VEHICLES :{BLACK}Yeni Araba
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}Yeni Araba
+STR_9007_BUILD_VEHICLE :{BLACK}Araba Al
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Araba alınamıyor...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (Detaylar)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}Yaş: {LTBLUE}{STRING}{BLACK} Bakım: {LTBLUE}{CURRENCY}/sene
+STR_900E_MAX_SPEED :{BLACK}Mak. hız: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Bu seneki kâr: {LTBLUE}{CURRENCY} (geçen sene: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}güvenilirlik: {LTBLUE}%{COMMA} {BLACK}Breakdowns since last service: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Yapım yılı: {LTBLUE}{NUM}{BLACK} Değeri: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Kapasite: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}...bir araba garajında duruyor olmalı
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Araba satılamıyor...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Araba başlayamıyor/duramıyor...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}Araba {COMMA} garajda bekliyor
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}{TOWN} Garajina gidiyor
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}{TOWN} Garajina gidiyor, {VELOCITY}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE :{LTBLUE}{TOWN} Garajinda Bakıma Gir
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE_VEL :{LTBLUE}{TOWN} Garajinda Bakım, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Araç garaja gidemiyor...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Yerel garaj bulunamadı
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Arabalar - bilgi için arabaya tıklayın
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Yeni araba al (araba garajı gerekir)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Aracın durumu - durdurmak/başlatmak için tıklayın
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Aracın komutlarını görmek için tıklayın
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Arabayı göster
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Aracı garaja gönder
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Aracı etrafta dolaşmaya zorla
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Araba ayrıntılarını göster
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Arabalar - ayrıntılı bilgi için araca tıklayın
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Yeni araba al
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Satmak için arabayı buraya sürükle
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Araba garajını göster
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Araba listesi - bilgi için arabayı tıklayın
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Seçili arabayı al
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}Yeni bir araba üretildi!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Fiyat: {CURRENCY}{}Hız: {VELOCITY}{}Bakım: {CURRENCY}/sene{}Kapasite: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Arabayı adlandır
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Araba adlandırılamıyor...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Arabayı adlandır
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Kutlama yapıldı . . .{}Şuraya ilk kez otobüs geldi: {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Kutlama yapıldı . . .{}Şuraya ilk kez kamyon geldi: {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}Trafik kazasi!{}Trenle çarpisan aracın soförü feci şekilde can verdi
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}Trafik kazasi!{}{COMMA} kişi patlamadan kurtulamadı
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Araç döndürülemiyor...
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}Birden fazla birimden oluşan araçlar çevrilemez
+STR_9034_RENAME :{BLACK}Ä°sim
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Araç türünü yeniden adlandır
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Araç türünü yeniden adlandır
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Araç türü yeniden adlandırılamıyor...
+STR_9038_GO_TO_ROADVEH_DEPOT :Garaja git: {TOWN}
+STR_SERVICE_AT_ROADVEH_DEPOT :Servise git: {TOWN} Garaji
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Kamyonu başka türde kargo taşıyabilmesi için modifiye et
+STR_REFIT_ROAD_VEHICLE :{BLACK}Kamyonu modifiye et
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Kamyonu seçili kargoyu taşıyabilmesi için modifiye et
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Kamyon modifiye edilemiyor...
+STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Kamyonun taşıyacağı kargo türünü seçin
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :İskele yapımı
+STR_9801_DOCK_CONSTRUCTION :{WHITE}İskele yapımı
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Buraya iskele yapılamaz...
+STR_9803_SHIP_DEPOT :{WHITE}{TOWN} Tersanesi
+STR_9804_NEW_SHIPS :{BLACK}Yeni gemi
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} Gemi
+STR_9808_NEW_SHIPS :{WHITE}Yeni gemi
+STR_9809_BUILD_SHIP :{BLACK}Gemi yap
+STR_CLONE_SHIP :{BLACK}Gemiyi kopyala
+STR_CLONE_SHIP_INFO :{BLACK}Geminin bir kopyasını oluşturur. CTRL-tıklama talimatları paylaştırır
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}Geminin bir kopyasını oluşturur. Önce bu düğmeye sonra da tersanenin içindeki veya dışındaki bir gemiye tıklayın. CTRL-tıklama talimatları paylaştırır
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}Gemi tersanede durdurulmalı
+STR_980C_CAN_T_SELL_SHIP :{WHITE}Gemi satılamaz...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Yemi yapılamaz...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Yolda gemi var
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Detaylar)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}Yaş: {LTBLUE}{STRING}{BLACK} Bakım: {LTBLUE}{CURRENCY}/sene
+STR_9813_MAX_SPEED :{BLACK}Mak. Hız: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Bu seneki kâr: {LTBLUE}{CURRENCY} (geçen sene: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}Güven: {LTBLUE}%{COMMA} {BLACK}Son yolculuktaki bozulmalar: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Yapım yılı: {LTBLUE}{NUM}{BLACK} Değeri: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}Kapasite: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}Gemi durdurulamaz/başlatılamaz...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Gemi tersaneye gönderilemez...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Yerel tersane bulunamadı
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}Gidiyor: {TOWN} Tersanesi
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}Gidiyor: {TOWN} Tersanesi, {VELOCITY}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE :{LTBLUE}{TOWN} Tersanesinde Bakım
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE_VEL :{LTBLUE}{TOWN} Tersanesinde Bakım, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}Gemi {COMMA} tersanede bekliyor
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Ä°skele yap
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Tersane yap (gemi yapmak ve bakımları için)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Gemiler - bilgi için gemiye tıkla
+STR_9820_BUILD_NEW_SHIP :{BLACK}Yeni gemi yap
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Satmak için gemiyi buraya sürükle
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Tersaneyi göster
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Gemiler - bilgi için gemiye tıkla
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Gemi yap (tersane gerektirir)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}Gemi seçim listesi - bilgi için gemiye tıkla
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Seçili gemiyi yap
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Geminin durumu - durdurmak/başlatmak için buraya tıkla
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Geminin talimatlarıni göster
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Gemiyi göster
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Tersaneye gönder
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Gemi ayrıntılarını göster
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}Yeni gemi üretildi!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Fiyatı: {CURRENCY} Mak. Hız: {VELOCITY}{}Kapasite: {CARGO}{}Bakım: {CURRENCY}/sene
+STR_982F_NAME_SHIP :{BLACK}Gemiyi adlandır
+
+STR_9831_NAME_SHIP :{WHITE}Gemiyi adlandır
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Gemi adlandırılamaz...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Kutlama yapıldı . . .{}Şuraya ilk kez gemi geldi: {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Yerimi olarak kullanilabilecek bir şamandıra yerlestir
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Şamandıra yerlestirilemez...
+STR_9836_RENAME :{BLACK}Ä°sim
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Gemi türünü adlandır
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Gemi türünü adlandır
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Gemi türü adlandırılamaz...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Başka bir yük taşımasi için modifiye et
+STR_983B_REFIT :{WHITE}{VEHICLE} (Modifiye)
+STR_983C_REFIT_SHIP :{BLACK}modifiye
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Tasinacak kargoyu seçin
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Seçili kargoyu taşımak için modifiye et
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Tasinacak kargo türünü seçin:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Yeni kapasite: {GOLD}{CARGO}{}{BLACK}Modifiye fiyatı: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Modifiye edilemez...
+STR_9842_REFITTABLE :(modifiyeli)
+STR_GO_TO_SHIP_DEPOT :Git: {TOWN} Tersanesi
+SERVICE_AT_SHIP_DEPOT :Servis: {TOWN} Tersanesi
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Havalimanları
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Buraya havalimanı yapılamaz...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} Hangarı
+STR_A003_NEW_AIRCRAFT :{BLACK}Yeni Uçak
+STR_CLONE_AIRCRAFT :{BLACK}Uçağı kopyala
+STR_CLONE_AIRCRAFT_INFO :{BLACK}Uçağın bir kopyasını oluşturur. CTRL-tıklama talimatları paylaştırır
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Uçağın bir kopyasını oluşturur. Önce bu düğmeye sonra da hangarın içindeki veya dışındaki bir uçaga tıklayın. CTRL-tıklama talimatları paylaştırır
+STR_A005_NEW_AIRCRAFT :{WHITE}Yeni Uçak
+STR_A006_BUILD_AIRCRAFT :{BLACK}Uçak Yap
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Uçak alınamaz...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} Uçak
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (Talimatlar)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (Detaylar)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Yaş: {LTBLUE}{STRING}{BLACK} Bakım: {LTBLUE}{CURRENCY}/yıl
+STR_A00E_MAX_SPEED :{BLACK}Mak. hız: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Bu seneki kâr: {LTBLUE}{CURRENCY} (geçen sene: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}Güvenilirlik: {LTBLUE}%{COMMA} {BLACK}Son servisten beri bozulmalar: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Yapım: {LTBLUE}{NUM}{BLACK} Değeri: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Hangara gönderilemiyor...
+STR_HEADING_FOR_HANGAR :{ORANGE}{STATION} Hangarına gidiyor
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}{STATION} Hangarına gidiyor, {VELOCITY}
+STR_HEADING_FOR_HANGAR_SERVICE :{LTBLUE}{STATION} Hangarında Bakım
+STR_HEADING_FOR_HANGAR_SERVICE_VEL :{LTBLUE}{STATION} Hangarında Bakım, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}Uçak {COMMA} hangarda bekliyor
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Yolda uçak var
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Uçak durdurulamaz/başlatılamaz...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Şu an uçusta
+STR_A019_CAPACITY :{BLACK}Kapasite: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Kapasite: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}Uçak hangarda durdurulmalı
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Uçak satılamıyor...
+STR_A01D_AIRPORT_CONSTRUCTION :Havalimanı binasi
+STR_A01E_BUILD_AIRPORT :{BLACK}Havalimanı yap
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Uçak - ayrıntılı bilgi için uçağı tıkla
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Yeni uçak al (hangarlı havalimanı gerekir)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Uçak - bilgi için uçaga tıkla
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Yeni uçak al
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}Satmak için uçağı buraya sürükleyin
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Hangarı göster
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Uçak listesi - bilgi için uçaga tıklayın
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Seçili uçaktan al
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Uçağın durumu - uçağı durdurmak/başlatmak için tıkla
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Uçağın talimatlarıni göster
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Uçağı göster
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Uçağı hangara gönder
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Uçak ayrıntılarını göster
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}Yeni bir uçak yapıldı!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Fiyat: {CURRENCY} Mak. Hız: {VELOCITY}{}Kapasite: {COMMA} yolcu, {COMMA} çanta posta{}Bakım: {CURRENCY}/yıl
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Uçağı adlandır
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Uçak adlandırılamaz...
+STR_A032_NAME_AIRCRAFT :{BLACK}Uçağı adlandır
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Kutlama yapıldı . . .{}{STATION} istasyonuna ilk kez uçak geldi!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Uçak Kazasi!{}{COMMA} ölü var - {STATION}
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Uçak Kazasi!{}Benzin yetmedi, {COMMA} kisi öldü!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Ä°sim
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Uçak türünü adlandır
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Uçak türünü adlandır
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Uçak türü adlandırılamaz...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Başka bir yük taşımak için modifiye et
+STR_A03C_REFIT :{WHITE}{VEHICLE} (Modifiye)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Modifiye
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Tasinacak kargo türünü seçin
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Seçili kargoyu taşımasi için uçağı modifiye et
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Tasinacak kargoyu seçin:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Yeni kapasite: {GOLD}{STRING}{}{BLACK}Modifiye fiyatı: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Modifiye edilemez...
+STR_GO_TO_AIRPORT_HANGAR :{STATION} Hangarına git
+SERVICE_AT_AIRPORT_HANGAR :Servis: {STATION} Hangarı
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}Zeplin düştü - {STATION}!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}UFO'ya çarpan araba parçalandı!
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}{TOWN} yakınlarındaki petrol rafinerisi patladı!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}{TOWN} yakınlarındaki fabrika kundaklandı!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}{TOWN} yakınlarına UFO kondu!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}{TOWN} yakınlarındaki kömür madeninde patlama oldu!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Sel baskını!{}En az {COMMA} kayıp var, hepsinin öldüğü tahmin ediliyor!
+
+STR_BRIBE_FAILED :{WHITE}Rüsvet teşebbüsünüzü
+STR_BRIBE_FAILED_2 :{WHITE}Reha Muhtar açığa çıkardı
+STR_BUILD_DATE :{BLACK}Yapım: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Ayrıntılı performans
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}Detay
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Araçlar:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Ä°stasyonlar:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Min. kâr:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Min. gelir:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Mak. gelir:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Taşınan:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Kargo:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Para:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Kredi:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Toplam:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Araç sayısı; araba, tren uçak ve gemiler dahil
+STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}İstasyon parçaları. Tek bir istasyon halinde olsa bile istasyonun her parçasi ayri olarak sayılir (ör: tren istasyonu, otobüs durağı, havalimanı)
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}En az gelirli aracın kârı (2 yildan yasli tüm araçlar için)
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Son 12 çeyrekte en az kârlı aydaki gelir
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Son 12 çeyrekte en çok kârlı aydaki gelir
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}Son 4 çeyrekte taşınan kargo miktar
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}Son çeyrekte taşınan farkli kargo türleri
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Bu şirketin bankadaki para miktarı
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}Bu şirketin bankadan aldığı kredi miktarı
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Toplam puan
+
+STR_NEWGRF_SETTINGS_BUTTON :{BLACK}NewGRF Ayarları
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}Newgrf ayarları
+STR_NEWGRF_APPLY_CHANGES :{BLACK}Uygula
+STR_NEWGRF_SET_PARAMETERS :{BLACK}Parametreler
+STR_NEWGRF_TIP :{BLACK}Yüklediğiniz tüm Newgrf'lerin listesi. Ayarları değiştirmek için bir sete tıklayın
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}Yüklenmiş newgrf dosyası yok! Newgrf yüklemek için kılavuza başvurun
+STR_NEWGRF_FILENAME :{BLACK}Dosya adı: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
+STR_NEWGRF_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING}
+STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}Çalışan bir oyunu değiştirmek üzeresiniz; bu OpenTTD'yi çökertebilir.{}Emin misiniz?
+
+STR_NEWGRF_ADD :{BLACK}Ekle
+STR_NEWGRF_ADD_TIP :{BLACK}Listeye NewGRF dosyası ekle
+STR_NEWGRF_REMOVE :{BLACK}Kaldır
+STR_NEWGRF_REMOVE_TIP :{BLACK}Seçili NewGRF dosyasını listeden kaldır
+STR_NEWGRF_MOVEUP :{BLACK}Yukarı Taşı
+STR_NEWGRF_MOVEUP_TIP :{BLACK}Seçili NewGRF dosyasını listenin yukarısına taşı
+STR_NEWGRF_MOVEDOWN :{BLACK}Aşağı Taşı
+STR_NEWGRF_MOVEDOWN_TIP :{BLACK}Seçili NewGRF dosyasını listenin aşağısına taşı
+STR_NEWGRF_FILE_TIP :{BLACK}Yüklü NewGRF dosyalarının listesidir. Seçeneklerini değiştirmek için bir dosyayı tıklayın
+STR_NEWGRF_PARAMETER :{BLACK}Seçenekler: {SILVER}{STRING}
+STR_NEWGRF_PARAMETER_QUERY :{BLACK}NewGRF seçeneklerini girin
+STR_NEWGRF_NO_INFO :{BLACK}Hiç bilgi yok
+
+STR_NEWGRF_ADD_CAPTION :{WHITE}Mümkün olan NewGRF dosyaları
+STR_NEWGRF_ADD_FILE :{BLACK}Seçime ekle
+STR_NEWGRF_ADD_FILE_TIP :{BLACK}seçili NewGRF'i ayarlarıma ekle
+STR_NEWGRF_RESCAN_FILES :{BLACK}Dosyaları tekrar tara
+STR_NEWGRF_RESCAN_FILES_TIP :{BLACK}Mümkün olan NewGRF dosyalarının listesini güncelle
+STR_NEWGRF_DUPLICATE_GRFID :{WHITE}Dosya eklenemiyor: GRF ID çakışması
+
+STR_NEWGRF_NOT_FOUND :{RED}Eşleşen dosya bulunamadı
+STR_NEWGRF_DISABLED :{RED}Etkisiz
+
+STR_CURRENCY_WINDOW :{WHITE}Özel Para Birimi
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Çarpan: {ORANGE}{CURRENCY} = £ {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Ayraç:
+STR_CURRENCY_PREFIX :{LTBLUE}Önek:
+STR_CURRENCY_SUFFIX :{LTBLUE}Sonek:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Euro'ya geç: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Euro'ya geç: {ORANGE}hiçbir zaman
+STR_CURRENCY_PREVIEW :{LTBLUE}Önizleme: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Özel para birimini değiştir
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} Trenler
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} Arabalar
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} Uçaklar
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} Gemiler
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Komut listesinde bu durak olan trenleri listele
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Komut listesinde bu durak olan arabaları listele
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Komut listesinde bu durak olan uçakları listele
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Komut listesinde bu durak olan gemileri listele
+
+STR_VEH_WITH_SHARED_ORDERS_LIST :{WHITE}{COMMA} Aracın paylaşılan talimatları
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}Aynı talimatlara sahip bütün araçları göster
+
+### depot strings
+STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Garajdaki bütün araçları satmak üzeresiniz. Emin misiniz?
+
+STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP :{BLACK}Gardaki tüm trenleri sat
+STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP :{BLACK}Garajdaki tüm arabaları sat
+STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP :{BLACK}Tersanedeki tüm gemileri sat
+STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP :{BLACK}Hangardaki tüm hava araçlarıni sat
+
+STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP :{BLACK}Bu garı talimat listesinde içeren trenleri listele
+STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP :{BLACK}Bu garajı talimat listesinde içeren arabaları listele
+STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP :{BLACK}Bu tersaneyi talimat listesinde içeren gemileri listele
+STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP :{BLACK}Bu havalimanındaki hangarlardan birini talimat listesinde içeren uçakları listele
+
+STR_DEPOT_AUTOREPLACE_TRAIN_TIP :{BLACK}Gardaki tüm trenleri otomatik yenile
+STR_DEPOT_AUTOREPLACE_ROADVEH_TIP :{BLACK}Garajdaki tüm arabaları otomatik yenile
+STR_DEPOT_AUTOREPLACE_SHIP_TIP :{BLACK}Tersanedeki tüm gemileri otomatik yenile
+STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP :{BLACK}Hangardaki tüm uçakları otomatik yenile
+
+STR_VEHICLE_LIST_TRAIN_DEPOT :{BLACK}{STRING} - {COMMA} Tren
+STR_VEHICLE_LIST_ROADVEH_DEPOT :{BLACK}{STRING} - {COMMA} Araba
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} Gemi
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} Uçak
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}{STRING} DeÄŸiÅŸtir
+STR_REPLACE_VEHICLES_START :{BLACK}Araçları Değiştirmeye Başla
+STR_REPLACE_VEHICLES_STOP :{BLACK}Araçları değiştirmeyi durdur
+STR_NOT_REPLACING :{BLACK}DeÄŸiÅŸtirilmiyor
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Hiç Araç Seçilmedi
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Değiştirilecek türü seçin
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Değiştirilecek türün yerine geçecek türü seçin
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Değiştirme işlemini durdurmak için basın
+STR_REPLACE_HELP_START_BUTTON :{BLACK}Değiştirme işlemini başlatmak için basın
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Lokomatiflerini değiştireceğiniz ray türünü seçin
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Soldaki değiştiriliyorsa neyle değiştirildiğini göster
+STR_REPLACE_HELP :{BLACK}Tren gara girdiginde seçilen türle değiştirilir
+STR_REPLACE_REMOVE_WAGON :{BLACK}Vagon kaldırma: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Otomatik yenilemede tren boyutunun artması gerekiyorsa vagonları kaldır(en önden başlayarak yeterli sayıda vagon silinir).
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}DeÄŸiÅŸtiriyor: {ORANGE}{SKIP}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} DENEYSEL ÖZELLiK {}Lokomotif ve vagon değişimi pencereleri arasında geçiş yap.{}Vagon değişimi sadece yeni vagon eskisinin taşıdığı türde yükü taşıyabiliyorsa yapılir. Değiştirme işlemi sırasında tüm vagonlar için bu durum kontrol edilir.
+STR_ENGINE_NOT_BUILDABLE :{WHITE}Lokomotif alınamaz
+
+STR_ENGINES :Lokomotifler
+STR_WAGONS :Vagon
+
+STR_MASS_STOP_DEPOT_TRAIN_TIP :{BLACK}Gardaki tüm trenleri durdurmak için tıkla
+STR_MASS_STOP_DEPOT_ROADVEH_TIP :{BLACK}Garajdaki tüm arabaları durdurmak için tıkla
+STR_MASS_STOP_DEPOT_SHIP_TIP :{BLACK}Tersanedeki tüm gemileri durdurmak için tıkla
+STR_MASS_STOP_HANGAR_TIP :{BLACK}Hangardaki tüm uçakları durdurmak için tıkla
+
+STR_MASS_START_DEPOT_TRAIN_TIP :{BLACK}Gardaki tüm trenleri başlatmak için tıkla
+STR_MASS_START_DEPOT_ROADVEH_TIP :{BLACK}Garajdaki tüm arabaları başlatmak için tıkla
+STR_MASS_START_DEPOT_SHIP_TIP :{BLACK}Tersanedeki tüm gemileri başlatmak için tıkla
+STR_MASS_START_HANGAR_TIP :{BLACK}Hangardaki tüm uçakları başlatmak için tıkla
+
+STR_MASS_STOP_LIST_TIP :{BLACK}Listedeki tüm araçları durdurmak için bas
+STR_MASS_START_LIST_TIP :{BLACK}Listedeki tüm araçları başlatmak için bas
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}Tabela Listesi - {COMMA} Tabela
+
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :Demiryolu Araçları
+STR_ELRAIL_VEHICLES :Elektrikli Trenler
+STR_MONORAIL_VEHICLES :Monoray Araçları
+STR_MAGLEV_VEHICLES :Maglev Araçları
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Fiyat: {GOLD}{CURRENCY}{BLACK} Ağırlık: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Hız: {GOLD}{VELOCITY}{BLACK} Güç: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}Hız: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Bakım: {GOLD}{CURRENCY}/sene
+STR_PURCHASE_INFO_CAPACITY :{BLACK}Kapasite: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Yapım yılı: {GOLD}{NUM}{BLACK} Ömür: {GOLD}{COMMA} sene
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}Mak. Güvenilirlik: {GOLD}%{COMMA}
+STR_PURCHASE_INFO_COST :{BLACK}Fiyat: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Ağırlık: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Fiyat: {GOLD}{CURRENCY}{BLACK} Hız: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Kapasite: {GOLD}{COMMA} yolcu, {COMMA} çanta posta
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Güç Veren Vagonlar: {GOLD}+{POWER}{BLACK} Ağırlık: {GOLD}+{WEIGHT_S}
+STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Modifiye edilebilir: {GOLD}
+STR_PURCHASE_INFO_ALL_TYPES :Tüm kargo türleri
+STR_PURCHASE_INFO_ALL_BUT :{GOLD} hariç hepsi
+STR_PURCHASE_INFO_MAX_TE :{BLACK}Mak. Çekim Gücü: {GOLD}{FORCE}
+
+########### String for New Landscape Generator
+
+STR_GENERATE :{WHITE}OluÅŸtur
+STR_RANDOM :{BLACK}Rastgele
+STR_RANDOM_HELP :{BLACK}Harita yapımı için kullanilan rastgele sayıyi değiştir
+STR_WORLD_GENERATION_CAPTION :{WHITE}Harita üretimi
+STR_RANDOM_SEED :{BLACK}Rastgele Sayı:
+STR_RANDOM_SEED_HELP :{BLACK}Rastgele bir sayı girmek için tıklayın
+STR_LAND_GENERATOR :{BLACK}Harita üretici:
+STR_TREE_PLACER :{BLACK}Ağaç algoritmasi:
+STR_HEIGHTMAP_ROTATION :{BLACK}Yükseklik haritası döndür:
+STR_TERRAIN_TYPE :{BLACK}Arazi türü:
+STR_QUANTITY_OF_SEA_LAKES :{BLACK}Deniz seviyesi:
+STR_SMOOTHNESS :{BLACK}Düzlük seviyesi:
+STR_SNOW_LINE_HEIGHT :{BLACK}Kar yüksekliği:
+STR_DATE :{BLACK}Tarih:
+STR_NUMBER_OF_TOWNS :{BLACK}Şehir sayısı:
+STR_NUMBER_OF_INDUSTRIES :{BLACK}Fabrika sayısı:
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_SNOW_LINE_UP :{BLACK}Kar yüksekliğini bir arttır
+STR_SNOW_LINE_DOWN :{BLACK}Kar yüksekliğini bir azalt
+STR_SNOW_LINE_QUERY_CAPT :{WHITE}Kar yüksekliğini değiştir
+STR_START_DATE_QUERY_CAPT :{WHITE}Başlangıç yılını değiştir
+STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Ölcek uyarısı
+STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Kaynak haritanin boyutunu değiştirmek önerilmez. Harita oluşturmaya devam edilsin mi?
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_HEIGHTMAP_NAME :{BLACK}Yükseklik haritası adı:
+STR_HEIGHTMAP_SIZE :{BLACK}Boyut: {ORANGE}{NUM} x {NUM}
+STR_GENERATION_WORLD :{WHITE}Harita oluÅŸturuluyor...
+STR_GENERATION_ABORT :{BLACK}Ä°ptal
+STR_GENERATION_ABORT_CAPTION :{WHITE}Harita Yapmayı iptal Et
+STR_GENERATION_ABORT_MESSAGE :{YELLOW}Oluşturmayı iptal etmek istediğinizden emin misiniz?
+STR_PROGRESS :{WHITE}%{NUM} tamamlandı
+STR_GENERATION_PROGRESS :{BLACK}{NUM} / {NUM}
+STR_WORLD_GENERATION :{BLACK}Harita üretimi
+STR_TREE_GENERATION :{BLACK}Ağaç üretimi
+STR_UNMOVABLE_GENERATION :{BLACK}Tasinmaz üretimi
+STR_CLEARING_TILES :{BLACK}Engebeli ve kayalik alan oluÅŸtur
+STR_SETTINGUP_GAME :{BLACK}Oyun ayarlanıyor
+STR_PREPARING_TILELOOP :{BLACK}tile-loop çalıştırılıyor
+STR_PREPARING_GAME :{BLACK}Oyun hazırlanıyor
+STR_DIFFICULTY_TO_CUSTOM :{WHITE}Bu işlem zorluk seviyesini özel'e getirdi
+STR_SE_FLAT_WORLD :{WHITE}Düzlük alan
+STR_SE_FLAT_WORLD_TIP :{BLACK}Düzlük alan oluştur
+STR_SE_RANDOM_LAND :{WHITE}Rastgele alan
+STR_SE_NEW_WORLD :{BLACK}Yeni senaryo oluÅŸtur
+STR_SE_CAPTION :{WHITE}Senaryo türü
+STR_FLAT_WORLD_HEIGHT_DOWN :{BLACK}Düzlüğü bir alçalt
+STR_FLAT_WORLD_HEIGHT_UP :{BLACK}Düzlüğün yüksekliğini bir arttır
+STR_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Düzlüğün yüksekliğini değiştir
+STR_FLAT_WORLD_HEIGHT :{BLACK}Düzlüğün Yüksekliği:
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+STR_SMALLMAP_CENTER :{BLACK}Küçük haritayı burada ortala
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}Küçük
+STR_CITY_AIRPORT :{BLACK}Şehirlerarası
+STR_METRO_AIRPORT :{BLACK}Büyükşehir havalimanı
+STR_INTERNATIONAL_AIRPORT :{BLACK}Uluslararası havalimanı
+STR_COMMUTER_AIRPORT :{BLACK}Abonman
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Kıtalararası
+STR_HELIPORT :{BLACK}Heliport
+STR_HELIDEPOT :{BLACK}Heligaraj
+STR_HELISTATION :{BLACK}Helistasyon
+
+STR_SMALL_AIRPORTS :{BLACK}Küçük havalimanları
+STR_LARGE_AIRPORTS :{BLACK}Büyük Havalimanları
+STR_HUB_AIRPORTS :{BLACK}Merkezi havalimanları
+STR_HELIPORTS :{BLACK}Helikopter havalimanları
+
+############ Tooltip measurment
+
+STR_MEASURE_LENGTH :{BLACK}Uzunluk: {NUM}
+STR_MEASURE_AREA :{BLACK}Alan: {NUM} x {NUM}
+STR_MEASURE_LENGTH_HEIGHTDIFF :{BLACK}Uzunluk: {NUM}{}Yükseklik farkı: {NUM} m
+STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}Alan: {NUM} x {NUM}{}Yükseklik farkı: {NUM} m
+
+########
diff --git a/src/lang/ukrainian.txt b/src/lang/ukrainian.txt
new file mode 100644
index 000000000..d7c144ffd
--- /dev/null
+++ b/src/lang/ukrainian.txt
@@ -0,0 +1,3113 @@
+##name Ukrainian
+##ownname УкраїнÑька
+##isocode uk_UA.UTF-8
+##plural 6
+##gender m f s
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}За межами карти
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Близько до краю карти
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}ÐедоÑтатньо коштів - потрібно {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Треба рівна ділÑнка
+STR_0008_WAITING :{BLACK}Чекає: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (перевезено з
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Приймає: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Приймає: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :паÑажирів
+STR_0010_COAL :вугіллÑ
+STR_0011_MAIL :пошту
+STR_0012_OIL :нафту
+STR_0013_LIVESTOCK :тварин
+STR_0014_GOODS :товари
+STR_0015_GRAIN :зерно
+STR_0016_WOOD :деревину
+STR_0017_IRON_ORE :залізну руду
+STR_0018_STEEL :Ñталь
+STR_0019_VALUABLES :коштовноÑÑ‚Ñ–
+STR_001A_COPPER_ORE :мідну руду
+STR_001B_MAIZE :кукурудзу
+STR_001C_FRUIT :фрукти
+STR_001D_DIAMONDS :діаманти
+STR_001E_FOOD :продукти
+STR_001F_PAPER :папір
+STR_0020_GOLD :золото
+STR_0021_WATER :воду
+STR_0022_WHEAT :пшеницю
+STR_0023_RUBBER :каучук
+STR_0024_SUGAR :цукор
+STR_0025_TOYS :іграшки
+STR_0026_CANDY :Ñолодощі
+STR_0027_COLA :Колу
+STR_0028_COTTON_CANDY :Ñолодку вату
+STR_0029_BUBBLES :бульбашки
+STR_002A_TOFFEE :іриÑ
+STR_002B_BATTERIES :батарейки
+STR_002C_PLASTIC :плаÑтик
+STR_002D_FIZZY_DRINKS :газовану воду
+STR_002E :
+STR_002F_PASSENGER :паÑажирів
+STR_0030_COAL :вугіллÑ
+STR_0031_MAIL :пошти
+STR_0032_OIL :нафти
+STR_0033_LIVESTOCK :тварин
+STR_0034_GOODS :товарів
+STR_0035_GRAIN :зерна
+STR_0036_WOOD :деревини
+STR_0037_IRON_ORE :залізної руди
+STR_0038_STEEL :Ñталі
+STR_0039_VALUABLES :коштовноÑтей
+STR_003A_COPPER_ORE :мідної руди
+STR_003B_MAIZE :кукурудзи
+STR_003C_FRUIT :фруктів
+STR_003D_DIAMOND :діамантів
+STR_003E_FOOD :продуктів
+STR_003F_PAPER :паперу
+STR_0040_GOLD :золота
+STR_0041_WATER :води
+STR_0042_WHEAT :пшениці
+STR_0043_RUBBER :каучуку
+STR_0044_SUGAR :цукру
+STR_0045_TOY :іграшок
+STR_0046_CANDY :цукерок
+STR_0047_COLA :Коли
+STR_0048_COTTON_CANDY :Ñолодкої вати
+STR_0049_BUBBLE :бульбашок
+STR_004A_TOFFEE :іриÑу
+STR_004B_BATTERY :батарейок
+STR_004C_PLASTIC :плаÑтику
+STR_004D_FIZZY_DRINK :газованої води
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} паÑажир{P "" и iв}
+STR_QUANTITY_COAL :{WEIGHT} вугіллÑ
+STR_QUANTITY_MAIL :{COMMA} Ñум{P ка ки ок} пошти
+STR_QUANTITY_OIL :{VOLUME} нафти
+STR_QUANTITY_LIVESTOCK :{COMMA} гол{P ова ови ів} тварин{P и и ""}
+STR_QUANTITY_GOODS :{COMMA} Ñщи{P к ки ків} товарів
+STR_QUANTITY_GRAIN :{WEIGHT} зерна
+STR_QUANTITY_WOOD :{WEIGHT} деревини
+STR_QUANTITY_IRON_ORE :{WEIGHT} залізної руди
+STR_QUANTITY_STEEL :{WEIGHT} Ñталі
+STR_QUANTITY_VALUABLES :{COMMA} Ñум{P ка ки ок} коштовноÑтей
+STR_QUANTITY_COPPER_ORE :{WEIGHT} мідної руди
+STR_QUANTITY_MAIZE :{WEIGHT} кукурудзи
+STR_QUANTITY_FRUIT :{WEIGHT} фруктів
+STR_QUANTITY_DIAMONDS :{COMMA} Ñум{P ка ки ок} діамантів
+STR_QUANTITY_FOOD :{WEIGHT} продуктів
+STR_QUANTITY_PAPER :{WEIGHT} паперу
+STR_QUANTITY_GOLD :{COMMA} міш{P ок ки ків} золота
+STR_QUANTITY_WATER :{VOLUME} води
+STR_QUANTITY_WHEAT :{WEIGHT} пшениці
+STR_QUANTITY_RUBBER :{VOLUME} каучуку
+STR_QUANTITY_SUGAR :{WEIGHT} цукру
+STR_QUANTITY_TOYS :{COMMA} іграш{P ка ки ок}
+STR_QUANTITY_SWEETS :{COMMA} пакун{P ок ки ків} цукерок
+STR_QUANTITY_COLA :{VOLUME} Коли
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} Ñолодкої вати
+STR_QUANTITY_BUBBLES :{COMMA} бульбаш{P ка ки ок}
+STR_QUANTITY_TOFFEE :{WEIGHT} іриÑу
+STR_QUANTITY_BATTERIES :{COMMA} батарей{P ка ки ок}
+STR_QUANTITY_PLASTIC :{VOLUME} плаÑтику
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} газованої вод{P а "" и}!!!
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}ПС
+STR_ABBREV_COAL :{TINYFONT}ВГ
+STR_ABBREV_MAIL :{TINYFONT}ПО
+STR_ABBREV_OIL :{TINYFONT}ÐФ
+STR_ABBREV_LIVESTOCK :{TINYFONT}ТВ
+STR_ABBREV_GOODS :{TINYFONT}ТО
+STR_ABBREV_GRAIN :{TINYFONT}ЗЕ
+STR_ABBREV_WOOD :{TINYFONT}ДР
+STR_ABBREV_IRON_ORE :{TINYFONT}ЗЛ
+STR_ABBREV_STEEL :{TINYFONT}СТ
+STR_ABBREV_VALUABLES :{TINYFONT}КШ
+STR_ABBREV_COPPER_ORE :{TINYFONT}МД
+STR_ABBREV_MAIZE :{TINYFONT}КУ
+STR_ABBREV_FRUIT :{TINYFONT}ФР
+STR_ABBREV_DIAMONDS :{TINYFONT}ДІ
+STR_ABBREV_FOOD :{TINYFONT}ПР
+STR_ABBREV_PAPER :{TINYFONT}ПÐ
+STR_ABBREV_GOLD :{TINYFONT}ЗО
+STR_ABBREV_WATER :{TINYFONT}ВО
+STR_ABBREV_WHEAT :{TINYFONT}ПШ
+STR_ABBREV_RUBBER :{TINYFONT}КÐ
+STR_ABBREV_SUGAR :{TINYFONT}ЦК
+STR_ABBREV_TOYS :{TINYFONT}ІГ
+STR_ABBREV_SWEETS :{TINYFONT}СЛ
+STR_ABBREV_COLA :{TINYFONT}КО
+STR_ABBREV_CANDYFLOSS :{TINYFONT}Ð’Ð
+STR_ABBREV_BUBBLES :{TINYFONT}БУ
+STR_ABBREV_TOFFEE :{TINYFONT}ІР
+STR_ABBREV_BATTERIES :{TINYFONT}БТ
+STR_ABBREV_PLASTIC :{TINYFONT}ПЛ
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}ГЗ
+STR_ABBREV_NONE :{TINYFONT}ÐÑ–
+STR_ABBREV_ALL :{TINYFONT}Ð’Ñе!!!
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Карта - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Опції ігри
+STR_00B2_MESSAGE :{YELLOW}ПовідомленнÑ
+STR_00B3_MESSAGE_FROM :{YELLOW}ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð²Ñ–Ð´ {STRING}
+STR_POPUP_CAUTION_CAPTION :{WHITE}Обережно!
+STR_00B4_CAN_T_DO_THIS :{WHITE}Ðеможливо це зробити...
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Ðеможливо очиÑтити цю ділÑнку...
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}ÐвторÑьке право {COPYRIGHT} 1995 ÐšÑ€Ñ–Ñ Ð¡Ð¾Ð¹Ñ”Ñ€, Ð’ÑÑ– права захищені
+STR_00B7_VERSION :{BLACK}OpenTTD верÑÑ–Ñ {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 OpenTTD-група
+STR_TRANSLATED_BY :{BLACK} Перекладач(і) -
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Вийти
+STR_00C8_YES :{BLACK}Так
+STR_00C9_NO :{BLACK}ÐÑ–
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Ви дійÑно бажаєте вийти до {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Ðічого
+STR_00D1_DARK_BLUE :Темно-Ñиній
+STR_00D2_PALE_GREEN :Світло-зелений
+STR_00D3_PINK :Рожевий
+STR_00D4_YELLOW :Жовтий
+STR_00D5_RED :Червоний
+STR_00D6_LIGHT_BLUE :Блакитний
+STR_00D7_GREEN :Зелений
+STR_00D8_DARK_GREEN :Темно-зелений
+STR_00D9_BLUE :Синій
+STR_00DA_CREAM :Кремовий
+STR_00DB_MAUVE :Бузковий
+STR_00DC_PURPLE :Фіолетовий
+STR_00DD_ORANGE :Помаранчевий
+STR_00DE_BROWN :Коричневий
+STR_00DF_GREY :Сірий
+STR_00E0_WHITE :Білий
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Дуже багато транÑпорту у грі
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Показати
+STR_00E5_CONTOURS :Границі
+STR_00E6_VEHICLES :Ðвто
+STR_00E7_INDUSTRIES :Виробництво
+STR_00E8_ROUTES :Маршрути
+STR_00E9_VEGETATION :РоÑлинніÑÑ‚ÑŒ
+STR_00EA_OWNERS :ВлаÑники
+STR_00EB_ROADS :{BLACK}{TINYFONT}Дороги
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Залізниці
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Станції/Ðеропорти/Порти
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Будівлі/Виробництво
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Ðвто
+STR_00F0_100M :{BLACK}{TINYFONT}100м
+STR_00F1_200M :{BLACK}{TINYFONT}200м
+STR_00F2_300M :{BLACK}{TINYFONT}300м
+STR_00F3_400M :{BLACK}{TINYFONT}400м
+STR_00F4_500M :{BLACK}{TINYFONT}500м
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Поїзди
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Ðвто
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Кораблі
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Літаки
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Маршрути
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Вугільна шахта
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}ЕлектроÑтанціÑ
+STR_00FC_FOREST :{BLACK}{TINYFONT}ЛіÑ
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}ЛіÑопилка
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Ðафтопереробний завод
+STR_00FF_FARM :{BLACK}{TINYFONT}Ферма
+STR_0100_FACTORY :{BLACK}{TINYFONT}Фабрика
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}ДрукарнÑ
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Ðафтова Ñвердловина
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Залізнорудна шахта
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Сталеварний завод
+STR_0105_BANK :{BLACK}{TINYFONT}Банк
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Паперова фабрика
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Золоторудна шахта
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Продуктовий завод
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Діамантова шахта
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Міднорудна шахта
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Фруктовий Ñад
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Каучуковий Ñад
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}ВодопоÑтачаннÑ
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Водонапірна башта
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}ЛіÑопилка
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Ð›Ñ–Ñ Ñолодкої вати
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Цукеркова фабрика
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Батарейкове поле
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Джерело Кока-Коли
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Іграшковий магазин
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Іграшкова фабрика
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}ПлаÑтикові фонтани
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Завод газованої води
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Бульбашкова фабрика
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}ІриÑковий кар'єр
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Цукрова копальнÑ
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Залізничний вокзал
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Вантажна ÑтанціÑ
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Ðвтовокзал
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Ðеропорт
+STR_011F_DOCK :{BLACK}{TINYFONT}Порт
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Ðерівна землÑ
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Трава
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}ПуÑтир
+STR_0123_FIELDS :{BLACK}{TINYFONT}ПолÑ
+STR_0124_TREES :{BLACK}{TINYFONT}Дерева
+STR_0125_ROCKS :{BLACK}{TINYFONT}КаміннÑ
+STR_0126_WATER :{BLACK}{TINYFONT}Вода
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Ðема влаÑника
+STR_0128_TOWNS :{BLACK}{TINYFONT}МіÑта
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Виробництво
+STR_012A_DESERT :{BLACK}{TINYFONT}ПуÑтелÑ
+STR_012B_SNOW :{BLACK}{TINYFONT}Сніг
+STR_012C_MESSAGE :{WHITE}ПовідомленнÑ
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Відміна
+STR_012F_OK :{BLACK}Так
+STR_0130_RENAME :{BLACK}Перейменувати
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Дуже багато імен
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Таке ім'Ñ Ð²Ð¶Ðµ Ñ”
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...влаÑніÑÑ‚ÑŒ {STRING}
+STR_013C_CARGO :{BLACK}Вантаж
+STR_013D_INFORMATION :{BLACK}ІнформаціÑ
+STR_013E_CAPACITIES :{BLACK}МіÑткіÑÑ‚ÑŒ
+STR_013E_TOTAL_CARGO :{BLACK}Повна міÑткіÑÑ‚ÑŒ
+STR_013F_CAPACITY :{BLACK}МіÑткіÑÑ‚ÑŒ: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}МіÑткіÑÑ‚ÑŒ:{LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Повна міÑткіÑÑ‚ÑŒ цього поїзду:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}Ðова гра
+STR_0141_LOAD_GAME :{BLACK}Завантажити гру
+STR_SINGLE_PLAYER :{BLACK}Один гравець
+STR_MULTIPLAYER :{BLACK}Мережна гра
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Розмір карти:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð³Ñ€Ð¸
+
+STR_0150_SOMEONE :дехто{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Карта
+STR_0152_TOWN_DIRECTORY :СпиÑок міÑÑ‚
+STR_0153_SUBSIDIES :СубÑидії
+
+STR_UNITS_IMPERIAL :ІмперÑька
+STR_UNITS_METRIC :Метрична
+STR_UNITS_SI :СІ
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} миль/год
+STR_UNITS_VELOCITY_METRIC :{COMMA} км/год
+STR_UNITS_VELOCITY_SI :{COMMA} м/Ñ
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}к.Ñ.
+STR_UNITS_POWER_METRIC :{COMMA}к.Ñ.
+STR_UNITS_POWER_SI :{COMMA}КВт
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}Ñ‚
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}Ñ‚
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}кг
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} тон{P а и ""}
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} тон{P а и ""}
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} кг
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}гал
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}л
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}м�
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} галон{P "" а ів}
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} літр{P "" а ів}
+STR_UNITS_VOLUME_LONG_SI :{COMMA} м�
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10^3 lbf
+STR_UNITS_FORCE_METRIC :{COMMA} ton force
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Прибуток виробництва
+STR_0155_INCOME_GRAPH :Графік доходів
+STR_0156_DELIVERED_CARGO_GRAPH :ДоÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð²Ð°Ð½Ñ‚Ð°Ð¶Ñ–Ð²
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Графік продуктивноÑÑ‚Ñ–
+STR_0158_COMPANY_VALUE_GRAPH :ВартіÑÑ‚ÑŒ компанії
+STR_0159_CARGO_PAYMENT_RATES :ВартіÑÑ‚ÑŒ перевезень
+STR_015A_COMPANY_LEAGUE_TABLE :Ð¢Ð°Ð±Ð»Ð¸Ñ†Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ñ–Ð¹
+STR_PERFORMANCE_DETAIL_MENU :ПродуктивніÑÑ‚ÑŒ
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}Про OpenTTD
+STR_015C_SAVE_GAME :Зберегти гру
+STR_015D_LOAD_GAME :Завантажити гру
+STR_015E_QUIT_GAME :Покинути гру
+STR_015F_QUIT :Вихід
+STR_ABANDON_GAME_QUERY :{YELLOW}Покинути гру?
+STR_0161_QUIT_GAME :{WHITE}Покинути гру
+STR_SORT_ORDER_TIP :{BLACK}Виберіть порÑдок ÑÐ¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ (Ñпадаючий/зроÑтаючий)
+STR_SORT_CRITERIA_TIP :{BLACK}Виберіть критерій ÑортуваннÑ
+STR_SORT_BY :{BLACK}Сортувати
+
+STR_SORT_BY_POPULATION :{BLACK}за наÑеленнÑм
+STR_SORT_BY_PRODUCTION :{BLACK}за виробництвом
+STR_SORT_BY_TYPE :{BLACK}за типом
+STR_SORT_BY_TRANSPORTED :{BLACK}за перевезеннÑм
+STR_SORT_BY_NAME :{BLACK}за назвою
+STR_SORT_BY_DROPDOWN_NAME :Ðазва
+STR_SORT_BY_DATE :{BLACK}за датою
+STR_SORT_BY_NUMBER :за номером
+STR_SORT_BY_PROFIT_LAST_YEAR :за прибутком минулого року
+STR_SORT_BY_PROFIT_THIS_YEAR :за прибутком цього року
+STR_SORT_BY_AGE :за віком
+STR_SORT_BY_RELIABILITY :за надійніÑÑ‚ÑŽ
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :за міÑткіÑÑ‚ÑŽ
+STR_SORT_BY_MAX_SPEED :за швидкіÑÑ‚ÑŽ
+STR_SORT_BY_MODEL :Модель
+STR_SORT_BY_VALUE :
+STR_SORT_BY_FACILITY :Вид Ñтанцій
+STR_SORT_BY_WAITING :
+STR_SORT_BY_RATING_MAX :Рейтинг вантажів
+STR_ENGINE_SORT_ENGINE_ID :ПотÑг(клаÑичне)
+STR_ENGINE_SORT_COST :Ціна
+STR_ENGINE_SORT_POWER :ПотужніÑÑ‚ÑŒ
+STR_ENGINE_SORT_INTRO_DATE :Дата випуÑку
+STR_ENGINE_SORT_RUNNING_COST :ВартіÑÑ‚ÑŒ екÑплуатації
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :ПотужніÑÑ‚ÑŒ/ВартіÑÑ‚ÑŒ екÑплуатації
+STR_ENGINE_SORT_CARGO_CAPACITY :МіÑткіÑÑ‚ÑŒ
+STR_NO_WAITING_CARGO :{BLACK}ЗвідÑи поки-що нічого перевозити
+STR_SELECT_ALL_FACILITIES :{BLACK}Вибрати веÑÑŒ транÑпорт
+STR_SELECT_ALL_TYPES :{BLACK}Вибрати вÑÑ– типи вантажів
+STR_AVAILABLE_ENGINES_TIP :{BLACK}Перелік доÑтупного транÑпорту
+STR_MANAGE_LIST :{BLACK}Редагувати ÑпиÑок
+STR_MANAGE_LIST_TIP :{BLACK}Дати Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð²Ñьому транÑпорту зі ÑпиÑку
+STR_REPLACE_VEHICLES :ОновленнÑ
+STR_SEND_TRAIN_TO_DEPOT :Відправити до депо
+STR_SEND_ROAD_VEHICLE_TO_DEPOT :Відправити до депо
+STR_SEND_SHIP_TO_DEPOT :Відправити до депо
+STR_SEND_AIRCRAFT_TO_HANGAR :Відправити в ангар
+STR_SEND_FOR_SERVICING :Відправити на техоглÑд
+
+############ range for months starts
+STR_0162_JAN :Січ
+STR_0163_FEB :Лют
+STR_0164_MAR :Бер
+STR_0165_APR :Кві
+STR_0166_MAY :Тра
+STR_0167_JUN :Чер
+STR_0168_JUL :Лип
+STR_0169_AUG :Сер
+STR_016A_SEP :Вер
+STR_016B_OCT :Жов
+STR_016C_NOV :ЛиÑ
+STR_016D_DEC :Гру
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Пауза
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Зберегти гру, покинути гру, вихід
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Показати зупинки, Ñтанції
+STR_0174_DISPLAY_MAP :{BLACK}Показати карту
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Показати карту, показати міÑта
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Показати міÑта
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}ФінанÑова інформаціÑ
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Головна інформаціÑ
+STR_0179_DISPLAY_GRAPHS :{BLACK}Показати графіки
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Показати таблицю компаній
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Показати поїзди
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Показати авто
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Показати кораблі
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Показати літаки
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Збільшити
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Зменшити
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Будувати залізниці
+STR_0182_BUILD_ROADS :{BLACK}Будувати дороги
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Будувати порти
+STR_0184_BUILD_AIRPORTS :{BLACK}Будувати аеропорти
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Садити дерева, позначити міÑце, тощо
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ земельну ділÑнку
+STR_0187_OPTIONS :{BLACK}Опції
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Ðеможна змінити інтервал обÑлуговуваннÑ...
+STR_018B_CLOSE_WINDOW :{BLACK}Закрити вікно
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Заголовок вікна - потÑгніть Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð²Ñ–ÐºÐ½Ð°
+STR_STICKY_BUTTON :{BLACK}Закріпити вікно
+STR_RESIZE_BUTTON :{BLACK}ÐатиÑніть Ñ– Ñ‚Ñгніть Ð´Ð»Ñ Ð·Ð¼Ñ–Ð½Ð¸ розміру вікна
+STR_SAVELOAD_HOME_BUTTON :{BLACK}ÐатиÑніть Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ñƒ до поточного каталогу запиÑу/завантаженнÑ
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Зруйнувати будинки, дороги і т.п.
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}ОпуÑтити ділÑнку землі
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}ПіднÑти ділÑнку землі
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Смуга прокрутки - прокручує ÑпиÑок вверх/вниз
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Смуга прокрутки - прокручує ÑпиÑок вліво/вправо
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Показати рельєф на карті
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Показати транÑпорт на карті
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Показати промиÑловіÑÑ‚ÑŒ на карті
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Показати маршрути на карті
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Показати роÑлинніÑÑ‚ÑŒ на карті
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Показати влаÑників землі на карті
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Показати назви міÑÑ‚ на карті
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Прибуток цього року: {CURRENCY} (минулого року: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} р{P ік оки оків} ({COMMA})
+STR_AGE_RED :{RED}{COMMA} р{P ік оки оків} ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Ðвто
+STR_019D_AIRCRAFT :Літак
+STR_019E_SHIP :Корабель
+STR_019F_TRAIN :Поїзд
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} зіÑтаривÑÑ
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} дуже зіÑтаривÑÑ
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} зіÑтаривÑÑ Ñ– терміново потребує заміни
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ ділÑнку
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}ВартіÑÑ‚ÑŒ очиÑтки: {LTBLUE}неможливо
+STR_01A5_COST_TO_CLEAR :{BLACK}ВартіÑÑ‚ÑŒ очиÑтки: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :немає
+STR_01A7_OWNER :{BLACK}ВлаÑник: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}МіÑцева влада: {LTBLUE}{STRING}
+STR_01A9_NONE :немає
+STR_01AA_NAME :{BLACK}Ðазва
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1
+STR_01AD_2ND :2
+STR_01AE_3RD :3
+STR_01AF_4TH :4
+STR_01B0_5TH :5
+STR_01B1_6TH :6
+STR_01B2_7TH :7
+STR_01B3_8TH :8
+STR_01B4_9TH :9
+STR_01B5_10TH :10
+STR_01B6_11TH :11
+STR_01B7_12TH :12
+STR_01B8_13TH :13
+STR_01B9_14TH :14
+STR_01BA_15TH :15
+STR_01BB_16TH :16
+STR_01BC_17TH :17
+STR_01BD_18TH :18
+STR_01BE_19TH :19
+STR_01BF_20TH :20
+STR_01C0_21ST :21
+STR_01C1_22ND :22
+STR_01C2_23RD :23
+STR_01C3_24TH :24
+STR_01C4_25TH :25
+STR_01C5_26TH :26
+STR_01C6_27TH :27
+STR_01C7_28TH :28
+STR_01C8_29TH :29
+STR_01C9_30TH :30
+STR_01CA_31ST :31
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Приймає: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Музичний програвач
+STR_01D3_SOUND_MUSIC :Звук/Музика
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Ðалаштувати звук/музику
+STR_01D5_ALL :{TINYFONT}Ð’ÑÑ–
+STR_01D6_OLD_STYLE :{TINYFONT}Старі теми
+STR_01D7_NEW_STYLE :{TINYFONT}Ðові теми
+STR_01D8_EZY_STREET :{TINYFONT}Дорожні теми
+STR_01D9_CUSTOM_1 :{TINYFONT}Ðабір 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Ðабір 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}ГучніÑÑ‚ÑŒ музики
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}ГучніÑÑ‚ÑŒ ефектів
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}Мін ' ' ' ' ' ' МакÑ
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}ПопереднÑ
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}ÐаÑтупна
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Зупинити
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Почати
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}ПотÑгніть повзунок Ð´Ð»Ñ Ð·Ð¼Ñ–Ð½Ð¸ Ñ€Ñ–Ð²Ð½Ñ Ð³ÑƒÑ‡Ð½Ð¾ÑÑ‚Ñ–
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Доріжка{SETX 88}Заголовок
+STR_01E9_SHUFFLE :{TINYFONT}Випадково
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Програма
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Вибір музичної програми
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Ðазва доріжки
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Програма - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}ОчиÑтити
+STR_01F1_SAVE :{TINYFONT}{BLACK}Зберегти
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Запрограмовані доріжки
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Вибрати програму 'вÑÑ–'
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Вибрати 'Ñтарі теми'
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Вибрати 'нові теми'
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Вибрати програму 'Ðабір 1'
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Вибрати програму 'Ðабір 2'
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}ОчиÑтити програму (тільки Ð´Ð»Ñ Ðабору 1 або Ðабору 2)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Зберегти Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¼ÑƒÐ·Ð¸ÐºÐ¸
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Виберіть доріжку, щоб додати до програми (тільки Ð´Ð»Ñ Ðабору 1 або Ðабору 2)
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Клікніть мишою на назві мелодії Ð´Ð»Ñ Ñ—Ñ— Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð·Ñ– ÑпиÑку (лише Ðабір1 та Ðабір2)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Вкл/викл випадкову програму
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Показує вікно вибору музичної програми
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}ÐатиÑніть Ð´Ð»Ñ Ð¿Ð¾ÐºÐ°Ð·Ñƒ в центрі екрану
+STR_01FE_DIFFICULTY :{BLACK}СкладніÑÑ‚ÑŒ ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :ОÑтаннє повідомленнÑ
+STR_0201_MESSAGE_SETTINGS :ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½ÑŒ
+STR_MESSAGE_HISTORY_MENU :ІÑÑ‚Ð¾Ñ€Ñ–Ñ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½ÑŒ
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Показати оÑтаннє повідомленнÑ. ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½ÑŒ
+STR_0204_MESSAGE_OPTIONS :{WHITE}ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½ÑŒ
+STR_0205_MESSAGE_TYPES :{BLACK}Типи повідомлень:-
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}ÐŸÑ€Ð¸Ð±ÑƒÑ‚Ñ‚Ñ Ð¿ÐµÑ€ÑˆÐ¾Ð³Ð¾ транÑпорту на Ñтанцію гравцÑ
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}ÐŸÑ€Ð¸Ð±ÑƒÑ‚Ñ‚Ñ Ð¿ÐµÑ€ÑˆÐ¾Ð³Ð¾ транÑпорту на Ñтанцію конкурента
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}ÐещаÑні випадки/Стихійні лиха
+STR_0209_COMPANY_INFORMATION :{YELLOW}Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ñ–Ñ—
+STR_020A_ECONOMY_CHANGES :{YELLOW}Зміни в економіці
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Поради/рекомендацї щодо транÑпорту гравцÑ
+STR_020C_NEW_VEHICLES :{YELLOW}Ðовий транÑпорт
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Зміни в попиті на перевезеннÑ
+STR_020E_SUBSIDIES :{YELLOW}СубÑидії
+STR_020F_GENERAL_INFORMATION :{YELLOW}Загальна інформаціÑ
+STR_MESSAGES_ALL :{YELLOW}Відображати Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ /Коротко/Повно/Викл
+STR_MESSAGE_SOUND :{YELLOW}Звукове ÑÐ¿Ð¾Ð²Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ð¿Ñ–Ð´Ñумкових новин
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...дуже далеко від попереднього пункту призначеннÑ
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Кращі компанії що доÑÑгли {NUM}{}({STRING} рівнÑ)
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Ð¢Ð°Ð±Ð»Ð¸Ñ†Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ñ–Ð¹ з {NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :БізнеÑмен
+STR_0214_ENTREPRENEUR :Підприємець
+STR_0215_INDUSTRIALIST :ПромиÑловець
+STR_0216_CAPITALIST :КапіталіÑÑ‚
+STR_0217_MAGNATE :Магнат
+STR_0218_MOGUL :Магнат року
+STR_0219_TYCOON_OF_THE_CENTURY :Магнат ÑторіччÑ
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} доÑÑгла ÑтатуÑу '{STRING}'!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}Гравець {PLAYERNAME} з {COMPANY} доÑÑг ÑтатуÑу '{STRING}'
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Створити Ñценарій
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Редактор Ñценарію
+STR_0223_LAND_GENERATION :{WHITE}Створити ландшафт
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Випадковий ландшафт
+STR_0227_RESET_LAND :{BLACK}ОчиÑтити ділÑнку
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Збільшити облаÑÑ‚ÑŒ ділÑнки Ð´Ð»Ñ Ð¿Ñ–Ð´Ð½ÑÑ‚Ñ‚Ñ/опуÑканнÑ
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Зменшити облаÑÑ‚ÑŒ ділÑнки Ð´Ð»Ñ Ð¿Ñ–Ð´Ð½ÑÑ‚Ñ‚Ñ/опуÑканнÑ
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Створити випадкову ділÑнку
+STR_022B_RESET_LANDSCAPE :{BLACK}ОчиÑтити ландшафт
+STR_022C_RESET_LANDSCAPE :{WHITE}ОчиÑтити ландшафт
+STR_LOAD_GAME_HEIGHTMAP :{WHITE}ВикортÑтовувати рельєф
+STR_LOAD_SCEN_HEIGHTMAP :{BLACK}ВзÑти з карти виÑот
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Ви дійÑно бажаєте очиÑтити ландшафт?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð»Ð°Ð½Ð´ÑˆÐ°Ñ„Ñ‚Ñƒ
+STR_022F_TOWN_GENERATION :{BLACK}Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¼Ñ–ÑÑ‚
+STR_0230_INDUSTRY_GENERATION :{BLACK}Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð²Ð¸Ñ€Ð¾Ð±Ð½Ð¸Ñ†Ñ‚Ð²Ð°
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Будівництво доріг
+STR_0233_TOWN_GENERATION :{WHITE}Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¼Ñ–ÑÑ‚
+STR_0234_NEW_TOWN :{BLACK}Ðове міÑто
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Будувати нове міÑто
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Тут не можна будувати міÑто...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...близько до краю карти
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...близько до іншого міÑта
+STR_0239_SITE_UNSUITABLE :{WHITE}...невідповідне міÑце
+STR_023A_TOO_MANY_TOWNS :{WHITE}...забагато міÑÑ‚
+STR_CANNOT_GENERATE_TOWN :{WHITE}Ðе можна Ñтворити міÑто
+STR_NO_SPACE_FOR_TOWN :{WHITE}...Ðа карті немає вільного міÑцÑ
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Збільшити розмір міÑта
+STR_023C_EXPAND :{BLACK}Розширити
+STR_023D_RANDOM_TOWN :{BLACK}Випадкове міÑто
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Будувати міÑто у випадковому міÑці
+STR_023F_INDUSTRY_GENERATION :{WHITE}Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð²Ð¸Ñ€Ð¾Ð±Ð½Ð¸Ñ†Ñ‚Ð²Ð°
+STR_0240_COAL_MINE :{BLACK}Вугільна шахта
+STR_0241_POWER_STATION :{BLACK}ЕлектроÑтанціÑ
+STR_0242_SAWMILL :{BLACK}ЛіÑопилка
+STR_0243_FOREST :{BLACK}ЛіÑ
+STR_0244_OIL_REFINERY :{BLACK}Ðафтопереробний завод
+STR_0245_OIL_RIG :{BLACK}Ðафтова платформа
+STR_0246_FACTORY :{BLACK}Фабрика
+STR_0247_STEEL_MILL :{BLACK}Сталеварний завод
+STR_0248_FARM :{BLACK}Ферма
+STR_0249_IRON_ORE_MINE :{BLACK}Залізорудна шахта
+STR_024A_OIL_WELLS :{BLACK}Ðафтова Ñвердловина
+STR_024B_BANK :{BLACK}Банк
+STR_024C_PAPER_MILL :{BLACK}Паперова фабрика
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Продуктовий завод
+STR_024E_PRINTING_WORKS :{BLACK}ДрукарнÑ
+STR_024F_GOLD_MINE :{BLACK}Золоторудна шахта
+STR_0250_LUMBER_MILL :{BLACK}ЛіÑопилка
+STR_0251_FRUIT_PLANTATION :{BLACK}Фруктовий Ñад
+STR_0252_RUBBER_PLANTATION :{BLACK}Каучуковий Ñад
+STR_0253_WATER_SUPPLY :{BLACK}ВодопоÑтачаннÑ
+STR_0254_WATER_TOWER :{BLACK}Водонапірна башта
+STR_0255_DIAMOND_MINE :{BLACK}Діамантова шахта
+STR_0256_COPPER_ORE_MINE :{BLACK}Міднорудна шахта
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Ð›Ñ–Ñ Ñолодкої вати
+STR_0258_CANDY_FACTORY :{BLACK}Цукеркова фабрика
+STR_0259_BATTERY_FARM :{BLACK}Батарейкове поле
+STR_025A_COLA_WELLS :{BLACK}Джерело Кока-коли
+STR_025B_TOY_SHOP :{BLACK}Іграшковий магазин
+STR_025C_TOY_FACTORY :{BLACK}Іграшкова фабрика
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}ПлаÑтикові фонтани
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Фабрика газованої води
+STR_025F_BUBBLE_GENERATOR :{BLACK}Бульбашкова фабрика
+STR_0260_TOFFEE_QUARRY :{BLACK}ІриÑковий кар'єр
+STR_0261_SUGAR_MINE :{BLACK}Цукрова копальнÑ
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Будувати вугільну шахту
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Будувати електроÑтанцію
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Будувати ліÑопилку
+STR_0265_PLANT_FOREST :{BLACK}ПоÑадити ліÑ
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Будувати нафтопереробний завод
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Будувати нафтову платформу (тільки Ð±Ñ–Ð»Ñ ÐºÑ€Ð°ÑŽ карти)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Будувати фабрику
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}БудуватиÑталеварний завод
+STR_026A_CONSTRUCT_FARM :{BLACK}Будувати ферму
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Будувати залізорудну шахту
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Будувати нафтову Ñвердловину
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Будувати банк (тільки у міÑтах з наÑеленнÑм більше 1200)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Будувати паперову фабоику
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Будувати продуктовий завод
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Будувати друкарню
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Будувати золоторудну шахту
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Будувати банк (тільки у міÑтах з наÑеленнÑм більше 1200)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Будувати ліÑопилку (Ð´Ð»Ñ Ð²Ð¸Ñ€ÑƒÐ±ÐºÐ¸ ліÑу Ñ– виробництва деревини)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}ПоÑадити фруктовий Ñад
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}ПоÑадити каучуковий Ñад
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Будувати водопоÑтачаннÑ
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Будувати водонапірна башту (тільки у міÑтах)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Будувати діамантову шахту
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Будувати міднорудну шахту
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}ПоÑадити Ð»Ñ–Ñ Ñолодкої вати
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Будувати цукеркову фабрику
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}ПоÑадити батарейкове поле
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Будувати джерело Кока-коли
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Будувати іграшковий магазин
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Будувати іграшкову фабрику
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Будувати плаÑтикові фонтани
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Будувати завод газованої води
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Будувати бульбашкову фабрику
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Будувати іриÑковий кар'єр
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Будувати цукрову копальню
+STR_0285_CAN_T_BUILD_HERE :{WHITE}Ðеможливо будувати {STRING} тут...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...Ñпочатку збудуйте міÑто
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...дозволÑєтьÑÑ Ñ‚Ñ–Ð»ÑŒÐºÐ¸ 1 у міÑÑ‚Ñ–
+STR_0288_PLANT_TREES :{BLACK}ÐаÑÐ°Ð´Ð¶ÐµÐ½Ð½Ñ Ð´ÐµÑ€ÐµÐ²
+STR_0289_PLACE_SIGN :{BLACK}Позначити міÑце
+STR_028A_RANDOM_TREES :{BLACK}Випадкові дерева
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}ÐаÑÐ°Ð´Ð¶ÐµÐ½Ð½Ñ Ð´ÐµÑ€ÐµÐ² випадково
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Ð Ð¾Ð·Ð¼Ñ–Ñ‰ÐµÐ½Ð½Ñ ÐºÐ°Ð¼'Ñних ділÑнок
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}ПоÑтавити маÑк
+STR_028E_PLACE_TRANSMITTER :{BLACK}ПоÑтавити ретранÑлÑтор
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Позначити територію пуÑтелі.{}ÐатиÑніть Ñ– утримуйте CTRL, щоб відмінити
+STR_CREATE_LAKE :{BLACK}Позначити територію води.{}ЗаповнитьÑÑ Ð²Ð¾Ð´Ð¾ÑŽ, Ñкщо на рівні морÑ
+STR_0290_DELETE :{BLACK}Видалити
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Видалити міÑто повніÑÑ‚ÑŽ
+STR_0292_SAVE_SCENARIO :Зберегти Ñценарій
+STR_0293_LOAD_SCENARIO :Завантажити Ñценарій
+STR_0294_QUIT_EDITOR :Вийти з редактору
+STR_0295 :
+STR_0296_QUIT :Вихід
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Зберегти Ñценарій, завантажити Ñценарій, вийти з редактору Ñценарію, вихід
+STR_0298_LOAD_SCENARIO :{WHITE}Завантажити Ñценарій
+STR_0299_SAVE_SCENARIO :{WHITE}Зберегти Ñценарій
+STR_029A_PLAY_SCENARIO :{BLACK}Грати за Ñценарієм
+STR_PLAY_HEIGHTMAP :{BLACK}Грати з карти виÑот
+STR_PLAY_HEIGHTMAP_HINT :{BLACK}Почати нову гру, викориÑтавши карту виÑот за ландшафт
+STR_QUIT_SCENARIO_QUERY :{YELLOW}Ви дійÑно бажаєти вийти з Ñценарію?
+STR_029C_QUIT_EDITOR :{WHITE}Вихід з редактору
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...можливо будувати лише у міÑтах з наÑÐµÐ»ÐµÐ½Ð½Ñ Ð½Ðµ менш 1200
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}ПеренеÑти початкову дату на 1 рік назад
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}ПеренеÑти початкову дату на 1 рік вперед
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...кінці моÑту мають бути на землі
+STR_02A1_SMALL :{BLACK}Мале
+STR_02A2_MEDIUM :{BLACK}Середнє
+STR_02A3_LARGE :{BLACK}Велике
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Вибір розміру міÑта
+STR_02A5_TOWN_SIZE :{YELLOW}Розмір міÑта:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Показує оÑтаннє Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð°Ð±Ð¾ новини
+STR_OFF :Викл
+STR_SUMMARY :Коротко
+STR_FULL :ПовніÑÑ‚ÑŽ
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :СпиÑок міÑÑ‚
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Ðазви транÑпорту
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Стандартні
+STR_02BF_CUSTOM :ВлаÑні
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Зберегти влаÑні назви
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Задати назви транÑпортним заÑобам
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Зберегти задані назви транÑпортних заÑобів
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð³Ñ€Ð¸
+STR_02C5_DIFFICULTY_SETTINGS :ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÑкладноÑÑ‚Ñ–
+STR_02C7_CONFIG_PATCHES :Розширені налаштуваннÑ4
+STR_NEWGRF_SETTINGS :Ðова графіка
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Показ назви міÑÑ‚
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Показ назви Ñтанцій
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Показ позначеннÑ
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Показ точки маршруту
+STR_02D0_FULL_ANIMATION :{SETX 12}Повна анімаціÑ
+STR_02D2_FULL_DETAIL :{SETX 12}Повна деталізаціÑ
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Прозорі будівлі
+STR_TRANSPARENT_SIGNS :{SETX 12}Прозорі назви Ñтанцій
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ ділÑнку
+STR_02D6 :
+STR_CONSOLE_SETTING :Вкл/викл конÑоль
+STR_02D7_SCREENSHOT_CTRL_S :ÐšÐ¾Ð¿Ñ–Ñ ÐµÐºÑ€Ð°Ð½Ñƒ (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :ÐšÐ¾Ð¿Ñ–Ñ Ð²Ñієї карти (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :Про гру 'OpenTTD'
+############ range ends here
+
+STR_02DB_OFF :{BLACK}Викл
+STR_02DA_ON :{BLACK}Вкл
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Показати ÑубÑидії
+STR_02DD_SUBSIDIES :СубÑидії
+STR_02DE_MAP_OF_WORLD :Карта Ñвіту
+STR_EXTRA_VIEW_PORT :Додаткове вікно
+STR_SIGN_LIST :СпиÑок позначень
+STR_02DF_TOWN_DIRECTORY :СпиÑок міÑÑ‚
+STR_TOWN_POPULATION :{BLACK}ÐаÑÐµÐ»ÐµÐ½Ð½Ñ Ñвіту: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Вікно {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Копіювати до вікна
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Копіювати міÑÑ†ÐµÐ¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð½Ñ Ð· оÑновного екрану до цього вікна
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Перейти з вікна
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Перейти на оÑновному екрані до цього міÑцÑ
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Грошова одиницÑ
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Виберіть грошову одиницю
+STR_MEASURING_UNITS :{BLACK}Одиниці виміру
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Вибір одиниць виміру
+STR_02E6_ROAD_VEHICLES :{BLACK}ÐапрÑмок руху
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Виберіть по Ñкій Ñтороні їхатиме транÑпорт
+STR_02E9_DRIVE_ON_LEFT :ЛівоÑторонній
+STR_02EA_DRIVE_ON_RIGHT :ПравоÑторонній
+STR_02EB_TOWN_NAMES :{BLACK}Ðазви міÑÑ‚
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Виберіть Ñтиль назв міÑÑ‚
+
+STR_02F4_AUTOSAVE :{BLACK}ÐвтозбереженнÑ
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Виберіть період Ð°Ð²Ñ‚Ð¾Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ð³Ñ€Ð¸
+STR_02F7_OFF :Вимкнено
+STR_02F8_EVERY_3_MONTHS :Кожні три міÑÑці
+STR_02F9_EVERY_6_MONTHS :Кожні півроку
+STR_02FA_EVERY_12_MONTHS :Щороку
+STR_02FB_START_A_NEW_GAME :{BLACK}Почати нову гру
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Продовжити збережену гру
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Створити Ñвій Ñценарій
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Грати одному
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Грати з 2-8 гравцÑми
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Показати Ð½Ð°Ð»Ð°ÑˆÑƒÐ²Ð°Ð½Ð½Ñ Ð³Ñ€Ð¸
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Показати Ð½Ð°Ð»Ð°ÑˆÑƒÐ²Ð°Ð½Ð½Ñ ÑкладноÑÑ‚Ñ–
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Почати нову викориÑтовуючи Ñценарій
+STR_0304_QUIT :{BLACK}Вихід
+STR_0305_QUIT_OPENTTD :{BLACK}покинути 'OpenTTD'
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...можна збудувати лише в міÑтах
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Вибрати 'помірний' клімат
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Вибрати 'Ñубарктичний' клімат
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Вибрати 'тропічний' клімат
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Вибрати 'іграшковий' варіант
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}ФінанÑувати будівництво нової промиÑловоÑÑ‚Ñ–
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Каталог промиÑловоÑÑ‚Ñ–
+STR_0313_FUND_NEW_INDUSTRY :Ðова промиÑловіÑÑ‚ÑŒ
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Ðову промиÑловіÑÑ‚ÑŒ
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...можна будувати лише у міÑтах
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...можна будувати лише у джунглÑÑ…
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...можна будувати лише у пуÑтелі
+STR_0319_PAUSED :{YELLOW}* * ПÐУЗР* *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Екран збережено в '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}Помилка Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ ÐµÐºÑ€Ð°Ð½Ñƒ!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Купити ділÑнку Ð´Ð»Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Ñƒ майбутньому
+STR_032F_AUTOSAVE :{RED}ÐвтозбереженнÑ
+STR_SAVING_GAME :{RED}* * ЗБЕРЕЖЕÐÐЯ ГРИ * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}ЗбереженнÑ...,{}зачекайте поки завершитьÑÑ!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Вибрати програму 'Дорожні теми'
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :ÐнглійÑькі(Оригінальні)
+STR_TOWNNAME_FRENCH :Французькі
+STR_TOWNNAME_GERMAN :Ðімецькі
+STR_TOWNNAME_ADDITIONAL_ENGLISH :ÐнглійÑькі(Додаткові)
+STR_TOWNNAME_LATIN_AMERICAN :Латино-ÐмериканÑькі
+STR_TOWNNAME_SILLY :Кумедні
+STR_TOWNNAME_SWEDISH :ШведÑькі
+STR_TOWNNAME_DUTCH :ГолландÑькі
+STR_TOWNNAME_FINNISH :ФінÑькі
+STR_TOWNNAME_POLISH :ПольÑькі
+STR_TOWNNAME_SLOVAKISH :Словацькі
+STR_TOWNNAME_NORWEGIAN :ÐорвежÑькі
+STR_TOWNNAME_HUNGARIAN :УгорÑькі
+STR_TOWNNAME_AUSTRIAN :ÐвÑтрійÑькі
+STR_TOWNNAME_ROMANIAN :РумунÑькі
+STR_TOWNNAME_CZECH :ЧеÑькі
+STR_TOWNNAME_SWISS :ШвейцарÑькі
+STR_TOWNNAME_DANISH :ДатÑькі
+STR_TOWNNAME_TURKISH :Турецький
+STR_TOWNNAME_ITALIAN :ІталійÑькі
+STR_TOWNNAME_CATALAN :КаталанÑькі
+############ end of townname region
+
+STR_CURR_GBP :Фунт
+STR_CURR_USD :Долар
+STR_CURR_EUR :Євро
+STR_CURR_YEN :Йєна
+STR_CURR_ATS :ÐвÑтрійÑький шиллінг
+STR_CURR_BEF :БельгійÑький франк
+STR_CURR_CHF :ШвейцарÑький франк
+STR_CURR_CZK :ЧешÑька крона
+STR_CURR_DEM :Ðімецька марка
+STR_CURR_DKK :ДатÑька крона
+STR_CURR_ESP :ПеÑета
+STR_CURR_FIM :ФінÑька марка
+STR_CURR_FRF :Франк
+STR_CURR_GRD :Грецька драхма
+STR_CURR_HUF :УгорÑький форінт
+STR_CURR_ISK :ІÑландÑька крона
+STR_CURR_ITL :ІталійÑька ліра
+STR_CURR_NLG :ГолландÑький гульден
+STR_CURR_NOK :ÐорвежÑька крона
+STR_CURR_PLN :ПольÑький злотий
+STR_CURR_ROL :РумунÑький лей
+STR_CURR_RUR :РоÑійÑький рубль
+STR_CURR_SIT :СловенÑький Талер (SIT)
+STR_CURR_SEK :ШведÑька крона
+STR_CURR_YTL :Турецька ліра (YTL)
+STR_CURR_SKK :Словацька крона (SKK)
+STR_CURR_BRR :БразильÑький реал (BRL)
+
+STR_CURR_CUSTOM :Вибрана...
+
+STR_OPTIONS_LANG :{BLACK}Мова
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Виберіть мову Ð´Ð»Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑтаннÑ
+
+STR_OPTIONS_FULLSCREEN :{BLACK}В повний екран
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}ÐатиÑніть цю кнопку щоб грати в повний екран
+
+STR_OPTIONS_RES :{BLACK}Роздільна здатніÑÑ‚ÑŒ
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Виберіть роздільну здатніÑÑ‚ÑŒ екрану
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Формат копій екрану
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Виберіть формат Ð´Ð»Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ¾Ð¿Ñ–Ð¹ екрану
+
+STR_AUTOSAVE_1_MONTH :ЩоміÑÑцÑ
+STR_AUTOSAVE_FAILED :{WHITE}Помилка автозбереженнÑ
+
+STR_MONTH_JAN :Січень
+STR_MONTH_FEB :Лютий
+STR_MONTH_MAR :Березень
+STR_MONTH_APR :Квітень
+STR_MONTH_MAY :Травень
+STR_MONTH_JUN :Червень
+STR_MONTH_JUL :Липень
+STR_MONTH_AUG :Серпень
+STR_MONTH_SEP :ВереÑень
+STR_MONTH_OCT :Жовтень
+STR_MONTH_NOV :ЛиÑтопад
+STR_MONTH_DEC :Грудень
+
+STR_HEADING_FOR_STATION :{LTBLUE}ПрÑмує до {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}ПрÑмує до {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Ðема завдань
+STR_NO_ORDERS_VEL :{LTBLUE}Ðема завдань, {VELOCITY}
+
+STR_PASSENGERS :паÑÐжир
+STR_BAGS :
+STR_TONS :тонИ
+STR_LITERS :літрів
+STR_ITEMS :штуК
+STR_CRATES :ЯщикИ
+STR_RES_OTHER :іншЕ
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Ðеможливо розділити ÑпиÑок завдань...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Ðеможливо Ñкопіювати ÑпиÑок завдань...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - Кінець наказів - -
+
+STR_TRAIN_IS_LOST :{WHITE}Поїзд {COMMA} заблукав.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}Поїзд {COMMA} Ð¿Ñ€Ð¸Ð½Ñ–Ñ Ð¿Ñ€Ð¸Ð±ÑƒÑ‚Ð¾Ðº минулого року {CURRENCY}
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}ЄвропейÑька грошова одиницÑ!{}{}У вашій країні введено євро - єдину валюту Ð´Ð»Ñ Ñ€Ð¾Ð·Ñ€Ð°Ñ…ÑƒÐ½ÐºÑ–Ð²!
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Поїзд {COMMA} має дуже мало завдань
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}Поїзд {COMMA} має пуÑтий наказ
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}Поїзд {COMMA} має подвійні накази
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}Поїзд {COMMA} має в наказі невірну Ñтанцію
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}Ðвто {COMMA} має дуже мало завдань
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}Ðвто {COMMA} має пуÑтий наказ
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}Ðвто {COMMA} має подвійні накази
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}Ðвто {COMMA} має в наказі невірну Ñтанцію
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}Корабель {COMMA} має дуже мало завдань
+STR_SHIP_HAS_VOID_ORDER :{WHITE}Корабель {COMMA} має пуÑтий наказ
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}Корабель {COMMA} має подвійні накази
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}Корабель {COMMA} має в наказі невірну Ñтанцію
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}Літак {COMMA} має дуже мало завдань
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}Літак {COMMA} має пуÑтий наказ
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}Літак {COMMA} має подвійні накази
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}Літак {COMMA} має в наказі невірну Ñтанцію
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}Помилка Ð°Ð²Ñ‚Ð¾Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ—Ð·Ð´Ð° {COMMA} (бракує коштів)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}Помилка Ð°Ð²Ñ‚Ð¾Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð°Ð²Ñ‚Ð¾ {COMMA} (бракує коштів)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}Помилка Ð°Ð²Ñ‚Ð¾Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ ÐºÐ¾Ñ€Ð°Ð±Ð»Ñ {COMMA} (бракує коштів)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}Помилка Ð°Ð²Ñ‚Ð¾Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð»Ñ–Ñ‚Ð°ÐºÐ° {COMMA} (бракує коштів)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}Поїзд {COMMA} дуже довгий піÑÐ»Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ
+
+STR_CONFIG_PATCHES :{BLACK}Розширені налаштуваннÑ1
+STR_CONFIG_PATCHES_TIP :{BLACK}Розширені налаштуваннÑ2
+STR_CONFIG_PATCHES_CAPTION :{WHITE}Розширені налаштуваннÑ3
+
+STR_CONFIG_PATCHES_OFF :Викл.
+STR_CONFIG_PATCHES_ON :Вкл.
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Показувати швидкіÑÑ‚ÑŒ у Ñтрокі Ñтану: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Будувати на Ñхилах та узбережжÑÑ…: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Великий району обÑлуговуваннÑ: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Переміщувати дороги, моÑти та іншу влаÑніÑÑ‚ÑŒ міÑта: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Будувати дуже довгі поїзди: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}РеаліÑтичне приÑÐºÐ¾Ñ€ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ—Ð·Ð´Ñ–Ð²: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Поїздам Ñ– кораблÑм повертати на 90 град.: {ORANGE}{STRING} {LTBLUE} (треба NPF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Будувати Ñуміжні залізничні Ñтанції: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Від'їжджати при повному завантажені будь-Ñкого вантажу: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}ВикориÑтовувати покращений алгоритм завантаженнÑ: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GRADUAL_LOADING :{LTBLUE}Завантажувати поÑтупово: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}ІнфлÑціÑ: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}ДоÑтавлÑти вантаж за умови, що там приймаєтьÑÑ: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Будувати дуже довгі моÑти: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Ðаказувати прÑмувати в депо: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Будувати виробництво Ñировини: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Подібна промиÑловіÑÑ‚ÑŒ в одному міÑÑ‚Ñ–: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Будувати промиÑловіÑÑ‚ÑŒ однакового типу поруч: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Завжди показувати повну дату в Ñтрокі Ñтану: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Показувати Ñигнали за напрÑмом руху: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Показувати вікно фінанÑів в кінці року: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}TTDPatch compatible nonstop handling: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Ставати транÑпорту в чергу: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Прокручувати вікно коли курÑор з краю: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Дозволити підкуплÑти міÑцеву владу: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Ðеоднорідні Ñтанції: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Ðовий глобальний пошук шлÑху(NPF, заміÑÑ‚ÑŒ NTP): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FREIGHT_TRAINS :{LTBLUE}Множник ваги Ð´Ð»Ñ Ñ–Ð¼Ñ–Ñ‚Ð°Ñ†Ñ–Ñ— важких потÑгів: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Завжди будувати малі аеропорти: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}ПовідомлÑти, коли поїзд загубивÑÑ {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Показ транÑпортних наказів: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :ні
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :так, крім зупиненого транÑпорту
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :уÑього транÑпорту
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Попереджати Ñкщо поїзд приноÑить збитки: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}ТранÑпорт не Ñтаріє: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}ÐÐ²Ñ‚Ð¾Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ñтарого транÑпорту
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}ÐÐ²Ñ‚Ð¾Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ñ‚Ñ€Ð°Ð½Ñпорту через {ORANGE}{STRING}{LTBLUE} міÑ. до/піÑÐ»Ñ Ð¼Ð°ÐºÑ.віку
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Ðеобхідна Ñума Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}ТриваліÑÑ‚ÑŒ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ помилку: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Показувати наÑÐµÐ»ÐµÐ½Ð½Ñ Ð¼Ñ–Ñта поруч з назвою: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Ðевидимі дерева Ñ– прозорі будівлі: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Генератор ландшафту: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :КлаÑичний
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :ТерраГен
+STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}ÐœÐ°ÐºÑ Ð²Ñ–Ð´Ð´Ð°Ð»ÐµÐ½Ñ–ÑÑ‚ÑŒ від нафтової Ñвердловини {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}ВиÑота Ñ€Ñ–Ð²Ð½Ñ Ñнігу: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN :{LTBLUE}ÐерівніÑÑ‚ÑŒ землі (лише Ð´Ð»Ñ TerraGenesis) : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Дуже гладкий
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH :Гладкий
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH :Грубий
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :Дуже грубий
+STR_CONFIG_PATCHES_TREE_PLACER :{LTBLUE}Ðлгоритм наÑÐ°Ð´Ð¶ÐµÐ½Ð½Ñ Ð´ÐµÑ€ÐµÐ²: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TREE_PLACER_NONE :Ðема
+STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL :КлаÑичний
+STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED :Покращений
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION :{LTBLUE}ÐžÐ±ÐµÑ€Ñ‚Ð°Ð½Ð½Ñ ÐºÐ°Ñ€Ñ‚Ð¸ виÑот: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Проти годинниковї
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE :За годинниковою
+STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT :{LTBLUE}Рівень виÑоти Ð´Ð»Ñ ÐºÐ°Ñ€Ñ‚ з плоÑким рельєфом: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}МакÑ. довжина Ñтанції: {ORANGE}{STRING} {RED}Велике Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð³Ð°Ð»ÑŒÐ¼ÑƒÑ” гру
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Ðвтоматичний техоглÑд гелікоптерів на площадках: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Включити меню рельєфу до меню будуваннÑ: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Протилежний напрÑмок прокрутки: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Показувати розміри будівництва в підÑказці: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Показати кольори компаній: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES_NONE :Жодна
+STR_CONFIG_PATCHES_LIVERIES_OWN :ÐœÐ¾Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ñ–Ñ
+STR_CONFIG_PATCHES_LIVERIES_ALL :Ð’ÑÑ– компанії
+STR_CONFIG_PATCHES_PREFER_TEAMCHAT :{LTBLUE}Командний чат по <ENTER>: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}МакÑ. поїздів у гравцÑ: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}МакÑ. авто у гравцÑ: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}МакÑ. літаків у гравцÑ: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}МакÑ. кораблів у гравцÑ: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Комп'ютер не будує потÑги: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Комп'ютер не будує авто: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Комп'ютер не будує літаки: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Комп'ютер не будує кораблі: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Ðовий тип інтелекту (альфа): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Включити інтелект при грі в мережі(теÑтовий): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Інтервал техоглÑду Ð´Ð»Ñ Ð¿Ð¾Ñ—Ð·Ð´Ñ–Ð²: {ORANGE}{STRING} дн/%
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Інтервал техоглÑду Ð´Ð»Ñ Ð¿Ð¾Ñ—Ð·Ð´Ñ–Ð²: {ORANGE}без тех.оглÑду
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Інтервал техоглÑду Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾: {ORANGE}{STRING} дн/%
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Інтервал техоглÑду Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾: {ORANGE}без тех.оглÑду
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Інтервал техоглÑду Ð´Ð»Ñ Ð»Ñ–Ñ‚Ð°ÐºÑ–Ð²: {ORANGE}{STRING} дн/%
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Інтервал техоглÑду Ð´Ð»Ñ Ð»Ñ–Ñ‚Ð°ÐºÑ–Ð²: {ORANGE}без тех.оглÑду
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Інтервал техоглÑду Ð´Ð»Ñ ÐºÐ¾Ñ€Ð°Ð±Ð»Ñ–Ð²: {ORANGE}{STRING} дн/%
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Інтервал техоглÑду Ð´Ð»Ñ ÐºÐ¾Ñ€Ð°Ð±Ð»Ñ–Ð²: {ORANGE}без тех.оглÑду
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Ðе робити техоглÑд, коли вимкнено аварії: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Обмежити швидкіÑÑ‚ÑŒ вагонів: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}Відключити електрички: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}ПоÑва кольорових новин у: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Початкова дата: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}Кінцева дата: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Економіка Ñпокійна (менш мінлива)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Можна купувати інші компанії
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}При протаÑкуванні Ñигнали ÑтавлÑÑ‚ÑŒÑÑ Ñ‡ÐµÑ€ÐµÐ·:{ORANGE}{STRING} клітки(ок)
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}ÐŸÐ¾Ð»Ð¾Ð¶ÐµÐ½Ð½Ñ Ð³Ð¾Ð»Ð¾Ð²Ð½Ð¾Ð³Ð¾ меню: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Ліворуч
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :По центру
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Праворуч
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Ð Ð°Ð´Ñ–ÑƒÑ Ð¿Ñ€Ð¸Ð»Ð¸Ð¿Ð°Ð½Ð½Ñ Ð²Ñ–ÐºÐ¾Ð½: {ORANGE}{STRING} пікÑ.
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}ÐŸÑ€Ð¸Ð»Ð¸Ð¿Ð°Ð½Ð½Ñ Ð²Ñ–ÐºÐ¾Ð½ {ORANGE}вимкнено
+
+STR_CONFIG_PATCHES_GUI :{BLACK}ВиглÑд
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Споруди
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}ТранÑпорт
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Станції
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Економіка
+STR_CONFIG_PATCHES_AI :{BLACK}Конкуренти
+
+STR_CONFIG_PATCHES_DISABLED :вимкнено
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Змініть значеннÑ
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Одне чи декілька значень інтервалів неÑуміÑні за даних умов! Дозволено 5-90% та 30-800 днів
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}ВикориÑтовувати YAPF Ð´Ð»Ñ ÐºÐ¾Ñ€Ð°Ð±Ð»Ñ–Ð²: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}ВикориÑтовувати YAPF Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}ВикориÑтовувати YAPF Ð´Ð»Ñ Ð¿Ð¾Ñ—Ð·Ð´Ñ–Ð²: {ORANGE}{STRING}
+
+STR_TEMPERATE_LANDSCAPE :Помірний ландшафт
+STR_SUB_ARCTIC_LANDSCAPE :Субарктичний ландшафт
+STR_SUB_TROPICAL_LANDSCAPE :Субтропічний ландшафт
+STR_TOYLAND_LANDSCAPE :Іграшковий ландшафт
+
+STR_CHEATS :{WHITE}Гратиму не чеÑно
+STR_CHEATS_TIP :{BLACK}Галка показує, що Ви Ñтали грати не чеÑно
+STR_CHEATS_WARNING :{BLACK}ПопередженнÑ! Ви збираєтеÑÑ Ð¾Ð±Ð¼Ð°Ð½ÑŽÐ²Ð°Ñ‚Ð¸ конкурентів. Зауважте, подібне безчеÑÑ‚Ñ Ð·Ð°Ð¿Ð°Ð¼'ÑтаєтьÑÑ Ð½Ð°Ð·Ð°Ð²Ð¶Ð´Ð¸.
+STR_CHEAT_MONEY :{LTBLUE}Збільшити кошти на {CURRENCY64}
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Грати за гравцÑ: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Супер бульдозер (руйнує вÑе): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Тунелі перетинаютьÑÑ: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Будувати в режимі паузи: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Літаки Ñідають Ñ– в малих аеропортах: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Змінити клімат: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Змінити дату: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}Дозволити зміну Ñ€Ñ–Ð²Ð½Ñ Ð²Ð¸Ñ€Ð¾Ð±Ð½Ð¸Ñ†Ñ‚Ð²Ð°: {ORANGE}{STRING}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}ПрÑмує до {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}ПрÑмує до {WAYPOINT}, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :Їхати через {WAYPOINT}
+STR_GO_NON_STOP_TO_WAYPOINT :Їхати без зупинок через {WAYPOINT}
+
+STR_WAYPOINTNAME_CITY :Пункт {TOWN}
+STR_WAYPOINTNAME_CITY_SERIAL :Пункт {TOWN} #{COMMA}
+STR_LANDINFO_WAYPOINT :Пункт
+
+STR_WAYPOINT :{WHITE}Точка маршруту
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Виберіть тип точки маршруту
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}Перейменуйте точку маршруту
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Ðе можна перейменувати точку маршруту...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Ð’Ñтановити точку маршруту
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Тут не можна вÑтановити точку маршруту..
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Тут не можна прибрати точку маршруту..
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Будувати колію викориÑтовуючи авторежим
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}...у цьому Ñценарію немає міÑÑ‚
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}Ви дійÑно бажаєте Ñтворити ландшафт випадково?
+STR_MANY_RANDOM_TOWNS :{BLACK}Багато різних міÑÑ‚
+STR_RANDOM_TOWNS_TIP :{BLACK}Випадково розташувати міÑта по карті
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Багато різної промиÑловоÑÑ‚Ñ–
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Випадково розташувати промиÑловіÑÑ‚ÑŒ по карті
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Ðеможливо Ñтворити промиÑловіÑÑ‚ÑŒ...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Змінити ландшафт
+STR_LANDSCAPING_TOOLBAR :{WHITE}Ландшафт
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Рівень землі
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Дерева випадкового типу
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}Садити дерева випадкового типу
+
+STR_CANT_BUILD_CANALS :{WHITE}Ðеможливо будувати канал тут...
+STR_BUILD_CANALS_TIP :{BLACK}Будувати канал
+STR_LANDINFO_CANAL :Канал
+
+STR_CANT_BUILD_LOCKS :{WHITE}Ðеможливо будувати шлюз тут...
+STR_BUILD_LOCKS_TIP :{BLACK}Будувати шлюз
+STR_LANDINFO_LOCK :Шлюз
+
+STR_BUOY_IS_IN_USE :{WHITE}...бакен викориÑтовуєтьÑÑ!
+
+STR_LANDINFO_COORDS :{BLACK}Координати: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Ðе можна зруйнувати чаÑтину Ñтанції...
+STR_CANT_CONVERT_RAIL :{WHITE}Тут не можна модернізувати колію...
+STR_CONVERT_RAIL_TIP :{BLACK}Модернізувати колію
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}ПеретÑгніть Ñюди поїзд Ð´Ð»Ñ Ð¹Ð¾Ð³Ð¾ продажу повніÑÑ‚ÑŽ
+
+STR_DRAG_DROP :{BLACK}ПеретÑгнути й відпуÑтити
+STR_STATION_DRAG_DROP :{BLACK}Будувати Ñтанцію за методом "перетÑгнути й відпуÑтити"
+STR_SELECT_STATION_CLASS_TIP :{BLACK}Виберіть тип Ñтанції Ð´Ð»Ñ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Виберіть тип Ñтанції Ð´Ð»Ñ Ð·Ð°Ð±ÑƒÐ´Ð¾Ð²Ð¸
+
+STR_FAST_FORWARD :{BLACK}ПриÑкорити гру
+STR_MESSAGE_HISTORY :{WHITE}ІÑÑ‚Ð¾Ñ€Ñ–Ñ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½ÑŒ
+STR_MESSAGE_HISTORY_TIP :{BLACK}СпиÑок оÑтанніх нових повідомлень
+STR_MESSAGES_DISABLE_ALL :{BLACK}Виключити уÑÑ–
+STR_MESSAGES_ENABLE_ALL :{BLACK}Включити уÑÑ–
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Збудувати вушільну шахту
+STR_CONSTRUCT_FOREST_TIP :{BLACK}ПоÑадити ліÑ
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Збудувати нафтову платформу
+STR_CONSTRUCT_FARM_TIP :{BLACK}Збудувати ферму
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Збудувати міднорудну шахту
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Збудувати нафтову Ñвердловину
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Збудувати золоторудну шахту
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Збудувати діамантову шахту
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Збудувати залізорудну шахту
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}ПоÑадити фруктовий Ñад
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}ПоÑадити каучуковий Ñад
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Збудувати водопоÑтачаннÑ
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}ПоÑадити Ð»Ñ–Ñ Ñолодкої вати
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}ПоÑадити батарейкове поле
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Будувати джерело кока-коли
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Будувати плаÑтикові фонтани
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Збудувати бульбашкову фабрику
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Будувати іриÑковий кар'єр
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Збудувати цукрову копальню
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}ПромиÑловіÑÑ‚ÑŒ
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA}% перевезено)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA}%/{COMMA}% перевезено)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}...дуже близько до іншої промиÑловоÑÑ‚Ñ–
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Переобладнати поїзд Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²ÐµÐ·ÐµÐ½Ð½Ñ Ñ–Ð½ÑˆÐ¾Ð³Ð¾ виду вантажу
+STR_RAIL_REFIT_VEHICLE :{BLACK}Переобладнати
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Виберіть вид вантажу Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²ÐµÐ·ÐµÐ½Ð½Ñ
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Переобладнати поїзд Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²ÐµÐ·ÐµÐ½Ð½Ñ Ð²Ð¸Ð±Ñ€Ð°Ð½Ð¾Ð³Ð¾ виду вантажу
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Ðеможливо переобладнати поїзд...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}ТриваліÑÑ‚ÑŒ обÑÐ»ÑƒÐ³Ð¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ñƒ відÑотках: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Змінити виробництво
+
+TEMP_AI_IN_PROGRESS :{WHITE}ЛаÑкаво проÑимо до теÑÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ інтелекту. Якщо Ви помітили недолік, надішліть копію екрану у форум.
+TEMP_AI_ACTIVATED :{WHITE}ПопередженнÑ: це новий інтелект вÑе ще альфа-верÑÑ–Ñ! Зараз задіÑні лише потÑги та авто!
+TEMP_AI_MULTIPLAYER :{WHITE}ПопередженнÑ: це вÑе ще екÑпериментальний інтелект. Будь-лаÑка повідомте про проблеми truelight@openttd.org.
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Мережна гра
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Ім'Ñ Ð³Ñ€Ð°Ð²Ñ†Ñ:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}Ім'Ñ, за Ñким тебе розпізнаватимуть інші гравці
+STR_NETWORK_CONNECTION :{BLACK}З'єднаннÑ:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Виберіть гру через інтернет або через локальну мережу(ЛОМ)
+
+STR_NETWORK_START_SERVER :{BLACK}Створити Ñервер
+STR_NETWORK_START_SERVER_TIP :{BLACK}Створити ваш влаÑний Ñервер
+
+STR_NETWORK_GAME_NAME :{BLACK}Ðазва
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Ðазва гри
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Мова, верÑÑ–Ñ Ñервера, та інше.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}ÐатиÑніть на гру із ÑпиÑку, щоб вибрати Ñ—Ñ—
+
+STR_NETWORK_FIND_SERVER :{BLACK}Знайти Ñервер
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Пошук мережі Ð´Ð»Ñ Ñервера
+STR_NETWORK_ADD_SERVER :{BLACK}Додати Ñервер
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Додати Ñервер до ÑпиÑку, Ñкий завжди буде перевірÑтиÑÑŒ на поточні ігри.
+STR_NETWORK_ENTER_IP :{BLACK}Введіть адреÑу Ñервера
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Клієнти
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Клієнти в мережі/макÑ.клієнтів{}Компанії в мережі/макÑ.компаній
+STR_NETWORK_GAME_INFO :{SILVER}Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ гру
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Клієнт: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Мова: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Шаблонt: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Розмір карти: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}ВерÑÑ–Ñ Ñерверу: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}ÐдреÑа Ñерверу: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Дата початку: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Поточна дата: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Захищено паролем!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}Сервер відключений
+STR_NETWORK_SERVER_FULL :{SILVER}Сервер зайнÑтий
+STR_NETWORK_VERSION_MISMATCH :{SILVER}ВерÑÑ–Ñ Ð½Ðµ ÑуміÑна
+STR_NETWORK_GRF_MISMATCH :{SILVER}NEWGRF ПОМИЛКÐ
+
+STR_NETWORK_JOIN_GAME :{BLACK}ПриєднатиÑÑ Ð´Ð¾ гри
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}Створити нову мережну гру
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Ðазва гри:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}Ðазва гри відображатиметьÑÑ Ñ–Ð½ÑˆÐ¸Ð¼ гравцÑм у меню мережної гри
+STR_NETWORK_SET_PASSWORD :{BLACK}Ð’Ñтановити пароль
+STR_NETWORK_PASSWORD_TIP :{BLACK}ЗахиÑÑ‚Ñ–Ñ‚ÑŒ вашу гру паролем, Ñкщо не бажаєте загального доÑтупу
+STR_NETWORK_SELECT_MAP :{BLACK}Виберіть карту:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}Ðа Ñкій карті бажаєте грати?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}МакÑ. клієнтів:
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Виберіть макÑимальну кількіÑÑ‚ÑŒ клієнтів. Ðе вÑÑ– Ñлоти мають бути зайнÑÑ‚Ñ–
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :Локальна
+STR_NETWORK_INTERNET :Інтернет
+STR_NETWORK_LAN_INTERNET :Локальна/Інтернет
+STR_NETWORK_INTERNET_ADVERTISE :
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 гравців
+STR_NETWORK_1_PLAYERS :1 гравець
+STR_NETWORK_2_PLAYERS :2 гравцÑ
+STR_NETWORK_3_PLAYERS :3 гравцÑ
+STR_NETWORK_4_PLAYERS :4 гравцÑ
+STR_NETWORK_5_PLAYERS :5 гравців
+STR_NETWORK_6_PLAYERS :6 гравців
+STR_NETWORK_7_PLAYERS :7 гравців
+STR_NETWORK_8_PLAYERS :8 гравців
+STR_NETWORK_9_PLAYERS :9 гравців
+STR_NETWORK_10_PLAYERS :10 гравців
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}МакÑимум компаній:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Обмежує кількіÑÑ‚ÑŒ компаній на Ñервері
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}МакÑмум глÑдачів:
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Обмежує кількіÑÑ‚ÑŒ глÑдачів на Ñервері
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Мова:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Інші гравці будуть знати Ñкою мовою ÑпілкуютьÑÑ Ð½Ð° Ñервері
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}Почати гру
+STR_NETWORK_START_GAME_TIP :{BLACK}Почати нову мережну гру з випадковою картою або Ñценарієм
+STR_NETWORK_LOAD_GAME :{BLACK}Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð³Ñ€Ð¸
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Продовжити збережену мережну гру
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Будь-Ñка
+STR_NETWORK_LANG_ENGLISH :ÐнглійÑька
+STR_NETWORK_LANG_GERMAN :Ðімецька
+STR_NETWORK_LANG_FRENCH :Французька
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Multiplayer game lobby
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Підготовка до з'єднаннÑ: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}СпиÑок вÑÑ–Ñ… компаній приÑутніх у цій грі. Ви можете Ñк приєднатиÑÑŒ до компанії так Ñ– Ñтворити нову, Ñкщо Ñ” вільне міÑце
+STR_NETWORK_NEW_COMPANY :{BLACK}Ðова компаніÑ
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Створити нову компанію
+STR_NETWORK_SPECTATE_GAME :{BLACK}Гра глÑдачем
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}СпоÑтерігати за грою Ñк глÑдач
+STR_NETWORK_JOIN_COMPANY :{BLACK}ПриєднатиÑÑŒ до компанії
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Допомогти керувати цією компанією
+STR_NETWORK_REFRESH :{BLACK}Оновити Ñервер
+STR_NETWORK_REFRESH_TIP :{BLACK}Оновити інформацію про Ñервер
+
+STR_NETWORK_COMPANY_INFO :{SILVER}Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ компанію
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Ðазва компанії: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}ЗаÑновано: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}ВартіÑÑ‚ÑŒ компанії: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Поточний баланÑ: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Прибуток минулого року: {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}ПродуктивніÑÑ‚ÑŒ: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}ТранÑпорту: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Станцій: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Гравців: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}З'єднаннÑ...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) З'єднаннÑ..
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) ÐвторизаціÑ..
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) ОчікуваннÑ..
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ ÐºÐ°Ñ€Ñ‚Ð¸..
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Обробка данних..
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) РегіÑтраціÑ..
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Запит інформації про гру..
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Запит інформації про компанію..
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} клієнт{P "" и ів} перед вами
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} кілобайт завантажено
+
+STR_NETWORK_DISCONNECT :{BLACK}Роз'єднаннÑ
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Введіть Ñуму, Ñку бажаєте передати
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Сервер захищено паролем. Введіть пароль
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}ÐšÐ¾Ð¼Ð¿Ð°Ð½Ñ–Ñ Ð·Ð°Ñ…Ð¸Ñ‰ÐµÐ½Ð° паролем. Введіть пароль
+STR_NETWORK_CLIENT_LIST :{WHITE}СпиÑок клієнтів
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE} Ðе знайдено мережевого приÑтрою або закомпільовано без ENABLE_NETWORK
+STR_NETWORK_ERR_NOSERVER :{WHITE} Ðе знайдено жодної мережної гри
+STR_NETWORK_ERR_NOCONNECTION :{WHITE} Сервер не відповідає на запит
+STR_NETWORK_ERR_DESYNC :{WHITE} Помилка Ñинхронізації з мережною грою
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} З'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð²Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð¾
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} Ðеможливо завантажити гру
+STR_NETWORK_ERR_SERVER_START :{WHITE} Ðеможливо Ñтворити Ñервер
+STR_NETWORK_ERR_CLIENT_START :{WHITE} Ðеможливо з'єднатиÑÑ
+STR_NETWORK_ERR_TIMEOUT :{WHITE} З'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ #{NUM} timed out
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE} Помилка протоколу - з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ñ€Ð¾Ð·Ñ–Ñ€Ð²Ð°Ð½Ð¾
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE} ВерÑÑ–Ñ ÐºÐ»Ñ–ÐµÐ½Ñ‚Ð° не Ñпівпадає з верÑією Ñервера
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} Пароль невірний
+STR_NETWORK_ERR_SERVER_FULL :{WHITE} Сервер переповнений
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} Ð’Ð°Ñ Ð²Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¾ від цього Ñерверу
+STR_NETWORK_ERR_KICKED :{WHITE} Ð’Ð°Ñ Ð²Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¾ від гри
+STR_NETWORK_ERR_CHEATER :{WHITE} Ðа цьому Ñервері грати нечеÑно не можна
+
+STR_NETWORK_ERR_LEFT :вийшов з гри
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :фатальна помилка
+STR_NETWORK_ERR_CLIENT_DESYNC :помилка Ñинхронізації
+STR_NETWORK_ERR_CLIENT_SAVEGAME :неможливо завантажити карту
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð²Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð¾
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :помилка протоколу
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :відмова авторизації
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :отримано неÑуміÑний пакет даних
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :невірна верÑÑ–Ñ Ð³Ñ€Ð¸
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :таке ім'Ñ Ð²Ð¶Ðµ Ñ”
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :пароль невірний
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :невірний ID Ð³Ñ€Ð°Ð²Ñ†Ñ Ð² DoCommand
+STR_NETWORK_ERR_CLIENT_KICKED :відключено Ñервером від гри
+STR_NETWORK_ERR_CLIENT_CHEATER :Ñпроба грати нечеÑно
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :Ñервер переповнений
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :приєднавÑÑ Ð´Ð¾ гри
+STR_NETWORK_GIVE_MONEY :ви отримали({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :ви дали {STRING} ({CURRENCY})
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Команда] :
+STR_NETWORK_CHAT_COMPANY :[Команда] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Команда] до {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[Приватно] :
+STR_NETWORK_CHAT_CLIENT :[Приватно] {STRING}:{GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[Приватно] до {STRING}:{GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[Ð’Ñім] :
+STR_NETWORK_CHAT_ALL :[Ð’Ñім] {STRING}:{GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :змінив Ñвоє ім'Ñ Ð½Ð°
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE} Сервер закрив ÑеанÑ
+STR_NETWORK_SERVER_REBOOT :{WHITE} ÐŸÐµÑ€ÐµÐ·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñервера...{}Зачекайте...
+
+STR_NETWORK_SERVER :Сервер
+STR_NETWORK_CLIENT :Клієнт
+STR_NETWORK_SPECTATORS :СпоÑтерігачі
+
+STR_NETWORK_CLIENTLIST_NONE :(нічого)
+STR_NETWORK_CLIENTLIST_KICK :Відключити гравцÑ
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Дати грошей
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð²Ñім
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ñ–Ñ—
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Приватне повідомленнÑ
+
+
+STR_NETWORK_SEND :{BLACK}Відправити
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}X-розмір карти: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Y-розмір карти: {ORANGE}{STRING}
+
+
+##### PNG-MAP-Loader
+
+STR_PNGMAP_ERROR :{WHITE}Ðеможливо завантажити ландшафт з PNG...
+STR_PNGMAP_ERR_FILE_NOT_FOUND :{WHITE}...файл не знайдено
+STR_PNGMAP_ERR_IMAGE_TYPE :{WHITE}...неможливо конвертувати. треба 8 чи 24-bit PNG формат.
+STR_PNGMAP_ERR_MISC :{WHITE}...Помилка. (можливо зіпÑований файл)
+
+STR_BMPMAP_ERROR :{WHITE}Ðеможу завантажити лашдшафт з BMP...
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}...неможливо претворити тип зображеннÑ
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Витрачено: {CURRENCY}
+STR_0801_COST :{RED}Витрачено: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Прибуток: {CURRENCY}
+STR_0803_INCOME :{GREEN}Прибуток: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}ПереÑадка: {CURRENCY}
+STR_FEEDER :{YELLOW}ПереÑадка: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Приблизні витрати: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Приблизний прибуток: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Ðеможливо піднÑти ділÑнку...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Ðеможливо опуÑтити ділÑнку...
+STR_080A_ROCKS :КаміннÑ
+STR_080B_ROUGH_LAND :Ðерівна землÑ
+STR_080C_BARE_LAND :ПуÑтир
+STR_080D_GRASS :Трава
+STR_080E_FIELDS :Поле
+STR_080F_SNOW_COVERED_LAND :ЗаÑніжена землÑ
+STR_0810_DESERT :ПуÑтелÑ
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Схил не в тому напрÑмку
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Ðеможливе з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ ÐºÐ¾Ð»Ñ–Ñ—
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}Роботи пошкодÑÑ‚ÑŒ тунель
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Вже понижено до Ñ€Ñ–Ð²Ð½Ñ Ð¼Ð¾Ñ€Ñ
+STR_1004_TOO_HIGH :{WHITE}Дуже виÑоко
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Ðе відповідний тип колії
+STR_1007_ALREADY_BUILT :{WHITE}...вже побудовано
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Спочатку приберіть колію
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Будівництво залізниці
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Будувати електрифіковану колію
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Будівництво монорельÑа
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}Будівництво магнітної подушки
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Виберіть міÑÑ‚
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Ðеможливо будувати депо тут...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Ðеможливо будувати Ñтанцію тут...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Ðеможливо будувати Ñигнали тут...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Ðеможливо будувати колію тут...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Ðеможливо прибрати колію звідÑи...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Ðеможливо прибрати Ñигнали звідÑи...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}ÐÐ°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð´ÐµÐ¿Ð¾
+STR_1015_RAILROAD_CONSTRUCTION :ЗалізницÑ
+STR_TOOLB_ELRAIL_CONSTRUCTION :Будувати електрифіковану колію
+STR_1016_MONORAIL_CONSTRUCTION :МонорельÑ
+STR_1017_MAGLEV_CONSTRUCTION :Магнітна подушка
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Будувати колію
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Будувати депо (Ð´Ð»Ñ ÐºÑƒÐ¿Ñ–Ð²Ð»Ñ– Ñ– ремонту поїздів)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Будувати Ñтанцію
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Будувати Ñигнал
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Будувати міÑÑ‚
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Будувати туннель
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Будувати/демонтувати колію або Ñигнали
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Вибір моÑту - натиÑніть на міÑÑ‚, Ñкий бажаєте збудувати
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Вибір Ð½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð´ÐµÐ¿Ð¾
+STR_1021_RAILROAD_TRACK :Залізнична коліÑ
+STR_1023_RAILROAD_TRAIN_DEPOT :Залізничне депо
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...Ñ†Ñ Ð´Ñ–Ð»Ñнка у влаÑноÑÑ‚Ñ– іншої компанії
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :ÐšÐ¾Ð»Ñ–Ñ Ð·Ñ– звичайними Ñигналами
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :ÐšÐ¾Ð»Ñ–Ñ Ð· вхідними Ñигналами
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :ÐšÐ¾Ð»Ñ–Ñ Ð· вихідними Ñигналами
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :ÐšÐ¾Ð»Ñ–Ñ Ð· комбінованими Ñигналами
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Спочатку зруйнуйте дорогу
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Дорога ремонтуєтьÑÑ
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Будівництво дороги
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Виберіть дорожний міÑÑ‚
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Ðеможливо будувати дорогу тут...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Ðеможливо прибрати дорогу звідÑи...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}ÐÐ°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð´ÐµÐ¿Ð¾
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Ðеможливо будувати депо тут...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Ðеможливо будувати зупинку тут...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Ðеможливо будувати вантажну Ñтанцію тут...
+STR_180A_ROAD_CONSTRUCTION :Будувати дороги
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Будувати дорогу
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Будувати автомобільне депо
+STR_180D_BUILD_BUS_STATION :{BLACK}Будувати зупинку
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Будувати вантажну Ñтанцію
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Будувати міÑÑ‚
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Будувати тунель
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Будувати/зруйнувати дорогу
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Виберіть Ð½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð´ÐµÐ¿Ð¾
+STR_1814_ROAD :Дорога
+STR_1815_ROAD_WITH_STREETLIGHTS :Дорога з вуличними ліхтарÑми
+STR_1816_TREE_LINED_ROAD :Дорога з наÑадженнÑми
+STR_1817_ROAD_VEHICLE_DEPOT :Ðвтомобільне депо
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :Залізничний переїзд
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}МіÑта
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Спочатку зруйнуйте Ñпоруду
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}ÐаÑеленнÑ: {ORANGE}{COMMA}{BLACK} Будинки: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Перейменувати
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Ðеможливо перейменувати...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}Влада міÑта {TOWN} проти цього
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Ðазви міÑÑ‚ - вкажіть на міÑто Ñ– воно з'ÑвитьÑÑ Ð² центрі екрану
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Показати в центрі екрану
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Змінити назву міÑта
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}ПаÑажирів за міÑÑць: {ORANGE}{COMMA}{BLACK} Ðайбільш: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Пошти за міÑÑць: {ORANGE}{COMMA}{BLACK} Ðайбільше: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Великий офіÑ
+STR_2010_OFFICE_BLOCK :ОфіÑний район
+STR_2011_SMALL_BLOCK_OF_FLATS :Будинки
+STR_2012_CHURCH :Церква
+STR_2013_LARGE_OFFICE_BLOCK :Великий офіÑний район
+STR_2014_TOWN_HOUSES :МіÑькі будинки
+STR_2015_HOTEL :Готель
+STR_2016_STATUE :Монумент
+STR_2017_FOUNTAIN :Фонтан
+STR_2018_PARK :Парк
+STR_2019_OFFICE_BLOCK :ОфіÑний район
+STR_201A_SHOPS_AND_OFFICES :Магазини й офіÑи
+STR_201B_MODERN_OFFICE_BUILDING :СучаÑний офіÑ
+STR_201C_WAREHOUSE :Склади
+STR_201D_OFFICE_BLOCK :ОфіÑний район
+STR_201E_STADIUM :Стадіон
+STR_201F_OLD_HOUSES :Старі будинки
+STR_2020_LOCAL_AUTHORITY :{BLACK}МіÑцева влада
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ міÑцеву владу
+STR_2022_LOCAL_AUTHORITY :{WHITE}{TOWN} міÑцева влада
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Рейтинги компаній:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}СубÑидії
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}ПропонуютьÑÑ ÑубÑидії:-
+STR_2027_FROM_TO :{ORANGE}ÐŸÐµÑ€ÐµÐ²ÐµÐ·ÐµÐ½Ð½Ñ {STRING} з {STRING} до {STRING}
+STR_2028_BY :{YELLOW} ({DATE_SHORT})
+STR_202A_NONE :{ORANGE}немає
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Призначені ÑубÑидії:-
+STR_202C_FROM_TO :{ORANGE}ÐŸÐµÑ€ÐµÐ²ÐµÐ·ÐµÐ½Ð½Ñ {STRING} з {STATION} до {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, по {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}СубÑидію відмінено:{}{}ÐŸÐµÑ€ÐµÐ²ÐµÐ·ÐµÐ½Ð½Ñ {STRING} з {STRING} до {STRING}.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}СубÑÐ¸Ð´Ñ–Ñ Ð²Ð¶Ðµ не надаєтьÑÑ:{}{}ÐŸÐµÑ€ÐµÐ²ÐµÐ·ÐµÐ½Ð½Ñ {STRING} з {STATION} до {STATION}.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}ПропонуєтьÑÑ Ñ€Ñ–Ñ‡Ð½Ð° ÑубÑÐ¸Ð´Ñ–Ñ {}{}першій компанії, Ñка привезе {STRING} з {STRING} до {STRING}!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}СубÑидію надано {COMPANY}!{}{}ÐŸÐµÑ€ÐµÐ²ÐµÐ·ÐµÐ½Ð½Ñ {STRING} з {STATION} до {STATION} принеÑе додатково 50% протÑгом наÑтупного року!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}СубÑидію надано {COMPANY}!{}{}ÐŸÐµÑ€ÐµÐ²ÐµÐ·ÐµÐ½Ð½Ñ {STRING} з {STATION} до {STATION} принеÑе вдвічі більше прибутків наÑтупного року!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}СубÑидію надано {COMPANY}!{}{}ÐŸÐµÑ€ÐµÐ²ÐµÐ·ÐµÐ½Ð½Ñ {STRING} з {STATION} до {STATION} принеÑе втричі більше прибутків наÑтупного року!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}СубÑидію надано {COMPANY}!{}{}ÐŸÐµÑ€ÐµÐ²ÐµÐ·ÐµÐ½Ð½Ñ {STRING} з {STATION} до {STATION} принеÑе вчетверо більше прибутків наÑтупного року!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE} Влада міÑта {TOWN} відмовлÑÑ” у будівництві ще одного аеропорту.
+STR_2036_COTTAGES :Котеджі
+STR_2037_HOUSES :Будинки
+STR_2038_FLATS :Квартири
+STR_2039_TALL_OFFICE_BLOCK :ХмарочоÑи
+STR_203A_SHOPS_AND_OFFICES :Магазини Ñ– офіÑи
+STR_203B_SHOPS_AND_OFFICES :Магазини Ñ– офіÑи
+STR_203C_THEATER :Театр
+STR_203D_STADIUM :Стадіон
+STR_203E_OFFICES :ОфіÑи
+STR_203F_HOUSES :Будинки
+STR_2040_CINEMA :Кінотеатр
+STR_2041_SHOPPING_MALL :Торговий центр
+STR_2042_DO_IT :{BLACK}Виконати
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}Що можна зробити в цьому міÑÑ‚Ñ– - виберіть пункт Ð´Ð»Ñ Ð´ÐµÑ‚Ð°Ð»ÑŒÐ½Ð¾Ñ— інформації
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Виконує вибрану дію зі ÑпиÑку
+STR_2045_ACTIONS_AVAILABLE :{BLACK}ДоÑтупні дії:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Мала рекламна кампаніÑ
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Ð¡ÐµÑ€ÐµÐ´Ð½Ñ Ñ€ÐµÐºÐ»Ð°Ð¼Ð½Ð° кампаніÑ
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Велика рекламна кампаніÑ
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :ПровеÑти реконÑтрукцію доріг
+STR_204A_BUILD_STATUE_OF_COMPANY :Збудувати монумент влаÑника компанії
+STR_204B_FUND_NEW_BUILDINGS :ФінанÑувати нові будівлі
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Купити єдине транÑпортне право
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Підкупити міÑцеву владу
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} ПровеÑти малу рекламну компанію, щоб залучити більше паÑажирів Ñ– вантажу до вашої компанії в цьому міÑÑ‚Ñ–.{} ВартіÑÑ‚ÑŒ: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} ПровеÑти Ñередню рекламну компанію, щоб залучити більше паÑажирів Ñ– вантажу до вашої компанії в цьому міÑÑ‚Ñ–.{} ВартіÑÑ‚ÑŒ: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} ПровеÑти велику рекламну компанію, щоб залучити більше паÑажирів Ñ– вантажу до вашої компанії в цьому міÑÑ‚Ñ–.{} ВартіÑÑ‚ÑŒ: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} РеконÑÑ‚Ñ€ÑƒÐºÑ†Ñ–Ñ Ð´Ð¾Ñ€Ñ–Ð³ призведе до значного Ð¿Ð¾Ð³Ñ–Ñ€ÑˆÐµÐ½Ð½Ñ Ñ€ÑƒÑ…Ñƒ на 6 міÑÑців.{} ВартіÑÑ‚ÑŒ: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Збудувати монумент на чеÑÑ‚ÑŒ вашої компанії.{} ВартіÑÑ‚ÑŒ: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} ФінанÑувати будівництво нових офіÑів у міÑÑ‚Ñ–.{} ВартіÑÑ‚ÑŒ: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Купити єдине транÑпортне право у міÑÑ‚Ñ– на 1 рік. ПаÑажири Ñ– вантажі у міÑÑ‚Ñ– будуть перевозитиÑÑŒ лише вашою компанією.{} ВартіÑÑ‚ÑŒ: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Підкуп міÑцевої влади збільшить ваш рейтинг, але при викритті загрожує Ñуворим покараннÑм.{} ВартіÑÑ‚ÑŒ: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}ТранÑпортний безлад у міÑÑ‚Ñ– {TOWN}!{}{}РеконÑÑ‚Ñ€ÑƒÐºÑ†Ñ–Ñ Ð´Ð¾Ñ€Ñ–Ð³, фінанÑована компанією {COMPANY} принеÑе транÑпорту незручноÑÑ‚Ñ– протÑгом 6 міÑÑців!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (будуєтьÑÑ)
+STR_2059_IGLOO :Іглу
+STR_205A_TEPEES :Вігвам
+STR_205B_TEAPOT_HOUSE :Чайник-Дім
+STR_205C_PIGGY_BANK :Копилка
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN} {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Ландшафт
+STR_2800_PLANT_TREES :ПоÑадити дерево
+STR_2801_PLACE_SIGN :Зробити позначеннÑ
+STR_2802_TREES :{WHITE}Дерева
+STR_2803_TREE_ALREADY_HERE :{WHITE}...Тут вже роÑте дерево
+STR_2804_SITE_UNSUITABLE :{WHITE}...невідповідне міÑце
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Ðеможливо поÑадити тут дерево
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...дуже багато позначень
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Ðеможливо позначити міÑце
+STR_280A_SIGN :ПозначеннÑ
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Ð ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð°Ð¿Ð¸Ñу
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Ðеможливо перейменувати міÑце...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Виберіть тип дерев
+STR_280E_TREES :Дерева
+STR_280F_RAINFOREST :Джунглі
+STR_2810_CACTUS_PLANTS :КактуÑи
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Вибір Ñтанції
+STR_3001_AIRPORT_SELECTION :{WHITE}Вибір аеропорту
+STR_3002_ORIENTATION :{BLACK}ÐаправленнÑ
+STR_3003_NUMBER_OF_TRACKS :{BLACK}КількіÑÑ‚ÑŒ колій
+STR_3004_PLATFORM_LENGTH :{BLACK}Довжина платформи
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Дуже близько до іншої залізничної Ñтанції
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Граничить з іншою Ñтанцією
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}Дуже багато Ñтанцій в цьому міÑÑ‚Ñ–
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}Дуже багато Ñтанцій
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Дуже багато зупинок
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}Дуже багато вантажних Ñтанцій
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Дуже близько до іншої Ñтанції
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Спочатку зруйнуйте залізничну Ñтанцію
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Дуже близько до іншого аеропорту
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Спочатку зруйнуйте аеропорт
+
+STR_3030_RENAME_STATION_LOADING :ÐŸÐµÑ€ÐµÐ¹Ð¼ÐµÐ½ÑƒÐ²Ð°Ð½Ð½Ñ Ñтанції
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Ðеможливо перейменувати Ñтанцію...
+STR_3032_RATINGS :{BLACK}Рейтинг
+STR_3033_ACCEPTS :{BLACK}Приймає
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}МіÑцевий рейтинг транÑпортної компанії:
+
+############ range for rating starts
+STR_3035_APPALLING :Жахливо
+STR_3036_VERY_POOR :Дуже погано
+STR_3037_POOR :Погано
+STR_3038_MEDIOCRE :Середньо
+STR_3039_GOOD :Добре
+STR_303A_VERY_GOOD :Дуже добре
+STR_303B_EXCELLENT :Відмінно
+STR_303C_OUTSTANDING :Ðайкраще
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} більше не приймає {STRING}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} більше не приймає {STRING} або {STRING}
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} тепер приймає {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} тепер приймає {STRING} і {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}ÐÐ°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð·ÑƒÐ¿Ð¸Ð½ÐºÐ¸
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}ÐÐ°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ñтанції
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Спочатку зруйнуйте зупинку
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Спочатку зруйнуйте вантажну Ñтанцію
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Ñтанці{P Ñ Ñ— й}
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- нема -
+STR_304B_SITE_UNSUITABLE :{WHITE}...ділÑнка не підходить Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Дуже близько до іншого порту
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Спочатку зруйнуйте порт
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Виберіть Ð½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð·Ð°Ð»Ñ–Ð·Ð½Ð¸Ñ‡Ð½Ð¾Ñ— Ñтанції
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Виберіть кількіÑÑ‚ÑŒ колій залізничної Ñтанції
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Виберіть довжину залізничної Ñтанції
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Виберіть Ð½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð·ÑƒÐ¿Ð¸Ð½ÐºÐ¸
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Виберіть Ð½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð½Ð¾Ñ— Ñтанції
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Показати Ñтанцію в центрі екрану
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Показати рейтинг Ñтанції
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Перейменувати Ñтанцію
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Показати ÑпиÑок Ð¿Ñ€Ð¸Ð¹Ð¼Ð°Ð½Ð½Ñ Ð²Ð°Ð½Ñ‚Ð°Ð¶Ñ–Ð²
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Ðазва Ñтанції - натиÑніть на назву щоб показати в центрі екрану
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Виберіть розмір/тип аеропорту
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :Залізнична ÑтанціÑ
+STR_305F_AIRCRAFT_HANGAR :Ðнгар
+STR_3060_AIRPORT :Ðеропорт
+STR_3061_TRUCK_LOADING_AREA :Вантажна ÑтанціÑ
+STR_3062_BUS_STATION :Зупинка
+STR_3063_SHIP_DOCK :Порт
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}ПідÑвічувати зону дії Ñтанції
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Ðе підÑвічувати зону дії Ñтанції
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}ПідÑÐ²Ñ–Ñ‡ÐµÐ½Ð½Ñ Ð·Ð¾Ð½Ð¸ дії
+STR_3068_DOCK :{WHITE}Порт
+STR_3069_BUOY :Бакен
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...бакен на шлÑху
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...Ñтанції дуже розкидані
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...неоднорідні Ñтанції відмінено
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Утримуйте CTRL Ð´Ð»Ñ Ð²Ð¸Ð±Ð¾Ñ€Ñƒ більш ніж одного пункту
+
+STR_UNDEFINED :(невизначено)
+STR_STAT_CLASS_DFLT :Default station
+STR_STAT_CLASS_WAYP :Пункт
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}ÐÐ°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ ÐºÐ¾Ñ€Ð°Ð±ÐµÐ»ÑŒÐ½Ð¾Ð³Ð¾ депо
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...має бути збудовано на воді
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Ðеможливо будувати корабельне депо тут...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Виберіть Ð½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ ÐºÐ¾Ñ€Ð°Ð±ÐµÐ»ÑŒÐ½Ð¾Ð³Ð¾ депо
+STR_3804_WATER :Вода
+STR_3805_COAST_OR_RIVERBANK :Берег
+STR_3806_SHIP_DEPOT :Корабельне депо
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...Ðеможливо будувати на воді
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Зберегти гру
+STR_4001_LOAD_GAME :{WHITE}Завантажити гру
+STR_4002_SAVE :{BLACK}Зберегти
+STR_4003_DELETE :{BLACK}Видалити
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} мегабайт вільно
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Ðеможливо прочитати приÑтрій
+STR_4007_GAME_SAVE_FAILED :{WHITE}Помилка запиÑу гри
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Ðеможлтво видалити файл
+STR_4009_GAME_LOAD_FAILED :{WHITE}Помилка Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð³Ñ€Ð¸
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}СпиÑок приÑтроїв, каталогів Ñ– збережених файлів гри
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Поточне вибране ім'Ñ Ñ„Ð°Ð¹Ð»Ñƒ Ð´Ð»Ñ Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ð³Ñ€Ð¸
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Видалити поточну вибрану збережену гру
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Зберегти поточну гру, викориÑтовуючи вибране ім'Ñ Ñ„Ð°Ð¹Ð»Ñƒ
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Виберіть новий тип гри
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Виберіть Ñценарій (зелений), вÑтановлена гра (Ñиній), або випадкова нова гра
+STR_4010_GENERATE_RANDOM_NEW_GAME :Генерувати випадкову нову гру
+STR_4011_LOAD_HEIGHTMAP :{WHITE}Завантажити ландшафт
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} на шлÑху
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :Вугільна шахта
+STR_4803_POWER_STATION :ЕлектроÑтанціÑ
+STR_4804_SAWMILL :ЛіÑопилка
+STR_4805_FOREST :ЛіÑ
+STR_4806_OIL_REFINERY :Ðафтопереробний завод
+STR_4807_OIL_RIG :Ðафтова платформа
+STR_4808_FACTORY :Фабрика
+STR_4809_PRINTING_WORKS :ДрукарнÑ
+STR_480A_STEEL_MILL :Сталеварний завод
+STR_480B_FARM :Ферма
+STR_480C_COPPER_ORE_MINE :Міднорудна шахта
+STR_480D_OIL_WELLS :Ðафтова Ñвердловина
+STR_480E_BANK :Банк
+STR_480F_FOOD_PROCESSING_PLANT :Продуктовий завод
+STR_4810_PAPER_MILL :Паперова фабрика
+STR_4811_GOLD_MINE :Золоторудна шахта
+STR_4812_BANK :Банк
+STR_4813_DIAMOND_MINE :Діамантова шахта
+STR_4814_IRON_ORE_MINE :Залізорудна шахта
+STR_4815_FRUIT_PLANTATION :Фруктовий Ñад
+STR_4816_RUBBER_PLANTATION :Каучуковий Ñад
+STR_4817_WATER_SUPPLY :ВодопоÑтачаннÑ
+STR_4818_WATER_TOWER :Водонапірна башта
+STR_4819_FACTORY :Фабрика
+STR_481A_FARM :Ферма
+STR_481B_LUMBER_MILL :ЛіÑопилка
+STR_481C_COTTON_CANDY_FOREST :Ð›Ñ–Ñ Ñолодкої вати
+STR_481D_CANDY_FACTORY :Цукеркова фабрика
+STR_481E_BATTERY_FARM :Батарейкове поле
+STR_481F_COLA_WELLS :Джерело Кока-коли
+STR_4820_TOY_SHOP :Іграшковий магазин
+STR_4821_TOY_FACTORY :Іграшкова фабрика
+STR_4822_PLASTIC_FOUNTAINS :ПлаÑтиковий фонтан
+STR_4823_FIZZY_DRINK_FACTORY :Завод газованої води
+STR_4824_BUBBLE_GENERATOR :Бульбашкова фабрика
+STR_4825_TOFFEE_QUARRY :ІриÑковий кар'єр
+STR_4826_SUGAR_MINE :Цукрова копальнÑ
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Потрібно: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Потрібно: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Потрібно: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Вироблено за міÑÑць:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% перевезено)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Показати в центрі екрану
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}БудуєтьÑÑ {STRING} Ð±Ñ–Ð»Ñ {TOWN}!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}ÐаÑаджено {STRING} Ð±Ñ–Ð»Ñ {TOWN}!
+STR_482F_COST :{BLACK}ВартіÑÑ‚ÑŒ: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Ðеможливо будувати тут...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...Ð»Ñ–Ñ Ð¼Ð¾Ð¶Ðµ бути поÑаджений вище від Ñ€Ñ–Ð²Ð½Ñ Ñнігу
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} невдовзі закриєтьÑÑ!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}Проблеми з поÑтавками на {INDUSTRY} незабаром призведуть до закриттÑ!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}ВідÑутніÑÑ‚ÑŒ дерев поруч незабаром призведе {INDUSTRY} до закриттÑ!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} збільшуєтьÑÑ Ð²Ð¸Ñ€Ð¾Ð±Ð½Ð¸Ñ†Ñ‚Ð²Ð¾!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}Знайдені нові залежі Ð²ÑƒÐ³Ñ–Ð»Ð»Ñ Ð½Ð° {INDUSTRY}!{}ОчікуєтьÑÑ Ð·Ð±Ñ–Ð»ÑŒÑˆÐµÐ½Ð½Ñ Ð²Ð¸Ñ€Ð¾Ð±Ð½Ð¸Ñ†Ñ‚Ð²Ð° вдвічі!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}Знайдені нові нафтові запаÑи на {INDUSTRY}!{}ОчікуєтьÑÑ Ð·Ð±Ñ–Ð»ÑŒÑˆÐµÐ½Ð½Ñ Ð²Ð¸Ñ€Ð¾Ð±Ð½Ð¸Ñ†Ñ‚Ð²Ð° вдвічі!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}УдоÑконалені ÑільÑькогоÑподарÑькі методи на {INDUSTRY} збільшили виробництво вдвічі!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}{INDUSTRY} виробництво впало на 50%
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}ÐашеÑÑ‚Ñ Ñаранчі призвело до ÑпуÑÑ‚Ð¾ÑˆÐµÐ½Ð½Ñ Ð½Ð° {INDUSTRY}!{}Виробництво впало на 50%
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...можливе Ñ€Ð¾Ð·Ð¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð»Ð¸ÑˆÐµ Ð±Ñ–Ð»Ñ ÐºÑ€Ð°ÑŽ карти
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}{STRING} виробництво {INDUSTRY} зроÑло на {COMMA}%!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}{STRING} виробництво {INDUSTRY} впало на {COMMA}%!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Поїзд у тунелі
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Ðвто в тунелі
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Інший тунель на шлÑху
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Ðеможливо виконати будівництво іншого ÐºÑ–Ð½Ñ†Ñ Ñ‚ÑƒÐ½ÐµÐ»ÑŽ
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Спочатку зруйнуйте тунель
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Спочатку зруйнуйте міÑÑ‚
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Початок та кінець не можуть бути в одному міÑці
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Рівна Ð·ÐµÐ¼Ð»Ñ Ñ‡Ð¸ вода має бути під моÑтом
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}Початок та кінець мають бути на одній лінії
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Ðевідповідне міÑце Ð´Ð»Ñ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÑƒ тунелÑ
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :ПідвіÑний Ñталевий
+STR_500F_GIRDER_STEEL :Балочний Ñталевий
+STR_5010_CANTILEVER_STEEL :КаркаÑний Ñталевий
+STR_5011_SUSPENSION_CONCRETE :ПідвіÑний бетонний
+STR_5012_WOODEN :Дерев'Ñний
+STR_5013_CONCRETE :Бетонний
+STR_5014_TUBULAR_STEEL :ТрубчаÑтий Ñталевий
+STR_BRIDGE_TUBULAR_SILICON :
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Ðеможливо збудувати міÑÑ‚...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Ðеможливо збудувати тунель...
+STR_5017_RAILROAD_TUNNEL :Залізничний тунель
+STR_5018_ROAD_TUNNEL :Ðвтомобільний тунель
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Сталевий підвіÑний залізничний міÑÑ‚
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Сталевий балочний залізничний міÑÑ‚
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Сталевий каркаÑний залізничний міÑÑ‚
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Залізобетонний підвіÑний залізничний міÑÑ‚
+STR_501F_WOODEN_RAIL_BRIDGE :Дерев'Ñний залізничний міÑÑ‚
+STR_5020_CONCRETE_RAIL_BRIDGE :Бетонний залізничний міÑÑ‚
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Сталевий підвіÑний автомобільний міÑÑ‚
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Сталевий балочний автомобільний міÑÑ‚
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Сталевий каркаÑний автомобільний міÑÑ‚
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Залізобетонний підвіÑний автомобільний міÑÑ‚
+STR_5025_WOODEN_ROAD_BRIDGE :Дерев'Ñний автомобільний міÑÑ‚
+STR_5026_CONCRETE_ROAD_BRIDGE :Бетонний автомобільний міÑÑ‚
+STR_5027_TUBULAR_RAIL_BRIDGE :ТрубчаÑтий залізничний міÑÑ‚
+STR_5028_TUBULAR_ROAD_BRIDGE :ТрубчаÑтий автомобільний міÑÑ‚
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Об'єкт на шлÑху
+STR_5801_TRANSMITTER :РетранÑлÑтор
+STR_5802_LIGHTHOUSE :МаÑк
+STR_5803_COMPANY_HEADQUARTERS :Головний Ð¾Ñ„Ñ–Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ñ–Ñ—
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...на шлÑху Головний офіÑ
+STR_5805_COMPANY_OWNED_LAND :Ð¦Ñ Ð´Ñ–Ð»Ñнка влаÑніть компанії
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Ðеможливо купити цю ділÑнку ...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...це вже ваша влаÑніÑÑ‚ÑŒ!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Без назви
+STR_SV_TRAIN_NAME :Поїзд {COMMA}
+STR_SV_ROADVEH_NAME :Ðвто {COMMA}
+STR_SV_SHIP_NAME :Корабель {COMMA}
+STR_SV_AIRCRAFT_NAME :Літак {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :{STRING} Північна
+STR_SV_STNAME_SOUTH :{STRING} Південна
+STR_SV_STNAME_EAST :{STRING} Східна
+STR_SV_STNAME_WEST :{STRING} Західна
+STR_SV_STNAME_CENTRAL :{STRING} Центральна
+STR_SV_STNAME_TRANSFER :{STRING} База
+STR_SV_STNAME_HALT :{STRING} Зупинка
+STR_SV_STNAME_VALLEY :{STRING} Долина
+STR_SV_STNAME_HEIGHTS :{STRING} ВиÑоти
+STR_SV_STNAME_WOODS :{STRING} ЛіÑи
+STR_SV_STNAME_LAKESIDE :{STRING} Озера
+STR_SV_STNAME_EXCHANGE :{STRING} Хм..
+STR_SV_STNAME_AIRPORT :{STRING} Ðеропорт
+STR_SV_STNAME_OILFIELD :{STRING} Ðафтовина
+STR_SV_STNAME_MINES :{STRING} Шахти
+STR_SV_STNAME_DOCKS :{STRING} Доки
+STR_SV_STNAME_BUOY_1 :{STRING} Бакен 1
+STR_SV_STNAME_BUOY_2 :{STRING} Бакен 2
+STR_SV_STNAME_BUOY_3 :{STRING} Бакен 3
+STR_SV_STNAME_BUOY_4 :{STRING} Бакен 4
+STR_SV_STNAME_BUOY_5 :{STRING} Бакен 5
+STR_SV_STNAME_BUOY_6 :{STRING} Бакен 6
+STR_SV_STNAME_BUOY_7 :{STRING} Бакен 7
+STR_SV_STNAME_BUOY_8 :{STRING} Бакен 8
+STR_SV_STNAME_BUOY_9 :{STRING} Бакен 9
+STR_SV_STNAME_ANNEXE :{STRING} Флігель
+STR_SV_STNAME_SIDINGS :{STRING} Хм2..
+STR_SV_STNAME_BRANCH :{STRING} ВідділеннÑ
+STR_SV_STNAME_UPPER :Верхній {STRING}
+STR_SV_STNAME_LOWER :Ðижній {STRING}
+STR_SV_STNAME_HELIPORT :{STRING} ГелМайданчик
+STR_SV_STNAME_FOREST :{STRING} ЛіÑ
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Рівень ÑкладноÑÑ‚Ñ–
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Зберегти
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Легкий
+STR_6802_MEDIUM :{BLACK}Середній
+STR_6803_HARD :{BLACK}Важкий
+STR_6804_CUSTOM :{BLACK}Вибірковий
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}КількіÑÑ‚ÑŒ конкурентів: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Конкуренти починають через: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}КількіÑÑ‚ÑŒ міÑÑ‚: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}КількіÑÑ‚ÑŒ промиÑловоÑтей: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Початковий кредит: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}ВідÑотки за кредит: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}ТранÑпортні витрати: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}ШвидкіÑÑ‚ÑŒ будівництва конкурентів: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}ДоÑвідченіÑÑ‚ÑŒ конкурентів: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Вихід з ладу техніки: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Множник Ð´Ð»Ñ ÑубÑидій: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}ВартіÑÑ‚ÑŒ будівництва: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Тип рельєфу: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}КількіÑÑ‚ÑŒ морів/озер: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Економіка: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Поїзди розвертаютьÑÑ: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Стихійні лиха/катаÑтрофи: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Ð’Ñ–Ð´Ð½Ð¾ÑˆÐµÐ½Ð½Ñ Ð²Ð»Ð°Ð´Ð¸ до перебудови території міÑта: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :Ðема
+STR_6816_LOW :Мало
+STR_6817_NORMAL :Ðормально
+STR_6818_HIGH :Багато
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Дуже повільно
+STR_681C_SLOW :Повільно
+STR_681D_MEDIUM :Середньо
+STR_681E_FAST :Швидко
+STR_681F_VERY_FAST :Дуже швидко
+STR_VERY_LOW :Дуже мало
+STR_6820_LOW :Мало
+STR_6821_MEDIUM :Середньо
+STR_6822_HIGH :Багато
+STR_6823_NONE :Відкл.
+STR_6824_REDUCED :Знижено
+STR_6825_NORMAL :Ðормально
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Дуже рівний
+STR_682B_FLAT :Рівнинний
+STR_682C_HILLY :Горбкуватий
+STR_682D_MOUNTAINOUS :ГориÑтий
+STR_682E_STEADY :Стабільна
+STR_682F_FLUCTUATING :ÐеÑтійка
+STR_6830_IMMEDIATE :Відразу
+STR_6831_3_MONTHS_AFTER_PLAYER :3 міÑÑців піÑÐ»Ñ Ð³Ñ€Ð°Ð²Ñ†Ñ
+STR_6832_6_MONTHS_AFTER_PLAYER :6 міÑÑців піÑÐ»Ñ Ð³Ñ€Ð°Ð²Ñ†Ñ
+STR_6833_9_MONTHS_AFTER_PLAYER :9 міÑÑців піÑÐ»Ñ Ð³Ñ€Ð°Ð²Ñ†Ñ
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :Ð’ кінці лінії, або на ÑтанціÑÑ…
+STR_6835_AT_END_OF_LINE_ONLY :Лише в кінці лінії
+STR_6836_OFF :Викл
+STR_6837_ON :Вкл
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Показати таблицю рекордів
+STR_6839_PERMISSIVE :ДопуÑтиме
+STR_683A_TOLERANT :Терпиме
+STR_683B_HOSTILE :Вороже
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Гравець {COMMA})
+STR_7004_NEW_FACE :{BLACK}Ðове лице
+STR_7005_COLOR_SCHEME :{BLACK}Колір
+STR_7006_COLOR_SCHEME :{GOLD}Колір:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Ðовий колір
+STR_7008_COMPANY_NAME :{BLACK}Ðазва компанії
+STR_7009_PRESIDENT_NAME :{BLACK}Ім'Ñ ÐºÐµÑ€Ñ–Ð²Ð½Ð¸ÐºÐ°
+STR_700A_COMPANY_NAME :Ðазва компанії
+STR_700B_PRESIDENT_S_NAME :Ім'Ñ ÐºÐµÑ€Ñ–Ð²Ð½Ð¸ÐºÐ°
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Ðеможливо змінити назву компанії...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Ðеможливо змінити ім'Ñ ÐºÐµÑ€Ñ–Ð²Ð½Ð¸ÐºÐ°...
+STR_700E_FINANCES :{WHITE}{COMPANY} ФінанÑи {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Витрати/Доходи
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Будівництво
+STR_7012_NEW_VEHICLES :{GOLD}Ðова техніка
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Поїзди: витрати
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Ðвто: витрати
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Літаки: витрати
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Кораблі: витрати
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Ð£Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð²Ð»Ð°ÑноÑÑ‚Ñ–
+STR_7018_TRAIN_INCOME :{GOLD}Поїзди: прибуток
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Ðвто: прибуток
+STR_701A_AIRCRAFT_INCOME :{GOLD}Літаки: прибуток
+STR_701B_SHIP_INCOME :{GOLD}Кораблі: прибуток
+STR_701C_LOAN_INTEREST :{GOLD}ВідÑотки за кредит
+STR_701D_OTHER :{GOLD}Інше
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Ð’Ñього:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Графік доходів
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Графік прибутку від виробництва
+STR_7026_BANK_BALANCE :{WHITE}Рахунок
+STR_7027_LOAN :{WHITE}ВзÑто в кредит
+STR_MAX_LOAN :{WHITE}МакÑ. кредит: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}Позичити {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Повернути {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...найбільший дозволений розмір кредиту {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Ðеможливо взÑти кредит...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...кредит вже оплачено
+STR_702E_REQUIRED :{WHITE}...{CURRENCY} потрібно
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Ðеможливо виплатити кредит...
+STR_INSUFFICIENT_FUNDS :{WHITE}Ðеможливо передати гроші, Ñкі взÑли в кредит з банку...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Вибір нового Ð»Ð¸Ñ†Ñ ÐºÐµÑ€Ñ–Ð²Ð½Ð¸ÐºÐ°
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Зміна кольору транÑпорту компанії
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Зміна імені керівника
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Зміна назви компанії
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}ÐатиÑніть на колір, Ñкий вам до вподоби
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Збільшити розмір кредиту
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Виплатити чаÑтину кредиту
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(Керівник)
+STR_7038_INAUGURATED :{GOLD}ЗаÑновано у: {WHITE}{NUM} році
+STR_7039_VEHICLES :{GOLD}ТранÑпорт:
+STR_TRAINS :{WHITE}{COMMA} поїзд{P "" и ів}
+STR_ROAD_VEHICLES :{WHITE}{COMMA} авто
+STR_AIRCRAFT :{WHITE}{COMMA} літак{P "" и ів}
+STR_SHIPS :{WHITE}{COMMA} кораб{P ель лі ів}
+STR_7042_NONE :{WHITE}Ðема
+STR_7043_FACE_SELECTION :{WHITE}Вибір лицÑ
+STR_7044_MALE :{BLACK}Чоловік
+STR_7045_FEMALE :{BLACK}Жінка
+STR_7046_NEW_FACE :{BLACK}Ðове лице
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Відмінити вибір нового лицÑ
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Підтвердити вибір нового лицÑ
+STR_7049_SELECT_MALE_FACES :{BLACK}Вибір чоловічого лицÑ
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Вибір жіночого лицÑ
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Генерувати випадкове нове лице
+STR_704C_KEY :{BLACK}Ключ
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Показ ключа до графіків
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Ключ до графіків компанії
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}ÐатиÑніть Ð´Ð»Ñ Ð²ÐºÐ»/викл окремого графіку компанії
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}ДоÑтавка одиниці вантажу
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Рейтинг продуктивноÑÑ‚Ñ– компанії(найбільший рейтинг=1000)
+STR_7052_COMPANY_VALUES :{WHITE}ВартіÑÑ‚ÑŒ компанії
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Ð¢Ð°Ð±Ð»Ð¸Ñ†Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ñ–Ð¹
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}ÐšÐ¾Ð¼Ð¿Ð°Ð½Ñ–Ñ Ñƒ Ñкруті!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} буде продано або оголошено банкрутом, Ñкщо найблищим чаÑом не зроÑте Ñ—Ñ— продуктивніÑÑ‚ÑŒ!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(Керівник)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Компанії об'єдналиÑÑ!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} була викуплена {COMPANY} за {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Ми шукаємо нового влаÑника нашої компанії.{}{}Ви бажаєте купити {COMPANY} за {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}БÐÐКРУТ!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} буде закрита кредиторами Ñ– вÑе майно буде продане!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}ЗаÑновано нову компанію!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} починає будівництво Ð±Ñ–Ð»Ñ {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Ðеможливо купити компанію...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Тарифи на доÑтавку вантажів
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Днів у дорозі
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Плата за доÑтавку 10 одиниць (або 10,000 літрів) вантажу на відÑтань 20 квадратів
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Вкл/викл графік типів вантажу
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Інженер
+STR_7067_TRAFFIC_MANAGER :Регулювальник
+STR_7068_TRANSPORT_COORDINATOR :ДиÑпетчер
+STR_7069_ROUTE_SUPERVISOR :Координатор
+STR_706A_DIRECTOR :Директор
+STR_706B_CHIEF_EXECUTIVE :Генеральний директор
+STR_706C_CHAIRMAN :Голова правліннÑ
+STR_706D_PRESIDENT :Президент компанії
+STR_706E_TYCOON :Магнат
+STR_706F_BUILD_HQ :{BLACK}Будувати ОфіÑ
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Будувати ОфіÑ/Показати ОфіÑ
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}ПеренеÑÐµÐ½Ð½Ñ ÐžÑ„Ñ–Ñу в інше міÑце. Коштує 1% від вартоÑÑ‚Ñ– компанії
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Ðеможливо збудувати ОфіÑ...
+STR_7072_VIEW_HQ :{BLACK}Показати ОфіÑ
+STR_RELOCATE_HQ :{BLACK}ПеренеÑти ОфіÑ
+STR_COMPANY_PASSWORD :{BLACK}Пароль
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Пароль захищає вашу компанію від Ð¿Ñ€Ð¸Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ñ–Ð½ÑˆÐ¸Ñ… гравців.
+STR_SET_COMPANY_PASSWORD :Ð’ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ð°Ñ€Ð¾Ð»ÑŽ
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}Світова економічна криза!{}{}ФінанÑиÑти очікують Ñпад виробництва та попиту!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Криза минула!{}{}Ð—Ð±Ñ–Ð»ÑŒÑˆÐµÐ½Ð½Ñ Ð´Ñ–ÑльноÑÑ‚Ñ– підніме промиÑловіÑÑ‚ÑŒ коли економіка ÑтабілізуєтьÑÑ!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Розмір вікна великий/малий
+STR_7076_COMPANY_VALUE :{GOLD}ВартіÑÑ‚ÑŒ компанії: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Купити 25% компанії
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Продати 25% компанії
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Купити 25% цієї компанії
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Продати 25% цієї компанії
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Ðеможливо купити 25% цієї компанії...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}Ðеможливо продати 25% цієї компанії...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% володіє {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% володіє {COMPANY}{} {COMMA}% володіє {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} викуплено {COMPANY}!
+STR_7080_PROTECTED :{WHITE}Ð¦Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ñ–Ñ Ð¿Ð¾ÐºÐ¸ ще не продаєтьÑÑ...
+
+STR_LIVERY_DEFAULT :Стандартний колір
+STR_LIVERY_STEAM :Паровози
+STR_LIVERY_DIESEL :Дизельні потÑги
+STR_LIVERY_ELECTRIC :Електричні потÑги
+STR_LIVERY_MONORAIL :МонорельÑові потÑги
+STR_LIVERY_MAGLEV :ПотÑги на магнітній подушці
+STR_LIVERY_DMU :
+STR_LIVERY_EMU :
+STR_LIVERY_PASSENGER_WAGON_STEAM :ПаÑажирÑький вагон (пар)
+STR_LIVERY_PASSENGER_WAGON_DIESEL :ПаÑажирÑький вагон (дизель)
+STR_LIVERY_PASSENGER_WAGON_ELECTRIC :ПаÑажирÑький вагон (електричка)
+STR_LIVERY_FREIGHT_WAGON :Завантажений вагон
+STR_LIVERY_BUS :ÐвтобуÑ
+STR_LIVERY_TRUCK :Вантажівка
+STR_LIVERY_PASSENGER_SHIP :ПаÑажиирÑький паром
+STR_LIVERY_FREIGHT_SHIP :Завантажений корабель
+STR_LIVERY_HELICOPTER :Гелікоптер
+STR_LIVERY_SMALL_PLANE :Малий літак
+STR_LIVERY_LARGE_PLANE :Великий літак
+
+STR_LIVERY_GENERAL_TIP :{BLACK}Показати оÑновні кольорові Ñхеми
+STR_LIVERY_TRAIN_TIP :{BLACK}Показати кольорову Ñхему поїздів
+STR_LIVERY_ROADVEH_TIP :{BLACK}Показати кольорові Ñхеми Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾
+STR_LIVERY_SHIP_TIP :{BLACK}Показати кольорову Ñхему кораблів
+STR_LIVERY_AIRCRAFT_TIP :{BLACK}Показати кольорові Ñхеми літаків
+STR_LIVERY_PRIMARY_TIP :{BLACK}Виберіть оÑновний колір Ð´Ð»Ñ Ð¾Ð±Ñ€Ð°Ð½Ð¾Ñ— Ñхеми
+STR_LIVERY_SECONDARY_TIP :{BLACK}Оберіть другий колір Ð´Ð»Ñ Ñхеми
+STR_LIVERY_PANEL_TIP :{BLACK}Оберіть кольорові Ñхеми Ð´Ð»Ñ Ð·Ð¼Ñ–Ð½Ð¸, чи декілька з CTRL+клік. Клікніть ліворуч щоб ввімкнути/вимкнути викориÑÑ‚Ð°Ð½Ð½Ñ Ñхем
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (паровий)
+STR_8001_MJS_250_DIESEL :MJS 250 (Дизель)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut Diesel
+STR_8006_POWERNAUT_DIESEL :Powernaut Diesel
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (Пар)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (Пар)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (Пар)
+STR_800A_SH_8P_STEAM :SH '8P' (Пар)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (Дизель)
+STR_800C_DASH_DIESEL :'Dash' (Дизель)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (Дизель)
+STR_800E_UU_37_DIESEL :UU '37' (Дизель)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (Дизель)
+STR_8010_CS_4000_DIESEL :CS 4000 (Дизель)
+STR_8011_CS_2400_DIESEL :CS 2400 (Дизель)
+STR_8012_CENTENNIAL_DIESEL :Centennial (Дизель)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (Дизель)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (Дизель)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (Дизель)
+STR_8016_SH_125_DIESEL :SH '125' (Дизель)
+STR_8017_SH_30_ELECTRIC :SH '30' (Електричка)
+STR_8018_SH_40_ELECTRIC :SH '40' (Електричка)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (Електричка)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (Електричка)
+STR_801B_PASSENGER_CAR :ПаÑажирÑький
+STR_801C_MAIL_VAN :Поштовий
+STR_801D_COAL_CAR :Вугільний
+STR_801E_OIL_TANKER :Ðафтовий
+STR_801F_LIVESTOCK_VAN :Вагон Ð´Ð»Ñ Ñ‚Ð²Ð°Ñ€Ð¸Ð½
+STR_8020_GOODS_VAN :Товарний
+STR_8021_GRAIN_HOPPER :Вагон Ð´Ð»Ñ Ð·ÐµÑ€Ð½Ð°
+STR_8022_WOOD_TRUCK :Вагон Ð´Ð»Ñ Ð´ÐµÑ€ÐµÐ²Ð¸Ð½Ð¸
+STR_8023_IRON_ORE_HOPPER :Вагон Ð´Ð»Ñ Ð·Ð°Ð»Ñ–Ð·Ð½Ð¾Ñ— руди
+STR_8024_STEEL_TRUCK :Вагон Ð»Ð»Ñ Ñталі
+STR_8025_ARMORED_VAN :Броньований вагон
+STR_8026_FOOD_VAN :Вагон Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´ÑƒÐºÑ‚Ñ–Ð²
+STR_8027_PAPER_TRUCK :Вагон Ð´Ð»Ñ Ð¿Ð°Ð¿ÐµÑ€Ñƒ
+STR_8028_COPPER_ORE_HOPPER :Вагон Ð´Ð»Ñ Ð¼Ñ–Ð´Ð½Ð¾Ñ— руди
+STR_8029_WATER_TANKER :ЦиÑтерна Ð´Ð»Ñ Ð²Ð¾Ð´Ð¸
+STR_802A_FRUIT_TRUCK :Вагон Ð´Ð»Ñ Ñ„Ñ€ÑƒÐºÑ‚Ñ–Ð²
+STR_802B_RUBBER_TRUCK :Вагон Ð´Ð»Ñ ÐºÐ°ÑƒÑ‡ÑƒÐºÑƒ
+STR_802C_SUGAR_TRUCK :Вагон Ð´Ð»Ñ Ñ†ÑƒÐºÑ€Ñƒ
+STR_802D_COTTON_CANDY_HOPPER :Вагон Ð´Ð»Ñ Ñолодощів
+STR_802E_TOFFEE_HOPPER :Вагон Ð´Ð»Ñ Ñ–Ñ€Ð¸Ñок
+STR_802F_BUBBLE_VAN :Вагон Ð´Ð»Ñ ÐºÑƒÐ»ÑŒÐ¾Ðº
+STR_8030_COLA_TANKER :ЦиÑтерна Ð´Ð»Ñ ÐºÐ¾Ð»Ð¸
+STR_8031_CANDY_VAN :Вагон Ð´Ð»Ñ Ñ†ÑƒÐºÐµÑ€Ð¾Ðº
+STR_8032_TOY_VAN :Вагон Ð´Ð»Ñ Ñ–Ð³Ñ€Ð°ÑˆÐ¾Ðº
+STR_8033_BATTERY_TRUCK :вантажівка Ð´Ð»Ñ Ð±Ð°Ñ‚Ð°Ñ€ÐµÐ¹Ð¾Ðº
+STR_8034_FIZZY_DRINK_TRUCK :вантажівка Ð´Ð»Ñ Ð³Ð°Ð·Ð¾Ð²Ð°Ð½Ð¾Ñ— води
+STR_8035_PLASTIC_TRUCK :вантажівка Ð´Ð»Ñ Ð¿Ð»Ð°Ñтику
+STR_8036_X2001_ELECTRIC :'X2001' (Електричка)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Електричка)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :ПаÑажирÑький
+STR_803A_MAIL_VAN :Вагон Ð´Ð»Ñ Ð¿Ð¾ÑˆÑ‚Ð¸
+STR_803B_COAL_CAR :Вагон Ð´Ð»Ñ Ð²ÑƒÐ³Ñ–Ð»Ð»Ñ
+STR_803C_OIL_TANKER :ЦиÑтерна Ð´Ð»Ñ Ð½Ð°Ñ„Ñ‚Ð¸
+STR_803D_LIVESTOCK_VAN :вантажівка Ð´Ð»Ñ Ñ‚Ð²Ð°Ñ€Ð¸Ð½
+STR_803E_GOODS_VAN :вантажівка Ð´Ð»Ñ Ñ‚Ð¾Ð²Ð°Ñ€Ñ–Ð²
+STR_803F_GRAIN_HOPPER :вагон Ð´Ð»Ñ Ð·ÐµÑ€Ð½Ð°
+STR_8040_WOOD_TRUCK :луÑовіз
+STR_8041_IRON_ORE_HOPPER :вагон Ð´Ð»Ñ Ð·Ð°Ð»Ñ–Ð·Ð½Ð¾Ñ—Ñ— руди
+STR_8042_STEEL_TRUCK :вантажівка Ð´Ð»Ñ Ñталі
+STR_8043_ARMORED_VAN :броньоване авто
+STR_8044_FOOD_VAN :вагон Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´ÑƒÐºÑ‚Ñ–Ð²
+STR_8045_PAPER_TRUCK :вантажівка Ð´Ð»Ñ Ð¿Ð°Ð¿ÐµÑ€Ñƒ
+STR_8046_COPPER_ORE_HOPPER :вагон Ð´Ð»Ñ Ð¼Ñ–Ð´Ð½Ð¾Ñ— руди
+STR_8047_WATER_TANKER :Танкер Ð´Ð»Ñ Ð²Ð¾Ð´Ð¸
+STR_8048_FRUIT_TRUCK :вантажівка Ð´Ð»Ñ Ñ„Ñ€ÑƒÐºÑ‚Ñ–Ð²
+STR_8049_RUBBER_TRUCK :вантажівка Ð´Ð»Ñ ÐºÐ°ÑƒÑ‡ÑƒÐºÑƒ
+STR_804A_SUGAR_TRUCK :вантажівка Ð´Ð»Ñ Ñ†ÑƒÐºÑ€Ñƒ
+STR_804B_COTTON_CANDY_HOPPER :вагон Ð´Ð»Ñ Ñ†ÑƒÐºÑ€Ð¾Ð²Ð¾Ñ— вати
+STR_804C_TOFFEE_HOPPER :вагон Ð´Ð»Ñ Ñ–Ñ€Ð¸Ñок
+STR_804D_BUBBLE_VAN :вагон Ð´Ð»Ñ Ð±ÑƒÐ»ÑŒÐ±Ð°ÑˆÐ¾Ðº
+STR_804E_COLA_TANKER :Танкер Ð´Ð»Ñ ÐºÐ¾Ð»Ð¸
+STR_804F_CANDY_VAN :вагон Ð´Ð»Ñ Ñ†ÑƒÐºÐµÑ€Ð¾Ðº
+STR_8050_TOY_VAN :вагон Ð´Ð»Ñ Ñ–Ð³Ñ€Ð°ÑˆÐ¾Ðº
+STR_8051_BATTERY_TRUCK :вагон Ð´Ð»Ñ Ð±Ð°Ñ‚Ð°Ñ€ÐµÐ¹Ð¾Ðº
+STR_8052_FIZZY_DRINK_TRUCK :вантажівка Ð´Ð»Ñ Ð³Ð°Ð·Ð¾Ð²Ð°Ð½Ð¾Ñ— води
+STR_8053_PLASTIC_TRUCK :вантажівка Ð´Ð»Ñ Ð¿Ð»Ð°Ñтику
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (електричка)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (електричка)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (електричка)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (електричка)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :ПаÑажирÑький катер
+STR_805A_MAIL_VAN :поштовий вагон
+STR_805B_COAL_CAR :вугільний фургон
+STR_805C_OIL_TANKER :нафтовий танкер
+STR_805D_LIVESTOCK_VAN :вагон Ð´Ð»Ñ Ñ…ÑƒÐ´Ð¾Ð±Ð¸
+STR_805E_GOODS_VAN :вагон Ð´Ð»Ñ Ñ‚Ð¾Ð²Ð°Ñ€Ñ–Ð²
+STR_805F_GRAIN_HOPPER :вагон Ð´Ð»Ñ Ð·ÐµÑ€Ð½Ð°
+STR_8060_WOOD_TRUCK :ліÑовіз
+STR_8061_IRON_ORE_HOPPER :вагон Ð´Ð»Ñ Ð·Ð°Ð»Ñ–Ð·Ð½Ð¾Ñ— руди
+STR_8062_STEEL_TRUCK :вантажівка Ð´Ð»Ñ Ñталі
+STR_8063_ARMORED_VAN :броноване авто
+STR_8064_FOOD_VAN :вантажівка Ð´Ð»Ñ Ñ—Ð¶Ñ–
+STR_8065_PAPER_TRUCK :вантажівка Ð´Ð»Ñ Ð¿Ð°Ð¿ÐµÑ€Ñƒ
+STR_8066_COPPER_ORE_HOPPER :вагон Ð´Ð»Ñ Ð¼Ñ–Ð´Ð½Ð¾Ñ— руди
+STR_8067_WATER_TANKER :циÑтерна Ð´Ð»Ñ Ð²Ð¾Ð´Ð¸
+STR_8068_FRUIT_TRUCK :фургон Ð´Ð»Ñ Ñ„Ñ€ÑƒÐºÑ‚Ñ–Ð²
+STR_8069_RUBBER_TRUCK :вантажівка Ð´Ð»Ñ ÐºÐ°ÑƒÑ‡ÑƒÐºÑƒ
+STR_806A_SUGAR_TRUCK :вантажівка Ð´Ð»Ñ Ñ†ÑƒÐºÑ€Ñƒ
+STR_806B_COTTON_CANDY_HOPPER :вагон Ð´Ð»Ñ Ñ†ÑƒÐºÑ€Ð¾Ð²Ð¾Ñ— вати
+STR_806C_TOFFEE_HOPPER :вагон Ð´Ð»Ñ Ñ–Ñ€Ð¸Ñу
+STR_806D_BUBBLE_VAN :вагон Ð´Ð»Ñ ÐºÑƒÐ»ÑŒÐ¾Ðº
+STR_806E_COLA_TANKER :вагон Ð´Ð»Ñ ÐºÐ¾Ð»Ð¸
+STR_806F_CANDY_VAN :вагон Ð´Ð»Ñ Ñ†ÑƒÐºÐµÑ€Ð¾Ðº
+STR_8070_TOY_VAN :вагон Ð´Ð»Ñ Ñ–Ð³Ñ€Ð°ÑˆÐ¾Ðº
+STR_8071_BATTERY_TRUCK :вагон Ð´Ð»Ñ Ð±Ð°Ñ‚Ð°Ñ€ÐµÐ¹Ð¾Ðº
+STR_8072_FIZZY_DRINK_TRUCK :вагон Ð´Ð»Ñ Ð³Ð°Ð·Ð¾Ð²Ð°Ð½Ð¾Ñ— води
+STR_8073_PLASTIC_TRUCK :вагон Ð´Ð»Ñ Ð¿Ð»Ð°Ñтику
+STR_8074_MPS_REGAL_BUS :MPS Regal автобуÑ
+STR_8075_HEREFORD_LEOPARD_BUS :Hereford Leopard автобуÑ
+STR_8076_FOSTER_BUS :Foster автобуÑ
+STR_8077_FOSTER_MKII_SUPERBUS :Foster MkII автобуÑ
+STR_8078_PLODDYPHUT_MKI_BUS :Ploddyphut MkI автобуÑ
+STR_8079_PLODDYPHUT_MKII_BUS :Ploddyphut MkII автобуÑ
+STR_807A_PLODDYPHUT_MKIII_BUS :Ploddyphut MkIII автобуÑ
+STR_807B_BALOGH_COAL_TRUCK :Balogh вугільний фургон
+STR_807C_UHL_COAL_TRUCK :Uhl вугільний фургон
+STR_807D_DW_COAL_TRUCK :DW вугільний фургон
+STR_807E_MPS_MAIL_TRUCK :MPS поштовий фургон
+STR_807F_REYNARD_MAIL_TRUCK :Reynard поштовий фургон
+STR_8080_PERRY_MAIL_TRUCK :Perry поштовий фургон
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :MightyMover поштовий фургон
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Powernaught поштовий фургон
+STR_8083_WIZZOWOW_MAIL_TRUCK :Wizzowow поштовий фургон
+STR_8084_WITCOMBE_OIL_TANKER :Witcombe циÑтерна Ð´Ð»Ñ Ð½Ð°Ñ„Ñ‚Ð¸
+STR_8085_FOSTER_OIL_TANKER :Foster циÑтерна Ð´Ð»Ñ Ð½Ð°Ñ„Ñ‚Ð¸
+STR_8086_PERRY_OIL_TANKER :Perry циÑтерна Ð´Ð»Ñ Ð½Ð°Ñ„Ñ‚Ð¸
+STR_8087_TALBOTT_LIVESTOCK_VAN :Talbott фургон Ð´Ð»Ñ Ñ…ÑƒÐ´Ð¾Ð±Ð¸
+STR_8088_UHL_LIVESTOCK_VAN :Uhl фургон Ð´Ð»Ñ Ñ…ÑƒÐ´Ð¾Ð±Ð¸
+STR_8089_FOSTER_LIVESTOCK_VAN :Foster фургон Ð´Ð»Ñ Ñ…ÑƒÐ´Ð¾Ð±Ð¸
+STR_808A_BALOGH_GOODS_TRUCK :Balogh вантажівка Ð´Ð»Ñ Ñ‚Ð¾Ð²Ð°Ñ€Ñ–Ð²
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Craighead вантажівка Ð´Ð»Ñ Ñ‚Ð¾Ð²Ð°Ñ€Ñ–Ð²
+STR_808C_GOSS_GOODS_TRUCK :Goss вантажівка Ð´Ð»Ñ Ñ‚Ð¾Ð²Ð°Ñ€Ñ–Ð²
+STR_808D_HEREFORD_GRAIN_TRUCK :Hereford вантажівка Ð´Ð»Ñ Ð·ÐµÑ€Ð½Ð°
+STR_808E_THOMAS_GRAIN_TRUCK :Thomas вантажівка Ð´Ð»Ñ Ð·ÐµÑ€Ð½Ð°
+STR_808F_GOSS_GRAIN_TRUCK :Goss вантажівка Ð´Ð»Ñ Ð·ÐµÑ€Ð½Ð°
+STR_8090_WITCOMBE_WOOD_TRUCK :Witcombe вантажівка Ð´Ð»Ñ Ð´ÐµÑ€ÐµÐ²Ð°
+STR_8091_FOSTER_WOOD_TRUCK :Foster вантажівка Ð´Ð»Ñ Ð´ÐµÑ€ÐµÐ²Ð°
+STR_8092_MORELAND_WOOD_TRUCK :Moreland вантажівка Ð´Ð»Ñ Ð´ÐµÑ€ÐµÐ²Ð°
+STR_8093_MPS_IRON_ORE_TRUCK :MPS вантажівка Ð´Ð»Ñ Ð·Ð°Ð»Ñ–Ð·Ð½Ð¾Ñ— руди
+STR_8094_UHL_IRON_ORE_TRUCK :Uhl вантажівка Ð´Ð»Ñ Ð·Ð°Ð»Ñ–Ð·Ð½Ð¾Ñ— руди
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Chippy вантажівка Ð´Ð»Ñ Ð·Ð°Ð»Ñ–Ð·Ð½Ð¾Ñ— руди
+STR_8096_BALOGH_STEEL_TRUCK :Balogh вантажівка Ð´Ð»Ñ Ñталі
+STR_8097_UHL_STEEL_TRUCK :Uhl вантажівка Ð´Ð»Ñ Ñталі
+STR_8098_KELLING_STEEL_TRUCK :Kelling вантажівка Ð´Ð»Ñ Ñталі
+STR_8099_BALOGH_ARMORED_TRUCK :Balogh броньоване авто
+STR_809A_UHL_ARMORED_TRUCK :Uhl броньоване авто
+STR_809B_FOSTER_ARMORED_TRUCK :Foster броньоване авто
+STR_809C_FOSTER_FOOD_VAN :Foster авто Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´ÑƒÐºÑ‚Ñ–Ð²
+STR_809D_PERRY_FOOD_VAN :Perry авто Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´ÑƒÐºÑ‚Ñ–Ð²
+STR_809E_CHIPPY_FOOD_VAN :Chippy авто Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´ÑƒÐºÑ‚Ñ–Ð²
+STR_809F_UHL_PAPER_TRUCK :Uhl вантажівка Ð´Ð»Ñ Ð¿Ð°Ð¿ÐµÑ€Ñƒ
+STR_80A0_BALOGH_PAPER_TRUCK :Balogh вантажівка Ð´Ð»Ñ Ð¿Ð°Ð¿ÐµÑ€Ñƒ
+STR_80A1_MPS_PAPER_TRUCK :MPS вантажівка Ð´Ð»Ñ Ð¿Ð°Ð¿ÐµÑ€Ñƒ
+STR_80A2_MPS_COPPER_ORE_TRUCK :MPS вантажівка Ð´Ð»Ñ Ð¼Ñ–Ð´Ð½Ð¾Ñ— руди
+STR_80A3_UHL_COPPER_ORE_TRUCK :Uhl вантажівка Ð´Ð»Ñ Ð¼Ñ–Ð´Ð½Ð¾Ñ— руди
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Goss вантажівка Ð´Ð»Ñ Ð¼Ñ–Ð´Ð½Ð¾Ñ— руди
+STR_80A5_UHL_WATER_TANKER :Uhl циÑтерна Ð´Ð»Ñ Ð²Ð¾Ð´Ð¸
+STR_80A6_BALOGH_WATER_TANKER :Balogh циÑтерна Ð´Ð»Ñ Ð²Ð¾Ð´Ð¸
+STR_80A7_MPS_WATER_TANKER :MPS циÑтерна Ð´Ð»Ñ Ð²Ð¾Ð´Ð¸
+STR_80A8_BALOGH_FRUIT_TRUCK :Balogh вантажівка Ð´Ð»Ñ Ñ„Ñ€ÑƒÐºÑ‚Ñ–Ð²
+STR_80A9_UHL_FRUIT_TRUCK :Uhl вантажівка Ð´Ð»Ñ Ñ„Ñ€ÑƒÐºÑ‚Ñ–Ð²
+STR_80AA_KELLING_FRUIT_TRUCK :Kelling вантажівка Ð´Ð»Ñ Ñ„Ñ€ÑƒÐºÑ‚Ñ–Ð²
+STR_80AB_BALOGH_RUBBER_TRUCK :Balogh вантажівка Ð´Ð»Ñ ÐºÐ°ÑƒÑ‡ÑƒÐºÐ°
+STR_80AC_UHL_RUBBER_TRUCK :Uhl вантажівка Ð´Ð»Ñ ÐºÐ°ÑƒÑ‡ÑƒÐºÐ°
+STR_80AD_RMT_RUBBER_TRUCK :RMTвантажівка Ð´Ð»Ñ ÐºÐ°ÑƒÑ‡ÑƒÐºÐ°
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :MightyMover вантажівка Ð´Ð»Ñ Ñ†ÑƒÐºÑ€Ñƒ
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Powernaught вантажівка Ð´Ð»Ñ Ñ†ÑƒÐºÑ€Ñƒ
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Wizzowow вантажівка Ð´Ð»Ñ Ñ†ÑƒÐºÑ€Ñƒ
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :MightyMover вантажівка Ð´Ð»Ñ ÐºÐ¾Ð»Ð¸
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Powernaught вантажівка Ð´Ð»Ñ ÐºÐ¾Ð»Ð¸
+STR_80B3_WIZZOWOW_COLA_TRUCK :Wizzowow вантажівка Ð´Ð»Ñ ÐºÐ¾Ð»Ð¸
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :MightyMover вантажівка Ð´Ð»Ñ Ñ†ÑƒÐºÑ€Ð¾Ð²Ð¾Ñ— вати
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Powernaught вантажівка Ð´Ð»Ñ Ñолодощів
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Wizzowow вантажівка Ð´Ð»Ñ Ñолодощів
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :MightyMover вантажівка Ð´Ð»Ñ Ñ–Ñ€Ð¸Ñок
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Powernaught вантажівка Ð´Ð»Ñ Ñ–Ñ€Ð¸Ñок
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Wizzowow вантажівка Ð´Ð»Ñ Ñ–Ñ€Ð¸Ñок
+STR_80BA_MIGHTYMOVER_TOY_VAN :MightyMover вагон Ð´Ð»Ñ Ñ–Ð³Ñ€Ð°ÑˆÐ¾Ðº
+STR_80BB_POWERNAUGHT_TOY_VAN :Powernaught вагон Ð´Ð»Ñ Ñ–Ð³Ñ€Ð°ÑˆÐ¾Ðº
+STR_80BC_WIZZOWOW_TOY_VAN :Wizzowow вагон Ð´Ð»Ñ Ñ–Ð³Ñ€Ð°ÑˆÐ¾Ðº
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :MightyMover вантажівка Ð´Ð»Ñ Ñ†ÑƒÐºÐµÑ€Ð¾Ðº
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Powernaught вантажівка Ð´Ð»Ñ Ñ†ÑƒÐºÐµÑ€Ð¾Ðº
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Wizzowow вантажівка Ð´Ð»Ñ Ñ†ÑƒÐºÐµÑ€Ð¾Ðº
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :MightyMover вантажівка Ð´Ð»Ñ Ð±Ð°Ñ‚Ð°Ñ€ÐµÐ¹Ð¾Ðº
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Powernaught вантажівка Ð´Ð»Ñ Ð±Ð°Ñ‚Ð°Ñ€ÐµÐ¹Ð¾Ðº
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Wizzowow вантажівка Ð´Ð»Ñ Ð±Ð°Ñ‚Ð°Ñ€ÐµÐ¹Ð¾Ðº
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :MightyMover вантажівка Ð´Ð»Ñ Ð³Ð°Ð·Ð¾Ð²Ð°Ð½Ð¾Ñ— води
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Powernaught вантажівка Ð´Ð»Ñ Ð³Ð°Ð·Ð¾Ð²Ð°Ð½Ð¾Ñ— води
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Wizzowow вантажівка Ð´Ð»Ñ Ð³Ð°Ð·Ð¾Ð²Ð°Ð½Ð¾Ñ— води
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :MightyMover вантажівка Ð´Ð»Ñ Ð¿Ð»Ð°Ñтику
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Powernaught вантажівка Ð´Ð»Ñ Ð¿Ð»Ð°Ñтику
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Wizzowow вантажівка Ð´Ð»Ñ Ð¿Ð»Ð°Ñтику
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :MightyMover вантажівка Ð´Ð»Ñ ÐºÑƒÐ»ÑŒÐ¾Ðº
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Powernaught вантажівка Ð´Ð»Ñ ÐºÑƒÐ»ÑŒÐ¾Ðº
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Wizzowow вантажівка Ð´Ð»Ñ ÐºÑƒÐ»ÑŒÐ¾Ðº
+STR_80CC_MPS_OIL_TANKER :MPS циÑтерна Ð´Ð»Ñ Ð½Ð°Ñ„Ñ‚Ð¸
+STR_80CD_CS_INC_OIL_TANKER :CS-Inc. циÑтерна Ð´Ð»Ñ Ð½Ð°Ñ„Ñ‚Ð¸
+STR_80CE_MPS_PASSENGER_FERRY :MPS Ð´Ð»Ñ Ð¿Ð°Ñажирів
+STR_80CF_FFP_PASSENGER_FERRY :FFP Ð´Ð»Ñ Ð¿Ð°Ñажирів
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Bakewell 300 Hovercraft
+STR_80D1_CHUGGER_CHUG_PASSENGER :Chugger-Chug Ð´Ð»Ñ Ð¿Ð°Ñажирів
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Shivershake Ð´Ð»Ñ Ð¿Ð°Ñажирів
+STR_80D3_YATE_CARGO_SHIP :Yate вантажний корабель
+STR_80D4_BAKEWELL_CARGO_SHIP :Bakewell вантажний корабель
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Mightymover вантажний корабель
+STR_80D6_POWERNAUT_CARGO_SHIP :Powernaut вантажний корабель
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Tricario гелікоптер
+STR_80FE_GURU_X2_HELICOPTER :Guru X2 гелікоптер
+STR_80FF_POWERNAUT_HELICOPTER :Powernaut гелікоптер
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð²Ñ–Ð´ виробника транÑпорту
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}Ми розробили новий {STRING} - бажаєте екÑлюзивно кориÑтуватиÑÑŒ ним протÑгом року, так ми побачимо Ñк він зарекомендує Ñебе перед тим Ñк буде доÑтупним Ð´Ð»Ñ Ð²ÑÑ–Ñ…?
+STR_8102_RAILROAD_LOCOMOTIVE :локомотив
+STR_8103_ROAD_VEHICLE :автомобіль
+STR_8104_AIRCRAFT :літак
+STR_8105_SHIP :корабель
+STR_8106_MONORAIL_LOCOMOTIVE :монорельÑовий поїзд
+STR_8107_MAGLEV_LOCOMOTIVE :поїзд на магнітній подушці
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}{TOWN} Залізничне депо
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Жителі ÑвÑткують . . .{}Перший поїзд з'ÑвивÑÑ Ð½Ð° {STATION}!
+STR_8802_DETAILS :{WHITE}{STRING} (Детально)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Поїзд на шлÑху
+STR_8804 :{SETX 10}{COMMA}: {STRING}{STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING}{STRING}
+STR_8806_GO_TO :ПрÑмувати до {STATION}
+STR_8807_GO_TO_TRANSFER :ПрÑмувати до {STATION} (ПереÑадити Ñ– забрати вантаж)
+STR_8808_GO_TO_UNLOAD :ПрÑмувати до {STATION} (Ðе завантажувати)
+STR_8809_GO_TO_TRANSFER_UNLOAD :ПрÑмувати до {STATION} (ПереÑадити Ñ– залишити вантаж)
+STR_880A_GO_TO_LOAD :ПрÑмувати до {STATION} (Завантажити)
+STR_880B_GO_TO_TRANSFER_LOAD :ПрÑмувати до {STATION} (ПереÑадити Ñ– завантажити повніÑÑ‚ÑŽ)
+STR_880C_GO_NON_STOP_TO :ПрÑмувати без зупинок до {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :ПрÑмувати без зупинок до {STATION} (ПереÑадити Ñ– забрати вантаж)
+STR_880E_GO_NON_STOP_TO_UNLOAD :ПрÑмувати без зупинок до {STATION} (Ðе завантажувати)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :ПрÑмувати без зупинок до {STATION} (ПереÑадити Ñ– залишити вантаж)
+STR_8810_GO_NON_STOP_TO_LOAD :ПрÑмувати без зупинок до {STATION} (Завантажити)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :ПрÑмувати без зупинок до {STATION} (ПереÑадити Ñ– завантажити повніÑÑ‚ÑŽ)
+STR_GO_TO_TRAIN_DEPOT :ПрÑмувати до {TOWN} депо
+STR_SERVICE_AT_TRAIN_DEPOT :РемонтуватиÑÑŒ в {TOWN} депо
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :ПрÑмувати без зупинок до {TOWN} депо
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :РемонтуватиÑÑŒ без зупинок в {TOWN} депо
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}ПрÑмує до {TOWN} депо
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}ПрÑмує до {TOWN} депо, {VELOCITY}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE :{LTBLUE}ТехоглÑд в {TOWN} депо
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE_VEL :{LTBLUE}ТехоглÑд в {TOWN} депо, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (Ðевірний наказ)
+
+STR_UNKNOWN_DESTINATION :невідомий напрÑм
+STR_8812_EMPTY :{LTBLUE}порожній
+STR_8813_FROM :{LTBLUE}{CARGO} з {STATION}
+STR_FROM_MULT :{LTBLUE}{CARGO} з {STATION} (x{NUM})
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}Поїзд {COMMA} чекає в депо
+STR_8815_NEW_VEHICLES :{BLACK}Ðовий транÑпорт
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Поїзд дуже довгий
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Поїзд можна змінювати тільки тоді, коли зупинений в депо
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} Поїзд{P "" и ів}
+
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Ðовий залізничний транÑпорт
+STR_NEW_ELRAIL_VEHICLES :{WHITE}Ðові елекричні потÑги
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Ðовий монорельÑовий транÑпорт
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Ðовий транÑпорт на магнітній подушці
+STR_ALL_AVAIL_RAIL_VEHICLES :{WHITE}ПотÑги
+
+STR_881F_BUILD_VEHICLE :{BLACK}Будувати
+STR_CLONE_ROAD_VEHICLE :{BLACK}Клонувати
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}Будувати копію авто. Утримуйте CTRL Ð´Ð»Ñ Ñпільного завданнÑ
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Будувати копію авто. ÐатиÑніть на цю кнопку Ñ– потім на авто в депо або ззовні. Утримуйте CTRL Ð´Ð»Ñ Ñпільного завданнÑ
+STR_CLONE_TRAIN :{BLACK}Клонувати
+STR_CLONE_TRAIN_INFO :{BLACK}Будувати копію поїзда з уÑіма вагонами. Утримуйте CTRL Ð´Ð»Ñ Ñпільного завданнÑ
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}Будувати копію поїзда з уÑіма вагонами. ÐатиÑніть на цю кнопку Ñ– потім на поїзд в депо або ззовні. Утримуйте CTRL Ð´Ð»Ñ Ñпільного завданнÑ
+STR_8820_RENAME :{BLACK}Перейменувати
+STR_8823_SKIP :{BLACK}ПропуÑтити
+STR_8824_DELETE :{BLACK}Видалити
+STR_8825_NON_STOP :{BLACK}Без зупинок
+STR_8826_GO_TO :{BLACK}ПрÑмувати
+STR_8827_FULL_LOAD :{BLACK}Повне завантаженнÑ
+STR_8828_UNLOAD :{BLACK}Ðе завантажувати
+STR_REFIT :{BLACK}Переобладнати
+STR_REFIT_TIP :{BLACK}Оберіть на Ñкий тип вантажу переобладнати це завданнÑ. Control+клік видалити команду переобладнаннÑ
+STR_REFIT_ORDER :(Переобладнати до {STRING})
+STR_8829_ORDERS :{WHITE}{VEHICLE} (Ðакази)
+STR_882A_END_OF_ORDERS :{SETX 10}- - Кінець наказів - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}ТехоглÑд
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Ðеможливо збудувати поїзд...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Рік випуÑку: {LTBLUE}{NUM}{BLACK} Ціна: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Ціна: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}ЗавантаженнÑ
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}Поїзд повинен ÑтоÑти в депо
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Ðеможлтво відправити поїзд в депо...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Ðе має міÑÑ†Ñ Ð´Ð»Ñ Ð½Ð°ÐºÐ°Ð·Ñ–Ð²
+STR_8832_TOO_MANY_ORDERS :{WHITE}Дуже багато наказів
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Ðеможливо додати наказ...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Ðеможливо видалити наказ...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Ðеможливо змінити наказ...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Ðеможливо переміÑтити транÑпорт...
+STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}задній потÑг зажди Ñлідує follow its front counterpart!!!
+STR_8838_N_A :немає{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Ðеможливо продати поїзд...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Ðеможливо знайти маршрут до міÑцевого депо
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Ðеможливо зупинити поїзд...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Інтервал техоглÑду: {LTBLUE}{COMMA}днів{BLACK} ОÑтанній техоглÑд: {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Інтервал техоглÑду: {LTBLUE}{COMMA}%{BLACK} ОÑтанній техоглÑд: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK} Поїзди - клікніть на поїзді Ð´Ð»Ñ Ð´ÐµÑ‚Ð°Ð»ÑŒÐ½Ð¾Ñ— інформаціїї
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Будувати поїзд(потребує залізничне депо)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Поїзди - клікніть на поїзді Ð´Ð»Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ—., перетÑгніть Ð´Ð»Ñ Ð´Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ Ð²Ð¸Ð»ÑƒÑ‡ÐµÐ½Ð½Ñ
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Будувати новий потÑг
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}ПеретÑгніть потÑг Ñюди, щоб продати його
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Показати депо в центрі головного екрану
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}СпиÑок поїздів - клікніть на поїзді Ð´Ð»Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ—
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Будувати вибраний поїзд
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Перейменуйте тип транÑпорту
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}ДіÑльніÑÑ‚ÑŒ поїзда - клікніть тут Ð´Ð»Ñ Ð¹Ð¾Ð³Ð¾ запуÑку/зупиненнÑ
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Показати маршрут поїзда
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Показати поїзд в центрі головноuj екрану
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Ðаправити поїзд у депо
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Ігнорувати червоне Ñвітло Ñемафору!
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Розвернути поїзд
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Показати детальну інформацію
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Збільшити період техоглÑду
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Зменшити період техоглÑду
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Показати інформацію про вантаж
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Показати інформацію про вагони
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Показати міÑткіÑÑ‚ÑŒ кожного вагону
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Паказати загальну міÑткіÑÑ‚ÑŒ поїзда, розділену за типом вантажу
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Маршрутний лиÑÑ‚ - клікніть на заданні Ð´Ð»Ñ Ð¹Ð¾Ð³Ð¾ вибору. CTRL + клік показати Ñтанцію
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}ПропуÑтити це завданнÑ, перейти до наÑтупного
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Видалити виділене завданнÑ
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Ðе зупинÑтиÑÑ Ð½Ð° відміченій Ñтанції
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Ð’Ñтавити новий пункт перед відміченим або додати в кінець
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Чекати повного Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð½Ð° цій Ñтанції
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Лише розвантажитиÑÑ Ð½Ð° цій Ñтанції
+STR_SERVICE_HINT :{BLACK}ПропуÑтити це Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð¿Ð¾ÐºÐ¸ обÑÐ»ÑƒÐ³Ð¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ñ‚Ñ€Ñ–Ð±Ð½Ðµ!!!
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}ДоÑтупний новий {STRING}!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Ціна: {CURRENCY} Вага: {WEIGHT_S}{}ШвидкіÑÑ‚ÑŒ: {VELOCITY} ПотужніÑÑ‚ÑŒ: {POWER}{}ВартіÑÑ‚ÑŒ екÑплуатації: {CURRENCY}/рік{}МіÑткіÑÑ‚ÑŒ: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}ЗламавÑÑ
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}Вік: {LTBLUE}{STRING}{BLACK} ТранÑпортні витрати: {LTBLUE}{CURRENCY}/рік
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Вага: {LTBLUE}{WEIGHT_S} {BLACK}ПотужніÑÑ‚ÑŒ: {LTBLUE}{POWER}{BLACK} МакÑ. швидкіÑÑ‚ÑŒ: {LTBLUE}{VELOCITY}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Прибуток: {LTBLUE}{CURRENCY} (минулого року: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}ÐадійніÑÑ‚ÑŒ: {LTBLUE}{COMMA}% {BLACK}Поломок піÑÐ»Ñ Ð¾Ñтаннього техоглÑду: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Зупинено
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Ðеможливо проїхати Ñигнал - небезпечно...
+STR_8863_CRASHED :{RED}ÐваріÑ!
+
+STR_8865_NAME_TRAIN :{WHITE}Ðазвати поїзд
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}Ðеможливо назвати поїзд...
+STR_8867_NAME_TRAIN :{BLACK}Ðазвати поїзд
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}ÐваріÑ!{}Поїзди зіткнулиÑÑ.{}{COMMA} загинуло.
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Ðеможливо розвернути поїзд...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Перейменувати тип поїзду
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Ðеможливо перейменувати тип поїзду...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Ðаказати транÑпорту примуÑово відвантажити вантаж
+STR_886F_TRANSFER :{BLACK}ПереÑадка
+
+STR_TRAIN_STOPPING :{RED}ЗупинÑєтьÑÑ
+STR_TRAIN_STOPPING_VEL :{RED}ЗупинÑєтьÑÑ, {VELOCITY}
+STR_INCOMPATIBLE_RAIL_TYPES :Залізничні колій неÑуміÑні
+STR_TRAIN_NO_POWER :{RED}Ðеелектрифіковано
+STR_TRAIN_START_NO_CATENARY :Ðема електрики, поїзд Ñтоїть
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Ðа шлÑху авто
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} Ðвто
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}{TOWN} Ðвто депо
+STR_9004_NEW_VEHICLES :{BLACK}Ðовий транÑпорт
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}Ðове авто
+STR_9007_BUILD_VEHICLE :{BLACK}Будувати
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Ðеможливо будувати авто...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (Детально)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}Вік: {LTBLUE}{STRING}{BLACK} ТранÑпортні витрати: {LTBLUE}{CURRENCY}/рік
+STR_900E_MAX_SPEED :{BLACK}МакÑ. швидкіÑÑ‚ÑŒ: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Прибуток цього року: {LTBLUE}{CURRENCY} (минулого року: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}ÐадійнітÑÑŒ: {LTBLUE}{COMMA}% {BLACK}Поломок піÑÐ»Ñ Ð¾Ñтаннього техоглÑду: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Рік випуÑку: {LTBLUE}{NUM}{BLACK} Ціна: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}МіÑткіÑÑ‚ÑŒ: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}...авто повинно ÑтоÑти в депо
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Ðеможливо продати авто...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Ðеможливо зупинити авто...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}Ðвто {COMMA} чекає в депо
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}ПрÑмує до {TOWN} депо
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}ПрÑмує до {TOWN} депо, {VELOCITY}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE :{LTBLUE}ТехоглÑд в {TOWN} дорожне депо
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE_VEL :{LTBLUE}ТехоглÑд в {TOWN} дорожне депо, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Ðеможливо направити авто в депо...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Ðеможливо знайти міÑцеве депо
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Ðвто - натиÑніть на авто Ð´Ð»Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ—
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Будувати нове авто (потрібне авто депо)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Показує, Ñку дію виконує авто - натиÑніть Ð´Ð»Ñ Ñ€ÑƒÑ…Ñƒ/зупинки авто
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Показати накази авто
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Показати авто в центрі екрану
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Ðаправити авто в депо
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Розвернути авто
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Показати авто детально
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Ðвто - натиÑніть на авто Ð´Ð»Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ—
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Будувати нове авто
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}ПеретÑгніть авто Ñюди, щоб продати
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Показати авто депо в центрі екрану
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}СпиÑок авто - натиÑніть на авто Ð´Ð»Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ—
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Будувати вибране авто
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}ДоÑтупне нове авто!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Ціна: {CURRENCY}{}ШвидкіÑÑ‚ÑŒ: {VELOCITY}{}ТранÑпортні витрати: {CURRENCY}/рік{}МіÑткіÑÑ‚ÑŒ: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Ðазвати авто
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Ðеможливо назвати авто...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Ðазвати авто
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}:Жителі ÑвÑткують . . .{}Перший Ð°Ð²Ñ‚Ð¾Ð±ÑƒÑ Ð·'ÑвивÑÑ Ð½Ð° {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Жителі ÑвÑткують . . .{}Перша вантажівка з'ÑвилаÑÑ Ð½Ð° {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}ÐваріÑ!{}Водій загинув при зіткненні авто з поїздом
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}ÐваріÑ!{}{COMMA} загинуло при зіткненні авто з поїздом
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Ðеможливо розвернути авто...
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}Ðеможливо розвернути довгий транÑпорт
+STR_9034_RENAME :{BLACK}Зміна назви
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Перейменувати тип авто
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Перейменувати тип авто
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Ðеможливо перейменувати тип авто...
+STR_9038_GO_TO_ROADVEH_DEPOT :Їхати в {TOWN} депо
+STR_SERVICE_AT_ROADVEH_DEPOT :РемонтуватиÑÑŒ в {TOWN} депо
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Переобладнати авто Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²ÐµÐ·ÐµÐ½Ð½Ñ Ñ–Ð½ÑˆÐ¸Ñ… вантажів
+STR_REFIT_ROAD_VEHICLE :{BLACK}Переобладнати авто
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Переобладнати авто Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²ÐµÐ·ÐµÐ½Ð½Ñ Ð²Ð¸Ð±Ñ€Ð°Ð½Ð¾Ð³Ð¾ вантажу
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Ðеможливо переобладнати авто
+STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Оберіть тип вантажу Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²ÐµÐ·ÐµÐ½Ð½Ñ
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Будувати порт
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Будівництво порту
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Ðеможливо будувати порт тут...
+STR_9803_SHIP_DEPOT :{WHITE}{TOWN} Корабельне депо
+STR_9804_NEW_SHIPS :{BLACK}Ðові кораблі
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} Кораб{P ель лі лів}
+STR_9808_NEW_SHIPS :{WHITE}Ðові кораблі
+STR_9809_BUILD_SHIP :{BLACK}Будувати корабель
+STR_CLONE_SHIP :{BLACK}Клонувати корабель
+STR_CLONE_SHIP_INFO :{BLACK}Будувати копію кораблÑ. Утримуйте CTRL Ð´Ð»Ñ Ñпільного завданнÑ
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}Будувати копію кораблÑ. ÐатиÑніть на цю кнопку Ñ– потім на корабель в депо або ззовні. Утримуйте CTRL Ð´Ð»Ñ Ñпільного завданнÑ
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}Корабль має бути в депо
+STR_980C_CAN_T_SELL_SHIP :{WHITE}Ðеможливо продати корабель...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Ðеможливо будувати корабель...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Корабель на шлÑху
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Деталі)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}Вік: {LTBLUE}{STRING}{BLACK} ТраÑпортні витрати: {LTBLUE}{CURRENCY}/рік
+STR_9813_MAX_SPEED :{BLACK}МакÑ. швидкіÑÑ‚ÑŒ: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Прибуток цього року: {LTBLUE}{CURRENCY} (минулого року: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}ÐадійніÑÑ‚ÑŒ: {LTBLUE}{COMMA}% {BLACK}Поломок піÑÐ»Ñ Ð¾Ñтаннього техоглÑду: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Рік випуÑку: {LTBLUE}{NUM}{BLACK} Ціна: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}МіÑткіÑÑ‚ÑŒ: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}Ðеможливо зупинити корабель...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Ðеможливо направити корабель в депо...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Ðеможливо знайти міÑцеве депо
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}ПрÑмує до {TOWN} депо
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}ПрÑмує до {TOWN} депо, {VELOCITY}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE :{LTBLUE}ТехоглÑд в {TOWN} корабельне депо
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE_VEL :{LTBLUE}ТехоглÑд в {TOWN} корабельне депо, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}Корабель {COMMA} чекає в депо
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Будувати корабель
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Будувати корабельне депо
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Кораблі - натиÑніть Ð´Ð»Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ—
+STR_9820_BUILD_NEW_SHIP :{BLACK}Будувати корабель
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}ПеретÑгніть корабель Ñюди, щоб продати
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Показати депо в центрі екрану
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Кораблі - натиÑніть Ð´Ð»Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ—
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Будувати корабель (потрібне корабельне депо)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}СпиÑок вибору кораблів - натиÑніть на корабель Ð´Ð»Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ—
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Будувати вибраний корабель
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Показує, Ñку дію виконує корабель - натиÑніть Ð´Ð»Ñ Ñ€ÑƒÑ…Ñƒ/зупинки кораблÑ
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Показати накази кораблÑ
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Показати корабель в центрі екрану
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Ðаправити корабель в депо
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Показати корабель детально
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}ДоÑтупний новий корабель!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Ціна: {CURRENCY} МакÑ. ШвидкітÑÑŒ: {VELOCITY}{}МіÑткіÑÑ‚ÑŒ: {CARGO}{}ТранÑпортні витрати: {CURRENCY}/рік
+STR_982F_NAME_SHIP :{BLACK}Ðазвати корабель
+
+STR_9831_NAME_SHIP :{WHITE}Ðазвати корабель
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Ðеможливо назвати корабель...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Жителі ÑвÑткують . . .{}Перший корабель з'ÑвивÑÑ Ð½Ð° {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}РозміÑтити бакен, Ñкий можна викориÑтовувати Ñк точку маршруту
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Ðеможливо розміÑтити бакен тут...
+STR_9836_RENAME :{BLACK}Зміна назви
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Перейменувати тип кораблÑ
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Перейменувати тип кораблÑ
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Ðеможливо перейменувати тип кораблÑ...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Переобладнати корабель Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²ÐµÐ·ÐµÐ½Ð½Ñ Ñ–Ð½ÑˆÐ¾Ð³Ð¾ виду вантажу
+STR_983B_REFIT :{WHITE}{VEHICLE} (ПереобладнаннÑ)
+STR_983C_REFIT_SHIP :{BLACK}Переобладнати корабель
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Виберіть вид вантажу Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¾Ð±Ð»Ð°Ð´Ð½Ð°Ð½Ð½Ñ
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Переобладнати корабель Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²ÐµÐ·ÐµÐ½Ð½Ñ Ð²Ð¸Ð±Ñ€Ð°Ð½Ð¾Ð³Ð¾ виду вантажу
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Виберіть вид вантажу Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²ÐµÐ·ÐµÐ½Ð½Ñ:-
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Ðова міÑткіÑÑ‚ÑŒ: {GOLD}{CARGO}{}{BLACK}ВартіÑÑ‚ÑŒ переобладнаннÑ: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Ðеможливо переобладнати корабель...
+STR_9842_REFITTABLE :(змінюєтьÑÑ)
+STR_GO_TO_SHIP_DEPOT :Пливти в {TOWN} депо
+SERVICE_AT_SHIP_DEPOT :РемонтуватиÑÑŒ в {TOWN} депо
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Ðеропорти
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Ðеможливо будувати аеропорт тут...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} Ðнгар
+STR_A003_NEW_AIRCRAFT :{BLACK}Ðовий літак
+STR_CLONE_AIRCRAFT :{BLACK}Клонувати
+STR_CLONE_AIRCRAFT_INFO :{BLACK}Будувати копію літака. Утримуйте CTRL Ð´Ð»Ñ Ñпільного завданнÑ
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Будувати копію літака. ÐатиÑніть на цю кнопку Ñ– потім на літак в ангарі або ззовні. Утримуйте CTRL Ð´Ð»Ñ Ñпільного завданнÑ
+STR_A005_NEW_AIRCRAFT :{WHITE}Ðові літаки
+STR_A006_BUILD_AIRCRAFT :{BLACK}Будувати
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Ðеможливо будувати літак...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} Літак {P "" и ів}
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (Ðакази)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (Детально)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Вік: {LTBLUE}{STRING}{BLACK} ТранÑпортні витрати: {LTBLUE}{CURRENCY}/рік
+STR_A00E_MAX_SPEED :{BLACK}МакÑ. швидкіÑÑ‚ÑŒ: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Прибуток цього року: {LTBLUE}{CURRENCY} (минулого року: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}ÐадійніÑÑ‚ÑŒ: {LTBLUE}{COMMA}% {BLACK}Поломок піÑÐ»Ñ Ð¾Ñтаннього техоглÑду: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Рік випуÑку: {LTBLUE}{NUM}{BLACK} Ціна: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Ðеможливо направити літак до ангару...
+STR_HEADING_FOR_HANGAR :{ORANGE}Литить до {STATION} ангару
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}Летить до {STATION} ангару, {VELOCITY}
+STR_HEADING_FOR_HANGAR_SERVICE :{LTBLUE}ТехоглÑд в {STATION} депо
+STR_HEADING_FOR_HANGAR_SERVICE_VEL :{LTBLUE}ТехоглÑд в {STATION} ангарі, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}Літак {COMMA} чекає в ангарі
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Літак на шлÑху
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Ðеможливо зупинити літак...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Літак у польоті
+STR_A019_CAPACITY :{BLACK}МіÑткіÑÑ‚ÑŒ: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}МіÑткіÑÑ‚ÑŒ: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}Літак повинен ÑтоÑти в ангарі
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Ðеможливо продати літак...
+STR_A01D_AIRPORT_CONSTRUCTION :Будувати аеропорт
+STR_A01E_BUILD_AIRPORT :{BLACK}Будувати аеропорт
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Літаки - натиÑніть на літак Ð´Ð»Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ—
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Будувати новий літак (потрібен аеропорт з ангаром)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Літаки - натиÑніть на літак Ð´Ð»Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ—
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Будувати літак
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}ПеретÑгніть літак Ñюди, щоб продати
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Показати ангар в центрі екрану
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}СпиÑок вибору літаків - натиÑніть на літак Ð´Ð»Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ—
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Будувати вибраний літак
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Показує, Ñку дію виконує літак - натиÑніть Ð´Ð»Ñ Ñ€ÑƒÑ…Ñƒ/зупинки літака
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Показати накази літака
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Показати літак в центрі екрану
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Ðаправити літак в ангар
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Показати літак детально
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}ДоÑтупний новий літак!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Ціна: {CURRENCY} МакÑ. швидкіÑÑ‚ÑŒ: {VELOCITY}{}МіÑткіÑÑ‚ÑŒ: {COMMA} паÑажирів, {COMMA} мішків пошти{}ТранÑпортні витрати: {CURRENCY}/рік
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Ðазвати літак
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Ðеможливо назвати...
+STR_A032_NAME_AIRCRAFT :{BLACK}Ðазвати літак
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Жителі ÑвÑткують . . .{}Перший літак з'ÑвивÑÑ Ð½Ð° {STATION}!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}{}{COMMA} загиблих в авіакатаÑтрофі! Літак розбивÑÑ Ð±Ñ–Ð»Ñ {STATION}
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}ÐвіакатаÑтрофа!{}Ð’ літака закінчилоÑÑŒ пальне, {COMMA} загинуло!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Зміна назви
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Перейменувати тип літака
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Перейменувати тип літака
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Ðеможливо перейменувати тип літака...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Переобладнати літак Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²ÐµÐ·ÐµÐ½Ð½Ñ Ñ–Ð½ÑˆÐ¾Ð³Ð¾ виду вантажу
+STR_A03C_REFIT :{WHITE}{VEHICLE} (ПереобладнаннÑ)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Переобладнати літак
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Виберіть вид вантажу Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¾Ð±Ð»Ð°Ð´Ð½Ð°Ð½Ð½Ñ
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Переобладнати літак Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²ÐµÐ·ÐµÐ½Ð½Ñ Ð²Ð¸Ð±Ñ€Ð°Ð½Ð¾Ð³Ð¾ виду вантажу
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Виберіть вид вантажу Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²ÐµÐ·ÐµÐ½Ð½Ñ:-
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Ðова міÑткіÑÑ‚ÑŒ: {GOLD}{STRING}{}{BLACK}ВартіÑÑ‚ÑŒ переобладнаннÑ: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Ðеможливо переобладнати літак...
+STR_GO_TO_AIRPORT_HANGAR :Летіти в {STATION} ангар
+SERVICE_AT_AIRPORT_HANGAR :РемонтуватиÑÑŒ в {STATION} ангарі
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}Дирижабль впав на {STATION}!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}ÐваріÑ!'ÐЛО' зіткнулоÑÑŒ з авто!
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}Вибухнув нафтопереробний завод Ð±Ñ–Ð»Ñ Ð¼Ñ–Ñта {TOWN}!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}За невідомих обÑтавин зруйновано фабрику Ð±Ñ–Ð»Ñ Ð¼Ñ–Ñта {TOWN}!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}'ÐЛО' приземлилоÑÑŒ Ð±Ñ–Ð»Ñ Ð¼Ñ–Ñта {TOWN}!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}Обвал на вугільній шахті призвів до проÑіву грунту Ð±Ñ–Ð»Ñ Ð¼Ñ–Ñта {TOWN}!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Повінь!{}Щонайменше {COMMA} зникло безвіÑти та загинуло!
+
+STR_BRIBE_FAILED :{WHITE}Ваша Ñпроба дати Ñ…Ð°Ð±Ð°Ñ€Ñ Ð±ÑƒÐ»Ð°
+STR_BRIBE_FAILED_2 :{WHITE}викрита міÑцевим Ñлідчим
+STR_BUILD_DATE :{BLACK}Рік випуÑку: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Детальна характериÑтика продуктивноÑÑ‚Ñ–
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}Детально
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}ТранÑпорт:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Станції:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Мін. дохід:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Мін. прибуток:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}МакÑ. прибуток:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}ДоÑтавлено:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Вантаж:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Кошти:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Кредит:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Ð’Ñього:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Загальна кількіÑÑ‚ÑŒ транÑпорту
+STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}Загальна кількіÑÑ‚ÑŒ Ñтанцій.
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}Прибуток транÑпорту з найменшим доходом (з уÑього транÑпорту від 2 років)
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Ðайменший міÑÑчний прибуток за оÑтанні 12 кварталів
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Ðайбільший міÑÑчний прибуток за оÑтанні 12 кварталів
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}КількіÑÑ‚ÑŒ одиниць вантажу, доÑтавлених за оÑтанні 4 квартали
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}КількіÑÑ‚ÑŒ видів вантажу, доÑтвлених за оÑтанній квартал
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Сума коштів на рахунку компанії
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}Сума кредиту, що надано компанії
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Загальна кількіÑÑŒ балів
+
+STR_NEWGRF_SETTINGS_BUTTON :{BLACK}NewGRF ÐалаштуваннÑ
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð¾Ð²Ð¾Ñ— графіки
+STR_NEWGRF_APPLY_CHANGES :{BLACK}ЗаÑтоÑувати зміни
+STR_NEWGRF_SET_PARAMETERS :{BLACK}Ð’ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ñ–Ð²
+STR_NEWGRF_TIP :{BLACK}СпиÑок уÑÑ–Ñ… ваших уÑтановок нової графіки. Виберіть Ð´Ð»Ñ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}ВідÑутні файли нової графіки! Прочитайте інÑтрукцію по вÑтановленню нової графіки
+STR_NEWGRF_FILENAME :{BLACK}Ім'Ñ Ñ„Ð°Ð¹Ð»Ñƒ: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}ID графіки: {SILVER}{STRING}
+STR_NEWGRF_MD5SUM :{BLACK}MD5Ñума: {SILVER}{STRING}
+STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}Ви хочете зробити зміни у вже запущеній грі; це може привеÑти до завиÑÐ°Ð½Ð½Ñ OpenTTD.{}Ви впевнені що хочете зробити це?
+
+STR_NEWGRF_ADD :{BLACK}Додати
+STR_NEWGRF_ADD_TIP :{BLACK}Додатифайли NewGRF до ÑпиÑку
+STR_NEWGRF_REMOVE :{BLACK}Видалити
+STR_NEWGRF_REMOVE_TIP :{BLACK}Видалити обрані файли NewGRF зі ÑпиÑку
+STR_NEWGRF_MOVEUP :{BLACK}ПереміÑтити вверх
+STR_NEWGRF_MOVEUP_TIP :{BLACK}ПереміÑтити вибрані файли вверх по ÑпиÑку
+STR_NEWGRF_MOVEDOWN :{BLACK}ПереміÑтити вниз
+STR_NEWGRF_MOVEDOWN_TIP :{BLACK}ПереміÑтити вибрані файли вниз по ÑпиÑку
+STR_NEWGRF_FILE_TIP :{BLACK}СпиÑок вÑтановлених NewGRF файлів. КÑлікніть на файлі щоб змінити його параметри
+STR_NEWGRF_PARAMETER :{BLACK}Параметри: {SILVER}{STRING}
+STR_NEWGRF_PARAMETER_QUERY :{BLACK}ВведітьNewGRF параметри
+STR_NEWGRF_NO_INFO :{BLACK}Ðемає доÑтупної інформації
+
+STR_NEWGRF_ADD_CAPTION :{WHITE}ДоÑтупні NewGRF файли
+STR_NEWGRF_ADD_FILE :{BLACK}Додати файл
+STR_NEWGRF_ADD_FILE_TIP :{BLACK}Додати вибраний NewGRF файл до Вашої конфігурації
+STR_NEWGRF_RESCAN_FILES :{BLACK}ПереглÑнути файли
+STR_NEWGRF_RESCAN_FILES_TIP :{BLACK}Оновити ÑпиÑок доÑтупних NewGRF файлів
+STR_NEWGRF_DUPLICATE_GRFID :{WHITE}Ðеможу додати файл: Ð´ÑƒÐ±Ð»ÑŽÐ²Ð°Ð½Ð½Ñ GRF ID
+
+STR_NEWGRF_NOT_FOUND :{RED}Таких файлів не знайдено
+STR_NEWGRF_DISABLED :{RED}Вимкнено
+
+STR_CURRENCY_WINDOW :{WHITE}Вибір грошової одиниці
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Валютний курÑ: {ORANGE}{CURRENCY} = Ј {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Роздільник:
+STR_CURRENCY_PREFIX :{LTBLUE}ПрефікÑ:
+STR_CURRENCY_SUFFIX :{LTBLUE}СуфікÑ:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Перехід на євро: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Перехід на євро: {ORANGE}ні
+STR_CURRENCY_PREVIEW :{LTBLUE}ВідображеннÑ: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ–Ð½ÑˆÐ¾Ñ— грошової одиниці
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} поїзд{P "" и ів}
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} авто
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} літак{P "" и ів}
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} кораб{P ель лі лів}
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Показати вÑÑ– поїзди, Ñкі заходÑÑ‚ÑŒ на цю Ñтанцію
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Показати вÑÑ– авто, Ñкі заходÑÑ‚ÑŒ на цю Ñтанцію
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Показати вÑÑ– літаки, Ñкі залітають на цю Ñтанцію
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Показати вÑÑ– кораблі, Ñкі запливають на цю Ñтанцію
+
+STR_VEH_WITH_SHARED_ORDERS_LIST :{WHITE}Спільні маршрути {COMMA} транÑп.заÑоб{P у iв ів}
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}Показати транÑпорт з таким Ñамим маршрутом
+
+### depot strings
+STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP :{BLACK}Продати вÑÑ– поїзди з депо
+STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP :{BLACK}Продати вÑÑ– автомобілі з депо
+STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP :{BLACK}Продати вÑÑ– кораблі з депо
+STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP :{BLACK}Продати вÑÑ– літаки з ангару
+
+STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP :{BLACK}Отримати ÑпиÑок вÑих поїздів, що заходÑÑ‚ÑŒ до ангарів
+STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP :{BLACK}Отримати ÑпиÑок вÑих авто, що заходÑÑ‚ÑŒ до ангарів
+STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP :{BLACK}Отримати ÑпиÑок вÑих кораблів, що заходÑÑ‚ÑŒ до ангарів
+STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP :{BLACK}Отримати ÑпиÑок вÑих літаків, що заходÑÑ‚ÑŒ до ангарів
+
+STR_DEPOT_AUTOREPLACE_TRAIN_TIP :{BLACK}Оновити вÑÑ– поїзди в депо
+STR_DEPOT_AUTOREPLACE_ROADVEH_TIP :{BLACK}Оновити вÑÑ– автомобілі в депо
+STR_DEPOT_AUTOREPLACE_SHIP_TIP :{BLACK}Оновити вÑÑ– кораблі в депо
+STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP :{BLACK}Оновити вÑÑ– літаки в депо
+
+STR_VEHICLE_LIST_TRAIN_DEPOT :{BLACK}{STRING} - {COMMA} Поїзд{P "" и ів}
+STR_VEHICLE_LIST_ROADVEH_DEPOT :{BLACK}{STRING} - {COMMA} Ðвто {P "" "" ""}
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} Кораб{P ель лі лів}
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} Ðеропорт
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}Оновити {STRING}
+STR_REPLACE_VEHICLES_START :{BLACK}Почати оновленнÑ
+STR_REPLACE_VEHICLES_STOP :{BLACK}Зупинити оновленнÑ
+STR_NOT_REPLACING :{BLACK}Ðе можна оновити
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Ðе вибрано машину
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Виберіть транÑпорт Ð´Ð»Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Виберіть новий транÑпорт, Ñким ви бажаєте замінити Ñтарий
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}ÐатиÑніть Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð¿Ð¸Ð½ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑу Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ‚Ñгів що вибрані ліворуч
+STR_REPLACE_HELP_START_BUTTON :{BLACK}ÐатиÑніть Ð´Ð»Ñ Ð·Ð°Ð¿ÑƒÑку Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ‚Ñгів, що вибрані праворуч на потÑги що вибрані праворуч
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Виберіть тип колії, Ð´Ð»Ñ Ñкої Ви хочете оновити потÑг
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Показує на Ñкий потÑг буде замінено потÑг, зображелий ліворуч
+STR_REPLACE_HELP :{BLACK}Це дозволить Вам оновити одні види потÑгів іншими, коли потÑг прибуде в депо
+STR_REPLACE_REMOVE_WAGON :{BLACK}Продаж вагонів!!!: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Дозволити автооновленню видалÑти вагони зберігаючи довжину потÑгу(починаючи Ñпереду), Ñкщо Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ñ€Ð¾Ð±Ð¸Ñ‚ÑŒ поїзд довшим.
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}ОновленнÑ: {ORANGE}{SKIP}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} ЕКСПЕРИМЕÐТÐЛЬÐО {}ÐŸÐµÑ€ÐµÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð¼Ñ–Ð¶ вікнами заміни потÑгів та вагонів.{}Ðвтозаміна потÑгів відбудетьÑÑ Ð»Ð¸ÑˆÐµ в тому випадку, Ñкщо Ñпівпаде тип вантажу що перевозитьÑÑ. Ð¦Ñ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ° проводитьÑÑ Ð´Ð»Ñ ÐºÐ¾Ð¶Ð½Ð¾Ð³Ð¾ вагону під Ñ‡Ð°Ñ Ð°Ð²Ñ‚Ð¾Ð·Ð°Ð¼Ñ–Ð½Ð¸.
+STR_ENGINE_NOT_BUILDABLE :{WHITE}потÑг неможна будувати
+
+STR_ENGINES :ПотÑги
+STR_WAGONS :Вагони
+
+STR_MASS_STOP_DEPOT_TRAIN_TIP :{BLACK}ÐатиÑніть Ð´Ð»Ñ Ð·ÑƒÐ¿Ð¸Ð½ÐºÐ¸ вÑÑ–Ñ… поїздів, що в депо
+STR_MASS_STOP_DEPOT_ROADVEH_TIP :{BLACK}ÐатиÑніть Ð´Ð»Ñ Ð·ÑƒÐ¿Ð¸Ð½ÐºÐ¸ вÑÑ–Ñ… авто, що в депо
+STR_MASS_STOP_DEPOT_SHIP_TIP :{BLACK}ÐатиÑніть Ð´Ð»Ñ Ð·ÑƒÐ¿Ð¸Ð½ÐºÐ¸ вÑÑ–Ñ… кораблів, що в депо
+STR_MASS_STOP_HANGAR_TIP :{BLACK}ÐатиÑніть Ð´Ð»Ñ Ð·ÑƒÐ¿Ð¸Ð½ÐºÐ¸ вÑÑ–Ñ… літаків, що в депо
+
+STR_MASS_START_DEPOT_TRAIN_TIP :{BLACK}ÐатиÑніть Ð´Ð»Ñ Ð²Ð¸Ñ—Ð·Ð´Ñƒ поїздів з депо
+STR_MASS_START_DEPOT_ROADVEH_TIP :{BLACK}ÐатиÑніть Ð´Ð»Ñ Ð²Ð¸Ñ—Ð·Ð´Ñƒ вÑÑ–Ñ… авто з депо
+STR_MASS_START_DEPOT_SHIP_TIP :{BLACK}ÐатиÑніть Ð´Ð»Ñ Ð²Ð¸Ñ—Ð·Ð´Ñƒ вÑÑ–Ñ… кораблів з депо
+STR_MASS_START_HANGAR_TIP :{BLACK}ÐатиÑніть Ð´Ð»Ñ Ð²Ð¸Ð»ÑŒÐ¾Ñ‚Ñƒ вÑÑ–Ñ… літаків з депо
+
+STR_MASS_STOP_LIST_TIP :{BLACK}ÐатиÑніть Ð´Ð»Ñ Ð·ÑƒÐ¿Ð¸Ð½ÐºÐ¸ вÑÑ–Ñ… авто зі ÑпиÑку
+STR_MASS_START_LIST_TIP :{BLACK}ÐатиÑніть Ð´Ð»Ñ Ð²Ð¸Ñ—Ð·Ð´Ñƒ вÑÑ–Ñ… авто зі ÑпиÑку
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}СпиÑок позначень - {COMMA} Позначен{P Ð½Ñ Ð½Ñ ÑŒ}
+
+STR_ORDER_REFIT_FAILED :{WHITE}ÐŸÐµÑ€ÐµÐ¾Ð±Ð»Ð°Ð´Ð½Ð°Ð½Ð½Ñ Ð°Ð²Ð°Ñ€Ñ–Ð¹Ð½Ð¾ зупинене {STRING} {COMMA}
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :ЗалізницÑ
+STR_ELRAIL_VEHICLES :Електрифіковані поїзди
+STR_MONORAIL_VEHICLES :МонорельÑ
+STR_MAGLEV_VEHICLES :Магнітна подушка
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Ціна: {GOLD}{CURRENCY}{BLACK} Вага: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}ШвидкіÑÑ‚ÑŒ: {GOLD}{VELOCITY}{BLACK} ПотужніÑÑ‚ÑŒ: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}ШвидкіÑÑ‚ÑŒ: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}ТранÑпортні витрати: {GOLD}{CURRENCY}/рік
+STR_PURCHASE_INFO_CAPACITY :{BLACK}МіÑткіÑÑ‚ÑŒ: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Рік випуÑку: {GOLD}{NUM}{BLACK} Вік: {GOLD}{COMMA} Ñ€ {P ік оки оків}
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}ÐадійніÑÑ‚ÑŒ: {GOLD}{COMMA}%
+STR_PURCHASE_INFO_COST :{BLACK}Ціна: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Вага: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Ціна: {GOLD}{CURRENCY}{BLACK} ШвидкіÑÑ‚ÑŒ: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}МіÑткіÑÑ‚ÑŒ: {GOLD}{COMMA} паÑажир{P "" и ів}, {COMMA} міш{P ок ки ків} пошти
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}ПотужніÑÑ‚ÑŒ: {GOLD}+{POWER}{BLACK} Вага: {GOLD}+{WEIGHT_S}
+STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Переобладнати на: {GOLD}
+STR_PURCHASE_INFO_ALL_TYPES :Ð’ÑÑ– типи вантажів
+STR_PURCHASE_INFO_ALL_BUT :Ð’ÑÑ– крім {GOLD}
+
+########### String for New Landscape Generator
+
+STR_GENERATE :{WHITE}Генерувати
+STR_RANDOM :{BLACK}Випадково
+STR_RANDOM_HELP :{BLACK}Змінити початкове Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ð³ÐµÐ½ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð°
+STR_WORLD_GENERATION_CAPTION :{WHITE}Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ñ Ñвіту
+STR_RANDOM_SEED :{BLACK}Початкове значеннÑ:
+STR_RANDOM_SEED_HELP :{BLACK}Клік Ð´Ð»Ñ Ð²Ð²Ð¾Ð´Ñƒ значеннÑ
+STR_LAND_GENERATOR :{BLACK}Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ñ–Ñ Ð»Ð°Ð½Ð´ÑˆÐ°Ñ„Ñ‚Ñƒ:
+STR_TREE_PLACER :{BLACK}ÐаÑÐ°Ð´Ð¶ÐµÐ½Ð½Ñ Ð´ÐµÑ€ÐµÐ²:
+STR_HEIGHTMAP_ROTATION :{BLACK}Поворот рельєфу
+STR_TERRAIN_TYPE :{BLACK}Тип ландшафту:
+STR_QUANTITY_OF_SEA_LAKES :{BLACK}Рівень морÑ:
+STR_SMOOTHNESS :{BLACK}Згладжений:
+STR_SNOW_LINE_HEIGHT :{BLACK}Ð›Ñ–Ð½Ñ–Ñ Ñнігу:
+STR_DATE :{BLACK}Дата:
+STR_NUMBER_OF_TOWNS :{BLACK}К-Ñ‚ÑŒ міÑÑ‚:
+STR_NUMBER_OF_INDUSTRIES :{BLACK}К-Ñ‚ÑŒ промиÑловоÑтей:
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_SNOW_LINE_UP :{BLACK}Підвищити лінію Ñнігу
+STR_SNOW_LINE_DOWN :{BLACK}Понизити лінію Ñнігу
+STR_SNOW_LINE_QUERY_CAPT :{WHITE}Змінити виÑоту лінії Ñнігу
+STR_START_DATE_QUERY_CAPT :{WHITE}Змінити рік початку гри
+STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Завелике значеннÑ
+STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Розміри дуже великі. Продовжити генерацію?
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_HEIGHTMAP_NAME :{BLACK}Ім'Ñ Ñ€ÐµÐ»ÑŒÑ”Ñ„Ð°:
+STR_HEIGHTMAP_SIZE :{BLACK}Розмір: {ORANGE}{NUM} x {NUM}
+STR_GENERATION_WORLD :{WHITE}Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ñ–Ñ Ñвіту...
+STR_GENERATION_ABORT :{BLACK}Перервати
+STR_GENERATION_ABORT_CAPTION :{WHITE}Перервати генерацію Ñвіту
+STR_GENERATION_ABORT_MESSAGE :{YELLOW}Ви дійÑно хочете перервати генерацію Ñвіту
+STR_PROGRESS :{WHITE}{NUM}% завершено
+STR_GENERATION_PROGRESS :{BLACK}{NUM} / {NUM}
+STR_WORLD_GENERATION :{BLACK}Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ñ Ñвіту
+STR_TREE_GENERATION :{BLACK}ÐаÑÐ°Ð´Ð¶ÐµÐ½Ð½Ñ Ð´ÐµÑ€ÐµÐ²
+STR_UNMOVABLE_GENERATION :{BLACK}Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ñ–Ñ Ð½ÐµÑ€ÑƒÑ…Ð¾Ð¼Ð¾ÑÑ‚Ñ–
+STR_CLEARING_TILES :{BLACK}Розкидати камінÑ
+STR_SETTINGUP_GAME :{BLACK}ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð³Ñ€Ð¸
+STR_PREPARING_TILELOOP :{BLACK}Виконуємо цикл
+STR_PREPARING_GAME :{BLACK}ГенеруєтьÑÑ Ð³Ñ€Ð°
+STR_DIFFICULTY_TO_CUSTOM :{WHITE}Змінити рівень ÑкладноÑÑ‚Ñ–
+STR_SE_FLAT_WORLD :{WHITE}Рівнина
+STR_SE_FLAT_WORLD_TIP :{BLACK}Генерувати рівнину
+STR_SE_RANDOM_LAND :{WHITE}Випадково
+STR_SE_NEW_WORLD :{BLACK}Створити новий Ñценарій
+STR_SE_CAPTION :{WHITE}Тип Ñценарію
+STR_FLAT_WORLD_HEIGHT_DOWN :{BLACK}ПіднÑти рівень рівної землі на 1
+STR_FLAT_WORLD_HEIGHT_UP :{BLACK}ОпуÑтити рівень рівної землі на 1
+STR_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Змінити виÑоту Ñ€Ñ–Ð²Ð½Ñ Ñ€Ñ–Ð²Ð½Ð¾Ñ— землі
+STR_FLAT_WORLD_HEIGHT :{BLACK}ВиÑота Ñ€Ñ–Ð²Ð½Ñ Ð¼Ð¾Ñ€Ñ
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+STR_SMALLMAP_CENTER :{BLACK}Центрувати мінікарту Ñюди
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}Малий
+STR_CITY_AIRPORT :{BLACK}МіÑÑький
+STR_METRO_AIRPORT :{BLACK}Столичний аеропорт
+STR_INTERNATIONAL_AIRPORT :{BLACK}Інтернаціональний
+STR_COMMUTER_AIRPORT :{BLACK}ПриміÑÑький
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Міжконтинентальний
+STR_HELIPORT :{BLACK}Гелікопорт
+STR_HELIDEPOT :{BLACK}Депо
+STR_HELISTATION :{BLACK}Гелікоптерна ÑтанціÑ
+
+STR_SMALL_AIRPORTS :{BLACK}Малі аеропорти
+STR_LARGE_AIRPORTS :{BLACK}Великі аеропорти
+STR_HUB_AIRPORTS :{BLACK}Мега-аеропорти
+STR_HELIPORTS :{BLACK}Геліко-аеропорт
+
+############ Tooltip measurment
+
+STR_MEASURE_LENGTH :{BLACK}Довжина: {NUM}
+STR_MEASURE_AREA :{BLACK}ОблаÑÑ‚ÑŒ: {NUM} x {NUM}
+STR_MEASURE_LENGTH_HEIGHTDIFF :{BLACK}Довжина: {NUM}{}Ð Ñ–Ð·Ð½Ð¸Ñ†Ñ Ð²Ð¸Ñот: {NUM} м
+STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}ДілÑнка: {NUM} x {NUM}{}Ð Ñ–Ð·Ð½Ð¸Ñ†Ñ Ð²Ð¸Ñот: {NUM} м
+
+########
diff --git a/src/lang/unfinished/afrikaans.txt b/src/lang/unfinished/afrikaans.txt
new file mode 100644
index 000000000..eb19dbd18
--- /dev/null
+++ b/src/lang/unfinished/afrikaans.txt
@@ -0,0 +1,2541 @@
+##name Afrikaans
+##ownname Afrikaans
+##isocode af_ZA.UTF-8
+##plural 0
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Oor kant van kaart
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Te naby aan kant van kaart
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Nie genoeg kontant nie - vereis {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Platte land vereis
+STR_0008_WAITING :{BLACK}Wagtend: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (onderweg van
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Aanvaar: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Aanvaar: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :Passasiers
+STR_0010_COAL :Steenkool
+STR_0011_MAIL :Pos
+STR_0012_OIL :Olie
+STR_0013_LIVESTOCK :Lewende Hawe
+STR_0014_GOODS :Goedere
+STR_0015_GRAIN :Graan
+STR_0016_WOOD :Hout
+STR_0017_IRON_ORE :Yster Erts
+STR_0018_STEEL :Staal
+STR_0019_VALUABLES :Kosbaarhede
+STR_001A_COPPER_ORE :Koper Erts
+STR_001B_MAIZE :Mielies
+STR_001C_FRUIT :Vrugte
+STR_001D_DIAMONDS :Diamante
+STR_001E_FOOD :Kos
+STR_001F_PAPER :Papier
+STR_0020_GOLD :Goud
+STR_0021_WATER :Water
+STR_0022_WHEAT :Koring
+STR_0023_RUBBER :Gomlastiek
+STR_0024_SUGAR :Suiker
+STR_0025_TOYS :Speelgoed
+STR_0026_CANDY :Lekkers
+STR_0027_COLA :Cola
+STR_0028_COTTON_CANDY :Spookasem
+STR_0029_BUBBLES :Borrels
+STR_002A_TOFFEE :Tameletjie
+STR_002B_BATTERIES :Batterye
+STR_002C_PLASTIC :Plastiek
+STR_002D_FIZZY_DRINKS :Koeldranke
+STR_002E :
+STR_002F_PASSENGER :Passasier
+STR_0030_COAL :Steenkool
+STR_0031_MAIL :Pos
+STR_0032_OIL :Olie
+STR_0033_LIVESTOCK :Lewende Hawe
+STR_0034_GOODS :Goedere
+STR_0035_GRAIN :Graan
+STR_0036_WOOD :Hout
+STR_0037_IRON_ORE :Yster Erts
+STR_0038_STEEL :Staal
+STR_0039_VALUABLES :Kosbaarhede
+STR_003A_COPPER_ORE :Koper Erts
+STR_003B_MAIZE :Mielies
+STR_003C_FRUIT :Vrugte
+STR_003D_DIAMOND :Diamant
+STR_003E_FOOD :Kos
+STR_003F_PAPER :Papier
+STR_0040_GOLD :Goud
+STR_0041_WATER :Water
+STR_0042_WHEAT :Koring
+STR_0043_RUBBER :Gomlastiek
+STR_0044_SUGAR :Suiker
+STR_0045_TOY :Speelgoed
+STR_0046_CANDY :Lekker
+STR_0047_COLA :Cola
+STR_0048_COTTON_CANDY :Spookasem
+STR_0049_BUBBLE :Borrel
+STR_004A_TOFFEE :Tameletjie
+STR_004B_BATTERY :Battery
+STR_004C_PLASTIC :Plastiek
+STR_004D_FIZZY_DRINK :Koeldranke
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}PS
+STR_ABBREV_COAL :{TINYFONT}SK
+STR_ABBREV_MAIL :{TINYFONT}PS
+STR_ABBREV_OIL :{TINYFONT}OL
+STR_ABBREV_LIVESTOCK :{TINYFONT}LH
+STR_ABBREV_GOODS :{TINYFONT}GD
+STR_ABBREV_GRAIN :{TINYFONT}GR
+STR_ABBREV_WOOD :{TINYFONT}HT
+STR_ABBREV_IRON_ORE :{TINYFONT}YE
+STR_ABBREV_STEEL :{TINYFONT}ST
+STR_ABBREV_VALUABLES :{TINYFONT}KH
+STR_ABBREV_COPPER_ORE :{TINYFONT}CE
+STR_ABBREV_MAIZE :{TINYFONT}GR
+STR_ABBREV_FRUIT :{TINYFONT}VR
+STR_ABBREV_DIAMONDS :{TINYFONT}DM
+STR_ABBREV_FOOD :{TINYFONT}KO
+STR_ABBREV_PAPER :{TINYFONT}PR
+STR_ABBREV_GOLD :{TINYFONT}GD
+STR_ABBREV_WATER :{TINYFONT}WR
+STR_ABBREV_WHEAT :{TINYFONT}GR
+STR_ABBREV_RUBBER :{TINYFONT}GL
+STR_ABBREV_SUGAR :{TINYFONT}SK
+STR_ABBREV_TOYS :{TINYFONT}SG
+STR_ABBREV_SWEETS :{TINYFONT}LE
+STR_ABBREV_COLA :{TINYFONT}CL
+STR_ABBREV_CANDYFLOSS :{TINYFONT}SA
+STR_ABBREV_BUBBLES :{TINYFONT}BO
+STR_ABBREV_TOFFEE :{TINYFONT}TL
+STR_ABBREV_BATTERIES :{TINYFONT}BA
+STR_ABBREV_PLASTIC :{TINYFONT}PL
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}KD
+STR_ABBREV_NONE :{TINYFONT}NS
+STR_ABBREV_ALL :{TINYFONT}ALLE
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Kaart - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Spel Opsies
+STR_00B2_MESSAGE :{YELLOW}Boodskap
+STR_00B3_MESSAGE_FROM :{YELLOW}Boodskap vanaf {STRING}
+STR_00B4_CAN_T_DO_THIS :{WHITE}Kan nie dit doen nie....
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Kan nie die area reinig nie....
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Oorspronklik kopiereg {COPYRIGHT} 1995 Chris Sawyer, Alle regte voorbehou
+STR_00B7_VERSION :{BLACK}OpenTTD bewerking {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 Die OpenTTD span
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Verlaat
+STR_00C8_YES :{BLACK}Ja
+STR_00C9_NO :{BLACK}Nee
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Is jy seker jy wil die spel verlaat en terug gaan na {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Niks
+STR_00D1_DARK_BLUE :Donker Blou
+STR_00D2_PALE_GREEN :Bleek Groen
+STR_00D3_PINK :Pienk
+STR_00D4_YELLOW :Geel
+STR_00D5_RED :Rooi
+STR_00D6_LIGHT_BLUE :Lighte Blou
+STR_00D7_GREEN :Groen
+STR_00D8_DARK_GREEN :Donker Groen
+STR_00D9_BLUE :Blou
+STR_00DA_CREAM :Room
+STR_00DB_MAUVE :Ligpers
+STR_00DC_PURPLE :Pers
+STR_00DD_ORANGE :Oranje
+STR_00DE_BROWN :Bruin
+STR_00DF_GREY :Grys
+STR_00E0_WHITE :Wit
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Te veel voertuie in die spel
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Plek
+STR_00E5_CONTOURS :Hoogtelyne
+STR_00E6_VEHICLES :Voertuie
+STR_00E7_INDUSTRIES :Nywerheide
+STR_00E8_ROUTES :Roete
+STR_00E9_VEGETATION :Plantegroei
+STR_00EA_OWNERS :Eienaars
+STR_00EB_ROADS :{BLACK}{TINYFONT}Paaie
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Spoorwege
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Stasies/Lughawe/Werfe
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Geboue/Nywerheide
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Voertuie
+STR_00F0_100M :{BLACK}{TINYFONT}100m
+STR_00F1_200M :{BLACK}{TINYFONT}200m
+STR_00F2_300M :{BLACK}{TINYFONT}300m
+STR_00F3_400M :{BLACK}{TINYFONT}400m
+STR_00F4_500M :{BLACK}{TINYFONT}500m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Treine
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Pad Voertuie
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Skepe
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Vliegtuie
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Vervoer Roete
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Steenkool Myn
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Krag Stasie
+STR_00FC_FOREST :{BLACK}{TINYFONT}Woud
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}Saagmeul
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Olie Raffineerdery
+STR_00FF_FARM :{BLACK}{TINYFONT}Plaas
+STR_0100_FACTORY :{BLACK}{TINYFONT}Fabriek
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Drukwerke
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Olie Bron
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Yster Erts Myn
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Staalmeul
+STR_0105_BANK :{BLACK}{TINYFONT}Bank
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Papiermeul
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Goud Myn
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Kos Verwerkings Fabriek
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Diamant Myn
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Koper Erts Myn
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Vrugte Plantasie
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Gomlastiek Plantasie
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Water Lewering
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Water Toring
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}Timmerhout Meul
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Spookasem Woud
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Lekker Fabriek
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Battery Plaas
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Cola Bron
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Speelgoed Winkel
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Speelgoed Fabriek
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Plastiek Fonteine
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Koeldrank Fabriek
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Borrel Ontwikkelaar
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Tameletjie Prooi
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Suiker Myn
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Spoorweg Stasie
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Vraagmotor Laai Area
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Bus Stasie
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Lughawe/Helihawe
+STR_011F_DOCK :{BLACK}{TINYFONT}Hawe
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Ru Land
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Gras Land
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Kaal Land
+STR_0123_FIELDS :{BLACK}{TINYFONT}Velde
+STR_0124_TREES :{BLACK}{TINYFONT}Boome
+STR_0125_ROCKS :{BLACK}{TINYFONT}Rotse
+STR_0126_WATER :{BLACK}{TINYFONT}Water
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Geen Besitter
+STR_0128_TOWNS :{BLACK}{TINYFONT}Stede
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Nywerheide
+STR_012A_DESERT :{BLACK}{TINYFONT}Woestyn
+STR_012B_SNOW :{BLACK}{TINYFONT}Sneeu
+STR_012C_MESSAGE :{WHITE}Boodskap
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Kanselleer
+STR_012F_OK :{BLACK}OK
+STR_0130_RENAME :{BLACK}Hernaam
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Te veel naame bepaal
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Verkieste naam alreeds in gebruik
+
+STR_0133_WINDOWS :Vensters
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...besit by {STRING}
+STR_013C_CARGO :{BLACK}Vrag
+STR_013D_INFORMATION :{BLACK}Inligting
+STR_013E_CAPACITIES :{BLACK}Kapasiteite
+STR_013E_TOTAL_CARGO :{BLACK}Totaale Vrag
+STR_013F_CAPACITY :{BLACK}Kapasiteit: {LTBLUE}{CARGO}
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Totaale vrag kapasitiet van die trein:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_0140_NEW_GAME :{BLACK}Nuwe Spel
+STR_0141_LOAD_GAME :{BLACK}Laai Spel
+STR_MULTIPLAYER :{BLACK}Veelspeler
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Kaart groote:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Spel Opsies
+
+STR_0150_SOMEONE :iemand{SKIP}{SKIP}
+STR_0152_TOWN_DIRECTORY :Stad index
+STR_0153_SUBSIDIES :Subsidie
+
+
+
+
+
+
+
+
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Opereer profyt grafiek
+STR_0155_INCOME_GRAPH :Inkoms grafiek
+STR_0156_DELIVERED_CARGO_GRAPH :Afgelewerde vrag grafiek
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Prestasie geskiedenis grafiek
+STR_0158_COMPANY_VALUE_GRAPH :Maatskappy waarde grafiek
+STR_0159_CARGO_PAYMENT_RATES :Vrag betaaling grade
+STR_015A_COMPANY_LEAGUE_TABLE :Maatskappy verbond tafel
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}Omtrent OpenTTD
+STR_015C_SAVE_GAME :Bewaar spel
+STR_015D_LOAD_GAME :Laai spel
+STR_015E_QUIT_GAME :Verlaat Spel
+STR_015F_QUIT :Uitgang
+STR_0160_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Is jy seker jy wil die spel verlaat?
+STR_0161_QUIT_GAME :{WHITE}Verlaat Spel
+
+STR_NO_WAITING_CARGO :{BLACK}Geen vrag van enige tipe is op wag
+
+############ range for months starts
+STR_0162_JAN :Jan
+STR_0163_FEB :Feb
+STR_0164_MAR :Mrt
+STR_0165_APR :Apr
+STR_0166_MAY :Mei
+STR_0167_JUN :Jun
+STR_0168_JUL :Jul
+STR_0169_AUG :Aug
+STR_016A_SEP :Sep
+STR_016B_OCT :Okt
+STR_016C_NOV :Nov
+STR_016D_DEC :Des
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Pouseer spel
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Bewaar spel. verlaat spel, verlaat
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Vertoon lys van maatskappy se stasies
+STR_0174_DISPLAY_MAP :{BLACK}Vertoon kaart
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Vertoon kaart, stad index
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Vertoon stad index
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Vertoon maatskappy finasi�e inligting
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Vertoon generale maatskappy inligting
+STR_0179_DISPLAY_GRAPHS :{BLACK}Vertoon grafieke
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Vertoon maatskappy verbond tafel
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Vertoon lys van maatskappy se treine
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Vertoon lys van maatskappy se pad voertuie
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Vertoon lys van maatskappy se skepe
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Vertoon lys van maatskappy se vliegtuie
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Vergroot die skerm
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Verklein die skerm
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Bou spoorweg spoor
+STR_0182_BUILD_ROADS :{BLACK}Bou Paaie
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Bou skip hawe
+STR_0184_BUILD_AIRPORTS :{BLACK}Bou lughawe
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Plant boome, plaas teken ens.
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Land area inligting
+STR_0187_OPTIONS :{BLACK}Opsies
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}kan nie tussendiens tydperk verander nie...
+STR_018B_CLOSE_WINDOW :{BLACK}Maak venster toe
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Venster titel - sleep die om venster te beweeg
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Breek gebou af ens. op 'n landblokkie
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Verlaag 'n hoek van land
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Verhoog 'n hoek van land
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Rol baan - rol die lys op/af
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Rol baan - rol die lys op/af
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Vertoon land hoogtelyne op kaart
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Vertoon voertuie op kaart
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Vertoon nywerheide op kaart
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Vertoon vervoer roete op kaart
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Vertoon plantegroei op kaart
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Vertoon land besitters op kaart
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Skakel stad naame aan/af op kaart
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Profyt die jaar: {CURRENCY} (verlede jaar: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} jaar{P "" e} ({COMMA})
+STR_AGE_RED :{RED}{COMMA} jaar{P "" e} ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Pad voertuig
+STR_019D_AIRCRAFT :Vliegtuig
+STR_019E_SHIP :Skip
+STR_019F_TRAIN :Trein
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} is besig om out te word
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} is besig om baie oud te word
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} is besig om baie oud te word en moet dringend vervang word
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Land Area Inligting
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Prys om te reinig: {LTBLUE}N/A
+STR_01A5_COST_TO_CLEAR :{BLACK}Prys om te reinig: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :N/A
+STR_01A7_OWNER :{BLACK}Besitter: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Plaaslike raad: {LTBLUE}{STRING}
+STR_01A9_NONE :Geen
+STR_01AA_NAME :{BLACK}Naam
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1ste
+STR_01AD_2ND :2de
+STR_01AE_3RD :3de
+STR_01AF_4TH :4de
+STR_01B0_5TH :5de
+STR_01B1_6TH :6de
+STR_01B2_7TH :7de
+STR_01B3_8TH :8ste
+STR_01B4_9TH :9de
+STR_01B5_10TH :10de
+STR_01B6_11TH :11de
+STR_01B7_12TH :12de
+STR_01B8_13TH :13de
+STR_01B9_14TH :14de
+STR_01BA_15TH :15de
+STR_01BB_16TH :16de
+STR_01BC_17TH :17de
+STR_01BD_18TH :18de
+STR_01BE_19TH :19de
+STR_01BF_20TH :20ste
+STR_01C0_21ST :21ste
+STR_01C1_22ND :22ste
+STR_01C2_23RD :23ste
+STR_01C3_24TH :24ste
+STR_01C4_25TH :25ste
+STR_01C5_26TH :26ste
+STR_01C6_27TH :27ste
+STR_01C7_28TH :28ste
+STR_01C8_29TH :29ste
+STR_01C9_30TH :30ste
+STR_01CA_31ST :31ste
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Vrag aanvaar: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Jazz Bl�kas
+STR_01D3_SOUND_MUSIC :Klank/musiek
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Vertoon klank/musiek venster
+STR_01D5_ALL :{TINYFONT}Alle
+STR_01D6_OLD_STYLE :{TINYFONT}Ou Styl
+STR_01D7_NEW_STYLE :{TINYFONT}Nuwe Styl
+STR_01D8_EZY_STREET :{TINYFONT}Ezy Straat
+STR_01D9_CUSTOM_1 :{TINYFONT}Gewoonte 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Gewoonte 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Musiek Volume
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Effekte Volume
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MIN ' ' ' ' ' ' MAX
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Gaan terug na vorig liedjie in keuse
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Gaan voor na volgende liedjie in keuse
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Ophou musiek speel
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Begin musiek speel
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Sleep skyfie om musiek en effekte volumes te stel
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Liedjie{SETX 88}Titel
+STR_01E9_SHUFFLE :{TINYFONT}Skuifel
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Musiek lys
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Musiek Lys Seleksie
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Liedjie Index
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Musiek Lys - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}Reinig
+STR_01F1_SAVE :{TINYFONT}{BLACK}Bewaar
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Huidige musiek keuse
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Kies 'alle liedjies' musiek lys
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Kies 'ou styl musiek' musiek lys
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Kies 'nuwe styl musiek' musiek lys
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Kies 'Gewoonte 1' musiek lys
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Kies 'Gewoonte 2' musiek lys
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Reinig huidige musiek keuse (slegs Gewoonte 1 of Gewoonte 2)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Bewaar musiek stellings
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Kliek op musiek liedjie om by huidige musiek lys in te sit (slegs Gewoonte 1 of Gewoonte 2)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Skakel musiek lys skuimel aan/af
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Vertoon musiek liedjie keuse venster
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Kliek op diens om uitsig te senter op nywerheid/stad
+STR_01FE_DIFFICULTY :{BLACK}Moeilikheid ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Laaste boodskap/nuus verslag
+STR_0201_MESSAGE_SETTINGS :Boodskap stellings
+STR_MESSAGE_HISTORY_MENU :Boodskap Geskidenis
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Vertoon laaste boodskap/nuus verslag, vertoon boodskap opsies
+STR_0204_MESSAGE_OPTIONS :{WHITE}Boodskap Opsies
+STR_0205_MESSAGE_TYPES :{BLACK}Boodskap tipes:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Aankoms van eerste voetuig by speler se stasie
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Aankoms van eerste voertuig by mededinger se stasie
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Ongelukke / rampe
+STR_0209_COMPANY_INFORMATION :{YELLOW}Maatkappy inligting
+STR_020A_ECONOMY_CHANGES :{YELLOW}Ekonomie veranderings
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Raad / inligting op speler se voertuie
+STR_020C_NEW_VEHICLES :{YELLOW}Nuwe voertuie
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Veranderings na vrag aanvarde
+STR_020E_SUBSIDIES :{YELLOW}Subsidiee
+STR_020F_GENERAL_INFORMATION :{YELLOW}Generale inligting
+STR_MESSAGES_ALL :{YELLOW}Stel alle boodskap tipes na: Af/Opsomming/Volle
+STR_MESSAGE_SOUND :{YELLOW}Speel geluid vir opsommige nuus boodskappe
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...te ver van vorige destinasie
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Hoof maatskappye wat het {NUM}{}({STRING} Vlak) gekry
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Sakeman
+STR_0214_ENTREPRENEUR :Ondernemer
+STR_0215_INDUSTRIALIST :Nyweraar
+STR_0216_CAPITALIST :Kapitalis
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} behaal '{STRING}' stand!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} van {COMPANY} behaal '{STRING}' stand!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Skep Draaiboek
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Draaiboek Redakteur
+STR_0223_LAND_GENERATION :{WHITE}Land Ontwikkeling
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Lukraak Land
+STR_0227_RESET_LAND :{BLACK}Herstel Land
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Vergroot land area om te verlaag/verhoog
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Verminder land area om te verlaag/verhoog
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Ontwikkel lukraak land
+STR_022B_RESET_LANDSCAPE :{BLACK}Herstel landerye
+STR_022C_RESET_LANDSCAPE :{WHITE}Herstel landerye
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Is jy seker jy wil die landerye herstel?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Landerye ontwikkeling
+STR_022F_TOWN_GENERATION :{BLACK}Stad ontwikkeling
+STR_0230_INDUSTRY_GENERATION :{BLACK}Nyweheid ontwikkeling
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Pad konstruksie
+STR_0233_TOWN_GENERATION :{WHITE}Stad Ontwikkeling
+STR_0234_NEW_TOWN :{BLACK}Nuwe Stad
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Bou nuwe stad
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Stad kan nie hier gebou word nie...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...te naby aan kant van kaart
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...te naby aan 'n ander stad
+STR_0239_SITE_UNSUITABLE :{WHITE}...plek ongeskik
+STR_023A_TOO_MANY_TOWNS :{WHITE}...te veel stede
+STR_CANNOT_GENERATE_TOWN :{WHITE}Kan nie enige stede bou nie
+STR_NO_SPACE_FOR_TOWN :{WHITE}...daar is nie meer spasie op die kaart nie
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Vergroot stad
+STR_023C_EXPAND :{BLACK}Uitbrei
+STR_023D_RANDOM_TOWN :{BLACK}Lukraak Stad
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Bou stad in lukraak plek
+STR_023F_INDUSTRY_GENERATION :{WHITE}Nywerheid Ontwikkeling
+STR_0240_COAL_MINE :{BLACK}Steenkool Myn
+STR_0241_POWER_STATION :{BLACK}Krag Stasie
+STR_0242_SAWMILL :{BLACK}Saagmeul
+STR_0243_FOREST :{BLACK}Woud
+STR_0244_OIL_REFINERY :{BLACK}Olie Raffineerdery
+STR_0245_OIL_RIG :{BLACK}Olieboor
+STR_0246_FACTORY :{BLACK}Fabriek
+STR_0247_STEEL_MILL :{BLACK}Staalmeul
+STR_0248_FARM :{BLACK}Plaas
+STR_0249_IRON_ORE_MINE :{BLACK}Yster Erts Myn
+STR_024A_OIL_WELLS :{BLACK}Olie Bron
+STR_024B_BANK :{BLACK}Bank
+STR_024C_PAPER_MILL :{BLACK}Papiermeul
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Kos Verwerking Fabriek
+STR_024E_PRINTING_WORKS :{BLACK}Drukwerke
+STR_024F_GOLD_MINE :{BLACK}Goud Myn
+STR_0250_LUMBER_MILL :{BLACK}Timmehoutmeul
+STR_0251_FRUIT_PLANTATION :{BLACK}Vrugte Plantasie
+STR_0252_RUBBER_PLANTATION :{BLACK}Gomlastiek Plantasie
+STR_0253_WATER_SUPPLY :{BLACK}Water Lewering
+STR_0254_WATER_TOWER :{BLACK}Water Toring
+STR_0255_DIAMOND_MINE :{BLACK}Diamant Myn
+STR_0256_COPPER_ORE_MINE :{BLACK}Koper Erts Myn
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Spookasem Woud
+STR_0258_CANDY_FACTORY :{BLACK}Lekker Fabriek
+STR_0259_BATTERY_FARM :{BLACK}Battery Plaas
+STR_025A_COLA_WELLS :{BLACK}Cola Bron
+STR_025B_TOY_SHOP :{BLACK}Speelgoed Winkel
+STR_025C_TOY_FACTORY :{BLACK}Speelgoed Fabriek
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Plastiek Fonteine
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Koeldrank Fabriek
+STR_025F_BUBBLE_GENERATOR :{BLACK}Borrel Ontwikkelaar
+STR_0260_TOFFEE_QUARRY :{BLACK}Tameletjie Prooi
+STR_0261_SUGAR_MINE :{BLACK}Suiker Myn
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Bou Steenkool Myn
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Bou Krag Stasie
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Bou Saagmeul
+STR_0265_PLANT_FOREST :{BLACK}Beplant Woud
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Bou Olie Raffineerdery
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Bou Olieboor (Kan slegs naby aan kante van kaart gebou word)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Bou Fabriek
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Bou Staalmeul
+STR_026A_CONSTRUCT_FARM :{BLACK}Bou Plaas
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Bou Yster Erts Myn
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Bou Olie Bron
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Bou Bank (kan slegs in stede met 'n populasie grooter as 1200 gebou)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Bou Papiermeul
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Bou Kos Verwerkings Fabriek
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Bou Drukwerke
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Bou Goud Myn
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Bou Bank (Kan slegs in stede gebou word)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Bou Timmerhoutmeul (om reenwoud te reinig en hout te maak)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Beplant Vrugte Plantasie
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Beplant Gomlastiek Plantasie
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Bou Water Lewering
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Bou Water Toring (Kan slegs in stede gebou word)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Bou Diamant Myn
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Bou Koper Erts Myn
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Beplant Spookasem Woud
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Bou Lekker Fabriek
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Bou Battery Plaas
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Bou Cola Bron
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Bou Speelgoed Winkel
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Bou Speelgoed Fabriek
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Bou Plastiek Fonteine
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Bou Koeldrank Fabriek
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Bou Borrel Ontwikkelaar
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Bou Tameletjie Prooi
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Bou Suiker Myn
+STR_0285_CAN_T_BUILD_HERE :{WHITE}Kan nie {STRING} hier bou nie...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...moet eers stad bou
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...slegs een toegelaat per stad
+STR_0288_PLANT_TREES :{BLACK}Boome beplant
+STR_0289_PLACE_SIGN :{BLACK}Plaas teken
+STR_028A_RANDOM_TREES :{BLACK}Lukraak Boome
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Beplant boome lukraake oor laderye
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Plaas rotse op landerye
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Plaas vuurtoring
+STR_028E_PLACE_TRANSMITTER :{BLACK}Plaas sender
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Bepaal woestyn ares.{}Druk en hou CTRL om te verwyder
+STR_CREATE_LAKE :{BLACK}Bepaal water area.{}Dit sal die omgewing vloed as dit teen seevlak is
+STR_0290_DELETE :{BLACK}Uitwis
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Uitwis hele stad
+STR_0292_SAVE_SCENARIO :Bewaar Draaiboek
+STR_0293_LOAD_SCENARIO :Laai draaiboek
+STR_0294_QUIT_EDITOR :Verlaat redakteur
+STR_0295 :
+STR_0296_QUIT :Verlaat
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Bewaar draaiboek, laai draaiboek, verlaat draaiboek redakteur, Verlaat
+STR_0298_LOAD_SCENARIO :{WHITE}Laai Draaiboek
+STR_0299_SAVE_SCENARIO :{WHITE}Bewaar Draaiboek
+STR_029A_PLAY_SCENARIO :{BLACK}Speel Draaiboek
+STR_029B_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Is jy seker jy wil die draaboek verlaat ?
+STR_029C_QUIT_EDITOR :{WHITE}Verlaat Redakteur
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...kan slegs in stede met 'n populasie van te minste 1200 gebou word
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Beweeg die begin datum terug 1 jaar
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Beweeg die begin datum voor 1 jaar
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...altbei einde van brug moet op land wees
+STR_02A1_SMALL :{BLACK}Klein
+STR_02A2_MEDIUM :{BLACK}Middel
+STR_02A3_LARGE :{BLACK}Groot
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Kies stad groote
+STR_02A5_TOWN_SIZE :{YELLOW}Stad groote:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Vertoon laaste boodskap of nuus verslag
+STR_OFF :Af
+STR_FULL :Vol
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Stad index
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Voertuig ontwerp naame
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Gebrekte
+STR_02BF_CUSTOM :Gewoonte
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Bewaar gewoonte naame
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Voertuig ontwerp name keuse
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Bewaar doelgeboude vortuig ontwerp naame
+
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Spel opsies
+STR_02C5_DIFFICULTY_SETTINGS :Moeilikheid stellings
+STR_NEWGRF_SETTINGS :Newgrf stellings
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Stad naame vertoon
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Stasie naame vertoon
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Tekens vertoon
+STR_02D0_FULL_ANIMATION :{SETX 12}Volle animasie
+STR_02D2_FULL_DETAIL :{SETX 12}Volle aanwyse
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Deurskynend geboue
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Land area inligting
+STR_02D6 :
+STR_CONSOLE_SETTING :Skakel troos
+STR_02D7_SCREENSHOT_CTRL_S :Skermskut (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Reuse Skermskut (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :Rakend 'OpenTTD'
+############ range ends here
+
+STR_02DB_OFF :{BLACK}Af
+STR_02DA_ON :{BLACK}An
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Vertoon subsidiee
+STR_02DD_SUBSIDIES :Subsidiee
+STR_02DE_MAP_OF_WORLD :Kaart van wereld
+STR_EXTRA_VIEW_PORT :Ekstra gesigswerf
+STR_02DF_TOWN_DIRECTORY :Stad indeks
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Gesigswerf {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Afskryf na gesigswerf
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Deeg van gesigswerf
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Koers eenheide
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Koers eendheide keuse
+STR_MEASURING_UNITS :{BLACK}Maatre� eenheide
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Maatre� eenheide keuse
+STR_02E6_ROAD_VEHICLES :{BLACK}Pad voertuie
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Selekteer kant van pad waarop voetuie bestuur
+STR_02E9_DRIVE_ON_LEFT :Bestuur op links
+STR_02EA_DRIVE_ON_RIGHT :Bestuur op regs
+STR_02EB_TOWN_NAMES :{BLACK}Stad naame
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Kies styl van stad naame
+
+STR_02F4_AUTOSAVE :{BLACK}Outobewaar
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Kies afstand tussen outomatiese spel bewaarde
+STR_02F7_OFF :Af
+STR_02F8_EVERY_3_MONTHS :Elke 3 maande
+STR_02F9_EVERY_6_MONTHS :Elke 6 maande
+STR_02FA_EVERY_12_MONTHS :Elke 12 maande
+STR_02FB_START_A_NEW_GAME :{BLACK}Begin nuwe spel
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Laai 'n bewaarde spel
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Skep 'n doelgeboude spel w�eld/draaiboek
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Kies enkel-spele spel
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Kies veelspeler spel met 2-8 spelers
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Vertoon spel opsies
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Vertoon moeilikheid opsies
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Begin 'n nuwe spel, met 'n doelgemaakte draaiboek
+STR_0304_QUIT :{BLACK}Verlaat
+STR_0305_QUIT_OPENTTD :{BLACK}Verlaat 'OpenTTD'
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...kan slegs in stede gebou word
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Kies 'gematig' landerye styl
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Kies 'onder-noordpool' landerye styl
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Kies 'onder-tropise' landerye styl
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Kies 'speelgoedland' landerye styl
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Befonds gebou van nuwe nywerheid
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Nywerheid Indeks
+STR_0313_FUND_NEW_INDUSTRY :Befonds nuwe nywerheid
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Befonds nuwe nywerheid
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...kan slegs in stede gebou word
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...kan slegs in reenwoud areas gebou word
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...kan slegs in woestyn areas gebou word
+STR_0319_PAUSED :{YELLOW}* * POUSEER * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Skermskut suksesvollig bewaar as '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}Skermskut gedop!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Koop land vir toekomende gebruik
+STR_032F_AUTOSAVE :{RED}OUTOBEWAAR
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Kies 'Ezy Straat styl musiek' musiek lys
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+############ end of townname region
+
+STR_CURR_GBP :Pounds ()
+STR_CURR_USD :Dollars ($)
+STR_CURR_EUR :Euro ()
+STR_CURR_YEN :Yen ()
+STR_CURR_ATS :Austrian Shilling (ATS)
+STR_CURR_BEF :Belgian Franc (BEF)
+STR_CURR_CHF :Swiss Franc (CHF)
+STR_CURR_CZK :Czech Koruna (CZK)
+STR_CURR_DEM :Deutschmark (DEM)
+STR_CURR_DKK :Danish Krone (DKK)
+STR_CURR_ESP :Peseta (ESP)
+STR_CURR_FIM :Finnish Markka (FIM)
+STR_CURR_FRF :Franc (FRF)
+STR_CURR_GRD :Greek Drachma (GRD)
+STR_CURR_HUF :Hungarian Forint (HUF)
+STR_CURR_ISK :Icelandic Krona (ISK)
+STR_CURR_ITL :Italian Lira (ITL)
+STR_CURR_NLG :Dutch Guilder (NLG)
+STR_CURR_NOK :Norwegian Krone (NOK)
+STR_CURR_PLN :Polish Zloty (PLN)
+STR_CURR_ROL :Romanian Leu (ROL)
+STR_CURR_RUR :Russian Rubles (RUR)
+STR_CURR_SEK :Swedish Krona (SEK)
+
+STR_CURR_CUSTOM :Gewoonte...
+
+STR_OPTIONS_LANG :{BLACK}Taal
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Volskerm
+
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+
+STR_AUTOSAVE_1_MONTH :Elke maand
+STR_AUTOSAVE_FAILED :{WHITE}Outobewaar gedop
+
+STR_MONTH_JAN :Januarie
+STR_MONTH_FEB :Februarie
+STR_MONTH_MAR :Maart
+STR_MONTH_APR :April
+STR_MONTH_MAY :Mei
+STR_MONTH_JUN :Junie
+STR_MONTH_JUL :Julie
+STR_MONTH_AUG :Augustus
+STR_MONTH_SEP :September
+STR_MONTH_OCT :Oktober
+STR_MONTH_NOV :November
+STR_MONTH_DEC :Desember
+
+STR_HEADING_FOR_STATION :{LTBLUE}Op pad na {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}Op pad na {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Geen Opdrae
+STR_NO_ORDERS_VEL :{LTBLUE}Geen opdrae, {VELOCITY}
+
+STR_PASSENGERS :passasiers
+STR_BAGS :sakke
+STR_LITERS :litres
+STR_ITEMS :items
+STR_CRATES :hokke
+STR_NOTHING :
+
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Kan nie opdraglys deel nie...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Kan nie opdraglys afskryf nie...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - Einde van Verdeelde Opdrae - -
+
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}Europees Geldelik Samesmelting!{}{}Die Euro is ingevoer as die enigste koers vir daagliks transaksies in u land!
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}Vliegtuig {COMMA} het te min opdrae in die opgawe
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}vliegtuig {COMMA} het 'n nietig opdrag
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}Vliegtuig {COMMA} het duplikaat opdrae
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}Vliegtuig {COMMA} hen 'n swak opdrag in sy opdrae
+# end of order system
+
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}Outohernuwe gedop op vliegtuig {COMMA} (geldperk)
+
+
+STR_CONFIG_PATCHES_OFF :Af
+STR_CONFIG_PATCHES_ON :Aan
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Wys voertuig spoed in die standbaan: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Toelaat opbou op hellings en strande: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Toelaat meer werklikheide opvanggebied groote: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Toelaat verwydering van meer stad-besite paaie, bruge, ens: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Stel in staat die gebou van baie lang treine: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Stel in staat realistiese versnelling vir treine: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Verbied triene en skepe om 90 graad draaie te maak: {ORANGE}{STRING} {LTBLUE} (benodig NPF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Verbind trein stasies wat langsaan gebou is: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Verlaat stasie as enige vrag vol is, as 'volle gelaai': {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Geruik verebeterde laai algoritme: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Inflasie: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Aflewer vrag na 'n stasie slegs as daar 'n aanvrag is:: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Toelaat opbou van baie lank bruge: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Toelaat gaan na depot opdrae: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Toelaat opbou van rumateriaal oplewering nywerheide: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Toelaat veelvout soortgelyke nywerheide per stad: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Nywerheide van die selfde tipe kan naby aan mekaar gebou word: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Altyd wys lang datum in die standbaan: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Wys seine op die bestuur kant: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Wys finansies venster op die einde van die jaar: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}TTDPatch bestaanbaar deurgaande behandeling: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Pad voertuig toustaan (met kwantum effekte): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Was skerm as muis by die kant is: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Toelaat die omkooping van plaaslike gesag: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Ongelyk stasies: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Klein lughawe is altyd toegelaat: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Bespreek voertuig se opdrae: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :nee
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :ja, maar uitsluit gestopde voertuie
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :van alle voertuie
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Waarsku as trein inkomste negatief is: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Voertuie verval nooit nie: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Outohernuwe voertuig as hy oud raak
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Outohernuwe wanner voertuig is {ORANGE}{STRING}{LTBLUE} maande voor/agter max ouderdom
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Outohernuwe minimum vereisde geld vir hernuwe: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Tydgrens van fout boodskap: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Wys stad populasie in stad naam teken: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Onsigbaar boome (met deurskynend geboue): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Sneeu lyn hoogte: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Max stasie omvang: {ORANGE}{STRING} {RED}Waarskuwing: Ho�stelling vertraag spel
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Versien helikopters by helihawes outomaties: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Verbind landereye werktuigbaan na spoor/pad/water/lughawe werktuigbaan: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Omkeer rol rigting: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Max treine per speler: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Max pad voertuie per speler: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}Max vliegtuie per speler: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}Max skepe per speler: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Vermink treine vir rekenaar: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Vermink pad voertuie vir rekenaar: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Vermink vliegtuie vir rekenaar: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Vermink skepe vir rekenaar: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Stel nuwe AI (alpha) in staat: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Toelaat AIe in veelspeeler (proefondervindelik): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Gebrekte versien tussentyd vir treine: {ORANGE}{STRING} dae/%
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Gebrekte versien tussentyd vir treine: {ORANGE}gestrem
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Gebrekte versien tussentyd vir pad voertuie: {ORANGE}{STRING} dae/%
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Gebrekte versien tussentyd vir pad voertuie: {ORANGE}gestrem
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Gebrekte versien tussentyd vir vlietuie: {ORANGE}{STRING} dae/%
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Gebrekte versien tussentyd vir vlietuie: {ORANGE}gestrem
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Gebrekte versien tussentyd vir skepe: {ORANGE}{STRING} dae/%
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Gebrekte versien tussentyd vir skepe: {ORANGE}gestrem
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Gestrem versiening wanneer oponthoude is na geen gestel: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Stel wa spoed limite in staak: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Gekleur nuus verskyn in: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Begins datum: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}Eindig spel in: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Stel vloeiende ekonomie in staak (meer, kleiner veranderings)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Toelaat deele aankoop van ander maatskappye
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Wanneer sleeping, plaas seine elke: {ORANGE}{STRING} teel(e)
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Posisie van hoof werktuigbaan: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Links
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Senter
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Regs
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Venster slag straal: {ORANGE}{STRING} px
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Venster slag straal: {ORANGE}gestrem
+
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Konstruksie
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Voertuie
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Stasies
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Ekonomie
+STR_CONFIG_PATCHES_AI :{BLACK}Mededingers
+
+STR_CONFIG_PATCHES_DISABLED :gestrem
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Verander stelling waarde
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Party of almal van die gebrekte versien tussentyd(e) onder is onbestaanbaar met die verkiesde stelling! 5-90% en 30-800 dae is geldig
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}Gebruik YAPF vir skepe: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}Gebruik YAPF vir pad voertuie: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}Gebruik YAPF vir treine: {ORANGE}{STRING}
+
+
+STR_CHEATS :{WHITE}Bedriege
+STR_CHEATS_TIP :{BLACK}tikblokkies aanwys as jy die bedreig vroe� gebruik het
+STR_CHEATS_WARNING :{BLACK}Waarskuwing! Jy gaan omtrent jou genoote mededingers verrai. Hou in gemoed dat so 'n skande sal vir ewig onhout word.
+STR_CHEAT_MONEY :{LTBLUE}Vermeerder geld by {CURRENCY64}
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Speel as speler: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Tower stootskraper (uitwis nywerheide, onbeweegbares): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Tonnels mag vir mekaar kruis: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Bou terwyl in pouseer metode: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Straalvliegtuie sal nie (dikwels) op klein lughawe bots nie: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Skakel klimaat: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Verander datum: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}Stel modifikasie van produksie waarde in staak: {ORANGE}{STRING}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}Op pad na {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Op pad na {WAYPOINT}, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :Gaan oor {WAYPOINT}
+STR_GO_NON_STOP_TO_WAYPOINT :Gaan deurgaande oor {WAYPOINT}
+
+STR_LANDINFO_WAYPOINT :Wegpunt
+
+
+STR_EDIT_WAYPOINT_NAME :{WHITE}Redigeer wegpunt naam
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Kan nie wegpunt naam verander nie...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Verdoel spoor na wegpunt
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Kanie nie trein wegpunt hier bou nie...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Kan nie trein wegpunt van hier werwyder nie...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Bou spoorweg spoor met die Outospoor metode
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}...daar is geen stad in die draaiboek
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}Is jy seker jy wil 'n lukraake landeryke skep?
+STR_MANY_RANDOM_TOWNS :{BLACK}Baie lukraak stede
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Baie luraak nyweheide
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Kan nie nywerheide ontwikkel nie...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Oppe die landargitekteur werktuigbaan om land te verhoog/verlaag, boome beplant, ens.
+STR_LANDSCAPING_TOOLBAR :{WHITE}Landargitekteur
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Vlakte land
+
+
+
+STR_CANT_BUILD_CANALS :{WHITE}Kan nie kanaale hier bou nie...
+STR_BUILD_CANALS_TIP :{BLACK}Bou kanaale
+STR_LANDINFO_CANAL :Kanaal
+
+STR_CANT_BUILD_LOCKS :{WHITE}Kan nie sluite hier bou nie...
+STR_BUILD_LOCKS_TIP :{BLACK}Bou sluite
+STR_LANDINFO_LOCK :Sluit
+
+STR_BUOY_IS_IN_USE :{WHITE}...baken is in gebruik!
+
+STR_LANDINFO_COORDS :{BLACK}Neweskikke: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Kan nie deel van stasie verwyder nie...
+STR_CANT_CONVERT_RAIL :{WHITE}Kan nie spoor tipe hier verdoel nie...
+STR_CONVERT_RAIL_TIP :{BLACK}Verdoel/Opgradeer die spoor tipe
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Sleep trein enjin hier om hele trein te verkoop
+
+STR_DRAG_DROP :{BLACK}Sleep & Drop
+
+STR_FAST_FORWARD :{BLACK}Vinnig vooruit die spel
+STR_MESSAGE_HISTORY :{WHITE}Boodskap Geskidenis
+STR_MESSAGE_HISTORY_TIP :{BLACK}'n Lys van al die onlangs nuus boodskappe
+STR_MESSAGES_DISABLE_ALL :{BLACK}Gestrem alle
+STR_MESSAGES_ENABLE_ALL :{BLACK}Stel alle in staak
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Bou Steenkool Myn
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Wout Beplant
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Bou Olieboor
+STR_CONSTRUCT_FARM_TIP :{BLACK}Befonds Plaas
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Bou Koper Erts Myn
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Boor vir Olie
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Bou Goud Myn
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Bou Diamant Myn
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Bou Yster Erts Myn
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Befonds Vrugte Plantasie
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Befonds Gomlastiek Plantasie
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Befonds Water Lewering
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Beplant Spookasem Woud
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}Befonds Battery Plaas
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Boor vir Cola
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Befonds Plastiek Fonteine
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Bou Borrel Ontwikkelaar
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Befonds Tameletjie Prooi
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Bou Suiker Myn
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Nywerheide
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA}% uitgevoer)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA}%/{COMMA}% uitgevoer)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}...te naby aan 'n ander nywerheid
+
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Versien tussentye is in persente: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Verander produksie
+
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Veelspeler
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Speler naam:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}Die is die naam waarmee ander spelers sal jou aanwys
+STR_NETWORK_CONNECTION :{BLACK}Verbinding:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Kies tueen internet spel of 'n Plaaslike Area Netwerk (LAN) spel
+
+STR_NETWORK_START_SERVER :{BLACK}Begin bediender
+STR_NETWORK_START_SERVER_TIP :{BLACK}Begin u eie bediender
+
+STR_NETWORK_GAME_NAME :{BLACK}Naam
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Naam van die spel
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Taal, bediender verwerking, ens.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}kliek 'n naam op die lys om dit te kies
+
+STR_NETWORK_FIND_SERVER :{BLACK}Versoek bediender
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Versoek netwerk vir 'n bediender
+STR_NETWORK_ADD_SERVER :{BLACK}Byvoeg Bediender
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Byvoeg 'n bediender na die lys wat sal altyd nagaan vir lopende spele
+STR_NETWORK_ENTER_IP :{BLACK}Invoeg die adres van die gasheer
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Kliente
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Kliente oplyn / Kliente max{}Maatskappye oplyn / Maatskappye max
+STR_NETWORK_GAME_INFO :{SILVER}SPEL INLIGTING
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Kliente: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Taal: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Blokkiestel: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Kaart groote: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}Bediender hersiening: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}Bediender adres: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Begin datum: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Huidige datum: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Wagwoord beskerm!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}BEDIENDER AFLYN
+STR_NETWORK_SERVER_FULL :{SILVER}BEDIENDER VOL
+STR_NETWORK_VERSION_MISMATCH :{SILVER}HERSIENING ONGELYK
+
+STR_NETWORK_JOIN_GAME :{BLACK}Verbind spel
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}Begin nuwe veelspeler spel
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Spel naam:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}Die spel naam sal vertoon word na ander spelers in die veelspeler keuse
+STR_NETWORK_SET_PASSWORD :{BLACK}Stel wagwoord
+STR_NETWORK_PASSWORD_TIP :{BLACK}Beskerm jou spel met 'n wagwoord as jy wil dit nie publieke toepassing laat wees nie
+STR_NETWORK_SELECT_MAP :{BLACK}Kies 'n kaart
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}Watter kaart wil jy speel?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}Max kliente:
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Kies die maksimum nommer van kielnte. Alle gleufe hoef nie om vol te wees nie
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :LAN
+STR_NETWORK_INTERNET :Internet
+STR_NETWORK_LAN_INTERNET :LAN / Internet
+STR_NETWORK_INTERNET_ADVERTISE :Internet (adverteer)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 spelers
+STR_NETWORK_1_PLAYERS :1 speler
+STR_NETWORK_2_PLAYERS :2 spelers
+STR_NETWORK_3_PLAYERS :3 spelers
+STR_NETWORK_4_PLAYERS :4 spelers
+STR_NETWORK_5_PLAYERS :5 spelers
+STR_NETWORK_6_PLAYERS :6 spelers
+STR_NETWORK_7_PLAYERS :7 spelers
+STR_NETWORK_8_PLAYERS :8 spelers
+STR_NETWORK_9_PLAYERS :9 spelers
+STR_NETWORK_10_PLAYERS :10 spelers
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}Max maatskappye:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Beperk die bedinder na 'n sekere bedrag van maatskappye
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}Max aanskouers:
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Beperk die bediender na 'n sekere bedrag van aanskouers
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Taal gepraat:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Ander spelers sal weet watter taal op die bediender gepraat is
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}Begin Spel
+STR_NETWORK_START_GAME_TIP :{BLACK}Begin 'n nuwe netwerk spel van 'n lukraak kaart, of draaiboek
+STR_NETWORK_LOAD_GAME :{BLACK}Laai Spel
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Vervolg 'n vroe� bewaarde veelspeler spel (wees seker om te verbind as die korrekte speler)
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Enige
+STR_NETWORK_LANG_ENGLISH :Engels
+STR_NETWORK_LANG_GERMAN :Duits
+STR_NETWORK_LANG_FRENCH :Frans
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Veelspeler spel tuiste
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Voorberei om te verbind: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}'n Lys van alle maatskappye huiding in die spel. Of kan jy een verbind of as daar 'n vry maatskappy gleuf is 'n nuwe ene begin
+STR_NETWORK_NEW_COMPANY :{BLACK}Nuwe Maatskappy
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Skep 'n nuwe maatskappy
+STR_NETWORK_SPECTATE_GAME :{BLACK}Aanskou spel
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Bekyk die spel as 'n aanskouer
+STR_NETWORK_JOIN_COMPANY :{BLACK}Verbind maatskappy
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Hulp om die maatskappy te bestuur
+STR_NETWORK_REFRESH :{BLACK}Vervris bediender
+STR_NETWORK_REFRESH_TIP :{BLACK}Vervris die bediender inligting
+
+STR_NETWORK_COMPANY_INFO :{SILVER}MAATSKAPPY INLIGTING
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Maatskappy naam: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}Inwyding: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}Maatskappy waarde: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Hudige balans: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Verlede jaar se inkome: {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}Prestasie: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}Voertuie: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Stasies: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Spelers: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}Aansluit...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) Aansluit..
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Gemagtiging...
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Opwagting...
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Kaart aflaai..
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Verwerk Data...
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) Registreer...
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Haal spel inligting...
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Haal maatskappy inligting...
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} Klient{P "" e} voor jou
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} kbytes afgelaai dusver
+
+STR_NETWORK_DISCONNECT :{BLACK}Loskoppel
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Invoeg die bedrag van geld jy wil gee
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Bediender is beskerm. Invoeg wagwoord
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Maatskappy is beskerm. Invoeg wagwoord
+STR_NETWORK_CLIENT_LIST :{WHITE}Klient Lys
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE} Geen netwerk ontwerp gevind of voldoen sonder ENABLE_NETWORK
+STR_NETWORK_ERR_NOSERVER :{WHITE} Kan nie enige netwerk spele vind nie
+STR_NETWORK_ERR_NOCONNECTION :{WHITE} Die bedinder het nie die versoek geantwoord nie
+STR_NETWORK_ERR_DESYNC :{WHITE} Netwerk-Spel sinchroniseering gedop
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} Netwerk-Spel verbinding verloor
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} Kan nie bewaarespel laai nie
+STR_NETWORK_ERR_SERVER_START :{WHITE} Bediender kan nie aangesit word nie
+STR_NETWORK_ERR_CLIENT_START :{WHITE} Kan nie verbinding kry nie
+STR_NETWORK_ERR_TIMEOUT :{WHITE} Verbinding #{NUM} het betyds uitgeloop
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE} A protokol-fout was gemaak en die verbinding was verlore
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE} Die hersiening van die klient is nie gelyk aan die bediender se hersiening nie
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} Verkeerde wagwoord
+STR_NETWORK_ERR_SERVER_FULL :{WHITE} Die bediender is vol
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} Jy is van die bediender verban
+STR_NETWORK_ERR_KICKED :{WHITE} Jy is van die spel geskop
+STR_NETWORK_ERR_CHEATER :{WHITE} Bedreiging is nie op die bediender toegelaat
+
+STR_NETWORK_ERR_LEFT :het die spel verlaat
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :algemeen fout
+STR_NETWORK_ERR_CLIENT_DESYNC :desync fout
+STR_NETWORK_ERR_CLIENT_SAVEGAME :kan nie kaart laai nie
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :verbinding verloor
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :protokol fout
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :nie gemagtig nie
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :vreemde pakket aanvaar
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :verkeerde hersiening
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :naam reeds in gebruik
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :verkeerde wagwoord
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :verkeerde speler-id in DoCommand
+STR_NETWORK_ERR_CLIENT_KICKED :geskop by bediender
+STR_NETWORK_ERR_CLIENT_CHEATER :was op die proef stel om 'n bereig te gebruik
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :bediender vol
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :het die spel verbind
+STR_NETWORK_GIVE_MONEY :het vir u maatskappy geld gegee ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :u het vir {STRING} geld ({CURRENCY}) gegee
+STR_NETWORK_CHAT_COMPANY :[Span] {STRING}:
+STR_NETWORK_CHAT_TO_COMPANY :[Span] Na {STRING}:
+STR_NETWORK_CHAT_CLIENT :[Privaat] {STRING}:
+STR_NETWORK_CHAT_TO_CLIENT :[Privaat] Na {STRING}:
+STR_NETWORK_CHAT_ALL :[All] {STRING}:
+STR_NETWORK_NAME_CHANGE :het hy/sy naam verander na
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE} Die bediender het die sessie toegemaak
+STR_NETWORK_SERVER_REBOOT :{WHITE} Die bediender is besig om te weerbegin...{}Wag asb...
+
+STR_NETWORK_SERVER :Bediender
+STR_NETWORK_CLIENT :Klient
+
+STR_NETWORK_CLIENTLIST_NONE :(geen)
+STR_NETWORK_CLIENTLIST_KICK :Skop
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Gee geld
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Praat met almal
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Praat met maatskappy
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Privaate boodskap
+
+
+STR_NETWORK_SEND :{BLACK}Stuur
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}X-groote van kaart: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Y-groote van kaart: {ORANGE}{STRING}
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Prys: {CURRENCY}
+STR_0801_COST :{RED}Koste: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Inkome: {CURRENCY}
+STR_0803_INCOME :{GREEN}Inkome: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Oorplaas: {CURRENCY}
+STR_FEEDER :{YELLOW}Oorplaas: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Geraamde Koste: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Geraamde Inkome: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Kan nie land verhoog hier nie...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Kan nie land verlaag hier nie...
+STR_080A_ROCKS :Rotse
+STR_080B_ROUGH_LAND :Ru land
+STR_080C_BARE_LAND :Kaal land
+STR_080D_GRASS :Gras
+STR_080E_FIELDS :Velde
+STR_080F_SNOW_COVERED_LAND :Sneeu-bedekte land
+STR_0810_DESERT :Woestyn
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Land skuins in verkeerde rigting
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Onmoontlike spoor kombinasie
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}Uitgrawing sal tonnel beskadig
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Reeds op seevlak
+STR_1004_TOO_HIGH :{WHITE}Te hoog
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Geen paslik spoorweg spoor
+STR_1007_ALREADY_BUILT :{WHITE}...reeds gebou
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Moet eers spoorweg spoor verwyder
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Spoorweg Kostruksie
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Eenspoor Konstruksie
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}MagLev Konstruksie
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Kies Spoor Brug
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Kan nie trein depot hier bou nie...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Kan nie spoorweg stasie hier bou nie...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Kan nie seine hier bou nie...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Kan nie spoorweg spoor hier bou nie...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Kan nie spoorweg spoor van hier verwyder nie...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Kan nie seine van hier verwyder nie...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Trein Depot Ori�tering
+STR_1015_RAILROAD_CONSTRUCTION :Spoorweg konstruksie
+STR_1016_MONORAIL_CONSTRUCTION :Eenspoor konstruksie
+STR_1017_MAGLEV_CONSTRUCTION :MagLev konstruksie
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Bou spoorweg spoor
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Bou trein depot (vir gebou en diens van treine)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Bou spoorweg stasie
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Bou spoorweg seine
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Bou spoorweg brug
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Bou spoorweg tonnel
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Skakel bou/verwyder vir spoorweg spoor en seine
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Brug keuse - kliek op jou verkiesde brug om dit te bou
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Kies spoorweg depot ori�tering
+STR_1021_RAILROAD_TRACK :Spoorweg spoor
+STR_1023_RAILROAD_TRAIN_DEPOT :Spoorweg trein depot
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...area is besit by 'n ander maatskappy
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Moet pad eers verwyder
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Pad Konstruksie
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Kies Pad Brug
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Kan nie pad hier bou nie...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Kan nie pad van hier verwyder nie...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Pad Depot Ori�tering
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Kan nie pad voertuig depot hier bou nie...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Kan nie bus stasie hier bou nie...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Kan nie vraagmotor stasie bou nie...
+STR_180A_ROAD_CONSTRUCTION :Pad konstruksie
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Bou pad afdeling
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Bou pad voertuig depot (vir bou en diens van voertuie)
+STR_180D_BUILD_BUS_STATION :{BLACK}Bou bus stasie
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Bou vraagmotor laai area
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Bou pad brug
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Bou pad tonnel
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Skakel bou/verwyder vir pad bou
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Kies pad voertuig depot ori�tering
+STR_1814_ROAD :Pad
+STR_1815_ROAD_WITH_STREETLIGHTS :Pad met straatligte
+STR_1816_TREE_LINED_ROAD :Boom-belynde pad
+STR_1817_ROAD_VEHICLE_DEPOT :Pad voertuig depot
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :Pad/spoor oorgang
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Stede
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Gebou moet eers afgebreek word
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}Populasie: {ORANGE}{COMMA}{BLACK} Huise: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Hernaam Stad
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Kan nie stad hernaam nie...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} plaaslike raad weier om dit te toelaat
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Stad naame - kliek op naam om skerm op stad te senter
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Senter skerm op stad
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Verander stad naam
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passasiers verlede maand: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Pos verlede maand: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Lank kantoor blok
+STR_2010_OFFICE_BLOCK :Kantoor blok
+STR_2011_SMALL_BLOCK_OF_FLATS :Klein blok van woonstelle
+STR_2012_CHURCH :Kerk
+STR_2013_LARGE_OFFICE_BLOCK :Groot kantoor blok
+STR_2014_TOWN_HOUSES :Meenthuise
+STR_2015_HOTEL :Hotel
+STR_2016_STATUE :Standbeeld
+STR_2017_FOUNTAIN :Fontein
+STR_2018_PARK :Park
+STR_2019_OFFICE_BLOCK :Kantoor blok
+STR_201A_SHOPS_AND_OFFICES :Winkels en kantoore
+STR_201B_MODERN_OFFICE_BUILDING :Moderne kantoor gebou
+STR_201C_WAREHOUSE :Pakhuis
+STR_201D_OFFICE_BLOCK :Kantoor blok
+STR_201E_STADIUM :Stadion
+STR_201F_OLD_HOUSES :Ou huise
+STR_2020_LOCAL_AUTHORITY :{BLACK}Plaaslike raad
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Wys inlingting oor plaaslike raad
+STR_2022_LOCAL_AUTHORITY :{WHITE}{TOWN} plaaslike raad
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Vervoer maatskappy graderings:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Subsidiee
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Subsidiee op aanbod vir diens opneming:
+STR_2027_FROM_TO :{ORANGE}{STRING} van {STRING} tot {STRING}
+STR_2028_BY :{YELLOW} (voor {DATE_SHORT})
+STR_202A_NONE :{ORANGE}Geen
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Dienste reeds gesubsidieer:
+STR_202C_FROM_TO :{ORANGE}{STRING} van {STATION} tot {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, tot {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}Aanbod van subsidie verval:{}{}{STRING} van {STRING} tot {STRING} sal nou nie 'n subsidie aantrek nie.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Subsidie terugtrek:{}{}{STRING} diens van {STATION} tot {STATION} is nie meer gesubsideieer nie.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Diens subsidie aanbod:{}{}Eerste {STRING} diens van {STRING} tot {STRING} sal 'n jaar se subsidie van die plaaslike raad kry!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Diens subsidie toeken aan {COMPANY}!{}{}{STRING} Diens van {STATION} tot {STATION} sal nou 50% extra vir die volgende jaar betaal!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Diens subsidie toeken aan {COMPANY}!{}{}{STRING} diens van {STATION} tot {STATION} sal nou dubbel pryse vir die volgende jaar betaal!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Diens subsidie toeken aan {COMPANY}!{}{}{STRING} diens van {STATION} tot {STATION} sal nou driemaal pryse vir die volgende jaar betaal!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Diens subsidie toeken aan {COMPANY}!{}{}{STRING} diens van {STATION} tot {STATION} sal nou viervoud pryse vir die volgende jaar betaal!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} plaaslike raad weier om nog 'n lughawe in die stad gebou te laat word
+STR_2036_COTTAGES :Kothuise
+STR_2037_HOUSES :Huise
+STR_2038_FLATS :Woonstelle
+STR_2039_TALL_OFFICE_BLOCK :Lank kantoor blok
+STR_203A_SHOPS_AND_OFFICES :Winkels en kantoore
+STR_203B_SHOPS_AND_OFFICES :Winkels en kantoore
+STR_203C_THEATER :Teatre
+STR_203D_STADIUM :Stadion
+STR_203E_OFFICES :Kantoore
+STR_203F_HOUSES :Huise
+STR_2040_CINEMA :Kinema
+STR_2041_SHOPPING_MALL :Inkoopies winkelplein
+STR_2042_DO_IT :{BLACK}Doen dit
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}Lys van dinge te doen by die stad - kliek op item vir meer besonderheide
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Voeg die beklemtoonde aksie in die lys bo uit
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Aksies beskikbaar:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Klein adverteer kampeer
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Medium adverteer kampeer
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Groot adverteer kampeer
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Befonds plaaslike pad heropbou
+STR_204A_BUILD_STATUE_OF_COMPANY :Bou standbeeld van maatskappy eienaar
+STR_204B_FUND_NEW_BUILDINGS :Befonds nuwe geboue
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Koop eksklusief vervoer regte
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Inlei 'n klein plaaslike adverteer kampeer, om meer passasiers en vrag na jou vervoer dienste te aantrek.{} Prys: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Inlei 'n medium plaaslike adverteer kampeer, om meer passasiers en vrag na jou vervoer dienste te aantrek.{} Prys: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Inlei 'n groot plaaslike adverteer kampeer, om meer passasiers en vrag na jou vervoer dienste te aantrek.{} Prys: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} Befonds die heropbou van die stedelike pad netwerk. Veroorsaak aanmerklike ontwrigging na pad verkeer vir omtrent 6 maande.{} Prys: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Bou 'n standbeeld in eer van u maatskappy.{} Prys: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Befonds die bou van nuwe kommersieel geboue in die stad.{} Prys: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Koop 1 jaar se ekslusief vervoer regte in stad. Stad raad sal passasiers en vrag slegs toelaat om jou maatskappy se stasies te gebruik.{} Prys: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}Verkeer warboel in {TOWN}!{}{}Pad heropbou program befonds by {COMPANY} bring 6 maande van narigheid na motoriste!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (onder opbou)
+STR_2059_IGLOO :Igloo
+STR_205A_TEPEES :Tepees
+STR_205B_TEAPOT_HOUSE :Teepot-Huis
+STR_205C_PIGGY_BANK :Varkie-Bank
+
+STR_INDUSTRY :{INDUSTRY}
+STR_INDUSTRY_FORMAT :{TOWN} {STRING}
+
+##id 0x2800
+STR_LANDSCAPING :Landargitekteur
+STR_2800_PLANT_TREES :Boome beplant
+STR_2801_PLACE_SIGN :Plaas teken
+STR_2802_TREES :{WHITE}Boome
+STR_2803_TREE_ALREADY_HERE :{WHITE}...boom reeds daar
+STR_2804_SITE_UNSUITABLE :{WHITE}...plek ongeskik
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Kan nie boom hier beplant nie...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...te veel tekens
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Kan nie teken hier plaas nie...
+STR_280A_SIGN :Teken
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Verander teken teks
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Teken naam kan nie verander word nie...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Kies boom tipe om te beplant
+STR_280E_TREES :Boome
+STR_280F_RAINFOREST :Reenwoud
+STR_2810_CACTUS_PLANTS :Kaktus Plante
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Spoor Stasie Keuse
+STR_3001_AIRPORT_SELECTION :{WHITE}Lughawe Keuse
+STR_3002_ORIENTATION :{BLACK}Ori�tering
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Nommer van spoore
+STR_3004_PLATFORM_LENGTH :{BLACK}Verhoog lengte
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Te naby aan 'n ander spoorweg stasie
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Grens aan meer as een bestaande stasie/laai area
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}Te veel stasies/laai areas in die stad
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}Te veel stasies/laai areas
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Te veel bushalte
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}Te veel vraagmotor stasies
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Te naby aan 'n ander stasie/laai area
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Moet eers spoorweg stasie afbreek
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Te naby aan 'n ander lughawe
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Moet eers lughawe afbreek
+
+STR_3030_RENAME_STATION_LOADING :Hernaam stasie/laai area
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Stasie kan nie hernaam word nie...
+STR_3032_RATINGS :{BLACK}Graderings
+STR_3033_ACCEPTS :{BLACK}Aanvaar
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}Plaaslike gradering van vervoer diens
+
+############ range for rating starts
+STR_3035_APPALLING :Onsettend
+STR_3036_VERY_POOR :Baie Arm
+STR_3037_POOR :Arm
+STR_3038_MEDIOCRE :Middelmagtig
+STR_3039_GOOD :Goed
+STR_303A_VERY_GOOD :Baie Goed
+STR_303B_EXCELLENT :Uitsteekent
+STR_303C_OUTSTANDING :Treffend
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} aanvaar nie meer {STRING} nie
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} aanvaar nie meer {STRING} of {STRING} nie
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} aanvaar nou {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} aanvaar nou {STRING} en {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Bus Stasie Ori�tering
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Vraagmotor Stasie Ori�t.
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Moet eers bus stasie afbreek
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Moet eers vraagmotor stasie afbreek
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Stasie{P "" s}
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Geen -
+STR_304B_SITE_UNSUITABLE :{WHITE}...plek ongeskik
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Te naby aan 'n ander werf
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Moet eers werf afbreek
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Kies spoorweg stasie ori�tering
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Kies nommer van verhoogte vir spoorweg stasie
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Kies lengte van spoorweg stasie
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Kies bus stasie ori�tering
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Kies vraagmotor laai area ori�tering
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Senter skerm op stasie
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Wys stasie graderings
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Verander naam van stasie
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Wys lys van aanvaarde vrag
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Stasie naame - Kliek op naam om skerm op stasie te senter
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Kies groote/tipe van lughawe
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_305E_RAILROAD_STATION :Spoorweg stasie
+STR_305F_AIRCRAFT_HANGAR :Vlietuig hangar
+STR_3060_AIRPORT :Lughawe
+STR_3061_TRUCK_LOADING_AREA :Vraagmotor laai area
+STR_3062_BUS_STATION :Bus stasie
+STR_3063_SHIP_DOCK :Skip werf
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Beklemtoon dekkingsarea van die voorgestelde bouterrein
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Moenie die dekkingsarea van die voorgestelde bouterrein beklemtoon nie
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Dekkingsarea beklemtoon
+STR_3068_DOCK :{WHITE}Werf
+STR_3069_BUOY :Baken
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...baken in die pad
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...Stasie te ver van mekaar af
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...ongelyk stasies is gestrem
+
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Skip Depot Ori�tering
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...moet op water gebou word
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Skip depot kan nie hier gebou word nie...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Kies skip depot ori�tering
+STR_3804_WATER :Water
+STR_3805_COAST_OR_RIVERBANK :Strand of oewer
+STR_3806_SHIP_DEPOT :Skip depot
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...Kan nie op water bou nie
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Bewar Spel
+STR_4001_LOAD_GAME :{WHITE}Laai Spel
+STR_4002_SAVE :{BLACK}Bewaar
+STR_4003_DELETE :{BLACK}Uitwis
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} megabyte{P "" s} vry
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Kan nie skyf lees nie
+STR_4007_GAME_SAVE_FAILED :{WHITE}Spel Bewaar Gedop
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Kan nie l�r uitwis nie
+STR_4009_GAME_LOAD_FAILED :{WHITE}Spel Laai Gedop
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}Lys van skywe, voublaaie en spel-bewaar l�rs
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Huidige naam vir bewaarde-spel
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Uitwis die verkieste bewaarde-spel
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Bewaar die huidige spel, met die verkieste naame
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Kies Nuwe Spel Tipe
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Kies draaiboek (groen), voor-gestelde spel (blou), of lukraak nuwe spel
+STR_4010_GENERATE_RANDOM_NEW_GAME :Onwikkel lukraak nuwe spel
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} in die pad
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :Steenkool Myn
+STR_4803_POWER_STATION :Krag Stasie
+STR_4804_SAWMILL :Saagmeul
+STR_4805_FOREST :Woud
+STR_4806_OIL_REFINERY :Olie Raffineerdery
+STR_4807_OIL_RIG :Olieboor
+STR_4808_FACTORY :Fabriek
+STR_4809_PRINTING_WORKS :Drukwerke
+STR_480A_STEEL_MILL :Staalmeul
+STR_480B_FARM :Plaas
+STR_480C_COPPER_ORE_MINE :Koper Erts Myn
+STR_480D_OIL_WELLS :Olie Bron
+STR_480E_BANK :Bank
+STR_480F_FOOD_PROCESSING_PLANT :Kos Verwerkings Fabriek
+STR_4810_PAPER_MILL :Papiermeul
+STR_4811_GOLD_MINE :Goud Myn
+STR_4812_BANK :Bank
+STR_4813_DIAMOND_MINE :Diamant Myn
+STR_4814_IRON_ORE_MINE :Yster Erts Myn
+STR_4815_FRUIT_PLANTATION :Vrugte Plantasie
+STR_4816_RUBBER_PLANTATION :Gomlastiek Plantasie
+STR_4817_WATER_SUPPLY :Water Lewering
+STR_4818_WATER_TOWER :Water Toring
+STR_4819_FACTORY :Fabriek
+STR_481A_FARM :Plaas
+STR_481B_LUMBER_MILL :Timmerhoutmeul
+STR_481C_COTTON_CANDY_FOREST :Spookasem Woud
+STR_481D_CANDY_FACTORY :Lekker Fabriek
+STR_481E_BATTERY_FARM :Battery Plaas
+STR_481F_COLA_WELLS :Cola Bron
+STR_4820_TOY_SHOP :Speelgoed Winkel
+STR_4821_TOY_FACTORY :Speelgoed Fabriek
+STR_4822_PLASTIC_FOUNTAINS :Plastiek Fonteine
+STR_4823_FIZZY_DRINK_FACTORY :Koeldranke Fabriek
+STR_4824_BUBBLE_GENERATOR :Borrel Ontwikkelaar
+STR_4825_TOFFEE_QUARRY :Tamletjie Prooi
+STR_4826_SUGAR_MINE :Suiker Myn
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Vereis: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Vereis: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Vereis: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Produksie verlede maand:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% uitgevoer)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Senter skerm op nywerheid
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Nuwe {STRING} onder opbou naby {TOWN}!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Nuwe {STRING} word naby {TOWN} beplant!
+STR_482F_COST :{BLACK}Koste: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Nywerheid tipe kan nie hier gebou word nie...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...woud kan net bo sneeu-lyn beplant word
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} aankondig dreigend sluiting!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}Lewering probleme veroorsaak {INDUSTRY} om dreigend sluting te aankondig!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}Gemis van naby boome veroorsaak {INDUSTRY} om dreigend sluiting te aankondig!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} vermeerder produksie!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}Nuwe steenkool laag vevind by {INDUSTRY}!{}Produksie is verwag om te verdubbel!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}Nuwe olie reserwes gevind by {INDUSTRY}!{}Produksie is verwag om te verdubbel!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}Verbeterde boerdery metodes by {INDUSTRY} sal produksie verdubbel!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}{INDUSTRY} produksie verminder 50%
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}Insek vervuiling oorsaak verwoesting by {INDUSTRY}!{}Produksie verminder 50%
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...kan net naby aan kant van kaart geplaas word
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}{STRING} produksie by {INDUSTRY} vermeerder {COMMA}%!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}{STRING} produksie by {INDUSTRY} verminder {COMMA}%!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Trein in tonnel
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Pad voetuig in tonnel
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Ander tonnel in die pad
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Onbekwaam om land vir ander einde van tonnel te uitgrawe
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Moet eers tonnel afbreek
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Moet eers brug afbreek
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Kan nie in die selfde plek begin en eindig nie
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Platte land of water nooding onder brug
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}Begin en eindig moet in lyn wees
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Plek ongeskik vir tonnel ingang
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Staking, Staal
+STR_500F_GIRDER_STEEL :Staaf, Staal
+STR_5010_CANTILEVER_STEEL :Vrydraer, Staal
+STR_5011_SUSPENSION_CONCRETE :Staking, Beton
+STR_5012_WOODEN :Houterig
+STR_5013_CONCRETE :Beton
+STR_5014_TUBULAR_STEEL : Buis, Staal
+STR_BRIDGE_TUBULAR_SILICON :Buis, Silicon
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Brug kan nie daar gebou word nie...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Tonnel kan nie daar gebou word nie...
+STR_5017_RAILROAD_TUNNEL :Spoorweg tonnel
+STR_5018_ROAD_TUNNEL :Pad tonnel
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Staal staking spoor brug
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Staal staaf spoor brug
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Staal vrydraer spoor brug
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Gewapende beton staking spoor brug
+STR_501F_WOODEN_RAIL_BRIDGE :Houterig spoor brug
+STR_5020_CONCRETE_RAIL_BRIDGE :Beton spoor brug
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Staal staking pad brug
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Staal staaf pad brug
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Staal vrydraer pad brug
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Gewapende beton staking pad brug
+STR_5025_WOODEN_ROAD_BRIDGE :Houterig pad brug
+STR_5026_CONCRETE_ROAD_BRIDGE :Beton pad brug
+STR_5027_TUBULAR_RAIL_BRIDGE :Buis spoor brug
+STR_5028_TUBULAR_ROAD_BRIDGE :Buis pad brug
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Voorwerp in die pad
+STR_5801_TRANSMITTER :Sender
+STR_5802_LIGHTHOUSE :Vuurtoring
+STR_5803_COMPANY_HEADQUARTERS :Maatskappy Hoofkwartier
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...maatskappy hoofkwartiers in die pad
+STR_5805_COMPANY_OWNED_LAND :Maatskappy-besitte land
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Land area kan nie aangekoop word nie...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...jy besit dit alreeds!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Moeilikheids Vlakte
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Bewaar
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Maklik
+STR_6802_MEDIUM :{BLACK}Gemiddel
+STR_6803_HARD :{BLACK}Streng
+STR_6804_CUSTOM :{BLACK}Gewoonte
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maksimum no. mededingers: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Mededinger begin tyd: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}No. van stede: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}No. van nywerheide: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Maksimum inisieele lening: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Inisieele rente koers: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Voertuig loopkoste: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Konstruksie spoed van mededinge: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Intelligensie van mededinge: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Voertuig oponthoude: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Subsidie vermenigvuld: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}koste van konstruksie: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Landerye tipe: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Hoeveelheid see/panne: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Ekonomie: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Trein omkeer: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Rampe: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Stad raad se houding na area herstruktuuring: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :Geen
+STR_6816_LOW :Laag
+STR_6817_NORMAL :Normaal
+STR_6818_HIGH :Hoog
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Baie Stadig
+STR_681C_SLOW :Stadig
+STR_681D_MEDIUM :Gemiddel
+STR_681E_FAST :Vinnig
+STR_681F_VERY_FAST :Baie Vinnig
+STR_6820_LOW :Laag
+STR_6821_MEDIUM :Gemiddel
+STR_6822_HIGH :Hoog
+STR_6823_NONE :Geen
+STR_6824_REDUCED :Verminder
+STR_6825_NORMAL :Normaal
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Baie Plat
+STR_682B_FLAT :Plat
+STR_682C_HILLY :Koppierig
+STR_682D_MOUNTAINOUS :Bergagtig
+STR_682E_STEADY :Gereeld
+STR_682F_FLUCTUATING :Skommelende
+STR_6830_IMMEDIATE :Onmiddelik
+STR_6831_3_MONTHS_AFTER_PLAYER :3 maande na speler
+STR_6832_6_MONTHS_AFTER_PLAYER :6 maande na speler
+STR_6833_9_MONTHS_AFTER_PLAYER :9 maande na speler
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :Op die einde van die lyn, en by stasies
+STR_6835_AT_END_OF_LINE_ONLY :Slegs op die ende van die lyn
+STR_6836_OFF :Af
+STR_6837_ON :Aan
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Wys ho�telling tabel
+STR_6839_PERMISSIVE :Permissief
+STR_683A_TOLERANT :Toelaatbaar
+STR_683B_HOSTILE :Vyandelik
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Speler {COMMA})
+STR_7004_NEW_FACE :{BLACK}Nuwe Gesig
+STR_7005_COLOR_SCHEME :{BLACK}Kleur Skema
+STR_7006_COLOR_SCHEME :{GOLD}Kleur Skema
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Nuwe Kleur Skema
+STR_7008_COMPANY_NAME :{BLACK}Maatskappy Naam
+STR_7009_PRESIDENT_NAME :{BLACK}Bestuurder Naam
+STR_700A_COMPANY_NAME :Maatskappy Naam
+STR_700B_PRESIDENT_S_NAME :Bestuurder se Naam
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Maatskappy naam kan nie verander word nie...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Bestuurder se naam kan nie verander word nie...
+STR_700E_FINANCES :{WHITE}{COMPANY} Finansies {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Onkoste/Inkome
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Kostruksie
+STR_7012_NEW_VEHICLES :{GOLD}Nuwe Voetuie
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Trein Loopkoste
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Pad Voetuig Loopkoste
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Vliegtuig Loopkoste
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Skip loopkoste
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Eiendom Onderhoud
+STR_7018_TRAIN_INCOME :{GOLD}Trein Inkome
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Pad Voertuig Inkome
+STR_701A_AIRCRAFT_INCOME :{GOLD}Vliegtuig Inkome
+STR_701B_SHIP_INCOME :{GOLD}Skip Inkome
+STR_701C_LOAN_INTEREST :{GOLD}Lening Rente
+STR_701D_OTHER :{GOLD}Ander
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Totaal:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Inkome Grafiek
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Bewerking Profyt Grafiek
+STR_7026_BANK_BALANCE :{WHITE}Bank Balans
+STR_7027_LOAN :{WHITE}Lening
+STR_MAX_LOAN :{WHITE}Max Lening: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}Leen {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Terugbetaal {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...maksimum vergun lening groote is {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Kan nie meer geld leen nie...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...geen lening om terugbetaal te word
+STR_702E_REQUIRED :{WHITE}...{CURRENCY} vereis
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Kan nie lening terugbetaal nie...
+STR_INSUFFICIENT_FUNDS :{WHITE}Kan nie geld wat van die bank geleen is weggee nie...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Kies nuwe gesig vir bestuurder
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Verander die maatskappy voertuig lewery
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}verander bestuurder se naam
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Verander die maatskappy se naam
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Kliek op verkieste kleur skema
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Vermeer groote van lening
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Terugbetaal deel van lening
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(Bestuurder)
+STR_7038_INAUGURATED :{GOLD}Bevestig: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Voertuie
+STR_AIRCRAFT :{WHITE}{COMMA} vliegtuig
+STR_7042_NONE :{WHITE}Geen
+STR_7043_FACE_SELECTION :{WHITE}Gesig Keuse
+STR_7044_MALE :{BLACK}Manlik
+STR_7045_FEMALE :{BLACK}Vroulik
+STR_7046_NEW_FACE :{BLACK}Nuwe Gesig
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Kanselleer nuwe gesig keuse
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Aanvar nuwe gesig keuse
+STR_7049_SELECT_MALE_FACES :{BLACK}Kies manlik gesige
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Kies vroulik gesige
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Ontwikkel lukrake Nuwe Gesig
+STR_704C_KEY :{BLACK}Sleutel
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Wys sleutel na grafieke
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Sleutel na maatskappy grafieke
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Kliek hier om maatskappy se intrede op grafiek aan/af te skakel
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Eenheide van vrag afgelewer
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Maatskappy prestasie graderings (maksimum gradering=1000)
+STR_7052_COMPANY_VALUES :{WHITE}Maatskappy waarde
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Maatskappy Liga Tabel
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}Vervoer maatsappy in moelikheid!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} sal binnekort afverkoop of bankrospeler verklaar word tensy prestasie verbeter!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(Bestuurder)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Vervoer maatskappy samesmelting!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} is na {COMPANY} vir {CURRENCY}! verkoop
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Ons is opsoek na 'n vervoer maatskappy wat ons se maatskappy sal oorvat.{}{}Wil jy {COMPANY} koop vir {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Bankrotspeler!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} is deur skuldeisers toegemaak en alle bates is afverkoop!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}Nuwe vervoer maatskappy geloods!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} begin konstruksie naby {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Maatskappy kan nie aangekoop word nie...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Vrag Betaalings Grade
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Dae in deurtog
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Betaaling vir aflewering van 10 eenhuide (of 10,000 liters) van vrag 'n afstand van 20 blokkies
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Skakel grafiek vir vrag tipe aan/af
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Ingenieur
+STR_7067_TRAFFIC_MANAGER :Verkeer Bestuurder
+STR_7068_TRANSPORT_COORDINATOR :Vervoer Ko�eerder
+STR_7069_ROUTE_SUPERVISOR :Roete Opsiener
+STR_706A_DIRECTOR :Direkteur
+STR_706B_CHIEF_EXECUTIVE :Hoofbestuursleier
+STR_706C_CHAIRMAN :Voorsitter
+STR_706D_PRESIDENT :President
+STR_706F_BUILD_HQ :{BLACK}Bou HK
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Bou maatskappy hoofkwartiers / wys maatskappy hoofkwartiers
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Maatskappy hoofkwartiers kan nie hier gebou word nie...
+STR_7072_VIEW_HQ :{BLACK}Wys HK
+STR_COMPANY_PASSWORD :{BLACK}Wagwoord
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Wagwoord-beskerm jou maatskappy om onmagtig gebruikers te belet van verbinding
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}W�eld Insinking!{}{}Finansieel eksperte vrees ergste as ekconomie inmekaar sak!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Insinking Oor!{}{}Oplewing in sake gee vertroue na nywerheide as ekonomie Versterk!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Skakel groot/klein venster groote
+STR_7076_COMPANY_VALUE :{GOLD}Maatskappy waarde: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Koop 25% aandeel in maatskappy
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Verkoop 25% aandeel in maatskappy
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Koop 25% aandeel in die maatskappy
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Verkoop 25% aandeel in die maatskappy
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Kan nie 25% aandeel in die maatskappy koop nie...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}Kan nie 25% aandeel in die maatskappy verkoop nie...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% besit by {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% besit by {COMPANY}{} {COMMA}% besit by {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} is deur {COMPANY}! oorgevat!
+STR_7080_PROTECTED :{WHITE}Die maatskappy is nie oud genoeg om aandeele te handel nie...
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (Stoom)
+STR_8001_MJS_250_DIESEL :MJS 250 (Diesel)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut Diesel
+STR_8006_POWERNAUT_DIESEL :Powernaut Diesel
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (Stoom)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (Stoom)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (Stoom)
+STR_800A_SH_8P_STEAM :SH '8P' (Stoom)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (Diesel)
+STR_800C_DASH_DIESEL :'Dash' (Diesel)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (Diesel)
+STR_800E_UU_37_DIESEL :UU '37' (Diesel)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (Diesel)
+STR_8010_CS_4000_DIESEL :CS 4000 (Diesel)
+STR_8011_CS_2400_DIESEL :CS 2400 (Diesel)
+STR_8012_CENTENNIAL_DIESEL :Centennial (Diesel)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (Diesel)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (Diesel)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (Diesel)
+STR_8016_SH_125_DIESEL :SH '125' (Diesel)
+STR_8017_SH_30_ELECTRIC :SH '30' (Elektries)
+STR_8018_SH_40_ELECTRIC :SH '40' (Elektries)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (Elektries)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (Elektries)
+STR_801B_PASSENGER_CAR :Passasier Rytuig
+STR_801C_MAIL_VAN :Pos Wa
+STR_801D_COAL_CAR :Steenkool Wa
+STR_801E_OIL_TANKER :Olie Tenkwa
+STR_801F_LIVESTOCK_VAN :Lewende Hawe Wa
+STR_8020_GOODS_VAN :Goedere Wa
+STR_8021_GRAIN_HOPPER :Graan Laai Bak
+STR_8022_WOOD_TRUCK :Hout Trok
+STR_8023_IRON_ORE_HOPPER :Yster Erts Laai Bak
+STR_8024_STEEL_TRUCK :Staal Trok
+STR_8025_ARMORED_VAN :Gepantserde Wa
+STR_8026_FOOD_VAN :Kos Wa
+STR_8027_PAPER_TRUCK :Papier Trok
+STR_8028_COPPER_ORE_HOPPER :Koper Erts Laai Bak
+STR_8029_WATER_TANKER :Water Tenkwa
+STR_802A_FRUIT_TRUCK :Vrugte Trok
+STR_802B_RUBBER_TRUCK :Gomlastiek Trok
+STR_802C_SUGAR_TRUCK :Suiker Trok
+STR_802D_COTTON_CANDY_HOPPER :Spookasem Laai Bak
+STR_802E_TOFFEE_HOPPER :Tameletjie Laai Bak
+STR_802F_BUBBLE_VAN :Borrel Wa
+STR_8030_COLA_TANKER :Cola Tenkwa
+STR_8031_CANDY_VAN :Lekker Wa
+STR_8032_TOY_VAN :Speelgoed Wa
+STR_8033_BATTERY_TRUCK :Battery Trok
+STR_8034_FIZZY_DRINK_TRUCK :Koeldrank Trok
+STR_8035_PLASTIC_TRUCK :Plastiek Trok
+STR_8036_X2001_ELECTRIC :'X2001' (Elektries)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Elektries)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :Passasier Rytuig
+STR_803A_MAIL_VAN :Pos Wa
+STR_803B_COAL_CAR :Steenkool Trok
+STR_803C_OIL_TANKER :Olie Tenkwa
+STR_803D_LIVESTOCK_VAN :Lewende Hawe Wa
+STR_803E_GOODS_VAN :Goedere Wa
+STR_803F_GRAIN_HOPPER :Graan Laai Bak
+STR_8040_WOOD_TRUCK :Hout Trok
+STR_8041_IRON_ORE_HOPPER :Yster Erts Laai Bak
+STR_8042_STEEL_TRUCK :Staal Trok
+STR_8043_ARMORED_VAN :Gepantserde Wa
+STR_8044_FOOD_VAN :Kos Wa
+STR_8045_PAPER_TRUCK :Papier Trok
+STR_8046_COPPER_ORE_HOPPER :Coper Erts Laai Bak
+STR_8047_WATER_TANKER :Water Tenkwa
+STR_8048_FRUIT_TRUCK :Vrugte Trok
+STR_8049_RUBBER_TRUCK :Gomlastiek Wa
+STR_804A_SUGAR_TRUCK :Suiker Trok
+STR_804B_COTTON_CANDY_HOPPER :Spookasem Laai Bak
+STR_804C_TOFFEE_HOPPER :Tameletjie Laai Bak
+STR_804D_BUBBLE_VAN :Borrel Wa
+STR_804E_COLA_TANKER :Cola Tenkwa
+STR_804F_CANDY_VAN :Lekker Wa
+STR_8050_TOY_VAN :Speelgoed Wa
+STR_8051_BATTERY_TRUCK :Bettery Trok
+STR_8052_FIZZY_DRINK_TRUCK :Koeldrank Trok
+STR_8053_PLASTIC_TRUCK :Plastiek Trok
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (Elektries)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (Elektries)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (Elektries)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (Elektries)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :Passasier Rytuig
+STR_805A_MAIL_VAN :Pos Wa
+STR_805B_COAL_CAR :Steenkool Trok
+STR_805C_OIL_TANKER :Olie Tenkwa
+STR_805D_LIVESTOCK_VAN :Lewende Hawe Wa
+STR_805E_GOODS_VAN :Goedere Wa
+STR_805F_GRAIN_HOPPER :Graan Laai Bak
+STR_8060_WOOD_TRUCK :Hout Trok
+STR_8061_IRON_ORE_HOPPER :Yster Erts Laai Bak
+STR_8062_STEEL_TRUCK :Staal Trok
+STR_8063_ARMORED_VAN :Gepantserde Wa
+STR_8064_FOOD_VAN :Kos Wa
+STR_8065_PAPER_TRUCK :Papier Trok
+STR_8066_COPPER_ORE_HOPPER :Koper Erts Laai Bak
+STR_8067_WATER_TANKER :Water Tenkwa
+STR_8068_FRUIT_TRUCK :Vrugte Trok
+STR_8069_RUBBER_TRUCK :Gomlastiek Trok
+STR_806A_SUGAR_TRUCK :Suiker Trok
+STR_806B_COTTON_CANDY_HOPPER :Spookasem Laai Bak
+STR_806C_TOFFEE_HOPPER :Tameletjie Laai Bak
+STR_806D_BUBBLE_VAN :Borrel Wa
+STR_806E_COLA_TANKER :Cola Tenkwa
+STR_806F_CANDY_VAN :Lekker Wa
+STR_8070_TOY_VAN :Speelgoed Wa
+STR_8071_BATTERY_TRUCK :Battery Trok
+STR_8072_FIZZY_DRINK_TRUCK :Koeldrank Wa
+STR_8073_PLASTIC_TRUCK :Plastiek Trok
+STR_8074_MPS_REGAL_BUS :MPS Regal Bus
+STR_8075_HEREFORD_LEOPARD_BUS :Hereford Leopard Bus
+STR_8076_FOSTER_BUS :Foster Bus
+STR_8077_FOSTER_MKII_SUPERBUS :Foster MkII Superbus
+STR_8078_PLODDYPHUT_MKI_BUS :Ploddyphut MkI Bus
+STR_8079_PLODDYPHUT_MKII_BUS :Ploddyphut MkII Bus
+STR_807A_PLODDYPHUT_MKIII_BUS :Ploddyphut MkIII Bus
+STR_807B_BALOGH_COAL_TRUCK :Balogh Steenkool Trok
+STR_807C_UHL_COAL_TRUCK :Uhl Steenkool Trok
+STR_807D_DW_COAL_TRUCK :DW Steenkool Trok
+STR_807E_MPS_MAIL_TRUCK :MPS Pos Trok
+STR_807F_REYNARD_MAIL_TRUCK :Reynard Pos Trok
+STR_8080_PERRY_MAIL_TRUCK :Perry Pos Trok
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :MightyMover Pos Trok
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Powernaught Pos Trok
+STR_8083_WIZZOWOW_MAIL_TRUCK :Wizzowow Pos Trok
+STR_8084_WITCOMBE_OIL_TANKER :Witcombe Olie Tenkwa
+STR_8085_FOSTER_OIL_TANKER :Foster Olie Tenkwa
+STR_8086_PERRY_OIL_TANKER :Perry Olie Tenkwa
+STR_8087_TALBOTT_LIVESTOCK_VAN :Talbott Lewende Hawe Wa
+STR_8088_UHL_LIVESTOCK_VAN :Uhl Lewende Hawe Wa
+STR_8089_FOSTER_LIVESTOCK_VAN :Foster Lewende Hawe Wa
+STR_808A_BALOGH_GOODS_TRUCK :Balogh Goedere Trok
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Craighead Goedere Trok
+STR_808C_GOSS_GOODS_TRUCK :Goss Goedere Trok
+STR_808D_HEREFORD_GRAIN_TRUCK :Hereford Graan Trok
+STR_808E_THOMAS_GRAIN_TRUCK :Thomas Graan Trok
+STR_808F_GOSS_GRAIN_TRUCK :Goss Graan Trok
+STR_8090_WITCOMBE_WOOD_TRUCK :Witcombe Hout Trok
+STR_8091_FOSTER_WOOD_TRUCK :Foster Hout Trok
+STR_8092_MORELAND_WOOD_TRUCK :Moreland Hout Trok
+STR_8093_MPS_IRON_ORE_TRUCK :MPS Yster Erts Trok
+STR_8094_UHL_IRON_ORE_TRUCK :Uhl Iron Yster Erts Trok
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Chippy Yster Erts Trok
+STR_8096_BALOGH_STEEL_TRUCK :Balogh Staal Trok
+STR_8097_UHL_STEEL_TRUCK :Uhl Staal Trok
+STR_8098_KELLING_STEEL_TRUCK :Kelling Staal Trok
+STR_8099_BALOGH_ARMORED_TRUCK :Balogh Gepantserde Trok
+STR_809A_UHL_ARMORED_TRUCK :Uhl Gepantserde Trok
+STR_809B_FOSTER_ARMORED_TRUCK :Foster Gepantserde Trok
+STR_809C_FOSTER_FOOD_VAN :Foster Kos Wa
+STR_809D_PERRY_FOOD_VAN :Perry Kos Wa
+STR_809E_CHIPPY_FOOD_VAN :Chippy Kos Wa
+STR_809F_UHL_PAPER_TRUCK :Uhl Papier Trok
+STR_80A0_BALOGH_PAPER_TRUCK :Balogh Papier Trok
+STR_80A1_MPS_PAPER_TRUCK :MPS Papier Trok
+STR_80A2_MPS_COPPER_ORE_TRUCK :MPS Koper Erts Trok
+STR_80A3_UHL_COPPER_ORE_TRUCK :Uhl Koper Erts Trok
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Goss Koper Erts Trok
+STR_80A5_UHL_WATER_TANKER :Uhl Water Tenkwa
+STR_80A6_BALOGH_WATER_TANKER :Balogh Water Tenkwa
+STR_80A7_MPS_WATER_TANKER :MPS Water Tenkwa
+STR_80A8_BALOGH_FRUIT_TRUCK :Balogh Vrugte Trok
+STR_80A9_UHL_FRUIT_TRUCK :Uhl Vrugte Trok
+STR_80AA_KELLING_FRUIT_TRUCK :Kelling Vrugte Trok
+STR_80AB_BALOGH_RUBBER_TRUCK :Balogh Gomlastiek Trok
+STR_80AC_UHL_RUBBER_TRUCK :Uhl Gomlastiek Trok
+STR_80AD_RMT_RUBBER_TRUCK :RMT Gomlastiek Trok
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :MightyMover Suiker Trok
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Powernaught Suiker Trok
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Wizzowow Suiker Trok
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :MightyMover Cola Trok
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Powernaught Cola Trok
+STR_80B3_WIZZOWOW_COLA_TRUCK :Wizzowow Cola Trok
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :MightyMover Spookasem Trok
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Powernaught Spookasem Trok
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Wizzowow Spookasem Trok
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :MightyMover Tameletjie Trok
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Powernaught Tameletjie Trok
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Wizzowow Tameletjie Trok
+STR_80BA_MIGHTYMOVER_TOY_VAN :MightyMover Speelgoed Wa
+STR_80BB_POWERNAUGHT_TOY_VAN :Powernaught Speelgoed Wa
+STR_80BC_WIZZOWOW_TOY_VAN :Wizzowow Speelgoed Wa
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :MightyMover Lekker Trok
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Powernaught Lekker Trok
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Wizzowow Lekker Trok
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :MightyMover Battery Trok
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Powernaught Battery Trok
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Wizzowow Battery Trok
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :MightyMover Koeldrank Trok
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Powernaught KoeldrankTrok
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Wizzowow Fizzy Koeldrank Trok
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :MightyMover Plastiek Trok
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Powernaught Plastiek Trok
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Wizzowow Plastiek Trok
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :MightyMover Borrel Trok
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Powernaught Borrel Trok
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Wizzowow Borrel Trok
+STR_80CC_MPS_OIL_TANKER :MPS Olie Tenkskip
+STR_80CD_CS_INC_OIL_TANKER :CS-Inc. Olie Tenkskip
+STR_80CE_MPS_PASSENGER_FERRY :MPS Passasier Veerboot
+STR_80CF_FFP_PASSENGER_FERRY :FFP Passasier Veerboot
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Bakewell 300 Skeertuig
+STR_80D1_CHUGGER_CHUG_PASSENGER :Chugger-Chug Passasier Veerboot
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Shivershake Passasier Veerboot
+STR_80D3_YATE_CARGO_SHIP :Yate Vrag skip
+STR_80D4_BAKEWELL_CARGO_SHIP :Bakewell Vrag skip
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Mightymover Vrag skip
+STR_80D6_POWERNAUT_CARGO_SHIP :Powernaut Vrag skip
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Tricario Helikopter
+STR_80FE_GURU_X2_HELICOPTER :Guru X2 Helikopter
+STR_80FF_POWERNAUT_HELICOPTER :Powernaut Helikopter
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Boodskap van voertuig fabrikant
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}Ons het juis 'n nuwe {STRING} ontwerp - sal jy in 'n jaar se eksklusief gebruik van die voertuig belang stel, dus kan ons sien hoe hy uitvoer voor dit algemeen beskikbaar is?
+STR_8102_RAILROAD_LOCOMOTIVE :spoorweg lokomotief
+STR_8103_ROAD_VEHICLE :pad voertuig
+STR_8104_AIRCRAFT :vliegtuig
+STR_8105_SHIP :skip
+STR_8106_MONORAIL_LOCOMOTIVE :eenspoor lokomotief
+STR_8107_MAGLEV_LOCOMOTIVE :maglev lokomotief
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}{TOWN} Trein Depot
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Burgers herdenk . . .{}Eerste trein arriveer by {STATION}!
+STR_8802_DETAILS :{WHITE}{STRING} (Aanwyse)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Trein in die pad
+STR_8804 :{SETX 10}{COMMA}: {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING}
+STR_8806_GO_TO :Gaan na {STATION}
+STR_8807_GO_TO_TRANSFER :Gaan na {STATION} (Oordrag en vat vrag)
+STR_8808_GO_TO_UNLOAD :Gaan na {STATION} (Aflaai)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Gaan na {STATION} (Oordrag en verlaat leeg)
+STR_880A_GO_TO_LOAD :Gaan na {STATION} (Laai)
+STR_880B_GO_TO_TRANSFER_LOAD :Gaan na {STATION} (Oordrag en wag vir volle lading)
+STR_880C_GO_NON_STOP_TO :Gaan deurgaande na {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Gaan deurgaande na {STATION} (Oordrag en vat vrag)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Gaan deurgaande na {STATION} (Aflaai)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Gaan deurgaande na {STATION} (Oordrag en verlaat leeg)
+STR_8810_GO_NON_STOP_TO_LOAD :Gaan deurgaande na {STATION} (Laai)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Gaan deurgaande na {STATION} (Oordrag en wag vir volle lading)
+STR_GO_TO_TRAIN_DEPOT :Gaan na {TOWN} Trein Depot
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Gaan deurgaande na {TOWN} Trein Depot
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}Op pad na {TOWN} Trein Depot
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}Op pad na {TOWN} Trein Depot, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (Swak Opdrag)
+
+STR_8812_EMPTY :{LTBLUE}Leeg
+STR_8813_FROM :{LTBLUE}{CARGO} vanaf {STATION}
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}Trein {COMMA} wag in depot
+STR_8815_NEW_VEHICLES :{BLACK}Nuwe Voertuie
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Trein te lang
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Treine kan slegs verander word as hulle in die depot gestop is
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} Trein{P "" s}
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Nuwe Spoor Voertuie
+STR_NEW_ELRAIL_VEHICLES :{WHITE}Nuwe Elektries Spoor Voertuie
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Nuwe Eenspoor Voertuie
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Nuwe Maglev Voertuie
+STR_881F_BUILD_VEHICLE :{BLACK}Bou Voertuig
+STR_CLONE_ROAD_VEHICLE :{BLACK}Kloon Voertuig
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}Dit sal 'n afskrywing van die pad voertuig bou. Control-kliek sal die opdrae deel
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Dit sal 'n afskrywing van 'n pad voertuig bou. Kliek die knoppie en dan op 'n pad voertuig binne of buite die depot. Control-kliek sal die opdrae deel
+STR_CLONE_TRAIN :{BLACK}Kloon Trein
+STR_CLONE_TRAIN_INFO :{BLACK}Dit sa 'n afskrywing van die trein bou insluitend alle trokke. Control-kliek sal die opdrae deel
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}Dit sal 'n afskrywing van 'n trein bou insluitend alle trokke. Kliek die knoppie en dan op 'n trein binne of buite die depot. Control-kliek sal die opdrae deel
+STR_8820_RENAME :{BLACK}Hername
+STR_8823_SKIP :{BLACK}Sprong
+STR_8824_DELETE :{BLACK}Uitwis
+STR_8825_NON_STOP :{BLACK}Deurgaande
+STR_8826_GO_TO :{BLACK}Gaan Na
+STR_8827_FULL_LOAD :{BLACK}Volle Lading
+STR_8828_UNLOAD :{BLACK}Aflaai
+STR_8829_ORDERS :{WHITE}{VEHICLE} (Opdrae)
+STR_882A_END_OF_ORDERS :{SETX 10}- - Einde van Opdrae - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Kan nie spoorweg voertuig bou nie...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Gebou: {LTBLUE}{NUM}{BLACK} Waarde: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Waarde: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}Laai / Aflaai
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Kan nie trein na depot stuur nie...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Geen spasie vir nog opdrae
+STR_8832_TOO_MANY_ORDERS :{WHITE}Te veel opdrae
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Kan nie nuwe opdrag invoeg nie...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Die opdrag kan nie uitwis word nie...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Die opdrag kan nie verander word nie...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Voertuig kan nie beweeg nie...
+STR_8838_N_A :N/A{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Kan nie spoorweg voertuig verkoop nie...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Kan nie roete vind na plaaslike depot nie
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Trein kan nie stop/ry word nie...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Diens tussentyd: {LTBLUE}{COMMA}dae{BLACK} Laaste diens: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Treine - kliek op trein vir inligting
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Bou nuwe treine (vereis trein depot)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Treine - kliek op trein vir info., sleep voertuig om te bysit/verwyder van trein
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Bou nuwe trein voertuig
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Sleep trein voertuig hier om dit te verkoop
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}senter skerm op trein depot
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Trein voertuig keuse lys - kliek op voertuig vir inligting
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Bou die beklemtoonde trein voertuig
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Hernaam trein voertuig tipe
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Huidige trein aksie - kliek hier om trein te stop/aanvang trein
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Wys trein se opdrae
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Senter skerm op trein
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Stuur trein na depot
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Dwing trein om voort te gaan sonder om vir seine te wag
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Omkeer rigting van trein
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Wys trein se aanwyse
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Verhoog diens tussentyd
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Verminder diens tussentyd
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Wys aanwyse van vrag gedra
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Wys aanwyse van trein voertuie
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Wys kapasiteite van elke voertuig
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}wys totaale kapasitiet van trein, verdeel by vrag tipe
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Opdraglys - kliek op 'n opdrag om dit te beklemtoon. CTRL + kliek senter op stasie
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}Sprong die huidige opdrag, en begin die volgende
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Uitwis die beklemtoonde opdrag
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Maak die beklemtoonde opdrag deaugaande
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Invoeg 'n nuwe opdrag voor die beklemtoonde opdrag, of byvoeg na einde van lys
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Maak die beklemtoonde opdrag dwing die voertuig om vir 'n volle lading te wag
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Maak die beklemtoonde opdrag dwing die voertuig te aflaai
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}Nuwe {STRING} nou beskikbaar!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_885C_BROKEN_DOWN :{RED}Oponthoud
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}Ouderdom: {LTBLUE}{STRING}{BLACK} Loopkoste: {LTBLUE}{CURRENCY}/Jr
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profyt die jaar: {LTBLUE}{CURRENCY} (verlede jaar: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}Deeglikheid: {LTBLUE}{COMMA}% {BLACK}Oponthoude sedert laaste diens: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Gestop
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Kan nie tein dwing om sein te vermy op gevaar...
+STR_8863_CRASHED :{RED}Botsing!
+
+STR_8865_NAME_TRAIN :{WHITE}Benaam trein
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}Trein kan nie benaam word nie...
+STR_8867_NAME_TRAIN :{BLACK}Benaam trein
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Trein Botsing!{}{COMMA} sterf in vuurbol na botsing
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Kan nie rigting van trein omkeer nie...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Hernaam trein voertuig tipe
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Trein voertuig tipe kan nie hernaam word nie...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Maak die beklemtoonde opdrag dwing die voertuig om sy vrag te stort
+STR_886F_TRANSFER :{BLACK}Oordrag
+
+STR_INCOMPATIBLE_RAIL_TYPES :Onbestaaanbaar spoor tipes
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Pad voertuig in die pad
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} Pad voertuig{P "" s}
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}{TOWN} Pad Voertuig Depot
+STR_9004_NEW_VEHICLES :{BLACK}Nuwe Voertuie
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}Nuwe Pad Voertuie
+STR_9007_BUILD_VEHICLE :{BLACK}Bou Voertuig
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Kan nie pad voertuig bou nie...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (Aanwyse)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}Ouderdom: {LTBLUE}{STRING}{BLACK} Loopkoste: {LTBLUE}{CURRENCY}/Jr
+STR_900E_MAX_SPEED :{BLACK}Max. spoed: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profyt die jaar: {LTBLUE}{CURRENCY} (verlede jaar: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}Deeglikheid: {LTBLUE}{COMMA}% {BLACK}Oponthoude sedert laaste diens: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Gebou: {LTBLUE}{NUM}{BLACK} Waarde: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Kapasitiet: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}...moet gestop binne 'n pad depot wees
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Kan nie pad voertuig verkoop nie
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Kani nie pad voertuig stop/ry nie...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}Pad voertuig {COMMA} wag in depot
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}Op pad na {TOWN} Pad Depot
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}Op pad na {TOWN} Pad Depot, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Kan nie voertuig na depot stuur nie...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Kan nie plaaslike depot vind nie
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Pad voertuie - kliek op voertuig vir inligting
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Bou nuwe pad voertuie (vereis pad voertuig depot)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Huidige voertuig aksie - kliek hier om voertuig to stop/ry
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Wys voertuig se opdrae
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Senter skerm op voertuig
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Stuur voertuig na depot
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Dwing voertuig om om te draai
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Wys pad voertuig aanwyse
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Voertuie - kliek op voertuig vir inligting
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Bou nuwe pad voertuig
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Sleep pad voertuig hier om dit te verkoop
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Senter skerm op pad voertuig depot
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Pad voertuig keuse lys - kliek op voertuig vir inligting
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Bou die beklemtoonde pad voertuig
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}Nuwe pad voertuig is nou beskikbaar!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Koste: {CURRENCY}{}Speod: {VELOCITY}{}Loopkoste: {CURRENCY}/yr{}Kapasitiet: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Benaam pad voertuig
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Pad voertuig kan nie benaam word nie...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Benaam pad voertuig
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Burgers herdenk . . .{}Eerste bus arriveer by {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Burgers herdenk . . .{}Eerste trok arriveer by {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}Pad Voertuig Botsing!{}Bestuurder sterf in vuurbol na botsing met trein
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}Pad voertuig Botsing!{}{COMMA} sterf in vuurbol na botsing met trein
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Kan nie voertuig dwing om te omdraai nie
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}Kan nie voertuie van veel deele draai nie
+STR_9034_RENAME :{BLACK}Hernaam
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Hernaam pad voertuig tipe
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Hernaam pad voertuig tipe
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Pad voertuig tipe kan nie hernaam word nie...
+STR_9038_GO_TO_ROADVEH_DEPOT :Gaan na {TOWN} Pad Voertuig Depot
+
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Werf Konstruksie
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Werf konstruksie
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Kan nie werf hier bou nie...
+STR_9803_SHIP_DEPOT :{WHITE}{TOWN} Skip Depot
+STR_9804_NEW_SHIPS :{BLACK}Nuwe Skepe
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} Skeep{P "" s}
+STR_9808_NEW_SHIPS :{WHITE}Nuwe Skepe
+STR_9809_BUILD_SHIP :{BLACK}Bou Skip
+STR_CLONE_SHIP :{BLACK}Kloon Skip
+STR_CLONE_SHIP_INFO :{BLACK}Dit sal 'n afskrywing van die skip bou. Control-kliek sal die opdrae deel
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}Dit sal 'n afskrywing van 'n skip bou. Kliek die knoppie en dan op 'n skip binne of buite die depot. Control-kliek sal die opdrae deel
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}Skip moet in 'n depot gestop wees
+STR_980C_CAN_T_SELL_SHIP :{WHITE}Skip kan nie verkoop word nie...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Kan nie skip bou nie...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Skip in die pad
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Aanwyse)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}Ouderdom: {LTBLUE}{STRING}{BLACK} Loopkoste: {LTBLUE}{CURRENCY}/Jr
+STR_9813_MAX_SPEED :{BLACK}Max. spoed: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profyt die jaar: {LTBLUE}{CURRENCY} (verlede jaar: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}Deeglikheid: {LTBLUE}{COMMA}% {BLACK}Oponthoude sedert laaste diens: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Gebou: {LTBLUE}{NUM}{BLACK} Waarde: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}Kapasitiet: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}Kan nie skip stop/ry nie
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Kan nie skip na depot sttur nie...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Kan nie plaaslike depot vind nie
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}Op pad na {TOWN} Skip Depot
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}Op pad na {TOWN} Skip Depot, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}Skip {COMMA} wag in depot
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Bou skip werf
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Bou skip depot (vir opbou en diens van skepe)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Skepe - kliek op skeep vir inligting
+STR_9820_BUILD_NEW_SHIP :{BLACK}Bou nuwe skip
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Sleep skip hier om dit te verkoop
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Senter skerm op skip depot
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Skepe - kliek op skip vir inligting
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Bou nuwe skepe (vereis skip depot)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}Skip keuse lys - kliek op skip vir inligting
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Bou die beklemtoonde skip
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Huidige skip aksie - kliek hier om skip te stop/ry
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Wys skip se opdrae
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Senter skerm op skip
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Stuur skip na depot
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Wys skip se aanwyse
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}Nuwe skip nou beskikbaar!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Koste: {CURRENCY} Max. Spoed: {VELOCITY}{}Kapasitiet: {CARGO}{}Loopkoste: {CURRENCY}/yr
+STR_982F_NAME_SHIP :{BLACK}Benaam skip
+
+STR_9831_NAME_SHIP :{WHITE}Benaam skip
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Kan nie skip benaam nie...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Burgers herdenk . . .{}Eerste skip arriveer by {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Plaas baken wat kan as 'n wegpunt gebruik word
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Kan nie baken hier plaas nie...
+STR_9836_RENAME :{BLACK}Hernaam
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Hernaam skip tipe
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Hernaam skip tipe
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Kan nie skip tipe hernaam nie...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Herstel vrag skip om 'n ander vrag tipe te vervoer
+STR_983B_REFIT :{WHITE}{VEHICLE} (Herstel)
+STR_983C_REFIT_SHIP :{BLACK}Herstel skip
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Kies vrag tipe vir skip te vervoer
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Herstel skip om die beklemtoonde vrag tipe te vervoer
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Kies vrag tipe vir skip te vervoer:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nuwe kapasiteit: {GOLD}{CARGO}{}{BLACK}Herstelkoste: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Skip kan nie herstel word nie...
+STR_9842_REFITTABLE :(herstelbaar)
+STR_GO_TO_SHIP_DEPOT :Gaan na {TOWN} Skip Depot
+SERVICE_AT_SHIP_DEPOT :Versiening by {TOWN} Skip Depot
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Lughawe
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Lughawe kan nie hier gebou word nie...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} Vliegtuig Hangar
+STR_A003_NEW_AIRCRAFT :{BLACK}Nuwe Vliegtuig
+STR_CLONE_AIRCRAFT :{BLACK}Kloon Vliegtuig
+STR_CLONE_AIRCRAFT_INFO :{BLACK}Dit sal 'n afskrywing van die vliegtuig bou. Control-kliek sal die opdrae deel
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Dit sal 'n afskrywing van 'n vliegtuig bou. Kliek die knoppie en dan op 'n vliegtuig binne of buite die hangar. Control-kliek sal die opdrae deel
+STR_A005_NEW_AIRCRAFT :{WHITE}Nuwe Vliegtuig
+STR_A006_BUILD_AIRCRAFT :{BLACK}Bou Vliegtuig
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Kan nie vliegtuig bou nie...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} Vliegtuie
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (Opdrae)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (Aanwyse)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Ouderdom: {LTBLUE}{STRING}{BLACK} Loopkoste: {LTBLUE}{CURRENCY}/Jr
+STR_A00E_MAX_SPEED :{BLACK}Max. spoed: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profyt die jaar: {LTBLUE}{CURRENCY} (verlede jaar: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}Deeglikheid: {LTBLUE}{COMMA}% {BLACK}Oponthoude sedert laaste diens: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Gebou: {LTBLUE}{NUM}{BLACK} Waarde: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Kan nie vlietuig na hangar stuur nie...
+STR_HEADING_FOR_HANGAR :{ORANGE}Op pad na {STATION} Hangar
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}Op pad na {STATION} Hangar, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}Vliegtuig {COMMA} wag in die vliegtuig hangar
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Vliegtuig in die pad
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Kan nie vliegtuig staak/aanvang nie...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Vliegtuig is opvlug
+STR_A019_CAPACITY :{BLACK}Kapasiteit: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Kapasiteit: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}Vliegtuig moet in hangar gestop wees
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Vliegtuig kan nie verkoop word nie...
+STR_A01D_AIRPORT_CONSTRUCTION :Lughawe konstruksie
+STR_A01E_BUILD_AIRPORT :{BLACK}Bou lughawe
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Vliegtuie - kliek op vliegtuig vir inligting
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Bou nuwe vliegtuig (vereis lughawe met hangar)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Vliegtuie - kliek op vliegtuig vir inligting
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Bou nuwe vliegtuig
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}Sleep vliegtuig hier om dit te verkoop
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Senter skerm op hangar
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Vliegtuig keuse lys - kliek op vliegtuig vir inligting
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Bou die beklemtoonde vliegtuig
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Huidige vliegtuig aksie - kliek hier on vliegtuig te stop/ry
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Wys vliegtuig se bestellings
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Senter skerm op vliegtuig
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Stuur vliegtuig na hangar
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Wys vliegtuig aanwyse
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}Nuwe vliegtuig nou beskikbaar!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Koste: {CURRENCY} Max. Spoed: {VELOCITY}{}Kapasiteit: {COMMA} passasiers, {COMMA} sakke van pos{}Loopkoste: {CURRENCY}/Jr
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Benaam vliegtuig
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Vliegtuig kan nie benaam word nie...
+STR_A032_NAME_AIRCRAFT :{BLACK}Benaam vliegtuig
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Burgers herdenk . . .{}Eerste vliegtuig arriveer by {STATION}!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Vliegtuig Botsing!{}{COMMA} stef in die vuurbol by {STATION}
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Hernaam
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Hernaam vliegtuig tipe
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Hernaam vliegtuig tipe
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Kan nie vliegtuig tipe hernaam nie...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Hestel vliegtuig om 'n ander vrag tipe te vervoer
+STR_A03C_REFIT :{WHITE}{VEHICLE} (Herstel)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Herstel vliegtuig
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Kies vrag tipe vir vliegtuig om te vervoer
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Herstel vliegtuig om beklemtoonde vrag tipe te vervoer
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Kies vrag tipe om te vervoer:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nuwe kapasiteit: {GOLD}{STRING}{}{BLACK}Herstelkoste: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Vliegtuig kan nie herstel word nie...
+STR_GO_TO_AIRPORT_HANGAR :Gaan na {STATION} Hangar
+SERVICE_AT_AIRPORT_HANGAR :Versiening by {STATION} Hangar
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}Zeppelin ramp by {STATION}!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Pad voertuig vernietig in 'VVV' botsing!
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}Olie raffineerdery ontploffing naby {TOWN}!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}Fabriek vernietig in verdage omstandighede naby {TOWN}!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}'VVV' beland naby {TOWN}!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}Steenkool myn bedaaring los spoor van vernietiging naby {TOWN}!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Vloede!{}Te minste {COMMA} verlore, vermoede dood agter beduidend vloeding!
+
+STR_BRIBE_FAILED :{WHITE}Jou omkooping onderneeming is deur
+STR_BRIBE_FAILED_2 :{WHITE}'n streek navorser uitgevind
+STR_BUILD_DATE :{BLACK}Gebou: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Voertuie:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Stasies:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Min. profyt:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Min. inkome:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Max. inkome:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Afgelewer:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Vrag:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Geld:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Lening:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Totaal:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Nommer van voertuie; dit sluit pad voertuie, treine, skepe en vliegtuie in
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}Die profyt van die voertuig met die laagste inkome (van alle voertuie ouer as 2 jaare)
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Bedrag van kontant gemaak in die maand met die laagste profyt in die laaste 12 kwartiers
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Bedrag van kontant gemaak in die maand met die hoogste profyt in die laaste 12 kwartiers
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}Eenheide van vrag afgelewer in die laaste vier kwartiers
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}Nommer van vrag tipes afgelewer in die verlede kwartier
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Bedrag van geld die maatskappy het in die bank
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}Die bedrag van geld dat die maatskappy het gevat op lening
+
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}Newgrf stellings
+STR_NEWGRF_TIP :{BLACK}'n Lys van al die Newgrf stelle wat ingestel is. Kliek op 'n stel om die stellings te verander
+STR_NEWGRF_FILENAME :{BLACK}Leernaam: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
+
+STR_CURRENCY_WINDOW :{WHITE}Gewoonte koers
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Wisselkoers: {ORANGE}{CURRENCY} = {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Afskeier
+STR_CURRENCY_PREFIX :{LTBLUE}Vervoegsel:
+STR_CURRENCY_SUFFIX :{LTBLUE}Agtervoegsel:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Verwissel na Euro: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Verwissel na Euro: {ORANGE}nooit
+STR_CURRENCY_PREVIEW :{LTBLUE}Voorskou: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Verander gewoonte koers stelling
+
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+
+
+
+STR_NOT_REPLACING :{BLACK}Word nie vervang nie
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Geen voertuig gekies
+STR_ENGINE_NOT_BUILDABLE :{WHITE}Enjin is nie boubaar nie
+
+STR_ENGINES :Enjine
+
+
+############ Lists rail types
+
+STR_ELRAIL_VEHICLES :Elektrifiseerde Spoor Voertuie
+STR_MONORAIL_VEHICLES :Eenspoor Voertuie
+STR_MAGLEV_VEHICLES :Maglev voertuie
+
+############ End of list of rail types
+
+
+
+########### String for new airports
+STR_CITY_AIRPORT :{BLACK}Stad
+STR_INTERNATIONAL_AIRPORT :{BLACK}Internasionaale lughawe
+STR_COMMUTER_AIRPORT :{BLACK}Pendelaar
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Tussenkontinentaal
+STR_HELIPORT :{BLACK}Helihawe
+STR_HELIDEPOT :{BLACK}Helidepot
+STR_HELISTATION :{BLACK}Helistasie
+
+STR_LARGE_AIRPORTS :{BLACK}Groot Lughawe
+STR_HELIPORTS :{BLACK}Helikopter lughawe
+########
diff --git a/src/lang/unfinished/croatian.txt b/src/lang/unfinished/croatian.txt
new file mode 100644
index 000000000..cbfafb8cb
--- /dev/null
+++ b/src/lang/unfinished/croatian.txt
@@ -0,0 +1,1713 @@
+##name Croatian
+##ownname Hrvatski
+##isocode hr_HR.UTF-8
+##plural 6
+##gender male female middle
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Izvan rubova karte
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Preblizu rubu karte
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Nedovoljno gotovine - potrebno {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Potrebna ravna površina
+STR_0008_WAITING :{BLACK}ÄŒekanje: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (na putu od
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Prihvaća: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Prihvaća: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :Putnici
+STR_0010_COAL :Ugljen
+STR_0011_MAIL :Pošta
+STR_0012_OIL :Nafta
+STR_0013_LIVESTOCK :Domaće životinje
+STR_0014_GOODS :Robe
+STR_0015_GRAIN :Žito
+STR_0016_WOOD :Drvo
+STR_0017_IRON_ORE :Željezo
+STR_0018_STEEL :ÄŒelik
+STR_0019_VALUABLES :Dragocjenosti
+STR_001A_COPPER_ORE :Bakar
+STR_001B_MAIZE :Kukuruz
+STR_001C_FRUIT :Voće
+STR_001D_DIAMONDS :Dijamanti
+STR_001E_FOOD :Hrana
+STR_001F_PAPER :Papir
+STR_0020_GOLD :Zlato
+STR_0021_WATER :Voda
+STR_0022_WHEAT :PÅ¡enica
+STR_0023_RUBBER :Guma
+STR_0024_SUGAR :Šećer
+STR_0025_TOYS :IgraÄke
+STR_0026_CANDY :Slatkiši
+STR_0027_COLA :Cola
+STR_0028_COTTON_CANDY :Šećerna vuna
+STR_0029_BUBBLES :Baloni
+STR_002A_TOFFEE :MlijeÄne karamele
+STR_002B_BATTERIES :Baterije
+STR_002C_PLASTIC :Plastika
+STR_002D_FIZZY_DRINKS :Gazirana pića
+STR_002E :
+STR_002F_PASSENGER :Putnik
+STR_0030_COAL :Ugljen
+STR_0031_MAIL :Pošta
+STR_0032_OIL :Nafta
+STR_0033_LIVESTOCK :Domaće životinje
+STR_0034_GOODS :Robe
+STR_0035_GRAIN :Žito
+STR_0036_WOOD :Drvo
+STR_0037_IRON_ORE :Željezo
+STR_0038_STEEL :ÄŒelik
+STR_0039_VALUABLES :Dragocjenosti
+STR_003A_COPPER_ORE :Bakar
+STR_003B_MAIZE :Kukuruz
+STR_003C_FRUIT :Voće
+STR_003D_DIAMOND :Dijamant
+STR_003E_FOOD :Hrana
+STR_003F_PAPER :Papir
+STR_0040_GOLD :Zlato
+STR_0041_WATER :Voda
+STR_0042_WHEAT :PÅ¡enica
+STR_0043_RUBBER :Guma
+STR_0044_SUGAR :Šećer
+STR_0045_TOY :IgraÄka
+STR_0046_CANDY :Slatkiš
+STR_0047_COLA :Cola
+STR_0048_COTTON_CANDY :Šećerna vuna
+STR_0049_BUBBLE :Balon
+STR_004A_TOFFEE :MlijeÄna karamela
+STR_004B_BATTERY :Baterija
+STR_004C_PLASTIC :Plastika
+STR_004D_FIZZY_DRINK :Gazirano piće
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_COAL :{WEIGHT} ugljena
+STR_QUANTITY_OIL :{VOLUME} nafte
+STR_QUANTITY_GRAIN :{WEIGHT} žita
+STR_QUANTITY_WOOD :{WEIGHT} drveta
+STR_QUANTITY_IRON_ORE :{WEIGHT} željeza
+STR_QUANTITY_STEEL :{WEIGHT} Äelika
+STR_QUANTITY_COPPER_ORE :{WEIGHT} bakra
+STR_QUANTITY_MAIZE :{WEIGHT} kukuruza
+STR_QUANTITY_FRUIT :{WEIGHT} voća
+STR_QUANTITY_FOOD :{WEIGHT} hrane
+STR_QUANTITY_PAPER :{WEIGHT} papira
+STR_QUANTITY_WATER :{VOLUME} vode
+STR_QUANTITY_WHEAT :{WEIGHT} pšenice
+STR_QUANTITY_RUBBER :{VOLUME} gume
+STR_QUANTITY_SUGAR :{WEIGHT} šećera
+STR_QUANTITY_COLA :{VOLUME} cole
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} šećerne vune
+STR_QUANTITY_TOFFEE :{WEIGHT} mlijeÄne karamele
+STR_QUANTITY_PLASTIC :{VOLUME} plastike
+STR_ABBREV_NOTHING :
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Karta - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Opcije za igru
+STR_00B2_MESSAGE :{YELLOW}Poruka
+STR_00B3_MESSAGE_FROM :{YELLOW}Poruka od {STRING}
+STR_00B4_CAN_T_DO_THIS :{WHITE}Ne mogu to uÄiniti....
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Nije moguće oÄistiti ovo podruÄje....
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Izvorno autorsko pravo {COPYRIGHT} 1995 Chris Sawyer, sva prava pridržana
+STR_00B7_VERSION :{BLACK}OpenTTD verzija {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 OpenTTD tim
+STR_TRANSLATED_BY :{BLACK} Prevoditelj(i) -
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Prekid
+STR_00C8_YES :{BLACK}Da
+STR_00C9_NO :{BLACK}Ne
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Jesi li siguran da želiš napustiti ovu igru i vratiti se {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Ništa
+STR_00D1_DARK_BLUE :Tamnoplava
+STR_00D2_PALE_GREEN :Blijedozelena
+STR_00D3_PINK :RužiÄasta
+STR_00D4_YELLOW :Žuta
+STR_00D5_RED :Crvena
+STR_00D6_LIGHT_BLUE :Svijetloplava
+STR_00D7_GREEN :Zelena
+STR_00D8_DARK_GREEN :Tamnozelena
+STR_00D9_BLUE :Plava
+STR_00DA_CREAM :Kremasta
+STR_00DB_MAUVE :SvijetloljubiÄasta
+STR_00DC_PURPLE :LjubiÄasta
+STR_00DD_ORANGE :NaranÄasta
+STR_00DE_BROWN :Smeđa
+STR_00DF_GREY :Siva
+STR_00E0_WHITE :Bijela
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Previše vozila u igri
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Lokacija
+STR_00E5_CONTOURS :Obrisi
+STR_00E6_VEHICLES :Vozila
+STR_00E7_INDUSTRIES :Gospodarstva
+STR_00E8_ROUTES :Trase
+STR_00E9_VEGETATION :Vegetacija
+STR_00EA_OWNERS :Vlasnici
+STR_00EB_ROADS :{BLACK}{TINYFONT}Ceste
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Željeznice
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Stanice/Zrakoplovne luke/Pristaništa
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Građevine/Gospodarstva
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Vozila
+STR_00F0_100M :{BLACK}{TINYFONT}100m
+STR_00F1_200M :{BLACK}{TINYFONT}200m
+STR_00F2_300M :{BLACK}{TINYFONT}300m
+STR_00F3_400M :{BLACK}{TINYFONT}400m
+STR_00F4_500M :{BLACK}{TINYFONT}500m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Vlakovi
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Cestovna vozila
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Brodovi
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Zrakoplov
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Prijevozne trase
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Rudnik ugljena
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Elektrana
+STR_00FC_FOREST :{BLACK}{TINYFONT}Å uma
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}Pilana
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Naftna rafinerija
+STR_00FF_FARM :{BLACK}{TINYFONT}Farma
+STR_0100_FACTORY :{BLACK}{TINYFONT}Tvornica
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Tiskara
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Naftna polja
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Rudnik željeza
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}ÄŒeliÄana
+STR_0105_BANK :{BLACK}{TINYFONT}Banka
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Tvornica papira
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Rudnik zlata
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Tvornica hrane
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Rudnik dijamanata
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Rudnik bakra
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Plantaža voća
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Plantaža gume
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Izvor vode
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Vodotoranj
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}Pilana
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Šuma šećerne vune
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Tvornica slatkiša
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Tvornica baterija
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Izvori Cole
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Trgovina igraÄkama
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Tvornica igraÄaka
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Izvori plastike
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Tvornica gaziranih pića
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Generator balona
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Iskop mlijeÄne karamele
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Šećerana
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}ŽeljezniÄka stanica
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Kamionski terminal
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Autobusn stanica
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Aerodrom/Heliodrom
+STR_011F_DOCK :{BLACK}{TINYFONT}Pristanište
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Surova zemlja
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Travnjak
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Ogoljena zemlja
+STR_0123_FIELDS :{BLACK}{TINYFONT}Polja
+STR_0124_TREES :{BLACK}{TINYFONT}Stabla
+STR_0125_ROCKS :{BLACK}{TINYFONT}Stijenje
+STR_0126_WATER :{BLACK}{TINYFONT}Voda
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Bez vlasnika
+STR_0128_TOWNS :{BLACK}{TINYFONT}Gradovi
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Gospodarstva
+STR_012A_DESERT :{BLACK}{TINYFONT}Pustinja
+STR_012B_SNOW :{BLACK}{TINYFONT}Snijeg
+STR_012C_MESSAGE :{WHITE}Poruka
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Odustani
+STR_012F_OK :{BLACK}OK
+STR_0130_RENAME :{BLACK}Preimenuj
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Previše definiranih imena
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Odabrano ime već se koristi
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...u vlasništvu {STRING}
+STR_013C_CARGO :{BLACK}Teret
+STR_013D_INFORMATION :{BLACK}Informacije
+STR_013E_CAPACITIES :{BLACK}Nosivosti
+STR_013E_TOTAL_CARGO :{BLACK}Ukupni teret
+STR_013F_CAPACITY :{BLACK}Nosivost: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}Nosivost: {LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Ukupna teretna nosivost ovoga vlaka:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}Nova igra
+STR_0141_LOAD_GAME :{BLACK}UÄitaj igru
+STR_SINGLE_PLAYER :{BLACK}Jedan igraÄ
+STR_MULTIPLAYER :{BLACK}ViÅ¡e igraÄa
+
+STR_64 :64
+STR_128 :
+STR_256 :256
+STR_512 :512
+STR_1024 :
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}VeliÄina karte:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Postavke igre
+
+STR_0150_SOMEONE :netko{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Karta svijeta
+STR_0152_TOWN_DIRECTORY :Popis gradova
+STR_0153_SUBSIDIES :Subvencije
+
+STR_UNITS_IMPERIAL :Imperijalni
+STR_UNITS_METRIC :MetriÄki
+STR_UNITS_SI :SI
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} mph
+STR_UNITS_VELOCITY_METRIC :{COMMA} km/h
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}KS
+STR_UNITS_POWER_METRIC :{COMMA}KS
+STR_UNITS_POWER_SI :{COMMA}kW
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg
+
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} kg
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}gal
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}l
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}m³
+
+STR_UNITS_VOLUME_LONG_SI :{COMMA} m³
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10³ lbf
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Graf operativne zarade
+STR_0155_INCOME_GRAPH :Graf prihoda
+STR_0156_DELIVERED_CARGO_GRAPH :Graf isporuÄenog tereta
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Graf povijesti uÄinka
+STR_0158_COMPANY_VALUE_GRAPH :Graf vrijednosti tvrtke
+STR_0159_CARGO_PAYMENT_RATES :Iznosi plaćanja tereta
+STR_015A_COMPANY_LEAGUE_TABLE :Tablica lige tvrtki
+STR_PERFORMANCE_DETAIL_MENU :Detaljna ocjena uÄinka
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}O OpenTTD
+STR_015C_SAVE_GAME :Spremi igru
+STR_015D_LOAD_GAME :UÄitaj igru
+STR_015E_QUIT_GAME :Napusti igru
+STR_015F_QUIT :Izlaz
+STR_0161_QUIT_GAME :{WHITE}Napusti igru
+STR_SORT_ORDER_TIP :{BLACK}Izaberi naÄin sortiranja (silazno/uzlazno)
+STR_SORT_CRITERIA_TIP :{BLACK}Izaberi kriterij za sortiranje
+STR_SORT_BY :{BLACK}Sortiraj prema
+
+STR_SORT_BY_POPULATION :{BLACK}Stanovnici
+STR_SORT_BY_PRODUCTION :{BLACK}Produkcija
+STR_SORT_BY_TYPE :{BLACK}Vrsta
+STR_SORT_BY_TRANSPORTED :{BLACK}Prevezeno
+STR_SORT_BY_NAME :{BLACK}Ime
+STR_SORT_BY_DROPDOWN_NAME :Ime
+STR_SORT_BY_DATE :{BLACK}Datum
+STR_SORT_BY_NUMBER :Broj
+STR_SORT_BY_PROFIT_LAST_YEAR :Zarada prošle godine
+STR_SORT_BY_PROFIT_THIS_YEAR :Zarada ove godine
+STR_SORT_BY_AGE :Godine
+STR_SORT_BY_RELIABILITY :Pouzdanost
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Totalna nosivost po vrsti tereta
+STR_SORT_BY_MAX_SPEED :Maksimalna brzina
+STR_SORT_BY_MODEL :Model
+STR_SORT_BY_VALUE :Vrijednost
+STR_SORT_BY_FACILITY :Vrsta stanice
+STR_SORT_BY_WAITING :Vrijednost tereta koji Äeka
+STR_SORT_BY_RATING_MAX :Ocjena tereta
+STR_ENGINE_SORT_COST :Trošak
+STR_ENGINE_SORT_POWER :Snaga
+STR_ENGINE_SORT_INTRO_DATE :Datum poÄetka
+STR_ENGINE_SORT_RUNNING_COST :Trošak uporabe
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Trošak snage/uporabe
+STR_ENGINE_SORT_CARGO_CAPACITY :Nosivost tereta
+STR_NO_WAITING_CARGO :{BLACK}Nijedna vrsta tereta ne Äeka
+STR_SELECT_ALL_FACILITIES :{BLACK}Izaberi sva sredstva
+STR_SELECT_ALL_TYPES :{BLACK}Izaberi sve vrste tereta (ukljuÄujući i teret koji ne Äeka)
+
+############ range for months starts
+STR_0162_JAN :Sij
+STR_0163_FEB :Velj
+STR_0164_MAR :Ožu
+STR_0165_APR :Tra
+STR_0166_MAY :Svi
+STR_0167_JUN :Lip
+STR_0168_JUL :Srp
+STR_0169_AUG :Kol
+STR_016A_SEP :Ruj
+STR_016B_OCT :Lis
+STR_016C_NOV :Stu
+STR_016D_DEC :Pro
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Zaustavi igru
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Spremi igru, napusti igru, prekini igru
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Prikaži popis stanica u vlasništvu tvrke
+STR_0174_DISPLAY_MAP :{BLACK}Prikaži kartu
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Prikaži kartu, popis gradova
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Prikaži popis gradova
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Prikaži financijske podatke tvrke
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Prikaži opće podatke tvrtke
+STR_0179_DISPLAY_GRAPHS :{BLACK}Prikaži grafove
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Prikaži tablicu lige tvrtki
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Prikaži popis vlakova u posjedu tvrtke
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Prikaži popis cestovnih vozila u posjedu tvrke
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Prikaž popis brodova u posjedu tvrke
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Prikaži popis zrakoplova u posjedu tvrtke
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Približi pogled
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Udalji pogled
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Izgradi željezniÄku prugu
+STR_0182_BUILD_ROADS :{BLACK}Izgradi cestu
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Izgradi pristanište za brodove
+STR_0184_BUILD_AIRPORTS :{BLACK}Izgradi zraÄnu luku
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Posadi drveće, postavi znakove itd.
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Podatci o zemlji
+STR_0187_OPTIONS :{BLACK}Postavke
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Promijeni servisni interval...
+STR_018B_CLOSE_WINDOW :{BLACK}Zatvori prozor
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Naslov prozora - povuci ovo za micanje prozora
+STR_STICKY_BUTTON :{BLACK}OznaÄi ovaj prozor kao nezatvoriv kad se rabi tipka 'Zatvori sve prozore'
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Uništi građevine itd. na kvadratu zemlje
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Snizi vrh kvadrata zemlje
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Povisi vrh kvadrata zemlje
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}PomiÄna traka - lista gore/dolje
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Prikaži obrise zemlje na karti
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Prikaži vozila na karti
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Prikaži gospodarstva na karti
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Prikaži prijevozne trase na karti
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Prikaži vegetaciju na karti
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Prikaži vlasnike zemlje na karti
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Prikaži/sakrij ime grada na karti
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Zarada ove godine: {CURRENCY} (prošle godine: {CURRENCY})
+
+############ range for service numbers starts
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Cestovno vozilo
+STR_019D_AIRCRAFT :Zrakoplov
+STR_019E_SHIP :Brod
+STR_019F_TRAIN :Vlak
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} postaje star
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} postaje vrlo star
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} postaje vrlo star i hitno treba zamjenu
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Podatci o zemlji
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}TroÅ¡kovi Äišćenja: {LTBLUE}N/A
+STR_01A5_COST_TO_CLEAR :{BLACK}TroÅ¡kovi Äišćenja: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :NIJE DOSTUPNO
+STR_01A7_OWNER :{BLACK}Vlasnik: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}PodruÄna nadležnost: {LTBLUE}{STRING}
+STR_01A9_NONE :Nijedan/Nitko/Ništa
+STR_01AA_NAME :{BLACK}Ime
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1.
+STR_01AD_2ND :2.
+STR_01AE_3RD :3.
+STR_01AF_4TH :4.
+STR_01B0_5TH :5.
+STR_01B1_6TH :6.
+STR_01B2_7TH :7.
+STR_01B3_8TH :8.
+STR_01B4_9TH :9.
+STR_01B5_10TH :10.
+STR_01B6_11TH :11.
+STR_01B7_12TH :12.
+STR_01B8_13TH :13.
+STR_01B9_14TH :14.
+STR_01BA_15TH :15.
+STR_01BB_16TH :16.
+STR_01BC_17TH :17.
+STR_01BD_18TH :18.
+STR_01BE_19TH :19.
+STR_01BF_20TH :20.
+STR_01C0_21ST :21.
+STR_01C1_22ND :22.
+STR_01C2_23RD :23.
+STR_01C3_24TH :24.
+STR_01C4_25TH :25.
+STR_01C5_26TH :26.
+STR_01C6_27TH :27.
+STR_01C7_28TH :28.
+STR_01C8_29TH :29.
+STR_01C9_30TH :30.
+STR_01CA_31ST :31.
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Prihvaćeni teret: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Jazz Jukebox
+STR_01D3_SOUND_MUSIC :Zvuk/glazba
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Prikaži prozor zvuk/glazba
+STR_01D5_ALL :{TINYFONT}Sve
+STR_01D6_OLD_STYLE :{TINYFONT}Staromodno
+STR_01D7_NEW_STYLE :{TINYFONT}Moderno
+STR_01D8_EZY_STREET :{TINYFONT}Laganica
+STR_01D9_CUSTOM_1 :{TINYFONT}Proizvoljno 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Proizvoljno 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Glasnoća glazbe
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Glasnoća efekata
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MIN ' ' ' ' ' ' MAX
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Prethodna traka
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Sljedeća traka
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Zaustavi glazbu
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Pokreni glazbu
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Povuci pomiÄnike za namjeÅ¡tanje glasnoće glazbe i zvukova
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Traka{SETX 88}Naslov
+STR_01E9_SHUFFLE :{TINYFONT}SluÄajnim redosljedom
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Program
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Izbor glazbenog programa
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Popis traka
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Program- '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}Prazno
+STR_01F1_SAVE :{TINYFONT}{BLACK}Spremi
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Aktivni glazbeni program
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Odaberi program 'sve trake'
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Odaberi program 'staromodna glazba'
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Odaberi program 'moderna glazba'
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Odaberi program 'Proizvoljna glazba 1'
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Odaberi program 'Proizvoljna glazba 2'
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Obriši aktivni program (samo Proizvoljno 1 ili Proizvoljno 2)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Spremi glazbene postavke
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Klikni na glazbenu traku za dodavanje u aktivni program (samo Proizvoljno 1 ili Proizvoljno 2)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Promjeni sluÄajni redosljed ukluÄeno/iskljuÄeno
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Prikaži prozor za izbor glazbenih traka
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Poduzetnik
+STR_0219_TYCOON_OF_THE_CENTURY :Tajkun stoljeća
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} postigao je '{STRING}' status!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} iz {COMPANY} postigao je '{STRING}' status!
+STR_021F :{BLUE}{COMMA}
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Tvornica gaziranih pića
+STR_025F_BUBBLE_GENERATOR :{BLACK}Generator balona
+STR_0260_TOFFEE_QUARRY :{BLACK}Iskop mlijeÄne karamele
+STR_0261_SUGAR_MINE :{BLACK}Rudnik šećera
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Izgradi rudnik ugljena
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Izgradi elektranu
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Izgradi pilanu
+STR_0265_PLANT_FOREST :{BLACK}Posadi Å¡umu
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Izgradi naftnu rafineriju
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Izgradi naftnu bušotinu (može biti sagrađena samo blizu rubova karte)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Izgradi tvornicu
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Izgradi ÄeliÄanu
+STR_026A_CONSTRUCT_FARM :{BLACK}Izgradi farmu
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Izgradi rudnik bakra
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Izgradi naftna polja
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Izgradi banku (može biti izgrađena samo u gradovima s brojem stanovnika većim od 1200)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Izgradi tvornicu papira
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Izgradi tvornicu hrane
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Izgradi tiskaru
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Izgradi rudnik zlata
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Izgradi banku (može biti izgrađena samo u gradovima)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Posadi plantažu voća
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Posadi plantažu gume
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Izgradi vodotoranj (može biti izgrađen samo u gradovima)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Izgradi rudnik dijamanata
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Izgradi tvornicu slatkiša
+STR_0285_CAN_T_BUILD_HERE :{WHITE}Ne možeš graditi {STRING} ovdje...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...moraš prvo izgraditi grad
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...dozvoljen samo jedan po gradu
+STR_0288_PLANT_TREES :{BLACK}Posadi drveće
+STR_0289_PLACE_SIGN :{BLACK}Stavi znak
+STR_028A_RANDOM_TREES :{BLACK}NasumiÄno odabrano drveće
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Postavi svjetionik
+STR_028E_PLACE_TRANSMITTER :{BLACK}Postavi odaÅ¡iljaÄ
+STR_0290_DELETE :{BLACK}Obriši
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Obriši ovaj grad u cjelosti
+STR_0292_SAVE_SCENARIO :Spremi scenarij
+STR_0293_LOAD_SCENARIO :UÄitaj secenarij
+STR_0295 :
+STR_0296_QUIT :Završi
+STR_0298_LOAD_SCENARIO :{WHITE}UÄitaj scenarij
+STR_0299_SAVE_SCENARIO :{WHITE}Spremi scenarij
+STR_029A_PLAY_SCENARIO :{BLACK}Igraj scenarij
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Pomakni poÄetni datum 1 godinu unatrag
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Pomakni poÄetni datum 1 godinu unaprijed
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...oba kraja mosta moraju biti na zemlji
+STR_02A1_SMALL :{BLACK}Malo
+STR_02A2_MEDIUM :{BLACK}Srednje
+STR_02A3_LARGE :{BLACK}Veliko
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Izaberi veliÄinu grada
+STR_02A5_TOWN_SIZE :{YELLOW}VeliÄina grada:
+
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Prikaži posljednu poruku ili novinski izvještaj
+STR_OFF :IskljuÄeno
+STR_SUMMARY :Sažetak
+STR_FULL :Puno
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Popis gradova
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Inicijalno
+STR_02BF_CUSTOM :Prilagođeno
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Spremi prilagođena imena
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Opcije igre
+STR_02C5_DIFFICULTY_SETTINGS :Postavke težine
+STR_02C7_CONFIG_PATCHES :Konfiguriraj zakrpe
+STR_GAMEOPTMENU_0A :
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Podatci o zemljištu
+STR_02D6 :
+STR_02D7_SCREENSHOT_CTRL_S :Slika ekrana (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Ogromna slika ekrana(Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :O 'OpenTTD'
+############ range ends here
+
+STR_02DB_OFF :{BLACK}IskljuÄeno
+STR_02DA_ON :{BLACK}UkljuÄeno
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Prikaži subvencije
+STR_02DD_SUBSIDIES :Subvencije
+STR_02DE_MAP_OF_WORLD :Karta svijeta
+STR_SIGN_LIST :Popis znakova
+STR_02DF_TOWN_DIRECTORY :Direktorij gradova
+STR_TOWN_POPULATION :{BLACK}Svjetska populacija: {COMMA}
+
+STR_02E0_CURRENCY_UNITS :{BLACK}NovÄane jedinice
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Odabir novÄanih jedinica
+STR_MEASURING_UNITS :{BLACK}Mjerne jedinice
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Odabir mjernih jedinica
+STR_02E6_ROAD_VEHICLES :{BLACK}Cestovna vozila
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Izaberi na kojoj će strani ceste vozila prometovati
+STR_02E9_DRIVE_ON_LEFT :Vozi na lijevoj strani
+STR_02EA_DRIVE_ON_RIGHT :Vozi na desnoj strani
+STR_02EB_TOWN_NAMES :{BLACK}Imena gradova
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Izaberi stil za imena gradova
+
+STR_02F4_AUTOSAVE :{BLACK}Automatsko spremanje
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Odaberi interval između automatskih spremanja igre
+STR_02F7_OFF :IskljuÄeno
+STR_02F8_EVERY_3_MONTHS :Svaka 3 mjeseca
+STR_02F9_EVERY_6_MONTHS :Svakih 6 mjeseci
+STR_02FA_EVERY_12_MONTHS :Svakih 12 mjeseci
+STR_02FB_START_A_NEW_GAME :{BLACK}ZapoÄni novu igru
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}UÄitaj spremljenu igru
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Kreiraj prilagoÄ‘eni igraÄki svijet/scenarij
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Odaberi igru za jednog igraÄa
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Odaberi igru za 2-8 igraÄa
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Prikaži opcije igre
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Prikaži opcije težine
+STR_0303_START_A_NEW_GAME_USING :{BLACK}ZapoÄni novu igru koristeći prilagoÄ‘eni scenarij
+STR_0304_QUIT :{BLACK}Odustani
+STR_0305_QUIT_OPENTTD :{BLACK}Odustani od 'OpenTTD'
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...može biti izgrađen samo u gradovima
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Odaberi 'umjeren' stil krajolika
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Odaberi 'subarktiÄki' stil krajolika
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Odaberi 'subtropski' stil krajolika
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Odaberi 'zemlju igraÄka' stil krajolika
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Financiraj konstrukciju nove industrije
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Lista gospodarstava
+STR_0313_FUND_NEW_INDUSTRY :Financiraj novo gospodarstvo
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Financiraj novu industriju
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...može biti izgrađen samo u gradovima
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...može biti izgrađen samo u predjelima kišnih šuma
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...može biti izgraÄ‘en samo u pustinjskim podruÄjima
+STR_0319_PAUSED :{YELLOW}* * PAUZA * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Slika ekrana uspješno spremljena kao '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}Slika ekrana nije uspjela!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Kupi zemlju za buduću uporabu
+STR_032F_AUTOSAVE :{RED}AUTOMATSKO SPREMANJE
+STR_SAVING_GAME :{RED}* * SAVING GAME * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}Spremanje joÅ¡ u tijeku,{}molimo priÄekajte dok se ne zavrÅ¡i!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Izaberi glazbeni program 'Ezy Street style'
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :Engleski (original)
+STR_TOWNNAME_FRENCH :Francuski
+STR_TOWNNAME_GERMAN :NjemaÄki
+STR_TOWNNAME_ADDITIONAL_ENGLISH :Engleski (dodatno)
+STR_TOWNNAME_LATIN_AMERICAN :LatinoameriÄki
+STR_TOWNNAME_SILLY :Blesavo
+STR_TOWNNAME_SWEDISH :Å vedski
+STR_TOWNNAME_DUTCH :Nizozemski
+STR_TOWNNAME_FINNISH :Finski
+STR_TOWNNAME_POLISH :Poljski
+STR_TOWNNAME_SLOVAKISH :SlovaÄki
+STR_TOWNNAME_NORWEGIAN :Norveški
+STR_TOWNNAME_HUNGARIAN :Mađarski
+STR_TOWNNAME_AUSTRIAN :Austrijski
+STR_TOWNNAME_ROMANIAN :Rumunjski
+STR_TOWNNAME_CZECH :Češki
+STR_TOWNNAME_SWISS :Å vicarski
+STR_TOWNNAME_DANISH :Danski
+STR_TOWNNAME_TURKISH :Turski
+STR_TOWNNAME_ITALIAN :Talijanski
+STR_TOWNNAME_CATALAN :Katalonski
+############ end of townname region
+
+STR_CURR_GBP :Funte (£)
+STR_CURR_USD :Dolari ($)
+STR_CURR_EUR :Euri (€)
+STR_CURR_YEN :Jeni (Â¥)
+STR_CURR_ATS :Austrijski Å¡iling (ATS)
+STR_CURR_BEF :Belgijski franak (BEF)
+STR_CURR_CHF :Å vicarski franak (CHF)
+STR_CURR_CZK :Češka kruna (CZK)
+STR_CURR_DEM :NjemaÄka marka (DEM)
+STR_CURR_DKK :Danska kruna (DKK)
+STR_CURR_ESP :Pezeta (ESP)
+STR_CURR_FIM :Finska marka (FIM)
+STR_CURR_FRF :Franak (FRF)
+STR_CURR_GRD :GrÄka drahma (GRD)
+STR_CURR_HUF :Mađarski forint (HUF)
+STR_CURR_ISK :Islandska kruna (ISK)
+STR_CURR_ITL :Talijanska lira (ITL)
+STR_CURR_NLG :Nizozemski gulden (NLG)
+STR_CURR_NOK :Norveška kruna (NOK)
+STR_CURR_PLN :Poljski zloti (PLN)
+STR_CURR_ROL :Rumunjski lev (ROL)
+STR_CURR_RUR :Ruske rublje (RUR)
+STR_CURR_SIT :Slovenski tolar (SIT)
+STR_CURR_SEK :Å vedska kruna (SEK)
+STR_CURR_YTL :Turska lira(YTL)
+STR_CURR_SKK :SlovaÄka kruna (SKK)
+STR_CURR_BRR :Brazilski real (BRL)
+
+STR_CURR_CUSTOM :Proizvoljno...
+
+STR_OPTIONS_LANG :{BLACK}Jezik
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Izaberi jeziÄno suÄelje
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Cijeli ekran
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}OznaÄi ovu kućicu kako bi igrao OpenTTD preko cijelog ekrana
+
+STR_OPTIONS_RES :{BLACK}RazluÄivost ekrana
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Izaberi rezoluciju ekrana
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Format za sliku ekrana
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Izaberi format za sliku ekrana
+
+STR_AUTOSAVE_1_MONTH :Svaki mjesec
+STR_AUTOSAVE_FAILED :{WHITE}Automatsko spremanje neuspješno
+
+STR_MONTH_JAN :SijeÄanj
+STR_MONTH_FEB :VeljaÄa
+STR_MONTH_MAR :Ožujak
+STR_MONTH_APR :Travanj
+STR_MONTH_MAY :Svibanj
+STR_MONTH_JUN :Lipanj
+STR_MONTH_JUL :Srpanj
+STR_MONTH_AUG :Kolovoz
+STR_MONTH_SEP :Rujan
+STR_MONTH_OCT :Listopad
+STR_MONTH_NOV :Studeni
+STR_MONTH_DEC :Prosinac
+
+STR_HEADING_FOR_STATION :{LTBLUE}Kreće se prema {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}Kreće se prema {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Nema narudžbi
+STR_NO_ORDERS_VEL :{LTBLUE}Nema narudžbi, {VELOCITY}
+
+STR_PASSENGERS :putnici
+STR_BAGS :vreće
+STR_TONS :tone
+STR_LITERS :litre
+STR_ITEMS :jedinice
+STR_CRATES :sanduci
+STR_RES_OTHER :ostalo
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+# end of order system
+
+
+
+
+
+
+
+
+
+
+
+
+
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Vozila
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Stanice
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Ekonomija
+STR_CONFIG_PATCHES_AI :{BLACK}Konkurenti
+
+STR_CONFIG_PATCHES_DISABLED :onemogućeno
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}Stavi drveće nasumiÄnog tipa
+
+STR_CANT_BUILD_CANALS :{WHITE}Ovdje ne možeš graditi kanale...
+STR_BUILD_CANALS_TIP :{BLACK}Izgradi kanale. Pritisni CTRL kako bi smjestio vodone ploÄice (samo na razini mora).
+STR_LANDINFO_CANAL :Kanal
+
+
+STR_BUOY_IS_IN_USE :{WHITE}...plutaÄa je u uporabi!
+
+STR_LANDINFO_COORDS :{BLACK}Koordinate: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Ne možeš ukloniti dio stanice...
+
+
+
+STR_FAST_FORWARD :{BLACK}Premotaj igru naprijed
+STR_MESSAGE_HISTORY :{WHITE}Povijest poruka
+STR_MESSAGE_HISTORY_TIP :{BLACK}Popis nedavnih novinskih poruka
+STR_MESSAGES_DISABLE_ALL :{BLACK}Onemogući sve
+STR_MESSAGES_ENABLE_ALL :{BLACK}Omogući sve
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Izgradi rudnik ugljena
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Posadi Å¡umu
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Izgradi naftnu bušotinu
+STR_CONSTRUCT_FARM_TIP :{BLACK}Financiraj farmu
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Izgradi rudnik bakra
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Bušenjem traži naftu
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Izgradi rudnik zlata
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Izgradi rudnik dijamanata
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Izgradi rudnik željeza
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Financiraj plantažu voća
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Financiraj plantažu gume
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Financiraj izvor vode
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Posadi šumu šećerne vune
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}Financiraj tvornicu baterija
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}Bušenjem traži Colu
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Financiraj izvore plastike
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Izgradi generator balona
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Financiraj kamenolom mlijeÄne karamele
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Izgradi šećeranu
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Gospodarstva
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA}% prevezeno)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA}%/{COMMA}% prevezeno)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}...preblizu drugom gospodarstvu
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Prepravi vlak kako bi nosio drugu vrstu tereta
+STR_RAIL_REFIT_VEHICLE :{BLACK}Prepravi vlak
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Izaberi vrstu tereta koju će vlak nositi
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Prepravi vlak kako bi nosio oznaÄenu vrstu tereta
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Ne možeš prepraviti vlak...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Servisni intervali u postotcima: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Promijeni proizvodnju
+
+TEMP_AI_IN_PROGRESS :{WHITE}Dobrodošli u novi AI pod razvojem. Ukoliko naiđete na probleme, napravite sliku ekrana i stavite ju na forum.
+TEMP_AI_ACTIVATED :{WHITE}Upozorenje: ovaj novi AI je još uvijek alfa! Trenutno, samo kamioni i autobusi rade!
+TEMP_AI_MULTIPLAYER :{WHITE}Upozorenje: implementacije je još uvijek pokusna (koristeći novi AI). Molimo prijavite bilo kakav problem na truelight@openttd.org
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}ViÅ¡e igraÄa
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Ime igraÄa:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}Ovo je ime po kojem će te drugi igraÄi identificirati
+STR_NETWORK_CONNECTION :{BLACK}Veza:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Izaberi između internetske igre ili igre preko lokalne mreže (LAN)
+
+STR_NETWORK_START_SERVER :{BLACK}Pokreni poslužitelj
+STR_NETWORK_START_SERVER_TIP :{BLACK}Pokreni vlastiti poslužitelj
+
+STR_NETWORK_GAME_NAME :{BLACK}Ime
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Ime igre
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Jezik, verzija poslužitelja, itd.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Klikni na igru s liste kako bi ju izabrao
+
+STR_NETWORK_FIND_SERVER :{BLACK}Pronađi poslužitelj
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Pronađi poslužitelje u mreži
+STR_NETWORK_ADD_SERVER :{BLACK}Dodaj poslužitelj
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Dodaje poslužitelj na popis koji će uvijek biti provjeren postoje li igre u tijeku.
+STR_NETWORK_ENTER_IP :{BLACK}Unesi adresu domaćina
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Klijenti
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Klijenata online / klijenata maks{}Tvrki online / tvrki maks
+STR_NETWORK_GAME_INFO :{SILVER}INFO O IGRI
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Klijenti: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Jezik: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Set ploÄica: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}VeliÄina karte: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}Verzija poslužitelja: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}Adresa poslužitelja: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Datum poÄetka: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Trenutni datum: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Zaštićeno zaporkom!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}POSLUŽITELJ NEDOSTUPAN
+STR_NETWORK_SERVER_FULL :{SILVER}POSLUŽITELJ PUN
+STR_NETWORK_VERSION_MISMATCH :{SILVER}RAZLIKA U VERZIJAMA
+
+STR_NETWORK_JOIN_GAME :{BLACK}Pridruži se igri
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}ZapoÄni novu igru za viÅ¡e igraÄa
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Ime igre:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}Ime igre bit će prikazno drugim igraÄima u izborniku za odabir igre s viÅ¡e igraÄa
+STR_NETWORK_SET_PASSWORD :{BLACK}Postavi zaporku
+STR_NETWORK_PASSWORD_TIP :{BLACK}Zaštiti svoju igru pomoću zaporke ukoliko ne želiš da bude javno dostupna
+STR_NETWORK_SELECT_MAP :{BLACK}Izaberi kartu:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}Koju kartu želiš igrati?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}Maks klijenata:
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Izaberi maksimalan broj klijenata. Ne moraju sva mjesta biti popunjena.
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :LAN
+STR_NETWORK_INTERNET :Internet
+STR_NETWORK_LAN_INTERNET :LAN / Internet
+STR_NETWORK_INTERNET_ADVERTISE :Internet (oglasi)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 igraÄa
+STR_NETWORK_1_PLAYERS :1 igraÄ
+STR_NETWORK_2_PLAYERS :2 igraÄa
+STR_NETWORK_3_PLAYERS :3 igraÄa
+STR_NETWORK_4_PLAYERS :4 igraÄa
+STR_NETWORK_5_PLAYERS :5 igraÄa
+STR_NETWORK_6_PLAYERS :6 igraÄa
+STR_NETWORK_7_PLAYERS :7 igraÄa
+STR_NETWORK_8_PLAYERS :8 igraÄa
+STR_NETWORK_9_PLAYERS :9 igraÄa
+STR_NETWORK_10_PLAYERS :10 igraÄa
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}Maks tvrki:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}OgraniÄi poslužitelj na odreÄ‘eni broj tvrtki
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}Maks promatraÄa:
+
+############ Leave those lines in this order!!
+############ End of leave-in-this-order
+
+
+
+
+
+
+
+############ Leave those lines in this order!!
+
+############ End of leave-in-this-order
+
+
+
+
+############ Leave those lines in this order!!
+############ End of leave-in-this-order
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE} Poslužitelj je zatvorio sesiju
+STR_NETWORK_SERVER_REBOOT :{WHITE} Poslužitelj se ponovno pokreće...{}Molimo priÄekajte...
+
+STR_NETWORK_SERVER :Poslužitelj
+STR_NETWORK_CLIENT :Klijent
+STR_NETWORK_SPECTATORS :PromatraÄi
+
+STR_NETWORK_CLIENTLIST_NONE :(nitko)
+STR_NETWORK_CLIENTLIST_KICK :Izbaci
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Daj novac
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Razgovaraj sa svima
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Razgovaraj s tvrtkom
+
+
+
+############ end network gui strings
+
+
+
+
+##### PNG-MAP-Loader
+
+
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Trošak: {CURRENCY}
+STR_0801_COST :{RED}Trošak: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Prihod: {CURRENCY}
+STR_0803_INCOME :{GREEN}Prihod: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Predviđeni trošak: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Predviđeni prihod: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Ne možeš povisiti zemlju ovdje...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Ne možeš sniziti zemlju ovdje...
+STR_080A_ROCKS :Stijenje
+STR_080B_ROUGH_LAND :Surova zemlja
+STR_080C_BARE_LAND :Ogoljena zemlja
+STR_080D_GRASS :Trava
+STR_080E_FIELDS :Polja
+STR_080F_SNOW_COVERED_LAND :Zemlja pokrivena snijegom
+STR_0810_DESERT :Pustinja
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Zemlja nakošena u krivom smjeru
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Nemoguća kombinacija traÄnica
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}Iskopavanja bi oštetila tunel
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Već je na razini mora
+STR_1004_TOO_HIGH :{WHITE}Previsoko
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Nije prikladno za želježnicke traÄnice
+STR_1007_ALREADY_BUILT :{WHITE}...već izgrađeno
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}MoraÅ¡ ukloniti prvo željezniÄke traÄnice
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}ŽeljezniÄka konstrukcija
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}JednotraÄna konstrukcija
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}MagLev konstrukcija
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Ne možeš postaviti znakove ovdje...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Ne možeÅ¡ graditi traÄnice ovdje...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Ne možeÅ¡ ukloniti traÄnice odavdje...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Ne možeš maknuti signale odavdje...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Smjer spremišta vlakova
+STR_1015_RAILROAD_CONSTRUCTION :Izgradnja željezniÄke pruge
+STR_TOOLB_ELRAIL_CONSTRUCTION :Izgradnja elektriÄne željezniÄke pruge
+STR_1016_MONORAIL_CONSTRUCTION :Izgradnja Monoraila
+STR_1017_MAGLEV_CONSTRUCTION :Izgradnja MagLeva
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Izgradi željezniÄke traÄnice
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Izgradi spremište vlakova (za gradnju i servisiranje vlakova)
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Izgradi željezniÄki tunel
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Odaberi smjer željezniÄkog spremiÅ¡ta
+STR_1021_RAILROAD_TRACK :ŽeljezniÄke traÄnice
+STR_1023_RAILROAD_TRAIN_DEPOT :Spremište vlakova
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...podruÄje je u vlasniÅ¡tvu druge tvrke
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :ŽeljezniÄke traÄnice s normalnim znakovima
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :ŽeljezniÄke traÄnice s prethodno postavljenim znakovima
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :ŽeljezniÄke traÄnice s izlaznim znakovima
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :ŽeljezniÄke traÄnice s kombo znakovima
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Moraš prvo ukloniti cestu
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Cestovni radovi u tijeku
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Rekonstrukcija ceste
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Izaberi cestovni most
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Ne možeš graditi cestu ovdje...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Ne možep maknuti cestu odavdje...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Smjer cestovnog spremišta
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Ne možeš izgraditi spremište cestovnih vozila ovdje...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Nije moguće izgraditi autobusnu stanicu...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Nije moguće izgraditi kamionski terminal...
+STR_180A_ROAD_CONSTRUCTION :Rekonstrukcija ceste
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Izgradi dio ceste
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Izgradi spremište cestovnih vozila (za izgradnju i servisiranje vozila)
+STR_180D_BUILD_BUS_STATION :{BLACK}Izgradi autobusnu stanicu
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Izgradi pretovarni kamionski terminal
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Izgradi cestovni most
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Izgradi cestovni tunel
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Izaberi smjer spremišta cestovnih vozila
+STR_1814_ROAD :Cesta
+STR_1815_ROAD_WITH_STREETLIGHTS :Cesta sa semaforima
+STR_1817_ROAD_VEHICLE_DEPOT :Spremište cestovnih vozila
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Gradovi
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Građevina mora prvo biti srušena
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}Stanovništvo: {ORANGE}{COMMA}{BLACK} Kuće: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Preimenuj grad
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Grad se ne može preimenovati...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} lokalna samouprava odbija dozvoliti ovo
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Imena gradova - klikni na ime kako bi centrirao pogled na ekran
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centriraj glavni pogled na lokaciju grada
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Promijeni ime grada
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Putnika prošli mjesec: {ORANGE}{COMMA}{BLACK} maks: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Pošte prošli mjesec: {ORANGE}{COMMA}{BLACK} maks: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Visoki uredski blok
+STR_2010_OFFICE_BLOCK :Uredski blok
+STR_2011_SMALL_BLOCK_OF_FLATS :Mali stambeni blok
+STR_2012_CHURCH :Crkva
+STR_2013_LARGE_OFFICE_BLOCK :Veliki uredski blok
+STR_2014_TOWN_HOUSES :Gradske kuće
+STR_2015_HOTEL :Hotel
+STR_2016_STATUE :Kip
+STR_2017_FOUNTAIN :Fontana
+STR_2018_PARK :Park
+STR_2019_OFFICE_BLOCK :Uredski blok
+STR_201A_SHOPS_AND_OFFICES :Trgovine i uredi
+STR_201B_MODERN_OFFICE_BUILDING :Moderne uredske zgrade
+STR_201C_WAREHOUSE :Skladište
+STR_201D_OFFICE_BLOCK :Uredski blok
+STR_201E_STADIUM :Stadion
+STR_201F_OLD_HOUSES :Stare kuće
+STR_2020_LOCAL_AUTHORITY :{BLACK}Lokalna samouprava
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Prikaži informacije o lokalnoj samoupravi
+STR_2022_LOCAL_AUTHORITY :{WHITE}{TOWN} lokalna samouprava
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Ocjene prijevoznih tvrtki:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Subvencije
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Ponuđene subvencije za pružanje usluga:
+STR_2027_FROM_TO :{ORANGE}{STRING} od {STRING} do {STRING}
+STR_2028_BY :{YELLOW} (do {DATE_SHORT})
+STR_202A_NONE :{ORANGE}Ništa
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Usluge već subvencionirane:
+STR_202C_FROM_TO :{ORANGE}{STRING} iz {STATION} prema {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, do {DATE_SHORT})
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} lokalne vlasti odbijaju dozvoliti izgradnju joÅ¡ jedne zraÄne luke u ovom gradu
+STR_2036_COTTAGES :Kolibe
+STR_2037_HOUSES :Kuće
+STR_2038_FLATS :Stanovi
+STR_2039_TALL_OFFICE_BLOCK :Visoki uredski blok
+STR_203A_SHOPS_AND_OFFICES :Trgovine i uredi
+STR_203B_SHOPS_AND_OFFICES :Trgovine i uredi
+STR_203C_THEATER :Kazalište
+STR_203D_STADIUM :Stadion
+STR_203E_OFFICES :Uredi
+STR_203F_HOUSES :Kuće
+STR_2040_CINEMA :Kino
+STR_2041_SHOPPING_MALL :TrgovaÄki centar
+STR_2042_DO_IT :{BLACK}UÄini to
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}Popis stvari koje treba uÄiniti u ovom gradu - klikni za dodatne informacije
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}IzvrÅ¡i oznaÄene akcije na listi iznad
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Dostupne akcije:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Mala oglasna kampanja
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Srednja oglasna kampanja
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Velika oglasna kampanja
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Financiraj rekonstrukciju lokalne prometnice
+STR_204A_BUILD_STATUE_OF_COMPANY :Izgradi kip vlasnika tvrke
+STR_204B_FUND_NEW_BUILDINGS :Financiraj nove građevine
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Kupi ekskluzivna prijevozna prava
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Podmiti lokalnu samoupravu
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Iniciraj malu oglasnu kampanju, kako bi privukao više putnika i tereta za svoje prijevozne usluge.{} Trošak: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Iniciraj srednju oglasnu kampanju, kako bi privukao više putnika i tereta za svoje prijevozne usluge.{} Trošak: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Iniciraj veliku oglasnu kampanju, kako bi privukao više putnika i tereta za svoje prijevozne usluge.{} Trošak: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} Financiraj rekonstrukciju urbane mreže prometnica. Uzrokuje znaÄajne poremećaje u cestovnom prometu do 6 mjeseci.{} TroÅ¡ak: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Izgradi kip u Äast svoje tvrke.{} TroÅ¡ak: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Financiraj izgradnju novih poslovnih prostora u gradu.{} Trošak: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Kupi jednogodišnje ekskluzivno prijevozno pravo u gradu. Gradska vlast će dopustiti putnicima i teretu da koriste samo stanice tvoje tvrtke.{} Trošak: {CURRENCY}
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (pod rekonstrukcijom)
+STR_2059_IGLOO :Iglu
+STR_205A_TEPEES :Indijanski Å¡ator
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN} {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_2800_PLANT_TREES :Posadi drveće
+STR_2801_PLACE_SIGN :Postavi znak
+STR_2802_TREES :{WHITE}Drveće
+STR_2803_TREE_ALREADY_HERE :{WHITE}...ovdje je već drvo
+STR_2804_SITE_UNSUITABLE :{WHITE}...mjesto neprikladno
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Ne možeš posaditi drvo ovdje...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...previše znakova
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Ne možeš postaviti znak ovdje...
+STR_280A_SIGN :Znak
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Uredi tekst znaka
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Ne možeš promijeniti ime znaka
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Izaberi vrstu drveta za sadnju
+STR_280E_TREES :Drveće
+STR_280F_RAINFOREST :Kišna šuma
+STR_2810_CACTUS_PLANTS :Kaktusi
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Odabir željezniÄke stanice
+STR_3001_AIRPORT_SELECTION :{WHITE}Odabir zraÄne luke
+STR_3002_ORIENTATION :{BLACK}Smjer
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Broj traÄnica
+STR_3004_PLATFORM_LENGTH :{BLACK}Dužina platforme
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Preblizu drugoj željezniÄkoj stanici
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Previše autobusnih stanica
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}Previše kamionskih stanica
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Preblizu drugoj zraÄnoj luci
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}MoraÅ¡ uniÅ¡titi zraÄnu luku prvo
+
+STR_3030_RENAME_STATION_LOADING :Preimenuj stanicu/terminal
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Ne možeš preimenovati stanicu...
+STR_3032_RATINGS :{BLACK}Ocjene
+STR_3033_ACCEPTS :{BLACK}Prihvaća
+
+############ range for rating starts
+STR_3035_APPALLING :Užasno
+STR_3036_VERY_POOR :Vrlo loše
+STR_3037_POOR :Loše
+STR_3038_MEDIOCRE :Osrednje
+STR_3039_GOOD :Dobro
+STR_303A_VERY_GOOD :Vrlo dobro
+STR_303B_EXCELLENT :Izvrsno
+STR_303C_OUTSTANDING :Izvanredno
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} više ne prihvaća {STRING}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} više ne prihvaća {STRING} or {STRING}
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} sad prihvaća {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} od sada prihvaća {STRING} i {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Smjer autobusne stanice
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Smjer kamionskog terminala
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Moraš uništiti autobusnu stanicu prvo
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Moraš uništiti kamionski terminal prvo
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Ništa -
+STR_304B_SITE_UNSUITABLE :{WHITE}...mjesto neprikladno
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Preblizu drugom pristaništu
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Prvo moraš srušiti pristanište
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Izaberi smjer željezniÄke stanice
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Izaberi broj platformi na željezniÄkoj stanici
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Izaberi dužinu željezniÄke stanice
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Izaberi smjer autobusne stanice
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Izaberi smjer kamionskog terminala
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Centriraj glavni pogled na lokaciju stanice
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Pokazi ocjene stanice
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Promijeni ime stanice
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Prikaži popis prihvaćenog tereta
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Imena stanica - klikni na ime kako bi centrirao glavni pogled na stanicu
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Izaberi veliÄinu/tip zraÄne luke
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :ŽeljezniÄka stanica
+STR_305F_AIRCRAFT_HANGAR :Zrakoplovni hangar
+STR_3060_AIRPORT :ZraÄna luka
+STR_3061_TRUCK_LOADING_AREA :Ukrcajno podruÄje
+STR_3062_BUS_STATION :Autobusna stanica
+STR_3063_SHIP_DOCK :Brodsko pristanište
+STR_3068_DOCK :{WHITE}Pristanište
+STR_3069_BUOY :PlutaÄa
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...plutaÄa na putu
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...stanica previše proširena
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...neuniformne stanice zabranjene
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Drži CTRL kako bi izabrao više od jednog itema
+
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Smjer brodskog spremišta
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...mora biti izgrađen na vodi
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Ne možeš graditi brodsko spremište ovdje...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Izaberi smjer brodsko spremišta
+STR_3804_WATER :Voda
+STR_3805_COAST_OR_RIVERBANK :Obala ili rijeÄni nasip
+STR_3806_SHIP_DEPOT :Brodsko spremište
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...Ne možeš graditi na vodi
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Spremi igru
+STR_4001_LOAD_GAME :{WHITE}UÄitaj igru
+STR_4002_SAVE :{BLACK}Spremi
+STR_4003_DELETE :{BLACK}Obriši
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Ne mogu proÄitati disk
+STR_4007_GAME_SAVE_FAILED :{WHITE}Spremanje igre nije uspjelo
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Ne mogu obrisati datoteku
+STR_4009_GAME_LOAD_FAILED :{WHITE}UÄitavanje igre nije uspjelo
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}Popis diskova, mapa i spremljenih datoteka
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Trenutno odabrano ime za spremanje igre
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Obriši trenutno odabranu spremljenu igru
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Spremi ovu igru, koristeći odabrano ime
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Odaberi vrstu nove igre
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Odaberi scenarij (zeleno), namjeÅ¡tenu igru (plavo), ili nasumiÄnu novu igru
+STR_4010_GENERATE_RANDOM_NEW_GAME :Generiraj nasumiÄnu novu igru
+STR_4011_LOAD_HEIGHTMAP :{WHITE}UÄitaj visinsku kartu
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} na putu
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :Rudnik ugljena
+STR_4803_POWER_STATION :Elektrana
+STR_4804_SAWMILL :Pilana
+STR_4805_FOREST :Å uma
+STR_4806_OIL_REFINERY :Naftna rafinerija
+STR_4807_OIL_RIG :Naftna bušotina
+STR_4808_FACTORY :Tvornica
+STR_4809_PRINTING_WORKS :Tiskara
+STR_480A_STEEL_MILL :ÄŒeliÄana
+STR_480B_FARM :Farma
+STR_480C_COPPER_ORE_MINE :Rudnik bakra
+STR_480D_OIL_WELLS :Naftna polja
+STR_480E_BANK :Banka
+STR_480F_FOOD_PROCESSING_PLANT :Tvornica hrane
+STR_4810_PAPER_MILL :Tvornica papira
+STR_4811_GOLD_MINE :Rudnik zlata
+STR_4812_BANK :Banka
+STR_4813_DIAMOND_MINE :Rudnik dijamanata
+STR_4814_IRON_ORE_MINE :Rudnik željeza
+STR_4815_FRUIT_PLANTATION :Plantaža voća
+STR_4816_RUBBER_PLANTATION :Plantaža gume
+STR_4817_WATER_SUPPLY :Izvor vode
+STR_4818_WATER_TOWER :Vodotoranj
+STR_4819_FACTORY :Tvornica
+STR_481A_FARM :Farma
+STR_481B_LUMBER_MILL :Pilana
+STR_481C_COTTON_CANDY_FOREST :Šuma šećerne vune
+STR_481D_CANDY_FACTORY :Tvornica slatkiša
+STR_481E_BATTERY_FARM :Tvornica baterija
+STR_481F_COLA_WELLS :Izvori Cole
+STR_4820_TOY_SHOP :Trgovina igraÄkama
+STR_4821_TOY_FACTORY :Tvornica igraÄaka
+STR_4822_PLASTIC_FOUNTAINS :Izvorni plastike
+STR_4823_FIZZY_DRINK_FACTORY :Tvornica gaziranih pića
+STR_4824_BUBBLE_GENERATOR :Generator balona
+STR_4825_TOFFEE_QUARRY :Iskop mlijeÄne karamele
+STR_4826_SUGAR_MINE :Rudnik šećera
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Treba: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Treba: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Treba: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}ProÅ¡lomjeseÄna proizvodnja:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% prevezeno)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centriraj glavni pogled na lokaciju gospodarstva
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Nova {STRING} pod konstrukcijom blizu grada {TOWN}!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Nova {STRING} se trenutno sadi blizu grada {TOWN}!
+STR_482F_COST :{BLACK}Trošak: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Ne možeš konstruirati ovaj tip gospodarstva ovdje...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...šume mogu jedino biti posađene iznad linije snijega
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} objavljuje skoro zatvaranje!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}Nabavni problemi uzrokuju {INDUSTRY} da objavi skoro zatvaranje!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}Manjak drveća u blizini uzrokuje {INDUSTRY} da objavi skoro zatvaranje!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} povećava produkciju!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}Nova pukotina ugljena pronaÄ‘ena kod {INDUSTRY}!{}OÄekuje se udvostruÄenje proizvodnje!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}Nove rezerve nafte pronaÄ‘ene kod:{INDUSTRY}!{}OÄekuje se udvostruÄenje proizvodnje!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}PoboljÅ¡ane metode uzgoja u {INDUSTRY}, oÄekuje se udvostruÄenje proizvodnje!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}{INDUSTRY} proizvodnja pala za 50%
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}Najezda kukaca uzrokovala havariju kod {INDUSTRY}!{}Proizvodnja pala za 50%
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...može se postaviti samo blizu rubova karte
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Vlak u tunelu
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Cestovno vozilo u tunelu
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Smeta drugi tunel
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Ne mogu iskopoati zemlju na drugoj strani tunela
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Moraš prvo srušiti tunel
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Moraš prvo srušiti most
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}PoÄetak i kraj ne mogu biti na istom mjestu
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Ispod mosta mora biti ravna zemlja ili voda
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}PoÄetak i kraj moraju biti u istoj liniji
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Neprikladan teren za ulaz u tunel
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Viseći, ÄeliÄni
+STR_500F_GIRDER_STEEL :Noseći, ÄeliÄni
+STR_5010_CANTILEVER_STEEL :Konzolni, ÄeliÄni
+STR_5011_SUSPENSION_CONCRETE :Viseći, betonski
+STR_5012_WOODEN :Drveni
+STR_5013_CONCRETE :Betonski
+STR_5014_TUBULAR_STEEL :Cijevni, ÄeliÄni
+STR_BRIDGE_TUBULAR_SILICON :Cjevni, silikonski
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Ovdje se ne može graditi most...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Ovdje se ne može graditi tunel...
+STR_5017_RAILROAD_TUNNEL :ŽeljezniÄki tunel
+STR_5018_ROAD_TUNNEL :Cestovni tunel
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :ÄŒeliÄni viseći željezniÄki most
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :ÄŒeliÄni noseći željezniÄki most
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :ÄŒeliÄni konzolni željezniÄki most
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :OjaÄani betonski viseći željezniÄki most
+STR_501F_WOODEN_RAIL_BRIDGE :Drveni željezniÄki most
+STR_5020_CONCRETE_RAIL_BRIDGE :Betonski željezniÄki most
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :ÄŒeliÄni viseći cestovni most
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :ÄŒeliÄni noseći cestovni most
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :ÄŒeliÄni konzolni cestovni most
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :OjaÄani betonski viseći cestovni most
+STR_5025_WOODEN_ROAD_BRIDGE :Drveni cestovni most
+STR_5026_CONCRETE_ROAD_BRIDGE :Betonski cestovni most
+STR_5027_TUBULAR_RAIL_BRIDGE :Cijevni željezniÄki most
+STR_5028_TUBULAR_ROAD_BRIDGE :Cijevni cestovni most
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Smeta objekt
+STR_5801_TRANSMITTER :OdaÅ¡iljaÄ
+STR_5802_LIGHTHOUSE :Svjetionik
+STR_5803_COMPANY_HEADQUARTERS :Sjedište tvrke
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...smeta sjedište tvrke
+STR_5805_COMPANY_OWNED_LAND :Zemlja u posjedu tvrke
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Ova zemlja ne može se kupiti...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...već je u tvom vlasništvu!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Neimenovan
+STR_SV_TRAIN_NAME :Vlak {COMMA}
+STR_SV_ROADVEH_NAME :Cestovno vozilo {COMMA}
+STR_SV_SHIP_NAME :Brod {COMMA}
+STR_SV_AIRCRAFT_NAME :Zrakoplov {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :{STRING} Sjever
+STR_SV_STNAME_SOUTH :{STRING} Jug
+STR_SV_STNAME_EAST :{STRING} Istok
+STR_SV_STNAME_WEST :{STRING} Zapad
+STR_SV_STNAME_CENTRAL :{STRING} Centrala
+STR_SV_STNAME_TRANSFER :{STRING} Transfer
+STR_SV_STNAME_HALT :{STRING} Zaustav
+STR_SV_STNAME_VALLEY :{STRING} Dolina
+STR_SV_STNAME_HEIGHTS :{STRING} Visine
+STR_SV_STNAME_WOODS :{STRING} Å ume
+STR_SV_STNAME_LAKESIDE :{STRING} Jezero
+STR_SV_STNAME_EXCHANGE :{STRING} Burza
+STR_SV_STNAME_AIRPORT :{STRING} ZraÄna luka
+STR_SV_STNAME_OILFIELD :{STRING} Naftno polje
+STR_SV_STNAME_MINES :{STRING} Rudnici
+STR_SV_STNAME_DOCKS :{STRING} Pristaništa
+STR_SV_STNAME_BUOY_1 :{STRING} PlutaÄa 1
+STR_SV_STNAME_BUOY_2 :{STRING} PlutaÄa 2
+STR_SV_STNAME_BUOY_3 :{STRING} PlutaÄa 3
+STR_SV_STNAME_BUOY_4 :{STRING} PlutaÄa 4
+STR_SV_STNAME_BUOY_5 :{STRING} PlutaÄa 5
+STR_SV_STNAME_BUOY_6 :{STRING} PlutaÄa 6
+STR_SV_STNAME_BUOY_7 :{STRING} PlutaÄa 7
+STR_SV_STNAME_BUOY_8 :{STRING} PlutaÄa 8
+STR_SV_STNAME_BUOY_9 :{STRING} PlutaÄa 9
+STR_SV_STNAME_ANNEXE :{STRING} Aneks
+STR_SV_STNAME_SIDINGS :{STRING} Krak
+STR_SV_STNAME_BRANCH :{STRING} Ogranak
+STR_SV_STNAME_UPPER :Gornji {STRING}
+STR_SV_STNAME_LOWER :Donji {STRING}
+STR_SV_STNAME_HELIPORT :{STRING} Heliodrom
+STR_SV_STNAME_FOREST :{STRING} Å uma
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Težina igre
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Spremi
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Lagano
+STR_6802_MEDIUM :{BLACK}Umjereno
+STR_6803_HARD :{BLACK}Teško
+STR_6804_CUSTOM :{BLACK}Proizvoljna igra
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maksimalan broj natjecatelja: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Vrijeme poÄetka igre natjecatelja: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}Broj gradova: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}Broj gospodarstava: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Maksimalni poÄetni kredit: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}PoÄetna kamata kredita: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Troškovi uporabe vozila: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Brzina razvoja natjecatelja: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Inteligencija natjecatelja: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Kvarovi na vozilima: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Subvencijski množitelj: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Troškovi građenja: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Vrsta terena: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}KoliÄina mora/jezera: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Ekonomija: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Promjena smjera vlakova: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Prirodne katastrofe: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Stav gradsko vijeća prema restrukturiranju podruÄja: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :Ništa
+STR_6816_LOW :Nisko
+STR_6817_NORMAL :Normalno
+STR_6818_HIGH :Visoko
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Vrlo sporo
+STR_681C_SLOW :Sporo
+STR_681D_MEDIUM :Umjereno
+STR_681E_FAST :Brzo
+STR_681F_VERY_FAST :Vrlo brzo
+STR_VERY_LOW :Vrlo nisko
+STR_6820_LOW :Nisko
+STR_6821_MEDIUM :Umjereno
+STR_6822_HIGH :Visoko
+STR_6823_NONE :Ništa
+STR_6824_REDUCED :Smanjeno
+STR_6825_NORMAL :Normalno
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Vrlo ravno
+STR_682B_FLAT :Ravno
+STR_682C_HILLY :Brežuljkasto
+STR_682D_MOUNTAINOUS :Brdovito
+STR_682E_STEADY :Stabilno
+STR_682F_FLUCTUATING :Promjenjivo
+STR_6830_IMMEDIATE :Odmah
+STR_6831_3_MONTHS_AFTER_PLAYER :3 mjeseca nakon igraÄa
+STR_6832_6_MONTHS_AFTER_PLAYER :6 mjeseci nakon igraÄa
+STR_6833_9_MONTHS_AFTER_PLAYER :9 mjeseci nakon igraÄa
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :Na kraju pruge, i na stanici
+STR_6835_AT_END_OF_LINE_ONLY :IskljuÄivo na kraju pruge
+STR_6836_OFF :IskljuÄeno
+STR_6837_ON :UkljuÄeno
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Prikaz tablice najboljih rezultata
+STR_6839_PERMISSIVE :Dopustiv
+STR_683A_TOLERANT :Tolerantan
+STR_683B_HOSTILE :Agresivan
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(IgraÄ {COMMA})
+STR_7004_NEW_FACE :{BLACK}Novo lice
+STR_7005_COLOR_SCHEME :{BLACK}Boja
+STR_7006_COLOR_SCHEME :{GOLD}Boja:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Nova boja
+STR_7008_COMPANY_NAME :{BLACK}Ime tvrtke
+STR_7009_PRESIDENT_NAME :{BLACK}Ime direktora
+STR_700A_COMPANY_NAME :Ime tvrtke
+STR_700B_PRESIDENT_S_NAME :Ime direktora
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Ime tvrtke ne može se promijeniti...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Ne možeš promijeniti ime direktora...
+STR_700E_FINANCES :{WHITE}{COMPANY} Financije {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Izdatci/Prihodi
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Građenje
+STR_7012_NEW_VEHICLES :{GOLD}Nova vozila
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Troškovi uporabe vlakova
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Troškovi uporabe cestovnih vozila
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Troškovi uporabe zrakoplova
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Troškovi uporabe brodova
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Održavanje posjeda
+STR_7018_TRAIN_INCOME :{GOLD}Prihod od vlakova
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Prihod od cestovnih vozila
+STR_701A_AIRCRAFT_INCOME :{GOLD}Prihod od zrakoplova
+STR_701B_SHIP_INCOME :{GOLD}Prihod od brodova
+STR_701C_LOAN_INTEREST :{GOLD}Kamate
+STR_701D_OTHER :{GOLD}Ostalo
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Ukupno:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Graf prihoda
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Graf operativnih prihoda
+STR_7026_BANK_BALANCE :{WHITE}Bankovna bilanca
+STR_7027_LOAN :{WHITE}Kredit
+STR_MAX_LOAN :{WHITE}Maks zajam: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}Pozajmi {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Otplati {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...najveći dopušteni kredit iznosi {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Ne možeš dobiti još kredita...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...nemaš kredita za otplatu
+STR_702E_REQUIRED :{WHITE}...{CURRENCY} potrebno
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Ne možeš otplatiti kredit...
+STR_INSUFFICIENT_FUNDS :{WHITE}Ne možeš dati novac koji je pozajmljen od banke...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Odaberi novo lice za direktora
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Promijeni izgled vozila tvrtke
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Promjeni ime direktora
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Promijeni ime tvrtke
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Klikni na odabranu boju
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Povećaj iznos kredita
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Otplati dio kredita
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(Direktor)
+STR_7038_INAUGURATED :{GOLD}Na poziciji od: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Vozila:
+STR_AIRCRAFT :{WHITE}{COMMA} zrakoplov
+STR_7042_NONE :{WHITE}Ništa
+STR_7043_FACE_SELECTION :{WHITE}Odabir lica
+STR_7044_MALE :{BLACK}Muško
+STR_7045_FEMALE :{BLACK}Žensko
+STR_7046_NEW_FACE :{BLACK}Novo lice
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Odustani od odabira novog lica
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Prihvati odabir novog lica
+STR_7049_SELECT_MALE_FACES :{BLACK}Odaberi muška lica
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Odaberi ženska lica
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Generiraj nasumiÄno novo lice
+STR_704C_KEY :{BLACK}KljuÄ
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Prikaži kljuÄeve po grafovima
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}KljuÄ za grafove tvrtke
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Klikni ovdje za ukljuÄivanje/iskljuÄivanje tvrke s grafa
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Dostavljenih jedinica tereta
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Ocjena uÄinka tvrtke (najveća ocjena = 1000)
+STR_7052_COMPANY_VALUES :{WHITE}Vrijednost tvrtki
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Tablica lige tvrtki
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}Prijevozna tvrtka u nevoljama!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} će biti rasprodana ili objaviti bankrot ukoliko se uÄinak uskoro ne poboljÅ¡a!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(Direktor)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Spajanje prijevoznih tvrki!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} je bila prodana tvrtki {COMPANY} za {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Tražimo prijevoznu tvrku koja bi preuzela našu tvrtku.{}{}Želiš li kupiti tvrtku{COMPANY} za {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Bankrot!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} je zatvorena od strane kreditora i sva je imovina rasprodana!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}Osnovana je nova prijevozna tvrtka!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} zapoÄinje gradnju blizu grada {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Ne možeš kupiti tvrtku...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Isplatne rate tereta
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Dana u tranzitu
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Aktiviraj/deaktiviraj graf za vrstu tereta
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Inženjer
+STR_7067_TRAFFIC_MANAGER :Prijevozni upravitelj
+STR_7068_TRANSPORT_COORDINATOR :Prijevozni koordinator
+STR_7069_ROUTE_SUPERVISOR :Prijevozni nadzornik
+STR_706A_DIRECTOR :Direktor
+STR_706B_CHIEF_EXECUTIVE :Izvršni direktor
+STR_706C_CHAIRMAN :Predsjedavajući
+STR_706D_PRESIDENT :Predsjednik
+STR_706E_TYCOON :Tajkun
+STR_706F_BUILD_HQ :{BLACK}Izgradi sjedište tvrtke
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Izgradi središte tvrtke / pogledaj sjedište tvrtke
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Ne mogu izgraditi sjedište tvrke...
+STR_7072_VIEW_HQ :{BLACK}Pogledaj sjedište tvrtke
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}Svjetska recesija!{}{}Financijski struÄnjaci oÄekuju najgore zbog ekonomske krize!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Recesija zavrÅ¡ena!{}{}Obrat u trgovanu daje samopouzdanje gospodarstvu jer ekonomija jaÄa!
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Kupi 25% udjela u tvrtci
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Prodaj 25% udio u tvrtci
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Kupi 25% udjela u ovoj tvrtci
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Prodaj 25% udjela u ovoj tvrtci
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Ne možeš kupiti 25% udjela u ovoj tvrtci...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}Ne možeš prodati 25% udjela u ovoj tvrtci...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% u vlasništvu {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% u vlasništvu {COMPANY}{} {COMMA}% u vlasništvu {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} je preuzeta od strane tvrtke {COMPANY}!
+STR_7080_PROTECTED :{WHITE}Ova tvrka još nije dovoljno stara da bi trgovala udjelima...
+
+
+
+##id 0x8000
+
+##id 0x8800
+
+
+
+
+
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Nema mjesta za nove naredbe
+STR_8832_TOO_MANY_ORDERS :{WHITE}Previše naredbi
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Ne možeš ubaciti novu naredbu...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Ne možeš obrisati ovu naredbu...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Can't modify this order...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Ne možeš micati vozilo...
+STR_8838_N_A :N/A{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Ne možeÅ¡ prodati željezniÄko vozilo
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Ne može pronaći put do lokalnog servisa
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Ne možeš zaustaviti/pokrenuti vlak...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Interval servisiranja: {LTBLUE}{COMMA}dana{BLACK} Zadnji servis: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Vlakovi - klikni na vlak za informacije
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Izgradi/kupi nove vlakove (potreban servis)
+
+
+
+##id 0x9000
+
+
+
+##id 0x9800
+
+SERVICE_AT_SHIP_DEPOT :Servis u brodskom spremištu grada {TOWN}
+
+##id 0xA000
+
+SERVICE_AT_AIRPORT_HANGAR :Servisiranje u hangaru {STATION}
+
+##id 0xB000
+
+
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+############ End of order list
+
+
+
+
+
+
+
+
+
+
+### depot strings
+
+
+
+
+
+
+
+
+
+
+
+
+############ Lists rail types
+
+
+############ End of list of rail types
+
+
+
+########### String for New Landscape Generator
+
+
+
+########### String for new airports
+
+
+############ Tooltip measurment
+
+
+########
diff --git a/src/lang/unfinished/frisian.txt b/src/lang/unfinished/frisian.txt
new file mode 100644
index 000000000..3b970a2b8
--- /dev/null
+++ b/src/lang/unfinished/frisian.txt
@@ -0,0 +1,354 @@
+##name Frisian
+##ownname Frysk
+##isocode fy_NL.UTF-8
+##plural 0
+
+##id 0x0000
+STR_NULL :
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0009 :{WHITE}{CARGO}
+STR_000B :{YELLOW}{STATION})
+STR_000E :
+STR_0011_MAIL :Post
+STR_0012_OIL :Oalje
+STR_0014_GOODS :Guod
+STR_0015_GRAIN :Graan
+STR_0016_WOOD :Hout
+STR_0018_STEEL :Stiel
+STR_0019_VALUABLES :Kostbere spullen
+STR_001A_COPPER_ORE :Koper erts
+STR_001B_MAIZE :Mais
+STR_001C_FRUIT :Fruit
+STR_001D_DIAMONDS :Diamant
+STR_001E_FOOD :Iten
+STR_001F_PAPER :Papier
+STR_0020_GOLD :Goud
+STR_0021_WATER :Wetter
+STR_0022_WHEAT :Weet
+STR_0023_RUBBER :Rubber
+STR_0024_SUGAR :Sûker
+STR_0025_TOYS :Boartersguod
+STR_0026_CANDY :Snobbersguod
+STR_0027_COLA :Cola
+STR_0028_COTTON_CANDY :Sûkerspin
+STR_0029_BUBBLES :Bubbels
+STR_002A_TOFFEE :Toffee
+STR_002B_BATTERIES :Batterijen
+STR_002C_PLASTIC :Plestik
+STR_002E :
+STR_002F_PASSENGER :Passazjier
+STR_0031_MAIL :Post
+STR_0032_OIL :Oalje
+STR_0033_LIVESTOCK :Fee
+STR_0034_GOODS :Guod
+STR_0035_GRAIN :Nôt
+STR_0036_WOOD :Hout
+STR_0037_IRON_ORE :Izer Erts
+STR_0038_STEEL :Stiel
+STR_0039_VALUABLES :Kostber guod
+STR_003A_COPPER_ORE :Koper Erts
+STR_003B_MAIZE :Mais
+STR_003C_FRUIT :Fruit
+STR_003D_DIAMOND :Diamant
+STR_003E_FOOD :Iten
+STR_003F_PAPER :Papier
+STR_0040_GOLD :Goud
+STR_0041_WATER :Wetter
+STR_0043_RUBBER :Rubber
+STR_0044_SUGAR :Sûker
+STR_0045_TOY :Boartesguod
+STR_0046_CANDY :Snobbersguod
+STR_0047_COLA :Cola
+STR_004A_TOFFEE :Toffee
+STR_004B_BATTERY :Batterij
+STR_004C_PLASTIC :Plestik
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} passazjier
+STR_QUANTITY_COAL :{WEIGHT} ton coal
+STR_QUANTITY_MAIL :{COMMA} tassen mei post
+STR_QUANTITY_OIL :{VOLUME} oalje
+STR_QUANTITY_GRAIN :{WEIGHT} ton graan
+STR_QUANTITY_WOOD :{WEIGHT} ton hout
+STR_QUANTITY_STEEL :{WEIGHT} ton stiel
+STR_QUANTITY_VALUABLES :{COMMA} tas kostber guod
+STR_QUANTITY_MAIZE :{WEIGHT} ton mais
+STR_QUANTITY_FRUIT :{WEIGHT} ton fruit
+STR_QUANTITY_FOOD :{WEIGHT} ton iten
+STR_QUANTITY_PAPER :{WEIGHT} ton papier
+STR_QUANTITY_GOLD :{COMMA} tas goud
+STR_QUANTITY_WATER :{VOLUME} wetter
+STR_00B2_MESSAGE :{YELLOW}Bericht
+STR_00B3_MESSAGE_FROM :{YELLOW}Bericht fan {STRING}
+STR_00B7_VERSION :{BLACK}OpenTTD fersje {REV}
+
+STR_00C8_YES :{BLACK}Ja
+STR_00C9_NO :{BLACK}Nee
+STR_00D1_DARK_BLUE :Tsjuster Blauw
+STR_00D3_PINK :Roze
+STR_00D4_YELLOW :Giel
+STR_00D5_RED :Read
+STR_00D6_LIGHT_BLUE :Ljocht Blauw
+STR_00D7_GREEN :Grien
+STR_00D8_DARK_GREEN :Tsjuster Grien
+STR_00D9_BLUE :Blauw
+STR_00DC_PURPLE :Pears
+STR_00DD_ORANGE :Oranje
+STR_00DE_BROWN :Brún
+STR_00DF_GREY :Griis
+STR_00E0_WHITE :Wyt
+
+
+
+
+
+############ range for menu starts
+############ range for menu ends
+
+
+
+############ range for months starts
+############ range for months ends
+
+
+############ range for service numbers starts
+############ range for service numbers ends
+
+
+############ range for days starts
+STR_01B0_5TH :5
+STR_01B1_6TH :6
+STR_01B2_7TH :7
+STR_01B3_8TH :8
+STR_01B4_9TH :9
+STR_01B5_10TH :10
+STR_01B6_11TH :11
+STR_01B7_12TH :12
+STR_01B8_13TH :13
+STR_01B9_14TH :14
+STR_01BA_15TH :15
+STR_01BB_16TH :16
+STR_01BC_17TH :17
+STR_01BD_18TH :18
+STR_01BE_19TH :19
+STR_01BF_20TH :20
+STR_01C0_21ST :21
+STR_01C1_22ND :22
+STR_01C2_23RD :23
+STR_01C3_24TH :24
+STR_01C4_25TH :25
+STR_01C5_26TH :26
+STR_01C6_27TH :27
+STR_01C7_28TH :28
+STR_01C8_29TH :29
+############ range for days ends
+
+
+
+
+
+############ range for menu starts
+############ range ends here
+
+############ range for menu starts
+############ range ends here
+
+
+
+
+############ range for menu starts
+############ range ends here
+
+
+
+
+
+############ start of townname region
+############ end of townname region
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+# end of order system
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+############ network gui strings
+
+
+
+
+
+
+
+
+
+
+
+############ Leave those lines in this order!!
+############ End of leave-in-this-order
+
+
+
+
+
+
+
+############ Leave those lines in this order!!
+
+############ End of leave-in-this-order
+
+
+
+
+############ Leave those lines in this order!!
+############ End of leave-in-this-order
+
+
+
+
+
+############ end network gui strings
+
+
+
+##id 0x0800
+
+##id 0x1000
+
+
+
+##id 0x1800
+
+##id 0x2000
+
+
+##id 0x2800
+
+##id 0x3000
+
+
+############ range for rating starts
+############ range for rating ends
+
+
+##id 0x3800
+
+##id 0x4000
+
+##id 0x4800
+
+############ range for requires starts
+############ range for requires ends
+
+
+##id 0x5000
+
+##id 0x5800
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+
+
+############ end of savegame specific region!
+
+##id 0x6800
+
+############ range for difficulty levels starts
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+############ range for difficulty settings ends
+
+
+##id 0x7000
+
+##id 0x8000
+
+##id 0x8800
+
+
+
+
+
+
+##id 0x9000
+
+
+##id 0x9800
+
+
+##id 0xA000
+
+
+##id 0xB000
+
+
+############ Those following lines need to be in this order!!
+############ End of order list
+
+
+
+
+
+
+
+
+############ Lists rail types
+
+
+############ End of list of rail types
+
+
diff --git a/src/lang/unfinished/greek.txt b/src/lang/unfinished/greek.txt
new file mode 100644
index 000000000..9ae7cdff8
--- /dev/null
+++ b/src/lang/unfinished/greek.txt
@@ -0,0 +1,1529 @@
+##name Greek
+##ownname Ελληνικά
+##isocode el_GR.UTF-8
+##plural 0
+##gender m f n
+
+##id 0x0000
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Απο την άκÏη του χάÏτη
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Πολυ κοντά στην άκÏη του χάÏτη
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Δεν υπάÏχουν αÏκετά χÏήματα - απαιτεί {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}.
+STR_0005 :{RED}{CURRENCY64}.
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Απαιτείται επίπεδο εδαφος
+STR_0008_WAITING :{BLACK}Αναμονη: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (καθ'οδόν από
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Δέχεται: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Δέχεται: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :Επιβάτες
+STR_0010_COAL :ΆνθÏακας
+STR_0011_MAIL :ΑλληλογÏαφία
+STR_0012_OIL :ΠετÏέλαιο
+STR_0013_LIVESTOCK :Ζώα
+STR_0014_GOODS :Αγαθά
+STR_0015_GRAIN :ΣιτάÏι
+STR_0016_WOOD :ΞÏλα
+STR_0017_IRON_ORE :ΜεταλλεÏματα ΣιδήÏου
+STR_0018_STEEL :Χάλυβας
+STR_0019_VALUABLES :Τιμαλφή
+STR_001A_COPPER_ORE :ΜεταλλεÏματα ΧαλκοÏ
+STR_001B_MAIZE :ΑÏαβόσιτος
+STR_001C_FRUIT :ΦÏοÏτα
+STR_001D_DIAMONDS :Διαμάντια
+STR_001E_FOOD :Φαγητό
+STR_001F_PAPER :ΧαÏτί
+STR_0020_GOLD :ΧÏυσός
+STR_0021_WATER :ÎεÏÏŒ
+STR_0022_WHEAT :Σίτος
+STR_0023_RUBBER :Λάστιχο
+STR_0024_SUGAR :ΖάχαÏη
+STR_0025_TOYS :Παιχνίδια
+STR_0026_CANDY :Γλυκά
+STR_0027_COLA :Κόλα
+STR_0028_COTTON_CANDY :Μαλλί της ΓÏιάς
+STR_0029_BUBBLES :Φυσαλίδες
+STR_002A_TOFFEE :Τόφυ
+STR_002B_BATTERIES :ΜπαταÏίες
+STR_002C_PLASTIC :Πλαστικά
+STR_002D_FIZZY_DRINKS :Αναψυκτικά
+STR_002E :
+STR_002F_PASSENGER :Επιβάτης
+STR_0030_COAL :ΆνθÏακας
+STR_0031_MAIL :ΑλληλογÏαφία
+STR_0032_OIL :ΠετÏέλαιο
+STR_0033_LIVESTOCK :Ζώο
+STR_0034_GOODS :Αγαθό
+STR_0035_GRAIN :ΣιτάÏι
+STR_0036_WOOD :ΞÏλο
+STR_0037_IRON_ORE :Μετάλλευμα ΣιδήÏου
+STR_0038_STEEL :
+STR_0039_VALUABLES :Τιμαλφή
+STR_003A_COPPER_ORE :Μετάλλευμα ΧαλκοÏ
+STR_003B_MAIZE :ΑÏαβόσιτος
+STR_003C_FRUIT :ΦÏοÏτο
+STR_003D_DIAMOND :Διαμάντι
+STR_003E_FOOD :Φαγητό
+STR_003F_PAPER :ΧαÏτί
+STR_0040_GOLD :ΧÏυσός
+STR_0041_WATER :ÎεÏÏŒ
+STR_0042_WHEAT :Σίτος
+STR_0043_RUBBER :Λάστιχο
+STR_0044_SUGAR :ΖάχαÏη
+STR_0045_TOY :Παιχνίδι
+STR_0046_CANDY :Γλυκό
+STR_0047_COLA :Κόλα
+STR_0048_COTTON_CANDY :Μαλλί της ΓÏιάς
+STR_0049_BUBBLE :Φυσαλίδα
+STR_004A_TOFFEE :Τόφυ
+STR_004B_BATTERY :ΜπαταÏία
+STR_004C_PLASTIC :Πλαστικό
+STR_004D_FIZZY_DRINK :Αναψυκτικό
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}ΧάÏτης - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Επιλογές ΠαιχνιδιοÏ
+STR_00B2_MESSAGE :{YELLOW}Μήνυμα
+STR_00B3_MESSAGE_FROM :{YELLOW}Μήνυμα από {STRING}
+STR_00B4_CAN_T_DO_THIS :{WHITE}Δεν μποÏεί να γίνει αυτό....
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Αυτή η πεÏιοχή είναι αδÏνατο να καθαÏιστεί...
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}ΑÏχικά Πνευματικά Δικαιώματα {COPYRIGHT} 1995 Chris Sawyer, Όλα τα δικαιώματα διατηÏοÏνται
+STR_00B7_VERSION :{BLACK}OpenTTD έκδοση {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 Η ομάδα του OpenTTD
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Έξοδος
+STR_00C8_YES :{BLACK}Îαί
+STR_00C9_NO :{BLACK}Όχι
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Είστε σίγουÏος/η ότι θέλετε να παÏατήσετε το παιχνίδι και να επιστÏέψετε στο {STRING};
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Τίποτα
+STR_00D1_DARK_BLUE :ΣκοÏÏο Μπλέ
+STR_00D2_PALE_GREEN :Χλωμό ΠÏάσινο
+STR_00D3_PINK :Ροζ
+STR_00D4_YELLOW :ΚίτÏινο
+STR_00D5_RED :Κόκκινο
+STR_00D6_LIGHT_BLUE :Ανοιχτό μπλέ
+STR_00D7_GREEN :ΠÏάσινο
+STR_00D8_DARK_GREEN :ΣκοÏÏο ΠÏάσινο
+STR_00D9_BLUE :Μπλέ
+STR_00DA_CREAM :ΚÏεμ
+STR_00DB_MAUVE :Μωβ
+STR_00DC_PURPLE :ΠοÏφυÏÏŒ
+STR_00DD_ORANGE :ΠοÏτοκαλί
+STR_00DE_BROWN :Καφέ
+STR_00DF_GREY :ΓκÏι
+STR_00E0_WHITE :Λευκό
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}ΠάÏα πολλά οχήματα στο παιχνίδι
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Τοποθεσία
+STR_00E5_CONTOURS :ΠεÏιγÏάμματα
+STR_00E6_VEHICLES :Οχήματα
+STR_00E7_INDUSTRIES :Βιομηχανίες
+STR_00E8_ROUTES :ΔιαδÏομές
+STR_00E9_VEGETATION :Βλάστηση
+STR_00EA_OWNERS :Ιδιοκτήτες
+STR_00EB_ROADS :{BLACK}{TINYFONT}ΔÏόμοι
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}ΣιδηÏόδÏομοι
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Σταθμοί/ΑεÏοδÏόμια/Λιμάνια
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}ΚτήÏια/Βιομηχανίες
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Οχήματα
+STR_00F0_100M :{BLACK}{TINYFONT}100 μ
+STR_00F1_200M :{BLACK}{TINYFONT}200 μ
+STR_00F2_300M :{BLACK}{TINYFONT}300 μ
+STR_00F3_400M :{BLACK}{TINYFONT}400 μ
+STR_00F4_500M :{BLACK}{TINYFONT}500 μ
+STR_00F5_TRAINS :{BLACK}{TINYFONT}ΤÏαίνα
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Οδικά Οχήματα
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Πλοία
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}ΑεÏοσκάφος
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}ΔιαδÏομές ΜεταφοÏών
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}ΟÏυχείο ΆνθÏακα
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Σταθμός ΠαÏαγωγής ΗλεκτÏÎ¹ÎºÎ¿Ï Î¡ÎµÏματος
+STR_00FC_FOREST :{BLACK}{TINYFONT}Δάσος
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}ΠÏιονιστήÏιο
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}ΔιυλιστήÏιο
+STR_00FF_FARM :{BLACK}{TINYFONT}ΦάÏμα
+STR_0100_FACTORY :{BLACK}{TINYFONT}ΕÏγοστάσιο
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}ΕÏγασίες ΕκτÏπωσης
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}ΠετÏελαιοπηγές
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}ΟÏυχείο ΜεταλλεÏματος ΣιδήÏου
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}ÎœÏλος Χάλυβα
+STR_0105_BANK :{BLACK}{TINYFONT}ΤÏάπεζα
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}ÎœÏλος ΧαÏτιοÏ
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}ΟÏυχείο ΧÏυσοÏ
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}ΕÏγοστάσιο ΕπεξεÏγασίας ΤÏοφίμων
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}ΟÏυχείο Διαμαντιών
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}ΟÏυχείο ΜεταλλεÏματος ΧαλκοÏ
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Φυτεία ΦÏοÏτων
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Φυτεία Λάστιχου
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}ΠαÏοχή ÎεÏοÏ
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}ΠÏÏγος Ύδατος
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}ÎœÏλος Ξυλείας
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Δάσος του ÎœÎ±Î»Î¹Î¿Ï Ï„Î·Ï‚ ΓÏιάς
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}ΕÏγοστάσιο Γλυκών
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}ΦάÏμα ΜπαταÏιών
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Πηγάδια Κόλας
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Κατάστημα Παιχνιδιών
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}ΕÏγοστάσιο Παιχνιδιών
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Πλαστικές Πηγές
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}ΕÏγοστάσιο ΠαÏαγωγής Αναψυκτικών
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}ΓεννήτÏια Φυσαλίδων
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Λατομείο Τόφυ
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}ΟÏυχείο ΖάχαÏης
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}ΣιδηÏοδÏομικός Σταθμός
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}ΠεÏιοχή ΦόÏτωσης ΦοÏτηγών
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Στάση ΛεωφοÏείου
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}ΑεÏοδÏόμιο/ΕλικοδÏόμιο
+STR_011F_DOCK :{BLACK}{TINYFONT}Λιμάνι
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}ΤÏÎ±Ï‡Ï ÎˆÎ´Î±Ï†Î¿Ï‚
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}ΓÏασίδι
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Γυμνό Έδαφος
+STR_0123_FIELDS :{BLACK}{TINYFONT}ΧωÏάφια
+STR_0124_TREES :{BLACK}{TINYFONT}ΔέντÏα
+STR_0125_ROCKS :{BLACK}{TINYFONT}Î’Ïάχοι
+STR_0126_WATER :{BLACK}{TINYFONT}ÎεÏÏŒ
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}ΧωÏίς Ιδιοκτήτη
+STR_0128_TOWNS :{BLACK}{TINYFONT}Πόλεις
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Βιομηχανίες
+STR_012A_DESERT :{BLACK}{TINYFONT}ΈÏημος
+STR_012B_SNOW :{BLACK}{TINYFONT}Χιόνι
+STR_012C_MESSAGE :{WHITE}Μήνυμα
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}ΆκυÏο
+STR_012F_OK :{BLACK}OK
+STR_0130_RENAME :{BLACK}Μετονομασία
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}ΚαθοÏίστηκαν πάÏα πολλά ονόματα
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Το όνομα που διαλέξατε υπάÏχει ήδη
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+
+STR_013B_OWNED_BY :{WHITE}...ιδιοκτησία του {STRING}
+STR_013C_CARGO :{BLACK}ΦοÏτίο
+STR_013D_INFORMATION :{BLACK}ΠληÏοφοÏίες
+STR_013E_CAPACITIES :{BLACK}ΧωÏητικότητες
+STR_013E_TOTAL_CARGO :{BLACK}Συνολικό ΦοÏτίο
+STR_013F_CAPACITY :{BLACK}ΧωÏητικότητα: {LTBLUE}{CARGO}
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Συνολική χωÏητικότητα φοÏτίου του Ï„Ïαίνου:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_0140_NEW_GAME :{BLACK}Îέο Παιχνίδι
+STR_0141_LOAD_GAME :{BLACK}ΦόÏτωση ΠαιχνιδιοÏ
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_0148_GAME_OPTIONS :{BLACK}Επιλογές ΠαιχνιδιοÏ
+
+STR_0150_SOMEONE :κάποιος{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :ΧάÏτης του Κόσμου
+STR_0152_TOWN_DIRECTORY :Κατάλογος Πόλεων
+STR_0153_SUBSIDIES :ΕπιχοÏηγήσεις
+
+
+
+
+
+
+
+
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :ΓÏάφημα λειτουÏÎ³Î¹ÎºÎ¿Ï ÎºÎ­Ïδους
+STR_0155_INCOME_GRAPH :ΓÏάφημα εισοδήματος
+STR_0156_DELIVERED_CARGO_GRAPH :ΓÏάφημα παÏαδοθέντος φοÏτίου
+STR_0157_PERFORMANCE_HISTORY_GRAPH :ΓÏάφημα ιστοÏÎ¹ÎºÎ¿Ï Î±Ï€ÏŒÎ´Î¿ÏƒÎ·Ï‚
+STR_0158_COMPANY_VALUE_GRAPH :ΓÏάφημα εταιÏικής αξίας
+STR_0159_CARGO_PAYMENT_RATES :Ποσοστά πληÏωμής φοÏτίου
+STR_015A_COMPANY_LEAGUE_TABLE :Πίνακας κατάταξης επιχείÏησης
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}Σχετικά με το OpenTTD
+STR_015C_SAVE_GAME :Αποθήκευση παιχνιδιοÏ
+STR_015D_LOAD_GAME :ΦόÏτωση παιχνιδιοÏ
+STR_015E_QUIT_GAME :ΠαÏαίτηση από το παιχνίδι
+STR_015F_QUIT :Έξοδος
+STR_0161_QUIT_GAME :{WHITE}ΠαÏαίτηση από το Παιχνίδι
+
+
+############ range for months starts
+STR_0162_JAN :Ιαν
+STR_0163_FEB :Φεβ
+STR_0164_MAR :ΜαÏ
+STR_0165_APR :ΑπÏ
+STR_0166_MAY :Μαι
+STR_0167_JUN :Ιουν
+STR_0168_JUL :Ιουλ
+STR_0169_AUG :Αυγ
+STR_016A_SEP :Σεπ
+STR_016B_OCT :Οκτ
+STR_016C_NOV :Îοε
+STR_016D_DEC :Δεκ
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}ΠαÏση του παιχνιδιοÏ
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Αποθήκευση, παÏαίτηση, έξοδος
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Εμφάνιση λίστας σταθμών της εταιÏείας
+STR_0174_DISPLAY_MAP :{BLACK}Εμφάνιση χάÏτη
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Εμφάνιση χάÏτη, καταλόγου πόλεων
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Εμφάνιση του καταλόγου των πόλεων
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Εμφάνιση οικονομικών πληÏοφοÏιών της εταιÏείας
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Εμφάνιση γενικών πληÏοφοÏιών της εταιÏείας
+STR_0179_DISPLAY_GRAPHS :{BLACK}Εμφάνιση γÏαφημάτων
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Εμφάνιση του πίνακα κατάταξης των εταιÏειών
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Εμφάνιση λίστας Ï„Ïαίνων της εταιÏείας
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Εμφάνιση λίστας με τα οδικά οχήματα της εταιÏείας
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Εμφάνιση λίστας με τα πλοία της εταιÏείας
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Εμφάνιση λίστας με τα αεÏοσκάφη της εταιÏείας
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Μεγέθυνση της εικόνας
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}ΣμίκÏυνση της εικόνας
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Κατασκευή σιδηÏόδÏομου
+STR_0182_BUILD_ROADS :{BLACK}Κατασκευή δÏόμων
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Κατασκευή αποβάθÏας
+STR_0184_BUILD_AIRPORTS :{BLACK}Κατασκευή αεÏοδÏομίων
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Τοποθέτηση δεντÏων, πινακίδων κλπ
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}ΠληÏοφοÏίες εδάφους
+STR_0187_OPTIONS :{BLACK}Επιλογές
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Δεν μποÏεί να αλλάξει το διάστημα της συντήÏησης...
+STR_018B_CLOSE_WINDOW :{BLACK}Κλείσιμο παÏαθÏÏου
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Τίτλος παÏαθÏÏου - σÏÏετε για να το μετακινήσετε
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Κατεδάφιση των κτηÏίων κ.λπ. σε ένα τετÏάγωνο εδάφους
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Χαμηλώστε μια γωνία του εδάφους
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Ανυψώστε μια γωνία του εδάφους
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}ΜπάÏα ΚÏλισης - μετακινεί την λίστα πάνω/κάτω
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Εμφάνιση πεÏιγÏαμμάτων εδάφους στο χάÏτη
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Εμφάνιση οχημάτων στο χάÏτη
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Εμφάνιση βιομηχανιών στο χάÏτη
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Εμφάνιση μεταφοÏικών οδών στο χάÏτη
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Εμφάνιση βλάστησης στο χάÏτη
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Εμφάνιση ιδιοκτητών γης στο χάÏτη
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Εναλλαγή ονομάτων πόλεων στο χάÏτη
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}ΚέÏδος αυτό το έτος: {CURRENCY} (Ï€ÏοηγοÏμενο έτος: {CURRENCY})
+
+############ range for service numbers starts
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Όχημα δÏόμου
+STR_019D_AIRCRAFT :ΑεÏοσκάφος
+STR_019E_SHIP :Πλοίο
+STR_019F_TRAIN :ΤÏένο
+STR_01A0_IS_GETTING_OLD :{WHITE}Το {STRING} {COMMA} παλιώνει
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}Το {STRING} {COMMA} παλιώνει πολÏ
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}Το {STRING} {COMMA} παλιώνει Ï€Î¿Î»Ï ÎºÎ±Î¹ χÏειάζεται επειγόντωςαντικατάσταση
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}ΠληÏοφοÏίες ΠεÏιοχής Εδάφους
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Κόστος καθαÏισμοÏ: {LTBLUE}Îœ/Δ
+STR_01A5_COST_TO_CLEAR :{BLACK}Κόστος καθαÏισμοÏ: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :Μ/Δ
+STR_01A7_OWNER :{BLACK}Ιδιοκτήτης: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Τοπική αÏχή: {LTBLUE}{STRING}
+STR_01A9_NONE :Κανένα
+STR_01AA_NAME :{BLACK}Όνομα
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1{G ος η ο}
+STR_01AD_2ND :2{G ος η ο}
+STR_01AE_3RD :3{G ος η ο}
+STR_01AF_4TH :4{G ος η ο}
+STR_01B0_5TH :5{G ος η ο}
+STR_01B1_6TH :6{G ος η ο}
+STR_01B2_7TH :7{G ος η ο}
+STR_01B3_8TH :8{G ος η ο}
+STR_01B4_9TH :9{G ος η ο}
+STR_01B5_10TH :10{G ος η ο}
+STR_01B6_11TH :11{G ος η ο}
+STR_01B7_12TH :12{G ος η ο}
+STR_01B8_13TH :13{G ος η ο}
+STR_01B9_14TH :14{G ος η ο}
+STR_01BA_15TH :15{G ος η ο}
+STR_01BB_16TH :16{G ος η ο}
+STR_01BC_17TH :17{G ος η ο}
+STR_01BD_18TH :18{G ος η ο}
+STR_01BE_19TH :19{G ος η ο}
+STR_01BF_20TH :20{G ος η ο}
+STR_01C0_21ST :21{G ος η ο}
+STR_01C1_22ND :22{G ος η ο}
+STR_01C2_23RD :23{G ος η ο}
+STR_01C3_24TH :24{G ος η ο}
+STR_01C4_25TH :25{G ος η ο}
+STR_01C5_26TH :26{G ος η ο}
+STR_01C6_27TH :27{G ος η ο}
+STR_01C7_28TH :28{G ος η ο}
+STR_01C8_29TH :29{G ος η ο}
+STR_01C9_30TH :30{G ος η ο}
+STR_01CA_31ST :31{G ος η ο}
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Αποδεκτό ΕμπόÏευμα: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Jazz Jukebox
+STR_01D3_SOUND_MUSIC :Ήχος/Μουσική
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Εμφάνιση παÏαθÏÏου ήχου/μουσικής
+STR_01D5_ALL :{TINYFONT}Όλα
+STR_01D6_OLD_STYLE :{TINYFONT}Παλιό Στυλ
+STR_01D7_NEW_STYLE :{TINYFONT}Îέο Στυλ
+STR_01D8_EZY_STREET :{TINYFONT}Ezy Street
+STR_01D9_CUSTOM_1 :{TINYFONT}ΠÏοσαÏμοσμένο 1
+STR_01DA_CUSTOM_2 :{TINYFONT}ΠÏοσαÏμοσμένο 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Ένταση Μουσικής
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Ένταση Εφφέ
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}ΕΛΑΧ ' ' ' ' ' ' ΜΕΓ
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Πλοήγηση στο Ï€ÏοηγοÏμενο κομμάτι της συλλογής
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Πλοήγηση στο επόμενο κομμάτι στη συλλογή
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Σταμάτημα αναπαÏαγωγής
+STR_01E1_START_PLAYING_MUSIC :{BLACK}ΈναÏξη αναπαÏαγωγής
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Μετακινήστε τις γÏαμμές κÏλισης για ÏÏθμιση έντασης
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Κομμάτι{SETX 88}Τίτλος
+STR_01E9_SHUFFLE :{TINYFONT}Τυχαία αναπαÏαγωγή
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}ΠÏόγÏαμμα
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Επιλογή ÎœÎ¿Ï…ÏƒÎ¹ÎºÎ¿Ï Î ÏογÏάμματος
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Λίστα Κομματιών
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}ΠÏόγÏαμμα - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}ΚαθαÏισμός
+STR_01F1_SAVE :{TINYFONT}{BLACK}Αποθήκευση
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}ΤÏέχον Ï€ÏόγÏαμμα μουσικών κομματιών
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Επιλογή Ï€ÏογÏάμματος 'όλα τα κομμάτια'
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Επιλογή Ï€ÏογÏάμματος 'παλιό στυλ'
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Επιλογή Ï€ÏογÏάμματος 'νέο στυλ'
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Επιλογή Ï€ÏογÏάμματος 'ΠÏοσαÏμοσμένο 1'
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Επιλογή Ï€ÏογÏάμματος 'ΠÏοσαÏμοσμένο 2'
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}ΚαθαÏισμός Ï„Ïέχοντος Ï€ÏογÏάμματος (ΠÏοσαÏμοσμένο1 ή ΠÏοσαÏμοσμένο2 μόνο)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Αποθήκευση επιλογών μουσικής
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Κάντε κλίκ στο μουσικό κομμάτι για Ï€Ïοσθήκη στο Ï„Ïέχον Ï€ÏόγÏαμμα (ΠÏοσαÏμοσμένο1 ή ΠÏοσαÏμοσμένο2 μόνο)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Εναλλαγή τυχαίας αναπαÏαγωγής on/off στο Ï€ÏόγÏαμμα
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Εμφάνιση παÏαθÏÏου επιλογής Î¼Î¿Ï…ÏƒÎ¹ÎºÎ¿Ï ÎºÎ¿Î¼Î¼Î±Ï„Î¹Î¿Ï
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Κάντε κλίκ στην υπηÏεσία για κεντÏάÏισμα στην βιομηχανία/πόλη
+STR_01FE_DIFFICULTY :{BLACK}{G=f}Δυσκολία ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Τελευταίο μήνυμα/αναφοÏά νέων
+STR_0201_MESSAGE_SETTINGS :Ρυθμίσεις μηνυμάτων
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Εμφάνιση τελευταίου μηνÏματος/αναφοÏάς νέων, επιλογές μηνυμάτων
+STR_0204_MESSAGE_OPTIONS :{WHITE}Επιλογές Μηνυμάτων
+STR_0205_MESSAGE_TYPES :{BLACK}ΤÏποι μηνυμάτων:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Άφιξη Ï€Ïώτου οχήματος στο σταθμό του παίκτη
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Άφιξη του Ï€Ïώτου οχήματος το σταθμό του αντιπάλου
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Ατυχήματα / καταστÏοφές
+STR_0209_COMPANY_INFORMATION :{YELLOW}ΠληÏοφοÏίες εταιÏείας
+STR_020A_ECONOMY_CHANGES :{YELLOW}Οικονομικές αλλαγές
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Συμβουλές / πληÏοφοÏίες για τα οχήματα του παίκτη
+STR_020C_NEW_VEHICLES :{YELLOW}Îέα οχήματα
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Αλλαγές στην αποδοχή φοÏτίου
+STR_020E_SUBSIDIES :{YELLOW}ΕπιχοÏηγήσεις
+STR_020F_GENERAL_INFORMATION :{YELLOW}Γενικές πληÏοφοÏίες
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...Ï€Î¿Î»Ï Î¼Î±ÎºÏιά από τον Ï€ÏοηγοÏμενο Ï€ÏοοÏισμό
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Οι καλÏτεÏες εταιÏείες που έφτασαν το {NUM}{}({STRING} Επίπεδο)
+STR_0212 :{BIGFONT}{COMMA},
+STR_0213_BUSINESSMAN :Επαγγελματίας
+STR_0214_ENTREPRENEUR :ΕπιχειÏηματίας
+STR_0215_INDUSTRIALIST :Βιομήχανος
+STR_0216_CAPITALIST :ΚεφαλαιοÏχος
+STR_0217_MAGNATE :Μεγιστάνας
+STR_0218_MOGUL :Τυχοδιώκτης
+STR_0219_TYCOON_OF_THE_CENTURY :Μεγιστάνας του Αιώνα
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} έφτασε στο επίπεδο '{STRING}'
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} της εταιÏείας {COMPANY} έφτασε στο επίπεδο '{STRING}'!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}ΔημιουÏγία ΣεναÏίου
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}ΠÏόγÏαμμα ΕπεξεÏτασίας ΣεναÏίου
+STR_0223_LAND_GENERATION :{WHITE}ΔημιουÏγία Γης
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Τυχαία Γη
+STR_0227_RESET_LAND :{BLACK}ΕπαναφοÏά Γης
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}ΑÏξηση πεÏιοχής για χαμήλωμα/ανÏψωση γης
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Μείωση πεÏιοχής για χαμήλωμα/ανÏψωση γης
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}ΔημιουÏγία τυχαίου εδάφους
+STR_022B_RESET_LANDSCAPE :{BLACK}ΕπαναφοÏά τοπίου
+STR_022C_RESET_LANDSCAPE :{WHITE}ΕπαναφοÏά Τοπίου
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Είστε σίγουÏος ότι θέλετε να επαναφέÏετε το τοπίο;
+STR_022E_LANDSCAPE_GENERATION :{BLACK}ΔημιουÏγία τοπίου
+STR_022F_TOWN_GENERATION :{BLACK}ΔημιουÏγία πόλης
+STR_0230_INDUSTRY_GENERATION :{BLACK}ΔημιουÏγία Βιομηχανίας
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Κατασκευή δÏόμου
+STR_0233_TOWN_GENERATION :{WHITE}ΔημιουÏγία Πόλης
+STR_0234_NEW_TOWN :{BLACK}Îέα Πόλη
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Κατασκευή νέας πόλης
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}ΑδÏνατο να χτιστεί πόλη εδώ...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...Ï€Î¿Î»Ï ÎºÎ¿Î½Ï„Î¬ στην άκÏη του χάÏτη
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...Ï€Î¿Î»Ï ÎºÎ¿Î½Ï„Î¬ σε άλλη πόλη
+STR_0239_SITE_UNSUITABLE :{WHITE}...ακατάλληλη πεÏιοχή
+STR_023A_TOO_MANY_TOWNS :{WHITE}...πάÏα πολλές πόλεις
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}ΑÏξηση μεγέθους πόλεως
+STR_023C_EXPAND :{BLACK}Επέκταση
+STR_023D_RANDOM_TOWN :{BLACK}Τυχαία Πόλη
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Χτίσιμο πόλης σε τυχαία τοποθεσία
+STR_023F_INDUSTRY_GENERATION :{WHITE}ΔημιουÏγία Βιομηχανίας
+STR_0240_COAL_MINE :{BLACK}{G=n}ΟÏυχείο ΆνθÏακα
+STR_0241_POWER_STATION :{BLACK}{G=m}Σταθμός ΠαÏαγωγής ΗλεκτÏισμοÏ
+STR_0242_SAWMILL :{BLACK}{G=n}ΠÏιονιστήÏιο
+STR_0243_FOREST :{BLACK}{G=n}Δάσος
+STR_0244_OIL_REFINERY :{BLACK}{G=n}ΔιυλιστήÏιο
+STR_0245_OIL_RIG :{BLACK}{G=f}ΠλατφόÏμα ΠετÏελαίου
+STR_0246_FACTORY :{BLACK}{G=n}ΕÏγοστάσιο
+STR_0247_STEEL_MILL :{BLACK}{G=m}ÎœÏλος Χάλυβα
+STR_0248_FARM :{BLACK}{G=f}ΦάÏμα
+STR_0249_IRON_ORE_MINE :{BLACK}{G=n}ΟÏυχείο ΜεταλλεÏματος ΣιδήÏου
+STR_024A_OIL_WELLS :{BLACK}Πηγάδια ΠετÏελαίου
+STR_024B_BANK :{BLACK}{G=f}ΤÏάπεζα
+STR_024C_PAPER_MILL :{BLACK}{G=m}ÎœÏλος ΧαÏτιοÏ
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}{G=n}ΕÏγοστάσιο ΕπεξεÏγασίας ΤÏοφίμων
+STR_024E_PRINTING_WORKS :{BLACK}ΕÏγασίες ΕκτÏπωσης
+STR_024F_GOLD_MINE :{BLACK}ΟÏυχείο ΧÏυσοÏ
+STR_0250_LUMBER_MILL :{BLACK}ÎœÏλος Ξυλείας
+STR_0251_FRUIT_PLANTATION :{BLACK}Φυτείες ΦÏοÏτων
+STR_0252_RUBBER_PLANTATION :{BLACK}Φυτείες Λάστιχου
+STR_0253_WATER_SUPPLY :{BLACK}ΠÏομήθεια ÎεÏοÏ
+STR_0254_WATER_TOWER :{BLACK}ΠÏÏγος ÎεÏοÏ
+STR_0255_DIAMOND_MINE :{BLACK}ΑδαμαντοÏυχείο
+STR_0256_COPPER_ORE_MINE :{BLACK}ΟÏυχείο ΜεταλλεÏματος ΧαλκοÏ
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Δάσος ÎœÎ±Î»Î»Î¹Î¿Ï Ï„Î·Ï‚ ΓÏιάς
+STR_0258_CANDY_FACTORY :{BLACK}ΕÏγοστάσιο Γλυκών
+STR_0259_BATTERY_FARM :{BLACK}ΦάÏμα ΜπαταÏίας
+STR_025A_COLA_WELLS :{BLACK}Πηγάδια Κόλα
+STR_025B_TOY_SHOP :{BLACK}Μαγαζί Παιχνιδιών
+STR_025C_TOY_FACTORY :{BLACK}ΕÏγοστάσιο Παιχνιδιών
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Πηγές ΠλαστικοÏ
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}ΕÏγοστάσιο ΑνθÏακοÏχων
+STR_025F_BUBBLE_GENERATOR :{BLACK}ΓεννήτÏια Φυσαλίδων
+STR_0260_TOFFEE_QUARRY :{BLACK}Λατομείο Τόφυ
+STR_0261_SUGAR_MINE :{BLACK}ΟÏυχείο ΖάχαÏης
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Κατασκευή ΟÏυχείου ΆνθÏακα
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Κατασκευή Î£Ï„Î±Î¸Î¼Î¿Ï Î Î±Ïαγωγής ΗλεκτÏισμοÏ
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Κατασκευή ΠÏιονιστηÏίου
+STR_0265_PLANT_FOREST :{BLACK}ΦÏτευση Δάσους
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Κατασκευή ΔιυλιστηÏίου
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Κατασκευή ΠλατφόÏμας ΠετÏελαίου (ΜποÏεί να χτιστεί μόνο στα άκÏα του χάÏτη)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Κατασκευή ΕÏγοστασίου
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Κατασκευή ÎœÏλου Χάλυβα
+STR_026A_CONSTRUCT_FARM :{BLACK}Κατασκευή ΦάÏμας
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Κατασκευή ΟÏυχείου ΜεταλλεÏματος ΣιδήÏου
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Κατασκευή Πηγαδιών ΠετÏελαίου
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Κατασκευή ΤÏάπεζας (ΜποÏεί να χτιστεί μόνο σε πόλεις με πληθυσμό άνω των 1200)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Κατασκευή ÎœÏλου ΧαÏτιοÏ
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Κατασκευή ΕÏγοστασίου ΕπεξεÏγασίας ΤÏοφίμων
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Κατασκευή ΕÏγαστηÏίου ΕκτÏπωσης
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Κατασκευή ΧÏυσοÏυχείου
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Κατασκευή ΤÏάπεζας (ΜποÏεί να χτιστεί μόνο σε πόλεις)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Κατασκευή ÎœÏλου Ξυλείας (για καθαÏισμό δασών και παÏαγωγή Ξυλείας)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}ΦÏτευση Φυτείας ΦÏοÏτων
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}ΦÏτευση Φυτείας Λάστιχου
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Κατασκευή ΠÏομήθειας ÎεÏοÏ
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Κατασκευή ΠÏÏγου ÎεÏÎ¿Ï (ΜποÏεί να χτιστεί μόνο σε πόλεις)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Κατασκευή ΑδαμαντοÏυχείου
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Κατασκευή ΟÏυχείου ΜεταλλεÏματος ΧαλκοÏ
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}ΦÏτευση Δάσους ÎœÎ±Î»Î»Î¹Î¿Ï Ï„Î·Ï‚ ΓÏιάς
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Κατασκευή ΕÏγοστασίου Γλυκών
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Κατασκευή ΦάÏμας ΜπαταÏιών
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Κατασκευή Πηγαδιών Κόλα
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Κατασκευή Καταστήματος Παιχνιδιών
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Κατασκευή ΕÏγοστασίου Παιχνιδιών
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Κατασκευή Πηγών ΠλαστικοÏ
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Κατασκευή ΕÏγοστασίου Αναψυκτικών
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Κατασκευή ΓεννήτÏιας Φυσαλίδων
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Κατασκευή Λατομείου Τόφυ
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Κατασκευή ΟÏυχείου ΖάχαÏης
+STR_0285_CAN_T_BUILD_HERE :{WHITE}ΑδÏνατο να χτιστεί {G ο η το} {STRING} εδώ...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...Ï€Ïέπει να χτιστεί πόλη Ï€Ïώτα
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...επιτÏέπεται μόνο μία ανά πόλη
+STR_0288_PLANT_TREES :{BLACK}ΦÏτευση ΔέντÏων
+STR_0289_PLACE_SIGN :{BLACK}Τοποθέτηση πινακίδας
+STR_028A_RANDOM_TREES :{BLACK}Τυχαία ΔέντÏα
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}ΦÏτευση δέντÏων τυχαία στο τοπίο
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Τοποθέτηση πετÏωδών επιφανειών στο τοπίο
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Τοποθέτηση φάÏου
+STR_028E_PLACE_TRANSMITTER :{BLACK}Τοποθέτηση αναμεταδότη
+STR_028F_DEFINE_DESERT_AREA :{BLACK}ΟÏίστε πεÏιοχή εÏήμου.{}Πατήστε και κÏατήστε το CTRL για αφαίÏεση
+STR_0290_DELETE :{BLACK}ΔιαγÏαφή
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}ΠλήÏης διαγÏαφή πόλεως
+STR_0292_SAVE_SCENARIO :Απποθήκευση σεναÏίου
+STR_0293_LOAD_SCENARIO :ΦόÏτωση σεναÏίου
+STR_0294_QUIT_EDITOR :Έξοδος από το Ï€ÏόγÏαμμα επεξεÏγασίας
+STR_0295 :
+STR_0296_QUIT :Έξοδος
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Αποθήκευση σεναÏίου, φόÏτωση, παÏαίτηση Ï€ÏόγÏαμμα επεξεÏγασίας, έξοδος
+STR_0298_LOAD_SCENARIO :{WHITE}ΦόÏτωση ΣεναÏίου
+STR_0299_SAVE_SCENARIO :{WHITE}Αποθήκευση ΣεναÏίου
+STR_029A_PLAY_SCENARIO :{BLACK}Παιξτε το ΣενάÏιο
+STR_029C_QUIT_EDITOR :{WHITE}Έξοδος από το ΠÏόγÏαμμα ΕπεξεÏγασίας
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...μποÏεί να χτιστεί μόνο σε πόλεις με πληθυσμό άνω των 1200
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Μετακίνηση ημ/νίας εκκίνησης 1 χÏόνο πίσω
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Μετακίνηση ημ/νίας εκκίνησης 1 χÏόνο μπÏοστά
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...και τα δÏο άκÏα της γέφυÏας Ï€Ïέπει να είναι σε έδαφος
+STR_02A1_SMALL :{BLACK}ΜικÏÏŒ
+STR_02A2_MEDIUM :{BLACK}Μεσαίο
+STR_02A3_LARGE :{BLACK}Μεγάλο
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Επιλογή μεγέθους πόλης
+STR_02A5_TOWN_SIZE :{YELLOW}Μέγεθος πόλης:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Εμφάνιση τελευταίου μηνÏματος ή αναφοÏάς νέων
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Καταλογος πόλεων
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Ονόματα σχεδίων οχημάτων
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :ΠÏοεπιλεγμέν{G ος η ο}
+STR_02BF_CUSTOM :ΠÏοσαÏμοσμέν{G ος η ο}
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Αποθήκευση Ï€ÏοσαÏμοσμένων ονομάτων
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Επιλογή ονομάτων σχεδίασης οχημάτων
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Αποθήκευση Ï€ÏοσαÏμοσμένων ονομάτων σχεδίασης οχημάτων
+
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Επιλογές παιχνιδιοÏ
+STR_02C5_DIFFICULTY_SETTINGS :Ρυθμίσεις δυσκολίας
+STR_02C7_CONFIG_PATCHES :ΡÏθμιση διοÏθώσεων
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Ονόματα πόλεων που εμφανίζονται
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Ονόματα σταθμών που εμφανίζονται
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Πινακίδες που εμφανίζονται
+STR_02D0_FULL_ANIMATION :{SETX 12}ΠλήÏες animation
+STR_02D2_FULL_DETAIL :{SETX 12}ΠλήÏης λεπτομέÏεια
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Διαφανή κτίÏια
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :ΠληÏοφοÏίες πεÏιοχής εδάφους
+STR_02D6 :
+STR_02D7_SCREENSHOT_CTRL_S :ΦωτογÏαφία εικόνας (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Γιγαντιαία ΦωτογÏαφία Εικόνας (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :Σχετικά με το 'OpenTTD'
+############ range ends here
+
+STR_02DB_OFF :{BLACK}ΑνενεÏγό
+STR_02DA_ON :{BLACK}ΕνεÏγό
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Εμφάνιση χÏηματοδοτήσεων
+STR_02DD_SUBSIDIES :ΧÏηματοδοτήσεις
+STR_02DE_MAP_OF_WORLD :ΧάÏτης του κόσμου
+STR_02DF_TOWN_DIRECTORY :Κατάλογος πόλεων
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Îομισματικές μονάδες
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Επιλογή νομισματικών μονάδων
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_02E6_ROAD_VEHICLES :{BLACK}Οχήματα δÏόμου
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Επιλογή πλευÏάς δÏόμου όπου τα οχήματα οδηγοÏν
+STR_02E9_DRIVE_ON_LEFT :Οδήγηση στα αÏιστεÏά
+STR_02EA_DRIVE_ON_RIGHT :Οδήγηση στα δεξιά
+STR_02EB_TOWN_NAMES :{BLACK}Ονόματα πόλεων
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Επιλογή στυλ ονομάτων πόλεων
+
+STR_02F4_AUTOSAVE :{BLACK}Αυτόματη αποθήκευση
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Επιλογή διάκενου ανάμεσα στις αυτόματες αποθηκεÏσεις
+STR_02F7_OFF :ΑνενεÏγό
+STR_02F8_EVERY_3_MONTHS :Κάθε 3 μήνες
+STR_02F9_EVERY_6_MONTHS :Κάθε 6 μήνες
+STR_02FA_EVERY_12_MONTHS :Κάθε 12 μήνες
+STR_02FB_START_A_NEW_GAME :{BLACK}ΈναÏξη νέου παιχνιδιοÏ
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}ΦόÏτωση αποθηκευμένου παιχνιδιοÏ
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}ΔημιουÏγία Ï€ÏοσαÏμοσμένου κόσμου/σεναÏίου
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Επιλογή Ï€Î±Î¹Ï‡Î½Î¹Î´Î¹Î¿Ï ÎµÎ½ÏŒÏ‚ παίκτη
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Επιλογή Ï€Î±Î¹Ï‡Î½Î¹Î´Î¹Î¿Ï Ï€Î¿Î»Î»ÏŽÎ½ παικτών (2-8)
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Εμφάνιση επιλογών παιχνιδιοÏ
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Εμφάνιση επιλογών δυσκολίας
+STR_0303_START_A_NEW_GAME_USING :{BLACK}ΈναÏξη νέου παιχνιδιοÏ, χÏησιμοποιώντας ένα Ï€ÏοσαÏμοσμένο σενάÏιο
+STR_0304_QUIT :{BLACK}Έξοδος
+STR_0305_QUIT_OPENTTD :{BLACK}Έξοδος από το 'OpenTTD'
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...μποÏεί να χτιστεί μόνο σε πόλεις
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Επιλογή 'ασταθοÏÏ‚' στυλ τοπίου
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Επιλογή 'υπό-αÏκτικοÏ' στυλ τοπίου
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Επιλογή 'υπό-Ï„ÏοπικοÏ' στυλ τοπίου
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Επιλογή 'παιχνιδοÏπολης' στυλ τοπίου
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}ΧÏηματοδοτήστε την κατασκευή νέας βιομηχανίας
+
+############ range for menu starts
+STR_0313_FUND_NEW_INDUSTRY :ΧÏηματοδότηση νέας βιομηχανίας
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}ΧÏηματοδότηση νέας βιομηχανίας
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...μποÏεί να χτιστεί μόνο σε πόλεις
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...μποÏεί να χτιστεί μόνο σε δασώδεις πεÏιοχές
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...μποÏεί να χτιστεί μόνο σε πεÏιοχές με έÏημο
+STR_0319_PAUSED :{YELLOW}* * ΠΑΥΣΗ * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}ΦωτογÏαφία εικόνας αποθηκεÏθηκε επιτυχώς ÏŽÏ‚ '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}ΦωτογÏαφία εικόνας απέτυχε!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}ΑγοÏά γης για μελλοντική χÏήση
+STR_032F_AUTOSAVE :{RED}ΑΥΤΟΜΑΤΗ ΑΠΟΘΗΚΕΥΣΗ
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Επιλογή Ï€ÏογÏάμματος 'Ezy Street στυλ μουσικής'
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+############ end of townname region
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+# end of order system
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+############ network gui strings
+
+
+
+
+
+
+
+
+
+
+
+############ Leave those lines in this order!!
+############ End of leave-in-this-order
+
+
+
+
+
+
+
+############ Leave those lines in this order!!
+
+############ End of leave-in-this-order
+
+
+
+
+############ Leave those lines in this order!!
+############ End of leave-in-this-order
+
+
+
+
+
+############ end network gui strings
+
+
+
+
+##### PNG-MAP-Loader
+
+
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Κόστος: {CURRENCY}
+STR_0801_COST :{RED}Κόστος: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Έσοδα: {CURRENCY}
+STR_0803_INCOME :{GREEN}Έσοδα: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Υπολογιζόμενο Κόστος: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Υπολογιζόμενα Έσοδα: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}ΑδÏνατο να υψωθεί η γη εδώ...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}ΑδÏνατο να χαμηλώσει η γη εδώ...
+STR_080A_ROCKS :ΠέτÏες
+STR_080B_ROUGH_LAND :ΣκληÏÏŒ έδαφος
+STR_080C_BARE_LAND :Γυμνό έδαφος
+STR_080D_GRASS :ΓÏασίδι
+STR_080E_FIELDS :ΧωÏάφια
+STR_080F_SNOW_COVERED_LAND :Χιονισμένο έδαφος
+STR_0810_DESERT :ΈÏημος
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Το έδαφος έχει λάθος κλίση
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}ΑδÏνατος συνδυασμός σιδηÏοδÏόμου
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}Η εκσκαφή θα κατέστÏεφε το τοÏνελ
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Ήδη στο επίπεδο της θάλασσας
+STR_1004_TOO_HIGH :{WHITE}Î Î¿Î»Ï ÏˆÎ·Î»Î¬
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Μη ταιÏιαστός σιδηÏόδÏομος
+STR_1007_ALREADY_BUILT :{WHITE}...ήδη χτισμένο
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}ΠÏέπει να αφαιÏεθεί ο σιδηÏόδÏομος Ï€Ïώτα
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Κατασκευή ΣιδηÏόδÏομου
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Κατασκευή ΟδοντοτοÏ
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}Κατασκευή MagLev
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Επιλογή ΓέφυÏας
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}ΑδÏνατο να χτιστεί αμαξοστάσιο εδώ...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}ΑδÏνατο να χτιστεί σταθμός Ï„Ïένων εδώ...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}ΑδÏνατο να χτιστοÏν σηματοδότες εδώ...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}ΑδÏνατο να χτιστεί σιδηÏόδÏομος εδώ...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}ΑδÏνατο να αφαιÏεθεί σιδηÏόδÏομος από εδώ...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}ΑδÏνατο να αφαιÏεθοÏν σηματοδότες από εδώ...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}ΠÏοσανατολισμός Αμαξοστασίου
+STR_1015_RAILROAD_CONSTRUCTION :Κατασκευή ΣιδηÏόδÏομου
+STR_1016_MONORAIL_CONSTRUCTION :Κατασκευή οδοντοτοÏ
+STR_1017_MAGLEV_CONSTRUCTION :Κατασκευή MagLev
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Κατασκευή σιδηÏόδÏομου
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Κατασκευή αμαξοστασίου (για κατασκευή και επισκευή Ï„Ïένων)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Κατασκευή ÏƒÏ„Î±Î¸Î¼Î¿Ï Ï„Ïένων
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Κατασκευή σηματοδοτών
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Κατασκευή γέφυÏας σιδηÏόδÏομου
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Κατασκευή τοÏνελ σιδηÏόδÏομου
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Εναλλαγή κατασκευής/αφαίÏεσης για σιδηÏόδÏομους και σηματοδότες
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Επιλογή γέφυÏας - κάντε κλικ στην γέφυÏα της Ï€Ïοτίμησής σας για κατασκευή
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Επιλογή Ï€ÏÎ¿ÏƒÎ±Î½Î±Ï„Î¿Î»Î¹ÏƒÎ¼Î¿Ï Î±Î¼Î±Î¾Î¿ÏƒÏ„Î±ÏƒÎ¯Î¿Ï…
+STR_1021_RAILROAD_TRACK :ΣιδηÏόδÏομος
+STR_1023_RAILROAD_TRAIN_DEPOT :Αμαξοστάσιο
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...αυτή η πεÏιοχή είναι ιδιοκτησία άλλης εταιÏείας
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}ΠÏέπει Ï€Ïώτα να αφαιÏεθεί ο δÏόμος
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Κατασκευή ΔÏόμου
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Επιλογή ΓέφυÏας ΔÏόμου
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}ΑδÏνατο να χτιστεί δÏόμος εδώ...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}ΑδÏνατο να αφαιÏεθεί δÏόμος από εδώ...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}ΠÏοσανατοισμός Î£Ï„Î±Î¸Î¼Î¿Ï ÎŸÏ‡Î·Î¼Î¬Ï„Ï‰Î½
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}ΑδÏνατο να χτιστεί σταθμός οχημάτων εδώ...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}ΑδÏνατο να χτιστεί στάση λεωφοÏείων...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}ΑδÏνατο να χτιστεί στάση φοÏτηγών...
+STR_180A_ROAD_CONSTRUCTION :Κατασκευή δÏόμου
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Κατασκευή ÎºÎ¿Î¼Î¼Î±Ï„Î¹Î¿Ï Î´Ïόμου
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Κατασκευή ÏƒÏ„Î±Î¸Î¼Î¿Ï Î¿Ï‡Î·Î¼Î¬Ï„Ï‰Î½ (για κατασκευή και επισκευή οχημάτων)
+STR_180D_BUILD_BUS_STATION :{BLACK}Κατασκευή ÏƒÏ„Î±Î¸Î¼Î¿Ï Î»ÎµÏ‰Ï†Î¿Ïείων
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Κατασκευή ÏƒÏ„Î±Î¸Î¼Î¿Ï Ï†ÏŒÏτωσης φοÏτηγών
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Κατασκευή γέφυÏας δÏόμου
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Κατασκευή τοÏνελ δÏόμου
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Εναλλαγή κατασκευής/αφαίÏεσης για αυτοκινητόδÏομους
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Επιλογή Ï€ÏÎ¿ÏƒÎ±Î½Î±Ï„Î¿Î»Î¹ÏƒÎ¼Î¿Ï ÏƒÏ„Î±Î¸Î¼Î¿Ï Î¿Ï‡Î·Î¼Î¬Ï„Ï‰Î½
+STR_1814_ROAD :ΔÏόμος
+STR_1815_ROAD_WITH_STREETLIGHTS :ΔÏόμος με φωτισμό
+STR_1816_TREE_LINED_ROAD :ΔÏόμος με δέντÏα
+STR_1817_ROAD_VEHICLE_DEPOT :Σταθμός Οχημάτων
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :ΔιασταÏÏωση δÏόμου/σιδηÏόδÏομου
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Πόλεις
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Το κτίÏιο Ï€Ïέπει Ï€Ïώτα να κατεδαφιστεί
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}Πληθυσμός: {ORANGE}{COMMA}{BLACK} Σπίτια: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Μετονομασία Πόλης
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}ΑδÏνατο να μετονομαστεί η πόλη...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} οι τοπικές αÏχές δεν το επιτÏέπουν
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Ονόματα πόλεων - πατήστε στο όνομα για να κεντÏάÏετε την εικόνα στην πόλη
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}ΚεντÏάÏισμα της εικόνας στην τοποθεσία της πόλης
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Αλλαγή ονόματος πόλεως
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Επιβάτες τον Ï€ÏοηγοÏμενο μήνα: {ORANGE}{COMMA}{BLACK} μεγ: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}ΑλληλογÏαφία τον Ï€ÏοηγοÏμενο μήνα: {ORANGE}{COMMA}{BLACK} μεγ: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Ψηλό συγκÏότημα γÏαφείων
+STR_2010_OFFICE_BLOCK :ΣυγκÏότημα γÏαφείων
+STR_2011_SMALL_BLOCK_OF_FLATS :ΜικÏÏŒ συγκÏότημα διαμεÏισμάτων
+STR_2012_CHURCH :Εκκλησία
+STR_2013_LARGE_OFFICE_BLOCK :Μεγάλο συγκÏότημα γÏαφείων
+STR_2014_TOWN_HOUSES :Σπίτια πόλης
+STR_2015_HOTEL :Ξενοδοχείο
+STR_2016_STATUE :Άγαλμα
+STR_2017_FOUNTAIN :ΣυντÏιβάνι
+STR_2018_PARK :ΠάÏκο
+STR_2019_OFFICE_BLOCK :ΣυγκÏότημα ΓÏαφείων
+STR_201A_SHOPS_AND_OFFICES :Καταστήματα και γÏαφεία
+STR_201B_MODERN_OFFICE_BUILDING :ΜοντέÏνο κτίÏιο γÏαφείων
+STR_201C_WAREHOUSE :Αποθήκη
+STR_201D_OFFICE_BLOCK :ΤετÏάγωνο γÏαφείων
+STR_201E_STADIUM :Γήπεδο
+STR_201F_OLD_HOUSES :Παλιά σπίτια
+STR_2020_LOCAL_AUTHORITY :{BLACK}Τοπική αÏχή
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Εμφάνιση πληÏοφοÏιών για την τοπική αÏχή
+STR_2022_LOCAL_AUTHORITY :{WHITE}Τοπική αÏχή της πόλης {TOWN}
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Ποσοστά εταιÏείας μεταφοÏών:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}ΧÏηματοδοτήσεις
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}ΤÏέχουσες χÏηματοδοτήσεις για υπηÏεσίες παίÏνοντας:
+STR_2027_FROM_TO :{ORANGE}{STRING} από {STRING} Ï€Ïός {STRING}
+STR_2028_BY :{YELLOW} (έως {DATE_SHORT})
+STR_202A_NONE :{ORANGE}Κανένα
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}ΥπηÏεσίες που έχουν χÏηματοδοτηθεί:
+STR_202C_FROM_TO :{ORANGE}{STRING} από το σταθμό {STATION} Ï€Ïος το σταθμό {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, έως {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}Έληξε Ï€ÏοσφοÏά χÏηματοδότησης:{}{}{STRING} από {STRING} Ï€Ïός {STRING} δεν θα Ï€ÏοσελκÏουν χÏηματοδότηση πια.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Η χÏηματοδότηση αποσÏÏθηκε:{}{}{STRING} υπηÏεσία {STATION} Ï€Ïος {STATION} δεν χÏηματοδοτείται πια.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}ΠÏοσφοÏά χÏηματοδότησης υπηÏεσίας:{}{}Η Ï€Ïώτη υπηÏεσία για {STRING} από {STRING} Ï€Ïος {STRING} επιχοÏηγείται για ένα έτος από την τοπική αÏχή!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Η επιχοÏήγηση υπηÏεσίας απονεμήθη στην εταιÏεία {COMPANY}!{}{}Η υπηÏεσία για {STRING} από το σταθμό {STATION} Ï€Ïος το σταθμό {STATION} θα χÏεώνεται 50% παÏαπάνω για ένα έτος!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Η επιχοÏήγηση υπηÏεσίας απονεμήθη στην εταιÏεία {COMPANY}!{}{}Η υπηÏεσία για {STRING} από το σταθμό {STATION} Ï€Ïος το σταθμό {STATION} θα χÏεώνεται διπλά για το επόμενο έτος!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Η επιχοÏήγηση υπηÏεσίας απονεμήθη στην εταιÏεία {COMPANY}!{}{}Η υπηÏεσία για {STRING} από το σταθμό {STATION} Ï€Ïος το σταθμό {STATION} θα χÏεώνεται Ï„Ïιπλά για το επόμενο έτος!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Η επιχοÏήγηση υπηÏεσίας απονεμήθη στην εταιÏεία {COMPANY}!{}{}Η υπηÏεσία για {STRING} από το σταθμό {STATION} Ï€Ïος το σταθμό {STATION} θα χÏεώνεται τετÏαπλά για το επόμενο έτος!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}Η τοπική αÏχή της πόλης {TOWN} αÏνείται να επιτÏέψει τη δημιουÏγία νέου αεÏοδÏομίου
+STR_2036_COTTAGES :ΧωÏάφια
+STR_2037_HOUSES :Σπίτια
+STR_2038_FLATS :ΔιαμεÏίσματα
+STR_2039_TALL_OFFICE_BLOCK :Ψηλό συγκÏότημα γÏαφείων
+STR_203A_SHOPS_AND_OFFICES :Καταστήματα και γÏαφεία
+STR_203B_SHOPS_AND_OFFICES :Καταστήματα και γÏαφεία
+STR_203C_THEATER :ΘέατÏο
+STR_203D_STADIUM :Στάδιο
+STR_203E_OFFICES :ΓÏαφεία
+STR_203F_HOUSES :Σπίτια
+STR_2040_CINEMA :ΚινηματογÏάφος
+STR_2041_SHOPPING_MALL :ΕμποÏικό κέντÏο
+STR_2042_DO_IT :{BLACK}Κάνε το
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}Λίστα Ï€Ïαγμάτων που Ï€Ïέπει να γίνουν σε αυτή την πόλη - κάντε κλικ στο αντικείμενο για πληÏοφοÏίες
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}ΔιενέÏγεια της επιλεγμένης Ï€Ïάξης στην παÏαπάνω λίστα
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Διαθέσιμες Ï€Ïάξεις:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :ΜικÏή διαφημιστική καμπάνια
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Μεσαία διαφημιστική καμπάνια
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Μεγάλη διαφημιστική καμπάνια
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :ΕπιχοÏήγηση ανακατασκευής Ï„Î¿Ï€Î¹ÎºÎ¿Ï Î¿Î´Î¹ÎºÎ¿Ï Î´Î¹ÎºÏ„Ïου
+STR_204A_BUILD_STATUE_OF_COMPANY :Χτίσιμο αγάλματος ιδιοκτήτη εταιÏείας
+STR_204B_FUND_NEW_BUILDINGS :ΕπιχοÏήγηση νέων κτιÏίων
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :ΑγοÏά αποκλειστικών δικαιωμάτων μεταφοÏάς
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} ΈναÏξη μικÏής τοπικής διαφημιστικής καμπάνιας, για να Ï€ÏοσελκÏσετε πεÏισσότεÏους επιβάτες και εμποÏεÏματα στις μεταφοÏικές σας υπηÏεσίες.{} Κόστος: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} ΈναÏξη μεσαίας τοπικής διαφημιστικής καμπάνιας, για να Ï€ÏοσελκÏσετε πεÏισσότεÏους επιβάτες και εμποÏεÏματα στις μεταφοÏικές σας υπηÏεσίες.{} Κόστος: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} ΈναÏξη μεγάλης τοπικής διαφημιστικής καμπάνιας, για να Ï€ÏοσελκÏσετε πεÏισσότεÏους επιβάτες και εμποÏεÏματα στις μεταφοÏικές σας υπηÏεσίες.{} Κόστος: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} ΕπιχοÏηγήστε την ανακατασκευή του Ï„Î¿Ï€Î¹ÎºÎ¿Ï Î¿Î´Î¹ÎºÎ¿Ï Î´Î¹ÎºÏ„Ïου. ΠÏοκαλεί σοβαÏή ενόχληση στην τοπικό οδικό δίκτυο για έως 6 μήνες.{} Κόστος: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Χτίστε ένα άγαλμα Ï€Ïος τιμήν της εταιÏείας σας.{} Κόστος: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} ΧÏηματοδοτήστε την κατασκευή νέων εμποÏικών κτιÏίων στην πόλη.{} Κόστος: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} ΑγοÏά αποκλειστικών δικαιωμάτων διάÏκειας 1 χÏόνου για την πόλη. Η τοπική αÏχή θα επιτÏέπει στους επιβάτες και τα φοÏτία να χÏησιμοποιοÏν μόνο τους σταθμοÏÏ‚ της εταιÏείας σας.{} Κόστος: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}Χαώδης κίνηση στην πόλη {TOWN}!{}{}ΧÏηματοδοτήθηκε Ï€ÏόγÏαμμα επανακατασκευής των δÏόμων από την εταιÏεία {COMPANY} και Ï€Ïοκαλεί 6 μήνες μιζέÏιας στους οδηγοÏÏ‚!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (υπό κατασκευή)
+STR_2059_IGLOO :ΙγκλοÏ
+STR_205A_TEPEES :Σκηνές ινδιάνων
+STR_205B_TEAPOT_HOUSE :Σπίτι-ΚαφετιέÏα
+STR_205C_PIGGY_BANK :ΤÏάπεζα-κουμπαÏάς
+
+
+##id 0x2800
+STR_2800_PLANT_TREES :ΦÏτευση δέντÏων
+STR_2801_PLACE_SIGN :Τοποθέτηση σηματοδότη
+STR_2802_TREES :{WHITE}ΔέντÏα
+STR_2803_TREE_ALREADY_HERE :{WHITE}...υπάÏχει ήδη δέντÏο εδώ
+STR_2804_SITE_UNSUITABLE :{WHITE}...ακατάλληλη τοποθεσία
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Δεν γίνεται να φυτευθεί δέντÏο εδώ...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...πάÏα πολλοί σηματοδότες
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Δεν γίνεται να τοποθετηθεί σηματοδότης εδώ...
+STR_280A_SIGN :Πινακίδα
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Αλλαγή κειμένου πινακίδας
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Δεν γίνεται να αλλαχθεί το κείμενο της πινακίδας...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Επιλέξτε Ï„Ïπο δέντÏου για φÏτευση
+STR_280E_TREES :ΔέντÏα
+STR_280F_RAINFOREST :Δάσος
+STR_2810_CACTUS_PLANTS :Κάκτοι
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Επιλογή ΣιδηÏοδÏÎ¿Î¼Î¹ÎºÎ¿Ï Î£Ï„Î±Î¸Î¼Î¿Ï
+STR_3001_AIRPORT_SELECTION :{WHITE}Επιλογή ΑεÏοδÏομίου
+STR_3002_ORIENTATION :{BLACK}ΠÏοσανατολισμός
+STR_3003_NUMBER_OF_TRACKS :{BLACK}ΑÏιθμός γÏαμμών
+STR_3004_PLATFORM_LENGTH :{BLACK}Μήκος ΠλατφόÏμας
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Î Î¿Î»Ï ÎºÎ¿Î½Ï„Î¬ σε άλλο σιδηÏοδÏομικό σταθμό
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}ΓειτονεÏει με πεÏισσότεÏες από μια υπάÏχουσες πεÏιοχές σταθμών/φόÏτωσης
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}ΠάÏα πολλές πεÏιοχές σταθμών/φόÏτωσης σε αυτή την πόλη
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}ΠάÏα πολλές πεÏιοχές σταθμών/φόÏτωσης
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}ΠάÏα πολλές στάσεις λεωφοÏείου
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}ΠάÏα πολλοί σταθμοί φοÏτηγών
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Î Î¿Î»Ï ÎºÎ¿Î½Ï„Î¬ σε μιά άλλη πεÏιοχή σταθμοÏ/φόÏτωσης
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}ΠÏέπει να κατεδαφιστεί ο σιδηÏοδÏομικός σταθμός Ï€Ïώτα
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Î Î¿Î»Ï ÎºÎ¿Î½Ï„Î¬ σε άλλο αεÏοδÏόμιο
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}ΠÏέπει να κατεδαφιστεί το αεÏοδÏόμιο Ï€Ïώτα
+
+STR_3030_RENAME_STATION_LOADING :Μετονομασία πεÏιοχής σταθμοÏ/φόÏτωσης
+STR_3031_CAN_T_RENAME_STATION :{WHITE}ΑδÏνατο να μετονομαστεί ο σταθμός...
+STR_3032_RATINGS :{BLACK}Βαθμολογίες
+STR_3033_ACCEPTS :{BLACK}Δέχεται
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}Τοπική βαθμολογία υπηÏεσίας μεταφοÏάς:
+
+############ range for rating starts
+STR_3035_APPALLING :Απαίσια
+STR_3036_VERY_POOR :Î Î¿Î»Ï ÎšÎ±ÎºÎ®
+STR_3037_POOR :Κακή
+STR_3038_MEDIOCRE :ΜέτÏια
+STR_3039_GOOD :Καλή
+STR_303A_VERY_GOOD :Î Î¿Î»Ï ÎšÎ±Î»Î®
+STR_303B_EXCELLENT :ΕξαιÏετική
+STR_303C_OUTSTANDING :Καταπληκτική
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}Ο σταθμός {STATION} δεν δέχεται πια {STRING}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}Ο σταθμός {STATION} δεν δέχεται πια {STRING} οÏτε {STRING}
+STR_3040_NOW_ACCEPTS :{WHITE}Ο σταθμός {STATION} Ï„ÏŽÏα δέχεται {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}Ο σταθμός {STATION} Ï„ÏŽÏα δέχεται {STRING} και {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}ΠÏοσανατολισμός Στάσης ΛεωφοÏείου
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}ΠÏος. Στάσης ΛεωφοÏείου
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}ΠÏέπει να κατεδαφιστεί η στάσης λεωφοÏείου Ï€Ïώτα
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}ΠÏέπει να κατεδαφιστεί ο σταθμός φοÏτηγών Ï€Ïώτα
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Σταθμός{P "" s}
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Κανένα -
+STR_304B_SITE_UNSUITABLE :{WHITE}...ακατάλληλη τοποθεσία
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Î Î¿Î»Ï ÎºÎ¿Î½Ï„Î¬ σε άλλη αποβάθÏα
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}ΠÏέπει να κατεδαφιστεί η αποβάθÏα Ï€Ïώτα
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Επιλογή Ï€ÏÎ¿ÏƒÎ±Î½Î±Ï„Î¿Î»Î¹ÏƒÎ¼Î¿Ï ÏƒÎ¹Î´Î·ÏοδÏÎ¿Î¼Î¹ÎºÎ¿Ï ÏƒÏ„Î±Î¸Î¼Î¿Ï
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Επιλέξτε τον αÏιθμό πλατφοÏμών για το σιδηÏοδÏομικό σταθμό
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Επιλέξτε το μήκος του σιδηÏοδÏÎ¿Î¼Î¹ÎºÎ¿Ï ÏƒÏ„Î±Î¸Î¼Î¿Ï
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Επιλέξτε τον Ï€Ïοσανατολισμό της στάσης των λεωφοÏείων
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Επιλέξτε τον Ï€Ïοσανατολισμό του χώÏου φόÏτωσης φοÏτηγών
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}ΚεντÏάÏισμα εικόνας στην τοποθεσία του σταθμοÏ
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Εμφάνιση στατιστικών σταθμοÏ
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Αλλαγή ονόματος του σταθμοÏ
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Εμφάνιση λίστας αποδεκτών φοÏτίων
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Ονόματα σταθμών - Κλικ στο όνομα για κεντÏάÏισμα εικόνας
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Επιλογή μεγέθους/Ï„Ïπου αεÏοδÏομίου
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_305E_RAILROAD_STATION :ΣιδηÏοδÏομικός σταθμός
+STR_305F_AIRCRAFT_HANGAR :Υπόστεγο ΑεÏοσκαφών
+STR_3060_AIRPORT :ΑεÏοδÏόμιο
+STR_3061_TRUCK_LOADING_AREA :ΧώÏος φόÏτωσης φοÏτηγών
+STR_3062_BUS_STATION :Στάση λεωφοÏείων
+STR_3063_SHIP_DOCK :ΑποβάθÏα πλοίων
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Εμφάνιση κάλυψης του Ï€ÏοτεινοÏμενου τόπου
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Μη εμφάνιση κάλυψης του Ï€ÏοτεινοÏμενου τόπου
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Κάλυψη πεÏιοχής
+STR_3068_DOCK :{WHITE}Λιμάνι
+STR_3069_BUOY :ΣημαδοÏÏα
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...σημαδοÏÏα στη μέση
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...ο σταθμός είναι υπεÏβολικά απλωμένος
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...ανομοιόμοÏφοι σταθμοί απενεÏγοποιημένοι
+
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}ΠÏοσανατολισμός Αποθήκης Πλοίων
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...Ï€Ïέπει να χτιστεί στο νεÏÏŒ
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}ΑδÏνατο να χτιστεί αποθήκη πλοίων εδώ...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Επιλέξτε τον Ï€Ïοσανατολισμό της αποθήκης πλοίων
+STR_3804_WATER :ÎεÏÏŒ
+STR_3805_COAST_OR_RIVERBANK :Ακτή ή όχθη ποταμοÏ
+STR_3806_SHIP_DEPOT :Αποθήκη πλοίων
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...ΑδÏνατο να χτιστεί στο νεÏÏŒ
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Αποθήκευση ΠαιχνιδιοÏ
+STR_4001_LOAD_GAME :{WHITE}ΦόÏτωση ΠαιχνιδιοÏ
+STR_4002_SAVE :{BLACK}Αποθήκευση
+STR_4003_DELETE :{BLACK}ΔιαγÏαφή
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} megabyte{P "" s} ελεÏθεÏα
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}ΑδÏνατη η ανάγνωση του δίσκου
+STR_4007_GAME_SAVE_FAILED :{WHITE}Αποθήκευση Î Î±Î¹Ï‡Î½Î¹Î´Î¹Î¿Ï Î‘Ï€Î­Ï„Ï…Ï‡Îµ
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}ΑδÏνατη η διαγÏαφή του αÏχείου
+STR_4009_GAME_LOAD_FAILED :{WHITE}ΦόÏτωση Î Î±Î¹Ï‡Î½Î¹Î´Î¹Î¿Ï Î‘Ï€Î­Ï„Ï…Ï‡Îµ
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}Λίστα δίσκων, φακέλλων και αποθηκευμένων παιχνιδιών
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}ΤÏέχον όνομα για το αποθηκευμένο παιχνίδι
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}ΔιαγÏαφή του επιλεγμένου αποθηκευμένου παιχνιδιοÏ
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Αποθήκευση παιχνιδιοÏ, χÏησιμοποιώντας το επιλεγμένο όνομα
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Επιλογή ΤÏπου Îέου ΠαιχνιδιοÏ
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Επιλογή σεναÏίου (Ï€Ïάσινο), Ï€Ïοεπιλεγμένου Ï€Î±Î¹Ï‡Î½Î¹Î´Î¹Î¿Ï (μπλε), ή τυχαίου νέου παιχνιδιοÏ
+STR_4010_GENERATE_RANDOM_NEW_GAME :ΔημιουÏγία τυχαίου νέου παιχνιδιοÏ
+STR_4011_LOAD_HEIGHTMAP :{WHITE}ΦόÏτωση Heightmap
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} στη μέση
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :ΟÏυχείο ΆνθÏακα
+STR_4803_POWER_STATION :Σταθμός ΗλεκτÏισμοÏ
+STR_4804_SAWMILL :ΠÏιονιστήÏιο
+STR_4805_FOREST :Δάσος
+STR_4806_OIL_REFINERY :ΔιυλιστήÏιο
+STR_4807_OIL_RIG :ΠετÏελαιοπηγή
+STR_4808_FACTORY :ΕÏγοστάσιο
+STR_4809_PRINTING_WORKS :ΕÏγασίες ΕκτÏπωσης
+STR_480A_STEEL_MILL :ΧαλυβουÏγείο
+STR_480B_FARM :ΦάÏμα
+STR_480C_COPPER_ORE_MINE :ΟÏυχείο ΜεταλλεÏματος ΧαλκοÏ
+STR_480D_OIL_WELLS :ΠετÏελαιοπηγές
+STR_480E_BANK :ΤÏάπεζα
+STR_480F_FOOD_PROCESSING_PLANT :ΕÏγοστάσιο ΕπεξεÏγασίας ΤÏοφών
+STR_4810_PAPER_MILL :ÎœÏλος ΧαÏτιοÏ
+STR_4811_GOLD_MINE :ΧÏυσοÏυχείο
+STR_4812_BANK :ΤÏάπεζα
+STR_4813_DIAMOND_MINE :ΑδαμαντοÏυχείο
+STR_4814_IRON_ORE_MINE :ΟÏυχείο ΜεταλλεÏματος ΣιδήÏου
+STR_4815_FRUIT_PLANTATION :Φυτεία ΦÏοÏτων
+STR_4816_RUBBER_PLANTATION :Φυτεία Λάστιχου
+STR_4817_WATER_SUPPLY :ΠÏομήθεια ÎεÏοÏ
+STR_4818_WATER_TOWER :ΠÏÏγος ÎεÏοÏ
+STR_4819_FACTORY :ΕÏγοστάσιο
+STR_481A_FARM :ΦάÏμα
+STR_481B_LUMBER_MILL :Υλοτομείο
+STR_481C_COTTON_CANDY_FOREST :Δάσος ÎœÎ±Î»Î»Î¹Î¿Ï Ï„Î·Ï‚ ΓÏιάς
+STR_481D_CANDY_FACTORY :ΕÏγοστάσιο Γλυκών
+STR_481E_BATTERY_FARM :ΦάÏμα ΜπαταÏιών
+STR_481F_COLA_WELLS :Πηγές Κόλα
+STR_4820_TOY_SHOP :Κατάστημα Παιχνιδιών
+STR_4821_TOY_FACTORY :ΕÏγοστάσιο Παιχνιδιών
+STR_4822_PLASTIC_FOUNTAINS :Πηγές ΠλαστικοÏ
+STR_4823_FIZZY_DRINK_FACTORY :ΕÏγοστάσιο Αναψυκτικών
+STR_4824_BUBBLE_GENERATOR :ΓεννήτÏια Φυσαλίδων
+STR_4825_TOFFEE_QUARRY :Λατομείο Τόφυ
+STR_4826_SUGAR_MINE :ΟÏυχείο ΖάχαÏης
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Απαιτεί: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Απαιτεί: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Απαιτεί: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}ΠαÏαγωγή Ï€ÏοηγοÏμενου μήνα:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% μεταφέÏθηκαν)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}ΚεντÏάÏισμα εικόνας στην πεÏιοχή της βιομηχανίας
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Îέο {STRING} υπό κατασκευή κοντά στην πόλη {TOWN}!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Îέα {STRING} φυτεÏεται κοντά στην πόλη {TOWN}!
+STR_482F_COST :{BLACK}Κόστος: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}ΑδÏνατο να χτιστεί αυτός ο Ï„Ïπος βιομηχανίας εδώ...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...το δάσος μποÏεί να φυτευτεί μόνο πάνω από την γÏαμμή χιονιοÏ
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}Η βιομηχανία {INDUSTRY} ανακοίνωσε άμεσο κλείσιμο!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}ΠÏοβλήματα στην Ï€Ïομήθεια αναγκάζουν την εταιÏεία {INDUSTRY} να κλείσει αμέσως!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}Η έλλειψη δέντÏων αναγκάζει την βιομηχανία {INDUSTRY} να κλείσει αμέσως!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}Η βιομηχανία {INDUSTRY} ανεβάζει την παÏαγωγή!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}Îέα φλέβα άνθÏακα βÏέθηκε στο {INDUSTRY}!{}Η παÏαγωγή αναμένεται να διπλασιαστεί!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}Îέα αποθέματα πετÏελαίου βÏέθηκαν στην {INDUSTRY}!{}Η παÏαγωγή αναμένεται να διπλασιαστεί!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}Βελτιωμένες μέθοδοι καλλιέÏγειας στην {INDUSTRY} αναμένεται να διπλασιάσουν την παÏαγωγή!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}Η παÏαγωγή στο/στη {INDUSTRY} μειώθηκε κατά 50%
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}Μόλυνση από έντομα Ï€Ïοκαλεί καταστÏοφή στη {INDUSTRY}!{}Η παÏαγωγή μειώθηκε κατά 50%
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...μποÏοÏν να τοποθετηθοÏν μόνο στις άκÏες του χάÏτη
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}ΤÏένο στο τοÏνελ
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Όχημα στο τοÏνελ
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Άλλο τουνελ στη μέση
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}ΑδÏνατο να γίνει εκσκαφή γης στην άλλη άκÏη του τοÏνελ
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}ΠÏέπει Ï€Ïώτα να καταστÏαφεί το τοÏνελ
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}ΠÏέπει Ï€Ïώτα να καταστÏαφεί η γέφυÏα
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Δεν γίνεται να ξεκινάει και να τελειώνει στο ίδιο σημείο
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Απαιτείται επίπεδο έδαφος ή νεÏÏŒ κάτω από τη γέφυÏα
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}Η αÏχή και το τέλος Ï€Ïέπει να είναι σε ευθεία
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Ακατάλληλη τοποθεσία για είσοδο τοÏνελ
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Ατσάλινη, με ΑναÏτήσεις
+STR_500F_GIRDER_STEEL :Με ΔοκοÏÏ‚, Ατσάλινη
+STR_5010_CANTILEVER_STEEL :ΚÏεμαστή, Ατσάλινη
+STR_5011_SUSPENSION_CONCRETE :Με αναÏτήσεις, Τσιμεντένια
+STR_5012_WOODEN :ΞÏλινη
+STR_5013_CONCRETE :Τσιμεντένια
+STR_5014_TUBULAR_STEEL :ΦυσοÏνα, Ατσάλινη
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}ΑδÏνατο να χτιστεί γέφυÏα εδώ...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}ΑδÏνατο να χτιστεί τοÏνελ εδώ...
+STR_5017_RAILROAD_TUNNEL :ΤοÏνελ σιδηÏόδÏομου
+STR_5018_ROAD_TUNNEL :ΤοÏνελ δÏόμου
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Ατσάλινη σιδηÏοδÏομική γέφυÏα με αναÏτήσεις
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Ατσάλινη σιδηÏοδÏομική γέφυÏα με δοκοÏÏ‚
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Ατσάλινη κÏεμαστή σιδηÏοδÏομική γέφυÏα
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :ΣιδηÏοδÏομική γέφυÏα από ενισχυμένο τσιμέντο
+STR_501F_WOODEN_RAIL_BRIDGE :ΞÏλινη σιδηÏοδÏομική γέφυÏα
+STR_5020_CONCRETE_RAIL_BRIDGE :Τσιμεντένια σιδηÏοδÏομική γέφυÏα
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Ατσάλινη γέφυÏα δÏόμου με αναÏτήσεις
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Ατσάλινη γέφυÏα δÏόμου με δοκοÏÏ‚
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Ατσάλινη κÏεμαστή γέφυÏα δÏόμου
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :ΓέφυÏα δÏόμου από ενισχυμένο τσιμέντο
+STR_5025_WOODEN_ROAD_BRIDGE :ΞÏλινη γέφυÏα δÏόμου
+STR_5026_CONCRETE_ROAD_BRIDGE :Τσιμεντένια γέφυÏα δÏόμου
+STR_5027_TUBULAR_RAIL_BRIDGE :ΚυλινδÏική σιδηÏοδÏομική γέφυÏα
+STR_5028_TUBULAR_ROAD_BRIDGE :ΚυλινδÏική γέφυÏα δÏόμου
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Αντικείμενο στη μέση
+STR_5801_TRANSMITTER :Αναμεταδότης
+STR_5802_LIGHTHOUSE :ΦάÏος
+STR_5803_COMPANY_HEADQUARTERS :ΚεντÏικά ΓÏαφεία ΕταιÏείας
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...κεντÏικά γÏαφεία εταιÏείας στη μέση
+STR_5805_COMPANY_OWNED_LAND :Ιδιόκτητη γή από εταιÏεία
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}ΑδÏνατο να αγοÏαστεί το έδαφος...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...είστε ήδη ιδιοκτήτης!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Βαθμός Δυσκολίας
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}ΕÏκολο
+STR_6802_MEDIUM :{BLACK}ΜέτÏιο
+STR_6803_HARD :{BLACK}ΔÏσκολο
+STR_6804_CUSTOM :{BLACK}ΠαÏαμετÏοποιήσιμο
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}Μέγιστος αÏ. αντιπάλων: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}ΈναÏξη αντιπάλου: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}ΑÏ. πόλεων: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}ΑÏ. βιομηχανιών: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Μέγιστο αÏχικό δάνειο: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}ΑÏχικό επιτόκιο: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Έξοδα συντήÏησης οχημάτων: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}ΤαχÏτητα κατασκευής αντιπάλων: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}ÎοημοσÏνη αντιπάλων: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Βλάβες οχημάτων: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Πολλαπλασιαστής χÏηματοδότησης: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Κόστος κατασκευής: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}ΤÏπος εδάφους: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Ποσότητα θάλασσας/λιμνών: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Οικονομικά: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}ΠεÏιστÏοφή Ï„Ïένων: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}ΚαταστÏοφές: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Θέση δημαÏÏ‡Î¹Î±ÎºÎ¿Ï ÏƒÏ…Î¼Î²Î¿Ï…Î»Î¯Î¿Ï… σχετικά με την αναδόμηση της πόλης: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :Κανένα
+STR_6816_LOW :Χαμηλό
+STR_6817_NORMAL :Κανονικό
+STR_6818_HIGH :Υψηλό
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Î Î¿Î»Ï Î±Ïγό
+STR_681C_SLOW :ΑÏγό
+STR_681D_MEDIUM :ΜέτÏιο
+STR_681E_FAST :ΓÏήγοÏο
+STR_681F_VERY_FAST :Î Î¿Î»Ï Î“ÏήγοÏο
+STR_6820_LOW :Χαμηλό
+STR_6821_MEDIUM :ΜέτÏιο
+STR_6822_HIGH :Υψηλό
+STR_6823_NONE :Κανένα
+STR_6824_REDUCED :Μειωμένο
+STR_6825_NORMAL :Κανονικό
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Î Î¿Î»Ï ÎµÏ€Î¯Ï€ÎµÎ´Î·
+STR_682B_FLAT :Επίπεδη
+STR_682C_HILLY :Με λόφους
+STR_682D_MOUNTAINOUS :Με βουνά
+STR_682E_STEADY :ΣταθεÏή
+STR_682F_FLUCTUATING :Κυμαινόμενη
+STR_6830_IMMEDIATE :Αμέσως
+STR_6831_3_MONTHS_AFTER_PLAYER :3 μήνες μετά τον παίκτη
+STR_6832_6_MONTHS_AFTER_PLAYER :6 μήνες μετά τον παίκτη
+STR_6833_9_MONTHS_AFTER_PLAYER :9 μήνες μετά τον παίκτη
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :Στο τέλος της γÏαμμής και στους σταθμοÏÏ‚
+STR_6835_AT_END_OF_LINE_ONLY :Στο τέλος της γÏαμμής μόνο
+STR_6836_OFF :ΑνενεÏγό
+STR_6837_ON :ΕνεÏγό
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Εμφάνιση γÏαφήματος καλÏτεων βαθμολογιών
+STR_6839_PERMISSIVE :Ανεκτικό
+STR_683A_TOLERANT :Υπομονετικό
+STR_683B_HOSTILE :ΕχθÏικό
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Παίκτης {COMMA})
+STR_7004_NEW_FACE :{BLACK}Îέο ΠÏόσωπο
+STR_7005_COLOR_SCHEME :{BLACK}ΧÏωματισμός
+STR_7006_COLOR_SCHEME :{GOLD}ΧÏωματισμός:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Îέος ΧÏωματισμός
+STR_7008_COMPANY_NAME :{BLACK}Όνομα ΕταιÏείας
+STR_7009_PRESIDENT_NAME :{BLACK}Όνομα Διευθυντή
+STR_700A_COMPANY_NAME :Όνομα ΕταιÏείας
+STR_700B_PRESIDENT_S_NAME :Όνομα Διευθυντή
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}ΑδÏνατο να αλλάξει το όνομα της εταιÏείας...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}ΑδÏνατο να αλλάξει το όνομα του διευθυντή...
+STR_700E_FINANCES :{WHITE}{COMPANY} Οικονομικά {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Έξοδα/Έσοδα
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Κατασκευή
+STR_7012_NEW_VEHICLES :{GOLD}Îέα Οχήματα
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}ΤÏεχοÏμενα Έξοδα ΤÏέν.
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}ΤÏεχοÏμενα Έξοδα Οχημ.
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}ΤÏεχοÏμενα Έξοδα ΑεÏοπ.
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}ΤÏεχοÏμενα Έξοδα Πλοίων
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}ΣυντήÏηση Ιδιοκτησίας
+STR_7018_TRAIN_INCOME :{GOLD}Έσοδα ΤÏένων
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Έσοδα Οχημάτων
+STR_701A_AIRCRAFT_INCOME :{GOLD}Έσοδα ΑεÏοπλάνων
+STR_701B_SHIP_INCOME :{GOLD}Έσοδα Πλοίων
+STR_701C_LOAN_INTEREST :{GOLD}Τόκος Δανείου
+STR_701D_OTHER :{GOLD}Άλλα
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}ΣÏνολο:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}ΓÏάφημα Εισοδήματος
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}ΓÏάφημα ΕνεÏγών Εσόδων
+STR_7026_BANK_BALANCE :{WHITE}Ισολογισμός ΤÏαπέζης
+STR_7027_LOAN :{WHITE}Δάνειο
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}Δανεισμός {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}ΠληÏωμή {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...το μέγιστο επιτÏεπόμενο δάνειο είναι {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}ΑδÏνατος ο δανεισμός πεÏισσοτέÏων χÏημάτων...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...δεν υπάÏχει δάνειο Ï€Ïος αποπληÏωμή
+STR_702E_REQUIRED :{WHITE}...ΑπαιτοÏνται {CURRENCY}
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}ΑδÏνατη η αποπληÏωμή του δανείου...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Επιλογή νέου Ï€Ïοσώπου διευθυντή
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Αλλαγή της εμφάνισης των οχημάτων της εταιÏείας
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Αλλαγή του ονόματος του διευθυντή
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Αλλαγή του ονόματος της εταιÏείας
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Κάντε κλικ στο χÏωματισμό της επιλογής σας
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}ΑÏξηση του μεγέθους του δανείου
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}ΑποπληÏωμή μέÏους του δανείου
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(Manager)
+STR_7038_INAUGURATED :{GOLD}Εγκαινιασμένος: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Οχήματα:
+STR_7042_NONE :{WHITE}Κανένα
+STR_7043_FACE_SELECTION :{WHITE}Επιλογή ΠÏοσώπου
+STR_7044_MALE :{BLACK}ΑÏσενικό
+STR_7045_FEMALE :{BLACK}Θηλυκό
+STR_7046_NEW_FACE :{BLACK}Îέο ΠÏόσωπο
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}ΑκÏÏωση επιλογής νέου Ï€Ïοσώπου
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Αποδοχή νέου Ï€Ïοσώπου
+STR_7049_SELECT_MALE_FACES :{BLACK}Επιλογή αÏσενικών Ï€Ïοσώπων
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Επιλογή θηλυκών Ï€Ïοσώπων
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}ΔημιουÏγία τυχαίου Ï€Ïοσώπου
+STR_704C_KEY :{BLACK}Κλειδί
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Εμφάνιση ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï ÏƒÏ„Î± γÏαφήματα
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}ΓÏαφήματα ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï ÎµÏ„Î±Î¹Ïείας
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Κάντε κλικ εδώ για ενναλαγή εμφάνισης της εταιÏείας στο γÏάφημα
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Μονάδες φοÏτίου που παÏαδόθηκαν
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Ποσοστά απόδοσης εταιÏείας (μέγιστη τιμή=1000)
+STR_7052_COMPANY_VALUES :{WHITE}Αξία εταιÏείας
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Πίνακας ΠÏωταθλήματος ΕταιÏειών
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}ΕταιÏεία μεταφοÏών σε μπελάδες!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}Η εταιÏεία {COMPANY} θα πωληθεί ή θα κυÏήξει πτώχευση αν δεν αυξηθεί η απόδοσή της!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(Διευθυντής)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Συγχώνευση εταιÏειών μεταφοÏάς!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}Η εταιÏεία {COMPANY} πουλήθηκε στην {COMPANY} για το ποσό των {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Ψάχνουμε μία εταιÏεία μεταφοÏών για να αναλάβει την εταιÏεία μας.{}{}Θέλετε να αγοÏάσετε την {COMPANY} για {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}ΧÏεωκοπία!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}Η {COMPANY} έκλεισε από τους επενδυτές και όλα εκποιήθηκαν!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}ΊδÏυση νέας εταιÏείας μεταφοÏών!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}Η {COMPANY} ξεκινά τις κατασκευές κοντά στην πόλη {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}ΑδÏνατη η εξαγοÏά της εταιÏείας...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Ποσοστά ΠληÏωμής ΦοÏτίων
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}ΜέÏες σε μεταφοÏά
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}ΠληÏωμή για την παÏάδοση 10 μονάδων (ή 10.000 λίτÏων) φοÏτίου σε απόσταση 20 τετÏαγώνων
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Ενναλαγή γÏαφήματος Ï„Ïπου φοÏτίου
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Μηχανικός
+STR_7067_TRAFFIC_MANAGER :ΔιαχειÏιστής ΚυκλοφοÏίας
+STR_7068_TRANSPORT_COORDINATOR :Συντονιστής ΜεταφοÏών
+STR_7069_ROUTE_SUPERVISOR :Επόπτης ΔιαδÏομών
+STR_706A_DIRECTOR :Διευθυντής
+STR_706B_CHIEF_EXECUTIVE :ΑνώτεÏος Υπάλληλος
+STR_706C_CHAIRMAN :ΔιαχειÏιστής
+STR_706D_PRESIDENT :ΠÏόεδÏος
+STR_706E_TYCOON :Μεγιστάνας
+STR_706F_BUILD_HQ :{BLACK}Χτίσιμο ΑÏχηγείου
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Χτίστιμο αÏχηγείου εταιÏείας / Ï€Ïοβολή αÏχηγείου
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}ΑδÏνατο να χτιστεί αÏχηγείο εταιÏείας...
+STR_7072_VIEW_HQ :{BLACK}ΠÏοβολή ΑÏχηγείου
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}Παγκόσμια ΥποχώÏηση!{}{}Οι οικονομολόγοι φοβοÏνται τα χειÏότεÏα καθώς η οικονομία πιάνει πάτο!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}ΥποχώÏηση Τέλος!{}{}ΚέÏδη στο εμπόÏιο δίνει σιγουÏιά στις βιομηχανίες καθώς η οικονομία δυναμώνει!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Εναλλαγή μεγάλου/μικÏÎ¿Ï Ï€Î±ÏαθÏÏου
+STR_7076_COMPANY_VALUE :{GOLD}Αξία εταιÏείας: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}ΑγοÏά μεÏιδίου 25% στην εταιÏεία
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Πώληση μεÏιδίου 25% της εταιÏείας
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}ΑγοÏά μεÏιδίου 25% της εταιÏείας
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Πώληση μεÏιδίου 25% της εταιÏείας
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}ΑδÏνατη η αγοÏά μεÏιδίου 25% της εταιÏείας...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}ΑδÏνατη η πώληση μεÏιδίου 25% της εταιÏείας...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% είναι ιδιοκτησία της {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% είναι ιδιοκτησία της εταιÏείας {COMPANY}{} {COMMA}% ιδιοκτησία της {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}Η {COMPANY} εξαγοÏάστηκε από την {COMPANY}!
+STR_7080_PROTECTED :{WHITE}Αυτή η εταιÏεία δεν είναι αÏκετά ÏŽÏιμη για συναλλαγή μετοχών ακόμα...
+
+
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (Ατμοκίνητο)
+STR_8001_MJS_250_DIESEL :MJS 250 (ΠετÏελαίου)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut ΠετÏελαίου
+STR_8006_POWERNAUT_DIESEL :Powernaut ΠετÏελαίου
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (Ατμοκίνητο)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (Ατμοκίνητο)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (Ατμοκίνητο)
+STR_800A_SH_8P_STEAM :SH '8P' (Ατμοκίνητο)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (ΠετÏελαίου)
+STR_800C_DASH_DIESEL :'Dash' (ΠετÏελαίου)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (ΠετÏελαίου)
+STR_800E_UU_37_DIESEL :UU '37' (ΠετÏελαίου)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (ΠετÏελαίου)
+STR_8010_CS_4000_DIESEL :CS 4000 (ΠετÏελαίου)
+STR_8011_CS_2400_DIESEL :CS 2400 (ΠετÏελαίου)
+STR_8012_CENTENNIAL_DIESEL :Centennial (ΠετÏελαίου)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (ΠετÏελαίου)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (ΠετÏελαίου)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (ΠετÏελαίου)
+STR_8016_SH_125_DIESEL :SH '125' (ΠετÏελαίου)
+STR_8017_SH_30_ELECTRIC :SH '30' (ΗλεκτÏικό)
+STR_8018_SH_40_ELECTRIC :SH '40' (ΗλεκτÏικό)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (ΗλεκτÏικό)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (ΗλεκτÏικό)
+STR_801B_PASSENGER_CAR :Βαγόνι επιβατών
+STR_801C_MAIL_VAN :Βαγόνι ΑλληλογÏαφίας
+STR_801D_COAL_CAR :ΦοÏτηγίδα ΆνθÏακα
+STR_801E_OIL_TANKER :Βυτίο ΠετÏελαίου
+STR_801F_LIVESTOCK_VAN :Βαγόνι Ζώων
+STR_8020_GOODS_VAN :Βαγόνι Αγαθών
+STR_8021_GRAIN_HOPPER :ΦοÏτηγίδα ΣιταÏιοÏ
+STR_8022_WOOD_TRUCK :ΦοÏτηγίδα Ξυλείας
+STR_8023_IRON_ORE_HOPPER :ΦοÏτηγίδα ΣιδήÏου
+STR_8024_STEEL_TRUCK :ΦοÏτηγίδα Χάλυβα
+STR_8025_ARMORED_VAN :ΤεθωÏακισμένο Βαγόνι
+STR_8026_FOOD_VAN :Βαγόνι ΤÏοφίμων
+STR_8027_PAPER_TRUCK :ΦοÏτηγίδα ΧαÏτιοÏ
+STR_8028_COPPER_ORE_HOPPER :ΦοÏτηγίδα ΧαλκοÏ
+STR_8029_WATER_TANKER :Βυτίο ÎεÏοÏ
+STR_802A_FRUIT_TRUCK :ΦοÏτηγίδα ΦÏοÏτων
+STR_802B_RUBBER_TRUCK :ΦοÏτηγίδα Λάστιχου
+STR_802C_SUGAR_TRUCK :ΦοÏτηγίδα ΖάχαÏης
+STR_802D_COTTON_CANDY_HOPPER :ΦοÏτηγίδα ÎœÎ±Î»Î»Î¹Î¿Ï Ï„Î·Ï‚ ΓÏιάς
+STR_802E_TOFFEE_HOPPER :ΦοÏτηγίδα Τόφυ
+STR_802F_BUBBLE_VAN :Βαγόνι Φυσαλίδων
+STR_8030_COLA_TANKER :Βυτίο Κόλα
+STR_8031_CANDY_VAN :Βαγόνι Γλυκών
+STR_8032_TOY_VAN :Βαγόνι Παιχνιδιών
+STR_8033_BATTERY_TRUCK :ΦοÏτηγίδα ΜπαταÏιών
+STR_8034_FIZZY_DRINK_TRUCK :ΦοÏτηγίδα Αναψυκτικών
+STR_8035_PLASTIC_TRUCK :ΦοÏτηγίδα ΠλαστικοÏ
+STR_8036_X2001_ELECTRIC :'X2001' (ΗλεκτÏικό)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (ΗλεκτÏικό)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+
+##id 0x8800
+
+
+
+
+
+
+
+
+##id 0x9000
+
+
+
+##id 0x9800
+
+SERVICE_AT_SHIP_DEPOT :Επισκευή στη Λιμεναποθήκη της πόλης {TOWN}
+
+##id 0xA000
+
+SERVICE_AT_AIRPORT_HANGAR :Επισκευή στο υπόστεγο {STATION}
+
+##id 0xB000
+
+
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}.
+############ Those following lines need to be in this order!!
+############ End of order list
+
+
+
+
+
+
+
+
+
+
+### depot strings
+
+
+
+
+
+
+
+
+
+
+
+
+############ Lists rail types
+
+
+############ End of list of rail types
+
+
+
+########### String for New Landscape Generator
+
+
+
+########### String for new airports
+
+
+############ Tooltip measurment
+
+
+########
diff --git a/src/lang/unfinished/japanese.txt b/src/lang/unfinished/japanese.txt
new file mode 100644
index 000000000..586ab0e64
--- /dev/null
+++ b/src/lang/unfinished/japanese.txt
@@ -0,0 +1,1436 @@
+##name Japanese
+##ownname 日本語
+##isocode ja_JP.UTF-8
+##plural 1
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}地図ã®ã‚¨ãƒƒã‚¸ã¯ã¡ã‚‡ã£ã¨è¿‘ã„ã§ã™
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}地図ã®ã‚¨ãƒƒã‚¸ã¯ã¡ã‚‡ã£ã¨è¿‘ã„ã§ã™
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}ãŠé‡‘ã¯ã‚ã‚Šã¾ã›ã‚“。{CURRENCY}ãŒã‹ã‹ã‚Šã¾ã™
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}å¹³ãŸã„地é¢ãŒã‹ã‹ã‚Šã¾ã™
+STR_0008_WAITING :{BLACK}å¾…ã£ã¦ã„ã¾ã™ï¼š {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}å—ã‘å–れる事ã¯ï¼š {WHITE}
+STR_000D_ACCEPTS :{BLACK}å—ã‘å–れる事ã¯ï¼š {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :乗客
+STR_0010_COAL :石炭
+STR_0011_MAIL :郵便物
+STR_0012_OIL :原油
+STR_0013_LIVESTOCK :家畜
+STR_0014_GOODS :商å“
+STR_0015_GRAIN :穀物
+STR_0016_WOOD :木æ
+STR_0017_IRON_ORE :鉄鉱
+STR_0018_STEEL :鋼鉄
+STR_0019_VALUABLES :è²´é‡å“
+STR_001A_COPPER_ORE :銅鉱
+STR_001B_MAIZE :トウモロコシ
+STR_001C_FRUIT :果物
+STR_001D_DIAMONDS :ダイヤモンド
+STR_001E_FOOD :食ã¹ç‰©
+STR_001F_PAPER :ç´™
+STR_0020_GOLD :金
+STR_0021_WATER :æ°´
+STR_0022_WHEAT :å°éº¦
+STR_0023_RUBBER :ゴム
+STR_0024_SUGAR :ç ‚ç³–
+STR_0025_TOYS :ãŠã‚‚ã¡ã‚ƒ
+STR_0026_CANDY :ãŠè“å­
+STR_0027_COLA :コーラ
+STR_0028_COTTON_CANDY :綿ã‚ã‚
+STR_0029_BUBBLES :泡
+STR_002A_TOFFEE :タフィー
+STR_002B_BATTERIES :乾電池
+STR_002C_PLASTIC :プラスãƒã‚¯
+STR_002D_FIZZY_DRINKS :清涼飲料水
+STR_002E :
+STR_002F_PASSENGER :乗客
+STR_0030_COAL :石炭
+STR_0031_MAIL :郵便物
+STR_0032_OIL :原油
+STR_0033_LIVESTOCK :家畜
+STR_0034_GOODS :商å“
+STR_0035_GRAIN :穀物
+STR_0036_WOOD :木æ
+STR_0037_IRON_ORE :鉄鉱
+STR_0038_STEEL :鋼鉄
+STR_0039_VALUABLES :è²´é‡å“
+STR_003A_COPPER_ORE :銅鉱
+STR_003B_MAIZE :トウモロコシ
+STR_003C_FRUIT :果物
+STR_003D_DIAMOND :ダイヤモンド
+STR_003E_FOOD :食ã¹ç‰©
+STR_003F_PAPER :ç´™
+STR_0040_GOLD :金
+STR_0041_WATER :æ°´
+STR_0042_WHEAT :å°éº¦
+STR_0043_RUBBER :ゴム
+STR_0044_SUGAR :ç ‚ç³–
+STR_0045_TOY :ãŠã‚‚ã¡ã‚ƒ
+STR_0046_CANDY :ãŠè“å­
+STR_0047_COLA :コーラ
+STR_0048_COTTON_CANDY :綿ã‚ã‚
+STR_0049_BUBBLE :泡
+STR_004A_TOFFEE :タフィー
+STR_004B_BATTERY :乾電池
+STR_004C_PLASTIC :プラスãƒã‚¯
+STR_004D_FIZZY_DRINK :清涼飲料水
+STR_QUANTITY_NOTHING :
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}åœ°å›³ï¼ {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}ゲーム設定
+STR_00B2_MESSAGE :{YELLOW}メッセージ
+STR_00B3_MESSAGE_FROM :{YELLOW} {STRING}ã‹ã‚‰ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸
+STR_00B4_CAN_T_DO_THIS :{WHITE}出æ¥ã¾ã›ã‚“
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}ãã®æ‰€ã‚’空ã‘ã¾ã›ã‚“
+STR_00B7_VERSION :{BLACK}OpenTTD ãƒãƒ¼ã‚¸ãƒ§ãƒ³ {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 The OpenTTD team
+STR_TRANSLATED_BY :{BLACK} 訳者ï¼
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C8_YES :{BLACK}ã¯ã„
+STR_00C9_NO :{BLACK}ã„ã„ãˆ
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :何も
+STR_00D1_DARK_BLUE :ç´ºé’色
+STR_00D2_PALE_GREEN :薄緑色
+STR_00D3_PINK :ピンク
+STR_00D4_YELLOW :黄色
+STR_00D5_RED :赤色
+STR_00D6_LIGHT_BLUE :è–„é’色
+STR_00D7_GREEN :緑色
+STR_00D8_DARK_GREEN :濃緑色
+STR_00D9_BLUE :é’色
+STR_00DA_CREAM :クリーム色
+STR_00DB_MAUVE :藤色
+STR_00DC_PURPLE :紫色
+STR_00DD_ORANGE :オレンジ色
+STR_00DE_BROWN :茶色
+STR_00DF_GREY :ç°è‰²
+STR_00E0_WHITE :白色
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}ゲームã®ãƒã‚¹ï¼ãƒˆãƒ©ãƒƒã‚¯æ•°ã®åˆ¶é™ã‚’超ãˆã¦ã„ã¾ã™
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}見付ã‘ã¾ã™
+STR_00E7_INDUSTRIES :産業
+STR_00E8_ROUTES :経路
+STR_00E9_VEGETATION :æ¤ç‰©
+STR_00EB_ROADS :{BLACK}{TINYFONT}é“è·¯
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}鉄é“
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}駅ï¼ç©ºæ¸¯ï¼æ³¢æ­¢å ´
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}建物ï¼ç”£æ¥­
+STR_00F0_100M :{BLACK}{TINYFONT}100m
+STR_00F1_200M :{BLACK}{TINYFONT}200m
+STR_00F2_300M :{BLACK}{TINYFONT}300m
+STR_00F3_400M :{BLACK}{TINYFONT}400m
+STR_00F4_500M :{BLACK}{TINYFONT}500m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}電車
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}ãƒã‚¹ï¼ãƒˆãƒ©ãƒƒã‚¯
+STR_00F7_SHIPS :{BLACK}{TINYFONT}船
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}飛行機
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}é‹é€çµŒè·¯
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}ç‚­å‘
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}発電所
+STR_00FC_FOREST :{BLACK}{TINYFONT}森林
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}製æ工場
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}製油所
+STR_00FF_FARM :{BLACK}{TINYFONT} 農場
+STR_0100_FACTORY :{BLACK}{TINYFONT} 工場
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}å°åˆ·æ‰€
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}油井
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}鉄鉱石鉱山
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}製鋼所
+STR_0105_BANK :{BLACK}{TINYFONT}銀行
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}製紙工場
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}金鉱
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}食å“加工場
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}ダイヤモンド鉱山
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}銅鉱山
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}果物農園
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}ゴム園
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}給水設備
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}給水塔
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}製æ所
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}綿è“å­
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}ãŠè“å­å·¥å ´
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}電池農園
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}コーラ泉
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}玩具店
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}玩具工場
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}プラスãƒãƒƒã‚¯æ³‰
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}ソーダ工場
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}泡ã®ç™ºç”Ÿå™¨
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}トッフィー採石場
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}砂糖鉱山
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}駅
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}トラックè·å½¹æ‰€
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}ãƒã‚¹åœ
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}空港ï¼ãƒ˜ãƒªãƒãƒ¼ãƒˆ
+STR_011F_DOCK :{BLACK}{TINYFONT}波止場
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}ã§ã“ã¼ã“ã®åœŸåœ°
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}è‰åœ°
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}裸地
+STR_0123_FIELDS :{BLACK}{TINYFONT}ç”°ç•‘
+STR_0124_TREES :{BLACK}{TINYFONT}木
+STR_0125_ROCKS :{BLACK}{TINYFONT}
+STR_0126_WATER :{BLACK}{TINYFONT}æ°´
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}所有者ãªã—
+STR_0128_TOWNS :{BLACK}{TINYFONT}町
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}産業
+STR_012A_DESERT :{BLACK}{TINYFONT}ç ‚æ¼ 
+STR_012B_SNOW :{BLACK}{TINYFONT}雪
+STR_012C_MESSAGE :{WHITE}メッセージ
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}キャンセル
+STR_012F_OK :{BLACK}OK
+STR_0130_RENAME :{BLACK}å称を変更
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}å称定義数ã®åˆ¶é™ã‚’超ãˆã¦ã„ã¾ã™
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}指定ã—ãŸå称ã¯æ—¢ã«ä½¿ç”¨ä¸­ã§ã™
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+
+STR_013B_OWNED_BY :{WHITE}...所有者㯠{STRING}
+STR_013C_CARGO :{BLACK}貨物
+STR_013D_INFORMATION :{BLACK}情報
+STR_013E_CAPACITIES :{BLACK}容é‡
+STR_013E_TOTAL_CARGO :{BLACK}åˆè¨ˆè²¨ç‰©
+STR_013F_CAPACITY :{BLACK}容é‡ï¼š{LTBLUE}{CARGO}
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}ã“ã®é›»è»Šã®è²¨ç‰©æœ€å¤§å®¹é‡ï¼š
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}æ–°ã—ã„ゲーム
+STR_0141_LOAD_GAME :{BLACK}ゲームを開ã
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}ゲームã®è¨­å®š
+
+STR_0150_SOMEONE :誰ã‹ã¯{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :世界ã®åœ°å›³
+STR_0152_TOWN_DIRECTORY :町ã®ãƒªã‚¹ãƒˆ
+STR_0153_SUBSIDIES :助æˆé‡‘
+
+STR_UNITS_METRIC :メートル法
+
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}ホースãƒãƒ¯ãƒ¼
+STR_UNITS_POWER_METRIC :{COMMA}ホースãƒãƒ¯ãƒ¼
+STR_UNITS_POWER_SI :{COMMA}キロワット
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}トン
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}トン
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}キロ
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} 英トン
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} ä»ãƒˆãƒ³
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} キロ
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}ガロン
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}リットル
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}m³
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} ガロン
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} リットル
+STR_UNITS_VOLUME_LONG_SI :{COMMA} m³
+
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :営業利益
+STR_0155_INCOME_GRAPH :所得グラフ
+STR_0156_DELIVERED_CARGO_GRAPH :é‹é€ã—ãŸè²¨ç‰©ã®ã‚°ãƒ©ãƒ•
+STR_0157_PERFORMANCE_HISTORY_GRAPH :æˆç¸¾ã‚°ãƒ©ãƒ•
+STR_0158_COMPANY_VALUE_GRAPH :会社価値グラフ
+STR_0159_CARGO_PAYMENT_RATES :貨物é‹é€æ–™
+STR_015A_COMPANY_LEAGUE_TABLE :会社ã®æˆç¸¾è¡¨
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}OpenTTDã¨ã¯ï¼Ÿã§ãã¡
+STR_015C_SAVE_GAME :ゲームをä¿å­˜
+STR_015D_LOAD_GAME :ゲームを開ã
+STR_015E_QUIT_GAME :ゲームを断念
+STR_015F_QUIT :出å£
+STR_0161_QUIT_GAME :{WHITE}ゲームã®æ–­å¿µ
+
+STR_SORT_BY_POPULATION :{BLACK}人å£
+STR_SORT_BY_TYPE :{BLACK}種類
+STR_SORT_BY_TRANSPORTED :{BLACK}é‹ã³ã 
+STR_SORT_BY_NAME :{BLACK}åå‰
+STR_SORT_BY_DROPDOWN_NAME :åå‰
+STR_SORT_BY_NUMBER :番å·
+STR_SORT_BY_VALUE :価値
+STR_SORT_BY_WAITING :å¾…ã£ã¦ã„ã‚‹ç©è·ä¾¡å€¤
+STR_ENGINE_SORT_COST :値段
+
+############ range for months starts
+STR_0162_JAN :1月
+STR_0163_FEB :2月
+STR_0164_MAR :3月
+STR_0165_APR :4月
+STR_0166_MAY :5月
+STR_0167_JUN :6月
+STR_0168_JUL :7月
+STR_0169_AUG :8月
+STR_016A_SEP :9月
+STR_016B_OCT :10月
+STR_016C_NOV :11月
+STR_016D_DEC :12月
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}ãƒãƒ¼ã‚º
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}ゲームをä¿å­˜ã€ã‚²ãƒ¼ãƒ ã‚’断念ã€çµ‚了
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}会社ã®é§…を表示ã—ã¾ã™
+STR_0174_DISPLAY_MAP :{BLACK}地図を見ã›ã¾ã™
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}地図ã€ç”ºã®ãƒªã‚¹ãƒˆã‚’表示ã—ã¾ã™
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}町ã®ãƒªã‚¹ãƒˆã‚’表示ã—ã¾ã™
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}会社ã®è²¡å‹™çŠ¶æ³ã‚’表示ã—ã¾ã™
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}会社ã®ä¸€èˆ¬æƒ…報を表示ã—ã¾ã™
+STR_0179_DISPLAY_GRAPHS :{BLACK}グラフを表示ã—ã¾ã™
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}会社ã®æˆç¸¾è¡¨ã‚’表示ã—ã¾ã™
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}会社ã®é›»è»Šã®ãƒªã‚¹ãƒˆã‚’表示ã—ã¾ã™
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}会社ã®ãƒã‚¹ï¼ãƒˆãƒ©ãƒƒã‚¯ã®ãƒªã‚¹ãƒˆã‚’表示ã—ã¾ã™
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}会社ã®èˆ¹ã®ãƒªã‚¹ãƒˆã‚’表示ã—ã¾ã™
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}会社ã®é£›è¡Œæ©Ÿã®ãƒªã‚¹ãƒˆã‚’表示ã—ã¾ã™
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}拡大ã—ã¾ã™
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}縮å°ã—ã¾ã™
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}鉄é“を建造ã—ã¾ã™
+STR_0182_BUILD_ROADS :{BLACK}é“路を建造ã—ã¾ã™
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}波止場を建造ã—ã¾ã™
+STR_0184_BUILD_AIRPORTS :{BLACK}空港を建造ã—ã¾ã™
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}木ã®æ¤ãˆã€æ¨™ç¤ºã®ç½®ãã“ã¨ãªã©
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}地域情報
+STR_0187_OPTIONS :{BLACK}設定
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}整備間隔ãŒå¤‰æ›´ã§ãã¾ã›ã‚“
+STR_018B_CLOSE_WINDOW :{BLACK}ウィンドウを閉ã˜ã¾ã™
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}ウィンドウã®ã‚¿ã‚¤ãƒˆãƒ« - ウィンドウを動ãã«ã¯ã€ã‚¯ãƒªãƒƒã‚¯ã—ã¦ãƒ‰ãƒ©ãƒƒã‚°ã—ã¾ã™
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}土地上ã®å»ºç‰©ãªã©ã‚’破壊ã—ã¾ã™
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}土地ã®è§’を下ã’ã¾ã™
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}土地ã®è§’を上ã’ã¾ã™
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}スクロールãƒãƒ¼
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}地図ã«åœŸåœ°ã®å½¢å‹¢ã‚’表示ã—ã¾ã™
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}地図ã«ä¹—り物を表示ã—ã¾ã™
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}地図ã«ç”£æ¥­ã‚’表示ã—ã¾ã™
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}地図ã«é‹é€çµŒè·¯ã‚’表示ã—ã¾ã™
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}地図ã«æ¤ç‰©ã‚’表示ã—ã¾ã™
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}地図ã«åœŸåœ°ã®æ‰€æœ‰è€…を表示ã—ã¾ã™
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}地図ã«ç”ºåã®è¡¨ç¤ºã‚’å…¥ï¼åˆ‡ã«ã—ã¾ã™
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}今年ã®åˆ©ç›Šï¼š{CURRENCY} (去年:{CURRENCY})
+
+############ range for service numbers starts
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :ãƒã‚¹ï¼ãƒˆãƒ©ãƒƒã‚¯
+STR_019D_AIRCRAFT :飛行機
+STR_019E_SHIP :船
+STR_019F_TRAIN :電車
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} ã¯å¤ããªã£ã¦ã„ã¾ã™
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} ã¯ã‹ã­ã¦å¤ããªã£ã¦ã„ã¾ã™
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} ã¯ã‹ã­ã¦å¤ããªã£ã¦ã„ã¦ã€ç·Šæ€¥ã«å–り替ãˆã‚‰ã‚Œãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}地域情報
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}破壊ã®ä¾¡æ ¼ï¼š{LTBLUE}破壊ä¸å¯
+STR_01A5_COST_TO_CLEAR :{BLACK}破壊ã®ä¾¡æ ¼ï¼š{LTBLUE}{CURRENCY}
+STR_01A6_N_A :N/A
+STR_01A7_OWNER :{BLACK}所有者:{LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK} 地方官åºï¼š{LTBLUE}{STRING}
+STR_01A9_NONE :何も
+STR_01AA_NAME :{BLACK}åå‰
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1æ—¥
+STR_01AD_2ND :2æ—¥
+STR_01AE_3RD :3æ—¥
+STR_01AF_4TH :4æ—¥
+STR_01B0_5TH :5æ—¥
+STR_01B1_6TH :6æ—¥
+STR_01B2_7TH :7æ—¥
+STR_01B3_8TH :8æ—¥
+STR_01B4_9TH :9æ—¥
+STR_01B5_10TH :10æ—¥
+STR_01B6_11TH :11æ—¥
+STR_01B7_12TH :12æ—¥
+STR_01B8_13TH :13æ—¥
+STR_01B9_14TH :14æ—¥
+STR_01BA_15TH :15æ—¥
+STR_01BB_16TH :16æ—¥
+STR_01BC_17TH :17æ—¥
+STR_01BD_18TH :18æ—¥
+STR_01BE_19TH :19æ—¥
+STR_01BF_20TH :20æ—¥
+STR_01C0_21ST :21æ—¥
+STR_01C1_22ND :22æ—¥
+STR_01C2_23RD :23æ—¥
+STR_01C3_24TH :24æ—¥
+STR_01C4_25TH :25æ—¥
+STR_01C5_26TH :26æ—¥
+STR_01C6_27TH :27æ—¥
+STR_01C7_28TH :28æ—¥
+STR_01C8_29TH :29日
+STR_01C9_30TH :30æ—¥
+STR_01CA_31ST :31æ—¥
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}å—ã‘å–る集è·ï¼š {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}ジャズジュークボックス
+STR_01D3_SOUND_MUSIC :エフェクトï¼éŸ³æ¥½
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}エフェクトï¼éŸ³æ¥½ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’表示ã—ã¾ã™
+STR_01D5_ALL :{TINYFONT}ã™ã¹ã¦
+STR_01D6_OLD_STYLE :{TINYFONT}æ—§å¼
+STR_01D7_NEW_STYLE :{TINYFONT}æ–°å¼
+STR_01D8_EZY_STREET :{TINYFONT}Ezy Street
+STR_01D9_CUSTOM_1 :{TINYFONT}カスタム 1
+STR_01DA_CUSTOM_2 :{TINYFONT}カスタム 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}音楽ã®éŸ³é‡
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}エフェクトã®éŸ³é‡
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MIN ' ' ' ' ' ' MAX
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}é¸æŠžéƒ¨åˆ†ã®å‰ã®æ›²ã¸ã‚¸ãƒ£ãƒ³ãƒ—
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}é¸æŠžéƒ¨åˆ†ã®æ¬¡ã®æ›²ã¸ã‚¸ãƒ£ãƒ³ãƒ—
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}音楽ã®å†ç”Ÿã‚’åœæ­¢
+STR_01E1_START_PLAYING_MUSIC :{BLACK}音楽ã®å†ç”Ÿã‚’開始
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}音楽ã¨ã‚¨ãƒ•ã‚§ã‚¯ãƒˆã®éŸ³é‡ã‚’設定ã™ã‚‹ã«ã¯ã€ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ã‚’ドラッグã—ã¾ã™
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}曲{SETX 88}タイトル
+STR_01E9_SHUFFLE :{TINYFONT}シャッフル
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}プレイリスト
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}プレイリストã®é¸æŠž
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}曲ã®ãƒªã‚¹ãƒˆ
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}プレイリスト - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}消去
+STR_01F1_SAVE :{TINYFONT}{BLACK}ä¿å­˜
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}å†ç”Ÿä¸­ã®ãƒ—レイリスト
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}プレイリスト「ã™ã¹ã¦ã®æ›²ã€ã‚’é¸æŠžã—ã¾ã™
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}プレイリスト「旧å¼éŸ³æ¥½ã€ã‚’é¸æŠžã—ã¾ã™
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}プレイリスト「新å¼éŸ³æ¥½ã€ã‚’é¸æŠžã—ã¾ã™
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}プレイリスト「カスタム 1ã€ã‚’é¸æŠžã—ã¾ã™
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}プレイリスト「カスタム 2ã€ã‚’é¸æŠžã—ã¾ã™
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}é¸æŠžã—ãŸãƒ—レイリストã®å†…容を消去ã—ã¾ã™ï¼ˆã‚«ã‚¹ã‚¿ãƒ  1ï¼2 ã®ã¿ï¼‰ã€‚
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}音楽ã®è¨­å®šã‚’ä¿å­˜
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}é¸æŠžã—ãŸãƒ—レイリストã¸è¿½åŠ ã™ã‚‹ã«ã¯ã€æ›²ã‚’クリックã—ã¾ã™ï¼ˆã‚«ã‚¹ã‚¿ãƒ  1ï¼2 ã®ã¿ï¼‰ã€‚
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}プレイリストã®ã‚·ãƒ£ãƒƒãƒ•ãƒ«ã‚’å…¥ï¼åˆ‡ã«ã—ã¾ã™
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}曲ã®é¸æŠžã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦è¡¨ç¤ºã—ã¾ã™
+STR_01FE_DIFFICULTY :{BLACK}難ã—ã•ï¼ˆ{STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :最後メッセージ
+STR_0201_MESSAGE_SETTINGS :メッセージ設定
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}最後メッセージãã‚Œã¨ã‚‚ã€ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸è¨­å®šã‚’見ã›ã¾ã™
+STR_0204_MESSAGE_OPTIONS :{WHITE}メッセージ設定
+STR_0205_MESSAGE_TYPES :{BLACK}メッセージタイプ:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}プレヤーã®ãƒã‚¹åœï¼é§…ãªã©ã¸ä¹—り物ã®åˆã‚ã¦ã®åˆ°ç€
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}競争者ã®ãƒã‚¹åœï¼é§…ãªã©ã¸ä¹—り物ã®åˆã‚ã¦ã®åˆ°ç€
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}事件ï¼ç½å®³
+STR_0209_COMPANY_INFORMATION :{YELLOW}会社情報
+STR_020A_ECONOMY_CHANGES :{YELLOW}経済ã®å¤‰åŒ–
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}プレヤーã®ä¹—り物ã«ã¤ã„ã¦ã®æƒ…å ±
+STR_020C_NEW_VEHICLES :{YELLOW}乗り物ã®æ–°ç™»å ´
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}貨物ã®å—ã‘å–ã‚Šã®å¤‰åŒ–
+STR_020E_SUBSIDIES :{YELLOW}助æˆé‡‘
+STR_020F_GENERAL_INFORMATION :{YELLOW}一般情報
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...å‰ã®è¡Œãå…ˆã‹ã‚‰é ã™ãŽã¾ã™
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}{NUM}{}({STRING} レベル) ã«å½“ãŸã£ãŸæœ€é«˜ã®ä¼šç¤¾
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}{NUM}ã®ä¼šç¤¾ãƒªãƒ¼ã‚°è¡¨
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :ビジãƒã‚¹ãƒžãƒ³
+STR_0214_ENTREPRENEUR :ä¼æ¥­å®¶
+STR_0215_INDUSTRIALIST :産業主義者
+STR_0216_CAPITALIST :資本家
+STR_0217_MAGNATE :大立者
+STR_0218_MOGUL :大御所
+STR_0219_TYCOON_OF_THE_CENTURY :大将è»
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}ã€ã€€{COMPANY}
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} ã¯ã€Œ{STRING}ã€ã«å½“ãŸã£ãŸï¼
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME}({COMPANY})ã¯ã€Œ{STRING}ã€ã«å½“ãŸã£ãŸï¼
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}シナリオを作æˆ
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}シナリオエディタ
+STR_0223_LAND_GENERATION :{WHITE}地勢ã®ç”Ÿæˆ
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}ランダムãªåœ°å‹¢
+STR_0227_RESET_LAND :{BLACK}地勢をリセット
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}ã‚ã’ã‚‹ï¼ä¸‹ã’る地域ã®ã‚µã‚¤ã‚ºã‚’拡大ã—ã¾ã™
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}ã‚ã’ã‚‹ï¼ä¸‹ã’る地域ã®ã‚µã‚¤ã‚ºã‚’縮å°ã—ã¾ã™
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}ランダムãªåœ°å‹¢ã‚’生æˆã—ã¾ã™
+STR_022B_RESET_LANDSCAPE :{BLACK}地勢をリセットã—ã¾ã™
+STR_022C_RESET_LANDSCAPE :{WHITE}地勢ã®ãƒªã‚»ãƒƒãƒˆ
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}地勢をリセットã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ
+STR_022E_LANDSCAPE_GENERATION :{BLACK}地勢ã®ç”Ÿæˆ
+STR_022F_TOWN_GENERATION :{BLACK}市町æ‘ã®ç”Ÿæˆ
+STR_0230_INDUSTRY_GENERATION :{BLACK}産業ã®ç”Ÿæˆ
+STR_0231_ROAD_CONSTRUCTION :{BLACK}é“è·¯ã®ç”Ÿæˆ
+STR_0233_TOWN_GENERATION :{WHITE}市町æ‘ã®ç”Ÿæˆ
+STR_0234_NEW_TOWN :{BLACK}æ–°è¦ç”º
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}æ–°è¦ç”ºã‚’建造ã—ã¾ã™
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}ã“ã“ã§ç”ºãŒå»ºé€ ã§ãã¾ã›ã‚“...
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...ä»–ã®ç”ºã®è¿‘ã™ãŽã¾ã™
+STR_0239_SITE_UNSUITABLE :{WHITE}...地域ãŒä¸é©å½“ã§ã™
+STR_023A_TOO_MANY_TOWNS :{WHITE}...市町æ‘æ•°ã®åˆ¶é™ã‚’超ãˆã¦ã„ã¾ã™
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}町ã®ã‚µã‚¤ã‚ºã‚’ã‚ã’ã¾ã™
+STR_023C_EXPAND :{BLACK}拡大
+STR_023D_RANDOM_TOWN :{BLACK}ランダムãªç”º
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}ランダムãªã¨ã“ã‚ã«ç”ºã‚’建造ã—ã¾ã™
+STR_023F_INDUSTRY_GENERATION :{WHITE}産業ã®ç”Ÿæˆ
+STR_0240_COAL_MINE :{BLACK}ç‚­å‘
+STR_0241_POWER_STATION :{BLACK}発電所
+STR_0242_SAWMILL :{BLACK}製æ工場
+STR_0243_FOREST :{BLACK}森林
+STR_0244_OIL_REFINERY :{BLACK}製油所
+STR_0246_FACTORY :{BLACK}工場
+STR_0247_STEEL_MILL :{BLACK}製鋼所
+STR_0248_FARM :{BLACK}農場
+STR_0249_IRON_ORE_MINE :{BLACK}鉄鉱石鉱山
+STR_024A_OIL_WELLS :{BLACK}油井
+STR_024B_BANK :{BLACK}銀行
+STR_024C_PAPER_MILL :{BLACK}製紙工場
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}食å“加工場
+STR_024E_PRINTING_WORKS :{BLACK}å°åˆ·æ‰€
+STR_024F_GOLD_MINE :{BLACK}金鉱
+STR_0250_LUMBER_MILL :{BLACK}製æ所
+STR_0251_FRUIT_PLANTATION :{BLACK}果物農園
+STR_0252_RUBBER_PLANTATION :{BLACK}ゴム園
+STR_0253_WATER_SUPPLY :{BLACK}給水設備
+STR_0254_WATER_TOWER :{BLACK}給水塔
+STR_0255_DIAMOND_MINE :{BLACK}ダイヤモンド鉱山
+STR_0256_COPPER_ORE_MINE :{BLACK}銅鉱石鉱山
+STR_0285_CAN_T_BUILD_HERE :{WHITE}ãã“ã« {STRING} を建ã¦ã‚‰ã‚Œã¾ã›ã‚“
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...ã¾ãšã¯ç”ºã‚’建造ã—ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...一町内ã«ä¸€ã¤ã—ã‹å»ºé€ ã§ãã¾ã›ã‚“
+STR_0296_QUIT :出å£
+STR_0298_LOAD_SCENARIO :{WHITE}シナリオを開ã
+STR_0299_SAVE_SCENARIO :{WHITE}シナリオをä¿å­˜
+STR_029A_PLAY_SCENARIO :{BLACK}シナリオをプレイ
+STR_029C_QUIT_EDITOR :{WHITE}エディタã®çµ‚了
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...人å£ãŒ1200人以上ã®å¸‚町ã®ã¿ã«å»ºé€ ã§ãã¾ã™
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}開始日を1年間減らã—ã¾ã™
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}開始日を1年間増やã—ã¾ã™
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...æ©‹ã®ç«¯ã¯ä¸¡æ–¹åœŸåœ°ä¸Šã«å»ºé€ ã—ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“
+STR_02A1_SMALL :{BLACK}å°ã•ã„
+STR_02A2_MEDIUM :{BLACK}町
+STR_02A3_LARGE :{BLACK}大ãã„
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}町ã®ã‚µã‚¤ã‚ºã‚’é¸æŠžã—ã¾ã™
+STR_02A5_TOWN_SIZE :{YELLOW}町ã®ã‚µã‚¤ã‚ºï¼š
+
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}最後ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ï¼å ±é“を表示ã—ã¾ã™
+STR_SUMMARY :ç²—ç­‹
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :市町æ‘ã®ãƒªã‚¹ãƒˆ
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}乗り物ã®å称
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :デフォルト
+STR_02BF_CUSTOM :カスタム
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}カスタムå称をä¿å­˜
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}乗り物ã®å称ã®é¸æŠž
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}カスタマイズã—ãŸä¹—り物ã®å称をä¿å­˜ã—ã¾ã™
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :ゲーム設定
+STR_02C5_DIFFICULTY_SETTINGS :難ã—ã•è¨­å®š
+STR_02C7_CONFIG_PATCHES :パッãƒã®è¨­å®š
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}市町æ‘åã®è¡¨ç¤º
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}駅ï¼ãƒã‚¹åœåã®è¡¨ç¤º
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}標示ã®è¡¨ç¤º
+STR_02D0_FULL_ANIMATION :{SETX 12}高級ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³
+STR_02D2_FULL_DETAIL :{SETX 12}高級ã®ç”»åƒ
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}é€æ˜Žãªå»ºç‰©
+STR_TRANSPARENT_SIGNS :{SETX 12}澄む駅看æ¿
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :地域情報
+STR_02D6 :
+STR_02D7_SCREENSHOT_CTRL_S :スクリーンショット(Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :大型スクリーンショット(Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :'OpenTTD'ã¨ã¯ï¼Ÿ
+############ range ends here
+
+STR_02DB_OFF :{BLACK}切
+STR_02DA_ON :{BLACK}å…¥
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}助æˆé‡‘を表示
+STR_02DD_SUBSIDIES :助æˆé‡‘
+STR_02DE_MAP_OF_WORLD :世界ã®åœ°å›³
+STR_02DF_TOWN_DIRECTORY :市町æ‘ã®ãƒªã‚¹ãƒˆ
+STR_TOWN_POPULATION :{BLACK}世界人å£ï¼š{COMMA}
+
+STR_02E0_CURRENCY_UNITS :{BLACK}通貨å˜ä½
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}通貨å˜ä½ã®é¸æŠž
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_02E6_ROAD_VEHICLES :{BLACK}ãƒã‚¹ï¼ãƒˆãƒ©ãƒƒã‚¯
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E9_DRIVE_ON_LEFT :å·¦ã«é‹è»¢ã—ã¾ã™
+STR_02EA_DRIVE_ON_RIGHT :å³ã«é‹è»¢ã—ã¾ã™
+STR_02EB_TOWN_NAMES :{BLACK}市町æ‘å
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}市町æ‘åã®ç¨®é¡žã®é¸æŠž
+
+STR_02F4_AUTOSAVE :{BLACK}自動ä¿å­˜
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}自動ä¿å­˜ã®é–“隔をé¸æŠžã—ã¾ã™
+STR_02F7_OFF :切
+STR_02F8_EVERY_3_MONTHS :毎3月
+STR_02F9_EVERY_6_MONTHS :毎6月
+STR_02FA_EVERY_12_MONTHS :毎12月
+STR_02FB_START_A_NEW_GAME :{BLACK}æ–°ã—ã„ゲームを始ã‚ã¾ã™
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}ゲームを開ãã¾ã™
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}カスタムシナリオを作æˆã—ã¾ã™
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}一人プレイをé¸æŠžã—ã¾ã™
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}多人数プレイ(2〜8人)をé¸æŠžã—ã¾ã™
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}ゲーム設定を見ã›ã¾ã™
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}難ã—ã•è¨­å®šã‚’見ã›ã¾ã™
+STR_0303_START_A_NEW_GAME_USING :{BLACK}カスタムシナリオを使用ã—ã¦æ–°è¦ã‚²ãƒ¼ãƒ ã‚’開始ã—ã¾ã™
+STR_0304_QUIT :{BLACK}出å£
+STR_0305_QUIT_OPENTTD :{BLACK}'OpenTTD'ã‚’æ­¢ã‚ã¾ã™
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}…町ã®å¤–ã«å»ºã¦ã¾ã›ã‚“
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}温帯地域をé¸æŠžã—ã¾ã™
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}亜寒帯地域をé¸æŠžã—ã¾ã™
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}亜熱帯地域をé¸æŠžã—ã¾ã™
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}ãŠã‚‚ã¡ã‚ƒã®å›½ã‚’é¸æŠžã—ã¾ã™
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}æ–°è¦ç”£æ¥­ã®å»ºé€ ã«è³‡é‡‘を供給ã—ã¾ã™
+
+############ range for menu starts
+STR_0313_FUND_NEW_INDUSTRY :æ–°è¦ç”£æ¥­ã®å»ºé€ ã«è³‡é‡‘を出ã™
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}æ–°è¦ç”£æ¥­ã®å»ºé€ ã«è³‡é‡‘ã®ä¾›çµ¦
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}…町ã®å¤–ã«å»ºã¦ã¾ã›ã‚“
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...雨林地域ã®ã¿ã«å»ºé€ ã§ãã¾ã™
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...砂漠地域ã®ã¿ã«å»ºé€ ã§ãã¾ã™
+STR_0319_PAUSED :{YELLOW}**ãƒãƒ¼ã‚ºï¼Šï¼Š
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}スクリーンショットを '{STRING}' ã«æ­£å¸¸ã«ä¿å­˜ã—ã¾ã—ãŸ
+STR_031C_SCREENSHOT_FAILED :{WHITE}スクリーンショットãŒå¤±æ•—ã—ã¾ã—ãŸï¼
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}å°†æ¥ç”¨ã«åœŸåœ°ã‚’購入
+STR_032F_AUTOSAVE :{RED}自動ä¿å­˜
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}'Ezy Street å¼ã®éŸ³æ¥½'ã®ãƒ—レイリストをé¸æŠžã—ã¾ã™
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :イギリス
+STR_TOWNNAME_FRENCH :フランス
+STR_TOWNNAME_GERMAN :ドイツ
+STR_TOWNNAME_ADDITIONAL_ENGLISH :イギリス(ãŠã¾ã‘)
+STR_TOWNNAME_LATIN_AMERICAN :ラテンアメリカ
+STR_TOWNNAME_SILLY :æ„š
+STR_TOWNNAME_SWEDISH :スウェーデン
+STR_TOWNNAME_POLISH :ãƒãƒ¼ãƒ©ãƒ³ãƒ‰
+STR_TOWNNAME_SLOVAKISH :スロãƒã‚­ã‚¢
+STR_TOWNNAME_NORWEGIAN :ノルウェー
+STR_TOWNNAME_HUNGARIAN :洪牙利
+STR_TOWNNAME_AUSTRIAN :オーストリア
+STR_TOWNNAME_ROMANIAN :ルーマニア
+STR_TOWNNAME_CZECH :ãƒã‚§ã‚³
+STR_TOWNNAME_SWISS :瑞西
+STR_TOWNNAME_DANISH :デーン
+STR_TOWNNAME_TURKISH :土国
+STR_TOWNNAME_ITALIAN :イタリ
+STR_TOWNNAME_CATALAN :カタラン
+############ end of townname region
+
+STR_CURR_YEN :日本ã®å††ï¼ˆï¿¥ï¼‰
+
+
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+
+
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+
+STR_AUTOSAVE_1_MONTH :毎月
+
+STR_MONTH_JAN :1月
+STR_MONTH_FEB :2月
+STR_MONTH_MAR :3月
+STR_MONTH_APR :4月
+STR_MONTH_MAY :5月
+STR_MONTH_JUN :6月
+STR_MONTH_JUL :7月
+STR_MONTH_AUG :8月
+STR_MONTH_SEP :9月
+STR_MONTH_OCT :10月
+STR_MONTH_NOV :11月
+STR_MONTH_DEC :12月
+
+
+STR_TONS :トン
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+
+STR_TRAIN_IS_LOST :{WHITE}電車{COMMA}ã¯è¿·ã„ã¾ã™
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}去年ã€é›»è»Š{COMMA}ã®å–り柄ã¯{CURRENCY}
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}電車{COMMA}ã®ãƒ«ãƒ¼ãƒˆã¯éŽå°é§…ãŒã‚ã‚Šã¾ã™
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}電車{COMMA}㯠空々予定ãŒã‚ã‚Šã¾ã™
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}電車{COMMA}ã®ãƒ«ãƒ¼ãƒˆã¯ãƒ‡ãƒ¥ãƒ¼ãƒ—リケート 駅ãŒã‚ã‚Šã¾ã™
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}電車{COMMA} ã®ãƒ«ãƒ¼ãƒˆã¯ç„¡åŠ¹ãªé§…ãŒã‚ã‚Šã¾ã™
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}電車{COMMA} ã®ã‚ªãƒ¼ãƒˆå–り替ãˆã‚‰ã‚Œã¾ã›ã‚“ (ãŠé‡‘ã®ã‹ãŽã‚Šï¼‰
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}付ã‘替ãˆã®å¾Œã§ã€é›»è»Š{COMMA}㯠ã¡ã‚‡ã£ã¨é•·ã„ã§ã™
+
+
+
+
+
+
+STR_CONFIG_PATCHES_LIVERIES_NONE :何も
+
+
+
+
+
+
+
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+
+STR_TEMPERATE_LANDSCAPE :温帯国
+STR_SUB_ARCTIC_LANDSCAPE :北極国
+STR_SUB_TROPICAL_LANDSCAPE :亜熱帯国
+STR_TOYLAND_LANDSCAPE :ãŠã¾ã¡ã‚ƒå›½
+
+
+
+
+
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+
+
+
+
+
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}ランドム種類ã®æœ¨
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}ランドム種類ã®æœ¨ã‚’æ¤ãˆã¾ã™
+
+
+
+
+
+
+
+
+
+
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+
+
+TEMP_AI_IN_PROGRESS :{WHITE}ã„らã£ã—ゃã„ã¾ã›ï¼ã“ã®AIã¯ç™ºå±•ä¸­ã§ã™ã€‚å•é¡ŒãŒã‚ã£ãŸã‚‰ã€ã‚¹ã‚¯ãƒªãƒ¼ãƒ³ã‚·ãƒ§ãƒƒãƒˆã‚’å–ã£ã¦ã€ãƒ•ã‚©ãƒ¼ãƒ©ãƒ ã«é€ã£ã¦ãã ã•ã„
+TEMP_AI_ACTIVATED :{WHITE}注æ„:AIã¯ã¾ã ã‚¢ãƒ«ãƒ•ã‚¡ã§ã™ï¼ä»Šã€è²¨ç‰©è‡ªå‹•è»Šã¨ãƒã‚¹ã ã‘ç–²ã‚ã‚Œã¾ã™ï¼
+TEMP_AI_MULTIPLAYER :{WHITE}注æ„:AIã¯ã¾ã å®Ÿé¨“段階ã§ã™ï¼å•é¡ŒãŒã‚ã£ãŸã‚‰ã€è‹±èªžã§truelight@openttd.orgをメールã—ã¦ãã ã•ã„。
+
+############ network gui strings
+
+
+
+
+STR_NETWORK_GAME_NAME :{BLACK}åå‰
+
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_LANGUAGE :{SILVER}国語:  {WHITE}{STRING}
+
+
+
+
+STR_NETWORK_INTERNET :インターãƒãƒƒãƒˆ
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ENGLISH :英語
+STR_NETWORK_LANG_GERMAN :ドイツ語
+STR_NETWORK_LANG_FRENCH :フランス語
+############ End of leave-in-this-order
+
+
+
+
+
+
+
+############ Leave those lines in this order!!
+
+############ End of leave-in-this-order
+
+
+
+
+############ Leave those lines in this order!!
+############ End of leave-in-this-order
+
+
+
+
+
+############ end network gui strings
+
+
+
+
+##### PNG-MAP-Loader
+
+
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}値段:{CURRENCY}
+STR_0801_COST :{RED}値段: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}所得:{CURRENCY}
+STR_0803_INCOME :{GREEN}所得:{CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}評価ã®ä¾¡å€¤ï¼š{CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}評価ã®æ‰€å¾—:{CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}ã“ã“ã«åœŸåœ°ãŒä¸Šã’られã¾ã›ã‚“
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}ã“ã“ã«åœŸåœ°ãŒä¸‹ã’られã¾ã›ã‚“
+STR_080A_ROCKS :岩石
+STR_080B_ROUGH_LAND :ã§ã“ã¼ã“ã®åœŸåœ°
+STR_080C_BARE_LAND :裸地
+STR_080D_GRASS :è‰åœ°
+STR_080E_FIELDS :ç”°ç•‘
+STR_080F_SNOW_COVERED_LAND :ç©é›ªåœ°åŸŸ
+STR_0810_DESERT :ç ‚æ¼ 
+
+##id 0x1000
+STR_1004_TOO_HIGH :{WHITE}ã¡ã‚‡ã£ã¨é«˜ã„ã§ã™
+STR_1007_ALREADY_BUILT :{WHITE}…もã†å»ºã¦ã¾ã—ãŸ
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}鉄é“ã®å»ºé€ 
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}電鉄建造
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}モノレールã®å»ºé€ 
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}マグレブã®å»ºé€ 
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}鉄é“ã®æ©‹ã®é¸æŠž
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}ã“ã“ã«é›»è»Šåº«ãŒå»ºé€ ã§ãã¾ã›ã‚“
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}ã“ã“ã«é§…ãŒå»ºé€ ã§ãã¾ã›ã‚“
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}ã“ã“ã«ä¿¡å·ãŒå»ºé€ ã§ãã¾ã›ã‚“
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}ã“ã“ã«ç·šè·¯ãŒå»ºé€ ã§ãã¾ã›ã‚“
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}ã“ã“ã‹ã‚‰ç·šè·¯ãŒå»ƒæ­¢ã§ãã¾ã›ã‚“
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}ã“ã“ã‹ã‚‰ä¿¡å·ãŒå»ƒæ­¢ã§ãã¾ã›ã‚“
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}電車庫ã®é…ç½®
+STR_1015_RAILROAD_CONSTRUCTION :鉄é“ã®å»ºé€ 
+STR_TOOLB_ELRAIL_CONSTRUCTION :電鉄建造
+STR_1016_MONORAIL_CONSTRUCTION :モノレールã®å»ºé€ 
+STR_1017_MAGLEV_CONSTRUCTION :マグレブã®å»ºé€ 
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}線路を建造ã—ã¾ã™
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}(電車ã®å»ºé€ ã‚„æ•´å‚™ã®ãŸã‚ã®ï¼‰é›»è»Šåº«ã‚’建造ã—ã¾ã™
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}駅を建造ã—ã¾ã™
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}鉄é“ã®ä¿¡å·ã‚’建造ã—ã¾ã™
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}鉄é“ã®æ©‹ã‚’建造ã—ã¾ã™
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}鉄é“ã®ãƒˆãƒ³ãƒãƒ«ã‚’建造ã—ã¾ã™
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}ç·šè·¯ã¨ä¿¡å·ã®å»ºé€ ï¼å»ƒæ­¢ã‚’切り替ãˆã¾ã™
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}æ©‹ã®é¸æŠž - ãŠå¥½ããªæ©‹ã‚’建造ã™ã‚‹ã«ã¯ã‚¯ãƒªãƒƒã‚¯ã—ã¾ã™
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}電車庫ã®é…置をé¸æŠžã—ã¾ã™
+STR_1021_RAILROAD_TRACK :ç·šè·¯
+STR_1023_RAILROAD_TRAIN_DEPOT :電車庫
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...ã“ã®åœŸåœ°ã¯ä»–ã®ä¼šç¤¾ã«æ‰€æœ‰ã•ã‚Œã¦ã„ã¾ã™
+
+
+
+##id 0x1800
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}ã“ã“ã‹ã‚‰é“è·¯ãŒå»ƒæ­¢ã§ãã¾ã›ã‚“...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}車庫ã®é…ç½®
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}ã“ã“ã«è»Šåº«ãŒå»ºé€ ã§ãã¾ã›ã‚“...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}ãƒã‚¹åœãŒå»ºé€ ã§ãã¾ã›ã‚“...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}è·å½¹æ‰€ãŒå»ºé€ ã§ãã¾ã›ã‚“...
+STR_180A_ROAD_CONSTRUCTION :é“è·¯ã®å»ºé€ 
+STR_180B_BUILD_ROAD_SECTION :{BLACK}é“è·¯ã®éƒ¨åˆ†ã‚’建造ã—ã¾ã™
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}(ãƒã‚¹ã€ãƒˆãƒ©ãƒƒã‚¯ã®å»ºé€ ã€æ•´å‚™ã®ãŸã‚ã®ï¼‰è»Šåº«ã‚’建造ã—ã¾ã™
+STR_180D_BUILD_BUS_STATION :{BLACK}ãƒã‚¹åœã‚’建造ã—ã¾ã™
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}è·å½¹æ‰€ã‚’建造ã—ã¾ã™
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}é“è·¯ã®ç«¯ã‚’建造ã—ã¾ã™
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}é“è·¯ã®ãƒˆãƒ³ãƒãƒ«ã‚’建造ã—ã¾ã™
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}é“è·¯ã®å»ºé€ ï¼å»ƒæ­¢ã‚’切り替ãˆã¾ã™
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}車庫ã®é…ç½®ã®é¸æŠž
+STR_1814_ROAD :é“è·¯
+STR_1815_ROAD_WITH_STREETLIGHTS :街路照明ã®ã‚ã‚‹é“è·¯
+STR_1816_TREE_LINED_ROAD :並木é“
+STR_1817_ROAD_VEHICLE_DEPOT :車庫
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :è¸åˆ‡
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}町
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}ã¾ãšã¯å»ºç‰©ã‚’破壊ã—ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}人å£ï¼š{ORANGE}{COMMA}人{BLACK} 建物:{ORANGE}{COMMA}戸
+STR_2007_RENAME_TOWN :町åを変更
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}町åãŒå¤‰æ›´ã§ãã¾ã›ã‚“...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN}ã®ç”ºè­°ä¼šã¯è¨±å¯ã—ã¾ã›ã‚“
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}町å - ç”»é¢ã‚’ãã®ç”ºã«é›†ä¸­ã™ã‚‹ã«ã¯ã€ã‚¯ãƒªãƒƒã‚¯ã—ã¾ã™
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}ç”»é¢ã‚’町ã«é›†ä¸­ã—ã¾ã™
+STR_200C_CHANGE_TOWN_NAME :{BLACK}町åを変更ã—ã¾ã™
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}先月ã®ä¹—客:{ORANGE}{COMMA}人{BLACK} 最大:{ORANGE}{COMMA}人
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}先月ã®éƒµä¾¿ç‰©ï¼š{ORANGE}{COMMA}個{BLACK} 最大:{ORANGE}{COMMA}個
+STR_200F_TALL_OFFICE_BLOCK :超高層ビル
+STR_2010_OFFICE_BLOCK :オフィスビル
+STR_2011_SMALL_BLOCK_OF_FLATS :アパート
+STR_2012_CHURCH :ãƒãƒ£ãƒ¼ãƒ
+STR_2013_LARGE_OFFICE_BLOCK :大型オフィスビル
+STR_2014_TOWN_HOUSES :マンション
+STR_2015_HOTEL :ホテル
+STR_2016_STATUE :彫åƒ
+STR_2017_FOUNTAIN :å™´æ°´
+STR_2018_PARK :公園
+STR_2019_OFFICE_BLOCK :オフィスビル
+STR_201A_SHOPS_AND_OFFICES :雑居ビル
+STR_201B_MODERN_OFFICE_BUILDING :近代ã®ã‚ªãƒ•ã‚£ã‚¹ãƒ“ル
+STR_201C_WAREHOUSE :倉庫
+STR_201D_OFFICE_BLOCK :オフィスビル
+STR_201E_STADIUM :スタジアム
+STR_201F_OLD_HOUSES :è€èˆ—
+STR_2020_LOCAL_AUTHORITY :{BLACK}町議会
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}町議会ã®æƒ…報を表示ã—ã¾ã™
+STR_2022_LOCAL_AUTHORITY :{WHITE}{TOWN}ã®ç”ºè­°ä¼š
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}会社ã®ç”ºå†…ã®ä¸–評:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}助æˆé‡‘
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}次ã®é‹é€çµŒè·¯ã«åŠ©æˆé‡‘ã‚’æ案ã—ã¾ã™ï¼š
+STR_2027_FROM_TO :{ORANGE}{STRING}ã‚’{STRING}ã‹ã‚‰{STRING}ã¸
+STR_2028_BY :{YELLOW} ({DATE_SHORT}ã®å‰ï¼‰
+STR_202A_NONE :{ORANGE}何も
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}æ—¢ã«åŠ©æˆé‡‘ã‚’å—ã‘ã¦ã„ã‚‹é‹é€çµŒè·¯ï¼š
+STR_202C_FROM_TO :{ORANGE}{STRING}{STATION}ã‹ã‚‰{STATION}ã¾ã§{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}ã€{DATE_SHORT}ã¾ã§ï¼‰
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}助æˆé‡‘ã®æ案ã®æœ‰åŠ¹æœŸé™ãŒåˆ‡ã‚‰ã‚ŒãŸï¼š{}{}{STRING}ã‚’{STRING}ã‹ã‚‰{STRING}ã¸ã®é‹é€çµŒè·¯ã¯ä»Šã‹ã‚‰åŠ©æˆé‡‘ã‚’å—ã‘ãªã„。
+STR_2036_COTTAGES :å°å±‹
+STR_2037_HOUSES :家
+STR_2038_FLATS :アパート
+STR_2039_TALL_OFFICE_BLOCK :大型オフィスビル
+STR_203A_SHOPS_AND_OFFICES :雑居
+STR_203B_SHOPS_AND_OFFICES :雑居
+STR_203C_THEATER :劇場
+STR_203D_STADIUM :スタジアム
+STR_203E_OFFICES :オフィスビル
+STR_203F_HOUSES :家
+STR_2040_CINEMA :映画館
+STR_2041_SHOPPING_MALL :デパート
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}ã“ã®ç”ºã®èµ·ã“ã›ã‚‹å‹•ä½œ - 詳ã—ãã¯é …目をクリックã—ã¾ã™
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}上記ã®ãƒªã‚¹ãƒˆã®æ´—濯中ã®å‹•ä½œã‚’èµ·ã“ã—ã¾ã™ã€‚
+STR_2045_ACTIONS_AVAILABLE :{BLACK}èµ·ã“ã›ã‚‹å‹•ä½œï¼š
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :å°åž‹åºƒå‘Šã‚­ãƒ£ãƒ³ãƒšãƒ¼ãƒ³
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :中型広告キャンペーン
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :大型広告キャンペーン
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :é“è·¯å†å»ºã‚’出資
+STR_204A_BUILD_STATUE_OF_COMPANY :会社長ã®å½«åƒã‚’建造
+STR_204B_FUND_NEW_BUILDINGS :市街地開発を出資
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :地方自治体を買åŽã—ã¾ã™
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} ã‚ãªãŸã®é‹é€çµŒè·¯ã®åˆ©ç”¨çŽ‡ã‚’増やã™ã«ã¯ã€ç”ºå†…ã®å°åž‹åºƒå‘Šã‚­ãƒ£ãƒ³ãƒšãƒ¼ãƒ³ã‚’è¡Œã„ã¾ã™ã€‚{} 価値:{CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} ã‚ãªãŸã®é‹é€çµŒè·¯ã®åˆ©ç”¨çŽ‡ã‚’増やã™ã«ã¯ã€ç”ºå†…ã®ä¸­åž‹åºƒå‘Šã‚­ãƒ£ãƒ³ãƒšãƒ¼ãƒ³ã‚’è¡Œã„ã¾ã™ã€‚{} 価値:{CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} ã‚ãªãŸã®é‹é€çµŒè·¯ã®åˆ©ç”¨çŽ‡ã‚’増やã™ã«ã¯ã€ç”ºå†…ã®å¤§åž‹åºƒå‘Šã‚­ãƒ£ãƒ³ãƒšãƒ¼ãƒ³ã‚’è¡Œã„ã¾ã™ã€‚{} 価値:{CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} 町内ã®é“è·¯ã®å†å»ºã‚’出資ã—ã¾ã™ã€‚最高 6 ヶ月間ã¾ã§ã€é“路交通ã«é€”絶を与ãˆã¾ã™ã€‚{} 価値:{CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} å声を増殖ã—ã¾ã™åœ°æ–¹è‡ªæ²»ä½“ã‚’è²·åŽã—ã¾ã™ã€‚ã‘ã‚Œã©ã‚‚ã€ã‚ã¶ãªã„ã§ã™ï¼{} 値段: {CURRENCY}
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN} {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_2802_TREES :{WHITE}木
+STR_2803_TREE_ALREADY_HERE :{WHITE}...木ã¯ã‚‚ã†ã‚ã‚Šã¾ã™
+STR_2806 :{WHITE}{STRING}
+STR_280E_TREES :木
+
+##id 0x3000
+STR_3003_NUMBER_OF_TRACKS :{BLACK}線路数
+STR_3004_PLATFORM_LENGTH :{BLACK}ホームã®é•·ã•
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}ä»–ã®é§…ã«è¿‘ã™ãŽã¾ã™
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}町内ã«é§…ï¼ãƒã‚¹åœï¼è·å½¹æ‰€ãŒå¤šã™ãŽã¾ã™
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}駅ï¼è·å½¹æ‰€ãŒå¤šã™ãŽã¾ã™
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}ãƒã‚¹åœãŒå¤šã™ãŽã¾ã™
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}è·å½¹æ‰€ãŒå¤šã™ãŽã¾ã™
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}ä»–ã®é§…ï¼è·å½¹æ‰€ã«è¿‘ã™ãŽã¾ã™
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}ã¾ãšã¯é§…を破壊ã—ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}ä»–ã®ç©ºæ¸¯ã«è¿‘ã™ãŽã¾ã™
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}ã¾ãšã¯ç©ºæ¸¯ã‚’破壊ã—ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“
+
+STR_3030_RENAME_STATION_LOADING :駅ï¼è·å½¹æ‰€ã®å称ã®å¤‰æ›´
+STR_3031_CAN_T_RENAME_STATION :{WHITE}駅åãŒå¤‰æ›´ã§ãã¾ã›ã‚“...
+
+############ range for rating starts
+STR_3035_APPALLING :最低
+STR_3036_VERY_POOR :ã¨ã¦ã‚‚悪ã„
+STR_3037_POOR :悪ã„
+STR_3038_MEDIOCRE :平凡
+STR_3039_GOOD :良ã„
+STR_303A_VERY_GOOD :ã¨ã¦ã‚‚良ã„
+STR_303B_EXCELLENT :ã™ã°ã‚‰ã—ã„
+STR_303C_OUTSTANDING :最高
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- 何も-
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}駅ã®ç·šè·¯æ•°ã‚’é¸æŠžã—ã¾ã™
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}駅ã®ãƒ›ãƒ¼ãƒ ã®é•·ã•ã‚’é¸æŠžã—ã¾ã™
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}ãƒã‚¹åœã®é…置をé¸æŠžã—ã¾ã™
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}è·å½¹æ‰€ã®é…置をé¸æŠžã—ã¾ã™
+STR_3054_SHOW_STATION_RATINGS :{BLACK}駅ã®è©•ä¾¡ã‚’表示ã—ã¾ã™
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}駅åを変更ã—ã¾ã™
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}å—ã‘å–る貨物ã®ãƒªã‚¹ãƒˆã‚’表示ã—ã¾ã™
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}空港ã®ã‚µã‚¤ã‚ºï¼ç¨®é¡žã‚’é¸æŠžã—ã¾ã™
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :駅
+STR_305F_AIRCRAFT_HANGAR :æ ¼ç´åº«
+STR_3060_AIRPORT :空港
+STR_3061_TRUCK_LOADING_AREA :è·å½¹æ‰€
+STR_3062_BUS_STATION :ãƒã‚¹åœ
+STR_3063_SHIP_DOCK :波止場
+STR_3068_DOCK :{WHITE}波止場
+STR_3069_BUOY :ブイ
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...駅ãŒåºƒã™ãŽã¾ã™
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}ã‚‚ã£ã¨äº‹ã‚’é¸ã¶ãŸã‚ã«ã€CTRLをプッシュ
+
+STR_UNDEFINED :(ãƒãƒ³ãƒŠãƒ»ã‚¹ãƒˆãƒªãƒ³ã‚°ï¼‰
+STR_STAT_CLASS_DFLT :デフォルト駅
+STR_STAT_CLASS_WAYP :通éŽç‚¹
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}造船所ã®é…ç½®
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}造船所ã®é…置をé¸æŠžã—ã¾ã™
+STR_3804_WATER :æ°´
+STR_3806_SHIP_DEPOT :造船所
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}ゲームをä¿å­˜
+STR_4001_LOAD_GAME :{WHITE}ゲームを開ã
+STR_4002_SAVE :{BLACK}ä¿å­˜
+STR_4003_DELETE :{BLACK}削除
+STR_4004 :{COMPANY}〠{DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} MB 使用å¯èƒ½
+STR_4007_GAME_SAVE_FAILED :{WHITE}ゲームã®ä¿å­˜ãŒå¤±æ•—ã—ã¾ã—ãŸ
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}ファイルを削除ã§ãã¾ã›ã‚“
+STR_4009_GAME_LOAD_FAILED :{WHITE}ゲームã®èª­ã¿è¾¼ã‚€ãŒå¤±æ•—ã—ã¾ã—ãŸ
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}ドライブã€ãƒ•ã‚©ãƒ«ãƒ€ã€ã‚²ãƒ¼ãƒ ãƒ•ã‚¡ã‚¤ãƒ«ã®ãƒªã‚¹ãƒˆ
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}ゲームã®ãƒ•ã‚¡ã‚¤ãƒ«å
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}é¸æŠžã—ãŸã‚²ãƒ¼ãƒ ã‚’削除ã—ã¾ã™
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}指定ã—ãŸãƒ•ã‚¡ã‚¤ãƒ«åã«ç¾åœ¨ã®ã‚²ãƒ¼ãƒ ã‚’ä¿å­˜ã—ã¾ã™
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}æ–°è¦ã‚²ãƒ¼ãƒ ç¨®é¡žã®é¸æŠž
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}シナリオ(緑)ã€ãƒ—リセットゲーム(é’)もã—ãã¯æ–°è¦ãƒ©ãƒ³ãƒ€ãƒ ã‚²ãƒ¼ãƒ ã‚’é¸æŠžã—ã¾ã™
+STR_4010_GENERATE_RANDOM_NEW_GAME :æ–°è¦ãƒ©ãƒ³ãƒ€ãƒ ã‚²ãƒ¼ãƒ ã‚’作æˆ
+
+##id 0x4800
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :ç‚­å‘
+STR_4803_POWER_STATION :発電所
+STR_4804_SAWMILL :製æ工場
+STR_4805_FOREST :森林
+STR_4806_OIL_REFINERY :石油精製所
+STR_4808_FACTORY :工場
+STR_4809_PRINTING_WORKS :å°åˆ·æ‰€
+STR_480A_STEEL_MILL :製鋼所
+STR_480B_FARM :農場
+STR_480C_COPPER_ORE_MINE :銅鉱石鉱山
+STR_480D_OIL_WELLS :油井
+STR_480E_BANK :銀行
+STR_480F_FOOD_PROCESSING_PLANT :食å“加工場
+STR_4810_PAPER_MILL :製紙工場
+STR_4811_GOLD_MINE :金山
+STR_4812_BANK :銀行
+STR_4813_DIAMOND_MINE :ダイヤモンド鉱山
+STR_4814_IRON_ORE_MINE :鉄鉱石鉱山
+STR_4815_FRUIT_PLANTATION :果物農園
+STR_4816_RUBBER_PLANTATION :ゴム園
+STR_4817_WATER_SUPPLY :給水設備
+STR_4818_WATER_TOWER :給水塔
+STR_4819_FACTORY :工場
+STR_481A_FARM :農場
+STR_481B_LUMBER_MILL :製æ所
+STR_481E_BATTERY_FARM :電池園
+STR_4826_SUGAR_MINE :砂糖鉱山
+
+############ range for requires starts
+############ range for requires ends
+
+STR_482F_COST :{BLACK}値段: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}ã“ã®ç”£æ¥­ãŒã“ã“ã«å»ºé€ ã§ãã¾ã›ã‚“...
+
+##id 0x5000
+STR_500D :{GOLD}{STRING}ã€ï½›ï½ {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :ã¤ã‚Šæ©‹ã€é‹¼é‰„製
+STR_500F_GIRDER_STEEL :ã‘ãŸæ©‹ã€é‹¼é‰„製
+STR_5010_CANTILEVER_STEEL :カンãƒãƒ¬ãƒãƒ¼æ©‹ã€é‹¼é‰„製
+STR_5011_SUSPENSION_CONCRETE :ã¤ã‚Šæ©‹ã€ã‚³ãƒ³ã‚¯ãƒªãƒ¼ãƒˆè£½
+STR_5012_WOODEN :木製
+STR_5013_CONCRETE :コンクリート製
+STR_5014_TUBULAR_STEEL :鋼管橋ã€é‹¼é‰„製
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}æ©‹ãŒã“ã“ã«å»ºé€ ã§ãã¾ã›ã‚“...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}トンãƒãƒ«ãŒã“ã“ã«å»ºé€ ã§ãã¾ã›ã‚“...
+STR_5017_RAILROAD_TUNNEL :鉄é“トンãƒãƒ«
+STR_5018_ROAD_TUNNEL :é“路トンãƒãƒ«
+
+##id 0x5800
+STR_5801_TRANSMITTER :é€ä¿¡æ©Ÿ
+STR_5802_LIGHTHOUSE :ç¯å°
+STR_5803_COMPANY_HEADQUARTERS :交通会社本部ビル
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...交通会社本部ビルãŒã‚ã‚Šã¾ã™
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :åå‰ç„¡ã—
+STR_SV_TRAIN_NAME :電車{COMMA}
+STR_SV_ROADVEH_NAME :車{COMMA}
+STR_SV_SHIP_NAME :シップ{COMMA}
+STR_SV_AIRCRAFT_NAME :飛行機{COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :{STRING} 北
+STR_SV_STNAME_SOUTH :{STRING} å—
+STR_SV_STNAME_EAST :{STRING} æ±
+STR_SV_STNAME_WEST :{STRING} 西
+STR_SV_STNAME_CENTRAL :{STRING}中
+STR_SV_STNAME_TRANSFER :{STRING}ä¹—ã‚Šæ›ãˆ
+STR_SV_STNAME_HALT :{STRING} åœç•™
+STR_SV_STNAME_VALLEY :{STRING} è°·
+STR_SV_STNAME_HEIGHTS :{STRING}高地
+STR_SV_STNAME_WOODS :{STRING} 森
+STR_SV_STNAME_LAKESIDE :{STRING} æ± å´
+STR_SV_STNAME_EXCHANGE :{STRING}更代
+STR_SV_STNAME_AIRPORT :{STRING}空港
+STR_SV_STNAME_OILFIELD :{STRING}油田
+STR_SV_STNAME_MINES :{STRING} 鉱区
+STR_SV_STNAME_DOCKS :{STRING} 船渠
+STR_SV_STNAME_BUOY_1 :{STRING} ボイ1
+STR_SV_STNAME_BUOY_2 :{STRING} ボイ2
+STR_SV_STNAME_BUOY_3 :{STRING} ボイ3
+STR_SV_STNAME_BUOY_4 :{STRING} ボイ4
+STR_SV_STNAME_BUOY_5 :{STRING} ボイ5
+STR_SV_STNAME_BUOY_6 :{STRING} ボイ6
+STR_SV_STNAME_BUOY_7 :{STRING} ボイ7
+STR_SV_STNAME_BUOY_8 :{STRING} ボイ8
+STR_SV_STNAME_BUOY_9 :{STRING} ボイ9
+STR_SV_STNAME_ANNEXE :{STRING}新館
+STR_SV_STNAME_SIDINGS :{STRING} å´ç·š
+STR_SV_STNAME_BRANCH :{STRING}支所
+STR_SV_STNAME_UPPER :{STRING}上
+STR_SV_STNAME_LOWER :{STRING}下
+STR_SV_STNAME_HELIPORT :{STRING}ヘリãƒãƒ¼ãƒˆ
+STR_SV_STNAME_FOREST :{STRING} 森林
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}難易度
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}安ã„
+STR_6802_MEDIUM :{BLACK}中ä½
+STR_6803_HARD :{BLACK}難ã—ã„
+STR_6804_CUSTOM :{BLACK}カスタム
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}競争者数ã®ä¸Šé™ï¼š{ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}競争者ã®é–‹å§‹é…延:{ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}市町æ‘数:{ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}工業数:{ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}åˆæœŸã®æœ€é«˜è²¸ä»˜é‡‘:{ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}åˆæœŸã®é‡‘利:{ORANGE}{COMMA}ï¼…
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}乗り物ã®é‹è»¢è²»ï¼š{ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}競争者ã®å»ºé€ é€Ÿåº¦ï¼š{ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}競争者ã®èƒ½åŠ›ãƒ¬ãƒ™ãƒ«ï¼š{ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}乗り物ã®æ©Ÿèƒ½åœæ­¢ï¼š{ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}助æˆé‡‘ã®ä¹—数:{ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}建造ã®ä¾¡å€¤ï¼š{ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}経済ã®å‚¾å‘:{ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}電車ã®å転:{ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}ç½å®³ï¼š{ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}町議会ã®åœ°åŸŸã®å†æ§‹ç¯‰ã«é–¢ã‚る姿勢:{ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :何も
+STR_6816_LOW :低ã„
+STR_6817_NORMAL :通常
+STR_6818_HIGH :高ã„
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :特ã«é…ã„
+STR_681C_SLOW :é…ã„
+STR_681D_MEDIUM :中ä½
+STR_681E_FAST :速ã„
+STR_681F_VERY_FAST :特ã«é€Ÿã„
+STR_6820_LOW :低ã„
+STR_6821_MEDIUM :中ä½
+STR_6822_HIGH :高ã„
+STR_6823_NONE :ãªã—
+STR_6824_REDUCED :軽減
+STR_6825_NORMAL :通常
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :特ã«å¹³ãŸã„
+STR_682B_FLAT :å¹³ãŸã„
+STR_682C_HILLY :丘陵地
+STR_682D_MOUNTAINOUS :山岳地
+STR_682E_STEADY :安定的
+STR_682F_FLUCTUATING :変動的
+STR_6830_IMMEDIATE :ã™ãã«
+STR_6831_3_MONTHS_AFTER_PLAYER :開始ã‹ã‚‰ 3 ヶ月
+STR_6832_6_MONTHS_AFTER_PLAYER :開始ã‹ã‚‰ 6 ヶ月
+STR_6833_9_MONTHS_AFTER_PLAYER :開始ã‹ã‚‰ 9 ヶ月
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :線路終点ã¨é§…
+STR_6835_AT_END_OF_LINE_ONLY :線路終点ã®ã¿
+STR_6836_OFF :切
+STR_6837_ON :å…¥
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}ãƒã‚¤ã‚¹ã‚³ã‚¢ã‚’表示
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7008_COMPANY_NAME :{BLACK}会社å
+STR_7009_PRESIDENT_NAME :{BLACK}社長ã®åå‰
+STR_700A_COMPANY_NAME :会社å
+STR_700B_PRESIDENT_S_NAME :社長ã®åå‰
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}会社åãŒå¤‰æ›´ã§ãã¾ã›ã‚“...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}社長ã®åå‰ãŒå¤‰æ›´ã§ãã¾ã›ã‚“...
+STR_7010 :{WHITE}{NUM}
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_TRAINS :{WHITE}{COMMA} 電車
+STR_AIRCRAFT :{WHITE}{COMMA} 飛行機
+STR_7042_NONE :{WHITE}何も
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+
+STR_LIVERY_BUS :ãƒã‚¹
+
+
+##id 0x8000
+STR_8104_AIRCRAFT :飛行機
+
+##id 0x8800
+
+
+
+STR_UNKNOWN_DESTINATION :ä¸æ˜Žè¡Œãå…ˆ
+STR_8816 :{BLACK}-
+
+
+STR_881F_BUILD_VEHICLE :{BLACK}車両を購入
+STR_8820_RENAME :{BLACK}å称を変更
+STR_8823_SKIP :{BLACK}スキップ
+STR_8824_DELETE :{BLACK}削除
+STR_8825_NON_STOP :{BLACK}直行便
+STR_8826_GO_TO :{BLACK}駅をé¸æŠž
+STR_8827_FULL_LOAD :{BLACK}全負è·
+STR_8828_UNLOAD :{BLACK}é™ã‚ã™
+STR_8829_ORDERS :{WHITE}{VEHICLE}(指令)
+STR_882A_END_OF_ORDERS :{SETX 10}- - 指å終了 - -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}鉄é“車両ãŒè³¼å…¥ã§ãã¾ã›ã‚“...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} 購入日付:{LTBLUE}{NUM}{BLACK} 価値:{LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} 価値:{LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}ç©ã¿é™ã‚ã—中
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}電車ã¯è»Šåº«ã«æ­¢ã‚ãªã‘ã‚Œã°æˆã‚‰ãªã„ã‚“ã§ã™
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}電車ãŒé›»è»Šåº«ã¸å›žé€ã§ãã¾ã›ã‚“...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}ã“れ以上ã®æŒ‡ä»¤ãŒè¿½åŠ ã§ãã¾ã›ã‚“
+STR_8832_TOO_MANY_ORDERS :{WHITE}指令ãŒå¤šã™ãŽã¾ã™
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}æ–°è¦æŒ‡ä»¤ãŒæŒ¿å…¥ã§ãã¾ã›ã‚“...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}ã“ã®æŒ‡ä»¤ãŒå‰Šé™¤ã§ãã¾ã›ã‚“...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}ã“ã®æŒ‡ä»¤ãŒå¤‰æ›´ã§ãã¾ã›ã‚“...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}ã“ã®è»Šè¼ŒãŒç§»å‹•ã§ãã¾ã›ã‚“...
+STR_8838_N_A :N/A{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}車両ãŒè²©å£²ã§ãã¾ã›ã‚“...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}電車庫ã¸ã®çµŒè·¯ãŒè¦‹ã¤ã‘られã¾ã›ã‚“
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}電車ãŒé–‹å§‹ï¼åœæ­¢ã§ãã¾ã›ã‚“...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}補修間隔:{LTBLUE}{COMMA}日間{BLACK} 最新ã®è£œä¿®ï¼š{LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}電車 - 情報を見るã«ã¯é›»è»Šã‚’クリックã—ã¾ã™
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}æ–°è¦é›»è»Šã‚’購入(電車庫ãŒå¿…è¦ï¼‰
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}電車 - 情報を見るã«ã¯é›»è»Šã‚’クリックã—ã¾ã™ã€‚車両を追加ï¼å–り除ãã«ã¯ãƒ‰ãƒ©ãƒƒã‚°ã—ã¾ã™ã€‚
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}æ–°è¦é›»è»Šè»Šä¸¡ã‚’購入
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}車両を販売ã™ã‚‹ã«ã¯ã€ã“ã“ã¸ãƒ‰ãƒ©ãƒƒã‚°ã—ã¾ã™
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}電車車両ã®ãƒªã‚¹ãƒˆ - 情報を見るã«ã¯è»Šä¸¡ã‚’クリックã—ã¾ã™
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}é¸æŠžã—ãŸè»Šä¸¡ã‚’購入
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}車両åを変更
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}電車ã®ç¾åœ¨ã®å‹•ä½œ - 開始ï¼åœæ­¢ã™ã‚‹ã«ã¯ã“ã“ã«ã‚¯ãƒªãƒƒã‚¯ã—ã¾ã™
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}電車ã®æŒ‡ä»¤ã‚’表示ã—ã¾ã™
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}電車を電車庫ã¸å›žé€ã—ã¾ã™ã€‚Control+クリックã™ã™ã‚‹ã¨ã€è£œä¿®ã®ã¿ã—ã¾ã™ã€‚
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}ä¿¡å·ãŒé’ã«ãªã‚‹ã¾ã§å¾…ãŸãšã«é›»è»Šã®ç¶šè¡Œã‚’強制ã—ã¾ã™
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}電車を逆転ã—ã¾ã™
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}電車ã®æƒ…報を表示ã—ã¾ã™
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}補修間隔を増やã™
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}補修間隔を減らã™
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}ç©ã‚“ã è²¨ç‰©ã®æƒ…報を表示ã—ã¾ã™
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}電車車両ã®æƒ…報を表示ã—ã¾ã™
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}å„車両ã®å®¹é‡ã‚’表示ã—ã¾ã™
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}貨物種類ã«ä¸¦ã¹æ›¿ãˆã¦é›»è»Šã®åˆè¨ˆå®¹é‡ã‚’表示ã—ã¾ã™
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}指令リスト - 指令をé¸æŠžã™ã‚‹ã«ã¯ã‚¯ãƒªãƒƒã‚¯ã—ã¾ã™ã€‚
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}ç¾åœ¨ã®æŒ‡ä»¤ã‚’スキップã—ã¦ã€æ¬¡ã¸ç§»å‹•ã—ã¾ã™
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}é¸æŠžã—ãŸæŒ‡ä»¤ã‚’削除ã—ã¾ã™
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}é¸æŠžã—ãŸæŒ‡ä»¤ã‚’「直行便ã€ã«ã—ã¾ã™
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}é¸æŠžã—ãŸæŒ‡ä»¤ã®å‰ï¼ãƒªã‚¹ãƒˆã®çµ‚ã‚ã‚Šã«æ–°è¦æŒ‡ä»¤ã‚’挿入ã—ã¾ã™
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}é¸æŠžã—ãŸæŒ‡ä»¤ã«å…¨è² è·ã¾ã§å¾…ã¤ã“ã¨ã‚’強制ã—ã¾ã™
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}é¸æŠžã—ãŸæŒ‡ä»¤ã«é™ã‚ã™ã“ã¨ã‚’強制ã—ã¾ã™
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}{STRING} ãŒæ–°ç™»å ´ï¼
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}値段: {CURRENCY}é‡ã•ï¼š {WEIGHT_S}{}スピード: {VELOCITY} 力: {POWER}{}é‹è»¢è²»ï¼š{CURRENCY}ï¼å¹´{}体ç©ï¼š {CARGO}
+STR_885C_BROKEN_DOWN :{RED}故障
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}年齢:{LTBLUE}{STRING}{BLACK} é‹è»¢è²»ï¼š{LTBLUE}1 å¹´é–“ã«{CURRENCY}
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}é‡ã•ï¼š {LTBLUE}{WEIGHT_S} {BLACK}力: {LTBLUE}{POWER}{BLACK} 最大スピード: {LTBLUE}{VELOCITY}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}今年ã®åˆ©ç›Šï¼š{LTBLUE}{CURRENCY}(去年:{CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}信頼度:{LTBLUE}{COMMA}% {BLACK}最新補修後ã®æ•…障:{LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}åœæ­¢ä¸­
+
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}電車事件ï¼{}{COMMA} 人ãŒæ­»äº¡
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}電車ãŒé€†è»¢ã§ãã¾ã›ã‚“...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}電車車両åを変更
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}車両åãŒå¤‰æ›´ã§ãã¾ã›ã‚“...
+
+STR_TRAIN_STOPPING :{RED}æ­¢ã¾ã£ã¦ã„ã¾ã™
+STR_TRAIN_STOPPING_VEL :{RED}æ­¢ã¾ã£ã¦ã„ã¾ã™ã€ {VELOCITY}
+STR_TRAIN_NO_POWER :{RED}é›»æºã¯ã‚ã‚Šã¾ã›ã‚“
+STR_TRAIN_START_NO_CATENARY :電車ã¯ã‘ã‚“åž‚ç·šãŒã‚ã‚Šã¾ã›ã‚“ã‹ã‚‰ã€é›»è»Šã¯å‹•ã出ã›ã¾ã›ã‚“。
+
+##id 0x9000
+STR_9002 :{WHITE}{VEHICLE}
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+
+
+
+##id 0x9800
+STR_980F :{WHITE}{VEHICLE}
+
+
+##id 0xA000
+STR_A00A :{WHITE}{VEHICLE}
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+
+##id 0xB000
+
+
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}ï¼{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}ï¼{COMMA})
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+############ End of order list
+
+
+
+
+
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} 飛行機
+
+
+STR_VEH_WITH_SHARED_ORDERS_LIST :{WHITE}シェアード ・ルート{COMMA} 車
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}ã“ã®ã‚¹ã‚±ã‚¸ãƒ¥ãƒ¼ãƒ«ã®è»Šå…¨éƒ¨ã‚’見ã›ã¾ã™
+
+### depot strings
+
+
+
+
+STR_VEHICLE_LIST_TRAIN_DEPOT :{BLACK}{STRING} - {COMMA} 電車
+STR_VEHICLE_LIST_ROADVEH_DEPOT :{BLACK}{STRING} - {COMMA} 車
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} シップ
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} 飛行機
+
+
+
+
+
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+
+
+############ Lists rail types
+
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+
+########### String for New Landscape Generator
+
+STR_WORLD_GENERATION_CAPTION :{WHITE}世界発電
+STR_TREE_PLACER :{BLACK}木アルゴリズム:
+STR_TERRAIN_TYPE :{BLACK}地形種類:
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_START_DATE_QUERY_CAPT :{WHITE}始ã‚る年を変ãˆã¾ã™
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_GENERATION_PROGRESS :{BLACK}{NUM} ï¼ {NUM}
+STR_WORLD_GENERATION :{BLACK}世界発電
+STR_TREE_GENERATION :{BLACK}木発電
+STR_UNMOVABLE_GENERATION :{BLACK}å¯å‹•ãªã„ 発電
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+
+########### String for new airports
+
+
+############ Tooltip measurment
+
+
+########
diff --git a/src/lang/unfinished/latvian.txt b/src/lang/unfinished/latvian.txt
new file mode 100644
index 000000000..8b41daf62
--- /dev/null
+++ b/src/lang/unfinished/latvian.txt
@@ -0,0 +1,1485 @@
+##name Latvian
+##ownname Latviešu valoda
+##isocode lv_LV.UTF-8
+##plural 3
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}A'rpus kartes robez'as
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Pa'ra'k tuvu kartes malai
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Nepietiek naudas - vajag {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Zemei ja'bu't plakanai
+STR_0008_WAITING :{BLACK}Gaidam: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (cel'a' no
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Pien'em: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Pien'em: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :Pasaz'ierus
+STR_0010_COAL :Ogles
+STR_0011_MAIL :Pastu
+STR_0012_OIL :Naftu
+STR_0013_LIVESTOCK :Liellopus
+STR_0014_GOODS :Preces
+STR_0015_GRAIN :Graudus
+STR_0016_WOOD :Kokmateria'lus
+STR_0017_IRON_ORE :Dzelzs ru'du
+STR_0018_STEEL :Te'raudu
+STR_0019_VALUABLES :Ve'rtspapi'ri
+STR_001A_COPPER_ORE :Vara ru'da
+STR_001B_MAIZE :Kukuru'za
+STR_001C_FRUIT :Augl'i
+STR_001D_DIAMONDS :Dimanti
+STR_001E_FOOD :Pa'rtika
+STR_001F_PAPER :Papi'rs
+STR_0020_GOLD :Zelts
+STR_0021_WATER :U'dens
+STR_0022_WHEAT :Kvies'i
+STR_0023_RUBBER :Gumija
+STR_0024_SUGAR :Cukurs
+STR_0025_TOYS :Rotal'lietas
+STR_0026_CANDY :Saldumi
+STR_0027_COLA :Kola
+STR_0028_COTTON_CANDY :Cukurvate
+STR_0029_BUBBLES :Burbul'i
+STR_002A_TOFFEE :Cukurpla'ksnes
+STR_002B_BATTERIES :Baterijas
+STR_002C_PLASTIC :Plastmasa
+STR_002D_FIZZY_DRINKS :Burbul'u'den'i
+STR_002E :
+STR_002F_PASSENGER :Pasaz'ieris
+STR_0030_COAL :Ogle
+STR_0031_MAIL :Pasts
+STR_0032_OIL :Nafta
+STR_0033_LIVESTOCK :Liellopi
+STR_0034_GOODS :Preces
+STR_0035_GRAIN :Graudi
+STR_0036_WOOD :Kokmaterea'li
+STR_0037_IRON_ORE :Dzelzs ru'da
+STR_0038_STEEL :Te'rauds
+STR_0039_VALUABLES :Ve'rtspapi'ri
+STR_003A_COPPER_ORE :Vara ru'da
+STR_003B_MAIZE :Kukuru'za
+STR_003C_FRUIT :Augl'i
+STR_003D_DIAMOND :Dimanti
+STR_003E_FOOD :Pa'rtika
+STR_003F_PAPER :papi'rs
+STR_0040_GOLD :Zelts
+STR_0041_WATER :U'dens
+STR_0042_WHEAT :Kvies'i
+STR_0043_RUBBER :Gumija
+STR_0044_SUGAR :Cukurs
+STR_0045_TOY :Rotal'lieta
+STR_0046_CANDY :Saldumi
+STR_0047_COLA :Kola
+STR_0048_COTTON_CANDY :Cukurvate
+STR_0049_BUBBLE :Burbulis
+STR_004A_TOFFEE :Cukurpla'ksni'te
+STR_004B_BATTERY :Baterijas
+STR_004C_PLASTIC :Plastmasas
+STR_004D_FIZZY_DRINK :Burbul'u'den'u
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} pasaz'ieris
+STR_QUANTITY_COAL :{WEIGHT} tonna ogl'u
+STR_QUANTITY_MAIL :{COMMA} pasta maiss
+STR_QUANTITY_OIL :{VOLUME} naftas
+STR_QUANTITY_LIVESTOCK :{COMMA} liellops
+STR_QUANTITY_GOODS :{COMMA} prec'u kaste
+STR_QUANTITY_GRAIN :{WEIGHT} tonna graudu
+STR_QUANTITY_WOOD :{WEIGHT} tonna kokmaterea'lu
+STR_QUANTITY_IRON_ORE :{WEIGHT} tonna dzelzs ru'das
+STR_QUANTITY_STEEL :{WEIGHT} tonna te'rauda
+STR_QUANTITY_VALUABLES :{COMMA} maiss ar ve'rtspapi'riem
+STR_QUANTITY_COPPER_ORE :{WEIGHT} tonna vara ru'das
+STR_QUANTITY_MAIZE :{WEIGHT} tonna kukuru'zas
+STR_QUANTITY_FRUIT :{WEIGHT} tonna augl'u
+STR_QUANTITY_DIAMONDS :{COMMA} maiss ar dimantiem
+STR_QUANTITY_FOOD :{WEIGHT} tonna pa'rtikas prec'u
+STR_QUANTITY_PAPER :{WEIGHT} tonna papi'ra
+STR_QUANTITY_GOLD :{COMMA} zelta maiss
+STR_QUANTITY_WATER :{VOLUME} u'dens
+STR_QUANTITY_WHEAT :{WEIGHT} tonna kvies'u
+STR_QUANTITY_RUBBER :{VOLUME} tonna gumijas
+STR_QUANTITY_SUGAR :{WEIGHT} tonna cukura
+STR_QUANTITY_TOYS :{COMMA} rotal'lieta
+STR_QUANTITY_SWEETS :{COMMA} saldumu maiss
+STR_QUANTITY_COLA :{VOLUME} kolas
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} tonna cukurvates
+STR_QUANTITY_BUBBLES :{COMMA} burbulis
+STR_QUANTITY_TOFFEE :{WEIGHT} tonna cukurpla'ksni's'u
+STR_QUANTITY_BATTERIES :{COMMA} baterija
+STR_QUANTITY_PLASTIC :{VOLUME} plastmasas
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} burbul'u'dens
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}PA
+STR_ABBREV_COAL :{TINYFONT}OG
+STR_ABBREV_MAIL :{TINYFONT}PT
+STR_ABBREV_OIL :{TINYFONT}NF
+STR_ABBREV_LIVESTOCK :{TINYFONT}LL
+STR_ABBREV_GOODS :{TINYFONT}PR
+STR_ABBREV_GRAIN :{TINYFONT}GR
+STR_ABBREV_WOOD :{TINYFONT}KM
+STR_ABBREV_IRON_ORE :{TINYFONT}DZ
+STR_ABBREV_STEEL :{TINYFONT}TR
+STR_ABBREV_VALUABLES :{TINYFONT}VP
+STR_ABBREV_COPPER_ORE :{TINYFONT}VR
+STR_ABBREV_MAIZE :{TINYFONT}KU
+STR_ABBREV_FRUIT :{TINYFONT}AU
+STR_ABBREV_DIAMONDS :{TINYFONT}DM
+STR_ABBREV_FOOD :{TINYFONT}PP
+STR_ABBREV_PAPER :{TINYFONT}PS
+STR_ABBREV_GOLD :{TINYFONT}ZE
+STR_ABBREV_WATER :{TINYFONT}UD
+STR_ABBREV_WHEAT :{TINYFONT}KV
+STR_ABBREV_RUBBER :{TINYFONT}GU
+STR_ABBREV_SUGAR :{TINYFONT}CU
+STR_ABBREV_TOYS :{TINYFONT}RT
+STR_ABBREV_SWEETS :{TINYFONT}SA
+STR_ABBREV_COLA :{TINYFONT}KO
+STR_ABBREV_CANDYFLOSS :{TINYFONT}CV
+STR_ABBREV_BUBBLES :{TINYFONT}BB
+STR_ABBREV_TOFFEE :{TINYFONT}CP
+STR_ABBREV_BATTERIES :{TINYFONT}BT
+STR_ABBREV_PLASTIC :{TINYFONT}PL
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}BU
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Karte - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Spe'les parametri
+STR_00B2_MESSAGE :{YELLOW}Zin'ojums
+STR_00B3_MESSAGE_FROM :{YELLOW}Zin'ojums no {STRING}
+STR_00B4_CAN_T_DO_THIS :{WHITE}Ta' nevar dari't....
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}S'o laukumu nevar noli'dzina't....
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Org'ìina'la's autortiesi'bas {COPYRIGHT} 1995 Chris Sawyer, Visas tiesi'bas rezerve'tas
+STR_00B7_VERSION :{BLACK}OpenTTD versija {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2004 OpenTTD grupa
+STR_TRANSLATED_BY :{BLACK} Tulkota'js(i) - Leo Selavo
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Beigt
+STR_00C8_YES :{BLACK}Ja'
+STR_00C9_NO :{BLACK}Ne'
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Vai Tu ties'a'm gribi pamest s'o spe'li un iet uz {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :Neka'
+STR_00D1_DARK_BLUE :Tums'i zils
+STR_00D2_PALE_GREEN :Gais'i zal's'
+STR_00D3_PINK :Roza'
+STR_00D4_YELLOW :Dzeltens
+STR_00D5_RED :Sarkans
+STR_00D6_LIGHT_BLUE :Gais'i zils
+STR_00D7_GREEN :Zal's'
+STR_00D8_DARK_GREEN :Tums'i zal's'
+STR_00D9_BLUE :Zils
+STR_00DA_CREAM :Krema kra'sa'
+STR_00DB_MAUVE :Mauve
+STR_00DC_PURPLE :Purpurs
+STR_00DD_ORANGE :Oranz's
+STR_00DE_BROWN :Bru'ns
+STR_00DF_GREY :Pele'ks
+STR_00E0_WHITE :Balts
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE} Spe'le' ir pa'ra'k daudz transporta li'dzekl'u
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Atras'ana's vieta
+STR_00E5_CONTOURS :Kontu'ras
+STR_00E6_VEHICLES :Transporta li'dzekl'i
+STR_00E7_INDUSTRIES :Industrijas
+STR_00E8_ROUTES :Mars'ruti
+STR_00E9_VEGETATION :Veg'eta'cija
+STR_00EA_OWNERS :I'pas'nieki
+STR_00EB_ROADS :{BLACK}{TINYFONT}Cel'i
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Dzelzscel'i
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Stacijas/Lidostas/Doki
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Celtnes/Industrijas
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Transporta li'dzekl'i
+STR_00F0_100M :{BLACK}{TINYFONT}100m
+STR_00F1_200M :{BLACK}{TINYFONT}200m
+STR_00F2_300M :{BLACK}{TINYFONT}300m
+STR_00F3_400M :{BLACK}{TINYFONT}400m
+STR_00F4_500M :{BLACK}{TINYFONT}500m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Vilcieni
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Cel'u transporta li'dzekl'i
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Kug'i
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Lidmaši'na
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Transporta mars'ruti
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Ogl'u raktuve
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Elektrostacija
+STR_00FC_FOREST :{BLACK}{TINYFONT}Mežs
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}Koku za'g'e'tava
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Naftas apstra'des stacija
+STR_00FF_FARM :{BLACK}{TINYFONT}Ferma
+STR_0100_FACTORY :{BLACK}{TINYFONT}Rupnîca
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Tipogrâfija
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Naftas atradnes
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Dzelzs ru'das raktuves
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Te'rauda lietuve
+STR_0105_BANK :{BLACK}{TINYFONT}Banka
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Papi'ra ru'pni'ca
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Zelta raktuves
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Pa'rtikas apstra'des ru'pni'ca
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Dimantu raktuves
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Vara ru'das raktuves
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Augl'u planta'cija
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Kauc'uka planta'cija
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}U'dens avoti
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}U'denstornis
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}Bal'k'u za'g'e'tava
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Cukurvates mez's'
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Saldumu ru'pni'ca
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Bateriju ferma
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Kolas akas
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Rotaïlietu Veikals
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Rotaïlietu Rupnîca
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Plastmasas stru'klakas
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Burbul'u'den'u ru'pni'ca
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Burbul'u g'enera'tors
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Cukurpla'ks'n'u lauztuves
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Cukura raktuves
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Dzelzscel'a stacija
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Kravas auto iekrautuve
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Autobusa stacija
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Lidosta/Helikopteru osta
+STR_011F_DOCK :{BLACK}{TINYFONT}Doki
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Neli'dzena zeme
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Za'la'ju zeme
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Kaila zeme
+STR_0123_FIELDS :{BLACK}{TINYFONT}Lauki
+STR_0124_TREES :{BLACK}{TINYFONT}Koki
+STR_0125_ROCKS :{BLACK}{TINYFONT}Akmen'i
+STR_0126_WATER :{BLACK}{TINYFONT}U'dens
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Nav i'pas'nieka
+STR_0128_TOWNS :{BLACK}{TINYFONT}Pilse'tas
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Industrijas
+STR_012A_DESERT :{BLACK}{TINYFONT}Tuksnesis
+STR_012B_SNOW :{BLACK}{TINYFONT}Sniegs
+STR_012C_MESSAGE :{WHITE}Zin'ojums
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Atcelt
+STR_012F_OK :{BLACK}Labi
+STR_0130_RENAME :{BLACK}Maini't nosaukumu
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Define'ti pa'ra'k daudz nosaukumi
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Izve'le'tais nosaukums jau tiek lietots
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...pieder {STRING}
+STR_013C_CARGO :{BLACK}Krava
+STR_013D_INFORMATION :{BLACK}Informa'cija
+STR_013E_CAPACITIES :{BLACK}Ietilpi'ba
+STR_013E_TOTAL_CARGO :{BLACK}Krava kopa'
+STR_013F_CAPACITY :{BLACK}Ietilpi'ba: {LTBLUE}{CARGO}
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Kope'ja' vilciena kravas ietilpi'ba:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_0140_NEW_GAME :{BLACK}Jauna spe'le
+STR_0141_LOAD_GAME :{BLACK}Iela'de't spe'li
+STR_SINGLE_PLAYER :{BLACK}Viens spe'le'ta'js
+STR_MULTIPLAYER :{BLACK}Daudz-spe'le'ta'ju
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Kartes izme'ri:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Spe'les rez'i'mi
+
+STR_0150_SOMEONE :ka'ds{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Pasaules karte
+STR_0152_TOWN_DIRECTORY :Pilse'tu saraksts
+STR_0153_SUBSIDIES :Subsi'dijas
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Pana'kumu grafiks
+STR_0155_INCOME_GRAPH :Iena'kumu grafiks
+STR_0156_DELIVERED_CARGO_GRAPH :Transporte'ta's kravas grafiks
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Uzn'e'me'jdarbi'bas ve'stures grafiks
+STR_0158_COMPANY_VALUE_GRAPH :Kompa'nijas ve'rti'bas grafiks
+STR_0159_CARGO_PAYMENT_RATES :Kravas apmaksas cenas
+STR_015A_COMPANY_LEAGUE_TABLE :Kompa'nijas li'gu tabula
+STR_PERFORMANCE_DETAIL_MENU :Detalize'ti uzn'e'me'jdarbi'bas rezulta'ti
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}Par OpenTTD
+STR_015C_SAVE_GAME :Saglaba't spe'li
+STR_015D_LOAD_GAME :Iela'de't spe'li
+STR_015E_QUIT_GAME :Pamest spe'li
+STR_015F_QUIT :Iziet a'ra'
+STR_0160_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Vai tu patiesi gribi pamest s'o spe'li?
+STR_0161_QUIT_GAME :{WHITE}Pamest spe'li
+STR_SORT_ORDER_TIP :{BLACK}Izve'le'ties saka'rtojumu (dilstos's/augos's)
+STR_SORT_CRITERIA_TIP :{BLACK}Izve'le'ties sorte's'anas krite'riju
+STR_SORT_BY :{BLACK}Saka'rtot pe'c
+
+STR_SORT_BY_POPULATION :{BLACK}Iedzi'vota'ju skaita
+STR_SORT_BY_PRODUCTION :{BLACK}Produkcijas
+STR_SORT_BY_TYPE :{BLACK}Tipa
+STR_SORT_BY_TRANSPORTED :{BLACK}Transporte'ta'
+STR_SORT_BY_NAME :{BLACK}Va'rda
+STR_SORT_BY_DROPDOWN_NAME :Va'rds
+STR_SORT_BY_DATE :{BLACK}Datums
+STR_SORT_BY_NUMBER :Nummurs
+STR_SORT_BY_PROFIT_LAST_YEAR :Paga'jus'a' gada iena'kums
+STR_SORT_BY_PROFIT_THIS_YEAR :S'i' gada iena'kums
+STR_SORT_BY_AGE :Vecums
+STR_SORT_BY_RELIABILITY :Dros'i'ba
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Kope'ja' ietilpi'ba pe'c kravas tipa
+STR_SORT_BY_MAX_SPEED :maksima'lais a'trums
+
+############ range for months starts
+STR_0162_JAN :Jan
+STR_0163_FEB :Feb
+STR_0164_MAR :Mar
+STR_0165_APR :Apr
+STR_0166_MAY :Mai
+STR_0167_JUN :Jûn
+STR_0168_JUL :Jûl
+STR_0169_AUG :Aug
+STR_016A_SEP :Sep
+STR_016B_OCT :Okt
+STR_016C_NOV :Nov
+STR_016D_DEC :Dec
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Pauze't spe'li
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Saglaba't spe'li, pamest spe'li, beigt
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Para'di't kompa'nijas staciju sarakstu
+STR_0174_DISPLAY_MAP :{BLACK}Para'di't karti
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Para'di't karti, pilse'tu sarakstu
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Para'di't pilse'tu sarakstu
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Para'di't kompa'niju finansia'lo sta'vokli
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Para'di't kompa'niju vispa're'jo informa'ciju
+STR_0179_DISPLAY_GRAPHS :{BLACK}Para'di't grafikus
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Para'di't kompa'niju li'gu tabulu
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Para'di't kompa'nijas vilcienu sarakstu
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Para'di't kompa'nijas automobil'u sarakstu
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Para'di't kompa'nijas kug'u sarakstu
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Para'di't kompa'nijas lidmas'i'nu sarakstu
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Palielina't skatu
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Samazina't skatu
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Bu've't sliez'u posmu
+STR_0182_BUILD_ROADS :{BLACK}Bu've't cel'us
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Bu've't kug'u dokus
+STR_0184_BUILD_AIRPORTS :{BLACK}Bu've't lidlaukus
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Sta'di't kokus, zi'mes, u.tml.
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Zemes informa'cija
+STR_0187_OPTIONS :{BLACK}Rez'i'mi
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Nevar maini't servisa interva'lu...
+STR_018B_CLOSE_WINDOW :{BLACK}Aiztaisi't logu
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Loga virsraksts - velc s'o lai pa'rvietotu logu
+STR_STICKY_BUTTON :{BLACK}Atzi'me' s'o logu ka' neaiztaisa'mu ar
+STR_RESIZE_BUTTON :{BLACK}Uzklikðíini un velc lai mainîtu ðî loga izmçrus
+STR_SAVELOAD_HOME_BUTTON :{BLACK}Klik te lai ietu uz tekos'o saglaba's'anas un iela'de's'anas direktorju
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Demole't celtnes un tml. uz zemes laucin'a
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Pazemina't zemes stu'ri
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Pacelt zemes stu'ri
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Skrollba'rs - bi'da sarakstu augs'up/lejup
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Skrollba'ri - skrolle' sarakstu pal kreisi un pa labi
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Ra'di't zemes kontu'ras uz kartes
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Ra'di't transporta li'dzekl'us uz kartes
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Ra'di't industrijas uz kartes
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Ra'di't transporta mars'rutus uz kartes
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Ra'di't veg'eta'ciju uz kartes
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Ra'di't zemes i'pas'niekus uz kartes
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Iesle'gt/izsle'gt pilse'tu nosaukumus uz kartes
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}S'i' gada iena'kums: {CURRENCY} (paga'jus'aja' gada': {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} gad{P s i} ({COMMA})
+STR_AGE_RED :{RED}{COMMA} gad{P s i} ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Cel'u transporta li'dzeklis
+STR_019D_AIRCRAFT :Lidmas'i'na
+STR_019E_SHIP :Kug'is
+STR_019F_TRAIN :Vilciens
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} paliek vecs
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} paliek l'oti vecs
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} paliek l'oti vecs un ir steidzami ja'nomaina
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Zemes laukuma informa'cija
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Izmaksas noli'dzina's'anai: {LTBLUE}N/A
+STR_01A5_COST_TO_CLEAR :{BLACK}Izmaksas noli'dzina's'anai: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :Nav
+STR_01A7_OWNER :{BLACK}I'pas'nieks: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Viete'ja's varas iesta'des: {LTBLUE}{STRING}
+STR_01A9_NONE :Neviens/neviena
+STR_01AA_NAME :{BLACK}Va'rds
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :Pirmais
+STR_01AD_2ND :Otrais
+STR_01AE_3RD :Tres'ais
+STR_01AF_4TH :Ceturtais
+STR_01B0_5TH :5.
+STR_01B1_6TH :6.
+STR_01B2_7TH :7.
+STR_01B3_8TH :8.
+STR_01B4_9TH :9.
+STR_01B5_10TH :10.
+STR_01B6_11TH :11.
+STR_01B7_12TH :12.
+STR_01B8_13TH :13.
+STR_01B9_14TH :14.
+STR_01BA_15TH :15.
+STR_01BB_16TH :16.
+STR_01BC_17TH :17.
+STR_01BD_18TH :18.
+STR_01BE_19TH :19.
+STR_01BF_20TH :20.
+STR_01C0_21ST :21.
+STR_01C1_22ND :22.
+STR_01C2_23RD :23.
+STR_01C3_24TH :24.
+STR_01C4_25TH :25.
+STR_01C5_26TH :26.
+STR_01C6_27TH :27.
+STR_01C7_28TH :28.
+STR_01C8_29TH :29.
+STR_01C9_30TH :30.
+STR_01CA_31ST :31.
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Pien'em kravu: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Dz'eza muzikas automa'ts
+STR_01D3_SOUND_MUSIC :Skan'a/mu'zika
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Ra'di't skan'as/mu'zikas logu
+STR_01D5_ALL :{TINYFONT}Visi
+STR_01D6_OLD_STYLE :{TINYFONT}Vecais stils
+STR_01D7_NEW_STYLE :{TINYFONT}Jaunais stils
+STR_01D8_EZY_STREET :{TINYFONT}Ezy iela
+STR_01D9_CUSTOM_1 :{TINYFONT}Specia'lais 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Specia'lais 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Muzikas skal'ums
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Efektu skal'ums
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MIN ' ' ' ' ' ' MAX
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Pa'rlekt uz ieprieks'e'jo dziesmu
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Pa'rlekt us na'kamo dziesmu
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Apsta'dina't muzikas spe'le's'anu
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Sa'kt muzikas spe'le's'anu
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Bi'di klok'us lai maini'tu muzikas un skan'as efektu skal'umu
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Treks{SETX 88}Nosaukums
+STR_01E9_SHUFFLE :{TINYFONT}Sajaukt
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Programma
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Mu'zikas programmas izve'le
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Treka indekss
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Programma - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}Dze'st
+STR_01F1_SAVE :{TINYFONT}{BLACK}Saglaba't
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Tekos'a' muzikas gabalu programma
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Atzi'me' ''visas dziesmas'' programmu
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Atzi'me' ''veca' stila muzika'' programmu
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Atzi'me' ''jauna' stila muzika'' programmu
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Atzi'me' ''1. Specia'lo'' (lietota'ja-define'to) programmu
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Atzi'me' ''2. Specia'lo'' (lietota'ja-define'to) programmu
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Dze'st tekos'o programmu (tikai 1.Specia'lo vai 2.Specia'lo)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Saglaba't muzikas rez'i'mus
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Uzkliks'k'ini uz muzikas treku lai to pievienotu tekos'ajai programmai (1.Specia'lai vai 2.Specia'lai)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Pa'rsle'gt muzikas saraksta sajauks'anu
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Para'di't muzikas saraksta atzi'me's'anas logu
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Uzkliks'k'ini uz servisa lai iecentre'tu skatu uz industriju vai pilse'tu
+STR_01FE_DIFFICULTY :{BLACK}Gru'ti'bas paka'pe ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Pe'de'ja' zin'a
+STR_0201_MESSAGE_SETTINGS :Zin'ojumu rez'i'mi
+STR_MESSAGE_HISTORY_MENU :Zin'ojumu ve'sture
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Para'di't pe'de'jo zin'u, para'di't zin'as rez'i'mus
+STR_0204_MESSAGE_OPTIONS :{WHITE}Zin'ojuma rez'i'mi
+STR_0205_MESSAGE_TYPES :{BLACK}Zin'ojumu veidi:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Spe'le'ta'ja stacija' ierodas pirmais transporta li'dzeklis
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Sa'ncens'a stacija' ierodas pirmais transporta li'dzeklis
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Negadijumi / ava'rijas
+STR_0209_COMPANY_INFORMATION :{YELLOW}Kompa'nijas informa'cija
+STR_020A_ECONOMY_CHANGES :{YELLOW}Ekonomijas izmain'as
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Padoms / informa'cija par spe'le'ta'ja transporta li'dzekl'iem
+STR_020C_NEW_VEHICLES :{YELLOW}Jaunie transporta li'dzekl'i
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Izmain'as kravas pien'ems'ana'
+STR_020E_SUBSIDIES :{YELLOW}Subsi'dijas
+STR_020F_GENERAL_INFORMATION :{YELLOW}Vispa'ri'ga informa'cija
+STR_MESSAGES_ALL :{YELLOW}Rez'i'ms visiem zin'ojumu tipiem (iesle'gts/izsle'gts/kopsavilkums)
+STR_MESSAGE_SOUND :{YELLOW}Spe'le't skan'as effektu zin'u kopsavilkumiem
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...pa'ra'k ta'lu no ieprieks'e'ja' gala punkta
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Laba'ka's kompa'nijas, kas sasniegus'as{NUM}{}({STRING} Level)
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Kompa'niju li'gu tabula {NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Biznesmens
+STR_0214_ENTREPRENEUR :Uzn'e'me'js
+STR_0215_INDUSTRIALIST :Industria'lists
+STR_0216_CAPITALIST :Kapita'lists
+STR_0217_MAGNATE :Magna'ts
+STR_0218_MOGUL :Moguls
+STR_0219_TYCOON_OF_THE_CENTURY :Gadsimta supervecis
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} sasniegus'i '{STRING}' statusu!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} no {COMPANY} sasniegusi '{STRING}' statusu!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Radi't scena'riju
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Scena'riju redaktors
+STR_0223_LAND_GENERATION :{WHITE}Zemes g'enere's'ana
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Nejaus'i g'enere'ta zeme
+STR_0227_RESET_LAND :{BLACK}Atjaunot zemi
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Palielina't zemes apgabalu pazemina's'anai/pazels'anai
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Samazina't zemes apgabalu pazemina's'anai/pazels'anai
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}G'enere't nejaus'u zemi
+STR_022B_RESET_LANDSCAPE :{BLACK}Atjaunot zemes virsu
+STR_022C_RESET_LANDSCAPE :{WHITE}Atjaunot zemes virsu
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Vai tu paties'a'm gribi atjaunot zemes virsu?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Zemes virsas g'enere's'ana
+STR_022F_TOWN_GENERATION :{BLACK}Pilse'tu g'enere's'ana
+STR_0230_INDUSTRY_GENERATION :{BLACK}Industrijas g'enere's'ana
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Cel'u konstrukcija
+STR_0233_TOWN_GENERATION :{WHITE}Pilse'tu g'enere's'ana
+STR_0234_NEW_TOWN :{BLACK}Jauna pilse'ta
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Konstrue't jaunu pilse'tu
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Te nevar bu've't jaunu pilse'tu...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...pa'ra'k tuvu kartes malai
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...pa'ra'k tuvu citai pilse'tai
+STR_0239_SITE_UNSUITABLE :{WHITE}...vieta nav pieme'rota
+STR_023A_TOO_MANY_TOWNS :{WHITE}...pa'ra'k daudz pilse'tu
+STR_CANNOT_GENERATE_TOWN :{WHITE}Celt pilse'tas nav iespe'jams
+STR_NO_SPACE_FOR_TOWN :{WHITE}...Uz kartes nav vaira'k vietas
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Palielina't pilse'tas izme'rus
+STR_023C_EXPAND :{BLACK}Paplas'ina't
+STR_023D_RANDOM_TOWN :{BLACK}Nejaus'a pilse'ta
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Celt pilse'tu nejaus'a' vieta'
+STR_023F_INDUSTRY_GENERATION :{WHITE}Industrijas g'enere's'ana
+STR_0240_COAL_MINE :{BLACK}Ogl'u raktuve
+STR_0241_POWER_STATION :{BLACK}Spe'kstacija
+STR_0242_SAWMILL :{BLACK}Kokza'g'e'tava
+STR_0243_FOREST :{BLACK}Mez's'
+STR_0244_OIL_REFINERY :{BLACK}Naftas pa'rstra'des ru'pni'ca
+STR_0245_OIL_RIG :{BLACK}Naftas atradnes
+STR_0246_FACTORY :{BLACK}Ru'pni'cu
+STR_0247_STEEL_MILL :{BLACK}Te'rauda lietuvi
+STR_0248_FARM :{BLACK}Fermu
+STR_0249_IRON_ORE_MINE :{BLACK}Dzelzs ru'das raktuves
+STR_024A_OIL_WELLS :{BLACK}Naftas su'kn'u staciju
+STR_024B_BANK :{BLACK}Banku
+STR_024C_PAPER_MILL :{BLACK}Papi'ra ru'pni'cu
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Pa'rtikas ru'pni'cu
+STR_024E_PRINTING_WORKS :{BLACK}Druka'tavu
+STR_024F_GOLD_MINE :{BLACK}Zelta atradnes
+STR_0250_LUMBER_MILL :{BLACK}Bal'k'u za'g'e'tavu
+STR_0251_FRUIT_PLANTATION :{BLACK}Augl'u planta'ciju
+STR_0252_RUBBER_PLANTATION :{BLACK}Kauc'uka planta'ciju
+STR_0253_WATER_SUPPLY :{BLACK}U'dens piega'di
+STR_0254_WATER_TOWER :{BLACK}U'dens torni
+STR_0255_DIAMOND_MINE :{BLACK}Dimanta raktuves
+STR_0256_COPPER_ORE_MINE :{BLACK}Vara ru'das raktuves
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Cukurvates mez'u
+STR_0258_CANDY_FACTORY :{BLACK}Saldumu ru'pni'cu
+STR_0259_BATTERY_FARM :{BLACK}Bateriju fermu
+STR_025A_COLA_WELLS :{BLACK}Kolas akas
+STR_025B_TOY_SHOP :{BLACK}Rotal'lietu veikalu
+STR_025C_TOY_FACTORY :{BLACK}Rotal'lietu ru'pni'cu
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Plastmasas stru'klakas
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Burbul'u'den'u ru'pni'cu
+STR_025F_BUBBLE_GENERATOR :{BLACK}Burbul'u g'eneratoru
+STR_0260_TOFFEE_QUARRY :{BLACK}Toffee lauztuves
+STR_0261_SUGAR_MINE :{BLACK}Cukura raktuves
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Bu've't ogl'u raktuves
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Bu've't spe'kstaciju
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Bu've't bal'k'u za'g'e'tavu
+STR_0265_PLANT_FOREST :{BLACK}Sta'di't mez'u
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Bu've't naftas pa'rstra'des ru'pni'cu
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Bu've't naftas platformu (atl'auts celt tikai kartes malu tuvuma')
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Bu've't rupni'cu
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Bu've't te'rauda lietuvi
+STR_026A_CONSTRUCT_FARM :{BLACK}Bu've't fermu
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Bu've't dzelzs ru'das raktuves
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Bu've't naftas atradnes
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Bu've't banku (atl'auts bu've't tikai pilse'ta's kur iedzi'vota'ju skaits liela'ks par 1200)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Bu've't papi'ra fabriku
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Bu've't pa'rtikas apstra'des ru'pni'cu
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Bu've't druka'tavu
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Bu've't zelta atradnes
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Bu've't banku (atl'auts celt tikai pilse'ta's)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Bu've't bal'k'u za'g'e'tavu (lai ti'ri'tu mez'us un raz'otu kokmaterea'lus)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Sta'di't augl'u planta'ciju
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Sta'di't kauc'uka planta'ciju
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Bu've't u'dens piega'des staciju
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Bu've't u'dens torni (atl'auts bu've't tikai pilse'ta's)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Bu've't dimanta raktuves
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Bu've't vara ru'das raktuves
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Sta'di't cukurvates mez'u
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Bu've't saldumu ru'pni'cu
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Bu've't bateriju fermu
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Bu've't kolas akas
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Bu've't rotal'lietu veikalu
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Bu've't rotal'lietu ru'pni'cu
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Bu've't plastmasas stru'klakas
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Bu've't burbul'u'den'u ru'pni'cu
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Bu've't burbul'u g'eneratoru
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Bu've't Toffee lauztuves
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Bu've't cukura raktuves
+STR_0285_CAN_T_BUILD_HERE :{WHITE}S'eit nevar bu've't {STRING}...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...vispirms ja'cel' pilse'ta
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...pilse'ta' atl'auts tikai viens(a)
+STR_0288_PLANT_TREES :{BLACK}Sta'di't kokus
+STR_0289_PLACE_SIGN :{BLACK}Novietot zi'mi
+STR_028A_RANDOM_TREES :{BLACK}Nejaus'i koki
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Nejaus'i sta'di't kokus pa visu plati'bu
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Novietot akmen'ainus apgabalus uz kartes
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Bu've't ba'ku
+STR_028E_PLACE_TRANSMITTER :{BLACK}Bu've't raidi'ta'ju
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Nora'di't tuksnes'a plati'bu.{}Spiest un turet CTRL lai to izdze'stu
+STR_CREATE_LAKE :{BLACK}Nora'di't u'dens plati'bu.{}Ta' tiks appludina'ta ja bu's ju'ras li'meni'
+STR_0290_DELETE :{BLACK}Izdzest
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Pilni'ba' izdze'st s'o pilse'tu
+STR_0292_SAVE_SCENARIO :Saglaba't scena'riju
+STR_0293_LOAD_SCENARIO :Iela'de't scena'riju
+STR_0294_QUIT_EDITOR :Beigt redaktoru
+STR_0295 :
+STR_0296_QUIT :Beigt
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Saglaba't scena'riju, iela'de't scena'riju, pamest scena'rija redaktoru, beigt
+STR_0298_LOAD_SCENARIO :{WHITE}Iela'de't scena'riju
+STR_0299_SAVE_SCENARIO :{WHITE}Saglaba't scena'riju
+STR_029A_PLAY_SCENARIO :{BLACK}Spe'le't scena'riju
+STR_029B_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Vai ju's ties'a'm ve'laties izbeigt s'o scena'riju?
+STR_029C_QUIT_EDITOR :{WHITE}Beigt redaktoru
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...atl'auts bu've't tikai pilse'ta's ar iedzi'vota'ju skaitu vismaz 1200
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Pa'rvietot starta datumu 1 gadu uz atpakal'u
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Pa'rvietot starta datumu 1 gadu uz prieks'u
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...abiem tilta galiem ja'bu't uz zemes
+STR_02A1_SMALL :{BLACK}Mazs
+STR_02A2_MEDIUM :{BLACK}Vide'js
+STR_02A3_LARGE :{BLACK}Liels
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Nora'di't pilse'tas izme'rus
+STR_02A5_TOWN_SIZE :{YELLOW}Pilse'tas izme'ri:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Para'di't pe'de'jo zin'ojumu
+STR_OFF :Nav
+STR_SUMMARY :Kopsavilkums
+STR_FULL :Pilns
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Pilse'tu saraksts
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Transporta li'dzekl'u dizaina nosaukumi
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Pe'c nokluse's'anas
+STR_02BF_CUSTOM :Specia'ls
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Saglaba't specia'los nosaukumus
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Transporta li'dzekl'u dizaina nosaukumu izve'le
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Saglaba't specia'los transporta li'dzekl'a dizaina nosaukumus
+
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Spe'les rez'i'mi
+STR_02C5_DIFFICULTY_SETTINGS :Gru'ti'bas paka'pes
+STR_02C7_CONFIG_PATCHES :Konfigure't labojumus (pac'us)
+STR_NEWGRF_SETTINGS :Newgrf rez'i'mi
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Ra'di't pilse'tu nosaukumus
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Ra'di't staciju nosaukumus
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Ra'di't zi'mes
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Ra'di't cel'a-zi'mes
+STR_02D0_FULL_ANIMATION :{SETX 12}Pilna anima'cija
+STR_02D2_FULL_DETAIL :{SETX 12}Pilnas detal'as
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Caurspi'di'gas e'kas
+STR_TRANSPARENT_SIGNS :{SETX 12}Caurspidi'gas staciju zi'mes
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Zemes apgabala informa'cija
+STR_02D6 :
+STR_CONSOLE_SETTING :Pa'rsle'gt konsoli
+STR_02D7_SCREENSHOT_CTRL_S :Ekra'na kopija (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Liela ekra'na kopija (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :Par 'OpenTTD'
+############ range ends here
+
+STR_02DB_OFF :{BLACK}Nav
+STR_02DA_ON :{BLACK}Ir
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Ra'di't subsi'dijas
+STR_02DD_SUBSIDIES :Subsi'dijas
+STR_02DE_MAP_OF_WORLD :Pasaules karte
+STR_EXTRA_VIEW_PORT :Papildus skats
+STR_SIGN_LIST :Zi'mju saraksts
+STR_02DF_TOWN_DIRECTORY :Pilse'tu saraksts
+STR_TOWN_POPULATION :{BLACK}Pasaules iedzi'vota'ju skaits: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Skats {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Kope't uz skatu
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Kope't globa'la' skata atras'ana's vietu uz s'o skatu
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Kope't no skata
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Kope't atras'ana's vietu no s'i' skata uz globa'lo skatu
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Naudas vieni'bas
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Naudas vieni'bu izve'le
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_02E6_ROAD_VEHICLES :{BLACK}Cel'a satiksmes li'dzekl'i
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Braucama's cel'a puses izve'le
+STR_02E9_DRIVE_ON_LEFT :Braukt pa kreiso pusi
+STR_02EA_DRIVE_ON_RIGHT :Braukt pa labo pusi
+STR_02EB_TOWN_NAMES :{BLACK}Pilse'tu nosaukumi
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Pilse'tu nosaukumu stila izve'le
+
+STR_02F4_AUTOSAVE :{BLACK}Auto-saglaba's'ana
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Spe'les auto-saglaba's'anas laika inerva'la izve'le
+STR_02F7_OFF :Nav
+STR_02F8_EVERY_3_MONTHS :Katrus 3 me'nes'us
+STR_02F9_EVERY_6_MONTHS :Katrus 6 me'nes'us
+STR_02FA_EVERY_12_MONTHS :Katrus 12 me'nes'us
+STR_02FB_START_A_NEW_GAME :{BLACK}Sa'kt jaunu spe'li
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Iela'de't saglaba'to spe'li
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Radi't specia'lu spe'les zemi un/vai scena'riju
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Izve'le'ties viena spe'le'ta'ja spe'li
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Izve'le'ties 2 li'dz 8 spe'le'ta'ju spe'li
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Ra'di't spe'les rez'i'mus
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Ra'di't gru'ti'bas paka'pes rez'i'mus
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Sa'kt jaunu spe'li ar specia'lu scena'riju
+STR_0304_QUIT :{BLACK}Beigt
+STR_0305_QUIT_OPENTTD :{BLACK}Beigt 'OpenTTD'
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...var celt tikai pilse'ta's
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Izve'le'ties ' me'renu ' zemes stilu
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Izve'le'ties ' sub-arktisku ' zemes stilu
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Izve'le'ties ' sub-tropisku ' zemes stilu
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Izve'le'ties ' rotal'u ' zemes stilu
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Finanse't jaunas industrijas bu'vnieci'bu
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Industriju saraksts
+STR_0313_FUND_NEW_INDUSTRY :Finanse't jaunu industriju
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Finanse't jaunu industriju
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...var celt tikai pilse'ta's
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...var celt tikai mez'u apgabalos
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...var celt tikai tuksnes'ainos apgabalos
+STR_0319_PAUSED :{YELLOW}* * PAUZE * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Ekra'na kopija saglaba'ta ieks' '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}Ekra'na kopija neizdeva's!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Pe'rc zemi na'kotnes lietos'anai
+STR_032F_AUTOSAVE :{RED}AUTOSAGLABA'S'ANA
+STR_SAVING_GAME :{RED}* * Spe'le tiek saglaba'ta * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}Notiek saglabas'ana,{}lu'dzu uzgaidiet!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}izve'lies 'Ez'u Ielas muzikas stila' programmu
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :Anglijas (orig'ina'lie)
+STR_TOWNNAME_FRENCH :Francijas
+STR_TOWNNAME_GERMAN :Va'cijas
+STR_TOWNNAME_ADDITIONAL_ENGLISH :Anglijas (papildus)
+STR_TOWNNAME_LATIN_AMERICAN :Lati'n'-Amerikas
+STR_TOWNNAME_SILLY :Joci'gi
+STR_TOWNNAME_SWEDISH :Zviedrijas
+STR_TOWNNAME_DUTCH :Da'nijas
+STR_TOWNNAME_FINNISH :Somijas
+STR_TOWNNAME_POLISH :Polijas
+STR_TOWNNAME_SLOVAKISH :Slova'kijas
+STR_TOWNNAME_NORWEGIAN :Norve'g'ijas
+STR_TOWNNAME_HUNGARIAN :Unga'rijas
+STR_TOWNNAME_AUSTRIAN :Austrijas
+STR_TOWNNAME_ROMANIAN :Ruma'nijas
+STR_TOWNNAME_CZECH :C'ehijas
+STR_TOWNNAME_SWISS :S'veices
+STR_TOWNNAME_DANISH :Da'n'u
+############ end of townname region
+
+STR_CURR_GBP :Ma'rcin'as (£)
+STR_CURR_USD :Dola'ri ($)
+STR_CURR_EUR :Eiro (€)
+STR_CURR_YEN :Jenas (Â¥)
+STR_CURR_ATS :Austrijas s'ilin'i (ATS)
+STR_CURR_BEF :Bel'g'ijas franki (BEF)
+STR_CURR_CHF :S'veices franki (CHF)
+STR_CURR_CZK :C'ehijas kronas (CZK)
+STR_CURR_DEM :Va'cijas markas (DEM)
+STR_CURR_DKK :Da'nijas kronas (DKK)
+STR_CURR_ESP :Pesetas (ESP)
+STR_CURR_FIM :Somijas marka (FIM)
+STR_CURR_FRF :Franki (FRF)
+STR_CURR_GRD :Griek'ijas drahmas (GRD)
+STR_CURR_HUF :Hungarijas forinti (HUF)
+STR_CURR_ISK :Islandes kronas (ISK)
+STR_CURR_ITL :Ita'lijas liras (ITL)
+STR_CURR_NLG :Da'nijas g'ilden'i (NLG)
+STR_CURR_NOK :Norve'g'ijas kronas (NOK)
+STR_CURR_PLN :Polijas zloti (PLN)
+STR_CURR_ROL :Ruma'nijas lejas (ROL)
+STR_CURR_RUR :Krievijas rubl'i (RUR)
+STR_CURR_SEK :Zviedru kronas (SEK)
+
+STR_CURR_CUSTOM :Specia'la...
+
+STR_OPTIONS_LANG :{BLACK}Valoda
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Interfeisa valodas izve'le
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Pilna ekra'na
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}iezi'me' k'eksi lai spe'le'tu OpenTTD pilna ekra'na rez'i'ma'
+
+STR_OPTIONS_RES :{BLACK}Ekra'na izs'k'irtspe'ja
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Ekra'na izs'k'irtspe'jas izve'le
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Ekra'na kopijas forma'ts
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Ekra'na kopijas forma'ta izve'le
+
+STR_AUTOSAVE_1_MONTH :Katru me'nesi
+STR_AUTOSAVE_FAILED :{WHITE}auto-saglaba's'ana neizdeva's
+
+STR_MONTH_JAN :Janva'ris
+STR_MONTH_FEB :Februa'ris
+STR_MONTH_MAR :Marts
+STR_MONTH_APR :Apri'lis
+STR_MONTH_MAY :Maijs
+STR_MONTH_JUN :Ju'nijs
+STR_MONTH_JUL :Ju'lijs
+STR_MONTH_AUG :Augusts
+STR_MONTH_SEP :Septembris
+STR_MONTH_OCT :Oktobris
+STR_MONTH_NOV :Novembris
+STR_MONTH_DEC :Decembris
+
+STR_HEADING_FOR_STATION :{LTBLUE}Dodas uz {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}Dodas uz {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Nav uzdevumu
+STR_NO_ORDERS_VEL :{LTBLUE}Nav uzdevumu, {VELOCITY}
+
+STR_PASSENGERS :pasaz'ieri
+STR_BAGS :somas
+STR_TONS :tonnas
+STR_LITERS :litri
+STR_ITEMS :lietas
+STR_CRATES :kastes
+STR_RES_OTHER :cits
+STR_NOTHING :
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Nevar dali'ties ar uzdevumu sarakstu...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Nevar kope't uzdevumu sarakstu...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - Dali'to uzdevumu beigas - -
+
+STR_TRAIN_IS_LOST :{WHITE}Vilciens {COMMA} ir pazaude'ts.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}Vilciena {COMMA} iena'kumi paga'jus'aja' gada' bija {CURRENCY}
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}Eiropas naudas apvieni'ba!{}{}Eiro ir ieviests ka' vieni'ga' naudas vieni'ba ju'su valsti'!
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Vilcienam {COMMA} nav pietiekos'i daudz uzdevumu
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}Vilcienam {COMMA} ir tuks's uzdevums
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}Vilcienam {COMMA} ir dubults uzdevums
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}Vilcienam {COMMA} ir nepareiza stacija ta' uzdevumos
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}Auto {COMMA} ir pa'ra'k maz uzdevumu
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}Auto {COMMA} ir tuks's uzdevums
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}Auto {COMMA} ir dubults uzdevums
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}Auto {COMMA} ir nepareiza stacija ta' uzdevumos
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}Kug'im {COMMA} ir pa'ra'k maz uzdevumu ta' saraksta'
+STR_SHIP_HAS_VOID_ORDER :{WHITE}Kug'im {COMMA} ir tuks's uzdevums
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}Kug'im {COMMA} ir dubults uzdevums
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}Kug'im {COMMA} ir nepareizs uzdevums
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}Lidmas'i'nai {COMMA} ir pa'ra'k maz uzdevumu
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}Lidmas'i'nai {COMMA} ir tuks's uzdevums
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}Lidmas'i'nai {COMMA} ir dubults uzdevums
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}Lidmas'i'nai {COMMA} ir nepareiza stacija ta's uzdevumu saraksta'
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}Vilciena autoatjaunos'ana neizdeva's {COMMA} (naudas limits)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}Automobil'a autoatjaunos'ana neizdeva's {COMMA} (naudas limits)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}Kug'a autoatjaunos'ana neizdeva's {COMMA} (naudas limits)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}Lidmas'i'nas autoatjaunos'ana neizdeva's {COMMA} (naudas limits)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}Vilciens {COMMA} ir pa'ra'k gars' pe'c aizvietos'anas
+
+STR_CONFIG_PATCHES :{BLACK}Konfigure' uzlabojumus
+STR_CONFIG_PATCHES_TIP :{BLACK}Konfigure't labojumus
+STR_CONFIG_PATCHES_CAPTION :{WHITE}Konfigure't labojumus
+
+STR_CONFIG_PATCHES_OFF :Ne'
+STR_CONFIG_PATCHES_ON :Ja'
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Ra'di't auto a'trumu statusa josla': {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Atl'aut celt uz neli'dzenas zemes un krastiem: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Atl'aut rea'listiskus katc'ementa apgabalus: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Atl'aut pilse'tai piederos'u cel'u un tiltu nojauks'anu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Atl'aut l'oti garu vilcienu cels'anu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Atl'aut rea'lu vilcienu pa'atrina'jumu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Aizliedz vilcieniem un kug'iem taisi't 90 gra'du pagriezienus: {ORANGE}{STRING} {LTBLUE} (nepiecies'ams NPF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Savienot vilciena stacijas kas celtas blakus: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Izbraukt no stacijas ja jebkura krava ir uzpildi'ta un "pilna krava" ir iesle'gta: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Lietot uzlabotu uzla'de's'anas algoritmu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Infla'cija: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Transporte't kravu uz staciju tikai tad ja ir pieprasijums: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Atl'aut l'oti garu tiltu cels'anu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Atl'aut "iet uz depo" komandu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Atl'aut materea'lu raz'os'anas industrijas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Atl'aut vaira'kas li'dzi'gas industrijas vienai pilse'tai: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Viena veida industrijas var tikt celtas tuvu viena no otras: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Vienme'r ra'di't garu datumu statusa josla': {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Ra'di't signa'lus brauks'anas puse': {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Ra'di't finanses gada beiga's: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}TTDPatch savietojams nekave'jos'ais apstra'da'jums: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Automobi'l'u rindas (ar kvantu efektiem): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Bi'di't logu kad pele ir ta' mala': {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Atl'aut viete'jo varas iesta'z'u piekukul'os'anu: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Ne-uniformas stacijas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Jauna' globa'la' cel'u kars'rutiza'cija (NPF, aizsta'j NTP): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Vienme'r atl'aut mazas lidostas: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Pa'rskati't transporta uzdevumus: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :Ne'
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :Ja', izn'emot transporta li'dzekl'us kas apsta'dina'ti
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :visus vecos transporta li'dzekl'us
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Bri'dina't ja vilciena iena'kums kl'u'st negati'vs: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Transporta li'dzekl'i nekad nemirst: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Automa'tiski atjaunot transporta li'dzekli kad tas kl'u'st vecs
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Automa'tiski atjaunot transporta li'dzekli {ORANGE}{STRING}{LTBLUE} me'nes'us pirms/pe'c maksima'la' vecuma
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Automa'tiski atjaunot minima'lo naudu kas nepiecies'ama atjaunos'anai: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Kl'u'das zin'ojuma ilgums: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Râdît pilsçtas iedzîvotâju skaitu pie pilsçtas nosaukuma: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Neredzami koki (ar caurspi'di'ga'm celtne'm): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Sniega li'nijas augstums: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Maksima'lais staciju izkaisijums: {ORANGE}{STRING} {RED}Uzmani'bu: augsts li'menis pale'lina spe'li
+
+
+
+
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Aizliedz servisu kad saboja's'ana's izsle'gta: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}Nobeidz spe'li: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Atïauj akciju pirkðanu no citâm kompânijâm
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Pa kreisi
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Centrâ
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Pa labi
+
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Stacijas
+
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+
+
+STR_CHEAT_SETUP_PROD :{LTBLUE}L'auj izmaini't produktu ve'rti'bas: {ORANGE}{STRING}
+
+
+STR_GO_TO_WAYPOINT :Caur {WAYPOINT}
+
+
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+
+
+
+
+
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Izlidzinât zemi
+
+
+
+STR_LANDINFO_CANAL :Kanals
+
+
+STR_BUOY_IS_IN_USE :{WHITE}...boja jau tiek lietota!
+
+
+
+
+
+
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Industrîjas
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Maini't produkciju
+
+
+############ network gui strings
+
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Spelçtâja vârds:
+
+
+STR_NETWORK_GAME_NAME :{BLACK}Vârds
+
+
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_LANGUAGE :{SILVER}Valoda: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}Servera adrese: {WHITE}{STRING} : {NUM}
+
+
+
+
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :LAN
+STR_NETWORK_INTERNET :Internets
+STR_NETWORK_LAN_INTERNET :LAN / Internets
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_2_PLAYERS :2 clienti
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}Sakt spçli
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ENGLISH :Angïu
+############ End of leave-in-this-order
+
+
+
+
+
+
+STR_NETWORK_CONNECTING :{WHITE}Savienojas...
+
+############ Leave those lines in this order!!
+
+############ End of leave-in-this-order
+
+
+
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} Nepareiza Parole
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} Jûs esat izraidîts no ðî servera
+
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :ðo vârdu jau lieto
+############ End of leave-in-this-order
+
+STR_NETWORK_SERVER :Serveris
+
+
+
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}kartes X-izme'ri: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}kartes Y-izme'ri: {ORANGE}{STRING}
+
+##id 0x0800
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Pa'rved: {CURRENCY}
+STR_FEEDER :{YELLOW}Pa'rved: {CURRENCY}
+STR_080A_ROCKS :Akmeòi
+
+##id 0x1000
+STR_1021_RAILROAD_TRACK :Dzelzceïa ceïs
+
+
+
+##id 0x1800
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Autoceïa Construction
+STR_1814_ROAD :Autoceïð
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Pilse'tas
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Vispirms ja'demole' celtne
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}Iedzi'vota'ji: {ORANGE}{COMMA}{BLACK} Ma'jas: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Pa'rsaukt pilse'tu
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Nevar pa'rsaukt pilse'tu...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} viete'ja's varas iesta'des noraida s'a'du ri'ci'bu
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Pilse'tu nosaukumi - izve'lies pilse'tu lai iecentre'tu uz to skatu
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Iecentre't galveno skatu uz pilse'tas atras'ana's vietu
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Pa'rsaukt pilse'tu
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Pasaz'ieri paga'jus'aja' me'nesi': {ORANGE}{COMMA}{BLACK} maksima'lais skaits: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Pasts paga'jus'aja' me'nesi': {ORANGE}{COMMA}{BLACK} Maksima'lais apjoms: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Augstceltne: ofisu ma'ja
+STR_2010_OFFICE_BLOCK :Ofisu kvarta'ls
+STR_2011_SMALL_BLOCK_OF_FLATS :Mazs dzi'vokl'u kvarta'ls
+STR_2012_CHURCH :Bazni'ca
+STR_2013_LARGE_OFFICE_BLOCK :Liels ofisu kvarta'ls
+STR_2014_TOWN_HOUSES :Dzi'vojama's ma'jas
+STR_2015_HOTEL :Viesni'ca
+STR_2016_STATUE :Statuja
+STR_2017_FOUNTAIN :Stru'klaka
+STR_2018_PARK :Parks
+STR_201E_STADIUM :Stadions
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Subsidijas
+STR_202A_NONE :{ORANGE}Neviens
+STR_2036_COTTAGES :Kotedži
+STR_203D_STADIUM :Stadions
+STR_203F_HOUSES :Mâjas
+STR_2040_CINEMA :Coca-Cola Plaza
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_205C_PIGGY_BANK :Cûku-Banka
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN} {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_2806 :{WHITE}{STRING}
+STR_280A_SIGN :Zîme
+STR_280E_TREES :Koki
+
+##id 0x3000
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Pa'ra'k daudz autobusa pieturu
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}pa'ra'k daudz kravas auto staciju
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+
+STR_3032_RATINGS :{BLACK}Reitingi
+
+############ range for rating starts
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION} {STATIONFEATURES}
+STR_3060_AIRPORT :Lidosta
+STR_3062_BUS_STATION :Autoosta
+STR_3063_SHIP_DOCK :Osta
+STR_3068_DOCK :{WHITE}Osta
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...neregula'ras stacijas nav atl'autas
+
+##id 0x3800
+STR_3804_WATER :Ûdens
+
+##id 0x4000
+STR_4004 :{COMPANY}, {DATE_LONG}
+
+##id 0x4800
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4804_SAWMILL :Gateris
+STR_4805_FOREST :Mežs
+STR_480B_FARM :Ferma
+STR_4812_BANK :Banka
+STR_4819_FACTORY :Rûpnîca
+
+############ range for requires starts
+############ range for requires ends
+
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Vilciens tunelî
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Vanšu, Terauda
+
+##id 0x5800
+STR_5803_COMPANY_HEADQUARTERS :Firmas Ofiss
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_TRAIN_NAME :Vilciens {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_FOREST :{STRING} Mežs
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Saglabât
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Viegls
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+############ range for difficulty settings ends
+
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_6824_REDUCED :Samazinâts
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_6830_IMMEDIATE :Uzreiz
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7004_NEW_FACE :{BLACK}Jauna Seja
+STR_7005_COLOR_SCHEME :{BLACK}Krasas shçma
+STR_7006_COLOR_SCHEME :{GOLD}Krasas shçma:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Jaunâ Krasas shçma
+STR_7010 :{WHITE}{NUM}
+STR_701D_OTHER :{GOLD}Citi
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7027_LOAN :{WHITE}Aizdevums
+STR_MAX_LOAN :{WHITE}Maksmalais Aizdevums: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_INSUFFICIENT_FUNDS :{WHITE}Naudu, kas ir bankas aizn'e'mums, nevar dot prom...
+STR_7042_NONE :{WHITE}Neviens
+STR_7044_MALE :{BLACK}Viriešu
+STR_7045_FEMALE :{BLACK}Sieviešu
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Bankrots!
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_COMPANY_PASSWORD :{BLACK}Parole
+STR_7080_PROTECTED :{WHITE}S'i' kompa'nija ir pa'ra'k jauna lai tirgotu akcijas...
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (Tvaika)
+STR_8001_MJS_250_DIESEL :MJS 250 (Dizelis)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut Dizelis
+STR_8006_POWERNAUT_DIESEL :Powernaut Dizelis
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (Tvaika)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (Tvaika)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (Tvaika)
+STR_800A_SH_8P_STEAM :SH '8P' (Tvaika)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (Dizelis)
+STR_800C_DASH_DIESEL :'Dash' (Dizelis)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (Dizelis)
+STR_800E_UU_37_DIESEL :UU '37' (Dizelis)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (Dizelis)
+STR_8010_CS_4000_DIESEL :CS 4000 (Dizelis)
+STR_8011_CS_2400_DIESEL :CS 2400 (Dizelis)
+STR_8012_CENTENNIAL_DIESEL :Centennial (Dizelis)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (Dizelis)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (Dizelis)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (Dizelis)
+STR_8016_SH_125_DIESEL :SH '125' (Dizelis)
+STR_8017_SH_30_ELECTRIC :SH '30' (Electric)
+STR_8018_SH_40_ELECTRIC :SH '40' (Electric)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (Electric)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (Electric)
+STR_8036_X2001_ELECTRIC :'X2001' (Electric)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Electric)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_803A_MAIL_VAN :Pasta Vagons
+STR_8048_FRUIT_TRUCK :Fruktu Vagons
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (Electric)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (Electric)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (Electric)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (Electric)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_805A_MAIL_VAN :Pasta Vagons
+STR_8074_MPS_REGAL_BUS :MPS Regal Autobuss
+STR_8075_HEREFORD_LEOPARD_BUS :Hereford Leopard Autobuss
+STR_8076_FOSTER_BUS :Foster Autobuss
+STR_8077_FOSTER_MKII_SUPERBUS :Foster MkII Superbus
+STR_8078_PLODDYPHUT_MKI_BUS :Ploddyphut MkI Autobuss
+STR_8079_PLODDYPHUT_MKII_BUS :Ploddyphut MkII Autobuss
+STR_807A_PLODDYPHUT_MKIII_BUS :Ploddyphut MkIII Autobuss
+STR_8090_WITCOMBE_WOOD_TRUCK :Witcombe Koku Vedçjs
+STR_809A_UHL_ARMORED_TRUCK :Uhl Brûòotais Auto
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Wizzowow Cukura Auto
+STR_80CE_MPS_PASSENGER_FERRY :MPS Pasažieru Pramis
+STR_80CF_FFP_PASSENGER_FERRY :FFP Pasažieru Pramis
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Bakewell 300 Hovercraft
+STR_80D1_CHUGGER_CHUG_PASSENGER :Chugger-Chug Pasažieru Pramis
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Shivershake Pasažieru Pramis
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttlle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzzer
+STR_80FD_TRICARIO_HELICOPTER :Tricario Helicopter
+STR_80FE_GURU_X2_HELICOPTER :Guru X2 Helicopter
+STR_80FF_POWERNAUT_HELICOPTER :Powernaut Helicopter
+STR_8104_AIRCRAFT :lidmaðîna
+
+##id 0x8800
+STR_8804 :{SETX 10}{COMMA}: {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING}
+STR_8807_GO_TO_TRANSFER :Uz {STATION} (Pa'rvest un pan'emt kravu)
+STR_8808_GO_TO_UNLOAD :Uz {STATION} (Nokraut)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Uz {STATION} (Pa'rvest un atsta't tuks'u)
+STR_880A_GO_TO_LOAD :Uz {STATION} (Piekraut)
+STR_880B_GO_TO_TRANSFER_LOAD :Go to {STATION} (Pa'rvest un gaidi't pilnu kravu)
+STR_880C_GO_NON_STOP_TO :Bez pieturam uz {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Bez pieturam uz {STATION} (Pa'rvest un pan'emt kravu)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Bez pieturam uz {STATION} (Nokraut)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Bez pieturam uz {STATION} (Pa'rvest un atsta't tuks'u)
+STR_8810_GO_NON_STOP_TO_LOAD :Bez pieturam uz {STATION} (Piekraut)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Bez pieturam uz {STATION} (Pa'rvest un gaidi't pilnu kravu)
+STR_GO_TO_TRAIN_DEPOT :Uz {TOWN} Vilcienu Depo
+
+
+
+STR_8812_EMPTY :{LTBLUE}Tukšs
+STR_8816 :{BLACK}-
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}Serviss
+STR_882E :{WHITE}{VEHICLE}
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}Vilciens ja'apsta'dina kad tas ierodas depo
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_8861_STOPPED :{RED}Stoppets
+
+STR_8865_NAME_TRAIN :{WHITE}Nosaukt vilcienu
+STR_8867_NAME_TRAIN :{BLACK}Nosaukt vilcienu
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Uzsve'rtai pa'velei spiest tansportli'dzekl'im nomest kravu
+STR_886F_TRANSFER :{BLACK}Tranzi'ts
+
+
+##id 0x9000
+STR_9002 :{WHITE}{VEHICLE}
+STR_9012_CAPACITY :{BLACK}Capacitâte: {LTBLUE}{CARGO}
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Cena: {CURRENCY}{}Atrums: {VELOCITY}{}Running Cost: {CURRENCY}/yr{}Capacity: {CARGO}
+
+STR_9034_RENAME :{BLACK}Pârsaukt
+
+##id 0x9800
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} Kuìi
+STR_980F :{WHITE}{VEHICLE}
+STR_9820_BUILD_NEW_SHIP :{BLACK}Uzbûvet jauno kuìi
+STR_982D :{BLACK}{BIGFONT}{STRING}
+
+STR_9836_RENAME :{BLACK}Pârsaukt
+
+##id 0xA000
+STR_A00A :{WHITE}{VEHICLE}
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Lidmaðînas avârija!{}Lidmaðînai pietrûka degviela, {COMMA} nogalinâti!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Pârsaukt
+STR_GO_TO_AIRPORT_HANGAR :Uz {STATION} Angâru
+SERVICE_AT_AIRPORT_HANGAR :Serviss {STATION} Angarâ
+
+##id 0xB000
+
+
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}Detaïas
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Stacijas:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Nauda:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Aizdevums:
+############ End of order list
+
+STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
+
+STR_CURRENCY_SUFFIX :{LTBLUE}Suffikss:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Pariet uz Eiro: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Pariet uz Eiro: {ORANGE}nekad
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} Kuìi
+
+
+STR_REPLACE_VEHICLES :{BLACK}Nomaini transporta lîdzekïus
+STR_REPLACE_VEHICLES_WHITE :{WHITE}Nomaini transporta lîdzekïus
+STR_REPLACE_VEHICLES_START :{BLACK}Sâc nomainît transporta lîdzekïus
+STR_REPLACE_VEHICLES_STOP :{BLACK}Pârtrauc nomainît transporta lîdzekïus
+STR_NOT_REPLACING :{BLACK}Netiks nomainîts
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Neviens transporta lîdzeklis nebija izvçlçts
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Izvçlies lokomatîves tipu kuru tu gribi nomainît
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Izvçlies jaunâs lokomatîves tipu kuru tu gribi lietot kreisâ pusç atzîmçtâs lokomatîves vietâ
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Nospied lai apturçtu kreisâ pusç atzîmçtâs lokomatîves aizvietoðanu
+STR_REPLACE_HELP_START_BUTTON :{BLACK}Nospied lai sâktu kreisâ pusç atzîmçtâs lokomatîves aizvietoðanu
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Izvçlies slieþu tipu kurâm tu gribi nomainît lokomatîves
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Parâda kura lokomatîve no pa kreisi atzîmçtajâm tiek nomainîta, ja vien kâda ir
+STR_REPLACE_HELP :{BLACK}ðis atïauj nomainît vienu lokomatîves tipu pret citu kad vilcieni ienâk depo
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}Zi'mju saraksts- {COMMA} Zi'mes
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :Slieþu transporta lîdzekïi
+STR_MONORAIL_VEHICLES :Monoslieþu transporta lîdzekïi
+STR_MAGLEV_VEHICLES :Maglev transporta lîdzekïi
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Cena: {GOLD}{CURRENCY}{BLACK} Svars: {GOLD}{WEIGHT_S}t
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}A'trums: {GOLD}{VELOCITY}{BLACK} Jauda: {GOLD}{POWER}zs
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Ekspua'tacijas izmaksas: {GOLD}{CURRENCY}/gada'
+STR_PURCHASE_INFO_CAPACITY :{BLACK}Ietilpi'ba: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Raz'ots: {GOLD}{NUM}{BLACK} Termin's': {GOLD}{COMMA} gadi
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}Maks.Dros'i'ba: {GOLD}{COMMA}%
+STR_PURCHASE_INFO_COST :{BLACK}Cena: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Svars: {GOLD}{WEIGHT_S}t ({WEIGHT_S}t)
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Cena: {GOLD}{CURRENCY}{BLACK} A'trums: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Ietilpi'ba: {GOLD}{COMMA} pasaz'ieru, {COMMA} pasta somas
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Motor-vagoni: {GOLD}+{POWER}zs{BLACK} Sva'rs: {GOLD}+{WEIGHT_S}t
diff --git a/src/lang/unfinished/lithuanian.txt b/src/lang/unfinished/lithuanian.txt
new file mode 100644
index 000000000..583f3d38d
--- /dev/null
+++ b/src/lang/unfinished/lithuanian.txt
@@ -0,0 +1,3118 @@
+##name Lithuanian
+##ownname Lietuvių
+##isocode lt_LT.UTF-8
+##plural 5
+##case kas ko kam ka kuo kur kreip
+##gender vyr mot
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Už žemelapio kraštų
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Per arti žemėlapio krašto
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Neužtenka lėšų: reikia {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Paviršius turi būti lygus
+STR_0008_WAITING :{BLACK}Laukia: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (maršrutas iš
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Priima: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Priima: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :
+STR_0010_COAL :Anglis
+STR_0011_MAIL :Pašto
+STR_0012_OIL :Naftos
+STR_0013_LIVESTOCK :Galvijų
+STR_0014_GOODS :Prekių
+STR_0015_GRAIN :Grūdų
+STR_0016_WOOD :Medienos
+STR_0017_IRON_ORE :Geležies rūdos
+STR_0018_STEEL :Plieno
+STR_0019_VALUABLES :Brangenybių
+STR_001A_COPPER_ORE :Vario rūdos
+STR_001B_MAIZE :Kukurūzų
+STR_001C_FRUIT :Vaisių
+STR_001D_DIAMONDS :Deimantų
+STR_001E_FOOD :Maisto
+STR_001F_PAPER :Popieriaus
+STR_0020_GOLD :Aukso
+STR_0021_WATER :Vandens
+STR_0022_WHEAT :KvieÄių
+STR_0023_RUBBER :Gumos
+STR_0024_SUGAR :Cukraus
+STR_0025_TOYS :Žaislų
+STR_0026_CANDY :Saldumynų
+STR_0027_COLA :Kolos
+STR_0028_COTTON_CANDY :Cukraus vatos
+STR_0029_BUBBLES :Burbulų
+STR_002A_TOFFEE :KaramelÄ—s
+STR_002B_BATTERIES :Baterijų
+STR_002C_PLASTIC :PlastmasÄ—s
+STR_002D_FIZZY_DRINKS :Gaiviųjų gėrimų
+STR_002E :
+STR_002F_PASSENGER :Keleivių
+STR_0030_COAL :Anglies
+STR_0031_MAIL :Pašto
+STR_0032_OIL :Naftos
+STR_0033_LIVESTOCK :Galvijų
+STR_0034_GOODS :Prekių
+STR_0035_GRAIN :Grūdų
+STR_0036_WOOD :Medienos
+STR_0037_IRON_ORE :Geležies rūdos
+STR_0038_STEEL :Plieno
+STR_0039_VALUABLES :Brangenybių
+STR_003A_COPPER_ORE :Vario rūdos
+STR_003B_MAIZE :Kukurūzų
+STR_003C_FRUIT :Vaisių
+STR_003D_DIAMOND :Deimantų
+STR_003E_FOOD :Maisto
+STR_003F_PAPER :Popieriaus
+STR_0040_GOLD :Aukso
+STR_0041_WATER :Vandens
+STR_0042_WHEAT :KvieÄių
+STR_0043_RUBBER :KauÄiuko
+STR_0044_SUGAR :Cukraus
+STR_0045_TOY :Žaislų
+STR_0046_CANDY :Saldumynų
+STR_0047_COLA :Kolos
+STR_0048_COTTON_CANDY :Cukraus vatos
+STR_0049_BUBBLE :Burbulų
+STR_004A_TOFFEE :KaramelÄ—s
+STR_004B_BATTERY :Baterijų
+STR_004C_PLASTIC :PlastmasÄ—s
+STR_004D_FIZZY_DRINK :Gaiviųjų gėrimų
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} keleiviai
+STR_QUANTITY_COAL :{WEIGHT} tonu anglies
+STR_QUANTITY_MAIL :{COMMA} pasto maisu
+STR_QUANTITY_OIL :{VOLUME} naftos
+STR_QUANTITY_LIVESTOCK :{COMMA} galvijas
+STR_QUANTITY_GOODS :{COMMA} prekiu deze
+STR_QUANTITY_GRAIN :{WEIGHT} tonu grudu
+STR_QUANTITY_WOOD :{WEIGHT} tonu medienos
+STR_QUANTITY_IRON_ORE :{WEIGHT} tonu gelezies rudos
+STR_QUANTITY_STEEL :{WEIGHT} tonu plieno
+STR_QUANTITY_VALUABLES :{COMMA} maiš{P as ai ų} brangenybių
+STR_QUANTITY_COPPER_ORE :{WEIGHT} tonu vario rudos
+STR_QUANTITY_MAIZE :{WEIGHT} tonu kukuruzu
+STR_QUANTITY_FRUIT :{WEIGHT} tonu vaisiu
+STR_QUANTITY_DIAMONDS :{COMMA} deziu deimantu
+STR_QUANTITY_FOOD :{WEIGHT} tonu maisto
+STR_QUANTITY_PAPER :{WEIGHT} tonu popieriaus
+STR_QUANTITY_GOLD :{COMMA} aukso kapsu
+STR_QUANTITY_WATER :{VOLUME} vandens
+STR_QUANTITY_WHEAT :{WEIGHT} tonu kvieciu
+STR_QUANTITY_RUBBER :{VOLUME} kauciuko
+STR_QUANTITY_SUGAR :{WEIGHT} tonu cukraus
+STR_QUANTITY_TOYS :{COMMA} zaislu
+STR_QUANTITY_SWEETS :{COMMA} saldumynu krepseliu
+STR_QUANTITY_COLA :{VOLUME} Coca-Colos
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} tonu cukraus vatos
+STR_QUANTITY_BUBBLES :{COMMA} burbulu
+STR_QUANTITY_TOFFEE :{WEIGHT} tonu karameles
+STR_QUANTITY_BATTERIES :{COMMA} bateriju
+STR_QUANTITY_PLASTIC :{VOLUME} plastmases
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} gaiviuju gerimu
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}PS
+STR_ABBREV_COAL :{TINYFONT}CL
+STR_ABBREV_MAIL :{TINYFONT}ML
+STR_ABBREV_OIL :{TINYFONT}OL
+STR_ABBREV_LIVESTOCK :{TINYFONT}LV
+STR_ABBREV_GOODS :{TINYFONT}GD
+STR_ABBREV_GRAIN :{TINYFONT}GR
+STR_ABBREV_WOOD :{TINYFONT}WD
+STR_ABBREV_IRON_ORE :{TINYFONT}OR
+STR_ABBREV_STEEL :{TINYFONT}ST
+STR_ABBREV_VALUABLES :{TINYFONT}VL
+STR_ABBREV_COPPER_ORE :{TINYFONT}CO
+STR_ABBREV_MAIZE :{TINYFONT}MZ
+STR_ABBREV_FRUIT :{TINYFONT}FT
+STR_ABBREV_DIAMONDS :{TINYFONT}DM
+STR_ABBREV_FOOD :{TINYFONT}FD
+STR_ABBREV_PAPER :{TINYFONT}PR
+STR_ABBREV_GOLD :{TINYFONT}GD
+STR_ABBREV_WATER :{TINYFONT}WR
+STR_ABBREV_WHEAT :{TINYFONT}WH
+STR_ABBREV_RUBBER :{TINYFONT}RB
+STR_ABBREV_SUGAR :{TINYFONT}SG
+STR_ABBREV_TOYS :{TINYFONT}TY
+STR_ABBREV_SWEETS :{TINYFONT}SW
+STR_ABBREV_COLA :{TINYFONT}CL
+STR_ABBREV_CANDYFLOSS :{TINYFONT}CF
+STR_ABBREV_BUBBLES :{TINYFONT}BU
+STR_ABBREV_TOFFEE :{TINYFONT}TF
+STR_ABBREV_BATTERIES :{TINYFONT}BA
+STR_ABBREV_PLASTIC :{TINYFONT}PL
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}FZ
+STR_ABBREV_NONE :{TINYFONT}NE
+STR_ABBREV_ALL :{TINYFONT}VISI
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Žemėlapis - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Žaidimo nustatymai
+STR_00B2_MESSAGE :{YELLOW}Žinutė
+STR_00B3_MESSAGE_FROM :{YELLOW}Žinutė nuo {STRING}
+STR_POPUP_CAUTION_CAPTION :{WHITE}Įspėjimas!
+STR_00B4_CAN_T_DO_THIS :{WHITE}To daryti negalima....
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Negalima griauti Å¡ios teritorijos....
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}PradinÄ—s versijos teisÄ—s priklauso {COPYRIGHT} 1995 Chris Sawyer, Visos teisÄ—s saugomos
+STR_00B7_VERSION :{BLACK}OpenTTD versija {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 OpenTTD komanda
+STR_TRANSLATED_BY :{BLACK} Vertejai: Mindaugas Surdokas (L781), Vytautas Liuolia
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Baigti
+STR_00C8_YES :{BLACK}Taip
+STR_00C9_NO :{BLACK}Ne
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Ar jūs tikrai norite nutraukti žaidimą ir grižti į {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :TuÅ¡Äia
+STR_00D1_DARK_BLUE :Tamsiai mÄ—lyna
+STR_00D2_PALE_GREEN :Pilkšvai žalia
+STR_00D3_PINK :Rausva
+STR_00D4_YELLOW :Geltona
+STR_00D5_RED :Raudona
+STR_00D6_LIGHT_BLUE :Žydra
+STR_00D7_GREEN :Žalia
+STR_00D8_DARK_GREEN :Tamsiai žalia
+STR_00D9_BLUE :MÄ—lyna
+STR_00DA_CREAM :KreminÄ—
+STR_00DB_MAUVE :Pilkšvai mėlyna
+STR_00DC_PURPLE :VioletinÄ—
+STR_00DD_ORANGE :Oranžinė
+STR_00DE_BROWN :Ruda
+STR_00DF_GREY :Pilka
+STR_00E0_WHITE :Balta
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Per daug transporto priemonių žaidime
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Vieta
+STR_00E5_CONTOURS :Kontūrai
+STR_00E6_VEHICLES :Transporto priemonÄ—s
+STR_00E7_INDUSTRIES :Pramonės įmonės
+STR_00E8_ROUTES :Keliai
+STR_00E9_VEGETATION :Augalija
+STR_00EA_OWNERS :Savininkai
+STR_00EB_ROADS :{BLACK}{TINYFONT}Keliai
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Geležinkeliai
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}StotelÄ—s/Oro uostai/Prieplaukos
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Pastatai/Pramonės įmonės
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Transporto priemonÄ—s
+STR_00F0_100M :{BLACK}{TINYFONT}100m
+STR_00F1_200M :{BLACK}{TINYFONT}200m
+STR_00F2_300M :{BLACK}{TINYFONT}300m
+STR_00F3_400M :{BLACK}{TINYFONT}400m
+STR_00F4_500M :{BLACK}{TINYFONT}500m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Traukiniai
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Automobiliai
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Laivai
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}LÄ—ktuvai
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Keliai
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Anglies kasykla
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}ElektrinÄ—
+STR_00FC_FOREST :{BLACK}{TINYFONT}Miškas
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}Lentpjūvė
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Naftos perdirbimo įmonė
+STR_00FF_FARM :{BLACK}{TINYFONT}Ferma
+STR_0100_FACTORY :{BLACK}{TINYFONT}Gamykla
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}SpaustuvÄ—
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Naftos gręžinys
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Geležies rūdos kasykla
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Plieno liejykla
+STR_0105_BANK :{BLACK}{TINYFONT}Bankas
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Popieriaus gamykla
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Aukso kasykla
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Maisto perdirbimo įmonė
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Deimantų kasykla
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Vario rūdos kasykla
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Vaismedžių plantacija
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}KauÄiukmedžių plantacija
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Vandens grežinys
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Vandentiekio bokštas
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}Lentpjūvė
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Cukraus vatos krumynai
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Saldumynų gamykla
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Baterijų ūkis
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Kolos gręžiniai
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Žaislų parduotuvė
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Žaislų gamykla
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}PlastmasÄ—s versmÄ—s
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Gaiviųjų gėrimų gamykla
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Burbulų leistuvas
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}KaramelÄ—s telkinys
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Cukraus kasykla
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Geležinkelio stotis
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Sunkvežimių pakrovimo aikštelė
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Autobusų stotis
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}Oro uostas/Sraigtasparnių aikštelė
+STR_011F_DOCK :{BLACK}{TINYFONT}Prieplauka
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Kalnuotas kraštas
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Ganykla
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Lygumos
+STR_0123_FIELDS :{BLACK}{TINYFONT}Laukai
+STR_0124_TREES :{BLACK}{TINYFONT}Medžiai
+STR_0125_ROCKS :{BLACK}{TINYFONT}Uolos
+STR_0126_WATER :{BLACK}{TINYFONT}Vanduo
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}NÄ—ra savininko
+STR_0128_TOWNS :{BLACK}{TINYFONT}Miestai
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Pramonės įmonės
+STR_012A_DESERT :{BLACK}{TINYFONT}Dykuma
+STR_012B_SNOW :{BLACK}{TINYFONT}Sniegas
+STR_012C_MESSAGE :{WHITE}Pranešimas
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}Atšaukti
+STR_012F_OK :{BLACK}Gerai
+STR_0130_RENAME :{BLACK}Pervardinti
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Per daug vardų
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Pasirinktas vardas jau naudojamas
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE}...priklauso {STRING}
+STR_013C_CARGO :{BLACK}Keliamoji galia
+STR_013D_INFORMATION :{BLACK}Informacija
+STR_013E_CAPACITIES :{BLACK}Talpumas
+STR_013E_TOTAL_CARGO :{BLACK}Visa keliamoji galia
+STR_013F_CAPACITY :{BLACK}Talpa: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}Talpa: {LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Visa traukinio keliamoji galia:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}Naujas žaidimas
+STR_0141_LOAD_GAME :{BLACK}Atverti žaidimą
+STR_SINGLE_PLAYER :{BLACK}Vienas zaidejas
+STR_MULTIPLAYER :{BLACK}Komandinis žaidimas
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Zemelapio dydis:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Žaidimo nustatymai
+
+STR_0150_SOMEONE :kažkas{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Žemėlapis
+STR_0152_TOWN_DIRECTORY :Miestų sąrašas
+STR_0153_SUBSIDIES :Subsidijos
+
+STR_UNITS_IMPERIAL :Imperines
+STR_UNITS_METRIC :Metrine
+STR_UNITS_SI :SI
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} mph
+STR_UNITS_VELOCITY_METRIC :{COMMA} km/h
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}AG
+STR_UNITS_POWER_METRIC :{COMMA}AG
+STR_UNITS_POWER_SI :{COMMA}kW
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} ton{P a os ų}
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} ton{P a os ų}
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} kg
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}gal
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}l
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}m?
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} galon{P as ai ų}
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} litr{P as ai ų}
+STR_UNITS_VOLUME_LONG_SI :{COMMA} m?
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10³ svar{P o ų ų} jėga (lbf)
+STR_UNITS_FORCE_METRIC :{COMMA} ton{P os ų ų} jėga
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Įprastinės veiklos pelno diagrama
+STR_0155_INCOME_GRAPH :Pajamų diagrama
+STR_0156_DELIVERED_CARGO_GRAPH :Krovinių pristatymo diagrama
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Našumo diagrama
+STR_0158_COMPANY_VALUE_GRAPH :Kompanijos vertÄ—s diagrama
+STR_0159_CARGO_PAYMENT_RATES :Krovinių apmokėjimo lygis
+STR_015A_COMPANY_LEAGUE_TABLE :Kompanijos užimama vieta
+STR_PERFORMANCE_DETAIL_MENU :Issamus veiklos ivertinimas
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}Apie OpenTTD
+STR_015C_SAVE_GAME :Išsaugoti žaidimą
+STR_015D_LOAD_GAME :Atverti žaidimą
+STR_015E_QUIT_GAME :Nutraukti žaidimą
+STR_015F_QUIT :IÅ¡eiti
+STR_ABANDON_GAME_QUERY :{YELLOW}Ar tikrai norite išeiti iš žaidimo?
+STR_0161_QUIT_GAME :{WHITE}Nutraukti žaidima
+STR_SORT_ORDER_TIP :{BLACK}Pasirink rikiavimo tvarka (mazejimo/didejimo)
+STR_SORT_CRITERIA_TIP :{BLACK}Pasirink rikiavimo kriteriju
+STR_SORT_BY :{BLACK}Rikiuoti pagal
+
+STR_SORT_BY_POPULATION :{BLACK}Populiacija
+STR_SORT_BY_PRODUCTION :{BLACK}Produkcija
+STR_SORT_BY_TYPE :{BLACK}Tipa
+STR_SORT_BY_TRANSPORTED :{BLACK}Pervezimus
+STR_SORT_BY_NAME :{BLACK}Varda
+STR_SORT_BY_DROPDOWN_NAME :Varda
+STR_SORT_BY_DATE :{BLACK}Data
+STR_SORT_BY_NUMBER :Kieki
+STR_SORT_BY_PROFIT_LAST_YEAR :Praeitu metu pelna
+STR_SORT_BY_PROFIT_THIS_YEAR :Siu metu pelna
+STR_SORT_BY_AGE :Amziu
+STR_SORT_BY_RELIABILITY :Patikimuma
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Suminius produkcijos pervezimus
+STR_SORT_BY_MAX_SPEED :Maksimalus greitis
+STR_SORT_BY_MODEL :Modelis
+STR_SORT_BY_VALUE :Verte
+STR_SORT_BY_FACILITY :Stoties tipas
+STR_SORT_BY_WAITING :Laukiancio krovinio verte
+STR_SORT_BY_RATING_MAX :Kroviniu reitingavimas
+STR_ENGINE_SORT_ENGINE_ID :VariklioID (klasikinis rūšiavimas)
+STR_ENGINE_SORT_COST :Kaina
+STR_ENGINE_SORT_POWER :Galia
+STR_ENGINE_SORT_INTRO_DATE :Atsiradimo data
+STR_ENGINE_SORT_RUNNING_COST :Eksplotacijos išlaidos
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Galia/Eksplotacijos išlaidos
+STR_ENGINE_SORT_CARGO_CAPACITY :Vagono talpa
+STR_NO_WAITING_CARGO :{BLACK}Jokiu kroviniu nera pakrovimui
+STR_SELECT_ALL_FACILITIES :{BLACK}Pazymeti visus pastatus
+STR_SELECT_ALL_TYPES :{BLACK}Pazymeti visus krovinio tipus (iskaitant nelaukiancius kroviniu)
+STR_AVAILABLE_ENGINES_TIP :{BLACK}Peržiūrėti galimų variklių sąrašą tinkamų šiai transporto priemonei.
+STR_MANAGE_LIST :{BLACK}Tvarkyti sąrašą
+STR_MANAGE_LIST_TIP :{BLACK}Siųsti nurodymus visoms šio sąrašo tr. priemonėms
+STR_REPLACE_VEHICLES :Keisti tr. priemones
+STR_SEND_TRAIN_TO_DEPOT :Siųsti į depą
+STR_SEND_ROAD_VEHICLE_TO_DEPOT :Siųsti į depą
+STR_SEND_SHIP_TO_DEPOT :Siųsti į depą
+STR_SEND_AIRCRAFT_TO_HANGAR :Siųsti į angarą
+STR_SEND_FOR_SERVICING :Siųsti techninės apžiūros
+
+############ range for months starts
+STR_0162_JAN :Sau
+STR_0163_FEB :Vas
+STR_0164_MAR :Kov
+STR_0165_APR :Bal
+STR_0166_MAY :Geg
+STR_0167_JUN :Bir
+STR_0168_JUL :Liep
+STR_0169_AUG :Rugp
+STR_016A_SEP :Rug
+STR_016B_OCT :Spa
+STR_016C_NOV :Lap
+STR_016D_DEC :Gruo
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Sustabdyti žaidimą
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Išsaugoti, nutraukti, išeiti iš žaidimo
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Rodyti stotelių sąrašą
+STR_0174_DISPLAY_MAP :{BLACK}Rodyti žemėlapį
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Rodyti žemėlapį, miestų sąrašą
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Rodyti miestų sąrašą
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Rodyti kompanijos finansinÄ™ informacijÄ…
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Rodyti pagrindinÄ™ kompanijos informacijÄ…
+STR_0179_DISPLAY_GRAPHS :{BLACK}Rodyti diagramas
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Transporto kompanijų vertinimas
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Rodyti traukinių sąrašą
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Rodyti automobilių sąrašą
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Rodyti laivų sąrašą
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Rodyti lektuvų sąrašą
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Priartinti vaizdÄ…
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Nutolinti vaizdÄ…
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Tiesti geležinkelius
+STR_0182_BUILD_ROADS :{BLACK}Tiesti kelius
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Statyti prieplaukas
+STR_0184_BUILD_AIRPORTS :{BLACK}Statyti oro uostus
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Sodinti medžius, statyti ženklus ir kt.
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Žemės ploto informacija
+STR_0187_OPTIONS :{BLACK}Parinktys
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Aptarnavimo intervalo keisti negalima...
+STR_018B_CLOSE_WINDOW :{BLACK}Uždaryti langą
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Lango pavadinimas - už jo tempiant galima judinti langą
+STR_STICKY_BUTTON :{BLACK}Pazymeti si langa kaip neuzdaroma komandos 'Uzdaryti visus langus' pagalba (arba 'Delete' klavisas)
+STR_RESIZE_BUTTON :{BLACK}Spragtelk ir trauk, jei nori pakeisti lango dydi
+STR_SAVELOAD_HOME_BUTTON :{BLACK}Spausti cia persokimui i numatytaja saugojimo/ikrovimo direktorija
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Nugriauti pastatus ir kita pasirinktam žemės plote
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Pažeminti žemės lygį
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Paaukštinti žemės lygį
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Slinkties juosta - paslenka sąrašą aukštyn/žemyn
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Prasukimo juosta - prasuka sarasa i kaire/desine
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Rodyti žemės kontūrus žemėlapyje
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Rodyti transporto priemones žemėlapyje
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Rodyti gamyklas žemėlapyje
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Rodyti transporto kelius žemėlapyje
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Rodyti augmeniją žemėlapyje
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Rodyti žemės savininkus žemėlapyje
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Rodyti/paslepti miestų pavadinimus žemėlapyje
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Šių metų pelnas: {CURRENCY} (praėjusių metų: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} metai ({COMMA})
+STR_AGE_RED :{RED}{COMMA} metai ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Automobilis
+STR_019D_AIRCRAFT :LÄ—ktuvas
+STR_019E_SHIP :Laivas
+STR_019F_TRAIN :Traukinys
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} sensta
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} labai paseno
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} labai paseno ir būtinai turi būti pakeistas
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Informacija apie žemės plotą
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}IÅ¡valymo kaina: {LTBLUE}NÄ–RA
+STR_01A5_COST_TO_CLEAR :{BLACK}IÅ¡valymo kaina: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :NÄ–RA
+STR_01A7_OWNER :{BLACK}Savininkas: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Vietos valdžia: {LTBLUE}{STRING}
+STR_01A9_NONE :NÄ—ra
+STR_01AA_NAME :{BLACK}Vardas
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1-ma(s)
+STR_01AD_2ND :2-ra(s)
+STR_01AE_3RD :3-Äia(s)
+STR_01AF_4TH :4-ta(s)
+STR_01B0_5TH :5-ta(s)
+STR_01B1_6TH :6-ta(s)
+STR_01B2_7TH :7-ta(s)
+STR_01B3_8TH :8-ta(s)
+STR_01B4_9TH :9-ta(s)
+STR_01B5_10TH :10-ta(s)
+STR_01B6_11TH :11-ta(s)
+STR_01B7_12TH :12-ta(s)
+STR_01B8_13TH :13-ta(s)
+STR_01B9_14TH :14-ta(s)
+STR_01BA_15TH :15-ta(s)
+STR_01BB_16TH :16-ta(s)
+STR_01BC_17TH :17-ta(s)
+STR_01BD_18TH :18-ta(s)
+STR_01BE_19TH :19-ta(s)
+STR_01BF_20TH :20-ta(s)
+STR_01C0_21ST :21-ma(s)
+STR_01C1_22ND :22-ra(s)
+STR_01C2_23RD :23-Äia(s)
+STR_01C3_24TH :24-ta(s)
+STR_01C4_25TH :25-ta(s)
+STR_01C5_26TH :26-ta(s)
+STR_01C6_27TH :27-ta(s)
+STR_01C7_28TH :28-ta(s)
+STR_01C8_29TH :29-ta(s)
+STR_01C9_30TH :30-ta(s)
+STR_01CA_31ST :31-ma(s)
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Krovinys priimtas: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Jazz Jukebox
+STR_01D3_SOUND_MUSIC :Garsas/muzika
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Rodyti garso/muzikos nustatymus
+STR_01D5_ALL :{TINYFONT}Visi
+STR_01D6_OLD_STYLE :{TINYFONT}Senas stilius
+STR_01D7_NEW_STYLE :{TINYFONT}Naujas stilius
+STR_01D8_EZY_STREET :{TINYFONT}Ezy Street
+STR_01D9_CUSTOM_1 :{TINYFONT}Speciali 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Speciali 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Muzikos garsas
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Efektų garsas
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}TYLU ' ' ' ' ' ' GARSU
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Pereiti prie buvusio garso takelio
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Pereiti prie kito pažymėto takelio
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Sustabdyti muzikos grojimÄ…
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Groti muzikÄ…
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Muzikos ir efektų garsumą galima keisti stumdant slankiklius
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}„{STRING}“
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Takelis{SETX 88}Pavadinimas
+STR_01E9_SHUFFLE :{TINYFONT}Atsitiktinis
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Programa
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Muzikos programos pasirinkimas
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} „{STRING}“
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} „{STRING}“
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Takelio numeris
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Programa - „{STRING}“
+STR_01F0_CLEAR :{TINYFONT}{BLACK}IÅ¡valyti
+STR_01F1_SAVE :{TINYFONT}{BLACK}IÅ¡saugoti
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Dabartinė garso takelių programa
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Parinkti „visi takeliai“ programą
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Parinkti „seno stiliaus muzika“ programą
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Parinkti „naujo stiliaus muzika“ programą
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Parinkti „Speciali 1“ (vartotojo sukurtą) programą
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Parinkti „Speciali 2“ (vartotojo sukurtą) programą
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Panaikinti esama programa (tik „Speciali 1“ arba „Speciali 2“)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}IÅ¡saugoti muzikos nustatymus
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Paspauskite ant garso takelio, norėdami įtraukti į sąrašą (tik „Speciali 1“ arba „Speciali 2“)
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Spragtelėjus takelį, jis pašalinamas iš dabartinės programos (tik „Speciali 1“ ir „Speciali 2“)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Programos „Atsitiktiniai takeliai“ įj./išj.
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Rodyti muzikos takelių pasirinkimo langą
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Paspauskite ant paslaugos, norėdami pamatyti įmonę/miestą
+STR_01FE_DIFFICULTY :{BLACK}Sunkumo lygis ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Paskutinė žinutė/naujiena
+STR_0201_MESSAGE_SETTINGS :ŽinuÄių nustatymai
+STR_MESSAGE_HISTORY_MENU :Zinuciu istorija
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Rodyti paskutinÄ™ žinute/naujienÄ…, rodyti žinuÄių nustatymus
+STR_0204_MESSAGE_OPTIONS :{WHITE}ŽinuÄių nustatymai
+STR_0205_MESSAGE_TYPES :{BLACK}ŽinuÄių tipai:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Pirmosios transporto priemonės atvykimas į žaidėjo stotelę
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Pirmosios transporto priemonės atvykimas į konkurento stotelę
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}Avarijos / nelaimÄ—s
+STR_0209_COMPANY_INFORMATION :{YELLOW}Kompanijos informacija
+STR_020A_ECONOMY_CHANGES :{YELLOW}Ekonomikos pokyÄiai
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Patarimai / informacija apie žaidėjo transporto priemones
+STR_020C_NEW_VEHICLES :{YELLOW}Naujos transporto priemonÄ—s
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Prekių supirkimo pokyÄiai
+STR_020E_SUBSIDIES :{YELLOW}Subsidijos
+STR_020F_GENERAL_INFORMATION :{YELLOW}Bendroji informacija
+STR_MESSAGES_ALL :{YELLOW}Pranesimu nustatymai (ijungta/isjungta/santrauka)
+STR_MESSAGE_SOUND :{YELLOW}Groti garsus pasirodzius naujienu santraukoms
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...per toli buvusio keliones tikslo
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Geriausios kompanijos, kurios pasieke {NUM}{}({STRING} lygį)
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Kompaniju Lygos lentele {NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Biznierius
+STR_0214_ENTREPRENEUR :Verslininkas
+STR_0215_INDUSTRIALIST :Pramonininkas
+STR_0216_CAPITALIST :Kapitalistas
+STR_0217_MAGNATE :Magnatas
+STR_0218_MOGUL :Didziausias magnatas
+STR_0219_TYCOON_OF_THE_CENTURY :Amžiaus magnatas
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} pasiekė „{STRING}“ statusą!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} iš {COMPANY} pasiekė „{STRING}“ statusą!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Sukurti scenarijų
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Scenarijaus redaktorius
+STR_0223_LAND_GENERATION :{WHITE}Kraštovaidžio kūrimas
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}Atsitiktinis reljefas
+STR_0227_RESET_LAND :{BLACK}Anuliuoti reljefÄ…
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Padidinkite sausumos plotą norėdami paaukštinti/pažeminti
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Sumažinkite sausumos plotą norėdami paaukštinti/pažeminti
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Kurti atsitiktinÄ™ sausumÄ…
+STR_022B_RESET_LANDSCAPE :{BLACK}Anuliuoti kraštovaizdį
+STR_022C_RESET_LANDSCAPE :{WHITE}Anuliuoti kraštovaizdį
+STR_LOAD_GAME_HEIGHTMAP :{WHITE}Naudoti Papildoma Zemelapi
+STR_LOAD_SCEN_HEIGHTMAP :{BLACK}Naudoti Papildoma Zemelapi
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Ar tikrai norite anuliuoti kraštovaiždį?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Kraštovaizdžio kūrimas
+STR_022F_TOWN_GENERATION :{BLACK}Miesto įkūrimas
+STR_0230_INDUSTRY_GENERATION :{BLACK}Pramonės kūrimas
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Kelio tiesimas
+STR_0233_TOWN_GENERATION :{WHITE}Miesto įkūrimas
+STR_0234_NEW_TOWN :{BLACK}Naujas miestas
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Įkurti naują miestą
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Negalima įkurti miesto...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...per arti žemėlapio krašto
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...per arti kito miesto
+STR_0239_SITE_UNSUITABLE :{WHITE}...netinkamas sklypas
+STR_023A_TOO_MANY_TOWNS :{WHITE}...per daug miestų
+STR_CANNOT_GENERATE_TOWN :{WHITE}Neimanoma statyti jokiu miestu
+STR_NO_SPACE_FOR_TOWN :{WHITE}...daugiau nera vietos zemelapyje
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}Padidinti miesto dydį
+STR_023C_EXPAND :{BLACK}IÅ¡plÄ—sti
+STR_023D_RANDOM_TOWN :{BLACK}Atsitiktinis miestas
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Pastatyti miestÄ… atsitiktinÄ—jÄ™ vietoje
+STR_023F_INDUSTRY_GENERATION :{WHITE}Pramonės kūrimas
+STR_0240_COAL_MINE :{BLACK}Anglies kasykla
+STR_0241_POWER_STATION :{BLACK}ElektrinÄ—
+STR_0242_SAWMILL :{BLACK}Lentpjūvė
+STR_0243_FOREST :{BLACK}Miškas
+STR_0244_OIL_REFINERY :{BLACK}Naftos perdirbimo įmone
+STR_0245_OIL_RIG :{BLACK}Naftos bokštas
+STR_0246_FACTORY :{BLACK}Gamykla
+STR_0247_STEEL_MILL :{BLACK}Plieno liejykla
+STR_0248_FARM :{BLACK}Ferma
+STR_0249_IRON_ORE_MINE :{BLACK}Geležies rūdos kasykla
+STR_024A_OIL_WELLS :{BLACK}Naftos gręžiniai
+STR_024B_BANK :{BLACK}Bankas
+STR_024C_PAPER_MILL :{BLACK}Popieriaus gamykla
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Maisto perdirbimo įmonė
+STR_024E_PRINTING_WORKS :{BLACK}SpaustuvÄ—
+STR_024F_GOLD_MINE :{BLACK}Aukso kasykla
+STR_0250_LUMBER_MILL :{BLACK}LentpjuvÄ—
+STR_0251_FRUIT_PLANTATION :{BLACK}Vaismedžių plantacija
+STR_0252_RUBBER_PLANTATION :{BLACK}KauÄiukmedių plantacija
+STR_0253_WATER_SUPPLY :{BLACK}Vandens gręžinys
+STR_0254_WATER_TOWER :{BLACK}Vandentiekio bokštas
+STR_0255_DIAMOND_MINE :{BLACK}Deimantų kasykla
+STR_0256_COPPER_ORE_MINE :{BLACK}Vario rūdos kasykla
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Cukraus vatos krūmynai
+STR_0258_CANDY_FACTORY :{BLACK}Saldumynų gamykla
+STR_0259_BATTERY_FARM :{BLACK}Baterijų ūkis
+STR_025A_COLA_WELLS :{BLACK}Kolos gręžiniai
+STR_025B_TOY_SHOP :{BLACK}Žaislų parduotuvė
+STR_025C_TOY_FACTORY :{BLACK}Žaislų gamykla
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}PlastmasÄ—s versmÄ—s
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Gaiviųjų gėrimų gamykla
+STR_025F_BUBBLE_GENERATOR :{BLACK}Burbulų leistuvas
+STR_0260_TOFFEE_QUARRY :{BLACK}KaramelÄ—s telkinys
+STR_0261_SUGAR_MINE :{BLACK}Cukraus kasykla
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Statyti anglies kasyklÄ…
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Statyti elektrinÄ™
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Statyti lentpjuvÄ™
+STR_0265_PLANT_FOREST :{BLACK}Užsodinti mišką
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Statyti naftos perdirbimo įmone
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Statyti naftos grežinį jūroje (tik prie žemelapio kraštų)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Statyti gamyklÄ…
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Statyti plieno liejyklÄ…
+STR_026A_CONSTRUCT_FARM :{BLACK}Statyti ūkį
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Statyti geležies rūdos kasyklą
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Gręžti naftos gręžinius
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Statyti banką (tik miestuose, kuriuose yra bent 1200 gyventojų)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Statyti popieriaus gamyklÄ…
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Statyti maisto perdirbimo imonÄ™
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Statyti spaustuvÄ™
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Statyti aukso kasyklÄ…
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Statyti bankÄ… (tik miestuose)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Pastatykite lentpjūvę (perdirbama nukirsta mediena)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Užsodinti vaismedžių plantaciją
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Užsodinti kauÄiukmedžių plantacijÄ…
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Statyti vandentiekį
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Statyti vandentiekio bokštą (tik miestuose)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Statyti deimantų kasyklą
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Statyti vario rūdos kasyklą
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Užsodinti cukraus vatos krūmynus
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Statyti saldumynų gamyklą
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Statyti baterijų ūkį
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Statyti kolos Å¡ulinius
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Statyti žaislų parduotuvę
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Statyti žaislų gamyklą
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Statyti plastmasÄ—s versmes
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Statyti gaiviųjų gėrimų gamyklą
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Statyti burbulų pūstuvą
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Statyti karamelės telkinį
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Statyti cukraus kasyklÄ…
+STR_0285_CAN_T_BUILD_HERE :{WHITE}{STRING} Äia negali bÅ«ti pastatytas...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...pirma reikia pastatyti miestÄ…
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...mieste gali buti tik vienas
+STR_0288_PLANT_TREES :{BLACK}Sodinti medžius
+STR_0289_PLACE_SIGN :{BLACK}Statyti ženklą
+STR_028A_RANDOM_TREES :{BLACK}Atsitiktiniai medžiai
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Atsitiktinai apsodinti sausumÄ… medziais
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Sukurti uolÄ—tas vietas
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Statyti švyturį
+STR_028E_PLACE_TRANSMITTER :{BLACK}Statyti siųstuvą
+STR_028F_DEFINE_DESERT_AREA :{BLACK}Nurodyti dykumos plotus{}Laikant nuspaustą VALD (CTRL) galima ją pašalinti
+STR_CREATE_LAKE :{BLACK}Pazymeti kaip vandeni, aplinkines zemes bus uztvindytos, jei bus juros lygyje
+STR_0290_DELETE :{BLACK}Å alinti
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Šalinti šį miestą
+STR_0292_SAVE_SCENARIO :Išsaugoti scenarijų
+STR_0293_LOAD_SCENARIO :Atverti scenarijų
+STR_0294_QUIT_EDITOR :Uždaryti redaktoriu
+STR_0295 :
+STR_0296_QUIT :IÅ¡eiti
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Išsaugoti scenarijų, atverti scenarijų, išjungti scenarijų redaktorių, išeiti
+STR_0298_LOAD_SCENARIO :{WHITE}Atverti scenarijų
+STR_0299_SAVE_SCENARIO :{WHITE}Išsaugoti scenarijų
+STR_029A_PLAY_SCENARIO :{BLACK}Išbandyti scenarijų (žaisti)
+STR_PLAY_HEIGHTMAP :{BLACK}Zaisti Papildomam zemelapyje
+STR_PLAY_HEIGHTMAP_HINT :{BLACK}Pradeti zaidima naudojant papildoma zemelapi ir zemtvraka
+STR_QUIT_SCENARIO_QUERY :{YELLOW}Ar tikrai norite išeiti iš šio scenarijaus?
+STR_029C_QUIT_EDITOR :{WHITE}Išeiti iš redaktoriaus
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...gali buti pastatyta tik miestuose, kuriuose yra bent 1200 gyventojų
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Žaidimo pradžios datą sumažinti 1 metais
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Žaidimo pradžios datą padidinti 1 metais
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...abu tilto galai turi buti ant zemÄ—s
+STR_02A1_SMALL :{BLACK}Mažas
+STR_02A2_MEDIUM :{BLACK}Vidutinis
+STR_02A3_LARGE :{BLACK}Didelis
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Išsirinkite miesto dydį
+STR_02A5_TOWN_SIZE :{YELLOW}Miesto dydis:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Parodyti paskutinę žinutę ar spaudos pranešimą
+STR_OFF :Isjungta
+STR_SUMMARY :Santrauka
+STR_FULL :Pilnas
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Miestų sąrašas
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Tr. priemonių pavadinimai
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Standartinis
+STR_02BF_CUSTOM :Tinkintas
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}IÅ¡saugoti tinkintus vardus
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Transporto priemonių pavadinimų pasirinkimo laukas
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Išsaugoti transporto priemonių pavadinimus
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Žaidimo parinktys
+STR_02C5_DIFFICULTY_SETTINGS :Sunkumo nustatymai
+STR_02C7_CONFIG_PATCHES :Nustatymai
+STR_NEWGRF_SETTINGS :Papild. grafikos nustatymai
+STR_GAMEOPTMENU_0A :
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Rodyti miestų pavadinimus
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Rodyti stotelių pavadinimus
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}Rodyti ženklus
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Rodyti tarpines stoteles
+STR_02D0_FULL_ANIMATION :{SETX 12}Pilna animacija
+STR_02D2_FULL_DETAIL :{SETX 12}Pilna detalizacija
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Permatomi pastatai
+STR_TRANSPARENT_SIGNS :{SETX 12}Permatomi stociu zenklai
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Langelio informacija
+STR_02D6 :
+STR_CONSOLE_SETTING :Konsole
+STR_02D7_SCREENSHOT_CTRL_S :Fotografuoti ekrano vaizda (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Fotografuoti viso ekrano vaizda (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :Apie „OpenTTD“
+############ range ends here
+
+STR_02DB_OFF :{BLACK}Isjungta
+STR_02DA_ON :{BLACK}Ijungta
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Rodyti subsidijas
+STR_02DD_SUBSIDIES :Subsidijos
+STR_02DE_MAP_OF_WORLD :Zemelapis
+STR_EXTRA_VIEW_PORT :Papildomas perziuros langas
+STR_SIGN_LIST :Zenklu sarasas
+STR_02DF_TOWN_DIRECTORY :Miestu sarasas
+STR_TOWN_POPULATION :{BLACK}Pasaulio populiacija: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Perziuros langas {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Kopijuoti i perziuros langa
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Kopijuoti globaline padeti i si perziuros langa
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Ikelti is perziuros lango
+STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Ikelti esama padeti i globaline perziura
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Valiuta
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Valiutos pasirinkimas
+STR_MEASURING_UNITS :{BLACK}Suvienodinti vienetus
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_MEASURING_UNITS_SELECTION :{BLACK}Suvienodinti pazymetus vienetus
+STR_02E6_ROAD_VEHICLES :{BLACK}Automobiliai
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Pasirink, kuria kelio puse vaziuos masinos
+STR_02E9_DRIVE_ON_LEFT :Vaziuoja kaire kelio puse
+STR_02EA_DRIVE_ON_RIGHT :Vaziuoja desine kelio puse
+STR_02EB_TOWN_NAMES :{BLACK}Miestu pavadinimai
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Pasirink miestu pavadinimu tipa
+
+STR_02F4_AUTOSAVE :{BLACK}Automatinis saugojimas
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Pasirink kaip daznai automatiskai saugoti zaidima
+STR_02F7_OFF :Isjungta
+STR_02F8_EVERY_3_MONTHS :Kas 3 menesius
+STR_02F9_EVERY_6_MONTHS :Kas 6 menesius
+STR_02FA_EVERY_12_MONTHS :Kas 12 menesiu
+STR_02FB_START_A_NEW_GAME :{BLACK}Pradeti nauja zaidima
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Atverti issaugota zaidima
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Sukurk savo zaidimo zemelapi/scenariju
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Pasirink 1 zaidejo zaidima
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Pasirinkite komandinį žaidima skirtą 2-8 žaidėjams
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Rodyti zaidimo nustatymus
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Rodyti sudetingumo nustatymus
+STR_0303_START_A_NEW_GAME_USING :{BLACK}Naujas zaidimas naudojantis scenarijumi
+STR_0304_QUIT :{BLACK}Baigti
+STR_0305_QUIT_OPENTTD :{BLACK}Baigti 'OpenTTD'
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...gali buti statomas tik miestuose
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Pasirink vidutini klimato tipa
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Pasirink sub-arktini klimato tipa
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Pasirink sub-tropini klimato tipa
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Pasirink zemelapio tipa 'zaislu salis'
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Statyti nauja gamykla
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Pramones katalogas
+STR_0313_FUND_NEW_INDUSTRY :Statyti nauja gamykla
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Statyti nauja gamykla
+STR_JUST_STRING :{STRING}
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...galima statyti tik miestuose
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...gali buti statomas tik dregnose miskingose teritorijose
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...gali buti statomas tik dykumose
+STR_0319_PAUSED :{YELLOW}* * S U S T A B D Y T A * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Ekrano vaizdas issaugotas kaip '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}Ekrano vaizdas neissaugotas!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Nusipirkti zeme velesniam naudojimui
+STR_032F_AUTOSAVE :{RED}AUTOMATINIS SAUGOJIMAS
+STR_SAVING_GAME :{RED}* * Issaugomas zaidimas * *
+STR_SAVE_STILL_IN_PROGRESS :{WHITE}Vyksta išsaugojimas,{}palaukite kol baigsis!
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Pasirink 'Ezy Street' muzikos stiliaus programa
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :Anglų (Oginalus)
+STR_TOWNNAME_FRENCH :Prancūzų
+STR_TOWNNAME_GERMAN :VokieÄių
+STR_TOWNNAME_ADDITIONAL_ENGLISH :Anglų (Papildomas)
+STR_TOWNNAME_LATIN_AMERICAN :Lotynų-Amerikos
+STR_TOWNNAME_SILLY :Kvaili
+STR_TOWNNAME_SWEDISH :Švedų
+STR_TOWNNAME_DUTCH :Olandų
+STR_TOWNNAME_FINNISH :Suomių
+STR_TOWNNAME_POLISH :Lenkų
+STR_TOWNNAME_SLOVAKISH :Slovakų
+STR_TOWNNAME_NORWEGIAN :Norvegų
+STR_TOWNNAME_HUNGARIAN :Vengrų
+STR_TOWNNAME_AUSTRIAN :Austrų
+STR_TOWNNAME_ROMANIAN :Rumunų
+STR_TOWNNAME_CZECH :Čekų
+STR_TOWNNAME_SWISS :Šveicarų
+STR_TOWNNAME_DANISH :Danų
+STR_TOWNNAME_TURKISH :Turkiški
+STR_TOWNNAME_ITALIAN :Italų
+STR_TOWNNAME_CATALAN :Katalonų
+############ end of townname region
+
+STR_CURR_GBP :Svarai sterlingai (£)
+STR_CURR_USD :Doleriai ($)
+STR_CURR_EUR :Eurai (€)
+STR_CURR_YEN :Jenos (Â¥)
+STR_CURR_ATS :Austru silingai (ATS)
+STR_CURR_BEF :Belgijos frankai (BEF)
+STR_CURR_CHF :Sveicarijos frankai (CHF)
+STR_CURR_CZK :Cekijos kronos (CZK)
+STR_CURR_DEM :Vokietijos markes (DEM)
+STR_CURR_DKK :Danijos kronos (DKK)
+STR_CURR_ESP :Ispanijos pesetos (ESP)
+STR_CURR_FIM :Suomijos markes (FIM)
+STR_CURR_FRF :Prancuzijos frankai (FRF)
+STR_CURR_GRD :Graikijos drachmos (GRD)
+STR_CURR_HUF :Vengrijos forintai (HUF)
+STR_CURR_ISK :Islandijos kronos (ISK)
+STR_CURR_ITL :Italu liros (ITL)
+STR_CURR_NLG :Olandijos guldenai (NLG)
+STR_CURR_NOK :Norvegijos kronos (NOK)
+STR_CURR_PLN :Lenkijos zlotai (PLN)
+STR_CURR_ROL :Rumunijos lejos (ROL)
+STR_CURR_RUR :Rusijos rubliai (RUR)
+STR_CURR_SIT :SlovÄ—nijos tolarai (SIT)
+STR_CURR_SEK :Svedijos kronos (SEK)
+STR_CURR_YTL :Turkijos liros (YTL)
+STR_CURR_SKK :Slovakijos kronos (SKK)
+STR_CURR_BRR :Brazilijos realai (BRL)
+
+STR_CURR_CUSTOM :Kita...
+
+STR_OPTIONS_LANG :{BLACK}Kalba
+STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_LANG_TIP :{BLACK}Pasirink aplinkos kalba
+
+STR_OPTIONS_FULLSCREEN :{BLACK}Per visa ekrana
+STR_OPTIONS_FULLSCREEN_TIP :{BLACK}Pazymek si langeli, jei nori zaisto OpenTTD per visa ekrana
+
+STR_OPTIONS_RES :{BLACK}Ekrano rezoliucija
+STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_RES_TIP :{BLACK}Pasirink ekrano rezoliucija
+
+STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Ekrano vaizdo kopijos tipas
+STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Pasirink ekrano vaizdo kopijos tipa
+
+STR_AUTOSAVE_1_MONTH :Kiekviena menesi
+STR_AUTOSAVE_FAILED :{WHITE}Automatinis issaugojimas nepavyko
+
+STR_MONTH_JAN :Sausis
+STR_MONTH_FEB :Vasaris
+STR_MONTH_MAR :Kovas
+STR_MONTH_APR :Balandis
+STR_MONTH_MAY :Geguze
+STR_MONTH_JUN :Birzelis
+STR_MONTH_JUL :Liepa
+STR_MONTH_AUG :Rugpjutis
+STR_MONTH_SEP :Rugsejis
+STR_MONTH_OCT :Spalis
+STR_MONTH_NOV :Lapkritis
+STR_MONTH_DEC :Gruodis
+
+STR_HEADING_FOR_STATION :{LTBLUE}Laukiama {STATION}
+STR_HEADING_FOR_STATION_VEL :{LTBLUE}Vaziuojama i {STATION}, {VELOCITY}
+STR_NO_ORDERS :{LTBLUE}Neturi uzduociu
+STR_NO_ORDERS_VEL :{LTBLUE}Neturi uzduociu, {VELOCITY}
+
+STR_PASSENGERS :keleiviai
+STR_BAGS :maisai
+STR_TONS :tonos
+STR_LITERS :litru
+STR_ITEMS :vienetu
+STR_CRATES :deziu
+STR_RES_OTHER :Kita
+STR_NOTHING :
+
+STR_SMALL_RIGHT_ARROW :{TINYFONT}{RIGHTARROW}
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Uzduociu sarasu dalintis negalima...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Uzduociu saraso kopijuoti negalima...
+STR_END_OF_SHARED_ORDERS :{SETX 10}- - Bendru uzduociu pabaiga - -
+
+STR_TRAIN_IS_LOST :{WHITE}Traukinys {COMMA} pasimete.
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}Traukinio {COMMA} pelnas praeitais metais buvo {CURRENCY}
+STR_EURO_INTRODUCE :{BLACK}{BIGFONT}Bendras Europos sajungos piniginis vienetas - Euras!{}{}Nuo siol Euras tampa pagrindine valiuta kasdieniniuose atsiskaitymuose!
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Traukinys {COMMA} turi per mazai uzduociu
+STR_TRAIN_HAS_VOID_ORDER :{WHITE}Traukinys {COMMA} neturi uzduociu
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}Traukinys {COMMA} turi kelias vienodas uzduotis
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}Traukinio {COMMA} uzduociu sarase yra netinkamu stoteliu
+STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}Automobilis {COMMA} turi per mazai uzduociu
+STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}Automobilis {COMMA} neturi uzduociu
+STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}Automobilis {COMMA} turi kelias vienodas uzduotis
+STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}Automobilio {COMMA} uzduociu sarase yra netinkamu stoteliu
+STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}Laivas {COMMA} turi per mazai uzduociu
+STR_SHIP_HAS_VOID_ORDER :{WHITE}Laivas {COMMA} neturi uzduociu
+STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}Laivas {COMMA} turi kelias vienodas uzduotis
+STR_SHIP_HAS_INVALID_ENTRY :{WHITE}Laivo {COMMA} uzduociu sarase yra netinkamu stoteliu
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}Lektuvas {COMMA} turi per mazai uzduociu
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}Lektuvas {COMMA} neturi uzduociu
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}Lektuvas {COMMA} turi kelias vienodas uzduotis
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}Lektuvo {COMMA} uzduociu sarase yra netinkamu stoteliu
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}Traukinio {COMMA} automatiskai atnaujinti nepavyko (pinigu limitas)
+STR_ROADVEHICLE_AUTORENEW_FAILED :{WHITE}Automobilio {COMMA} automatiskai atnaujinti nepavyko (pinigu limitas)
+STR_SHIP_AUTORENEW_FAILED :{WHITE}Laivo {COMMA} automatinis atnaujimimas nepavyko (pinigu limitas)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}Lektuvo {COMMA} automatinis atnaujimimas nepavyko (pinigu limitas)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}Traukinys {COMMA} yra per ilgas po atnaujinimo
+
+STR_CONFIG_PATCHES :{BLACK}Nustatymu konfiguravimas
+STR_CONFIG_PATCHES_TIP :{BLACK}Konfiguruok nustatymus
+STR_CONFIG_PATCHES_CAPTION :{WHITE}Nustatymu konfiguravimas
+
+STR_CONFIG_PATCHES_OFF :Isjungtas
+STR_CONFIG_PATCHES_ON :Ijungtas
+STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Rodyti tr. priemones greiti statuso eiluteje: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Leisti statyti pastatus pakrantese ir staituose: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Leisti realistinio dydzio 'catchment areas'?: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Leisti griauti miestams priklausancius tiltus, kelius ir kt.: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Leisti statyti ypac ilgus traukinius: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Realistiska traukiniu akseleracija: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Drausti trauk/laivams suktis 90 laips.kampu: {ORANGE}{STRING} {LTBLUE} (reik. NPF)
+STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Leisti sujungti greta pastatytas stoteles: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Palikti stotele, jei nors 1 krovinys pilnai pakrautas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Naudoti patobulinta krovimo algoritma: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GRADUAL_LOADING :{LTBLUE}Pakrauti tr. priemones paeiliui: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Infliacija: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Pristatyti krovini stotelei tiktai tuomet, kai yra poreikis: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Leisti statyti labai ilgus tiltus: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Leisti naudoti uzduoti 'Keliauti i depa': {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Leisti statyti zaliava gaminancius fabrikus: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Leisti kelias panasias pramones imones viename mieste: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Leisti statyti to paties tipo fabrikus arti vienas kito: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Rodyti pilna data busenos eiluteje: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Sviesoforus rodyti vairuotojo puseje: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Rodyti finansine ataskaita metu pabaigoje: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}TTDPatch suderinta nuolatine prieziura?: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Automobiliu vilkstine (su kvantavimo efektu): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Perstumti vaizda, kai pele pasiekia ekrano krasta: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Leisti papirkineti miesto valdzia: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Nestandartines stoteles: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Globalus kelio radimo algoritmas (NPF, panaikina NTP): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_FREIGHT_TRAINS :{LTBLUE}Krovinių svorio daugiklis skirtas imituoti prikrautus traukinius: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Visada leisti statyti mazus oro uotus: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}PerspÄ—ti apie traukinio praradimÄ…: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Perziureti tr. pr. uzduotis: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :ne
+STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :taip, bet isskyrus sustabdytas tr. pr.
+STR_CONFIG_PATCHES_ORDER_REVIEW_ON :visu tr. priemoniu
+STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Perspeti, jei traukinio pajamos neigiamos: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Tr. priemones niekada nepasensta: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Automatiskai atnaujinti tr. priemone, kai ji pasensta
+STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Automatiskai atnaujinti tr. pr. {ORANGE}{STRING}{LTBLUE} men. iki/po maks. amziaus
+STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Automatiniam atnaujinimui reikalinga minimali suma: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Klaidos pranesimu rodymo trukme: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Rodyti miestu gyventoju skaiciu salia pavadinimo: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Nematomi medziai (kai ijungti permatomi pastatai): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Sausumos kūrimas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :Originalus
+STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis
+STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}Didžiausias atstumas nuo kraštų naftos perdirbimo įmonėms {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Sniego linijos aukstis: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN :{LTBLUE}Paviršiaus nelygumas (tik TerraGenesis) : {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Labai lygus
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH :Lygus
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH :Kalnuotas
+STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :Labai kalnuotas
+STR_CONFIG_PATCHES_TREE_PLACER :{LTBLUE}Medžių sodinimo algoritmas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TREE_PLACER_NONE :Jokio
+STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL :Standartinis
+STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED :Pagerintas
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION :{LTBLUE}AukÅ¡Äių žemÄ—lapio pasukimas: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Prieš laikrodžio rodyklę
+STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE :Pagal laikrodžio rodyklę
+STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT :{LTBLUE}Aušktis skiriamas „lygiaus scenarijaus“ žemėlapiui: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Maks. soties plotis: {ORANGE}{STRING} {RED}Demesio: Auksti parametrai letina zaidima
+STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Remontuoti malunsparnius automatiskai: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Susieti kraštovaizdžio įrankių juostą su bėgių/kelių/vandens/orouostų įrankių juostomis: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Apkeisti slinkties kryptį: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Rodyti matavimo pastabą, kai naudojami įvairūs statybų įrankiai: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Rodyti kompanijos ženklus: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_LIVERIES_NONE :Jokių
+STR_CONFIG_PATCHES_LIVERIES_OWN :Savo kompanijos
+STR_CONFIG_PATCHES_LIVERIES_ALL :Visų kompanijų
+STR_CONFIG_PATCHES_PREFER_TEAMCHAT :{LTBLUE}Rašyti komandai naudojant <ĮVESTI> (ENTER): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Maks. traukiniu vienam zaidejui: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Maks. automobiliu zaidejui: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}Maks. lektuvu zaidejui: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}Maks. laivu zaidejui: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Atjungti traukinius kompiuteriui: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Atjungti automobilius kompiuteriui: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Atjungti lektuvus kompiuteriui: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Atjungti laivus kompiuteriui: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Naujas dirbtinio intelekto algoritmas AI (testuojamas): {ORANGE}{STRING}
+STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Naudoti DI (dirbtinį intelektą) komandiniame žaidime (eksperimentinis): {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Traukiniu remonto intervalas: {ORANGE}{STRING} (d. ar %)
+STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Traukiniu remonto intervalas: {ORANGE}isjungta
+STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Automobiliu remonto intervalas: {ORANGE}{STRING} (d. ar %)
+STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Automobiliu remonto intervalas: {ORANGE}isjungta
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Lektuvu remonto intervalas: {ORANGE}{STRING} (d. ar %)
+STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Lektuvu remonto intervalas: {ORANGE} isjungta
+STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Laivu remonto intervalas: {ORANGE}{STRING} (d. ar %)
+STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Laivu remonto intervalas: {ORANGE} isjungta
+STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Atjungti technine apziura, jei gedimai nenaudojami: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Suaktyvinti vagonu greicio apribojima: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}Uždrausti elektrinius bėgius: {ORANGE}{STRING}
+
+STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Spalvotos naujienos atsiranda: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Zaidimo pradzia: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}Zaidimo pabaiga: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Tolygi ekonomika (daug, bet nezymiu pokyciu)
+STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Leisti pirkti kitu kompaniju akcijas
+STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Tempiant, kopijuoti sviesoforus kas: {ORANGE}{STRING} langeli(us)
+STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Pagrindines irankiu juostos pozicija: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Kaireje
+STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Centruoti
+STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Desineje
+STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Langu persidengimo atstumas: {ORANGE}{STRING} px
+STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Langų kibumo atsumas: {ORANGE}disabled
+
+STR_CONFIG_PATCHES_GUI :{BLACK}Vaizdas
+STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Konstrukcijos
+STR_CONFIG_PATCHES_VEHICLES :{BLACK}Tr. priemones
+STR_CONFIG_PATCHES_STATIONS :{BLACK}Stoteles
+STR_CONFIG_PATCHES_ECONOMY :{BLACK}Ekonomika
+STR_CONFIG_PATCHES_AI :{BLACK}Priesininkai
+
+STR_CONFIG_PATCHES_DISABLED :isjungta
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Keisti reiksmes
+STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Klaidingai nurodytas remonto intervalas. Intervalas dienomis: 30-800 d., procentais: 5-90%.
+STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}Naudoti YAPF laivams: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}Naudoti YAPF masinoms: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}Naudoti YAPF traukiniams: {ORANGE}{STRING}
+
+STR_TEMPERATE_LANDSCAPE :Normalus klimatas
+STR_SUB_ARCTIC_LANDSCAPE :Sub-arktinis klimatas
+STR_SUB_TROPICAL_LANDSCAPE :Sub-tropinis klimatas
+STR_TOYLAND_LANDSCAPE :'Zaislinis' klimatas
+
+STR_CHEATS :{WHITE}Sukciavimai
+STR_CHEATS_TIP :{BLACK}Laukeliai rodo ar jus naudojote si triuka pries tai
+STR_CHEATS_WARNING :{BLACK}Demesio! Tu bandai isduoti vargsus savo varzovus. Tai bus tavo geda visiems laikams ir niekada neuzmirsta.
+STR_CHEAT_MONEY :{LTBLUE}Padauginti pinigu {CURRENCY64}
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Zaisti uz zaideja: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Magiskas buldozeris (pasalina gamyklas ir kt.): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Tuneliai gali susikirsti: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Galima statyti pauzes rezime: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Reaktyviniai lektuvai nesuges (dazniausiai) mazuose oro uostuose: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Perjungti klimata: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Pakeisti data: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}Leisti keisti produkcijos vertes: {ORANGE}{STRING}
+
+STR_HEADING_FOR_WAYPOINT :{LTBLUE}Juda i {WAYPOINT}
+STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Juda i {WAYPOINT}, {VELOCITY}
+
+STR_GO_TO_WAYPOINT :Vaziuoti per {WAYPOINT}
+STR_GO_NON_STOP_TO_WAYPOINT :Vaziuoti be sustojimo per {WAYPOINT}
+
+STR_WAYPOINTNAME_CITY :Kontroles punktas {TOWN}
+STR_WAYPOINTNAME_CITY_SERIAL :{TOWN} kontroles punktas#{COMMA}
+STR_LANDINFO_WAYPOINT :Kontroles punktas
+
+STR_WAYPOINT :{WHITE}Kontroles punktas
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Pasirinkite punkto tipa
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+STR_EDIT_WAYPOINT_NAME :{WHITE}Redaguoti punkto varda
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Neimanoma pakeisti punkto vardo...
+STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Paversti begius i kontroles punkta
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Cia neimanoma pastatyti traukiniu kontroles punkto...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Nepavyko pasalinti sio traukiniu kontroles punkto
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Statyti gelezinkelio begius naudojant automatini rezima
+
+STR_NO_TOWN_IN_SCENARIO :{WHITE}...siame scenarijuje nera miestu
+
+STR_GENERATE_RANDOM_LANDSCAPE :{WHITE}Ar tikrai norite sukurti atsitiktini krastovaizdi?
+STR_MANY_RANDOM_TOWNS :{BLACK}Daug atsitiktiniu miestu
+STR_RANDOM_TOWNS_TIP :{BLACK}Uzpildyti zemelapi daugybe atsitiktiniu miestu
+STR_MANY_RANDOM_INDUSTRIES :{BLACK}Daug atsitiktiniu pramones imoniu
+STR_RANDOM_INDUSTRIES_TIP :{BLACK}Uzpildyti zemelapi daugybe atsitiktiniu pramones imoniu
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Neimanoma sukurti pramones imoniu...
+
+STR_LANDSCAPING_TOOLBAR_TIP :{BLACK}Atidaro zemes tvarkymo irankiu juosta, skirta pakelti/nuleisti zemes lygiui, sodinti medzius ir t.t.
+STR_LANDSCAPING_TOOLBAR :{WHITE}Zemes tvarkymas
+STR_LEVEL_LAND_TOOLTIP :{BLACK}Zemes lygis
+
+
+STR_TREES_RANDOM_TYPE :{BLACK}Atsitiktiniai medziai
+STR_TREES_RANDOM_TYPE_TIP :{BLACK}Sodinti atsitiktinius medzius
+
+STR_CANT_BUILD_CANALS :{WHITE}Neimanoma cia iskasti kanalu...
+STR_BUILD_CANALS_TIP :{BLACK}Kasti kanalus
+STR_LANDINFO_CANAL :Kanalas
+
+STR_CANT_BUILD_LOCKS :{WHITE}Neimanoma cia irengti sliuzu...
+STR_BUILD_LOCKS_TIP :{BLACK}Irengti sliuzus
+STR_LANDINFO_LOCK :Sliuzai
+
+STR_BUOY_IS_IN_USE :{WHITE}...pluduras naudojamas!
+
+STR_LANDINFO_COORDS :{BLACK}Koordinates: {LTBLUE}{NUM}x{NUM} ({STRING})
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Neimanoma pasalinti stoties dalies...
+STR_CANT_CONVERT_RAIL :{WHITE}Neimanoma cia pakeisti begio tipo...
+STR_CONVERT_RAIL_TIP :{BLACK}Pakeisti ar pagerinti begio tipa
+
+STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Nutempkite lokomotyva cia, noredami parduoti visa traukini
+
+STR_DRAG_DROP :{BLACK}Nutempti
+STR_STATION_DRAG_DROP :{BLACK}Statyti stotele uzbreziant jos dydi
+STR_SELECT_STATION_CLASS_TIP :{BLACK}Pasirinkti stoties klase rodymui
+STR_SELECT_STATION_TYPE_TIP :{BLACK}Pasirinkti stoties statymo tipa
+
+STR_FAST_FORWARD :{BLACK}Pagreitinti laiko tekme
+STR_MESSAGE_HISTORY :{WHITE}Zinuciu istorija
+STR_MESSAGE_HISTORY_TIP :{BLACK}Paskutiniu zinuciu sarasas
+STR_MESSAGES_DISABLE_ALL :{BLACK}Atjungti visus
+STR_MESSAGES_ENABLE_ALL :{BLACK}Ijungti visus
+
+STR_CONSTRUCT_COAL_MINE_TIP :{BLACK}Statyti anglies kasykla
+STR_CONSTRUCT_FOREST_TIP :{BLACK}Sodinti miska
+STR_CONSTRUCT_OIL_RIG_TIP :{BLACK}Statyti naftos platforma
+STR_CONSTRUCT_FARM_TIP :{BLACK}Įsteigti ūkį
+STR_CONSTRUCT_COPPER_ORE_MINE_TIP :{BLACK}Statyti vario rudos kasykla
+STR_CONSTRUCT_OIL_WELLS_TIP :{BLACK}Ieskoti naftos
+STR_CONSTRUCT_GOLD_MINE_TIP :{BLACK}Statyti aukso kasyklas
+STR_CONSTRUCT_DIAMOND_MINE_TIP :{BLACK}Statyti deimantu kasyklas
+STR_CONSTRUCT_IRON_ORE_MINE_TIP :{BLACK}Statyti anglies rudos kasykla
+STR_CONSTRUCT_FRUIT_PLANTATION_TIP :{BLACK}Užsodinti vaismedžių plantaciją
+STR_CONSTRUCT_RUBBER_PLANTATION_TIP :{BLACK}Užsodinti kauÄiukmedžių plantacijÄ…
+STR_CONSTRUCT_WATER_SUPPLY_TIP :{BLACK}Statyti vandens siurbline
+STR_CONSTRUCT_COTTON_CANDY_TIP :{BLACK}Uzsodinti ledinuku miska
+STR_CONSTRUCT_BATTERY_FARM_TIP :{BLACK}Statyti saules energijos baterijas
+STR_CONSTRUCT_COLA_WELLS_TIP :{BLACK}grezti kokakolos grezini
+STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP :{BLACK}Statyti plastikinius fontanus
+STR_CONSTRUCT_BUBBLE_GENERATOR_TIP :{BLACK}Statyti muilo burbulu generatoriu
+STR_CONSTRUCT_TOFFEE_QUARRY_TIP :{BLACK}Statyti saldainiu fabrika
+STR_CONSTRUCT_SUGAR_MINE_TIP :{BLACK}Statyti cukraus kasykla
+
+STR_INDUSTRYDIR_CAPTION :{WHITE}Gamyklos
+STR_INDUSTRYDIR_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}){YELLOW} ({COMMA}% transportuota)
+STR_INDUSTRYDIR_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO}/{CARGO}){YELLOW} ({COMMA}%/{COMMA}% transportuota)
+STR_INDUSTRYDIR_ITEM_NOPROD :{ORANGE}{INDUSTRY}
+
+STR_INDUSTRY_TOO_CLOSE :{WHITE}...per arti kitos gamyklos
+
+STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Isteigti traukini, kuris rupinsis prioritetiniais kroviniais
+STR_RAIL_REFIT_VEHICLE :{BLACK}Isteigti traukini
+STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Pasirink prioritetini krovinio tipa, kurio rupinsis traukinys
+STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Isteigti traukini prioritetiniu kroviniu pervezimui
+STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Negalima isteigti traukinio...
+STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Remonto intervalas procentais: {ORANGE}{STRING}
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Keisti produkcija
+
+TEMP_AI_IN_PROGRESS :{WHITE}Dirbtinio intelekto algoritmas pradeda darba. Jei iskils problemu - fotografuok ekrano vaizda ir konsultuokis forumuose. Sekmes!
+TEMP_AI_ACTIVATED :{WHITE}Demesio: sis naujas dirbtinio intelekto algoritmas dar tik testuojamas! Siuo metu dirba tik su automobiliais!
+TEMP_AI_MULTIPLAYER :{WHITE}Įspėjimas: realizacija dar eksperimentinė (naudojamas naujas Dirbtinis intelektas). Visas iškilusias problemas praneškite truelight@openttd.org.
+
+############ network gui strings
+
+STR_NETWORK_MULTIPLAYER :{WHITE}Komandinis žaidimas
+
+STR_NETWORK_PLAYER_NAME :{BLACK}Zaidejo vardas:
+STR_NETWORK_ENTER_NAME_TIP :{BLACK}Tai vardas, pagal kuri kiti zaidejai tave pazins
+STR_NETWORK_CONNECTION :{BLACK}Rysys:
+STR_NETWORK_CONNECTION_TIP :{BLACK}Pasirink zaidima internete ar vietiniame tinkle (LAN)
+
+STR_NETWORK_START_SERVER :{BLACK}Sukurti serveri
+STR_NETWORK_START_SERVER_TIP :{BLACK}Sukurti savo serveri
+
+STR_NETWORK_GAME_NAME :{BLACK}Vardas
+STR_NETWORK_GAME_NAME_TIP :{BLACK}Zaidimo pavadinimas
+STR_NETWORK_INFO_ICONS_TIP :{BLACK}Kalba, serverio versija ir kt.
+STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Pasirink is saraso zaidima
+
+STR_NETWORK_FIND_SERVER :{BLACK}Rasti serveri
+STR_NETWORK_FIND_SERVER_TIP :{BLACK}Ieskoti serverio
+STR_NETWORK_ADD_SERVER :{BLACK}Prideti serveri
+STR_NETWORK_ADD_SERVER_TIP :{BLACK}Prideda serveri i sarasa, kuris tikrinamas ieskant zaidimu
+STR_NETWORK_ENTER_IP :{BLACK}Ivesk adresa (IP)
+
+STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
+STR_NETWORK_CLIENTS_CAPTION :{BLACK}Zaidejai
+STR_NETWORK_CLIENTS_CAPTION_TIP :{BLACK}Zaidzia / maksimaliai zaideju
+STR_NETWORK_GAME_INFO :{SILVER}Zaidimo informacija
+STR_ORANGE :{ORANGE}{STRING}
+STR_NETWORK_CLIENTS :{SILVER}Zaidejai: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA}
+STR_NETWORK_LANGUAGE :{SILVER}Kalba: {WHITE}{STRING}
+STR_NETWORK_TILESET :{SILVER}Pavadinimas: {WHITE}{STRING}
+STR_NETWORK_MAP_SIZE :{SILVER}Zemelapio dydis: {WHITE}{COMMA}x{COMMA}
+STR_NETWORK_SERVER_VERSION :{SILVER}Serverio versija: {WHITE}{STRING}
+STR_NETWORK_SERVER_ADDRESS :{SILVER}Serverio adresas: {WHITE}{STRING} : {NUM}
+STR_NETWORK_START_DATE :{SILVER}Zaidimo pradzia: {WHITE}{DATE_SHORT}
+STR_NETWORK_CURRENT_DATE :{SILVER}Dabartine data: {WHITE}{DATE_SHORT}
+STR_NETWORK_PASSWORD :{SILVER}Apsaugota slaptazodziu!
+STR_NETWORK_SERVER_OFFLINE :{SILVER}SERVERIS ISJUNGTAS
+STR_NETWORK_SERVER_FULL :{SILVER}SERVERIS PILNAS
+STR_NETWORK_VERSION_MISMATCH :{SILVER}VERSIJU NESUTAPIMAS
+STR_NETWORK_GRF_MISMATCH :{SILVER}NEWGRF NEATITIKIMAS
+
+STR_NETWORK_JOIN_GAME :{BLACK}Jungtis
+
+
+STR_NETWORK_START_GAME_WINDOW :{WHITE}Pradeti nauja daugiazaidejini zaidima
+
+STR_NETWORK_NEW_GAME_NAME :{BLACK}Zaidimo vardas:
+STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}Zaidimo pavadinimas bus rodomas kitiems zaidejams meniu
+STR_NETWORK_SET_PASSWORD :{BLACK}Nustatyti slaptazodi
+STR_NETWORK_PASSWORD_TIP :{BLACK}Apsaugokite savo zaidima slaptazodziu, jei nenorite, kad jis butu viesai prieinamas
+STR_NETWORK_SELECT_MAP :{BLACK}Pasirinkite zemelapi:
+STR_NETWORK_SELECT_MAP_TIP :{BLACK}Kuriame zemelapyje norite zaisti?
+STR_NETWORK_NUMBER_OF_CLIENTS :{BLACK}Maksimalus klientu skaicius:
+STR_NETWORK_NUMBER_OF_CLIENTS_TIP :{BLACK}Pasirinkite maksimalu klientu skaiciu. Nebutinai visos jungtys turi buti uzpildytos
+STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LAN :Vietinis tinklas
+STR_NETWORK_INTERNET :Internetas
+STR_NETWORK_LAN_INTERNET :Vietinis tinklas/ Internet
+STR_NETWORK_INTERNET_ADVERTISE :Internetas (reklamuotis metaserveryje)
+STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_0_PLAYERS :0 zaideju
+STR_NETWORK_1_PLAYERS :1 zaidejas
+STR_NETWORK_2_PLAYERS :2 zaidejai
+STR_NETWORK_3_PLAYERS :3 zaidejai
+STR_NETWORK_4_PLAYERS :4 zaidejai
+STR_NETWORK_5_PLAYERS :5 zaidejai
+STR_NETWORK_6_PLAYERS :6 zaidejai
+STR_NETWORK_7_PLAYERS :7 zaidejai
+STR_NETWORK_8_PLAYERS :8 zaidejai
+STR_NETWORK_9_PLAYERS :9 zaidejai
+STR_NETWORK_10_PLAYERS :10 zaideju
+STR_NETWORK_NUMBER_OF_COMPANIES :{BLACK}Maksimum kompaniju:
+STR_NETWORK_NUMBER_OF_COMPANIES_TIP :{BLACK}Riboti serveri iki tam tikro skaiciaus kompaniju
+STR_NETWORK_COMBO3 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_NUMBER_OF_SPECTATORS :{BLACK}Maksimum ziurovu:
+STR_NETWORK_NUMBER_OF_SPECTATORS_TIP :{BLACK}Riboti serveri iki tam tikro skaiciaus ziurovu
+STR_NETWORK_COMBO4 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Kalba:
+STR_NETWORK_LANGUAGE_TIP :{BLACK}Kiti zaidejai zinos kokia kalba kalbama serveryje
+STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_NETWORK_START_GAME :{BLACK}Pradeti zaidima
+STR_NETWORK_START_GAME_TIP :{BLACK}Predeti nauja zaidima tinkle (atsitiktinis zemelapis ar scenarijus)
+STR_NETWORK_LOAD_GAME :{BLACK}Atverti zaidima
+STR_NETWORK_LOAD_GAME_TIP :{BLACK}Atstatyti anksciau issaugota zaidima tinkle (isitikink kad prisijungei prie to pacio zaidejo)
+
+############ Leave those lines in this order!!
+STR_NETWORK_LANG_ANY :Bet kokia
+STR_NETWORK_LANG_ENGLISH :Anglu
+STR_NETWORK_LANG_GERMAN :Vokieciu
+STR_NETWORK_LANG_FRENCH :Prancuzu
+############ End of leave-in-this-order
+
+STR_NETWORK_GAME_LOBBY :{WHITE}Keliu zaideju meniu
+
+STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Ruosiamasi jungtis: {ORANGE}{STRING}
+STR_NETWORK_COMPANY_LIST_TIP :{BLACK}Sarasas visu kompaniju zaidime. Gali arba prisijungti prie kurios nors, arba sukurti nauja kompanija (jei yra laisvu vietu)
+STR_NETWORK_NEW_COMPANY :{BLACK}Nauja kompanija
+STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Sukursi nauja kompanija
+STR_NETWORK_SPECTATE_GAME :{BLACK}Stebeti zaidima
+STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Stebesi zaidima kaip ziurovas
+STR_NETWORK_JOIN_COMPANY :{BLACK}Prisijungti prie kompanijos
+STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Padesi valdyti sia kompanija
+STR_NETWORK_REFRESH :{BLACK}Atnaujinti serveri
+STR_NETWORK_REFRESH_TIP :{BLACK}Atnaujinti serverio informacija
+
+STR_NETWORK_COMPANY_INFO :{SILVER}KOMPANIJOS INFORMACIJA
+
+STR_NETWORK_COMPANY_NAME :{SILVER}Kompanijos pavadinimas: {WHITE}{STRING}
+STR_NETWORK_INAUGURATION_YEAR :{SILVER}Pradejo zaisti: {WHITE}{NUM}
+STR_NETWORK_VALUE :{SILVER}Kompanijos verte: {WHITE}{CURRENCY64}
+STR_NETWORK_CURRENT_BALANCE :{SILVER}Dabartinis balansas: {WHITE}{CURRENCY64}
+STR_NETWORK_LAST_YEARS_INCOME :{SILVER}Praeitu metu pajamos: {WHITE}{CURRENCY64}
+STR_NETWORK_PERFORMANCE :{SILVER}Sparta: {WHITE}{NUM}
+
+STR_NETWORK_VEHICLES :{SILVER}Transporto priemones: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_STATIONS :{SILVER}Stoteles: {WHITE}{NUM} {TRAIN}, {NUM} {LORRY}, {NUM} {BUS}, {NUM} {PLANE}, {NUM} {SHIP}
+STR_NETWORK_PLAYERS :{SILVER}Zaidejai: {WHITE}{STRING}
+
+STR_NETWORK_CONNECTING :{WHITE}Jungiamasi...
+
+############ Leave those lines in this order!!
+STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) Jungiamasi..
+STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Autorizuojamasi..
+STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Laukiama..
+STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Siunciamas zemelapis..
+STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Dumenu apdorojimas...
+STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) Registruojamasi..
+
+STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Gaunama zaidimo informacija..
+STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Gaunama kompanijos informacija..
+############ End of leave-in-this-order
+STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} vartotoj{P as ai ų} prieš tave
+STR_NETWORK_CONNECTING_DOWNLOADING :{BLACK}{NUM} / {NUM} Kb parsiusta
+
+STR_NETWORK_DISCONNECT :{BLACK}Atsijungti
+
+STR_NETWORK_GIVE_MONEY_CAPTION :{WHITE}Ivesk pinigu kieki kuri nori duoti
+STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Serveris apsaugotas. Ivesk slaptazodi
+STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Kompanija apsaugota. Ivesk slaptazodi
+STR_NETWORK_CLIENT_LIST :{WHITE}Zaideju sarasas
+
+STR_NETWORK_ERR_NOTAVAILABLE :{WHITE} Nerastas tinklo irenginys arba sukompiliuota be ENABLE_NETWORK
+STR_NETWORK_ERR_NOSERVER :{WHITE} Nerado nei vieno zidimo tinkle
+STR_NETWORK_ERR_NOCONNECTION :{WHITE} Serveris neatsake i uzklausa
+STR_NETWORK_ERR_DESYNC :{WHITE} Zaidimo tinkle sinchronizacija nepavyko
+STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} Nutruko rysys
+STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} Negali atverti issaugoto zaidimo
+STR_NETWORK_ERR_SERVER_START :{WHITE} Negali paleisti serverio
+STR_NETWORK_ERR_CLIENT_START :{WHITE} Negali prisijungti
+STR_NETWORK_ERR_TIMEOUT :{WHITE} Baigesi prisijungimo #{NUM} laikas
+STR_NETWORK_ERR_SERVER_ERROR :{WHITE} Protokoli klaida. Prisijungimas baigtas
+STR_NETWORK_ERR_WRONG_REVISION :{WHITE} Zaidimo versija neatitinka serverio zaidimo versijos
+STR_NETWORK_ERR_WRONG_PASSWORD :{WHITE} Blogas slaptazodis
+STR_NETWORK_ERR_SERVER_FULL :{WHITE} Serveris pilnas
+STR_NETWORK_ERR_SERVER_BANNED :{WHITE} Tau uzdrausta prisijungti prie sio serverio (BAN)
+STR_NETWORK_ERR_KICKED :{WHITE} Tu ismestas is zaidimo (KICK)
+STR_NETWORK_ERR_CHEATER :{WHITE} Sukciavimas neleidziamas tinklo zaidime
+
+STR_NETWORK_ERR_LEFT :paliko zaidima
+############ Leave those lines in this order!!
+STR_NETWORK_ERR_CLIENT_GENERAL :klaida
+STR_NETWORK_ERR_CLIENT_DESYNC :sinchronizacijos klaida
+STR_NETWORK_ERR_CLIENT_SAVEGAME :negali uzkrauti zemelapio
+STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :prarastas rysys
+STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :protokolo klaida
+STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :Ne autorizuota
+STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :gautas neteisingas paketas
+STR_NETWORK_ERR_CLIENT_WRONG_REVISION :bloga versija
+STR_NETWORK_ERR_CLIENT_NAME_IN_USE :toks vardas jau naudojamas
+STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :blogas zaidimo slaptazodis
+STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :blogas zaidejo ID (DoCommand)
+STR_NETWORK_ERR_CLIENT_KICKED :ismestas serverio
+STR_NETWORK_ERR_CLIENT_CHEATER :bande sukciauti
+STR_NETWORK_ERR_CLIENT_SERVER_FULL :serveris pilnas
+############ End of leave-in-this-order
+STR_NETWORK_CLIENT_JOINED :prisijunge prie zaidimo
+STR_NETWORK_GIVE_MONEY :dave tavo kompanijai siek tiek pinigu: ({CURRENCY})
+STR_NETWORK_GAVE_MONEY_AWAY :tu davei {STRING} siek tiek pinigu: ({CURRENCY})
+STR_NETWORK_CHAT_COMPANY_CAPTION :[Komandai] :
+STR_NETWORK_CHAT_COMPANY :[Komandai] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_COMPANY :[Komandai] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_CLIENT_CAPTION :[PrivaÄiai] :
+STR_NETWORK_CHAT_CLIENT :[PrivaÄiai] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_TO_CLIENT :[PrivaÄiai] {STRING}: {GRAY}{STRING}
+STR_NETWORK_CHAT_ALL_CAPTION :[Visiems] :
+STR_NETWORK_CHAT_ALL :[Visiems] {STRING}: {GRAY}{STRING}
+STR_NETWORK_NAME_CHANGE :pakeite savo varda i
+STR_NETWORK_SERVER_SHUTDOWN :{WHITE} Serveris uzsidare
+STR_NETWORK_SERVER_REBOOT :{WHITE} Serveris persikrauna...{}Prasau palaukti...
+
+STR_NETWORK_SERVER :Serveris
+STR_NETWORK_CLIENT :Zaidejas
+STR_NETWORK_SPECTATORS :StebÄ—tojai
+
+STR_NETWORK_CLIENTLIST_NONE :(nera)
+STR_NETWORK_CLIENTLIST_KICK :Ismesti (Kick)
+STR_NETWORK_CLIENTLIST_GIVE_MONEY :Duoti pinigu
+STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL :Sakyti visiems
+STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY :Sakyti kompanijai
+STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT :Privati zinute
+
+
+STR_NETWORK_SEND :{BLACK}Siusti
+
+############ end network gui strings
+
+
+STR_CONFIG_PATCHES_MAP_X :{LTBLUE}Zemelapio X-koord. dydis: {ORANGE}{STRING}
+STR_CONFIG_PATCHES_MAP_Y :{LTBLUE}Zemelapio Y-koord. dydis: {ORANGE}{STRING}
+
+
+##### PNG-MAP-Loader
+
+STR_PNGMAP_ERROR :{WHITE}Neina pakrauti zemetvarkos is PNG...
+STR_PNGMAP_ERR_FILE_NOT_FOUND :{WHITE}...byla nerasta.
+STR_PNGMAP_ERR_IMAGE_TYPE :{WHITE}...Negali perversti paveiklselio. 8 arba 24-bit PNG paveikslelis reikalingas.
+STR_PNGMAP_ERR_MISC :{WHITE}...kazkas buvo ne taip. Atsiprasome. (greiciausiai pazeistas failas)
+
+STR_BMPMAP_ERROR :{WHITE}Negalima nuskaityti kraštovaizdžio iš BMP...
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}...nepavyko pakeisti vaizdo failo formato.
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Kainuoja: {CURRENCY}
+STR_0801_COST :{RED}Kainuoja: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Pajamos: {CURRENCY}
+STR_0803_INCOME :{GREEN}Pajamos: {CURRENCY}
+STR_FEEDER_TINY :{TINYFONT}{YELLOW}Pervesti: {CURRENCY}
+STR_FEEDER :{YELLOW}Pervesti: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Numatoma kaina: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Numatomos pajamos: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Negali pakelti zemiu cia...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Negali nukasti zemiu cia...
+STR_080A_ROCKS :Akmenys
+STR_080B_ROUGH_LAND :Nelygi zeme
+STR_080C_BARE_LAND :Lygi zeme
+STR_080D_GRASS :Zole
+STR_080E_FIELDS :Laukai
+STR_080F_SNOW_COVERED_LAND :Uzpustyta zeme
+STR_0810_DESERT :Dykuma
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Neteisingas zemiu nuolydis
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Negalima keliu kombinacija
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}Kasinejimai sugriaus tuneli
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Ir taip juros lygis
+STR_1004_TOO_HIGH :{WHITE}Per auksta
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Netinkamas begis
+STR_1007_ALREADY_BUILT :{WHITE}...jau pastatytas
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Pirmiau pasalinkite gelezinkelio begius
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Gelezinkelio statyba
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Elektrifikuoto Gelezinkelio Statyba
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Vienbegio gelezinkelio statyba
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}MagLev statyba
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Pasirinkite gelezinkelio tilto tipa
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Neimanoma cia pastatyti traukiniu depo...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Neimanoma cia pastatyti gelezinkelio stoties...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Neimanoma cia pastatyti sviesoforu...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Neimanoma cia pastatyti begiu...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Neimanoma pasalinti begiu...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Neimanoma pasalinti sviesoforu...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Traukiniu depo orientacija
+STR_1015_RAILROAD_CONSTRUCTION :Gelezinkelio statyba
+STR_TOOLB_ELRAIL_CONSTRUCTION :Elektrifikuoto Gelezinkelio statyba
+STR_1016_MONORAIL_CONSTRUCTION :Vienbegio gelezinkelio statyba
+STR_1017_MAGLEV_CONSTRUCTION :MagLev statyba
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Statyti gelezinkelio begius
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Statyti traukiniu depa (traukiniu surinkimui ir aptarnavimui)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Statyti gelezinkelio stoti
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Statyti gelezinkelio sviesoforus
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Statyti gelezinkelio tilta
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Statyti gelezinkelio tuneli
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Pasalina begius/sviesoforus
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Tilto statymas - parink kur statyti tilta
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Pasirink gelezinkelio depo orientacija
+STR_1021_RAILROAD_TRACK :Genezinkelio begiai
+STR_1023_RAILROAD_TRAIN_DEPOT :Traukiniu depas
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...sis langelis priklauso kitai kompanijai
+STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :Gelezinkelio begiai su paprastais sviesoforais
+STR_RAILROAD_TRACK_WITH_PRESIGNALS :Gelezinkelio begiai su pre-sviesoforais
+STR_RAILROAD_TRACK_WITH_EXITSIGNALS :Gelezinkelio begiai su exit-sviesoforais
+STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :Gelezinkelio begiai su combo-sviesoforais
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Pirmiausia pasalink kelia
+STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Vyksta kelio darbai
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Kelio tiesimas
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Pasirink tilto tipa
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Asfaltuoti kelio cia negalima...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Sio kelio pasalinti negalima...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Automobiliu garazo orientacija
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Automomobiliu garazo cia statyti negalima...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Autobusu stoteles cia statyti negalima...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Sunkvezimiu pakrovimo aiksteles cia statyti negalima...
+STR_180A_ROAD_CONSTRUCTION :Keliu asfaltavimas
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Asfaltuoti kelia
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Statyti automobiliu garaza (automoiliu pirkimui ir remontui)
+STR_180D_BUILD_BUS_STATION :{BLACK}Statyti autobusu stotele
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Statyti sunkveziniu pakrovimo aikstele
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Statyti tilta automobiliams
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Statyti tuneli automobiliams
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Kelio konstrukciju pasalinimas
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Pasirink automobiliu garazo orientacija
+STR_1814_ROAD :Kelias
+STR_1815_ROAD_WITH_STREETLIGHTS :Kelias su zibintais
+STR_1816_TREE_LINED_ROAD :Trijuostis kelias
+STR_1817_ROAD_VEHICLE_DEPOT :Automobiliu garazas
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :Gelezinkelio pervaza
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Miestai
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Pirmiau turi butu nugriautas pastatas
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}Populiacija: {ORANGE}{COMMA}{BLACK} Namu skaicius: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Pervardinti miesta
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Negalima pervardinti miesto...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} vietine valdzia neleidzia
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Paspausk ant pavavinimo, kad parodyti ekrano centre
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Rodyti miesta ekrano centre
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Keisti miesto varda
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Keleiviu skaicius praeita menesi: {ORANGE}{COMMA}{BLACK} Maks.: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Pasto siuntu praejusi menesi: {ORANGE}{COMMA}{BLACK} Maks.: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Aukstas biuru pastatas
+STR_2010_OFFICE_BLOCK :Biuru kompleksas
+STR_2011_SMALL_BLOCK_OF_FLATS :Nedidelis daugiabutis
+STR_2012_CHURCH :Baznycia
+STR_2013_LARGE_OFFICE_BLOCK :Didelis biuru pastatas
+STR_2014_TOWN_HOUSES :Rotuse
+STR_2015_HOTEL :Viesbutis
+STR_2016_STATUE :Statula
+STR_2017_FOUNTAIN :Fontanas
+STR_2018_PARK :Parkas
+STR_2019_OFFICE_BLOCK :Biuru pastatas
+STR_201A_SHOPS_AND_OFFICES :Parduotuves ir biurai
+STR_201B_MODERN_OFFICE_BUILDING :Modern biuru pastatas
+STR_201C_WAREHOUSE :Sandeliai
+STR_201D_OFFICE_BLOCK :Biuru pastatas
+STR_201E_STADIUM :Stadionas
+STR_201F_OLD_HOUSES :Seni namai
+STR_2020_LOCAL_AUTHORITY :{BLACK}Valdzia
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Rodyti informacija apie valdzia
+STR_2022_LOCAL_AUTHORITY :{WHITE}{TOWN} vietine valdzia
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Transporto kompaniju reitingai:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Subsidijos
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Dar nepanaudotos subsidijos:
+STR_2027_FROM_TO :{ORANGE}{STRING} is {STRING} i {STRING}
+STR_2028_BY :{YELLOW} (iki {DATE_SHORT})
+STR_202A_NONE :{ORANGE}Niekas
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Jau subsidijuojama:
+STR_202C_FROM_TO :{ORANGE}{STRING} is {STATION} i {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, iki {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}Subsidiju pasiulymas baigesi:{}{}{STRING} pervezimas is {STRING} i {STRING} daugiau nebesubsidijuojamas.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Subsidiju laikas baigesi:{}{}{STRING} transportavimas is {STATION} i {STATION} daugiau nebesubsidijuojama.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Subsidiju pasiulymas:{}{}Pirmasis pervezes {STRING} is {STRING} i {STRING} gaus metine vietines valdzios subsidija!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subsidijos suteiktos {COMPANY}!{}{}{STRING} pervezimas is {STATION} i {STATION} metams bus 50% daugiau apmokama!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subsidijos suteiktos {COMPANY}!{}{}{STRING} pervezimas is {STATION} i {STATION} bus metus apmokamas padidintu 200% tarifu!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subsidijos suteiktos {COMPANY}!{}{}{STRING} pervezimas is {STATION} i {STATION} bus metus apmokamas padidintu 300% tarifu!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subsidijos suteiktos {COMPANY}!{}{}{STRING} pervezimas is {STATION} i {STATION} bus metus apmokamas padidintu 400% tarifu!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} vietine valdzia neleidzia statyti kito oro uosto siame mieste
+STR_2036_COTTAGES :Vasarnamiai
+STR_2037_HOUSES :Namai
+STR_2038_FLATS :Butai
+STR_2039_TALL_OFFICE_BLOCK :Daugiaauksciu ofisu blokas
+STR_203A_SHOPS_AND_OFFICES :Parduotuves ir biurai
+STR_203B_SHOPS_AND_OFFICES :Parduotuves ir biurai
+STR_203C_THEATER :Teatras
+STR_203D_STADIUM :Stadionas
+STR_203E_OFFICES :Biurai
+STR_203F_HOUSES :Namai
+STR_2040_CINEMA :Kino teatras
+STR_2041_SHOPPING_MALL :Parduotuviu rajonas
+STR_2042_DO_IT :{BLACK}Pirmyn!
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}Sarasas veiksmu, kuriuos galima atlikti siame mieste - paspausk ant pavadinimo, jei nori daugiau informacijos
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Atlikti auksciau pasirinkta veiksma
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Galimos akcijos:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Maza reklamine kompanija
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Vidutine reklamine kompanija
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Didele reklamine kompanija
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Finansuoti keliu rekonstrukcija
+STR_204A_BUILD_STATUE_OF_COMPANY :Pastatyti kompanijos statula
+STR_204B_FUND_NEW_BUILDINGS :Finansuoti nauju pastatu statyba
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Issipirkti isskirtines teises transportui
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Papirkti vietine valdzia
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Inicijuos maza reklamine kompanija, kad pritraukti daugiau keleiviu ir kroviniu i tavo kompanijos stoteles.{} Kainuos: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Inicijuos vidutine reklamine kompanija, kad pritraukti daugiau keleiviu ir kroviniu i tavo kompanijos stoteles.{} Kainuos: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Inicijuos didele reklamine kompanija, kad pritraukti daugiau keleiviu ir kroviniu i tavo kompanijos stoteles.{} Kainuos: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} Finansuoja miesto keliu rekonstrukcija. Laikinai (iki 6 men.) sutrinka susisiekimas keliais.{} Kainuos: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Statyti statula kompanijos garbei.{} Kainuos: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Finansuoti nauju komerciniu pastatu statyba mieste.{} Cost: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Pirkti isskirtines transporto teises mieste 1 metams. Miesto valdzia keleivius ir krovinius leis pervezti tik tavo kompanijai.{} Kaina: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Paperkant vietinÄ™ valdžiÄ… pakeliamas JÅ«sų reitingas, taÄiau, jeigu pagaus, bus taikoma sunki bausmÄ—.{} Kaina: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}Eismo chaosas {TOWN}!{}{}Keliu rekonstrukcija, finansuojama {COMPANY}, sukels 6 menesiu chaosa keliuose!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (statoma)
+STR_2059_IGLOO :iglus
+STR_205A_TEPEES :Vigvamai
+STR_205B_TEAPOT_HOUSE :Arbatos namai
+STR_205C_PIGGY_BANK :Parsiuku bankas
+
+STR_INDUSTRY :{INDUSTRY}
+STR_TOWN :{TOWN}
+STR_INDUSTRY_FORMAT :{TOWN} {STRING}
+STR_STATION :{STATION}
+
+##id 0x2800
+STR_LANDSCAPING :Reljefinimas
+STR_2800_PLANT_TREES :Sodinti medzius
+STR_2801_PLACE_SIGN :Statyti zenkla
+STR_2802_TREES :{WHITE}Medziai
+STR_2803_TREE_ALREADY_HERE :{WHITE}...medis jau yra
+STR_2804_SITE_UNSUITABLE :{WHITE}...vieta netinkama
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Neimanoma pasodinti medzio...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...per daug zenklu
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Cia zenklo statyti negalima...
+STR_280A_SIGN :Zenklas
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Redaguoti zenklo teksta
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Zenklo pavadinimo keisti negalima...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Pasirink norimu sodinti medziu tipa
+STR_280E_TREES :Medziai
+STR_280F_RAINFOREST :Atograzu miskas
+STR_2810_CACTUS_PLANTS :Kaktusiniai augalai
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Gelezinkelio stoties pasirinkimas
+STR_3001_AIRPORT_SELECTION :{WHITE}Oro uosto pasirinkimas
+STR_3002_ORIENTATION :{BLACK}Orientacia
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Keliu kiekis
+STR_3004_PLATFORM_LENGTH :{BLACK}Platformos ilgis
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Per arti kitos gelezinkelio stoties
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Ribojasi su bent viena stotele
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}Per daug stoteliu/pakrovimo aiksteliu siame mieste
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}Per daug stoteliu
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}Per daug autobusu sustojimu
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}Per daug sunkvezimiu stoteliu
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Per arti kitos stoteles
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Pirmiausia turi nugriauti gelezinkelio stoti
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Per arti kito oro uosto
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Pirmiausia turi nugriauti oro uosta
+
+STR_3030_RENAME_STATION_LOADING :Pervardinti stotele
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Stoteles pervardinti negalima...
+STR_3032_RATINGS :{BLACK}Reitingai
+STR_3033_ACCEPTS :{BLACK}Priima
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}Vietinis transporto sistemos reitingas:
+
+############ range for rating starts
+STR_3035_APPALLING :Baisus
+STR_3036_VERY_POOR :Labai blogas
+STR_3037_POOR :Blogas
+STR_3038_MEDIOCRE :Pusetinas
+STR_3039_GOOD :Geras
+STR_303A_VERY_GOOD :Labai geras
+STR_303B_EXCELLENT :Puikus
+STR_303C_OUTSTANDING :Nuostabus
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} daugiau nepriima {STRING}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} daugiau nepriima {STRING} arba {STRING}
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} jau priima {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} jau priima {STRING} ir {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Autobuso stoteles orientacija
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Sunkvezimio pakrovimo aiksteles orientacija
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Pirmiausia turi nugriauti autobusu stotele
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Pirmiausia turi nugriauti sunkvezimiu pakrovimo aikstele
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Stoteles
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Nieko -
+STR_304B_SITE_UNSUITABLE :{WHITE}...netinkama vieta
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Per arti kitos prieplaukos
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Pirmiausia nugriauk prieplauka
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Pasirink gelezinkelio stoties orientacija
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Pasirink gelezinkelio stoties keliu skaiciu
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Pasirink gelezinkelio stoties ilgi
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Pasirink autobusu stoteles orientacija
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Pasirink sunkvezimiu pakrovimo aiksteles orientacija
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Rodyti stotele ekrano centre
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Parodyti stoteles reitingus
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Pakeisti stoteles pavadinima
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Rodyti priimamu kroviniu sarasa
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Paspausk ant stoteles pavadinimo, kad pamatytum ja ekrano centre
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Pasirinkite aerouosto dydi/tipa
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_STATION_SIGN_TINY :{TINYFONT}{STATION}
+STR_305E_RAILROAD_STATION :Gelezinkelio stotis
+STR_305F_AIRCRAFT_HANGAR :Lektuvo angaras
+STR_3060_AIRPORT :Oro uostas
+STR_3061_TRUCK_LOADING_AREA :Sunkveziniu pakrovimo aikstele
+STR_3062_BUS_STATION :Autobusu stotele
+STR_3063_SHIP_DOCK :Laivu prieplauka
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Rodyti stoteles aptarnaujama teritorija
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Nerodyti stoteles aptarnaujamos teritorijos
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Rodyk aptarnaujama teritorija
+STR_3068_DOCK :{WHITE}Prieplauka
+STR_3069_BUOY :Pluduras
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...pluduras pakeliui
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...stotis per daug issipletusi
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...nestandartines stoteles atjungtos
+STR_USE_CTRL_TO_SELECT_MORE :{BLACK}Laikant nuspaustą VALD (CTRL) galima pažymėti daugiau nei vieną
+
+STR_UNDEFINED :(neapibrėžta eilutė)
+STR_STAT_CLASS_DFLT :Numatytoji stotis
+STR_STAT_CLASS_WAYP :Keliarodziai
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Laivu depo orientacija
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...turi buti statoma ant vandens
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}DLaivu depo statyti negalima...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Pasirink laivu depo orientacija
+STR_3804_WATER :Vanduo
+STR_3805_COAST_OR_RIVERBANK :Juros ar upes krantas
+STR_3806_SHIP_DEPOT :Laivu depas
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...Negalima statyti ant vandens
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Issaugoti zaidima
+STR_4001_LOAD_GAME :{WHITE}Atverti zaidima
+STR_4002_SAVE :{BLACK}Issaugoti
+STR_4003_DELETE :{BLACK}Trinti
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} Mb laisva
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Negali pasiekti disko
+STR_4007_GAME_SAVE_FAILED :{WHITE}Zaidimo issaugoti nepavyko
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Failo istrinti nepavyko
+STR_4009_GAME_LOAD_FAILED :{WHITE}Zaidimo atverti nepavyko
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}Disku, katalogu ir issaugotu zaidimu sarasas
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Pasirinktas zaidimas
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Istrinti pasirinkta zaidima
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Issaugoti zaidima pasirinktu vardu
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Pasirink zaujo zaidimo tipa
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Pasirinkite scenariju (zalia spalva), nustatyta zaidima (melyna), ar atsitiktini nauja zaidima
+STR_4010_GENERATE_RANDOM_NEW_GAME :Atsitiktinai generuoti nauja zaidima
+STR_4011_LOAD_HEIGHTMAP :{WHITE}Atverti aukÅ¡Äių žemÄ—lapį
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} kelyje
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :anglies kasykla
+STR_4803_POWER_STATION :elektrine
+STR_4804_SAWMILL :lentpjuve
+STR_4805_FOREST :miskas
+STR_4806_OIL_REFINERY :naftos perdirbimo imone
+STR_4807_OIL_RIG :naftos platformoje
+STR_4808_FACTORY :gamykla
+STR_4809_PRINTING_WORKS :spaustuveje
+STR_480A_STEEL_MILL :plieno liejykla
+STR_480B_FARM :Å«kis
+STR_480C_COPPER_ORE_MINE :vario rudos kasykla
+STR_480D_OIL_WELLS :naftos grezinys
+STR_480E_BANK :banke
+STR_480F_FOOD_PROCESSING_PLANT :Maisto perdirbimo įmone
+STR_4810_PAPER_MILL :popieriaus fabrike
+STR_4811_GOLD_MINE :aukso kasykla
+STR_4812_BANK :bankas
+STR_4813_DIAMOND_MINE :deimantu kasykla
+STR_4814_IRON_ORE_MINE :gelezies rudos kasykla
+STR_4815_FRUIT_PLANTATION :vaisiu plantacijoje
+STR_4816_RUBBER_PLANTATION :kauciuko plantacijoje
+STR_4817_WATER_SUPPLY :vandens saugykloje
+STR_4818_WATER_TOWER :vandentiekio bokste
+STR_4819_FACTORY :gamykloje
+STR_481A_FARM :Å«kis
+STR_481B_LUMBER_MILL :Lentpjuve
+STR_481C_COTTON_CANDY_FOREST :ledinuku miskas
+STR_481D_CANDY_FACTORY :saldumynu fabrike
+STR_481E_BATTERY_FARM :Bateriju gamykla
+STR_481F_COLA_WELLS :kolos sulinyje
+STR_4820_TOY_SHOP :zaislu parduotuveje
+STR_4821_TOY_FACTORY :zaislu fabrile
+STR_4822_PLASTIC_FOUNTAINS :Plastiko fontanai
+STR_4823_FIZZY_DRINK_FACTORY :Putojanciu gerimu gamykla
+STR_4824_BUBBLE_GENERATOR :burbulu generatoriuje
+STR_4825_TOFFEE_QUARRY :saldainiu fabrike
+STR_4826_SUGAR_MINE :cukraus kasykloje
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Laukia: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Laukia: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Laukia: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Progukcija praeita menesi:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% transportuota)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Rodyti gamykla ekrano centre
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Statomas naujas {STRING} netoli miesto: {TOWN}!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Sodinamas naujas {STRING} netoli miesto: {TOWN}!
+STR_482F_COST :{BLACK}Kaina: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Neimanoma cia pastatyti sio tipo pramones imones...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...miskas gali buti pasodintas tik zemiau sniego ribos
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} pranesa apie neatideliotina uzdaryma!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}Tiekimo problemos vercia {INDUSTRY} paskelbti apie uzdaryma!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}Medziu trukumas vercia {INDUSTRY} pasklebti apie neatideliotina uzdaryma!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} didina produkcijos apimtis!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}{INDUSTRY} pranesa apie rastus naujus anglies isteklius!{}Produkcija tikimasi dvigubinti!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}{INDUSTRY} pranesa apie rastus naujus anglies isteklius!{}Produkcija tikimasi dvigubinti!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}{INDUSTRY} pagerino zemdirbystes metodus ir tikisi padvigubinti produkcija!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}{INDUSTRY} produkcija krenta 50%
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}Vabzdziu anpludzio baime vercia {INDUSTRY}!{} mazinti produkcija perpus.
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...gali buti tik prie zemelapio krastu
+STR_INDUSTRY_PROD_GOUP :{BLACK}{BIGFONT}{STRING} produkcija auga ({INDUSTRY}) - {COMMA}%!
+STR_INDUSTRY_PROD_GODOWN :{BLACK}{BIGFONT}{STRING} produkcija krenta ({INDUSTRY}) - {COMMA}%!
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Tunelyje traukinys
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Tunelyje transporto priemone
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Trukdo kitas tunelis
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Nepavyko iskasti zemes kitame tunelio gale
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Pirmiau reikia pasalinti tuneli
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Pirmiau reikia pasalinti tilta
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Negalima pradeti ir baigti tuo paciu metu
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Po tiltu turi buti lygi zeme arba vanduo
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}Pradzia ir pabaiga turi buti vienoje linijoje
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Vieta netinkama ivaziavimui i tuneli
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :Kabantis (plienas)
+STR_500F_GIRDER_STEEL :Plieno siju
+STR_5010_CANTILEVER_STEEL :Plieno konstrukciju
+STR_5011_SUSPENSION_CONCRETE :Kabantis (betonas)
+STR_5012_WOODEN :Medinis
+STR_5013_CONCRETE :Betoninis
+STR_5014_TUBULAR_STEEL :Vamzdinis (plienas)
+STR_BRIDGE_TUBULAR_SILICON :Vamzdinis (silicio pluostas)
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Negalima cia statyti tilto...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Negalima cia statyti tunelio...
+STR_5017_RAILROAD_TUNNEL :Gelezinkelio tunelis
+STR_5018_ROAD_TUNNEL :Tunelis
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :Plieninis kabantis gelezinkelio tiltas
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Plieno siju gelezinkelio tiltas
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Plieno konstrukciju gelezinkelio tiltas
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :Betoninis kabantis gelezinkelio tiltas
+STR_501F_WOODEN_RAIL_BRIDGE :Medinis gelezinkelio tiltas
+STR_5020_CONCRETE_RAIL_BRIDGE :Betoninis gelezinkelio tiltas
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :Plieninis pakabinamas tiltas
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Plieno siju tiltas
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Plieno konstrukciju tiltas
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :Pakabinamas tiltas su betono atramomis
+STR_5025_WOODEN_ROAD_BRIDGE :Medinis tiltas
+STR_5026_CONCRETE_ROAD_BRIDGE :Betoninis tiltas
+STR_5027_TUBULAR_RAIL_BRIDGE :Vamzdinis gelezinkelio tiltas
+STR_5028_TUBULAR_ROAD_BRIDGE :Vamzdinis tiltas
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Kelyje objektas
+STR_5801_TRANSMITTER :Radijo siustuvas
+STR_5802_LIGHTHOUSE :Svyturys
+STR_5803_COMPANY_HEADQUARTERS :Kompanijos bustine
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...trukdo kompanijos bustine
+STR_5805_COMPANY_OWNED_LAND :Kompanijos zeme
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Neimanoma uzsisakyti sio langelio...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...jis ir taip priklauso jums!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_EMPTY :
+STR_SV_UNNAMED :Bevardis
+STR_SV_TRAIN_NAME :Traukinys {COMMA}
+STR_SV_ROADVEH_NAME :Automobilis {COMMA}
+STR_SV_SHIP_NAME :Laivas {COMMA}
+STR_SV_AIRCRAFT_NAME :Lektuvas {COMMA}
+
+STR_SV_STNAME :{STRING}
+STR_SV_STNAME_NORTH :{STRING} Siaure
+STR_SV_STNAME_SOUTH :{STRING} Pietus
+STR_SV_STNAME_EAST :{STRING} Rytai
+STR_SV_STNAME_WEST :{STRING} Vakarai
+STR_SV_STNAME_CENTRAL :{STRING} Centrine
+STR_SV_STNAME_TRANSFER :{STRING} Perdavimas
+STR_SV_STNAME_HALT :{STRING} Galine
+STR_SV_STNAME_VALLEY :{STRING} Slenio
+STR_SV_STNAME_HEIGHTS :{STRING} Aukstumu
+STR_SV_STNAME_WOODS :{STRING} Misko
+STR_SV_STNAME_LAKESIDE :{STRING} Ezero
+STR_SV_STNAME_EXCHANGE :{STRING}
+STR_SV_STNAME_AIRPORT :{STRING} Oro Uostas
+STR_SV_STNAME_OILFIELD :{STRING} Naftos Platforma
+STR_SV_STNAME_MINES :{STRING} Kasyklos
+STR_SV_STNAME_DOCKS :{STRING} Dokai
+STR_SV_STNAME_BUOY_1 :{STRING} Pluduras 1
+STR_SV_STNAME_BUOY_2 :{STRING} Pluduras 2
+STR_SV_STNAME_BUOY_3 :{STRING} Pluduras 3
+STR_SV_STNAME_BUOY_4 :{STRING} Pluduras 4
+STR_SV_STNAME_BUOY_5 :{STRING} Pluduras 5
+STR_SV_STNAME_BUOY_6 :{STRING} Pluduras 6
+STR_SV_STNAME_BUOY_7 :{STRING} Pluduras 7
+STR_SV_STNAME_BUOY_8 :{STRING} Pluduras 8
+STR_SV_STNAME_BUOY_9 :{STRING} Pluduras 9
+STR_SV_STNAME_ANNEXE :{STRING} Kreivoji
+STR_SV_STNAME_SIDINGS :{STRING} Krastine
+STR_SV_STNAME_BRANCH :{STRING} Atsaka
+STR_SV_STNAME_UPPER :Aukstutine {STRING}
+STR_SV_STNAME_LOWER :Zemutine {STRING}
+STR_SV_STNAME_HELIPORT :{STRING} Sraigtasparniu Aikstele
+STR_SV_STNAME_FOREST :{STRING} Miskas
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Sunkumo lygis
+STR_OPTIONS_SAVE_CHANGES :{BLACK}Issaugoti
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Lengvas
+STR_6802_MEDIUM :{BLACK}Vidutinis
+STR_6803_HARD :{BLACK}Sunkus
+STR_6804_CUSTOM :{BLACK}Individualus
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maksimalus priesininku skaicius: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Priesininkas pradeda zaidima: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}Miestu gausumas zemelapyje: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}Gamyklu gausumas zemelapyje: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Maksimali paskola: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Pradinis palukanu procentas: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Islaidu transporto priem. eksploatacijai lygis: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Priesininku konstrukciju statymo greitis: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Priesininku intelektas: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Trensporto priemoniu gedimo lygis: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}Subsidiju daugiklis: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Konstrukciju kainos lygis: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Vietoves tipas: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}Juros/ezeru kiekis: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Ekonomika: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}Traukiniai apsisuka: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Nelaimes, katastrofos: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Miesto valdzios poziuris i aplinkos pertvarkyma: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :Nera
+STR_6816_LOW :Zemas
+STR_6817_NORMAL :Normalus
+STR_6818_HIGH :Aukstas
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Labai letas
+STR_681C_SLOW :Letas
+STR_681D_MEDIUM :Vidutinis
+STR_681E_FAST :Greitas
+STR_681F_VERY_FAST :Labai greitas
+STR_VERY_LOW :Labai zemas
+STR_6820_LOW :Zemas
+STR_6821_MEDIUM :Vidutinis
+STR_6822_HIGH :Aukstas
+STR_6823_NONE :Nera
+STR_6824_REDUCED :Sumazintas
+STR_6825_NORMAL :Normalus
+STR_6826_X1_5 :x1.5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Labai lygus
+STR_682B_FLAT :Lygus
+STR_682C_HILLY :Kalvos
+STR_682D_MOUNTAINOUS :Kalnuotas
+STR_682E_STEADY :Pastovi
+STR_682F_FLUCTUATING :Kintanti
+STR_6830_IMMEDIATE :Kartu su zaideju
+STR_6831_3_MONTHS_AFTER_PLAYER :3 menesiai nuo zaidimo pradzios
+STR_6832_6_MONTHS_AFTER_PLAYER :6 menesiai nuo zaidimo pradzios
+STR_6833_9_MONTHS_AFTER_PLAYER :9 menesiai nuo zaidimo pradzios
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :Trasos pabaigoje, stotelese
+STR_6835_AT_END_OF_LINE_ONLY :Tiktai trasos pabaigoje
+STR_6836_OFF :Isjungta
+STR_6837_ON :Ijungta
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Rodyti rezultatu lentele
+STR_6839_PERMISSIVE :Atlaidus
+STR_683A_TOLERANT :Tolerantiskas
+STR_683B_HOSTILE :Priesiskas
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Zaidejas {COMMA})
+STR_7004_NEW_FACE :{BLACK}Naujas veidas
+STR_7005_COLOR_SCHEME :{BLACK}Spalva
+STR_7006_COLOR_SCHEME :{GOLD}Spalva:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Nauja spalva
+STR_7008_COMPANY_NAME :{BLACK}Kompanijos pavadinimas
+STR_7009_PRESIDENT_NAME :{BLACK}Direktoriaus vardas
+STR_700A_COMPANY_NAME :Kompanijos pavadinimas
+STR_700B_PRESIDENT_S_NAME :Direktoriaus vardas
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Kompanijos vardo pakeisti negalima...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Direktoriaus vardo pakeisti negalima...
+STR_700E_FINANCES :{WHITE}{COMPANY} Finansai {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Sanaudos/Pajamos
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}Konstrukcijos
+STR_7012_NEW_VEHICLES :{GOLD}Nauja technika
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Traukiniu sanaudos
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Automobiliu sanaudos
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Lektuvu sanaudos
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Laivu sanaudos
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Nekilnojamo turto sanaudos
+STR_7018_TRAIN_INCOME :{GOLD}Traukiniu pajamos
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Masinu pajamos
+STR_701A_AIRCRAFT_INCOME :{GOLD}Lektuvu pajamos
+STR_701B_SHIP_INCOME :{GOLD}Laivu pajamos
+STR_701C_LOAN_INTEREST :{GOLD}Paskolos palukanos
+STR_701D_OTHER :{GOLD}Kita
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}Viso:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}Pajamu diagrama
+STR_CURRCOMPACT :{CURRCOMPACT64}
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Dirbancio pelno grafikas
+STR_7026_BANK_BALANCE :{WHITE}Saskaitos balansas
+STR_7027_LOAN :{WHITE}Paskola
+STR_MAX_LOAN :{WHITE}Maksimali paskola: {BLACK}{CURRENCY64}
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}Skolintis{SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}Grazinti{SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...skolintis maksimaliai galima {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Daugiau skolintis negalima...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...kreditas grazintas
+STR_702E_REQUIRED :{WHITE}...{CURRENCY} reikia
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Skolos grazinti negalima...
+STR_INSUFFICIENT_FUNDS :{WHITE}Negalima dovanoti is banko pasiskolintu pinigu...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Pasirink nauja veida
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Keicia kompanijos transporto priemoniu spalva
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Keicia kompanijos direktoriaus varda
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Keicia kompanijos pavadinima
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Paspausk ant pasirinktos spalvos
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Padidina paskola
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}Grazina paskolos dali
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(Direktorius)
+STR_7038_INAUGURATED :{GOLD}Eina pareigas nuo: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Transporto priemones:
+STR_TRAINS :{WHITE}{COMMA} traukin{P ys iai ių}
+STR_ROAD_VEHICLES :{WHITE}{COMMA} automobili{P s ai ų}
+STR_AIRCRAFT :{WHITE}{COMMA} lektuvai
+STR_SHIPS :{WHITE}{COMMA} laiv{P as ai ų}
+STR_7042_NONE :{WHITE}Neturi
+STR_7043_FACE_SELECTION :{WHITE}Veido pasirinkimas
+STR_7044_MALE :{BLACK}Vyras
+STR_7045_FEMALE :{BLACK}Moteris
+STR_7046_NEW_FACE :{BLACK}Naujas veidas
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}Nutraukia veido pasirinkima
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Uzbaigia veido pasirinkima
+STR_7049_SELECT_MALE_FACES :{BLACK}Pasirink vyriska veida
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Pasirink moteriska veida
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Generuoja atsitiktinai nauja veida
+STR_704C_KEY :{BLACK}Spalva
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Rodo zaideju spalvas
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}Kompaniju spalvos
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Paspausk kad rodyti/paslepti kompanijos grafika
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Prekiu vienetu pervezta
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Kompanijos pajegumo reitingas (maksimalus=1000)
+STR_7052_COMPANY_VALUES :{WHITE}Kompanijos verte
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Kompaniju lentele
+STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}Transporto kompanija susidure su sunkumais!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} kompanija bus parduota arba bankrutuos nebent reikalai pasitaisys!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(Valdytojas)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Transporto kompaniju susijungimas!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} buvo parduota {COMPANY} uz {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Mes ieskome, kas galetu perimti musu kompanija.{}{}Ar jus noretumete pirkti {COMPANY} uz {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Bankrotas!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}Kreditoriu susirinkimas nusprende uzdaryti {COMPANY} ir parduoti visa turta!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}Ikurta nauja transporto kompanija!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} pradeda statybas prie {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Neimanoma pirkti kompanijos...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Kroviniu pervezimo tarifai
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Dienu kelyje
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}Tarifai pervezant 10 vienetu (ar 10000 litru) kroviniu 20 kvadraciuku atstumu
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Ijungti/isjungti grafika kroviniu tipui
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Inzinierius
+STR_7067_TRAFFIC_MANAGER :Eismo reguliuotojas
+STR_7068_TRANSPORT_COORDINATOR :Transporto koordinatorius
+STR_7069_ROUTE_SUPERVISOR :Marsrutu priziuretojas
+STR_706A_DIRECTOR :Direktorius
+STR_706B_CHIEF_EXECUTIVE :Vykdantysis vadovas
+STR_706C_CHAIRMAN :Pirmininkas
+STR_706D_PRESIDENT :Prezidentas
+STR_706E_TYCOON :Magnatas
+STR_706F_BUILD_HQ :{BLACK}Pastatyti firmos bustine
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Statyti/apziureti kompanijos bustine
+STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Perstatyti kompanijos bustine kitur uz 1% kompanijos vertes
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Neimanoma pastatyti kompanijos bustines...
+STR_7072_VIEW_HQ :{BLACK}Apziureti bustine
+STR_RELOCATE_HQ :{BLACK}Perkelti bustine
+STR_COMPANY_PASSWORD :{BLACK}Slaptazodis
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Slaptazodis apsaugo tavo kompanija nuo neleistinu vartotoju prisijungimo.
+STR_SET_COMPANY_PASSWORD :Ivesti slaptazodi
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}Pasauline krize!{}{}Ekonomikai griuvant, finansu ekspertai bijo paties blogiausio!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Krize iveikta!{}{}Prekybos pagyvejimas suteikia naujas viltis pramones imonems!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Pakeisti lango dydi
+STR_7076_COMPANY_VALUE :{GOLD}Kompanijos verte: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Pirkti 25% kompanijos akciju
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Parduoti 25% kompanijos akciju
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Pirkti 25% sios kompanijos akciju
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Parduoti 25% sios kompanijos akciju
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Negalima nusipirkti 25% sios kompanijos akciju...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}Negalima parduoti 25% sios kompanijos akciju...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% priklauso {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% priklauso {COMPANY}{} {COMMA}% priklauso {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} buvo perimta {COMPANY}!
+STR_7080_PROTECTED :{WHITE}Si kompanija dar pernelyg jauna, kad galetu pardavineti savo akcijas...
+
+STR_LIVERY_DEFAULT :Standartinis Livery
+STR_LIVERY_STEAM :Garo Variklis
+STR_LIVERY_DIESEL :Dyzelinis Variklis
+STR_LIVERY_ELECTRIC :Elektrinis Variklis
+STR_LIVERY_MONORAIL :Vienbegis Variklis
+STR_LIVERY_MAGLEV :Maglev Variklis
+STR_LIVERY_DMU :DMU
+STR_LIVERY_EMU :EMU
+STR_LIVERY_PASSENGER_WAGON_STEAM :Keleivinis Vagonas (Garinis)
+STR_LIVERY_PASSENGER_WAGON_DIESEL :Keleivinis Vagonas (Dyzelinis)
+STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Keleivinis Vagonas (Elektrinis)
+STR_LIVERY_FREIGHT_WAGON :Vagonas
+STR_LIVERY_BUS :Autobusas
+STR_LIVERY_TRUCK :Krovininis
+STR_LIVERY_PASSENGER_SHIP :Keleivinis laivas
+STR_LIVERY_FREIGHT_SHIP :Freight Laivas
+STR_LIVERY_HELICOPTER :Sraigtasparnis
+STR_LIVERY_SMALL_PLANE :Mazas orlaivis
+STR_LIVERY_LARGE_PLANE :Didelis Orlaivis
+
+STR_LIVERY_GENERAL_TIP :{BLACK}Rodyti pagrinidines spalvu parinktis
+STR_LIVERY_TRAIN_TIP :{BLACK}Rodyti traukiniu spalvas
+STR_LIVERY_ROADVEH_TIP :{BLACK}Rodyti masinu spalvas
+STR_LIVERY_SHIP_TIP :{BLACK}Rodyti laivu spalvas
+STR_LIVERY_AIRCRAFT_TIP :{BLACK}Rodyti lektuvu parinktas spalvas
+STR_LIVERY_PRIMARY_TIP :{BLACK}Pasirinkite pirmine spalva
+STR_LIVERY_SECONDARY_TIP :{BLACK}Pasirinikite antrine spalva
+STR_LIVERY_PANEL_TIP :{BLACK}Pazymekite spalva pazymejimui arba multispalvas CTRL+click. Paspauskite spalvos naudojimui
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (Garai)
+STR_8001_MJS_250_DIESEL :MJS 250 (Dyzelis)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut Dyzelis
+STR_8006_POWERNAUT_DIESEL :Powernaut Dyzelis
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (Garai)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (Garai)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (Garai)
+STR_800A_SH_8P_STEAM :SH '8P' (Garai)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (Dyzelis)
+STR_800C_DASH_DIESEL :'Dash' (Dyzelis)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (Dyzelis)
+STR_800E_UU_37_DIESEL :UU '37' (Dyzelis)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (Dyzelis)
+STR_8010_CS_4000_DIESEL :CS 4000 (Dyzelis)
+STR_8011_CS_2400_DIESEL :CS 2400 (Dyzelis)
+STR_8012_CENTENNIAL_DIESEL :Centennial (Dyzelis)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (Dyzelis)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (Dyzelis)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (Dyzelis)
+STR_8016_SH_125_DIESEL :SH '125' (Dyzelis)
+STR_8017_SH_30_ELECTRIC :SH '30' (Elektra)
+STR_8018_SH_40_ELECTRIC :SH '40' (Elektra)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (Elektra)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (Elektra)
+STR_801B_PASSENGER_CAR :Keleiviu vagonas
+STR_801C_MAIL_VAN :Pasto vagonas
+STR_801D_COAL_CAR :Anglies vagonas
+STR_801E_OIL_TANKER :Naftos cisterna
+STR_801F_LIVESTOCK_VAN :Gyvuliu vagonas
+STR_8020_GOODS_VAN :Prekiu vagonas
+STR_8021_GRAIN_HOPPER :Grudu vagonas
+STR_8022_WOOD_TRUCK :Medienos vagonas
+STR_8023_IRON_ORE_HOPPER :Gelezies rudos vagonas
+STR_8024_STEEL_TRUCK :Plieno vagonas
+STR_8025_ARMORED_VAN :Sarvuotas vagonas
+STR_8026_FOOD_VAN :Maisto vagonas
+STR_8027_PAPER_TRUCK :Popieriaus vagonas
+STR_8028_COPPER_ORE_HOPPER :Vario rudos vagonas
+STR_8029_WATER_TANKER :Vandens cisterna
+STR_802A_FRUIT_TRUCK :Vaisiu sunkvezimis
+STR_802B_RUBBER_TRUCK :Kauciuko sunkvezimis
+STR_802C_SUGAR_TRUCK :Cukraus sunkvezimis
+STR_802D_COTTON_CANDY_HOPPER :Ledinuku sunkvezimis
+STR_802E_TOFFEE_HOPPER :Saldainiu sunkvezimis
+STR_802F_BUBBLE_VAN :Burbulu sunkvezimis
+STR_8030_COLA_TANKER :Kolos sunkvezimis
+STR_8031_CANDY_VAN :Saldumynu sunkvezimis
+STR_8032_TOY_VAN :Zaislu sunkvezimis
+STR_8033_BATTERY_TRUCK :Bateriju sunkvezimis
+STR_8034_FIZZY_DRINK_TRUCK :Putojanciu gerimu sunkvezimis
+STR_8035_PLASTIC_TRUCK :Plastic Truck
+STR_8036_X2001_ELECTRIC :'X2001' (Elektra)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Elektra)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :Passenger Carriage
+STR_803A_MAIL_VAN :Mail Van
+STR_803B_COAL_CAR :Coal Truck
+STR_803C_OIL_TANKER :Oil Tanker
+STR_803D_LIVESTOCK_VAN :Livestock Van
+STR_803E_GOODS_VAN :Goods Van
+STR_803F_GRAIN_HOPPER :Grain Hopper
+STR_8040_WOOD_TRUCK :Medienos sunkvezimis
+STR_8041_IRON_ORE_HOPPER :Iron Ore Hopper
+STR_8042_STEEL_TRUCK :Steel Truck
+STR_8043_ARMORED_VAN :Armoured Van
+STR_8044_FOOD_VAN :Food Van
+STR_8045_PAPER_TRUCK :Paper Truck
+STR_8046_COPPER_ORE_HOPPER :Copper Ore Hopper
+STR_8047_WATER_TANKER :Water Tanker
+STR_8048_FRUIT_TRUCK :Fruit Truck
+STR_8049_RUBBER_TRUCK :Rubber Truck
+STR_804A_SUGAR_TRUCK :Sugar Truck
+STR_804B_COTTON_CANDY_HOPPER :Candyfloss Hopper
+STR_804C_TOFFEE_HOPPER :Toffee Hopper
+STR_804D_BUBBLE_VAN :Bubble Van
+STR_804E_COLA_TANKER :Cola Tanker
+STR_804F_CANDY_VAN :Sweet Van
+STR_8050_TOY_VAN :Toy Van
+STR_8051_BATTERY_TRUCK :Battery Truck
+STR_8052_FIZZY_DRINK_TRUCK :Fizzy Drink Truck
+STR_8053_PLASTIC_TRUCK :Plastic Truck
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (Electric)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (Electric)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (Electric)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (Electric)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :Passenger Carriage
+STR_805A_MAIL_VAN :Mail Van
+STR_805B_COAL_CAR :Coal Truck
+STR_805C_OIL_TANKER :Oil Tanker
+STR_805D_LIVESTOCK_VAN :Livestock Van
+STR_805E_GOODS_VAN :Goods Van
+STR_805F_GRAIN_HOPPER :Grain Hopper
+STR_8060_WOOD_TRUCK :Wood Truck
+STR_8061_IRON_ORE_HOPPER :Iron Ore Hopper
+STR_8062_STEEL_TRUCK :Steel Truck
+STR_8063_ARMORED_VAN :Armoured Van
+STR_8064_FOOD_VAN :Food Van
+STR_8065_PAPER_TRUCK :Paper Truck
+STR_8066_COPPER_ORE_HOPPER :Copper Ore Hopper
+STR_8067_WATER_TANKER :Water Tanker
+STR_8068_FRUIT_TRUCK :Fruit Truck
+STR_8069_RUBBER_TRUCK :Rubber Truck
+STR_806A_SUGAR_TRUCK :Sugar Truck
+STR_806B_COTTON_CANDY_HOPPER :Candyfloss Hopper
+STR_806C_TOFFEE_HOPPER :Toffee Hopper
+STR_806D_BUBBLE_VAN :Bubble Van
+STR_806E_COLA_TANKER :Cola Tanker
+STR_806F_CANDY_VAN :Sweet Van
+STR_8070_TOY_VAN :Toy Van
+STR_8071_BATTERY_TRUCK :Battery Truck
+STR_8072_FIZZY_DRINK_TRUCK :Fizzy Drink Truck
+STR_8073_PLASTIC_TRUCK :Plastic Truck
+STR_8074_MPS_REGAL_BUS :MPS karaliskas autobusas
+STR_8075_HEREFORD_LEOPARD_BUS :Hereford Leopard autobusas
+STR_8076_FOSTER_BUS :Foster autobusas
+STR_8077_FOSTER_MKII_SUPERBUS :Foster MkII superautobusas
+STR_8078_PLODDYPHUT_MKI_BUS :Ploddyphut MkI autobusas
+STR_8079_PLODDYPHUT_MKII_BUS :Ploddyphut MkII autobusas
+STR_807A_PLODDYPHUT_MKIII_BUS :Ploddyphut MkIII autobusas
+STR_807B_BALOGH_COAL_TRUCK :Balogh Coal Truck
+STR_807C_UHL_COAL_TRUCK :Uhl Coal Truck
+STR_807D_DW_COAL_TRUCK :DW Coal Truck
+STR_807E_MPS_MAIL_TRUCK :MPS Mail Truck
+STR_807F_REYNARD_MAIL_TRUCK :Reynard Mail Truck
+STR_8080_PERRY_MAIL_TRUCK :Perry Mail Truck
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :MightyMover Mail Truck
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Powernaught Mail Truck
+STR_8083_WIZZOWOW_MAIL_TRUCK :Wizzowow Mail Truck
+STR_8084_WITCOMBE_OIL_TANKER :Witcombe naftos tanklaivis
+STR_8085_FOSTER_OIL_TANKER :Foster naftos tanklaivis
+STR_8086_PERRY_OIL_TANKER :Perry naftos tanklaivis
+STR_8087_TALBOTT_LIVESTOCK_VAN :Talbott Livestock Van
+STR_8088_UHL_LIVESTOCK_VAN :Uhl Livestock Van
+STR_8089_FOSTER_LIVESTOCK_VAN :Foster Livestock Van
+STR_808A_BALOGH_GOODS_TRUCK :Balogh Goods Truck
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Craighead Goods Truck
+STR_808C_GOSS_GOODS_TRUCK :Goss Goods Truck
+STR_808D_HEREFORD_GRAIN_TRUCK :Hereford Grain Truck
+STR_808E_THOMAS_GRAIN_TRUCK :Thomas Grain Truck
+STR_808F_GOSS_GRAIN_TRUCK :Goss Grain Truck
+STR_8090_WITCOMBE_WOOD_TRUCK :Witcombe Wood Truck
+STR_8091_FOSTER_WOOD_TRUCK :Foster Wood Truck
+STR_8092_MORELAND_WOOD_TRUCK :Moreland Wood Truck
+STR_8093_MPS_IRON_ORE_TRUCK :MPS Iron Ore Truck
+STR_8094_UHL_IRON_ORE_TRUCK :Uhl Iron Ore Truck
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Chippy Iron Ore Truck
+STR_8096_BALOGH_STEEL_TRUCK :Balogh Steel Truck
+STR_8097_UHL_STEEL_TRUCK :Uhl Steel Truck
+STR_8098_KELLING_STEEL_TRUCK :Kelling Steel Truck
+STR_8099_BALOGH_ARMORED_TRUCK :Balogh Armoured Truck
+STR_809A_UHL_ARMORED_TRUCK :Uhl Armoured Truck
+STR_809B_FOSTER_ARMORED_TRUCK :Foster Armoured Truck
+STR_809C_FOSTER_FOOD_VAN :Foster Food Van
+STR_809D_PERRY_FOOD_VAN :Perry Food Van
+STR_809E_CHIPPY_FOOD_VAN :Chippy Food Van
+STR_809F_UHL_PAPER_TRUCK :Uhl Paper Truck
+STR_80A0_BALOGH_PAPER_TRUCK :Balogh Paper Truck
+STR_80A1_MPS_PAPER_TRUCK :MPS Paper Truck
+STR_80A2_MPS_COPPER_ORE_TRUCK :MPS Copper Ore Truck
+STR_80A3_UHL_COPPER_ORE_TRUCK :Uhl Copper Ore Truck
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Goss Copper Ore Truck
+STR_80A5_UHL_WATER_TANKER :Uhl vandens tankeris
+STR_80A6_BALOGH_WATER_TANKER :Balogh vandens tankeris
+STR_80A7_MPS_WATER_TANKER :MPS vandens tanklaivis
+STR_80A8_BALOGH_FRUIT_TRUCK :Balogh Fruit Truck
+STR_80A9_UHL_FRUIT_TRUCK :Uhl Fruit Truck
+STR_80AA_KELLING_FRUIT_TRUCK :Kelling Fruit Truck
+STR_80AB_BALOGH_RUBBER_TRUCK :Balogh Rubber Truck
+STR_80AC_UHL_RUBBER_TRUCK :Uhl Rubber Truck
+STR_80AD_RMT_RUBBER_TRUCK :RMT Rubber Truck
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :MightyMover Sugar Truck
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Powernaught Sugar Truck
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Wizzowow Sugar Truck
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :MightyMover Cola Truck
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Powernaught Cola Truck
+STR_80B3_WIZZOWOW_COLA_TRUCK :Wizzowow Cola Truck
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :MightyMover Candyfloss Truck
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Powernaught Candyfloss Truck
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Wizzowow Candyfloss Truck
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :MightyMover Toffee Truck
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Powernaught Toffee Truck
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Wizzowow Toffee Truck
+STR_80BA_MIGHTYMOVER_TOY_VAN :MightyMover Toy Van
+STR_80BB_POWERNAUGHT_TOY_VAN :Powernaught Toy Van
+STR_80BC_WIZZOWOW_TOY_VAN :Wizzowow Toy Van
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :MightyMover Sweet Truck
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Powernaught Sweet Truck
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Wizzowow Sweet Truck
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :MightyMover Battery Truck
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Powernaught Battery Truck
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Wizzowow Battery Truck
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :MightyMover Fizzy Drink Truck
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Powernaught Fizzy Drink Truck
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Wizzowow Fizzy Drink Truck
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :MightyMover Plastic Truck
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Powernaught Plastic Truck
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Wizzowow Plastic Truck
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :MightyMover Bubble Truck
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Powernaught Bubble Truck
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Wizzowow Bubble Truck
+STR_80CC_MPS_OIL_TANKER :MPS naftos tankeris
+STR_80CD_CS_INC_OIL_TANKER :CS-Inc. naftos tankeris
+STR_80CE_MPS_PASSENGER_FERRY :MPS zmoniu keltas
+STR_80CF_FFP_PASSENGER_FERRY :FFP zmoniu keltas
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Bakewell 300 Hovercraft
+STR_80D1_CHUGGER_CHUG_PASSENGER :Chugger-Chug zmoniu keltas
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Shivershake zmoniu keltas
+STR_80D3_YATE_CARGO_SHIP :Yate krovininis laivas
+STR_80D4_BAKEWELL_CARGO_SHIP :Bakewell krovininis laivas
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Mightymover krovininis laivas
+STR_80D6_POWERNAUT_CARGO_SHIP :Powernaut krovininis laivas
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Tricario malunsparnis
+STR_80FE_GURU_X2_HELICOPTER :Guru X2 malunsparnis
+STR_80FF_POWERNAUT_HELICOPTER :Powernaut malunsparnis
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Automobiliu gamintojo zinute
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}Mes ka tik sukonstravome nauja masina {STRING} - ar tu noretum vienerius metus isskirtinemis teisemis bandyti si gamini pries pradedant serijine gamyba?
+STR_8102_RAILROAD_LOCOMOTIVE :lokomotyvas
+STR_8103_ROAD_VEHICLE :automobilis
+STR_8104_AIRCRAFT :lektuvas
+STR_8105_SHIP :laivas
+STR_8106_MONORAIL_LOCOMOTIVE :vienbegis lokomotyvas
+STR_8107_MAGLEV_LOCOMOTIVE :magnetinis lokomotyvas
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}{TOWN} Traukiniu depas
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Gyventojai svencia . . .{}Pirmas traukinys atvaziavo i {STATION}!
+STR_8802_DETAILS :{WHITE}{STRING} (Detales)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Traukinys kelyje
+STR_8804 :{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING} {STRING}
+STR_8806_GO_TO :Vaziuoja i {STATION}
+STR_8807_GO_TO_TRANSFER :Vykti i {STATION} (Perkelti ir pakrauti krovinius)
+STR_8808_GO_TO_UNLOAD :Vykti i {STATION} (Issikrauti)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Vykti i {STATION} (Perkrauti ir palikti tuscia)
+STR_880A_GO_TO_LOAD :Vykti i {STATION} (Pasikrauti)
+STR_880B_GO_TO_TRANSFER_LOAD :Vykti i {STATION} (Perkrauti ir palaukti pilno pakrovimo)
+STR_880C_GO_NON_STOP_TO :Vykti be sustojimo i {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Vykti be sustojimo i {STATION} (Perkrauti ir paimti krovini)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Vykti be sustojimo i {STATION} (Issikrauti)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Vykti be sustojimo i {STATION} (Perkrauti ir palikti tuscia)
+STR_8810_GO_NON_STOP_TO_LOAD :Vykti be sustojimo i {STATION} (Pasikrauti)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Vykti be sustojimo i {STATION} (Perkrauti ir palaukti pilno pakrovimo)
+STR_GO_TO_TRAIN_DEPOT :Vaziuoti i {TOWN} Traukinio Depa
+STR_SERVICE_AT_TRAIN_DEPOT :Remontas {TOWN} traukiniu depe
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Vaziuoti nestojant i {TOWN} traukiniu depa
+STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Remontas nestojant {TOWN} traukiniu depe
+
+STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}Kursas i {TOWN} depa
+STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}Kursas i {TOWN} depa, {VELOCITY}
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE :{LTBLUE}Servisas {TOWN} Traukiniu Depe
+STR_HEADING_FOR_TRAIN_DEPOT_SERVICE_VEL :{LTBLUE}Servisas {TOWN} Traukiniu Depe, {VELOCITY}
+
+STR_INVALID_ORDER :{RED} (Neteisinga tvarka)
+
+STR_UNKNOWN_DESTINATION :nezinomas tikslas
+STR_8812_EMPTY :{LTBLUE}Tuscias
+STR_8813_FROM :{LTBLUE}{CARGO} is {STATION}
+STR_FROM_MULT :{LTBLUE}{CARGO} iš {STATION} (x{NUM})
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}Traukinys {COMMA} laukia depe
+STR_8815_NEW_VEHICLES :{BLACK}Naujos tr. priemones
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Traukinys per ilgas
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Sukeisti traukinius galima tiktai sustabdytus depe
+STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} traukiniai
+
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Nauji Traukiniai
+STR_NEW_ELRAIL_VEHICLES :{WHITE}Nauji Elektriniai Traukiniai
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Nauji Vienbegiai Traukiniai
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Nauji Maglev Traukiniai
+STR_ALL_AVAIL_RAIL_VEHICLES :{WHITE}Traukiniai
+
+STR_881F_BUILD_VEHICLE :{BLACK}Pirkti
+STR_CLONE_ROAD_VEHICLE :{BLACK}Kopijuoti automobilį
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}Tai pagamins automobilio kopijÄ…. SpragtelÄ—jus laikant VALD (CTRL) nukopijuojami nurodymai
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Tai pagamins automobilio kopiją. Spragtelkite šį mygtuką, o tada automobilį esantį depe arba už jo ribų. Spragtelėjus laikant VALD (CTRL) nukopijuojami nurodymai
+STR_CLONE_TRAIN :{BLACK}Kopijuoti traukinį
+STR_CLONE_TRAIN_INFO :{BLACK}Tai pagamins traukinio kopijÄ… su visais vagonais. SpragtelÄ—jus laikant VALD (CTRL) nukopijuojami nurodymai
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}Tai pagamins traukinio kopiją su visais vagonais. Spragtelkite šį mygtuką, o tada traukinį esantį depe arba už jo ribų. Spragtelėjus laikant VALD (CTRL) nukopijuojami nurodymai
+STR_8820_RENAME :{BLACK}Pervardinti
+STR_8823_SKIP :{BLACK}Praleisti
+STR_8824_DELETE :{BLACK}Istrinti
+STR_8825_NON_STOP :{BLACK}Nestoti
+STR_8826_GO_TO :{BLACK}Vaziuoti
+STR_8827_FULL_LOAD :{BLACK}Pakrauti
+STR_8828_UNLOAD :{BLACK}Iskrauti
+STR_REFIT :{BLACK}Naujinti
+STR_REFIT_TIP :{BLACK}Pasirinkite kurį vagonų tipą kuriuo tipu pakeisti (eilės tvarka). Spragtelėjus laikant VALD (CTRL) nurodymas pašalinamas
+STR_REFIT_ORDER :(Keisti į {STRING})
+STR_8829_ORDERS :{WHITE}{VEHICLE} (Uzduotys)
+STR_882A_END_OF_ORDERS :{SETX 10}- - Uzduociu pabaiga- -
+STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING}
+STR_SERVICE :{BLACK}Remontas
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Gelezinkelio transporto priemones nupirkti negalima...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Pastatyta: {LTBLUE}{NUM}{BLACK} Verte: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Verte: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}Pasikrauna / Issikrauna
+STR_TRAIN_MUST_BE_STOPPED :{WHITE}Traukinys turi buti sustabdytas depe
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Traukinio pasiusti i depa negalima...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Truksta vietos uzduotims
+STR_8832_TOO_MANY_ORDERS :{WHITE}Per daug uzduociu
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Negali iterpti naujos uzduoties...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Sios uzduoties negalima istrinti...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Sios uzduoties negalima keisti...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Transporto priemones perkelti negalima...
+STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}Galinis variklis visada seks is paskos priekio
+STR_8838_N_A :N/A{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Priemones negalima parduoti...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Neranda kelio iki artimiausio garazo
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Traukinio sustabdyti/paleisti negalima...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Remonto intervalas: {LTBLUE}{COMMA}dienos{BLACK} Paskutinis remontas: {LTBLUE}{DATE_LONG}
+STR_SERVICING_INTERVAL_PERCENT :{BLACK}Remonto intervalas: {LTBLUE}{COMMA}%{BLACK} Paskutinis remontas: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Traukiniai - spausk ant traukinio, jei nori detalesnes informacijos
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Isigyti nauju traukiniu (reikia traukiniu depo)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Traukiniai - paspausk ant traukinio jei nori detalesnes informacijos, tempk vagona, jei nori ji prikabinti/pasalinti nuo traukinio
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Isigyti nauja gelezinkelio transporto priemone
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Nutempk transporto priemone cia, jei nori ja parduoti
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Parodyti traukiniu depa ekrano centre
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Transporto priemoniu pasirinkimo sarasas - paspausk ant priemones, kad gautum daugiau informacijos
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Isigyti pazymeta transporto priemone
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Pervardinti traukinio tipa
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Dabartine traukinio uzduotis - paspausk cia, jei nori sustabdyti.paleisti traukini
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Parodyti traukinio uzduotis
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Parodyti traukini ekrano centre
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Siusti traukini i depa
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Priversti traukini vaziuoti nelaukiant signalo leidimo
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Pakeisti traukinio vaziavimo krypti
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Rodyti detalia traukinio informacija
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}Didinti intervala tarp remontu
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}Mazinti intervala tarp remontu
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Rodyti detalia kroviniu informacija
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Rodyti detalia vagonu informacija
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Rodyti detalia vagonu talpos informacija
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Rodyti bendra traukinio talpos informacija pagal kroviniu tipa
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Nurodymų sąrašas - nurodymas pažymimas ant jo spragtelėjus. Spregtelėjimas laikant VALD (CTRL) nukelia į stotį
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}Praleisti esama uzduoti, vygdyti sekancia
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Istrinti pazymeta uzduoti
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Nestoti pazymetoje stoteleje
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Iterpti nauja uzduoti pries pazymeta, arba iterpti saraso pabaigoje
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Pazymetoje stoteleje laukti, kol transporto priemone pilnai pasikraus
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Iskrauti krovini pazymetoje stoteleje
+STR_SERVICE_HINT :{BLACK}Nevykdyti sios uzduoties iki tol, kol nereikes remonto
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}Naujas {STRING} atsirado!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Kaina: {CURRENCY} Svoris: {WEIGHT_S}{}Greitis: {VELOCITY} Galia: {POWER}{}Eksplotacijos išlaidos: {CURRENCY}/metus{}Talpa: {CARGO}
+STR_885C_BROKEN_DOWN :{RED}Sugedo
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}Amzius: {LTBLUE}{STRING}{BLACK} Eksploatacijos islaidos: {LTBLUE}{CURRENCY}/met
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Svoris: {LTBLUE}{WEIGHT_S} {BLACK}Galia: {LTBLUE}{POWER}{BLACK} Did. greitis: {LTBLUE}{VELOCITY}
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Svoris: {LTBLUE}{WEIGHT_S} {BLACK}Galia: {LTBLUE}{POWER}{BLACK} Did. greitis {LTBLUE}{VELOCITY} {BLACK}Did. K.G.: {LTBLUE}{FORCE}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Siu metu pelnas : {LTBLUE}{CURRENCY} (praeitu metu: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}Patikimumas: {LTBLUE}{COMMA}% {BLACK}Gedimai nuo praeito remonto: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Sustabdyta
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Neimanoma priversti traukinio vaziuoti nesaugiai...
+STR_8863_CRASHED :{RED}Avarija!
+
+STR_8865_NAME_TRAIN :{WHITE}Traukinio vardas
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}Negali pakeisti traukinio vardo...
+STR_8867_NAME_TRAIN :{BLACK}Traukinio vardas
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Traukinio avarija!{}{COMMA} zuvo liepsnose po katastrofos
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Traukinio vaziavimo krypties pakeisti negalima...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Pervardinti traukinio tipa
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Neimanoma pervardinti traukinio tipo...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Priversti iškrauti krovinius pažymėta tvarka
+STR_886F_TRANSFER :{BLACK}Perkelti
+
+STR_TRAIN_STOPPING :{RED}Stabdoma
+STR_TRAIN_STOPPING_VEL :{RED}Stabdomas, {VELOCITY}
+STR_INCOMPATIBLE_RAIL_TYPES :Nesuderinami begiai
+STR_TRAIN_NO_POWER :{RED}NÄ—ra energijos
+STR_TRAIN_START_NO_CATENARY :Šiuose bėgiuose trūkta grandies, taigi traukiniai negali judėti
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Automobilis kelyje
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} Automobiliai
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}{TOWN} Automobiliu garazas
+STR_9004_NEW_VEHICLES :{BLACK}Naujos tr. priemones
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}Nauji automobiliai
+STR_9007_BUILD_VEHICLE :{BLACK}Isigyti priemone
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Automobilio isigyti negalima...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (Detaliau)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}Amzius: {LTBLUE}{STRING}{BLACK} Eksploatacijos islaidos: {LTBLUE}{CURRENCY}/met
+STR_900E_MAX_SPEED :{BLACK}Maks. greitis: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Pelnas siais metais: {LTBLUE}{CURRENCY} (praejusiais metais: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}Patikimumas: {LTBLUE}{COMMA}% {BLACK}Sugedo po paskutinio remonto: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Pastatytas: {LTBLUE}{NUM}{BLACK} Verte: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Talpa: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE}...automobilis turi buti sustabdytas garaze
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Automobilio parduoti negalima...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Automobilio sustabdyti/paleisti negalima...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}Automobilis {COMMA} laukia garaze
+STR_HEADING_FOR_ROAD_DEPOT :{ORANGE}Uzduotis: {TOWN} garazas
+STR_HEADING_FOR_ROAD_DEPOT_VEL :{ORANGE}Uzduotis: {TOWN} garazas, {VELOCITY}
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE :{LTBLUE}Servisas{TOWN} Masinu Depe
+STR_HEADING_FOR_ROAD_DEPOT_SERVICE_VEL :{LTBLUE}Servisas {TOWN} Masinu Depe, {VELOCITY}
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Negalima rasti automobilio garazo...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Negalima rasti garazo
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Automobiliai - paspausk ant automobilio, jei nori detalesnes informacijos
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Isigyti nauja automobili (reikia automobiliu garazo)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Automobilio uzduotis - spustelk cia, jei nori sustabdyti/paleisti automobili
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Rodyti automobilio uzduotis
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Rodyti automobili ekrano centre
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Siusti automobili i artimiausia garaza
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Apgrezti automobili
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Rodyti detalia automobilio informacija
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Automobiliai - paspausk ant automobilio, jei nori detalesnes informacijos
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Isigyti nauja automobili
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Nutempk automobili cia, jei nori ji parduoti
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Rodyti automobiliu garaza ekrano centre
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Automobiliu pasirinkimo sarasas - paspausk ant automobilio jei nori detalesnes informacijos
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Isigyti pazymeta automobili
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}Atsirado naujas automobilis!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Kaina: {CURRENCY}{}Greitis: {VELOCITY}{}Eksploatavimo kaina: {CURRENCY}/met{}Talpa: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Pavadinti automobili
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Automobilio pavadinti nepavyko...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Pavadinti automobili
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Gyventojai svencia. . .{}Pirmas autobusas atvyko i {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Gyventojai svencia. . .{}Pirmas sunkvezimis atvyko i {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}Automobilio avarija!{}Automobilio vairuotojas zuvo po susidurimo su traukiniu
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}Automobilio avarija!{}{COMMA} sudege po susidurimo su traukiniu
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Automobilis negali apsisukti...
+STR_ONLY_TURN_SINGLE_UNIT :{WHITE}negalima pajudinti automobiliu sudarytu is keliu vienetu
+STR_9034_RENAME :{BLACK}Pervardinti
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Pervardinti automobiliu tipa
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Pervardinti automobiliu tipa
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Negali pervardinti automobliu tipo...
+STR_9038_GO_TO_ROADVEH_DEPOT :Kursas: {TOWN} automobiliu garazas
+STR_SERVICE_AT_ROADVEH_DEPOT :Remontas: {TOWN} garaze
+
+STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Perkomplektuoti transporto priemone kad galetu vezti kitoki krovinio tipa
+STR_REFIT_ROAD_VEHICLE :{BLACK}Perkomplektuoti
+STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Perkomplektuoti transporto priemone kad galetu vezti pazymeta krovinio tipa
+STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Neimanoma perkomplektuoti...
+STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Nurodykite šios transporto priemonės pervežamą krovinių tipą
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Doku konstrukcija
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Doku konstrukcija
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Neimanoma pastatyti uosto cia...
+STR_9803_SHIP_DEPOT :{WHITE}{TOWN} Laivu depas
+STR_9804_NEW_SHIPS :{BLACK}Naujas laivas
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} Laivai
+STR_9808_NEW_SHIPS :{WHITE}Nauji laivai
+STR_9809_BUILD_SHIP :{BLACK}Nupirkti Laiva
+STR_CLONE_SHIP :{BLACK}Kopijuoti laivÄ…
+STR_CLONE_SHIP_INFO :{BLACK}Tai pagamins laivo kopijÄ…. SpragtelÄ—jus laikant VALD (CTRL) nukopijuojami nurodymai
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}Tai pagamins laivo kopiją. Spragtelkite šį mygtuką, o tada traukinį esantį depe arba už jo ribų. Spragtelėjus laikant VALD (CTRL) nukopijuojami nurodymai
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}Laivas turi buti sustabdytas garaze
+STR_980C_CAN_T_SELL_SHIP :{WHITE}Laivo parduoti negalima...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Laivo isigyti negalima...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Laivas kelyje
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Detaliau)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}Amzius: {LTBLUE}{STRING}{BLACK} Eksploatavimo islaidos: {LTBLUE}{CURRENCY}/met
+STR_9813_MAX_SPEED :{BLACK}Maks. greitis: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Pelnas siais metais: {LTBLUE}{CURRENCY} (praeitais metais: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}Patikimumas: {LTBLUE}{COMMA}% {BLACK}Gedimai po paskutinio remonto: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Pastatytas: {LTBLUE}{NUM}{BLACK} Verte: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}Talpa: {LTBLUE}{CARGO}
+STR_9818_CAN_T_STOP_START_SHIP :{WHITE}Sustabdyti/paleisti laivo negalima...
+STR_9819_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Nusiusti i laivu depa negalima...
+STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Negali rasti artimiausio laivu depo
+STR_HEADING_FOR_SHIP_DEPOT :{ORANGE}Kursas: {TOWN} laivu depas
+STR_HEADING_FOR_SHIP_DEPOT_VEL :{ORANGE}Kursas: {TOWN} laivu depas, {VELOCITY}
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE :{LTBLUE}Servisas{TOWN} Laivu Depe
+STR_HEADING_FOR_SHIP_DEPOT_SERVICE_VEL :{LTBLUE}Servisas {TOWN} Laivu Depe, {VELOCITY}
+STR_981C_SHIP_IS_WAITING_IN_DEPOT :{WHITE}Laivas laukia depe: {COMMA}
+STR_981D_BUILD_SHIP_DOCK :{BLACK}Statyti laivu doka
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Statyti laivu depa (nauju laivu isigijimui, remontui)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Laivai - paspausk ant laivo, jei nori daugiau informacijos
+STR_9820_BUILD_NEW_SHIP :{BLACK}Statyti nauja laiva
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Nutempk laiva cia, jei nori ji parduoti
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Rodyti laivu depa ekrano centre
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Laivai - paspausk ant laivo, jei nori daugiau informacijos
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Statyti naujus laivus (reikia laivu depo)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}Laivu sarasas - paspausk ant laivo, jei nori detalesnes informacijos
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Statyti pazymeta laiva
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Dabartine laivo uzduotis - paspausk cia, jei nori sustabdyti/paleisti laiva
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Rodyti laivo uzduotis
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Rodyti laiva ekrano centre
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Nukreipti laiva i depa
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Rodyti laivo informacija
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}Atsirado naujas laivas!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Kainuoja: {CURRENCY} Maks. Greitis: {VELOCITY}{}Talpa: {CARGO}{}Vaziavimo kaina: {CURRENCY}/m
+STR_982F_NAME_SHIP :{BLACK}Laivo vardas
+
+STR_9831_NAME_SHIP :{WHITE}Laivo vardas
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Negalima pervardyti laivo...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Zmones dziaugiasi...{}Pirmas laivas atvyko i {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Statyti pludura, kuris bus naudojamas kaip tarpine stotele
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Negalima cia statyti pluduro...
+STR_9836_RENAME :{BLACK}Pervardinti
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Pakeisti laivo tipa
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Pakeisti laivo varda
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Laivo vardo pakeisti negalima...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Perorientuoti laivo pervezamo krovinio tipa
+STR_983B_REFIT :{WHITE}{VEHICLE} (Perorientuoti)
+STR_983C_REFIT_SHIP :{BLACK}Perorientuoti laiva
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Pasirink krovinio tipa, kuri laivas tures 'sergeti'
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Pakeisti pervezamo krovinio tipa
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Pasirink 'sergimo' krovinio tipa:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nauja talpa: {GOLD}{CARGO}{}{BLACK}Remonto kaina: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Negalima perorientuotilaivo...
+STR_9842_REFITTABLE :(perorientuotinas)
+STR_GO_TO_SHIP_DEPOT :Uzduotis: laivu depas {TOWN}
+SERVICE_AT_SHIP_DEPOT :Remontas {TOWN} miesto laivų depe
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}Oro uostai
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Negalima cia statyti oro uosto...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} Lektuvu angaras
+STR_A003_NEW_AIRCRAFT :{BLACK}Naujas lektuvas
+STR_CLONE_AIRCRAFT :{BLACK}Kopijuoti lÄ—ktuvÄ…
+STR_CLONE_AIRCRAFT_INFO :{BLACK}Tai pagamins lÄ—ktuvo kopijÄ…. SpragtelÄ—jus laikant VALD (CTRL) nukopijuojami nurodymai
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Tai pagamins lėktuvo kopiją. Spragtelkite šį mygtuką, o tada traukinį esantį angare arba už jo ribų. Spragtelėjus laikant VALD (CTRL) nukopijuojami nurodymai
+STR_A005_NEW_AIRCRAFT :{WHITE}Naujas lektuvas
+STR_A006_BUILD_AIRCRAFT :{BLACK}Isigyti lektuva
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Negalima isigyti lektuvo...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} Lektuvai
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (Uzduotys)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (Detaliau)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Amzius: {LTBLUE}{STRING}{BLACK} Eksploatacijos islaidos: {LTBLUE}{CURRENCY}/met.
+STR_A00E_MAX_SPEED :{BLACK}Maks. greitis: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Pelnas siais metais: {LTBLUE}{CURRENCY} (praeitais metais: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}Patikimumas: {LTBLUE}{COMMA}% {BLACK}Gedimai po paskutinio remonto: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Pastatytas: {LTBLUE}{NUM}{BLACK} Verte: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Negalima lektuvo nusiusti i angara...
+STR_HEADING_FOR_HANGAR :{ORANGE}Kursas: {STATION} angaras
+STR_HEADING_FOR_HANGAR_VEL :{ORANGE}Kursas: {STATION} angarasangar, {VELOCITY}
+STR_HEADING_FOR_HANGAR_SERVICE :{LTBLUE}Sevisas {STATION} Angare
+STR_HEADING_FOR_HANGAR_SERVICE_VEL :{LTBLUE}Servisas{STATION} Angare, {VELOCITY}
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}Lektuvas {COMMA} laukia angare
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Oro uostai
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Negalima cia statyti oro uosto...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Lektuvas dabar skrenda
+STR_A019_CAPACITY :{BLACK}Talpa: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Talpa: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}Lektuvas turi buti sustabdytas angare
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Negalima parduoti lektuvo...
+STR_A01D_AIRPORT_CONSTRUCTION :Oro uostu konstr.
+STR_A01E_BUILD_AIRPORT :{BLACK}Statyti opo uosta
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Lektuvas - spauskite ant lektuvo informacijai
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Statyti nauja lektuva (reikia oro uosto su angaru)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Lektuvas - paspausk ant lektuvo, jei nori daugiau informacijos
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Statyti nauja lektuva
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}Nutempk lektuva cia, jei nori parduoti
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Rodyti lektuvu angara ekrano centre
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Lektuvu sarasas - paspausk ant lektuvo, jei nori daugiau informacijos
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Statyti pazymeta lektuva
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Dabartine lektuvo uzduotis - spausk cia, jei nori sustabryti.paleisti lektuva
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Rodyti lektuvo uzduotis
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Rodyti lektuva ektrano centre
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Siusti lektuva i angara
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Rodyti lektuvo informacija
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}Atsirado naujas lektuvas!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Kaina: {CURRENCY} Maks. greitis: {VELOCITY}{}Talpa: {COMMA} keleiviu, {COMMA} pasto maisail{}Eksploatacijos islaidos: {CURRENCY}/met.
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Pervardinti lektuva
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Negalima pervardinti lektuvo...
+STR_A032_NAME_AIRCRAFT :{BLACK}Pervardinti lektuva
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Gyventojai dziugauja. . .{}Pirmas lektuvas atvyko i {STATION}!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Lektuvo katastrofa!{}{COMMA} sudege liepsnose prie {STATION}
+STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Lektuvo katastrofa!{}Lektuvas pritruko degalu, {COMMA} nukrito ant zemes!
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Pervardinti
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Pakeisti lektuvo varda
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Pakeisti lektuvo varda
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Negalima pakeisti lektuvo vardo...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Pakeisti lektuvo pervezamu kroviniu tipa
+STR_A03C_REFIT :{WHITE}{VEHICLE} (Keisti)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Keisti krovinio tipa
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Pasirink nauja krovinio tipa
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Pakeisti lektuvo pervezamo krovinio tipa pazymetu
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Pasirink nauja kroviniu tipa:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nauja talpa: {GOLD}{STRING}{}{BLACK}Pakeitimo kaina: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Negalima pakeisti krovinio tipo...
+STR_GO_TO_AIRPORT_HANGAR :Kursas: {STATION} angaras
+SERVICE_AT_AIRPORT_HANGAR :Remontas {STATION} angare
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT} Dirizablio katastrofa {STATION}!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Automobilis sunaikintas ateiviu!
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}Naftos perdirbimo fabriko sprogimas salia {TOWN}!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT} Įtartinomis aplinkybėmis sunaikintas ūkis, esantis prie {TOWN}!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}Ateiviai nusileido salia {TOWN}!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}Anglies kasyklose salia {TOWN} sedantis gruntas sukele katastrofa - kasykla nenaudojama!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Potvynis!{}Automobilio {COMMA} buvo pasigesta, kaip spejama, tai susije su potvyniu!
+
+STR_BRIBE_FAILED :{WHITE}Tavo meginimas papirkti buvo
+STR_BRIBE_FAILED_2 :{WHITE}issaiskinta vietiniu pareigunu
+STR_BUILD_DATE :{BLACK}Pastatytas: {LTBLUE}{DATE_LONG}
+
+STR_PERFORMANCE_DETAIL :{WHITE}Issamus veiklos ivertinimas
+STR_PERFORMANCE_DETAIL_KEY :{BLACK}Detaliai
+STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT})
+STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA})
+STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}%
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Automobiliai:
+STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Stoteles:
+STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}MIn. pelnas:
+STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Min. pajamos:
+STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Maks. pajamos:
+STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Pristatyta:
+STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Kroviniai:
+STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Pinigai:
+STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Skola:
+STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Viso:
+############ End of order list
+STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Transporto priemoniu skaicius; sis skaicius susideda is automoboliu, traukiniu, laivu ir lektuvu
+STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}Stoteliu kiekis. Kiekviena stotele (pvz. traukiniu, autobusu ar lektuvu) yra skaiciuojama, net jei jos ir yra apjungtos i viena bendra stoti
+STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}Maziausiai pajamu atnesusios tr. priemones pelnas (is visu tr. priermoniu, senesniu nei 2 metai)
+STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Kiekis uzdirbtu pinigu per menesi su zemiausiu pelno rodikliu per paskutinius 12 ketvirciu
+STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Kiekis uzdirbtu pinigu per menesi su didziausiu paskutiniu 12 menesiu pelnu
+STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}Per paskutinius metus (4 ketv.) kroviniu kiekis
+STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}Per paskutini ketvirti perveztu kroviniu rusiu kiekis
+STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Kompanijos pinigu kiekis banko saskaitoje
+STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}Kompanijos pasiskolintu pinigu kiekis
+STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Viso tasku (is visu galimu)
+
+STR_NEWGRF_SETTINGS_BUTTON :{BLACK}NewGRF Nustatymai
+STR_NEWGRF_SETTINGS_CAPTION :{WHITE}Newgrf settings
+STR_NEWGRF_APPLY_CHANGES :{BLACK}Pakeitimai isigalioja
+STR_NEWGRF_SET_PARAMETERS :{BLACK}Nustatyti parametrus
+STR_NEWGRF_TIP :{BLACK}Instaliuotu NewGRF sarasas. Spustelk ant norimos eilutes, jei nori keisti jos nustatymus
+STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}Nera instaliuota NewGRF failu! Prasau skaityti vartotojo vadove apie tai, kaip instaliuoti naujus grafinus elementus (NewGRF)
+STR_NEWGRF_FILENAME :{BLACK}Failo vardas: {SILVER}{STRING}
+STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
+STR_NEWGRF_MD5SUM :{BLACK}MD5suma: {SILVER}{STRING}
+STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}JÅ«s norite atlikti pakeitimus veikianÄiam žaidimui: OpenTTD gali pakibti.{}Ar jÅ«s tikrai norite tai atlikti?
+
+STR_NEWGRF_ADD :{BLACK}PridÄ—ti
+STR_NEWGRF_ADD_TIP :{BLACK}Pridėti NewGRF failą į sąrašą
+STR_NEWGRF_REMOVE :{BLACK}Pašalinti
+STR_NEWGRF_REMOVE_TIP :{BLACK}Pašalinti pažymėtą NewGRF filą iš sąrašo
+STR_NEWGRF_MOVEUP :{BLACK}Perkelti aukštyn
+STR_NEWGRF_MOVEUP_TIP :{BLACK}Perkelti pažymėtus NewGRF failus sąraše aukštyn
+STR_NEWGRF_MOVEDOWN :{BLACK}Perkelti žemyn
+STR_NEWGRF_MOVEDOWN_TIP :{BLACK}Perkelti pažymėtus NewGRF failus sąraše žemyn
+STR_NEWGRF_FILE_TIP :{BLACK}Įdiegtų NewGRF filų sąrašas. Sragtelėjus failą galima keisti jo parametrus
+STR_NEWGRF_PARAMETER :{BLACK}Parametrai: {SILVER}{STRING}
+STR_NEWGRF_PARAMETER_QUERY :{BLACK}Įveskite NewGRF parametrus
+STR_NEWGRF_NO_INFO :{BLACK}Informacija neprieinama
+
+STR_NEWGRF_ADD_CAPTION :{WHITE}Prieinami NewGRF filai
+STR_NEWGRF_ADD_FILE :{BLACK}Pridėti prie pažymėjimo
+STR_NEWGRF_ADD_FILE_TIP :{BLACK}Įtraukti pažymėtus NewGRF failus į jūsų nustatymus
+STR_NEWGRF_RESCAN_FILES :{BLACK}Atnaujinti sąrašą
+STR_NEWGRF_RESCAN_FILES_TIP :{BLACK}Atnaujinti prieinamų NewGRF filų sąrašą
+STR_NEWGRF_DUPLICATE_GRFID :{WHITE}Negalima pridÄ—ti failo: pasikartojantis GRF ID
+
+STR_NEWGRF_NOT_FOUND :{RED}Atitinkamas failas nerastas
+STR_NEWGRF_DISABLED :{RED}Uždrausta
+
+STR_CURRENCY_WINDOW :{WHITE}Pasirinkti valiuta
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Keitimo santykis: {ORANGE}{CURRENCY} = £ {COMMA}
+STR_CURRENCY_SEPARATOR :{LTBLUE}Skyriklis:
+STR_CURRENCY_PREFIX :{LTBLUE}Priesdelis:
+STR_CURRENCY_SUFFIX :{LTBLUE}Pavadinimas:
+STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Pereiti prie Euro: {ORANGE}{NUM}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Pereiti prie Euro: {ORANGE}niekada
+STR_CURRENCY_PREVIEW :{LTBLUE}Perziura: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Keisti pasirinktos valiutos nustatymus
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+STR_LORRY :{BLACK}{LORRY}
+STR_PLANE :{BLACK}{PLANE}
+STR_SHIP :{BLACK}{SHIP}
+
+STR_SCHEDULED_TRAINS :{WHITE}{STATION} - {COMMA} Traukiniai
+STR_SCHEDULED_ROAD_VEHICLES :{WHITE}{STATION} - {COMMA} Automobiliai
+STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} Lektuvai
+STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} Laivai
+
+STR_SCHEDULED_TRAINS_TIP :{BLACK}Rodyti visus traukinius, kuriu uzduotuse yra itraukta si stotele
+STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Rodyti visus automobilius, kuriu uzduotyse yra pamineta si stotele
+STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Rodyti visus lektuvus, kuriu uzduotyse yra pamineta si stotele
+STR_SCHEDULED_SHIPS_TIP :{BLACK}Rodyti visus laivus, kuriu uzduotyse yra pamineta si stotele
+
+STR_VEH_WITH_SHARED_ORDERS_LIST :{WHITE}Nurodymais dalijasi {COMMA} tr. priemon{P ė ės ių}
+STR_VEH_WITH_SHARED_ORDERS_LIST_TIP :{BLACK}Parodyti visas tr. priemones, kurios dalijasi Å¡iais nurodymais
+
+### depot strings
+STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Ar tikrai norite parduoti visas tr. priemones esanÄias Å¡iame depe?
+
+STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP :{BLACK}Parduoti visus traukinius Å¡iame depe
+STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP :{BLACK}Parduoti visus automobilius Å¡iame depe
+STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP :{BLACK}Parduoti visus laivus Å¡iame depe
+STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP :{BLACK}Parduoti visus lÄ—ktuvus Å¡iame angare
+
+STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP :{BLACK}Gauti sÄ…raÅ¡Ä… visų traukinių turiunÄių nurodymuose šį depÄ…
+STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP :{BLACK}Gauti sÄ…raÅ¡Ä… visų automobilių turiunÄių nurodymuose šį depÄ…
+STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP :{BLACK}Gauti sÄ…raÅ¡Ä… visų laivų turiunÄių nurodymuose šį depÄ…
+STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP :{BLACK}Gauti sÄ…raÅ¡Ä… visų lÄ—ktuvų turiunÄių nurodymuose šį angarÄ…
+
+STR_DEPOT_AUTOREPLACE_TRAIN_TIP :{BLACK}Pakeisti visus traukinius depe
+STR_DEPOT_AUTOREPLACE_ROADVEH_TIP :{BLACK}Pakeisti automobilius traukinius depe
+STR_DEPOT_AUTOREPLACE_SHIP_TIP :{BLACK}Pakeisti visus laivus depe
+STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP :{BLACK}Pakeisti visus lÄ—ktuvus angare
+
+STR_VEHICLE_LIST_TRAIN_DEPOT :{BLACK}{STRING} - {COMMA} traukin{P ys iai ių}
+STR_VEHICLE_LIST_ROADVEH_DEPOT :{BLACK}{STRING} - {COMMA} automobil{P is iai ių}
+STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} laiv{P as ai ų}
+STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} lėktuv{P as ai ų}
+
+STR_REPLACE_VEHICLES_WHITE :{WHITE}Keisti tr. priemones {STRING}
+STR_REPLACE_VEHICLES_START :{BLACK}Pradeti tr. priemonių keitimą
+STR_REPLACE_VEHICLES_STOP :{BLACK}Stabdyti tr. priemonių keitimą
+STR_NOT_REPLACING :{BLACK}Nekeiciama
+STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Nera pazymeta nei viena tr. priemone
+STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Pasirink tr. priemones tipa, kuriuo reikes keisti
+STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Pasirink tr. priemones tipa, kuria bus keiciamos pasirinktos tr. priemones
+STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Spustelk, jei nori sustabdyti siuo metu vykdoma keitimo procedura
+STR_REPLACE_HELP_START_BUTTON :{BLACK}Spustelk, jei nori pradeti pazymeto tipo tr. priemoniu keitimo procedura
+STR_REPLACE_HELP_RAILTYPE :{BLACK}Pasirink norimu keisti traukiniu begiu tipa
+STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Kaireje lango dalyje pazymeta tr. priemone bus pakeista tr. priemone, kuri yra pazymeta desineje lango puseje
+STR_REPLACE_HELP :{BLACK}Tai leidzia tau keisti viena tr. priemoniu tipa kitu, kai pirmojo tipo traukinys uzsuka i depa
+STR_REPLACE_REMOVE_WAGON :{BLACK}Vagono pasalinimas: {ORANGE}{SKIP}{STRING}
+STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Pakeitimo metu išlaikyti traukinio ilgį atjungiant vagonus (pradedant juo priekio), jeigu pakeitus garvežį traukinys pailgėtų.
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}Keicima: {ORANGE}{SKIP}{SKIP}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} EKSPERIMENTINÄ– GALIMYBÄ– {}PereidinÄ—ti tarp garvežių ir vagonų pakeitimo langų.{}Vagonai bus pakeiÄiami tik tada, jeigu naujasis vagonas galÄ—s gabenti tÄ… patį krovinio tipÄ… kaip ir senasis. Tai atliekama patikrinant kiekvienÄ… vagonÄ… jo keitimo metu.
+STR_ENGINE_NOT_BUILDABLE :{WHITE}Variklio neimanoma pagaminti
+
+STR_ENGINES :Varikliai
+STR_WAGONS :Vagonai
+
+STR_MASS_STOP_DEPOT_TRAIN_TIP :{BLACK}SpragtelÄ—kite norÄ—dami sustabdyti visus traukinius esanÄius depe
+STR_MASS_STOP_DEPOT_ROADVEH_TIP :{BLACK}SpragtelÄ—kite norÄ—dami sustabdyti visus automobilius esanÄius depe
+STR_MASS_STOP_DEPOT_SHIP_TIP :{BLACK}SpragtelÄ—kite norÄ—dami sustabdyti visus laivus esanÄius depe
+STR_MASS_STOP_HANGAR_TIP :{BLACK}SpragtelÄ—kite norÄ—dami sustabdyti visus lÄ—ktuvus esanÄius angare
+
+STR_MASS_START_DEPOT_TRAIN_TIP :{BLACK}SpragtelÄ—kite norÄ—dami paleisti visus traukinius esanÄius depe
+STR_MASS_START_DEPOT_ROADVEH_TIP :{BLACK}SpragtelÄ—kite norÄ—dami paleisti visus automobilius esanÄius depe
+STR_MASS_START_DEPOT_SHIP_TIP :{BLACK}SpragtelÄ—kite norÄ—dami paleisti visus laivus esanÄius depe
+STR_MASS_START_HANGAR_TIP :{BLACK}SpragtelÄ—kite norÄ—dami paleisti visus lÄ—ktuvus esanÄius angare
+
+STR_MASS_STOP_LIST_TIP :{BLACK}Paspauskite noredami sustabdyti automobilius is saraso
+STR_MASS_START_LIST_TIP :{BLACK}Paspauskite noredami paleisti automobilius is saraso
+
+STR_SHORT_DATE :{WHITE}{DATE_TINY}
+STR_SIGN_LIST_CAPTION :{WHITE}Zenklu sarasas - {COMMA} Zenklai
+
+STR_ORDER_REFIT_FAILED :{WHITE}Klaida pakeitimo metu {STRING} {COMMA}
+
+############ Lists rail types
+
+STR_RAIL_VEHICLES :Paprasti traukiniai
+STR_ELRAIL_VEHICLES :Elektrifikuoti Traukiniai
+STR_MONORAIL_VEHICLES :Vienbegiai traukiniai
+STR_MAGLEV_VEHICLES :Magnetiniai traukiniai
+
+############ End of list of rail types
+
+STR_TINY_BLACK :{BLACK}{TINYFONT}{COMMA}
+
+STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Kaina: {GOLD}{CURRENCY}{BLACK} Svoris: {GOLD}{WEIGHT_S}
+STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Greitis: {GOLD}{VELOCITY}{BLACK} Galia: {GOLD}{POWER}
+STR_PURCHASE_INFO_SPEED :{BLACK}Greitis: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Vaziavimo kaina: {GOLD}{CURRENCY}/m
+STR_PURCHASE_INFO_CAPACITY :{BLACK}Talpa: {GOLD}{CARGO} {STRING}
+STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Sukurtas: {GOLD}{NUM}{BLACK} Tarnavimo laikas: {GOLD}{COMMA} metu
+STR_PURCHASE_INFO_RELIABILITY :{BLACK}Maks. Patikimumas: {GOLD}{COMMA}%
+STR_PURCHASE_INFO_COST :{BLACK}Kaina: {GOLD}{CURRENCY}
+STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Svoris: {GOLD}{WEIGHT_S} ({WEIGHT_S})
+STR_PURCHASE_INFO_COST_SPEED :{BLACK}Kaina: {GOLD}{CURRENCY}{BLACK} Greitis: {GOLD}{VELOCITY}
+STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Talpa: {GOLD}{COMMA} keleiviu, {COMMA} pasto maisu
+STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Pajungta vagonu: {GOLD}+{POWER}{BLACK} Svoris: {GOLD}+{WEIGHT_S}
+STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}PakeiÄiami į: {GOLD}
+STR_PURCHASE_INFO_ALL_TYPES :Visus krovinių tipus
+STR_PURCHASE_INFO_ALL_BUT :Visus, išskyrus {GOLD}
+STR_PURCHASE_INFO_MAX_TE :{BLACK}Did. traukiamoji galia: {GOLD}{FORCE}
+
+########### String for New Landscape Generator
+
+STR_GENERATE :{WHITE}Generuoti
+STR_RANDOM :{BLACK}Bet kaip
+STR_RANDOM_HELP :{BLACK}Pakeisti i bet koki Pasaulio Generavima
+STR_WORLD_GENERATION_CAPTION :{WHITE}Pasaulio kūrimas
+STR_RANDOM_SEED :{BLACK}Bet koks:
+STR_RANDOM_SEED_HELP :{BLACK}Paspauskite noredami ivesti bet koki seed
+STR_LAND_GENERATOR :{BLACK}Pasaulio generatorius:
+STR_TREE_PLACER :{BLACK}Medžių algoritmas:
+STR_HEIGHTMAP_ROTATION :{BLACK}Zemelapio rotacija:
+STR_TERRAIN_TYPE :{BLACK}VietovÄ—s tipas:
+STR_QUANTITY_OF_SEA_LAKES :{BLACK}Juros lygis:
+STR_SMOOTHNESS :{BLACK}Jautrumas:
+STR_SNOW_LINE_HEIGHT :{BLACK}Sniego linijos aukstis:
+STR_DATE :{BLACK}Data:
+STR_NUMBER_OF_TOWNS :{BLACK}Miestu kiekis:
+STR_NUMBER_OF_INDUSTRIES :{BLACK}Industriju kiekis:
+STR_GENERATE_DATE :{BLACK}{DATE_LONG}
+STR_SNOW_LINE_UP :{BLACK}Pakeisti sniego linijos auksti vienu auksciau
+STR_SNOW_LINE_DOWN :{BLACK}Pakeisti sniego linija viena zemiau
+STR_SNOW_LINE_QUERY_CAPT :{WHITE}Pakeisti sniego linijos auksti
+STR_START_DATE_QUERY_CAPT :{WHITE}Keisti pradzios metus
+STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Skales ispejimas
+STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Perdaryti pagrindini zemelapi per daug nerekomenduojama. Testi generavima?
+STR_SNOW_LINE_HEIGHT_NUM :{NUM}
+STR_HEIGHTMAP_NAME :{BLACK}Zemelapio vardas:
+STR_HEIGHTMAP_SIZE :{BLACK}Dydis: {ORANGE}{NUM} x {NUM}
+STR_GENERATION_WORLD :{WHITE}Pasaulis generuojamas...
+STR_GENERATION_ABORT :{BLACK}Nutraukti
+STR_GENERATION_ABORT_CAPTION :{WHITE}Nutraukti pasaulio generavima
+STR_GENERATION_ABORT_MESSAGE :{YELLOW}Ar jus tikrai norite nutraukti generavima?
+STR_PROGRESS :{WHITE}{NUM}% pabaigta
+STR_GENERATION_PROGRESS :{BLACK}{NUM} / {NUM}
+STR_WORLD_GENERATION :{BLACK}Pasaulio generacija
+STR_TREE_GENERATION :{BLACK}Medziu generacija
+STR_UNMOVABLE_GENERATION :{BLACK}Nejudinama generacija
+STR_CLEARING_TILES :{BLACK}Daubų ir uolų generacija
+STR_SETTINGUP_GAME :{BLACK}Sukurti zaidima
+STR_PREPARING_TILELOOP :{BLACK}Paleidziamas tile-loop
+STR_PREPARING_GAME :{BLACK}Ruosiamas zaidimas
+STR_DIFFICULTY_TO_CUSTOM :{WHITE}Sis veiksmas pakeite sunkumo lygi i specialu
+STR_SE_FLAT_WORLD :{WHITE}Lygi zeme
+STR_SE_FLAT_WORLD_TIP :{BLACK}Generuoti lygia zeme
+STR_SE_RANDOM_LAND :{WHITE}Bet kokia zeme
+STR_SE_NEW_WORLD :{BLACK}Sukurti nauja scenariju
+STR_SE_CAPTION :{WHITE}Scenarijaus tipas
+STR_FLAT_WORLD_HEIGHT_DOWN :{BLACK}Pakeisk aukštį lygumos vienu zemyn
+STR_FLAT_WORLD_HEIGHT_UP :{BLACK}Pakelti lygios zemes lygi vienu lygiu
+STR_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Keisti lygumos auksti
+STR_FLAT_WORLD_HEIGHT :{BLACK}Lygumos aukstis:
+STR_FLAT_WORLD_HEIGHT_NUM :{NUM}
+
+STR_SMALLMAP_CENTER :{BLACK}Centruoti maza zemelapi i sita vieta
+
+########### String for new airports
+STR_SMALL_AIRPORT :{BLACK}Mazas
+STR_CITY_AIRPORT :{BLACK}Miestas
+STR_METRO_AIRPORT :{BLACK}Metropoliteno orouostas
+STR_INTERNATIONAL_AIRPORT :{BLACK}Internacionalinis orouostas
+STR_COMMUTER_AIRPORT :{BLACK}Rajonas
+STR_INTERCONTINENTAL_AIRPORT :{BLACK}Tarpkontinentinis
+STR_HELIPORT :{BLACK}Heliportas
+STR_HELIDEPOT :{BLACK}Helidepas
+STR_HELISTATION :{BLACK}Helistotis
+
+STR_SMALL_AIRPORTS :{BLACK}Mazi orouostai
+STR_LARGE_AIRPORTS :{BLACK}Dideli orouostai
+STR_HUB_AIRPORTS :{BLACK}Issisakojantys orouostai
+STR_HELIPORTS :{BLACK}Heliportai
+
+############ Tooltip measurment
+
+STR_MEASURE_LENGTH :{BLACK}Atstumas: {NUM}
+STR_MEASURE_AREA :{BLACK}Sritis: {NUM} x {NUM}
+STR_MEASURE_LENGTH_HEIGHTDIFF :{BLACK}Atstumas: {NUM}{}AukÅ¡Äių skirtumas: {NUM} m
+STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}Sritis: {NUM} x {NUM}{}AukÅ¡Äių skirtumas: {NUM} m
+
+########
diff --git a/src/lang/unfinished/serbian.txt b/src/lang/unfinished/serbian.txt
new file mode 100644
index 000000000..5bc98f923
--- /dev/null
+++ b/src/lang/unfinished/serbian.txt
@@ -0,0 +1,3 @@
+##name Serbian
+##ownname Srpski
+##isocode sr_YU.UTF-8
diff --git a/src/lang/unfinished/simplified_chinese.txt b/src/lang/unfinished/simplified_chinese.txt
new file mode 100644
index 000000000..b7e41a1b6
--- /dev/null
+++ b/src/lang/unfinished/simplified_chinese.txt
@@ -0,0 +1,1761 @@
+##name Chinese (Simplified)
+##ownname 简体中文
+##isocode zh_CN.UTF-8
+
+##id 0x0000
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}超过地图边缘
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}è·ç¦»åœ°å›¾è¾¹ç¼˜å¤ªè¿‘
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}现金ä¸è¶³ï¼šéœ€è¦{CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}需è¦ä¸€å—平地
+STR_0008_WAITING :{BLACK}正在等待:{WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (从
+STR_000B :{YELLOW}{STATION} 出å‘的途中)
+STR_000C_ACCEPTS :{BLACK}接å—: {WHITE}
+STR_000D_ACCEPTS :{BLACK}接å—: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :乘客
+STR_0010_COAL :ç…¤
+STR_0011_MAIL :邮件
+STR_0012_OIL :原油
+STR_0013_LIVESTOCK :家畜
+STR_0014_GOODS :货物
+STR_0015_GRAIN :è°·å­
+STR_0016_WOOD :木æ
+STR_0017_IRON_ORE :é“矿石
+STR_0018_STEEL :é’¢æ
+STR_0019_VALUABLES :ç å®
+STR_001A_COPPER_ORE :铜矿石
+STR_001B_MAIZE :玉米
+STR_001C_FRUIT :水果
+STR_001D_DIAMONDS :钻石
+STR_001E_FOOD :食å“
+STR_001F_PAPER :纸张
+STR_0020_GOLD :金æ¡
+STR_0021_WATER :æ·¡æ°´
+STR_0022_WHEAT :å°éº¦
+STR_0023_RUBBER :橡胶
+STR_0024_SUGAR :ç³–
+STR_0025_TOYS :玩具
+STR_0026_CANDY :糖果
+STR_0027_COLA :å¯ä¹
+STR_0028_COTTON_CANDY :棉花糖
+STR_0029_BUBBLES :泡泡
+STR_002A_TOFFEE :太妃糖
+STR_002B_BATTERIES :电池
+STR_002C_PLASTIC :å¡‘æ–™
+STR_002D_FIZZY_DRINKS :æ¿€å¼é¥®æ–™
+STR_002F_PASSENGER :乘客
+STR_0030_COAL :ç…¤
+STR_0031_MAIL :信件
+STR_0032_OIL :原油
+STR_0033_LIVESTOCK :家畜
+STR_0034_GOODS :货物
+STR_0035_GRAIN :è°·å­
+STR_0036_WOOD :木æ
+STR_0037_IRON_ORE :é“矿石
+STR_0038_STEEL :é’¢æ
+STR_0039_VALUABLES :ç å®
+STR_003A_COPPER_ORE :铜矿石
+STR_003B_MAIZE :玉米
+STR_003C_FRUIT :水果
+STR_003D_DIAMOND :钻石
+STR_003E_FOOD :食å“
+STR_003F_PAPER :纸张
+STR_0040_GOLD :金æ¡
+STR_0041_WATER :æ·¡æ°´
+STR_0042_WHEAT :å°éº¦
+STR_0043_RUBBER :橡胶
+STR_0044_SUGAR :ç³–
+STR_0045_TOY :玩具
+STR_0046_CANDY :糖果
+STR_0047_COLA :å¯ä¹
+STR_0048_COTTON_CANDY :棉花糖
+STR_0049_BUBBLE :泡泡
+STR_004A_TOFFEE :太妃糖
+STR_004B_BATTERY :电池
+STR_004C_PLASTIC :å¡‘æ–™
+STR_004D_FIZZY_DRINK :æ¿€å¼æ°´
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}地图:{STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}游æˆé€‰é¡¹
+STR_00B2_MESSAGE :{YELLOW}消æ¯
+STR_00B3_MESSAGE_FROM :{YELLOW}æ¥è‡ª{STRING}的消æ¯
+STR_00B4_CAN_T_DO_THIS :{WHITE}ä¸èƒ½è¿™æ ·åšâ€¦
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}ä¸èƒ½æ¸…除该区域…
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}原始版æƒäººï¼š{COPYRIGHT} 1995 Chris Sawyer, All rights reserved
+STR_00B7_VERSION :{BLACK}OpenTTD版本{REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 The OpenTTD team
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}退出
+STR_00C8_YES :{BLACK}是
+STR_00C9_NO :{BLACK}ä¸
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}你确定è¦æ”¾å¼ƒå½“å‰çš„游æˆå¹¶è¿”回{STRING}å—?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :什么都没有
+STR_00D1_DARK_BLUE :æ·±è“
+STR_00D2_PALE_GREEN :浅绿
+STR_00D3_PINK :粉红
+STR_00D4_YELLOW :黄
+STR_00D5_RED :红
+STR_00D6_LIGHT_BLUE :亮è“
+STR_00D7_GREEN :绿
+STR_00D8_DARK_GREEN :深绿
+STR_00D9_BLUE :è“
+STR_00DA_CREAM :奶白
+STR_00DB_MAUVE :紫红
+STR_00DC_PURPLE :ç´«
+STR_00DD_ORANGE :橙黄
+STR_00DE_BROWN :棕
+STR_00DF_GREY :ç°
+STR_00E0_WHITE :白
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}游æˆä¸­çš„车辆已ç»å¤ªå¤šäº†
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}ä½ç½®
+STR_00E5_CONTOURS :等高线
+STR_00E6_VEHICLES :车辆
+STR_00E7_INDUSTRIES :工业
+STR_00E8_ROUTES :路线
+STR_00E9_VEGETATION :æ¤è¢«
+STR_00EA_OWNERS :属主
+STR_00EB_ROADS :{BLACK}{TINYFONT}公路
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}é“è·¯
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}车站/机场/ç å¤´
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}建筑物/工业设施
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}车辆
+STR_00F0_100M :{BLACK}{TINYFONT}100ç±³
+STR_00F1_200M :{BLACK}{TINYFONT}200ç±³
+STR_00F2_300M :{BLACK}{TINYFONT}300ç±³
+STR_00F3_400M :{BLACK}{TINYFONT}400ç±³
+STR_00F4_500M :{BLACK}{TINYFONT}500ç±³
+STR_00F5_TRAINS :{BLACK}{TINYFONT}ç«è½¦
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}汽车
+STR_00F7_SHIPS :{BLACK}{TINYFONT}船åª
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}飞机
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}è¿è¾“路线
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}煤矿
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}å‘电厂
+STR_00FC_FOREST :{BLACK}{TINYFONT}林场
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}锯木厂
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}炼油厂
+STR_00FF_FARM :{BLACK}{TINYFONT}农场
+STR_0100_FACTORY :{BLACK}{TINYFONT}工厂
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}å°åˆ·åŽ‚
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}油井
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}é“矿
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}炼钢厂
+STR_0105_BANK :{BLACK}{TINYFONT}银行
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}造纸厂
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}金矿
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}食å“加工厂
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}钻石矿
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}铜矿
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}果园
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}橡胶园
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}水厂
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}æ°´å¡”
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}木æ厂
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}棉花糖果园
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}糖果厂
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}电池农场
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}å¯ä¹äº•
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}玩具船
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}玩具厂
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}塑料泉
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}æ¿€å¼æ°´åŽ‚
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}泡泡机
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}太妃糖矿场
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}蔗糖矿
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}ç«è½¦ç«™
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Lorry Loading Bay
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}公车站
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}机场/ç›´å‡é£žæœºåœæœºåª
+STR_011F_DOCK :{BLACK}{TINYFONT}ç å¤´
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}粗糙的土地
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}è‰åœ°
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}赤裸的土地
+STR_0123_FIELDS :{BLACK}{TINYFONT}田地
+STR_0124_TREES :{BLACK}{TINYFONT}æ ‘
+STR_0125_ROCKS :{BLACK}{TINYFONT}石头
+STR_0126_WATER :{BLACK}{TINYFONT}æ°´
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}无人拥有
+STR_0128_TOWNS :{BLACK}{TINYFONT}城镇
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}工业
+STR_012A_DESERT :{BLACK}{TINYFONT}沙漠
+STR_012B_SNOW :{BLACK}{TINYFONT}雪
+STR_012C_MESSAGE :{WHITE}消æ¯
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}å–消
+STR_012F_OK :{BLACK}确定
+STR_0130_RENAME :{BLACK}é‡å‘½å
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}å·²ç»å®šä¹‰äº†å¤ªå¤šåå­—
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}选定的åå­—å·²ç»è¢«ä½¿ç”¨äº†
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+
+STR_013B_OWNED_BY :{WHITE}...属于 {STRING}
+STR_013C_CARGO :{BLACK}货舱
+STR_013D_INFORMATION :{BLACK}ä¿¡æ¯
+STR_013E_CAPACITIES :{BLACK}容é‡
+STR_013E_TOTAL_CARGO :{BLACK}总货物
+STR_013F_CAPACITY :{BLACK}容é‡ï¼š{LTBLUE}{CARGO}
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}此列车的总容é‡ä¸ºï¼š
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_0140_NEW_GAME :{BLACK}新游æˆ
+STR_0141_LOAD_GAME :{BLACK}读å–游æˆ
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_0148_GAME_OPTIONS :{BLACK}游æˆé€‰é¡¹
+
+STR_0150_SOMEONE :æŸäºº{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :世界地图
+STR_0152_TOWN_DIRECTORY :城镇列表
+STR_0153_SUBSIDIES :特殊补助
+
+
+
+
+
+
+
+
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :利润曲线
+STR_0155_INCOME_GRAPH :收入曲线
+STR_0156_DELIVERED_CARGO_GRAPH :è¿è¾“æˆæžœæ›²çº¿
+STR_0157_PERFORMANCE_HISTORY_GRAPH :表现情况曲线
+STR_0158_COMPANY_VALUE_GRAPH :å…¬å¸ä»·å€¼æ›²çº¿
+STR_0159_CARGO_PAYMENT_RATES :货物标准率
+STR_015A_COMPANY_LEAGUE_TABLE :å…¬å¸è”盟表
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}关于OpenTTD
+STR_015C_SAVE_GAME :ä¿å­˜æ¸¸æˆ
+STR_015D_LOAD_GAME :读å–游æˆ
+STR_015E_QUIT_GAME :放弃游æˆ
+STR_015F_QUIT :退出
+STR_0160_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}你确定è¦é€€å‡ºå½“å‰æ¸¸æˆå—?
+STR_0161_QUIT_GAME :{WHITE}放弃游æˆ
+
+
+############ range for months starts
+STR_0162_JAN :一月
+STR_0163_FEB :二月
+STR_0164_MAR :三月
+STR_0165_APR :四月
+STR_0166_MAY :五月
+STR_0167_JUN :六月
+STR_0168_JUL :七月
+STR_0169_AUG :八月
+STR_016A_SEP :ä¹æœˆ
+STR_016B_OCT :å月
+STR_016C_NOV :å一月
+STR_016D_DEC :å二月
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}æš‚åœæ¸¸æˆ
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}ä¿å­˜æ¸¸æˆï¼Œæ”¾å¼ƒæ¸¸æˆï¼Œé€€å‡º
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}显示公å¸æ‹¥æœ‰çš„所有车站的列表
+STR_0174_DISPLAY_MAP :{BLACK}显示地图
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}显示地图,城镇列表
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}显示城镇列表
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}显示公å¸è´¢æ”¿ä¿¡æ¯
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}显示公å¸æ¦‚况
+STR_0179_DISPLAY_GRAPHS :{BLACK}显示图表
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}显示公å¸è”盟列表
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}显示公å¸æ‹¥æœ‰çš„ç«è½¦çš„列表
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}显示公å¸æ‹¥æœ‰çš„汽车的列表
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}显示公å¸æ‹¥æœ‰çš„船åªçš„列表
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}显示公å¸æ‹¥æœ‰çš„飞机的列表
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}放大
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}缩å°
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}建设é“è·¯
+STR_0182_BUILD_ROADS :{BLACK}建设公路
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}建设ç å¤´
+STR_0184_BUILD_AIRPORTS :{BLACK}建设机场
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}æ¤æ ‘ã€è®¾ç½®åœ°æ ‡ç­‰
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}土地信æ¯
+STR_0187_OPTIONS :{BLACK}选项
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}ä¸èƒ½æ›´æ”¹ç»´æŠ¤å‘¨æœŸ
+STR_018B_CLOSE_WINDOW :{BLACK}关闭窗å£
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}窗å£æ ‡é¢˜ - 拖拽此处以移动窗å£
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}清除当å‰åœŸåœ°ä¸Šçš„建筑物等
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}é™ä½Žåœ°è¡¨
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}æå‡åœ°è¡¨
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}æ»šåŠ¨æ¡ - 拖动滑å—å¯ä»¥æŸ¥çœ‹æ›´å¤šä¿¡æ¯
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}在地图上显示ç»çº¬çº¿
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}在地图上显示车辆
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}在地图上显示工业
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}在地图上显示è¿è¾“路线
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}在地图上显示æ¤è¢«
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}在地图上显示属主
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}在地图上显示/éšè—城镇åå­—
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}今年的利润:{CURRENCY} (去年的利润:{CURRENCY})
+
+############ range for service numbers starts
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :汽车
+STR_019D_AIRCRAFT :飞机
+STR_019E_SHIP :船åª
+STR_019F_TRAIN :ç«è½¦
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} å·²ç»è€åŒ–
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} å·²ç»è¶…期æœå½¹å¤šå¹´
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} å·²ç»è¶…期æœå½¹å¤šå¹´å¹¶ä¸”亟待更新
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}土地信æ¯
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}清除费用:{LTBLUE}N/A
+STR_01A5_COST_TO_CLEAR :{BLACK}清除费用: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :无效
+STR_01A7_OWNER :{BLACK}属主: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}当地政府: {LTBLUE}{STRING}
+STR_01A9_NONE :没有
+STR_01AA_NAME :{BLACK}åå­—
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1æ—¥
+STR_01AD_2ND :2æ—¥
+STR_01AE_3RD :3æ—¥
+STR_01AF_4TH :4æ—¥
+STR_01B0_5TH :5æ—¥
+STR_01B1_6TH :6æ—¥
+STR_01B2_7TH :7æ—¥
+STR_01B3_8TH :8æ—¥
+STR_01B4_9TH :9æ—¥
+STR_01B5_10TH :10æ—¥
+STR_01B6_11TH :11æ—¥
+STR_01B7_12TH :12æ—¥
+STR_01B8_13TH :13æ—¥
+STR_01B9_14TH :14æ—¥
+STR_01BA_15TH :15æ—¥
+STR_01BB_16TH :16æ—¥
+STR_01BC_17TH :17æ—¥
+STR_01BD_18TH :18æ—¥
+STR_01BE_19TH :19æ—¥
+STR_01BF_20TH :20æ—¥
+STR_01C0_21ST :21æ—¥
+STR_01C1_22ND :22æ—¥
+STR_01C2_23RD :23æ—¥
+STR_01C3_24TH :24æ—¥
+STR_01C4_25TH :25æ—¥
+STR_01C5_26TH :26æ—¥
+STR_01C6_27TH :27æ—¥
+STR_01C7_28TH :28æ—¥
+STR_01C8_29TH :29æ—¥
+STR_01C9_30TH :30æ—¥
+STR_01CA_31ST :31æ—¥
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}接å—: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}爵士ä¹å”±ç‰‡æœº
+STR_01D3_SOUND_MUSIC :音ä¹/音效
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}显示音ä¹/音效窗å£
+STR_01D5_ALL :{TINYFONT}全部
+STR_01D6_OLD_STYLE :{TINYFONT}旧风格
+STR_01D7_NEW_STYLE :{TINYFONT}新风格
+STR_01D8_EZY_STREET :{TINYFONT}Ezyè¡—
+STR_01D9_CUSTOM_1 :{TINYFONT}自定义1
+STR_01DA_CUSTOM_2 :{TINYFONT}自定义2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}音ä¹éŸ³é‡
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}音效银两
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}æœ€å° ' ' ' ' ' ' 最大
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}跳到上一首歌
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}跳到下一首歌
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}åœæ­¢æ’­æ”¾éŸ³ä¹
+STR_01E1_START_PLAYING_MUSIC :{BLACK}开始播放音ä¹
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}拖动滑å—æ¥è°ƒèŠ‚音效和音ä¹çš„音é‡
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}轨é“{SETX 88}标题
+STR_01E9_SHUFFLE :{TINYFONT}拖拽
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}程åº
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}选择音ä¹ç¨‹åº
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}音轨索引
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}ç¨‹åº - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}清除
+STR_01F1_SAVE :{TINYFONT}{BLACK}ä¿å­˜
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}当å‰éŸ³è½¨ç¨‹åº
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}选择 全部音轨 程åº
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}选择 è€å¼éŸ³ä¹ 程åº
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}选择 æ–°å¼éŸ³ä¹ 程åº
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}没有 自定义1(用户定义)程åº
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}没有 自定义2(用户定义)程åº
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}清除当å‰ç¨‹åº(仅适用于 自定义1 或 自定义2)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}ä¿å­˜éŸ³ä¹è®¾ç½®
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}点击音ä¹å¯ä»¥åŠ å…¥å½“å‰ç¨‹åº(自定义1 或 自定义2)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}切æ¢ç¨‹åºæ‹–拽 å¼€/å…³
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}显示选择音轨窗å£
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}点击æœåŠ¡å¯ä»¥å°†å·¥ä¸š/城市居中
+STR_01FE_DIFFICULTY :{BLACK}难度 ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :最新消æ¯/æ–°é—»
+STR_0201_MESSAGE_SETTINGS :消æ¯è®¾ç½®
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}显示最新消æ¯/æ–°é—» 显示消æ¯é€‰é¡¹
+STR_0204_MESSAGE_OPTIONS :{WHITE}消æ¯é€‰é¡¹
+STR_0205_MESSAGE_TYPES :{BLACK}消æ¯ç±»åž‹:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}玩家的首次通车庆典
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}对手的首次通车庆典
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}事故/ç¾éš¾
+STR_0209_COMPANY_INFORMATION :{YELLOW}å…¬å¸ä¿¡æ¯
+STR_020A_ECONOMY_CHANGES :{YELLOW}ç»æµŽæ–°é—»
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}玩家的车辆信æ¯/建议
+STR_020C_NEW_VEHICLES :{YELLOW}新建车辆
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}接å—货物ç§ç±»å˜æ›´
+STR_020E_SUBSIDIES :{YELLOW}特殊津贴
+STR_020F_GENERAL_INFORMATION :{YELLOW}一般信æ¯
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE}...è·ç¦»ä¸Šä¸€ç›®çš„地过远
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}达到{NUM}{}({STRING} 级别)的顶级公å¸
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :å°å•†äºº
+STR_0214_ENTREPRENEUR :ä¼ä¸šå®¶
+STR_0215_INDUSTRIALIST :实业家
+STR_0216_CAPITALIST :资本家
+STR_0217_MAGNATE :商业巨头
+STR_0218_MOGUL :财阀
+STR_0219_TYCOON_OF_THE_CENTURY :世纪大亨
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} 达到 '{STRING}' 状æ€!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} çš„ {COMPANY} 达到 '{STRING}' 状æ€!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}创建场景
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}场景编辑器
+STR_0223_LAND_GENERATION :{WHITE}生æˆåœ°å½¢
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}éšæœºåœ°å½¢
+STR_0227_RESET_LAND :{BLACK}é‡ç½®åœ°å½¢
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}增加å¯ä»¥ æå‡/é™ä½Ž 的区域
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}å‡å°‘å¯ä»¥ æå‡/é™ä½Ž 的区域
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}生æˆéšæœºåœ°å½¢
+STR_022B_RESET_LANDSCAPE :{BLACK}é‡ç½®æ™¯è§‚
+STR_022C_RESET_LANDSCAPE :{WHITE}é‡ç½®æ™¯è§‚
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}你确定è¦é‡ç½®æ™¯è§‚么?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}çœåŸŽæ™¯è§‚
+STR_022F_TOWN_GENERATION :{BLACK}生æˆåŸŽé•‡
+STR_0230_INDUSTRY_GENERATION :{BLACK}生æˆå·¥ä¸š
+STR_0231_ROAD_CONSTRUCTION :{BLACK}建设é“è·¯
+STR_0233_TOWN_GENERATION :{WHITE}生æˆåŸŽé•‡
+STR_0234_NEW_TOWN :{BLACK}新的城镇
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}建设新城镇
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}ä¸èƒ½åœ¨è¿™é‡Œå»ºç«‹åŸŽé•‡...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}...è·ç¦»åœ°å›¾è¾¹ç¼˜è¿‡è¿‘
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...è·ç¦»å¦ä¸€åŸŽé•‡è¿‡è¿‘
+STR_0239_SITE_UNSUITABLE :{WHITE}...ä¸é€‚当的ä½ç½®
+STR_023A_TOO_MANY_TOWNS :{WHITE}...城镇过多
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}扩大城镇规模
+STR_023C_EXPAND :{BLACK}拓展
+STR_023D_RANDOM_TOWN :{BLACK}éšæœºåŸŽé•‡
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}建立一个éšæœºåŸŽé•‡
+STR_023F_INDUSTRY_GENERATION :{WHITE}生æˆå·¥ä¸š
+STR_0240_COAL_MINE :{BLACK}煤矿
+STR_0241_POWER_STATION :{BLACK}å‘电厂
+STR_0242_SAWMILL :{BLACK}木æ厂
+STR_0243_FOREST :{BLACK}林场
+STR_0244_OIL_REFINERY :{BLACK}炼油厂
+STR_0245_OIL_RIG :{BLACK}钻井平å°
+STR_0246_FACTORY :{BLACK}工厂
+STR_0247_STEEL_MILL :{BLACK}炼钢厂
+STR_0248_FARM :{BLACK}农场
+STR_0249_IRON_ORE_MINE :{BLACK}é“矿
+STR_024A_OIL_WELLS :{BLACK}油井
+STR_024B_BANK :{BLACK}银行
+STR_024C_PAPER_MILL :{BLACK}造纸厂
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}食å“加工厂
+STR_024E_PRINTING_WORKS :{BLACK}å°åˆ·åŽ‚
+STR_024F_GOLD_MINE :{BLACK}金矿
+STR_0250_LUMBER_MILL :{BLACK}木æ厂
+STR_0251_FRUIT_PLANTATION :{BLACK}果园
+STR_0252_RUBBER_PLANTATION :{BLACK}橡胶园
+STR_0253_WATER_SUPPLY :{BLACK}水厂
+STR_0254_WATER_TOWER :{BLACK}æ°´å¡”
+STR_0255_DIAMOND_MINE :{BLACK}钻石矿
+STR_0256_COPPER_ORE_MINE :{BLACK}铜矿
+STR_0257_COTTON_CANDY_FOREST :{BLACK}棉花糖森林
+STR_0258_CANDY_FACTORY :{BLACK}糖果厂
+STR_0259_BATTERY_FARM :{BLACK}电池农场
+STR_025A_COLA_WELLS :{BLACK}å¯ä¹äº•
+STR_025B_TOY_SHOP :{BLACK}玩具商店
+STR_025C_TOY_FACTORY :{BLACK}玩具工厂
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}塑料喷泉
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}泡泡饮料厂
+STR_025F_BUBBLE_GENERATOR :{BLACK}泡泡å‘生器
+STR_0260_TOFFEE_QUARRY :{BLACK}太妃糖厂
+STR_0261_SUGAR_MINE :{BLACK}蔗糖矿
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}创建煤矿
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}创建å‘电厂
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}创建木æ厂
+STR_0265_PLANT_FOREST :{BLACK}创建林场
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}创建炼油厂
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}创建钻井平å°(åªèƒ½åœ¨åœ°å›¾è¾¹ç¼˜åˆ›å»º)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}创建工厂
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}创建炼钢厂
+STR_026A_CONSTRUCT_FARM :{BLACK}创建农场
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}创建é“矿
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}创建油井
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}创建银行(åªèƒ½åœ¨äººå£è¶…过1200人的城镇中创建)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}创建造纸厂
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}创建食å“加工厂
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}创建å°åˆ·åŽ‚
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}创建金矿
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}创建银行(åªèƒ½åœ¨åŸŽé•‡ä¸­åˆ›å»º)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}创建木æ厂(å¯ä»¥é‡‡ä¼é›¨æž—中的树木并生产木æ)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}创建果园
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}创建橡胶园
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}创建水厂
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}创建水塔(åªèƒ½åœ¨åŸŽå¸‚中创建)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}创建钻石矿
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}创建铜矿
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}创建棉花糖森林
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}创建糖果厂
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}创建电池农场
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}创建å¯ä¹äº•
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}创建玩具商店
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}创建玩具工厂
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}创建塑料喷泉
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}创建泡泡水工厂
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}创建泡泡å‘生器
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}创建太妃糖厂
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}创建蔗糖矿
+STR_0285_CAN_T_BUILD_HERE :{WHITE}ä¸èƒ½åœ¨è¿™é‡Œåˆ›å»º {STRING} ...
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...必须建创建一个城镇
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...æ¯ä¸ªåŸŽé•‡åªèƒ½å»ºè®¾ä¸€ä¸ª
+STR_0288_PLANT_TREES :{BLACK}æ¤æ ‘
+STR_0289_PLACE_SIGN :{BLACK}设置地标
+STR_028A_RANDOM_TREES :{BLACK}éšæœºæŒ‡æ•°
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}在场景上éšæœºæ¤æ ‘
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}在场景éšæœºåˆ›å»ºçŸ³åœ°
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}设置ç¯å¡”
+STR_028E_PLACE_TRANSMITTER :{BLACK}创建转播塔
+STR_028F_DEFINE_DESERT_AREA :{BLACK}设置沙漠区域.{}æ‘ä½CTRLä¸æ”¾å¯ä»¥æ¸…除
+STR_0290_DELETE :{BLACK}删除
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}删除整个城镇
+STR_0292_SAVE_SCENARIO :ä¿å­˜åœºæ™¯
+STR_0293_LOAD_SCENARIO :读å–场景
+STR_0294_QUIT_EDITOR :退出编辑器
+STR_0295 :
+STR_0296_QUIT :退出
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}ä¿å­˜åœºæ™¯ 读å–场景 放弃编辑退出
+STR_0298_LOAD_SCENARIO :{WHITE}读å–场景
+STR_0299_SAVE_SCENARIO :{WHITE}ä¿å­˜åœºæ™¯
+STR_029A_PLAY_SCENARIO :{BLACK}从场景开始游æˆ
+STR_029B_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}真的è¦é€€å‡ºåœºæ™¯?
+STR_029C_QUIT_EDITOR :{WHITE}退出编辑器
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}... åªèƒ½åœ¨äººå£è¶…过 1200 的城镇创建
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}将开始年份æå‰1å¹´
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}将开始年份推åŽ1å¹´
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...桥的两端必须都在陆地上
+STR_02A1_SMALL :{BLACK}å°
+STR_02A2_MEDIUM :{BLACK}中
+STR_02A3_LARGE :{BLACK}大
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}选择城镇规模
+STR_02A5_TOWN_SIZE :{YELLOW}城镇规模:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}显示最åŽä¸€æ¬¡æ¶ˆæ¯æˆ–æ–°é—»
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :城市索引
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}车辆å称
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :默认
+STR_02BF_CUSTOM :自定义
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}ä¿å­˜è‡ªå®šä¹‰å称
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}选择车辆å称
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}ä¿å­˜è‡ªå®šä¹‰è½¦è¾†å称
+
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :游æˆé€‰é¡¹
+STR_02C5_DIFFICULTY_SETTINGS :难度设定
+STR_02C7_CONFIG_PATCHES :é…ç½®patch
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}显示城镇å称
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}显示车站å称
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}显示标牌
+STR_02D0_FULL_ANIMATION :{SETX 12}完整动画
+STR_02D2_FULL_DETAIL :{SETX 12}完整细节
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}建筑物é€æ˜Ž
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :显示地å—ä¿¡æ¯
+STR_02D6 :
+STR_02D7_SCREENSHOT_CTRL_S :å±å¹•æˆªå›¾ (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :大型å±å¹•æˆªå›¾ (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :关于 'OpenTTD'
+############ range ends here
+
+STR_02DB_OFF :{BLACK}关闭
+STR_02DA_ON :{BLACK}å¼€å¯
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}显示特殊津贴
+STR_02DD_SUBSIDIES :津贴
+STR_02DE_MAP_OF_WORLD :世界地图
+STR_02DF_TOWN_DIRECTORY :城镇索引
+
+STR_02E0_CURRENCY_UNITS :{BLACK}æµé€šå•ä½
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}选择æµé€šå•ä½
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_02E6_ROAD_VEHICLES :{BLACK}汽车
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}选择汽车行驶方å‘
+STR_02E9_DRIVE_ON_LEFT :左侧
+STR_02EA_DRIVE_ON_RIGHT :å³ä¾§
+STR_02EB_TOWN_NAMES :{BLACK}城镇å称
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}选择城镇å称风格
+
+STR_02F4_AUTOSAVE :{BLACK}自动ä¿å­˜
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}选择自动ä¿å­˜é—´éš”
+STR_02F7_OFF :关闭
+STR_02F8_EVERY_3_MONTHS :æ¯ 3 个月
+STR_02F9_EVERY_6_MONTHS :æ¯ 6 个月
+STR_02FA_EVERY_12_MONTHS :æ¯ 12 个月
+STR_02FB_START_A_NEW_GAME :{BLACK}开始新游æˆ
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}读å–存档游æˆ
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}创建一个自定义的游æˆä¸–ç•Œ/场景
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}选择å•çŽ©å®¶æ¸¸æˆ
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}é€‰æ‹©å¤šçŽ©å®¶æ¸¸æˆ (2-8玩家)
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}显示游æˆé€‰é¡¹
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}选择难度选项
+STR_0303_START_A_NEW_GAME_USING :{BLACK}开始新游æˆï¼Œä½¿ç”¨è‡ªå®šä¹‰åœºæ™¯
+STR_0304_QUIT :{BLACK}退出
+STR_0305_QUIT_OPENTTD :{BLACK}退出 'OpenTTD'
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...åªèƒ½åœ¨åŸŽé•‡é‡Œå»ºè®¾
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}选择 温润 气候
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}选择 寒带 气候
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}选择 亚热带 气候
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}选择 çŽ©å¶ åœºæ™¯
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}创建新的工业设施
+
+############ range for menu starts
+STR_0313_FUND_NEW_INDUSTRY :创建新工业
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}创建新工业
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...åªèƒ½åœ¨åŸŽé•‡ä¸­å»ºè®¾
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}...åªèƒ½åœ¨é›¨æž—中建设
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}...åªèƒ½åœ¨æ²™æ¼ ä¸­å»ºè®¾
+STR_0319_PAUSED :{YELLOW}* * æš‚åœä¸­ * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}å±å¹•æˆªå›¾è¢«æˆåŠŸä¿å­˜ä¸º '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}å±å¹•æˆªå›¾å¤±è´¥!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}为将æ¥å»ºè®¾è´­ä¹°åœŸåœ°
+STR_032F_AUTOSAVE :{RED}自动ä¿å­˜
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}选择 '街舞风格音ä¹' 程åº
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+############ end of townname region
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+# end of order system
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+############ network gui strings
+
+
+
+
+
+
+
+
+
+
+
+############ Leave those lines in this order!!
+############ End of leave-in-this-order
+
+
+
+
+
+
+
+############ Leave those lines in this order!!
+
+############ End of leave-in-this-order
+
+
+
+
+############ Leave those lines in this order!!
+############ End of leave-in-this-order
+
+
+
+
+
+############ end network gui strings
+
+
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}费用: {CURRENCY}
+STR_0801_COST :{RED}费用: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}收入: {CURRENCY}
+STR_0803_INCOME :{GREEN}收入: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}预期费用: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}预期收入: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}ä¸èƒ½æå‡åœ°è¡¨...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}ä¸èƒ½é™ä½Žåœ°è¡¨...
+STR_080A_ROCKS :岩石地é¢
+STR_080B_ROUGH_LAND :粗糙地é¢
+STR_080C_BARE_LAND :秃地
+STR_080D_GRASS :è‰åœ°
+STR_080E_FIELDS :田地
+STR_080F_SNOW_COVERED_LAND :积雪地é¢
+STR_0810_DESERT :沙漠
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}错误的斜é¢æ–¹å‘
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}错误的路轨组åˆ
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}挖掘土地将会破å隧é“
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}å·²ç»é™åˆ°æµ·å¹³é¢äº†
+STR_1004_TOO_HIGH :{WHITE}地表太高
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}没有适åˆçš„é“轨
+STR_1007_ALREADY_BUILT :{WHITE}...å·²ç»å»ºé€ äº†
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}必须先清除é“轨
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}é“路建设
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}å•è½¨é“路建设
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}ç£æ‚¬æµ®é“路建设
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}选择é“路桥
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}ä¸èƒ½åœ¨è¿™é‡Œå»ºè®¾ç«è½¦è½¦åº“...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}ä¸èƒ½åœ¨è¿™é‡Œå»ºè®¾ç«è½¦ç«™...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}ä¸èƒ½åœ¨è¿™é‡Œè®¾ç«‹ä¿¡å·ç¯...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}ä¸èƒ½åœ¨è¿™é‡Œå»ºè®¾é“è·¯...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}ä¸èƒ½æ¸…除这里的é“轨...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}ä¸èƒ½æ¸…除这里的信å·ç¯...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}ç«è½¦è½¦åº“çš„æ–¹å‘
+STR_1015_RAILROAD_CONSTRUCTION :é“路建设
+STR_1016_MONORAIL_CONSTRUCTION :å•è½¨é“路建设
+STR_1017_MAGLEV_CONSTRUCTION :ç£æ‚¬æµ®é“路建设
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}建设é“轨
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}建设ç«è½¦è½¦åº“ (用以购买或维护ç«è½¦)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}建设ç«è½¦ç«™
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}建设é“路信å·
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}建设é“路桥
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}建设ç«è½¦éš§é“
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}åˆ‡æ¢ å»ºè®¾/清除 é“轨和信å·
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}é€‰æ‹©æ¡¥æ¢ - 在需è¦çš„æ¡¥æ¢ä¸Šå•å‡»å³å¯
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}选择ç«è½¦è½¦åº“æ–¹å‘
+STR_1021_RAILROAD_TRACK :é“轨
+STR_1023_RAILROAD_TRAIN_DEPOT :ç«è½¦è½¦åº“
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE}...这个地å—ç”±å¦ä¸€å…¬å¸æ‹¥æœ‰
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}必须先清除公路
+STR_1802_ROAD_CONSTRUCTION :{WHITE}公路建设
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}选择公路桥
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}ä¸èƒ½åœ¨è¿™é‡Œå»ºè®¾å…¬è·¯...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}ä¸èƒ½æ¸…除这里的公路...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}汽车车库的方å‘
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}ä¸èƒ½åœ¨è¿™é‡Œå»ºè®¾æ±½è½¦è½¦åº“...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}ä¸èƒ½å»ºè®¾å…¬è½¦ç«™...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}ä¸èƒ½å»ºè®¾è´§è½¦åœº...
+STR_180A_ROAD_CONSTRUCTION :公路建设
+STR_180B_BUILD_ROAD_SECTION :{BLACK}公路建设区
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}建设汽车车库 (用以购买和维护车辆)
+STR_180D_BUILD_BUS_STATION :{BLACK}建设公共汽车站
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}建设货车场
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}建设公路桥æ¢
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}建设公路隧é“
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}åˆ‡æ¢ å»ºè®¾/清除 公路设施
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}选择汽车车库方å‘
+STR_1814_ROAD :公路
+STR_1815_ROAD_WITH_STREETLIGHTS :带路ç¯çš„公路
+STR_1816_TREE_LINED_ROAD :æž—è«å…¬è·¯
+STR_1817_ROAD_VEHICLE_DEPOT :汽车车库
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :公路/é“路平交路å£
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}城镇
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}必须先拆除原有建筑
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}人å£: {ORANGE}{COMMA}{BLACK} 房屋: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :é‡å‘½å城镇
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}ä¸èƒ½é‡å‘½å城镇...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} 市政府ä¸å…许这样åš
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}城镇å称 - 点击å称å¯ä»¥å°†è§†ç‚¹å±…中
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}将视点中心移至城镇所在地
+STR_200C_CHANGE_TOWN_NAME :{BLACK}修改城镇å称
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}上个月的乘客: {ORANGE}{COMMA}{BLACK} 最多: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}上个月的邮件: {ORANGE}{COMMA}{BLACK} 最多: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :高档办公区
+STR_2010_OFFICE_BLOCK :办公区
+STR_2011_SMALL_BLOCK_OF_FLATS :低档办公区
+STR_2012_CHURCH :教堂
+STR_2013_LARGE_OFFICE_BLOCK :大型办公区
+STR_2014_TOWN_HOUSES :镇屋
+STR_2015_HOTEL :宾馆
+STR_2016_STATUE :å¡‘åƒ
+STR_2017_FOUNTAIN :喷泉
+STR_2018_PARK :公园
+STR_2019_OFFICE_BLOCK :办公区
+STR_201A_SHOPS_AND_OFFICES :商店和咖啡屋
+STR_201B_MODERN_OFFICE_BUILDING :现代办公大楼
+STR_201C_WAREHOUSE :仓库
+STR_201D_OFFICE_BLOCK :办公区
+STR_201E_STADIUM :è¿åŠ¨åœº
+STR_201F_OLD_HOUSES :è€æˆ¿å­
+STR_2020_LOCAL_AUTHORITY :{BLACK}市政府
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}显示市政府信æ¯
+STR_2022_LOCAL_AUTHORITY :{WHITE}{TOWN} 市政府
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}è¿è¾“å…¬å¸å£°èª‰:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}津贴
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}å¯ç”¨çš„津贴项目:
+STR_2027_FROM_TO :{ORANGE}{STRING} 从 {STRING} 到 {STRING}
+STR_2028_BY :{YELLOW} (到 {DATE_SHORT} 为止)
+STR_202A_NONE :{ORANGE}没有
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}å·²ç»å®žçŽ°çš„项目:
+STR_202C_FROM_TO :{ORANGE}{STRING} 从 {STATION} 到 {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, 到 {DATE_SHORT} 为止)
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}津贴项目到期:{}{}{STRING} 从 {STRING} 到 {STRING} 的津贴项目已ç»åˆ°æœŸ.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}津贴项目作废:{}{}è¿è¾“ {STRING} æœåŠ¡ (从 {STATION} 到 {STATION}) å·²ç»ä½œåºŸ.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}新的津贴项目:{}{}第一æä¾› {STRING} è¿è¾“æœåŠ¡ (从 {STRING} 到 {STRING}) 将获得由市政府奖励的一年的专è¥æƒ!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}奖励给 {COMPANY} 的特殊津贴!{}{}è¿è¾“ {STRING} (从 {STATION} 到 {STATION}) 明年将获得é¢å¤–çš„50%的收入!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}奖励给 {COMPANY} 的特殊津贴!{}{}è¿è¾“ {STRING} (从 {STATION} 到 {STATION}) 明年将得到åŒå€æ”¶å…¥!
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}奖励给 {COMPANY} 的特殊津贴!{}{}è¿è¾“ {STRING} (从 {STATION} 到 {STATION}) 明年将得到三å€æ”¶å…¥!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}奖励给 {COMPANY} 的特殊津贴!{}{}è¿è¾“ {STRING} (从 {STATION} 到 {STATION}) 明年将得到四å€æ”¶å…¥!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} 市政府ä¸å…许在城镇内å†å»ºç«‹å¦ä¸€ä¸ªæœºåœº
+STR_2036_COTTAGES :æ‘èˆ
+STR_2037_HOUSES :别墅
+STR_2038_FLATS :平房
+STR_2039_TALL_OFFICE_BLOCK :高档办公区
+STR_203A_SHOPS_AND_OFFICES :商店和办公室
+STR_203B_SHOPS_AND_OFFICES :商店和办公室
+STR_203C_THEATER :剧场
+STR_203D_STADIUM :体育场
+STR_203E_OFFICES :办公室
+STR_203F_HOUSES :别墅
+STR_2040_CINEMA :电影院
+STR_2041_SHOPPING_MALL :购物商场
+STR_2042_DO_IT :{BLACK}执行
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}å¯ä»¥åœ¨å½“å‰åŸŽé•‡è¿›è¡Œçš„活动 - 点击项目以察看详细信æ¯
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}执行上é¢é«˜äº®çš„项目
+STR_2045_ACTIONS_AVAILABLE :{BLACK}å¯æ‰§è¡Œçš„æ“作:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :å°åž‹å¹¿å‘ŠæŠ•æ”¾
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :中等广告投放
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :大型广告投放
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :进行é“路翻修
+STR_204A_BUILD_STATUE_OF_COMPANY :为公å¸æ‰€æœ‰äººå»ºè®¾å¡‘åƒ
+STR_204B_FUND_NEW_BUILDINGS :建设新房屋
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :购买专è¥æƒ
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} 进行一个å°åž‹çš„广告投放, 从而为你的公å¸å¸å¼•æ›´å¤šçš„乘客和货物.{} 费用: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} 进行一个中等的广告投放, 从而为你的公å¸å¸å¼•æ›´å¤šçš„乘客和货物.{} 费用: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} 进行一个大型的广告投放, 从而为你的公å¸å¸å¼•æ›´å¤šçš„乘客和货物.{} 费用: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} 翻修市内的é“路网. 未æ¥6个月内市内公路交通将å—到一定影å“.{} 费用: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} 将为你的公å¸å»ºè®¾ä¸€å°Šé›„伟的塑åƒ.{} 费用: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} 在城镇中建设新的商业设施.{} 费用: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} å‘市政府购买一年的专è¥æƒ. 所有乘客和货物åªèƒ½é€‰æ‹©ä½ çš„å…¬å¸æ供的æœåŠ¡.{} 费用: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}{TOWN} 的交通陷入混乱!{}{}ç”± {COMPANY} 赞助的é“路翻修工程导致市内公路交通6个月的瘫痪!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (建设中)
+STR_2059_IGLOO :圆顶建筑
+STR_205A_TEPEES :锥顶建筑
+STR_205B_TEAPOT_HOUSE :茶壶å°å±‹
+STR_205C_PIGGY_BANK :扑满银行
+
+
+##id 0x2800
+STR_2800_PLANT_TREES :æ¤æ ‘
+STR_2801_PLACE_SIGN :放置标签
+STR_2802_TREES :{WHITE}树木
+STR_2803_TREE_ALREADY_HERE :{WHITE}...此处已有树木
+STR_2804_SITE_UNSUITABLE :{WHITE}...地点ä¸åˆé€‚
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}ä¸èƒ½åœ¨è¿™é‡Œæ¤æ ‘...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE}...标签过多
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}ä¸èƒ½åœ¨è¿™é‡Œæ”¾ç½®æ ‡ç­¾...
+STR_280A_SIGN :标签
+STR_280B_EDIT_SIGN_TEXT :{WHITE}编辑标签文本
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}ä¸èƒ½æ”¹å˜æ ‡ç­¾çš„åå­—...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}选择树木的类型
+STR_280E_TREES :树木
+STR_280F_RAINFOREST :雨林
+STR_2810_CACTUS_PLANTS :仙人掌
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}选择ç«è½¦ç«™
+STR_3001_AIRPORT_SELECTION :{WHITE}选择机场
+STR_3002_ORIENTATION :{BLACK}æ–¹å‘
+STR_3003_NUMBER_OF_TRACKS :{BLACK}月å°æ€»æ•°
+STR_3004_PLATFORM_LENGTH :{BLACK}月å°é•¿åº¦
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}è·ç¦»å¦ä¸€ç«è½¦ç«™è¿‡è¿‘
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}与两个或以上的车站/货场毗邻
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}城镇中的车站/货场过多
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}车站/货场过多
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}公车站过多
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}货车场过多
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}è·ç¦»å¦ä¸€è½¦ç«™/货场过近
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}必须先清除ç«è½¦ç«™
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}è·ç¦»å¦ä¸€é£žæœºåœºè¿‡è¿‘
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}必须先清除飞机场
+
+STR_3030_RENAME_STATION_LOADING :é‡å‘½å车站/货场区域
+STR_3031_CAN_T_RENAME_STATION :{WHITE}ä¸èƒ½é‡å‘½å车站...
+STR_3032_RATINGS :{BLACK}评价
+STR_3033_ACCEPTS :{BLACK}接收
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}è¿è¾“æœåŠ¡çš„地方评价:
+
+############ range for rating starts
+STR_3035_APPALLING :骇人å¬é—»
+STR_3036_VERY_POOR :éžå¸¸å·®
+STR_3037_POOR :å·®
+STR_3038_MEDIOCRE :一般
+STR_3039_GOOD :好
+STR_303A_VERY_GOOD :éžå¸¸å¥½
+STR_303B_EXCELLENT :优秀
+STR_303C_OUTSTANDING :完美
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} å°†ä¸å†æŽ¥å— {STRING}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} å°†ä¸å†æŽ¥å— {STRING} 或 {STRING}
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} å¼€å§‹æŽ¥å— {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} å¼€å§‹æŽ¥å— {STRING} å’Œ {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}公车站方å‘
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}货场方å‘
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}必须先清除公车站
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}å¿…é¡»å‰æ¸…除货场
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- 没有 -
+STR_304B_SITE_UNSUITABLE :{WHITE}...地点ä¸åˆé€‚
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}è·ç¦»å¦ä¸€ç å¤´è¿‡è¿‘
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}必须先清除ç å¤´
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}选择ç«è½¦ç«™æ–¹å‘
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}选择月å°çš„æ•°é‡
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}选择月å°çš„长度
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}选择公车站方å‘
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}选择货场方å‘
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}将视点中心移动到车站ä½ç½®
+STR_3054_SHOW_STATION_RATINGS :{BLACK}显示车展评价
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}更改车站å称
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}显示接å—的货物类型
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}车站å称 - 点击车站åå­—å¯ä»¥å°†è§†ç‚¹ç§»åŠ¨åˆ°è½¦ç«™ä½ç½®
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}选择机场的大å°/类型
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_305E_RAILROAD_STATION :ç«è½¦ç«™
+STR_305F_AIRCRAFT_HANGAR :飞机库
+STR_3060_AIRPORT :机场
+STR_3061_TRUCK_LOADING_AREA :货场
+STR_3062_BUS_STATION :公车站
+STR_3063_SHIP_DOCK :ç å¤´
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}高亮显示车站/机场/ç å¤´çš„覆盖范围
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}åœæ­¢é«˜äº®æ˜¾ç¤ºè½¦ç«™/机场/ç å¤´çš„覆盖范围
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}高亮覆盖范围
+STR_3068_DOCK :{WHITE}ç å¤´
+STR_3069_BUOY :浮标
+STR_306A_BUOY_IN_THE_WAY :{WHITE}...å·²ç»æœ‰æµ®æ ‡äº†
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE}...车站太大了
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE}...å·²ç»ç¦ç”¨éžçŸ©å½¢çš„车站
+
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}船åžçš„æ–¹å‘
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE}...必须在水上建设
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}ä¸èƒ½åœ¨è¿™é‡Œå»ºé€ èˆ¹åž...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}选择船åžæ–¹å‘
+STR_3804_WATER :æ°´
+STR_3805_COAST_OR_RIVERBANK :海岸或河堤
+STR_3806_SHIP_DEPOT :船åž
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...ä¸èƒ½åœ¨æ°´ä¸Šå»ºé€ 
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}ä¿å­˜æ¸¸æˆ
+STR_4001_LOAD_GAME :{WHITE}读å–存档
+STR_4002_SAVE :{BLACK}ä¿å­˜
+STR_4003_DELETE :{BLACK}删除
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}ä¸èƒ½è¯»å–ç£ç›˜
+STR_4007_GAME_SAVE_FAILED :{WHITE}游æˆä¿å­˜å¤±è´¥
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}ä¸èƒ½åˆ é™¤æ–‡ä»¶
+STR_4009_GAME_LOAD_FAILED :{WHITE}游æˆè¯»å–失败
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}车辆, 索引和存档的文件
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}当å‰é€‰æ‹©çš„存档的åå­—
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}删除当å‰é€‰æ‹©çš„存档
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}用当å‰æ¸¸æˆè¦†ç›–选定的存档
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}选择新游æˆç±»åž‹
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}选择场景(绿色), 预设游æˆ(è“色), 或éšæœºæ¸¸æˆ
+STR_4010_GENERATE_RANDOM_NEW_GAME :生æˆéšæœºæ¸¸æˆ
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} 挡路
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :煤矿
+STR_4803_POWER_STATION :å‘电厂
+STR_4804_SAWMILL :木æ场
+STR_4805_FOREST :森林
+STR_4806_OIL_REFINERY :炼油厂
+STR_4807_OIL_RIG :钻井平å°
+STR_4808_FACTORY :工厂
+STR_4809_PRINTING_WORKS :å°åˆ·åŽ‚
+STR_480A_STEEL_MILL :炼钢厂
+STR_480B_FARM :农场
+STR_480C_COPPER_ORE_MINE :铜矿
+STR_480D_OIL_WELLS :油井
+STR_480E_BANK :银行
+STR_480F_FOOD_PROCESSING_PLANT :食å“加工厂
+STR_4810_PAPER_MILL :造纸厂
+STR_4811_GOLD_MINE :金矿
+STR_4812_BANK :银行
+STR_4813_DIAMOND_MINE :钻石矿
+STR_4814_IRON_ORE_MINE :é“矿
+STR_4815_FRUIT_PLANTATION :果园
+STR_4816_RUBBER_PLANTATION :橡胶园
+STR_4817_WATER_SUPPLY :水厂
+STR_4818_WATER_TOWER :æ°´å¡”
+STR_4819_FACTORY :工厂
+STR_481A_FARM :农场
+STR_481B_LUMBER_MILL :木æ场
+STR_481C_COTTON_CANDY_FOREST :棉花糖森林
+STR_481D_CANDY_FACTORY :糖果厂
+STR_481E_BATTERY_FARM :电池农场
+STR_481F_COLA_WELLS :å¯ä¹äº•
+STR_4820_TOY_SHOP :玩具商店
+STR_4821_TOY_FACTORY :玩具工厂
+STR_4822_PLASTIC_FOUNTAINS :塑料喷泉
+STR_4823_FIZZY_DRINK_FACTORY :泡泡饮料工厂
+STR_4824_BUBBLE_GENERATOR :泡泡厂
+STR_4825_TOFFEE_QUARRY :太妃矿
+STR_4826_SUGAR_MINE :糖矿
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}需è¦: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}需è¦: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}需è¦: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}上月产é‡:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% 被è¿èµ°)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}将视点移动到工厂ä½ç½®
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}新的 {STRING} 在 {TOWN} 附近开始建设!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}新的 {STRING} 在 {TOWN} 附近开始生长!
+STR_482F_COST :{BLACK}费用: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}ä¸èƒ½åœ¨è¿™é‡Œå»ºè®¾æ­¤ç±»çš„工业设施...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...森林必须在雪线以上建设
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} å³å°†å®£å‘Šå…³å¼ !
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}由于供应ä¸è¶³, {INDUSTRY} å³å°†å®£å‘Šå…³å¼ !
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}由于附近缺少树木, {INDUSTRY} å³å°†å®£å‘Šå…³å¼ !
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} 增加产é‡!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}在 {INDUSTRY} å‘现新的煤矿!{}产é‡å³å°†åŠ å€!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}在 {INDUSTRY} å‘现新的石油!{}产é‡å³å°†åŠ å€!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}{INDUSTRY} 的生产方法改良, 产é‡å³å°†åŠ å€!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}{INDUSTRY} 产é‡å‡å°‘50%
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}虫害导致 {INDUSTRY} 歉收!{}产é‡é™ä½Ž50%
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE}...åªèƒ½åœ¨åœ°å›¾è¾¹ç¼˜è®¾ç½®
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}ç«è½¦æ­£åœ¨éš§é“中
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}汽车正在隧é“中
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}å’Œå¦ä¸€ä¸ªéš§é“交å‰
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}没有åˆé€‚çš„ä½ç½®å»ºé€ éš§é“出å£
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}必须先清除隧é“
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}必须先清除桥æ¢
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}起点和终点ä¸èƒ½é‡åˆ
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}桥下的地é¢æˆ–æ°´é¢å¿…须为平é¢
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}起始点和结æŸç‚¹å¿…须在一æ¡çº¿ä¸Š
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}该地点ä¸é€‚åˆä½œä¸ºéš§é“å…¥å£
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :斜拉钢索桥
+STR_500F_GIRDER_STEEL :钢架桥
+STR_5010_CANTILEVER_STEEL :钢制悬臂桥
+STR_5011_SUSPENSION_CONCRETE :æ··å‡åœŸé«˜æž¶æ¡¥
+STR_5012_WOODEN :木桥
+STR_5013_CONCRETE :æ··å‡åœŸæ¡¥
+STR_5014_TUBULAR_STEEL :钢制å°é—­æ¡¥
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}ä¸èƒ½åœ¨è¿™é‡Œå»ºé€ æ¡¥æ¢...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}ä¸èƒ½åœ¨è¿™é‡Œå»ºè®¾éš§é“...
+STR_5017_RAILROAD_TUNNEL :é“路隧é“
+STR_5018_ROAD_TUNNEL :公路隧é“
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :钢质斜拉é“路桥
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :钢架é“路桥
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :钢架悬臂é“路桥
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :æ··å‡åœŸæ–œæ‹‰é“路桥
+STR_501F_WOODEN_RAIL_BRIDGE :木质é“路桥
+STR_5020_CONCRETE_RAIL_BRIDGE :æ··å‡åœŸé“路桥
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :钢质斜拉公路桥
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :钢架公路桥
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :钢质悬臂公路桥
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :æ··å‡åœŸæ–œæ‹‰å…¬è·¯æ¡¥
+STR_5025_WOODEN_ROAD_BRIDGE :木质公路桥
+STR_5026_CONCRETE_ROAD_BRIDGE :æ··å‡åœŸå…¬è·¯æ¡¥
+STR_5027_TUBULAR_RAIL_BRIDGE :å°é—­é“路桥
+STR_5028_TUBULAR_ROAD_BRIDGE :å°é—­å…¬è·¯æ¡¥
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}目标处有障ç¢ç‰©
+STR_5801_TRANSMITTER :中继塔
+STR_5802_LIGHTHOUSE :ç¯å¡”
+STR_5803_COMPANY_HEADQUARTERS :å…¬å¸æ€»éƒ¨
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE}...目标处有公å¸æ€»éƒ¨
+STR_5805_COMPANY_OWNED_LAND :å…¬å¸æ‰€æ‹¥æœ‰çš„土地
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}ä¸èƒ½å¤Ÿä¹°è¿™ä¸ªåœ°å—...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE}...ä½ å·²ç»æ‹¥æœ‰è¿™ä¸ªåœ°å—了!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}难度级别
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}容易
+STR_6802_MEDIUM :{BLACK}中等
+STR_6803_HARD :{BLACK}å›°éš¾
+STR_6804_CUSTOM :{BLACK}自定义
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}最大竞争对手数é‡: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}竞争对手开业时间: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}城镇数é‡: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}工业数é‡: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}最大åˆå§‹è´·æ¬¾é¢: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}åˆå§‹è´·æ¬¾åˆ©çŽ‡: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}车辆è¿è¥æˆæœ¬: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}对手的建设速度: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}对手的智慧程度: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}车辆抛锚: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}津贴增益率: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}建设æˆæœ¬: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}地形类别 {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}水域比例: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}ç»æµŽ: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}ç«è½¦æŽ‰å¤´: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}ç¾å®³: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}市政委员会对地å—é‡æ–°è§„划的æ€åº¦: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :没有
+STR_6816_LOW :较低
+STR_6817_NORMAL :正常
+STR_6818_HIGH :较高
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :很慢
+STR_681C_SLOW :æ…¢
+STR_681D_MEDIUM :中等
+STR_681E_FAST :å¿«
+STR_681F_VERY_FAST :很快
+STR_6820_LOW :较低
+STR_6821_MEDIUM :中等
+STR_6822_HIGH :较高
+STR_6823_NONE :没有
+STR_6824_REDUCED :较少
+STR_6825_NORMAL :正常
+STR_6826_X1_5 :1.5 å€
+STR_6827_X2 :2 å€
+STR_6828_X3 :3 å€
+STR_6829_X4 :4 å€
+STR_682A_VERY_FLAT :éžå¸¸å¹³æ•´
+STR_682B_FLAT :平整
+STR_682C_HILLY :丘陵
+STR_682D_MOUNTAINOUS :山地
+STR_6831_3_MONTHS_AFTER_PLAYER :çŽ©å®¶å¼€å§‹åŽ 3 个月
+STR_6832_6_MONTHS_AFTER_PLAYER :çŽ©å®¶å¼€å§‹åŽ 6 个月
+STR_6833_9_MONTHS_AFTER_PLAYER :çŽ©å®¶å¼€å§‹åŽ 9 个月
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :在é“轨末端和车站
+STR_6835_AT_END_OF_LINE_ONLY :仅在é“轨末端
+STR_6836_OFF :关闭
+STR_6837_ON :å¼€å¯
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}显示高分图表
+STR_6839_PERMISSIVE :温和的
+STR_683A_TOLERANT :å¿è€çš„
+STR_683B_HOSTILE :敌对的
+
+##id 0x7000
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(玩家 {COMMA})
+STR_7004_NEW_FACE :{BLACK}新头åƒ
+STR_7005_COLOR_SCHEME :{BLACK}颜色
+STR_7006_COLOR_SCHEME :{GOLD}颜色:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}新颜色
+STR_7008_COMPANY_NAME :{BLACK}å…¬å¸å称
+STR_7009_PRESIDENT_NAME :{BLACK}ç»è¥è€…
+STR_700A_COMPANY_NAME :å…¬å¸å称
+STR_700B_PRESIDENT_S_NAME :ç»è¥è€…
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}ä¸èƒ½æ›´æ”¹å…¬å¸å称...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}ä¸èƒ½æ›´æ”¹ç»è¥è€…的姓å...
+STR_700E_FINANCES :{WHITE}{COMPANY} 财政 {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}支出/收入
+STR_7010 :{WHITE}{NUM}
+STR_7011_CONSTRUCTION :{GOLD}建设
+STR_7012_NEW_VEHICLES :{GOLD}新购车辆
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}é“è·¯è¿è¥æˆæœ¬
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}公路è¿è¥æˆæœ¬
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}航空è¿è¥æˆæœ¬
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}船åªè¿è¥æˆæœ¬
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}资产维护费用
+STR_7018_TRAIN_INCOME :{GOLD}é“è·¯è¿è¥æ”¶å…¥
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}公路è¿è¥æ”¶å…¥
+STR_701A_AIRCRAFT_INCOME :{GOLD}航空è¿è¥æ”¶å…¥
+STR_701B_SHIP_INCOME :{GOLD}船åªè¿è¥æ”¶å…¥
+STR_701C_LOAN_INTEREST :{GOLD}贷款利æ¯
+STR_701D_OTHER :{GOLD}其他
+STR_701E :{BLACK}-{CURRENCY64}
+STR_701F :{BLACK}+{CURRENCY64}
+STR_7020_TOTAL :{WHITE}总计:
+STR_7021 :{COMPANY}{PLAYERNAME}
+STR_7022_INCOME_GRAPH :{WHITE}收益图
+STR_7024 :{COMMA}
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}è¿è¥åˆ©æ¶¦å›¾
+STR_7026_BANK_BALANCE :{WHITE}银行账户
+STR_7027_LOAN :{WHITE}贷款
+STR_7028 :{BLACK}{CURRENCY64}
+STR_7029_BORROW :{BLACK}贷款 {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}å¿è¿˜ {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...贷款的最大许å¯é¢åº¦æ˜¯ {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}ä¸èƒ½å†è´·æ¬¾äº†...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...没有å¯ä»¥å¿è¿˜çš„贷款
+STR_702E_REQUIRED :{WHITE}...éœ€è¦ {CURRENCY}
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}ä¸èƒ½å¿è¿˜è´·æ¬¾...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}为ç»è¥è€…选择新头åƒ
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}更改公å¸æ‰€å±žçš„车辆和设施的颜色
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}更改ç»è¥è€…的姓å
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}更该公å¸å称
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}在喜欢的颜色上å•å‡»
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}增加贷款规模
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}å¿è¿˜éƒ¨åˆ†è´·æ¬¾
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(ç»è¥è€…)
+STR_7038_INAUGURATED :{GOLD}开张大å‰: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}车辆:
+STR_7042_NONE :{WHITE}没有
+STR_7043_FACE_SELECTION :{WHITE}选择头åƒ
+STR_7044_MALE :{BLACK}男性
+STR_7045_FEMALE :{BLACK}女性
+STR_7046_NEW_FACE :{BLACK}新头åƒ
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}å–消选择新头åƒ
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}确定选择新头åƒ
+STR_7049_SELECT_MALE_FACES :{BLACK}选择男性头åƒ
+STR_704A_SELECT_FEMALE_FACES :{BLACK}选择女性头åƒ
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}生æˆéšæœºçš„新头åƒ
+STR_704C_KEY :{BLACK}索引
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}显示图表索引
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}å…¬å¸ç´¢å¼•
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}å•å‡»æ­¤å¤„选择是å¦åœ¨å›¾è¡¨ä¸­æ˜¾ç¤ºè¯¥å…¬å¸
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}è¿è¾“的货物数é‡
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}å…¬å¸è¡¨çŽ°çŽ‡ (最大表现率为1000)
+STR_7052_COMPANY_VALUES :{WHITE}å…¬å¸ä»·å€¼
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}å…¬å¸è”盟表
+STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}'
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}è¿è¾“å…¬å¸é™·å…¥å›°å¢ƒ!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}{COMPANY} 如果ä¸èƒ½åœ¨è¿‘期æ高业绩将被出售或破产!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(ç»è¥è€…)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}è¿è¾“å…¬å¸åˆå¹¶!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} 被 {COMPANY} 以 {CURRENCY} 收购!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}我们正在寻找一个å¯ä»¥æŽ¥å—我公å¸çš„买家.{}{}ä½ æ„¿æ„收购 {COMPANY} 并支付 {CURRENCY} å—?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}破产!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :{BLACK}{BIGFONT}{COMPANY} 被债æƒäººå¼ºè¡Œå…³é—­å¹¶å‡ºå”®å…¨éƒ¨èµ„产!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}æ–°å…¬å¸å¼€å¼ å¤§å‰!
+STR_705F_STARTS_CONSTRUCTION_NEAR :{BLACK}{BIGFONT}{COMPANY} 开始在 {TOWN} 附近大兴土木!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}ä¸èƒ½è´­ä¹°å…¬å¸...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}货物è¿ä»·è¡¨
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}è¿è¾“时间
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}å°† 10 å•ä½ (或 10,000 å‡) 货物è¿è¾“ 20 方格的价格
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}切æ¢æ˜¯å¦æ˜¾ç¤ºè¯¥è´§ç‰©ç±»åž‹
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :技师
+STR_7067_TRAFFIC_MANAGER :è¿è¾“管ç†å‘˜
+STR_7068_TRANSPORT_COORDINATOR :è¿è¾“调度员
+STR_7069_ROUTE_SUPERVISOR :路线负责人
+STR_706A_DIRECTOR :主管
+STR_706B_CHIEF_EXECUTIVE :首席执行官
+STR_706C_CHAIRMAN :主席
+STR_706D_PRESIDENT :总统
+STR_706E_TYCOON :大亨
+STR_706F_BUILD_HQ :{BLACK}建设公å¸æ€»éƒ¨
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}建设/查看公å¸æ€»éƒ¨
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}ä¸èƒ½å»ºè®¾å…¬å¸æ€»éƒ¨...
+STR_7072_VIEW_HQ :{BLACK}查看公å¸æ€»éƒ¨
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}世界ç»æµŽç–²è½¯!{}{}ç»æµŽä¸“家预测大衰退!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}ç»æµŽå¤è‹!{}{}ä¼ä¸šå®¶æ¢å¤å¯¹å·¥ä¸šæŠ•èµ„的信心!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}切æ¢çª—å£å¤§å°
+STR_7076_COMPANY_VALUE :{GOLD}å…¬å¸ä»·å€¼: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}è´­ä¹°è¯¥å…¬å¸ 25% çš„è‚¡æƒ
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}å‡ºå”®è¯¥å…¬å¸ 25% çš„è‚¡æƒ
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}è´­ä¹°è¯¥å…¬å¸ 25% çš„è‚¡æƒ
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}å‡ºå”®è¯¥å…¬å¸ 25% çš„è‚¡æƒ
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}ä¸èƒ½è´­ä¹°è¯¥å…¬å¸çš„è‚¡æƒ...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}ä¸èƒ½å‡ºå”®è¯¥å…¬å¸çš„è‚¡æƒ...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% çš„è‚¡æƒå±žäºŽ {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% çš„è‚¡æƒå±žäºŽ {COMPANY}{} {COMMA}% çš„è‚¡æƒå±žäºŽ {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :{BLACK}{BIGFONT}{COMPANY} 被 {COMPANY} 整体收购!
+STR_7080_PROTECTED :{WHITE}该公å¸è‰åˆ›ä¹‹åˆ, å°šä¸èƒ½å‡ºå”®è‚¡æƒ...
+
+##id 0x8000
+STR_8000_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (蒸汽机)
+STR_8001_MJS_250_DIESEL :MJS 250 (柴油机)
+STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
+STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
+STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
+STR_8005_PLODDYPHUT_DIESEL :Ploddyphut 柴油型
+STR_8006_POWERNAUT_DIESEL :Powernaut 柴油型
+STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (蒸汽机)
+STR_8008_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (蒸汽机)
+STR_8009_GINZU_A4_STEAM :Ginzu 'A4' (蒸汽机)
+STR_800A_SH_8P_STEAM :SH '8P' (蒸汽机)
+STR_800B_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (柴油机)
+STR_800C_DASH_DIESEL :'Dash' (柴油机)
+STR_800D_SH_HENDRY_25_DIESEL :SH/Hendry '25' (柴油机)
+STR_800E_UU_37_DIESEL :UU '37' (柴油机)
+STR_800F_FLOSS_47_DIESEL :Floss '47' (柴油机)
+STR_8010_CS_4000_DIESEL :CS 4000 (柴油机)
+STR_8011_CS_2400_DIESEL :CS 2400 (柴油机)
+STR_8012_CENTENNIAL_DIESEL :Centennial (柴油机)
+STR_8013_KELLING_3100_DIESEL :Kelling 3100 (柴油机)
+STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (柴油机)
+STR_8015_MJS_1000_DIESEL :MJS 1000 (柴油机)
+STR_8016_SH_125_DIESEL :SH '125' (柴油机)
+STR_8017_SH_30_ELECTRIC :SH '30' (电力机车)
+STR_8018_SH_40_ELECTRIC :SH '40' (电力机车)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (电力机车)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (电力机车)
+STR_801B_PASSENGER_CAR :旅客车厢
+STR_801C_MAIL_VAN :邮政车厢
+STR_801D_COAL_CAR :煤炭挂车
+STR_801E_OIL_TANKER :原油ç½è½¦
+STR_801F_LIVESTOCK_VAN :牲畜挂车
+STR_8020_GOODS_VAN :货物挂车
+STR_8021_GRAIN_HOPPER :谷物挂车
+STR_8022_WOOD_TRUCK :木æ挂车
+STR_8023_IRON_ORE_HOPPER :é“矿石挂车
+STR_8024_STEEL_TRUCK :é’¢æ挂车
+STR_8025_ARMORED_VAN :装甲挂车
+STR_8026_FOOD_VAN :食å“挂车
+STR_8027_PAPER_TRUCK :纸张挂车
+STR_8028_COPPER_ORE_HOPPER :铜矿石挂车
+STR_8029_WATER_TANKER :æ°´ç½è½¦
+STR_802A_FRUIT_TRUCK :水果挂车
+STR_802B_RUBBER_TRUCK :橡胶挂车
+STR_802C_SUGAR_TRUCK :蔗糖挂车
+STR_802D_COTTON_CANDY_HOPPER :棉花糖挂车
+STR_802E_TOFFEE_HOPPER :太妃糖挂车
+STR_802F_BUBBLE_VAN :泡泡挂车
+STR_8030_COLA_TANKER :å¯ä¹ç½è½¦
+STR_8031_CANDY_VAN :糖果挂车
+STR_8032_TOY_VAN :玩具挂车
+STR_8033_BATTERY_TRUCK :电池挂车
+STR_8034_FIZZY_DRINK_TRUCK :泡泡水挂车
+STR_8035_PLASTIC_TRUCK :塑料挂车
+STR_8036_X2001_ELECTRIC :'X2001' (电力机车)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (电力机车)
+STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
+STR_8039_PASSENGER_CAR :旅客车厢
+STR_803A_MAIL_VAN :邮政车厢
+STR_803B_COAL_CAR :煤炭挂车
+STR_803C_OIL_TANKER :原油挂车
+STR_803D_LIVESTOCK_VAN :牲畜挂车
+STR_803E_GOODS_VAN :货物挂车
+STR_803F_GRAIN_HOPPER :谷物挂车
+STR_8040_WOOD_TRUCK :木æ挂车
+STR_8041_IRON_ORE_HOPPER :é“矿石挂车
+STR_8042_STEEL_TRUCK :é’¢æ挂车
+STR_8043_ARMORED_VAN :装甲挂车
+STR_8044_FOOD_VAN :食å“挂车
+STR_8045_PAPER_TRUCK :纸张挂车
+STR_8046_COPPER_ORE_HOPPER :铜矿石挂车
+STR_8047_WATER_TANKER :æ°´ç½è½¦
+STR_8048_FRUIT_TRUCK :水果挂车
+STR_8049_RUBBER_TRUCK :橡胶挂车
+STR_804A_SUGAR_TRUCK :蔗糖挂车
+STR_804B_COTTON_CANDY_HOPPER :棉花糖挂车
+STR_804C_TOFFEE_HOPPER :太妃挂车
+STR_804D_BUBBLE_VAN :泡泡挂车
+STR_804E_COLA_TANKER :å¯ä¹ç½è½¦
+STR_804F_CANDY_VAN :糖果挂车
+STR_8050_TOY_VAN :玩具挂车
+STR_8051_BATTERY_TRUCK :电池挂车
+STR_8052_FIZZY_DRINK_TRUCK :泡泡水挂车
+STR_8053_PLASTIC_TRUCK :塑料挂车
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (电力机车)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (电力机车)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (电力机车)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (电力机车)
+STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
+STR_8059_PASSENGER_CAR :旅客车厢
+STR_805A_MAIL_VAN :邮政车厢
+STR_805B_COAL_CAR :煤炭挂车
+STR_805C_OIL_TANKER :原油挂车
+STR_805D_LIVESTOCK_VAN :牲畜挂车
+STR_805E_GOODS_VAN :货物挂车
+STR_805F_GRAIN_HOPPER :谷物挂车
+STR_8060_WOOD_TRUCK :木æ挂车
+STR_8061_IRON_ORE_HOPPER :é“矿石挂车
+STR_8062_STEEL_TRUCK :é’¢æ挂车
+STR_8063_ARMORED_VAN :装甲挂车
+STR_8064_FOOD_VAN :食å“挂车
+STR_8065_PAPER_TRUCK :纸张挂车
+STR_8066_COPPER_ORE_HOPPER :铜矿石挂车
+STR_8067_WATER_TANKER :æ°´ç½è½¦
+STR_8068_FRUIT_TRUCK :水果挂车
+STR_8069_RUBBER_TRUCK :橡胶挂车
+STR_806A_SUGAR_TRUCK :蔗糖挂车
+STR_806B_COTTON_CANDY_HOPPER :棉花糖挂车
+STR_806C_TOFFEE_HOPPER :太妃糖挂车
+STR_806D_BUBBLE_VAN :泡泡挂车
+STR_806E_COLA_TANKER :å¯ä¹ç½è½¦
+STR_806F_CANDY_VAN :糖果挂车
+STR_8070_TOY_VAN :玩具挂车
+STR_8071_BATTERY_TRUCK :电池挂车
+STR_8072_FIZZY_DRINK_TRUCK :泡泡水挂车
+STR_8073_PLASTIC_TRUCK :塑料挂车
+STR_8074_MPS_REGAL_BUS :MPS Regal 客车
+STR_8075_HEREFORD_LEOPARD_BUS :Hereford Leopard 客车
+STR_8076_FOSTER_BUS :Foster 客车
+STR_8077_FOSTER_MKII_SUPERBUS :Foster MkII 超级客车
+STR_8078_PLODDYPHUT_MKI_BUS :Ploddyphut MkI 客车
+STR_8079_PLODDYPHUT_MKII_BUS :Ploddyphut MkII 客车
+STR_807A_PLODDYPHUT_MKIII_BUS :Ploddyphut MkIII 客车
+STR_807B_BALOGH_COAL_TRUCK :Balogh 煤炭å¡è½¦
+STR_807C_UHL_COAL_TRUCK :Uhl 煤炭å¡è½¦
+STR_807D_DW_COAL_TRUCK :DW 煤炭å¡è½¦
+STR_807E_MPS_MAIL_TRUCK :MPS 邮政å¡è½¦
+STR_807F_REYNARD_MAIL_TRUCK :Reynard 邮政å¡è½¦
+STR_8080_PERRY_MAIL_TRUCK :Perry 邮政å¡è½¦
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :MightyMover 邮政å¡è½¦
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Powernaught 邮政å¡è½¦
+STR_8083_WIZZOWOW_MAIL_TRUCK :Wizzowow 邮政å¡è½¦
+STR_8084_WITCOMBE_OIL_TANKER :Witcombe æ²¹ç½è½¦
+STR_8085_FOSTER_OIL_TANKER :Foster æ²¹ç½è½¦
+STR_8086_PERRY_OIL_TANKER :Perry æ²¹ç½è½¦
+STR_8087_TALBOTT_LIVESTOCK_VAN :Talbott 牲畜å¡è½¦
+STR_8088_UHL_LIVESTOCK_VAN :Uhl 牲畜å¡è½¦
+STR_8089_FOSTER_LIVESTOCK_VAN :Foster 牲畜å¡è½¦
+STR_808A_BALOGH_GOODS_TRUCK :Balogh 货物å¡è½¦
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Craighead 货物å¡è½¦
+STR_808C_GOSS_GOODS_TRUCK :Goss 货物å¡è½¦
+STR_808D_HEREFORD_GRAIN_TRUCK :Hereford 谷物å¡è½¦
+STR_808E_THOMAS_GRAIN_TRUCK :Thomas 谷物å¡è½¦
+STR_808F_GOSS_GRAIN_TRUCK :Goss 谷物å¡è½¦
+STR_8090_WITCOMBE_WOOD_TRUCK :Witcombe 木æå¡è½¦
+STR_8091_FOSTER_WOOD_TRUCK :Foster 木æå¡è½¦
+STR_8092_MORELAND_WOOD_TRUCK :Moreland 木æå¡è½¦
+STR_8093_MPS_IRON_ORE_TRUCK :MPS é“矿石å¡è½¦
+STR_8094_UHL_IRON_ORE_TRUCK :Uhl é“矿石å¡è½¦
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Chippy é“矿石å¡è½¦
+STR_8096_BALOGH_STEEL_TRUCK :Balogh é’¢æå¡è½¦
+STR_8097_UHL_STEEL_TRUCK :Uhl é’¢æå¡è½¦
+STR_8098_KELLING_STEEL_TRUCK :Kelling é’¢æå¡è½¦
+STR_8099_BALOGH_ARMORED_TRUCK :Balogh 装甲å¡è½¦
+STR_809A_UHL_ARMORED_TRUCK :Uhl 装甲å¡è½¦
+STR_809B_FOSTER_ARMORED_TRUCK :Foster 装甲å¡è½¦
+STR_809C_FOSTER_FOOD_VAN :Foster 食å“å¡è½¦
+STR_809D_PERRY_FOOD_VAN :Perry 装甲å¡è½¦
+STR_809E_CHIPPY_FOOD_VAN :Chippy 装甲å¡è½¦
+STR_809F_UHL_PAPER_TRUCK :Uhl 纸张å¡è½¦
+STR_80A0_BALOGH_PAPER_TRUCK :Balogh 纸张å¡è½¦
+STR_80A1_MPS_PAPER_TRUCK :MPS 纸张å¡è½¦
+STR_80A2_MPS_COPPER_ORE_TRUCK :MPS 铜矿石å¡è½¦
+STR_80A3_UHL_COPPER_ORE_TRUCK :Uhl 铜矿石å¡è½¦
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Goss 铜矿石å¡è½¦
+STR_80A5_UHL_WATER_TANKER :Uhl æ°´ç½è½¦
+STR_80A6_BALOGH_WATER_TANKER :Balogh æ°´ç½è½¦
+STR_80A7_MPS_WATER_TANKER :MPS æ°´ç½è½¦
+STR_80A8_BALOGH_FRUIT_TRUCK :Balogh æ°´æžœå¡è½¦
+STR_80A9_UHL_FRUIT_TRUCK :Uhl æ°´æžœå¡è½¦
+STR_80AA_KELLING_FRUIT_TRUCK :Kelling æ°´æžœå¡è½¦
+STR_80AB_BALOGH_RUBBER_TRUCK :Balogh 橡胶å¡è½¦
+STR_80AC_UHL_RUBBER_TRUCK :Uhl 橡胶å¡è½¦
+STR_80AD_RMT_RUBBER_TRUCK :RMT 橡胶å¡è½¦
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :MightyMover è”—ç³–å¡è½¦
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Powernaught è”—ç³–å¡è½¦
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Wizzowow è”—ç³–å¡è½¦
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :MightyMover å¯ä¹ç½è½¦
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Powernaught å¯ä¹ç½è½¦
+STR_80B3_WIZZOWOW_COLA_TRUCK :Wizzowow å¯ä¹ç½è½¦
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :MightyMover 棉花糖å¡è½¦
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Powernaught 棉花糖å¡è½¦
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Wizzowow 棉花糖å¡è½¦
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :MightyMover 太妃糖å¡è½¦
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Powernaught 太妃糖å¡è½¦
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Wizzowow 太妃糖å¡è½¦
+STR_80BA_MIGHTYMOVER_TOY_VAN :MightyMover 玩具å¡è½¦
+STR_80BB_POWERNAUGHT_TOY_VAN :Powernaught 玩具å¡è½¦
+STR_80BC_WIZZOWOW_TOY_VAN :Wizzowow 玩具å¡è½¦
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :MightyMover ç³–æžœå¡è½¦
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Powernaught ç³–æžœå¡è½¦
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Wizzowow ç³–æžœå¡è½¦
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :MightyMover 电池å¡è½¦
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Powernaught 电池å¡è½¦
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Wizzowow 电池å¡è½¦
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :MightyMover 泡泡水å¡è½¦
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Powernaught 泡泡水å¡è½¦
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Wizzowow 泡泡水å¡è½¦
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :MightyMover å¡‘æ–™å¡è½¦
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Powernaught å¡‘æ–™å¡è½¦
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Wizzowow å¡‘æ–™å¡è½¦
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :MightyMover 泡泡å¡è½¦
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Powernaught 泡泡å¡è½¦
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Wizzowow 泡泡å¡è½¦
+STR_80CC_MPS_OIL_TANKER :MPS æ²¹ç½è½¦
+STR_80CD_CS_INC_OIL_TANKER :CS-Inc. æ²¹ç½è½¦
+STR_80CE_MPS_PASSENGER_FERRY :MPS 旅客渡船
+STR_80CF_FFP_PASSENGER_FERRY :FFP 旅客渡船
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Bakewell 300 气垫船
+STR_80D1_CHUGGER_CHUG_PASSENGER :Chugger-Chug 旅客渡船
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Shivershake 旅客渡船
+STR_80D3_YATE_CARGO_SHIP :Yate 货船
+STR_80D4_BAKEWELL_CARGO_SHIP :Bakewell 货船
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Mightymover 货船
+STR_80D6_POWERNAUT_CARGO_SHIP :Powernaut 货船
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Tricario ç›´å‡æœº
+STR_80FE_GURU_X2_HELICOPTER :Guru X2 ç›´å‡æœº
+STR_80FF_POWERNAUT_HELICOPTER :Powernaut ç›´å‡æœº
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}车辆制造厂æ¥çš„消æ¯
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}我们新近设计了一ç§æ–°çš„ {STRING} - 在我们正å¼æŽ¨å‘市场之å‰å°†å……分测试它的性能, 您是å¦æ„¿æ„æå‰ä¸€å¹´è¯•ç”¨?
+STR_8102_RAILROAD_LOCOMOTIVE :é“路机车
+STR_8103_ROAD_VEHICLE :汽车
+STR_8104_AIRCRAFT :飞机
+STR_8105_SHIP :船åª
+STR_8106_MONORAIL_LOCOMOTIVE :å•è½¨æœºè½¦
+STR_8107_MAGLEV_LOCOMOTIVE :ç£æ‚¬æµ®æœºè½¦
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}{TOWN} ç«è½¦è½¦åº“
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}市民欢庆 . . .{}历å²ä¸Šç¬¬ä¸€è¾†ç«è½¦åˆ°è¾¾ {STATION}!
+STR_8802_DETAILS :{WHITE}{STRING} (详情)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}这个ä½ç½®ä¸Šæœ‰ç«è½¦
+STR_8804 :{SETX 10}{COMMA}: {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING}
+STR_8806_GO_TO :å‰å¾€ {STATION}
+STR_8807_GO_TO_TRANSFER :å‰å¾€ {STATION} (è”è¿ç«™, 装载货物或乘客)
+STR_8808_GO_TO_UNLOAD :å‰å¾€ {STATION} (å¸è½½)
+STR_8809_GO_TO_TRANSFER_UNLOAD :å‰å¾€ {STATION} (è”è¿ç»ˆç‚¹, å¸è½½å…¨éƒ¨è´§ç‰©æˆ–乘客)
+STR_880A_GO_TO_LOAD :å‰å¾€ {STATION} (装载)
+STR_880B_GO_TO_TRANSFER_LOAD :å‰å¾€ {STATION} (è”è¿ç«™, 装满乘客或货物)
+STR_880C_GO_NON_STOP_TO :å‰å¾€ {STATION} 但ä¸åœè½¦
+STR_880D_GO_TO_NON_STOP_TRANSFER :å‰å¾€ {STATION} 但ä¸åœè½¦ (è”è¿ç«™, 装载货物或乘客)
+STR_880E_GO_NON_STOP_TO_UNLOAD :å‰å¾€ {STATION} 但ä¸åœè½¦ (å¸è½½)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :å‰å¾€ {STATION} 但ä¸åœè½¦ (è”è¿ç»ˆç‚¹, å¸è½½å…¨éƒ¨è´§ç‰©æˆ–乘客)
+STR_8810_GO_NON_STOP_TO_LOAD :å‰å¾€ {STATION} 但ä¸åœè½¦ (装载)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :å‰å¾€ {STATION} 但ä¸åœè½¦ (è”è¿ç«™, 装满货物或乘客)
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :å‰å¾€ {TOWN} ç«è½¦è½¦åº“但ä¸åœè½¦
+
+
+
+STR_8812_EMPTY :{LTBLUE}空
+STR_8813_FROM :{LTBLUE}{CARGO} æ¥è‡ª {STATION}
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}列车 {COMMA} 正在车库中等侯调度
+STR_8815_NEW_VEHICLES :{BLACK}è´­ä¹°æ–°ç«è½¦
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}ç«è½¦å¤ªé•¿äº†
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}åªæœ‰å®Œå…¨åœå…¥ç«è½¦è½¦åº“åŽæ‰èƒ½æ›´æ”¹ç«è½¦é…ç½®
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}è´­ä¹°æ–°ç«è½¦
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}è´­ä¹°å•è½¨åˆ—车
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}è´­ä¹°ç£æ‚¬æµ®åˆ—车
+STR_881F_BUILD_VEHICLE :{BLACK}购买列车
+STR_8820_RENAME :{BLACK}é‡å‘½å
+STR_8823_SKIP :{BLACK}跳过
+STR_8824_DELETE :{BLACK}删除
+STR_8825_NON_STOP :{BLACK}ä¸åœè½¦
+STR_8826_GO_TO :{BLACK}å‰å¾€
+STR_8827_FULL_LOAD :{BLACK}完全装载
+STR_8828_UNLOAD :{BLACK}完全å¸è½½
+STR_8829_ORDERS :{WHITE}{VEHICLE} (调度)
+STR_882A_END_OF_ORDERS :{SETX 10}- - 调度表结尾 - -
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}ä¸èƒ½å¤Ÿä¹°åˆ—车...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} 购买年份: {LTBLUE}{NUM}{BLACK} 价值: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} 价值: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}正在装载/å¸è½½
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}ä¸èƒ½å°†åˆ—车å¬å›žè½¦åº“...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}没有更多的ä½ç½®æ”¾ç½®æ–°çš„调度命令了
+STR_8832_TOO_MANY_ORDERS :{WHITE}调度命令太多了
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}ä¸èƒ½æ’入新的调度命令...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}ä¸èƒ½åˆ é™¤è¿™ä¸ªè°ƒåº¦å‘½ä»¤...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}ä¸èƒ½ä¿®æ”¹è¿™æ¡è°ƒåº¦å‘½ä»¤...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}ä¸èƒ½ç§»åŠ¨åˆ—车...
+STR_8838_N_A :ä¸å­˜åœ¨{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}ä¸èƒ½å‡ºå”®åˆ—车...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}找ä¸åˆ°å‰å¾€è½¦åº“的路径
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}ä¸èƒ½åœæ­¢/å¯åŠ¨åˆ—车...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}ä¿å…»å‘¨æœŸ: {LTBLUE}{COMMA}天{BLACK} 上次ä¿å…»: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}列车 - å•å‡»åˆ—车查看详情
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}购买新的列车 (需è¦ç«è½¦è½¦åº“)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}列车 - 点击查看详情, 拖动以增加/删除列车车厢
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}购买新的列车车厢
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}将列车车厢拖动到这里å¯ä»¥å°†å…¶å‡ºå”®
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}将视点调整到列车车库的ä½ç½®
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}列车车厢选择表 - å•å‡»è½¦è¾†æŸ¥çœ‹è¯¦æƒ…
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}购买高亮的列车车é‡
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}é‡å‘½å列车车辆类型
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}列车当å‰çš„çŠ¶æ€ - å•å‡»ä»¥å¯åŠ¨/åœæ­¢åˆ—车
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}显示列车的调度信æ¯
+
+
+
+##id 0x9000
+
+
+
+##id 0x9800
+
+SERVICE_AT_SHIP_DEPOT :在 {TOWN} 船åžè¿›è¡Œä¿å…»
+
+##id 0xA000
+
+SERVICE_AT_AIRPORT_HANGAR :在 {STATION}
+
+##id 0xB000
+
+
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+############ End of order list
+
+
+
+
+
+
+
+
+
+############ Lists rail types
+
+
+############ End of list of rail types
+
+
+
+########### String for new airports
+
+########
diff --git a/src/lang/unfinished/slovenian.txt b/src/lang/unfinished/slovenian.txt
new file mode 100644
index 000000000..71bc1b503
--- /dev/null
+++ b/src/lang/unfinished/slovenian.txt
@@ -0,0 +1,2318 @@
+##name Slovenian
+##ownname Slovenscina
+##isocode sl_SL.UTF-8
+##plural 8
+
+##id 0x0000
+STR_NULL :
+STR_0001_OFF_EDGE_OF_MAP :{WHITE}Cez rob maper
+STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Preblizu robu mape
+STR_0003_NOT_ENOUGH_CASH_REQUIRES :{WHITE}Premalo denarja - potrebujete {CURRENCY}
+STR_0004 :{WHITE}{CURRENCY64}
+STR_0005 :{RED}{CURRENCY64}
+STR_EMPTY :
+STR_0007_FLAT_LAND_REQUIRED :{WHITE}Potrebno je ravno zemljisce
+STR_0008_WAITING :{BLACK}Cakam: {WHITE}{STRING}
+STR_0009 :{WHITE}{CARGO}
+STR_000A_EN_ROUTE_FROM :{WHITE}{CARGO}{YELLOW} (iz
+STR_000B :{YELLOW}{STATION})
+STR_000C_ACCEPTS :{BLACK}Sprejema: {WHITE}
+STR_000D_ACCEPTS :{BLACK}Sprejema: {GOLD}
+STR_000E :
+STR_000F_PASSENGERS :Potniki
+STR_0010_COAL :Premog
+STR_0011_MAIL :Pošta
+STR_0012_OIL :Nafta
+STR_0013_LIVESTOCK :Živina
+STR_0014_GOODS :Dobrine
+STR_0015_GRAIN :Žito
+STR_0016_WOOD :Les
+STR_0017_IRON_ORE :Železova ruda
+STR_0018_STEEL :Jeklo
+STR_0019_VALUABLES :Dragocenosti
+STR_001A_COPPER_ORE :Bakrova ruda
+STR_001B_MAIZE :Koruza
+STR_001C_FRUIT :Sadje
+STR_001D_DIAMONDS :Diamanti
+STR_001E_FOOD :Hrana
+STR_001F_PAPER :Papir
+STR_0020_GOLD :Zlato
+STR_0021_WATER :Voda
+STR_0022_WHEAT :PÅ¡enica
+STR_0023_RUBBER :Guma
+STR_0024_SUGAR :Sladkor
+STR_0025_TOYS :IgraÄe
+STR_0026_CANDY :Bonboni
+STR_0027_COLA :Cockta
+STR_0028_COTTON_CANDY :Sladkorna pena
+STR_0029_BUBBLES :MehurÄki
+STR_002A_TOFFEE :Karamela
+STR_002B_BATTERIES :Baterije
+STR_002C_PLASTIC :Plastika
+STR_002D_FIZZY_DRINKS :Gazirane pijaÄe
+STR_002E :
+STR_002F_PASSENGER :Potnik
+STR_0030_COAL :Premog
+STR_0031_MAIL :Pošta
+STR_0032_OIL :Nafta
+STR_0033_LIVESTOCK :Živina
+STR_0034_GOODS :Dobrine
+STR_0035_GRAIN :Žito
+STR_0036_WOOD :Les
+STR_0037_IRON_ORE :Železova ruda
+STR_0038_STEEL :Jeklo
+STR_0039_VALUABLES :Dragocenosti
+STR_003A_COPPER_ORE :Bakrova ruda
+STR_003B_MAIZE :Koruza
+STR_003C_FRUIT :Sadje
+STR_003D_DIAMOND :Diamanti
+STR_003E_FOOD :Hrana
+STR_003F_PAPER :Papir
+STR_0040_GOLD :Zlato
+STR_0041_WATER :Voda
+STR_0042_WHEAT :PÅ¡enica
+STR_0043_RUBBER :Guma
+STR_0044_SUGAR :Sladkor
+STR_0045_TOY :IgraÄe
+STR_0046_CANDY :Bombon
+STR_0047_COLA :Cockta
+STR_0048_COTTON_CANDY :Sladkorna pena
+STR_0049_BUBBLE :MehurÄki
+STR_004A_TOFFEE :Karamela
+STR_004B_BATTERY :Baterija
+STR_004C_PLASTIC :Plastika
+STR_004D_FIZZY_DRINK :Gazirana pijaÄa
+STR_QUANTITY_NOTHING :
+STR_QUANTITY_PASSENGERS :{COMMA} potnikov
+STR_QUANTITY_COAL :{WEIGHT} ton premoga
+STR_QUANTITY_MAIL :{COMMA} vrec poste
+STR_QUANTITY_OIL :{VOLUME} nafte
+STR_QUANTITY_LIVESTOCK :{COMMA} glav zivine
+STR_QUANTITY_GOODS :{COMMA} paketov dobrin
+STR_QUANTITY_GRAIN :{WEIGHT} ton zita
+STR_QUANTITY_WOOD :{WEIGHT} lesa
+STR_QUANTITY_IRON_ORE :{WEIGHT} ton zelezove rude
+STR_QUANTITY_STEEL :{WEIGHT} ton jekla
+STR_QUANTITY_VALUABLES :{COMMA} vrec dragocenosti
+STR_QUANTITY_COPPER_ORE :{WEIGHT} ton bakrove rude
+STR_QUANTITY_MAIZE :{WEIGHT} ton koruze
+STR_QUANTITY_FRUIT :{WEIGHT}ton sadja
+STR_QUANTITY_DIAMONDS :{COMMA} vrec diamantov
+STR_QUANTITY_FOOD :{WEIGHT}ton hrane
+STR_QUANTITY_PAPER :{WEIGHT} ton papirja
+STR_QUANTITY_GOLD :{COMMA} vrec zlata
+STR_QUANTITY_WATER :{VOLUME} vode
+STR_QUANTITY_WHEAT :{WEIGHT} ton psenice
+STR_QUANTITY_RUBBER :{VOLUME} gume
+STR_QUANTITY_SUGAR :{WEIGHT} ton sladkorja
+STR_QUANTITY_TOYS :{COMMA} igrac
+STR_QUANTITY_SWEETS :{COMMA} vrec slascic
+STR_QUANTITY_COLA :{VOLUME} cockte
+STR_QUANTITY_CANDYFLOSS :{WEIGHT} ton sladkorne pene
+STR_QUANTITY_BUBBLES :{COMMA} balonckov
+STR_QUANTITY_TOFFEE :{WEIGHT} ton karamele
+STR_QUANTITY_BATTERIES :{COMMA} baterij
+STR_QUANTITY_PLASTIC :{VOLUME} plastike
+STR_QUANTITY_FIZZY_DRINKS :{COMMA} gaziranih pijac
+STR_ABBREV_NOTHING :
+STR_ABBREV_PASSENGERS :{TINYFONT}PO
+STR_ABBREV_COAL :{TINYFONT}PR
+STR_ABBREV_MAIL :{TINYFONT}PS
+STR_ABBREV_OIL :{TINYFONT}NF
+STR_ABBREV_LIVESTOCK :{TINYFONT}ZV
+STR_ABBREV_GOODS :{TINYFONT}DO
+STR_ABBREV_GRAIN :{TINYFONT}ZT
+STR_ABBREV_WOOD :{TINYFONT}LS
+STR_ABBREV_IRON_ORE :{TINYFONT}ZR
+STR_ABBREV_STEEL :{TINYFONT}JK
+STR_ABBREV_VALUABLES :{TINYFONT}DR
+STR_ABBREV_COPPER_ORE :{TINYFONT}BK
+STR_ABBREV_MAIZE :{TINYFONT}KZ
+STR_ABBREV_FRUIT :{TINYFONT}SJ
+STR_ABBREV_DIAMONDS :{TINYFONT}DM
+STR_ABBREV_FOOD :{TINYFONT}ZI
+STR_ABBREV_PAPER :{TINYFONT}PR
+STR_ABBREV_GOLD :{TINYFONT}ZL
+STR_ABBREV_WATER :{TINYFONT}VO
+STR_ABBREV_WHEAT :{TINYFONT}PN
+STR_ABBREV_RUBBER :{TINYFONT}GU
+STR_ABBREV_SUGAR :{TINYFONT}SK
+STR_ABBREV_TOYS :{TINYFONT}IG
+STR_ABBREV_SWEETS :{TINYFONT}SL
+STR_ABBREV_COLA :{TINYFONT}CK
+STR_ABBREV_CANDYFLOSS :{TINYFONT}SP
+STR_ABBREV_BUBBLES :{TINYFONT}MH
+STR_ABBREV_TOFFEE :{TINYFONT}TF
+STR_ABBREV_BATTERIES :{TINYFONT}BA
+STR_ABBREV_PLASTIC :{TINYFONT}PL
+STR_ABBREV_FIZZY_DRINKS :{TINYFONT}GP
+STR_ABBREV_NONE :{TINYFONT}NO
+STR_ABBREV_ALL :{TINYFONT}VSE
+STR_00AE :{WHITE}{DATE_SHORT}
+STR_00AF :{WHITE}{DATE_LONG}
+STR_00B0_MAP :{WHITE}Zemljevid - {STRING}
+STR_00B1_GAME_OPTIONS :{WHITE}Možnosti Igre
+STR_00B2_MESSAGE :{YELLOW}SporoÄilo
+STR_00B3_MESSAGE_FROM :{YELLOW}SporoÄilo od {STRING}
+STR_POPUP_CAUTION_CAPTION :{WHITE}Pozor!
+STR_00B4_CAN_T_DO_THIS :{WHITE}Ne morem narediti tega ...
+STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Ne morem oÄistiti tega podroÄja ...
+STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Prvotne avtorske pravice {COPYRIGHT} 1995 Chris Sawyer, Vse pravice pridržane
+STR_00B7_VERSION :{BLACK}OpenTTD razliÄica {REV}
+STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2006 ekipa OpenTTD
+STR_TRANSLATED_BY :{BLACK} Prevod - seba
+
+STR_00C5 :{BLACK}{CROSS}
+STR_00C6 :{SILVER}{CROSS}
+STR_00C7_QUIT :{WHITE}Izhod
+STR_00C8_YES :{BLACK}Da
+STR_00C9_NO :{BLACK}Ne
+STR_00CA_ARE_YOU_SURE_YOU_WANT_TO :{YELLOW}Ali ste prepriÄani, da želite zapustiti igro in se vrniti v {STRING}?
+STR_00CB_1 :{BLACK}1
+STR_00CC_2 :{BLACK}2
+STR_00CD_3 :{BLACK}3
+STR_00CE_4 :{BLACK}4
+STR_00CF_5 :{BLACK}5
+STR_00D0_NOTHING :NiÄ
+STR_00D1_DARK_BLUE :Temno modra
+STR_00D2_PALE_GREEN :Svetlo zelena
+STR_00D3_PINK :Rožnata
+STR_00D4_YELLOW :Rumena
+STR_00D5_RED :RdeÄa
+STR_00D6_LIGHT_BLUE :Svetlo modra
+STR_00D7_GREEN :Zelena
+STR_00D8_DARK_GREEN :Temno zelena
+STR_00D9_BLUE :Modra
+STR_00DA_CREAM :Kremna
+STR_00DB_MAUVE :Slezenasta
+STR_00DC_PURPLE :VijoliÄna
+STR_00DD_ORANGE :Oranžna
+STR_00DE_BROWN :Rjava
+STR_00DF_GREY :Siva
+STR_00E0_WHITE :Bela
+STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}PreveÄ vozil v igri
+STR_00E2 :{BLACK}{COMMA}
+STR_00E3 :{RED}{COMMA}
+STR_00E4_LOCATION :{BLACK}Lokacija
+STR_00E5_CONTOURS :NaÄrt
+STR_00E6_VEHICLES :Vozila
+STR_00E7_INDUSTRIES :Industrije
+STR_00E8_ROUTES :Poti
+STR_00E9_VEGETATION :Vegetacija
+STR_00EA_OWNERS :Lastniki
+STR_00EB_ROADS :{BLACK}{TINYFONT}Ceste
+STR_00EC_RAILROADS :{BLACK}{TINYFONT}Železnice
+STR_00ED_STATIONS_AIRPORTS_DOCKS :{BLACK}{TINYFONT}Postaje/LetaliÅ¡Äa/PristaniÅ¡Äa
+STR_00EE_BUILDINGS_INDUSTRIES :{BLACK}{TINYFONT}Stavbe/Industrije
+STR_00EF_VEHICLES :{BLACK}{TINYFONT}Vozila
+STR_00F0_100M :{BLACK}{TINYFONT}100m
+STR_00F1_200M :{BLACK}{TINYFONT}200m
+STR_00F2_300M :{BLACK}{TINYFONT}300m
+STR_00F3_400M :{BLACK}{TINYFONT}400m
+STR_00F4_500M :{BLACK}{TINYFONT}500m
+STR_00F5_TRAINS :{BLACK}{TINYFONT}Vlaki
+STR_00F6_ROAD_VEHICLES :{BLACK}{TINYFONT}Cestna vozila
+STR_00F7_SHIPS :{BLACK}{TINYFONT}Ladje
+STR_00F8_AIRCRAFT :{BLACK}{TINYFONT}Letala
+STR_00F9_TRANSPORT_ROUTES :{BLACK}{TINYFONT}Transportne poti
+STR_00FA_COAL_MINE :{BLACK}{TINYFONT}Rudnik premoga
+STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Termoelektrarna
+STR_00FC_FOREST :{BLACK}{TINYFONT}Gozd
+STR_00FD_SAWMILL :{BLACK}{TINYFONT}Žaga
+STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Naftna rafinerija
+STR_00FF_FARM :{BLACK}{TINYFONT}Kmetija
+STR_0100_FACTORY :{BLACK}{TINYFONT}Tovarna
+STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Tiskarna
+STR_0102_OIL_WELLS :{BLACK}{TINYFONT}Naftno polje
+STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Rudnik železa
+STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Jeklarna
+STR_0105_BANK :{BLACK}{TINYFONT}Banka
+STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Papirnica
+STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Rudnik zlata
+STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Predelava hrane
+STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Rudnik diamantov
+STR_010A_COPPER_ORE_MINE :{BLACK}{TINYFONT}Rudnik bakra
+STR_010B_FRUIT_PLANTATION :{BLACK}{TINYFONT}Sadovnjak
+STR_010C_RUBBER_PLANTATION :{BLACK}{TINYFONT}Plantaža gume
+STR_010D_WATER_SUPPLY :{BLACK}{TINYFONT}Vodni izvir
+STR_010E_WATER_TOWER :{BLACK}{TINYFONT}Vodni stolp
+STR_010F_LUMBER_MILL :{BLACK}{TINYFONT}Žaga
+STR_0110_COTTON_CANDY_FOREST :{BLACK}{TINYFONT}Gozd sladkorne pene
+STR_0111_CANDY_FACTORY :{BLACK}{TINYFONT}Tovarna slaÅ¡Äic
+STR_0112_BATTERY_FARM :{BLACK}{TINYFONT}Farma baterij
+STR_0113_COLA_WELLS :{BLACK}{TINYFONT}Izvir Cockte
+STR_0114_TOY_SHOP :{BLACK}{TINYFONT}Trgovina z igraÄami
+STR_0115_TOY_FACTORY :{BLACK}{TINYFONT}Tovarna igraÄ
+STR_0116_PLASTIC_FOUNTAINS :{BLACK}{TINYFONT}Vodnjaki plastike
+STR_0117_FIZZY_DRINK_FACTORY :{BLACK}{TINYFONT}Tovarna gaziranih pijaÄ
+STR_0118_BUBBLE_GENERATOR :{BLACK}{TINYFONT}Generator balonÄkov
+STR_0119_TOFFEE_QUARRY :{BLACK}{TINYFONT}Jama karamele
+STR_011A_SUGAR_MINE :{BLACK}{TINYFONT}Rudnik sladkorja
+STR_011B_RAILROAD_STATION :{BLACK}{TINYFONT}Železniška postaja
+STR_011C_TRUCK_LOADING_BAY :{BLACK}{TINYFONT}Distribucijsko obmoÄje za tovornjake
+STR_011D_BUS_STATION :{BLACK}{TINYFONT}Avtobusna postaja
+STR_011E_AIRPORT_HELIPORT :{BLACK}{TINYFONT}LetaliÅ¡Äe/Heliport
+STR_011F_DOCK :{BLACK}{TINYFONT}PristaniÅ¡Äe
+STR_0120_ROUGH_LAND :{BLACK}{TINYFONT}Groba tla
+STR_0121_GRASS_LAND :{BLACK}{TINYFONT}Travnata tla
+STR_0122_BARE_LAND :{BLACK}{TINYFONT}Gola tla
+STR_0123_FIELDS :{BLACK}{TINYFONT}Polja
+STR_0124_TREES :{BLACK}{TINYFONT}Drevesa
+STR_0125_ROCKS :{BLACK}{TINYFONT}Kamni
+STR_0126_WATER :{BLACK}{TINYFONT}Voda
+STR_0127_NO_OWNER :{BLACK}{TINYFONT}Brez lastnika
+STR_0128_TOWNS :{BLACK}{TINYFONT}Mesta
+STR_0129_INDUSTRIES :{BLACK}{TINYFONT}Industrije
+STR_012A_DESERT :{BLACK}{TINYFONT}PuÅ¡Äava
+STR_012B_SNOW :{BLACK}{TINYFONT}Sneg
+STR_012C_MESSAGE :{WHITE}SporoÄilo
+STR_012D :{WHITE}{STRING}
+STR_012E_CANCEL :{BLACK}PrekliÄi
+STR_012F_OK :{BLACK}Potrdi
+STR_0130_RENAME :{BLACK}Preimenuj
+STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}PreveÄ definiranih imen
+STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Izbrano ime je že v uporabi
+
+STR_0133_WINDOWS :Windows
+STR_0134_UNIX :Unix
+STR_0135_OSX :OS X
+STR_OSNAME_BEOS :BeOS
+STR_OSNAME_MORPHOS :MorphOS
+STR_OSNAME_AMIGAOS :AmigaOS
+STR_OSNAME_OS2 :OS/2
+
+STR_013B_OWNED_BY :{WHITE} ... pripada {STRING}
+STR_013C_CARGO :{BLACK}Tovor
+STR_013D_INFORMATION :{BLACK}Informacije
+STR_013E_CAPACITIES :{BLACK}Kapacitete
+STR_013E_TOTAL_CARGO :{BLACK}Skupni tovor
+STR_013F_CAPACITY :{BLACK}Kapaciteta: {LTBLUE}{CARGO}
+STR_CAPACITY_MULT :{BLACK}Kapaciteta: {LTBLUE}{CARGO} (x{NUM})
+STR_013F_TOTAL_CAPACITY_TEXT :{BLACK}Skupna tovorna kapaciteta tega vlaka:
+STR_013F_TOTAL_CAPACITY :{LTBLUE}- {CARGO} ({SHORTCARGO})
+STR_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO} ({SHORTCARGO}) (x{NUM})
+STR_0140_NEW_GAME :{BLACK}Nova igra
+STR_0141_LOAD_GAME :{BLACK}Naloži igro
+STR_SINGLE_PLAYER :{BLACK}En igralec
+STR_MULTIPLAYER :{BLACK}Vec igralcev
+
+STR_64 :64
+STR_128 :128
+STR_256 :256
+STR_512 :512
+STR_1024 :1024
+STR_2048 :2048
+STR_MAPSIZE :{BLACK}Velikost mape:
+STR_BY :{BLACK}*
+STR_0148_GAME_OPTIONS :{BLACK}Možnosti
+
+STR_0150_SOMEONE :nekdo{SKIP}{SKIP}
+STR_0151_MAP_OF_WORLD :Zemljevid sveta
+STR_0152_TOWN_DIRECTORY :Imenik mest
+STR_0153_SUBSIDIES :Subvencije
+
+STR_UNITS_IMPERIAL :Imperialisticne
+STR_UNITS_METRIC :Metricne
+STR_UNITS_SI :SI
+
+STR_UNITS_VELOCITY_IMPERIAL :{COMMA} mph
+STR_UNITS_VELOCITY_METRIC :{COMMA} km/h
+STR_UNITS_VELOCITY_SI :{COMMA} m/s
+
+STR_UNITS_POWER_IMPERIAL :{COMMA}KM
+STR_UNITS_POWER_METRIC :{COMMA}KM
+STR_UNITS_POWER_SI :{COMMA}kW
+
+STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t
+STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg
+
+STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA} ton
+STR_UNITS_WEIGHT_LONG_METRIC :{COMMA} ton
+STR_UNITS_WEIGHT_LONG_SI :{COMMA} kg
+
+STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}gal
+STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}l
+STR_UNITS_VOLUME_SHORT_SI :{COMMA}m³
+
+STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA} galonov
+STR_UNITS_VOLUME_LONG_METRIC :{COMMA} litrov
+STR_UNITS_VOLUME_LONG_SI :{COMMA} m³
+
+STR_UNITS_FORCE_IMPERIAL :{COMMA}x10³ lbf
+STR_UNITS_FORCE_METRIC :{COMMA} ton sile
+STR_UNITS_FORCE_SI :{COMMA} kN
+
+############ range for menu starts
+STR_0154_OPERATING_PROFIT_GRAPH :Graf dobiÄka
+STR_0155_INCOME_GRAPH :Graf prihodkov
+STR_0156_DELIVERED_CARGO_GRAPH :Graf dostavljenega tovora
+STR_0157_PERFORMANCE_HISTORY_GRAPH :Graf zgodovine dela
+STR_0158_COMPANY_VALUE_GRAPH :Graf vrednosti podjetja
+STR_0159_CARGO_PAYMENT_RATES :Graf plaÄila za tovor
+STR_015A_COMPANY_LEAGUE_TABLE :Tabela lige podjetij
+STR_PERFORMANCE_DETAIL_MENU :Podrobna delavna ocena
+############ range for menu ends
+
+STR_015B_OPENTTD :{WHITE}O OpenTTD
+STR_015C_SAVE_GAME :Shrani igro
+STR_015D_LOAD_GAME :Naloži igro
+STR_015E_QUIT_GAME :Zapusti igro
+STR_015F_QUIT :Izhod
+STR_ABANDON_GAME_QUERY :{YELLOW}Ali ste prepriÄani, da želite zapustiti igro?
+STR_0161_QUIT_GAME :{WHITE}Zapusti igro
+STR_SORT_ORDER_TIP :{BLACK}Izberi nacin sortiranja (padajoce/narascujoce)
+STR_SORT_CRITERIA_TIP :{BLACK}Izberi kriterij za sortiranje
+STR_SORT_BY :{BLACK}Sortiraj po
+
+STR_SORT_BY_POPULATION :{BLACK}Populacija
+STR_SORT_BY_PRODUCTION :{BLACK}Produkcija
+STR_SORT_BY_TYPE :{BLACK}Tip
+STR_SORT_BY_TRANSPORTED :{BLACK}Preneseno
+STR_SORT_BY_NAME :{BLACK}Ime
+STR_SORT_BY_DROPDOWN_NAME :Ime
+STR_SORT_BY_DATE :{BLACK}Datum
+STR_SORT_BY_NUMBER :Stevilo
+STR_SORT_BY_PROFIT_LAST_YEAR :Profit zadnje leto
+STR_SORT_BY_PROFIT_THIS_YEAR :Profit to leto
+STR_SORT_BY_AGE :Starost
+STR_SORT_BY_RELIABILITY :Zanesljivost
+STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Skupna sposobnost po tipu tovora
+STR_SORT_BY_MAX_SPEED :Najvecja hitrost
+STR_SORT_BY_MODEL :Model
+STR_SORT_BY_VALUE :Vrednost
+STR_SORT_BY_FACILITY :Tip postaje
+STR_SORT_BY_WAITING :ÄŒakanje vrednosti tovora
+STR_SORT_BY_RATING_MAX :Ocene tovora
+STR_ENGINE_SORT_ENGINE_ID :ID motorja (klasiÄno urejanje)
+STR_ENGINE_SORT_COST :Cena
+STR_ENGINE_SORT_POWER :MoÄ
+STR_ENGINE_SORT_INTRO_DATE :Datum vstopa
+STR_ENGINE_SORT_RUNNING_COST :Stroški obratovanja
+STR_ENGINE_SORT_POWER_VS_RUNNING_COST :MoÄ/StroÅ¡ki obratovanja
+STR_ENGINE_SORT_CARGO_CAPACITY :Kapaciteta tovora
+STR_NO_WAITING_CARGO :{BLACK}Noben tovor ne Äaka
+STR_SELECT_ALL_FACILITIES :{BLACK}Izberi vse pripomoÄke
+STR_SELECT_ALL_TYPES :{BLACK}Izberi vse vrste tovora (vkljuÄno z nobenega Äakanja)
+STR_AVAILABLE_ENGINES_TIP :{BLACK}Prikaži seznam motorjev na voljo za ta tip vozila.
+
+############ range for months starts
+STR_0162_JAN :Jan
+STR_0163_FEB :Feb
+STR_0164_MAR :Mar
+STR_0165_APR :Apr
+STR_0166_MAY :Maj
+STR_0167_JUN :Jun
+STR_0168_JUL :Jul
+STR_0169_AUG :Avg
+STR_016A_SEP :Sep
+STR_016B_OCT :Okt
+STR_016C_NOV :Nov
+STR_016D_DEC :Dec
+############ range for months ends
+
+STR_016E :{TINYFONT}{STRING}{} {STRING}
+STR_016F :{TINYFONT}{STRING}{} {STRING}{}{NUM}
+STR_0170 :{TINYFONT}{STRING}-
+STR_0171_PAUSE_GAME :{BLACK}Pavza
+STR_0172_SAVE_GAME_ABANDON_GAME :{BLACK}Shrani igro, zapusti igro, izhod
+STR_0173_DISPLAY_LIST_OF_COMPANY :{BLACK}Prikaži seznam postaj podjetja
+STR_0174_DISPLAY_MAP :{BLACK}Prikaži zemljevid
+STR_0175_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Prikaži zemljevid, imenik mest
+STR_0176_DISPLAY_TOWN_DIRECTORY :{BLACK}Prikaži imenik mest
+STR_0177_DISPLAY_COMPANY_FINANCES :{BLACK}Prikaži finanÄne podatke podjetja
+STR_0178_DISPLAY_COMPANY_GENERAL :{BLACK}Prikaži splošne podatke podjetja
+STR_0179_DISPLAY_GRAPHS :{BLACK}Prikaži grafe
+STR_017A_DISPLAY_COMPANY_LEAGUE :{BLACK}Prikaži tabelo lige podjetij
+STR_017B_DISPLAY_LIST_OF_COMPANY :{BLACK}Prikaži seznam vlakov podjetja
+STR_017C_DISPLAY_LIST_OF_COMPANY :{BLACK}Prikaži seznam cestnih vozil podjetja
+STR_017D_DISPLAY_LIST_OF_COMPANY :{BLACK}Prikaži seznam ladij podjetja
+STR_017E_DISPLAY_LIST_OF_COMPANY :{BLACK}Prikaži seznam letal podjetja
+STR_017F_ZOOM_THE_VIEW_IN :{BLACK}Približaj pogled
+STR_0180_ZOOM_THE_VIEW_OUT :{BLACK}Oddalji pogled
+STR_0181_BUILD_RAILROAD_TRACK :{BLACK}Postavi železniške tire
+STR_0182_BUILD_ROADS :{BLACK}Zgradi ceste
+STR_0183_BUILD_SHIP_DOCKS :{BLACK}Zgradi pristaniÅ¡Äa
+STR_0184_BUILD_AIRPORTS :{BLACK}Zgradi letaliÅ¡Äa
+STR_0185_PLANT_TREES_PLACE_SIGNS :{BLACK}Posadi drevesa, postavi znake ipd.
+STR_0186_LAND_BLOCK_INFORMATION :{BLACK}Informacije o terenu
+STR_0187_OPTIONS :{BLACK}Možnosti
+STR_0188 :{BLACK}{SMALLUPARROW}
+STR_0189 :{BLACK}{SMALLDOWNARROW}
+STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Ne morem spremeniti intervala servisiranja ...
+STR_018B_CLOSE_WINDOW :{BLACK}Zapri okno
+STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Naslov okna - primi in vleci, da premakneš okno
+STR_STICKY_BUTTON :{BLACK}Oznaci to okno za nezapirljivo z 'Zapri vsa okna' tipko
+STR_RESIZE_BUTTON :{BLACK}Klikni in dragaj to, da zmanjsas okno
+STR_SAVELOAD_HOME_BUTTON :{BLACK}Klikni tukaj za skok na mapo shrani/naloži
+STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Podri zgradbe itd. na kvadratku zemlje
+STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Znižaj rob terena
+STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Zvišaj rob terena
+STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Drsnik - premakne seznam gor/dol
+STR_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Skrol-bar - skrolaj seznam levo/desno
+STR_0191_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Pokaži naÄrt terena na zemljevidu
+STR_0192_SHOW_VEHICLES_ON_MAP :{BLACK}Pokaži vozila na zemljevidu
+STR_0193_SHOW_INDUSTRIES_ON_MAP :{BLACK}Pokaži industrije na zemljevidu
+STR_0194_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Pokaži transportne poti na zemljevidu
+STR_0195_SHOW_VEGETATION_ON_MAP :{BLACK}Pokaži vegetacijo na zemljevidu
+STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Pokaži lastnike terena na zemljevidu
+STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}VkljuÄi/izkljuÄi imena mest na zemljevidu
+STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Prihodki to leto: {CURRENCY} (prejšnje leto: {CURRENCY})
+
+############ range for service numbers starts
+STR_AGE :{COMMA} let{P o ""} ({COMMA})
+STR_AGE_RED :{RED}{COMMA} let{P o ""} ({COMMA})
+############ range for service numbers ends
+
+STR_019C_ROAD_VEHICLE :Cestno vozilo
+STR_019D_AIRCRAFT :Letalo
+STR_019E_SHIP :Ladja
+STR_019F_TRAIN :Vlak
+STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} postaja staro
+STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} postaja zelo staro
+STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} postaja zelo staro in nujno potrebuje zamenjavo
+STR_01A3_LAND_AREA_INFORMATION :{WHITE}Informacije o zemljiÅ¡Äu
+STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Cena za ÄiÅ¡Äenje: {LTBLUE}N/A
+STR_01A5_COST_TO_CLEAR :{BLACK}Cena za ÄiÅ¡Äenje: {LTBLUE}{CURRENCY}
+STR_01A6_N_A :Ni na voljo
+STR_01A7_OWNER :{BLACK}Lastnik: {LTBLUE}{STRING}
+STR_01A8_LOCAL_AUTHORITY :{BLACK}Lokalna oblast: {LTBLUE}{STRING}
+STR_01A9_NONE :NihÄe
+STR_01AA_NAME :{BLACK}Ime
+STR_01AB :{BLACK}{TINYFONT}{STRING}
+
+############ range for days starts
+STR_01AC_1ST :1.
+STR_01AD_2ND :2.
+STR_01AE_3RD :3.
+STR_01AF_4TH :4.
+STR_01B0_5TH :5.
+STR_01B1_6TH :6.
+STR_01B2_7TH :7.
+STR_01B3_8TH :8.
+STR_01B4_9TH :9.
+STR_01B5_10TH :10.
+STR_01B6_11TH :11.
+STR_01B7_12TH :12.
+STR_01B8_13TH :13.
+STR_01B9_14TH :14.
+STR_01BA_15TH :15.
+STR_01BB_16TH :16.
+STR_01BC_17TH :17.
+STR_01BD_18TH :18.
+STR_01BE_19TH :19.
+STR_01BF_20TH :20.
+STR_01C0_21ST :21.
+STR_01C1_22ND :22.
+STR_01C2_23RD :23.
+STR_01C3_24TH :24.
+STR_01C4_25TH :25.
+STR_01C5_26TH :26.
+STR_01C6_27TH :27.
+STR_01C7_28TH :28.
+STR_01C8_29TH :29.
+STR_01C9_30TH :30.
+STR_01CA_31ST :31.
+############ range for days ends
+
+STR_01CB :{TINYFONT}{COMMA}
+
+STR_01CE_CARGO_ACCEPTED :{BLACK}Tovor sprejet: {LTBLUE}
+
+STR_01D1_8 :({COMMA}/8 {STRING})
+STR_01D2_JAZZ_JUKEBOX :{WHITE}Jazz Jukebox
+STR_01D3_SOUND_MUSIC :Zvok/glasba
+STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Prikaži okno za zvok/glasbo
+STR_01D5_ALL :{TINYFONT}Vsi
+STR_01D6_OLD_STYLE :{TINYFONT}Star stil
+STR_01D7_NEW_STYLE :{TINYFONT}Novi stil
+STR_01D8_EZY_STREET :{TINYFONT}Ezy Street
+STR_01D9_CUSTOM_1 :{TINYFONT}Po meri 1
+STR_01DA_CUSTOM_2 :{TINYFONT}Po meri 2
+STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Glasnost glasbe
+STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Glasnost zvokov
+STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MIN ' ' ' ' ' ' MAX
+STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}SkoÄi na prejÅ¡njo skladbo v izboru
+STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}PreskoÄi na naslednjo skladbo v izboru
+STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Ustavi glasbo
+STR_01E1_START_PLAYING_MUSIC :{BLACK}Predvajaj glasbo
+STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Premikaj drsnike za nastavitev glasnosti glasbe in zvokov
+STR_01E3 :{DKGREEN}{TINYFONT}--
+STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA}
+STR_01E5 :{DKGREEN}{TINYFONT}{COMMA}
+STR_01E6 :{DKGREEN}{TINYFONT}------
+STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}"
+STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Skladba{SETX 88}Naslov
+STR_01E9_SHUFFLE :{TINYFONT}Zmešaj
+STR_01EA_PROGRAM :{TINYFONT}{BLACK}Program
+STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Izbor glasbenega programa
+STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}"
+STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}"
+STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Seznam skladb
+STR_01EF_PROGRAM :{TINYFONT}{BLACK}Program - '{STRING}'
+STR_01F0_CLEAR :{TINYFONT}{BLACK}Zbriši
+STR_01F1_SAVE :{TINYFONT}{BLACK}Shrani
+STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Trenutni program glasbe
+STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Izberi glasbeni program 'vse skladbe'
+STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Izberi glasbeni program 'stari stil'
+STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Izberi glasbeni program 'novi stil'
+STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Izberi glasbeni program 'po meri 1'
+STR_01F7_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Izberi glasbeni program 'po meri 2'
+STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Zbriši trenutni glasbeni program (samo po meri 1 in 2)
+STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Shrani glasbene nastavitve
+STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Kliknite na skladbo, Äe jo želite dodati na trenutni program (samo po meri 1 in 2)
+STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Kliknite na skladbo, Äe jo želite odstraniti iz programa (samo Poljubno1 ali Poljubno2)
+STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Preklapljaj zmeÅ¡an program vkljuÄeno/izkljuÄeno
+STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Pokaži okno z izborom glasbe
+STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Kliknite na storitev za pogled na industrijo/mesto
+STR_01FE_DIFFICULTY :{BLACK}Težavnost ({STRING})
+STR_01FF :{TINYFONT}{BLACK}{DATE_LONG}
+STR_0200_LAST_MESSAGE_NEWS_REPORT :Zadnje sporoÄilo/novica
+STR_0201_MESSAGE_SETTINGS :Nastavitve sporoÄil
+STR_MESSAGE_HISTORY_MENU :Zgodovina sporoÄil
+STR_0203_SHOW_LAST_MESSAGE_NEWS :{BLACK}Prikaži zadnje sporoÄilo/novico, prikaži možnosti sporoÄil
+STR_0204_MESSAGE_OPTIONS :{WHITE}Možnosti SporoÄil
+STR_0205_MESSAGE_TYPES :{BLACK}Tipi sporoÄil:
+STR_0206_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Prihod prvega vozila na igralÄevo postajo
+STR_0207_ARRIVAL_OF_FIRST_VEHICLE :{YELLOW}Prihod prvega vozila na nasprotnikovo postajo
+STR_0208_ACCIDENTS_DISASTERS :{YELLOW}NesreÄe / katastrofe
+STR_0209_COMPANY_INFORMATION :{YELLOW}Informacije o podjetju
+STR_020A_ECONOMY_CHANGES :{YELLOW}Ekonomske spremembe
+STR_020B_ADVICE_INFORMATION_ON_PLAYER :{YELLOW}Nasveti / informacije o igralÄevem vozilu
+STR_020C_NEW_VEHICLES :{YELLOW}Odkrito novo vozilo
+STR_020D_CHANGES_OF_CARGO_ACCEPTANCE :{YELLOW}Spremebe v sprejemanju tovora
+STR_020E_SUBSIDIES :{YELLOW}Subvencije
+STR_020F_GENERAL_INFORMATION :{YELLOW}Splošne Informacije
+STR_MESSAGES_ALL :{YELLOW}Nastavi prikaz vseh sporoÄil na: IzkljuÄen / Povzetek / Poln
+STR_MESSAGE_SOUND :{YELLOW}Zaigraj zvok ob povzetku novega sporoÄila
+STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO :{WHITE} ... predaleÄ od prejÅ¡njega cilja
+STR_0211_TOP_COMPANIES_WHO_REACHED :{BIGFONT}{BLACK}Najboljša podjetja, ki so dosegla {NUM}{}({STRING} stopnjo)
+STR_TOP_COMPANIES_NETWORK_GAME :{BIGFONT}{BLACK}Seznam najboljših podjetij v {NUM}
+STR_0212 :{BIGFONT}{COMMA}.
+STR_0213_BUSINESSMAN :Poslovnež
+STR_0214_ENTREPRENEUR :Podjetnik
+STR_0215_INDUSTRIALIST :Industrijalec
+STR_0216_CAPITALIST :Kapitalist
+STR_0217_MAGNATE :Magnat
+STR_0218_MOGUL :Vladar
+STR_0219_TYCOON_OF_THE_CENTURY :Velekapitalist stoletja
+STR_HIGHSCORE_NAME :{BIGFONT}{PLAYERNAME}, {COMPANY}
+STR_HIGHSCORE_STATS :{BIGFONT}'{STRING}' ({COMMA})
+STR_021B_ACHIEVES_STATUS :{BLACK}{BIGFONT}{COMPANY} doseže naslov '{STRING}'!
+STR_021C_OF_ACHIEVES_STATUS :{WHITE}{BIGFONT}{PLAYERNAME} iz podjetja {COMPANY} je dosegel naslov '{STRING}'!
+STR_021F :{BLUE}{COMMA}
+STR_0220_CREATE_SCENARIO :{BLACK}Ustvari Scenarij
+STR_0221_OPENTTD :{YELLOW}OpenTTD
+STR_0222_SCENARIO_EDITOR :{YELLOW}Urejevalnik scenarijev
+STR_0223_LAND_GENERATION :{WHITE}Generator terena
+STR_0224 :{BLACK}{UPARROW}
+STR_0225 :{BLACK}{DOWNARROW}
+STR_0226_RANDOM_LAND :{BLACK}NakljuÄni teren
+STR_0227_RESET_LAND :{BLACK}Ponastavi teren
+STR_0228_INCREASE_SIZE_OF_LAND_AREA :{BLACK}PoveÄaj obmoÄje za nižanje/viÅ¡anje terena
+STR_0229_DECREASE_SIZE_OF_LAND_AREA :{BLACK}ZmanjÅ¡aj obmoÄje za nižanje/viÅ¡anje terena
+STR_022A_GENERATE_RANDOM_LAND :{BLACK}Zgeneriraj nakljuÄni teren
+STR_022B_RESET_LANDSCAPE :{BLACK}Ponastavi pokrajino
+STR_022C_RESET_LANDSCAPE :{WHITE}Ponastavi pokrajino
+STR_LOAD_GAME_HEIGHTMAP :{WHITE}Uporabi višinsko karto
+STR_LOAD_SCEN_HEIGHTMAP :{BLACK}Uporabi višinsko karto
+STR_022D_ARE_YOU_SURE_YOU_WANT_TO :{WHITE}Ali ste prepriÄani, da želite ponastaviti pokrajino?
+STR_022E_LANDSCAPE_GENERATION :{BLACK}Generator pokrajine
+STR_022F_TOWN_GENERATION :{BLACK}Generator mest
+STR_0230_INDUSTRY_GENERATION :{BLACK}Generator industrije
+STR_0231_ROAD_CONSTRUCTION :{BLACK}Gradnja cest
+STR_0233_TOWN_GENERATION :{WHITE}Generator mest
+STR_0234_NEW_TOWN :{BLACK}Novo mesto
+STR_0235_CONSTRUCT_NEW_TOWN :{BLACK}Zgradi novo mesto
+STR_0236_CAN_T_BUILD_TOWN_HERE :{WHITE}Ne morete zgraditi mesta tukaj ...
+STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE} ... preblizu roba zemljevida
+STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE} ... preblizu drugemu mestu
+STR_0239_SITE_UNSUITABLE :{WHITE} ... neprimerna lokacija
+STR_023A_TOO_MANY_TOWNS :{WHITE} ... preveliko Å¡tevilo mest
+STR_CANNOT_GENERATE_TOWN :{WHITE}Ni mogoÄe zgraditi mest
+STR_NO_SPACE_FOR_TOWN :{WHITE} ... ni veÄ prostora na zemljevidu
+STR_023B_INCREASE_SIZE_OF_TOWN :{BLACK}PoveÄaj velikost mesta
+STR_023C_EXPAND :{BLACK}Razširi
+STR_023D_RANDOM_TOWN :{BLACK}NakljuÄno mesto
+STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION :{BLACK}Zgradi mesto na nakljuÄni lokaciji
+STR_023F_INDUSTRY_GENERATION :{WHITE}Generator indrustrij
+STR_0240_COAL_MINE :{BLACK}Rudnik Premoga
+STR_0241_POWER_STATION :{BLACK}Termoelektrarna
+STR_0242_SAWMILL :{BLACK}Žaga
+STR_0243_FOREST :{BLACK}Gozd
+STR_0244_OIL_REFINERY :{BLACK}Naftna rafinerija
+STR_0245_OIL_RIG :{BLACK}Naftne vrtine
+STR_0246_FACTORY :{BLACK}Tovarna
+STR_0247_STEEL_MILL :{BLACK}Jeklarna
+STR_0248_FARM :{BLACK}Kmetija
+STR_0249_IRON_ORE_MINE :{BLACK}Rudnik železa
+STR_024A_OIL_WELLS :{BLACK}Naftni Vrelci
+STR_024B_BANK :{BLACK}Banka
+STR_024C_PAPER_MILL :{BLACK}Papirnica
+STR_024D_FOOD_PROCESSING_PLANT :{BLACK}Predelava živil
+STR_024E_PRINTING_WORKS :{BLACK}Tiskarna
+STR_024F_GOLD_MINE :{BLACK}Rudnik Zlata
+STR_0250_LUMBER_MILL :{BLACK}Žaga
+STR_0251_FRUIT_PLANTATION :{BLACK}Sadovnjak
+STR_0252_RUBBER_PLANTATION :{BLACK}Plantaža kavÄuka
+STR_0253_WATER_SUPPLY :{BLACK}Vodni izvir
+STR_0254_WATER_TOWER :{BLACK}Vodovodni Stolp
+STR_0255_DIAMOND_MINE :{BLACK}Rudnik Diamantov
+STR_0256_COPPER_ORE_MINE :{BLACK}Rudnik bakra
+STR_0257_COTTON_CANDY_FOREST :{BLACK}Gozd sladkorne pene
+STR_0258_CANDY_FACTORY :{BLACK}Tovarna slaÅ¡Äic
+STR_0259_BATTERY_FARM :{BLACK}Farma baterij
+STR_025A_COLA_WELLS :{BLACK}Vrelci Cockte
+STR_025B_TOY_SHOP :{BLACK}Trgovina z igraÄami
+STR_025C_TOY_FACTORY :{BLACK}Tovarna IgraÄ
+STR_025D_PLASTIC_FOUNTAINS :{BLACK}Vodnjaki plastike
+STR_025E_FIZZY_DRINK_FACTORY :{BLACK}Tovarna gaziranih pijaÄ
+STR_025F_BUBBLE_GENERATOR :{BLACK}Generator mehurÄkov
+STR_0260_TOFFEE_QUARRY :{BLACK}Jama karamele
+STR_0261_SUGAR_MINE :{BLACK}Rudnik sladkorja
+STR_0262_CONSTRUCT_COAL_MINE :{BLACK}Zgradi rudnik premoga
+STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Zgradi termoelektrarno
+STR_0264_CONSTRUCT_SAWMILL :{BLACK}Zgradi žago
+STR_0265_PLANT_FOREST :{BLACK}Posadi gozd
+STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Zgradi naftno rafinerijo
+STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Zgradi naftno ploÅ¡Äad (Lahko je zgrajena samo blizu robu zemljevida)
+STR_0268_CONSTRUCT_FACTORY :{BLACK}Zgradi tovarno
+STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Zgradi jeklarno
+STR_026A_CONSTRUCT_FARM :{BLACK}Zgradi kmetijo
+STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Zgradi rudnik železa
+STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Zgradi naftne vrelce
+STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Zgradi banko (Lahko je zgrajena samo v mestih s populacijo veÄjo od 1200 ljudi)
+STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Zgradi papirnico
+STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Zgradi tovarno predelave hrane
+STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Zgradi tiskarno
+STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Zgradi rudnik zlata
+STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Zgradi banko (Samo v mestih)
+STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Zgradi žago (za zmanjševanje deževnega gozda in predelavo lesa)
+STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Zgradi sadovnjak
+STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Zgradi plantažo kavÄuka
+STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Zgradi vodno zajetje
+STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Zgradi vodovodni stolp (Samo v mestih)
+STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Zgradi rudnik diamantov
+STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Zgradi rudnik bakra
+STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Posadi gozd sladkorne pene
+STR_027B_CONSTRUCT_CANDY_FACTORY :{BLACK}Zgradi tovarno slaÅ¡Äic
+STR_027C_CONSTRUCT_BATTERY_FARM :{BLACK}Zgradi farmo baterij
+STR_027D_CONSTRUCT_COLA_WELLS :{BLACK}Zgradi vrelce Cockte
+STR_027E_CONSTRUCT_TOY_SHOP :{BLACK}Zgradi trgovino z igraÄami
+STR_027F_CONSTRUCT_TOY_FACTORY :{BLACK}Zgradi tovarno igraÄ
+STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS :{BLACK}Zgradi vodnjake plastike
+STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY :{BLACK}Zgradi tovarno gaziranih pijaÄ
+STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Zgradi generator mehurÄkov
+STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Zgradi jamo karamele
+STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Zgradi rudnik sladkorja
+STR_0285_CAN_T_BUILD_HERE :{WHITE}Tukaj ni možno zgraditi {STRING}
+STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE} ... najprej je potrebno zgraditi mesto
+STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE} ... samo ena dovoljena v mestu
+STR_0288_PLANT_TREES :{BLACK}Posadi drevesa
+STR_0289_PLACE_SIGN :{BLACK}Postavi znak
+STR_028A_RANDOM_TREES :{BLACK}NakljuÄna drevesa
+STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Posadi drevesa nakljuÄno po ozemlju
+STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Ustvari kamnita obmoÄja nakljuÄno po ozemlju
+STR_028D_PLACE_LIGHTHOUSE :{BLACK}Postavi svetilnik
+STR_028E_PLACE_TRANSMITTER :{BLACK}Postavi oddajnik
+STR_028F_DEFINE_DESERT_AREA :{BLACK}DoloÄi obmoÄja puÅ¡Äave.{}Pritisnite in držite CTRL za odstranitev
+STR_CREATE_LAKE :{BLACK}DoloÄi vodno obmoÄje.{}Voda bo poplavila okolico, Äe bo na viÅ¡ini morja
+STR_0290_DELETE :{BLACK}Izbriši
+STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Popolnoma izbriši mesto
+STR_0292_SAVE_SCENARIO :Shrani scenarij
+STR_0293_LOAD_SCENARIO :Naloži scenarij
+STR_0294_QUIT_EDITOR :Izhod iz urejevalnika
+STR_0295 :
+STR_0296_QUIT :Izhod
+STR_0297_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Shrani, naloži scenarij, zapusti urejevalnik scenarijev, izhod
+STR_0298_LOAD_SCENARIO :{WHITE}Naloži scenarij
+STR_0299_SAVE_SCENARIO :{WHITE}Shrani scenarij
+STR_029A_PLAY_SCENARIO :{BLACK}Igraj scenarij
+STR_PLAY_HEIGHTMAP :{BLACK}Igraj višinsko karto
+STR_PLAY_HEIGHTMAP_HINT :{BLACK}ZaÄni novo igro z uporabo viÅ¡inske karte za pokrajino
+STR_QUIT_SCENARIO_QUERY :{YELLOW}Ali ste prepriÄani, da želite zapustiti ta scenarij?
+STR_029C_QUIT_EDITOR :{WHITE}Izhod iz urejevalnika
+STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE} ... lahko zgrajen samo v mestih s populacijo 1200 ali veÄ ljudi
+STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Premakni zaÄetni datum za 1 leto nazaj
+STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Premakni zaÄetni datum za 1 leto naprej
+STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE} ... oba prikljuÄka mostu morata biti na kopnem
+STR_02A1_SMALL :{BLACK}Majhno
+STR_02A2_MEDIUM :{BLACK}Srednje
+STR_02A3_LARGE :{BLACK}Veliko
+STR_02A4_SELECT_TOWN_SIZE :{BLACK}Izberite velikost mesta
+STR_02A5_TOWN_SIZE :{YELLOW}Velikost mesta:
+
+STR_02B6 :{STRING} - {STRING}
+STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS :{BLACK}Prikaži zadnje sporoÄilo oziroma novico
+STR_OFF :IzkljuÄeno
+STR_SUMMARY :Povzetek
+STR_FULL :Polno
+STR_02BA :{SILVER}- - {COMPANY} - -
+STR_02BB_TOWN_DIRECTORY :Imenik mest
+STR_02BC_VEHICLE_DESIGN_NAMES :{BLACK}Imena oblike vozil
+STR_02BD :{BLACK}{STRING}
+STR_02BE_DEFAULT :Privzeto
+STR_02BF_CUSTOM :Po meri
+STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Shrani poljubna imena
+STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Izbira imen oblik vozil
+STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Shrani poljubna imena oblik vozil
+
+STR_CHECKMARK :{CHECKMARK}
+############ range for menu starts
+STR_02C3_GAME_OPTIONS :Možnosti igre
+STR_02C5_DIFFICULTY_SETTINGS :Nastavitve težavnosti
+STR_02C7_CONFIG_PATCHES :Urejanje popravkov
+STR_NEWGRF_SETTINGS :NewGRF nastavitve
+STR_02CA_TOWN_NAMES_DISPLAYED :{SETX 12}Imena mest prikazana
+STR_02CC_STATION_NAMES_DISPLAYED :{SETX 12}Imena postaj prikazana
+STR_02CE_SIGNS_DISPLAYED :{SETX 12}SporoÄila prikazana
+STR_WAYPOINTS_DISPLAYED2 :{SETX 12}Smerokazi prikazani
+STR_02D0_FULL_ANIMATION :{SETX 12}Polne animacije
+STR_02D2_FULL_DETAIL :{SETX 12}Vse podrobnosti
+STR_02D4_TRANSPARENT_BUILDINGS :{SETX 12}Prosojne stavbe
+STR_TRANSPARENT_SIGNS :{SETX 12}Prosojni napisi postaj
+############ range ends here
+
+############ range for menu starts
+STR_02D5_LAND_BLOCK_INFO :Informacije o terenu
+STR_02D6 :
+STR_CONSOLE_SETTING :Vklopi/Izklopi konzolo
+STR_02D7_SCREENSHOT_CTRL_S :Zajemi sliko (Ctrl-S)
+STR_02D8_GIANT_SCREENSHOT_CTRL_G :Zajemi celostno slika (Ctrl-G)
+STR_02D9_ABOUT_OPENTTD :O 'OpenTTD'
+############ range ends here
+
+STR_02DB_OFF :{BLACK}IzkljuÄeno
+STR_02DA_ON :{BLACK}VkljuÄeno
+STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Prikaži subvencije
+STR_02DD_SUBSIDIES :Subvencije
+STR_02DE_MAP_OF_WORLD :Zemljevid sveta
+STR_EXTRA_VIEW_PORT :Dodaten pogled
+STR_SIGN_LIST :Seznam napisov
+STR_02DF_TOWN_DIRECTORY :Imenik mest
+STR_TOWN_POPULATION :{BLACK}Svetovna populacija: {COMMA}
+STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Pogled {COMMA}
+STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Kopiraj na pogled
+
+STR_02E0_CURRENCY_UNITS :{BLACK}Valute
+STR_02E1 :{BLACK}{SKIP}{STRING}
+STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Izbira valut
+STR_MEASURING_UNITS :{BLACK}Merske enote
+STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING}
+STR_02E6_ROAD_VEHICLES :{BLACK}Cestna vozila
+STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Izberite smer vožnje cestnih vozil
+STR_02E9_DRIVE_ON_LEFT :Vožnja po levi
+STR_02EA_DRIVE_ON_RIGHT :Vožnja po desni
+STR_02EB_TOWN_NAMES :{BLACK}Imena mest
+STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Izberite slog imena mest
+
+STR_02F4_AUTOSAVE :{BLACK}Shrani
+STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING}
+STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Izberite Äasovni interval samodejnega shranjevanja igre
+STR_02F7_OFF :Izklopljeno
+STR_02F8_EVERY_3_MONTHS :Vsake 3 mesece
+STR_02F9_EVERY_6_MONTHS :Vsakih 6 mesecev
+STR_02FA_EVERY_12_MONTHS :Vsakih 12 mesecev
+STR_02FB_START_A_NEW_GAME :{BLACK}ZaÄni novo igro
+STR_02FC_LOAD_A_SAVED_GAME :{BLACK}Naloži shranjeno igro
+STR_02FE_CREATE_A_CUSTOMIZED_GAME :{BLACK}Ustvari poljubni svet/scenarij
+STR_02FF_SELECT_SINGLE_PLAYER_GAME :{BLACK}Izberi igro za enega igralca
+STR_0300_SELECT_MULTIPLAYER_GAME :{BLACK}Izberi igro za 2-8 igralcev
+STR_0301_DISPLAY_GAME_OPTIONS :{BLACK}Prikaži možnosti igre
+STR_0302_DISPLAY_DIFFICULTY_OPTIONS :{BLACK}Prikaži nastavitve težavnosti
+STR_0303_START_A_NEW_GAME_USING :{BLACK}ZaÄni novo igro po scenariju
+STR_0304_QUIT :{BLACK}Izhod
+STR_0305_QUIT_OPENTTD :{BLACK}Izhod iz 'OpenTTD'
+STR_0307_OPENTTD :{WHITE}OpenTTD {REV}
+STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE} ... samo v mestih
+STR_030E_SELECT_TEMPERATE_LANDSCAPE :{BLACK}Izberi obiÄajen slog ozemlja
+STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE :{BLACK}Izberi stepski slog ozemlja
+STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE :{BLACK}Izberi subtropski slog ozemlja
+STR_0311_SELECT_TOYLAND_LANDSCAPE :{BLACK}Izberi ozemlje sveta igraÄ
+STR_0312_FUND_CONSTRUCTION_OF_NEW :{BLACK}Financiraj izgradnjo nove industrije
+
+############ range for menu starts
+STR_INDUSTRY_DIR :Imenik tovarn
+STR_0313_FUND_NEW_INDUSTRY :Odpri novo industrijo
+############ range ends here
+
+STR_0314_FUND_NEW_INDUSTRY :{WHITE}Odpri novo industrijo
+STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE} ... gradnja mogoÄa samo v mestih
+STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE} ... gradnja mogoÄa samo v obmoÄju deževnega gozda
+STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE} ... gradnja mogoÄa samo v puÅ¡Äavi
+STR_0319_PAUSED :{YELLOW}* * ZAUSTAVLJENO * *
+
+STR_031B_SCREENSHOT_SUCCESSFULLY :{WHITE}Slika je uspešno zajeta kot {} '{STRING}'
+STR_031C_SCREENSHOT_FAILED :{WHITE}Zajemanje slike je {}SPODLETELO!!!
+
+STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Kupi zemljiÅ¡Äe za prihodnjo rabo
+STR_032F_AUTOSAVE :{RED}Samodejno shranjevanje
+STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Izberi 'Ezy Street' glasbeni program
+
+STR_0335_6 :{BLACK}6
+STR_0336_7 :{BLACK}7
+
+############ start of townname region
+STR_TOWNNAME_ORIGINAL_ENGLISH :Angleska (Originalna)
+STR_TOWNNAME_FRENCH :Francoska
+STR_TOWNNAME_GERMAN :Nemška
+STR_TOWNNAME_ADDITIONAL_ENGLISH :Angleska (Dodatna)
+STR_TOWNNAME_LATIN_AMERICAN :Latinsko-Ameriska
+STR_TOWNNAME_SILLY :Neumna
+STR_TOWNNAME_SWEDISH :Svedska
+STR_TOWNNAME_DUTCH :Nizozemska
+STR_TOWNNAME_FINNISH :Finska
+STR_TOWNNAME_POLISH :Poljska
+STR_TOWNNAME_SLOVAKISH :Slovaska
+STR_TOWNNAME_HUNGARIAN :Madzarska
+STR_TOWNNAME_AUSTRIAN :Avstrijska
+STR_TOWNNAME_ROMANIAN :Romunska
+STR_TOWNNAME_CZECH :Ceska
+STR_TOWNNAME_SWISS :Svicarska
+STR_TOWNNAME_DANISH :Danska
+############ end of townname region
+
+STR_CURR_GBP :Funt (£)
+STR_CURR_USD :Dolar ($)
+STR_CURR_EUR :Euro (€)
+STR_CURR_YEN :Jen (Â¥)
+STR_CURR_ATS :Avstrijski Siling (ATS)
+STR_CURR_BEF :Belgijski Frank (BEF)
+STR_CURR_CHF :Svicarski Frank (CHF)
+STR_CURR_CZK :Ceska Krona (CZK)
+STR_CURR_DEM :Nemska Marka (DEM)
+STR_CURR_DKK :Danska Krona (DKK)
+STR_CURR_ESP :Pezeta (ESP)
+STR_CURR_FIM :Finska Marka (FIM)
+STR_CURR_FRF :Frank (FRF)
+STR_CURR_GRD :Grska Drahma (GRD)
+STR_CURR_HUF :Madzarski Forint (HUF)
+STR_CURR_ISK :Islandska Krona (ISK)
+STR_CURR_ITL :Italijanska Lira (ITL)
+STR_CURR_NLG :Nizozemski Gulden (NLG)
+STR_CURR_NOK :Norveska Krona (NOK)
+STR_CURR_PLN :Poljski Zlot (PLN)
+STR_CURR_ROL :Romunski Lev (ROL)
+STR_CURR_RUR :Ruski Rubelj (RUR)
+STR_CURR_SEK :Svedska Krona (SEK)
+
+STR_CURR_CUSTOM :Poljubno...
+
+STR_OPTIONS_LANG :{BLACK}Jezik
+
+
+
+
+STR_AUTOSAVE_1_MONTH :Vsak mesec
+STR_AUTOSAVE_FAILED :{WHITE}Samodejno shranjevanje spodletelo
+
+STR_MONTH_JAN :Januar
+STR_MONTH_FEB :Februar
+STR_MONTH_MAR :Marec
+STR_MONTH_APR :April
+STR_MONTH_MAY :Maj
+STR_MONTH_JUN :Junij
+STR_MONTH_JUL :Julij
+STR_MONTH_AUG :Avgust
+STR_MONTH_SEP :September
+STR_MONTH_OCT :Oktober
+STR_MONTH_NOV :November
+STR_MONTH_DEC :December
+
+
+STR_BAGS :vreÄ
+STR_TONS :tone
+
+
+STR_CANT_SHARE_ORDER_LIST :{WHITE}Ni mogoÄe deliti navodil ...
+STR_CANT_COPY_ORDER_LIST :{WHITE}Ni mogoÄe skopirati navodil ...
+
+STR_TRAIN_IS_LOST :{WHITE}Vlak {COMMA} se je izgubil
+STR_TRAIN_IS_UNPROFITABLE :{WHITE}Vlak {COMMA} je imel {CURRENCY} lansko leto
+
+# Start of order review system.
+# DON'T ADD OR REMOVE LINES HERE
+STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Vlak {COMMA} ima premalo narocil na svojem seznamu
+STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}Vlak {COMMA} ima podvojena narocila
+STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}Vlak {COMMA} ima nepravilno zaporedje narocil
+STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}Letalo {COMMA} ima premalo ukazov v navodilih
+STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}Letalo {COMMA} ima niÄen ukaz
+STR_AIRCRAFT_HAS_DUPLICATE_ENTRY :{WHITE}Letalo {COMMA} ima podvojene ukaze
+STR_AIRCRAFT_HAS_INVALID_ENTRY :{WHITE}Letalo {COMMA} ima neveljavne postaje v navodilih
+# end of order system
+
+STR_TRAIN_AUTORENEW_FAILED :{WHITE}Avtomatska zamenjava je spodletela na vlaku {COMMA} (denarni problemi)
+STR_AIRCRAFT_AUTORENEW_FAILED :{WHITE}Samoprenova neuspela na letalu {COMMA} (omejitev z denarjem)
+STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}Vlak {COMMA} je predolg po zamenjavi
+
+STR_CONFIG_PATCHES :{BLACK}Nastavitve popravkov
+
+STR_CONFIG_PATCHES_OFF :Izklopi
+STR_CONFIG_PATCHES_ON :Vklopi
+
+
+
+
+
+
+
+
+
+
+STR_CONFIG_PATCHES_AI :{BLACK}Tekmeci
+
+STR_CONFIG_PATCHES_DISABLED :dizejblano
+STR_CONFIG_PATCHES_INT32 :{NUM}
+STR_CONFIG_PATCHES_CURRENCY :{CURRENCY}
+
+
+STR_TEMPERATE_LANDSCAPE :Zmerno podnebje
+STR_TOYLAND_LANDSCAPE :Igracarsko pokrajina
+
+STR_CHEATS :{WHITE}Goljufije
+STR_CHEATS_TIP :{BLACK}Kljukice kažejo, Äe so bile goljufije že kdaj uporabljene
+STR_CHEATS_WARNING :{BLACK}Pozor! Nameravate izdati svoje tekmece. Tako sramotno dejanje bo zapomnjeno za vselej.
+STR_CHEAT_MONEY :{LTBLUE}PoveÄaj denar za {CURRENCY64}
+STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Igra se kot igralec: {ORANGE}{COMMA}
+STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Čarobni buldožer (odstrani tovarne, neodstranljive objekte): {ORANGE}{STRING}
+STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Tuneli se lahko križajo pod zemljo: {ORANGE}{STRING}
+STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Zgrajeno med pavzo: {ORANGE}{STRING}
+STR_CHEAT_NO_JETCRASH :{LTBLUE}Reaktivci ne bodo strmoglavili (pogostokrat) na malih letaliÅ¡Äih: {ORANGE} {STRING}
+STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Spreminjanje klime: {ORANGE} {STRING}
+STR_CHEAT_CHANGE_DATE :{LTBLUE}Spremeni datum: {ORANGE} {DATE_SHORT}
+STR_CHEAT_SETUP_PROD :{LTBLUE}OmogoÄi spreminjanje vrednosti produktov: {ORANGE}{STRING}
+
+
+
+STR_WAYPOINTNAME_CITY :Smerokaz {TOWN}
+STR_WAYPOINTNAME_CITY_SERIAL :Smerokaz {TOWN} #{COMMA}
+
+STR_WAYPOINT :{WHITE}Smerokaz
+STR_WAYPOINT_GRAPHICS_TIP :{BLACK}Izberi vrsto smerokaza
+
+STR_WAYPOINT_VIEWPORT :{WHITE}{WAYPOINT}
+STR_WAYPOINT_VIEWPORT_TINY :{TINYFONT}{WHITE}{WAYPOINT}
+STR_WAYPOINT_RAW :{WAYPOINT}
+
+STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Ni mogoÄe preimenovati kažipota ...
+STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Ni mogoÄe postaviti kažipotov tukaj ...
+STR_CANT_REMOVE_TRAIN_WAYPOINT :{WHITE}Ni mogoÄe odstraniti kažipota tukaj ...
+
+STR_BUILD_AUTORAIL_TIP :{BLACK}Gradi železnico s pomoÄjo Samodejne gradnje
+
+
+STR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Ni mogoÄe zgraditi industrij ...
+
+
+
+
+STR_CANT_BUILD_CANALS :{WHITE}Ni mogoÄe zgraditi kanalov tukaj ...
+STR_BUILD_CANALS_TIP :{BLACK}Gradnja kanalov. CTRL+klik za postavitev morskih kvadratkov (samo na nadmorski višini morja)
+
+STR_CANT_BUILD_LOCKS :{WHITE}Ni mogoÄe zgraditi zapornic tukaj ...
+STR_BUILD_LOCKS_TIP :{BLACK}Gradnja zapornic
+
+STR_BUOY_IS_IN_USE :{WHITE} ... boja v uporabi!
+
+
+STR_CANT_REMOVE_PART_OF_STATION :{WHITE}Ni mogoÄe odstraniti dela postaje ...
+STR_CANT_CONVERT_RAIL :{WHITE}Ni mogoÄe spremeniti železnice tukaj ...
+
+
+
+
+
+
+
+STR_CONFIG_GAME_PRODUCTION :{WHITE}Spremeni produkcijo
+
+TEMP_AI_IN_PROGRESS :{WHITE}Dobrodosli v UI v razvoju. Ce boste prisli do problemov, posnamite zaslonsko sliko in jo prilepite na forum.
+TEMP_AI_ACTIVATED :{WHITE}Opozorilo: Nova UI je se vedno alfa razlicica! Zaenkrat, samo tovornjaki in avtobusi delujejo!
+TEMP_AI_MULTIPLAYER :{WHITE}Opozorilo:Implementacija je se vedno testna (uporablja novo UI). Prosimo porocajte kakrsne koli probleme na truelight@openttd.org.
+
+############ network gui strings
+
+
+
+
+
+
+
+
+
+
+
+############ Leave those lines in this order!!
+############ End of leave-in-this-order
+
+
+
+
+
+
+
+############ Leave those lines in this order!!
+
+############ End of leave-in-this-order
+
+
+
+
+############ Leave those lines in this order!!
+############ End of leave-in-this-order
+
+
+
+
+
+############ end network gui strings
+
+
+
+
+##### PNG-MAP-Loader
+
+
+STR_BMPMAP_ERROR :{WHITE}Ni mogoÄe naložiti pokrajine iz formata BMP ...
+STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE} ... ni mogoÄe spremeniti tipa slike.
+
+##id 0x0800
+STR_0800_COST :{TINYFONT}{RED}Stroški: {CURRENCY}
+STR_0801_COST :{RED}Stroški: {CURRENCY}
+STR_0802_INCOME :{TINYFONT}{GREEN}Prihodki: {CURRENCY}
+STR_0803_INCOME :{GREEN}Prihodki: {CURRENCY}
+STR_0805_ESTIMATED_COST :{WHITE}Ocenjeni stroški: {CURRENCY}
+STR_0807_ESTIMATED_INCOME :{WHITE}Predvideni prihodki: {CURRENCY}
+STR_0808_CAN_T_RAISE_LAND_HERE :{WHITE}Tukaj ne morete dvigniti terena ...
+STR_0809_CAN_T_LOWER_LAND_HERE :{WHITE}Tukaj ne morete znižati terena ...
+STR_080A_ROCKS :Kamenje
+STR_080B_ROUGH_LAND :Groba tla
+STR_080C_BARE_LAND :Gola tla
+STR_080D_GRASS :Trava
+STR_080E_FIELDS :Polja
+STR_080F_SNOW_COVERED_LAND :Zasnežen teren
+STR_0810_DESERT :PuÅ¡Äava
+
+##id 0x1000
+STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Teren nagnjen v napaÄno smer
+STR_1001_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}NemogoÄa kombinacija tirnic
+STR_1002_EXCAVATION_WOULD_DAMAGE :{WHITE}Premikanje bi lahko poškodovalo tunel
+STR_1003_ALREADY_AT_SEA_LEVEL :{WHITE}Že na nadmorski višini
+STR_1004_TOO_HIGH :{WHITE}Previsoko
+STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Nobene uporabne traÄnice
+STR_1007_ALREADY_BUILT :{WHITE} ... že zgrajeno
+STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Najprej morate odstraniti traÄnice
+STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Gradnja železnice
+STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Elektrificirana Zeleznica
+STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Gradnja enotirne železnice
+STR_100C_MAGLEV_CONSTRUCTION :{WHITE}Gradnja magnetne železnice
+STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Izberi železniški most
+STR_100E_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Tu ne morete zgraditi železniÅ¡kega skladiÅ¡Äa ...
+STR_100F_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Tu ne morete zgraditi železniške postaje ...
+STR_1010_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Tu ne morete zgraditi semaforjev ...
+STR_1011_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Tu ne morete zgraditi železniških tirov ...
+STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Tu ne morete odstraniti železniških tirov ...
+STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Tu ne morete odstraniti semaforjev ...
+STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Smer železniÅ¡kega skladiÅ¡Äa
+STR_1015_RAILROAD_CONSTRUCTION :Gradnja železnice
+STR_TOOLB_ELRAIL_CONSTRUCTION :Elektrificirana zeleznica
+STR_1016_MONORAIL_CONSTRUCTION :Enotirna železnica
+STR_1017_MAGLEV_CONSTRUCTION :Magnetna železnica
+STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Zgradi traÄnice
+STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Zgradi železniÅ¡ko skladiÅ¡Äe (za izgradnjo in servis vlakov)
+STR_101A_BUILD_RAILROAD_STATION :{BLACK}Zgradi železniško postajo
+STR_101B_BUILD_RAILROAD_SIGNALS :{BLACK}Zgradi železniške semaforje
+STR_101C_BUILD_RAILROAD_BRIDGE :{BLACK}Zgradi železniški most
+STR_101D_BUILD_RAILROAD_TUNNEL :{BLACK}Zgradi železniški tunel
+STR_101E_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Preklopi gradnjo/rušenje železniških semaforjev
+STR_101F_BRIDGE_SELECTION_CLICK :{BLACK}Izbira mostu - kliknite na željeni most za izgradnjo
+STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO :{BLACK}Izberi smer železniÅ¡kega skladiÅ¡Äa
+STR_1021_RAILROAD_TRACK :Železniška proga
+STR_1023_RAILROAD_TRAIN_DEPOT :ŽelezniÅ¡ko skladiÅ¡Äe
+STR_1024_AREA_IS_OWNED_BY_ANOTHER :{WHITE} ... zemljiÅ¡Äe je last nekega drugega podjetja
+
+
+
+##id 0x1800
+STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Najprej odstrani cesto
+STR_1802_ROAD_CONSTRUCTION :{WHITE}Cestne gradnje
+STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Izberi cestni most
+STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Tu ne morete zgraditi ceste ...
+STR_1805_CAN_T_REMOVE_ROAD_FROM :{WHITE}Tu ne morete odstraniti ceste ...
+STR_1806_ROAD_DEPOT_ORIENTATION :{WHITE}Smer garaže
+STR_1807_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Ne morete zgraditi garaže tukaj ...
+STR_1808_CAN_T_BUILD_BUS_STATION :{WHITE}Ne morete zgraditi avtobusne postaje ...
+STR_1809_CAN_T_BUILD_TRUCK_STATION :{WHITE}Ne morete zgraditi tovorne postaje tukaj ...
+STR_180A_ROAD_CONSTRUCTION :Gradnja ceste
+STR_180B_BUILD_ROAD_SECTION :{BLACK}Zgradi cestni odsek
+STR_180C_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Zgradi garažo (za izgradnjo in servis vozil)
+STR_180D_BUILD_BUS_STATION :{BLACK}Zgradi avtobusno postajo
+STR_180E_BUILD_TRUCK_LOADING_BAY :{BLACK}Zgradi tovorno postajo
+STR_180F_BUILD_ROAD_BRIDGE :{BLACK}Zgradi cestni most
+STR_1810_BUILD_ROAD_TUNNEL :{BLACK}Zgradi cestni predor
+STR_1811_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Preklapljaj gradnjo/rušenje cestnih konstrukcij
+STR_1813_SELECT_ROAD_VEHICLE_DEPOT :{BLACK}Izberi smer garaže
+STR_1814_ROAD :Cesta
+STR_1815_ROAD_WITH_STREETLIGHTS :Cesta s cestnimi luÄmi
+STR_1816_TREE_LINED_ROAD :Cesta z drevoredom
+STR_1817_ROAD_VEHICLE_DEPOT :Garaža
+STR_1818_ROAD_RAIL_LEVEL_CROSSING :Cestno/železniÅ¡ko križiÅ¡Äe
+
+##id 0x2000
+STR_2000_TOWNS :{WHITE}Mesta
+STR_TOWN_LABEL_POP :{WHITE}{TOWN} ({COMMA})
+STR_TOWN_LABEL :{WHITE}{TOWN}
+STR_TOWN_LABEL_TINY_BLACK :{TINYFONT}{BLACK}{TOWN}
+STR_TOWN_LABEL_TINY_WHITE :{TINYFONT}{WHITE}{TOWN}
+STR_2002 :{TINYFONT}{BLACK}{STRING}
+STR_2004_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Najprej mora biti stavba porušena
+STR_2005 :{WHITE}{TOWN}
+STR_2006_POPULATION :{BLACK}Populacija: {ORANGE}{COMMA}{BLACK} Å tevilo stavb: {ORANGE}{COMMA}
+STR_2007_RENAME_TOWN :Preimenuj mesto
+STR_2008_CAN_T_RENAME_TOWN :{WHITE}Ne morete preimenovati mesta ...
+STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} lokalna oblast tega ne dovoli
+STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Imena mest - kliknite na ime za pogled na mesto
+STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Premakni celotni pogled na mesto
+STR_200C_CHANGE_TOWN_NAME :{BLACK}Spremeni ime mesta
+STR_200D_PASSENGERS_LAST_MONTH_MAX :{BLACK}Potnikov prejšnji mesec: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200E_MAIL_LAST_MONTH_MAX :{BLACK}Pošte prejšnji mesec: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
+STR_200F_TALL_OFFICE_BLOCK :Visok pisarniški blok
+STR_2010_OFFICE_BLOCK :Pisarniški blok
+STR_2011_SMALL_BLOCK_OF_FLATS :Majhen blok
+STR_2012_CHURCH :Cerkev
+STR_2013_LARGE_OFFICE_BLOCK :Velik pisarniški blok
+STR_2014_TOWN_HOUSES :MeÅ¡Äanske hiÅ¡e
+STR_2015_HOTEL :Hotel
+STR_2016_STATUE :Spomenik
+STR_2017_FOUNTAIN :Vodnjak
+STR_2018_PARK :Park
+STR_2019_OFFICE_BLOCK :Pisarniški blok
+STR_201A_SHOPS_AND_OFFICES :Trgovine in pisarne
+STR_201B_MODERN_OFFICE_BUILDING :Moderna pisarniška hiša
+STR_201C_WAREHOUSE :SkladiÅ¡Äe
+STR_201D_OFFICE_BLOCK :Pisarniška hiša
+STR_201E_STADIUM :Stadion
+STR_201F_OLD_HOUSES :Stare hiše
+STR_2020_LOCAL_AUTHORITY :{BLACK}Mestni svet
+STR_2021_SHOW_INFORMATION_ON_LOCAL :{BLACK}Pokaži informacije o lokalni oblasti
+STR_2022_LOCAL_AUTHORITY :{WHITE}{TOWN} mestni svet
+STR_2023_TRANSPORT_COMPANY_RATINGS :{BLACK}Ocene podjetja:
+STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING}
+STR_2025_SUBSIDIES :{WHITE}Subvencije
+STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Ponudba subvencije za storitev:
+STR_2027_FROM_TO :{ORANGE}{STRING} iz {STRING} v {STRING}
+STR_2028_BY :{YELLOW} (do {DATE_SHORT})
+STR_202A_NONE :{ORANGE}NihÄe
+STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Že subvencionirane storitve:
+STR_202C_FROM_TO :{ORANGE}{STRING} od {STATION} do {STATION}{YELLOW} ({COMPANY}
+STR_202D_UNTIL :{YELLOW}, do {DATE_SHORT})
+STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}Subvencioniranje zakljuÄeno: storitev {}{}{STRING} od {STRING} do {STRING} ne bo subvencionirana.
+STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Subvencija je potekla:{}{}{STRING} storitev od {STATION} do {STATION} ni veÄ subvencionirana.
+STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Nova subvencija:{}{}Prva {STRING} storitev od {STRING} do {STRING} bo subvencionirana s strani mestnega sveta!
+STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subvencija podeljena {COMPANY}!{}{}{STRING} storitev od {STATION} do {STATION} bo prinesla 50% veÄji prihodek za naslednje leto!
+STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subvencija podeljena {COMPANY}!{}{}{STRING} storitev od {STATION} do {STATION} bo prinesla dvakratni prihodek
+STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subvencija podeljena {COMPANY}!{}{}{STRING} storitev od {STATION} do {STATION} bo prinesla trikratni prihodek za naslednje leto!
+STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Subvencija podeljena {COMPANY}!{}{}{STRING} storitev od {STATION} do {STATION} bo prinesla Å¡tirikratni prihodek za naslednje leto!
+STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} mestni svet prepoveduje gradnjo Å¡e enega letaliÅ¡Äa v tem mestu
+STR_2036_COTTAGES :KoÄe
+STR_2037_HOUSES :Hiše
+STR_2038_FLATS :Stanovanja
+STR_2039_TALL_OFFICE_BLOCK :Visoka poslovna hiša
+STR_203A_SHOPS_AND_OFFICES :Trgovine in pisarne
+STR_203B_SHOPS_AND_OFFICES :Trgovine in pisarne
+STR_203C_THEATER :GledaliÅ¡Äe
+STR_203D_STADIUM :Stadion
+STR_203E_OFFICES :Pisarne
+STR_203F_HOUSES :Hiše
+STR_2040_CINEMA :Kino
+STR_2041_SHOPPING_MALL :Trgovski center
+STR_2042_DO_IT :{BLACK}Stori to
+STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}Seznam stvari, ki jih lahko naredite v tem mestu - kliknite na predmet za podrobnosti
+STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Izvrši izbrano storitev na zgornjem seznamu
+STR_2045_ACTIONS_AVAILABLE :{BLACK}Storitve na voljo:
+STR_2046_SMALL_ADVERTISING_CAMPAIGN :Majhna reklamna kampanija
+STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Srednje velika reklamna kampanija
+STR_2048_LARGE_ADVERTISING_CAMPAIGN :Velika reklamna kampanija
+STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Financiraj obnovo cest
+STR_204A_BUILD_STATUE_OF_COMPANY :Zgradi spomenik lastniku podjetja
+STR_204B_FUND_NEW_BUILDINGS :Sponzoriraj nove stavbe
+STR_204C_BUY_EXCLUSIVE_TRANSPORT :Kupi eksluzivne transportne pravice
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Podkupi lokalno oblast
+STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} IzvrÅ¡i majhno reklamno kampanijo z namenom privabiti veÄ potnikov in tovora podjetju.{} Cena: {CURRENCY}
+STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} IzvrÅ¡i srednje-veliko reklamno kampanijo z namenom privabiti veÄ potnikov in tovora podjetju.{} Cena: {CURRENCY}
+STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} IzvrÅ¡i veliko reklamno kampanijo z namenom privabiti veÄ potnikov in tovora podjetju.{} Cena: {CURRENCY}
+STR_2050_FUND_THE_RECONSTRUCTION :{WHITE}{STRING}{}{YELLOW} Financiraj obnovo cest z namenom motnje cestnega prometa tudi do 6 mesecev.{} Cena: {CURRENCY}
+STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Zgradi spomenik v Äast podjetju.{} Cena: {CURRENCY}
+STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Financiraj izgradnjo novih poslovnih stavb v mestu.{} Cena: {CURRENCY}
+STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Kupi enoletno izkljuÄno pravico do transporta v mestu. Lokalne oblasti bodo dovolile potnikom in tovoru do izkljuÄno vaÅ¡e uporabe transportnih storitev.{} Cena: {CURRENCY}
+STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Podkupi lokalno oblast za izboljsavo svojih rating ob tveganju resnih kazni ob caught.{} Stane: {CURRENCY}
+STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}Prometni kaos v mestu {TOWN}!{}{}Obnovitvena dela, ki jih financira podjetje {COMPANY}, bodo prinesla 6 mesecev noÄnih mor voznikom motornih vozil!
+STR_2056 :{TINYFONT}{WHITE}{TOWN}
+STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_2058_UNDER_CONSTRUCTION :{STRING} (v izgradnji)
+STR_2059_IGLOO :Iglu
+STR_205B_TEAPOT_HOUSE :Čajna hiša
+STR_205C_PIGGY_BANK :PraÅ¡iÄkova banka
+
+
+##id 0x2800
+STR_2800_PLANT_TREES :Posadi drevesa
+STR_2801_PLACE_SIGN :Postavi znak
+STR_2802_TREES :{WHITE}Drevesa
+STR_2803_TREE_ALREADY_HERE :{WHITE} ... drevo že posajeno
+STR_2804_SITE_UNSUITABLE :{WHITE} ... sajenje nemogoÄe
+STR_2805_CAN_T_PLANT_TREE_HERE :{WHITE}Ne morete posaditi drevesa tukaj ...
+STR_2806 :{WHITE}{STRING}
+STR_2808_TOO_MANY_SIGNS :{WHITE} ... preveÄ znakov
+STR_2809_CAN_T_PLACE_SIGN_HERE :{WHITE}Ne morete postaviti znaka tukaj
+STR_280A_SIGN :Znak
+STR_280B_EDIT_SIGN_TEXT :{WHITE}Uredi znak
+STR_280C_CAN_T_CHANGE_SIGN_NAME :{WHITE}Ne morete spremeniti imena znaka ...
+STR_280D_SELECT_TREE_TYPE_TO_PLANT :{BLACK}Izberite vrsto drevesa za posaditev
+STR_280E_TREES :Drevesa
+STR_280F_RAINFOREST :Deževni gozd
+STR_2810_CACTUS_PLANTS :Kaktusi
+
+##id 0x3000
+STR_3000_RAIL_STATION_SELECTION :{WHITE}Izbira železniške postaje
+STR_3001_AIRPORT_SELECTION :{WHITE}Izbira letaliÅ¡Äa
+STR_3002_ORIENTATION :{BLACK}Orientacija
+STR_3003_NUMBER_OF_TRACKS :{BLACK}Å tevilo peronov
+STR_3004_PLATFORM_LENGTH :{BLACK}Dolžina perona
+STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD :{WHITE}Preblizu druge železniške postaje
+STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Združi dve postaji
+STR_3007_TOO_MANY_STATIONS_LOADING :{WHITE}PreveÄ postaj v tem mestu
+STR_3008_TOO_MANY_STATIONS_LOADING :{WHITE}PreveÄ postaj na zemljevidu
+STR_3008A_TOO_MANY_BUS_STOPS :{WHITE}PreveÄ avtobusnih postaj
+STR_3008B_TOO_MANY_TRUCK_STOPS :{WHITE}PreveÄ tovornih postaj
+STR_3009_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Preblizu druge postaje
+STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES}
+STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}Najprej je potrebno porušiti postajo
+STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Preblizu sosednjemu letaliÅ¡Äu
+STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Najprej je potrebno poruÅ¡iti letaliÅ¡Äe
+
+STR_3030_RENAME_STATION_LOADING :Preimenuj postajo
+STR_3031_CAN_T_RENAME_STATION :{WHITE}Ni mogoÄe preimenovati postaje
+STR_3032_RATINGS :{BLACK}Ocene
+STR_3033_ACCEPTS :{BLACK}Sprejema
+STR_3034_LOCAL_RATING_OF_TRANSPORT :{BLACK}Lokalne ocene transportne storitve:
+
+############ range for rating starts
+STR_3035_APPALLING :Strašen
+STR_3036_VERY_POOR :Zelo slab
+STR_3037_POOR :Slab
+STR_3038_MEDIOCRE :Srednji
+STR_3039_GOOD :Dober
+STR_303A_VERY_GOOD :Zelo dober
+STR_303B_EXCELLENT :Izvrsten
+STR_303C_OUTSTANDING :Sijajen
+############ range for rating ends
+
+STR_303D :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
+STR_303E_NO_LONGER_ACCEPTS :{WHITE}{STATION} ne sprejema veÄ {STRING}
+STR_303F_NO_LONGER_ACCEPTS_OR :{WHITE}{STATION} ne sprejema veÄ {STRING} in {STRING}
+STR_3040_NOW_ACCEPTS :{WHITE}{STATION} sedaj sprejema {STRING}
+STR_3041_NOW_ACCEPTS_AND :{WHITE}{STATION} sedaj sprejema {STRING} in {STRING}
+STR_3042_BUS_STATION_ORIENTATION :{WHITE}Orientacija avtobusne postaje
+STR_3043_TRUCK_STATION_ORIENT :{WHITE}Orientacija tovorne postaje.
+STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Najprej morate porušiti avtobusno postajo
+STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Najprej morate porušiti tovorno postajo
+STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Postaja{P "" s}
+STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES}
+STR_304A_NONE :{YELLOW}- Nobeno -
+STR_304B_SITE_UNSUITABLE :{WHITE} ... neprimerna lokacija
+STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Preblizu drugemu pristaniÅ¡Äu
+STR_304D_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Najprej morate poruÅ¡iti pristaniÅ¡Äe
+STR_304E_SELECT_RAILROAD_STATION :{BLACK}Izberite orientacijo železniške postaje
+STR_304F_SELECT_NUMBER_OF_PLATFORMS :{BLACK}Izberite število peronov železniške postaje
+STR_3050_SELECT_LENGTH_OF_RAILROAD :{BLACK}Izberite dolžino železniške postaje
+STR_3051_SELECT_BUS_STATION_ORIENTATION :{BLACK}Izberite orientacijo železniške postaje
+STR_3052_SELECT_TRUCK_LOADING_BAY :{BLACK}Izberite orientacijo tovorne postaje
+STR_3053_CENTER_MAIN_VIEW_ON_STATION :{BLACK}Pogled na postajo
+STR_3054_SHOW_STATION_RATINGS :{BLACK}Prikaz ocen postaje
+STR_3055_CHANGE_NAME_OF_STATION :{BLACK}Spremeni ime postaje
+STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO :{BLACK}Prikaži seznam sprejetega tovora
+STR_3057_STATION_NAMES_CLICK_ON :{BLACK}Imena postaj - kliknite na ime za pogled na postajo
+STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT :{BLACK}Izbira velikosti/tipa letaliÅ¡Äa
+STR_305C_0 :{STATION} {STATIONFEATURES}
+STR_305E_RAILROAD_STATION :Železniška postaja
+STR_305F_AIRCRAFT_HANGAR :Hangar
+STR_3060_AIRPORT :LetaliÅ¡Äe
+STR_3061_TRUCK_LOADING_AREA :Tovorna postaja
+STR_3062_BUS_STATION :Avtobusna postaja
+STR_3063_SHIP_DOCK :PristaniÅ¡Äe
+STR_3064_HIGHLIGHT_COVERAGE_AREA :{BLACK}Osvetli pokritost obmoÄja
+STR_3065_DON_T_HIGHLIGHT_COVERAGE :{BLACK}Ne osvetli pokritosti obmoÄja
+STR_3066_COVERAGE_AREA_HIGHLIGHT :{BLACK}Osvetlitev pokritosti obmoÄja
+STR_3068_DOCK :{WHITE}PristaniÅ¡Äe
+STR_3069_BUOY :Boja
+STR_306A_BUOY_IN_THE_WAY :{WHITE} ... boja na poti
+STR_306C_STATION_TOO_SPREAD_OUT :{WHITE} ... postaja preveÄ razÅ¡irjena
+STR_306D_NONUNIFORM_STATIONS_DISALLOWED :{WHITE} ... nehomogene postaje izklopljene
+
+
+##id 0x3800
+STR_3800_SHIP_DEPOT_ORIENTATION :{WHITE}Orientacija ladjedelnice
+STR_3801_MUST_BE_BUILT_ON_WATER :{WHITE} ... zgrajeno mora biti na vodi
+STR_3802_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Ne morem zgraditi ladjedelnice tukaj ...
+STR_3803_SELECT_SHIP_DEPOT_ORIENTATION :{BLACK}Izberite orientacijo ladjedelnice
+STR_3804_WATER :Voda
+STR_3805_COAST_OR_RIVERBANK :Obala ali nabrežje
+STR_3806_SHIP_DEPOT :Ladjedelnica
+STR_3807_CAN_T_BUILD_ON_WATER :{WHITE} ... Ni mogoÄe graditi na vodi
+
+##id 0x4000
+STR_4000_SAVE_GAME :{WHITE}Shrani igro
+STR_4001_LOAD_GAME :{WHITE}Naloži igro
+STR_4002_SAVE :{BLACK}Shrani
+STR_4003_DELETE :{BLACK}Izbriši
+STR_4004 :{COMPANY}, {DATE_LONG}
+STR_4005_BYTES_FREE :{BLACK}{COMMA} megabajtov{P "" s} prosto
+STR_4006_UNABLE_TO_READ_DRIVE :{BLACK}Ni mogoÄe brati pogona
+STR_4007_GAME_SAVE_FAILED :{WHITE}Shranjevanje igre ni uspelo
+STR_4008_UNABLE_TO_DELETE_FILE :{WHITE}Ni mogoÄe izbrisati datoteke
+STR_4009_GAME_LOAD_FAILED :{WHITE}Nalaganje igre ni uspelo
+STR_400A_LIST_OF_DRIVES_DIRECTORIES :{BLACK}Seznam pogonov, zemljevidov in shranjenih iger
+STR_400B_CURRENTLY_SELECTED_NAME :{BLACK}Trenutno izbrano ime za shranjevanje
+STR_400C_DELETE_THE_CURRENTLY_SELECTED :{BLACK}Izbriši trenutno izbrano shranjeno igro
+STR_400D_SAVE_THE_CURRENT_GAME_USING :{BLACK}Shrani trenutno igro z izbranim imenom
+STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Izberi tip nove igre
+STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Izberite scenarij (zeleno), prednastavljeno igro (modro) ali nakljuÄno novo igro
+STR_4010_GENERATE_RANDOM_NEW_GAME :Ustvari nakljuÄno novo igro
+STR_4011_LOAD_HEIGHTMAP :{WHITE}Naloži višinsko karto
+
+##id 0x4800
+STR_4800_IN_THE_WAY :{WHITE}{STRING} na poti
+STR_4801 :{WHITE}{INDUSTRY}
+STR_4802_COAL_MINE :Rudnik premoga
+STR_4803_POWER_STATION :Termoelektrarna
+STR_4804_SAWMILL :Žaga
+STR_4805_FOREST :Gozd
+STR_4806_OIL_REFINERY :Naftna rafinerija
+STR_4807_OIL_RIG :Naftna ploÅ¡Äad
+STR_4808_FACTORY :Tovarna
+STR_4809_PRINTING_WORKS :Tiskarna
+STR_480A_STEEL_MILL :Železarna
+STR_480B_FARM :Kmetija
+STR_480C_COPPER_ORE_MINE :Rudnik bakra
+STR_480D_OIL_WELLS :Naftni izviri
+STR_480E_BANK :Banka
+STR_480F_FOOD_PROCESSING_PLANT :Predelava živil
+STR_4810_PAPER_MILL :Papirnica
+STR_4811_GOLD_MINE :Rudnik zlata
+STR_4812_BANK :Banka
+STR_4813_DIAMOND_MINE :Rudnik diamantov
+STR_4814_IRON_ORE_MINE :Rudnik železa
+STR_4815_FRUIT_PLANTATION :Sadovnjak
+STR_4816_RUBBER_PLANTATION :Plantaža kavÄuka
+STR_4817_WATER_SUPPLY :Vodno zajetje
+STR_4818_WATER_TOWER :Vodovodni stolp
+STR_4819_FACTORY :Tovarna
+STR_481A_FARM :Kmetija
+STR_481B_LUMBER_MILL :Žaga
+STR_481C_COTTON_CANDY_FOREST :Gozd sladkorne pene
+STR_481D_CANDY_FACTORY :Tovarna slaÅ¡Äic
+STR_481E_BATTERY_FARM :Farma baterij
+STR_481F_COLA_WELLS :Izvir Cockte
+STR_4820_TOY_SHOP :Trgovina z igraÄami
+STR_4821_TOY_FACTORY :Tovarna igraÄ
+STR_4822_PLASTIC_FOUNTAINS :Vodnjaki plastike
+STR_4823_FIZZY_DRINK_FACTORY :Tovarna gaziranih pijaÄ
+STR_4824_BUBBLE_GENERATOR :Generator mehurÄkov
+STR_4825_TOFFEE_QUARRY :Jama karamele
+STR_4826_SUGAR_MINE :Rudnik sladkorja
+
+############ range for requires starts
+STR_4827_REQUIRES :{BLACK}Potrebuje: {YELLOW}{STRING}
+STR_4828_REQUIRES :{BLACK}Potrebuje: {YELLOW}{STRING}, {STRING}
+STR_4829_REQUIRES :{BLACK}Potrebuje:: {YELLOW}{STRING}, {STRING}, {STRING}
+############ range for requires ends
+
+STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Proizvodnja prejšnjega meseca:
+STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% oddano)
+STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Pogled na industrijo
+STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Nov {STRING} v izgradnji blizu mesta {TOWN}!
+STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Nov {STRING} v izgradnji blizu mesta {TOWN}!
+STR_482F_COST :{BLACK}Cena: {YELLOW}{CURRENCY}
+STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Tukaj ni mogoÄe zgraditi tega tipa industrije ...
+STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE} ... gozd je mogoÄe posaditi samo nad snežno mejo
+STR_4832_ANNOUNCES_IMMINENT_CLOSURE :{BLACK}{BIGFONT}{INDUSTRY} napoveduje takojšnje zaprtje!
+STR_4833_SUPPLY_PROBLEMS_CAUSE_TO :{BLACK}{BIGFONT}Zaradi težav z zalogami {INDUSTRY} napoveduje takojšnje zaprtje!
+STR_4834_LACK_OF_NEARBY_TREES_CAUSES :{BLACK}{BIGFONT}Zaradi pomanjkanja bližnjih dreves {INDUSTRY} napoveduje takojšnje zaprtje!
+STR_4835_INCREASES_PRODUCTION :{BLACK}{BIGFONT}{INDUSTRY} poveÄuje proizvodnjo!
+STR_4836_NEW_COAL_SEAM_FOUND_AT :{BLACK}{BIGFONT}Nova žila premoga najdena v {INDUSTRY}!{}Proizvodnja se bo podvojila!
+STR_4837_NEW_OIL_RESERVES_FOUND :{BLACK}{BIGFONT}Nove rezerve nafte odkrite v {INDUSTRY}!{}Proizvodnja se bo podvojila!
+STR_4838_IMPROVED_FARMING_METHODS :{BLACK}{BIGFONT}Izboljšane metode pridelovanja v {INDUSTRY} bodo podvojile proizvodnjo!
+STR_4839_PRODUCTION_DOWN_BY_50 :{BLACK}{BIGFONT}{INDUSTRY} proizvodnja zmanjšana za 50%
+STR_483A_INSECT_INFESTATION_CAUSES :{BLACK}{BIGFONT}Insekti povzroÄili opustoÅ¡enje v {INDUSTRY}!{}Proizvodnja zmanjÅ¡ana za 50%
+STR_483B_CAN_ONLY_BE_POSITIONED :{WHITE} ... mogoÄe zgraditi samo ob robu zemljevida
+
+##id 0x5000
+STR_5000_TRAIN_IN_TUNNEL :{WHITE}Vlak v tunelu
+STR_5001_ROAD_VEHICLE_IN_TUNNEL :{WHITE}Cestno vozilo v tunelu
+STR_5003_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}ObstojeÄi tunel v napoto
+STR_5005_UNABLE_TO_EXCAVATE_LAND :{WHITE}Ni mogoÄe izkopati zakljuÄka tunela na drugem koncu
+STR_5006_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Potrebno je najprej podreti drugi tunel
+STR_5007_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Potebno je najprej porušiti most
+STR_5008_CANNOT_START_AND_END_ON :{WHITE}Ni mogoÄe zaÄeti in konÄati v isti toÄki
+STR_5009_LEVEL_LAND_OR_WATER_REQUIRED :{WHITE}Raven teren ali vodovje zahtevano pod mostom
+STR_500A_START_AND_END_MUST_BE_IN :{WHITE}ZaÄetek in konec morata biti na isti viÅ¡ini
+STR_500B_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Lokacija neprimerna za vhod v tunel
+STR_500D :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
+STR_500E_SUSPENSION_STEEL :ViseÄi, Jekleni
+STR_500F_GIRDER_STEEL :Nosilni, Jekleni
+STR_5010_CANTILEVER_STEEL :Nosilen, Jeklen
+STR_5011_SUSPENSION_CONCRETE :ViseÄ, Betonski
+STR_5012_WOODEN :Lesen
+STR_5013_CONCRETE :Betonski
+STR_5014_TUBULAR_STEEL :Cevast, Jeklen
+STR_BRIDGE_TUBULAR_SILICON :Cevast, Silicijev
+STR_5015_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Tukaj ni mogoÄe zgraditi mostu ...
+STR_5016_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Tukaj ni mogoÄe zgraditi tunela ...
+STR_5017_RAILROAD_TUNNEL :Železniški predor
+STR_5018_ROAD_TUNNEL :Cestni predor
+STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE :ViseÄ jekleni železniÅ¡ki most
+STR_501C_STEEL_GIRDER_RAIL_BRIDGE :Nosilen jeklen železniški most
+STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE :Nosilen jeklen železniški most
+STR_501E_REINFORCED_CONCRETE_SUSPENSION :OjaÄan viseÄ betonski železniÅ¡ki most
+STR_501F_WOODEN_RAIL_BRIDGE :Lesen železniški most
+STR_5020_CONCRETE_RAIL_BRIDGE :Betonski železniški most
+STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE :ViseÄ jeklen cestni most
+STR_5022_STEEL_GIRDER_ROAD_BRIDGE :Nosilen jeklen cestni most
+STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE :Jeklen cestni most na nosilcih
+STR_5024_REINFORCED_CONCRETE_SUSPENSION :OjaÄan viseÄ betonski cestni most
+STR_5025_WOODEN_ROAD_BRIDGE :Lesen cestni most
+STR_5026_CONCRETE_ROAD_BRIDGE :Betonski cestni most
+STR_5027_TUBULAR_RAIL_BRIDGE :Cevast železniški most
+STR_5028_TUBULAR_ROAD_BRIDGE :Cevast cestni most
+
+##id 0x5800
+STR_5800_OBJECT_IN_THE_WAY :{WHITE}Objekt na poti
+STR_5801_TRANSMITTER :Oddajnik
+STR_5802_LIGHTHOUSE :Svetilnik
+STR_5803_COMPANY_HEADQUARTERS :Sedež podjetja
+STR_5804_COMPANY_HEADQUARTERS_IN :{WHITE} ... sedež podjetja na poti
+STR_5805_COMPANY_OWNED_LAND :Ozemlje v lasti podjetja
+STR_5806_CAN_T_PURCHASE_THIS_LAND :{WHITE}Ni mogoÄe kupiti tega zemljiÅ¡Äa ...
+STR_5807_YOU_ALREADY_OWN_IT :{WHITE} ... ste že lastnik!
+
+
+############ WARNING, using range 0x6000 for strings that are stored in the savegame
+############ These strings may never get a new id, or savegames will break!
+##id 0x6000
+STR_SV_UNNAMED :Neimenovano
+STR_SV_TRAIN_NAME :Vlak {COMMA}
+
+STR_SV_STNAME_SOUTH :{STRING} Jug
+STR_SV_STNAME_WEST :{STRING} Zahod
+STR_SV_STNAME_VALLEY :{STRING} Dolina
+STR_SV_STNAME_UPPER :Zgornje {STRING}
+
+############ end of savegame specific region!
+
+##id 0x6800
+STR_6800_DIFFICULTY_LEVEL :{WHITE}Težavnostna stopnja
+
+############ range for difficulty levels starts
+STR_6801_EASY :{BLACK}Preprosto
+STR_6802_MEDIUM :{BLACK}Srednje
+STR_6803_HARD :{BLACK}Težko
+STR_6804_CUSTOM :{BLACK}Po meri
+############ range for difficulty levels ends
+
+############ range for difficulty settings starts
+STR_6805_MAXIMUM_NO_COMPETITORS :{LTBLUE}NajveÄje Å¡tevilo nasprotnikov: {ORANGE}{COMMA}
+STR_6806_COMPETITOR_START_TIME :{LTBLUE}Nasportnikov zaÄetni Äas: {ORANGE}{STRING}
+STR_6807_NO_OF_TOWNS :{LTBLUE}Å t. mest: {ORANGE}{STRING}
+STR_6808_NO_OF_INDUSTRIES :{LTBLUE}Å t. industrij: {ORANGE}{STRING}
+STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Najvišje možno posojilo: {ORANGE}{CURRENCY}
+STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Obrestna mera: {ORANGE}{COMMA}%
+STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Cena vzdrževanja vozil: {ORANGE}{STRING}
+STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Nasprotnikova hitrost gradnje: {ORANGE}{STRING}
+STR_680D_INTELLIGENCE_OF_COMPETITORS :{LTBLUE}Inteligenca nasprotnikov: {ORANGE}{STRING}
+STR_680E_VEHICLE_BREAKDOWNS :{LTBLUE}Okvare vozil: {ORANGE}{STRING}
+STR_680F_SUBSIDY_MULTIPLIER :{LTBLUE}VeÄkratnik subvencij: {ORANGE}{STRING}
+STR_6810_COST_OF_CONSTRUCTION :{LTBLUE}Cena gradnje: {ORANGE}{STRING}
+STR_6811_TERRAIN_TYPE :{LTBLUE}Tip terena: {ORANGE}{STRING}
+STR_6812_QUANTITY_OF_SEA_LAKES :{LTBLUE}KoliÄina vodovij: {ORANGE}{STRING}
+STR_6813_ECONOMY :{LTBLUE}Ekonomija: {ORANGE}{STRING}
+STR_6814_TRAIN_REVERSING :{LTBLUE}ObraÄanje vlakov: {ORANGE}{STRING}
+STR_6815_DISASTERS :{LTBLUE}Katastrofe: {ORANGE}{STRING}
+STR_16816_CITY_APPROVAL :{LTBLUE}Odnos mestnega sveta do rekonstrukcije: {ORANGE}{STRING}
+############ range for difficulty settings ends
+
+STR_26816_NONE :NiÄ
+STR_6816_LOW :Nizko
+STR_6817_NORMAL :Normalno
+STR_6818_HIGH :Visoko
+STR_6819 :{BLACK}{SMALLLEFTARROW}
+STR_681A :{BLACK}{SMALLRIGHTARROW}
+STR_681B_VERY_SLOW :Zelo poÄasno
+STR_681C_SLOW :PoÄasno
+STR_681D_MEDIUM :Srednje
+STR_681E_FAST :Hitro
+STR_681F_VERY_FAST :Zelo hitro
+STR_VERY_LOW :Zelo Nizko
+STR_6820_LOW :Nizko
+STR_6821_MEDIUM :Srednje
+STR_6822_HIGH :Visoko
+STR_6823_NONE :Nobeno
+STR_6824_REDUCED :Zmanjšano
+STR_6825_NORMAL :Normalno
+STR_6826_X1_5 :x1,5
+STR_6827_X2 :x2
+STR_6828_X3 :x3
+STR_6829_X4 :x4
+STR_682A_VERY_FLAT :Zelo položno
+STR_682B_FLAT :Položno
+STR_682C_HILLY :Hribovito
+STR_682D_MOUNTAINOUS :Gorato
+STR_682E_STEADY :Stalno
+STR_682F_FLUCTUATING :Fluktuacija
+STR_6830_IMMEDIATE :Takojšnje
+STR_6831_3_MONTHS_AFTER_PLAYER :3 mesece za igralcem
+STR_6832_6_MONTHS_AFTER_PLAYER :6 mesecev za igralcem
+STR_6833_9_MONTHS_AFTER_PLAYER :9 mesecev za igralcem
+STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :Na koncu linije in na postajah
+STR_6835_AT_END_OF_LINE_ONLY :Samo na koncu linije
+STR_6836_OFF :Izklopljeno
+STR_6837_ON :Vklopljeno
+STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Pokaži tabelo najboljših
+STR_6839_PERMISSIVE :Dopustno
+STR_683A_TOLERANT :Tolerantno
+STR_683B_HOSTILE :Sovražno
+
+##id 0x7000
+STR_7000 :
+STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME}
+STR_7002_PLAYER :(Igralec {COMMA})
+STR_7004_NEW_FACE :{BLACK}Nov obraz
+STR_7005_COLOR_SCHEME :{BLACK}Barva
+STR_7006_COLOR_SCHEME :{GOLD}Barva:
+STR_7007_NEW_COLOR_SCHEME :{WHITE}Nova barva
+STR_7008_COMPANY_NAME :{BLACK}Ime podjetja
+STR_7009_PRESIDENT_NAME :{BLACK}Ime lastnika
+STR_700A_COMPANY_NAME :Ime podjetja
+STR_700B_PRESIDENT_S_NAME :Ime lastnika
+STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Ni mogoÄe spremeniti imena podjetja ...
+STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Ni mogoÄe spremeniti imena lastnika ...
+STR_700E_FINANCES :{WHITE}{COMPANY} Finance {BLACK}{PLAYERNAME}
+STR_700F_EXPENDITURE_INCOME :{WHITE}Izdatki/Prilivi
+STR_7011_CONSTRUCTION :{GOLD}Konstrukcija
+STR_7012_NEW_VEHICLES :{GOLD}Nova vozila
+STR_7013_TRAIN_RUNNING_COSTS :{GOLD}Cena delovanja vlakov
+STR_7014_ROAD_VEH_RUNNING_COSTS :{GOLD}Cena delovanja cestnih vozil
+STR_7015_AIRCRAFT_RUNNING_COSTS :{GOLD}Cena delovanja letal
+STR_7016_SHIP_RUNNING_COSTS :{GOLD}Cena delovanja ladij
+STR_7017_PROPERTY_MAINTENANCE :{GOLD}Vzdrževanje
+STR_7018_TRAIN_INCOME :{GOLD}Priliv vlakov
+STR_7019_ROAD_VEHICLES_INCOME :{GOLD}Priliv cestnih vozil
+STR_701A_AIRCRAFT_INCOME :{GOLD}Priliv letal
+STR_701B_SHIP_INCOME :{GOLD}Priliv ladij
+STR_701C_LOAN_INTEREST :{GOLD}Obresti posojila
+STR_701D_OTHER :{GOLD}Drugo
+STR_7020_TOTAL :{WHITE}Skupaj:
+STR_7022_INCOME_GRAPH :{WHITE}Graf priliva
+STR_7025_OPERATING_PROFIT_GRAPH :{WHITE}Graf Äistega dobiÄka
+STR_7026_BANK_BALANCE :{WHITE}Stanje na banki
+STR_7027_LOAN :{WHITE}Posojilo
+STR_7029_BORROW :{BLACK}Sposodi {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702A_REPAY :{BLACK}OdplaÄaj {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY}
+STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE} ... najvišje posojilo je {CURRENCY}
+STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Ni si mogoÄe izposoditi veÄ denarja ...
+STR_702D_LOAN_ALREADY_REPAYED :{WHITE} ... ni posojila za odplaÄati
+STR_702E_REQUIRED :{WHITE}...{CURRENCY} potrebno
+STR_702F_CAN_T_REPAY_LOAN :{WHITE}Ni mogoÄe odplaÄati posojila ...
+STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Izberi nov obraz za lastnika
+STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Spremeni barvo vozil podjetja
+STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Spremeni ime lastnika
+STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Spremeni ime podjetja
+STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Kliknite na željeno barvo
+STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}PoveÄaj viÅ¡ino posojila
+STR_7036_REPAY_PART_OF_LOAN :{BLACK}OdplaÄaj del posojila
+STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(Lastnik)
+STR_7038_INAUGURATED :{GOLD}Postavljen spomenik: {WHITE}{NUM}
+STR_7039_VEHICLES :{GOLD}Vozila:
+STR_TRAINS :{WHITE}{COMMA} vlak{P "" s}
+STR_AIRCRAFT :{WHITE}{COMMA} letalo
+STR_7042_NONE :{WHITE}NiÄ
+STR_7043_FACE_SELECTION :{WHITE}Izbira obraza
+STR_7044_MALE :{BLACK}Moški
+STR_7045_FEMALE :{BLACK}Ženska
+STR_7046_NEW_FACE :{BLACK}Nov obraz
+STR_7047_CANCEL_NEW_FACE_SELECTION :{BLACK}PrekliÄi izbiro novega obraza
+STR_7048_ACCEPT_NEW_FACE_SELECTION :{BLACK}Sprejmi nov obraz
+STR_7049_SELECT_MALE_FACES :{BLACK}Izberi moške slike
+STR_704A_SELECT_FEMALE_FACES :{BLACK}Izberi ženske slike
+STR_704B_GENERATE_RANDOM_NEW_FACE :{BLACK}Naredi nakljuÄno novo sliko
+STR_704C_KEY :{BLACK}KljuÄ
+STR_704D_SHOW_KEY_TO_GRAPHS :{BLACK}Prikaži kljuÄe grafov
+STR_704E_KEY_TO_COMPANY_GRAPHS :{WHITE}KljuÄi grafov podjetij
+STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY :{BLACK}Kliknite sem za napise podjetja na grafu vkljuÄeno/izkljuÄeno
+STR_7050_UNITS_OF_CARGO_DELIVERED :{WHITE}Enot tovora dostavljenega
+STR_7051_COMPANY_PERFORMANCE_RATINGS :{WHITE}Ocene podjetja (max=1000)
+STR_7052_COMPANY_VALUES :{WHITE}Vrednosti podjetij
+STR_7053_COMPANY_LEAGUE_TABLE :{WHITE}Seznam najboljših podjetij
+STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}Podjetje v težavah!
+STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :Podjetje {BLACK}{BIGFONT}{COMPANY} bo prodano ali prisiljeno v steÄajni postopek, Äe se stanje kmalu ne izboljÅ¡a!
+STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(Lastnik)
+STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Združevalec podjetij!
+STR_705A_HAS_BEEN_SOLD_TO_FOR :Podjetje {BLACK}{BIGFONT}{COMPANY} je bilo prodano podejtju {COMPANY} za {CURRENCY}!
+STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}IÅ¡Äemo novega lastnika, ki bi prevzel naÅ¡e podjetje.{}{}Ali bi želeli kupiti podjetje {COMPANY} za {CURRENCY}?
+STR_705C_BANKRUPT :{BLACK}{BIGFONT}Bankrotirali ste!
+STR_705D_HAS_BEEN_CLOSED_DOWN_BY :Investitorji so zaprli podjetje {BLACK}{BIGFONT}{COMPANY} in prodali vse imetje!
+STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED :{BLACK}{BIGFONT}Ustanoveljno novo podjetje!
+STR_705F_STARTS_CONSTRUCTION_NEAR :Podjetje {BLACK}{BIGFONT}{COMPANY} zaÄenja gradnjo blizu mesta {TOWN}!
+STR_7060_CAN_T_BUY_COMPANY :{WHITE}Ne morete kupiti podjetja ...
+STR_7061_CARGO_PAYMENT_RATES :{WHITE}Ocene plaÄevanja tovora
+STR_7062_DAYS_IN_TRANSIT :{BLACK}{TINYFONT}Dni v prevozu
+STR_7063_PAYMENT_FOR_DELIVERING :{BLACK}{TINYFONT}PlaÄilo za dostavo 10 enot (ali 10.000 litrov) tovora za razdaljo 20 kvadratkov
+STR_7064_TOGGLE_GRAPH_FOR_CARGO :{BLACK}Prikaži graf za tip tovora vkljuÄen/izkljuÄen
+STR_7065 :{BLACK}{TINYFONT}{STRING}
+STR_7066_ENGINEER :Inženir
+STR_7067_TRAFFIC_MANAGER :Vodja prometa
+STR_7068_TRANSPORT_COORDINATOR :Koordinator transporta
+STR_7069_ROUTE_SUPERVISOR :Nadzornik dostave
+STR_706A_DIRECTOR :Direktor
+STR_706B_CHIEF_EXECUTIVE :Vrhovni direktor
+STR_706C_CHAIRMAN :Minister
+STR_706D_PRESIDENT :Predsednik
+STR_706E_TYCOON :Velekapitalist
+STR_706F_BUILD_HQ :{BLACK}Zgradi sedež podjetja
+STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Zgradi sedež podjetja / poglej sedež podjetja
+STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Ne morem zgraditi sedeža podjetja
+STR_7072_VIEW_HQ :{BLACK}Poglej sedež podjetja
+STR_COMPANY_PASSWORD :{BLACK}Geslo
+STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}ZaÅ¡Äitite svoje podjetje z geslom, da prepreÄite prikljuÄitev drugih uporabnikov k podjetju.
+STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}Svetovna recesija!{}{}Ekonomisti se bojijo najhujšega ob trenutnem poteku dogodkov!
+STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Konec recesije!{}{}IzboljÅ¡anje trgovanja poveÄuje zaupanje domaÄe industrije, gospodarstvo napreduje!
+STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Menjaj veliko/majhno velikost okna
+STR_7076_COMPANY_VALUE :{GOLD}Vrednost podjetja: {WHITE}{CURRENCY64}
+STR_7077_BUY_25_SHARE_IN_COMPANY :{BLACK}Kupi 25% delnic podjetja
+STR_7078_SELL_25_SHARE_IN_COMPANY :{BLACK}Prodaj 25% delnic podjetja
+STR_7079_BUY_25_SHARE_IN_THIS_COMPANY :{BLACK}Kupi 25% delnic tega podjetja
+STR_707A_SELL_25_SHARE_IN_THIS_COMPANY :{BLACK}Prodaj 25% delnic tega podjetja
+STR_707B_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Ni mogoÄe kupiti 25% tržnega deleža tega podjetja ...
+STR_707C_CAN_T_SELL_25_SHARE_IN :{WHITE}Ni mogoÄe prodati 25% tržnega deleža tega podjetja ...
+STR_707D_OWNED_BY :{WHITE}({COMMA}% last podjetja {COMPANY})
+STR_707E_OWNED_BY_OWNED_BY :{WHITE}({COMMA}% last podjetja {COMPANY}{} {COMMA}% last podjetja {COMPANY})
+STR_707F_HAS_BEEN_TAKEN_OVER_BY :Podjetje {BLACK}{BIGFONT}{COMPANY} je bilo prevzeto iz strani podjetja {COMPANY}!
+STR_7080_PROTECTED :{WHITE}Podjetje Å¡e ni dovolj staro, da bi lahko trgovalo z lastnimi delnicami ...
+
+
+
+##id 0x8000
+STR_8017_SH_30_ELECTRIC :SH '30' (ElektriÄen)
+STR_8018_SH_40_ELECTRIC :SH '40' (ElektriÄen)
+STR_8019_T_I_M_ELECTRIC :'T.I.M.' (ElektriÄen)
+STR_801A_ASIASTAR_ELECTRIC :'AsiaStar' (ElektriÄen)
+STR_801B_PASSENGER_CAR :Potniški prevoz
+STR_801C_MAIL_VAN :Kamion s pošto
+STR_801D_COAL_CAR :Kamion s premogom
+STR_801E_OIL_TANKER :Naftni tanker
+STR_801F_LIVESTOCK_VAN :Kamion z živino
+STR_8020_GOODS_VAN :Kamion z dobrinami
+STR_8021_GRAIN_HOPPER :Kamion z žitom
+STR_8022_WOOD_TRUCK :Kamion z lesom
+STR_8023_IRON_ORE_HOPPER :Kamion z železovo rudo
+STR_8024_STEEL_TRUCK :Kamion z jeklom
+STR_8025_ARMORED_VAN :Oklepen kamion
+STR_8026_FOOD_VAN :Kamion s hrano
+STR_8027_PAPER_TRUCK :Kamion s papirjem
+STR_8028_COPPER_ORE_HOPPER :Kamion z bakrovo rudo
+STR_8029_WATER_TANKER :Cisterna z vodo
+STR_802A_FRUIT_TRUCK :Kamion s sadjem
+STR_802B_RUBBER_TRUCK :Kamion z gumo
+STR_802C_SUGAR_TRUCK :Kamion s sladkorjem
+STR_802D_COTTON_CANDY_HOPPER :Kamion s sladkorno peno
+STR_802E_TOFFEE_HOPPER :Kamion s toffee
+STR_802F_BUBBLE_VAN :Kamion z mehurÄki
+STR_8030_COLA_TANKER :Kamion s Cockto
+STR_8031_CANDY_VAN :Kamion s sladkarijami
+STR_8032_TOY_VAN :Kamion z igraÄami
+STR_8033_BATTERY_TRUCK :Kamion z baterijami
+STR_8034_FIZZY_DRINK_TRUCK :Kamion z gaziranimi pijaÄami
+STR_8035_PLASTIC_TRUCK :Kamion s plastiko
+STR_8036_X2001_ELECTRIC :'X2001' (ElektriÄen)
+STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (ElektriÄen)
+STR_8039_PASSENGER_CAR :Prevoz potnikov
+STR_803A_MAIL_VAN :Tovornjak pošte
+STR_803B_COAL_CAR :Tovornjak premoga
+STR_803C_OIL_TANKER :Cisterna z nafto
+STR_803D_LIVESTOCK_VAN :Tovornjak živine
+STR_803E_GOODS_VAN :Tovornjak dobrin
+STR_803F_GRAIN_HOPPER :Tovornjak žita
+STR_8040_WOOD_TRUCK :Tovornjak lesa
+STR_8041_IRON_ORE_HOPPER :Tovornjak železove rude
+STR_8042_STEEL_TRUCK :Tovornjak jekla
+STR_8043_ARMORED_VAN :Oklepen tovornjak
+STR_8044_FOOD_VAN :Tovornjak hrane
+STR_8045_PAPER_TRUCK :Tovornjak papirja
+STR_8046_COPPER_ORE_HOPPER :Tovornjak bakrove rude
+STR_8047_WATER_TANKER :Cisterna z vodo
+STR_8048_FRUIT_TRUCK :Tovornjak sadja
+STR_8049_RUBBER_TRUCK :Tovornjak gume
+STR_804A_SUGAR_TRUCK :Tovornjak sladkorja
+STR_804B_COTTON_CANDY_HOPPER :Tovornjak sladkorne pene
+STR_804C_TOFFEE_HOPPER :Tovornjak toffee
+STR_804D_BUBBLE_VAN :Tovornjak mehurÄkov
+STR_804E_COLA_TANKER :Tovornjak Cockte
+STR_804F_CANDY_VAN :Tovornjak slaÅ¡Äic
+STR_8050_TOY_VAN :Tovornjak igraÄ
+STR_8051_BATTERY_TRUCK :Tovornjak baterij
+STR_8052_FIZZY_DRINK_TRUCK :Tovornjak gaziranih pijaÄ
+STR_8053_PLASTIC_TRUCK :Tovornjak plastike
+STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (ElektriÄen)
+STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (ElektriÄen)
+STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (ElektriÄen)
+STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (ElektriÄen)
+STR_8059_PASSENGER_CAR :Potniški vagon
+STR_805A_MAIL_VAN :Poštni vagon
+STR_805B_COAL_CAR :Vagon za premog
+STR_805C_OIL_TANKER :Vagon za nafto
+STR_805D_LIVESTOCK_VAN :Vagon za živino
+STR_805E_GOODS_VAN :Vagon za dobrine
+STR_805F_GRAIN_HOPPER :Vagon za žito
+STR_8060_WOOD_TRUCK :Vagon za les
+STR_8061_IRON_ORE_HOPPER :Vagon za železovo rudo
+STR_8062_STEEL_TRUCK :Vagon za jeklo
+STR_8063_ARMORED_VAN :Oklepni vagon
+STR_8064_FOOD_VAN :Vagon za hrano
+STR_8065_PAPER_TRUCK :Vagon za papir
+STR_8066_COPPER_ORE_HOPPER :Vagon za bakrovo rudo
+STR_8067_WATER_TANKER :Vodna cisterna
+STR_8068_FRUIT_TRUCK :Vagon za sadje
+STR_8069_RUBBER_TRUCK :Vagon za gumo
+STR_806A_SUGAR_TRUCK :Vagon za sladkor
+STR_806B_COTTON_CANDY_HOPPER :Vagon za sladkorno peno
+STR_806C_TOFFEE_HOPPER :Vagon za karamelo
+STR_806D_BUBBLE_VAN :Vagon za mehurÄke
+STR_806E_COLA_TANKER :Cisterna za Cockto
+STR_806F_CANDY_VAN :Vagon za slaÅ¡Äice
+STR_8070_TOY_VAN :Vagon za igraÄe
+STR_8071_BATTERY_TRUCK :Tovornjak za baterije
+STR_8072_FIZZY_DRINK_TRUCK :Tovornjak za gazirane pijaÄe
+STR_8073_PLASTIC_TRUCK :Tovornjak za plastiko
+STR_8074_MPS_REGAL_BUS :MPS regionalni avtobus
+STR_8075_HEREFORD_LEOPARD_BUS :Hereford Leopard avtobus
+STR_8076_FOSTER_BUS :Foster avtobus
+STR_8077_FOSTER_MKII_SUPERBUS :Foster MkII Superbus
+STR_8078_PLODDYPHUT_MKI_BUS :Ploddyphut MkI avtobus
+STR_8079_PLODDYPHUT_MKII_BUS :Ploddyphut MkII avtobus
+STR_807A_PLODDYPHUT_MKIII_BUS :Ploddyphut MkIII avtobus
+STR_807B_BALOGH_COAL_TRUCK :Balogh tovornjak za premog
+STR_807C_UHL_COAL_TRUCK :Uhl tovornjak za premog
+STR_807D_DW_COAL_TRUCK :DW tovornjak za premog
+STR_807E_MPS_MAIL_TRUCK :MPS tovornjak za pošto
+STR_807F_REYNARD_MAIL_TRUCK :Reynard tovornjak za pošto
+STR_8080_PERRY_MAIL_TRUCK :Perry tovornjak za pošto
+STR_8081_MIGHTYMOVER_MAIL_TRUCK :MightyMover tovornjak za pošto
+STR_8082_POWERNAUGHT_MAIL_TRUCK :Powernaught tovornjak za pošto
+STR_8083_WIZZOWOW_MAIL_TRUCK :Wizzowow tovornjak za pošto
+STR_8084_WITCOMBE_OIL_TANKER :Witcombe cisterna za nafto
+STR_8085_FOSTER_OIL_TANKER :Foster cisterna za nafto
+STR_8086_PERRY_OIL_TANKER :Perry cisterna za nafto
+STR_8087_TALBOTT_LIVESTOCK_VAN :Talbott tovornjak za živino
+STR_8088_UHL_LIVESTOCK_VAN :Uhl tovornjak za živino
+STR_8089_FOSTER_LIVESTOCK_VAN :Foster tovornjak za živino
+STR_808A_BALOGH_GOODS_TRUCK :Balogh tovornjak za dobrine
+STR_808B_CRAIGHEAD_GOODS_TRUCK :Craighead tovornjak za dobrine
+STR_808C_GOSS_GOODS_TRUCK :Goss tovornjak za dobrine
+STR_808D_HEREFORD_GRAIN_TRUCK :Hereford tovornjak za žito
+STR_808E_THOMAS_GRAIN_TRUCK :Thomas tovornjak za žito
+STR_808F_GOSS_GRAIN_TRUCK :Goss tovornjak za žito
+STR_8090_WITCOMBE_WOOD_TRUCK :Witcombe tovornjak za les
+STR_8091_FOSTER_WOOD_TRUCK :Fooster tovornjak za les
+STR_8092_MORELAND_WOOD_TRUCK :Moreland tovornjak za les
+STR_8093_MPS_IRON_ORE_TRUCK :MPS tovornjak za železovo rudo
+STR_8094_UHL_IRON_ORE_TRUCK :Uhl tovornjak za železovo rudo
+STR_8095_CHIPPY_IRON_ORE_TRUCK :Chippy tovornjak za železovo rudo
+STR_8096_BALOGH_STEEL_TRUCK :Balogh tovornjak za jeklo
+STR_8097_UHL_STEEL_TRUCK :Uhl tovornjak za jeklo
+STR_8098_KELLING_STEEL_TRUCK :Kelling tovornjak za jeklo
+STR_8099_BALOGH_ARMORED_TRUCK :Balogh oklepni tovornjak
+STR_809A_UHL_ARMORED_TRUCK :Uhl oklepni tovornjak
+STR_809B_FOSTER_ARMORED_TRUCK :Foster oklepni tovornjak
+STR_809C_FOSTER_FOOD_VAN :Foster tovornjak za živila
+STR_809D_PERRY_FOOD_VAN :Perry tovornjak za živila
+STR_809E_CHIPPY_FOOD_VAN :Chippy tovornjak za živila
+STR_809F_UHL_PAPER_TRUCK :Uhl tovornjak za papir
+STR_80A0_BALOGH_PAPER_TRUCK :Balogh tovornjak za papir
+STR_80A1_MPS_PAPER_TRUCK :MPS tovornjak za papir
+STR_80A2_MPS_COPPER_ORE_TRUCK :MPS tovornjak za bakrovo rudo
+STR_80A3_UHL_COPPER_ORE_TRUCK :Uhl tovornjak za bakrovo rudo
+STR_80A4_GOSS_COPPER_ORE_TRUCK :Goss tovornjak za bakrovo rudo
+STR_80A5_UHL_WATER_TANKER :Uhl cisterna za vodo
+STR_80A6_BALOGH_WATER_TANKER :Balogh cisterna za vodo
+STR_80A7_MPS_WATER_TANKER :MPS cisterna za vodo
+STR_80A8_BALOGH_FRUIT_TRUCK :Balogh tovornjak za sadje
+STR_80A9_UHL_FRUIT_TRUCK :Uhl tovornjak za sadje
+STR_80AA_KELLING_FRUIT_TRUCK :Kelling tovornjak za sadje
+STR_80AB_BALOGH_RUBBER_TRUCK :Balogh tovornjak za gumo
+STR_80AC_UHL_RUBBER_TRUCK :Uhl tovornjak za gumo
+STR_80AD_RMT_RUBBER_TRUCK :RMT tovornjak za gumo
+STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :MightyMover tovornjak za sladkor
+STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Powernaught tovornjak za sladkor
+STR_80B0_WIZZOWOW_SUGAR_TRUCK :Wizzowow tovornjak za sladkor
+STR_80B1_MIGHTYMOVER_COLA_TRUCK :MightyMover cisterna za Cockto
+STR_80B2_POWERNAUGHT_COLA_TRUCK :Powernaught cisterna za Cockto
+STR_80B3_WIZZOWOW_COLA_TRUCK :Wizzowow cisterna za Cockto
+STR_80B4_MIGHTYMOVER_COTTON_CANDY :MightyMover tovornjak za sladkorno peno
+STR_80B5_POWERNAUGHT_COTTON_CANDY :Powernaught tovornjak za sladkorno peno
+STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Wizzowow tovornjak za sladkorno peno
+STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :MightyMover tovornjak za toffee
+STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Powernaught tovornjak za toffee
+STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Wizzowow tovornjak za toffee
+STR_80BA_MIGHTYMOVER_TOY_VAN :MightyMover tovornjak za igraÄe
+STR_80BB_POWERNAUGHT_TOY_VAN :Powernaught tovornjak za igraÄe
+STR_80BC_WIZZOWOW_TOY_VAN :Wizzowow tovornjak za igraÄe
+STR_80BD_MIGHTYMOVER_CANDY_TRUCK :MightyMover tovornjak za sladkarije
+STR_80BE_POWERNAUGHT_CANDY_TRUCK :Powernaught tovornjak za sladkarije
+STR_80BF_WIZZOWOW_CANDY_TRUCK :Wizzowow tovornjak za sladkarije
+STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :MightyMover tovornjak za baterije
+STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Powernaught tovornjak za baterije
+STR_80C2_WIZZOWOW_BATTERY_TRUCK :Wizzowow tovornjak za baterije
+STR_80C3_MIGHTYMOVER_FIZZY_DRINK :MightyMover tovornjak za gazirane pijaÄe
+STR_80C4_POWERNAUGHT_FIZZY_DRINK :Powernaught tovornjak za gazirane pijaÄe
+STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Wizzowow tovornjak za gazirane pijaÄe
+STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :MightyMover tovornjak za plastiko
+STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Powernaught tovornjak za plastiko
+STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Wizzowow tovornjak za plastiko
+STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :MightyMover tovornjak za mehurÄke
+STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Powernaught tovornjak za mehurÄke
+STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Wizzowow tovornjak za mehurÄke
+STR_80CC_MPS_OIL_TANKER :MPS naftni tanker
+STR_80CD_CS_INC_OIL_TANKER :CS-Inc. naftni tanker
+STR_80CE_MPS_PASSENGER_FERRY :MPS potniški trajekt
+STR_80CF_FFP_PASSENGER_FERRY :FFP potniški trajekt
+STR_80D0_BAKEWELL_300_HOVERCRAFT :Bakewell 300 Hovercraft
+STR_80D1_CHUGGER_CHUG_PASSENGER :Chugger-Chug potniški trajekt
+STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Shivershake potniški trajekt
+STR_80D3_YATE_CARGO_SHIP :Yate tovorna ladja
+STR_80D4_BAKEWELL_CARGO_SHIP :Bakewell tovorna ladja
+STR_80D5_MIGHTYMOVER_CARGO_SHIP :Mightymover tovorna ladja
+STR_80D6_POWERNAUT_CARGO_SHIP :Powernaut tovorna ladja
+STR_80D7_SAMPSON_U52 :Sampson U52
+STR_80D8_COLEMAN_COUNT :Coleman Count
+STR_80D9_FFP_DART :FFP Dart
+STR_80DA_YATE_HAUGAN :Yate Haugan
+STR_80DB_BAKEWELL_COTSWALD_LB_3 :Bakewell Cotswald LB-3
+STR_80DC_BAKEWELL_LUCKETT_LB_8 :Bakewell Luckett LB-8
+STR_80DD_BAKEWELL_LUCKETT_LB_9 :Bakewell Luckett LB-9
+STR_80DE_BAKEWELL_LUCKETT_LB80 :Bakewell Luckett LB80
+STR_80DF_BAKEWELL_LUCKETT_LB_10 :Bakewell Luckett LB-10
+STR_80E0_BAKEWELL_LUCKETT_LB_11 :Bakewell Luckett LB-11
+STR_80E1_YATE_AEROSPACE_YAC_1_11 :Yate Aerospace YAC 1-11
+STR_80E2_DARWIN_100 :Darwin 100
+STR_80E3_DARWIN_200 :Darwin 200
+STR_80E4_DARWIN_300 :Darwin 300
+STR_80E5_DARWIN_400 :Darwin 400
+STR_80E6_DARWIN_500 :Darwin 500
+STR_80E7_DARWIN_600 :Darwin 600
+STR_80E8_GURU_GALAXY :Guru Galaxy
+STR_80E9_AIRTAXI_A21 :Airtaxi A21
+STR_80EA_AIRTAXI_A31 :Airtaxi A31
+STR_80EB_AIRTAXI_A32 :Airtaxi A32
+STR_80EC_AIRTAXI_A33 :Airtaxi A33
+STR_80ED_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46
+STR_80EE_DINGER_100 :Dinger 100
+STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
+STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
+STR_80F1_KELLING_K1 :Kelling K1
+STR_80F2_KELLING_K6 :Kelling K6
+STR_80F3_KELLING_K7 :Kelling K7
+STR_80F4_DARWIN_700 :Darwin 700
+STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
+STR_80F6_DINGER_200 :Dinger 200
+STR_80F7_DINGER_1000 :Dinger 1000
+STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
+STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
+STR_80FA_FLASHBANG_X1 :Flashbang X1
+STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
+STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
+STR_80FD_TRICARIO_HELICOPTER :Tricario helikopter
+STR_80FE_GURU_X2_HELICOPTER :Guru X2 helikopter
+STR_80FF_POWERNAUT_HELICOPTER :Powernaut helikopter
+STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}SporoÄilo od proizvajalca vozila
+STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}Pravkar smo izdelali novi {STRING} - ali vas zanima enoletna ekskluzivna pravica do uporabe tega vozila, preden ga ponudimo na trgu?
+STR_8102_RAILROAD_LOCOMOTIVE :železniška lokomotiva
+STR_8103_ROAD_VEHICLE :cestno vozilo
+STR_8104_AIRCRAFT :letalo
+STR_8105_SHIP :ladja
+STR_8106_MONORAIL_LOCOMOTIVE :enotirna lokomotiva
+STR_8107_MAGLEV_LOCOMOTIVE :magnetna lokomotiva
+
+##id 0x8800
+STR_8800_TRAIN_DEPOT :{WHITE}{TOWN} Železniška garaža
+STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Prebivalci praznujejo . . .{}Prvi vlak je pripeljal na postajo {STATION}!
+STR_8802_DETAILS :{WHITE}{STRING} (Podrobnosti)
+STR_8803_TRAIN_IN_THE_WAY :{WHITE}Vlak na poti
+STR_8804 :{SETX 10}{COMMA}: {STRING}
+STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING}
+STR_8806_GO_TO :Pojdi do postaje {STATION}
+STR_8807_GO_TO_TRANSFER :Pojdi do postaje {STATION} (Prenesi in vzemi tovor)
+STR_8808_GO_TO_UNLOAD :Pojdi do postaje {STATION} (Raztovori)
+STR_8809_GO_TO_TRANSFER_UNLOAD :Pojdi do postaje {STATION} (Prenesi in pusti prazno)
+STR_880A_GO_TO_LOAD :Pojdi do postaje {STATION} (Naloži)
+STR_880B_GO_TO_TRANSFER_LOAD :Pojdi do postaje {STATION} (Prenesi in poÄakaj na polno breme)
+STR_880C_GO_NON_STOP_TO :Pojdi brez postanka do postaje {STATION}
+STR_880D_GO_TO_NON_STOP_TRANSFER :Pojdi brez postanka do postaje {STATION} (Prenesi in vzemi tovor)
+STR_880E_GO_NON_STOP_TO_UNLOAD :Pojdi brez postanka do postaje {STATION} (Raztovori)
+STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Pojdi brez postanka do postaje {STATION} (Prenesi in pusti prazno)
+STR_8810_GO_NON_STOP_TO_LOAD :Pojdi brez postanka do postaje {STATION} (Nalozi)
+STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Pojdi brez postanka do postaje {STATION} (Prenesi in poÄakaj na polno breme)
+STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Pojdi brez postanka do garaže {TOWN}
+
+
+
+STR_UNKNOWN_DESTINATION :neznana lokacija
+STR_8812_EMPTY :{LTBLUE}Prazen
+STR_8813_FROM :Tovor {LTBLUE}{CARGO} iz postaje {STATION}
+STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}Vlak {COMMA} Äaka v garaži
+STR_8815_NEW_VEHICLES :{BLACK}Nova vozila
+STR_8816 :{BLACK}-
+STR_8819_TRAIN_TOO_LONG :{WHITE}Vlak je predolg
+STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Vlaki so lahko spremenjeni šele, ko stojijo v garaži
+
+STR_881C_NEW_RAIL_VEHICLES :{WHITE}Nova železniška vozila
+STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}Nova enotirna vozila
+STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}Nova magnetna vozila
+STR_ALL_AVAIL_RAIL_VEHICLES :{WHITE}Železniška vozila
+
+STR_881F_BUILD_VEHICLE :{BLACK}Zgradi vozilo
+STR_CLONE_ROAD_VEHICLE :{BLACK}Kloniraj vozilo
+STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}To bo zgradilo kopijo vozila. CTRL+klik skopira tudi navodila
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}To bo zgradilo kopijo vozila. Kliknite na ta gumb in nato na vozilo v ali zunaj garaže. CTRL+klik skopira tudi navodila
+STR_CLONE_TRAIN :{BLACK}Kloniraj vlak
+STR_CLONE_TRAIN_INFO :{BLACK}To bo zgradilo kopijo vlaka vkljuÄno z vsemi vagoni. CTRL+klik skopira tudi navodila
+STR_CLONE_TRAIN_DEPOT_INFO :{BLACK}To bo zgradilo kopijo vlaka vkljuÄno z vsemi vagoni. Kliknite na ta gumb in nato na vlak v ali zunaj garaže. CTRL+klik skopira tudi navodila
+STR_8820_RENAME :{BLACK}Preimenuj
+STR_8823_SKIP :{BLACK}PreskoÄi
+STR_8824_DELETE :{BLACK}Izbriši
+STR_8825_NON_STOP :{BLACK}Brez prestanka
+STR_8826_GO_TO :{BLACK}Pojdi do
+STR_8827_FULL_LOAD :{BLACK}Naloži polno
+STR_8828_UNLOAD :{BLACK}Raztovori
+STR_8829_ORDERS :{WHITE}{VEHICLE} (Navodila)
+STR_882A_END_OF_ORDERS :{SETX 10}- - Konec navodil - -
+STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Ni mogoÄe kupiti vozila ...
+STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Zgrajen: {LTBLUE}{NUM}{BLACK} Vrednost: {LTBLUE}{CURRENCY}
+STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Vrednost: {LTBLUE}{CURRENCY}
+STR_882E :{WHITE}{VEHICLE}
+STR_882F_LOADING_UNLOADING :{LTBLUE}Natovarjanje / Raztovarjanje
+STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Vlaka ni mogoÄe poslati v garažo ...
+STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Ni veÄ prostora za navodila
+STR_8832_TOO_MANY_ORDERS :{WHITE}PreveÄ navodil
+STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Ni moogÄe vstaviti nov ukaz ...
+STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Ni mogoÄe izbrisati ukaza ...
+STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Ni mogoÄe spreminjati ukaza ...
+STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Ni mogoÄe premakniti vozila ...
+STR_8838_N_A :Ni na voljo{SKIP}
+STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Vlaka ni mogoÄe prodati ...
+STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Ni mogoÄe najti poti do najbližje garaže
+STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Ni mogoÄe ustaviti/zagnati vlaka ...
+STR_883C_SERVICING_INTERVAL_DAYS :{BLACK}Interval servisiranja: {LTBLUE}{COMMA}dni{BLACK} Zadnji servis: {LTBLUE}{DATE_LONG}
+STR_883D_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Vlaki - kliknite na vlak za informacije
+STR_883E_BUILD_NEW_TRAINS_REQUIRES :{BLACK}Zgradi nove vlake (zahteva železniško garažo)
+STR_883F_TRAINS_CLICK_ON_TRAIN_FOR :{BLACK}Vlaki - kliknite na vlak za informacije, povlecite vozilo za dodajanje/odstranjevanje iz vlaka
+STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Zgradi novo železniško vozilo
+STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Povlecite železniÅ¡ko vozilo sem, Äe ga želite prodati
+STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Pogled na železniško garažo
+STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Seznam železniških vozil - kliknite na vozilo za informacije
+STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Zgradi izbrano železniško vozilo
+STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Preimenuj železniško vozilo
+STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Trenutno železniško vozilo - kliknite sem za izklop/zagon vozila
+STR_8847_SHOW_TRAIN_S_ORDERS :{BLACK}Pokaži navodila železniškega vozila
+STR_8848_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Pogled na železniško vozilo
+STR_8849_SEND_TRAIN_TO_DEPOT :{BLACK}Pošlji vlak v železniško garažo. CTRL+klik samo na servis
+STR_884A_FORCE_TRAIN_TO_PROCEED :{BLACK}Prisili vlak, naj nadaljuje brez Äakanja semaforjev
+STR_884B_REVERSE_DIRECTION_OF_TRAIN :{BLACK}Obrni smer vlaka
+STR_884C_SHOW_TRAIN_DETAILS :{BLACK}Pokaži podrobnosti vlaka
+STR_884D_INCREASE_SERVICING_INTERVAL :{BLACK}PodaljÅ¡aj Äas med servisi
+STR_884E_DECREASE_SERVICING_INTERVAL :{BLACK}SkrajÅ¡aj Äas med servisi
+STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED :{BLACK}Pokaži podrobnosti tovora na vlaku
+STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Pokaži podrobnosti o vagonih
+STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Prikaži kapacitete vsakega vagona
+STR_8852_SHOW_TOTAL_CARGO :{BLACK}Prikaži polno kapaciteto vlaka, razdeli glede na tip tovora
+STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Seznam navodil - kliknite na ukaz, da ga izberete. CTRL+klik prikaže postajo
+STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}PreskoÄi trenuten ukaz in izvrÅ¡i naslednjega
+STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Zbriši izbran ukaz
+STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}OznaÄi izbran ukaz kot brez-postanka
+STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Vstavi nov ukaz pred izbranega ali pa ga dodaj na koncu seznama
+STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}OznaÄi izbran ukaz, naj vozilo Äaka na polno obremenitev
+STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}OznaÄi izbran ukaz, naj se vozilo v celoti raztovori
+STR_8859_NEW_NOW_AVAILABLE :{BLACK}{BIGFONT}Nov {STRING} je sedaj na voljo!
+STR_885A :{BLACK}{BIGFONT}{STRING}
+STR_885C_BROKEN_DOWN :{RED}Pokvarjen
+STR_885D_AGE_RUNNING_COST_YR :{BLACK}Starost: {LTBLUE}{STRING}{BLACK} Stroški obratovanja: {LTBLUE}{CURRENCY}/leto
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Teza: {LTBLUE}{WEIGHT_S} {BLACK}Moc: {LTBLUE}{POWER}{BLACK} Max. hitrost: {LTBLUE}{VELOCITY}
+STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Letošnji profit: {LTBLUE}{CURRENCY} (lansko leto: {CURRENCY})
+STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}Zanseljivost: {LTBLUE}{COMMA}% {BLACK}Å t. okvar od zadnjega servisa: {LTBLUE}{COMMA}
+STR_8861_STOPPED :{RED}Ustavljeno
+STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Ni mogoÄe, da vlak v nevarnosti pelje mimo semaforjev ...
+STR_8863_CRASHED :{RED}NesreÄa!
+
+STR_8865_NAME_TRAIN :{WHITE}Poimenuj vlak
+STR_8866_CAN_T_NAME_TRAIN :{WHITE}Ni mogoÄe poimenovati vlaka ...
+STR_8867_NAME_TRAIN :{BLACK}Poimenuj vlak
+STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}ŽelezniÅ¡ka nesreÄa!{}{COMMA} je umrlo v plamenih ob trku
+STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Ni mogoÄe spremeniti smeri vlaka ...
+STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Preimenuj železniško vozilo
+STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Ni mogoÄe preimenovati železniÅ¡kega vozila ...
+STR_886D_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Nastavi ukaz, naj prisili vozilo, da se raztovori
+STR_886F_TRANSFER :{BLACK}Prenos
+
+STR_TRAIN_STOPPING :{RED}Ustavljam
+STR_TRAIN_STOPPING_VEL :{RED}Ustavljam, {VELOCITY}
+
+##id 0x9000
+STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Cestno vozilo na poti
+STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} Cestna vozila
+STR_9002 :{WHITE}{VEHICLE}
+STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}{TOWN} Garaža za cestna vozila
+STR_9004_NEW_VEHICLES :{BLACK}Nova vozila
+STR_9006_NEW_ROAD_VEHICLES :{WHITE}Nova cestna vozila
+STR_9007_BUILD_VEHICLE :{BLACK}Zgradi vozilo
+STR_9009_CAN_T_BUILD_ROAD_VEHICLE :{WHITE}Ni mogoÄe zgraditi cestnega vozila ...
+STR_900C_DETAILS :{WHITE}{VEHICLE} (Podrobnosti)
+STR_900D_AGE_RUNNING_COST_YR :{BLACK}Starost: {LTBLUE}{STRING}{BLACK} Stroški obratovanja: {LTBLUE}{CURRENCY}/leto
+STR_900E_MAX_SPEED :{BLACK}Max. hitrost: {LTBLUE}{VELOCITY}
+STR_900F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Letošnji profit: {LTBLUE}{CURRENCY} (lansko leto: {CURRENCY})
+STR_9010_RELIABILITY_BREAKDOWNS :{BLACK}Zanesljivost: {LTBLUE}{COMMA}% {BLACK}Å t. okvar od zadnjega servisa: {LTBLUE}{COMMA}
+STR_9011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Zgrajen: {LTBLUE}{NUM}{BLACK} Vrednost: {LTBLUE}{CURRENCY}
+STR_9012_CAPACITY :{BLACK}Kapaciteta: {LTBLUE}{CARGO}
+STR_9013_MUST_BE_STOPPED_INSIDE :{WHITE} ... mora biti ustavljen v garaži
+STR_9014_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Ni mogoÄe prodati cestnega vozila ...
+STR_9015_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Ni mogoÄe ustaviti/zagnati cestnega vozila ...
+STR_9016_ROAD_VEHICLE_IS_WAITING :{WHITE}Cestno vozilo {COMMA} Äaka v garaži
+STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT :{WHITE}Ni mogoÄe poslati vozila v garažo ...
+STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Ni mogoÄe najti najbližje garaže
+STR_901A_ROAD_VEHICLES_CLICK_ON :{BLACK}Cestna vozila - kliknite na vozilo za informacije
+STR_901B_BUILD_NEW_ROAD_VEHICLES :{BLACK}Zgradi nova cestna vozila (zahteva garažo)
+STR_901C_CURRENT_VEHICLE_ACTION :{BLACK}Dejanja trenutnega vozila - kliknite za ustavitev/zagon vozila
+STR_901D_SHOW_VEHICLE_S_ORDERS :{BLACK}Pokaži navodila vozila
+STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE :{BLACK}Pogled na vozilo
+STR_901F_SEND_VEHICLE_TO_DEPOT :{BLACK}Pošlji vozilo v garažo. CTRL+klik samo na servis
+STR_9020_FORCE_VEHICLE_TO_TURN_AROUND :{BLACK}Prisili vozilo, da se obrne okoli
+STR_9021_SHOW_ROAD_VEHICLE_DETAILS :{BLACK}Prikaži podrobnosti cestnega vozila
+STR_9022_VEHICLES_CLICK_ON_VEHICLE :{BLACK}Vozila - kliknite na vozilo za informacije
+STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Zgradi novo cestno vozilo
+STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Povlecite cestno vozilo sem, Äe ga želite prodati
+STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Pogled na garažo
+STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Seznam cestnih vozil - kliknite na vozilo za informacije
+STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Zgradi izbrano cestno vozilo
+STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}Novo cestno vozilo sedaj na voljo!
+STR_9029 :{BLACK}{BIGFONT}{STRING}
+STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Cena: {CURRENCY}{}Hitrost: {VELOCITY}{}Stroški obratovanja: {CURRENCY}/leto{}Kapaciteta: {CARGO}
+
+STR_902C_NAME_ROAD_VEHICLE :{WHITE}Poimenuj cestno vozilo
+STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Ni mogoÄe poimenovati cestnega vozila ...
+STR_902E_NAME_ROAD_VEHICLE :{BLACK}Poimenuj cestno vozilo
+STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Prebivalci praznujejo . . .{}Prihod prvega avtobusa na postajo {STATION}!
+STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Prebivalci praznujejo . . .{}Prihod prvega tovornjaka na postajo {STATION}!
+STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}Prometna nesreÄa!{}Voznik umrl v plamenih ob trku z vlakom
+STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}Prometna nesreÄa!{}{COMMA} umrlo v plamenih ob trku z vlakom
+STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Ni mogoÄe okoli obrniti vozila ...
+STR_9034_RENAME :{BLACK}Preimenuj
+STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Preimenuj cestno vozilo
+STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Preimenuj cestno vozilo
+STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Ni mogoÄe preimenovati cestnega vozila ...
+STR_9038_GO_TO_ROADVEH_DEPOT :Pojdi v garažo v mestu {TOWN}
+
+
+##id 0x9800
+STR_9800_DOCK_CONSTRUCTION :Gradnja pomola
+STR_9801_DOCK_CONSTRUCTION :{WHITE}Gradnja pomola
+STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Ni mogoÄe zgraditi pomola tukaj ...
+STR_9803_SHIP_DEPOT :{WHITE}{TOWN} Ladjedelnica
+STR_9804_NEW_SHIPS :{BLACK}Nove ladje
+STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} Ladje
+STR_9808_NEW_SHIPS :{WHITE}Nove ladje
+STR_9809_BUILD_SHIP :{BLACK}Zgradi ladjo
+STR_CLONE_SHIP :{BLACK}Kloniraj ladjo
+STR_CLONE_SHIP_INFO :{BLACK}To bo zgradilo kopijo ladje. CTRL+klik skopira tudi navodila
+STR_CLONE_SHIP_DEPOT_INFO :{BLACK}To bo zgradilo kopijo ladje. Kliknite na ta gumb in nato na ladjo v ali zunaj ladjedelnice. CTRL+klik skopira tudi navodila
+STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}Ladja mora biti ustavljena in v ladjedelnici
+STR_980C_CAN_T_SELL_SHIP :{WHITE}Ni mogoÄe prodati ladje ...
+STR_980D_CAN_T_BUILD_SHIP :{WHITE}Ni mogoÄe zgraditi ladje ...
+STR_980E_SHIP_IN_THE_WAY :{WHITE}Ladja v napoto
+STR_980F :{WHITE}{VEHICLE}
+STR_9811_DETAILS :{WHITE}{VEHICLE} (Podrobnosti)
+STR_9812_AGE_RUNNING_COST_YR :{BLACK}Starost: {LTBLUE}{STRING}{BLACK} Stroški obratovanja: {LTBLUE}{CURRENCY}/leto
+STR_9813_MAX_SPEED :{BLACK}Max. hitrost: {LTBLUE}{VELOCITY}
+STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit letos: {LTBLUE}{CURRENCY} (lansko leto: {CURRENCY})
+STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}Zanesljivost: {LTBLUE}{COMMA}% {BLACK}Å t. okvar od zadnjegea servisa: {LTBLUE}{COMMA}
+STR_9816_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Zgrajen: {LTBLUE}{NUM}{BLACK} Vrednost: {LTBLUE}{CURRENCY}
+STR_9817_CAPACITY :{BLACK}Kapaciteta: {LTBLUE}{CARGO}
+STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING :{BLACK}Zgradi ladjedelnico (za izgradnjo in servisiranje ladij)
+STR_981F_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Ladje - kliknite na ladjo za informacije
+STR_9820_BUILD_NEW_SHIP :{BLACK}Zgradi novo ladjo
+STR_9821_DRAG_SHIP_TO_HERE_TO_SELL :{BLACK}Povlecite novo ladjo sem, Äe jo želite prodati
+STR_9822_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Pogled na ladjedelnico
+STR_9823_SHIPS_CLICK_ON_SHIP_FOR :{BLACK}Ladje - kliknite na ladjo za informacije
+STR_9824_BUILD_NEW_SHIPS_REQUIRES :{BLACK}Zgradi nove ladje (zahteva ladjedelnico)
+STR_9825_SHIP_SELECTION_LIST_CLICK :{BLACK}Seznam ladij - kliknite na ladjo za informacije
+STR_9826_BUILD_THE_HIGHLIGHTED_SHIP :{BLACK}Zgradi izbrano ladjo
+STR_9827_CURRENT_SHIP_ACTION_CLICK :{BLACK}Trenutna ladja - kliknite sem za ustavitev/zagon ladje
+STR_9828_SHOW_SHIP_S_ORDERS :{BLACK}Prikaži navodila ladje
+STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Pogled na ladjo
+STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Pošlji ladjo v ladjedelnico. CTRL+klik samo na servis
+STR_982B_SHOW_SHIP_DETAILS :{BLACK}Prikaži podrobnosti ladje
+STR_982C_NEW_SHIP_NOW_AVAILABLE :{BLACK}{BIGFONT}Nova ladja na voljo!
+STR_982D :{BLACK}{BIGFONT}{STRING}
+STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Cena: {CURRENCY} Max. hitrost: {VELOCITY}{}Kapaciteta: {CARGO}{}Stroški obratovanja: {CURRENCY}/leto
+STR_982F_NAME_SHIP :{BLACK}Poimenuj ladjo
+
+STR_9831_NAME_SHIP :{WHITE}Poimenuj ladjo
+STR_9832_CAN_T_NAME_SHIP :{WHITE}Ni mogoÄe poimenovati ladje ...
+STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Prebivalci praznujejo . . .{}Prva ladja prispela na postajo {STATION}!
+STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Postavi bojo, ki je lahko uporabljena kot smerokaz
+STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Ni mogoÄe postaviti boje tukaj ...
+STR_9836_RENAME :{BLACK}Preimenuj
+STR_9837_RENAME_SHIP_TYPE :{BLACK}Preimenuj ladjo
+STR_9838_RENAME_SHIP_TYPE :{WHITE}Preimenuj ladjo
+STR_9839_CAN_T_RENAME_SHIP_TYPE :{WHITE}Ni mogoÄe preimeonvati ladje ...
+STR_983A_REFIT_CARGO_SHIP_TO_CARRY :{BLACK}Preuredi tovorni prostor tako, da bo ladja lahko sprejela drug tovor
+STR_983B_REFIT :{WHITE}{VEHICLE} (Preuredi)
+STR_983C_REFIT_SHIP :{BLACK}Preuredi ladjo
+STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Izberite tip tovora
+STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Preuredi tovorni prostor ladje za izbrani tovor
+STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Izberite tip tovora:
+STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nova kapaciteta: {GOLD}{CARGO}{}{BLACK}Cena za preureditev: {GOLD}{CURRENCY}
+STR_9841_CAN_T_REFIT_SHIP :{WHITE}Ni mogoÄe preurediti ladje ...
+STR_9842_REFITTABLE :(spremenljivo)
+SERVICE_AT_SHIP_DEPOT :Storitev v {TOWN} doku
+
+##id 0xA000
+STR_A000_AIRPORTS :{WHITE}LetaliÅ¡Äa
+STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Ni mogoÄe zgraditi letaliÅ¡Äa tukaj ...
+STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} Hangar
+STR_A003_NEW_AIRCRAFT :{BLACK}Novo letalo
+STR_CLONE_AIRCRAFT :{BLACK}Kloniraj letalo
+STR_CLONE_AIRCRAFT_INFO :{BLACK}To bo zgradilo kopijo letala. CTRL+klik skopira tudi navodila
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}To bo zgradilo kopijo letala. Kliknite na ta gumb in nato na letalo v ali zunaj hangarja. CTRL+klik skopira tudi navodila
+STR_A005_NEW_AIRCRAFT :{WHITE}Novo letalo
+STR_A006_BUILD_AIRCRAFT :{BLACK}Zgradi letalo
+STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Ni mogoÄe zgraditi letala ...
+STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} Letalo
+STR_A00A :{WHITE}{VEHICLE}
+STR_A00B_ORDERS :{WHITE}{VEHICLE} (Navodila)
+STR_A00C_DETAILS :{WHITE}{VEHICLE} (Podrobnosti)
+STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Starost: {LTBLUE}{STRING}{BLACK} Stroški obratovanja: {LTBLUE}{CURRENCY}/leto
+STR_A00E_MAX_SPEED :{BLACK}Max. hitrost: {LTBLUE}{VELOCITY}
+STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit letos: {LTBLUE}{CURRENCY} (lansko leto: {CURRENCY})
+STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}Zanesljivost: {LTBLUE}{COMMA}% {BLACK}Å t. okvar od zadnjega servisa: {LTBLUE}{COMMA}
+STR_A011_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Zgrajen: {LTBLUE}{NUM}{BLACK} Vrednost: {LTBLUE}{CURRENCY}
+STR_A012_CAN_T_SEND_AIRCRAFT_TO :{WHITE}Ni mogoÄe poslati letala v hangar ...
+STR_A014_AIRCRAFT_IS_WAITING_IN :{WHITE}Letalo {COMMA} Äaka v hangarju
+STR_A015_AIRCRAFT_IN_THE_WAY :{WHITE}Letalo v napoto
+STR_A016_CAN_T_STOP_START_AIRCRAFT :{WHITE}Ni mogoÄe ustaviti/zagnati letala ...
+STR_A017_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Letalo v letu
+STR_A019_CAPACITY :{BLACK}Kapaciteta: {LTBLUE}{CARGO}, {CARGO}
+STR_A01A_CAPACITY :{BLACK}Kapaciteta: {LTBLUE}{CARGO}
+STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}Letalo mora biti ustavljeno v hangarju
+STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}Ni mogoÄe prodati letala ...
+STR_A01D_AIRPORT_CONSTRUCTION :Gradnja letaliÅ¡Äa
+STR_A01E_BUILD_AIRPORT :{BLACK}Zgradi letaliÅ¡Äe
+STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Letalo - kliknite na letalo za informacije
+STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}Gradnja novega letala (zahteva letaliÅ¡Äe s hangarjem)
+STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}Letalo - kliknite na letalo za informacije
+STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}Zgradi novo letalo
+STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}Povlecite letalo sem, Äe ga želite prodati
+STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}Pogled na hangar
+STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}Seznam letal - kliknite na letalo za informacije
+STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT :{BLACK}Zgradi izbrano letalo
+STR_A027_CURRENT_AIRCRAFT_ACTION :{BLACK}Trenutno letalo - kliknite sem za ustavitev/zagon letala
+STR_A028_SHOW_AIRCRAFT_S_ORDERS :{BLACK}Prikaži navodila letala
+STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Pogled na letalo
+STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Pošlji letalo v hangar. CTRL+klik samo na servis
+STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Prikaži podrobnosti letala
+STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE :{BLACK}{BIGFONT}Novo letalo na voljo!
+STR_A02D :{BLACK}{BIGFONT}{STRING}
+STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Cena: {CURRENCY} Max. hitrost: {VELOCITY}{}Kapaciteta: {COMMA} potnikov, {COMMA} vreÄ poÅ¡te{}StroÅ¡ki obratovanja: {CURRENCY}/leto
+
+STR_A030_NAME_AIRCRAFT :{WHITE}Poimenuj letalo
+STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Ni mogoÄe poimenovati letala ...
+STR_A032_NAME_AIRCRAFT :{BLACK}Poimenuj letalo
+STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Prebivalci praznujejo . . .{}Prvo letalo pristalo na postaji {STATION}!
+STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Letalska nesreÄa!{}{COMMA} umrlo v plamenih na letaliÅ¡Äu {STATION}
+STR_A036 :{TINYFONT}{BLACK}{STATION}
+STR_A037_RENAME :{BLACK}Preimenuj
+STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Preimenuj letalo
+STR_A039_RENAME_AIRCRAFT_TYPE :{WHITE}Preimenuj letalo
+STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Ni mogoÄe preimenovati letala ...
+STR_A03B_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Preuredi tovorni prostor letala, da lahko nosi drugaÄen tovor
+STR_A03C_REFIT :{WHITE}{VEHICLE} (Preuredi)
+STR_A03D_REFIT_AIRCRAFT :{BLACK}Preuredi letalo
+STR_A03E_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Izberite tip tovora
+STR_A03F_REFIT_AIRCRAFT_TO_CARRY :{BLACK}Preuredi letalo, da lahko nosi izbran tovor
+STR_A040_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Izberite tip tovora:
+STR_A041_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nova kapaciteta: {GOLD}{STRING}{}{BLACK}Cena za preureditev: {GOLD}{CURRENCY}
+STR_A042_CAN_T_REFIT_AIRCRAFT :{WHITE}Ni mogoÄe preurediti letala ...
+SERVICE_AT_AIRPORT_HANGAR :Storitev v {STATION} Hangarju
+
+##id 0xB000
+STR_B000_ZEPPELIN_DISASTER_AT :{BLACK}{BIGFONT}NesreÄa cepelina na postaji {STATION}!
+STR_B001_ROAD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Cestno vozilo uniÄeno v trku z 'NLP'!
+STR_B002_OIL_REFINERY_EXPLOSION :{BLACK}{BIGFONT}Eksplozija naftne rafinerije blizu mesta {TOWN}!
+STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}Tovarna uniÄena v sumljivih okoliÅ¡Äinah blizu mesta {TOWN}!
+STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}'NLP' pristal blizu mesta {TOWN}!
+STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}Rudnik premoga puÅ¡Äa opustoÅ¡enje v okolici mesta {TOWN}!
+STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}Poplave!{}Vsaj {COMMA} pogreÅ¡anih, najverjetneje mrtvih ob moÄnih neurjih!
+
+STR_BRIBE_FAILED :{WHITE}Vaša podkupnina je bila
+STR_BRIBE_FAILED_2 :{WHITE}odkrita s strani lokalnih preiskovalcev
+STR_BUILD_DATE :{BLACK}Zgrajeno: {LTBLUE}{DATE_LONG}
+
+SET_PERFORMANCE_DETAIL_INT :{BLACK}{NUM}
+############ Those following lines need to be in this order!!
+############ End of order list
+
+
+
+
+
+
+STR_TRAIN :{BLACK}{TRAIN}
+STR_BUS :{BLACK}{BUS}
+
+
+
+
+### depot strings
+
+
+
+
+
+
+STR_WAGONS :Vagoni
+
+
+
+
+
+
+############ Lists rail types
+
+
+############ End of list of rail types
+
+
+
+########### String for New Landscape Generator
+
+STR_CLEARING_TILES :{BLACK}Generiranje grobih in skalnatih tal
+
+
+########### String for new airports
+STR_CITY_AIRPORT :{BLACK}Mestno
+STR_COMMUTER_AIRPORT :{BLACK}VozaÄ
+
+
+############ Tooltip measurment
+
+
+########
diff --git a/src/lang/unfinished/traditional_chinese.txt b/src/lang/unfinished/traditional_chinese.txt
new file mode 100644
index 000000000..81913d445
--- /dev/null
+++ b/src/lang/unfinished/traditional_chinese.txt
@@ -0,0 +1,2 @@
+##name Chinese (Simplified)
+##isocode zh_TW.UTF-8
diff --git a/src/livery.h b/src/livery.h
new file mode 100644
index 000000000..2655dcd48
--- /dev/null
+++ b/src/livery.h
@@ -0,0 +1,58 @@
+/* $Id$ */
+
+#ifndef LIVERY_H
+#define LIVERY_H
+
+
+/* List of different livery schemes. */
+typedef enum LiverySchemes {
+ LS_DEFAULT,
+
+ /* Rail vehicles */
+ LS_STEAM,
+ LS_DIESEL,
+ LS_ELECTRIC,
+ LS_MONORAIL,
+ LS_MAGLEV,
+ LS_DMU,
+ LS_EMU,
+ LS_PASSENGER_WAGON_STEAM,
+ LS_PASSENGER_WAGON_DIESEL,
+ LS_PASSENGER_WAGON_ELECTRIC,
+ LS_FREIGHT_WAGON,
+
+ /* Road vehicles */
+ LS_BUS,
+ LS_TRUCK,
+
+ /* Ships */
+ LS_PASSENGER_SHIP,
+ LS_FREIGHT_SHIP,
+
+ /* Aircraft */
+ LS_HELICOPTER,
+ LS_SMALL_PLANE,
+ LS_LARGE_PLANE,
+
+ LS_END
+} LiveryScheme;
+
+
+/* List of different livery classes, used only by the livery GUI. */
+typedef enum LiveryClasses {
+ LC_OTHER,
+ LC_RAIL,
+ LC_ROAD,
+ LC_SHIP,
+ LC_AIRCRAFT,
+ LC_END
+} LiveryClass;
+
+
+typedef struct Livery {
+ bool in_use; ///< Set if this livery should be used instead of the default livery.
+ byte colour1; ///< First colour, for all vehicles.
+ byte colour2; ///< Second colour, for vehicles with 2CC support.
+} Livery;
+
+#endif /* LIVERY_H */
diff --git a/src/lzoconf.h b/src/lzoconf.h
new file mode 100644
index 000000000..fa50113f4
--- /dev/null
+++ b/src/lzoconf.h
@@ -0,0 +1,452 @@
+/* $Id$ */
+
+/* lzoconf.h -- configuration for the LZO real-time data compression library
+
+ This file is part of the LZO real-time data compression library.
+
+ Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
+ All Rights Reserved.
+
+ The LZO library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ The LZO library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the LZO library; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Markus F.X.J. Oberhumer
+ <markus@oberhumer.com>
+ http://www.oberhumer.com/opensource/lzo/
+ */
+
+
+#ifndef LZOCONF_H
+#define LZOCONF_H
+
+#define LZO_VERSION 0x1080
+#define LZO_VERSION_STRING "1.08"
+#define LZO_VERSION_DATE "Jul 12 2002"
+
+/* internal Autoconf configuration file - only used when building LZO */
+#if defined(LZO_HAVE_CONFIG_H)
+# include <config.h>
+#endif
+#include <limits.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/***********************************************************************
+ * LZO requires a conforming <limits.h>
+ ***********************************************************************/
+
+#if !defined(CHAR_BIT) || (CHAR_BIT != 8)
+# error "invalid CHAR_BIT"
+#endif
+#if !defined(UCHAR_MAX) || !defined(UINT_MAX) || !defined(ULONG_MAX)
+# error "check your compiler installation"
+#endif
+#if (USHRT_MAX < 1) || (UINT_MAX < 1) || (ULONG_MAX < 1)
+# error "your limits.h macros are broken"
+#endif
+
+/* workaround a cpp bug under hpux 10.20 */
+#define LZO_0xffffffffL 4294967295ul
+
+#if !defined(LZO_UINT32_C)
+# if (UINT_MAX < LZO_0xffffffffL)
+# define LZO_UINT32_C(c) c ## UL
+# else
+# define LZO_UINT32_C(c) c ## U
+# endif
+#endif
+
+
+/***********************************************************************
+ * architecture defines
+ ***********************************************************************/
+
+#if !defined(__LZO_WIN) && !defined(__LZO_DOS) && !defined(__LZO_OS2)
+# if defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows)
+# define __LZO_WIN
+# elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
+# define __LZO_WIN
+# elif defined(__NT__) || defined(__NT_DLL__) || defined(__WINDOWS_386__)
+# define __LZO_WIN
+# elif defined(__DOS__) || defined(__MSDOS__) || defined(MSDOS)
+# define __LZO_DOS
+# elif defined(__OS2__) || defined(__OS2V2__) || defined(OS2)
+# define __LZO_OS2
+# elif defined(__palmos__)
+# define __LZO_PALMOS
+# elif defined(__TOS__) || defined(__atarist__)
+# define __LZO_TOS
+# endif
+#endif
+
+#if (UINT_MAX < LZO_0xffffffffL)
+# if defined(__LZO_WIN)
+# define __LZO_WIN16
+# elif defined(__LZO_DOS)
+# define __LZO_DOS16
+# elif defined(__LZO_PALMOS)
+# define __LZO_PALMOS16
+# elif defined(__LZO_TOS)
+# define __LZO_TOS16
+# elif defined(__C166__)
+# else
+ /* porting hint: for pure 16-bit architectures try compiling
+ * everything with -D__LZO_STRICT_16BIT */
+# error "16-bit target not supported - contact me for porting hints"
+# endif
+#endif
+
+#if !defined(__LZO_i386)
+# if defined(__LZO_DOS) || defined(__LZO_WIN16)
+# define __LZO_i386
+# elif defined(__i386__) || defined(__386__) || defined(_M_IX86)
+# define __LZO_i386
+# endif
+#endif
+
+#if defined(__LZO_STRICT_16BIT)
+# if (UINT_MAX < LZO_0xffffffffL)
+# include <lzo16bit.h>
+# endif
+#endif
+
+/* memory checkers */
+#if !defined(__LZO_CHECKER)
+# if defined(__BOUNDS_CHECKING_ON)
+# define __LZO_CHECKER
+# elif defined(__CHECKER__)
+# define __LZO_CHECKER
+# elif defined(__INSURE__)
+# define __LZO_CHECKER
+# elif defined(__PURIFY__)
+# define __LZO_CHECKER
+# endif
+#endif
+
+
+/***********************************************************************
+ * integral and pointer types
+ ***********************************************************************/
+
+/* Integral types with 32 bits or more */
+#if !defined(LZO_UINT32_MAX)
+# if (UINT_MAX >= LZO_0xffffffffL)
+ typedef unsigned int lzo_uint32;
+ typedef int lzo_int32;
+# define LZO_UINT32_MAX UINT_MAX
+# define LZO_INT32_MAX INT_MAX
+# define LZO_INT32_MIN INT_MIN
+# elif (ULONG_MAX >= LZO_0xffffffffL)
+ typedef unsigned long lzo_uint32;
+ typedef long lzo_int32;
+# define LZO_UINT32_MAX ULONG_MAX
+# define LZO_INT32_MAX LONG_MAX
+# define LZO_INT32_MIN LONG_MIN
+# else
+# error "lzo_uint32"
+# endif
+#endif
+
+/* lzo_uint is used like size_t */
+#if !defined(LZO_UINT_MAX)
+# if (UINT_MAX >= LZO_0xffffffffL)
+ typedef unsigned int lzo_uint;
+ typedef int lzo_int;
+# define LZO_UINT_MAX UINT_MAX
+# define LZO_INT_MAX INT_MAX
+# define LZO_INT_MIN INT_MIN
+# elif (ULONG_MAX >= LZO_0xffffffffL)
+ typedef unsigned long lzo_uint;
+ typedef long lzo_int;
+# define LZO_UINT_MAX ULONG_MAX
+# define LZO_INT_MAX LONG_MAX
+# define LZO_INT_MIN LONG_MIN
+# else
+# error "lzo_uint"
+# endif
+#endif
+
+typedef int lzo_bool;
+
+
+/***********************************************************************
+ * memory models
+ ***********************************************************************/
+
+/* Memory model for the public code segment. */
+#if !defined(__LZO_CMODEL)
+# if defined(__LZO_DOS16) || defined(__LZO_WIN16)
+# define __LZO_CMODEL __far
+# elif defined(__LZO_i386) && defined(__WATCOMC__)
+# define __LZO_CMODEL __near
+# else
+# define __LZO_CMODEL
+# endif
+#endif
+
+/* Memory model for the public data segment. */
+#if !defined(__LZO_DMODEL)
+# if defined(__LZO_DOS16) || defined(__LZO_WIN16)
+# define __LZO_DMODEL __far
+# elif defined(__LZO_i386) && defined(__WATCOMC__)
+# define __LZO_DMODEL __near
+# else
+# define __LZO_DMODEL
+# endif
+#endif
+
+/* Memory model that allows to access memory at offsets of lzo_uint. */
+#if !defined(__LZO_MMODEL)
+# if (LZO_UINT_MAX <= UINT_MAX)
+# define __LZO_MMODEL
+# elif defined(__LZO_DOS16) || defined(__LZO_WIN16)
+# define __LZO_MMODEL __huge
+# define LZO_999_UNSUPPORTED
+# elif defined(__LZO_PALMOS16) || defined(__LZO_TOS16)
+# define __LZO_MMODEL
+# else
+# error "__LZO_MMODEL"
+# endif
+#endif
+
+/* no typedef here because of const-pointer issues */
+#define lzo_byte unsigned char __LZO_MMODEL
+#define lzo_bytep unsigned char __LZO_MMODEL *
+#define lzo_charp char __LZO_MMODEL *
+#define lzo_voidp void __LZO_MMODEL *
+#define lzo_shortp short __LZO_MMODEL *
+#define lzo_ushortp unsigned short __LZO_MMODEL *
+#define lzo_uint32p lzo_uint32 __LZO_MMODEL *
+#define lzo_int32p lzo_int32 __LZO_MMODEL *
+#define lzo_uintp lzo_uint __LZO_MMODEL *
+#define lzo_intp lzo_int __LZO_MMODEL *
+#define lzo_voidpp lzo_voidp __LZO_MMODEL *
+#define lzo_bytepp lzo_bytep __LZO_MMODEL *
+
+#ifndef lzo_sizeof_dict_t
+# define lzo_sizeof_dict_t sizeof(lzo_bytep)
+#endif
+
+
+/***********************************************************************
+ * calling conventions and function types
+ ***********************************************************************/
+
+/* linkage */
+#if !defined(__LZO_EXTERN_C)
+# ifdef __cplusplus
+# define __LZO_EXTERN_C extern "C"
+# else
+# define __LZO_EXTERN_C extern
+# endif
+#endif
+
+/* calling convention */
+#if !defined(__LZO_CDECL)
+# if defined(__LZO_DOS16) || defined(__LZO_WIN16)
+# define __LZO_CDECL __LZO_CMODEL __cdecl
+# elif defined(__LZO_i386) && defined(_MSC_VER)
+# define __LZO_CDECL __LZO_CMODEL __cdecl
+# elif defined(__LZO_i386) && defined(__WATCOMC__)
+# define __LZO_CDECL __LZO_CMODEL __cdecl
+# else
+# define __LZO_CDECL __LZO_CMODEL
+# endif
+#endif
+#if !defined(__LZO_ENTRY)
+# define __LZO_ENTRY __LZO_CDECL
+#endif
+
+/* C++ exception specification for extern "C" function types */
+#if !defined(__cplusplus)
+# undef LZO_NOTHROW
+# define LZO_NOTHROW
+#elif !defined(LZO_NOTHROW)
+# define LZO_NOTHROW
+#endif
+
+
+typedef int
+(__LZO_ENTRY *lzo_compress_t) ( const lzo_byte *src, lzo_uint src_len,
+ lzo_byte *dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem );
+
+typedef int
+(__LZO_ENTRY *lzo_decompress_t) ( const lzo_byte *src, lzo_uint src_len,
+ lzo_byte *dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem );
+
+typedef int
+(__LZO_ENTRY *lzo_optimize_t) ( lzo_byte *src, lzo_uint src_len,
+ lzo_byte *dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem );
+
+typedef int
+(__LZO_ENTRY *lzo_compress_dict_t)(const lzo_byte *src, lzo_uint src_len,
+ lzo_byte *dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem,
+ const lzo_byte *dict, lzo_uint dict_len );
+
+typedef int
+(__LZO_ENTRY *lzo_decompress_dict_t)(const lzo_byte *src, lzo_uint src_len,
+ lzo_byte *dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem,
+ const lzo_byte *dict, lzo_uint dict_len );
+
+
+/* assembler versions always use __cdecl */
+typedef int
+(__LZO_CDECL *lzo_compress_asm_t)( const lzo_byte *src, lzo_uint src_len,
+ lzo_byte *dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem );
+
+typedef int
+(__LZO_CDECL *lzo_decompress_asm_t)( const lzo_byte *src, lzo_uint src_len,
+ lzo_byte *dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem );
+
+
+/* a progress indicator callback function */
+typedef void (__LZO_ENTRY *lzo_progress_callback_t) (lzo_uint, lzo_uint);
+
+
+/***********************************************************************
+ * export information
+ ***********************************************************************/
+
+/* DLL export information */
+#if !defined(__LZO_EXPORT1)
+# define __LZO_EXPORT1
+#endif
+#if !defined(__LZO_EXPORT2)
+# define __LZO_EXPORT2
+#endif
+
+/* exported calling convention for C functions */
+#if !defined(LZO_PUBLIC)
+# define LZO_PUBLIC(_rettype) \
+ __LZO_EXPORT1 _rettype __LZO_EXPORT2 __LZO_ENTRY
+#endif
+#if !defined(LZO_EXTERN)
+# define LZO_EXTERN(_rettype) __LZO_EXTERN_C LZO_PUBLIC(_rettype)
+#endif
+#if !defined(LZO_PRIVATE)
+# define LZO_PRIVATE(_rettype) static _rettype __LZO_ENTRY
+#endif
+
+/* exported __cdecl calling convention for assembler functions */
+#if !defined(LZO_PUBLIC_CDECL)
+# define LZO_PUBLIC_CDECL(_rettype) \
+ __LZO_EXPORT1 _rettype __LZO_EXPORT2 __LZO_CDECL
+#endif
+#if !defined(LZO_EXTERN_CDECL)
+# define LZO_EXTERN_CDECL(_rettype) __LZO_EXTERN_C LZO_PUBLIC_CDECL(_rettype)
+#endif
+
+/* exported global variables (LZO currently uses no static variables and
+ * is fully thread safe) */
+#if !defined(LZO_PUBLIC_VAR)
+# define LZO_PUBLIC_VAR(_type) \
+ __LZO_EXPORT1 _type __LZO_EXPORT2 __LZO_DMODEL
+#endif
+#if !defined(LZO_EXTERN_VAR)
+# define LZO_EXTERN_VAR(_type) extern LZO_PUBLIC_VAR(_type)
+#endif
+
+
+/***********************************************************************
+ * error codes and prototypes
+ ***********************************************************************/
+
+/* Error codes for the compression/decompression functions. Negative
+ * values are errors, positive values will be used for special but
+ * normal events.
+ */
+#define LZO_E_OK 0
+#define LZO_E_ERROR (-1)
+#define LZO_E_OUT_OF_MEMORY (-2) /* not used right now */
+#define LZO_E_NOT_COMPRESSIBLE (-3) /* not used right now */
+#define LZO_E_INPUT_OVERRUN (-4)
+#define LZO_E_OUTPUT_OVERRUN (-5)
+#define LZO_E_LOOKBEHIND_OVERRUN (-6)
+#define LZO_E_EOF_NOT_FOUND (-7)
+#define LZO_E_INPUT_NOT_CONSUMED (-8)
+
+
+/* lzo_init() should be the first function you call.
+ * Check the return code !
+ *
+ * lzo_init() is a macro to allow checking that the library and the
+ * compiler's view of various types are consistent.
+ */
+#define lzo_init() __lzo_init2(LZO_VERSION,(int)sizeof(short),(int)sizeof(int),\
+ (int)sizeof(long),(int)sizeof(lzo_uint32),(int)sizeof(lzo_uint),\
+ (int)lzo_sizeof_dict_t,(int)sizeof(char *),(int)sizeof(lzo_voidp),\
+ (int)sizeof(lzo_compress_t))
+LZO_EXTERN(int) __lzo_init2(unsigned,int,int,int,int,int,int,int,int,int);
+
+/* version functions (useful for shared libraries) */
+LZO_EXTERN(unsigned) lzo_version(void);
+LZO_EXTERN(const char *) lzo_version_string(void);
+LZO_EXTERN(const char *) lzo_version_date(void);
+LZO_EXTERN(const lzo_charp) _lzo_version_string(void);
+LZO_EXTERN(const lzo_charp) _lzo_version_date(void);
+
+/* string functions */
+LZO_EXTERN(int)
+lzo_memcmp(const lzo_voidp _s1, const lzo_voidp _s2, lzo_uint _len);
+LZO_EXTERN(lzo_voidp)
+lzo_memcpy(lzo_voidp _dest, const lzo_voidp _src, lzo_uint _len);
+LZO_EXTERN(lzo_voidp)
+lzo_memmove(lzo_voidp _dest, const lzo_voidp _src, lzo_uint _len);
+LZO_EXTERN(lzo_voidp)
+lzo_memset(lzo_voidp _s, int _c, lzo_uint _len);
+
+/* checksum functions */
+LZO_EXTERN(lzo_uint32)
+lzo_adler32(lzo_uint32 _adler, const lzo_byte *_buf, lzo_uint _len);
+LZO_EXTERN(lzo_uint32)
+lzo_crc32(lzo_uint32 _c, const lzo_byte *_buf, lzo_uint _len);
+
+/* misc. */
+LZO_EXTERN(lzo_bool) lzo_assert(int _expr);
+LZO_EXTERN(int) _lzo_config_check(void);
+typedef union { lzo_bytep p; lzo_uint u; } __lzo_pu_u;
+typedef union { lzo_bytep p; lzo_uint32 u32; } __lzo_pu32_u;
+typedef union { void *vp; lzo_bytep bp; lzo_uint32 u32; long l; } lzo_align_t;
+
+/* align a char pointer on a boundary that is a multiple of `size' */
+LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp _ptr, lzo_uint _size);
+#define LZO_PTR_ALIGN_UP(_ptr,_size) \
+ ((_ptr) + (lzo_uint) __lzo_align_gap((const lzo_voidp)(_ptr),(lzo_uint)(_size)))
+
+/* deprecated - only for backward compatibility */
+#define LZO_ALIGN(_ptr,_size) LZO_PTR_ALIGN_UP(_ptr,_size)
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* LZOCONF_H */
diff --git a/src/macros.h b/src/macros.h
new file mode 100644
index 000000000..8e310c07e
--- /dev/null
+++ b/src/macros.h
@@ -0,0 +1,190 @@
+/* $Id$ */
+
+#ifndef MACROS_H
+#define MACROS_H
+
+#include "map.h"
+
+/// Fetch n bits starting at bit s from x
+#define GB(x, s, n) (((x) >> (s)) & ((1U << (n)) - 1))
+/// Set n bits starting at bit s in x to d
+#define SB(x, s, n, d) ((x) = ((x) & ~(((1U << (n)) - 1) << (s))) | ((d) << (s)))
+/// Add i to the n bits starting at bit s in x
+#define AB(x, s, n, i) ((x) = ((x) & ~(((1U << (n)) - 1) << (s))) | (((x) + ((i) << (s))) & (((1U << (n)) - 1) << (s))))
+
+#ifdef min
+#undef min
+#endif
+
+#ifdef max
+#undef max
+#endif
+
+static inline int min(int a, int b) { if (a <= b) return a; return b; }
+static inline int max(int a, int b) { if (a >= b) return a; return b; }
+static inline int64 max64(int64 a, int64 b) { if (a >= b) return a; return b; }
+
+static inline uint minu(uint a, uint b) { if (a <= b) return a; return b; }
+static inline uint maxu(uint a, uint b) { if (a >= b) return a; return b; }
+
+
+static inline int clamp(int a, int min, int max)
+{
+ if (a <= min) return min;
+ if (a >= max) return max;
+ return a;
+}
+
+static inline uint clampu(uint a, uint min, uint max)
+{
+ if (a <= min) return min;
+ if (a >= max) return max;
+ return a;
+}
+
+static inline int32 BIGMULSS(int32 a, int32 b, int shift) {
+ return (int32)(((int64)(a) * (int64)(b)) >> (shift));
+}
+
+static inline int64 BIGMULSS64(int64 a, int64 b, int shift) {
+ return ((a) * (b)) >> (shift);
+}
+
+static inline uint32 BIGMULUS(uint32 a, uint32 b, int shift) {
+ return (uint32)(((uint64)(a) * (uint64)(b)) >> (shift));
+}
+
+static inline int64 BIGMULS(int32 a, int32 b) {
+ return (int64)(a) * (int64)(b);
+}
+
+/* OPT: optimized into an unsigned comparison */
+//#define IS_INSIDE_1D(x, base, size) ((x) >= (base) && (x) < (base) + (size))
+#define IS_INSIDE_1D(x, base, size) ( (uint)((x) - (base)) < ((uint)(size)) )
+
+
+#define HASBIT(x,y) (((x) & (1 << (y))) != 0)
+#define SETBIT(x,y) ((x) |= (1 << (y)))
+#define CLRBIT(x,y) ((x) &= ~(1 << (y)))
+#define TOGGLEBIT(x,y) ((x) ^= (1 << (y)))
+
+// checking more bits. Maybe unneccessary, but easy to use
+#define HASBITS(x,y) ((x) & (y))
+#define SETBITS(x,y) ((x) |= (y))
+#define CLRBITS(x,y) ((x) &= ~(y))
+
+#define GENERAL_SPRITE_COLOR(color) ( ((color) + PALETTE_RECOLOR_START) << PALETTE_SPRITE_START)
+#define PLAYER_SPRITE_COLOR(owner) ( GENERAL_SPRITE_COLOR(_player_colors[owner]))
+#define SPRITE_PALETTE(x) ((x) | PALETTE_MODIFIER_COLOR)
+
+extern const byte _ffb_64[128];
+/* Returns the position of the first bit that is not zero, counted from the
+ * left. Ie, 10110100 returns 2, 00000001 returns 0, etc. When x == 0 returns
+ * 0.
+ */
+#define FIND_FIRST_BIT(x) _ffb_64[(x)]
+/* Returns x with the first bit that is not zero, counted from the left, set
+ * to zero. So, 10110100 returns 10110000, 00000001 returns 00000000, etc.
+ */
+#define KILL_FIRST_BIT(x) _ffb_64[(x)+64]
+
+static inline int FindFirstBit2x64(int value)
+{
+/*
+ int i = 0;
+ if ( (byte) value == 0) {
+ i += 8;
+ value >>= 8;
+ }
+ return i + FIND_FIRST_BIT(value & 0x3F);
+
+Faster ( or at least cleaner ) implementation below?
+*/
+ if (GB(value, 0, 8) == 0) {
+ return FIND_FIRST_BIT(GB(value, 8, 6)) + 8;
+ } else {
+ return FIND_FIRST_BIT(GB(value, 0, 6));
+ }
+
+}
+
+static inline int KillFirstBit2x64(int value)
+{
+ if (GB(value, 0, 8) == 0) {
+ return KILL_FIRST_BIT(GB(value, 8, 6)) << 8;
+ } else {
+ return value & (KILL_FIRST_BIT(GB(value, 0, 6)) | 0x3F00);
+ }
+}
+
+/** returns true if value a has only one bit set to 1 */
+#define HAS_SINGLE_BIT(a) ( ((a) & ((a) - 1)) == 0)
+
+/* [min,max), strictly less than */
+#define IS_BYTE_INSIDE(a,min,max) ((byte)((a)-(min)) < (byte)((max)-(min)))
+#define IS_INT_INSIDE(a,min,max) ((uint)((a)-(min)) < (uint)((max)-(min)))
+
+
+#define CHANCE16(a,b) ((uint16)Random() <= (uint16)((65536 * (a)) / (b)))
+#define CHANCE16R(a,b,r) ((uint16)(r=Random()) <= (uint16)((65536 * (a)) / (b)))
+#define CHANCE16I(a,b,v) ((uint16)(v) <= (uint16)((65536 * (a)) / (b)))
+
+
+#define for_each_bit(_i, _b) \
+ for (_i = 0; _b != 0; _i++, _b >>= 1) \
+ if (_b & 1)
+
+#define abs myabs
+
+
+static inline int intxchg_(int *a, int b) { int t = *a; *a = b; return t; }
+#define intswap(a,b) ((b) = intxchg_(&(a), (b)))
+static inline int uintxchg_(uint *a, uint b) { uint t = *a; *a = b; return t; }
+#define uintswap(a,b) ((b) = uintxchg_(&(a), (b)))
+
+static inline int myabs(int a) { if (a<0) a = -a; return a; }
+static inline int64 myabs64(int64 a) { if (a<0) a = -a; return a; }
+
+static inline void swap_byte(byte *a, byte *b) { byte t = *a; *a = *b; *b = t; }
+static inline void swap_uint16(uint16 *a, uint16 *b) { uint16 t = *a; *a = *b; *b = t; }
+static inline void swap_int16(int16 *a, int16 *b) { int16 t = *a; *a = *b; *b = t; }
+static inline void swap_uint32(uint32 *a, uint32 *b) { uint32 t = *a; *a = *b; *b = t; }
+static inline void swap_int32(int32 *a, int32 *b) { int32 t = *a; *a = *b; *b = t; }
+static inline void swap_tile(TileIndex *a, TileIndex *b) { TileIndex t = *a; *a = *b; *b = t; }
+
+
+static inline uint16 ReadLE16Aligned(const void* x)
+{
+ return FROM_LE16(*(const uint16*)x);
+}
+
+static inline uint16 ReadLE16Unaligned(const void* x)
+{
+#ifdef OTTD_ALIGNMENT
+ return ((const byte*)x)[0] | ((const byte*)x)[1] << 8;
+#else
+ return FROM_LE16(*(const uint16*)x);
+#endif
+}
+
+
+/**
+ * ROtate x Left/Right by n (must be >= 0)
+ * @note Assumes a byte has 8 bits
+ */
+#define ROL(x, n) ((x) << (n) | (x) >> (sizeof(x) * 8 - (n)))
+#define ROR(x, n) ((x) >> (n) | (x) << (sizeof(x) * 8 - (n)))
+
+/**
+ * Return the smallest multiple of n equal or greater than x
+ * @note n must be a power of 2
+ */
+#define ALIGN(x, n) (((x) + (n) - 1) & ~((n) - 1))
+
+/** return the largest value that can be entered in a variable.
+ * known to work for uint32.
+ * used by TGP to set the max value of the _patches.generation_seed in its definition
+ */
+#define MAX_UVALUE(type) ((type)~(type)0)
+
+#endif /* MACROS_H */
diff --git a/src/main_gui.c b/src/main_gui.c
new file mode 100644
index 000000000..e2b816e75
--- /dev/null
+++ b/src/main_gui.c
@@ -0,0 +1,2436 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "heightmap.h"
+#include "currency.h"
+#include "functions.h"
+#include "spritecache.h"
+#include "station.h"
+#include "strings.h"
+#include "table/sprites.h"
+#include "table/strings.h"
+#include "map.h"
+#include "tile.h"
+#include "window.h"
+#include "gui.h"
+#include "viewport.h"
+#include "gfx.h"
+#include "player.h"
+#include "command.h"
+#include "news.h"
+#include "town.h"
+#include "vehicle.h"
+#include "console.h"
+#include "sound.h"
+#include "network/network.h"
+#include "signs.h"
+#include "waypoint.h"
+#include "variables.h"
+#include "train.h"
+#include "unmovable_map.h"
+#include "string.h"
+#include "screenshot.h"
+#include "genworld.h"
+#include "settings.h"
+#include "date.h"
+#include "vehicle_gui.h"
+#include "newgrf_config.h"
+
+#include "network/network_data.h"
+#include "network/network_client.h"
+#include "network/network_server.h"
+#include "network/network_gui.h"
+#include "industry.h"
+
+static int _rename_id = 1;
+static int _rename_what = -1;
+
+static byte _terraform_size = 1;
+RailType _last_built_railtype;
+static int _scengen_town_size = 2; // depress medium-sized towns per default
+
+extern void GenerateIndustries(void);
+extern bool GenerateTowns(void);
+
+
+void HandleOnEditText(const char *str)
+{
+ int id = _rename_id;
+ _cmd_text = str;
+
+ switch (_rename_what) {
+ case 0: /* Rename a s sign, if string is empty, delete sign */
+ DoCommandP(0, id, 0, NULL, CMD_RENAME_SIGN | CMD_MSG(STR_280C_CAN_T_CHANGE_SIGN_NAME));
+ break;
+ case 1: /* Rename a waypoint */
+ if (*str == '\0') return;
+ DoCommandP(0, id, 0, NULL, CMD_RENAME_WAYPOINT | CMD_MSG(STR_CANT_CHANGE_WAYPOINT_NAME));
+ break;
+#ifdef ENABLE_NETWORK
+ case 3: { /* Give money, you can only give money in excess of loan */
+ const Player *p = GetPlayer(_current_player);
+ int32 money = min(p->money64 - p->current_loan, atoi(str) / _currency->rate);
+ char msg[20];
+
+ money = clamp(money, 0, 20000000); // Clamp between 20 million and 0
+
+ // Give 'id' the money, and substract it from ourself
+ if (!DoCommandP(0, money, id, NULL, CMD_GIVE_MONEY | CMD_MSG(STR_INSUFFICIENT_FUNDS))) break;
+
+ // Inform the player of this action
+ snprintf(msg, sizeof(msg), "%d", money);
+
+ if (!_network_server) {
+ SEND_COMMAND(PACKET_CLIENT_CHAT)(NETWORK_ACTION_GIVE_MONEY, DESTTYPE_TEAM, id, msg);
+ } else {
+ NetworkServer_HandleChat(NETWORK_ACTION_GIVE_MONEY, DESTTYPE_TEAM, id, msg, NETWORK_SERVER_INDEX);
+ }
+ } break;
+#endif /* ENABLE_NETWORK */
+ default: NOT_REACHED();
+ }
+
+ _rename_id = _rename_what = -1;
+}
+
+/**
+ * This code is shared for the majority of the pushbuttons.
+ * Handles e.g. the pressing of a button (to build things), playing of click sound and sets certain parameters
+ *
+ * @param w Window which called the function
+ * @param widget ID of the widget (=button) that called this function
+ * @param cursor How should the cursor image change? E.g. cursor with depot image in it
+ * @param mode Tile highlighting mode, e.g. drawing a rectangle or a dot on the ground
+ * @param placeproc Procedure which will be called when someone clicks on the map
+
+ * @return true if the button is clicked, false if it's unclicked
+ */
+bool HandlePlacePushButton(Window *w, int widget, CursorID cursor, int mode, PlaceProc *placeproc)
+{
+ if (IsWindowWidgetDisabled(w, widget)) return false;
+
+ SndPlayFx(SND_15_BEEP);
+ SetWindowDirty(w);
+
+ if (IsWindowWidgetLowered(w, widget)) {
+ ResetObjectToPlace();
+ return false;
+ }
+
+ SetObjectToPlace(cursor, mode, w->window_class, w->window_number);
+ LowerWindowWidget(w, widget);
+ _place_proc = placeproc;
+ return true;
+}
+
+
+void CcPlaySound10(bool success, TileIndex tile, uint32 p1, uint32 p2)
+{
+ if (success) SndPlayTileFx(SND_12_EXPLOSION, tile);
+}
+
+
+static void ToolbarPauseClick(Window *w)
+{
+ if (_networking && !_network_server) return; // only server can pause the game
+
+ if (DoCommandP(0, _pause ? 0 : 1, 0, NULL, CMD_PAUSE)) SndPlayFx(SND_15_BEEP);
+}
+
+static void ToolbarFastForwardClick(Window *w)
+{
+ _fast_forward ^= true;
+ SndPlayFx(SND_15_BEEP);
+}
+
+
+static void MenuClickSettings(int index)
+{
+ switch (index) {
+ case 0: ShowGameOptions(); return;
+ case 1: ShowGameDifficulty(); return;
+ case 2: ShowPatchesSelection(); return;
+ case 3: ShowNewGRFSettings(!_networking, true, true, &_grfconfig); return;
+
+ case 5: _display_opt ^= DO_SHOW_TOWN_NAMES; break;
+ case 6: _display_opt ^= DO_SHOW_STATION_NAMES; break;
+ case 7: _display_opt ^= DO_SHOW_SIGNS; break;
+ case 8: _display_opt ^= DO_WAYPOINTS; break;
+ case 9: _display_opt ^= DO_FULL_ANIMATION; break;
+ case 10: _display_opt ^= DO_FULL_DETAIL; break;
+ case 11: _display_opt ^= DO_TRANS_BUILDINGS; break;
+ case 12: _display_opt ^= DO_TRANS_SIGNS; break;
+ }
+ MarkWholeScreenDirty();
+}
+
+static void MenuClickSaveLoad(int index)
+{
+ if (_game_mode == GM_EDITOR) {
+ switch (index) {
+ case 0: ShowSaveLoadDialog(SLD_SAVE_SCENARIO); break;
+ case 1: ShowSaveLoadDialog(SLD_LOAD_SCENARIO); break;
+ case 2: AskExitToGameMenu(); break;
+ case 4: HandleExitGameRequest(); break;
+ }
+ } else {
+ switch (index) {
+ case 0: ShowSaveLoadDialog(SLD_SAVE_GAME); break;
+ case 1: ShowSaveLoadDialog(SLD_LOAD_GAME); break;
+ case 2: AskExitToGameMenu(); break;
+ case 3: HandleExitGameRequest(); break;
+ }
+ }
+}
+
+static void MenuClickMap(int index)
+{
+ switch (index) {
+ case 0: ShowSmallMap(); break;
+ case 1: ShowExtraViewPortWindow(); break;
+ case 2: ShowSignList(); break;
+ }
+}
+
+static void MenuClickTown(int index)
+{
+ ShowTownDirectory();
+}
+
+static void MenuClickScenMap(int index)
+{
+ switch (index) {
+ case 0: ShowSmallMap(); break;
+ case 1: ShowExtraViewPortWindow(); break;
+ case 2: ShowSignList(); break;
+ case 3: ShowTownDirectory(); break;
+ }
+}
+
+static void MenuClickSubsidies(int index)
+{
+ ShowSubsidiesList();
+}
+
+static void MenuClickStations(int index)
+{
+ ShowPlayerStations(index);
+}
+
+static void MenuClickFinances(int index)
+{
+ ShowPlayerFinances(index);
+}
+
+static void MenuClickCompany(int index)
+{
+ if (_networking && index == 0) {
+ ShowClientList();
+ } else {
+ if (_networking) index--;
+ ShowPlayerCompany(index);
+ }
+}
+
+static void MenuClickGraphs(int index)
+{
+ switch (index) {
+ case 0: ShowOperatingProfitGraph(); break;
+ case 1: ShowIncomeGraph(); break;
+ case 2: ShowDeliveredCargoGraph(); break;
+ case 3: ShowPerformanceHistoryGraph(); break;
+ case 4: ShowCompanyValueGraph(); break;
+ case 5: ShowCargoPaymentRates(); break;
+ }
+}
+
+static void MenuClickLeague(int index)
+{
+ switch (index) {
+ case 0: ShowCompanyLeagueTable(); break;
+ case 1: ShowPerformanceRatingDetail(); break;
+ }
+}
+
+static void MenuClickIndustry(int index)
+{
+ switch (index) {
+ case 0: ShowIndustryDirectory(); break;
+ case 1: ShowBuildIndustryWindow(); break;
+ }
+}
+
+static void MenuClickShowTrains(int index)
+{
+ ShowVehicleListWindow(index, INVALID_STATION, VEH_Train);
+}
+
+static void MenuClickShowRoad(int index)
+{
+ ShowVehicleListWindow(index, INVALID_STATION, VEH_Road);
+}
+
+static void MenuClickShowShips(int index)
+{
+ ShowVehicleListWindow(index, INVALID_STATION, VEH_Ship);
+}
+
+static void MenuClickShowAir(int index)
+{
+ ShowVehicleListWindow(index, INVALID_STATION, VEH_Aircraft);
+}
+
+static void MenuClickBuildRail(int index)
+{
+ _last_built_railtype = index;
+ ShowBuildRailToolbar(_last_built_railtype, -1);
+}
+
+static void MenuClickBuildRoad(int index)
+{
+ ShowBuildRoadToolbar();
+}
+
+static void MenuClickBuildWater(int index)
+{
+ ShowBuildDocksToolbar();
+}
+
+static void MenuClickBuildAir(int index)
+{
+ ShowBuildAirToolbar();
+}
+
+#ifdef ENABLE_NETWORK
+void ShowNetworkGiveMoneyWindow(PlayerID player)
+{
+ _rename_id = player;
+ _rename_what = 3;
+ ShowQueryString(STR_EMPTY, STR_NETWORK_GIVE_MONEY_CAPTION, 30, 180, NULL, CS_NUMERAL);
+}
+#endif /* ENABLE_NETWORK */
+
+void ShowRenameSignWindow(const Sign *si)
+{
+ _rename_id = si->index;
+ _rename_what = 0;
+ ShowQueryString(si->str, STR_280B_EDIT_SIGN_TEXT, 30, 180, NULL, CS_ALPHANUMERAL);
+}
+
+void ShowRenameWaypointWindow(const Waypoint *wp)
+{
+ int id = wp->index;
+
+ /* Are we allowed to change the name of the waypoint? */
+ if (!CheckTileOwnership(wp->xy)) {
+ ShowErrorMessage(_error_message, STR_CANT_CHANGE_WAYPOINT_NAME,
+ TileX(wp->xy) * TILE_SIZE, TileY(wp->xy) * TILE_SIZE);
+ return;
+ }
+
+ _rename_id = id;
+ _rename_what = 1;
+ SetDParam(0, id);
+ ShowQueryString(STR_WAYPOINT_RAW, STR_EDIT_WAYPOINT_NAME, 30, 180, NULL, CS_ALPHANUMERAL);
+}
+
+static void SelectSignTool(void)
+{
+ if (_cursor.sprite == SPR_CURSOR_SIGN) {
+ ResetObjectToPlace();
+ } else {
+ SetObjectToPlace(SPR_CURSOR_SIGN, 1, 1, 0);
+ _place_proc = PlaceProc_Sign;
+ }
+}
+
+static void MenuClickForest(int index)
+{
+ switch (index) {
+ case 0: ShowTerraformToolbar(); break;
+ case 1: ShowBuildTreesToolbar(); break;
+ case 2: SelectSignTool(); break;
+ }
+}
+
+static void MenuClickMusicWindow(int index)
+{
+ ShowMusicWindow();
+}
+
+static void MenuClickNewspaper(int index)
+{
+ switch (index) {
+ case 0: ShowLastNewsMessage(); break;
+ case 1: ShowMessageOptions(); break;
+ case 2: ShowMessageHistory(); break;
+ }
+}
+
+static void MenuClickSmallScreenshot(void)
+{
+ SetScreenshotType(SC_VIEWPORT);
+}
+
+static void MenuClickWorldScreenshot(void)
+{
+ SetScreenshotType(SC_WORLD);
+}
+
+static void MenuClickHelp(int index)
+{
+ switch (index) {
+ case 0: PlaceLandBlockInfo(); break;
+ case 2: IConsoleSwitch(); break;
+ case 3: MenuClickSmallScreenshot(); break;
+ case 4: MenuClickWorldScreenshot(); break;
+ case 5: ShowAboutWindow(); break;
+ }
+}
+
+
+typedef void MenuClickedProc(int index);
+
+static MenuClickedProc * const _menu_clicked_procs[] = {
+ NULL, /* 0 */
+ NULL, /* 1 */
+ MenuClickSettings, /* 2 */
+ MenuClickSaveLoad, /* 3 */
+ MenuClickMap, /* 4 */
+ MenuClickTown, /* 5 */
+ MenuClickSubsidies, /* 6 */
+ MenuClickStations, /* 7 */
+ MenuClickFinances, /* 8 */
+ MenuClickCompany, /* 9 */
+ MenuClickGraphs, /* 10 */
+ MenuClickLeague, /* 11 */
+ MenuClickIndustry, /* 12 */
+ MenuClickShowTrains, /* 13 */
+ MenuClickShowRoad, /* 14 */
+ MenuClickShowShips, /* 15 */
+ MenuClickShowAir, /* 16 */
+ MenuClickScenMap, /* 17 */
+ NULL, /* 18 */
+ MenuClickBuildRail, /* 19 */
+ MenuClickBuildRoad, /* 20 */
+ MenuClickBuildWater, /* 21 */
+ MenuClickBuildAir, /* 22 */
+ MenuClickForest, /* 23 */
+ MenuClickMusicWindow, /* 24 */
+ MenuClickNewspaper, /* 25 */
+ MenuClickHelp, /* 26 */
+};
+
+static void MenuWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_CREATE: w->widget[0].right = w->width - 1; break;
+
+ case WE_PAINT: {
+ int x, y;
+
+ byte count = WP(w, menu_d).item_count;
+ byte sel = WP(w, menu_d).sel_index;
+ uint16 chk = WP(w, menu_d).checked_items;
+ StringID string = WP(w, menu_d).string_id;
+ byte dis = WP(w, menu_d).disabled_items;
+
+ DrawWindowWidgets(w);
+
+ x = 1;
+ y = 1;
+
+ for (; count != 0; count--, string++, sel--) {
+ byte color = HASBIT(dis, 0) ? 14 : (sel == 0) ? 12 : 16;
+ if (sel == 0) GfxFillRect(x, y, x + w->width - 3, y + 9, 0);
+
+ if (HASBIT(chk, 0)) DrawString(x + 2, y, STR_CHECKMARK, color);
+ DrawString(x + 2, y, string, color);
+
+ y += 10;
+ chk >>= 1;
+ dis >>= 1;
+ }
+ } break;
+
+ case WE_DESTROY: {
+ Window *v = FindWindowById(WC_MAIN_TOOLBAR, 0);
+ RaiseWindowWidget(v, WP(w,menu_d).main_button);
+ SetWindowDirty(v);
+ return;
+ }
+
+ case WE_POPUPMENU_SELECT: {
+ int index = GetMenuItemIndex(w, e->we.popupmenu.pt.x, e->we.popupmenu.pt.y);
+ int action_id;
+
+
+ if (index < 0) {
+ Window *w2 = FindWindowById(WC_MAIN_TOOLBAR,0);
+ if (GetWidgetFromPos(w2, e->we.popupmenu.pt.x - w2->left, e->we.popupmenu.pt.y - w2->top) == WP(w,menu_d).main_button)
+ index = WP(w,menu_d).sel_index;
+ }
+
+ action_id = WP(w,menu_d).action_id;
+ DeleteWindow(w);
+
+ if (index >= 0) {
+ assert((uint)index <= lengthof(_menu_clicked_procs));
+ _menu_clicked_procs[action_id](index);
+ }
+
+ break;
+ }
+
+ case WE_POPUPMENU_OVER: {
+ int index = GetMenuItemIndex(w, e->we.popupmenu.pt.x, e->we.popupmenu.pt.y);
+
+ if (index == -1 || index == WP(w,menu_d).sel_index) return;
+
+ WP(w,menu_d).sel_index = index;
+ SetWindowDirty(w);
+ return;
+ }
+ }
+}
+
+/* Dynamic widget length determined by toolbar-string length.
+ * See PopupMainToolbMenu en MenuWndProc */
+static const Widget _menu_widgets[] = {
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 0, 0, 0, 0x0, STR_NULL},
+{ WIDGETS_END},
+};
+
+
+static const Widget _player_menu_widgets[] = {
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 240, 0, 81, 0x0, STR_NULL},
+{ WIDGETS_END},
+};
+
+
+static int GetPlayerIndexFromMenu(int index)
+{
+ if (index >= 0) {
+ const Player *p;
+
+ FOR_ALL_PLAYERS(p) {
+ if (p->is_active && --index < 0) return p->index;
+ }
+ }
+ return -1;
+}
+
+static void UpdatePlayerMenuHeight(Window *w)
+{
+ byte num = ActivePlayerCount();
+
+ // Increase one to fit in PlayerList in the menu when in network
+ if (_networking && WP(w,menu_d).main_button == 9) num++;
+
+ if (WP(w,menu_d).item_count != num) {
+ WP(w,menu_d).item_count = num;
+ SetWindowDirty(w);
+ num = num * 10 + 2;
+ w->height = num;
+ w->widget[0].bottom = w->widget[0].top + num - 1;
+ SetWindowDirty(w);
+ }
+}
+
+extern void DrawPlayerIcon(PlayerID pid, int x, int y);
+
+static void PlayerMenuWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ int x,y;
+ byte sel, color;
+ Player *p;
+ uint16 chk;
+
+ UpdatePlayerMenuHeight(w);
+ DrawWindowWidgets(w);
+
+ x = 1;
+ y = 1;
+ sel = WP(w,menu_d).sel_index;
+ chk = WP(w,menu_d).checked_items; // let this mean gray items.
+
+ // 9 = playerlist
+ if (_networking && WP(w,menu_d).main_button == 9) {
+ if (sel == 0) {
+ GfxFillRect(x, y, x + 238, y + 9, 0);
+ }
+ DrawString(x + 19, y, STR_NETWORK_CLIENT_LIST, 0x0);
+ y += 10;
+ sel--;
+ }
+
+ FOR_ALL_PLAYERS(p) {
+ if (p->is_active) {
+ if (p->index == sel) {
+ GfxFillRect(x, y, x + 238, y + 9, 0);
+ }
+
+ DrawPlayerIcon(p->index, x + 2, y + 1);
+
+ SetDParam(0, p->name_1);
+ SetDParam(1, p->name_2);
+ SetDParam(2, GetPlayerNameString(p->index, 3));
+
+ color = (p->index == sel) ? 0xC : 0x10;
+ if (chk&1) color = 14;
+ DrawString(x + 19, y, STR_7021, color);
+
+ y += 10;
+ }
+ chk >>= 1;
+ }
+
+ break;
+ }
+
+ case WE_DESTROY: {
+ Window *v = FindWindowById(WC_MAIN_TOOLBAR, 0);
+ RaiseWindowWidget(v, WP(w,menu_d).main_button);
+ SetWindowDirty(v);
+ return;
+ }
+
+ case WE_POPUPMENU_SELECT: {
+ int index = GetMenuItemIndex(w, e->we.popupmenu.pt.x, e->we.popupmenu.pt.y);
+ int action_id = WP(w,menu_d).action_id;
+
+ // We have a new entry at the top of the list of menu 9 when networking
+ // so keep that in count
+ if (_networking && WP(w,menu_d).main_button == 9) {
+ if (index > 0) index = GetPlayerIndexFromMenu(index - 1) + 1;
+ } else {
+ index = GetPlayerIndexFromMenu(index);
+ }
+
+ if (index < 0) {
+ Window *w2 = FindWindowById(WC_MAIN_TOOLBAR,0);
+ if (GetWidgetFromPos(w2, e->we.popupmenu.pt.x - w2->left, e->we.popupmenu.pt.y - w2->top) == WP(w,menu_d).main_button)
+ index = WP(w,menu_d).sel_index;
+ }
+
+ DeleteWindow(w);
+
+ if (index >= 0) {
+ assert(index >= 0 && index < 30);
+ _menu_clicked_procs[action_id](index);
+ }
+ break;
+ }
+ case WE_POPUPMENU_OVER: {
+ int index;
+ UpdatePlayerMenuHeight(w);
+ index = GetMenuItemIndex(w, e->we.popupmenu.pt.x, e->we.popupmenu.pt.y);
+
+ // We have a new entry at the top of the list of menu 9 when networking
+ // so keep that in count
+ if (_networking && WP(w,menu_d).main_button == 9) {
+ if (index > 0) index = GetPlayerIndexFromMenu(index - 1) + 1;
+ } else {
+ index = GetPlayerIndexFromMenu(index);
+ }
+
+ if (index == -1 || index == WP(w,menu_d).sel_index) return;
+
+ WP(w,menu_d).sel_index = index;
+ SetWindowDirty(w);
+ return;
+ }
+ }
+}
+
+/** Get the maximum length of a given string in a string-list. This is an
+ * implicit string-list where the ID's are consecutive
+ * @param base_string StringID of the first string in the list
+ * @param count amount of StringID's in the list
+ * @return the length of the longest string */
+static int GetStringListMaxWidth(StringID base_string, byte count)
+{
+ char buffer[512];
+ int width, max_width;
+ byte i;
+
+ max_width = 0;
+ for (i = 0; i != count; i++) {
+ GetString(buffer, base_string + i, lastof(buffer));
+ width = GetStringBoundingBox(buffer).width;
+ if (width > max_width) max_width = width;
+ }
+
+ return max_width;
+}
+
+/** Show a general dropdown menu. The positioning of the dropdown menu
+ * defaults to the left side of the parent_button, eg the button that caused
+ * this window to appear. The only exceptions are when the right side of this
+ * dropdown would fall outside the main toolbar window, in that case it is
+ * aligned with the toolbar's right side.
+ * Since the disable-mask is only 8 bits right now, these dropdowns are
+ * restricted to 8 items max if any bits of disabled_mask are active.
+ * @param w Pointer to a window this dropdown menu belongs to. Has no effect
+ * whatsoever, only graphically for positioning.
+ * @param parent_button The widget identifier of the button that was clicked for
+ * this dropdown. The created dropdown then knows what button to raise (button) on
+ * action and whose function to execute (action).
+ * It is possible to appoint another button for an action event by setting the
+ * upper 8 bits of this parameter. If non is set, action is presumed to be the same
+ * as button. So<br>
+ * button bits 0 - 7 - widget clicked to get dropdown
+ * action bits 8 - 15 - function of widget to execute on select (defaults to bits 0 - 7)
+ * @param base_string The first StringID shown in the dropdown list. All others are
+ * consecutive indeces from the language file. XXX - fix? Use ingame-string tables?
+ * @param item_count Number of strings in the list, see previous parameter
+ * @param disabled_mask Bitmask of disabled strings in the list
+ * @return Return a pointer to the newly created dropdown window */
+static Window *PopupMainToolbMenu(Window *w, uint16 parent_button, StringID base_string, byte item_count, byte disabled_mask)
+{
+ int width;
+ int x = w->widget[GB(parent_button, 0, 8)].left;
+
+ assert(disabled_mask == 0 || item_count <= 8);
+ LowerWindowWidget(w, parent_button);
+ InvalidateWidget(w, parent_button);
+
+ DeleteWindowById(WC_TOOLBAR_MENU, 0);
+
+ /* Extend the dropdown toolbar to the longest string in the list and
+ * also make sure the dropdown is fully visible within the window.
+ * x + w->left because x is supposed to be the offset of the toolbar-button
+ * we clicked on and w->left the toolbar window itself. So meaning that
+ * the default position is aligned with the left side of the clicked button */
+ width = max(GetStringListMaxWidth(base_string, item_count) + 6, 140);
+ x = w->left + clamp(x, 0, w->width - width); // or alternatively '_screen.width - width'
+
+ w = AllocateWindow(x, 22, width, item_count * 10 + 2, MenuWndProc, WC_TOOLBAR_MENU, _menu_widgets);
+ w->widget[0].bottom = item_count * 10 + 1;
+ w->flags4 &= ~WF_WHITE_BORDER_MASK;
+
+ WP(w,menu_d).item_count = item_count;
+ WP(w,menu_d).sel_index = 0;
+ WP(w,menu_d).main_button = GB(parent_button, 0, 8);
+ WP(w,menu_d).action_id = (GB(parent_button, 8, 8) != 0) ? GB(parent_button, 8, 8) : parent_button;
+ WP(w,menu_d).string_id = base_string;
+ WP(w,menu_d).checked_items = 0;
+ WP(w,menu_d).disabled_items = disabled_mask;
+
+ _popup_menu_active = true;
+
+ SndPlayFx(SND_15_BEEP);
+ return w;
+}
+
+static Window *PopupMainPlayerToolbMenu(Window *w, int x, int main_button, int gray)
+{
+ x += w->left;
+
+ LowerWindowWidget(w, main_button);
+ InvalidateWidget(w, main_button);
+
+ DeleteWindowById(WC_TOOLBAR_MENU, 0);
+ w = AllocateWindow(x, 0x16, 0xF1, 0x52, PlayerMenuWndProc, WC_TOOLBAR_MENU, _player_menu_widgets);
+ w->flags4 &= ~WF_WHITE_BORDER_MASK;
+ WP(w,menu_d).item_count = 0;
+ WP(w,menu_d).sel_index = (_local_player != PLAYER_SPECTATOR) ? _local_player : GetPlayerIndexFromMenu(0);
+ if (_networking && main_button == 9) {
+ if (_local_player != PLAYER_SPECTATOR) {
+ WP(w,menu_d).sel_index++;
+ } else {
+ /* Select client list by default for spectators */
+ WP(w,menu_d).sel_index = 0;
+ }
+ }
+ WP(w,menu_d).action_id = main_button;
+ WP(w,menu_d).main_button = main_button;
+ WP(w,menu_d).checked_items = gray;
+ WP(w,menu_d).disabled_items = 0;
+ _popup_menu_active = true;
+ SndPlayFx(SND_15_BEEP);
+ return w;
+}
+
+static void ToolbarSaveClick(Window *w)
+{
+ PopupMainToolbMenu(w, 3, STR_015C_SAVE_GAME, 4, 0);
+}
+
+static void ToolbarMapClick(Window *w)
+{
+ PopupMainToolbMenu(w, 4, STR_02DE_MAP_OF_WORLD, 3, 0);
+}
+
+static void ToolbarTownClick(Window *w)
+{
+ PopupMainToolbMenu(w, 5, STR_02BB_TOWN_DIRECTORY, 1, 0);
+}
+
+static void ToolbarSubsidiesClick(Window *w)
+{
+ PopupMainToolbMenu(w, 6, STR_02DD_SUBSIDIES, 1, 0);
+}
+
+static void ToolbarStationsClick(Window *w)
+{
+ PopupMainPlayerToolbMenu(w, 162, 7, 0);
+}
+
+static void ToolbarMoneyClick(Window *w)
+{
+ PopupMainPlayerToolbMenu(w, 191, 8, 0);
+}
+
+static void ToolbarPlayersClick(Window *w)
+{
+ PopupMainPlayerToolbMenu(w, 213, 9, 0);
+}
+
+static void ToolbarGraphsClick(Window *w)
+{
+ PopupMainToolbMenu(w, 10, STR_0154_OPERATING_PROFIT_GRAPH, 6, 0);
+}
+
+static void ToolbarLeagueClick(Window *w)
+{
+ PopupMainToolbMenu(w, 11, STR_015A_COMPANY_LEAGUE_TABLE, 2, 0);
+}
+
+static void ToolbarIndustryClick(Window *w)
+{
+ /* Disable build-industry menu if we are a spectator */
+ PopupMainToolbMenu(w, 12, STR_INDUSTRY_DIR, 2, (_current_player == PLAYER_SPECTATOR) ? (1 << 1) : 0);
+}
+
+static void ToolbarTrainClick(Window *w)
+{
+ const Vehicle *v;
+ int dis = -1;
+
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == VEH_Train && IsFrontEngine(v)) CLRBIT(dis, v->owner);
+ }
+ PopupMainPlayerToolbMenu(w, 310, 13, dis);
+}
+
+static void ToolbarRoadClick(Window *w)
+{
+ const Vehicle *v;
+ int dis = -1;
+
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == VEH_Road) CLRBIT(dis, v->owner);
+ }
+ PopupMainPlayerToolbMenu(w, 332, 14, dis);
+}
+
+static void ToolbarShipClick(Window *w)
+{
+ const Vehicle *v;
+ int dis = -1;
+
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == VEH_Ship) CLRBIT(dis, v->owner);
+ }
+ PopupMainPlayerToolbMenu(w, 354, 15, dis);
+}
+
+static void ToolbarAirClick(Window *w)
+{
+ const Vehicle *v;
+ int dis = -1;
+
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == VEH_Aircraft) CLRBIT(dis, v->owner);
+ }
+ PopupMainPlayerToolbMenu(w, 376, 16, dis);
+}
+
+/* Zooms a viewport in a window in or out */
+/* No button handling or what so ever */
+bool DoZoomInOutWindow(int how, Window *w)
+{
+ ViewPort *vp;
+
+ assert(w != NULL);
+ vp = w->viewport;
+
+ switch (how) {
+ case ZOOM_IN:
+ if (vp->zoom == 0) return false;
+ vp->zoom--;
+ vp->virtual_width >>= 1;
+ vp->virtual_height >>= 1;
+
+ WP(w,vp_d).scrollpos_x += vp->virtual_width >> 1;
+ WP(w,vp_d).scrollpos_y += vp->virtual_height >> 1;
+ break;
+ case ZOOM_OUT:
+ if (vp->zoom == 2) return false;
+ vp->zoom++;
+
+ WP(w,vp_d).scrollpos_x -= vp->virtual_width >> 1;
+ WP(w,vp_d).scrollpos_y -= vp->virtual_height >> 1;
+
+ vp->virtual_width <<= 1;
+ vp->virtual_height <<= 1;
+ break;
+ }
+ if (vp != NULL) { // the vp can be null when how == ZOOM_NONE
+ vp->virtual_left = WP(w, vp_d).scrollpos_x;
+ vp->virtual_top = WP(w, vp_d).scrollpos_y;
+ }
+ SetWindowDirty(w);
+ /* Update the windows that have zoom-buttons to perhaps disable their buttons */
+ SendWindowMessageClass(w->window_class, how, w->window_number, 0);
+ return true;
+}
+
+static void ToolbarZoomInClick(Window *w)
+{
+ if (DoZoomInOutWindow(ZOOM_IN, FindWindowById(WC_MAIN_WINDOW, 0))) {
+ HandleButtonClick(w, 17);
+ SndPlayFx(SND_15_BEEP);
+ }
+}
+
+static void ToolbarZoomOutClick(Window *w)
+{
+ if (DoZoomInOutWindow(ZOOM_OUT,FindWindowById(WC_MAIN_WINDOW, 0))) {
+ HandleButtonClick(w, 18);
+ SndPlayFx(SND_15_BEEP);
+ }
+}
+
+static void ToolbarBuildRailClick(Window *w)
+{
+ const Player *p = GetPlayer(_local_player);
+ Window *w2;
+ w2 = PopupMainToolbMenu(w, 19, STR_1015_RAILROAD_CONSTRUCTION, RAILTYPE_END, ~p->avail_railtypes);
+ WP(w2,menu_d).sel_index = _last_built_railtype;
+}
+
+static void ToolbarBuildRoadClick(Window *w)
+{
+ PopupMainToolbMenu(w, 20, STR_180A_ROAD_CONSTRUCTION, 1, 0);
+}
+
+static void ToolbarBuildWaterClick(Window *w)
+{
+ PopupMainToolbMenu(w, 21, STR_9800_DOCK_CONSTRUCTION, 1, 0);
+}
+
+static void ToolbarBuildAirClick(Window *w)
+{
+ PopupMainToolbMenu(w, 22, STR_A01D_AIRPORT_CONSTRUCTION, 1, 0);
+}
+
+static void ToolbarForestClick(Window *w)
+{
+ PopupMainToolbMenu(w, 23, STR_LANDSCAPING, 3, 0);
+}
+
+static void ToolbarMusicClick(Window *w)
+{
+ PopupMainToolbMenu(w, 24, STR_01D3_SOUND_MUSIC, 1, 0);
+}
+
+static void ToolbarNewspaperClick(Window *w)
+{
+ PopupMainToolbMenu(w, 25, STR_0200_LAST_MESSAGE_NEWS_REPORT, 3, 0);
+}
+
+static void ToolbarHelpClick(Window *w)
+{
+ PopupMainToolbMenu(w, 26, STR_02D5_LAND_BLOCK_INFO, 6, 0);
+}
+
+static void ToolbarOptionsClick(Window *w)
+{
+ uint16 x = 0;
+
+ w = PopupMainToolbMenu(w, 2, STR_02C3_GAME_OPTIONS, 13, 0);
+
+ if (_display_opt & DO_SHOW_TOWN_NAMES) SETBIT(x, 5);
+ if (_display_opt & DO_SHOW_STATION_NAMES) SETBIT(x, 6);
+ if (_display_opt & DO_SHOW_SIGNS) SETBIT(x, 7);
+ if (_display_opt & DO_WAYPOINTS) SETBIT(x, 8);
+ if (_display_opt & DO_FULL_ANIMATION) SETBIT(x, 9);
+ if (_display_opt & DO_FULL_DETAIL) SETBIT(x, 10);
+ if (_display_opt & DO_TRANS_BUILDINGS) SETBIT(x, 11);
+ if (_display_opt & DO_TRANS_SIGNS) SETBIT(x, 12);
+ WP(w,menu_d).checked_items = x;
+}
+
+
+static void ToolbarScenSaveOrLoad(Window *w)
+{
+ PopupMainToolbMenu(w, 3, STR_0292_SAVE_SCENARIO, 5, 0);
+}
+
+static void ToolbarScenDateBackward(Window *w)
+{
+ // don't allow too fast scrolling
+ if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) {
+ HandleButtonClick(w, 6);
+ SetWindowDirty(w);
+
+ _patches_newgame.starting_year = clamp(_patches_newgame.starting_year - 1, MIN_YEAR, MAX_YEAR);
+ SetDate(ConvertYMDToDate(_patches_newgame.starting_year, 0, 1));
+ }
+ _left_button_clicked = false;
+}
+
+static void ToolbarScenDateForward(Window *w)
+{
+ // don't allow too fast scrolling
+ if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) {
+ HandleButtonClick(w, 7);
+ SetWindowDirty(w);
+
+ _patches_newgame.starting_year = clamp(_patches_newgame.starting_year + 1, MIN_YEAR, MAX_YEAR);
+ SetDate(ConvertYMDToDate(_patches_newgame.starting_year, 0, 1));
+ }
+ _left_button_clicked = false;
+}
+
+static void ToolbarScenMapTownDir(Window *w)
+{
+ /* Scenario editor button, *hack*hack* use different button to activate */
+ PopupMainToolbMenu(w, 8 | (17 << 8), STR_02DE_MAP_OF_WORLD, 4, 0);
+}
+
+static void ToolbarScenZoomIn(Window *w)
+{
+ if (DoZoomInOutWindow(ZOOM_IN, FindWindowById(WC_MAIN_WINDOW, 0))) {
+ HandleButtonClick(w, 9);
+ SndPlayFx(SND_15_BEEP);
+ }
+}
+
+static void ToolbarScenZoomOut(Window *w)
+{
+ if (DoZoomInOutWindow(ZOOM_OUT, FindWindowById(WC_MAIN_WINDOW, 0))) {
+ HandleButtonClick(w, 10);
+ SndPlayFx(SND_15_BEEP);
+ }
+}
+
+void ZoomInOrOutToCursorWindow(bool in, Window *w)
+{
+ ViewPort *vp;
+ Point pt;
+
+ assert(w != 0);
+
+ vp = w->viewport;
+
+ if (_game_mode != GM_MENU) {
+ if ((in && vp->zoom == 0) || (!in && vp->zoom == 2))
+ return;
+
+ pt = GetTileZoomCenterWindow(in,w);
+ if (pt.x != -1) {
+ ScrollWindowTo(pt.x, pt.y, w);
+
+ DoZoomInOutWindow(in ? ZOOM_IN : ZOOM_OUT, w);
+ }
+ }
+}
+
+// TODO - Incorporate into game itself to allow for ingame raising/lowering of
+// larger chunks at the same time OR remove altogether, as we have 'level land' ?
+/**
+ * Raise/Lower a bigger chunk of land at the same time in the editor. When
+ * raising get the lowest point, when lowering the highest point, and set all
+ * tiles in the selection to that height.
+ * @param tile The top-left tile where the terraforming will start
+ * @param mode 1 for raising, 0 for lowering land
+ */
+static void CommonRaiseLowerBigLand(TileIndex tile, int mode)
+{
+ int sizex, sizey;
+ byte h;
+
+ _generating_world = true; // used to create green terraformed land
+
+ if (_terraform_size == 1) {
+ StringID msg =
+ mode ? STR_0808_CAN_T_RAISE_LAND_HERE : STR_0809_CAN_T_LOWER_LAND_HERE;
+
+ DoCommandP(tile, 8, (uint32)mode, CcTerraform, CMD_TERRAFORM_LAND | CMD_AUTO | CMD_MSG(msg));
+ } else {
+ SndPlayTileFx(SND_1F_SPLAT, tile);
+
+ assert(_terraform_size != 0);
+ // check out for map overflows
+ sizex = min(MapSizeX() - TileX(tile) - 1, _terraform_size);
+ sizey = min(MapSizeY() - TileY(tile) - 1, _terraform_size);
+
+ if (sizex == 0 || sizey == 0) return;
+
+ if (mode != 0) {
+ /* Raise land */
+ h = 15; // XXX - max height
+ BEGIN_TILE_LOOP(tile2, sizex, sizey, tile) {
+ h = min(h, TileHeight(tile2));
+ } END_TILE_LOOP(tile2, sizex, sizey, tile)
+ } else {
+ /* Lower land */
+ h = 0;
+ BEGIN_TILE_LOOP(tile2, sizex, sizey, tile) {
+ h = max(h, TileHeight(tile2));
+ } END_TILE_LOOP(tile2, sizex, sizey, tile)
+ }
+
+ BEGIN_TILE_LOOP(tile2, sizex, sizey, tile) {
+ if (TileHeight(tile2) == h) {
+ DoCommandP(tile2, 8, (uint32)mode, NULL, CMD_TERRAFORM_LAND | CMD_AUTO);
+ }
+ } END_TILE_LOOP(tile2, sizex, sizey, tile)
+ }
+
+ _generating_world = false;
+}
+
+static void PlaceProc_RaiseBigLand(TileIndex tile)
+{
+ CommonRaiseLowerBigLand(tile, 1);
+}
+
+static void PlaceProc_LowerBigLand(TileIndex tile)
+{
+ CommonRaiseLowerBigLand(tile, 0);
+}
+
+static void PlaceProc_RockyArea(TileIndex tile)
+{
+ VpStartPlaceSizing(tile, VPM_X_AND_Y | GUI_PlaceProc_RockyArea);
+}
+
+static void PlaceProc_LightHouse(TileIndex tile)
+{
+ if (!IsTileType(tile, MP_CLEAR) || IsSteepSlope(GetTileSlope(tile, NULL))) {
+ return;
+ }
+
+ MakeLighthouse(tile);
+ MarkTileDirtyByTile(tile);
+ SndPlayTileFx(SND_1F_SPLAT, tile);
+}
+
+static void PlaceProc_Transmitter(TileIndex tile)
+{
+ if (!IsTileType(tile, MP_CLEAR) || IsSteepSlope(GetTileSlope(tile, NULL))) {
+ return;
+ }
+
+ MakeTransmitter(tile);
+ MarkTileDirtyByTile(tile);
+ SndPlayTileFx(SND_1F_SPLAT, tile);
+}
+
+static void PlaceProc_DesertArea(TileIndex tile)
+{
+ VpStartPlaceSizing(tile, VPM_X_AND_Y | GUI_PlaceProc_DesertArea);
+}
+
+static void PlaceProc_WaterArea(TileIndex tile)
+{
+ VpStartPlaceSizing(tile, VPM_X_AND_Y | GUI_PlaceProc_WaterArea);
+}
+
+static const Widget _scen_edit_land_gen_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_0223_LAND_GENERATION, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_STICKYBOX, RESIZE_NONE, 7, 170, 181, 0, 13, STR_NULL, STR_STICKY_BUTTON},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 181, 14, 95, 0x0, STR_NULL},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 2, 23, 14, 35, SPR_IMG_DYNAMITE, STR_018D_DEMOLISH_BUILDINGS_ETC},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 24, 45, 14, 35, SPR_IMG_TERRAFORM_DOWN, STR_018E_LOWER_A_CORNER_OF_LAND},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 46, 67, 14, 35, SPR_IMG_TERRAFORM_UP, STR_018F_RAISE_A_CORNER_OF_LAND},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 68, 89, 14, 35, SPR_IMG_LEVEL_LAND, STR_LEVEL_LAND_TOOLTIP},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 90, 111, 14, 35, SPR_IMG_BUILD_CANAL, STR_CREATE_LAKE},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 112, 134, 14, 35, SPR_IMG_ROCKS, STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 135, 157, 14, 35, SPR_IMG_LIGHTHOUSE_DESERT, STR_NULL}, // XXX - dynamic
+{ WWT_IMGBTN, RESIZE_NONE, 14, 158, 179, 14, 35, SPR_IMG_TRANSMITTER, STR_028E_PLACE_TRANSMITTER},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 139, 149, 43, 54, STR_0224, STR_0228_INCREASE_SIZE_OF_LAND_AREA},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 139, 149, 56, 67, STR_0225, STR_0229_DECREASE_SIZE_OF_LAND_AREA},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 34, 149, 75, 86, STR_SE_NEW_WORLD, STR_022A_GENERATE_RANDOM_LAND},
+{ WIDGETS_END},
+};
+
+static const int8 _multi_terraform_coords[][2] = {
+ { 0, -2},
+ { 4, 0}, { -4, 0}, { 0, 2},
+ { -8, 2}, { -4, 4}, { 0, 6}, { 4, 4}, { 8, 2},
+ {-12, 0}, { -8, -2}, { -4, -4}, { 0, -6}, { 4, -4}, { 8, -2}, { 12, 0},
+ {-16, 2}, {-12, 4}, { -8, 6}, { -4, 8}, { 0, 10}, { 4, 8}, { 8, 6}, { 12, 4}, { 16, 2},
+ {-20, 0}, {-16, -2}, {-12, -4}, { -8, -6}, { -4, -8}, { 0,-10}, { 4, -8}, { 8, -6}, { 12, -4}, { 16, -2}, { 20, 0},
+ {-24, 2}, {-20, 4}, {-16, 6}, {-12, 8}, { -8, 10}, { -4, 12}, { 0, 14}, { 4, 12}, { 8, 10}, { 12, 8}, { 16, 6}, { 20, 4}, { 24, 2},
+ {-28, 0}, {-24, -2}, {-20, -4}, {-16, -6}, {-12, -8}, { -8,-10}, { -4,-12}, { 0,-14}, { 4,-12}, { 8,-10}, { 12, -8}, { 16, -6}, { 20, -4}, { 24, -2}, { 28, 0},
+};
+
+// TODO - Merge with terraform_gui.c (move there) after I have cooled down at its braindeadness
+// and changed OnButtonClick to include the widget as well in the function decleration. Post 0.4.0 - Darkvater
+static void EditorTerraformClick_Dynamite(Window *w)
+{
+ HandlePlacePushButton(w, 4, ANIMCURSOR_DEMOLISH, 1, PlaceProc_DemolishArea);
+}
+
+static void EditorTerraformClick_LowerBigLand(Window *w)
+{
+ HandlePlacePushButton(w, 5, ANIMCURSOR_LOWERLAND, 2, PlaceProc_LowerBigLand);
+}
+
+static void EditorTerraformClick_RaiseBigLand(Window *w)
+{
+ HandlePlacePushButton(w, 6, ANIMCURSOR_RAISELAND, 2, PlaceProc_RaiseBigLand);
+}
+
+static void EditorTerraformClick_LevelLand(Window *w)
+{
+ HandlePlacePushButton(w, 7, SPR_CURSOR_LEVEL_LAND, 2, PlaceProc_LevelLand);
+}
+
+static void EditorTerraformClick_WaterArea(Window *w)
+{
+ HandlePlacePushButton(w, 8, SPR_CURSOR_CANAL, 1, PlaceProc_WaterArea);
+}
+
+static void EditorTerraformClick_RockyArea(Window *w)
+{
+ HandlePlacePushButton(w, 9, SPR_CURSOR_ROCKY_AREA, 1, PlaceProc_RockyArea);
+}
+
+static void EditorTerraformClick_DesertLightHouse(Window *w)
+{
+ HandlePlacePushButton(w, 10, SPR_CURSOR_LIGHTHOUSE, 1, (_opt.landscape == LT_DESERT) ? PlaceProc_DesertArea : PlaceProc_LightHouse);
+}
+
+static void EditorTerraformClick_Transmitter(Window *w)
+{
+ HandlePlacePushButton(w, 11, SPR_CURSOR_TRANSMITTER, 1, PlaceProc_Transmitter);
+}
+
+static const uint16 _editor_terraform_keycodes[] = {
+ 'D',
+ 'Q',
+ 'W',
+ 'E',
+ 'R',
+ 'T',
+ 'Y',
+ 'U'
+};
+
+typedef void OnButtonClick(Window *w);
+static OnButtonClick * const _editor_terraform_button_proc[] = {
+ EditorTerraformClick_Dynamite,
+ EditorTerraformClick_LowerBigLand,
+ EditorTerraformClick_RaiseBigLand,
+ EditorTerraformClick_LevelLand,
+ EditorTerraformClick_WaterArea,
+ EditorTerraformClick_RockyArea,
+ EditorTerraformClick_DesertLightHouse,
+ EditorTerraformClick_Transmitter
+};
+
+static void ScenEditLandGenWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_CREATE:
+ // XXX - lighthouse button is widget 10!! Don't forget when changing
+ w->widget[10].tooltips = (_opt.landscape == LT_DESERT) ? STR_028F_DEFINE_DESERT_AREA : STR_028D_PLACE_LIGHTHOUSE;
+ break;
+
+ case WE_PAINT:
+ DrawWindowWidgets(w);
+
+ {
+ int n = _terraform_size * _terraform_size;
+ const int8 *coords = &_multi_terraform_coords[0][0];
+
+ assert(n != 0);
+ do {
+ DrawSprite(SPR_WHITE_POINT, 77 + coords[0], 55 + coords[1]);
+ coords += 2;
+ } while (--n);
+ }
+
+ if (IsWindowWidgetLowered(w, 5) || IsWindowWidgetLowered(w, 6)) // change area-size if raise/lower corner is selected
+ SetTileSelectSize(_terraform_size, _terraform_size);
+
+ break;
+
+ case WE_KEYPRESS: {
+ uint i;
+
+ for (i = 0; i != lengthof(_editor_terraform_keycodes); i++) {
+ if (e->we.keypress.keycode == _editor_terraform_keycodes[i]) {
+ e->we.keypress.cont = false;
+ _editor_terraform_button_proc[i](w);
+ break;
+ }
+ }
+ } break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11:
+ _editor_terraform_button_proc[e->we.click.widget - 4](w);
+ break;
+ case 12: case 13: { /* Increase/Decrease terraform size */
+ int size = (e->we.click.widget == 12) ? 1 : -1;
+ HandleButtonClick(w, e->we.click.widget);
+ size += _terraform_size;
+
+ if (!IS_INT_INSIDE(size, 1, 8 + 1)) return;
+ _terraform_size = size;
+
+ SndPlayFx(SND_15_BEEP);
+ SetWindowDirty(w);
+ } break;
+ case 14: /* gen random land */
+ HandleButtonClick(w, 14);
+ ShowCreateScenario();
+ break;
+ }
+ break;
+
+ case WE_TIMEOUT: {
+ uint i;
+ for (i = 0; i < w->widget_count; i++) {
+ if (IsWindowWidgetLowered(w, i)) {
+ RaiseWindowWidget(w, i);
+ InvalidateWidget(w, i);
+ }
+ if (i == 3) i = 11;
+ }
+ break;
+ }
+ case WE_PLACE_OBJ:
+ _place_proc(e->we.place.tile);
+ break;
+ case WE_PLACE_DRAG:
+ VpSelectTilesWithMethod(e->we.place.pt.x, e->we.place.pt.y, e->we.place.userdata & 0xF);
+ break;
+
+ case WE_PLACE_MOUSEUP:
+ if (e->we.place.pt.x != -1) {
+ if ((e->we.place.userdata & 0xF) == VPM_X_AND_Y) // dragged actions
+ GUIPlaceProcDragXY(e);
+ }
+ break;
+
+ case WE_ABORT_PLACE_OBJ:
+ RaiseWindowButtons(w);
+ SetWindowDirty(w);
+ break;
+ }
+}
+
+static const WindowDesc _scen_edit_land_gen_desc = {
+ WDP_AUTO, WDP_AUTO, 182, 96,
+ WC_SCEN_LAND_GEN,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON,
+ _scen_edit_land_gen_widgets,
+ ScenEditLandGenWndProc,
+};
+
+static inline void ShowEditorTerraformToolBar(void)
+{
+ AllocateWindowDescFront(&_scen_edit_land_gen_desc, 0);
+}
+
+static void ToolbarScenGenLand(Window *w)
+{
+ HandleButtonClick(w, 11);
+ SndPlayFx(SND_15_BEEP);
+
+ ShowEditorTerraformToolBar();
+}
+
+void CcBuildTown(bool success, TileIndex tile, uint32 p1, uint32 p2)
+{
+ if (success) {
+ SndPlayTileFx(SND_1F_SPLAT, tile);
+ ResetObjectToPlace();
+ }
+}
+
+static void PlaceProc_Town(TileIndex tile)
+{
+ DoCommandP(tile, _scengen_town_size, 0, CcBuildTown, CMD_BUILD_TOWN | CMD_MSG(STR_0236_CAN_T_BUILD_TOWN_HERE));
+}
+
+
+static const Widget _scen_edit_town_gen_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 147, 0, 13, STR_0233_TOWN_GENERATION, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_STICKYBOX, RESIZE_NONE, 7, 148, 159, 0, 13, 0x0, STR_STICKY_BUTTON},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 159, 14, 81, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 157, 16, 27, STR_0234_NEW_TOWN, STR_0235_CONSTRUCT_NEW_TOWN},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 157, 29, 40, STR_023D_RANDOM_TOWN, STR_023E_BUILD_TOWN_IN_RANDOM_LOCATION},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 157, 42, 53, STR_MANY_RANDOM_TOWNS, STR_RANDOM_TOWNS_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 53, 68, 79, STR_02A1_SMALL, STR_02A4_SELECT_TOWN_SIZE},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 54, 105, 68, 79, STR_02A2_MEDIUM, STR_02A4_SELECT_TOWN_SIZE},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 106, 157, 68, 79, STR_02A3_LARGE, STR_02A4_SELECT_TOWN_SIZE},
+{ WWT_LABEL, RESIZE_NONE, 7, 0, 147, 54, 67, STR_02A5_TOWN_SIZE, STR_NULL},
+{ WIDGETS_END},
+};
+
+static void ScenEditTownGenWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT:
+ DrawWindowWidgets(w);
+ break;
+
+ case WE_CREATE:
+ LowerWindowWidget(w, (_scengen_town_size - 1)+ 7);
+ break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 4: /* new town */
+ HandlePlacePushButton(w, 4, SPR_CURSOR_TOWN, 1, PlaceProc_Town);
+ break;
+ case 5: {/* random town */
+ Town *t;
+
+ HandleButtonClick(w, 5);
+ _generating_world = true;
+ t = CreateRandomTown(20, _scengen_town_size);
+ _generating_world = false;
+
+ if (t == NULL) {
+ ShowErrorMessage(STR_NO_SPACE_FOR_TOWN, STR_CANNOT_GENERATE_TOWN, 0, 0);
+ } else {
+ ScrollMainWindowToTile(t->xy);
+ }
+
+ break;
+ }
+ case 6: {/* many random towns */
+ HandleButtonClick(w, 6);
+
+ _generating_world = true;
+ if (!GenerateTowns()) ShowErrorMessage(STR_NO_SPACE_FOR_TOWN, STR_CANNOT_GENERATE_TOWN, 0, 0);
+ _generating_world = false;
+ break;
+ }
+
+ case 7: case 8: case 9:
+ RaiseWindowWidget(w, (_scengen_town_size - 1) + 7);
+ _scengen_town_size = (e->we.click.widget - 7) + 1;
+ LowerWindowWidget(w, (_scengen_town_size - 1) + 7);
+ SetWindowDirty(w);
+ break;
+ }
+ break;
+
+ case WE_TIMEOUT:
+ RaiseWindowWidget(w, 5);
+ RaiseWindowWidget(w, 6);
+ SetWindowDirty(w);
+ break;
+ case WE_PLACE_OBJ:
+ _place_proc(e->we.place.tile);
+ break;
+ case WE_ABORT_PLACE_OBJ:
+ RaiseWindowButtons(w);
+ LowerWindowWidget(w, (_scengen_town_size - 1) + 7);
+ SetWindowDirty(w);
+ break;
+ }
+}
+
+static const WindowDesc _scen_edit_town_gen_desc = {
+ WDP_AUTO, WDP_AUTO, 160, 82,
+ WC_SCEN_TOWN_GEN,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON,
+ _scen_edit_town_gen_widgets,
+ ScenEditTownGenWndProc,
+};
+
+static void ToolbarScenGenTown(Window *w)
+{
+ HandleButtonClick(w, 12);
+ SndPlayFx(SND_15_BEEP);
+
+ AllocateWindowDescFront(&_scen_edit_town_gen_desc, 0);
+}
+
+
+static const Widget _scenedit_industry_normal_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_023F_INDUSTRY_GENERATION, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 224, 0x0, STR_NULL},
+
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_MANY_RANDOM_INDUSTRIES, STR_RANDOM_INDUSTRIES_TIP},
+
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_0240_COAL_MINE, STR_0262_CONSTRUCT_COAL_MINE},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_0241_POWER_STATION, STR_0263_CONSTRUCT_POWER_STATION},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 68, 79, STR_0242_SAWMILL, STR_0264_CONSTRUCT_SAWMILL},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 81, 92, STR_0243_FOREST, STR_0265_PLANT_FOREST},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 94, 105, STR_0244_OIL_REFINERY, STR_0266_CONSTRUCT_OIL_REFINERY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 107, 118, STR_0245_OIL_RIG, STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 120, 131, STR_0246_FACTORY, STR_0268_CONSTRUCT_FACTORY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 133, 144, STR_0247_STEEL_MILL, STR_0269_CONSTRUCT_STEEL_MILL},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 146, 157, STR_0248_FARM, STR_026A_CONSTRUCT_FARM},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 159, 170, STR_0249_IRON_ORE_MINE, STR_026B_CONSTRUCT_IRON_ORE_MINE},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 172, 183, STR_024A_OIL_WELLS, STR_026C_CONSTRUCT_OIL_WELLS},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 185, 196, STR_024B_BANK, STR_026D_CONSTRUCT_BANK_CAN_ONLY},
+{ WIDGETS_END},
+};
+
+
+static const Widget _scenedit_industry_hilly_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_023F_INDUSTRY_GENERATION, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 224, 0x0, STR_NULL},
+
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_MANY_RANDOM_INDUSTRIES, STR_RANDOM_INDUSTRIES_TIP},
+
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_0240_COAL_MINE, STR_0262_CONSTRUCT_COAL_MINE},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_0241_POWER_STATION, STR_0263_CONSTRUCT_POWER_STATION},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 68, 79, STR_024C_PAPER_MILL, STR_026E_CONSTRUCT_PAPER_MILL},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 81, 92, STR_0243_FOREST, STR_0265_PLANT_FOREST},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 94, 105, STR_0244_OIL_REFINERY, STR_0266_CONSTRUCT_OIL_REFINERY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 107, 118, STR_024D_FOOD_PROCESSING_PLANT, STR_026F_CONSTRUCT_FOOD_PROCESSING},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 120, 131, STR_024E_PRINTING_WORKS, STR_0270_CONSTRUCT_PRINTING_WORKS},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 133, 144, STR_024F_GOLD_MINE, STR_0271_CONSTRUCT_GOLD_MINE},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 146, 157, STR_0248_FARM, STR_026A_CONSTRUCT_FARM},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 159, 170, STR_024B_BANK, STR_0272_CONSTRUCT_BANK_CAN_ONLY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 172, 183, STR_024A_OIL_WELLS, STR_026C_CONSTRUCT_OIL_WELLS},
+{ WIDGETS_END},
+};
+
+static const Widget _scenedit_industry_desert_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_023F_INDUSTRY_GENERATION, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 224, 0x0, STR_NULL},
+
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_MANY_RANDOM_INDUSTRIES, STR_RANDOM_INDUSTRIES_TIP},
+
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_0250_LUMBER_MILL, STR_0273_CONSTRUCT_LUMBER_MILL_TO},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_0251_FRUIT_PLANTATION, STR_0274_PLANT_FRUIT_PLANTATION},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 68, 79, STR_0252_RUBBER_PLANTATION, STR_0275_PLANT_RUBBER_PLANTATION},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 81, 92, STR_0244_OIL_REFINERY, STR_0266_CONSTRUCT_OIL_REFINERY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 94, 105, STR_024D_FOOD_PROCESSING_PLANT, STR_026F_CONSTRUCT_FOOD_PROCESSING},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 107, 118, STR_0246_FACTORY, STR_0268_CONSTRUCT_FACTORY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 120, 131, STR_0253_WATER_SUPPLY, STR_0276_CONSTRUCT_WATER_SUPPLY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 133, 144, STR_0248_FARM, STR_026A_CONSTRUCT_FARM},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 146, 157, STR_0254_WATER_TOWER, STR_0277_CONSTRUCT_WATER_TOWER_CAN},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 159, 170, STR_024A_OIL_WELLS, STR_026C_CONSTRUCT_OIL_WELLS},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 172, 183, STR_024B_BANK, STR_0272_CONSTRUCT_BANK_CAN_ONLY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 185, 196, STR_0255_DIAMOND_MINE, STR_0278_CONSTRUCT_DIAMOND_MINE},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 198, 209, STR_0256_COPPER_ORE_MINE, STR_0279_CONSTRUCT_COPPER_ORE_MINE},
+{ WIDGETS_END},
+};
+
+static const Widget _scenedit_industry_candy_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_023F_INDUSTRY_GENERATION, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 224, 0x0, STR_NULL},
+
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_MANY_RANDOM_INDUSTRIES, STR_RANDOM_INDUSTRIES_TIP},
+
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_0257_COTTON_CANDY_FOREST, STR_027A_PLANT_COTTON_CANDY_FOREST},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_0258_CANDY_FACTORY, STR_027B_CONSTRUCT_CANDY_FACTORY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 68, 79, STR_0259_BATTERY_FARM, STR_027C_CONSTRUCT_BATTERY_FARM},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 81, 92, STR_025A_COLA_WELLS, STR_027D_CONSTRUCT_COLA_WELLS},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 94, 105, STR_025B_TOY_SHOP, STR_027E_CONSTRUCT_TOY_SHOP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 107, 118, STR_025C_TOY_FACTORY, STR_027F_CONSTRUCT_TOY_FACTORY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 120, 131, STR_025D_PLASTIC_FOUNTAINS, STR_0280_CONSTRUCT_PLASTIC_FOUNTAINS},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 133, 144, STR_025E_FIZZY_DRINK_FACTORY, STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 146, 157, STR_025F_BUBBLE_GENERATOR, STR_0282_CONSTRUCT_BUBBLE_GENERATOR},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 159, 170, STR_0260_TOFFEE_QUARRY, STR_0283_CONSTRUCT_TOFFEE_QUARRY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 172, 183, STR_0261_SUGAR_MINE, STR_0284_CONSTRUCT_SUGAR_MINE},
+{ WIDGETS_END},
+};
+
+
+static bool AnyTownExists(void)
+{
+ const Town *t;
+
+ FOR_ALL_TOWNS(t) return true;
+
+ return false;
+}
+
+extern Industry *CreateNewIndustry(TileIndex tile, int type);
+
+/**
+ * Search callback function for TryBuildIndustry
+ * @param tile to test
+ * @param data that is passed by the caller. In this case, the type of industry been tested
+ * @result of the operation
+ */
+static bool SearchTileForIndustry(TileIndex tile, uint32 data)
+{
+ return CreateNewIndustry(tile, data) != NULL;
+}
+
+/**
+ * Perform a 9*9 tiles circular search around a tile
+ * in order to find a suitable zone to create the desired industry
+ * @param tile to start search for
+ * @param type of the desired industry
+ */
+static bool TryBuildIndustry(TileIndex tile, int type)
+{
+ return CircularTileSearch(tile, 9, SearchTileForIndustry, type);
+}
+
+
+static const byte _industry_type_list[4][16] = {
+ { 0, 1, 2, 3, 4, 5, 6, 8, 9, 18, 11, 12},
+ { 0, 1, 14, 3, 4, 13, 7, 15, 9, 16, 11, 12},
+ {25, 19, 20, 4, 13, 23, 21, 24, 22, 11, 16, 17, 10},
+ {26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36},
+};
+
+static int _industry_type_to_place;
+bool _ignore_restrictions;
+
+static void ScenEditIndustryWndProc(Window *w, WindowEvent *e)
+{
+ int button;
+
+ switch (e->event) {
+ case WE_PAINT:
+ DrawWindowWidgets(w);
+ break;
+
+ case WE_CLICK:
+ if (e->we.click.widget == 3) {
+ HandleButtonClick(w, 3);
+
+ if (!AnyTownExists()) {
+ ShowErrorMessage(STR_0286_MUST_BUILD_TOWN_FIRST, STR_CAN_T_GENERATE_INDUSTRIES, 0, 0);
+ return;
+ }
+
+ _generating_world = true;
+ GenerateIndustries();
+ _generating_world = false;
+ }
+
+ if ((button=e->we.click.widget) >= 4) {
+ if (HandlePlacePushButton(w, button, SPR_CURSOR_INDUSTRY, 1, NULL))
+ _industry_type_to_place = _industry_type_list[_opt.landscape][button - 4];
+ }
+ break;
+ case WE_PLACE_OBJ: {
+ int type;
+
+ // Show error if no town exists at all
+ type = _industry_type_to_place;
+ if (!AnyTownExists()) {
+ SetDParam(0, GetIndustrySpec(type)->name);
+ ShowErrorMessage(STR_0286_MUST_BUILD_TOWN_FIRST, STR_0285_CAN_T_BUILD_HERE, e->we.place.pt.x, e->we.place.pt.y);
+ return;
+ }
+
+ _current_player = OWNER_NONE;
+ _generating_world = true;
+ _ignore_restrictions = true;
+ if (!TryBuildIndustry(e->we.place.tile,type)) {
+ SetDParam(0, GetIndustrySpec(type)->name);
+ ShowErrorMessage(_error_message, STR_0285_CAN_T_BUILD_HERE, e->we.place.pt.x, e->we.place.pt.y);
+ }
+ _ignore_restrictions = false;
+ _generating_world = false;
+ break;
+ }
+ case WE_ABORT_PLACE_OBJ:
+ RaiseWindowButtons(w);
+ SetWindowDirty(w);
+ break;
+ case WE_TIMEOUT:
+ RaiseWindowWidget(w, 3);
+ InvalidateWidget(w, 3);
+ break;
+ }
+}
+
+static const WindowDesc _scenedit_industry_normal_desc = {
+ WDP_AUTO, WDP_AUTO, 170, 225,
+ WC_SCEN_INDUSTRY,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _scenedit_industry_normal_widgets,
+ ScenEditIndustryWndProc,
+};
+
+static const WindowDesc _scenedit_industry_hilly_desc = {
+ WDP_AUTO, WDP_AUTO, 170, 225,
+ WC_SCEN_INDUSTRY,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _scenedit_industry_hilly_widgets,
+ ScenEditIndustryWndProc,
+};
+
+static const WindowDesc _scenedit_industry_desert_desc = {
+ WDP_AUTO, WDP_AUTO, 170, 225,
+ WC_SCEN_INDUSTRY,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _scenedit_industry_desert_widgets,
+ ScenEditIndustryWndProc,
+};
+
+static const WindowDesc _scenedit_industry_candy_desc = {
+ WDP_AUTO, WDP_AUTO, 170, 225,
+ WC_SCEN_INDUSTRY,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _scenedit_industry_candy_widgets,
+ ScenEditIndustryWndProc,
+};
+
+static const WindowDesc * const _scenedit_industry_descs[] = {
+ &_scenedit_industry_normal_desc,
+ &_scenedit_industry_hilly_desc,
+ &_scenedit_industry_desert_desc,
+ &_scenedit_industry_candy_desc,
+};
+
+
+static void ToolbarScenGenIndustry(Window *w)
+{
+ HandleButtonClick(w, 13);
+ SndPlayFx(SND_15_BEEP);
+ AllocateWindowDescFront(_scenedit_industry_descs[_opt.landscape],0);
+}
+
+static void ToolbarScenBuildRoad(Window *w)
+{
+ HandleButtonClick(w, 14);
+ SndPlayFx(SND_15_BEEP);
+ ShowBuildRoadScenToolbar();
+}
+
+static void ToolbarScenPlantTrees(Window *w)
+{
+ HandleButtonClick(w, 15);
+ SndPlayFx(SND_15_BEEP);
+ ShowBuildTreesScenToolbar();
+}
+
+static void ToolbarScenPlaceSign(Window *w)
+{
+ HandleButtonClick(w, 16);
+ SndPlayFx(SND_15_BEEP);
+ SelectSignTool();
+}
+
+static void ToolbarBtn_NULL(Window *w)
+{
+}
+
+
+typedef void ToolbarButtonProc(Window *w);
+
+static ToolbarButtonProc * const _toolbar_button_procs[] = {
+ ToolbarPauseClick,
+ ToolbarFastForwardClick,
+ ToolbarOptionsClick,
+ ToolbarSaveClick,
+ ToolbarMapClick,
+ ToolbarTownClick,
+ ToolbarSubsidiesClick,
+ ToolbarStationsClick,
+ ToolbarMoneyClick,
+ ToolbarPlayersClick,
+ ToolbarGraphsClick,
+ ToolbarLeagueClick,
+ ToolbarIndustryClick,
+ ToolbarTrainClick,
+ ToolbarRoadClick,
+ ToolbarShipClick,
+ ToolbarAirClick,
+ ToolbarZoomInClick,
+ ToolbarZoomOutClick,
+ ToolbarBuildRailClick,
+ ToolbarBuildRoadClick,
+ ToolbarBuildWaterClick,
+ ToolbarBuildAirClick,
+ ToolbarForestClick,
+ ToolbarMusicClick,
+ ToolbarNewspaperClick,
+ ToolbarHelpClick,
+};
+
+static void MainToolbarWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT:
+ // Draw brown-red toolbar bg.
+ GfxFillRect(0, 0, w->width-1, w->height-1, 0xB2);
+ GfxFillRect(0, 0, w->width-1, w->height-1, 0xB4 | PALETTE_MODIFIER_GREYOUT);
+
+ /* If spectator, disable all construction buttons
+ * ie : Build road, rail, ships, airports and landscaping
+ * Since enabled state is the default, just disable when needed */
+ SetWindowWidgetsDisabledState(w, _current_player == PLAYER_SPECTATOR, 19, 20, 21, 22, 23, WIDGET_LIST_END);
+ /* disable company list drop downs, if there are no companies */
+ SetWindowWidgetsDisabledState(w, ActivePlayerCount() == 0, 7, 8, 13, 14, 15, 16, WIDGET_LIST_END);
+
+ DrawWindowWidgets(w);
+ break;
+
+ case WE_CLICK: {
+ if (_game_mode != GM_MENU && !IsWindowWidgetDisabled(w, e->we.click.widget))
+ _toolbar_button_procs[e->we.click.widget](w);
+ } break;
+
+ case WE_KEYPRESS: {
+ switch (e->we.keypress.keycode) {
+ case WKC_F1: case WKC_PAUSE: ToolbarPauseClick(w); break;
+ case WKC_F2: ShowGameOptions(); break;
+ case WKC_F3: MenuClickSaveLoad(0); break;
+ case WKC_F4: ShowSmallMap(); break;
+ case WKC_F5: ShowTownDirectory(); break;
+ case WKC_F6: ShowSubsidiesList(); break;
+ case WKC_F7: ShowPlayerStations(_local_player); break;
+ case WKC_F8: ShowPlayerFinances(_local_player); break;
+ case WKC_F9: ShowPlayerCompany(_local_player); break;
+ case WKC_F10:ShowOperatingProfitGraph(); break;
+ case WKC_F11: ShowCompanyLeagueTable(); break;
+ case WKC_F12: ShowBuildIndustryWindow(); break;
+ case WKC_SHIFT | WKC_F1: ShowVehicleListWindow(_local_player, INVALID_STATION, VEH_Train); break;
+ case WKC_SHIFT | WKC_F2: ShowVehicleListWindow(_local_player, INVALID_STATION, VEH_Road); break;
+ case WKC_SHIFT | WKC_F3: ShowVehicleListWindow(_local_player, INVALID_STATION, VEH_Ship); break;
+ case WKC_SHIFT | WKC_F4: ShowVehicleListWindow(_local_player, INVALID_STATION, VEH_Aircraft); break;
+ case WKC_SHIFT | WKC_F5: ToolbarZoomInClick(w); break;
+ case WKC_SHIFT | WKC_F6: ToolbarZoomOutClick(w); break;
+ case WKC_SHIFT | WKC_F7: ShowBuildRailToolbar(_last_built_railtype, -1); break;
+ case WKC_SHIFT | WKC_F8: ShowBuildRoadToolbar(); break;
+ case WKC_SHIFT | WKC_F9: ShowBuildDocksToolbar(); break;
+ case WKC_SHIFT | WKC_F10:ShowBuildAirToolbar(); break;
+ case WKC_SHIFT | WKC_F11: ShowBuildTreesToolbar(); break;
+ case WKC_SHIFT | WKC_F12: ShowMusicWindow(); break;
+ case WKC_CTRL | 'S': MenuClickSmallScreenshot(); break;
+ case WKC_CTRL | 'G': MenuClickWorldScreenshot(); break;
+ case WKC_CTRL | WKC_ALT | 'C': if (!_networking) ShowCheatWindow(); break;
+ case 'A': ShowBuildRailToolbar(_last_built_railtype, 4); break; /* Invoke Autorail */
+ case 'L': ShowTerraformToolbar(); break;
+ default: return;
+ }
+ e->we.keypress.cont = false;
+ } break;
+
+ case WE_PLACE_OBJ: {
+ _place_proc(e->we.place.tile);
+ } break;
+
+ case WE_ABORT_PLACE_OBJ: {
+ RaiseWindowWidget(w, 25);
+ SetWindowDirty(w);
+ } break;
+
+ case WE_MOUSELOOP:
+ if (IsWindowWidgetLowered(w, 0) != !!_pause) {
+ ToggleWidgetLoweredState(w, 0);
+ InvalidateWidget(w, 0);
+ }
+
+ if (IsWindowWidgetLowered(w, 1) != !!_fast_forward) {
+ ToggleWidgetLoweredState(w, 1);
+ InvalidateWidget(w, 1);
+ }
+ break;
+
+ case WE_TIMEOUT: {
+ uint i;
+ for (i = 2; i < w->widget_count; i++) {
+ if (IsWindowWidgetLowered(w, i)) {
+ RaiseWindowWidget(w, i);
+ InvalidateWidget(w, i);
+ }
+ }
+ break;
+ }
+
+ case WE_MESSAGE:
+ HandleZoomMessage(w, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, 17, 18);
+ break;
+ }
+}
+
+static const Widget _toolb_normal_widgets[] = {
+{ WWT_IMGBTN, RESIZE_NONE, 14, 0, 21, 0, 21, SPR_IMG_PAUSE, STR_0171_PAUSE_GAME},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 22, 43, 0, 21, SPR_IMG_FASTFORWARD, STR_FAST_FORWARD},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 44, 65, 0, 21, SPR_IMG_SETTINGS, STR_0187_OPTIONS},
+{ WWT_IMGBTN_2, RESIZE_NONE, 14, 66, 87, 0, 21, SPR_IMG_SAVE, STR_0172_SAVE_GAME_ABANDON_GAME},
+
+{ WWT_IMGBTN, RESIZE_NONE, 14, 96, 117, 0, 21, SPR_IMG_SMALLMAP, STR_0174_DISPLAY_MAP},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 118, 139, 0, 21, SPR_IMG_TOWN, STR_0176_DISPLAY_TOWN_DIRECTORY},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 140, 161, 0, 21, SPR_IMG_SUBSIDIES, STR_02DC_DISPLAY_SUBSIDIES},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 162, 183, 0, 21, SPR_IMG_COMPANY_LIST, STR_0173_DISPLAY_LIST_OF_COMPANY},
+
+{ WWT_IMGBTN, RESIZE_NONE, 14, 191, 212, 0, 21, SPR_IMG_COMPANY_FINANCE, STR_0177_DISPLAY_COMPANY_FINANCES},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 213, 235, 0, 21, SPR_IMG_COMPANY_GENERAL, STR_0178_DISPLAY_COMPANY_GENERAL},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 236, 257, 0, 21, SPR_IMG_GRAPHS, STR_0179_DISPLAY_GRAPHS},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 258, 279, 0, 21, SPR_IMG_COMPANY_LEAGUE, STR_017A_DISPLAY_COMPANY_LEAGUE},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 280, 301, 0, 21, SPR_IMG_INDUSTRY, STR_0312_FUND_CONSTRUCTION_OF_NEW},
+
+{ WWT_IMGBTN, RESIZE_NONE, 14, 310, 331, 0, 21, SPR_IMG_TRAINLIST, STR_017B_DISPLAY_LIST_OF_COMPANY},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 332, 353, 0, 21, SPR_IMG_TRUCKLIST, STR_017C_DISPLAY_LIST_OF_COMPANY},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 354, 375, 0, 21, SPR_IMG_SHIPLIST, STR_017D_DISPLAY_LIST_OF_COMPANY},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 376, 397, 0, 21, SPR_IMG_AIRPLANESLIST, STR_017E_DISPLAY_LIST_OF_COMPANY},
+
+{ WWT_IMGBTN, RESIZE_NONE, 14, 406, 427, 0, 21, SPR_IMG_ZOOMIN, STR_017F_ZOOM_THE_VIEW_IN},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 428, 449, 0, 21, SPR_IMG_ZOOMOUT, STR_0180_ZOOM_THE_VIEW_OUT},
+
+{ WWT_IMGBTN, RESIZE_NONE, 14, 457, 478, 0, 21, SPR_IMG_BUILDRAIL, STR_0181_BUILD_RAILROAD_TRACK},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 479, 500, 0, 21, SPR_IMG_BUILDROAD, STR_0182_BUILD_ROADS},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 501, 522, 0, 21, SPR_IMG_BUILDWATER, STR_0183_BUILD_SHIP_DOCKS},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 523, 544, 0, 21, SPR_IMG_BUILDAIR, STR_0184_BUILD_AIRPORTS},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 545, 566, 0, 21, SPR_IMG_LANDSCAPING, STR_LANDSCAPING_TOOLBAR_TIP}, // tree icon is 0x2E6
+
+{ WWT_IMGBTN, RESIZE_NONE, 14, 574, 595, 0, 21, SPR_IMG_MUSIC, STR_01D4_SHOW_SOUND_MUSIC_WINDOW},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 596, 617, 0, 21, SPR_IMG_MESSAGES, STR_0203_SHOW_LAST_MESSAGE_NEWS},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 618, 639, 0, 21, SPR_IMG_QUERY, STR_0186_LAND_BLOCK_INFORMATION},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _toolb_normal_desc = {
+ 0, 0, 640, 22,
+ WC_MAIN_TOOLBAR,0,
+ WDF_STD_TOOLTIPS | WDF_DEF_WIDGET,
+ _toolb_normal_widgets,
+ MainToolbarWndProc
+};
+
+
+static const Widget _toolb_scen_widgets[] = {
+{ WWT_IMGBTN, RESIZE_NONE, 14, 0, 21, 0, 21, SPR_IMG_PAUSE, STR_0171_PAUSE_GAME},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 22, 43, 0, 21, SPR_IMG_FASTFORWARD, STR_FAST_FORWARD},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 44, 65, 0, 21, SPR_IMG_SETTINGS, STR_0187_OPTIONS},
+{WWT_IMGBTN_2, RESIZE_NONE, 14, 66, 87, 0, 21, SPR_IMG_SAVE, STR_0297_SAVE_SCENARIO_LOAD_SCENARIO},
+
+{ WWT_PANEL, RESIZE_NONE, 14, 96, 225, 0, 21, 0x0, STR_NULL},
+
+{ WWT_PANEL, RESIZE_NONE, 14, 233, 362, 0, 21, 0x0, STR_NULL},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 236, 247, 5, 16, SPR_ARROW_DOWN, STR_029E_MOVE_THE_STARTING_DATE},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 347, 358, 5, 16, SPR_ARROW_UP, STR_029F_MOVE_THE_STARTING_DATE},
+
+{ WWT_IMGBTN, RESIZE_NONE, 14, 371, 392, 0, 21, SPR_IMG_SMALLMAP, STR_0175_DISPLAY_MAP_TOWN_DIRECTORY},
+
+{ WWT_IMGBTN, RESIZE_NONE, 14, 400, 421, 0, 21, SPR_IMG_ZOOMIN, STR_017F_ZOOM_THE_VIEW_IN},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 422, 443, 0, 21, SPR_IMG_ZOOMOUT, STR_0180_ZOOM_THE_VIEW_OUT},
+
+{ WWT_IMGBTN, RESIZE_NONE, 14, 452, 473, 0, 21, SPR_IMG_LANDSCAPING, STR_022E_LANDSCAPE_GENERATION},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 474, 495, 0, 21, SPR_IMG_TOWN, STR_022F_TOWN_GENERATION},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 496, 517, 0, 21, SPR_IMG_INDUSTRY, STR_0230_INDUSTRY_GENERATION},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 518, 539, 0, 21, SPR_IMG_BUILDROAD, STR_0231_ROAD_CONSTRUCTION},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 540, 561, 0, 21, SPR_IMG_PLANTTREES, STR_0288_PLANT_TREES},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 562, 583, 0, 21, SPR_IMG_SIGN, STR_0289_PLACE_SIGN},
+
+{ WWT_EMPTY, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL},
+{ WWT_EMPTY, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL},
+{ WWT_EMPTY, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL},
+{ WWT_EMPTY, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL},
+{ WWT_EMPTY, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL},
+{ WWT_EMPTY, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL},
+{ WWT_EMPTY, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 596, 617, 0, 21, SPR_IMG_MUSIC, STR_01D4_SHOW_SOUND_MUSIC_WINDOW},
+{ WWT_EMPTY, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 618, 639, 0, 21, SPR_IMG_QUERY, STR_0186_LAND_BLOCK_INFORMATION},
+{WIDGETS_END},
+};
+
+static ToolbarButtonProc * const _scen_toolbar_button_procs[] = {
+ ToolbarPauseClick,
+ ToolbarFastForwardClick,
+ ToolbarOptionsClick,
+ ToolbarScenSaveOrLoad,
+ ToolbarBtn_NULL,
+ ToolbarBtn_NULL,
+ ToolbarScenDateBackward,
+ ToolbarScenDateForward,
+ ToolbarScenMapTownDir,
+ ToolbarScenZoomIn,
+ ToolbarScenZoomOut,
+ ToolbarScenGenLand,
+ ToolbarScenGenTown,
+ ToolbarScenGenIndustry,
+ ToolbarScenBuildRoad,
+ ToolbarScenPlantTrees,
+ ToolbarScenPlaceSign,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ ToolbarMusicClick,
+ NULL,
+ ToolbarHelpClick,
+};
+
+static void ScenEditToolbarWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT:
+ SetWindowWidgetDisabledState(w, 6, _patches_newgame.starting_year <= MIN_YEAR);
+ SetWindowWidgetDisabledState(w, 7, _patches_newgame.starting_year >= MAX_YEAR);
+
+ // Draw brown-red toolbar bg.
+ GfxFillRect(0, 0, w->width-1, w->height-1, 0xB2);
+ GfxFillRect(0, 0, w->width-1, w->height-1, 0xB4 | PALETTE_MODIFIER_GREYOUT);
+
+ DrawWindowWidgets(w);
+
+ SetDParam(0, ConvertYMDToDate(_patches_newgame.starting_year, 0, 1));
+ DrawStringCentered(298, 6, STR_00AF, 0);
+
+ SetDParam(0, ConvertYMDToDate(_patches_newgame.starting_year, 0, 1));
+ DrawStringCentered(161, 1, STR_0221_OPENTTD, 0);
+ DrawStringCentered(161, 11,STR_0222_SCENARIO_EDITOR, 0);
+
+ break;
+
+ case WE_CLICK: {
+ if (_game_mode == GM_MENU) return;
+ _scen_toolbar_button_procs[e->we.click.widget](w);
+ } break;
+
+ case WE_KEYPRESS:
+ switch (e->we.keypress.keycode) {
+ case WKC_F1: ToolbarPauseClick(w); break;
+ case WKC_F2: ShowGameOptions(); break;
+ case WKC_F3: MenuClickSaveLoad(0); break;
+ case WKC_F4: ToolbarScenGenLand(w); break;
+ case WKC_F5: ToolbarScenGenTown(w); break;
+ case WKC_F6: ToolbarScenGenIndustry(w); break;
+ case WKC_F7: ToolbarScenBuildRoad(w); break;
+ case WKC_F8: ToolbarScenPlantTrees(w); break;
+ case WKC_F9: ToolbarScenPlaceSign(w); break;
+ case WKC_F10: ShowMusicWindow(); break;
+ case WKC_F11: PlaceLandBlockInfo(); break;
+ case WKC_CTRL | 'S': MenuClickSmallScreenshot(); break;
+ case WKC_CTRL | 'G': MenuClickWorldScreenshot(); break;
+ case 'L': ShowEditorTerraformToolBar(); break;
+ default: return;
+ }
+ e->we.keypress.cont = false;
+ break;
+
+ case WE_PLACE_OBJ: {
+ _place_proc(e->we.place.tile);
+ } break;
+
+ case WE_ABORT_PLACE_OBJ: {
+ RaiseWindowWidget(w, 25);
+ SetWindowDirty(w);
+ } break;
+
+ case WE_MOUSELOOP:
+ if (IsWindowWidgetLowered(w, 0) != !!_pause) {
+ ToggleWidgetLoweredState(w, 0);
+ SetWindowDirty(w);
+ }
+
+ if (IsWindowWidgetLowered(w, 1) != !!_fast_forward) {
+ ToggleWidgetLoweredState(w, 1);
+ SetWindowDirty(w);
+ }
+ break;
+
+ case WE_MESSAGE:
+ HandleZoomMessage(w, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, 9, 10);
+ break;
+ }
+}
+
+static const WindowDesc _toolb_scen_desc = {
+ 0, 0, 640, 22,
+ WC_MAIN_TOOLBAR,0,
+ WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _toolb_scen_widgets,
+ ScenEditToolbarWndProc
+};
+
+extern GetNewsStringCallbackProc * const _get_news_string_callback[];
+
+
+static bool DrawScrollingStatusText(const NewsItem *ni, int pos)
+{
+ char buf[512];
+ StringID str;
+ const char *s;
+ char *d;
+ DrawPixelInfo tmp_dpi, *old_dpi;
+ int x;
+ char buffer[256];
+
+ if (ni->display_mode == 3) {
+ str = _get_news_string_callback[ni->callback](ni);
+ } else {
+ COPY_IN_DPARAM(0, ni->params, lengthof(ni->params));
+ str = ni->string_id;
+ }
+
+ GetString(buf, str, lastof(buf));
+
+ s = buf;
+ d = buffer;
+
+ for (;;) {
+ WChar c = Utf8Consume(&s);
+ if (c == 0) {
+ *d = '\0';
+ break;
+ } else if (*s == 0x0D) {
+ d[0] = d[1] = d[2] = d[3] = ' ';
+ d += 4;
+ } else if (IsPrintable(c)) {
+ d += Utf8Encode(d, c);
+ }
+ }
+
+ if (!FillDrawPixelInfo(&tmp_dpi, 141, 1, 358, 11)) return true;
+
+ old_dpi = _cur_dpi;
+ _cur_dpi = &tmp_dpi;
+
+ x = DoDrawString(buffer, pos, 0, 13);
+ _cur_dpi = old_dpi;
+
+ return x > 0;
+}
+
+static void StatusBarWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ const Player *p = (_local_player == PLAYER_SPECTATOR) ? NULL : GetPlayer(_local_player);
+
+ DrawWindowWidgets(w);
+ SetDParam(0, _date);
+ DrawStringCentered(
+ 70, 1, (_pause || _patches.status_long_date) ? STR_00AF : STR_00AE, 0
+ );
+
+ if (p != NULL) {
+ // Draw player money
+ SetDParam64(0, p->money64);
+ DrawStringCentered(570, 1, p->player_money >= 0 ? STR_0004 : STR_0005, 0);
+ }
+
+ // Draw status bar
+ if (w->message.msg) { // true when saving is active
+ DrawStringCentered(320, 1, STR_SAVING_GAME, 0);
+ } else if (_do_autosave) {
+ DrawStringCentered(320, 1, STR_032F_AUTOSAVE, 0);
+ } else if (_pause) {
+ DrawStringCentered(320, 1, STR_0319_PAUSED, 0);
+ } else if (WP(w,def_d).data_1 > -1280 && FindWindowById(WC_NEWS_WINDOW,0) == NULL && _statusbar_news_item.string_id != 0) {
+ // Draw the scrolling news text
+ if (!DrawScrollingStatusText(&_statusbar_news_item, WP(w,def_d).data_1))
+ WP(w,def_d).data_1 = -1280;
+ } else {
+ if (p != NULL) {
+ // This is the default text
+ SetDParam(0, p->name_1);
+ SetDParam(1, p->name_2);
+ DrawStringCentered(320, 1, STR_02BA, 0);
+ }
+ }
+
+ if (WP(w, def_d).data_2 > 0) DrawSprite(SPR_BLOT | PALETTE_TO_RED, 489, 2);
+ } break;
+
+ case WE_MESSAGE:
+ w->message.msg = e->we.message.msg;
+ SetWindowDirty(w);
+ break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 1: ShowLastNewsMessage(); break;
+ case 2: if (_local_player != PLAYER_SPECTATOR) ShowPlayerFinances(_local_player); break;
+ default: ResetObjectToPlace();
+ }
+ break;
+
+ case WE_TICK: {
+ if (_pause) return;
+
+ if (WP(w, def_d).data_1 > -1280) { /* Scrolling text */
+ WP(w, def_d).data_1 -= 2;
+ InvalidateWidget(w, 1);
+ }
+
+ if (WP(w, def_d).data_2 > 0) { /* Red blot to show there are new unread newsmessages */
+ WP(w, def_d).data_2 -= 2;
+ } else if (WP(w, def_d).data_2 < 0) {
+ WP(w, def_d).data_2 = 0;
+ InvalidateWidget(w, 1);
+ }
+
+ break;
+ }
+ }
+}
+
+static const Widget _main_status_widgets[] = {
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 139, 0, 11, 0x0, STR_NULL},
+{ WWT_PUSHBTN, RESIZE_NONE, 14, 140, 499, 0, 11, 0x0, STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS},
+{ WWT_PUSHBTN, RESIZE_NONE, 14, 500, 639, 0, 11, 0x0, STR_NULL},
+{ WIDGETS_END},
+};
+
+static WindowDesc _main_status_desc = {
+ WDP_CENTER, 0, 640, 12,
+ WC_STATUS_BAR,0,
+ WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _main_status_widgets,
+ StatusBarWndProc
+};
+
+extern void UpdateAllStationVirtCoord(void);
+
+static void MainWindowWndProc(Window *w, WindowEvent *e)
+{
+ int off_x;
+
+ switch (e->event) {
+ case WE_PAINT:
+ DrawWindowViewport(w);
+ if (_game_mode == GM_MENU) {
+ off_x = _screen.width / 2;
+
+ DrawSprite(SPR_OTTD_O, off_x - 120, 50);
+ DrawSprite(SPR_OTTD_P, off_x - 86, 50);
+ DrawSprite(SPR_OTTD_E, off_x - 53, 50);
+ DrawSprite(SPR_OTTD_N, off_x - 22, 50);
+
+ DrawSprite(SPR_OTTD_T, off_x + 34, 50);
+ DrawSprite(SPR_OTTD_T, off_x + 65, 50);
+ DrawSprite(SPR_OTTD_D, off_x + 96, 50);
+
+ /*
+ DrawSprite(SPR_OTTD_R, off_x + 119, 50);
+ DrawSprite(SPR_OTTD_A, off_x + 148, 50);
+ DrawSprite(SPR_OTTD_N, off_x + 181, 50);
+ DrawSprite(SPR_OTTD_S, off_x + 215, 50);
+ DrawSprite(SPR_OTTD_P, off_x + 246, 50);
+ DrawSprite(SPR_OTTD_O, off_x + 275, 50);
+ DrawSprite(SPR_OTTD_R, off_x + 307, 50);
+ DrawSprite(SPR_OTTD_T, off_x + 337, 50);
+
+ DrawSprite(SPR_OTTD_T, off_x + 390, 50);
+ DrawSprite(SPR_OTTD_Y, off_x + 417, 50);
+ DrawSprite(SPR_OTTD_C, off_x + 447, 50);
+ DrawSprite(SPR_OTTD_O, off_x + 478, 50);
+ DrawSprite(SPR_OTTD_O, off_x + 509, 50);
+ DrawSprite(SPR_OTTD_N, off_x + 541, 50);
+ */
+ }
+ break;
+
+ case WE_KEYPRESS:
+ switch (e->we.keypress.keycode) {
+ case 'Q' | WKC_CTRL:
+ case 'Q' | WKC_META:
+ HandleExitGameRequest();
+ break;
+ }
+
+ /* Disable all key shortcuts, except quit shortcuts when
+ * generating the world, otherwise they create threading
+ * problem during the generating, resulting in random
+ * assertions that are hard to trigger and debug */
+ if (IsGeneratingWorld()) break;
+
+ if (e->we.keypress.keycode == WKC_BACKQUOTE) {
+ IConsoleSwitch();
+ e->we.keypress.cont = false;
+ break;
+ }
+
+ if (_game_mode == GM_MENU) break;
+
+ switch (e->we.keypress.keycode) {
+ case 'C':
+ case 'Z': {
+ Point pt = GetTileBelowCursor();
+ if (pt.x != -1) {
+ ScrollMainWindowTo(pt.x, pt.y);
+ if (e->we.keypress.keycode == 'Z') MaxZoomInOut(ZOOM_IN, w);
+ }
+ break;
+ }
+
+ case WKC_ESC: ResetObjectToPlace(); break;
+ case WKC_DELETE: DeleteNonVitalWindows(); break;
+ case WKC_DELETE | WKC_SHIFT: DeleteAllNonVitalWindows(); break;
+ case 'R' | WKC_CTRL: MarkWholeScreenDirty(); break;
+
+#if defined(_DEBUG)
+ case '0' | WKC_ALT: /* Crash the game */
+ *(byte*)0 = 0;
+ break;
+
+ case '1' | WKC_ALT: /* Gimme money */
+ /* Server can not cheat in advertise mode either! */
+ if (!_networking || !_network_server || !_network_advertise)
+ DoCommandP(0, -10000000, 0, NULL, CMD_MONEY_CHEAT);
+ break;
+
+ case '2' | WKC_ALT: /* Update the coordinates of all station signs */
+ UpdateAllStationVirtCoord();
+ break;
+#endif
+
+ case 'X':
+ _display_opt ^= DO_TRANS_BUILDINGS;
+ MarkWholeScreenDirty();
+ break;
+
+#ifdef ENABLE_NETWORK
+ case WKC_RETURN: case 'T': // smart chat; send to team if any, otherwise to all
+ if (_networking) {
+ const NetworkClientInfo *cio = NetworkFindClientInfoFromIndex(_network_own_client_index);
+ bool teamchat = false;
+
+ /* Only players actually playing can speak to team. Eg spectators cannot */
+ if (_patches.prefer_teamchat && IsValidPlayer(cio->client_playas)) {
+ const NetworkClientInfo *ci;
+ FOR_ALL_ACTIVE_CLIENT_INFOS(ci) {
+ if (ci->client_playas == cio->client_playas && ci != cio) {
+ teamchat = true;
+ break;
+ }
+ }
+ }
+
+ ShowNetworkChatQueryWindow(teamchat ? DESTTYPE_TEAM : DESTTYPE_BROADCAST, cio->client_playas);
+ }
+ break;
+
+ case WKC_SHIFT | WKC_RETURN: case WKC_SHIFT | 'T': // send text message to all players
+ if (_networking) ShowNetworkChatQueryWindow(DESTTYPE_BROADCAST, 0);
+ break;
+
+ case WKC_CTRL | WKC_RETURN: case WKC_CTRL | 'T': // send text to all team mates
+ if (_networking) {
+ const NetworkClientInfo *ci = NetworkFindClientInfoFromIndex(_network_own_client_index);
+ ShowNetworkChatQueryWindow(DESTTYPE_TEAM, ci->client_playas);
+ }
+ break;
+#endif
+
+ default: return;
+ }
+ e->we.keypress.cont = false;
+ break;
+
+ case WE_SCROLL: {
+ ViewPort *vp = IsPtInWindowViewport(w, _cursor.pos.x, _cursor.pos.y);
+
+ if (vp == NULL) {
+ _cursor.fix_at = false;
+ _scrolling_viewport = false;
+ }
+
+ WP(w, vp_d).scrollpos_x += e->we.scroll.delta.x << vp->zoom;
+ WP(w, vp_d).scrollpos_y += e->we.scroll.delta.y << vp->zoom;
+ } break;
+
+ case WE_MOUSEWHEEL:
+ ZoomInOrOutToCursorWindow(e->we.wheel.wheel < 0, w);
+ break;
+
+ case WE_MESSAGE:
+ /* Forward the message to the appropiate toolbar (ingame or scenario editor) */
+ SendWindowMessage(WC_MAIN_TOOLBAR, 0, e->we.message.msg, e->we.message.wparam, e->we.message.lparam);
+ break;
+ }
+}
+
+
+void ShowSelectGameWindow(void);
+
+void SetupColorsAndInitialWindow(void)
+{
+ uint i;
+ Window *w;
+ int width, height;
+
+ for (i = 0; i != 16; i++) {
+ const byte *b = GetNonSprite(PALETTE_RECOLOR_START + i);
+
+ assert(b);
+ memcpy(_colour_gradient[i], b + 0xC6, sizeof(_colour_gradient[i]));
+ }
+
+ width = _screen.width;
+ height = _screen.height;
+
+ w = AllocateWindow(0, 0, width, height, MainWindowWndProc, WC_MAIN_WINDOW, NULL);
+ AssignWindowViewport(w, 0, 0, width, height, TileXY(32, 32), 0);
+
+ // XXX: these are not done
+ switch (_game_mode) {
+ default: NOT_REACHED();
+ case GM_MENU:
+ ShowSelectGameWindow();
+ break;
+
+ case GM_NORMAL:
+ case GM_EDITOR:
+ ShowVitalWindows();
+ break;
+ }
+}
+
+void ShowVitalWindows(void)
+{
+ Window *w;
+
+ w = AllocateWindowDesc((_game_mode != GM_EDITOR) ? &_toolb_normal_desc : &_toolb_scen_desc);
+ DoZoomInOutWindow(ZOOM_NONE, w);
+
+ CLRBITS(w->flags4, WF_WHITE_BORDER_MASK);
+
+ SetWindowWidgetDisabledState(w, 0, _networking && !_network_server); // if not server, disable pause button
+ SetWindowWidgetDisabledState(w, 1, _networking); // if networking, disable fast-forward button
+
+ /* 'w' is for sure a WC_MAIN_TOOLBAR */
+ PositionMainToolbar(w);
+
+ /* Status bad only for normal games */
+ if (_game_mode == GM_EDITOR) return;
+
+ _main_status_desc.top = _screen.height - 12;
+ w = AllocateWindowDesc(&_main_status_desc);
+ CLRBITS(w->flags4, WF_WHITE_BORDER_MASK);
+
+ WP(w,def_d).data_1 = -1280;
+}
+
+void GameSizeChanged(void)
+{
+ _cur_resolution[0] = _screen.width;
+ _cur_resolution[1] = _screen.height;
+ RelocateAllWindows(_screen.width, _screen.height);
+ ScreenSizeChanged();
+ MarkWholeScreenDirty();
+}
+
+void InitializeMainGui(void)
+{
+ /* Clean old GUI values */
+ _last_built_railtype = 0;
+}
+
+
diff --git a/src/map.c b/src/map.c
new file mode 100644
index 000000000..df16343c7
--- /dev/null
+++ b/src/map.c
@@ -0,0 +1,246 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "debug.h"
+#include "functions.h"
+#include "macros.h"
+#include "map.h"
+#include "direction.h"
+
+#if defined(_MSC_VER) && _MSC_VER >= 1400 /* VStudio 2005 is stupid! */
+/* Why the hell is that not in all MSVC headers?? */
+_CRTIMP void __cdecl _assert(void *, void *, unsigned);
+#endif
+
+uint _map_log_x;
+uint _map_size_x;
+uint _map_size_y;
+uint _map_tile_mask;
+uint _map_size;
+
+Tile* _m = NULL;
+
+
+void AllocateMap(uint size_x, uint size_y)
+{
+ // Make sure that the map size is within the limits and that
+ // the x axis size is a power of 2.
+ if (size_x < 64 || size_x > 2048 ||
+ size_y < 64 || size_y > 2048 ||
+ (size_x&(size_x-1)) != 0 ||
+ (size_y&(size_y-1)) != 0)
+ error("Invalid map size");
+
+ DEBUG(map, 1, "Allocating map of size %dx%d", size_x, size_y);
+
+ _map_log_x = FindFirstBit(size_x);
+ _map_size_x = size_x;
+ _map_size_y = size_y;
+ _map_size = size_x * size_y;
+ _map_tile_mask = _map_size - 1;
+
+ free(_m);
+ _m = calloc(_map_size, sizeof(*_m));
+
+ // XXX TODO handle memory shortage more gracefully
+ if (_m == NULL) error("Failed to allocate memory for the map");
+}
+
+
+#ifdef _DEBUG
+TileIndex TileAdd(TileIndex tile, TileIndexDiff add,
+ const char *exp, const char *file, int line)
+{
+ int dx;
+ int dy;
+ uint x;
+ uint y;
+
+ dx = add & MapMaxX();
+ if (dx >= (int)MapSizeX() / 2) dx -= MapSizeX();
+ dy = (add - dx) / (int)MapSizeX();
+
+ x = TileX(tile) + dx;
+ y = TileY(tile) + dy;
+
+ if (x >= MapSizeX() || y >= MapSizeY()) {
+ char buf[512];
+
+ snprintf(buf, lengthof(buf), "TILE_ADD(%s) when adding 0x%.4X and 0x%.4X failed",
+ exp, tile, add);
+#if !defined(_MSC_VER)
+ fprintf(stderr, "%s:%d %s\n", file, line, buf);
+#else
+ _assert(buf, (char*)file, line);
+#endif
+ }
+
+ assert(TileXY(x,y) == TILE_MASK(tile + add));
+
+ return TileXY(x,y);
+}
+#endif
+
+
+uint ScaleByMapSize(uint n)
+{
+ // First shift by 12 to prevent integer overflow for large values of n.
+ // >>12 is safe since the min mapsize is 64x64
+ // Add (1<<4)-1 to round upwards.
+ return (n * (MapSize() >> 12) + (1<<4) - 1) >> 4;
+}
+
+
+// Scale relative to the circumference of the map
+uint ScaleByMapSize1D(uint n)
+{
+ // Normal circumference for the X+Y is 256+256 = 1<<9
+ // Note, not actually taking the full circumference into account,
+ // just half of it.
+ // (1<<9) - 1 is there to scale upwards.
+ return (n * (MapSizeX() + MapSizeY()) + (1<<9) - 1) >> 9;
+}
+
+
+// This function checks if we add addx/addy to tile, if we
+// do wrap around the edges. For example, tile = (10,2) and
+// addx = +3 and addy = -4. This function will now return
+// INVALID_TILE, because the y is wrapped. This is needed in
+// for example, farmland. When the tile is not wrapped,
+// the result will be tile + TileDiffXY(addx, addy)
+uint TileAddWrap(TileIndex tile, int addx, int addy)
+{
+ uint x = TileX(tile) + addx;
+ uint y = TileY(tile) + addy;
+
+ // Are we about to wrap?
+ if (x < MapMaxX() && y < MapMaxY())
+ return tile + TileDiffXY(addx, addy);
+
+ return INVALID_TILE;
+}
+
+const TileIndexDiffC _tileoffs_by_diagdir[] = {
+ {-1, 0}, // DIAGDIR_NE
+ { 0, 1}, // DIAGDIR_SE
+ { 1, 0}, // DIAGDIR_SW
+ { 0, -1} // DIAGDIR_NW
+};
+
+const TileIndexDiffC _tileoffs_by_dir[] = {
+ {-1, -1}, // DIR_N
+ {-1, 0}, // DIR_NE
+ {-1, 1}, // DIR_E
+ { 0, 1}, // DIR_SE
+ { 1, 1}, // DIR_S
+ { 1, 0}, // DIR_SW
+ { 1, -1}, // DIR_W
+ { 0, -1} // DIR_NW
+};
+
+uint DistanceManhattan(TileIndex t0, TileIndex t1)
+{
+ const uint dx = abs(TileX(t0) - TileX(t1));
+ const uint dy = abs(TileY(t0) - TileY(t1));
+ return dx + dy;
+}
+
+
+uint DistanceSquare(TileIndex t0, TileIndex t1)
+{
+ const int dx = TileX(t0) - TileX(t1);
+ const int dy = TileY(t0) - TileY(t1);
+ return dx * dx + dy * dy;
+}
+
+
+uint DistanceMax(TileIndex t0, TileIndex t1)
+{
+ const uint dx = abs(TileX(t0) - TileX(t1));
+ const uint dy = abs(TileY(t0) - TileY(t1));
+ return dx > dy ? dx : dy;
+}
+
+
+uint DistanceMaxPlusManhattan(TileIndex t0, TileIndex t1)
+{
+ const uint dx = abs(TileX(t0) - TileX(t1));
+ const uint dy = abs(TileY(t0) - TileY(t1));
+ return dx > dy ? 2 * dx + dy : 2 * dy + dx;
+}
+
+uint DistanceFromEdge(TileIndex tile)
+{
+ const uint xl = TileX(tile);
+ const uint yl = TileY(tile);
+ const uint xh = MapSizeX() - 1 - xl;
+ const uint yh = MapSizeY() - 1 - yl;
+ const uint minl = xl < yl ? xl : yl;
+ const uint minh = xh < yh ? xh : yh;
+ return minl < minh ? minl : minh;
+}
+
+/**
+ * Function performing a search around a center tile and going outward, thus in circle.
+ * Although it really is a square search...
+ * Every tile will be tested by means of the callback function proc,
+ * which will determine if yes or no the given tile meets criteria of search.
+ * @param tile to start the search from
+ * @param size: number of tiles per side of the desired search area
+ * @param proc: callback testing function pointer.
+ * @param data to be passed to the callback function. Depends on the implementation
+ * @result of the search
+ * @pre proc != NULL
+ * @pre size > 0
+ */
+bool CircularTileSearch(TileIndex tile, uint size, TestTileOnSearchProc proc, uint32 data)
+{
+ uint n, x, y;
+ DiagDirection dir;
+
+ assert(proc != NULL);
+ assert(size > 0);
+
+ x = TileX(tile);
+ y = TileY(tile);
+
+ if (size % 2 == 1) {
+ /* If the length of the side is uneven, the center has to be checked
+ * separately, as the pattern of uneven sides requires to go around the center */
+ n = 2;
+ if (proc(TileXY(x, y), data)) return true;
+
+ /* If tile test is not successfull, get one tile down and left,
+ * ready for a test in first circle around center tile */
+ x += _tileoffs_by_dir[DIR_W].x;
+ y += _tileoffs_by_dir[DIR_W].y;
+ } else {
+ n = 1;
+ /* To use _tileoffs_by_diagdir's order, we must relocate to
+ * another tile, as we now first go 'up', 'right', 'down', 'left'
+ * instead of 'right', 'down', 'left', 'up', which the calling
+ * function assume. */
+ x++;
+ }
+
+ for (; n < size; n += 2) {
+ for (dir = DIAGDIR_NE; dir < DIAGDIR_END; dir++) {
+ uint j;
+ for (j = n; j != 0; j--) {
+ if (x <= MapMaxX() && y <= MapMaxY() && ///< Is the tile within the map?
+ proc(TileXY(x, y), data)) { ///< Is the callback successfulll?
+ return true; ///< then stop the search
+ }
+
+ /* Step to the next 'neighbour' in the circular line */
+ x += _tileoffs_by_diagdir[dir].x;
+ y += _tileoffs_by_diagdir[dir].y;
+ }
+ }
+ /* Jump to next circle to test */
+ x += _tileoffs_by_dir[DIR_W].x;
+ y += _tileoffs_by_dir[DIR_W].y;
+ }
+ return false;
+}
diff --git a/src/map.h b/src/map.h
new file mode 100644
index 000000000..25e29ef06
--- /dev/null
+++ b/src/map.h
@@ -0,0 +1,190 @@
+/* $Id$ */
+
+#ifndef MAP_H
+#define MAP_H
+
+#include "stdafx.h"
+
+// Putting externs inside inline functions seems to confuse the aliasing
+// checking on MSVC6. Never use those variables directly.
+extern uint _map_log_x;
+extern uint _map_size_x;
+extern uint _map_size_y;
+extern uint _map_tile_mask;
+extern uint _map_size;
+
+#define TILE_MASK(x) ((x) & _map_tile_mask)
+#define TILE_ASSERT(x) assert(TILE_MASK(x) == (x));
+
+typedef struct Tile {
+ byte type_height;
+ byte m1;
+ uint16 m2;
+ byte m3;
+ byte m4;
+ byte m5;
+ byte extra;
+} Tile;
+
+extern Tile* _m;
+
+void AllocateMap(uint size_x, uint size_y);
+
+// binary logarithm of the map size, try to avoid using this one
+static inline uint MapLogX(void) { return _map_log_x; }
+/* The size of the map */
+static inline uint MapSizeX(void) { return _map_size_x; }
+static inline uint MapSizeY(void) { return _map_size_y; }
+/* The maximum coordinates */
+static inline uint MapMaxX(void) { return _map_size_x - 1; }
+static inline uint MapMaxY(void) { return _map_size_y - 1; }
+/* The number of tiles in the map */
+static inline uint MapSize(void) { return _map_size; }
+
+// Scale a number relative to the map size
+uint ScaleByMapSize(uint); // Scale relative to the number of tiles
+uint ScaleByMapSize1D(uint); // Scale relative to the circumference of the map
+
+typedef uint32 TileIndex;
+typedef int32 TileIndexDiff;
+
+static inline TileIndex TileXY(uint x, uint y)
+{
+ return (y * MapSizeX()) + x;
+}
+
+static inline TileIndexDiff TileDiffXY(int x, int y)
+{
+ // Multiplication gives much better optimization on MSVC than shifting.
+ // 0 << shift isn't optimized to 0 properly.
+ // Typically x and y are constants, and then this doesn't result
+ // in any actual multiplication in the assembly code..
+ return (y * MapSizeX()) + x;
+}
+
+static inline TileIndex TileVirtXY(uint x, uint y)
+{
+ return (y >> 4 << MapLogX()) + (x >> 4);
+}
+
+typedef byte Owner;
+enum Owners {
+ OWNER_TOWN = 0x0F, // a town owns the tile
+ OWNER_NONE = 0x10, // nobody owns the tile
+ OWNER_WATER = 0x11, // "water" owns the tile
+ OWNER_END = 0x12,
+};
+
+enum {
+ INVALID_TILE = (TileIndex)-1
+};
+
+enum {
+ TILE_SIZE = 16, /* Tiles are 16x16 "units" in size */
+ TILE_PIXELS = 32, /* a tile is 32x32 pixels */
+ TILE_HEIGHT = 8, /* The standard height-difference between tiles on two levels is 8 (z-diff 8) */
+};
+
+
+static inline uint TileX(TileIndex tile)
+{
+ return tile & MapMaxX();
+}
+
+static inline uint TileY(TileIndex tile)
+{
+ return tile >> MapLogX();
+}
+
+
+typedef struct TileIndexDiffC {
+ int16 x;
+ int16 y;
+} TileIndexDiffC;
+
+static inline TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc)
+{
+ return (tidc.y << MapLogX()) + tidc.x;
+}
+
+
+#ifndef _DEBUG
+ #define TILE_ADD(x,y) ((x) + (y))
+#else
+ extern TileIndex TileAdd(TileIndex tile, TileIndexDiff add,
+ const char *exp, const char *file, int line);
+ #define TILE_ADD(x, y) (TileAdd((x), (y), #x " + " #y, __FILE__, __LINE__))
+#endif
+
+#define TILE_ADDXY(tile, x, y) TILE_ADD(tile, TileDiffXY(x, y))
+
+uint TileAddWrap(TileIndex tile, int addx, int addy);
+
+static inline TileIndexDiffC TileIndexDiffCByDiagDir(uint dir) {
+ extern const TileIndexDiffC _tileoffs_by_diagdir[4];
+
+ assert(dir < lengthof(_tileoffs_by_diagdir));
+ return _tileoffs_by_diagdir[dir];
+}
+
+/* Returns tile + the diff given in diff. If the result tile would end up
+ * outside of the map, INVALID_TILE is returned instead.
+ */
+static inline TileIndex AddTileIndexDiffCWrap(TileIndex tile, TileIndexDiffC diff) {
+ int x = TileX(tile) + diff.x;
+ int y = TileY(tile) + diff.y;
+ if (x < 0 || y < 0 || x > (int)MapMaxX() || y > (int)MapMaxY())
+ return INVALID_TILE;
+ else
+ return TileXY(x, y);
+}
+
+// Functions to calculate distances
+uint DistanceManhattan(TileIndex, TileIndex); // also known as L1-Norm. Is the shortest distance one could go over diagonal tracks (or roads)
+uint DistanceSquare(TileIndex, TileIndex); // euclidian- or L2-Norm squared
+uint DistanceMax(TileIndex, TileIndex); // also known as L-Infinity-Norm
+uint DistanceMaxPlusManhattan(TileIndex, TileIndex); // Max + Manhattan
+uint DistanceFromEdge(TileIndex); // shortest distance from any edge of the map
+
+
+#define BEGIN_TILE_LOOP(var,w,h,tile) \
+ { \
+ int h_cur = h; \
+ uint var = tile; \
+ do { \
+ int w_cur = w; \
+ do {
+
+#define END_TILE_LOOP(var,w,h,tile) \
+ } while (++var, --w_cur != 0); \
+ } while (var += TileDiffXY(0, 1) - (w), --h_cur != 0); \
+ }
+
+static inline TileIndexDiff TileOffsByDiagDir(uint dir)
+{
+ extern const TileIndexDiffC _tileoffs_by_diagdir[4];
+
+ assert(dir < lengthof(_tileoffs_by_diagdir));
+ return ToTileIndexDiff(_tileoffs_by_diagdir[dir]);
+}
+
+static inline TileIndexDiff TileOffsByDir(uint dir)
+{
+ extern const TileIndexDiffC _tileoffs_by_dir[8];
+
+ assert(dir < lengthof(_tileoffs_by_dir));
+ return ToTileIndexDiff(_tileoffs_by_dir[dir]);
+}
+
+typedef bool TestTileOnSearchProc(TileIndex tile, uint32 data);
+bool CircularTileSearch(TileIndex tile, uint size, TestTileOnSearchProc proc, uint32 data);
+
+/* Approximation of the length of a straight track, relative to a diagonal
+ * track (ie the size of a tile side). #defined instead of const so it can
+ * stay integer. (no runtime float operations) Is this needed?
+ * Watch out! There are _no_ brackets around here, to prevent intermediate
+ * rounding! Be careful when using this!
+ * This value should be sqrt(2)/2 ~ 0.7071 */
+#define STRAIGHT_TRACK_LENGTH 7071/10000
+
+#endif /* MAP_H */
diff --git a/src/masm64.rules b/src/masm64.rules
new file mode 100644
index 000000000..8444fa3f6
--- /dev/null
+++ b/src/masm64.rules
@@ -0,0 +1,266 @@
+<?xml version="1.0" encoding="utf-8"?>
+<VisualStudioToolFile
+ Name="Microsoft Macro Assembler 64"
+ Version="8.00"
+ >
+ <Rules>
+ <CustomBuildRule
+ Name="MASM AMD64"
+ DisplayName="Microsoft Macro Assembler for AMD64"
+ CommandLine="ml64.exe /c [AllOptions] [AdditionalOptions] /Ta[inputs]"
+ Outputs="[$ObjectFileName]"
+ FileExtensions="*.asm"
+ ExecutionDescription="Assembling..."
+ >
+ <Properties>
+ <BooleanProperty
+ Name="NoLogo"
+ DisplayName="Suppress Startup Banner"
+ Description="Suppress the display of the startup banner and information messages. (/nologo)"
+ HelpURL="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vclrfml.asp"
+ Switch="/nologo"
+ DefaultValue="true"
+ />
+ <StringProperty
+ Name="ObjectFileName"
+ DisplayName="Object File Name"
+ PropertyPageName="Object File"
+ Description="Specifies the name of the output object file. (/Fo:[file])"
+ HelpURL="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vclrfml.asp"
+ Switch="/Fo&quot;[value]&quot;"
+ DefaultValue="$(IntDir)\$(InputName).obj"
+ />
+ <BooleanProperty
+ Name="PreserveIdentifierCase"
+ DisplayName="Preserve Identifier Case"
+ PropertyPageName="Identifiers"
+ Description="Preserves case of all user identifiers. (/Cp)"
+ HelpURL="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vclrfml.asp"
+ Switch="/Cp"
+ />
+ <BooleanProperty
+ Name="PreservePublicAndExternSymbolCase"
+ DisplayName="Preserve Public and Extern Symbol Case"
+ PropertyPageName="Identifiers"
+ Description="Preserves case in public and extern symbols. (/Cx)"
+ HelpURL="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vclrfml.asp"
+ Switch="/Cx"
+ />
+ <StringProperty
+ Name="PreprocessorDefinitions"
+ DisplayName="Preprocessor Definitions"
+ Description="Defines a text macro with the given name. (/D[symbol])"
+ HelpURL="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vclrfml.asp"
+ Switch="/D&quot;[value]&quot;"
+ Delimited="true"
+ Inheritable="true"
+ />
+ <BooleanProperty
+ Name="GeneratePreprocessedSourceListing"
+ DisplayName="Generate Preprocessed Source Listing"
+ PropertyPageName="Listing File"
+ Description="Generates a preprocessed source listing to the Output Window. (/EP)"
+ HelpURL="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vclrfml.asp"
+ Switch="/EP"
+ />
+ <StringProperty
+ Name="AssembledCodeListingFile"
+ DisplayName="Assembled Code Listing File"
+ PropertyPageName="Listing File"
+ Description="Generates an assembled code listing file. (/Fl[file])"
+ HelpURL="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vclrfml.asp"
+ Switch="/Fl&quot;[value]&quot;"
+ />
+ <StringProperty
+ Name="SourceBrowserFile"
+ DisplayName="Source Browser File"
+ PropertyPageName="Source Browser File"
+ Description="Generates a source browser .sbr file. (/Fr[file])"
+ HelpURL="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vclrfml.asp"
+ Switch="/Fr&quot;[value]&quot;"
+ />
+ <StringProperty
+ Name="ExtendedSourceBrowserFile"
+ DisplayName="Extended Source Browser File"
+ PropertyPageName="Source Browser File"
+ Description="Generates an extended form of a source browser .sbr file. (/FR[file])"
+ HelpURL="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vclrfml.asp"
+ Switch="/FR&quot;[value]&quot;"
+ />
+ <StringProperty
+ Name="IncludePaths"
+ DisplayName="Include Paths"
+ Description="Sets path for include file. A maximum of 10 /I options is allowed. (/I [path])"
+ HelpURL="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vclrfml.asp"
+ Switch="/I &quot;[value]&quot;"
+ Delimited="true"
+ Inheritable="true"
+ />
+ <BooleanProperty
+ Name="ListAllAvailableInformation"
+ DisplayName="List All Available Information"
+ PropertyPageName="Listing File"
+ Description="Turns on listing of all available information. (/Sa)"
+ HelpURL="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vclrfml.asp"
+ Switch="/Sa"
+ />
+ <BooleanProperty
+ Name="AddInstructionTimings"
+ DisplayName="Add Instruction Timings"
+ PropertyPageName="Listing File"
+ Description="Adds instruction timings to listing file. (/Sc)"
+ HelpURL="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vclrfml.asp"
+ Switch="/Sc"
+ />
+ <BooleanProperty
+ Name="AddFirstPassListing"
+ DisplayName="Add First Pass Listing"
+ PropertyPageName="Listing File"
+ Description="Adds first-pass listing to listing file. (/Sf)"
+ HelpURL="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vclrfml.asp"
+ Switch="/Sf"
+ />
+ <IntegerProperty
+ Name="SourceListingLineWidth"
+ DisplayName="Source Listing Line Width"
+ PropertyPageName="Listing File"
+ Description="Sets the line width of source listing in characters per line. Range is 60 to 255 or 0. Default is 0. Same as PAGE width. (/Sl [width])"
+ HelpURL="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vclrfml.asp"
+ Switch="/Sl [value]"
+ />
+ <BooleanProperty
+ Name="DisableSymbolTable"
+ DisplayName="Disable Symbol Table"
+ PropertyPageName="Listing File"
+ Description="Turns off symbol table when producing a listing. (/Sn)"
+ HelpURL="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vclrfml.asp"
+ Switch="/Sn"
+ />
+ <IntegerProperty
+ Name="SourceListingPageLength"
+ DisplayName="Source Listing Page Length"
+ PropertyPageName="Listing File"
+ Description="Sets the page length of source listing in lines per page. Range is 10 to 255 or 0. Default is 0. Same as PAGE length. (/Sp [length])"
+ HelpURL="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vclrfml.asp"
+ Switch="/Sp [value]"
+ />
+ <StringProperty
+ Name="SourceListingSubTitle"
+ DisplayName="Source Listing Subtitle"
+ PropertyPageName="Listing File"
+ Description="Specifies subtitle text for source listing. Same as SUBTITLE text. (/Ss [subtitle])"
+ HelpURL="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vclrfml.asp"
+ Switch="/Ss [value]"
+ />
+ <StringProperty
+ Name="SourceListingTitle"
+ DisplayName="Source Listing Title"
+ PropertyPageName="Listing File"
+ Description="Specifies title for source listing. Same as TITLE text. (/St [title])"
+ HelpURL="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vclrfml.asp"
+ Switch="/St [value]"
+ />
+ <BooleanProperty
+ Name="EnableFalseConditionalsInListing"
+ DisplayName="Enable False Conditionals In Listing"
+ PropertyPageName="Listing File"
+ Description="Turns on false conditionals in listing. (/Sx)"
+ HelpURL="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vclrfml.asp"
+ Switch="/Sx"
+ />
+ <EnumProperty
+ Name="WarningLevel"
+ DisplayName="Warning Level"
+ Description="Sets the warning level, where level = 0, 1, 2, or 3. (/W0, /W1, /W2, /W3)"
+ HelpURL="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vclrfml.asp"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch="/W0"
+ DisplayName="Warning Level 0 (/W0)"
+ />
+ <EnumValue
+ Value="1"
+ Switch="/W1"
+ DisplayName="Warning Level 1 (/W1)"
+ />
+ <EnumValue
+ Value="2"
+ Switch="/W2"
+ DisplayName="Warning Level 2 (/W2)"
+ />
+ <EnumValue
+ Value="3"
+ Switch="/W3"
+ DisplayName="Warning Level 3 (/W3)"
+ />
+ </Values>
+ </EnumProperty>
+ <BooleanProperty
+ Name="TreatWarningsAsErrors"
+ DisplayName="Treat Warnings As Errors"
+ Description="Returns an error code if warnings are generated. (/WX)"
+ HelpURL="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vclrfml.asp"
+ Switch="/WX"
+ />
+ <BooleanProperty
+ Name="GenerateLineInformation"
+ DisplayName="Generate Line Information"
+ PropertyPageName="Object File"
+ Description="Generates line-number information in object file. (/Zd)"
+ HelpURL="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vclrfml.asp"
+ Switch="/Zd"
+ />
+ <BooleanProperty
+ Name="MakeAllSymbolsPublic"
+ DisplayName="Make All Symbols Public"
+ PropertyPageName="Object File"
+ Description="Makes all symbols public. (/Zf)"
+ HelpURL="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vclrfml.asp"
+ Switch="/Zf"
+ />
+ <BooleanProperty
+ Name="GenerateCodeViewInformation"
+ DisplayName="Generate CodeView Information"
+ PropertyPageName="Object File"
+ Description="Generates CodeView information in object file. (/Zi)"
+ HelpURL="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vclrfml.asp"
+ Switch="/Zi"
+ />
+ <EnumProperty
+ Name="PackAlignmentBoundary"
+ DisplayName="Pack Alignment Boundary"
+ PropertyPageName="Advanced"
+ Description="Packs structures on the specified byte boundary. The alignment can be 1, 2, or 4. (/Zp1, /Zp2, /Zp4)"
+ HelpURL="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vclrfml.asp"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch="/Zp1"
+ DisplayName="One Byte Boundary (/Zp1)"
+ />
+ <EnumValue
+ Value="1"
+ Switch="/Zp2"
+ DisplayName="Two Byte Boundary (/Zp2)"
+ />
+ <EnumValue
+ Value="2"
+ Switch="/Zp4"
+ DisplayName="Four Byte Boundary (/Zp4)"
+ />
+ </Values>
+ </EnumProperty>
+ <BooleanProperty
+ Name="PerformSyntaxCheckOnly"
+ DisplayName="Perform Syntax Check Only"
+ Description="Performs a syntax check only. (/Zs)"
+ HelpURL="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vclrfml.asp"
+ Switch="/Zs"
+ />
+ </Properties>
+ </CustomBuildRule>
+ </Rules>
+</VisualStudioToolFile>
diff --git a/src/md5.c b/src/md5.c
new file mode 100644
index 000000000..59728e78a
--- /dev/null
+++ b/src/md5.c
@@ -0,0 +1,384 @@
+/* $Id$ */
+
+/*
+ Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ L. Peter Deutsch
+ ghost@aladdin.com
+
+ */
+/* $Id$ */
+/*
+ Independent implementation of MD5 (RFC 1321).
+
+ This code implements the MD5 Algorithm defined in RFC 1321, whose
+ text is available at
+ http://www.ietf.org/rfc/rfc1321.txt
+ The code is derived from the text of the RFC, including the test suite
+ (section A.5) but excluding the rest of Appendix A. It does not include
+ any code or documentation that is identified in the RFC as being
+ copyrighted.
+
+ The original and principal author of md5.c is L. Peter Deutsch
+ <ghost@aladdin.com>. Other authors are noted in the change history
+ that follows (in reverse chronological order):
+
+ 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
+ either statically or dynamically; added missing #include <string.h>
+ in library.
+ 2002-03-11 lpd Corrected argument list for main(), and added int return
+ type, in test program and T value program.
+ 2002-02-21 lpd Added missing #include <stdio.h> in test program.
+ 2000-07-03 lpd Patched to eliminate warnings about "constant is
+ unsigned in ANSI C, signed in traditional"; made test program
+ self-checking.
+ 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+ 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
+ 1999-05-03 lpd Original version.
+ */
+
+#include "stdafx.h"
+#include "md5.h"
+#include <string.h>
+
+#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
+#if defined(TTD_BIG_ENDIAN)
+# define BYTE_ORDER 1
+#else
+# define BYTE_ORDER -1
+#endif
+
+#define T_MASK ((md5_word_t)~0)
+#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
+#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
+#define T3 0x242070db
+#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
+#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
+#define T6 0x4787c62a
+#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
+#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
+#define T9 0x698098d8
+#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
+#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
+#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
+#define T13 0x6b901122
+#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
+#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
+#define T16 0x49b40821
+#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
+#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
+#define T19 0x265e5a51
+#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
+#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
+#define T22 0x02441453
+#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
+#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
+#define T25 0x21e1cde6
+#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
+#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
+#define T28 0x455a14ed
+#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
+#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
+#define T31 0x676f02d9
+#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
+#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
+#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
+#define T35 0x6d9d6122
+#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
+#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
+#define T38 0x4bdecfa9
+#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
+#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
+#define T41 0x289b7ec6
+#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
+#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
+#define T44 0x04881d05
+#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
+#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
+#define T47 0x1fa27cf8
+#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
+#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
+#define T50 0x432aff97
+#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
+#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
+#define T53 0x655b59c3
+#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
+#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
+#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
+#define T57 0x6fa87e4f
+#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
+#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
+#define T60 0x4e0811a1
+#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
+#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
+#define T63 0x2ad7d2bb
+#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
+
+
+static void
+md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
+{
+ md5_word_t
+ a = pms->abcd[0], b = pms->abcd[1],
+ c = pms->abcd[2], d = pms->abcd[3];
+ md5_word_t t;
+#if BYTE_ORDER > 0
+ /* Define storage only for big-endian CPUs. */
+ md5_word_t X[16];
+#else
+ /* Define storage for little-endian or both types of CPUs. */
+ md5_word_t xbuf[16];
+ const md5_word_t *X;
+#endif
+
+ {
+#if BYTE_ORDER == 0
+ /*
+ * Determine dynamically whether this is a big-endian or
+ * little-endian machine, since we can use a more efficient
+ * algorithm on the latter.
+ */
+ static const int w = 1;
+
+ if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
+#endif
+#if BYTE_ORDER <= 0 /* little-endian */
+ {
+ /*
+ * On little-endian machines, we can process properly aligned
+ * data without copying it.
+ */
+ if (!((data - (const md5_byte_t *)0) & 3)) {
+ /* data are properly aligned */
+ X = (const md5_word_t *)data;
+ } else {
+ /* not aligned */
+ memcpy(xbuf, data, 64);
+ X = xbuf;
+ }
+ }
+#endif
+#if BYTE_ORDER == 0
+ else /* dynamic big-endian */
+#endif
+#if BYTE_ORDER >= 0 /* big-endian */
+ {
+ /*
+ * On big-endian machines, we must arrange the bytes in the
+ * right order.
+ */
+ const md5_byte_t *xp = data;
+ int i;
+
+# if BYTE_ORDER == 0
+ X = xbuf; /* (dynamic only) */
+# else
+# define xbuf X /* (static only) */
+# endif
+ for (i = 0; i < 16; ++i, xp += 4)
+ xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
+ }
+#endif
+ }
+
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
+
+ /* Round 1. */
+ /* Let [abcd k s i] denote the operation
+ a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
+#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + F(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 0, 7, T1);
+ SET(d, a, b, c, 1, 12, T2);
+ SET(c, d, a, b, 2, 17, T3);
+ SET(b, c, d, a, 3, 22, T4);
+ SET(a, b, c, d, 4, 7, T5);
+ SET(d, a, b, c, 5, 12, T6);
+ SET(c, d, a, b, 6, 17, T7);
+ SET(b, c, d, a, 7, 22, T8);
+ SET(a, b, c, d, 8, 7, T9);
+ SET(d, a, b, c, 9, 12, T10);
+ SET(c, d, a, b, 10, 17, T11);
+ SET(b, c, d, a, 11, 22, T12);
+ SET(a, b, c, d, 12, 7, T13);
+ SET(d, a, b, c, 13, 12, T14);
+ SET(c, d, a, b, 14, 17, T15);
+ SET(b, c, d, a, 15, 22, T16);
+#undef SET
+
+ /* Round 2. */
+ /* Let [abcd k s i] denote the operation
+ a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
+#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + G(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 1, 5, T17);
+ SET(d, a, b, c, 6, 9, T18);
+ SET(c, d, a, b, 11, 14, T19);
+ SET(b, c, d, a, 0, 20, T20);
+ SET(a, b, c, d, 5, 5, T21);
+ SET(d, a, b, c, 10, 9, T22);
+ SET(c, d, a, b, 15, 14, T23);
+ SET(b, c, d, a, 4, 20, T24);
+ SET(a, b, c, d, 9, 5, T25);
+ SET(d, a, b, c, 14, 9, T26);
+ SET(c, d, a, b, 3, 14, T27);
+ SET(b, c, d, a, 8, 20, T28);
+ SET(a, b, c, d, 13, 5, T29);
+ SET(d, a, b, c, 2, 9, T30);
+ SET(c, d, a, b, 7, 14, T31);
+ SET(b, c, d, a, 12, 20, T32);
+#undef SET
+
+ /* Round 3. */
+ /* Let [abcd k s t] denote the operation
+ a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + H(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 5, 4, T33);
+ SET(d, a, b, c, 8, 11, T34);
+ SET(c, d, a, b, 11, 16, T35);
+ SET(b, c, d, a, 14, 23, T36);
+ SET(a, b, c, d, 1, 4, T37);
+ SET(d, a, b, c, 4, 11, T38);
+ SET(c, d, a, b, 7, 16, T39);
+ SET(b, c, d, a, 10, 23, T40);
+ SET(a, b, c, d, 13, 4, T41);
+ SET(d, a, b, c, 0, 11, T42);
+ SET(c, d, a, b, 3, 16, T43);
+ SET(b, c, d, a, 6, 23, T44);
+ SET(a, b, c, d, 9, 4, T45);
+ SET(d, a, b, c, 12, 11, T46);
+ SET(c, d, a, b, 15, 16, T47);
+ SET(b, c, d, a, 2, 23, T48);
+#undef SET
+
+ /* Round 4. */
+ /* Let [abcd k s t] denote the operation
+ a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
+#define I(x, y, z) ((y) ^ ((x) | ~(z)))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + I(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 0, 6, T49);
+ SET(d, a, b, c, 7, 10, T50);
+ SET(c, d, a, b, 14, 15, T51);
+ SET(b, c, d, a, 5, 21, T52);
+ SET(a, b, c, d, 12, 6, T53);
+ SET(d, a, b, c, 3, 10, T54);
+ SET(c, d, a, b, 10, 15, T55);
+ SET(b, c, d, a, 1, 21, T56);
+ SET(a, b, c, d, 8, 6, T57);
+ SET(d, a, b, c, 15, 10, T58);
+ SET(c, d, a, b, 6, 15, T59);
+ SET(b, c, d, a, 13, 21, T60);
+ SET(a, b, c, d, 4, 6, T61);
+ SET(d, a, b, c, 11, 10, T62);
+ SET(c, d, a, b, 2, 15, T63);
+ SET(b, c, d, a, 9, 21, T64);
+#undef SET
+
+ /* Then perform the following additions. (That is increment each
+ of the four registers by the value it had before this block
+ was started.) */
+ pms->abcd[0] += a;
+ pms->abcd[1] += b;
+ pms->abcd[2] += c;
+ pms->abcd[3] += d;
+}
+
+void
+md5_init(md5_state_t *pms)
+{
+ pms->count[0] = pms->count[1] = 0;
+ pms->abcd[0] = 0x67452301;
+ pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
+ pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
+ pms->abcd[3] = 0x10325476;
+}
+
+void
+md5_append(md5_state_t *pms, const void *data, size_t nbytes)
+{
+ const md5_byte_t *p = (const md5_byte_t *)data;
+ size_t left = nbytes;
+ size_t offset = (pms->count[0] >> 3) & 63;
+ md5_word_t nbits = (md5_word_t)(nbytes << 3);
+
+ if (nbytes <= 0)
+ return;
+
+ /* Update the message length. */
+ pms->count[1] += (md5_word_t)(nbytes >> 29);
+ pms->count[0] += nbits;
+ if (pms->count[0] < nbits)
+ pms->count[1]++;
+
+ /* Process an initial partial block. */
+ if (offset) {
+ size_t copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
+
+ memcpy(pms->buf + offset, p, copy);
+ if (offset + copy < 64)
+ return;
+ p += copy;
+ left -= copy;
+ md5_process(pms, pms->buf);
+ }
+
+ /* Process full blocks. */
+ for (; left >= 64; p += 64, left -= 64)
+ md5_process(pms, p);
+
+ /* Process a final partial block. */
+ if (left)
+ memcpy(pms->buf, p, left);
+}
+
+void
+md5_finish(md5_state_t *pms, md5_byte_t digest[16])
+{
+ static const md5_byte_t pad[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+ md5_byte_t data[8];
+ int i;
+
+ /* Save the length before padding. */
+ for (i = 0; i < 8; ++i)
+ data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
+ /* Pad to 56 bytes mod 64. */
+ md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
+ /* Append the length. */
+ md5_append(pms, data, 8);
+ for (i = 0; i < 16; ++i)
+ digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
+}
diff --git a/src/md5.h b/src/md5.h
new file mode 100644
index 000000000..6e1f3044b
--- /dev/null
+++ b/src/md5.h
@@ -0,0 +1,93 @@
+/* $Id$ */
+
+/*
+ Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ L. Peter Deutsch
+ ghost@aladdin.com
+
+ */
+/* $Id$ */
+/*
+ Independent implementation of MD5 (RFC 1321).
+
+ This code implements the MD5 Algorithm defined in RFC 1321, whose
+ text is available at
+ http://www.ietf.org/rfc/rfc1321.txt
+ The code is derived from the text of the RFC, including the test suite
+ (section A.5) but excluding the rest of Appendix A. It does not include
+ any code or documentation that is identified in the RFC as being
+ copyrighted.
+
+ The original and principal author of md5.h is L. Peter Deutsch
+ <ghost@aladdin.com>. Other authors are noted in the change history
+ that follows (in reverse chronological order):
+
+ 2002-04-13 lpd Removed support for non-ANSI compilers; removed
+ references to Ghostscript; clarified derivation from RFC 1321;
+ now handles byte order either statically or dynamically.
+ 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+ 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
+ added conditionalization for C++ compilation from Martin
+ Purschke <purschke@bnl.gov>.
+ 1999-05-03 lpd Original version.
+ */
+
+#ifndef MD5_INCLUDED
+#define MD5_INCLUDED
+
+/*
+ * This package supports both compile-time and run-time determination of CPU
+ * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
+ * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
+ * defined as non-zero, the code will be compiled to run only on big-endian
+ * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
+ * run on either big- or little-endian CPUs, but will run slightly less
+ * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
+ */
+
+typedef unsigned char md5_byte_t; /* 8-bit byte */
+typedef unsigned int md5_word_t; /* 32-bit word */
+
+/* Define the state of the MD5 Algorithm. */
+typedef struct md5_state_s {
+ md5_word_t count[2]; /* message length in bits, lsw first */
+ md5_word_t abcd[4]; /* digest buffer */
+ md5_byte_t buf[64]; /* accumulate block */
+} md5_state_t;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* Initialize the algorithm. */
+void md5_init(md5_state_t *pms);
+
+/* Append a string to the message. */
+void md5_append(md5_state_t *pms, const void *data, size_t nbytes);
+
+/* Finish the message and return the digest. */
+void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
+
+#ifdef __cplusplus
+} /* end extern "C" */
+#endif
+
+#endif /* MD5_INCLUDED */
diff --git a/src/mersenne.c b/src/mersenne.c
new file mode 100644
index 000000000..bc4cb949a
--- /dev/null
+++ b/src/mersenne.c
@@ -0,0 +1,74 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+
+#ifdef MERSENNE_TWISTER
+
+// Source code for Mersenne Twister.
+// A Random number generator with much higher quality random numbers.
+
+#define N (624) // length of _mt_state vector
+#define M (397) // a period parameter
+#define K (0x9908B0DFU) // a magic constant
+#define hiBit(u) ((u) & 0x80000000U) // mask all but highest bit of u
+#define loBit(u) ((u) & 0x00000001U) // mask all but lowest bit of u
+#define loBits(u) ((u) & 0x7FFFFFFFU) // mask the highest bit of u
+#define mixBits(u, v) (hiBit(u)|loBits(v)) // move hi bit of u to hi bit of v
+
+static uint32 _mt_state[N+1]; // _mt_state vector + 1 extra to not violate ANSI C
+static uint32 *_mt_next; // _mt_next random value is computed from here
+static int _mt_left = -1; // can *_mt_next++ this many times before reloading
+
+void SeedMT(uint32 seed)
+{
+ register uint32 x = (seed | 1U) & 0xFFFFFFFFU, *s = _mt_state;
+ register int j;
+
+ for (_mt_left=0, *s++=x, j=N; --j;
+ *s++ = (x*=69069U) & 0xFFFFFFFFU);
+ }
+
+
+static uint32 ReloadMT(void)
+ {
+ register uint32 *p0=_mt_state, *p2=_mt_state+2, *pM=_mt_state+M, s0, s1;
+ register int j;
+
+ if (_mt_left < -1)
+ SeedMT(4357U);
+
+ _mt_left=N-1, _mt_next=_mt_state+1;
+
+ for (s0=_mt_state[0], s1=_mt_state[1], j=N-M+1; --j; s0=s1, s1=*p2++)
+ *p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
+
+ for (pM=_mt_state, j=M; --j; s0=s1, s1=*p2++)
+ *p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
+
+ s1=_mt_state[0], *p0 = *pM ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
+ s1 ^= (s1 >> 11);
+ s1 ^= (s1 << 7) & 0x9D2C5680U;
+ s1 ^= (s1 << 15) & 0xEFC60000U;
+ return(s1 ^ (s1 >> 18));
+ }
+
+
+uint32 RandomMT(void)
+{
+ uint32 y;
+
+ if (--_mt_left < 0)
+ return ReloadMT();
+
+ y = *_mt_next++;
+ y ^= (y >> 11);
+ y ^= (y << 7) & 0x9D2C5680U;
+ y ^= (y << 15) & 0xEFC60000U;
+ return y ^ (y >> 18);
+}
+#else
+
+void SeedMT(uint32 seed) {}
+
+#endif /* MERSENNE_TWISTER */
diff --git a/src/minilzo.c b/src/minilzo.c
new file mode 100644
index 000000000..ab26b0a02
--- /dev/null
+++ b/src/minilzo.c
@@ -0,0 +1,1971 @@
+/* $Id$ */
+
+/* minilzo.c -- mini subset of the LZO real-time data compression library
+
+ This file is part of the LZO real-time data compression library.
+
+ Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
+ All Rights Reserved.
+
+ The LZO library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ The LZO library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the LZO library; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Markus F.X.J. Oberhumer
+ <markus@oberhumer.com>
+ http://www.oberhumer.com/opensource/lzo/
+ */
+
+/*
+ * NOTE:
+ * the full LZO package can be found at
+ * http://www.oberhumer.com/opensource/lzo/
+ */
+
+#define LZO_DISABLE_CHECKS
+#define LZO1X
+
+#define __LZO_IN_MINILZO
+#define LZO_BUILD
+
+#ifdef MINILZO_HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#undef LZO_HAVE_CONFIG_H
+#include "minilzo.h"
+
+#if !defined(MINILZO_VERSION) || (MINILZO_VERSION != 0x1080)
+# error "version mismatch in miniLZO source files"
+#endif
+
+#ifdef MINILZO_HAVE_CONFIG_H
+# define LZO_HAVE_CONFIG_H
+#endif
+
+#if !defined(LZO_NO_SYS_TYPES_H)
+# include <sys/types.h>
+#endif
+#include <stdio.h>
+
+#ifndef __LZO_CONF_H
+#define __LZO_CONF_H
+
+#if defined(__BOUNDS_CHECKING_ON)
+# include <unchecked.h>
+#else
+# define BOUNDS_CHECKING_OFF_DURING(stmt) stmt
+# define BOUNDS_CHECKING_OFF_IN_EXPR(expr) (expr)
+#endif
+
+#if !defined(LZO_HAVE_CONFIG_H)
+# include <stddef.h>
+# include <string.h>
+# if !defined(NO_STDLIB_H)
+# include <stdlib.h>
+# endif
+# define HAVE_MEMCMP
+# define HAVE_MEMCPY
+# define HAVE_MEMMOVE
+# define HAVE_MEMSET
+#else
+# include <sys/types.h>
+# if defined(HAVE_STDDEF_H)
+# include <stddef.h>
+# endif
+# if defined(STDC_HEADERS)
+# include <string.h>
+# include <stdlib.h>
+# endif
+#endif
+
+#if defined(__LZO_DOS16) || defined(__LZO_WIN16)
+# define HAVE_MALLOC_H
+# define HAVE_HALLOC
+#endif
+
+#undef NDEBUG
+#if !defined(LZO_DEBUG)
+# define NDEBUG
+#endif
+#if defined(LZO_DEBUG) || !defined(NDEBUG)
+# if !defined(NO_STDIO_H)
+# include <stdio.h>
+# endif
+#endif
+#include <assert.h>
+
+#if !defined(LZO_COMPILE_TIME_ASSERT)
+# define LZO_COMPILE_TIME_ASSERT(expr) \
+ { typedef int __lzo_compile_time_assert_fail[1 - 2 * !(expr)]; }
+#endif
+
+#if !defined(LZO_UNUSED)
+# if 1
+# define LZO_UNUSED(var) ((void)&var)
+# elif 0
+# define LZO_UNUSED(var) { typedef int __lzo_unused[sizeof(var) ? 2 : 1]; }
+# else
+# define LZO_UNUSED(parm) (parm = parm)
+# endif
+#endif
+
+#if !defined(__inline__) && !defined(__GNUC__)
+# if defined(__cplusplus)
+# define __inline__ inline
+# else
+# define __inline__
+# endif
+#endif
+
+#if defined(NO_MEMCMP)
+# undef HAVE_MEMCMP
+#endif
+
+#if 0
+# define LZO_BYTE(x) ((unsigned char) (x))
+#else
+# define LZO_BYTE(x) ((unsigned char) ((x) & 0xff))
+#endif
+
+#define LZO_MAX(a,b) ((a) >= (b) ? (a) : (b))
+#define LZO_MIN(a,b) ((a) <= (b) ? (a) : (b))
+#define LZO_MAX3(a,b,c) ((a) >= (b) ? LZO_MAX(a,c) : LZO_MAX(b,c))
+#define LZO_MIN3(a,b,c) ((a) <= (b) ? LZO_MIN(a,c) : LZO_MIN(b,c))
+
+#define lzo_sizeof(type) ((lzo_uint) (sizeof(type)))
+
+#define LZO_HIGH(array) ((lzo_uint) (sizeof(array)/sizeof(*(array))))
+
+#define LZO_SIZE(bits) (1u << (bits))
+#define LZO_MASK(bits) (LZO_SIZE(bits) - 1)
+
+#define LZO_LSIZE(bits) (1ul << (bits))
+#define LZO_LMASK(bits) (LZO_LSIZE(bits) - 1)
+
+#define LZO_USIZE(bits) ((lzo_uint) 1 << (bits))
+#define LZO_UMASK(bits) (LZO_USIZE(bits) - 1)
+
+#define LZO_STYPE_MAX(b) (((1l << (8*(b)-2)) - 1l) + (1l << (8*(b)-2)))
+#define LZO_UTYPE_MAX(b) (((1ul << (8*(b)-1)) - 1ul) + (1ul << (8*(b)-1)))
+
+#if !defined(SIZEOF_UNSIGNED)
+# if (UINT_MAX == 0xffff)
+# define SIZEOF_UNSIGNED 2
+# elif (UINT_MAX == LZO_0xffffffffL)
+# define SIZEOF_UNSIGNED 4
+# elif (UINT_MAX >= LZO_0xffffffffL)
+# define SIZEOF_UNSIGNED 8
+# else
+# error "SIZEOF_UNSIGNED"
+# endif
+#endif
+
+#if !defined(SIZEOF_UNSIGNED_LONG)
+# if (ULONG_MAX == LZO_0xffffffffL)
+# define SIZEOF_UNSIGNED_LONG 4
+# elif (ULONG_MAX >= LZO_0xffffffffL)
+# define SIZEOF_UNSIGNED_LONG 8
+# else
+# error "SIZEOF_UNSIGNED_LONG"
+# endif
+#endif
+
+#if !defined(SIZEOF_SIZE_T)
+# define SIZEOF_SIZE_T SIZEOF_UNSIGNED
+#endif
+#if !defined(SIZE_T_MAX)
+# define SIZE_T_MAX LZO_UTYPE_MAX(SIZEOF_SIZE_T)
+#endif
+
+#if 1 && defined(__LZO_i386) && (UINT_MAX == LZO_0xffffffffL)
+# if !defined(LZO_UNALIGNED_OK_2) && (USHRT_MAX == 0xffff)
+# define LZO_UNALIGNED_OK_2
+# endif
+# if !defined(LZO_UNALIGNED_OK_4) && (LZO_UINT32_MAX == LZO_0xffffffffL)
+# define LZO_UNALIGNED_OK_4
+# endif
+#endif
+
+#if defined(LZO_UNALIGNED_OK_2) || defined(LZO_UNALIGNED_OK_4)
+# if !defined(LZO_UNALIGNED_OK)
+# define LZO_UNALIGNED_OK
+# endif
+#endif
+
+#if defined(__LZO_NO_UNALIGNED)
+# undef LZO_UNALIGNED_OK
+# undef LZO_UNALIGNED_OK_2
+# undef LZO_UNALIGNED_OK_4
+#endif
+
+#if defined(LZO_UNALIGNED_OK_2) && (USHRT_MAX != 0xffff)
+# error "LZO_UNALIGNED_OK_2 must not be defined on this system"
+#endif
+#if defined(LZO_UNALIGNED_OK_4) && (LZO_UINT32_MAX != LZO_0xffffffffL)
+# error "LZO_UNALIGNED_OK_4 must not be defined on this system"
+#endif
+
+#if defined(__LZO_NO_ALIGNED)
+# undef LZO_ALIGNED_OK_4
+#endif
+
+#if defined(LZO_ALIGNED_OK_4) && (LZO_UINT32_MAX != LZO_0xffffffffL)
+# error "LZO_ALIGNED_OK_4 must not be defined on this system"
+#endif
+
+#define LZO_LITTLE_ENDIAN 1234
+#define LZO_BIG_ENDIAN 4321
+#define LZO_PDP_ENDIAN 3412
+
+#if !defined(LZO_BYTE_ORDER)
+# if defined(MFX_BYTE_ORDER)
+# define LZO_BYTE_ORDER MFX_BYTE_ORDER
+# elif defined(__LZO_i386)
+# define LZO_BYTE_ORDER LZO_LITTLE_ENDIAN
+# elif defined(BYTE_ORDER)
+# define LZO_BYTE_ORDER BYTE_ORDER
+# elif defined(__BYTE_ORDER)
+# define LZO_BYTE_ORDER __BYTE_ORDER
+# endif
+#endif
+
+#if defined(LZO_BYTE_ORDER)
+# if (LZO_BYTE_ORDER != LZO_LITTLE_ENDIAN) && \
+ (LZO_BYTE_ORDER != LZO_BIG_ENDIAN)
+# error "invalid LZO_BYTE_ORDER"
+# endif
+#endif
+
+#if defined(LZO_UNALIGNED_OK) && !defined(LZO_BYTE_ORDER)
+# error "LZO_BYTE_ORDER is not defined"
+#endif
+
+#define LZO_OPTIMIZE_GNUC_i386_IS_BUGGY
+
+#if defined(NDEBUG) && !defined(LZO_DEBUG) && !defined(__LZO_CHECKER)
+# if defined(__GNUC__) && defined(__i386__)
+# if !defined(LZO_OPTIMIZE_GNUC_i386_IS_BUGGY)
+# define LZO_OPTIMIZE_GNUC_i386
+# endif
+# endif
+#endif
+
+__LZO_EXTERN_C int __lzo_init_done;
+__LZO_EXTERN_C const lzo_byte __lzo_copyright[];
+LZO_EXTERN(const lzo_byte *) lzo_copyright(void);
+__LZO_EXTERN_C const lzo_uint32 _lzo_crc32_table[256];
+
+#define _LZO_STRINGIZE(x) #x
+#define _LZO_MEXPAND(x) _LZO_STRINGIZE(x)
+
+#define _LZO_CONCAT2(a,b) a ## b
+#define _LZO_CONCAT3(a,b,c) a ## b ## c
+#define _LZO_CONCAT4(a,b,c,d) a ## b ## c ## d
+#define _LZO_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e
+
+#define _LZO_ECONCAT2(a,b) _LZO_CONCAT2(a,b)
+#define _LZO_ECONCAT3(a,b,c) _LZO_CONCAT3(a,b,c)
+#define _LZO_ECONCAT4(a,b,c,d) _LZO_CONCAT4(a,b,c,d)
+#define _LZO_ECONCAT5(a,b,c,d,e) _LZO_CONCAT5(a,b,c,d,e)
+
+#ifndef __LZO_PTR_H
+#define __LZO_PTR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(__LZO_DOS16) || defined(__LZO_WIN16)
+# include <dos.h>
+# if 1 && defined(__WATCOMC__)
+# include <i86.h>
+ __LZO_EXTERN_C unsigned char _HShift;
+# define __LZO_HShift _HShift
+# elif 1 && defined(_MSC_VER)
+ __LZO_EXTERN_C unsigned short __near _AHSHIFT;
+# define __LZO_HShift ((unsigned) &_AHSHIFT)
+# elif defined(__LZO_WIN16)
+# define __LZO_HShift 3
+# else
+# define __LZO_HShift 12
+# endif
+# if !defined(_FP_SEG) && defined(FP_SEG)
+# define _FP_SEG FP_SEG
+# endif
+# if !defined(_FP_OFF) && defined(FP_OFF)
+# define _FP_OFF FP_OFF
+# endif
+#endif
+
+#if !defined(lzo_ptrdiff_t)
+# if (UINT_MAX >= LZO_0xffffffffL)
+ typedef ptrdiff_t lzo_ptrdiff_t;
+# else
+ typedef long lzo_ptrdiff_t;
+# endif
+#endif
+
+#if !defined(__LZO_HAVE_PTR_T)
+# if defined(lzo_ptr_t)
+# define __LZO_HAVE_PTR_T
+# endif
+#endif
+#if !defined(__LZO_HAVE_PTR_T)
+# if defined(_WIN64)
+ typedef unsigned __int64 lzo_ptr_t;
+ typedef signed __int64 lzo_sptr_r;
+# define __LZO_HAVE_PTR_T
+# endif
+#endif
+#if !defined(__LZO_HAVE_PTR_T)
+# if defined(SIZEOF_CHAR_P) && defined(SIZEOF_UNSIGNED_LONG)
+# if (SIZEOF_CHAR_P == SIZEOF_UNSIGNED_LONG)
+ typedef unsigned long lzo_ptr_t;
+ typedef long lzo_sptr_t;
+# define __LZO_HAVE_PTR_T
+# endif
+# endif
+#endif
+#if !defined(__LZO_HAVE_PTR_T)
+# if defined(SIZEOF_CHAR_P) && defined(SIZEOF_UNSIGNED)
+# if (SIZEOF_CHAR_P == SIZEOF_UNSIGNED)
+ typedef unsigned int lzo_ptr_t;
+ typedef int lzo_sptr_t;
+# define __LZO_HAVE_PTR_T
+# endif
+# endif
+#endif
+#if !defined(__LZO_HAVE_PTR_T)
+# if defined(SIZEOF_CHAR_P) && defined(SIZEOF_UNSIGNED_SHORT)
+# if (SIZEOF_CHAR_P == SIZEOF_UNSIGNED_SHORT)
+ typedef unsigned short lzo_ptr_t;
+ typedef short lzo_sptr_t;
+# define __LZO_HAVE_PTR_T
+# endif
+# endif
+#endif
+#if !defined(__LZO_HAVE_PTR_T)
+# if defined(LZO_HAVE_CONFIG_H) || defined(SIZEOF_CHAR_P)
+# error "no suitable type for lzo_ptr_t"
+# else
+ typedef unsigned long lzo_ptr_t;
+ typedef long lzo_sptr_t;
+# define __LZO_HAVE_PTR_T
+# endif
+#endif
+
+#if defined(__LZO_DOS16) || defined(__LZO_WIN16)
+#define PTR(a) ((lzo_bytep) (a))
+#define PTR_ALIGNED_4(a) ((_FP_OFF(a) & 3) == 0)
+#define PTR_ALIGNED2_4(a,b) (((_FP_OFF(a) | _FP_OFF(b)) & 3) == 0)
+#else
+#define PTR(a) ((lzo_ptr_t) (a))
+#define PTR_LINEAR(a) PTR(a)
+#define PTR_ALIGNED_4(a) ((PTR_LINEAR(a) & 3) == 0)
+#define PTR_ALIGNED_8(a) ((PTR_LINEAR(a) & 7) == 0)
+#define PTR_ALIGNED2_4(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 3) == 0)
+#define PTR_ALIGNED2_8(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 7) == 0)
+#endif
+
+#define PTR_LT(a,b) (PTR(a) < PTR(b))
+#define PTR_GE(a,b) (PTR(a) >= PTR(b))
+#define PTR_DIFF(a,b) ((lzo_ptrdiff_t) (PTR(a) - PTR(b)))
+#define pd(a,b) ((lzo_uint) ((a)-(b)))
+
+LZO_EXTERN(lzo_ptr_t)
+__lzo_ptr_linear(const lzo_voidp ptr);
+
+typedef union
+{
+ char a_char;
+ unsigned char a_uchar;
+ short a_short;
+ unsigned short a_ushort;
+ int a_int;
+ unsigned int a_uint;
+ long a_long;
+ unsigned long a_ulong;
+ lzo_int a_lzo_int;
+ lzo_uint a_lzo_uint;
+ lzo_int32 a_lzo_int32;
+ lzo_uint32 a_lzo_uint32;
+ ptrdiff_t a_ptrdiff_t;
+ lzo_ptrdiff_t a_lzo_ptrdiff_t;
+ lzo_ptr_t a_lzo_ptr_t;
+ lzo_voidp a_lzo_voidp;
+ void * a_void_p;
+ lzo_bytep a_lzo_bytep;
+ lzo_bytepp a_lzo_bytepp;
+ lzo_uintp a_lzo_uintp;
+ lzo_uint * a_lzo_uint_p;
+ lzo_uint32p a_lzo_uint32p;
+ lzo_uint32 * a_lzo_uint32_p;
+ unsigned char * a_uchar_p;
+ char * a_char_p;
+}
+lzo_full_align_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#define LZO_DETERMINISTIC
+
+#define LZO_DICT_USE_PTR
+#if defined(__LZO_DOS16) || defined(__LZO_WIN16) || defined(__LZO_STRICT_16BIT)
+# undef LZO_DICT_USE_PTR
+#endif
+
+#if defined(LZO_DICT_USE_PTR)
+# define lzo_dict_t const lzo_bytep
+# define lzo_dict_p lzo_dict_t __LZO_MMODEL *
+#else
+# define lzo_dict_t lzo_uint
+# define lzo_dict_p lzo_dict_t __LZO_MMODEL *
+#endif
+
+#if !defined(lzo_moff_t)
+#define lzo_moff_t lzo_uint
+#endif
+
+#endif
+
+
+#ifndef __LZO_UTIL_H
+#define __LZO_UTIL_H
+
+#ifndef __LZO_CONF_H
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if 1 && defined(HAVE_MEMCPY)
+#if !defined(__LZO_DOS16) && !defined(__LZO_WIN16)
+
+#define MEMCPY8_DS(dest,src,len) \
+ memcpy(dest,src,len); \
+ dest += len; \
+ src += len
+
+#endif
+#endif
+
+#if 0 && !defined(MEMCPY8_DS)
+
+#define MEMCPY8_DS(dest,src,len) \
+ { do { \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ len -= 8; \
+ } while (len > 0); }
+
+#endif
+
+#if !defined(MEMCPY8_DS)
+
+#define MEMCPY8_DS(dest,src,len) \
+ { register lzo_uint __l = (len) / 8; \
+ do { \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ } while (--__l > 0); }
+
+#endif
+
+#define MEMCPY_DS(dest,src,len) \
+ do *dest++ = *src++; \
+ while (--len > 0)
+
+#define MEMMOVE_DS(dest,src,len) \
+ do *dest++ = *src++; \
+ while (--len > 0)
+
+#if 0 && defined(LZO_OPTIMIZE_GNUC_i386)
+
+#define BZERO8_PTR(s,l,n) \
+__asm__ __volatile__( \
+ "movl %0,%%eax \n" \
+ "movl %1,%%edi \n" \
+ "movl %2,%%ecx \n" \
+ "cld \n" \
+ "rep \n" \
+ "stosl %%eax,(%%edi) \n" \
+ : \
+ :"g" (0),"g" (s),"g" (n) \
+ :"eax","edi","ecx", "memory", "cc" \
+)
+
+#elif (LZO_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMSET)
+
+#if 1
+#define BZERO8_PTR(s,l,n) memset((s),0,(lzo_uint)(l)*(n))
+#else
+#define BZERO8_PTR(s,l,n) memset((lzo_voidp)(s),0,(lzo_uint)(l)*(n))
+#endif
+
+#else
+
+#define BZERO8_PTR(s,l,n) \
+ lzo_memset((lzo_voidp)(s),0,(lzo_uint)(l)*(n))
+
+#endif
+
+#if 0
+#if defined(__GNUC__) && defined(__i386__)
+
+unsigned char lzo_rotr8(unsigned char value, int shift);
+extern __inline__ unsigned char lzo_rotr8(unsigned char value, int shift)
+{
+ unsigned char result;
+
+ __asm__ __volatile__ ("movb %b1, %b0; rorb %b2, %b0"
+ : "=a"(result) : "g"(value), "c"(shift));
+ return result;
+}
+
+unsigned short lzo_rotr16(unsigned short value, int shift);
+extern __inline__ unsigned short lzo_rotr16(unsigned short value, int shift)
+{
+ unsigned short result;
+
+ __asm__ __volatile__ ("movw %b1, %b0; rorw %b2, %b0"
+ : "=a"(result) : "g"(value), "c"(shift));
+ return result;
+}
+
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+/* If you use the LZO library in a product, you *must* keep this
+ * copyright string in the executable of your product.
+ */
+
+const lzo_byte __lzo_copyright[] =
+#if !defined(__LZO_IN_MINLZO)
+ LZO_VERSION_STRING;
+#else
+ "\n\n\n"
+ "LZO real-time data compression library.\n"
+ "Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 Markus Franz Xaver Johannes Oberhumer\n"
+ "<markus.oberhumer@jk.uni-linz.ac.at>\n"
+ "http://www.oberhumer.com/opensource/lzo/\n"
+ "\n"
+ "LZO version: v" LZO_VERSION_STRING ", " LZO_VERSION_DATE "\n"
+ "LZO build date: " __DATE__ " " __TIME__ "\n\n"
+ "LZO special compilation options:\n"
+#ifdef __cplusplus
+ " __cplusplus\n"
+#endif
+#if defined(__PIC__)
+ " __PIC__\n"
+#elif defined(__pic__)
+ " __pic__\n"
+#endif
+#if (UINT_MAX < LZO_0xffffffffL)
+ " 16BIT\n"
+#endif
+#if defined(__LZO_STRICT_16BIT)
+ " __LZO_STRICT_16BIT\n"
+#endif
+#if (UINT_MAX > LZO_0xffffffffL)
+ " UINT_MAX=" _LZO_MEXPAND(UINT_MAX) "\n"
+#endif
+#if (ULONG_MAX > LZO_0xffffffffL)
+ " ULONG_MAX=" _LZO_MEXPAND(ULONG_MAX) "\n"
+#endif
+#if defined(LZO_BYTE_ORDER)
+ " LZO_BYTE_ORDER=" _LZO_MEXPAND(LZO_BYTE_ORDER) "\n"
+#endif
+#if defined(LZO_UNALIGNED_OK_2)
+ " LZO_UNALIGNED_OK_2\n"
+#endif
+#if defined(LZO_UNALIGNED_OK_4)
+ " LZO_UNALIGNED_OK_4\n"
+#endif
+#if defined(LZO_ALIGNED_OK_4)
+ " LZO_ALIGNED_OK_4\n"
+#endif
+#if defined(LZO_DICT_USE_PTR)
+ " LZO_DICT_USE_PTR\n"
+#endif
+#if defined(__LZO_QUERY_COMPRESS)
+ " __LZO_QUERY_COMPRESS\n"
+#endif
+#if defined(__LZO_QUERY_DECOMPRESS)
+ " __LZO_QUERY_DECOMPRESS\n"
+#endif
+#if defined(__LZO_IN_MINILZO)
+ " __LZO_IN_MINILZO\n"
+#endif
+ "\n\n"
+ "$Id: LZO " LZO_VERSION_STRING " built " __DATE__ " " __TIME__
+#if defined(__GNUC__) && defined(__VERSION__)
+ " by gcc " __VERSION__
+#elif defined(__BORLANDC__)
+ " by Borland C " _LZO_MEXPAND(__BORLANDC__)
+#elif defined(_MSC_VER)
+ " by Microsoft C " _LZO_MEXPAND(_MSC_VER)
+#elif defined(__PUREC__)
+ " by Pure C " _LZO_MEXPAND(__PUREC__)
+#elif defined(__SC__)
+ " by Symantec C " _LZO_MEXPAND(__SC__)
+#elif defined(__TURBOC__)
+ " by Turbo C " _LZO_MEXPAND(__TURBOC__)
+#elif defined(__WATCOMC__)
+ " by Watcom C " _LZO_MEXPAND(__WATCOMC__)
+#endif
+ " $\n"
+ "$Copyright: LZO (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 Markus Franz Xaver Johannes Oberhumer $\n";
+#endif
+
+#define LZO_BASE 65521u
+#define LZO_NMAX 5552
+
+#define LZO_DO1(buf,i) {s1 += buf[i]; s2 += s1;}
+#define LZO_DO2(buf,i) LZO_DO1(buf,i); LZO_DO1(buf,i+1);
+#define LZO_DO4(buf,i) LZO_DO2(buf,i); LZO_DO2(buf,i+2);
+#define LZO_DO8(buf,i) LZO_DO4(buf,i); LZO_DO4(buf,i+4);
+#define LZO_DO16(buf,i) LZO_DO8(buf,i); LZO_DO8(buf,i+8);
+
+LZO_PUBLIC(lzo_uint32)
+lzo_adler32(lzo_uint32 adler, const lzo_byte *buf, lzo_uint len)
+{
+ lzo_uint32 s1 = adler & 0xffff;
+ lzo_uint32 s2 = (adler >> 16) & 0xffff;
+ int k;
+
+ if (buf == NULL)
+ return 1;
+
+ while (len > 0)
+ {
+ k = len < LZO_NMAX ? (int) len : LZO_NMAX;
+ len -= k;
+ if (k >= 16) do
+ {
+ LZO_DO16(buf,0);
+ buf += 16;
+ k -= 16;
+ } while (k >= 16);
+ if (k != 0) do
+ {
+ s1 += *buf++;
+ s2 += s1;
+ } while (--k > 0);
+ s1 %= LZO_BASE;
+ s2 %= LZO_BASE;
+ }
+ return (s2 << 16) | s1;
+}
+
+#if 0
+# define IS_SIGNED(type) (((type) (1ul << (8 * sizeof(type) - 1))) < 0)
+# define IS_UNSIGNED(type) (((type) (1ul << (8 * sizeof(type) - 1))) > 0)
+#else
+# define IS_SIGNED(type) (((type) (-1)) < ((type) 0))
+# define IS_UNSIGNED(type) (((type) (-1)) > ((type) 0))
+#endif
+
+#define IS_POWER_OF_2(x) (((x) & ((x) - 1)) == 0)
+
+// static lzo_bool schedule_insns_bug(void);
+// static lzo_bool strength_reduce_bug(int *);
+
+#if 0 || defined(LZO_DEBUG)
+#include <stdio.h>
+static lzo_bool __lzo_assert_fail(const char *s, unsigned line)
+{
+#if defined(__palmos__)
+ printf("LZO assertion failed in line %u: '%s'\n",line,s);
+#else
+ fprintf(stderr,"LZO assertion failed in line %u: '%s'\n",line,s);
+#endif
+ return 0;
+}
+# define __lzo_assert(x) ((x) ? 1 : __lzo_assert_fail(#x,__LINE__))
+#else
+# define __lzo_assert(x) ((x) ? 1 : 0)
+#endif
+
+#undef COMPILE_TIME_ASSERT
+#if 0
+# define COMPILE_TIME_ASSERT(expr) r &= __lzo_assert(expr)
+#else
+# define COMPILE_TIME_ASSERT(expr) LZO_COMPILE_TIME_ASSERT(expr)
+#endif
+
+
+#define do_compress _lzo1x_1_do_compress
+
+#define LZO_NEED_DICT_H
+#define D_BITS 12
+#define D_INDEX1(d,p) d = DM((0x21*DX3(p,5,5,6)) >> 5)
+#define D_INDEX2(d,p) d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f)
+
+#ifndef __LZO_CONFIG1X_H
+#define __LZO_CONFIG1X_H
+
+#define LZO_EOF_CODE
+#undef LZO_DETERMINISTIC
+
+#define M1_MAX_OFFSET 0x0400
+#ifndef M2_MAX_OFFSET
+#define M2_MAX_OFFSET 0x0800
+#endif
+#define M3_MAX_OFFSET 0x4000
+#define M4_MAX_OFFSET 0xbfff
+
+#define MX_MAX_OFFSET (M1_MAX_OFFSET + M2_MAX_OFFSET)
+
+#define M1_MIN_LEN 2
+#define M1_MAX_LEN 2
+#define M2_MIN_LEN 3
+#ifndef M2_MAX_LEN
+#define M2_MAX_LEN 8
+#endif
+#define M3_MIN_LEN 3
+#define M3_MAX_LEN 33
+#define M4_MIN_LEN 3
+#define M4_MAX_LEN 9
+
+#define M1_MARKER 0
+#define M2_MARKER 64
+#define M3_MARKER 32
+#define M4_MARKER 16
+
+#ifndef MIN_LOOKAHEAD
+#define MIN_LOOKAHEAD (M2_MAX_LEN + 1)
+#endif
+
+#if defined(LZO_NEED_DICT_H)
+
+#ifndef LZO_HASH
+#define LZO_HASH LZO_HASH_LZO_INCREMENTAL_B
+#endif
+#define DL_MIN_LEN M2_MIN_LEN
+
+#ifndef __LZO_DICT_H
+#define __LZO_DICT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(D_BITS) && defined(DBITS)
+# define D_BITS DBITS
+#endif
+#if !defined(D_BITS)
+# error "D_BITS is not defined"
+#endif
+#if (D_BITS < 16)
+# define D_SIZE LZO_SIZE(D_BITS)
+# define D_MASK LZO_MASK(D_BITS)
+#else
+# define D_SIZE LZO_USIZE(D_BITS)
+# define D_MASK LZO_UMASK(D_BITS)
+#endif
+#define D_HIGH ((D_MASK >> 1) + 1)
+
+#if !defined(DD_BITS)
+# define DD_BITS 0
+#endif
+#define DD_SIZE LZO_SIZE(DD_BITS)
+#define DD_MASK LZO_MASK(DD_BITS)
+
+#if !defined(DL_BITS)
+# define DL_BITS (D_BITS - DD_BITS)
+#endif
+#if (DL_BITS < 16)
+# define DL_SIZE LZO_SIZE(DL_BITS)
+# define DL_MASK LZO_MASK(DL_BITS)
+#else
+# define DL_SIZE LZO_USIZE(DL_BITS)
+# define DL_MASK LZO_UMASK(DL_BITS)
+#endif
+
+#if (D_BITS != DL_BITS + DD_BITS)
+# error "D_BITS does not match"
+#endif
+#if (D_BITS < 8 || D_BITS > 18)
+# error "invalid D_BITS"
+#endif
+#if (DL_BITS < 8 || DL_BITS > 20)
+# error "invalid DL_BITS"
+#endif
+#if (DD_BITS < 0 || DD_BITS > 6)
+# error "invalid DD_BITS"
+#endif
+
+#if !defined(DL_MIN_LEN)
+# define DL_MIN_LEN 3
+#endif
+#if !defined(DL_SHIFT)
+# define DL_SHIFT ((DL_BITS + (DL_MIN_LEN - 1)) / DL_MIN_LEN)
+#endif
+
+#define LZO_HASH_GZIP 1
+#define LZO_HASH_GZIP_INCREMENTAL 2
+#define LZO_HASH_LZO_INCREMENTAL_A 3
+#define LZO_HASH_LZO_INCREMENTAL_B 4
+
+#if !defined(LZO_HASH)
+# error "choose a hashing strategy"
+#endif
+
+#if (DL_MIN_LEN == 3)
+# define _DV2_A(p,shift1,shift2) \
+ (((( (lzo_uint32)((p)[0]) << shift1) ^ (p)[1]) << shift2) ^ (p)[2])
+# define _DV2_B(p,shift1,shift2) \
+ (((( (lzo_uint32)((p)[2]) << shift1) ^ (p)[1]) << shift2) ^ (p)[0])
+# define _DV3_B(p,shift1,shift2,shift3) \
+ ((_DV2_B((p)+1,shift1,shift2) << (shift3)) ^ (p)[0])
+#elif (DL_MIN_LEN == 2)
+# define _DV2_A(p,shift1,shift2) \
+ (( (lzo_uint32)(p[0]) << shift1) ^ p[1])
+# define _DV2_B(p,shift1,shift2) \
+ (( (lzo_uint32)(p[1]) << shift1) ^ p[2])
+#else
+# error "invalid DL_MIN_LEN"
+#endif
+#define _DV_A(p,shift) _DV2_A(p,shift,shift)
+#define _DV_B(p,shift) _DV2_B(p,shift,shift)
+#define DA2(p,s1,s2) \
+ (((((lzo_uint32)((p)[2]) << (s2)) + (p)[1]) << (s1)) + (p)[0])
+#define DS2(p,s1,s2) \
+ (((((lzo_uint32)((p)[2]) << (s2)) - (p)[1]) << (s1)) - (p)[0])
+#define DX2(p,s1,s2) \
+ (((((lzo_uint32)((p)[2]) << (s2)) ^ (p)[1]) << (s1)) ^ (p)[0])
+#define DA3(p,s1,s2,s3) ((DA2((p)+1,s2,s3) << (s1)) + (p)[0])
+#define DS3(p,s1,s2,s3) ((DS2((p)+1,s2,s3) << (s1)) - (p)[0])
+#define DX3(p,s1,s2,s3) ((DX2((p)+1,s2,s3) << (s1)) ^ (p)[0])
+#define DMS(v,s) ((lzo_uint) (((v) & (D_MASK >> (s))) << (s)))
+#define DM(v) DMS(v,0)
+
+#if (LZO_HASH == LZO_HASH_GZIP)
+# define _DINDEX(dv,p) (_DV_A((p),DL_SHIFT))
+
+#elif (LZO_HASH == LZO_HASH_GZIP_INCREMENTAL)
+# define __LZO_HASH_INCREMENTAL
+# define DVAL_FIRST(dv,p) dv = _DV_A((p),DL_SHIFT)
+# define DVAL_NEXT(dv,p) dv = (((dv) << DL_SHIFT) ^ p[2])
+# define _DINDEX(dv,p) (dv)
+# define DVAL_LOOKAHEAD DL_MIN_LEN
+
+#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_A)
+# define __LZO_HASH_INCREMENTAL
+# define DVAL_FIRST(dv,p) dv = _DV_A((p),5)
+# define DVAL_NEXT(dv,p) \
+ dv ^= (lzo_uint32)(p[-1]) << (2*5); dv = (((dv) << 5) ^ p[2])
+# define _DINDEX(dv,p) ((0x9f5f * (dv)) >> 5)
+# define DVAL_LOOKAHEAD DL_MIN_LEN
+
+#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_B)
+# define __LZO_HASH_INCREMENTAL
+# define DVAL_FIRST(dv,p) dv = _DV_B((p),5)
+# define DVAL_NEXT(dv,p) \
+ dv ^= p[-1]; dv = (((dv) >> 5) ^ ((lzo_uint32)(p[2]) << (2*5)))
+# define _DINDEX(dv,p) ((0x9f5f * (dv)) >> 5)
+# define DVAL_LOOKAHEAD DL_MIN_LEN
+
+#else
+# error "choose a hashing strategy"
+#endif
+
+#ifndef DINDEX
+#define DINDEX(dv,p) ((lzo_uint)((_DINDEX(dv,p)) & DL_MASK) << DD_BITS)
+#endif
+#if !defined(DINDEX1) && defined(D_INDEX1)
+#define DINDEX1 D_INDEX1
+#endif
+#if !defined(DINDEX2) && defined(D_INDEX2)
+#define DINDEX2 D_INDEX2
+#endif
+
+#if !defined(__LZO_HASH_INCREMENTAL)
+# define DVAL_FIRST(dv,p) ((void) 0)
+# define DVAL_NEXT(dv,p) ((void) 0)
+# define DVAL_LOOKAHEAD 0
+#endif
+
+#if !defined(DVAL_ASSERT)
+#if defined(__LZO_HASH_INCREMENTAL) && !defined(NDEBUG)
+static void DVAL_ASSERT(lzo_uint32 dv, const lzo_byte *p)
+{
+ lzo_uint32 df;
+ DVAL_FIRST(df,(p));
+ assert(DINDEX(dv,p) == DINDEX(df,p));
+}
+#else
+# define DVAL_ASSERT(dv,p) ((void) 0)
+#endif
+#endif
+
+#if defined(LZO_DICT_USE_PTR)
+# define DENTRY(p,in) (p)
+# define GINDEX(m_pos,m_off,dict,dindex,in) m_pos = dict[dindex]
+#else
+# define DENTRY(p,in) ((lzo_uint) ((p)-(in)))
+# define GINDEX(m_pos,m_off,dict,dindex,in) m_off = dict[dindex]
+#endif
+
+#if (DD_BITS == 0)
+
+# define UPDATE_D(dict,drun,dv,p,in) dict[ DINDEX(dv,p) ] = DENTRY(p,in)
+# define UPDATE_I(dict,drun,index,p,in) dict[index] = DENTRY(p,in)
+# define UPDATE_P(ptr,drun,p,in) (ptr)[0] = DENTRY(p,in)
+
+#else
+
+# define UPDATE_D(dict,drun,dv,p,in) \
+ dict[ DINDEX(dv,p) + drun++ ] = DENTRY(p,in); drun &= DD_MASK
+# define UPDATE_I(dict,drun,index,p,in) \
+ dict[ (index) + drun++ ] = DENTRY(p,in); drun &= DD_MASK
+# define UPDATE_P(ptr,drun,p,in) \
+ (ptr) [ drun++ ] = DENTRY(p,in); drun &= DD_MASK
+
+#endif
+
+#if defined(LZO_DICT_USE_PTR)
+
+#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \
+ (m_pos == NULL || (m_off = (lzo_moff_t) (ip - m_pos)) > max_offset)
+
+#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \
+ (BOUNDS_CHECKING_OFF_IN_EXPR( \
+ (PTR_LT(m_pos,in) || \
+ (m_off = (lzo_moff_t) PTR_DIFF(ip,m_pos)) <= 0 || \
+ m_off > max_offset) ))
+
+#else
+
+#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \
+ (m_off == 0 || \
+ ((m_off = (lzo_moff_t) ((ip)-(in)) - m_off) > max_offset) || \
+ (m_pos = (ip) - (m_off), 0) )
+
+#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \
+ ((lzo_moff_t) ((ip)-(in)) <= m_off || \
+ ((m_off = (lzo_moff_t) ((ip)-(in)) - m_off) > max_offset) || \
+ (m_pos = (ip) - (m_off), 0) )
+
+#endif
+
+#if defined(LZO_DETERMINISTIC)
+# define LZO_CHECK_MPOS LZO_CHECK_MPOS_DET
+#else
+# define LZO_CHECK_MPOS LZO_CHECK_MPOS_NON_DET
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
+
+#endif
+
+#define DO_COMPRESS lzo1x_1_compress
+
+static
+lzo_uint do_compress ( const lzo_byte *in , lzo_uint in_len,
+ lzo_byte *out, lzo_uintp out_len,
+ lzo_voidp wrkmem )
+{
+ register const lzo_byte *ip;
+ lzo_byte *op;
+ const lzo_byte * const in_end = in + in_len;
+ const lzo_byte * const ip_end = in + in_len - M2_MAX_LEN - 5;
+ const lzo_byte *ii;
+ lzo_dict_p const dict = (lzo_dict_p) wrkmem;
+
+ op = out;
+ ip = in;
+ ii = ip;
+
+ ip += 4;
+ for (;;)
+ {
+ register const lzo_byte *m_pos;
+ lzo_moff_t m_off;
+ lzo_uint m_len;
+ lzo_uint dindex;
+
+ DINDEX1(dindex,ip);
+ GINDEX(m_pos,m_off,dict,dindex,in);
+ if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET))
+ goto literal;
+ if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
+ goto try_match;
+ DINDEX2(dindex,ip);
+ GINDEX(m_pos,m_off,dict,dindex,in);
+ if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET))
+ goto literal;
+ if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
+ goto try_match;
+ goto literal;
+
+try_match:
+#if 1 && defined(LZO_UNALIGNED_OK_2)
+ if (* (const lzo_ushortp) m_pos != * (const lzo_ushortp) ip)
+#else
+ if (m_pos[0] != ip[0] || m_pos[1] != ip[1])
+#endif
+ {
+ }
+ else
+ {
+ if (m_pos[2] == ip[2])
+ {
+ goto match;
+ }
+ }
+
+literal:
+ UPDATE_I(dict,0,dindex,ip,in);
+ ++ip;
+ if (ip >= ip_end)
+ break;
+ continue;
+
+match:
+ UPDATE_I(dict,0,dindex,ip,in);
+ if (pd(ip,ii) > 0)
+ {
+ register lzo_uint t = pd(ip,ii);
+
+ if (t <= 3)
+ {
+ assert(op - 2 > out);
+ op[-2] |= LZO_BYTE(t);
+ }
+ else if (t <= 18)
+ *op++ = LZO_BYTE(t - 3);
+ else
+ {
+ register lzo_uint tt = t - 18;
+
+ *op++ = 0;
+ while (tt > 255)
+ {
+ tt -= 255;
+ *op++ = 0;
+ }
+ assert(tt > 0);
+ *op++ = LZO_BYTE(tt);
+ }
+ do *op++ = *ii++; while (--t > 0);
+ }
+
+ assert(ii == ip);
+ ip += 3;
+ if (m_pos[3] != *ip++ || m_pos[4] != *ip++ || m_pos[5] != *ip++ ||
+ m_pos[6] != *ip++ || m_pos[7] != *ip++ || m_pos[8] != *ip++) {
+
+ --ip;
+ m_len = ip - ii;
+ assert(m_len >= 3); assert(m_len <= M2_MAX_LEN);
+
+ if (m_off <= M2_MAX_OFFSET)
+ {
+ m_off -= 1;
+ *op++ = LZO_BYTE(((m_len - 1) << 5) | ((m_off & 7) << 2));
+ *op++ = LZO_BYTE(m_off >> 3);
+ }
+ else if (m_off <= M3_MAX_OFFSET)
+ {
+ m_off -= 1;
+ *op++ = LZO_BYTE(M3_MARKER | (m_len - 2));
+ goto m3_m4_offset;
+ }
+ else
+ {
+ m_off -= 0x4000;
+ assert(m_off > 0); assert(m_off <= 0x7fff);
+ *op++ = LZO_BYTE(M4_MARKER |
+ ((m_off & 0x4000) >> 11) | (m_len - 2));
+ goto m3_m4_offset;
+ }
+ }
+ else
+ {
+ {
+ const lzo_byte *end = in_end;
+ const lzo_byte *m = m_pos + M2_MAX_LEN + 1;
+ while (ip < end && *m == *ip)
+ m++, ip++;
+ m_len = (ip - ii);
+ }
+ assert(m_len > M2_MAX_LEN);
+
+ if (m_off <= M3_MAX_OFFSET)
+ {
+ m_off -= 1;
+ if (m_len <= 33)
+ *op++ = LZO_BYTE(M3_MARKER | (m_len - 2));
+ else
+ {
+ m_len -= 33;
+ *op++ = M3_MARKER | 0;
+ goto m3_m4_len;
+ }
+ }
+ else
+ {
+ m_off -= 0x4000;
+ assert(m_off > 0); assert(m_off <= 0x7fff);
+ if (m_len <= M4_MAX_LEN)
+ *op++ = LZO_BYTE(M4_MARKER |
+ ((m_off & 0x4000) >> 11) | (m_len - 2));
+ else
+ {
+ m_len -= M4_MAX_LEN;
+ *op++ = LZO_BYTE(M4_MARKER | ((m_off & 0x4000) >> 11));
+m3_m4_len:
+ while (m_len > 255)
+ {
+ m_len -= 255;
+ *op++ = 0;
+ }
+ assert(m_len > 0);
+ *op++ = LZO_BYTE(m_len);
+ }
+ }
+
+m3_m4_offset:
+ *op++ = LZO_BYTE((m_off & 63) << 2);
+ *op++ = LZO_BYTE(m_off >> 6);
+ }
+
+ ii = ip;
+ if (ip >= ip_end)
+ break;
+ }
+
+ *out_len = op - out;
+ return pd(in_end,ii);
+}
+
+LZO_PUBLIC(int)
+DO_COMPRESS ( const lzo_byte *in , lzo_uint in_len,
+ lzo_byte *out, lzo_uintp out_len,
+ lzo_voidp wrkmem )
+{
+ lzo_byte *op = out;
+ lzo_uint t;
+
+ if (in_len <= M2_MAX_LEN + 5)
+ t = in_len;
+ else
+ {
+ t = do_compress(in,in_len,op,out_len,wrkmem);
+ op += *out_len;
+ }
+
+ if (t > 0)
+ {
+ const lzo_byte *ii = in + in_len - t;
+
+ if (op == out && t <= 238)
+ *op++ = LZO_BYTE(17 + t);
+ else if (t <= 3)
+ op[-2] |= LZO_BYTE(t);
+ else if (t <= 18)
+ *op++ = LZO_BYTE(t - 3);
+ else
+ {
+ lzo_uint tt = t - 18;
+
+ *op++ = 0;
+ while (tt > 255)
+ {
+ tt -= 255;
+ *op++ = 0;
+ }
+ assert(tt > 0);
+ *op++ = LZO_BYTE(tt);
+ }
+ do *op++ = *ii++; while (--t > 0);
+ }
+
+ *op++ = M4_MARKER | 1;
+ *op++ = 0;
+ *op++ = 0;
+
+ *out_len = op - out;
+ return LZO_E_OK;
+}
+
+#undef do_compress
+#undef DO_COMPRESS
+#undef LZO_HASH
+
+#undef LZO_TEST_DECOMPRESS_OVERRUN
+#undef LZO_TEST_DECOMPRESS_OVERRUN_INPUT
+#undef LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT
+#undef LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND
+#undef DO_DECOMPRESS
+#define DO_DECOMPRESS lzo1x_decompress
+
+#if defined(LZO_TEST_DECOMPRESS_OVERRUN)
+# if !defined(LZO_TEST_DECOMPRESS_OVERRUN_INPUT)
+# define LZO_TEST_DECOMPRESS_OVERRUN_INPUT 2
+# endif
+# if !defined(LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT)
+# define LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT 2
+# endif
+# if !defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND)
+# define LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND
+# endif
+#endif
+
+#undef TEST_IP
+#undef TEST_OP
+#undef TEST_LOOKBEHIND
+#undef NEED_IP
+#undef NEED_OP
+#undef HAVE_TEST_IP
+#undef HAVE_TEST_OP
+#undef HAVE_NEED_IP
+#undef HAVE_NEED_OP
+#undef HAVE_ANY_IP
+#undef HAVE_ANY_OP
+
+#if defined(LZO_TEST_DECOMPRESS_OVERRUN_INPUT)
+# if (LZO_TEST_DECOMPRESS_OVERRUN_INPUT >= 1)
+# define TEST_IP (ip < ip_end)
+# endif
+# if (LZO_TEST_DECOMPRESS_OVERRUN_INPUT >= 2)
+# define NEED_IP(x) \
+ if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun
+# endif
+#endif
+
+#if defined(LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT)
+# if (LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT >= 1)
+# define TEST_OP (op <= op_end)
+# endif
+# if (LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT >= 2)
+# undef TEST_OP
+# define NEED_OP(x) \
+ if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun
+# endif
+#endif
+
+#if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND)
+# define TEST_LOOKBEHIND(m_pos,out) if (m_pos < out) goto lookbehind_overrun
+#else
+# define TEST_LOOKBEHIND(m_pos,op) ((void) 0)
+#endif
+
+#if !defined(LZO_EOF_CODE) && !defined(TEST_IP)
+# define TEST_IP (ip < ip_end)
+#endif
+
+#if defined(TEST_IP)
+# define HAVE_TEST_IP
+#else
+# define TEST_IP 1
+#endif
+#if defined(TEST_OP)
+# define HAVE_TEST_OP
+#else
+# define TEST_OP 1
+#endif
+
+#if defined(NEED_IP)
+# define HAVE_NEED_IP
+#else
+# define NEED_IP(x) ((void) 0)
+#endif
+#if defined(NEED_OP)
+# define HAVE_NEED_OP
+#else
+# define NEED_OP(x) ((void) 0)
+#endif
+
+#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP)
+# define HAVE_ANY_IP
+#endif
+#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP)
+# define HAVE_ANY_OP
+#endif
+
+#undef __COPY4
+#define __COPY4(dst,src) * (lzo_uint32p)(dst) = * (const lzo_uint32p)(src)
+
+#undef COPY4
+#if defined(LZO_UNALIGNED_OK_4)
+# define COPY4(dst,src) __COPY4(dst,src)
+#elif defined(LZO_ALIGNED_OK_4)
+# define COPY4(dst,src) __COPY4((lzo_ptr_t)(dst),(lzo_ptr_t)(src))
+#endif
+
+#if defined(DO_DECOMPRESS)
+LZO_PUBLIC(int)
+DO_DECOMPRESS ( const lzo_byte *in , lzo_uint in_len,
+ lzo_byte *out, lzo_uintp out_len,
+ lzo_voidp wrkmem )
+#endif
+{
+ register lzo_byte *op;
+ register const lzo_byte *ip;
+ register lzo_uint t;
+ register const lzo_byte *m_pos;
+
+ const lzo_byte * const ip_end = in + in_len;
+#if defined(HAVE_ANY_OP)
+ lzo_byte * const op_end = out + *out_len;
+#endif
+
+ LZO_UNUSED(wrkmem);
+
+ *out_len = 0;
+
+ op = out;
+ ip = in;
+
+ if (*ip > 17)
+ {
+ t = *ip++ - 17;
+ if (t < 4)
+ goto match_next;
+ assert(t > 0); NEED_OP(t); NEED_IP(t+1);
+ do *op++ = *ip++; while (--t > 0);
+ goto first_literal_run;
+ }
+
+ while (TEST_IP && TEST_OP)
+ {
+ t = *ip++;
+ if (t >= 16)
+ goto match;
+ if (t == 0)
+ {
+ NEED_IP(1);
+ while (*ip == 0)
+ {
+ t += 255;
+ ip++;
+ NEED_IP(1);
+ }
+ t += 15 + *ip++;
+ }
+ assert(t > 0); NEED_OP(t+3); NEED_IP(t+4);
+#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
+#if !defined(LZO_UNALIGNED_OK_4)
+ if (PTR_ALIGNED2_4(op,ip))
+ {
+#endif
+ COPY4(op,ip);
+ op += 4; ip += 4;
+ if (--t > 0)
+ {
+ if (t >= 4)
+ {
+ do {
+ COPY4(op,ip);
+ op += 4; ip += 4; t -= 4;
+ } while (t >= 4);
+ if (t > 0) do *op++ = *ip++; while (--t > 0);
+ }
+ else
+ do *op++ = *ip++; while (--t > 0);
+ }
+#if !defined(LZO_UNALIGNED_OK_4)
+ }
+ else
+#endif
+#endif
+#if !defined(LZO_UNALIGNED_OK_4)
+ {
+ *op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
+ do *op++ = *ip++; while (--t > 0);
+ }
+#endif
+
+first_literal_run:
+
+ t = *ip++;
+ if (t >= 16)
+ goto match;
+ m_pos = op - (1 + M2_MAX_OFFSET);
+ m_pos -= t >> 2;
+ m_pos -= *ip++ << 2;
+ TEST_LOOKBEHIND(m_pos,out); NEED_OP(3);
+ *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
+ goto match_done;
+
+ while (TEST_IP && TEST_OP)
+ {
+match:
+ if (t >= 64)
+ {
+#if defined(LZO1X)
+ m_pos = op - 1;
+ m_pos -= (t >> 2) & 7;
+ m_pos -= *ip++ << 3;
+ t = (t >> 5) - 1;
+#endif
+ TEST_LOOKBEHIND(m_pos,out); assert(t > 0); NEED_OP(t+3-1);
+ goto copy_match;
+ }
+ else if (t >= 32)
+ {
+ t &= 31;
+ if (t == 0)
+ {
+ NEED_IP(1);
+ while (*ip == 0)
+ {
+ t += 255;
+ ip++;
+ NEED_IP(1);
+ }
+ t += 31 + *ip++;
+ }
+#if defined(LZO_UNALIGNED_OK_2) && (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN)
+ m_pos = op - 1;
+ m_pos -= (* (const lzo_ushortp) ip) >> 2;
+#else
+ m_pos = op - 1;
+ m_pos -= (ip[0] >> 2) + (ip[1] << 6);
+#endif
+ ip += 2;
+ }
+ else if (t >= 16)
+ {
+ m_pos = op;
+ m_pos -= (t & 8) << 11;
+ t &= 7;
+ if (t == 0)
+ {
+ NEED_IP(1);
+ while (*ip == 0)
+ {
+ t += 255;
+ ip++;
+ NEED_IP(1);
+ }
+ t += 7 + *ip++;
+ }
+#if defined(LZO_UNALIGNED_OK_2) && (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN)
+ m_pos -= (* (const lzo_ushortp) ip) >> 2;
+#else
+ m_pos -= (ip[0] >> 2) + (ip[1] << 6);
+#endif
+ ip += 2;
+ if (m_pos == op)
+ goto eof_found;
+ m_pos -= 0x4000;
+ }
+ else
+ {
+ m_pos = op - 1;
+ m_pos -= t >> 2;
+ m_pos -= *ip++ << 2;
+ TEST_LOOKBEHIND(m_pos,out); NEED_OP(2);
+ *op++ = *m_pos++; *op++ = *m_pos;
+ goto match_done;
+ }
+
+ TEST_LOOKBEHIND(m_pos,out); assert(t > 0); NEED_OP(t+3-1);
+#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
+#if !defined(LZO_UNALIGNED_OK_4)
+ if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
+ {
+ assert((op - m_pos) >= 4);
+#else
+ if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
+ {
+#endif
+ COPY4(op,m_pos);
+ op += 4; m_pos += 4; t -= 4 - (3 - 1);
+ do {
+ COPY4(op,m_pos);
+ op += 4; m_pos += 4; t -= 4;
+ } while (t >= 4);
+ if (t > 0) do *op++ = *m_pos++; while (--t > 0);
+ }
+ else
+#endif
+ {
+copy_match:
+ *op++ = *m_pos++; *op++ = *m_pos++;
+ do *op++ = *m_pos++; while (--t > 0);
+ }
+
+match_done:
+ t = ip[-2] & 3;
+ if (t == 0)
+ break;
+
+match_next:
+ assert(t > 0); NEED_OP(t); NEED_IP(t+1);
+ do *op++ = *ip++; while (--t > 0);
+ t = *ip++;
+ }
+ }
+
+#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
+ *out_len = op - out;
+ return LZO_E_EOF_NOT_FOUND;
+#endif
+
+eof_found:
+ assert(t == 1);
+ *out_len = op - out;
+ return (ip == ip_end ? LZO_E_OK :
+ (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
+
+#if defined(HAVE_NEED_IP)
+input_overrun:
+ *out_len = op - out;
+ return LZO_E_INPUT_OVERRUN;
+#endif
+
+#if defined(HAVE_NEED_OP)
+output_overrun:
+ *out_len = op - out;
+ return LZO_E_OUTPUT_OVERRUN;
+#endif
+
+#if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND)
+lookbehind_overrun:
+ *out_len = op - out;
+ return LZO_E_LOOKBEHIND_OVERRUN;
+#endif
+}
+
+#define LZO_TEST_DECOMPRESS_OVERRUN
+#undef DO_DECOMPRESS
+#define DO_DECOMPRESS lzo1x_decompress_safe
+
+#if defined(LZO_TEST_DECOMPRESS_OVERRUN)
+# if !defined(LZO_TEST_DECOMPRESS_OVERRUN_INPUT)
+# define LZO_TEST_DECOMPRESS_OVERRUN_INPUT 2
+# endif
+# if !defined(LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT)
+# define LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT 2
+# endif
+# if !defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND)
+# define LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND
+# endif
+#endif
+
+#undef TEST_IP
+#undef TEST_OP
+#undef TEST_LOOKBEHIND
+#undef NEED_IP
+#undef NEED_OP
+#undef HAVE_TEST_IP
+#undef HAVE_TEST_OP
+#undef HAVE_NEED_IP
+#undef HAVE_NEED_OP
+#undef HAVE_ANY_IP
+#undef HAVE_ANY_OP
+
+
+#if 0
+
+#if defined(LZO_TEST_DECOMPRESS_OVERRUN_INPUT)
+# if (LZO_TEST_DECOMPRESS_OVERRUN_INPUT >= 1)
+# define TEST_IP (ip < ip_end)
+# endif
+# if (LZO_TEST_DECOMPRESS_OVERRUN_INPUT >= 2)
+# define NEED_IP(x) \
+ if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun
+# endif
+#endif
+
+#if defined(LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT)
+# if (LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT >= 1)
+# define TEST_OP (op <= op_end)
+# endif
+# if (LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT >= 2)
+# undef TEST_OP
+# define NEED_OP(x) \
+ if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun
+# endif
+#endif
+
+#if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND)
+# define TEST_LOOKBEHIND(m_pos,out) if (m_pos < out) goto lookbehind_overrun
+#else
+# define TEST_LOOKBEHIND(m_pos,op) ((void) 0)
+#endif
+
+#if !defined(LZO_EOF_CODE) && !defined(TEST_IP)
+# define TEST_IP (ip < ip_end)
+#endif
+
+#if defined(TEST_IP)
+# define HAVE_TEST_IP
+#else
+# define TEST_IP 1
+#endif
+#if defined(TEST_OP)
+# define HAVE_TEST_OP
+#else
+# define TEST_OP 1
+#endif
+
+#if defined(NEED_IP)
+# define HAVE_NEED_IP
+#else
+# define NEED_IP(x) ((void) 0)
+#endif
+#if defined(NEED_OP)
+# define HAVE_NEED_OP
+#else
+# define NEED_OP(x) ((void) 0)
+#endif
+
+#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP)
+# define HAVE_ANY_IP
+#endif
+#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP)
+# define HAVE_ANY_OP
+#endif
+
+#undef __COPY4
+#define __COPY4(dst,src) * (lzo_uint32p)(dst) = * (const lzo_uint32p)(src)
+
+#undef COPY4
+#if defined(LZO_UNALIGNED_OK_4)
+# define COPY4(dst,src) __COPY4(dst,src)
+#elif defined(LZO_ALIGNED_OK_4)
+# define COPY4(dst,src) __COPY4((lzo_ptr_t)(dst),(lzo_ptr_t)(src))
+#endif
+
+#if defined(DO_DECOMPRESS)
+LZO_PUBLIC(int)
+DO_DECOMPRESS ( const lzo_byte *in , lzo_uint in_len,
+ lzo_byte *out, lzo_uintp out_len,
+ lzo_voidp wrkmem )
+#endif
+{
+ register lzo_byte *op;
+ register const lzo_byte *ip;
+ register lzo_uint t;
+ register const lzo_byte *m_pos;
+
+ const lzo_byte * const ip_end = in + in_len;
+#if defined(HAVE_ANY_OP)
+ lzo_byte * const op_end = out + *out_len;
+#endif
+
+ LZO_UNUSED(wrkmem);
+
+ *out_len = 0;
+
+ op = out;
+ ip = in;
+
+ if (*ip > 17)
+ {
+ t = *ip++ - 17;
+ if (t < 4)
+ goto match_next;
+ assert(t > 0); NEED_OP(t); NEED_IP(t+1);
+ do *op++ = *ip++; while (--t > 0);
+ goto first_literal_run;
+ }
+
+ while (TEST_IP && TEST_OP)
+ {
+ t = *ip++;
+ if (t >= 16)
+ goto match;
+ if (t == 0)
+ {
+ NEED_IP(1);
+ while (*ip == 0)
+ {
+ t += 255;
+ ip++;
+ NEED_IP(1);
+ }
+ t += 15 + *ip++;
+ }
+ assert(t > 0); NEED_OP(t+3); NEED_IP(t+4);
+#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
+#if !defined(LZO_UNALIGNED_OK_4)
+ if (PTR_ALIGNED2_4(op,ip))
+ {
+#endif
+ COPY4(op,ip);
+ op += 4; ip += 4;
+ if (--t > 0)
+ {
+ if (t >= 4)
+ {
+ do {
+ COPY4(op,ip);
+ op += 4; ip += 4; t -= 4;
+ } while (t >= 4);
+ if (t > 0) do *op++ = *ip++; while (--t > 0);
+ }
+ else
+ do *op++ = *ip++; while (--t > 0);
+ }
+#if !defined(LZO_UNALIGNED_OK_4)
+ }
+ else
+#endif
+#endif
+#if !defined(LZO_UNALIGNED_OK_4)
+ {
+ *op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
+ do *op++ = *ip++; while (--t > 0);
+ }
+#endif
+
+first_literal_run:
+
+ t = *ip++;
+ if (t >= 16)
+ goto match;
+#if defined(LZO1Z)
+ t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
+ m_pos = op - t;
+ last_m_off = t;
+#else
+ m_pos = op - (1 + M2_MAX_OFFSET);
+ m_pos -= t >> 2;
+ m_pos -= *ip++ << 2;
+#endif
+ TEST_LOOKBEHIND(m_pos,out); NEED_OP(3);
+ *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
+ goto match_done;
+
+ while (TEST_IP && TEST_OP)
+ {
+match:
+ if (t >= 64)
+ {
+#if defined(LZO1X)
+ m_pos = op - 1;
+ m_pos -= (t >> 2) & 7;
+ m_pos -= *ip++ << 3;
+ t = (t >> 5) - 1;
+#elif defined(LZO1Y)
+ m_pos = op - 1;
+ m_pos -= (t >> 2) & 3;
+ m_pos -= *ip++ << 2;
+ t = (t >> 4) - 3;
+#elif defined(LZO1Z)
+ {
+ lzo_uint off = t & 0x1f;
+ m_pos = op;
+ if (off >= 0x1c)
+ {
+ assert(last_m_off > 0);
+ m_pos -= last_m_off;
+ }
+ else
+ {
+ off = 1 + (off << 6) + (*ip++ >> 2);
+ m_pos -= off;
+ last_m_off = off;
+ }
+ }
+ t = (t >> 5) - 1;
+#endif
+ TEST_LOOKBEHIND(m_pos,out); assert(t > 0); NEED_OP(t+3-1);
+ goto copy_match;
+ }
+ else if (t >= 32)
+ {
+ t &= 31;
+ if (t == 0)
+ {
+ NEED_IP(1);
+ while (*ip == 0)
+ {
+ t += 255;
+ ip++;
+ NEED_IP(1);
+ }
+ t += 31 + *ip++;
+ }
+#if defined(LZO1Z)
+ {
+ lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
+ m_pos = op - off;
+ last_m_off = off;
+ }
+#elif defined(LZO_UNALIGNED_OK_2) && (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN)
+ m_pos = op - 1;
+ m_pos -= (* (const lzo_ushortp) ip) >> 2;
+#else
+ m_pos = op - 1;
+ m_pos -= (ip[0] >> 2) + (ip[1] << 6);
+#endif
+ ip += 2;
+ }
+ else if (t >= 16)
+ {
+ m_pos = op;
+ m_pos -= (t & 8) << 11;
+ t &= 7;
+ if (t == 0)
+ {
+ NEED_IP(1);
+ while (*ip == 0)
+ {
+ t += 255;
+ ip++;
+ NEED_IP(1);
+ }
+ t += 7 + *ip++;
+ }
+#if defined(LZO1Z)
+ m_pos -= (ip[0] << 6) + (ip[1] >> 2);
+#elif defined(LZO_UNALIGNED_OK_2) && (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN)
+ m_pos -= (* (const lzo_ushortp) ip) >> 2;
+#else
+ m_pos -= (ip[0] >> 2) + (ip[1] << 6);
+#endif
+ ip += 2;
+ if (m_pos == op)
+ goto eof_found;
+ m_pos -= 0x4000;
+#if defined(LZO1Z)
+ last_m_off = op - m_pos;
+#endif
+ }
+ else
+ {
+#if defined(LZO1Z)
+ t = 1 + (t << 6) + (*ip++ >> 2);
+ m_pos = op - t;
+ last_m_off = t;
+#else
+ m_pos = op - 1;
+ m_pos -= t >> 2;
+ m_pos -= *ip++ << 2;
+#endif
+ TEST_LOOKBEHIND(m_pos,out); NEED_OP(2);
+ *op++ = *m_pos++; *op++ = *m_pos;
+ goto match_done;
+ }
+
+ TEST_LOOKBEHIND(m_pos,out); assert(t > 0); NEED_OP(t+3-1);
+#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
+#if !defined(LZO_UNALIGNED_OK_4)
+ if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
+ {
+ assert((op - m_pos) >= 4);
+#else
+ if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
+ {
+#endif
+ COPY4(op,m_pos);
+ op += 4; m_pos += 4; t -= 4 - (3 - 1);
+ do {
+ COPY4(op,m_pos);
+ op += 4; m_pos += 4; t -= 4;
+ } while (t >= 4);
+ if (t > 0) do *op++ = *m_pos++; while (--t > 0);
+ }
+ else
+#endif
+ {
+copy_match:
+ *op++ = *m_pos++; *op++ = *m_pos++;
+ do *op++ = *m_pos++; while (--t > 0);
+ }
+
+
+match_done:
+#if defined(LZO1Z)
+ t = ip[-1] & 3;
+#else
+ t = ip[-2] & 3;
+#endif
+ if (t == 0)
+ break;
+
+match_next:
+ assert(t > 0); NEED_OP(t); NEED_IP(t+1);
+ do *op++ = *ip++; while (--t > 0);
+ t = *ip++;
+ }
+ }
+
+#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
+ *out_len = op - out;
+ return LZO_E_EOF_NOT_FOUND;
+#endif
+
+eof_found:
+ assert(t == 1);
+ *out_len = op - out;
+ return (ip == ip_end ? LZO_E_OK :
+ (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
+
+#if defined(HAVE_NEED_IP)
+input_overrun:
+ *out_len = op - out;
+ return LZO_E_INPUT_OVERRUN;
+#endif
+
+#if defined(HAVE_NEED_OP)
+output_overrun:
+ *out_len = op - out;
+ return LZO_E_OUTPUT_OVERRUN;
+#endif
+
+#if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND)
+lookbehind_overrun:
+ *out_len = op - out;
+ return LZO_E_LOOKBEHIND_OVERRUN;
+#endif
+}
+
+#endif
+
+/***** End of minilzo.c *****/
diff --git a/src/minilzo.h b/src/minilzo.h
new file mode 100644
index 000000000..cf06a4c9c
--- /dev/null
+++ b/src/minilzo.h
@@ -0,0 +1,97 @@
+/* $Id$ */
+
+/* minilzo.h -- mini subset of the LZO real-time data compression library
+
+ This file is part of the LZO real-time data compression library.
+
+ Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
+ All Rights Reserved.
+
+ The LZO library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ The LZO library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the LZO library; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Markus F.X.J. Oberhumer
+ <markus@oberhumer.com>
+ http://www.oberhumer.com/opensource/lzo/
+ */
+
+/*
+ * NOTE:
+ * the full LZO package can be found at
+ * http://www.oberhumer.com/opensource/lzo/
+ */
+
+
+#ifndef MINILZO_H
+#define MINILZO_H
+
+#define MINILZO_VERSION 0x1080
+
+#ifdef __LZOCONF_H
+# error "you cannot use both LZO and miniLZO"
+#endif
+
+#undef LZO_HAVE_CONFIG_H
+#include "lzoconf.h"
+
+#if !defined(LZO_VERSION) || (LZO_VERSION != MINILZO_VERSION)
+# error "version mismatch in header files"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Memory required for the wrkmem parameter.
+ * When the required size is 0, you can also pass a NULL pointer.
+ */
+
+#define LZO1X_MEM_COMPRESS LZO1X_1_MEM_COMPRESS
+#define LZO1X_1_MEM_COMPRESS ((lzo_uint32) (16384L * lzo_sizeof_dict_t))
+#define LZO1X_MEM_DECOMPRESS (0)
+
+
+/* compression */
+LZO_EXTERN(int)
+lzo1x_1_compress ( const lzo_byte *src, lzo_uint src_len,
+ lzo_byte *dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem );
+
+/* decompression */
+LZO_EXTERN(int)
+lzo1x_decompress ( const lzo_byte *src, lzo_uint src_len,
+ lzo_byte *dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem /* NOT USED */ );
+
+/* safe decompression with overrun testing */
+LZO_EXTERN(int)
+lzo1x_decompress_safe ( const lzo_byte *src, lzo_uint src_len,
+ lzo_byte *dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem /* NOT USED */ );
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* MINILZO_H */
diff --git a/src/misc.c b/src/misc.c
new file mode 100644
index 000000000..fd3a74b79
--- /dev/null
+++ b/src/misc.c
@@ -0,0 +1,634 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "currency.h"
+#include "functions.h"
+#include "news.h"
+#include "player.h"
+#include "string.h"
+#include "table/strings.h"
+#include "table/sprites.h"
+#include "map.h"
+#include "vehicle.h"
+#include "saveload.h"
+#include "engine.h"
+#include "vehicle_gui.h"
+#include "variables.h"
+#include "ai/ai.h"
+#include "table/landscape_const.h"
+#include "date.h"
+
+char _name_array[512][32];
+
+#ifndef MERSENNE_TWISTER
+
+#ifdef RANDOM_DEBUG
+#include "network/network_data.h"
+uint32 DoRandom(int line, const char *file)
+#else // RANDOM_DEBUG
+uint32 Random(void)
+#endif // RANDOM_DEBUG
+{
+
+uint32 s;
+uint32 t;
+
+#ifdef RANDOM_DEBUG
+ if (_networking && (DEREF_CLIENT(0)->status != STATUS_INACTIVE || !_network_server))
+ printf("Random [%d/%d] %s:%d\n",_frame_counter, _current_player, file, line);
+#endif
+
+ s = _random_seeds[0][0];
+ t = _random_seeds[0][1];
+ _random_seeds[0][0] = s + ROR(t ^ 0x1234567F, 7) + 1;
+ return _random_seeds[0][1] = ROR(s, 3) - 1;
+}
+#endif // MERSENNE_TWISTER
+
+#if defined(RANDOM_DEBUG) && !defined(MERSENNE_TWISTER)
+uint DoRandomRange(uint max, int line, const char *file)
+{
+ return GB(DoRandom(line, file), 0, 16) * max >> 16;
+}
+#else
+uint RandomRange(uint max)
+{
+ return GB(Random(), 0, 16) * max >> 16;
+}
+#endif
+
+
+uint32 InteractiveRandom(void)
+{
+ uint32 t = _random_seeds[1][1];
+ uint32 s = _random_seeds[1][0];
+ _random_seeds[1][0] = s + ROR(t ^ 0x1234567F, 7) + 1;
+ return _random_seeds[1][1] = ROR(s, 3) - 1;
+}
+
+uint InteractiveRandomRange(uint max)
+{
+ return GB(InteractiveRandom(), 0, 16) * max >> 16;
+}
+
+void InitializeVehicles(void);
+void InitializeWaypoints(void);
+void InitializeDepots(void);
+void InitializeEngines(void);
+void InitializeOrders(void);
+void InitializeClearLand(void);
+void InitializeRailGui(void);
+void InitializeRoadGui(void);
+void InitializeAirportGui(void);
+void InitializeDockGui(void);
+void InitializeIndustries(void);
+void InitializeMainGui(void);
+void InitializeLandscape(void);
+void InitializeTowns(void);
+void InitializeTrees(void);
+void InitializeSigns(void);
+void InitializeStations(void);
+static void InitializeNameMgr(void);
+void InitializePlayers(void);
+static void InitializeCheats(void);
+void InitializeNPF(void);
+
+void InitializeGame(int mode, uint size_x, uint size_y)
+{
+ AllocateMap(size_x, size_y);
+
+ AddTypeToEngines(); // make sure all engines have a type
+
+ SetObjectToPlace(SPR_CURSOR_ZZZ, 0, 0, 0);
+
+ _pause = 0;
+ _fast_forward = 0;
+ _tick_counter = 0;
+ _date_fract = 0;
+ _cur_tileloop_tile = 0;
+
+ if ((mode & IG_DATE_RESET) == IG_DATE_RESET) {
+ SetDate(ConvertYMDToDate(_patches.starting_year, 0, 1));
+ }
+
+ InitializeEngines();
+ InitializeVehicles();
+ InitializeWaypoints();
+ InitializeDepots();
+ InitializeOrders();
+
+ InitNewsItemStructs();
+ InitializeLandscape();
+ InitializeClearLand();
+ InitializeRailGui();
+ InitializeRoadGui();
+ InitializeAirportGui();
+ InitializeDockGui();
+ InitializeTowns();
+ InitializeTrees();
+ InitializeSigns();
+ InitializeStations();
+ InitializeIndustries();
+ InitializeMainGui();
+
+ InitializeNameMgr();
+ InitializeVehiclesGuiList();
+ InitializeTrains();
+ InitializeNPF();
+
+ AI_Initialize();
+ InitializePlayers();
+ InitializeCheats();
+
+ InitTextEffects();
+ InitTextMessage();
+ InitializeAnimatedTiles();
+
+ InitializeLandscapeVariables(false);
+
+ ResetObjectToPlace();
+}
+
+bool IsCustomName(StringID id)
+{
+ return GB(id, 11, 5) == 15;
+}
+
+void DeleteName(StringID id)
+{
+ if (IsCustomName(id)) {
+ memset(_name_array[id & 0x1FF], 0, sizeof(_name_array[id & 0x1FF]));
+ }
+}
+
+char *GetName(char *buff, StringID id, const char* last)
+{
+ return strecpy(buff, _name_array[id & ~0x600], last);
+}
+
+
+static void InitializeCheats(void)
+{
+ memset(&_cheats, 0, sizeof(Cheats));
+}
+
+
+static void InitializeNameMgr(void)
+{
+ memset(_name_array, 0, sizeof(_name_array));
+}
+
+StringID RealAllocateName(const char *name, byte skip, bool check_double)
+{
+ char (*free_item)[lengthof(*_name_array)] = NULL;
+ char (*i)[lengthof(*_name_array)];
+
+ for (i = _name_array; i != endof(_name_array); ++i) {
+ if ((*i)[0] == '\0') {
+ if (free_item == NULL) free_item = i;
+ } else if (check_double && strncmp(*i, name, lengthof(*i) - 1) == 0) {
+ _error_message = STR_0132_CHOSEN_NAME_IN_USE_ALREADY;
+ return 0;
+ }
+ }
+
+ if (free_item != NULL) {
+ ttd_strlcpy(*free_item, name, lengthof(*free_item));
+ return (free_item - _name_array) | 0x7800 | (skip << 8);
+ } else {
+ _error_message = STR_0131_TOO_MANY_NAMES_DEFINED;
+ return 0;
+ }
+}
+
+void ConvertNameArray(void)
+{
+ uint i;
+
+ for (i = 0; i < lengthof(_name_array); i++) {
+ const char *strfrom = _name_array[i];
+ char tmp[sizeof(*_name_array)];
+ char *strto = tmp;
+
+ for (; *strfrom != '\0'; strfrom++) {
+ WChar c = (byte)*strfrom;
+ switch (c) {
+ case 0xA4: c = 0x20AC; break; // Euro
+ case 0xA6: c = 0x0160; break; // S with caron
+ case 0xA8: c = 0x0161; break; // s with caron
+ case 0xB4: c = 0x017D; break; // Z with caron
+ case 0xB8: c = 0x017E; break; // z with caron
+ case 0xBC: c = 0x0152; break; // OE ligature
+ case 0xBD: c = 0x0153; break; // oe ligature
+ case 0xBE: c = 0x0178; break; // Y with diaresis
+ default: break;
+ }
+ if (strto + Utf8CharLen(c) > lastof(tmp)) break;
+ strto += Utf8Encode(strto, c);
+ }
+
+ /* Terminate the new string and copy it back to the name array */
+ *strto = '\0';
+ memcpy(_name_array[i], tmp, sizeof(*_name_array));
+ }
+}
+
+// Calculate constants that depend on the landscape type.
+void InitializeLandscapeVariables(bool only_constants)
+{
+ const CargoTypesValues *lpd;
+ uint i;
+ StringID str;
+
+ lpd = &_cargo_types_base_values[_opt.landscape];
+
+ for (i = 0; i != NUM_CARGO; i++) {
+ _cargoc.sprites[i] = lpd->sprites[i];
+
+ str = lpd->names[i];
+ _cargoc.names_s[i] = str;
+ _cargoc.names_long[i] = (str += 0x40);
+ _cargoc.names_short[i] = (str += 0x20);
+ _cargoc.weights[i] = lpd->weights[i];
+
+ if (!only_constants) {
+ _cargo_payment_rates[i] = lpd->initial_cargo_payment[i];
+ _cargo_payment_rates_frac[i] = 0;
+ }
+
+ _cargoc.transit_days_1[i] = lpd->transit_days_table_1[i];
+ _cargoc.transit_days_2[i] = lpd->transit_days_table_2[i];
+ }
+}
+
+
+
+int FindFirstBit(uint32 value)
+{
+ // This is much faster than the one that was before here.
+ // Created by Darkvater.. blame him if it is wrong ;)
+ // Btw, the macro FINDFIRSTBIT is better to use when your value is
+ // not more than 128.
+ byte i = 0;
+ if (value & 0xffff0000) { value >>= 16; i += 16; }
+ if (value & 0x0000ff00) { value >>= 8; i += 8; }
+ if (value & 0x000000f0) { value >>= 4; i += 4; }
+ if (value & 0x0000000c) { value >>= 2; i += 2; }
+ if (value & 0x00000002) { i += 1; }
+ return i;
+}
+
+
+static void Save_NAME(void)
+{
+ int i;
+
+ for (i = 0; i != lengthof(_name_array); ++i) {
+ if (_name_array[i][0] != '\0') {
+ SlSetArrayIndex(i);
+ SlArray(_name_array[i], (uint)strlen(_name_array[i]), SLE_UINT8);
+ }
+ }
+}
+
+static void Load_NAME(void)
+{
+ int index;
+
+ while ((index = SlIterateArray()) != -1) {
+ SlArray(_name_array[index],SlGetFieldLength(),SLE_UINT8);
+ }
+}
+
+static const SaveLoadGlobVarList _date_desc[] = {
+ SLEG_CONDVAR(_date, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
+ SLEG_CONDVAR(_date, SLE_INT32, 31, SL_MAX_VERSION),
+ SLEG_VAR(_date_fract, SLE_UINT16),
+ SLEG_VAR(_tick_counter, SLE_UINT16),
+ SLEG_VAR(_vehicle_id_ctr_day, SLE_UINT16),
+ SLEG_VAR(_age_cargo_skip_counter, SLE_UINT8),
+ SLEG_VAR(_avail_aircraft, SLE_UINT8),
+ SLEG_CONDVAR(_cur_tileloop_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+ SLEG_CONDVAR(_cur_tileloop_tile, SLE_UINT32, 6, SL_MAX_VERSION),
+ SLEG_VAR(_disaster_delay, SLE_UINT16),
+ SLEG_VAR(_station_tick_ctr, SLE_UINT16),
+ SLEG_VAR(_random_seeds[0][0], SLE_UINT32),
+ SLEG_VAR(_random_seeds[0][1], SLE_UINT32),
+ SLEG_CONDVAR(_cur_town_ctr, SLE_FILE_U8 | SLE_VAR_U32, 0, 9),
+ SLEG_CONDVAR(_cur_town_ctr, SLE_UINT32, 10, SL_MAX_VERSION),
+ SLEG_VAR(_cur_player_tick_index, SLE_FILE_U8 | SLE_VAR_U32),
+ SLEG_VAR(_next_competitor_start, SLE_FILE_U16 | SLE_VAR_U32),
+ SLEG_VAR(_trees_tick_ctr, SLE_UINT8),
+ SLEG_CONDVAR(_pause, SLE_UINT8, 4, SL_MAX_VERSION),
+ SLEG_CONDVAR(_cur_town_iter, SLE_UINT32, 11, SL_MAX_VERSION),
+ SLEG_END()
+};
+
+// Save load date related variables as well as persistent tick counters
+// XXX: currently some unrelated stuff is just put here
+static void SaveLoad_DATE(void)
+{
+ SlGlobList(_date_desc);
+}
+
+
+static const SaveLoadGlobVarList _view_desc[] = {
+ SLEG_CONDVAR(_saved_scrollpos_x, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
+ SLEG_CONDVAR(_saved_scrollpos_x, SLE_INT32, 6, SL_MAX_VERSION),
+ SLEG_CONDVAR(_saved_scrollpos_y, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
+ SLEG_CONDVAR(_saved_scrollpos_y, SLE_INT32, 6, SL_MAX_VERSION),
+ SLEG_VAR(_saved_scrollpos_zoom, SLE_UINT8),
+ SLEG_END()
+};
+
+static void SaveLoad_VIEW(void)
+{
+ SlGlobList(_view_desc);
+}
+
+static uint32 _map_dim_x;
+static uint32 _map_dim_y;
+
+static const SaveLoadGlobVarList _map_dimensions[] = {
+ SLEG_CONDVAR(_map_dim_x, SLE_UINT32, 6, SL_MAX_VERSION),
+ SLEG_CONDVAR(_map_dim_y, SLE_UINT32, 6, SL_MAX_VERSION),
+ SLEG_END()
+};
+
+static void Save_MAPS(void)
+{
+ _map_dim_x = MapSizeX();
+ _map_dim_y = MapSizeY();
+ SlGlobList(_map_dimensions);
+}
+
+static void Load_MAPS(void)
+{
+ SlGlobList(_map_dimensions);
+ AllocateMap(_map_dim_x, _map_dim_y);
+}
+
+static void Load_MAPT(void)
+{
+ uint size = MapSize();
+ uint i;
+
+ for (i = 0; i != size;) {
+ byte buf[4096];
+ uint j;
+
+ SlArray(buf, lengthof(buf), SLE_UINT8);
+ for (j = 0; j != lengthof(buf); j++) _m[i++].type_height = buf[j];
+ }
+}
+
+static void Save_MAPT(void)
+{
+ uint size = MapSize();
+ uint i;
+
+ SlSetLength(size);
+ for (i = 0; i != size;) {
+ byte buf[4096];
+ uint j;
+
+ for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].type_height;
+ SlArray(buf, lengthof(buf), SLE_UINT8);
+ }
+}
+
+static void Load_MAP1(void)
+{
+ uint size = MapSize();
+ uint i;
+
+ for (i = 0; i != size;) {
+ byte buf[4096];
+ uint j;
+
+ SlArray(buf, lengthof(buf), SLE_UINT8);
+ for (j = 0; j != lengthof(buf); j++) _m[i++].m1 = buf[j];
+ }
+}
+
+static void Save_MAP1(void)
+{
+ uint size = MapSize();
+ uint i;
+
+ SlSetLength(size);
+ for (i = 0; i != size;) {
+ byte buf[4096];
+ uint j;
+
+ for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].m1;
+ SlArray(buf, lengthof(buf), SLE_UINT8);
+ }
+}
+
+static void Load_MAP2(void)
+{
+ uint size = MapSize();
+ uint i;
+
+ for (i = 0; i != size;) {
+ uint16 buf[4096];
+ uint j;
+
+ SlArray(buf, lengthof(buf),
+ /* In those versions the m2 was 8 bits */
+ CheckSavegameVersion(5) ? SLE_FILE_U8 | SLE_VAR_U16 : SLE_UINT16
+ );
+ for (j = 0; j != lengthof(buf); j++) _m[i++].m2 = buf[j];
+ }
+}
+
+static void Save_MAP2(void)
+{
+ uint size = MapSize();
+ uint i;
+
+ SlSetLength(size * sizeof(_m[0].m2));
+ for (i = 0; i != size;) {
+ uint16 buf[4096];
+ uint j;
+
+ for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].m2;
+ SlArray(buf, lengthof(buf), SLE_UINT16);
+ }
+}
+
+static void Load_MAP3(void)
+{
+ uint size = MapSize();
+ uint i;
+
+ for (i = 0; i != size;) {
+ byte buf[4096];
+ uint j;
+
+ SlArray(buf, lengthof(buf), SLE_UINT8);
+ for (j = 0; j != lengthof(buf); j++) _m[i++].m3 = buf[j];
+ }
+}
+
+static void Save_MAP3(void)
+{
+ uint size = MapSize();
+ uint i;
+
+ SlSetLength(size);
+ for (i = 0; i != size;) {
+ byte buf[4096];
+ uint j;
+
+ for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].m3;
+ SlArray(buf, lengthof(buf), SLE_UINT8);
+ }
+}
+
+static void Load_MAP4(void)
+{
+ uint size = MapSize();
+ uint i;
+
+ for (i = 0; i != size;) {
+ byte buf[4096];
+ uint j;
+
+ SlArray(buf, lengthof(buf), SLE_UINT8);
+ for (j = 0; j != lengthof(buf); j++) _m[i++].m4 = buf[j];
+ }
+}
+
+static void Save_MAP4(void)
+{
+ uint size = MapSize();
+ uint i;
+
+ SlSetLength(size);
+ for (i = 0; i != size;) {
+ byte buf[4096];
+ uint j;
+
+ for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].m4;
+ SlArray(buf, lengthof(buf), SLE_UINT8);
+ }
+}
+
+static void Load_MAP5(void)
+{
+ uint size = MapSize();
+ uint i;
+
+ for (i = 0; i != size;) {
+ byte buf[4096];
+ uint j;
+
+ SlArray(buf, lengthof(buf), SLE_UINT8);
+ for (j = 0; j != lengthof(buf); j++) _m[i++].m5 = buf[j];
+ }
+}
+
+static void Save_MAP5(void)
+{
+ uint size = MapSize();
+ uint i;
+
+ SlSetLength(size);
+ for (i = 0; i != size;) {
+ byte buf[4096];
+ uint j;
+
+ for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].m5;
+ SlArray(buf, lengthof(buf), SLE_UINT8);
+ }
+}
+
+static void Load_MAPE(void)
+{
+ uint size = MapSize();
+ uint i;
+
+ if (CheckSavegameVersion(42)) {
+ for (i = 0; i != size;) {
+ uint8 buf[1024];
+ uint j;
+
+ SlArray(buf, lengthof(buf), SLE_UINT8);
+ for (j = 0; j != lengthof(buf); j++) {
+ _m[i++].extra = GB(buf[j], 0, 2);
+ _m[i++].extra = GB(buf[j], 2, 2);
+ _m[i++].extra = GB(buf[j], 4, 2);
+ _m[i++].extra = GB(buf[j], 6, 2);
+ }
+ }
+ } else {
+ for (i = 0; i != size;) {
+ byte buf[4096];
+ uint j;
+
+ SlArray(buf, lengthof(buf), SLE_UINT8);
+ for (j = 0; j != lengthof(buf); j++) _m[i++].extra = buf[j];
+ }
+ }
+}
+
+static void Save_MAPE(void)
+{
+ uint size = MapSize();
+ uint i;
+
+ SlSetLength(size);
+ for (i = 0; i != size;) {
+ uint8 buf[4096];
+ uint j;
+
+ for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].extra;
+ SlArray(buf, lengthof(buf), SLE_UINT8);
+ }
+}
+
+
+static void Save_CHTS(void)
+{
+ byte count = sizeof(_cheats)/sizeof(Cheat);
+ Cheat* cht = (Cheat*) &_cheats;
+ Cheat* cht_last = &cht[count];
+
+ SlSetLength(count * 2);
+ for (; cht != cht_last; cht++) {
+ SlWriteByte(cht->been_used);
+ SlWriteByte(cht->value);
+ }
+}
+
+static void Load_CHTS(void)
+{
+ Cheat* cht = (Cheat*)&_cheats;
+ uint count = SlGetFieldLength() / 2;
+ uint i;
+
+ for (i = 0; i < count; i++) {
+ cht[i].been_used = SlReadByte();
+ cht[i].value = SlReadByte();
+ }
+}
+
+
+const ChunkHandler _misc_chunk_handlers[] = {
+ { 'MAPS', Save_MAPS, Load_MAPS, CH_RIFF },
+ { 'MAPT', Save_MAPT, Load_MAPT, CH_RIFF },
+ { 'MAPO', Save_MAP1, Load_MAP1, CH_RIFF },
+ { 'MAP2', Save_MAP2, Load_MAP2, CH_RIFF },
+ { 'M3LO', Save_MAP3, Load_MAP3, CH_RIFF },
+ { 'M3HI', Save_MAP4, Load_MAP4, CH_RIFF },
+ { 'MAP5', Save_MAP5, Load_MAP5, CH_RIFF },
+ { 'MAPE', Save_MAPE, Load_MAPE, CH_RIFF },
+
+ { 'NAME', Save_NAME, Load_NAME, CH_ARRAY},
+ { 'DATE', SaveLoad_DATE, SaveLoad_DATE, CH_RIFF},
+ { 'VIEW', SaveLoad_VIEW, SaveLoad_VIEW, CH_RIFF},
+ { 'CHTS', Save_CHTS, Load_CHTS, CH_RIFF | CH_LAST}
+};
diff --git a/src/misc_cmd.c b/src/misc_cmd.c
new file mode 100644
index 000000000..94b675531
--- /dev/null
+++ b/src/misc_cmd.c
@@ -0,0 +1,336 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "functions.h"
+#include "string.h"
+#include "table/strings.h"
+#include "command.h"
+#include "player.h"
+#include "gfx.h"
+#include "window.h"
+#include "gui.h"
+#include "economy.h"
+#include "network/network.h"
+#include "variables.h"
+#include "livery.h"
+
+/** Change the player's face.
+ * @param tile unused
+ * @param p1 unused
+ * @param p2 face bitmasked
+ */
+int32 CmdSetPlayerFace(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ if (flags & DC_EXEC) {
+ GetPlayer(_current_player)->face = p2;
+ MarkWholeScreenDirty();
+ }
+ return 0;
+}
+
+/** Change the player's company-colour
+ * @param tile unused
+ * @param p1 bitstuffed:
+ * p1 bits 0-7 scheme to set
+ * p1 bits 8-9 set in use state or first/second colour
+ * @param p2 new colour for vehicles, property, etc.
+ */
+int32 CmdSetPlayerColor(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Player *p, *pp;
+ byte colour;
+ LiveryScheme scheme = GB(p1, 0, 8);
+ byte state = GB(p1, 8, 2);
+
+ if (p2 >= 16) return CMD_ERROR; // max 16 colours
+ colour = p2;
+
+ if (scheme >= LS_END || state >= 3) return CMD_ERROR;
+
+ p = GetPlayer(_current_player);
+
+ /* Ensure no two companies have the same primary colour */
+ if (scheme == LS_DEFAULT && state == 0) {
+ FOR_ALL_PLAYERS(pp) {
+ if (pp->is_active && pp != p && pp->player_color == colour) return CMD_ERROR;
+ }
+ }
+
+ if (flags & DC_EXEC) {
+ switch (state) {
+ case 0:
+ p->livery[scheme].colour1 = colour;
+
+ /* If setting the first colour of the default scheme, adjust the
+ * original and cached player colours too. */
+ if (scheme == LS_DEFAULT) {
+ _player_colors[_current_player] = colour;
+ p->player_color = colour;
+ }
+ break;
+
+ case 1:
+ p->livery[scheme].colour2 = colour;
+ break;
+
+ case 2:
+ p->livery[scheme].in_use = colour != 0;
+
+ /* Now handle setting the default scheme's in_use flag.
+ * This is different to the other schemes, as it signifies if any
+ * scheme is active at all. If this flag is not set, then no
+ * processing of vehicle types occurs at all, and only the default
+ * colours will be used. */
+
+ /* If enabling a scheme, set the default scheme to be in use too */
+ if (colour != 0) {
+ p->livery[LS_DEFAULT].in_use = true;
+ break;
+ }
+
+ /* Else loop through all schemes to see if any are left enabled.
+ * If not, disable the default scheme too. */
+ p->livery[LS_DEFAULT].in_use = false;
+ for (scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
+ if (p->livery[scheme].in_use) {
+ p->livery[LS_DEFAULT].in_use = true;
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ MarkWholeScreenDirty();
+ }
+ return 0;
+}
+
+/** Increase the loan of your company.
+ * @param tile unused
+ * @param p1 unused
+ * @param p2 when set, loans the maximum amount in one go (press CTRL)
+ */
+int32 CmdIncreaseLoan(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Player *p;
+
+ p = GetPlayer(_current_player);
+
+ if (p->current_loan >= _economy.max_loan) {
+ SetDParam(0, _economy.max_loan);
+ return_cmd_error(STR_702B_MAXIMUM_PERMITTED_LOAN);
+ }
+
+ if (flags & DC_EXEC) {
+ /* Loan the maximum amount or not? */
+ int32 loan = (p2) ? _economy.max_loan - p->current_loan : (IsHumanPlayer(_current_player) || _patches.ainew_active) ? 10000 : 50000;
+
+ p->money64 += loan;
+ p->current_loan += loan;
+ UpdatePlayerMoney32(p);
+ InvalidatePlayerWindows(p);
+ }
+
+ return 0;
+}
+
+/** Decrease the loan of your company.
+ * @param tile unused
+ * @param p1 unused
+ * @param p2 when set, pays back the maximum loan permitting money (press CTRL)
+ */
+int32 CmdDecreaseLoan(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Player *p;
+ int32 loan;
+
+ p = GetPlayer(_current_player);
+
+ if (p->current_loan == 0) return_cmd_error(STR_702D_LOAN_ALREADY_REPAYED);
+
+ loan = p->current_loan;
+
+ /* p2 is true while CTRL is pressed (repay all possible loan, or max money you have)
+ * Repay any loan in chunks of 10.000 pounds */
+ if (p2) {
+ loan = min(loan, p->player_money);
+ loan = max(loan, 10000);
+ loan -= loan % 10000;
+ } else {
+ loan = min(loan, (IsHumanPlayer(_current_player) || _patches.ainew_active) ? 10000 : 50000);
+ }
+
+ if (p->player_money < loan) {
+ SetDParam(0, loan);
+ return_cmd_error(STR_702E_REQUIRED);
+ }
+
+ if (flags & DC_EXEC) {
+ p->money64 -= loan;
+ p->current_loan -= loan;
+ UpdatePlayerMoney32(p);
+ InvalidatePlayerWindows(p);
+ }
+ return 0;
+}
+
+/** Change the name of the company.
+ * @param tile unused
+ * @param p1 unused
+ * @param p2 unused
+ */
+int32 CmdChangeCompanyName(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ StringID str;
+ Player *p;
+
+ if (_cmd_text[0] == '\0') return CMD_ERROR;
+
+ str = AllocateNameUnique(_cmd_text, 4);
+ if (str == 0) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ p = GetPlayer(_current_player);
+ DeleteName(p->name_1);
+ p->name_1 = str;
+ MarkWholeScreenDirty();
+ } else {
+ DeleteName(str);
+ }
+
+ return 0;
+}
+
+/** Change the name of the president.
+ * @param tile unused
+ * @param p1 unused
+ * @param p2 unused
+ */
+int32 CmdChangePresidentName(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ StringID str;
+ Player *p;
+
+ if (_cmd_text[0] == '\0') return CMD_ERROR;
+
+ str = AllocateNameUnique(_cmd_text, 4);
+ if (str == 0) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ p = GetPlayer(_current_player);
+ DeleteName(p->president_name_1);
+ p->president_name_1 = str;
+
+ if (p->name_1 == STR_SV_UNNAMED) {
+ char buf[80];
+
+ snprintf(buf, lengthof(buf), "%s Transport", _cmd_text);
+ _cmd_text = buf;
+ DoCommand(0, 0, 0, DC_EXEC, CMD_CHANGE_COMPANY_NAME);
+ }
+ MarkWholeScreenDirty();
+ } else {
+ DeleteName(str);
+ }
+
+ return 0;
+}
+
+/** Pause/Unpause the game (server-only).
+ * Increase or decrease the pause counter. If the counter is zero,
+ * the game is unpaused. A counter is used instead of a boolean value
+ * to have more control over the game when saving/loading, etc.
+ * @param tile unused
+ * @param p1 0 = decrease pause counter; 1 = increase pause counter
+ * @param p2 unused
+ */
+int32 CmdPause(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ if (flags & DC_EXEC) {
+ _pause += (p1 == 1) ? 1 : -1;
+ if (_pause == (byte)-1) _pause = 0;
+ InvalidateWindow(WC_STATUS_BAR, 0);
+ InvalidateWindow(WC_MAIN_TOOLBAR, 0);
+ }
+ return 0;
+}
+
+/** Change the financial flow of your company.
+ * This is normally only enabled in offline mode, but if there is a debug
+ * build, you can cheat (to test).
+ * @param tile unused
+ * @param p1 the amount of money to receive (if negative), or spend (if positive)
+ * @param p2 unused
+ */
+int32 CmdMoneyCheat(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+#ifndef _DEBUG
+ if (_networking) return CMD_ERROR;
+#endif
+ SET_EXPENSES_TYPE(EXPENSES_OTHER);
+ return (int32)p1;
+}
+
+/** Transfer funds (money) from one player to another.
+ * To prevent abuse in multiplayer games you can only send money to other
+ * players if you have paid off your loan (either explicitely, or implicitely
+ * given the fact that you have more money than loan).
+ * @param tile unused
+ * @param p1 the amount of money to transfer; max 20.000.000
+ * @param p2 the player to transfer the money to
+ */
+int32 CmdGiveMoney(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ const Player *p = GetPlayer(_current_player);
+ int32 amount = min((int32)p1, 20000000);
+
+ SET_EXPENSES_TYPE(EXPENSES_OTHER);
+
+ /* You can only transfer funds that is in excess of your loan */
+ if (p->money64 - p->current_loan < amount || amount <= 0) return CMD_ERROR;
+ if (!_networking || !IsValidPlayer((PlayerID)p2)) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ /* Add money to player */
+ PlayerID old_cp = _current_player;
+ _current_player = p2;
+ SubtractMoneyFromPlayer(-amount);
+ _current_player = old_cp;
+ }
+
+ /* Subtract money from local-player */
+ return amount;
+}
+
+/** Change difficulty level/settings (server-only).
+ * We cannot really check for valid values of p2 (too much work mostly); stored
+ * in file 'settings_gui.c' _game_setting_info[]; we'll just trust the server it knows
+ * what to do and does this correctly
+ * @param tile unused
+ * @param p1 the difficulty setting being changed. If it is -1, the difficulty level
+ * itself is changed. The new value is inside p2
+ * @param p2 new value for a difficulty setting or difficulty level
+ */
+int32 CmdChangeDifficultyLevel(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ if (p1 != (uint32)-1L && ((int32)p1 >= GAME_DIFFICULTY_NUM || (int32)p1 < 0)) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ if (p1 != (uint32)-1L) {
+ ((int*)&_opt_ptr->diff)[p1] = p2;
+ _opt_ptr->diff_level = 3; // custom difficulty level
+ } else {
+ _opt_ptr->diff_level = p2;
+ }
+
+ /* If we are a network-client, update the difficult setting (if it is open).
+ * Use this instead of just dirtying the window because we need to load in
+ * the new difficulty settings */
+ if (_networking && !_network_server && FindWindowById(WC_GAME_OPTIONS, 0) != NULL)
+ ShowGameDifficulty();
+ }
+ return 0;
+}
diff --git a/src/misc_gui.c b/src/misc_gui.c
new file mode 100644
index 000000000..693272c2f
--- /dev/null
+++ b/src/misc_gui.c
@@ -0,0 +1,1912 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "hal.h"
+#include "heightmap.h"
+#include "debug.h"
+#include "functions.h"
+#include "newgrf.h"
+#include "saveload.h"
+#include "strings.h"
+#include "table/sprites.h"
+#include "table/strings.h"
+#include "table/tree_land.h"
+#include "map.h"
+#include "window.h"
+#include "gui.h"
+#include "viewport.h"
+#include "gfx.h"
+#include "station.h"
+#include "command.h"
+#include "player.h"
+#include "town.h"
+#include "sound.h"
+#include "network/network.h"
+#include "string.h"
+#include "variables.h"
+#include "vehicle.h"
+#include "train.h"
+#include "tgp.h"
+#include "settings.h"
+#include "date.h"
+
+#include "fios.h"
+/* Variables to display file lists */
+FiosItem *_fios_list;
+int _saveload_mode;
+
+extern void GenerateLandscape(byte mode);
+extern void SwitchMode(int new_mode);
+
+static bool _fios_path_changed;
+static bool _savegame_sort_dirty;
+
+typedef struct LandInfoData {
+ Town *town;
+ int32 costclear;
+ AcceptedCargo ac;
+ TileIndex tile;
+ TileDesc td;
+} LandInfoData;
+
+static void LandInfoWndProc(Window *w, WindowEvent *e)
+{
+ if (e->event == WE_PAINT) {
+ const LandInfoData *lid;
+ StringID str;
+ int i;
+
+ DrawWindowWidgets(w);
+
+ lid = WP(w,void_d).data;
+
+ SetDParam(0, lid->td.dparam[0]);
+ DrawStringCentered(140, 16, lid->td.str, 13);
+
+ SetDParam(0, STR_01A6_N_A);
+ if (lid->td.owner != OWNER_NONE && lid->td.owner != OWNER_WATER)
+ GetNameOfOwner(lid->td.owner, lid->tile);
+ DrawStringCentered(140, 27, STR_01A7_OWNER, 0);
+
+ str = STR_01A4_COST_TO_CLEAR_N_A;
+ if (!CmdFailed(lid->costclear)) {
+ SetDParam(0, lid->costclear);
+ str = STR_01A5_COST_TO_CLEAR;
+ }
+ DrawStringCentered(140, 38, str, 0);
+
+ snprintf(_userstring, lengthof(_userstring), "0x%.4X", lid->tile);
+ SetDParam(0, TileX(lid->tile));
+ SetDParam(1, TileY(lid->tile));
+ SetDParam(2, STR_SPEC_USERSTRING);
+ DrawStringCentered(140, 49, STR_LANDINFO_COORDS, 0);
+
+ SetDParam(0, STR_01A9_NONE);
+ if (lid->town != NULL) {
+ SetDParam(0, STR_TOWN);
+ SetDParam(1, lid->town->index);
+ }
+ DrawStringCentered(140,60, STR_01A8_LOCAL_AUTHORITY, 0);
+
+ {
+ char buf[512];
+ char *p = GetString(buf, STR_01CE_CARGO_ACCEPTED, lastof(buf));
+ bool found = false;
+
+ for (i = 0; i < NUM_CARGO; ++i) {
+ if (lid->ac[i] > 0) {
+ // Add a comma between each item.
+ if (found) {
+ *p++ = ',';
+ *p++ = ' ';
+ }
+ found = true;
+
+ // If the accepted value is less than 8, show it in 1/8:ths
+ if (lid->ac[i] < 8) {
+ SetDParam(0, lid->ac[i]);
+ SetDParam(1, _cargoc.names_s[i]);
+ p = GetString(p, STR_01D1_8, lastof(buf));
+ } else {
+ p = GetString(p, _cargoc.names_s[i], lastof(buf));
+ }
+ }
+ }
+
+ if (found) DrawStringMultiCenter(140, 76, BindCString(buf), 276);
+ }
+
+ if (lid->td.build_date != 0) {
+ SetDParam(0,lid->td.build_date);
+ DrawStringCentered(140,71, STR_BUILD_DATE, 0);
+ }
+ }
+}
+
+static const Widget _land_info_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 279, 0, 13, STR_01A3_LAND_AREA_INFORMATION, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 279, 14, 92, 0x0, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _land_info_desc = {
+ WDP_AUTO, WDP_AUTO, 280, 93,
+ WC_LAND_INFO,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _land_info_widgets,
+ LandInfoWndProc
+};
+
+static void Place_LandInfo(TileIndex tile)
+{
+ Player *p;
+ static LandInfoData lid;
+ Window *w;
+ int64 old_money;
+
+ DeleteWindowById(WC_LAND_INFO, 0);
+
+ w = AllocateWindowDesc(&_land_info_desc);
+ WP(w,void_d).data = &lid;
+
+ lid.tile = tile;
+ lid.town = ClosestTownFromTile(tile, _patches.dist_local_authority);
+
+ p = GetPlayer(IsValidPlayer(_local_player) ? _local_player : 0);
+
+ old_money = p->money64;
+ p->money64 = p->player_money = 0x7fffffff;
+ lid.costclear = DoCommand(tile, 0, 0, 0, CMD_LANDSCAPE_CLEAR);
+ p->money64 = old_money;
+ UpdatePlayerMoney32(p);
+
+ // Becuase build_date is not set yet in every TileDesc, we make sure it is empty
+ lid.td.build_date = 0;
+
+ GetAcceptedCargo(tile, lid.ac);
+ GetTileDesc(tile, &lid.td);
+
+#if defined(_DEBUG)
+# define LANDINFOD_LEVEL 0
+#else
+# define LANDINFOD_LEVEL 1
+#endif
+ DEBUG(misc, LANDINFOD_LEVEL, "TILE: %#x (%i,%i)", tile, TileX(tile), TileY(tile));
+ DEBUG(misc, LANDINFOD_LEVEL, "type_height = %#x", _m[tile].type_height);
+ DEBUG(misc, LANDINFOD_LEVEL, "m1 = %#x", _m[tile].m1);
+ DEBUG(misc, LANDINFOD_LEVEL, "m2 = %#x", _m[tile].m2);
+ DEBUG(misc, LANDINFOD_LEVEL, "m3 = %#x", _m[tile].m3);
+ DEBUG(misc, LANDINFOD_LEVEL, "m4 = %#x", _m[tile].m4);
+ DEBUG(misc, LANDINFOD_LEVEL, "m5 = %#x", _m[tile].m5);
+ DEBUG(misc, LANDINFOD_LEVEL, "extra = %#x", _m[tile].extra);
+#undef LANDINFOD_LEVEL
+}
+
+void PlaceLandBlockInfo(void)
+{
+ if (_cursor.sprite == SPR_CURSOR_QUERY) {
+ ResetObjectToPlace();
+ } else {
+ _place_proc = Place_LandInfo;
+ SetObjectToPlace(SPR_CURSOR_QUERY, 1, 1, 0);
+ }
+}
+
+static const char *credits[] = {
+ /*************************************************************************
+ * maximum length of string which fits in window -^*/
+ "Original design by Chris Sawyer",
+ "Original graphics by Simon Foster",
+ "",
+ "The OpenTTD team (in alphabetical order):",
+ " Jean-Francois Claeys (Belugas) - In training, not yet specialized",
+ " Bjarni Corfitzen (Bjarni) - MacOSX port, coder",
+ " Matthijs Kooijman (blathijs) - Pathfinder-guru",
+ " Victor Fischer (Celestar) - Programming everywhere you need him to",
+ " Tamás Faragó (Darkvater) - Lead coder",
+ " Loïc Guilloux (glx) - In training, not yet specialized",
+ " Jaroslav Mazanec (KUDr) - YAPG (Yet Another Pathfinder God) ;)",
+ " Attila Bán (MiHaMiX) - WebTranslator, Nightlies, Wiki and bugtracker host",
+ " Peter Nelson (peter1138) - Spiritual descendant from newgrf gods",
+ " Remko Bijker (Rubidium) - Belugas code scrutinizer",
+ " Christoph Mallon (Tron) - Programmer, code correctness police",
+ " Patric Stout (TrueLight) - Coder, network guru, SVN- and website host",
+ "",
+ "Retired Developers:",
+ " Ludvig Strigeus (ludde) - OpenTTD author, main coder (0.1 - 0.3.3)",
+ " Serge Paquet (vurlix) - Assistant project manager, coder (0.1 - 0.3.3)",
+ " Dominik Scherer (dominik81) - Lead programmer, GUI expert (0.3.0 - 0.3.6)",
+ " Owen Rudge (orudge) - Forum- and masterserver host, OS/2 port (0.1 - 0.4.8)",
+ "",
+ "Special thanks go out to:",
+ " Josef Drexler - For his great work on TTDPatch",
+ " Marcin Grzegorczyk - For his documentation of TTD internals",
+ " Petr Baudis (pasky) - Many patches, newgrf support",
+ " Stefan Meißner (sign_de) - For his work on the console",
+ " Simon Sasburg (HackyKid) - Many bugfixes he has blessed us with (and PBS)",
+ " Cian Duffy (MYOB) - BeOS port / manual writing",
+ " Christian Rosentreter (tokai) - MorphOS / AmigaOS port",
+ " Richard Kempton (richK) - additional airports, initial TGP implementation",
+ "",
+ " Michael Blunck - Pre-Signals and Semaphores © 2003",
+ " George - Canal/Lock graphics © 2003-2004",
+ " Marcin Grzegorczyk - Foundations for Tracks on Slopes",
+ " All Translators - Who made OpenTTD a truly international game",
+ " Bug Reporters - Without whom OpenTTD would still be full of bugs!",
+ "",
+ "",
+ "And last but not least:",
+ " Chris Sawyer - For an amazing game!"
+};
+
+static void AboutWindowProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_CREATE: /* Set up window counter and start position of scroller */
+ WP(w, scroller_d).counter = 0;
+ WP(w, scroller_d).height = w->height - 40;
+ break;
+ case WE_PAINT: {
+ uint i;
+ int y = WP(w, scroller_d).height;
+ DrawWindowWidgets(w);
+
+ // Show original copyright and revision version
+ DrawStringCentered(210, 17, STR_00B6_ORIGINAL_COPYRIGHT, 0);
+ DrawStringCentered(210, 17 + 10, STR_00B7_VERSION, 0);
+
+ // Show all scrolling credits
+ for (i = 0; i < lengthof(credits); i++) {
+ if (y >= 50 && y < (w->height - 40)) {
+ DoDrawString(credits[i], 10, y, 0x10);
+ }
+ y += 10;
+ }
+
+ // If the last text has scrolled start anew from the start
+ if (y < 50) WP(w, scroller_d).height = w->height - 40;
+
+ DoDrawStringCentered(210, w->height - 25, "Website: http://www.openttd.org", 16);
+ DrawStringCentered(210, w->height - 15, STR_00BA_COPYRIGHT_OPENTTD, 0);
+ } break;
+ case WE_MOUSELOOP: /* Timer to scroll the text and adjust the new top */
+ if (WP(w, scroller_d).counter++ % 3 == 0) {
+ WP(w, scroller_d).height--;
+ SetWindowDirty(w);
+ }
+ break;
+ }
+}
+
+static const Widget _about_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 419, 0, 13, STR_015B_OPENTTD, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 419, 14, 271, 0x0, STR_NULL},
+{ WWT_FRAME, RESIZE_NONE, 14, 5, 414, 40, 245, STR_NULL, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _about_desc = {
+ WDP_CENTER, WDP_CENTER, 420, 272,
+ WC_GAME_OPTIONS,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _about_widgets,
+ AboutWindowProc
+};
+
+
+void ShowAboutWindow(void)
+{
+ DeleteWindowById(WC_GAME_OPTIONS, 0);
+ AllocateWindowDesc(&_about_desc);
+}
+
+static int _tree_to_plant;
+
+static const uint32 _tree_sprites[] = {
+ 0x655, 0x663, 0x678, 0x62B, 0x647, 0x639, 0x64E, 0x632, 0x67F, 0x68D, 0x69B, 0x6A9,
+ 0x6AF, 0x6D2, 0x6D9, 0x6C4, 0x6CB, 0x6B6, 0x6BD, 0x6E0,
+ 0x72E, 0x734, 0x74A, 0x74F, 0x76B, 0x78F, 0x788, 0x77B, 0x75F, 0x774, 0x720, 0x797,
+ 0x79E, 0x7A5 | PALETTE_TO_GREEN, 0x7AC | PALETTE_TO_RED, 0x7B3, 0x7BA, 0x7C1 | PALETTE_TO_RED, 0x7C8 | PALETTE_TO_PALE_GREEN, 0x7CF | PALETTE_TO_YELLOW, 0x7D6 | PALETTE_TO_RED
+};
+
+static void BuildTreesWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ int x,y;
+ int i, count;
+
+ DrawWindowWidgets(w);
+
+ WP(w,tree_d).base = i = _tree_base_by_landscape[_opt.landscape];
+ WP(w,tree_d).count = count = _tree_count_by_landscape[_opt.landscape];
+
+ x = 18;
+ y = 54;
+ do {
+ DrawSprite(_tree_sprites[i], x, y);
+ x += 35;
+ if (!(++i & 3)) {
+ x -= 35 * 4;
+ y += 47;
+ }
+ } while (--count);
+ } break;
+
+ case WE_CLICK: {
+ int wid = e->we.click.widget;
+
+ switch (wid) {
+ case 0:
+ ResetObjectToPlace();
+ break;
+
+ case 3: case 4: case 5: case 6:
+ case 7: case 8: case 9: case 10:
+ case 11:case 12: case 13: case 14:
+ if (wid - 3 >= WP(w,tree_d).count) break;
+
+ if (HandlePlacePushButton(w, wid, SPR_CURSOR_TREE, 1, NULL))
+ _tree_to_plant = WP(w,tree_d).base + wid - 3;
+ break;
+
+ case 15: // tree of random type.
+ if (HandlePlacePushButton(w, 15, SPR_CURSOR_TREE, 1, NULL))
+ _tree_to_plant = -1;
+ break;
+
+ case 16: /* place trees randomly over the landscape*/
+ LowerWindowWidget(w, 16);
+ w->flags4 |= 5 << WF_TIMEOUT_SHL;
+ SndPlayFx(SND_15_BEEP);
+ PlaceTreesRandomly();
+ MarkWholeScreenDirty();
+ break;
+ }
+ } break;
+
+ case WE_PLACE_OBJ:
+ VpStartPlaceSizing(e->we.place.tile, VPM_X_AND_Y_LIMITED);
+ VpSetPlaceSizingLimit(20);
+ break;
+
+ case WE_PLACE_DRAG:
+ VpSelectTilesWithMethod(e->we.place.pt.x, e->we.place.pt.y, e->we.place.userdata);
+ return;
+
+ case WE_PLACE_MOUSEUP:
+ if (e->we.place.pt.x != -1) {
+ DoCommandP(e->we.place.tile, _tree_to_plant, e->we.place.starttile, NULL,
+ CMD_PLANT_TREE | CMD_AUTO | CMD_MSG(STR_2805_CAN_T_PLANT_TREE_HERE));
+ }
+ break;
+
+ case WE_TIMEOUT:
+ RaiseWindowWidget(w, 16);
+ break;
+
+ case WE_ABORT_PLACE_OBJ:
+ RaiseWindowButtons(w);
+ break;
+ }
+}
+
+static const Widget _build_trees_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 142, 0, 13, STR_2802_TREES, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 142, 14, 170, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 14, 2, 35, 16, 61, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT},
+{ WWT_PANEL, RESIZE_NONE, 14, 37, 70, 16, 61, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT},
+{ WWT_PANEL, RESIZE_NONE, 14, 72, 105, 16, 61, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT},
+{ WWT_PANEL, RESIZE_NONE, 14, 107, 140, 16, 61, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT},
+{ WWT_PANEL, RESIZE_NONE, 14, 2, 35, 63, 108, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT},
+{ WWT_PANEL, RESIZE_NONE, 14, 37, 70, 63, 108, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT},
+{ WWT_PANEL, RESIZE_NONE, 14, 72, 105, 63, 108, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT},
+{ WWT_PANEL, RESIZE_NONE, 14, 107, 140, 63, 108, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT},
+{ WWT_PANEL, RESIZE_NONE, 14, 2, 35, 110, 155, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT},
+{ WWT_PANEL, RESIZE_NONE, 14, 37, 70, 110, 155, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT},
+{ WWT_PANEL, RESIZE_NONE, 14, 72, 105, 110, 155, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT},
+{ WWT_PANEL, RESIZE_NONE, 14, 107, 140, 110, 155, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 140, 157, 168, STR_TREES_RANDOM_TYPE, STR_TREES_RANDOM_TYPE_TIP},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _build_trees_desc = {
+ 497, 22, 143, 171,
+ WC_BUILD_TREES, WC_SCEN_LAND_GEN,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _build_trees_widgets,
+ BuildTreesWndProc
+};
+
+static const Widget _build_trees_scen_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 142, 0, 13, STR_2802_TREES, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 142, 14, 183, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 14, 2, 35, 16, 61, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT},
+{ WWT_PANEL, RESIZE_NONE, 14, 37, 70, 16, 61, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT},
+{ WWT_PANEL, RESIZE_NONE, 14, 72, 105, 16, 61, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT},
+{ WWT_PANEL, RESIZE_NONE, 14, 107, 140, 16, 61, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT},
+{ WWT_PANEL, RESIZE_NONE, 14, 2, 35, 63, 108, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT},
+{ WWT_PANEL, RESIZE_NONE, 14, 37, 70, 63, 108, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT},
+{ WWT_PANEL, RESIZE_NONE, 14, 72, 105, 63, 108, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT},
+{ WWT_PANEL, RESIZE_NONE, 14, 107, 140, 63, 108, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT},
+{ WWT_PANEL, RESIZE_NONE, 14, 2, 35, 110, 155, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT},
+{ WWT_PANEL, RESIZE_NONE, 14, 37, 70, 110, 155, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT},
+{ WWT_PANEL, RESIZE_NONE, 14, 72, 105, 110, 155, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT},
+{ WWT_PANEL, RESIZE_NONE, 14, 107, 140, 110, 155, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 140, 157, 168, STR_TREES_RANDOM_TYPE, STR_TREES_RANDOM_TYPE_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 140, 170, 181, STR_028A_RANDOM_TREES, STR_028B_PLANT_TREES_RANDOMLY_OVER},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _build_trees_scen_desc = {
+ WDP_AUTO, WDP_AUTO, 143, 184,
+ WC_BUILD_TREES,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _build_trees_scen_widgets,
+ BuildTreesWndProc
+};
+
+
+void ShowBuildTreesToolbar(void)
+{
+ if (!IsValidPlayer(_current_player)) return;
+ AllocateWindowDescFront(&_build_trees_desc, 0);
+}
+
+void ShowBuildTreesScenToolbar(void)
+{
+ AllocateWindowDescFront(&_build_trees_scen_desc, 0);
+}
+
+static uint32 _errmsg_decode_params[20];
+static StringID _errmsg_message_1, _errmsg_message_2;
+static uint _errmsg_duration;
+
+
+static const Widget _errmsg_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 4, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 4, 11, 239, 0, 13, STR_00B2_MESSAGE, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 4, 0, 239, 14, 45, 0x0, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const Widget _errmsg_face_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 4, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 4, 11, 333, 0, 13, STR_00B3_MESSAGE_FROM, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 4, 0, 333, 14, 136, 0x0, STR_NULL},
+{ WIDGETS_END},
+};
+
+static void ErrmsgWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT:
+ COPY_IN_DPARAM(0, _errmsg_decode_params, lengthof(_errmsg_decode_params));
+ DrawWindowWidgets(w);
+ COPY_IN_DPARAM(0, _errmsg_decode_params, lengthof(_errmsg_decode_params));
+ if (!IsWindowOfPrototype(w, _errmsg_face_widgets)) {
+ DrawStringMultiCenter(
+ 120,
+ (_errmsg_message_1 == INVALID_STRING_ID ? 25 : 15),
+ _errmsg_message_2,
+ 238);
+ if (_errmsg_message_1 != INVALID_STRING_ID)
+ DrawStringMultiCenter(
+ 120,
+ 30,
+ _errmsg_message_1,
+ 238);
+ } else {
+ const Player *p = GetPlayer(GetDParamX(_errmsg_decode_params,2));
+ DrawPlayerFace(p->face, p->player_color, 2, 16);
+
+ DrawStringMultiCenter(
+ 214,
+ (_errmsg_message_1 == INVALID_STRING_ID ? 65 : 45),
+ _errmsg_message_2,
+ 238);
+ if (_errmsg_message_1 != INVALID_STRING_ID)
+ DrawStringMultiCenter(
+ 214,
+ 90,
+ _errmsg_message_1,
+ 238);
+ }
+ break;
+
+ case WE_MOUSELOOP:
+ if (_right_button_down) DeleteWindow(w);
+ break;
+
+ case WE_4:
+ if (--_errmsg_duration == 0) DeleteWindow(w);
+ break;
+
+ case WE_DESTROY:
+ SetRedErrorSquare(0);
+ _switch_mode_errorstr = INVALID_STRING_ID;
+ break;
+
+ case WE_KEYPRESS:
+ if (e->we.keypress.keycode == WKC_SPACE) {
+ // Don't continue.
+ e->we.keypress.cont = false;
+ DeleteWindow(w);
+ }
+ break;
+ }
+}
+
+void ShowErrorMessage(StringID msg_1, StringID msg_2, int x, int y)
+{
+ Window *w;
+ const ViewPort *vp;
+ Point pt;
+
+ DeleteWindowById(WC_ERRMSG, 0);
+
+ //assert(msg_2);
+ if (msg_2 == 0) msg_2 = STR_EMPTY;
+
+ _errmsg_message_1 = msg_1;
+ _errmsg_message_2 = msg_2;
+ COPY_OUT_DPARAM(_errmsg_decode_params, 0, lengthof(_errmsg_decode_params));
+ _errmsg_duration = _patches.errmsg_duration;
+ if (!_errmsg_duration) return;
+
+ if (_errmsg_message_1 != STR_013B_OWNED_BY || GetDParamX(_errmsg_decode_params,2) >= 8) {
+
+ if ( (x|y) != 0) {
+ pt = RemapCoords2(x, y);
+ vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
+
+ // move x pos to opposite corner
+ pt.x = ((pt.x - vp->virtual_left) >> vp->zoom) + vp->left;
+ pt.x = (pt.x < (_screen.width >> 1)) ? _screen.width - 260 : 20;
+
+ // move y pos to opposite corner
+ pt.y = ((pt.y - vp->virtual_top) >> vp->zoom) + vp->top;
+ pt.y = (pt.y < (_screen.height >> 1)) ? _screen.height - 80 : 100;
+
+ } else {
+ pt.x = (_screen.width - 240) >> 1;
+ pt.y = (_screen.height - 46) >> 1;
+ }
+ w = AllocateWindow(pt.x, pt.y, 240, 46, ErrmsgWndProc, WC_ERRMSG, _errmsg_widgets);
+ } else {
+ if ( (x|y) != 0) {
+ pt = RemapCoords2(x, y);
+ vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
+ pt.x = clamp(((pt.x - vp->virtual_left) >> vp->zoom) + vp->left - (334/2), 0, _screen.width - 334);
+ pt.y = clamp(((pt.y - vp->virtual_top) >> vp->zoom) + vp->top - (137/2), 22, _screen.height - 137);
+ } else {
+ pt.x = (_screen.width - 334) >> 1;
+ pt.y = (_screen.height - 137) >> 1;
+ }
+ w = AllocateWindow(pt.x, pt.y, 334, 137, ErrmsgWndProc, WC_ERRMSG, _errmsg_face_widgets);
+ }
+
+ w->desc_flags = WDF_STD_BTN | WDF_DEF_WIDGET;
+}
+
+
+void ShowEstimatedCostOrIncome(int32 cost, int x, int y)
+{
+ StringID msg = STR_0805_ESTIMATED_COST;
+
+ if (cost < 0) {
+ cost = -cost;
+ msg = STR_0807_ESTIMATED_INCOME;
+ }
+ SetDParam(0, cost);
+ ShowErrorMessage(INVALID_STRING_ID, msg, x, y);
+}
+
+void ShowCostOrIncomeAnimation(int x, int y, int z, int32 cost)
+{
+ StringID msg;
+ Point pt = RemapCoords(x,y,z);
+
+ msg = STR_0801_COST;
+ if (cost < 0) {
+ cost = -cost;
+ msg = STR_0803_INCOME;
+ }
+ SetDParam(0, cost);
+ AddTextEffect(msg, pt.x, pt.y, 0x250);
+}
+
+void ShowFeederIncomeAnimation(int x, int y, int z, int32 cost)
+{
+ Point pt = RemapCoords(x,y,z);
+
+ SetDParam(0, cost);
+ AddTextEffect(STR_FEEDER, pt.x, pt.y, 0x250);
+}
+
+static const Widget _tooltips_widgets[] = {
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 199, 0, 31, 0x0, STR_NULL},
+{ WIDGETS_END},
+};
+
+
+static void TooltipsWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ uint arg;
+ GfxFillRect(0, 0, w->width - 1, w->height - 1, 0);
+ GfxFillRect(1, 1, w->width - 2, w->height - 2, 0x44);
+
+ for (arg = 0; arg < WP(w, tooltips_d).paramcount; arg++) {
+ SetDParam(arg, WP(w, tooltips_d).params[arg]);
+ }
+ DrawStringMultiCenter((w->width >> 1), (w->height >> 1) - 5, WP(w, tooltips_d).string_id, 197);
+ break;
+ }
+
+ case WE_MOUSELOOP:
+ /* We can show tooltips while dragging tools. These are shown as long as
+ * we are dragging the tool. Normal tooltips work with rmb */
+ if (WP(w, tooltips_d).paramcount == 0 ) {
+ if (!_right_button_down) DeleteWindow(w);
+ } else {
+ if (!_left_button_down) DeleteWindow(w);
+ }
+
+ break;
+ }
+}
+
+/** Shows a tooltip
+* @param str String to be displayed
+* @param params (optional) up to 5 pieces of additional information that may be
+* added to a tooltip; currently only supports parameters of {NUM} (integer) */
+void GuiShowTooltipsWithArgs(StringID str, uint paramcount, const uint32 params[])
+{
+ char buffer[512];
+ BoundingRect br;
+ Window *w;
+ uint i;
+ int x, y;
+
+ DeleteWindowById(WC_TOOLTIPS, 0);
+
+ /* We only show measurement tooltips with patch setting on */
+ if (str == STR_NULL || (paramcount != 0 && !_patches.measure_tooltip)) return;
+
+ for (i = 0; i != paramcount; i++) SetDParam(i, params[i]);
+ GetString(buffer, str, lastof(buffer));
+
+ br = GetStringBoundingBox(buffer);
+ br.width += 6; br.height += 4; // increase slightly to have some space around the box
+
+ /* Cut tooltip length to 200 pixels max, wrap to new line if longer */
+ if (br.width > 200) {
+ br.height += ((br.width - 4) / 176) * 10;
+ br.width = 200;
+ }
+
+ /* Correctly position the tooltip position, watch out for window and cursor size
+ * Clamp value to below main toolbar and above statusbar. If tooltip would
+ * go below window, flip it so it is shown above the cursor */
+ y = clamp(_cursor.pos.y + _cursor.size.y + _cursor.offs.y + 5, 22, _screen.height - 12);
+ if (y + br.height > _screen.height - 12) y = _cursor.pos.y + _cursor.offs.y - br.height - 5;
+ x = clamp(_cursor.pos.x - (br.width >> 1), 0, _screen.width - br.width);
+
+ w = AllocateWindow(x, y, br.width, br.height, TooltipsWndProc, WC_TOOLTIPS, _tooltips_widgets);
+
+ WP(w, tooltips_d).string_id = str;
+ assert(sizeof(WP(w, tooltips_d).params[0]) == sizeof(params[0]));
+ memcpy(WP(w, tooltips_d).params, params, sizeof(WP(w, tooltips_d).params[0]) * paramcount);
+ WP(w, tooltips_d).paramcount = paramcount;
+
+ w->flags4 &= ~WF_WHITE_BORDER_MASK; // remove white-border from tooltip
+ w->widget[0].right = br.width;
+ w->widget[0].bottom = br.height;
+}
+
+
+static void DrawStationCoverageText(const AcceptedCargo accepts,
+ int str_x, int str_y, uint mask)
+{
+ char *b = _userstring;
+ bool first = true;
+ int i;
+
+ b = InlineString(b, STR_000D_ACCEPTS);
+
+ for (i = 0; i != NUM_CARGO; i++, mask >>= 1) {
+ if (b >= lastof(_userstring) - 5) break;
+ if (accepts[i] >= 8 && mask & 1) {
+ if (first) {
+ first = false;
+ } else {
+ /* Add a comma if this is not the first item */
+ *b++ = ',';
+ *b++ = ' ';
+ }
+ b = InlineString(b, _cargoc.names_s[i]);
+ }
+ }
+
+ /* If first is still true then no cargo is accepted */
+ if (first) b = InlineString(b, STR_00D0_NOTHING);
+
+ *b = '\0';
+ DrawStringMultiLine(str_x, str_y, STR_SPEC_USERSTRING, 144);
+}
+
+void DrawStationCoverageAreaText(int sx, int sy, uint mask, int rad) {
+ TileIndex tile = TileVirtXY(_thd.pos.x, _thd.pos.y);
+ AcceptedCargo accepts;
+ if (tile < MapSize()) {
+ GetAcceptanceAroundTiles(accepts, tile, _thd.size.x / TILE_SIZE, _thd.size.y / TILE_SIZE , rad);
+ DrawStationCoverageText(accepts, sx, sy, mask);
+ }
+}
+
+void CheckRedrawStationCoverage(const Window *w)
+{
+ if (_thd.dirty & 1) {
+ _thd.dirty &= ~1;
+ SetWindowDirty(w);
+ }
+}
+
+void SetVScrollCount(Window *w, int num)
+{
+ w->vscroll.count = num;
+ num -= w->vscroll.cap;
+ if (num < 0) num = 0;
+ if (num < w->vscroll.pos) w->vscroll.pos = num;
+}
+
+void SetVScroll2Count(Window *w, int num)
+{
+ w->vscroll2.count = num;
+ num -= w->vscroll2.cap;
+ if (num < 0) num = 0;
+ if (num < w->vscroll2.pos) w->vscroll2.pos = num;
+}
+
+void SetHScrollCount(Window *w, int num)
+{
+ w->hscroll.count = num;
+ num -= w->hscroll.cap;
+ if (num < 0) num = 0;
+ if (num < w->hscroll.pos) w->hscroll.pos = num;
+}
+
+/* Delete a character at the caret position in a text buf.
+ * If backspace is set, delete the character before the caret,
+ * else delete the character after it. */
+static void DelChar(Textbuf *tb, bool backspace)
+{
+ WChar c;
+ uint width;
+ size_t len;
+
+ if (backspace) {
+ do {
+ tb->caretpos--;
+ } while (IsUtf8Part(*(tb->buf + tb->caretpos)));
+ }
+
+ len = Utf8Decode(&c, tb->buf + tb->caretpos);
+ width = GetCharacterWidth(FS_NORMAL, c);
+
+ tb->width -= width;
+ if (backspace) tb->caretxoffs -= width;
+
+ /* Move the remaining characters over the marker */
+ memmove(tb->buf + tb->caretpos, tb->buf + tb->caretpos + len, tb->length - tb->caretpos - len + 1);
+ tb->length -= len;
+}
+
+/**
+ * Delete a character from a textbuffer, either with 'Delete' or 'Backspace'
+ * The character is delete from the position the caret is at
+ * @param tb @Textbuf type to be changed
+ * @param delmode Type of deletion, either @WKC_BACKSPACE or @WKC_DELETE
+ * @return Return true on successfull change of Textbuf, or false otherwise
+ */
+bool DeleteTextBufferChar(Textbuf *tb, int delmode)
+{
+ if (delmode == WKC_BACKSPACE && tb->caretpos != 0) {
+ DelChar(tb, true);
+ return true;
+ } else if (delmode == WKC_DELETE && tb->caretpos < tb->length) {
+ DelChar(tb, false);
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Delete every character in the textbuffer
+ * @param tb @Textbuf buffer to be emptied
+ */
+void DeleteTextBufferAll(Textbuf *tb)
+{
+ memset(tb->buf, 0, tb->maxlength);
+ tb->length = tb->width = 0;
+ tb->caretpos = tb->caretxoffs = 0;
+}
+
+/**
+ * Insert a character to a textbuffer. If maxwidth of the Textbuf is zero,
+ * we don't care about the visual-length but only about the physical
+ * length of the string
+ * @param tb @Textbuf type to be changed
+ * @param key Character to be inserted
+ * @return Return true on successfull change of Textbuf, or false otherwise
+ */
+bool InsertTextBufferChar(Textbuf *tb, WChar key)
+{
+ const byte charwidth = GetCharacterWidth(FS_NORMAL, key);
+ size_t len = Utf8CharLen(key);
+ if (tb->length < (tb->maxlength - len) && (tb->maxwidth == 0 || tb->width + charwidth <= tb->maxwidth)) {
+ memmove(tb->buf + tb->caretpos + len, tb->buf + tb->caretpos, tb->length - tb->caretpos + 1);
+ Utf8Encode(tb->buf + tb->caretpos, key);
+ tb->length += len;
+ tb->width += charwidth;
+
+ tb->caretpos += len;
+ tb->caretxoffs += charwidth;
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Handle text navigation with arrow keys left/right.
+ * This defines where the caret will blink and the next characer interaction will occur
+ * @param tb @Textbuf type where navigation occurs
+ * @param navmode Direction in which navigation occurs @WKC_LEFT, @WKC_RIGHT, @WKC_END, @WKC_HOME
+ * @return Return true on successfull change of Textbuf, or false otherwise
+ */
+bool MoveTextBufferPos(Textbuf *tb, int navmode)
+{
+ switch (navmode) {
+ case WKC_LEFT:
+ if (tb->caretpos != 0) {
+ WChar c;
+
+ do {
+ tb->caretpos--;
+ } while (IsUtf8Part(*(tb->buf + tb->caretpos)));
+
+ Utf8Decode(&c, tb->buf + tb->caretpos);
+ tb->caretxoffs -= GetCharacterWidth(FS_NORMAL, c);
+
+ return true;
+ }
+ break;
+ case WKC_RIGHT:
+ if (tb->caretpos < tb->length) {
+ WChar c;
+
+ tb->caretpos += Utf8Decode(&c, tb->buf + tb->caretpos);
+ tb->caretxoffs += GetCharacterWidth(FS_NORMAL, c);
+
+ return true;
+ }
+ break;
+ case WKC_HOME:
+ tb->caretpos = 0;
+ tb->caretxoffs = 0;
+ return true;
+ case WKC_END:
+ tb->caretpos = tb->length;
+ tb->caretxoffs = tb->width;
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Initialize the textbuffer by supplying it the buffer to write into
+ * and the maximum length of this buffer
+ * @param tb @Textbuf type which is getting initialized
+ * @param buf the buffer that will be holding the data for input
+ * @param maxlength maximum length in characters of this buffer
+ * @param maxwidth maximum length in pixels of this buffer. If reached, buffer
+ * cannot grow, even if maxlength would allow because there is space. A length
+ * of zero '0' means the buffer is only restricted by maxlength */
+void InitializeTextBuffer(Textbuf *tb, const char *buf, uint16 maxlength, uint16 maxwidth)
+{
+ tb->buf = (char*)buf;
+ tb->maxlength = maxlength;
+ tb->maxwidth = maxwidth;
+ tb->caret = true;
+ UpdateTextBufferSize(tb);
+}
+
+/**
+ * Update @Textbuf type with its actual physical character and screenlength
+ * Get the count of characters in the string as well as the width in pixels.
+ * Useful when copying in a larger amount of text at once
+ * @param tb @Textbuf type which length is calculated
+ */
+void UpdateTextBufferSize(Textbuf *tb)
+{
+ const char *buf = tb->buf;
+ WChar c = Utf8Consume(&buf);
+
+ tb->width = 0;
+ tb->length = 0;
+
+ for (; c != '\0' && tb->length < (tb->maxlength - 1); c = Utf8Consume(&buf)) {
+ tb->width += GetCharacterWidth(FS_NORMAL, c);
+ tb->length += Utf8CharLen(c);
+ }
+
+ tb->caretpos = tb->length;
+ tb->caretxoffs = tb->width;
+}
+
+int HandleEditBoxKey(Window *w, querystr_d *string, int wid, WindowEvent *e)
+{
+ e->we.keypress.cont = false;
+
+ switch (e->we.keypress.keycode) {
+ case WKC_ESC: return 2;
+ case WKC_RETURN: case WKC_NUM_ENTER: return 1;
+ case (WKC_CTRL | 'V'):
+ if (InsertTextBufferClipboard(&string->text))
+ InvalidateWidget(w, wid);
+ break;
+ case (WKC_CTRL | 'U'):
+ DeleteTextBufferAll(&string->text);
+ InvalidateWidget(w, wid);
+ break;
+ case WKC_BACKSPACE: case WKC_DELETE:
+ if (DeleteTextBufferChar(&string->text, e->we.keypress.keycode))
+ InvalidateWidget(w, wid);
+ break;
+ case WKC_LEFT: case WKC_RIGHT: case WKC_END: case WKC_HOME:
+ if (MoveTextBufferPos(&string->text, e->we.keypress.keycode))
+ InvalidateWidget(w, wid);
+ break;
+ default:
+ if (IsValidChar(e->we.keypress.key, string->afilter)) {
+ if (InsertTextBufferChar(&string->text, e->we.keypress.key)) {
+ InvalidateWidget(w, wid);
+ }
+ } else { // key wasn't caught. Continue only if standard entry specified
+ e->we.keypress.cont = (string->afilter == CS_ALPHANUMERAL);
+ }
+ }
+
+ return 0;
+}
+
+bool HandleCaret(Textbuf *tb)
+{
+ /* caret changed? */
+ bool b = !!(_caret_timer & 0x20);
+
+ if (b != tb->caret) {
+ tb->caret = b;
+ return true;
+ }
+ return false;
+}
+
+void HandleEditBox(Window *w, querystr_d *string, int wid)
+{
+ if (HandleCaret(&string->text)) InvalidateWidget(w, wid);
+}
+
+void DrawEditBox(Window *w, querystr_d *string, int wid)
+{
+ DrawPixelInfo dpi, *old_dpi;
+ int delta;
+ const Widget *wi = &w->widget[wid];
+ const Textbuf *tb = &string->text;
+
+ /* Limit the drawing of the string inside the widget boundaries */
+ if (!FillDrawPixelInfo(&dpi,
+ wi->left + 4,
+ wi->top + 1,
+ wi->right - wi->left - 4,
+ wi->bottom - wi->top - 1)
+ ) return;
+
+ GfxFillRect(wi->left + 1, wi->top + 1, wi->right - 1, wi->bottom - 1, 215);
+
+ old_dpi = _cur_dpi;
+ _cur_dpi = &dpi;
+
+ /* We will take the current widget length as maximum width, with a small
+ * space reserved at the end for the caret to show */
+ delta = (wi->right - wi->left) - tb->width - 10;
+ if (delta > 0) delta = 0;
+
+ if (tb->caretxoffs + delta < 0) delta = -tb->caretxoffs;
+
+ DoDrawString(tb->buf, delta, 0, 8);
+ if (tb->caret) DoDrawString("_", tb->caretxoffs + delta, 0, 12);
+
+ _cur_dpi = old_dpi;
+}
+
+enum QueryStringWidgets {
+ QUERY_STR_WIDGET_TEXT = 3,
+ QUERY_STR_WIDGET_CANCEL,
+ QUERY_STR_WIDGET_OK
+};
+
+
+static void QueryStringWndProc(Window *w, WindowEvent *e)
+{
+ querystr_d *qs = &WP(w, querystr_d);
+
+ switch (e->event) {
+ case WE_CREATE:
+ SETBIT(_no_scroll, SCROLL_EDIT);
+ break;
+
+ case WE_PAINT:
+ SetDParam(0, qs->caption);
+ DrawWindowWidgets(w);
+
+ DrawEditBox(w, qs, QUERY_STR_WIDGET_TEXT);
+ break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case QUERY_STR_WIDGET_OK:
+ press_ok:;
+ if (qs->orig == NULL || strcmp(qs->text.buf, qs->orig) != 0) {
+ Window *parent = w->parent;
+ qs->handled = true;
+
+ /* If the parent is NULL, the editbox is handled by general function
+ * HandleOnEditText */
+ if (parent != NULL) {
+ WindowEvent e;
+ e.event = WE_ON_EDIT_TEXT;
+ e.we.edittext.str = qs->text.buf;
+ parent->wndproc(parent, &e);
+ } else {
+ HandleOnEditText(qs->text.buf);
+ }
+ }
+ /* Fallthrough */
+ case QUERY_STR_WIDGET_CANCEL:
+ DeleteWindow(w);
+ break;
+ }
+ break;
+
+ case WE_MOUSELOOP:
+ HandleEditBox(w, qs, QUERY_STR_WIDGET_TEXT);
+ break;
+
+ case WE_KEYPRESS:
+ switch (HandleEditBoxKey(w, qs, QUERY_STR_WIDGET_TEXT, e)) {
+ case 1: goto press_ok; /* Enter pressed, confirms change */
+ case 2: DeleteWindow(w); break; /* ESC pressed, closes window, abandons changes */
+ }
+ break;
+
+ case WE_DESTROY: /* Call cancellation of query, if we have not handled it before */
+ if (!qs->handled && w->parent != NULL) {
+ WindowEvent e;
+ Window *parent = w->parent;
+
+ qs->handled = true;
+ e.event = WE_ON_EDIT_TEXT_CANCEL;
+ parent->wndproc(parent, &e);
+ }
+ CLRBIT(_no_scroll, SCROLL_EDIT);
+ break;
+ }
+}
+
+static const Widget _query_string_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 259, 0, 13, STR_012D, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 259, 14, 29, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 14, 2, 257, 16, 27, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 0, 129, 30, 41, STR_012E_CANCEL, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 130, 259, 30, 41, STR_012F_OK, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _query_string_desc = {
+ 190, 219, 260, 42,
+ WC_QUERY_STRING,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _query_string_widgets,
+ QueryStringWndProc
+};
+
+static char _edit_str_buf[64];
+
+/** Show a query popup window with a textbox in it.
+ * @param str StringID for the text shown in the textbox
+ * @param caption StringID of text shown in caption of querywindow
+ * @param maxlen maximum length in characters allowed. If bit 12 is set we
+ * will not check the resulting string against to original string to return success
+ * @param maxwidth maximum width in pixels allowed
+ * @param parent pointer to a Window that will handle the events (ok/cancel) of this
+ * window. If NULL, results are handled by global function HandleOnEditText
+ * @param afilter filters out unwanted character input */
+void ShowQueryString(StringID str, StringID caption, uint maxlen, uint maxwidth, Window *parent, CharSetFilter afilter)
+{
+ static char orig_str_buf[lengthof(_edit_str_buf)];
+ Window *w;
+ uint realmaxlen = maxlen & ~0x1000;
+
+ assert(realmaxlen < lengthof(_edit_str_buf));
+
+ DeleteWindowById(WC_QUERY_STRING, 0);
+ DeleteWindowById(WC_SAVELOAD, 0);
+
+ w = AllocateWindowDesc(&_query_string_desc);
+ w->parent = parent;
+
+ GetString(_edit_str_buf, str, lastof(_edit_str_buf));
+ _edit_str_buf[realmaxlen - 1] = '\0';
+
+ if (maxlen & 0x1000) {
+ WP(w, querystr_d).orig = NULL;
+ } else {
+ strecpy(orig_str_buf, _edit_str_buf, lastof(orig_str_buf));
+ WP(w, querystr_d).orig = orig_str_buf;
+ }
+
+ LowerWindowWidget(w, QUERY_STR_WIDGET_TEXT);
+ WP(w, querystr_d).caption = caption;
+ WP(w, querystr_d).afilter = afilter;
+ InitializeTextBuffer(&WP(w, querystr_d).text, _edit_str_buf, realmaxlen, maxwidth);
+}
+
+
+enum QueryWidgets {
+ QUERY_WIDGET_CAPTION = 1,
+ QUERY_WIDGET_NO = 3,
+ QUERY_WIDGET_YES
+};
+
+
+typedef struct query_d {
+ void (*proc)(Window*, bool); ///< callback function executed on closing of popup. Window* points to parent, bool is true if 'yes' clicked, false otherwise
+ StringID message; ///< message shown for query window
+ uint32 params[20]; ///< local copy of _decode_parameters
+ bool calledback; ///< has callback been executed already (internal usage for WE_DESTROY event)
+} query_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(query_d));
+
+
+static void QueryWndProc(Window *w, WindowEvent *e)
+{
+ query_d *q = &WP(w, query_d);
+
+ switch (e->event) {
+ case WE_PAINT:
+ COPY_IN_DPARAM(0, q->params, lengthof(q->params));
+ DrawWindowWidgets(w);
+ COPY_IN_DPARAM(0, q->params, lengthof(q->params));
+
+ DrawStringMultiCenter(w->width / 2, (w->height / 2) - 10, q->message, w->width);
+ break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case QUERY_WIDGET_YES:
+ q->calledback = true;
+ if (q->proc != NULL) q->proc(w->parent, true);
+ /* Fallthrough */
+ case QUERY_WIDGET_NO:
+ DeleteWindow(w);
+ break;
+ }
+ break;
+
+ case WE_KEYPRESS: /* ESC closes the window, Enter confirms the action */
+ switch (e->we.keypress.keycode) {
+ case WKC_RETURN:
+ case WKC_NUM_ENTER:
+ q->calledback = true;
+ if (q->proc != NULL) q->proc(w->parent, true);
+ /* Fallthrough */
+ case WKC_ESC:
+ e->we.keypress.cont = false;
+ DeleteWindow(w);
+ break;
+ }
+ break;
+
+ case WE_DESTROY: /* Call callback function (if any) on window close if not yet called */
+ if (!q->calledback && q->proc != NULL) {
+ q->calledback = true;
+ q->proc(w->parent, false);
+ }
+ break;
+ }
+}
+
+
+static const Widget _query_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 4, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 4, 11, 209, 0, 13, STR_NULL, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 4, 0, 209, 14, 81, 0x0, /*OVERRIDE*/STR_NULL},
+{WWT_PUSHTXTBTN, RESIZE_NONE, 3, 20, 90, 62, 73, STR_00C9_NO, STR_NULL},
+{WWT_PUSHTXTBTN, RESIZE_NONE, 3, 120, 190, 62, 73, STR_00C8_YES, STR_NULL},
+{ WIDGETS_END },
+};
+
+static const WindowDesc _query_desc = {
+ WDP_CENTER, WDP_CENTER, 210, 82,
+ WC_CONFIRM_POPUP_QUERY, 0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_UNCLICK_BUTTONS | WDF_DEF_WIDGET | WDF_MODAL,
+ _query_widgets,
+ QueryWndProc
+};
+
+/** Show a modal confirmation window with standard 'yes' and 'no' buttons
+ * The window is aligned to the centre of its parent.
+ * NOTE: You cannot use BindCString as parameter for this window!
+ * @param caption string shown as window caption
+ * @param message string that will be shown for the window
+ * @param parent pointer to parent window, if this pointer is NULL the parent becomes
+ * the main window WC_MAIN_WINDOW
+ * @param x,y coordinates to show the window at
+ * @param yes_no_callback callback function called when window is closed through any button */
+void ShowQuery(StringID caption, StringID message, Window *parent, void (*callback)(Window*, bool))
+{
+ Window *w = AllocateWindowDesc(&_query_desc);
+ if (w == NULL) return;
+
+ if (parent == NULL) parent = FindWindowById(WC_MAIN_WINDOW, 0);
+ w->parent = parent;
+ w->left = parent->left + (parent->width / 2) - (w->width / 2);
+ w->top = parent->top + (parent->height / 2) - (w->height / 2);
+
+ /* Create a backup of the variadic arguments to strings because it will be
+ * overridden pretty often. We will copy these back for drawing */
+ COPY_OUT_DPARAM(WP(w, query_d).params, 0, lengthof(WP(w, query_d).params));
+ w->widget[QUERY_WIDGET_CAPTION].data = caption;
+ WP(w, query_d).message = message;
+ WP(w, query_d).proc = callback;
+ WP(w, query_d).calledback = false;
+}
+
+
+static const Widget _load_dialog_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_RIGHT, 14, 11, 256, 0, 13, STR_NULL, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 0, 127, 14, 25, STR_SORT_BY_NAME, STR_SORT_ORDER_TIP},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 128, 256, 14, 25, STR_SORT_BY_DATE, STR_SORT_ORDER_TIP},
+{ WWT_PANEL, RESIZE_RIGHT, 14, 0, 256, 26, 47, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_RB, 14, 0, 256, 48, 293, 0x0, STR_NULL},
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 245, 256, 48, 59, SPR_HOUSE_ICON, STR_SAVELOAD_HOME_BUTTON},
+{ WWT_INSET, RESIZE_RB, 14, 2, 243, 50, 291, 0x0, STR_400A_LIST_OF_DRIVES_DIRECTORIES},
+{ WWT_SCROLLBAR, RESIZE_LRB, 14, 245, 256, 60, 281, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WWT_RESIZEBOX, RESIZE_LRTB, 14, 245, 256, 282, 293, 0x0, STR_RESIZE_BUTTON},
+{ WIDGETS_END},
+};
+
+static const Widget _save_dialog_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_RIGHT, 14, 11, 256, 0, 13, STR_NULL, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 0, 127, 14, 25, STR_SORT_BY_NAME, STR_SORT_ORDER_TIP},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 128, 256, 14, 25, STR_SORT_BY_DATE, STR_SORT_ORDER_TIP},
+{ WWT_PANEL, RESIZE_RIGHT, 14, 0, 256, 26, 47, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_RB, 14, 0, 256, 48, 291, 0x0, STR_NULL},
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 245, 256, 48, 59, SPR_HOUSE_ICON, STR_SAVELOAD_HOME_BUTTON},
+{ WWT_INSET, RESIZE_RB, 14, 2, 243, 50, 290, 0x0, STR_400A_LIST_OF_DRIVES_DIRECTORIES},
+{ WWT_SCROLLBAR, RESIZE_LRB, 14, 245, 256, 60, 291, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WWT_PANEL, RESIZE_RTB, 14, 0, 256, 292, 307, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_RTB, 14, 2, 254, 294, 305, 0x0, STR_400B_CURRENTLY_SELECTED_NAME},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 127, 308, 319, STR_4003_DELETE, STR_400C_DELETE_THE_CURRENTLY_SELECTED},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 128, 244, 308, 319, STR_4002_SAVE, STR_400D_SAVE_THE_CURRENT_GAME_USING},
+{ WWT_RESIZEBOX, RESIZE_LRTB, 14, 245, 256, 308, 319, 0x0, STR_RESIZE_BUTTON},
+{ WIDGETS_END},
+};
+
+// Colors for fios types
+const byte _fios_colors[] = {13, 9, 9, 6, 5, 6, 5, 6, 6, 8};
+
+void BuildFileList(void)
+{
+ _fios_path_changed = true;
+ FiosFreeSavegameList();
+
+ switch (_saveload_mode) {
+ case SLD_NEW_GAME:
+ case SLD_LOAD_SCENARIO:
+ case SLD_SAVE_SCENARIO:
+ _fios_list = FiosGetScenarioList(_saveload_mode); break;
+ case SLD_LOAD_HEIGHTMAP:
+ _fios_list = FiosGetHeightmapList(_saveload_mode); break;
+
+ default: _fios_list = FiosGetSavegameList(_saveload_mode); break;
+ }
+}
+
+static void DrawFiosTexts(uint maxw)
+{
+ static const char *path = NULL;
+ static StringID str = STR_4006_UNABLE_TO_READ_DRIVE;
+ static uint32 tot = 0;
+
+ if (_fios_path_changed) {
+ str = FiosGetDescText(&path, &tot);
+ _fios_path_changed = false;
+ }
+
+ if (str != STR_4006_UNABLE_TO_READ_DRIVE) SetDParam(0, tot);
+ DrawString(2, 37, str, 0);
+ DoDrawStringTruncated(path, 2, 27, 16, maxw);
+}
+
+static void MakeSortedSaveGameList(void)
+{
+ uint sort_start = 0;
+ uint sort_end = 0;
+ uint s_amount;
+ int i;
+
+ /* Directories are always above the files (FIOS_TYPE_DIR)
+ * Drives (A:\ (windows only) are always under the files (FIOS_TYPE_DRIVE)
+ * Only sort savegames/scenarios, not directories
+ */
+ for (i = 0; i < _fios_num; i++) {
+ switch (_fios_list[i].type) {
+ case FIOS_TYPE_DIR: sort_start++; break;
+ case FIOS_TYPE_PARENT: sort_start++; break;
+ case FIOS_TYPE_DRIVE: sort_end++; break;
+ }
+ }
+
+ s_amount = _fios_num - sort_start - sort_end;
+ if (s_amount > 0)
+ qsort(_fios_list + sort_start, s_amount, sizeof(FiosItem), compare_FiosItems);
+}
+
+static void GenerateFileName(void)
+{
+ /* Check if we are not a specatator who wants to generate a name..
+ Let's use the name of player #0 for now. */
+ const Player *p = GetPlayer(IsValidPlayer(_local_player) ? _local_player : 0);
+
+ SetDParam(0, p->name_1);
+ SetDParam(1, p->name_2);
+ SetDParam(2, _date);
+ GetString(_edit_str_buf, STR_4004, lastof(_edit_str_buf));
+}
+
+extern void StartupEngines(void);
+
+static void SaveLoadDlgWndProc(Window *w, WindowEvent *e)
+{
+ static FiosItem o_dir;
+
+ switch (e->event) {
+ case WE_CREATE: { /* Set up OPENTTD button */
+ o_dir.type = FIOS_TYPE_DIRECT;
+ switch (_saveload_mode) {
+ case SLD_SAVE_GAME:
+ case SLD_LOAD_GAME:
+ ttd_strlcpy(&o_dir.name[0], _paths.save_dir, sizeof(o_dir.name));
+ break;
+
+ case SLD_SAVE_SCENARIO:
+ case SLD_LOAD_SCENARIO:
+ ttd_strlcpy(&o_dir.name[0], _paths.scenario_dir, sizeof(o_dir.name));
+ break;
+
+ case SLD_LOAD_HEIGHTMAP:
+ ttd_strlcpy(&o_dir.name[0], _paths.heightmap_dir, sizeof(o_dir.name));
+ break;
+
+ default:
+ ttd_strlcpy(&o_dir.name[0], _paths.personal_dir, sizeof(o_dir.name));
+ }
+ break;
+ }
+
+ case WE_PAINT: {
+ int pos;
+ int y;
+
+ SetVScrollCount(w, _fios_num);
+ DrawWindowWidgets(w);
+ DrawFiosTexts(w->width);
+
+ if (_savegame_sort_dirty) {
+ _savegame_sort_dirty = false;
+ MakeSortedSaveGameList();
+ }
+
+ GfxFillRect(w->widget[7].left + 1, w->widget[7].top + 1, w->widget[7].right, w->widget[7].bottom, 0xD7);
+ DoDrawString(
+ _savegame_sort_order & SORT_DESCENDING ? DOWNARROW : UPARROW,
+ _savegame_sort_order & SORT_BY_NAME ? w->widget[2].right - 9 : w->widget[3].right - 9,
+ 15, 16
+ );
+
+ y = w->widget[7].top + 1;
+ for (pos = w->vscroll.pos; pos < _fios_num; pos++) {
+ const FiosItem *item = _fios_list + pos;
+
+ DoDrawStringTruncated(item->title, 4, y, _fios_colors[item->type], w->width - 18);
+ y += 10;
+ if (y >= w->vscroll.cap * 10 + w->widget[7].top + 1) break;
+ }
+
+ if (_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO) {
+ DrawEditBox(w, &WP(w,querystr_d), 10);
+ }
+ break;
+ }
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 2: /* Sort save names by name */
+ _savegame_sort_order = (_savegame_sort_order == SORT_BY_NAME) ?
+ SORT_BY_NAME | SORT_DESCENDING : SORT_BY_NAME;
+ _savegame_sort_dirty = true;
+ SetWindowDirty(w);
+ break;
+
+ case 3: /* Sort save names by date */
+ _savegame_sort_order = (_savegame_sort_order == SORT_BY_DATE) ?
+ SORT_BY_DATE | SORT_DESCENDING : SORT_BY_DATE;
+ _savegame_sort_dirty = true;
+ SetWindowDirty(w);
+ break;
+
+ case 6: /* OpenTTD 'button', jumps to OpenTTD directory */
+ FiosBrowseTo(&o_dir);
+ SetWindowDirty(w);
+ BuildFileList();
+ break;
+
+ case 7: { /* Click the listbox */
+ int y = (e->we.click.pt.y - w->widget[e->we.click.widget].top - 1) / 10;
+ char *name;
+ const FiosItem *file;
+
+ if (y < 0 || (y += w->vscroll.pos) >= w->vscroll.count) return;
+
+ file = _fios_list + y;
+
+ name = FiosBrowseTo(file);
+ if (name != NULL) {
+ if (_saveload_mode == SLD_LOAD_GAME || _saveload_mode == SLD_LOAD_SCENARIO) {
+ _switch_mode = (_game_mode == GM_EDITOR) ? SM_LOAD_SCENARIO : SM_LOAD;
+
+ SetFiosType(file->type);
+ ttd_strlcpy(_file_to_saveload.name, name, sizeof(_file_to_saveload.name));
+ ttd_strlcpy(_file_to_saveload.title, file->title, sizeof(_file_to_saveload.title));
+
+ DeleteWindow(w);
+ } else if (_saveload_mode == SLD_LOAD_HEIGHTMAP) {
+ SetFiosType(file->type);
+ ttd_strlcpy(_file_to_saveload.name, name, sizeof(_file_to_saveload.name));
+ ttd_strlcpy(_file_to_saveload.title, file->title, sizeof(_file_to_saveload.title));
+
+ DeleteWindow(w);
+ ShowHeightmapLoad();
+ } else {
+ // SLD_SAVE_GAME, SLD_SAVE_SCENARIO copy clicked name to editbox
+ ttd_strlcpy(WP(w, querystr_d).text.buf, file->title, WP(w, querystr_d).text.maxlength);
+ UpdateTextBufferSize(&WP(w, querystr_d).text);
+ InvalidateWidget(w, 10);
+ }
+ } else {
+ // Changed directory, need repaint.
+ SetWindowDirty(w);
+ BuildFileList();
+ }
+ break;
+ }
+
+ case 11: case 12: /* Delete, Save game */
+ break;
+ }
+ break;
+ case WE_MOUSELOOP:
+ if (_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO) {
+ HandleEditBox(w, &WP(w, querystr_d), 10);
+ }
+ break;
+ case WE_KEYPRESS:
+ if (e->we.keypress.keycode == WKC_ESC) {
+ DeleteWindow(w);
+ return;
+ }
+
+ if (_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO) {
+ if (HandleEditBoxKey(w, &WP(w, querystr_d), 10, e) == 1) /* Press Enter */
+ HandleButtonClick(w, 12);
+ }
+ break;
+ case WE_TIMEOUT:
+ /* This test protects against using widgets 11 and 12 which are only available
+ * in those two saveload mode */
+ if (!(_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO)) break;
+
+ if (IsWindowWidgetLowered(w, 11)) { /* Delete button clicked */
+ if (!FiosDelete(WP(w,querystr_d).text.buf)) {
+ ShowErrorMessage(INVALID_STRING_ID, STR_4008_UNABLE_TO_DELETE_FILE, 0, 0);
+ } else {
+ BuildFileList();
+ /* Reset file name to current date on successfull delete */
+ if (_saveload_mode == SLD_SAVE_GAME) GenerateFileName();
+ }
+
+ UpdateTextBufferSize(&WP(w, querystr_d).text);
+ SetWindowDirty(w);
+ } else if (IsWindowWidgetLowered(w, 12)) { /* Save button clicked */
+ _switch_mode = SM_SAVE;
+ FiosMakeSavegameName(_file_to_saveload.name, WP(w,querystr_d).text.buf, sizeof(_file_to_saveload.name));
+
+ /* In the editor set up the vehicle engines correctly (date might have changed) */
+ if (_game_mode == GM_EDITOR) StartupEngines();
+ }
+ break;
+ case WE_DESTROY:
+ // pause is only used in single-player, non-editor mode, non menu mode
+ if (!_networking && _game_mode != GM_EDITOR && _game_mode != GM_MENU) {
+ DoCommandP(0, 0, 0, NULL, CMD_PAUSE);
+ }
+ FiosFreeSavegameList();
+ CLRBIT(_no_scroll, SCROLL_SAVE);
+ break;
+ case WE_RESIZE: {
+ /* Widget 2 and 3 have to go with halve speed, make it so obiwan */
+ uint diff = e->we.sizing.diff.x / 2;
+ w->widget[2].right += diff;
+ w->widget[3].left += diff;
+ w->widget[3].right += e->we.sizing.diff.x;
+
+ /* Same for widget 11 and 12 in save-dialog */
+ if (_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO) {
+ w->widget[11].right += diff;
+ w->widget[12].left += diff;
+ w->widget[12].right += e->we.sizing.diff.x;
+ }
+
+ w->vscroll.cap += e->we.sizing.diff.y / 10;
+ } break;
+ }
+}
+
+static const WindowDesc _load_dialog_desc = {
+ WDP_CENTER, WDP_CENTER, 257, 294,
+ WC_SAVELOAD,0,
+ WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_STD_BTN | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
+ _load_dialog_widgets,
+ SaveLoadDlgWndProc,
+};
+
+static const WindowDesc _save_dialog_desc = {
+ WDP_CENTER, WDP_CENTER, 257, 320,
+ WC_SAVELOAD,0,
+ WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_STD_BTN | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
+ _save_dialog_widgets,
+ SaveLoadDlgWndProc,
+};
+
+void ShowSaveLoadDialog(int mode)
+{
+ static const StringID saveload_captions[] = {
+ STR_4001_LOAD_GAME,
+ STR_0298_LOAD_SCENARIO,
+ STR_4000_SAVE_GAME,
+ STR_0299_SAVE_SCENARIO,
+ STR_4011_LOAD_HEIGHTMAP,
+ };
+
+ Window *w;
+ const WindowDesc *sld = &_save_dialog_desc;
+
+
+ SetObjectToPlace(SPR_CURSOR_ZZZ, 0, 0, 0);
+ DeleteWindowById(WC_QUERY_STRING, 0);
+ DeleteWindowById(WC_SAVELOAD, 0);
+
+ _saveload_mode = mode;
+ SETBIT(_no_scroll, SCROLL_SAVE);
+
+ switch (mode) {
+ case SLD_SAVE_GAME: GenerateFileName(); break;
+ case SLD_SAVE_SCENARIO: strcpy(_edit_str_buf, "UNNAMED"); break;
+ default: sld = &_load_dialog_desc; break;
+ }
+
+ assert((uint)mode < lengthof(saveload_captions));
+ w = AllocateWindowDesc(sld);
+ w->widget[1].data = saveload_captions[mode];
+ w->vscroll.cap = 24;
+ w->resize.step_width = 2;
+ w->resize.step_height = 10;
+ w->resize.height = w->height - 14 * 10; // Minimum of 10 items
+ LowerWindowWidget(w, 7);
+
+ WP(w, querystr_d).afilter = CS_ALPHANUMERAL;
+ InitializeTextBuffer(&WP(w, querystr_d).text, _edit_str_buf, lengthof(_edit_str_buf), 240);
+
+ // pause is only used in single-player, non-editor mode, non-menu mode. It
+ // will be unpaused in the WE_DESTROY event handler.
+ if (_game_mode != GM_MENU && !_networking && _game_mode != GM_EDITOR) {
+ DoCommandP(0, 1, 0, NULL, CMD_PAUSE);
+ }
+
+ BuildFileList();
+
+ ResetObjectToPlace();
+}
+
+void RedrawAutosave(void)
+{
+ SetWindowDirty(FindWindowById(WC_STATUS_BAR, 0));
+}
+
+void SetFiosType(const byte fiostype)
+{
+ switch (fiostype) {
+ case FIOS_TYPE_FILE:
+ case FIOS_TYPE_SCENARIO:
+ _file_to_saveload.mode = SL_LOAD;
+ break;
+
+ case FIOS_TYPE_OLDFILE:
+ case FIOS_TYPE_OLD_SCENARIO:
+ _file_to_saveload.mode = SL_OLD_LOAD;
+ break;
+
+#ifdef WITH_PNG
+ case FIOS_TYPE_PNG:
+ _file_to_saveload.mode = SL_PNG;
+ break;
+#endif /* WITH_PNG */
+
+ case FIOS_TYPE_BMP:
+ _file_to_saveload.mode = SL_BMP;
+ break;
+
+ default:
+ _file_to_saveload.mode = SL_INVALID;
+ break;
+ }
+}
+
+static int32 ClickMoneyCheat(int32 p1, int32 p2)
+{
+ DoCommandP(0, -10000000, 0, NULL, CMD_MONEY_CHEAT);
+ return true;
+}
+
+// p1 player to set to, p2 is -1 or +1 (down/up)
+static int32 ClickChangePlayerCheat(int32 p1, int32 p2)
+{
+ while (IsValidPlayer((PlayerID)p1)) {
+ if (_players[p1].is_active) {
+ SetLocalPlayer((PlayerID)p1);
+
+ MarkWholeScreenDirty();
+ return _local_player;
+ }
+ p1 += p2;
+ }
+
+ return _local_player;
+}
+
+// p1 -1 or +1 (down/up)
+static int32 ClickChangeClimateCheat(int32 p1, int32 p2)
+{
+ if (p1 == -1) p1 = 3;
+ if (p1 == 4) p1 = 0;
+ _opt.landscape = p1;
+ ReloadNewGRFData();
+ return _opt.landscape;
+}
+
+extern void EnginesMonthlyLoop(void);
+
+// p2 1 (increase) or -1 (decrease)
+static int32 ClickChangeDateCheat(int32 p1, int32 p2)
+{
+ YearMonthDay ymd;
+ ConvertDateToYMD(_date, &ymd);
+
+ if ((ymd.year == MIN_YEAR && p2 == -1) || (ymd.year == MAX_YEAR && p2 == 1)) return _cur_year;
+
+ SetDate(ConvertYMDToDate(_cur_year + p2, ymd.month, ymd.day));
+ EnginesMonthlyLoop();
+ SetWindowDirty(FindWindowById(WC_STATUS_BAR, 0));
+ return _cur_year;
+}
+
+typedef int32 CheckButtonClick(int32, int32);
+
+enum ce_flags {CE_CLICK = 1 << 0};
+
+typedef byte ce_flags;
+
+typedef struct CheatEntry {
+ VarType type; // type of selector
+ ce_flags flags; // selector flags
+ StringID str; // string with descriptive text
+ void *variable; // pointer to the variable
+ bool *been_used; // has this cheat been used before?
+ CheckButtonClick *proc;// procedure
+ int16 min, max; // range for spinbox setting
+} CheatEntry;
+
+static const CheatEntry _cheats_ui[] = {
+ {SLE_BOOL,CE_CLICK, STR_CHEAT_MONEY, &_cheats.money.value, &_cheats.money.been_used, &ClickMoneyCheat, 0, 0},
+ {SLE_UINT8, 0, STR_CHEAT_CHANGE_PLAYER, &_local_player, &_cheats.switch_player.been_used, &ClickChangePlayerCheat, 0, 11},
+ {SLE_BOOL, 0, STR_CHEAT_EXTRA_DYNAMITE, &_cheats.magic_bulldozer.value, &_cheats.magic_bulldozer.been_used, NULL, 0, 0},
+ {SLE_BOOL, 0, STR_CHEAT_CROSSINGTUNNELS,&_cheats.crossing_tunnels.value,&_cheats.crossing_tunnels.been_used,NULL, 0, 0},
+ {SLE_BOOL, 0, STR_CHEAT_BUILD_IN_PAUSE, &_cheats.build_in_pause.value, &_cheats.build_in_pause.been_used, NULL, 0, 0},
+ {SLE_BOOL, 0, STR_CHEAT_NO_JETCRASH, &_cheats.no_jetcrash.value, &_cheats.no_jetcrash.been_used, NULL, 0, 0},
+ {SLE_BOOL, 0, STR_CHEAT_SETUP_PROD, &_cheats.setup_prod.value, &_cheats.setup_prod.been_used, NULL, 0, 0},
+ {SLE_UINT8, 0, STR_CHEAT_SWITCH_CLIMATE, &_opt.landscape, &_cheats.switch_climate.been_used, &ClickChangeClimateCheat,-1, 4},
+ {SLE_INT32, 0, STR_CHEAT_CHANGE_DATE, &_cur_year, &_cheats.change_date.been_used, &ClickChangeDateCheat, -1, 1},
+};
+
+
+static const Widget _cheat_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 399, 0, 13, STR_CHEATS, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 399, 14, 169, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 399, 14, 169, 0x0, STR_CHEATS_TIP},
+{ WIDGETS_END},
+};
+
+extern void DrawPlayerIcon(PlayerID pid, int x, int y);
+
+static void CheatsWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ int clk = WP(w,def_d).data_1;
+ int x, y;
+ int i;
+
+ DrawWindowWidgets(w);
+
+ DrawStringMultiCenter(200, 25, STR_CHEATS_WARNING, 350);
+
+ x = 0;
+ y = 45;
+
+ for (i = 0; i != lengthof(_cheats_ui); i++) {
+ const CheatEntry *ce = &_cheats_ui[i];
+
+ DrawSprite((*ce->been_used) ? SPR_BOX_CHECKED : SPR_BOX_EMPTY, x + 5, y + 2);
+
+ switch (ce->type) {
+ case SLE_BOOL: {
+ bool on = (*(bool*)ce->variable);
+
+ if (ce->flags & CE_CLICK) {
+ DrawFrameRect(x + 20, y + 1, x + 30 + 9, y + 9, 0, (clk - (i * 2) == 1) ? FR_LOWERED : 0);
+ if (i == 0) { // XXX - hack/hack for first element which is increase money. Told ya it's a mess
+ SetDParam64(0, 10000000);
+ } else {
+ SetDParam(0, false);
+ }
+ } else {
+ DrawFrameRect(x + 20, y + 1, x + 30 + 9, y + 9, on ? 6 : 4, on ? FR_LOWERED : 0);
+ SetDParam(0, on ? STR_CONFIG_PATCHES_ON : STR_CONFIG_PATCHES_OFF);
+ }
+ } break;
+ default: {
+ int32 val = (int32)ReadValue(ce->variable, ce->type);
+ char buf[512];
+
+ /* Draw [<][>] boxes for settings of an integer-type */
+ DrawArrowButtons(x + 20, y, 3, clk - (i * 2), true, true);
+
+ switch (ce->str) {
+ /* Display date for change date cheat */
+ case STR_CHEAT_CHANGE_DATE: SetDParam(0, _date); break;
+ /* Draw colored flag for change player cheat */
+ case STR_CHEAT_CHANGE_PLAYER:
+ SetDParam(0, val);
+ GetString(buf, STR_CHEAT_CHANGE_PLAYER, lastof(buf));
+ DrawPlayerIcon(_current_player, 60 + GetStringBoundingBox(buf).width, y + 2);
+ break;
+ /* Set correct string for switch climate cheat */
+ case STR_CHEAT_SWITCH_CLIMATE: val += STR_TEMPERATE_LANDSCAPE;
+ /* Fallthrough */
+ default: SetDParam(0, val);
+ }
+ } break;
+ }
+
+ DrawString(50, y + 1, ce->str, 0);
+
+ y += 12;
+ }
+ break;
+ }
+
+ case WE_CLICK: {
+ const CheatEntry *ce;
+ uint btn = (e->we.click.pt.y - 46) / 12;
+ int32 value, oldvalue;
+ uint x = e->we.click.pt.x;
+
+ // not clicking a button?
+ if (!IS_INT_INSIDE(x, 20, 40) || btn >= lengthof(_cheats_ui)) break;
+
+ ce = &_cheats_ui[btn];
+ oldvalue = value = (int32)ReadValue(ce->variable, ce->type);
+
+ *ce->been_used = true;
+
+ switch (ce->type) {
+ case SLE_BOOL:
+ if (ce->flags & CE_CLICK) WP(w,def_d).data_1 = btn * 2 + 1;
+ value ^= 1;
+ if (ce->proc != NULL) ce->proc(value, 0);
+ break;
+ default: {
+ /* Add a dynamic step-size to the scroller. In a maximum of
+ * 50-steps you should be able to get from min to max */
+ uint16 step = ((ce->max - ce->min) / 20);
+ if (step == 0) step = 1;
+
+ /* Increase or decrease the value and clamp it to extremes */
+ value += (x >= 30) ? step : -step;
+ clamp(value, ce->min, ce->max);
+
+ // take whatever the function returns
+ value = ce->proc(value, (x >= 30) ? 1 : -1);
+
+ if (value != oldvalue) {
+ WP(w,def_d).data_1 = btn * 2 + 1 + ((x >= 30) ? 1 : 0);
+ }
+ } break;
+ }
+
+ if (value != oldvalue) {
+ WriteValue(ce->variable, ce->type, (int64)value);
+ SetWindowDirty(w);
+ }
+
+ w->flags4 |= 5 << WF_TIMEOUT_SHL;
+
+ SetWindowDirty(w);
+ }
+ break;
+ case WE_TIMEOUT:
+ WP(w,def_d).data_1 = 0;
+ SetWindowDirty(w);
+ break;
+ }
+}
+
+static const WindowDesc _cheats_desc = {
+ 240, 22, 400, 170,
+ WC_CHEATS,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _cheat_widgets,
+ CheatsWndProc
+};
+
+
+void ShowCheatWindow(void)
+{
+ DeleteWindowById(WC_CHEATS, 0);
+ AllocateWindowDesc(&_cheats_desc);
+}
diff --git a/src/mixer.c b/src/mixer.c
new file mode 100644
index 000000000..5b97afbf9
--- /dev/null
+++ b/src/mixer.c
@@ -0,0 +1,140 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "mixer.h"
+
+struct MixerChannel {
+ bool active;
+
+ // pointer to allocated buffer memory
+ int8 *memory;
+
+ // current position in memory
+ uint32 pos;
+ uint32 frac_pos;
+ uint32 frac_speed;
+ uint32 samples_left;
+
+ // Mixing volume
+ uint volume_left;
+ uint volume_right;
+
+ uint flags;
+};
+
+static MixerChannel _channels[8];
+static uint32 _play_rate;
+
+
+static void mix_int8_to_int16(MixerChannel *sc, int16 *buffer, uint samples)
+{
+ int8 *b;
+ uint32 frac_pos;
+ uint32 frac_speed;
+ uint volume_left;
+ uint volume_right;
+
+ if (samples > sc->samples_left) samples = sc->samples_left;
+ sc->samples_left -= samples;
+ assert(samples > 0);
+
+ b = sc->memory + sc->pos;
+ frac_pos = sc->frac_pos;
+ frac_speed = sc->frac_speed;
+ volume_left = sc->volume_left;
+ volume_right = sc->volume_right;
+
+ if (frac_speed == 0x10000) {
+ // Special case when frac_speed is 0x10000
+ do {
+ buffer[0] += *b * volume_left >> 8;
+ buffer[1] += *b * volume_right >> 8;
+ b++;
+ buffer += 2;
+ } while (--samples > 0);
+ } else {
+ do {
+ buffer[0] += *b * volume_left >> 8;
+ buffer[1] += *b * volume_right >> 8;
+ buffer += 2;
+ frac_pos += frac_speed;
+ b += frac_pos >> 16;
+ frac_pos &= 0xffff;
+ } while (--samples > 0);
+ }
+
+ sc->frac_pos = frac_pos;
+ sc->pos = b - sc->memory;
+}
+
+static void MxCloseChannel(MixerChannel *mc)
+{
+ if (mc->flags & MX_AUTOFREE) free(mc->memory);
+ mc->active = false;
+ mc->memory = NULL;
+}
+
+void MxMixSamples(void *buffer, uint samples)
+{
+ MixerChannel *mc;
+
+ // Clear the buffer
+ memset(buffer, 0, sizeof(int16) * 2 * samples);
+
+ // Mix each channel
+ for (mc = _channels; mc != endof(_channels); mc++) {
+ if (mc->active) {
+ mix_int8_to_int16(mc, buffer, samples);
+ if (mc->samples_left == 0) MxCloseChannel(mc);
+ }
+ }
+}
+
+MixerChannel *MxAllocateChannel(void)
+{
+ MixerChannel *mc;
+ for (mc = _channels; mc != endof(_channels); mc++)
+ if (mc->memory == NULL) {
+ mc->active = false;
+ return mc;
+ }
+ return NULL;
+}
+
+void MxSetChannelRawSrc(MixerChannel *mc, int8 *mem, uint size, uint rate, uint flags)
+{
+ mc->memory = mem;
+ mc->flags = flags;
+ mc->frac_pos = 0;
+ mc->pos = 0;
+
+ mc->frac_speed = (rate << 16) / _play_rate;
+
+ // adjust the magnitude to prevent overflow
+ while (size & 0xFFFF0000) {
+ size >>= 1;
+ rate = (rate >> 1) + 1;
+ }
+
+ mc->samples_left = size * _play_rate / rate;
+}
+
+void MxSetChannelVolume(MixerChannel *mc, uint left, uint right)
+{
+ mc->volume_left = left;
+ mc->volume_right = right;
+}
+
+
+void MxActivateChannel(MixerChannel* mc)
+{
+ mc->active = true;
+}
+
+
+bool MxInitialize(uint rate)
+{
+ _play_rate = rate;
+ return true;
+}
diff --git a/src/mixer.h b/src/mixer.h
new file mode 100644
index 000000000..d50dc4739
--- /dev/null
+++ b/src/mixer.h
@@ -0,0 +1,23 @@
+/* $Id$ */
+
+#ifndef MIXER_H
+#define MIXER_H
+
+typedef struct MixerChannel MixerChannel;
+
+enum {
+ MX_AUTOFREE = 1,
+// MX_8BIT = 2,
+// MX_STEREO = 4,
+// MX_UNSIGNED = 8,
+};
+
+bool MxInitialize(uint rate);
+void MxMixSamples(void* buffer, uint samples);
+
+MixerChannel* MxAllocateChannel(void);
+void MxSetChannelRawSrc(MixerChannel *mc, int8 *mem, uint size, uint rate, uint flags);
+void MxSetChannelVolume(MixerChannel *mc, uint left, uint right);
+void MxActivateChannel(MixerChannel*);
+
+#endif /* MIXER_H */
diff --git a/src/music.c b/src/music.c
new file mode 100644
index 000000000..202690139
--- /dev/null
+++ b/src/music.c
@@ -0,0 +1,28 @@
+/* $Id$ */
+
+#include "music.h"
+
+const SongSpecs origin_songs_specs[NUM_SONGS_AVAILABLE] = {
+ {"gm_tt00.gm", "Tycoon DELUXE Theme"},
+ {"gm_tt02.gm", "Easy Driver"},
+ {"gm_tt03.gm", "Little Red Diesel"},
+ {"gm_tt17.gm", "Cruise Control"},
+ {"gm_tt07.gm", "Don't Walk!"},
+ {"gm_tt09.gm", "Fell Apart On Me"},
+ {"gm_tt04.gm", "City Groove"},
+ {"gm_tt19.gm", "Funk Central"},
+ {"gm_tt06.gm", "Stoke It"},
+ {"gm_tt12.gm", "Road Hog"},
+ {"gm_tt05.gm", "Aliens Ate My Railway"},
+ {"gm_tt01.gm", "Snarl Up"},
+ {"gm_tt18.gm", "Stroll On"},
+ {"gm_tt10.gm", "Can't Get There From Here"},
+ {"gm_tt08.gm", "Sawyer's Tune"},
+ {"gm_tt13.gm", "Hold That Train!"},
+ {"gm_tt21.gm", "Movin' On"},
+ {"gm_tt15.gm", "Goss Groove"},
+ {"gm_tt16.gm", "Small Town"},
+ {"gm_tt14.gm", "Broomer's Oil Rag"},
+ {"gm_tt20.gm", "Jammit"},
+ {"gm_tt11.gm", "Hard Drivin'"},
+};
diff --git a/src/music.h b/src/music.h
new file mode 100644
index 000000000..a33565224
--- /dev/null
+++ b/src/music.h
@@ -0,0 +1,16 @@
+/* $Id$ */
+
+#ifndef MUSIC_H
+#define MUSIC_H
+
+#define NUM_SONGS_PLAYLIST 33
+#define NUM_SONGS_AVAILABLE 22
+
+typedef struct SongSpecs {
+ char filename[256];
+ char song_name[64];
+} SongSpecs;
+
+extern const SongSpecs origin_songs_specs[NUM_SONGS_AVAILABLE];
+
+#endif //MUSIC_H
diff --git a/src/music/bemidi.cpp b/src/music/bemidi.cpp
new file mode 100644
index 000000000..d87fae63b
--- /dev/null
+++ b/src/music/bemidi.cpp
@@ -0,0 +1,53 @@
+/* $Id$ */
+
+#include "../stdafx.h"
+#include "../openttd.h"
+#include "bemidi.h"
+
+// BeOS System Includes
+#include <MidiSynthFile.h>
+
+static BMidiSynthFile midiSynthFile;
+
+static const char *bemidi_start(const char * const *parm)
+{
+ return NULL;
+}
+
+static void bemidi_stop(void)
+{
+ midiSynthFile.UnloadFile();
+}
+
+static void bemidi_play_song(const char *filename)
+{
+ bemidi_stop();
+ entry_ref midiRef;
+ get_ref_for_path(filename, &midiRef);
+ midiSynthFile.LoadFile(&midiRef);
+ midiSynthFile.Start();
+}
+
+static void bemidi_stop_song(void)
+{
+ midiSynthFile.UnloadFile();
+}
+
+static bool bemidi_is_playing(void)
+{
+ return !midiSynthFile.IsFinished();
+}
+
+static void bemidi_set_volume(byte vol)
+{
+ fprintf(stderr, "BeMidi: Set volume not implemented\n");
+}
+
+const HalMusicDriver _bemidi_music_driver = {
+ bemidi_start,
+ bemidi_stop,
+ bemidi_play_song,
+ bemidi_stop_song,
+ bemidi_is_playing,
+ bemidi_set_volume,
+};
diff --git a/src/music/bemidi.h b/src/music/bemidi.h
new file mode 100644
index 000000000..10ead59ff
--- /dev/null
+++ b/src/music/bemidi.h
@@ -0,0 +1,10 @@
+/* $Id$ */
+
+#ifndef MUSIC_BEMIDI_H
+#define MUSIC_BEMIDI_H
+
+#include "../hal.h"
+
+extern const HalMusicDriver _bemidi_music_driver;
+
+#endif
diff --git a/src/music/dmusic.cpp b/src/music/dmusic.cpp
new file mode 100644
index 000000000..e20842d2e
--- /dev/null
+++ b/src/music/dmusic.cpp
@@ -0,0 +1,232 @@
+/* $Id$ */
+
+#include "../stdafx.h"
+
+#ifdef WIN32_ENABLE_DIRECTMUSIC_SUPPORT
+
+extern "C" {
+ #include "../openttd.h"
+ #include "../debug.h"
+ #include "../win32.h"
+ #include "dmusic.h"
+}
+
+#include <windows.h>
+#include <dmksctrl.h>
+#include <dmusici.h>
+#include <dmusicc.h>
+#include <dmusicf.h>
+
+
+// the performance object controls manipulation of the segments
+static IDirectMusicPerformance* performance = NULL;
+
+// the loader object can load many types of DMusic related files
+static IDirectMusicLoader* loader = NULL;
+
+// the segment object is where the MIDI data is stored for playback
+static IDirectMusicSegment* segment = NULL;
+
+static bool seeking = false;
+
+
+#define M(x) x "\0"
+static const char ole_files[] =
+ M("ole32.dll")
+ M("CoCreateInstance")
+ M("CoInitialize")
+ M("CoUninitialize")
+ M("")
+;
+#undef M
+
+struct ProcPtrs {
+ unsigned long (WINAPI * CoCreateInstance)(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID* ppv);
+ HRESULT (WINAPI * CoInitialize)(LPVOID pvReserved);
+ void (WINAPI * CoUninitialize)();
+};
+
+static ProcPtrs proc;
+
+
+static const char* DMusicMidiStart(const char* const* parm)
+{
+ if (performance != NULL) return NULL;
+
+ if (proc.CoCreateInstance == NULL) {
+ if (!LoadLibraryList((Function*)&proc, ole_files))
+ return "ole32.dll load failed";
+ }
+
+ // Initialize COM
+ if (FAILED(proc.CoInitialize(NULL))) {
+ return "COM initialization failed";
+ }
+
+ // create the performance object
+ if (FAILED(proc.CoCreateInstance(
+ CLSID_DirectMusicPerformance,
+ NULL,
+ CLSCTX_INPROC,
+ IID_IDirectMusicPerformance,
+ (LPVOID*)&performance
+ ))) {
+ proc.CoUninitialize();
+ return "Failed to create the performance object";
+ }
+
+ // initialize it
+ if (FAILED(performance->Init(NULL, NULL, NULL))) {
+ performance->Release();
+ performance = NULL;
+ proc.CoUninitialize();
+ return "Failed to initialize performance object";
+ }
+
+ // choose default Windows synth
+ if (FAILED(performance->AddPort(NULL))) {
+ performance->CloseDown();
+ performance->Release();
+ performance = NULL;
+ proc.CoUninitialize();
+ return "AddPort failed";
+ }
+
+ // create the loader object; this will be used to load the MIDI file
+ if (FAILED(proc.CoCreateInstance(
+ CLSID_DirectMusicLoader,
+ NULL,
+ CLSCTX_INPROC,
+ IID_IDirectMusicLoader,
+ (LPVOID*)&loader
+ ))) {
+ performance->CloseDown();
+ performance->Release();
+ performance = NULL;
+ proc.CoUninitialize();
+ return "Failed to create loader object";
+ }
+
+ return NULL;
+}
+
+
+static void DMusicMidiStop(void)
+{
+ seeking = false;
+
+ if (performance != NULL) performance->Stop(NULL, NULL, 0, 0);
+
+ if (segment != NULL) {
+ segment->SetParam(GUID_Unload, 0xFFFFFFFF, 0, 0, performance);
+ segment->Release();
+ segment = NULL;
+ }
+
+ if (performance != NULL) {
+ performance->CloseDown();
+ performance->Release();
+ performance = NULL;
+ }
+
+ if (loader != NULL) {
+ loader->Release();
+ loader = NULL;
+ }
+
+ proc.CoUninitialize();
+}
+
+
+static void DMusicMidiPlaySong(const char* filename)
+{
+ // set up the loader object info
+ DMUS_OBJECTDESC obj_desc;
+ ZeroMemory(&obj_desc, sizeof(obj_desc));
+ obj_desc.dwSize = sizeof(obj_desc);
+ obj_desc.guidClass = CLSID_DirectMusicSegment;
+ obj_desc.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_FILENAME | DMUS_OBJ_FULLPATH;
+ MultiByteToWideChar(
+ CP_ACP, MB_PRECOMPOSED,
+ filename, -1,
+ obj_desc.wszFileName, lengthof(obj_desc.wszFileName)
+ );
+
+ // release the existing segment if we have any
+ if (segment != NULL) {
+ segment->Release();
+ segment = NULL;
+ }
+
+ // make a new segment
+ if (FAILED(loader->GetObject(
+ &obj_desc, IID_IDirectMusicSegment, (LPVOID*)&segment
+ ))) {
+ DEBUG(driver, 0, "DirectMusic: GetObject failed");
+ return;
+ }
+
+ // tell the segment what kind of data it contains
+ if (FAILED(segment->SetParam(
+ GUID_StandardMIDIFile, 0xFFFFFFFF, 0, 0, performance
+ ))) {
+ DEBUG(driver, 0, "DirectMusic: SetParam (MIDI file) failed");
+ return;
+ }
+
+ // tell the segment to 'download' the instruments
+ if (FAILED(segment->SetParam(GUID_Download, 0xFFFFFFFF, 0, 0, performance))) {
+ DEBUG(driver, 0, "DirectMusic: failed to download instruments");
+ return;
+ }
+
+ // start playing the MIDI file
+ if (FAILED(performance->PlaySegment(segment, 0, 0, NULL))) {
+ DEBUG(driver, 0, "DirectMusic: PlaySegment failed");
+ return;
+ }
+
+ seeking = true;
+}
+
+
+static void DMusicMidiStopSong(void)
+{
+ if (FAILED(performance->Stop(segment, NULL, 0, 0))) {
+ DEBUG(driver, 0, "DirectMusic: StopSegment failed");
+ }
+ seeking = false;
+}
+
+
+static bool DMusicMidiIsSongPlaying(void)
+{
+ /* Not the nicest code, but there is a short delay before playing actually
+ * starts. OpenTTD makes no provision for this. */
+ if (performance->IsPlaying(segment, NULL) == S_OK) {
+ seeking = false;
+ return true;
+ } else {
+ return seeking;
+ }
+}
+
+
+static void DMusicMidiSetVolume(byte vol)
+{
+ // 0 - 127 -> -2000 - 0
+ long db = vol * 2000 / 127 - 2000;
+ performance->SetGlobalParam(GUID_PerfMasterVolume, &db, sizeof(db));
+}
+
+
+extern "C" const HalMusicDriver _dmusic_midi_driver = {
+ DMusicMidiStart,
+ DMusicMidiStop,
+ DMusicMidiPlaySong,
+ DMusicMidiStopSong,
+ DMusicMidiIsSongPlaying,
+ DMusicMidiSetVolume,
+};
+
+#endif
diff --git a/src/music/dmusic.h b/src/music/dmusic.h
new file mode 100644
index 000000000..5d0990137
--- /dev/null
+++ b/src/music/dmusic.h
@@ -0,0 +1,10 @@
+/* $Id$ */
+
+#ifndef MUSIC_DMUSIC_H
+#define MUSIC_DMUSIC_H
+
+#include "../hal.h"
+
+extern const HalMusicDriver _dmusic_midi_driver;
+
+#endif
diff --git a/src/music/extmidi.c b/src/music/extmidi.c
new file mode 100644
index 000000000..901fa4fd7
--- /dev/null
+++ b/src/music/extmidi.c
@@ -0,0 +1,108 @@
+/* $Id$ */
+
+#ifndef __MORPHOS__
+#include "../stdafx.h"
+#include "../openttd.h"
+#include "../sound.h"
+#include "../string.h"
+#include "../variables.h"
+#include "../debug.h"
+#include "extmidi.h"
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+static struct {
+ char song[MAX_PATH];
+ pid_t pid;
+} _midi;
+
+static void DoPlay(void);
+static void DoStop(void);
+
+static const char* ExtMidiStart(const char* const * parm)
+{
+ _midi.song[0] = '\0';
+ _midi.pid = -1;
+ return NULL;
+}
+
+static void ExtMidiStop(void)
+{
+ _midi.song[0] = '\0';
+ DoStop();
+}
+
+static void ExtMidiPlaySong(const char* filename)
+{
+ ttd_strlcpy(_midi.song, filename, lengthof(_midi.song));
+ DoStop();
+}
+
+static void ExtMidiStopSong(void)
+{
+ _midi.song[0] = '\0';
+ DoStop();
+}
+
+static bool ExtMidiIsPlaying(void)
+{
+ if (_midi.pid != -1 && waitpid(_midi.pid, NULL, WNOHANG) == _midi.pid)
+ _midi.pid = -1;
+ if (_midi.pid == -1 && _midi.song[0] != '\0') DoPlay();
+ return _midi.pid != -1;
+}
+
+static void ExtMidiSetVolume(byte vol)
+{
+ DEBUG(driver, 1, "extmidi: set volume not implemented");
+}
+
+static void DoPlay(void)
+{
+ _midi.pid = fork();
+ switch (_midi.pid) {
+ case 0: {
+ int d;
+
+ close(0);
+ d = open("/dev/null", O_RDONLY);
+ if (d != -1 && dup2(d, 1) != -1 && dup2(d, 2) != -1) {
+ #if defined(MIDI_ARG)
+ execlp(msf.extmidi, "extmidi", MIDI_ARG, _midi.song, (char*)0);
+ #else
+ execlp(msf.extmidi, "extmidi", _midi.song, (char*)0);
+ #endif
+ }
+ _exit(1);
+ }
+
+ case -1:
+ DEBUG(driver, 0, "extmidi: couldn't fork: %s", strerror(errno));
+ /* FALLTHROUGH */
+
+ default:
+ _midi.song[0] = '\0';
+ break;
+ }
+}
+
+static void DoStop(void)
+{
+ if (_midi.pid != -1) kill(_midi.pid, SIGTERM);
+}
+
+const HalMusicDriver _extmidi_music_driver = {
+ ExtMidiStart,
+ ExtMidiStop,
+ ExtMidiPlaySong,
+ ExtMidiStopSong,
+ ExtMidiIsPlaying,
+ ExtMidiSetVolume,
+};
+
+#endif /* __MORPHOS__ */
diff --git a/src/music/extmidi.h b/src/music/extmidi.h
new file mode 100644
index 000000000..681c34bd6
--- /dev/null
+++ b/src/music/extmidi.h
@@ -0,0 +1,10 @@
+/* $Id$ */
+
+#ifndef MUSIC_EXTERNAL_H
+#define MUSIC_EXTERNAL_H
+
+#include "../hal.h"
+
+extern const HalMusicDriver _extmidi_music_driver;
+
+#endif
diff --git a/src/music/null_m.c b/src/music/null_m.c
new file mode 100644
index 000000000..c76a60211
--- /dev/null
+++ b/src/music/null_m.c
@@ -0,0 +1,21 @@
+/* $Id$ */
+
+#include "../stdafx.h"
+#include "../openttd.h"
+#include "null_m.h"
+
+static const char* NullMidiStart(const char* const* parm) { return NULL; }
+static void NullMidiStop(void) {}
+static void NullMidiPlaySong(const char *filename) {}
+static void NullMidiStopSong(void) {}
+static bool NullMidiIsSongPlaying(void) { return true; }
+static void NullMidiSetVolume(byte vol) {}
+
+const HalMusicDriver _null_music_driver = {
+ NullMidiStart,
+ NullMidiStop,
+ NullMidiPlaySong,
+ NullMidiStopSong,
+ NullMidiIsSongPlaying,
+ NullMidiSetVolume,
+};
diff --git a/src/music/null_m.h b/src/music/null_m.h
new file mode 100644
index 000000000..0f3e2cfa5
--- /dev/null
+++ b/src/music/null_m.h
@@ -0,0 +1,10 @@
+/* $Id$ */
+
+#ifndef MUSIC_NULL_H
+#define MUSIC_NULL_H
+
+#include "../hal.h"
+
+extern const HalMusicDriver _null_music_driver;
+
+#endif
diff --git a/src/music/os2_m.c b/src/music/os2_m.c
new file mode 100644
index 000000000..75df60c8d
--- /dev/null
+++ b/src/music/os2_m.c
@@ -0,0 +1,77 @@
+/* $Id$ */
+
+#include "../stdafx.h"
+#include "../openttd.h"
+#include "os2_m.h"
+
+#define INCL_DOS
+#define INCL_OS2MM
+#define INCL_WIN
+
+#include <stdarg.h>
+#include <os2.h>
+#include <os2me.h>
+
+/**********************
+ * OS/2 MIDI PLAYER
+ **********************/
+
+/* Interesting how similar the MCI API in OS/2 is to the Win32 MCI API,
+ * eh? Anyone would think they both came from the same place originally! ;)
+ */
+
+static long CDECL MidiSendCommand(const char *cmd, ...)
+{
+ va_list va;
+ char buf[512];
+ va_start(va, cmd);
+ vsprintf(buf, cmd, va);
+ va_end(va);
+ return mciSendString(buf, NULL, 0, NULL, 0);
+}
+
+static void OS2MidiPlaySong(const char *filename)
+{
+ MidiSendCommand("close all");
+
+ if (MidiSendCommand("open %s type sequencer alias song", filename) != 0)
+ return;
+
+ MidiSendCommand("play song from 0");
+}
+
+static void OS2MidiStopSong(void)
+{
+ MidiSendCommand("close all");
+}
+
+static void OS2MidiSetVolume(byte vol)
+{
+ MidiSendCommand("set song audio volume %d", ((vol/127)*100));
+}
+
+static bool OS2MidiIsSongPlaying(void)
+{
+ char buf[16];
+ mciSendString("status song mode", buf, sizeof(buf), NULL, 0);
+ return strcmp(buf, "playing") == 0 || strcmp(buf, "seeking") == 0;
+}
+
+static const char *OS2MidiStart(const char * const *parm)
+{
+ return 0;
+}
+
+static void OS2MidiStop(void)
+{
+ MidiSendCommand("close all");
+}
+
+const HalMusicDriver _os2_music_driver = {
+ OS2MidiStart,
+ OS2MidiStop,
+ OS2MidiPlaySong,
+ OS2MidiStopSong,
+ OS2MidiIsSongPlaying,
+ OS2MidiSetVolume,
+};
diff --git a/src/music/os2_m.h b/src/music/os2_m.h
new file mode 100644
index 000000000..173f096a5
--- /dev/null
+++ b/src/music/os2_m.h
@@ -0,0 +1,10 @@
+/* $Id$ */
+
+#ifndef MUSIC_OS2_H
+#define MUSIC_OS2_H
+
+#include "../hal.h"
+
+extern const HalMusicDriver _os2_music_driver;
+
+#endif
diff --git a/src/music/qtmidi.c b/src/music/qtmidi.c
new file mode 100644
index 000000000..6f0a215d0
--- /dev/null
+++ b/src/music/qtmidi.c
@@ -0,0 +1,371 @@
+/* $Id$ */
+
+/**
+ * @file qtmidi.c
+ * @brief MIDI music player for MacOS X using QuickTime.
+ *
+ * This music player should work in all MacOS X releases starting from 10.0,
+ * as QuickTime is an integral part of the system since the old days of the
+ * Motorola 68k-based Macintoshes. The only extra dependency apart from
+ * QuickTime itself is Carbon, which is included since 10.0 as well.
+ *
+ * QuickTime gets fooled with the MIDI files from Transport Tycoon Deluxe
+ * because of the @c .gm suffix. To force QuickTime to load the MIDI files
+ * without the need of dealing with the individual QuickTime components
+ * needed to play music (data source, MIDI parser, note allocators,
+ * synthesizers and the like) some Carbon functions are used to set the file
+ * type as seen by QuickTime, using @c FSpSetFInfo() (which modifies the
+ * file's resource fork).
+ */
+
+
+/*
+ * OpenTTD includes.
+ */
+#define WindowClass OSX_WindowClass
+#include <QuickTime/QuickTime.h>
+#undef WindowClass
+
+#include "../stdafx.h"
+#include "../openttd.h"
+#include "qtmidi.h"
+
+/*
+ * System includes. We need to workaround with some defines because there's
+ * stuff already defined in QuickTime headers.
+ */
+#define OTTD_Random OSX_OTTD_Random
+#undef OTTD_Random
+#undef WindowClass
+#undef SL_ERROR
+#undef bool
+
+#include <assert.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+// we need to include debug.h after CoreServices because defining DEBUG will break CoreServices in OSX 10.2
+#include "../debug.h"
+
+
+enum {
+ midiType = 'Midi' /**< OSType code for MIDI songs. */
+};
+
+
+/**
+ * Converts a Unix-like pathname to a @c FSSpec structure which may be
+ * used with functions from several MacOS X frameworks (Carbon, QuickTime,
+ * etc). The pointed file or directory must exist.
+ *
+ * @param *path A string containing a Unix-like path.
+ * @param *spec Pointer to a @c FSSpec structure where the result will be
+ * stored.
+ * @return Wether the conversion was successful.
+ */
+static bool PathToFSSpec(const char *path, FSSpec *spec)
+{
+ FSRef ref;
+ assert(spec != NULL);
+ assert(path != NULL);
+
+ return
+ FSPathMakeRef((UInt8*)path, &ref, NULL) == noErr &&
+ FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, spec, NULL) == noErr;
+}
+
+
+/**
+ * Sets the @c OSType of a given file to @c 'Midi', but only if it's not
+ * already set.
+ *
+ * @param *spec A @c FSSpec structure referencing a file.
+ */
+static void SetMIDITypeIfNeeded(const FSSpec *spec)
+{
+ FSRef ref;
+ FSCatalogInfo catalogInfo;
+
+ assert(spec);
+
+ if (noErr != FSpMakeFSRef(spec, &ref)) return;
+ if (noErr != FSGetCatalogInfo(&ref, kFSCatInfoNodeFlags | kFSCatInfoFinderInfo, &catalogInfo, NULL, NULL, NULL)) return;
+ if (!(catalogInfo.nodeFlags & kFSNodeIsDirectoryMask)) {
+ FileInfo * const info = (FileInfo *) catalogInfo.finderInfo;
+ if (info->fileType != midiType && !(info->finderFlags & kIsAlias)) {
+ OSErr e;
+ info->fileType = midiType;
+ e = FSSetCatalogInfo(&ref, kFSCatInfoFinderInfo, &catalogInfo);
+ if (e == noErr) {
+ DEBUG(driver, 3, "qtmidi: changed filetype to 'Midi'");
+ } else {
+ DEBUG(driver, 0, "qtmidi: changing filetype to 'Midi' failed - error %d", e);
+ }
+ }
+ }
+}
+
+
+/**
+ * Loads a MIDI file and returns it as a QuickTime Movie structure.
+ *
+ * @param *path String with the path of an existing MIDI file.
+ * @param *moov Pointer to a @c Movie where the result will be stored.
+ * @return Wether the file was loaded and the @c Movie successfully created.
+ */
+static bool LoadMovieForMIDIFile(const char *path, Movie *moov)
+{
+ int fd;
+ int ret;
+ char magic[4];
+ FSSpec fsspec;
+ short refnum = 0;
+ short resid = 0;
+
+ assert(path != NULL);
+ assert(moov != NULL);
+
+ DEBUG(driver, 2, "qtmidi: start loading '%s'...", path);
+
+ /*
+ * XXX Manual check for MIDI header ('MThd'), as I don't know how to make
+ * QuickTime load MIDI files without a .mid suffix without knowing it's
+ * a MIDI file and setting the OSType of the file to the 'Midi' value.
+ * Perhahaps ugly, but it seems that it does the Right Thing(tm).
+ */
+ fd = open(path, O_RDONLY, 0);
+ if (fd == -1) return false;
+ ret = read(fd, magic, 4);
+ close(fd);
+ if (ret < 4) return false;
+
+ DEBUG(driver, 3, "qtmidi: header is '%.4s'", magic);
+ if (magic[0] != 'M' || magic[1] != 'T' || magic[2] != 'h' || magic[3] != 'd')
+ return false;
+
+ if (!PathToFSSpec(path, &fsspec)) return false;
+ SetMIDITypeIfNeeded(&fsspec);
+
+ if (OpenMovieFile(&fsspec, &refnum, fsRdPerm) != noErr) return false;
+ DEBUG(driver, 3, "qtmidi: '%s' successfully opened", path);
+
+ if (noErr != NewMovieFromFile(moov, refnum, &resid, NULL,
+ newMovieActive | newMovieDontAskUnresolvedDataRefs, NULL)) {
+ CloseMovieFile(refnum);
+ return false;
+ }
+ DEBUG(driver, 3, "qtmidi: movie container created");
+
+ CloseMovieFile(refnum);
+ return true;
+}
+
+
+/**
+ * Flag which has the @c true value when QuickTime is available and
+ * initialized.
+ */
+static bool _quicktime_started = false;
+
+
+/**
+ * Initialize QuickTime if needed. This function sets the
+ * #_quicktime_started flag to @c true if QuickTime is present in the system
+ * and it was initialized properly.
+ */
+static void InitQuickTimeIfNeeded(void)
+{
+ OSStatus dummy;
+
+ if (_quicktime_started) return;
+
+ DEBUG(driver, 2, "qtmidi: initializing Quicktime");
+ /* Be polite: check wether QuickTime is available and initialize it. */
+ _quicktime_started =
+ (noErr == Gestalt(gestaltQuickTime, &dummy)) &&
+ (noErr == EnterMovies());
+ if (!_quicktime_started) DEBUG(driver, 0, "qtmidi: Quicktime initialization failed!");
+}
+
+
+/** Possible states of the QuickTime music driver. */
+enum {
+ QT_STATE_IDLE, /**< No file loaded. */
+ QT_STATE_PLAY, /**< File loaded, playing. */
+ QT_STATE_STOP, /**< File loaded, stopped. */
+};
+
+
+static Movie _quicktime_movie; /**< Current QuickTime @c Movie. */
+static byte _quicktime_volume = 127; /**< Current volume. */
+static int _quicktime_state = QT_STATE_IDLE; /**< Current player state. */
+
+
+/**
+ * Maps OpenTTD volume to QuickTime notion of volume.
+ */
+#define VOLUME ((short)((0x00FF & _quicktime_volume) << 1))
+
+
+static void StopSong(void);
+
+
+/**
+ * Initialized the MIDI player, including QuickTime initialization.
+ *
+ * @todo Give better error messages by inspecting error codes returned by
+ * @c Gestalt() and @c EnterMovies(). Needs changes in
+ * #InitQuickTimeIfNeeded.
+ */
+static const char* StartDriver(const char * const *parm)
+{
+ InitQuickTimeIfNeeded();
+ return (_quicktime_started) ? NULL : "can't initialize QuickTime";
+}
+
+
+/**
+ * Checks wether the player is active.
+ *
+ * This function is called at regular intervals from OpenTTD's main loop, so
+ * we call @c MoviesTask() from here to let QuickTime do its work.
+ */
+static bool SongIsPlaying(void)
+{
+ if (!_quicktime_started) return true;
+
+ switch (_quicktime_state) {
+ case QT_STATE_IDLE:
+ case QT_STATE_STOP:
+ /* Do nothing. */
+ break;
+ case QT_STATE_PLAY:
+ MoviesTask(_quicktime_movie, 0);
+ /* Check wether movie ended. */
+ if (IsMovieDone(_quicktime_movie) ||
+ (GetMovieTime(_quicktime_movie, NULL) >=
+ GetMovieDuration(_quicktime_movie)))
+ _quicktime_state = QT_STATE_STOP;
+ }
+
+ return _quicktime_state == QT_STATE_PLAY;
+}
+
+
+/**
+ * Stops the MIDI player.
+ *
+ * Stops playing and frees any used resources before returning. As it
+ * deinitilizes QuickTime, the #_quicktime_started flag is set to @c false.
+ */
+static void StopDriver(void)
+{
+ if (!_quicktime_started) return;
+
+ DEBUG(driver, 2, "qtmidi: stopping driver...");
+ switch (_quicktime_state) {
+ case QT_STATE_IDLE:
+ DEBUG(driver, 3, "qtmidi: stopping not needed, already idle");
+ /* Do nothing. */
+ break;
+ case QT_STATE_PLAY:
+ StopSong();
+ case QT_STATE_STOP:
+ DisposeMovie(_quicktime_movie);
+ }
+
+ ExitMovies();
+ _quicktime_started = false;
+}
+
+
+/**
+ * Starts playing a new song.
+ *
+ * @param filename Path to a MIDI file.
+ */
+static void PlaySong(const char *filename)
+{
+ if (!_quicktime_started) return;
+
+ DEBUG(driver, 2, "qtmidi: trying to play '%s'", filename);
+ switch (_quicktime_state) {
+ case QT_STATE_PLAY:
+ StopSong();
+ DEBUG(driver, 3, "qtmidi: previous tune stopped");
+ /* XXX Fall-through -- no break needed. */
+ case QT_STATE_STOP:
+ DisposeMovie(_quicktime_movie);
+ DEBUG(driver, 3, "qtmidi: previous tune disposed");
+ _quicktime_state = QT_STATE_IDLE;
+ /* XXX Fall-through -- no break needed. */
+ case QT_STATE_IDLE:
+ LoadMovieForMIDIFile(filename, &_quicktime_movie);
+ SetMovieVolume(_quicktime_movie, VOLUME);
+ StartMovie(_quicktime_movie);
+ _quicktime_state = QT_STATE_PLAY;
+ }
+ DEBUG(driver, 3, "qtmidi: playing '%s'", filename);
+}
+
+
+/**
+ * Stops playing the current song, if the player is active.
+ */
+static void StopSong(void)
+{
+ if (!_quicktime_started) return;
+
+ switch (_quicktime_state) {
+ case QT_STATE_IDLE:
+ /* XXX Fall-through -- no break needed. */
+ case QT_STATE_STOP:
+ DEBUG(driver, 3, "qtmidi: stop requested, but already idle");
+ /* Do nothing. */
+ break;
+ case QT_STATE_PLAY:
+ StopMovie(_quicktime_movie);
+ _quicktime_state = QT_STATE_STOP;
+ DEBUG(driver, 3, "qtmidi: player stopped");
+ }
+}
+
+
+/**
+ * Changes the playing volume of the MIDI player.
+ *
+ * As QuickTime controls volume in a per-movie basis, the desired volume is
+ * stored in #_quicktime_volume, and the volume is set here using the
+ * #VOLUME macro, @b and when loading new song in #PlaySong.
+ *
+ * @param vol The desired volume, range of the value is @c 0-127
+ */
+static void SetVolume(byte vol)
+{
+ if (!_quicktime_started) return;
+
+ _quicktime_volume = vol;
+
+ DEBUG(driver, 2, "qtmidi: set volume to %u (%hi)", vol, VOLUME);
+ switch (_quicktime_state) {
+ case QT_STATE_IDLE:
+ /* Do nothing. */
+ break;
+ case QT_STATE_PLAY:
+ case QT_STATE_STOP:
+ SetMovieVolume(_quicktime_movie, VOLUME);
+ }
+}
+
+
+/**
+ * Table of callbacks that implement the QuickTime MIDI player.
+ */
+const HalMusicDriver _qtime_music_driver = {
+ StartDriver,
+ StopDriver,
+ PlaySong,
+ StopSong,
+ SongIsPlaying,
+ SetVolume,
+};
diff --git a/src/music/qtmidi.h b/src/music/qtmidi.h
new file mode 100644
index 000000000..727ce25e1
--- /dev/null
+++ b/src/music/qtmidi.h
@@ -0,0 +1,10 @@
+/* $Id$ */
+
+#ifndef MUSIC_MACOSX_QUICKTIME_H
+#define MUSIC_MACOSX_QUICKTIME_H
+
+#include "../hal.h"
+
+extern const HalMusicDriver _qtime_music_driver;
+
+#endif /* !MUSIC_MACOSX_QUICKTIME_H */
diff --git a/src/music/win32_m.c b/src/music/win32_m.c
new file mode 100644
index 000000000..36b79b30b
--- /dev/null
+++ b/src/music/win32_m.c
@@ -0,0 +1,170 @@
+/* $Id$ */
+
+#include "../stdafx.h"
+#include "../openttd.h"
+#include "win32_m.h"
+#include <windows.h>
+#include <mmsystem.h>
+
+static struct {
+ bool stop_song;
+ bool terminate;
+ bool playing;
+ int new_vol;
+ HANDLE wait_obj;
+ UINT_PTR devid;
+ char start_song[260];
+} _midi;
+
+static void Win32MidiPlaySong(const char *filename)
+{
+ strcpy(_midi.start_song, filename);
+ _midi.playing = true;
+ _midi.stop_song = false;
+ SetEvent(_midi.wait_obj);
+}
+
+static void Win32MidiStopSong(void)
+{
+ if (_midi.playing) {
+ _midi.stop_song = true;
+ _midi.start_song[0] = '\0';
+ SetEvent(_midi.wait_obj);
+ }
+}
+
+static bool Win32MidiIsSongPlaying(void)
+{
+ return _midi.playing;
+}
+
+static void Win32MidiSetVolume(byte vol)
+{
+ _midi.new_vol = vol;
+ SetEvent(_midi.wait_obj);
+}
+
+static MCIERROR CDECL MidiSendCommand(const char* cmd, ...)
+{
+ va_list va;
+ char buf[512];
+
+ va_start(va, cmd);
+ vsprintf(buf, cmd, va);
+ va_end(va);
+ return mciSendStringA(buf, NULL, 0, 0);
+}
+
+static bool MidiIntPlaySong(const char *filename)
+{
+ MidiSendCommand("close all");
+ if (MidiSendCommand("open \"%s\" type sequencer alias song", filename) != 0)
+ return false;
+
+ if (MidiSendCommand("play song from 0") != 0)
+ return false;
+ return true;
+}
+
+static void MidiIntStopSong(void)
+{
+ MidiSendCommand("close all");
+}
+
+static void MidiIntSetVolume(int vol)
+{
+ DWORD v = (vol * 65535 / 127);
+ midiOutSetVolume((HMIDIOUT)_midi.devid, v + (v << 16));
+}
+
+static bool MidiIntIsSongPlaying(void)
+{
+ char buf[16];
+ mciSendStringA("status song mode", buf, sizeof(buf), 0);
+ return strcmp(buf, "playing") == 0 || strcmp(buf, "seeking") == 0;
+}
+
+static DWORD WINAPI MidiThread(LPVOID arg)
+{
+ _midi.wait_obj = CreateEvent(NULL, FALSE, FALSE, NULL);
+
+ do {
+ char *s;
+ int vol;
+
+ vol = _midi.new_vol;
+ if (vol != -1) {
+ _midi.new_vol = -1;
+ MidiIntSetVolume(vol);
+ }
+
+ s = _midi.start_song;
+ if (s[0] != '\0') {
+ _midi.playing = MidiIntPlaySong(s);
+ s[0] = '\0';
+
+ // Delay somewhat in case we don't manage to play.
+ if (!_midi.playing) {
+ Sleep(5000);
+ }
+ }
+
+ if (_midi.stop_song && _midi.playing) {
+ _midi.stop_song = false;
+ _midi.playing = false;
+ MidiIntStopSong();
+ }
+
+ if (_midi.playing && !MidiIntIsSongPlaying())
+ _midi.playing = false;
+
+ WaitForMultipleObjects(1, &_midi.wait_obj, FALSE, 1000);
+ } while (!_midi.terminate);
+
+ DeleteObject(_midi.wait_obj);
+ return 0;
+}
+
+static const char *Win32MidiStart(const char * const *parm)
+{
+ MIDIOUTCAPS midicaps;
+ DWORD threadId;
+ UINT nbdev;
+ UINT_PTR dev;
+ char buf[16];
+
+ mciSendStringA("capability sequencer has audio", buf, lengthof(buf), 0);
+ if (strcmp(buf, "true") != 0) return "MCI sequencer can't play audio";
+
+ memset(&_midi, 0, sizeof(_midi));
+ _midi.new_vol = -1;
+
+ /* Get midi device */
+ _midi.devid = MIDI_MAPPER;
+ for (dev = 0, nbdev = midiOutGetNumDevs(); dev < nbdev; dev++) {
+ if (midiOutGetDevCaps(dev, &midicaps, sizeof(midicaps)) == 0 && (midicaps.dwSupport & MIDICAPS_VOLUME)) {
+ _midi.devid = dev;
+ break;
+ }
+ }
+
+ if (CreateThread(NULL, 8192, MidiThread, 0, 0, &threadId) == NULL)
+ return "Failed to create thread";
+
+ return NULL;
+}
+
+static void Win32MidiStop(void)
+{
+ _midi.terminate = true;
+ SetEvent(_midi.wait_obj);
+}
+
+const HalMusicDriver _win32_music_driver = {
+ Win32MidiStart,
+ Win32MidiStop,
+ Win32MidiPlaySong,
+ Win32MidiStopSong,
+ Win32MidiIsSongPlaying,
+ Win32MidiSetVolume,
+};
diff --git a/src/music/win32_m.h b/src/music/win32_m.h
new file mode 100644
index 000000000..83893ed1e
--- /dev/null
+++ b/src/music/win32_m.h
@@ -0,0 +1,10 @@
+/* $Id$ */
+
+#ifndef MUSIC_WIN32_H
+#define MUSIC_WIN32_H
+
+#include "../hal.h"
+
+extern const HalMusicDriver _win32_music_driver;
+
+#endif
diff --git a/src/music_gui.c b/src/music_gui.c
new file mode 100644
index 000000000..84a6324c2
--- /dev/null
+++ b/src/music_gui.c
@@ -0,0 +1,506 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "table/strings.h"
+#include "table/sprites.h"
+#include "functions.h"
+#include "window.h"
+#include "gfx.h"
+#include "sound.h"
+#include "hal.h"
+#include "macros.h"
+#include "variables.h"
+#include "music.h"
+
+static byte _music_wnd_cursong;
+static bool _song_is_active;
+static byte _cur_playlist[NUM_SONGS_PLAYLIST];
+
+
+
+static byte _playlist_all[] = {
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 0
+};
+
+static byte _playlist_old_style[] = {
+ 1, 8, 2, 9, 14, 15, 19, 13, 0
+};
+
+static byte _playlist_new_style[] = {
+ 6, 11, 10, 17, 21, 18, 5, 0
+};
+
+static byte _playlist_ezy_street[] = {
+ 12, 7, 16, 3, 20, 4, 0
+};
+
+static byte * const _playlists[] = {
+ _playlist_all,
+ _playlist_old_style,
+ _playlist_new_style,
+ _playlist_ezy_street,
+ msf.custom_1,
+ msf.custom_2,
+};
+
+static void SkipToPrevSong(void)
+{
+ byte *b = _cur_playlist;
+ byte *p = b;
+ byte t;
+
+ if (b[0] == 0) return; // empty playlist
+
+ do p++; while (p[0] != 0); // find the end
+
+ t = *--p; // and copy the bytes
+ while (p != b) {
+ p--;
+ p[1] = p[0];
+ }
+ *b = t;
+
+ _song_is_active = false;
+}
+
+static void SkipToNextSong(void)
+{
+ byte* b = _cur_playlist;
+ byte t;
+
+ t = b[0];
+ if (t != 0) {
+ while (b[1] != 0) {
+ b[0] = b[1];
+ b++;
+ }
+ b[0] = t;
+ }
+
+ _song_is_active = false;
+}
+
+static void MusicVolumeChanged(byte new_vol)
+{
+ _music_driver->set_volume(new_vol);
+}
+
+static void DoPlaySong(void)
+{
+ char filename[256];
+ snprintf(filename, sizeof(filename), "%s%s",
+ _paths.gm_dir, origin_songs_specs[_music_wnd_cursong - 1].filename);
+ _music_driver->play_song(filename);
+}
+
+static void DoStopMusic(void)
+{
+ _music_driver->stop_song();
+}
+
+static void SelectSongToPlay(void)
+{
+ uint i = 0;
+ uint j = 0;
+ char filename[256];
+
+ memset(_cur_playlist, 0, sizeof(_cur_playlist));
+ do {
+ if (_playlists[msf.playlist][i] != 0) { // Don't evaluate playlist terminator
+ snprintf(filename, sizeof(filename), "%s%s",
+ _paths.gm_dir, origin_songs_specs[(_playlists[msf.playlist][i]) - 1].filename);
+
+ /* we are now checking for the existence of that file prior
+ * to add it to the list of available songs */
+ if (FileExists(filename)) {
+ _cur_playlist[j] = _playlists[msf.playlist][i];
+ j++;
+ }
+ }
+ } while (_playlists[msf.playlist][i++] != 0 && i < lengthof(_cur_playlist) - 1);
+
+ if (msf.shuffle) {
+ i = 500;
+ do {
+ uint32 r = InteractiveRandom();
+ byte *a = &_cur_playlist[GB(r, 0, 5)];
+ byte *b = &_cur_playlist[GB(r, 8, 5)];
+
+ if (*a != 0 && *b != 0) {
+ byte t = *a;
+ *a = *b;
+ *b = t;
+ }
+ } while (--i);
+ }
+}
+
+static void StopMusic(void)
+{
+ _music_wnd_cursong = 0;
+ DoStopMusic();
+ _song_is_active = false;
+ InvalidateWindowWidget(WC_MUSIC_WINDOW, 0, 9);
+}
+
+static void PlayPlaylistSong(void)
+{
+ if (_cur_playlist[0] == 0) {
+ SelectSongToPlay();
+ /* if there is not songs in the playlist, it may indicate
+ * no file on the gm folder, or even no gm folder.
+ * Stop the playback, then */
+ if (_cur_playlist[0] == 0) {
+ _song_is_active = false;
+ _music_wnd_cursong = 0;
+ msf.playing = false;
+ return;
+ }
+ }
+ _music_wnd_cursong = _cur_playlist[0];
+ DoPlaySong();
+ _song_is_active = true;
+
+ InvalidateWindowWidget(WC_MUSIC_WINDOW, 0, 9);
+}
+
+void ResetMusic(void)
+{
+ _music_wnd_cursong = 1;
+ DoPlaySong();
+}
+
+void MusicLoop(void)
+{
+ if (!msf.playing && _song_is_active) {
+ StopMusic();
+ } else if (msf.playing && !_song_is_active) {
+ PlayPlaylistSong();
+ }
+
+ if (!_song_is_active) return;
+
+ if (!_music_driver->is_song_playing()) {
+ if (_game_mode != GM_MENU) {
+ StopMusic();
+ SkipToNextSong();
+ PlayPlaylistSong();
+ } else {
+ ResetMusic();
+ }
+ }
+}
+
+static void MusicTrackSelectionWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ const byte* p;
+ uint i;
+ int y;
+
+ SetWindowWidgetDisabledState(w, 11, msf.playlist <= 3);
+ LowerWindowWidget(w, 3);
+ LowerWindowWidget(w, 4);
+ DrawWindowWidgets(w);
+
+ GfxFillRect(3, 23, 3+177,23+191,0);
+ GfxFillRect(251, 23, 251+177,23+191,0);
+
+ DrawStringCentered(92, 15, STR_01EE_TRACK_INDEX, 0);
+
+ SetDParam(0, STR_01D5_ALL + msf.playlist);
+ DrawStringCentered(340, 15, STR_01EF_PROGRAM, 0);
+
+ for (i = 1; i <= NUM_SONGS_AVAILABLE; i++) {
+ SetDParam(0, i);
+ SetDParam(2, i);
+ SetDParam(1, SPECSTR_SONGNAME);
+ DrawString(4, 23+(i-1)*6, (i < 10) ? STR_01EC_0 : STR_01ED, 0);
+ }
+
+ for (i = 0; i != 6; i++) {
+ DrawStringCentered(216, 45 + i * 8, STR_01D5_ALL + i, (i == msf.playlist) ? 0xC : 0x10);
+ }
+
+ DrawStringCentered(216, 45+8*6+16, STR_01F0_CLEAR, 0);
+#if 0
+ DrawStringCentered(216, 45 + 8 * 6 + 16 * 2, STR_01F1_SAVE, 0);
+#endif
+
+ y = 23;
+ for (p = _playlists[msf.playlist], i = 0; (i = *p) != 0; p++) {
+ SetDParam(0, i);
+ SetDParam(1, SPECSTR_SONGNAME);
+ SetDParam(2, i);
+ DrawString(252, y, (i < 10) ? STR_01EC_0 : STR_01ED, 0);
+ y += 6;
+ }
+ break;
+ }
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 3: { // add to playlist
+ int y = (e->we.click.pt.y - 23) / 6;
+ uint i;
+ byte *p;
+
+ if (msf.playlist < 4) return;
+ if (!IS_INT_INSIDE(y, 0, NUM_SONGS_AVAILABLE)) return;
+
+ p = _playlists[msf.playlist];
+ for (i = 0; i != NUM_SONGS_PLAYLIST - 1; i++) {
+ if (p[i] == 0) {
+ p[i] = y + 1;
+ p[i + 1] = 0;
+ SetWindowDirty(w);
+ SelectSongToPlay();
+ break;
+ }
+ }
+ } break;
+
+ case 4: { // remove from playlist
+ int y = (e->we.click.pt.y - 23) / 6;
+ uint i;
+ byte *p;
+
+ if (msf.playlist < 4) return;
+ if (!IS_INT_INSIDE(y, 0, NUM_SONGS_AVAILABLE)) return;
+
+ p = _playlists[msf.playlist];
+ for (i = y; i != NUM_SONGS_PLAYLIST - 1; i++) {
+ p[i] = p[i + 1];
+ }
+
+ SetWindowDirty(w);
+ SelectSongToPlay();
+ } break;
+
+ case 11: // clear
+ _playlists[msf.playlist][0] = 0;
+ SetWindowDirty(w);
+ StopMusic();
+ SelectSongToPlay();
+ break;
+
+#if 0
+ case 12: // save
+ ShowInfo("MusicTrackSelectionWndProc:save not implemented\n");
+ break;
+#endif
+
+ case 5: case 6: case 7: case 8: case 9: case 10: /* set playlist */
+ msf.playlist = e->we.click.widget - 5;
+ SetWindowDirty(w);
+ InvalidateWindow(WC_MUSIC_WINDOW, 0);
+ StopMusic();
+ SelectSongToPlay();
+ break;
+ }
+ break;
+ }
+}
+
+static const Widget _music_track_selection_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 431, 0, 13, STR_01EB_MUSIC_PROGRAM_SELECTION, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 431, 14, 217, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 14, 2, 181, 22, 215, 0x0, STR_01FA_CLICK_ON_MUSIC_TRACK_TO},
+{ WWT_PANEL, RESIZE_NONE, 14, 250, 429, 22, 215, 0x0, STR_CLICK_ON_TRACK_TO_REMOVE},
+{ WWT_PUSHBTN, RESIZE_NONE, 14, 186, 245, 44, 51, 0x0, STR_01F3_SELECT_ALL_TRACKS_PROGRAM},
+{ WWT_PUSHBTN, RESIZE_NONE, 14, 186, 245, 52, 59, 0x0, STR_01F4_SELECT_OLD_STYLE_MUSIC},
+{ WWT_PUSHBTN, RESIZE_NONE, 14, 186, 245, 60, 67, 0x0, STR_01F5_SELECT_NEW_STYLE_MUSIC},
+{ WWT_PUSHBTN, RESIZE_NONE, 14, 186, 245, 68, 75, 0x0, STR_0330_SELECT_EZY_STREET_STYLE},
+{ WWT_PUSHBTN, RESIZE_NONE, 14, 186, 245, 76, 83, 0x0, STR_01F6_SELECT_CUSTOM_1_USER_DEFINED},
+{ WWT_PUSHBTN, RESIZE_NONE, 14, 186, 245, 84, 91, 0x0, STR_01F7_SELECT_CUSTOM_2_USER_DEFINED},
+{ WWT_PUSHBTN, RESIZE_NONE, 14, 186, 245, 108, 115, 0x0, STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1},
+#if 0
+{ WWT_PUSHBTN, RESIZE_NONE, 14, 186, 245, 124, 131, 0x0, STR_01F9_SAVE_MUSIC_SETTINGS},
+#endif
+{ WIDGETS_END},
+};
+
+static const WindowDesc _music_track_selection_desc = {
+ 104, 131, 432, 218,
+ WC_MUSIC_TRACK_SELECTION,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _music_track_selection_widgets,
+ MusicTrackSelectionWndProc
+};
+
+static void ShowMusicTrackSelection(void)
+{
+ AllocateWindowDescFront(&_music_track_selection_desc, 0);
+}
+
+static void MusicWindowWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ uint i;
+ StringID str;
+
+ RaiseWindowWidget(w, 7);
+ RaiseWindowWidget(w, 9);
+ DrawWindowWidgets(w);
+
+ GfxFillRect(187, 16, 200, 33, 0);
+
+ for (i = 0; i != 8; i++) {
+ int color = 0xD0;
+ if (i > 4) {
+ color = 0xBF;
+ if (i > 6) {
+ color = 0xB8;
+ }
+ }
+ GfxFillRect(187, NUM_SONGS_PLAYLIST - i * 2, 200, NUM_SONGS_PLAYLIST - i * 2, color);
+ }
+
+ GfxFillRect(60, 46, 239, 52, 0);
+
+ if (_song_is_active == 0 || _music_wnd_cursong == 0) {
+ str = STR_01E3;
+ } else {
+ SetDParam(0, _music_wnd_cursong);
+ str = (_music_wnd_cursong < 10) ? STR_01E4_0 : STR_01E5;
+ }
+ DrawString(62, 46, str, 0);
+
+ str = STR_01E6;
+ if (_song_is_active != 0 && _music_wnd_cursong != 0) {
+ str = STR_01E7;
+ SetDParam(0, SPECSTR_SONGNAME);
+ SetDParam(1, _music_wnd_cursong);
+ }
+ DrawStringCentered(155, 46, str, 0);
+
+
+ DrawString(60, 38, STR_01E8_TRACK_XTITLE, 0);
+
+ for (i = 0; i != 6; i++) {
+ DrawStringCentered(25 + i * 50, 59, STR_01D5_ALL + i, msf.playlist == i ? 0xC : 0x10);
+ }
+
+ DrawStringCentered(31, 43, STR_01E9_SHUFFLE, (msf.shuffle ? 0xC : 0x10));
+ DrawStringCentered(269, 43, STR_01EA_PROGRAM, 0);
+ DrawStringCentered(141, 15, STR_01DB_MUSIC_VOLUME, 0);
+ DrawStringCentered(141, 29, STR_01DD_MIN_MAX, 0);
+ DrawStringCentered(247, 15, STR_01DC_EFFECTS_VOLUME, 0);
+ DrawStringCentered(247, 29, STR_01DD_MIN_MAX, 0);
+
+ DrawFrameRect(108, 23, 174, 26, 14, FR_LOWERED);
+ DrawFrameRect(214, 23, 280, 26, 14, FR_LOWERED);
+
+ DrawFrameRect(
+ 108 + msf.music_vol / 2, 22, 111 + msf.music_vol / 2, 28, 14, 0
+ );
+
+ DrawFrameRect(
+ 214 + msf.effect_vol / 2, 22, 217 + msf.effect_vol / 2, 28, 14, 0
+ );
+ } break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 2: // skip to prev
+ if (!_song_is_active)
+ return;
+ SkipToPrevSong();
+ break;
+ case 3: // skip to next
+ if (!_song_is_active)
+ return;
+ SkipToNextSong();
+ break;
+ case 4: // stop playing
+ msf.playing = false;
+ break;
+ case 5: // start playing
+ msf.playing = true;
+ break;
+ case 6:{ // volume sliders
+ byte *vol,new_vol;
+ int x = e->we.click.pt.x - 88;
+
+ if (x < 0)
+ return;
+
+ vol = &msf.music_vol;
+ if (x >= 106) {
+ vol = &msf.effect_vol;
+ x -= 106;
+ }
+
+ new_vol = min(max(x-21,0)*2,127);
+ if (new_vol != *vol) {
+ *vol = new_vol;
+ if (vol == &msf.music_vol)
+ MusicVolumeChanged(new_vol);
+ SetWindowDirty(w);
+ }
+
+ _left_button_clicked = false;
+ } break;
+ case 10: //toggle shuffle
+ msf.shuffle ^= 1;
+ StopMusic();
+ SelectSongToPlay();
+ break;
+ case 11: //show track selection
+ ShowMusicTrackSelection();
+ break;
+ case 12: case 13: case 14: case 15: case 16: case 17: // playlist
+ msf.playlist = e->we.click.widget - 12;
+ SetWindowDirty(w);
+ InvalidateWindow(WC_MUSIC_TRACK_SELECTION, 0);
+ StopMusic();
+ SelectSongToPlay();
+ break;
+ }
+ break;
+
+ case WE_MOUSELOOP:
+ InvalidateWindowWidget(WC_MUSIC_WINDOW, 0, 7);
+ break;
+ }
+
+}
+
+static const Widget _music_window_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 299, 0, 13, STR_01D2_JAZZ_JUKEBOX, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PUSHIMGBTN, RESIZE_NONE, 14, 0, 21, 14, 35, SPR_IMG_SKIP_TO_PREV, STR_01DE_SKIP_TO_PREVIOUS_TRACK},
+{ WWT_PUSHIMGBTN, RESIZE_NONE, 14, 22, 43, 14, 35, SPR_IMG_SKIP_TO_NEXT, STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION},
+{ WWT_PUSHIMGBTN, RESIZE_NONE, 14, 44, 65, 14, 35, SPR_IMG_STOP_MUSIC, STR_01E0_STOP_PLAYING_MUSIC},
+{ WWT_PUSHIMGBTN, RESIZE_NONE, 14, 66, 87, 14, 35, SPR_IMG_PLAY_MUSIC, STR_01E1_START_PLAYING_MUSIC},
+{ WWT_PANEL, RESIZE_NONE, 14, 88, 299, 14, 35, 0x0, STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC},
+{ WWT_PANEL, RESIZE_NONE, 14, 186, 201, 15, 34, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 299, 36, 57, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 14, 59, 240, 45, 53, 0x0, STR_NULL},
+{ WWT_PUSHBTN, RESIZE_NONE, 14, 6, 55, 42, 49, 0x0, STR_01FB_TOGGLE_PROGRAM_SHUFFLE},
+{ WWT_PUSHBTN, RESIZE_NONE, 14, 244, 293, 42, 49, 0x0, STR_01FC_SHOW_MUSIC_TRACK_SELECTION},
+{ WWT_PUSHBTN, RESIZE_NONE, 14, 0, 49, 58, 65, 0x0, STR_01F3_SELECT_ALL_TRACKS_PROGRAM},
+{ WWT_PUSHBTN, RESIZE_NONE, 14, 50, 99, 58, 65, 0x0, STR_01F4_SELECT_OLD_STYLE_MUSIC},
+{ WWT_PUSHBTN, RESIZE_NONE, 14, 100, 149, 58, 65, 0x0, STR_01F5_SELECT_NEW_STYLE_MUSIC},
+{ WWT_PUSHBTN, RESIZE_NONE, 14, 150, 199, 58, 65, 0x0, STR_0330_SELECT_EZY_STREET_STYLE},
+{ WWT_PUSHBTN, RESIZE_NONE, 14, 200, 249, 58, 65, 0x0, STR_01F6_SELECT_CUSTOM_1_USER_DEFINED},
+{ WWT_PUSHBTN, RESIZE_NONE, 14, 250, 299, 58, 65, 0x0, STR_01F7_SELECT_CUSTOM_2_USER_DEFINED},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _music_window_desc = {
+ 0, 22, 300, 66,
+ WC_MUSIC_WINDOW,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _music_window_widgets,
+ MusicWindowWndProc
+};
+
+void ShowMusicWindow(void)
+{
+ AllocateWindowDescFront(&_music_window_desc, 0);
+}
diff --git a/src/namegen.c b/src/namegen.c
new file mode 100644
index 000000000..c70cc2d35
--- /dev/null
+++ b/src/namegen.c
@@ -0,0 +1,790 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "debug.h"
+#include "macros.h"
+#include "namegen.h"
+#include "table/namegen.h"
+#include "string.h"
+
+static inline uint32 SeedChance(int shift_by, int max, uint32 seed)
+{
+ return (GB(seed, shift_by, 16) * max) >> 16;
+}
+
+static inline uint32 SeedModChance(int shift_by, int max, uint32 seed)
+{
+ /* This actually gives *MUCH* more even distribution of the values
+ * than SeedChance(), which is absolutely horrible in that. If
+ * you do not believe me, try with i.e. the Czech town names,
+ * compare the words (nicely visible on prefixes) generated by
+ * SeedChance() and SeedModChance(). Do not get dicouraged by the
+ * never-use-modulo myths, which hold true only for the linear
+ * congruential generators (and Random() isn't such a generator).
+ * --pasky */
+ // TODO: Perhaps we should use it for all the name generators? --pasky
+ return (seed >> shift_by) % max;
+}
+
+static inline int32 SeedChanceBias(int shift_by, int max, uint32 seed, int bias)
+{
+ return SeedChance(shift_by, max + bias, seed) - bias;
+}
+
+static void ReplaceWords(const char *org, const char *rep, char *buf)
+{
+ if (strncmp(buf, org, 4) == 0) strncpy(buf, rep, 4);
+}
+
+static byte MakeEnglishOriginalTownName(char *buf, uint32 seed, const char *last)
+{
+ int i;
+
+ //null terminates the string for strcat
+ strecpy(buf, "", last);
+
+ // optional first segment
+ i = SeedChanceBias(0, lengthof(name_original_english_1), seed, 50);
+ if (i >= 0)
+ strecat(buf, name_original_english_1[i], last);
+
+ //mandatory middle segments
+ strecat(buf, name_original_english_2[SeedChance(4, lengthof(name_original_english_2), seed)], last);
+ strecat(buf, name_original_english_3[SeedChance(7, lengthof(name_original_english_3), seed)], last);
+ strecat(buf, name_original_english_4[SeedChance(10, lengthof(name_original_english_4), seed)], last);
+ strecat(buf, name_original_english_5[SeedChance(13, lengthof(name_original_english_5), seed)], last);
+
+ //optional last segment
+ i = SeedChanceBias(15, lengthof(name_original_english_6), seed, 60);
+ if (i >= 0)
+ strecat(buf, name_original_english_6[i], last);
+
+ if (buf[0] == 'C' && (buf[1] == 'e' || buf[1] == 'i'))
+ buf[0] = 'K';
+
+ ReplaceWords("Cunt", "East", buf);
+ ReplaceWords("Slag", "Pits", buf);
+ ReplaceWords("Slut", "Edin", buf);
+ //ReplaceWords("Fart", "Boot", buf);
+ ReplaceWords("Drar", "Quar", buf);
+ ReplaceWords("Dreh", "Bash", buf);
+ ReplaceWords("Frar", "Shor", buf);
+ ReplaceWords("Grar", "Aber", buf);
+ ReplaceWords("Brar", "Over", buf);
+ ReplaceWords("Wrar", "Inve", buf);
+
+ return 0;
+}
+
+
+static byte MakeEnglishAdditionalTownName(char *buf, uint32 seed, const char *last)
+{
+ int i;
+
+ //null terminates the string for strcat
+ strecpy(buf, "", last);
+
+ // optional first segment
+ i = SeedChanceBias(0, lengthof(name_additional_english_prefix), seed, 50);
+ if (i >= 0)
+ strecat(buf,name_additional_english_prefix[i], last);
+
+ if (SeedChance(3, 20, seed) >= 14) {
+ strecat(buf, name_additional_english_1a[SeedChance(6, lengthof(name_additional_english_1a), seed)], last);
+ } else {
+ strecat(buf, name_additional_english_1b1[SeedChance(6, lengthof(name_additional_english_1b1), seed)], last);
+ strecat(buf, name_additional_english_1b2[SeedChance(9, lengthof(name_additional_english_1b2), seed)], last);
+ if (SeedChance(11, 20, seed) >= 4) {
+ strecat(buf, name_additional_english_1b3a[SeedChance(12, lengthof(name_additional_english_1b3a), seed)], last);
+ } else {
+ strecat(buf, name_additional_english_1b3b[SeedChance(12, lengthof(name_additional_english_1b3b), seed)], last);
+ }
+ }
+
+ strecat(buf, name_additional_english_2[SeedChance(14, lengthof(name_additional_english_2), seed)], last);
+
+ //optional last segment
+ i = SeedChanceBias(15, lengthof(name_additional_english_3), seed, 60);
+ if (i >= 0)
+ strecat(buf, name_additional_english_3[i], last);
+
+ ReplaceWords("Cunt", "East", buf);
+ ReplaceWords("Slag", "Pits", buf);
+ ReplaceWords("Slut", "Edin", buf);
+ ReplaceWords("Fart", "Boot", buf);
+ ReplaceWords("Drar", "Quar", buf);
+ ReplaceWords("Dreh", "Bash", buf);
+ ReplaceWords("Frar", "Shor", buf);
+ ReplaceWords("Grar", "Aber", buf);
+ ReplaceWords("Brar", "Over", buf);
+ ReplaceWords("Wrar", "Stan", buf);
+
+ return 0;
+}
+
+static byte MakeAustrianTownName(char *buf, uint32 seed, const char *last)
+{
+ int i, j = 0;
+ strecpy(buf, "", last);
+
+ // Bad, Maria, Gross, ...
+ i = SeedChanceBias(0, lengthof(name_austrian_a1), seed, 15);
+ if (i >= 0) strecat(buf, name_austrian_a1[i], last);
+
+ i = SeedChance(4, 6, seed);
+ if (i >= 4) {
+ // Kaisers-kirchen
+ strecat(buf, name_austrian_a2[SeedChance( 7, lengthof(name_austrian_a2), seed)], last);
+ strecat(buf, name_austrian_a3[SeedChance(13, lengthof(name_austrian_a3), seed)], last);
+ } else if (i >= 2) {
+ // St. Johann
+ strecat(buf, name_austrian_a5[SeedChance( 7, lengthof(name_austrian_a5), seed)], last);
+ strecat(buf, name_austrian_a6[SeedChance( 9, lengthof(name_austrian_a6), seed)], last);
+ j = 1; // More likely to have a " an der " or " am "
+ } else {
+ // Zell
+ strecat(buf, name_austrian_a4[SeedChance( 7, lengthof(name_austrian_a4), seed)], last);
+ }
+
+ i = SeedChance(1, 6, seed);
+ if (i >= 4 - j) {
+ // an der Donau (rivers)
+ strecat(buf, name_austrian_f1[SeedChance(4, lengthof(name_austrian_f1), seed)], last);
+ strecat(buf, name_austrian_f2[SeedChance(5, lengthof(name_austrian_f2), seed)], last);
+ } else if (i >= 2 - j) {
+ // am Dachstein (mountains)
+ strecat(buf, name_austrian_b1[SeedChance(4, lengthof(name_austrian_b1), seed)], last);
+ strecat(buf, name_austrian_b2[SeedChance(5, lengthof(name_austrian_b2), seed)], last);
+ }
+
+ return 0;
+}
+
+static byte MakeGermanTownName(char *buf, uint32 seed, const char *last)
+{
+ uint i;
+ uint seed_derivative;
+
+ //null terminates the string for strcat
+ strecpy(buf, "", last);
+
+ seed_derivative = SeedChance(7, 28, seed);
+
+ //optional prefix
+ if (seed_derivative == 12 || seed_derivative == 19) {
+ i = SeedChance(2, lengthof(name_german_pre), seed);
+ strecat(buf,name_german_pre[i], last);
+ }
+
+ // mandatory middle segments including option of hardcoded name
+ i = SeedChance(3, lengthof(name_german_real) + lengthof(name_german_1), seed);
+ if (i < lengthof(name_german_real)) {
+ strecat(buf,name_german_real[i], last);
+ } else {
+ strecat(buf, name_german_1[i - lengthof(name_german_real)], last);
+
+ i = SeedChance(5, lengthof(name_german_2), seed);
+ strecat(buf, name_german_2[i], last);
+ }
+
+ // optional suffix
+ if (seed_derivative == 24) {
+ i = SeedChance(9,
+ lengthof(name_german_4_an_der) + lengthof(name_german_4_am), seed);
+ if (i < lengthof(name_german_4_an_der)) {
+ strecat(buf, name_german_3_an_der[0], last);
+ strecat(buf, name_german_4_an_der[i], last);
+ } else {
+ strecat(buf, name_german_3_am[0], last);
+ strecat(buf, name_german_4_am[i - lengthof(name_german_4_an_der)], last);
+ }
+ }
+ return 0;
+}
+
+static byte MakeSpanishTownName(char *buf, uint32 seed, const char *last)
+{
+ strecpy(buf, name_spanish_real[SeedChance(0, lengthof(name_spanish_real), seed)], last);
+ return 0;
+}
+
+static byte MakeFrenchTownName(char *buf, uint32 seed, const char *last)
+{
+ strecpy(buf, name_french_real[SeedChance(0, lengthof(name_french_real), seed)], last);
+ return 0;
+}
+
+static byte MakeSillyTownName(char *buf, uint32 seed, const char *last)
+{
+ strecpy(buf, name_silly_1[SeedChance( 0, lengthof(name_silly_1), seed)], last);
+ strecat(buf, name_silly_2[SeedChance(16, lengthof(name_silly_2), seed)], last);
+ return 0;
+}
+
+static byte MakeSwedishTownName(char *buf, uint32 seed, const char *last)
+{
+ int i;
+
+ //null terminates the string for strcat
+ strecpy(buf, "", last);
+
+ // optional first segment
+ i = SeedChanceBias(0, lengthof(name_swedish_1), seed, 50);
+ if (i >= 0)
+ strecat(buf, name_swedish_1[i], last);
+
+ // mandatory middle segments including option of hardcoded name
+ if (SeedChance(4, 5, seed) >= 3) {
+ strecat(buf, name_swedish_2[SeedChance( 7, lengthof(name_swedish_2), seed)], last);
+ } else {
+ strecat(buf, name_swedish_2a[SeedChance( 7, lengthof(name_swedish_2a), seed)], last);
+ strecat(buf, name_swedish_2b[SeedChance(10, lengthof(name_swedish_2b), seed)], last);
+ strecat(buf, name_swedish_2c[SeedChance(13, lengthof(name_swedish_2c), seed)], last);
+ }
+
+ strecat(buf, name_swedish_3[SeedChance(16, lengthof(name_swedish_3), seed)], last);
+
+ return 0;
+}
+
+static byte MakeDutchTownName(char *buf, uint32 seed, const char *last)
+{
+ int i;
+
+ //null terminates the string for strcat
+ strecpy(buf, "", last);
+
+ // optional first segment
+ i = SeedChanceBias(0, lengthof(name_dutch_1), seed, 50);
+ if (i >= 0)
+ strecat(buf, name_dutch_1[i], last);
+
+ // mandatory middle segments including option of hardcoded name
+ if (SeedChance(6, 9, seed) > 4) {
+ strecat(buf, name_dutch_2[SeedChance( 9, lengthof(name_dutch_2), seed)], last);
+ } else {
+ strecat(buf, name_dutch_3[SeedChance( 9, lengthof(name_dutch_3), seed)], last);
+ strecat(buf, name_dutch_4[SeedChance(12, lengthof(name_dutch_4), seed)], last);
+ }
+ strecat(buf, name_dutch_5[SeedChance(15, lengthof(name_dutch_5), seed)], last);
+
+ return 0;
+}
+
+static byte MakeFinnishTownName(char *buf, uint32 seed, const char *last)
+{
+ //null terminates the string for strcat
+ strecpy(buf, "", last);
+
+ // Select randomly if town name should consists of one or two parts.
+ if (SeedChance(0, 15, seed) >= 10) {
+ strecat(buf, name_finnish_real[SeedChance(2, lengthof(name_finnish_real), seed)], last);
+ } else if (SeedChance(0, 15, seed) >= 5) {
+ // A two-part name by combining one of name_finnish_1 + "la"/"lä"
+ // The reason for not having the contents of name_finnish_{1,2} in the same table is
+ // that the ones in name_finnish_2 are not good for this purpose.
+ uint sel = SeedChance( 0, lengthof(name_finnish_1), seed);
+ char *end;
+ strecat(buf, name_finnish_1[sel], last);
+ end = &buf[strlen(buf)-1];
+ if (*end == 'i')
+ *end = 'e';
+ if (strstr(buf, "a") || strstr(buf, "o") || strstr(buf, "u") ||
+ strstr(buf, "A") || strstr(buf, "O") || strstr(buf, "U"))
+ {
+ strecat(buf, "la", last);
+ } else {
+ strecat(buf, "lä", last);
+ }
+ } else {
+ // A two-part name by combining one of name_finnish_{1,2} + name_finnish_3.
+ // Why aren't name_finnish_{1,2} just one table? See above.
+ uint sel = SeedChance(2,
+ lengthof(name_finnish_1) + lengthof(name_finnish_2), seed);
+ if (sel >= lengthof(name_finnish_1)) {
+ strecat(buf, name_finnish_2[sel-lengthof(name_finnish_1)], last);
+ } else {
+ strecat(buf, name_finnish_1[sel], last);
+ }
+ strecat(buf, name_finnish_3[SeedChance(10, lengthof(name_finnish_3), seed)], last);
+ }
+
+ return 0;
+}
+
+static byte MakePolishTownName(char *buf, uint32 seed, const char *last)
+{
+ uint i;
+ uint j;
+
+ //null terminates the string for strcat
+ strecpy(buf, "", last);
+
+ // optional first segment
+ i = SeedChance(0,
+ lengthof(name_polish_2_o) + lengthof(name_polish_2_m) +
+ lengthof(name_polish_2_f) + lengthof(name_polish_2_n),
+ seed);
+ j = SeedChance(2, 20, seed);
+
+
+ if (i < lengthof(name_polish_2_o)) {
+ strecat(buf, name_polish_2_o[SeedChance(3, lengthof(name_polish_2_o), seed)], last);
+ } else if (i < lengthof(name_polish_2_m) + lengthof(name_polish_2_o)) {
+ if (j < 4)
+ strecat(buf, name_polish_1_m[SeedChance(5, lengthof(name_polish_1_m), seed)], last);
+
+ strecat(buf, name_polish_2_m[SeedChance(7, lengthof(name_polish_2_m), seed)], last);
+
+ if (j >= 4 && j < 16)
+ strecat(buf, name_polish_3_m[SeedChance(10, lengthof(name_polish_3_m), seed)], last);
+ } else if (i < lengthof(name_polish_2_f) + lengthof(name_polish_2_m) + lengthof(name_polish_2_o)) {
+ if (j < 4)
+ strecat(buf, name_polish_1_f[SeedChance(5, lengthof(name_polish_1_f), seed)], last);
+
+ strecat(buf, name_polish_2_f[SeedChance(7, lengthof(name_polish_2_f), seed)], last);
+
+ if (j >= 4 && j < 16)
+ strecat(buf, name_polish_3_f[SeedChance(10, lengthof(name_polish_3_f), seed)], last);
+ } else {
+ if (j < 4)
+ strecat(buf, name_polish_1_n[SeedChance(5, lengthof(name_polish_1_n), seed)], last);
+
+ strecat(buf, name_polish_2_n[SeedChance(7, lengthof(name_polish_2_n), seed)], last);
+
+ if (j >= 4 && j < 16)
+ strecat(buf, name_polish_3_n[SeedChance(10, lengthof(name_polish_3_n), seed)], last);
+ }
+ return 0;
+}
+
+static byte MakeCzechTownName(char *buf, uint32 seed, const char *last)
+{
+ /* Probability of prefixes/suffixes */
+ /* 0..11 prefix, 12..13 prefix+suffix, 14..17 suffix, 18..31 nothing */
+ int prob_tails;
+ bool do_prefix, do_suffix, dynamic_subst;
+ /* IDs of the respective parts */
+ int prefix = 0, ending = 0, suffix = 0;
+ uint postfix = 0;
+ uint stem;
+ /* The select criteria. */
+ CzechGender gender;
+ CzechChoose choose;
+ CzechAllow allow;
+
+ // 1:3 chance to use a real name.
+ if (SeedModChance(0, 4, seed) == 0) {
+ strecpy(buf, name_czech_real[SeedModChance(4, lengthof(name_czech_real), seed)], last);
+ return 0;
+ }
+
+ // NUL terminates the string for strcat()
+ strecpy(buf, "", last);
+
+ prob_tails = SeedModChance(2, 32, seed);
+ do_prefix = prob_tails < 12;
+ do_suffix = prob_tails > 11 && prob_tails < 17;
+
+ if (do_prefix) prefix = SeedModChance(5, lengthof(name_czech_adj) * 12, seed) / 12;
+ if (do_suffix) suffix = SeedModChance(7, lengthof(name_czech_suffix), seed);
+ // 3:1 chance 3:1 to use dynamic substantive
+ stem = SeedModChance(9,
+ lengthof(name_czech_subst_full) + 3 * lengthof(name_czech_subst_stem),
+ seed);
+ if (stem < lengthof(name_czech_subst_full)) {
+ // That was easy!
+ dynamic_subst = false;
+ gender = name_czech_subst_full[stem].gender;
+ choose = name_czech_subst_full[stem].choose;
+ allow = name_czech_subst_full[stem].allow;
+ } else {
+ unsigned int map[lengthof(name_czech_subst_ending)];
+ int ending_start = -1, ending_stop = -1;
+ int i;
+
+ // Load the substantive
+ dynamic_subst = true;
+ stem -= lengthof(name_czech_subst_full);
+ stem %= lengthof(name_czech_subst_stem);
+ gender = name_czech_subst_stem[stem].gender;
+ choose = name_czech_subst_stem[stem].choose;
+ allow = name_czech_subst_stem[stem].allow;
+
+ // Load the postfix (1:1 chance that a postfix will be inserted)
+ postfix = SeedModChance(14, lengthof(name_czech_subst_postfix) * 2, seed);
+
+ if (choose & CZC_POSTFIX) {
+ // Always get a real postfix.
+ postfix %= lengthof(name_czech_subst_postfix);
+ }
+ if (choose & CZC_NOPOSTFIX) {
+ // Always drop a postfix.
+ postfix += lengthof(name_czech_subst_postfix);
+ }
+ if (postfix < lengthof(name_czech_subst_postfix)) {
+ choose |= CZC_POSTFIX;
+ } else {
+ choose |= CZC_NOPOSTFIX;
+ }
+
+ // Localize the array segment containing a good gender
+ for (ending = 0; ending < (int) lengthof(name_czech_subst_ending); ending++) {
+ const CzechNameSubst *e = &name_czech_subst_ending[ending];
+
+ if (gender == CZG_FREE ||
+ (gender == CZG_NFREE && e->gender != CZG_SNEUT && e->gender != CZG_PNEUT) ||
+ gender == e->gender) {
+ if (ending_start < 0)
+ ending_start = ending;
+
+ } else if (ending_start >= 0) {
+ ending_stop = ending - 1;
+ break;
+ }
+ }
+ if (ending_stop < 0) {
+ // Whoa. All the endings matched.
+ ending_stop = ending - 1;
+ }
+
+ // Make a sequential map of the items with good mask
+ i = 0;
+ for (ending = ending_start; ending <= ending_stop; ending++) {
+ const CzechNameSubst *e = &name_czech_subst_ending[ending];
+
+ if ((e->choose & choose) == choose && (e->allow & allow) != 0)
+ map[i++] = ending;
+ }
+ assert(i > 0);
+
+ // Load the ending
+ ending = map[SeedModChance(16, i, seed)];
+ // Override possible CZG_*FREE; this must be a real gender,
+ // otherwise we get overflow when modifying the adjectivum.
+ gender = name_czech_subst_ending[ending].gender;
+ assert(gender != CZG_FREE && gender != CZG_NFREE);
+ }
+
+ if (do_prefix && (name_czech_adj[prefix].choose & choose) != choose) {
+ // Throw away non-matching prefix.
+ do_prefix = false;
+ }
+
+ // Now finally construct the name
+
+ if (do_prefix) {
+ CzechPattern pattern = name_czech_adj[prefix].pattern;
+ size_t endpos;
+
+ strecat(buf, name_czech_adj[prefix].name, last);
+ endpos = strlen(buf) - 1;
+ /* Find the first character in a UTF-8 sequence */
+ while (GB(buf[endpos], 6, 2) == 2) endpos--;
+ if (gender == CZG_SMASC && pattern == CZP_PRIVL) {
+ /* -ovX -> -uv */
+ buf[endpos - 2] = 'u';
+ assert(buf[endpos - 1] == 'v');
+ buf[endpos] = '\0';
+ } else {
+ strecpy(buf + endpos, name_czech_patmod[gender][pattern], last);
+ }
+
+ strecat(buf, " ", last);
+ }
+
+ if (dynamic_subst) {
+ strecat(buf, name_czech_subst_stem[stem].name, last);
+ if (postfix < lengthof(name_czech_subst_postfix)) {
+ const char *poststr = name_czech_subst_postfix[postfix];
+ const char *endstr = name_czech_subst_ending[ending].name;
+ size_t postlen, endlen;
+
+ postlen = strlen(poststr);
+ endlen = strlen(endstr);
+ assert(postlen > 0 && endlen > 0);
+
+ // Kill the "avava" and "Jananna"-like cases
+ if (postlen < 2 || postlen > endlen || (
+ (poststr[1] != 'v' || poststr[1] != endstr[1]) &&
+ poststr[2] != endstr[1])
+ ) {
+ size_t buflen;
+ strecat(buf, poststr, last);
+ buflen = strlen(buf);
+
+ // k-i -> c-i, h-i -> z-i
+ if (endstr[0] == 'i') {
+ switch (buf[buflen - 1]) {
+ case 'k': buf[buflen - 1] = 'c'; break;
+ case 'h': buf[buflen - 1] = 'z'; break;
+ default: break;
+ }
+ }
+ }
+ }
+ strecat(buf, name_czech_subst_ending[ending].name, last);
+ } else {
+ strecat(buf, name_czech_subst_full[stem].name, last);
+ }
+
+ if (do_suffix) {
+ strecat(buf, " ", last);
+ strecat(buf, name_czech_suffix[suffix], last);
+ }
+
+ return 0;
+}
+
+static byte MakeRomanianTownName(char *buf, uint32 seed, const char *last)
+{
+ strecpy(buf, name_romanian_real[SeedChance(0, lengthof(name_romanian_real), seed)], last);
+ return 0;
+}
+
+static byte MakeSlovakTownName(char *buf, uint32 seed, const char *last)
+{
+ strecpy(buf, name_slovak_real[SeedChance(0, lengthof(name_slovak_real), seed)], last);
+ return 0;
+}
+
+static byte MakeNorwegianTownName(char *buf, uint32 seed, const char *last)
+{
+ strecpy(buf, "", last);
+
+ // Use first 4 bit from seed to decide whether or not this town should
+ // have a real name 3/16 chance. Bit 0-3
+ if (SeedChance(0, 15, seed) < 3) {
+ // Use 7bit for the realname table index. Bit 4-10
+ strecat(buf, name_norwegian_real[SeedChance(4, lengthof(name_norwegian_real), seed)], last);
+ } else {
+ // Use 7bit for the first fake part. Bit 4-10
+ strecat(buf, name_norwegian_1[SeedChance(4, lengthof(name_norwegian_1), seed)], last);
+ // Use 7bit for the last fake part. Bit 11-17
+ strecat(buf, name_norwegian_2[SeedChance(11, lengthof(name_norwegian_2), seed)], last);
+ }
+
+ return 0;
+}
+
+static byte MakeHungarianTownName(char *buf, uint32 seed, const char *last)
+{
+ uint i;
+
+ //null terminates the string for strcat
+ strecpy(buf, "", last);
+
+ if (SeedChance(12, 15, seed) < 3) {
+ strecat(buf, name_hungarian_real[SeedChance(0, lengthof(name_hungarian_real), seed)], last);
+ } else {
+ // optional first segment
+ i = SeedChance(3, lengthof(name_hungarian_1) * 3, seed);
+ if (i < lengthof(name_hungarian_1))
+ strecat(buf, name_hungarian_1[i], last);
+
+ // mandatory middle segments
+ strecat(buf, name_hungarian_2[SeedChance(3, lengthof(name_hungarian_2), seed)], last);
+ strecat(buf, name_hungarian_3[SeedChance(6, lengthof(name_hungarian_3), seed)], last);
+
+ // optional last segment
+ i = SeedChance(10, lengthof(name_hungarian_4) * 3, seed);
+ if (i < lengthof(name_hungarian_4)) {
+ strecat(buf, name_hungarian_4[i], last);
+ }
+ }
+
+ return 0;
+}
+
+static byte MakeSwissTownName(char *buf, uint32 seed, const char *last)
+{
+ strecpy(buf, name_swiss_real[SeedChance(0, lengthof(name_swiss_real), seed)], last);
+ return 0;
+}
+
+static byte MakeDanishTownName(char *buf, uint32 seed, const char *last)
+{
+ int i;
+
+ // null terminates the string for strcat
+ strecpy(buf, "", last);
+
+ // optional first segment
+ i = SeedChanceBias(0, lengthof(name_danish_1), seed, 50);
+ if (i >= 0)
+ strecat(buf, name_danish_1[i], last);
+
+ // middle segments removed as this algorithm seems to create much more realistic names
+ strecat(buf, name_danish_2[SeedChance( 7, lengthof(name_danish_2), seed)], last);
+ strecat(buf, name_danish_3[SeedChance(16, lengthof(name_danish_3), seed)], last);
+
+ return 0;
+}
+
+static byte MakeTurkishTownName(char *buf, uint32 seed, const char *last)
+{
+ uint i;
+
+ // null terminates the string for strcat
+ strecpy(buf, "", last);
+
+ if ((i = SeedModChance(0, 5, seed)) == 0) {
+ strecat(buf, name_turkish_prefix[SeedModChance( 2, lengthof(name_turkish_prefix), seed)], last);
+
+ // middle segment
+ strecat(buf, name_turkish_middle[SeedModChance( 4, lengthof(name_turkish_middle), seed)], last);
+
+ // optional suffix
+ if (SeedModChance(0, 7, seed) == 0) {
+ strecat(buf, name_turkish_suffix[SeedModChance( 10, lengthof(name_turkish_suffix), seed)], last);
+ }
+ } else {
+ if (i == 1 || i == 2) {
+ strecat(buf, name_turkish_prefix[SeedModChance( 2, lengthof(name_turkish_prefix), seed)], last);
+ strecat(buf, name_turkish_suffix[SeedModChance( 4, lengthof(name_turkish_suffix), seed)], last);
+ } else {
+ strecat(buf, name_turkish_real[SeedModChance( 4, lengthof(name_turkish_real), seed)], last);
+ }
+ }
+ return 0;
+}
+
+static const char *mascul_femin_italian[] = {
+ "o",
+ "a",
+};
+
+static byte MakeItalianTownName(char *buf, uint32 seed, const char *last)
+{
+ strecpy(buf, "", last);
+
+ if (SeedModChance(0, 6, seed) == 0) { // real city names
+ strecat(buf, name_italian_real[SeedModChance(4, lengthof(name_italian_real), seed)], last);
+ } else {
+ uint i;
+
+ if (SeedModChance(0, 8, seed) == 0) { // prefix
+ strecat(buf, name_italian_pref[SeedModChance(11, lengthof(name_italian_pref), seed)], last);
+ }
+
+ i = SeedChance(0, 2, seed);
+ if (i == 0) { // masculine form
+ strecat(buf, name_italian_1m[SeedModChance(4, lengthof(name_italian_1m), seed)], last);
+ } else { // feminine form
+ strecat(buf, name_italian_1f[SeedModChance(4, lengthof(name_italian_1f), seed)], last);
+ }
+
+ if (SeedModChance(3, 3, seed) == 0) {
+ strecat(buf, name_italian_2[SeedModChance(11, lengthof(name_italian_2), seed)], last);
+ strecat(buf,mascul_femin_italian[i], last);
+ } else {
+ strecat(buf, name_italian_2i[SeedModChance(16, lengthof(name_italian_2i), seed)], last);
+ }
+
+ if (SeedModChance(15, 4, seed) == 0) {
+ if (SeedModChance(5, 2, seed) == 0) { // generic suffix
+ strecat(buf, name_italian_3[SeedModChance(4, lengthof(name_italian_3), seed)], last);
+ } else { // river name suffix
+ strecat(buf, name_italian_river1[SeedModChance(4, lengthof(name_italian_river1), seed)], last);
+ strecat(buf, name_italian_river2[SeedModChance(16, lengthof(name_italian_river2), seed)], last);
+ }
+ }
+ }
+
+ return 0;
+}
+
+static byte MakeCatalanTownName(char *buf, uint32 seed, const char *last)
+{
+ strecpy(buf, "", last);
+
+ if (SeedModChance(0, 3, seed) == 0) { // real city names
+ strecat(buf, name_catalan_real[SeedModChance(4, lengthof(name_catalan_real), seed)], last);
+ } else {
+ uint i;
+
+ if (SeedModChance(0, 2, seed) == 0) { // prefix
+ strecat(buf, name_catalan_pref[SeedModChance(11, lengthof(name_catalan_pref), seed)], last);
+ }
+
+ i = SeedChance(0, 2, seed);
+ if (i == 0) { // masculine form
+ strecat(buf, name_catalan_1m[SeedModChance(4, lengthof(name_catalan_1m), seed)], last);
+ strecat(buf, name_catalan_2m[SeedModChance(11, lengthof(name_catalan_2m), seed)], last);
+ } else { // feminine form
+ strecat(buf, name_catalan_1f[SeedModChance(4, lengthof(name_catalan_1f), seed)], last);
+ strecat(buf, name_catalan_2f[SeedModChance(11, lengthof(name_catalan_2f), seed)], last);
+ }
+
+
+ if (SeedModChance(15, 5, seed) == 0) {
+ if (SeedModChance(5, 2, seed) == 0) { // generic suffix
+ strecat(buf, name_catalan_3[SeedModChance(4, lengthof(name_catalan_3), seed)], last);
+ } else { // river name suffix
+ strecat(buf, name_catalan_river1[SeedModChance(4, lengthof(name_catalan_river1), seed)], last);
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+
+TownNameGenerator * const _town_name_generators[] =
+{
+ MakeEnglishOriginalTownName,
+ MakeFrenchTownName,
+ MakeGermanTownName,
+ MakeEnglishAdditionalTownName,
+ MakeSpanishTownName,
+ MakeSillyTownName,
+ MakeSwedishTownName,
+ MakeDutchTownName,
+ MakeFinnishTownName,
+ MakePolishTownName,
+ MakeSlovakTownName,
+ MakeNorwegianTownName,
+ MakeHungarianTownName,
+ MakeAustrianTownName,
+ MakeRomanianTownName,
+ MakeCzechTownName,
+ MakeSwissTownName,
+ MakeDanishTownName,
+ MakeTurkishTownName,
+ MakeItalianTownName,
+ MakeCatalanTownName,
+};
+
+// DO WE NEED THIS ANY MORE?
+#define FIXNUM(x, y, z) (((((x) << 16) / (y)) + 1) << z)
+
+uint32 GetOldTownName(uint32 townnameparts, byte old_town_name_type)
+{
+ switch (old_town_name_type) {
+ case 0: case 3: /* English, American */
+ /* Already OK */
+ return townnameparts;
+
+ case 1: /* French */
+ /* For some reason 86 needs to be subtracted from townnameparts
+ * 0000 0000 0000 0000 0000 0000 1111 1111 */
+ return FIXNUM(townnameparts - 86, lengthof(name_french_real), 0);
+
+ case 2: /* German */
+ DEBUG(misc, 0, "German Townnames are buggy (%d)", townnameparts);
+ return townnameparts;
+
+ case 4: /* Latin-American */
+ /* 0000 0000 0000 0000 0000 0000 1111 1111 */
+ return FIXNUM(townnameparts, lengthof(name_spanish_real), 0);
+
+ case 5: /* Silly */
+ /* NUM_SILLY_1 - lower 16 bits
+ * NUM_SILLY_2 - upper 16 bits without leading 1 (first 8 bytes)
+ * 1000 0000 2222 2222 0000 0000 1111 1111 */
+ return FIXNUM(townnameparts, lengthof(name_silly_1), 0) | FIXNUM(GB(townnameparts, 16, 8), lengthof(name_silly_2), 16);
+ }
+ return 0;
+}
diff --git a/src/namegen.h b/src/namegen.h
new file mode 100644
index 000000000..664a014ec
--- /dev/null
+++ b/src/namegen.h
@@ -0,0 +1,10 @@
+/* $Id$ */
+
+#ifndef NAMEGEN_H
+#define NAMEGEN_H
+
+typedef byte TownNameGenerator(char *buf, uint32 seed, const char *last);
+
+extern TownNameGenerator * const _town_name_generators[];
+
+#endif /* NAMEGEN_H */
diff --git a/src/network/core/config.h b/src/network/core/config.h
new file mode 100644
index 000000000..0b80800f0
--- /dev/null
+++ b/src/network/core/config.h
@@ -0,0 +1,49 @@
+/* $Id$ */
+
+#ifndef NETWORK_CORE_CONFIG_H
+#define NETWORK_CORE_CONFIG_H
+
+#ifdef ENABLE_NETWORK
+
+/** DNS hostname of the masterserver */
+#define NETWORK_MASTER_SERVER_HOST "master.openttd.org"
+/** Message sent to the masterserver to 'identify' this client as OpenTTD */
+#define NETWORK_MASTER_SERVER_WELCOME_MESSAGE "OpenTTDRegister"
+
+enum {
+ NETWORK_MASTER_SERVER_PORT = 3978, ///< The default port of the master server (UDP)
+ NETWORK_DEFAULT_PORT = 3979, ///< The default port of the game server (TCP & UDP)
+
+ SEND_MTU = 1460, ///< Number of bytes we can pack in a single packet
+
+ NETWORK_GAME_INFO_VERSION = 4, ///< What version of game-info do we use?
+ NETWORK_COMPANY_INFO_VERSION = 4, ///< What version of company info is this?
+ NETWORK_MASTER_SERVER_VERSION = 1, ///< What version of master-server-protocol do we use?
+
+ NETWORK_NAME_LENGTH = 80, ///< The maximum length of the server name and map name, in bytes including '\0'
+ NETWORK_HOSTNAME_LENGTH = 80, ///< The maximum length of the host name, in bytes including '\0'
+ NETWORK_REVISION_LENGTH = 15, ///< The maximum length of the revision, in bytes including '\0'
+ NETWORK_PASSWORD_LENGTH = 20, ///< The maximum length of the password, in bytes including '\0'
+ NETWORK_PLAYERS_LENGTH = 200, ///< The maximum length for the list of players that controls a company, in bytes including '\0'
+ NETWORK_CLIENT_NAME_LENGTH = 25, ///< The maximum length of a player, in bytes including '\0'
+ NETWORK_RCONCOMMAND_LENGTH = 500, ///< The maximum length of a rconsole command, in bytes including '\0'
+
+ NETWORK_GRF_NAME_LENGTH = 80, ///< Maximum length of the name of a GRF
+ /**
+ * Maximum number of GRFs that can be sent.
+ * This value is related to number of handles (files) OpenTTD can open.
+ * This is currently 64 and about 10 are currently used when OpenTTD loads
+ * without any NewGRFs. Therefore one can only load about 55 NewGRFs, so
+ * this is not a limit, but rather a way to easily check whether the limit
+ * imposed by the handle count is reached. Secondly it isn't possible to
+ * send much more GRF IDs + MD5sums in the PACKET_UDP_SERVER_RESPONSE, due
+ * to the limited size of UDP packets.
+ */
+ NETWORK_MAX_GRF_COUNT = 55,
+
+ NETWORK_NUM_LANGUAGES = 4, ///< Number of known languages (to the network protocol) + 1 for 'any'.
+};
+
+#endif /* ENABLE_NETWORK */
+
+#endif /* NETWORK_CORE_CONFIG_H */
diff --git a/src/network/core/game.h b/src/network/core/game.h
new file mode 100644
index 000000000..71268f7d2
--- /dev/null
+++ b/src/network/core/game.h
@@ -0,0 +1,47 @@
+/* $Id$ */
+
+#ifndef NETWORK_CORE_GAME_H
+#define NETWORK_CORE_GAME_H
+
+#ifdef ENABLE_NETWORK
+
+/**
+ * @file game.h Information about a game that is sent between a
+ * game server, game client and masterserver.
+ */
+
+/**
+ * This is the struct used by both client and server
+ * some fields will be empty on the client (like game_password) by default
+ * and only filled with data a player enters.
+ */
+typedef struct NetworkGameInfo {
+ byte game_info_version; ///< Version of the game info
+ char server_name[NETWORK_NAME_LENGTH]; ///< Server name
+ char hostname[NETWORK_HOSTNAME_LENGTH]; ///< Hostname of the server (if any)
+ char server_revision[NETWORK_REVISION_LENGTH]; ///< The version number the server is using (e.g.: 'r304' or 0.5.0)
+ bool version_compatible; ///< Can we connect to this server or not? (based on server_revision)
+ bool compatible; ///< Can we connect to this server or not? (based on server_revision _and_ grf_match
+ byte server_lang; ///< Language of the server (we should make a nice table for this)
+ byte use_password; ///< Is set to != 0 if it uses a password
+ char server_password[NETWORK_PASSWORD_LENGTH]; ///< On the server: the game password, on the client: != "" if server has password
+ byte clients_max; ///< Max clients allowed on server
+ byte clients_on; ///< Current count of clients on server
+ byte companies_max; ///< Max companies allowed on server
+ byte companies_on; ///< How many started companies do we have
+ byte spectators_max; ///< Max spectators allowed on server
+ byte spectators_on; ///< How many spectators do we have?
+ Date game_date; ///< Current date
+ Date start_date; ///< When the game started
+ char map_name[NETWORK_NAME_LENGTH]; ///< Map which is played ["random" for a randomized map]
+ uint16 map_width; ///< Map width
+ uint16 map_height; ///< Map height
+ byte map_set; ///< Graphical set
+ bool dedicated; ///< Is this a dedicated server?
+ char rcon_password[NETWORK_PASSWORD_LENGTH]; ///< RCon password for the server. "" if rcon is disabled
+ struct GRFConfig *grfconfig; ///< List of NewGRF files used
+} NetworkGameInfo;
+
+#endif /* ENABLE_NETWORK */
+
+#endif /* NETWORK_CORE_GAME_H */
diff --git a/src/network/core/os_abstraction.h b/src/network/core/os_abstraction.h
new file mode 100644
index 000000000..c7df16a93
--- /dev/null
+++ b/src/network/core/os_abstraction.h
@@ -0,0 +1,181 @@
+/* $Id$ */
+
+#ifndef NETWORK_CORE_OS_ABSTRACTION_H
+#define NETWORK_CORE_OS_ABSTRACTION_H
+
+/**
+ * @file os_abstraction.h Network stuff has many things that needs to be
+ * included and/or implemented by default.
+ * All those things are in this file.
+ */
+
+/* Include standard stuff per OS */
+
+#ifdef ENABLE_NETWORK
+
+/* Windows stuff */
+#if defined(WIN32) || defined(WIN64)
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <windows.h>
+
+#if !(defined(__MINGW32__) || defined(__CYGWIN__))
+ /* Windows has some different names for some types */
+ typedef SSIZE_T ssize_t;
+ typedef int socklen_t;
+#endif
+
+#define GET_LAST_ERROR() WSAGetLastError()
+#define EWOULDBLOCK WSAEWOULDBLOCK
+/* Windows has some different names for some types */
+typedef unsigned long in_addr_t;
+#endif /* WIN32 */
+
+/* UNIX stuff */
+#if defined(UNIX)
+# define SOCKET int
+# define INVALID_SOCKET -1
+# if !defined(__MORPHOS__) && !defined(__AMIGA__)
+# define ioctlsocket ioctl
+# if !defined(BEOS_NET_SERVER)
+# define closesocket close
+# endif
+# define GET_LAST_ERROR() (errno)
+# endif
+/* Need this for FIONREAD on solaris */
+# define BSD_COMP
+
+/* Includes needed for UNIX-like systems */
+# include <unistd.h>
+# include <sys/ioctl.h>
+# if defined(__BEOS__) && defined(BEOS_NET_SERVER)
+# include <be/net/socket.h>
+# include <be/kernel/OS.h> // snooze()
+# include <be/net/netdb.h>
+ typedef unsigned long in_addr_t;
+# define INADDR_NONE INADDR_BROADCAST
+# else
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <netinet/tcp.h>
+# include <arpa/inet.h>
+# include <net/if.h>
+/* According to glibc/NEWS, <ifaddrs.h> appeared in glibc-2.3. */
+# if !defined(__sgi__) && !defined(SUNOS) && !defined(__MORPHOS__) && !defined(__BEOS__) && !defined(__INNOTEK_LIBC__) \
+ && !(defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 2)) && !defined(__dietlibc__)
+/* If for any reason ifaddrs.h does not exist on your system, comment out
+ * the following two lines and an alternative way will be used to fetch
+ * the list of IPs from the system. */
+# include <ifaddrs.h>
+# define HAVE_GETIFADDRS
+# endif
+# if defined(SUNOS) || defined(__MORPHOS__) || defined(__BEOS__)
+# define INADDR_NONE 0xffffffff
+# endif
+# if defined(__BEOS__) && !defined(BEOS_NET_SERVER)
+ /* needed on Zeta */
+# include <sys/sockio.h>
+# endif
+# endif /* BEOS_NET_SERVER */
+
+# if !defined(__BEOS__) && defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 1)
+ typedef uint32_t in_addr_t;
+# endif
+
+# include <errno.h>
+# include <sys/time.h>
+# include <netdb.h>
+#endif // UNIX
+
+#ifdef __BEOS__
+ typedef int socklen_t;
+#endif
+
+/* OS/2 stuff */
+#if defined(__OS2__)
+# define SOCKET int
+# define INVALID_SOCKET -1
+# define ioctlsocket ioctl
+# define closesocket close
+# define GET_LAST_ERROR() (sock_errno())
+
+/* Includes needed for OS/2 systems */
+# include <types.h>
+# include <unistd.h>
+# include <sys/ioctl.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <netinet/tcp.h>
+# include <arpa/inet.h>
+# include <net/if.h>
+# include <errno.h>
+# include <sys/time.h>
+# include <netdb.h>
+# include <nerrno.h>
+# define INADDR_NONE 0xffffffff
+
+typedef int socklen_t;
+#if !defined(__INNOTEK_LIBC__)
+typedef unsigned long in_addr_t;
+#endif /* __INNOTEK_LIBC__ */
+#endif /* OS/2 */
+
+/* MorphOS and Amiga stuff */
+#if defined(__MORPHOS__) || defined(__AMIGA__)
+# include <exec/types.h>
+# include <proto/exec.h> // required for Open/CloseLibrary()
+# if defined(__MORPHOS__)
+# include <sys/filio.h> // FIO* defines
+# include <sys/sockio.h> // SIO* defines
+# include <netinet/in.h>
+# else /* __AMIGA__ */
+# include <proto/socket.h>
+# endif
+
+/* Make the names compatible */
+# define closesocket(s) CloseSocket(s)
+# define GET_LAST_ERROR() Errno()
+# define ioctlsocket(s,request,status) IoctlSocket((LONG)s,(ULONG)request,(char*)status)
+# define ioctl ioctlsocket
+
+ typedef unsigned int in_addr_t;
+ typedef long socklen_t;
+ extern struct Library *SocketBase;
+
+# ifdef __AMIGA__
+ /* for usleep() implementation */
+ extern struct Device *TimerBase;
+ extern struct MsgPort *TimerPort;
+ extern struct timerequest *TimerRequest;
+# endif
+#endif // __MORPHOS__ || __AMIGA__
+
+static inline bool SetNonBlocking(int d)
+{
+#ifdef WIN32
+ u_long nonblocking = 1;
+#else
+ int nonblocking = 1;
+#endif
+#if defined(__BEOS__) && defined(BEOS_NET_SERVER)
+ return setsockopt(d, SOL_SOCKET, SO_NONBLOCK, &nonblocking, sizeof(nonblocking)) == 0;
+#else
+ return ioctlsocket(d, FIONBIO, &nonblocking) == 0;
+#endif
+}
+
+static inline bool SetNoDelay(int d)
+{
+ /* XXX should this be done at all? */
+#if !defined(BEOS_NET_SERVER) // not implemented on BeOS net_server
+ int b = 1;
+ /* The (const char*) cast is needed for windows */
+ return setsockopt(d, IPPROTO_TCP, TCP_NODELAY, (const char*)&b, sizeof(b)) == 0;
+#else
+ return true;
+#endif
+}
+
+#endif /* ENABLE_NETWORK */
+
+#endif /* NETWORK_CORE_OS_ABSTRACTION_H */
diff --git a/src/network/core/packet.c b/src/network/core/packet.c
new file mode 100644
index 000000000..957bd2ad6
--- /dev/null
+++ b/src/network/core/packet.c
@@ -0,0 +1,216 @@
+/* $Id$ */
+
+#ifdef ENABLE_NETWORK
+
+#include "../../stdafx.h"
+#include "../../macros.h"
+#include "../../string.h"
+
+#include "os_abstraction.h"
+#include "config.h"
+#include "packet.h"
+
+/**
+ * @file packet.h Basic functions to create, fill and read packets.
+ */
+
+
+/* Do not want to include functions.h and all required headers */
+extern void NORETURN CDECL error(const char *str, ...);
+
+
+/**
+ * Create a packet for sending
+ * @param type the of packet
+ * @return the newly created packet
+ */
+Packet *NetworkSend_Init(PacketType type)
+{
+ Packet *packet = malloc(sizeof(Packet));
+ /* An error is inplace here, because it simply means we ran out of memory. */
+ if (packet == NULL) error("Failed to allocate Packet");
+
+ /* Skip the size so we can write that in before sending the packet */
+ packet->size = sizeof(packet->size);
+ packet->buffer[packet->size++] = type;
+ packet->pos = 0;
+
+ return packet;
+}
+
+/**
+ * Writes the packet size from the raw packet from packet->size
+ * @param packet the packet to write the size of
+ */
+void NetworkSend_FillPacketSize(Packet *packet)
+{
+ packet->buffer[0] = GB(packet->size, 0, 8);
+ packet->buffer[1] = GB(packet->size, 8, 8);
+}
+
+/**
+ * The next couple of functions make sure we can send
+ * uint8, uint16, uint32 and uint64 endian-safe
+ * over the network. The least significant bytes are
+ * sent first.
+ *
+ * So 0x01234567 would be sent as 67 45 23 01.
+ */
+
+void NetworkSend_uint8(Packet *packet, uint8 data)
+{
+ assert(packet->size < sizeof(packet->buffer) - sizeof(data));
+ packet->buffer[packet->size++] = data;
+}
+
+void NetworkSend_uint16(Packet *packet, uint16 data)
+{
+ assert(packet->size < sizeof(packet->buffer) - sizeof(data));
+ packet->buffer[packet->size++] = GB(data, 0, 8);
+ packet->buffer[packet->size++] = GB(data, 8, 8);
+}
+
+void NetworkSend_uint32(Packet *packet, uint32 data)
+{
+ assert(packet->size < sizeof(packet->buffer) - sizeof(data));
+ packet->buffer[packet->size++] = GB(data, 0, 8);
+ packet->buffer[packet->size++] = GB(data, 8, 8);
+ packet->buffer[packet->size++] = GB(data, 16, 8);
+ packet->buffer[packet->size++] = GB(data, 24, 8);
+}
+
+void NetworkSend_uint64(Packet *packet, uint64 data)
+{
+ assert(packet->size < sizeof(packet->buffer) - sizeof(data));
+ packet->buffer[packet->size++] = GB(data, 0, 8);
+ packet->buffer[packet->size++] = GB(data, 8, 8);
+ packet->buffer[packet->size++] = GB(data, 16, 8);
+ packet->buffer[packet->size++] = GB(data, 24, 8);
+ packet->buffer[packet->size++] = GB(data, 32, 8);
+ packet->buffer[packet->size++] = GB(data, 40, 8);
+ packet->buffer[packet->size++] = GB(data, 48, 8);
+ packet->buffer[packet->size++] = GB(data, 56, 8);
+}
+
+/**
+ * Sends a string over the network. It sends out
+ * the string + '\0'. No size-byte or something.
+ */
+void NetworkSend_string(Packet *packet, const char* data)
+{
+ assert(data != NULL);
+ assert(packet->size < sizeof(packet->buffer) - strlen(data) - 1);
+ while ((packet->buffer[packet->size++] = *data++) != '\0') {}
+}
+
+
+/**
+ * Receiving commands
+ * Again, the next couple of functions are endian-safe
+ * see the comment before NetworkSend_uint8 for more info.
+ */
+
+
+extern uint CloseConnection(NetworkClientState *cs);
+
+/** Is it safe to read from the packet, i.e. didn't we run over the buffer ? */
+static inline bool CanReadFromPacket(NetworkClientState *cs, Packet *packet, uint bytes_to_read)
+{
+ /* Don't allow reading from a closed socket */
+ if (HasClientQuit(cs)) return false;
+
+ /* Check if variable is within packet-size */
+ if (packet->pos + bytes_to_read > packet->size) {
+ CloseConnection(cs);
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Reads the packet size from the raw packet and stores it in the packet->size
+ * @param packet the packet to read the size of
+ */
+void NetworkRecv_ReadPacketSize(Packet *packet)
+{
+ packet->size = (uint16)packet->buffer[0];
+ packet->size += (uint16)packet->buffer[1] << 8;
+}
+
+uint8 NetworkRecv_uint8(NetworkClientState *cs, Packet *packet)
+{
+ uint8 n;
+
+ if (!CanReadFromPacket(cs, packet, sizeof(n))) return 0;
+
+ n = packet->buffer[packet->pos++];
+ return n;
+}
+
+uint16 NetworkRecv_uint16(NetworkClientState *cs, Packet *packet)
+{
+ uint16 n;
+
+ if (!CanReadFromPacket(cs, packet, sizeof(n))) return 0;
+
+ n = (uint16)packet->buffer[packet->pos++];
+ n += (uint16)packet->buffer[packet->pos++] << 8;
+ return n;
+}
+
+uint32 NetworkRecv_uint32(NetworkClientState *cs, Packet *packet)
+{
+ uint32 n;
+
+ if (!CanReadFromPacket(cs, packet, sizeof(n))) return 0;
+
+ n = (uint32)packet->buffer[packet->pos++];
+ n += (uint32)packet->buffer[packet->pos++] << 8;
+ n += (uint32)packet->buffer[packet->pos++] << 16;
+ n += (uint32)packet->buffer[packet->pos++] << 24;
+ return n;
+}
+
+uint64 NetworkRecv_uint64(NetworkClientState *cs, Packet *packet)
+{
+ uint64 n;
+
+ if (!CanReadFromPacket(cs, packet, sizeof(n))) return 0;
+
+ n = (uint64)packet->buffer[packet->pos++];
+ n += (uint64)packet->buffer[packet->pos++] << 8;
+ n += (uint64)packet->buffer[packet->pos++] << 16;
+ n += (uint64)packet->buffer[packet->pos++] << 24;
+ n += (uint64)packet->buffer[packet->pos++] << 32;
+ n += (uint64)packet->buffer[packet->pos++] << 40;
+ n += (uint64)packet->buffer[packet->pos++] << 48;
+ n += (uint64)packet->buffer[packet->pos++] << 56;
+ return n;
+}
+
+/** Reads a string till it finds a '\0' in the stream */
+void NetworkRecv_string(NetworkClientState *cs, Packet *p, char *buffer, size_t size)
+{
+ PacketSize pos;
+ char *bufp = buffer;
+
+ /* Don't allow reading from a closed socket */
+ if (HasClientQuit(cs)) return;
+
+ pos = p->pos;
+ while (--size > 0 && pos < p->size && (*buffer++ = p->buffer[pos++]) != '\0') {}
+
+ if (size == 0 || pos == p->size) {
+ *buffer = '\0';
+ /* If size was sooner to zero then the string in the stream
+ * skip till the \0, so than packet can be read out correctly for the rest */
+ while (pos < p->size && p->buffer[pos] != '\0') pos++;
+ pos++;
+ }
+ p->pos = pos;
+
+ str_validate(bufp);
+}
+
+#endif /* ENABLE_NETWORK */
diff --git a/src/network/core/packet.h b/src/network/core/packet.h
new file mode 100644
index 000000000..2510c69a7
--- /dev/null
+++ b/src/network/core/packet.h
@@ -0,0 +1,67 @@
+/* $Id$ */
+
+#ifndef NETWORK_CORE_PACKET_H
+#define NETWORK_CORE_PACKET_H
+
+#ifdef ENABLE_NETWORK
+
+/**
+ * @file packet.h Basic functions to create, fill and read packets.
+ */
+
+typedef struct NetworkClientState NetworkClientState;
+
+/**
+ * Queries the network client state struct to determine whether
+ * the client has quit. It indirectly also queries whether the
+ * packet is corrupt as the connection will be closed if it is
+ * reading beyond the boundary of the received packet.
+ * @param cs the state to query
+ * @param true if the connection should be considered dropped
+ */
+bool HasClientQuit(NetworkClientState *cs);
+
+typedef uint16 PacketSize; ///< Size of the whole packet.
+typedef uint8 PacketType; ///< Identifier for the packet
+
+/**
+ * Internal entity of a packet. As everything is sent as a packet,
+ * all network communication will need to call the functions that
+ * populate the packet.
+ * Every packet can be at most SEND_MTU bytes. Overflowing this
+ * limit will give an assertion when sending (i.e. writing) the
+ * packet. Reading past the size of the packet when receiving
+ * will return all 0 values and "" in case of the string.
+ */
+typedef struct Packet {
+ /** The next packet. Used for queueing packets before sending. */
+ struct Packet *next;
+ /** The size of the whole packet for received packets. For packets
+ * that will be sent, the value is filled in just before the
+ * actual transmission. */
+ PacketSize size;
+ /** The current read/write position in the packet */
+ PacketSize pos;
+ /** The buffer of this packet */
+ byte buffer[SEND_MTU];
+} Packet;
+
+
+Packet *NetworkSend_Init(PacketType type);
+void NetworkSend_FillPacketSize(Packet *packet);
+void NetworkSend_uint8 (Packet *packet, uint8 data);
+void NetworkSend_uint16(Packet *packet, uint16 data);
+void NetworkSend_uint32(Packet *packet, uint32 data);
+void NetworkSend_uint64(Packet *packet, uint64 data);
+void NetworkSend_string(Packet *packet, const char* data);
+
+void NetworkRecv_ReadPacketSize(Packet *packet);
+uint8 NetworkRecv_uint8 (NetworkClientState *cs, Packet *packet);
+uint16 NetworkRecv_uint16(NetworkClientState *cs, Packet *packet);
+uint32 NetworkRecv_uint32(NetworkClientState *cs, Packet *packet);
+uint64 NetworkRecv_uint64(NetworkClientState *cs, Packet *packet);
+void NetworkRecv_string(NetworkClientState *cs, Packet *packet, char* buffer, size_t size);
+
+#endif /* ENABLE_NETWORK */
+
+#endif /* NETWORK_CORE_PACKET_H */
diff --git a/src/network/core/tcp.c b/src/network/core/tcp.c
new file mode 100644
index 000000000..ec073c7ce
--- /dev/null
+++ b/src/network/core/tcp.c
@@ -0,0 +1,227 @@
+/* $Id$ */
+
+#ifdef ENABLE_NETWORK
+
+#include "../../stdafx.h"
+#include "../../debug.h"
+#include "../../openttd.h"
+#include "../../variables.h"
+#include "table/strings.h"
+#include "../../functions.h"
+
+#include "os_abstraction.h"
+#include "config.h"
+#include "packet.h"
+#include "../network_data.h"
+#include "tcp.h"
+
+/**
+ * @file tcp.c Basic functions to receive and send TCP packets.
+ */
+
+/**
+ * Functions to help NetworkRecv_Packet/NetworkSend_Packet a bit
+ * A socket can make errors. When that happens this handles what to do.
+ * For clients: close connection and drop back to main-menu
+ * For servers: close connection and that is it
+ * @param cs the client to close the connection of
+ * @return the new status
+ */
+NetworkRecvStatus CloseConnection(NetworkClientState *cs)
+{
+ NetworkCloseClient(cs);
+
+ /* Clients drop back to the main menu */
+ if (!_network_server && _networking) {
+ _switch_mode = SM_MENU;
+ _networking = false;
+ _switch_mode_errorstr = STR_NETWORK_ERR_LOSTCONNECTION;
+
+ return NETWORK_RECV_STATUS_CONN_LOST;
+ }
+
+ return NETWORK_RECV_STATUS_OKAY;
+}
+
+/**
+ * Whether the client has quit or not (used in packet.c)
+ * @param cs the client to check
+ * @return true if the client has quit
+ */
+bool HasClientQuit(NetworkClientState *cs)
+{
+ return cs->has_quit;
+}
+
+/**
+ * This function puts the packet in the send-queue and it is send as
+ * soon as possible. This is the next tick, or maybe one tick later
+ * if the OS-network-buffer is full)
+ * @param packet the packet to send
+ * @param cs the client to send to
+ */
+void NetworkSend_Packet(Packet *packet, NetworkClientState *cs)
+{
+ Packet *p;
+ assert(packet != NULL);
+
+ packet->pos = 0;
+ packet->next = NULL;
+
+ NetworkSend_FillPacketSize(packet);
+
+ /* Locate last packet buffered for the client */
+ p = cs->packet_queue;
+ if (p == NULL) {
+ /* No packets yet */
+ cs->packet_queue = packet;
+ } else {
+ /* Skip to the last packet */
+ while (p->next != NULL) p = p->next;
+ p->next = packet;
+ }
+}
+
+/**
+ * Sends all the buffered packets out for this client. It stops when:
+ * 1) all packets are send (queue is empty)
+ * 2) the OS reports back that it can not send any more
+ * data right now (full network-buffer, it happens ;))
+ * 3) sending took too long
+ * @param cs the client to send the packets for
+ */
+bool NetworkSend_Packets(NetworkClientState *cs)
+{
+ ssize_t res;
+ Packet *p;
+
+ /* We can not write to this socket!! */
+ if (!cs->writable) return false;
+ if (cs->socket == INVALID_SOCKET) return false;
+
+ p = cs->packet_queue;
+ while (p != NULL) {
+ res = send(cs->socket, p->buffer + p->pos, p->size - p->pos, 0);
+ if (res == -1) {
+ int err = GET_LAST_ERROR();
+ if (err != EWOULDBLOCK) {
+ /* Something went wrong.. close client! */
+ DEBUG(net, 0, "send failed with error %d", err);
+ CloseConnection(cs);
+ return false;
+ }
+ return true;
+ }
+ if (res == 0) {
+ /* Client/server has left us :( */
+ CloseConnection(cs);
+ return false;
+ }
+
+ p->pos += res;
+
+ /* Is this packet sent? */
+ if (p->pos == p->size) {
+ /* Go to the next packet */
+ cs->packet_queue = p->next;
+ free(p);
+ p = cs->packet_queue;
+ } else {
+ return true;
+ }
+ }
+
+ return true;
+}
+
+/**
+ * Receives a packet for the given client
+ * @param cs the client to (try to) receive a packet for
+ * @param status the variable to store the status into
+ * @return the received packet (or NULL when it didn't receive one)
+ */
+Packet *NetworkRecv_Packet(NetworkClientState *cs, NetworkRecvStatus *status)
+{
+ ssize_t res;
+ Packet *p;
+
+ *status = NETWORK_RECV_STATUS_OKAY;
+
+ if (cs->socket == INVALID_SOCKET) return NULL;
+
+ if (cs->packet_recv == NULL) {
+ cs->packet_recv = malloc(sizeof(Packet));
+ if (cs->packet_recv == NULL) error("Failed to allocate packet");
+ /* Set pos to zero! */
+ cs->packet_recv->pos = 0;
+ cs->packet_recv->size = 0; // Can be ommited, just for safety reasons
+ }
+
+ p = cs->packet_recv;
+
+ /* Read packet size */
+ if (p->pos < sizeof(PacketSize)) {
+ while (p->pos < sizeof(PacketSize)) {
+ /* Read the size of the packet */
+ res = recv(cs->socket, p->buffer + p->pos, sizeof(PacketSize) - p->pos, 0);
+ if (res == -1) {
+ int err = GET_LAST_ERROR();
+ if (err != EWOULDBLOCK) {
+ /* Something went wrong... (104 is connection reset by peer) */
+ if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
+ *status = CloseConnection(cs);
+ return NULL;
+ }
+ /* Connection would block, so stop for now */
+ return NULL;
+ }
+ if (res == 0) {
+ /* Client/server has left */
+ *status = CloseConnection(cs);
+ return NULL;
+ }
+ p->pos += res;
+ }
+
+ NetworkRecv_ReadPacketSize(p);
+
+ if (p->size > SEND_MTU) {
+ *status = CloseConnection(cs);
+ return NULL;
+ }
+ }
+
+ /* Read rest of packet */
+ while (p->pos < p->size) {
+ res = recv(cs->socket, p->buffer + p->pos, p->size - p->pos, 0);
+ if (res == -1) {
+ int err = GET_LAST_ERROR();
+ if (err != EWOULDBLOCK) {
+ /* Something went wrong... (104 is connection reset by peer) */
+ if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
+ *status = CloseConnection(cs);
+ return NULL;
+ }
+ /* Connection would block */
+ return NULL;
+ }
+ if (res == 0) {
+ /* Client/server has left */
+ *status = CloseConnection(cs);
+ return NULL;
+ }
+
+ p->pos += res;
+ }
+
+ /* We have a complete packet, return it! */
+ p->pos = 2;
+ p->next = NULL; // Should not be needed, but who knows...
+
+ /* Prepare for receiving a new packet */
+ cs->packet_recv = NULL;
+
+ return p;
+}
+
+#endif /* ENABLE_NETWORK */
diff --git a/src/network/core/tcp.h b/src/network/core/tcp.h
new file mode 100644
index 000000000..e3c307353
--- /dev/null
+++ b/src/network/core/tcp.h
@@ -0,0 +1,60 @@
+/* $Id$ */
+
+#ifndef NETWORK_CORE_TCP_H
+#define NETWORK_CORE_TCP_H
+
+#ifdef ENABLE_NETWORK
+
+/**
+ * @file tcp.h Basic functions to receive and send TCP packets.
+ */
+
+/**
+ * Enum with all types of UDP packets.
+ * The order of the first 4 packets MUST not be changed, as
+ * it protects old clients from joining newer servers
+ * (because SERVER_ERROR is the respond to a wrong revision)
+ */
+enum {
+ PACKET_SERVER_FULL,
+ PACKET_SERVER_BANNED,
+ PACKET_CLIENT_JOIN,
+ PACKET_SERVER_ERROR,
+ PACKET_CLIENT_COMPANY_INFO,
+ PACKET_SERVER_COMPANY_INFO,
+ PACKET_SERVER_CLIENT_INFO,
+ PACKET_SERVER_NEED_PASSWORD,
+ PACKET_CLIENT_PASSWORD,
+ PACKET_SERVER_WELCOME,
+ PACKET_CLIENT_GETMAP,
+ PACKET_SERVER_WAIT,
+ PACKET_SERVER_MAP,
+ PACKET_CLIENT_MAP_OK,
+ PACKET_SERVER_JOIN,
+ PACKET_SERVER_FRAME,
+ PACKET_SERVER_SYNC,
+ PACKET_CLIENT_ACK,
+ PACKET_CLIENT_COMMAND,
+ PACKET_SERVER_COMMAND,
+ PACKET_CLIENT_CHAT,
+ PACKET_SERVER_CHAT,
+ PACKET_CLIENT_SET_PASSWORD,
+ PACKET_CLIENT_SET_NAME,
+ PACKET_CLIENT_QUIT,
+ PACKET_CLIENT_ERROR,
+ PACKET_SERVER_QUIT,
+ PACKET_SERVER_ERROR_QUIT,
+ PACKET_SERVER_SHUTDOWN,
+ PACKET_SERVER_NEWGAME,
+ PACKET_SERVER_RCON,
+ PACKET_CLIENT_RCON,
+ PACKET_END ///< Must ALWAYS be on the end of this list!! (period)
+};
+
+void NetworkSend_Packet(Packet *packet, NetworkClientState *cs);
+Packet *NetworkRecv_Packet(NetworkClientState *cs, NetworkRecvStatus *status);
+bool NetworkSend_Packets(NetworkClientState *cs);
+
+#endif /* ENABLE_NETWORK */
+
+#endif /* NETWORK_CORE_TCP_H */
diff --git a/src/network/core/udp.c b/src/network/core/udp.c
new file mode 100644
index 000000000..badd9a532
--- /dev/null
+++ b/src/network/core/udp.c
@@ -0,0 +1,277 @@
+/* $Id$ */
+
+#ifdef ENABLE_NETWORK
+
+#include "../../stdafx.h"
+#include "../../date.h"
+#include "../../debug.h"
+#include "../../macros.h"
+#include "../../newgrf_config.h"
+
+#include "os_abstraction.h"
+#include "config.h"
+#include "game.h"
+#include "packet.h"
+#include "udp.h"
+
+/**
+ * @file udp.c Basic functions to receive and send UDP packets.
+ */
+
+/**
+ * Send a packet over UDP
+ * @param udp the socket to send over
+ * @param p the packet to send
+ * @param recv the receiver (target) of the packet
+ */
+void NetworkSendUDP_Packet(SOCKET udp, Packet *p, struct sockaddr_in *recv)
+{
+ int res;
+
+ NetworkSend_FillPacketSize(p);
+
+ /* Send the buffer */
+ res = sendto(udp, p->buffer, p->size, 0, (struct sockaddr *)recv, sizeof(*recv));
+
+ /* Check for any errors, but ignore it otherwise */
+ if (res == -1) DEBUG(net, 1, "[udp] sendto failed with: %i", GET_LAST_ERROR());
+}
+
+/**
+ * Start listening on the given host and port.
+ * @param udp the place where the (references to the) UDP are stored
+ * @param host the host (ip) to listen on
+ * @param port the port to listen on
+ * @param broadcast whether to allow broadcast sending/receiving
+ * @return true if the listening succeeded
+ */
+bool NetworkUDPListen(SOCKET *udp, uint32 host, uint16 port, bool broadcast)
+{
+ struct sockaddr_in sin;
+
+ /* Make sure socket is closed */
+ closesocket(*udp);
+
+ *udp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (*udp == INVALID_SOCKET) {
+ DEBUG(net, 0, "[udp] failed to start UDP listener");
+ return false;
+ }
+
+ /* set nonblocking mode for socket */
+ {
+ unsigned long blocking = 1;
+#ifndef BEOS_NET_SERVER
+ ioctlsocket(*udp, FIONBIO, &blocking);
+#else
+ setsockopt(*udp, SOL_SOCKET, SO_NONBLOCK, &blocking, NULL);
+#endif
+ }
+
+ sin.sin_family = AF_INET;
+ /* Listen on all IPs */
+ sin.sin_addr.s_addr = host;
+ sin.sin_port = htons(port);
+
+ if (bind(*udp, (struct sockaddr*)&sin, sizeof(sin)) != 0) {
+ DEBUG(net, 0, "[udp] bind failed on %s:%i", inet_ntoa(*(struct in_addr *)&host), port);
+ return false;
+ }
+
+ if (broadcast) {
+ /* Enable broadcast */
+ unsigned long val = 1;
+#ifndef BEOS_NET_SERVER // will work around this, some day; maybe.
+ setsockopt(*udp, SOL_SOCKET, SO_BROADCAST, (char *) &val , sizeof(val));
+#endif
+ }
+
+ DEBUG(net, 1, "[udp] listening on port %s:%d", inet_ntoa(*(struct in_addr *)&host), port);
+
+ return true;
+}
+
+/**
+ * Receive a packet at UDP level
+ * @param udp the socket to receive the packet on
+ */
+void NetworkUDPReceive(SOCKET udp)
+{
+ struct sockaddr_in client_addr;
+ socklen_t client_len;
+ int nbytes;
+ Packet p;
+ int packet_len;
+
+ packet_len = sizeof(p.buffer);
+ client_len = sizeof(client_addr);
+
+ /* Try to receive anything */
+ nbytes = recvfrom(udp, p.buffer, packet_len, 0, (struct sockaddr *)&client_addr, &client_len);
+
+ /* We got some bytes for the base header of the packet.
+ * Assume we received the whole packet. */
+ if (nbytes > 2) {
+ NetworkRecv_ReadPacketSize(&p);
+
+ /* Put the position on the right place */
+ p.pos = 2;
+ p.next = NULL;
+
+ /* Handle the packet */
+ NetworkHandleUDPPacket(&p, &client_addr);
+ }
+}
+
+
+/**
+ * Serializes the GRFIdentifier (GRF ID and MD5 checksum) to the packet
+ * @param p the packet to write the data to
+ * @param c the configuration to write the GRF ID and MD5 checksum from
+ */
+void NetworkSend_GRFIdentifier(Packet *p, const GRFConfig *c)
+{
+ uint j;
+ NetworkSend_uint32(p, c->grfid);
+ for (j = 0; j < sizeof(c->md5sum); j++) {
+ NetworkSend_uint8 (p, c->md5sum[j]);
+ }
+}
+
+/**
+ * Deserializes the GRFIdentifier (GRF ID and MD5 checksum) from the packet
+ * @param cs the client state (for closing connect on out-of-bounds reading etc)
+ * @param p the packet to read the data from
+ * @param c the configuration to write the GRF ID and MD5 checksum to
+ */
+void NetworkRecv_GRFIdentifier(NetworkClientState *cs, Packet *p, GRFConfig *c)
+{
+ uint j;
+ c->grfid = NetworkRecv_uint32(cs, p);
+ for (j = 0; j < sizeof(c->md5sum); j++) {
+ c->md5sum[j] = NetworkRecv_uint8(cs, p);
+ }
+}
+
+
+/**
+ * Serializes the NetworkGameInfo struct to the packet
+ * @param p the packet to write the data to
+ * @param info the NetworkGameInfo struct to serialize
+ */
+void NetworkSend_NetworkGameInfo(Packet *p, const NetworkGameInfo *info)
+{
+ NetworkSend_uint8 (p, NETWORK_GAME_INFO_VERSION);
+
+ /*
+ * Please observe the order.
+ * The parts must be read in the same order as they are sent!
+ */
+
+
+ /* NETWORK_GAME_INFO_VERSION = 4 */
+ {
+ /* Only send the GRF Identification (GRF_ID and MD5 checksum) of
+ * the GRFs that are needed, i.e. the ones that the server has
+ * selected in the NewGRF GUI and not the ones that are used due
+ * to the fact that they are in [newgrf-static] in openttd.cfg */
+ const GRFConfig *c;
+ uint count = 0;
+
+ /* Count number of GRFs to send information about */
+ for (c = info->grfconfig; c != NULL; c = c->next) {
+ if (!HASBIT(c->flags, GCF_STATIC)) count++;
+ }
+ NetworkSend_uint8 (p, count); // Send number of GRFs
+
+ /* Send actual GRF Identifications */
+ for (c = info->grfconfig; c != NULL; c = c->next) {
+ if (!HASBIT(c->flags, GCF_STATIC)) NetworkSend_GRFIdentifier(p, c);
+ }
+ }
+
+ /* NETWORK_GAME_INFO_VERSION = 3 */
+ NetworkSend_uint32(p, info->game_date);
+ NetworkSend_uint32(p, info->start_date);
+
+ /* NETWORK_GAME_INFO_VERSION = 2 */
+ NetworkSend_uint8 (p, info->companies_max);
+ NetworkSend_uint8 (p, info->companies_on);
+ NetworkSend_uint8 (p, info->spectators_max);
+
+ /* NETWORK_GAME_INFO_VERSION = 1 */
+ NetworkSend_string(p, info->server_name);
+ NetworkSend_string(p, info->server_revision);
+ NetworkSend_uint8 (p, info->server_lang);
+ NetworkSend_uint8 (p, info->use_password);
+ NetworkSend_uint8 (p, info->clients_max);
+ NetworkSend_uint8 (p, info->clients_on);
+ NetworkSend_uint8 (p, info->spectators_on);
+ NetworkSend_string(p, info->map_name);
+ NetworkSend_uint16(p, info->map_width);
+ NetworkSend_uint16(p, info->map_height);
+ NetworkSend_uint8 (p, info->map_set);
+ NetworkSend_uint8 (p, info->dedicated);
+}
+
+/**
+ * Deserializes the NetworkGameInfo struct from the packet
+ * @param cs the client state (for closing connect on out-of-bounds reading etc)
+ * @param p the packet to read the data from
+ * @param info the NetworkGameInfo to deserialize into
+ */
+void NetworkRecv_NetworkGameInfo(NetworkClientState *cs, Packet *p, NetworkGameInfo *info)
+{
+ info->game_info_version = NetworkRecv_uint8(cs, p);
+
+ /*
+ * Please observe the order.
+ * The parts must be read in the same order as they are sent!
+ */
+
+ switch (info->game_info_version) {
+ case 4: {
+ GRFConfig *c, **dst = &info->grfconfig;
+ uint i;
+ uint num_grfs = NetworkRecv_uint8(cs, p);
+
+ for (i = 0; i < num_grfs; i++) {
+ c = calloc(1, sizeof(*c));
+ NetworkRecv_GRFIdentifier(cs, p, c);
+ HandleIncomingNetworkGameInfoGRFConfig(c);
+
+ /* Append GRFConfig to the list */
+ *dst = c;
+ dst = &c->next;
+ }
+ } /* Fallthrough */
+ case 3:
+ info->game_date = NetworkRecv_uint32(cs, p);
+ info->start_date = NetworkRecv_uint32(cs, p);
+ /* Fallthrough */
+ case 2:
+ info->companies_max = NetworkRecv_uint8 (cs, p);
+ info->companies_on = NetworkRecv_uint8 (cs, p);
+ info->spectators_max = NetworkRecv_uint8 (cs, p);
+ /* Fallthrough */
+ case 1:
+ NetworkRecv_string(cs, p, info->server_name, sizeof(info->server_name));
+ NetworkRecv_string(cs, p, info->server_revision, sizeof(info->server_revision));
+ info->server_lang = NetworkRecv_uint8 (cs, p);
+ info->use_password = NetworkRecv_uint8 (cs, p);
+ info->clients_max = NetworkRecv_uint8 (cs, p);
+ info->clients_on = NetworkRecv_uint8 (cs, p);
+ info->spectators_on = NetworkRecv_uint8 (cs, p);
+ if (info->game_info_version < 3) { // 16 bits dates got scrapped and are read earlier
+ info->game_date = NetworkRecv_uint16(cs, p) + DAYS_TILL_ORIGINAL_BASE_YEAR;
+ info->start_date = NetworkRecv_uint16(cs, p) + DAYS_TILL_ORIGINAL_BASE_YEAR;
+ }
+ NetworkRecv_string(cs, p, info->map_name, sizeof(info->map_name));
+ info->map_width = NetworkRecv_uint16(cs, p);
+ info->map_height = NetworkRecv_uint16(cs, p);
+ info->map_set = NetworkRecv_uint8 (cs, p);
+ info->dedicated = NetworkRecv_uint8 (cs, p);
+ }
+}
+
+#endif /* ENABLE_NETWORK */
diff --git a/src/network/core/udp.h b/src/network/core/udp.h
new file mode 100644
index 000000000..3221e664f
--- /dev/null
+++ b/src/network/core/udp.h
@@ -0,0 +1,62 @@
+/* $Id$ */
+
+#ifndef NETWORK_CORE_UDP_H
+#define NETWORK_CORE_UDP_H
+
+#ifdef ENABLE_NETWORK
+
+/**
+ * @file udp.h Basic functions to receive and send UDP packets.
+ */
+
+///** Sending/receiving of UDP packets **////
+
+void NetworkSendUDP_Packet(SOCKET udp, Packet *p, struct sockaddr_in *recv);
+bool NetworkUDPListen(SOCKET *udp, uint32 host, uint16 port, bool broadcast);
+void NetworkUDPReceive(SOCKET udp);
+
+/**
+ * Function that is called for every received UDP packet.
+ * @param packet the received packet
+ * @param client_addr the address of the sender of the packet
+ */
+void NetworkHandleUDPPacket(Packet *p, struct sockaddr_in *client_addr);
+
+
+///** Sending/receiving of (large) chuncks of UDP packets **////
+
+
+/** Enum with all types of UDP packets. The order MUST not be changed **/
+enum {
+ PACKET_UDP_CLIENT_FIND_SERVER, ///< Queries a game server for game information
+ PACKET_UDP_SERVER_RESPONSE, ///< Reply of the game server with game information
+ PACKET_UDP_CLIENT_DETAIL_INFO, ///< Queries a game server about details of the game, such as companies
+ PACKET_UDP_SERVER_DETAIL_INFO, ///< Reply of the game server about details of the game, such as companies
+ PACKET_UDP_SERVER_REGISTER, ///< Packet to register itself to the master server
+ PACKET_UDP_MASTER_ACK_REGISTER, ///< Packet indicating registration has succedeed
+ PACKET_UDP_CLIENT_GET_LIST, ///< Request for serverlist from master server
+ PACKET_UDP_MASTER_RESPONSE_LIST, ///< Response from master server with server ip's + port's
+ PACKET_UDP_SERVER_UNREGISTER, ///< Request to be removed from the server-list
+ PACKET_UDP_CLIENT_GET_NEWGRFS, ///< Requests the name for a list of GRFs (GRF_ID and MD5)
+ PACKET_UDP_SERVER_NEWGRFS, ///< Sends the list of NewGRF's requested.
+ PACKET_UDP_END ///< Must ALWAYS be on the end of this list!! (period)
+};
+
+void NetworkSend_GRFIdentifier(Packet *p, const GRFConfig *c);
+void NetworkSend_NetworkGameInfo(Packet *p, const NetworkGameInfo *info);
+
+void NetworkRecv_GRFIdentifier(NetworkClientState *cs, Packet *p, GRFConfig *c);
+void NetworkRecv_NetworkGameInfo(NetworkClientState *cs, Packet *p, NetworkGameInfo *info);
+
+/**
+ * Function that is called for every GRFConfig that is read when receiving
+ * a NetworkGameInfo. Only grfid and md5sum are set, the rest is zero. This
+ * function must set all appropriate fields. This GRF is later appended to
+ * the grfconfig list of the NetworkGameInfo.
+ * @param config the GRF to handle
+ */
+void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config);
+
+#endif /* ENABLE_NETWORK */
+
+#endif /* NETWORK_CORE_UDP_H */
diff --git a/src/network/network.c b/src/network/network.c
new file mode 100644
index 000000000..c8cb85804
--- /dev/null
+++ b/src/network/network.c
@@ -0,0 +1,1451 @@
+/* $Id$ */
+
+#include "../stdafx.h"
+#include "network_data.h"
+
+#if defined(WITH_REV)
+ extern const char _openttd_revision[];
+#elif defined(WITH_REV_HACK)
+ #define WITH_REV
+ const char _openttd_revision[] = WITH_REV_HACK;
+#else
+ const char _openttd_revision[] = NOREV_STRING;
+#endif
+
+
+#ifdef ENABLE_NETWORK
+
+#include "../openttd.h"
+#include "../debug.h"
+#include "../functions.h"
+#include "../string.h"
+#include "../strings.h"
+#include "../map.h"
+#include "../command.h"
+#include "../variables.h"
+#include "../date.h"
+#include "../newgrf_config.h"
+#include "table/strings.h"
+#include "network_client.h"
+#include "network_server.h"
+#include "network_udp.h"
+#include "network_gamelist.h"
+#include "core/udp.h"
+#include "core/tcp.h"
+#include "network_gui.h"
+#include "../console.h" /* IConsoleCmdExec */
+#include <stdarg.h> /* va_list */
+#include "../md5.h"
+
+#ifdef __MORPHOS__
+// the library base is required here
+struct Library *SocketBase = NULL;
+#endif
+
+// The listen socket for the server
+static SOCKET _listensocket;
+
+// The amount of clients connected
+static byte _network_clients_connected = 0;
+// The index counter for new clients (is never decreased)
+static uint16 _network_client_index = NETWORK_SERVER_INDEX + 1;
+
+/* Some externs / forwards */
+extern void StateGameLoop(void);
+
+// Function that looks up the CI for a given client-index
+NetworkClientInfo *NetworkFindClientInfoFromIndex(uint16 client_index)
+{
+ NetworkClientInfo *ci;
+
+ for (ci = _network_client_info; ci != endof(_network_client_info); ci++) {
+ if (ci->client_index == client_index) return ci;
+ }
+
+ return NULL;
+}
+
+/** Return the CI for a given IP
+ * @param ip IP of the client we are looking for. This must be in string-format
+ * @return return a pointer to the corresponding NetworkClientInfo struct or NULL on failure */
+NetworkClientInfo *NetworkFindClientInfoFromIP(const char *ip)
+{
+ NetworkClientInfo *ci;
+ uint32 ip_number = inet_addr(ip);
+
+ for (ci = _network_client_info; ci != endof(_network_client_info); ci++) {
+ if (ci->client_ip == ip_number) return ci;
+ }
+
+ return NULL;
+}
+
+// Function that looks up the CS for a given client-index
+NetworkClientState *NetworkFindClientStateFromIndex(uint16 client_index)
+{
+ NetworkClientState *cs;
+
+ for (cs = _clients; cs != &_clients[MAX_CLIENT_INFO]; cs++) {
+ if (cs->index == client_index) return cs;
+ }
+
+ return NULL;
+}
+
+// NetworkGetClientName is a server-safe function to get the name of the client
+// if the user did not send it yet, Client #<no> is used.
+void NetworkGetClientName(char *client_name, size_t size, const NetworkClientState *cs)
+{
+ const NetworkClientInfo *ci = DEREF_CLIENT_INFO(cs);
+
+ if (ci->client_name[0] == '\0') {
+ snprintf(client_name, size, "Client #%4d", cs->index);
+ } else {
+ ttd_strlcpy(client_name, ci->client_name, size);
+ }
+}
+
+byte NetworkSpectatorCount(void)
+{
+ const NetworkClientState *cs;
+ byte count = 0;
+
+ FOR_ALL_CLIENTS(cs) {
+ if (DEREF_CLIENT_INFO(cs)->client_playas == PLAYER_SPECTATOR) count++;
+ }
+
+ return count;
+}
+
+// This puts a text-message to the console, or in the future, the chat-box,
+// (to keep it all a bit more general)
+// If 'self_send' is true, this is the client who is sending the message
+void CDECL NetworkTextMessage(NetworkAction action, uint16 color, bool self_send, const char *name, const char *str, ...)
+{
+ char buf[1024];
+ va_list va;
+ const int duration = 10; // Game days the messages stay visible
+ char message[1024];
+ char temp[1024];
+
+ va_start(va, str);
+ vsnprintf(buf, lengthof(buf), str, va);
+ va_end(va);
+
+ switch (action) {
+ case NETWORK_ACTION_SERVER_MESSAGE:
+ color = 1;
+ snprintf(message, sizeof(message), "*** %s", buf);
+ break;
+ case NETWORK_ACTION_JOIN:
+ color = 1;
+ GetString(temp, STR_NETWORK_CLIENT_JOINED, lastof(temp));
+ snprintf(message, sizeof(message), "*** %s %s", name, temp);
+ break;
+ case NETWORK_ACTION_LEAVE:
+ color = 1;
+ GetString(temp, STR_NETWORK_ERR_LEFT, lastof(temp));
+ snprintf(message, sizeof(message), "*** %s %s (%s)", name, temp, buf);
+ break;
+ case NETWORK_ACTION_GIVE_MONEY:
+ if (self_send) {
+ SetDParamStr(0, name);
+ SetDParam(1, atoi(buf));
+ GetString(temp, STR_NETWORK_GAVE_MONEY_AWAY, lastof(temp));
+ snprintf(message, sizeof(message), "*** %s", temp);
+ } else {
+ SetDParam(0, atoi(buf));
+ GetString(temp, STR_NETWORK_GIVE_MONEY, lastof(temp));
+ snprintf(message, sizeof(message), "*** %s %s", name, temp);
+ }
+ break;
+ case NETWORK_ACTION_NAME_CHANGE:
+ GetString(temp, STR_NETWORK_NAME_CHANGE, lastof(temp));
+ snprintf(message, sizeof(message), "*** %s %s %s", name, temp, buf);
+ break;
+ case NETWORK_ACTION_CHAT_COMPANY:
+ SetDParamStr(0, name);
+ SetDParamStr(1, buf);
+ GetString(temp, self_send ? STR_NETWORK_CHAT_TO_COMPANY : STR_NETWORK_CHAT_COMPANY, lastof(temp));
+ ttd_strlcpy(message, temp, sizeof(message));
+ break;
+ case NETWORK_ACTION_CHAT_CLIENT:
+ SetDParamStr(0, name);
+ SetDParamStr(1, buf);
+ GetString(temp, self_send ? STR_NETWORK_CHAT_TO_CLIENT : STR_NETWORK_CHAT_CLIENT, lastof(temp));
+ ttd_strlcpy(message, temp, sizeof(message));
+ break;
+ default:
+ SetDParamStr(0, name);
+ SetDParamStr(1, buf);
+ GetString(temp, STR_NETWORK_CHAT_ALL, lastof(temp));
+ ttd_strlcpy(message, temp, sizeof(message));
+ break;
+ }
+
+ IConsolePrintF(color, "%s", message);
+ AddTextMessage(color, duration, "%s", message);
+}
+
+// Calculate the frame-lag of a client
+uint NetworkCalculateLag(const NetworkClientState *cs)
+{
+ int lag = cs->last_frame_server - cs->last_frame;
+ // This client has missed his ACK packet after 1 DAY_TICKS..
+ // so we increase his lag for every frame that passes!
+ // The packet can be out by a max of _net_frame_freq
+ if (cs->last_frame_server + DAY_TICKS + _network_frame_freq < _frame_counter)
+ lag += _frame_counter - (cs->last_frame_server + DAY_TICKS + _network_frame_freq);
+
+ return lag;
+}
+
+
+// There was a non-recoverable error, drop back to the main menu with a nice
+// error
+static void NetworkError(StringID error_string)
+{
+ _switch_mode = SM_MENU;
+ _switch_mode_errorstr = error_string;
+}
+
+static void ClientStartError(const char *error)
+{
+ DEBUG(net, 0, "[client] could not start network: %s",error);
+ NetworkError(STR_NETWORK_ERR_CLIENT_START);
+}
+
+static void ServerStartError(const char *error)
+{
+ DEBUG(net, 0, "[server] could not start network: %s",error);
+ NetworkError(STR_NETWORK_ERR_SERVER_START);
+}
+
+static void NetworkClientError(NetworkRecvStatus res, NetworkClientState* cs)
+{
+ // First, send a CLIENT_ERROR to the server, so he knows we are
+ // disconnection (and why!)
+ NetworkErrorCode errorno;
+
+ // We just want to close the connection..
+ if (res == NETWORK_RECV_STATUS_CLOSE_QUERY) {
+ cs->has_quit = true;
+ NetworkCloseClient(cs);
+ _networking = false;
+
+ DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
+ return;
+ }
+
+ switch (res) {
+ case NETWORK_RECV_STATUS_DESYNC: errorno = NETWORK_ERROR_DESYNC; break;
+ case NETWORK_RECV_STATUS_SAVEGAME: errorno = NETWORK_ERROR_SAVEGAME_FAILED; break;
+ default: errorno = NETWORK_ERROR_GENERAL; break;
+ }
+ // This means we fucked up and the server closed the connection
+ if (res != NETWORK_RECV_STATUS_SERVER_ERROR && res != NETWORK_RECV_STATUS_SERVER_FULL &&
+ res != NETWORK_RECV_STATUS_SERVER_BANNED) {
+ SEND_COMMAND(PACKET_CLIENT_ERROR)(errorno);
+
+ // Dequeue all commands before closing the socket
+ NetworkSend_Packets(DEREF_CLIENT(0));
+ }
+
+ _switch_mode = SM_MENU;
+ NetworkCloseClient(cs);
+ _networking = false;
+}
+
+/** Retrieve a string representation of an internal error number
+ * @param buf buffer where the error message will be stored
+ * @param err NetworkErrorCode
+ * @return returns a pointer to the error message (buf) */
+char* GetNetworkErrorMsg(char* buf, NetworkErrorCode err, const char* last)
+{
+ /* List of possible network errors, used by
+ * PACKET_SERVER_ERROR and PACKET_CLIENT_ERROR */
+ static const StringID network_error_strings[] = {
+ STR_NETWORK_ERR_CLIENT_GENERAL,
+ STR_NETWORK_ERR_CLIENT_DESYNC,
+ STR_NETWORK_ERR_CLIENT_SAVEGAME,
+ STR_NETWORK_ERR_CLIENT_CONNECTION_LOST,
+ STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR,
+ STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED,
+ STR_NETWORK_ERR_CLIENT_NOT_EXPECTED,
+ STR_NETWORK_ERR_CLIENT_WRONG_REVISION,
+ STR_NETWORK_ERR_CLIENT_NAME_IN_USE,
+ STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD,
+ STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH,
+ STR_NETWORK_ERR_CLIENT_KICKED,
+ STR_NETWORK_ERR_CLIENT_CHEATER,
+ STR_NETWORK_ERR_CLIENT_SERVER_FULL
+ };
+
+ if (err >= lengthof(network_error_strings)) err = 0;
+
+ return GetString(buf, network_error_strings[err], last);
+}
+
+/* Count the number of active clients connected */
+static uint NetworkCountPlayers(void)
+{
+ const NetworkClientState *cs;
+ uint count = 0;
+
+ FOR_ALL_CLIENTS(cs) {
+ const NetworkClientInfo *ci = DEREF_CLIENT_INFO(cs);
+ if (IsValidPlayer(ci->client_playas)) count++;
+ }
+
+ return count;
+}
+
+static bool _min_players_paused = false;
+
+/* Check if the minimum number of players has been reached and pause or unpause the game as appropriate */
+void CheckMinPlayers(void)
+{
+ if (!_network_dedicated) return;
+
+ if (NetworkCountPlayers() < _network_min_players) {
+ if (_min_players_paused) return;
+
+ _min_players_paused = true;
+ DoCommandP(0, 1, 0, NULL, CMD_PAUSE);
+ NetworkServer_HandleChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game paused (not enough players)", NETWORK_SERVER_INDEX);
+ } else {
+ if (!_min_players_paused) return;
+
+ _min_players_paused = false;
+ DoCommandP(0, 0, 0, NULL, CMD_PAUSE);
+ NetworkServer_HandleChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game unpaused (enough players)", NETWORK_SERVER_INDEX);
+ }
+}
+
+// Find all IP-aliases for this host
+static void NetworkFindIPs(void)
+{
+ int i;
+
+#if defined(BEOS_NET_SERVER) /* doesn't have neither getifaddrs or net/if.h */
+ /* Based on Andrew Bachmann's netstat+.c. Big thanks to him! */
+ int _netstat(int fd, char **output, int verbose);
+
+ int seek_past_header(char **pos, const char *header) {
+ char *new_pos = strstr(*pos, header);
+ if (new_pos == 0) {
+ return B_ERROR;
+ }
+ *pos += strlen(header) + new_pos - *pos + 1;
+ return B_OK;
+ }
+
+ int output_length;
+ char *output_pointer = NULL;
+ char **output;
+ int sock = socket(AF_INET, SOCK_DGRAM, 0);
+ i = 0;
+
+ // If something fails, make sure the list is empty
+ _broadcast_list[0] = 0;
+
+ if (sock < 0) {
+ DEBUG(net, 0, "[core] error creating socket");
+ return;
+ }
+
+ output_length = _netstat(sock, &output_pointer, 1);
+ if (output_length < 0) {
+ DEBUG(net, 0, "[core] error running _netstat");
+ return;
+ }
+
+ output = &output_pointer;
+ if (seek_past_header(output, "IP Interfaces:") == B_OK) {
+ for (;;) {
+ uint32 n, fields, read;
+ uint8 i1, i2, i3, i4, j1, j2, j3, j4;
+ struct in_addr inaddr;
+ uint32 ip;
+ uint32 netmask;
+
+ fields = sscanf(*output, "%u: %hhu.%hhu.%hhu.%hhu, netmask %hhu.%hhu.%hhu.%hhu%n",
+ &n, &i1,&i2,&i3,&i4, &j1,&j2,&j3,&j4, &read);
+ read += 1;
+ if (fields != 9) {
+ break;
+ }
+
+ ip = (uint32)i1 << 24 | (uint32)i2 << 16 | (uint32)i3 << 8 | (uint32)i4;
+ netmask = (uint32)j1 << 24 | (uint32)j2 << 16 | (uint32)j3 << 8 | (uint32)j4;
+
+ if (ip != INADDR_LOOPBACK && ip != INADDR_ANY) {
+ inaddr.s_addr = htonl(ip | ~netmask);
+ _broadcast_list[i] = inaddr.s_addr;
+ i++;
+ }
+ if (read < 0) {
+ break;
+ }
+ *output += read;
+ }
+ /* XXX - Using either one of these crashes openttd heavily? - wber */
+ /*free(output_pointer);*/
+ /*free(output);*/
+ closesocket(sock);
+ }
+#elif defined(HAVE_GETIFADDRS)
+ struct ifaddrs *ifap, *ifa;
+
+ // If something fails, make sure the list is empty
+ _broadcast_list[0] = 0;
+
+ if (getifaddrs(&ifap) != 0)
+ return;
+
+ i = 0;
+ for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
+ if (!(ifa->ifa_flags & IFF_BROADCAST)) continue;
+ if (ifa->ifa_broadaddr == NULL) continue;
+ if (ifa->ifa_broadaddr->sa_family != AF_INET) continue;
+ _broadcast_list[i] = ((struct sockaddr_in*)ifa->ifa_broadaddr)->sin_addr.s_addr;
+ i++;
+ }
+ freeifaddrs(ifap);
+
+#else /* not HAVE_GETIFADDRS */
+ SOCKET sock;
+#ifdef WIN32
+ DWORD len = 0;
+ INTERFACE_INFO ifo[MAX_INTERFACES];
+ uint j;
+#else
+ char buf[4 * 1024]; // Arbitrary buffer size
+ struct ifconf ifconf;
+ const char* buf_end;
+ const char* p;
+#endif
+
+ // If something fails, make sure the list is empty
+ _broadcast_list[0] = 0;
+
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sock == INVALID_SOCKET) return;
+
+#ifdef WIN32
+ memset(&ifo[0], 0, sizeof(ifo));
+ if ((WSAIoctl(sock, SIO_GET_INTERFACE_LIST, NULL, 0, &ifo[0], sizeof(ifo), &len, NULL, NULL)) != 0) {
+ closesocket(sock);
+ return;
+ }
+
+ i = 0;
+ for (j = 0; j < len / sizeof(*ifo); j++) {
+ if (ifo[j].iiFlags & IFF_LOOPBACK) continue;
+ if (!(ifo[j].iiFlags & IFF_BROADCAST)) continue;
+ /* iiBroadcast is unusable, because it always seems to be set to
+ * 255.255.255.255.
+ */
+ _broadcast_list[i++] =
+ ifo[j].iiAddress.AddressIn.sin_addr.s_addr |
+ ~ifo[j].iiNetmask.AddressIn.sin_addr.s_addr;
+ }
+#else
+ ifconf.ifc_len = sizeof(buf);
+ ifconf.ifc_buf = buf;
+ if (ioctl(sock, SIOCGIFCONF, &ifconf) == -1) {
+ closesocket(sock);
+ return;
+ }
+
+ i = 0;
+ buf_end = buf + ifconf.ifc_len;
+ for (p = buf; p < buf_end;) {
+ const struct ifreq* req = (const struct ifreq*)p;
+
+ if (req->ifr_addr.sa_family == AF_INET) {
+ struct ifreq r;
+
+ strncpy(r.ifr_name, req->ifr_name, lengthof(r.ifr_name));
+ if (ioctl(sock, SIOCGIFFLAGS, &r) != -1 &&
+ r.ifr_flags & IFF_BROADCAST &&
+ ioctl(sock, SIOCGIFBRDADDR, &r) != -1) {
+ _broadcast_list[i++] =
+ ((struct sockaddr_in*)&r.ifr_broadaddr)->sin_addr.s_addr;
+ }
+ }
+
+ p += sizeof(struct ifreq);
+#ifdef AF_LINK
+ p += req->ifr_addr.sa_len - sizeof(struct sockaddr);
+#endif
+ }
+#endif
+
+ closesocket(sock);
+#endif /* not HAVE_GETIFADDRS */
+
+ _broadcast_list[i] = 0;
+
+ DEBUG(net, 3, "Detected broadcast addresses:");
+ // Now display to the debug all the detected ips
+ for (i = 0; _broadcast_list[i] != 0; i++) {
+ DEBUG(net, 3, "%d) %s", i, inet_ntoa(*(struct in_addr *)&_broadcast_list[i]));//inet_ntoa(inaddr));
+ }
+}
+
+// Resolve a hostname to a inet_addr
+unsigned long NetworkResolveHost(const char *hostname)
+{
+ in_addr_t ip;
+
+ // First try: is it an ip address?
+ ip = inet_addr(hostname);
+
+ // If not try to resolve the name
+ if (ip == INADDR_NONE) {
+ struct hostent *he = gethostbyname(hostname);
+ if (he == NULL) {
+ DEBUG(net, 0, "Cannot resolve '%s'", hostname);
+ } else {
+ struct in_addr addr = *(struct in_addr *)he->h_addr_list[0];
+ DEBUG(net, 1, "Resolved '%s' to %s", hostname, inet_ntoa(addr));
+ ip = addr.s_addr;
+ }
+ }
+ return ip;
+}
+
+// Converts a string to ip/port/player
+// Format: IP#player:port
+//
+// connection_string will be re-terminated to seperate out the hostname, and player and port will
+// be set to the player and port strings given by the user, inside the memory area originally
+// occupied by connection_string.
+void ParseConnectionString(const char **player, const char **port, char *connection_string)
+{
+ char *p;
+ for (p = connection_string; *p != '\0'; p++) {
+ if (*p == '#') {
+ *p = '\0';
+ *player = ++p;
+ while (IsValidChar(*p, CS_NUMERAL)) p++;
+ if (*p == '\0') break;
+ } else if (*p == ':') {
+ *port = p + 1;
+ *p = '\0';
+ }
+ }
+}
+
+// Creates a new client from a socket
+// Used both by the server and the client
+static NetworkClientState *NetworkAllocClient(SOCKET s)
+{
+ NetworkClientState *cs;
+ byte client_no = 0;
+
+ if (_network_server) {
+ // Can we handle a new client?
+ if (_network_clients_connected >= MAX_CLIENTS) return NULL;
+ if (_network_game_info.clients_on >= _network_game_info.clients_max) return NULL;
+
+ // Register the login
+ client_no = _network_clients_connected++;
+ }
+
+ cs = DEREF_CLIENT(client_no);
+ memset(cs, 0, sizeof(*cs));
+ cs->socket = s;
+ cs->last_frame = 0;
+ cs->has_quit = false;
+
+ cs->last_frame = _frame_counter;
+ cs->last_frame_server = _frame_counter;
+
+ if (_network_server) {
+ NetworkClientInfo *ci = DEREF_CLIENT_INFO(cs);
+ memset(ci, 0, sizeof(*ci));
+
+ cs->index = _network_client_index++;
+ ci->client_index = cs->index;
+ ci->client_playas = PLAYER_INACTIVE_CLIENT;
+ ci->join_date = _date;
+
+ InvalidateWindow(WC_CLIENT_LIST, 0);
+ }
+
+ return cs;
+}
+
+// Close a connection
+void NetworkCloseClient(NetworkClientState *cs)
+{
+ NetworkClientInfo *ci;
+ // Socket is already dead
+ if (cs->socket == INVALID_SOCKET) {
+ cs->has_quit = true;
+ return;
+ }
+
+ DEBUG(net, 1, "Closed client connection %d", cs->index);
+
+ if (!cs->has_quit && _network_server && cs->status > STATUS_INACTIVE) {
+ // We did not receive a leave message from this client...
+ NetworkErrorCode errorno = NETWORK_ERROR_CONNECTION_LOST;
+ char str[100];
+ char client_name[NETWORK_CLIENT_NAME_LENGTH];
+ NetworkClientState *new_cs;
+
+ NetworkGetClientName(client_name, sizeof(client_name), cs);
+
+ GetNetworkErrorMsg(str, errorno, lastof(str));
+
+ NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, client_name, "%s", str);
+
+ // Inform other clients of this... strange leaving ;)
+ FOR_ALL_CLIENTS(new_cs) {
+ if (new_cs->status > STATUS_AUTH && cs != new_cs) {
+ SEND_COMMAND(PACKET_SERVER_ERROR_QUIT)(new_cs, cs->index, errorno);
+ }
+ }
+ }
+
+ /* When the client was PRE_ACTIVE, the server was in pause mode, so unpause */
+ if (cs->status == STATUS_PRE_ACTIVE && _network_pause_on_join) {
+ DoCommandP(0, 0, 0, NULL, CMD_PAUSE);
+ NetworkServer_HandleChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game unpaused", NETWORK_SERVER_INDEX);
+ }
+
+ closesocket(cs->socket);
+ cs->writable = false;
+ cs->has_quit = true;
+
+ // Free all pending and partially received packets
+ while (cs->packet_queue != NULL) {
+ Packet *p = cs->packet_queue->next;
+ free(cs->packet_queue);
+ cs->packet_queue = p;
+ }
+ free(cs->packet_recv);
+ cs->packet_recv = NULL;
+
+ while (cs->command_queue != NULL) {
+ CommandPacket *p = cs->command_queue->next;
+ free(cs->command_queue);
+ cs->command_queue = p;
+ }
+
+ // Close the gap in the client-list
+ ci = DEREF_CLIENT_INFO(cs);
+
+ if (_network_server) {
+ // We just lost one client :(
+ if (cs->status > STATUS_INACTIVE) _network_game_info.clients_on--;
+ _network_clients_connected--;
+
+ while ((cs + 1) != DEREF_CLIENT(MAX_CLIENTS) && (cs + 1)->socket != INVALID_SOCKET) {
+ *cs = *(cs + 1);
+ *ci = *(ci + 1);
+ cs++;
+ ci++;
+ }
+
+ InvalidateWindow(WC_CLIENT_LIST, 0);
+ }
+
+ // Reset the status of the last socket
+ cs->socket = INVALID_SOCKET;
+ cs->status = STATUS_INACTIVE;
+ cs->index = NETWORK_EMPTY_INDEX;
+ ci->client_index = NETWORK_EMPTY_INDEX;
+
+ CheckMinPlayers();
+}
+
+// A client wants to connect to a server
+static bool NetworkConnect(const char *hostname, int port)
+{
+ SOCKET s;
+ struct sockaddr_in sin;
+
+ DEBUG(net, 1, "Connecting to %s %d", hostname, port);
+
+ s = socket(AF_INET, SOCK_STREAM, 0);
+ if (s == INVALID_SOCKET) {
+ ClientStartError("socket() failed");
+ return false;
+ }
+
+ if (!SetNoDelay(s)) DEBUG(net, 1, "Setting TCP_NODELAY failed");
+
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = NetworkResolveHost(hostname);
+ sin.sin_port = htons(port);
+ _network_last_host_ip = sin.sin_addr.s_addr;
+
+ /* We failed to connect for which reason what so ever */
+ if (connect(s, (struct sockaddr*) &sin, sizeof(sin)) != 0) return false;
+
+ if (!SetNonBlocking(s)) DEBUG(net, 0, "Setting non-blocking mode failed"); // XXX should this be an error?
+
+ // in client mode, only the first client field is used. it's pointing to the server.
+ NetworkAllocClient(s);
+
+ _network_join_status = NETWORK_JOIN_STATUS_CONNECTING;
+ ShowJoinStatusWindow();
+
+ return true;
+}
+
+// For the server, to accept new clients
+static void NetworkAcceptClients(void)
+{
+ struct sockaddr_in sin;
+ NetworkClientState *cs;
+ uint i;
+ bool banned;
+
+ // Should never ever happen.. is it possible??
+ assert(_listensocket != INVALID_SOCKET);
+
+ for (;;) {
+ socklen_t sin_len = sizeof(sin);
+ SOCKET s = accept(_listensocket, (struct sockaddr*)&sin, &sin_len);
+ if (s == INVALID_SOCKET) return;
+
+ SetNonBlocking(s); // XXX error handling?
+
+ DEBUG(net, 1, "Client connected from %s on frame %d", inet_ntoa(sin.sin_addr), _frame_counter);
+
+ SetNoDelay(s); // XXX error handling?
+
+ /* Check if the client is banned */
+ banned = false;
+ for (i = 0; i < lengthof(_network_ban_list); i++) {
+ if (_network_ban_list[i] == NULL) continue;
+
+ if (sin.sin_addr.s_addr == inet_addr(_network_ban_list[i])) {
+ Packet *p = NetworkSend_Init(PACKET_SERVER_BANNED);
+
+ DEBUG(net, 1, "Banned ip tried to join (%s), refused", _network_ban_list[i]);
+
+ p->buffer[0] = p->size & 0xFF;
+ p->buffer[1] = p->size >> 8;
+
+ send(s, p->buffer, p->size, 0);
+ closesocket(s);
+
+ free(p);
+
+ banned = true;
+ break;
+ }
+ }
+ /* If this client is banned, continue with next client */
+ if (banned) continue;
+
+ cs = NetworkAllocClient(s);
+ if (cs == NULL) {
+ // no more clients allowed?
+ // Send to the client that we are full!
+ Packet *p = NetworkSend_Init(PACKET_SERVER_FULL);
+
+ p->buffer[0] = p->size & 0xFF;
+ p->buffer[1] = p->size >> 8;
+
+ send(s, p->buffer, p->size, 0);
+ closesocket(s);
+
+ free(p);
+
+ continue;
+ }
+
+ // a new client has connected. We set him at inactive for now
+ // maybe he is only requesting server-info. Till he has sent a PACKET_CLIENT_MAP_OK
+ // the client stays inactive
+ cs->status = STATUS_INACTIVE;
+
+ DEREF_CLIENT_INFO(cs)->client_ip = sin.sin_addr.s_addr; // Save the IP of the client
+ }
+}
+
+// Set up the listen socket for the server
+static bool NetworkListen(void)
+{
+ SOCKET ls;
+ struct sockaddr_in sin;
+
+ DEBUG(net, 1, "Listening on %s:%d", _network_server_bind_ip_host, _network_server_port);
+
+ ls = socket(AF_INET, SOCK_STREAM, 0);
+ if (ls == INVALID_SOCKET) {
+ ServerStartError("socket() on listen socket failed");
+ return false;
+ }
+
+ { // reuse the socket
+ int reuse = 1;
+ // The (const char*) cast is needed for windows!!
+ if (setsockopt(ls, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) == -1) {
+ ServerStartError("setsockopt() on listen socket failed");
+ return false;
+ }
+ }
+
+ if (!SetNonBlocking(ls)) DEBUG(net, 0, "Setting non-blocking mode failed"); // XXX should this be an error?
+
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = _network_server_bind_ip;
+ sin.sin_port = htons(_network_server_port);
+
+ if (bind(ls, (struct sockaddr*)&sin, sizeof(sin)) != 0) {
+ ServerStartError("bind() failed");
+ return false;
+ }
+
+ if (listen(ls, 1) != 0) {
+ ServerStartError("listen() failed");
+ return false;
+ }
+
+ _listensocket = ls;
+
+ return true;
+}
+
+// Close all current connections
+static void NetworkClose(void)
+{
+ NetworkClientState *cs;
+
+ FOR_ALL_CLIENTS(cs) {
+ if (!_network_server) {
+ SEND_COMMAND(PACKET_CLIENT_QUIT)("leaving");
+ NetworkSend_Packets(cs);
+ }
+ NetworkCloseClient(cs);
+ }
+
+ if (_network_server) {
+ // We are a server, also close the listensocket
+ closesocket(_listensocket);
+ _listensocket = INVALID_SOCKET;
+ DEBUG(net, 1, "Closed listener");
+ NetworkUDPClose();
+ }
+}
+
+// Inits the network (cleans sockets and stuff)
+static void NetworkInitialize(void)
+{
+ NetworkClientState *cs;
+
+ _local_command_queue = NULL;
+
+ // Clean all client-sockets
+ memset(_clients, 0, sizeof(_clients));
+ for (cs = _clients; cs != &_clients[MAX_CLIENTS]; cs++) {
+ cs->socket = INVALID_SOCKET;
+ cs->status = STATUS_INACTIVE;
+ cs->command_queue = NULL;
+ }
+
+ // Clean the client_info memory
+ memset(&_network_client_info, 0, sizeof(_network_client_info));
+ memset(&_network_player_info, 0, sizeof(_network_player_info));
+
+ _sync_frame = 0;
+ _network_first_time = true;
+
+ _network_reconnect = 0;
+
+ NetworkUDPInitialize();
+}
+
+// Query a server to fetch his game-info
+// If game_info is true, only the gameinfo is fetched,
+// else only the client_info is fetched
+NetworkGameList *NetworkQueryServer(const char* host, unsigned short port, bool game_info)
+{
+ if (!_network_available) return NULL;
+
+ NetworkDisconnect();
+
+ if (game_info) return NetworkUDPQueryServer(host, port);
+
+ NetworkInitialize();
+
+ _network_server = false;
+
+ // Try to connect
+ _networking = NetworkConnect(host, port);
+
+ // We are connected
+ if (_networking) {
+ SEND_COMMAND(PACKET_CLIENT_COMPANY_INFO)();
+ } else { // No networking, close everything down again
+ NetworkDisconnect();
+ }
+
+ return NULL;
+}
+
+/* Validates an address entered as a string and adds the server to
+ * the list. If you use this function, the games will be marked
+ * as manually added. */
+void NetworkAddServer(const char *b)
+{
+ if (*b != '\0') {
+ NetworkGameList *item;
+ const char *port = NULL;
+ const char *player = NULL;
+ char host[NETWORK_HOSTNAME_LENGTH];
+ uint16 rport;
+
+ ttd_strlcpy(host, b, lengthof(host));
+
+ ttd_strlcpy(_network_default_ip, b, lengthof(_network_default_ip));
+ rport = NETWORK_DEFAULT_PORT;
+
+ ParseConnectionString(&player, &port, host);
+ if (port != NULL) rport = atoi(port);
+
+ item = NetworkQueryServer(host, rport, true);
+ item->manually = true;
+ }
+}
+
+/* Generates the list of manually added hosts from NetworkGameList and
+ * dumps them into the array _network_host_list. This array is needed
+ * by the function that generates the config file. */
+void NetworkRebuildHostList(void)
+{
+ uint i = 0;
+ const NetworkGameList *item = _network_game_list;
+ while (item != NULL && i != lengthof(_network_host_list)) {
+ if (item->manually) {
+ free(_network_host_list[i]);
+ _network_host_list[i++] = str_fmt("%s:%i", item->info.hostname, item->port);
+ }
+ item = item->next;
+ }
+
+ for (; i < lengthof(_network_host_list); i++) {
+ free(_network_host_list[i]);
+ _network_host_list[i] = NULL;
+ }
+}
+
+// Used by clients, to connect to a server
+bool NetworkClientConnectGame(const char *host, uint16 port)
+{
+ if (!_network_available) return false;
+
+ if (port == 0) return false;
+
+ ttd_strlcpy(_network_last_host, host, sizeof(_network_last_host));
+ _network_last_port = port;
+
+ NetworkDisconnect();
+ NetworkUDPClose();
+ NetworkInitialize();
+
+ // Try to connect
+ _networking = NetworkConnect(host, port);
+
+ // We are connected
+ if (_networking) {
+ IConsoleCmdExec("exec scripts/on_client.scr 0");
+ NetworkClient_Connected();
+ } else {
+ // Connecting failed
+ NetworkError(STR_NETWORK_ERR_NOCONNECTION);
+ }
+
+ return _networking;
+}
+
+static void NetworkInitGameInfo(void)
+{
+ NetworkClientInfo *ci;
+
+ ttd_strlcpy(_network_game_info.server_name, _network_server_name, sizeof(_network_game_info.server_name));
+ ttd_strlcpy(_network_game_info.server_password, _network_server_password, sizeof(_network_server_password));
+ ttd_strlcpy(_network_game_info.rcon_password, _network_rcon_password, sizeof(_network_rcon_password));
+ if (_network_game_info.server_name[0] == '\0')
+ snprintf(_network_game_info.server_name, sizeof(_network_game_info.server_name), "Unnamed Server");
+
+ ttd_strlcpy(_network_game_info.server_revision, _openttd_revision, sizeof(_network_game_info.server_revision));
+
+ // The server is a client too ;)
+ if (_network_dedicated) {
+ _network_game_info.clients_on = 0;
+ _network_game_info.companies_on = 0;
+ _network_game_info.dedicated = true;
+ } else {
+ _network_game_info.clients_on = 1;
+ _network_game_info.companies_on = 1;
+ _network_game_info.dedicated = false;
+ }
+
+ _network_game_info.spectators_on = 0;
+
+ _network_game_info.game_date = _date;
+ _network_game_info.start_date = ConvertYMDToDate(_patches.starting_year, 0, 1);
+ _network_game_info.map_width = MapSizeX();
+ _network_game_info.map_height = MapSizeY();
+ _network_game_info.map_set = _opt.landscape;
+
+ _network_game_info.use_password = (_network_server_password[0] != '\0');
+
+ // We use _network_client_info[MAX_CLIENT_INFO - 1] to store the server-data in it
+ // The index is NETWORK_SERVER_INDEX ( = 1)
+ ci = &_network_client_info[MAX_CLIENT_INFO - 1];
+ memset(ci, 0, sizeof(*ci));
+
+ ci->client_index = NETWORK_SERVER_INDEX;
+ ci->client_playas = _network_dedicated ? PLAYER_SPECTATOR : _local_player;
+
+ ttd_strlcpy(ci->client_name, _network_player_name, sizeof(ci->client_name));
+ ttd_strlcpy(ci->unique_id, _network_unique_id, sizeof(ci->unique_id));
+}
+
+bool NetworkServerStart(void)
+{
+ if (!_network_available) return false;
+
+ /* Call the pre-scripts */
+ IConsoleCmdExec("exec scripts/pre_server.scr 0");
+ if (_network_dedicated) IConsoleCmdExec("exec scripts/pre_dedicated.scr 0");
+
+ NetworkInitialize();
+ if (!NetworkListen()) return false;
+
+ // Try to start UDP-server
+ _network_udp_server = true;
+ _network_udp_server = NetworkUDPListen(&_udp_server_socket, _network_server_bind_ip, _network_server_port, false);
+
+ _network_server = true;
+ _networking = true;
+ _frame_counter = 0;
+ _frame_counter_server = 0;
+ _frame_counter_max = 0;
+ _last_sync_frame = 0;
+ _network_own_client_index = NETWORK_SERVER_INDEX;
+
+ /* Non-dedicated server will always be player #1 */
+ if (!_network_dedicated) _network_playas = 0;
+
+ _network_clients_connected = 0;
+
+ NetworkInitGameInfo();
+
+ // execute server initialization script
+ IConsoleCmdExec("exec scripts/on_server.scr 0");
+ // if the server is dedicated ... add some other script
+ if (_network_dedicated) IConsoleCmdExec("exec scripts/on_dedicated.scr 0");
+
+ _min_players_paused = false;
+ CheckMinPlayers();
+
+ /* Try to register us to the master server */
+ _network_last_advertise_frame = 0;
+ _network_need_advertise = true;
+ NetworkUDPAdvertise();
+ return true;
+}
+
+// The server is rebooting...
+// The only difference with NetworkDisconnect, is the packets that is sent
+void NetworkReboot(void)
+{
+ if (_network_server) {
+ NetworkClientState *cs;
+ FOR_ALL_CLIENTS(cs) {
+ SEND_COMMAND(PACKET_SERVER_NEWGAME)(cs);
+ NetworkSend_Packets(cs);
+ }
+ }
+
+ NetworkClose();
+
+ // Free all queued commands
+ while (_local_command_queue != NULL) {
+ CommandPacket *p = _local_command_queue;
+ _local_command_queue = _local_command_queue->next;
+ free(p);
+ }
+
+ _networking = false;
+ _network_server = false;
+}
+
+// We want to disconnect from the host/clients
+void NetworkDisconnect(void)
+{
+ if (_network_server) {
+ NetworkClientState *cs;
+ FOR_ALL_CLIENTS(cs) {
+ SEND_COMMAND(PACKET_SERVER_SHUTDOWN)(cs);
+ NetworkSend_Packets(cs);
+ }
+ }
+
+ if (_network_advertise) NetworkUDPRemoveAdvertise();
+
+ DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
+
+ NetworkClose();
+
+ // Free all queued commands
+ while (_local_command_queue != NULL) {
+ CommandPacket *p = _local_command_queue;
+ _local_command_queue = _local_command_queue->next;
+ free(p);
+ }
+
+ _networking = false;
+ _network_server = false;
+}
+
+// Receives something from the network
+static bool NetworkReceive(void)
+{
+ NetworkClientState *cs;
+ int n;
+ fd_set read_fd, write_fd;
+ struct timeval tv;
+
+ FD_ZERO(&read_fd);
+ FD_ZERO(&write_fd);
+
+ FOR_ALL_CLIENTS(cs) {
+ FD_SET(cs->socket, &read_fd);
+ FD_SET(cs->socket, &write_fd);
+ }
+
+ // take care of listener port
+ if (_network_server) FD_SET(_listensocket, &read_fd);
+
+ tv.tv_sec = tv.tv_usec = 0; // don't block at all.
+#if !defined(__MORPHOS__) && !defined(__AMIGA__)
+ n = select(FD_SETSIZE, &read_fd, &write_fd, NULL, &tv);
+#else
+ n = WaitSelect(FD_SETSIZE, &read_fd, &write_fd, NULL, &tv, NULL);
+#endif
+ if (n == -1 && !_network_server) NetworkError(STR_NETWORK_ERR_LOSTCONNECTION);
+
+ // accept clients..
+ if (_network_server && FD_ISSET(_listensocket, &read_fd)) NetworkAcceptClients();
+
+ // read stuff from clients
+ FOR_ALL_CLIENTS(cs) {
+ cs->writable = !!FD_ISSET(cs->socket, &write_fd);
+ if (FD_ISSET(cs->socket, &read_fd)) {
+ if (_network_server) {
+ NetworkServer_ReadPackets(cs);
+ } else {
+ NetworkRecvStatus res;
+
+ // The client already was quiting!
+ if (cs->has_quit) return false;
+
+ res = NetworkClient_ReadPackets(cs);
+ if (res != NETWORK_RECV_STATUS_OKAY) {
+ // The client made an error of which we can not recover
+ // close the client and drop back to main menu
+ NetworkClientError(res, cs);
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+}
+
+// This sends all buffered commands (if possible)
+static void NetworkSend(void)
+{
+ NetworkClientState *cs;
+ FOR_ALL_CLIENTS(cs) {
+ if (cs->writable) {
+ NetworkSend_Packets(cs);
+
+ if (cs->status == STATUS_MAP) {
+ // This client is in the middle of a map-send, call the function for that
+ SEND_COMMAND(PACKET_SERVER_MAP)(cs);
+ }
+ }
+ }
+}
+
+// Handle the local-command-queue
+static void NetworkHandleLocalQueue(void)
+{
+ CommandPacket *cp, **cp_prev;
+
+ cp_prev = &_local_command_queue;
+
+ while ( (cp = *cp_prev) != NULL) {
+
+ // The queue is always in order, which means
+ // that the first element will be executed first.
+ if (_frame_counter < cp->frame) break;
+
+ if (_frame_counter > cp->frame) {
+ // If we reach here, it means for whatever reason, we've already executed
+ // past the command we need to execute.
+ DEBUG(net, 0, "Trying to execute a packet in the past!");
+ assert(0);
+ }
+
+ // We can execute this command
+ NetworkExecuteCommand(cp);
+
+ *cp_prev = cp->next;
+ free(cp);
+ }
+
+ // Just a safety check, to be removed in the future.
+ // Make sure that no older command appears towards the end of the queue
+ // In that case we missed executing it. This will never happen.
+ for (cp = _local_command_queue; cp; cp = cp->next) {
+ assert(_frame_counter < cp->frame);
+ }
+
+}
+
+static bool NetworkDoClientLoop(void)
+{
+ _frame_counter++;
+
+ NetworkHandleLocalQueue();
+
+ StateGameLoop();
+
+ // Check if we are in sync!
+ if (_sync_frame != 0) {
+ if (_sync_frame == _frame_counter) {
+#ifdef NETWORK_SEND_DOUBLE_SEED
+ if (_sync_seed_1 != _random_seeds[0][0] || _sync_seed_2 != _random_seeds[0][1]) {
+#else
+ if (_sync_seed_1 != _random_seeds[0][0]) {
+#endif
+ NetworkError(STR_NETWORK_ERR_DESYNC);
+ DEBUG(net, 0, "Sync error detected!");
+ NetworkClientError(NETWORK_RECV_STATUS_DESYNC, DEREF_CLIENT(0));
+ return false;
+ }
+
+ // If this is the first time we have a sync-frame, we
+ // need to let the server know that we are ready and at the same
+ // frame as he is.. so we can start playing!
+ if (_network_first_time) {
+ _network_first_time = false;
+ SEND_COMMAND(PACKET_CLIENT_ACK)();
+ }
+
+ _sync_frame = 0;
+ } else if (_sync_frame < _frame_counter) {
+ DEBUG(net, 1, "Missed frame for sync-test (%d / %d)", _sync_frame, _frame_counter);
+ _sync_frame = 0;
+ }
+ }
+
+ return true;
+}
+
+// We have to do some UDP checking
+void NetworkUDPGameLoop(void)
+{
+ if (_network_udp_server) {
+ NetworkUDPReceive(_udp_server_socket);
+ if (_udp_master_socket != INVALID_SOCKET) {
+ NetworkUDPReceive(_udp_master_socket);
+ }
+ } else if (_udp_client_socket != INVALID_SOCKET) {
+ NetworkUDPReceive(_udp_client_socket);
+ if (_network_udp_broadcast > 0) _network_udp_broadcast--;
+ }
+}
+
+// The main loop called from ttd.c
+// Here we also have to do StateGameLoop if needed!
+void NetworkGameLoop(void)
+{
+ if (!_networking) return;
+
+ if (!NetworkReceive()) return;
+
+ if (_network_server) {
+ bool send_frame = false;
+
+ // We first increase the _frame_counter
+ _frame_counter++;
+ // Update max-frame-counter
+ if (_frame_counter > _frame_counter_max) {
+ _frame_counter_max = _frame_counter + _network_frame_freq;
+ send_frame = true;
+ }
+
+ NetworkHandleLocalQueue();
+
+ // Then we make the frame
+ StateGameLoop();
+
+ _sync_seed_1 = _random_seeds[0][0];
+#ifdef NETWORK_SEND_DOUBLE_SEED
+ _sync_seed_2 = _random_seeds[0][1];
+#endif
+
+ NetworkServer_Tick(send_frame);
+ } else {
+ // Client
+
+ // Make sure we are at the frame were the server is (quick-frames)
+ if (_frame_counter_server > _frame_counter) {
+ while (_frame_counter_server > _frame_counter) {
+ if (!NetworkDoClientLoop()) break;
+ }
+ } else {
+ // Else, keep on going till _frame_counter_max
+ if (_frame_counter_max > _frame_counter) NetworkDoClientLoop();
+ }
+ }
+
+ NetworkSend();
+}
+
+static void NetworkGenerateUniqueId(void)
+{
+ md5_state_t state;
+ md5_byte_t digest[16];
+ char hex_output[16*2 + 1];
+ char coding_string[NETWORK_NAME_LENGTH];
+ int di;
+
+ snprintf(coding_string, sizeof(coding_string), "%d%s", (uint)Random(), "OpenTTD Unique ID");
+
+ /* Generate the MD5 hash */
+ md5_init(&state);
+ md5_append(&state, (const md5_byte_t*)coding_string, strlen(coding_string));
+ md5_finish(&state, digest);
+
+ for (di = 0; di < 16; ++di)
+ sprintf(hex_output + di * 2, "%02x", digest[di]);
+
+ /* _network_unique_id is our id */
+ snprintf(_network_unique_id, sizeof(_network_unique_id), "%s", hex_output);
+}
+
+// This tries to launch the network for a given OS
+void NetworkStartUp(void)
+{
+ DEBUG(net, 3, "[core] starting network...");
+
+#if defined(__MORPHOS__) || defined(__AMIGA__)
+ /*
+ * IMPORTANT NOTE: SocketBase needs to be initialized before we use _any_
+ * network related function, else: crash.
+ */
+ DEBUG(net, 3, "[core] loading bsd socket library");
+ SocketBase = OpenLibrary("bsdsocket.library", 4);
+ if (SocketBase == NULL) {
+ DEBUG(net, 0, "[core] can't open bsdsocket.library version 4, network unavailable");
+ _network_available = false;
+ return;
+ }
+
+#if defined(__AMIGA__)
+ // for usleep() implementation (only required for legacy AmigaOS builds)
+ TimerPort = CreateMsgPort();
+ if (TimerPort != NULL) {
+ TimerRequest = (struct timerequest*)CreateIORequest(TimerPort, sizeof(struct timerequest);
+ if (TimerRequest != NULL) {
+ if (OpenDevice("timer.device", UNIT_MICROHZ, (struct IORequest*)TimerRequest, 0) == 0) {
+ TimerBase = TimerRequest->tr_node.io_Device;
+ if (TimerBase == NULL) {
+ // free ressources...
+ DEBUG(net, 0, "[core] can't initialize timer, network unavailable");
+ _network_available = false;
+ return;
+ }
+ }
+ }
+ }
+#endif // __AMIGA__
+#endif // __MORPHOS__ / __AMIGA__
+
+ // Network is available
+ _network_available = true;
+ _network_dedicated = false;
+ _network_last_advertise_frame = 0;
+ _network_need_advertise = true;
+ _network_advertise_retries = 0;
+
+ /* Load the ip from the openttd.cfg */
+ _network_server_bind_ip = inet_addr(_network_server_bind_ip_host);
+ /* And put the data back in it in case it was an invalid ip */
+ snprintf(_network_server_bind_ip_host, sizeof(_network_server_bind_ip_host), "%s", inet_ntoa(*(struct in_addr *)&_network_server_bind_ip));
+
+ /* Generate an unique id when there is none yet */
+ if (_network_unique_id[0] == '\0') NetworkGenerateUniqueId();
+
+ {
+ byte cl_max = _network_game_info.clients_max;
+ byte cp_max = _network_game_info.companies_max;
+ byte sp_max = _network_game_info.spectators_max;
+
+ memset(&_network_game_info, 0, sizeof(_network_game_info));
+ _network_game_info.clients_max = cl_max;
+ _network_game_info.companies_max = cp_max;
+ _network_game_info.spectators_max = sp_max;
+ }
+
+ // Let's load the network in windows
+ #if defined(WIN32)
+ {
+ WSADATA wsa;
+ DEBUG(net, 3, "[core] loading windows socket library");
+ if (WSAStartup(MAKEWORD(2,0), &wsa) != 0) {
+ DEBUG(net, 0, "[core] WSAStartup failed, network unavailable");
+ _network_available = false;
+ return;
+ }
+ }
+ #endif // WIN32
+
+ NetworkInitialize();
+ DEBUG(net, 3, "[core] network online, multiplayer available");
+ NetworkFindIPs();
+}
+
+// This shuts the network down
+void NetworkShutDown(void)
+{
+ NetworkDisconnect();
+ NetworkUDPClose();
+
+ DEBUG(net, 3, "[core] shutting down network");
+
+ _network_available = false;
+
+#if defined(__MORPHOS__) || defined(__AMIGA__)
+ // free allocated ressources
+#if defined(__AMIGA__)
+ if (TimerBase != NULL) CloseDevice((struct IORequest*)TimerRequest); // XXX This smells wrong
+ if (TimerRequest != NULL) DeleteIORequest(TimerRequest);
+ if (TimerPort != NULL) DeleteMsgPort(TimerPort);
+#endif
+
+ if (SocketBase != NULL) CloseLibrary(SocketBase);
+#endif
+
+#if defined(WIN32)
+ WSACleanup();
+#endif
+}
+
+#endif /* ENABLE_NETWORK */
diff --git a/src/network/network.h b/src/network/network.h
new file mode 100644
index 000000000..779fe393e
--- /dev/null
+++ b/src/network/network.h
@@ -0,0 +1,212 @@
+/* $Id$ */
+
+#ifndef NETWORK_H
+#define NETWORK_H
+
+#define NOREV_STRING "norev000"
+
+#ifdef ENABLE_NETWORK
+
+#include "../player.h"
+#include "core/config.h"
+#include "core/game.h"
+
+// If this line is enable, every frame will have a sync test
+// this is not needed in normal games. Normal is like 1 sync in 100
+// frames. You can enable this if you have a lot of desyncs on a certain
+// game.
+// Remember: both client and server have to be compiled with this
+// option enabled to make it to work. If one of the two has it disabled
+// nothing will happen.
+//#define ENABLE_NETWORK_SYNC_EVERY_FRAME
+
+// In theory sending 1 of the 2 seeds is enough to check for desyncs
+// so in theory, this next define can be left off.
+//#define NETWORK_SEND_DOUBLE_SEED
+
+// How many clients can we have? Like.. MAX_PLAYERS - 1 is the amount of
+// players that can really play.. so.. a max of 4 spectators.. gives us..
+// MAX_PLAYERS + 3
+#define MAX_CLIENTS (MAX_PLAYERS + 3)
+
+
+// Do not change this next line. It should _ALWAYS_ be MAX_CLIENTS + 1
+#define MAX_CLIENT_INFO (MAX_CLIENTS + 1)
+
+#define MAX_INTERFACES 9
+
+
+// How many vehicle/station types we put over the network
+#define NETWORK_VEHICLE_TYPES 5
+#define NETWORK_STATION_TYPES 5
+
+typedef struct NetworkPlayerInfo {
+ char company_name[NETWORK_NAME_LENGTH]; // Company name
+ char password[NETWORK_PASSWORD_LENGTH]; // The password for the player
+ Year inaugurated_year; // What year the company started in
+ int64 company_value; // The company value
+ int64 money; // The amount of money the company has
+ int64 income; // How much did the company earned last year
+ uint16 performance; // What was his performance last month?
+ byte use_password; // 0: No password 1: There is a password
+ uint16 num_vehicle[NETWORK_VEHICLE_TYPES]; // How many vehicles are there of this type?
+ uint16 num_station[NETWORK_STATION_TYPES]; // How many stations are there of this type?
+ char players[NETWORK_PLAYERS_LENGTH]; // The players that control this company (Name1, name2, ..)
+ uint16 months_empty; // How many months the company is empty
+} NetworkPlayerInfo;
+
+typedef struct NetworkClientInfo {
+ uint16 client_index; // Index of the client (same as ClientState->index)
+ char client_name[NETWORK_CLIENT_NAME_LENGTH]; // Name of the client
+ byte client_lang; // The language of the client
+ byte client_playas; // As which player is this client playing (PlayerID)
+ uint32 client_ip; // IP-address of the client (so he can be banned)
+ Date join_date; // Gamedate the player has joined
+ char unique_id[NETWORK_NAME_LENGTH]; // Every play sends an unique id so we can indentify him
+} NetworkClientInfo;
+
+typedef struct NetworkGameList {
+ NetworkGameInfo info;
+ uint32 ip;
+ uint16 port;
+ bool online; // False if the server did not respond (default status)
+ bool manually; // True if the server was added manually
+ struct NetworkGameList *next;
+} NetworkGameList;
+
+typedef enum {
+ NETWORK_JOIN_STATUS_CONNECTING,
+ NETWORK_JOIN_STATUS_AUTHORIZING,
+ NETWORK_JOIN_STATUS_WAITING,
+ NETWORK_JOIN_STATUS_DOWNLOADING,
+ NETWORK_JOIN_STATUS_PROCESSING,
+ NETWORK_JOIN_STATUS_REGISTERING,
+
+ NETWORK_JOIN_STATUS_GETTING_COMPANY_INFO,
+} NetworkJoinStatus;
+
+// language ids for server_lang and client_lang
+typedef enum {
+ NETLANG_ANY = 0,
+ NETLANG_ENGLISH = 1,
+ NETLANG_GERMAN = 2,
+ NETLANG_FRENCH = 3,
+} NetworkLanguage;
+
+VARDEF NetworkGameList *_network_game_list;
+
+VARDEF NetworkGameInfo _network_game_info;
+VARDEF NetworkPlayerInfo _network_player_info[MAX_PLAYERS];
+VARDEF NetworkClientInfo _network_client_info[MAX_CLIENT_INFO];
+
+VARDEF char _network_player_name[NETWORK_CLIENT_NAME_LENGTH];
+VARDEF char _network_default_ip[NETWORK_HOSTNAME_LENGTH];
+
+VARDEF uint16 _network_own_client_index;
+VARDEF char _network_unique_id[NETWORK_NAME_LENGTH]; // Our own unique ID
+
+VARDEF uint32 _frame_counter_server; // The frame_counter of the server, if in network-mode
+VARDEF uint32 _frame_counter_max; // To where we may go with our clients
+
+VARDEF uint32 _last_sync_frame; // Used in the server to store the last time a sync packet was sent to clients.
+
+// networking settings
+VARDEF uint32 _broadcast_list[MAX_INTERFACES + 1];
+
+VARDEF uint16 _network_server_port;
+/* We use bind_ip and bind_ip_host, where bind_ip_host is the readable form of
+ bind_ip_host, and bind_ip the numeric value, because we want a nice number
+ in the openttd.cfg, but we wants to use the uint32 internally.. */
+VARDEF uint32 _network_server_bind_ip;
+VARDEF char _network_server_bind_ip_host[NETWORK_HOSTNAME_LENGTH];
+VARDEF bool _is_network_server; // Does this client wants to be a network-server?
+VARDEF char _network_server_name[NETWORK_NAME_LENGTH];
+VARDEF char _network_server_password[NETWORK_PASSWORD_LENGTH];
+VARDEF char _network_rcon_password[NETWORK_PASSWORD_LENGTH];
+
+VARDEF uint16 _network_max_join_time; ///< Time a client can max take to join
+VARDEF bool _network_pause_on_join; ///< Pause the game when a client tries to join (more chance of succeeding join)
+
+VARDEF uint16 _redirect_console_to_client;
+
+VARDEF uint16 _network_sync_freq;
+VARDEF uint8 _network_frame_freq;
+
+VARDEF uint32 _sync_seed_1, _sync_seed_2;
+VARDEF uint32 _sync_frame;
+VARDEF bool _network_first_time;
+// Vars needed for the join-GUI
+VARDEF NetworkJoinStatus _network_join_status;
+VARDEF uint8 _network_join_waiting;
+VARDEF uint16 _network_join_kbytes;
+VARDEF uint16 _network_join_kbytes_total;
+
+VARDEF char _network_last_host[NETWORK_HOSTNAME_LENGTH];
+VARDEF short _network_last_port;
+VARDEF uint32 _network_last_host_ip;
+VARDEF uint8 _network_reconnect;
+
+VARDEF bool _network_udp_server;
+VARDEF uint16 _network_udp_broadcast;
+
+VARDEF byte _network_lan_internet;
+
+VARDEF bool _network_need_advertise;
+VARDEF uint32 _network_last_advertise_frame;
+VARDEF uint8 _network_advertise_retries;
+
+VARDEF bool _network_autoclean_companies;
+VARDEF uint8 _network_autoclean_unprotected; // Remove a company after X months
+VARDEF uint8 _network_autoclean_protected; // Unprotect a company after X months
+
+VARDEF Year _network_restart_game_year; // If this year is reached, the server automaticly restarts
+VARDEF uint8 _network_min_players; // Minimum number of players for game to unpause
+
+NetworkGameList *NetworkQueryServer(const char* host, unsigned short port, bool game_info);
+
+byte NetworkSpectatorCount(void);
+
+VARDEF char *_network_host_list[10];
+VARDEF char *_network_ban_list[25];
+
+void ParseConnectionString(const char **player, const char **port, char *connection_string);
+void NetworkUpdateClientInfo(uint16 client_index);
+void NetworkAddServer(const char *b);
+void NetworkRebuildHostList(void);
+bool NetworkChangeCompanyPassword(byte argc, char *argv[]);
+void NetworkPopulateCompanyInfo(void);
+void UpdateNetworkGameWindow(bool unselect);
+void CheckMinPlayers(void);
+
+void NetworkStartUp(void);
+void NetworkUDPClose(void);
+void NetworkShutDown(void);
+void NetworkGameLoop(void);
+void NetworkUDPGameLoop(void);
+bool NetworkServerStart(void);
+bool NetworkClientConnectGame(const char *host, uint16 port);
+void NetworkReboot(void);
+void NetworkDisconnect(void);
+
+VARDEF bool _networking; ///< are we in networking mode?
+VARDEF bool _network_server; ///< network-server is active
+VARDEF bool _network_available; ///< is network mode available?
+
+#else /* ENABLE_NETWORK */
+/* Network function stubs when networking is disabled */
+
+static inline void NetworkStartUp(void) {}
+static inline void NetworkShutDown(void) {}
+
+#define _networking 0
+#define _network_server 0
+#define _network_available 0
+
+#endif /* ENABLE_NETWORK */
+
+/* These variables must always be registered! */
+VARDEF bool _network_dedicated; ///< are we a dedicated server?
+VARDEF bool _network_advertise; ///< is the server advertising to the master server?
+VARDEF PlayerID _network_playas; ///< an id to play as.. (see players.h:Players)
+
+#endif /* NETWORK_H */
diff --git a/src/network/network_client.c b/src/network/network_client.c
new file mode 100644
index 000000000..6e27eec56
--- /dev/null
+++ b/src/network/network_client.c
@@ -0,0 +1,819 @@
+/* $Id$ */
+
+#ifdef ENABLE_NETWORK
+
+#include "../stdafx.h"
+#include "../debug.h"
+#include "../string.h"
+#include "../strings.h"
+#include "network_data.h"
+#include "core/tcp.h"
+#include "../date.h"
+#include "table/strings.h"
+#include "../functions.h"
+#include "network_client.h"
+#include "network_gamelist.h"
+#include "network_gui.h"
+#include "../saveload.h"
+#include "../command.h"
+#include "../window.h"
+#include "../console.h"
+#include "../variables.h"
+#include "../ai/ai.h"
+
+
+// This file handles all the client-commands
+
+
+// So we don't make too much typos ;)
+#define MY_CLIENT DEREF_CLIENT(0)
+
+static uint32 last_ack_frame;
+
+// **********
+// Sending functions
+// DEF_CLIENT_SEND_COMMAND has no parameters
+// **********
+
+DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_COMPANY_INFO)
+{
+ //
+ // Packet: CLIENT_COMPANY_INFO
+ // Function: Request company-info (in detail)
+ // Data:
+ // <none>
+ //
+ Packet *p;
+ _network_join_status = NETWORK_JOIN_STATUS_GETTING_COMPANY_INFO;
+ InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
+
+ p = NetworkSend_Init(PACKET_CLIENT_COMPANY_INFO);
+ NetworkSend_Packet(p, MY_CLIENT);
+}
+
+DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_JOIN)
+{
+ //
+ // Packet: CLIENT_JOIN
+ // Function: Try to join the server
+ // Data:
+ // String: OpenTTD Revision (norev000 if no revision)
+ // String: Player Name (max NETWORK_NAME_LENGTH)
+ // uint8: Play as Player id (1..MAX_PLAYERS)
+ // uint8: Language ID
+ // String: Unique id to find the player back in server-listing
+ //
+
+ extern const char _openttd_revision[];
+ Packet *p;
+ _network_join_status = NETWORK_JOIN_STATUS_AUTHORIZING;
+ InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
+
+ p = NetworkSend_Init(PACKET_CLIENT_JOIN);
+ NetworkSend_string(p, _openttd_revision);
+ NetworkSend_string(p, _network_player_name); // Player name
+ NetworkSend_uint8(p, _network_playas); // PlayAs
+ NetworkSend_uint8(p, NETLANG_ANY); // Language
+ NetworkSend_string(p, _network_unique_id);
+ NetworkSend_Packet(p, MY_CLIENT);
+}
+
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_PASSWORD)(NetworkPasswordType type, const char *password)
+{
+ //
+ // Packet: CLIENT_PASSWORD
+ // Function: Send a password to the server to authorize
+ // Data:
+ // uint8: NetworkPasswordType
+ // String: Password
+ //
+ Packet *p = NetworkSend_Init(PACKET_CLIENT_PASSWORD);
+ NetworkSend_uint8(p, type);
+ NetworkSend_string(p, password);
+ NetworkSend_Packet(p, MY_CLIENT);
+}
+
+DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_GETMAP)
+{
+ //
+ // Packet: CLIENT_GETMAP
+ // Function: Request the map from the server
+ // Data:
+ // <none>
+ //
+
+ Packet *p = NetworkSend_Init(PACKET_CLIENT_GETMAP);
+ NetworkSend_Packet(p, MY_CLIENT);
+}
+
+DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_MAP_OK)
+{
+ //
+ // Packet: CLIENT_MAP_OK
+ // Function: Tell the server that we are done receiving/loading the map
+ // Data:
+ // <none>
+ //
+
+ Packet *p = NetworkSend_Init(PACKET_CLIENT_MAP_OK);
+ NetworkSend_Packet(p, MY_CLIENT);
+}
+
+DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_ACK)
+{
+ //
+ // Packet: CLIENT_ACK
+ // Function: Tell the server we are done with this frame
+ // Data:
+ // uint32: current FrameCounter of the client
+ //
+
+ Packet *p = NetworkSend_Init(PACKET_CLIENT_ACK);
+
+ NetworkSend_uint32(p, _frame_counter);
+ NetworkSend_Packet(p, MY_CLIENT);
+}
+
+// Send a command packet to the server
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_COMMAND)(CommandPacket *cp)
+{
+ //
+ // Packet: CLIENT_COMMAND
+ // Function: Send a DoCommand to the Server
+ // Data:
+ // uint8: PlayerID (0..MAX_PLAYERS-1)
+ // uint32: CommandID (see command.h)
+ // uint32: P1 (free variables used in DoCommand)
+ // uint32: P2
+ // uint32: Tile
+ // string: text
+ // uint8: CallBackID (see callback_table.c)
+ //
+
+ Packet *p = NetworkSend_Init(PACKET_CLIENT_COMMAND);
+
+ NetworkSend_uint8(p, cp->player);
+ NetworkSend_uint32(p, cp->cmd);
+ NetworkSend_uint32(p, cp->p1);
+ NetworkSend_uint32(p, cp->p2);
+ NetworkSend_uint32(p, (uint32)cp->tile);
+ NetworkSend_string(p, cp->text);
+ NetworkSend_uint8(p, cp->callback);
+
+ NetworkSend_Packet(p, MY_CLIENT);
+}
+
+// Send a chat-packet over the network
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_CHAT)(NetworkAction action, DestType type, int dest, const char *msg)
+{
+ //
+ // Packet: CLIENT_CHAT
+ // Function: Send a chat-packet to the serve
+ // Data:
+ // uint8: ActionID (see network_data.h, NetworkAction)
+ // uint8: Destination Type (see network_data.h, DestType);
+ // uint8: Destination Player (1..MAX_PLAYERS)
+ // String: Message (max MAX_TEXT_MSG_LEN)
+ //
+
+ Packet *p = NetworkSend_Init(PACKET_CLIENT_CHAT);
+
+ NetworkSend_uint8(p, action);
+ NetworkSend_uint8(p, type);
+ NetworkSend_uint8(p, dest);
+ NetworkSend_string(p, msg);
+ NetworkSend_Packet(p, MY_CLIENT);
+}
+
+// Send an error-packet over the network
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_ERROR)(NetworkErrorCode errorno)
+{
+ //
+ // Packet: CLIENT_ERROR
+ // Function: The client made an error and is quiting the game
+ // Data:
+ // uint8: ErrorID (see network_data.h, NetworkErrorCode)
+ //
+ Packet *p = NetworkSend_Init(PACKET_CLIENT_ERROR);
+
+ NetworkSend_uint8(p, errorno);
+ NetworkSend_Packet(p, MY_CLIENT);
+}
+
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_SET_PASSWORD)(const char *password)
+{
+ //
+ // Packet: PACKET_CLIENT_SET_PASSWORD
+ // Function: Set the password for the clients current company
+ // Data:
+ // String: Password
+ //
+ Packet *p = NetworkSend_Init(PACKET_CLIENT_SET_PASSWORD);
+
+ NetworkSend_string(p, password);
+ NetworkSend_Packet(p, MY_CLIENT);
+}
+
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_SET_NAME)(const char *name)
+{
+ //
+ // Packet: PACKET_CLIENT_SET_NAME
+ // Function: Gives the player a new name
+ // Data:
+ // String: Name
+ //
+ Packet *p = NetworkSend_Init(PACKET_CLIENT_SET_NAME);
+
+ NetworkSend_string(p, name);
+ NetworkSend_Packet(p, MY_CLIENT);
+}
+
+// Send an quit-packet over the network
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_QUIT)(const char *leavemsg)
+{
+ //
+ // Packet: CLIENT_QUIT
+ // Function: The client is quiting the game
+ // Data:
+ // String: leave-message
+ //
+ Packet *p = NetworkSend_Init(PACKET_CLIENT_QUIT);
+
+ NetworkSend_string(p, leavemsg);
+ NetworkSend_Packet(p, MY_CLIENT);
+}
+
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_RCON)(const char *pass, const char *command)
+{
+ Packet *p = NetworkSend_Init(PACKET_CLIENT_RCON);
+ NetworkSend_string(p, pass);
+ NetworkSend_string(p, command);
+ NetworkSend_Packet(p, MY_CLIENT);
+}
+
+
+// **********
+// Receiving functions
+// DEF_CLIENT_RECEIVE_COMMAND has parameter: Packet *p
+// **********
+
+extern bool SafeSaveOrLoad(const char *filename, int mode, int newgm);
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_FULL)
+{
+ // We try to join a server which is full
+ _switch_mode_errorstr = STR_NETWORK_ERR_SERVER_FULL;
+ DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
+
+ return NETWORK_RECV_STATUS_SERVER_FULL;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_BANNED)
+{
+ // We try to join a server where we are banned
+ _switch_mode_errorstr = STR_NETWORK_ERR_SERVER_BANNED;
+ DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
+
+ return NETWORK_RECV_STATUS_SERVER_BANNED;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_COMPANY_INFO)
+{
+ byte company_info_version;
+ int i;
+
+ company_info_version = NetworkRecv_uint8(MY_CLIENT, p);
+
+ if (!MY_CLIENT->has_quit && company_info_version == NETWORK_COMPANY_INFO_VERSION) {
+ byte total;
+ byte current;
+
+ total = NetworkRecv_uint8(MY_CLIENT, p);
+
+ // There is no data at all..
+ if (total == 0) return NETWORK_RECV_STATUS_CLOSE_QUERY;
+
+ current = NetworkRecv_uint8(MY_CLIENT, p);
+ if (!IsValidPlayer(current)) return NETWORK_RECV_STATUS_CLOSE_QUERY;
+
+ NetworkRecv_string(MY_CLIENT, p, _network_player_info[current].company_name, sizeof(_network_player_info[current].company_name));
+ _network_player_info[current].inaugurated_year = NetworkRecv_uint32(MY_CLIENT, p);
+ _network_player_info[current].company_value = NetworkRecv_uint64(MY_CLIENT, p);
+ _network_player_info[current].money = NetworkRecv_uint64(MY_CLIENT, p);
+ _network_player_info[current].income = NetworkRecv_uint64(MY_CLIENT, p);
+ _network_player_info[current].performance = NetworkRecv_uint16(MY_CLIENT, p);
+ _network_player_info[current].use_password = NetworkRecv_uint8(MY_CLIENT, p);
+ for (i = 0; i < NETWORK_VEHICLE_TYPES; i++)
+ _network_player_info[current].num_vehicle[i] = NetworkRecv_uint16(MY_CLIENT, p);
+ for (i = 0; i < NETWORK_STATION_TYPES; i++)
+ _network_player_info[current].num_station[i] = NetworkRecv_uint16(MY_CLIENT, p);
+
+ NetworkRecv_string(MY_CLIENT, p, _network_player_info[current].players, sizeof(_network_player_info[current].players));
+
+ InvalidateWindow(WC_NETWORK_WINDOW, 0);
+
+ return NETWORK_RECV_STATUS_OKAY;
+ }
+
+ return NETWORK_RECV_STATUS_CLOSE_QUERY;
+}
+
+// This packet contains info about the client (playas and name)
+// as client we save this in NetworkClientInfo, linked via 'index'
+// which is always an unique number on a server.
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_CLIENT_INFO)
+{
+ NetworkClientInfo *ci;
+ uint16 index = NetworkRecv_uint16(MY_CLIENT, p);
+ PlayerID playas = NetworkRecv_uint8(MY_CLIENT, p);
+ char name[NETWORK_NAME_LENGTH];
+ char unique_id[NETWORK_NAME_LENGTH];
+
+ NetworkRecv_string(MY_CLIENT, p, name, sizeof(name));
+ NetworkRecv_string(MY_CLIENT, p, unique_id, sizeof(unique_id));
+
+ if (MY_CLIENT->has_quit) return NETWORK_RECV_STATUS_CONN_LOST;
+
+ /* Do we receive a change of data? Most likely we changed playas */
+ if (index == _network_own_client_index) _network_playas = playas;
+
+ ci = NetworkFindClientInfoFromIndex(index);
+ if (ci != NULL) {
+ if (playas == ci->client_playas && strcmp(name, ci->client_name) != 0) {
+ // Client name changed, display the change
+ NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, 1, false, ci->client_name, "%s", name);
+ } else if (playas != ci->client_playas) {
+ // The player changed from client-player..
+ // Do not display that for now
+ }
+
+ ci->client_playas = playas;
+ ttd_strlcpy(ci->client_name, name, sizeof(ci->client_name));
+
+ InvalidateWindow(WC_CLIENT_LIST, 0);
+
+ return NETWORK_RECV_STATUS_OKAY;
+ }
+
+ // We don't have this index yet, find an empty index, and put the data there
+ ci = NetworkFindClientInfoFromIndex(NETWORK_EMPTY_INDEX);
+ if (ci != NULL) {
+ ci->client_index = index;
+ ci->client_playas = playas;
+
+ ttd_strlcpy(ci->client_name, name, sizeof(ci->client_name));
+ ttd_strlcpy(ci->unique_id, unique_id, sizeof(ci->unique_id));
+
+ InvalidateWindow(WC_CLIENT_LIST, 0);
+
+ return NETWORK_RECV_STATUS_OKAY;
+ }
+
+ // Here the program should never ever come.....
+ return NETWORK_RECV_STATUS_MALFORMED_PACKET;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_ERROR)
+{
+ NetworkErrorCode error = NetworkRecv_uint8(MY_CLIENT, p);
+
+ switch (error) {
+ /* We made an error in the protocol, and our connection is closed.... */
+ case NETWORK_ERROR_NOT_AUTHORIZED:
+ case NETWORK_ERROR_NOT_EXPECTED:
+ case NETWORK_ERROR_PLAYER_MISMATCH:
+ _switch_mode_errorstr = STR_NETWORK_ERR_SERVER_ERROR;
+ break;
+ case NETWORK_ERROR_FULL:
+ _switch_mode_errorstr = STR_NETWORK_ERR_SERVER_FULL;
+ break;
+ case NETWORK_ERROR_WRONG_REVISION:
+ _switch_mode_errorstr = STR_NETWORK_ERR_WRONG_REVISION;
+ break;
+ case NETWORK_ERROR_WRONG_PASSWORD:
+ _switch_mode_errorstr = STR_NETWORK_ERR_WRONG_PASSWORD;
+ break;
+ case NETWORK_ERROR_KICKED:
+ _switch_mode_errorstr = STR_NETWORK_ERR_KICKED;
+ break;
+ case NETWORK_ERROR_CHEATER:
+ _switch_mode_errorstr = STR_NETWORK_ERR_CHEATER;
+ break;
+ default:
+ _switch_mode_errorstr = STR_NETWORK_ERR_LOSTCONNECTION;
+ }
+
+ DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
+
+ return NETWORK_RECV_STATUS_SERVER_ERROR;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_NEED_PASSWORD)
+{
+ NetworkPasswordType type = NetworkRecv_uint8(MY_CLIENT, p);
+
+ switch (type) {
+ case NETWORK_GAME_PASSWORD:
+ case NETWORK_COMPANY_PASSWORD:
+ ShowNetworkNeedPassword(type);
+ return NETWORK_RECV_STATUS_OKAY;
+
+ default: return NETWORK_RECV_STATUS_MALFORMED_PACKET;
+ }
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_WELCOME)
+{
+ _network_own_client_index = NetworkRecv_uint16(MY_CLIENT, p);
+
+ // Start receiving the map
+ SEND_COMMAND(PACKET_CLIENT_GETMAP)();
+ return NETWORK_RECV_STATUS_OKAY;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_WAIT)
+{
+ _network_join_status = NETWORK_JOIN_STATUS_WAITING;
+ _network_join_waiting = NetworkRecv_uint8(MY_CLIENT, p);
+ InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
+
+ // We are put on hold for receiving the map.. we need GUI for this ;)
+ DEBUG(net, 1, "The server is currently busy sending the map to someone else, please wait..." );
+ DEBUG(net, 1, "There are %d clients in front of you", _network_join_waiting);
+
+ return NETWORK_RECV_STATUS_OKAY;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_MAP)
+{
+ static char filename[256];
+ static FILE *file_pointer;
+
+ byte maptype;
+
+ maptype = NetworkRecv_uint8(MY_CLIENT, p);
+
+ if (MY_CLIENT->has_quit) return NETWORK_RECV_STATUS_CONN_LOST;
+
+ // First packet, init some stuff
+ if (maptype == MAP_PACKET_START) {
+ // The name for the temp-map
+ snprintf(filename, lengthof(filename), "%s%snetwork_client.tmp", _paths.autosave_dir, PATHSEP);
+
+ file_pointer = fopen(filename, "wb");
+ if (file_pointer == NULL) {
+ _switch_mode_errorstr = STR_NETWORK_ERR_SAVEGAMEERROR;
+ return NETWORK_RECV_STATUS_SAVEGAME;
+ }
+
+ _frame_counter = _frame_counter_server = _frame_counter_max = NetworkRecv_uint32(MY_CLIENT, p);
+
+ _network_join_status = NETWORK_JOIN_STATUS_DOWNLOADING;
+ _network_join_kbytes = 0;
+ _network_join_kbytes_total = NetworkRecv_uint32(MY_CLIENT, p) / 1024;
+ InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
+
+ // The first packet does not contain any more data
+ return NETWORK_RECV_STATUS_OKAY;
+ }
+
+ if (maptype == MAP_PACKET_NORMAL) {
+ // We are still receiving data, put it to the file
+ fwrite(p->buffer + p->pos, 1, p->size - p->pos, file_pointer);
+
+ _network_join_kbytes = ftell(file_pointer) / 1024;
+ InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
+ }
+
+ // Check if this was the last packet
+ if (maptype == MAP_PACKET_END) {
+ fclose(file_pointer);
+
+ _network_join_status = NETWORK_JOIN_STATUS_PROCESSING;
+ InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
+
+ /* The map is done downloading, load it */
+ if (!SafeSaveOrLoad(filename, SL_LOAD, GM_NORMAL)) {
+ DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
+ _switch_mode_errorstr = STR_NETWORK_ERR_SAVEGAMEERROR;
+ return NETWORK_RECV_STATUS_SAVEGAME;
+ }
+ /* If the savegame has successfully loaded, ALL windows have been removed,
+ * only toolbar/statusbar and gamefield are visible */
+
+ _opt_ptr = &_opt; // during a network game you are always in-game
+
+ // Say we received the map and loaded it correctly!
+ SEND_COMMAND(PACKET_CLIENT_MAP_OK)();
+
+ /* New company/spectator (invalid player) or company we want to join is not active
+ * Switch local player to spectator and await the server's judgement */
+ if (_network_playas == PLAYER_NEW_COMPANY || !IsValidPlayer(_network_playas) ||
+ !GetPlayer(_network_playas)->is_active) {
+
+ SetLocalPlayer(PLAYER_SPECTATOR);
+
+ if (_network_playas != PLAYER_SPECTATOR) {
+ /* We have arrived and ready to start playing; send a command to make a new player;
+ * the server will give us a client-id and let us in */
+ _network_join_status = NETWORK_JOIN_STATUS_REGISTERING;
+ ShowJoinStatusWindow();
+ NetworkSend_Command(0, 0, 0, CMD_PLAYER_CTRL, NULL);
+ }
+ } else {
+ // take control over an existing company
+ SetLocalPlayer(_network_playas);
+ }
+ }
+
+ return NETWORK_RECV_STATUS_OKAY;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_FRAME)
+{
+ _frame_counter_server = NetworkRecv_uint32(MY_CLIENT, p);
+ _frame_counter_max = NetworkRecv_uint32(MY_CLIENT, p);
+#ifdef ENABLE_NETWORK_SYNC_EVERY_FRAME
+ // Test if the server supports this option
+ // and if we are at the frame the server is
+ if (p->pos < p->size) {
+ _sync_frame = _frame_counter_server;
+ _sync_seed_1 = NetworkRecv_uint32(MY_CLIENT, p);
+#ifdef NETWORK_SEND_DOUBLE_SEED
+ _sync_seed_2 = NetworkRecv_uint32(MY_CLIENT, p);
+#endif
+ }
+#endif
+ DEBUG(net, 5, "Received FRAME %d", _frame_counter_server);
+
+ // Let the server know that we received this frame correctly
+ // We do this only once per day, to save some bandwidth ;)
+ if (!_network_first_time && last_ack_frame < _frame_counter) {
+ last_ack_frame = _frame_counter + DAY_TICKS;
+ DEBUG(net, 4, "Sent ACK at %d", _frame_counter);
+ SEND_COMMAND(PACKET_CLIENT_ACK)();
+ }
+
+ return NETWORK_RECV_STATUS_OKAY;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_SYNC)
+{
+ _sync_frame = NetworkRecv_uint32(MY_CLIENT, p);
+ _sync_seed_1 = NetworkRecv_uint32(MY_CLIENT, p);
+#ifdef NETWORK_SEND_DOUBLE_SEED
+ _sync_seed_2 = NetworkRecv_uint32(MY_CLIENT, p);
+#endif
+
+ return NETWORK_RECV_STATUS_OKAY;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_COMMAND)
+{
+ CommandPacket *cp = malloc(sizeof(CommandPacket));
+ cp->player = NetworkRecv_uint8(MY_CLIENT, p);
+ cp->cmd = NetworkRecv_uint32(MY_CLIENT, p);
+ cp->p1 = NetworkRecv_uint32(MY_CLIENT, p);
+ cp->p2 = NetworkRecv_uint32(MY_CLIENT, p);
+ cp->tile = NetworkRecv_uint32(MY_CLIENT, p);
+ NetworkRecv_string(MY_CLIENT, p, cp->text, sizeof(cp->text));
+ cp->callback = NetworkRecv_uint8(MY_CLIENT, p);
+ cp->frame = NetworkRecv_uint32(MY_CLIENT, p);
+ cp->next = NULL;
+
+ // The server did send us this command..
+ // queue it in our own queue, so we can handle it in the upcoming frame!
+
+ if (_local_command_queue == NULL) {
+ _local_command_queue = cp;
+ } else {
+ // Find last packet
+ CommandPacket *c = _local_command_queue;
+ while (c->next != NULL) c = c->next;
+ c->next = cp;
+ }
+
+ return NETWORK_RECV_STATUS_OKAY;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_CHAT)
+{
+ char name[NETWORK_NAME_LENGTH], msg[MAX_TEXT_MSG_LEN];
+ const NetworkClientInfo *ci = NULL, *ci_to;
+
+ NetworkAction action = NetworkRecv_uint8(MY_CLIENT, p);
+ uint16 index = NetworkRecv_uint16(MY_CLIENT, p);
+ bool self_send = NetworkRecv_uint8(MY_CLIENT, p);
+ NetworkRecv_string(MY_CLIENT, p, msg, MAX_TEXT_MSG_LEN);
+
+ ci_to = NetworkFindClientInfoFromIndex(index);
+ if (ci_to == NULL) return NETWORK_RECV_STATUS_OKAY;
+
+ /* Did we initiate the action locally? */
+ if (self_send) {
+ switch (action) {
+ case NETWORK_ACTION_CHAT_CLIENT:
+ /* For speaking to client we need the client-name */
+ snprintf(name, sizeof(name), "%s", ci_to->client_name);
+ ci = NetworkFindClientInfoFromIndex(_network_own_client_index);
+ break;
+
+ /* For speaking to company or giving money, we need the player-name */
+ case NETWORK_ACTION_GIVE_MONEY:
+ if (!IsValidPlayer(ci_to->client_playas)) return NETWORK_RECV_STATUS_OKAY;
+ /* fallthrough */
+ case NETWORK_ACTION_CHAT_COMPANY: {
+ StringID str = IsValidPlayer(ci_to->client_playas) ? GetPlayer(ci_to->client_playas)->name_1 : STR_NETWORK_SPECTATORS;
+
+ GetString(name, str, lastof(name));
+ ci = NetworkFindClientInfoFromIndex(_network_own_client_index);
+ } break;
+
+ default: NOT_REACHED(); break;
+ }
+ } else {
+ /* Display message from somebody else */
+ snprintf(name, sizeof(name), "%s", ci_to->client_name);
+ ci = ci_to;
+ }
+
+ if (ci != NULL)
+ NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas), self_send, name, "%s", msg);
+ return NETWORK_RECV_STATUS_OKAY;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_ERROR_QUIT)
+{
+ char str[100];
+ uint16 index;
+ NetworkClientInfo *ci;
+
+ index = NetworkRecv_uint16(MY_CLIENT, p);
+ GetNetworkErrorMsg(str, NetworkRecv_uint8(MY_CLIENT, p), lastof(str));
+
+ ci = NetworkFindClientInfoFromIndex(index);
+ if (ci != NULL) {
+ NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, ci->client_name, "%s", str);
+
+ // The client is gone, give the NetworkClientInfo free
+ ci->client_index = NETWORK_EMPTY_INDEX;
+ }
+
+ InvalidateWindow(WC_CLIENT_LIST, 0);
+
+ return NETWORK_RECV_STATUS_OKAY;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_QUIT)
+{
+ char str[100];
+ uint16 index;
+ NetworkClientInfo *ci;
+
+ index = NetworkRecv_uint16(MY_CLIENT, p);
+ NetworkRecv_string(MY_CLIENT, p, str, lengthof(str));
+
+ ci = NetworkFindClientInfoFromIndex(index);
+ if (ci != NULL) {
+ NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, ci->client_name, "%s", str);
+
+ // The client is gone, give the NetworkClientInfo free
+ ci->client_index = NETWORK_EMPTY_INDEX;
+ } else {
+ DEBUG(net, 0, "Unknown client (%d) is leaving the game", index);
+ }
+
+ InvalidateWindow(WC_CLIENT_LIST, 0);
+
+ // If we come here it means we could not locate the client.. strange :s
+ return NETWORK_RECV_STATUS_OKAY;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_JOIN)
+{
+ uint16 index;
+ NetworkClientInfo *ci;
+
+ index = NetworkRecv_uint16(MY_CLIENT, p);
+
+ ci = NetworkFindClientInfoFromIndex(index);
+ if (ci != NULL)
+ NetworkTextMessage(NETWORK_ACTION_JOIN, 1, false, ci->client_name, "");
+
+ InvalidateWindow(WC_CLIENT_LIST, 0);
+
+ return NETWORK_RECV_STATUS_OKAY;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_SHUTDOWN)
+{
+ _switch_mode_errorstr = STR_NETWORK_SERVER_SHUTDOWN;
+
+ return NETWORK_RECV_STATUS_SERVER_ERROR;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_NEWGAME)
+{
+ // To trottle the reconnects a bit, every clients waits
+ // his _local_player value before reconnecting
+ // PLAYER_SPECTATOR is currently 255, so to avoid long wait periods
+ // set the max to 10.
+ _network_reconnect = min(_local_player + 1, 10);
+ _switch_mode_errorstr = STR_NETWORK_SERVER_REBOOT;
+
+ return NETWORK_RECV_STATUS_SERVER_ERROR;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_RCON)
+{
+ char rcon_out[NETWORK_RCONCOMMAND_LENGTH];
+ uint16 color_code;
+
+ color_code = NetworkRecv_uint16(MY_CLIENT, p);
+ NetworkRecv_string(MY_CLIENT, p, rcon_out, sizeof(rcon_out));
+
+ IConsolePrint(color_code, rcon_out);
+
+ return NETWORK_RECV_STATUS_OKAY;
+}
+
+
+
+// The layout for the receive-functions by the client
+typedef NetworkRecvStatus NetworkClientPacket(Packet *p);
+
+// This array matches PacketType. At an incoming
+// packet it is matches against this array
+// and that way the right function to handle that
+// packet is found.
+static NetworkClientPacket* const _network_client_packet[] = {
+ RECEIVE_COMMAND(PACKET_SERVER_FULL),
+ RECEIVE_COMMAND(PACKET_SERVER_BANNED),
+ NULL, /*PACKET_CLIENT_JOIN,*/
+ RECEIVE_COMMAND(PACKET_SERVER_ERROR),
+ NULL, /*PACKET_CLIENT_COMPANY_INFO,*/
+ RECEIVE_COMMAND(PACKET_SERVER_COMPANY_INFO),
+ RECEIVE_COMMAND(PACKET_SERVER_CLIENT_INFO),
+ RECEIVE_COMMAND(PACKET_SERVER_NEED_PASSWORD),
+ NULL, /*PACKET_CLIENT_PASSWORD,*/
+ RECEIVE_COMMAND(PACKET_SERVER_WELCOME),
+ NULL, /*PACKET_CLIENT_GETMAP,*/
+ RECEIVE_COMMAND(PACKET_SERVER_WAIT),
+ RECEIVE_COMMAND(PACKET_SERVER_MAP),
+ NULL, /*PACKET_CLIENT_MAP_OK,*/
+ RECEIVE_COMMAND(PACKET_SERVER_JOIN),
+ RECEIVE_COMMAND(PACKET_SERVER_FRAME),
+ RECEIVE_COMMAND(PACKET_SERVER_SYNC),
+ NULL, /*PACKET_CLIENT_ACK,*/
+ NULL, /*PACKET_CLIENT_COMMAND,*/
+ RECEIVE_COMMAND(PACKET_SERVER_COMMAND),
+ NULL, /*PACKET_CLIENT_CHAT,*/
+ RECEIVE_COMMAND(PACKET_SERVER_CHAT),
+ NULL, /*PACKET_CLIENT_SET_PASSWORD,*/
+ NULL, /*PACKET_CLIENT_SET_NAME,*/
+ NULL, /*PACKET_CLIENT_QUIT,*/
+ NULL, /*PACKET_CLIENT_ERROR,*/
+ RECEIVE_COMMAND(PACKET_SERVER_QUIT),
+ RECEIVE_COMMAND(PACKET_SERVER_ERROR_QUIT),
+ RECEIVE_COMMAND(PACKET_SERVER_SHUTDOWN),
+ RECEIVE_COMMAND(PACKET_SERVER_NEWGAME),
+ RECEIVE_COMMAND(PACKET_SERVER_RCON),
+ NULL, /*PACKET_CLIENT_RCON,*/
+};
+
+// If this fails, check the array above with network_data.h
+assert_compile(lengthof(_network_client_packet) == PACKET_END);
+
+// Is called after a client is connected to the server
+void NetworkClient_Connected(void)
+{
+ // Set the frame-counter to 0 so nothing happens till we are ready
+ _frame_counter = 0;
+ _frame_counter_server = 0;
+ last_ack_frame = 0;
+ // Request the game-info
+ SEND_COMMAND(PACKET_CLIENT_JOIN)();
+}
+
+// Reads the packets from the socket-stream, if available
+NetworkRecvStatus NetworkClient_ReadPackets(NetworkClientState *cs)
+{
+ Packet *p;
+ NetworkRecvStatus res = NETWORK_RECV_STATUS_OKAY;
+
+ while (res == NETWORK_RECV_STATUS_OKAY && (p = NetworkRecv_Packet(cs, &res)) != NULL) {
+ byte type = NetworkRecv_uint8(MY_CLIENT, p);
+ if (type < PACKET_END && _network_client_packet[type] != NULL && !MY_CLIENT->has_quit) {
+ res = _network_client_packet[type](p);
+ } else {
+ res = NETWORK_RECV_STATUS_MALFORMED_PACKET;
+ DEBUG(net, 0, "[client] received invalid packet type %d", type);
+ }
+
+ free(p);
+ }
+
+ return res;
+}
+
+#endif /* ENABLE_NETWORK */
diff --git a/src/network/network_client.h b/src/network/network_client.h
new file mode 100644
index 000000000..2dd776ac1
--- /dev/null
+++ b/src/network/network_client.h
@@ -0,0 +1,25 @@
+/* $Id$ */
+
+#ifndef NETWORK_CLIENT_H
+#define NETWORK_CLIENT_H
+
+#ifdef ENABLE_NETWORK
+
+DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_GAME_INFO);
+DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_COMPANY_INFO);
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_COMMAND)(CommandPacket *cp);
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_ERROR)(NetworkErrorCode errorno);
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_QUIT)(const char *leavemsg);
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_CHAT)(NetworkAction action, DestType desttype, int dest, const char *msg);
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_PASSWORD)(NetworkPasswordType type, const char *password);
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_SET_PASSWORD)(const char *password);
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_SET_NAME)(const char *name);
+DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_ACK);
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_RCON)(const char *pass, const char *command);
+
+NetworkRecvStatus NetworkClient_ReadPackets(NetworkClientState *cs);
+void NetworkClient_Connected(void);
+
+#endif /* ENABLE_NETWORK */
+
+#endif /* NETWORK_CLIENT_H */
diff --git a/src/network/network_data.c b/src/network/network_data.c
new file mode 100644
index 000000000..9e5e6424d
--- /dev/null
+++ b/src/network/network_data.c
@@ -0,0 +1,106 @@
+/* $Id$ */
+
+#ifdef ENABLE_NETWORK
+
+#include "../stdafx.h"
+#include "../debug.h"
+#include "network_data.h"
+#include "../string.h"
+#include "network_client.h"
+#include "../command.h"
+#include "../callback_table.h"
+
+// Add a command to the local command queue
+void NetworkAddCommandQueue(NetworkClientState *cs, CommandPacket *cp)
+{
+ CommandPacket* new_cp = malloc(sizeof(*new_cp));
+
+ *new_cp = *cp;
+
+ if (cs->command_queue == NULL) {
+ cs->command_queue = new_cp;
+ } else {
+ CommandPacket *c = cs->command_queue;
+ while (c->next != NULL) c = c->next;
+ c->next = new_cp;
+ }
+}
+
+// Prepare a DoCommand to be send over the network
+void NetworkSend_Command(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback)
+{
+ CommandPacket *c = malloc(sizeof(CommandPacket));
+ byte temp_callback;
+
+ c->player = _local_player;
+ c->next = NULL;
+ c->tile = tile;
+ c->p1 = p1;
+ c->p2 = p2;
+ c->cmd = cmd;
+ c->callback = 0;
+
+ temp_callback = 0;
+
+ while (temp_callback < _callback_table_count && _callback_table[temp_callback] != callback)
+ temp_callback++;
+ if (temp_callback == _callback_table_count) {
+ DEBUG(net, 0, "Unknown callback. (Pointer: %p) No callback sent", callback);
+ temp_callback = 0; /* _callback_table[0] == NULL */
+ }
+
+ if (_network_server) {
+ // We are the server, so set the command to be executed next possible frame
+ c->frame = _frame_counter_max + 1;
+ } else {
+ c->frame = 0; // The client can't tell which frame, so just make it 0
+ }
+
+ ttd_strlcpy(c->text, (_cmd_text != NULL) ? _cmd_text : "", lengthof(c->text));
+
+ if (_network_server) {
+ // If we are the server, we queue the command in our 'special' queue.
+ // In theory, we could execute the command right away, but then the
+ // client on the server can do everything 1 tick faster than others.
+ // So to keep the game fair, we delay the command with 1 tick
+ // which gives about the same speed as most clients.
+ NetworkClientState *cs;
+
+ // And we queue it for delivery to the clients
+ FOR_ALL_CLIENTS(cs) {
+ if (cs->status > STATUS_AUTH) NetworkAddCommandQueue(cs, c);
+ }
+
+ // Only the server gets the callback, because clients should not get them
+ c->callback = temp_callback;
+ if (_local_command_queue == NULL) {
+ _local_command_queue = c;
+ } else {
+ // Find last packet
+ CommandPacket *cp = _local_command_queue;
+ while (cp->next != NULL) cp = cp->next;
+ cp->next = c;
+ }
+
+ return;
+ }
+
+ // Clients send their command to the server and forget all about the packet
+ c->callback = temp_callback;
+ SEND_COMMAND(PACKET_CLIENT_COMMAND)(c);
+}
+
+// Execute a DoCommand we received from the network
+void NetworkExecuteCommand(CommandPacket *cp)
+{
+ _current_player = cp->player;
+ _cmd_text = cp->text;
+ /* cp->callback is unsigned. so we don't need to do lower bounds checking. */
+ if (cp->callback > _callback_table_count) {
+ DEBUG(net, 0, "Received out-of-bounds callback (%d)", cp->callback);
+ cp->callback = 0;
+ }
+ DoCommandP(cp->tile, cp->p1, cp->p2, _callback_table[cp->callback], cp->cmd | CMD_NETWORK_COMMAND);
+}
+
+#endif /* ENABLE_NETWORK */
diff --git a/src/network/network_data.h b/src/network/network_data.h
new file mode 100644
index 000000000..3e42e00cf
--- /dev/null
+++ b/src/network/network_data.h
@@ -0,0 +1,167 @@
+/* $Id$ */
+
+#ifndef NETWORK_DATA_H
+#define NETWORK_DATA_H
+
+// Is the network enabled?
+#ifdef ENABLE_NETWORK
+
+#include "../openttd.h"
+#include "network.h"
+#include "core/os_abstraction.h"
+#include "core/config.h"
+#include "core/packet.h"
+
+#define MAX_TEXT_MSG_LEN 1024 /* long long long long sentences :-) */
+
+// The client-info-server-index is always 1
+#define NETWORK_SERVER_INDEX 1
+#define NETWORK_EMPTY_INDEX 0
+
+typedef struct CommandPacket {
+ struct CommandPacket *next;
+ PlayerID player; /// player that is executing the command
+ uint32 cmd; /// command being executed
+ uint32 p1; /// parameter p1
+ uint32 p2; /// parameter p2
+ TileIndex tile; /// tile command being executed on
+ char text[80];
+ uint32 frame; /// the frame in which this packet is executed
+ byte callback; /// any callback function executed upon successful completion of the command
+} CommandPacket;
+
+typedef enum {
+ STATUS_INACTIVE,
+ STATUS_AUTH, // This means that the client is authorized
+ STATUS_MAP_WAIT, // This means that the client is put on hold because someone else is getting the map
+ STATUS_MAP,
+ STATUS_DONE_MAP,
+ STATUS_PRE_ACTIVE,
+ STATUS_ACTIVE,
+} ClientStatus;
+
+typedef enum {
+ MAP_PACKET_START,
+ MAP_PACKET_NORMAL,
+ MAP_PACKET_END,
+} MapPacket;
+
+typedef enum {
+ NETWORK_RECV_STATUS_OKAY,
+ NETWORK_RECV_STATUS_DESYNC,
+ NETWORK_RECV_STATUS_SAVEGAME,
+ NETWORK_RECV_STATUS_CONN_LOST,
+ NETWORK_RECV_STATUS_MALFORMED_PACKET,
+ NETWORK_RECV_STATUS_SERVER_ERROR, // The server told us we made an error
+ NETWORK_RECV_STATUS_SERVER_FULL,
+ NETWORK_RECV_STATUS_SERVER_BANNED,
+ NETWORK_RECV_STATUS_CLOSE_QUERY, // Done quering the server
+} NetworkRecvStatus;
+
+typedef enum {
+ NETWORK_ERROR_GENERAL, // Try to use thisone like never
+
+ // Signals from clients
+ NETWORK_ERROR_DESYNC,
+ NETWORK_ERROR_SAVEGAME_FAILED,
+ NETWORK_ERROR_CONNECTION_LOST,
+ NETWORK_ERROR_ILLEGAL_PACKET,
+
+ // Signals from servers
+ NETWORK_ERROR_NOT_AUTHORIZED,
+ NETWORK_ERROR_NOT_EXPECTED,
+ NETWORK_ERROR_WRONG_REVISION,
+ NETWORK_ERROR_NAME_IN_USE,
+ NETWORK_ERROR_WRONG_PASSWORD,
+ NETWORK_ERROR_PLAYER_MISMATCH, // Happens in CLIENT_COMMAND
+ NETWORK_ERROR_KICKED,
+ NETWORK_ERROR_CHEATER,
+ NETWORK_ERROR_FULL,
+} NetworkErrorCode;
+
+// Actions that can be used for NetworkTextMessage
+typedef enum {
+ NETWORK_ACTION_JOIN,
+ NETWORK_ACTION_LEAVE,
+ NETWORK_ACTION_SERVER_MESSAGE,
+ NETWORK_ACTION_CHAT,
+ NETWORK_ACTION_CHAT_COMPANY,
+ NETWORK_ACTION_CHAT_CLIENT,
+ NETWORK_ACTION_GIVE_MONEY,
+ NETWORK_ACTION_NAME_CHANGE,
+} NetworkAction;
+
+typedef enum {
+ NETWORK_GAME_PASSWORD,
+ NETWORK_COMPANY_PASSWORD,
+} NetworkPasswordType;
+
+// To keep the clients all together
+struct NetworkClientState { // Typedeffed in network_core/packet.h
+ SOCKET socket;
+ uint16 index;
+ uint32 last_frame;
+ uint32 last_frame_server;
+ byte lag_test; // This byte is used for lag-testing the client
+
+ ClientStatus status;
+ bool writable; // is client ready to write to?
+ bool has_quit;
+
+ Packet *packet_queue; // Packets that are awaiting delivery
+ Packet *packet_recv; // Partially received packet
+
+ CommandPacket *command_queue; // The command-queue awaiting delivery
+};
+
+typedef enum {
+ DESTTYPE_BROADCAST, ///< Send message/notice to all players (All)
+ DESTTYPE_TEAM, ///< Send message/notice to everyone playing the same company (Team)
+ DESTTYPE_CLIENT, ///< Send message/notice to only a certain player (Private)
+} DestType;
+
+CommandPacket *_local_command_queue;
+
+SOCKET _udp_client_socket; // udp client socket
+SOCKET _udp_server_socket; // udp server socket
+SOCKET _udp_master_socket; // udp master socket
+
+// Here we keep track of the clients
+// (and the client uses [0] for his own communication)
+NetworkClientState _clients[MAX_CLIENTS];
+#define DEREF_CLIENT(i) (&_clients[i])
+// This returns the NetworkClientInfo from a NetworkClientState
+#define DEREF_CLIENT_INFO(cs) (&_network_client_info[cs - _clients])
+
+// Macros to make life a bit more easier
+#define DEF_CLIENT_RECEIVE_COMMAND(type) NetworkRecvStatus NetworkPacketReceive_ ## type ## _command(Packet *p)
+#define DEF_CLIENT_SEND_COMMAND(type) void NetworkPacketSend_ ## type ## _command(void)
+#define DEF_CLIENT_SEND_COMMAND_PARAM(type) void NetworkPacketSend_ ## type ## _command
+#define DEF_SERVER_RECEIVE_COMMAND(type) void NetworkPacketReceive_ ## type ## _command(NetworkClientState *cs, Packet *p)
+#define DEF_SERVER_SEND_COMMAND(type) void NetworkPacketSend_ ## type ## _command(NetworkClientState *cs)
+#define DEF_SERVER_SEND_COMMAND_PARAM(type) void NetworkPacketSend_ ## type ## _command
+
+#define SEND_COMMAND(type) NetworkPacketSend_ ## type ## _command
+#define RECEIVE_COMMAND(type) NetworkPacketReceive_ ## type ## _command
+
+#define FOR_ALL_CLIENTS(cs) for (cs = _clients; cs != endof(_clients) && cs->socket != INVALID_SOCKET; cs++)
+#define FOR_ALL_ACTIVE_CLIENT_INFOS(ci) for (ci = _network_client_info; ci != endof(_network_client_info); ci++) if (ci->client_index != NETWORK_EMPTY_INDEX)
+
+void NetworkExecuteCommand(CommandPacket *cp);
+void NetworkAddCommandQueue(NetworkClientState *cs, CommandPacket *cp);
+
+// from network.c
+void NetworkCloseClient(NetworkClientState *cs);
+void CDECL NetworkTextMessage(NetworkAction action, uint16 color, bool self_send, const char *name, const char *str, ...);
+void NetworkGetClientName(char *clientname, size_t size, const NetworkClientState *cs);
+uint NetworkCalculateLag(const NetworkClientState *cs);
+byte NetworkGetCurrentLanguageIndex(void);
+NetworkClientInfo *NetworkFindClientInfoFromIndex(uint16 client_index);
+NetworkClientInfo *NetworkFindClientInfoFromIP(const char *ip);
+NetworkClientState *NetworkFindClientStateFromIndex(uint16 client_index);
+unsigned long NetworkResolveHost(const char *hostname);
+char* GetNetworkErrorMsg(char* buf, NetworkErrorCode err, const char* last);
+
+#endif /* ENABLE_NETWORK */
+
+#endif /* NETWORK_DATA_H */
diff --git a/src/network/network_gamelist.c b/src/network/network_gamelist.c
new file mode 100644
index 000000000..a830073ad
--- /dev/null
+++ b/src/network/network_gamelist.c
@@ -0,0 +1,74 @@
+/* $Id$ */
+
+#ifdef ENABLE_NETWORK
+
+#include "../stdafx.h"
+#include "../debug.h"
+#include "network_data.h"
+#include "../newgrf_config.h"
+
+// This file handles the GameList
+// Also, it handles the request to a server for data about the server
+
+/** Add a new item to the linked gamelist. If the IP and Port match
+ * return the existing item instead of adding it again
+ * @param ip the IP-address (inet_addr) of the to-be added item
+ * @param port the port the server is running on
+ * @return a point to the newly added or already existing item */
+NetworkGameList *NetworkGameListAddItem(uint32 ip, uint16 port)
+{
+ NetworkGameList *item, *prev_item;
+
+ prev_item = NULL;
+ for (item = _network_game_list; item != NULL; item = item->next) {
+ if (item->ip == ip && item->port == port) return item;
+ prev_item = item;
+ }
+
+ item = malloc(sizeof(*item));
+ memset(item, 0, sizeof(*item));
+ item->next = NULL;
+ item->ip = ip;
+ item->port = port;
+
+ if (prev_item == NULL) {
+ _network_game_list = item;
+ } else {
+ prev_item->next = item;
+ }
+ DEBUG(net, 4, "[gamelist] added server to list");
+
+ UpdateNetworkGameWindow(false);
+
+ return item;
+}
+
+/** Remove an item from the gamelist linked list
+ * @param remove pointer to the item to be removed */
+void NetworkGameListRemoveItem(NetworkGameList *remove)
+{
+ NetworkGameList *item, *prev_item;
+
+ prev_item = NULL;
+ for (item = _network_game_list; item != NULL; item = item->next) {
+ if (remove == item) {
+ if (prev_item == NULL) {
+ _network_game_list = remove->next;
+ } else {
+ prev_item->next = remove->next;
+ }
+
+ /* Remove GRFConfig information */
+ ClearGRFConfigList(&remove->info.grfconfig);
+ free(remove);
+ remove = NULL;
+
+ DEBUG(net, 4, "[gamelist] removed server from list");
+ UpdateNetworkGameWindow(false);
+ return;
+ }
+ prev_item = item;
+ }
+}
+
+#endif /* ENABLE_NETWORK */
diff --git a/src/network/network_gamelist.h b/src/network/network_gamelist.h
new file mode 100644
index 000000000..c1a1a0904
--- /dev/null
+++ b/src/network/network_gamelist.h
@@ -0,0 +1,11 @@
+/* $Id$ */
+
+#ifndef NETWORK_GAMELIST_H
+#define NETWORK_GAMELIST_H
+
+void NetworkGameListClear(void);
+NetworkGameList *NetworkGameListAddItem(uint32 ip, uint16 port);
+void NetworkGameListRemoveItem(NetworkGameList *remove);
+void NetworkGameListAddQueriedItem(const NetworkGameInfo *info, bool server_online);
+
+#endif /* NETWORK_GAMELIST_H */
diff --git a/src/network/network_gui.c b/src/network/network_gui.c
new file mode 100644
index 000000000..dd865118e
--- /dev/null
+++ b/src/network/network_gui.c
@@ -0,0 +1,1706 @@
+/* $Id$ */
+
+#ifdef ENABLE_NETWORK
+#include "../stdafx.h"
+#include "../openttd.h"
+#include "../string.h"
+#include "../strings.h"
+#include "../table/sprites.h"
+#include "network.h"
+#include "../date.h"
+
+#include "../fios.h"
+#include "table/strings.h"
+#include "../functions.h"
+#include "network_data.h"
+#include "network_client.h"
+#include "network_gui.h"
+#include "network_gamelist.h"
+#include "../window.h"
+#include "../gui.h"
+#include "../gfx.h"
+#include "../command.h"
+#include "../variables.h"
+#include "network_server.h"
+#include "network_udp.h"
+#include "../settings.h"
+#include "../string.h"
+#include "../town.h"
+#include "../newgrf.h"
+
+#define BGC 5
+#define BTC 15
+
+typedef struct network_d {
+ PlayerID company; // select company in network lobby
+ byte field; // select text-field in start-server and game-listing
+ NetworkGameList *server; // selected server in lobby and game-listing
+ FiosItem *map; // selected map in start-server
+} network_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(network_d));
+
+typedef struct network_ql_d {
+ network_d n; // see above; general stuff
+ querystr_d q; // text-input in start-server and game-listing
+ NetworkGameList **sort_list; // list of games (sorted)
+ list_d l; // accompanying list-administration
+} network_ql_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(network_ql_d));
+
+/* Global to remember sorting after window has been closed */
+static Listing _ng_sorting;
+
+static char _edit_str_buf[150];
+static bool _chat_tab_completion_active;
+
+static void ShowNetworkStartServerWindow(void);
+static void ShowNetworkLobbyWindow(NetworkGameList *ngl);
+extern void SwitchMode(int new_mode);
+
+static const StringID _connection_types_dropdown[] = {
+ STR_NETWORK_LAN_INTERNET,
+ STR_NETWORK_INTERNET_ADVERTISE,
+ INVALID_STRING_ID
+};
+
+static const StringID _lan_internet_types_dropdown[] = {
+ STR_NETWORK_LAN,
+ STR_NETWORK_INTERNET,
+ INVALID_STRING_ID
+};
+
+static const StringID _players_dropdown[] = {
+ STR_NETWORK_0_PLAYERS,
+ STR_NETWORK_1_PLAYERS,
+ STR_NETWORK_2_PLAYERS,
+ STR_NETWORK_3_PLAYERS,
+ STR_NETWORK_4_PLAYERS,
+ STR_NETWORK_5_PLAYERS,
+ STR_NETWORK_6_PLAYERS,
+ STR_NETWORK_7_PLAYERS,
+ STR_NETWORK_8_PLAYERS,
+ STR_NETWORK_9_PLAYERS,
+ STR_NETWORK_10_PLAYERS,
+ INVALID_STRING_ID
+};
+
+static const StringID _language_dropdown[] = {
+ STR_NETWORK_LANG_ANY,
+ STR_NETWORK_LANG_ENGLISH,
+ STR_NETWORK_LANG_GERMAN,
+ STR_NETWORK_LANG_FRENCH,
+ INVALID_STRING_ID
+};
+
+enum {
+ NET_PRC__OFFSET_TOP_WIDGET = 54,
+ NET_PRC__OFFSET_TOP_WIDGET_COMPANY = 52,
+ NET_PRC__SIZE_OF_ROW = 14,
+};
+
+/** Update the network new window because a new server is
+ * found on the network.
+ * @param unselect unselect the currently selected item */
+void UpdateNetworkGameWindow(bool unselect)
+{
+ SendWindowMessage(WC_NETWORK_WINDOW, 0, unselect, 0, 0);
+}
+
+static bool _internal_sort_order; // Used for Qsort order-flipping
+typedef int CDECL NGameNameSortFunction(const void*, const void*);
+
+/** Qsort function to sort by name. */
+static int CDECL NGameNameSorter(const void *a, const void *b)
+{
+ const NetworkGameList *cmp1 = *(const NetworkGameList**)a;
+ const NetworkGameList *cmp2 = *(const NetworkGameList**)b;
+ int r = strcasecmp(cmp1->info.server_name, cmp2->info.server_name);
+
+ return _internal_sort_order ? -r : r;
+}
+
+/** Qsort function to sort by the amount of clients online on a
+ * server. If the two servers have the same amount, the one with the
+ * higher maximum is preferred. */
+static int CDECL NGameClientSorter(const void *a, const void *b)
+{
+ const NetworkGameList *cmp1 = *(const NetworkGameList**)a;
+ const NetworkGameList *cmp2 = *(const NetworkGameList**)b;
+ /* Reverse as per default we are interested in most-clients first */
+ int r = cmp1->info.clients_on - cmp2->info.clients_on;
+
+ if (r == 0) r = cmp1->info.clients_max - cmp2->info.clients_max;
+ if (r == 0) r = strcasecmp(cmp1->info.server_name, cmp2->info.server_name);
+
+ return _internal_sort_order ? -r : r;
+}
+
+/** Qsort function to sort by joinability. If both servers are the
+ * same, prefer the non-passworded server first. */
+static int CDECL NGameAllowedSorter(const void *a, const void *b)
+{
+ const NetworkGameList *cmp1 = *(const NetworkGameList**)a;
+ const NetworkGameList *cmp2 = *(const NetworkGameList**)b;
+ /* Reverse default as we are interested in compatible clients first */
+ int r = cmp2->info.compatible - cmp1->info.compatible;
+
+ if (r == 0) r = cmp1->info.use_password - cmp2->info.use_password;
+ if (r == 0) r = strcasecmp(cmp1->info.server_name, cmp2->info.server_name);
+
+ return _internal_sort_order ? -r : r;
+}
+
+/** (Re)build the network game list as its amount has changed because
+ * an item has been added or deleted for example
+ * @param ngl list_d struct that contains all necessary information for sorting */
+static void BuildNetworkGameList(network_ql_d *nqld)
+{
+ NetworkGameList *ngl_temp;
+ uint n = 0;
+
+ if (!(nqld->l.flags & VL_REBUILD)) return;
+
+ /* Count the number of games in the list */
+ for (ngl_temp = _network_game_list; ngl_temp != NULL; ngl_temp = ngl_temp->next) n++;
+ if (n == 0) return;
+
+ /* Create temporary array of games to use for listing */
+ free(nqld->sort_list);
+ nqld->sort_list = malloc(n * sizeof(nqld->sort_list[0]));
+ if (nqld->sort_list == NULL) error("Could not allocate memory for the network-game-sorting-list");
+ nqld->l.list_length = n;
+
+ for (n = 0, ngl_temp = _network_game_list; ngl_temp != NULL; ngl_temp = ngl_temp->next) {
+ nqld->sort_list[n++] = ngl_temp;
+ }
+
+ /* Force resort */
+ nqld->l.flags &= ~VL_REBUILD;
+ nqld->l.flags |= VL_RESORT;
+}
+
+static void SortNetworkGameList(network_ql_d *nqld)
+{
+ static NGameNameSortFunction * const ngame_sorter[] = {
+ &NGameNameSorter,
+ &NGameClientSorter,
+ &NGameAllowedSorter
+ };
+
+ NetworkGameList *item;
+ uint i;
+
+ if (!(nqld->l.flags & VL_RESORT)) return;
+ if (nqld->l.list_length == 0) return;
+
+ _internal_sort_order = !!(nqld->l.flags & VL_DESC);
+ qsort(nqld->sort_list, nqld->l.list_length, sizeof(nqld->sort_list[0]), ngame_sorter[nqld->l.sort_type]);
+
+ /* After sorting ngl->sort_list contains the sorted items. Put these back
+ * into the original list. Basically nothing has changed, we are only
+ * shuffling the ->next pointers */
+ _network_game_list = nqld->sort_list[0];
+ for (item = _network_game_list, i = 1; i != nqld->l.list_length; i++) {
+ item->next = nqld->sort_list[i];
+ item = item->next;
+ }
+ item->next = NULL;
+
+ nqld->l.flags &= ~VL_RESORT;
+}
+
+/* Uses network_ql_d (network_d, querystr_d and list_d) WP macro */
+static void NetworkGameWindowWndProc(Window *w, WindowEvent *e)
+{
+ network_d *nd = &WP(w, network_ql_d).n;
+ list_d *ld = &WP(w, network_ql_d).l;
+
+ switch (e->event) {
+ case WE_CREATE: /* Focus input box */
+ nd->field = 3;
+ nd->server = NULL;
+
+ WP(w, network_ql_d).sort_list = NULL;
+ ld->flags = VL_REBUILD | (_ng_sorting.order << (VL_DESC - 1));
+ ld->sort_type = _ng_sorting.criteria;
+ break;
+
+ case WE_PAINT: {
+ const NetworkGameList *sel = nd->server;
+ const char *arrow = (ld->flags & VL_DESC) ? DOWNARROW : UPARROW;
+
+ if (ld->flags & VL_REBUILD) {
+ BuildNetworkGameList(&WP(w, network_ql_d));
+ SetVScrollCount(w, ld->list_length);
+ }
+ if (ld->flags & VL_RESORT) SortNetworkGameList(&WP(w, network_ql_d));
+
+ SetWindowWidgetDisabledState(w, 17, sel == NULL);
+ /* Join Button disabling conditions */
+ SetWindowWidgetDisabledState(w, 16, sel == NULL || // no Selected Server
+ !sel->online || // Server offline
+ sel->info.clients_on >= sel->info.clients_max || // Server full
+ !sel->info.compatible); // Revision mismatch
+
+ SetWindowWidgetHiddenState(w, 18, sel == NULL ||
+ !sel->online ||
+ sel->info.grfconfig == NULL);
+
+ SetDParam(0, 0x00);
+ SetDParam(7, _lan_internet_types_dropdown[_network_lan_internet]);
+ DrawWindowWidgets(w);
+
+ DrawEditBox(w, &WP(w, network_ql_d).q, 3);
+
+ DrawString(9, 23, STR_NETWORK_CONNECTION, 2);
+ DrawString(210, 23, STR_NETWORK_PLAYER_NAME, 2);
+
+ /* Sort based on widgets: name, clients, compatibility */
+ switch (ld->sort_type) {
+ case 6 - 6: DoDrawString(arrow, w->widget[6].right - 10, 42, 0x10); break;
+ case 7 - 6: DoDrawString(arrow, w->widget[7].right - 10, 42, 0x10); break;
+ case 8 - 6: DoDrawString(arrow, w->widget[8].right - 10, 42, 0x10); break;
+ }
+
+ { // draw list of games
+ uint16 y = NET_PRC__OFFSET_TOP_WIDGET + 3;
+ int32 n = 0;
+ int32 pos = w->vscroll.pos;
+ uint max_name_width = w->widget[6].right - w->widget[6].left - 5;
+ const NetworkGameList *cur_item = _network_game_list;
+
+ while (pos > 0 && cur_item != NULL) {
+ pos--;
+ cur_item = cur_item->next;
+ }
+
+ while (cur_item != NULL) {
+ // show highlighted item with a different colour
+ if (cur_item == sel) GfxFillRect(w->widget[6].left + 1, y - 2, w->widget[8].right - 1, y + 9, 10);
+
+ SetDParamStr(0, cur_item->info.server_name);
+ DrawStringTruncated(w->widget[6].left + 5, y, STR_02BD, 16, max_name_width);
+
+ SetDParam(0, cur_item->info.clients_on);
+ SetDParam(1, cur_item->info.clients_max);
+ SetDParam(2, cur_item->info.companies_on);
+ SetDParam(3, cur_item->info.companies_max);
+ DrawStringCentered(210, y, STR_NETWORK_GENERAL_ONLINE, 2);
+
+ // only draw icons if the server is online
+ if (cur_item->online) {
+ // draw a lock if the server is password protected.
+ if (cur_item->info.use_password) DrawSprite(SPR_LOCK, w->widget[8].left + 5, y - 1);
+
+ // draw red or green icon, depending on compatibility with server.
+ DrawSprite(SPR_BLOT | (cur_item->info.compatible ? PALETTE_TO_GREEN : (cur_item->info.version_compatible ? PALETTE_TO_YELLOW : PALETTE_TO_RED)), w->widget[8].left + 15, y);
+
+ // draw flag according to server language
+ DrawSprite(SPR_FLAGS_BASE + cur_item->info.server_lang, w->widget[8].left + 25, y);
+ }
+
+ cur_item = cur_item->next;
+ y += NET_PRC__SIZE_OF_ROW;
+ if (++n == w->vscroll.cap) break; // max number of games in the window
+ }
+ }
+
+ /* Draw the right menu */
+ GfxFillRect(311, 43, 539, 92, 157);
+ if (sel == NULL) {
+ DrawStringCentered(425, 58, STR_NETWORK_GAME_INFO, 0);
+ } else if (!sel->online) {
+ SetDParamStr(0, sel->info.server_name);
+ DrawStringCentered(425, 68, STR_ORANGE, 0); // game name
+
+ DrawStringCentered(425, 132, STR_NETWORK_SERVER_OFFLINE, 0); // server offline
+ } else { // show game info
+ uint16 y = 100;
+ const uint16 x = w->widget[15].left + 5;
+
+ DrawStringCentered(425, 48, STR_NETWORK_GAME_INFO, 0);
+
+
+ SetDParamStr(0, sel->info.server_name);
+ DrawStringCenteredTruncated(w->widget[15].left, w->widget[15].right, 62, STR_ORANGE, 16); // game name
+
+ SetDParamStr(0, sel->info.map_name);
+ DrawStringCenteredTruncated(w->widget[15].left, w->widget[15].right, 74, STR_02BD, 16); // map name
+
+ SetDParam(0, sel->info.clients_on);
+ SetDParam(1, sel->info.clients_max);
+ SetDParam(2, sel->info.companies_on);
+ SetDParam(3, sel->info.companies_max);
+ DrawString(x, y, STR_NETWORK_CLIENTS, 2);
+ y += 10;
+
+ SetDParam(0, _language_dropdown[sel->info.server_lang]);
+ DrawString(x, y, STR_NETWORK_LANGUAGE, 2); // server language
+ y += 10;
+
+ SetDParam(0, STR_TEMPERATE_LANDSCAPE + sel->info.map_set);
+ DrawString(x, y, STR_NETWORK_TILESET, 2); // tileset
+ y += 10;
+
+ SetDParam(0, sel->info.map_width);
+ SetDParam(1, sel->info.map_height);
+ DrawString(x, y, STR_NETWORK_MAP_SIZE, 2); // map size
+ y += 10;
+
+ SetDParamStr(0, sel->info.server_revision);
+ DrawString(x, y, STR_NETWORK_SERVER_VERSION, 2); // server version
+ y += 10;
+
+ SetDParamStr(0, sel->info.hostname);
+ SetDParam(1, sel->port);
+ DrawString(x, y, STR_NETWORK_SERVER_ADDRESS, 2); // server address
+ y += 10;
+
+ SetDParam(0, sel->info.start_date);
+ DrawString(x, y, STR_NETWORK_START_DATE, 2); // start date
+ y += 10;
+
+ SetDParam(0, sel->info.game_date);
+ DrawString(x, y, STR_NETWORK_CURRENT_DATE, 2); // current date
+ y += 10;
+
+ y += 2;
+
+ if (!sel->info.compatible) {
+ DrawStringCentered(425, y, sel->info.version_compatible ? STR_NETWORK_GRF_MISMATCH : STR_NETWORK_VERSION_MISMATCH, 0); // server mismatch
+ } else if (sel->info.clients_on == sel->info.clients_max) {
+ // Show: server full, when clients_on == clients_max
+ DrawStringCentered(425, y, STR_NETWORK_SERVER_FULL, 0); // server full
+ } else if (sel->info.use_password) {
+ DrawStringCentered(425, y, STR_NETWORK_PASSWORD, 0); // password warning
+ }
+
+ y += 10;
+ }
+ } break;
+
+ case WE_CLICK:
+ nd->field = e->we.click.widget;
+ switch (e->we.click.widget) {
+ case 0: case 14: /* Close 'X' | Cancel button */
+ DeleteWindowById(WC_NETWORK_WINDOW, 0);
+ break;
+ case 4: case 5:
+ ShowDropDownMenu(w, _lan_internet_types_dropdown, _network_lan_internet, 5, 0, 0); // do it for widget 5
+ break;
+ case 6: /* Sort by name */
+ case 7: /* Sort by connected clients */
+ case 8: /* Connectivity (green dot) */
+ if (ld->sort_type == e->we.click.widget - 6) ld->flags ^= VL_DESC;
+ ld->flags |= VL_RESORT;
+ ld->sort_type = e->we.click.widget - 6;
+
+ _ng_sorting.order = !!(ld->flags & VL_DESC);
+ _ng_sorting.criteria = ld->sort_type;
+ SetWindowDirty(w);
+ break;
+ case 9: { /* Matrix to show networkgames */
+ NetworkGameList *cur_item;
+ uint32 id_v = (e->we.click.pt.y - NET_PRC__OFFSET_TOP_WIDGET) / NET_PRC__SIZE_OF_ROW;
+
+ if (id_v >= w->vscroll.cap) return; // click out of bounds
+ id_v += w->vscroll.pos;
+
+ cur_item = _network_game_list;
+ for (; id_v > 0 && cur_item != NULL; id_v--) cur_item = cur_item->next;
+
+ nd->server = cur_item;
+ SetWindowDirty(w);
+ } break;
+ case 11: /* Find server automatically */
+ switch (_network_lan_internet) {
+ case 0: NetworkUDPSearchGame(); break;
+ case 1: NetworkUDPQueryMasterServer(); break;
+ }
+ break;
+ case 12: { // Add a server
+ ShowQueryString(
+ BindCString(_network_default_ip),
+ STR_NETWORK_ENTER_IP,
+ 31 | 0x1000, // maximum number of characters OR
+ 250, // characters up to this width pixels, whichever is satisfied first
+ w, CS_ALPHANUMERAL);
+ } break;
+ case 13: /* Start server */
+ ShowNetworkStartServerWindow();
+ break;
+ case 16: /* Join Game */
+ if (nd->server != NULL) {
+ snprintf(_network_last_host, sizeof(_network_last_host), "%s", inet_ntoa(*(struct in_addr *)&nd->server->ip));
+ _network_last_port = nd->server->port;
+ ShowNetworkLobbyWindow(nd->server);
+ }
+ break;
+ case 17: // Refresh
+ if (nd->server != NULL)
+ NetworkQueryServer(nd->server->info.hostname, nd->server->port, true);
+ break;
+ case 18: // NewGRF Settings
+ if (nd->server != NULL) ShowNewGRFSettings(false, false, false, &nd->server->info.grfconfig);
+ break;
+
+ } break;
+
+ case WE_DROPDOWN_SELECT: /* we have selected a dropdown item in the list */
+ switch (e->we.dropdown.button) {
+ case 5:
+ _network_lan_internet = e->we.dropdown.index;
+ break;
+ }
+
+ SetWindowDirty(w);
+ break;
+
+ case WE_MOUSELOOP:
+ if (nd->field == 3) HandleEditBox(w, &WP(w, network_ql_d).q, 3);
+ break;
+
+ case WE_MESSAGE:
+ if (e->we.message.msg != 0) nd->server = NULL;
+ ld->flags |= VL_REBUILD;
+ SetWindowDirty(w);
+ break;
+
+ case WE_KEYPRESS:
+ if (nd->field != 3) {
+ if (nd->server != NULL) {
+ if (e->we.keypress.keycode == WKC_DELETE) { /* Press 'delete' to remove servers */
+ NetworkGameListRemoveItem(nd->server);
+ NetworkRebuildHostList();
+ nd->server = NULL;
+ }
+ }
+ break;
+ }
+
+ if (HandleEditBoxKey(w, &WP(w, network_ql_d).q, 3, e) == 1) break; // enter pressed
+
+ // The name is only allowed when it starts with a letter!
+ if (_edit_str_buf[0] != '\0' && _edit_str_buf[0] != ' ') {
+ ttd_strlcpy(_network_player_name, _edit_str_buf, lengthof(_network_player_name));
+ } else {
+ ttd_strlcpy(_network_player_name, "Player", lengthof(_network_player_name));
+ }
+
+ break;
+
+ case WE_ON_EDIT_TEXT:
+ NetworkAddServer(e->we.edittext.str);
+ NetworkRebuildHostList();
+ break;
+
+ case WE_DESTROY: /* Nicely clean up the sort-list */
+ free(WP(w, network_ql_d).sort_list);
+ break;
+ }
+}
+
+static const Widget _network_game_window_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, BGC, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, BGC, 11, 549, 0, 13, STR_NETWORK_MULTIPLAYER, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, BGC, 0, 549, 14, 263, 0x0, STR_NULL},
+
+/* LEFT SIDE */
+{ WWT_PANEL, RESIZE_NONE, BGC, 310, 461, 22, 33, 0x0, STR_NETWORK_ENTER_NAME_TIP},
+
+{ WWT_INSET, RESIZE_NONE, BGC, 90, 181, 22, 33, STR_NETWORK_COMBO1, STR_NETWORK_CONNECTION_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, BGC, 170, 180, 23, 32, STR_0225, STR_NETWORK_CONNECTION_TIP},
+
+{ WWT_PUSHTXTBTN, RESIZE_NONE, BTC, 10, 170, 42, 53, STR_NETWORK_GAME_NAME, STR_NETWORK_GAME_NAME_TIP},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, BTC, 171, 250, 42, 53, STR_NETWORK_CLIENTS_CAPTION, STR_NETWORK_CLIENTS_CAPTION_TIP},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, BTC, 251, 290, 42, 53, STR_EMPTY, STR_NETWORK_INFO_ICONS_TIP},
+
+{ WWT_MATRIX, RESIZE_NONE, BGC, 10, 290, 54, 236, (13 << 8) + 1, STR_NETWORK_CLICK_GAME_TO_SELECT},
+{ WWT_SCROLLBAR, RESIZE_NONE, BGC, 291, 302, 42, 236, STR_NULL, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+
+{ WWT_PUSHTXTBTN, RESIZE_NONE, BTC, 30, 130, 246, 257, STR_NETWORK_FIND_SERVER, STR_NETWORK_FIND_SERVER_TIP},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, BTC, 180, 280, 246, 257, STR_NETWORK_ADD_SERVER, STR_NETWORK_ADD_SERVER_TIP},
+
+/* RIGHT SIDE */
+{ WWT_PUSHTXTBTN, RESIZE_NONE, BTC, 315, 415, 246, 257, STR_NETWORK_START_SERVER, STR_NETWORK_START_SERVER_TIP},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, BTC, 430, 535, 246, 257, STR_012E_CANCEL, STR_NULL},
+
+{ WWT_PANEL, RESIZE_NONE, BGC, 310, 540, 42, 236, 0x0, STR_NULL},
+
+{ WWT_PUSHTXTBTN, RESIZE_NONE, BTC, 315, 415, 215, 226, STR_NETWORK_JOIN_GAME, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, BTC, 430, 535, 215, 226, STR_NETWORK_REFRESH, STR_NETWORK_REFRESH_TIP},
+
+{ WWT_PUSHTXTBTN, RESIZE_NONE, BTC, 430, 535, 197, 208, STR_NEWGRF_SETTINGS_BUTTON, STR_NULL},
+
+{ WIDGETS_END},
+};
+
+static const WindowDesc _network_game_window_desc = {
+ WDP_CENTER, WDP_CENTER, 550, 264,
+ WC_NETWORK_WINDOW,0,
+ WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _network_game_window_widgets,
+ NetworkGameWindowWndProc,
+};
+
+void ShowNetworkGameWindow(void)
+{
+ static bool first = true;
+ Window *w;
+ DeleteWindowById(WC_NETWORK_WINDOW, 0);
+
+ /* Only show once */
+ if (first) {
+ char* const *srv;
+
+ first = false;
+ // add all servers from the config file to our list
+ for (srv = &_network_host_list[0]; srv != endof(_network_host_list) && *srv != NULL; srv++) {
+ NetworkAddServer(*srv);
+ }
+
+ _ng_sorting.criteria = 2; // sort default by collectivity (green-dots on top)
+ _ng_sorting.order = 0; // sort ascending by default
+ }
+
+ w = AllocateWindowDesc(&_network_game_window_desc);
+ if (w != NULL) {
+ querystr_d *querystr = &WP(w, network_ql_d).q;
+
+ ttd_strlcpy(_edit_str_buf, _network_player_name, lengthof(_edit_str_buf));
+ w->vscroll.cap = 13;
+
+ querystr->afilter = CS_ALPHANUMERAL;
+ InitializeTextBuffer(&querystr->text, _edit_str_buf, lengthof(_edit_str_buf), 120);
+
+ UpdateNetworkGameWindow(true);
+ }
+}
+
+enum {
+ NSSWND_START = 64,
+ NSSWND_ROWSIZE = 12
+};
+
+/* Uses network_ql_d (network_d, querystr_d and list_d) WP macro */
+static void NetworkStartServerWindowWndProc(Window *w, WindowEvent *e)
+{
+ network_d *nd = &WP(w, network_ql_d).n;
+
+ switch (e->event) {
+ case WE_CREATE: /* focus input box */
+ nd->field = 3;
+ _network_game_info.use_password = (_network_server_password[0] != '\0');
+ break;
+
+ case WE_PAINT: {
+ int y = NSSWND_START, pos;
+ const FiosItem *item;
+
+ SetDParam( 7, _connection_types_dropdown[_network_advertise]);
+ SetDParam( 9, _players_dropdown[_network_game_info.clients_max]);
+ SetDParam(11, _players_dropdown[_network_game_info.companies_max]);
+ SetDParam(13, _players_dropdown[_network_game_info.spectators_max]);
+ SetDParam(15, _language_dropdown[_network_game_info.server_lang]);
+ DrawWindowWidgets(w);
+
+ GfxFillRect(11, 63, 258, 215, 0xD7);
+ DrawEditBox(w, &WP(w, network_ql_d).q, 3);
+
+ DrawString(10, 22, STR_NETWORK_NEW_GAME_NAME, 2);
+
+ DrawString(10, 43, STR_NETWORK_SELECT_MAP, 2);
+
+ DrawString(280, 63, STR_NETWORK_CONNECTION, 2);
+ DrawString(280, 95, STR_NETWORK_NUMBER_OF_CLIENTS, 2);
+ DrawString(280, 127, STR_NETWORK_NUMBER_OF_COMPANIES, 2);
+ DrawString(280, 159, STR_NETWORK_NUMBER_OF_SPECTATORS, 2);
+ DrawString(280, 191, STR_NETWORK_LANGUAGE_SPOKEN, 2);
+
+ if (_network_game_info.use_password) DoDrawString("*", 408, 23, 3);
+
+ // draw list of maps
+ pos = w->vscroll.pos;
+ while (pos < _fios_num + 1) {
+ item = _fios_list + pos - 1;
+ if (item == nd->map || (pos == 0 && nd->map == NULL))
+ GfxFillRect(11, y - 1, 258, y + 10, 155); // show highlighted item with a different colour
+
+ if (pos == 0) {
+ DrawString(14, y, STR_4010_GENERATE_RANDOM_NEW_GAME, 9);
+ } else {
+ DoDrawString(item->title, 14, y, _fios_colors[item->type] );
+ }
+ pos++;
+ y += NSSWND_ROWSIZE;
+
+ if (y >= w->vscroll.cap * NSSWND_ROWSIZE + NSSWND_START) break;
+ }
+ } break;
+
+ case WE_CLICK:
+ nd->field = e->we.click.widget;
+ switch (e->we.click.widget) {
+ case 0: /* Close 'X' */
+ case 19: /* Cancel button */
+ ShowNetworkGameWindow();
+ break;
+
+ case 4: /* Set password button */
+ ShowQueryString(BindCString(_network_server_password), STR_NETWORK_SET_PASSWORD, 20, 250, w, CS_ALPHANUMERAL);
+ break;
+
+ case 5: { /* Select map */
+ int y = (e->we.click.pt.y - NSSWND_START) / NSSWND_ROWSIZE;
+
+ y += w->vscroll.pos;
+ if (y >= w->vscroll.count) return;
+
+ nd->map = (y == 0) ? NULL : _fios_list + y - 1;
+ SetWindowDirty(w);
+ } break;
+ case 7: case 8: /* Connection type */
+ ShowDropDownMenu(w, _connection_types_dropdown, _network_advertise, 8, 0, 0); // do it for widget 8
+ break;
+ case 9: case 10: /* Number of Players (hide 0 and 1 players) */
+ ShowDropDownMenu(w, _players_dropdown, _network_game_info.clients_max, 10, 0, 3);
+ break;
+ case 11: case 12: /* Number of Companies (hide 0, 9 and 10 companies; max is 8) */
+ ShowDropDownMenu(w, _players_dropdown, _network_game_info.companies_max, 12, 0, 1537);
+ break;
+ case 13: case 14: /* Number of Spectators */
+ ShowDropDownMenu(w, _players_dropdown, _network_game_info.spectators_max, 14, 0, 0);
+ break;
+ case 15: case 16: /* Language */
+ ShowDropDownMenu(w, _language_dropdown, _network_game_info.server_lang, 16, 0, 0);
+ break;
+ case 17: /* Start game */
+ _is_network_server = true;
+
+ if (nd->map == NULL) { // start random new game
+ ShowGenerateLandscape();
+ } else { // load a scenario
+ char *name = FiosBrowseTo(nd->map);
+ if (name != NULL) {
+ SetFiosType(nd->map->type);
+ ttd_strlcpy(_file_to_saveload.name, name, sizeof(_file_to_saveload.name));
+ ttd_strlcpy(_file_to_saveload.title, nd->map->title, sizeof(_file_to_saveload.title));
+
+ DeleteWindow(w);
+ SwitchMode(SM_START_SCENARIO);
+ }
+ }
+ break;
+ case 18: /* Load game */
+ _is_network_server = true;
+ /* XXX - WC_NETWORK_WINDOW should stay, but if it stays, it gets
+ * copied all the elements of 'load game' and upon closing that, it segfaults */
+ DeleteWindowById(WC_NETWORK_WINDOW, 0);
+ ShowSaveLoadDialog(SLD_LOAD_GAME);
+ break;
+ }
+ break;
+
+ case WE_DROPDOWN_SELECT: /* we have selected a dropdown item in the list */
+ switch (e->we.dropdown.button) {
+ case 8: _network_advertise = (e->we.dropdown.index != 0); break;
+ case 10: _network_game_info.clients_max = e->we.dropdown.index; break;
+ case 12: _network_game_info.companies_max = e->we.dropdown.index; break;
+ case 14: _network_game_info.spectators_max = e->we.dropdown.index; break;
+ case 16: _network_game_info.server_lang = e->we.dropdown.index; break;
+ }
+
+ SetWindowDirty(w);
+ break;
+
+ case WE_MOUSELOOP:
+ if (nd->field == 3) HandleEditBox(w, &WP(w, network_ql_d).q, 3);
+ break;
+
+ case WE_KEYPRESS:
+ if (nd->field == 3) {
+ if (HandleEditBoxKey(w, &WP(w, network_ql_d).q, 3, e) == 1) break; // enter pressed
+
+ ttd_strlcpy(_network_server_name, WP(w, network_ql_d).q.text.buf, sizeof(_network_server_name));
+ UpdateTextBufferSize(&WP(w, network_ql_d).q.text);
+ }
+ break;
+
+ case WE_ON_EDIT_TEXT: {
+ ttd_strlcpy(_network_server_password, e->we.edittext.str, lengthof(_network_server_password));
+ _network_game_info.use_password = (_network_server_password[0] != '\0');
+ SetWindowDirty(w);
+ } break;
+ }
+}
+
+static const Widget _network_start_server_window_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, BGC, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW },
+{ WWT_CAPTION, RESIZE_NONE, BGC, 11, 419, 0, 13, STR_NETWORK_START_GAME_WINDOW, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, BGC, 0, 419, 14, 243, 0x0, STR_NULL},
+
+{ WWT_PANEL, RESIZE_NONE, BGC, 100, 272, 22, 33, 0x0, STR_NETWORK_NEW_GAME_NAME_TIP},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, BTC, 285, 405, 22, 33, STR_NETWORK_SET_PASSWORD, STR_NETWORK_PASSWORD_TIP},
+
+{ WWT_INSET, RESIZE_NONE, BGC, 10, 271, 62, 216, 0x0, STR_NETWORK_SELECT_MAP_TIP},
+{ WWT_SCROLLBAR, RESIZE_NONE, BGC, 259, 270, 63, 215, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+/* Combo boxes to control Connection Type / Max Clients / Max Companies / Max Observers / Language */
+{ WWT_INSET, RESIZE_NONE, BGC, 280, 410, 77, 88, STR_NETWORK_COMBO1, STR_NETWORK_CONNECTION_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, BGC, 399, 409, 78, 87, STR_0225, STR_NETWORK_CONNECTION_TIP},
+{ WWT_INSET, RESIZE_NONE, BGC, 280, 410, 109, 120, STR_NETWORK_COMBO2, STR_NETWORK_NUMBER_OF_CLIENTS_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, BGC, 399, 409, 110, 119, STR_0225, STR_NETWORK_NUMBER_OF_CLIENTS_TIP},
+{ WWT_INSET, RESIZE_NONE, BGC, 280, 410, 141, 152, STR_NETWORK_COMBO3, STR_NETWORK_NUMBER_OF_COMPANIES_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, BGC, 399, 409, 142, 151, STR_0225, STR_NETWORK_NUMBER_OF_COMPANIES_TIP},
+{ WWT_INSET, RESIZE_NONE, BGC, 280, 410, 173, 184, STR_NETWORK_COMBO4, STR_NETWORK_NUMBER_OF_SPECTATORS_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, BGC, 399, 409, 174, 183, STR_0225, STR_NETWORK_NUMBER_OF_SPECTATORS_TIP},
+{ WWT_INSET, RESIZE_NONE, BGC, 280, 410, 205, 216, STR_NETWORK_COMBO5, STR_NETWORK_LANGUAGE_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, BGC, 399, 409, 206, 215, STR_0225, STR_NETWORK_LANGUAGE_TIP},
+
+{ WWT_PUSHTXTBTN, RESIZE_NONE, BTC, 40, 140, 224, 235, STR_NETWORK_START_GAME, STR_NETWORK_START_GAME_TIP},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, BTC, 150, 250, 224, 235, STR_NETWORK_LOAD_GAME, STR_NETWORK_LOAD_GAME_TIP},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, BTC, 260, 360, 224, 235, STR_012E_CANCEL, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _network_start_server_window_desc = {
+ WDP_CENTER, WDP_CENTER, 420, 244,
+ WC_NETWORK_WINDOW,0,
+ WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _network_start_server_window_widgets,
+ NetworkStartServerWindowWndProc,
+};
+
+static void ShowNetworkStartServerWindow(void)
+{
+ Window *w;
+ DeleteWindowById(WC_NETWORK_WINDOW, 0);
+
+ w = AllocateWindowDesc(&_network_start_server_window_desc);
+ ttd_strlcpy(_edit_str_buf, _network_server_name, lengthof(_edit_str_buf));
+
+ _saveload_mode = SLD_NEW_GAME;
+ BuildFileList();
+ w->vscroll.cap = 12;
+ w->vscroll.count = _fios_num+1;
+
+ WP(w, network_ql_d).q.afilter = CS_ALPHANUMERAL;
+ InitializeTextBuffer(&WP(w, network_ql_d).q.text, _edit_str_buf, lengthof(_edit_str_buf), 160);
+}
+
+static byte NetworkLobbyFindCompanyIndex(byte pos)
+{
+ byte i;
+
+ /* Scroll through all _network_player_info and get the 'pos' item
+ that is not empty */
+ for (i = 0; i < MAX_PLAYERS; i++) {
+ if (_network_player_info[i].company_name[0] != '\0') {
+ if (pos-- == 0) return i;
+ }
+ }
+
+ return 0;
+}
+
+/* uses network_d WP macro */
+static void NetworkLobbyWindowWndProc(Window *w, WindowEvent *e)
+{
+ network_d *nd = &WP(w, network_d);
+
+ switch (e->event) {
+ case WE_CREATE:
+ nd->company = (byte)-1;
+ break;
+
+ case WE_PAINT: {
+ const NetworkGameInfo *gi = &nd->server->info;
+ int y = NET_PRC__OFFSET_TOP_WIDGET_COMPANY, pos;
+
+ SetWindowWidgetDisabledState(w, 7, nd->company == (byte)-1);
+ SetWindowWidgetDisabledState(w, 8, gi->companies_on >= gi->companies_max);
+ /* You can not join a server as spectator when it has no companies active..
+ * it causes some nasty crashes */
+ SetWindowWidgetDisabledState(w, 9, gi->spectators_on >= gi->spectators_max ||
+ gi->companies_on == 0);
+
+ DrawWindowWidgets(w);
+
+ SetDParamStr(0, gi->server_name);
+ DrawString(10, 22, STR_NETWORK_PREPARE_TO_JOIN, 2);
+
+ /* Draw company list */
+ pos = w->vscroll.pos;
+ while (pos < gi->companies_on) {
+ byte company = NetworkLobbyFindCompanyIndex(pos);
+ bool income = false;
+ if (nd->company == company)
+ GfxFillRect(11, y - 1, 154, y + 10, 10); // show highlighted item with a different colour
+
+ DoDrawStringTruncated(_network_player_info[company].company_name, 13, y, 16, 135 - 13);
+ if (_network_player_info[company].use_password != 0) DrawSprite(SPR_LOCK, 135, y);
+
+ /* If the company's income was positive puts a green dot else a red dot */
+ if (_network_player_info[company].income >= 0) income = true;
+ DrawSprite(SPR_BLOT | (income ? PALETTE_TO_GREEN : PALETTE_TO_RED), 145, y);
+
+ pos++;
+ y += NET_PRC__SIZE_OF_ROW;
+ if (pos >= w->vscroll.cap) break;
+ }
+
+ /* Draw info about selected company when it is selected in the left window */
+ GfxFillRect(174, 39, 403, 75, 157);
+ DrawStringCentered(290, 50, STR_NETWORK_COMPANY_INFO, 0);
+ if (nd->company != (byte)-1) {
+ const uint x = 183;
+ const uint trunc_width = w->widget[6].right - x;
+ y = 80;
+
+ SetDParam(0, nd->server->info.clients_on);
+ SetDParam(1, nd->server->info.clients_max);
+ SetDParam(2, nd->server->info.companies_on);
+ SetDParam(3, nd->server->info.companies_max);
+ DrawString(x, y, STR_NETWORK_CLIENTS, 2);
+ y += 10;
+
+ SetDParamStr(0, _network_player_info[nd->company].company_name);
+ DrawStringTruncated(x, y, STR_NETWORK_COMPANY_NAME, 2, trunc_width);
+ y += 10;
+
+ SetDParam(0, _network_player_info[nd->company].inaugurated_year);
+ DrawString(x, y, STR_NETWORK_INAUGURATION_YEAR, 2); // inauguration year
+ y += 10;
+
+ SetDParam64(0, _network_player_info[nd->company].company_value);
+ DrawString(x, y, STR_NETWORK_VALUE, 2); // company value
+ y += 10;
+
+ SetDParam64(0, _network_player_info[nd->company].money);
+ DrawString(x, y, STR_NETWORK_CURRENT_BALANCE, 2); // current balance
+ y += 10;
+
+ SetDParam64(0, _network_player_info[nd->company].income);
+ DrawString(x, y, STR_NETWORK_LAST_YEARS_INCOME, 2); // last year's income
+ y += 10;
+
+ SetDParam(0, _network_player_info[nd->company].performance);
+ DrawString(x, y, STR_NETWORK_PERFORMANCE, 2); // performance
+ y += 10;
+
+ SetDParam(0, _network_player_info[nd->company].num_vehicle[0]);
+ SetDParam(1, _network_player_info[nd->company].num_vehicle[1]);
+ SetDParam(2, _network_player_info[nd->company].num_vehicle[2]);
+ SetDParam(3, _network_player_info[nd->company].num_vehicle[3]);
+ SetDParam(4, _network_player_info[nd->company].num_vehicle[4]);
+ DrawString(x, y, STR_NETWORK_VEHICLES, 2); // vehicles
+ y += 10;
+
+ SetDParam(0, _network_player_info[nd->company].num_station[0]);
+ SetDParam(1, _network_player_info[nd->company].num_station[1]);
+ SetDParam(2, _network_player_info[nd->company].num_station[2]);
+ SetDParam(3, _network_player_info[nd->company].num_station[3]);
+ SetDParam(4, _network_player_info[nd->company].num_station[4]);
+ DrawString(x, y, STR_NETWORK_STATIONS, 2); // stations
+ y += 10;
+
+ SetDParamStr(0, _network_player_info[nd->company].players);
+ DrawStringTruncated(x, y, STR_NETWORK_PLAYERS, 2, trunc_width); // players
+ }
+ } break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 0: case 11: /* Close 'X' | Cancel button */
+ ShowNetworkGameWindow();
+ break;
+ case 4: { /* Company list */
+ uint32 id_v = (e->we.click.pt.y - NET_PRC__OFFSET_TOP_WIDGET_COMPANY) / NET_PRC__SIZE_OF_ROW;
+
+ if (id_v >= w->vscroll.cap) return;
+
+ id_v += w->vscroll.pos;
+ nd->company = (id_v >= nd->server->info.companies_on) ? (byte)-1 : NetworkLobbyFindCompanyIndex(id_v);
+ SetWindowDirty(w);
+ } break;
+ case 7: /* Join company */
+ if (nd->company != (byte)-1) {
+ _network_playas = nd->company;
+ NetworkClientConnectGame(_network_last_host, _network_last_port);
+ }
+ break;
+ case 8: /* New company */
+ _network_playas = PLAYER_NEW_COMPANY;
+ NetworkClientConnectGame(_network_last_host, _network_last_port);
+ break;
+ case 9: /* Spectate game */
+ _network_playas = PLAYER_SPECTATOR;
+ NetworkClientConnectGame(_network_last_host, _network_last_port);
+ break;
+ case 10: /* Refresh */
+ NetworkQueryServer(_network_last_host, _network_last_port, false); // company info
+ NetworkUDPQueryServer(_network_last_host, _network_last_port); // general data
+ break;
+ } break;
+
+ case WE_MESSAGE:
+ SetWindowDirty(w);
+ break;
+ }
+}
+
+static const Widget _network_lobby_window_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, BGC, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW },
+{ WWT_CAPTION, RESIZE_NONE, BGC, 11, 419, 0, 13, STR_NETWORK_GAME_LOBBY, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, BGC, 0, 419, 14, 234, 0x0, STR_NULL},
+
+// company list
+{ WWT_PANEL, RESIZE_NONE, BTC, 10, 155, 38, 49, 0x0, STR_NULL},
+{ WWT_MATRIX, RESIZE_NONE, BGC, 10, 155, 50, 190, (10 << 8) + 1, STR_NETWORK_COMPANY_LIST_TIP},
+{ WWT_SCROLLBAR, RESIZE_NONE, BGC, 156, 167, 38, 190, STR_NULL, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+
+// company/player info
+{ WWT_PANEL, RESIZE_NONE, BGC, 173, 404, 38, 190, 0x0, STR_NULL},
+
+// buttons
+{ WWT_PUSHTXTBTN, RESIZE_NONE, BTC, 10, 151, 200, 211, STR_NETWORK_JOIN_COMPANY, STR_NETWORK_JOIN_COMPANY_TIP},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, BTC, 10, 151, 215, 226, STR_NETWORK_NEW_COMPANY, STR_NETWORK_NEW_COMPANY_TIP},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, BTC, 158, 268, 200, 211, STR_NETWORK_SPECTATE_GAME, STR_NETWORK_SPECTATE_GAME_TIP},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, BTC, 158, 268, 215, 226, STR_NETWORK_REFRESH, STR_NETWORK_REFRESH_TIP},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, BTC, 278, 388, 200, 211, STR_012E_CANCEL, STR_NULL},
+
+{ WIDGETS_END},
+};
+
+static const WindowDesc _network_lobby_window_desc = {
+ WDP_CENTER, WDP_CENTER, 420, 235,
+ WC_NETWORK_WINDOW,0,
+ WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _network_lobby_window_widgets,
+ NetworkLobbyWindowWndProc,
+};
+
+/* Show the networklobbywindow with the selected server
+ * @param ngl Selected game pointer which is passed to the new window */
+static void ShowNetworkLobbyWindow(NetworkGameList *ngl)
+{
+ Window *w;
+ DeleteWindowById(WC_NETWORK_WINDOW, 0);
+
+ NetworkQueryServer(_network_last_host, _network_last_port, false); // company info
+ NetworkUDPQueryServer(_network_last_host, _network_last_port); // general data
+
+ w = AllocateWindowDesc(&_network_lobby_window_desc);
+ if (w != NULL) {
+ WP(w, network_ql_d).n.server = ngl;
+ strcpy(_edit_str_buf, "");
+ w->vscroll.cap = 10;
+ }
+}
+
+// The window below gives information about the connected clients
+// and also makes able to give money to them, kick them (if server)
+// and stuff like that.
+
+extern void DrawPlayerIcon(PlayerID pid, int x, int y);
+
+// Every action must be of this form
+typedef void ClientList_Action_Proc(byte client_no);
+
+// Max 10 actions per client
+#define MAX_CLIENTLIST_ACTION 10
+
+// Some standard bullshit.. defines variables ;)
+static void ClientListWndProc(Window *w, WindowEvent *e);
+static void ClientListPopupWndProc(Window *w, WindowEvent *e);
+static byte _selected_clientlist_item = 255;
+static byte _selected_clientlist_y = 0;
+static char _clientlist_action[MAX_CLIENTLIST_ACTION][50];
+static ClientList_Action_Proc *_clientlist_proc[MAX_CLIENTLIST_ACTION];
+
+enum {
+ CLNWND_OFFSET = 16,
+ CLNWND_ROWSIZE = 10
+};
+
+static const Widget _client_list_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 249, 0, 13, STR_NETWORK_CLIENT_LIST, STR_018C_WINDOW_TITLE_DRAG_THIS},
+
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 249, 14, 14 + CLNWND_ROWSIZE + 1, 0x0, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const Widget _client_list_popup_widgets[] = {
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 99, 0, 0, 0, STR_NULL},
+{ WIDGETS_END},
+};
+
+static WindowDesc _client_list_desc = {
+ WDP_AUTO, WDP_AUTO, 250, 1,
+ WC_CLIENT_LIST,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _client_list_widgets,
+ ClientListWndProc
+};
+
+// Finds the Xth client-info that is active
+static const NetworkClientInfo *NetworkFindClientInfo(byte client_no)
+{
+ const NetworkClientInfo *ci;
+
+ FOR_ALL_ACTIVE_CLIENT_INFOS(ci) {
+ if (client_no == 0) return ci;
+ client_no--;
+ }
+
+ return NULL;
+}
+
+// Here we start to define the options out of the menu
+static void ClientList_Kick(byte client_no)
+{
+ if (client_no < MAX_PLAYERS)
+ SEND_COMMAND(PACKET_SERVER_ERROR)(DEREF_CLIENT(client_no), NETWORK_ERROR_KICKED);
+}
+
+static void ClientList_Ban(byte client_no)
+{
+ uint i;
+ uint32 ip = NetworkFindClientInfo(client_no)->client_ip;
+
+ for (i = 0; i < lengthof(_network_ban_list); i++) {
+ if (_network_ban_list[i] == NULL) {
+ _network_ban_list[i] = strdup(inet_ntoa(*(struct in_addr *)&ip));
+ break;
+ }
+ }
+
+ if (client_no < MAX_PLAYERS)
+ SEND_COMMAND(PACKET_SERVER_ERROR)(DEREF_CLIENT(client_no), NETWORK_ERROR_KICKED);
+}
+
+static void ClientList_GiveMoney(byte client_no)
+{
+ if (NetworkFindClientInfo(client_no) != NULL)
+ ShowNetworkGiveMoneyWindow(NetworkFindClientInfo(client_no)->client_playas);
+}
+
+static void ClientList_SpeakToClient(byte client_no)
+{
+ if (NetworkFindClientInfo(client_no) != NULL)
+ ShowNetworkChatQueryWindow(DESTTYPE_CLIENT, NetworkFindClientInfo(client_no)->client_index);
+}
+
+static void ClientList_SpeakToCompany(byte client_no)
+{
+ if (NetworkFindClientInfo(client_no) != NULL)
+ ShowNetworkChatQueryWindow(DESTTYPE_TEAM, NetworkFindClientInfo(client_no)->client_playas);
+}
+
+static void ClientList_SpeakToAll(byte client_no)
+{
+ ShowNetworkChatQueryWindow(DESTTYPE_BROADCAST, 0);
+}
+
+static void ClientList_None(byte client_no)
+{
+ // No action ;)
+}
+
+
+
+// Help, a action is clicked! What do we do?
+static void HandleClientListPopupClick(byte index, byte clientno) {
+ // A click on the Popup of the ClientList.. handle the command
+ if (index < MAX_CLIENTLIST_ACTION && _clientlist_proc[index] != NULL) {
+ _clientlist_proc[index](clientno);
+ }
+}
+
+// Finds the amount of clients and set the height correct
+static bool CheckClientListHeight(Window *w)
+{
+ int num = 0;
+ const NetworkClientInfo *ci;
+
+ // Should be replaced with a loop through all clients
+ FOR_ALL_ACTIVE_CLIENT_INFOS(ci) {
+ num++;
+ }
+
+ num *= CLNWND_ROWSIZE;
+
+ // If height is changed
+ if (w->height != CLNWND_OFFSET + num + 1) {
+ // XXX - magic unfortunately; (num + 2) has to be one bigger than heigh (num + 1)
+ SetWindowDirty(w);
+ w->widget[2].bottom = w->widget[2].top + num + 2;
+ w->height = CLNWND_OFFSET + num + 1;
+ SetWindowDirty(w);
+ return false;
+ }
+ return true;
+}
+
+// Finds the amount of actions in the popup and set the height correct
+static uint ClientListPopupHeigth(void) {
+ int i, num = 0;
+
+ // Find the amount of actions
+ for (i = 0; i < MAX_CLIENTLIST_ACTION; i++) {
+ if (_clientlist_action[i][0] == '\0') continue;
+ if (_clientlist_proc[i] == NULL) continue;
+ num++;
+ }
+
+ num *= CLNWND_ROWSIZE;
+
+ return num + 1;
+}
+
+// Show the popup (action list)
+static Window *PopupClientList(Window *w, int client_no, int x, int y)
+{
+ int i, h;
+ const NetworkClientInfo *ci;
+ DeleteWindowById(WC_TOOLBAR_MENU, 0);
+
+ // Clean the current actions
+ for (i = 0; i < MAX_CLIENTLIST_ACTION; i++) {
+ _clientlist_action[i][0] = '\0';
+ _clientlist_proc[i] = NULL;
+ }
+
+ // Fill the actions this client has
+ // Watch is, max 50 chars long!
+
+ ci = NetworkFindClientInfo(client_no);
+ if (ci == NULL) return NULL;
+
+ i = 0;
+ if (_network_own_client_index != ci->client_index) {
+ GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT, lastof(_clientlist_action[i]));
+ _clientlist_proc[i++] = &ClientList_SpeakToClient;
+ }
+
+ if (IsValidPlayer(ci->client_playas) || ci->client_playas == PLAYER_SPECTATOR) {
+ GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY, lastof(_clientlist_action[i]));
+ _clientlist_proc[i++] = &ClientList_SpeakToCompany;
+ }
+ GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL, lastof(_clientlist_action[i]));
+ _clientlist_proc[i++] = &ClientList_SpeakToAll;
+
+ if (_network_own_client_index != ci->client_index) {
+ /* We are no spectator and the player we want to give money to is no spectator */
+ if (IsValidPlayer(_network_playas) && IsValidPlayer(ci->client_playas)) {
+ GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_GIVE_MONEY, lastof(_clientlist_action[i]));
+ _clientlist_proc[i++] = &ClientList_GiveMoney;
+ }
+ }
+
+ // A server can kick clients (but not himself)
+ if (_network_server && _network_own_client_index != ci->client_index) {
+ GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_KICK, lastof(_clientlist_action[i]));
+ _clientlist_proc[i++] = &ClientList_Kick;
+
+ sprintf(_clientlist_action[i],"Ban"); // XXX GetString?
+ _clientlist_proc[i++] = &ClientList_Ban;
+ }
+
+ if (i == 0) {
+ GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_NONE, lastof(_clientlist_action[i]));
+ _clientlist_proc[i++] = &ClientList_None;
+ }
+
+ /* Calculate the height */
+ h = ClientListPopupHeigth();
+
+ // Allocate the popup
+ w = AllocateWindow(x, y, 150, h + 1, ClientListPopupWndProc, WC_TOOLBAR_MENU, _client_list_popup_widgets);
+ w->widget[0].bottom = w->widget[0].top + h;
+ w->widget[0].right = w->widget[0].left + 150;
+
+ w->flags4 &= ~WF_WHITE_BORDER_MASK;
+ WP(w,menu_d).item_count = 0;
+ // Save our client
+ WP(w,menu_d).main_button = client_no;
+ WP(w,menu_d).sel_index = 0;
+ // We are a popup
+ _popup_menu_active = true;
+
+ return w;
+}
+
+/** Main handle for the client popup list
+ * uses menu_d WP macro */
+static void ClientListPopupWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ int i, y, sel;
+ byte colour;
+ DrawWindowWidgets(w);
+
+ // Draw the actions
+ sel = WP(w,menu_d).sel_index;
+ y = 1;
+ for (i = 0; i < MAX_CLIENTLIST_ACTION; i++, y += CLNWND_ROWSIZE) {
+ if (_clientlist_action[i][0] == '\0') continue;
+ if (_clientlist_proc[i] == NULL) continue;
+
+ if (sel-- == 0) { // Selected item, highlight it
+ GfxFillRect(1, y, 150 - 2, y + CLNWND_ROWSIZE - 1, 0);
+ colour = 0xC;
+ } else {
+ colour = 0x10;
+ }
+
+ DoDrawString(_clientlist_action[i], 4, y, colour);
+ }
+ } break;
+
+ case WE_POPUPMENU_SELECT: {
+ // We selected an action
+ int index = (e->we.popupmenu.pt.y - w->top) / CLNWND_ROWSIZE;
+
+ if (index >= 0 && e->we.popupmenu.pt.y >= w->top)
+ HandleClientListPopupClick(index, WP(w,menu_d).main_button);
+
+ DeleteWindowById(WC_TOOLBAR_MENU, 0);
+ } break;
+
+ case WE_POPUPMENU_OVER: {
+ // Our mouse hoovers over an action? Select it!
+ int index = (e->we.popupmenu.pt.y - w->top) / CLNWND_ROWSIZE;
+
+ if (index == -1 || index == WP(w,menu_d).sel_index) return;
+
+ WP(w,menu_d).sel_index = index;
+ SetWindowDirty(w);
+ } break;
+
+ }
+}
+
+// Main handle for clientlist
+static void ClientListWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ NetworkClientInfo *ci;
+ int y, i = 0;
+ byte colour;
+
+ // Check if we need to reset the height
+ if (!CheckClientListHeight(w)) break;
+
+ DrawWindowWidgets(w);
+
+ y = CLNWND_OFFSET;
+
+ FOR_ALL_ACTIVE_CLIENT_INFOS(ci) {
+ if (_selected_clientlist_item == i++) { // Selected item, highlight it
+ GfxFillRect(1, y, 248, y + CLNWND_ROWSIZE - 1, 0);
+ colour = 0xC;
+ } else {
+ colour = 0x10;
+ }
+
+ if (ci->client_index == NETWORK_SERVER_INDEX) {
+ DrawString(4, y, STR_NETWORK_SERVER, colour);
+ } else {
+ DrawString(4, y, STR_NETWORK_CLIENT, colour);
+ }
+
+ // Filter out spectators
+ if (IsValidPlayer(ci->client_playas)) DrawPlayerIcon(ci->client_playas, 64, y + 1);
+
+ DoDrawString(ci->client_name, 81, y, colour);
+
+ y += CLNWND_ROWSIZE;
+ }
+ } break;
+
+ case WE_CLICK:
+ // Show the popup with option
+ if (_selected_clientlist_item != 255) {
+ PopupClientList(w, _selected_clientlist_item, e->we.click.pt.x + w->left, e->we.click.pt.y + w->top);
+ }
+
+ break;
+
+ case WE_MOUSEOVER:
+ // -1 means we left the current window
+ if (e->we.mouseover.pt.y == -1) {
+ _selected_clientlist_y = 0;
+ _selected_clientlist_item = 255;
+ SetWindowDirty(w);
+ break;
+ }
+ // It did not change.. no update!
+ if (e->we.mouseover.pt.y == _selected_clientlist_y) break;
+
+ // Find the new selected item (if any)
+ _selected_clientlist_y = e->we.mouseover.pt.y;
+ if (e->we.mouseover.pt.y > CLNWND_OFFSET) {
+ _selected_clientlist_item = (e->we.mouseover.pt.y - CLNWND_OFFSET) / CLNWND_ROWSIZE;
+ } else {
+ _selected_clientlist_item = 255;
+ }
+
+ // Repaint
+ SetWindowDirty(w);
+ break;
+
+ case WE_DESTROY: case WE_CREATE:
+ // When created or destroyed, data is reset
+ _selected_clientlist_item = 255;
+ _selected_clientlist_y = 0;
+ break;
+ }
+}
+
+void ShowClientList(void)
+{
+ AllocateWindowDescFront(&_client_list_desc, 0);
+}
+
+
+static NetworkPasswordType pw_type;
+
+
+void ShowNetworkNeedPassword(NetworkPasswordType npt)
+{
+ StringID caption;
+
+ pw_type = npt;
+ switch (npt) {
+ default: NOT_REACHED();
+ case NETWORK_GAME_PASSWORD: caption = STR_NETWORK_NEED_GAME_PASSWORD_CAPTION; break;
+ case NETWORK_COMPANY_PASSWORD: caption = STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION; break;
+ }
+ ShowQueryString(STR_EMPTY, caption, 20, 180, FindWindowById(WC_NETWORK_STATUS_WINDOW, 0), CS_ALPHANUMERAL);
+}
+
+
+static void NetworkJoinStatusWindowWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ uint8 progress; // used for progress bar
+ DrawWindowWidgets(w);
+
+ DrawStringCentered(125, 35, STR_NETWORK_CONNECTING_1 + _network_join_status, 14);
+ switch (_network_join_status) {
+ case NETWORK_JOIN_STATUS_CONNECTING: case NETWORK_JOIN_STATUS_AUTHORIZING:
+ case NETWORK_JOIN_STATUS_GETTING_COMPANY_INFO:
+ progress = 10; // first two stages 10%
+ break;
+ case NETWORK_JOIN_STATUS_WAITING:
+ SetDParam(0, _network_join_waiting);
+ DrawStringCentered(125, 46, STR_NETWORK_CONNECTING_WAITING, 14);
+ progress = 15; // third stage is 15%
+ break;
+ case NETWORK_JOIN_STATUS_DOWNLOADING:
+ SetDParam(0, _network_join_kbytes);
+ SetDParam(1, _network_join_kbytes_total);
+ DrawStringCentered(125, 46, STR_NETWORK_CONNECTING_DOWNLOADING, 14);
+ /* Fallthrough */
+ default: /* Waiting is 15%, so the resting receivement of map is maximum 70% */
+ progress = 15 + _network_join_kbytes * (100 - 15) / _network_join_kbytes_total;
+ }
+
+ /* Draw nice progress bar :) */
+ DrawFrameRect(20, 18, (int)((w->width - 20) * progress / 100), 28, 10, 0);
+ } break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 2: /* Disconnect button */
+ NetworkDisconnect();
+ DeleteWindow(w);
+ SwitchMode(SM_MENU);
+ ShowNetworkGameWindow();
+ break;
+ }
+ break;
+
+ /* If the server asks for a password, we need to fill it in */
+ case WE_ON_EDIT_TEXT_CANCEL:
+ NetworkDisconnect();
+ ShowNetworkGameWindow();
+ break;
+
+ case WE_ON_EDIT_TEXT:
+ SEND_COMMAND(PACKET_CLIENT_PASSWORD)(pw_type, e->we.edittext.str);
+ break;
+ }
+}
+
+static const Widget _network_join_status_window_widget[] = {
+{ WWT_CAPTION, RESIZE_NONE, 14, 0, 249, 0, 13, STR_NETWORK_CONNECTING, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 249, 14, 84, 0x0, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, BTC, 75, 175, 69, 80, STR_NETWORK_DISCONNECT, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _network_join_status_window_desc = {
+ WDP_CENTER, WDP_CENTER, 250, 85,
+ WC_NETWORK_STATUS_WINDOW, 0,
+ WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_MODAL,
+ _network_join_status_window_widget,
+ NetworkJoinStatusWindowWndProc,
+};
+
+void ShowJoinStatusWindow(void)
+{
+ Window *w;
+ DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
+ w = AllocateWindowDesc(&_network_join_status_window_desc);
+ /* Parent the status window to the lobby */
+ if (w != NULL) w->parent = FindWindowById(WC_NETWORK_WINDOW, 0);
+}
+
+static void SendChat(const char *buf, DestType type, byte dest)
+{
+ if (buf[0] == '\0') return;
+ if (!_network_server) {
+ SEND_COMMAND(PACKET_CLIENT_CHAT)(NETWORK_ACTION_CHAT + type, type, dest, buf);
+ } else {
+ NetworkServer_HandleChat(NETWORK_ACTION_CHAT + type, type, dest, buf, NETWORK_SERVER_INDEX);
+ }
+}
+
+/**
+ * Find the next item of the list of things that can be auto-completed.
+ * @param item The current indexed item to return. This function can, and most
+ * likely will, alter item, to skip empty items in the arrays.
+ * @return Returns the char that matched to the index.
+ */
+static const char *ChatTabCompletionNextItem(uint *item)
+{
+ static char chat_tab_temp_buffer[64];
+
+ /* First, try clients */
+ if (*item < MAX_CLIENT_INFO) {
+ /* Skip inactive clients */
+ while (_network_client_info[*item].client_index == NETWORK_EMPTY_INDEX && *item < MAX_CLIENT_INFO) (*item)++;
+ if (*item < MAX_CLIENT_INFO) return _network_client_info[*item].client_name;
+ }
+
+ /* Then, try townnames */
+ /* Not that the following assumes all town indices are adjacent, ie no
+ * towns have been deleted. */
+ if (*item <= (uint)MAX_CLIENT_INFO + GetMaxTownIndex()) {
+ const Town *t;
+
+ FOR_ALL_TOWNS_FROM(t, *item - MAX_CLIENT_INFO) {
+ /* Get the town-name via the string-system */
+ SetDParam(0, t->townnameparts);
+ GetString(chat_tab_temp_buffer, t->townnametype, lastof(chat_tab_temp_buffer));
+ return &chat_tab_temp_buffer[0];
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * Find what text to complete. It scans for a space from the left and marks
+ * the word right from that as to complete. It also writes a \0 at the
+ * position of the space (if any). If nothing found, buf is returned.
+ */
+static char *ChatTabCompletionFindText(char *buf)
+{
+ char *p = strrchr(buf, ' ');
+ if (p == NULL) return buf;
+
+ *p = '\0';
+ return p + 1;
+}
+
+/**
+ * See if we can auto-complete the current text of the user.
+ */
+static void ChatTabCompletion(Window *w)
+{
+ static char _chat_tab_completion_buf[lengthof(_edit_str_buf)];
+ Textbuf *tb = &WP(w, querystr_d).text;
+ uint len, tb_len;
+ uint item;
+ char *tb_buf, *pre_buf;
+ const char *cur_name;
+ bool second_scan = false;
+
+ item = 0;
+
+ /* Copy the buffer so we can modify it without damaging the real data */
+ pre_buf = (_chat_tab_completion_active) ? strdup(_chat_tab_completion_buf) : strdup(tb->buf);
+
+ tb_buf = ChatTabCompletionFindText(pre_buf);
+ tb_len = strlen(tb_buf);
+
+ while ((cur_name = ChatTabCompletionNextItem(&item)) != NULL) {
+ item++;
+
+ if (_chat_tab_completion_active) {
+ /* We are pressing TAB again on the same name, is there an other name
+ * that starts with this? */
+ if (!second_scan) {
+ uint offset;
+ uint length;
+
+ /* If we are completing at the begin of the line, skip the ': ' we added */
+ if (tb_buf == pre_buf) {
+ offset = 0;
+ length = tb->length - 2;
+ } else {
+ /* Else, find the place we are completing at */
+ offset = strlen(pre_buf) + 1;
+ length = tb->length - offset;
+ }
+
+ /* Compare if we have a match */
+ if (strlen(cur_name) == length && strncmp(cur_name, tb->buf + offset, length) == 0) second_scan = true;
+
+ continue;
+ }
+
+ /* Now any match we make on _chat_tab_completion_buf after this, is perfect */
+ }
+
+ len = strlen(cur_name);
+ if (tb_len < len && strncasecmp(cur_name, tb_buf, tb_len) == 0) {
+ /* Save the data it was before completion */
+ if (!second_scan) snprintf(_chat_tab_completion_buf, lengthof(_chat_tab_completion_buf), "%s", tb->buf);
+ _chat_tab_completion_active = true;
+
+ /* Change to the found name. Add ': ' if we are at the start of the line (pretty) */
+ if (pre_buf == tb_buf) {
+ snprintf(tb->buf, lengthof(_edit_str_buf), "%s: ", cur_name);
+ } else {
+ snprintf(tb->buf, lengthof(_edit_str_buf), "%s %s", pre_buf, cur_name);
+ }
+
+ /* Update the textbuffer */
+ UpdateTextBufferSize(&WP(w, querystr_d).text);
+
+ SetWindowDirty(w);
+ free(pre_buf);
+ return;
+ }
+ }
+
+ if (second_scan) {
+ /* We walked all posibilities, and the user presses tab again.. revert to original text */
+ strcpy(tb->buf, _chat_tab_completion_buf);
+ _chat_tab_completion_active = false;
+
+ /* Update the textbuffer */
+ UpdateTextBufferSize(&WP(w, querystr_d).text);
+
+ SetWindowDirty(w);
+ }
+ free(pre_buf);
+}
+
+/* uses querystr_d WP macro
+ * uses querystr_d->caption to store
+ * - type of chat message (Private/Team/All) in bytes 0-7
+ * - destination of chat message in the case of Team/Private in bytes 8-15 */
+static void ChatWindowWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_CREATE:
+ SendWindowMessage(WC_NEWS_WINDOW, 0, WE_CREATE, w->height, 0);
+ SETBIT(_no_scroll, SCROLL_CHAT); // do not scroll the game with the arrow-keys
+ break;
+
+ case WE_PAINT: {
+ static const StringID chat_captions[] = {
+ STR_NETWORK_CHAT_ALL_CAPTION,
+ STR_NETWORK_CHAT_COMPANY_CAPTION,
+ STR_NETWORK_CHAT_CLIENT_CAPTION
+ };
+ StringID msg;
+
+ DrawWindowWidgets(w);
+
+ assert(GB(WP(w, querystr_d).caption, 0, 8) < lengthof(chat_captions));
+ msg = chat_captions[GB(WP(w, querystr_d).caption, 0, 8)];
+ DrawStringRightAligned(w->widget[2].left - 2, w->widget[2].top + 1, msg, 16);
+ DrawEditBox(w, &WP(w, querystr_d), 2);
+ } break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 3: { /* Send */
+ DestType type = GB(WP(w, querystr_d).caption, 0, 8);
+ byte dest = GB(WP(w, querystr_d).caption, 8, 8);
+ SendChat(WP(w, querystr_d).text.buf, type, dest);
+ } /* FALLTHROUGH */
+ case 0: /* Cancel */ DeleteWindow(w); break;
+ }
+ break;
+
+ case WE_MOUSELOOP:
+ HandleEditBox(w, &WP(w, querystr_d), 2);
+ break;
+
+ case WE_KEYPRESS:
+ if (e->we.keypress.keycode == WKC_TAB) {
+ ChatTabCompletion(w);
+ } else {
+ _chat_tab_completion_active = false;
+ switch (HandleEditBoxKey(w, &WP(w, querystr_d), 2, e)) {
+ case 1: { /* Return */
+ DestType type = GB(WP(w, querystr_d).caption, 0, 8);
+ byte dest = GB(WP(w, querystr_d).caption, 8, 8);
+ SendChat(WP(w, querystr_d).text.buf, type, dest);
+ } /* FALLTHROUGH */
+ case 2: /* Escape */ DeleteWindow(w); break;
+ }
+ }
+ break;
+
+ case WE_DESTROY:
+ SendWindowMessage(WC_NEWS_WINDOW, 0, WE_DESTROY, 0, 0);
+ CLRBIT(_no_scroll, SCROLL_CHAT);
+ break;
+ }
+}
+
+static const Widget _chat_window_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_PANEL, RESIZE_NONE, 14, 11, 639, 0, 13, 0x0, STR_NULL}, // background
+{ WWT_PANEL, RESIZE_NONE, 14, 75, 577, 1, 12, 0x0, STR_NULL}, // text box
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 578, 639, 1, 12, STR_NETWORK_SEND, STR_NULL}, // send button
+{ WIDGETS_END},
+};
+
+static const WindowDesc _chat_window_desc = {
+ WDP_CENTER, -26, 640, 14, // x, y, width, height
+ WC_SEND_NETWORK_MSG,0,
+ WDF_STD_TOOLTIPS | WDF_DEF_WIDGET,
+ _chat_window_widgets,
+ ChatWindowWndProc
+};
+
+void ShowNetworkChatQueryWindow(DestType type, byte dest)
+{
+ Window *w;
+
+ DeleteWindowById(WC_SEND_NETWORK_MSG, 0);
+
+ _edit_str_buf[0] = '\0';
+ _chat_tab_completion_active = false;
+
+ w = AllocateWindowDesc(&_chat_window_desc);
+
+ LowerWindowWidget(w, 2);
+ WP(w, querystr_d).caption = GB(type, 0, 8) | (dest << 8); // Misuse of caption
+ WP(w, querystr_d).afilter = CS_ALPHANUMERAL;
+ InitializeTextBuffer(&WP(w, querystr_d).text, _edit_str_buf, lengthof(_edit_str_buf), 0);
+}
+
+#endif /* ENABLE_NETWORK */
diff --git a/src/network/network_gui.h b/src/network/network_gui.h
new file mode 100644
index 000000000..aa4313eba
--- /dev/null
+++ b/src/network/network_gui.h
@@ -0,0 +1,26 @@
+/* $Id$ */
+
+#ifndef NETWORK_GUI_H
+#define NETWORK_GUI_H
+
+#ifdef ENABLE_NETWORK
+
+#include "network_data.h"
+
+void ShowNetworkNeedPassword(NetworkPasswordType npt);
+void ShowNetworkGiveMoneyWindow(byte player); // PlayerID
+void ShowNetworkChatQueryWindow(DestType type, byte dest);
+void ShowJoinStatusWindow(void);
+void ShowNetworkGameWindow(void);
+void ShowClientList(void);
+
+#else /* ENABLE_NETWORK */
+/* Network function stubs when networking is disabled */
+
+static inline void ShowNetworkChatQueryWindow(byte desttype, byte dest) {}
+static inline void ShowClientList(void) {}
+static inline void ShowNetworkGameWindow(void) {}
+
+#endif /* ENABLE_NETWORK */
+
+#endif /* NETWORK_GUI_H */
diff --git a/src/network/network_server.c b/src/network/network_server.c
new file mode 100644
index 000000000..5a7109105
--- /dev/null
+++ b/src/network/network_server.c
@@ -0,0 +1,1528 @@
+/* $Id$ */
+
+#ifdef ENABLE_NETWORK
+
+#include "../stdafx.h"
+#include "../openttd.h" // XXX StringID
+#include "../debug.h"
+#include "../string.h"
+#include "../strings.h"
+#include "network_data.h"
+#include "core/tcp.h"
+#include "../train.h"
+#include "../date.h"
+#include "table/strings.h"
+#include "../functions.h"
+#include "network_server.h"
+#include "network_udp.h"
+#include "../console.h"
+#include "../command.h"
+#include "../saveload.h"
+#include "../vehicle.h"
+#include "../station.h"
+#include "../variables.h"
+#include "../genworld.h"
+
+// This file handles all the server-commands
+
+static void NetworkHandleCommandQueue(NetworkClientState* cs);
+
+// **********
+// Sending functions
+// DEF_SERVER_SEND_COMMAND has parameter: NetworkClientState *cs
+// **********
+
+DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_CLIENT_INFO)(NetworkClientState *cs, NetworkClientInfo *ci)
+{
+ //
+ // Packet: SERVER_CLIENT_INFO
+ // Function: Sends info about a client
+ // Data:
+ // uint16: The index of the client (always unique on a server. 1 = server)
+ // uint8: As which player the client is playing
+ // String: The name of the client
+ // String: The unique id of the client
+ //
+
+ if (ci->client_index != NETWORK_EMPTY_INDEX) {
+ Packet *p = NetworkSend_Init(PACKET_SERVER_CLIENT_INFO);
+ NetworkSend_uint16(p, ci->client_index);
+ NetworkSend_uint8 (p, ci->client_playas);
+ NetworkSend_string(p, ci->client_name);
+ NetworkSend_string(p, ci->unique_id);
+
+ NetworkSend_Packet(p, cs);
+ }
+}
+
+DEF_SERVER_SEND_COMMAND(PACKET_SERVER_COMPANY_INFO)
+{
+//
+ // Packet: SERVER_COMPANY_INFO
+ // Function: Sends info about the companies
+ // Data:
+ //
+
+ int i;
+
+ Player *player;
+ Packet *p;
+
+ byte active = ActivePlayerCount();
+
+ if (active == 0) {
+ p = NetworkSend_Init(PACKET_SERVER_COMPANY_INFO);
+
+ NetworkSend_uint8 (p, NETWORK_COMPANY_INFO_VERSION);
+ NetworkSend_uint8 (p, active);
+
+ NetworkSend_Packet(p, cs);
+ return;
+ }
+
+ NetworkPopulateCompanyInfo();
+
+ FOR_ALL_PLAYERS(player) {
+ if (!player->is_active) continue;
+
+ p = NetworkSend_Init(PACKET_SERVER_COMPANY_INFO);
+
+ NetworkSend_uint8 (p, NETWORK_COMPANY_INFO_VERSION);
+ NetworkSend_uint8 (p, active);
+ NetworkSend_uint8 (p, player->index);
+
+ NetworkSend_string(p, _network_player_info[player->index].company_name);
+ NetworkSend_uint32(p, _network_player_info[player->index].inaugurated_year);
+ NetworkSend_uint64(p, _network_player_info[player->index].company_value);
+ NetworkSend_uint64(p, _network_player_info[player->index].money);
+ NetworkSend_uint64(p, _network_player_info[player->index].income);
+ NetworkSend_uint16(p, _network_player_info[player->index].performance);
+
+ /* Send 1 if there is a passord for the company else send 0 */
+ if (_network_player_info[player->index].password[0] != '\0') {
+ NetworkSend_uint8(p, 1);
+ } else {
+ NetworkSend_uint8(p, 0);
+ }
+
+ for (i = 0; i < NETWORK_VEHICLE_TYPES; i++) {
+ NetworkSend_uint16(p, _network_player_info[player->index].num_vehicle[i]);
+ }
+
+ for (i = 0; i < NETWORK_STATION_TYPES; i++) {
+ NetworkSend_uint16(p, _network_player_info[player->index].num_station[i]);
+ }
+
+ if (_network_player_info[player->index].players[0] == '\0') {
+ NetworkSend_string(p, "<none>");
+ } else {
+ NetworkSend_string(p, _network_player_info[player->index].players);
+ }
+
+ NetworkSend_Packet(p, cs);
+ }
+
+ p = NetworkSend_Init(PACKET_SERVER_COMPANY_INFO);
+
+ NetworkSend_uint8 (p, NETWORK_COMPANY_INFO_VERSION);
+ NetworkSend_uint8 (p, 0);
+
+ NetworkSend_Packet(p, cs);
+}
+
+DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR)(NetworkClientState *cs, NetworkErrorCode error)
+{
+ //
+ // Packet: SERVER_ERROR
+ // Function: The client made an error
+ // Data:
+ // uint8: ErrorID (see network_data.h, NetworkErrorCode)
+ //
+
+ char str[100];
+ Packet *p = NetworkSend_Init(PACKET_SERVER_ERROR);
+
+ NetworkSend_uint8(p, error);
+ NetworkSend_Packet(p, cs);
+
+ GetNetworkErrorMsg(str, error, lastof(str));
+
+ // Only send when the current client was in game
+ if (cs->status > STATUS_AUTH) {
+ NetworkClientState *new_cs;
+ char client_name[NETWORK_CLIENT_NAME_LENGTH];
+
+ NetworkGetClientName(client_name, sizeof(client_name), cs);
+
+ DEBUG(net, 1, "'%s' made an error and has been disconnected. Reason: '%s'", client_name, str);
+
+ NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, client_name, "%s", str);
+
+ FOR_ALL_CLIENTS(new_cs) {
+ if (new_cs->status > STATUS_AUTH && new_cs != cs) {
+ // Some errors we filter to a more general error. Clients don't have to know the real
+ // reason a joining failed.
+ if (error == NETWORK_ERROR_NOT_AUTHORIZED || error == NETWORK_ERROR_NOT_EXPECTED || error == NETWORK_ERROR_WRONG_REVISION)
+ error = NETWORK_ERROR_ILLEGAL_PACKET;
+
+ SEND_COMMAND(PACKET_SERVER_ERROR_QUIT)(new_cs, cs->index, error);
+ }
+ }
+ } else {
+ DEBUG(net, 1, "Client %d made an error and has been disconnected. Reason: '%s'", cs->index, str);
+ }
+
+ cs->has_quit = true;
+
+ // Make sure the data get's there before we close the connection
+ NetworkSend_Packets(cs);
+
+ // The client made a mistake, so drop his connection now!
+ NetworkCloseClient(cs);
+}
+
+DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_NEED_PASSWORD)(NetworkClientState *cs, NetworkPasswordType type)
+{
+ //
+ // Packet: SERVER_NEED_PASSWORD
+ // Function: Indication to the client that the server needs a password
+ // Data:
+ // uint8: Type of password
+ //
+
+ Packet *p = NetworkSend_Init(PACKET_SERVER_NEED_PASSWORD);
+ NetworkSend_uint8(p, type);
+ NetworkSend_Packet(p, cs);
+}
+
+DEF_SERVER_SEND_COMMAND(PACKET_SERVER_WELCOME)
+{
+ //
+ // Packet: SERVER_WELCOME
+ // Function: The client is joined and ready to receive his map
+ // Data:
+ // uint16: Own ClientID
+ //
+
+ Packet *p;
+ const NetworkClientState *new_cs;
+
+ // Invalid packet when status is AUTH or higher
+ if (cs->status >= STATUS_AUTH) return;
+
+ cs->status = STATUS_AUTH;
+ _network_game_info.clients_on++;
+
+ p = NetworkSend_Init(PACKET_SERVER_WELCOME);
+ NetworkSend_uint16(p, cs->index);
+ NetworkSend_Packet(p, cs);
+
+ // Transmit info about all the active clients
+ FOR_ALL_CLIENTS(new_cs) {
+ if (new_cs != cs && new_cs->status > STATUS_AUTH)
+ SEND_COMMAND(PACKET_SERVER_CLIENT_INFO)(cs, DEREF_CLIENT_INFO(new_cs));
+ }
+ // Also send the info of the server
+ SEND_COMMAND(PACKET_SERVER_CLIENT_INFO)(cs, NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX));
+}
+
+DEF_SERVER_SEND_COMMAND(PACKET_SERVER_WAIT)
+{
+ //
+ // Packet: PACKET_SERVER_WAIT
+ // Function: The client can not receive the map at the moment because
+ // someone else is already receiving the map
+ // Data:
+ // uint8: Clients awaiting map
+ //
+ int waiting = 0;
+ NetworkClientState *new_cs;
+ Packet *p;
+
+ // Count how many players are waiting in the queue
+ FOR_ALL_CLIENTS(new_cs) {
+ if (new_cs->status == STATUS_MAP_WAIT) waiting++;
+ }
+
+ p = NetworkSend_Init(PACKET_SERVER_WAIT);
+ NetworkSend_uint8(p, waiting);
+ NetworkSend_Packet(p, cs);
+}
+
+// This sends the map to the client
+DEF_SERVER_SEND_COMMAND(PACKET_SERVER_MAP)
+{
+ //
+ // Packet: SERVER_MAP
+ // Function: Sends the map to the client, or a part of it (it is splitted in
+ // a lot of multiple packets)
+ // Data:
+ // uint8: packet-type (MAP_PACKET_START, MAP_PACKET_NORMAL and MAP_PACKET_END)
+ // if MAP_PACKET_START:
+ // uint32: The current FrameCounter
+ // if MAP_PACKET_NORMAL:
+ // piece of the map (till max-size of packet)
+ // if MAP_PACKET_END:
+ // uint32: seed0 of player
+ // uint32: seed1 of player
+ // last 2 are repeated MAX_PLAYERS time
+ //
+
+ static FILE *file_pointer;
+ static uint sent_packets; // How many packets we did send succecfully last time
+
+ if (cs->status < STATUS_AUTH) {
+ // Illegal call, return error and ignore the packet
+ SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_AUTHORIZED);
+ return;
+ }
+
+ if (cs->status == STATUS_AUTH) {
+ char filename[256];
+ Packet *p;
+
+ // Make a dump of the current game
+ snprintf(filename, lengthof(filename), "%s%snetwork_server.tmp", _paths.autosave_dir, PATHSEP);
+ if (SaveOrLoad(filename, SL_SAVE) != SL_OK) error("network savedump failed");
+
+ file_pointer = fopen(filename, "rb");
+ fseek(file_pointer, 0, SEEK_END);
+
+ // Now send the _frame_counter and how many packets are coming
+ p = NetworkSend_Init(PACKET_SERVER_MAP);
+ NetworkSend_uint8(p, MAP_PACKET_START);
+ NetworkSend_uint32(p, _frame_counter);
+ NetworkSend_uint32(p, ftell(file_pointer));
+ NetworkSend_Packet(p, cs);
+
+ fseek(file_pointer, 0, SEEK_SET);
+
+ sent_packets = 4; // We start with trying 4 packets
+
+ cs->status = STATUS_MAP;
+ /* Mark the start of download */
+ cs->last_frame = _frame_counter;
+ cs->last_frame_server = _frame_counter;
+ }
+
+ if (cs->status == STATUS_MAP) {
+ uint i;
+ int res;
+ for (i = 0; i < sent_packets; i++) {
+ Packet *p = NetworkSend_Init(PACKET_SERVER_MAP);
+ NetworkSend_uint8(p, MAP_PACKET_NORMAL);
+ res = (int)fread(p->buffer + p->size, 1, SEND_MTU - p->size, file_pointer);
+
+ if (ferror(file_pointer)) error("Error reading temporary network savegame!");
+
+ p->size += res;
+ NetworkSend_Packet(p, cs);
+ if (feof(file_pointer)) {
+ // Done reading!
+ Packet *p = NetworkSend_Init(PACKET_SERVER_MAP);
+ NetworkSend_uint8(p, MAP_PACKET_END);
+ NetworkSend_Packet(p, cs);
+
+ // Set the status to DONE_MAP, no we will wait for the client
+ // to send it is ready (maybe that happens like never ;))
+ cs->status = STATUS_DONE_MAP;
+ fclose(file_pointer);
+
+ {
+ NetworkClientState *new_cs;
+ bool new_map_client = false;
+ // Check if there is a client waiting for receiving the map
+ // and start sending him the map
+ FOR_ALL_CLIENTS(new_cs) {
+ if (new_cs->status == STATUS_MAP_WAIT) {
+ // Check if we already have a new client to send the map to
+ if (!new_map_client) {
+ // If not, this client will get the map
+ new_cs->status = STATUS_AUTH;
+ new_map_client = true;
+ SEND_COMMAND(PACKET_SERVER_MAP)(new_cs);
+ } else {
+ // Else, send the other clients how many clients are in front of them
+ SEND_COMMAND(PACKET_SERVER_WAIT)(new_cs);
+ }
+ }
+ }
+ }
+
+ // There is no more data, so break the for
+ break;
+ }
+ }
+
+ // Send all packets (forced) and check if we have send it all
+ NetworkSend_Packets(cs);
+ if (cs->packet_queue == NULL) {
+ // All are sent, increase the sent_packets
+ sent_packets *= 2;
+ } else {
+ // Not everything is sent, decrease the sent_packets
+ if (sent_packets > 1) sent_packets /= 2;
+ }
+ }
+}
+
+DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_JOIN)(NetworkClientState *cs, uint16 client_index)
+{
+ //
+ // Packet: SERVER_JOIN
+ // Function: A client is joined (all active clients receive this after a
+ // PACKET_CLIENT_MAP_OK) Mostly what directly follows is a
+ // PACKET_SERVER_CLIENT_INFO
+ // Data:
+ // uint16: Client-Index
+ //
+
+ Packet *p = NetworkSend_Init(PACKET_SERVER_JOIN);
+
+ NetworkSend_uint16(p, client_index);
+
+ NetworkSend_Packet(p, cs);
+}
+
+
+DEF_SERVER_SEND_COMMAND(PACKET_SERVER_FRAME)
+{
+ //
+ // Packet: SERVER_FRAME
+ // Function: Sends the current frame-counter to the client
+ // Data:
+ // uint32: Frame Counter
+ // uint32: Frame Counter Max (how far may the client walk before the server?)
+ // [uint32: general-seed-1]
+ // [uint32: general-seed-2]
+ // (last two depends on compile-settings, and are not default settings)
+ //
+
+ Packet *p = NetworkSend_Init(PACKET_SERVER_FRAME);
+ NetworkSend_uint32(p, _frame_counter);
+ NetworkSend_uint32(p, _frame_counter_max);
+#ifdef ENABLE_NETWORK_SYNC_EVERY_FRAME
+ NetworkSend_uint32(p, _sync_seed_1);
+#ifdef NETWORK_SEND_DOUBLE_SEED
+ NetworkSend_uint32(p, _sync_seed_2);
+#endif
+#endif
+ NetworkSend_Packet(p, cs);
+}
+
+DEF_SERVER_SEND_COMMAND(PACKET_SERVER_SYNC)
+{
+ //
+ // Packet: SERVER_SYNC
+ // Function: Sends a sync-check to the client
+ // Data:
+ // uint32: Frame Counter
+ // uint32: General-seed-1
+ // [uint32: general-seed-2]
+ // (last one depends on compile-settings, and are not default settings)
+ //
+
+ Packet *p = NetworkSend_Init(PACKET_SERVER_SYNC);
+ NetworkSend_uint32(p, _frame_counter);
+ NetworkSend_uint32(p, _sync_seed_1);
+
+#ifdef NETWORK_SEND_DOUBLE_SEED
+ NetworkSend_uint32(p, _sync_seed_2);
+#endif
+ NetworkSend_Packet(p, cs);
+}
+
+DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_COMMAND)(NetworkClientState *cs, CommandPacket *cp)
+{
+ //
+ // Packet: SERVER_COMMAND
+ // Function: Sends a DoCommand to the client
+ // Data:
+ // uint8: PlayerID (0..MAX_PLAYERS-1)
+ // uint32: CommandID (see command.h)
+ // uint32: P1 (free variables used in DoCommand)
+ // uint32: P2
+ // uint32: Tile
+ // string: text
+ // uint8: CallBackID (see callback_table.c)
+ // uint32: Frame of execution
+ //
+
+ Packet *p = NetworkSend_Init(PACKET_SERVER_COMMAND);
+
+ NetworkSend_uint8(p, cp->player);
+ NetworkSend_uint32(p, cp->cmd);
+ NetworkSend_uint32(p, cp->p1);
+ NetworkSend_uint32(p, cp->p2);
+ NetworkSend_uint32(p, cp->tile);
+ NetworkSend_string(p, cp->text);
+ NetworkSend_uint8(p, cp->callback);
+ NetworkSend_uint32(p, cp->frame);
+
+ NetworkSend_Packet(p, cs);
+}
+
+DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_CHAT)(NetworkClientState *cs, NetworkAction action, uint16 client_index, bool self_send, const char *msg)
+{
+ //
+ // Packet: SERVER_CHAT
+ // Function: Sends a chat-packet to the client
+ // Data:
+ // uint8: ActionID (see network_data.h, NetworkAction)
+ // uint16: Client-index
+ // String: Message (max MAX_TEXT_MSG_LEN)
+ //
+
+ Packet *p = NetworkSend_Init(PACKET_SERVER_CHAT);
+
+ NetworkSend_uint8(p, action);
+ NetworkSend_uint16(p, client_index);
+ NetworkSend_uint8(p, self_send);
+ NetworkSend_string(p, msg);
+
+ NetworkSend_Packet(p, cs);
+}
+
+DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR_QUIT)(NetworkClientState *cs, uint16 client_index, NetworkErrorCode errorno)
+{
+ //
+ // Packet: SERVER_ERROR_QUIT
+ // Function: One of the clients made an error and is quiting the game
+ // This packet informs the other clients of that.
+ // Data:
+ // uint16: Client-index
+ // uint8: ErrorID (see network_data.h, NetworkErrorCode)
+ //
+
+ Packet *p = NetworkSend_Init(PACKET_SERVER_ERROR_QUIT);
+
+ NetworkSend_uint16(p, client_index);
+ NetworkSend_uint8(p, errorno);
+
+ NetworkSend_Packet(p, cs);
+}
+
+DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_QUIT)(NetworkClientState *cs, uint16 client_index, const char *leavemsg)
+{
+ //
+ // Packet: SERVER_ERROR_QUIT
+ // Function: A client left the game, and this packets informs the other clients
+ // of that.
+ // Data:
+ // uint16: Client-index
+ // String: leave-message
+ //
+
+ Packet *p = NetworkSend_Init(PACKET_SERVER_QUIT);
+
+ NetworkSend_uint16(p, client_index);
+ NetworkSend_string(p, leavemsg);
+
+ NetworkSend_Packet(p, cs);
+}
+
+DEF_SERVER_SEND_COMMAND(PACKET_SERVER_SHUTDOWN)
+{
+ //
+ // Packet: SERVER_SHUTDOWN
+ // Function: Let the clients know that the server is closing
+ // Data:
+ // <none>
+ //
+
+ Packet *p = NetworkSend_Init(PACKET_SERVER_SHUTDOWN);
+ NetworkSend_Packet(p, cs);
+}
+
+DEF_SERVER_SEND_COMMAND(PACKET_SERVER_NEWGAME)
+{
+ //
+ // Packet: PACKET_SERVER_NEWGAME
+ // Function: Let the clients know that the server is loading a new map
+ // Data:
+ // <none>
+ //
+
+ Packet *p = NetworkSend_Init(PACKET_SERVER_NEWGAME);
+ NetworkSend_Packet(p, cs);
+}
+
+DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_RCON)(NetworkClientState *cs, uint16 color, const char *command)
+{
+ Packet *p = NetworkSend_Init(PACKET_SERVER_RCON);
+
+ NetworkSend_uint16(p, color);
+ NetworkSend_string(p, command);
+ NetworkSend_Packet(p, cs);
+}
+
+// **********
+// Receiving functions
+// DEF_SERVER_RECEIVE_COMMAND has parameter: NetworkClientState *cs, Packet *p
+// **********
+
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMPANY_INFO)
+{
+ SEND_COMMAND(PACKET_SERVER_COMPANY_INFO)(cs);
+}
+
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_JOIN)
+{
+ char name[NETWORK_CLIENT_NAME_LENGTH];
+ char unique_id[NETWORK_NAME_LENGTH];
+ NetworkClientInfo *ci;
+ byte playas;
+ NetworkLanguage client_lang;
+ char client_revision[NETWORK_REVISION_LENGTH];
+
+ NetworkRecv_string(cs, p, client_revision, sizeof(client_revision));
+
+#if defined(WITH_REV) || defined(WITH_REV_HACK)
+ // Check if the client has revision control enabled
+ if (strcmp(NOREV_STRING, client_revision) != 0 &&
+ strcmp(_network_game_info.server_revision, client_revision) != 0) {
+ // Different revisions!!
+ SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_WRONG_REVISION);
+ return;
+ }
+#endif
+
+ NetworkRecv_string(cs, p, name, sizeof(name));
+ playas = NetworkRecv_uint8(cs, p);
+ client_lang = NetworkRecv_uint8(cs, p);
+ NetworkRecv_string(cs, p, unique_id, sizeof(unique_id));
+
+ if (cs->has_quit) return;
+
+ // join another company does not affect these values
+ switch (playas) {
+ case PLAYER_NEW_COMPANY: /* New company */
+ if (ActivePlayerCount() >= _network_game_info.companies_max) {
+ SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_FULL);
+ return;
+ }
+ break;
+ case PLAYER_SPECTATOR: /* Spectator */
+ if (NetworkSpectatorCount() >= _network_game_info.spectators_max) {
+ SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_FULL);
+ return;
+ }
+ break;
+ default: /* Join another company (companies 1-8 (index 0-7)) */
+ if (!IsValidPlayer(playas)) {
+ SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_PLAYER_MISMATCH);
+ return;
+ }
+ break;
+ }
+
+ // We need a valid name.. make it Player
+ if (*name == '\0') ttd_strlcpy(name, "Player", sizeof(name));
+
+ if (!NetworkFindName(name)) { // Change name if duplicate
+ // We could not create a name for this player
+ SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NAME_IN_USE);
+ return;
+ }
+
+ ci = DEREF_CLIENT_INFO(cs);
+
+ ttd_strlcpy(ci->client_name, name, sizeof(ci->client_name));
+ ttd_strlcpy(ci->unique_id, unique_id, sizeof(ci->unique_id));
+ ci->client_playas = playas;
+ ci->client_lang = client_lang;
+
+ // We now want a password from the client
+ // else we do not allow him in!
+ if (_network_game_info.use_password) {
+ SEND_COMMAND(PACKET_SERVER_NEED_PASSWORD)(cs, NETWORK_GAME_PASSWORD);
+ } else {
+ if (IsValidPlayer(ci->client_playas) && _network_player_info[ci->client_playas].password[0] != '\0') {
+ SEND_COMMAND(PACKET_SERVER_NEED_PASSWORD)(cs, NETWORK_COMPANY_PASSWORD);
+ } else {
+ SEND_COMMAND(PACKET_SERVER_WELCOME)(cs);
+ }
+ }
+
+ /* Make sure companies to which people try to join are not autocleaned */
+ if (IsValidPlayer(playas)) _network_player_info[playas].months_empty = 0;
+}
+
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_PASSWORD)
+{
+ NetworkPasswordType type;
+ char password[NETWORK_PASSWORD_LENGTH];
+ const NetworkClientInfo *ci;
+
+ type = NetworkRecv_uint8(cs, p);
+ NetworkRecv_string(cs, p, password, sizeof(password));
+
+ if (cs->status == STATUS_INACTIVE && type == NETWORK_GAME_PASSWORD) {
+ // Check game-password
+ if (strcmp(password, _network_game_info.server_password) != 0) {
+ // Password is invalid
+ SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_WRONG_PASSWORD);
+ return;
+ }
+
+ ci = DEREF_CLIENT_INFO(cs);
+
+ if (IsValidPlayer(ci->client_playas) && _network_player_info[ci->client_playas].password[0] != '\0') {
+ SEND_COMMAND(PACKET_SERVER_NEED_PASSWORD)(cs, NETWORK_COMPANY_PASSWORD);
+ return;
+ }
+
+ // Valid password, allow user
+ SEND_COMMAND(PACKET_SERVER_WELCOME)(cs);
+ return;
+ } else if (cs->status == STATUS_INACTIVE && type == NETWORK_COMPANY_PASSWORD) {
+ ci = DEREF_CLIENT_INFO(cs);
+
+ if (strcmp(password, _network_player_info[ci->client_playas].password) != 0) {
+ // Password is invalid
+ SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_WRONG_PASSWORD);
+ return;
+ }
+
+ SEND_COMMAND(PACKET_SERVER_WELCOME)(cs);
+ return;
+ }
+
+
+ SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
+ return;
+}
+
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_GETMAP)
+{
+ const NetworkClientState *new_cs;
+
+ // The client was never joined.. so this is impossible, right?
+ // Ignore the packet, give the client a warning, and close his connection
+ if (cs->status < STATUS_AUTH || cs->has_quit) {
+ SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_AUTHORIZED);
+ return;
+ }
+
+ // Check if someone else is receiving the map
+ FOR_ALL_CLIENTS(new_cs) {
+ if (new_cs->status == STATUS_MAP) {
+ // Tell the new client to wait
+ cs->status = STATUS_MAP_WAIT;
+ SEND_COMMAND(PACKET_SERVER_WAIT)(cs);
+ return;
+ }
+ }
+
+ // We receive a request to upload the map.. give it to the client!
+ SEND_COMMAND(PACKET_SERVER_MAP)(cs);
+}
+
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_MAP_OK)
+{
+ // Client has the map, now start syncing
+ if (cs->status == STATUS_DONE_MAP && !cs->has_quit) {
+ char client_name[NETWORK_CLIENT_NAME_LENGTH];
+ NetworkClientState *new_cs;
+
+ NetworkGetClientName(client_name, sizeof(client_name), cs);
+
+ NetworkTextMessage(NETWORK_ACTION_JOIN, 1, false, client_name, "");
+
+ // Mark the client as pre-active, and wait for an ACK
+ // so we know he is done loading and in sync with us
+ cs->status = STATUS_PRE_ACTIVE;
+ NetworkHandleCommandQueue(cs);
+ SEND_COMMAND(PACKET_SERVER_FRAME)(cs);
+ SEND_COMMAND(PACKET_SERVER_SYNC)(cs);
+
+ // This is the frame the client receives
+ // we need it later on to make sure the client is not too slow
+ cs->last_frame = _frame_counter;
+ cs->last_frame_server = _frame_counter;
+
+ FOR_ALL_CLIENTS(new_cs) {
+ if (new_cs->status > STATUS_AUTH) {
+ SEND_COMMAND(PACKET_SERVER_CLIENT_INFO)(new_cs, DEREF_CLIENT_INFO(cs));
+ SEND_COMMAND(PACKET_SERVER_JOIN)(new_cs, cs->index);
+ }
+ }
+
+ if (_network_pause_on_join) {
+ /* Now pause the game till the client is in sync */
+ DoCommandP(0, 1, 0, NULL, CMD_PAUSE);
+
+ NetworkServer_HandleChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game paused (incoming client)", NETWORK_SERVER_INDEX);
+ }
+ } else {
+ // Wrong status for this packet, give a warning to client, and close connection
+ SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
+ }
+}
+
+/** Enforce the command flags.
+ * Eg a server-only command can only be executed by a server, etc.
+ * @param *cp the commandpacket that is going to be checked
+ * @param *ci client information for debugging output to console
+ */
+static bool CheckCommandFlags(const CommandPacket *cp, const NetworkClientInfo *ci)
+{
+ byte flags = GetCommandFlags(cp->cmd);
+
+ if (flags & CMD_SERVER && ci->client_index != NETWORK_SERVER_INDEX) {
+ IConsolePrintF(_icolour_err, "WARNING: server only command from client %d (IP: %s), kicking...", ci->client_index, GetPlayerIP(ci));
+ return false;
+ }
+
+ if (flags & CMD_OFFLINE) {
+ IConsolePrintF(_icolour_err, "WARNING: offline only command from client %d (IP: %s), kicking...", ci->client_index, GetPlayerIP(ci));
+ return false;
+ }
+
+ return true;
+}
+
+/** The client has done a command and wants us to handle it
+ * @param *cs the connected client that has sent the command
+ * @param *p the packet in which the command was sent
+ */
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND)
+{
+ NetworkClientState *new_cs;
+ const NetworkClientInfo *ci;
+ byte callback;
+
+ CommandPacket *cp = malloc(sizeof(CommandPacket));
+
+ // The client was never joined.. so this is impossible, right?
+ // Ignore the packet, give the client a warning, and close his connection
+ if (cs->status < STATUS_DONE_MAP || cs->has_quit) {
+ SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
+ return;
+ }
+
+ cp->player = NetworkRecv_uint8(cs, p);
+ cp->cmd = NetworkRecv_uint32(cs, p);
+ cp->p1 = NetworkRecv_uint32(cs, p);
+ cp->p2 = NetworkRecv_uint32(cs, p);
+ cp->tile = NetworkRecv_uint32(cs, p);
+ NetworkRecv_string(cs, p, cp->text, lengthof(cp->text));
+
+ callback = NetworkRecv_uint8(cs, p);
+
+ if (cs->has_quit) return;
+
+ ci = DEREF_CLIENT_INFO(cs);
+
+ /* Check if cp->cmd is valid */
+ if (!IsValidCommand(cp->cmd)) {
+ IConsolePrintF(_icolour_err, "WARNING: invalid command from client %d (IP: %s).", ci->client_index, GetPlayerIP(ci));
+ SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
+ return;
+ }
+
+ if (!CheckCommandFlags(cp, ci)) {
+ SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_KICKED);
+ return;
+ }
+
+ /** Only CMD_PLAYER_CTRL is always allowed, for the rest, playas needs
+ * to match the player in the packet. If it doesn't, the client has done
+ * something pretty naughty (or a bug), and will be kicked
+ */
+ if (!(cp->cmd == CMD_PLAYER_CTRL && cp->p1 == 0) && ci->client_playas != cp->player) {
+ IConsolePrintF(_icolour_err, "WARNING: player %d (IP: %s) tried to execute a command as player %d, kicking...",
+ ci->client_playas + 1, GetPlayerIP(ci), cp->player + 1);
+ SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_PLAYER_MISMATCH);
+ return;
+ }
+
+ /** @todo CMD_PLAYER_CTRL with p1 = 0 announces a new player to the server. To give the
+ * player the correct ID, the server injects p2 and executes the command. Any other p1
+ * is prohibited. Pretty ugly and should be redone together with its function.
+ * @see CmdPlayerCtrl() players.c:655
+ */
+ if (cp->cmd == CMD_PLAYER_CTRL) {
+ if (cp->p1 != 0) {
+ SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_CHEATER);
+ return;
+ }
+
+ /* XXX - Execute the command as a valid player. Normally this would be done by a
+ * spectator, but that is not allowed any commands. So do an impersonation. The drawback
+ * of this is that the first company's last_built_tile is also updated... */
+ cp->player = 0;
+ cp->p2 = cs - _clients; // XXX - UGLY! p2 is mis-used to get the client-id in CmdPlayerCtrl
+ }
+
+ // The frame can be executed in the same frame as the next frame-packet
+ // That frame just before that frame is saved in _frame_counter_max
+ cp->frame = _frame_counter_max + 1;
+ cp->next = NULL;
+
+ // Queue the command for the clients (are send at the end of the frame
+ // if they can handle it ;))
+ FOR_ALL_CLIENTS(new_cs) {
+ if (new_cs->status >= STATUS_MAP) {
+ // Callbacks are only send back to the client who sent them in the
+ // first place. This filters that out.
+ cp->callback = (new_cs != cs) ? 0 : callback;
+ NetworkAddCommandQueue(new_cs, cp);
+ }
+ }
+
+ cp->callback = 0;
+ // Queue the command on the server
+ if (_local_command_queue == NULL) {
+ _local_command_queue = cp;
+ } else {
+ // Find last packet
+ CommandPacket *c = _local_command_queue;
+ while (c->next != NULL) c = c->next;
+ c->next = cp;
+ }
+}
+
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_ERROR)
+{
+ // This packets means a client noticed an error and is reporting this
+ // to us. Display the error and report it to the other clients
+ NetworkClientState *new_cs;
+ char str[100];
+ char client_name[NETWORK_CLIENT_NAME_LENGTH];
+ NetworkErrorCode errorno = NetworkRecv_uint8(cs, p);
+
+ // The client was never joined.. thank the client for the packet, but ignore it
+ if (cs->status < STATUS_DONE_MAP || cs->has_quit) {
+ cs->has_quit = true;
+ return;
+ }
+
+ NetworkGetClientName(client_name, sizeof(client_name), cs);
+
+ GetNetworkErrorMsg(str, errorno, lastof(str));
+
+ DEBUG(net, 2, "'%s' reported an error and is closing its connection (%s)", client_name, str);
+
+ NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, client_name, "%s", str);
+
+ FOR_ALL_CLIENTS(new_cs) {
+ if (new_cs->status > STATUS_AUTH) {
+ SEND_COMMAND(PACKET_SERVER_ERROR_QUIT)(new_cs, cs->index, errorno);
+ }
+ }
+
+ cs->has_quit = true;
+}
+
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_QUIT)
+{
+ // The client wants to leave. Display this and report it to the other
+ // clients.
+ NetworkClientState *new_cs;
+ char str[100];
+ char client_name[NETWORK_CLIENT_NAME_LENGTH];
+
+ // The client was never joined.. thank the client for the packet, but ignore it
+ if (cs->status < STATUS_DONE_MAP || cs->has_quit) {
+ cs->has_quit = true;
+ return;
+ }
+
+ NetworkRecv_string(cs, p, str, lengthof(str));
+
+ NetworkGetClientName(client_name, sizeof(client_name), cs);
+
+ NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, client_name, "%s", str);
+
+ FOR_ALL_CLIENTS(new_cs) {
+ if (new_cs->status > STATUS_AUTH) {
+ SEND_COMMAND(PACKET_SERVER_QUIT)(new_cs, cs->index, str);
+ }
+ }
+
+ cs->has_quit = true;
+}
+
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_ACK)
+{
+ uint32 frame = NetworkRecv_uint32(cs, p);
+
+ /* The client is trying to catch up with the server */
+ if (cs->status == STATUS_PRE_ACTIVE) {
+ /* The client is not yet catched up? */
+ if (frame + DAY_TICKS < _frame_counter) return;
+
+ /* Now he is! Unpause the game */
+ cs->status = STATUS_ACTIVE;
+
+ if (_network_pause_on_join) {
+ DoCommandP(0, 0, 0, NULL, CMD_PAUSE);
+ NetworkServer_HandleChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game unpaused (client connected)", NETWORK_SERVER_INDEX);
+ }
+
+ CheckMinPlayers();
+
+ /* Execute script for, e.g. MOTD */
+ IConsoleCmdExec("exec scripts/on_server_connect.scr 0");
+ }
+
+ // The client received the frame, make note of it
+ cs->last_frame = frame;
+ // With those 2 values we can calculate the lag realtime
+ cs->last_frame_server = _frame_counter;
+}
+
+
+
+void NetworkServer_HandleChat(NetworkAction action, DestType desttype, int dest, const char *msg, uint16 from_index)
+{
+ NetworkClientState *cs;
+ const NetworkClientInfo *ci, *ci_own, *ci_to;
+
+ switch (desttype) {
+ case DESTTYPE_CLIENT:
+ /* Are we sending to the server? */
+ if (dest == NETWORK_SERVER_INDEX) {
+ ci = NetworkFindClientInfoFromIndex(from_index);
+ /* Display the text locally, and that is it */
+ if (ci != NULL)
+ NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas), false, ci->client_name, "%s", msg);
+ } else {
+ /* Else find the client to send the message to */
+ FOR_ALL_CLIENTS(cs) {
+ if (cs->index == dest) {
+ SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, from_index, false, msg);
+ break;
+ }
+ }
+ }
+
+ // Display the message locally (so you know you have sent it)
+ if (from_index != dest) {
+ if (from_index == NETWORK_SERVER_INDEX) {
+ ci = NetworkFindClientInfoFromIndex(from_index);
+ ci_to = NetworkFindClientInfoFromIndex(dest);
+ if (ci != NULL && ci_to != NULL)
+ NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas), true, ci_to->client_name, "%s", msg);
+ } else {
+ FOR_ALL_CLIENTS(cs) {
+ if (cs->index == from_index) {
+ SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, dest, true, msg);
+ break;
+ }
+ }
+ }
+ }
+ break;
+ case DESTTYPE_TEAM: {
+ bool show_local = true; // If this is false, the message is already displayed
+ // on the client who did sent it.
+ /* Find all clients that belong to this player */
+ ci_to = NULL;
+ FOR_ALL_CLIENTS(cs) {
+ ci = DEREF_CLIENT_INFO(cs);
+ if (ci->client_playas == dest) {
+ SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, from_index, false, msg);
+ if (cs->index == from_index) show_local = false;
+ ci_to = ci; // Remember a client that is in the company for company-name
+ }
+ }
+
+ ci = NetworkFindClientInfoFromIndex(from_index);
+ ci_own = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
+ if (ci != NULL && ci_own != NULL && ci_own->client_playas == dest) {
+ NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas), false, ci->client_name, "%s", msg);
+ if (from_index == NETWORK_SERVER_INDEX) show_local = false;
+ ci_to = ci_own;
+ }
+
+ /* There is no such player */
+ if (ci_to == NULL) break;
+
+ // Display the message locally (so you know you have sent it)
+ if (ci != NULL && show_local) {
+ if (from_index == NETWORK_SERVER_INDEX) {
+ char name[NETWORK_NAME_LENGTH];
+ StringID str = IsValidPlayer(ci_to->client_playas) ? GetPlayer(ci_to->client_playas)->name_1 : STR_NETWORK_SPECTATORS;
+ GetString(name, str, lastof(name));
+ NetworkTextMessage(action, GetDrawStringPlayerColor(ci_own->client_playas), true, name, "%s", msg);
+ } else {
+ FOR_ALL_CLIENTS(cs) {
+ if (cs->index == from_index) {
+ SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, ci_to->client_index, true, msg);
+ }
+ }
+ }
+ }
+ }
+ break;
+ default:
+ DEBUG(net, 0, "[server] received unknown chat destination type %d. Doing broadcast instead", desttype);
+ /* fall-through to next case */
+ case DESTTYPE_BROADCAST:
+ FOR_ALL_CLIENTS(cs) {
+ SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, from_index, false, msg);
+ }
+ ci = NetworkFindClientInfoFromIndex(from_index);
+ if (ci != NULL)
+ NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas), false, ci->client_name, "%s", msg);
+ break;
+ }
+}
+
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_CHAT)
+{
+ NetworkAction action = NetworkRecv_uint8(cs, p);
+ DestType desttype = NetworkRecv_uint8(cs, p);
+ int dest = NetworkRecv_uint8(cs, p);
+ char msg[MAX_TEXT_MSG_LEN];
+
+ NetworkRecv_string(cs, p, msg, MAX_TEXT_MSG_LEN);
+
+ NetworkServer_HandleChat(action, desttype, dest, msg, cs->index);
+}
+
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_SET_PASSWORD)
+{
+ char password[NETWORK_PASSWORD_LENGTH];
+ const NetworkClientInfo *ci;
+
+ NetworkRecv_string(cs, p, password, sizeof(password));
+ ci = DEREF_CLIENT_INFO(cs);
+
+ if (IsValidPlayer(ci->client_playas)) {
+ ttd_strlcpy(_network_player_info[ci->client_playas].password, password, sizeof(_network_player_info[0].password));
+ }
+}
+
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_SET_NAME)
+{
+ char client_name[NETWORK_CLIENT_NAME_LENGTH];
+ NetworkClientInfo *ci;
+
+ NetworkRecv_string(cs, p, client_name, sizeof(client_name));
+ ci = DEREF_CLIENT_INFO(cs);
+
+ if (cs->has_quit) return;
+
+ if (ci != NULL) {
+ // Display change
+ if (NetworkFindName(client_name)) {
+ NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, 1, false, ci->client_name, "%s", client_name);
+ ttd_strlcpy(ci->client_name, client_name, sizeof(ci->client_name));
+ NetworkUpdateClientInfo(ci->client_index);
+ }
+ }
+}
+
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_RCON)
+{
+ char pass[NETWORK_PASSWORD_LENGTH];
+ char command[NETWORK_RCONCOMMAND_LENGTH];
+
+ if (_network_game_info.rcon_password[0] == '\0') return;
+
+ NetworkRecv_string(cs, p, pass, sizeof(pass));
+ NetworkRecv_string(cs, p, command, sizeof(command));
+
+ if (strcmp(pass, _network_game_info.rcon_password) != 0) {
+ DEBUG(net, 0, "[rcon] wrong password from client-id %d", cs->index);
+ return;
+ }
+
+ DEBUG(net, 0, "[rcon] client-id %d executed: '%s'", cs->index, command);
+
+ _redirect_console_to_client = cs->index;
+ IConsoleCmdExec(command);
+ _redirect_console_to_client = 0;
+ return;
+}
+
+// The layout for the receive-functions by the server
+typedef void NetworkServerPacket(NetworkClientState *cs, Packet *p);
+
+
+// This array matches PacketType. At an incoming
+// packet it is matches against this array
+// and that way the right function to handle that
+// packet is found.
+static NetworkServerPacket* const _network_server_packet[] = {
+ NULL, /*PACKET_SERVER_FULL,*/
+ NULL, /*PACKET_SERVER_BANNED,*/
+ RECEIVE_COMMAND(PACKET_CLIENT_JOIN),
+ NULL, /*PACKET_SERVER_ERROR,*/
+ RECEIVE_COMMAND(PACKET_CLIENT_COMPANY_INFO),
+ NULL, /*PACKET_SERVER_COMPANY_INFO,*/
+ NULL, /*PACKET_SERVER_CLIENT_INFO,*/
+ NULL, /*PACKET_SERVER_NEED_PASSWORD,*/
+ RECEIVE_COMMAND(PACKET_CLIENT_PASSWORD),
+ NULL, /*PACKET_SERVER_WELCOME,*/
+ RECEIVE_COMMAND(PACKET_CLIENT_GETMAP),
+ NULL, /*PACKET_SERVER_WAIT,*/
+ NULL, /*PACKET_SERVER_MAP,*/
+ RECEIVE_COMMAND(PACKET_CLIENT_MAP_OK),
+ NULL, /*PACKET_SERVER_JOIN,*/
+ NULL, /*PACKET_SERVER_FRAME,*/
+ NULL, /*PACKET_SERVER_SYNC,*/
+ RECEIVE_COMMAND(PACKET_CLIENT_ACK),
+ RECEIVE_COMMAND(PACKET_CLIENT_COMMAND),
+ NULL, /*PACKET_SERVER_COMMAND,*/
+ RECEIVE_COMMAND(PACKET_CLIENT_CHAT),
+ NULL, /*PACKET_SERVER_CHAT,*/
+ RECEIVE_COMMAND(PACKET_CLIENT_SET_PASSWORD),
+ RECEIVE_COMMAND(PACKET_CLIENT_SET_NAME),
+ RECEIVE_COMMAND(PACKET_CLIENT_QUIT),
+ RECEIVE_COMMAND(PACKET_CLIENT_ERROR),
+ NULL, /*PACKET_SERVER_QUIT,*/
+ NULL, /*PACKET_SERVER_ERROR_QUIT,*/
+ NULL, /*PACKET_SERVER_SHUTDOWN,*/
+ NULL, /*PACKET_SERVER_NEWGAME,*/
+ NULL, /*PACKET_SERVER_RCON,*/
+ RECEIVE_COMMAND(PACKET_CLIENT_RCON),
+};
+
+// If this fails, check the array above with network_data.h
+assert_compile(lengthof(_network_server_packet) == PACKET_END);
+
+// This update the company_info-stuff
+void NetworkPopulateCompanyInfo(void)
+{
+ char password[NETWORK_PASSWORD_LENGTH];
+ const Player *p;
+ const Vehicle *v;
+ const Station *s;
+ const NetworkClientState *cs;
+ const NetworkClientInfo *ci;
+ uint i;
+ uint16 months_empty;
+
+ FOR_ALL_PLAYERS(p) {
+ if (!p->is_active) {
+ memset(&_network_player_info[p->index], 0, sizeof(NetworkPlayerInfo));
+ continue;
+ }
+
+ // Clean the info but not the password
+ ttd_strlcpy(password, _network_player_info[p->index].password, sizeof(password));
+ months_empty = _network_player_info[p->index].months_empty;
+ memset(&_network_player_info[p->index], 0, sizeof(NetworkPlayerInfo));
+ _network_player_info[p->index].months_empty = months_empty;
+ ttd_strlcpy(_network_player_info[p->index].password, password, sizeof(_network_player_info[p->index].password));
+
+ // Grap the company name
+ SetDParam(0, p->name_1);
+ SetDParam(1, p->name_2);
+ GetString(_network_player_info[p->index].company_name, STR_JUST_STRING, lastof(_network_player_info[p->index].company_name));
+
+ // Check the income
+ if (_cur_year - 1 == p->inaugurated_year) {
+ // The player is here just 1 year, so display [2], else display[1]
+ for (i = 0; i < lengthof(p->yearly_expenses[2]); i++) {
+ _network_player_info[p->index].income -= p->yearly_expenses[2][i];
+ }
+ } else {
+ for (i = 0; i < lengthof(p->yearly_expenses[1]); i++) {
+ _network_player_info[p->index].income -= p->yearly_expenses[1][i];
+ }
+ }
+
+ // Set some general stuff
+ _network_player_info[p->index].inaugurated_year = p->inaugurated_year;
+ _network_player_info[p->index].company_value = p->old_economy[0].company_value;
+ _network_player_info[p->index].money = p->money64;
+ _network_player_info[p->index].performance = p->old_economy[0].performance_history;
+ }
+
+ // Go through all vehicles and count the type of vehicles
+ FOR_ALL_VEHICLES(v) {
+ if (!IsValidPlayer(v->owner)) continue;
+
+ switch (v->type) {
+ case VEH_Train:
+ if (IsFrontEngine(v)) _network_player_info[v->owner].num_vehicle[0]++;
+ break;
+
+ case VEH_Road:
+ if (v->cargo_type != CT_PASSENGERS) {
+ _network_player_info[v->owner].num_vehicle[1]++;
+ } else {
+ _network_player_info[v->owner].num_vehicle[2]++;
+ }
+ break;
+
+ case VEH_Aircraft:
+ if (v->subtype <= 2) _network_player_info[v->owner].num_vehicle[3]++;
+ break;
+
+ case VEH_Ship:
+ _network_player_info[v->owner].num_vehicle[4]++;
+ break;
+
+ case VEH_Special:
+ case VEH_Disaster:
+ break;
+ }
+ }
+
+ // Go through all stations and count the types of stations
+ FOR_ALL_STATIONS(s) {
+ if (IsValidPlayer(s->owner)) {
+ NetworkPlayerInfo *npi = &_network_player_info[s->owner];
+
+ if (s->facilities & FACIL_TRAIN) npi->num_station[0]++;
+ if (s->facilities & FACIL_TRUCK_STOP) npi->num_station[1]++;
+ if (s->facilities & FACIL_BUS_STOP) npi->num_station[2]++;
+ if (s->facilities & FACIL_AIRPORT) npi->num_station[3]++;
+ if (s->facilities & FACIL_DOCK) npi->num_station[4]++;
+ }
+ }
+
+ ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
+ // Register local player (if not dedicated)
+ if (ci != NULL && IsValidPlayer(ci->client_playas))
+ ttd_strlcpy(_network_player_info[ci->client_playas].players, ci->client_name, sizeof(_network_player_info[0].players));
+
+ FOR_ALL_CLIENTS(cs) {
+ char client_name[NETWORK_CLIENT_NAME_LENGTH];
+
+ NetworkGetClientName(client_name, sizeof(client_name), cs);
+
+ ci = DEREF_CLIENT_INFO(cs);
+ if (ci != NULL && IsValidPlayer(ci->client_playas)) {
+ if (strlen(_network_player_info[ci->client_playas].players) != 0)
+ ttd_strlcat(_network_player_info[ci->client_playas].players, ", ", lengthof(_network_player_info[0].players));
+
+ ttd_strlcat(_network_player_info[ci->client_playas].players, client_name, lengthof(_network_player_info[0].players));
+ }
+ }
+}
+
+// Send a packet to all clients with updated info about this client_index
+void NetworkUpdateClientInfo(uint16 client_index)
+{
+ NetworkClientState *cs;
+ NetworkClientInfo *ci = NetworkFindClientInfoFromIndex(client_index);
+
+ if (ci == NULL) return;
+
+ FOR_ALL_CLIENTS(cs) {
+ SEND_COMMAND(PACKET_SERVER_CLIENT_INFO)(cs, ci);
+ }
+}
+
+/* Check if we want to restart the map */
+static void NetworkCheckRestartMap(void)
+{
+ if (_network_restart_game_year != 0 && _cur_year >= _network_restart_game_year) {
+ DEBUG(net, 0, "Auto-restarting map. Year %d reached", _cur_year);
+
+ StartNewGameWithoutGUI(GENERATE_NEW_SEED);
+ }
+}
+
+/* Check if the server has autoclean_companies activated
+ Two things happen:
+ 1) If a company is not protected, it is closed after 1 year (for example)
+ 2) If a company is protected, protection is disabled after 3 years (for example)
+ (and item 1. happens a year later) */
+static void NetworkAutoCleanCompanies(void)
+{
+ const NetworkClientState *cs;
+ const NetworkClientInfo *ci;
+ const Player *p;
+ bool clients_in_company[MAX_PLAYERS];
+
+ if (!_network_autoclean_companies) return;
+
+ memset(clients_in_company, 0, sizeof(clients_in_company));
+
+ /* Detect the active companies */
+ FOR_ALL_CLIENTS(cs) {
+ ci = DEREF_CLIENT_INFO(cs);
+ if (IsValidPlayer(ci->client_playas)) clients_in_company[ci->client_playas] = true;
+ }
+
+ if (!_network_dedicated) {
+ ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
+ if (IsValidPlayer(ci->client_playas)) clients_in_company[ci->client_playas] = true;
+ }
+
+ /* Go through all the comapnies */
+ FOR_ALL_PLAYERS(p) {
+ /* Skip the non-active once */
+ if (!p->is_active || p->is_ai) continue;
+
+ if (!clients_in_company[p->index]) {
+ /* The company is empty for one month more */
+ _network_player_info[p->index].months_empty++;
+
+ /* Is the company empty for autoclean_unprotected-months, and is there no protection? */
+ if (_network_player_info[p->index].months_empty > _network_autoclean_unprotected && _network_player_info[p->index].password[0] == '\0') {
+ /* Shut the company down */
+ DoCommandP(0, 2, p->index, NULL, CMD_PLAYER_CTRL);
+ IConsolePrintF(_icolour_def, "Auto-cleaned company #%d", p->index + 1);
+ }
+ /* Is the compnay empty for autoclean_protected-months, and there is a protection? */
+ if (_network_player_info[p->index].months_empty > _network_autoclean_protected && _network_player_info[p->index].password[0] != '\0') {
+ /* Unprotect the company */
+ _network_player_info[p->index].password[0] = '\0';
+ IConsolePrintF(_icolour_def, "Auto-removed protection from company #%d", p->index+1);
+ _network_player_info[p->index].months_empty = 0;
+ }
+ } else {
+ /* It is not empty, reset the date */
+ _network_player_info[p->index].months_empty = 0;
+ }
+ }
+}
+
+// This function changes new_name to a name that is unique (by adding #1 ...)
+// and it returns true if that succeeded.
+bool NetworkFindName(char new_name[NETWORK_CLIENT_NAME_LENGTH])
+{
+ NetworkClientState *new_cs;
+ bool found_name = false;
+ byte number = 0;
+ char original_name[NETWORK_CLIENT_NAME_LENGTH];
+
+ // We use NETWORK_CLIENT_NAME_LENGTH in here, because new_name is really a pointer
+ ttd_strlcpy(original_name, new_name, NETWORK_CLIENT_NAME_LENGTH);
+
+ while (!found_name) {
+ const NetworkClientInfo *ci;
+
+ found_name = true;
+ FOR_ALL_CLIENTS(new_cs) {
+ ci = DEREF_CLIENT_INFO(new_cs);
+ if (strcmp(ci->client_name, new_name) == 0) {
+ // Name already in use
+ found_name = false;
+ break;
+ }
+ }
+ // Check if it is the same as the server-name
+ ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
+ if (ci != NULL) {
+ if (strcmp(ci->client_name, new_name) == 0) found_name = false; // name already in use
+ }
+
+ if (!found_name) {
+ // Try a new name (<name> #1, <name> #2, and so on)
+
+ // Stop if we tried for more than 50 times..
+ if (number++ > 50) break;
+ snprintf(new_name, NETWORK_CLIENT_NAME_LENGTH, "%s #%d", original_name, number);
+ }
+ }
+
+ return found_name;
+}
+
+// Reads a packet from the stream
+bool NetworkServer_ReadPackets(NetworkClientState *cs)
+{
+ Packet *p;
+ NetworkRecvStatus res;
+ while ((p = NetworkRecv_Packet(cs, &res)) != NULL) {
+ byte type = NetworkRecv_uint8(cs, p);
+ if (type < PACKET_END && _network_server_packet[type] != NULL && !cs->has_quit) {
+ _network_server_packet[type](cs, p);
+ } else {
+ DEBUG(net, 0, "[server] received invalid packet type %d", type);
+ }
+ free(p);
+ }
+
+ return true;
+}
+
+// Handle the local command-queue
+static void NetworkHandleCommandQueue(NetworkClientState* cs)
+{
+ CommandPacket *cp;
+
+ while ( (cp = cs->command_queue) != NULL) {
+ SEND_COMMAND(PACKET_SERVER_COMMAND)(cs, cp);
+
+ cs->command_queue = cp->next;
+ free(cp);
+ }
+}
+
+// This is called every tick if this is a _network_server
+void NetworkServer_Tick(bool send_frame)
+{
+ NetworkClientState *cs;
+#ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
+ bool send_sync = false;
+#endif
+
+#ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
+ if (_frame_counter >= _last_sync_frame + _network_sync_freq) {
+ _last_sync_frame = _frame_counter;
+ send_sync = true;
+ }
+#endif
+
+ // Now we are done with the frame, inform the clients that they can
+ // do their frame!
+ FOR_ALL_CLIENTS(cs) {
+ // Check if the speed of the client is what we can expect from a client
+ if (cs->status == STATUS_ACTIVE) {
+ // 1 lag-point per day
+ int lag = NetworkCalculateLag(cs) / DAY_TICKS;
+ if (lag > 0) {
+ if (lag > 3) {
+ // Client did still not report in after 4 game-day, drop him
+ // (that is, the 3 of above, + 1 before any lag is counted)
+ IConsolePrintF(_icolour_err,"Client #%d is dropped because the client did not respond for more than 4 game-days", cs->index);
+ NetworkCloseClient(cs);
+ continue;
+ }
+
+ // Report once per time we detect the lag
+ if (cs->lag_test == 0) {
+ IConsolePrintF(_icolour_warn,"[%d] Client #%d is slow, try increasing *net_frame_freq to a higher value!", _frame_counter, cs->index);
+ cs->lag_test = 1;
+ }
+ } else {
+ cs->lag_test = 0;
+ }
+ } else if (cs->status == STATUS_PRE_ACTIVE) {
+ int lag = NetworkCalculateLag(cs);
+ if (lag > _network_max_join_time) {
+ IConsolePrintF(_icolour_err,"Client #%d is dropped because it took longer than %d ticks for him to join", cs->index, _network_max_join_time);
+ NetworkCloseClient(cs);
+ }
+ }
+
+ if (cs->status >= STATUS_PRE_ACTIVE) {
+ // Check if we can send command, and if we have anything in the queue
+ NetworkHandleCommandQueue(cs);
+
+ // Send an updated _frame_counter_max to the client
+ if (send_frame) SEND_COMMAND(PACKET_SERVER_FRAME)(cs);
+
+#ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
+ // Send a sync-check packet
+ if (send_sync) SEND_COMMAND(PACKET_SERVER_SYNC)(cs);
+#endif
+ }
+ }
+
+ /* See if we need to advertise */
+ NetworkUDPAdvertise();
+}
+
+void NetworkServerYearlyLoop(void)
+{
+ NetworkCheckRestartMap();
+}
+
+void NetworkServerMonthlyLoop(void)
+{
+ NetworkAutoCleanCompanies();
+}
+
+#endif /* ENABLE_NETWORK */
diff --git a/src/network/network_server.h b/src/network/network_server.h
new file mode 100644
index 000000000..c5b2baade
--- /dev/null
+++ b/src/network/network_server.h
@@ -0,0 +1,39 @@
+/* $Id$ */
+
+#ifndef NETWORK_SERVER_H
+#define NETWORK_SERVER_H
+
+#ifdef ENABLE_NETWORK
+
+DEF_SERVER_SEND_COMMAND(PACKET_SERVER_MAP);
+DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR_QUIT)(NetworkClientState *cs, uint16 client_index, NetworkErrorCode errorno);
+DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR)(NetworkClientState *cs, NetworkErrorCode error);
+DEF_SERVER_SEND_COMMAND(PACKET_SERVER_SHUTDOWN);
+DEF_SERVER_SEND_COMMAND(PACKET_SERVER_NEWGAME);
+DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_RCON)(NetworkClientState *cs, uint16 color, const char *command);
+
+bool NetworkFindName(char new_name[NETWORK_CLIENT_NAME_LENGTH]);
+void NetworkServer_HandleChat(NetworkAction action, DestType type, int dest, const char *msg, uint16 from_index);
+
+bool NetworkServer_ReadPackets(NetworkClientState *cs);
+void NetworkServer_Tick(bool send_frame);
+void NetworkServerMonthlyLoop(void);
+void NetworkServerYearlyLoop(void);
+
+static inline const char* GetPlayerIP(const NetworkClientInfo* ci)
+{
+ struct in_addr addr;
+
+ addr.s_addr = ci->client_ip;
+ return inet_ntoa(addr);
+}
+
+#else /* ENABLE_NETWORK */
+/* Network function stubs when networking is disabled */
+
+static inline void NetworkServerMonthlyLoop(void) {}
+static inline void NetworkServerYearlyLoop(void) {}
+
+#endif /* ENABLE_NETWORK */
+
+#endif /* NETWORK_SERVER_H */
diff --git a/src/network/network_udp.c b/src/network/network_udp.c
new file mode 100644
index 000000000..aeef75e77
--- /dev/null
+++ b/src/network/network_udp.c
@@ -0,0 +1,663 @@
+/* $Id$ */
+
+#ifdef ENABLE_NETWORK
+
+#include "../stdafx.h"
+#include "../debug.h"
+#include "../string.h"
+#include "network_data.h"
+#include "../date.h"
+#include "../map.h"
+#include "network_gamelist.h"
+#include "network_udp.h"
+#include "../variables.h"
+#include "../newgrf_config.h"
+
+#include "core/udp.h"
+
+/**
+ * @file network_udp.c This file handles the UDP related communication.
+ *
+ * This is the GameServer <-> MasterServer and GameServer <-> GameClient
+ * communication before the game is being joined.
+ */
+
+enum {
+ ADVERTISE_NORMAL_INTERVAL = 30000, // interval between advertising in ticks (15 minutes)
+ ADVERTISE_RETRY_INTERVAL = 300, // readvertise when no response after this many ticks (9 seconds)
+ ADVERTISE_RETRY_TIMES = 3 // give up readvertising after this much failed retries
+};
+
+#define DEF_UDP_RECEIVE_COMMAND(type) void NetworkPacketReceive_ ## type ## _command(Packet *p, struct sockaddr_in *client_addr)
+
+static NetworkClientState _udp_cs;
+
+DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER)
+{
+ Packet *packet;
+ // Just a fail-safe.. should never happen
+ if (!_network_udp_server)
+ return;
+
+ packet = NetworkSend_Init(PACKET_UDP_SERVER_RESPONSE);
+
+ // Update some game_info
+ _network_game_info.game_date = _date;
+ _network_game_info.map_width = MapSizeX();
+ _network_game_info.map_height = MapSizeY();
+ _network_game_info.map_set = _opt.landscape;
+ _network_game_info.companies_on = ActivePlayerCount();
+ _network_game_info.spectators_on = NetworkSpectatorCount();
+ _network_game_info.grfconfig = _grfconfig;
+
+ NetworkSend_NetworkGameInfo(p, &_network_game_info);
+
+ // Let the client know that we are here
+ NetworkSendUDP_Packet(_udp_server_socket, packet, client_addr);
+
+ free(packet);
+
+ DEBUG(net, 2, "[udp] queried from '%s'", inet_ntoa(client_addr->sin_addr));
+}
+
+void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config)
+{
+ /* Find the matching GRF file */
+ const GRFConfig *f = FindGRFConfig(config->grfid, config->md5sum);
+ if (f == NULL) {
+ /* Don't know the GRF, so mark game incompatible and the (possibly)
+ * already resolved name for this GRF (another server has sent the
+ * name of the GRF already */
+ config->name = FindUnknownGRFName(config->grfid, config->md5sum, true);
+ SETBIT(config->flags, GCF_NOT_FOUND);
+ } else {
+ config->filename = f->filename;
+ config->name = f->name;
+ config->info = f->info;
+ }
+ SETBIT(config->flags, GCF_COPY);
+}
+
+DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_SERVER_RESPONSE)
+{
+ extern const char _openttd_revision[];
+ NetworkGameList *item;
+
+ // Just a fail-safe.. should never happen
+ if (_network_udp_server || _udp_cs.has_quit) return;
+
+ DEBUG(net, 4, "[udp] server response from %s:%d", inet_ntoa(client_addr->sin_addr),ntohs(client_addr->sin_port));
+
+ // Find next item
+ item = NetworkGameListAddItem(inet_addr(inet_ntoa(client_addr->sin_addr)), ntohs(client_addr->sin_port));
+
+ NetworkRecv_NetworkGameInfo(&_udp_cs, p, &item->info);
+
+ item->info.compatible = true;
+ {
+ /* Checks whether there needs to be a request for names of GRFs and makes
+ * the request if necessary. GRFs that need to be requested are the GRFs
+ * that do not exist on the clients system and we do not have the name
+ * resolved of, i.e. the name is still UNKNOWN_GRF_NAME_PLACEHOLDER.
+ * The in_request array and in_request_count are used so there is no need
+ * to do a second loop over the GRF list, which can be relatively expensive
+ * due to the string comparisons. */
+ const GRFConfig *in_request[NETWORK_MAX_GRF_COUNT];
+ const GRFConfig *c;
+ uint in_request_count = 0;
+ struct sockaddr_in out_addr;
+
+ for (c = item->info.grfconfig; c != NULL; c = c->next) {
+ if (HASBIT(c->flags, GCF_NOT_FOUND)) item->info.compatible = false;
+ if (!HASBIT(c->flags, GCF_NOT_FOUND) || strcmp(c->name, UNKNOWN_GRF_NAME_PLACEHOLDER) != 0) continue;
+ in_request[in_request_count] = c;
+ in_request_count++;
+ }
+
+ if (in_request_count > 0) {
+ /* There are 'unknown' GRFs, now send a request for them */
+ uint i;
+ Packet *packet = NetworkSend_Init(PACKET_UDP_CLIENT_GET_NEWGRFS);
+
+ NetworkSend_uint8 (packet, in_request_count);
+ for (i = 0; i < in_request_count; i++) {
+ NetworkSend_GRFIdentifier(packet, in_request[i]);
+ }
+
+ out_addr.sin_family = AF_INET;
+ out_addr.sin_port = htons(item->port);
+ out_addr.sin_addr.s_addr = item->ip;
+ NetworkSendUDP_Packet(_udp_client_socket, packet, &out_addr);
+ free(packet);
+ }
+ }
+
+ if (item->info.server_lang >= NETWORK_NUM_LANGUAGES) item->info.server_lang = 0;
+ if (item->info.map_set >= NUM_LANDSCAPE ) item->info.map_set = 0;
+
+ if (item->info.hostname[0] == '\0')
+ snprintf(item->info.hostname, sizeof(item->info.hostname), "%s", inet_ntoa(client_addr->sin_addr));
+
+ /* Check if we are allowed on this server based on the revision-match */
+ item->info.version_compatible =
+ strcmp(item->info.server_revision, _openttd_revision) == 0 ||
+ strcmp(item->info.server_revision, NOREV_STRING) == 0;
+ item->info.compatible &= item->info.version_compatible; // Already contains match for GRFs
+
+ item->online = true;
+
+ UpdateNetworkGameWindow(false);
+}
+
+DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_DETAIL_INFO)
+{
+ NetworkClientState *cs;
+ NetworkClientInfo *ci;
+ Packet *packet;
+ Player *player;
+ byte current = 0;
+ int i;
+
+ // Just a fail-safe.. should never happen
+ if (!_network_udp_server) return;
+
+ packet = NetworkSend_Init(PACKET_UDP_SERVER_DETAIL_INFO);
+
+ /* Send the amount of active companies */
+ NetworkSend_uint8 (packet, NETWORK_COMPANY_INFO_VERSION);
+ NetworkSend_uint8 (packet, ActivePlayerCount());
+
+ /* Fetch the latest version of everything */
+ NetworkPopulateCompanyInfo();
+
+ /* Go through all the players */
+ FOR_ALL_PLAYERS(player) {
+ /* Skip non-active players */
+ if (!player->is_active) continue;
+
+ current++;
+
+ /* Send the information */
+ NetworkSend_uint8(packet, current);
+
+ NetworkSend_string(packet, _network_player_info[player->index].company_name);
+ NetworkSend_uint32(packet, _network_player_info[player->index].inaugurated_year);
+ NetworkSend_uint64(packet, _network_player_info[player->index].company_value);
+ NetworkSend_uint64(packet, _network_player_info[player->index].money);
+ NetworkSend_uint64(packet, _network_player_info[player->index].income);
+ NetworkSend_uint16(packet, _network_player_info[player->index].performance);
+
+ /* Send 1 if there is a passord for the company else send 0 */
+ if (_network_player_info[player->index].password[0] != '\0') {
+ NetworkSend_uint8(packet, 1);
+ } else {
+ NetworkSend_uint8(packet, 0);
+ }
+
+ for (i = 0; i < NETWORK_VEHICLE_TYPES; i++)
+ NetworkSend_uint16(packet, _network_player_info[player->index].num_vehicle[i]);
+
+ for (i = 0; i < NETWORK_STATION_TYPES; i++)
+ NetworkSend_uint16(packet, _network_player_info[player->index].num_station[i]);
+
+ /* Find the clients that are connected to this player */
+ FOR_ALL_CLIENTS(cs) {
+ ci = DEREF_CLIENT_INFO(cs);
+ if (ci->client_playas == player->index) {
+ /* The uint8 == 1 indicates that a client is following */
+ NetworkSend_uint8(packet, 1);
+ NetworkSend_string(packet, ci->client_name);
+ NetworkSend_string(packet, ci->unique_id);
+ NetworkSend_uint32(packet, ci->join_date);
+ }
+ }
+ /* Also check for the server itself */
+ ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
+ if (ci->client_playas == player->index) {
+ /* The uint8 == 1 indicates that a client is following */
+ NetworkSend_uint8(packet, 1);
+ NetworkSend_string(packet, ci->client_name);
+ NetworkSend_string(packet, ci->unique_id);
+ NetworkSend_uint32(packet, ci->join_date);
+ }
+
+ /* Indicates end of client list */
+ NetworkSend_uint8(packet, 0);
+ }
+
+ /* And check if we have any spectators */
+ FOR_ALL_CLIENTS(cs) {
+ ci = DEREF_CLIENT_INFO(cs);
+ if (!IsValidPlayer(ci->client_playas)) {
+ /* The uint8 == 1 indicates that a client is following */
+ NetworkSend_uint8(packet, 1);
+ NetworkSend_string(packet, ci->client_name);
+ NetworkSend_string(packet, ci->unique_id);
+ NetworkSend_uint32(packet, ci->join_date);
+ }
+ }
+
+ /* Also check for the server itself */
+ ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
+ if (!IsValidPlayer(ci->client_playas)) {
+ /* The uint8 == 1 indicates that a client is following */
+ NetworkSend_uint8(packet, 1);
+ NetworkSend_string(packet, ci->client_name);
+ NetworkSend_string(packet, ci->unique_id);
+ NetworkSend_uint32(packet, ci->join_date);
+ }
+
+ /* Indicates end of client list */
+ NetworkSend_uint8(packet, 0);
+
+ NetworkSendUDP_Packet(_udp_server_socket, packet, client_addr);
+
+ free(packet);
+}
+
+DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_MASTER_RESPONSE_LIST)
+{
+ int i;
+ struct in_addr ip;
+ uint16 port;
+ uint8 ver;
+
+ /* packet begins with the protocol version (uint8)
+ * then an uint16 which indicates how many
+ * ip:port pairs are in this packet, after that
+ * an uint32 (ip) and an uint16 (port) for each pair
+ */
+
+ ver = NetworkRecv_uint8(&_udp_cs, p);
+
+ if (_udp_cs.has_quit) return;
+
+ if (ver == 1) {
+ for (i = NetworkRecv_uint16(&_udp_cs, p); i != 0 ; i--) {
+ ip.s_addr = TO_LE32(NetworkRecv_uint32(&_udp_cs, p));
+ port = NetworkRecv_uint16(&_udp_cs, p);
+ NetworkUDPQueryServer(inet_ntoa(ip), port);
+ }
+ }
+}
+
+DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_MASTER_ACK_REGISTER)
+{
+ _network_advertise_retries = 0;
+ DEBUG(net, 2, "[udp] advertising on master server successfull");
+
+ /* We are advertised, but we don't want to! */
+ if (!_network_advertise) NetworkUDPRemoveAdvertise();
+}
+
+/**
+ * A client has requested the names of some NewGRFs.
+ *
+ * Replying this can be tricky as we have a limit of SEND_MTU bytes
+ * in the reply packet and we can send up to 100 bytes per NewGRF
+ * (GRF ID, MD5sum and NETWORK_GRF_NAME_LENGTH bytes for the name).
+ * As SEND_MTU is _much_ less than 100 * NETWORK_MAX_GRF_COUNT, it
+ * could be that a packet overflows. To stop this we only reply
+ * with the first N NewGRFs so that if the first N + 1 NewGRFs
+ * would be sent, the packet overflows.
+ * in_reply and in_reply_count are used to keep a list of GRFs to
+ * send in the reply.
+ */
+DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_GET_NEWGRFS)
+{
+ uint8 num_grfs;
+ uint i;
+
+ const GRFConfig *in_reply[NETWORK_MAX_GRF_COUNT];
+ Packet *packet;
+ uint8 in_reply_count = 0;
+ uint packet_len = 0;
+
+ /* Just a fail-safe.. should never happen */
+ if (_udp_cs.has_quit) return;
+
+ DEBUG(net, 6, "[udp] newgrf data request from %s:%d", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port));
+
+ num_grfs = NetworkRecv_uint8 (&_udp_cs, p);
+ if (num_grfs > NETWORK_MAX_GRF_COUNT) return;
+
+ for (i = 0; i < num_grfs; i++) {
+ GRFConfig c;
+ const GRFConfig *f;
+
+ NetworkRecv_GRFIdentifier(&_udp_cs, p, &c);
+
+ /* Find the matching GRF file */
+ f = FindGRFConfig(c.grfid, c.md5sum);
+ if (f == NULL) continue; // The GRF is unknown to this server
+
+ /* If the reply might exceed the size of the packet, only reply
+ * the current list and do not send the other data.
+ * The name could be an empty string, if so take the filename. */
+ packet_len += sizeof(c.grfid) + sizeof(c.md5sum) +
+ min(strlen((f->name != NULL && strlen(f->name) > 0) ? f->name : f->filename) + 1, NETWORK_GRF_NAME_LENGTH);
+ if (packet_len > SEND_MTU - 4) { // 4 is 3 byte header + grf count in reply
+ break;
+ }
+ in_reply[in_reply_count] = f;
+ in_reply_count++;
+ }
+
+ if (in_reply_count == 0) return;
+
+ packet = NetworkSend_Init(PACKET_UDP_SERVER_NEWGRFS);
+ NetworkSend_uint8 (packet, in_reply_count);
+ for (i = 0; i < in_reply_count; i++) {
+ char name[NETWORK_GRF_NAME_LENGTH];
+
+ /* The name could be an empty string, if so take the filename */
+ ttd_strlcpy(name, (in_reply[i]->name != NULL && strlen(in_reply[i]->name) > 0) ?
+ in_reply[i]->name : in_reply[i]->filename, sizeof(name));
+ NetworkSend_GRFIdentifier(packet, in_reply[i]);
+ NetworkSend_string(packet, name);
+ }
+
+ NetworkSendUDP_Packet(_udp_server_socket, packet, client_addr);
+ free(packet);
+}
+
+/** The return of the client's request of the names of some NewGRFs */
+DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_SERVER_NEWGRFS)
+{
+ uint8 num_grfs;
+ uint i;
+
+ /* Just a fail-safe.. should never happen */
+ if (_udp_cs.has_quit) return;
+
+ DEBUG(net, 6, "[udp] newgrf data reply from %s:%d", inet_ntoa(client_addr->sin_addr),ntohs(client_addr->sin_port));
+
+ num_grfs = NetworkRecv_uint8 (&_udp_cs, p);
+ if (num_grfs > NETWORK_MAX_GRF_COUNT) return;
+
+ for (i = 0; i < num_grfs; i++) {
+ char *unknown_name;
+ char name[NETWORK_GRF_NAME_LENGTH];
+ GRFConfig c;
+
+ NetworkRecv_GRFIdentifier(&_udp_cs, p, &c);
+ NetworkRecv_string(&_udp_cs, p, name, sizeof(name));
+
+ /* An empty name is not possible under normal circumstances
+ * and causes problems when showing the NewGRF list. */
+ if (strlen(name) == 0) continue;
+
+ /* Finds the fake GRFConfig for the just read GRF ID and MD5sum tuple.
+ * If it exists and not resolved yet, then name of the fake GRF is
+ * overwritten with the name from the reply. */
+ unknown_name = FindUnknownGRFName(c.grfid, c.md5sum, false);
+ if (unknown_name != NULL && strcmp(unknown_name, UNKNOWN_GRF_NAME_PLACEHOLDER) == 0) {
+ ttd_strlcpy(unknown_name, name, NETWORK_GRF_NAME_LENGTH);
+ }
+ }
+}
+
+
+// The layout for the receive-functions by UDP
+typedef void NetworkUDPPacket(Packet *p, struct sockaddr_in *client_addr);
+
+static NetworkUDPPacket* const _network_udp_packet[] = {
+ RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER),
+ RECEIVE_COMMAND(PACKET_UDP_SERVER_RESPONSE),
+ RECEIVE_COMMAND(PACKET_UDP_CLIENT_DETAIL_INFO),
+ NULL,
+ NULL,
+ RECEIVE_COMMAND(PACKET_UDP_MASTER_ACK_REGISTER),
+ NULL,
+ RECEIVE_COMMAND(PACKET_UDP_MASTER_RESPONSE_LIST),
+ NULL,
+ RECEIVE_COMMAND(PACKET_UDP_CLIENT_GET_NEWGRFS),
+ RECEIVE_COMMAND(PACKET_UDP_SERVER_NEWGRFS),
+};
+
+
+// If this fails, check the array above with network_data.h
+assert_compile(lengthof(_network_udp_packet) == PACKET_UDP_END);
+
+
+void NetworkHandleUDPPacket(Packet *p, struct sockaddr_in *client_addr)
+{
+ byte type;
+
+ /* Fake a client, so we can see when there is an illegal packet */
+ _udp_cs.socket = INVALID_SOCKET;
+ _udp_cs.has_quit = false;
+
+ type = NetworkRecv_uint8(&_udp_cs, p);
+
+ if (type < PACKET_UDP_END && _network_udp_packet[type] != NULL && !_udp_cs.has_quit) {
+ _network_udp_packet[type](p, client_addr);
+ } else {
+ if (!_udp_cs.has_quit) {
+ DEBUG(net, 0, "[udp] received invalid packet type %d", type);
+ } else {
+ DEBUG(net, 0, "[udp] received illegal packet");
+ }
+ }
+}
+
+
+// Close UDP connection
+void NetworkUDPClose(void)
+{
+ DEBUG(net, 1, "[udp] closed listeners");
+
+ if (_network_udp_server) {
+ if (_udp_server_socket != INVALID_SOCKET) {
+ closesocket(_udp_server_socket);
+ _udp_server_socket = INVALID_SOCKET;
+ }
+
+ if (_udp_master_socket != INVALID_SOCKET) {
+ closesocket(_udp_master_socket);
+ _udp_master_socket = INVALID_SOCKET;
+ }
+
+ _network_udp_server = false;
+ _network_udp_broadcast = 0;
+ } else {
+ if (_udp_client_socket != INVALID_SOCKET) {
+ closesocket(_udp_client_socket);
+ _udp_client_socket = INVALID_SOCKET;
+ }
+ _network_udp_broadcast = 0;
+ }
+}
+
+// Broadcast to all ips
+static void NetworkUDPBroadCast(SOCKET udp)
+{
+ Packet* p = NetworkSend_Init(PACKET_UDP_CLIENT_FIND_SERVER);
+ uint i;
+
+ for (i = 0; _broadcast_list[i] != 0; i++) {
+ struct sockaddr_in out_addr;
+
+ out_addr.sin_family = AF_INET;
+ out_addr.sin_port = htons(_network_server_port);
+ out_addr.sin_addr.s_addr = _broadcast_list[i];
+
+ DEBUG(net, 4, "[udp] broadcasting to %s", inet_ntoa(out_addr.sin_addr));
+
+ NetworkSendUDP_Packet(udp, p, &out_addr);
+ }
+
+ free(p);
+}
+
+
+// Request the the server-list from the master server
+void NetworkUDPQueryMasterServer(void)
+{
+ struct sockaddr_in out_addr;
+ Packet *p;
+
+ if (_udp_client_socket == INVALID_SOCKET)
+ if (!NetworkUDPListen(&_udp_client_socket, 0, 0, true))
+ return;
+
+ p = NetworkSend_Init(PACKET_UDP_CLIENT_GET_LIST);
+
+ out_addr.sin_family = AF_INET;
+ out_addr.sin_port = htons(NETWORK_MASTER_SERVER_PORT);
+ out_addr.sin_addr.s_addr = NetworkResolveHost(NETWORK_MASTER_SERVER_HOST);
+
+ // packet only contains protocol version
+ NetworkSend_uint8(p, NETWORK_MASTER_SERVER_VERSION);
+
+ NetworkSendUDP_Packet(_udp_client_socket, p, &out_addr);
+
+ DEBUG(net, 2, "[udp] master server queried at %s:%d", inet_ntoa(out_addr.sin_addr),ntohs(out_addr.sin_port));
+
+ free(p);
+}
+
+// Find all servers
+void NetworkUDPSearchGame(void)
+{
+ // We are still searching..
+ if (_network_udp_broadcast > 0) return;
+
+ // No UDP-socket yet..
+ if (_udp_client_socket == INVALID_SOCKET)
+ if (!NetworkUDPListen(&_udp_client_socket, 0, 0, true))
+ return;
+
+ DEBUG(net, 0, "[udp] searching server");
+
+ NetworkUDPBroadCast(_udp_client_socket);
+ _network_udp_broadcast = 300; // Stay searching for 300 ticks
+}
+
+NetworkGameList *NetworkUDPQueryServer(const char* host, unsigned short port)
+{
+ struct sockaddr_in out_addr;
+ Packet *p;
+ NetworkGameList *item;
+
+ // No UDP-socket yet..
+ if (_udp_client_socket == INVALID_SOCKET)
+ if (!NetworkUDPListen(&_udp_client_socket, 0, 0, true))
+ return NULL;
+
+ out_addr.sin_family = AF_INET;
+ out_addr.sin_port = htons(port);
+ out_addr.sin_addr.s_addr = NetworkResolveHost(host);
+
+ // Clear item in gamelist
+ item = NetworkGameListAddItem(inet_addr(inet_ntoa(out_addr.sin_addr)), ntohs(out_addr.sin_port));
+ memset(&item->info, 0, sizeof(item->info));
+ ttd_strlcpy(item->info.server_name, host, lengthof(item->info.server_name));
+ ttd_strlcpy(item->info.hostname, host, lengthof(item->info.hostname));
+ item->online = false;
+
+ // Init the packet
+ p = NetworkSend_Init(PACKET_UDP_CLIENT_FIND_SERVER);
+
+ NetworkSendUDP_Packet(_udp_client_socket, p, &out_addr);
+
+ free(p);
+
+ UpdateNetworkGameWindow(false);
+ return item;
+}
+
+/* Remove our advertise from the master-server */
+void NetworkUDPRemoveAdvertise(void)
+{
+ struct sockaddr_in out_addr;
+ Packet *p;
+
+ /* Check if we are advertising */
+ if (!_networking || !_network_server || !_network_udp_server) return;
+
+ /* check for socket */
+ if (_udp_master_socket == INVALID_SOCKET)
+ if (!NetworkUDPListen(&_udp_master_socket, _network_server_bind_ip, 0, false))
+ return;
+
+ DEBUG(net, 1, "[udp] removing advertise from master server");
+
+ /* Find somewhere to send */
+ out_addr.sin_family = AF_INET;
+ out_addr.sin_port = htons(NETWORK_MASTER_SERVER_PORT);
+ out_addr.sin_addr.s_addr = NetworkResolveHost(NETWORK_MASTER_SERVER_HOST);
+
+ /* Send the packet */
+ p = NetworkSend_Init(PACKET_UDP_SERVER_UNREGISTER);
+ /* Packet is: Version, server_port */
+ NetworkSend_uint8(p, NETWORK_MASTER_SERVER_VERSION);
+ NetworkSend_uint16(p, _network_server_port);
+ NetworkSendUDP_Packet(_udp_master_socket, p, &out_addr);
+
+ free(p);
+}
+
+/* Register us to the master server
+ This function checks if it needs to send an advertise */
+void NetworkUDPAdvertise(void)
+{
+ struct sockaddr_in out_addr;
+ Packet *p;
+
+ /* Check if we should send an advertise */
+ if (!_networking || !_network_server || !_network_udp_server || !_network_advertise)
+ return;
+
+ /* check for socket */
+ if (_udp_master_socket == INVALID_SOCKET)
+ if (!NetworkUDPListen(&_udp_master_socket, _network_server_bind_ip, 0, false))
+ return;
+
+ if (_network_need_advertise) {
+ _network_need_advertise = false;
+ _network_advertise_retries = ADVERTISE_RETRY_TIMES;
+ } else {
+ /* Only send once every ADVERTISE_NORMAL_INTERVAL ticks */
+ if (_network_advertise_retries == 0) {
+ if ((_network_last_advertise_frame + ADVERTISE_NORMAL_INTERVAL) > _frame_counter)
+ return;
+ _network_advertise_retries = ADVERTISE_RETRY_TIMES;
+ }
+
+ if ((_network_last_advertise_frame + ADVERTISE_RETRY_INTERVAL) > _frame_counter)
+ return;
+ }
+
+ _network_advertise_retries--;
+ _network_last_advertise_frame = _frame_counter;
+
+ /* Find somewhere to send */
+ out_addr.sin_family = AF_INET;
+ out_addr.sin_port = htons(NETWORK_MASTER_SERVER_PORT);
+ out_addr.sin_addr.s_addr = NetworkResolveHost(NETWORK_MASTER_SERVER_HOST);
+
+ DEBUG(net, 1, "[udp] advertising to master server");
+
+ /* Send the packet */
+ p = NetworkSend_Init(PACKET_UDP_SERVER_REGISTER);
+ /* Packet is: WELCOME_MESSAGE, Version, server_port */
+ NetworkSend_string(p, NETWORK_MASTER_SERVER_WELCOME_MESSAGE);
+ NetworkSend_uint8(p, NETWORK_MASTER_SERVER_VERSION);
+ NetworkSend_uint16(p, _network_server_port);
+ NetworkSendUDP_Packet(_udp_master_socket, p, &out_addr);
+
+ free(p);
+}
+
+void NetworkUDPInitialize(void)
+{
+ _udp_client_socket = INVALID_SOCKET;
+ _udp_server_socket = INVALID_SOCKET;
+ _udp_master_socket = INVALID_SOCKET;
+
+ _network_udp_server = false;
+ _network_udp_broadcast = 0;
+}
+
+#endif /* ENABLE_NETWORK */
diff --git a/src/network/network_udp.h b/src/network/network_udp.h
new file mode 100644
index 000000000..4488d19d4
--- /dev/null
+++ b/src/network/network_udp.h
@@ -0,0 +1,17 @@
+/* $Id$ */
+
+#ifndef NETWORK_UDP_H
+#define NETWORK_UDP_H
+
+#ifdef ENABLE_NETWORK
+
+void NetworkUDPInitialize(void);
+void NetworkUDPSearchGame(void);
+void NetworkUDPQueryMasterServer(void);
+NetworkGameList *NetworkUDPQueryServer(const char* host, unsigned short port);
+void NetworkUDPAdvertise(void);
+void NetworkUDPRemoveAdvertise(void);
+
+#endif /* ENABLE_NETWORK */
+
+#endif /* NETWORK_UDP_H */
diff --git a/src/newgrf.c b/src/newgrf.c
new file mode 100644
index 000000000..c2b4e464b
--- /dev/null
+++ b/src/newgrf.c
@@ -0,0 +1,3694 @@
+/* $Id$ */
+
+#include "stdafx.h"
+
+#include <stdarg.h>
+
+#include "openttd.h"
+#include "debug.h"
+#include "gfx.h"
+#include "fileio.h"
+#include "functions.h"
+#include "engine.h"
+#include "spritecache.h"
+#include "station.h"
+#include "sprite.h"
+#include "newgrf.h"
+#include "variables.h"
+#include "string.h"
+#include "table/strings.h"
+#include "bridge.h"
+#include "economy.h"
+#include "newgrf_engine.h"
+#include "vehicle.h"
+#include "newgrf_text.h"
+#include "table/sprites.h"
+#include "fontcache.h"
+#include "date.h"
+#include "currency.h"
+#include "sound.h"
+#include "newgrf_config.h"
+#include "newgrf_sound.h"
+#include "newgrf_spritegroup.h"
+
+/* TTDPatch extended GRF format codec
+ * (c) Petr Baudis 2004 (GPL'd)
+ * Changes by Florian octo Forster are (c) by the OpenTTD development team.
+ *
+ * Contains portions of documentation by TTDPatch team.
+ * Thanks especially to Josef Drexler for the documentation as well as a lot
+ * of help at #tycoon. Also thanks to Michael Blunck for is GRF files which
+ * served as subject to the initial testing of this codec. */
+
+
+static int _skip_sprites; // XXX
+static uint _file_index; // XXX
+SpriteID _signal_base;
+SpriteID _coast_base;
+
+static GRFFile *_cur_grffile;
+GRFFile *_first_grffile;
+static SpriteID _cur_spriteid;
+static GrfLoadingStage _cur_stage;
+static uint32 _nfo_line;
+
+static GRFConfig *_cur_grfconfig;
+
+/* Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E */
+static byte _misc_grf_features = 0;
+
+/* 32 * 8 = 256 flags. Apparently TTDPatch uses this many.. */
+static uint32 _ttdpatch_flags[8];
+
+/* Used by Action 0x06 to preload a pseudo sprite and modify its content */
+static byte *_preload_sprite = NULL;
+
+/* Set if any vehicle is loaded which uses 2cc (two company colours) */
+bool _have_2cc = false;
+
+
+typedef enum GrfDataType {
+ GDT_SOUND,
+} GrfDataType;
+
+static byte _grf_data_blocks;
+static GrfDataType _grf_data_type;
+
+
+typedef enum grfspec_feature {
+ GSF_TRAIN,
+ GSF_ROAD,
+ GSF_SHIP,
+ GSF_AIRCRAFT,
+ GSF_STATION,
+ GSF_CANAL,
+ GSF_BRIDGE,
+ GSF_TOWNHOUSE,
+ GSF_GLOBALVAR,
+ GSF_INDUSTRYTILES,
+ GSF_INDUSTRIES,
+ GSF_CARGOS,
+ GSF_SOUNDFX,
+} grfspec_feature;
+
+
+typedef void (*SpecialSpriteHandler)(byte *buf, int len);
+
+static const int _vehcounts[4] = {
+ /* GSF_TRAIN */ NUM_TRAIN_ENGINES,
+ /* GSF_ROAD */ NUM_ROAD_ENGINES,
+ /* GSF_SHIP */ NUM_SHIP_ENGINES,
+ /* GSF_AIRCRAFT */ NUM_AIRCRAFT_ENGINES
+};
+
+static const int _vehshifts[4] = {
+ /* GSF_TRAIN */ 0,
+ /* GSF_ROAD */ ROAD_ENGINES_INDEX,
+ /* GSF_SHIP */ SHIP_ENGINES_INDEX,
+ /* GSF_AIRCRAFT */ AIRCRAFT_ENGINES_INDEX,
+};
+
+enum {
+ MAX_STATIONS = 256,
+};
+
+static uint16 cargo_allowed[TOTAL_NUM_ENGINES];
+static uint16 cargo_disallowed[TOTAL_NUM_ENGINES];
+
+/* Contains the GRF ID of the owner of a vehicle if it has been reserved */
+static uint32 _grm_engines[TOTAL_NUM_ENGINES];
+
+/** DEBUG() function dedicated to newGRF debugging messages
+ * Function is essentialy the same as DEBUG(grf, severity, ...) with the
+ * addition of file:line information when parsing grf files.
+ * NOTE: for the above reason(s) grfmsg() should ONLY be used for
+ * loading/parsing grf files, not for runtime debug messages as there
+ * is no file information available during that time.
+ * @param severity debugging severity level, see debug.h
+ * @param debugging message in printf() format */
+void CDECL grfmsg(int severity, const char *str, ...)
+{
+ char buf[1024];
+ va_list va;
+
+ va_start(va, str);
+ vsnprintf(buf, sizeof(buf), str, va);
+ va_end(va);
+
+ DEBUG(grf, severity, "[%s:%d] %s", _cur_grfconfig->filename, _nfo_line, buf);
+}
+
+static inline void check_length(int real, int wanted, const char *str)
+{
+ if (real >= wanted) return;
+ grfmsg(0, "%s: Invalid pseudo sprite length %d (expected %d)!", str, real, wanted);
+}
+
+static inline byte grf_load_byte(byte **buf)
+{
+ return *(*buf)++;
+}
+
+static uint16 grf_load_word(byte **buf)
+{
+ uint16 val = grf_load_byte(buf);
+ return val | (grf_load_byte(buf) << 8);
+}
+
+static uint16 grf_load_extended(byte** buf)
+{
+ uint16 val;
+ val = grf_load_byte(buf);
+ if (val == 0xFF) val = grf_load_word(buf);
+ return val;
+}
+
+static uint32 grf_load_dword(byte **buf)
+{
+ uint32 val = grf_load_word(buf);
+ return val | (grf_load_word(buf) << 16);
+}
+
+static uint32 grf_load_var(byte size, byte **buf)
+{
+ switch (size) {
+ case 1: return grf_load_byte(buf);
+ case 2: return grf_load_word(buf);
+ case 4: return grf_load_dword(buf);
+ default:
+ NOT_REACHED();
+ return 0;
+ }
+}
+
+static GRFFile *GetFileByGRFID(uint32 grfid)
+{
+ GRFFile *file;
+
+ for (file = _first_grffile; file != NULL; file = file->next) {
+ if (file->grfid == grfid) break;
+ }
+ return file;
+}
+
+static GRFFile *GetFileByFilename(const char *filename)
+{
+ GRFFile *file;
+
+ for (file = _first_grffile; file != NULL; file = file->next) {
+ if (strcmp(file->filename, filename) == 0) break;
+ }
+ return file;
+}
+
+
+typedef bool (*VCI_Handler)(uint engine, int numinfo, int prop, byte **buf, int len);
+
+#define FOR_EACH_OBJECT for (i = 0; i < numinfo; i++)
+
+static void dewagonize(int condition, int engine)
+{
+ EngineInfo *ei = &_engine_info[engine];
+ RailVehicleInfo *rvi = &_rail_vehicle_info[engine];
+
+ if (condition != 0) {
+ ei->unk2 &= ~0x80;
+ rvi->flags &= ~2;
+ } else {
+ ei->unk2 |= 0x80;
+ rvi->flags |= 2;
+ }
+}
+
+static bool RailVehicleChangeInfo(uint engine, int numinfo, int prop, byte **bufp, int len)
+{
+ EngineInfo *ei = &_engine_info[engine];
+ RailVehicleInfo *rvi = &_rail_vehicle_info[engine];
+ byte *buf = *bufp;
+ int i;
+ bool ret = false;
+
+ switch (prop) {
+ case 0x05: /* Track type */
+ FOR_EACH_OBJECT {
+ uint8 tracktype = grf_load_byte(&buf);
+
+ switch (tracktype) {
+ case 0: ei[i].railtype = rvi[i].engclass == 2 ? RAILTYPE_ELECTRIC : RAILTYPE_RAIL; break;
+ case 1: ei[i].railtype = RAILTYPE_MONO; break;
+ case 2: ei[i].railtype = RAILTYPE_MAGLEV; break;
+ default:
+ grfmsg(1, "RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype);
+ break;
+ }
+ }
+ break;
+
+ case 0x08: /* AI passenger service */
+ /* TODO */
+ FOR_EACH_OBJECT grf_load_byte(&buf);
+ ret = true;
+ break;
+
+ case 0x09: /* Speed (1 unit is 1 kmh) */
+ FOR_EACH_OBJECT {
+ uint16 speed = grf_load_word(&buf);
+ if (speed == 0xFFFF) speed = 0;
+
+ rvi[i].max_speed = speed;
+ }
+ break;
+
+ case 0x0B: /* Power */
+ FOR_EACH_OBJECT {
+ uint16 power = grf_load_word(&buf);
+
+ if (rvi[i].flags & RVI_MULTIHEAD) power /= 2;
+
+ rvi[i].power = power;
+ dewagonize(power, engine + i);
+ }
+ break;
+
+ case 0x0D: /* Running cost factor */
+ FOR_EACH_OBJECT {
+ uint8 runcostfact = grf_load_byte(&buf);
+
+ if (rvi[i].flags & RVI_MULTIHEAD) runcostfact /= 2;
+
+ rvi[i].running_cost_base = runcostfact;
+ }
+ break;
+
+ case 0x0E: /* Running cost base */
+ FOR_EACH_OBJECT {
+ uint32 base = grf_load_dword(&buf);
+
+ switch (base) {
+ case 0x4C30: rvi[i].running_cost_class = 0; break;
+ case 0x4C36: rvi[i].running_cost_class = 1; break;
+ case 0x4C3C: rvi[i].running_cost_class = 2; break;
+ case 0: break; /* Used by wagons */
+ default:
+ grfmsg(1, "RailVehicleChangeInfo: Unsupported running cost base 0x%04X, ignoring", base);
+ break;
+ }
+ }
+ break;
+
+ case 0x12: /* Sprite ID */
+ FOR_EACH_OBJECT {
+ uint8 spriteid = grf_load_byte(&buf);
+
+ /* TTD sprite IDs point to a location in a 16bit array, but we use it
+ * as an array index, so we need it to be half the original value. */
+ if (spriteid < 0xFD) spriteid >>= 1;
+
+ rvi[i].image_index = spriteid;
+ }
+ break;
+
+ case 0x13: /* Dual-headed */
+ FOR_EACH_OBJECT {
+ uint8 dual = grf_load_byte(&buf);
+
+ if (dual != 0) {
+ if (!(rvi[i].flags & RVI_MULTIHEAD)) {
+ // adjust power and running cost if needed
+ rvi[i].power /= 2;
+ rvi[i].running_cost_base /= 2;
+ }
+ rvi[i].flags |= RVI_MULTIHEAD;
+ } else {
+ if (rvi[i].flags & RVI_MULTIHEAD) {
+ // adjust power and running cost if needed
+ rvi[i].power *= 2;
+ rvi[i].running_cost_base *= 2;
+ }
+ rvi[i].flags &= ~RVI_MULTIHEAD;
+ }
+ }
+ break;
+
+ case 0x14: /* Cargo capacity */
+ FOR_EACH_OBJECT rvi[i].capacity = grf_load_byte(&buf);
+ break;
+
+ case 0x15: /* Cargo type */
+ FOR_EACH_OBJECT {
+ uint8 ctype = grf_load_byte(&buf);
+
+ if (ctype < NUM_CARGO) {
+ rvi[i].cargo_type = ctype;
+ } else {
+ grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, ignoring", ctype);
+ }
+ }
+ break;
+
+ case 0x16: /* Weight */
+ FOR_EACH_OBJECT SB(rvi[i].weight, 0, 8, grf_load_byte(&buf));
+ break;
+
+ case 0x17: /* Cost factor */
+ FOR_EACH_OBJECT rvi[i].base_cost = grf_load_byte(&buf);
+ break;
+
+ case 0x18: /* AI rank */
+ FOR_EACH_OBJECT rvi[i].ai_rank = grf_load_byte(&buf);
+ break;
+
+ case 0x19: /* Engine traction type */
+ /* What do the individual numbers mean?
+ * 0x00 .. 0x07: Steam
+ * 0x08 .. 0x27: Diesel
+ * 0x28 .. 0x31: Electric
+ * 0x32 .. 0x37: Monorail
+ * 0x38 .. 0x41: Maglev
+ */
+ FOR_EACH_OBJECT {
+ uint8 traction = grf_load_byte(&buf);
+ int engclass;
+
+ if (traction <= 0x07) {
+ engclass = 0;
+ } else if (traction <= 0x27) {
+ engclass = 1;
+ } else if (traction <= 0x31) {
+ engclass = 2;
+ } else if (traction <= 0x41) {
+ engclass = 2;
+ } else {
+ break;
+ }
+ if (ei[i].railtype == RAILTYPE_RAIL && engclass == 2) ei[i].railtype = RAILTYPE_ELECTRIC;
+ if (ei[i].railtype == RAILTYPE_ELECTRIC && engclass != 2) ei[i].railtype = RAILTYPE_RAIL;
+
+ rvi[i].engclass = engclass;
+ }
+ break;
+
+ case 0x1A: /* Alter purchase list sort order */
+ FOR_EACH_OBJECT {
+ EngineID pos = grf_load_byte(&buf);
+
+ if (pos < NUM_TRAIN_ENGINES) {
+ AlterRailVehListOrder(engine + i, pos);
+ } else {
+ grfmsg(2, "RailVehicleChangeInfo: Invalid train engine ID %d, ignoring", pos);
+ }
+ }
+ break;
+
+ case 0x1B: /* Powered wagons power bonus */
+ FOR_EACH_OBJECT rvi[i].pow_wag_power = grf_load_word(&buf);
+ break;
+
+ case 0x1C: /* Refit cost */
+ FOR_EACH_OBJECT ei[i].refit_cost = grf_load_byte(&buf);
+ break;
+
+ case 0x1D: /* Refit cargo */
+ FOR_EACH_OBJECT ei[i].refit_mask = grf_load_dword(&buf);
+ break;
+
+ case 0x1E: /* Callback */
+ FOR_EACH_OBJECT ei[i].callbackmask = grf_load_byte(&buf);
+ break;
+
+ case 0x1F: /* Tractive effort coefficient */
+ FOR_EACH_OBJECT rvi[i].tractive_effort = grf_load_byte(&buf);
+ break;
+
+ case 0x21: /* Shorter vehicle */
+ FOR_EACH_OBJECT rvi[i].shorten_factor = grf_load_byte(&buf);
+ break;
+
+ case 0x22: /* Visual effect */
+ // see note in engine.h about rvi->visual_effect
+ FOR_EACH_OBJECT rvi[i].visual_effect = grf_load_byte(&buf);
+ break;
+
+ case 0x23: /* Powered wagons weight bonus */
+ FOR_EACH_OBJECT rvi[i].pow_wag_weight = grf_load_byte(&buf);
+ break;
+
+ case 0x24: /* High byte of vehicle weight */
+ FOR_EACH_OBJECT {
+ byte weight = grf_load_byte(&buf);
+
+ if (weight > 4) {
+ grfmsg(2, "RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight << 8);
+ } else {
+ SB(rvi[i].weight, 8, 8, weight);
+ }
+ }
+ break;
+
+ case 0x25: /* User-defined bit mask to set when checking veh. var. 42 */
+ FOR_EACH_OBJECT rvi[i].user_def_data = grf_load_byte(&buf);
+ break;
+
+ case 0x27: /* Miscellaneous flags */
+ FOR_EACH_OBJECT {
+ ei[i].misc_flags = grf_load_byte(&buf);
+ if (HASBIT(ei[i].misc_flags, EF_USES_2CC)) _have_2cc = true;
+ }
+ break;
+
+ case 0x28: /* Cargo classes allowed */
+ FOR_EACH_OBJECT cargo_allowed[engine + i] = grf_load_word(&buf);
+ break;
+
+ case 0x29: /* Cargo classes disallowed */
+ FOR_EACH_OBJECT cargo_disallowed[engine + i] = grf_load_word(&buf);
+ break;
+
+ case 0x2A: /* Long format introduction date (days since year 0) */
+ FOR_EACH_OBJECT ei[i].base_intro = grf_load_dword(&buf);
+ break;
+
+ /* TODO */
+ /* Fall-through for unimplemented one byte long properties. */
+ case 0x20: /* Air drag */
+ case 0x26: /* Retire vehicle early */
+ /* TODO */
+ FOR_EACH_OBJECT grf_load_byte(&buf);
+ ret = true;
+ break;
+
+ default:
+ ret = true;
+ break;
+ }
+ *bufp = buf;
+ return ret;
+}
+
+static bool RoadVehicleChangeInfo(uint engine, int numinfo, int prop, byte **bufp, int len)
+{
+ EngineInfo *ei = &_engine_info[ROAD_ENGINES_INDEX + engine];
+ RoadVehicleInfo *rvi = &_road_vehicle_info[engine];
+ byte *buf = *bufp;
+ int i;
+ bool ret = false;
+
+ switch (prop) {
+ case 0x08: /* Speed (1 unit is 0.5 kmh) */
+ FOR_EACH_OBJECT rvi[i].max_speed = grf_load_byte(&buf);
+ break;
+
+ case 0x09: /* Running cost factor */
+ FOR_EACH_OBJECT rvi[i].running_cost = grf_load_byte(&buf);
+ break;
+
+ case 0x0A: /* Running cost base */
+ /* TODO: I have no idea. --pasky */
+ FOR_EACH_OBJECT grf_load_dword(&buf);
+ ret = true;
+ break;
+
+ case 0x0E: /* Sprite ID */
+ FOR_EACH_OBJECT {
+ uint8 spriteid = grf_load_byte(&buf);
+
+ // cars have different custom id in the GRF file
+ if (spriteid == 0xFF) spriteid = 0xFD;
+
+ if (spriteid < 0xFD) spriteid >>= 1;
+
+ rvi[i].image_index = spriteid;
+ }
+ break;
+
+ case 0x0F: /* Cargo capacity */
+ FOR_EACH_OBJECT rvi[i].capacity = grf_load_byte(&buf);
+ break;
+
+ case 0x10: /* Cargo type */
+ FOR_EACH_OBJECT {
+ uint8 cargo = grf_load_byte(&buf);
+
+ if (cargo < NUM_CARGO) {
+ rvi[i].cargo_type = cargo;
+ } else {
+ grfmsg(2, "RoadVehicleChangeInfo: Invalid cargo type %d, ignoring", cargo);
+ }
+ }
+ break;
+
+ case 0x11: /* Cost factor */
+ FOR_EACH_OBJECT rvi[i].base_cost = grf_load_byte(&buf); // ?? is it base_cost?
+ break;
+
+ case 0x12: /* SFX */
+ FOR_EACH_OBJECT rvi[i].sfx = grf_load_byte(&buf);
+ break;
+
+ case 0x13: /* Power in 10hp */
+ case 0x14: /* Weight in 1/4 tons */
+ case 0x15: /* Speed in mph*0.8 */
+ /* TODO: Support for road vehicles realistic power
+ * computations (called rvpower in TTDPatch) is just
+ * missing in OTTD yet. --pasky */
+ FOR_EACH_OBJECT grf_load_byte(&buf);
+ ret = true;
+ break;
+
+ case 0x16: /* Cargos available for refitting */
+ FOR_EACH_OBJECT ei[i].refit_mask = grf_load_dword(&buf);
+ break;
+
+ case 0x17: /* Callback mask */
+ FOR_EACH_OBJECT ei[i].callbackmask = grf_load_byte(&buf);
+ break;
+
+ case 0x1A: /* Refit cost */
+ FOR_EACH_OBJECT ei[i].refit_cost = grf_load_byte(&buf);
+ break;
+
+ case 0x1C: /* Miscellaneous flags */
+ FOR_EACH_OBJECT {
+ ei[i].misc_flags = grf_load_byte(&buf);
+ if (HASBIT(ei[i].misc_flags, EF_USES_2CC)) _have_2cc = true;
+ }
+ break;
+
+ case 0x1D: /* Cargo classes allowed */
+ FOR_EACH_OBJECT cargo_allowed[ROAD_ENGINES_INDEX + engine + i] = grf_load_word(&buf);
+ break;
+
+ case 0x1E: /* Cargo classes disallowed */
+ FOR_EACH_OBJECT cargo_disallowed[ROAD_ENGINES_INDEX + engine + i] = grf_load_word(&buf);
+ break;
+
+ case 0x1F: /* Long format introduction date (days since year 0) */
+ FOR_EACH_OBJECT ei[i].base_intro = grf_load_dword(&buf);
+ break;
+
+ case 0x18: /* Tractive effort */
+ case 0x19: /* Air drag */
+ case 0x1B: /* Retire vehicle early */
+ /* TODO */
+ FOR_EACH_OBJECT grf_load_byte(&buf);
+ ret = true;
+ break;
+
+ default:
+ ret = true;
+ break;
+ }
+
+ *bufp = buf;
+ return ret;
+}
+
+static bool ShipVehicleChangeInfo(uint engine, int numinfo, int prop, byte **bufp, int len)
+{
+ EngineInfo *ei = &_engine_info[SHIP_ENGINES_INDEX + engine];
+ ShipVehicleInfo *svi = &_ship_vehicle_info[engine];
+ byte *buf = *bufp;
+ int i;
+ bool ret = false;
+
+ //printf("e %x prop %x?\n", engine, prop);
+ switch (prop) {
+ case 0x08: /* Sprite ID */
+ FOR_EACH_OBJECT {
+ uint8 spriteid = grf_load_byte(&buf);
+
+ // ships have different custom id in the GRF file
+ if (spriteid == 0xFF) spriteid = 0xFD;
+
+ if (spriteid < 0xFD) spriteid >>= 1;
+
+ svi[i].image_index = spriteid;
+ }
+ break;
+
+ case 0x09: /* Refittable */
+ FOR_EACH_OBJECT svi[i].refittable = grf_load_byte(&buf);
+ break;
+
+ case 0x0A: /* Cost factor */
+ FOR_EACH_OBJECT svi[i].base_cost = grf_load_byte(&buf); // ?? is it base_cost?
+ break;
+
+ case 0x0B: /* Speed (1 unit is 0.5 kmh) */
+ FOR_EACH_OBJECT svi[i].max_speed = grf_load_byte(&buf);
+ break;
+
+ case 0x0C: /* Cargo type */
+ FOR_EACH_OBJECT {
+ uint8 cargo = grf_load_byte(&buf);
+
+ // XXX: Need to consult this with patchman yet.
+#if 0
+ // Documentation claims this is already the
+ // per-landscape cargo type id, but newships.grf
+ // assume otherwise.
+ cargo = local_cargo_id_ctype[cargo];
+#endif
+ if (cargo < NUM_CARGO) {
+ svi[i].cargo_type = cargo;
+ } else {
+ grfmsg(2, "ShipVehicleChangeInfo: Invalid cargo type %d, ignoring", cargo);
+ }
+ }
+ break;
+
+ case 0x0D: /* Cargo capacity */
+ FOR_EACH_OBJECT svi[i].capacity = grf_load_word(&buf);
+ break;
+
+ case 0x0F: /* Running cost factor */
+ FOR_EACH_OBJECT svi[i].running_cost = grf_load_byte(&buf);
+ break;
+
+ case 0x10: /* SFX */
+ FOR_EACH_OBJECT svi[i].sfx = grf_load_byte(&buf);
+ break;
+
+ case 0x11: /* Cargos available for refitting */
+ FOR_EACH_OBJECT ei[i].refit_mask = grf_load_dword(&buf);
+ break;
+
+ case 0x12: /* Callback mask */
+ FOR_EACH_OBJECT ei[i].callbackmask = grf_load_byte(&buf);
+ break;
+
+ case 0x13: /* Refit cost */
+ FOR_EACH_OBJECT ei[i].refit_cost = grf_load_byte(&buf);
+ break;
+
+ case 0x17: /* Miscellaneous flags */
+ FOR_EACH_OBJECT {
+ ei[i].misc_flags = grf_load_byte(&buf);
+ if (HASBIT(ei[i].misc_flags, EF_USES_2CC)) _have_2cc = true;
+ }
+ break;
+
+ case 0x18: /* Cargo classes allowed */
+ FOR_EACH_OBJECT cargo_allowed[SHIP_ENGINES_INDEX + engine + i] = grf_load_word(&buf);
+ break;
+
+ case 0x19: /* Cargo classes disallowed */
+ FOR_EACH_OBJECT cargo_disallowed[SHIP_ENGINES_INDEX + engine + i] = grf_load_word(&buf);
+ break;
+
+ case 0x1A: /* Long format introduction date (days since year 0) */
+ FOR_EACH_OBJECT ei[i].base_intro = grf_load_dword(&buf);
+ break;
+
+ case 0x14: /* Ocean speed fraction */
+ case 0x15: /* Canal speed fraction */
+ case 0x16: /* Retire vehicle early */
+ /* TODO */
+ FOR_EACH_OBJECT grf_load_byte(&buf);
+ ret = true;
+ break;
+
+ default:
+ ret = true;
+ break;
+ }
+
+ *bufp = buf;
+ return ret;
+}
+
+static bool AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, byte **bufp, int len)
+{
+ EngineInfo *ei = &_engine_info[AIRCRAFT_ENGINES_INDEX + engine];
+ AircraftVehicleInfo *avi = &_aircraft_vehicle_info[engine];
+ byte *buf = *bufp;
+ int i;
+ bool ret = false;
+
+ //printf("e %x prop %x?\n", engine, prop);
+ switch (prop) {
+ case 0x08: /* Sprite ID */
+ FOR_EACH_OBJECT {
+ uint8 spriteid = grf_load_byte(&buf);
+
+ // aircraft have different custom id in the GRF file
+ if (spriteid == 0xFF) spriteid = 0xFD;
+
+ if (spriteid < 0xFD) spriteid >>= 1;
+
+ avi[i].image_index = spriteid;
+ }
+ break;
+
+ case 0x09: /* Helicopter */
+ FOR_EACH_OBJECT {
+ if (grf_load_byte(&buf) == 0) {
+ avi[i].subtype = 0;
+ } else {
+ SB(avi[i].subtype, 0, 1, 1);
+ }
+ }
+ break;
+
+ case 0x0A: /* Large */
+ FOR_EACH_OBJECT SB(avi[i].subtype, 1, 1, (grf_load_byte(&buf) != 0 ? 1 : 0));
+ break;
+
+ case 0x0B: /* Cost factor */
+ FOR_EACH_OBJECT avi[i].base_cost = grf_load_byte(&buf); // ?? is it base_cost?
+ break;
+
+ case 0x0C: /* Speed (1 unit is 8 mph) */
+ FOR_EACH_OBJECT avi[i].max_speed = grf_load_byte(&buf);
+ break;
+
+ case 0x0D: /* Acceleration */
+ FOR_EACH_OBJECT avi[i].acceleration = grf_load_byte(&buf);
+ break;
+
+ case 0x0E: /* Running cost factor */
+ FOR_EACH_OBJECT avi[i].running_cost = grf_load_byte(&buf);
+ break;
+
+ case 0x0F: /* Passenger capacity */
+ FOR_EACH_OBJECT avi[i].passenger_capacity = grf_load_word(&buf);
+ break;
+
+ case 0x11: /* Mail capacity */
+ FOR_EACH_OBJECT avi[i].mail_capacity = grf_load_byte(&buf);
+ break;
+
+ case 0x12: /* SFX */
+ FOR_EACH_OBJECT avi[i].sfx = grf_load_byte(&buf);
+ break;
+
+ case 0x13: /* Cargos available for refitting */
+ FOR_EACH_OBJECT ei[i].refit_mask = grf_load_dword(&buf);
+ break;
+
+ case 0x14: /* Callback mask */
+ FOR_EACH_OBJECT ei[i].callbackmask = grf_load_byte(&buf);
+ break;
+
+ case 0x15: /* Refit cost */
+ FOR_EACH_OBJECT ei[i].refit_cost = grf_load_byte(&buf);
+ break;
+
+ case 0x17: /* Miscellaneous flags */
+ FOR_EACH_OBJECT {
+ ei[i].misc_flags = grf_load_byte(&buf);
+ if (HASBIT(ei[i].misc_flags, EF_USES_2CC)) _have_2cc = true;
+ }
+ break;
+
+ case 0x18: /* Cargo classes allowed */
+ FOR_EACH_OBJECT cargo_allowed[AIRCRAFT_ENGINES_INDEX + engine + i] = grf_load_word(&buf);
+ break;
+
+ case 0x19: /* Cargo classes disallowed */
+ FOR_EACH_OBJECT cargo_disallowed[AIRCRAFT_ENGINES_INDEX + engine + i] = grf_load_word(&buf);
+ break;
+
+ case 0x1A: /* Long format introduction date (days since year 0) */
+ FOR_EACH_OBJECT ei[i].base_intro = grf_load_dword(&buf);
+ break;
+
+ case 0x16: /* Retire vehicle early */
+ /* TODO */
+ FOR_EACH_OBJECT grf_load_byte(&buf);
+ ret = true;
+ break;
+
+ default:
+ ret = true;
+ break;
+ }
+
+ *bufp = buf;
+ return ret;
+}
+
+static bool StationChangeInfo(uint stid, int numinfo, int prop, byte **bufp, int len)
+{
+ StationSpec **statspec;
+ byte *buf = *bufp;
+ int i;
+ bool ret = false;
+
+ if (stid + numinfo > MAX_STATIONS) {
+ grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid + numinfo, MAX_STATIONS);
+ return false;
+ }
+
+ /* Allocate station specs if necessary */
+ if (_cur_grffile->stations == NULL) _cur_grffile->stations = calloc(MAX_STATIONS, sizeof(*_cur_grffile->stations));
+
+ statspec = &_cur_grffile->stations[stid];
+
+ if (prop != 0x08) {
+ /* Check that all stations we are modifying are defined. */
+ FOR_EACH_OBJECT {
+ if (statspec[i] == NULL) {
+ grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
+ return false;
+ }
+ }
+ }
+
+ switch (prop) {
+ case 0x08: /* Class ID */
+ FOR_EACH_OBJECT {
+ uint32 classid;
+
+ /* Property 0x08 is special; it is where the station is allocated */
+ if (statspec[i] == NULL) statspec[i] = calloc(1, sizeof(*statspec[i]));
+
+ /* Swap classid because we read it in BE meaning WAYP or DFLT */
+ classid = grf_load_dword(&buf);
+ statspec[i]->sclass = AllocateStationClass(BSWAP32(classid));
+ }
+ break;
+
+ case 0x09: /* Define sprite layout */
+ FOR_EACH_OBJECT {
+ StationSpec *statspec = _cur_grffile->stations[stid + i];
+ uint t;
+
+ statspec->tiles = grf_load_extended(&buf);
+ statspec->renderdata = calloc(statspec->tiles, sizeof(*statspec->renderdata));
+ statspec->copied_renderdata = false;
+
+ for (t = 0; t < statspec->tiles; t++) {
+ DrawTileSprites *dts = &statspec->renderdata[t];
+ uint seq_count = 0;
+
+ dts->seq = NULL;
+ dts->ground_sprite = grf_load_dword(&buf);
+ if (dts->ground_sprite == 0) continue;
+
+ while (buf < *bufp + len) {
+ DrawTileSeqStruct *dtss;
+
+ // no relative bounding box support
+ dts->seq = realloc((void*)dts->seq, ++seq_count * sizeof(DrawTileSeqStruct));
+ dtss = (DrawTileSeqStruct*) &dts->seq[seq_count - 1];
+
+ dtss->delta_x = grf_load_byte(&buf);
+ if ((byte) dtss->delta_x == 0x80) break;
+ dtss->delta_y = grf_load_byte(&buf);
+ dtss->delta_z = grf_load_byte(&buf);
+ dtss->size_x = grf_load_byte(&buf);
+ dtss->size_y = grf_load_byte(&buf);
+ dtss->size_z = grf_load_byte(&buf);
+ dtss->image = grf_load_dword(&buf);
+
+ /* Remap flags as ours collide */
+ if (HASBIT(dtss->image, 31)) {
+ CLRBIT(dtss->image, 31);
+ SETBIT(dtss->image, 30);
+ }
+ if (HASBIT(dtss->image, 14)) {
+ CLRBIT(dtss->image, 14);
+ SETBIT(dtss->image, 31);
+ }
+ }
+ }
+ }
+ break;
+
+ case 0x0A: /* Copy sprite layout */
+ FOR_EACH_OBJECT {
+ StationSpec *statspec = _cur_grffile->stations[stid + i];
+ byte srcid = grf_load_byte(&buf);
+ const StationSpec *srcstatspec = _cur_grffile->stations[srcid];
+
+ statspec->tiles = srcstatspec->tiles;
+ statspec->renderdata = srcstatspec->renderdata;
+ statspec->copied_renderdata = true;
+ }
+ break;
+
+ case 0x0B: /* Callback mask */
+ FOR_EACH_OBJECT statspec[i]->callbackmask = grf_load_byte(&buf);
+ break;
+
+ case 0x0C: /* Disallowed number of platforms */
+ FOR_EACH_OBJECT statspec[i]->disallowed_platforms = grf_load_byte(&buf);
+ break;
+
+ case 0x0D: /* Disallowed platform lengths */
+ FOR_EACH_OBJECT statspec[i]->disallowed_lengths = grf_load_byte(&buf);
+ break;
+
+ case 0x0E: /* Define custom layout */
+ FOR_EACH_OBJECT {
+ StationSpec *statspec = _cur_grffile->stations[stid + i];
+
+ statspec->copied_layouts = false;
+
+ while (buf < *bufp + len) {
+ byte length = grf_load_byte(&buf);
+ byte number = grf_load_byte(&buf);
+ StationLayout layout;
+ uint l, p;
+
+ if (length == 0 || number == 0) break;
+
+ //debug("l %d > %d ?", length, stat->lengths);
+ if (length > statspec->lengths) {
+ statspec->platforms = realloc(statspec->platforms, length);
+ memset(statspec->platforms + statspec->lengths, 0, length - statspec->lengths);
+
+ statspec->layouts = realloc(statspec->layouts, length * sizeof(*statspec->layouts));
+ memset(statspec->layouts + statspec->lengths, 0,
+ (length - statspec->lengths) * sizeof(*statspec->layouts));
+
+ statspec->lengths = length;
+ }
+ l = length - 1; // index is zero-based
+
+ //debug("p %d > %d ?", number, stat->platforms[l]);
+ if (number > statspec->platforms[l]) {
+ statspec->layouts[l] = realloc(statspec->layouts[l],
+ number * sizeof(**statspec->layouts));
+ // We expect NULL being 0 here, but C99 guarantees that.
+ memset(statspec->layouts[l] + statspec->platforms[l], 0,
+ (number - statspec->platforms[l]) * sizeof(**statspec->layouts));
+
+ statspec->platforms[l] = number;
+ }
+
+ p = 0;
+ layout = malloc(length * number);
+ for (l = 0; l < length; l++) {
+ for (p = 0; p < number; p++) {
+ layout[l * number + p] = grf_load_byte(&buf);
+ }
+ }
+
+ l--;
+ p--;
+ free(statspec->layouts[l][p]);
+ statspec->layouts[l][p] = layout;
+ }
+ }
+ break;
+
+ case 0x0F: /* Copy custom layout */
+ FOR_EACH_OBJECT {
+ StationSpec *statspec = _cur_grffile->stations[stid + i];
+ byte srcid = grf_load_byte(&buf);
+ const StationSpec *srcstatspec = _cur_grffile->stations[srcid];
+
+ statspec->lengths = srcstatspec->lengths;
+ statspec->platforms = srcstatspec->platforms;
+ statspec->layouts = srcstatspec->layouts;
+ statspec->copied_layouts = true;
+ }
+ break;
+
+ case 0x10: /* Little/lots cargo threshold */
+ FOR_EACH_OBJECT statspec[i]->cargo_threshold = grf_load_word(&buf);
+ break;
+
+ case 0x11: /* Pylon placement */
+ FOR_EACH_OBJECT statspec[i]->pylons = grf_load_byte(&buf);
+ break;
+
+ case 0x12: /* Cargo types for random triggers */
+ FOR_EACH_OBJECT statspec[i]->cargo_triggers = grf_load_dword(&buf);
+ break;
+
+ case 0x13: /* General flags */
+ FOR_EACH_OBJECT statspec[i]->flags = grf_load_byte(&buf);
+ break;
+
+ case 0x14: /* Overhead wire placement */
+ FOR_EACH_OBJECT statspec[i]->wires = grf_load_byte(&buf);
+ break;
+
+ case 0x15: /* Blocked tiles */
+ FOR_EACH_OBJECT statspec[i]->blocked = grf_load_byte(&buf);
+ break;
+
+ default:
+ ret = true;
+ break;
+ }
+
+ *bufp = buf;
+ return ret;
+}
+
+static bool BridgeChangeInfo(uint brid, int numinfo, int prop, byte **bufp, int len)
+{
+ byte *buf = *bufp;
+ int i;
+ bool ret = false;
+
+ switch (prop) {
+ case 0x08: /* Year of availability */
+ FOR_EACH_OBJECT _bridge[brid + i].avail_year = ORIGINAL_BASE_YEAR + grf_load_byte(&buf);
+ break;
+
+ case 0x09: /* Minimum length */
+ FOR_EACH_OBJECT _bridge[brid + i].min_length = grf_load_byte(&buf);
+ break;
+
+ case 0x0A: /* Maximum length */
+ FOR_EACH_OBJECT _bridge[brid + i].max_length = grf_load_byte(&buf);
+ break;
+
+ case 0x0B: /* Cost factor */
+ FOR_EACH_OBJECT _bridge[brid + i].price = grf_load_byte(&buf);
+ break;
+
+ case 0x0C: /* Maximum speed */
+ FOR_EACH_OBJECT _bridge[brid + i].speed = grf_load_word(&buf);
+ break;
+
+ case 0x0D: /* Bridge sprite tables */
+ FOR_EACH_OBJECT {
+ Bridge *bridge = &_bridge[brid + i];
+ byte tableid = grf_load_byte(&buf);
+ byte numtables = grf_load_byte(&buf);
+
+ if (bridge->sprite_table == NULL) {
+ /* Allocate memory for sprite table pointers and zero out */
+ bridge->sprite_table = calloc(7, sizeof(*bridge->sprite_table));
+ }
+
+ for (; numtables-- != 0; tableid++) {
+ byte sprite;
+
+ if (tableid >= 7) { // skip invalid data
+ grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid);
+ for (sprite = 0; sprite < 32; sprite++) grf_load_dword(&buf);
+ continue;
+ }
+
+ if (bridge->sprite_table[tableid] == NULL) {
+ bridge->sprite_table[tableid] = malloc(32 * sizeof(**bridge->sprite_table));
+ }
+
+ for (sprite = 0; sprite < 32; sprite++)
+ bridge->sprite_table[tableid][sprite] = grf_load_dword(&buf);
+ }
+ }
+ break;
+
+ case 0x0E: /* Flags; bit 0 - disable far pillars */
+ FOR_EACH_OBJECT _bridge[brid + i].flags = grf_load_byte(&buf);
+ break;
+
+ case 0x0F: /* Long format year of availability (year since year 0) */
+ FOR_EACH_OBJECT _bridge[brid + i].avail_year = clamp(grf_load_dword(&buf), MIN_YEAR, MAX_YEAR);
+ break;
+
+ default:
+ ret = true;
+ }
+
+ *bufp = buf;
+ return ret;
+}
+
+static bool GlobalVarChangeInfo(uint gvid, int numinfo, int prop, byte **bufp, int len)
+{
+ byte *buf = *bufp;
+ int i;
+ bool ret = false;
+
+ switch (prop) {
+ case 0x08: /* Cost base factor */
+ FOR_EACH_OBJECT {
+ byte factor = grf_load_byte(&buf);
+ uint price = gvid + i;
+
+ if (price < NUM_PRICES) {
+ SetPriceBaseMultiplier(price, factor);
+ } else {
+ grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price);
+ }
+ }
+ break;
+
+ case 0x0A: // Currency display names
+ FOR_EACH_OBJECT {
+ uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
+ StringID newone = GetGRFStringID(_cur_grffile->grfid, grf_load_word(&buf));
+
+ if ((newone != STR_UNDEFINED) && (curidx < NUM_CURRENCY)) {
+ _currency_specs[curidx].name = newone;
+ }
+ }
+ break;
+
+ case 0x0B: // Currency multipliers
+ FOR_EACH_OBJECT {
+ uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
+ uint32 rate = grf_load_dword(&buf);
+
+ if (curidx < NUM_CURRENCY) {
+ /* TTDPatch uses a multiple of 1000 for its conversion calculations,
+ * which OTTD does not. For this reason, divide grf value by 1000,
+ * to be compatible */
+ _currency_specs[curidx].rate = rate / 1000;
+ } else {
+ grfmsg(1, "GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
+ }
+ }
+ break;
+
+ case 0x0C: // Currency options
+ FOR_EACH_OBJECT {
+ uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
+ uint16 options = grf_load_word(&buf);
+
+ if (curidx < NUM_CURRENCY) {
+ _currency_specs[curidx].separator = GB(options, 0, 8);
+ /* By specifying only one bit, we prevent errors,
+ * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
+ _currency_specs[curidx].symbol_pos = GB(options, 8, 1);
+ } else {
+ grfmsg(1, "GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
+ }
+ }
+ break;
+
+ case 0x0D: // Currency prefix symbol
+ FOR_EACH_OBJECT {
+ uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
+ uint32 tempfix = grf_load_dword(&buf);
+
+ if (curidx < NUM_CURRENCY) {
+ memcpy(_currency_specs[curidx].prefix,&tempfix,4);
+ _currency_specs[curidx].prefix[4] = 0;
+ } else {
+ grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
+ }
+ }
+ break;
+
+ case 0x0E: // Currency suffix symbol
+ FOR_EACH_OBJECT {
+ uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
+ uint32 tempfix = grf_load_dword(&buf);
+
+ if (curidx < NUM_CURRENCY) {
+ memcpy(&_currency_specs[curidx].suffix,&tempfix,4);
+ _currency_specs[curidx].suffix[4] = 0;
+ } else {
+ grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
+ }
+ }
+ break;
+
+ case 0x0F: // Euro introduction dates
+ FOR_EACH_OBJECT {
+ uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
+ Year year_euro = grf_load_word(&buf);
+
+ if (curidx < NUM_CURRENCY) {
+ _currency_specs[curidx].to_euro = year_euro;
+ } else {
+ grfmsg(1, "GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
+ }
+ }
+ break;
+
+ case 0x09: // Cargo translation table
+ case 0x10: // 12 * 32 * B Snow line height table
+ default:
+ ret = true;
+ }
+
+ *bufp = buf;
+ return ret;
+}
+
+static bool SoundEffectChangeInfo(uint sid, int numinfo, int prop, byte **bufp, int len)
+{
+ byte *buf = *bufp;
+ int i;
+ bool ret = false;
+
+ if (_cur_grffile->sound_offset == 0) {
+ grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
+ return false;
+ }
+
+ switch (prop) {
+ case 0x08: /* Relative volume */
+ FOR_EACH_OBJECT {
+ uint sound = sid + i + _cur_grffile->sound_offset - GetNumOriginalSounds();
+
+ if (sound >= GetNumSounds()) {
+ grfmsg(1, "SoundEffectChangeInfo: Sound %d not defined (max %d)", sound, GetNumSounds());
+ } else {
+ GetSound(sound)->volume = grf_load_byte(&buf);
+ }
+ }
+ break;
+
+ case 0x09: /* Priority */
+ FOR_EACH_OBJECT {
+ uint sound = sid + i + _cur_grffile->sound_offset - GetNumOriginalSounds();
+
+ if (sound >= GetNumSounds()) {
+ grfmsg(1, "SoundEffectChangeInfo: Sound %d not defined (max %d)", sound, GetNumSounds());
+ } else {
+ GetSound(sound)->priority = grf_load_byte(&buf);
+ }
+ }
+ break;
+
+ case 0x0A: /* Override old sound */
+ FOR_EACH_OBJECT {
+ uint sound = sid + i + _cur_grffile->sound_offset - GetNumOriginalSounds();
+ uint orig_sound = grf_load_byte(&buf);
+
+ if (sound >= GetNumSounds() || orig_sound >= GetNumSounds()) {
+ grfmsg(1, "SoundEffectChangeInfo: Sound %d or %d not defined (max %d)", sound, orig_sound, GetNumSounds());
+ } else {
+ FileEntry *newfe = GetSound(sound);
+ FileEntry *oldfe = GetSound(orig_sound);
+
+ /* Literally copy the data of the new sound over the original */
+ *oldfe = *newfe;
+ }
+ }
+ break;
+
+ default:
+ ret = true;
+ }
+
+ *bufp = buf;
+ return ret;
+}
+
+/* Action 0x00 */
+static void FeatureChangeInfo(byte *buf, int len)
+{
+ byte *bufend = buf + len;
+ int i;
+
+ /* <00> <feature> <num-props> <num-info> <id> (<property <new-info>)...
+ *
+ * B feature 0, 1, 2 or 3 for trains, road vehicles, ships or planes
+ * 4 for defining new train station sets
+ * B num-props how many properties to change per vehicle/station
+ * B num-info how many vehicles/stations to change
+ * B id ID of first vehicle/station to change, if num-info is
+ * greater than one, this one and the following
+ * vehicles/stations will be changed
+ * B property what property to change, depends on the feature
+ * V new-info new bytes of info (variable size; depends on properties) */
+ /* TODO: Bridges, town houses. */
+
+ static const VCI_Handler handler[] = {
+ /* GSF_TRAIN */ RailVehicleChangeInfo,
+ /* GSF_ROAD */ RoadVehicleChangeInfo,
+ /* GSF_SHIP */ ShipVehicleChangeInfo,
+ /* GSF_AIRCRAFT */ AircraftVehicleChangeInfo,
+ /* GSF_STATION */ StationChangeInfo,
+ /* GSF_CANAL */ NULL,
+ /* GSF_BRIDGE */ BridgeChangeInfo,
+ /* GSF_TOWNHOUSE */ NULL,
+ /* GSF_GLOBALVAR */ GlobalVarChangeInfo,
+ /* GSF_INDUSTRYTILES */NULL,
+ /* GSF_INDUSTRIES */ NULL,
+ /* GSF_CARGOS */ NULL,
+ /* GSF_SOUNDFX */ SoundEffectChangeInfo,
+ };
+
+ uint8 feature;
+ uint8 numprops;
+ uint8 numinfo;
+ byte engine;
+ EngineInfo *ei = NULL;
+
+ if (len == 1) {
+ grfmsg(8, "Silently ignoring one-byte special sprite 0x00");
+ return;
+ }
+
+ check_length(len, 6, "FeatureChangeInfo");
+ buf++;
+ feature = grf_load_byte(&buf);
+ numprops = grf_load_byte(&buf);
+ numinfo = grf_load_byte(&buf);
+ engine = grf_load_byte(&buf);
+
+ grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
+ feature, numprops, engine, numinfo);
+
+ if (feature >= lengthof(handler) || handler[feature] == NULL) {
+ grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature);
+ return;
+ }
+
+ if (feature <= GSF_AIRCRAFT) {
+ if (engine + numinfo > _vehcounts[feature]) {
+ grfmsg(0, "FeatureChangeInfo: Last engine ID %d out of bounds (max %d), skipping", engine + numinfo, _vehcounts[feature]);
+ return;
+ }
+ ei = &_engine_info[engine + _vehshifts[feature]];
+ }
+
+ while (numprops-- && buf < bufend) {
+ uint8 prop = grf_load_byte(&buf);
+ bool ignoring = false;
+
+ switch (feature) {
+ case GSF_TRAIN:
+ case GSF_ROAD:
+ case GSF_SHIP:
+ case GSF_AIRCRAFT:
+ /* Common properties for vehicles */
+ switch (prop) {
+ case 0x00: /* Introduction date */
+ FOR_EACH_OBJECT ei[i].base_intro = grf_load_word(&buf) + DAYS_TILL_ORIGINAL_BASE_YEAR;
+ break;
+
+ case 0x02: /* Decay speed */
+ FOR_EACH_OBJECT SB(ei[i].unk2, 0, 7, grf_load_byte(&buf) & 0x7F);
+ break;
+
+ case 0x03: /* Vehicle life */
+ FOR_EACH_OBJECT ei[i].lifelength = grf_load_byte(&buf);
+ break;
+
+ case 0x04: /* Model life */
+ FOR_EACH_OBJECT ei[i].base_life = grf_load_byte(&buf);
+ break;
+
+ case 0x06: /* Climates available */
+ FOR_EACH_OBJECT ei[i].climates = grf_load_byte(&buf);
+ break;
+
+ case 0x07: /* Loading speed */
+ /* Hyronymus explained me what does
+ * this mean and insists on having a
+ * credit ;-). --pasky */
+ FOR_EACH_OBJECT ei[i].load_amount = grf_load_byte(&buf);
+ break;
+
+ default:
+ if (handler[feature](engine, numinfo, prop, &buf, bufend - buf))
+ ignoring = true;
+ break;
+ }
+ break;
+
+ default:
+ if (handler[feature](engine, numinfo, prop, &buf, bufend - buf))
+ ignoring = true;
+ break;
+ }
+
+ if (ignoring) grfmsg(2, "FeatureChangeInfo: Ignoring property 0x%02X (not implemented)", prop);
+ }
+}
+
+#undef FOR_EACH_OBJECT
+
+/**
+ * Creates a spritegroup representing a callback result
+ * @param value The value that was used to represent this callback result
+ * @return A spritegroup representing that callback result
+ */
+static const SpriteGroup* NewCallBackResultSpriteGroup(uint16 value)
+{
+ SpriteGroup *group = AllocateSpriteGroup();
+
+ group->type = SGT_CALLBACK;
+
+ // Old style callback results have the highest byte 0xFF so signify it is a callback result
+ // New style ones only have the highest bit set (allows 15-bit results, instead of just 8)
+ if ((value >> 8) == 0xFF) {
+ value &= ~0xFF00;
+ } else {
+ value &= ~0x8000;
+ }
+
+ group->g.callback.result = value;
+
+ return group;
+}
+
+/**
+ * Creates a spritegroup representing a sprite number result.
+ * @param value The sprite number.
+ * @param sprites The number of sprites per set.
+ * @return A spritegroup representing the sprite number result.
+ */
+static const SpriteGroup* NewResultSpriteGroup(SpriteID sprite, byte num_sprites)
+{
+ SpriteGroup *group = AllocateSpriteGroup();
+ group->type = SGT_RESULT;
+ group->g.result.sprite = sprite;
+ group->g.result.num_sprites = num_sprites;
+ return group;
+}
+
+/* Action 0x01 */
+static void NewSpriteSet(byte *buf, int len)
+{
+ /* <01> <feature> <num-sets> <num-ent>
+ *
+ * B feature feature to define sprites for
+ * 0, 1, 2, 3: veh-type, 4: train stations
+ * B num-sets number of sprite sets
+ * E num-ent how many entries per sprite set
+ * For vehicles, this is the number of different
+ * vehicle directions in each sprite set
+ * Set num-dirs=8, unless your sprites are symmetric.
+ * In that case, use num-dirs=4.
+ * For stations, must be 12 (hex) for the eighteen
+ * different sprites that make up a station */
+ /* TODO: No stations support. */
+ uint8 feature;
+ uint num_sets;
+ uint num_ents;
+ uint i;
+
+ check_length(len, 4, "NewSpriteSet");
+ buf++;
+ feature = grf_load_byte(&buf);
+ num_sets = grf_load_byte(&buf);
+ num_ents = grf_load_extended(&buf);
+
+ _cur_grffile->spriteset_start = _cur_spriteid;
+ _cur_grffile->spriteset_feature = feature;
+ _cur_grffile->spriteset_numsets = num_sets;
+ _cur_grffile->spriteset_numents = num_ents;
+
+ grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
+ _cur_spriteid, feature, num_sets, num_ents, num_sets * num_ents
+ );
+
+ for (i = 0; i < num_sets * num_ents; i++) {
+ LoadNextSprite(_cur_spriteid++, _file_index);
+ _nfo_line++;
+ }
+}
+
+/* Helper function to either create a callback or link to a previously
+ * defined spritegroup. */
+static const SpriteGroup* GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
+{
+ if (HASBIT(groupid, 15)) return NewCallBackResultSpriteGroup(groupid);
+
+ if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
+ grfmsg(1, "NewSpriteGroup(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
+ return NULL;
+ }
+
+ return _cur_grffile->spritegroups[groupid];
+}
+
+/* Helper function to either create a callback or a result sprite group. */
+static const SpriteGroup* CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid, uint16 num_sprites)
+{
+ if (HASBIT(spriteid, 15)) return NewCallBackResultSpriteGroup(spriteid);
+
+ if (spriteid >= _cur_grffile->spriteset_numsets) {
+ grfmsg(1, "NewSpriteGroup(0x%02X:0x%02X): Sprite set %u invalid, max %u", setid, type, spriteid, _cur_grffile->spriteset_numsets);
+ return NULL;
+ }
+
+ /* Check if the sprite is within range. This can fail if the Action 0x01
+ * is skipped, as TTDPatch mandates that Action 0x02s must be processed.
+ * We don't have that rule, but must live by the Patch... */
+ if (_cur_grffile->spriteset_start + spriteid * num_sprites + num_sprites > _cur_spriteid) {
+ grfmsg(1, "NewSpriteGroup(0x%02X:0x%02X): Real Sprite IDs 0x%04X - 0x%04X do not (all) exist (max 0x%04X), leaving empty",
+ setid, type,
+ _cur_grffile->spriteset_start + spriteid * num_sprites,
+ _cur_grffile->spriteset_start + spriteid * num_sprites + num_sprites - 1, _cur_spriteid - 1);
+ return NULL;
+ }
+
+ if (feature != _cur_grffile->spriteset_feature) {
+ grfmsg(1, "NewSpriteGroup(0x%02X:0x%02X): Sprite set feature 0x%02X does not match action feature 0x%02X, skipping",
+ _cur_grffile->spriteset_feature, feature);
+ return NULL;
+ }
+
+ return NewResultSpriteGroup(_cur_grffile->spriteset_start + spriteid * num_sprites, num_sprites);
+}
+
+/* Action 0x02 */
+static void NewSpriteGroup(byte *buf, int len)
+{
+ /* <02> <feature> <set-id> <type/num-entries> <feature-specific-data...>
+ *
+ * B feature see action 1
+ * B set-id ID of this particular definition
+ * B type/num-entries
+ * if 80 or greater, this is a randomized or variational
+ * list definition, see below
+ * otherwise it specifies a number of entries, the exact
+ * meaning depends on the feature
+ * V feature-specific-data (huge mess, don't even look it up --pasky) */
+ uint8 feature;
+ uint8 setid;
+ uint8 type;
+ SpriteGroup *group = NULL;
+ byte *bufend = buf + len;
+
+ check_length(len, 5, "NewSpriteGroup");
+ buf++;
+
+ feature = grf_load_byte(&buf);
+ setid = grf_load_byte(&buf);
+ type = grf_load_byte(&buf);
+
+ if (setid >= _cur_grffile->spritegroups_count) {
+ // Allocate memory for new sprite group references.
+ _cur_grffile->spritegroups = realloc(_cur_grffile->spritegroups, (setid + 1) * sizeof(*_cur_grffile->spritegroups));
+ // Initialise new space to NULL
+ for (; _cur_grffile->spritegroups_count < (setid + 1); _cur_grffile->spritegroups_count++)
+ _cur_grffile->spritegroups[_cur_grffile->spritegroups_count] = NULL;
+ }
+
+ switch (type) {
+ /* Deterministic Sprite Group */
+ case 0x81: // Self scope, byte
+ case 0x82: // Parent scope, byte
+ case 0x85: // Self scope, word
+ case 0x86: // Parent scope, word
+ case 0x89: // Self scope, dword
+ case 0x8A: // Parent scope, dword
+ {
+ byte varadjust;
+ byte varsize;
+ uint i;
+
+ /* Check we can load the var size parameter */
+ check_length(bufend - buf, 1, "NewSpriteGroup (Deterministic) (1)");
+
+ group = AllocateSpriteGroup();
+ group->type = SGT_DETERMINISTIC;
+ group->g.determ.var_scope = HASBIT(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
+
+ switch (GB(type, 2, 2)) {
+ default: NOT_REACHED();
+ case 0: group->g.determ.size = DSG_SIZE_BYTE; varsize = 1; break;
+ case 1: group->g.determ.size = DSG_SIZE_WORD; varsize = 2; break;
+ case 2: group->g.determ.size = DSG_SIZE_DWORD; varsize = 4; break;
+ }
+
+ check_length(bufend - buf, 5 + varsize, "NewSpriteGroup (Deterministic) (2)");
+
+ /* Loop through the var adjusts. Unfortunately we don't know how many we have
+ * from the outset, so we shall have to keep reallocing. */
+ do {
+ DeterministicSpriteGroupAdjust *adjust;
+
+ if (group->g.determ.num_adjusts > 0) {
+ check_length(bufend - buf, 2 + varsize + 3, "NewSpriteGroup (Deterministic) (3)");
+ }
+
+ group->g.determ.num_adjusts++;
+ group->g.determ.adjusts = realloc(group->g.determ.adjusts, group->g.determ.num_adjusts * sizeof(*group->g.determ.adjusts));
+
+ adjust = &group->g.determ.adjusts[group->g.determ.num_adjusts - 1];
+
+ /* The first var adjust doesn't have an operation specified, so we set it to add. */
+ adjust->operation = group->g.determ.num_adjusts == 1 ? DSGA_OP_ADD : grf_load_byte(&buf);
+ adjust->variable = grf_load_byte(&buf);
+ adjust->parameter = IS_BYTE_INSIDE(adjust->variable, 0x60, 0x80) ? grf_load_byte(&buf) : 0;
+
+ varadjust = grf_load_byte(&buf);
+ adjust->shift_num = GB(varadjust, 0, 5);
+ adjust->type = GB(varadjust, 6, 2);
+ adjust->and_mask = grf_load_var(varsize, &buf);
+
+ if (adjust->type != DSGA_TYPE_NONE) {
+ adjust->add_val = grf_load_var(varsize, &buf);
+ adjust->divmod_val = grf_load_var(varsize, &buf);
+ } else {
+ adjust->add_val = 0;
+ adjust->divmod_val = 0;
+ }
+
+ /* Continue reading var adjusts while bit 5 is set. */
+ } while (HASBIT(varadjust, 5));
+
+ group->g.determ.num_ranges = grf_load_byte(&buf);
+ group->g.determ.ranges = calloc(group->g.determ.num_ranges, sizeof(*group->g.determ.ranges));
+
+ check_length(bufend - buf, 2 + (2 + 2 * varsize) * group->g.determ.num_ranges, "NewSpriteGroup (Deterministic)");
+
+ for (i = 0; i < group->g.determ.num_ranges; i++) {
+ group->g.determ.ranges[i].group = GetGroupFromGroupID(setid, type, grf_load_word(&buf));
+ group->g.determ.ranges[i].low = grf_load_var(varsize, &buf);
+ group->g.determ.ranges[i].high = grf_load_var(varsize, &buf);
+ }
+
+ group->g.determ.default_group = GetGroupFromGroupID(setid, type, grf_load_word(&buf));
+ break;
+ }
+
+ /* Randomized Sprite Group */
+ case 0x80: // Self scope
+ case 0x83: // Parent scope
+ {
+ byte triggers;
+ uint i;
+
+ check_length(bufend - buf, 7, "NewSpriteGroup (Randomized) (1)");
+
+ group = AllocateSpriteGroup();
+ group->type = SGT_RANDOMIZED;
+ group->g.random.var_scope = HASBIT(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
+
+ triggers = grf_load_byte(&buf);
+ group->g.random.triggers = GB(triggers, 0, 7);
+ group->g.random.cmp_mode = HASBIT(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
+ group->g.random.lowest_randbit = grf_load_byte(&buf);
+ group->g.random.num_groups = grf_load_byte(&buf);
+ group->g.random.groups = calloc(group->g.random.num_groups, sizeof(*group->g.random.groups));
+
+ check_length(bufend - buf, 2 * group->g.random.num_groups, "NewSpriteGroup (Randomized) (2)");
+
+ for (i = 0; i < group->g.random.num_groups; i++) {
+ group->g.random.groups[i] = GetGroupFromGroupID(setid, type, grf_load_word(&buf));
+ }
+
+ break;
+ }
+
+ /* Neither a variable or randomized sprite group... must be a real group */
+ default:
+ {
+
+
+ switch (feature) {
+ case GSF_TRAIN:
+ case GSF_ROAD:
+ case GSF_SHIP:
+ case GSF_AIRCRAFT:
+ case GSF_STATION:
+ {
+ byte sprites = _cur_grffile->spriteset_numents;
+ byte num_loaded = type;
+ byte num_loading = grf_load_byte(&buf);
+ uint i;
+
+ if (_cur_grffile->spriteset_start == 0) {
+ grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
+ return;
+ }
+
+ check_length(bufend - buf, 2 * num_loaded + 2 * num_loading, "NewSpriteGroup (Real) (1)");
+
+ group = AllocateSpriteGroup();
+ group->type = SGT_REAL;
+
+ group->g.real.num_loaded = num_loaded;
+ group->g.real.num_loading = num_loading;
+ if (num_loaded > 0) group->g.real.loaded = calloc(num_loaded, sizeof(*group->g.real.loaded));
+ if (num_loading > 0) group->g.real.loading = calloc(num_loading, sizeof(*group->g.real.loading));
+
+ grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u views, %u loaded, %u loading",
+ setid, sprites, num_loaded, num_loading);
+
+ for (i = 0; i < num_loaded; i++) {
+ uint16 spriteid = grf_load_word(&buf);
+ group->g.real.loaded[i] = CreateGroupFromGroupID(feature, setid, type, spriteid, sprites);
+ grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
+ }
+
+ for (i = 0; i < num_loading; i++) {
+ uint16 spriteid = grf_load_word(&buf);
+ group->g.real.loading[i] = CreateGroupFromGroupID(feature, setid, type, spriteid, sprites);
+ grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
+ }
+
+ break;
+ }
+
+ /* Loading of Tile Layout and Production Callback groups would happen here */
+ default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature);
+ }
+ }
+ }
+
+ _cur_grffile->spritegroups[setid] = group;
+}
+
+/* Action 0x03 */
+static void FeatureMapSpriteGroup(byte *buf, int len)
+{
+ /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
+ * id-list := [<id>] [id-list]
+ * cargo-list := <cargo-type> <cid> [cargo-list]
+ *
+ * B feature see action 0
+ * B n-id bits 0-6: how many IDs this definition applies to
+ * bit 7: if set, this is a wagon override definition (see below)
+ * B ids the IDs for which this definition applies
+ * B num-cid number of cargo IDs (sprite group IDs) in this definition
+ * can be zero, in that case the def-cid is used always
+ * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
+ * W cid cargo ID (sprite group ID) for this type of cargo
+ * W def-cid default cargo ID (sprite group ID) */
+ /* TODO: Bridges, town houses. */
+ /* TODO: Multiple cargo support could be useful even for trains/cars -
+ * cargo id 0xff is used for showing images in the build train list. */
+
+ static byte *last_engines;
+ static int last_engines_count;
+ uint8 feature;
+ uint8 idcount;
+ bool wagover;
+ uint8 cidcount;
+ int c, i;
+
+ check_length(len, 6, "FeatureMapSpriteGroup");
+ feature = buf[1];
+ idcount = buf[2] & 0x7F;
+ wagover = (buf[2] & 0x80) == 0x80;
+ check_length(len, 3 + idcount, "FeatureMapSpriteGroup");
+
+ /* If ``n-id'' (or ``idcount'') is zero, this is a ``feature
+ * callback''. */
+ if (idcount == 0) {
+ grfmsg(2, "FeatureMapSpriteGroup: Feature callbacks not implemented yet");
+ return;
+ }
+
+ cidcount = buf[3 + idcount];
+ check_length(len, 4 + idcount + cidcount * 3, "FeatureMapSpriteGroup");
+
+ grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids, %d cids, wagon override %d",
+ feature, idcount, cidcount, wagover);
+
+ if (feature > GSF_STATION) {
+ grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
+ return;
+ }
+
+
+ if (feature == GSF_STATION) {
+ // We do things differently for stations.
+
+ for (i = 0; i < idcount; i++) {
+ uint8 stid = buf[3 + i];
+ StationSpec *statspec = _cur_grffile->stations[stid];
+ byte *bp = &buf[4 + idcount];
+
+ for (c = 0; c < cidcount; c++) {
+ uint8 ctype = grf_load_byte(&bp);
+ uint16 groupid = grf_load_word(&bp);
+
+ if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
+ grfmsg(1, "FeatureMapSpriteGroup: Spriteset 0x%04X out of range 0x%X or empty, skipping",
+ groupid, _cur_grffile->spritegroups_count);
+ return;
+ }
+
+ if (ctype == 0xFE) ctype = GC_DEFAULT_NA;
+ if (ctype == 0xFF) ctype = GC_PURCHASE;
+
+ if (ctype >= NUM_GLOBAL_CID) {
+ grfmsg(1, "FeatureMapSpriteGroup: Cargo type %d out of range, skipping.", ctype);
+ continue;
+ }
+
+ statspec->spritegroup[ctype] = _cur_grffile->spritegroups[groupid];
+ }
+ }
+
+ {
+ byte *bp = buf + 4 + idcount + cidcount * 3;
+ uint16 groupid = grf_load_word(&bp);
+
+ if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
+ grfmsg(1, "FeatureMapSpriteGroup: Spriteset 0x%04X out of range 0x%X or empty, skipping",
+ groupid, _cur_grffile->spritegroups_count);
+ return;
+ }
+
+ for (i = 0; i < idcount; i++) {
+ uint8 stid = buf[3 + i];
+ StationSpec *statspec = _cur_grffile->stations[stid];
+
+ statspec->spritegroup[GC_DEFAULT] = _cur_grffile->spritegroups[groupid];
+ statspec->grfid = _cur_grffile->grfid;
+ statspec->localidx = stid;
+ SetCustomStationSpec(statspec);
+ }
+ }
+ return;
+ }
+
+ // FIXME: Tropicset contains things like:
+ // 03 00 01 19 01 00 00 00 00 - this is missing one 00 at the end,
+ // what should we exactly do with that? --pasky
+
+ if (_cur_grffile->spriteset_start == 0 || _cur_grffile->spritegroups == 0) {
+ grfmsg(1, "FeatureMapSpriteGroup: No sprite set to work on! Skipping");
+ return;
+ }
+
+ if (!wagover && last_engines_count != idcount) {
+ last_engines = realloc(last_engines, idcount);
+ last_engines_count = idcount;
+ }
+
+ if (wagover) {
+ if (last_engines_count == 0) {
+ grfmsg(0, "FeatureMapSpriteGroup: WagonOverride: No engine to do override with");
+ return;
+ }
+ grfmsg(6, "FeatureMapSpriteGroup: WagonOverride: %u engines, %u wagons",
+ last_engines_count, idcount);
+ }
+
+
+ for (i = 0; i < idcount; i++) {
+ uint8 engine_id = buf[3 + i];
+ uint8 engine = engine_id + _vehshifts[feature];
+ byte *bp = &buf[4 + idcount];
+
+ if (engine_id > _vehcounts[feature]) {
+ grfmsg(0, "Id %u for feature 0x%02X is out of bounds", engine_id, feature);
+ return;
+ }
+
+ grfmsg(7, "FeatureMapSpriteGroup: [%d] Engine %d...", i, engine);
+
+ for (c = 0; c < cidcount; c++) {
+ uint8 ctype = grf_load_byte(&bp);
+ uint16 groupid = grf_load_word(&bp);
+
+ grfmsg(8, "FeatureMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
+
+ if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
+ grfmsg(1, "FeatureMapSpriteGroup: Spriteset 0x%04X out of range 0x%X or empty, skipping", groupid, _cur_grffile->spritegroups_count);
+ return;
+ }
+
+ if (ctype == GC_INVALID) ctype = GC_PURCHASE;
+
+ if (ctype >= NUM_GLOBAL_CID) {
+ grfmsg(1, "FeatureMapSpriteGroup: Cargo type %d out of range, skipping.", ctype);
+ continue;
+ }
+
+ if (wagover) {
+ SetWagonOverrideSprites(engine, ctype, _cur_grffile->spritegroups[groupid], last_engines, last_engines_count);
+ } else {
+ SetCustomEngineSprites(engine, ctype, _cur_grffile->spritegroups[groupid]);
+ last_engines[i] = engine;
+ }
+ }
+ }
+
+ {
+ byte *bp = buf + 4 + idcount + cidcount * 3;
+ uint16 groupid = grf_load_word(&bp);
+
+ grfmsg(8, "-- Default group id 0x%04X", groupid);
+
+ for (i = 0; i < idcount; i++) {
+ uint8 engine = buf[3 + i] + _vehshifts[feature];
+
+ // Don't tell me you don't love duplicated code!
+ if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
+ grfmsg(1, "FeatureMapSpriteGroup: Spriteset 0x%04X out of range 0x%X or empty, skipping", groupid, _cur_grffile->spritegroups_count);
+ return;
+ }
+
+ if (wagover) {
+ /* If the ID for this action 3 is the same as the vehicle ID,
+ * this indicates we have a helicopter rotor override. */
+ if (feature == GSF_AIRCRAFT && engine == last_engines[i]) {
+ SetRotorOverrideSprites(engine, _cur_grffile->spritegroups[groupid]);
+ } else {
+ // TODO: No multiple cargo types per vehicle yet. --pasky
+ SetWagonOverrideSprites(engine, GC_DEFAULT, _cur_grffile->spritegroups[groupid], last_engines, last_engines_count);
+ }
+ } else {
+ SetCustomEngineSprites(engine, GC_DEFAULT, _cur_grffile->spritegroups[groupid]);
+ SetEngineGRF(engine, _cur_grffile);
+ last_engines[i] = engine;
+ }
+ }
+ }
+}
+
+/* Action 0x04 */
+static void FeatureNewName(byte *buf, int len)
+{
+ /* <04> <veh-type> <language-id> <num-veh> <offset> <data...>
+ *
+ * B veh-type see action 0 (as 00..07, + 0A
+ * But IF veh-type = 48, then generic text
+ * B language-id If bit 6 is set, This is the extended language scheme,
+ with up to 64 language.
+ Otherwise, it is a mapping where set bits have meaning
+ 0 = american, 1 = english, 2 = german, 3 = french, 4 = spanish
+ Bit 7 set means this is a generic text, not a vehicle one (or else)
+ * B num-veh number of vehicles which are getting a new name
+ * B/W offset number of the first vehicle that gets a new name
+ * Byte : ID of vehicle to change
+ * Word : ID of string to change/add
+ * S data new texts, each of them zero-terminated, after
+ * which the next name begins. */
+ /* TODO: No support for changing non-vehicle text. Perhaps we shouldn't
+ * implement it at all, but it could be useful for some "modpacks"
+ * (completely new scenarios changing all graphics and logically also
+ * factory names etc). We should then also support all languages (by
+ * name), not only the original four ones. --pasky
+ * All of the above are coming. In Time. Some sooner than others :)*/
+
+ uint8 feature;
+ uint8 lang;
+ uint8 num;
+ uint16 id;
+ uint16 endid;
+ const char* name;
+ bool new_scheme = _cur_grffile->grf_version >= 7;
+ bool generic;
+
+ check_length(len, 6, "FeatureNewName");
+ buf++;
+ feature = grf_load_byte(&buf);
+ lang = grf_load_byte(&buf);
+ num = grf_load_byte(&buf);
+ generic = HASBIT(lang, 7);
+ id = generic ? grf_load_word(&buf) : grf_load_byte(&buf);
+
+ CLRBIT(lang, 7);
+
+ if (feature <= GSF_AIRCRAFT && id < _vehcounts[feature]) {
+ id += _vehshifts[feature];
+ }
+ endid = id + num;
+
+ grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
+ id, endid, feature, lang);
+
+ name = (const char*)buf; /*transfer read value*/
+ len -= generic ? 6 : 5;
+
+ for (; id < endid && len > 0; id++) {
+ size_t ofs = strlen(name) + 1;
+
+ if (ofs < 128) {
+ grfmsg(8, "FeatureNewName: %d <- %s", id, name);
+
+ switch (feature) {
+ case GSF_TRAIN:
+ case GSF_ROAD:
+ case GSF_SHIP:
+ case GSF_AIRCRAFT: {
+ if (id < TOTAL_NUM_ENGINES) {
+ StringID string = AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_8000_KIRBY_PAUL_TANK_STEAM + id);
+ SetCustomEngineName(id, string);
+ } else {
+ AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, id);
+ }
+ break;
+ }
+
+ default:
+ switch (GB(id, 8, 8)) {
+ case 0xC4: /* Station class name */
+ if (_cur_grffile->stations == NULL || _cur_grffile->stations[GB(id, 0, 8)] == NULL) {
+ grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
+ } else {
+ StationClassID sclass = _cur_grffile->stations[GB(id, 0, 8)]->sclass;
+ SetStationClassName(sclass, AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED));
+ }
+ break;
+
+ case 0xC5: /* Station name */
+ if (_cur_grffile->stations == NULL || _cur_grffile->stations[GB(id, 0, 8)] == NULL) {
+ grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
+ } else {
+ _cur_grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
+ }
+ break;
+
+ case 0xC9:
+ case 0xD0:
+ case 0xDC:
+ AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
+ break;
+
+ default:
+ grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
+ break;
+ }
+ break;
+
+#if 0
+ case GSF_CANAL :
+ case GSF_BRIDGE :
+ case GSF_TOWNHOUSE :
+ AddGRFString(_cur_spriteid, id, lang, name);
+ switch (GB(id, 8,8)) {
+ case 0xC9: /* House name */
+ default:
+ grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
+ }
+ break;
+
+ case GSF_INDUSTRIES :
+ case 0x48 : /* for generic strings */
+ AddGRFString(_cur_spriteid, id, lang, name);
+ break;
+ default :
+ grfmsg(7, "FeatureNewName: Unsupported feature (0x%02X)", feature);
+ break;
+#endif
+ }
+ } else {
+ /* ofs is the string length + 1, so if the string is empty, ofs
+ * is 1 */
+ if (ofs == 1) {
+ grfmsg(7, "FeatureNewName: Can't add empty name");
+ } else {
+ grfmsg(7, "FeatureNewName: Too long a name (%d)", ofs);
+ }
+ }
+ name += ofs;
+ len -= (int)ofs;
+ }
+}
+
+/* Action 0x05 */
+static void GraphicsNew(byte *buf, int len)
+{
+ /* <05> <graphics-type> <num-sprites> <other data...>
+ *
+ * B graphics-type What set of graphics the sprites define.
+ * E num-sprites How many sprites are in this set?
+ * V other data Graphics type specific data. Currently unused. */
+ /* TODO */
+
+ uint8 type;
+ uint16 num;
+ SpriteID replace = 0;
+
+ check_length(len, 2, "GraphicsNew");
+ buf++;
+ type = grf_load_byte(&buf);
+ num = grf_load_extended(&buf);
+
+ switch (type) {
+ case 0x04: /* Signal graphics */
+ if (num != 112 && num != 240) {
+ grfmsg(1, "GraphicsNews: Signal graphics sprite count must be 112 or 240, skipping");
+ return;
+ }
+ _signal_base = _cur_spriteid;
+ break;
+
+ case 0x05: /* Catenary graphics */
+ if (num != 48) {
+ grfmsg(1, "GraphicsNews: Catenary graphics sprite count must be 48, skipping");
+ return;
+ }
+ replace = SPR_ELRAIL_BASE + 3;
+ break;
+
+ case 0x06: /* Foundations */
+ if (num != 74) {
+ grfmsg(1, "GraphicsNews: Foundation graphics sprite count must be 74, skipping");
+ return;
+ }
+ replace = SPR_SLOPES_BASE;
+ break;
+
+ case 0x08: /* Canal graphics */
+ if (num != 65) {
+ grfmsg(1, "GraphicsNews: Canal graphics sprite count must be 65, skipping");
+ return;
+ }
+ replace = SPR_CANALS_BASE + 5;
+ break;
+
+ case 0x0D: /* Coast graphics */
+ if (num != 16) {
+ grfmsg(1, "GraphicsNews: Coast graphics sprite count must be 16, skipping");
+ return;
+ }
+ _coast_base = _cur_spriteid;
+ break;
+
+ default:
+ grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)",
+ type, num);
+ return;
+ }
+
+ if (replace == 0) {
+ grfmsg(2, "GraphicsNew: Loading %u sprites of type 0x%02X at SpriteID 0x%04X", num, type, _cur_spriteid);
+ } else {
+ grfmsg(2, "GraphicsNew: Replacing %u sprites of type 0x%02X at SpriteID 0x%04X", num, type, replace);
+ }
+
+ for (; num > 0; num--) {
+ LoadNextSprite(replace == 0 ? _cur_spriteid++ : replace++, _file_index);
+ _nfo_line++;
+ }
+}
+
+static uint32 GetParamVal(byte param, uint32 *cond_val)
+{
+ switch (param) {
+ case 0x81: /* current year */
+ return clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
+
+ case 0x83: /* current climate, 0=temp, 1=arctic, 2=trop, 3=toyland */
+ return _opt.landscape;
+
+ case 0x84: /* GRF loading stage */
+ return (_cur_stage > GLS_INIT) | ((_cur_stage == GLS_ACTIVATION) << 9);
+
+ case 0x85: /* TTDPatch flags, only for bit tests */
+ if (cond_val == NULL) {
+ /* Supported in Action 0x07 and 0x09, not 0x0D */
+ return 0;
+ } else {
+ uint32 param_val = _ttdpatch_flags[*cond_val / 0x20];
+ *cond_val %= 0x20;
+ return param_val;
+ }
+
+ case 0x86: /* road traffic side, bit 4 clear=left, set=right */
+ return _opt.road_side << 4;
+
+ case 0x88: /* GRF ID check */
+ return 0;
+
+ case 0x8B: { /* TTDPatch version */
+ uint major = 2;
+ uint minor = 6;
+ uint revision = 0; // special case: 2.0.1 is 2.0.10
+ uint build = 1168;
+ return (major << 24) | (minor << 20) | (revision << 16) | build;
+ }
+
+ case 0x8D: /* TTD Version, 00=DOS, 01=Windows */
+ return !_use_dos_palette;
+
+ case 0x8E: /* Y-offset for train sprites */
+ return _traininfo_vehicle_pitch;
+
+ case 0x92: /* Game mode */
+ return _game_mode;
+
+ case 0x9A: /* Always -1 */
+ return -1;
+
+ case 0x9D: /* TTD Platform, 00=TTDPatch, 01=OpenTTD */
+ return 1;
+
+ case 0x9E: /* Miscellaneous GRF features */
+ return _misc_grf_features;
+
+ default:
+ /* GRF Parameter */
+ if (param < 0x80) return _cur_grffile->param[param];
+
+ /* In-game variable. */
+ grfmsg(1, "Unsupported in-game variable 0x%02X", param);
+ return -1;
+ }
+}
+
+/* Action 0x06 */
+static void CfgApply(byte *buf, int len)
+{
+ /* <06> <param-num> <param-size> <offset> ... <FF>
+ *
+ * B param-num Number of parameter to substitute (First = "zero")
+ * Ignored if that parameter was not specified in newgrf.cfg
+ * B param-size How many bytes to replace. If larger than 4, the
+ * bytes of the following parameter are used. In that
+ * case, nothing is applied unless *all* parameters
+ * were specified.
+ * B offset Offset into data from beginning of next sprite
+ * to place where parameter is to be stored. */
+
+ /* Preload the next sprite */
+ uint32 pos = FioGetPos();
+ uint16 num = FioReadWord();
+ uint8 type = FioReadByte();
+
+ /* Check if the sprite is a pseudo sprite. We can't operate on real sprites. */
+ if (type == 0xFF) {
+ _preload_sprite = malloc(num);
+ FioReadBlock(_preload_sprite, num);
+ }
+
+ /* Reset the file position to the start of the next sprite */
+ FioSeekTo(pos, SEEK_SET);
+
+ if (type != 0xFF) {
+ grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
+ return;
+ }
+
+ /* Now perform the Action 0x06 on our data. */
+ buf++;
+
+ for (;;) {
+ uint i;
+ uint param_num;
+ uint param_size;
+ uint offset;
+ bool add_value;
+
+ /* Read the parameter to apply. 0xFF indicates no more data to change. */
+ param_num = grf_load_byte(&buf);
+ if (param_num == 0xFF) break;
+
+ /* Get the size of the parameter to use. If the size covers multiple
+ * double words, sequential parameter values are used. */
+ param_size = grf_load_byte(&buf);
+
+ /* Bit 7 of param_size indicates we should add to the original value
+ * instead of replacing it. */
+ add_value = HASBIT(param_size, 7);
+ param_size = GB(param_size, 0, 7);
+
+ /* Where to apply the data to within the pseudo sprite data. */
+ offset = grf_load_extended(&buf);
+
+ /* If the parameter is a GRF parameter (not an internal variable) check
+ * if it (and all further sequential parameters) has been defined. */
+ if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur_grffile->param_end) {
+ grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
+ break;
+ }
+
+ grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
+
+ for (i = 0; i < param_size; i++) {
+ uint32 value = GetParamVal(param_num + i / 4, NULL);
+
+ if (add_value) {
+ _preload_sprite[offset + i] += GB(value, (i % 4) * 8, 8);
+ } else {
+ _preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
+ }
+ }
+ }
+}
+
+/* Action 0x07 */
+/* Action 0x09 */
+static void SkipIf(byte *buf, int len)
+{
+ /* <07/09> <param-num> <param-size> <condition-type> <value> <num-sprites>
+ *
+ * B param-num
+ * B param-size
+ * B condition-type
+ * V value
+ * B num-sprites */
+ /* TODO: More params. More condition types. */
+ uint8 param;
+ uint8 paramsize;
+ uint8 condtype;
+ uint8 numsprites;
+ uint32 param_val = 0;
+ uint32 cond_val = 0;
+ uint32 mask = 0;
+ bool result;
+ GRFLabel *label;
+ GRFLabel *choice = NULL;
+
+ check_length(len, 6, "SkipIf");
+ buf++;
+ param = grf_load_byte(&buf);
+ paramsize = grf_load_byte(&buf);
+ condtype = grf_load_byte(&buf);
+
+ if (condtype < 2) {
+ /* Always 1 for bit tests, the given value should be ignored. */
+ paramsize = 1;
+ }
+
+ switch (paramsize) {
+ case 4: cond_val = grf_load_dword(&buf); mask = 0xFFFFFFFF; break;
+ case 2: cond_val = grf_load_word(&buf); mask = 0x0000FFFF; break;
+ case 1: cond_val = grf_load_byte(&buf); mask = 0x000000FF; break;
+ default: break;
+ }
+
+ if (param < 0x80 && _cur_grffile->param_end <= param) {
+ grfmsg(7, "Param %d undefined, skipping test", param);
+ return;
+ }
+
+ param_val = GetParamVal(param, &cond_val);
+
+ grfmsg(7, "Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
+
+ if (param == 0x88) {
+ /* GRF ID checks */
+
+ const GRFConfig *c = GetGRFConfig(cond_val);
+
+ if (condtype != 10 && c == NULL) {
+ grfmsg(7, "GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
+ return;
+ }
+
+ switch (condtype) {
+ /* Tests 6 to 10 are only for param 0x88, GRFID checks */
+ case 6: /* Is GRFID active? */
+ result = HASBIT(c->flags, GCF_ACTIVATED);
+ break;
+
+ case 7: /* Is GRFID non-active? */
+ result = !HASBIT(c->flags, GCF_ACTIVATED);
+ break;
+
+ case 8: /* GRFID is not but will be active? */
+ result = !HASBIT(c->flags, GCF_ACTIVATED) && !HASBIT(c->flags, GCF_DISABLED);
+ break;
+
+ case 9: /* GRFID is or will be active? */
+ result = !HASBIT(c->flags, GCF_NOT_FOUND) && !HASBIT(c->flags, GCF_DISABLED);
+ break;
+
+ case 10: /* GRFID is not nor will be active */
+ /* This is the only condtype that doesn't get ignored if the GRFID is not found */
+ result = c == NULL || HASBIT(c->flags, GCF_DISABLED) || HASBIT(c->flags, GCF_NOT_FOUND);
+ break;
+
+ default: grfmsg(1, "Unsupported GRF test %d. Ignoring", condtype); return;
+ }
+ } else {
+ /* Parameter or variable tests */
+ switch (condtype) {
+ case 0: result = !!(param_val & (1 << cond_val));
+ break;
+ case 1: result = !(param_val & (1 << cond_val));
+ break;
+ case 2: result = (param_val & mask) == cond_val;
+ break;
+ case 3: result = (param_val & mask) != cond_val;
+ break;
+ case 4: result = (param_val & mask) < cond_val;
+ break;
+ case 5: result = (param_val & mask) > cond_val;
+ break;
+
+ default: grfmsg(1, "Unsupported test %d. Ignoring", condtype); return;
+ }
+ }
+
+ if (!result) {
+ grfmsg(2, "Not skipping sprites, test was false");
+ return;
+ }
+
+ numsprites = grf_load_byte(&buf);
+
+ /* numsprites can be a GOTO label if it has been defined in the GRF
+ * file. The jump will always be the first matching label that follows
+ * the current nfo_line. If no matching label is found, the first matching
+ * label in the file is used. */
+ for (label = _cur_grffile->label; label != NULL; label = label->next) {
+ if (label->label != numsprites) continue;
+
+ /* Remember a goto before the current line */
+ if (choice == NULL) choice = label;
+ /* If we find a label here, this is definitely good */
+ if (label->nfo_line > _nfo_line) {
+ choice = label;
+ break;
+ }
+ }
+
+ if (choice != NULL) {
+ grfmsg(2, "Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
+ FioSeekTo(choice->pos, SEEK_SET);
+ _nfo_line = choice->nfo_line;
+ return;
+ }
+
+ grfmsg(2, "Skipping %d sprites, test was true", numsprites);
+ _skip_sprites = numsprites;
+ if (_skip_sprites == 0) {
+ /* Zero means there are no sprites to skip, so
+ * we use -1 to indicate that all further
+ * sprites should be skipped. */
+ _skip_sprites = -1;
+ }
+}
+
+
+/* Action 0x08 (GLS_SAFETYSCAN) */
+static void SafeInfo(byte *buf, int len)
+{
+ uint8 version;
+ uint32 grfid;
+ const char *name;
+ const char *info;
+ int name_len;
+ int info_len;
+
+ check_length(len, 8, "Info"); buf++;
+ version = grf_load_byte(&buf);
+ grfid = grf_load_dword(&buf);
+
+ _cur_grfconfig->grfid = grfid;
+
+ /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
+ if (GB(grfid, 24, 8) == 0xFF) SETBIT(_cur_grfconfig->flags, GCF_SYSTEM);
+
+ len -= 6;
+ name = (const char*)buf;
+ name_len = ttd_strnlen(name, len);
+
+ if (name_len < len) {
+ _cur_grfconfig->name = TranslateTTDPatchCodes(name);
+
+ len -= name_len + 1;
+ info = name + name_len + 1;
+ info_len = ttd_strnlen(info, len);
+
+ if (info_len < len) _cur_grfconfig->info = TranslateTTDPatchCodes(info);
+ }
+}
+
+/* Action 0x08 (GLS_INFOSCAN) */
+static void ScanInfo(byte *buf, int len)
+{
+ SafeInfo(buf, len);
+
+ /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
+ _skip_sprites = -1;
+}
+
+/* Action 0x08 */
+static void GRFInfo(byte *buf, int len)
+{
+ /* <08> <version> <grf-id> <name> <info>
+ *
+ * B version newgrf version, currently 06
+ * 4*B grf-id globally unique ID of this .grf file
+ * S name name of this .grf set
+ * S info string describing the set, and e.g. author and copyright */
+ /* TODO: Check version. (We should have own versioning done somehow.) */
+ uint8 version;
+ uint32 grfid;
+ const char *name;
+
+ check_length(len, 8, "GRFInfo"); buf++;
+ version = grf_load_byte(&buf);
+ grfid = grf_load_dword(&buf);
+ name = (const char*)buf;
+
+ _cur_grffile->grfid = grfid;
+ _cur_grffile->grf_version = version;
+ SETBIT(_cur_grfconfig->flags, GCF_ACTIVATED);
+
+ /* Do swap the GRFID for displaying purposes since people expect that */
+ DEBUG(grf, 1, "Loaded GRFv%d set %08lX - %s", version, BSWAP32(grfid), name);
+}
+
+/* Action 0x0A */
+static void SpriteReplace(byte *buf, int len)
+{
+ /* <0A> <num-sets> <set1> [<set2> ...]
+ * <set>: <num-sprites> <first-sprite>
+ *
+ * B num-sets How many sets of sprites to replace.
+ * Each set:
+ * B num-sprites How many sprites are in this set
+ * W first-sprite First sprite number to replace */
+ uint8 num_sets;
+ uint i;
+
+ buf++; /* skip action byte */
+ num_sets = grf_load_byte(&buf);
+
+ for (i = 0; i < num_sets; i++) {
+ uint8 num_sprites = grf_load_byte(&buf);
+ uint16 first_sprite = grf_load_word(&buf);
+ uint j;
+
+ grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
+ i, num_sprites, first_sprite
+ );
+
+ for (j = 0; j < num_sprites; j++) {
+ LoadNextSprite(first_sprite + j, _file_index); // XXX
+ _nfo_line++;
+ }
+ }
+}
+
+/* Action 0x0B */
+static void GRFError(byte *buf, int len)
+{
+ /* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
+ *
+ * B severity 00: notice, contine loading grf file
+ * 01: warning, continue loading grf file
+ * 02: error, but continue loading grf file, and attempt
+ * loading grf again when loading or starting next game
+ * 03: error, abort loading and prevent loading again in
+ * the future (only when restarting the patch)
+ * B language-id see action 4, use 1F for built-in error messages
+ * B message-id message to show, see below
+ * S message for custom messages (message-id FF), text of the message
+ * not present for built-in messages.
+ * V data additional data for built-in (or custom) messages
+ * B parnum see action 6, only used with built-in message 03 */
+ /* TODO: For now we just show the message, sometimes incomplete and never translated. */
+
+ static const char *const msgstr[] = {
+ "%sRequires at least pseudo-TTDPatch version %s",
+ "%sThis file is for %s version of TTD",
+ "%sDesigned to be used with %s",
+ "%sInvalid parameter %s",
+ "%sMust be loaded before %s",
+ "%sMust be loaded after %s",
+ "%s%s"
+ };
+
+ static const char *const sevstr[] = {
+ "",
+ "Warning: ",
+ "Error: ",
+ "Fatal: ",
+ };
+ uint8 sevid;
+ uint8 msgid;
+
+ check_length(len, 6, "GRFError");
+ sevid = buf[1];
+ msgid = buf[3];
+
+ // Undocumented TTDPatch feature.
+ if (!HASBIT(sevid, 7) && _cur_stage < GLS_ACTIVATION) {
+ grfmsg(7, "Skipping non-fatal GRFError in stage 1");
+ return;
+ }
+
+ sevid = GB(sevid, 0, 2);
+ grfmsg(0, msgstr[(msgid == 0xFF) ? lengthof(msgstr) - 1 : msgid], sevstr[sevid], &buf[4]);
+}
+
+/* Action 0x0C */
+static void GRFComment(byte *buf, int len)
+{
+ /* <0C> [<ignored...>]
+ *
+ * V ignored Anything following the 0C is ignored */
+
+ static char comment[256];
+ if (len == 1) return;
+
+ ttd_strlcpy(comment, (char*)(buf + 1), minu(sizeof(comment), len));
+ grfmsg(2, "GRFComment: %s", comment);
+}
+
+/* Action 0x0D */
+static void ParamSet(byte *buf, int len)
+{
+ /* <0D> <target> <operation> <source1> <source2> [<data>]
+ *
+ * B target parameter number where result is stored
+ * B operation operation to perform, see below
+ * B source1 first source operand
+ * B source2 second source operand
+ * D data data to use in the calculation, not necessary
+ * if both source1 and source2 refer to actual parameters
+ *
+ * Operations
+ * 00 Set parameter equal to source1
+ * 01 Addition, source1 + source2
+ * 02 Subtraction, source1 - source2
+ * 03 Unsigned multiplication, source1 * source2 (both unsigned)
+ * 04 Signed multiplication, source1 * source2 (both signed)
+ * 05 Unsigned bit shift, source1 by source2 (source2 taken to be a
+ * signed quantity; left shift if positive and right shift if
+ * negative, source1 is unsigned)
+ * 06 Signed bit shift, source1 by source2
+ * (source2 like in 05, and source1 as well)
+ */
+
+ byte target;
+ byte oper;
+ uint32 src1;
+ uint32 src2;
+ uint32 data = 0;
+ uint32 res;
+
+ check_length(len, 5, "ParamSet");
+ buf++;
+ target = grf_load_byte(&buf);
+ oper = grf_load_byte(&buf);
+ src1 = grf_load_byte(&buf);
+ src2 = grf_load_byte(&buf);
+
+ if (len >= 8) data = grf_load_dword(&buf);
+
+ /* You can add 80 to the operation to make it apply only if the target
+ * is not defined yet. In this respect, a parameter is taken to be
+ * defined if any of the following applies:
+ * - it has been set to any value in the newgrf(w).cfg parameter list
+ * - it OR A PARAMETER WITH HIGHER NUMBER has been set to any value by
+ * an earlier action D */
+ if (oper & 0x80) {
+ if (target < 0x80 && target < _cur_grffile->param_end) {
+ grfmsg(7, "Param %u already defined, skipping", target);
+ return;
+ }
+
+ oper &= 0x7F;
+ }
+
+ if (src2 == 0xFE) {
+ if (GB(data, 0, 8) == 0xFF) {
+ if (data == 0x0000FFFF) {
+ /* Patch variables */
+ grfmsg(2, "ParamSet: Reading Patch variables unsupported");
+ return;
+ } else {
+ /* GRF Resource Management */
+ if (_cur_stage != GLS_ACTIVATION) {
+ /* Ignore GRM during initialization */
+ src1 = 0;
+ } else {
+ uint8 op = src1;
+ uint8 feature = GB(data, 8, 8);
+ uint16 count = GB(data, 16, 16);
+
+ switch (feature) {
+ case 0x00: /* Trains */
+ case 0x01: /* Road Vehicles */
+ case 0x02: /* Ships */
+ case 0x03: /* Aircraft */
+ {
+ uint start = 0;
+ uint size = 0;
+ uint shift = _vehshifts[feature];
+ int i;
+
+ if (op == 6) {
+ /* Return GRFID of set that reserved ID */
+ src1 = _grm_engines[shift + _cur_grffile->param[target]];
+ break;
+ }
+
+ /* With an operation of 2 or 3, we want to reserve a specific block of IDs */
+ if (op == 2 || op == 3) start = _cur_grffile->param[target];
+
+ for (i = start; i < _vehcounts[feature]; i++) {
+ if (_grm_engines[shift + i] == 0) {
+ size++;
+ } else {
+ if (op == 2 || op == 3) break;
+ start = i + 1;
+ size = 0;
+ }
+
+ if (size == count) break;
+ }
+
+ if (size == count) {
+ /* Got the slot... */
+ if (op == 0 || op == 3) {
+ grfmsg(2, "GRM: Reserving %d vehicles at %d", count, start);
+ for (i = 0; i < count; i++) _grm_engines[shift + start + i] = _cur_grffile->grfid;
+ }
+ src1 = start;
+ } else {
+ /* Unable to allocate */
+ if (op != 4 && op != 5) {
+ /* Deactivate GRF */
+ grfmsg(0, "GRM: Unable to allocate %d vehicles, deactivating", count);
+ SETBIT(_cur_grfconfig->flags, GCF_DISABLED);
+ CLRBIT(_cur_grfconfig->flags, GCF_ACTIVATED);
+
+ _skip_sprites = -1;
+ return;
+ }
+
+ grfmsg(1, "GRM: Unable to allocate %d vehicles", count);
+ src1 = -1;
+ }
+ break;
+ }
+
+ case 0x08: /* General sprites */
+ switch (op) {
+ case 0:
+ /* 'Reserve' space at the current sprite ID */
+ src1 = _cur_spriteid;
+ _cur_spriteid += count;
+ break;
+
+ case 1:
+ src1 = _cur_spriteid;
+ break;
+
+ default:
+ grfmsg(1, "GRM: Unsupported operation %d for general sprites", op);
+ return;
+ }
+ break;
+
+ default: grfmsg(1, "GRM: Unsupported feature 0x%X", feature); return;
+ }
+ }
+ }
+ } else {
+ /* Read another GRF File's parameter */
+ const GRFFile *file = GetFileByGRFID(data);
+ if (file == NULL || src1 >= file->param_end) {
+ src1 = 0;
+ } else {
+ src1 = file->param[src1];
+ }
+ }
+ } else {
+ /* The source1 and source2 operands refer to the grf parameter number
+ * like in action 6 and 7. In addition, they can refer to the special
+ * variables available in action 7, or they can be FF to use the value
+ * of <data>. If referring to parameters that are undefined, a value
+ * of 0 is used instead. */
+ src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL);
+ src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL);
+ }
+
+ /* TODO: You can access the parameters of another GRF file by using
+ * source2=FE, source1=the other GRF's parameter number and data=GRF
+ * ID. This is only valid with operation 00 (set). If the GRF ID
+ * cannot be found, a value of 0 is used for the parameter value
+ * instead. */
+
+ switch (oper) {
+ case 0x00:
+ res = src1;
+ break;
+
+ case 0x01:
+ res = src1 + src2;
+ break;
+
+ case 0x02:
+ res = src1 - src2;
+ break;
+
+ case 0x03:
+ res = src1 * src2;
+ break;
+
+ case 0x04:
+ res = (int32)src1 * (int32)src2;
+ break;
+
+ case 0x05:
+ if ((int32)src2 < 0) {
+ res = src1 >> -(int32)src2;
+ } else {
+ res = src1 << src2;
+ }
+ break;
+
+ case 0x06:
+ if ((int32)src2 < 0) {
+ res = (int32)src1 >> -(int32)src2;
+ } else {
+ res = (int32)src1 << src2;
+ }
+ break;
+
+ case 0x07: /* Bitwise AND */
+ res = src1 & src2;
+ break;
+
+ case 0x08: /* Bitwise OR */
+ res = src1 | src2;
+ break;
+
+ case 0x09: /* Unsigned division */
+ if (src2 == 0) {
+ res = src1;
+ } else {
+ res = src1 / src2;
+ }
+ break;
+
+ case 0x0A: /* Signed divison */
+ if (src2 == 0) {
+ res = src1;
+ } else {
+ res = (int32)src1 / (int32)src2;
+ }
+ break;
+
+ case 0x0B: /* Unsigned modulo */
+ if (src2 == 0) {
+ res = src1;
+ } else {
+ res = src1 % src2;
+ }
+ break;
+
+ case 0x0C: /* Signed modulo */
+ if (src2 == 0) {
+ res = src1;
+ } else {
+ res = (int32)src1 % (int32)src2;
+ }
+ break;
+
+ default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return;
+ }
+
+ switch (target) {
+ case 0x8E: // Y-Offset for train sprites
+ _traininfo_vehicle_pitch = res;
+ break;
+
+ // TODO implement
+ case 0x8F: // Rail track type cost factors
+ case 0x93: // Tile refresh offset to left
+ case 0x94: // Tile refresh offset to right
+ case 0x95: // Tile refresh offset upwards
+ case 0x96: // Tile refresh offset downwards
+ case 0x97: // Snow line height
+ case 0x99: // Global ID offset
+ grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
+ break;
+
+ case 0x9E: /* Miscellaneous GRF features */
+ _misc_grf_features = res;
+ /* Set train list engine width */
+ _traininfo_vehicle_width = HASBIT(res, 3) ? 32 : 29;
+ break;
+
+ default:
+ if (target < 0x80) {
+ _cur_grffile->param[target] = res;
+ if (target + 1U > _cur_grffile->param_end) _cur_grffile->param_end = target + 1;
+ } else {
+ grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
+ }
+ break;
+ }
+}
+
+/* Action 0x0E */
+static void GRFInhibit(byte *buf, int len)
+{
+ /* <0E> <num> <grfids...>
+ *
+ * B num Number of GRFIDs that follow
+ * D grfids GRFIDs of the files to deactivate */
+
+ byte num;
+ int i;
+
+ check_length(len, 1, "GRFInhibit");
+ buf++, len--;
+ num = grf_load_byte(&buf); len--;
+ check_length(len, 4 * num, "GRFInhibit");
+
+ for (i = 0; i < num; i++) {
+ uint32 grfid = grf_load_dword(&buf);
+ GRFConfig *file = GetGRFConfig(grfid);
+
+ /* Unset activation flag */
+ if (file != NULL && file != _cur_grfconfig) {
+ grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
+ SETBIT(file->flags, GCF_DISABLED);
+ CLRBIT(file->flags, GCF_ACTIVATED);
+ }
+ }
+}
+
+/* Action 0x10 */
+static void DefineGotoLabel(byte *buf, int len)
+{
+ /* <10> <label> [<comment>]
+ *
+ * B label The label to define
+ * V comment Optional comment - ignored */
+
+ GRFLabel *label;
+
+ check_length(len, 1, "DefineGotoLabel");
+ buf++; len--;
+
+ label = malloc(sizeof(*label));
+ label->label = grf_load_byte(&buf);
+ label->nfo_line = _nfo_line;
+ label->pos = FioGetPos();
+ label->next = NULL;
+
+ /* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */
+ if (_cur_grffile->label == NULL) {
+ _cur_grffile->label = label;
+ } else {
+ /* Attach the label to the end of the list */
+ GRFLabel *l;
+ for (l = _cur_grffile->label; l->next != NULL; l = l->next);
+ l->next = label;
+ }
+
+ grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
+}
+
+/* Action 0x11 */
+static void GRFSound(byte *buf, int len)
+{
+ /* <11> <num>
+ *
+ * W num Number of sound files that follow */
+
+ uint16 num;
+
+ check_length(len, 1, "GRFSound");
+ buf++;
+ num = grf_load_word(&buf);
+
+ _grf_data_blocks = num;
+ _grf_data_type = GDT_SOUND;
+
+ if (_cur_grffile->sound_offset == 0) _cur_grffile->sound_offset = GetNumSounds();
+}
+
+static void ImportGRFSound(byte *buf, int len)
+{
+ const GRFFile *file;
+ FileEntry *se = AllocateFileEntry();
+ uint32 grfid = grf_load_dword(&buf);
+ uint16 sound = grf_load_word(&buf);
+
+ file = GetFileByGRFID(grfid);
+ if (file == NULL || file->sound_offset == 0) {
+ grfmsg(1, "ImportGRFSound: Source file not available");
+ return;
+ }
+
+ if (file->sound_offset + sound >= GetNumSounds()) {
+ grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound);
+ return;
+ }
+
+ grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound, file->sound_offset + sound, grfid);
+
+ *se = *GetSound(file->sound_offset + sound);
+
+ /* Reset volume and priority, which TTDPatch doesn't copy */
+ se->volume = 128;
+ se->priority = 0;
+}
+
+/* 'Action 0xFE' */
+static void GRFImportBlock(byte *buf, int len)
+{
+ if (_grf_data_blocks == 0) {
+ grfmsg(2, "GRFImportBlock: Unexpected import block, skipping");
+ return;
+ }
+
+ buf++;
+
+ _grf_data_blocks--;
+
+ /* XXX 'Action 0xFE' isn't really specified. It is only mentioned for
+ * importing sounds, so this is probably all wrong... */
+ if (grf_load_byte(&buf) != _grf_data_type) {
+ grfmsg(1, "GRFImportBlock: Import type mismatch");
+ }
+
+ switch (_grf_data_type) {
+ case GDT_SOUND: ImportGRFSound(buf, len - 1); break;
+ default: NOT_REACHED(); break;
+ }
+}
+
+static void LoadGRFSound(byte *buf, int len)
+{
+ byte *buf_start = buf;
+ FileEntry *se;
+
+ /* Allocate a sound entry. This is done even if the data is not loaded
+ * so that the indices used elsewhere are still correct. */
+ se = AllocateFileEntry();
+
+ if (grf_load_dword(&buf) != BSWAP32('RIFF')) {
+ grfmsg(1, "LoadGRFSound: Missing RIFF header");
+ return;
+ }
+
+ /* Size of file -- we ignore this */
+ grf_load_dword(&buf);
+
+ if (grf_load_dword(&buf) != BSWAP32('WAVE')) {
+ grfmsg(1, "LoadGRFSound: Invalid RIFF type");
+ return;
+ }
+
+ for (;;) {
+ uint32 tag = grf_load_dword(&buf);
+ uint32 size = grf_load_dword(&buf);
+
+ switch (tag) {
+ case ' tmf': /* 'fmt ' */
+ /* Audio format, must be 1 (PCM) */
+ if (grf_load_word(&buf) != 1) {
+ grfmsg(1, "LoadGRFSound: Invalid audio format");
+ return;
+ }
+ se->channels = grf_load_word(&buf);
+ se->rate = grf_load_dword(&buf);
+ grf_load_dword(&buf);
+ grf_load_word(&buf);
+ se->bits_per_sample = grf_load_word(&buf);
+
+ /* Consume any extra bytes */
+ for (; size > 16; size--) grf_load_byte(&buf);
+ break;
+
+ case 'atad': /* 'data' */
+ se->file_size = size;
+ se->file_offset = FioGetPos() - (len - (buf - buf_start)) + 1;
+ se->file_offset |= _file_index << 24;
+
+ /* Set default volume and priority */
+ se->volume = 0x80;
+ se->priority = 0;
+
+ grfmsg(2, "LoadGRFSound: channels %u, sample rate %u, bits per sample %u, length %u", se->channels, se->rate, se->bits_per_sample, size);
+ return;
+
+ default:
+ se->file_size = 0;
+ return;
+ }
+ }
+}
+
+/* Action 0x12 */
+static void LoadFontGlyph(byte *buf, int len)
+{
+ /* <12> <num_def> <font_size> <num_char> <base_char>
+ *
+ * B num_def Number of definitions
+ * B font_size Size of font (0 = normal, 1 = small, 2 = large)
+ * B num_char Number of consecutive glyphs
+ * W base_char First character index */
+
+ uint8 num_def;
+ uint i;
+
+ buf++; len--;
+ check_length(len, 1, "LoadFontGlyph");
+
+ num_def = grf_load_byte(&buf);
+
+ check_length(len, 1 + num_def * 4, "LoadFontGlyph");
+
+ for (i = 0; i < num_def; i++) {
+ FontSize size = grf_load_byte(&buf);
+ uint8 num_char = grf_load_byte(&buf);
+ uint16 base_char = grf_load_word(&buf);
+ uint c;
+
+ grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
+
+ for (c = 0; c < num_char; c++) {
+ SetUnicodeGlyph(size, base_char + c, _cur_spriteid);
+ LoadNextSprite(_cur_spriteid++, _file_index);
+ _nfo_line++;
+ }
+ }
+}
+
+/* 'Action 0xFF' */
+static void GRFDataBlock(byte *buf, int len)
+{
+ byte name_len;
+ const char *name;
+
+ if (_grf_data_blocks == 0) {
+ grfmsg(2, "GRFDataBlock: unexpected data block, skipping");
+ return;
+ }
+
+ buf++;
+ name_len = grf_load_byte(&buf);
+ name = (const char *)buf;
+ buf += name_len + 1;
+
+ grfmsg(2, "GRFDataBlock: block name '%s'...", name);
+
+ _grf_data_blocks--;
+
+ switch (_grf_data_type) {
+ case GDT_SOUND: LoadGRFSound(buf, len - name_len - 2); break;
+ default: NOT_REACHED(); break;
+ }
+}
+
+
+/* Used during safety scan on unsafe actions */
+static void GRFUnsafe(byte *buf, int len)
+{
+ SETBIT(_cur_grfconfig->flags, GCF_UNSAFE);
+
+ /* Skip remainder of GRF if GRF ID is set */
+ if (_cur_grfconfig->grfid != 0) _skip_sprites = -1;
+}
+
+
+static void InitializeGRFSpecial(void)
+{
+ _ttdpatch_flags[0] = ((_patches.always_small_airport ? 1 : 0) << 0x0C) // keepsmallairport
+ | (1 << 0x0D) // newairports
+ | (1 << 0x0E) // largestations
+ | ((_patches.longbridges ? 1 : 0) << 0x0F) // longbridges
+ | (0 << 0x10) // loadtime
+ | (1 << 0x12) // presignals
+ | (1 << 0x13) // extpresignals
+ | ((_patches.never_expire_vehicles ? 1 : 0) << 0x16) // enginespersist
+ | (1 << 0x1B) // multihead
+ | (1 << 0x1D) // lowmemory
+ | (1 << 0x1E); // generalfixes
+
+ _ttdpatch_flags[1] = (0 << 0x07) // moreairports - based on units of noise
+ | ((_patches.mammoth_trains ? 1 : 0) << 0x08) // mammothtrains
+ | (1 << 0x09) // trainrefit
+ | (0 << 0x0B) // subsidiaries
+ | ((_patches.gradual_loading ? 1 : 0) << 0x1C) // gradualloading
+ | (1 << 0x12) // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD
+ | (1 << 0x13) // unifiedmaglevmode - set bit 1 mode
+ | (1 << 0x14) // bridgespeedlimits
+ | (1 << 0x16) // eternalgame
+ | (1 << 0x17) // newtrains
+ | (1 << 0x18) // newrvs
+ | (1 << 0x19) // newships
+ | (1 << 0x1A) // newplanes
+ | ((_patches.signal_side ? 1 : 0) << 0x1B) // signalsontrafficside
+ | (1 << 0x1C); // electrifiedrailway
+
+ _ttdpatch_flags[2] = (1 << 0x01) // loadallgraphics - obsolote
+ | (1 << 0x03) // semaphores
+ | (0 << 0x0B) // enhancedgui
+ | (0 << 0x0C) // newagerating
+ | ((_patches.build_on_slopes ? 1 : 0) << 0x0D) // buildonslopes
+ | (0 << 0x0F) // planespeed
+ | (0 << 0x10) // moreindustriesperclimate - obsolete
+ | (0 << 0x11) // moretoylandfeatures
+ | (1 << 0x12) // newstations
+ | (0 << 0x13) // tracktypecostdiff
+ | (0 << 0x14) // manualconvert
+ | ((_patches.build_on_slopes ? 1 : 0) << 0x15) // buildoncoasts
+ | (1 << 0x16) // canals
+ | (1 << 0x17) // newstartyear
+ | (0 << 0x18) // freighttrains
+ | (0 << 0x19) // newhouses
+ | (1 << 0x1A) // newbridges
+ | (0 << 0x1B) // newtownnames
+ | (0 << 0x1C) // moreanimations
+ | ((_patches.wagon_speed_limits ? 1 : 0) << 0x1D) // wagonspeedlimits
+ | (1 << 0x1E) // newshistory
+ | (0 << 0x1F); // custombridgeheads
+
+ _ttdpatch_flags[3] = (0 << 0x00) // newcargodistribution
+ | (1 << 0x01) // windowsnap
+ | (0 << 0x02) // townbuildnoroad
+ | (0 << 0x03) // pathbasedsignalling. To enable if ever pbs is back
+ | (0 << 0x04) // aichoosechance
+ | (1 << 0x05) // resolutionwidth
+ | (1 << 0x06) // resolutionheight
+ | (0 << 0x07) // newindustries
+ | (0 << 0x08) // fifoloading
+ | (0 << 0x09) // townroadbranchprob
+ | (0 << 0x0A) // tempsnowline
+ | (0 << 0x0B) // newcargo
+ | (1 << 0x0C) // enhancemultiplayer
+ | (1 << 0x0D) // onewayroads
+ | ((_patches.nonuniform_stations ? 1 : 0) << 0x0E) // irregularstations
+ | (1 << 0x0F) // statistics
+ | (1 << 0x10) // newsounds
+ | (1 << 0x11) // autoreplace
+ | (1 << 0x12) // autoslope
+ | (0 << 0x13) // followvehicle
+ | (0 << 0x14) // trams
+ | (0 << 0x15) // enhancetunnels
+ | (0 << 0x16) // shortrvs
+ | (0 << 0x17); // articulatedrvs
+}
+
+static void ResetCustomStations(void)
+{
+ StationSpec *statspec;
+ GRFFile *file;
+ uint i;
+ uint t;
+
+ for (file = _first_grffile; file != NULL; file = file->next) {
+ if (file->stations == NULL) continue;
+ for (i = 0; i < MAX_STATIONS; i++) {
+ if (file->stations[i] == NULL) continue;
+ statspec = file->stations[i];
+
+ /* Release renderdata, if it wasn't copied from another custom station spec */
+ if (!statspec->copied_renderdata) {
+ for (t = 0; t < statspec->tiles; t++) {
+ free((void*)statspec->renderdata[t].seq);
+ }
+ free(statspec->renderdata);
+ }
+
+ /* Release platforms and layouts */
+ if (!statspec->copied_layouts) {
+ uint l, p;
+ for (l = 0; l < statspec->lengths; l++) {
+ for (p = 0; p < statspec->platforms[l]; p++) {
+ free(statspec->layouts[l][p]);
+ }
+ free(statspec->layouts[l]);
+ }
+ free(statspec->layouts);
+ free(statspec->platforms);
+ }
+
+ /* Release this station */
+ free(statspec);
+ }
+
+ /* Free and reset the station data */
+ free(file->stations);
+ file->stations = NULL;
+ }
+}
+
+static void ResetNewGRF(void)
+{
+ GRFFile *f, *next;
+
+ for (f = _first_grffile; f != NULL; f = next) {
+ next = f->next;
+
+ free(f->filename);
+ free(f);
+ }
+
+ _first_grffile = NULL;
+ _cur_grffile = NULL;
+}
+
+/**
+ * Reset all NewGRF loaded data
+ * TODO
+ */
+static void ResetNewGRFData(void)
+{
+ uint i;
+
+ CleanUpStrings();
+
+ // Copy/reset original engine info data
+ memcpy(&_engine_info, &orig_engine_info, sizeof(orig_engine_info));
+ memcpy(&_rail_vehicle_info, &orig_rail_vehicle_info, sizeof(orig_rail_vehicle_info));
+ memcpy(&_ship_vehicle_info, &orig_ship_vehicle_info, sizeof(orig_ship_vehicle_info));
+ memcpy(&_aircraft_vehicle_info, &orig_aircraft_vehicle_info, sizeof(orig_aircraft_vehicle_info));
+ memcpy(&_road_vehicle_info, &orig_road_vehicle_info, sizeof(orig_road_vehicle_info));
+
+ // Copy/reset original bridge info data
+ // First, free sprite table data
+ for (i = 0; i < MAX_BRIDGES; i++) {
+ if (_bridge[i].sprite_table != NULL) {
+ uint j;
+
+ for (j = 0; j < 7; j++) free(_bridge[i].sprite_table[j]);
+ free(_bridge[i].sprite_table);
+ }
+ }
+ memcpy(&_bridge, &orig_bridge, sizeof(_bridge));
+
+ // Reset refit/cargo class data
+ memset(&cargo_allowed, 0, sizeof(cargo_allowed));
+ memset(&cargo_disallowed, 0, sizeof(cargo_disallowed));
+
+ // Reset GRM reservations
+ memset(&_grm_engines, 0, sizeof(_grm_engines));
+
+ // Unload sprite group data
+ UnloadWagonOverrides();
+ UnloadRotorOverrideSprites();
+ UnloadCustomEngineSprites();
+ UnloadCustomEngineNames();
+ ResetEngineListOrder();
+
+ // Reset price base data
+ ResetPriceBaseMultipliers();
+
+ /* Reset the curencies array */
+ ResetCurrencies();
+
+ // Reset station classes
+ ResetStationClasses();
+ ResetCustomStations();
+
+ /* Reset NewGRF files */
+ ResetNewGRF();
+
+ // Add engine type to engine data. This is needed for the refit precalculation.
+ AddTypeToEngines();
+
+ /* Reset misc GRF features and train list display variables */
+ _misc_grf_features = 0;
+ _traininfo_vehicle_pitch = 0;
+ _traininfo_vehicle_width = 29;
+ _have_2cc = false;
+ _signal_base = 0;
+ _coast_base = 0;
+
+ InitializeSoundPool();
+ InitializeSpriteGroupPool();
+}
+
+/** Reset all NewGRFData that was used only while processing data */
+static void ClearTemporaryNewGRFData(void)
+{
+ /* Clear the GOTO labels used for GRF processing */
+ GRFLabel *l;
+ for (l = _cur_grffile->label; l != NULL;) {
+ GRFLabel *l2 = l->next;
+ free(l);
+ l = l2;
+ }
+ _cur_grffile->label = NULL;
+
+ /* Clear the list of spritegroups */
+ free(_cur_grffile->spritegroups);
+ _cur_grffile->spritegroups = NULL;
+ _cur_grffile->spritegroups_count = 0;
+}
+
+static void InitNewGRFFile(const GRFConfig *config, int sprite_offset)
+{
+ GRFFile *newfile;
+
+ newfile = GetFileByFilename(config->filename);
+ if (newfile != NULL) {
+ /* We already loaded it once. */
+ newfile->sprite_offset = sprite_offset;
+ _cur_grffile = newfile;
+ return;
+ }
+
+ newfile = calloc(1, sizeof(*newfile));
+
+ if (newfile == NULL) error ("Out of memory");
+
+ newfile->filename = strdup(config->filename);
+ newfile->sprite_offset = sprite_offset;
+
+ /* Copy the initial parameter list */
+ assert(lengthof(newfile->param) == lengthof(config->param) && lengthof(config->param) == 0x80);
+ newfile->param_end = config->num_params;
+ memcpy(newfile->param, config->param, sizeof(newfile->param));
+
+ if (_first_grffile == NULL) {
+ _cur_grffile = newfile;
+ _first_grffile = newfile;
+ } else {
+ _cur_grffile->next = newfile;
+ _cur_grffile = newfile;
+ }
+}
+
+
+/** Bitmasked values of what type of cargo is refittable for the given vehicle-type.
+ * This coupled with the landscape information (_landscape_global_cargo_mask) gives
+ * us exactly what is refittable and what is not */
+#define MC(cargo) (1 << cargo)
+static const uint32 _default_refitmasks[NUM_VEHICLE_TYPES] = {
+ /* Trains */
+ MC(GC_PASSENGERS) | MC(GC_COAL) | MC(GC_MAIL) | MC(GC_LIVESTOCK) | MC(GC_GOODS) | MC(GC_GRAIN) | MC(GC_WOOD) | MC(GC_IRON_ORE) |
+ MC(GC_STEEL) | MC(GC_VALUABLES) | MC(GC_PAPER) | MC(GC_FOOD) | MC(GC_FRUIT) | MC(GC_COPPER_ORE) | MC(GC_WATER) | MC(GC_SUGAR) |
+ MC(GC_TOYS) | MC(GC_CANDY) | MC(GC_TOFFEE) | MC(GC_COLA) | MC(GC_COTTON_CANDY) | MC(GC_BUBBLES) | MC(GC_PLASTIC) | MC(GC_FIZZY_DRINKS),
+ /* Road vehicles (not refittable by default) */
+ 0,
+ /* Ships */
+ MC(GC_COAL) | MC(GC_MAIL) | MC(GC_LIVESTOCK) | MC(GC_GOODS) | MC(GC_GRAIN) | MC(GC_WOOD) | MC(GC_IRON_ORE) | MC(GC_STEEL) | MC(GC_VALUABLES) |
+ MC(GC_PAPER) | MC(GC_FOOD) | MC(GC_FRUIT) | MC(GC_COPPER_ORE) | MC(GC_WATER) | MC(GC_RUBBER) | MC(GC_SUGAR) | MC(GC_TOYS) | MC(GC_BATTERIES) |
+ MC(GC_CANDY) | MC(GC_TOFFEE) | MC(GC_COLA) | MC(GC_COTTON_CANDY) | MC(GC_BUBBLES) | MC(GC_PLASTIC) | MC(GC_FIZZY_DRINKS),
+ /* Aircraft */
+ MC(GC_PASSENGERS) | MC(GC_MAIL) | MC(GC_GOODS) | MC(GC_VALUABLES) | MC(GC_FOOD) | MC(GC_FRUIT) | MC(GC_SUGAR) | MC(GC_TOYS) |
+ MC(GC_BATTERIES) | MC(GC_CANDY) | MC(GC_TOFFEE) | MC(GC_COLA) | MC(GC_COTTON_CANDY) | MC(GC_BUBBLES) | MC(GC_PLASTIC) | MC(GC_FIZZY_DRINKS),
+ /* Special/Disaster */
+ 0,0
+};
+#undef MC
+
+
+/**
+ * Precalculate refit masks from cargo classes for all vehicles.
+ */
+static void CalculateRefitMasks(void)
+{
+ EngineID engine;
+
+ for (engine = 0; engine < TOTAL_NUM_ENGINES; engine++) {
+ uint32 mask = 0;
+ uint32 not_mask = 0;
+ uint32 xor_mask = _engine_info[engine].refit_mask;
+ byte i;
+
+ if (cargo_allowed[engine] != 0) {
+ // Build up the list of cargo types from the set cargo classes.
+ for (i = 0; i < lengthof(cargo_classes); i++) {
+ if (HASBIT(cargo_allowed[engine], i)) mask |= cargo_classes[i];
+ if (HASBIT(cargo_disallowed[engine], i)) not_mask |= cargo_classes[i];
+ }
+ } else {
+ // Don't apply default refit mask to wagons or engines with no capacity
+ if (xor_mask == 0 && (
+ GetEngine(engine)->type != VEH_Train || (
+ RailVehInfo(engine)->capacity != 0 &&
+ !(RailVehInfo(engine)->flags & RVI_WAGON)
+ )
+ )) {
+ xor_mask = _default_refitmasks[GetEngine(engine)->type - VEH_Train];
+ }
+ }
+ _engine_info[engine].refit_mask = ((mask & ~not_mask) ^ xor_mask) & _landscape_global_cargo_mask[_opt.landscape];
+ }
+}
+
+/* Here we perform initial decoding of some special sprites (as are they
+ * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
+ * partial implementation yet). */
+/* XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
+ * a crafted invalid GRF file. We should tell that to the user somehow, or
+ * better make this more robust in the future. */
+static void DecodeSpecialSprite(uint num, GrfLoadingStage stage)
+{
+ /* XXX: There is a difference between staged loading in TTDPatch and
+ * here. In TTDPatch, for some reason actions 1 and 2 are carried out
+ * during stage 1, whilst action 3 is carried out during stage 2 (to
+ * "resolve" cargo IDs... wtf). This is a little problem, because cargo
+ * IDs are valid only within a given set (action 1) block, and may be
+ * overwritten after action 3 associates them. But overwriting happens
+ * in an earlier stage than associating, so... We just process actions
+ * 1 and 2 in stage 2 now, let's hope that won't get us into problems.
+ * --pasky */
+ /* We need a pre-stage to set up GOTO labels of Action 0x10 because the grf
+ * is not in memory and scanning the file every time would be too expensive.
+ * In other stages we skip action 0x10 since it's already dealt with. */
+ static const SpecialSpriteHandler handlers[][GLS_END] = {
+ /* 0x00 */ { NULL, GRFUnsafe, NULL, NULL, FeatureChangeInfo, },
+ /* 0x01 */ { NULL, GRFUnsafe, NULL, NULL, NewSpriteSet, },
+ /* 0x02 */ { NULL, GRFUnsafe, NULL, NULL, NewSpriteGroup, },
+ /* 0x03 */ { NULL, GRFUnsafe, NULL, NULL, FeatureMapSpriteGroup, },
+ /* 0x04 */ { NULL, NULL, NULL, NULL, FeatureNewName, },
+ /* 0x05 */ { NULL, NULL, NULL, NULL, GraphicsNew, },
+ /* 0x06 */ { NULL, NULL, NULL, CfgApply, CfgApply, },
+ /* 0x07 */ { NULL, NULL, NULL, NULL, SkipIf, },
+ /* 0x08 */ { ScanInfo, SafeInfo, NULL, GRFInfo, GRFInfo, },
+ /* 0x09 */ { NULL, NULL, NULL, SkipIf, SkipIf, },
+ /* 0x0A */ { NULL, NULL, NULL, NULL, SpriteReplace, },
+ /* 0x0B */ { NULL, NULL, NULL, GRFError, GRFError, },
+ /* 0x0C */ { NULL, NULL, NULL, GRFComment, GRFComment, },
+ /* 0x0D */ { NULL, GRFUnsafe, NULL, ParamSet, ParamSet, },
+ /* 0x0E */ { NULL, GRFUnsafe, NULL, GRFInhibit, GRFInhibit, },
+ /* 0x0F */ { NULL, NULL, NULL, NULL, NULL, },
+ /* 0x10 */ { NULL, NULL, DefineGotoLabel, NULL, NULL, },
+ /* 0x11 */ { NULL, GRFUnsafe, NULL, NULL, GRFSound, },
+ /* 0x12 */ { NULL, NULL, NULL, NULL, LoadFontGlyph, },
+ };
+
+ byte* buf;
+ byte action;
+
+ if (_preload_sprite == NULL) {
+ /* No preloaded sprite to work with; allocate and read the
+ * pseudo sprite content. */
+ buf = malloc(num);
+ if (buf == NULL) error("DecodeSpecialSprite: Could not allocate memory");
+ FioReadBlock(buf, num);
+ } else {
+ /* Use the preloaded sprite data. */
+ buf = _preload_sprite;
+ _preload_sprite = NULL;
+ grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
+
+ /* Skip the real (original) content of this action. */
+ FioSeekTo(num, SEEK_CUR);
+ }
+
+ action = buf[0];
+
+ if (action == 0xFF) {
+ grfmsg(7, "Handling data block in stage %d", stage);
+ GRFDataBlock(buf, num);
+ } else if (action == 0xFE) {
+ grfmsg(7, "Handling import block in stage %d", stage);
+ GRFImportBlock(buf, num);
+ } else if (action >= lengthof(handlers)) {
+ grfmsg(7, "Skipping unknown action 0x%02X", action);
+ } else if (handlers[action][stage] == NULL) {
+ grfmsg(7, "Skipping action 0x%02X in stage %d", action, stage);
+ } else {
+ grfmsg(7, "Handling action 0x%02X in stage %d", action, stage);
+ handlers[action][stage](buf, num);
+ }
+ free(buf);
+}
+
+
+void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage)
+{
+ const char *filename = config->filename;
+ uint16 num;
+
+ /* A .grf file is activated only if it was active when the game was
+ * started. If a game is loaded, only its active .grfs will be
+ * reactivated, unless "loadallgraphics on" is used. A .grf file is
+ * considered active if its action 8 has been processed, i.e. its
+ * action 8 hasn't been skipped using an action 7.
+ *
+ * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
+ * carried out. All others are ignored, because they only need to be
+ * processed once at initialization. */
+ if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
+ _cur_grffile = GetFileByFilename(filename);
+ if (_cur_grffile == NULL) error("File '%s' lost in cache.\n", filename);
+ if (stage == GLS_ACTIVATION && !HASBIT(config->flags, GCF_ACTIVATED)) return;
+ }
+
+ FioOpenFile(file_index, filename);
+ _file_index = file_index; // XXX
+
+ _cur_grfconfig = config;
+
+ DEBUG(grf, 2, "Reading NewGRF-file '%s'", filename);
+
+ /* Skip the first sprite; we don't care about how many sprites this
+ * does contain; newest TTDPatches and George's longvehicles don't
+ * neither, apparently. */
+ if (FioReadWord() == 4 && FioReadByte() == 0xFF) {
+ FioReadDword();
+ } else {
+ DEBUG(grf, 7, "Custom .grf has invalid format");
+ return;
+ }
+
+ _skip_sprites = 0; // XXX
+ _nfo_line = 0;
+
+ while ((num = FioReadWord()) != 0) {
+ byte type = FioReadByte();
+ _nfo_line++;
+
+ if (type == 0xFF) {
+ if (_skip_sprites == 0) {
+ DecodeSpecialSprite(num, stage);
+
+ /* Stop all processing if we are to skip the remaining sprites */
+ if (_skip_sprites == -1) break;
+
+ continue;
+ } else {
+ FioSkipBytes(num);
+ }
+ } else {
+ if (_skip_sprites == 0) grfmsg(7, "Skipping unexpected sprite");
+
+ FioSkipBytes(7);
+ num -= 8;
+
+ if (type & 2) {
+ FioSkipBytes(num);
+ } else {
+ while (num > 0) {
+ int8 i = FioReadByte();
+ if (i >= 0) {
+ num -= i;
+ FioSkipBytes(i);
+ } else {
+ i = -(i >> 3);
+ num -= i;
+ FioReadByte();
+ }
+ }
+ }
+ }
+
+ if (_skip_sprites > 0) _skip_sprites--;
+ }
+}
+
+
+void LoadNewGRF(uint load_index, uint file_index)
+{
+ GrfLoadingStage stage;
+
+ InitializeGRFSpecial();
+
+ ResetNewGRFData();
+
+ /* Load newgrf sprites
+ * in each loading stage, (try to) open each file specified in the config
+ * and load information from it. */
+ for (stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
+ uint slot = file_index;
+ GRFConfig *c;
+
+ _cur_stage = stage;
+ _cur_spriteid = load_index;
+ for (c = _grfconfig; c != NULL; c = c->next) {
+ if (HASBIT(c->flags, GCF_DISABLED) || HASBIT(c->flags, GCF_NOT_FOUND)) continue;
+
+ // TODO usererror()
+ if (!FioCheckFileExists(c->filename)) error("NewGRF file is missing '%s'", c->filename);
+
+ if (stage == GLS_LABELSCAN) InitNewGRFFile(c, _cur_spriteid);
+ LoadNewGRFFile(c, slot++, stage);
+ if (stage == GLS_ACTIVATION) ClearTemporaryNewGRFData();
+ DEBUG(sprite, 2, "Currently %i sprites are loaded", load_index);
+ }
+ }
+
+ // Pre-calculate all refit masks after loading GRF files
+ CalculateRefitMasks();
+}
+
+
diff --git a/src/newgrf.h b/src/newgrf.h
new file mode 100644
index 000000000..1d8c5a365
--- /dev/null
+++ b/src/newgrf.h
@@ -0,0 +1,73 @@
+/* $Id$ */
+
+#ifndef NEWGRF_H
+#define NEWGRF_H
+
+#include "station.h"
+#include "newgrf_config.h"
+
+typedef enum GrfLoadingStage {
+ GLS_FILESCAN,
+ GLS_SAFETYSCAN,
+ GLS_LABELSCAN,
+ GLS_INIT,
+ GLS_ACTIVATION,
+ GLS_END,
+} GrfLoadingStage;
+
+typedef struct GRFLabel {
+ byte label;
+ uint32 nfo_line;
+ uint32 pos;
+ struct GRFLabel *next;
+} GRFLabel;
+
+typedef struct GRFFile {
+ char *filename;
+ uint32 grfid;
+ uint16 sprite_offset;
+ byte grf_version;
+ struct GRFFile *next;
+
+ /* A sprite group contains all sprites of a given vehicle (or multiple
+ * vehicles) when carrying given cargo. It consists of several sprite
+ * sets. Group ids are refered as "cargo id"s by TTDPatch
+ * documentation, contributing to the global confusion.
+ *
+ * A sprite set contains all sprites of a given vehicle carrying given
+ * cargo at a given *stage* - that is usually its load stage. Ie. you
+ * can have a spriteset for an empty wagon, wagon full of coal,
+ * half-filled wagon etc. Each spriteset contains eight sprites (one
+ * per direction) or four sprites if the vehicle is symmetric. */
+
+ SpriteID spriteset_start;
+ int spriteset_numsets;
+ int spriteset_numents;
+ int spriteset_feature;
+
+ int spritegroups_count;
+ struct SpriteGroup **spritegroups;
+
+ uint sound_offset;
+
+ StationSpec **stations;
+
+ uint32 param[0x80];
+ uint param_end; /// one more than the highest set parameter
+
+ GRFLabel *label; ///< Pointer to the first label. This is a linked list, not an array.
+} GRFFile;
+
+extern GRFFile *_first_grffile;
+
+extern SpriteID _signal_base;
+extern SpriteID _coast_base;
+extern bool _have_2cc;
+
+void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage);
+void LoadNewGRF(uint load_index, uint file_index);
+void ReloadNewGRFData(void); // in openttd.c
+
+void CDECL grfmsg(int severity, const char *str, ...);
+
+#endif /* NEWGRF_H */
diff --git a/src/newgrf_callbacks.h b/src/newgrf_callbacks.h
new file mode 100644
index 000000000..9d0a7a3da
--- /dev/null
+++ b/src/newgrf_callbacks.h
@@ -0,0 +1,89 @@
+/* $Id$ */
+
+#ifndef NEWGRF_CALLBACKS_H
+#define NEWGRF_CALLBACKS_H
+
+/** @file newgrf_callbacks.h
+ */
+
+/**
+ * List of implemented NewGRF callbacks.
+ * Names are formatted as CBID_<CLASS>_<CALLBACK>
+ */
+enum CallbackID {
+ // Powered wagons, if the result is lower as 0x40 then the wagon is powered
+ // TODO: interpret the rest of the result, aka "visual effects"
+ CBID_TRAIN_WAGON_POWER = 0x10,
+
+ // Vehicle length, returns the amount of 1/8's the vehicle is shorter
+ // only for train vehicles
+ CBID_TRAIN_VEHICLE_LENGTH = 0x11,
+
+ /* Called to determine the amount of cargo to load per unit of time when
+ * using gradual loading. */
+ CBID_VEHICLE_LOAD_AMOUNT = 0x12,
+
+ /* Called (if appropriate bit in callback mask is set) to determine if a
+ * newstation should be made available to build */
+ CBID_STATION_AVAILABILITY = 0x13,
+
+ /* Called (if appropriate bit in callback mask is set) when drawing a tile
+ * to choose a sprite layout to draw, instead of the standard 0-7 range */
+ CBID_STATION_SPRITE_LAYOUT = 0x14,
+
+ // Refit capacity, the passed vehicle needs to have its ->cargo_type set to
+ // the cargo we are refitting to, returns the new cargo capacity
+ CBID_VEHICLE_REFIT_CAPACITY = 0x15,
+
+ CBID_TRAIN_ARTIC_ENGINE = 0x16,
+
+ CBID_VEHICLE_CARGO_SUFFIX = 0x19,
+
+ CBID_TRAIN_ALLOW_WAGON_ATTACH = 0x1D,
+
+ /* This callback is called from vehicle purchase lists. It returns a value to be
+ * used as a custom string ID in the 0xD000 range. */
+ CBID_VEHICLE_ADDITIONAL_TEXT = 0x23,
+
+ /* Called when building a station to customize the tile layout */
+ CBID_STATION_TILE_LAYOUT = 0x24,
+
+ /* Called when the player (or AI) tries to start or stop a vehicle. Mainly
+ * used for preventing a vehicle from leaving the depot. */
+ CBID_VEHICLE_START_STOP_CHECK = 0x31,
+
+ /* Called to play a special sound effect */
+ CBID_VEHICLE_SOUND_EFFECT = 0x33,
+};
+
+/**
+ * Callback masks for vehicles, indicates which callbacks are used by a vehicle.
+ * Some callbacks are always used and don't have a mask.
+ */
+enum VehicleCallbackMask {
+ CBM_WAGON_POWER = 0, ///< Powered wagons (trains only)
+ CBM_VEHICLE_LENGTH = 1, ///< Vehicle length (trains only)
+ CBM_LOAD_AMOUNT = 2, ///< Load amount
+ CBM_REFIT_CAPACITY = 3, ///< Cargo capacity after refit
+ CBM_ARTIC_ENGINE = 4, ///< Add articulated engines (trains only)
+ CBM_CARGO_SUFFIX = 5, ///< Show suffix after cargo name
+ CBM_COLOUR_REMAP = 6, ///< Change colour mapping of vehicle
+ CBM_SOUND_EFFECT = 7, ///< Vehicle uses custom sound effects
+};
+
+/**
+ * Callback masks for stations.
+ */
+enum StationCallbackMask {
+ CBM_STATION_AVAIL = 0, ///< Availability of station in construction window
+ CBM_CUSTOM_LAYOUT = 1, ///< Use callback to select a tile layout to use
+};
+
+/**
+ * Result of a failed callback.
+ */
+enum {
+ CALLBACK_FAILED = 0xFFFF
+};
+
+#endif /* NEWGRF_CALLBACKS_H */
diff --git a/src/newgrf_cargo.c b/src/newgrf_cargo.c
new file mode 100644
index 000000000..386f8c384
--- /dev/null
+++ b/src/newgrf_cargo.c
@@ -0,0 +1,68 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "newgrf_cargo.h"
+
+/** TRANSLATE FROM LOCAL CARGO TO GLOBAL CARGO ID'S.
+ * This maps the per-landscape cargo ID's to globally unique cargo ID's usable ie. in
+ * the custom GRF files. It is basically just a transcribed table from TTDPatch's newgrf.txt.
+ */
+const CargoID _global_cargo_id[NUM_LANDSCAPE][NUM_CARGO] = {
+ /* LT_NORMAL */ {GC_PASSENGERS, GC_COAL, GC_MAIL, GC_OIL, GC_LIVESTOCK, GC_GOODS, GC_GRAIN, GC_WOOD, GC_IRON_ORE, GC_STEEL, GC_VALUABLES, GC_PAPER_TEMP},
+ /* LT_HILLY */ {GC_PASSENGERS, GC_COAL, GC_MAIL, GC_OIL, GC_LIVESTOCK, GC_GOODS, GC_GRAIN, GC_WOOD, GC_INVALID, GC_PAPER, GC_VALUABLES, GC_FOOD },
+ /* LT_DESERT */ {GC_PASSENGERS, GC_RUBBER, GC_MAIL, GC_OIL, GC_FRUIT, GC_GOODS, GC_GRAIN, GC_WOOD, GC_COPPER_ORE, GC_WATER, GC_VALUABLES, GC_FOOD },
+ /* LT_CANDY */ {GC_PASSENGERS, GC_SUGAR, GC_MAIL, GC_TOYS, GC_BATTERIES, GC_CANDY, GC_TOFFEE, GC_COLA, GC_COTTON_CANDY, GC_BUBBLES, GC_PLASTIC, GC_FIZZY_DRINKS },
+ /**
+ * - GC_INVALID (255) means that cargo is not available for that climate
+ * - GC_PAPER_TEMP (27) is paper in temperate climate in TTDPatch
+ * Following can be renumbered:
+ * - GC_DEFAULT (29) is the defa ult cargo for the purpose of spritesets
+ * - GC_PURCHASE (30) is the purchase list image (the equivalent of 0xff) for the purpose of spritesets
+ */
+};
+
+/** BEGIN --- TRANSLATE FROM GLOBAL CARGO TO LOCAL CARGO ID'S **/
+/** Map global cargo ID's to local-cargo ID's */
+const CargoID _local_cargo_id_ctype[NUM_GLOBAL_CID] = {
+ CT_PASSENGERS, CT_COAL, CT_MAIL, CT_OIL, CT_LIVESTOCK, CT_GOODS, CT_GRAIN, CT_WOOD, /* 0- 7 */
+ CT_IRON_ORE, CT_STEEL, CT_VALUABLES, CT_PAPER, CT_FOOD, CT_FRUIT, CT_COPPER_ORE, CT_WATER, /* 8-15 */
+ CT_RUBBER, CT_SUGAR, CT_TOYS, CT_BATTERIES, CT_CANDY, CT_TOFFEE, CT_COLA, CT_COTTON_CANDY, /* 16-23 */
+ CT_BUBBLES, CT_PLASTIC, CT_FIZZY_DRINKS, CT_PAPER /* unsup. */, CT_HILLY_UNUSED, /* 24-28 */
+ CT_INVALID, CT_INVALID /* 29-30 */
+};
+
+/** Bitmasked value where the global cargo ID is available in landscape
+ * 0: LT_NORMAL, 1: LT_HILLY, 2: LT_DESERT, 3: LT_CANDY */
+#define MC(cargo) (1 << cargo)
+const uint32 _landscape_global_cargo_mask[NUM_LANDSCAPE] =
+{ /* LT_NORMAL: temperate */
+ MC(GC_PASSENGERS) | MC(GC_COAL) | MC(GC_MAIL) | MC(GC_OIL) | MC(GC_LIVESTOCK) | MC(GC_GOODS) | MC(GC_GRAIN) | MC(GC_WOOD) | MC(GC_IRON_ORE) | MC(GC_STEEL) | MC(GC_VALUABLES),
+ /* LT_HILLY: arctic */
+ MC(GC_PASSENGERS) | MC(GC_COAL) | MC(GC_MAIL) | MC(GC_OIL) | MC(GC_LIVESTOCK) | MC(GC_GOODS) | MC(GC_GRAIN) | MC(GC_WOOD) | MC(GC_VALUABLES) | MC(GC_PAPER) | MC(GC_FOOD),
+ /* LT_DESERT: rainforest/desert */
+ MC(GC_PASSENGERS) | MC(GC_MAIL) | MC(GC_OIL) | MC(GC_GOODS) | MC(GC_GRAIN) | MC(GC_WOOD) | MC(GC_VALUABLES) | MC(GC_FOOD) | MC(GC_FRUIT) | MC(GC_COPPER_ORE) | MC(GC_WATER) | MC(GC_RUBBER),
+ /* LT_CANDY: toyland */
+ MC(GC_PASSENGERS) | MC(GC_MAIL) | MC(GC_SUGAR) | MC(GC_TOYS) | MC(GC_BATTERIES) | MC(GC_CANDY) | MC(GC_TOFFEE) | MC(GC_COLA) | MC(GC_COTTON_CANDY) | MC(GC_BUBBLES) | MC(GC_PLASTIC) | MC(GC_FIZZY_DRINKS)
+};
+/** END --- TRANSLATE FROM GLOBAL CARGO TO LOCAL CARGO ID'S **/
+
+/**
+ * Bitmask of classes for cargo types.
+ */
+const uint32 cargo_classes[16] = {
+ /* Passengers */ MC(GC_PASSENGERS),
+ /* Mail */ MC(GC_MAIL),
+ /* Express */ MC(GC_GOODS) | MC(GC_FOOD) | MC(GC_CANDY),
+ /* Armoured */ MC(GC_VALUABLES),
+ /* Bulk */ MC(GC_COAL) | MC(GC_GRAIN) | MC(GC_IRON_ORE) | MC(GC_COPPER_ORE) | MC(GC_FRUIT) | MC(GC_SUGAR) | MC(GC_TOFFEE) | MC(GC_COTTON_CANDY),
+ /* Piece */ MC(GC_LIVESTOCK) | MC(GC_WOOD) | MC(GC_STEEL) | MC(GC_PAPER) | MC(GC_TOYS) | MC(GC_BATTERIES) | MC(GC_BUBBLES) | MC(GC_FIZZY_DRINKS),
+ /* Liquids */ MC(GC_OIL) | MC(GC_WATER) | MC(GC_RUBBER) | MC(GC_COLA) | MC(GC_PLASTIC),
+ /* Chilled */ MC(GC_FOOD) | MC(GC_FRUIT),
+ /* Undefined */ 0, 0, 0, 0, 0, 0, 0, 0
+};
+#undef MC
+
+/**
+ *there are 32 slots available per climate with newcargo.*/
+#define MAXSLOTS 32
diff --git a/src/newgrf_cargo.h b/src/newgrf_cargo.h
new file mode 100644
index 000000000..d3b352e48
--- /dev/null
+++ b/src/newgrf_cargo.h
@@ -0,0 +1,60 @@
+/* $Id$ */
+
+#ifndef NEWGRF_CARGO_H
+#define NEWGRF_CARGO_H
+
+enum {
+ CC_NOAVAILABLE = 0,
+ CC_PASSENGERS = 1 << 0,
+ CC_MAIL = 1 << 1,
+ CC_EXPRESS = 1 << 2,
+ CC_ARMOURED = 1 << 3,
+ CC_BULK = 1 << 4,
+ CC_PIECE_GOODS = 1 << 5,
+ CC_LIQUID = 1 << 6,
+ CC_REFRIGERATED = 1 << 7,
+};
+
+enum GlobalCargo {
+ GC_PASSENGERS = 0,
+ GC_COAL = 1,
+ GC_MAIL = 2,
+ GC_OIL = 3,
+ GC_LIVESTOCK = 4,
+ GC_GOODS = 5,
+ GC_GRAIN = 6, // GC_WHEAT / GC_MAIZE
+ GC_WOOD = 7,
+ GC_IRON_ORE = 8,
+ GC_STEEL = 9,
+ GC_VALUABLES = 10, // GC_GOLD / GC_DIAMONDS
+ GC_PAPER = 11,
+ GC_FOOD = 12,
+ GC_FRUIT = 13,
+ GC_COPPER_ORE = 14,
+ GC_WATER = 15,
+ GC_RUBBER = 16,
+ GC_SUGAR = 17,
+ GC_TOYS = 18,
+ GC_BATTERIES = 19,
+ GC_CANDY = 20,
+ GC_TOFFEE = 21,
+ GC_COLA = 22,
+ GC_COTTON_CANDY = 23,
+ GC_BUBBLES = 24,
+ GC_PLASTIC = 25,
+ GC_FIZZY_DRINKS = 26,
+ GC_PAPER_TEMP = 27,
+ GC_UNDEFINED = 28, // undefined; unused slot in arctic climate
+ GC_DEFAULT = 29,
+ GC_PURCHASE = 30,
+ GC_DEFAULT_NA = 31, // New stations only
+ GC_INVALID = 255,
+ NUM_GLOBAL_CID = 32
+};
+
+VARDEF const CargoID _global_cargo_id[NUM_LANDSCAPE][NUM_CARGO];
+VARDEF const uint32 _landscape_global_cargo_mask[NUM_LANDSCAPE];
+VARDEF const CargoID _local_cargo_id_ctype[NUM_GLOBAL_CID];
+VARDEF const uint32 cargo_classes[16];
+
+#endif /* NEWGRF_CARGO_H */
diff --git a/src/newgrf_config.c b/src/newgrf_config.c
new file mode 100644
index 000000000..a6ab2fae5
--- /dev/null
+++ b/src/newgrf_config.c
@@ -0,0 +1,463 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "functions.h"
+#include "macros.h"
+#include "debug.h"
+#include "variables.h"
+#include "string.h"
+#include "saveload.h"
+#include "md5.h"
+#include "network/network_data.h"
+#include "newgrf.h"
+#include "newgrf_config.h"
+
+#include "fileio.h"
+#include "fios.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef WIN32
+# include <io.h>
+#else
+# include <unistd.h>
+# include <dirent.h>
+#endif /* WIN32 */
+
+
+GRFConfig *_all_grfs;
+GRFConfig *_grfconfig;
+GRFConfig *_grfconfig_newgame;
+GRFConfig *_grfconfig_static;
+
+
+/* Calculate the MD5 Sum for a GRF */
+static bool CalcGRFMD5Sum(GRFConfig *config)
+{
+ FILE *f;
+ char filename[MAX_PATH];
+ md5_state_t md5state;
+ md5_byte_t buffer[1024];
+ size_t len;
+
+ /* open the file */
+ snprintf(filename, lengthof(filename), "%s%s", _paths.data_dir, config->filename);
+ f = fopen(filename, "rb");
+ if (f == NULL) return false;
+
+ /* calculate md5sum */
+ md5_init(&md5state);
+ while ((len = fread(buffer, 1, sizeof(buffer), f)) != 0) {
+ md5_append(&md5state, buffer, len);
+ }
+ md5_finish(&md5state, config->md5sum);
+
+ fclose(f);
+
+ return true;
+}
+
+
+/* Find the GRFID and calculate the md5sum */
+bool FillGRFDetails(GRFConfig *config, bool is_static)
+{
+ if (!FioCheckFileExists(config->filename)) {
+ SETBIT(config->flags, GCF_NOT_FOUND);
+ return false;
+ }
+
+ /* Find and load the Action 8 information */
+ /* 62 is the last file slot before sample.cat.
+ * Should perhaps be some "don't care" value */
+ LoadNewGRFFile(config, 62, is_static ? GLS_SAFETYSCAN : GLS_FILESCAN);
+
+ /* GCF_UNSAFE is set if GLS_SAFETYSCAN finds unsafe actions */
+ if (HASBIT(config->flags, GCF_UNSAFE)) return false;
+
+ /* Skip if the grfid is 0 (not read) or 0xFFFFFFFF (ttdp system grf) */
+ if (config->grfid == 0 || config->grfid == 0xFFFFFFFF) return false;
+
+ return CalcGRFMD5Sum(config);
+}
+
+
+void ClearGRFConfig(GRFConfig **config)
+{
+ /* GCF_COPY as in NOT strdupped/alloced the filename, name and info */
+ if (!HASBIT((*config)->flags, GCF_COPY)) {
+ free((*config)->filename);
+ free((*config)->name);
+ free((*config)->info);
+ }
+ free(*config);
+ *config = NULL;
+}
+
+
+/* Clear a GRF Config list */
+void ClearGRFConfigList(GRFConfig **config)
+{
+ GRFConfig *c, *next;
+ for (c = *config; c != NULL; c = next) {
+ next = c->next;
+ ClearGRFConfig(&c);
+ }
+ *config = NULL;
+}
+
+
+/** Copy a GRF Config list
+ * @param dst pointer to destination list
+ * @param srt pointer to source list values
+ * @return pointer to the last value added to the destination list */
+GRFConfig **CopyGRFConfigList(GRFConfig **dst, const GRFConfig *src)
+{
+ GRFConfig *c;
+
+ /* Clear destination as it will be overwritten */
+ ClearGRFConfigList(dst);
+ for (; src != NULL; src = src->next) {
+ c = calloc(1, sizeof(*c));
+ *c = *src;
+ if (src->filename != NULL) c->filename = strdup(src->filename);
+ if (src->name != NULL) c->name = strdup(src->name);
+ if (src->info != NULL) c->info = strdup(src->info);
+
+ *dst = c;
+ dst = &c->next;
+ }
+
+ return dst;
+}
+
+/**
+ * Removes duplicates from lists of GRFConfigs. These duplicates
+ * are introduced when the _grfconfig_static GRFs are appended
+ * to the _grfconfig on a newgame or savegame. As the parameters
+ * of the static GRFs could be different that the parameters of
+ * the ones used non-statically. This can result in desyncs in
+ * multiplayers, so the duplicate static GRFs have to be removed.
+ *
+ * This function _assumes_ that all static GRFs are placed after
+ * the non-static GRFs.
+ *
+ * @param list the list to remove the duplicates from
+ */
+static void RemoveDuplicatesFromGRFConfigList(GRFConfig *list)
+{
+ GRFConfig *prev;
+ GRFConfig *cur;
+
+ if (list == NULL) return;
+
+ for (prev = list, cur = list->next; cur != NULL; prev = cur, cur = cur->next) {
+ if (cur->grfid != list->grfid) continue;
+ assert(HASBIT(cur->flags, GCF_STATIC));
+ prev->next = cur->next;
+ ClearGRFConfig(&cur);
+ cur = prev; // Just go back one so it continues as normal later on
+ }
+
+ RemoveDuplicatesFromGRFConfigList(list->next);
+}
+
+/**
+ * Appends the static GRFs to a list of GRFs
+ * @param dst the head of the list to add to
+ */
+void AppendStaticGRFConfigs(GRFConfig **dst)
+{
+ GRFConfig **tail = dst;
+ while (*tail != NULL) tail = &(*tail)->next;
+
+ CopyGRFConfigList(tail, _grfconfig_static);
+ RemoveDuplicatesFromGRFConfigList(*dst);
+}
+
+
+/* Reset the current GRF Config to either blank or newgame settings */
+void ResetGRFConfig(bool defaults)
+{
+ GRFConfig **c = &_grfconfig;
+
+ if (defaults) {
+ c = CopyGRFConfigList(c, _grfconfig_newgame);
+ } else {
+ ClearGRFConfigList(c);
+ }
+
+ AppendStaticGRFConfigs(&_grfconfig);
+}
+
+
+/* Check if all GRFs in the GRF Config can be loaded */
+bool IsGoodGRFConfigList(void)
+{
+ bool res = true;
+ GRFConfig *c;
+
+ for (c = _grfconfig; c != NULL; c = c->next) {
+ const GRFConfig *f = FindGRFConfig(c->grfid, c->md5sum);
+ if (f == NULL) {
+ char buf[512], *p = buf;
+ uint i;
+
+ p += snprintf(p, lastof(buf) - p, "Couldn't find NewGRF %08X (%s) checksum ", BSWAP32(c->grfid), c->filename);
+ for (i = 0; i < lengthof(c->md5sum); i++) {
+ p += snprintf(p, lastof(buf) - p, "%02X", c->md5sum[i]);
+ }
+ ShowInfo(buf);
+
+ res = false;
+ } else {
+ DEBUG(grf, 1, "Loading GRF %08X from '%s'", BSWAP32(c->grfid), f->filename);
+ /* The filename could be the filename as in the savegame. As we need
+ * to load the GRF here, we need the correct filename, so overwrite that
+ * in any case and set the name and info when it is not set already.
+ * When the GCF_COPY flag is set, it is certain that the filename is
+ * already a local one, so there is no need to replace it. */
+ if (!HASBIT(c->flags, GCF_COPY)) {
+ free(c->filename);
+ c->filename = strdup(f->filename);
+ if (c->name == NULL) c->name = strdup(f->name);
+ if (c->info == NULL) c->info = strdup(f->info);
+ }
+ }
+ }
+
+ return res;
+}
+
+
+extern bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb);
+
+/* Scan a path for NewGRFs */
+static uint ScanPath(const char *path)
+{
+ uint num = 0;
+ struct stat sb;
+ struct dirent *dirent;
+ DIR *dir;
+ GRFConfig *c;
+
+ if ((dir = opendir(path)) == NULL) return 0;
+
+ while ((dirent = readdir(dir)) != NULL) {
+ const char *d_name = FS2OTTD(dirent->d_name);
+ char filename[MAX_PATH];
+
+ if (!FiosIsValidFile(path, dirent, &sb)) continue;
+
+ snprintf(filename, lengthof(filename), "%s" PATHSEP "%s", path, d_name);
+
+ if (sb.st_mode & S_IFDIR) {
+ /* Directory */
+ if (strcmp(d_name, ".") == 0 || strcmp(d_name, "..") == 0) continue;
+ num += ScanPath(filename);
+ } else if (sb.st_mode & S_IFREG) {
+ /* File */
+ char *ext = strrchr(filename, '.');
+ char *file = filename + strlen(_paths.data_dir) + 1; // Crop base path
+
+ /* If no extension or extension isn't .grf, skip the file */
+ if (ext == NULL) continue;
+ if (strcasecmp(ext, ".grf") != 0) continue;
+
+ c = calloc(1, sizeof(*c));
+ c->filename = strdup(file);
+
+ if (FillGRFDetails(c, false)) {
+ if (_all_grfs == NULL) {
+ _all_grfs = c;
+ } else {
+ /* Insert file into list at a position determined by its
+ * name, so the list is sorted as we go along */
+ GRFConfig **pd, *d;
+ for (pd = &_all_grfs; (d = *pd) != NULL; pd = &d->next) {
+ if (strcasecmp(c->name, d->name) <= 0) break;
+ }
+ c->next = d;
+ *pd = c;
+ }
+
+ num++;
+ } else {
+ /* File couldn't be opened, or is either not a NewGRF or is a
+ * 'system' NewGRF, so forget about it. */
+ free(c->filename);
+ free(c->name);
+ free(c->info);
+ free(c);
+ }
+ }
+ }
+
+ closedir(dir);
+
+ return num;
+}
+
+
+/* Scan for all NewGRFs */
+void ScanNewGRFFiles(void)
+{
+ uint num;
+
+ ClearGRFConfigList(&_all_grfs);
+
+ DEBUG(grf, 1, "Scanning for NewGRFs");
+ num = ScanPath(_paths.data_dir);
+ DEBUG(grf, 1, "Scan complete, found %d files", num);
+}
+
+
+/* Find a NewGRF in the scanned list */
+const GRFConfig *FindGRFConfig(uint32 grfid, uint8 *md5sum)
+{
+ GRFConfig *c;
+ static const uint8 blanksum[sizeof(c->md5sum)] = { 0 };
+
+ for (c = _all_grfs; c != NULL; c = c->next) {
+ if (c->grfid == grfid) {
+ if (memcmp(blanksum, c->md5sum, sizeof(c->md5sum)) == 0) CalcGRFMD5Sum(c);
+ if (memcmp(md5sum, c->md5sum, sizeof(c->md5sum)) == 0) return c;
+ }
+ }
+
+ return NULL;
+}
+
+#ifdef ENABLE_NETWORK
+
+/** Structure for UnknownGRFs; this is a lightweight variant of GRFConfig */
+typedef struct UnknownGRF UnknownGRF;
+struct UnknownGRF {
+ UnknownGRF *next;
+ uint32 grfid;
+ uint8 md5sum[16];
+ char name[NETWORK_GRF_NAME_LENGTH];
+};
+
+/**
+ * Finds the name of a NewGRF in the list of names for unknown GRFs. An
+ * unknown GRF is a GRF where the .grf is not found during scanning.
+ *
+ * The names are resolved via UDP calls to servers that should know the name,
+ * though the replies may not come. This leaves "<Unknown>" as name, though
+ * that shouldn't matter _very_ much as they need GRF crawler or so to look
+ * up the GRF anyway and that works better with the GRF ID.
+ *
+ * @param grfid the GRF ID part of the 'unique' GRF identifier
+ * @param md5sum the MD5 checksum part of the 'unique' GRF identifier
+ * @param create whether to create a new GRFConfig if the GRFConfig did not
+ * exist in the fake list of GRFConfigs.
+ * @return the GRFConfig with the given GRF ID and MD5 checksum or NULL when
+ * it does not exist and create is false. This value must NEVER be
+ * freed by the caller.
+ */
+char *FindUnknownGRFName(uint32 grfid, uint8 *md5sum, bool create)
+{
+ UnknownGRF *grf;
+ static UnknownGRF *unknown_grfs = NULL;
+
+ for (grf = unknown_grfs; grf != NULL; grf = grf->next) {
+ if (grf->grfid == grfid) {
+ if (memcmp(md5sum, grf->md5sum, sizeof(grf->md5sum)) == 0) return grf->name;
+ }
+ }
+
+ if (!create) return NULL;
+
+ grf = calloc(1, sizeof(*grf));
+ grf->grfid = grfid;
+ grf->next = unknown_grfs;
+ ttd_strlcpy(grf->name, UNKNOWN_GRF_NAME_PLACEHOLDER, sizeof(grf->name));
+ memcpy(grf->md5sum, md5sum, sizeof(grf->md5sum));
+
+ unknown_grfs = grf;
+ return grf->name;
+}
+
+#endif /* ENABLE_NETWORK */
+
+
+/* Retrieve a NewGRF from the current config by its grfid */
+GRFConfig *GetGRFConfig(uint32 grfid)
+{
+ GRFConfig *c;
+
+ for (c = _grfconfig; c != NULL; c = c->next) {
+ if (c->grfid == grfid) return c;
+ }
+
+ return NULL;
+}
+
+
+/* Build a space separated list of parameters, and terminate */
+char *GRFBuildParamList(char *dst, const GRFConfig *c, const char *last)
+{
+ uint i;
+
+ /* Return an empty string if there are no parameters */
+ if (c->num_params == 0) return strecpy(dst, "", last);
+
+ for (i = 0; i < c->num_params; i++) {
+ if (i > 0) dst = strecpy(dst, " ", last);
+ dst += snprintf(dst, last - dst, "%d", c->param[i]);
+ }
+ return dst;
+}
+
+
+static const SaveLoad _grfconfig_desc[] = {
+ SLE_STR(GRFConfig, filename, SLE_STR, 0x40),
+ SLE_VAR(GRFConfig, grfid, SLE_UINT32),
+ SLE_ARR(GRFConfig, md5sum, SLE_UINT8, 16),
+ SLE_ARR(GRFConfig, param, SLE_UINT32, 0x80),
+ SLE_VAR(GRFConfig, num_params, SLE_UINT8),
+ SLE_END()
+};
+
+
+static void Save_NGRF(void)
+{
+ GRFConfig *c;
+ int index = 0;
+
+ for (c = _grfconfig; c != NULL; c = c->next) {
+ if (HASBIT(c->flags, GCF_STATIC)) continue;
+ SlSetArrayIndex(index++);
+ SlObject(c, _grfconfig_desc);
+ }
+}
+
+
+static void Load_NGRF(void)
+{
+ GRFConfig *first = NULL;
+ GRFConfig **last = &first;
+
+ while (SlIterateArray() != -1) {
+ GRFConfig *c = calloc(1, sizeof(*c));
+ SlObject(c, _grfconfig_desc);
+
+ /* Append our configuration to the list */
+ *last = c;
+ last = &c->next;
+ }
+
+ /* Append static NewGRF configuration */
+ CopyGRFConfigList(last, _grfconfig_static);
+
+ ClearGRFConfigList(&_grfconfig);
+ _grfconfig = first;
+ AppendStaticGRFConfigs(&_grfconfig);
+}
+
+const ChunkHandler _newgrf_chunk_handlers[] = {
+ { 'NGRF', Save_NGRF, Load_NGRF, CH_ARRAY | CH_LAST }
+};
+
+
diff --git a/src/newgrf_config.h b/src/newgrf_config.h
new file mode 100644
index 000000000..6ebc3ffa2
--- /dev/null
+++ b/src/newgrf_config.h
@@ -0,0 +1,64 @@
+/* $Id$ */
+
+#ifndef NEWGRF_CONFIG_H
+#define NEWGRF_CONFIG_H
+
+/* GRF config bit flags */
+enum {
+ GCF_DISABLED,
+ GCF_NOT_FOUND,
+ GCF_ACTIVATED,
+ GCF_SYSTEM,
+ GCF_UNSAFE,
+ GCF_STATIC,
+ GCF_COPY, ///< The data is copied from a grf in _all_grfs
+};
+
+typedef struct GRFConfig {
+ char *filename;
+ char *name;
+ char *info;
+ uint32 grfid;
+
+ uint8 flags;
+ uint8 md5sum[16];
+ uint32 param[0x80];
+ uint8 num_params;
+
+ struct GRFConfig *next;
+} GRFConfig;
+
+/* First item in list of all scanned NewGRFs */
+extern GRFConfig *_all_grfs;
+
+/* First item in list of current GRF set up */
+extern GRFConfig *_grfconfig;
+
+/* First item in list of default GRF set up */
+extern GRFConfig *_grfconfig_newgame;
+
+/* First item in list of static GRF set up */
+extern GRFConfig *_grfconfig_static;
+
+void ScanNewGRFFiles(void);
+const GRFConfig *FindGRFConfig(uint32 grfid, uint8 *md5sum);
+GRFConfig *GetGRFConfig(uint32 grfid);
+GRFConfig **CopyGRFConfigList(GRFConfig **dst, const GRFConfig *src);
+void AppendStaticGRFConfigs(GRFConfig **dst);
+void ClearGRFConfig(GRFConfig **config);
+void ClearGRFConfigList(GRFConfig **config);
+void ResetGRFConfig(bool defaults);
+bool IsGoodGRFConfigList(void);
+bool FillGRFDetails(GRFConfig *config, bool is_static);
+char *GRFBuildParamList(char *dst, const GRFConfig *c, const char *last);
+
+/* In newgrf_gui.c */
+void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFConfig **config);
+
+#ifdef ENABLE_NETWORK
+/* For communication about GRFs over the network */
+#define UNKNOWN_GRF_NAME_PLACEHOLDER "<Unknown>"
+char *FindUnknownGRFName(uint32 grfid, uint8 *md5sum, bool create);
+#endif /* ENABLE_NETWORK */
+
+#endif /* NEWGRF_CONFIG_H */
diff --git a/src/newgrf_engine.c b/src/newgrf_engine.c
new file mode 100644
index 000000000..0662f3fc8
--- /dev/null
+++ b/src/newgrf_engine.c
@@ -0,0 +1,1157 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "variables.h"
+#include "debug.h"
+#include "functions.h"
+#include "engine.h"
+#include "train.h"
+#include "player.h"
+#include "station.h"
+#include "airport.h"
+#include "newgrf.h"
+#include "newgrf_callbacks.h"
+#include "newgrf_engine.h"
+#include "newgrf_station.h"
+#include "newgrf_spritegroup.h"
+#include "newgrf_cargo.h"
+#include "date.h"
+
+
+
+/* Default cargo classes */
+static const uint16 _cargo_classes[NUM_GLOBAL_CID] = {
+ CC_PASSENGERS,
+ CC_BULK,
+ CC_MAIL,
+ CC_LIQUID,
+ CC_PIECE_GOODS,
+ CC_EXPRESS,
+ CC_BULK,
+ CC_PIECE_GOODS,
+ CC_BULK,
+ CC_PIECE_GOODS,
+ CC_ARMOURED,
+ CC_PIECE_GOODS,
+ CC_REFRIGERATED | CC_EXPRESS,
+ CC_REFRIGERATED | CC_EXPRESS,
+ CC_BULK,
+ CC_LIQUID,
+ CC_LIQUID,
+ CC_BULK,
+ CC_PIECE_GOODS,
+ CC_PIECE_GOODS,
+ CC_EXPRESS,
+ CC_BULK,
+ CC_LIQUID,
+ CC_BULK,
+ CC_PIECE_GOODS,
+ CC_LIQUID,
+ CC_PIECE_GOODS,
+ CC_PIECE_GOODS,
+ CC_NOAVAILABLE,
+ CC_NOAVAILABLE,
+ CC_NOAVAILABLE,
+};
+
+int _traininfo_vehicle_pitch = 0;
+int _traininfo_vehicle_width = 29;
+
+typedef struct WagonOverride {
+ byte *train_id;
+ int trains;
+ CargoID cargo;
+ const SpriteGroup *group;
+} WagonOverride;
+
+typedef struct WagonOverrides {
+ int overrides_count;
+ WagonOverride *overrides;
+} WagonOverrides;
+
+static WagonOverrides _engine_wagon_overrides[TOTAL_NUM_ENGINES];
+
+void SetWagonOverrideSprites(EngineID engine, CargoID cargo, const SpriteGroup *group, byte *train_id, int trains)
+{
+ WagonOverrides *wos;
+ WagonOverride *wo;
+
+ assert(engine < TOTAL_NUM_ENGINES);
+ assert(cargo < NUM_GLOBAL_CID);
+
+ wos = &_engine_wagon_overrides[engine];
+ wos->overrides_count++;
+ wos->overrides = realloc(wos->overrides,
+ wos->overrides_count * sizeof(*wos->overrides));
+
+ wo = &wos->overrides[wos->overrides_count - 1];
+ /* FIXME: If we are replacing an override, release original SpriteGroup
+ * to prevent leaks. But first we need to refcount the SpriteGroup.
+ * --pasky */
+ wo->group = group;
+ wo->cargo = cargo;
+ wo->trains = trains;
+ wo->train_id = malloc(trains);
+ memcpy(wo->train_id, train_id, trains);
+}
+
+static const SpriteGroup *GetWagonOverrideSpriteSet(EngineID engine, CargoID cargo, byte overriding_engine)
+{
+ const WagonOverrides *wos = &_engine_wagon_overrides[engine];
+ int i;
+
+ // XXX: This could turn out to be a timesink on profiles. We could
+ // always just dedicate 65535 bytes for an [engine][train] trampoline
+ // for O(1). Or O(logMlogN) and searching binary tree or smt. like
+ // that. --pasky
+
+ for (i = 0; i < wos->overrides_count; i++) {
+ const WagonOverride *wo = &wos->overrides[i];
+ int j;
+
+ for (j = 0; j < wo->trains; j++) {
+ if (wo->train_id[j] == overriding_engine && (wo->cargo == cargo || wo->cargo == GC_DEFAULT)) return wo->group;
+ }
+ }
+ return NULL;
+}
+
+/**
+ * Unload all wagon override sprite groups.
+ */
+void UnloadWagonOverrides(void)
+{
+ WagonOverrides *wos;
+ WagonOverride *wo;
+ EngineID engine;
+ int i;
+
+ for (engine = 0; engine < TOTAL_NUM_ENGINES; engine++) {
+ wos = &_engine_wagon_overrides[engine];
+ for (i = 0; i < wos->overrides_count; i++) {
+ wo = &wos->overrides[i];
+ wo->group = NULL;
+ free(wo->train_id);
+ }
+ free(wos->overrides);
+ wos->overrides_count = 0;
+ wos->overrides = NULL;
+ }
+}
+
+// 0 - 28 are cargos, 29 is default, 30 is the advert (purchase list)
+// (It isn't and shouldn't be like this in the GRF files since new cargo types
+// may appear in future - however it's more convenient to store it like this in
+// memory. --pasky)
+static const SpriteGroup *engine_custom_sprites[TOTAL_NUM_ENGINES][NUM_GLOBAL_CID];
+static const GRFFile *_engine_grf[TOTAL_NUM_ENGINES];
+
+void SetCustomEngineSprites(EngineID engine, byte cargo, const SpriteGroup *group)
+{
+ assert(engine < TOTAL_NUM_ENGINES);
+ assert(cargo < NUM_GLOBAL_CID);
+
+ if (engine_custom_sprites[engine][cargo] != NULL) {
+ grfmsg(6, "SetCustomEngineSprites: engine %d cargo %d already has group -- replacing", engine, cargo);
+ }
+ engine_custom_sprites[engine][cargo] = group;
+}
+
+/**
+ * Unload all engine sprite groups.
+ */
+void UnloadCustomEngineSprites(void)
+{
+ EngineID engine;
+ CargoID cargo;
+
+ for (engine = 0; engine < TOTAL_NUM_ENGINES; engine++) {
+ for (cargo = 0; cargo < NUM_GLOBAL_CID; cargo++) {
+ engine_custom_sprites[engine][cargo] = NULL;
+ }
+ _engine_grf[engine] = 0;
+ }
+}
+
+static const SpriteGroup *heli_rotor_custom_sprites[NUM_AIRCRAFT_ENGINES];
+
+/** Load a rotor override sprite group for an aircraft */
+void SetRotorOverrideSprites(EngineID engine, const SpriteGroup *group)
+{
+ assert(engine >= AIRCRAFT_ENGINES_INDEX);
+ assert(engine < AIRCRAFT_ENGINES_INDEX + NUM_AIRCRAFT_ENGINES);
+
+ if (heli_rotor_custom_sprites[engine - AIRCRAFT_ENGINES_INDEX] != NULL) {
+ grfmsg(6, "SetRotorOverrideSprites: engine %d already has group -- replacing.", engine);
+ }
+ heli_rotor_custom_sprites[engine - AIRCRAFT_ENGINES_INDEX] = group;
+}
+
+/** Unload all rotor override sprite groups */
+void UnloadRotorOverrideSprites(void)
+{
+ EngineID engine;
+
+ /* Starting at AIRCRAFT_ENGINES_INDEX may seem pointless, but it means
+ * the context of EngineID is correct */
+ for (engine = AIRCRAFT_ENGINES_INDEX; engine < AIRCRAFT_ENGINES_INDEX + NUM_AIRCRAFT_ENGINES; engine++) {
+ heli_rotor_custom_sprites[engine - AIRCRAFT_ENGINES_INDEX] = NULL;
+ }
+}
+
+
+/**
+ * Tie a GRFFile entry to an engine, to allow us to retrieve GRF parameters
+ * etc during a game.
+ * @param engine Engine ID to tie the GRFFile to.
+ * @param file Pointer of GRFFile to tie.
+ */
+void SetEngineGRF(EngineID engine, const GRFFile *file)
+{
+ assert(engine < TOTAL_NUM_ENGINES);
+ _engine_grf[engine] = file;
+}
+
+
+/**
+ * Retrieve the GRFFile tied to an engine
+ * @param engine Engine ID to retrieve.
+ * @return Pointer to GRFFile.
+ */
+const GRFFile *GetEngineGRF(EngineID engine)
+{
+ assert(engine < TOTAL_NUM_ENGINES);
+ return _engine_grf[engine];
+}
+
+
+/**
+ * Retrieve the GRF ID of the GRFFile tied to an engine
+ * @param engine Engine ID to retrieve.
+ * @return 32 bit GRFID value.
+ */
+uint32 GetEngineGRFID(EngineID engine)
+{
+ assert(engine < TOTAL_NUM_ENGINES);
+ return _engine_grf[engine]->grfid;
+}
+
+
+static int MapOldSubType(const Vehicle *v)
+{
+ if (v->type != VEH_Train) return v->subtype;
+ if (IsTrainEngine(v)) return 0;
+ if (IsFreeWagon(v)) return 4;
+ return 2;
+}
+
+
+/* TTDP style aircraft movement states for GRF Action 2 Var 0xE2 */
+enum {
+ AMS_TTDP_HANGAR,
+ AMS_TTDP_TO_HANGAR,
+ AMS_TTDP_TO_PAD1,
+ AMS_TTDP_TO_PAD2,
+ AMS_TTDP_TO_PAD3,
+ AMS_TTDP_TO_ENTRY_2_AND_3,
+ AMS_TTDP_TO_ENTRY_2_AND_3_AND_H,
+ AMS_TTDP_TO_JUNCTION,
+ AMS_TTDP_LEAVE_RUNWAY,
+ AMS_TTDP_TO_INWAY,
+ AMS_TTDP_TO_RUNWAY,
+ AMS_TTDP_TO_OUTWAY,
+ AMS_TTDP_WAITING,
+ AMS_TTDP_TAKEOFF,
+ AMS_TTDP_TO_TAKEOFF,
+ AMS_TTDP_CLIMBING,
+ AMS_TTDP_FLIGHT_APPROACH,
+ AMS_TTDP_UNUSED_0x11,
+ AMS_TTDP_FLIGHT_TO_TOWER,
+ AMS_TTDP_UNUSED_0x13,
+ AMS_TTDP_FLIGHT_FINAL,
+ AMS_TTDP_FLIGHT_DESCENT,
+ AMS_TTDP_BRAKING,
+ AMS_TTDP_HELI_TAKEOFF_AIRPORT,
+ AMS_TTDP_HELI_TO_TAKEOFF_AIRPORT,
+ AMS_TTDP_HELI_LAND_AIRPORT,
+ AMS_TTDP_HELI_TAKEOFF_HELIPORT,
+ AMS_TTDP_HELI_TO_TAKEOFF_HELIPORT,
+ AMS_TTDP_HELI_LAND_HELIPORT,
+};
+
+
+/**
+ * Map OTTD aircraft movement states to TTDPatch style movement states
+ * (VarAction 2 Variable 0xE2)
+ */
+static byte MapAircraftMovementState(const Vehicle *v)
+{
+ const Station *st = GetStation(v->u.air.targetairport);
+ byte amdflag = GetAirportMovingData(st->airport_type, v->u.air.pos)->flag;
+
+ switch (v->u.air.state) {
+ case HANGAR:
+ /* The international airport is a special case as helicopters can land in
+ * front of the hanger. Helicopters also change their air.state to
+ * AMED_HELI_LOWER some time before actually descending. */
+
+ /* This condition only occurs for helicopters, during descent,
+ * to a landing by the hanger of an international airport. */
+ if (amdflag & AMED_HELI_LOWER) return AMS_TTDP_HELI_LAND_AIRPORT;
+
+ /* This condition only occurs for helicopters, before starting descent,
+ * to a landing by the hanger of an international airport. */
+ if (amdflag & AMED_SLOWTURN) return AMS_TTDP_FLIGHT_TO_TOWER;
+
+ // The final two conditions apply to helicopters or aircraft.
+ /* Has reached hanger? */
+ if (amdflag & AMED_EXACTPOS) return AMS_TTDP_HANGAR;
+
+ // Still moving towards hanger.
+ return AMS_TTDP_TO_HANGAR;
+
+ case TERM1:
+ if (amdflag & AMED_EXACTPOS) return AMS_TTDP_TO_PAD1;
+ return AMS_TTDP_TO_JUNCTION;
+
+ case TERM2:
+ if (amdflag & AMED_EXACTPOS) return AMS_TTDP_TO_PAD2;
+ return AMS_TTDP_TO_ENTRY_2_AND_3_AND_H;
+
+ case TERM3:
+ case TERM4:
+ case TERM5:
+ case TERM6:
+ case TERM7:
+ case TERM8:
+ /* TTDPatch only has 3 terminals, so treat these states the same */
+ if (amdflag & AMED_EXACTPOS) return AMS_TTDP_TO_PAD3;
+ return AMS_TTDP_TO_ENTRY_2_AND_3_AND_H;
+
+ case HELIPAD1:
+ case HELIPAD2:
+ case HELIPAD3:
+ case HELIPAD4: // Will only occur for helicopters.
+ if (amdflag & AMED_HELI_LOWER) return AMS_TTDP_HELI_LAND_AIRPORT; // Descending.
+ if (amdflag & AMED_SLOWTURN) return AMS_TTDP_FLIGHT_TO_TOWER; // Still hasn't started descent.
+ return AMS_TTDP_TO_JUNCTION; // On the ground.
+
+ case TAKEOFF: // Moving to takeoff position.
+ return AMS_TTDP_TO_OUTWAY;
+
+ case STARTTAKEOFF: // Accelerating down runway.
+ return AMS_TTDP_TAKEOFF;
+
+ case ENDTAKEOFF: // Ascent
+ return AMS_TTDP_CLIMBING;
+
+ case HELITAKEOFF: // Helicopter is moving to take off position.
+ switch (st->airport_type) {
+ case AT_SMALL:
+ case AT_LARGE:
+ case AT_METROPOLITAN:
+ case AT_INTERNATIONAL:
+ case AT_COMMUTER:
+ case AT_INTERCON:
+ /* Note, Helidepot and Helistation are treated as airports as
+ * helicopters are taking off from ground level. */
+ case AT_HELIDEPOT:
+ case AT_HELISTATION:
+ if (amdflag & AMED_HELI_RAISE) return AMS_TTDP_HELI_TAKEOFF_AIRPORT;
+ return AMS_TTDP_TO_JUNCTION;
+
+ case AT_HELIPORT:
+ case AT_OILRIG:
+ return AMS_TTDP_HELI_TAKEOFF_HELIPORT;
+
+ default:
+ return AMS_TTDP_HELI_TAKEOFF_AIRPORT;
+ }
+
+ case FLYING:
+ return AMS_TTDP_FLIGHT_TO_TOWER;
+
+ case LANDING: // Descent
+ return AMS_TTDP_FLIGHT_DESCENT;
+
+ case ENDLANDING: // On the runway braking
+ if (amdflag & AMED_BRAKE) return AMS_TTDP_BRAKING;
+ // Landed - moving off runway
+ return AMS_TTDP_TO_INWAY;
+
+ case HELILANDING:
+ case HELIENDLANDING: // Helicoptor is decending.
+ if (amdflag & AMED_HELI_LOWER) {
+ switch (st->airport_type) {
+ case AT_HELIPORT:
+ case AT_OILRIG:
+ return AMS_TTDP_HELI_LAND_HELIPORT;
+
+ default:
+ /* Note, Helidepot and Helistation are treated as airports as
+ * helicopters are landing at ground level. */
+ return AMS_TTDP_HELI_LAND_AIRPORT;
+ }
+ }
+ return AMS_TTDP_FLIGHT_TO_TOWER;
+
+ default:
+ return AMS_TTDP_HANGAR;
+ }
+}
+
+
+/* TTDP style aircraft movement action for GRF Action 2 Var 0xE6 */
+enum {
+ AMA_TTDP_IN_HANGAR,
+ AMA_TTDP_ON_PAD1,
+ AMA_TTDP_ON_PAD2,
+ AMA_TTDP_ON_PAD3,
+ AMA_TTDP_HANGAR_TO_PAD1,
+ AMA_TTDP_HANGAR_TO_PAD2,
+ AMA_TTDP_HANGAR_TO_PAD3,
+ AMA_TTDP_LANDING_TO_PAD1,
+ AMA_TTDP_LANDING_TO_PAD2,
+ AMA_TTDP_LANDING_TO_PAD3,
+ AMA_TTDP_PAD1_TO_HANGAR,
+ AMA_TTDP_PAD2_TO_HANGAR,
+ AMA_TTDP_PAD3_TO_HANGAR,
+ AMA_TTDP_PAD1_TO_TAKEOFF,
+ AMA_TTDP_PAD2_TO_TAKEOFF,
+ AMA_TTDP_PAD3_TO_TAKEOFF,
+ AMA_TTDP_HANGAR_TO_TAKOFF,
+ AMA_TTDP_LANDING_TO_HANGAR,
+ AMA_TTDP_IN_FLIGHT,
+};
+
+
+/**
+ * Map OTTD aircraft movement states to TTDPatch style movement actions
+ * (VarAction 2 Variable 0xE6)
+ * This is not fully supported yet but it's enough for Planeset.
+ */
+static byte MapAircraftMovementAction(const Vehicle *v)
+{
+ switch (v->u.air.state) {
+ case HANGAR:
+ return (v->cur_speed > 0) ? AMA_TTDP_LANDING_TO_HANGAR : AMA_TTDP_IN_HANGAR;
+
+ case TERM1:
+ case HELIPAD1:
+ return (v->current_order.type == OT_LOADING) ? AMA_TTDP_ON_PAD1 : AMA_TTDP_LANDING_TO_PAD1;
+
+ case TERM2:
+ case HELIPAD2:
+ return (v->current_order.type == OT_LOADING) ? AMA_TTDP_ON_PAD2 : AMA_TTDP_LANDING_TO_PAD2;
+
+ case TERM3:
+ case TERM4:
+ case TERM5:
+ case TERM6:
+ case TERM7:
+ case TERM8:
+ case HELIPAD3:
+ case HELIPAD4:
+ return (v->current_order.type == OT_LOADING) ? AMA_TTDP_ON_PAD3 : AMA_TTDP_LANDING_TO_PAD3;
+
+ case TAKEOFF: // Moving to takeoff position
+ case STARTTAKEOFF: // Accelerating down runway
+ case ENDTAKEOFF: // Ascent
+ case HELITAKEOFF:
+ // TODO Need to find which terminal (or hanger) we've come from. How?
+ return AMA_TTDP_PAD1_TO_TAKEOFF;
+
+ case FLYING:
+ return AMA_TTDP_IN_FLIGHT;
+
+ case LANDING: // Descent
+ case ENDLANDING: // On the runway braking
+ case HELILANDING:
+ case HELIENDLANDING:
+ // TODO Need to check terminal we're landing to. Is it known yet?
+ return (v->current_order.type == OT_GOTO_DEPOT) ?
+ AMA_TTDP_LANDING_TO_HANGAR : AMA_TTDP_LANDING_TO_PAD1;
+
+ default:
+ return AMA_TTDP_IN_HANGAR;
+ }
+}
+
+
+/* TTDP airport types. Used to map our types to TTDPatch's */
+enum {
+ ATP_TTDP_SMALL,
+ ATP_TTDP_LARGE,
+ ATP_TTDP_HELIPORT,
+ ATP_TTDP_OILRIG,
+};
+
+
+/* Vehicle Resolver Functions */
+static inline const Vehicle *GRV(const ResolverObject *object)
+{
+ return object->scope == VSG_SCOPE_SELF ? object->u.vehicle.self : object->u.vehicle.parent;
+}
+
+
+static uint32 VehicleGetRandomBits(const ResolverObject *object)
+{
+ return GRV(object) == NULL ? 0 : GRV(object)->random_bits;
+}
+
+
+static uint32 VehicleGetTriggers(const ResolverObject *object)
+{
+ return GRV(object) == NULL ? 0 : GRV(object)->waiting_triggers;
+}
+
+
+static void VehicleSetTriggers(const ResolverObject *object, int triggers)
+{
+ /* Evil cast to get around const-ness. This used to be achieved by an
+ * innocent looking function pointer cast... Currently I cannot see a
+ * way of avoiding this without removing consts deep within gui code.
+ */
+ Vehicle *v = (Vehicle*)GRV(object);
+
+ /* This function must only be called when processing triggers -- any
+ * other time is an error. */
+ assert(object->trigger != 0);
+
+ if (v != NULL) v->waiting_triggers = triggers;
+}
+
+
+static uint32 GetVehicleTypeInfo(EngineID engine_type)
+{
+ /* Bit 0 Vehicle type is available on the market
+ * Bit 1 Vehicle type is in the testing phase
+ * Bit 2 Exclusive testing offer for a human player active */
+ const Engine *e = GetEngine(engine_type);
+ uint32 var = 0;
+
+ if (e->player_avail == 0xFF) SETBIT(var, 0);
+ if (e->age < e->duration_phase_1) SETBIT(var, 1);
+ if (e->player_avail > 0 && e->player_avail != 0xFF) SETBIT(var, 2);
+ return var;
+}
+
+
+static uint32 GetGRFParameter(EngineID engine_type, byte parameter)
+{
+ const GRFFile *file = GetEngineGRF(engine_type);
+
+ if (parameter >= file->param_end) return 0;
+ return file->param[parameter];
+}
+
+
+static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
+{
+ const Vehicle *v = GRV(object);
+
+ if (v == NULL) {
+ /* Vehicle does not exist, so we're in a purchase list */
+ switch (variable) {
+ case 0x43: return _current_player; /* Owner information */
+ case 0x46: return 0; /* Motion counter */
+ case 0x48: return GetVehicleTypeInfo(object->u.vehicle.self_type); /* Vehicle Type Info */
+ case 0xC4: return clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR; /* Build year */
+ case 0xDA: return INVALID_VEHICLE; /* Next vehicle */
+ case 0x7F: return GetGRFParameter(object->u.vehicle.self_type, parameter); /* Read GRF parameter */
+ }
+
+ *available = false;
+ return -1;
+ }
+
+ /* Calculated vehicle parameters */
+ switch (variable) {
+ case 0x40: /* Get length of consist */
+ case 0x41: /* Get length of same consecutive wagons */
+ if (v->type != VEH_Train) return 1;
+
+ {
+ const Vehicle* u;
+ byte chain_before = 0;
+ byte chain_after = 0;
+
+ for (u = GetFirstVehicleInChain(v); u != v; u = u->next) {
+ chain_before++;
+ if (variable == 0x41 && u->engine_type != v->engine_type) chain_before = 0;
+ }
+
+ while (u->next != NULL && (variable == 0x40 || u->next->engine_type == v->engine_type)) {
+ chain_after++;
+ u = u->next;
+ }
+
+ return chain_before | chain_after << 8 | (chain_before + chain_after + (variable == 0x41)) << 16;
+ }
+
+ case 0x42: { /* Consist cargo information */
+ /* XXX Missing support for common refit cycle and property 25 */
+ const Vehicle *u;
+ byte cargo_classes = 0;
+ uint common_cargo_best = 0;
+ uint common_cargos[NUM_GLOBAL_CID];
+ byte user_def_data = 0;
+ CargoID cargo;
+ CargoID common_cargo_type = GC_PASSENGERS;
+
+ /* Reset our arrays */
+ memset(common_cargos, 0, sizeof(common_cargos));
+
+ for (u = v; u != NULL; u = u->next) {
+ /* Skip empty engines */
+ if (u->cargo_cap == 0) continue;
+ /* Map from climate to global cargo ID */
+ cargo = _global_cargo_id[_opt.landscape][u->cargo_type];
+ cargo_classes |= _cargo_classes[cargo];
+ common_cargos[cargo]++;
+ user_def_data |= RailVehInfo(u->engine_type)->user_def_data;
+ }
+
+ /* Pick the most common cargo type */
+ for (cargo = 0; cargo < NUM_GLOBAL_CID; cargo++) {
+ if (common_cargos[cargo] > common_cargo_best) {
+ common_cargo_best = common_cargos[cargo];
+ common_cargo_type = cargo;
+ }
+ }
+
+ return cargo_classes | (common_cargo_type << 8) | (user_def_data << 24);
+ }
+
+ case 0x43: /* Player information */
+ return v->owner;
+
+ case 0x44: /* Aircraft information */
+ if (v->type != VEH_Aircraft) return -1;
+
+ {
+ const Vehicle *w = v->next;
+ uint16 altitude = v->z_pos - w->z_pos; /* Aircraft height - shadow height */
+ byte airporttype;
+
+ switch (GetStation(v->u.air.targetairport)->airport_type) {
+ /* Note, Helidepot and Helistation are treated as small airports
+ * as they are at ground level. */
+ case AT_HELIDEPOT:
+ case AT_HELISTATION:
+ case AT_COMMUTER:
+ case AT_SMALL: airporttype = ATP_TTDP_SMALL; break;
+ case AT_METROPOLITAN:
+ case AT_INTERNATIONAL:
+ case AT_INTERCON:
+ case AT_LARGE: airporttype = ATP_TTDP_LARGE; break;
+ case AT_HELIPORT: airporttype = ATP_TTDP_HELIPORT; break;
+ case AT_OILRIG: airporttype = ATP_TTDP_OILRIG; break;
+ default: airporttype = ATP_TTDP_LARGE; break;
+ }
+
+ return (altitude << 8) | airporttype;
+ }
+
+ case 0x46: /* Motion counter */
+ return v->motion_counter;
+
+ case 0x47: { /* Vehicle cargo info */
+ /* Format: ccccwwtt
+ * tt - the cargo type transported by the vehicle,
+ * translated if a translation table has been installed.
+ * ww - cargo unit weight in 1/16 tons, same as cargo prop. 0F.
+ * cccc - the cargo class value of the cargo transported by the vehicle.
+ */
+ CargoID cid = _global_cargo_id[_opt.landscape][v->cargo_type];
+
+ return (_cargo_classes[cid] << 16) | (_cargoc.weights[v->cargo_type] << 8) | cid;
+ }
+
+ case 0x48: return GetVehicleTypeInfo(v->engine_type); /* Vehicle Type Info */
+
+ /* Variables which use the parameter */
+ case 0x60: /* Count consist's engine ID occurance */
+ if (v->type != VEH_Train) return v->engine_type == parameter;
+
+ {
+ uint count = 0;
+ for (; v != NULL; v = v->next) {
+ if (v->engine_type == parameter) count++;
+ }
+ return count;
+ }
+
+ case 0x7F: return GetGRFParameter(v->engine_type, parameter); /* Read GRF parameter */
+ }
+
+ /* General vehicle properties */
+ switch (variable - 0x80) {
+ case 0x00: return v->type;
+ case 0x01: return MapOldSubType(v);
+ case 0x04: return v->index;
+ case 0x05: return GB(v->index, 8, 8);
+ case 0x0A: return PackOrder(&v->current_order);
+ case 0x0B: return GB(PackOrder(&v->current_order), 8, 8);
+ case 0x0C: return v->num_orders;
+ case 0x0D: return v->cur_order_index;
+ case 0x10: return v->load_unload_time_rem;
+ case 0x11: return GB(v->load_unload_time_rem, 8, 8);
+ case 0x12: return max(v->date_of_last_service - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
+ case 0x13: return GB(max(v->date_of_last_service - DAYS_TILL_ORIGINAL_BASE_YEAR, 0), 8, 8);
+ case 0x14: return v->service_interval;
+ case 0x15: return GB(v->service_interval, 8, 8);
+ case 0x16: return v->last_station_visited;
+ case 0x17: return v->tick_counter;
+ case 0x18: return v->max_speed;
+ case 0x19: return GB(v->max_speed, 8, 8);
+ case 0x1A: return v->x_pos;
+ case 0x1B: return GB(v->x_pos, 8, 8);
+ case 0x1C: return v->y_pos;
+ case 0x1D: return GB(v->y_pos, 8, 8);
+ case 0x1E: return v->z_pos;
+ case 0x1F: return object->info_view ? DIR_W : v->direction;
+ case 0x28: return v->cur_image;
+ case 0x29: return GB(v->cur_image, 8, 8);
+ case 0x32: return v->vehstatus;
+ case 0x33: return 0; // non-existent high byte of vehstatus
+ case 0x34: return v->cur_speed;
+ case 0x35: return GB(v->cur_speed, 8, 8);
+ case 0x36: return v->subspeed;
+ case 0x37: return v->acceleration;
+ case 0x39: return v->cargo_type;
+ case 0x3A: return v->cargo_cap;
+ case 0x3B: return GB(v->cargo_cap, 8, 8);
+ case 0x3C: return v->cargo_count;
+ case 0x3D: return GB(v->cargo_count, 8, 8);
+ case 0x3E: return v->cargo_source;
+ case 0x3F: return v->cargo_days;
+ case 0x40: return v->age;
+ case 0x41: return GB(v->age, 8, 8);
+ case 0x42: return v->max_age;
+ case 0x43: return GB(v->max_age, 8, 8);
+ case 0x44: return clamp(v->build_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
+ case 0x45: return v->unitnumber;
+ case 0x46: return v->engine_type;
+ case 0x47: return GB(v->engine_type, 8, 8);
+ case 0x48: return v->spritenum;
+ case 0x49: return v->day_counter;
+ case 0x4A: return v->breakdowns_since_last_service;
+ case 0x4B: return v->breakdown_ctr;
+ case 0x4C: return v->breakdown_delay;
+ case 0x4D: return v->breakdown_chance;
+ case 0x4E: return v->reliability;
+ case 0x4F: return GB(v->reliability, 8, 8);
+ case 0x50: return v->reliability_spd_dec;
+ case 0x51: return GB(v->reliability_spd_dec, 8, 8);
+ case 0x52: return v->profit_this_year;
+ case 0x53: return GB(v->profit_this_year, 8, 24);
+ case 0x54: return GB(v->profit_this_year, 16, 16);
+ case 0x55: return GB(v->profit_this_year, 24, 8);
+ case 0x56: return v->profit_last_year;
+ case 0x57: return GB(v->profit_last_year, 8, 24);
+ case 0x58: return GB(v->profit_last_year, 16, 16);
+ case 0x59: return GB(v->profit_last_year, 24, 8);
+ case 0x5A: return v->next == NULL ? INVALID_VEHICLE : v->next->index;
+ case 0x5C: return v->value;
+ case 0x5D: return GB(v->value, 8, 24);
+ case 0x5E: return GB(v->value, 16, 16);
+ case 0x5F: return GB(v->value, 24, 8);
+ case 0x60: return v->string_id;
+ case 0x61: return GB(v->string_id, 8, 8);
+ case 0x72: return v->cargo_subtype;
+ case 0x7A: return v->random_bits;
+ case 0x7B: return v->waiting_triggers;
+ }
+
+ /* Vehicle specific properties */
+ switch (v->type) {
+ case VEH_Train:
+ switch (variable - 0x80) {
+ case 0x62: return v->u.rail.track;
+ case 0x66: return v->u.rail.railtype;
+ case 0x73: return v->u.rail.cached_veh_length;
+ case 0x74: return v->u.rail.cached_power;
+ case 0x75: return GB(v->u.rail.cached_power, 8, 24);
+ case 0x76: return GB(v->u.rail.cached_power, 16, 16);
+ case 0x77: return GB(v->u.rail.cached_power, 24, 8);
+ case 0x7C: return v->first->index;
+ case 0x7D: return GB(v->first->index, 8, 8);
+ case 0x7F: return 0; // Used for vehicle reversing hack in TTDP
+ }
+ break;
+
+ case VEH_Road:
+ switch (variable - 0x80) {
+ case 0x62: return v->u.road.state;
+ case 0x64: return v->u.road.blocked_ctr;
+ case 0x65: return GB(v->u.road.blocked_ctr, 8, 8);
+ case 0x66: return v->u.road.overtaking;
+ case 0x67: return v->u.road.overtaking_ctr;
+ case 0x68: return v->u.road.crashed_ctr;
+ case 0x69: return GB(v->u.road.crashed_ctr, 8, 8);
+ }
+ break;
+
+ case VEH_Aircraft:
+ switch (variable - 0x80) {
+ case 0x62: return MapAircraftMovementState(v); // Current movement state
+ case 0x63: return v->u.air.targetairport; // Airport to which the action refers
+ case 0x66: return MapAircraftMovementAction(v); // Current movement action
+ }
+ break;
+ }
+
+ DEBUG(grf, 1, "Unhandled vehicle property 0x%X, type 0x%X", variable, v->type);
+
+ *available = false;
+ return -1;
+}
+
+
+static const SpriteGroup *VehicleResolveReal(const ResolverObject *object, const SpriteGroup *group)
+{
+ const Vehicle *v = object->u.vehicle.self;
+ uint totalsets;
+ uint set;
+ bool in_motion;
+
+ if (v == NULL) return group->g.real.loading[0];
+
+ if (v->type == VEH_Train) {
+ in_motion = GetFirstVehicleInChain(v)->current_order.type != OT_LOADING;
+ } else {
+ in_motion = v->current_order.type != OT_LOADING;
+ }
+
+ totalsets = in_motion ? group->g.real.num_loaded : group->g.real.num_loading;
+
+ if (v->cargo_count == v->cargo_cap || totalsets == 1) {
+ set = totalsets - 1;
+ } else if (v->cargo_count == 0 || totalsets == 2) {
+ set = 0;
+ } else {
+ set = v->cargo_count * (totalsets - 2) / max(1, v->cargo_cap) + 1;
+ }
+
+ return in_motion ? group->g.real.loaded[set] : group->g.real.loading[set];
+}
+
+
+static inline void NewVehicleResolver(ResolverObject *res, EngineID engine_type, const Vehicle *v)
+{
+ res->GetRandomBits = &VehicleGetRandomBits;
+ res->GetTriggers = &VehicleGetTriggers;
+ res->SetTriggers = &VehicleSetTriggers;
+ res->GetVariable = &VehicleGetVariable;
+ res->ResolveReal = &VehicleResolveReal;
+
+ res->u.vehicle.self = v;
+ res->u.vehicle.parent = (v != NULL && v->type == VEH_Train) ? GetFirstVehicleInChain(v) : v;
+
+ res->u.vehicle.self_type = engine_type;
+
+ res->info_view = false;
+
+ res->callback = 0;
+ res->callback_param1 = 0;
+ res->callback_param2 = 0;
+ res->last_value = 0;
+ res->trigger = 0;
+ res->reseed = 0;
+}
+
+
+/** Retrieve the SpriteGroup for the specified vehicle.
+ * If the vehicle is not specified, the purchase list group for the engine is
+ * chosen. For trains, an additional engine override lookup is performed.
+ * @param engine Engine type of the vehicle.
+ * @param v The vehicle itself.
+ * @returns The selected SpriteGroup for the vehicle.
+ */
+static const SpriteGroup *GetVehicleSpriteGroup(EngineID engine, const Vehicle *v)
+{
+ const SpriteGroup *group;
+ CargoID cargo;
+
+ if (v == NULL) {
+ cargo = GC_PURCHASE;
+ } else {
+ cargo = _global_cargo_id[_opt.landscape][v->cargo_type];
+ assert(cargo != GC_INVALID);
+
+ if (v->type == VEH_Train) {
+ group = GetWagonOverrideSpriteSet(engine, cargo, v->u.rail.first_engine);
+
+ if (group != NULL) return group;
+ }
+ }
+
+ group = engine_custom_sprites[engine][cargo];
+ if (group != NULL) return group;
+
+ /* Fall back to the default set if the selected cargo type is not defined */
+ return engine_custom_sprites[engine][GC_DEFAULT];
+}
+
+
+SpriteID GetCustomEngineSprite(EngineID engine, const Vehicle *v, Direction direction)
+{
+ const SpriteGroup *group;
+ ResolverObject object;
+
+ NewVehicleResolver(&object, engine, v);
+
+ group = Resolve(GetVehicleSpriteGroup(engine, v), &object);
+ if (group == NULL || group->type != SGT_RESULT) return 0;
+
+ return group->g.result.sprite + (direction % group->g.result.num_sprites);
+}
+
+
+SpriteID GetRotorOverrideSprite(EngineID engine, const Vehicle *v, bool info_view)
+{
+ const SpriteGroup *group;
+ ResolverObject object;
+
+ assert(engine >= AIRCRAFT_ENGINES_INDEX);
+ assert(engine < AIRCRAFT_ENGINES_INDEX + NUM_AIRCRAFT_ENGINES);
+
+ /* Only valid for helicopters */
+ assert(!(AircraftVehInfo(engine)->subtype & AIR_CTOL));
+
+ NewVehicleResolver(&object, engine, v);
+
+ object.info_view = info_view;
+
+ group = heli_rotor_custom_sprites[engine - AIRCRAFT_ENGINES_INDEX];
+ group = Resolve(group, &object);
+
+ if (group == NULL || group->type != SGT_RESULT) return 0;
+
+ if (v == NULL) return group->g.result.sprite;
+
+ return group->g.result.sprite + (info_view ? 0 : (v->next->next->u.air.state % group->g.result.num_sprites));
+}
+
+
+/**
+ * Check if a wagon is currently using a wagon override
+ * @param v The wagon to check
+ * @return true if it is using an override, false otherwise
+ */
+bool UsesWagonOverride(const Vehicle* v)
+{
+ assert(v->type == VEH_Train);
+ return GetWagonOverrideSpriteSet(v->engine_type, _global_cargo_id[_opt.landscape][v->cargo_type], v->u.rail.first_engine) != NULL;
+}
+
+/**
+ * Evaluate a newgrf callback for vehicles
+ * @param callback The callback to evalute
+ * @param param1 First parameter of the callback
+ * @param param2 Second parameter of the callback
+ * @param engine Engine type of the vehicle to evaluate the callback for
+ * @param vehicle The vehicle to evaluate the callback for, or NULL if it doesnt exist yet
+ * @return The value the callback returned, or CALLBACK_FAILED if it failed
+ */
+uint16 GetVehicleCallback(uint16 callback, uint32 param1, uint32 param2, EngineID engine, const Vehicle *v)
+{
+ const SpriteGroup *group;
+ ResolverObject object;
+
+ NewVehicleResolver(&object, engine, v);
+
+ object.callback = callback;
+ object.callback_param1 = param1;
+ object.callback_param2 = param2;
+
+ group = Resolve(GetVehicleSpriteGroup(engine, v), &object);
+ if (group == NULL || group->type != SGT_CALLBACK) return CALLBACK_FAILED;
+
+ return group->g.callback.result;
+}
+
+/**
+ * Evaluate a newgrf callback for vehicles with a different vehicle for parent scope.
+ * @param callback The callback to evalute
+ * @param param1 First parameter of the callback
+ * @param param2 Second parameter of the callback
+ * @param engine Engine type of the vehicle to evaluate the callback for
+ * @param v The vehicle to evaluate the callback for, or NULL if it doesnt exist yet
+ * @param parent The vehicle to use for parent scope
+ * @return The value the callback returned, or CALLBACK_FAILED if it failed
+ */
+uint16 GetVehicleCallbackParent(uint16 callback, uint32 param1, uint32 param2, EngineID engine, const Vehicle *v, const Vehicle *parent)
+{
+ const SpriteGroup *group;
+ ResolverObject object;
+
+ NewVehicleResolver(&object, engine, v);
+
+ object.callback = callback;
+ object.callback_param1 = param1;
+ object.callback_param2 = param2;
+
+ object.u.vehicle.parent = parent;
+
+ group = Resolve(GetVehicleSpriteGroup(engine, v), &object);
+ if (group == NULL || group->type != SGT_CALLBACK) return CALLBACK_FAILED;
+
+ return group->g.callback.result;
+}
+
+static void DoTriggerVehicle(Vehicle *v, VehicleTrigger trigger, byte base_random_bits, bool first)
+{
+ const SpriteGroup *group;
+ ResolverObject object;
+ byte new_random_bits;
+
+ /* We can't trigger a non-existent vehicle... */
+ assert(v != NULL);
+
+ NewVehicleResolver(&object, v->engine_type, v);
+
+ object.trigger = trigger;
+
+ group = Resolve(GetVehicleSpriteGroup(v->engine_type, v), &object);
+
+ new_random_bits = Random();
+ v->random_bits &= ~object.reseed;
+ v->random_bits |= (first ? new_random_bits : base_random_bits) & object.reseed;
+
+ switch (trigger) {
+ case VEHICLE_TRIGGER_NEW_CARGO:
+ /* All vehicles in chain get ANY_NEW_CARGO trigger now.
+ * So we call it for the first one and they will recurse. */
+ /* Indexing part of vehicle random bits needs to be
+ * same for all triggered vehicles in the chain (to get
+ * all the random-cargo wagons carry the same cargo,
+ * i.e.), so we give them all the NEW_CARGO triggered
+ * vehicle's portion of random bits. */
+ assert(first);
+ DoTriggerVehicle(GetFirstVehicleInChain(v), VEHICLE_TRIGGER_ANY_NEW_CARGO, new_random_bits, false);
+ break;
+
+ case VEHICLE_TRIGGER_DEPOT:
+ /* We now trigger the next vehicle in chain recursively.
+ * The random bits portions may be different for each
+ * vehicle in chain. */
+ if (v->next != NULL) DoTriggerVehicle(v->next, trigger, 0, true);
+ break;
+
+ case VEHICLE_TRIGGER_EMPTY:
+ /* We now trigger the next vehicle in chain
+ * recursively. The random bits portions must be same
+ * for each vehicle in chain, so we give them all
+ * first chained vehicle's portion of random bits. */
+ if (v->next != NULL) DoTriggerVehicle(v->next, trigger, first ? new_random_bits : base_random_bits, false);
+ break;
+
+ case VEHICLE_TRIGGER_ANY_NEW_CARGO:
+ /* Now pass the trigger recursively to the next vehicle
+ * in chain. */
+ assert(!first);
+ if (v->next != NULL) DoTriggerVehicle(v->next, VEHICLE_TRIGGER_ANY_NEW_CARGO, base_random_bits, false);
+ break;
+ }
+}
+
+void TriggerVehicle(Vehicle *v, VehicleTrigger trigger)
+{
+ if (trigger == VEHICLE_TRIGGER_DEPOT) {
+ // store that the vehicle entered a depot this tick
+ VehicleEnteredDepotThisTick(v);
+ }
+
+ DoTriggerVehicle(v, trigger, 0, true);
+}
+
+StringID _engine_custom_names[TOTAL_NUM_ENGINES];
+
+void SetCustomEngineName(EngineID engine, StringID name)
+{
+ assert(engine < lengthof(_engine_custom_names));
+ _engine_custom_names[engine] = name;
+}
+
+void UnloadCustomEngineNames(void)
+{
+ EngineID i;
+ for (i = 0; i < TOTAL_NUM_ENGINES; i++) {
+ _engine_custom_names[i] = 0;
+ }
+}
+
+StringID GetCustomEngineName(EngineID engine)
+{
+ return _engine_custom_names[engine] == 0 ? _engine_name_strings[engine] : _engine_custom_names[engine];
+}
+
+// Functions for changing the order of vehicle purchase lists
+// This is currently only implemented for rail vehicles.
+static EngineID _engine_list_order[NUM_TRAIN_ENGINES];
+static byte _engine_list_position[NUM_TRAIN_ENGINES];
+
+void ResetEngineListOrder(void)
+{
+ EngineID i;
+
+ for (i = 0; i < NUM_TRAIN_ENGINES; i++) {
+ _engine_list_order[i] = i;
+ _engine_list_position[i] = i;
+ }
+}
+
+/**
+ * Get the EngineID at position pos.
+ * Used when drawing a(n unsorted) list of engines.
+ * @param pos List position/
+ * @return The EngineID at the requested position.
+ */
+EngineID GetRailVehAtPosition(EngineID pos)
+{
+ if (pos < NUM_TRAIN_ENGINES) return _engine_list_order[pos];
+ return pos;
+}
+
+/**
+ * Get the list position of an engine.
+ * Used when sorting a list of engines.
+ * @param engine ID of the engine.
+ * @return The list position of the engine.
+ */
+uint16 ListPositionOfEngine(EngineID engine)
+{
+ if (engine < NUM_TRAIN_ENGINES) return _engine_list_position[engine];
+ return engine;
+}
+
+void AlterRailVehListOrder(EngineID engine, EngineID target)
+{
+ EngineID i;
+ bool moving = false;
+
+ if (engine == target) return;
+
+ // First, remove our ID from the list.
+ for (i = 0; i < NUM_TRAIN_ENGINES - 1; i++) {
+ if (_engine_list_order[i] == engine) moving = true;
+ if (moving) _engine_list_order[i] = _engine_list_order[i + 1];
+ }
+
+ // Now, insert it again, before the target engine.
+ for (i = NUM_TRAIN_ENGINES - 1; i > 0; i--) {
+ _engine_list_order[i] = _engine_list_order[i - 1];
+ if (_engine_list_order[i] == target) {
+ _engine_list_order[i - 1] = engine;
+ break;
+ }
+ }
+
+ // Update the engine list position (a reverse of engine list order)
+ for (i = 0; i < NUM_TRAIN_ENGINES; i++) {
+ _engine_list_position[_engine_list_order[i]] = i;
+ }
+}
diff --git a/src/newgrf_engine.h b/src/newgrf_engine.h
new file mode 100644
index 000000000..bd9ddb230
--- /dev/null
+++ b/src/newgrf_engine.h
@@ -0,0 +1,67 @@
+/* $Id$ */
+
+#ifndef NEWGRF_ENGINE_H
+#define NEWGRF_ENGINE_H
+
+#include "newgrf.h"
+#include "direction.h"
+#include "newgrf_cargo.h"
+
+/** @file newgrf_engine.h
+ */
+
+extern int _traininfo_vehicle_pitch;
+extern int _traininfo_vehicle_width;
+
+extern const CargoID _global_cargo_id[NUM_LANDSCAPE][NUM_CARGO];
+extern const uint32 _landscape_global_cargo_mask[NUM_LANDSCAPE];
+extern const CargoID _local_cargo_id_ctype[NUM_GLOBAL_CID];
+extern const uint32 cargo_classes[16];
+
+void SetWagonOverrideSprites(EngineID engine, CargoID cargo, const struct SpriteGroup *group, byte *train_id, int trains);
+void SetCustomEngineSprites(EngineID engine, byte cargo, const struct SpriteGroup *group);
+void SetRotorOverrideSprites(EngineID engine, const struct SpriteGroup *group);
+SpriteID GetCustomEngineSprite(EngineID engine, const Vehicle* v, Direction direction);
+SpriteID GetRotorOverrideSprite(EngineID engine, const Vehicle* v, bool info_view);
+#define GetCustomRotorSprite(v, i) GetRotorOverrideSprite(v->engine_type, v, i)
+#define GetCustomRotorIcon(et) GetRotorOverrideSprite(et, NULL, true)
+
+/* Forward declaration of GRFFile, to avoid unnecessary inclusion of newgrf.h
+ * elsewhere... */
+struct GRFFile;
+
+void SetEngineGRF(EngineID engine, const struct GRFFile *file);
+const struct GRFFile *GetEngineGRF(EngineID engine);
+uint32 GetEngineGRFID(EngineID engine);
+
+uint16 GetVehicleCallback(uint16 callback, uint32 param1, uint32 param2, EngineID engine, const Vehicle *v);
+uint16 GetVehicleCallbackParent(uint16 callback, uint32 param1, uint32 param2, EngineID engine, const Vehicle *v, const Vehicle *parent);
+bool UsesWagonOverride(const Vehicle *v);
+#define GetCustomVehicleSprite(v, direction) GetCustomEngineSprite(v->engine_type, v, direction)
+#define GetCustomVehicleIcon(et, direction) GetCustomEngineSprite(et, NULL, direction)
+
+typedef enum VehicleTrigger {
+ VEHICLE_TRIGGER_NEW_CARGO = 1,
+ // Externally triggered only for the first vehicle in chain
+ VEHICLE_TRIGGER_DEPOT = 2,
+ // Externally triggered only for the first vehicle in chain, only if whole chain is empty
+ VEHICLE_TRIGGER_EMPTY = 4,
+ // Not triggered externally (called for the whole chain if we got NEW_CARGO)
+ VEHICLE_TRIGGER_ANY_NEW_CARGO = 8,
+} VehicleTrigger;
+void TriggerVehicle(Vehicle *veh, VehicleTrigger trigger);
+
+void SetCustomEngineName(EngineID engine, StringID name);
+StringID GetCustomEngineName(EngineID engine);
+
+void UnloadWagonOverrides(void);
+void UnloadRotorOverrideSprites(void);
+void UnloadCustomEngineSprites(void);
+void UnloadCustomEngineNames(void);
+
+void ResetEngineListOrder(void);
+EngineID GetRailVehAtPosition(EngineID pos);
+uint16 ListPositionOfEngine(EngineID engine);
+void AlterRailVehListOrder(EngineID engine, EngineID target);
+
+#endif /* NEWGRF_ENGINE_H */
diff --git a/src/newgrf_gui.c b/src/newgrf_gui.c
new file mode 100644
index 000000000..4ae734207
--- /dev/null
+++ b/src/newgrf_gui.c
@@ -0,0 +1,534 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "functions.h"
+#include "variables.h"
+#include "gfx.h"
+#include "gui.h"
+#include "window.h"
+#include "table/strings.h"
+#include "table/sprites.h"
+#include "newgrf.h"
+#include "newgrf_config.h"
+
+
+/** Parse an integerlist string and set each found value
+ * @param p the string to be parsed. Each element in the list is seperated by a
+ * comma or a space character
+ * @param items pointer to the integerlist-array that will be filled with values
+ * @param maxitems the maximum number of elements the integerlist-array has
+ * @return returns the number of items found, or -1 on an error */
+static int parse_intlist(const char *p, int *items, int maxitems)
+{
+ int n = 0, v;
+ char *end;
+
+ for (;;) {
+ v = strtol(p, &end, 0);
+ if (p == end || n == maxitems) return -1;
+ p = end;
+ items[n++] = v;
+ if (*p == '\0') break;
+ if (*p != ',' && *p != ' ') return -1;
+ p++;
+ }
+
+ return n;
+}
+
+
+static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint w, bool show_params)
+{
+ char buff[512];
+ char *s;
+ uint i;
+
+ /* Draw filename or not if it is not known (GRF sent over internet) */
+ if (c->filename != NULL) {
+ SetDParamStr(0, c->filename);
+ y += DrawStringMultiLine(x, y, STR_NEWGRF_FILENAME, w);
+ }
+
+ /* Prepare and draw GRF ID */
+ snprintf(buff, lengthof(buff), "%08X", (uint32)BSWAP32(c->grfid));
+ SetDParamStr(0, buff);
+ y += DrawStringMultiLine(x, y, STR_NEWGRF_GRF_ID, w);
+
+ /* Prepare and draw MD5 sum */
+ s = buff;
+ for (i = 0; i < lengthof(c->md5sum); i++) {
+ s += snprintf(s, lastof(buff) - s, "%02X", c->md5sum[i]);
+ }
+ SetDParamStr(0, buff);
+ y += DrawStringMultiLine(x, y, STR_NEWGRF_MD5SUM, w);
+
+ /* Show GRF parameter list */
+ if (show_params) {
+ if (c->num_params > 0) {
+ GRFBuildParamList(buff, c, lastof(buff));
+ SetDParamStr(0, buff);
+ } else {
+ SetDParam(0, STR_01A9_NONE);
+ }
+ y += DrawStringMultiLine(x, y, STR_NEWGRF_PARAMETER, w);
+ }
+
+ /* Show flags */
+ if (HASBIT(c->flags, GCF_NOT_FOUND)) y += DrawStringMultiLine(x, y, STR_NEWGRF_NOT_FOUND, w);
+ if (HASBIT(c->flags, GCF_DISABLED)) y += DrawStringMultiLine(x, y, STR_NEWGRF_DISABLED, w);
+
+ /* Draw GRF info if it exists */
+ if (c->info != NULL && strlen(c->info) != 0) {
+ SetDParamStr(0, c->info);
+ y += DrawStringMultiLine(x, y, STR_02BD, w);
+ } else {
+ y += DrawStringMultiLine(x, y, STR_NEWGRF_NO_INFO, w);
+ }
+}
+
+
+/* Dialogue for adding NewGRF files to the selection */
+typedef struct newgrf_add_d {
+ GRFConfig **list;
+ const GRFConfig *sel;
+} newgrf_add_d;
+
+
+static void NewGRFAddDlgWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ const GRFConfig *c;
+ int y;
+ int n = 0;
+
+ /* Count the number of GRFs */
+ for (c = _all_grfs; c != NULL; c = c->next) n++;
+
+ w->vscroll.cap = (w->widget[3].bottom - w->widget[3].top) / 10;
+ SetVScrollCount(w, n);
+
+ SetWindowWidgetDisabledState(w, 6, WP(w, newgrf_add_d).sel == NULL);
+ DrawWindowWidgets(w);
+
+ GfxFillRect(w->widget[3].left + 1, w->widget[3].top + 1, w->widget[3].right, w->widget[3].bottom, 0xD7);
+
+ n = 0;
+ y = w->widget[3].top + 1;
+
+ for (c = _all_grfs; c != NULL; c = c->next) {
+ if (n >= w->vscroll.pos && n < w->vscroll.pos + w->vscroll.cap) {
+ bool h = c == WP(w, newgrf_add_d).sel;
+ const char *text = (c->name != NULL && strlen(c->name) != 0) ? c->name : c->filename;
+
+ /* Draw selection background */
+ if (h) GfxFillRect(3, y, w->width - 15, y + 9, 156);
+ DoDrawStringTruncated(text, 4, y, h ? 0xC : 0x6, w->width - 18);
+ y += 10;
+ }
+ n++;
+ }
+
+ if (WP(w, newgrf_add_d).sel != NULL) {
+ const Widget *wi = &w->widget[5];
+ ShowNewGRFInfo(WP(w, newgrf_add_d).sel, wi->left + 2, wi->top + 2, wi->right - wi->left - 2, false);
+ }
+ break;
+ }
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 3: {
+ // Get row...
+ const GRFConfig *c;
+ uint i = (e->we.click.pt.y - w->widget[3].top) / 10 + w->vscroll.pos;
+
+ for (c = _all_grfs; c != NULL && i > 0; c = c->next, i--);
+ WP(w, newgrf_add_d).sel = c;
+ SetWindowDirty(w);
+ break;
+ }
+
+ case 6: /* Add selection to list */
+ if (WP(w, newgrf_add_d).sel != NULL) {
+ const GRFConfig *src = WP(w, newgrf_add_d).sel;
+ GRFConfig **list, *c;
+
+ /* Find last entry in the list, checking for duplicate grfid on the way */
+ for (list = WP(w, newgrf_add_d).list; *list != NULL; list = &(*list)->next) {
+ if ((*list)->grfid == src->grfid) {
+ ShowErrorMessage(INVALID_STRING_ID, STR_NEWGRF_DUPLICATE_GRFID, 0, 0);
+ return;
+ }
+ }
+
+ /* Copy GRF details from scanned list */
+ c = calloc(1, sizeof(*c));
+ *c = *src;
+ c->filename = strdup(src->filename);
+ if (src->name != NULL) c->name = strdup(src->name);
+ if (src->info != NULL) c->info = strdup(src->info);
+ c->next = NULL;
+
+ /* Append GRF config to configuration list */
+ *list = c;
+
+ DeleteWindowByClass(WC_SAVELOAD);
+ InvalidateWindowData(WC_GAME_OPTIONS, 0);
+ }
+ break;
+
+ case 7: /* Rescan list */
+ WP(w, newgrf_add_d).sel = NULL;
+ ScanNewGRFFiles();
+ SetWindowDirty(w);
+ break;
+ }
+ break;
+ }
+}
+
+
+static const Widget _newgrf_add_dlg_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW },
+{ WWT_CAPTION, RESIZE_RIGHT, 14, 11, 306, 0, 13, STR_NEWGRF_ADD_CAPTION, STR_018C_WINDOW_TITLE_DRAG_THIS },
+
+/* List of files */
+{ WWT_PANEL, RESIZE_RB, 14, 0, 294, 14, 221, 0x0, STR_NULL },
+{ WWT_INSET, RESIZE_RB, 14, 2, 292, 16, 219, 0x0, STR_NULL },
+{ WWT_SCROLLBAR, RESIZE_LRB, 14, 295, 306, 14, 221, 0x0, STR_NULL },
+
+/* NewGRF file info */
+{ WWT_PANEL, RESIZE_RTB, 14, 0, 306, 222, 324, 0x0, STR_NULL },
+
+{ WWT_PUSHTXTBTN, RESIZE_RTB, 14, 0, 146, 325, 336, STR_NEWGRF_ADD_FILE, STR_NEWGRF_ADD_FILE_TIP },
+{ WWT_PUSHTXTBTN, RESIZE_LRTB, 14, 147, 294, 325, 336, STR_NEWGRF_RESCAN_FILES, STR_NEWGRF_RESCAN_FILES_TIP },
+{ WWT_RESIZEBOX, RESIZE_LRTB, 14, 295, 306, 325, 336, 0x0, STR_RESIZE_BUTTON },
+{ WIDGETS_END },
+};
+
+
+static const WindowDesc _newgrf_add_dlg_desc = {
+ WDP_CENTER, WDP_CENTER, 307, 337,
+ WC_SAVELOAD, 0,
+ WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_STD_BTN | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
+ _newgrf_add_dlg_widgets,
+ NewGRFAddDlgWndProc,
+};
+
+
+/* 'NewGRF Settings' dialogue */
+typedef struct newgrf_d {
+ GRFConfig **orig_list; ///< grf list the window is shown with
+ GRFConfig **list; ///< temporary grf list to which changes are made
+ GRFConfig *sel; ///< selected grf item
+ bool editable; ///< is the window editable
+ bool show_params; ///< are the grf-parameters shown in the info-panel
+ bool execute; ///< on pressing 'apply changes' are grf changes applied immediately, or only list is updated
+} newgrf_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(newgrf_d));
+
+
+enum ShowNewGRFStateWidgets {
+ SNGRFS_ADD = 3,
+ SNGRFS_REMOVE,
+ SNGRFS_MOVE_UP,
+ SNGRFS_MOVE_DOWN,
+ SNGRFS_FILE_LIST = 7,
+ SNGRFS_NEWGRF_INFO = 9,
+ SNGRFS_SET_PARAMETERS,
+ SNGRFS_APPLY_CHANGES,
+};
+
+
+static void SetupNewGRFState(Window *w)
+{
+ bool disable_all = WP(w, newgrf_d).sel == NULL || !WP(w, newgrf_d).editable;
+
+ SetWindowWidgetDisabledState(w, 3, !WP(w, newgrf_d).editable);
+ SetWindowWidgetsDisabledState(w, disable_all,
+ SNGRFS_REMOVE,
+ SNGRFS_MOVE_UP,
+ SNGRFS_MOVE_DOWN,
+ WIDGET_LIST_END
+ );
+ SetWindowWidgetDisabledState(w, SNGRFS_SET_PARAMETERS, !WP(w, newgrf_d).show_params || disable_all);
+
+ if (!disable_all) {
+ /* All widgets are now enabled, so disable widgets we can't use */
+ if (WP(w, newgrf_d).sel == *WP(w, newgrf_d).list) DisableWindowWidget(w, SNGRFS_MOVE_UP);
+ if (WP(w, newgrf_d).sel->next == NULL) DisableWindowWidget(w, SNGRFS_MOVE_DOWN);
+ }
+}
+
+
+static void SetupNewGRFWindow(Window *w)
+{
+ const GRFConfig *c;
+ int i;
+
+ for (c = *WP(w, newgrf_d).list, i = 0; c != NULL; c = c->next, i++);
+
+ w->vscroll.cap = (w->widget[SNGRFS_FILE_LIST].bottom - w->widget[SNGRFS_FILE_LIST].top) / 14 + 1;
+ SetVScrollCount(w, i);
+ SetWindowWidgetDisabledState(w, SNGRFS_APPLY_CHANGES, !WP(w, newgrf_d).editable);
+}
+
+
+/** Callback function for the newgrf 'apply changes' confirmation window
+ * @param yes_clicked boolean value, true when yes was clicked, false otherwise */
+static void NewGRFConfirmationCallback(Window *w, bool confirmed)
+{
+ if (confirmed) {
+ newgrf_d *nd = &WP(w, newgrf_d);
+
+ CopyGRFConfigList(nd->orig_list, *nd->list);
+ ReloadNewGRFData();
+ }
+}
+
+
+static void NewGRFWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ const GRFConfig *c;
+ int i, y;
+
+ SetupNewGRFState(w);
+
+ DrawWindowWidgets(w);
+
+ /* Draw NewGRF list */
+ y = w->widget[SNGRFS_FILE_LIST].top;
+ for (c = *WP(w, newgrf_d).list, i = 0; c != NULL; c = c->next, i++) {
+ if (i >= w->vscroll.pos && i < w->vscroll.pos + w->vscroll.cap) {
+ const char *text = (c->name != NULL && strlen(c->name) != 0) ? c->name : c->filename;
+ PalSpriteID pal;
+
+ /* Pick a colour */
+ if (HASBIT(c->flags, GCF_NOT_FOUND) || HASBIT(c->flags, GCF_DISABLED)) {
+ pal = PALETTE_TO_RED;
+ } else if (HASBIT(c->flags, GCF_STATIC)) {
+ pal = PALETTE_TO_YELLOW;
+ } else if (HASBIT(c->flags, GCF_ACTIVATED)) {
+ pal = PALETTE_TO_GREEN;
+ } else {
+ pal = PALETTE_TO_BLUE;
+ }
+
+ DrawSprite(SPRITE_PALETTE(SPR_SQUARE | pal), 5, y + 2);
+ DoDrawString(text, 25, y + 3, WP(w, newgrf_d).sel == c ? 0xC : 0x10);
+ y += 14;
+ }
+ }
+
+ if (WP(w, newgrf_d).sel != NULL) {
+ /* Draw NewGRF file info */
+ const Widget *wi = &w->widget[SNGRFS_NEWGRF_INFO];
+ ShowNewGRFInfo(WP(w, newgrf_d).sel, wi->left + 2, wi->top + 2, wi->right - wi->left - 2, WP(w, newgrf_d).show_params);
+ }
+
+ break;
+ }
+
+ case WE_INVALIDATE_DATA:
+ SetupNewGRFWindow(w);
+ break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case SNGRFS_ADD: { /* Add GRF */
+ GRFConfig **list = WP(w, newgrf_d).list;
+ Window *w;
+
+ DeleteWindowByClass(WC_SAVELOAD);
+ w = AllocateWindowDesc(&_newgrf_add_dlg_desc);
+ w->resize.step_height = 10;
+
+ WP(w, newgrf_add_d).list = list;
+ break;
+ }
+
+ case SNGRFS_REMOVE: { /* Remove GRF */
+ GRFConfig **pc, *c, *newsel;
+
+ /* Choose the next GRF file to be the selected file */
+ newsel = WP(w, newgrf_d).sel->next;
+
+ for (pc = WP(w, newgrf_d).list; (c = *pc) != NULL; pc = &c->next) {
+ /* If the new selection is empty (i.e. we're deleting the last item
+ * in the list, pick the file just before the selected file */
+ if (newsel == NULL && c->next == WP(w, newgrf_d).sel) newsel = c;
+
+ if (c == WP(w, newgrf_d).sel) {
+ *pc = c->next;
+ free(c);
+ break;
+ }
+ }
+
+ WP(w, newgrf_d).sel = newsel;
+ SetupNewGRFWindow(w);
+ SetWindowDirty(w);
+ break;
+ }
+
+ case SNGRFS_MOVE_UP: { /* Move GRF up */
+ GRFConfig **pc, *c;
+ if (WP(w, newgrf_d).sel == NULL) break;
+
+ for (pc = WP(w, newgrf_d).list; (c = *pc) != NULL; pc = &c->next) {
+ if (c->next == WP(w, newgrf_d).sel) {
+ c->next = WP(w, newgrf_d).sel->next;
+ WP(w, newgrf_d).sel->next = c;
+ *pc = WP(w, newgrf_d).sel;
+ break;
+ }
+ }
+ SetWindowDirty(w);
+ break;
+ }
+
+ case SNGRFS_MOVE_DOWN: { /* Move GRF down */
+ GRFConfig **pc, *c;
+ if (WP(w, newgrf_d).sel == NULL) break;
+
+ for (pc = WP(w, newgrf_d).list; (c = *pc) != NULL; pc = &c->next) {
+ if (c == WP(w, newgrf_d).sel) {
+ *pc = c->next;
+ c->next = c->next->next;
+ (*pc)->next = c;
+ break;
+ }
+ }
+ SetWindowDirty(w);
+ break;
+ }
+
+ case SNGRFS_FILE_LIST: { /* Select a GRF */
+ GRFConfig *c;
+ uint i = (e->we.click.pt.y - w->widget[SNGRFS_FILE_LIST].top) / 14 + w->vscroll.pos;
+
+ for (c = *WP(w, newgrf_d).list; c != NULL && i > 0; c = c->next, i--);
+ WP(w, newgrf_d).sel = c;
+
+ SetWindowDirty(w);
+ break;
+ }
+
+ case SNGRFS_APPLY_CHANGES: /* Apply changes made to GRF list */
+ if (WP(w, newgrf_d).execute) {
+ ShowQuery(
+ STR_POPUP_CAUTION_CAPTION,
+ STR_NEWGRF_CONFIRMATION_TEXT,
+ w,
+ NewGRFConfirmationCallback
+ );
+ } else {
+ CopyGRFConfigList(WP(w, newgrf_d).orig_list, *WP(w, newgrf_d).list);
+ }
+ break;
+
+ case SNGRFS_SET_PARAMETERS: { /* Edit parameters */
+ char buff[512];
+ if (WP(w, newgrf_d).sel == NULL) break;
+
+ GRFBuildParamList(buff, WP(w, newgrf_d).sel, lastof(buff));
+ ShowQueryString(BindCString(buff), STR_NEWGRF_PARAMETER_QUERY, 63, 250, w, CS_ALPHANUMERAL);
+ break;
+ }
+ }
+ break;
+
+ case WE_ON_EDIT_TEXT:
+ if (e->we.edittext.str != NULL) {
+ /* Parse our new "int list" */
+ GRFConfig *c = WP(w, newgrf_d).sel;
+ c->num_params = parse_intlist(e->we.edittext.str, (int*)c->param, lengthof(c->param));
+
+ /* parse_intlist returns -1 on error */
+ if (c->num_params == (byte)-1) c->num_params = 0;
+ }
+ SetWindowDirty(w);
+ break;
+
+ case WE_DESTROY:
+ /* Remove the temporary copy of grf-list used in window */
+ ClearGRFConfigList(WP(w, newgrf_d).list);
+ break;
+
+ case WE_RESIZE:
+ w->vscroll.cap += e->we.sizing.diff.y / 14;
+ w->widget[SNGRFS_FILE_LIST].data = (w->vscroll.cap << 8) + 1;
+ break;
+ }
+}
+
+
+static const Widget _newgrf_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 10, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW },
+{ WWT_CAPTION, RESIZE_RIGHT, 10, 11, 299, 0, 13, STR_NEWGRF_SETTINGS_CAPTION, STR_018C_WINDOW_TITLE_DRAG_THIS },
+
+/* NewGRF file Add, Remove, Move up, Move down */
+{ WWT_PANEL, RESIZE_RIGHT, 10, 0, 299, 14, 29, STR_NULL, STR_NULL },
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 3, 10, 79, 16, 27, STR_NEWGRF_ADD, STR_NEWGRF_ADD_TIP },
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 3, 80, 149, 16, 27, STR_NEWGRF_REMOVE, STR_NEWGRF_REMOVE_TIP },
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 3, 150, 219, 16, 27, STR_NEWGRF_MOVEUP, STR_NEWGRF_MOVEUP_TIP },
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 3, 220, 289, 16, 27, STR_NEWGRF_MOVEDOWN, STR_NEWGRF_MOVEDOWN_TIP },
+
+/* NewGRF file list */
+{ WWT_MATRIX, RESIZE_RB, 10, 0, 287, 30, 99, 0x501, STR_NEWGRF_FILE_TIP },
+{ WWT_SCROLLBAR, RESIZE_LRB, 10, 288, 299, 30, 99, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST },
+
+/* NewGRF file info */
+{ WWT_PANEL, RESIZE_RTB, 10, 0, 299, 100, 212, STR_NULL, STR_NULL },
+
+/* Edit parameter and apply changes button... */
+{ WWT_PUSHTXTBTN, RESIZE_TB, 10, 0, 143, 213, 224, STR_NEWGRF_SET_PARAMETERS, STR_NULL },
+{ WWT_PUSHTXTBTN, RESIZE_RTB, 10, 144, 287, 213, 224, STR_NEWGRF_APPLY_CHANGES, STR_NULL },
+
+{ WWT_RESIZEBOX, RESIZE_LRTB, 10, 288, 299, 213, 224, 0x0, STR_RESIZE_BUTTON },
+
+{ WIDGETS_END },
+};
+
+
+static const WindowDesc _newgrf_desc = {
+ WDP_CENTER, WDP_CENTER, 300, 225,
+ WC_GAME_OPTIONS, 0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
+ _newgrf_widgets,
+ NewGRFWndProc,
+};
+
+
+/** Setup the NewGRF gui
+ * @param editable allow the user to make changes to the grfconfig in the window
+ * @param show_params show information about what parameters are set for the grf files
+ * @param exec_changes if changes are made to the list (editable is true), apply these
+ * changes immediately or only update the list
+ * @param config pointer to a linked-list of grfconfig's that will be shown */
+void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFConfig **config)
+{
+ static GRFConfig *local = NULL;
+ Window *w;
+
+ DeleteWindowByClass(WC_GAME_OPTIONS);
+ w = AllocateWindowDesc(&_newgrf_desc);
+ if (w == NULL) return;
+
+ w->resize.step_height = 14;
+ CopyGRFConfigList(&local, *config);
+
+ /* Clear selections */
+ WP(w, newgrf_d).sel = NULL;
+ WP(w, newgrf_d).list = &local;
+ WP(w, newgrf_d).orig_list = config;
+ WP(w, newgrf_d).editable = editable;
+ WP(w, newgrf_d).execute = exec_changes;
+ WP(w, newgrf_d).show_params = show_params;
+
+ SetupNewGRFWindow(w);
+}
diff --git a/src/newgrf_sound.c b/src/newgrf_sound.c
new file mode 100644
index 000000000..e96934104
--- /dev/null
+++ b/src/newgrf_sound.c
@@ -0,0 +1,68 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "oldpool.h"
+#include "sound.h"
+#include "engine.h"
+#include "vehicle.h"
+#include "newgrf_callbacks.h"
+#include "newgrf_engine.h"
+#include "newgrf_sound.h"
+
+static uint _sound_count = 0;
+STATIC_OLD_POOL(SoundInternal, FileEntry, 3, 1000, NULL, NULL)
+
+
+/* Allocate a new FileEntry */
+FileEntry *AllocateFileEntry(void)
+{
+ if (_sound_count == GetSoundInternalPoolSize()) {
+ if (!AddBlockToPool(&_SoundInternal_pool)) return NULL;
+ }
+
+ return GetSoundInternal(_sound_count++);
+}
+
+
+void InitializeSoundPool(void)
+{
+ CleanPool(&_SoundInternal_pool);
+ _sound_count = 0;
+
+ /* Copy original sound data to the pool */
+ SndCopyToPool();
+}
+
+
+FileEntry *GetSound(uint index)
+{
+ if (index >= _sound_count) return NULL;
+ return GetSoundInternal(index);
+}
+
+
+uint GetNumSounds(void)
+{
+ return _sound_count;
+}
+
+
+bool PlayVehicleSound(const Vehicle *v, VehicleSoundEvent event)
+{
+ const GRFFile *file = GetEngineGRF(v->engine_type);
+ uint16 callback;
+
+ /* If the engine has no GRF ID associated it can't ever play any new sounds */
+ if (file == NULL) return false;
+
+ /* Check that the vehicle type uses the sound effect callback */
+ if (!HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_SOUND_EFFECT)) return false;
+
+ callback = GetVehicleCallback(CBID_VEHICLE_SOUND_EFFECT, event, 0, v->engine_type, v);
+ if (callback == CALLBACK_FAILED) return false;
+ if (callback >= GetNumOriginalSounds()) callback += file->sound_offset - GetNumOriginalSounds();
+
+ if (callback < GetNumSounds()) SndPlayVehicleFx(callback, v);
+ return true;
+}
diff --git a/src/newgrf_sound.h b/src/newgrf_sound.h
new file mode 100644
index 000000000..ec2727fb1
--- /dev/null
+++ b/src/newgrf_sound.h
@@ -0,0 +1,25 @@
+/* $Id$ */
+
+#ifndef NEWGRF_SOUND_H
+#define NEWGRF_SOUND_H
+
+typedef enum VehicleSoundEvents {
+ VSE_START = 1,
+ VSE_TUNNEL = 2,
+ VSE_BREAKDOWN = 3,
+ VSE_RUNNING = 4,
+ VSE_TOUCHDOWN = 5,
+ VSE_TRAIN_EFFECT = 6,
+ VSE_RUNNING_16 = 7,
+ VSE_STOPPED_16 = 8,
+ VSE_LOAD_UNLOAD = 9,
+} VehicleSoundEvent;
+
+
+FileEntry *AllocateFileEntry(void);
+void InitializeSoundPool(void);
+FileEntry *GetSound(uint index);
+uint GetNumSounds(void);
+bool PlayVehicleSound(const Vehicle *v, VehicleSoundEvent event);
+
+#endif /* NEWGRF_SOUND_H */
diff --git a/src/newgrf_spritegroup.c b/src/newgrf_spritegroup.c
new file mode 100644
index 000000000..f97da9c90
--- /dev/null
+++ b/src/newgrf_spritegroup.c
@@ -0,0 +1,233 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "variables.h"
+#include "macros.h"
+#include "oldpool.h"
+#include "newgrf_spritegroup.h"
+#include "date.h"
+
+static void SpriteGroupPoolCleanBlock(uint start_item, uint end_item);
+
+static uint _spritegroup_count = 0;
+STATIC_OLD_POOL(SpriteGroup, SpriteGroup, 9, 250, NULL, SpriteGroupPoolCleanBlock)
+
+static void DestroySpriteGroup(SpriteGroup *group)
+{
+ /* Free dynamically allocated memory */
+ /* XXX Cast away the consts due to MSVC being buggy... */
+ switch (group->type) {
+ case SGT_REAL:
+ free((SpriteGroup**)group->g.real.loaded);
+ free((SpriteGroup**)group->g.real.loading);
+ break;
+
+ case SGT_DETERMINISTIC:
+ free(group->g.determ.adjusts);
+ free(group->g.determ.ranges);
+ break;
+
+ case SGT_RANDOMIZED:
+ free((SpriteGroup**)group->g.random.groups);
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void SpriteGroupPoolCleanBlock(uint start_item, uint end_item)
+{
+ uint i;
+
+ for (i = start_item; i <= end_item; i++) {
+ DestroySpriteGroup(GetSpriteGroup(i));
+ }
+}
+
+
+/* Allocate a new SpriteGroup */
+SpriteGroup *AllocateSpriteGroup(void)
+{
+ /* This is totally different to the other pool allocators, as we never remove an item from the pool. */
+ if (_spritegroup_count == GetSpriteGroupPoolSize()) {
+ if (!AddBlockToPool(&_SpriteGroup_pool)) return NULL;
+ }
+
+ return GetSpriteGroup(_spritegroup_count++);
+}
+
+
+void InitializeSpriteGroupPool(void)
+{
+ CleanPool(&_SpriteGroup_pool);
+
+ _spritegroup_count = 0;
+}
+
+
+static inline uint32 GetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
+{
+ /* Return common variables */
+ switch (variable) {
+ case 0x00: return max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
+ case 0x01: return clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
+ case 0x02: return _cur_month;
+ case 0x03: return _opt.landscape;
+ case 0x09: return _date_fract;
+ case 0x0A: return _tick_counter;
+ case 0x0C: return object->callback;
+ case 0x10: return object->callback_param1;
+ case 0x11: return 0;
+ case 0x18: return object->callback_param2;
+ case 0x1A: return -1;
+ case 0x1B: return GB(_display_opt, 0, 6);
+ case 0x1C: return object->last_value;
+ case 0x20: return _opt.landscape == LT_HILLY ? _opt.snow_line : 0xFF;
+
+ /* Not a common variable, so evalute the feature specific variables */
+ default: return object->GetVariable(object, variable, parameter, available);
+ }
+}
+
+
+/* Evaluate an adjustment for a variable of the given size. This is a bit of
+ * an unwieldy macro, but it saves triplicating the code. */
+#define BUILD_EVAL_ADJUST(size, usize) \
+static inline usize EvalAdjust_ ## size(const DeterministicSpriteGroupAdjust *adjust, usize last_value, int32 value) \
+{ \
+ value >>= adjust->shift_num; \
+ value &= adjust->and_mask; \
+\
+ if (adjust->type != DSGA_TYPE_NONE) value += (size)adjust->add_val; \
+\
+ switch (adjust->type) { \
+ case DSGA_TYPE_DIV: value /= (size)adjust->divmod_val; break; \
+ case DSGA_TYPE_MOD: value %= (usize)adjust->divmod_val; break; \
+ case DSGA_TYPE_NONE: break; \
+ } \
+\
+ /* Get our value to the correct range */ \
+ value = (usize)value; \
+\
+ switch (adjust->operation) { \
+ case DSGA_OP_ADD: return last_value + value; \
+ case DSGA_OP_SUB: return last_value - value; \
+ case DSGA_OP_SMIN: return min(last_value, value); \
+ case DSGA_OP_SMAX: return max(last_value, value); \
+ case DSGA_OP_UMIN: return min((usize)last_value, (usize)value); \
+ case DSGA_OP_UMAX: return max((usize)last_value, (usize)value); \
+ case DSGA_OP_SDIV: return last_value / value; \
+ case DSGA_OP_SMOD: return last_value % value; \
+ case DSGA_OP_UDIV: return (usize)last_value / (usize)value; \
+ case DSGA_OP_UMOD: return (usize)last_value % (usize)value; \
+ case DSGA_OP_MUL: return last_value * value; \
+ case DSGA_OP_AND: return last_value & value; \
+ case DSGA_OP_OR: return last_value | value; \
+ case DSGA_OP_XOR: return last_value ^ value; \
+ default: return value; \
+ } \
+}
+
+
+BUILD_EVAL_ADJUST(int8, uint8)
+BUILD_EVAL_ADJUST(int16, uint16)
+BUILD_EVAL_ADJUST(int32, uint32)
+
+
+static inline const SpriteGroup *ResolveVariable(const SpriteGroup *group, ResolverObject *object)
+{
+ static SpriteGroup nvarzero;
+ int32 last_value = object->last_value;
+ int32 value = -1;
+ uint i;
+
+ object->scope = group->g.determ.var_scope;
+
+ for (i = 0; i < group->g.determ.num_adjusts; i++) {
+ DeterministicSpriteGroupAdjust *adjust = &group->g.determ.adjusts[i];
+
+ /* Try to get the variable. We shall assume it is available, unless told otherwise. */
+ bool available = true;
+ value = GetVariable(object, adjust->variable, adjust->parameter, &available);
+
+ if (!available) {
+ /* Unsupported property: skip further processing and return either
+ * the group from the first range or the default group. */
+ return Resolve(group->g.determ.num_ranges > 0 ? group->g.determ.ranges[0].group : group->g.determ.default_group, object);
+ }
+
+ switch (group->g.determ.size) {
+ case DSG_SIZE_BYTE: value = EvalAdjust_int8(adjust, last_value, value); break;
+ case DSG_SIZE_WORD: value = EvalAdjust_int16(adjust, last_value, value); break;
+ case DSG_SIZE_DWORD: value = EvalAdjust_int32(adjust, last_value, value); break;
+ default: NOT_REACHED(); break;
+ }
+ last_value = value;
+ }
+
+ if (group->g.determ.num_ranges == 0) {
+ /* nvar == 0 is a special case -- we turn our value into a callback result */
+ nvarzero.type = SGT_CALLBACK;
+ nvarzero.g.callback.result = GB(value, 0, 15);
+ return &nvarzero;
+ }
+
+ for (i = 0; i < group->g.determ.num_ranges; i++) {
+ if (group->g.determ.ranges[i].low <= (uint32)value && (uint32)value <= group->g.determ.ranges[i].high) {
+ return Resolve(group->g.determ.ranges[i].group, object);
+ }
+ }
+
+ return Resolve(group->g.determ.default_group, object);
+}
+
+
+static inline const SpriteGroup *ResolveRandom(const SpriteGroup *group, ResolverObject *object)
+{
+ uint32 mask;
+ byte index;
+
+ object->scope = group->g.random.var_scope;
+
+ if (object->trigger != 0) {
+ /* Handle triggers */
+ /* Magic code that may or may not do the right things... */
+ byte waiting_triggers = object->GetTriggers(object);
+ byte match = group->g.random.triggers & (waiting_triggers | object->trigger);
+ bool res;
+
+ res = (group->g.random.cmp_mode == RSG_CMP_ANY) ?
+ (match != 0) : (match == group->g.random.triggers);
+
+ if (res) {
+ waiting_triggers &= ~match;
+ object->reseed |= (group->g.random.num_groups - 1) << group->g.random.lowest_randbit;
+ } else {
+ waiting_triggers |= object->trigger;
+ }
+
+ object->SetTriggers(object, waiting_triggers);
+ }
+
+ mask = (group->g.random.num_groups - 1) << group->g.random.lowest_randbit;
+ index = (object->GetRandomBits(object) & mask) >> group->g.random.lowest_randbit;
+
+ return Resolve(group->g.random.groups[index], object);
+}
+
+
+/* ResolverObject (re)entry point */
+const SpriteGroup *Resolve(const SpriteGroup *group, ResolverObject *object)
+{
+ /* We're called even if there is no group, so quietly return nothing */
+ if (group == NULL) return NULL;
+
+ switch (group->type) {
+ case SGT_REAL: return object->ResolveReal(object, group);
+ case SGT_DETERMINISTIC: return ResolveVariable(group, object);
+ case SGT_RANDOMIZED: return ResolveRandom(group, object);
+ default: return group;
+ }
+}
diff --git a/src/newgrf_spritegroup.h b/src/newgrf_spritegroup.h
new file mode 100644
index 000000000..f77b6009d
--- /dev/null
+++ b/src/newgrf_spritegroup.h
@@ -0,0 +1,196 @@
+/* $Id$ */
+
+#ifndef NEWGRF_SPRITEGROUP_H
+#define NEWGRF_SPRITEGROUP_H
+
+
+typedef struct SpriteGroup SpriteGroup;
+
+
+/* 'Real' sprite groups contain a list of other result or callback sprite
+ * groups. */
+typedef struct RealSpriteGroup {
+ // Loaded = in motion, loading = not moving
+ // Each group contains several spritesets, for various loading stages
+
+ // XXX: For stations the meaning is different - loaded is for stations
+ // with small amount of cargo whilst loading is for stations with a lot
+ // of da stuff.
+
+ byte num_loaded; ///< Number of loaded groups
+ byte num_loading; ///< Number of loading groups
+ const SpriteGroup **loaded; ///< List of loaded groups (can be SpriteIDs or Callback results)
+ const SpriteGroup **loading; ///< List of loading groups (can be SpriteIDs or Callback results)
+} RealSpriteGroup;
+
+/* Shared by deterministic and random groups. */
+typedef enum VarSpriteGroupScopes {
+ VSG_SCOPE_SELF,
+ // Engine of consists for vehicles, city for stations.
+ VSG_SCOPE_PARENT,
+} VarSpriteGroupScope;
+
+typedef enum DeterministicSpriteGroupSizes {
+ DSG_SIZE_BYTE,
+ DSG_SIZE_WORD,
+ DSG_SIZE_DWORD,
+} DeterministicSpriteGroupSize;
+
+typedef enum DeterministicSpriteGroupAdjustTypes {
+ DSGA_TYPE_NONE,
+ DSGA_TYPE_DIV,
+ DSGA_TYPE_MOD,
+} DeterministicSpriteGroupAdjustType;
+
+typedef enum DeterministicSpriteGroupAdjustOperations {
+ DSGA_OP_ADD, // a + b
+ DSGA_OP_SUB, // a - b
+ DSGA_OP_SMIN, // (signed) min(a, b)
+ DSGA_OP_SMAX, // (signed) max(a, b)
+ DSGA_OP_UMIN, // (unsigned) min(a, b)
+ DSGA_OP_UMAX, // (unsigned) max(a, b)
+ DSGA_OP_SDIV, // (signed) a / b
+ DSGA_OP_SMOD, // (signed) a % b
+ DSGA_OP_UDIV, // (unsigned) a / b
+ DSGA_OP_UMOD, // (unsigned) a & b
+ DSGA_OP_MUL, // a * b
+ DSGA_OP_AND, // a & b
+ DSGA_OP_OR, // a | b
+ DSGA_OP_XOR, // a ^ b
+} DeterministicSpriteGroupAdjustOperation;
+
+
+typedef struct DeterministicSpriteGroupAdjust {
+ DeterministicSpriteGroupAdjustOperation operation;
+ DeterministicSpriteGroupAdjustType type;
+ byte variable;
+ byte parameter; ///< Used for variables between 0x60 and 0x7F inclusive.
+ byte shift_num;
+ uint32 and_mask;
+ uint32 add_val;
+ uint32 divmod_val;
+} DeterministicSpriteGroupAdjust;
+
+
+typedef struct DeterministicSpriteGroupRange {
+ const SpriteGroup *group;
+ uint32 low;
+ uint32 high;
+} DeterministicSpriteGroupRange;
+
+
+typedef struct DeterministicSpriteGroup {
+ VarSpriteGroupScope var_scope;
+ DeterministicSpriteGroupSize size;
+ byte num_adjusts;
+ byte num_ranges;
+ DeterministicSpriteGroupAdjust *adjusts;
+ DeterministicSpriteGroupRange *ranges; // Dynamically allocated
+
+ // Dynamically allocated, this is the sole owner
+ const SpriteGroup *default_group;
+} DeterministicSpriteGroup;
+
+typedef enum RandomizedSpriteGroupCompareModes {
+ RSG_CMP_ANY,
+ RSG_CMP_ALL,
+} RandomizedSpriteGroupCompareMode;
+
+typedef struct RandomizedSpriteGroup {
+ // Take this object:
+ VarSpriteGroupScope var_scope;
+
+ // Check for these triggers:
+ RandomizedSpriteGroupCompareMode cmp_mode;
+ byte triggers;
+
+ // Look for this in the per-object randomized bitmask:
+ byte lowest_randbit;
+ byte num_groups; // must be power of 2
+
+ // Take the group with appropriate index:
+ const SpriteGroup **groups;
+} RandomizedSpriteGroup;
+
+
+/* This contains a callback result. A failed callback has a value of
+ * CALLBACK_FAILED */
+typedef struct CallbackResultSpriteGroup {
+ uint16 result;
+} CallbackResultSpriteGroup;
+
+
+/* A result sprite group returns the first SpriteID and the number of
+ * sprites in the set */
+typedef struct ResultSpriteGroup {
+ SpriteID sprite;
+ byte num_sprites;
+} ResultSpriteGroup;
+
+/* List of different sprite group types */
+typedef enum SpriteGroupType {
+ SGT_INVALID,
+ SGT_REAL,
+ SGT_DETERMINISTIC,
+ SGT_RANDOMIZED,
+ SGT_CALLBACK,
+ SGT_RESULT,
+} SpriteGroupType;
+
+/* Common wrapper for all the different sprite group types */
+struct SpriteGroup {
+ SpriteGroupType type;
+
+ union {
+ RealSpriteGroup real;
+ DeterministicSpriteGroup determ;
+ RandomizedSpriteGroup random;
+ CallbackResultSpriteGroup callback;
+ ResultSpriteGroup result;
+ } g;
+};
+
+
+SpriteGroup *AllocateSpriteGroup(void);
+void InitializeSpriteGroupPool(void);
+
+
+typedef struct ResolverObject {
+ uint16 callback;
+ uint32 callback_param1;
+ uint32 callback_param2;
+
+ byte trigger;
+ uint32 last_value;
+ uint32 reseed;
+ VarSpriteGroupScope scope;
+
+ bool info_view; ///< Indicates if the item is being drawn in an info window
+
+ union {
+ struct {
+ const struct Vehicle *self;
+ const struct Vehicle *parent;
+ EngineID self_type;
+ } vehicle;
+ struct {
+ TileIndex tile;
+ const struct Station *st;
+ const struct StationSpec *statspec;
+ CargoID cargo_type;
+ } station;
+ } u;
+
+ uint32 (*GetRandomBits)(const struct ResolverObject*);
+ uint32 (*GetTriggers)(const struct ResolverObject*);
+ void (*SetTriggers)(const struct ResolverObject*, int);
+ uint32 (*GetVariable)(const struct ResolverObject*, byte, byte, bool*);
+ const SpriteGroup *(*ResolveReal)(const struct ResolverObject*, const SpriteGroup*);
+} ResolverObject;
+
+
+/* Base sprite group resolver */
+const SpriteGroup *Resolve(const SpriteGroup *group, ResolverObject *object);
+
+
+#endif /* NEWGRF_SPRITEGROUP_H */
diff --git a/src/newgrf_station.c b/src/newgrf_station.c
new file mode 100644
index 000000000..f36769a41
--- /dev/null
+++ b/src/newgrf_station.c
@@ -0,0 +1,766 @@
+/* $Id$ */
+
+/** @file newgrf_station.c Functions for dealing with station classes and custom stations. */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "variables.h"
+#include "functions.h"
+#include "debug.h"
+#include "sprite.h"
+#include "table/sprites.h"
+#include "table/strings.h"
+#include "station.h"
+#include "station_map.h"
+#include "newgrf.h"
+#include "newgrf_callbacks.h"
+#include "newgrf_station.h"
+#include "newgrf_spritegroup.h"
+#include "date.h"
+
+static StationClass station_classes[STAT_CLASS_MAX];
+
+enum {
+ MAX_SPECLIST = 255,
+};
+
+/**
+ * Reset station classes to their default state.
+ * This includes initialising the Default and Waypoint classes with an empty
+ * entry, for standard stations and waypoints.
+ */
+void ResetStationClasses(void)
+{
+ StationClassID i;
+ for (i = 0; i < STAT_CLASS_MAX; i++) {
+ station_classes[i].id = 0;
+ station_classes[i].name = STR_EMPTY;
+ station_classes[i].stations = 0;
+
+ free(station_classes[i].spec);
+ station_classes[i].spec = NULL;
+ }
+
+ // Set up initial data
+ station_classes[0].id = 'DFLT';
+ station_classes[0].name = STR_STAT_CLASS_DFLT;
+ station_classes[0].stations = 1;
+ station_classes[0].spec = malloc(sizeof(*station_classes[0].spec));
+ station_classes[0].spec[0] = NULL;
+
+ station_classes[1].id = 'WAYP';
+ station_classes[1].name = STR_STAT_CLASS_WAYP;
+ station_classes[1].stations = 1;
+ station_classes[1].spec = malloc(sizeof(*station_classes[1].spec));
+ station_classes[1].spec[0] = NULL;
+}
+
+/**
+ * Allocate a station class for the given class id.
+ * @param classid A 32 bit value identifying the class.
+ * @return Index into station_classes of allocated class.
+ */
+StationClassID AllocateStationClass(uint32 class)
+{
+ StationClassID i;
+
+ for (i = 0; i < STAT_CLASS_MAX; i++) {
+ if (station_classes[i].id == class) {
+ // ClassID is already allocated, so reuse it.
+ return i;
+ } else if (station_classes[i].id == 0) {
+ // This class is empty, so allocate it to the ClassID.
+ station_classes[i].id = class;
+ return i;
+ }
+ }
+
+ grfmsg(2, "StationClassAllocate: already allocated %d classes, using default", STAT_CLASS_MAX);
+ return STAT_CLASS_DFLT;
+}
+
+/** Set the name of a custom station class */
+void SetStationClassName(StationClassID sclass, StringID name)
+{
+ assert(sclass < STAT_CLASS_MAX);
+ station_classes[sclass].name = name;
+}
+
+/** Retrieve the name of a custom station class */
+StringID GetStationClassName(StationClassID sclass)
+{
+ assert(sclass < STAT_CLASS_MAX);
+ return station_classes[sclass].name;
+}
+
+/** Build a list of station class name StringIDs to use in a dropdown list
+ * @return Pointer to a (static) array of StringIDs
+ */
+StringID *BuildStationClassDropdown(void)
+{
+ /* Allow room for all station classes, plus a terminator entry */
+ static StringID names[STAT_CLASS_MAX + 1];
+ uint i;
+
+ /* Add each name */
+ for (i = 0; i < STAT_CLASS_MAX && station_classes[i].id != 0; i++) {
+ names[i] = station_classes[i].name;
+ }
+ /* Terminate the list */
+ names[i] = INVALID_STRING_ID;
+
+ return names;
+}
+
+/**
+ * Get the number of station classes in use.
+ * @return Number of station classes.
+ */
+uint GetNumStationClasses(void)
+{
+ uint i;
+ for (i = 0; i < STAT_CLASS_MAX && station_classes[i].id != 0; i++);
+ return i;
+}
+
+/**
+ * Return the number of stations for the given station class.
+ * @param sclass Index of the station class.
+ * @return Number of stations in the class.
+ */
+uint GetNumCustomStations(StationClassID sclass)
+{
+ assert(sclass < STAT_CLASS_MAX);
+ return station_classes[sclass].stations;
+}
+
+/**
+ * Tie a station spec to its station class.
+ * @param spec The station spec.
+ */
+void SetCustomStationSpec(StationSpec *statspec)
+{
+ StationClass *station_class;
+ int i;
+
+ /* If the station has already been allocated, don't reallocate it. */
+ if (statspec->allocated) return;
+
+ assert(statspec->sclass < STAT_CLASS_MAX);
+ station_class = &station_classes[statspec->sclass];
+
+ i = station_class->stations++;
+ station_class->spec = realloc(station_class->spec, station_class->stations * sizeof(*station_class->spec));
+
+ station_class->spec[i] = statspec;
+ statspec->allocated = true;
+}
+
+/**
+ * Retrieve a station spec from a class.
+ * @param sclass Index of the station class.
+ * @param station The station index with the class.
+ * @return The station spec.
+ */
+const StationSpec *GetCustomStationSpec(StationClassID sclass, uint station)
+{
+ assert(sclass < STAT_CLASS_MAX);
+ if (station < station_classes[sclass].stations)
+ return station_classes[sclass].spec[station];
+
+ // If the custom station isn't defined any more, then the GRF file
+ // probably was not loaded.
+ return NULL;
+}
+
+
+const StationSpec *GetCustomStationSpecByGrf(uint32 grfid, byte localidx)
+{
+ StationClassID i;
+ uint j;
+
+ for (i = STAT_CLASS_DFLT; i < STAT_CLASS_MAX; i++) {
+ for (j = 0; j < station_classes[i].stations; j++) {
+ const StationSpec *statspec = station_classes[i].spec[j];
+ if (statspec == NULL) continue;
+ if (statspec->grfid == grfid && statspec->localidx == localidx) return statspec;
+ }
+ }
+
+ return NULL;
+}
+
+
+/* Evaluate a tile's position within a station, and return the result a bitstuffed format.
+ * if not centred: .TNLcCpP, if centred: .TNL..CP
+ * T = Tile layout number (GetStationGfx), N = Number of platforms, L = Length of platforms
+ * C = Current platform number from start, c = from end
+ * P = Position along platform from start, p = from end
+ * if centred, C/P start from the centre and c/p are not available.
+ */
+uint32 GetPlatformInfo(Axis axis, byte tile, int platforms, int length, int x, int y, bool centred)
+{
+ uint32 retval = 0;
+
+ if (axis == AXIS_X) {
+ intswap(platforms, length);
+ intswap(x, y);
+ }
+
+ /* Limit our sizes to 4 bits */
+ platforms = min(15, platforms);
+ length = min(15, length);
+ x = min(15, x);
+ y = min(15, y);
+ if (centred) {
+ x -= platforms / 2;
+ y -= length / 2;
+ SB(retval, 0, 4, y & 0xF);
+ SB(retval, 4, 4, x & 0xF);
+ } else {
+ SB(retval, 0, 4, y);
+ SB(retval, 4, 4, length - y - 1);
+ SB(retval, 8, 4, x);
+ SB(retval, 12, 4, platforms - x - 1);
+ }
+ SB(retval, 16, 4, length);
+ SB(retval, 20, 4, platforms);
+ SB(retval, 24, 4, tile);
+
+ return retval;
+}
+
+
+/* Find the end of a railway station, from the tile, in the direction of delta.
+ * If check_type is set, we stop if the custom station type changes.
+ * If check_axis is set, we stop if the station direction changes.
+ */
+static TileIndex FindRailStationEnd(TileIndex tile, TileIndexDiff delta, bool check_type, bool check_axis)
+{
+ bool waypoint;
+ byte orig_type = 0;
+ Axis orig_axis = AXIS_X;
+
+ waypoint = IsTileType(tile, MP_RAILWAY);
+
+ if (waypoint) {
+ if (check_axis) orig_axis = GetWaypointAxis(tile);
+ } else {
+ if (check_type) orig_type = GetCustomStationSpecIndex(tile);
+ if (check_axis) orig_axis = GetRailStationAxis(tile);
+ }
+
+ while (true) {
+ TileIndex new_tile = TILE_ADD(tile, delta);
+
+ if (waypoint) {
+ if (!IsTileType(new_tile, MP_RAILWAY)) break;
+ if (!IsRailWaypoint(new_tile)) break;
+ if (check_axis && GetWaypointAxis(new_tile) != orig_axis) break;
+ } else {
+ if (!IsRailwayStationTile(new_tile)) break;
+ if (check_type && GetCustomStationSpecIndex(new_tile) != orig_type) break;
+ if (check_axis && GetRailStationAxis(new_tile) != orig_axis) break;
+ }
+
+ tile = new_tile;
+ }
+ return tile;
+}
+
+
+static uint32 GetPlatformInfoHelper(TileIndex tile, bool check_type, bool check_axis, bool centred)
+{
+ int tx = TileX(tile);
+ int ty = TileY(tile);
+ int sx = TileX(FindRailStationEnd(tile, TileDiffXY(-1, 0), check_type, check_axis));
+ int sy = TileY(FindRailStationEnd(tile, TileDiffXY( 0, -1), check_type, check_axis));
+ int ex = TileX(FindRailStationEnd(tile, TileDiffXY( 1, 0), check_type, check_axis)) + 1;
+ int ey = TileY(FindRailStationEnd(tile, TileDiffXY( 0, 1), check_type, check_axis)) + 1;
+ Axis axis = IsTileType(tile, MP_RAILWAY) ? GetWaypointAxis(tile) : GetRailStationAxis(tile);
+
+ tx -= sx; ex -= sx;
+ ty -= sy; ey -= sy;
+
+ return GetPlatformInfo(axis, IsTileType(tile, MP_RAILWAY) ? 2 : GetStationGfx(tile), ex, ey, tx, ty, centred);
+}
+
+
+static uint32 GetRailContinuationInfo(TileIndex tile)
+{
+ /* Tile offsets and exit dirs for X axis */
+ static Direction x_dir[8] = { DIR_SW, DIR_NE, DIR_SE, DIR_NW, DIR_S, DIR_E, DIR_W, DIR_N };
+ static DiagDirection x_exits[8] = { DIAGDIR_SW, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NE, DIAGDIR_SW, DIAGDIR_NE };
+
+ /* Tile offsets and exit dirs for Y axis */
+ static Direction y_dir[8] = { DIR_SE, DIR_NW, DIR_SW, DIR_NE, DIR_S, DIR_W, DIR_E, DIR_N };
+ static DiagDirection y_exits[8] = { DIAGDIR_SE, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NW, DIAGDIR_SE, DIAGDIR_NW };
+
+ Axis axis = IsTileType(tile, MP_RAILWAY) ? GetWaypointAxis(tile) : GetRailStationAxis(tile);
+
+ /* Choose appropriate lookup table to use */
+ Direction *dir = axis == AXIS_X ? x_dir : y_dir;
+ DiagDirection *diagdir = axis == AXIS_X ? x_exits : y_exits;
+
+ uint32 res = 0;
+ uint i;
+
+ for (i = 0; i < lengthof(x_dir); i++, dir++, diagdir++) {
+ uint32 ts = GetTileTrackStatus(tile + TileOffsByDir(*dir), TRANSPORT_RAIL);
+ if (ts != 0) {
+ /* If there is any track on the tile, set the bit in the second byte */
+ SETBIT(res, i + 8);
+
+ /* If any track reaches our exit direction, set the bit in the lower byte */
+ if (ts & DiagdirReachesTracks(*diagdir)) SETBIT(res, i);
+ }
+ }
+
+ return res;
+}
+
+
+/* Station Resolver Functions */
+static uint32 StationGetRandomBits(const ResolverObject *object)
+{
+ const Station *st = object->u.station.st;
+ const TileIndex tile = object->u.station.tile;
+ return (st == NULL ? 0 : st->random_bits) | (tile == INVALID_TILE ? 0 : GetStationTileRandomBits(tile) << 16);
+}
+
+
+static uint32 StationGetTriggers(const ResolverObject *object)
+{
+ const Station *st = object->u.station.st;
+ return st == NULL ? 0 : st->waiting_triggers;
+}
+
+
+static void StationSetTriggers(const ResolverObject *object, int triggers)
+{
+ Station *st = (Station*)object->u.station.st;
+ assert(st != NULL);
+ st->waiting_triggers = triggers;
+}
+
+
+static uint32 StationGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
+{
+ const Station *st = object->u.station.st;
+ TileIndex tile = object->u.station.tile;
+
+ if (st == NULL) {
+ /* Station does not exist, so we're in a purchase list */
+ switch (variable) {
+ case 0x40:
+ case 0x41:
+ case 0x46:
+ case 0x47:
+ case 0x49: return 0x2110000; /* Platforms, tracks & position */
+ case 0x42: return 0; /* Rail type (XXX Get current type from GUI?) */
+ case 0x43: return _current_player; /* Station owner */
+ case 0x44: return 2; /* PBS status */
+ case 0xFA: return max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0); /* Build date */
+ }
+
+ *available = false;
+ return -1;
+ }
+
+ switch (variable) {
+ /* Calculated station variables */
+ case 0x40: return GetPlatformInfoHelper(tile, false, false, false);
+ case 0x41: return GetPlatformInfoHelper(tile, true, false, false);
+ case 0x42: /* Terrain and rail type */
+ return ((_opt.landscape == LT_HILLY && GetTileZ(tile) > _opt.snow_line) ? 4 : 0) |
+ (GetRailType(tile) << 8);
+ case 0x43: return st->owner; /* Station owner */
+ case 0x44: return 2; /* PBS status */
+ case 0x45: return GetRailContinuationInfo(tile);
+ case 0x46: return GetPlatformInfoHelper(tile, false, false, true);
+ case 0x47: return GetPlatformInfoHelper(tile, true, false, true);
+ case 0x48: { /* Accepted cargo types */
+ CargoID cargo_type;
+ uint32 value = 0;
+
+ for (cargo_type = 0; cargo_type < NUM_CARGO; cargo_type++) {
+ if (HASBIT(st->goods[cargo_type].waiting_acceptance, 15)) SETBIT(value, cargo_type);
+ }
+ return value;
+ }
+ case 0x49: return GetPlatformInfoHelper(tile, false, true, false);
+
+ /* Variables which use the parameter */
+ case 0x60: return GB(st->goods[parameter].waiting_acceptance, 0, 12);
+ case 0x61: return st->goods[parameter].days_since_pickup;
+ case 0x62: return st->goods[parameter].rating;
+ case 0x63: return st->goods[parameter].enroute_time;
+ case 0x64: return st->goods[parameter].last_speed | (st->goods[parameter].last_age << 8);
+ case 0x65: return GB(st->goods[parameter].waiting_acceptance, 12, 4);
+
+ /* General station properties */
+ case 0x82: return 50;
+ case 0x84: return st->string_id;
+ case 0x86: return 0;
+ case 0x8A: return st->had_vehicle_of_type;
+ case 0xF0: return st->facilities;
+ case 0xF1: return st->airport_type;
+ case 0xF2: return st->truck_stops->status;
+ case 0xF3: return st->bus_stops->status;
+ case 0xF6: return st->airport_flags;
+ case 0xF7: return GB(st->airport_flags, 8, 8);
+ case 0xFA: return max(st->build_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
+ }
+
+ /* Handle cargo variables (deprecated) */
+ if (variable >= 0x8C && variable <= 0xEC) {
+ const GoodsEntry *g = &st->goods[GB(variable - 0x8C, 3, 4)];
+ switch (GB(variable - 0x8C, 0, 3)) {
+ case 0: return g->waiting_acceptance;
+ case 1: return GB(g->waiting_acceptance, 8, 8);
+ case 2: return g->days_since_pickup;
+ case 3: return g->rating;
+ case 4: return g->enroute_from;
+ case 5: return g->enroute_time;
+ case 6: return g->last_speed;
+ case 7: return g->last_age;
+ }
+ }
+
+ DEBUG(grf, 1, "Unhandled station property 0x%X", variable);
+
+ *available = false;
+ return -1;
+}
+
+
+static const SpriteGroup *StationResolveReal(const ResolverObject *object, const SpriteGroup *group)
+{
+ const Station *st = object->u.station.st;
+ const StationSpec *statspec = object->u.station.statspec;
+ uint set;
+
+ uint cargo = 0;
+ CargoID cargo_type = object->u.station.cargo_type;
+
+ if (st == NULL || statspec->sclass == STAT_CLASS_WAYP) {
+ return group->g.real.loading[0];
+ }
+
+ switch (cargo_type) {
+ case GC_INVALID:
+ case GC_DEFAULT_NA:
+ case GC_PURCHASE:
+ cargo = 0;
+ break;
+
+ case GC_DEFAULT:
+ for (cargo_type = 0; cargo_type < NUM_CARGO; cargo_type++) {
+ cargo += GB(st->goods[cargo_type].waiting_acceptance, 0, 12);
+ }
+ break;
+
+ default:
+ cargo = GB(st->goods[_local_cargo_id_ctype[cargo_type]].waiting_acceptance, 0, 12);
+ break;
+ }
+
+ if (HASBIT(statspec->flags, 1)) cargo /= (st->trainst_w + st->trainst_h);
+ cargo = min(0xfff, cargo);
+
+ if (cargo > statspec->cargo_threshold) {
+ if (group->g.real.num_loading > 0) {
+ set = ((cargo - statspec->cargo_threshold) * group->g.real.num_loading) / (4096 - statspec->cargo_threshold);
+ return group->g.real.loading[set];
+ }
+ } else {
+ if (group->g.real.num_loaded > 0) {
+ set = (cargo * group->g.real.num_loaded) / (statspec->cargo_threshold + 1);
+ return group->g.real.loaded[set];
+ }
+ }
+
+ return group->g.real.loading[0];
+}
+
+
+static void NewStationResolver(ResolverObject *res, const StationSpec *statspec, const Station *st, TileIndex tile)
+{
+ res->GetRandomBits = StationGetRandomBits;
+ res->GetTriggers = StationGetTriggers;
+ res->SetTriggers = StationSetTriggers;
+ res->GetVariable = StationGetVariable;
+ res->ResolveReal = StationResolveReal;
+
+ res->u.station.st = st;
+ res->u.station.statspec = statspec;
+ res->u.station.tile = tile;
+
+ res->callback = 0;
+ res->callback_param1 = 0;
+ res->callback_param2 = 0;
+ res->last_value = 0;
+ res->trigger = 0;
+ res->reseed = 0;
+}
+
+static const SpriteGroup *ResolveStation(const StationSpec *statspec, const Station *st, ResolverObject *object)
+{
+ const SpriteGroup *group;
+ CargoID ctype = GC_DEFAULT_NA;
+
+ if (st == NULL) {
+ /* No station, so we are in a purchase list */
+ ctype = GC_PURCHASE;
+ } else {
+ CargoID cargo;
+
+ /* Pick the first cargo that we have waiting */
+ for (cargo = 0; cargo < NUM_GLOBAL_CID; cargo++) {
+ CargoID lcid = _local_cargo_id_ctype[cargo];
+ if (lcid != CT_INVALID && statspec->spritegroup[cargo] != NULL && GB(st->goods[lcid].waiting_acceptance, 0, 12) != 0) {
+ ctype = cargo;
+ break;
+ }
+ }
+ }
+
+ group = statspec->spritegroup[ctype];
+ if (group == NULL) {
+ ctype = GC_DEFAULT;
+ group = statspec->spritegroup[ctype];
+ }
+
+ if (group == NULL) return NULL;
+
+ /* Remember the cargo type we've picked */
+ object->u.station.cargo_type = ctype;
+
+ return Resolve(group, object);
+}
+
+SpriteID GetCustomStationRelocation(const StationSpec *statspec, const Station *st, TileIndex tile)
+{
+ const SpriteGroup *group;
+ ResolverObject object;
+
+ NewStationResolver(&object, statspec, st, tile);
+
+ group = ResolveStation(statspec, st, &object);
+ if (group == NULL || group->type != SGT_RESULT) return 0;
+ return group->g.result.sprite - 0x42D;
+}
+
+
+SpriteID GetCustomStationGroundRelocation(const StationSpec *statspec, const Station *st, TileIndex tile)
+{
+ const SpriteGroup *group;
+ ResolverObject object;
+
+ NewStationResolver(&object, statspec, st, tile);
+ object.callback_param1 = 1; /* Indicate we are resolving the ground sprite */
+
+ group = ResolveStation(statspec, st, &object);
+ if (group == NULL || group->type != SGT_RESULT) return 0;
+ return group->g.result.sprite - 0x42D;
+}
+
+
+uint16 GetStationCallback(uint16 callback, uint32 param1, uint32 param2, const StationSpec *statspec, const Station *st, TileIndex tile)
+{
+ const SpriteGroup *group;
+ ResolverObject object;
+
+ NewStationResolver(&object, statspec, st, tile);
+
+ object.callback = callback;
+ object.callback_param1 = param1;
+ object.callback_param2 = param2;
+
+ group = ResolveStation(statspec, st, &object);
+ if (group == NULL || group->type != SGT_CALLBACK) return CALLBACK_FAILED;
+ return group->g.callback.result;
+}
+
+
+/**
+ * Allocate a StationSpec to a Station. This is called once per build operation.
+ * @param spec StationSpec to allocate.
+ * @param st Station to allocate it to.
+ * @param exec Whether to actually allocate the spec.
+ * @return Index within the Station's spec list, or -1 if the allocation failed.
+ */
+int AllocateSpecToStation(const StationSpec *statspec, Station *st, bool exec)
+{
+ uint i;
+
+ if (statspec == NULL) return 0;
+
+ /* Check if this spec has already been allocated */
+ for (i = 1; i < st->num_specs && i < MAX_SPECLIST; i++) {
+ if (st->speclist[i].spec == statspec) return i;
+ }
+
+ for (i = 1; i < st->num_specs && i < MAX_SPECLIST; i++) {
+ if (st->speclist[i].spec == NULL && st->speclist[i].grfid == 0) break;
+ }
+
+ if (i == MAX_SPECLIST) return -1;
+
+ if (exec) {
+ if (i >= st->num_specs) {
+ st->num_specs = i + 1;
+ st->speclist = realloc(st->speclist, st->num_specs * sizeof(*st->speclist));
+
+ if (st->num_specs == 2) {
+ /* Initial allocation */
+ st->speclist[0].spec = NULL;
+ st->speclist[0].grfid = 0;
+ st->speclist[0].localidx = 0;
+ }
+ }
+
+ st->speclist[i].spec = statspec;
+ st->speclist[i].grfid = statspec->grfid;
+ st->speclist[i].localidx = statspec->localidx;
+ }
+
+ return i;
+}
+
+
+/** Deallocate a StationSpec from a Station. Called when removing a single station tile.
+ * @param st Station to work with.
+ * @param specindex Index of the custom station within the Station's spec list.
+ * @return Indicates whether the StationSpec was deallocated.
+ */
+void DeallocateSpecFromStation(Station* st, byte specindex)
+{
+ /* specindex of 0 (default) is never freeable */
+ if (specindex == 0) return;
+
+ /* Check all tiles over the station to check if the specindex is still in use */
+ BEGIN_TILE_LOOP(tile, st->trainst_w, st->trainst_h, st->train_tile) {
+ if (IsTileType(tile, MP_STATION) && GetStationIndex(tile) == st->index && IsRailwayStation(tile) && GetCustomStationSpecIndex(tile) == specindex) {
+ return;
+ }
+ } END_TILE_LOOP(tile, st->trainst_w, st->trainst_h, st->train_tile)
+
+ /* This specindex is no longer in use, so deallocate it */
+ st->speclist[specindex].spec = NULL;
+ st->speclist[specindex].grfid = 0;
+ st->speclist[specindex].localidx = 0;
+
+ /* If this was the highest spec index, reallocate */
+ if (specindex == st->num_specs - 1) {
+ for (; st->speclist[st->num_specs - 1].grfid == 0 && st->num_specs > 1; st->num_specs--);
+
+ if (st->num_specs > 1) {
+ st->speclist = realloc(st->speclist, st->num_specs * sizeof(*st->speclist));
+ } else {
+ free(st->speclist);
+ st->num_specs = 0;
+ st->speclist = NULL;
+ }
+ }
+}
+
+/** Draw representation of a station tile for GUI purposes.
+ * @param x, y Position of image.
+ * @param dir Direction.
+ * @param railtype Rail type.
+ * @param sclass, station Type of station.
+ * @return True if the tile was drawn (allows for fallback to default graphic)
+ */
+bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID sclass, uint station)
+{
+ const StationSpec *statspec;
+ const DrawTileSprites *sprites;
+ const DrawTileSeqStruct *seq;
+ const RailtypeInfo *rti = GetRailTypeInfo(railtype);
+ SpriteID relocation;
+ PalSpriteID image;
+ PalSpriteID colourmod = SPRITE_PALETTE(PLAYER_SPRITE_COLOR(_local_player));
+ uint tile = 2;
+
+ statspec = GetCustomStationSpec(sclass, station);
+ if (statspec == NULL) return false;
+
+ relocation = GetCustomStationRelocation(statspec, NULL, INVALID_TILE);
+
+ if (HASBIT(statspec->callbackmask, CBM_CUSTOM_LAYOUT)) {
+ uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0x2110000, 0, statspec, NULL, INVALID_TILE);
+ if (callback != CALLBACK_FAILED) tile = callback;
+ }
+
+ if (statspec->renderdata == NULL) {
+ sprites = GetStationTileLayout(tile + axis);
+ } else {
+ sprites = &statspec->renderdata[(tile < statspec->tiles) ? tile + axis : axis];
+ }
+
+ image = sprites->ground_sprite;
+ if (HASBIT(image, 31)) {
+ CLRBIT(image, 31);
+ image += GetCustomStationGroundRelocation(statspec, NULL, INVALID_TILE);
+ image += rti->custom_ground_offset;
+ } else {
+ image += rti->total_offset;
+ }
+
+ if (image & PALETTE_MODIFIER_COLOR) image &= SPRITE_MASK;
+ DrawSprite(image, x, y);
+
+ foreach_draw_tile_seq(seq, sprites->seq) {
+ Point pt;
+ image = seq->image;
+ if (HASBIT(image, 30)) {
+ CLRBIT(image, 30);
+ image += rti->total_offset;
+ } else {
+ image += relocation;
+ }
+
+ if ((byte)seq->delta_z != 0x80) {
+ pt = RemapCoords(seq->delta_x, seq->delta_y, seq->delta_z);
+ DrawSprite((image & SPRITE_MASK) | colourmod, x + pt.x, y + pt.y);
+ }
+ }
+
+ return true;
+}
+
+
+static const StationSpec* GetStationSpec(TileIndex t)
+{
+ const Station* st;
+ uint specindex;
+
+ if (!IsCustomStationSpecIndex(t)) return NULL;
+
+ st = GetStationByTile(t);
+ specindex = GetCustomStationSpecIndex(t);
+ return specindex < st->num_specs ? st->speclist[specindex].spec : NULL;
+}
+
+
+/* Check if a rail station tile is traversable.
+ * XXX This could be cached (during build) in the map array to save on all the dereferencing */
+bool IsStationTileBlocked(TileIndex tile)
+{
+ const StationSpec* statspec = GetStationSpec(tile);
+
+ return statspec != NULL && HASBIT(statspec->blocked, GetStationGfx(tile));
+}
+
+/* Check if a rail station tile is electrifiable.
+ * XXX This could be cached (during build) in the map array to save on all the dereferencing */
+bool IsStationTileElectrifiable(TileIndex tile)
+{
+ const StationSpec* statspec = GetStationSpec(tile);
+
+ return
+ statspec == NULL ||
+ HASBIT(statspec->pylons, GetStationGfx(tile)) ||
+ !HASBIT(statspec->wires, GetStationGfx(tile));
+}
diff --git a/src/newgrf_station.h b/src/newgrf_station.h
new file mode 100644
index 000000000..a133fb3d7
--- /dev/null
+++ b/src/newgrf_station.h
@@ -0,0 +1,128 @@
+/* $Id$ */
+
+/** @file newgrf_station.h Header file for NewGRF stations */
+
+#ifndef NEWGRF_STATION_H
+#define NEWGRF_STATION_H
+
+#include "engine.h"
+#include "newgrf_cargo.h"
+
+typedef enum {
+ STAT_CLASS_DFLT, ///< Default station class.
+ STAT_CLASS_WAYP, ///< Waypoint class.
+ STAT_CLASS_MAX = 32, ///< Maximum number of classes.
+} StationClassID;
+
+/* Station layout for given dimensions - it is a two-dimensional array
+ * where index is computed as (x * platforms) + platform. */
+typedef byte *StationLayout;
+
+typedef struct StationSpec {
+ uint32 grfid; ///< ID of GRF file station belongs to.
+ int localidx; ///< Index within GRF file of station.
+
+ bool allocated; ///< Flag whether this station has been added to a station class list
+
+ StationClassID sclass; ///< The class to which this spec belongs.
+ StringID name; ///< Name of this station.
+
+ /**
+ * Bitmask of number of platforms available for the station.
+ * 0..6 correpsond to 1..7, while bit 7 corresponds to >7 platforms.
+ */
+ byte disallowed_platforms;
+ /**
+ * Bitmask of platform lengths available for the station.
+ * 0..6 correpsond to 1..7, while bit 7 corresponds to >7 tiles long.
+ */
+ byte disallowed_lengths;
+
+ /** Number of tile layouts.
+ * A minimum of 8 is required is required for stations.
+ * 0-1 = plain platform
+ * 2-3 = platform with building
+ * 4-5 = platform with roof, left side
+ * 6-7 = platform with roof, right side
+ */
+ uint tiles;
+ DrawTileSprites *renderdata; ///< Array of tile layouts.
+ bool copied_renderdata;
+
+ /** Cargo threshold for choosing between little and lots of cargo
+ * @note little/lots are equivalent to the moving/loading states for vehicles
+ */
+ uint16 cargo_threshold;
+
+ uint32 cargo_triggers; ///< Bitmask of cargo types which cause trigger re-randomizing
+
+ byte callbackmask; ///< Bitmask of callbacks to use, @see newgrf_callbacks.h
+
+ byte flags; ///< Bitmask of flags, bit 0: use different sprite set; bit 1: divide cargo about by station size
+
+ byte pylons; ///< Bitmask of base tiles (0 - 7) which should contain elrail pylons
+ byte wires; ///< Bitmask of base tiles (0 - 7) which should contain elrail wires
+ byte blocked; ///< Bitmask of base tiles (0 - 7) which are blocked to trains
+
+ byte lengths;
+ byte *platforms;
+ StationLayout **layouts;
+ bool copied_layouts;
+
+ /**
+ * NUM_GLOBAL_CID sprite groups.
+ * Used for obtaining the sprite offset of custom sprites, and for
+ * evaluating callbacks.
+ */
+ const struct SpriteGroup *spritegroup[NUM_GLOBAL_CID];
+} StationSpec;
+
+/**
+ * Struct containing information relating to station classes.
+ */
+typedef struct StationClass {
+ uint32 id; ///< ID of this class, e.g. 'DFLT', 'WAYP', etc.
+ StringID name; ///< Name of this class.
+ uint stations; ///< Number of stations in this class.
+ StationSpec **spec; ///< Array of station specifications.
+} StationClass;
+
+void ResetStationClasses(void);
+StationClassID AllocateStationClass(uint32 cls);
+void SetStationClassName(StationClassID sclass, StringID name);
+StringID GetStationClassName(StationClassID sclass);
+StringID *BuildStationClassDropdown(void);
+
+uint GetNumStationClasses(void);
+uint GetNumCustomStations(StationClassID sclass);
+
+void SetCustomStationSpec(StationSpec *statspec);
+const StationSpec *GetCustomStationSpec(StationClassID sclass, uint station);
+const StationSpec *GetCustomStationSpecByGrf(uint32 grfid, byte localidx);
+
+/* Evaluate a tile's position within a station, and return the result a bitstuffed format. */
+uint32 GetPlatformInfo(Axis axis, byte tile, int platforms, int length, int x, int y, bool centred);
+
+/* Get sprite offset for a given custom station and station structure (may be
+ * NULL - that means we are in a build dialog). The station structure is used
+ * for variational sprite groups. */
+SpriteID GetCustomStationRelocation(const StationSpec *statspec, const Station *st, TileIndex tile);
+SpriteID GetCustomStationGroundRelocation(const StationSpec *statspec, const Station *st, TileIndex tile);
+uint16 GetStationCallback(uint16 callback, uint32 param1, uint32 param2, const StationSpec *statspec, const Station *st, TileIndex tile);
+
+/* Check if a rail station tile is traversable. */
+bool IsStationTileBlocked(TileIndex tile);
+
+/* Check if a rail station tile is electrifiable. */
+bool IsStationTileElectrifiable(TileIndex tile);
+
+/* Allocate a StationSpec to a Station. This is called once per build operation. */
+int AllocateSpecToStation(const StationSpec *statspec, Station *st, bool exec);
+
+/* Deallocate a StationSpec from a Station. Called when removing a single station tile. */
+void DeallocateSpecFromStation(Station* st, byte specindex);
+
+/* Draw representation of a station tile for GUI purposes. */
+bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID sclass, uint station);
+
+#endif /* NEWGRF_STATION_H */
diff --git a/src/newgrf_text.c b/src/newgrf_text.c
new file mode 100644
index 000000000..e859f6e6c
--- /dev/null
+++ b/src/newgrf_text.c
@@ -0,0 +1,436 @@
+/* $Id$ */
+
+/** @file
+ * Implementation of Action 04 "universal holder" structure and functions.
+ * This file implements a linked-lists of strings,
+ * holding everything that the newgrf action 04 will send over to OpenTTD.
+ * One of the biggest problems is that Dynamic lang Array uses ISO codes
+ * as way to identifying current user lang, while newgrf uses bit shift codes
+ * not related to ISO. So equivalence functionnality had to be set.
+ */
+
+#include "stdafx.h"
+#include "debug.h"
+#include "openttd.h"
+#include "string.h"
+#include "strings.h"
+#include "variables.h"
+#include "macros.h"
+#include "table/strings.h"
+#include "newgrf.h"
+#include "newgrf_text.h"
+#include "table/control_codes.h"
+
+#define GRFTAB 28
+#define TABSIZE 11
+
+/**
+ * Explains the newgrf shift bit positionning.
+ * the grf base will not be used in order to find the string, but rather for
+ * jumping from standard langID scheme to the new one.
+ */
+typedef enum grf_base_languages {
+ GRFLB_AMERICAN = 0x01,
+ GRFLB_ENGLISH = 0x02,
+ GRFLB_GERMAN = 0x04,
+ GRFLB_FRENCH = 0x08,
+ GRFLB_SPANISH = 0x10,
+ GRFLB_GENERIC = 0x80,
+} grf_base_language;
+
+typedef enum grf_extended_languages {
+ GRFLX_AMERICAN = 0x00,
+ GRFLX_ENGLISH = 0x01,
+ GRFLX_GERMAN = 0x02,
+ GRFLX_FRENCH = 0x03,
+ GRFLX_SPANISH = 0x04,
+ GRFLX_RUSSIAN = 0x07,
+ GRFLX_CZECH = 0x15,
+ GRFLX_SLOVAK = 0x16,
+ GRFLX_AFRIKAANS = 0x1B,
+ GRFLX_GREEK = 0x1E,
+ GRFLX_DUTCH = 0x1F,
+ GRFLX_CATALAN = 0x22,
+ GRFLX_HUNGARIAN = 0x24,
+ GRFLX_ITALIAN = 0x27,
+ GRFLX_ROMANIAN = 0x28,
+ GRFLX_ICELANDIC = 0x29,
+ GRFLX_LATVIAN = 0x2A,
+ GRFLX_LITHUANIAN = 0x2B,
+ GRFLX_SLOVENIAN = 0x2C,
+ GRFLX_DANISH = 0x2D,
+ GRFLX_SWEDISH = 0x2E,
+ GRFLX_NORWEGIAN = 0x2F,
+ GRFLX_POLISH = 0x30,
+ GRFLX_GALICIAN = 0x31,
+ GRFLX_FRISIAN = 0x32,
+ GRFLX_UKRAINIAN = 0x33,
+ GRFLX_ESTONIAN = 0x34,
+ GRFLX_FINNISH = 0x35,
+ GRFLX_PORTUGUESE = 0x36,
+ GRFLX_BRAZILIAN = 0x37,
+ GRFLX_CROATIAN = 0x38,
+ GRFLX_TURKISH = 0x3E,
+ GRFLX_UNSPECIFIED = 0x7F,
+} grf_language;
+
+
+typedef struct iso_grf {
+ char code[6];
+ byte grfLangID;
+} iso_grf;
+
+/**
+ * ISO code VS NewGrf langID conversion array.
+ * This array is used in two ways:
+ * 1-its ISO part is matching OpenTTD dynamic language id
+ * with newgrf bit positionning language id
+ * 2-its shift part is used to know what is the shift to
+ * watch for when inserting new strings, hence analysing newgrf langid
+ */
+const iso_grf iso_codes[] = {
+ {"en_US", GRFLX_AMERICAN},
+ {"en_GB", GRFLX_ENGLISH},
+ {"de_DE", GRFLX_GERMAN},
+ {"fr_FR", GRFLX_FRENCH},
+ {"es_ES", GRFLX_SPANISH},
+ {"af_ZA", GRFLX_AFRIKAANS},
+ {"hr_HR", GRFLX_CROATIAN},
+ {"cs_CS", GRFLX_CZECH},
+ {"ca_ES", GRFLX_CATALAN},
+ {"da_DA", GRFLX_DANISH},
+ {"nl_NL", GRFLX_DUTCH},
+ {"et_ET", GRFLX_ESTONIAN},
+ {"fi_FI", GRFLX_FINNISH},
+ {"fy_NL", GRFLX_FRISIAN},
+ {"gl_ES", GRFLX_GALICIAN},
+ {"el_GR", GRFLX_GREEK},
+ {"hu_HU", GRFLX_HUNGARIAN},
+ {"is_IS", GRFLX_ICELANDIC},
+ {"it_IT", GRFLX_ITALIAN},
+ {"lv_LV", GRFLX_LATVIAN},
+ {"lt_LT", GRFLX_LITHUANIAN},
+ {"nb_NO", GRFLX_NORWEGIAN},
+ {"pl_PL", GRFLX_POLISH},
+ {"pt_PT", GRFLX_PORTUGUESE},
+ {"pt_BR", GRFLX_BRAZILIAN},
+ {"ro_RO", GRFLX_ROMANIAN},
+ {"ru_RU", GRFLX_RUSSIAN},
+ {"sk_SK", GRFLX_SLOVAK},
+ {"sl_SL", GRFLX_SLOVENIAN},
+ {"sv_SE", GRFLX_SWEDISH},
+ {"tr_TR", GRFLX_TURKISH},
+ {"uk_UA", GRFLX_UKRAINIAN},
+ {"gen", GRFLB_GENERIC} //this is not iso code, but there has to be something...
+};
+
+
+/**
+ * Element of the linked list.
+ * Each of those elements represent the string,
+ * but according to a different lang.
+ */
+typedef struct GRFText {
+ struct GRFText *next;
+ byte langid;
+ char text[VARARRAY_SIZE];
+} GRFText;
+
+
+/**
+ * Holder of the above structure.
+ * Putting both grfid and stringid together allows us to avoid duplicates,
+ * since it is NOT SUPPOSED to happen.
+ */
+typedef struct GRFTextEntry {
+ uint32 grfid;
+ uint16 stringid;
+ StringID def_string;
+ GRFText *textholder;
+} GRFTextEntry;
+
+
+static uint _num_grf_texts = 0;
+static GRFTextEntry _grf_text[(1 << TABSIZE) * 3];
+static byte _currentLangID = GRFLX_ENGLISH; //by default, english is used.
+
+
+char *TranslateTTDPatchCodes(const char *str)
+{
+ char *tmp = malloc(strlen(str) * 10 + 1); /* Allocate space to allow for expansion */
+ char *d = tmp;
+ bool unicode = false;
+ WChar c;
+ size_t len = Utf8Decode(&c, str);
+
+ if (c == 0x00DE) {
+ /* The thorn ('þ') indicates a unicode string to TTDPatch */
+ unicode = true;
+ str += len;
+ }
+
+ for (;;) {
+ const char *tmp = str; /* Used for UTF-8 decoding */
+
+ c = (byte)*str++;
+ if (c == 0) break;
+
+ switch (c) {
+ case 0x01:
+ d += Utf8Encode(d, SCC_SETX);
+ *d++ = *str++;
+ break;
+ case 0x0A: break;
+ case 0x0D: *d++ = 0x0A; break;
+ case 0x0E: d += Utf8Encode(d, SCC_TINYFONT); break;
+ case 0x0F: d += Utf8Encode(d, SCC_BIGFONT); break;
+ case 0x1F:
+ d += Utf8Encode(d, SCC_SETXY);
+ *d++ = *str++;
+ *d++ = *str++;
+ break;
+ case 0x7B:
+ case 0x7C:
+ case 0x7D:
+ case 0x7E: d += Utf8Encode(d, SCC_NUM); break;
+ case 0x7F: d += Utf8Encode(d, SCC_CURRENCY); break;
+ case 0x80: d += Utf8Encode(d, SCC_STRING); break;
+ case 0x81: {
+ StringID string;
+ string = *str++;
+ string |= *str++ << 8;
+ d += Utf8Encode(d, SCC_STRING_ID);
+ d += Utf8Encode(d, string);
+ break;
+ }
+ case 0x82: d += Utf8Encode(d, SCC_DATE_TINY); break;
+ case 0x83: d += Utf8Encode(d, SCC_DATE_SHORT); break;
+ case 0x84: d += Utf8Encode(d, SCC_VELOCITY); break;
+ case 0x85: d += Utf8Encode(d, SCC_SKIP); break;
+ case 0x86: /* "Rotate down top 4 words on stack" */ break;
+ case 0x87: d += Utf8Encode(d, SCC_VOLUME); break;
+ case 0x88: d += Utf8Encode(d, SCC_BLUE); break;
+ case 0x89: d += Utf8Encode(d, SCC_SILVER); break;
+ case 0x8A: d += Utf8Encode(d, SCC_GOLD); break;
+ case 0x8B: d += Utf8Encode(d, SCC_RED); break;
+ case 0x8C: d += Utf8Encode(d, SCC_PURPLE); break;
+ case 0x8D: d += Utf8Encode(d, SCC_LTBROWN); break;
+ case 0x8E: d += Utf8Encode(d, SCC_ORANGE); break;
+ case 0x8F: d += Utf8Encode(d, SCC_GREEN); break;
+ case 0x90: d += Utf8Encode(d, SCC_YELLOW); break;
+ case 0x91: d += Utf8Encode(d, SCC_DKGREEN); break;
+ case 0x92: d += Utf8Encode(d, SCC_CREAM); break;
+ case 0x93: d += Utf8Encode(d, SCC_BROWN); break;
+ case 0x94: d += Utf8Encode(d, SCC_WHITE); break;
+ case 0x95: d += Utf8Encode(d, SCC_LTBLUE); break;
+ case 0x96: d += Utf8Encode(d, SCC_GRAY); break;
+ case 0x97: d += Utf8Encode(d, SCC_DKBLUE); break;
+ case 0x98: d += Utf8Encode(d, SCC_BLACK); break;
+ case 0x9E: d += Utf8Encode(d, 0x20AC); break; // Euro
+ case 0x9F: d += Utf8Encode(d, 0x0178); break; // Y with diaeresis
+ case 0xA0: d += Utf8Encode(d, SCC_UPARROW); break;
+ case 0xAA: d += Utf8Encode(d, SCC_DOWNARROW); break;
+ case 0xAC: d += Utf8Encode(d, SCC_CHECKMARK); break;
+ case 0xAD: d += Utf8Encode(d, SCC_CROSS); break;
+ case 0xAF: d += Utf8Encode(d, SCC_RIGHTARROW); break;
+ case 0xB4: d += Utf8Encode(d, SCC_TRAIN); break;
+ case 0xB5: d += Utf8Encode(d, SCC_LORRY); break;
+ case 0xB6: d += Utf8Encode(d, SCC_BUS); break;
+ case 0xB7: d += Utf8Encode(d, SCC_PLANE); break;
+ case 0xB8: d += Utf8Encode(d, SCC_SHIP); break;
+ default:
+ if (unicode) {
+ d += Utf8Encode(d, Utf8Consume(&tmp));
+ str = tmp;
+ break;
+ }
+
+ /* Validate any unhandled character */
+ if (!IsValidChar(c, CS_ALPHANUMERAL)) c = '?';
+ d += Utf8Encode(d, c);
+ break;
+ }
+ }
+
+ *d = '\0';
+ return realloc(tmp, strlen(tmp) + 1);
+}
+
+
+/**
+ * Add the new read string into our structure.
+ */
+StringID AddGRFString(uint32 grfid, uint16 stringid, byte langid_to_add, bool new_scheme, const char *text_to_add, StringID def_string)
+{
+ char *translatedtext;
+ GRFText *newtext;
+ uint id;
+
+ /* When working with the old language scheme (grf_version is less than 7) and
+ * English or American is among the set bits, simply add it as English in
+ * the new scheme, i.e. as langid = 1.
+ * If English is set, it is pretty safe to assume the translations are not
+ * actually translated.
+ */
+ if (!new_scheme) {
+ if (HASBITS(langid_to_add, GRFLB_AMERICAN | GRFLB_ENGLISH)) {
+ langid_to_add = GRFLX_ENGLISH;
+ } else {
+ StringID ret = STR_EMPTY;
+ if (langid_to_add & GRFLB_GERMAN) ret = AddGRFString(grfid, stringid, GRFLX_GERMAN, true, text_to_add, def_string);
+ if (langid_to_add & GRFLB_FRENCH) ret = AddGRFString(grfid, stringid, GRFLX_FRENCH, true, text_to_add, def_string);
+ if (langid_to_add & GRFLB_SPANISH) ret = AddGRFString(grfid, stringid, GRFLX_SPANISH, true, text_to_add, def_string);
+ return ret;
+ }
+ }
+
+ for (id = 0; id < _num_grf_texts; id++) {
+ if (_grf_text[id].grfid == grfid && _grf_text[id].stringid == stringid) {
+ break;
+ }
+ }
+
+ /* Too many strings allocated, return empty */
+ if (id == lengthof(_grf_text)) return STR_EMPTY;
+
+ translatedtext = TranslateTTDPatchCodes(text_to_add);
+
+ newtext = malloc(sizeof(*newtext) + strlen(translatedtext) + 1);
+ newtext->next = NULL;
+ newtext->langid = langid_to_add;
+ strcpy(newtext->text, translatedtext);
+
+ free(translatedtext);
+
+ /* If we didn't find our stringid and grfid in the list, allocate a new id */
+ if (id == _num_grf_texts) _num_grf_texts++;
+
+ if (_grf_text[id].textholder == NULL) {
+ _grf_text[id].grfid = grfid;
+ _grf_text[id].stringid = stringid;
+ _grf_text[id].def_string = def_string;
+ _grf_text[id].textholder = newtext;
+ } else {
+ GRFText **ptext, *text;
+ bool replaced = false;
+
+ /* Loop through all languages and see if we can replace a string */
+ for (ptext = &_grf_text[id].textholder; (text = *ptext) != NULL; ptext = &text->next) {
+ if (text->langid != langid_to_add) continue;
+ newtext->next = text->next;
+ *ptext = newtext;
+ free(text);
+ replaced = true;
+ break;
+ }
+
+ /* If a string wasn't replaced, then we must append the new string */
+ if (!replaced) *ptext = newtext;
+ }
+
+ grfmsg(3, "Added 0x%X: grfid %08X string 0x%X lang 0x%X string '%s'", id, grfid, stringid, newtext->langid, newtext->text);
+
+ return (GRFTAB << TABSIZE) + id;
+}
+
+/* Used to remember the grfid that the last retrieved string came from */
+static uint32 _last_grfid = 0;
+
+/**
+ * Returns the index for this stringid associated with its grfID
+ */
+StringID GetGRFStringID(uint32 grfid, uint16 stringid)
+{
+ uint id;
+
+ /* grfid is zero when we're being called via an include */
+ if (grfid == 0) grfid = _last_grfid;
+
+ for (id = 0; id < _num_grf_texts; id++) {
+ if (_grf_text[id].grfid == grfid && _grf_text[id].stringid == stringid) {
+ return (GRFTAB << TABSIZE) + id;
+ }
+ }
+
+ return STR_UNDEFINED;
+}
+
+
+char *GetGRFString(char *buff, uint16 stringid, const char* last)
+{
+ const GRFText *default_text = NULL;
+ const GRFText *search_text;
+
+ assert(_grf_text[stringid].grfid != 0);
+
+ /* Remember this grfid in case the string has included text */
+ _last_grfid = _grf_text[stringid].grfid;
+
+ /*Search the list of lang-strings of this stringid for current lang */
+ for (search_text = _grf_text[stringid].textholder; search_text != NULL; search_text = search_text->next) {
+ if (search_text->langid == _currentLangID) {
+ return strecpy(buff, search_text->text, last);
+ }
+
+ /* If the current string is English or American, set it as the
+ * fallback language if the specific language isn't available. */
+ if (search_text->langid == GRFLX_UNSPECIFIED || (default_text == NULL && (search_text->langid == GRFLX_ENGLISH || search_text->langid == GRFLX_AMERICAN))) {
+ default_text = search_text;
+ }
+ }
+
+ /* If there is a fallback string, return that */
+ if (default_text != NULL) return strecpy(buff, default_text->text, last);
+
+ /* Use the default string ID if the fallback string isn't available */
+ return GetString(buff, _grf_text[stringid].def_string, last);
+}
+
+/**
+ * Equivalence Setter function between game and newgrf langID.
+ * This function will adjust _currentLangID as to what is the LangID
+ * of the current language set by the user.
+ * The array iso_codes will be used to find that match.
+ * If not found, it will have to be standard english
+ * This function is called after the user changed language,
+ * from strings.c:ReadLanguagePack
+ * @param iso code of current selection
+ */
+void SetCurrentGrfLangID(const char *iso_name)
+{
+ /* Use English by default, if we can't match up the iso_code. */
+ byte ret = GRFLX_ENGLISH;
+ byte i;
+
+ for (i=0; i < lengthof(iso_codes); i++) {
+ if (strncmp(iso_codes[i].code, iso_name, strlen(iso_codes[i].code)) == 0) {
+ /* We found a match, so let's use it. */
+ ret = i;
+ break;
+ }
+ }
+ _currentLangID = ret;
+}
+
+/**
+ * House cleaning.
+ * Remove all strings and reset the text counter.
+ */
+void CleanUpStrings(void)
+{
+ uint id;
+
+ for (id = 0; id < _num_grf_texts; id++) {
+ GRFText *grftext = _grf_text[id].textholder;
+ while (grftext != NULL) {
+ GRFText *grftext2 = grftext->next;
+ free(grftext);
+ grftext = grftext2;
+ }
+ _grf_text[id].grfid = 0;
+ _grf_text[id].stringid = 0;
+ _grf_text[id].textholder = NULL;
+ }
+
+ _num_grf_texts = 0;
+}
diff --git a/src/newgrf_text.h b/src/newgrf_text.h
new file mode 100644
index 000000000..b9850a54e
--- /dev/null
+++ b/src/newgrf_text.h
@@ -0,0 +1,16 @@
+/* $Id$ */
+#ifndef NEWGRF_TEXT_H
+#define NEWGRF_TEXT_H
+
+/** @file
+ * Header of Action 04 "universal holder" structure and functions
+ */
+
+StringID AddGRFString(uint32 grfid, uint16 stringid, byte langid, bool new_scheme, const char *text_to_add, StringID def_string);
+StringID GetGRFStringID(uint32 grfid, uint16 stringid);
+char *GetGRFString(char *buff, uint16 stringid, const char* last);
+void CleanUpStrings(void);
+void SetCurrentGrfLangID(const char *iso_name);
+char *TranslateTTDPatchCodes(const char *str);
+
+#endif /* NEWGRF_TEXT_H */
diff --git a/src/news.h b/src/news.h
new file mode 100644
index 000000000..72f7e842a
--- /dev/null
+++ b/src/news.h
@@ -0,0 +1,83 @@
+/* $Id$ */
+
+#ifndef NEWS_H
+#define NEWS_H
+
+struct NewsItem {
+ StringID string_id;
+ uint16 duration;
+ Date date;
+ byte flags;
+ byte display_mode;
+ byte type;
+ byte callback;
+
+ TileIndex data_a;
+ TileIndex data_b;
+
+ uint32 params[10];
+};
+
+typedef bool ValidationProc ( uint data_a, uint data_b );
+typedef void DrawNewsCallbackProc(Window *w);
+typedef StringID GetNewsStringCallbackProc(const NewsItem *ni);
+
+#define NEWS_FLAGS(mode,flag,type,cb) ((cb)<<24 | (type)<<16 | (flag)<<8 | (mode))
+void AddNewsItem(StringID string, uint32 flags, uint data_a, uint data_b);
+void NewsLoop(void);
+void DrawNewsBorder(const Window *w);
+void InitNewsItemStructs(void);
+
+VARDEF NewsItem _statusbar_news_item;
+
+enum NewsType {
+ NT_ARRIVAL_PLAYER = 0,
+ NT_ARRIVAL_OTHER = 1,
+ NT_ACCIDENT = 2,
+ NT_COMPANY_INFO = 3,
+ NT_ECONOMY = 4,
+ NT_ADVICE = 5,
+ NT_NEW_VEHICLES = 6,
+ NT_ACCEPTANCE = 7,
+ NT_SUBSIDIES = 8,
+ NT_GENERAL = 9,
+};
+
+enum NewsMode {
+ NM_SMALL = 0, ///< Show only a small popup informing us about vehicle age for example
+ NM_NORMAL = 1, ///< Show a simple news message (height 170 pixels)
+ NM_THIN = 2, ///< Show a simple news message (height 130 pixels)
+ NM_CALLBACK = 3, ///< Do some special processing before displaying news message. Which callback to call is in NewsCallback
+};
+
+enum NewsFlags {
+ NF_VIEWPORT = (1 << 1), ///< Does the news message have a viewport? (ingame picture of happening)
+ NF_TILE = (1 << 2), ///< When clicked on the news message scroll to a given tile? Tile is in data_a/data_b
+ NF_VEHICLE = (1 << 3), ///< When clicked on the message scroll to the vehicle? VehicleID is in data_a
+ NF_FORCE_BIG = (1 << 4), ///< Force the appearance of a news message if it has already been shown (internal)
+ NF_INCOLOR = (1 << 5), ///< Show the newsmessage in colour, otherwise it defaults to black & white
+};
+
+enum NewsCallback {
+ DNC_TRAINAVAIL = 0, ///< Show new train available message. StringID is EngineID
+ DNC_ROADAVAIL = 1, ///< Show new road vehicle available message. StringID is EngineID
+ DNC_SHIPAVAIL = 2, ///< Show new ship available message. StringID is EngineID
+ DNC_AIRCRAFTAVAIL = 3, ///< Show new aircraft available message. StringID is EngineID
+ DNC_BANKRUPCY = 4, ///< Show bankrupcy message. StringID is PlayerID (0-3) and NewsBankrupcy (4-7)
+};
+
+enum NewsBankrupcy {
+ NB_BTROUBLE = (1 << 4), ///< Company is in trouble (warning)
+ NB_BMERGER = (2 << 4), ///< Company has been bought by another company
+ NB_BBANKRUPT = (3 << 4), ///< Company has gone bankrupt
+ NB_BNEWCOMPANY = (4 << 4), ///< A new company has been started
+};
+
+/**
+ * Delete a news item type about a vehicle
+ * if the news item type is INVALID_STRING_ID all news about the vehicle get
+ * deleted
+ */
+void DeleteVehicleNews(VehicleID, StringID news);
+
+#endif /* NEWS_H */
diff --git a/src/news_gui.c b/src/news_gui.c
new file mode 100644
index 000000000..7400ac1e4
--- /dev/null
+++ b/src/news_gui.c
@@ -0,0 +1,922 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "functions.h"
+#include "strings.h"
+#include "table/sprites.h"
+#include "table/strings.h"
+#include "window.h"
+#include "gui.h"
+#include "viewport.h"
+#include "gfx.h"
+#include "news.h"
+#include "vehicle.h"
+#include "sound.h"
+#include "variables.h"
+#include "date.h"
+#include "string.h"
+
+/* News system
+ * News system is realized as a FIFO queue (in an array)
+ * The positions in the queue can't be rearranged, we only access
+ * the array elements through pointers to the elements. Once the
+ * array is full, the oldest entry (_oldest_news) is being overwritten
+ * by the newest (_latest news).
+ *
+ * oldest current lastest
+ * | | |
+ * [O------------F-------------C---------L ]
+ * |
+ * forced
+ *
+ * Of course by using an array we can have situations like
+ *
+ * [----L O-----F---------C-----------------]
+ * This is where we have wrapped around the array and have
+ * (MAX_NEWS - O) + L news items
+ */
+
+#define MAX_NEWS 30
+
+typedef byte NewsID;
+#define INVALID_NEWS 255
+
+static NewsItem _news_items[MAX_NEWS];
+static NewsID _current_news = INVALID_NEWS; // points to news item that should be shown next
+static NewsID _oldest_news = 0; // points to first item in fifo queue
+static NewsID _latest_news = INVALID_NEWS; // points to last item in fifo queue
+/* if the message being shown was forced by the user, its index is stored in
+ * _forced_news. forced_news is INVALID_NEWS otherwise.
+ * (Users can force messages through history or "last message") */
+static NewsID _forced_news = INVALID_NEWS;
+
+static byte _total_news = 0; // total news count
+
+void DrawNewsNewTrainAvail(Window *w);
+void DrawNewsNewRoadVehAvail(Window *w);
+void DrawNewsNewShipAvail(Window *w);
+void DrawNewsNewAircraftAvail(Window *w);
+void DrawNewsBankrupcy(Window *w);
+static void MoveToNextItem(void);
+
+StringID GetNewsStringNewTrainAvail(const NewsItem *ni);
+StringID GetNewsStringNewRoadVehAvail(const NewsItem *ni);
+StringID GetNewsStringNewShipAvail(const NewsItem *ni);
+StringID GetNewsStringNewAircraftAvail(const NewsItem *ni);
+StringID GetNewsStringBankrupcy(const NewsItem *ni);
+
+static DrawNewsCallbackProc * const _draw_news_callback[] = {
+ DrawNewsNewTrainAvail, /* DNC_TRAINAVAIL */
+ DrawNewsNewRoadVehAvail, /* DNC_ROADAVAIL */
+ DrawNewsNewShipAvail, /* DNC_SHIPAVAIL */
+ DrawNewsNewAircraftAvail, /* DNC_AIRCRAFTAVAIL */
+ DrawNewsBankrupcy, /* DNC_BANKRUPCY */
+};
+
+GetNewsStringCallbackProc * const _get_news_string_callback[] = {
+ GetNewsStringNewTrainAvail, /* DNC_TRAINAVAIL */
+ GetNewsStringNewRoadVehAvail, /* DNC_ROADAVAIL */
+ GetNewsStringNewShipAvail, /* DNC_SHIPAVAIL */
+ GetNewsStringNewAircraftAvail, /* DNC_AIRCRAFTAVAIL */
+ GetNewsStringBankrupcy, /* DNC_BANKRUPCY */
+};
+
+void InitNewsItemStructs(void)
+{
+ memset(_news_items, 0, sizeof(_news_items));
+ _current_news = INVALID_NEWS;
+ _oldest_news = 0;
+ _latest_news = INVALID_NEWS;
+ _forced_news = INVALID_NEWS;
+ _total_news = 0;
+}
+
+void DrawNewsBorder(const Window *w)
+{
+ int left = 0;
+ int right = w->width - 1;
+ int top = 0;
+ int bottom = w->height - 1;
+
+ GfxFillRect(left, top, right, bottom, 0xF);
+
+ GfxFillRect(left, top, left, bottom, 0xD7);
+ GfxFillRect(right, top, right, bottom, 0xD7);
+ GfxFillRect(left, top, right, top, 0xD7);
+ GfxFillRect(left, bottom, right, bottom, 0xD7);
+
+ DrawString(left + 2, top + 1, STR_00C6, 0);
+}
+
+static void NewsWindowProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_CREATE: { /* If chatbar is open at creation time, we need to go above it */
+ const Window *w1 = FindWindowById(WC_SEND_NETWORK_MSG, 0);
+ w->message.msg = (w1 != NULL) ? w1->height : 0;
+ } break;
+
+ case WE_PAINT: {
+ const NewsItem *ni = WP(w, news_d).ni;
+ ViewPort *vp;
+
+ switch (ni->display_mode) {
+ case NM_NORMAL:
+ case NM_THIN: {
+ DrawNewsBorder(w);
+
+ DrawString(2, 1, STR_00C6, 0);
+
+ SetDParam(0, ni->date);
+ DrawStringRightAligned(428, 1, STR_01FF, 0);
+
+ if (!(ni->flags & NF_VIEWPORT)) {
+ COPY_IN_DPARAM(0, ni->params, lengthof(ni->params));
+ DrawStringMultiCenter(215, ni->display_mode == NM_NORMAL ? 76 : 56,
+ ni->string_id, 426);
+ } else {
+ byte bk = _display_opt;
+ _display_opt &= ~DO_TRANS_BUILDINGS;
+ DrawWindowViewport(w);
+ _display_opt = bk;
+
+ /* Shade the viewport into gray, or color*/
+ vp = w->viewport;
+ GfxFillRect(vp->left - w->left, vp->top - w->top,
+ vp->left - w->left + vp->width - 1, vp->top - w->top + vp->height - 1,
+ (ni->flags & NF_INCOLOR ? 0x322 : 0x323) | USE_COLORTABLE
+ );
+
+ COPY_IN_DPARAM(0, ni->params, lengthof(ni->params));
+ DrawStringMultiCenter(w->width / 2, 20, ni->string_id, 428);
+ }
+ break;
+ }
+
+ case NM_CALLBACK: {
+ _draw_news_callback[ni->callback](w);
+ break;
+ }
+
+ default: {
+ DrawWindowWidgets(w);
+ if (!(ni->flags & NF_VIEWPORT)) {
+ COPY_IN_DPARAM(0, ni->params, lengthof(ni->params));
+ DrawStringMultiCenter(140, 38, ni->string_id, 276);
+ } else {
+ DrawWindowViewport(w);
+ COPY_IN_DPARAM(0, ni->params, lengthof(ni->params));
+ DrawStringMultiCenter(w->width / 2, w->height - 16, ni->string_id, 276);
+ }
+ break;
+ }
+ }
+ } break;
+
+ case WE_CLICK: {
+ switch (e->we.click.widget) {
+ case 1: {
+ NewsItem *ni = WP(w, news_d).ni;
+ DeleteWindow(w);
+ ni->duration = 0;
+ _forced_news = INVALID_NEWS;
+ } break;
+ case 0: {
+ NewsItem *ni = WP(w, news_d).ni;
+ if (ni->flags & NF_VEHICLE) {
+ Vehicle *v = GetVehicle(ni->data_a);
+ ScrollMainWindowTo(v->x_pos, v->y_pos);
+ } else if (ni->flags & NF_TILE) {
+ if (!ScrollMainWindowToTile(ni->data_a) && ni->data_b != 0)
+ ScrollMainWindowToTile(ni->data_b);
+ }
+ } break;
+ }
+ } break;
+
+ case WE_KEYPRESS:
+ if (e->we.keypress.keycode == WKC_SPACE) {
+ // Don't continue.
+ e->we.keypress.cont = false;
+ DeleteWindow(w);
+ }
+ break;
+
+ case WE_MESSAGE: /* The chatbar has notified us that is was either created or closed */
+ switch (e->we.message.msg) {
+ case WE_CREATE: w->message.msg = e->we.message.wparam; break;
+ case WE_DESTROY: w->message.msg = 0; break;
+ }
+ break;
+
+ case WE_TICK: { /* Scroll up newsmessages from the bottom in steps of 4 pixels */
+ int diff;
+ int y = max(w->top - 4, _screen.height - w->height - 12 - w->message.msg);
+ if (y == w->top) return;
+
+ if (w->viewport != NULL)
+ w->viewport->top += y - w->top;
+
+ diff = abs(w->top - y);
+ w->top = y;
+
+ SetDirtyBlocks(w->left, w->top - diff, w->left + w->width, w->top + w->height);
+ } break;
+ }
+}
+
+/** Return the correct index in the pseudo-fifo
+ * queue and deals with overflows when increasing the index */
+static inline NewsID increaseIndex(NewsID i)
+{
+ assert(i != INVALID_NEWS);
+ return (i + 1) % MAX_NEWS;
+}
+
+/** Return the correct index in the pseudo-fifo
+ * queue and deals with overflows when decreasing the index */
+static inline NewsID decreaseIndex(NewsID i)
+{
+ assert(i != INVALID_NEWS);
+ return (i + MAX_NEWS - 1) % MAX_NEWS;
+}
+
+/** Add a new newsitem to be shown.
+ * @param string String to display, can have special values based on parameter 'flags'
+ * @param flags various control bits that will show various news-types. See macro NEWS_FLAGS()
+ * @param data_a news-specific value based on news type
+ * @param data_b news-specific value based on news type
+ * @note flags exists of 4 byte-sized extra parameters.<br/>
+ * 1. 0 - 7 display_mode, any of the NewsMode enums (NM_)<br/>
+ * 2. 8 - 15 news flags, any of the NewsFlags enums (NF_) NF_INCOLOR are set automatically if needed<br/>
+ * 3. 16 - 23 news category, any of the NewsType enums (NT_)<br/>
+ * 4. 24 - 31 news callback function, any of the NewsCallback enums (DNC_)<br/>
+ * If the display mode is NM_CALLBACK special news is shown and parameter
+ * stringid has a special meaning.<br/>
+ * DNC_TRAINAVAIL, DNC_ROADAVAIL, DNC_SHIPAVAIL, DNC_AIRCRAFTAVAIL: StringID is
+ * the index of the engine that is shown<br/>
+ * DNC_BANKRUPCY: bytes 0-3 of StringID contains the player that is in trouble,
+ * and 4-7 contains what kind of bankrupcy message is shown, NewsBankrupcy enum (NB_)<br/>
+ * @see NewsMode
+ * @see NewsFlags
+ * @see NewsType
+ * @see NewsCallback */
+void AddNewsItem(StringID string, uint32 flags, uint data_a, uint data_b)
+{
+ NewsID l_news;
+
+ if (_game_mode == GM_MENU) return;
+
+ // check the rare case that the oldest (to be overwritten) news item is open
+ if (_total_news == MAX_NEWS && (_oldest_news == _current_news || _oldest_news == _forced_news))
+ MoveToNextItem();
+
+ _forced_news = INVALID_NEWS;
+ if (_total_news < MAX_NEWS) _total_news++;
+
+ /* Increase _latest_news. If we have no news yet, use _oldest news as an
+ * index. We cannot use 0 as _oldest_news can jump around due to
+ * DeleteVehicleNews */
+ l_news = _latest_news;
+ _latest_news = (_latest_news == INVALID_NEWS) ? _oldest_news : increaseIndex(_latest_news);
+
+ /* If the fifo-buffer is full, overwrite the oldest entry */
+ if (l_news != INVALID_NEWS && _latest_news == _oldest_news) {
+ assert(_total_news == MAX_NEWS);
+ _oldest_news = increaseIndex(_oldest_news);
+ }
+
+ { /* Add news to _latest_news */
+ Window *w;
+ NewsItem *ni = &_news_items[_latest_news];
+ memset(ni, 0, sizeof(*ni));
+
+ ni->string_id = string;
+ ni->display_mode = (byte)flags;
+ ni->flags = (byte)(flags >> 8);
+
+ // show this news message in color?
+ if (_cur_year >= _patches.colored_news_year) ni->flags |= NF_INCOLOR;
+
+ ni->type = (byte)(flags >> 16);
+ ni->callback = (byte)(flags >> 24);
+ ni->data_a = data_a;
+ ni->data_b = data_b;
+ ni->date = _date;
+ COPY_OUT_DPARAM(ni->params, 0, lengthof(ni->params));
+
+ w = FindWindowById(WC_MESSAGE_HISTORY, 0);
+ if (w == NULL) return;
+ SetWindowDirty(w);
+ w->vscroll.count = _total_news;
+ }
+}
+
+
+// don't show item if it's older than x days
+static const byte _news_items_age[] = {60, 60, 90, 60, 90, 30, 150, 30, 90, 180};
+
+static const Widget _news_type13_widgets[] = {
+{ WWT_PANEL, RESIZE_NONE, 15, 0, 429, 0, 169, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 15, 0, 10, 0, 11, 0x0, STR_NULL},
+{ WIDGETS_END},
+};
+
+static WindowDesc _news_type13_desc = {
+ WDP_CENTER, 476, 430, 170,
+ WC_NEWS_WINDOW, 0,
+ WDF_DEF_WIDGET,
+ _news_type13_widgets,
+ NewsWindowProc
+};
+
+static const Widget _news_type2_widgets[] = {
+{ WWT_PANEL, RESIZE_NONE, 15, 0, 429, 0, 129, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 15, 0, 10, 0, 11, 0x0, STR_NULL},
+{ WIDGETS_END},
+};
+
+static WindowDesc _news_type2_desc = {
+ WDP_CENTER, 476, 430, 130,
+ WC_NEWS_WINDOW, 0,
+ WDF_DEF_WIDGET,
+ _news_type2_widgets,
+ NewsWindowProc
+};
+
+static const Widget _news_type0_widgets[] = {
+{ WWT_PANEL, RESIZE_NONE, 5, 0, 279, 14, 86, 0x0, STR_NULL},
+{ WWT_CLOSEBOX, RESIZE_NONE, 5, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 5, 11, 279, 0, 13, STR_012C_MESSAGE, STR_NULL},
+{ WWT_INSET, RESIZE_NONE, 5, 2, 277, 16, 64, 0x0, STR_NULL},
+{ WIDGETS_END},
+};
+
+static WindowDesc _news_type0_desc = {
+ WDP_CENTER, 476, 280, 87,
+ WC_NEWS_WINDOW, 0,
+ WDF_DEF_WIDGET,
+ _news_type0_widgets,
+ NewsWindowProc
+};
+
+static const SoundFx _news_sounds[] = {
+ SND_1D_APPLAUSE,
+ SND_1D_APPLAUSE,
+ 0,
+ 0,
+ 0,
+ 0,
+ SND_1E_OOOOH,
+ 0,
+ 0,
+ 0
+};
+
+/** Get the value of an item of the news-display settings. This is
+ * a little tricky since on/off/summary must use 2 bits to store the value
+ * @param item the item whose value is requested
+ * @return return the found value which is between 0-2
+ */
+static inline byte GetNewsDisplayValue(byte item)
+{
+ assert(item < 10 && GB(_news_display_opt, item * 2, 2) <= 2);
+ return GB(_news_display_opt, item * 2, 2);
+}
+
+/** Set the value of an item in the news-display settings. This is
+ * a little tricky since on/off/summary must use 2 bits to store the value
+ * @param item the item whose value is being set
+ * @param val new value
+ */
+static inline void SetNewsDisplayValue(byte item, byte val)
+{
+ assert(item < 10 && val <= 2);
+ SB(_news_display_opt, item * 2, 2, val);
+}
+
+// open up an own newspaper window for the news item
+static void ShowNewspaper(NewsItem *ni)
+{
+ Window *w;
+ SoundFx sound;
+ int top;
+ ni->flags &= ~NF_FORCE_BIG;
+ ni->duration = 555;
+
+ sound = _news_sounds[ni->type];
+ if (sound != 0) SndPlayFx(sound);
+
+ top = _screen.height;
+ switch (ni->display_mode) {
+ case NM_NORMAL:
+ case NM_CALLBACK: {
+ _news_type13_desc.top = top;
+ w = AllocateWindowDesc(&_news_type13_desc);
+ if (ni->flags & NF_VIEWPORT)
+ AssignWindowViewport(w, 2, 58, 0x1AA, 0x6E,
+ ni->data_a | (ni->flags & NF_VEHICLE ? 0x80000000 : 0), 0);
+ break;
+ }
+
+ case NM_THIN: {
+ _news_type2_desc.top = top;
+ w = AllocateWindowDesc(&_news_type2_desc);
+ if (ni->flags & NF_VIEWPORT)
+ AssignWindowViewport(w, 2, 58, 0x1AA, 0x46,
+ ni->data_a | (ni->flags & NF_VEHICLE ? 0x80000000 : 0), 0);
+ break;
+ }
+
+ default: {
+ _news_type0_desc.top = top;
+ w = AllocateWindowDesc(&_news_type0_desc);
+ if (ni->flags & NF_VIEWPORT)
+ AssignWindowViewport(w, 3, 17, 0x112, 0x2F,
+ ni->data_a | (ni->flags & NF_VEHICLE ? 0x80000000 : 0), 0);
+ break;
+ }
+ }
+ WP(w, news_d).ni = &_news_items[_forced_news == INVALID_NEWS ? _current_news : _forced_news];
+ w->flags4 |= WF_DISABLE_VP_SCROLL;
+}
+
+// show news item in the ticker
+static void ShowTicker(const NewsItem *ni)
+{
+ Window *w;
+
+ if (_news_ticker_sound) SndPlayFx(SND_16_MORSE);
+
+ _statusbar_news_item = *ni;
+ w = FindWindowById(WC_STATUS_BAR, 0);
+ if (w != NULL) WP(w, def_d).data_1 = 360;
+}
+
+
+// Are we ready to show another news item?
+// Only if nothing is in the newsticker and no newspaper is displayed
+static bool ReadyForNextItem(void)
+{
+ const Window *w;
+ NewsID item = (_forced_news == INVALID_NEWS) ? _current_news : _forced_news;
+ NewsItem *ni;
+
+ if (item >= MAX_NEWS) return true;
+ ni = &_news_items[item];
+
+ // Ticker message
+ // Check if the status bar message is still being displayed?
+ w = FindWindowById(WC_STATUS_BAR, 0);
+ if (w != NULL && WP(w, const def_d).data_1 > -1280) return false;
+
+ // Newspaper message, decrement duration counter
+ if (ni->duration != 0) ni->duration--;
+
+ // neither newsticker nor newspaper are running
+ return (ni->duration == 0 || FindWindowById(WC_NEWS_WINDOW, 0) == NULL);
+}
+
+static void MoveToNextItem(void)
+{
+ DeleteWindowById(WC_NEWS_WINDOW, 0);
+ _forced_news = INVALID_NEWS;
+
+ // if we're not at the last item, then move on
+ if (_current_news != _latest_news) {
+ NewsItem *ni;
+
+ _current_news = (_current_news == INVALID_NEWS) ? _oldest_news : increaseIndex(_current_news);
+ ni = &_news_items[_current_news];
+
+ // check the date, don't show too old items
+ if (_date - _news_items_age[ni->type] > ni->date) return;
+
+ switch (GetNewsDisplayValue(ni->type)) {
+ case 0: { /* Off - show nothing only a small reminder in the status bar */
+ Window *w = FindWindowById(WC_STATUS_BAR, 0);
+
+ if (w != NULL) {
+ WP(w, def_d).data_2 = 91;
+ SetWindowDirty(w);
+ }
+ break;
+ }
+
+ case 1: /* Summary - show ticker, but if forced big, cascade to full */
+ if (!(ni->flags & NF_FORCE_BIG)) {
+ ShowTicker(ni);
+ break;
+ }
+ /* Fallthrough */
+
+ case 2: /* Full - show newspaper*/
+ ShowNewspaper(ni);
+ break;
+ }
+ }
+}
+
+void NewsLoop(void)
+{
+ // no news item yet
+ if (_total_news == 0) return;
+
+ if (ReadyForNextItem()) MoveToNextItem();
+}
+
+/* Do a forced show of a specific message */
+static void ShowNewsMessage(NewsID i)
+{
+ if (_total_news == 0) return;
+
+ // Delete the news window
+ DeleteWindowById(WC_NEWS_WINDOW, 0);
+
+ // setup forced news item
+ _forced_news = i;
+
+ if (_forced_news != INVALID_NEWS) {
+ NewsItem *ni = &_news_items[_forced_news];
+ ni->duration = 555;
+ ni->flags |= NF_FORCE_BIG;
+ DeleteWindowById(WC_NEWS_WINDOW, 0);
+ ShowNewspaper(ni);
+ }
+}
+
+void ShowLastNewsMessage(void)
+{
+ switch (_forced_news) {
+ case INVALID_NEWS: // Not forced any news yet, show the current one
+ ShowNewsMessage(_current_news);
+ break;
+ case 0: //
+ ShowNewsMessage(_total_news != MAX_NEWS ? _latest_news : MAX_NEWS - 1);
+ break;
+ default: // 'Scrolling' through news history show each one in turn
+ ShowNewsMessage(_forced_news - 1);
+ break;
+ }
+}
+
+
+/* return news by number, with 0 being the most
+ * recent news. Returns INVALID_NEWS if end of queue reached. */
+static NewsID getNews(NewsID i)
+{
+ if (i >= _total_news) return INVALID_NEWS;
+
+ if (_latest_news < i) {
+ i = _latest_news + MAX_NEWS - i;
+ } else {
+ i = _latest_news - i;
+ }
+
+ i %= MAX_NEWS;
+ return i;
+}
+
+/** Draw an unformatted news message truncated to a maximum length. If
+ * length exceeds maximum length it will be postfixed by '...'
+ * @param x,y position of the string
+ * @param color the color the string will be shown in
+ * @param *ni NewsItem being printed
+ * @param maxw maximum width of string in pixels
+ */
+static void DrawNewsString(int x, int y, uint16 color, const NewsItem *ni, uint maxw)
+{
+ char buffer[512], buffer2[512];
+ const char *ptr;
+ char *dest;
+ StringID str;
+
+ if (ni->display_mode == 3) {
+ str = _get_news_string_callback[ni->callback](ni);
+ } else {
+ COPY_IN_DPARAM(0, ni->params, lengthof(ni->params));
+ str = ni->string_id;
+ }
+
+ GetString(buffer, str, lastof(buffer));
+ /* Copy the just gotten string to another buffer to remove any formatting
+ * from it such as big fonts, etc. */
+ ptr = buffer;
+ dest = buffer2;
+ for (;;) {
+ WChar c = Utf8Consume(&ptr);
+ if (c == 0) break;
+ if (c == '\r') {
+ dest[0] = dest[1] = dest[2] = dest[3] = ' ';
+ dest += 4;
+ } else if (IsPrintable(c)) {
+ dest += Utf8Encode(dest, c);
+ }
+ }
+
+ *dest = '\0';
+ /* Truncate and show string; postfixed by '...' if neccessary */
+ DoDrawStringTruncated(buffer2, x, y, color, maxw);
+}
+
+
+static void MessageHistoryWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ int y = 19;
+ NewsID p, show;
+
+ SetVScrollCount(w, _total_news);
+ DrawWindowWidgets(w);
+
+ if (_total_news == 0) break;
+ show = min(_total_news, w->vscroll.cap);
+
+ for (p = w->vscroll.pos; p < w->vscroll.pos + show; p++) {
+ // get news in correct order
+ const NewsItem *ni = &_news_items[getNews(p)];
+
+ SetDParam(0, ni->date);
+ DrawString(4, y, STR_SHORT_DATE, 12);
+
+ DrawNewsString(82, y, 12, ni, w->width - 95);
+ y += 12;
+ }
+ break;
+ }
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 3: {
+ int y = (e->we.click.pt.y - 19) / 12;
+ NewsID p = getNews(y + w->vscroll.pos);
+
+ if (p == INVALID_NEWS) break;
+
+ ShowNewsMessage(p);
+ break;
+ }
+ }
+ break;
+
+ case WE_RESIZE:
+ w->vscroll.cap += e->we.sizing.diff.y / 12;
+ break;
+ }
+}
+
+static const Widget _message_history_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 13, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_RIGHT, 13, 11, 387, 0, 13, STR_MESSAGE_HISTORY, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_STICKYBOX, RESIZE_LR, 13, 388, 399, 0, 13, 0x0, STR_STICKY_BUTTON},
+{ WWT_PANEL, RESIZE_RB, 13, 0, 387, 14, 139, 0x0, STR_MESSAGE_HISTORY_TIP},
+{ WWT_SCROLLBAR, RESIZE_LRB, 13, 388, 399, 14, 127, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WWT_RESIZEBOX, RESIZE_LRTB, 13, 388, 399, 128, 139, 0x0, STR_RESIZE_BUTTON},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _message_history_desc = {
+ 240, 22, 400, 140,
+ WC_MESSAGE_HISTORY, 0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
+ _message_history_widgets,
+ MessageHistoryWndProc
+};
+
+void ShowMessageHistory(void)
+{
+ Window *w;
+
+ DeleteWindowById(WC_MESSAGE_HISTORY, 0);
+ w = AllocateWindowDesc(&_message_history_desc);
+
+ if (w != NULL) {
+ w->vscroll.cap = 10;
+ w->vscroll.count = _total_news;
+ w->resize.step_height = 12;
+ w->resize.height = w->height - 12 * 6; // minimum of 4 items in the list, each item 12 high
+ w->resize.step_width = 1;
+ w->resize.width = 200; // can't make window any smaller than 200 pixel
+ SetWindowDirty(w);
+ }
+}
+
+/** Setup the disabled/enabled buttons in the message window
+ * If the value is 'off' disable the [<] widget, and enable the [>] one
+ * Same-wise for all the others. Starting value of 3 is the first widget
+ * group. These are grouped as [<][>] .. [<][>], etc.
+ */
+static void SetMessageButtonStates(Window *w, byte value, int element)
+{
+ element *= 2;
+
+ SetWindowWidgetDisabledState(w, element + 3, value == 0);
+ SetWindowWidgetDisabledState(w, element + 3 + 1, value == 2);
+}
+
+static void MessageOptionsWndProc(Window *w, WindowEvent *e)
+{
+ static const StringID message_opt[] = {STR_OFF, STR_SUMMARY, STR_FULL, INVALID_STRING_ID};
+
+ /* WP(w, def_d).data_1 are stores the clicked state of the fake widgets
+ * WP(w, def_d).data_2 stores state of the ALL on/off/summary button */
+ switch (e->event) {
+ case WE_CREATE: {
+ uint32 val = _news_display_opt;
+ int i;
+ WP(w, def_d).data_1 = WP(w, def_d).data_2 = 0;
+
+ // Set up the initial disabled buttons in the case of 'off' or 'full'
+ for (i = 0; i != 10; i++, val >>= 2) SetMessageButtonStates(w, val & 0x3, i);
+ } break;
+
+ case WE_PAINT: {
+ uint32 val = _news_display_opt;
+ int click_state = WP(w, def_d).data_1;
+ int i, y;
+
+ if (_news_ticker_sound) LowerWindowWidget(w, 25);
+ DrawWindowWidgets(w);
+
+ /* XXX - Draw the fake widgets-buttons. Can't add these to the widget-desc since
+ * openttd currently can only handle 32 widgets. So hack it *g* */
+ for (i = 0, y = 26; i != 10; i++, y += 12, click_state >>= 1, val >>= 2) {
+ bool clicked = !!(click_state & 1);
+
+ DrawFrameRect(13, y, 89, 11 + y, 3, (clicked) ? FR_LOWERED : 0);
+ DrawStringCentered(((13 + 89 + 1) >> 1) + clicked, ((y + 11 + y + 1) >> 1) - 5 + clicked, message_opt[val & 0x3], 0x10);
+ DrawString(103, y + 1, i + STR_0206_ARRIVAL_OF_FIRST_VEHICLE, 0);
+ }
+
+ DrawString( 8, y + 9, message_opt[WP(w, def_d).data_2], 0x10);
+ DrawString(103, y + 9, STR_MESSAGES_ALL, 0);
+ DrawString(103, y + 9 + 12, STR_MESSAGE_SOUND, 0);
+
+ } break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 2: /* Clicked on any of the fake widgets */
+ if (e->we.click.pt.x > 13 && e->we.click.pt.x < 89 && e->we.click.pt.y > 26 && e->we.click.pt.y < 146) {
+ int element = (e->we.click.pt.y - 26) / 12;
+ byte val = (GetNewsDisplayValue(element) + 1) % 3;
+
+ SetMessageButtonStates(w, val, element);
+ SetNewsDisplayValue(element, val);
+
+ WP(w, def_d).data_1 |= (1 << element);
+ w->flags4 |= 5 << WF_TIMEOUT_SHL; // XXX - setup unclick (fake widget)
+ SetWindowDirty(w);
+ }
+ break;
+ case 23: case 24: /* Dropdown menu for all settings */
+ ShowDropDownMenu(w, message_opt, WP(w, def_d).data_2, 24, 0, 0);
+ break;
+ case 25: /* Change ticker sound on/off */
+ _news_ticker_sound ^= 1;
+ ToggleWidgetLoweredState(w, e->we.click.widget);
+ InvalidateWidget(w, e->we.click.widget);
+ break;
+ default: { /* Clicked on the [<] .. [>] widgets */
+ int wid = e->we.click.widget;
+ if (wid > 2 && wid < 23) {
+ int element = (wid - 3) / 2;
+ byte val = (GetNewsDisplayValue(element) + ((wid & 1) ? -1 : 1)) % 3;
+
+ SetMessageButtonStates(w, val, element);
+ SetNewsDisplayValue(element, val);
+ SetWindowDirty(w);
+ }
+ } break;
+ } break;
+
+ case WE_DROPDOWN_SELECT: {/* Select all settings for newsmessages */
+ int i;
+
+ WP(w, def_d).data_2 = e->we.dropdown.index;
+
+ for (i = 0; i != 10; i++) {
+ SB(_news_display_opt, i*2, 2, e->we.dropdown.index);
+ SetMessageButtonStates(w, e->we.dropdown.index, i);
+ }
+ SetWindowDirty(w);
+ break;
+ }
+
+ case WE_TIMEOUT: /* XXX - Hack to animate 'fake' buttons */
+ WP(w, def_d).data_1 = 0;
+ SetWindowDirty(w);
+ break;
+ }
+}
+
+static const Widget _message_options_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 13, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 13, 11, 409, 0, 13, STR_0204_MESSAGE_OPTIONS, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 13, 0, 409, 14, 184, 0x0, STR_NULL},
+
+{ WWT_PUSHIMGBTN, RESIZE_NONE, 3, 4, 12, 26, 37, SPR_ARROW_LEFT, STR_HSCROLL_BAR_SCROLLS_LIST},
+{ WWT_PUSHIMGBTN, RESIZE_NONE, 3, 90, 98, 26, 37, SPR_ARROW_RIGHT, STR_HSCROLL_BAR_SCROLLS_LIST},
+
+{ WWT_PUSHIMGBTN, RESIZE_NONE, 3, 4, 12, 38, 49, SPR_ARROW_LEFT, STR_HSCROLL_BAR_SCROLLS_LIST},
+{ WWT_PUSHIMGBTN, RESIZE_NONE, 3, 90, 98, 38, 49, SPR_ARROW_RIGHT, STR_HSCROLL_BAR_SCROLLS_LIST},
+
+{ WWT_PUSHIMGBTN, RESIZE_NONE, 3, 4, 12, 50, 61, SPR_ARROW_LEFT, STR_HSCROLL_BAR_SCROLLS_LIST},
+{ WWT_PUSHIMGBTN, RESIZE_NONE, 3, 90, 98, 50, 61, SPR_ARROW_RIGHT, STR_HSCROLL_BAR_SCROLLS_LIST},
+
+{ WWT_PUSHIMGBTN, RESIZE_NONE, 3, 4, 12, 62, 73, SPR_ARROW_LEFT, STR_HSCROLL_BAR_SCROLLS_LIST},
+{ WWT_PUSHIMGBTN, RESIZE_NONE, 3, 90, 98, 62, 73, SPR_ARROW_RIGHT, STR_HSCROLL_BAR_SCROLLS_LIST},
+
+{ WWT_PUSHIMGBTN, RESIZE_NONE, 3, 4, 12, 74, 85, SPR_ARROW_LEFT, STR_HSCROLL_BAR_SCROLLS_LIST},
+{ WWT_PUSHIMGBTN, RESIZE_NONE, 3, 90, 98, 74, 85, SPR_ARROW_RIGHT, STR_HSCROLL_BAR_SCROLLS_LIST},
+
+{ WWT_PUSHIMGBTN, RESIZE_NONE, 3, 4, 12, 86, 97, SPR_ARROW_LEFT, STR_HSCROLL_BAR_SCROLLS_LIST},
+{ WWT_PUSHIMGBTN, RESIZE_NONE, 3, 90, 98, 86, 97, SPR_ARROW_RIGHT, STR_HSCROLL_BAR_SCROLLS_LIST},
+
+{ WWT_PUSHIMGBTN, RESIZE_NONE, 3, 4, 12, 98, 109, SPR_ARROW_LEFT, STR_HSCROLL_BAR_SCROLLS_LIST},
+{ WWT_PUSHIMGBTN, RESIZE_NONE, 3, 90, 98, 98, 109, SPR_ARROW_RIGHT, STR_HSCROLL_BAR_SCROLLS_LIST},
+
+{ WWT_PUSHIMGBTN, RESIZE_NONE, 3, 4, 12, 110, 121, SPR_ARROW_LEFT, STR_HSCROLL_BAR_SCROLLS_LIST},
+{ WWT_PUSHIMGBTN, RESIZE_NONE, 3, 90, 98, 110, 121, SPR_ARROW_RIGHT, STR_HSCROLL_BAR_SCROLLS_LIST},
+
+{ WWT_PUSHIMGBTN, RESIZE_NONE, 3, 4, 12, 122, 133, SPR_ARROW_LEFT, STR_HSCROLL_BAR_SCROLLS_LIST},
+{ WWT_PUSHIMGBTN, RESIZE_NONE, 3, 90, 98, 122, 133, SPR_ARROW_RIGHT, STR_HSCROLL_BAR_SCROLLS_LIST},
+
+{ WWT_PUSHIMGBTN, RESIZE_NONE, 3, 4, 12, 134, 145, SPR_ARROW_LEFT, STR_HSCROLL_BAR_SCROLLS_LIST},
+{ WWT_PUSHIMGBTN, RESIZE_NONE, 3, 90, 98, 134, 145, SPR_ARROW_RIGHT, STR_HSCROLL_BAR_SCROLLS_LIST},
+
+{ WWT_PANEL, RESIZE_NONE, 3, 4, 86, 154, 165, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 3, 87, 98, 154, 165, STR_0225, STR_NULL},
+{ WWT_TEXTBTN_2, RESIZE_NONE, 3, 4, 98, 166, 177, STR_02DB_OFF, STR_NULL},
+
+{ WWT_LABEL, RESIZE_NONE, 13, 0, 409, 13, 26, STR_0205_MESSAGE_TYPES, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _message_options_desc = {
+ 270, 22, 410, 185,
+ WC_GAME_OPTIONS, 0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _message_options_widgets,
+ MessageOptionsWndProc
+};
+
+void ShowMessageOptions(void)
+{
+ DeleteWindowById(WC_GAME_OPTIONS, 0);
+ AllocateWindowDesc(&_message_options_desc);
+}
+
+
+void DeleteVehicleNews(VehicleID vid, StringID news)
+{
+ NewsID n;
+
+ for (n = _oldest_news; _latest_news != INVALID_NEWS; n = increaseIndex(n)) {
+ const NewsItem *ni = &_news_items[n];
+
+ if (ni->flags & NF_VEHICLE &&
+ ni->data_a == vid &&
+ (news == INVALID_STRING_ID || ni->string_id == news)) {
+ Window *w;
+
+ if (_forced_news == n || _current_news == n) MoveToNextItem();
+ _total_news--;
+
+ // If this is the last news item, invalidate _latest_news
+ if (_latest_news == _oldest_news) {
+ assert(_total_news == 0);
+ _latest_news = INVALID_NEWS;
+ }
+
+ /* Since we only imitate a FIFO removing an arbitrary element does need
+ * some magic. Remove the item by shifting head towards the tail. eg
+ * oldest remove last
+ * | | |
+ * [------O--------n-----L--]
+ * will become (change dramatized to make clear)
+ * [---------O-----------L--]
+ * Also update the current news item in case it was pointing to the
+ * oldest, now shifted item */
+ if (_total_news != 0) {
+ NewsID i;
+ for (i = n; i != _oldest_news; i = decreaseIndex(i)) {
+ _news_items[i] = _news_items[decreaseIndex(i)];
+ }
+
+ if (_current_news == _oldest_news) _current_news = increaseIndex(_current_news);
+ _oldest_news = increaseIndex(_oldest_news);
+ }
+
+ w = FindWindowById(WC_MESSAGE_HISTORY, 0);
+ if (w != NULL) {
+ SetWindowDirty(w);
+ w->vscroll.count = _total_news;
+ }
+ }
+
+ if (n == _latest_news) break;
+ }
+}
diff --git a/src/npf.c b/src/npf.c
new file mode 100644
index 000000000..97b9bf367
--- /dev/null
+++ b/src/npf.c
@@ -0,0 +1,894 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "bridge_map.h"
+#include "debug.h"
+#include "functions.h"
+#include "npf.h"
+#include "aystar.h"
+#include "macros.h"
+#include "pathfind.h"
+#include "station.h"
+#include "station_map.h"
+#include "tile.h"
+#include "depot.h"
+#include "tunnel_map.h"
+#include "network/network.h"
+#include "water_map.h"
+
+static AyStar _npf_aystar;
+
+/* The cost of each trackdir. A diagonal piece is the full NPF_TILE_LENGTH,
+ * the shorter piece is sqrt(2)/2*NPF_TILE_LENGTH =~ 0.7071
+ */
+#define NPF_STRAIGHT_LENGTH (uint)(NPF_TILE_LENGTH * STRAIGHT_TRACK_LENGTH)
+static const uint _trackdir_length[TRACKDIR_END] = {
+ NPF_TILE_LENGTH, NPF_TILE_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH,
+ 0, 0,
+ NPF_TILE_LENGTH, NPF_TILE_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH
+};
+
+/**
+ * Calculates the minimum distance traveled to get from t0 to t1 when only
+ * using tracks (ie, only making 45 degree turns). Returns the distance in the
+ * NPF scale, ie the number of full tiles multiplied by NPF_TILE_LENGTH to
+ * prevent rounding.
+ */
+static uint NPFDistanceTrack(TileIndex t0, TileIndex t1)
+{
+ const uint dx = abs(TileX(t0) - TileX(t1));
+ const uint dy = abs(TileY(t0) - TileY(t1));
+
+ const uint straightTracks = 2 * min(dx, dy); /* The number of straight (not full length) tracks */
+ /* OPTIMISATION:
+ * Original: diagTracks = max(dx, dy) - min(dx,dy);
+ * Proof:
+ * (dx+dy) - straightTracks == (min + max) - straightTracks = min + max - 2 * min = max - min */
+ const uint diagTracks = dx + dy - straightTracks; /* The number of diagonal (full tile length) tracks. */
+
+ /* Don't factor out NPF_TILE_LENGTH below, this will round values and lose
+ * precision */
+ return diagTracks * NPF_TILE_LENGTH + straightTracks * NPF_TILE_LENGTH * STRAIGHT_TRACK_LENGTH;
+}
+
+
+#if 0
+static uint NTPHash(uint key1, uint key2)
+{
+ /* This function uses the old hash, which is fixed on 10 bits (1024 buckets) */
+ return PATHFIND_HASH_TILE(key1);
+}
+#endif
+
+/**
+ * Calculates a hash value for use in the NPF.
+ * @param key1 The TileIndex of the tile to hash
+ * @param key2 The Trackdir of the track on the tile.
+ *
+ * @todo Think of a better hash.
+ */
+static uint NPFHash(uint key1, uint key2)
+{
+ /* TODO: think of a better hash? */
+ uint part1 = TileX(key1) & NPF_HASH_HALFMASK;
+ uint part2 = TileY(key1) & NPF_HASH_HALFMASK;
+
+ assert(IsValidTrackdir(key2));
+ assert(IsValidTile(key1));
+ return ((part1 << NPF_HASH_HALFBITS | part2) + (NPF_HASH_SIZE * key2 / TRACKDIR_END)) % NPF_HASH_SIZE;
+}
+
+static int32 NPFCalcZero(AyStar* as, AyStarNode* current, OpenListNode* parent)
+{
+ return 0;
+}
+
+/* Calcs the tile of given station that is closest to a given tile
+ * for this we assume the station is a rectangle,
+ * as defined by its top tile (st->train_tile) and its width/height (st->trainst_w, st->trainst_h)
+ */
+static TileIndex CalcClosestStationTile(StationID station, TileIndex tile)
+{
+ const Station* st = GetStation(station);
+
+ uint minx = TileX(st->train_tile); // topmost corner of station
+ uint miny = TileY(st->train_tile);
+ uint maxx = minx + st->trainst_w - 1; // lowermost corner of station
+ uint maxy = miny + st->trainst_h - 1;
+ uint x;
+ uint y;
+
+ // we are going the aim for the x coordinate of the closest corner
+ // but if we are between those coordinates, we will aim for our own x coordinate
+ x = clamp(TileX(tile), minx, maxx);
+
+ // same for y coordinate, see above comment
+ y = clamp(TileY(tile), miny, maxy);
+
+ // return the tile of our target coordinates
+ return TileXY(x, y);
+}
+
+/* Calcs the heuristic to the target station or tile. For train stations, it
+ * takes into account the direction of approach.
+ */
+static int32 NPFCalcStationOrTileHeuristic(AyStar* as, AyStarNode* current, OpenListNode* parent)
+{
+ NPFFindStationOrTileData* fstd = (NPFFindStationOrTileData*)as->user_target;
+ NPFFoundTargetData* ftd = (NPFFoundTargetData*)as->user_path;
+ TileIndex from = current->tile;
+ TileIndex to = fstd->dest_coords;
+ uint dist;
+
+ // for train-stations, we are going to aim for the closest station tile
+ if (as->user_data[NPF_TYPE] == TRANSPORT_RAIL && fstd->station_index != INVALID_STATION)
+ to = CalcClosestStationTile(fstd->station_index, from);
+
+ if (as->user_data[NPF_TYPE] == TRANSPORT_ROAD) {
+ /* Since roads only have diagonal pieces, we use manhattan distance here */
+ dist = DistanceManhattan(from, to) * NPF_TILE_LENGTH;
+ } else {
+ /* Ships and trains can also go diagonal, so the minimum distance is shorter */
+ dist = NPFDistanceTrack(from, to);
+ }
+
+ DEBUG(npf, 4, "Calculating H for: (%d, %d). Result: %d", TileX(current->tile), TileY(current->tile), dist);
+
+ if (dist < ftd->best_bird_dist) {
+ ftd->best_bird_dist = dist;
+ ftd->best_trackdir = current->user_data[NPF_TRACKDIR_CHOICE];
+ }
+ return dist;
+}
+
+
+/* Fills AyStarNode.user_data[NPF_TRACKDIRCHOICE] with the chosen direction to
+ * get here, either getting it from the current choice or from the parent's
+ * choice */
+static void NPFFillTrackdirChoice(AyStarNode* current, OpenListNode* parent)
+{
+ if (parent->path.parent == NULL) {
+ Trackdir trackdir = (Trackdir)current->direction;
+ /* This is a first order decision, so we'd better save the
+ * direction we chose */
+ current->user_data[NPF_TRACKDIR_CHOICE] = trackdir;
+ DEBUG(npf, 6, "Saving trackdir: 0x%X", trackdir);
+ } else {
+ /* We've already made the decision, so just save our parent's decision */
+ current->user_data[NPF_TRACKDIR_CHOICE] = parent->path.node.user_data[NPF_TRACKDIR_CHOICE];
+ }
+}
+
+/* Will return the cost of the tunnel. If it is an entry, it will return the
+ * cost of that tile. If the tile is an exit, it will return the tunnel length
+ * including the exit tile. Requires that this is a Tunnel tile */
+static uint NPFTunnelCost(AyStarNode* current)
+{
+ DiagDirection exitdir = TrackdirToExitdir((Trackdir)current->direction);
+ TileIndex tile = current->tile;
+ if (GetTunnelDirection(tile) == ReverseDiagDir(exitdir)) {
+ /* We just popped out if this tunnel, since were
+ * facing the tunnel exit */
+ FindLengthOfTunnelResult flotr;
+ flotr = FindLengthOfTunnel(tile, ReverseDiagDir(exitdir));
+ return flotr.length * NPF_TILE_LENGTH;
+ //TODO: Penalty for tunnels?
+ } else {
+ /* We are entering the tunnel, the enter tile is just a
+ * straight track */
+ return NPF_TILE_LENGTH;
+ }
+}
+
+static inline uint NPFBridgeCost(AyStarNode *current)
+{
+ return NPF_TILE_LENGTH * GetBridgeLength(current->tile, GetOtherBridgeEnd(current->tile));
+}
+
+static uint NPFSlopeCost(AyStarNode* current)
+{
+ TileIndex next = current->tile + TileOffsByDiagDir(TrackdirToExitdir(current->direction));
+ int x,y;
+ int8 z1,z2;
+
+ x = TileX(current->tile) * TILE_SIZE;
+ y = TileY(current->tile) * TILE_SIZE;
+ /* get the height of the center of the current tile */
+ z1 = GetSlopeZ(x + TILE_SIZE / 2, y + TILE_SIZE / 2);
+
+ x = TileX(next) * TILE_SIZE;
+ y = TileY(next) * TILE_SIZE;
+ /* get the height of the center of the next tile */
+ z2 = GetSlopeZ(x + TILE_SIZE / 2, y + TILE_SIZE / 2);
+
+ if (z2 - z1 > 1) {
+ /* Slope up */
+ return _patches.npf_rail_slope_penalty;
+ }
+ return 0;
+ /* Should we give a bonus for slope down? Probably not, we
+ * could just substract that bonus from the penalty, because
+ * there is only one level of steepness... */
+}
+
+/**
+ * Mark tiles by mowing the grass when npf debug level >= 1.
+ * Will not work for multiplayer games, since it can (will) cause desyncs.
+ */
+static void NPFMarkTile(TileIndex tile)
+{
+#ifndef NO_DEBUG_MESSAGES
+ if (_debug_npf_level < 1 || _networking) return;
+ switch (GetTileType(tile)) {
+ case MP_RAILWAY:
+ /* DEBUG: mark visited tiles by mowing the grass under them ;-) */
+ if (!IsTileDepotType(tile, TRANSPORT_RAIL)) {
+ SetRailGroundType(tile, RAIL_GROUND_BARREN);
+ MarkTileDirtyByTile(tile);
+ }
+ break;
+
+ case MP_STREET:
+ if (!IsTileDepotType(tile, TRANSPORT_ROAD)) {
+ SetRoadside(tile, ROADSIDE_BARREN);
+ MarkTileDirtyByTile(tile);
+ }
+ break;
+
+ default:
+ break;
+ }
+#endif
+}
+
+static int32 NPFWaterPathCost(AyStar* as, AyStarNode* current, OpenListNode* parent)
+{
+ //TileIndex tile = current->tile;
+ int32 cost = 0;
+ Trackdir trackdir = (Trackdir)current->direction;
+
+ cost = _trackdir_length[trackdir]; /* Should be different for diagonal tracks */
+
+ if (IsBuoyTile(current->tile) && IsDiagonalTrackdir(trackdir))
+ cost += _patches.npf_buoy_penalty; /* A small penalty for going over buoys */
+
+ if (current->direction != NextTrackdir((Trackdir)parent->path.node.direction))
+ cost += _patches.npf_water_curve_penalty;
+
+ /* TODO More penalties? */
+
+ return cost;
+}
+
+/* Determine the cost of this node, for road tracks */
+static int32 NPFRoadPathCost(AyStar* as, AyStarNode* current, OpenListNode* parent)
+{
+ TileIndex tile = current->tile;
+ int32 cost = 0;
+
+ /* Determine base length */
+ switch (GetTileType(tile)) {
+ case MP_TUNNELBRIDGE:
+ cost = IsTunnel(tile) ? NPFTunnelCost(current) : NPFBridgeCost(current);
+ break;
+
+ case MP_STREET:
+ cost = NPF_TILE_LENGTH;
+ /* Increase the cost for level crossings */
+ if (IsLevelCrossing(tile)) cost += _patches.npf_crossing_penalty;
+ break;
+
+ default:
+ break;
+ }
+
+ /* Determine extra costs */
+
+ /* Check for slope */
+ cost += NPFSlopeCost(current);
+
+ /* Check for turns. Road vehicles only really drive diagonal, turns are
+ * represented by non-diagonal tracks */
+ if (!IsDiagonalTrackdir(current->direction))
+ cost += _patches.npf_road_curve_penalty;
+
+ NPFMarkTile(tile);
+ DEBUG(npf, 4, "Calculating G for: (%d, %d). Result: %d", TileX(current->tile), TileY(current->tile), cost);
+ return cost;
+}
+
+
+/* Determine the cost of this node, for railway tracks */
+static int32 NPFRailPathCost(AyStar* as, AyStarNode* current, OpenListNode* parent)
+{
+ TileIndex tile = current->tile;
+ Trackdir trackdir = (Trackdir)current->direction;
+ int32 cost = 0;
+ /* HACK: We create a OpenListNode manually, so we can call EndNodeCheck */
+ OpenListNode new_node;
+
+ /* Determine base length */
+ switch (GetTileType(tile)) {
+ case MP_TUNNELBRIDGE:
+ cost = IsTunnel(tile) ? NPFTunnelCost(current) : NPFBridgeCost(current);
+ break;
+
+ case MP_RAILWAY:
+ cost = _trackdir_length[trackdir]; /* Should be different for diagonal tracks */
+ break;
+
+ case MP_STREET: /* Railway crossing */
+ cost = NPF_TILE_LENGTH;
+ break;
+
+ case MP_STATION:
+ /* We give a station tile a penalty. Logically we would only want to give
+ * station tiles that are not our destination this penalty. This would
+ * discourage trains to drive through busy stations. But, we can just
+ * give any station tile a penalty, because every possible route will get
+ * this penalty exactly once, on its end tile (if it's a station) and it
+ * will therefore not make a difference. */
+ cost = NPF_TILE_LENGTH + _patches.npf_rail_station_penalty;
+ break;
+
+ default:
+ break;
+ }
+
+ /* Determine extra costs */
+
+ /* Check for signals */
+ if (IsTileType(tile, MP_RAILWAY) && HasSignalOnTrackdir(tile, trackdir)) {
+ /* Ordinary track with signals */
+ if (GetSignalStateByTrackdir(tile, trackdir) == SIGNAL_STATE_RED) {
+ /* Signal facing us is red */
+ if (!NPFGetFlag(current, NPF_FLAG_SEEN_SIGNAL)) {
+ /* Penalize the first signal we
+ * encounter, if it is red */
+
+ /* Is this a presignal exit or combo? */
+ SignalType sigtype = GetSignalType(tile);
+ if (sigtype == SIGTYPE_EXIT || sigtype == SIGTYPE_COMBO) {
+ /* Penalise exit and combo signals differently (heavier) */
+ cost += _patches.npf_rail_firstred_exit_penalty;
+ } else {
+ cost += _patches.npf_rail_firstred_penalty;
+ }
+ }
+ /* Record the state of this signal */
+ NPFSetFlag(current, NPF_FLAG_LAST_SIGNAL_RED, true);
+ } else {
+ /* Record the state of this signal */
+ NPFSetFlag(current, NPF_FLAG_LAST_SIGNAL_RED, false);
+ }
+ NPFSetFlag(current, NPF_FLAG_SEEN_SIGNAL, true);
+ }
+
+ /* Penalise the tile if it is a target tile and the last signal was
+ * red */
+ /* HACK: We create a new_node here so we can call EndNodeCheck. Ugly as hell
+ * of course... */
+ new_node.path.node = *current;
+ if (as->EndNodeCheck(as, &new_node) == AYSTAR_FOUND_END_NODE && NPFGetFlag(current, NPF_FLAG_LAST_SIGNAL_RED))
+ cost += _patches.npf_rail_lastred_penalty;
+
+ /* Check for slope */
+ cost += NPFSlopeCost(current);
+
+ /* Check for turns */
+ if (current->direction != NextTrackdir((Trackdir)parent->path.node.direction))
+ cost += _patches.npf_rail_curve_penalty;
+ //TODO, with realistic acceleration, also the amount of straight track between
+ // curves should be taken into account, as this affects the speed limit.
+
+ /* Check for reverse in depot */
+ if (IsTileDepotType(tile, TRANSPORT_RAIL) && as->EndNodeCheck(as, &new_node) != AYSTAR_FOUND_END_NODE) {
+ /* Penalise any depot tile that is not the last tile in the path. This
+ * _should_ penalise every occurence of reversing in a depot (and only
+ * that) */
+ cost += _patches.npf_rail_depot_reverse_penalty;
+ }
+
+ /* Check for occupied track */
+ //TODO
+
+ NPFMarkTile(tile);
+ DEBUG(npf, 4, "Calculating G for: (%d, %d). Result: %d", TileX(current->tile), TileY(current->tile), cost);
+ return cost;
+}
+
+/* Will find any depot */
+static int32 NPFFindDepot(AyStar* as, OpenListNode *current)
+{
+ /* It's not worth caching the result with NPF_FLAG_IS_TARGET here as below,
+ * since checking the cache not that much faster than the actual check */
+ return IsTileDepotType(current->path.node.tile, as->user_data[NPF_TYPE]) ?
+ AYSTAR_FOUND_END_NODE : AYSTAR_DONE;
+}
+
+/* Will find a station identified using the NPFFindStationOrTileData */
+static int32 NPFFindStationOrTile(AyStar* as, OpenListNode *current)
+{
+ NPFFindStationOrTileData* fstd = (NPFFindStationOrTileData*)as->user_target;
+ AyStarNode *node = &current->path.node;
+ TileIndex tile = node->tile;
+
+ /* If GetNeighbours said we could get here, we assume the station type
+ * is correct */
+ if (
+ (fstd->station_index == INVALID_STATION && tile == fstd->dest_coords) || /* We've found the tile, or */
+ (IsTileType(tile, MP_STATION) && GetStationIndex(tile) == fstd->station_index) /* the station */
+ ) {
+ return AYSTAR_FOUND_END_NODE;
+ } else {
+ return AYSTAR_DONE;
+ }
+}
+
+/* To be called when current contains the (shortest route to) the target node.
+ * Will fill the contents of the NPFFoundTargetData using
+ * AyStarNode[NPF_TRACKDIR_CHOICE].
+ */
+static void NPFSaveTargetData(AyStar* as, OpenListNode* current)
+{
+ NPFFoundTargetData* ftd = (NPFFoundTargetData*)as->user_path;
+ ftd->best_trackdir = (Trackdir)current->path.node.user_data[NPF_TRACKDIR_CHOICE];
+ ftd->best_path_dist = current->g;
+ ftd->best_bird_dist = 0;
+ ftd->node = current->path.node;
+}
+
+/**
+ * Finds out if a given player's vehicles are allowed to enter a given tile.
+ * @param owner The owner of the vehicle.
+ * @param tile The tile that is about to be entered.
+ * @param enterdir The direction from which the vehicle wants to enter the tile.
+ * @return true if the vehicle can enter the tile.
+ * @todo This function should be used in other places than just NPF,
+ * maybe moved to another file too.
+ */
+static bool VehicleMayEnterTile(Owner owner, TileIndex tile, DiagDirection enterdir)
+{
+ if (IsTileType(tile, MP_RAILWAY) || /* Rail tile (also rail depot) */
+ IsRailwayStationTile(tile) || /* Rail station tile */
+ IsTileDepotType(tile, TRANSPORT_ROAD) || /* Road depot tile */
+ IsRoadStopTile(tile) || /* Road station tile */
+ IsTileDepotType(tile, TRANSPORT_WATER)) { /* Water depot tile */
+ return IsTileOwner(tile, owner); /* You need to own these tiles entirely to use them */
+ }
+
+ switch (GetTileType(tile)) {
+ case MP_STREET:
+ /* rail-road crossing : are we looking at the railway part? */
+ if (IsLevelCrossing(tile) &&
+ DiagDirToAxis(enterdir) != GetCrossingRoadAxis(tile)) {
+ return IsTileOwner(tile, owner); /* Railway needs owner check, while the street is public */
+ }
+ break;
+
+ case MP_TUNNELBRIDGE:
+ if ((IsTunnel(tile) && GetTunnelTransportType(tile) == TRANSPORT_RAIL) ||
+ (IsBridge(tile) && GetBridgeTransportType(tile) == TRANSPORT_RAIL)) {
+ return IsTileOwner(tile, owner);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return true; /* no need to check */
+}
+
+
+/**
+ * Returns the direction the exit of the depot on the given tile is facing.
+ */
+static DiagDirection GetDepotDirection(TileIndex tile, TransportType type)
+{
+ assert(IsTileDepotType(tile, type));
+
+ switch (type) {
+ case TRANSPORT_RAIL: return GetRailDepotDirection(tile);
+ case TRANSPORT_ROAD: return GetRoadDepotDirection(tile);
+ case TRANSPORT_WATER: return GetShipDepotDirection(tile);
+ default: return INVALID_DIAGDIR; /* Not reached */
+ }
+}
+
+
+/* Will just follow the results of GetTileTrackStatus concerning where we can
+ * go and where not. Uses AyStar.user_data[NPF_TYPE] as the transport type and
+ * an argument to GetTileTrackStatus. Will skip tunnels, meaning that the
+ * entry and exit are neighbours. Will fill
+ * AyStarNode.user_data[NPF_TRACKDIR_CHOICE] with an appropriate value, and
+ * copy AyStarNode.user_data[NPF_NODE_FLAGS] from the parent */
+static void NPFFollowTrack(AyStar* aystar, OpenListNode* current)
+{
+ Trackdir src_trackdir = (Trackdir)current->path.node.direction;
+ TileIndex src_tile = current->path.node.tile;
+ DiagDirection src_exitdir = TrackdirToExitdir(src_trackdir);
+ TileIndex dst_tile = INVALID_TILE;
+ int i;
+ TrackdirBits trackdirbits, ts;
+ TransportType type = aystar->user_data[NPF_TYPE];
+ bool override_dst_check = false;
+ /* Initialize to 0, so we can jump out (return) somewhere an have no neighbours */
+ aystar->num_neighbours = 0;
+ DEBUG(npf, 4, "Expanding: (%d, %d, %d) [%d]", TileX(src_tile), TileY(src_tile), src_trackdir, src_tile);
+
+ /* Find dest tile */
+ if (IsTunnelTile(src_tile) && GetTunnelDirection(src_tile) == src_exitdir) {
+ /* This is a tunnel. We know this tunnel is our type,
+ * otherwise we wouldn't have got here. It is also facing us,
+ * so we should skip it's body */
+ dst_tile = GetOtherTunnelEnd(src_tile);
+ override_dst_check = true;
+ } else if (IsBridgeTile(src_tile) && GetBridgeRampDirection(src_tile) == src_exitdir) {
+ dst_tile = GetOtherBridgeEnd(src_tile);
+ override_dst_check = true;
+ } else if (type != TRANSPORT_WATER && (IsRoadStopTile(src_tile) || IsTileDepotType(src_tile, type))) {
+ /* This is a road station or a train or road depot. We can enter and exit
+ * those from one side only. Trackdirs don't support that (yet), so we'll
+ * do this here. */
+
+ DiagDirection exitdir;
+ /* Find out the exit direction first */
+ if (IsRoadStopTile(src_tile)) {
+ exitdir = GetRoadStopDir(src_tile);
+ } else { /* Train or road depot */
+ exitdir = GetDepotDirection(src_tile, type);
+ }
+
+ /* Let's see if were headed the right way into the depot */
+ if (src_trackdir == DiagdirToDiagTrackdir(ReverseDiagDir(exitdir))) {
+ /* We are headed inwards. We cannot go through the back of the depot.
+ * For rail, we can now reverse. Reversing for road vehicles is never
+ * useful, since you cannot take paths you couldn't take before
+ * reversing (as with rail). */
+ if (type == TRANSPORT_RAIL) {
+ /* We can only reverse here, so we'll not consider this direction, but
+ * jump ahead to the reverse direction. It would be nicer to return
+ * one neighbour here (the reverse trackdir of the one we are
+ * considering now) and then considering that one to return the tracks
+ * outside of the depot. But, because the code layout is cleaner this
+ * way, we will just pretend we are reversed already */
+ src_trackdir = ReverseTrackdir(src_trackdir);
+ dst_tile = AddTileIndexDiffCWrap(src_tile, TileIndexDiffCByDiagDir(exitdir));
+ } else {
+ dst_tile = INVALID_TILE; /* Road vehicle heading inwards: dead end */
+ }
+ } else {
+ dst_tile = AddTileIndexDiffCWrap(src_tile, TileIndexDiffCByDiagDir(exitdir));
+ }
+ } else {
+ /* This a normal tile, a bridge, a tunnel exit, etc. */
+ dst_tile = AddTileIndexDiffCWrap(src_tile, TileIndexDiffCByDiagDir(TrackdirToExitdir(src_trackdir)));
+ }
+ if (dst_tile == INVALID_TILE) {
+ /* We reached the border of the map */
+ /* TODO Nicer control flow for this */
+ return;
+ }
+
+ /* I can't enter a tunnel entry/exit tile from a tile above the tunnel. Note
+ * that I can enter the tunnel from a tile below the tunnel entrance. This
+ * solves the problem of vehicles wanting to drive off a tunnel entrance */
+ if (!override_dst_check) {
+ if (IsTileType(dst_tile, MP_TUNNELBRIDGE)) {
+ if (IsTunnel(dst_tile)) {
+ if (GetTunnelDirection(dst_tile) != src_exitdir) return;
+ } else {
+ if (GetBridgeRampDirection(dst_tile) != src_exitdir) return;
+ }
+ }
+ }
+
+ /* check correct rail type (mono, maglev, etc) */
+ if (type == TRANSPORT_RAIL) {
+ RailType dst_type = GetTileRailType(dst_tile, src_trackdir);
+ if (!HASBIT(aystar->user_data[NPF_RAILTYPES], dst_type))
+ return;
+ }
+
+ /* Check the owner of the tile */
+ if (!VehicleMayEnterTile(aystar->user_data[NPF_OWNER], dst_tile, TrackdirToExitdir(src_trackdir))) {
+ return;
+ }
+
+ /* Determine available tracks */
+ if (type != TRANSPORT_WATER && (IsRoadStopTile(dst_tile) || IsTileDepotType(dst_tile, type))){
+ /* Road stations and road and train depots return 0 on GTTS, so we have to do this by hand... */
+ DiagDirection exitdir;
+ if (IsRoadStopTile(dst_tile)) {
+ exitdir = GetRoadStopDir(dst_tile);
+ } else { /* Road or train depot */
+ exitdir = GetDepotDirection(dst_tile, type);
+ }
+ /* Find the trackdirs that are available for a depot or station with this
+ * orientation. They are only "inwards", since we are reaching this tile
+ * from some other tile. This prevents vehicles driving into depots from
+ * the back */
+ ts = TrackdirToTrackdirBits(DiagdirToDiagTrackdir(ReverseDiagDir(exitdir)));
+ } else {
+ ts = GetTileTrackStatus(dst_tile, type);
+ }
+ trackdirbits = ts & TRACKDIR_BIT_MASK; /* Filter out signal status and the unused bits */
+
+ DEBUG(npf, 4, "Next node: (%d, %d) [%d], possible trackdirs: 0x%X", TileX(dst_tile), TileY(dst_tile), dst_tile, trackdirbits);
+ /* Select only trackdirs we can reach from our current trackdir */
+ trackdirbits &= TrackdirReachesTrackdirs(src_trackdir);
+ if (_patches.forbid_90_deg && (type == TRANSPORT_RAIL || type == TRANSPORT_WATER)) /* Filter out trackdirs that would make 90 deg turns for trains */
+ trackdirbits &= ~TrackdirCrossesTrackdirs(src_trackdir);
+
+ DEBUG(npf, 6, "After filtering: (%d, %d), possible trackdirs: 0x%X", TileX(dst_tile), TileY(dst_tile), trackdirbits);
+
+ i = 0;
+ /* Enumerate possible track */
+ while (trackdirbits != 0) {
+ Trackdir dst_trackdir;
+ dst_trackdir = FindFirstBit2x64(trackdirbits);
+ trackdirbits = KillFirstBit2x64(trackdirbits);
+ DEBUG(npf, 5, "Expanded into trackdir: %d, remaining trackdirs: 0x%X", dst_trackdir, trackdirbits);
+
+ /* Check for oneway signal against us */
+ if (IsTileType(dst_tile, MP_RAILWAY) && GetRailTileType(dst_tile) == RAIL_TILE_SIGNALS) {
+ if (HasSignalOnTrackdir(dst_tile, ReverseTrackdir(dst_trackdir)) && !HasSignalOnTrackdir(dst_tile, dst_trackdir))
+ // if one way signal not pointing towards us, stop going in this direction.
+ break;
+ }
+ {
+ /* We've found ourselves a neighbour :-) */
+ AyStarNode* neighbour = &aystar->neighbours[i];
+ neighbour->tile = dst_tile;
+ neighbour->direction = dst_trackdir;
+ /* Save user data */
+ neighbour->user_data[NPF_NODE_FLAGS] = current->path.node.user_data[NPF_NODE_FLAGS];
+ NPFFillTrackdirChoice(neighbour, current);
+ }
+ i++;
+ }
+ aystar->num_neighbours = i;
+}
+
+/*
+ * Plan a route to the specified target (which is checked by target_proc),
+ * from start1 and if not NULL, from start2 as well. The type of transport we
+ * are checking is in type. reverse_penalty is applied to all routes that
+ * originate from the second start node.
+ * When we are looking for one specific target (optionally multiple tiles), we
+ * should use a good heuristic to perform aystar search. When we search for
+ * multiple targets that are spread around, we should perform a breadth first
+ * search by specifiying CalcZero as our heuristic.
+ */
+static NPFFoundTargetData NPFRouteInternal(AyStarNode* start1, AyStarNode* start2, NPFFindStationOrTileData* target, AyStar_EndNodeCheck target_proc, AyStar_CalculateH heuristic_proc, TransportType type, Owner owner, RailTypeMask railtypes, uint reverse_penalty)
+{
+ int r;
+ NPFFoundTargetData result;
+
+ /* Initialize procs */
+ _npf_aystar.CalculateH = heuristic_proc;
+ _npf_aystar.EndNodeCheck = target_proc;
+ _npf_aystar.FoundEndNode = NPFSaveTargetData;
+ _npf_aystar.GetNeighbours = NPFFollowTrack;
+ switch (type) {
+ default: NOT_REACHED();
+ case TRANSPORT_RAIL: _npf_aystar.CalculateG = NPFRailPathCost; break;
+ case TRANSPORT_ROAD: _npf_aystar.CalculateG = NPFRoadPathCost; break;
+ case TRANSPORT_WATER: _npf_aystar.CalculateG = NPFWaterPathCost; break;
+ }
+
+ /* Initialize Start Node(s) */
+ start1->user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR;
+ start1->user_data[NPF_NODE_FLAGS] = 0;
+ _npf_aystar.addstart(&_npf_aystar, start1, 0);
+ if (start2) {
+ start2->user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR;
+ start2->user_data[NPF_NODE_FLAGS] = 0;
+ NPFSetFlag(start2, NPF_FLAG_REVERSE, true);
+ _npf_aystar.addstart(&_npf_aystar, start2, reverse_penalty);
+ }
+
+ /* Initialize result */
+ result.best_bird_dist = (uint)-1;
+ result.best_path_dist = (uint)-1;
+ result.best_trackdir = INVALID_TRACKDIR;
+ _npf_aystar.user_path = &result;
+
+ /* Initialize target */
+ _npf_aystar.user_target = target;
+
+ /* Initialize user_data */
+ _npf_aystar.user_data[NPF_TYPE] = type;
+ _npf_aystar.user_data[NPF_OWNER] = owner;
+ _npf_aystar.user_data[NPF_RAILTYPES] = railtypes;
+
+ /* GO! */
+ r = AyStarMain_Main(&_npf_aystar);
+ assert(r != AYSTAR_STILL_BUSY);
+
+ if (result.best_bird_dist != 0) {
+ if (target != NULL) {
+ DEBUG(npf, 1, "Could not find route to tile 0x%X from 0x%X.", target->dest_coords, start1->tile);
+ } else {
+ /* Assumption: target == NULL, so we are looking for a depot */
+ DEBUG(npf, 1, "Could not find route to a depot from tile 0x%X.", start1->tile);
+ }
+
+ }
+ return result;
+}
+
+NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailTypeMask railtypes)
+{
+ AyStarNode start1;
+ AyStarNode start2;
+
+ start1.tile = tile1;
+ start2.tile = tile2;
+ /* We set this in case the target is also the start tile, we will just
+ * return a not found then */
+ start1.user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR;
+ start1.direction = trackdir1;
+ start2.direction = trackdir2;
+ start2.user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR;
+
+ return NPFRouteInternal(&start1, (IsValidTile(tile2) ? &start2 : NULL), target, NPFFindStationOrTile, NPFCalcStationOrTileHeuristic, type, owner, railtypes, 0);
+}
+
+NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailTypeMask railtypes)
+{
+ return NPFRouteToStationOrTileTwoWay(tile, trackdir, INVALID_TILE, 0, target, type, owner, railtypes);
+}
+
+NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, TransportType type, Owner owner, RailTypeMask railtypes, uint reverse_penalty)
+{
+ AyStarNode start1;
+ AyStarNode start2;
+
+ start1.tile = tile1;
+ start2.tile = tile2;
+ /* We set this in case the target is also the start tile, we will just
+ * return a not found then */
+ start1.user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR;
+ start1.direction = trackdir1;
+ start2.direction = trackdir2;
+ start2.user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR;
+
+ /* perform a breadth first search. Target is NULL,
+ * since we are just looking for any depot...*/
+ return NPFRouteInternal(&start1, (IsValidTile(tile2) ? &start2 : NULL), NULL, NPFFindDepot, NPFCalcZero, type, owner, railtypes, reverse_penalty);
+}
+
+NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailTypeMask railtypes)
+{
+ return NPFRouteToDepotBreadthFirstTwoWay(tile, trackdir, INVALID_TILE, 0, type, owner, railtypes, 0);
+}
+
+NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailTypeMask railtypes)
+{
+ /* Okay, what we're gonna do. First, we look at all depots, calculate
+ * the manhatten distance to get to each depot. We then sort them by
+ * distance. We start by trying to plan a route to the closest, then
+ * the next closest, etc. We stop when the best route we have found so
+ * far, is shorter than the manhattan distance. This will obviously
+ * always find the closest depot. It will probably be most efficient
+ * for ships, since the heuristic will not be to far off then. I hope.
+ */
+ Queue depots;
+ int r;
+ NPFFoundTargetData best_result = {(uint)-1, (uint)-1, INVALID_TRACKDIR, {INVALID_TILE, 0, {0, 0}}};
+ NPFFoundTargetData result;
+ NPFFindStationOrTileData target;
+ AyStarNode start;
+ Depot* current;
+ Depot *depot;
+
+ init_InsSort(&depots);
+ /* Okay, let's find all depots that we can use first */
+ FOR_ALL_DEPOTS(depot) {
+ /* Check if this is really a valid depot, it is of the needed type and
+ * owner */
+ if (IsTileDepotType(depot->xy, type) && IsTileOwner(depot->xy, owner))
+ /* If so, let's add it to the queue, sorted by distance */
+ depots.push(&depots, depot, DistanceManhattan(tile, depot->xy));
+ }
+
+ /* Now, let's initialise the aystar */
+
+ /* Initialize procs */
+ _npf_aystar.CalculateH = NPFCalcStationOrTileHeuristic;
+ _npf_aystar.EndNodeCheck = NPFFindStationOrTile;
+ _npf_aystar.FoundEndNode = NPFSaveTargetData;
+ _npf_aystar.GetNeighbours = NPFFollowTrack;
+ switch (type) {
+ default: NOT_REACHED();
+ case TRANSPORT_RAIL: _npf_aystar.CalculateG = NPFRailPathCost; break;
+ case TRANSPORT_ROAD: _npf_aystar.CalculateG = NPFRoadPathCost; break;
+ case TRANSPORT_WATER: _npf_aystar.CalculateG = NPFWaterPathCost; break;
+ }
+
+ /* Initialize target */
+ target.station_index = INVALID_STATION; /* We will initialize dest_coords inside the loop below */
+ _npf_aystar.user_target = &target;
+
+ /* Initialize user_data */
+ _npf_aystar.user_data[NPF_TYPE] = type;
+ _npf_aystar.user_data[NPF_OWNER] = owner;
+
+ /* Initialize Start Node */
+ start.tile = tile;
+ start.direction = trackdir; /* We will initialize user_data inside the loop below */
+
+ /* Initialize Result */
+ _npf_aystar.user_path = &result;
+ best_result.best_path_dist = (uint)-1;
+ best_result.best_bird_dist = (uint)-1;
+
+ /* Just iterate the depots in order of increasing distance */
+ while ((current = depots.pop(&depots))) {
+ /* Check to see if we already have a path shorter than this
+ * depot's manhattan distance. HACK: We call DistanceManhattan
+ * again, we should probably modify the queue to give us that
+ * value... */
+ if ( DistanceManhattan(tile, current->xy * NPF_TILE_LENGTH) > best_result.best_path_dist)
+ break;
+
+ /* Initialize Start Node */
+ /* We set this in case the target is also the start tile, we will just
+ * return a not found then */
+ start.user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR;
+ start.user_data[NPF_NODE_FLAGS] = 0;
+ _npf_aystar.addstart(&_npf_aystar, &start, 0);
+
+ /* Initialize result */
+ result.best_bird_dist = (uint)-1;
+ result.best_path_dist = (uint)-1;
+ result.best_trackdir = INVALID_TRACKDIR;
+
+ /* Initialize target */
+ target.dest_coords = current->xy;
+
+ /* GO! */
+ r = AyStarMain_Main(&_npf_aystar);
+ assert(r != AYSTAR_STILL_BUSY);
+
+ /* This depot is closer */
+ if (result.best_path_dist < best_result.best_path_dist)
+ best_result = result;
+ }
+ if (result.best_bird_dist != 0) {
+ DEBUG(npf, 1, "Could not find route to any depot from tile 0x%X.", tile);
+ }
+ return best_result;
+}
+
+void InitializeNPF(void)
+{
+ init_AyStar(&_npf_aystar, NPFHash, NPF_HASH_SIZE);
+ _npf_aystar.loops_per_tick = 0;
+ _npf_aystar.max_path_cost = 0;
+ //_npf_aystar.max_search_nodes = 0;
+ /* We will limit the number of nodes for now, until we have a better
+ * solution to really fix performance */
+ _npf_aystar.max_search_nodes = _patches.npf_max_search_nodes;
+}
+
+void NPFFillWithOrderData(NPFFindStationOrTileData* fstd, Vehicle* v)
+{
+ /* Ships don't really reach their stations, but the tile in front. So don't
+ * save the station id for ships. For roadvehs we don't store it either,
+ * because multistop depends on vehicles actually reaching the exact
+ * dest_tile, not just any stop of that station.
+ * So only for train orders to stations we fill fstd->station_index, for all
+ * others only dest_coords */
+ if (v->current_order.type == OT_GOTO_STATION && v->type == VEH_Train) {
+ fstd->station_index = v->current_order.dest;
+ /* Let's take the closest tile of the station as our target for trains */
+ fstd->dest_coords = CalcClosestStationTile(v->current_order.dest, v->tile);
+ } else {
+ fstd->dest_coords = v->dest_tile;
+ fstd->station_index = INVALID_STATION;
+ }
+}
diff --git a/src/npf.h b/src/npf.h
new file mode 100644
index 000000000..653d31b9a
--- /dev/null
+++ b/src/npf.h
@@ -0,0 +1,121 @@
+/* $Id$ */
+
+#ifndef NPF_H
+#define NPF_H
+
+#include "openttd.h"
+#include "aystar.h"
+#include "station.h"
+#include "vehicle.h"
+#include "tile.h"
+
+//mowing grass
+enum {
+ NPF_HASH_BITS = 12, /* The size of the hash used in pathfinding. Just changing this value should be sufficient to change the hash size. Should be an even value. */
+ /* Do no change below values */
+ NPF_HASH_SIZE = 1 << NPF_HASH_BITS,
+ NPF_HASH_HALFBITS = NPF_HASH_BITS / 2,
+ NPF_HASH_HALFMASK = (1 << NPF_HASH_HALFBITS) - 1
+};
+
+/* For new pathfinding. Define here so it is globally available without having
+ * to include npf.h */
+enum {
+ NPF_TILE_LENGTH = 100
+};
+
+enum {
+ /** This penalty is the equivalent of "inifite", which means that paths that
+ * get this penalty will be chosen, but only if there is no other route
+ * without it. Be careful with not applying this penalty to often, or the
+ * total path cost might overflow..
+ * For now, this is just a Very Big Penalty, we might actually implement
+ * this in a nicer way :-)
+ */
+ NPF_INFINITE_PENALTY = 1000 * NPF_TILE_LENGTH
+};
+
+typedef struct NPFFindStationOrTileData { /* Meant to be stored in AyStar.targetdata */
+ TileIndex dest_coords; /* An indication of where the station is, for heuristic purposes, or the target tile */
+ StationID station_index; /* station index we're heading for, or INVALID_STATION when we're heading for a tile */
+} NPFFindStationOrTileData;
+
+enum { /* Indices into AyStar.userdata[] */
+ NPF_TYPE = 0, /* Contains a TransportTypes value */
+ NPF_OWNER, /* Contains an Owner value */
+ NPF_RAILTYPES, /* Contains a bitmask the compatible RailTypes of the engine when NPF_TYPE == TRANSPORT_RAIL. Unused otherwise. */
+};
+
+enum { /* Indices into AyStarNode.userdata[] */
+ NPF_TRACKDIR_CHOICE = 0, /* The trackdir chosen to get here */
+ NPF_NODE_FLAGS,
+};
+
+typedef enum { /* Flags for AyStarNode.userdata[NPF_NODE_FLAGS]. Use NPFGetBit() and NPFGetBit() to use them. */
+ NPF_FLAG_SEEN_SIGNAL, /* Used to mark that a signal was seen on the way, for rail only */
+ NPF_FLAG_REVERSE, /* Used to mark that this node was reached from the second start node, if applicable */
+ NPF_FLAG_LAST_SIGNAL_RED, /* Used to mark that the last signal on this path was red */
+} NPFNodeFlag;
+
+typedef struct NPFFoundTargetData { /* Meant to be stored in AyStar.userpath */
+ uint best_bird_dist; /* The best heuristic found. Is 0 if the target was found */
+ uint best_path_dist; /* The shortest path. Is (uint)-1 if no path is found */
+ Trackdir best_trackdir; /* The trackdir that leads to the shortest path/closest birds dist */
+ AyStarNode node; /* The node within the target the search led us to */
+} NPFFoundTargetData;
+
+/* These functions below are _not_ re-entrant, in favor of speed! */
+
+/* Will search from the given tile and direction, for a route to the given
+ * station for the given transport type. See the declaration of
+ * NPFFoundTargetData above for the meaning of the result. */
+NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailTypeMask railtypes);
+
+/* Will search as above, but with two start nodes, the second being the
+ * reverse. Look at the NPF_FLAG_REVERSE flag in the result node to see which
+ * direction was taken (NPFGetBit(result.node, NPF_FLAG_REVERSE)) */
+NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailTypeMask railtypes);
+
+/* Will search a route to the closest depot. */
+
+/* Search using breadth first. Good for little track choice and inaccurate
+ * heuristic, such as railway/road.*/
+NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailTypeMask railtypes);
+/* Same as above but with two start nodes, the second being the reverse. Call
+ * NPFGetBit(result.node, NPF_FLAG_REVERSE) to see from which node the path
+ * orginated. All pathfs from the second node will have the given
+ * reverse_penalty applied (NPF_TILE_LENGTH is the equivalent of one full
+ * tile).
+ */
+NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, TransportType type, Owner owner, RailTypeMask railtypes, uint reverse_penalty);
+/* Search by trying each depot in order of Manhattan Distance. Good for lots
+ * of choices and accurate heuristics, such as water. */
+NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailTypeMask railtypes);
+
+void NPFFillWithOrderData(NPFFindStationOrTileData* fstd, Vehicle* v);
+
+
+/*
+ * Functions to manipulate the various NPF related flags on an AyStarNode.
+ */
+
+/**
+ * Returns the current value of the given flag on the given AyStarNode.
+ */
+static inline bool NPFGetFlag(const AyStarNode* node, NPFNodeFlag flag)
+{
+ return HASBIT(node->user_data[NPF_NODE_FLAGS], flag);
+}
+
+/**
+ * Sets the given flag on the given AyStarNode to the given value.
+ */
+static inline void NPFSetFlag(AyStarNode* node, NPFNodeFlag flag, bool value)
+{
+ if (value)
+ SETBIT(node->user_data[NPF_NODE_FLAGS], flag);
+ else
+ CLRBIT(node->user_data[NPF_NODE_FLAGS], flag);
+}
+
+#endif /* NPF_H */
diff --git a/src/oldloader.c b/src/oldloader.c
new file mode 100644
index 000000000..f6a56fdd6
--- /dev/null
+++ b/src/oldloader.c
@@ -0,0 +1,1583 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "station_map.h"
+#include "table/strings.h"
+#include "functions.h"
+#include "map.h"
+#include "town.h"
+#include "industry.h"
+#include "station.h"
+#include "economy.h"
+#include "player.h"
+#include "engine.h"
+#include "vehicle.h"
+#include "signs.h"
+#include "debug.h"
+#include "depot.h"
+#include "network/network.h"
+#include "ai/ai.h"
+#include "date.h"
+
+enum {
+ HEADER_SIZE = 49,
+ BUFFER_SIZE = 4096,
+
+ OLD_MAP_SIZE = 256 * 256
+};
+
+typedef struct LoadgameState {
+ FILE *file;
+
+ uint chunk_size;
+
+ bool decoding;
+ byte decode_char;
+
+ uint buffer_count;
+ uint buffer_cur;
+ byte buffer[BUFFER_SIZE];
+
+ uint total_read;
+ bool failed;
+} LoadgameState;
+
+/* OldChunk-Type */
+typedef enum OldChunkTypes {
+ OC_SIMPLE = 0,
+ OC_NULL = 1,
+ OC_CHUNK = 2,
+ OC_ASSERT = 3,
+ /* 8 bytes allocated (256 max) */
+
+ OC_VAR_I8 = 1 << 8,
+ OC_VAR_U8 = 2 << 8,
+ OC_VAR_I16 = 3 << 8,
+ OC_VAR_U16 = 4 << 8,
+ OC_VAR_I32 = 5 << 8,
+ OC_VAR_U32 = 6 << 8,
+ OC_VAR_I64 = 7 << 8,
+ /* 8 bytes allocated (256 max) */
+
+ OC_FILE_I8 = 1 << 16,
+ OC_FILE_U8 = 2 << 16,
+ OC_FILE_I16 = 3 << 16,
+ OC_FILE_U16 = 4 << 16,
+ OC_FILE_I32 = 5 << 16,
+ OC_FILE_U32 = 6 << 16,
+ /* 8 bytes allocated (256 max) */
+
+ OC_INT8 = OC_VAR_I8 | OC_FILE_I8,
+ OC_UINT8 = OC_VAR_U8 | OC_FILE_U8,
+ OC_INT16 = OC_VAR_I16 | OC_FILE_I16,
+ OC_UINT16 = OC_VAR_U16 | OC_FILE_U16,
+ OC_INT32 = OC_VAR_I32 | OC_FILE_I32,
+ OC_UINT32 = OC_VAR_U32 | OC_FILE_U32,
+
+ OC_TILE = OC_VAR_U32 | OC_FILE_U16,
+
+ OC_END = 0 ///< End of the whole chunk, all 32bits set to zero
+} OldChunkType;
+
+typedef bool OldChunkProc(LoadgameState *ls, int num);
+
+typedef struct OldChunks {
+ OldChunkType type; ///< Type of field
+ uint32 amount; ///< Amount of fields
+
+ void *ptr; ///< Pointer where to save the data (may only be set if offset is 0)
+ uint offset; ///< Offset from basepointer (may only be set if ptr is NULL)
+ OldChunkProc *proc; ///< Pointer to function that is called with OC_CHUNK
+} OldChunks;
+
+/* If it fails, check lines above.. */
+assert_compile(sizeof(TileIndex) == 4);
+
+static uint32 _bump_assert_value;
+static bool _read_ttdpatch_flags;
+
+static OldChunkType GetOldChunkType(OldChunkType type) {return GB(type, 0, 8);}
+static OldChunkType GetOldChunkVarType(OldChunkType type) {return GB(type, 8, 8) << 8;}
+static OldChunkType GetOldChunkFileType(OldChunkType type) {return GB(type, 16, 8) << 16;}
+
+static inline byte CalcOldVarLen(OldChunkType type)
+{
+ static const byte type_mem_size[] = {0, 1, 1, 2, 2, 4, 4, 8};
+ byte length = GB(type, 8, 8);
+ assert(length != 0 && length < lengthof(type_mem_size));
+ return type_mem_size[length];
+}
+
+/**
+ *
+ * Reads a byte from a file (do not call yourself, use ReadByte())
+ *
+ */
+static byte ReadByteFromFile(LoadgameState *ls)
+{
+ /* To avoid slow reads, we read BUFFER_SIZE of bytes per time
+ and just return a byte per time */
+ if (ls->buffer_cur >= ls->buffer_count) {
+ /* Read some new bytes from the file */
+ int count = (int)fread(ls->buffer, 1, BUFFER_SIZE, ls->file);
+
+ /* We tried to read, but there is nothing in the file anymore.. */
+ if (count == 0) {
+ DEBUG(oldloader, 0, "Read past end of file, loading failed");
+ ls->failed = true;
+ }
+
+ ls->buffer_count = count;
+ ls->buffer_cur = 0;
+ }
+
+ return ls->buffer[ls->buffer_cur++];
+}
+
+/**
+ *
+ * Reads a byte from the buffer and decompress if needed
+ *
+ */
+static byte ReadByte(LoadgameState *ls)
+{
+ /* Old savegames have a nice compression algorithm (RLE)
+ which means that we have a chunk, which starts with a length
+ byte. If that byte is negative, we have to repeat the next byte
+ that many times (+1). Else, we need to read that amount of bytes.
+ Works pretty good if you have many zero's behind eachother */
+
+ if (ls->chunk_size == 0) {
+ /* Read new chunk */
+ int8 new_byte = ReadByteFromFile(ls);
+
+ if (new_byte < 0) {
+ /* Repeat next char for new_byte times */
+ ls->decoding = true;
+ ls->decode_char = ReadByteFromFile(ls);
+ ls->chunk_size = -new_byte + 1;
+ } else {
+ ls->decoding = false;
+ ls->chunk_size = new_byte + 1;
+ }
+ }
+
+ ls->total_read++;
+ ls->chunk_size--;
+
+ return ls->decoding ? ls->decode_char : ReadByteFromFile(ls);
+}
+
+static inline uint16 ReadUint16(LoadgameState *ls)
+{
+ byte x = ReadByte(ls);
+ return x | ReadByte(ls) << 8;
+}
+
+static inline uint32 ReadUint32(LoadgameState *ls)
+{
+ uint16 x = ReadUint16(ls);
+ return x | ReadUint16(ls) << 16;
+}
+
+/**
+ *
+ * Loads a chunk from the old savegame
+ *
+ */
+static bool LoadChunk(LoadgameState *ls, void *base, const OldChunks *chunks)
+{
+ const OldChunks *chunk = chunks;
+ byte *base_ptr = base;
+
+ while (chunk->type != OC_END) {
+ byte* ptr = chunk->ptr;
+ uint i;
+
+ for (i = 0; i < chunk->amount; i++) {
+ if (ls->failed) return false;
+
+ /* Handle simple types */
+ if (GetOldChunkType(chunk->type) != 0) {
+ switch (GetOldChunkType(chunk->type)) {
+ /* Just read the byte and forget about it */
+ case OC_NULL: ReadByte(ls); break;
+
+ case OC_CHUNK:
+ /* Call function, with 'i' as parameter to tell which item we
+ * are going to read */
+ if (!chunk->proc(ls, i)) return false;
+ break;
+
+ case OC_ASSERT:
+ DEBUG(oldloader, 4, "Assert point: 0x%X / 0x%X", ls->total_read, chunk->offset + _bump_assert_value);
+ if (ls->total_read != chunk->offset + _bump_assert_value) ls->failed = true;
+ default: break;
+ }
+ } else {
+ uint32 res = 0;
+
+ /* Reading from the file: bits 16 to 23 have the FILE type */
+ switch (GetOldChunkFileType(chunk->type)) {
+ case OC_FILE_I8: res = (int8)ReadByte(ls); break;
+ case OC_FILE_U8: res = ReadByte(ls); break;
+ case OC_FILE_I16: res = (int16)ReadUint16(ls); break;
+ case OC_FILE_U16: res = ReadUint16(ls); break;
+ case OC_FILE_I32: res = (int32)ReadUint32(ls); break;
+ case OC_FILE_U32: res = ReadUint32(ls); break;
+ default: NOT_REACHED();
+ }
+
+ /* Sanity check */
+ assert(base_ptr != NULL || chunk->ptr != NULL);
+
+ /* Writing to the var: bits 8 to 15 have the VAR type */
+ if (chunk->ptr == NULL) ptr = base_ptr + chunk->offset;
+
+ /* Write the data */
+ switch (GetOldChunkVarType(chunk->type)) {
+ case OC_VAR_I8: *(int8 *)ptr = GB(res, 0, 8); break;
+ case OC_VAR_U8: *(uint8 *)ptr = GB(res, 0, 8); break;
+ case OC_VAR_I16:*(int16 *)ptr = GB(res, 0, 16); break;
+ case OC_VAR_U16:*(uint16*)ptr = GB(res, 0, 16); break;
+ case OC_VAR_I32:*(int32 *)ptr = res; break;
+ case OC_VAR_U32:*(uint32*)ptr = res; break;
+ case OC_VAR_I64:*(int64 *)ptr = res; break;
+ default: NOT_REACHED();
+ }
+
+ /* Increase pointer base for arrays when looping */
+ if (chunk->amount > 1 && chunk->ptr != NULL) ptr += CalcOldVarLen(chunk->type);
+ }
+ }
+
+ chunk++;
+ }
+
+ return true;
+}
+
+/**
+ *
+ * Initialize some data before reading
+ *
+ */
+static void InitLoading(LoadgameState *ls)
+{
+ ls->chunk_size = 0;
+ ls->total_read = 0;
+ ls->failed = false;
+
+ ls->decoding = false;
+ ls->decode_char = 0;
+
+ ls->buffer_cur = 0;
+ ls->buffer_count = 0;
+ memset(ls->buffer, 0, BUFFER_SIZE);
+
+ _bump_assert_value = 0;
+
+ _read_ttdpatch_flags = false;
+}
+
+
+/*
+ * Begin -- Stuff to fix the savegames to be OpenTTD compatible
+ */
+
+extern uint32 GetOldTownName(uint32 townnameparts, byte old_town_name_type);
+
+static void FixOldTowns(void)
+{
+ Town *town;
+
+ /* Convert town-names if needed */
+ FOR_ALL_TOWNS(town) {
+ if (IS_INT_INSIDE(town->townnametype, 0x20C1, 0x20C3)) {
+ town->townnametype = SPECSTR_TOWNNAME_ENGLISH + _opt.town_name;
+ town->townnameparts = GetOldTownName(town->townnameparts, _opt.town_name);
+ }
+ }
+}
+
+static void FixOldStations(void)
+{
+ Station *st;
+
+ FOR_ALL_STATIONS(st) {
+ /* Check if we need to swap width and height for the station */
+ if (st->train_tile != 0 && GetRailStationAxis(st->train_tile) != AXIS_X) {
+ swap_byte(&st->trainst_w, &st->trainst_h);
+ }
+
+ /* Check if there is a bus or truck station, and convert to new format */
+ if (st->bus_tile_obsolete != 0) {
+ st->bus_stops = AllocateRoadStop();
+ st->bus_stops->xy = st->bus_tile_obsolete;
+ st->bus_stops->used = true;
+ st->bus_stops->status = 3;
+ st->bus_stops->station = st->index;
+ st->bus_stops->next = NULL;
+ st->bus_stops->prev = NULL;
+ st->bus_stops->num_vehicles = 0;
+ }
+
+ if (st->lorry_tile_obsolete != 0) {
+ st->truck_stops = AllocateRoadStop();
+ st->truck_stops->xy = st->lorry_tile_obsolete;
+ st->truck_stops->used = true;
+ st->truck_stops->status = 3;
+ st->truck_stops->station = st->index;
+ st->truck_stops->next = NULL;
+ st->truck_stops->prev = NULL;
+ st->truck_stops->num_vehicles = 0;
+ }
+ }
+}
+
+static void FixOldVehicles(void)
+{
+ /* Check for shared orders, and link them correctly */
+ Vehicle* v;
+
+ FOR_ALL_VEHICLES(v) {
+ Vehicle *u;
+
+ FOR_ALL_VEHICLES_FROM(u, v->index + 1) {
+ /* If a vehicle has the same orders, add the link to eachother
+ * in both vehicles */
+ if (v->orders == u->orders) {
+ v->next_shared = u;
+ u->prev_shared = v;
+ break;
+ }
+ }
+ }
+}
+
+/*
+ * End -- Stuff to fix the savegames to be OpenTTD compatible
+ */
+
+
+/* Help:
+ * - OCL_SVAR: load 'type' to offset 'offset' in a struct of type 'base', which must also
+ * be given via base in LoadChunk() as real pointer
+ * - OCL_VAR: load 'type' to a global var
+ * - OCL_END: every struct must end with this
+ * - OCL_NULL: read 'amount' of bytes and send them to /dev/null or something
+ * - OCL_CHUNK: load an other proc to load a part of the savegame, 'amount' times
+ * - OCL_ASSERT: to check if we are really at the place we expect to be.. because old savegames are too binary to be sure ;)
+ */
+#define OCL_SVAR(type, base, offset) { type, 1, NULL, (uint)offsetof(base, offset), NULL }
+#define OCL_VAR(type, amount, pointer) { type, amount, pointer, 0, NULL }
+#define OCL_END() { OC_END, 0, NULL, 0, NULL }
+#define OCL_NULL(amount) { OC_NULL, amount, NULL, 0, NULL }
+#define OCL_CHUNK(amount, proc) { OC_CHUNK, amount, NULL, 0, proc }
+#define OCL_ASSERT(size) { OC_ASSERT, 1, NULL, size, NULL }
+
+/* The savegames has some hard-coded pointers, because it always enters the same
+ piece of memory.. we don't.. so we need to remap ;)
+ Old Towns are 94 bytes big
+ Old Orders are 2 bytes big */
+#define REMAP_TOWN_IDX(x) ((x) - (0x0459154 - 0x0458EF0)) / 94
+#define REMAP_ORDER_IDX(x) ((x) - (0x045AB08 - 0x0458EF0)) / 2
+
+extern TileIndex _animated_tile_list[256];
+extern char _name_array[512][32];
+
+static byte _old_vehicle_multiplier;
+static uint8 _old_map3[OLD_MAP_SIZE * 2];
+static bool _new_ttdpatch_format;
+static uint32 _old_town_index;
+static uint16 _old_string_id;
+static uint16 _old_string_id_2;
+
+static void ReadTTDPatchFlags(void)
+{
+ int i;
+
+ if (_read_ttdpatch_flags) return;
+
+ _read_ttdpatch_flags = true;
+
+ /* TTDPatch misuses _old_map3 for flags.. read them! */
+ _old_vehicle_multiplier = _old_map3[0];
+ /* Somehow.... there was an error in some savegames, so 0 becomes 1
+ and 1 becomes 2. The rest of the values are okay */
+ if (_old_vehicle_multiplier < 2) _old_vehicle_multiplier++;
+
+ /* TTDPatch incraeses the Vehicle-part in the middle of the game,
+ so if the multipler is anything else but 1, the assert fails..
+ bump the assert value so it doesn't!
+ (1 multipler == 850 vehicles
+ 1 vehicle == 128 bytes */
+ _bump_assert_value = (_old_vehicle_multiplier - 1) * 850 * 128;
+
+ /* Check if we have a modern TTDPatch savegame (has extra data all around) */
+ _new_ttdpatch_format = (memcmp(&_old_map3[0x1FFFA], "TTDp", 4) == 0);
+
+ /* Clean the misused places */
+ for (i = 0; i < 17; i++) _old_map3[i] = 0;
+ for (i = 0x1FE00; i < 0x20000; i++) _old_map3[i] = 0;
+
+ if (_new_ttdpatch_format) DEBUG(oldloader, 1, "Found TTDPatch game");
+
+ DEBUG(oldloader, 1, "Vehicle-multiplier is set to %d (%d vehicles)", _old_vehicle_multiplier, _old_vehicle_multiplier * 850);
+}
+
+static const OldChunks town_chunk[] = {
+ OCL_SVAR( OC_TILE, Town, xy ),
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, population ),
+ OCL_SVAR( OC_UINT16, Town, townnametype ),
+ OCL_SVAR( OC_UINT32, Town, townnameparts ),
+ OCL_SVAR( OC_UINT8, Town, grow_counter ),
+ OCL_NULL( 1 ), // sort_index, no longer in use
+ OCL_NULL( 4 ), // sign-coordinates, no longer in use
+ OCL_NULL( 2 ), // namewidth, no longer in use
+ OCL_SVAR( OC_UINT16, Town, flags12 ),
+ OCL_NULL( 10 ), // radius, no longer in use
+
+ OCL_SVAR( OC_UINT16, Town, ratings[0] ),
+ OCL_SVAR( OC_UINT16, Town, ratings[1] ),
+ OCL_SVAR( OC_UINT16, Town, ratings[2] ),
+ OCL_SVAR( OC_UINT16, Town, ratings[3] ),
+ OCL_SVAR( OC_UINT16, Town, ratings[4] ),
+ OCL_SVAR( OC_UINT16, Town, ratings[5] ),
+ OCL_SVAR( OC_UINT16, Town, ratings[6] ),
+ OCL_SVAR( OC_UINT16, Town, ratings[7] ),
+
+ /* XXX - This is pretty odd.. we read 32bit, but only write 8bit.. sure there is
+ nothing changed?? */
+ OCL_SVAR( OC_FILE_U32 | OC_VAR_U8, Town, have_ratings ),
+ OCL_SVAR( OC_FILE_U32 | OC_VAR_U8, Town, statues ),
+ OCL_SVAR( OC_UINT16, Town, num_houses ),
+ OCL_SVAR( OC_UINT8, Town, time_until_rebuild ),
+ OCL_SVAR( OC_UINT8, Town, growth_rate ),
+
+ OCL_SVAR( OC_UINT16, Town, new_max_pass ),
+ OCL_SVAR( OC_UINT16, Town, new_max_mail ),
+ OCL_SVAR( OC_UINT16, Town, new_act_pass ),
+ OCL_SVAR( OC_UINT16, Town, new_act_mail ),
+ OCL_SVAR( OC_UINT16, Town, max_pass ),
+ OCL_SVAR( OC_UINT16, Town, max_mail ),
+ OCL_SVAR( OC_UINT16, Town, act_pass ),
+ OCL_SVAR( OC_UINT16, Town, act_mail ),
+
+ OCL_SVAR( OC_UINT8, Town, pct_pass_transported ),
+ OCL_SVAR( OC_UINT8, Town, pct_mail_transported ),
+
+ OCL_SVAR( OC_UINT16, Town, new_act_food ),
+ OCL_SVAR( OC_UINT16, Town, new_act_water ),
+ OCL_SVAR( OC_UINT16, Town, act_food ),
+ OCL_SVAR( OC_UINT16, Town, act_water ),
+
+ OCL_SVAR( OC_UINT8, Town, road_build_months ),
+ OCL_SVAR( OC_UINT8, Town, fund_buildings_months ),
+
+ OCL_NULL( 8 ), // some junk at the end of the record
+
+ OCL_END()
+};
+static bool LoadOldTown(LoadgameState *ls, int num)
+{
+ if (!AddBlockIfNeeded(&_Town_pool, num))
+ error("Towns: failed loading savegame: too many towns");
+
+ return LoadChunk(ls, GetTown(num), town_chunk);
+}
+
+static uint16 _old_order;
+static const OldChunks order_chunk[] = {
+ OCL_VAR ( OC_UINT16, 1, &_old_order ),
+ OCL_END()
+};
+
+static bool LoadOldOrder(LoadgameState *ls, int num)
+{
+ if (!AddBlockIfNeeded(&_Order_pool, num))
+ error("Orders: failed loading savegame: too many orders");
+
+ if (!LoadChunk(ls, NULL, order_chunk)) return false;
+
+ AssignOrder(GetOrder(num), UnpackOldOrder(_old_order));
+
+ /* Relink the orders to eachother (in TTD(Patch) the orders for one
+ vehicle are behind eachother, with OT_NOTHING as indication that
+ it is the last order */
+ if (num > 0 && GetOrder(num)->type != OT_NOTHING)
+ GetOrder(num - 1)->next = GetOrder(num);
+
+ return true;
+}
+
+static const OldChunks depot_chunk[] = {
+ OCL_SVAR( OC_TILE, Depot, xy ),
+ OCL_VAR ( OC_UINT32, 1, &_old_town_index ),
+ OCL_END()
+};
+
+static bool LoadOldDepot(LoadgameState *ls, int num)
+{
+ if (!AddBlockIfNeeded(&_Depot_pool, num))
+ error("Depots: failed loading savegame: too many depots");
+
+ if (!LoadChunk(ls, GetDepot(num), depot_chunk)) return false;
+
+ if (IsValidDepot(GetDepot(num))) {
+ GetDepot(num)->town_index = REMAP_TOWN_IDX(_old_town_index);
+ }
+
+ return true;
+}
+
+static int32 _old_price;
+static uint16 _old_price_frac;
+static const OldChunks price_chunk[] = {
+ OCL_VAR ( OC_INT32, 1, &_old_price ),
+ OCL_VAR ( OC_UINT16, 1, &_old_price_frac ),
+ OCL_END()
+};
+
+static bool LoadOldPrice(LoadgameState *ls, int num)
+{
+ if (!LoadChunk(ls, NULL, price_chunk)) return false;
+
+ /* We use a struct to store the prices, but they are ints in a row..
+ so just access the struct as an array of int32's */
+ ((int32*)&_price)[num] = _old_price;
+ _price_frac[num] = _old_price_frac;
+
+ return true;
+}
+
+static const OldChunks cargo_payment_rate_chunk[] = {
+ OCL_VAR ( OC_INT32, 1, &_old_price ),
+ OCL_VAR ( OC_UINT16, 1, &_old_price_frac ),
+
+ OCL_NULL( 2 ), // Junk
+ OCL_END()
+};
+
+static bool LoadOldCargoPaymentRate(LoadgameState *ls, int num)
+{
+ if (!LoadChunk(ls, NULL, cargo_payment_rate_chunk)) return false;
+
+ _cargo_payment_rates[num] = -_old_price;
+ _cargo_payment_rates_frac[num] = _old_price_frac;
+
+ return true;
+}
+
+static uint8 _old_platforms;
+static uint _current_station_id;
+
+static const OldChunks goods_chunk[] = {
+ OCL_SVAR( OC_UINT16, GoodsEntry, waiting_acceptance ),
+ OCL_SVAR( OC_UINT8, GoodsEntry, days_since_pickup ),
+ OCL_SVAR( OC_UINT8, GoodsEntry, rating ),
+ OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, GoodsEntry, enroute_from ),
+ OCL_SVAR( OC_UINT8, GoodsEntry, enroute_time ),
+ OCL_SVAR( OC_UINT8, GoodsEntry, last_speed ),
+ OCL_SVAR( OC_UINT8, GoodsEntry, last_age ),
+
+ OCL_END()
+};
+
+static bool LoadOldGood(LoadgameState *ls, int num)
+{
+ Station *st = GetStation(_current_station_id);
+ return LoadChunk(ls, &st->goods[num], goods_chunk);
+}
+
+static const OldChunks station_chunk[] = {
+ OCL_SVAR( OC_TILE, Station, xy ),
+ OCL_VAR ( OC_UINT32, 1, &_old_town_index ),
+
+ OCL_SVAR( OC_TILE, Station, bus_tile_obsolete ),
+ OCL_SVAR( OC_TILE, Station, lorry_tile_obsolete ),
+ OCL_SVAR( OC_TILE, Station, train_tile ),
+ OCL_SVAR( OC_TILE, Station, airport_tile ),
+ OCL_SVAR( OC_TILE, Station, dock_tile ),
+
+ OCL_VAR ( OC_UINT8, 1, &_old_platforms ),
+
+ OCL_NULL( 1 ), // sort-index, no longer in use
+ OCL_NULL( 2 ), // sign-width, no longer in use
+
+ OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
+
+ OCL_NULL( 4 ), // sign left/top, no longer in use
+
+ OCL_SVAR( OC_UINT16, Station, had_vehicle_of_type ),
+
+ OCL_CHUNK( 12, LoadOldGood ),
+
+ OCL_SVAR( OC_UINT8, Station, time_since_load ),
+ OCL_SVAR( OC_UINT8, Station, time_since_unload ),
+ OCL_SVAR( OC_UINT8, Station, delete_ctr ),
+ OCL_SVAR( OC_UINT8, Station, owner ),
+ OCL_SVAR( OC_UINT8, Station, facilities ),
+ OCL_SVAR( OC_UINT8, Station, airport_type ),
+ OCL_NULL( 2 ), // Bus/truck status, no longer in use
+ OCL_SVAR( OC_UINT8, Station, blocked_months_obsolete ),
+ OCL_NULL( 1 ), // Unknown
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Station, airport_flags ),
+ OCL_NULL( 2 ), // last_vehicle. now last_vehicle_type
+
+ OCL_NULL( 4 ), // Junk at end of chunk
+
+ OCL_END()
+};
+static bool LoadOldStation(LoadgameState *ls, int num)
+{
+ Station *st;
+
+ if (!AddBlockIfNeeded(&_Station_pool, num))
+ error("Stations: failed loading savegame: too many stations");
+
+ st = GetStation(num);
+ _current_station_id = num;
+
+ if (!LoadChunk(ls, st, station_chunk))
+ return false;
+
+ if (IsValidStation(st)) {
+ if (st->train_tile) {
+ /* Calculate the trainst_w and trainst_h */
+ uint w = GB(_old_platforms, 3, 3);
+ uint h = GB(_old_platforms, 0, 3);
+ st->trainst_w = w;
+ st->trainst_h = h;
+ }
+
+ st->town = GetTown(REMAP_TOWN_IDX(_old_town_index));
+ st->string_id = RemapOldStringID(_old_string_id);
+ }
+
+ return true;
+}
+
+static const OldChunks industry_chunk[] = {
+ OCL_SVAR( OC_TILE, Industry, xy ),
+ OCL_VAR ( OC_UINT32, 1, &_old_town_index ),
+ OCL_SVAR( OC_UINT8, Industry, width ),
+ OCL_SVAR( OC_UINT8, Industry, height ),
+ OCL_SVAR( OC_UINT8, Industry, produced_cargo[0] ),
+ OCL_SVAR( OC_UINT8, Industry, produced_cargo[1] ),
+
+ OCL_SVAR( OC_UINT16, Industry, cargo_waiting[0] ),
+ OCL_SVAR( OC_UINT16, Industry, cargo_waiting[1] ),
+
+ OCL_SVAR( OC_UINT8, Industry, production_rate[0] ),
+ OCL_SVAR( OC_UINT8, Industry, production_rate[1] ),
+
+ OCL_SVAR( OC_UINT8, Industry, accepts_cargo[0] ),
+ OCL_SVAR( OC_UINT8, Industry, accepts_cargo[1] ),
+ OCL_SVAR( OC_UINT8, Industry, accepts_cargo[2] ),
+
+ OCL_SVAR( OC_UINT8, Industry, prod_level ),
+
+ OCL_SVAR( OC_UINT16, Industry, last_mo_production[0] ),
+ OCL_SVAR( OC_UINT16, Industry, last_mo_production[1] ),
+ OCL_SVAR( OC_UINT16, Industry, last_mo_transported[0] ),
+ OCL_SVAR( OC_UINT16, Industry, last_mo_transported[1] ),
+
+ OCL_SVAR( OC_UINT8, Industry, pct_transported[0] ),
+ OCL_SVAR( OC_UINT8, Industry, pct_transported[1] ),
+
+ OCL_SVAR( OC_UINT16, Industry, total_production[0] ),
+ OCL_SVAR( OC_UINT16, Industry, total_production[1] ),
+ OCL_SVAR( OC_UINT16, Industry, total_transported[0] ),
+ OCL_SVAR( OC_UINT16, Industry, total_transported[1] ),
+
+ OCL_SVAR( OC_UINT8, Industry, type ),
+ OCL_SVAR( OC_UINT8, Industry, owner ),
+ OCL_SVAR( OC_UINT8, Industry, random_color ),
+ OCL_SVAR( OC_FILE_U8 | OC_VAR_I32, Industry, last_prod_year ),
+ OCL_SVAR( OC_UINT16, Industry, counter ),
+ OCL_SVAR( OC_UINT8, Industry, was_cargo_delivered ),
+
+ OCL_NULL( 9 ), // Random junk at the end of this chunk
+
+ OCL_END()
+};
+
+static bool LoadOldIndustry(LoadgameState *ls, int num)
+{
+ Industry *i;
+
+ if (!AddBlockIfNeeded(&_Industry_pool, num))
+ error("Industries: failed loading savegame: too many industries");
+
+ i = GetIndustry(num);
+ if (!LoadChunk(ls, i, industry_chunk)) return false;
+
+ if (IsValidIndustry(i)) {
+ i->town = GetTown(REMAP_TOWN_IDX(_old_town_index));
+ }
+
+ return true;
+}
+
+static PlayerID _current_player_id;
+static uint16 _old_inaugurated_year;
+static int32 _old_yearly;
+
+static const OldChunks player_yearly_chunk[] = {
+ OCL_VAR( OC_INT32, 1, &_old_yearly ),
+ OCL_END()
+};
+
+static bool OldPlayerYearly(LoadgameState *ls, int num)
+{
+ int i;
+ Player *p = GetPlayer(_current_player_id);
+
+ for (i = 0; i < 13; i++) {
+ if (!LoadChunk(ls, NULL, player_yearly_chunk)) return false;
+
+ p->yearly_expenses[num][i] = _old_yearly;
+ }
+
+ return true;
+}
+
+static const OldChunks player_economy_chunk[] = {
+ OCL_SVAR( OC_INT32, PlayerEconomyEntry, income ),
+ OCL_SVAR( OC_INT32, PlayerEconomyEntry, expenses ),
+ OCL_SVAR( OC_INT32, PlayerEconomyEntry, delivered_cargo ),
+ OCL_SVAR( OC_INT32, PlayerEconomyEntry, performance_history ),
+ OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, PlayerEconomyEntry, company_value ),
+
+ OCL_END()
+};
+
+static bool OldPlayerEconomy(LoadgameState *ls, int num)
+{
+ int i;
+ Player *p = GetPlayer(_current_player_id);
+
+ if (!LoadChunk(ls, &p->cur_economy, player_economy_chunk)) return false;
+
+ /* Don't ask, but the number in TTD(Patch) are inversed to OpenTTD */
+ p->cur_economy.income = -p->cur_economy.income;
+ p->cur_economy.expenses = -p->cur_economy.expenses;
+
+ for (i = 0; i < 24; i++) {
+ if (!LoadChunk(ls, &p->old_economy[i], player_economy_chunk)) return false;
+
+ p->old_economy[i].income = -p->old_economy[i].income;
+ p->old_economy[i].expenses = -p->old_economy[i].expenses;
+ }
+
+ return true;
+}
+
+static const OldChunks player_ai_build_rec_chunk[] = {
+ OCL_SVAR( OC_TILE, AiBuildRec, spec_tile ),
+ OCL_SVAR( OC_TILE, AiBuildRec, use_tile ),
+ OCL_SVAR( OC_UINT8, AiBuildRec, rand_rng ),
+ OCL_SVAR( OC_UINT8, AiBuildRec, cur_building_rule ),
+ OCL_SVAR( OC_UINT8, AiBuildRec, unk6 ),
+ OCL_SVAR( OC_UINT8, AiBuildRec, unk7 ),
+ OCL_SVAR( OC_UINT8, AiBuildRec, buildcmd_a ),
+ OCL_SVAR( OC_UINT8, AiBuildRec, buildcmd_b ),
+ OCL_SVAR( OC_UINT8, AiBuildRec, direction ),
+ OCL_SVAR( OC_UINT8, AiBuildRec, cargo ),
+
+ OCL_NULL( 8 ), // Junk...
+
+ OCL_END()
+};
+
+static bool OldLoadAIBuildRec(LoadgameState *ls, int num)
+{
+ Player *p = GetPlayer(_current_player_id);
+
+ switch (num) {
+ case 0: return LoadChunk(ls, &p->ai.src, player_ai_build_rec_chunk);
+ case 1: return LoadChunk(ls, &p->ai.dst, player_ai_build_rec_chunk);
+ case 2: return LoadChunk(ls, &p->ai.mid1, player_ai_build_rec_chunk);
+ case 3: return LoadChunk(ls, &p->ai.mid2, player_ai_build_rec_chunk);
+ }
+
+ return false;
+}
+static const OldChunks player_ai_chunk[] = {
+ OCL_SVAR( OC_UINT8, PlayerAI, state ),
+ OCL_NULL( 1 ), // Junk
+ OCL_SVAR( OC_UINT8, PlayerAI, state_mode ),
+ OCL_SVAR( OC_UINT16, PlayerAI, state_counter ),
+ OCL_SVAR( OC_UINT16, PlayerAI, timeout_counter ),
+
+ OCL_CHUNK( 4, OldLoadAIBuildRec ),
+
+ OCL_NULL( 20 ), // More junk
+
+ OCL_SVAR( OC_UINT8, PlayerAI, cargo_type ),
+ OCL_SVAR( OC_UINT8, PlayerAI, num_wagons ),
+ OCL_SVAR( OC_UINT8, PlayerAI, build_kind ),
+ OCL_SVAR( OC_UINT8, PlayerAI, num_build_rec ),
+ OCL_SVAR( OC_UINT8, PlayerAI, num_loco_to_build ),
+ OCL_SVAR( OC_UINT8, PlayerAI, num_want_fullload ),
+
+ OCL_NULL( 14 ), // Oh no more junk :|
+
+ OCL_NULL( 2 ), // Loco-id, not used
+
+ OCL_SVAR( OC_UINT16, PlayerAI, wagon_list[0] ),
+ OCL_SVAR( OC_UINT16, PlayerAI, wagon_list[1] ),
+ OCL_SVAR( OC_UINT16, PlayerAI, wagon_list[2] ),
+ OCL_SVAR( OC_UINT16, PlayerAI, wagon_list[3] ),
+ OCL_SVAR( OC_UINT16, PlayerAI, wagon_list[4] ),
+ OCL_SVAR( OC_UINT16, PlayerAI, wagon_list[5] ),
+ OCL_SVAR( OC_UINT16, PlayerAI, wagon_list[6] ),
+ OCL_SVAR( OC_UINT16, PlayerAI, wagon_list[7] ),
+ OCL_SVAR( OC_UINT16, PlayerAI, wagon_list[8] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, order_list_blocks[0] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, order_list_blocks[1] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, order_list_blocks[2] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, order_list_blocks[3] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, order_list_blocks[4] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, order_list_blocks[5] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, order_list_blocks[6] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, order_list_blocks[7] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, order_list_blocks[8] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, order_list_blocks[9] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, order_list_blocks[10] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, order_list_blocks[11] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, order_list_blocks[12] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, order_list_blocks[13] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, order_list_blocks[14] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, order_list_blocks[15] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, order_list_blocks[16] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, order_list_blocks[17] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, order_list_blocks[18] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, order_list_blocks[19] ),
+
+ OCL_SVAR( OC_UINT16, PlayerAI, start_tile_a ),
+ OCL_SVAR( OC_UINT16, PlayerAI, start_tile_b ),
+ OCL_SVAR( OC_UINT16, PlayerAI, cur_tile_a ),
+ OCL_SVAR( OC_UINT16, PlayerAI, cur_tile_b ),
+
+ OCL_SVAR( OC_UINT8, PlayerAI, start_dir_a ),
+ OCL_SVAR( OC_UINT8, PlayerAI, start_dir_b ),
+ OCL_SVAR( OC_UINT8, PlayerAI, cur_dir_a ),
+ OCL_SVAR( OC_UINT8, PlayerAI, cur_dir_b ),
+
+ OCL_SVAR( OC_UINT8, PlayerAI, banned_tile_count ),
+
+ OCL_SVAR( OC_TILE, PlayerAI, banned_tiles[0] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, banned_val[0] ),
+ OCL_SVAR( OC_TILE, PlayerAI, banned_tiles[1] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, banned_val[1] ),
+ OCL_SVAR( OC_TILE, PlayerAI, banned_tiles[2] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, banned_val[2] ),
+ OCL_SVAR( OC_TILE, PlayerAI, banned_tiles[3] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, banned_val[3] ),
+ OCL_SVAR( OC_TILE, PlayerAI, banned_tiles[4] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, banned_val[4] ),
+ OCL_SVAR( OC_TILE, PlayerAI, banned_tiles[5] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, banned_val[5] ),
+ OCL_SVAR( OC_TILE, PlayerAI, banned_tiles[6] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, banned_val[6] ),
+ OCL_SVAR( OC_TILE, PlayerAI, banned_tiles[7] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, banned_val[7] ),
+ OCL_SVAR( OC_TILE, PlayerAI, banned_tiles[8] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, banned_val[8] ),
+ OCL_SVAR( OC_TILE, PlayerAI, banned_tiles[9] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, banned_val[9] ),
+ OCL_SVAR( OC_TILE, PlayerAI, banned_tiles[10] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, banned_val[10] ),
+ OCL_SVAR( OC_TILE, PlayerAI, banned_tiles[11] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, banned_val[11] ),
+ OCL_SVAR( OC_TILE, PlayerAI, banned_tiles[12] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, banned_val[12] ),
+ OCL_SVAR( OC_TILE, PlayerAI, banned_tiles[13] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, banned_val[13] ),
+ OCL_SVAR( OC_TILE, PlayerAI, banned_tiles[14] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, banned_val[14] ),
+ OCL_SVAR( OC_TILE, PlayerAI, banned_tiles[15] ),
+ OCL_SVAR( OC_UINT8, PlayerAI, banned_val[15] ),
+
+ OCL_SVAR( OC_UINT8, PlayerAI, railtype_to_use ),
+ OCL_SVAR( OC_UINT8, PlayerAI, route_type_mask ),
+
+ OCL_END()
+};
+
+static bool OldPlayerAI(LoadgameState *ls, int num)
+{
+ Player *p = GetPlayer(_current_player_id);
+
+ return LoadChunk(ls, &p->ai, player_ai_chunk);
+}
+
+static const OldChunks player_chunk[] = {
+ OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
+ OCL_SVAR( OC_UINT32, Player, name_2 ),
+ OCL_SVAR( OC_UINT32, Player, face ),
+ OCL_VAR ( OC_UINT16, 1, &_old_string_id_2 ),
+ OCL_SVAR( OC_UINT32, Player, president_name_2 ),
+
+ OCL_SVAR( OC_INT32, Player, player_money ),
+ OCL_SVAR( OC_INT32, Player, current_loan ),
+
+ OCL_SVAR( OC_UINT8, Player, player_color ),
+ OCL_SVAR( OC_UINT8, Player, player_money_fraction ),
+ OCL_SVAR( OC_UINT8, Player, quarters_of_bankrupcy ),
+ OCL_SVAR( OC_UINT8, Player, bankrupt_asked ),
+ OCL_SVAR( OC_UINT32, Player, bankrupt_value ),
+ OCL_SVAR( OC_UINT16, Player, bankrupt_timeout ),
+
+ OCL_SVAR( OC_FILE_U32 | OC_VAR_U16, Player, cargo_types ),
+
+ OCL_CHUNK( 3, OldPlayerYearly ),
+ OCL_CHUNK( 1, OldPlayerEconomy ),
+
+ OCL_VAR ( OC_UINT16, 1, &_old_inaugurated_year ),
+ OCL_SVAR( OC_TILE, Player, last_build_coordinate ),
+ OCL_SVAR( OC_UINT8, Player, num_valid_stat_ent ),
+
+ OCL_CHUNK( 1, OldPlayerAI ),
+
+ OCL_SVAR( OC_UINT8, Player, block_preview ),
+ OCL_SVAR( OC_UINT8, Player, ai.tick ),
+ OCL_SVAR( OC_UINT8, Player, avail_railtypes ),
+ OCL_SVAR( OC_TILE, Player, location_of_house ),
+ OCL_SVAR( OC_UINT8, Player, share_owners[0] ),
+ OCL_SVAR( OC_UINT8, Player, share_owners[1] ),
+ OCL_SVAR( OC_UINT8, Player, share_owners[2] ),
+ OCL_SVAR( OC_UINT8, Player, share_owners[3] ),
+
+ OCL_NULL( 8 ), // junk at end of chunk
+
+ OCL_END()
+};
+
+static bool LoadOldPlayer(LoadgameState *ls, int num)
+{
+ Player *p = GetPlayer(num);
+
+ _current_player_id = num;
+
+ if (!LoadChunk(ls, p, player_chunk)) return false;
+
+ p->name_1 = RemapOldStringID(_old_string_id);
+ p->president_name_1 = RemapOldStringID(_old_string_id_2);
+ p->money64 = p->player_money;
+
+ if (num == 0) {
+ /* If the first player has no name, make sure we call it UNNAMED */
+ if (p->name_1 == 0)
+ p->name_1 = STR_SV_UNNAMED;
+ } else {
+ /* Beside some multiplayer maps (1 on 1), which we don't official support,
+ all other players are an AI.. mark them as such */
+ p->is_ai = true;
+ }
+
+ /* Sometimes it is better to not ask.. in old scenarios, the money
+ was always 893288 pounds. In the newer versions this is correct,
+ but correct for those oldies
+ Ps: this also means that if you had exact 893288 pounds, you will go back
+ to 10000.. this is a very VERY small chance ;) */
+ if (p->player_money == 893288)
+ p->money64 = p->player_money = p->current_loan = 100000;
+
+ _player_colors[num] = p->player_color;
+ p->inaugurated_year = _old_inaugurated_year;
+ if (p->location_of_house == 0xFFFF)
+ p->location_of_house = 0;
+
+ /* State 20 for AI players is sell vehicle. Since the AI struct is not
+ * really figured out as of now, p->ai.cur_veh; needed for 'sell vehicle'
+ * is NULL and the function will crash. To fix this, just change the state
+ * to some harmless state, like 'loop vehicle'; 1 */
+ if (!IsHumanPlayer(num) && p->ai.state == 20) p->ai.state = 1;
+
+ if (p->is_ai && (!_networking || _network_server) && _ai.enabled)
+ AI_StartNewAI(p->index);
+
+ return true;
+}
+
+static uint32 _old_order_ptr;
+static uint16 _old_next_ptr;
+static uint32 _current_vehicle_id;
+
+static const OldChunks vehicle_train_chunk[] = {
+ OCL_SVAR( OC_UINT8, VehicleRail, track ),
+ OCL_SVAR( OC_UINT8, VehicleRail, force_proceed ),
+ OCL_SVAR( OC_UINT16, VehicleRail, crash_anim_pos ),
+ OCL_SVAR( OC_UINT8, VehicleRail, railtype ),
+
+ OCL_NULL( 5 ), // Junk
+
+ OCL_END()
+};
+
+static const OldChunks vehicle_road_chunk[] = {
+ OCL_SVAR( OC_UINT8, VehicleRoad, state ),
+ OCL_SVAR( OC_UINT8, VehicleRoad, frame ),
+ OCL_SVAR( OC_UINT16, VehicleRoad, blocked_ctr ),
+ OCL_SVAR( OC_UINT8, VehicleRoad, overtaking ),
+ OCL_SVAR( OC_UINT8, VehicleRoad, overtaking_ctr ),
+ OCL_SVAR( OC_UINT16, VehicleRoad, crashed_ctr ),
+ OCL_SVAR( OC_UINT8, VehicleRoad, reverse_ctr ),
+
+ OCL_NULL( 1 ), // Junk
+
+ OCL_END()
+};
+
+static const OldChunks vehicle_ship_chunk[] = {
+ OCL_SVAR( OC_UINT8, VehicleShip, state ),
+
+ OCL_NULL( 9 ), // Junk
+
+ OCL_END()
+};
+
+static const OldChunks vehicle_air_chunk[] = {
+ OCL_SVAR( OC_UINT8, VehicleAir, pos ),
+ OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, VehicleAir, targetairport ),
+ OCL_SVAR( OC_UINT16, VehicleAir, crashed_counter ),
+ OCL_SVAR( OC_UINT8, VehicleAir, state ),
+
+ OCL_NULL( 5 ), // Junk
+
+ OCL_END()
+};
+
+static const OldChunks vehicle_special_chunk[] = {
+ OCL_SVAR( OC_UINT16, VehicleSpecial, unk0 ),
+ OCL_SVAR( OC_UINT8, VehicleSpecial, unk2 ),
+
+ OCL_NULL( 7 ), // Junk
+
+ OCL_END()
+};
+
+static const OldChunks vehicle_disaster_chunk[] = {
+ OCL_SVAR( OC_UINT16, VehicleDisaster, image_override ),
+ OCL_SVAR( OC_UINT16, VehicleDisaster, unk2 ),
+
+ OCL_NULL( 6 ), // Junk
+
+ OCL_END()
+};
+
+static const OldChunks vehicle_empty_chunk[] = {
+ OCL_NULL( 10 ), // Junk
+
+ OCL_END()
+};
+
+static bool LoadOldVehicleUnion(LoadgameState *ls, int num)
+{
+ Vehicle *v = GetVehicle(_current_vehicle_id);
+ uint temp = ls->total_read;
+ bool res;
+
+ switch (v->type) {
+ case VEH_Train: res = LoadChunk(ls, &v->u.rail, vehicle_train_chunk); break;
+ case VEH_Road: res = LoadChunk(ls, &v->u.road, vehicle_road_chunk); break;
+ case VEH_Ship: res = LoadChunk(ls, &v->u.ship, vehicle_ship_chunk); break;
+ case VEH_Aircraft: res = LoadChunk(ls, &v->u.air, vehicle_air_chunk); break;
+ case VEH_Special: res = LoadChunk(ls, &v->u.special, vehicle_special_chunk); break;
+ case VEH_Disaster: res = LoadChunk(ls, &v->u.disaster, vehicle_disaster_chunk); break;
+ default: res = LoadChunk(ls, NULL, vehicle_empty_chunk); break;
+ }
+
+ /* This chunk size should always be 10 bytes */
+ if (ls->total_read - temp != 10) {
+ DEBUG(oldloader, 4, "Assert failed in Vehicle");
+ return false;
+ }
+
+ return res;
+}
+
+static const OldChunks vehicle_chunk[] = {
+ OCL_SVAR( OC_UINT8, Vehicle, type ),
+ OCL_SVAR( OC_UINT8, Vehicle, subtype ),
+
+ OCL_NULL( 2 ), // Hash, calculated automatically
+ OCL_NULL( 2 ), // Index, calculated automatically
+
+ OCL_VAR ( OC_UINT32, 1, &_old_order_ptr ),
+ OCL_VAR ( OC_UINT16, 1, &_old_order ),
+
+ OCL_SVAR( OC_UINT8, Vehicle, num_orders ),
+ OCL_SVAR( OC_UINT8, Vehicle, cur_order_index ),
+ OCL_SVAR( OC_TILE, Vehicle, dest_tile ),
+ OCL_SVAR( OC_UINT16, Vehicle, load_unload_time_rem ),
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, date_of_last_service ),
+ OCL_SVAR( OC_UINT16, Vehicle, service_interval ),
+ OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Vehicle, last_station_visited ),
+ OCL_SVAR( OC_UINT8, Vehicle, tick_counter ),
+ OCL_SVAR( OC_UINT16, Vehicle, max_speed ),
+
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Vehicle, x_pos ),
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Vehicle, y_pos ),
+ OCL_SVAR( OC_UINT8, Vehicle, z_pos ),
+ OCL_SVAR( OC_UINT8, Vehicle, direction ),
+ OCL_SVAR( OC_INT8, Vehicle, x_offs ),
+ OCL_SVAR( OC_INT8, Vehicle, y_offs ),
+ OCL_SVAR( OC_UINT8, Vehicle, sprite_width ),
+ OCL_SVAR( OC_UINT8, Vehicle, sprite_height ),
+ OCL_SVAR( OC_UINT8, Vehicle, z_height ),
+
+ OCL_SVAR( OC_UINT8, Vehicle, owner ),
+ OCL_SVAR( OC_TILE, Vehicle, tile ),
+ OCL_SVAR( OC_UINT16, Vehicle, cur_image ),
+
+ OCL_NULL( 8 ), // Vehicle sprite box, calculated automatically
+
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, Vehicle, vehstatus ),
+ OCL_SVAR( OC_UINT16, Vehicle, cur_speed ),
+ OCL_SVAR( OC_UINT8, Vehicle, subspeed ),
+ OCL_SVAR( OC_UINT8, Vehicle, acceleration ),
+ OCL_SVAR( OC_UINT8, Vehicle, progress ),
+
+ OCL_SVAR( OC_UINT8, Vehicle, cargo_type ),
+ OCL_SVAR( OC_UINT16, Vehicle, cargo_cap ),
+ OCL_SVAR( OC_UINT16, Vehicle, cargo_count ),
+ OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Vehicle, cargo_source ),
+ OCL_SVAR( OC_UINT8, Vehicle, cargo_days ),
+
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, age ),
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, max_age ),
+ OCL_SVAR( OC_FILE_U8 | OC_VAR_I32, Vehicle, build_year ),
+ OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Vehicle, unitnumber ),
+
+ OCL_SVAR( OC_UINT16, Vehicle, engine_type ),
+
+ OCL_SVAR( OC_UINT8, Vehicle, spritenum ),
+ OCL_SVAR( OC_UINT8, Vehicle, day_counter ),
+
+ OCL_SVAR( OC_UINT8, Vehicle, breakdowns_since_last_service ),
+ OCL_SVAR( OC_UINT8, Vehicle, breakdown_ctr ),
+ OCL_SVAR( OC_UINT8, Vehicle, breakdown_delay ),
+ OCL_SVAR( OC_UINT8, Vehicle, breakdown_chance ),
+
+ OCL_SVAR( OC_UINT16, Vehicle, reliability ),
+ OCL_SVAR( OC_UINT16, Vehicle, reliability_spd_dec ),
+
+ OCL_SVAR( OC_INT32, Vehicle, profit_this_year ),
+ OCL_SVAR( OC_INT32, Vehicle, profit_last_year ),
+
+ OCL_VAR ( OC_UINT16, 1, &_old_next_ptr ),
+
+ OCL_SVAR( OC_UINT32, Vehicle, value ),
+
+ OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
+
+ OCL_CHUNK( 1, LoadOldVehicleUnion ),
+
+ OCL_NULL( 20 ), // Junk at end of struct (TTDPatch has some data in it)
+
+ OCL_END()
+};
+
+static bool LoadOldVehicle(LoadgameState *ls, int num)
+{
+ uint i;
+
+ /* Read the TTDPatch flags, because we need some info from it */
+ ReadTTDPatchFlags();
+
+ for (i = 0; i < _old_vehicle_multiplier; i++) {
+ Vehicle *v;
+
+ _current_vehicle_id = num * _old_vehicle_multiplier + i;
+
+ if (!AddBlockIfNeeded(&_Vehicle_pool, _current_vehicle_id))
+ error("Vehicles: failed loading savegame: too many vehicles");
+
+ v = GetVehicle(_current_vehicle_id);
+ if (!LoadChunk(ls, v, vehicle_chunk)) return false;
+
+ /* This should be consistent, else we have a big problem... */
+ if (v->index != _current_vehicle_id) {
+ DEBUG(oldloader, 0, "Loading failed - vehicle-array is invalid");
+ return false;
+ }
+
+ if (_old_order_ptr != 0 && _old_order_ptr != 0xFFFFFFFF) {
+ v->orders = GetOrder(REMAP_ORDER_IDX(_old_order_ptr));
+ }
+ AssignOrder(&v->current_order, UnpackOldOrder(_old_order));
+
+ /* For some reason we need to correct for this */
+ switch (v->spritenum) {
+ case 0xfd: break;
+ case 0xff: v->spritenum = 0xfe; break;
+ default: v->spritenum >>= 1; break;
+ }
+
+ if (_old_next_ptr != 0xFFFF)
+ v->next = GetVehicle(_old_next_ptr);
+
+ v->string_id = RemapOldStringID(_old_string_id);
+
+ /* Vehicle-subtype is different in TTD(Patch) */
+ if (v->type == VEH_Special) v->subtype = v->subtype >> 1;
+ }
+
+ return true;
+}
+
+static const OldChunks sign_chunk[] = {
+ OCL_SVAR( OC_UINT16, Sign, str ),
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_I32,Sign, x ),
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_I32,Sign, y ),
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_I8, Sign, z ),
+
+ OCL_NULL( 6 ), // Width of sign, no longer in use
+
+ OCL_END()
+};
+
+static bool LoadOldSign(LoadgameState *ls, int num)
+{
+ if (!AddBlockIfNeeded(&_Sign_pool, num))
+ error("Signs: failed loading savegame: too many signs");
+
+ return LoadChunk(ls, GetSign(num), sign_chunk);
+}
+
+static const OldChunks engine_chunk[] = {
+ OCL_SVAR( OC_UINT16, Engine, player_avail ),
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Engine, intro_date ),
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Engine, age ),
+ OCL_SVAR( OC_UINT16, Engine, reliability ),
+ OCL_SVAR( OC_UINT16, Engine, reliability_spd_dec ),
+ OCL_SVAR( OC_UINT16, Engine, reliability_start ),
+ OCL_SVAR( OC_UINT16, Engine, reliability_max ),
+ OCL_SVAR( OC_UINT16, Engine, reliability_final ),
+ OCL_SVAR( OC_UINT16, Engine, duration_phase_1 ),
+ OCL_SVAR( OC_UINT16, Engine, duration_phase_2 ),
+ OCL_SVAR( OC_UINT16, Engine, duration_phase_3 ),
+
+ OCL_SVAR( OC_UINT8, Engine, lifelength ),
+ OCL_SVAR( OC_UINT8, Engine, flags ),
+ OCL_SVAR( OC_UINT8, Engine, preview_player ),
+ OCL_SVAR( OC_UINT8, Engine, preview_wait ),
+ OCL_SVAR( OC_UINT8, Engine, railtype ),
+
+ OCL_NULL( 1 ), // Junk
+
+ OCL_END()
+};
+
+static bool LoadOldEngine(LoadgameState *ls, int num)
+{
+ if (!LoadChunk(ls, GetEngine(num), engine_chunk)) return false;
+
+ /* Make sure wagons are marked as do-not-age */
+ if ((num >= 27 && num < 54) || (num >= 57 && num < 84) || (num >= 89 && num < 116))
+ GetEngine(num)->age = 0xFFFF;
+
+ return true;
+}
+
+static const OldChunks subsidy_chunk[] = {
+ OCL_SVAR( OC_UINT8, Subsidy, cargo_type ),
+ OCL_SVAR( OC_UINT8, Subsidy, age ),
+ OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Subsidy, from ),
+ OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Subsidy, to ),
+
+ OCL_END()
+};
+
+static inline bool LoadOldSubsidy(LoadgameState *ls, int num)
+{
+ return LoadChunk(ls, &_subsidies[num], subsidy_chunk);
+}
+
+static const OldChunks game_difficulty_chunk[] = {
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, max_no_competitors ),
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, competitor_start_time ),
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, number_towns ),
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, number_industries ),
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, max_loan ),
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, initial_interest ),
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, vehicle_costs ),
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, competitor_speed ),
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, competitor_intelligence ),
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, vehicle_breakdowns ),
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, subsidy_multiplier ),
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, construction_cost ),
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, terrain_type ),
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, quantity_sea_lakes ),
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, economy ),
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, line_reverse_mode ),
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, disasters ),
+ OCL_END()
+};
+
+static inline bool LoadOldGameDifficulty(LoadgameState *ls, int num)
+{
+ return LoadChunk(ls, &_opt.diff, game_difficulty_chunk);
+}
+
+
+static bool LoadOldMapPart1(LoadgameState *ls, int num)
+{
+ uint i;
+
+ for (i = 0; i < OLD_MAP_SIZE; i++) {
+ _m[i].m1 = ReadByte(ls);
+ }
+ for (i = 0; i < OLD_MAP_SIZE; i++) {
+ _m[i].m2 = ReadByte(ls);
+ }
+ for (i = 0; i < OLD_MAP_SIZE; i++) {
+ _old_map3[i * 2] = ReadByte(ls);
+ _old_map3[i * 2 + 1] = ReadByte(ls);
+ }
+ for (i = 0; i < OLD_MAP_SIZE / 4; i++) {
+ byte b = ReadByte(ls);
+ _m[i * 4 + 0].extra = GB(b, 0, 2);
+ _m[i * 4 + 1].extra = GB(b, 2, 2);
+ _m[i * 4 + 2].extra = GB(b, 4, 2);
+ _m[i * 4 + 3].extra = GB(b, 6, 2);
+ }
+
+ return !ls->failed;
+}
+
+static bool LoadOldMapPart2(LoadgameState *ls, int num)
+{
+ uint i;
+
+ for (i = 0; i < OLD_MAP_SIZE; i++) {
+ _m[i].type_height = ReadByte(ls);
+ }
+ for (i = 0; i < OLD_MAP_SIZE; i++) {
+ _m[i].m5 = ReadByte(ls);
+ }
+
+ return !ls->failed;
+}
+
+static uint32 _old_cur_town_ctr;
+static const OldChunks main_chunk[] = {
+ OCL_ASSERT( 0 ),
+ OCL_VAR ( OC_FILE_U16 | OC_VAR_U32, 1, &_date ),
+ OCL_VAR ( OC_UINT16, 1, &_date_fract ),
+ OCL_NULL( 600 ), // TextEffects
+ OCL_VAR ( OC_UINT32, 2, &_random_seeds[0] ),
+
+ OCL_ASSERT( 0x264 ),
+ OCL_CHUNK( 70, LoadOldTown ),
+ OCL_ASSERT( 0x1C18 ),
+ OCL_CHUNK(5000, LoadOldOrder ),
+ OCL_ASSERT( 0x4328 ),
+
+ OCL_VAR ( OC_TILE, 256, &_animated_tile_list[0] ),
+ OCL_NULL( 4 ), // old end-of-order-list-pointer, no longer in use
+
+ OCL_CHUNK( 255, LoadOldDepot ),
+ OCL_ASSERT( 0x4B26 ),
+
+ OCL_VAR ( OC_UINT32, 1, &_old_cur_town_ctr ),
+ OCL_NULL( 2 ), // timer_counter, no longer in use
+ OCL_NULL( 2 ), // land_code, no longer in use
+
+ OCL_VAR ( OC_FILE_U16 | OC_VAR_U8, 1, &_age_cargo_skip_counter ),
+ OCL_VAR ( OC_UINT16, 1, &_tick_counter ),
+ OCL_VAR ( OC_TILE, 1, &_cur_tileloop_tile ),
+
+ OCL_CHUNK( 49, LoadOldPrice ),
+ OCL_CHUNK( 12, LoadOldCargoPaymentRate ),
+
+ OCL_ASSERT( 0x4CBA ),
+
+ OCL_CHUNK( 1, LoadOldMapPart1 ),
+
+ OCL_ASSERT( 0x48CBA ),
+
+ OCL_CHUNK(250, LoadOldStation ),
+ OCL_CHUNK( 90, LoadOldIndustry ),
+ OCL_CHUNK( 8, LoadOldPlayer ),
+
+ OCL_ASSERT( 0x547F2 ),
+
+ OCL_CHUNK( 850, LoadOldVehicle ),
+
+ OCL_ASSERT( 0x6F0F2 ),
+
+ OCL_VAR ( OC_UINT8, 32 * 500, &_name_array[0] ),
+
+ OCL_NULL( 0x2000 ), // Old hash-table, no longer in use
+
+ OCL_CHUNK( 40, LoadOldSign ),
+ OCL_CHUNK(256, LoadOldEngine ),
+
+ OCL_VAR ( OC_UINT16, 1, &_vehicle_id_ctr_day ),
+
+ OCL_CHUNK( 8, LoadOldSubsidy ),
+
+ OCL_VAR ( OC_FILE_U16 | OC_VAR_U32, 1, &_next_competitor_start ),
+ OCL_VAR ( OC_FILE_I16 | OC_VAR_I32, 1, &_saved_scrollpos_x ),
+ OCL_VAR ( OC_FILE_I16 | OC_VAR_I32, 1, &_saved_scrollpos_y ),
+ OCL_VAR ( OC_FILE_U16 | OC_VAR_U8, 1, &_saved_scrollpos_zoom ),
+
+ OCL_VAR ( OC_UINT32, 1, &_economy.max_loan ),
+ OCL_VAR ( OC_UINT32, 1, &_economy.max_loan_unround ),
+ OCL_VAR ( OC_FILE_U16 | OC_VAR_U32, 1, &_economy.fluct ),
+
+ OCL_VAR ( OC_UINT16, 1, &_disaster_delay ),
+
+ OCL_NULL( 144 ), // cargo-stuff, calculated in InitializeLandscapeVariables
+
+ OCL_VAR ( OC_UINT16, 256, &_engine_name_strings[0] ),
+
+ OCL_NULL( 144 ), // AI cargo-stuff, calculated in InitializeLandscapeVariables
+ OCL_NULL( 2 ), // Company indexes of players, no longer in use
+
+ OCL_VAR ( OC_FILE_U8 | OC_VAR_U16, 1, &_station_tick_ctr ),
+
+ OCL_VAR ( OC_UINT8, 1, &_opt.currency ),
+ OCL_VAR ( OC_UINT8, 1, &_opt.units ),
+ OCL_VAR ( OC_FILE_U8 | OC_VAR_U32, 1, &_cur_player_tick_index ),
+
+ OCL_NULL( 2 ), // Date stuff, calculated automatically
+ OCL_NULL( 8 ), // Player colors, calculated automatically
+
+ OCL_VAR ( OC_UINT8, 1, &_economy.infl_amount ),
+ OCL_VAR ( OC_UINT8, 1, &_economy.infl_amount_pr ),
+ OCL_VAR ( OC_UINT8, 1, &_economy.interest_rate ),
+ OCL_VAR ( OC_UINT8, 1, &_avail_aircraft ),
+ OCL_VAR ( OC_UINT8, 1, &_opt.road_side ),
+ OCL_VAR ( OC_UINT8, 1, &_opt.town_name ),
+
+ OCL_CHUNK( 1, LoadOldGameDifficulty ),
+
+ OCL_ASSERT( 0x77130 ),
+
+ OCL_VAR ( OC_UINT8, 1, &_opt.diff_level ),
+ OCL_VAR ( OC_UINT8, 1, &_opt.landscape ),
+ OCL_VAR ( OC_UINT8, 1, &_trees_tick_ctr ),
+
+ OCL_NULL( 1 ), // Custom vehicle types yes/no, no longer used
+ OCL_VAR ( OC_UINT8, 1, &_opt.snow_line ),
+
+ OCL_NULL( 32 ), // new_industry_randtable, no longer used (because of new design)
+ OCL_NULL( 36 ), // cargo-stuff, calculated in InitializeLandscapeVariables
+
+ OCL_ASSERT( 0x77179 ),
+
+ OCL_CHUNK( 1, LoadOldMapPart2 ),
+
+ OCL_ASSERT( 0x97179 ),
+
+ /* Below any (if available) extra chunks from TTDPatch can follow */
+
+ OCL_END()
+};
+
+static bool LoadOldMain(LoadgameState *ls)
+{
+ int i;
+
+ /* The first 49 is the name of the game + checksum, skip it */
+ fseek(ls->file, HEADER_SIZE, SEEK_SET);
+
+ DEBUG(oldloader, 4, "Reading main chunk...");
+ /* Load the biggest chunk */
+ if (!LoadChunk(ls, NULL, main_chunk)) {
+ DEBUG(oldloader, 0, "Loading failed");
+ return false;
+ }
+ DEBUG(oldloader, 4, "Done, converting game data...");
+
+ /* Fix some general stuff */
+ _opt.landscape = _opt.landscape & 0xF;
+
+ /* Remap some pointers */
+ _cur_town_ctr = REMAP_TOWN_IDX(_old_cur_town_ctr);
+
+ /* _old_map3 is changed in _map3_lo and _map3_hi */
+ for (i = 0; i < OLD_MAP_SIZE; i++) {
+ _m[i].m3 = _old_map3[i * 2];
+ _m[i].m4 = _old_map3[i * 2 + 1];
+ }
+
+ for (i = 0; i < OLD_MAP_SIZE; i ++) {
+ if (IsTileType(i, MP_RAILWAY)) {
+ /* We save presignals different from TTDPatch, convert them */
+ if (GetRailTileType(i) == RAIL_TILE_SIGNALS) {
+ /* This byte is always zero in TTD for this type of tile */
+ if (_m[i].m4) /* Convert the presignals to our own format */
+ _m[i].m4 = (_m[i].m4 >> 1) & 7;
+ }
+ /* TTDPatch stores PBS things in L6 and all elsewhere; so we'll just
+ * clear it for ourselves and let OTTD's rebuild PBS itself */
+ _m[i].m4 &= 0xF; /* Only keep the lower four bits; upper four is PBS */
+ }
+ }
+
+ /* Fix the game to be compatible with OpenTTD */
+ FixOldTowns();
+ FixOldStations();
+ FixOldVehicles();
+
+ AddTypeToEngines();
+
+ /* We have a new difficulty setting */
+ _opt.diff.town_council_tolerance = clamp(_opt.diff_level, 0, 2);
+
+ DEBUG(oldloader, 4, "Finished converting game data");
+ DEBUG(oldloader, 1, "TTD(Patch) savegame successfully converted");
+
+ return true;
+}
+
+bool LoadOldSaveGame(const char *file)
+{
+ LoadgameState ls;
+
+ DEBUG(oldloader, 4, "Trying to load a TTD(Patch) savegame");
+
+ InitLoading(&ls);
+
+ /* Open file */
+ ls.file = fopen(file, "rb");
+
+ if (ls.file == NULL) {
+ DEBUG(oldloader, 0, "Cannot open file '%s'", file);
+ return false;
+ }
+
+ /* Load the main chunk */
+ if (!LoadOldMain(&ls)) return false;
+
+ fclose(ls.file);
+
+ _pause = 2;
+
+ return true;
+}
+
+void GetOldSaveGameName(char *title, const char *path, const char *file)
+{
+ char filename[MAX_PATH];
+ FILE *f;
+
+ snprintf(filename, lengthof(filename), "%s" PATHSEP "%s", path, file);
+ f = fopen(filename, "rb");
+ title[0] = '\0';
+ title[48] = '\0';
+
+ if (f == NULL) return;
+
+ if (fread(title, 1, 48, f) != 48) snprintf(title, 48, "Corrupt file");
+
+ fclose(f);
+}
diff --git a/src/oldpool.c b/src/oldpool.c
new file mode 100644
index 000000000..2b2d188e8
--- /dev/null
+++ b/src/oldpool.c
@@ -0,0 +1,86 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "debug.h"
+#include "functions.h"
+#include "oldpool.h"
+
+/**
+ * Clean a pool in a safe way (does free all blocks)
+ */
+void CleanPool(OldMemoryPool *pool)
+{
+ uint i;
+
+ DEBUG(misc, 4, "[Pool] (%s) cleaning pool..", pool->name);
+
+ /* Free all blocks */
+ for (i = 0; i < pool->current_blocks; i++) {
+ if (pool->clean_block_proc != NULL) {
+ pool->clean_block_proc(i * (1 << pool->block_size_bits), (i + 1) * (1 << pool->block_size_bits) - 1);
+ }
+ free(pool->blocks[i]);
+ }
+
+ /* Free the block itself */
+ free(pool->blocks);
+
+ /* Clear up some critical data */
+ pool->total_items = 0;
+ pool->current_blocks = 0;
+ pool->blocks = NULL;
+}
+
+/**
+ * This function tries to increase the size of array by adding
+ * 1 block too it
+ *
+ * @return Returns false if the pool could not be increased
+ */
+bool AddBlockToPool(OldMemoryPool *pool)
+{
+ /* Is the pool at his max? */
+ if (pool->max_blocks == pool->current_blocks)
+ return false;
+
+ pool->total_items = (pool->current_blocks + 1) * (1 << pool->block_size_bits);
+
+ DEBUG(misc, 4, "[Pool] (%s) increasing size of pool to %d items (%d bytes)", pool->name, pool->total_items, pool->total_items * pool->item_size);
+
+ /* Increase the poolsize */
+ pool->blocks = realloc(pool->blocks, sizeof(pool->blocks[0]) * (pool->current_blocks + 1));
+ if (pool->blocks == NULL) error("Pool: (%s) could not allocate memory for blocks", pool->name);
+
+ /* Allocate memory to the new block item */
+ pool->blocks[pool->current_blocks] = malloc(pool->item_size * (1 << pool->block_size_bits));
+ if (pool->blocks[pool->current_blocks] == NULL)
+ error("Pool: (%s) could not allocate memory for blocks", pool->name);
+
+ /* Clean the content of the new block */
+ memset(pool->blocks[pool->current_blocks], 0, pool->item_size * (1 << pool->block_size_bits));
+
+ /* Call a custom function if defined (e.g. to fill indexes) */
+ if (pool->new_block_proc != NULL)
+ pool->new_block_proc(pool->current_blocks * (1 << pool->block_size_bits));
+
+ /* We have a new block */
+ pool->current_blocks++;
+
+ return true;
+}
+
+/**
+ * Adds blocks to the pool if needed (and possible) till index fits inside the pool
+ *
+ * @return Returns false if adding failed
+ */
+bool AddBlockIfNeeded(OldMemoryPool *pool, uint index)
+{
+ while (index >= pool->total_items) {
+ if (!AddBlockToPool(pool))
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/oldpool.h b/src/oldpool.h
new file mode 100644
index 000000000..ba22e4ef4
--- /dev/null
+++ b/src/oldpool.h
@@ -0,0 +1,96 @@
+/* $Id$ */
+
+#ifndef OLDPOOL_H
+#define OLDPOOL_H
+
+typedef struct OldMemoryPool OldMemoryPool;
+
+/* The function that is called after a new block is added
+ start_item is the first item of the new made block */
+typedef void OldMemoryPoolNewBlock(uint start_item);
+/* The function that is called before a block is cleaned up */
+typedef void OldMemoryPoolCleanBlock(uint start_item, uint end_item);
+
+/**
+ * Stuff for dynamic vehicles. Use the wrappers to access the OldMemoryPool
+ * please try to avoid manual calls!
+ */
+struct OldMemoryPool {
+ const char* const name; ///< Name of the pool (just for debugging)
+
+ const uint max_blocks; ///< The max amount of blocks this pool can have
+ const uint block_size_bits; ///< The size of each block in bits
+ const uint item_size; ///< How many bytes one block is
+
+ /// Pointer to a function that is called after a new block is added
+ OldMemoryPoolNewBlock *new_block_proc;
+ /// Pointer to a function that is called to clean a block
+ OldMemoryPoolCleanBlock *clean_block_proc;
+
+ uint current_blocks; ///< How many blocks we have in our pool
+ uint total_items; ///< How many items we now have in this pool
+
+ byte **blocks; ///< An array of blocks (one block hold all the items)
+};
+
+/**
+ * Those are the wrappers:
+ * CleanPool cleans the pool up, but you can use AddBlockToPool directly again
+ * (no need to call CreatePool!)
+ * AddBlockToPool adds 1 more block to the pool. Returns false if there is no
+ * more room
+ */
+void CleanPool(OldMemoryPool *array);
+bool AddBlockToPool(OldMemoryPool *array);
+
+/**
+ * Adds blocks to the pool if needed (and possible) till index fits inside the pool
+ *
+ * @return Returns false if adding failed
+ */
+bool AddBlockIfNeeded(OldMemoryPool *array, uint index);
+
+
+#define OLD_POOL_ENUM(name, type, block_size_bits, max_blocks) \
+ enum { \
+ name##_POOL_BLOCK_SIZE_BITS = block_size_bits, \
+ name##_POOL_MAX_BLOCKS = max_blocks \
+ };
+
+
+#define OLD_POOL_ACCESSORS(name, type) \
+ static inline type* Get##name(uint index) \
+ { \
+ assert(index < _##name##_pool.total_items); \
+ return (type*)( \
+ _##name##_pool.blocks[index >> name##_POOL_BLOCK_SIZE_BITS] + \
+ (index & ((1 << name##_POOL_BLOCK_SIZE_BITS) - 1)) * sizeof(type) \
+ ); \
+ } \
+\
+ static inline uint Get##name##PoolSize(void) \
+ { \
+ return _##name##_pool.total_items; \
+ }
+
+
+#define DECLARE_OLD_POOL(name, type, block_size_bits, max_blocks) \
+ OLD_POOL_ENUM(name, type, block_size_bits, max_blocks) \
+ extern OldMemoryPool _##name##_pool; \
+ OLD_POOL_ACCESSORS(name, type)
+
+
+#define DEFINE_OLD_POOL(name, type, new_block_proc, clean_block_proc) \
+ OldMemoryPool _##name##_pool = { \
+ #name, name##_POOL_MAX_BLOCKS, name##_POOL_BLOCK_SIZE_BITS, sizeof(type), \
+ new_block_proc, clean_block_proc, \
+ 0, 0, NULL \
+ };
+
+
+#define STATIC_OLD_POOL(name, type, block_size_bits, max_blocks, new_block_proc, clean_block_proc) \
+ OLD_POOL_ENUM(name, type, block_size_bits, max_blocks) \
+ static DEFINE_OLD_POOL(name, type, new_block_proc, clean_block_proc) \
+ OLD_POOL_ACCESSORS(name, type)
+
+#endif /* OLDPOOL_H */
diff --git a/src/openttd.c b/src/openttd.c
new file mode 100644
index 000000000..3f15a944e
--- /dev/null
+++ b/src/openttd.c
@@ -0,0 +1,1685 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "string.h"
+#include "table/strings.h"
+#include "debug.h"
+#include "driver.h"
+#include "saveload.h"
+#include "strings.h"
+#include "map.h"
+#include "tile.h"
+#include "void_map.h"
+
+#define VARDEF
+#include "openttd.h"
+#include "bridge_map.h"
+#include "functions.h"
+#include "mixer.h"
+#include "spritecache.h"
+#include "strings.h"
+#include "gfx.h"
+#include "gfxinit.h"
+#include "gui.h"
+#include "station.h"
+#include "station_map.h"
+#include "town_map.h"
+#include "tunnel_map.h"
+#include "vehicle.h"
+#include "viewport.h"
+#include "window.h"
+#include "player.h"
+#include "command.h"
+#include "town.h"
+#include "industry.h"
+#include "news.h"
+#include "engine.h"
+#include "sound.h"
+#include "economy.h"
+#include "fileio.h"
+#include "hal.h"
+#include "airport.h"
+#include "console.h"
+#include "screenshot.h"
+#include "network/network.h"
+#include "signs.h"
+#include "depot.h"
+#include "waypoint.h"
+#include "ai/ai.h"
+#include "train.h"
+#include "yapf/yapf.h"
+#include "settings.h"
+#include "genworld.h"
+#include "date.h"
+#include "clear_map.h"
+#include "fontcache.h"
+#include "newgrf_config.h"
+
+#include "bridge_map.h"
+#include "clear_map.h"
+#include "rail_map.h"
+#include "road_map.h"
+#include "water_map.h"
+#include "industry_map.h"
+
+#include <stdarg.h>
+
+void CallLandscapeTick(void);
+void IncreaseDate(void);
+void DoPaletteAnimations(void);
+void MusicLoop(void);
+void ResetMusic(void);
+void InitializeStations(void);
+void DeleteAllPlayerStations(void);
+
+extern void SetDifficultyLevel(int mode, GameOptions *gm_opt);
+extern void DoStartupNewPlayer(bool is_ai);
+extern void ShowOSErrorBox(const char *buf);
+
+/* TODO: usrerror() for errors which are not of an internal nature but
+ * caused by the user, i.e. missing files or fatal configuration errors.
+ * Post-0.4.0 since Celestar doesn't want this in SVN before. --pasky */
+
+void CDECL error(const char *s, ...)
+{
+ va_list va;
+ char buf[512];
+
+ va_start(va, s);
+ vsnprintf(buf, lengthof(buf), s, va);
+ va_end(va);
+
+ ShowOSErrorBox(buf);
+ if (_video_driver != NULL) _video_driver->stop();
+
+ assert(0);
+ exit(1);
+}
+
+void CDECL ShowInfoF(const char *str, ...)
+{
+ va_list va;
+ char buf[1024];
+ va_start(va, str);
+ vsnprintf(buf, lengthof(buf), str, va);
+ va_end(va);
+ ShowInfo(buf);
+}
+
+
+void *ReadFileToMem(const char *filename, size_t *lenp, size_t maxsize)
+{
+ FILE *in;
+ byte *mem;
+ size_t len;
+
+ in = fopen(filename, "rb");
+ if (in == NULL) return NULL;
+
+ fseek(in, 0, SEEK_END);
+ len = ftell(in);
+ fseek(in, 0, SEEK_SET);
+ if (len > maxsize || (mem = malloc(len + 1)) == NULL) {
+ fclose(in);
+ return NULL;
+ }
+ mem[len] = 0;
+ if (fread(mem, len, 1, in) != 1) {
+ fclose(in);
+ free(mem);
+ return NULL;
+ }
+ fclose(in);
+
+ *lenp = len;
+ return mem;
+}
+
+static void showhelp(void)
+{
+ extern const char _openttd_revision[];
+ char buf[4096], *p;
+
+ p = buf;
+
+ p += snprintf(p, lengthof(buf), "OpenTTD %s\n", _openttd_revision);
+ p = strecpy(p,
+ "\n"
+ "\n"
+ "Command line options:\n"
+ " -v drv = Set video driver (see below)\n"
+ " -s drv = Set sound driver (see below)\n"
+ " -m drv = Set music driver (see below)\n"
+ " -r res = Set resolution (for instance 800x600)\n"
+ " -h = Display this help text\n"
+ " -t year = Set starting year\n"
+ " -d [[fac=]lvl[,...]]= Debug mode\n"
+ " -e = Start Editor\n"
+ " -g [savegame] = Start new/save game immediately\n"
+ " -G seed = Set random seed\n"
+ " -n [ip:port#player] = Start networkgame\n"
+ " -D = Start dedicated server\n"
+#if !defined(__MORPHOS__) && !defined(__AMIGA__) && !defined(WIN32)
+ " -f = Fork into the background (dedicated only)\n"
+#endif
+ " -i = Force to use the DOS palette\n"
+ " (use this if you see a lot of pink)\n"
+ " -c config_file = Use 'config_file' instead of 'openttd.cfg'\n"
+ "\n",
+ lastof(buf)
+ );
+
+ p = GetDriverList(p, lastof(buf));
+
+ ShowInfo(buf);
+}
+
+
+typedef struct {
+ char *opt;
+ int numleft;
+ char **argv;
+ const char *options;
+ char *cont;
+} MyGetOptData;
+
+static void MyGetOptInit(MyGetOptData *md, int argc, char **argv, const char *options)
+{
+ md->cont = NULL;
+ md->numleft = argc;
+ md->argv = argv;
+ md->options = options;
+}
+
+static int MyGetOpt(MyGetOptData *md)
+{
+ char *s,*r,*t;
+
+ s = md->cont;
+ if (s != NULL)
+ goto md_continue_here;
+
+ for (;;) {
+ if (--md->numleft < 0) return -1;
+
+ s = *md->argv++;
+ if (*s == '-') {
+md_continue_here:;
+ s++;
+ if (*s != 0) {
+ // Found argument, try to locate it in options.
+ if (*s == ':' || (r = strchr(md->options, *s)) == NULL) {
+ // ERROR!
+ return -2;
+ }
+ if (r[1] == ':') {
+ // Item wants an argument. Check if the argument follows, or if it comes as a separate arg.
+ if (!*(t = s + 1)) {
+ // It comes as a separate arg. Check if out of args?
+ if (--md->numleft < 0 || *(t = *md->argv) == '-') {
+ // Check if item is optional?
+ if (r[2] != ':')
+ return -2;
+ md->numleft++;
+ t = NULL;
+ } else {
+ md->argv++;
+ }
+ }
+ md->opt = t;
+ md->cont = NULL;
+ return *s;
+ }
+ md->opt = NULL;
+ md->cont = s;
+ return *s;
+ }
+ } else {
+ // This is currently not supported.
+ return -2;
+ }
+ }
+}
+
+
+static void ParseResolution(int res[2], const char *s)
+{
+ char *t = strchr(s, 'x');
+ if (t == NULL) {
+ ShowInfoF("Invalid resolution '%s'", s);
+ return;
+ }
+
+ res[0] = clamp(strtoul(s, NULL, 0), 64, MAX_SCREEN_WIDTH);
+ res[1] = clamp(strtoul(t + 1, NULL, 0), 64, MAX_SCREEN_HEIGHT);
+}
+
+static void InitializeDynamicVariables(void)
+{
+ /* Dynamic stuff needs to be initialized somewhere... */
+ _town_sort = NULL;
+ _industry_sort = NULL;
+}
+
+static void UnInitializeDynamicVariables(void)
+{
+ /* Dynamic stuff needs to be free'd somewhere... */
+ CleanPool(&_Town_pool);
+ CleanPool(&_Industry_pool);
+ CleanPool(&_Station_pool);
+ CleanPool(&_Vehicle_pool);
+ CleanPool(&_Sign_pool);
+ CleanPool(&_Order_pool);
+
+ free((void*)_town_sort);
+ free((void*)_industry_sort);
+}
+
+static void UnInitializeGame(void)
+{
+ UnInitWindowSystem();
+
+ free(_config_file);
+}
+
+static void LoadIntroGame(void)
+{
+ char filename[256];
+
+ _game_mode = GM_MENU;
+ CLRBITS(_display_opt, DO_TRANS_BUILDINGS); // don't make buildings transparent in intro
+ _opt_ptr = &_opt_newgame;
+ ResetGRFConfig(false);
+
+ // Setup main window
+ ResetWindowSystem();
+ SetupColorsAndInitialWindow();
+
+ // Generate a world.
+ snprintf(filename, lengthof(filename), "%sopntitle.dat", _paths.data_dir);
+#if defined SECOND_DATA_DIR
+ if (SaveOrLoad(filename, SL_LOAD) != SL_OK) {
+ snprintf(filename, lengthof(filename), "%sopntitle.dat", _paths.second_data_dir);
+ }
+#endif
+ if (SaveOrLoad(filename, SL_LOAD) != SL_OK) {
+ GenerateWorld(GW_EMPTY, 64, 64); // if failed loading, make empty world.
+ WaitTillGeneratedWorld();
+ }
+
+ _pause = 0;
+ SetLocalPlayer(0);
+ /* Make sure you can't scroll in the menu */
+ _scrolling_viewport = 0;
+ _cursor.fix_at = false;
+ MarkWholeScreenDirty();
+
+ // Play main theme
+ if (_music_driver->is_song_playing()) ResetMusic();
+}
+
+#if defined(UNIX) && !defined(__MORPHOS__)
+extern void DedicatedFork(void);
+#endif
+
+int ttd_main(int argc, char *argv[])
+{
+ MyGetOptData mgo;
+ int i;
+ const char *optformat;
+ char musicdriver[16], sounddriver[16], videodriver[16];
+ int resolution[2] = {0,0};
+ Year startyear = INVALID_YEAR;
+ uint generation_seed = GENERATE_NEW_SEED;
+ bool dedicated = false;
+ bool network = false;
+ char *network_conn = NULL;
+
+ musicdriver[0] = sounddriver[0] = videodriver[0] = 0;
+
+ _game_mode = GM_MENU;
+ _switch_mode = SM_MENU;
+ _switch_mode_errorstr = INVALID_STRING_ID;
+ _dedicated_forks = false;
+ _config_file = NULL;
+
+ // The last param of the following function means this:
+ // a letter means: it accepts that param (e.g.: -h)
+ // a ':' behind it means: it need a param (e.g.: -m<driver>)
+ // a '::' behind it means: it can optional have a param (e.g.: -d<debug>)
+ optformat = "m:s:v:hDn::eit:d::r:g::G:c:"
+#if !defined(__MORPHOS__) && !defined(__AMIGA__) && !defined(WIN32)
+ "f"
+#endif
+ ;
+
+ MyGetOptInit(&mgo, argc-1, argv+1, optformat);
+ while ((i = MyGetOpt(&mgo)) != -1) {
+ switch (i) {
+ case 'm': ttd_strlcpy(musicdriver, mgo.opt, sizeof(musicdriver)); break;
+ case 's': ttd_strlcpy(sounddriver, mgo.opt, sizeof(sounddriver)); break;
+ case 'v': ttd_strlcpy(videodriver, mgo.opt, sizeof(videodriver)); break;
+ case 'D':
+ strcpy(musicdriver, "null");
+ strcpy(sounddriver, "null");
+ strcpy(videodriver, "dedicated");
+ dedicated = true;
+ break;
+ case 'f': _dedicated_forks = true; break;
+ case 'n':
+ network = true;
+ network_conn = mgo.opt; // optional IP parameter, NULL if unset
+ break;
+ case 'r': ParseResolution(resolution, mgo.opt); break;
+ case 't': startyear = atoi(mgo.opt); break;
+ case 'd': {
+#if defined(WIN32)
+ CreateConsole();
+#endif
+ if (mgo.opt != NULL) SetDebugString(mgo.opt);
+ } break;
+ case 'e': _switch_mode = SM_EDITOR; break;
+ case 'i': _use_dos_palette = true; break;
+ case 'g':
+ if (mgo.opt != NULL) {
+ strcpy(_file_to_saveload.name, mgo.opt);
+ _switch_mode = SM_LOAD;
+ } else {
+ _switch_mode = SM_NEWGAME;
+ }
+ break;
+ case 'G': generation_seed = atoi(mgo.opt); break;
+ case 'c': _config_file = strdup(mgo.opt); break;
+ case -2:
+ case 'h':
+ showhelp();
+ return 0;
+ }
+ }
+
+ DeterminePaths();
+ CheckExternalFiles();
+
+#if defined(UNIX) && !defined(__MORPHOS__)
+ // We must fork here, or we'll end up without some resources we need (like sockets)
+ if (_dedicated_forks)
+ DedicatedFork();
+#endif
+
+ LoadFromConfig();
+ CheckConfig();
+ LoadFromHighScore();
+
+ // override config?
+ if (musicdriver[0]) ttd_strlcpy(_ini_musicdriver, musicdriver, sizeof(_ini_musicdriver));
+ if (sounddriver[0]) ttd_strlcpy(_ini_sounddriver, sounddriver, sizeof(_ini_sounddriver));
+ if (videodriver[0]) ttd_strlcpy(_ini_videodriver, videodriver, sizeof(_ini_videodriver));
+ if (resolution[0]) { _cur_resolution[0] = resolution[0]; _cur_resolution[1] = resolution[1]; }
+ if (startyear != INVALID_YEAR) _patches_newgame.starting_year = startyear;
+ if (generation_seed != GENERATE_NEW_SEED) _patches_newgame.generation_seed = generation_seed;
+
+ if (_dedicated_forks && !dedicated) _dedicated_forks = false;
+
+ // enumerate language files
+ InitializeLanguagePacks();
+
+ // initialize screenshot formats
+ InitializeScreenshotFormats();
+
+ // initialize airport state machines
+ InitializeAirports();
+
+ /* initialize all variables that are allocated dynamically */
+ InitializeDynamicVariables();
+
+ /* start the AI */
+ AI_Initialize();
+
+ // Sample catalogue
+ DEBUG(misc, 1, "Loading sound effects...");
+ MxInitialize(11025);
+ SoundInitialize("sample.cat");
+
+ /* Initialize FreeType */
+ InitFreeType();
+
+ // This must be done early, since functions use the InvalidateWindow* calls
+ InitWindowSystem();
+
+ /* Initialize game palette */
+ GfxInitPalettes();
+
+ DEBUG(driver, 1, "Loading drivers...");
+ LoadDriver(SOUND_DRIVER, _ini_sounddriver);
+ LoadDriver(MUSIC_DRIVER, _ini_musicdriver);
+ LoadDriver(VIDEO_DRIVER, _ini_videodriver); // load video last, to prevent an empty window while sound and music loads
+ _savegame_sort_order = SORT_BY_DATE | SORT_DESCENDING;
+
+ // restore saved music volume
+ _music_driver->set_volume(msf.music_vol);
+
+ NetworkStartUp(); // initialize network-core
+
+ ScanNewGRFFiles();
+
+ _opt_ptr = &_opt_newgame;
+ ResetGRFConfig(false);
+
+ /* XXX - ugly hack, if diff_level is 9, it means we got no setting from the config file */
+ if (_opt_newgame.diff_level == 9) SetDifficultyLevel(0, &_opt_newgame);
+
+ /* Make sure _patches is filled with _patches_newgame if we switch to a game directly */
+ if (_switch_mode != SM_NONE) {
+ _opt = _opt_newgame;
+ UpdatePatches();
+ }
+
+ // initialize the ingame console
+ IConsoleInit();
+ _cursor.in_window = true;
+ InitializeGUI();
+ IConsoleCmdExec("exec scripts/autoexec.scr 0");
+
+ GenerateWorld(GW_EMPTY, 64, 64); // Make the viewport initialization happy
+ WaitTillGeneratedWorld();
+
+#ifdef ENABLE_NETWORK
+ if (network && _network_available) {
+ if (network_conn != NULL) {
+ const char *port = NULL;
+ const char *player = NULL;
+ uint16 rport;
+
+ rport = NETWORK_DEFAULT_PORT;
+ _network_playas = PLAYER_NEW_COMPANY;
+
+ ParseConnectionString(&player, &port, network_conn);
+
+ if (player != NULL) {
+ _network_playas = atoi(player);
+
+ if (_network_playas != PLAYER_SPECTATOR) {
+ _network_playas--;
+ if (!IsValidPlayer(_network_playas)) return false;
+ }
+ }
+ if (port != NULL) rport = atoi(port);
+
+ LoadIntroGame();
+ _switch_mode = SM_NONE;
+ NetworkClientConnectGame(network_conn, rport);
+ }
+ }
+#endif /* ENABLE_NETWORK */
+
+ _video_driver->main_loop();
+
+ WaitTillSaved();
+ IConsoleFree();
+
+ if (_network_available) NetworkShutDown(); // Shut down the network and close any open connections
+
+ _video_driver->stop();
+ _music_driver->stop();
+ _sound_driver->stop();
+
+ SaveToConfig();
+ SaveToHighScore();
+
+ // uninitialize airport state machines
+ UnInitializeAirports();
+
+ /* uninitialize variables that are allocated dynamic */
+ UnInitializeDynamicVariables();
+
+ /* stop the AI */
+ AI_Uninitialize();
+
+ /* Close all and any open filehandles */
+ FioCloseAll();
+ UnInitializeGame();
+
+ return 0;
+}
+
+void HandleExitGameRequest(void)
+{
+ if (_game_mode == GM_MENU) { // do not ask to quit on the main screen
+ _exit_game = true;
+ } else if (_patches.autosave_on_exit) {
+ DoExitSave();
+ _exit_game = true;
+ } else {
+ AskExitGame();
+ }
+}
+
+
+/** Mutex so that only one thread can communicate with the main program
+ * at any given time */
+static ThreadMsg _message = MSG_OTTD_NO_MESSAGE;
+
+static inline void OTTD_ReleaseMutex(void) {_message = MSG_OTTD_NO_MESSAGE;}
+static inline ThreadMsg OTTD_PollThreadEvent(void) {return _message;}
+
+/** Called by running thread to execute some action in the main game.
+ * It will stall as long as the mutex is not freed (handled) by the game */
+void OTTD_SendThreadMessage(ThreadMsg msg)
+{
+ if (_exit_game) return;
+ while (_message != MSG_OTTD_NO_MESSAGE) CSleep(10);
+
+ _message = msg;
+}
+
+
+/** Handle the user-messages sent to us
+ * @param message message sent
+ */
+static void ProcessSentMessage(ThreadMsg message)
+{
+ switch (message) {
+ case MSG_OTTD_SAVETHREAD_DONE: SaveFileDone(); break;
+ case MSG_OTTD_SAVETHREAD_ERROR: SaveFileError(); break;
+ default: NOT_REACHED();
+ }
+
+ OTTD_ReleaseMutex(); // release mutex so that other threads, messages can be handled
+}
+
+static void ShowScreenshotResult(bool b)
+{
+ if (b) {
+ SetDParamStr(0, _screenshot_name);
+ ShowErrorMessage(INVALID_STRING_ID, STR_031B_SCREENSHOT_SUCCESSFULLY, 0, 0);
+ } else {
+ ShowErrorMessage(INVALID_STRING_ID, STR_031C_SCREENSHOT_FAILED, 0, 0);
+ }
+
+}
+
+static void MakeNewGameDone(void)
+{
+ /* In a dedicated server, the server does not play */
+ if (_network_dedicated) {
+ SetLocalPlayer(PLAYER_SPECTATOR);
+ return;
+ }
+
+ /* Create a single player */
+ DoStartupNewPlayer(false);
+
+ SetLocalPlayer(0);
+ _current_player = _local_player;
+ DoCommandP(0, (_patches.autorenew << 15 ) | (_patches.autorenew_months << 16) | 4, _patches.autorenew_money, NULL, CMD_SET_AUTOREPLACE);
+
+ SettingsDisableElrail(_patches.disable_elrails);
+
+ MarkWholeScreenDirty();
+}
+
+static void MakeNewGame(bool from_heightmap)
+{
+ _game_mode = GM_NORMAL;
+
+ ResetGRFConfig(true);
+
+ GenerateWorldSetCallback(&MakeNewGameDone);
+ GenerateWorld(from_heightmap ? GW_HEIGHTMAP : GW_NEWGAME, 1 << _patches.map_x, 1 << _patches.map_y);
+}
+
+static void MakeNewEditorWorldDone(void)
+{
+ SetLocalPlayer(OWNER_NONE);
+
+ MarkWholeScreenDirty();
+}
+
+static void MakeNewEditorWorld(void)
+{
+ _game_mode = GM_EDITOR;
+
+ ResetGRFConfig(true);
+
+ GenerateWorldSetCallback(&MakeNewEditorWorldDone);
+ GenerateWorld(GW_EMPTY, 1 << _patches.map_x, 1 << _patches.map_y);
+}
+
+void StartupPlayers(void);
+void StartupDisasters(void);
+extern void StartupEconomy(void);
+
+/**
+ * Start Scenario starts a new game based on a scenario.
+ * Eg 'New Game' --> select a preset scenario
+ * This starts a scenario based on your current difficulty settings
+ */
+static void StartScenario(void)
+{
+ _game_mode = GM_NORMAL;
+
+ // invalid type
+ if (_file_to_saveload.mode == SL_INVALID) {
+ DEBUG(sl, 0, "Savegame is obsolete or invalid format: '%s'", _file_to_saveload.name);
+ ShowErrorMessage(INVALID_STRING_ID, STR_4009_GAME_LOAD_FAILED, 0, 0);
+ _game_mode = GM_MENU;
+ return;
+ }
+
+ // Reinitialize windows
+ ResetWindowSystem();
+
+ SetupColorsAndInitialWindow();
+
+ ResetGRFConfig(true);
+
+ // Load game
+ if (SaveOrLoad(_file_to_saveload.name, _file_to_saveload.mode) != SL_OK) {
+ LoadIntroGame();
+ ShowErrorMessage(INVALID_STRING_ID, STR_4009_GAME_LOAD_FAILED, 0, 0);
+ }
+
+ _opt_ptr = &_opt;
+ _opt_ptr->diff = _opt_newgame.diff;
+ _opt.diff_level = _opt_newgame.diff_level;
+
+ // Inititalize data
+ StartupEconomy();
+ StartupPlayers();
+ StartupEngines();
+ StartupDisasters();
+
+ SetLocalPlayer(0);
+ _current_player = _local_player;
+ DoCommandP(0, (_patches.autorenew << 15 ) | (_patches.autorenew_months << 16) | 4, _patches.autorenew_money, NULL, CMD_SET_AUTOREPLACE);
+
+ MarkWholeScreenDirty();
+}
+
+bool SafeSaveOrLoad(const char *filename, int mode, int newgm)
+{
+ byte ogm = _game_mode;
+
+ _game_mode = newgm;
+ switch (SaveOrLoad(filename, mode)) {
+ case SL_OK: return true;
+
+ case SL_REINIT:
+ switch (ogm) {
+ case GM_MENU: LoadIntroGame(); break;
+ case GM_EDITOR: MakeNewEditorWorld(); break;
+ default: MakeNewGame(false); break;
+ }
+ return false;
+
+ default:
+ _game_mode = ogm;
+ return false;
+ }
+}
+
+void SwitchMode(int new_mode)
+{
+#ifdef ENABLE_NETWORK
+ // If we are saving something, the network stays in his current state
+ if (new_mode != SM_SAVE) {
+ // If the network is active, make it not-active
+ if (_networking) {
+ if (_network_server && (new_mode == SM_LOAD || new_mode == SM_NEWGAME)) {
+ NetworkReboot();
+ NetworkUDPClose();
+ } else {
+ NetworkDisconnect();
+ NetworkUDPClose();
+ }
+ }
+
+ // If we are a server, we restart the server
+ if (_is_network_server) {
+ // But not if we are going to the menu
+ if (new_mode != SM_MENU) {
+ NetworkServerStart();
+ } else {
+ // This client no longer wants to be a network-server
+ _is_network_server = false;
+ }
+ }
+ }
+#endif /* ENABLE_NETWORK */
+
+ switch (new_mode) {
+ case SM_EDITOR: /* Switch to scenario editor */
+ MakeNewEditorWorld();
+ break;
+
+ case SM_NEWGAME: /* New Game --> 'Random game' */
+#ifdef ENABLE_NETWORK
+ if (_network_server) {
+ snprintf(_network_game_info.map_name, lengthof(_network_game_info.map_name), "Random Map");
+ }
+#endif /* ENABLE_NETWORK */
+ MakeNewGame(false);
+ break;
+
+ case SM_START_SCENARIO: /* New Game --> Choose one of the preset scenarios */
+#ifdef ENABLE_NETWORK
+ if (_network_server) {
+ snprintf(_network_game_info.map_name, lengthof(_network_game_info.map_name), "%s (Loaded scenario)", _file_to_saveload.title);
+ }
+#endif /* ENABLE_NETWORK */
+ StartScenario();
+ break;
+
+ case SM_LOAD: { /* Load game, Play Scenario */
+ _opt_ptr = &_opt;
+ ResetGRFConfig(true);
+
+ if (!SafeSaveOrLoad(_file_to_saveload.name, _file_to_saveload.mode, GM_NORMAL)) {
+ LoadIntroGame();
+ ShowErrorMessage(INVALID_STRING_ID, STR_4009_GAME_LOAD_FAILED, 0, 0);
+ } else {
+ /* Update the local player for a loaded game. It is either always
+ * player #1 (eg 0) or in the case of a dedicated server a spectator */
+ SetLocalPlayer(_network_dedicated ? PLAYER_SPECTATOR : 0);
+ DoCommandP(0, 0, 0, NULL, CMD_PAUSE); // decrease pause counter (was increased from opening load dialog)
+#ifdef ENABLE_NETWORK
+ if (_network_server) {
+ snprintf(_network_game_info.map_name, lengthof(_network_game_info.map_name), "%s (Loaded game)", _file_to_saveload.title);
+ }
+#endif /* ENABLE_NETWORK */
+ }
+ break;
+ }
+
+ case SM_START_HEIGHTMAP: /* Load a heightmap and start a new game from it */
+#ifdef ENABLE_NETWORK
+ if (_network_server) {
+ snprintf(_network_game_info.map_name, lengthof(_network_game_info.map_name), "%s (Heightmap)", _file_to_saveload.title);
+ }
+#endif /* ENABLE_NETWORK */
+ MakeNewGame(true);
+ break;
+
+ case SM_LOAD_HEIGHTMAP: /* Load heightmap from scenario editor */
+ SetLocalPlayer(OWNER_NONE);
+
+ GenerateWorld(GW_HEIGHTMAP, 1 << _patches.map_x, 1 << _patches.map_y);
+ MarkWholeScreenDirty();
+ break;
+
+ case SM_LOAD_SCENARIO: { /* Load scenario from scenario editor */
+ if (SafeSaveOrLoad(_file_to_saveload.name, _file_to_saveload.mode, GM_EDITOR)) {
+ Player *p;
+
+ _opt_ptr = &_opt;
+
+ SetLocalPlayer(OWNER_NONE);
+ _generating_world = true;
+ /* Delete all players */
+ FOR_ALL_PLAYERS(p) {
+ if (p->is_active) {
+ ChangeOwnershipOfPlayerItems(p->index, PLAYER_SPECTATOR);
+ p->is_active = false;
+ }
+ }
+ _generating_world = false;
+ _patches_newgame.starting_year = _cur_year;
+ // delete all stations owned by a player
+ DeleteAllPlayerStations();
+ } else {
+ ShowErrorMessage(INVALID_STRING_ID, STR_4009_GAME_LOAD_FAILED, 0, 0);
+ }
+ break;
+ }
+
+ case SM_MENU: /* Switch to game intro menu */
+ LoadIntroGame();
+ break;
+
+ case SM_SAVE: /* Save game */
+ if (SaveOrLoad(_file_to_saveload.name, SL_SAVE) != SL_OK) {
+ ShowErrorMessage(INVALID_STRING_ID, STR_4007_GAME_SAVE_FAILED, 0, 0);
+ } else {
+ DeleteWindowById(WC_SAVELOAD, 0);
+ }
+ break;
+
+ case SM_GENRANDLAND: /* Generate random land within scenario editor */
+ SetLocalPlayer(OWNER_NONE);
+ GenerateWorld(GW_RANDOM, 1 << _patches.map_x, 1 << _patches.map_y);
+ // XXX: set date
+ MarkWholeScreenDirty();
+ break;
+ }
+
+ if (_switch_mode_errorstr != INVALID_STRING_ID) {
+ ShowErrorMessage(INVALID_STRING_ID, _switch_mode_errorstr, 0, 0);
+ }
+}
+
+
+// State controlling game loop.
+// The state must not be changed from anywhere
+// but here.
+// That check is enforced in DoCommand.
+void StateGameLoop(void)
+{
+ // dont execute the state loop during pause
+ if (_pause) return;
+ if (IsGeneratingWorld()) return;
+
+ if (_game_mode == GM_EDITOR) {
+ RunTileLoop();
+ CallVehicleTicks();
+ CallLandscapeTick();
+ CallWindowTickEvent();
+ NewsLoop();
+ } else {
+ // All these actions has to be done from OWNER_NONE
+ // for multiplayer compatibility
+ PlayerID p = _current_player;
+ _current_player = OWNER_NONE;
+
+ AnimateAnimatedTiles();
+ IncreaseDate();
+ RunTileLoop();
+ CallVehicleTicks();
+ CallLandscapeTick();
+
+ AI_RunGameLoop();
+
+ CallWindowTickEvent();
+ NewsLoop();
+ _current_player = p;
+ }
+}
+
+static void DoAutosave(void)
+{
+ char buf[200];
+
+ if (_patches.keep_all_autosave && _local_player != PLAYER_SPECTATOR) {
+ const Player *p = GetPlayer(_local_player);
+ char* s = buf;
+
+ s += snprintf(buf, lengthof(buf), "%s%s", _paths.autosave_dir, PATHSEP);
+
+ SetDParam(0, p->name_1);
+ SetDParam(1, p->name_2);
+ SetDParam(2, _date);
+ s = GetString(s, STR_4004, lastof(buf));
+ strecpy(s, ".sav", lastof(buf));
+ } else { /* generate a savegame name and number according to _patches.max_num_autosaves */
+ snprintf(buf, lengthof(buf), "%s%sautosave%d.sav", _paths.autosave_dir, PATHSEP, _autosave_ctr);
+
+ _autosave_ctr++;
+ if (_autosave_ctr >= _patches.max_num_autosaves) {
+ // we reached the limit for numbers of autosaves. We will start over
+ _autosave_ctr = 0;
+ }
+ }
+
+ DEBUG(sl, 2, "Autosaving to '%s'", buf);
+ if (SaveOrLoad(buf, SL_SAVE) != SL_OK)
+ ShowErrorMessage(INVALID_STRING_ID, STR_AUTOSAVE_FAILED, 0, 0);
+}
+
+static void ScrollMainViewport(int x, int y)
+{
+ if (_game_mode != GM_MENU) {
+ Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
+ assert(w);
+
+ WP(w,vp_d).scrollpos_x += x << w->viewport->zoom;
+ WP(w,vp_d).scrollpos_y += y << w->viewport->zoom;
+ }
+}
+
+static const int8 scrollamt[16][2] = {
+ { 0, 0},
+ {-2, 0}, // 1 : left
+ { 0, -2}, // 2 : up
+ {-2, -1}, // 3 : left + up
+ { 2, 0}, // 4 : right
+ { 0, 0}, // 5 : left + right
+ { 2, -1}, // 6 : right + up
+ { 0, -2}, // 7 : left + right + up = up
+ { 0 ,2}, // 8 : down
+ {-2 ,1}, // 9 : down+left
+ { 0, 0}, // 10 : impossible
+ {-2, 0}, // 11 : left + up + down = left
+ { 2, 1}, // 12 : down+right
+ { 0, 2}, // 13 : left + right + down = down
+ { 0, -2}, // 14 : left + right + up = up
+ { 0, 0}, // 15 : impossible
+};
+
+static void HandleKeyScrolling(void)
+{
+ if (_dirkeys && !_no_scroll) {
+ int factor = _shift_pressed ? 50 : 10;
+ ScrollMainViewport(scrollamt[_dirkeys][0] * factor, scrollamt[_dirkeys][1] * factor);
+ }
+}
+
+void GameLoop(void)
+{
+ ThreadMsg message;
+
+ if ((message = OTTD_PollThreadEvent()) != 0) ProcessSentMessage(message);
+
+ // autosave game?
+ if (_do_autosave) {
+ _do_autosave = false;
+ DoAutosave();
+ RedrawAutosave();
+ }
+
+ // handle scrolling of the main window
+ HandleKeyScrolling();
+
+ // make a screenshot?
+ if (IsScreenshotRequested()) ShowScreenshotResult(MakeScreenshot());
+
+ // switch game mode?
+ if (_switch_mode != SM_NONE) {
+ SwitchMode(_switch_mode);
+ _switch_mode = SM_NONE;
+ }
+
+ IncreaseSpriteLRU();
+ InteractiveRandom();
+
+ if (_scroller_click_timeout > 3) {
+ _scroller_click_timeout -= 3;
+ } else {
+ _scroller_click_timeout = 0;
+ }
+
+ _caret_timer += 3;
+ _timer_counter += 8;
+ CursorTick();
+
+#ifdef ENABLE_NETWORK
+ // Check for UDP stuff
+ if (_network_available) NetworkUDPGameLoop();
+
+ if (_networking && !IsGeneratingWorld()) {
+ // Multiplayer
+ NetworkGameLoop();
+ } else {
+ if (_network_reconnect > 0 && --_network_reconnect == 0) {
+ // This means that we want to reconnect to the last host
+ // We do this here, because it means that the network is really closed
+ NetworkClientConnectGame(_network_last_host, _network_last_port);
+ }
+ // Singleplayer
+ StateGameLoop();
+ }
+#else
+ StateGameLoop();
+#endif /* ENABLE_NETWORK */
+
+ if (!_pause && _display_opt & DO_FULL_ANIMATION) DoPaletteAnimations();
+
+ if (!_pause || _cheats.build_in_pause.value) MoveAllTextEffects();
+
+ InputLoop();
+
+ MusicLoop();
+}
+
+void BeforeSaveGame(void)
+{
+ const Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
+
+ if (w != NULL) {
+ _saved_scrollpos_x = WP(w, const vp_d).scrollpos_x;
+ _saved_scrollpos_y = WP(w, const vp_d).scrollpos_y;
+ _saved_scrollpos_zoom = w->viewport->zoom;
+ }
+}
+
+static void ConvertTownOwner(void)
+{
+ TileIndex tile;
+
+ for (tile = 0; tile != MapSize(); tile++) {
+ switch (GetTileType(tile)) {
+ case MP_STREET:
+ if (IsLevelCrossing(tile) && GetCrossingRoadOwner(tile) & 0x80) {
+ SetCrossingRoadOwner(tile, OWNER_TOWN);
+ }
+ /* FALLTHROUGH */
+
+ case MP_TUNNELBRIDGE:
+ if (GetTileOwner(tile) & 0x80) SetTileOwner(tile, OWNER_TOWN);
+ break;
+
+ default: break;
+ }
+ }
+}
+
+// before savegame version 4, the name of the company determined if it existed
+static void CheckIsPlayerActive(void)
+{
+ Player *p;
+
+ FOR_ALL_PLAYERS(p) {
+ if (p->name_1 != 0) p->is_active = true;
+ }
+}
+
+// since savegame version 4.1, exclusive transport rights are stored at towns
+static void UpdateExclusiveRights(void)
+{
+ Town *t;
+
+ FOR_ALL_TOWNS(t) {
+ t->exclusivity = (byte)-1;
+ }
+
+ /* FIXME old exclusive rights status is not being imported (stored in s->blocked_months_obsolete)
+ * could be implemented this way:
+ * 1.) Go through all stations
+ * Build an array town_blocked[ town_id ][ player_id ]
+ * that stores if at least one station in that town is blocked for a player
+ * 2.) Go through that array, if you find a town that is not blocked for
+ * one player, but for all others, then give him exclusivity.
+ */
+}
+
+static const byte convert_currency[] = {
+ 0, 1, 12, 8, 3,
+ 10, 14, 19, 4, 5,
+ 9, 11, 13, 6, 17,
+ 16, 22, 21, 7, 15,
+ 18, 2, 20, };
+
+// since savegame version 4.2 the currencies are arranged differently
+static void UpdateCurrencies(void)
+{
+ _opt.currency = convert_currency[_opt.currency];
+}
+
+/* Up to revision 1413 the invisible tiles at the southern border have not been
+ * MP_VOID, even though they should have. This is fixed by this function
+ */
+static void UpdateVoidTiles(void)
+{
+ uint i;
+
+ for (i = 0; i < MapMaxY(); ++i) MakeVoid(i * MapSizeX() + MapMaxX());
+ for (i = 0; i < MapSizeX(); ++i) MakeVoid(MapSizeX() * MapMaxY() + i);
+}
+
+// since savegame version 6.0 each sign has an "owner", signs without owner (from old games are set to 255)
+static void UpdateSignOwner(void)
+{
+ Sign *si;
+
+ FOR_ALL_SIGNS(si) si->owner = OWNER_NONE;
+}
+
+extern void UpdateOldAircraft( void );
+extern void UpdateOilRig( void );
+
+
+static inline RailType UpdateRailType(RailType rt, RailType min)
+{
+ return rt >= min ? (RailType)(rt + 1): rt;
+}
+
+bool AfterLoadGame(void)
+{
+ Window *w;
+ ViewPort *vp;
+ Player *p;
+
+ // in version 2.1 of the savegame, town owner was unified.
+ if (CheckSavegameVersionOldStyle(2, 1)) ConvertTownOwner();
+
+ // from version 4.1 of the savegame, exclusive rights are stored at towns
+ if (CheckSavegameVersionOldStyle(4, 1)) UpdateExclusiveRights();
+
+ // from version 4.2 of the savegame, currencies are in a different order
+ if (CheckSavegameVersionOldStyle(4, 2)) UpdateCurrencies();
+
+ // from version 6.1 of the savegame, signs have an "owner"
+ if (CheckSavegameVersionOldStyle(6, 1)) UpdateSignOwner();
+
+ /* In old version there seems to be a problem that water is owned by
+ OWNER_NONE, not OWNER_WATER.. I can't replicate it for the current
+ (4.3) version, so I just check when versions are older, and then
+ walk through the whole map.. */
+ if (CheckSavegameVersionOldStyle(4, 3)) {
+ TileIndex tile = TileXY(0, 0);
+ uint w = MapSizeX();
+ uint h = MapSizeY();
+
+ BEGIN_TILE_LOOP(tile_cur, w, h, tile)
+ if (IsTileType(tile_cur, MP_WATER) && GetTileOwner(tile_cur) >= MAX_PLAYERS)
+ SetTileOwner(tile_cur, OWNER_WATER);
+ END_TILE_LOOP(tile_cur, w, h, tile)
+ }
+
+ // convert road side to my format.
+ if (_opt.road_side) _opt.road_side = 1;
+
+ /* Check all NewGRFs are present */
+ if (!IsGoodGRFConfigList()) return false;
+
+ /* Update current year
+ * must be done before loading sprites as some newgrfs check it */
+ SetDate(_date);
+
+ // Load the sprites
+ GfxLoadSprites();
+ LoadStringWidthTable();
+
+ /* Connect front and rear engines of multiheaded trains and converts
+ * subtype to the new format */
+ if (CheckSavegameVersionOldStyle(17, 1)) ConvertOldMultiheadToNew();
+
+ /* Connect front and rear engines of multiheaded trains */
+ ConnectMultiheadedTrains();
+
+ // reinit the landscape variables (landscape might have changed)
+ InitializeLandscapeVariables(true);
+
+ // Update all vehicles
+ AfterLoadVehicles();
+
+ // Update all waypoints
+ if (CheckSavegameVersion(12)) FixOldWaypoints();
+
+ UpdateAllWaypointSigns();
+
+ // in version 2.2 of the savegame, we have new airports
+ if (CheckSavegameVersionOldStyle(2, 2)) UpdateOldAircraft();
+
+ UpdateAllStationVirtCoord();
+
+ // Setup town coords
+ AfterLoadTown();
+ UpdateAllSignVirtCoords();
+
+ // make sure there is a town in the game
+ if (_game_mode == GM_NORMAL && !ClosestTownFromTile(0, (uint)-1)) {
+ _error_message = STR_NO_TOWN_IN_SCENARIO;
+ return false;
+ }
+
+ // Initialize windows
+ ResetWindowSystem();
+ SetupColorsAndInitialWindow();
+
+ w = FindWindowById(WC_MAIN_WINDOW, 0);
+
+ WP(w,vp_d).scrollpos_x = _saved_scrollpos_x;
+ WP(w,vp_d).scrollpos_y = _saved_scrollpos_y;
+
+ vp = w->viewport;
+ vp->zoom = _saved_scrollpos_zoom;
+ vp->virtual_width = vp->width << vp->zoom;
+ vp->virtual_height = vp->height << vp->zoom;
+
+ // in version 4.1 of the savegame, is_active was introduced to determine
+ // if a player does exist, rather then checking name_1
+ if (CheckSavegameVersionOldStyle(4, 1)) CheckIsPlayerActive();
+
+ // the void tiles on the southern border used to belong to a wrong class (pre 4.3).
+ if (CheckSavegameVersionOldStyle(4, 3)) UpdateVoidTiles();
+
+ // If Load Scenario / New (Scenario) Game is used,
+ // a player does not exist yet. So create one here.
+ // 1 exeption: network-games. Those can have 0 players
+ // But this exeption is not true for network_servers!
+ if (!_players[0].is_active && (!_networking || (_networking && _network_server)))
+ DoStartupNewPlayer(false);
+
+ DoZoomInOutWindow(ZOOM_NONE, w); // update button status
+ MarkWholeScreenDirty();
+
+ // In 5.1, Oilrigs have been moved (again)
+ if (CheckSavegameVersionOldStyle(5, 1)) UpdateOilRig();
+
+ /* In version 6.1 we put the town index in the map-array. To do this, we need
+ * to use m2 (16bit big), so we need to clean m2, and that is where this is
+ * all about ;) */
+ if (CheckSavegameVersionOldStyle(6, 1)) {
+ BEGIN_TILE_LOOP(tile, MapSizeX(), MapSizeY(), 0) {
+ switch (GetTileType(tile)) {
+ case MP_HOUSE:
+ _m[tile].m4 = _m[tile].m2;
+ SetTownIndex(tile, CalcClosestTownFromTile(tile, (uint)-1)->index);
+ break;
+
+ case MP_STREET:
+ _m[tile].m4 |= (_m[tile].m2 << 4);
+ if (IsTileOwner(tile, OWNER_TOWN)) {
+ SetTownIndex(tile, CalcClosestTownFromTile(tile, (uint)-1)->index);
+ } else {
+ SetTownIndex(tile, 0);
+ }
+ break;
+
+ default: break;
+ }
+ } END_TILE_LOOP(tile, MapSizeX(), MapSizeY(), 0);
+ }
+
+ /* From version 9.0, we update the max passengers of a town (was sometimes negative
+ * before that. */
+ if (CheckSavegameVersion(9)) {
+ Town *t;
+ FOR_ALL_TOWNS(t) UpdateTownMaxPass(t);
+ }
+
+ /* From version 16.0, we included autorenew on engines, which are now saved, but
+ * of course, we do need to initialize them for older savegames. */
+ if (CheckSavegameVersion(16)) {
+ FOR_ALL_PLAYERS(p) {
+ p->engine_renew_list = NULL;
+ p->engine_renew = false;
+ p->engine_renew_months = -6;
+ p->engine_renew_money = 100000;
+ }
+
+ /* When loading a game, _local_player is not yet set to the correct value.
+ * However, in a dedicated server we are a spectator, so nothing needs to
+ * happen. In case we are not a dedicated server, the local player always
+ * becomes player 0, unless we are in the scenario editor where all the
+ * players are 'invalid'.
+ */
+ if (!_network_dedicated && IsValidPlayer(0)) {
+ p = GetPlayer(0);
+ p->engine_renew = _patches.autorenew;
+ p->engine_renew_months = _patches.autorenew_months;
+ p->engine_renew_money = _patches.autorenew_money;
+ }
+ }
+
+ if (CheckSavegameVersion(42)) {
+ TileIndex map_end = MapSize();
+ TileIndex tile;
+ Vehicle* v;
+
+ for (tile = 0; tile != map_end; tile++) {
+ if (MayHaveBridgeAbove(tile)) ClearBridgeMiddle(tile);
+ if (IsBridgeTile(tile)) {
+ if (HASBIT(_m[tile].m5, 6)) { // middle part
+ Axis axis = (Axis)GB(_m[tile].m5, 0, 1);
+
+ if (HASBIT(_m[tile].m5, 5)) { // transport route under bridge?
+ if (GB(_m[tile].m5, 3, 2) == TRANSPORT_RAIL) {
+ MakeRailNormal(
+ tile,
+ GetTileOwner(tile),
+ axis == AXIS_X ? TRACK_BIT_Y : TRACK_BIT_X,
+ GetRailType(tile)
+ );
+ } else {
+ TownID town = IsTileOwner(tile, OWNER_TOWN) ? ClosestTownFromTile(tile, (uint)-1)->index : 0;
+
+ MakeRoadNormal(
+ tile,
+ GetTileOwner(tile),
+ axis == AXIS_X ? ROAD_Y : ROAD_X,
+ town
+ );
+ }
+ } else {
+ if (GB(_m[tile].m5, 3, 2) == 0) {
+ MakeClear(tile, CLEAR_GRASS, 3);
+ } else {
+ MakeCanal(tile, GetTileOwner(tile));
+ }
+ }
+ SetBridgeMiddle(tile, axis);
+ } else { // ramp
+ Axis axis = (Axis)GB(_m[tile].m5, 0, 1);
+ uint north_south = GB(_m[tile].m5, 5, 1);
+ DiagDirection dir = ReverseDiagDir(XYNSToDiagDir(axis, north_south));
+ TransportType type = (TransportType)GB(_m[tile].m5, 1, 2);
+
+ _m[tile].m5 = 1 << 7 | type << 2 | dir;
+ }
+ }
+ }
+
+ FOR_ALL_VEHICLES(v) {
+ if (v->type != VEH_Train && v->type != VEH_Road) continue;
+ if (IsBridgeTile(v->tile)) {
+ DiagDirection dir = GetBridgeRampDirection(v->tile);
+
+ if (dir != DirToDiagDir(v->direction)) continue;
+ switch (dir) {
+ default: NOT_REACHED();
+ case DIAGDIR_NE: if ((v->x_pos & 0xF) != 0) continue; break;
+ case DIAGDIR_SE: if ((v->y_pos & 0xF) != TILE_SIZE - 1) continue; break;
+ case DIAGDIR_SW: if ((v->x_pos & 0xF) != TILE_SIZE - 1) continue; break;
+ case DIAGDIR_NW: if ((v->y_pos & 0xF) != 0) continue; break;
+ }
+ } else if (v->z_pos > GetSlopeZ(v->x_pos, v->y_pos)) {
+ v->tile = GetNorthernBridgeEnd(v->tile);
+ } else {
+ continue;
+ }
+ if (v->type == VEH_Train) {
+ v->u.rail.track = 0x40;
+ } else {
+ v->u.road.state = 0xFF;
+ }
+ }
+ }
+
+ /* Elrails got added in rev 24 */
+ if (CheckSavegameVersion(24)) {
+ Vehicle *v;
+ uint i;
+ TileIndex t;
+ RailType min_rail = RAILTYPE_ELECTRIC;
+
+ for (i = 0; i < lengthof(_engines); i++) {
+ Engine *e = GetEngine(i);
+ if (e->type == VEH_Train &&
+ (e->railtype != RAILTYPE_RAIL || RailVehInfo(i)->engclass == 2)) {
+ e->railtype++;
+ }
+ }
+
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == VEH_Train) {
+ RailType rt = GetEngine(v->engine_type)->railtype;
+
+ v->u.rail.railtype = rt;
+ if (rt == RAILTYPE_ELECTRIC) min_rail = RAILTYPE_RAIL;
+ }
+ }
+
+ /* .. so we convert the entire map from normal to elrail (so maintain "fairness") */
+ for (t = 0; t < MapSize(); t++) {
+ switch (GetTileType(t)) {
+ case MP_RAILWAY:
+ SetRailType(t, UpdateRailType(GetRailType(t), min_rail));
+ break;
+
+ case MP_STREET:
+ if (IsLevelCrossing(t)) {
+ SetRailTypeCrossing(t, UpdateRailType(GetRailTypeCrossing(t), min_rail));
+ }
+ break;
+
+ case MP_STATION:
+ if (IsRailwayStation(t)) {
+ SetRailType(t, UpdateRailType(GetRailType(t), min_rail));
+ }
+ break;
+
+ case MP_TUNNELBRIDGE:
+ if (IsTunnel(t)) {
+ if (GetTunnelTransportType(t) == TRANSPORT_RAIL) {
+ SetRailType(t, UpdateRailType(GetRailType(t), min_rail));
+ }
+ } else {
+ if (GetBridgeTransportType(t) == TRANSPORT_RAIL) {
+ SetRailType(t, UpdateRailType(GetRailType(t), min_rail));
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == VEH_Train && (IsFrontEngine(v) || IsFreeWagon(v))) TrainConsistChanged(v);
+ }
+
+ }
+
+ /* In version 16.1 of the savegame a player can decide if trains, which get
+ * replaced, shall keep their old length. In all prior versions, just default
+ * to false */
+ if (CheckSavegameVersionOldStyle(16, 1)) {
+ FOR_ALL_PLAYERS(p) p->renew_keep_length = false;
+ }
+
+ /* In version 17, ground type is moved from m2 to m4 for depots and
+ * waypoints to make way for storing the index in m2. The custom graphics
+ * id which was stored in m4 is now saved as a grf/id reference in the
+ * waypoint struct. */
+ if (CheckSavegameVersion(17)) {
+ Waypoint *wp;
+
+ FOR_ALL_WAYPOINTS(wp) {
+ if (wp->deleted == 0) {
+ const StationSpec *statspec = NULL;
+
+ if (HASBIT(_m[wp->xy].m3, 4))
+ statspec = GetCustomStationSpec(STAT_CLASS_WAYP, _m[wp->xy].m4 + 1);
+
+ if (statspec != NULL) {
+ wp->stat_id = _m[wp->xy].m4 + 1;
+ wp->grfid = statspec->grfid;
+ wp->localidx = statspec->localidx;
+ } else {
+ // No custom graphics set, so set to default.
+ wp->stat_id = 0;
+ wp->grfid = 0;
+ wp->localidx = 0;
+ }
+
+ // Move ground type bits from m2 to m4.
+ _m[wp->xy].m4 = GB(_m[wp->xy].m2, 0, 4);
+ // Store waypoint index in the tile.
+ _m[wp->xy].m2 = wp->index;
+ }
+ }
+ } else {
+ /* As of version 17, we recalculate the custom graphic ID of waypoints
+ * from the GRF ID / station index. */
+ AfterLoadWaypoints();
+ }
+
+ /* From version 15, we moved a semaphore bit from bit 2 to bit 3 in m4, making
+ * room for PBS. Now in version 21 move it back :P. */
+ if (CheckSavegameVersion(21) && !CheckSavegameVersion(15)) {
+ BEGIN_TILE_LOOP(tile, MapSizeX(), MapSizeY(), 0) {
+ if (IsTileType(tile, MP_RAILWAY)) {
+ if (HasSignals(tile)) {
+ // convert PBS signals to combo-signals
+ if (HASBIT(_m[tile].m4, 2)) SetSignalType(tile, SIGTYPE_COMBO);
+
+ // move the signal variant back
+ SetSignalVariant(tile, HASBIT(_m[tile].m4, 3) ? SIG_SEMAPHORE : SIG_ELECTRIC);
+ CLRBIT(_m[tile].m4, 3);
+ }
+
+ // Clear PBS reservation on track
+ if (!IsTileDepotType(tile, TRANSPORT_RAIL)) {
+ SB(_m[tile].m4, 4, 4, 0);
+ } else {
+ CLRBIT(_m[tile].m3, 6);
+ }
+ }
+
+ // Clear PBS reservation on crossing
+ if (IsTileType(tile, MP_STREET) && IsLevelCrossing(tile))
+ CLRBIT(_m[tile].m5, 0);
+
+ // Clear PBS reservation on station
+ if (IsTileType(tile, MP_STATION))
+ CLRBIT(_m[tile].m3, 6);
+ } END_TILE_LOOP(tile, MapSizeX(), MapSizeY(), 0);
+ }
+
+ if (CheckSavegameVersion(22)) UpdatePatches();
+
+ if (CheckSavegameVersion(25)) {
+ Vehicle *v;
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == VEH_Road) {
+ v->vehstatus &= ~0x40;
+ v->u.road.slot = NULL;
+ v->u.road.slot_age = 0;
+ }
+ }
+ }
+
+ if (CheckSavegameVersion(26)) {
+ Station *st;
+ FOR_ALL_STATIONS(st) {
+ st->last_vehicle_type = VEH_Invalid;
+ }
+ }
+
+ YapfNotifyTrackLayoutChange(INVALID_TILE, INVALID_TRACK);
+
+ if (CheckSavegameVersion(34)) FOR_ALL_PLAYERS(p) ResetPlayerLivery(p);
+
+ FOR_ALL_PLAYERS(p) p->avail_railtypes = GetPlayerRailtypes(p->index);
+
+ if (!CheckSavegameVersion(27)) AfterLoadStations();
+
+ {
+ /* Set up the engine count for all players */
+ Player *players[MAX_PLAYERS];
+ int i;
+ const Vehicle *v;
+
+ for (i = 0; i < MAX_PLAYERS; i++) players[i] = GetPlayer(i);
+
+ FOR_ALL_VEHICLES(v) {
+ if (!IsEngineCountable(v)) continue;
+ players[v->owner]->num_engines[v->engine_type]++;
+ }
+ }
+
+ /* Time starts at 0 instead of 1920.
+ * Account for this in older games by adding an offset */
+ if (CheckSavegameVersion(31)) {
+ Station *st;
+ Waypoint *wp;
+ Engine *e;
+ Player *player;
+ Industry *i;
+ Vehicle *v;
+
+ _date += DAYS_TILL_ORIGINAL_BASE_YEAR;
+ _cur_year += ORIGINAL_BASE_YEAR;
+
+ FOR_ALL_STATIONS(st) st->build_date += DAYS_TILL_ORIGINAL_BASE_YEAR;
+ FOR_ALL_WAYPOINTS(wp) wp->build_date += DAYS_TILL_ORIGINAL_BASE_YEAR;
+ FOR_ALL_ENGINES(e) e->intro_date += DAYS_TILL_ORIGINAL_BASE_YEAR;
+ FOR_ALL_PLAYERS(player) player->inaugurated_year += ORIGINAL_BASE_YEAR;
+ FOR_ALL_INDUSTRIES(i) i->last_prod_year += ORIGINAL_BASE_YEAR;
+
+ FOR_ALL_VEHICLES(v) {
+ v->date_of_last_service += DAYS_TILL_ORIGINAL_BASE_YEAR;
+ v->build_year += ORIGINAL_BASE_YEAR;
+ }
+ }
+
+ /* From 32 on we save the industry who made the farmland.
+ * To give this prettyness to old savegames, we remove all farmfields and
+ * plant new ones. */
+ if (CheckSavegameVersion(32)) {
+ Industry *i;
+
+ BEGIN_TILE_LOOP(tile_cur, MapSizeX(), MapSizeY(), 0) {
+ if (IsTileType(tile_cur, MP_CLEAR) && IsClearGround(tile_cur, CLEAR_FIELDS)) {
+ MakeClear(tile_cur, CLEAR_GRASS, 3);
+ }
+ } END_TILE_LOOP(tile_cur, MapSizeX(), MapSizeY(), 0)
+
+ FOR_ALL_INDUSTRIES(i) {
+ uint j;
+
+ if (i->type == IT_FARM || i->type == IT_FARM_2) {
+ for (j = 0; j != 50; j++) PlantRandomFarmField(i);
+ }
+ }
+ }
+
+ /* Setting no refit flags to all orders in savegames from before refit in orders were added */
+ if (CheckSavegameVersion(36)) {
+ Order *order;
+ Vehicle *v;
+
+ FOR_ALL_ORDERS(order) {
+ order->refit_cargo = CT_NO_REFIT;
+ order->refit_subtype = CT_NO_REFIT;
+ }
+
+ FOR_ALL_VEHICLES(v) {
+ v->current_order.refit_cargo = CT_NO_REFIT;
+ v->current_order.refit_subtype = CT_NO_REFIT;
+ }
+ }
+
+ if (CheckSavegameVersion(37)) {
+ ConvertNameArray();
+ }
+
+ /* from version 38 we have optional elrails, since we cannot know the
+ * preference of a user, let elrails enabled; it can be disabled manually */
+ if (CheckSavegameVersion(38)) {
+ _patches.disable_elrails = false; // enable elrails
+ /* do the same as when elrails were enabled/disabled manually just now */
+ SettingsDisableElrail(_patches.disable_elrails);
+ }
+
+ if (CheckSavegameVersion(43)) {
+ BEGIN_TILE_LOOP(tile_cur, MapSizeX(), MapSizeY(), 0) {
+ if (IsTileType(tile_cur, MP_INDUSTRY)) {
+ switch (GetIndustryGfx(tile_cur)) {
+ case GFX_POWERPLANT_SPARKS:
+ SetIndustryAnimationState(tile_cur, GB(_m[tile_cur].m1, 2, 5));
+ break;
+
+ case GFX_OILWELL_ANIMATED_1:
+ case GFX_OILWELL_ANIMATED_2:
+ case GFX_OILWELL_ANIMATED_3:
+ SetIndustryAnimationState(tile_cur, GB(_m[tile_cur].m1, 0, 2));
+ break;
+
+ case GFX_COAL_MINE_TOWER_ANIMATED:
+ case GFX_COPPER_MINE_TOWER_ANIMATED:
+ case GFX_GOLD_MINE_TOWER_ANIMATED:
+ SetIndustryAnimationState(tile_cur, _m[tile_cur].m1);
+ break;
+
+ default: /* No animation states to change */
+ break;
+ }
+ }
+ } END_TILE_LOOP(tile_cur, MapSizeX(), MapSizeY(), 0)
+ }
+
+ return true;
+}
+
+/** Reload all NewGRF files during a running game. This is a cut-down
+ * version of AfterLoadGame().
+ * XXX - We need to reset the vehicle position hash because with a non-empty
+ * hash AfterLoadVehicles() will loop infinitely. We need AfterLoadVehicles()
+ * to recalculate vehicle data as some NewGRF vehicle sets could have been
+ * removed or added and changed statistics */
+void ReloadNewGRFData(void)
+{
+ /* reload grf data */
+ GfxLoadSprites();
+ LoadStringWidthTable();
+ /* reload vehicles */
+ ResetVehiclePosHash();
+ AfterLoadVehicles();
+ /* update station and waypoint graphics */
+ AfterLoadWaypoints();
+ AfterLoadStations();
+ /* redraw the whole screen */
+ MarkWholeScreenDirty();
+}
diff --git a/src/openttd.h b/src/openttd.h
new file mode 100644
index 000000000..912ae4d8d
--- /dev/null
+++ b/src/openttd.h
@@ -0,0 +1,567 @@
+/* $Id$ */
+/** @file openttd.h */
+
+#ifndef OPENTTD_H
+#define OPENTTD_H
+
+#ifndef VARDEF
+#define VARDEF extern
+#endif
+
+typedef struct Rect {
+ int left,top,right,bottom;
+} Rect;
+
+typedef struct Oblong {
+ int x, y;
+ int width, height;
+} Oblong;
+
+typedef struct BoundingRect {
+ int width;
+ int height;
+} BoundingRect;
+
+typedef struct Point {
+ int x,y;
+} Point;
+
+typedef struct Pair {
+ int a;
+ int b;
+} Pair;
+
+#include "map.h"
+#include "slope.h"
+
+// Forward declarations of structs.
+typedef struct Vehicle Vehicle;
+typedef struct Depot Depot;
+typedef struct Waypoint Waypoint;
+typedef struct Window Window;
+typedef struct Station Station;
+typedef struct ViewPort ViewPort;
+typedef struct Town Town;
+typedef struct NewsItem NewsItem;
+typedef struct Industry Industry;
+typedef struct DrawPixelInfo DrawPixelInfo;
+typedef byte PlayerID;
+typedef byte VehicleOrderID; ///< The index of an order within its current vehicle (not pool related)
+typedef byte CargoID;
+typedef byte LandscapeID;
+typedef uint32 SpriteID; ///< The number of a sprite, without mapping bits and colortables
+typedef uint32 PalSpriteID; ///< The number of a sprite plus all the mapping bits and colortables
+typedef uint32 CursorID;
+typedef uint16 EngineID;
+typedef uint16 UnitID;
+typedef uint16 StringID;
+typedef EngineID *EngineList; ///< engine list type placeholder acceptable for C code (see helpers.cpp)
+
+/* IDs used in Pools */
+typedef uint16 VehicleID;
+typedef uint16 StationID;
+typedef uint16 RoadStopID;
+typedef uint16 TownID;
+typedef uint16 IndustryID;
+typedef uint16 DepotID;
+typedef uint16 WaypointID;
+typedef uint16 OrderID;
+typedef uint16 SignID;
+typedef uint16 EngineRenewID;
+typedef uint16 DestinationID;
+
+/* DestinationID must be at least as large as every these below, because it can
+ * be any of them
+ */
+assert_compile(sizeof(DestinationID) == sizeof(DepotID));
+assert_compile(sizeof(DestinationID) == sizeof(WaypointID));
+assert_compile(sizeof(DestinationID) == sizeof(StationID));
+
+typedef uint32 WindowNumber;
+typedef byte WindowClass;
+
+enum {
+ INVALID_YEAR = -1,
+ INVALID_DATE = -1,
+};
+
+typedef int32 Year;
+typedef int32 Date;
+
+
+enum GameModes {
+ GM_MENU,
+ GM_NORMAL,
+ GM_EDITOR
+};
+
+enum SwitchModes {
+ SM_NONE = 0,
+ SM_NEWGAME = 1,
+ SM_EDITOR = 2,
+ SM_LOAD = 3,
+ SM_MENU = 4,
+ SM_SAVE = 5,
+ SM_GENRANDLAND = 6,
+ SM_LOAD_SCENARIO = 9,
+ SM_START_SCENARIO = 10,
+ SM_START_HEIGHTMAP = 11,
+ SM_LOAD_HEIGHTMAP = 12,
+};
+
+
+/* Modes for GenerateWorld */
+enum GenerateWorldModes {
+ GW_NEWGAME = 0, /* Generate a map for a new game */
+ GW_EMPTY = 1, /* Generate an empty map (sea-level) */
+ GW_RANDOM = 2, /* Generate a random map for SE */
+ GW_HEIGHTMAP = 3, /* Generate a newgame from a heightmap */
+};
+
+/* Modes for InitializeGame, those are _bits_! */
+enum InitializeGameModes {
+ IG_NONE = 0, /* Don't do anything special */
+ IG_DATE_RESET = 1, /* Reset the date when initializing a game */
+};
+
+
+typedef enum TransportTypes {
+ /* These constants are for now linked to the representation of bridges
+ * and tunnels, so they can be used by GetTileTrackStatus_TunnelBridge.
+ * In an ideal world, these constants would be used everywhere when
+ * accessing tunnels and bridges. For now, you should just not change
+ * the values for road and rail.
+ */
+ TRANSPORT_RAIL = 0,
+ TRANSPORT_ROAD = 1,
+ TRANSPORT_WATER, // = 2
+ TRANSPORT_END,
+ INVALID_TRANSPORT = 0xff,
+} TransportType;
+
+typedef struct TileInfo {
+ uint x;
+ uint y;
+ Slope tileh;
+ TileIndex tile;
+ uint z;
+} TileInfo;
+
+
+/* Display Options */
+enum {
+ DO_SHOW_TOWN_NAMES = 1 << 0,
+ DO_SHOW_STATION_NAMES = 1 << 1,
+ DO_SHOW_SIGNS = 1 << 2,
+ DO_FULL_ANIMATION = 1 << 3,
+ DO_TRANS_BUILDINGS = 1 << 4,
+ DO_FULL_DETAIL = 1 << 5,
+ DO_WAYPOINTS = 1 << 6,
+ DO_TRANS_SIGNS = 1 << 7,
+};
+
+/* Landscape types */
+enum {
+ LT_NORMAL = 0,
+ LT_HILLY = 1,
+ LT_DESERT = 2,
+ LT_CANDY = 3,
+
+ NUM_LANDSCAPE = 4,
+};
+
+enum {
+ NUM_PRICES = 49,
+};
+
+typedef struct Prices {
+ int32 station_value;
+ int32 build_rail;
+ int32 build_road;
+ int32 build_signals;
+ int32 build_bridge;
+ int32 build_train_depot;
+ int32 build_road_depot;
+ int32 build_ship_depot;
+ int32 build_tunnel;
+ int32 train_station_track;
+ int32 train_station_length;
+ int32 build_airport;
+ int32 build_bus_station;
+ int32 build_truck_station;
+ int32 build_dock;
+ int32 build_railvehicle;
+ int32 build_railwagon;
+ int32 aircraft_base;
+ int32 roadveh_base;
+ int32 ship_base;
+ int32 build_trees;
+ int32 terraform;
+ int32 clear_1;
+ int32 purchase_land;
+ int32 clear_2;
+ int32 clear_3;
+ int32 remove_trees;
+ int32 remove_rail;
+ int32 remove_signals;
+ int32 clear_bridge;
+ int32 remove_train_depot;
+ int32 remove_road_depot;
+ int32 remove_ship_depot;
+ int32 clear_tunnel;
+ int32 clear_water;
+ int32 remove_rail_station;
+ int32 remove_airport;
+ int32 remove_bus_station;
+ int32 remove_truck_station;
+ int32 remove_dock;
+ int32 remove_house;
+ int32 remove_road;
+ int32 running_rail[3];
+ int32 aircraft_running;
+ int32 roadveh_running;
+ int32 ship_running;
+ int32 build_industry;
+} Prices;
+
+#define GAME_DIFFICULTY_NUM 18
+
+typedef struct GameDifficulty {
+ int max_no_competitors;
+ int competitor_start_time;
+ int number_towns;
+ int number_industries;
+ int max_loan;
+ int initial_interest;
+ int vehicle_costs;
+ int competitor_speed;
+ int competitor_intelligence; // no longer in use
+ int vehicle_breakdowns;
+ int subsidy_multiplier;
+ int construction_cost;
+ int terrain_type;
+ int quantity_sea_lakes;
+ int economy;
+ int line_reverse_mode;
+ int disasters;
+ int town_council_tolerance; // minimum required town ratings to be allowed to demolish stuff
+} GameDifficulty;
+
+enum {
+ // Temperate
+ CT_PASSENGERS = 0,
+ CT_COAL = 1,
+ CT_MAIL = 2,
+ CT_OIL = 3,
+ CT_LIVESTOCK = 4,
+ CT_GOODS = 5,
+ CT_GRAIN = 6,
+ CT_WOOD = 7,
+ CT_IRON_ORE = 8,
+ CT_STEEL = 9,
+ CT_VALUABLES = 10,
+ CT_FOOD = 11,
+
+ // Arctic
+ CT_WHEAT = 6,
+ CT_HILLY_UNUSED = 8,
+ CT_PAPER = 9,
+ CT_GOLD = 10,
+
+ // Tropic
+ CT_RUBBER = 1,
+ CT_FRUIT = 4,
+ CT_MAIZE = 6,
+ CT_COPPER_ORE = 8,
+ CT_WATER = 9,
+ CT_DIAMONDS = 10,
+
+ // Toyland
+ CT_SUGAR = 1,
+ CT_TOYS = 3,
+ CT_BATTERIES = 4,
+ CT_CANDY = 5,
+ CT_TOFFEE = 6,
+ CT_COLA = 7,
+ CT_COTTON_CANDY = 8,
+ CT_BUBBLES = 9,
+ CT_PLASTIC = 10,
+ CT_FIZZY_DRINKS = 11,
+
+ NUM_CARGO = 12,
+
+ CT_NO_REFIT = 0xFE,
+ CT_INVALID = 0xFF
+};
+
+typedef uint AcceptedCargo[NUM_CARGO];
+
+typedef struct TileDesc {
+ StringID str;
+ Owner owner;
+ Date build_date;
+ uint32 dparam[2];
+} TileDesc;
+
+typedef struct {
+ int32 left;
+ int32 top;
+ byte width_1, width_2;
+} ViewportSign;
+
+
+typedef void DrawTileProc(TileInfo *ti);
+typedef uint GetSlopeZProc(TileIndex tile, uint x, uint y);
+typedef int32 ClearTileProc(TileIndex tile, byte flags);
+typedef void GetAcceptedCargoProc(TileIndex tile, AcceptedCargo res);
+typedef void GetTileDescProc(TileIndex tile, TileDesc *td);
+/* GetTileTrackStatusProcs return a value that contains the possible tracks
+ * that can be taken on a given tile by a given transport. The return value is
+ * composed as follows: 0xaabbccdd. ccdd and aabb are bitmasks of trackdirs,
+ * where bit n corresponds to trackdir n. ccdd are the trackdirs that are
+ * present in the tile (1==present, 0==not present), aabb is the signal
+ * status, if applicable (0==green/no signal, 1==red, note that this is
+ * reversed from map3/2[tile] for railway signals).
+ *
+ * The result (let's call it ts) is often used as follows:
+ * tracks = (byte)(ts | ts >>8)
+ * This effectively converts the present part of the result (ccdd) to a
+ * track bitmask, which disregards directions. Normally, this is the same as just
+ * doing (byte)ts I think, although I am not really sure
+ *
+ * A trackdir is combination of a track and a dir, where the lower three bits
+ * are a track, the fourth bit is the direction. these give 12 (or 14)
+ * possible options: 0-5 and 8-13, so we need 14 bits for a trackdir bitmask
+ * above.
+ */
+typedef uint32 GetTileTrackStatusProc(TileIndex tile, TransportType mode);
+typedef void GetProducedCargoProc(TileIndex tile, CargoID *b);
+typedef void ClickTileProc(TileIndex tile);
+typedef void AnimateTileProc(TileIndex tile);
+typedef void TileLoopProc(TileIndex tile);
+typedef void ChangeTileOwnerProc(TileIndex tile, PlayerID old_player, PlayerID new_player);
+/* Return value has bit 0x2 set, when the vehicle enters a station. Then,
+ * result << 8 contains the id of the station entered. If the return value has
+ * bit 0x8 set, the vehicle could not and did not enter the tile. Are there
+ * other bits that can be set? */
+typedef uint32 VehicleEnterTileProc(Vehicle *v, TileIndex tile, int x, int y);
+typedef Slope GetSlopeTilehProc(TileIndex, Slope tileh);
+
+typedef struct {
+ DrawTileProc *draw_tile_proc;
+ GetSlopeZProc *get_slope_z_proc;
+ ClearTileProc *clear_tile_proc;
+ GetAcceptedCargoProc *get_accepted_cargo_proc;
+ GetTileDescProc *get_tile_desc_proc;
+ GetTileTrackStatusProc *get_tile_track_status_proc;
+ ClickTileProc *click_tile_proc;
+ AnimateTileProc *animate_tile_proc;
+ TileLoopProc *tile_loop_proc;
+ ChangeTileOwnerProc *change_tile_owner_proc;
+ GetProducedCargoProc *get_produced_cargo_proc;
+ VehicleEnterTileProc *vehicle_enter_tile_proc;
+ GetSlopeTilehProc *get_slope_tileh_proc;
+} TileTypeProcs;
+
+
+enum {
+ WC_MAIN_WINDOW,
+ WC_MAIN_TOOLBAR,
+ WC_STATUS_BAR,
+ WC_BUILD_TOOLBAR,
+ WC_NEWS_WINDOW,
+ WC_TOWN_DIRECTORY,
+ WC_STATION_LIST,
+ WC_TOWN_VIEW,
+ WC_SMALLMAP,
+ WC_TRAINS_LIST,
+ WC_ROADVEH_LIST,
+ WC_SHIPS_LIST,
+ WC_AIRCRAFT_LIST,
+ WC_VEHICLE_VIEW,
+ WC_VEHICLE_DETAILS,
+ WC_VEHICLE_REFIT,
+ WC_VEHICLE_ORDERS,
+ WC_STATION_VIEW,
+ WC_VEHICLE_DEPOT,
+ WC_BUILD_VEHICLE,
+ WC_BUILD_BRIDGE,
+ WC_ERRMSG,
+ WC_BUILD_STATION,
+ WC_BUS_STATION,
+ WC_TRUCK_STATION,
+ WC_BUILD_DEPOT,
+ WC_COMPANY,
+ WC_FINANCES,
+ WC_PLAYER_COLOR,
+ WC_QUERY_STRING,
+ WC_SAVELOAD,
+ WC_SELECT_GAME,
+ WC_TOOLBAR_MENU,
+ WC_INCOME_GRAPH,
+ WC_OPERATING_PROFIT,
+ WC_TOOLTIPS,
+ WC_INDUSTRY_VIEW,
+ WC_PLAYER_FACE,
+ WC_LAND_INFO,
+ WC_TOWN_AUTHORITY,
+ WC_SUBSIDIES_LIST,
+ WC_GRAPH_LEGEND,
+ WC_DELIVERED_CARGO,
+ WC_PERFORMANCE_HISTORY,
+ WC_COMPANY_VALUE,
+ WC_COMPANY_LEAGUE,
+ WC_BUY_COMPANY,
+ WC_PAYMENT_RATES,
+ WC_ENGINE_PREVIEW,
+ WC_MUSIC_WINDOW,
+ WC_MUSIC_TRACK_SELECTION,
+ WC_SCEN_LAND_GEN,
+ WC_SCEN_TOWN_GEN,
+ WC_SCEN_INDUSTRY,
+ WC_SCEN_BUILD_ROAD,
+ WC_BUILD_TREES,
+ WC_SEND_NETWORK_MSG,
+ WC_DROPDOWN_MENU,
+ WC_BUILD_INDUSTRY,
+ WC_GAME_OPTIONS,
+ WC_NETWORK_WINDOW,
+ WC_INDUSTRY_DIRECTORY,
+ WC_MESSAGE_HISTORY,
+ WC_CHEATS,
+ WC_PERFORMANCE_DETAIL,
+ WC_CONSOLE,
+ WC_EXTRA_VIEW_PORT,
+ WC_CLIENT_LIST,
+ WC_NETWORK_STATUS_WINDOW,
+ WC_CUSTOM_CURRENCY,
+ WC_REPLACE_VEHICLE,
+ WC_HIGHSCORE,
+ WC_ENDSCREEN,
+ WC_SIGN_LIST,
+ WC_GENERATE_LANDSCAPE,
+ WC_GENERATE_PROGRESS_WINDOW,
+ WC_CONFIRM_POPUP_QUERY,
+};
+
+
+enum {
+ EXPENSES_CONSTRUCTION = 0,
+ EXPENSES_NEW_VEHICLES = 1,
+ EXPENSES_TRAIN_RUN = 2,
+ EXPENSES_ROADVEH_RUN = 3,
+ EXPENSES_AIRCRAFT_RUN = 4,
+ EXPENSES_SHIP_RUN = 5,
+ EXPENSES_PROPERTY = 6,
+ EXPENSES_TRAIN_INC = 7,
+ EXPENSES_ROADVEH_INC = 8,
+ EXPENSES_AIRCRAFT_INC = 9,
+ EXPENSES_SHIP_INC = 10,
+ EXPENSES_LOAN_INT = 11,
+ EXPENSES_OTHER = 12,
+};
+
+enum {
+ MAX_LANG = 64,
+};
+
+// special string constants
+enum SpecialStrings {
+
+ // special strings for town names. the town name is generated dynamically on request.
+ SPECSTR_TOWNNAME_START = 0x20C0,
+ SPECSTR_TOWNNAME_ENGLISH = SPECSTR_TOWNNAME_START,
+ SPECSTR_TOWNNAME_FRENCH,
+ SPECSTR_TOWNNAME_GERMAN,
+ SPECSTR_TOWNNAME_AMERICAN,
+ SPECSTR_TOWNNAME_LATIN,
+ SPECSTR_TOWNNAME_SILLY,
+ SPECSTR_TOWNNAME_SWEDISH,
+ SPECSTR_TOWNNAME_DUTCH,
+ SPECSTR_TOWNNAME_FINNISH,
+ SPECSTR_TOWNNAME_POLISH,
+ SPECSTR_TOWNNAME_SLOVAKISH,
+ SPECSTR_TOWNNAME_NORWEGIAN,
+ SPECSTR_TOWNNAME_HUNGARIAN,
+ SPECSTR_TOWNNAME_AUSTRIAN,
+ SPECSTR_TOWNNAME_ROMANIAN,
+ SPECSTR_TOWNNAME_CZECH,
+ SPECSTR_TOWNNAME_SWISS,
+ SPECSTR_TOWNNAME_DANISH,
+ SPECSTR_TOWNNAME_TURKISH,
+ SPECSTR_TOWNNAME_ITALIAN,
+ SPECSTR_TOWNNAME_CATALAN,
+ SPECSTR_TOWNNAME_LAST = SPECSTR_TOWNNAME_CATALAN,
+
+ // special strings for player names on the form "TownName transport".
+ SPECSTR_PLAYERNAME_START = 0x70EA,
+ SPECSTR_PLAYERNAME_ENGLISH = SPECSTR_PLAYERNAME_START,
+ SPECSTR_PLAYERNAME_FRENCH,
+ SPECSTR_PLAYERNAME_GERMAN,
+ SPECSTR_PLAYERNAME_AMERICAN,
+ SPECSTR_PLAYERNAME_LATIN,
+ SPECSTR_PLAYERNAME_SILLY,
+ SPECSTR_PLAYERNAME_LAST = SPECSTR_PLAYERNAME_SILLY,
+
+ SPECSTR_ANDCO_NAME = 0x70E6,
+ SPECSTR_PRESIDENT_NAME = 0x70E7,
+ SPECSTR_SONGNAME = 0x70E8,
+
+ // reserve MAX_LANG strings for the *.lng files
+ SPECSTR_LANGUAGE_START = 0x7100,
+ SPECSTR_LANGUAGE_END = SPECSTR_LANGUAGE_START + MAX_LANG - 1,
+
+ // reserve 32 strings for various screen resolutions
+ SPECSTR_RESOLUTION_START = SPECSTR_LANGUAGE_END + 1,
+ SPECSTR_RESOLUTION_END = SPECSTR_RESOLUTION_START + 0x1F,
+
+ // reserve 32 strings for screenshot formats
+ SPECSTR_SCREENSHOT_START = SPECSTR_RESOLUTION_END + 1,
+ SPECSTR_SCREENSHOT_END = SPECSTR_SCREENSHOT_START + 0x1F,
+
+ // Used to implement SetDParamStr
+ STR_SPEC_DYNSTRING = 0xF800,
+ STR_SPEC_USERSTRING = 0xF808,
+};
+
+typedef void PlaceProc(TileIndex tile);
+
+enum {
+ SORT_ASCENDING = 0,
+ SORT_DESCENDING = 1,
+ SORT_BY_DATE = 0,
+ SORT_BY_NAME = 2
+};
+
+VARDEF byte _savegame_sort_order;
+
+#define INVALID_STRING_ID 0xFFFF
+
+enum {
+ MAX_SCREEN_WIDTH = 2048,
+ MAX_SCREEN_HEIGHT = 1200,
+};
+
+/* In certain windows you navigate with the arrow keys. Do not scroll the
+ * gameview when here. Bitencoded variable that only allows scrolling if all
+ * elements are zero */
+enum {
+ SCROLL_CON = 0,
+ SCROLL_EDIT = 1,
+ SCROLL_SAVE = 2,
+ SCROLL_CHAT = 4,
+};
+VARDEF byte _no_scroll;
+
+/** To have a concurrently running thread interface with the main program, use
+ * the OTTD_SendThreadMessage() function. Actions to perform upon the message are handled
+ * in the ProcessSentMessage() function */
+typedef enum ThreadMsgs {
+ MSG_OTTD_NO_MESSAGE,
+ MSG_OTTD_SAVETHREAD_DONE,
+ MSG_OTTD_SAVETHREAD_ERROR,
+} ThreadMsg;
+
+void OTTD_SendThreadMessage(ThreadMsg msg);
+
+#endif /* OPENTTD_H */
diff --git a/src/order.h b/src/order.h
new file mode 100644
index 000000000..7031f2455
--- /dev/null
+++ b/src/order.h
@@ -0,0 +1,202 @@
+/* $Id$ */
+
+/** @file order.h */
+
+#ifndef ORDER_H
+#define ORDER_H
+
+#include "macros.h"
+#include "oldpool.h"
+
+enum {
+ INVALID_VEH_ORDER_ID = 0xFF,
+ INVALID_ORDER = 0xFFFF,
+};
+
+/* Order types */
+enum OrderTypes {
+ OT_NOTHING = 0,
+ OT_GOTO_STATION = 1,
+ OT_GOTO_DEPOT = 2,
+ OT_LOADING = 3,
+ OT_LEAVESTATION = 4,
+ OT_DUMMY = 5,
+ OT_GOTO_WAYPOINT = 6,
+};
+/* It needs to be 8bits, because we save and load it as such */
+typedef uint8 OrderType;
+
+/* Order flags -- please use OFB instead OF and use HASBIT/SETBIT/CLEARBIT */
+
+/** Order flag masks - these are for direct bit operations */
+enum OrderFlagMasks {
+ //Flags for stations:
+ /** vehicle will transfer cargo (i. e. not deliver to nearby industry/town even if accepted there) */
+ OF_TRANSFER = 0x1,
+ /** If OF_TRANSFER is not set, drop any cargo loaded. If accepted, deliver, otherwise cargo remains at the station.
+ * No new cargo is loaded onto the vehicle whatsoever */
+ OF_UNLOAD = 0x2,
+ /** Wait for full load of all vehicles, or of at least one cargo type, depending on patch setting
+ * @todo make this two different flags */
+ OF_FULL_LOAD = 0x4,
+
+ //Flags for depots:
+ /** The current depot-order was initiated because it was in the vehicle's order list */
+ OF_PART_OF_ORDERS = 0x2,
+ /** if OF_PART_OF_ORDERS is not set, this will cause the vehicle to be stopped in the depot */
+ OF_HALT_IN_DEPOT = 0x4,
+ /** if OF_PART_OF_ORDERS is set, this will cause the order only be come active if the vehicle needs servicing */
+ OF_SERVICE_IF_NEEDED = 0x4, //used when OF_PART_OF_ORDERS is set.
+
+ //Common flags
+ /** This causes the vehicle not to stop at intermediate OR the destination station (depending on patch settings)
+ * @todo make this two different flags */
+ OF_NON_STOP = 0x8
+};
+
+/** Order flags bits - these are for the *BIT macros
+ * for descrption of flags, see OrderFlagMasks
+ * @see OrderFlagMasks
+ */
+enum {
+ OFB_TRANSFER = 0,
+ OFB_UNLOAD = 1,
+ OFB_FULL_LOAD = 2,
+ OFB_PART_OF_ORDERS = 1,
+ OFB_HALT_IN_DEPOT = 2,
+ OFB_SERVICE_IF_NEEDED = 2,
+ OFB_NON_STOP = 3
+};
+
+
+/* Possible clone options */
+enum {
+ CO_SHARE = 0,
+ CO_COPY = 1,
+ CO_UNSHARE = 2
+};
+
+/* If you change this, keep in mind that it is saved on 3 places:
+ * - Load_ORDR, all the global orders
+ * - Vehicle -> current_order
+ * - REF_SHEDULE (all REFs are currently limited to 16 bits!!)
+ */
+typedef struct Order {
+ OrderType type;
+ uint8 flags;
+ DestinationID dest; ///< The destionation of the order.
+
+ struct Order *next; ///< Pointer to next order. If NULL, end of list
+
+ OrderID index; ///< Index of the order, is not saved or anything, just for reference
+
+ CargoID refit_cargo; // Refit CargoID
+ byte refit_subtype; // Refit subtype
+} Order;
+
+#define MAX_BACKUP_ORDER_COUNT 40
+
+typedef struct {
+ VehicleID clone;
+ VehicleOrderID orderindex;
+ Order order[MAX_BACKUP_ORDER_COUNT + 1];
+ uint16 service_interval;
+ char name[32];
+} BackuppedOrders;
+
+VARDEF TileIndex _backup_orders_tile;
+VARDEF BackuppedOrders _backup_orders_data[1];
+
+DECLARE_OLD_POOL(Order, Order, 6, 1000)
+
+static inline VehicleOrderID GetMaxOrderIndex(void)
+{
+ /* TODO - This isn't the real content of the function, but
+ * with the new pool-system this will be replaced with one that
+ * _really_ returns the highest index. Now it just returns
+ * the next safe value we are sure about everything is below.
+ */
+ return GetOrderPoolSize() - 1;
+}
+
+static inline VehicleOrderID GetNumOrders(void)
+{
+ return GetOrderPoolSize();
+}
+
+/**
+ * Check if a Order really exists.
+ */
+static inline bool IsValidOrder(const Order *o)
+{
+ return o->type != OT_NOTHING;
+}
+
+static inline void DeleteOrder(Order *o)
+{
+ o->type = OT_NOTHING;
+ o->next = NULL;
+}
+
+#define FOR_ALL_ORDERS_FROM(order, start) for (order = GetOrder(start); order != NULL; order = (order->index + 1U < GetOrderPoolSize()) ? GetOrder(order->index + 1U) : NULL) if (IsValidOrder(order))
+#define FOR_ALL_ORDERS(order) FOR_ALL_ORDERS_FROM(order, 0)
+
+
+#define FOR_VEHICLE_ORDERS(v, order) for (order = v->orders; order != NULL; order = order->next)
+
+static inline bool HasOrderPoolFree(uint amount)
+{
+ const Order *order;
+
+ /* There is always room if not all blocks in the pool are reserved */
+ if (_Order_pool.current_blocks < _Order_pool.max_blocks)
+ return true;
+
+ FOR_ALL_ORDERS(order)
+ if (order->type == OT_NOTHING)
+ if (--amount == 0)
+ return true;
+
+ return false;
+}
+
+static inline bool IsOrderPoolFull(void)
+{
+ return !HasOrderPoolFree(1);
+}
+
+/* Pack and unpack routines */
+
+static inline uint32 PackOrder(const Order *order)
+{
+ return order->dest << 16 | order->flags << 8 | order->type;
+}
+
+static inline Order UnpackOrder(uint32 packed)
+{
+ Order order;
+ order.type = (OrderType)GB(packed, 0, 8);
+ order.flags = GB(packed, 8, 8);
+ order.dest = GB(packed, 16, 16);
+ order.next = NULL;
+ order.index = 0; // avoid compiler warning
+ order.refit_cargo = CT_NO_REFIT;
+ order.refit_subtype = 0;
+ return order;
+}
+
+/* Functions */
+void BackupVehicleOrders(const Vehicle *v, BackuppedOrders *order);
+void RestoreVehicleOrders(const Vehicle* v, const BackuppedOrders* order);
+void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination);
+void InvalidateVehicleOrder(const Vehicle *v);
+bool VehicleHasDepotOrders(const Vehicle *v);
+void CheckOrders(const Vehicle*);
+void DeleteVehicleOrders(Vehicle *v);
+bool IsOrderListShared(const Vehicle *v);
+void AssignOrder(Order *order, Order data);
+bool CheckForValidOrders(const Vehicle* v);
+
+Order UnpackOldOrder(uint16 packed);
+
+#endif /* ORDER_H */
diff --git a/src/order_cmd.c b/src/order_cmd.c
new file mode 100644
index 000000000..b510e84ea
--- /dev/null
+++ b/src/order_cmd.c
@@ -0,0 +1,1278 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "order.h"
+#include "airport.h"
+#include "depot.h"
+#include "functions.h"
+#include "table/strings.h"
+#include "vehicle.h"
+#include "waypoint.h"
+#include "command.h"
+#include "station.h"
+#include "player.h"
+#include "news.h"
+#include "saveload.h"
+#include "vehicle_gui.h"
+
+/**
+ * Called if a new block is added to the order-pool
+ */
+static void OrderPoolNewBlock(uint start_item)
+{
+ Order *order;
+
+ /* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
+ * TODO - This is just a temporary stage, this will be removed. */
+ for (order = GetOrder(start_item); order != NULL; order = (order->index + 1U < GetOrderPoolSize()) ? GetOrder(order->index + 1U) : NULL) order->index = start_item++;
+}
+
+DEFINE_OLD_POOL(Order, Order, OrderPoolNewBlock, NULL)
+
+/**
+ *
+ * Unpacks a order from savegames made with TTD(Patch)
+ *
+ */
+Order UnpackOldOrder(uint16 packed)
+{
+ Order order;
+ order.type = GB(packed, 0, 4);
+ order.flags = GB(packed, 4, 4);
+ order.dest = GB(packed, 8, 8);
+ order.next = NULL;
+
+ order.refit_cargo = CT_NO_REFIT;
+ order.refit_subtype = 0;
+ order.index = 0; // avoid compiler warning
+
+ // Sanity check
+ // TTD stores invalid orders as OT_NOTHING with non-zero flags/station
+ if (order.type == OT_NOTHING && (order.flags != 0 || order.dest != 0)) {
+ order.type = OT_DUMMY;
+ order.flags = 0;
+ }
+
+ return order;
+}
+
+/**
+ *
+ * Unpacks a order from savegames with version 4 and lower
+ *
+ */
+static Order UnpackVersion4Order(uint16 packed)
+{
+ Order order;
+ order.type = GB(packed, 0, 4);
+ order.flags = GB(packed, 4, 4);
+ order.dest = GB(packed, 8, 8);
+ order.next = NULL;
+ order.index = 0; // avoid compiler warning
+ order.refit_cargo = CT_NO_REFIT;
+ order.refit_subtype = 0;
+ return order;
+}
+
+/**
+ *
+ * Updates the widgets of a vehicle which contains the order-data
+ *
+ */
+void InvalidateVehicleOrder(const Vehicle *v)
+{
+ InvalidateWindow(WC_VEHICLE_VIEW, v->index);
+ InvalidateWindow(WC_VEHICLE_ORDERS, v->index);
+}
+
+/**
+ *
+ * Swap two orders
+ *
+ */
+static void SwapOrders(Order *order1, Order *order2)
+{
+ Order temp_order;
+
+ temp_order = *order1;
+ AssignOrder(order1, *order2);
+ order1->next = order2->next;
+ AssignOrder(order2, temp_order);
+ order2->next = temp_order.next;
+}
+
+/**
+ *
+ * Allocate a new order
+ *
+ * @return Order* if a free space is found, else NULL.
+ *
+ */
+static Order *AllocateOrder(void)
+{
+ Order *order;
+
+ /* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
+ * TODO - This is just a temporary stage, this will be removed. */
+ for (order = GetOrder(0); order != NULL; order = (order->index + 1U < GetOrderPoolSize()) ? GetOrder(order->index + 1U) : NULL) {
+ if (!IsValidOrder(order)) {
+ OrderID index = order->index;
+
+ memset(order, 0, sizeof(*order));
+ order->index = index;
+ order->next = NULL;
+ order->refit_cargo = CT_NO_REFIT;
+ order->refit_subtype = 0;
+
+ return order;
+ }
+ }
+
+ /* Check if we can add a block to the pool */
+ if (AddBlockToPool(&_Order_pool)) return AllocateOrder();
+
+ return NULL;
+}
+
+/**
+ *
+ * Assign data to an order (from an other order)
+ * This function makes sure that the index is maintained correctly
+ *
+ */
+void AssignOrder(Order *order, Order data)
+{
+ order->type = data.type;
+ order->flags = data.flags;
+ order->dest = data.dest;
+
+ order->refit_cargo = data.refit_cargo;
+ order->refit_subtype = data.refit_subtype;
+}
+
+
+/**
+ * Delete all news items regarding defective orders about a vehicle
+ * This could kill still valid warnings (for example about void order when just
+ * another order gets added), but assume the player will notice the problems,
+ * when (s)he's changing the orders.
+ */
+static void DeleteOrderWarnings(const Vehicle* v)
+{
+ DeleteVehicleNews(v->index, STR_TRAIN_HAS_TOO_FEW_ORDERS + (v->type - VEH_Train) * 4);
+ DeleteVehicleNews(v->index, STR_TRAIN_HAS_VOID_ORDER + (v->type - VEH_Train) * 4);
+ DeleteVehicleNews(v->index, STR_TRAIN_HAS_DUPLICATE_ENTRY + (v->type - VEH_Train) * 4);
+ DeleteVehicleNews(v->index, STR_TRAIN_HAS_INVALID_ENTRY + (v->type - VEH_Train) * 4);
+}
+
+
+/** Add an order to the orderlist of a vehicle.
+ * @param tile unused
+ * @param p1 various bitstuffed elements
+ * - p1 = (bit 0 - 15) - ID of the vehicle
+ * - p1 = (bit 16 - 31) - the selected order (if any). If the last order is given,
+ * the order will be inserted before that one
+ * only the first 8 bits used currently (bit 16 - 23) (max 255)
+ * @param p2 packed order to insert
+ */
+int32 CmdInsertOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle *v;
+ VehicleID veh = GB(p1, 0, 16);
+ VehicleOrderID sel_ord = GB(p1, 16, 16);
+ Order new_order = UnpackOrder(p2);
+
+ if (!IsValidVehicleID(veh)) return CMD_ERROR;
+
+ v = GetVehicle(veh);
+
+ if (!CheckOwnership(v->owner)) return CMD_ERROR;
+
+ /* Check if the inserted order is to the correct destination (owner, type),
+ * and has the correct flags if any */
+ switch (new_order.type) {
+ case OT_GOTO_STATION: {
+ const Station *st;
+
+ if (!IsValidStationID(new_order.dest)) return CMD_ERROR;
+ st = GetStation(new_order.dest);
+
+ if (st->airport_type != AT_OILRIG && !IsBuoy(st) && !CheckOwnership(st->owner)) {
+ return CMD_ERROR;
+ }
+
+ switch (v->type) {
+ case VEH_Train:
+ if (!(st->facilities & FACIL_TRAIN)) return CMD_ERROR;
+ break;
+
+ case VEH_Road:
+ if (v->cargo_type == CT_PASSENGERS) {
+ if (!(st->facilities & FACIL_BUS_STOP)) return CMD_ERROR;
+ } else {
+ if (!(st->facilities & FACIL_TRUCK_STOP)) return CMD_ERROR;
+ }
+ break;
+
+ case VEH_Ship:
+ if (!(st->facilities & FACIL_DOCK)) return CMD_ERROR;
+ break;
+
+ case VEH_Aircraft:
+ if (!(st->facilities & FACIL_AIRPORT)) return CMD_ERROR;
+ break;
+
+ default: return CMD_ERROR;
+ }
+
+ /* Order flags can be any of the following for stations:
+ * [full-load | unload] [+ transfer] [+ non-stop]
+ * non-stop orders (if any) are only valid for trains */
+ switch (new_order.flags) {
+ case 0:
+ case OF_FULL_LOAD:
+ case OF_FULL_LOAD | OF_TRANSFER:
+ case OF_UNLOAD:
+ case OF_UNLOAD | OF_TRANSFER:
+ case OF_TRANSFER:
+ break;
+
+ case OF_NON_STOP:
+ case OF_NON_STOP | OF_FULL_LOAD:
+ case OF_NON_STOP | OF_FULL_LOAD | OF_TRANSFER:
+ case OF_NON_STOP | OF_UNLOAD:
+ case OF_NON_STOP | OF_UNLOAD | OF_TRANSFER:
+ case OF_NON_STOP | OF_TRANSFER:
+ if (v->type != VEH_Train) return CMD_ERROR;
+ break;
+
+ default: return CMD_ERROR;
+ }
+ break;
+ }
+
+ case OT_GOTO_DEPOT: {
+ if (v->type == VEH_Aircraft) {
+ const Station* st;
+
+ if (!IsValidStationID(new_order.dest)) return CMD_ERROR;
+ st = GetStation(new_order.dest);
+
+ if ((st->airport_type != AT_OILRIG && !CheckOwnership(st->owner)) ||
+ !(st->facilities & FACIL_AIRPORT) ||
+ GetAirport(st->airport_type)->nof_depots == 0) {
+ return CMD_ERROR;
+ }
+ } else {
+ const Depot* dp;
+
+ if (!IsValidDepotID(new_order.dest)) return CMD_ERROR;
+ dp = GetDepot(new_order.dest);
+
+ if (!CheckOwnership(GetTileOwner(dp->xy))) return CMD_ERROR;
+
+ switch (v->type) {
+ case VEH_Train:
+ if (!IsTileDepotType(dp->xy, TRANSPORT_RAIL)) return CMD_ERROR;
+ break;
+
+ case VEH_Road:
+ if (!IsTileDepotType(dp->xy, TRANSPORT_ROAD)) return CMD_ERROR;
+ break;
+
+ case VEH_Ship:
+ if (!IsTileDepotType(dp->xy, TRANSPORT_WATER)) return CMD_ERROR;
+ break;
+
+ default: return CMD_ERROR;
+ }
+ }
+
+ /* Order flags can be any of the following for depots:
+ * order [+ halt] [+ non-stop]
+ * non-stop orders (if any) are only valid for trains */
+ switch (new_order.flags) {
+ case OF_PART_OF_ORDERS:
+ case OF_PART_OF_ORDERS | OF_HALT_IN_DEPOT:
+ break;
+
+ case OF_NON_STOP | OF_PART_OF_ORDERS:
+ case OF_NON_STOP | OF_PART_OF_ORDERS | OF_HALT_IN_DEPOT:
+ if (v->type != VEH_Train) return CMD_ERROR;
+ break;
+
+ default: return CMD_ERROR;
+ }
+ break;
+ }
+
+ case OT_GOTO_WAYPOINT: {
+ const Waypoint* wp;
+
+ if (v->type != VEH_Train) return CMD_ERROR;
+
+ if (!IsValidWaypointID(new_order.dest)) return CMD_ERROR;
+ wp = GetWaypoint(new_order.dest);
+
+ if (!CheckOwnership(GetTileOwner(wp->xy))) return CMD_ERROR;
+
+ /* Order flags can be any of the following for waypoints:
+ * [non-stop]
+ * non-stop orders (if any) are only valid for trains */
+ switch (new_order.flags) {
+ case 0: break;
+
+ case OF_NON_STOP:
+ if (v->type != VEH_Train) return CMD_ERROR;
+ break;
+
+ default: return CMD_ERROR;
+ }
+ break;
+ }
+
+ default: return CMD_ERROR;
+ }
+
+ if (sel_ord > v->num_orders) return CMD_ERROR;
+
+ if (IsOrderPoolFull()) return_cmd_error(STR_8831_NO_MORE_SPACE_FOR_ORDERS);
+
+ /* XXX - This limit is only here because the backuppedorders can't
+ * handle any more then this.. */
+ if (v->num_orders >= MAX_BACKUP_ORDER_COUNT) return_cmd_error(STR_8832_TOO_MANY_ORDERS);
+
+ /* For ships, make sure that the station is not too far away from the
+ * previous destination, for human players with new pathfinding disabled */
+ if (v->type == VEH_Ship && IsHumanPlayer(v->owner) &&
+ sel_ord != 0 && GetVehicleOrder(v, sel_ord - 1)->type == OT_GOTO_STATION
+ && !_patches.new_pathfinding_all) {
+
+ int dist = DistanceManhattan(
+ GetStation(GetVehicleOrder(v, sel_ord - 1)->dest)->xy,
+ GetStation(new_order.dest)->xy // XXX type != OT_GOTO_STATION?
+ );
+ if (dist >= 130)
+ return_cmd_error(STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO);
+ }
+
+ if (flags & DC_EXEC) {
+ Vehicle *u;
+ Order *new = AllocateOrder();
+ AssignOrder(new, new_order);
+
+ /* Create new order and link in list */
+ if (v->orders == NULL) {
+ v->orders = new;
+ } else {
+ /* Try to get the previous item (we are inserting above the
+ selected) */
+ Order *order = GetVehicleOrder(v, sel_ord - 1);
+
+ if (order == NULL && GetVehicleOrder(v, sel_ord) != NULL) {
+ /* There is no previous item, so we are altering v->orders itself
+ But because the orders can be shared, we copy the info over
+ the v->orders, so we don't have to change the pointers of
+ all vehicles */
+ SwapOrders(v->orders, new);
+ /* Now update the next pointers */
+ v->orders->next = new;
+ } else if (order == NULL) {
+ /* 'sel' is a non-existing order, add him to the end */
+ order = GetLastVehicleOrder(v);
+ order->next = new;
+ } else {
+ /* Put the new order in between */
+ new->next = order->next;
+ order->next = new;
+ }
+ }
+
+ u = GetFirstVehicleFromSharedList(v);
+ DeleteOrderWarnings(u);
+ for (; u != NULL; u = u->next_shared) {
+ /* Increase amount of orders */
+ u->num_orders++;
+
+ /* If the orderlist was empty, assign it */
+ if (u->orders == NULL) u->orders = v->orders;
+
+ assert(v->orders == u->orders);
+
+ /* If there is added an order before the current one, we need
+ to update the selected order */
+ if (sel_ord <= u->cur_order_index) {
+ uint cur = u->cur_order_index + 1;
+ /* Check if we don't go out of bound */
+ if (cur < u->num_orders)
+ u->cur_order_index = cur;
+ }
+ /* Update any possible open window of the vehicle */
+ InvalidateVehicleOrder(u);
+ }
+
+ /* Make sure to rebuild the whole list */
+ RebuildVehicleLists();
+ }
+
+ return 0;
+}
+
+/** Declone an order-list
+ * @param *dst delete the orders of this vehicle
+ * @param flags execution flags
+ */
+static int32 DecloneOrder(Vehicle *dst, uint32 flags)
+{
+ if (flags & DC_EXEC) {
+ DeleteVehicleOrders(dst);
+ InvalidateVehicleOrder(dst);
+ RebuildVehicleLists();
+ }
+ return 0;
+}
+
+/** Delete an order from the orderlist of a vehicle.
+ * @param tile unused
+ * @param p1 the ID of the vehicle
+ * @param p2 the order to delete (max 255)
+ */
+int32 CmdDeleteOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle *v, *u;
+ VehicleID veh_id = p1;
+ VehicleOrderID sel_ord = p2;
+ Order *order;
+
+ if (!IsValidVehicleID(veh_id)) return CMD_ERROR;
+
+ v = GetVehicle(veh_id);
+
+ if (!CheckOwnership(v->owner)) return CMD_ERROR;
+
+ /* If we did not select an order, we maybe want to de-clone the orders */
+ if (sel_ord >= v->num_orders)
+ return DecloneOrder(v, flags);
+
+ order = GetVehicleOrder(v, sel_ord);
+ if (order == NULL) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ if (GetVehicleOrder(v, sel_ord - 1) == NULL) {
+ if (GetVehicleOrder(v, sel_ord + 1) != NULL) {
+ /* First item, but not the last, so we need to alter v->orders
+ Because we can have shared order, we copy the data
+ from the next item over the deleted */
+ order = GetVehicleOrder(v, sel_ord + 1);
+ SwapOrders(v->orders, order);
+ } else {
+ /* Last item, so clean the list */
+ v->orders = NULL;
+ }
+ } else {
+ GetVehicleOrder(v, sel_ord - 1)->next = order->next;
+ }
+
+ /* Give the item free */
+ order->type = OT_NOTHING;
+ order->next = NULL;
+
+ u = GetFirstVehicleFromSharedList(v);
+ DeleteOrderWarnings(u);
+ for (; u != NULL; u = u->next_shared) {
+ u->num_orders--;
+
+ if (sel_ord < u->cur_order_index)
+ u->cur_order_index--;
+
+ /* If we removed the last order, make sure the shared vehicles
+ * also set their orders to NULL */
+ if (v->orders == NULL) u->orders = NULL;
+
+ assert(v->orders == u->orders);
+
+ /* NON-stop flag is misused to see if a train is in a station that is
+ * on his order list or not */
+ if (sel_ord == u->cur_order_index && u->current_order.type == OT_LOADING &&
+ HASBIT(u->current_order.flags, OFB_NON_STOP)) {
+ u->current_order.flags = 0;
+ }
+
+ /* Update any possible open window of the vehicle */
+ InvalidateVehicleOrder(u);
+ }
+
+ RebuildVehicleLists();
+ }
+
+ return 0;
+}
+
+/** Goto next order of order-list.
+ * @param tile unused
+ * @param p1 The ID of the vehicle which order is skipped
+ * @param p2 unused
+ */
+int32 CmdSkipOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle *v;
+ VehicleID veh_id = p1;
+
+ if (!IsValidVehicleID(veh_id)) return CMD_ERROR;
+
+ v = GetVehicle(veh_id);
+
+ if (!CheckOwnership(v->owner)) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ /* Goto next order */
+ VehicleOrderID b = v->cur_order_index + 1;
+ if (b >= v->num_orders) b = 0;
+
+ v->cur_order_index = b;
+
+ if (v->type == VEH_Train) v->u.rail.days_since_order_progr = 0;
+
+ if (v->type == VEH_Road) ClearSlot(v);
+
+ /* NON-stop flag is misused to see if a train is in a station that is
+ * on his order list or not */
+ if (v->current_order.type == OT_LOADING && HASBIT(v->current_order.flags, OFB_NON_STOP))
+ v->current_order.flags = 0;
+
+ InvalidateVehicleOrder(v);
+ }
+
+ /* We have an aircraft/ship, they have a mini-schedule, so update them all */
+ if (v->type == VEH_Aircraft) InvalidateWindowClasses(WC_AIRCRAFT_LIST);
+ if (v->type == VEH_Ship) InvalidateWindowClasses(WC_SHIPS_LIST);
+
+ return 0;
+}
+
+
+/** Modify an order in the orderlist of a vehicle.
+ * @param tile unused
+ * @param p1 various bitstuffed elements
+ * - p1 = (bit 0 - 15) - ID of the vehicle
+ * - p1 = (bit 16 - 31) - the selected order (if any). If the last order is given,
+ * the order will be inserted before that one
+ * only the first 8 bits used currently (bit 16 - 23) (max 255)
+ * @param p2 mode to change the order to (always set)
+ */
+int32 CmdModifyOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle *v;
+ Order *order;
+ VehicleOrderID sel_ord = GB(p1, 16, 16); // XXX - automatically truncated to 8 bits.
+ VehicleID veh = GB(p1, 0, 16);
+
+ if (!IsValidVehicleID(veh)) return CMD_ERROR;
+ if (p2 != OFB_FULL_LOAD && p2 != OFB_UNLOAD && p2 != OFB_NON_STOP && p2 != OFB_TRANSFER) return CMD_ERROR;
+
+ v = GetVehicle(veh);
+
+ if (!CheckOwnership(v->owner)) return CMD_ERROR;
+
+ /* Is it a valid order? */
+ if (sel_ord >= v->num_orders) return CMD_ERROR;
+
+ order = GetVehicleOrder(v, sel_ord);
+ if (order->type != OT_GOTO_STATION &&
+ (order->type != OT_GOTO_DEPOT || p2 == OFB_UNLOAD) &&
+ (order->type != OT_GOTO_WAYPOINT || p2 != OFB_NON_STOP)) {
+ return CMD_ERROR;
+ }
+
+ if (flags & DC_EXEC) {
+ switch (p2) {
+ case OFB_FULL_LOAD:
+ TOGGLEBIT(order->flags, OFB_FULL_LOAD);
+ if (order->type != OT_GOTO_DEPOT) CLRBIT(order->flags, OFB_UNLOAD);
+ break;
+ case OFB_UNLOAD:
+ TOGGLEBIT(order->flags, OFB_UNLOAD);
+ CLRBIT(order->flags, OFB_FULL_LOAD);
+ break;
+ case OFB_NON_STOP:
+ TOGGLEBIT(order->flags, OFB_NON_STOP);
+ break;
+ case OFB_TRANSFER:
+ TOGGLEBIT(order->flags, OFB_TRANSFER);
+ break;
+ default: NOT_REACHED();
+ }
+
+ /* Update the windows and full load flags, also for vehicles that share the same order list */
+ {
+ Vehicle* u;
+
+ u = GetFirstVehicleFromSharedList(v);
+ DeleteOrderWarnings(u);
+ for (; u != NULL; u = u->next_shared) {
+ /* Toggle u->current_order "Full load" flag if it changed.
+ * However, as the same flag is used for depot orders, check
+ * whether we are not going to a depot as there are three
+ * cases where the full load flag can be active and only
+ * one case where the flag is used for depot orders. In the
+ * other cases for the OrderType the flags are not used,
+ * so do not care and those orders should not be active
+ * when this function is called.
+ */
+ if (sel_ord == u->cur_order_index &&
+ u->current_order.type != OT_GOTO_DEPOT &&
+ HASBIT(u->current_order.flags, OFB_FULL_LOAD) != HASBIT(order->flags, OFB_FULL_LOAD)) {
+ TOGGLEBIT(u->current_order.flags, OFB_FULL_LOAD);
+ }
+ InvalidateVehicleOrder(u);
+ }
+ }
+ }
+
+ return 0;
+}
+
+/** Clone/share/copy an order-list of an other vehicle.
+ * @param p1 various bitstuffed elements
+ * - p1 = (bit 0-15) - destination vehicle to clone orders to (p1 & 0xFFFF)
+ * - p1 = (bit 16-31) - source vehicle to clone orders from, if any (none for CO_UNSHARE)
+ * @param p2 mode of cloning: CO_SHARE, CO_COPY, or CO_UNSHARE
+ */
+int32 CmdCloneOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle *dst;
+ VehicleID veh_src = GB(p1, 16, 16);
+ VehicleID veh_dst = GB(p1, 0, 16);
+
+ if (!IsValidVehicleID(veh_dst)) return CMD_ERROR;
+
+ dst = GetVehicle(veh_dst);
+
+ if (!CheckOwnership(dst->owner)) return CMD_ERROR;
+
+ switch (p2) {
+ case CO_SHARE: {
+ Vehicle *src;
+
+ if (!IsValidVehicleID(veh_src)) return CMD_ERROR;
+
+ src = GetVehicle(veh_src);
+
+ /* Sanity checks */
+ if (!CheckOwnership(src->owner) || dst->type != src->type || dst == src)
+ return CMD_ERROR;
+
+ /* Trucks can't share orders with busses (and visa versa) */
+ if (src->type == VEH_Road) {
+ if (src->cargo_type != dst->cargo_type && (src->cargo_type == CT_PASSENGERS || dst->cargo_type == CT_PASSENGERS))
+ return CMD_ERROR;
+ }
+
+ /* Is the vehicle already in the shared list? */
+ {
+ const Vehicle* u;
+
+ for (u = GetFirstVehicleFromSharedList(src); u != NULL; u = u->next_shared) {
+ if (u == dst) return CMD_ERROR;
+ }
+ }
+
+ if (flags & DC_EXEC) {
+ /* If the destination vehicle had a OrderList, destroy it */
+ DeleteVehicleOrders(dst);
+
+ dst->orders = src->orders;
+ dst->num_orders = src->num_orders;
+
+ /* Link this vehicle in the shared-list */
+ dst->next_shared = src->next_shared;
+ dst->prev_shared = src;
+ if (src->next_shared != NULL) src->next_shared->prev_shared = dst;
+ src->next_shared = dst;
+
+ InvalidateVehicleOrder(dst);
+ InvalidateVehicleOrder(src);
+
+ RebuildVehicleLists();
+ }
+ } break;
+
+ case CO_COPY: {
+ Vehicle *src;
+ int delta;
+
+ if (!IsValidVehicleID(veh_src)) return CMD_ERROR;
+
+ src = GetVehicle(veh_src);
+
+ /* Sanity checks */
+ if (!CheckOwnership(src->owner) || dst->type != src->type || dst == src)
+ return CMD_ERROR;
+
+ /* Trucks can't copy all the orders from busses (and visa versa) */
+ if (src->type == VEH_Road) {
+ const Order *order;
+ TileIndex required_dst = INVALID_TILE;
+
+ FOR_VEHICLE_ORDERS(src, order) {
+ if (order->type == OT_GOTO_STATION) {
+ const Station *st = GetStation(order->dest);
+ if (dst->cargo_type == CT_PASSENGERS) {
+ if (st->bus_stops != NULL) required_dst = st->bus_stops->xy;
+ } else {
+ if (st->truck_stops != NULL) required_dst = st->truck_stops->xy;
+ }
+ /* This station has not the correct road-bay, so we can't copy! */
+ if (required_dst == INVALID_TILE)
+ return CMD_ERROR;
+ }
+ }
+ }
+
+ /* make sure there are orders available */
+ delta = IsOrderListShared(dst) ? src->num_orders + 1 : src->num_orders - dst->num_orders;
+ if (!HasOrderPoolFree(delta))
+ return_cmd_error(STR_8831_NO_MORE_SPACE_FOR_ORDERS);
+
+ if (flags & DC_EXEC) {
+ const Order *order;
+ Order **order_dst;
+
+ /* If the destination vehicle had a OrderList, destroy it */
+ DeleteVehicleOrders(dst);
+
+ order_dst = &dst->orders;
+ FOR_VEHICLE_ORDERS(src, order) {
+ *order_dst = AllocateOrder();
+ AssignOrder(*order_dst, *order);
+ order_dst = &(*order_dst)->next;
+ }
+
+ dst->num_orders = src->num_orders;
+
+ InvalidateVehicleOrder(dst);
+
+ RebuildVehicleLists();
+ }
+ } break;
+
+ case CO_UNSHARE: return DecloneOrder(dst, flags);
+ default: return CMD_ERROR;
+ }
+
+ return 0;
+}
+
+/** Add/remove refit orders from an order
+ * @param tile Not used
+ * @param p1 VehicleIndex of the vehicle having the order
+ * @param p2 bitmask
+ * - bit 0-7 CargoID
+ * - bit 8-15 Cargo subtype
+ * - bit 16-23 number of order to modify
+ */
+int32 CmdOrderRefit(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ const Vehicle *v;
+ Order *order;
+ VehicleID veh = GB(p1, 0, 16);
+ VehicleOrderID order_number = GB(p2, 16, 8);
+ CargoID cargo = GB(p2, 0, 8);
+ byte subtype = GB(p2, 8, 8);
+
+ if (!IsValidVehicleID(veh)) return CMD_ERROR;
+
+ v = GetVehicle(veh);
+
+ if (!CheckOwnership(v->owner)) return CMD_ERROR;
+
+ order = GetVehicleOrder(v, order_number);
+ if (order == NULL) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ Vehicle *u;
+
+ order->refit_cargo = cargo;
+ order->refit_subtype = subtype;
+
+ u = GetFirstVehicleFromSharedList(v);
+ for (; u != NULL; u = u->next_shared) {
+ /* Update any possible open window of the vehicle */
+ InvalidateVehicleOrder(u);
+
+ /* If the vehicle already got the current depot set as current order, then update current order as well */
+ if (u->cur_order_index == order_number && HASBIT(u->current_order.flags, OFB_PART_OF_ORDERS)) {
+ u->current_order.refit_cargo = cargo;
+ u->current_order.refit_subtype = subtype;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/**
+ *
+ * Backup a vehicle order-list, so you can replace a vehicle
+ * without loosing the order-list
+ *
+ */
+void BackupVehicleOrders(const Vehicle *v, BackuppedOrders *bak)
+{
+ /* Save general info */
+ bak->orderindex = v->cur_order_index;
+ bak->service_interval = v->service_interval;
+
+ /* Safe custom string, if any */
+ if (!IsCustomName(v->string_id)) {
+ bak->name[0] = '\0';
+ } else {
+ GetName(bak->name, v->string_id & 0x7FF, lastof(bak->name));
+ }
+
+ /* If we have shared orders, store it on a special way */
+ if (IsOrderListShared(v)) {
+ const Vehicle *u = (v->next_shared) ? v->next_shared : v->prev_shared;
+
+ bak->clone = u->index;
+ } else {
+ /* Else copy the orders */
+ Order *order, *dest;
+
+ dest = bak->order;
+
+ /* We do not have shared orders */
+ bak->clone = INVALID_VEHICLE;
+
+ /* Copy the orders */
+ FOR_VEHICLE_ORDERS(v, order) {
+ *dest = *order;
+ dest++;
+ }
+ /* End the list with an OT_NOTHING */
+ dest->type = OT_NOTHING;
+ dest->next = NULL;
+ }
+}
+
+/**
+ *
+ * Restore vehicle orders that are backupped via BackupVehicleOrders
+ *
+ */
+void RestoreVehicleOrders(const Vehicle* v, const BackuppedOrders* bak)
+{
+ uint i;
+
+ /* If we have a custom name, process that */
+ if (bak->name[0] != 0) {
+ _cmd_text = bak->name;
+ DoCommandP(0, v->index, 0, NULL, CMD_NAME_VEHICLE);
+ }
+
+ /* If we had shared orders, recover that */
+ if (bak->clone != INVALID_VEHICLE) {
+ DoCommandP(0, v->index | (bak->clone << 16), 0, NULL, CMD_CLONE_ORDER);
+ return;
+ }
+
+ /* CMD_NO_TEST_IF_IN_NETWORK is used here, because CMD_INSERT_ORDER checks if the
+ * order number is one more than the current amount of orders, and because
+ * in network the commands are queued before send, the second insert always
+ * fails in test mode. By bypassing the test-mode, that no longer is a problem. */
+ for (i = 0; bak->order[i].type != OT_NOTHING; i++) {
+ if (!DoCommandP(0, v->index + (i << 16), PackOrder(&bak->order[i]), NULL, CMD_INSERT_ORDER | CMD_NO_TEST_IF_IN_NETWORK))
+ break;
+ }
+
+ /* Restore vehicle order-index and service interval */
+ DoCommandP(0, v->index, bak->orderindex | (bak->service_interval << 16) , NULL, CMD_RESTORE_ORDER_INDEX);
+}
+
+/** Restore the current order-index of a vehicle and sets service-interval.
+ * @param tile unused
+ * @param p1 the ID of the vehicle
+ * @param p2 various bistuffed elements
+ * - p2 = (bit 0-15) - current order-index (p2 & 0xFFFF)
+ * - p2 = (bit 16-31) - service interval (p2 >> 16)
+ * @todo Unfortunately you cannot safely restore the unitnumber or the old vehicle
+ * as far as I can see. We can store it in BackuppedOrders, and restore it, but
+ * but we have no way of seeing it has been tampered with or not, as we have no
+ * legit way of knowing what that ID was.@n
+ * If we do want to backup/restore it, just add UnitID uid to BackuppedOrders, and
+ * restore it as parameter 'y' (ugly hack I know) for example. "v->unitnumber = y;"
+ */
+int32 CmdRestoreOrderIndex(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle *v;
+ VehicleOrderID cur_ord = GB(p2, 0, 16);
+ uint16 serv_int = GB(p2, 16, 16);
+
+ if (!IsValidVehicleID(p1)) return CMD_ERROR;
+
+ v = GetVehicle(p1);
+
+ /* Check the vehicle type and ownership, and if the service interval and order are in range */
+ if (!CheckOwnership(v->owner)) return CMD_ERROR;
+ if (serv_int != GetServiceIntervalClamped(serv_int) || cur_ord >= v->num_orders) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ v->cur_order_index = cur_ord;
+ v->service_interval = serv_int;
+ }
+
+ return 0;
+}
+
+
+static TileIndex GetStationTileForVehicle(const Vehicle* v, const Station* st)
+{
+ switch (v->type) {
+ default: NOT_REACHED();
+ case VEH_Train: return st->train_tile;
+ case VEH_Aircraft: return st->airport_tile;
+ case VEH_Ship: return st->dock_tile;
+ case VEH_Road:
+ if (v->cargo_type == CT_PASSENGERS) {
+ return (st->bus_stops != NULL) ? st->bus_stops->xy : 0;
+ } else {
+ return (st->truck_stops != NULL) ? st->truck_stops->xy : 0;
+ }
+ }
+}
+
+
+/**
+ *
+ * Check the orders of a vehicle, to see if there are invalid orders and stuff
+ *
+ */
+void CheckOrders(const Vehicle* v)
+{
+ /* Does the user wants us to check things? */
+ if (_patches.order_review_system == 0) return;
+
+ /* Do nothing for crashed vehicles */
+ if (v->vehstatus & VS_CRASHED) return;
+
+ /* Do nothing for stopped vehicles if setting is '1' */
+ if (_patches.order_review_system == 1 && v->vehstatus & VS_STOPPED)
+ return;
+
+ /* do nothing we we're not the first vehicle in a share-chain */
+ if (v->next_shared != NULL) return;
+
+ /* Only check every 20 days, so that we don't flood the message log */
+ if (v->owner == _local_player && v->day_counter % 20 == 0) {
+ int n_st, problem_type = -1;
+ const Order *order;
+ int message = 0;
+
+ /* Check the order list */
+ n_st = 0;
+
+ FOR_VEHICLE_ORDERS(v, order) {
+ /* Dummy order? */
+ if (order->type == OT_DUMMY) {
+ problem_type = 1;
+ break;
+ }
+ /* Does station have a load-bay for this vehicle? */
+ if (order->type == OT_GOTO_STATION) {
+ const Station* st = GetStation(order->dest);
+ TileIndex required_tile = GetStationTileForVehicle(v, st);
+
+ n_st++;
+ if (required_tile == 0) problem_type = 3;
+ }
+ }
+
+ /* Check if the last and the first order are the same */
+ if (v->num_orders > 1) {
+ const Order* last = GetLastVehicleOrder(v);
+
+ if (v->orders->type == last->type &&
+ v->orders->flags == last->flags &&
+ v->orders->dest == last->dest) {
+ problem_type = 2;
+ }
+ }
+
+ /* Do we only have 1 station in our order list? */
+ if (n_st < 2 && problem_type == -1) problem_type = 0;
+
+ /* We don't have a problem */
+ if (problem_type < 0) return;
+
+ message = STR_TRAIN_HAS_TOO_FEW_ORDERS + ((v->type - VEH_Train) << 2) + problem_type;
+ //DEBUG(misc, 3, "Triggered News Item for vehicle %d", v->index);
+
+ SetDParam(0, v->unitnumber);
+ AddNewsItem(
+ message,
+ NEWS_FLAGS(NM_SMALL, NF_VIEWPORT | NF_VEHICLE, NT_ADVICE, 0),
+ v->index,
+ 0
+ );
+ }
+}
+
+/**
+ * Removes an order from all vehicles. Triggers when, say, a station is removed.
+ * @param type The type of the order (OT_GOTO_[STATION|DEPOT|WAYPOINT]).
+ * @param destination The destination. Can be a StationID, DepotID or WaypointID.
+ */
+void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination)
+{
+ Vehicle *v;
+
+ /* Aircraft have StationIDs for depot orders and never use DepotIDs
+ * This fact is handled specially below
+ */
+
+ /* Go through all vehicles */
+ FOR_ALL_VEHICLES(v) {
+ Order *order;
+ bool invalidate;
+
+ /* Forget about this station if this station is removed */
+ if (v->last_station_visited == destination && type == OT_GOTO_STATION) {
+ v->last_station_visited = INVALID_STATION;
+ }
+
+ order = &v->current_order;
+ if ((v->type == VEH_Aircraft && order->type == OT_GOTO_DEPOT ? OT_GOTO_STATION : order->type) == type &&
+ v->current_order.dest == destination) {
+ order->type = OT_DUMMY;
+ order->flags = 0;
+ InvalidateWindow(WC_VEHICLE_VIEW, v->index);
+ }
+
+ /* Clear the order from the order-list */
+ invalidate = false;
+ FOR_VEHICLE_ORDERS(v, order) {
+ if ((v->type == VEH_Aircraft && order->type == OT_GOTO_DEPOT ? OT_GOTO_STATION : order->type) == type &&
+ order->dest == destination) {
+ order->type = OT_DUMMY;
+ order->flags = 0;
+ invalidate = true;
+ }
+ }
+
+ /* Only invalidate once, and if needed */
+ if (invalidate) InvalidateWindow(WC_VEHICLE_ORDERS, v->index);
+ }
+}
+
+/**
+ *
+ * Checks if a vehicle has a GOTO_DEPOT in his order list
+ *
+ * @return True if this is true (lol ;))
+ *
+ */
+bool VehicleHasDepotOrders(const Vehicle *v)
+{
+ const Order *order;
+
+ FOR_VEHICLE_ORDERS(v, order) {
+ if (order->type == OT_GOTO_DEPOT)
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ *
+ * Delete all orders from a vehicle
+ *
+ */
+void DeleteVehicleOrders(Vehicle *v)
+{
+ Order *cur, *next;
+
+ DeleteOrderWarnings(v);
+
+ /* If we have a shared order-list, don't delete the list, but just
+ remove our pointer */
+ if (IsOrderListShared(v)) {
+ const Vehicle *u = v;
+
+ v->orders = NULL;
+ v->num_orders = 0;
+
+ /* Unlink ourself */
+ if (v->prev_shared != NULL) {
+ v->prev_shared->next_shared = v->next_shared;
+ u = v->prev_shared;
+ }
+ if (v->next_shared != NULL) {
+ v->next_shared->prev_shared = v->prev_shared;
+ u = v->next_shared;
+ }
+ v->prev_shared = NULL;
+ v->next_shared = NULL;
+
+ /* We only need to update this-one, because if there is a third
+ * vehicle which shares the same order-list, nothing will change. If
+ * this is the last vehicle, the last line of the order-window
+ * will change from Shared order list, to Order list, so it needs
+ * an update */
+ InvalidateVehicleOrder(u);
+ return;
+ }
+
+ /* Remove the orders */
+ cur = v->orders;
+ v->orders = NULL;
+ v->num_orders = 0;
+
+ if (cur != NULL) {
+ /* Delete the vehicle list of shared orders, if any */
+ int window_type = 0;
+
+ switch (v->type) {
+ case VEH_Train: window_type = WC_TRAINS_LIST; break;
+ case VEH_Road: window_type = WC_ROADVEH_LIST; break;
+ case VEH_Ship: window_type = WC_SHIPS_LIST; break;
+ case VEH_Aircraft: window_type = WC_AIRCRAFT_LIST; break;
+ default: NOT_REACHED();
+ }
+ DeleteWindowById(window_type, (cur->index << 16) | (v->type << 11) | VLW_SHARED_ORDERS | v->owner);
+ }
+
+ while (cur != NULL) {
+ next = cur->next;
+ DeleteOrder(cur);
+ cur = next;
+ }
+}
+
+/**
+ *
+ * Check if we share our orders with an other vehicle
+ *
+ * @return Returns the vehicle who has the same order
+ *
+ */
+bool IsOrderListShared(const Vehicle *v)
+{
+ return v->next_shared != NULL || v->prev_shared != NULL;
+}
+
+/**
+ *
+ * Check if a vehicle has any valid orders
+ *
+ * @return false if there are no valid orders
+ *
+ */
+bool CheckForValidOrders(const Vehicle* v)
+{
+ const Order *order;
+
+ FOR_VEHICLE_ORDERS(v, order) if (order->type != OT_DUMMY) return true;
+
+ return false;
+}
+
+void InitializeOrders(void)
+{
+ CleanPool(&_Order_pool);
+ AddBlockToPool(&_Order_pool);
+
+ _backup_orders_tile = 0;
+}
+
+static const SaveLoad _order_desc[] = {
+ SLE_VAR(Order, type, SLE_UINT8),
+ SLE_VAR(Order, flags, SLE_UINT8),
+ SLE_VAR(Order, dest, SLE_UINT16),
+ SLE_REF(Order, next, REF_ORDER),
+ SLE_CONDVAR(Order, refit_cargo, SLE_UINT8, 36, SL_MAX_VERSION),
+ SLE_CONDVAR(Order, refit_subtype, SLE_UINT8, 36, SL_MAX_VERSION),
+
+ /* Leftover from the minor savegame version stuff
+ * We will never use those free bytes, but we have to keep this line to allow loading of old savegames */
+ SLE_CONDNULL(10, 5, 35),
+ SLE_END()
+};
+
+static void Save_ORDR(void)
+{
+ Order *order;
+
+ FOR_ALL_ORDERS(order) {
+ SlSetArrayIndex(order->index);
+ SlObject(order, _order_desc);
+ }
+}
+
+static void Load_ORDR(void)
+{
+ if (CheckSavegameVersionOldStyle(5, 2)) {
+ /* Version older than 5.2 did not have a ->next pointer. Convert them
+ (in the old days, the orderlist was 5000 items big) */
+ uint len = SlGetFieldLength();
+ uint i;
+
+ if (CheckSavegameVersion(5)) {
+ /* Pre-version 5 had an other layout for orders
+ (uint16 instead of uint32) */
+ uint16 orders[5000];
+
+ len /= sizeof(uint16);
+ assert (len <= lengthof(orders));
+
+ SlArray(orders, len, SLE_UINT16);
+
+ for (i = 0; i < len; ++i) {
+ if (!AddBlockIfNeeded(&_Order_pool, i))
+ error("Orders: failed loading savegame: too many orders");
+
+ AssignOrder(GetOrder(i), UnpackVersion4Order(orders[i]));
+ }
+ } else if (CheckSavegameVersionOldStyle(5, 2)) {
+ uint32 orders[5000];
+
+ len /= sizeof(uint32);
+ assert (len <= lengthof(orders));
+
+ SlArray(orders, len, SLE_UINT32);
+
+ for (i = 0; i < len; ++i) {
+ if (!AddBlockIfNeeded(&_Order_pool, i))
+ error("Orders: failed loading savegame: too many orders");
+
+ AssignOrder(GetOrder(i), UnpackOrder(orders[i]));
+ }
+ }
+
+ /* Update all the next pointer */
+ for (i = 1; i < len; ++i) {
+ /* The orders were built like this:
+ * Vehicle one had order[0], and as long as order++.type was not
+ * OT_NOTHING, it was part of the order-list of that vehicle */
+ if (GetOrder(i)->type != OT_NOTHING)
+ GetOrder(i - 1)->next = GetOrder(i);
+ }
+ } else {
+ int index;
+
+ while ((index = SlIterateArray()) != -1) {
+ Order *order;
+
+ if (!AddBlockIfNeeded(&_Order_pool, index))
+ error("Orders: failed loading savegame: too many orders");
+
+ order = GetOrder(index);
+ SlObject(order, _order_desc);
+ }
+ }
+}
+
+const ChunkHandler _order_chunk_handlers[] = {
+ { 'ORDR', Save_ORDR, Load_ORDR, CH_ARRAY | CH_LAST},
+};
diff --git a/src/order_gui.c b/src/order_gui.c
new file mode 100644
index 000000000..adcaadba0
--- /dev/null
+++ b/src/order_gui.c
@@ -0,0 +1,664 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "road_map.h"
+#include "station_map.h"
+#include "table/sprites.h"
+#include "table/strings.h"
+#include "functions.h"
+#include "map.h"
+#include "tile.h"
+#include "window.h"
+#include "gui.h"
+#include "gfx.h"
+#include "vehicle.h"
+#include "station.h"
+#include "town.h"
+#include "command.h"
+#include "viewport.h"
+#include "depot.h"
+#include "waypoint.h"
+#include "train.h"
+#include "water_map.h"
+#include "vehicle_gui.h"
+
+static int OrderGetSel(const Window *w)
+{
+ const Vehicle *v = GetVehicle(w->window_number);
+ int num = WP(w,order_d).sel;
+
+ return (num >= 0 && num < v->num_orders) ? num : v->num_orders;
+}
+
+static StringID StationOrderStrings[] = {
+ STR_8806_GO_TO,
+ STR_8807_GO_TO_TRANSFER,
+ STR_8808_GO_TO_UNLOAD,
+ STR_8809_GO_TO_TRANSFER_UNLOAD,
+ STR_880A_GO_TO_LOAD,
+ STR_880B_GO_TO_TRANSFER_LOAD,
+ STR_NULL,
+ STR_NULL,
+ STR_880C_GO_NON_STOP_TO,
+ STR_880D_GO_TO_NON_STOP_TRANSFER,
+ STR_880E_GO_NON_STOP_TO_UNLOAD,
+ STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD,
+ STR_8810_GO_NON_STOP_TO_LOAD,
+ STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD,
+ STR_NULL
+};
+
+static void DrawOrdersWindow(Window *w)
+{
+ const Vehicle *v;
+ const Order *order;
+ StringID str;
+ int sel;
+ int y, i;
+ bool shared_orders;
+ byte color;
+
+ v = GetVehicle(w->window_number);
+
+ shared_orders = IsOrderListShared(v);
+
+ SetVScrollCount(w, v->num_orders + 1);
+
+ sel = OrderGetSel(w);
+ SetDParam(2, STR_8827_FULL_LOAD);
+
+ order = GetVehicleOrder(v, sel);
+
+ if (v->owner == _local_player) {
+ /* skip */
+ SetWindowWidgetDisabledState(w, 4, v->num_orders == 0);
+
+ /* delete */
+ SetWindowWidgetDisabledState(w, 5,
+ (uint)v->num_orders + (shared_orders ? 1 : 0) <= (uint)WP(w, order_d).sel);
+
+ /* non-stop only for trains */
+ SetWindowWidgetDisabledState(w, 6, v->type != VEH_Train || order == NULL);
+ SetWindowWidgetDisabledState(w, 8, order == NULL); // full load
+ SetWindowWidgetDisabledState(w, 9, order == NULL); // unload
+ SetWindowWidgetDisabledState(w, 10, order == NULL); // transfer
+ /* Disable list of vehicles with the same shared orders if there is no list */
+ SetWindowWidgetDisabledState(w, 11, !shared_orders || v->orders == NULL);
+ SetWindowWidgetDisabledState(w, 12, order == NULL); // Refit
+ HideWindowWidget(w, 12); // Refit
+ } else {
+ DisableWindowWidget(w, 10);
+ }
+
+ ShowWindowWidget(w, 9); // Unload
+
+ if (order != NULL) {
+ switch (order->type) {
+ case OT_GOTO_STATION: break;
+
+ case OT_GOTO_DEPOT:
+ DisableWindowWidget(w, 10);
+
+ /* Remove unload and replace it with refit */
+ HideWindowWidget(w, 9);
+ ShowWindowWidget(w, 12);
+ SetDParam(2,STR_SERVICE);
+ break;
+
+ case OT_GOTO_WAYPOINT:
+ DisableWindowWidget(w, 8);
+ DisableWindowWidget(w, 9);
+ DisableWindowWidget(w, 10);
+ break;
+
+ default: // every other orders
+ DisableWindowWidget(w, 6);
+ DisableWindowWidget(w, 8);
+ DisableWindowWidget(w, 9);
+ }
+ }
+
+ SetDParam(0, v->string_id);
+ SetDParam(1, v->unitnumber);
+ DrawWindowWidgets(w);
+
+ y = 15;
+
+ i = w->vscroll.pos;
+ order = GetVehicleOrder(v, i);
+ while (order != NULL) {
+ str = (v->cur_order_index == i) ? STR_8805 : STR_8804;
+ SetDParam(3, STR_EMPTY);
+
+ if (i - w->vscroll.pos < w->vscroll.cap) {
+ SetDParam(1, 6);
+
+ switch (order->type) {
+ case OT_GOTO_STATION:
+ SetDParam(1, StationOrderStrings[order->flags]);
+ SetDParam(2, order->dest);
+ break;
+
+ case OT_GOTO_DEPOT: {
+ StringID s = STR_NULL;
+
+ if (v->type == VEH_Aircraft) {
+ s = STR_GO_TO_AIRPORT_HANGAR;
+ SetDParam(2, order->dest);
+ } else {
+ SetDParam(2, GetDepot(order->dest)->town_index);
+
+ switch (v->type) {
+ case VEH_Train: s = (order->flags & OF_NON_STOP) ? STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT : STR_GO_TO_TRAIN_DEPOT; break;
+ case VEH_Road: s = STR_9038_GO_TO_ROADVEH_DEPOT; break;
+ case VEH_Ship: s = STR_GO_TO_SHIP_DEPOT; break;
+ default: break;
+ }
+ }
+
+ if (order->flags & OF_FULL_LOAD) s++; /* service at */
+
+ SetDParam(1, s);
+ if (order->refit_cargo < NUM_CARGO) {
+ SetDParam(3, STR_REFIT_ORDER);
+ SetDParam(4, _cargoc.names_s[order->refit_cargo]);
+ } else {
+ SetDParam(3, STR_EMPTY);
+ }
+ break;
+ }
+
+ case OT_GOTO_WAYPOINT:
+ SetDParam(1, (order->flags & OF_NON_STOP) ? STR_GO_NON_STOP_TO_WAYPOINT : STR_GO_TO_WAYPOINT);
+ SetDParam(2, order->dest);
+ break;
+
+ default: break;
+ }
+
+ color = (i == WP(w,order_d).sel) ? 0xC : 0x10;
+ SetDParam(0, i + 1);
+ if (order->type != OT_DUMMY) {
+ DrawString(2, y, str, color);
+ } else {
+ SetDParam(1, STR_INVALID_ORDER);
+ SetDParam(2, order->dest);
+ DrawString(2, y, str, color);
+ }
+ y += 10;
+ }
+
+ i++;
+ order = order->next;
+ }
+
+ if (i - w->vscroll.pos < w->vscroll.cap) {
+ str = shared_orders ? STR_END_OF_SHARED_ORDERS : STR_882A_END_OF_ORDERS;
+ color = (i == WP(w,order_d).sel) ? 0xC : 0x10;
+ DrawString(2, y, str, color);
+ }
+}
+
+static Order GetOrderCmdFromTile(const Vehicle *v, TileIndex tile)
+{
+ Order order;
+ order.next = NULL;
+ order.index = 0;
+ order.refit_cargo = CT_INVALID;
+ order.refit_subtype = 0;
+
+ // check depot first
+ if (_patches.gotodepot) {
+ switch (GetTileType(tile)) {
+ case MP_RAILWAY:
+ if (v->type == VEH_Train && IsTileOwner(tile, _local_player)) {
+ if (IsRailDepot(tile)) {
+ order.type = OT_GOTO_DEPOT;
+ order.flags = OF_PART_OF_ORDERS;
+ order.dest = GetDepotByTile(tile)->index;
+ return order;
+ }
+ }
+ break;
+
+ case MP_STREET:
+ if (GetRoadTileType(tile) == ROAD_TILE_DEPOT && v->type == VEH_Road && IsTileOwner(tile, _local_player)) {
+ order.type = OT_GOTO_DEPOT;
+ order.flags = OF_PART_OF_ORDERS;
+ order.dest = GetDepotByTile(tile)->index;
+ return order;
+ }
+ break;
+
+ case MP_STATION:
+ if (v->type != VEH_Aircraft) break;
+ if (IsHangar(tile) && IsTileOwner(tile, _local_player)) {
+ order.type = OT_GOTO_DEPOT;
+ order.flags = OF_PART_OF_ORDERS;
+ order.dest = GetStationIndex(tile);
+ return order;
+ }
+ break;
+
+ case MP_WATER:
+ if (v->type != VEH_Ship) break;
+ if (IsTileDepotType(tile, TRANSPORT_WATER) &&
+ IsTileOwner(tile, _local_player)) {
+ TileIndex tile2 = GetOtherShipDepotTile(tile);
+
+ order.type = OT_GOTO_DEPOT;
+ order.flags = OF_PART_OF_ORDERS;
+ order.dest = GetDepotByTile(tile < tile2 ? tile : tile2)->index;
+ return order;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ // check waypoint
+ if (IsTileType(tile, MP_RAILWAY) &&
+ v->type == VEH_Train &&
+ IsTileOwner(tile, _local_player) &&
+ IsRailWaypoint(tile)) {
+ order.type = OT_GOTO_WAYPOINT;
+ order.flags = 0;
+ order.dest = GetWaypointByTile(tile)->index;
+ return order;
+ }
+
+ if (IsTileType(tile, MP_STATION)) {
+ StationID st_index = GetStationIndex(tile);
+ const Station *st = GetStation(st_index);
+
+ if (st->owner == _current_player || st->owner == OWNER_NONE) {
+ byte facil;
+ (facil=FACIL_DOCK, v->type == VEH_Ship) ||
+ (facil=FACIL_TRAIN, v->type == VEH_Train) ||
+ (facil=FACIL_AIRPORT, v->type == VEH_Aircraft) ||
+ (facil=FACIL_BUS_STOP, v->type == VEH_Road && v->cargo_type == CT_PASSENGERS) ||
+ (facil=FACIL_TRUCK_STOP, 1);
+ if (st->facilities & facil) {
+ order.type = OT_GOTO_STATION;
+ order.flags = 0;
+ order.dest = st_index;
+ return order;
+ }
+ }
+ }
+
+ // not found
+ order.type = OT_NOTHING;
+ order.flags = 0;
+ order.dest = INVALID_STATION;
+ return order;
+}
+
+static bool HandleOrderVehClick(const Vehicle *v, const Vehicle *u, Window *w)
+{
+ if (u->type != v->type) return false;
+
+ if (u->type == VEH_Train && !IsFrontEngine(u)) {
+ u = GetFirstVehicleInChain(u);
+ if (!IsFrontEngine(u)) return false;
+ }
+
+ // v is vehicle getting orders. Only copy/clone orders if vehicle doesn't have any orders yet
+ // obviously if you press CTRL on a non-empty orders vehicle you know what you are doing
+ if (v->num_orders != 0 && _ctrl_pressed == 0) return false;
+
+ if (DoCommandP(v->tile, v->index | (u->index << 16), _ctrl_pressed ? 0 : 1, NULL,
+ _ctrl_pressed ? CMD_CLONE_ORDER | CMD_MSG(STR_CANT_SHARE_ORDER_LIST) : CMD_CLONE_ORDER | CMD_MSG(STR_CANT_COPY_ORDER_LIST))) {
+ WP(w,order_d).sel = -1;
+ ResetObjectToPlace();
+ }
+
+ return true;
+}
+
+static void OrdersPlaceObj(const Vehicle *v, TileIndex tile, Window *w)
+{
+ Order cmd;
+ const Vehicle *u;
+
+ // check if we're clicking on a vehicle first.. clone orders in that case.
+ u = CheckMouseOverVehicle();
+ if (u != NULL && HandleOrderVehClick(v, u, w)) return;
+
+ cmd = GetOrderCmdFromTile(v, tile);
+ if (cmd.type == OT_NOTHING) return;
+
+ if (DoCommandP(v->tile, v->index + (OrderGetSel(w) << 16), PackOrder(&cmd), NULL, CMD_INSERT_ORDER | CMD_MSG(STR_8833_CAN_T_INSERT_NEW_ORDER))) {
+ if (WP(w,order_d).sel != -1) WP(w,order_d).sel++;
+ ResetObjectToPlace();
+ }
+}
+
+static void OrderClick_Goto(Window *w, const Vehicle *v)
+{
+ InvalidateWidget(w, 7);
+ ToggleWidgetLoweredState(w, 7);
+ if (IsWindowWidgetLowered(w, 7)) {
+ _place_clicked_vehicle = NULL;
+ SetObjectToPlaceWnd(ANIMCURSOR_PICKSTATION, 1, w);
+ } else {
+ ResetObjectToPlace();
+ }
+}
+
+static void OrderClick_FullLoad(Window *w, const Vehicle *v)
+{
+ DoCommandP(v->tile, v->index + (OrderGetSel(w) << 16), OFB_FULL_LOAD, NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
+}
+
+static void OrderClick_Unload(Window *w, const Vehicle *v)
+{
+ DoCommandP(v->tile, v->index + (OrderGetSel(w) << 16), OFB_UNLOAD, NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
+}
+
+static void OrderClick_Nonstop(Window *w, const Vehicle *v)
+{
+ DoCommandP(v->tile, v->index + (OrderGetSel(w) << 16), OFB_NON_STOP, NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
+}
+
+static void OrderClick_Transfer(Window* w, const Vehicle* v)
+{
+ DoCommandP(v->tile, v->index + (OrderGetSel(w) << 16), OFB_TRANSFER, NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
+}
+
+static void OrderClick_Skip(Window *w, const Vehicle *v)
+{
+ DoCommandP(v->tile, v->index, 0, NULL, CMD_SKIP_ORDER);
+}
+
+static void OrderClick_Delete(Window *w, const Vehicle *v)
+{
+ DoCommandP(v->tile, v->index, OrderGetSel(w), NULL, CMD_DELETE_ORDER | CMD_MSG(STR_8834_CAN_T_DELETE_THIS_ORDER));
+}
+
+static void OrderClick_Refit(Window *w, const Vehicle *v)
+{
+ if (_ctrl_pressed) {
+ /* Cancel refitting */
+ DoCommandP(v->tile, v->index, (WP(w,order_d).sel << 16) | (CT_NO_REFIT << 8) | CT_NO_REFIT, NULL, CMD_ORDER_REFIT);
+ } else {
+ ShowVehicleRefitWindow(v, WP(w,order_d).sel);
+ }
+}
+
+typedef void OnButtonVehClick(Window *w, const Vehicle *v);
+
+static OnButtonVehClick* const _order_button_proc[] = {
+ OrderClick_Skip,
+ OrderClick_Delete,
+ OrderClick_Nonstop,
+ OrderClick_Goto,
+ OrderClick_FullLoad,
+ OrderClick_Unload,
+ OrderClick_Transfer
+};
+
+static const uint16 _order_keycodes[] = {
+ 'D', //skip order
+ 'F', //delete order
+ 'G', //non-stop
+ 'H', //goto order
+ 'J', //full load
+ 'K' //unload
+};
+
+static void OrdersWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_CREATE:
+ /* Move Refit to the same location as Unload
+ * This will ensure that they always stay at the same location even if Unload is moved in a later commit */
+ w->widget[12].left = w->widget[9].left;
+ w->widget[12].right = w->widget[9].right;
+ w->widget[12].top = w->widget[9].top;
+ w->widget[12].bottom = w->widget[9].bottom;
+ break;
+
+ case WE_PAINT:
+ DrawOrdersWindow(w);
+ break;
+
+ case WE_CLICK: {
+ Vehicle *v = GetVehicle(w->window_number);
+ switch (e->we.click.widget) {
+ case 2: { /* orders list */
+ int sel = (e->we.click.pt.y - 15) / 10;
+
+ if ((uint)sel >= w->vscroll.cap) return;
+
+ sel += w->vscroll.pos;
+
+ if (_ctrl_pressed && sel < v->num_orders) {
+ const Order *ord = GetVehicleOrder(v, sel);
+ TileIndex xy;
+
+ switch (ord->type) {
+ case OT_GOTO_STATION: xy = GetStation(ord->dest)->xy ; break;
+ case OT_GOTO_DEPOT: xy = GetDepot(ord->dest)->xy; break;
+ case OT_GOTO_WAYPOINT: xy = GetWaypoint(ord->dest)->xy; break;
+ default: xy = 0; break;
+ }
+
+ if (xy != 0) ScrollMainWindowToTile(xy);
+ return;
+ }
+
+ if (sel == WP(w,order_d).sel) sel = -1;
+ WP(w,order_d).sel = sel;
+ SetWindowDirty(w);
+ } break;
+
+ case 4: /* skip button */
+ OrderClick_Skip(w, v);
+ break;
+
+ case 5: /* delete button */
+ OrderClick_Delete(w, v);
+ break;
+
+ case 6: /* non stop button */
+ OrderClick_Nonstop(w, v);
+ break;
+
+ case 7: /* goto button */
+ OrderClick_Goto(w, v);
+ break;
+
+ case 8: /* full load button */
+ OrderClick_FullLoad(w, v);
+ break;
+
+ case 9: /* unload button */
+ OrderClick_Unload(w, v);
+ break;
+ case 10: /* transfer button */
+ OrderClick_Transfer(w, v);
+ break;
+ case 11: /* Vehicle with same shared Orders button */
+ ShowVehWithSharedOrders(v, v->type);
+ break;
+ case 12:
+ OrderClick_Refit(w, v);
+ break;
+ }
+ } break;
+
+ case WE_KEYPRESS: {
+ Vehicle *v = GetVehicle(w->window_number);
+ uint i;
+
+ if (v->owner != _local_player) break;
+
+ for (i = 0; i < lengthof(_order_keycodes); i++) {
+ if (e->we.keypress.keycode == _order_keycodes[i]) {
+ e->we.keypress.cont = false;
+ //see if the button is disabled
+ if (!IsWindowWidgetDisabled(w, i + 4)) _order_button_proc[i](w, v);
+ break;
+ }
+ }
+ break;
+ }
+
+ case WE_RCLICK: {
+ const Vehicle *v = GetVehicle(w->window_number);
+ int s = OrderGetSel(w);
+
+ if (e->we.click.widget != 8) break;
+ if (s == v->num_orders || GetVehicleOrder(v, s)->type != OT_GOTO_DEPOT) {
+ GuiShowTooltips(STR_8857_MAKE_THE_HIGHLIGHTED_ORDER);
+ } else {
+ GuiShowTooltips(STR_SERVICE_HINT);
+ }
+ } break;
+
+ case WE_PLACE_OBJ: {
+ OrdersPlaceObj(GetVehicle(w->window_number), e->we.place.tile, w);
+ } break;
+
+ case WE_ABORT_PLACE_OBJ: {
+ RaiseWindowWidget(w, 7);
+ InvalidateWidget(w, 7);
+ } break;
+
+ // check if a vehicle in a depot was clicked..
+ case WE_MOUSELOOP: {
+ const Vehicle *v = _place_clicked_vehicle;
+ /*
+ * Check if we clicked on a vehicle
+ * and if the GOTO button of this window is pressed
+ * This is because of all open order windows WE_MOUSELOOP is called
+ * and if you have 3 windows open, and this check is not done
+ * the order is copied to the last open window instead of the
+ * one where GOTO is enabled
+ */
+ if (v != NULL && IsWindowWidgetLowered(w, 7)) {
+ _place_clicked_vehicle = NULL;
+ HandleOrderVehClick(GetVehicle(w->window_number), v, w);
+ }
+ } break;
+
+ case WE_RESIZE:
+ /* Update the scroll + matrix */
+ w->vscroll.cap = (w->widget[2].bottom - w->widget[2].top) / 10;
+ break;
+
+ case WE_TIMEOUT: { // handle button unclick ourselves...
+ // unclick all buttons except for the 'goto' button (7), which is 'persistent'
+ uint i;
+ for (i = 0; i < w->widget_count; i++) {
+ if (IsWindowWidgetLowered(w, i) && i != 7) {
+ RaiseWindowWidget(w, i);
+ InvalidateWidget(w, i);
+ }
+ }
+ } break;
+ }
+}
+
+static const Widget _orders_train_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_RIGHT, 14, 11, 398, 0, 13, STR_8829_ORDERS, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_RB, 14, 0, 386, 14, 75, 0x0, STR_8852_ORDERS_LIST_CLICK_ON_ORDER},
+{ WWT_SCROLLBAR, RESIZE_LRB, 14, 387, 398, 14, 75, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 52, 76, 87, STR_8823_SKIP, STR_8853_SKIP_THE_CURRENT_ORDER},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 53, 105, 76, 87, STR_8824_DELETE, STR_8854_DELETE_THE_HIGHLIGHTED},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 106, 158, 76, 87, STR_8825_NON_STOP, STR_8855_MAKE_THE_HIGHLIGHTED_ORDER},
+{ WWT_TEXTBTN, RESIZE_TB, 14, 159, 211, 76, 87, STR_8826_GO_TO, STR_8856_INSERT_A_NEW_ORDER_BEFORE},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 212, 264, 76, 87, STR_FULLLOAD_OR_SERVICE, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 265, 319, 76, 87, STR_8828_UNLOAD, STR_8858_MAKE_THE_HIGHLIGHTED_ORDER},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 320, 372, 76, 87, STR_886F_TRANSFER, STR_886D_MAKE_THE_HIGHLIGHTED_ORDER},
+{ WWT_PUSHIMGBTN, RESIZE_TB, 14, 373, 386, 76, 87, SPR_SHARED_ORDERS_ICON, STR_VEH_WITH_SHARED_ORDERS_LIST_TIP},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 320, 372, 76, 87, STR_REFIT, STR_REFIT_TIP},
+{ WWT_PANEL, RESIZE_RTB, 14, 387, 386, 76, 87, 0x0, STR_NULL},
+{ WWT_RESIZEBOX, RESIZE_LRTB, 14, 387, 398, 76, 87, 0x0, STR_RESIZE_BUTTON},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _orders_train_desc = {
+ WDP_AUTO, WDP_AUTO, 399, 88,
+ WC_VEHICLE_ORDERS,WC_VEHICLE_VIEW,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_RESIZABLE,
+ _orders_train_widgets,
+ OrdersWndProc
+};
+
+static const Widget _orders_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_RIGHT, 14, 11, 409, 0, 13, STR_8829_ORDERS, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_RB, 14, 0, 397, 14, 75, 0x0, STR_8852_ORDERS_LIST_CLICK_ON_ORDER},
+{ WWT_SCROLLBAR, RESIZE_LRB, 14, 398, 409, 14, 75, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 63, 76, 87, STR_8823_SKIP, STR_8853_SKIP_THE_CURRENT_ORDER},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 64, 128, 76, 87, STR_8824_DELETE, STR_8854_DELETE_THE_HIGHLIGHTED},
+{ WWT_EMPTY, RESIZE_TB, 14, 0, 0, 76, 87, 0x0, 0x0},
+{ WWT_TEXTBTN, RESIZE_TB, 14, 129, 192, 76, 87, STR_8826_GO_TO, STR_8856_INSERT_A_NEW_ORDER_BEFORE},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 193, 256, 76, 87, STR_FULLLOAD_OR_SERVICE, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 257, 319, 76, 87, STR_8828_UNLOAD, STR_8858_MAKE_THE_HIGHLIGHTED_ORDER},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 320, 383, 76, 87, STR_886F_TRANSFER, STR_886D_MAKE_THE_HIGHLIGHTED_ORDER},
+{ WWT_PUSHIMGBTN, RESIZE_TB, 14, 384, 397, 76, 87, SPR_SHARED_ORDERS_ICON, STR_VEH_WITH_SHARED_ORDERS_LIST_TIP},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 320, 383, 76, 87, STR_REFIT, STR_REFIT_TIP},
+{ WWT_PANEL, RESIZE_RTB, 14, 397, 396, 76, 87, 0x0, STR_NULL},
+{ WWT_RESIZEBOX, RESIZE_LRTB, 14, 398, 409, 76, 87, 0x0, STR_RESIZE_BUTTON},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _orders_desc = {
+ WDP_AUTO, WDP_AUTO, 410, 88,
+ WC_VEHICLE_ORDERS,WC_VEHICLE_VIEW,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_RESIZABLE,
+ _orders_widgets,
+ OrdersWndProc
+};
+
+static const Widget _other_orders_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_RIGHT, 14, 11, 331, 0, 13, STR_A00B_ORDERS, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_RB, 14, 0, 319, 14, 75, 0x0, STR_8852_ORDERS_LIST_CLICK_ON_ORDER},
+{ WWT_SCROLLBAR, RESIZE_LRB, 14, 320, 331, 14, 75, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WWT_EMPTY, RESIZE_NONE, 14, 0, 319, 76, 87, 0x0, STR_NULL},
+{ WWT_EMPTY, RESIZE_NONE, 14, 0, 319, 76, 87, 0x0, STR_NULL},
+{ WWT_EMPTY, RESIZE_NONE, 14, 0, 319, 76, 87, 0x0, STR_NULL},
+{ WWT_EMPTY, RESIZE_NONE, 14, 0, 319, 76, 87, 0x0, STR_NULL},
+{ WWT_EMPTY, RESIZE_NONE, 14, 0, 319, 76, 87, 0x0, STR_NULL},
+{ WWT_EMPTY, RESIZE_NONE, 14, 0, 319, 76, 87, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_RTB, 14, 0, 319, 76, 87, 0x0, STR_NULL},
+{ WWT_RESIZEBOX, RESIZE_LRTB, 14, 320, 331, 76, 87, 0x0, STR_RESIZE_BUTTON},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _other_orders_desc = {
+ WDP_AUTO, WDP_AUTO, 332, 88,
+ WC_VEHICLE_ORDERS,WC_VEHICLE_VIEW,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
+ _other_orders_widgets,
+ OrdersWndProc
+};
+
+void ShowOrdersWindow(const Vehicle *v)
+{
+ Window *w;
+ VehicleID veh = v->index;
+
+ DeleteWindowById(WC_VEHICLE_ORDERS, veh);
+ DeleteWindowById(WC_VEHICLE_DETAILS, veh);
+
+ if (v->owner != _local_player) {
+ w = AllocateWindowDescFront(&_other_orders_desc, veh);
+ } else {
+ w = AllocateWindowDescFront((v->type == VEH_Train) ? &_orders_train_desc : &_orders_desc, veh);
+ }
+
+ if (w != NULL) {
+ w->caption_color = v->owner;
+ w->vscroll.cap = 6;
+ w->resize.step_height = 10;
+ WP(w,order_d).sel = -1;
+ }
+}
diff --git a/src/os/macosx/G5_detector.c b/src/os/macosx/G5_detector.c
new file mode 100644
index 000000000..b4831c772
--- /dev/null
+++ b/src/os/macosx/G5_detector.c
@@ -0,0 +1,29 @@
+/* $Id$ */
+
+#include <mach/mach.h>
+#include <mach/mach_host.h>
+#include <mach/host_info.h>
+#include <mach/machine.h>
+#include <stdio.h>
+
+
+#ifndef CPU_SUBTYPE_POWERPC_970
+#define CPU_SUBTYPE_POWERPC_970 ((cpu_subtype_t) 100)
+#endif
+
+// this function is a lightly modified version of some code from Apple's developer homepage to detect G5 CPUs at runtime
+main()
+{
+ host_basic_info_data_t hostInfo;
+ mach_msg_type_number_t infoCount;
+ boolean_t is_G5;
+
+ infoCount = HOST_BASIC_INFO_COUNT;
+ host_info(mach_host_self(), HOST_BASIC_INFO,
+ (host_info_t)&hostInfo, &infoCount);
+
+ is_G5 = ((hostInfo.cpu_type == CPU_TYPE_POWERPC) &&
+ (hostInfo.cpu_subtype == CPU_SUBTYPE_POWERPC_970));
+ if (is_G5)
+ printf("1");
+}
diff --git a/src/os/macosx/macos.h b/src/os/macosx/macos.h
new file mode 100644
index 000000000..b8a6cd511
--- /dev/null
+++ b/src/os/macosx/macos.h
@@ -0,0 +1,30 @@
+/* $Id$ */
+
+#ifndef MACOS_H
+#define MACOS_H
+
+/*
+ * Functions to show the popup window
+ * use ShowMacDialog when you want to control title, message and text on the button
+ * ShowMacAssertDialog is used by assert
+ * ShowMacErrorDialog should be used when an unrecoverable error shows up. It only contains the title, which will should tell what went wrong
+ * the function then adds text that tells the user to update and then report the bug if it's present in the newest version
+ * It also quits in a nice way since we call it when we know something happened that will crash OpenTTD (like a needed pointer turns out to be NULL or similar)
+ */
+void ShowMacDialog ( const char *title, const char *message, const char *buttonLabel );
+void ShowMacAssertDialog ( const char *function, const char *file, const int line, const char *expression );
+void ShowMacErrorDialog(const char *error);
+
+// Since MacOS X users will never see an assert unless they started the game from a terminal
+// we're using a custom assert(e) macro.
+#undef assert
+
+#ifdef NDEBUG
+#define assert(e) ((void)0)
+#else
+
+#define assert(e) \
+ (__builtin_expect(!(e), 0) ? ShowMacAssertDialog ( __func__, __FILE__, __LINE__, #e ): (void)0 )
+#endif
+
+#endif /* MACOS_H */
diff --git a/src/os/macosx/macos.m b/src/os/macosx/macos.m
new file mode 100644
index 000000000..59801fce0
--- /dev/null
+++ b/src/os/macosx/macos.m
@@ -0,0 +1,162 @@
+/* $Id$ */
+
+#include <AppKit/AppKit.h>
+
+#include <mach/mach.h>
+#include <mach/mach_host.h>
+#include <mach/host_info.h>
+#include <mach/machine.h>
+#include <stdio.h>
+#include "../../stdafx.h"
+#include "../../openttd.h"
+#include "../../newgrf.h"
+#include "../../gfx.h"
+#include "../../macros.h"
+#include "../../string.h"
+
+#ifndef CPU_SUBTYPE_POWERPC_970
+#define CPU_SUBTYPE_POWERPC_970 ((cpu_subtype_t) 100)
+#endif
+
+/*
+ * This file contains objective C
+ * Apple uses objective C instead of plain C to interact with OS specific/native functions
+ *
+ * Note: TrueLight's crosscompiler can handle this, but it likely needs a manual modification for each change in this file.
+ * To insure that the crosscompiler still works, let him try any changes before they are committed
+ */
+
+static char *GetOSString(void)
+{
+ static char buffer[175];
+ const char* CPU;
+ char OS[20];
+ char newgrf[125];
+ long sysVersion;
+ extern const char _openttd_revision[];
+
+ // get the hardware info
+ host_basic_info_data_t hostInfo;
+ mach_msg_type_number_t infoCount;
+
+ infoCount = HOST_BASIC_INFO_COUNT;
+ host_info(
+ mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo, &infoCount
+ );
+
+ // replace the hardware info with strings, that tells a bit more than just an int
+ switch (hostInfo.cpu_subtype) {
+#ifdef __POWERPC__
+ case CPU_SUBTYPE_POWERPC_750: CPU = "G3"; break;
+ case CPU_SUBTYPE_POWERPC_7400:
+ case CPU_SUBTYPE_POWERPC_7450: CPU = "G4"; break;
+ case CPU_SUBTYPE_POWERPC_970: CPU = "G5"; break;
+ default: CPU = "Unknown PPC"; break;
+#else
+ /* it looks odd to have a switch for two cases, but it leaves room for easy
+ * expansion. Odds are that Apple will some day use newer CPUs than i686
+ */
+ case CPU_SUBTYPE_PENTPRO: CPU = "i686"; break;
+ default: CPU = "Unknown Intel"; break;
+#endif
+ }
+
+ // get the version of OSX
+ if (Gestalt(gestaltSystemVersion, &sysVersion) != noErr) {
+ sprintf(OS, "Undetected");
+ } else {
+ int majorHiNib = GB(sysVersion, 12, 4);
+ int majorLoNib = GB(sysVersion, 8, 4);
+ int minorNib = GB(sysVersion, 4, 4);
+ int bugNib = GB(sysVersion, 0, 4);
+
+ sprintf(OS, "%d%d.%d.%d", majorHiNib, majorLoNib, minorNib, bugNib);
+ }
+
+ // make a list of used newgrf files
+ if (_first_grffile != NULL) {
+ char* n = newgrf;
+ const GRFFile* file;
+
+ for (file = _first_grffile; file != NULL; file = file->next) {
+ n = strecpy(n, " ", lastof(newgrf));
+ n = strecpy(n, file->filename, lastof(newgrf));
+ }
+ } else {
+ sprintf(newgrf, "none");
+ }
+
+ snprintf(
+ buffer, lengthof(buffer),
+ "Please add this info: (tip: copy-paste works)\n"
+ "CPU: %s, OSX: %s, OpenTTD version: %s\n"
+ "NewGRF files:%s",
+ CPU, OS, _openttd_revision, newgrf
+ );
+ return buffer;
+}
+
+
+#ifdef WITH_SDL
+
+void ShowMacDialog(const char* title, const char* message, const char* buttonLabel)
+{
+ NSRunAlertPanel([NSString stringWithCString: title], [NSString stringWithCString: message], [NSString stringWithCString: buttonLabel], nil, nil);
+}
+
+#elif defined WITH_COCOA
+
+void CocoaDialog(const char* title, const char* message, const char* buttonLabel);
+
+void ShowMacDialog(const char* title, const char* message, const char* buttonLabel)
+{
+ CocoaDialog(title, message, buttonLabel);
+}
+
+
+#else
+
+void ShowMacDialog(const char* title, const char* message, const char* buttonLabel)
+{
+ fprintf(stderr, "%s: %s\n", title, message);
+}
+
+#endif
+
+void ShowMacAssertDialog(const char* function, const char* file, const int line, const char* expression)
+{
+ const char* buffer =
+ [[NSString stringWithFormat:@
+ "An assertion has failed and OpenTTD must quit.\n"
+ "%s in %s (line %d)\n"
+ "\"%s\"\n"
+ "\n"
+ "You should report this error the OpenTTD developers if you think you found a bug.\n"
+ "\n"
+ "%s",
+ function, file, line, expression, GetOSString()] cString
+ ];
+ NSLog(@"%s", buffer);
+ ToggleFullScreen(0);
+ ShowMacDialog("Assertion Failed", buffer, "Quit");
+
+ // abort so that a debugger has a chance to notice
+ abort();
+}
+
+
+void ShowMacErrorDialog(const char *error)
+{
+ const char* buffer =
+ [[NSString stringWithFormat:@
+ "Please update to the newest version of OpenTTD\n"
+ "If the problem presists, please report this to\n"
+ "http://bugs.openttd.org\n"
+ "\n"
+ "%s",
+ GetOSString()] cString
+ ];
+ ToggleFullScreen(0);
+ ShowMacDialog(error, buffer, "Quit");
+ abort();
+}
diff --git a/src/os/macosx/osx_stdafx.h b/src/os/macosx/osx_stdafx.h
new file mode 100644
index 000000000..9567d70ba
--- /dev/null
+++ b/src/os/macosx/osx_stdafx.h
@@ -0,0 +1,19 @@
+/* $Id$ */
+
+#ifndef MACOS_STDAFX_H
+#define MACOS_STDAFX_H
+
+#include <CoreServices/CoreServices.h>
+// remove the variables that CoreServices defines, but we define ourselves too
+#undef bool
+#undef false
+#undef true
+
+/* Name conflict */
+#define Rect OTTDRect
+#define Point OTTDPoint
+#define GetTime OTTDGetTime
+
+#define SL_ERROR OSX_SL_ERROR
+
+#endif /* MACOS_STDAFX_H */
diff --git a/src/os/macosx/splash.c b/src/os/macosx/splash.c
new file mode 100644
index 000000000..46a19b1a6
--- /dev/null
+++ b/src/os/macosx/splash.c
@@ -0,0 +1,144 @@
+/* $Id$ */
+
+#include "../../stdafx.h"
+#include "../../openttd.h"
+#include "../../variables.h"
+#include "../../macros.h"
+#include "../../debug.h"
+#include "../../functions.h"
+#include "../../gfx.h"
+#include "../../fileio.h"
+
+#include "splash.h"
+
+#ifdef WITH_PNG
+
+#include <png.h>
+
+static void PNGAPI png_my_error(png_structp png_ptr, png_const_charp message)
+{
+ DEBUG(misc, 0, "[libpng] error: %s - %s", message, (char *)png_get_error_ptr(png_ptr));
+ longjmp(png_ptr->jmpbuf, 1);
+}
+
+static void PNGAPI png_my_warning(png_structp png_ptr, png_const_charp message)
+{
+ DEBUG(misc, 1, "[libpng] warning: %s - %s", message, (char *)png_get_error_ptr(png_ptr));
+}
+
+void DisplaySplashImage(void)
+{
+ png_byte header[8];
+ FILE *f;
+ png_structp png_ptr;
+ png_infop info_ptr, end_info;
+ uint width, height, bit_depth, color_type;
+ png_colorp palette;
+ int num_palette;
+ png_bytep *row_pointers;
+ uint8 *src, *dst;
+ uint y;
+ uint xoff, yoff;
+ int i;
+
+ f = FioFOpenFile(SPLASH_IMAGE_FILE);
+ if (f == NULL) return;
+
+ fread(header, 1, 8, f);
+ if (png_sig_cmp(header, 0, 8) != 0) {
+ fclose(f);
+ return;
+ }
+
+ png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, (png_voidp) NULL, png_my_error, png_my_warning);
+
+ if (png_ptr == NULL) {
+ fclose(f);
+ return;
+ }
+
+ info_ptr = png_create_info_struct(png_ptr);
+ if (info_ptr == NULL) {
+ png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
+ fclose(f);
+ return;
+ }
+
+ end_info = png_create_info_struct(png_ptr);
+ if (end_info == NULL) {
+ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
+ fclose(f);
+ return;
+ }
+
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
+ fclose(f);
+ return;
+ }
+
+ png_init_io(png_ptr, f);
+ png_set_sig_bytes(png_ptr, 8);
+
+ png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
+
+ width = png_get_image_width(png_ptr, info_ptr);
+ height = png_get_image_height(png_ptr, info_ptr);
+ bit_depth = png_get_bit_depth(png_ptr, info_ptr);
+ color_type = png_get_color_type(png_ptr, info_ptr);
+
+ if (color_type != PNG_COLOR_TYPE_PALETTE || bit_depth != 8) {
+ png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
+ fclose(f);
+ return;
+ }
+
+ if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE)) {
+ png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
+ fclose(f);
+ return;
+ }
+
+ png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
+
+ row_pointers = png_get_rows(png_ptr, info_ptr);
+
+ memset(_screen.dst_ptr, 0xff, _screen.pitch * _screen.height);
+
+ if (width > (uint) _screen.width) width = _screen.width;
+ if (height > (uint) _screen.height) height = _screen.height;
+
+ xoff = (_screen.width - width) / 2;
+ yoff = (_screen.height - height) / 2;
+ for (y = 0; y < height; y++) {
+ src = row_pointers[y];
+ dst = ((uint8 *) _screen.dst_ptr) + (yoff + y) * _screen.pitch + xoff;
+
+ memcpy(dst, src, width);
+ }
+
+ for (i = 0; i < num_palette; i++) {
+ _cur_palette[i].r = palette[i].red;
+ _cur_palette[i].g = palette[i].green;
+ _cur_palette[i].b = palette[i].blue;
+ }
+
+ _cur_palette[0xff].r = 0;
+ _cur_palette[0xff].g = 0;
+ _cur_palette[0xff].b = 0;
+
+ _pal_first_dirty = 0;
+ _pal_last_dirty = 0xff;
+
+ png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
+ fclose(f);
+ return;
+}
+
+
+
+#else /* WITH_PNG */
+
+void DisplaySplashImage(void) {}
+
+#endif /* WITH_PNG */
diff --git a/src/os/macosx/splash.h b/src/os/macosx/splash.h
new file mode 100644
index 000000000..39880562d
--- /dev/null
+++ b/src/os/macosx/splash.h
@@ -0,0 +1,10 @@
+/* $Id$ */
+
+#ifndef SPLASH_H
+#define SPLASH_H
+
+#define SPLASH_IMAGE_FILE "splash.png"
+
+void DisplaySplashImage(void);
+
+#endif
diff --git a/src/os2.c b/src/os2.c
new file mode 100644
index 000000000..e01d7c0d2
--- /dev/null
+++ b/src/os2.c
@@ -0,0 +1,266 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "variables.h"
+#include "string.h"
+#include "table/strings.h"
+#include "gfx.h"
+#include "gui.h"
+#include "functions.h"
+#include "macros.h"
+
+#include <direct.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <time.h>
+#include <dos.h>
+
+#define INCL_WIN
+#define INCL_WINCLIPBOARD
+
+#include <os2.h>
+#include <i86.h>
+
+bool FiosIsRoot(const char *file)
+{
+ return path[3] == '\0';
+}
+
+void FiosGetDrives(void)
+{
+ FiosItem *fios;
+ unsigned disk, disk2, save, total;
+
+ _dos_getdrive(&save); // save original drive
+
+ /* get an available drive letter */
+ for (disk = 1;; disk++) {
+ _dos_setdrive(disk, &total);
+ if (disk >= total) return;
+ _dos_getdrive(&disk2);
+
+ if (disk == disk2) {
+ FiosItem *fios = FiosAlloc();
+ fios->type = FIOS_TYPE_DRIVE;
+ fios->mtime = 0;
+ snprintf(fios->name, lengthof(fios->name), "%c:", 'A' + disk - 1);
+ ttd_strlcpy(fios->title, fios->name, lengthof(fios->title));
+ }
+ }
+
+ _dos_setdrive(save, &total); // restore the original drive
+}
+
+bool FiosGetDiskFreeSpace(const char *path, uint32 *tot)
+{
+ struct diskfree_t free;
+ char drive = path[0] - 'A' + 1;
+
+ if (tot != NULL && _getdiskfree(drive, &free) == 0) {
+ *tot = free.avail_clusters * free.sectors_per_cluster * free.bytes_per_sector;
+ return true;
+ }
+
+ return false;
+}
+
+bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb)
+{
+ char filename[MAX_PATH];
+
+ snprintf(filename, lengthof(filename), "%s" PATHSEP "%s", path, ent->d_name);
+ if (stat(filename, sb) != 0) return false;
+
+ return (ent->d_name[0] != '.'); // hidden file
+}
+
+static void ChangeWorkingDirectory(char *exe)
+{
+ char *s = strrchr(exe, '\\');
+ if (s != NULL) {
+ *s = '\0';
+ chdir(exe);
+ *s = '\\';
+ }
+}
+
+void ShowInfo(const char *str)
+{
+ HAB hab;
+ HMQ hmq;
+ ULONG rc;
+
+ // init PM env.
+ hmq = WinCreateMsgQueue((hab = WinInitialize(0)), 0);
+
+ // display the box
+ rc = WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, str, "OpenTTD", 0, MB_OK | MB_MOVEABLE | MB_INFORMATION);
+
+ // terminate PM env.
+ WinDestroyMsgQueue(hmq);
+ WinTerminate(hab);
+}
+
+void ShowOSErrorBox(const char *buf)
+{
+ HAB hab;
+ HMQ hmq;
+ ULONG rc;
+
+ // init PM env.
+ hmq = WinCreateMsgQueue((hab = WinInitialize(0)), 0);
+
+ // display the box
+ rc = WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, buf, "OpenTTD", 0, MB_OK | MB_MOVEABLE | MB_ERROR);
+
+ // terminate PM env.
+ WinDestroyMsgQueue(hmq);
+ WinTerminate(hab);
+}
+
+int CDECL main(int argc, char* argv[])
+{
+ // change the working directory to enable doubleclicking in UIs
+ ChangeWorkingDirectory(argv[0]);
+
+ _random_seeds[1][1] = _random_seeds[1][0] = _random_seeds[0][1] = _random_seeds[0][0] = time(NULL);
+
+ return ttd_main(argc, argv);
+}
+
+void DeterminePaths(void)
+{
+ char *s;
+
+ _paths.game_data_dir = malloc(MAX_PATH);
+ ttd_strlcpy(_paths.game_data_dir, GAME_DATA_DIR, MAX_PATH);
+ #if defined SECOND_DATA_DIR
+ _paths.second_data_dir = malloc(MAX_PATH);
+ ttd_strlcpy(_paths.second_data_dir, SECOND_DATA_DIR, MAX_PATH);
+ #endif
+
+#if defined(USE_HOMEDIR)
+ {
+ const char *homedir = getenv("HOME");
+
+ if (homedir == NULL) {
+ const struct passwd *pw = getpwuid(getuid());
+ if (pw != NULL) homedir = pw->pw_dir;
+ }
+
+ _paths.personal_dir = str_fmt("%s" PATHSEP "%s", homedir, PERSONAL_DIR);
+ }
+
+#else /* not defined(USE_HOMEDIR) */
+
+ _paths.personal_dir = malloc(MAX_PATH);
+ ttd_strlcpy(_paths.personal_dir, PERSONAL_DIR, MAX_PATH);
+
+ // check if absolute or relative path
+ s = strchr(_paths.personal_dir, '\\');
+
+ // add absolute path
+ if (s == NULL || _paths.personal_dir != s) {
+ getcwd(_paths.personal_dir, MAX_PATH);
+ s = strchr(_paths.personal_dir, 0);
+ *s++ = '\\';
+ ttd_strlcpy(s, PERSONAL_DIR, MAX_PATH);
+ }
+
+#endif /* defined(USE_HOMEDIR) */
+
+ s = strchr(_paths.personal_dir, 0);
+
+ // append a / ?
+ if (s[-1] != '\\') strcpy(s, "\\");
+
+ _paths.save_dir = str_fmt("%ssave", _paths.personal_dir);
+ _paths.autosave_dir = str_fmt("%s\\autosave", _paths.save_dir);
+ _paths.scenario_dir = str_fmt("%sscenario", _paths.personal_dir);
+ _paths.heightmap_dir = str_fmt("%sscenario\\heightmap", _paths.personal_dir);
+ _paths.gm_dir = str_fmt("%sgm\\", _paths.game_data_dir);
+ _paths.data_dir = str_fmt("%sdata\\", _paths.game_data_dir);
+
+ if (_config_file == NULL)
+ _config_file = str_fmt("%sopenttd.cfg", _paths.personal_dir);
+
+ _highscore_file = str_fmt("%shs.dat", _paths.personal_dir);
+ _log_file = str_fmt("%sopenttd.log", _paths.personal_dir);
+
+#if defined CUSTOM_LANG_DIR
+ // sets the search path for lng files to the custom one
+ _paths.lang_dir = malloc( MAX_PATH );
+ ttd_strlcpy( _paths.lang_dir, CUSTOM_LANG_DIR, MAX_PATH);
+#else
+ _paths.lang_dir = str_fmt("%slang\\", _paths.game_data_dir);
+#endif
+
+ // create necessary folders
+ mkdir(_paths.personal_dir);
+ mkdir(_paths.save_dir);
+ mkdir(_paths.autosave_dir);
+ mkdir(_paths.scenario_dir);
+ mkdir(_paths.heightmap_dir);
+}
+
+/**
+ * Insert a chunk of text from the clipboard onto the textbuffer. Get TEXT clipboard
+ * and append this up to the maximum length (either absolute or screenlength). If maxlength
+ * is zero, we don't care about the screenlength but only about the physical length of the string
+ * @param tb @Textbuf type to be changed
+ * @return Return true on successfull change of Textbuf, or false otherwise
+ */
+bool InsertTextBufferClipboard(Textbuf *tb)
+{
+ HAB hab = 0;
+
+ if (WinOpenClipbrd(hab))
+ {
+ const char* text = (const char*)WinQueryClipbrdData(hab, CF_TEXT);
+
+ if (text != NULL)
+ {
+ uint length = 0;
+ uint width = 0;
+ const char* i;
+
+ for (i = text; IsValidAsciiChar(*i); i++)
+ {
+ uint w;
+
+ if (tb->length + length >= tb->maxlength - 1) break;
+
+ w = GetCharacterWidth(FS_NORMAL, (byte)*i);
+ if (tb->maxwidth != 0 && width + tb->width + w > tb->maxwidth) break;
+
+ width += w;
+ length++;
+ }
+
+ memmove(tb->buf + tb->caretpos + length, tb->buf + tb->caretpos, tb->length - tb->caretpos + 1);
+ memcpy(tb->buf + tb->caretpos, text, length);
+ tb->width += width;
+ tb->caretxoffs += width;
+ tb->length += length;
+ tb->caretpos += length;
+
+ WinCloseClipbrd(hab);
+ return true;
+ }
+
+ WinCloseClipbrd(hab);
+ }
+
+ return false;
+}
+
+
+void CSleep(int milliseconds)
+{
+ delay(milliseconds);
+}
+
+const char *FS2OTTD(const char *name) {return name;}
+const char *OTTD2FS(const char *name) {return name;}
diff --git a/src/os_timer.c b/src/os_timer.c
new file mode 100644
index 000000000..e2a96e8f9
--- /dev/null
+++ b/src/os_timer.c
@@ -0,0 +1,70 @@
+/* $Id$ */
+
+#include "stdafx.h"
+
+#undef RDTSC_AVAILABLE
+
+/* rdtsc for MSC_VER, uses simple inline assembly, or _rdtsc
+ * from external win64.asm because VS2005 does not support inline assembly */
+#if defined(_MSC_VER) && !defined(RDTSC_AVAILABLE)
+# if defined (_M_AMD64)
+extern uint64 _rdtsc(void);
+# else
+uint64 _declspec(naked) _rdtsc(void)
+{
+ _asm {
+ rdtsc
+ ret
+ }
+}
+# endif
+# define RDTSC_AVAILABLE
+#endif
+
+/* rdtsc for OS/2. Hopefully this works, who knows */
+#if defined (__WATCOMC__) && !defined(RDTSC_AVAILABLE)
+unsigned __int64 _rdtsc( void);
+# pragma aux _rdtsc = 0x0F 0x31 value [edx eax] parm nomemory modify exact [edx eax] nomemory;
+# define RDTSC_AVAILABLE
+#endif
+
+/* rdtsc for all other *nix-en (hopefully). Use GCC syntax */
+#if defined(__i386__) || defined(__x86_64__) && !defined(RDTSC_AVAILABLE)
+uint64 _rdtsc(void)
+{
+ uint32 high, low;
+ __asm__ __volatile__ ("rdtsc" : "=a" (low), "=d" (high));
+ return ((uint64)high << 32) | low;
+}
+# define RDTSC_AVAILABLE
+#endif
+
+/* rdtsc for PPC which has this not */
+#if (defined(__POWERPC__) || defined(__powerpc__)) && !defined(RDTSC_AVAILABLE)
+uint64 _rdtsc(void)
+{
+ uint32 high = 0, high2 = 0, low;
+ /* PPC does not have rdtsc, so we cheat by reading the two 32-bit time-counters
+ * it has, 'Move From Time Base (Upper)'. Since these are two reads, in the
+ * very unlikely event that the lower part overflows to the upper part while we
+ * read it; we double-check and reread the registers */
+ asm volatile (
+ "mftbu %0\n"
+ "mftb %1\n"
+ "mftbu %2\n"
+ "cmpw %3,%4\n"
+ "bne- $-16\n"
+ : "=r" (high), "=r" (low), "=r" (high2)
+ : "0" (high), "2" (high2)
+ );
+ return ((uint64)high << 32) | low;
+}
+# define RDTSC_AVAILABLE
+#endif
+
+/* In all other cases we have no support for rdtsc. No major issue,
+ * you just won't be able to profile your code with TIC()/TOC() */
+#if !defined(RDTSC_AVAILABLE)
+#warning "(non-fatal) No support for rdtsc(), you won't be able to profile with TIC/TOC"
+uint64 _rdtsc(void) {return 0;}
+#endif
diff --git a/src/ottdres.rc b/src/ottdres.rc
new file mode 100644
index 000000000..383d59af4
--- /dev/null
+++ b/src/ottdres.rc
@@ -0,0 +1,107 @@
+//Microsoft Developer Studio generated resource script.
+//
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "resource.h"
+#define APSTUDIO_HIDDEN_SYMBOLS
+#include "windows.h"
+#undef APSTUDIO_HIDDEN_SYMBOLS
+#ifdef MSVC
+#include "winres.h"
+#else
+#include "afxres.h"
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Neutral (Default) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEUD)
+#ifdef _WIN32
+LANGUAGE LANG_NEUTRAL, SUBLANG_DEFAULT
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+100 ICON DISCARDABLE "openttd.ico"
+101 ICON DISCARDABLE "mainicon.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+100 DIALOG DISCARDABLE 0, 0, 305, 70
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Fatal Application Failure"
+FONT 8, "MS Sans Serif"
+BEGIN
+ PUSHBUTTON "&Close",12,7,49,50,14
+ PUSHBUTTON "&Submit report",14,81,49,68,14,WS_DISABLED
+ PUSHBUTTON "&Emergency save",13,155,49,68,14
+ PUSHBUTTON "",15,243,49,55,14
+ EDITTEXT 11,7,70,291,118,ES_MULTILINE | ES_READONLY | WS_VSCROLL |
+ WS_HSCROLL | NOT WS_TABSTOP
+ LTEXT "",10,36,7,262,34
+ ICON 100,IDC_STATIC,9,9,20,20
+END
+
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 0,5,0,0
+ PRODUCTVERSION 0,5,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "Comments", "This program is licensed under the GNU General Public License.\0"
+ VALUE "CompanyName", "OpenTTD Development Team\0"
+ VALUE "FileDescription", "OpenTTD\0"
+ VALUE "FileVersion", "Development Version\0"
+ VALUE "InternalName", "openttd\0"
+ VALUE "LegalCopyright", "Copyright © OpenTTD Developers 2002-2006. All Rights Reserved.\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "openttd.exe\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "OpenTTD\0"
+ VALUE "ProductVersion", "0.0.0.0\0"
+ VALUE "SpecialBuild", "-\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // Neutral (Default) resources
+/////////////////////////////////////////////////////////////////////////////
diff --git a/src/pathfind.c b/src/pathfind.c
new file mode 100644
index 000000000..81ccc699c
--- /dev/null
+++ b/src/pathfind.c
@@ -0,0 +1,968 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "bridge_map.h"
+#include "station_map.h"
+#include "depot.h"
+#include "functions.h"
+#include "map.h"
+#include "tile.h"
+#include "pathfind.h"
+#include "rail.h"
+#include "debug.h"
+#include "tunnel_map.h"
+#include "variables.h"
+#include "depot.h"
+
+// remember which tiles we have already visited so we don't visit them again.
+static bool TPFSetTileBit(TrackPathFinder *tpf, TileIndex tile, int dir)
+{
+ uint hash, val, offs;
+ TrackPathFinderLink *link, *new_link;
+ uint bits = 1 << dir;
+
+ if (tpf->disable_tile_hash)
+ return true;
+
+ hash = PATHFIND_HASH_TILE(tile);
+
+ val = tpf->hash_head[hash];
+
+ if (val == 0) {
+ /* unused hash entry, set the appropriate bit in it and return true
+ * to indicate that a bit was set. */
+ tpf->hash_head[hash] = bits;
+ tpf->hash_tile[hash] = tile;
+ return true;
+ } else if (!(val & 0x8000)) {
+ /* single tile */
+
+ if (tile == tpf->hash_tile[hash]) {
+ /* found another bit for the same tile,
+ * check if this bit is already set, if so, return false */
+ if (val & bits)
+ return false;
+
+ /* otherwise set the bit and return true to indicate that the bit
+ * was set */
+ tpf->hash_head[hash] = val | bits;
+ return true;
+ } else {
+ /* two tiles with the same hash, need to make a link */
+
+ /* allocate a link. if out of links, handle this by returning
+ * that a tile was already visisted. */
+ if (tpf->num_links_left == 0) {
+ return false;
+ }
+ tpf->num_links_left--;
+ link = tpf->new_link++;
+
+ /* move the data that was previously in the hash_??? variables
+ * to the link struct, and let the hash variables point to the link */
+ link->tile = tpf->hash_tile[hash];
+ tpf->hash_tile[hash] = PATHFIND_GET_LINK_OFFS(tpf, link);
+
+ link->flags = tpf->hash_head[hash];
+ tpf->hash_head[hash] = 0xFFFF; /* multi link */
+
+ link->next = 0xFFFF;
+ }
+ } else {
+ /* a linked list of many tiles,
+ * find the one corresponding to the tile, if it exists.
+ * otherwise make a new link */
+
+ offs = tpf->hash_tile[hash];
+ do {
+ link = PATHFIND_GET_LINK_PTR(tpf, offs);
+ if (tile == link->tile) {
+ /* found the tile in the link list,
+ * check if the bit was alrady set, if so return false to indicate that the
+ * bit was already set */
+ if (link->flags & bits)
+ return false;
+ link->flags |= bits;
+ return true;
+ }
+ } while ((offs=link->next) != 0xFFFF);
+ }
+
+ /* get here if we need to add a new link to link,
+ * first, allocate a new link, in the same way as before */
+ if (tpf->num_links_left == 0) {
+ return false;
+ }
+ tpf->num_links_left--;
+ new_link = tpf->new_link++;
+
+ /* then fill the link with the new info, and establish a ptr from the old
+ * link to the new one */
+ new_link->tile = tile;
+ new_link->flags = bits;
+ new_link->next = 0xFFFF;
+
+ link->next = PATHFIND_GET_LINK_OFFS(tpf, new_link);
+ return true;
+}
+
+static const byte _bits_mask[4] = {
+ 0x19,
+ 0x16,
+ 0x25,
+ 0x2A,
+};
+
+static const byte _tpf_new_direction[14] = {
+ 0, 1, 0, 1, 2, 1,
+ 0, 0,
+ 2, 3, 3, 2, 3, 0,
+};
+
+static const byte _tpf_prev_direction[14] = {
+ 0, 1, 1, 0, 1, 2,
+ 0, 0,
+ 2, 3, 2, 3, 0, 3,
+};
+
+
+static const byte _otherdir_mask[4] = {
+ 0x10,
+ 0,
+ 0x5,
+ 0x2A,
+};
+
+static void TPFMode2(TrackPathFinder* tpf, TileIndex tile, DiagDirection direction)
+{
+ uint bits;
+ int i;
+ RememberData rd;
+
+ assert(tpf->tracktype == TRANSPORT_WATER);
+
+ // This addition will sometimes overflow by a single tile.
+ // The use of TILE_MASK here makes sure that we still point at a valid
+ // tile, and then this tile will be in the sentinel row/col, so GetTileTrackStatus will fail.
+ tile = TILE_MASK(tile + TileOffsByDiagDir(direction));
+
+ if (++tpf->rd.cur_length > 50)
+ return;
+
+ bits = GetTileTrackStatus(tile, tpf->tracktype);
+ bits = (byte)((bits | (bits >> 8)) & _bits_mask[direction]);
+ if (bits == 0)
+ return;
+
+ assert(TileX(tile) != MapMaxX() && TileY(tile) != MapMaxY());
+
+ if ( (bits & (bits - 1)) == 0 ) {
+ /* only one direction */
+ i = 0;
+ while (!(bits&1))
+ i++, bits>>=1;
+
+ rd = tpf->rd;
+ goto continue_here;
+ }
+ /* several directions */
+ i=0;
+ do {
+ if (!(bits & 1)) continue;
+ rd = tpf->rd;
+
+ // Change direction 4 times only
+ if ((byte)i != tpf->rd.pft_var6) {
+ if (++tpf->rd.depth > 4) {
+ tpf->rd = rd;
+ return;
+ }
+ tpf->rd.pft_var6 = (byte)i;
+ }
+
+continue_here:;
+ tpf->the_dir = i + (HASBIT(_otherdir_mask[direction], i) ? 8 : 0);
+
+ if (!tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length, NULL)) {
+ TPFMode2(tpf, tile, _tpf_new_direction[tpf->the_dir]);
+ }
+
+ tpf->rd = rd;
+ } while (++i, bits>>=1);
+
+}
+
+
+/* Returns the end tile and the length of a tunnel. The length does not
+ * include the starting tile (entry), it does include the end tile (exit).
+ */
+FindLengthOfTunnelResult FindLengthOfTunnel(TileIndex tile, DiagDirection dir)
+{
+ TileIndexDiff delta = TileOffsByDiagDir(dir);
+ uint z = GetTileZ(tile);
+ FindLengthOfTunnelResult flotr;
+
+ flotr.length = 0;
+
+ dir = ReverseDiagDir(dir);
+ do {
+ flotr.length++;
+ tile += delta;
+ } while(
+ !IsTunnelTile(tile) ||
+ GetTunnelDirection(tile) != dir ||
+ GetTileZ(tile) != z
+ );
+
+ flotr.tile = tile;
+ return flotr;
+}
+
+static const uint16 _tpfmode1_and[4] = { 0x1009, 0x16, 0x520, 0x2A00 };
+
+static uint SkipToEndOfTunnel(TrackPathFinder* tpf, TileIndex tile, DiagDirection direction)
+{
+ FindLengthOfTunnelResult flotr;
+ TPFSetTileBit(tpf, tile, 14);
+ flotr = FindLengthOfTunnel(tile, direction);
+ tpf->rd.cur_length += flotr.length;
+ TPFSetTileBit(tpf, flotr.tile, 14);
+ return flotr.tile;
+}
+
+const byte _ffb_64[128] = {
+ 0, 0, 1, 0, 2, 0, 1, 0,
+ 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0,
+ 3, 0, 1, 0, 2, 0, 1, 0,
+ 5, 0, 1, 0, 2, 0, 1, 0,
+ 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0,
+ 3, 0, 1, 0, 2, 0, 1, 0,
+
+ 0, 0, 0, 2, 0, 4, 4, 6,
+ 0, 8, 8, 10, 8, 12, 12, 14,
+ 0, 16, 16, 18, 16, 20, 20, 22,
+16, 24, 24, 26, 24, 28, 28, 30,
+ 0, 32, 32, 34, 32, 36, 36, 38,
+32, 40, 40, 42, 40, 44, 44, 46,
+32, 48, 48, 50, 48, 52, 52, 54,
+48, 56, 56, 58, 56, 60, 60, 62,
+};
+
+static void TPFMode1(TrackPathFinder* tpf, TileIndex tile, DiagDirection direction)
+{
+ uint bits;
+ int i;
+ RememberData rd;
+ TileIndex tile_org = tile;
+
+ if (IsTileType(tile, MP_TUNNELBRIDGE)) {
+ if (IsTunnel(tile)) {
+ if (GetTunnelDirection(tile) != direction ||
+ GetTunnelTransportType(tile) != tpf->tracktype) {
+ return;
+ }
+ tile = SkipToEndOfTunnel(tpf, tile, direction);
+ } else {
+ TileIndex tile_end;
+ if (GetBridgeRampDirection(tile) != direction ||
+ GetBridgeTransportType(tile) != tpf->tracktype) {
+ return;
+ }
+ //fprintf(stderr, "%s: Planning over bridge\n", __func__);
+ // TODO doesn't work - WHAT doesn't work?
+ TPFSetTileBit(tpf, tile, 14);
+ tile_end = GetOtherBridgeEnd(tile);
+ tpf->rd.cur_length += DistanceManhattan(tile, tile_end);
+ tile = tile_end;
+ TPFSetTileBit(tpf, tile, 14);
+ }
+ }
+ tile += TileOffsByDiagDir(direction);
+
+ /* Check in case of rail if the owner is the same */
+ if (tpf->tracktype == TRANSPORT_RAIL) {
+ // don't enter train depot from the back
+ if (IsTileDepotType(tile, TRANSPORT_RAIL) && GetRailDepotDirection(tile) == direction) return;
+
+ if (IsTileType(tile_org, MP_RAILWAY) || IsTileType(tile_org, MP_STATION) || IsTileType(tile_org, MP_TUNNELBRIDGE))
+ if (IsTileType(tile, MP_RAILWAY) || IsTileType(tile, MP_STATION) || IsTileType(tile, MP_TUNNELBRIDGE))
+ if (GetTileOwner(tile_org) != GetTileOwner(tile)) return;
+ }
+
+ // check if the new tile can be entered from that direction
+ if (tpf->tracktype == TRANSPORT_ROAD) {
+ // road stops and depots now have a track (r4419)
+ // don't enter road stop from the back
+ if (IsRoadStopTile(tile) && ReverseDiagDir(GetRoadStopDir(tile)) != direction) return;
+ // don't enter road depot from the back
+ if (IsTileDepotType(tile, TRANSPORT_ROAD) && ReverseDiagDir(GetRoadDepotDirection(tile)) != direction) return;
+ }
+
+ /* Check if the new tile is a tunnel or bridge head and that the direction
+ * and transport type match */
+ if (IsTileType(tile, MP_TUNNELBRIDGE)) {
+ if (IsTunnel(tile)) {
+ if (GetTunnelDirection(tile) != direction ||
+ GetTunnelTransportType(tile) != tpf->tracktype) {
+ return;
+ }
+ } else if (IsBridge(tile)) {
+ if (GetBridgeRampDirection(tile) != direction ||
+ GetBridgeTransportType(tile) != tpf->tracktype) {
+ return;
+ }
+ }
+ }
+
+ tpf->rd.cur_length++;
+
+ bits = GetTileTrackStatus(tile, tpf->tracktype);
+
+ if ((byte)bits != tpf->var2) {
+ bits &= _tpfmode1_and[direction];
+ bits = bits | (bits>>8);
+ }
+ bits &= 0xBF;
+
+ if (bits != 0) {
+ if (!tpf->disable_tile_hash || (tpf->rd.cur_length <= 64 && (KILL_FIRST_BIT(bits) == 0 || ++tpf->rd.depth <= 7))) {
+ do {
+ i = FIND_FIRST_BIT(bits);
+ bits = KILL_FIRST_BIT(bits);
+
+ tpf->the_dir = (_otherdir_mask[direction] & (byte)(1 << i)) ? (i+8) : i;
+ rd = tpf->rd;
+
+ if (TPFSetTileBit(tpf, tile, tpf->the_dir) &&
+ !tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length, &tpf->rd.pft_var6) ) {
+ TPFMode1(tpf, tile, _tpf_new_direction[tpf->the_dir]);
+ }
+ tpf->rd = rd;
+ } while (bits != 0);
+ }
+ }
+
+ /* the next is only used when signals are checked.
+ * seems to go in 2 directions simultaneously */
+
+ /* if i can get rid of this, tail end recursion can be used to minimize
+ * stack space dramatically. */
+
+ /* If we are doing signal setting, we must reverse at evere tile, so we
+ * iterate all the tracks in a signal block, even when a normal train would
+ * not reach it (for example, when two lines merge */
+ if (tpf->hasbit_13)
+ return;
+
+ direction = ReverseDiagDir(direction);
+ tile += TileOffsByDiagDir(direction);
+
+ bits = GetTileTrackStatus(tile, tpf->tracktype);
+ bits |= (bits >> 8);
+
+ if ( (byte)bits != tpf->var2) {
+ bits &= _bits_mask[direction];
+ }
+
+ bits &= 0xBF;
+ if (bits == 0)
+ return;
+
+ do {
+ i = FIND_FIRST_BIT(bits);
+ bits = KILL_FIRST_BIT(bits);
+
+ tpf->the_dir = (_otherdir_mask[direction] & (byte)(1 << i)) ? (i+8) : i;
+ rd = tpf->rd;
+ if (TPFSetTileBit(tpf, tile, tpf->the_dir) &&
+ !tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length, &tpf->rd.pft_var6) ) {
+ TPFMode1(tpf, tile, _tpf_new_direction[tpf->the_dir]);
+ }
+ tpf->rd = rd;
+ } while (bits != 0);
+}
+
+void FollowTrack(TileIndex tile, uint16 flags, DiagDirection direction, TPFEnumProc *enum_proc, TPFAfterProc *after_proc, void *data)
+{
+ TrackPathFinder tpf;
+
+ assert(direction < 4);
+
+ /* initialize path finder variables */
+ tpf.userdata = data;
+ tpf.enum_proc = enum_proc;
+ tpf.new_link = tpf.links;
+ tpf.num_links_left = lengthof(tpf.links);
+
+ tpf.rd.cur_length = 0;
+ tpf.rd.depth = 0;
+ tpf.rd.pft_var6 = 0;
+
+ tpf.var2 = HASBIT(flags, 15) ? 0x43 : 0xFF; /* 0x8000 */
+
+ tpf.disable_tile_hash = HASBIT(flags, 12); /* 0x1000 */
+ tpf.hasbit_13 = HASBIT(flags, 13); /* 0x2000 */
+
+
+ tpf.tracktype = (byte)flags;
+
+ if (HASBIT(flags, 11)) {
+ tpf.rd.pft_var6 = 0xFF;
+ tpf.enum_proc(tile, data, 0, 0, 0);
+ TPFMode2(&tpf, tile, direction);
+ } else {
+ /* clear the hash_heads */
+ memset(tpf.hash_head, 0, sizeof(tpf.hash_head));
+ TPFMode1(&tpf, tile, direction);
+ }
+
+ if (after_proc != NULL)
+ after_proc(&tpf);
+}
+
+typedef struct {
+ TileIndex tile;
+ uint16 cur_length; // This is the current length to this tile.
+ uint16 priority; // This is the current length + estimated length to the goal.
+ byte track;
+ byte depth;
+ byte state;
+ byte first_track;
+} StackedItem;
+
+static const byte _new_track[6][4] = {
+{0, 0xff, 8, 0xff,},
+{0xff, 1, 0xff, 9,},
+{0xff, 2, 10, 0xff,},
+{3, 0xff, 0xff, 11,},
+{12, 4, 0xff, 0xff,},
+{0xff, 0xff, 5, 13,},
+};
+
+typedef struct HashLink {
+ TileIndex tile;
+ uint16 typelength;
+ uint16 next;
+} HashLink;
+
+typedef struct {
+ NTPEnumProc *enum_proc;
+ void *userdata;
+ TileIndex dest;
+
+ TransportType tracktype;
+ RailTypeMask railtypes;
+ uint maxlength;
+
+ HashLink *new_link;
+ uint num_links_left;
+
+ uint nstack;
+ StackedItem stack[256]; // priority queue of stacked items
+
+ uint16 hash_head[0x400]; // hash heads. 0 means unused. 0xFFFC = length, 0x3 = dir
+ TileIndex hash_tile[0x400]; // tiles. or links.
+
+ HashLink links[0x400]; // hash links
+
+} NewTrackPathFinder;
+#define NTP_GET_LINK_OFFS(tpf, link) ((byte*)(link) - (byte*)tpf->links)
+#define NTP_GET_LINK_PTR(tpf, link_offs) (HashLink*)((byte*)tpf->links + (link_offs))
+
+#define ARR(i) tpf->stack[(i)-1]
+
+// called after a new element was added in the queue at the last index.
+// move it down to the proper position
+static inline void HeapifyUp(NewTrackPathFinder *tpf)
+{
+ StackedItem si;
+ int i = ++tpf->nstack;
+
+ while (i != 1 && ARR(i).priority < ARR(i>>1).priority) {
+ // the child element is larger than the parent item.
+ // swap the child item and the parent item.
+ si = ARR(i); ARR(i) = ARR(i>>1); ARR(i>>1) = si;
+ i>>=1;
+ }
+}
+
+// called after the element 0 was eaten. fill it with a new element
+static inline void HeapifyDown(NewTrackPathFinder *tpf)
+{
+ StackedItem si;
+ int i = 1, j;
+ int n;
+
+ assert(tpf->nstack > 0);
+ n = --tpf->nstack;
+
+ if (n == 0) return; // heap is empty so nothing to do?
+
+ // copy the last item to index 0. we use it as base for heapify.
+ ARR(1) = ARR(n+1);
+
+ while ((j=i*2) <= n) {
+ // figure out which is smaller of the children.
+ if (j != n && ARR(j).priority > ARR(j+1).priority)
+ j++; // right item is smaller
+
+ assert(i <= n && j <= n);
+ if (ARR(i).priority <= ARR(j).priority)
+ break; // base elem smaller than smallest, done!
+
+ // swap parent with the child
+ si = ARR(i); ARR(i) = ARR(j); ARR(j) = si;
+ i = j;
+ }
+}
+
+// mark a tile as visited and store the length of the path.
+// if we already had a better path to this tile, return false.
+// otherwise return true.
+static bool NtpVisit(NewTrackPathFinder* tpf, TileIndex tile, DiagDirection dir, uint length)
+{
+ uint hash,head;
+ HashLink *link, *new_link;
+
+ assert(length < 16384-1);
+
+ hash = PATHFIND_HASH_TILE(tile);
+
+ // never visited before?
+ if ((head=tpf->hash_head[hash]) == 0) {
+ tpf->hash_tile[hash] = tile;
+ tpf->hash_head[hash] = dir | (length << 2);
+ return true;
+ }
+
+ if (head != 0xffff) {
+ if (tile == tpf->hash_tile[hash] && (head & 0x3) == dir) {
+
+ // longer length
+ if (length >= (head >> 2)) return false;
+
+ tpf->hash_head[hash] = dir | (length << 2);
+ return true;
+ }
+ // two tiles with the same hash, need to make a link
+ // allocate a link. if out of links, handle this by returning
+ // that a tile was already visisted.
+ if (tpf->num_links_left == 0) {
+ DEBUG(ntp, 1, "No links left");
+ return false;
+ }
+
+ tpf->num_links_left--;
+ link = tpf->new_link++;
+
+ /* move the data that was previously in the hash_??? variables
+ * to the link struct, and let the hash variables point to the link */
+ link->tile = tpf->hash_tile[hash];
+ tpf->hash_tile[hash] = NTP_GET_LINK_OFFS(tpf, link);
+
+ link->typelength = tpf->hash_head[hash];
+ tpf->hash_head[hash] = 0xFFFF; /* multi link */
+ link->next = 0xFFFF;
+ } else {
+ // a linked list of many tiles,
+ // find the one corresponding to the tile, if it exists.
+ // otherwise make a new link
+
+ uint offs = tpf->hash_tile[hash];
+ do {
+ link = NTP_GET_LINK_PTR(tpf, offs);
+ if (tile == link->tile && (link->typelength & 0x3U) == dir) {
+ if (length >= (uint)(link->typelength >> 2)) return false;
+ link->typelength = dir | (length << 2);
+ return true;
+ }
+ } while ((offs = link->next) != 0xFFFF);
+ }
+
+ /* get here if we need to add a new link to link,
+ * first, allocate a new link, in the same way as before */
+ if (tpf->num_links_left == 0) {
+ DEBUG(ntp, 1, "No links left");
+ return false;
+ }
+ tpf->num_links_left--;
+ new_link = tpf->new_link++;
+
+ /* then fill the link with the new info, and establish a ptr from the old
+ * link to the new one */
+ new_link->tile = tile;
+ new_link->typelength = dir | (length << 2);
+ new_link->next = 0xFFFF;
+
+ link->next = NTP_GET_LINK_OFFS(tpf, new_link);
+ return true;
+}
+
+/**
+ * Checks if the shortest path to the given tile/dir so far is still the given
+ * length.
+ * @return true if the length is still the same
+ * @pre The given tile/dir combination should be present in the hash, by a
+ * previous call to NtpVisit().
+ */
+static bool NtpCheck(NewTrackPathFinder *tpf, TileIndex tile, uint dir, uint length)
+{
+ uint hash,head,offs;
+ HashLink *link;
+
+ hash = PATHFIND_HASH_TILE(tile);
+ head=tpf->hash_head[hash];
+ assert(head);
+
+ if (head != 0xffff) {
+ assert( tpf->hash_tile[hash] == tile && (head & 3) == dir);
+ assert( (head >> 2) <= length);
+ return length == (head >> 2);
+ }
+
+ // else it's a linked list of many tiles
+ offs = tpf->hash_tile[hash];
+ for (;;) {
+ link = NTP_GET_LINK_PTR(tpf, offs);
+ if (tile == link->tile && (link->typelength & 0x3U) == dir) {
+ assert((uint)(link->typelength >> 2) <= length);
+ return length == (uint)(link->typelength >> 2);
+ }
+ offs = link->next;
+ assert(offs != 0xffff);
+ }
+}
+
+
+static const uint16 _is_upwards_slope[15] = {
+ 0, // no tileh
+ (1 << TRACKDIR_X_SW) | (1 << TRACKDIR_Y_NW), // 1
+ (1 << TRACKDIR_X_SW) | (1 << TRACKDIR_Y_SE), // 2
+ (1 << TRACKDIR_X_SW), // 3
+ (1 << TRACKDIR_X_NE) | (1 << TRACKDIR_Y_SE), // 4
+ 0, // 5
+ (1 << TRACKDIR_Y_SE), // 6
+ 0, // 7
+ (1 << TRACKDIR_X_NE) | (1 << TRACKDIR_Y_NW), // 8,
+ (1 << TRACKDIR_Y_NW), // 9
+ 0, //10
+ 0, //11,
+ (1 << TRACKDIR_X_NE), //12
+ 0, //13
+ 0, //14
+};
+
+static uint DistanceMoo(TileIndex t0, TileIndex t1)
+{
+ const uint dx = abs(TileX(t0) - TileX(t1));
+ const uint dy = abs(TileY(t0) - TileY(t1));
+
+ const uint straightTracks = 2 * min(dx, dy); /* The number of straight (not full length) tracks */
+ /* OPTIMISATION:
+ * Original: diagTracks = max(dx, dy) - min(dx,dy);
+ * Proof:
+ * (dx-dy) - straightTracks == (min + max) - straightTracks = min + // max - 2 * min = max - min */
+ const uint diagTracks = dx + dy - straightTracks; /* The number of diagonal (full tile length) tracks. */
+
+ return diagTracks*DIAG_FACTOR + straightTracks*STR_FACTOR;
+}
+
+// These has to be small cause the max length of a track
+// is currently limited to 16384
+
+static const byte _length_of_track[16] = {
+ DIAG_FACTOR, DIAG_FACTOR, STR_FACTOR, STR_FACTOR, STR_FACTOR, STR_FACTOR, 0, 0,
+ DIAG_FACTOR, DIAG_FACTOR, STR_FACTOR, STR_FACTOR, STR_FACTOR, STR_FACTOR, 0, 0
+};
+
+// new more optimized pathfinder for trains...
+// Tile is the tile the train is at.
+// direction is the tile the train is moving towards.
+
+static void NTPEnum(NewTrackPathFinder* tpf, TileIndex tile, DiagDirection direction)
+{
+ TrackBits bits, allbits;
+ uint track;
+ TileIndex tile_org;
+ StackedItem si;
+ int estimation;
+
+
+
+ // Need to have a special case for the start.
+ // We shouldn't call the callback for the current tile.
+ si.cur_length = 1; // Need to start at 1 cause 0 is a reserved value.
+ si.depth = 0;
+ si.state = 0;
+ si.first_track = 0xFF;
+ goto start_at;
+
+ for (;;) {
+ // Get the next item to search from from the priority queue
+ do {
+ if (tpf->nstack == 0)
+ return; // nothing left? then we're done!
+ si = tpf->stack[0];
+ tile = si.tile;
+
+ HeapifyDown(tpf);
+ // Make sure we havn't already visited this tile.
+ } while (!NtpCheck(tpf, tile, _tpf_prev_direction[si.track], si.cur_length));
+
+ // Add the length of this track.
+ si.cur_length += _length_of_track[si.track];
+
+callback_and_continue:
+ if (tpf->enum_proc(tile, tpf->userdata, si.first_track, si.cur_length))
+ return;
+
+ assert(si.track <= 13);
+ direction = _tpf_new_direction[si.track];
+
+start_at:
+ // If the tile is the entry tile of a tunnel, and we're not going out of the tunnel,
+ // need to find the exit of the tunnel.
+ if (IsTileType(tile, MP_TUNNELBRIDGE)) {
+ if (IsTunnel(tile)) {
+ if (GetTunnelDirection(tile) != ReverseDiagDir(direction)) {
+ FindLengthOfTunnelResult flotr;
+
+ /* We are not just driving out of the tunnel */
+ if (GetTunnelDirection(tile) != direction ||
+ GetTunnelTransportType(tile) != tpf->tracktype) {
+ // We are not driving into the tunnel, or it is an invalid tunnel
+ continue;
+ }
+ if (!HASBIT(tpf->railtypes, GetRailType(tile))) {
+ bits = 0;
+ break;
+ }
+ flotr = FindLengthOfTunnel(tile, direction);
+ si.cur_length += flotr.length * DIAG_FACTOR;
+ tile = flotr.tile;
+ // tile now points to the exit tile of the tunnel
+ }
+ } else {
+ TileIndex tile_end;
+ if (GetBridgeRampDirection(tile) != ReverseDiagDir(direction)) {
+ // We are not just leaving the bridge
+ if (GetBridgeRampDirection(tile) != direction ||
+ GetBridgeTransportType(tile) != tpf->tracktype) {
+ // Not entering the bridge or not compatible
+ continue;
+ }
+ }
+ tile_end = GetOtherBridgeEnd(tile);
+ si.cur_length += DistanceManhattan(tile, tile_end) * DIAG_FACTOR;
+ tile = tile_end;
+ }
+ }
+
+ // This is a special loop used to go through
+ // a rail net and find the first intersection
+ tile_org = tile;
+ for (;;) {
+ assert(direction <= 3);
+ tile += TileOffsByDiagDir(direction);
+
+ // too long search length? bail out.
+ if (si.cur_length >= tpf->maxlength) {
+ DEBUG(ntp, 1, "Cur_length too big");
+ bits = 0;
+ break;
+ }
+
+ // Not a regular rail tile?
+ // Then we can't use the code below, but revert to more general code.
+ if (!IsTileType(tile, MP_RAILWAY) || !IsPlainRailTile(tile)) {
+ // We found a tile which is not a normal railway tile.
+ // Determine which tracks that exist on this tile.
+ bits = GetTileTrackStatus(tile, TRANSPORT_RAIL) & _tpfmode1_and[direction];
+ bits = (bits | (bits >> 8)) & 0x3F;
+
+ // Check that the tile contains exactly one track
+ if (bits == 0 || KILL_FIRST_BIT(bits) != 0) break;
+
+ if (!HASBIT(tpf->railtypes, IsTileType(tile, MP_STREET) ? GetRailTypeCrossing(tile) : GetRailType(tile))) {
+ bits = 0;
+ break;
+ }
+
+ ///////////////////
+ // If we reach here, the tile has exactly one track.
+ // tile - index to a tile that is not rail tile, but still straight (with optional signals)
+ // bits - bitmask of which track that exist on the tile (exactly one bit is set)
+ // direction - which direction are we moving in?
+ ///////////////////
+ si.track = _new_track[FIND_FIRST_BIT(bits)][direction];
+ si.cur_length += _length_of_track[si.track];
+ goto callback_and_continue;
+ }
+
+ /* Regular rail tile, determine which tracks exist. */
+ allbits = GetTrackBits(tile);
+ /* Which tracks are reachable? */
+ bits = allbits & DiagdirReachesTracks(direction);
+
+ /* The tile has no reachable tracks => End of rail segment
+ * or Intersection => End of rail segment. We check this agains all the
+ * bits, not just reachable ones, to prevent infinite loops. */
+ if (bits == 0 || TracksOverlap(allbits)) break;
+
+ if (!HASBIT(tpf->railtypes, GetRailType(tile))) {
+ bits = 0;
+ break;
+ }
+
+ /* If we reach here, the tile has exactly one track, and this
+ track is reachable => Rail segment continues */
+
+ track = _new_track[FIND_FIRST_BIT(bits)][direction];
+ assert(track != 0xff);
+
+ si.cur_length += _length_of_track[track];
+
+ // Check if this rail is an upwards slope. If it is, then add a penalty.
+ // Small optimization here.. if (track&7)>1 then it can't be a slope so we avoid calling GetTileSlope
+ if ((track & 7) <= 1 && (_is_upwards_slope[GetTileSlope(tile, NULL)] & (1 << track)) ) {
+ // upwards slope. add some penalty.
+ si.cur_length += 4*DIAG_FACTOR;
+ }
+
+ // railway tile with signals..?
+ if (HasSignals(tile)) {
+ if (!HasSignalOnTrackdir(tile, track)) {
+ // if one way signal not pointing towards us, stop going in this direction => End of rail segment.
+ if (HasSignalOnTrackdir(tile, ReverseTrackdir(track))) {
+ bits = 0;
+ break;
+ }
+ } else if (GetSignalStateByTrackdir(tile, track) == SIGNAL_STATE_GREEN) {
+ // green signal in our direction. either one way or two way.
+ si.state |= 3;
+ } else {
+ // reached a red signal.
+ if (HasSignalOnTrackdir(tile, ReverseTrackdir(track))) {
+ // two way red signal. unless we passed another green signal on the way,
+ // stop going in this direction => End of rail segment.
+ // this is to prevent us from going into a full platform.
+ if (!(si.state&1)) {
+ bits = 0;
+ break;
+ }
+ }
+ if (!(si.state & 2)) {
+ // Is this the first signal we see? And it's red... add penalty
+ si.cur_length += 10*DIAG_FACTOR;
+ si.state += 2; // remember that we added penalty.
+ // Because we added a penalty, we can't just continue as usual.
+ // Need to get out and let A* do it's job with
+ // possibly finding an even shorter path.
+ break;
+ }
+ }
+
+ if (tpf->enum_proc(tile, tpf->userdata, si.first_track, si.cur_length))
+ return; /* Don't process this tile any further */
+ }
+
+ // continue with the next track
+ direction = _tpf_new_direction[track];
+
+ // safety check if we're running around chasing our tail... (infinite loop)
+ if (tile == tile_org) {
+ bits = 0;
+ break;
+ }
+ }
+
+ // There are no tracks to choose between.
+ // Stop searching in this direction
+ if (bits == 0)
+ continue;
+
+ ////////////////
+ // We got multiple tracks to choose between (intersection).
+ // Branch the search space into several branches.
+ ////////////////
+
+ // Check if we've already visited this intersection.
+ // If we've already visited it with a better length, then
+ // there's no point in visiting it again.
+ if (!NtpVisit(tpf, tile, direction, si.cur_length))
+ continue;
+
+ // Push all possible alternatives that we can reach from here
+ // onto the priority heap.
+ // 'bits' contains the tracks that we can choose between.
+
+ // First compute the estimated distance to the target.
+ // This is used to implement A*
+ estimation = 0;
+ if (tpf->dest != 0)
+ estimation = DistanceMoo(tile, tpf->dest);
+
+ si.depth++;
+ if (si.depth == 0)
+ continue; /* We overflowed our depth. No more searching in this direction. */
+ si.tile = tile;
+ do {
+ si.track = _new_track[FIND_FIRST_BIT(bits)][direction];
+ assert(si.track != 0xFF);
+ si.priority = si.cur_length + estimation;
+
+ // out of stack items, bail out?
+ if (tpf->nstack >= lengthof(tpf->stack)) {
+ DEBUG(ntp, 1, "Out of stack");
+ break;
+ }
+
+ tpf->stack[tpf->nstack] = si;
+ HeapifyUp(tpf);
+ } while ((bits = KILL_FIRST_BIT(bits)) != 0);
+
+ // If this is the first intersection, we need to fill the first_track member.
+ // so the code outside knows which path is better.
+ // also randomize the order in which we search through them.
+ if (si.depth == 1) {
+ assert(tpf->nstack == 1 || tpf->nstack == 2 || tpf->nstack == 3);
+ if (tpf->nstack != 1) {
+ uint32 r = Random();
+ if (r&1) swap_byte(&tpf->stack[0].track, &tpf->stack[1].track);
+ if (tpf->nstack != 2) {
+ byte t = tpf->stack[2].track;
+ if (r&2) swap_byte(&tpf->stack[0].track, &t);
+ if (r&4) swap_byte(&tpf->stack[1].track, &t);
+ tpf->stack[2].first_track = tpf->stack[2].track = t;
+ }
+ tpf->stack[0].first_track = tpf->stack[0].track;
+ tpf->stack[1].first_track = tpf->stack[1].track;
+ }
+ }
+
+ // Continue with the next from the queue...
+ }
+}
+
+
+// new pathfinder for trains. better and faster.
+void NewTrainPathfind(TileIndex tile, TileIndex dest, RailTypeMask railtypes, DiagDirection direction, NTPEnumProc* enum_proc, void* data)
+{
+ NewTrackPathFinder tpf;
+
+ tpf.dest = dest;
+ tpf.userdata = data;
+ tpf.enum_proc = enum_proc;
+ tpf.tracktype = TRANSPORT_RAIL;
+ tpf.railtypes = railtypes;
+ tpf.maxlength = min(_patches.pf_maxlength * 3, 10000);
+ tpf.nstack = 0;
+ tpf.new_link = tpf.links;
+ tpf.num_links_left = lengthof(tpf.links);
+ memset(tpf.hash_head, 0, sizeof(tpf.hash_head));
+
+ NTPEnum(&tpf, tile, direction);
+}
diff --git a/src/pathfind.h b/src/pathfind.h
new file mode 100644
index 000000000..432d7ea88
--- /dev/null
+++ b/src/pathfind.h
@@ -0,0 +1,77 @@
+/* $Id$ */
+
+#ifndef PATHFIND_H
+#define PATHFIND_H
+
+#include "direction.h"
+
+enum {
+ STR_FACTOR = 2,
+ DIAG_FACTOR = 3
+};
+
+//#define PF_BENCH // perform simple benchmarks on the train pathfinder (not
+//supported on all archs)
+
+typedef struct TrackPathFinder TrackPathFinder;
+typedef bool TPFEnumProc(TileIndex tile, void *data, int track, uint length, byte *state);
+typedef void TPFAfterProc(TrackPathFinder *tpf);
+
+typedef bool NTPEnumProc(TileIndex tile, void *data, int track, uint length);
+
+#define PATHFIND_GET_LINK_OFFS(tpf, link) ((byte*)(link) - (byte*)tpf->links)
+#define PATHFIND_GET_LINK_PTR(tpf, link_offs) (TrackPathFinderLink*)((byte*)tpf->links + (link_offs))
+
+/* y7 y6 y5 y4 y3 y2 y1 y0 x7 x6 x5 x4 x3 x2 x1 x0
+ * y7 y6 y5 y4 y3 y2 y1 y0 x4 x3 x2 x1 x0 0 0 0
+ * 0 0 y7 y6 y5 y4 y3 y2 y1 y0 x4 x3 x2 x1 x0 0
+ * 0 0 0 0 y5 y4 y3 y2 y1 y0 x4 x3 x2 x1 x0 0
+ */
+#define PATHFIND_HASH_TILE(tile) (TileX(tile) & 0x1F) + ((TileY(tile) & 0x1F) << 5)
+
+typedef struct TrackPathFinderLink {
+ TileIndex tile;
+ uint16 flags;
+ uint16 next;
+} TrackPathFinderLink;
+
+typedef struct RememberData {
+ uint16 cur_length;
+ byte depth;
+ byte pft_var6;
+} RememberData;
+
+struct TrackPathFinder {
+ int num_links_left;
+ TrackPathFinderLink *new_link;
+
+ TPFEnumProc *enum_proc;
+
+ void *userdata;
+
+ RememberData rd;
+
+ int the_dir;
+
+ byte tracktype;
+ byte var2;
+ bool disable_tile_hash;
+ bool hasbit_13;
+
+ uint16 hash_head[0x400];
+ TileIndex hash_tile[0x400]; /* stores the link index when multi link. */
+
+ TrackPathFinderLink links[0x400]; /* hopefully, this is enough. */
+};
+
+void FollowTrack(TileIndex tile, uint16 flags, DiagDirection direction, TPFEnumProc* enum_proc, TPFAfterProc* after_proc, void* data);
+
+typedef struct {
+ TileIndex tile;
+ int length;
+} FindLengthOfTunnelResult;
+FindLengthOfTunnelResult FindLengthOfTunnel(TileIndex tile, DiagDirection direction);
+
+void NewTrainPathfind(TileIndex tile, TileIndex dest, RailTypeMask railtypes, DiagDirection direction, NTPEnumProc* enum_proc, void* data);
+
+#endif /* PATHFIND_H */
diff --git a/src/player.h b/src/player.h
new file mode 100644
index 000000000..df959c6e0
--- /dev/null
+++ b/src/player.h
@@ -0,0 +1,354 @@
+/* $Id$ */
+
+#ifndef PLAYER_H
+#define PLAYER_H
+
+#include "oldpool.h"
+#include "aystar.h"
+#include "rail.h"
+#include "engine.h"
+#include "livery.h"
+
+typedef struct PlayerEconomyEntry {
+ int32 income;
+ int32 expenses;
+ int32 delivered_cargo;
+ int32 performance_history; // player score (scale 0-1000)
+ int64 company_value;
+} PlayerEconomyEntry;
+
+typedef struct AiBuildRec {
+ TileIndex spec_tile;
+ TileIndex use_tile;
+ byte rand_rng;
+ byte cur_building_rule;
+ byte unk6;
+ byte unk7;
+ byte buildcmd_a;
+ byte buildcmd_b;
+ byte direction;
+ CargoID cargo;
+} AiBuildRec;
+
+typedef struct PlayerAI {
+ byte state;
+ byte tick; // Used to determine how often to move
+ uint32 state_counter; // Can hold tile index!
+ uint16 timeout_counter;
+
+ byte state_mode;
+ byte banned_tile_count;
+ byte railtype_to_use;
+
+ CargoID cargo_type;
+ byte num_wagons;
+ byte build_kind;
+ byte num_build_rec;
+ byte num_loco_to_build;
+ byte num_want_fullload;
+
+ byte route_type_mask;
+
+ TileIndex start_tile_a;
+ TileIndex cur_tile_a;
+ byte cur_dir_a;
+ byte start_dir_a;
+
+ TileIndex start_tile_b;
+ TileIndex cur_tile_b;
+ byte cur_dir_b;
+ byte start_dir_b;
+
+ Vehicle *cur_veh; /* only used by some states */
+
+ AiBuildRec src, dst, mid1, mid2;
+
+ VehicleID wagon_list[9];
+ byte order_list_blocks[20];
+
+ TileIndex banned_tiles[16];
+ byte banned_val[16];
+} PlayerAI;
+
+typedef struct Ai_PathFinderInfo {
+ TileIndex start_tile_tl; // tl = top-left
+ TileIndex start_tile_br; // br = bottom-right
+ TileIndex end_tile_tl; // tl = top-left
+ TileIndex end_tile_br; // br = bottom-right
+ byte start_direction; // 0 to 3 or AI_PATHFINDER_NO_DIRECTION
+ byte end_direction; // 0 to 3 or AI_PATHFINDER_NO_DIRECTION
+
+ TileIndex route[500];
+ byte route_extra[500]; // Some extra information about the route like bridge/tunnel
+ int route_length;
+ int position; // Current position in the build-path, needed to build the path
+
+ bool rail_or_road; // true = rail, false = road
+} Ai_PathFinderInfo;
+
+// The amount of memory reserved for the AI-special-vehicles
+#define AI_MAX_SPECIAL_VEHICLES 100
+
+typedef struct Ai_SpecialVehicle {
+ VehicleID veh_id;
+ uint32 flag;
+} Ai_SpecialVehicle;
+
+typedef struct PlayerAiNew {
+ uint8 state;
+ uint tick;
+ uint idle;
+
+ int temp; // A value used in more than one function, but it just temporary
+ // The use is pretty simple: with this we can 'think' about stuff
+ // in more than one tick, and more than one AI. A static will not
+ // do, because they are not saved. This way, the AI is almost human ;)
+ int counter; // For the same reason as temp, we have counter. It can count how
+ // long we are trying something, and just abort if it takes too long
+
+ // Pathfinder stuff
+ Ai_PathFinderInfo path_info;
+ AyStar *pathfinder;
+
+ // Route stuff
+
+ CargoID cargo;
+ byte tbt; // train/bus/truck 0/1/2 AI_TRAIN/AI_BUS/AI_TRUCK
+ int new_cost;
+
+ byte action;
+
+ int last_id; // here is stored the last id of the searched city/industry
+ Date last_vehiclecheck_date; // Used in CheckVehicle
+ Ai_SpecialVehicle special_vehicles[AI_MAX_SPECIAL_VEHICLES]; // Some vehicles have some special flags
+
+ TileIndex from_tile;
+ TileIndex to_tile;
+
+ byte from_direction;
+ byte to_direction;
+
+ bool from_deliver; // True if this is the station that GIVES cargo
+ bool to_deliver;
+
+ TileIndex depot_tile;
+ byte depot_direction;
+
+ byte amount_veh; // How many vehicles we are going to build in this route
+ byte cur_veh; // How many vehicles did we bought?
+ VehicleID veh_id; // Used when bought a vehicle
+ VehicleID veh_main_id; // The ID of the first vehicle, for shared copy
+
+ int from_ic; // ic = industry/city. This is the ID of them
+ byte from_type; // AI_NO_TYPE/AI_CITY/AI_INDUSTRY
+ int to_ic;
+ byte to_type;
+
+} PlayerAiNew;
+
+
+
+typedef struct Player {
+ uint32 name_2;
+ uint16 name_1;
+
+ uint16 president_name_1;
+ uint32 president_name_2;
+
+ uint32 face;
+
+ int32 player_money;
+ int32 current_loan;
+ int64 money64; // internal 64-bit version of the money. the 32-bit field will be clamped to plus minus 2 billion
+
+ byte player_color;
+ Livery livery[LS_END];
+ byte player_money_fraction;
+ byte avail_railtypes;
+ byte block_preview;
+ PlayerID index;
+
+ uint16 cargo_types; /* which cargo types were transported the last year */
+
+ TileIndex location_of_house;
+ TileIndex last_build_coordinate;
+
+ PlayerID share_owners[4];
+
+ Year inaugurated_year;
+ byte num_valid_stat_ent;
+
+ byte quarters_of_bankrupcy;
+ byte bankrupt_asked; // which players were asked about buying it?
+ int16 bankrupt_timeout;
+ int32 bankrupt_value;
+
+ bool is_active;
+ bool is_ai;
+ PlayerAI ai;
+ PlayerAiNew ainew;
+
+ int64 yearly_expenses[3][13];
+ PlayerEconomyEntry cur_economy;
+ PlayerEconomyEntry old_economy[24];
+ EngineRenewList engine_renew_list; // Defined later
+ bool engine_renew;
+ bool renew_keep_length;
+ int16 engine_renew_months;
+ uint32 engine_renew_money;
+ uint16 num_engines[TOTAL_NUM_ENGINES]; // caches the number of engines of each type the player owns (no need to save this)
+} Player;
+
+uint16 GetDrawStringPlayerColor(PlayerID player);
+
+void ChangeOwnershipOfPlayerItems(PlayerID old_player, PlayerID new_player);
+void GetNameOfOwner(Owner owner, TileIndex tile);
+int64 CalculateCompanyValue(const Player* p);
+void InvalidatePlayerWindows(const Player* p);
+void UpdatePlayerMoney32(Player *p);
+void SetLocalPlayer(PlayerID new_player);
+#define FOR_ALL_PLAYERS(p) for (p = _players; p != endof(_players); p++)
+
+VARDEF PlayerID _local_player;
+VARDEF PlayerID _current_player;
+
+/* Player identifiers All players below MAX_PLAYERS are playable
+ * players, above, they are special, computer controlled players */
+enum Players {
+ PLAYER_INACTIVE_CLIENT = 253,
+ PLAYER_NEW_COMPANY = 254, ///< Command 'player' in Multiplayer to create a new company
+ PLAYER_SPECTATOR = 255, ///< Spectator in Multiplayer or the player in the scenario editor
+ MAX_PLAYERS = 8,
+};
+
+VARDEF Player _players[MAX_PLAYERS];
+// NOSAVE: can be determined from player structs
+VARDEF byte _player_colors[MAX_PLAYERS];
+
+static inline byte ActivePlayerCount(void)
+{
+ const Player *p;
+ byte count = 0;
+
+ FOR_ALL_PLAYERS(p) {
+ if (p->is_active) count++;
+ }
+
+ return count;
+}
+
+static inline Player* GetPlayer(PlayerID i)
+{
+ assert(i < lengthof(_players));
+ return &_players[i];
+}
+
+static inline bool IsLocalPlayer(void)
+{
+ return _local_player == _current_player;
+}
+
+static inline bool IsValidPlayer(PlayerID pi)
+{
+ return pi < MAX_PLAYERS;
+}
+
+byte GetPlayerRailtypes(PlayerID p);
+
+/** Finds out if a Player has a certain railtype available */
+static inline bool HasRailtypeAvail(const Player *p, RailType Railtype)
+{
+ return HASBIT(p->avail_railtypes, Railtype);
+}
+
+static inline bool IsHumanPlayer(PlayerID pi)
+{
+ return !GetPlayer(pi)->is_ai;
+}
+
+static inline bool IsInteractivePlayer(PlayerID pi)
+{
+ return pi == _local_player;
+}
+
+/* Validate functions for rail building */
+static inline bool ValParamRailtype(uint32 rail) { return HASBIT(GetPlayer(_current_player)->avail_railtypes, rail);}
+
+/** Returns the "best" railtype a player can build.
+ * As the AI doesn't know what the BEST one is, we have our own priority list
+ * here. When adding new railtypes, modify this function
+ * @param p the player "in action"
+ * @return The "best" railtype a player has available
+ */
+static inline RailType GetBestRailtype(const Player* p)
+{
+ if (HasRailtypeAvail(p, RAILTYPE_MAGLEV)) return RAILTYPE_MAGLEV;
+ if (HasRailtypeAvail(p, RAILTYPE_MONO)) return RAILTYPE_MONO;
+ if (HasRailtypeAvail(p, RAILTYPE_ELECTRIC)) return RAILTYPE_ELECTRIC;
+ return RAILTYPE_RAIL;
+}
+
+typedef struct HighScore {
+ char company[100];
+ StringID title; // NO_SAVE, has troubles with changing string-numbers.
+ uint16 score; // do NOT change type, will break hs.dat
+} HighScore;
+
+VARDEF HighScore _highscore_table[5][5]; // 4 difficulty-settings (+ network); top 5
+void SaveToHighScore(void);
+void LoadFromHighScore(void);
+int8 SaveHighScoreValue(const Player *p);
+int8 SaveHighScoreValueNetwork(void);
+
+/* Engine Replacement Functions */
+
+/**
+ * Remove all engine replacement settings for the given player.
+ * @param p Player.
+ */
+static inline void RemoveAllEngineReplacementForPlayer(Player *p) { RemoveAllEngineReplacement(&p->engine_renew_list); }
+
+/**
+ * Retrieve the engine replacement for the given player and original engine type.
+ * @param p Player.
+ * @param engine Engine type.
+ * @return The engine type to replace with, or INVALID_ENGINE if no
+ * replacement is in the list.
+ */
+static inline EngineID EngineReplacementForPlayer(const Player *p, EngineID engine) { return EngineReplacement(p->engine_renew_list, engine); }
+
+/**
+ * Check if a player has a replacement set up for the given engine.
+ * @param p Player.
+ * @param engine Engine type to be replaced.
+ * @return true if a replacement was set up, false otherwise.
+ */
+static inline bool EngineHasReplacementForPlayer(const Player *p, EngineID engine) { return EngineReplacementForPlayer(p, engine) != INVALID_ENGINE; }
+
+/**
+ * Add an engine replacement for the player.
+ * @param p Player.
+ * @param old_engine The original engine type.
+ * @param new_engine The replacement engine type.
+ * @param flags The calling command flags.
+ * @return 0 on success, CMD_ERROR on failure.
+ */
+static inline int32 AddEngineReplacementForPlayer(Player *p, EngineID old_engine, EngineID new_engine, uint32 flags) { return AddEngineReplacement(&p->engine_renew_list, old_engine, new_engine, flags); }
+
+/**
+ * Remove an engine replacement for the player.
+ * @param p Player.
+ * @param engine The original engine type.
+ * @param flags The calling command flags.
+ * @return 0 on success, CMD_ERROR on failure.
+ */
+static inline int32 RemoveEngineReplacementForPlayer(Player *p, EngineID engine, uint32 flags) {return RemoveEngineReplacement(&p->engine_renew_list, engine, flags); }
+
+/**
+ * Reset the livery schemes to the player's primary colour.
+ * This is used on loading games without livery information and on new player start up.
+ * @param p Player to reset.
+ */
+void ResetPlayerLivery(Player *p);
+
+#endif /* PLAYER_H */
diff --git a/src/player_gui.c b/src/player_gui.c
new file mode 100644
index 000000000..c4612f5dc
--- /dev/null
+++ b/src/player_gui.c
@@ -0,0 +1,1131 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "table/sprites.h"
+#include "table/strings.h"
+#include "functions.h"
+#include "window.h"
+#include "gui.h"
+#include "viewport.h"
+#include "gfx.h"
+#include "player.h"
+#include "command.h"
+#include "vehicle.h"
+#include "economy.h"
+#include "network/network.h"
+#include "variables.h"
+#include "train.h"
+#include "date.h"
+#include "newgrf.h"
+#include "network/network_data.h"
+#include "network/network_client.h"
+
+static void DoShowPlayerFinances(PlayerID player, bool show_small, bool show_stickied);
+
+static void DrawPlayerEconomyStats(const Player *p, byte mode)
+{
+ int x,y,i,j,year;
+ const int64 (*tbl)[13];
+ int64 sum, cost;
+ StringID str;
+
+ if (!(mode & 1)) { // normal sized economics window (mode&1) is minimized status
+ /* draw categories */
+ DrawStringCenterUnderline(61, 15, STR_700F_EXPENDITURE_INCOME, 0);
+ for (i = 0; i != 13; i++)
+ DrawString(2, 27 + i*10, STR_7011_CONSTRUCTION + i, 0);
+ DrawStringRightAligned(111, 27 + 10*13 + 2, STR_7020_TOTAL, 0);
+
+ /* draw the price columns */
+ year = _cur_year - 2;
+ j = 3;
+ x = 215;
+ tbl = p->yearly_expenses + 2;
+ do {
+ if (year >= p->inaugurated_year) {
+ SetDParam(0, year);
+ DrawStringRightAlignedUnderline(x, 15, STR_7010, 0);
+ sum = 0;
+ for (i = 0; i != 13; i++) {
+ /* draw one row in the price column */
+ cost = (*tbl)[i];
+ if (cost != 0) {
+ sum += cost;
+
+ str = STR_701E;
+ if (cost < 0) { cost = -cost; str++; }
+ SetDParam64(0, cost);
+ DrawStringRightAligned(x, 27+i*10, str, 0);
+ }
+ }
+
+ str = STR_701E;
+ if (sum < 0) { sum = -sum; str++; }
+ SetDParam64(0, sum);
+ DrawStringRightAligned(x, 27 + 13*10 + 2, str, 0);
+
+ GfxFillRect(x - 75, 27 + 10*13, x, 27 + 10*13, 215);
+ x += 95;
+ }
+ year++;
+ tbl--;
+ } while (--j != 0);
+
+ y = 171;
+
+ // draw max loan aligned to loan below (y += 10)
+ SetDParam64(0, (uint64)_economy.max_loan);
+ DrawString(202, y+10, STR_MAX_LOAN, 0);
+ } else {
+ y = 15;
+ }
+
+ DrawString(2, y, STR_7026_BANK_BALANCE, 0);
+ SetDParam64(0, p->money64);
+ DrawStringRightAligned(182, y, STR_7028, 0);
+
+ y += 10;
+
+ DrawString(2, y, STR_7027_LOAN, 0);
+ SetDParam64(0, p->current_loan);
+ DrawStringRightAligned(182, y, STR_7028, 0);
+
+ y += 12;
+
+ GfxFillRect(182 - 75, y-2, 182, y-2, 215);
+
+ SetDParam64(0, p->money64 - p->current_loan);
+ DrawStringRightAligned(182, y, STR_7028, 0);
+}
+
+static const Widget _player_finances_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 379, 0, 13, STR_700E_FINANCES, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 380, 394, 0, 13, SPR_LARGE_SMALL_WINDOW, STR_7075_TOGGLE_LARGE_SMALL_WINDOW},
+{ WWT_STICKYBOX, RESIZE_NONE, 14, 395, 406, 0, 13, 0x0, STR_STICKY_BUTTON},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 406, 14, 169, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 406, 170, 203, 0x0, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 0, 202, 204, 215, STR_7029_BORROW, STR_7035_INCREASE_SIZE_OF_LOAN},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 203, 406, 204, 215, STR_702A_REPAY, STR_7036_REPAY_PART_OF_LOAN},
+{ WIDGETS_END},
+};
+
+static const Widget _other_player_finances_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 379, 0, 13, STR_700E_FINANCES, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 380, 394, 0, 13, SPR_LARGE_SMALL_WINDOW, STR_7075_TOGGLE_LARGE_SMALL_WINDOW},
+{ WWT_STICKYBOX, RESIZE_NONE, 14, 395, 406, 0, 13, 0x0, STR_STICKY_BUTTON},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 406, 14, 169, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 406, 170, 203, 0x0, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const Widget _other_player_finances_small_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 253, 0, 13, STR_700E_FINANCES, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 254, 267, 0, 13, SPR_LARGE_SMALL_WINDOW, STR_7075_TOGGLE_LARGE_SMALL_WINDOW},
+{ WWT_STICKYBOX, RESIZE_NONE, 14, 268, 279, 0, 13, 0x0, STR_STICKY_BUTTON},
+{ WWT_EMPTY, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 279, 14, 47, 0x0, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const Widget _player_finances_small_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 253, 0, 13, STR_700E_FINANCES, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_IMGBTN, RESIZE_NONE, 14, 254, 267, 0, 13, SPR_LARGE_SMALL_WINDOW, STR_7075_TOGGLE_LARGE_SMALL_WINDOW},
+{ WWT_STICKYBOX, RESIZE_NONE, 14, 268, 279, 0, 13, 0x0, STR_STICKY_BUTTON},
+{ WWT_EMPTY, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 279, 14, 47, STR_NULL, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 0, 139, 48, 59, STR_7029_BORROW, STR_7035_INCREASE_SIZE_OF_LOAN},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 140, 279, 48, 59, STR_702A_REPAY, STR_7036_REPAY_PART_OF_LOAN},
+{ WIDGETS_END},
+};
+
+
+static void PlayerFinancesWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ PlayerID player = w->window_number;
+ const Player *p = GetPlayer(player);
+
+ if (player == _local_player) {
+ /* borrow/repay buttons only exist for local player */
+ SetWindowWidgetDisabledState(w, 7, p->current_loan == 0);
+ }
+
+ SetDParam(0, p->name_1);
+ SetDParam(1, p->name_2);
+ SetDParam(2, GetPlayerNameString(player, 3));
+ SetDParam(4, 10000);
+ DrawWindowWidgets(w);
+
+ DrawPlayerEconomyStats(p, (byte)WP(w,def_d).data_1);
+ } break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 2: {/* toggle size */
+ byte mode = (byte)WP(w,def_d).data_1;
+ bool stickied = !!(w->flags4 & WF_STICKY);
+ PlayerID player = w->window_number;
+ DeleteWindow(w);
+ DoShowPlayerFinances(player, !HASBIT(mode, 0), stickied);
+ } break;
+
+ case 6: /* increase loan */
+ DoCommandP(0, 0, _ctrl_pressed, NULL, CMD_INCREASE_LOAN | CMD_MSG(STR_702C_CAN_T_BORROW_ANY_MORE_MONEY));
+ break;
+
+ case 7: /* repay loan */
+ DoCommandP(0, 0, _ctrl_pressed, NULL, CMD_DECREASE_LOAN | CMD_MSG(STR_702F_CAN_T_REPAY_LOAN));
+ break;
+ }
+ break;
+ }
+}
+
+static const WindowDesc _player_finances_desc = {
+ WDP_AUTO, WDP_AUTO, 407, 216,
+ WC_FINANCES,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON,
+ _player_finances_widgets,
+ PlayerFinancesWndProc
+};
+
+static const WindowDesc _player_finances_small_desc = {
+ WDP_AUTO, WDP_AUTO, 280, 60,
+ WC_FINANCES,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON,
+ _player_finances_small_widgets,
+ PlayerFinancesWndProc
+};
+
+static const WindowDesc _other_player_finances_desc = {
+ WDP_AUTO, WDP_AUTO, 407, 204,
+ WC_FINANCES,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON,
+ _other_player_finances_widgets,
+ PlayerFinancesWndProc
+};
+
+static const WindowDesc _other_player_finances_small_desc = {
+ WDP_AUTO, WDP_AUTO, 280, 48,
+ WC_FINANCES,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON,
+ _other_player_finances_small_widgets,
+ PlayerFinancesWndProc
+};
+
+static void DoShowPlayerFinances(PlayerID player, bool show_small, bool show_stickied)
+{
+ Window *w;
+ int mode;
+
+ static const WindowDesc * const desc_table[2 * 2] = {
+ &_player_finances_desc, &_player_finances_small_desc,
+ &_other_player_finances_desc, &_other_player_finances_small_desc,
+ };
+
+ if (!IsValidPlayer(player)) return;
+
+ mode = (player != _local_player) * 2 + show_small;
+ w = AllocateWindowDescFront(desc_table[mode], player);
+ if (w != NULL) {
+ w->caption_color = w->window_number;
+ WP(w,def_d).data_1 = mode;
+ if (show_stickied) w->flags4 |= WF_STICKY;
+ }
+}
+
+void ShowPlayerFinances(PlayerID player)
+{
+ DoShowPlayerFinances(player, false, false);
+}
+
+/* List of colours for the livery window */
+static const StringID _colour_dropdown[] = {
+ STR_00D1_DARK_BLUE,
+ STR_00D2_PALE_GREEN,
+ STR_00D3_PINK,
+ STR_00D4_YELLOW,
+ STR_00D5_RED,
+ STR_00D6_LIGHT_BLUE,
+ STR_00D7_GREEN,
+ STR_00D8_DARK_GREEN,
+ STR_00D9_BLUE,
+ STR_00DA_CREAM,
+ STR_00DB_MAUVE,
+ STR_00DC_PURPLE,
+ STR_00DD_ORANGE,
+ STR_00DE_BROWN,
+ STR_00DF_GREY,
+ STR_00E0_WHITE,
+ INVALID_STRING_ID
+};
+
+/* Association of liveries to livery classes */
+static const LiveryClass livery_class[LS_END] = {
+ LC_OTHER,
+ LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL,
+ LC_ROAD, LC_ROAD,
+ LC_SHIP, LC_SHIP,
+ LC_AIRCRAFT, LC_AIRCRAFT, LC_AIRCRAFT,
+};
+
+/* Number of liveries in each class, used to determine the height of the livery window */
+static const byte livery_height[] = {
+ 1,
+ 11,
+ 2,
+ 2,
+ 3,
+};
+
+typedef struct livery_d {
+ uint32 sel;
+ LiveryClass livery_class;
+} livery_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(livery_d));
+
+static void ShowColourDropDownMenu(Window *w, uint32 widget)
+{
+ uint32 used_colours = 0;
+ const Livery *livery;
+ LiveryScheme scheme;
+
+ /* Disallow other player colours for the primary colour */
+ if (HASBIT(WP(w, livery_d).sel, LS_DEFAULT) && widget == 10) {
+ const Player *p;
+ FOR_ALL_PLAYERS(p) {
+ if (p->is_active && p->index != _local_player) SETBIT(used_colours, p->player_color);
+ }
+ }
+
+ /* Get the first selected livery to use as the default dropdown item */
+ for (scheme = 0; scheme < LS_END; scheme++) {
+ if (HASBIT(WP(w, livery_d).sel, scheme)) break;
+ }
+ if (scheme == LS_END) scheme = LS_DEFAULT;
+ livery = &GetPlayer(w->window_number)->livery[scheme];
+
+ ShowDropDownMenu(w, _colour_dropdown, widget == 10 ? livery->colour1 : livery->colour2, widget, used_colours, 0);
+}
+
+static void SelectPlayerLiveryWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_CREATE:
+ LowerWindowWidget(w, WP(w, livery_d).livery_class + 2);
+ if (!_have_2cc) {
+ HideWindowWidget(w, 11);
+ HideWindowWidget(w, 12);
+ }
+ break;
+
+ case WE_PAINT: {
+ const Player *p = GetPlayer(w->window_number);
+ LiveryScheme scheme = LS_DEFAULT;
+ int y = 51;
+
+ /* Disable dropdown controls if no scheme is selected */
+ SetWindowWidgetDisabledState(w, 9, (WP(w, livery_d).sel == 0));
+ SetWindowWidgetDisabledState(w, 10, (WP(w, livery_d).sel == 0));
+ SetWindowWidgetDisabledState(w, 11, (WP(w, livery_d).sel == 0));
+ SetWindowWidgetDisabledState(w, 12, (WP(w, livery_d).sel == 0));
+
+ if (!(WP(w, livery_d).sel == 0)) {
+ for (scheme = 0; scheme < LS_END; scheme++) {
+ if (HASBIT(WP(w, livery_d).sel, scheme)) break;
+ }
+ if (scheme == LS_END) scheme = LS_DEFAULT;
+ }
+
+ SetDParam(0, STR_00D1_DARK_BLUE + p->livery[scheme].colour1);
+ SetDParam(1, STR_00D1_DARK_BLUE + p->livery[scheme].colour2);
+
+ DrawWindowWidgets(w);
+
+ for (scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
+ if (livery_class[scheme] == WP(w, livery_d).livery_class) {
+ bool sel = HASBIT(WP(w, livery_d).sel, scheme) != 0;
+
+ if (scheme != LS_DEFAULT) {
+ DrawSprite(p->livery[scheme].in_use ? SPR_BOX_CHECKED : SPR_BOX_EMPTY, 2, y);
+ }
+
+ DrawString(15, y, STR_LIVERY_DEFAULT + scheme, sel ? 0xC : 0x10);
+
+ DrawSprite(SPR_SQUARE | GENERAL_SPRITE_COLOR(p->livery[scheme].colour1) | PALETTE_MODIFIER_COLOR, 152, y);
+ DrawString(165, y, STR_00D1_DARK_BLUE + p->livery[scheme].colour1, sel ? 0xC : 2);
+
+ if (_have_2cc) {
+ DrawSprite(SPR_SQUARE | GENERAL_SPRITE_COLOR(p->livery[scheme].colour2) | PALETTE_MODIFIER_COLOR, 277, y);
+ DrawString(290, y, STR_00D1_DARK_BLUE + p->livery[scheme].colour2, sel ? 0xC : 2);
+ }
+
+ y += 14;
+ }
+ }
+ break;
+ }
+
+ case WE_CLICK: {
+ switch (e->we.click.widget) {
+ /* Livery Class buttons */
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6: {
+ LiveryScheme scheme;
+
+ RaiseWindowWidget(w, WP(w, livery_d).livery_class + 2);
+ WP(w, livery_d).livery_class = e->we.click.widget - 2;
+ WP(w, livery_d).sel = 0;
+ LowerWindowWidget(w, WP(w, livery_d).livery_class + 2);
+
+ /* Select the first item in the list */
+ for (scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
+ if (livery_class[scheme] == WP(w, livery_d).livery_class) {
+ WP(w, livery_d).sel = 1 << scheme;
+ break;
+ }
+ }
+ w->height = 49 + livery_height[WP(w, livery_d).livery_class] * 14;
+ w->widget[13].bottom = w->height - 1;
+ w->widget[13].data = livery_height[WP(w, livery_d).livery_class] << 8 | 1;
+ MarkWholeScreenDirty();
+ break;
+ }
+
+ case 9:
+ case 10: // First colour dropdown
+ ShowColourDropDownMenu(w, 10);
+ break;
+
+ case 11:
+ case 12: // Second colour dropdown
+ ShowColourDropDownMenu(w, 12);
+ break;
+
+ case 13: {
+ LiveryScheme scheme;
+ LiveryScheme j = (e->we.click.pt.y - 48) / 14;
+
+ for (scheme = 0; scheme <= j; scheme++) {
+ if (livery_class[scheme] != WP(w, livery_d).livery_class) j++;
+ if (scheme >= LS_END) return;
+ }
+ if (j >= LS_END) return;
+
+ /* If clicking on the left edge, toggle using the livery */
+ if (e->we.click.pt.x < 10) {
+ DoCommandP(0, j | (2 << 8), !GetPlayer(w->window_number)->livery[j].in_use, NULL, CMD_SET_PLAYER_COLOR);
+ }
+
+ if (_ctrl_pressed) {
+ TOGGLEBIT(WP(w, livery_d).sel, j);
+ } else {
+ WP(w, livery_d).sel = 1 << j;
+ }
+ SetWindowDirty(w);
+ break;
+ }
+ }
+ break;
+ }
+
+ case WE_DROPDOWN_SELECT: {
+ LiveryScheme scheme;
+
+ for (scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
+ if (HASBIT(WP(w, livery_d).sel, scheme)) {
+ DoCommandP(0, scheme | (e->we.dropdown.button == 10 ? 0 : 256), e->we.dropdown.index, NULL, CMD_SET_PLAYER_COLOR);
+ }
+ }
+ break;
+ }
+ }
+}
+
+static const Widget _select_player_livery_2cc_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW },
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 399, 0, 13, STR_7007_NEW_COLOR_SCHEME, STR_018C_WINDOW_TITLE_DRAG_THIS },
+{ WWT_IMGBTN, RESIZE_NONE, 14, 0, 21, 14, 35, SPR_IMG_COMPANY_GENERAL, STR_LIVERY_GENERAL_TIP },
+{ WWT_IMGBTN, RESIZE_NONE, 14, 22, 43, 14, 35, SPR_IMG_TRAINLIST, STR_LIVERY_TRAIN_TIP },
+{ WWT_IMGBTN, RESIZE_NONE, 14, 44, 65, 14, 35, SPR_IMG_TRUCKLIST, STR_LIVERY_ROADVEH_TIP },
+{ WWT_IMGBTN, RESIZE_NONE, 14, 66, 87, 14, 35, SPR_IMG_SHIPLIST, STR_LIVERY_SHIP_TIP },
+{ WWT_IMGBTN, RESIZE_NONE, 14, 88, 109, 14, 35, SPR_IMG_AIRPLANESLIST, STR_LIVERY_AIRCRAFT_TIP },
+{ WWT_PANEL, RESIZE_NONE, 14, 110, 399, 14, 35, 0x0, STR_NULL },
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 149, 36, 47, 0x0, STR_NULL },
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 150, 262, 36, 47, STR_02BD, STR_LIVERY_PRIMARY_TIP },
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 263, 274, 36, 47, STR_0225, STR_LIVERY_PRIMARY_TIP },
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 275, 387, 36, 47, STR_02E1, STR_LIVERY_SECONDARY_TIP },
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 388, 399, 36, 47, STR_0225, STR_LIVERY_SECONDARY_TIP },
+{ WWT_MATRIX, RESIZE_NONE, 14, 0, 399, 48, 48 + 1 * 14, (1 << 8) | 1, STR_LIVERY_PANEL_TIP },
+{ WIDGETS_END },
+};
+
+static const WindowDesc _select_player_livery_2cc_desc = {
+ WDP_AUTO, WDP_AUTO, 400, 49 + 1 * 14,
+ WC_PLAYER_COLOR, 0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _select_player_livery_2cc_widgets,
+ SelectPlayerLiveryWndProc
+};
+
+
+static const Widget _select_player_livery_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW },
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 274, 0, 13, STR_7007_NEW_COLOR_SCHEME, STR_018C_WINDOW_TITLE_DRAG_THIS },
+{ WWT_IMGBTN, RESIZE_NONE, 14, 0, 21, 14, 35, SPR_IMG_COMPANY_GENERAL, STR_LIVERY_GENERAL_TIP },
+{ WWT_IMGBTN, RESIZE_NONE, 14, 22, 43, 14, 35, SPR_IMG_TRAINLIST, STR_LIVERY_TRAIN_TIP },
+{ WWT_IMGBTN, RESIZE_NONE, 14, 44, 65, 14, 35, SPR_IMG_TRUCKLIST, STR_LIVERY_ROADVEH_TIP },
+{ WWT_IMGBTN, RESIZE_NONE, 14, 66, 87, 14, 35, SPR_IMG_SHIPLIST, STR_LIVERY_SHIP_TIP },
+{ WWT_IMGBTN, RESIZE_NONE, 14, 88, 109, 14, 35, SPR_IMG_AIRPLANESLIST, STR_LIVERY_AIRCRAFT_TIP },
+{ WWT_PANEL, RESIZE_NONE, 14, 110, 274, 14, 35, 0x0, STR_NULL },
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 149, 36, 47, 0x0, STR_NULL },
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 150, 262, 36, 47, STR_02BD, STR_LIVERY_PRIMARY_TIP },
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 263, 274, 36, 47, STR_0225, STR_LIVERY_PRIMARY_TIP },
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 275, 275, 36, 47, STR_02E1, STR_LIVERY_SECONDARY_TIP },
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 275, 275, 36, 47, STR_0225, STR_LIVERY_SECONDARY_TIP },
+{ WWT_MATRIX, RESIZE_NONE, 14, 0, 274, 48, 48 + 1 * 14, (1 << 8) | 1, STR_LIVERY_PANEL_TIP },
+{ WIDGETS_END },
+};
+
+static const WindowDesc _select_player_livery_desc = {
+ WDP_AUTO, WDP_AUTO, 275, 49 + 1 * 14,
+ WC_PLAYER_COLOR, 0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _select_player_livery_widgets,
+ SelectPlayerLiveryWndProc
+};
+
+static void SelectPlayerFaceWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ Player *p;
+ LowerWindowWidget(w, WP(w, facesel_d).gender + 5);
+ DrawWindowWidgets(w);
+ p = GetPlayer(w->window_number);
+ DrawPlayerFace(WP(w,facesel_d).face, p->player_color, 2, 16);
+ } break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 3: DeleteWindow(w); break;
+ case 4: /* ok click */
+ DoCommandP(0, 0, WP(w,facesel_d).face, NULL, CMD_SET_PLAYER_FACE);
+ DeleteWindow(w);
+ break;
+ case 5: /* male click */
+ case 6: /* female click */
+ RaiseWindowWidget(w, WP(w, facesel_d).gender + 5);
+ WP(w, facesel_d).gender = e->we.click.widget - 5;
+ LowerWindowWidget(w, WP(w, facesel_d).gender + 5);
+ SetWindowDirty(w);
+ break;
+ case 7:
+ WP(w,facesel_d).face = (WP(w,facesel_d).gender << 31) + GB(InteractiveRandom(), 0, 31);
+ SetWindowDirty(w);
+ break;
+ }
+ break;
+ }
+}
+
+static const Widget _select_player_face_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 189, 0, 13, STR_7043_FACE_SELECTION, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 189, 14, 136, 0x0, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 0, 94, 137, 148, STR_012E_CANCEL, STR_7047_CANCEL_NEW_FACE_SELECTION},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 95, 189, 137, 148, STR_012F_OK, STR_7048_ACCEPT_NEW_FACE_SELECTION},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 95, 187, 25, 36, STR_7044_MALE, STR_7049_SELECT_MALE_FACES},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 95, 187, 37, 48, STR_7045_FEMALE, STR_704A_SELECT_FEMALE_FACES},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 95, 187, 79, 90, STR_7046_NEW_FACE, STR_704B_GENERATE_RANDOM_NEW_FACE},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _select_player_face_desc = {
+ WDP_AUTO, WDP_AUTO, 190, 149,
+ WC_PLAYER_FACE,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _select_player_face_widgets,
+ SelectPlayerFaceWndProc
+};
+
+/* Names of the widgets. Keep them in the same order as in the widget array */
+enum PlayerCompanyWindowWidgets {
+ PCW_WIDGET_CLOSEBOX = 0,
+ PCW_WIDGET_CAPTION,
+ PCW_WIDGET_FACE,
+ PCW_WIDGET_NEW_FACE,
+ PCW_WIDGET_COLOR_SCHEME,
+ PCW_WIDGET_PRESIDENT_NAME,
+ PCW_WIDGET_COMPANY_NAME,
+ PCW_WIDGET_BUILD_VIEW_HQ,
+ PCW_WIDGET_RELOCATE_HQ,
+ PCW_WIDGET_BUY_SHARE,
+ PCW_WIDGET_SELL_SHARE,
+ PCW_WIDGET_COMPANY_PASSWORD,
+};
+
+static const Widget _player_company_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 359, 0, 13, STR_7001, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 359, 14, 157, 0x0, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 0, 89, 158, 169, STR_7004_NEW_FACE, STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 90, 179, 158, 169, STR_7005_COLOR_SCHEME, STR_7031_CHANGE_THE_COMPANY_VEHICLE},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 180, 269, 158, 169, STR_7009_PRESIDENT_NAME, STR_7032_CHANGE_THE_PRESIDENT_S},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 270, 359, 158, 169, STR_7008_COMPANY_NAME, STR_7033_CHANGE_THE_COMPANY_NAME},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 266, 355, 18, 29, STR_7072_VIEW_HQ, STR_7070_BUILD_COMPANY_HEADQUARTERS},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 266, 355, 32, 43, STR_RELOCATE_HQ, STR_RELOCATE_COMPANY_HEADQUARTERS},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 0, 179, 158, 169, STR_7077_BUY_25_SHARE_IN_COMPANY, STR_7079_BUY_25_SHARE_IN_THIS_COMPANY},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 180, 359, 158, 169, STR_7078_SELL_25_SHARE_IN_COMPANY, STR_707A_SELL_25_SHARE_IN_THIS_COMPANY},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 266, 355, 138, 149, STR_COMPANY_PASSWORD, STR_COMPANY_PASSWORD_TOOLTIP},
+{ WIDGETS_END},
+};
+
+static void DrawPlayerVehiclesAmount(PlayerID player)
+{
+ const int x = 110;
+ int y = 72;
+ const Vehicle *v;
+ uint train = 0;
+ uint road = 0;
+ uint air = 0;
+ uint ship = 0;
+
+ DrawString(x, y, STR_7039_VEHICLES, 0);
+
+ FOR_ALL_VEHICLES(v) {
+ if (v->owner == player) {
+ switch (v->type) {
+ case VEH_Train: if (IsFrontEngine(v)) train++; break;
+ case VEH_Road: road++; break;
+ case VEH_Aircraft: if (v->subtype <= 2) air++; break;
+ case VEH_Ship: ship++; break;
+ default: break;
+ }
+ }
+ }
+
+ if (train+road+air+ship == 0) {
+ DrawString(x+70, y, STR_7042_NONE, 0);
+ } else {
+ if (train != 0) {
+ SetDParam(0, train);
+ DrawString(x + 70, y, STR_TRAINS, 0);
+ y += 10;
+ }
+
+ if (road != 0) {
+ SetDParam(0, road);
+ DrawString(x + 70, y, STR_ROAD_VEHICLES, 0);
+ y += 10;
+ }
+
+ if (air != 0) {
+ SetDParam(0, air);
+ DrawString(x + 70, y, STR_AIRCRAFT, 0);
+ y += 10;
+ }
+
+ if (ship != 0) {
+ SetDParam(0, ship);
+ DrawString(x + 70, y, STR_SHIPS, 0);
+ }
+ }
+}
+
+int GetAmountOwnedBy(const Player *p, PlayerID owner)
+{
+ return (p->share_owners[0] == owner) +
+ (p->share_owners[1] == owner) +
+ (p->share_owners[2] == owner) +
+ (p->share_owners[3] == owner);
+}
+
+static void DrawCompanyOwnerText(const Player *p)
+{
+ const Player *p2;
+ int num = -1;
+
+ FOR_ALL_PLAYERS(p2) {
+ uint amt = GetAmountOwnedBy(p, p2->index);
+ if (amt != 0) {
+ num++;
+
+ SetDParam(num * 3 + 0, amt * 25);
+ SetDParam(num * 3 + 1, p2->name_1);
+ SetDParam(num * 3 + 2, p2->name_2);
+
+ if (num != 0) break;
+ }
+ }
+
+ if (num >= 0) DrawString(120, 124, STR_707D_OWNED_BY + num, 0);
+}
+
+static void PlayerCompanyWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ const Player *p = GetPlayer(w->window_number);
+ bool local = w->window_number == _local_player;
+
+ SetWindowWidgetHiddenState(w, PCW_WIDGET_NEW_FACE, !local);
+ SetWindowWidgetHiddenState(w, PCW_WIDGET_COLOR_SCHEME, !local);
+ SetWindowWidgetHiddenState(w, PCW_WIDGET_PRESIDENT_NAME, !local);
+ SetWindowWidgetHiddenState(w, PCW_WIDGET_COMPANY_NAME, !local);
+ w->widget[PCW_WIDGET_BUILD_VIEW_HQ].data = (local && p->location_of_house == 0) ? STR_706F_BUILD_HQ : STR_7072_VIEW_HQ;
+ if (local && p->location_of_house != 0) w->widget[PCW_WIDGET_BUILD_VIEW_HQ].type = WWT_PUSHTXTBTN; //HQ is already built.
+ SetWindowWidgetDisabledState(w, PCW_WIDGET_BUILD_VIEW_HQ, !local && p->location_of_house == 0);
+ SetWindowWidgetHiddenState(w, PCW_WIDGET_RELOCATE_HQ, !local || p->location_of_house == 0);
+ SetWindowWidgetHiddenState(w, PCW_WIDGET_BUY_SHARE, local);
+ SetWindowWidgetHiddenState(w, PCW_WIDGET_SELL_SHARE, local);
+ SetWindowWidgetHiddenState(w, PCW_WIDGET_COMPANY_PASSWORD, !local || !_networking);
+
+ if (!local) {
+ if (_patches.allow_shares) { // Shares are allowed
+ /* If all shares are owned by someone (none by nobody), disable buy button */
+ SetWindowWidgetDisabledState(w, PCW_WIDGET_BUY_SHARE, GetAmountOwnedBy(p, PLAYER_SPECTATOR) == 0 ||
+ /* Only 25% left to buy. If the player is human, disable buying it up.. TODO issues! */
+ (GetAmountOwnedBy(p, PLAYER_SPECTATOR) == 1 && !p->is_ai) ||
+ /* Spectators cannot do anything of course */
+ _local_player == PLAYER_SPECTATOR);
+
+ /* If the player doesn't own any shares, disable sell button */
+ SetWindowWidgetDisabledState(w, PCW_WIDGET_SELL_SHARE, (GetAmountOwnedBy(p, _local_player) == 0) ||
+ /* Spectators cannot do anything of course */
+ _local_player == PLAYER_SPECTATOR);
+ } else { // Shares are not allowed, disable buy/sell buttons
+ DisableWindowWidget(w, PCW_WIDGET_BUY_SHARE);
+ DisableWindowWidget(w, PCW_WIDGET_SELL_SHARE);
+ }
+ }
+
+ SetDParam(0, p->name_1);
+ SetDParam(1, p->name_2);
+ SetDParam(2, GetPlayerNameString((byte)w->window_number, 3));
+
+ DrawWindowWidgets(w);
+
+ SetDParam(0, p->inaugurated_year);
+ DrawString(110, 25, STR_7038_INAUGURATED, 0);
+
+ DrawPlayerVehiclesAmount(w->window_number);
+
+ DrawString(110,48, STR_7006_COLOR_SCHEME, 0);
+ // Draw company-colour bus
+ DrawSprite(PLAYER_SPRITE_COLOR(p->index) + SPRITE_PALETTE(SPR_VEH_BUS_SW_VIEW), 215, 49);
+
+ DrawPlayerFace(p->face, p->player_color, 2, 16);
+
+ SetDParam(0, p->president_name_1);
+ SetDParam(1, p->president_name_2);
+ DrawStringMultiCenter(48, 141, STR_7037_PRESIDENT, 94);
+
+ SetDParam64(0, CalculateCompanyValue(p));
+ DrawString(110, 114, STR_7076_COMPANY_VALUE, 0);
+
+ DrawCompanyOwnerText(p);
+
+ break;
+ }
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case PCW_WIDGET_NEW_FACE: {
+ Window *wf = AllocateWindowDescFront(&_select_player_face_desc, w->window_number);
+ if (wf != NULL) {
+ wf->caption_color = w->window_number;
+ WP(wf,facesel_d).face = GetPlayer(wf->window_number)->face;
+ WP(wf,facesel_d).gender = 0;
+ }
+ break;
+ }
+
+ case PCW_WIDGET_COLOR_SCHEME: {
+ Window *wf = AllocateWindowDescFront(_have_2cc ? &_select_player_livery_2cc_desc : &_select_player_livery_desc, w->window_number);
+ if (wf != NULL) {
+ wf->caption_color = wf->window_number;
+ WP(wf,livery_d).livery_class = LC_OTHER;
+ WP(wf,livery_d).sel = 1;
+ LowerWindowWidget(wf, 2);
+ }
+ break;
+ }
+
+ case PCW_WIDGET_PRESIDENT_NAME: {
+ const Player *p = GetPlayer(w->window_number);
+ WP(w, def_d).byte_1 = 0;
+ SetDParam(0, p->president_name_2);
+ ShowQueryString(p->president_name_1, STR_700B_PRESIDENT_S_NAME, 31, 94, w, CS_ALPHANUMERAL);
+ break;
+ }
+
+ case PCW_WIDGET_COMPANY_NAME: {
+ Player *p = GetPlayer(w->window_number);
+ WP(w,def_d).byte_1 = 1;
+ SetDParam(0, p->name_2);
+ ShowQueryString(p->name_1, STR_700A_COMPANY_NAME, 31, 150, w, CS_ALPHANUMERAL);
+ break;
+ }
+
+ case PCW_WIDGET_BUILD_VIEW_HQ: {
+ TileIndex tile = GetPlayer(w->window_number)->location_of_house;
+ if (tile == 0) {
+ if ((byte)w->window_number != _local_player)
+ return;
+ SetObjectToPlaceWnd(SPR_CURSOR_HQ, 1, w);
+ SetTileSelectSize(2, 2);
+ LowerWindowWidget(w, PCW_WIDGET_BUILD_VIEW_HQ);
+ InvalidateWidget(w, PCW_WIDGET_BUILD_VIEW_HQ);
+ } else {
+ ScrollMainWindowToTile(tile);
+ }
+ break;
+ }
+
+ case PCW_WIDGET_RELOCATE_HQ:
+ SetObjectToPlaceWnd(SPR_CURSOR_HQ, 1, w);
+ SetTileSelectSize(2, 2);
+ LowerWindowWidget(w, PCW_WIDGET_RELOCATE_HQ);
+ InvalidateWidget(w, PCW_WIDGET_RELOCATE_HQ);
+ break;
+
+ case PCW_WIDGET_BUY_SHARE:
+ DoCommandP(0, w->window_number, 0, NULL, CMD_BUY_SHARE_IN_COMPANY | CMD_MSG(STR_707B_CAN_T_BUY_25_SHARE_IN_THIS));
+ break;
+
+ case PCW_WIDGET_SELL_SHARE:
+ DoCommandP(0, w->window_number, 0, NULL, CMD_SELL_SHARE_IN_COMPANY | CMD_MSG(STR_707C_CAN_T_SELL_25_SHARE_IN));
+ break;
+
+ #ifdef ENABLE_NETWORK
+ case PCW_WIDGET_COMPANY_PASSWORD:
+ if (w->window_number == _local_player) {
+ WP(w,def_d).byte_1 = 2;
+ ShowQueryString(BindCString(_network_player_info[_local_player].password),
+ STR_SET_COMPANY_PASSWORD, sizeof(_network_player_info[_local_player].password), 250, w, CS_ALPHANUMERAL);
+ }
+ break;
+ #endif /* ENABLE_NETWORK */
+ }
+ break;
+
+ case WE_MOUSELOOP:
+ /* redraw the window every now and then */
+ if ((++w->vscroll.pos & 0x1F) == 0) SetWindowDirty(w);
+ break;
+
+ case WE_PLACE_OBJ:
+ if (DoCommandP(e->we.place.tile, 0, 0, NULL, CMD_BUILD_COMPANY_HQ | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS)))
+ ResetObjectToPlace();
+ w->widget[PCW_WIDGET_BUILD_VIEW_HQ].type = WWT_PUSHTXTBTN; // this button can now behave as a normal push button
+ RaiseWindowButtons(w);
+ break;
+
+ case WE_ABORT_PLACE_OBJ:
+ RaiseWindowButtons(w);
+ break;
+
+ case WE_DESTROY:
+ DeleteWindowById(WC_PLAYER_FACE, w->window_number);
+ break;
+
+ case WE_ON_EDIT_TEXT: {
+ char *b = e->we.edittext.str;
+
+ // empty string is allowed for password
+ if (*b == '\0' && WP(w,def_d).byte_1 != 2) return;
+
+ _cmd_text = b;
+ switch (WP(w,def_d).byte_1) {
+ case 0: /* Change president name */
+ DoCommandP(0, 0, 0, NULL, CMD_CHANGE_PRESIDENT_NAME | CMD_MSG(STR_700D_CAN_T_CHANGE_PRESIDENT));
+ break;
+ case 1: /* Change company name */
+ DoCommandP(0, 0, 0, NULL, CMD_CHANGE_COMPANY_NAME | CMD_MSG(STR_700C_CAN_T_CHANGE_COMPANY_NAME));
+ break;
+ #ifdef ENABLE_NETWORK
+ case 2: /* Change company password */
+ if (*b == '\0') *b = '*'; // empty password is a '*' because of console argument
+ NetworkChangeCompanyPassword(1, &b);
+ break;
+ #endif /* ENABLE_NETWORK */
+ }
+ break;
+ }
+ }
+}
+
+
+static const WindowDesc _player_company_desc = {
+ WDP_AUTO, WDP_AUTO, 360, 170,
+ WC_COMPANY, 0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _player_company_widgets,
+ PlayerCompanyWndProc
+};
+
+void ShowPlayerCompany(PlayerID player)
+{
+ Window *w;
+
+ if (!IsValidPlayer(player)) return;
+
+ w = AllocateWindowDescFront(&_player_company_desc, player);
+ if (w != NULL) w->caption_color = w->window_number;
+}
+
+
+
+static void BuyCompanyWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ Player *p = GetPlayer(w->window_number);
+ SetDParam(0, p->name_1);
+ SetDParam(1, p->name_2);
+ DrawWindowWidgets(w);
+
+ DrawPlayerFace(p->face, p->player_color, 2, 16);
+
+ SetDParam(0, p->name_1);
+ SetDParam(1, p->name_2);
+ SetDParam(2, p->bankrupt_value);
+ DrawStringMultiCenter(214, 65, STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT, 238);
+ break;
+ }
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 3:
+ DeleteWindow(w);
+ break;
+ case 4: {
+ DoCommandP(0, w->window_number, 0, NULL, CMD_BUY_COMPANY | CMD_MSG(STR_7060_CAN_T_BUY_COMPANY));
+ break;
+ }
+ }
+ break;
+ }
+}
+
+static const Widget _buy_company_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 5, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 5, 11, 333, 0, 13, STR_00B3_MESSAGE_FROM, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 5, 0, 333, 14, 136, 0x0, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 5, 148, 207, 117, 128, STR_00C9_NO, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 5, 218, 277, 117, 128, STR_00C8_YES, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _buy_company_desc = {
+ 153, 171, 334, 137,
+ WC_BUY_COMPANY,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _buy_company_widgets,
+ BuyCompanyWndProc
+};
+
+
+void ShowBuyCompanyDialog(uint player)
+{
+ AllocateWindowDescFront(&_buy_company_desc, player);
+}
+
+/********** HIGHSCORE and ENDGAME windows */
+
+/* Always draw a maximized window and within there the centered background */
+static void SetupHighScoreEndWindow(Window *w, uint *x, uint *y)
+{
+ uint i;
+ // resize window to "full-screen"
+ w->width = _screen.width;
+ w->height = _screen.height;
+ w->widget[0].right = w->width - 1;
+ w->widget[0].bottom = w->height - 1;
+
+ DrawWindowWidgets(w);
+
+ /* Center Highscore/Endscreen background */
+ *x = max(0, (_screen.width / 2) - (640 / 2));
+ *y = max(0, (_screen.height / 2) - (480 / 2));
+ for (i = 0; i < 10; i++) // the image is split into 10 50px high parts
+ DrawSprite(WP(w, highscore_d).background_img + i, *x, *y + (i * 50));
+}
+
+extern StringID EndGameGetPerformanceTitleFromValue(uint value);
+
+/* End game window shown at the end of the game */
+static void EndGameWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ const Player *p;
+ uint x, y;
+
+ SetupHighScoreEndWindow(w, &x, &y);
+
+ if (!IsValidPlayer(_local_player)) break;
+
+ p = GetPlayer(_local_player);
+ /* We need to get performance from last year because the image is shown
+ * at the start of the new year when these things have already been copied */
+ if (WP(w, highscore_d).background_img == SPR_TYCOON_IMG2_BEGIN) { // Tycoon of the century \o/
+ SetDParam(0, p->president_name_1);
+ SetDParam(1, p->president_name_2);
+ SetDParam(2, p->name_1);
+ SetDParam(3, p->name_2);
+ SetDParam(4, EndGameGetPerformanceTitleFromValue(p->old_economy[0].performance_history));
+ DrawStringMultiCenter(x + (640 / 2), y + 107, STR_021C_OF_ACHIEVES_STATUS, 640);
+ } else {
+ SetDParam(0, p->name_1);
+ SetDParam(1, p->name_2);
+ SetDParam(2, EndGameGetPerformanceTitleFromValue(p->old_economy[0].performance_history));
+ DrawStringMultiCenter(x + (640 / 2), y + 157, STR_021B_ACHIEVES_STATUS, 640);
+ }
+ } break;
+ case WE_CLICK: /* Close the window (and show the highscore window) */
+ DeleteWindow(w);
+ break;
+ case WE_DESTROY: /* Show the highscore window when this one is closed */
+ if (!_networking) DoCommandP(0, 0, 0, NULL, CMD_PAUSE); // unpause
+ ShowHighscoreTable(w->window_number, WP(w, highscore_d).rank);
+ break;
+ }
+}
+
+static void HighScoreWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ const HighScore *hs = _highscore_table[w->window_number];
+ uint x, y;
+ uint8 i;
+
+ SetupHighScoreEndWindow(w, &x, &y);
+
+ SetDParam(0, _patches.ending_year);
+ SetDParam(1, w->window_number + STR_6801_EASY);
+ DrawStringMultiCenter(x + (640 / 2), y + 62, !_networking ? STR_0211_TOP_COMPANIES_WHO_REACHED : STR_TOP_COMPANIES_NETWORK_GAME, 500);
+
+ /* Draw Highscore peepz */
+ for (i = 0; i < lengthof(_highscore_table[0]); i++) {
+ SetDParam(0, i + 1);
+ DrawString(x + 40, y + 140 + (i * 55), STR_0212, 0x10);
+
+ if (hs[i].company[0] != '\0') {
+ uint16 colour = (WP(w, highscore_d).rank == (int8)i) ? 0x3 : 0x10; // draw new highscore in red
+
+ DoDrawString(hs[i].company, x + 71, y + 140 + (i * 55), colour);
+ SetDParam(0, hs[i].title);
+ SetDParam(1, hs[i].score);
+ DrawString(x + 71, y + 160 + (i * 55), STR_HIGHSCORE_STATS, colour);
+ }
+ }
+ } break;
+
+ case WE_CLICK: /* Onclick to close window, and in destroy event handle the rest */
+ DeleteWindow(w);
+ break;
+
+ case WE_DESTROY: /* Get back all the hidden windows */
+ if (_game_mode != GM_MENU) ShowVitalWindows();
+
+ if (!_networking) DoCommandP(0, 0, 0, NULL, CMD_PAUSE); // unpause
+ break;
+ }
+ }
+
+static const Widget _highscore_widgets[] = {
+{ WWT_PANEL, RESIZE_NONE, 16, 0, 640, 0, 480, 0x0, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _highscore_desc = {
+ 0, 0, 641, 481,
+ WC_HIGHSCORE,0,
+ 0,
+ _highscore_widgets,
+ HighScoreWndProc
+};
+
+static const WindowDesc _endgame_desc = {
+ 0, 0, 641, 481,
+ WC_ENDSCREEN,0,
+ 0,
+ _highscore_widgets,
+ EndGameWndProc
+};
+
+/* Show the highscore table for a given difficulty. When called from
+ * endgame ranking is set to the top5 element that was newly added
+ * and is thus highlighted */
+void ShowHighscoreTable(int difficulty, int8 ranking)
+{
+ Window *w;
+
+ // pause game to show the chart
+ if (!_networking) DoCommandP(0, 1, 0, NULL, CMD_PAUSE);
+
+ /* Close all always on-top windows to get a clean screen */
+ if (_game_mode != GM_MENU) HideVitalWindows();
+
+ DeleteWindowByClass(WC_HIGHSCORE);
+ w = AllocateWindowDesc(&_highscore_desc);
+
+ if (w != NULL) {
+ MarkWholeScreenDirty();
+ w->window_number = difficulty; // show highscore chart for difficulty...
+ WP(w, highscore_d).background_img = SPR_HIGHSCORE_CHART_BEGIN; // which background to show
+ WP(w, highscore_d).rank = ranking;
+ }
+}
+
+/* Show the endgame victory screen in 2050. Update the new highscore
+ * if it was high enough */
+void ShowEndGameChart(void)
+{
+ Window *w;
+
+ /* Dedicated server doesn't need the highscore window */
+ if (_network_dedicated) return;
+ /* Pause in single-player to have a look at the highscore at your own leisure */
+ if (!_networking) DoCommandP(0, 1, 0, NULL, CMD_PAUSE);
+
+ HideVitalWindows();
+ DeleteWindowByClass(WC_ENDSCREEN);
+ w = AllocateWindowDesc(&_endgame_desc);
+
+ if (w != NULL) {
+ MarkWholeScreenDirty();
+
+ WP(w, highscore_d).background_img = SPR_TYCOON_IMG1_BEGIN;
+
+ if (_local_player != PLAYER_SPECTATOR) {
+ const Player *p = GetPlayer(_local_player);
+ if (p->old_economy[0].performance_history == SCORE_MAX)
+ WP(w, highscore_d).background_img = SPR_TYCOON_IMG2_BEGIN;
+ }
+
+ /* In a network game show the endscores of the custom difficulty 'network' which is the last one
+ * as well as generate a TOP5 of that game, and not an all-time top5. */
+ if (_networking) {
+ w->window_number = lengthof(_highscore_table) - 1;
+ WP(w, highscore_d).rank = SaveHighScoreValueNetwork();
+ } else {
+ // in single player _local player is always valid
+ const Player *p = GetPlayer(_local_player);
+ w->window_number = _opt.diff_level;
+ WP(w, highscore_d).rank = SaveHighScoreValue(p);
+ }
+ }
+}
diff --git a/src/players.c b/src/players.c
new file mode 100644
index 000000000..4c2d1ed37
--- /dev/null
+++ b/src/players.c
@@ -0,0 +1,1339 @@
+/* $Id$ */
+
+/** @file players.c
+ * @todo Cleanup the messy DrawPlayerFace function asap
+ */
+#include "stdafx.h"
+#include "openttd.h"
+#include "engine.h"
+#include "functions.h"
+#include "string.h"
+#include "strings.h"
+#include "table/strings.h"
+#include "table/sprites.h"
+#include "map.h"
+#include "player.h"
+#include "town.h"
+#include "vehicle.h"
+#include "station.h"
+#include "gfx.h"
+#include "news.h"
+#include "saveload.h"
+#include "command.h"
+#include "sound.h"
+#include "network/network.h"
+#include "variables.h"
+#include "engine.h"
+#include "ai/ai.h"
+#include "date.h"
+#include "window.h"
+
+/**
+ * Sets the local player and updates the patch settings that are set on a
+ * per-company (player) basis to reflect the core's state in the GUI.
+ * @param new_player the new player
+ * @pre IsValidPlayer(new_player) || new_player == PLAYER_SPECTATOR || new_player == OWNER_NONE
+ */
+void SetLocalPlayer(PlayerID new_player)
+{
+ /* Player could also be PLAYER_SPECTATOR or OWNER_NONE */
+ assert(IsValidPlayer(new_player) || new_player == PLAYER_SPECTATOR || new_player == OWNER_NONE);
+
+ _local_player = new_player;
+
+ /* Do not update the patches if we are in the intro GUI */
+ if (IsValidPlayer(new_player) && _game_mode != GM_MENU) {
+ const Player *p = GetPlayer(new_player);
+ _patches.autorenew = p->engine_renew;
+ _patches.autorenew_months = p->engine_renew_months;
+ _patches.autorenew_money = p->engine_renew_money;
+ InvalidateWindow(WC_GAME_OPTIONS, 0);
+ }
+}
+
+
+uint16 GetDrawStringPlayerColor(PlayerID player)
+{
+ /* Get the color for DrawString-subroutines which matches the color
+ * of the player */
+ if (!IsValidPlayer(player)) return _colour_gradient[COLOUR_WHITE][4] | IS_PALETTE_COLOR;
+ return (_colour_gradient[_player_colors[player]][4]) | IS_PALETTE_COLOR;
+}
+
+
+static const SpriteID cheeks_table[4] = {
+ 0x325, 0x326,
+ 0x390, 0x3B0,
+};
+
+static const SpriteID mouth_table[3] = {
+ 0x34C, 0x34D, 0x34F
+};
+
+void DrawPlayerFace(uint32 face, int color, int x, int y)
+{
+ byte flag = 0;
+
+ if ( (int32)face < 0)
+ flag |= 1;
+ if ((((((face >> 7) ^ face) >> 7) ^ face) & 0x8080000) == 0x8000000)
+ flag |= 2;
+
+ /* draw the gradient */
+ DrawSprite(GENERAL_SPRITE_COLOR(color) + SPRITE_PALETTE(SPR_GRADIENT), x, y);
+
+ /* draw the cheeks */
+ DrawSprite(cheeks_table[flag&3], x, y);
+
+ /* draw the chin */
+ /* FIXME: real code uses -2 in zoomlevel 1 */
+ {
+ uint val = GB(face, 4, 2);
+ if (!(flag & 2)) {
+ DrawSprite(0x327 + (flag&1?0:val), x, y);
+ } else {
+ DrawSprite((flag&1?0x3B1:0x391) + (val>>1), x, y);
+ }
+ }
+ /* draw the eyes */
+ {
+ uint val1 = GB(face, 6, 4);
+ uint val2 = GB(face, 20, 3);
+ uint32 high = 0x314 << PALETTE_SPRITE_START;
+
+ if (val2 >= 6) {
+ high = 0x30F << PALETTE_SPRITE_START;
+ if (val2 != 6)
+ high = 0x30D << PALETTE_SPRITE_START;
+ }
+
+ if (!(flag & 2)) {
+ if (!(flag & 1)) {
+ DrawSprite(high+((val1 * 12 >> 4) + SPRITE_PALETTE(0x32B)), x, y);
+ } else {
+ DrawSprite(high+(val1 + SPRITE_PALETTE(0x337)), x, y);
+ }
+ } else {
+ if (!(flag & 1)) {
+ DrawSprite(high+((val1 * 11 >> 4) + SPRITE_PALETTE(0x39A)), x, y);
+ } else {
+ DrawSprite(high+(val1 + SPRITE_PALETTE(0x3B8)), x, y);
+ }
+ }
+ }
+
+ /* draw the mouth */
+ {
+ uint val = GB(face, 10, 6);
+ uint val2;
+
+ if (!(flag&1)) {
+ val2 = ((val&0xF) * 15 >> 4);
+
+ if (val2 < 3) {
+ DrawSprite((flag&2 ? 0x397 : 0x367) + val2, x, y);
+ /* skip the rest */
+ goto skip_mouth;
+ }
+
+ val2 -= 3;
+ if (flag & 2) {
+ if (val2 > 8) val2 = 0;
+ val2 += 0x3A5 - 0x35B;
+ }
+ DrawSprite(val2 + 0x35B, x, y);
+ } else if (!(flag&2)) {
+ DrawSprite(((val&0xF) * 10 >> 4) + 0x351, x, y);
+ } else {
+ DrawSprite(((val&0xF) * 9 >> 4) + 0x3C8, x, y);
+ }
+
+ val >>= 3;
+
+ if (!(flag&2)) {
+ if (!(flag&1)) {
+ DrawSprite(0x349 + val, x, y);
+ } else {
+ DrawSprite( mouth_table[(val*3>>3)], x, y);
+ }
+ } else {
+ if (!(flag&1)) {
+ DrawSprite(0x393 + (val&3), x, y);
+ } else {
+ DrawSprite(0x3B3 + (val*5>>3), x, y);
+ }
+ }
+
+ skip_mouth:;
+ }
+
+
+ /* draw the hair */
+ {
+ uint val = GB(face, 16, 4);
+ if (flag & 2) {
+ if (flag & 1) {
+ DrawSprite(0x3D9 + (val * 5 >> 4), x, y);
+ } else {
+ DrawSprite(0x3D4 + (val * 5 >> 4), x, y);
+ }
+ } else {
+ if (flag & 1) {
+ DrawSprite(0x38B + (val * 5 >> 4), x, y);
+ } else {
+ DrawSprite(0x382 + (val * 9 >> 4), x, y);
+ }
+ }
+ }
+
+ /* draw the tie */
+ {
+ uint val = GB(face, 20, 8);
+
+ if (!(flag&1)) {
+ DrawSprite(0x36B + (GB(val, 0, 2) * 3 >> 2), x, y);
+ DrawSprite(0x36E + (GB(val, 2, 2) * 4 >> 2), x, y);
+ DrawSprite(0x372 + (GB(val, 4, 4) * 6 >> 4), x, y);
+ } else {
+ DrawSprite(0x378 + (GB(val, 0, 2) * 3 >> 2), x, y);
+ DrawSprite(0x37B + (GB(val, 2, 2) * 4 >> 2), x, y);
+
+ val >>= 4;
+ if (val < 3) DrawSprite((flag & 2 ? 0x3D1 : 0x37F) + val, x, y);
+ }
+ }
+
+ /* draw the glasses */
+ {
+ uint val = GB(face, 28, 3);
+
+ if (flag & 2) {
+ if (val <= 1) DrawSprite(0x3AE + val, x, y);
+ } else {
+ if (val <= 1) DrawSprite(0x347 + val, x, y);
+ }
+ }
+}
+
+void InvalidatePlayerWindows(const Player *p)
+{
+ PlayerID pid = p->index;
+
+ if (pid == _local_player) InvalidateWindow(WC_STATUS_BAR, 0);
+ InvalidateWindow(WC_FINANCES, pid);
+}
+
+bool CheckPlayerHasMoney(int32 cost)
+{
+ if (cost > 0) {
+ PlayerID pid = _current_player;
+ if (IsValidPlayer(pid) && cost > GetPlayer(pid)->player_money) {
+ SetDParam(0, cost);
+ _error_message = STR_0003_NOT_ENOUGH_CASH_REQUIRES;
+ return false;
+ }
+ }
+ return true;
+}
+
+static void SubtractMoneyFromAnyPlayer(Player *p, int32 cost)
+{
+ p->money64 -= cost;
+ UpdatePlayerMoney32(p);
+
+ p->yearly_expenses[0][_yearly_expenses_type] += cost;
+
+ if (HASBIT(1<<7|1<<8|1<<9|1<<10, _yearly_expenses_type)) {
+ p->cur_economy.income -= cost;
+ } else if (HASBIT(1<<2|1<<3|1<<4|1<<5|1<<6|1<<11, _yearly_expenses_type)) {
+ p->cur_economy.expenses -= cost;
+ }
+
+ InvalidatePlayerWindows(p);
+}
+
+void SubtractMoneyFromPlayer(int32 cost)
+{
+ PlayerID pid = _current_player;
+
+ if (IsValidPlayer(pid)) SubtractMoneyFromAnyPlayer(GetPlayer(pid), cost);
+}
+
+void SubtractMoneyFromPlayerFract(PlayerID player, int32 cost)
+{
+ Player *p = GetPlayer(player);
+ byte m = p->player_money_fraction;
+
+ p->player_money_fraction = m - (byte)cost;
+ cost >>= 8;
+ if (p->player_money_fraction > m) cost++;
+ if (cost != 0) SubtractMoneyFromAnyPlayer(p, cost);
+}
+
+// the player_money field is kept as it is, but money64 contains the actual amount of money.
+void UpdatePlayerMoney32(Player *p)
+{
+ if (p->money64 < -2000000000) {
+ p->player_money = -2000000000;
+ } else if (p->money64 > 2000000000) {
+ p->player_money = 2000000000;
+ } else {
+ p->player_money = (int32)p->money64;
+ }
+}
+
+void GetNameOfOwner(Owner owner, TileIndex tile)
+{
+ SetDParam(2, owner);
+
+ if (owner != OWNER_TOWN) {
+ if (!IsValidPlayer(owner)) {
+ SetDParam(0, STR_0150_SOMEONE);
+ } else {
+ const Player* p = GetPlayer(owner);
+
+ SetDParam(0, p->name_1);
+ SetDParam(1, p->name_2);
+ }
+ } else {
+ const Town* t = ClosestTownFromTile(tile, (uint)-1);
+
+ SetDParam(0, STR_TOWN);
+ SetDParam(1, t->index);
+ }
+}
+
+
+bool CheckOwnership(PlayerID owner)
+{
+ assert(owner < OWNER_END);
+
+ if (owner == _current_player) return true;
+ _error_message = STR_013B_OWNED_BY;
+ GetNameOfOwner(owner, 0);
+ return false;
+}
+
+bool CheckTileOwnership(TileIndex tile)
+{
+ Owner owner = GetTileOwner(tile);
+
+ assert(owner < OWNER_END);
+
+ if (owner == _current_player) return true;
+ _error_message = STR_013B_OWNED_BY;
+
+ // no need to get the name of the owner unless we're the local player (saves some time)
+ if (IsLocalPlayer()) GetNameOfOwner(owner, tile);
+ return false;
+}
+
+static void GenerateCompanyName(Player *p)
+{
+ TileIndex tile;
+ Town *t;
+ StringID str;
+ Player *pp;
+ uint32 strp;
+ char buffer[100];
+
+ if (p->name_1 != STR_SV_UNNAMED) return;
+
+ tile = p->last_build_coordinate;
+ if (tile == 0) return;
+
+ t = ClosestTownFromTile(tile, (uint)-1);
+
+ if (IS_INT_INSIDE(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST+1)) {
+ str = t->townnametype - SPECSTR_TOWNNAME_START + SPECSTR_PLAYERNAME_START;
+ strp = t->townnameparts;
+
+verify_name:;
+ // No player must have this name already
+ FOR_ALL_PLAYERS(pp) {
+ if (pp->name_1 == str && pp->name_2 == strp) goto bad_town_name;
+ }
+
+ GetString(buffer, str, lastof(buffer));
+ if (strlen(buffer) >= 32 || GetStringBoundingBox(buffer).width >= 150)
+ goto bad_town_name;
+
+set_name:;
+ p->name_1 = str;
+ p->name_2 = strp;
+
+ MarkWholeScreenDirty();
+
+ if (!IsHumanPlayer(p->index)) {
+ SetDParam(0, t->index);
+ AddNewsItem((StringID)(p->index | NB_BNEWCOMPANY), NEWS_FLAGS(NM_CALLBACK, NF_TILE, NT_COMPANY_INFO, DNC_BANKRUPCY), p->last_build_coordinate, 0);
+ }
+ return;
+ }
+bad_town_name:;
+
+ if (p->president_name_1 == SPECSTR_PRESIDENT_NAME) {
+ str = SPECSTR_ANDCO_NAME;
+ strp = p->president_name_2;
+ goto set_name;
+ } else {
+ str = SPECSTR_ANDCO_NAME;
+ strp = Random();
+ goto verify_name;
+ }
+}
+
+#define COLOR_SWAP(i,j) do { byte t=colors[i];colors[i]=colors[j];colors[j]=t; } while(0)
+
+static const byte _color_sort[16] = {2, 2, 3, 2, 3, 2, 3, 2, 3, 2, 2, 2, 3, 1, 1, 1};
+static const byte _color_similar_1[16] = {8, 6, 255, 12, 255, 0, 1, 1, 0, 13, 11, 10, 3, 9, 15, 14};
+static const byte _color_similar_2[16] = {5, 7, 255, 255, 255, 8, 7, 6, 5, 12, 255, 255, 9, 255, 255, 255};
+
+static byte GeneratePlayerColor(void)
+{
+ byte colors[16], pcolor, t2;
+ int i,j,n;
+ uint32 r;
+ Player *p;
+
+ // Initialize array
+ for (i = 0; i != 16; i++) colors[i] = i;
+
+ // And randomize it
+ n = 100;
+ do {
+ r = Random();
+ COLOR_SWAP(GB(r, 0, 4), GB(r, 4, 4));
+ } while (--n);
+
+ // Bubble sort it according to the values in table 1
+ i = 16;
+ do {
+ for (j = 0; j != 15; j++) {
+ if (_color_sort[colors[j]] < _color_sort[colors[j + 1]]) {
+ COLOR_SWAP(j, j + 1);
+ }
+ }
+ } while (--i);
+
+ // Move the colors that look similar to each player's color to the side
+ FOR_ALL_PLAYERS(p) if (p->is_active) {
+ pcolor = p->player_color;
+ for (i=0; i!=16; i++) if (colors[i] == pcolor) {
+ colors[i] = 0xFF;
+
+ t2 = _color_similar_1[pcolor];
+ if (t2 == 0xFF) break;
+ for (i=0; i!=15; i++) {
+ if (colors[i] == t2) {
+ do COLOR_SWAP(i,i+1); while (++i != 15);
+ break;
+ }
+ }
+
+ t2 = _color_similar_2[pcolor];
+ if (t2 == 0xFF) break;
+ for (i = 0; i != 15; i++) {
+ if (colors[i] == t2) {
+ do COLOR_SWAP(i, i + 1); while (++i != 15);
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ // Return the first available color
+ for (i = 0;; i++) {
+ if (colors[i] != 0xFF) return colors[i];
+ }
+}
+
+static void GeneratePresidentName(Player *p)
+{
+ Player *pp;
+ char buffer[100], buffer2[40];
+
+ for (;;) {
+restart:;
+
+ p->president_name_2 = Random();
+ p->president_name_1 = SPECSTR_PRESIDENT_NAME;
+
+ SetDParam(0, p->president_name_2);
+ GetString(buffer, p->president_name_1, lastof(buffer));
+ if (strlen(buffer) >= 32 || GetStringBoundingBox(buffer).width >= 94)
+ continue;
+
+ FOR_ALL_PLAYERS(pp) {
+ if (pp->is_active && p != pp) {
+ SetDParam(0, pp->president_name_2);
+ GetString(buffer2, pp->president_name_1, lastof(buffer2));
+ if (strcmp(buffer2, buffer) == 0)
+ goto restart;
+ }
+ }
+ return;
+ }
+}
+
+static Player *AllocatePlayer(void)
+{
+ Player *p;
+ // Find a free slot
+ FOR_ALL_PLAYERS(p) {
+ if (!p->is_active) {
+ int i = p->index;
+ memset(p, 0, sizeof(Player));
+ p->index = i;
+ return p;
+ }
+ }
+ return NULL;
+}
+
+void ResetPlayerLivery(Player *p)
+{
+ LiveryScheme scheme;
+
+ for (scheme = 0; scheme < LS_END; scheme++) {
+ p->livery[scheme].in_use = false;
+ p->livery[scheme].colour1 = p->player_color;
+ p->livery[scheme].colour2 = p->player_color;
+ }
+}
+
+Player *DoStartupNewPlayer(bool is_ai)
+{
+ Player *p;
+
+ p = AllocatePlayer();
+ if (p == NULL) return NULL;
+
+ // Make a color
+ p->player_color = GeneratePlayerColor();
+ ResetPlayerLivery(p);
+ _player_colors[p->index] = p->player_color;
+ p->name_1 = STR_SV_UNNAMED;
+ p->is_active = true;
+
+ p->money64 = p->player_money = p->current_loan = 100000;
+
+ p->is_ai = is_ai;
+ p->ai.state = 5; /* AIS_WANT_NEW_ROUTE */
+ p->share_owners[0] = p->share_owners[1] = p->share_owners[2] = p->share_owners[3] = PLAYER_SPECTATOR;
+
+ p->avail_railtypes = GetPlayerRailtypes(p->index);
+ p->inaugurated_year = _cur_year;
+ p->face = Random();
+
+ /* Engine renewal settings */
+ p->engine_renew_list = NULL;
+ p->renew_keep_length = false;
+ p->engine_renew = false;
+ p->engine_renew_months = -6;
+ p->engine_renew_money = 100000;
+
+ GeneratePresidentName(p);
+
+ InvalidateWindow(WC_GRAPH_LEGEND, 0);
+ InvalidateWindow(WC_TOOLBAR_MENU, 0);
+ InvalidateWindow(WC_CLIENT_LIST, 0);
+
+ if (is_ai && (!_networking || _network_server) && _ai.enabled)
+ AI_StartNewAI(p->index);
+
+ memset(p->num_engines, 0, sizeof(p->num_engines));
+
+ return p;
+}
+
+void StartupPlayers(void)
+{
+ // The AI starts like in the setting with +2 month max
+ _next_competitor_start = _opt.diff.competitor_start_time * 90 * DAY_TICKS + RandomRange(60 * DAY_TICKS) + 1;
+}
+
+static void MaybeStartNewPlayer(void)
+{
+ uint n;
+ Player *p;
+
+ // count number of competitors
+ n = 0;
+ FOR_ALL_PLAYERS(p) {
+ if (p->is_active && p->is_ai) n++;
+ }
+
+ // when there's a lot of computers in game, the probability that a new one starts is lower
+ if (n < (uint)_opt.diff.max_no_competitors &&
+ n < (_network_server ?
+ InteractiveRandomRange(_opt.diff.max_no_competitors + 2) :
+ RandomRange(_opt.diff.max_no_competitors + 2)
+ )) {
+ /* Send a command to all clients to start up a new AI.
+ * Works fine for Multiplayer and Singleplayer */
+ DoCommandP(0, 1, 0, NULL, CMD_PLAYER_CTRL);
+ }
+
+ // The next AI starts like the difficulty setting said, with +2 month max
+ _next_competitor_start = _opt.diff.competitor_start_time * 90 * DAY_TICKS + 1;
+ _next_competitor_start += _network_server ? InteractiveRandomRange(60 * DAY_TICKS) : RandomRange(60 * DAY_TICKS);
+}
+
+void InitializePlayers(void)
+{
+ uint i;
+
+ memset(_players, 0, sizeof(_players));
+ for (i = 0; i != MAX_PLAYERS; i++) _players[i].index = i;
+ _cur_player_tick_index = 0;
+}
+
+void OnTick_Players(void)
+{
+ Player *p;
+
+ if (_game_mode == GM_EDITOR) return;
+
+ p = GetPlayer(_cur_player_tick_index);
+ _cur_player_tick_index = (_cur_player_tick_index + 1) % MAX_PLAYERS;
+ if (p->name_1 != 0) GenerateCompanyName(p);
+
+ if (AI_AllowNewAI() && _game_mode != GM_MENU && !--_next_competitor_start)
+ MaybeStartNewPlayer();
+}
+
+// index is the next parameter in _decode_parameters to set up
+StringID GetPlayerNameString(PlayerID player, uint index)
+{
+ if (IsHumanPlayer(player) && IsValidPlayer(player)) {
+ SetDParam(index, player+1);
+ return STR_7002_PLAYER;
+ }
+ return STR_EMPTY;
+}
+
+extern void ShowPlayerFinances(int player);
+
+void PlayersYearlyLoop(void)
+{
+ Player *p;
+
+ // Copy statistics
+ FOR_ALL_PLAYERS(p) {
+ if (p->is_active) {
+ memmove(&p->yearly_expenses[1], &p->yearly_expenses[0], sizeof(p->yearly_expenses) - sizeof(p->yearly_expenses[0]));
+ memset(&p->yearly_expenses[0], 0, sizeof(p->yearly_expenses[0]));
+ InvalidateWindow(WC_FINANCES, p->index);
+ }
+ }
+
+ if (_patches.show_finances && _local_player != PLAYER_SPECTATOR) {
+ ShowPlayerFinances(_local_player);
+ p = GetPlayer(_local_player);
+ if (p->num_valid_stat_ent > 5 && p->old_economy[0].performance_history < p->old_economy[4].performance_history) {
+ SndPlayFx(SND_01_BAD_YEAR);
+ } else {
+ SndPlayFx(SND_00_GOOD_YEAR);
+ }
+ }
+}
+
+byte GetPlayerRailtypes(PlayerID p)
+{
+ byte rt = 0;
+ EngineID i;
+
+ for (i = 0; i != TOTAL_NUM_ENGINES; i++) {
+ const Engine* e = GetEngine(i);
+ const EngineInfo *ei = EngInfo(i);
+
+ if (e->type == VEH_Train && HASBIT(ei->climates, _opt.landscape) &&
+ (HASBIT(e->player_avail, p) || _date >= (e->intro_date + 365)) &&
+ !(RailVehInfo(i)->flags & RVI_WAGON)) {
+ assert(e->railtype < RAILTYPE_END);
+ SETBIT(rt, e->railtype);
+ }
+ }
+
+ return rt;
+}
+
+static void DeletePlayerStuff(PlayerID pi)
+{
+ Player *p;
+
+ DeletePlayerWindows(pi);
+ p = GetPlayer(pi);
+ DeleteName(p->name_1);
+ DeleteName(p->president_name_1);
+ p->name_1 = 0;
+ p->president_name_1 = 0;
+}
+
+/** Change engine renewal parameters
+ * @param tile unused
+ * @param p1 bits 0-3 command
+ * - p1 = 0 - change auto renew bool
+ * - p1 = 1 - change auto renew months
+ * - p1 = 2 - change auto renew money
+ * - p1 = 3 - change auto renew array
+ * - p1 = 4 - change bool, months & money all together
+ * - p1 = 5 - change renew_keep_length
+ * @param p2 value to set
+ * if p1 = 0, then:
+ * - p2 = enable engine renewal
+ * if p1 = 1, then:
+ * - p2 = months left before engine expires to replace it
+ * if p1 = 2, then
+ * - p2 = minimum amount of money available
+ * if p1 = 3, then:
+ * - p2 bits 0-15 = old engine type
+ * - p2 bits 16-31 = new engine type
+ * if p1 = 4, then:
+ * - p1 bit 15 = enable engine renewal
+ * - p1 bits 16-31 = months left before engine expires to replace it
+ * - p2 bits 0-31 = minimum amount of money available
+ * if p1 = 5, then
+ * - p2 = enable renew_keep_length
+ */
+int32 CmdSetAutoReplace(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Player *p;
+ if (!IsValidPlayer(_current_player)) return CMD_ERROR;
+
+ p = GetPlayer(_current_player);
+ switch (GB(p1, 0, 3)) {
+ case 0:
+ if (p->engine_renew == (bool)GB(p2, 0, 1))
+ return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ p->engine_renew = (bool)GB(p2, 0, 1);
+ if (IsLocalPlayer()) {
+ _patches.autorenew = p->engine_renew;
+ InvalidateWindow(WC_GAME_OPTIONS, 0);
+ }
+ }
+ break;
+ case 1:
+ if (p->engine_renew_months == (int16)p2)
+ return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ p->engine_renew_months = (int16)p2;
+ if (IsLocalPlayer()) {
+ _patches.autorenew_months = p->engine_renew_months;
+ InvalidateWindow(WC_GAME_OPTIONS, 0);
+ }
+ }
+ break;
+ case 2:
+ if (p->engine_renew_money == (uint32)p2)
+ return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ p->engine_renew_money = (uint32)p2;
+ if (IsLocalPlayer()) {
+ _patches.autorenew_money = p->engine_renew_money;
+ InvalidateWindow(WC_GAME_OPTIONS, 0);
+ }
+ }
+ break;
+ case 3: {
+ EngineID old_engine_type = GB(p2, 0, 16);
+ EngineID new_engine_type = GB(p2, 16, 16);
+ int32 cost;
+
+ if (new_engine_type != INVALID_ENGINE) {
+ /* First we make sure that it's a valid type the user requested
+ * check that it's an engine that is in the engine array */
+ if (!IsEngineIndex(new_engine_type))
+ return CMD_ERROR;
+
+ // check that the new vehicle type is the same as the original one
+ if (GetEngine(old_engine_type)->type != GetEngine(new_engine_type)->type)
+ return CMD_ERROR;
+
+ // make sure that we do not replace a plane with a helicopter or vise versa
+ if (GetEngine(new_engine_type)->type == VEH_Aircraft &&
+ (AircraftVehInfo(old_engine_type)->subtype & AIR_CTOL) != (AircraftVehInfo(new_engine_type)->subtype & AIR_CTOL))
+ return CMD_ERROR;
+
+ // make sure that the player can actually buy the new engine
+ if (!HASBIT(GetEngine(new_engine_type)->player_avail, _current_player))
+ return CMD_ERROR;
+
+ cost = AddEngineReplacementForPlayer(p, old_engine_type, new_engine_type, flags);
+ } else {
+ cost = RemoveEngineReplacementForPlayer(p, old_engine_type, flags);
+ }
+
+ if (IsLocalPlayer()) InvalidateWindow(WC_REPLACE_VEHICLE, GetEngine(old_engine_type)->type);
+
+ return cost;
+ }
+
+ case 4:
+ if (flags & DC_EXEC) {
+ p->engine_renew = (bool)GB(p1, 15, 1);
+ p->engine_renew_months = (int16)GB(p1, 16, 16);
+ p->engine_renew_money = (uint32)p2;
+
+ if (IsLocalPlayer()) {
+ _patches.autorenew = p->engine_renew;
+ _patches.autorenew_months = p->engine_renew_months;
+ _patches.autorenew_money = p->engine_renew_money;
+ InvalidateWindow(WC_GAME_OPTIONS, 0);
+ }
+ }
+ break;
+ case 5:
+ if (p->renew_keep_length == (bool)GB(p2, 0, 1))
+ return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ p->renew_keep_length = (bool)GB(p2, 0, 1);
+ if (IsLocalPlayer()) {
+ InvalidateWindow(WC_REPLACE_VEHICLE, VEH_Train);
+ }
+ }
+ break;
+
+ }
+ return 0;
+}
+
+/** Control the players: add, delete, etc.
+ * @param tile unused
+ * @param p1 various functionality
+ * - p1 = 0 - create a new player, Which player (network) it will be is in p2
+ * - p1 = 1 - create a new AI player
+ * - p1 = 2 - delete a player. Player is identified by p2
+ * - p1 = 3 - merge two companies together. Player to merge #1 with player #2. Identified by p2
+ * @param p2 various functionality, dictated by p1
+ * - p1 = 0 - ClientID of the newly created player
+ * - p1 = 2 - PlayerID of the that is getting deleted
+ * - p1 = 3 - #1 p2 = (bit 0-15) - player to merge (p2 & 0xFFFF)
+ * - #2 p2 = (bit 16-31) - player to be merged into ((p2>>16)&0xFFFF)
+ * @todo In the case of p1=0, create new player, the clientID of the new player is in parameter
+ * p2. This parameter is passed in at function DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND)
+ * on the server itself. First of all this is unbelievably ugly; second of all, well,
+ * it IS ugly! <b>Someone fix this up :)</b> So where to fix?@n
+ * @arg - network_server.c:838 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND)@n
+ * @arg - network_client.c:536 DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_MAP) from where the map has been received
+ */
+int32 CmdPlayerCtrl(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ if (flags & DC_EXEC) _current_player = OWNER_NONE;
+
+ switch (p1) {
+ case 0: { /* Create a new player */
+ /* Joining Client:
+ * _local_player: PLAYER_SPECTATOR
+ * _network_playas/cid = requested company/player
+ *
+ * Other client(s)/server:
+ * _local_player/_network_playas: what they play as
+ * cid = requested company/player of joining client */
+ Player *p;
+ uint16 cid = p2; // ClientID
+
+ /* This command is only executed in a multiplayer game */
+ if (!_networking) return CMD_ERROR;
+
+ /* Has the network client a correct ClientID? */
+ if (!(flags & DC_EXEC)) return 0;
+#ifdef ENABLE_NETWORK
+ if (cid >= MAX_CLIENT_INFO) return 0;
+#endif /* ENABLE_NETWORK */
+
+ /* Delete multiplayer progress bar */
+ DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
+
+ p = DoStartupNewPlayer(false);
+
+ /* A new player could not be created, revert to being a spectator */
+ if (p == NULL) {
+#ifdef ENABLE_NETWORK
+ if (_network_server) {
+ NetworkClientInfo *ci = &_network_client_info[cid];
+ ci->client_playas = PLAYER_SPECTATOR;
+ NetworkUpdateClientInfo(ci->client_index);
+ } else
+#endif /* ENABLE_NETWORK */
+ {
+ _network_playas = PLAYER_SPECTATOR;
+ SetLocalPlayer(PLAYER_SPECTATOR);
+ }
+ break;
+ }
+
+ /* This is the joining client who wants a new company */
+ if (_local_player != _network_playas) {
+ assert(_local_player == PLAYER_SPECTATOR && _network_playas == p->index);
+ SetLocalPlayer(p->index);
+ MarkWholeScreenDirty();
+ }
+
+ /* Now that we have a new player, broadcast its autorenew settings to
+ * all clients so everything is in sync */
+ DoCommand(0,
+ (_patches.autorenew << 15 ) | (_patches.autorenew_months << 16) | 4,
+ _patches.autorenew_money,
+ DC_EXEC,
+ CMD_SET_AUTOREPLACE
+ );
+
+#ifdef ENABLE_NETWORK
+ if (_network_server) {
+ /* XXX - UGLY! p2 (pid) is mis-used to fetch the client-id, done at
+ * server-side in network_server.c:838, function
+ * DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND) */
+ NetworkClientInfo *ci = &_network_client_info[cid];
+ ci->client_playas = p->index;
+ NetworkUpdateClientInfo(ci->client_index);
+
+ if (IsValidPlayer(ci->client_playas)) {
+ PlayerID player_backup = _local_player;
+ _network_player_info[p->index].months_empty = 0;
+
+ /* XXX - When a client joins, we automatically set its name to the
+ * player's name (for some reason). As it stands now only the server
+ * knows the client's name, so it needs to send out a "broadcast" to
+ * do this. To achieve this we send a network command. However, it
+ * uses _local_player to execute the command as. To prevent abuse
+ * (eg. only yourself can change your name/company), we 'cheat' by
+ * impersonation _local_player as the server. Not the best solution;
+ * but it works.
+ * TODO: Perhaps this could be improved by when the client is ready
+ * with joining to let it send itself the command, and not the server?
+ * For example in network_client.c:534? */
+ _cmd_text = ci->client_name;
+ _local_player = ci->client_playas;
+ NetworkSend_Command(0, 0, 0, CMD_CHANGE_PRESIDENT_NAME, NULL);
+ _local_player = player_backup;
+ }
+ }
+#endif /* ENABLE_NETWORK */
+ } break;
+
+ case 1: /* Make a new AI player */
+ if (!(flags & DC_EXEC)) return 0;
+
+ DoStartupNewPlayer(true);
+ break;
+
+ case 2: { /* Delete a player */
+ Player *p;
+
+ if (!IsValidPlayer(p2)) return CMD_ERROR;
+
+ if (!(flags & DC_EXEC)) return 0;
+
+ p = GetPlayer(p2);
+
+ /* Only allow removal of HUMAN companies */
+ if (IsHumanPlayer(p->index)) {
+ /* Delete any open window of the company */
+ DeletePlayerWindows(p->index);
+
+ /* Show the bankrupt news */
+ SetDParam(0, p->name_1);
+ SetDParam(1, p->name_2);
+ AddNewsItem( (StringID)(p->index | NB_BBANKRUPT), NEWS_FLAGS(NM_CALLBACK, 0, NT_COMPANY_INFO, DNC_BANKRUPCY),0,0);
+
+ /* Remove the company */
+ ChangeOwnershipOfPlayerItems(p->index, PLAYER_SPECTATOR);
+ p->is_active = false;
+ }
+ RemoveAllEngineReplacementForPlayer(p);
+
+ } break;
+
+ case 3: { /* Merge a company (#1) into another company (#2), elimination company #1 */
+ PlayerID pid_old = GB(p2, 0, 16);
+ PlayerID pid_new = GB(p2, 16, 16);
+
+ if (!IsValidPlayer(pid_old) || !IsValidPlayer(pid_new)) return CMD_ERROR;
+
+ if (!(flags & DC_EXEC)) return CMD_ERROR;
+
+ ChangeOwnershipOfPlayerItems(pid_old, pid_new);
+ DeletePlayerStuff(pid_old);
+ } break;
+
+ default: return CMD_ERROR;
+ }
+
+ return 0;
+}
+
+static const StringID _endgame_perf_titles[] = {
+ STR_0213_BUSINESSMAN,
+ STR_0213_BUSINESSMAN,
+ STR_0213_BUSINESSMAN,
+ STR_0213_BUSINESSMAN,
+ STR_0213_BUSINESSMAN,
+ STR_0214_ENTREPRENEUR,
+ STR_0214_ENTREPRENEUR,
+ STR_0215_INDUSTRIALIST,
+ STR_0215_INDUSTRIALIST,
+ STR_0216_CAPITALIST,
+ STR_0216_CAPITALIST,
+ STR_0217_MAGNATE,
+ STR_0217_MAGNATE,
+ STR_0218_MOGUL,
+ STR_0218_MOGUL,
+ STR_0219_TYCOON_OF_THE_CENTURY
+};
+
+StringID EndGameGetPerformanceTitleFromValue(uint value)
+{
+ value = minu(value / 64, lengthof(_endgame_perf_titles) - 1);
+
+ return _endgame_perf_titles[value];
+}
+
+/* Return true if any cheat has been used, false otherwise */
+static bool CheatHasBeenUsed(void)
+{
+ const Cheat* cht = (Cheat*)&_cheats;
+ const Cheat* cht_last = &cht[sizeof(_cheats) / sizeof(Cheat)];
+
+ for (; cht != cht_last; cht++) {
+ if (cht->been_used) return true;
+ }
+
+ return false;
+}
+
+/* Save the highscore for the player */
+int8 SaveHighScoreValue(const Player *p)
+{
+ HighScore *hs = _highscore_table[_opt.diff_level];
+ uint i;
+ uint16 score = p->old_economy[0].performance_history;
+
+ /* Exclude cheaters from the honour of being in the highscore table */
+ if (CheatHasBeenUsed()) return -1;
+
+ for (i = 0; i < lengthof(_highscore_table[0]); i++) {
+ /* You are in the TOP5. Move all values one down and save us there */
+ if (hs[i].score <= score) {
+ // move all elements one down starting from the replaced one
+ memmove(&hs[i + 1], &hs[i], sizeof(HighScore) * (lengthof(_highscore_table[0]) - i - 1));
+ SetDParam(0, p->president_name_1);
+ SetDParam(1, p->president_name_2);
+ SetDParam(2, p->name_1);
+ SetDParam(3, p->name_2);
+ GetString(hs[i].company, STR_HIGHSCORE_NAME, lastof(hs[i].company)); // get manager/company name string
+ hs[i].score = score;
+ hs[i].title = EndGameGetPerformanceTitleFromValue(score);
+ return i;
+ }
+ }
+
+ return -1; // too bad; we did not make it into the top5
+}
+
+/* Sort all players given their performance */
+static int CDECL HighScoreSorter(const void *a, const void *b)
+{
+ const Player *pa = *(const Player* const*)a;
+ const Player *pb = *(const Player* const*)b;
+
+ return pb->old_economy[0].performance_history - pa->old_economy[0].performance_history;
+}
+
+/* Save the highscores in a network game when it has ended */
+#define LAST_HS_ITEM lengthof(_highscore_table) - 1
+int8 SaveHighScoreValueNetwork(void)
+{
+ const Player* p;
+ const Player* pl[MAX_PLAYERS];
+ size_t count = 0;
+ int8 player = -1;
+
+ /* Sort all active players with the highest score first */
+ FOR_ALL_PLAYERS(p) if (p->is_active) pl[count++] = p;
+ qsort((Player*)pl, count, sizeof(pl[0]), HighScoreSorter);
+
+ {
+ uint i;
+
+ memset(_highscore_table[LAST_HS_ITEM], 0, sizeof(_highscore_table[0]));
+
+ /* Copy over Top5 companies */
+ for (i = 0; i < lengthof(_highscore_table[LAST_HS_ITEM]) && i < count; i++) {
+ HighScore* hs = &_highscore_table[LAST_HS_ITEM][i];
+
+ SetDParam(0, pl[i]->president_name_1);
+ SetDParam(1, pl[i]->president_name_2);
+ SetDParam(2, pl[i]->name_1);
+ SetDParam(3, pl[i]->name_2);
+ GetString(hs->company, STR_HIGHSCORE_NAME, lastof(hs->company)); // get manager/company name string
+ hs->score = pl[i]->old_economy[0].performance_history;
+ hs->title = EndGameGetPerformanceTitleFromValue(hs->score);
+
+ // get the ranking of the local player
+ if (pl[i]->index == _local_player) player = i;
+ }
+ }
+
+ /* Add top5 players to highscore table */
+ return player;
+}
+
+/* Save HighScore table to file */
+void SaveToHighScore(void)
+{
+ FILE *fp = fopen(_highscore_file, "wb");
+
+ if (fp != NULL) {
+ uint i;
+ HighScore *hs;
+
+ for (i = 0; i < LAST_HS_ITEM; i++) { // don't save network highscores
+ for (hs = _highscore_table[i]; hs != endof(_highscore_table[i]); hs++) {
+ /* First character is a command character, so strlen will fail on that */
+ byte length = min(sizeof(hs->company), (hs->company[0] == '\0') ? 0 : (int)strlen(&hs->company[1]) + 1);
+
+ fwrite(&length, sizeof(length), 1, fp); // write away string length
+ fwrite(hs->company, length, 1, fp);
+ fwrite(&hs->score, sizeof(hs->score), 1, fp);
+ fwrite("", 2, 1, fp); /* XXX - placeholder for hs->title, not saved anymore; compatibility */
+ }
+ }
+ fclose(fp);
+ }
+}
+
+/* Initialize the highscore table to 0 and if any file exists, load in values */
+void LoadFromHighScore(void)
+{
+ FILE *fp = fopen(_highscore_file, "rb");
+
+ memset(_highscore_table, 0, sizeof(_highscore_table));
+
+ if (fp != NULL) {
+ uint i;
+ HighScore *hs;
+
+ for (i = 0; i < LAST_HS_ITEM; i++) { // don't load network highscores
+ for (hs = _highscore_table[i]; hs != endof(_highscore_table[i]); hs++) {
+ byte length;
+ fread(&length, sizeof(length), 1, fp);
+
+ fread(hs->company, 1, length, fp);
+ fread(&hs->score, sizeof(hs->score), 1, fp);
+ fseek(fp, 2, SEEK_CUR); /* XXX - placeholder for hs->title, not saved anymore; compatibility */
+ hs->title = EndGameGetPerformanceTitleFromValue(hs->score);
+ }
+ }
+ fclose(fp);
+ }
+
+ /* Initialize end of game variable (when to show highscore chart) */
+ _patches.ending_year = 2051;
+}
+
+// Save/load of players
+static const SaveLoad _player_desc[] = {
+ SLE_VAR(Player, name_2, SLE_UINT32),
+ SLE_VAR(Player, name_1, SLE_STRINGID),
+
+ SLE_VAR(Player, president_name_1,SLE_UINT16),
+ SLE_VAR(Player, president_name_2,SLE_UINT32),
+
+ SLE_VAR(Player, face, SLE_UINT32),
+
+ // money was changed to a 64 bit field in savegame version 1.
+ SLE_CONDVAR(Player, money64, SLE_VAR_I64 | SLE_FILE_I32, 0, 0),
+ SLE_CONDVAR(Player, money64, SLE_INT64, 1, SL_MAX_VERSION),
+
+ SLE_VAR(Player, current_loan, SLE_INT32),
+
+ SLE_VAR(Player, player_color, SLE_UINT8),
+ SLE_VAR(Player, player_money_fraction, SLE_UINT8),
+ SLE_VAR(Player, avail_railtypes, SLE_UINT8),
+ SLE_VAR(Player, block_preview, SLE_UINT8),
+
+ SLE_VAR(Player, cargo_types, SLE_UINT16),
+ SLE_CONDVAR(Player, location_of_house, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+ SLE_CONDVAR(Player, location_of_house, SLE_UINT32, 6, SL_MAX_VERSION),
+ SLE_CONDVAR(Player, last_build_coordinate, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+ SLE_CONDVAR(Player, last_build_coordinate, SLE_UINT32, 6, SL_MAX_VERSION),
+ SLE_CONDVAR(Player, inaugurated_year, SLE_FILE_U8 | SLE_VAR_I32, 0, 30),
+ SLE_CONDVAR(Player, inaugurated_year, SLE_INT32, 31, SL_MAX_VERSION),
+
+ SLE_ARR(Player, share_owners, SLE_UINT8, 4),
+
+ SLE_VAR(Player, num_valid_stat_ent, SLE_UINT8),
+
+ SLE_VAR(Player, quarters_of_bankrupcy, SLE_UINT8),
+ SLE_VAR(Player, bankrupt_asked, SLE_UINT8),
+ SLE_VAR(Player, bankrupt_timeout, SLE_INT16),
+ SLE_VAR(Player, bankrupt_value, SLE_INT32),
+
+ // yearly expenses was changed to 64-bit in savegame version 2.
+ SLE_CONDARR(Player, yearly_expenses, SLE_FILE_I32 | SLE_VAR_I64, 3 * 13, 0, 1),
+ SLE_CONDARR(Player, yearly_expenses, SLE_INT64, 3 * 13, 2, SL_MAX_VERSION),
+
+ SLE_CONDVAR(Player, is_ai, SLE_BOOL, 2, SL_MAX_VERSION),
+ SLE_CONDVAR(Player, is_active, SLE_BOOL, 4, SL_MAX_VERSION),
+
+ // Engine renewal settings
+ SLE_CONDNULL(512, 16, 18),
+ SLE_CONDREF(Player, engine_renew_list, REF_ENGINE_RENEWS, 19, SL_MAX_VERSION),
+ SLE_CONDVAR(Player, engine_renew, SLE_BOOL, 16, SL_MAX_VERSION),
+ SLE_CONDVAR(Player, engine_renew_months, SLE_INT16, 16, SL_MAX_VERSION),
+ SLE_CONDVAR(Player, engine_renew_money, SLE_UINT32, 16, SL_MAX_VERSION),
+ SLE_CONDVAR(Player, renew_keep_length, SLE_BOOL, 2, SL_MAX_VERSION), // added with 16.1, but was blank since 2
+
+ // reserve extra space in savegame here. (currently 63 bytes)
+ SLE_CONDNULL(63, 2, SL_MAX_VERSION),
+
+ SLE_END()
+};
+
+static const SaveLoad _player_economy_desc[] = {
+ // these were changed to 64-bit in savegame format 2
+ SLE_CONDVAR(PlayerEconomyEntry, income, SLE_INT32, 0, 1),
+ SLE_CONDVAR(PlayerEconomyEntry, expenses, SLE_INT32, 0, 1),
+ SLE_CONDVAR(PlayerEconomyEntry, company_value, SLE_FILE_I32 | SLE_VAR_I64, 0, 1),
+ SLE_CONDVAR(PlayerEconomyEntry, income, SLE_FILE_I64 | SLE_VAR_I32, 2, SL_MAX_VERSION),
+ SLE_CONDVAR(PlayerEconomyEntry, expenses, SLE_FILE_I64 | SLE_VAR_I32, 2, SL_MAX_VERSION),
+ SLE_CONDVAR(PlayerEconomyEntry, company_value, SLE_INT64, 2, SL_MAX_VERSION),
+
+ SLE_VAR(PlayerEconomyEntry, delivered_cargo, SLE_INT32),
+ SLE_VAR(PlayerEconomyEntry, performance_history, SLE_INT32),
+
+ SLE_END()
+};
+
+static const SaveLoad _player_ai_desc[] = {
+ SLE_VAR(PlayerAI, state, SLE_UINT8),
+ SLE_VAR(PlayerAI, tick, SLE_UINT8),
+ SLE_CONDVAR(PlayerAI, state_counter, SLE_FILE_U16 | SLE_VAR_U32, 0, 12),
+ SLE_CONDVAR(PlayerAI, state_counter, SLE_UINT32, 13, SL_MAX_VERSION),
+ SLE_VAR(PlayerAI, timeout_counter, SLE_UINT16),
+
+ SLE_VAR(PlayerAI, state_mode, SLE_UINT8),
+ SLE_VAR(PlayerAI, banned_tile_count, SLE_UINT8),
+ SLE_VAR(PlayerAI, railtype_to_use, SLE_UINT8),
+
+ SLE_VAR(PlayerAI, cargo_type, SLE_UINT8),
+ SLE_VAR(PlayerAI, num_wagons, SLE_UINT8),
+ SLE_VAR(PlayerAI, build_kind, SLE_UINT8),
+ SLE_VAR(PlayerAI, num_build_rec, SLE_UINT8),
+ SLE_VAR(PlayerAI, num_loco_to_build, SLE_UINT8),
+ SLE_VAR(PlayerAI, num_want_fullload, SLE_UINT8),
+
+ SLE_VAR(PlayerAI, route_type_mask, SLE_UINT8),
+
+ SLE_CONDVAR(PlayerAI, start_tile_a, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+ SLE_CONDVAR(PlayerAI, start_tile_a, SLE_UINT32, 6, SL_MAX_VERSION),
+ SLE_CONDVAR(PlayerAI, cur_tile_a, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+ SLE_CONDVAR(PlayerAI, cur_tile_a, SLE_UINT32, 6, SL_MAX_VERSION),
+ SLE_VAR(PlayerAI, start_dir_a, SLE_UINT8),
+ SLE_VAR(PlayerAI, cur_dir_a, SLE_UINT8),
+
+ SLE_CONDVAR(PlayerAI, start_tile_b, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+ SLE_CONDVAR(PlayerAI, start_tile_b, SLE_UINT32, 6, SL_MAX_VERSION),
+ SLE_CONDVAR(PlayerAI, cur_tile_b, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+ SLE_CONDVAR(PlayerAI, cur_tile_b, SLE_UINT32, 6, SL_MAX_VERSION),
+ SLE_VAR(PlayerAI, start_dir_b, SLE_UINT8),
+ SLE_VAR(PlayerAI, cur_dir_b, SLE_UINT8),
+
+ SLE_REF(PlayerAI, cur_veh, REF_VEHICLE),
+
+ SLE_ARR(PlayerAI, wagon_list, SLE_UINT16, 9),
+ SLE_ARR(PlayerAI, order_list_blocks, SLE_UINT8, 20),
+ SLE_ARR(PlayerAI, banned_tiles, SLE_UINT16, 16),
+
+ SLE_CONDNULL(64, 2, SL_MAX_VERSION),
+ SLE_END()
+};
+
+static const SaveLoad _player_ai_build_rec_desc[] = {
+ SLE_CONDVAR(AiBuildRec, spec_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+ SLE_CONDVAR(AiBuildRec, spec_tile, SLE_UINT32, 6, SL_MAX_VERSION),
+ SLE_CONDVAR(AiBuildRec, use_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+ SLE_CONDVAR(AiBuildRec, use_tile, SLE_UINT32, 6, SL_MAX_VERSION),
+ SLE_VAR(AiBuildRec, rand_rng, SLE_UINT8),
+ SLE_VAR(AiBuildRec, cur_building_rule, SLE_UINT8),
+ SLE_VAR(AiBuildRec, unk6, SLE_UINT8),
+ SLE_VAR(AiBuildRec, unk7, SLE_UINT8),
+ SLE_VAR(AiBuildRec, buildcmd_a, SLE_UINT8),
+ SLE_VAR(AiBuildRec, buildcmd_b, SLE_UINT8),
+ SLE_VAR(AiBuildRec, direction, SLE_UINT8),
+ SLE_VAR(AiBuildRec, cargo, SLE_UINT8),
+ SLE_END()
+};
+
+static const SaveLoad _player_livery_desc[] = {
+ SLE_CONDVAR(Livery, in_use, SLE_BOOL, 34, SL_MAX_VERSION),
+ SLE_CONDVAR(Livery, colour1, SLE_UINT8, 34, SL_MAX_VERSION),
+ SLE_CONDVAR(Livery, colour2, SLE_UINT8, 34, SL_MAX_VERSION),
+ SLE_END()
+};
+
+static void SaveLoad_PLYR(Player* p)
+{
+ int i;
+
+ SlObject(p, _player_desc);
+
+ // Write AI?
+ if (!IsHumanPlayer(p->index)) {
+ SlObject(&p->ai, _player_ai_desc);
+ for (i = 0; i != p->ai.num_build_rec; i++) {
+ SlObject(&p->ai.src + i, _player_ai_build_rec_desc);
+ }
+ }
+
+ // Write economy
+ SlObject(&p->cur_economy, _player_economy_desc);
+
+ // Write old economy entries.
+ for (i = 0; i < p->num_valid_stat_ent; i++) {
+ SlObject(&p->old_economy[i], _player_economy_desc);
+ }
+
+ // Write each livery entry.
+ for (i = 0; i < LS_END; i++) {
+ SlObject(&p->livery[i], _player_livery_desc);
+ }
+}
+
+static void Save_PLYR(void)
+{
+ Player *p;
+ FOR_ALL_PLAYERS(p) {
+ if (p->is_active) {
+ SlSetArrayIndex(p->index);
+ SlAutolength((AutolengthProc*)SaveLoad_PLYR, p);
+ }
+ }
+}
+
+static void Load_PLYR(void)
+{
+ int index;
+ while ((index = SlIterateArray()) != -1) {
+ Player *p = GetPlayer(index);
+ SaveLoad_PLYR(p);
+ _player_colors[index] = p->player_color;
+ UpdatePlayerMoney32(p);
+
+ /* This is needed so an AI is attached to a loaded AI */
+ if (p->is_ai && (!_networking || _network_server) && _ai.enabled)
+ AI_StartNewAI(p->index);
+ }
+}
+
+const ChunkHandler _player_chunk_handlers[] = {
+ { 'PLYR', Save_PLYR, Load_PLYR, CH_ARRAY | CH_LAST},
+};
diff --git a/src/queue.c b/src/queue.c
new file mode 100644
index 000000000..9986442bf
--- /dev/null
+++ b/src/queue.c
@@ -0,0 +1,736 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "queue.h"
+
+static void Stack_Clear(Queue* q, bool free_values)
+{
+ if (free_values) {
+ uint i;
+
+ for (i = 0; i < q->data.stack.size; i++) free(q->data.stack.elements[i]);
+ }
+ q->data.stack.size = 0;
+}
+
+static void Stack_Free(Queue* q, bool free_values)
+{
+ q->clear(q, free_values);
+ free(q->data.stack.elements);
+ if (q->freeq) free(q);
+}
+
+static bool Stack_Push(Queue* q, void* item, int priority)
+{
+ if (q->data.stack.size == q->data.stack.max_size) return false;
+ q->data.stack.elements[q->data.stack.size++] = item;
+ return true;
+}
+
+static void* Stack_Pop(Queue* q)
+{
+ if (q->data.stack.size == 0) return NULL;
+ return q->data.stack.elements[--q->data.stack.size];
+}
+
+static bool Stack_Delete(Queue* q, void* item, int priority)
+{
+ return false;
+}
+
+static Queue* init_stack(Queue* q, uint max_size)
+{
+ q->push = Stack_Push;
+ q->pop = Stack_Pop;
+ q->del = Stack_Delete;
+ q->clear = Stack_Clear;
+ q->free = Stack_Free;
+ q->data.stack.max_size = max_size;
+ q->data.stack.size = 0;
+ q->data.stack.elements = malloc(max_size * sizeof(*q->data.stack.elements));
+ q->freeq = false;
+ return q;
+}
+
+Queue* new_Stack(uint max_size)
+{
+ Queue* q = malloc(sizeof(*q));
+
+ init_stack(q, max_size);
+ q->freeq = true;
+ return q;
+}
+
+/*
+ * Fifo
+ */
+
+static void Fifo_Clear(Queue* q, bool free_values)
+{
+ if (free_values) {
+ uint head = q->data.fifo.head;
+ uint tail = q->data.fifo.tail; /* cache for speed */
+
+ while (head != tail) {
+ free(q->data.fifo.elements[tail]);
+ tail = (tail + 1) % q->data.fifo.max_size;
+ }
+ }
+ q->data.fifo.head = 0;
+ q->data.fifo.tail = 0;
+}
+
+static void Fifo_Free(Queue* q, bool free_values)
+{
+ q->clear(q, free_values);
+ free(q->data.fifo.elements);
+ if (q->freeq) free(q);
+}
+
+static bool Fifo_Push(Queue* q, void* item, int priority)
+{
+ uint next = (q->data.fifo.head + 1) % q->data.fifo.max_size;
+
+ if (next == q->data.fifo.tail) return false;
+ q->data.fifo.elements[q->data.fifo.head] = item;
+
+ q->data.fifo.head = next;
+ return true;
+}
+
+static void* Fifo_Pop(Queue* q)
+{
+ void* result;
+
+ if (q->data.fifo.head == q->data.fifo.tail) return NULL;
+ result = q->data.fifo.elements[q->data.fifo.tail];
+
+ q->data.fifo.tail = (q->data.fifo.tail + 1) % q->data.fifo.max_size;
+ return result;
+}
+
+static bool Fifo_Delete(Queue* q, void* item, int priority)
+{
+ return false;
+}
+
+static Queue* init_fifo(Queue* q, uint max_size)
+{
+ q->push = Fifo_Push;
+ q->pop = Fifo_Pop;
+ q->del = Fifo_Delete;
+ q->clear = Fifo_Clear;
+ q->free = Fifo_Free;
+ q->data.fifo.max_size = max_size;
+ q->data.fifo.head = 0;
+ q->data.fifo.tail = 0;
+ q->data.fifo.elements = malloc(max_size * sizeof(*q->data.fifo.elements));
+ q->freeq = false;
+ return q;
+}
+
+Queue* new_Fifo(uint max_size)
+{
+ Queue* q = malloc(sizeof(*q));
+
+ init_fifo(q, max_size);
+ q->freeq = true;
+ return q;
+}
+
+
+/*
+ * Insertion Sorter
+ */
+
+static void InsSort_Clear(Queue* q, bool free_values)
+{
+ InsSortNode* node = q->data.inssort.first;
+ InsSortNode* prev;
+
+ while (node != NULL) {
+ if (free_values) free(node->item);
+ prev = node;
+ node = node->next;
+ free(prev);
+ }
+ q->data.inssort.first = NULL;
+}
+
+static void InsSort_Free(Queue* q, bool free_values)
+{
+ q->clear(q, free_values);
+ if (q->freeq) free(q);
+}
+
+static bool InsSort_Push(Queue* q, void* item, int priority)
+{
+ InsSortNode* newnode = malloc(sizeof(*newnode));
+
+ if (newnode == NULL) return false;
+ newnode->item = item;
+ newnode->priority = priority;
+ if (q->data.inssort.first == NULL ||
+ q->data.inssort.first->priority >= priority) {
+ newnode->next = q->data.inssort.first;
+ q->data.inssort.first = newnode;
+ } else {
+ InsSortNode* node = q->data.inssort.first;
+ while (node != NULL) {
+ if (node->next == NULL || node->next->priority >= priority) {
+ newnode->next = node->next;
+ node->next = newnode;
+ break;
+ }
+ node = node->next;
+ }
+ }
+ return true;
+}
+
+static void* InsSort_Pop(Queue* q)
+{
+ InsSortNode* node = q->data.inssort.first;
+ void* result;
+
+ if (node == NULL) return NULL;
+ result = node->item;
+ q->data.inssort.first = q->data.inssort.first->next;
+ assert(q->data.inssort.first == NULL || q->data.inssort.first->priority >= node->priority);
+ free(node);
+ return result;
+}
+
+static bool InsSort_Delete(Queue* q, void* item, int priority)
+{
+ return false;
+}
+
+void init_InsSort(Queue* q)
+{
+ q->push = InsSort_Push;
+ q->pop = InsSort_Pop;
+ q->del = InsSort_Delete;
+ q->clear = InsSort_Clear;
+ q->free = InsSort_Free;
+ q->data.inssort.first = NULL;
+ q->freeq = false;
+}
+
+Queue* new_InsSort(void)
+{
+ Queue* q = malloc(sizeof(*q));
+
+ init_InsSort(q);
+ q->freeq = true;
+ return q;
+}
+
+
+/*
+ * Binary Heap
+ * For information, see: http://www.policyalmanac.org/games/binaryHeaps.htm
+ */
+
+#define BINARY_HEAP_BLOCKSIZE (1 << BINARY_HEAP_BLOCKSIZE_BITS)
+#define BINARY_HEAP_BLOCKSIZE_MASK (BINARY_HEAP_BLOCKSIZE - 1)
+
+// To make our life easy, we make the next define
+// Because Binary Heaps works with array from 1 to n,
+// and C with array from 0 to n-1, and we don't like typing
+// q->data.binaryheap.elements[i - 1] every time, we use this define.
+#define BIN_HEAP_ARR(i) q->data.binaryheap.elements[((i) - 1) >> BINARY_HEAP_BLOCKSIZE_BITS][((i) - 1) & BINARY_HEAP_BLOCKSIZE_MASK]
+
+static void BinaryHeap_Clear(Queue* q, bool free_values)
+{
+ /* Free all items if needed and free all but the first blocks of memory */
+ uint i;
+ uint j;
+
+ for (i = 0; i < q->data.binaryheap.blocks; i++) {
+ if (q->data.binaryheap.elements[i] == NULL) {
+ /* No more allocated blocks */
+ break;
+ }
+ /* For every allocated block */
+ if (free_values) {
+ for (j = 0; j < (1 << BINARY_HEAP_BLOCKSIZE_BITS); j++) {
+ /* For every element in the block */
+ if ((q->data.binaryheap.size >> BINARY_HEAP_BLOCKSIZE_BITS) == i &&
+ (q->data.binaryheap.size & BINARY_HEAP_BLOCKSIZE_MASK) == j) {
+ break; /* We're past the last element */
+ }
+ free(q->data.binaryheap.elements[i][j].item);
+ }
+ }
+ if (i != 0) {
+ /* Leave the first block of memory alone */
+ free(q->data.binaryheap.elements[i]);
+ q->data.binaryheap.elements[i] = NULL;
+ }
+ }
+ q->data.binaryheap.size = 0;
+ q->data.binaryheap.blocks = 1;
+}
+
+static void BinaryHeap_Free(Queue* q, bool free_values)
+{
+ uint i;
+
+ q->clear(q, free_values);
+ for (i = 0; i < q->data.binaryheap.blocks; i++) {
+ if (q->data.binaryheap.elements[i] == NULL) break;
+ free(q->data.binaryheap.elements[i]);
+ }
+ free(q->data.binaryheap.elements);
+ if (q->freeq) free(q);
+}
+
+static bool BinaryHeap_Push(Queue* q, void* item, int priority)
+{
+#ifdef QUEUE_DEBUG
+ printf("[BinaryHeap] Pushing an element. There are %d elements left\n", q->data.binaryheap.size);
+#endif
+
+ if (q->data.binaryheap.size == q->data.binaryheap.max_size) return false;
+ assert(q->data.binaryheap.size < q->data.binaryheap.max_size);
+
+ if (q->data.binaryheap.elements[q->data.binaryheap.size >> BINARY_HEAP_BLOCKSIZE_BITS] == NULL) {
+ /* The currently allocated blocks are full, allocate a new one */
+ assert((q->data.binaryheap.size & BINARY_HEAP_BLOCKSIZE_MASK) == 0);
+ q->data.binaryheap.elements[q->data.binaryheap.size >> BINARY_HEAP_BLOCKSIZE_BITS] = malloc(BINARY_HEAP_BLOCKSIZE * sizeof(*q->data.binaryheap.elements[0]));
+ q->data.binaryheap.blocks++;
+#ifdef QUEUE_DEBUG
+ printf("[BinaryHeap] Increasing size of elements to %d nodes\n", q->data.binaryheap.blocks * BINARY_HEAP_BLOCKSIZE);
+#endif
+ }
+
+ // Add the item at the end of the array
+ BIN_HEAP_ARR(q->data.binaryheap.size + 1).priority = priority;
+ BIN_HEAP_ARR(q->data.binaryheap.size + 1).item = item;
+ q->data.binaryheap.size++;
+
+ // Now we are going to check where it belongs. As long as the parent is
+ // bigger, we switch with the parent
+ {
+ BinaryHeapNode temp;
+ int i;
+ int j;
+
+ i = q->data.binaryheap.size;
+ while (i > 1) {
+ // Get the parent of this object (divide by 2)
+ j = i / 2;
+ // Is the parent bigger then the current, switch them
+ if (BIN_HEAP_ARR(i).priority <= BIN_HEAP_ARR(j).priority) {
+ temp = BIN_HEAP_ARR(j);
+ BIN_HEAP_ARR(j) = BIN_HEAP_ARR(i);
+ BIN_HEAP_ARR(i) = temp;
+ i = j;
+ } else {
+ // It is not, we're done!
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+static bool BinaryHeap_Delete(Queue* q, void* item, int priority)
+{
+ uint i = 0;
+
+#ifdef QUEUE_DEBUG
+ printf("[BinaryHeap] Deleting an element. There are %d elements left\n", q->data.binaryheap.size);
+#endif
+
+ // First, we try to find the item..
+ do {
+ if (BIN_HEAP_ARR(i + 1).item == item) break;
+ i++;
+ } while (i < q->data.binaryheap.size);
+ // We did not find the item, so we return false
+ if (i == q->data.binaryheap.size) return false;
+
+ // Now we put the last item over the current item while decreasing the size of the elements
+ q->data.binaryheap.size--;
+ BIN_HEAP_ARR(i + 1) = BIN_HEAP_ARR(q->data.binaryheap.size + 1);
+
+ // Now the only thing we have to do, is resort it..
+ // On place i there is the item to be sorted.. let's start there
+ {
+ uint j;
+ BinaryHeapNode temp;
+ /* Because of the fact that Binary Heap uses array from 1 to n, we need to
+ * increase i by 1
+ */
+ i++;
+
+ for (;;) {
+ j = i;
+ // Check if we have 2 childs
+ if (2 * j + 1 <= q->data.binaryheap.size) {
+ // Is this child smaller than the parent?
+ if (BIN_HEAP_ARR(j).priority >= BIN_HEAP_ARR(2 * j).priority) i = 2 * j;
+ // Yes, we _need_ to use i here, not j, because we want to have the smallest child
+ // This way we get that straight away!
+ if (BIN_HEAP_ARR(i).priority >= BIN_HEAP_ARR(2 * j + 1).priority) i = 2 * j + 1;
+ // Do we have one child?
+ } else if (2 * j <= q->data.binaryheap.size) {
+ if (BIN_HEAP_ARR(j).priority >= BIN_HEAP_ARR(2 * j).priority) i = 2 * j;
+ }
+
+ // One of our childs is smaller than we are, switch
+ if (i != j) {
+ temp = BIN_HEAP_ARR(j);
+ BIN_HEAP_ARR(j) = BIN_HEAP_ARR(i);
+ BIN_HEAP_ARR(i) = temp;
+ } else {
+ // None of our childs is smaller, so we stay here.. stop :)
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+static void* BinaryHeap_Pop(Queue* q)
+{
+ void* result;
+
+#ifdef QUEUE_DEBUG
+ printf("[BinaryHeap] Popping an element. There are %d elements left\n", q->data.binaryheap.size);
+#endif
+
+ if (q->data.binaryheap.size == 0) return NULL;
+
+ // The best item is always on top, so give that as result
+ result = BIN_HEAP_ARR(1).item;
+ // And now we should get rid of this item...
+ BinaryHeap_Delete(q, BIN_HEAP_ARR(1).item, BIN_HEAP_ARR(1).priority);
+
+ return result;
+}
+
+void init_BinaryHeap(Queue* q, uint max_size)
+{
+ assert(q != NULL);
+ q->push = BinaryHeap_Push;
+ q->pop = BinaryHeap_Pop;
+ q->del = BinaryHeap_Delete;
+ q->clear = BinaryHeap_Clear;
+ q->free = BinaryHeap_Free;
+ q->data.binaryheap.max_size = max_size;
+ q->data.binaryheap.size = 0;
+ // We malloc memory in block of BINARY_HEAP_BLOCKSIZE
+ // It autosizes when it runs out of memory
+ q->data.binaryheap.elements = calloc((max_size - 1) / BINARY_HEAP_BLOCKSIZE + 1, sizeof(*q->data.binaryheap.elements));
+ q->data.binaryheap.elements[0] = malloc(BINARY_HEAP_BLOCKSIZE * sizeof(*q->data.binaryheap.elements[0]));
+ q->data.binaryheap.blocks = 1;
+ q->freeq = false;
+#ifdef QUEUE_DEBUG
+ printf("[BinaryHeap] Initial size of elements is %d nodes\n", BINARY_HEAP_BLOCKSIZE);
+#endif
+}
+
+Queue* new_BinaryHeap(uint max_size)
+{
+ Queue* q = malloc(sizeof(*q));
+
+ init_BinaryHeap(q, max_size);
+ q->freeq = true;
+ return q;
+}
+
+// Because we don't want anyone else to bother with our defines
+#undef BIN_HEAP_ARR
+
+/*
+ * Hash
+ */
+
+void init_Hash(Hash* h, Hash_HashProc* hash, uint num_buckets)
+{
+ /* Allocate space for the Hash, the buckets and the bucket flags */
+ uint i;
+
+ assert(h != NULL);
+#ifdef HASH_DEBUG
+ debug("Allocated hash: %p", h);
+#endif
+ h->hash = hash;
+ h->size = 0;
+ h->num_buckets = num_buckets;
+ h->buckets = malloc(num_buckets * (sizeof(*h->buckets) + sizeof(*h->buckets_in_use)));
+#ifdef HASH_DEBUG
+ debug("Buckets = %p", h->buckets);
+#endif
+ h->buckets_in_use = (bool*)(h->buckets + num_buckets);
+ h->freeh = false;
+ for (i = 0; i < num_buckets; i++) h->buckets_in_use[i] = false;
+}
+
+Hash* new_Hash(Hash_HashProc* hash, int num_buckets)
+{
+ Hash* h = malloc(sizeof(*h));
+
+ init_Hash(h, hash, num_buckets);
+ h->freeh = true;
+ return h;
+}
+
+void delete_Hash(Hash* h, bool free_values)
+{
+ uint i;
+
+ /* Iterate all buckets */
+ for (i = 0; i < h->num_buckets; i++) {
+ if (h->buckets_in_use[i]) {
+ HashNode* node;
+
+ /* Free the first value */
+ if (free_values) free(h->buckets[i].value);
+ node = h->buckets[i].next;
+ while (node != NULL) {
+ HashNode* prev = node;
+
+ node = node->next;
+ /* Free the value */
+ if (free_values) free(prev->value);
+ /* Free the node */
+ free(prev);
+ }
+ }
+ }
+ free(h->buckets);
+ /* No need to free buckets_in_use, it is always allocated in one
+ * malloc with buckets */
+#ifdef HASH_DEBUG
+ debug("Freeing Hash: %p", h);
+#endif
+ if (h->freeh) free(h);
+}
+
+#ifdef HASH_STATS
+static void stat_Hash(const Hash* h)
+{
+ uint used_buckets = 0;
+ uint max_collision = 0;
+ uint max_usage = 0;
+ uint usage[200];
+ uint i;
+
+ for (i = 0; i < lengthof(usage); i++) usage[i] = 0;
+ for (i = 0; i < h->num_buckets; i++) {
+ uint collision = 0;
+ if (h->buckets_in_use[i]) {
+ const HashNode* node;
+
+ used_buckets++;
+ for (node = &h->buckets[i]; node != NULL; node = node->next) collision++;
+ if (collision > max_collision) max_collision = collision;
+ }
+ if (collision >= lengthof(usage)) collision = lengthof(usage) - 1;
+ usage[collision]++;
+ if (collision > 0 && usage[collision] >= max_usage) {
+ max_usage = usage[collision];
+ }
+ }
+ printf(
+ "---\n"
+ "Hash size: %d\n"
+ "Nodes used: %d\n"
+ "Non empty buckets: %d\n"
+ "Max collision: %d\n",
+ h->num_buckets, h->size, used_buckets, max_collision
+ );
+ printf("{ ");
+ for (i = 0; i <= max_collision; i++) {
+ if (usage[i] > 0) {
+ printf("%d:%d ", i, usage[i]);
+#if 0
+ if (i > 0) {
+ uint j;
+
+ for (j = 0; j < usage[i] * 160 / 800; j++) putchar('#');
+ }
+ printf("\n");
+#endif
+ }
+ }
+ printf ("}\n");
+}
+#endif
+
+void clear_Hash(Hash* h, bool free_values)
+{
+ uint i;
+
+#ifdef HASH_STATS
+ if (h->size > 2000) stat_Hash(h);
+#endif
+
+ /* Iterate all buckets */
+ for (i = 0; i < h->num_buckets; i++) {
+ if (h->buckets_in_use[i]) {
+ HashNode* node;
+
+ h->buckets_in_use[i] = false;
+ /* Free the first value */
+ if (free_values) free(h->buckets[i].value);
+ node = h->buckets[i].next;
+ while (node != NULL) {
+ HashNode* prev = node;
+
+ node = node->next;
+ if (free_values) free(prev->value);
+ free(prev);
+ }
+ }
+ }
+ h->size = 0;
+}
+
+/* Finds the node that that saves this key pair. If it is not
+ * found, returns NULL. If it is found, *prev is set to the
+ * node before the one found, or if the node found was the first in the bucket
+ * to NULL. If it is not found, *prev is set to the last HashNode in the
+ * bucket, or NULL if it is empty. prev can also be NULL, in which case it is
+ * not used for output.
+ */
+static HashNode* Hash_FindNode(const Hash* h, uint key1, uint key2, HashNode** prev_out)
+{
+ uint hash = h->hash(key1, key2);
+ HashNode* result = NULL;
+
+#ifdef HASH_DEBUG
+ debug("Looking for %u, %u", key1, key2);
+#endif
+ /* Check if the bucket is empty */
+ if (!h->buckets_in_use[hash]) {
+ if (prev_out != NULL) *prev_out = NULL;
+ result = NULL;
+ /* Check the first node specially */
+ } else if (h->buckets[hash].key1 == key1 && h->buckets[hash].key2 == key2) {
+ /* Save the value */
+ result = h->buckets + hash;
+ if (prev_out != NULL) *prev_out = NULL;
+#ifdef HASH_DEBUG
+ debug("Found in first node: %p", result);
+#endif
+ /* Check all other nodes */
+ } else {
+ HashNode* prev = h->buckets + hash;
+ HashNode* node;
+
+ for (node = prev->next; node != NULL; node = node->next) {
+ if (node->key1 == key1 && node->key2 == key2) {
+ /* Found it */
+ result = node;
+#ifdef HASH_DEBUG
+ debug("Found in other node: %p", result);
+#endif
+ break;
+ }
+ prev = node;
+ }
+ if (prev_out != NULL) *prev_out = prev;
+ }
+#ifdef HASH_DEBUG
+ if (result == NULL) debug("Not found");
+#endif
+ return result;
+}
+
+void* Hash_Delete(Hash* h, uint key1, uint key2)
+{
+ void* result;
+ HashNode* prev; /* Used as output var for below function call */
+ HashNode* node = Hash_FindNode(h, key1, key2, &prev);
+
+ if (node == NULL) {
+ /* not found */
+ result = NULL;
+ } else if (prev == NULL) {
+ /* It is in the first node, we can't free that one, so we free
+ * the next one instead (if there is any)*/
+ /* Save the value */
+ result = node->value;
+ if (node->next != NULL) {
+ HashNode* next = node->next;
+ /* Copy the second to the first */
+ *node = *next;
+ /* Free the second */
+#ifndef NOFREE
+ free(next);
+#endif
+ } else {
+ /* This was the last in this bucket */
+ /* Mark it as empty */
+ uint hash = h->hash(key1, key2);
+ h->buckets_in_use[hash] = false;
+ }
+ } else {
+ /* It is in another node */
+ /* Save the value */
+ result = node->value;
+ /* Link previous and next nodes */
+ prev->next = node->next;
+ /* Free the node */
+#ifndef NOFREE
+ free(node);
+#endif
+ }
+ if (result != NULL) h->size--;
+ return result;
+}
+
+
+void* Hash_Set(Hash* h, uint key1, uint key2, void* value)
+{
+ HashNode* prev;
+ HashNode* node = Hash_FindNode(h, key1, key2, &prev);
+
+ if (node != NULL) {
+ /* Found it */
+ void* result = node->value;
+
+ node->value = value;
+ return result;
+ }
+ /* It is not yet present, let's add it */
+ if (prev == NULL) {
+ /* The bucket is still empty */
+ uint hash = h->hash(key1, key2);
+ h->buckets_in_use[hash] = true;
+ node = h->buckets + hash;
+ } else {
+ /* Add it after prev */
+ node = malloc(sizeof(*node));
+ prev->next = node;
+ }
+ node->next = NULL;
+ node->key1 = key1;
+ node->key2 = key2;
+ node->value = value;
+ h->size++;
+ return NULL;
+}
+
+void* Hash_Get(const Hash* h, uint key1, uint key2)
+{
+ HashNode* node = Hash_FindNode(h, key1, key2, NULL);
+
+#ifdef HASH_DEBUG
+ debug("Found node: %p", node);
+#endif
+ return (node != NULL) ? node->value : NULL;
+}
+
+uint Hash_Size(const Hash* h)
+{
+ return h->size;
+}
diff --git a/src/queue.h b/src/queue.h
new file mode 100644
index 000000000..1bbdf353c
--- /dev/null
+++ b/src/queue.h
@@ -0,0 +1,208 @@
+/* $Id$ */
+
+#ifndef QUEUE_H
+#define QUEUE_H
+
+//#define NOFREE
+//#define QUEUE_DEBUG
+//#define HASH_DEBUG
+//#define HASH_STATS
+
+
+typedef struct Queue Queue;
+typedef bool Queue_PushProc(Queue* q, void* item, int priority);
+typedef void* Queue_PopProc(Queue* q);
+typedef bool Queue_DeleteProc(Queue* q, void* item, int priority);
+typedef void Queue_ClearProc(Queue* q, bool free_values);
+typedef void Queue_FreeProc(Queue* q, bool free_values);
+
+typedef struct InsSortNode InsSortNode;
+struct InsSortNode {
+ void* item;
+ int priority;
+ InsSortNode* next;
+};
+
+typedef struct BinaryHeapNode BinaryHeapNode;
+struct BinaryHeapNode {
+ void* item;
+ int priority;
+};
+
+
+struct Queue{
+ /*
+ * Pushes an element into the queue, at the appropriate place for the queue.
+ * Requires the queue pointer to be of an appropriate type, of course.
+ */
+ Queue_PushProc* push;
+ /*
+ * Pops the first element from the queue. What exactly is the first element,
+ * is defined by the exact type of queue.
+ */
+ Queue_PopProc* pop;
+ /*
+ * Deletes the item from the queue. priority should be specified if
+ * known, which speeds up the deleting for some queue's. Should be -1
+ * if not known.
+ */
+ Queue_DeleteProc* del;
+
+ /* Clears the queue, by removing all values from it. It's state is
+ * effectively reset. If free_items is true, each of the items cleared
+ * in this way are free()'d.
+ */
+ Queue_ClearProc* clear;
+ /* Frees the queue, by reclaiming all memory allocated by it. After
+ * this it is no longer usable. If free_items is true, any remaining
+ * items are free()'d too.
+ */
+ Queue_FreeProc* free;
+
+ union {
+ struct {
+ uint max_size;
+ uint size;
+ void** elements;
+ } stack;
+ struct {
+ uint max_size;
+ uint head; /* The index where the last element should be inserted */
+ uint tail; /* The index where the next element should be read */
+ void** elements;
+ } fifo;
+ struct {
+ InsSortNode* first;
+ } inssort;
+ struct {
+ uint max_size;
+ uint size;
+ uint blocks; /* The amount of blocks for which space is reserved in elements */
+ BinaryHeapNode** elements;
+ } binaryheap;
+ } data;
+
+ /* If true, this struct will be free'd when the
+ * Queue is deleted. */
+ bool freeq;
+};
+
+/* Initializes a stack and allocates internal memory. */
+void init_Stack(Queue* q, uint max_size);
+
+/* Allocate a new stack with a maximum of max_size elements. */
+Queue* new_Stack(uint max_size);
+
+/*
+ * Fifo
+ */
+
+/* Initializes a fifo and allocates internal memory for maximum of max_size
+ * elements */
+void init_Fifo(Queue* q, uint max_size);
+
+/* Allocate a new fifo and initializes it with a maximum of max_size elements. */
+Queue* new_Fifo(uint max_size);
+
+Queue* new_Fifo_in_buffer(uint max_size, void* buffer);
+
+int build_Fifo(void* buffer, uint size);
+
+/*
+ * Insertion Sorter
+ */
+
+/* Initializes a inssort and allocates internal memory. There is no maximum
+ * size */
+void init_InsSort(Queue* q);
+
+/* Allocate a new fifo and initializes it. There is no maximum size */
+Queue* new_InsSort(void);
+
+/*
+ * Binary Heap
+ * For information, see:
+ * http://www.policyalmanac.org/games/binaryHeaps.htm
+ */
+
+/* The amount of elements that will be malloc'd at a time */
+#define BINARY_HEAP_BLOCKSIZE_BITS 10
+
+/* Initializes a binary heap and allocates internal memory for maximum of
+ * max_size elements */
+void init_BinaryHeap(Queue* q, uint max_size);
+
+/* Allocate a new binary heap and initializes it with a maximum of max_size
+ * elements. */
+Queue* new_BinaryHeap(uint max_size);
+
+/*
+ * Hash
+ */
+typedef struct HashNode HashNode;
+struct HashNode {
+ uint key1;
+ uint key2;
+ void* value;
+ HashNode* next;
+};
+/**
+ * Generates a hash code from the given key pair. You should make sure that
+ * the resulting range is clearly defined.
+ */
+typedef uint Hash_HashProc(uint key1, uint key2);
+typedef struct Hash {
+ /* The hash function used */
+ Hash_HashProc* hash;
+ /* The amount of items in the hash */
+ uint size;
+ /* The number of buckets allocated */
+ uint num_buckets;
+ /* A pointer to an array of num_buckets buckets. */
+ HashNode* buckets;
+ /* A pointer to an array of numbuckets booleans, which will be true if
+ * there are any Nodes in the bucket */
+ bool* buckets_in_use;
+ /* If true, buckets will be freed in delete_hash */
+ bool freeb;
+ /* If true, the pointer to this struct will be freed in delete_hash */
+ bool freeh;
+} Hash;
+
+/* Call these function to manipulate a hash */
+
+/* Deletes the value with the specified key pair from the hash and returns
+ * that value. Returns NULL when the value was not present. The value returned
+ * is _not_ free()'d! */
+void* Hash_Delete(Hash* h, uint key1, uint key2);
+/* Sets the value associated with the given key pair to the given value.
+ * Returns the old value if the value was replaced, NULL when it was not yet present. */
+void* Hash_Set(Hash* h, uint key1, uint key2, void* value);
+/* Gets the value associated with the given key pair, or NULL when it is not
+ * present. */
+void* Hash_Get(const Hash* h, uint key1, uint key2);
+
+/* Call these function to create/destroy a hash */
+
+/* Builds a new hash, with num_buckets buckets. Make sure that hash() always
+ * returns a hash less than num_buckets! Call delete_hash after use */
+Hash* new_Hash(Hash_HashProc* hash, int num_buckets);
+/* Builds a new hash in an existing struct. Make sure that hash() always
+ * returns a hash less than num_buckets! Call delete_hash after use */
+void init_Hash(Hash* h, Hash_HashProc* hash, uint num_buckets);
+/*
+ * Deletes the hash and cleans up. Only cleans up memory allocated by new_Hash
+ * & friends. If free is true, it will call free() on all the values that
+ * are left in the hash.
+ */
+void delete_Hash(Hash* h, bool free_values);
+/*
+ * Cleans the hash, but keeps the memory allocated
+ */
+void clear_Hash(Hash* h, bool free_values);
+/*
+ * Gets the current size of the Hash
+ */
+uint Hash_Size(const Hash* h);
+
+#endif /* QUEUE_H */
diff --git a/src/rail.c b/src/rail.c
new file mode 100644
index 000000000..c4b20de27
--- /dev/null
+++ b/src/rail.c
@@ -0,0 +1,132 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "bridge_map.h"
+#include "rail.h"
+#include "station_map.h"
+#include "tunnel_map.h"
+
+/* XXX: Below 3 tables store duplicate data. Maybe remove some? */
+/* Maps a trackdir to the bit that stores its status in the map arrays, in the
+ * direction along with the trackdir */
+const byte _signal_along_trackdir[] = {
+ 0x80, 0x80, 0x80, 0x20, 0x40, 0x10, 0, 0,
+ 0x40, 0x40, 0x40, 0x10, 0x80, 0x20
+};
+
+/* Maps a trackdir to the bit that stores its status in the map arrays, in the
+ * direction against the trackdir */
+const byte _signal_against_trackdir[] = {
+ 0x40, 0x40, 0x40, 0x10, 0x80, 0x20, 0, 0,
+ 0x80, 0x80, 0x80, 0x20, 0x40, 0x10
+};
+
+/* Maps a Track to the bits that store the status of the two signals that can
+ * be present on the given track */
+const byte _signal_on_track[] = {
+ 0xC0, 0xC0, 0xC0, 0x30, 0xC0, 0x30
+};
+
+/* Maps a diagonal direction to the all trackdirs that are connected to any
+ * track entering in this direction (including those making 90 degree turns)
+ */
+const TrackdirBits _exitdir_reaches_trackdirs[] = {
+ TRACKDIR_BIT_X_NE | TRACKDIR_BIT_LOWER_E | TRACKDIR_BIT_LEFT_N, /* DIAGDIR_NE */
+ TRACKDIR_BIT_Y_SE | TRACKDIR_BIT_LEFT_S | TRACKDIR_BIT_UPPER_E, /* DIAGDIR_SE */
+ TRACKDIR_BIT_X_SW | TRACKDIR_BIT_UPPER_W | TRACKDIR_BIT_RIGHT_S, /* DIAGDIR_SW */
+ TRACKDIR_BIT_Y_NW | TRACKDIR_BIT_RIGHT_N | TRACKDIR_BIT_LOWER_W /* DIAGDIR_NW */
+};
+
+const Trackdir _next_trackdir[] = {
+ TRACKDIR_X_NE, TRACKDIR_Y_SE, TRACKDIR_LOWER_E, TRACKDIR_UPPER_E, TRACKDIR_RIGHT_S, TRACKDIR_LEFT_S, INVALID_TRACKDIR, INVALID_TRACKDIR,
+ TRACKDIR_X_SW, TRACKDIR_Y_NW, TRACKDIR_LOWER_W, TRACKDIR_UPPER_W, TRACKDIR_RIGHT_N, TRACKDIR_LEFT_N
+};
+
+/* Maps a trackdir to all trackdirs that make 90 deg turns with it. */
+const TrackdirBits _track_crosses_trackdirs[] = {
+ TRACKDIR_BIT_Y_SE | TRACKDIR_BIT_Y_NW, /* TRACK_X */
+ TRACKDIR_BIT_X_NE | TRACKDIR_BIT_X_SW, /* TRACK_Y */
+ TRACKDIR_BIT_RIGHT_N | TRACKDIR_BIT_RIGHT_S | TRACKDIR_BIT_LEFT_N | TRACKDIR_BIT_LEFT_S, /* TRACK_UPPER */
+ TRACKDIR_BIT_RIGHT_N | TRACKDIR_BIT_RIGHT_S | TRACKDIR_BIT_LEFT_N | TRACKDIR_BIT_LEFT_S, /* TRACK_LOWER */
+ TRACKDIR_BIT_UPPER_W | TRACKDIR_BIT_UPPER_E | TRACKDIR_BIT_LOWER_W | TRACKDIR_BIT_LOWER_E, /* TRACK_LEFT */
+ TRACKDIR_BIT_UPPER_W | TRACKDIR_BIT_UPPER_E | TRACKDIR_BIT_LOWER_W | TRACKDIR_BIT_LOWER_E /* TRACK_RIGHT */
+};
+
+/* Maps a track to all tracks that make 90 deg turns with it. */
+const TrackBits _track_crosses_tracks[] = {
+ TRACK_BIT_Y, /* TRACK_X */
+ TRACK_BIT_X, /* TRACK_Y */
+ TRACK_BIT_VERT, /* TRACK_UPPER */
+ TRACK_BIT_VERT, /* TRACK_LOWER */
+ TRACK_BIT_HORZ, /* TRACK_LEFT */
+ TRACK_BIT_HORZ /* TRACK_RIGHT */
+};
+
+/* Maps a trackdir to the (4-way) direction the tile is exited when following
+ * that trackdir */
+const DiagDirection _trackdir_to_exitdir[] = {
+ DIAGDIR_NE,DIAGDIR_SE,DIAGDIR_NE,DIAGDIR_SE,DIAGDIR_SW,DIAGDIR_SE, DIAGDIR_NE,DIAGDIR_NE,
+ DIAGDIR_SW,DIAGDIR_NW,DIAGDIR_NW,DIAGDIR_SW,DIAGDIR_NW,DIAGDIR_NE,
+};
+
+const Trackdir _track_exitdir_to_trackdir[][DIAGDIR_END] = {
+ {TRACKDIR_X_NE, INVALID_TRACKDIR, TRACKDIR_X_SW, INVALID_TRACKDIR},
+ {INVALID_TRACKDIR, TRACKDIR_Y_SE, INVALID_TRACKDIR, TRACKDIR_Y_NW},
+ {TRACKDIR_UPPER_E, INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_UPPER_W},
+ {INVALID_TRACKDIR, TRACKDIR_LOWER_E, TRACKDIR_LOWER_W, INVALID_TRACKDIR},
+ {INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_LEFT_S, TRACKDIR_LEFT_N},
+ {TRACKDIR_RIGHT_N, TRACKDIR_RIGHT_S, INVALID_TRACKDIR, INVALID_TRACKDIR}
+};
+
+const Trackdir _track_enterdir_to_trackdir[][DIAGDIR_END] = { // TODO: replace magic with enums
+ {TRACKDIR_X_NE, INVALID_TRACKDIR, TRACKDIR_X_SW, INVALID_TRACKDIR},
+ {INVALID_TRACKDIR, TRACKDIR_Y_SE, INVALID_TRACKDIR, TRACKDIR_Y_NW},
+ {INVALID_TRACKDIR, TRACKDIR_UPPER_E, TRACKDIR_UPPER_W, INVALID_TRACKDIR},
+ {TRACKDIR_LOWER_E, INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_LOWER_W},
+ {TRACKDIR_LEFT_N, TRACKDIR_LEFT_S, INVALID_TRACKDIR, INVALID_TRACKDIR},
+ {INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_RIGHT_S, TRACKDIR_RIGHT_N}
+};
+
+const Trackdir _track_direction_to_trackdir[][DIR_END] = {
+ {INVALID_TRACKDIR, TRACKDIR_X_NE, INVALID_TRACKDIR, INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_X_SW, INVALID_TRACKDIR, INVALID_TRACKDIR},
+ {INVALID_TRACKDIR, INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_Y_SE, INVALID_TRACKDIR, INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_Y_NW},
+ {INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_UPPER_E, INVALID_TRACKDIR, INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_UPPER_W, INVALID_TRACKDIR},
+ {INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_LOWER_E, INVALID_TRACKDIR, INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_LOWER_W, INVALID_TRACKDIR},
+ {TRACKDIR_LEFT_N, INVALID_TRACKDIR, INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_LEFT_S, INVALID_TRACKDIR, INVALID_TRACKDIR, INVALID_TRACKDIR},
+ {TRACKDIR_RIGHT_N, INVALID_TRACKDIR, INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_RIGHT_S, INVALID_TRACKDIR, INVALID_TRACKDIR, INVALID_TRACKDIR}
+};
+
+const Trackdir _dir_to_diag_trackdir[] = {
+ TRACKDIR_X_NE, TRACKDIR_Y_SE, TRACKDIR_X_SW, TRACKDIR_Y_NW,
+};
+
+
+RailType GetTileRailType(TileIndex tile, Trackdir trackdir)
+{
+ switch (GetTileType(tile)) {
+ case MP_RAILWAY:
+ return GetRailType(tile);
+
+ case MP_STREET:
+ /* rail/road crossing */
+ if (IsLevelCrossing(tile)) return GetRailTypeCrossing(tile);
+ break;
+
+ case MP_STATION:
+ if (IsRailwayStationTile(tile)) return GetRailType(tile);
+ break;
+
+ case MP_TUNNELBRIDGE:
+ if (IsTunnel(tile)) {
+ if (GetTunnelTransportType(tile) == TRANSPORT_RAIL) return GetRailType(tile);
+ } else {
+ if (GetBridgeTransportType(tile) == TRANSPORT_RAIL) return GetRailType(tile);
+ }
+ break;
+
+ default:
+ break;
+ }
+ return INVALID_RAILTYPE;
+}
diff --git a/src/rail.h b/src/rail.h
new file mode 100644
index 000000000..37270a1bf
--- /dev/null
+++ b/src/rail.h
@@ -0,0 +1,471 @@
+/* $Id$ */
+
+/** @file rail.h */
+
+#ifndef RAIL_H
+#define RAIL_H
+
+#include "direction.h"
+#include "tile.h"
+
+typedef enum RailTypes {
+ RAILTYPE_RAIL = 0,
+ RAILTYPE_ELECTRIC = 1,
+ RAILTYPE_MONO = 2,
+ RAILTYPE_MAGLEV = 3,
+ RAILTYPE_END,
+ INVALID_RAILTYPE = 0xFF
+} RailType;
+
+typedef byte RailTypeMask;
+
+
+/** These are used to specify a single track.
+ * Can be translated to a trackbit with TrackToTrackbit */
+typedef enum Track {
+ TRACK_X = 0,
+ TRACK_Y = 1,
+ TRACK_UPPER = 2,
+ TRACK_LOWER = 3,
+ TRACK_LEFT = 4,
+ TRACK_RIGHT = 5,
+ TRACK_END,
+ INVALID_TRACK = 0xFF
+} Track;
+
+
+/** Convert an Axis to the corresponding Track
+ * AXIS_X -> TRACK_X
+ * AXIS_Y -> TRACK_Y
+ * Uses the fact that they share the same internal encoding
+ */
+static inline Track AxisToTrack(Axis a)
+{
+ return (Track)a;
+}
+
+
+/** Bitfield corresponding to Track */
+typedef enum TrackBits {
+ TRACK_BIT_NONE = 0U,
+ TRACK_BIT_X = 1U << TRACK_X,
+ TRACK_BIT_Y = 1U << TRACK_Y,
+ TRACK_BIT_UPPER = 1U << TRACK_UPPER,
+ TRACK_BIT_LOWER = 1U << TRACK_LOWER,
+ TRACK_BIT_LEFT = 1U << TRACK_LEFT,
+ TRACK_BIT_RIGHT = 1U << TRACK_RIGHT,
+ TRACK_BIT_CROSS = TRACK_BIT_X | TRACK_BIT_Y,
+ TRACK_BIT_HORZ = TRACK_BIT_UPPER | TRACK_BIT_LOWER,
+ TRACK_BIT_VERT = TRACK_BIT_LEFT | TRACK_BIT_RIGHT,
+ TRACK_BIT_3WAY_NE = TRACK_BIT_X | TRACK_BIT_UPPER | TRACK_BIT_RIGHT,
+ TRACK_BIT_3WAY_SE = TRACK_BIT_Y | TRACK_BIT_LOWER | TRACK_BIT_RIGHT,
+ TRACK_BIT_3WAY_SW = TRACK_BIT_X | TRACK_BIT_LOWER | TRACK_BIT_LEFT,
+ TRACK_BIT_3WAY_NW = TRACK_BIT_Y | TRACK_BIT_UPPER | TRACK_BIT_LEFT,
+ TRACK_BIT_ALL = TRACK_BIT_CROSS | TRACK_BIT_HORZ | TRACK_BIT_VERT,
+ TRACK_BIT_MASK = 0x3FU
+} TrackBits;
+
+
+/**
+ * Maps a Track to the corresponding TrackBits value
+ */
+static inline TrackBits TrackToTrackBits(Track track)
+{
+ return (TrackBits)(1 << track);
+}
+
+
+static inline TrackBits AxisToTrackBits(Axis a)
+{
+ return TrackToTrackBits(AxisToTrack(a));
+}
+
+
+/** These are a combination of tracks and directions. Values are 0-5 in one
+ * direction (corresponding to the Track enum) and 8-13 in the other direction. */
+typedef enum Trackdirs {
+ TRACKDIR_X_NE = 0,
+ TRACKDIR_Y_SE = 1,
+ TRACKDIR_UPPER_E = 2,
+ TRACKDIR_LOWER_E = 3,
+ TRACKDIR_LEFT_S = 4,
+ TRACKDIR_RIGHT_S = 5,
+ /* Note the two missing values here. This enables trackdir -> track
+ * conversion by doing (trackdir & 7) */
+ TRACKDIR_X_SW = 8,
+ TRACKDIR_Y_NW = 9,
+ TRACKDIR_UPPER_W = 10,
+ TRACKDIR_LOWER_W = 11,
+ TRACKDIR_LEFT_N = 12,
+ TRACKDIR_RIGHT_N = 13,
+ TRACKDIR_END,
+ INVALID_TRACKDIR = 0xFF,
+} Trackdir;
+
+/** These are a combination of tracks and directions. Values are 0-5 in one
+ * direction (corresponding to the Track enum) and 8-13 in the other direction. */
+typedef enum TrackdirBits {
+ TRACKDIR_BIT_NONE = 0x0000,
+ TRACKDIR_BIT_X_NE = 0x0001,
+ TRACKDIR_BIT_Y_SE = 0x0002,
+ TRACKDIR_BIT_UPPER_E = 0x0004,
+ TRACKDIR_BIT_LOWER_E = 0x0008,
+ TRACKDIR_BIT_LEFT_S = 0x0010,
+ TRACKDIR_BIT_RIGHT_S = 0x0020,
+ /* Again, note the two missing values here. This enables trackdir -> track conversion by doing (trackdir & 0xFF) */
+ TRACKDIR_BIT_X_SW = 0x0100,
+ TRACKDIR_BIT_Y_NW = 0x0200,
+ TRACKDIR_BIT_UPPER_W = 0x0400,
+ TRACKDIR_BIT_LOWER_W = 0x0800,
+ TRACKDIR_BIT_LEFT_N = 0x1000,
+ TRACKDIR_BIT_RIGHT_N = 0x2000,
+ TRACKDIR_BIT_MASK = 0x3F3F,
+ INVALID_TRACKDIR_BIT = 0xFFFF,
+} TrackdirBits;
+
+/** This struct contains all the info that is needed to draw and construct tracks.
+ */
+typedef struct RailtypeInfo {
+ /** Struct containing the main sprites. @note not all sprites are listed, but only
+ * the ones used directly in the code */
+ struct {
+ SpriteID track_y; ///< single piece of rail in Y direction, with ground
+ SpriteID track_ns; ///< two pieces of rail in North and South corner (East-West direction)
+ SpriteID ground; ///< ground sprite for a 3-way switch
+ SpriteID single_y; ///< single piece of rail in Y direction, without ground
+ SpriteID single_x; ///< single piece of rail in X direction
+ SpriteID single_n; ///< single piece of rail in the northern corner
+ SpriteID single_s; ///< single piece of rail in the southern corner
+ SpriteID single_e; ///< single piece of rail in the eastern corner
+ SpriteID single_w; ///< single piece of rail in the western corner
+ SpriteID crossing; ///< level crossing, rail in X direction
+ SpriteID tunnel; ///< tunnel sprites base
+ } base_sprites;
+
+ /** struct containing the sprites for the rail GUI. @note only sprites referred to
+ * directly in the code are listed */
+ struct {
+ SpriteID build_ns_rail; ///< button for building single rail in N-S direction
+ SpriteID build_x_rail; ///< button for building single rail in X direction
+ SpriteID build_ew_rail; ///< button for building single rail in E-W direction
+ SpriteID build_y_rail; ///< button for building single rail in Y direction
+ SpriteID auto_rail; ///< button for the autorail construction
+ SpriteID build_depot; ///< button for building depots
+ SpriteID build_tunnel; ///< button for building a tunnel
+ SpriteID convert_rail; ///< button for converting rail
+ } gui_sprites;
+
+ struct {
+ CursorID rail_ns;
+ CursorID rail_swne;
+ CursorID rail_ew;
+ CursorID rail_nwse;
+ CursorID autorail;
+ CursorID depot;
+ CursorID tunnel;
+ CursorID convert;
+ } cursor;
+
+ struct {
+ StringID toolbar_caption;
+ } strings;
+
+ /** sprite number difference between a piece of track on a snowy ground and the corresponding one on normal ground */
+ SpriteID snow_offset;
+
+ /** bitmask to the OTHER railtypes on which an engine of THIS railtype generates power */
+ RailTypeMask powered_railtypes;
+
+ /** bitmask to the OTHER railtypes on which an engine of THIS railtype can physically travel */
+ RailTypeMask compatible_railtypes;
+
+ /**
+ * Offset between the current railtype and normal rail. This means that:<p>
+ * 1) All the sprites in a railset MUST be in the same order. This order
+ * is determined by normal rail. Check sprites 1005 and following for this order<p>
+ * 2) The position where the railtype is loaded must always be the same, otherwise
+ * the offset will fail.<p>
+ * @note: Something more flexible might be desirable in the future.
+ */
+ SpriteID total_offset;
+
+ /**
+ * Bridge offset
+ */
+ SpriteID bridge_offset;
+
+ /**
+ * Offset to add to ground sprite when drawing custom waypoints / stations
+ */
+ byte custom_ground_offset;
+} RailtypeInfo;
+
+extern RailtypeInfo _railtypes[RAILTYPE_END];
+
+// these are the maximums used for updating signal blocks, and checking if a depot is in a pbs block
+enum {
+ NUM_SSD_ENTRY = 256, // max amount of blocks
+ NUM_SSD_STACK = 32, // max amount of blocks to check recursively
+};
+
+/**
+ * Maps a Trackdir to the corresponding TrackdirBits value
+ */
+static inline TrackdirBits TrackdirToTrackdirBits(Trackdir trackdir) { return (TrackdirBits)(1 << trackdir); }
+
+/**
+ * These functions check the validity of Tracks and Trackdirs. assert against
+ * them when convenient.
+ */
+static inline bool IsValidTrack(Track track) { return track < TRACK_END; }
+static inline bool IsValidTrackdir(Trackdir trackdir) { return (TrackdirToTrackdirBits(trackdir) & TRACKDIR_BIT_MASK) != 0; }
+
+/**
+ * Functions to map tracks to the corresponding bits in the signal
+ * presence/status bytes in the map. You should not use these directly, but
+ * wrapper functions below instead. XXX: Which are these?
+ */
+
+/**
+ * Maps a trackdir to the bit that stores its status in the map arrays, in the
+ * direction along with the trackdir.
+ */
+extern const byte _signal_along_trackdir[TRACKDIR_END];
+static inline byte SignalAlongTrackdir(Trackdir trackdir) {return _signal_along_trackdir[trackdir];}
+
+/**
+ * Maps a trackdir to the bit that stores its status in the map arrays, in the
+ * direction against the trackdir.
+ */
+static inline byte SignalAgainstTrackdir(Trackdir trackdir) {
+ extern const byte _signal_against_trackdir[TRACKDIR_END];
+ return _signal_against_trackdir[trackdir];
+}
+
+/**
+ * Maps a Track to the bits that store the status of the two signals that can
+ * be present on the given track.
+ */
+static inline byte SignalOnTrack(Track track) {
+ extern const byte _signal_on_track[TRACK_END];
+ return _signal_on_track[track];
+}
+
+
+/*
+ * Functions describing logical relations between Tracks, TrackBits, Trackdirs
+ * TrackdirBits, Direction and DiagDirections.
+ *
+ * TODO: Add #unndefs or something similar to remove the arrays used below
+ * from the global scope and expose direct uses of them.
+ */
+
+/**
+ * Maps a trackdir to the reverse trackdir.
+ */
+static inline Trackdir ReverseTrackdir(Trackdir trackdir) {
+ return (Trackdir)(trackdir ^ 8);
+}
+
+/**
+ * Returns the Track that a given Trackdir represents
+ */
+static inline Track TrackdirToTrack(Trackdir trackdir) { return (Track)(trackdir & 0x7); }
+
+/**
+ * Returns a Trackdir for the given Track. Since every Track corresponds to
+ * two Trackdirs, we choose the one which points between NE and S.
+ * Note that the actual implementation is quite futile, but this might change
+ * in the future.
+ */
+static inline Trackdir TrackToTrackdir(Track track) { return (Trackdir)track; }
+
+/**
+ * Returns a TrackdirBit mask that contains the two TrackdirBits that
+ * correspond with the given Track (one for each direction).
+ */
+static inline TrackdirBits TrackToTrackdirBits(Track track)
+{
+ Trackdir td = TrackToTrackdir(track);
+ return (TrackdirBits)(TrackdirToTrackdirBits(td) | TrackdirToTrackdirBits(ReverseTrackdir(td)));
+}
+
+/**
+ * Discards all directional information from the given TrackdirBits. Any
+ * Track which is present in either direction will be present in the result.
+ */
+static inline TrackBits TrackdirBitsToTrackBits(TrackdirBits bits)
+{
+ return (TrackBits)((bits | (bits >> 8)) & TRACK_BIT_MASK);
+}
+
+/**
+ * Maps a trackdir to the trackdir that you will end up on if you go straight
+ * ahead. This will be the same trackdir for diagonal trackdirs, but a
+ * different (alternating) one for straight trackdirs
+ */
+static inline Trackdir NextTrackdir(Trackdir trackdir)
+{
+ extern const Trackdir _next_trackdir[TRACKDIR_END];
+ return _next_trackdir[trackdir];
+}
+
+/**
+ * Maps a track to all tracks that make 90 deg turns with it.
+ */
+static inline TrackBits TrackCrossesTracks(Track track)
+{
+ extern const TrackBits _track_crosses_tracks[TRACK_END];
+ return _track_crosses_tracks[track];
+}
+
+/**
+ * Maps a trackdir to the (4-way) direction the tile is exited when following
+ * that trackdir.
+ */
+static inline DiagDirection TrackdirToExitdir(Trackdir trackdir)
+{
+ extern const DiagDirection _trackdir_to_exitdir[TRACKDIR_END];
+ return _trackdir_to_exitdir[trackdir];
+}
+
+/**
+ * Maps a track and an (4-way) dir to the trackdir that represents the track
+ * with the exit in the given direction.
+ */
+static inline Trackdir TrackExitdirToTrackdir(Track track, DiagDirection diagdir)
+{
+ extern const Trackdir _track_exitdir_to_trackdir[TRACK_END][DIAGDIR_END];
+ return _track_exitdir_to_trackdir[track][diagdir];
+}
+
+/**
+ * Maps a track and an (4-way) dir to the trackdir that represents the track
+ * with the exit in the given direction.
+ */
+static inline Trackdir TrackEnterdirToTrackdir(Track track, DiagDirection diagdir)
+{
+ extern const Trackdir _track_enterdir_to_trackdir[TRACK_END][DIAGDIR_END];
+ return _track_enterdir_to_trackdir[track][diagdir];
+}
+
+/**
+ * Maps a track and a full (8-way) direction to the trackdir that represents
+ * the track running in the given direction.
+ */
+static inline Trackdir TrackDirectionToTrackdir(Track track, Direction dir)
+{
+ extern const Trackdir _track_direction_to_trackdir[TRACK_END][DIR_END];
+ return _track_direction_to_trackdir[track][dir];
+}
+
+/**
+ * Maps a (4-way) direction to the diagonal trackdir that runs in that
+ * direction.
+ */
+static inline Trackdir DiagdirToDiagTrackdir(DiagDirection diagdir)
+{
+ extern const Trackdir _dir_to_diag_trackdir[DIAGDIR_END];
+ return _dir_to_diag_trackdir[diagdir];
+}
+
+extern const TrackdirBits _exitdir_reaches_trackdirs[DIAGDIR_END];
+
+/**
+ * Returns all trackdirs that can be reached when entering a tile from a given
+ * (diagonal) direction. This will obviously include 90 degree turns, since no
+ * information is available about the exact angle of entering */
+static inline TrackdirBits DiagdirReachesTrackdirs(DiagDirection diagdir) { return _exitdir_reaches_trackdirs[diagdir]; }
+
+/**
+ * Returns all tracks that can be reached when entering a tile from a given
+ * (diagonal) direction. This will obviously include 90 degree turns, since no
+ * information is available about the exact angle of entering */
+static inline TrackBits DiagdirReachesTracks(DiagDirection diagdir) { return TrackdirBitsToTrackBits(DiagdirReachesTrackdirs(diagdir)); }
+
+/**
+ * Maps a trackdir to the trackdirs that can be reached from it (ie, when
+ * entering the next tile. This will include 90 degree turns!
+ */
+static inline TrackdirBits TrackdirReachesTrackdirs(Trackdir trackdir) { return _exitdir_reaches_trackdirs[TrackdirToExitdir(trackdir)]; }
+/* Note that there is no direct table for this function (there used to be),
+ * but it uses two simpeler tables to achieve the result */
+
+
+/**
+ * Maps a trackdir to all trackdirs that make 90 deg turns with it.
+ */
+static inline TrackdirBits TrackdirCrossesTrackdirs(Trackdir trackdir) {
+ extern const TrackdirBits _track_crosses_trackdirs[TRACKDIR_END];
+ return _track_crosses_trackdirs[TrackdirToTrack(trackdir)];
+}
+
+
+/* Checks if a given Track is diagonal */
+static inline bool IsDiagonalTrack(Track track) { return (track == TRACK_X) || (track == TRACK_Y); }
+
+/* Checks if a given Trackdir is diagonal. */
+static inline bool IsDiagonalTrackdir(Trackdir trackdir) { return IsDiagonalTrack(TrackdirToTrack(trackdir)); }
+
+
+/**
+ * Returns a pointer to the Railtype information for a given railtype
+ * @param railtype the rail type which the information is requested for
+ * @return The pointer to the RailtypeInfo
+ */
+static inline const RailtypeInfo *GetRailTypeInfo(RailType railtype)
+{
+ assert(railtype < RAILTYPE_END);
+ return &_railtypes[railtype];
+}
+
+/**
+ * Checks if an engine of the given RailType can drive on a tile with a given
+ * RailType. This would normally just be an equality check, but for electric
+ * rails (which also support non-electric engines).
+ * @return Whether the engine can drive on this tile.
+ * @param enginetype The RailType of the engine we are considering.
+ * @param tiletype The RailType of the tile we are considering.
+ */
+static inline bool IsCompatibleRail(RailType enginetype, RailType tiletype)
+{
+ return HASBIT(GetRailTypeInfo(enginetype)->compatible_railtypes, tiletype);
+}
+
+static inline bool HasPowerOnRail(RailType enginetype, RailType tiletype)
+{
+ return HASBIT(GetRailTypeInfo(enginetype)->powered_railtypes, tiletype);
+}
+
+/**
+ * Checks if the given tracks overlap, ie form a crossing. Basically this
+ * means when there is more than one track on the tile, exept when there are
+ * two parallel tracks.
+ * @param bits The tracks present.
+ * @return Whether the tracks present overlap in any way.
+ */
+static inline bool TracksOverlap(TrackBits bits)
+{
+ /* With no, or only one track, there is no overlap */
+ if (bits == 0 || KILL_FIRST_BIT(bits) == 0) return false;
+ /* We know that there are at least two tracks present. When there are more
+ * than 2 tracks, they will surely overlap. When there are two, they will
+ * always overlap unless they are lower & upper or right & left. */
+ return bits != TRACK_BIT_HORZ && bits != TRACK_BIT_VERT;
+}
+
+void DrawTrainDepotSprite(int x, int y, int image, RailType railtype);
+void DrawDefaultWaypointSprite(int x, int y, RailType railtype);
+
+/**
+ * Draws overhead wires and pylons for electric railways.
+ * @param ti The TileInfo struct of the tile being drawn
+ * @see DrawCatenaryRailway
+ */
+void DrawCatenary(const TileInfo *ti);
+
+uint GetRailFoundation(Slope tileh, TrackBits bits);
+
+int32 SettingsDisableElrail(int32 p1); ///< _patches.disable_elrail callback
+
+#endif /* RAIL_H */
diff --git a/src/rail_cmd.c b/src/rail_cmd.c
new file mode 100644
index 000000000..a793bb8a5
--- /dev/null
+++ b/src/rail_cmd.c
@@ -0,0 +1,1985 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "bridge_map.h"
+#include "debug.h"
+#include "functions.h"
+#include "rail_map.h"
+#include "road_map.h"
+#include "table/sprites.h"
+#include "table/strings.h"
+#include "map.h"
+#include "tile.h"
+#include "town_map.h"
+#include "tunnel_map.h"
+#include "vehicle.h"
+#include "viewport.h"
+#include "command.h"
+#include "pathfind.h"
+#include "engine.h"
+#include "town.h"
+#include "sound.h"
+#include "station.h"
+#include "sprite.h"
+#include "depot.h"
+#include "waypoint.h"
+#include "window.h"
+#include "rail.h"
+#include "railtypes.h" // include table for railtypes
+#include "newgrf.h"
+#include "yapf/yapf.h"
+#include "newgrf_callbacks.h"
+#include "newgrf_station.h"
+#include "train.h"
+
+const byte _track_sloped_sprites[14] = {
+ 14, 15, 22, 13,
+ 0, 21, 17, 12,
+ 23, 0, 18, 20,
+ 19, 16
+};
+
+
+/* 4
+ * ---------
+ * |\ /|
+ * | \ 1/ |
+ * | \ / |
+ * | \ / |
+ * 16| \ |32
+ * | / \2 |
+ * | / \ |
+ * | / \ |
+ * |/ \|
+ * ---------
+ * 8
+ */
+
+
+
+/* MAP2 byte: abcd???? => Signal On? Same coding as map3lo
+ * MAP3LO byte: abcd???? => Signal Exists?
+ * a and b are for diagonals, upper and left,
+ * one for each direction. (ie a == NE->SW, b ==
+ * SW->NE, or v.v., I don't know. b and c are
+ * similar for lower and right.
+ * MAP2 byte: ????abcd => Type of ground.
+ * MAP3LO byte: ????abcd => Type of rail.
+ * MAP5: 00abcdef => rail
+ * 01abcdef => rail w/ signals
+ * 10uuuuuu => unused
+ * 11uuuudd => rail depot
+ */
+
+static bool CheckTrackCombination(TileIndex tile, TrackBits to_build, uint flags)
+{
+ TrackBits current; /* The current track layout */
+ TrackBits future; /* The track layout we want to build */
+ _error_message = STR_1001_IMPOSSIBLE_TRACK_COMBINATION;
+
+ if (!IsPlainRailTile(tile)) return false;
+
+ /* So, we have a tile with tracks on it (and possibly signals). Let's see
+ * what tracks first */
+ current = GetTrackBits(tile);
+ future = current | to_build;
+
+ /* Are we really building something new? */
+ if (current == future) {
+ /* Nothing new is being built */
+ _error_message = STR_1007_ALREADY_BUILT;
+ return false;
+ }
+
+ /* Let's see if we may build this */
+ if (flags & DC_NO_RAIL_OVERLAP || HasSignals(tile)) {
+ /* If we are not allowed to overlap (flag is on for ai players or we have
+ * signals on the tile), check that */
+ return future == TRACK_BIT_HORZ || future == TRACK_BIT_VERT;
+ } else {
+ /* Normally, we may overlap and any combination is valid */
+ return true;
+ }
+}
+
+
+static const TrackBits _valid_tileh_slopes[][15] = {
+
+// set of normal ones
+{
+ TRACK_BIT_ALL,
+ TRACK_BIT_RIGHT,
+ TRACK_BIT_UPPER,
+ TRACK_BIT_X,
+
+ TRACK_BIT_LEFT,
+ 0,
+ TRACK_BIT_Y,
+ TRACK_BIT_LOWER,
+
+ TRACK_BIT_LOWER,
+ TRACK_BIT_Y,
+ 0,
+ TRACK_BIT_LEFT,
+
+ TRACK_BIT_X,
+ TRACK_BIT_UPPER,
+ TRACK_BIT_RIGHT,
+},
+
+// allowed rail for an evenly raised platform
+{
+ 0,
+ TRACK_BIT_LEFT,
+ TRACK_BIT_LOWER,
+ TRACK_BIT_Y | TRACK_BIT_LOWER | TRACK_BIT_LEFT,
+
+ TRACK_BIT_RIGHT,
+ TRACK_BIT_ALL,
+ TRACK_BIT_X | TRACK_BIT_LOWER | TRACK_BIT_RIGHT,
+ TRACK_BIT_ALL,
+
+ TRACK_BIT_UPPER,
+ TRACK_BIT_X | TRACK_BIT_UPPER | TRACK_BIT_LEFT,
+ TRACK_BIT_ALL,
+ TRACK_BIT_ALL,
+
+ TRACK_BIT_Y | TRACK_BIT_UPPER | TRACK_BIT_RIGHT,
+ TRACK_BIT_ALL,
+ TRACK_BIT_ALL
+}
+};
+
+uint GetRailFoundation(Slope tileh, TrackBits bits)
+{
+ uint i;
+
+ if (!IsSteepSlope(tileh)) {
+ if ((~_valid_tileh_slopes[0][tileh] & bits) == 0) return 0;
+ if ((~_valid_tileh_slopes[1][tileh] & bits) == 0) return tileh;
+ }
+
+ switch (bits) {
+ default: NOT_REACHED();
+ case TRACK_BIT_X: i = 0; break;
+ case TRACK_BIT_Y: i = 1; break;
+ case TRACK_BIT_LEFT: return 15 + 8 + (tileh == SLOPE_STEEP_W ? 4 : 0);
+ case TRACK_BIT_LOWER: return 15 + 8 + (tileh == SLOPE_STEEP_S ? 5 : 1);
+ case TRACK_BIT_RIGHT: return 15 + 8 + (tileh == SLOPE_STEEP_E ? 6 : 2);
+ case TRACK_BIT_UPPER: return 15 + 8 + (tileh == SLOPE_STEEP_N ? 7 : 3);
+ }
+ switch (tileh) {
+ case SLOPE_W:
+ case SLOPE_STEEP_W: i += 0; break;
+ case SLOPE_S:
+ case SLOPE_STEEP_S: i += 2; break;
+ case SLOPE_E:
+ case SLOPE_STEEP_E: i += 4; break;
+ case SLOPE_N:
+ case SLOPE_STEEP_N: i += 6; break;
+ default: return 0;
+ }
+ return i + 15;
+}
+
+
+static uint32 CheckRailSlope(Slope tileh, TrackBits rail_bits, TrackBits existing, TileIndex tile)
+{
+ if (IsSteepSlope(tileh)) {
+ if (existing == 0) {
+ TrackBits valid = TRACK_BIT_CROSS | (HASBIT(1 << SLOPE_STEEP_W | 1 << SLOPE_STEEP_E, tileh) ? TRACK_BIT_VERT : TRACK_BIT_HORZ);
+ if (valid & rail_bits) return _price.terraform;
+ }
+ } else {
+ rail_bits |= existing;
+
+ // don't allow building on the lower side of a coast
+ if (IsTileType(tile, MP_WATER) &&
+ ~_valid_tileh_slopes[1][tileh] & rail_bits) {
+ return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER);
+ }
+
+ // no special foundation
+ if ((~_valid_tileh_slopes[0][tileh] & rail_bits) == 0)
+ return 0;
+
+ if ((~_valid_tileh_slopes[1][tileh] & rail_bits) == 0 || ( // whole tile is leveled up
+ (rail_bits == TRACK_BIT_X || rail_bits == TRACK_BIT_Y) &&
+ (tileh == SLOPE_W || tileh == SLOPE_S || tileh == SLOPE_E || tileh == SLOPE_N)
+ )) { // partly up
+ if (existing != 0) {
+ return 0;
+ } else if (!_patches.build_on_slopes || _is_old_ai_player) {
+ return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
+ } else {
+ return _price.terraform;
+ }
+ }
+ }
+ return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
+}
+
+/* Validate functions for rail building */
+static inline bool ValParamTrackOrientation(Track track) {return IsValidTrack(track);}
+
+/** Build a single piece of rail
+ * @param tile tile to build on
+ * @param p1 railtype of being built piece (normal, mono, maglev)
+ * @param p2 rail track to build
+ */
+int32 CmdBuildSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Slope tileh;
+ RailType railtype;
+ Track track;
+ TrackBits trackbit;
+ int32 cost = 0;
+ int32 ret;
+
+ if (!ValParamRailtype(p1) || !ValParamTrackOrientation(p2)) return CMD_ERROR;
+ railtype = (RailType)p1;
+ track = (Track)p2;
+
+ tileh = GetTileSlope(tile, NULL);
+ trackbit = TrackToTrackBits(track);
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ switch (GetTileType(tile)) {
+ case MP_RAILWAY:
+ if (!CheckTrackCombination(tile, trackbit, flags) ||
+ !EnsureNoVehicle(tile)) {
+ return CMD_ERROR;
+ }
+ if (!IsTileOwner(tile, _current_player) ||
+ !IsCompatibleRail(GetRailType(tile), railtype)) {
+ // Get detailed error message
+ return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+ }
+
+ ret = CheckRailSlope(tileh, trackbit, GetTrackBits(tile), tile);
+ if (CmdFailed(ret)) return ret;
+ cost += ret;
+
+ /* If the rail types don't match, try to convert only if engines of
+ * the present rail type are powered on the new rail type. */
+ if (GetRailType(tile) != railtype && HasPowerOnRail(GetRailType(tile), railtype)) {
+ ret = DoCommand(tile, tile, railtype, flags, CMD_CONVERT_RAIL);
+ if (CmdFailed(ret)) return ret;
+ cost += ret;
+ }
+
+ if (flags & DC_EXEC) {
+ SetRailGroundType(tile, RAIL_GROUND_BARREN);
+ SetTrackBits(tile, GetTrackBits(tile) | trackbit);
+ }
+ break;
+
+ case MP_STREET:
+#define M(x) (1 << (x))
+ /* Level crossings may only be built on these slopes */
+ if (!HASBIT(M(SLOPE_SEN) | M(SLOPE_ENW) | M(SLOPE_NWS) | M(SLOPE_NS) | M(SLOPE_WSE) | M(SLOPE_EW) | M(SLOPE_FLAT), tileh)) {
+ return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
+ }
+#undef M
+
+ if (!EnsureNoVehicle(tile)) return CMD_ERROR;
+
+ if (GetRoadTileType(tile) == ROAD_TILE_NORMAL) {
+ if (HasRoadWorks(tile)) return_cmd_error(STR_ROAD_WORKS_IN_PROGRESS);
+
+ if ((track == TRACK_X && GetRoadBits(tile) == ROAD_Y) ||
+ (track == TRACK_Y && GetRoadBits(tile) == ROAD_X)) {
+ if (flags & DC_EXEC) {
+ MakeRoadCrossing(tile, GetTileOwner(tile), _current_player, (track == TRACK_X ? AXIS_Y : AXIS_X), railtype, GetTownIndex(tile));
+ }
+ break;
+ }
+ }
+
+ if (IsLevelCrossing(tile) && GetCrossingRailBits(tile) == trackbit) {
+ return_cmd_error(STR_1007_ALREADY_BUILT);
+ }
+ /* FALLTHROUGH */
+
+ default:
+ ret = CheckRailSlope(tileh, trackbit, 0, tile);
+ if (CmdFailed(ret)) return ret;
+ cost += ret;
+
+ ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+ if (CmdFailed(ret)) return ret;
+ cost += ret;
+
+ if (flags & DC_EXEC) MakeRailNormal(tile, _current_player, trackbit, railtype);
+ break;
+ }
+
+ if (flags & DC_EXEC) {
+ MarkTileDirtyByTile(tile);
+ SetSignalsOnBothDir(tile, track);
+ YapfNotifyTrackLayoutChange(tile, track);
+ }
+
+ return cost + _price.build_rail;
+}
+
+/** Remove a single piece of track
+ * @param tile tile to remove track from
+ * @param p1 unused
+ * @param p2 rail orientation
+ */
+int32 CmdRemoveSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Track track = (Track)p2;
+ TrackBits trackbit;
+ int32 cost = _price.remove_rail;
+ bool crossing = false;
+
+ if (!ValParamTrackOrientation(p2)) return CMD_ERROR;
+ trackbit = TrackToTrackBits(track);
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ switch (GetTileType(tile)) {
+ case MP_STREET: {
+ if (!IsLevelCrossing(tile) ||
+ GetCrossingRailBits(tile) != trackbit ||
+ (_current_player != OWNER_WATER && !CheckTileOwnership(tile)) ||
+ !EnsureNoVehicle(tile)) {
+ return CMD_ERROR;
+ }
+
+ if (flags & DC_EXEC) {
+ MakeRoadNormal(tile, GetCrossingRoadOwner(tile), GetCrossingRoadBits(tile), GetTownIndex(tile));
+ }
+ break;
+ }
+
+ case MP_RAILWAY: {
+ TrackBits present;
+
+ if (!IsPlainRailTile(tile) ||
+ (_current_player != OWNER_WATER && !CheckTileOwnership(tile)) ||
+ !EnsureNoVehicle(tile)) {
+ return CMD_ERROR;
+ }
+
+ present = GetTrackBits(tile);
+ if ((present & trackbit) == 0) return CMD_ERROR;
+ if (present == (TRACK_BIT_X | TRACK_BIT_Y)) crossing = true;
+
+ /* Charge extra to remove signals on the track, if they are there */
+ if (HasSignalOnTrack(tile, track))
+ cost += DoCommand(tile, track, 0, flags, CMD_REMOVE_SIGNALS);
+
+ if (flags & DC_EXEC) {
+ present ^= trackbit;
+ if (present == 0) {
+ DoClearSquare(tile);
+ } else {
+ SetTrackBits(tile, present);
+ }
+ }
+ break;
+ }
+
+ default: return CMD_ERROR;
+ }
+
+ if (flags & DC_EXEC) {
+ MarkTileDirtyByTile(tile);
+ if (crossing) {
+ /* crossing is set when only TRACK_BIT_X and TRACK_BIT_Y are set. As we
+ * are removing one of these pieces, we'll need to update signals for
+ * both directions explicitly, as after the track is removed it won't
+ * 'connect' with the other piece. */
+ SetSignalsOnBothDir(tile, TRACK_X);
+ SetSignalsOnBothDir(tile, TRACK_Y);
+ YapfNotifyTrackLayoutChange(tile, TRACK_X);
+ YapfNotifyTrackLayoutChange(tile, TRACK_Y);
+ } else {
+ SetSignalsOnBothDir(tile, track);
+ YapfNotifyTrackLayoutChange(tile, track);
+ }
+ }
+
+ return cost;
+}
+
+
+static const TileIndexDiffC _trackdelta[] = {
+ { -1, 0 }, { 0, 1 }, { -1, 0 }, { 0, 1 }, { 1, 0 }, { 0, 1 },
+ { 0, 0 },
+ { 0, 0 },
+ { 1, 0 }, { 0, -1 }, { 0, -1 }, { 1, 0 }, { 0, -1 }, { -1, 0 },
+ { 0, 0 },
+ { 0, 0 }
+};
+
+
+static int32 ValidateAutoDrag(Trackdir *trackdir, TileIndex start, TileIndex end)
+{
+ int x = TileX(start);
+ int y = TileY(start);
+ int ex = TileX(end);
+ int ey = TileY(end);
+ int dx, dy, trdx, trdy;
+
+ if (!ValParamTrackOrientation(*trackdir)) return CMD_ERROR;
+
+ // calculate delta x,y from start to end tile
+ dx = ex - x;
+ dy = ey - y;
+
+ // calculate delta x,y for the first direction
+ trdx = _trackdelta[*trackdir].x;
+ trdy = _trackdelta[*trackdir].y;
+
+ if (!IsDiagonalTrackdir(*trackdir)) {
+ trdx += _trackdelta[*trackdir ^ 1].x;
+ trdy += _trackdelta[*trackdir ^ 1].y;
+ }
+
+ // validate the direction
+ while (
+ (trdx <= 0 && dx > 0) ||
+ (trdx >= 0 && dx < 0) ||
+ (trdy <= 0 && dy > 0) ||
+ (trdy >= 0 && dy < 0)
+ ) {
+ if (!HASBIT(*trackdir, 3)) { // first direction is invalid, try the other
+ SETBIT(*trackdir, 3); // reverse the direction
+ trdx = -trdx;
+ trdy = -trdy;
+ } else { // other direction is invalid too, invalid drag
+ return CMD_ERROR;
+ }
+ }
+
+ // (for diagonal tracks, this is already made sure of by above test), but:
+ // for non-diagonal tracks, check if the start and end tile are on 1 line
+ if (!IsDiagonalTrackdir(*trackdir)) {
+ trdx = _trackdelta[*trackdir].x;
+ trdy = _trackdelta[*trackdir].y;
+ if (abs(dx) != abs(dy) && abs(dx) + abs(trdy) != abs(dy) + abs(trdx))
+ return CMD_ERROR;
+ }
+
+ return 0;
+}
+
+/** Build a stretch of railroad tracks.
+ * @param tile start tile of drag
+ * @param p1 end tile of drag
+ * @param p2 various bitstuffed elements
+ * - p2 = (bit 0-3) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev)
+ * - p2 = (bit 4-6) - track-orientation, valid values: 0-5 (Track enum)
+ * - p2 = (bit 7) - 0 = build, 1 = remove tracks
+ */
+static int32 CmdRailTrackHelper(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ int32 ret, total_cost = 0;
+ Track track = (Track)GB(p2, 4, 3);
+ Trackdir trackdir;
+ byte mode = HASBIT(p2, 7);
+ RailType railtype = (RailType)GB(p2, 0, 4);
+ TileIndex end_tile;
+
+ if (!ValParamRailtype(railtype) || !ValParamTrackOrientation(track)) return CMD_ERROR;
+ if (p1 >= MapSize()) return CMD_ERROR;
+ end_tile = p1;
+ trackdir = TrackToTrackdir(track);
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ if (CmdFailed(ValidateAutoDrag(&trackdir, tile, end_tile))) return CMD_ERROR;
+
+ if (flags & DC_EXEC) SndPlayTileFx(SND_20_SPLAT_2, tile);
+
+ for (;;) {
+ ret = DoCommand(tile, railtype, TrackdirToTrack(trackdir), flags, (mode == 0) ? CMD_BUILD_SINGLE_RAIL : CMD_REMOVE_SINGLE_RAIL);
+
+ if (CmdFailed(ret)) {
+ if ((_error_message != STR_1007_ALREADY_BUILT) && (mode == 0)) break;
+ _error_message = INVALID_STRING_ID;
+ } else {
+ total_cost += ret;
+ }
+
+ if (tile == end_tile) break;
+
+ tile += ToTileIndexDiff(_trackdelta[trackdir]);
+
+ // toggle railbit for the non-diagonal tracks
+ if (!IsDiagonalTrackdir(trackdir)) trackdir ^= 1;
+ }
+
+ return (total_cost == 0) ? CMD_ERROR : total_cost;
+}
+
+/** Build rail on a stretch of track.
+ * Stub for the unified rail builder/remover
+ * @see CmdRailTrackHelper
+ */
+int32 CmdBuildRailroadTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ return CmdRailTrackHelper(tile, flags, p1, CLRBIT(p2, 7));
+}
+
+/** Build rail on a stretch of track.
+ * Stub for the unified rail builder/remover
+ * @see CmdRailTrackHelper
+ */
+int32 CmdRemoveRailroadTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ return CmdRailTrackHelper(tile, flags, p1, SETBIT(p2, 7));
+}
+
+/** Build a train depot
+ * @param tile position of the train depot
+ * @param p1 rail type
+ * @param p2 entrance direction (DiagDirection)
+ *
+ * @todo When checking for the tile slope,
+ * distingush between "Flat land required" and "land sloped in wrong direction"
+ */
+int32 CmdBuildTrainDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Depot *d;
+ int32 cost, ret;
+ Slope tileh;
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ if (!EnsureNoVehicle(tile)) return CMD_ERROR;
+ /* check railtype and valid direction for depot (0 through 3), 4 in total */
+ if (!ValParamRailtype(p1) || p2 > 3) return CMD_ERROR;
+
+ tileh = GetTileSlope(tile, NULL);
+
+ /* Prohibit construction if
+ * The tile is non-flat AND
+ * 1) The AI is "old-school"
+ * 2) build-on-slopes is disabled
+ * 3) the tile is steep i.e. spans two height levels
+ * 4) the exit points in the wrong direction
+ */
+
+ if (tileh != SLOPE_FLAT && (
+ _is_old_ai_player ||
+ !_patches.build_on_slopes ||
+ IsSteepSlope(tileh) ||
+ !CanBuildDepotByTileh(p2, tileh)
+ )) {
+ return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
+ }
+
+ ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+ if (CmdFailed(ret)) return CMD_ERROR;
+ cost = ret;
+
+ if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
+
+ d = AllocateDepot();
+ if (d == NULL) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ MakeRailDepot(tile, _current_player, p2, p1);
+ MarkTileDirtyByTile(tile);
+
+ d->xy = tile;
+ d->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
+
+ UpdateSignalsOnSegment(tile, p2);
+ YapfNotifyTrackLayoutChange(tile, TrackdirToTrack(DiagdirToDiagTrackdir(p2)));
+ }
+
+ return cost + _price.build_train_depot;
+}
+
+/** Build signals, alternate between double/single, signal/semaphore,
+ * pre/exit/combo-signals, and what-else not
+ * @param tile tile where to build the signals
+ * @param p1 various bitstuffed elements
+ * - p1 = (bit 0-2) - track-orientation, valid values: 0-5 (Track enum)
+ * - p1 = (bit 3) - choose semaphores/signals or cycle normal/pre/exit/combo depending on context
+ * @param p2 used for CmdBuildManySignals() to copy direction of first signal
+ * TODO: p2 should be replaced by two bits for "along" and "against" the track.
+ */
+int32 CmdBuildSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ SignalVariant sigvar;
+ bool pre_signal;
+ Track track = (Track)(p1 & 0x7);
+ int32 cost;
+
+ // Same bit, used in different contexts
+ sigvar = HASBIT(p1, 3) ? SIG_SEMAPHORE : SIG_ELECTRIC;
+ pre_signal = HASBIT(p1, 3);
+
+ if (!ValParamTrackOrientation(track) || !IsTileType(tile, MP_RAILWAY) || !EnsureNoVehicle(tile))
+ return CMD_ERROR;
+
+ /* Protect against invalid signal copying */
+ if (p2 != 0 && (p2 & SignalOnTrack(track)) == 0) return CMD_ERROR;
+
+ /* You can only build signals on plain rail tiles, and the selected track must exist */
+ if (!IsPlainRailTile(tile) || !HasTrack(tile, track)) return CMD_ERROR;
+
+ if (!CheckTileOwnership(tile)) return CMD_ERROR;
+
+ _error_message = STR_1005_NO_SUITABLE_RAILROAD_TRACK;
+
+ {
+ /* See if this is a valid track combination for signals, (ie, no overlap) */
+ TrackBits trackbits = GetTrackBits(tile);
+ if (KILL_FIRST_BIT(trackbits) != 0 && /* More than one track present */
+ trackbits != TRACK_BIT_HORZ &&
+ trackbits != TRACK_BIT_VERT) {
+ return CMD_ERROR;
+ }
+ }
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ if (!HasSignalOnTrack(tile, track)) {
+ // build new signals
+ cost = _price.build_signals;
+ } else {
+ if (p2 != 0 && sigvar != GetSignalVariant(tile)) {
+ // convert signals <-> semaphores
+ cost = _price.build_signals + _price.remove_signals;
+ } else {
+ // it is free to change orientation/pre-exit-combo signals
+ cost = 0;
+ }
+ }
+
+ if (flags & DC_EXEC) {
+ if (!HasSignals(tile)) {
+ // there are no signals at all on this tile yet
+ _m[tile].m5 |= RAIL_TILE_SIGNALS; // change into signals
+ _m[tile].m2 |= 0xF0; // all signals are on
+ _m[tile].m3 &= ~0xF0; // no signals built by default
+ SetSignalType(tile, SIGTYPE_NORMAL);
+ SetSignalVariant(tile, sigvar);
+ }
+
+ if (p2 == 0) {
+ if (!HasSignalOnTrack(tile, track)) {
+ // build new signals
+ _m[tile].m3 |= SignalOnTrack(track);
+ } else {
+ if (pre_signal) {
+ // cycle between normal -> pre -> exit -> combo -> ...
+ SignalType type = GetSignalType(tile);
+
+ SetSignalType(tile, type == SIGTYPE_COMBO ? SIGTYPE_NORMAL : type + 1);
+ } else {
+ CycleSignalSide(tile, track);
+ }
+ }
+ } else {
+ /* If CmdBuildManySignals is called with copying signals, just copy the
+ * direction of the first signal given as parameter by CmdBuildManySignals */
+ _m[tile].m3 &= ~SignalOnTrack(track);
+ _m[tile].m3 |= p2 & SignalOnTrack(track);
+ SetSignalVariant(tile, sigvar);
+ }
+
+ MarkTileDirtyByTile(tile);
+ SetSignalsOnBothDir(tile, track);
+ YapfNotifyTrackLayoutChange(tile, track);
+ }
+
+ return cost;
+}
+
+/** Build many signals by dragging; AutoSignals
+ * @param tile start tile of drag
+ * @param p1 end tile of drag
+ * @param p2 various bitstuffed elements
+ * - p2 = (bit 0) - 0 = build, 1 = remove signals
+ * - p2 = (bit 3) - 0 = signals, 1 = semaphores
+ * - p2 = (bit 4- 6) - track-orientation, valid values: 0-5 (Track enum)
+ * - p2 = (bit 24-31) - user defined signals_density
+ */
+static int32 CmdSignalTrackHelper(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ int32 ret, total_cost, signal_ctr;
+ byte signals;
+ bool error = true;
+ TileIndex end_tile;
+
+ int mode = p2 & 0x1;
+ Track track = GB(p2, 4, 3);
+ Trackdir trackdir = TrackToTrackdir(track);
+ byte semaphores = (HASBIT(p2, 3) ? 8 : 0);
+ byte signal_density = (p2 >> 24);
+
+ if (p1 >= MapSize()) return CMD_ERROR;
+ end_tile = p1;
+ if (signal_density == 0 || signal_density > 20) return CMD_ERROR;
+
+ if (!IsTileType(tile, MP_RAILWAY)) return CMD_ERROR;
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ /* for vertical/horizontal tracks, double the given signals density
+ * since the original amount will be too dense (shorter tracks) */
+ if (!IsDiagonalTrack(track)) signal_density *= 2;
+
+ if (CmdFailed(ValidateAutoDrag(&trackdir, tile, end_tile))) return CMD_ERROR;
+
+ track = TrackdirToTrack(trackdir); /* trackdir might have changed, keep track in sync */
+
+ // copy the signal-style of the first rail-piece if existing
+ if (HasSignals(tile)) {
+ signals = _m[tile].m3 & SignalOnTrack(track);
+ if (signals == 0) signals = SignalOnTrack(track); /* Can this actually occur? */
+
+ // copy signal/semaphores style (independent of CTRL)
+ semaphores = (GetSignalVariant(tile) == SIG_ELECTRIC ? 0 : 8);
+ } else { // no signals exist, drag a two-way signal stretch
+ signals = SignalOnTrack(track);
+ }
+
+ /* signal_ctr - amount of tiles already processed
+ * signals_density - patch setting to put signal on every Nth tile (double space on |, -- tracks)
+ **********
+ * trackdir - trackdir to build with autorail
+ * semaphores - semaphores or signals
+ * signals - is there a signal/semaphore on the first tile, copy its style (two-way/single-way)
+ * and convert all others to semaphore/signal
+ * mode - 1 remove signals, 0 build signals */
+ signal_ctr = total_cost = 0;
+ for (;;) {
+ // only build/remove signals with the specified density
+ if (signal_ctr % signal_density == 0) {
+ ret = DoCommand(tile, TrackdirToTrack(trackdir) | semaphores, signals, flags, (mode == 1) ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS);
+
+ /* Be user-friendly and try placing signals as much as possible */
+ if (!CmdFailed(ret)) {
+ error = false;
+ total_cost += ret;
+ }
+ }
+
+ if (tile == end_tile) break;
+
+ tile += ToTileIndexDiff(_trackdelta[trackdir]);
+ signal_ctr++;
+
+ // toggle railbit for the non-diagonal tracks (|, -- tracks)
+ if (!IsDiagonalTrackdir(trackdir)) trackdir ^= 1;
+ }
+
+ return error ? CMD_ERROR : total_cost;
+}
+
+/** Build signals on a stretch of track.
+ * Stub for the unified signal builder/remover
+ * @see CmdSignalTrackHelper
+ */
+int32 CmdBuildSignalTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ return CmdSignalTrackHelper(tile, flags, p1, p2);
+}
+
+/** Remove signals
+ * @param tile coordinates where signal is being deleted from
+ * @param p1 track to remove signal from (Track enum)
+ */
+int32 CmdRemoveSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Track track = (Track)(p1 & 0x7);
+
+ if (!ValParamTrackOrientation(track) ||
+ !IsTileType(tile, MP_RAILWAY) ||
+ !EnsureNoVehicle(tile) ||
+ !HasSignalOnTrack(tile, track)) {
+ return CMD_ERROR;
+ }
+
+ /* Only water can remove signals from anyone */
+ if (_current_player != OWNER_WATER && !CheckTileOwnership(tile)) return CMD_ERROR;
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ /* Do it? */
+ if (flags & DC_EXEC) {
+ _m[tile].m3 &= ~SignalOnTrack(track);
+
+ /* removed last signal from tile? */
+ if (GB(_m[tile].m3, 4, 4) == 0) {
+ SB(_m[tile].m2, 4, 4, 0);
+ SB(_m[tile].m5, 6, 2, RAIL_TILE_NORMAL >> 6); // XXX >> because the constant is meant for direct application, not use with SB
+ SetSignalVariant(tile, SIG_ELECTRIC); // remove any possible semaphores
+ }
+
+ SetSignalsOnBothDir(tile, track);
+ YapfNotifyTrackLayoutChange(tile, track);
+
+ MarkTileDirtyByTile(tile);
+ }
+
+ return _price.remove_signals;
+}
+
+/** Remove signals on a stretch of track.
+ * Stub for the unified signal builder/remover
+ * @see CmdSignalTrackHelper
+ */
+int32 CmdRemoveSignalTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ return CmdSignalTrackHelper(tile, flags, p1, SETBIT(p2, 0));
+}
+
+typedef int32 DoConvertRailProc(TileIndex tile, RailType totype, bool exec);
+
+static int32 DoConvertRail(TileIndex tile, RailType totype, bool exec)
+{
+ if (!CheckTileOwnership(tile)) return CMD_ERROR;
+
+ if (!EnsureNoVehicle(tile) && (!IsCompatibleRail(GetRailType(tile), totype) || IsPlainRailTile(tile))) return CMD_ERROR;
+
+ // tile is already of requested type?
+ if (GetRailType(tile) == totype) return CMD_ERROR;
+
+ // 'hidden' elrails can't be downgraded to normal rail when elrails are disabled
+ if (_patches.disable_elrails && totype == RAILTYPE_RAIL && GetRailType(tile) == RAILTYPE_ELECTRIC) return CMD_ERROR;
+
+ // change type.
+ if (exec) {
+ TrackBits tracks;
+ SetRailType(tile, totype);
+ MarkTileDirtyByTile(tile);
+
+ // notify YAPF about the track layout change
+ for (tracks = GetTrackBits(tile); tracks != TRACK_BIT_NONE; tracks = KILL_FIRST_BIT(tracks))
+ YapfNotifyTrackLayoutChange(tile, FIND_FIRST_BIT(tracks));
+
+ if (IsTileDepotType(tile, TRANSPORT_RAIL)) {
+ Vehicle *v;
+
+ /* Update build vehicle window related to this depot */
+ InvalidateWindowData(WC_BUILD_VEHICLE, tile);
+
+ /* update power of trains in this depot */
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == VEH_Train && IsFrontEngine(v) && v->tile == tile && v->u.rail.track == 0x80) {
+ TrainPowerChanged(v);
+ }
+ }
+ }
+ }
+
+ return _price.build_rail / 2;
+}
+
+extern int32 DoConvertStationRail(TileIndex tile, RailType totype, bool exec);
+extern int32 DoConvertStreetRail(TileIndex tile, RailType totype, bool exec);
+extern int32 DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec);
+
+/** Convert one rail type to the other. You can convert normal rail to
+ * monorail/maglev easily or vice-versa.
+ * @param tile end tile of rail conversion drag
+ * @param p1 start tile of drag
+ * @param p2 new railtype to convert to
+ */
+int32 CmdConvertRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ int32 ret, cost, money;
+ int ex;
+ int ey;
+ int sx, sy, x, y;
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ if (!ValParamRailtype(p2)) return CMD_ERROR;
+ if (p1 >= MapSize()) return CMD_ERROR;
+
+ // make sure sx,sy are smaller than ex,ey
+ ex = TileX(tile);
+ ey = TileY(tile);
+ sx = TileX(p1);
+ sy = TileY(p1);
+ if (ex < sx) intswap(ex, sx);
+ if (ey < sy) intswap(ey, sy);
+
+ money = GetAvailableMoneyForCommand();
+ cost = 0;
+ ret = 0;
+
+ for (x = sx; x <= ex; ++x) {
+ for (y = sy; y <= ey; ++y) {
+ TileIndex tile = TileXY(x, y);
+ DoConvertRailProc* proc;
+
+ switch (GetTileType(tile)) {
+ case MP_RAILWAY: proc = DoConvertRail; break;
+ case MP_STATION: proc = DoConvertStationRail; break;
+ case MP_STREET: proc = DoConvertStreetRail; break;
+ case MP_TUNNELBRIDGE: proc = DoConvertTunnelBridgeRail; break;
+ default: continue;
+ }
+
+ ret = proc(tile, p2, false);
+ if (CmdFailed(ret)) continue;
+ cost += ret;
+
+ if (flags & DC_EXEC) {
+ money -= ret;
+ if (money < 0) {
+ _additional_cash_required = ret;
+ return cost - ret;
+ }
+ proc(tile, p2, true);
+ }
+ }
+ }
+
+ return (cost == 0) ? ret : cost;
+}
+
+static int32 RemoveTrainDepot(TileIndex tile, uint32 flags)
+{
+ if (!CheckTileOwnership(tile) && _current_player != OWNER_WATER)
+ return CMD_ERROR;
+
+ if (!EnsureNoVehicle(tile))
+ return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ DiagDirection dir = GetRailDepotDirection(tile);
+
+ DeleteDepot(GetDepotByTile(tile));
+ UpdateSignalsOnSegment(tile, dir);
+ YapfNotifyTrackLayoutChange(tile, TrackdirToTrack(DiagdirToDiagTrackdir(dir)));
+ }
+
+ return _price.remove_train_depot;
+}
+
+static int32 ClearTile_Track(TileIndex tile, byte flags)
+{
+ int32 cost;
+ int32 ret;
+
+ if (flags & DC_AUTO) {
+ if (!IsTileOwner(tile, _current_player))
+ return_cmd_error(STR_1024_AREA_IS_OWNED_BY_ANOTHER);
+
+ if (IsPlainRailTile(tile)) {
+ return_cmd_error(STR_1008_MUST_REMOVE_RAILROAD_TRACK);
+ } else {
+ return_cmd_error(STR_2004_BUILDING_MUST_BE_DEMOLISHED);
+ }
+ }
+
+ cost = 0;
+
+ switch (GetRailTileType(tile)) {
+ case RAIL_TILE_SIGNALS:
+ case RAIL_TILE_NORMAL: {
+ TrackBits tracks = GetTrackBits(tile);
+ uint i;
+
+ for_each_bit (i, tracks) {
+ ret = DoCommand(tile, 0, i, flags, CMD_REMOVE_SINGLE_RAIL);
+ if (CmdFailed(ret)) return CMD_ERROR;
+ cost += ret;
+ }
+ return cost;
+ }
+
+ case RAIL_TILE_DEPOT_WAYPOINT:
+ if (GetRailTileSubtype(tile) == RAIL_SUBTYPE_DEPOT) {
+ return RemoveTrainDepot(tile, flags);
+ } else {
+ return RemoveTrainWaypoint(tile, flags, false);
+ }
+
+ default:
+ return CMD_ERROR;
+ }
+}
+
+#include "table/track_land.h"
+
+static void DrawSingleSignal(TileIndex tile, byte condition, uint image, uint pos)
+{
+ bool side = _opt.road_side & _patches.signal_side;
+ static const Point SignalPositions[2][12] = {
+ { /* Signals on the left side */
+ /* LEFT LEFT RIGHT RIGHT UPPER UPPER */
+ { 8, 5}, {14, 1}, { 1, 14}, { 9, 11}, { 1, 0}, { 3, 10},
+ /* LOWER LOWER X X Y Y */
+ {11, 4}, {14, 14}, {11, 3}, { 4, 13}, { 3, 4}, {11, 13}
+ }, { /* Signals on the right side */
+ /* LEFT LEFT RIGHT RIGHT UPPER UPPER */
+ {14, 1}, {12, 10}, { 4, 6}, { 1, 14}, {10, 4}, { 0, 1},
+ /* LOWER LOWER X X Y Y */
+ {14, 14}, { 5, 12}, {11, 13}, { 4, 3}, {13, 4}, { 3, 11}
+ }
+ };
+
+ static const SpriteID SignalBase[2][2][4] = {
+ { /* Signals on left side */
+ { 0x4FB, 0x1323, 0x1333, 0x1343}, /* light signals */
+ { 0x1353, 0x1363, 0x1373, 0x1383} /* semaphores */
+ }, { /* Signals on right side */
+ { 0x4FB, 0x1323, 0x1333, 0x1343}, /* light signals */
+ { 0x1446, 0x1456, 0x1466, 0x1476} /* semaphores */
+ /* | | | | */
+ /* normal, entry, exit, combo */
+ }
+ };
+
+ uint x = TileX(tile) * TILE_SIZE + SignalPositions[side][pos].x;
+ uint y = TileY(tile) * TILE_SIZE + SignalPositions[side][pos].y;
+
+ SpriteID sprite;
+
+ /* _signal_base is set by our NewGRF Action 5 loader. If it is 0 then we
+ * just draw the standard signals, else we get the offset from _signal_base
+ * and draw that sprite. All the signal sprites are loaded sequentially. */
+ if (_signal_base == 0 || (GetSignalType(tile) == 0 && GetSignalVariant(tile) == SIG_ELECTRIC)) {
+ sprite = SignalBase[side][GetSignalVariant(tile)][GetSignalType(tile)] + image + condition;
+ } else {
+ sprite = _signal_base + (GetSignalType(tile) - 1) * 16 + GetSignalVariant(tile) * 64 + image + condition;
+ }
+
+ AddSortableSpriteToDraw(sprite, x, y, 1, 1, 10, GetSlopeZ(x,y));
+}
+
+static uint32 _drawtile_track_palette;
+
+
+static void DrawTrackFence_NW(const TileInfo *ti)
+{
+ uint32 image = 0x515;
+ if (ti->tileh != SLOPE_FLAT) image = (ti->tileh & SLOPE_S) ? 0x519 : 0x51B;
+ AddSortableSpriteToDraw(image | _drawtile_track_palette,
+ ti->x, ti->y + 1, 16, 1, 4, ti->z);
+}
+
+static void DrawTrackFence_SE(const TileInfo *ti)
+{
+ uint32 image = 0x515;
+ if (ti->tileh != SLOPE_FLAT) image = (ti->tileh & SLOPE_S) ? 0x519 : 0x51B;
+ AddSortableSpriteToDraw(image | _drawtile_track_palette,
+ ti->x, ti->y + TILE_SIZE - 1, 16, 1, 4, ti->z);
+}
+
+static void DrawTrackFence_NW_SE(const TileInfo *ti)
+{
+ DrawTrackFence_NW(ti);
+ DrawTrackFence_SE(ti);
+}
+
+static void DrawTrackFence_NE(const TileInfo *ti)
+{
+ uint32 image = 0x516;
+ if (ti->tileh != SLOPE_FLAT) image = (ti->tileh & SLOPE_S) ? 0x51A : 0x51C;
+ AddSortableSpriteToDraw(image | _drawtile_track_palette,
+ ti->x + 1, ti->y, 1, 16, 4, ti->z);
+}
+
+static void DrawTrackFence_SW(const TileInfo *ti)
+{
+ uint32 image = 0x516;
+ if (ti->tileh != SLOPE_FLAT) image = (ti->tileh & SLOPE_S) ? 0x51A : 0x51C;
+ AddSortableSpriteToDraw(image | _drawtile_track_palette,
+ ti->x + TILE_SIZE - 1, ti->y, 1, 16, 4, ti->z);
+}
+
+static void DrawTrackFence_NE_SW(const TileInfo *ti)
+{
+ DrawTrackFence_NE(ti);
+ DrawTrackFence_SW(ti);
+}
+
+static void DrawTrackFence_NS_1(const TileInfo *ti)
+{
+ int z = ti->z;
+ if (ti->tileh & SLOPE_W) z += TILE_HEIGHT;
+ AddSortableSpriteToDraw(0x517 | _drawtile_track_palette,
+ ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z);
+}
+
+static void DrawTrackFence_NS_2(const TileInfo *ti)
+{
+ int z = ti->z;
+ if (ti->tileh & SLOPE_E) z += TILE_HEIGHT;
+ AddSortableSpriteToDraw(0x517 | _drawtile_track_palette,
+ ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z);
+}
+
+static void DrawTrackFence_WE_1(const TileInfo *ti)
+{
+ int z = ti->z;
+ if (ti->tileh & SLOPE_N) z += TILE_HEIGHT;
+ AddSortableSpriteToDraw(0x518 | _drawtile_track_palette,
+ ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z);
+}
+
+static void DrawTrackFence_WE_2(const TileInfo *ti)
+{
+ int z = ti->z;
+ if (ti->tileh & SLOPE_S) z += TILE_HEIGHT;
+ AddSortableSpriteToDraw(0x518 | _drawtile_track_palette,
+ ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z);
+}
+
+
+static void DrawTrackDetails(const TileInfo* ti)
+{
+ switch (GetRailGroundType(ti->tile)) {
+ case RAIL_GROUND_FENCE_NW: DrawTrackFence_NW(ti); break;
+ case RAIL_GROUND_FENCE_SE: DrawTrackFence_SE(ti); break;
+ case RAIL_GROUND_FENCE_SENW: DrawTrackFence_NW_SE(ti); break;
+ case RAIL_GROUND_FENCE_NE: DrawTrackFence_NE(ti); break;
+ case RAIL_GROUND_FENCE_SW: DrawTrackFence_SW(ti); break;
+ case RAIL_GROUND_FENCE_NESW: DrawTrackFence_NE_SW(ti); break;
+ case RAIL_GROUND_FENCE_VERT1: DrawTrackFence_NS_1(ti); break;
+ case RAIL_GROUND_FENCE_VERT2: DrawTrackFence_NS_2(ti); break;
+ case RAIL_GROUND_FENCE_HORIZ1: DrawTrackFence_WE_1(ti); break;
+ case RAIL_GROUND_FENCE_HORIZ2: DrawTrackFence_WE_2(ti); break;
+ default: break;
+ }
+}
+
+
+/**
+ * Draw ground sprite and track bits
+ * @param ti TileInfo
+ * @param track TrackBits to draw
+ * @param earth Draw as earth
+ * @param snow Draw as snow
+ * @param flat Always draw foundation
+ */
+static void DrawTrackBits(TileInfo* ti, TrackBits track)
+{
+ const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
+ PalSpriteID image;
+ bool junction = false;
+
+ // Select the sprite to use.
+ (image = rti->base_sprites.track_y, track == TRACK_BIT_Y) ||
+ (image++, track == TRACK_BIT_X) ||
+ (image++, track == TRACK_BIT_UPPER) ||
+ (image++, track == TRACK_BIT_LOWER) ||
+ (image++, track == TRACK_BIT_RIGHT) ||
+ (image++, track == TRACK_BIT_LEFT) ||
+ (image++, track == TRACK_BIT_CROSS) ||
+
+ (image = rti->base_sprites.track_ns, track == TRACK_BIT_HORZ) ||
+ (image++, track == TRACK_BIT_VERT) ||
+
+ (junction = true, false) ||
+ (image = rti->base_sprites.ground, (track & TRACK_BIT_3WAY_NE) == 0) ||
+ (image++, (track & TRACK_BIT_3WAY_SW) == 0) ||
+ (image++, (track & TRACK_BIT_3WAY_NW) == 0) ||
+ (image++, (track & TRACK_BIT_3WAY_SE) == 0) ||
+ (image++, true);
+
+ if (ti->tileh != SLOPE_FLAT) {
+ uint foundation = GetRailFoundation(ti->tileh, track);
+
+ if (foundation != 0) DrawFoundation(ti, foundation);
+
+ // DrawFoundation() modifies ti.
+ // Default sloped sprites..
+ if (ti->tileh != SLOPE_FLAT)
+ image = _track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.track_y;
+ }
+
+ switch (GetRailGroundType(ti->tile)) {
+ case RAIL_GROUND_BARREN: image |= PALETTE_TO_BARE_LAND; break;
+ case RAIL_GROUND_ICE_DESERT: image += rti->snow_offset; break;
+ default: break;
+ }
+
+ DrawGroundSprite(image);
+
+ // Draw track pieces individually for junction tiles
+ if (junction) {
+ if (track & TRACK_BIT_X) DrawGroundSprite(rti->base_sprites.single_y);
+ if (track & TRACK_BIT_Y) DrawGroundSprite(rti->base_sprites.single_x);
+ if (track & TRACK_BIT_UPPER) DrawGroundSprite(rti->base_sprites.single_n);
+ if (track & TRACK_BIT_LOWER) DrawGroundSprite(rti->base_sprites.single_s);
+ if (track & TRACK_BIT_LEFT) DrawGroundSprite(rti->base_sprites.single_w);
+ if (track & TRACK_BIT_RIGHT) DrawGroundSprite(rti->base_sprites.single_e);
+ }
+
+ if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
+
+}
+
+static void DrawSignals(TileIndex tile, TrackBits rails)
+{
+#define MAYBE_DRAW_SIGNAL(x,y,z) if (IsSignalPresent(tile, x)) DrawSingleSignal(tile, GetSingleSignalState(tile, x), y - 0x4FB, z)
+
+ if (!(rails & TRACK_BIT_Y)) {
+ if (!(rails & TRACK_BIT_X)) {
+ if (rails & TRACK_BIT_LEFT) {
+ MAYBE_DRAW_SIGNAL(2, 0x509, 0);
+ MAYBE_DRAW_SIGNAL(3, 0x507, 1);
+ }
+ if (rails & TRACK_BIT_RIGHT) {
+ MAYBE_DRAW_SIGNAL(0, 0x509, 2);
+ MAYBE_DRAW_SIGNAL(1, 0x507, 3);
+ }
+ if (rails & TRACK_BIT_UPPER) {
+ MAYBE_DRAW_SIGNAL(3, 0x505, 4);
+ MAYBE_DRAW_SIGNAL(2, 0x503, 5);
+ }
+ if (rails & TRACK_BIT_LOWER) {
+ MAYBE_DRAW_SIGNAL(1, 0x505, 6);
+ MAYBE_DRAW_SIGNAL(0, 0x503, 7);
+ }
+ } else {
+ MAYBE_DRAW_SIGNAL(3, 0x4FB, 8);
+ MAYBE_DRAW_SIGNAL(2, 0x4FD, 9);
+ }
+ } else {
+ MAYBE_DRAW_SIGNAL(3, 0x4FF, 10);
+ MAYBE_DRAW_SIGNAL(2, 0x501, 11);
+ }
+}
+
+static void DrawTile_Track(TileInfo *ti)
+{
+ const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
+ PalSpriteID image;
+
+ _drawtile_track_palette = SPRITE_PALETTE(PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile)));
+
+ if (IsPlainRailTile(ti->tile)) {
+ TrackBits rails = GetTrackBits(ti->tile);
+
+ DrawTrackBits(ti, rails);
+
+ if (_display_opt & DO_FULL_DETAIL) DrawTrackDetails(ti);
+
+ if (HasSignals(ti->tile)) DrawSignals(ti->tile, rails);
+ } else {
+ // draw depot/waypoint
+ const DrawTileSprites* dts;
+ const DrawTileSeqStruct* dtss;
+ uint32 relocation;
+
+ if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
+
+ if (GetRailTileSubtype(ti->tile) == RAIL_SUBTYPE_DEPOT) {
+ dts = &_depot_gfx_table[GetRailDepotDirection(ti->tile)];
+
+ relocation = rti->total_offset;
+
+ image = dts->ground_sprite;
+ if (image != SPR_FLAT_GRASS_TILE) image += rti->total_offset;
+
+ // adjust ground tile for desert
+ // don't adjust for snow, because snow in depots looks weird
+ if (IsSnowRailGround(ti->tile) && _opt.landscape == LT_DESERT) {
+ if (image != SPR_FLAT_GRASS_TILE) {
+ image += rti->snow_offset; // tile with tracks
+ } else {
+ image = SPR_FLAT_SNOWY_TILE; // flat ground
+ }
+ }
+ } else {
+ // look for customization
+ byte stat_id = GetWaypointByTile(ti->tile)->stat_id;
+ const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, stat_id);
+
+ if (statspec != NULL) {
+ // emulate station tile - open with building
+ const Station* st = ComposeWaypointStation(ti->tile);
+ uint gfx = 2;
+
+ if (HASBIT(statspec->callbackmask, CBM_CUSTOM_LAYOUT)) {
+ uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0, 0, statspec, st, ti->tile);
+ if (callback != CALLBACK_FAILED) gfx = callback;
+ }
+
+ if (statspec->renderdata == NULL) {
+ dts = GetStationTileLayout(gfx);
+ } else {
+ dts = &statspec->renderdata[(gfx < statspec->tiles ? gfx : 0) + GetWaypointAxis(ti->tile)];
+ }
+
+ if (dts != NULL && dts->seq != NULL) {
+ relocation = GetCustomStationRelocation(statspec, st, ti->tile);
+
+ image = dts->ground_sprite;
+ if (HASBIT(image, 31)) {
+ CLRBIT(image, 31);
+ image += GetCustomStationGroundRelocation(statspec, st, ti->tile);
+ image += rti->custom_ground_offset;
+ } else {
+ image += rti->total_offset;
+ }
+ } else {
+ goto default_waypoint;
+ }
+ } else {
+default_waypoint:
+ // There is no custom layout, fall back to the default graphics
+ dts = &_waypoint_gfx_table[GetWaypointAxis(ti->tile)];
+ relocation = 0;
+ image = dts->ground_sprite + rti->total_offset;
+ if (IsSnowRailGround(ti->tile)) image += rti->snow_offset;
+ }
+ }
+
+ DrawGroundSprite(image);
+
+ if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
+
+ foreach_draw_tile_seq(dtss, dts->seq) {
+ uint32 image = dtss->image + relocation;
+
+ if (_display_opt & DO_TRANS_BUILDINGS) {
+ MAKE_TRANSPARENT(image);
+ } else if (image & PALETTE_MODIFIER_COLOR) {
+ image |= _drawtile_track_palette;
+ }
+ AddSortableSpriteToDraw(
+ image,
+ ti->x + dtss->delta_x, ti->y + dtss->delta_y,
+ dtss->size_x, dtss->size_y,
+ dtss->size_z, ti->z + dtss->delta_z
+ );
+ }
+ }
+ DrawBridgeMiddle(ti);
+}
+
+
+static void DrawTileSequence(int x, int y, uint32 ground, const DrawTileSeqStruct* dtss, uint32 offset)
+{
+ uint32 palette = PLAYER_SPRITE_COLOR(_local_player);
+
+ DrawSprite(ground, x, y);
+ for (; dtss->image != 0; dtss++) {
+ Point pt = RemapCoords(dtss->delta_x, dtss->delta_y, dtss->delta_z);
+ uint32 image = dtss->image + offset;
+
+ if (image & PALETTE_MODIFIER_COLOR) image |= palette;
+ DrawSprite(image, x + pt.x, y + pt.y);
+ }
+}
+
+void DrawTrainDepotSprite(int x, int y, int dir, RailType railtype)
+{
+ const DrawTileSprites* dts = &_depot_gfx_table[dir];
+ uint32 image = dts->ground_sprite;
+ uint32 offset = GetRailTypeInfo(railtype)->total_offset;
+
+ if (image != SPR_FLAT_GRASS_TILE) image += offset;
+ DrawTileSequence(x + 33, y + 17, image, dts->seq, offset);
+}
+
+void DrawDefaultWaypointSprite(int x, int y, RailType railtype)
+{
+ uint32 offset = GetRailTypeInfo(railtype)->total_offset;
+ const DrawTileSprites* dts = &_waypoint_gfx_table[AXIS_X];
+
+ DrawTileSequence(x, y, dts->ground_sprite + offset, dts->seq, 0);
+}
+
+typedef struct SetSignalsData {
+ int cur;
+ int cur_stack;
+ bool stop;
+ bool has_presignal;
+
+ // presignal info
+ int presignal_exits;
+ int presignal_exits_free;
+
+ // these are used to keep track of the signals that change.
+ byte bit[NUM_SSD_ENTRY];
+ TileIndex tile[NUM_SSD_ENTRY];
+
+ // these are used to keep track of the stack that modifies presignals recursively
+ TileIndex next_tile[NUM_SSD_STACK];
+ byte next_dir[NUM_SSD_STACK];
+
+} SetSignalsData;
+
+static bool SetSignalsEnumProc(TileIndex tile, void* data, int track, uint length, byte* state)
+{
+ SetSignalsData* ssd = data;
+
+ if (!IsTileType(tile, MP_RAILWAY)) return false;
+
+ // the tile has signals?
+ if (HasSignalOnTrack(tile, TrackdirToTrack(track))) {
+ if (HasSignalOnTrackdir(tile, ReverseTrackdir(track))) {
+ // yes, add the signal to the list of signals
+ if (ssd->cur != NUM_SSD_ENTRY) {
+ ssd->tile[ssd->cur] = tile; // remember the tile index
+ ssd->bit[ssd->cur] = track; // and the controlling bit number
+ ssd->cur++;
+ }
+
+ // remember if this block has a presignal.
+ ssd->has_presignal |= IsPresignalEntry(tile);
+ }
+
+ if (HasSignalOnTrackdir(tile, track) && IsPresignalExit(tile)) {
+ // this is an exit signal that points out from the segment
+ ssd->presignal_exits++;
+ if (GetSignalStateByTrackdir(tile, track) != SIGNAL_STATE_RED)
+ ssd->presignal_exits_free++;
+ }
+
+ return true;
+ } else if (IsTileDepotType(tile, TRANSPORT_RAIL)) {
+ return true; // don't look further if the tile is a depot
+ }
+
+ return false;
+}
+
+/* Struct to parse data from VehicleFromPos to SignalVehicleCheckProc */
+typedef struct SignalVehicleCheckStruct {
+ TileIndex tile;
+ uint track;
+} SignalVehicleCheckStruct;
+
+static void *SignalVehicleCheckProc(Vehicle *v, void *data)
+{
+ const SignalVehicleCheckStruct* dest = data;
+
+ if (v->type != VEH_Train) return NULL;
+
+ /* Wrong tile, or no train? Not a match */
+ if (v->tile != dest->tile) return NULL;
+
+ /* Are we on the same piece of track? */
+ if (dest->track & v->u.rail.track * 0x101) return v;
+
+ return NULL;
+}
+
+/* Special check for SetSignalsAfterProc, to see if there is a vehicle on this tile */
+static bool SignalVehicleCheck(TileIndex tile, uint track)
+{
+ SignalVehicleCheckStruct dest;
+
+ dest.tile = tile;
+ dest.track = track;
+
+ /* Locate vehicles in tunnels or on bridges */
+ if (IsTunnelTile(tile) || IsBridgeTile(tile)) {
+ TileIndex end;
+ DiagDirection direction;
+
+ if (IsTunnelTile(tile)) {
+ end = GetOtherTunnelEnd(tile);
+ direction = GetTunnelDirection(tile);
+ } else {
+ end = GetOtherBridgeEnd(tile);
+ direction = GetBridgeRampDirection(tile);
+ }
+
+ dest.track = 1 << (direction & 1); // get the trackbit the vehicle would have if it has not entered the tunnel yet (ie is still visible)
+
+ // check for a vehicle with that trackdir on the start tile of the tunnel
+ if (VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL) return true;
+
+ // check for a vehicle with that trackdir on the end tile of the tunnel
+ if (VehicleFromPos(end, &dest, SignalVehicleCheckProc) != NULL) return true;
+
+ // now check all tiles from start to end for a warping vehicle
+ // NOTE: the hashes for tiles may overlap, so this could maybe be optimised a bit by not checking every tile?
+ dest.track = 0x40; //Vehicle inside a tunnel or on a bridge
+ for (; tile != end; tile += TileOffsByDiagDir(direction)) {
+ if (VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL)
+ return true;
+ }
+
+ // no vehicle found
+ return false;
+ }
+
+ return VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL;
+}
+
+static void SetSignalsAfterProc(TrackPathFinder *tpf)
+{
+ SetSignalsData *ssd = tpf->userdata;
+ const TrackPathFinderLink* link;
+ uint offs;
+ uint i;
+
+ ssd->stop = false;
+
+ /* Go through all the PF tiles */
+ for (i = 0; i < lengthof(tpf->hash_head); i++) {
+ /* Empty hash item */
+ if (tpf->hash_head[i] == 0) continue;
+
+ /* If 0x8000 is not set, there is only 1 item */
+ if (!(tpf->hash_head[i] & 0x8000)) {
+ /* Check if there is a vehicle on this tile */
+ if (SignalVehicleCheck(tpf->hash_tile[i], tpf->hash_head[i])) {
+ ssd->stop = true;
+ return;
+ }
+ } else {
+ /* There are multiple items, where hash_tile points to the first item in the list */
+ offs = tpf->hash_tile[i];
+ do {
+ /* Find the next item */
+ link = PATHFIND_GET_LINK_PTR(tpf, offs);
+ /* Check if there is a vehicle on this tile */
+ if (SignalVehicleCheck(link->tile, link->flags)) {
+ ssd->stop = true;
+ return;
+ }
+ /* Goto the next item */
+ } while ((offs = link->next) != 0xFFFF);
+ }
+ }
+}
+
+static const byte _dir_from_track[14] = {
+ 0,1,0,1,2,1, 0,0,
+ 2,3,3,2,3,0,
+};
+
+
+static void ChangeSignalStates(SetSignalsData *ssd)
+{
+ int i;
+
+ // thinking about presignals...
+ // the presignal is green if,
+ // if no train is in the segment AND
+ // there is at least one green exit signal OR
+ // there are no exit signals in the segment
+
+ // then mark the signals in the segment accordingly
+ for (i = 0; i != ssd->cur; i++) {
+ TileIndex tile = ssd->tile[i];
+ byte bit = SignalAgainstTrackdir(ssd->bit[i]);
+ uint16 m2 = _m[tile].m2;
+
+ // presignals don't turn green if there is at least one presignal exit and none are free
+ if (IsPresignalEntry(tile)) {
+ int ex = ssd->presignal_exits, exfree = ssd->presignal_exits_free;
+
+ // subtract for dual combo signals so they don't count themselves
+ if (IsPresignalExit(tile) && HasSignalOnTrackdir(tile, ssd->bit[i])) {
+ ex--;
+ if (GetSignalStateByTrackdir(tile, ssd->bit[i]) != SIGNAL_STATE_RED) exfree--;
+ }
+
+ // if we have exits and none are free, make red.
+ if (ex && !exfree) goto make_red;
+ }
+
+ // check if the signal is unaffected.
+ if (ssd->stop) {
+make_red:
+ // turn red
+ if ((bit & m2) == 0) continue;
+ } else {
+ // turn green
+ if ((bit & m2) != 0) continue;
+ }
+
+ /* Update signals on the other side of this exit-combo signal; it changed. */
+ if (IsPresignalExit(tile)) {
+ if (ssd->cur_stack != NUM_SSD_STACK) {
+ ssd->next_tile[ssd->cur_stack] = tile;
+ ssd->next_dir[ssd->cur_stack] = _dir_from_track[ssd->bit[i]];
+ ssd->cur_stack++;
+ } else {
+ DEBUG(misc, 0, "NUM_SSD_STACK too small"); /// @todo WTF is this???
+ }
+ }
+
+ // it changed, so toggle it
+ _m[tile].m2 = m2 ^ bit;
+ MarkTileDirtyByTile(tile);
+ }
+}
+
+
+bool UpdateSignalsOnSegment(TileIndex tile, DiagDirection direction)
+{
+ SetSignalsData ssd;
+ int result = -1;
+
+ ssd.cur_stack = 0;
+
+ for (;;) {
+ // go through one segment and update all signals pointing into that segment.
+ ssd.cur = ssd.presignal_exits = ssd.presignal_exits_free = 0;
+ ssd.has_presignal = false;
+
+ FollowTrack(tile, 0xC000 | TRANSPORT_RAIL, direction, SetSignalsEnumProc, SetSignalsAfterProc, &ssd);
+ ChangeSignalStates(&ssd);
+
+ // remember the result only for the first iteration.
+ if (result < 0) {
+ // stay in depot while segment is occupied or while all presignal exits are blocked
+ result = ssd.stop || (ssd.presignal_exits > 0 && ssd.presignal_exits_free == 0);
+ }
+
+ // if any exit signals were changed, we need to keep going to modify the stuff behind those.
+ if (ssd.cur_stack == 0) break;
+
+ // one or more exit signals were changed, so we need to update another segment too.
+ tile = ssd.next_tile[--ssd.cur_stack];
+ direction = ssd.next_dir[ssd.cur_stack];
+ }
+
+ return result != 0;
+}
+
+void SetSignalsOnBothDir(TileIndex tile, byte track)
+{
+ static const DiagDirection _search_dir_1[] = {
+ DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE
+ };
+ static const DiagDirection _search_dir_2[] = {
+ DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE
+ };
+
+ UpdateSignalsOnSegment(tile, _search_dir_1[track]);
+ UpdateSignalsOnSegment(tile, _search_dir_2[track]);
+}
+
+static uint GetSlopeZ_Track(TileIndex tile, uint x, uint y)
+{
+ uint z;
+ Slope tileh = GetTileSlope(tile, &z);
+
+ if (tileh == SLOPE_FLAT) return z;
+ if (IsPlainRailTile(tile)) {
+ uint f = GetRailFoundation(tileh, GetTrackBits(tile));
+
+ if (f != 0) {
+ if (IsSteepSlope(tileh)) {
+ z += TILE_HEIGHT;
+ } else if (f < 15) {
+ return z + TILE_HEIGHT; // leveled foundation
+ }
+ tileh = _inclined_tileh[f - 15]; // inclined foundation
+ }
+ return z + GetPartialZ(x & 0xF, y & 0xF, tileh);
+ } else {
+ return z + TILE_HEIGHT;
+ }
+}
+
+static Slope GetSlopeTileh_Track(TileIndex tile, Slope tileh)
+{
+ if (tileh == SLOPE_FLAT) return SLOPE_FLAT;
+ if (IsPlainRailTile(tile)) {
+ uint f = GetRailFoundation(tileh, GetTrackBits(tile));
+
+ if (f == 0) return tileh;
+ if (f < 15) return SLOPE_FLAT; // leveled foundation
+ return _inclined_tileh[f - 15]; // inclined foundation
+ } else {
+ return SLOPE_FLAT;
+ }
+}
+
+static void GetAcceptedCargo_Track(TileIndex tile, AcceptedCargo ac)
+{
+ /* not used */
+}
+
+static void AnimateTile_Track(TileIndex tile)
+{
+ /* not used */
+}
+
+static void TileLoop_Track(TileIndex tile)
+{
+ RailGroundType old_ground = GetRailGroundType(tile);
+ RailGroundType new_ground;
+
+ switch (_opt.landscape) {
+ case LT_HILLY:
+ if (GetTileZ(tile) > _opt.snow_line) {
+ new_ground = RAIL_GROUND_ICE_DESERT;
+ goto set_ground;
+ }
+ break;
+
+ case LT_DESERT:
+ if (GetTropicZone(tile) == TROPICZONE_DESERT) {
+ new_ground = RAIL_GROUND_ICE_DESERT;
+ goto set_ground;
+ }
+ break;
+ }
+
+ if (!IsPlainRailTile(tile)) return;
+
+ new_ground = RAIL_GROUND_GRASS;
+
+ if (old_ground != RAIL_GROUND_BARREN) { /* wait until bottom is green */
+ /* determine direction of fence */
+ TrackBits rail = GetTrackBits(tile);
+
+ switch (rail) {
+ case TRACK_BIT_UPPER: new_ground = RAIL_GROUND_FENCE_HORIZ1; break;
+ case TRACK_BIT_LOWER: new_ground = RAIL_GROUND_FENCE_HORIZ2; break;
+ case TRACK_BIT_LEFT: new_ground = RAIL_GROUND_FENCE_VERT1; break;
+ case TRACK_BIT_RIGHT: new_ground = RAIL_GROUND_FENCE_VERT2; break;
+
+ default: {
+ PlayerID owner = GetTileOwner(tile);
+
+ if (rail == (TRACK_BIT_LOWER | TRACK_BIT_RIGHT) || (
+ (rail & TRACK_BIT_3WAY_NW) == 0 &&
+ (rail & TRACK_BIT_X)
+ )) {
+ TileIndex n = tile + TileDiffXY(0, -1);
+ TrackBits nrail = GetTrackBits(n);
+
+ if (!IsTileType(n, MP_RAILWAY) ||
+ !IsTileOwner(n, owner) ||
+ nrail == TRACK_BIT_UPPER ||
+ nrail == TRACK_BIT_LEFT) {
+ new_ground = RAIL_GROUND_FENCE_NW;
+ }
+ }
+
+ if (rail == (TRACK_BIT_UPPER | TRACK_BIT_LEFT) || (
+ (rail & TRACK_BIT_3WAY_SE) == 0 &&
+ (rail & TRACK_BIT_X)
+ )) {
+ TileIndex n = tile + TileDiffXY(0, 1);
+ TrackBits nrail = GetTrackBits(n);
+
+ if (!IsTileType(n, MP_RAILWAY) ||
+ !IsTileOwner(n, owner) ||
+ nrail == TRACK_BIT_LOWER ||
+ nrail == TRACK_BIT_RIGHT) {
+ new_ground = (new_ground == RAIL_GROUND_FENCE_NW) ?
+ RAIL_GROUND_FENCE_SENW : RAIL_GROUND_FENCE_SE;
+ }
+ }
+
+ if (rail == (TRACK_BIT_LOWER | TRACK_BIT_LEFT) || (
+ (rail & TRACK_BIT_3WAY_NE) == 0 &&
+ (rail & TRACK_BIT_Y)
+ )) {
+ TileIndex n = tile + TileDiffXY(-1, 0);
+ TrackBits nrail = GetTrackBits(n);
+
+ if (!IsTileType(n, MP_RAILWAY) ||
+ !IsTileOwner(n, owner) ||
+ nrail == TRACK_BIT_UPPER ||
+ nrail == TRACK_BIT_RIGHT) {
+ new_ground = RAIL_GROUND_FENCE_NE;
+ }
+ }
+
+ if (rail == (TRACK_BIT_UPPER | TRACK_BIT_RIGHT) || (
+ (rail & TRACK_BIT_3WAY_SW) == 0 &&
+ (rail & TRACK_BIT_Y)
+ )) {
+ TileIndex n = tile + TileDiffXY(1, 0);
+ TrackBits nrail = GetTrackBits(n);
+
+ if (!IsTileType(n, MP_RAILWAY) ||
+ !IsTileOwner(n, owner) ||
+ nrail == TRACK_BIT_LOWER ||
+ nrail == TRACK_BIT_LEFT) {
+ new_ground = (new_ground == RAIL_GROUND_FENCE_NE) ?
+ RAIL_GROUND_FENCE_NESW : RAIL_GROUND_FENCE_SW;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+set_ground:
+ if (old_ground != new_ground) {
+ SetRailGroundType(tile, new_ground);
+ MarkTileDirtyByTile(tile);
+ }
+}
+
+
+static uint32 GetTileTrackStatus_Track(TileIndex tile, TransportType mode)
+{
+ byte a;
+ uint16 b;
+
+ if (mode != TRANSPORT_RAIL) return 0;
+
+ if (IsPlainRailTile(tile)) {
+ TrackBits rails = GetTrackBits(tile);
+ uint32 ret = rails * 0x101;
+
+ if (HasSignals(tile)) {
+ a = _m[tile].m3;
+ b = _m[tile].m2;
+
+ b &= a;
+
+ /* When signals are not present (in neither
+ * direction), we pretend them to be green. (So if
+ * signals are only one way, the other way will
+ * implicitely become `red' */
+ if ((a & 0xC0) == 0) b |= 0xC0;
+ if ((a & 0x30) == 0) b |= 0x30;
+
+ if ((b & 0x80) == 0) ret |= 0x10070000;
+ if ((b & 0x40) == 0) ret |= 0x07100000;
+ if ((b & 0x20) == 0) ret |= 0x20080000;
+ if ((b & 0x10) == 0) ret |= 0x08200000;
+ } else {
+ if (rails == TRACK_BIT_CROSS) ret |= 0x40;
+ }
+ return ret;
+ } else {
+ if (GetRailTileSubtype(tile) == RAIL_SUBTYPE_DEPOT) {
+ return AxisToTrackBits(DiagDirToAxis(GetRailDepotDirection(tile))) * 0x101;
+ } else {
+ return GetRailWaypointBits(tile) * 0x101;
+ }
+ }
+}
+
+static void ClickTile_Track(TileIndex tile)
+{
+ if (IsTileDepotType(tile, TRANSPORT_RAIL)) {
+ ShowDepotWindow(tile, VEH_Train);
+ } else if (IsRailWaypoint(tile)) {
+ ShowRenameWaypointWindow(GetWaypointByTile(tile));
+ }
+}
+
+static void GetTileDesc_Track(TileIndex tile, TileDesc *td)
+{
+ td->owner = GetTileOwner(tile);
+ switch (GetRailTileType(tile)) {
+ case RAIL_TILE_NORMAL:
+ td->str = STR_1021_RAILROAD_TRACK;
+ break;
+
+ case RAIL_TILE_SIGNALS: {
+ const StringID signal_type[] = {
+ STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS,
+ STR_RAILROAD_TRACK_WITH_PRESIGNALS,
+ STR_RAILROAD_TRACK_WITH_EXITSIGNALS,
+ STR_RAILROAD_TRACK_WITH_COMBOSIGNALS
+ };
+
+ td->str = signal_type[GetSignalType(tile)];
+ break;
+ }
+
+ case RAIL_TILE_DEPOT_WAYPOINT:
+ default:
+ td->str = (GetRailTileSubtype(tile) == RAIL_SUBTYPE_DEPOT) ?
+ STR_1023_RAILROAD_TRAIN_DEPOT : STR_LANDINFO_WAYPOINT;
+ break;
+ }
+}
+
+static void ChangeTileOwner_Track(TileIndex tile, PlayerID old_player, PlayerID new_player)
+{
+ if (!IsTileOwner(tile, old_player)) return;
+
+ if (new_player != PLAYER_SPECTATOR) {
+ SetTileOwner(tile, new_player);
+ } else {
+ DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
+ }
+}
+
+static const byte _fractcoords_behind[4] = { 0x8F, 0x8, 0x80, 0xF8 };
+static const byte _fractcoords_enter[4] = { 0x8A, 0x48, 0x84, 0xA8 };
+static const byte _deltacoord_leaveoffset[8] = {
+ -1, 0, 1, 0, /* x */
+ 0, 1, 0, -1 /* y */
+};
+
+static uint32 VehicleEnter_Track(Vehicle *v, TileIndex tile, int x, int y)
+{
+ byte fract_coord;
+ byte fract_coord_leave;
+ DiagDirection dir;
+ int length;
+
+ // this routine applies only to trains in depot tiles
+ if (v->type != VEH_Train || !IsTileDepotType(tile, TRANSPORT_RAIL)) return 0;
+
+ /* depot direction */
+ dir = GetRailDepotDirection(tile);
+
+ /* calculate the point where the following wagon should be activated */
+ /* this depends on the length of the current vehicle */
+ length = v->u.rail.cached_veh_length;
+
+ fract_coord_leave =
+ ((_fractcoords_enter[dir] & 0x0F) + // x
+ (length + 1) * _deltacoord_leaveoffset[dir]) +
+ (((_fractcoords_enter[dir] >> 4) + // y
+ ((length + 1) * _deltacoord_leaveoffset[dir+4])) << 4);
+
+ fract_coord = (x & 0xF) + ((y & 0xF) << 4);
+
+ if (_fractcoords_behind[dir] == fract_coord) {
+ /* make sure a train is not entering the tile from behind */
+ return 8;
+ } else if (_fractcoords_enter[dir] == fract_coord) {
+ if (DiagDirToDir(ReverseDiagDir(dir)) == v->direction) {
+ /* enter the depot */
+ v->u.rail.track = 0x80,
+ v->vehstatus |= VS_HIDDEN; /* hide it */
+ v->direction = ReverseDir(v->direction);
+ if (v->next == NULL) VehicleEnterDepot(v);
+ v->tile = tile;
+
+ InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
+ return 4;
+ }
+ } else if (fract_coord_leave == fract_coord) {
+ if (DiagDirToDir(dir) == v->direction) {
+ /* leave the depot? */
+ if ((v = v->next) != NULL) {
+ v->vehstatus &= ~VS_HIDDEN;
+ v->u.rail.track = (DiagDirToAxis(dir) == AXIS_X ? 1 : 2);
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+const TileTypeProcs _tile_type_rail_procs = {
+ DrawTile_Track, /* draw_tile_proc */
+ GetSlopeZ_Track, /* get_slope_z_proc */
+ ClearTile_Track, /* clear_tile_proc */
+ GetAcceptedCargo_Track, /* get_accepted_cargo_proc */
+ GetTileDesc_Track, /* get_tile_desc_proc */
+ GetTileTrackStatus_Track, /* get_tile_track_status_proc */
+ ClickTile_Track, /* click_tile_proc */
+ AnimateTile_Track, /* animate_tile_proc */
+ TileLoop_Track, /* tile_loop_clear */
+ ChangeTileOwner_Track, /* change_tile_owner_clear */
+ NULL, /* get_produced_cargo_proc */
+ VehicleEnter_Track, /* vehicle_enter_tile_proc */
+ GetSlopeTileh_Track, /* get_slope_tileh_proc */
+};
diff --git a/src/rail_gui.c b/src/rail_gui.c
new file mode 100644
index 000000000..0a63a41f3
--- /dev/null
+++ b/src/rail_gui.c
@@ -0,0 +1,1188 @@
+/* $Id$ */
+
+/** @file rail_gui.c File for dealing with rail construction user interface */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "table/sprites.h"
+#include "table/strings.h"
+#include "functions.h"
+#include "map.h"
+#include "tile.h"
+#include "window.h"
+#include "gui.h"
+#include "viewport.h"
+#include "gfx.h"
+#include "sound.h"
+#include "command.h"
+#include "vehicle.h"
+#include "station.h"
+#include "waypoint.h"
+#include "debug.h"
+#include "variables.h"
+#include "newgrf_callbacks.h"
+#include "newgrf_station.h"
+#include "train.h"
+
+static RailType _cur_railtype;
+static bool _remove_button_clicked;
+static DiagDirection _build_depot_direction;
+static byte _waypoint_count = 1;
+static byte _cur_waypoint_type;
+
+static struct {
+ byte orientation;
+ byte numtracks;
+ byte platlength;
+ bool dragdrop;
+
+ bool newstations;
+ byte station_class;
+ byte station_type;
+ byte station_count;
+} _railstation;
+
+
+static void HandleStationPlacement(TileIndex start, TileIndex end);
+static void ShowBuildTrainDepotPicker(void);
+static void ShowBuildWaypointPicker(void);
+static void ShowStationBuilder(void);
+
+void CcPlaySound1E(bool success, TileIndex tile, uint32 p1, uint32 p2)
+{
+ if (success) SndPlayTileFx(SND_20_SPLAT_2, tile);
+}
+
+static void GenericPlaceRail(TileIndex tile, int cmd)
+{
+ DoCommandP(tile, _cur_railtype, cmd, CcPlaySound1E,
+ _remove_button_clicked ?
+ CMD_REMOVE_SINGLE_RAIL | CMD_MSG(STR_1012_CAN_T_REMOVE_RAILROAD_TRACK) | CMD_AUTO | CMD_NO_WATER :
+ CMD_BUILD_SINGLE_RAIL | CMD_MSG(STR_1011_CAN_T_BUILD_RAILROAD_TRACK) | CMD_AUTO | CMD_NO_WATER
+ );
+}
+
+static void PlaceRail_N(TileIndex tile)
+{
+ int cmd = _tile_fract_coords.x > _tile_fract_coords.y ? 4 : 5;
+ GenericPlaceRail(tile, cmd);
+}
+
+static void PlaceRail_NE(TileIndex tile)
+{
+ VpStartPlaceSizing(tile, VPM_FIX_Y);
+}
+
+static void PlaceRail_E(TileIndex tile)
+{
+ int cmd = _tile_fract_coords.x + _tile_fract_coords.y <= 15 ? 2 : 3;
+ GenericPlaceRail(tile, cmd);
+}
+
+static void PlaceRail_NW(TileIndex tile)
+{
+ VpStartPlaceSizing(tile, VPM_FIX_X);
+}
+
+static void PlaceRail_AutoRail(TileIndex tile)
+{
+ VpStartPlaceSizing(tile, VPM_RAILDIRS);
+}
+
+static void PlaceExtraDepotRail(TileIndex tile, uint16 extra)
+{
+ if (GetRailTileType(tile) != RAIL_TILE_NORMAL) return;
+ if ((GetTrackBits(tile) & GB(extra, 8, 8)) == 0) return;
+
+ DoCommandP(tile, _cur_railtype, extra & 0xFF, NULL, CMD_BUILD_SINGLE_RAIL | CMD_AUTO | CMD_NO_WATER);
+}
+
+static const uint16 _place_depot_extra[12] = {
+ 0x0604, 0x2102, 0x1202, 0x0505,
+ 0x2400, 0x2801, 0x1800, 0x1401,
+ 0x2203, 0x0904, 0x0A05, 0x1103,
+};
+
+
+void CcRailDepot(bool success, TileIndex tile, uint32 p1, uint32 p2)
+{
+ if (success) {
+ DiagDirection dir = p2;
+
+ SndPlayTileFx(SND_20_SPLAT_2, tile);
+ ResetObjectToPlace();
+
+ tile += TileOffsByDiagDir(dir);
+
+ if (IsTileType(tile, MP_RAILWAY)) {
+ PlaceExtraDepotRail(tile, _place_depot_extra[dir]);
+ PlaceExtraDepotRail(tile, _place_depot_extra[dir + 4]);
+ PlaceExtraDepotRail(tile, _place_depot_extra[dir + 8]);
+ }
+ }
+}
+
+static void PlaceRail_Depot(TileIndex tile)
+{
+ DoCommandP(tile, _cur_railtype, _build_depot_direction, CcRailDepot,
+ CMD_BUILD_TRAIN_DEPOT | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_100E_CAN_T_BUILD_TRAIN_DEPOT));
+}
+
+static void PlaceRail_Waypoint(TileIndex tile)
+{
+ if (!_remove_button_clicked) {
+ DoCommandP(tile, _cur_waypoint_type, 0, CcPlaySound1E, CMD_BUILD_TRAIN_WAYPOINT | CMD_MSG(STR_CANT_BUILD_TRAIN_WAYPOINT));
+ } else {
+ DoCommandP(tile, 0, 0, CcPlaySound1E, CMD_REMOVE_TRAIN_WAYPOINT | CMD_MSG(STR_CANT_REMOVE_TRAIN_WAYPOINT));
+ }
+}
+
+void CcStation(bool success, TileIndex tile, uint32 p1, uint32 p2)
+{
+ if (success) {
+ SndPlayTileFx(SND_20_SPLAT_2, tile);
+ /* Only close the station builder window if the default station is chosen. */
+ if (_railstation.station_class == STAT_CLASS_DFLT && _railstation.station_type == 0) ResetObjectToPlace();
+ }
+}
+
+static void PlaceRail_Station(TileIndex tile)
+{
+ if (_remove_button_clicked) {
+ DoCommandP(tile, 0, 0, CcPlaySound1E, CMD_REMOVE_FROM_RAILROAD_STATION | CMD_MSG(STR_CANT_REMOVE_PART_OF_STATION));
+ } else if (_railstation.dragdrop) {
+ VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED);
+ VpSetPlaceSizingLimit(_patches.station_spread);
+ } else {
+ DoCommandP(tile,
+ _railstation.orientation | (_railstation.numtracks << 8) | (_railstation.platlength << 16),
+ _cur_railtype | (_railstation.station_class << 8) | (_railstation.station_type << 16), CcStation,
+ CMD_BUILD_RAILROAD_STATION | CMD_NO_WATER | CMD_AUTO | CMD_MSG(STR_100F_CAN_T_BUILD_RAILROAD_STATION));
+ }
+}
+
+static void GenericPlaceSignals(TileIndex tile)
+{
+ uint trackstat;
+ uint i;
+
+ trackstat = (byte)GetTileTrackStatus(tile, TRANSPORT_RAIL);
+
+ if ((trackstat & 0x30)) // N-S direction
+ trackstat = (_tile_fract_coords.x <= _tile_fract_coords.y) ? 0x20 : 0x10;
+
+ if ((trackstat & 0x0C)) // E-W direction
+ trackstat = (_tile_fract_coords.x + _tile_fract_coords.y <= 15) ? 4 : 8;
+
+ // Lookup the bit index
+ i = 0;
+ if (trackstat != 0) {
+ for (; !(trackstat & 1); trackstat >>= 1) i++;
+ }
+
+ if (!_remove_button_clicked) {
+ DoCommandP(tile, i + (_ctrl_pressed ? 8 : 0), 0, CcPlaySound1E,
+ CMD_BUILD_SIGNALS | CMD_AUTO | CMD_MSG(STR_1010_CAN_T_BUILD_SIGNALS_HERE));
+ } else {
+ DoCommandP(tile, i, 0, CcPlaySound1E,
+ CMD_REMOVE_SIGNALS | CMD_AUTO | CMD_MSG(STR_1013_CAN_T_REMOVE_SIGNALS_FROM));
+ }
+}
+
+static void PlaceRail_Bridge(TileIndex tile)
+{
+ VpStartPlaceSizing(tile, VPM_X_OR_Y);
+}
+
+void CcBuildRailTunnel(bool success, TileIndex tile, uint32 p1, uint32 p2)
+{
+ if (success) {
+ SndPlayTileFx(SND_20_SPLAT_2, tile);
+ ResetObjectToPlace();
+ } else {
+ SetRedErrorSquare(_build_tunnel_endtile);
+ }
+}
+
+static void PlaceRail_Tunnel(TileIndex tile)
+{
+ DoCommandP(tile, _cur_railtype, 0, CcBuildRailTunnel,
+ CMD_BUILD_TUNNEL | CMD_AUTO | CMD_MSG(STR_5016_CAN_T_BUILD_TUNNEL_HERE));
+}
+
+void PlaceProc_BuyLand(TileIndex tile)
+{
+ DoCommandP(tile, 0, 0, CcPlaySound1E, CMD_PURCHASE_LAND_AREA | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_5806_CAN_T_PURCHASE_THIS_LAND));
+}
+
+static void PlaceRail_ConvertRail(TileIndex tile)
+{
+ VpStartPlaceSizing(tile, VPM_X_AND_Y | GUI_PlaceProc_ConvertRailArea);
+}
+
+static void PlaceRail_AutoSignals(TileIndex tile)
+{
+ VpStartPlaceSizing(tile, VPM_SIGNALDIRS);
+}
+
+
+/** Enum referring to the widgets of the build rail toolbar */
+enum {
+ RTW_CAPTION = 1,
+ RTW_BUILD_NS = 4,
+ RTW_BUILD_X = 5,
+ RTW_BUILD_EW = 6,
+ RTW_BUILD_Y = 7,
+ RTW_AUTORAIL = 8,
+ RTW_DEMOLISH = 9,
+ RTW_BUILD_DEPOT = 10,
+ RTW_BUILD_WAYPOINT = 11,
+ RTW_BUILD_STATION = 12,
+ RTW_BUILD_SIGNALS = 13,
+ RTW_BUILD_BRIDGE = 14,
+ RTW_BUILD_TUNNEL = 15,
+ RTW_REMOVE = 16,
+ RTW_CONVERT_RAIL = 17
+};
+
+
+static void BuildRailClick_N(Window *w)
+{
+ HandlePlacePushButton(w, RTW_BUILD_NS, GetRailTypeInfo(_cur_railtype)->cursor.rail_ns, 1, PlaceRail_N);
+}
+
+static void BuildRailClick_NE(Window *w)
+{
+ HandlePlacePushButton(w, RTW_BUILD_X, GetRailTypeInfo(_cur_railtype)->cursor.rail_swne, 1, PlaceRail_NE);
+}
+
+static void BuildRailClick_E(Window *w)
+{
+ HandlePlacePushButton(w, RTW_BUILD_EW, GetRailTypeInfo(_cur_railtype)->cursor.rail_ew, 1, PlaceRail_E);
+}
+
+static void BuildRailClick_NW(Window *w)
+{
+ HandlePlacePushButton(w, RTW_BUILD_Y, GetRailTypeInfo(_cur_railtype)->cursor.rail_nwse, 1, PlaceRail_NW);
+}
+
+static void BuildRailClick_AutoRail(Window *w)
+{
+ HandlePlacePushButton(w, RTW_AUTORAIL, GetRailTypeInfo(_cur_railtype)->cursor.autorail, VHM_RAIL, PlaceRail_AutoRail);
+}
+
+static void BuildRailClick_Demolish(Window *w)
+{
+ HandlePlacePushButton(w, RTW_DEMOLISH, ANIMCURSOR_DEMOLISH, 1, PlaceProc_DemolishArea);
+}
+
+static void BuildRailClick_Depot(Window *w)
+{
+ if (HandlePlacePushButton(w, RTW_BUILD_DEPOT, GetRailTypeInfo(_cur_railtype)->cursor.depot, 1, PlaceRail_Depot)) {
+ ShowBuildTrainDepotPicker();
+ }
+}
+
+static void BuildRailClick_Waypoint(Window *w)
+{
+ _waypoint_count = GetNumCustomStations(STAT_CLASS_WAYP);
+ if (HandlePlacePushButton(w, RTW_BUILD_WAYPOINT, SPR_CURSOR_WAYPOINT, 1, PlaceRail_Waypoint) &&
+ _waypoint_count > 1) {
+ ShowBuildWaypointPicker();
+ }
+}
+
+static void BuildRailClick_Station(Window *w)
+{
+ if (HandlePlacePushButton(w, RTW_BUILD_STATION, SPR_CURSOR_RAIL_STATION, 1, PlaceRail_Station)) ShowStationBuilder();
+}
+
+static void BuildRailClick_AutoSignals(Window *w)
+{
+ HandlePlacePushButton(w, RTW_BUILD_SIGNALS, ANIMCURSOR_BUILDSIGNALS, VHM_RECT, PlaceRail_AutoSignals);
+}
+
+static void BuildRailClick_Bridge(Window *w)
+{
+ HandlePlacePushButton(w, RTW_BUILD_BRIDGE, SPR_CURSOR_BRIDGE, 1, PlaceRail_Bridge);
+}
+
+static void BuildRailClick_Tunnel(Window *w)
+{
+ HandlePlacePushButton(w, RTW_BUILD_TUNNEL, GetRailTypeInfo(_cur_railtype)->cursor.tunnel, 3, PlaceRail_Tunnel);
+}
+
+static void BuildRailClick_Remove(Window *w)
+{
+ if (IsWindowWidgetDisabled(w, RTW_REMOVE)) return;
+ SetWindowDirty(w);
+ SndPlayFx(SND_15_BEEP);
+
+ ToggleWidgetLoweredState(w, RTW_REMOVE);
+ _remove_button_clicked = IsWindowWidgetLowered(w, RTW_REMOVE);
+ SetSelectionRed(_remove_button_clicked);
+
+ // handle station builder
+ if (_remove_button_clicked) {
+ SetTileSelectSize(1, 1);
+ }
+}
+
+static void BuildRailClick_Convert(Window *w)
+{
+ HandlePlacePushButton(w, RTW_CONVERT_RAIL, GetRailTypeInfo(_cur_railtype)->cursor.convert, 1, PlaceRail_ConvertRail);
+}
+
+static void BuildRailClick_Landscaping(Window *w)
+{
+ ShowTerraformToolbar();
+}
+
+static void DoRailroadTrack(int mode)
+{
+ DoCommandP(TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), _cur_railtype | (mode << 4), NULL,
+ _remove_button_clicked ?
+ CMD_REMOVE_RAILROAD_TRACK | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1012_CAN_T_REMOVE_RAILROAD_TRACK) :
+ CMD_BUILD_RAILROAD_TRACK | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1011_CAN_T_BUILD_RAILROAD_TRACK)
+ );
+}
+
+static void HandleAutodirPlacement(void)
+{
+ TileHighlightData *thd = &_thd;
+ int trackstat = thd->drawstyle & 0xF; // 0..5
+
+ if (thd->drawstyle & HT_RAIL) { // one tile case
+ GenericPlaceRail(TileVirtXY(thd->selend.x, thd->selend.y), trackstat);
+ return;
+ }
+
+ DoRailroadTrack(trackstat);
+}
+
+static void HandleAutoSignalPlacement(void)
+{
+ TileHighlightData *thd = &_thd;
+ byte trackstat = thd->drawstyle & 0xF; // 0..5
+
+ if (thd->drawstyle == HT_RECT) { // one tile case
+ GenericPlaceSignals(TileVirtXY(thd->selend.x, thd->selend.y));
+ return;
+ }
+
+ // _patches.drag_signals_density is given as a parameter such that each user in a network
+ // game can specify his/her own signal density
+ DoCommandP(
+ TileVirtXY(thd->selstart.x, thd->selstart.y),
+ TileVirtXY(thd->selend.x, thd->selend.y),
+ (_ctrl_pressed ? 1 << 3 : 0) | (trackstat << 4) | (_patches.drag_signals_density << 24),
+ CcPlaySound1E,
+ _remove_button_clicked ?
+ CMD_REMOVE_SIGNAL_TRACK | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1013_CAN_T_REMOVE_SIGNALS_FROM) :
+ CMD_BUILD_SIGNAL_TRACK | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1010_CAN_T_BUILD_SIGNALS_HERE)
+ );
+}
+
+
+typedef void OnButtonClick(Window *w);
+
+static OnButtonClick * const _build_railroad_button_proc[] = {
+ BuildRailClick_N,
+ BuildRailClick_NE,
+ BuildRailClick_E,
+ BuildRailClick_NW,
+ BuildRailClick_AutoRail,
+ BuildRailClick_Demolish,
+ BuildRailClick_Depot,
+ BuildRailClick_Waypoint,
+ BuildRailClick_Station,
+ BuildRailClick_AutoSignals,
+ BuildRailClick_Bridge,
+ BuildRailClick_Tunnel,
+ BuildRailClick_Remove,
+ BuildRailClick_Convert,
+ BuildRailClick_Landscaping,
+};
+
+static const uint16 _rail_keycodes[] = {
+ '1',
+ '2',
+ '3',
+ '4',
+ '5',
+ '6',
+ '7', // depot
+ '8', // waypoint
+ '9', // station
+ 'S', // signals
+ 'B', // bridge
+ 'T', // tunnel
+ 'R', // remove
+ 'C', // convert rail
+ 'L', // landscaping
+};
+
+
+static void UpdateRemoveWidgetStatus(Window *w, int clicked_widget)
+{
+ /* If it is the removal button that has been clicked, do nothing,
+ * as it is up to the other buttons to drive removal status */
+ if (clicked_widget == RTW_REMOVE) return;
+
+ switch (clicked_widget) {
+ case RTW_BUILD_NS:
+ case RTW_BUILD_X:
+ case RTW_BUILD_EW:
+ case RTW_BUILD_Y:
+ case RTW_AUTORAIL:
+ case RTW_BUILD_WAYPOINT:
+ case RTW_BUILD_STATION:
+ case RTW_BUILD_SIGNALS:
+ /* Removal button is enabled only if the rail/signal/waypoint/station
+ * button is still lowered. Once raised, it has to be disabled */
+ SetWindowWidgetDisabledState(w, RTW_REMOVE, !IsWindowWidgetLowered(w, clicked_widget));
+ break;
+
+ default:
+ /* When any other buttons than rail/signal/waypoint/station, raise and
+ * disable the removal button*/
+ DisableWindowWidget(w, RTW_REMOVE);
+ RaiseWindowWidget(w, RTW_REMOVE);
+ break;
+ }
+}
+
+static void BuildRailToolbWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_CREATE: DisableWindowWidget(w, RTW_REMOVE); break;
+
+ case WE_PAINT: DrawWindowWidgets(w); break;
+
+ case WE_CLICK:
+ if (e->we.click.widget >= 4) {
+ _remove_button_clicked = false;
+ _build_railroad_button_proc[e->we.click.widget - 4](w);
+ }
+ UpdateRemoveWidgetStatus(w, e->we.click.widget);
+ break;
+
+ case WE_KEYPRESS: {
+ uint i;
+
+ for (i = 0; i != lengthof(_rail_keycodes); i++) {
+ if (e->we.keypress.keycode == _rail_keycodes[i]) {
+ e->we.keypress.cont = false;
+ _remove_button_clicked = false;
+ _build_railroad_button_proc[i](w);
+ UpdateRemoveWidgetStatus(w, i + 4);
+ break;
+ }
+ }
+ MarkTileDirty(_thd.pos.x, _thd.pos.y); // redraw tile selection
+ break;
+ }
+
+ case WE_PLACE_OBJ:
+ _place_proc(e->we.place.tile);
+ return;
+
+ case WE_PLACE_DRAG: {
+ VpSelectTilesWithMethod(e->we.place.pt.x, e->we.place.pt.y, e->we.place.userdata & 0xF);
+ return;
+ }
+
+ case WE_PLACE_MOUSEUP:
+ if (e->we.place.pt.x != -1) {
+ TileIndex start_tile = e->we.place.starttile;
+ TileIndex end_tile = e->we.place.tile;
+
+ if (e->we.place.userdata == VPM_X_OR_Y) {
+ ResetObjectToPlace();
+ ShowBuildBridgeWindow(start_tile, end_tile, _cur_railtype);
+ } else if (e->we.place.userdata == VPM_RAILDIRS) {
+ bool old = _remove_button_clicked;
+ if (_ctrl_pressed) _remove_button_clicked = true;
+ HandleAutodirPlacement();
+ _remove_button_clicked = old;
+ } else if (e->we.place.userdata == VPM_SIGNALDIRS) {
+ HandleAutoSignalPlacement();
+ } else if ((e->we.place.userdata & 0xF) == VPM_X_AND_Y) {
+ if (GUIPlaceProcDragXY(e)) break;
+
+ if ((e->we.place.userdata >> 4) == GUI_PlaceProc_ConvertRailArea >> 4)
+ DoCommandP(end_tile, start_tile, _cur_railtype, CcPlaySound10, CMD_CONVERT_RAIL | CMD_MSG(STR_CANT_CONVERT_RAIL));
+ } else if (e->we.place.userdata == VPM_X_AND_Y_LIMITED) {
+ HandleStationPlacement(start_tile, end_tile);
+ } else {
+ DoRailroadTrack(e->we.place.userdata & 1);
+ }
+ }
+ break;
+
+ case WE_ABORT_PLACE_OBJ:
+ RaiseWindowButtons(w);
+ DisableWindowWidget(w, RTW_REMOVE);
+ InvalidateWidget(w, RTW_REMOVE);
+
+ w = FindWindowById(WC_BUILD_STATION, 0);
+ if (w != NULL) WP(w,def_d).close = true;
+ w = FindWindowById(WC_BUILD_DEPOT, 0);
+ if (w != NULL) WP(w,def_d).close = true;
+ break;
+
+ case WE_PLACE_PRESIZE: {
+ TileIndex tile = e->we.place.tile;
+
+ DoCommand(tile, 0, 0, DC_AUTO, CMD_BUILD_TUNNEL);
+ VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile);
+ } break;
+
+ case WE_DESTROY:
+ if (_patches.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0);
+ break;
+ }
+}
+
+
+static const Widget _build_rail_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 359, 0, 13, STR_100A_RAILROAD_CONSTRUCTION, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_STICKYBOX, RESIZE_NONE, 7, 360, 371, 0, 13, 0x0, STR_STICKY_BUTTON},
+
+{ WWT_PANEL, RESIZE_NONE, 7, 110, 113, 14, 35, 0x0, STR_NULL},
+
+{ WWT_IMGBTN, RESIZE_NONE, 7, 0, 21, 14, 35, SPR_IMG_RAIL_NS, STR_1018_BUILD_RAILROAD_TRACK},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 22, 43, 14, 35, SPR_IMG_RAIL_NE, STR_1018_BUILD_RAILROAD_TRACK},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 44, 65, 14, 35, SPR_IMG_RAIL_EW, STR_1018_BUILD_RAILROAD_TRACK},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 66, 87, 14, 35, SPR_IMG_RAIL_NW, STR_1018_BUILD_RAILROAD_TRACK},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 88, 109, 14, 35, SPR_IMG_AUTORAIL, STR_BUILD_AUTORAIL_TIP},
+
+{ WWT_IMGBTN, RESIZE_NONE, 7, 114, 135, 14, 35, SPR_IMG_DYNAMITE, STR_018D_DEMOLISH_BUILDINGS_ETC},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 136, 157, 14, 35, SPR_IMG_DEPOT_RAIL, STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 158, 179, 14, 35, SPR_IMG_WAYPOINT, STR_CONVERT_RAIL_TO_WAYPOINT_TIP},
+
+{ WWT_IMGBTN, RESIZE_NONE, 7, 180, 221, 14, 35, SPR_IMG_RAIL_STATION, STR_101A_BUILD_RAILROAD_STATION},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 222, 243, 14, 35, SPR_IMG_RAIL_SIGNALS, STR_101B_BUILD_RAILROAD_SIGNALS},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 244, 285, 14, 35, SPR_IMG_BRIDGE, STR_101C_BUILD_RAILROAD_BRIDGE},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 286, 305, 14, 35, SPR_IMG_TUNNEL_RAIL, STR_101D_BUILD_RAILROAD_TUNNEL},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 306, 327, 14, 35, SPR_IMG_REMOVE, STR_101E_TOGGLE_BUILD_REMOVE_FOR},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 328, 349, 14, 35, SPR_IMG_CONVERT_RAIL, STR_CONVERT_RAIL_TIP},
+
+{ WWT_IMGBTN, RESIZE_NONE, 7, 350, 371, 14, 35, SPR_IMG_LANDSCAPING, STR_LANDSCAPING_TOOLBAR_TIP},
+
+{ WIDGETS_END},
+};
+
+static const WindowDesc _build_rail_desc = {
+ WDP_ALIGN_TBR, 22, 372, 36,
+ WC_BUILD_TOOLBAR, 0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON,
+ _build_rail_widgets,
+ BuildRailToolbWndProc
+};
+
+
+/** Configures the rail toolbar for railtype given
+ * @param railtype the railtype to display
+ * @param w the window to modify
+ */
+static void SetupRailToolbar(RailType railtype, Window *w)
+{
+ const RailtypeInfo *rti = GetRailTypeInfo(railtype);
+
+ assert(railtype < RAILTYPE_END);
+ w->widget[RTW_CAPTION].data = rti->strings.toolbar_caption;
+ w->widget[RTW_BUILD_NS].data = rti->gui_sprites.build_ns_rail;
+ w->widget[RTW_BUILD_X].data = rti->gui_sprites.build_x_rail;
+ w->widget[RTW_BUILD_EW].data = rti->gui_sprites.build_ew_rail;
+ w->widget[RTW_BUILD_Y].data = rti->gui_sprites.build_y_rail;
+ w->widget[RTW_AUTORAIL].data = rti->gui_sprites.auto_rail;
+ w->widget[RTW_BUILD_DEPOT].data = rti->gui_sprites.build_depot;
+ w->widget[RTW_CONVERT_RAIL].data = rti->gui_sprites.convert_rail;
+ w->widget[RTW_BUILD_TUNNEL].data = rti->gui_sprites.build_tunnel;
+}
+
+void ShowBuildRailToolbar(RailType railtype, int button)
+{
+ Window *w;
+
+ if (!IsValidPlayer(_current_player)) return;
+ if (!ValParamRailtype(railtype)) return;
+
+ // don't recreate the window if we're clicking on a button and the window exists.
+ if (button < 0 || !(w = FindWindowById(WC_BUILD_TOOLBAR, 0)) || w->wndproc != BuildRailToolbWndProc) {
+ DeleteWindowById(WC_BUILD_TOOLBAR, 0);
+ _cur_railtype = railtype;
+ w = AllocateWindowDesc(&_build_rail_desc);
+ SetupRailToolbar(railtype, w);
+ }
+
+ _remove_button_clicked = false;
+ if (w != NULL && button >= 0) {
+ _build_railroad_button_proc[button](w);
+ UpdateRemoveWidgetStatus(w, button + 4);
+ }
+ if (_patches.link_terraform_toolbar) ShowTerraformToolbar();
+}
+
+/* TODO: For custom stations, respect their allowed platforms/lengths bitmasks!
+ * --pasky */
+
+static void HandleStationPlacement(TileIndex start, TileIndex end)
+{
+ uint sx = TileX(start);
+ uint sy = TileY(start);
+ uint ex = TileX(end);
+ uint ey = TileY(end);
+ uint w,h;
+
+ if (sx > ex) uintswap(sx,ex);
+ if (sy > ey) uintswap(sy,ey);
+ w = ex - sx + 1;
+ h = ey - sy + 1;
+ if (!_railstation.orientation) uintswap(w,h);
+
+ DoCommandP(TileXY(sx, sy),
+ _railstation.orientation | (w << 8) | (h << 16),
+ _cur_railtype | (_railstation.station_class << 8) | (_railstation.station_type << 16), CcStation,
+ CMD_BUILD_RAILROAD_STATION | CMD_NO_WATER | CMD_AUTO | CMD_MSG(STR_100F_CAN_T_BUILD_RAILROAD_STATION));
+}
+
+/* Check if the currently selected station size is allowed */
+static void CheckSelectedSize(Window *w, const StationSpec *statspec)
+{
+ if (statspec == NULL || _railstation.dragdrop) return;
+
+ if (HASBIT(statspec->disallowed_platforms, _railstation.numtracks - 1)) {
+ RaiseWindowWidget(w, _railstation.numtracks + 4);
+ _railstation.numtracks = 1;
+ while (HASBIT(statspec->disallowed_platforms, _railstation.numtracks - 1)) {
+ _railstation.numtracks++;
+ }
+ LowerWindowWidget(w, _railstation.numtracks + 4);
+ }
+
+ if (HASBIT(statspec->disallowed_lengths, _railstation.platlength - 1)) {
+ RaiseWindowWidget(w, _railstation.platlength + 11);
+ _railstation.platlength = 1;
+ while (HASBIT(statspec->disallowed_lengths, _railstation.platlength - 1)) {
+ _railstation.platlength++;
+ }
+ LowerWindowWidget(w, _railstation.platlength + 11);
+ }
+}
+
+static void StationBuildWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_CREATE:
+ LowerWindowWidget(w, _railstation.orientation + 3);
+ if (_railstation.dragdrop) {
+ LowerWindowWidget(w, 19);
+ } else {
+ LowerWindowWidget(w, _railstation.numtracks + 4);
+ LowerWindowWidget(w, _railstation.platlength + 11);
+ }
+ SetWindowWidgetLoweredState(w, 20, !_station_show_coverage);
+ SetWindowWidgetLoweredState(w, 21, _station_show_coverage);
+ break;
+
+ case WE_PAINT: {
+ int rad;
+ uint bits;
+ bool newstations = _railstation.newstations;
+ int y_offset;
+ DrawPixelInfo tmp_dpi, *old_dpi;
+
+ if (WP(w,def_d).close) return;
+
+ if (_railstation.dragdrop) {
+ SetTileSelectSize(1, 1);
+ } else {
+ int x = _railstation.numtracks;
+ int y = _railstation.platlength;
+ if (_railstation.orientation == 0) intswap(x,y);
+ if (!_remove_button_clicked)
+ SetTileSelectSize(x, y);
+ }
+
+ rad = (_patches.modified_catchment) ? CA_TRAIN : 4;
+
+ if (_station_show_coverage)
+ SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
+
+ /* Update buttons for correct spread value */
+ for (bits = _patches.station_spread; bits < 7; bits++) {
+ DisableWindowWidget(w, bits + 5);
+ DisableWindowWidget(w, bits + 12);
+ }
+
+ if (newstations) {
+ const StationSpec *statspec = GetCustomStationSpec(_railstation.station_class, _railstation.station_type);
+
+ for (bits = 0; bits < 7; bits++) {
+ if (statspec == NULL) {
+ EnableWindowWidget(w, bits + 5);
+ EnableWindowWidget(w, bits + 12);
+ } else {
+ SetWindowWidgetDisabledState(w, bits + 5, HASBIT(statspec->disallowed_platforms, bits));
+ SetWindowWidgetDisabledState(w, bits + 12, HASBIT(statspec->disallowed_lengths, bits));
+ }
+ }
+ }
+
+ SetDParam(0, GetStationClassName(_railstation.station_class));
+ DrawWindowWidgets(w);
+
+ y_offset = newstations ? 90 : 0;
+
+ /* Set up a clipping area for the '/' station preview */
+ if (FillDrawPixelInfo(&tmp_dpi, 7, 26 + y_offset, 66, 48)) {
+ old_dpi = _cur_dpi;
+ _cur_dpi = &tmp_dpi;
+ if (!DrawStationTile(32, 16, _cur_railtype, AXIS_X, _railstation.station_class, _railstation.station_type)) {
+ StationPickerDrawSprite(32, 16, _cur_railtype, 2);
+ }
+ _cur_dpi = old_dpi;
+ }
+
+ /* Set up a clipping area for the '\' station preview */
+ if (FillDrawPixelInfo(&tmp_dpi, 75, 26 + y_offset, 66, 48)) {
+ old_dpi = _cur_dpi;
+ _cur_dpi = &tmp_dpi;
+ if (!DrawStationTile(32, 16, _cur_railtype, AXIS_Y, _railstation.station_class, _railstation.station_type)) {
+ StationPickerDrawSprite(32, 16, _cur_railtype, 3);
+ }
+ _cur_dpi = old_dpi;
+ }
+
+ DrawStringCentered(74, 15 + y_offset, STR_3002_ORIENTATION, 0);
+ DrawStringCentered(74, 76 + y_offset, STR_3003_NUMBER_OF_TRACKS, 0);
+ DrawStringCentered(74, 101 + y_offset, STR_3004_PLATFORM_LENGTH, 0);
+ DrawStringCentered(74, 141 + y_offset, STR_3066_COVERAGE_AREA_HIGHLIGHT, 0);
+
+ DrawStationCoverageAreaText(2, 166 + y_offset, (uint)-1, rad);
+
+ if (newstations) {
+ uint16 i;
+ uint y = 35;
+
+ for (i = w->vscroll.pos; i < _railstation.station_count && i < (uint)(w->vscroll.pos + w->vscroll.cap); i++) {
+ const StationSpec *statspec = GetCustomStationSpec(_railstation.station_class, i);
+
+ if (statspec != NULL && statspec->name != 0) {
+ if (HASBIT(statspec->callbackmask, CBM_STATION_AVAIL) && GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE) == 0) {
+ GfxFillRect(8, y - 2, 127, y + 10, PALETTE_MODIFIER_GREYOUT);
+ }
+
+ DrawStringTruncated(9, y, statspec->name, i == _railstation.station_type ? 12 : 16, 118);
+ } else {
+ DrawStringTruncated(9, y, STR_STAT_CLASS_DFLT, i == _railstation.station_type ? 12 : 16, 118);
+ }
+
+ y += 14;
+ }
+ }
+ } break;
+
+ case WE_CLICK: {
+ switch (e->we.click.widget) {
+ case 3:
+ case 4:
+ RaiseWindowWidget(w, _railstation.orientation + 3);
+ _railstation.orientation = e->we.click.widget - 3;
+ LowerWindowWidget(w, _railstation.orientation + 3);
+ SndPlayFx(SND_15_BEEP);
+ SetWindowDirty(w);
+ break;
+
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ RaiseWindowWidget(w, _railstation.numtracks + 4);
+ RaiseWindowWidget(w, 19);
+ _railstation.numtracks = (e->we.click.widget - 5) + 1;
+ _railstation.dragdrop = false;
+ LowerWindowWidget(w, _railstation.platlength + 11);
+ LowerWindowWidget(w, _railstation.numtracks + 4);
+ SndPlayFx(SND_15_BEEP);
+ SetWindowDirty(w);
+ break;
+
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ case 16:
+ case 17:
+ case 18:
+ RaiseWindowWidget(w, _railstation.platlength + 11);
+ RaiseWindowWidget(w, 19);
+ _railstation.platlength = (e->we.click.widget - 12) + 1;
+ _railstation.dragdrop = false;
+ LowerWindowWidget(w, _railstation.platlength + 11);
+ LowerWindowWidget(w, _railstation.numtracks + 4);
+ SndPlayFx(SND_15_BEEP);
+ SetWindowDirty(w);
+ break;
+
+ case 19:
+ _railstation.dragdrop ^= true;
+ ToggleWidgetLoweredState(w, 19);
+ SetWindowWidgetLoweredState(w, _railstation.numtracks + 4, !_railstation.dragdrop);
+ SetWindowWidgetLoweredState(w, _railstation.platlength + 11, !_railstation.dragdrop);
+ SndPlayFx(SND_15_BEEP);
+ SetWindowDirty(w);
+ break;
+
+ case 20:
+ case 21:
+ _station_show_coverage = e->we.click.widget - 20;
+ SetWindowWidgetLoweredState(w, 20, !_station_show_coverage);
+ SetWindowWidgetLoweredState(w, 21, _station_show_coverage);
+ SndPlayFx(SND_15_BEEP);
+ SetWindowDirty(w);
+ break;
+
+ case 22:
+ case 23:
+ ShowDropDownMenu(w, BuildStationClassDropdown(), _railstation.station_class, 23, 0, 1 << STAT_CLASS_WAYP);
+ break;
+
+ case 24: {
+ const StationSpec *statspec;
+ int y = (e->we.click.pt.y - 32) / 14;
+
+ if (y >= w->vscroll.cap) return;
+ y += w->vscroll.pos;
+ if (y >= _railstation.station_count) return;
+
+ /* Check station availability callback */
+ statspec = GetCustomStationSpec(_railstation.station_class, y);
+ if (statspec != NULL &&
+ HASBIT(statspec->callbackmask, CBM_STATION_AVAIL) &&
+ GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE) == 0) return;
+
+ _railstation.station_type = y;
+
+ CheckSelectedSize(w, statspec);
+
+ SndPlayFx(SND_15_BEEP);
+ SetWindowDirty(w);
+ break;
+ }
+ }
+ } break;
+
+ case WE_DROPDOWN_SELECT:
+ if (_railstation.station_class != e->we.dropdown.index) {
+ _railstation.station_class = e->we.dropdown.index;
+ _railstation.station_type = 0;
+ _railstation.station_count = GetNumCustomStations(_railstation.station_class);
+
+ CheckSelectedSize(w, GetCustomStationSpec(_railstation.station_class, _railstation.station_type));
+
+ w->vscroll.count = _railstation.station_count;
+ w->vscroll.pos = _railstation.station_type;
+ }
+
+ SndPlayFx(SND_15_BEEP);
+ SetWindowDirty(w);
+ break;
+
+ case WE_MOUSELOOP:
+ if (WP(w,def_d).close) {
+ DeleteWindow(w);
+ return;
+ }
+ CheckRedrawStationCoverage(w);
+ break;
+
+ case WE_DESTROY:
+ if (!WP(w,def_d).close) ResetObjectToPlace();
+ break;
+ }
+}
+
+static const Widget _station_builder_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 147, 0, 13, STR_3000_RAIL_STATION_SELECTION, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 147, 14, 199, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 14, 7, 72, 26, 73, 0x0, STR_304E_SELECT_RAILROAD_STATION},
+{ WWT_PANEL, RESIZE_NONE, 14, 75, 140, 26, 73, 0x0, STR_304E_SELECT_RAILROAD_STATION},
+
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 22, 36, 87, 98, STR_00CB_1, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 37, 51, 87, 98, STR_00CC_2, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 52, 66, 87, 98, STR_00CD_3, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 67, 81, 87, 98, STR_00CE_4, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 82, 96, 87, 98, STR_00CF_5, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 97, 111, 87, 98, STR_0335_6, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 112, 126, 87, 98, STR_0336_7, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
+
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 22, 36, 112, 123, STR_00CB_1, STR_3050_SELECT_LENGTH_OF_RAILROAD},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 37, 51, 112, 123, STR_00CC_2, STR_3050_SELECT_LENGTH_OF_RAILROAD},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 52, 66, 112, 123, STR_00CD_3, STR_3050_SELECT_LENGTH_OF_RAILROAD},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 67, 81, 112, 123, STR_00CE_4, STR_3050_SELECT_LENGTH_OF_RAILROAD},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 82, 96, 112, 123, STR_00CF_5, STR_3050_SELECT_LENGTH_OF_RAILROAD},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 97, 111, 112, 123, STR_0335_6, STR_3050_SELECT_LENGTH_OF_RAILROAD},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 112, 126, 112, 123, STR_0336_7, STR_3050_SELECT_LENGTH_OF_RAILROAD},
+
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 37, 111, 126, 137, STR_DRAG_DROP, STR_STATION_DRAG_DROP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 14, 73, 152, 163, STR_02DB_OFF, STR_3065_DON_T_HIGHLIGHT_COVERAGE},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 74, 133, 152, 163, STR_02DA_ON, STR_3064_HIGHLIGHT_COVERAGE_AREA},
+{ WIDGETS_END},
+};
+
+static const Widget _newstation_builder_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 147, 0, 13, STR_3000_RAIL_STATION_SELECTION, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 147, 14, 289, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 14, 7, 72, 116, 163, 0x0, STR_304E_SELECT_RAILROAD_STATION},
+{ WWT_PANEL, RESIZE_NONE, 14, 75, 140, 116, 163, 0x0, STR_304E_SELECT_RAILROAD_STATION},
+
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 22, 36, 177, 188, STR_00CB_1, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 37, 51, 177, 188, STR_00CC_2, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 52, 66, 177, 188, STR_00CD_3, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 67, 81, 177, 188, STR_00CE_4, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 82, 96, 177, 188, STR_00CF_5, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 97, 111, 177, 188, STR_0335_6, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 112, 126, 177, 188, STR_0336_7, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
+
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 22, 36, 202, 213, STR_00CB_1, STR_3050_SELECT_LENGTH_OF_RAILROAD},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 37, 51, 202, 213, STR_00CC_2, STR_3050_SELECT_LENGTH_OF_RAILROAD},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 52, 66, 202, 213, STR_00CD_3, STR_3050_SELECT_LENGTH_OF_RAILROAD},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 67, 81, 202, 213, STR_00CE_4, STR_3050_SELECT_LENGTH_OF_RAILROAD},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 82, 96, 202, 213, STR_00CF_5, STR_3050_SELECT_LENGTH_OF_RAILROAD},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 97, 111, 202, 213, STR_0335_6, STR_3050_SELECT_LENGTH_OF_RAILROAD},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 112, 126, 202, 213, STR_0336_7, STR_3050_SELECT_LENGTH_OF_RAILROAD},
+
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 37, 111, 216, 227, STR_DRAG_DROP, STR_STATION_DRAG_DROP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 14, 73, 242, 253, STR_02DB_OFF, STR_3065_DON_T_HIGHLIGHT_COVERAGE},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 74, 133, 242, 253, STR_02DA_ON, STR_3064_HIGHLIGHT_COVERAGE_AREA},
+
+/* newstations gui additions */
+{ WWT_INSET, RESIZE_NONE, 14, 7, 140, 17, 28, STR_02BD, STR_SELECT_STATION_CLASS_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 129, 139, 18, 27, STR_0225, STR_SELECT_STATION_CLASS_TIP},
+{ WWT_MATRIX, RESIZE_NONE, 14, 7, 128, 32, 102, 0x501, STR_SELECT_STATION_TYPE_TIP},
+{ WWT_SCROLLBAR, RESIZE_NONE, 14, 129, 140, 32, 102, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _station_builder_desc = {
+ WDP_AUTO, WDP_AUTO, 148, 200,
+ WC_BUILD_STATION, WC_BUILD_TOOLBAR,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _station_builder_widgets,
+ StationBuildWndProc
+};
+
+static const WindowDesc _newstation_builder_desc = {
+ WDP_AUTO, WDP_AUTO, 148, 290,
+ WC_BUILD_STATION, WC_BUILD_TOOLBAR,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _newstation_builder_widgets,
+ StationBuildWndProc
+};
+
+static void ShowStationBuilder(void)
+{
+ Window *w;
+ if (GetNumStationClasses() <= 2 && GetNumCustomStations(STAT_CLASS_DFLT) == 1) {
+ w = AllocateWindowDesc(&_station_builder_desc);
+ _railstation.newstations = false;
+ } else {
+ w = AllocateWindowDesc(&_newstation_builder_desc);
+ _railstation.newstations = true;
+ _railstation.station_count = GetNumCustomStations(_railstation.station_class);
+
+ w->vscroll.count = _railstation.station_count;
+ w->vscroll.cap = 5;
+ w->vscroll.pos = clamp(_railstation.station_type - 2, 0, w->vscroll.count - w->vscroll.cap);
+ }
+}
+
+static void BuildTrainDepotWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_CREATE: LowerWindowWidget(w, _build_depot_direction + 3); break;
+
+ case WE_PAINT: {
+ RailType r;
+
+ DrawWindowWidgets(w);
+
+ r = _cur_railtype;
+ DrawTrainDepotSprite(70, 17, 0, r);
+ DrawTrainDepotSprite(70, 69, 1, r);
+ DrawTrainDepotSprite( 2, 69, 2, r);
+ DrawTrainDepotSprite( 2, 17, 3, r);
+ break;
+ }
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ RaiseWindowWidget(w, _build_depot_direction + 3);
+ _build_depot_direction = e->we.click.widget - 3;
+ LowerWindowWidget(w, _build_depot_direction + 3);
+ SndPlayFx(SND_15_BEEP);
+ SetWindowDirty(w);
+ break;
+ }
+ break;
+
+ case WE_MOUSELOOP:
+ if (WP(w,def_d).close) DeleteWindow(w);
+ return;
+
+ case WE_DESTROY:
+ if (!WP(w,def_d).close) ResetObjectToPlace();
+ break;
+ }
+}
+
+static const Widget _build_depot_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 139, 0, 13, STR_1014_TRAIN_DEPOT_ORIENTATION, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 139, 14, 121, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 14, 71, 136, 17, 66, 0x0, STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO},
+{ WWT_PANEL, RESIZE_NONE, 14, 71, 136, 69, 118, 0x0, STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO},
+{ WWT_PANEL, RESIZE_NONE, 14, 3, 68, 69, 118, 0x0, STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO},
+{ WWT_PANEL, RESIZE_NONE, 14, 3, 68, 17, 66, 0x0, STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _build_depot_desc = {
+ WDP_AUTO, WDP_AUTO, 140, 122,
+ WC_BUILD_DEPOT, WC_BUILD_TOOLBAR,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _build_depot_widgets,
+ BuildTrainDepotWndProc
+};
+
+static void ShowBuildTrainDepotPicker(void)
+{
+ AllocateWindowDesc(&_build_depot_desc);
+}
+
+
+static void BuildWaypointWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ uint i;
+
+ for (i = 0; i < w->hscroll.cap; i++) {
+ SetWindowWidgetLoweredState(w, i + 3, (w->hscroll.pos + i) == _cur_waypoint_type);
+ }
+
+ DrawWindowWidgets(w);
+
+ for (i = 0; i < w->hscroll.cap; i++) {
+ if (w->hscroll.pos + i < w->hscroll.count) {
+ const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, w->hscroll.pos + i);
+
+ DrawWaypointSprite(2 + i * 68, 25, w->hscroll.pos + i, _cur_railtype);
+
+ if (statspec != NULL &&
+ HASBIT(statspec->callbackmask, CBM_STATION_AVAIL) &&
+ GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE) == 0) {
+ GfxFillRect(4 + i * 68, 18, 67 + i * 68, 75, PALETTE_MODIFIER_GREYOUT);
+ }
+ }
+ }
+ break;
+ }
+ case WE_CLICK: {
+ switch (e->we.click.widget) {
+ case 3: case 4: case 5: case 6: case 7: {
+ byte type = e->we.click.widget - 3 + w->hscroll.pos;
+
+ /* Check station availability callback */
+ const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, type);
+ if (statspec != NULL &&
+ HASBIT(statspec->callbackmask, CBM_STATION_AVAIL) &&
+ GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE) == 0) return;
+
+ _cur_waypoint_type = type;
+ SndPlayFx(SND_15_BEEP);
+ SetWindowDirty(w);
+ break;
+ }
+ }
+ break;
+ }
+
+ case WE_MOUSELOOP:
+ if (WP(w,def_d).close) DeleteWindow(w);
+ break;
+
+ case WE_DESTROY:
+ if (!WP(w,def_d).close) ResetObjectToPlace();
+ break;
+ }
+}
+
+static const Widget _build_waypoint_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 343, 0, 13, STR_WAYPOINT, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 343, 14, 91, 0x0, 0},
+
+{ WWT_PANEL, RESIZE_NONE, 7, 3, 68, 17, 76, 0x0, STR_WAYPOINT_GRAPHICS_TIP},
+{ WWT_PANEL, RESIZE_NONE, 7, 71, 136, 17, 76, 0x0, STR_WAYPOINT_GRAPHICS_TIP},
+{ WWT_PANEL, RESIZE_NONE, 7, 139, 204, 17, 76, 0x0, STR_WAYPOINT_GRAPHICS_TIP},
+{ WWT_PANEL, RESIZE_NONE, 7, 207, 272, 17, 76, 0x0, STR_WAYPOINT_GRAPHICS_TIP},
+{ WWT_PANEL, RESIZE_NONE, 7, 275, 340, 17, 76, 0x0, STR_WAYPOINT_GRAPHICS_TIP},
+
+{ WWT_HSCROLLBAR, RESIZE_NONE, 7, 1, 343, 80, 91, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _build_waypoint_desc = {
+ WDP_AUTO, WDP_AUTO, 344, 92,
+ WC_BUILD_DEPOT, WC_BUILD_TOOLBAR,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _build_waypoint_widgets,
+ BuildWaypointWndProc
+};
+
+static void ShowBuildWaypointPicker(void)
+{
+ Window *w = AllocateWindowDesc(&_build_waypoint_desc);
+ w->hscroll.cap = 5;
+ w->hscroll.count = _waypoint_count;
+}
+
+
+void InitializeRailGui(void)
+{
+ _build_depot_direction = DIAGDIR_NW;
+ _railstation.numtracks = 1;
+ _railstation.platlength = 1;
+ _railstation.dragdrop = true;
+}
+
+void ReinitGuiAfterToggleElrail(bool disable)
+{
+ extern RailType _last_built_railtype;
+ if (disable && _last_built_railtype == RAILTYPE_ELECTRIC) {
+ Window *w;
+ _last_built_railtype = _cur_railtype = RAILTYPE_RAIL;
+ w = FindWindowById(WC_BUILD_TOOLBAR, 0);
+ if (w != NULL && w->wndproc == BuildRailToolbWndProc) {
+ SetupRailToolbar(_cur_railtype, w);
+ SetWindowDirty(w);
+ }
+ }
+ MarkWholeScreenDirty();
+}
+
+
diff --git a/src/rail_map.h b/src/rail_map.h
new file mode 100644
index 000000000..902d4e6a4
--- /dev/null
+++ b/src/rail_map.h
@@ -0,0 +1,342 @@
+/* $Id$ */
+
+#ifndef RAIL_MAP_H
+#define RAIL_MAP_H
+
+#include "direction.h"
+#include "rail.h"
+#include "tile.h"
+
+
+typedef enum RailTileType {
+ RAIL_TILE_NORMAL = 0x0,
+ RAIL_TILE_SIGNALS = 0x40,
+ RAIL_TILE_UNUSED = 0x80, /* XXX: Maybe this could become waypoints? */
+ RAIL_TILE_DEPOT_WAYPOINT = 0xC0, /* Is really depots and waypoints... */
+ RAIL_TILE_TYPE_MASK = 0xC0
+} RailTileType;
+
+static inline RailTileType GetRailTileType(TileIndex t)
+{
+ assert(IsTileType(t, MP_RAILWAY));
+ return (RailTileType)(_m[t].m5 & RAIL_TILE_TYPE_MASK);
+}
+
+/**
+ * Returns whether this is plain rails, with or without signals. Iow, if this
+ * tiles RailTileType is RAIL_TILE_NORMAL or RAIL_TILE_SIGNALS.
+ */
+static inline bool IsPlainRailTile(TileIndex tile)
+{
+ RailTileType rtt = GetRailTileType(tile);
+ return rtt == RAIL_TILE_NORMAL || rtt == RAIL_TILE_SIGNALS;
+}
+
+/**
+ * Checks if a rail tile has signals.
+ */
+static inline bool HasSignals(TileIndex tile)
+{
+ return GetRailTileType(tile) == RAIL_TILE_SIGNALS;
+}
+
+
+/** These specify the subtype when the main rail type is
+ * RAIL_TILE_DEPOT_WAYPOINT */
+typedef enum RailTileSubtypes {
+ RAIL_SUBTYPE_DEPOT = 0x00,
+ RAIL_SUBTYPE_WAYPOINT = 0x04,
+ RAIL_SUBTYPE_MASK = 0x3C
+} RailTileSubtype;
+
+/**
+ * Returns the RailTileSubtype of a given rail tile with type
+ * RAIL_TILE_DEPOT_WAYPOINT
+ */
+static inline RailTileSubtype GetRailTileSubtype(TileIndex tile)
+{
+ assert(GetRailTileType(tile) == RAIL_TILE_DEPOT_WAYPOINT);
+ return (RailTileSubtype)(_m[tile].m5 & RAIL_SUBTYPE_MASK);
+}
+
+
+static inline bool IsRailDepot(TileIndex t)
+{
+ return
+ GetRailTileType(t) == RAIL_TILE_DEPOT_WAYPOINT &&
+ GetRailTileSubtype(t) == RAIL_SUBTYPE_DEPOT;
+}
+
+
+static inline bool IsRailWaypoint(TileIndex t)
+{
+ return
+ GetRailTileType(t) == RAIL_TILE_DEPOT_WAYPOINT &&
+ GetRailTileSubtype(t) == RAIL_SUBTYPE_WAYPOINT;
+}
+
+
+static inline RailType GetRailType(TileIndex t)
+{
+ return (RailType)GB(_m[t].m3, 0, 4);
+}
+
+// TODO remove this by moving to the same bits as GetRailType()
+static inline RailType GetRailTypeCrossing(TileIndex t)
+{
+ return (RailType)GB(_m[t].m4, 0, 4);
+}
+
+static inline void SetRailType(TileIndex t, RailType r)
+{
+ SB(_m[t].m3, 0, 4, r);
+}
+
+// TODO remove this by moving to the same bits as SetRailType()
+static inline void SetRailTypeCrossing(TileIndex t, RailType r)
+{
+ SB(_m[t].m4, 0, 4, r);
+}
+
+
+static inline TrackBits GetTrackBits(TileIndex tile)
+{
+ return (TrackBits)GB(_m[tile].m5, 0, 6);
+}
+
+static inline void SetTrackBits(TileIndex t, TrackBits b)
+{
+ SB(_m[t].m5, 0, 6, b);
+}
+
+/**
+ * Returns whether the given track is present on the given tile. Tile must be
+ * a plain rail tile (IsPlainRailTile()).
+ */
+static inline bool HasTrack(TileIndex tile, Track track)
+{
+ return HASBIT(GetTrackBits(tile), track);
+}
+
+
+static inline DiagDirection GetRailDepotDirection(TileIndex t)
+{
+ return (DiagDirection)GB(_m[t].m5, 0, 2);
+}
+
+
+static inline Axis GetWaypointAxis(TileIndex t)
+{
+ return (Axis)GB(_m[t].m5, 0, 1);
+}
+
+static inline Track GetRailWaypointTrack(TileIndex t)
+{
+ return AxisToTrack(GetWaypointAxis(t));
+}
+
+static inline TrackBits GetRailWaypointBits(TileIndex t)
+{
+ return TrackToTrackBits(GetRailWaypointTrack(t));
+}
+
+
+typedef enum SignalType {
+ SIGTYPE_NORMAL = 0, // normal signal
+ SIGTYPE_ENTRY = 1, // presignal block entry
+ SIGTYPE_EXIT = 2, // presignal block exit
+ SIGTYPE_COMBO = 3 // presignal inter-block
+} SignalType;
+
+static inline SignalType GetSignalType(TileIndex t)
+{
+ assert(GetRailTileType(t) == RAIL_TILE_SIGNALS);
+ return (SignalType)GB(_m[t].m4, 0, 2);
+}
+
+static inline void SetSignalType(TileIndex t, SignalType s)
+{
+ assert(GetRailTileType(t) == RAIL_TILE_SIGNALS);
+ SB(_m[t].m4, 0, 2, s);
+}
+
+static inline bool IsPresignalEntry(TileIndex t)
+{
+ return GetSignalType(t) == SIGTYPE_ENTRY || GetSignalType(t) == SIGTYPE_COMBO;
+}
+
+static inline bool IsPresignalExit(TileIndex t)
+{
+ return GetSignalType(t) == SIGTYPE_EXIT || GetSignalType(t) == SIGTYPE_COMBO;
+}
+
+static inline void CycleSignalSide(TileIndex t, Track track)
+{
+ byte sig;
+ byte pos = 6;
+ if (track == TRACK_LOWER || track == TRACK_RIGHT) pos = 4;
+
+ sig = GB(_m[t].m3, pos, 2);
+ if (--sig == 0) sig = 3;
+ SB(_m[t].m3, pos, 2, sig);
+}
+
+
+typedef enum SignalVariant {
+ SIG_ELECTRIC = 0,
+ SIG_SEMAPHORE = 1
+} SignalVariant;
+
+static inline SignalVariant GetSignalVariant(TileIndex t)
+{
+ return (SignalVariant)GB(_m[t].m4, 2, 1);
+}
+
+static inline void SetSignalVariant(TileIndex t, SignalVariant v)
+{
+ SB(_m[t].m4, 2, 1, v);
+}
+
+static inline bool IsSignalPresent(TileIndex t, byte signalbit)
+{
+ return HASBIT(_m[t].m3, signalbit + 4);
+}
+
+/** These are states in which a signal can be. Currently these are only two, so
+ * simple boolean logic will do. But do try to compare to this enum instead of
+ * normal boolean evaluation, since that will make future additions easier.
+ */
+typedef enum SignalStates {
+ SIGNAL_STATE_RED = 0,
+ SIGNAL_STATE_GREEN = 1,
+} SignalState;
+
+static inline SignalState GetSingleSignalState(TileIndex t, byte signalbit)
+{
+ return (SignalState)HASBIT(_m[t].m2, signalbit + 4);
+}
+
+
+/**
+ * Checks for the presence of signals (either way) on the given track on the
+ * given rail tile.
+ */
+static inline bool HasSignalOnTrack(TileIndex tile, Track track)
+{
+ assert(IsValidTrack(track));
+ return
+ GetRailTileType(tile) == RAIL_TILE_SIGNALS &&
+ (_m[tile].m3 & SignalOnTrack(track)) != 0;
+}
+
+/**
+ * Checks for the presence of signals along the given trackdir on the given
+ * rail tile.
+ *
+ * Along meaning if you are currently driving on the given trackdir, this is
+ * the signal that is facing us (for which we stop when it's red).
+ */
+static inline bool HasSignalOnTrackdir(TileIndex tile, Trackdir trackdir)
+{
+ assert (IsValidTrackdir(trackdir));
+ return
+ GetRailTileType(tile) == RAIL_TILE_SIGNALS &&
+ _m[tile].m3 & SignalAlongTrackdir(trackdir);
+}
+
+/**
+ * Gets the state of the signal along the given trackdir.
+ *
+ * Along meaning if you are currently driving on the given trackdir, this is
+ * the signal that is facing us (for which we stop when it's red).
+ */
+static inline SignalState GetSignalStateByTrackdir(TileIndex tile, Trackdir trackdir)
+{
+ assert(IsValidTrackdir(trackdir));
+ assert(HasSignalOnTrack(tile, TrackdirToTrack(trackdir)));
+ return _m[tile].m2 & SignalAlongTrackdir(trackdir) ?
+ SIGNAL_STATE_GREEN : SIGNAL_STATE_RED;
+}
+
+
+/**
+ * Return the rail type of tile, or INVALID_RAILTYPE if this is no rail tile.
+ * Note that there is no check if the given trackdir is actually present on
+ * the tile!
+ * The given trackdir is used when there are (could be) multiple rail types on
+ * one tile.
+ */
+RailType GetTileRailType(TileIndex tile, Trackdir trackdir);
+
+
+typedef enum RailGroundType {
+ RAIL_GROUND_BARREN = 0,
+ RAIL_GROUND_GRASS = 1,
+ RAIL_GROUND_FENCE_NW = 2,
+ RAIL_GROUND_FENCE_SE = 3,
+ RAIL_GROUND_FENCE_SENW = 4,
+ RAIL_GROUND_FENCE_NE = 5,
+ RAIL_GROUND_FENCE_SW = 6,
+ RAIL_GROUND_FENCE_NESW = 7,
+ RAIL_GROUND_FENCE_VERT1 = 8,
+ RAIL_GROUND_FENCE_VERT2 = 9,
+ RAIL_GROUND_FENCE_HORIZ1 = 10,
+ RAIL_GROUND_FENCE_HORIZ2 = 11,
+ RAIL_GROUND_ICE_DESERT = 12,
+} RailGroundType;
+
+static inline void SetRailGroundType(TileIndex t, RailGroundType rgt)
+{
+ if (GetRailTileType(t) == RAIL_TILE_DEPOT_WAYPOINT) {
+ SB(_m[t].m4, 0, 4, rgt);
+ return;
+ }
+ SB(_m[t].m2, 0, 4, rgt);
+}
+
+static inline RailGroundType GetRailGroundType(TileIndex t)
+{
+ /* TODO Unify this */
+ if (GetRailTileType(t) == RAIL_TILE_DEPOT_WAYPOINT) return (RailGroundType)GB(_m[t].m4, 0, 4);
+ return (RailGroundType)GB(_m[t].m2, 0, 4);
+}
+
+static inline bool IsSnowRailGround(TileIndex t)
+{
+ return GetRailGroundType(t) == RAIL_GROUND_ICE_DESERT;
+}
+
+
+static inline void MakeRailNormal(TileIndex t, Owner o, TrackBits b, RailType r)
+{
+ SetTileType(t, MP_RAILWAY);
+ SetTileOwner(t, o);
+ _m[t].m2 = 0;
+ _m[t].m3 = r;
+ _m[t].m4 = 0;
+ _m[t].m5 = RAIL_TILE_NORMAL | b;
+}
+
+
+static inline void MakeRailDepot(TileIndex t, Owner o, DiagDirection d, RailType r)
+{
+ SetTileType(t, MP_RAILWAY);
+ SetTileOwner(t, o);
+ _m[t].m2 = 0;
+ _m[t].m3 = r;
+ _m[t].m4 = 0;
+ _m[t].m5 = RAIL_TILE_DEPOT_WAYPOINT | RAIL_SUBTYPE_DEPOT | d;
+}
+
+
+static inline void MakeRailWaypoint(TileIndex t, Owner o, Axis a, RailType r, uint index)
+{
+ SetTileType(t, MP_RAILWAY);
+ SetTileOwner(t, o);
+ _m[t].m2 = index;
+ _m[t].m3 = r;
+ _m[t].m4 = 0;
+ _m[t].m5 = RAIL_TILE_DEPOT_WAYPOINT | RAIL_SUBTYPE_WAYPOINT | a;
+}
+
+#endif /* RAIL_MAP_H */
diff --git a/src/railtypes.h b/src/railtypes.h
new file mode 100644
index 000000000..e21c1250d
--- /dev/null
+++ b/src/railtypes.h
@@ -0,0 +1,214 @@
+/* $Id$ */
+
+#ifndef RAILTYPES_H
+#define RAILTYPES_H
+
+/** @file railtypes.h
+ * All the railtype-specific information is stored here.
+ */
+
+/** Global Railtype definition
+ */
+RailtypeInfo _railtypes[] = {
+ /** Railway */
+ { /* Main Sprites */
+ { SPR_RAIL_TRACK_Y, SPR_RAIL_TRACK_N_S, SPR_RAIL_TRACK_BASE, SPR_RAIL_SINGLE_Y, SPR_RAIL_SINGLE_X,
+ SPR_RAIL_SINGLE_NORTH, SPR_RAIL_SINGLE_SOUTH, SPR_RAIL_SINGLE_EAST, SPR_RAIL_SINGLE_WEST,
+ SPR_CROSSING_OFF_X_RAIL,
+ SPR_TUNNEL_ENTRY_REAR_RAIL
+ },
+
+ /* GUI sprites */
+ { 0x4E3, 0x4E4, 0x4E5, 0x4E6,
+ SPR_IMG_AUTORAIL,
+ SPR_IMG_DEPOT_RAIL,
+ SPR_IMG_TUNNEL_RAIL,
+ SPR_IMG_CONVERT_RAIL
+ },
+
+ {
+ SPR_CURSOR_NS_TRACK,
+ SPR_CURSOR_SWNE_TRACK,
+ SPR_CURSOR_EW_TRACK,
+ SPR_CURSOR_NWSE_TRACK,
+ SPR_CURSOR_AUTORAIL,
+ SPR_CURSOR_RAIL_DEPOT,
+ SPR_CURSOR_TUNNEL_RAIL,
+ SPR_CURSOR_CONVERT_RAIL
+ },
+
+ /* strings */
+ { STR_100A_RAILROAD_CONSTRUCTION },
+
+ /* Offset of snow tiles */
+ SPR_RAIL_SNOW_OFFSET,
+
+ /* Powered railtypes */
+ 1 << RAILTYPE_RAIL | 1 << RAILTYPE_ELECTRIC,
+
+ /* Compatible railtypes */
+ 1 << RAILTYPE_RAIL | 1 << RAILTYPE_ELECTRIC,
+
+ /* main offset */
+ 0,
+
+ /* bridge offset */
+ 0,
+
+ /* custom ground offset */
+ 0,
+ },
+
+ /** Electrified railway */
+ { /* Main Sprites */
+ { SPR_RAIL_TRACK_Y, SPR_RAIL_TRACK_N_S, SPR_RAIL_TRACK_BASE, SPR_RAIL_SINGLE_Y, SPR_RAIL_SINGLE_X,
+ SPR_RAIL_SINGLE_NORTH, SPR_RAIL_SINGLE_SOUTH, SPR_RAIL_SINGLE_EAST, SPR_RAIL_SINGLE_WEST,
+ SPR_CROSSING_OFF_X_RAIL,
+ SPR_TUNNEL_ENTRY_REAR_RAIL
+ },
+
+ /* GUI sprites */
+ {
+ SPR_BUILD_NS_ELRAIL,
+ SPR_BUILD_X_ELRAIL,
+ SPR_BUILD_EW_ELRAIL,
+ SPR_BUILD_Y_ELRAIL,
+ SPR_OPENTTD_BASE + 0,
+ 0x50E,
+ SPR_BUILD_TUNNEL_ELRAIL,
+ SPR_IMG_CONVERT_RAIL
+ },
+
+ {
+ SPR_CURSOR_NS_ELRAIL,
+ SPR_CURSOR_SWNE_ELRAIL,
+ SPR_CURSOR_EW_ELRAIL,
+ SPR_CURSOR_NWSE_ELRAIL,
+ SPR_CURSOR_AUTORAIL,
+ SPR_CURSOR_RAIL_DEPOT,
+ SPR_CURSOR_TUNNEL_ELRAIL,
+ SPR_CURSOR_CONVERT_RAIL
+ },
+
+ /* strings */
+ { STR_TITLE_ELRAIL_CONSTRUCTION },
+
+ /* Offset of snow tiles */
+ SPR_RAIL_SNOW_OFFSET,
+
+ /* Powered railtypes */
+ 1 << RAILTYPE_ELECTRIC,
+
+ /* Compatible railtypes */
+ 1 << RAILTYPE_ELECTRIC | 1 << RAILTYPE_RAIL,
+
+ /* main offset */
+ 0,
+
+ /* bridge offset */
+ 0,
+
+ /* custom ground offset */
+ 0,
+ },
+
+ /** Monorail */
+ { /* Main Sprites */
+ { SPR_MONO_TRACK_Y, SPR_MONO_TRACK_N_S, SPR_MONO_TRACK_BASE, SPR_MONO_SINGLE_Y, SPR_MONO_SINGLE_X,
+ SPR_MONO_SINGLE_NORTH, SPR_MONO_SINGLE_SOUTH, SPR_MONO_SINGLE_EAST, SPR_MONO_SINGLE_WEST,
+ SPR_CROSSING_OFF_X_MONO,
+ SPR_TUNNEL_ENTRY_REAR_MONO
+ },
+
+ /* GUI sprites */
+ { 0x4E7, 0x4E8, 0x4E9, 0x4EA,
+ SPR_IMG_AUTOMONO,
+ SPR_IMG_DEPOT_MONO,
+ SPR_IMG_TUNNEL_MONO,
+ SPR_IMG_CONVERT_MONO
+ },
+
+ {
+ SPR_CURSOR_NS_MONO,
+ SPR_CURSOR_SWNE_MONO,
+ SPR_CURSOR_EW_MONO,
+ SPR_CURSOR_NWSE_MONO,
+ SPR_CURSOR_AUTOMONO,
+ SPR_CURSOR_MONO_DEPOT,
+ SPR_CURSOR_TUNNEL_MONO,
+ SPR_CURSOR_CONVERT_MONO
+ },
+
+ /* strings */
+ { STR_100B_MONORAIL_CONSTRUCTION },
+
+ /* Offset of snow tiles */
+ SPR_MONO_SNOW_OFFSET,
+
+ /* Powered railtypes */
+ 1 << RAILTYPE_MONO,
+
+ /* Compatible Railtypes */
+ 1 << RAILTYPE_MONO,
+
+ /* main offset */
+ 82,
+
+ /* bridge offset */
+ 16,
+
+ /* custom ground offset */
+ 1,
+ },
+
+ /** Maglev */
+ { /* Main sprites */
+ { SPR_MGLV_TRACK_Y, SPR_MGLV_TRACK_N_S, SPR_MGLV_TRACK_BASE, SPR_MGLV_SINGLE_Y, SPR_MGLV_SINGLE_X,
+ SPR_MGLV_SINGLE_NORTH, SPR_MGLV_SINGLE_SOUTH, SPR_MGLV_SINGLE_EAST, SPR_MGLV_SINGLE_WEST,
+ SPR_CROSSING_OFF_X_MAGLEV,
+ SPR_TUNNEL_ENTRY_REAR_MAGLEV
+ },
+
+ /* GUI sprites */
+ { 0x4EB, 0x4EC, 0x4EE, 0x4ED,
+ SPR_IMG_AUTOMAGLEV,
+ SPR_IMG_DEPOT_MAGLEV,
+ SPR_IMG_TUNNEL_MAGLEV,
+ SPR_IMG_CONVERT_MAGLEV
+ },
+
+ {
+ SPR_CURSOR_NS_MAGLEV,
+ SPR_CURSOR_SWNE_MAGLEV,
+ SPR_CURSOR_EW_MAGLEV,
+ SPR_CURSOR_NWSE_MAGLEV,
+ SPR_CURSOR_AUTOMAGLEV,
+ SPR_CURSOR_MAGLEV_DEPOT,
+ SPR_CURSOR_TUNNEL_MAGLEV,
+ SPR_CURSOR_CONVERT_MAGLEV
+ },
+
+ /* strings */
+ { STR_100C_MAGLEV_CONSTRUCTION },
+
+ /* Offset of snow tiles */
+ SPR_MGLV_SNOW_OFFSET,
+
+ /* Powered railtypes */
+ 1 << RAILTYPE_MAGLEV,
+
+ /* Compatible Railtypes */
+ 1 << RAILTYPE_MAGLEV,
+
+ /* main offset */
+ 164,
+
+ /* bridge offset */
+ 24,
+
+ /* custom ground offset */
+ 2,
+ },
+};
+
+#endif /* RAILTYPES_H */
diff --git a/src/resource.h b/src/resource.h
new file mode 100644
index 000000000..41ff821b5
--- /dev/null
+++ b/src/resource.h
@@ -0,0 +1,17 @@
+/* $Id$ */
+
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by ttd.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 104
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1005
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/src/road.h b/src/road.h
new file mode 100644
index 000000000..3418ef8cd
--- /dev/null
+++ b/src/road.h
@@ -0,0 +1,26 @@
+/* $Id$ */
+
+#ifndef ROAD_H
+#define ROAD_H
+
+typedef enum RoadBits {
+ ROAD_NW = 1U,
+ ROAD_SW = 2U,
+ ROAD_SE = 4U,
+ ROAD_NE = 8U,
+ ROAD_X = ROAD_SW | ROAD_NE,
+ ROAD_Y = ROAD_NW | ROAD_SE,
+ ROAD_ALL = ROAD_X | ROAD_Y
+} RoadBits;
+
+static inline RoadBits ComplementRoadBits(RoadBits r)
+{
+ return (RoadBits)(ROAD_ALL ^ r);
+}
+
+static inline RoadBits DiagDirToRoadBits(DiagDirection d)
+{
+ return (RoadBits)(1U << (3 ^ d));
+}
+
+#endif /* ROAD_H */
diff --git a/src/road_cmd.c b/src/road_cmd.c
new file mode 100644
index 000000000..9f3bc3f6a
--- /dev/null
+++ b/src/road_cmd.c
@@ -0,0 +1,1065 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "bridge_map.h"
+#include "rail_map.h"
+#include "road_map.h"
+#include "sprite.h"
+#include "table/sprites.h"
+#include "table/strings.h"
+#include "functions.h"
+#include "map.h"
+#include "tile.h"
+#include "town_map.h"
+#include "vehicle.h"
+#include "viewport.h"
+#include "command.h"
+#include "player.h"
+#include "town.h"
+#include "gfx.h"
+#include "sound.h"
+#include "yapf/yapf.h"
+#include "depot.h"
+
+
+static uint CountRoadBits(RoadBits r)
+{
+ uint count = 0;
+
+ if (r & ROAD_NW) ++count;
+ if (r & ROAD_SW) ++count;
+ if (r & ROAD_SE) ++count;
+ if (r & ROAD_NE) ++count;
+ return count;
+}
+
+
+static bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, bool* edge_road)
+{
+ RoadBits present;
+ RoadBits n;
+ Owner owner;
+ *edge_road = true;
+
+ if (_game_mode == GM_EDITOR) return true;
+
+ // Only do the special processing for actual players.
+ if (!IsValidPlayer(_current_player)) return true;
+
+ owner = IsLevelCrossingTile(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile);
+
+ // Only do the special processing if the road is owned
+ // by a town
+ if (owner != OWNER_TOWN) return (owner == OWNER_NONE) || CheckOwnership(owner);
+
+ if (_cheats.magic_bulldozer.value) return true;
+
+ // Get a bitmask of which neighbouring roads has a tile
+ n = 0;
+ present = GetAnyRoadBits(tile);
+ if (present & ROAD_NE && GetAnyRoadBits(TILE_ADDXY(tile,-1, 0)) & ROAD_SW) n |= ROAD_NE;
+ if (present & ROAD_SE && GetAnyRoadBits(TILE_ADDXY(tile, 0, 1)) & ROAD_NW) n |= ROAD_SE;
+ if (present & ROAD_SW && GetAnyRoadBits(TILE_ADDXY(tile, 1, 0)) & ROAD_NE) n |= ROAD_SW;
+ if (present & ROAD_NW && GetAnyRoadBits(TILE_ADDXY(tile, 0,-1)) & ROAD_SE) n |= ROAD_NW;
+
+ // If 0 or 1 bits are set in n, or if no bits that match the bits to remove,
+ // then allow it
+ if ((n & (n - 1)) != 0 && (n & remove) != 0) {
+ Town *t;
+ *edge_road = false;
+ // you can remove all kind of roads with extra dynamite
+ if (_patches.extra_dynamite) return true;
+
+ t = ClosestTownFromTile(tile, _patches.dist_local_authority);
+
+ SetDParam(0, t->index);
+ _error_message = STR_2009_LOCAL_AUTHORITY_REFUSES;
+ return false;
+ }
+
+ return true;
+}
+
+
+/** Delete a piece of road.
+ * @param tile tile where to remove road from
+ * @param p1 road piece flags
+ * @param p2 unused
+ */
+int32 CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ // cost for removing inner/edge -roads
+ static const uint16 road_remove_cost[2] = {50, 18};
+
+ Owner owner;
+ Town *t;
+ /* true if the roadpiece was always removeable,
+ * false if it was a center piece. Affects town ratings drop */
+ bool edge_road;
+ RoadBits pieces;
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ /* Road pieces are max 4 bitset values (NE, NW, SE, SW) */
+ if (p1 >> 4) return CMD_ERROR;
+ pieces = p1;
+
+ if (!IsTileType(tile, MP_STREET)) return CMD_ERROR;
+
+ owner = IsLevelCrossingTile(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile);
+
+ if (owner == OWNER_TOWN && _game_mode != GM_EDITOR) {
+ t = GetTownByTile(tile);
+ } else {
+ t = NULL;
+ }
+
+ if (!CheckAllowRemoveRoad(tile, pieces, &edge_road)) return CMD_ERROR;
+
+ if (!EnsureNoVehicle(tile)) return CMD_ERROR;
+
+ // check if you're allowed to remove the street owned by a town
+ // removal allowance depends on difficulty setting
+ if (!CheckforTownRating(flags, t, ROAD_REMOVE)) return CMD_ERROR;
+
+ switch (GetRoadTileType(tile)) {
+ case ROAD_TILE_NORMAL: {
+ RoadBits present = GetRoadBits(tile);
+ RoadBits c = pieces;
+
+ if (HasRoadWorks(tile)) return_cmd_error(STR_ROAD_WORKS_IN_PROGRESS);
+
+ if (GetTileSlope(tile, NULL) != SLOPE_FLAT &&
+ (present == ROAD_Y || present == ROAD_X)) {
+ c |= (c & 0xC) >> 2;
+ c |= (c & 0x3) << 2;
+ }
+
+ // limit the bits to delete to the existing bits.
+ c &= present;
+ if (c == 0) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
+
+ present ^= c;
+ if (present == 0) {
+ DoClearSquare(tile);
+ } else {
+ SetRoadBits(tile, present);
+ MarkTileDirtyByTile(tile);
+ }
+ }
+ return CountRoadBits(c) * _price.remove_road;
+ }
+
+ case ROAD_TILE_CROSSING: {
+ if (pieces & ComplementRoadBits(GetCrossingRoadBits(tile))) {
+ return CMD_ERROR;
+ }
+
+ if (flags & DC_EXEC) {
+ ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
+
+ MakeRailNormal(tile, GetTileOwner(tile), GetCrossingRailBits(tile), GetRailTypeCrossing(tile));
+ MarkTileDirtyByTile(tile);
+ YapfNotifyTrackLayoutChange(tile, FIND_FIRST_BIT(GetTrackBits(tile)));
+ }
+ return _price.remove_road * 2;
+ }
+
+ default:
+ case ROAD_TILE_DEPOT:
+ return CMD_ERROR;
+ }
+}
+
+
+static const RoadBits _valid_tileh_slopes_road[][15] = {
+ // set of normal ones
+ {
+ ROAD_ALL, 0, 0,
+ ROAD_X, 0, 0, // 3, 4, 5
+ ROAD_Y, 0, 0,
+ ROAD_Y, 0, 0, // 9, 10, 11
+ ROAD_X, 0, 0
+ },
+ // allowed road for an evenly raised platform
+ {
+ 0,
+ ROAD_SW | ROAD_NW,
+ ROAD_SW | ROAD_SE,
+ ROAD_Y | ROAD_SW,
+
+ ROAD_SE | ROAD_NE, // 4
+ ROAD_ALL,
+ ROAD_X | ROAD_SE,
+ ROAD_ALL,
+
+ ROAD_NW | ROAD_NE, // 8
+ ROAD_X | ROAD_NW,
+ ROAD_ALL,
+ ROAD_ALL,
+
+ ROAD_Y | ROAD_NE, // 12
+ ROAD_ALL,
+ ROAD_ALL
+ },
+};
+
+
+static uint32 CheckRoadSlope(Slope tileh, RoadBits* pieces, RoadBits existing)
+{
+ RoadBits road_bits;
+
+ if (IsSteepSlope(tileh)) {
+ if (existing == 0) {
+ // force full pieces.
+ *pieces |= (*pieces & 0xC) >> 2;
+ *pieces |= (*pieces & 0x3) << 2;
+ if (*pieces == ROAD_X || *pieces == ROAD_Y) return _price.terraform;
+ }
+ return CMD_ERROR;
+ }
+ road_bits = *pieces | existing;
+
+ // no special foundation
+ if ((~_valid_tileh_slopes_road[0][tileh] & road_bits) == 0) {
+ // force that all bits are set when we have slopes
+ if (tileh != SLOPE_FLAT) *pieces |= _valid_tileh_slopes_road[0][tileh];
+ return 0; // no extra cost
+ }
+
+ // foundation is used. Whole tile is leveled up
+ if ((~_valid_tileh_slopes_road[1][tileh] & road_bits) == 0) {
+ return existing != 0 ? 0 : _price.terraform;
+ }
+
+ // partly leveled up tile, only if there's no road on that tile
+ if (existing == 0 && (tileh == SLOPE_W || tileh == SLOPE_S || tileh == SLOPE_E || tileh == SLOPE_N)) {
+ // force full pieces.
+ *pieces |= (*pieces & 0xC) >> 2;
+ *pieces |= (*pieces & 0x3) << 2;
+ if (*pieces == ROAD_X || *pieces == ROAD_Y) return _price.terraform;
+ }
+ return CMD_ERROR;
+}
+
+/** Build a piece of road.
+ * @param tile tile where to build road
+ * @param p1 road piece flags
+ * @param p2 the town that is building the road (0 if not applicable)
+ */
+int32 CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ int32 cost = 0;
+ int32 ret;
+ RoadBits existing = 0;
+ RoadBits pieces;
+ Slope tileh;
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ /* Road pieces are max 4 bitset values (NE, NW, SE, SW) and town can only be non-zero
+ * if a non-player is building the road */
+ if ((p1 >> 4) || (IsValidPlayer(_current_player) && p2 != 0) || !IsValidTownID(p2)) return CMD_ERROR;
+ pieces = p1;
+
+ tileh = GetTileSlope(tile, NULL);
+
+ switch (GetTileType(tile)) {
+ case MP_STREET:
+ switch (GetRoadTileType(tile)) {
+ case ROAD_TILE_NORMAL:
+ if (HasRoadWorks(tile)) return_cmd_error(STR_ROAD_WORKS_IN_PROGRESS);
+
+ existing = GetRoadBits(tile);
+ if ((existing & pieces) == pieces) {
+ return_cmd_error(STR_1007_ALREADY_BUILT);
+ }
+ if (!EnsureNoVehicle(tile)) return CMD_ERROR;
+ break;
+
+ case ROAD_TILE_CROSSING:
+ if (pieces != GetCrossingRoadBits(tile)) { // XXX is this correct?
+ return_cmd_error(STR_1007_ALREADY_BUILT);
+ }
+ goto do_clear;
+
+ default:
+ case ROAD_TILE_DEPOT:
+ goto do_clear;
+ }
+ break;
+
+ case MP_RAILWAY: {
+ Axis roaddir;
+
+ if (IsSteepSlope(tileh)) {
+ return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
+ }
+
+#define M(x) (1 << (x))
+ /* Level crossings may only be built on these slopes */
+ if (!HASBIT(M(SLOPE_SEN) | M(SLOPE_ENW) | M(SLOPE_NWS) | M(SLOPE_NS) | M(SLOPE_WSE) | M(SLOPE_EW) | M(SLOPE_FLAT), tileh)) {
+ return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
+ }
+#undef M
+
+ if (GetRailTileType(tile) != RAIL_TILE_NORMAL) goto do_clear;
+ switch (GetTrackBits(tile)) {
+ case TRACK_BIT_X:
+ if (pieces & ROAD_X) goto do_clear;
+ roaddir = AXIS_Y;
+ break;
+
+ case TRACK_BIT_Y:
+ if (pieces & ROAD_Y) goto do_clear;
+ roaddir = AXIS_X;
+ break;
+
+ default: goto do_clear;
+ }
+
+ if (!EnsureNoVehicle(tile)) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ YapfNotifyTrackLayoutChange(tile, FIND_FIRST_BIT(GetTrackBits(tile)));
+ MakeRoadCrossing(tile, _current_player, GetTileOwner(tile), roaddir, GetRailType(tile), p2);
+ MarkTileDirtyByTile(tile);
+ }
+ return _price.build_road * 2;
+ }
+
+ default:
+do_clear:;
+ ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+ if (CmdFailed(ret)) return ret;
+ cost += ret;
+ }
+
+ ret = CheckRoadSlope(tileh, &pieces, existing);
+ /* Return an error if we need to build a foundation (ret != 0) but the
+ * current patch-setting is turned off (or stupid AI@work) */
+ if (CmdFailed(ret) || (ret != 0 && (!_patches.build_on_slopes || _is_old_ai_player)))
+ return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
+
+ cost += ret;
+
+ if (IsTileType(tile, MP_STREET)) {
+ // Don't put the pieces that already exist
+ pieces &= ComplementRoadBits(existing);
+ }
+
+ cost += CountRoadBits(pieces) * _price.build_road;
+
+ if (flags & DC_EXEC) {
+ if (IsTileType(tile, MP_STREET)) {
+ SetRoadBits(tile, existing | pieces);
+ } else {
+ MakeRoadNormal(tile, _current_player, pieces, p2);
+ }
+
+ MarkTileDirtyByTile(tile);
+ }
+ return cost;
+}
+
+int32 DoConvertStreetRail(TileIndex tile, RailType totype, bool exec)
+{
+ // not a railroad crossing?
+ if (!IsLevelCrossing(tile)) return CMD_ERROR;
+
+ // not owned by me?
+ if (!CheckTileOwnership(tile) || !EnsureNoVehicle(tile)) return CMD_ERROR;
+
+ if (GetRailTypeCrossing(tile) == totype) return CMD_ERROR;
+
+ // 'hidden' elrails can't be downgraded to normal rail when elrails are disabled
+ if (_patches.disable_elrails && totype == RAILTYPE_RAIL && GetRailTypeCrossing(tile) == RAILTYPE_ELECTRIC) return CMD_ERROR;
+
+ if (exec) {
+ SetRailTypeCrossing(tile, totype);
+ MarkTileDirtyByTile(tile);
+ YapfNotifyTrackLayoutChange(tile, FIND_FIRST_BIT(GetCrossingRailBits(tile)));
+ }
+
+ return _price.build_rail >> 1;
+}
+
+
+/** Build a long piece of road.
+ * @param end_tile end tile of drag
+ * @param p1 start tile of drag
+ * @param p2 various bitstuffed elements
+ * - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1)
+ * - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2)
+ * - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4)
+ */
+int32 CmdBuildLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ TileIndex start_tile, tile;
+ int32 cost, ret;
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ if (p1 >= MapSize()) return CMD_ERROR;
+
+ start_tile = p1;
+
+ /* Only drag in X or Y direction dictated by the direction variable */
+ if (!HASBIT(p2, 2) && TileY(start_tile) != TileY(end_tile)) return CMD_ERROR; // x-axis
+ if (HASBIT(p2, 2) && TileX(start_tile) != TileX(end_tile)) return CMD_ERROR; // y-axis
+
+ /* Swap start and ending tile, also the half-tile drag var (bit 0 and 1) */
+ if (start_tile > end_tile || (start_tile == end_tile && HASBIT(p2, 0))) {
+ TileIndex t = start_tile;
+ start_tile = end_tile;
+ end_tile = t;
+ p2 ^= IS_INT_INSIDE(p2&3, 1, 3) ? 3 : 0;
+ }
+
+ cost = 0;
+ tile = start_tile;
+ // Start tile is the small number.
+ for (;;) {
+ RoadBits bits = HASBIT(p2, 2) ? ROAD_Y : ROAD_X;
+
+ if (tile == end_tile && !HASBIT(p2, 1)) bits &= ROAD_NW | ROAD_NE;
+ if (tile == start_tile && HASBIT(p2, 0)) bits &= ROAD_SE | ROAD_SW;
+
+ ret = DoCommand(tile, bits, 0, flags, CMD_BUILD_ROAD);
+ if (CmdFailed(ret)) {
+ if (_error_message != STR_1007_ALREADY_BUILT) return CMD_ERROR;
+ _error_message = INVALID_STRING_ID;
+ } else {
+ cost += ret;
+ }
+
+ if (tile == end_tile) break;
+
+ tile += HASBIT(p2, 2) ? TileDiffXY(0, 1) : TileDiffXY(1, 0);
+ }
+
+ return (cost == 0) ? CMD_ERROR : cost;
+}
+
+/** Remove a long piece of road.
+ * @param end_tile end tile of drag
+ * @param p1 start tile of drag
+ * @param p2 various bitstuffed elements
+ * - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1)
+ * - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2)
+ * - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4)
+ */
+int32 CmdRemoveLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ TileIndex start_tile, tile;
+ int32 cost, ret;
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ if (p1 >= MapSize()) return CMD_ERROR;
+
+ start_tile = p1;
+
+ /* Only drag in X or Y direction dictated by the direction variable */
+ if (!HASBIT(p2, 2) && TileY(start_tile) != TileY(end_tile)) return CMD_ERROR; // x-axis
+ if (HASBIT(p2, 2) && TileX(start_tile) != TileX(end_tile)) return CMD_ERROR; // y-axis
+
+ /* Swap start and ending tile, also the half-tile drag var (bit 0 and 1) */
+ if (start_tile > end_tile || (start_tile == end_tile && HASBIT(p2, 0))) {
+ TileIndex t = start_tile;
+ start_tile = end_tile;
+ end_tile = t;
+ p2 ^= IS_INT_INSIDE(p2 & 3, 1, 3) ? 3 : 0;
+ }
+
+ cost = 0;
+ tile = start_tile;
+ // Start tile is the small number.
+ for (;;) {
+ RoadBits bits = HASBIT(p2, 2) ? ROAD_Y : ROAD_X;
+
+ if (tile == end_tile && !HASBIT(p2, 1)) bits &= ROAD_NW | ROAD_NE;
+ if (tile == start_tile && HASBIT(p2, 0)) bits &= ROAD_SE | ROAD_SW;
+
+ // try to remove the halves.
+ if (bits != 0) {
+ ret = DoCommand(tile, bits, 0, flags, CMD_REMOVE_ROAD);
+ if (!CmdFailed(ret)) cost += ret;
+ }
+
+ if (tile == end_tile) break;
+
+ tile += HASBIT(p2, 2) ? TileDiffXY(0, 1) : TileDiffXY(1, 0);
+ }
+
+ return (cost == 0) ? CMD_ERROR : cost;
+}
+
+/** Build a road depot.
+ * @param tile tile where to build the depot
+ * @param p1 entrance direction (DiagDirection)
+ * @param p2 unused
+ *
+ * @todo When checking for the tile slope,
+ * distingush between "Flat land required" and "land sloped in wrong direction"
+ */
+int32 CmdBuildRoadDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ int32 cost;
+ Depot *dep;
+ Slope tileh;
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ if (p1 > 3) return CMD_ERROR; // check direction
+
+ if (!EnsureNoVehicle(tile)) return CMD_ERROR;
+
+ tileh = GetTileSlope(tile, NULL);
+ if (tileh != SLOPE_FLAT && (
+ !_patches.build_on_slopes ||
+ IsSteepSlope(tileh) ||
+ !CanBuildDepotByTileh(p1, tileh)
+ )) {
+ return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
+ }
+
+ cost = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+ if (CmdFailed(cost)) return CMD_ERROR;
+
+ if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
+
+ dep = AllocateDepot();
+ if (dep == NULL) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ dep->xy = tile;
+ dep->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
+
+ MakeRoadDepot(tile, _current_player, p1);
+ MarkTileDirtyByTile(tile);
+ }
+ return cost + _price.build_road_depot;
+}
+
+static int32 RemoveRoadDepot(TileIndex tile, uint32 flags)
+{
+ if (!CheckTileOwnership(tile) && _current_player != OWNER_WATER)
+ return CMD_ERROR;
+
+ if (!EnsureNoVehicle(tile)) return CMD_ERROR;
+
+ if (flags & DC_EXEC) DeleteDepot(GetDepotByTile(tile));
+
+ return _price.remove_road_depot;
+}
+
+#define M(x) (1<<(x))
+
+static int32 ClearTile_Road(TileIndex tile, byte flags)
+{
+ switch (GetRoadTileType(tile)) {
+ case ROAD_TILE_NORMAL: {
+ RoadBits b = GetRoadBits(tile);
+
+ if (!((1 << b) & (M(1)|M(2)|M(4)|M(8))) &&
+ (!(flags & DC_AI_BUILDING) || !IsTileOwner(tile, OWNER_TOWN)) &&
+ flags & DC_AUTO) {
+ return_cmd_error(STR_1801_MUST_REMOVE_ROAD_FIRST);
+ }
+ return DoCommand(tile, b, 0, flags, CMD_REMOVE_ROAD);
+ }
+
+ case ROAD_TILE_CROSSING: {
+ int32 ret;
+
+ if (flags & DC_AUTO) return_cmd_error(STR_1801_MUST_REMOVE_ROAD_FIRST);
+
+ ret = DoCommand(tile, GetCrossingRoadBits(tile), 0, flags, CMD_REMOVE_ROAD);
+ if (CmdFailed(ret)) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+ }
+ return ret;
+ }
+
+ default:
+ case ROAD_TILE_DEPOT:
+ if (flags & DC_AUTO) {
+ return_cmd_error(STR_2004_BUILDING_MUST_BE_DEMOLISHED);
+ }
+ return RemoveRoadDepot(tile, flags);
+ }
+}
+
+
+typedef struct DrawRoadTileStruct {
+ uint16 image;
+ byte subcoord_x;
+ byte subcoord_y;
+} DrawRoadTileStruct;
+
+#include "table/road_land.h"
+
+
+uint GetRoadFoundation(Slope tileh, RoadBits bits)
+{
+ uint i;
+
+ // normal level sloped building
+ if (!IsSteepSlope(tileh) &&
+ (~_valid_tileh_slopes_road[1][tileh] & bits) == 0) {
+ return tileh;
+ }
+
+ // inclined sloped building
+ switch (bits) {
+ case ROAD_X: i = 0; break;
+ case ROAD_Y: i = 1; break;
+ default: return 0;
+ }
+ switch (tileh) {
+ case SLOPE_W:
+ case SLOPE_STEEP_W: i += 0; break;
+ case SLOPE_S:
+ case SLOPE_STEEP_S: i += 2; break;
+ case SLOPE_E:
+ case SLOPE_STEEP_E: i += 4; break;
+ case SLOPE_N:
+ case SLOPE_STEEP_N: i += 6; break;
+ default: return 0;
+ }
+ return i + 15;
+}
+
+const byte _road_sloped_sprites[14] = {
+ 0, 0, 2, 0,
+ 0, 1, 0, 0,
+ 3, 0, 0, 0,
+ 0, 0
+};
+
+/**
+ * Draw ground sprite and road pieces
+ * @param ti TileInfo
+ * @param road RoadBits to draw
+ */
+static void DrawRoadBits(TileInfo* ti)
+{
+ RoadBits road = GetRoadBits(ti->tile);
+ const DrawRoadTileStruct *drts;
+ PalSpriteID image = 0;
+ Roadside roadside;
+
+ if (ti->tileh != SLOPE_FLAT) {
+ int foundation = GetRoadFoundation(ti->tileh, road);
+
+ if (foundation != 0) DrawFoundation(ti, foundation);
+
+ // DrawFoundation() modifies ti.
+ // Default sloped sprites..
+ if (ti->tileh != SLOPE_FLAT) image = _road_sloped_sprites[ti->tileh - 1] + 0x53F;
+ }
+
+ if (image == 0) image = _road_tile_sprites_1[road];
+
+ roadside = GetRoadside(ti->tile);
+
+ if (IsOnSnow(ti->tile)) {
+ image += 19;
+ } else {
+ switch (roadside) {
+ case ROADSIDE_BARREN: image |= PALETTE_TO_BARE_LAND; break;
+ case ROADSIDE_GRASS: break;
+ case ROADSIDE_GRASS_ROAD_WORKS: break;
+ default: image -= 19; break; // Paved
+ }
+ }
+
+ DrawGroundSprite(image);
+
+ if (HasRoadWorks(ti->tile)) {
+ // Road works
+ DrawGroundSprite(road & ROAD_X ? SPR_EXCAVATION_X : SPR_EXCAVATION_Y);
+ return;
+ }
+
+ // Return if full detail is disabled, or we are zoomed fully out.
+ if (!(_display_opt & DO_FULL_DETAIL) || _cur_dpi->zoom == 2) return;
+
+ // Draw extra details.
+ for (drts = _road_display_table[roadside][road]; drts->image != 0; drts++) {
+ int x = ti->x | drts->subcoord_x;
+ int y = ti->y | drts->subcoord_y;
+ byte z = ti->z;
+ if (ti->tileh != SLOPE_FLAT) z = GetSlopeZ(x, y);
+ AddSortableSpriteToDraw(drts->image, x, y, 2, 2, 0x10, z);
+ }
+}
+
+static void DrawTile_Road(TileInfo *ti)
+{
+ switch (GetRoadTileType(ti->tile)) {
+ case ROAD_TILE_NORMAL:
+ DrawRoadBits(ti);
+ break;
+
+ case ROAD_TILE_CROSSING: {
+ PalSpriteID image;
+
+ if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
+
+ image = GetRailTypeInfo(GetRailTypeCrossing(ti->tile))->base_sprites.crossing;
+
+ if (GetCrossingRoadAxis(ti->tile) == AXIS_X) image++;
+ if (IsCrossingBarred(ti->tile)) image += 2;
+
+ if (IsOnSnow(ti->tile)) {
+ image += 8;
+ } else {
+ switch (GetRoadside(ti->tile)) {
+ case ROADSIDE_BARREN: image |= PALETTE_TO_BARE_LAND; break;
+ case ROADSIDE_GRASS: break;
+ default: image += 4; break; // Paved
+ }
+ }
+
+ DrawGroundSprite(image);
+ if (GetRailTypeCrossing(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
+ break;
+ }
+
+ default:
+ case ROAD_TILE_DEPOT: {
+ const DrawTileSprites* dts;
+ const DrawTileSeqStruct* dtss;
+ uint32 palette;
+
+ if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
+
+ palette = PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile));
+
+ dts = &_road_depot[GetRoadDepotDirection(ti->tile)];
+ DrawGroundSprite(dts->ground_sprite);
+
+ for (dtss = dts->seq; dtss->image != 0; dtss++) {
+ uint32 image = dtss->image;
+
+ if (_display_opt & DO_TRANS_BUILDINGS) {
+ MAKE_TRANSPARENT(image);
+ } else if (image & PALETTE_MODIFIER_COLOR) {
+ image |= palette;
+ }
+
+ AddSortableSpriteToDraw(
+ image,
+ ti->x + dtss->delta_x, ti->y + dtss->delta_y,
+ dtss->size_x, dtss->size_y,
+ dtss->size_z, ti->z
+ );
+ }
+ break;
+ }
+ }
+ DrawBridgeMiddle(ti);
+}
+
+void DrawRoadDepotSprite(int x, int y, DiagDirection dir)
+{
+ uint32 palette = PLAYER_SPRITE_COLOR(_local_player);
+ const DrawTileSprites* dts = &_road_depot[dir];
+ const DrawTileSeqStruct* dtss;
+
+ x += 33;
+ y += 17;
+
+ DrawSprite(dts->ground_sprite, x, y);
+
+ for (dtss = dts->seq; dtss->image != 0; dtss++) {
+ Point pt = RemapCoords(dtss->delta_x, dtss->delta_y, dtss->delta_z);
+ uint32 image = dtss->image;
+
+ if (image & PALETTE_MODIFIER_COLOR) image |= palette;
+
+ DrawSprite(image, x + pt.x, y + pt.y);
+ }
+}
+
+static uint GetSlopeZ_Road(TileIndex tile, uint x, uint y)
+{
+ uint z;
+ Slope tileh = GetTileSlope(tile, &z);
+
+ if (tileh == SLOPE_FLAT) return z;
+ if (GetRoadTileType(tile) == ROAD_TILE_NORMAL) {
+ uint f = GetRoadFoundation(tileh, GetRoadBits(tile));
+
+ if (f != 0) {
+ if (IsSteepSlope(tileh)) {
+ z += TILE_HEIGHT;
+ } else if (f < 15) {
+ return z + TILE_HEIGHT; // leveled foundation
+ }
+ tileh = _inclined_tileh[f - 15]; // inclined foundation
+ }
+ return z + GetPartialZ(x & 0xF, y & 0xF, tileh);
+ } else {
+ return z + TILE_HEIGHT;
+ }
+}
+
+static Slope GetSlopeTileh_Road(TileIndex tile, Slope tileh)
+{
+ if (tileh == SLOPE_FLAT) return SLOPE_FLAT;
+ if (GetRoadTileType(tile) == ROAD_TILE_NORMAL) {
+ uint f = GetRoadFoundation(tileh, GetRoadBits(tile));
+
+ if (f == 0) return tileh;
+ if (f < 15) return SLOPE_FLAT; // leveled foundation
+ return _inclined_tileh[f - 15]; // inclined foundation
+ } else {
+ return SLOPE_FLAT;
+ }
+}
+
+static void GetAcceptedCargo_Road(TileIndex tile, AcceptedCargo ac)
+{
+ /* not used */
+}
+
+static void AnimateTile_Road(TileIndex tile)
+{
+ if (IsLevelCrossing(tile)) MarkTileDirtyByTile(tile);
+}
+
+
+static const Roadside _town_road_types[][2] = {
+ { ROADSIDE_GRASS, ROADSIDE_GRASS },
+ { ROADSIDE_PAVED, ROADSIDE_PAVED },
+ { ROADSIDE_PAVED, ROADSIDE_PAVED },
+ { ROADSIDE_TREES, ROADSIDE_TREES },
+ { ROADSIDE_STREET_LIGHTS, ROADSIDE_PAVED }
+};
+
+static const Roadside _town_road_types_2[][2] = {
+ { ROADSIDE_GRASS, ROADSIDE_GRASS },
+ { ROADSIDE_PAVED, ROADSIDE_PAVED },
+ { ROADSIDE_STREET_LIGHTS, ROADSIDE_PAVED },
+ { ROADSIDE_STREET_LIGHTS, ROADSIDE_PAVED },
+ { ROADSIDE_STREET_LIGHTS, ROADSIDE_PAVED }
+};
+
+
+static void TileLoop_Road(TileIndex tile)
+{
+ switch (_opt.landscape) {
+ case LT_HILLY:
+ if (IsOnSnow(tile) != (GetTileZ(tile) > _opt.snow_line)) {
+ ToggleSnow(tile);
+ MarkTileDirtyByTile(tile);
+ }
+ break;
+
+ case LT_DESERT:
+ if (GetTropicZone(tile) == TROPICZONE_DESERT && !IsOnDesert(tile)) {
+ ToggleDesert(tile);
+ MarkTileDirtyByTile(tile);
+ }
+ break;
+ }
+
+ if (GetRoadTileType(tile) == ROAD_TILE_DEPOT) return;
+
+ if (!HasRoadWorks(tile)) {
+ const Town* t = ClosestTownFromTile(tile, (uint)-1);
+ int grp = 0;
+
+ if (t != NULL) {
+ grp = GetTownRadiusGroup(t, tile);
+
+ // Show an animation to indicate road work
+ if (t->road_build_months != 0 &&
+ (DistanceManhattan(t->xy, tile) < 8 || grp != 0) &&
+ GetRoadTileType(tile) == ROAD_TILE_NORMAL && (GetRoadBits(tile) == ROAD_X || GetRoadBits(tile) == ROAD_Y)) {
+ if (GetTileSlope(tile, NULL) == SLOPE_FLAT && EnsureNoVehicle(tile) && CHANCE16(1, 20)) {
+ StartRoadWorks(tile);
+
+ SndPlayTileFx(SND_21_JACKHAMMER, tile);
+ CreateEffectVehicleAbove(
+ TileX(tile) * TILE_SIZE + 7,
+ TileY(tile) * TILE_SIZE + 7,
+ 0,
+ EV_BULLDOZER);
+ MarkTileDirtyByTile(tile);
+ return;
+ }
+ }
+ }
+
+ {
+ /* Adjust road ground type depending on 'grp' (grp is the distance to the center) */
+ const Roadside* new_rs = (_opt.landscape == LT_CANDY) ? _town_road_types_2[grp] : _town_road_types[grp];
+ Roadside cur_rs = GetRoadside(tile);
+
+ /* We have our desired type, do nothing */
+ if (cur_rs == new_rs[0]) return;
+
+ /* We have the pre-type of the desired type, switch to the desired type */
+ if (cur_rs == new_rs[1]) {
+ cur_rs = new_rs[0];
+ /* We have barren land, install the pre-type */
+ } else if (cur_rs == ROADSIDE_BARREN) {
+ cur_rs = new_rs[1];
+ /* We're totally off limits, remove any installation and make barren land */
+ } else {
+ cur_rs = ROADSIDE_BARREN;
+ }
+ SetRoadside(tile, cur_rs);
+ MarkTileDirtyByTile(tile);
+ }
+ } else if (IncreaseRoadWorksCounter(tile)) {
+ TerminateRoadWorks(tile);
+ MarkTileDirtyByTile(tile);
+ }
+}
+
+static void ClickTile_Road(TileIndex tile)
+{
+ if (GetRoadTileType(tile) == ROAD_TILE_DEPOT) ShowDepotWindow(tile, VEH_Road);
+}
+
+static const byte _road_trackbits[16] = {
+ 0x0, 0x0, 0x0, 0x10, 0x0, 0x2, 0x8, 0x1A, 0x0, 0x4, 0x1, 0x15, 0x20, 0x26, 0x29, 0x3F,
+};
+
+static uint32 GetTileTrackStatus_Road(TileIndex tile, TransportType mode)
+{
+ switch (mode) {
+ case TRANSPORT_RAIL:
+ if (!IsLevelCrossing(tile)) return 0;
+ return GetCrossingRailBits(tile) * 0x101;
+
+ case TRANSPORT_ROAD:
+ switch (GetRoadTileType(tile)) {
+ case ROAD_TILE_NORMAL:
+ return HasRoadWorks(tile) ? 0 : _road_trackbits[GetRoadBits(tile)] * 0x101;
+
+ case ROAD_TILE_CROSSING: {
+ uint32 r = AxisToTrackBits(GetCrossingRoadAxis(tile)) * 0x101;
+
+ if (IsCrossingBarred(tile)) r *= 0x10001;
+ return r;
+ }
+
+ default:
+ case ROAD_TILE_DEPOT:
+ return AxisToTrackBits(DiagDirToAxis(GetRoadDepotDirection(tile))) * 0x101;
+ }
+ break;
+
+ default: break;
+ }
+ return 0;
+}
+
+static const StringID _road_tile_strings[] = {
+ STR_1814_ROAD,
+ STR_1814_ROAD,
+ STR_1814_ROAD,
+ STR_1815_ROAD_WITH_STREETLIGHTS,
+ STR_1814_ROAD,
+ STR_1816_TREE_LINED_ROAD,
+ STR_1814_ROAD,
+ STR_1814_ROAD,
+};
+
+static void GetTileDesc_Road(TileIndex tile, TileDesc *td)
+{
+ td->owner = GetTileOwner(tile);
+ switch (GetRoadTileType(tile)) {
+ case ROAD_TILE_CROSSING: td->str = STR_1818_ROAD_RAIL_LEVEL_CROSSING; break;
+ case ROAD_TILE_DEPOT: td->str = STR_1817_ROAD_VEHICLE_DEPOT; break;
+ default: td->str = _road_tile_strings[GetRoadside(tile)]; break;
+ }
+}
+
+static const byte _roadveh_enter_depot_unk0[4] = {
+ 8, 9, 0, 1
+};
+
+static uint32 VehicleEnter_Road(Vehicle *v, TileIndex tile, int x, int y)
+{
+ switch (GetRoadTileType(tile)) {
+ case ROAD_TILE_CROSSING:
+ if (v->type == VEH_Train && !IsCrossingBarred(tile)) {
+ /* train crossing a road */
+ SndPlayVehicleFx(SND_0E_LEVEL_CROSSING, v);
+ BarCrossing(tile);
+ MarkTileDirtyByTile(tile);
+ }
+ break;
+
+ case ROAD_TILE_DEPOT:
+ if (v->type == VEH_Road &&
+ v->u.road.frame == 11 &&
+ _roadveh_enter_depot_unk0[GetRoadDepotDirection(tile)] == v->u.road.state) {
+ VehicleEnterDepot(v);
+ return 4;
+ }
+ break;
+
+ default: break;
+ }
+ return 0;
+}
+
+
+static void ChangeTileOwner_Road(TileIndex tile, PlayerID old_player, PlayerID new_player)
+{
+ if (IsLevelCrossing(tile) && GetCrossingRoadOwner(tile) == old_player) {
+ SetCrossingRoadOwner(tile, new_player == PLAYER_SPECTATOR ? OWNER_NONE : new_player);
+ }
+
+ if (!IsTileOwner(tile, old_player)) return;
+
+ if (new_player != PLAYER_SPECTATOR) {
+ SetTileOwner(tile, new_player);
+ } else {
+ switch (GetRoadTileType(tile)) {
+ case ROAD_TILE_NORMAL:
+ SetTileOwner(tile, OWNER_NONE);
+ break;
+
+ case ROAD_TILE_CROSSING:
+ MakeRoadNormal(tile, GetCrossingRoadOwner(tile), GetCrossingRoadBits(tile), GetTownIndex(tile));
+ break;
+
+ default:
+ case ROAD_TILE_DEPOT:
+ DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
+ break;
+ }
+ }
+}
+
+
+const TileTypeProcs _tile_type_road_procs = {
+ DrawTile_Road, /* draw_tile_proc */
+ GetSlopeZ_Road, /* get_slope_z_proc */
+ ClearTile_Road, /* clear_tile_proc */
+ GetAcceptedCargo_Road, /* get_accepted_cargo_proc */
+ GetTileDesc_Road, /* get_tile_desc_proc */
+ GetTileTrackStatus_Road, /* get_tile_track_status_proc */
+ ClickTile_Road, /* click_tile_proc */
+ AnimateTile_Road, /* animate_tile_proc */
+ TileLoop_Road, /* tile_loop_clear */
+ ChangeTileOwner_Road, /* change_tile_owner_clear */
+ NULL, /* get_produced_cargo_proc */
+ VehicleEnter_Road, /* vehicle_enter_tile_proc */
+ GetSlopeTileh_Road, /* get_slope_tileh_proc */
+};
diff --git a/src/road_cmd.h b/src/road_cmd.h
new file mode 100644
index 000000000..436ecd900
--- /dev/null
+++ b/src/road_cmd.h
@@ -0,0 +1,10 @@
+/* $Id$ */
+
+#ifndef ROAD_CMD_H
+#define ROAD_CMD_H
+
+#include "direction.h"
+
+void DrawRoadDepotSprite(int x, int y, DiagDirection dir);
+
+#endif /* ROAD_CMD_H */
diff --git a/src/road_gui.c b/src/road_gui.c
new file mode 100644
index 000000000..8507de65f
--- /dev/null
+++ b/src/road_gui.c
@@ -0,0 +1,560 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "road_cmd.h"
+#include "road_map.h"
+#include "table/sprites.h"
+#include "table/strings.h"
+#include "functions.h"
+#include "map.h"
+#include "tile.h"
+#include "window.h"
+#include "gui.h"
+#include "viewport.h"
+#include "gfx.h"
+#include "sound.h"
+#include "command.h"
+#include "variables.h"
+//needed for catchments
+#include "station.h"
+
+
+static void ShowBusStationPicker(void);
+static void ShowTruckStationPicker(void);
+static void ShowRoadDepotPicker(void);
+
+static bool _remove_button_clicked;
+
+static byte _place_road_flag;
+
+static byte _road_depot_orientation;
+static byte _road_station_picker_orientation;
+
+void CcPlaySound1D(bool success, TileIndex tile, uint32 p1, uint32 p2)
+{
+ if (success) SndPlayTileFx(SND_1F_SPLAT, tile);
+}
+
+static void PlaceRoad_NE(TileIndex tile)
+{
+ _place_road_flag = (_tile_fract_coords.y >= 8) + 4;
+ VpStartPlaceSizing(tile, VPM_FIX_X);
+}
+
+static void PlaceRoad_NW(TileIndex tile)
+{
+ _place_road_flag = (_tile_fract_coords.x >= 8) + 0;
+ VpStartPlaceSizing(tile, VPM_FIX_Y);
+}
+
+static void PlaceRoad_Bridge(TileIndex tile)
+{
+ VpStartPlaceSizing(tile, VPM_X_OR_Y);
+}
+
+
+void CcBuildRoadTunnel(bool success, TileIndex tile, uint32 p1, uint32 p2)
+{
+ if (success) {
+ SndPlayTileFx(SND_20_SPLAT_2, tile);
+ ResetObjectToPlace();
+ } else {
+ SetRedErrorSquare(_build_tunnel_endtile);
+ }
+}
+
+static void PlaceRoad_Tunnel(TileIndex tile)
+{
+ DoCommandP(tile, 0x200, 0, CcBuildRoadTunnel, CMD_BUILD_TUNNEL | CMD_AUTO | CMD_MSG(STR_5016_CAN_T_BUILD_TUNNEL_HERE));
+}
+
+static void BuildRoadOutsideStation(TileIndex tile, DiagDirection direction)
+{
+ tile += TileOffsByDiagDir(direction);
+ // if there is a roadpiece just outside of the station entrance, build a connecting route
+ if (IsTileType(tile, MP_STREET) && GetRoadTileType(tile) == ROAD_TILE_NORMAL) {
+ DoCommandP(tile, DiagDirToRoadBits(ReverseDiagDir(direction)), 0, NULL, CMD_BUILD_ROAD);
+ }
+}
+
+void CcRoadDepot(bool success, TileIndex tile, uint32 p1, uint32 p2)
+{
+ if (success) {
+ SndPlayTileFx(SND_1F_SPLAT, tile);
+ ResetObjectToPlace();
+ BuildRoadOutsideStation(tile, p1);
+ }
+}
+
+static void PlaceRoad_Depot(TileIndex tile)
+{
+ DoCommandP(tile, _road_depot_orientation, 0, CcRoadDepot, CMD_BUILD_ROAD_DEPOT | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1807_CAN_T_BUILD_ROAD_VEHICLE));
+}
+
+static void PlaceRoad_BusStation(TileIndex tile)
+{
+ DoCommandP(tile, _road_station_picker_orientation, RS_BUS, CcRoadDepot, CMD_BUILD_ROAD_STOP | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1808_CAN_T_BUILD_BUS_STATION));
+}
+
+static void PlaceRoad_TruckStation(TileIndex tile)
+{
+ DoCommandP(tile, _road_station_picker_orientation, RS_TRUCK, CcRoadDepot, CMD_BUILD_ROAD_STOP | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1809_CAN_T_BUILD_TRUCK_STATION));
+}
+
+static void PlaceRoad_DemolishArea(TileIndex tile)
+{
+ VpStartPlaceSizing(tile, 4);
+}
+
+
+enum {
+ RTW_ROAD_X = 3,
+ RTW_ROAD_Y = 4,
+ RTW_DEMOLISH = 5,
+ RTW_DEPOT = 6,
+ RTW_BUS_STATION = 7,
+ RTW_TRUCK_STATION = 8,
+ RTW_BUILD_BRIDGE = 9,
+ RTW_BUILD_TUNNEL = 10,
+ RTW_REMOVE = 11
+};
+
+
+typedef void OnButtonClick(Window *w);
+
+static void BuildRoadClick_NE(Window *w)
+{
+ HandlePlacePushButton(w, RTW_ROAD_X, SPR_CURSOR_ROAD_NESW, 1, PlaceRoad_NE);
+}
+
+static void BuildRoadClick_NW(Window *w)
+{
+ HandlePlacePushButton(w, RTW_ROAD_Y, SPR_CURSOR_ROAD_NWSE, 1, PlaceRoad_NW);
+}
+
+
+static void BuildRoadClick_Demolish(Window *w)
+{
+ HandlePlacePushButton(w, RTW_DEMOLISH, ANIMCURSOR_DEMOLISH, 1, PlaceRoad_DemolishArea);
+}
+
+static void BuildRoadClick_Depot(Window *w)
+{
+ if (_game_mode == GM_EDITOR) return;
+ if (HandlePlacePushButton(w, RTW_DEPOT, SPR_CURSOR_ROAD_DEPOT, 1, PlaceRoad_Depot)) ShowRoadDepotPicker();
+}
+
+static void BuildRoadClick_BusStation(Window *w)
+{
+ if (_game_mode == GM_EDITOR) return;
+ if (HandlePlacePushButton(w, RTW_BUS_STATION, SPR_CURSOR_BUS_STATION, 1, PlaceRoad_BusStation)) ShowBusStationPicker();
+}
+
+static void BuildRoadClick_TruckStation(Window *w)
+{
+ if (_game_mode == GM_EDITOR) return;
+ if (HandlePlacePushButton(w, RTW_TRUCK_STATION, SPR_CURSOR_TRUCK_STATION, 1, PlaceRoad_TruckStation)) ShowTruckStationPicker();
+}
+
+static void BuildRoadClick_Bridge(Window *w)
+{
+ HandlePlacePushButton(w, RTW_BUILD_BRIDGE, SPR_CURSOR_BRIDGE, 1, PlaceRoad_Bridge);
+}
+
+static void BuildRoadClick_Tunnel(Window *w)
+{
+ HandlePlacePushButton(w, RTW_BUILD_TUNNEL, SPR_CURSOR_ROAD_TUNNEL, 3, PlaceRoad_Tunnel);
+}
+
+static void BuildRoadClick_Remove(Window *w)
+{
+ if (IsWindowWidgetDisabled(w, RTW_REMOVE)) return;
+ SetWindowDirty(w);
+ SndPlayFx(SND_15_BEEP);
+ ToggleWidgetLoweredState(w, RTW_REMOVE);
+ SetSelectionRed(IsWindowWidgetLowered(w, RTW_REMOVE));
+}
+
+static void BuildRoadClick_Landscaping(Window *w)
+{
+ ShowTerraformToolbar();
+}
+
+static OnButtonClick* const _build_road_button_proc[] = {
+ BuildRoadClick_NE,
+ BuildRoadClick_NW,
+ BuildRoadClick_Demolish,
+ BuildRoadClick_Depot,
+ BuildRoadClick_BusStation,
+ BuildRoadClick_TruckStation,
+ BuildRoadClick_Bridge,
+ BuildRoadClick_Tunnel,
+ BuildRoadClick_Remove,
+ BuildRoadClick_Landscaping,
+};
+
+static void BuildRoadToolbWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_CREATE: DisableWindowWidget(w, RTW_REMOVE); break;
+
+ case WE_PAINT:
+ if (IsWindowWidgetLowered(w, RTW_ROAD_X) || IsWindowWidgetLowered(w, RTW_ROAD_Y)) {
+ EnableWindowWidget(w, RTW_REMOVE);
+ }
+ DrawWindowWidgets(w);
+ break;
+
+ case WE_CLICK: {
+ if (e->we.click.widget >= 3) _build_road_button_proc[e->we.click.widget - 3](w);
+ } break;
+
+ case WE_KEYPRESS:
+ switch (e->we.keypress.keycode) {
+ case '1': BuildRoadClick_NE(w); break;
+ case '2': BuildRoadClick_NW(w); break;
+ case '3': BuildRoadClick_Demolish(w); break;
+ case '4': BuildRoadClick_Depot(w); break;
+ case '5': BuildRoadClick_BusStation(w); break;
+ case '6': BuildRoadClick_TruckStation(w); break;
+ case 'B': BuildRoadClick_Bridge(w); break;
+ case 'T': BuildRoadClick_Tunnel(w); break;
+ case 'R': BuildRoadClick_Remove(w); break;
+ case 'L': BuildRoadClick_Landscaping(w); break;
+ default: return;
+ }
+ MarkTileDirty(_thd.pos.x, _thd.pos.y); // redraw tile selection
+ e->we.keypress.cont = false;
+ break;
+
+ case WE_PLACE_OBJ:
+ _remove_button_clicked = IsWindowWidgetLowered(w, RTW_REMOVE);
+ _place_proc(e->we.place.tile);
+ break;
+
+ case WE_ABORT_PLACE_OBJ:
+ RaiseWindowButtons(w);
+ DisableWindowWidget(w, RTW_REMOVE);
+ InvalidateWidget(w, RTW_REMOVE);
+
+ w = FindWindowById(WC_BUS_STATION, 0);
+ if (w != NULL) WP(w,def_d).close = true;
+ w = FindWindowById(WC_TRUCK_STATION, 0);
+ if (w != NULL) WP(w,def_d).close = true;
+ w = FindWindowById(WC_BUILD_DEPOT, 0);
+ if (w != NULL) WP(w,def_d).close = true;
+ break;
+
+ case WE_PLACE_DRAG: {
+ int sel_method;
+ switch (e->we.place.userdata) {
+ case 1:
+ sel_method = VPM_FIX_X;
+ _place_road_flag = (_place_road_flag & ~2) | ((e->we.place.pt.y & 8) >> 2);
+ break;
+
+ case 2:
+ sel_method = VPM_FIX_Y;
+ _place_road_flag = (_place_road_flag & ~2) | ((e->we.place.pt.x & 8) >> 2);
+ break;
+
+ case 4:
+ sel_method = VPM_X_AND_Y;
+ break;
+
+ default:
+ sel_method = VPM_X_OR_Y;
+ break;
+ }
+
+ VpSelectTilesWithMethod(e->we.place.pt.x, e->we.place.pt.y, sel_method);
+ return;
+ }
+
+ case WE_PLACE_MOUSEUP:
+ if (e->we.place.pt.x != -1) {
+ TileIndex start_tile = e->we.place.starttile;
+ TileIndex end_tile = e->we.place.tile;
+
+ if (e->we.place.userdata == 0) {
+ ResetObjectToPlace();
+ ShowBuildBridgeWindow(start_tile, end_tile, 0x80);
+ } else if (e->we.place.userdata != 4) {
+ DoCommandP(end_tile, start_tile, _place_road_flag, CcPlaySound1D,
+ _remove_button_clicked ?
+ CMD_REMOVE_LONG_ROAD | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1805_CAN_T_REMOVE_ROAD_FROM) :
+ CMD_BUILD_LONG_ROAD | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1804_CAN_T_BUILD_ROAD_HERE));
+ } else {
+ DoCommandP(end_tile, start_tile, 0, CcPlaySound10, CMD_CLEAR_AREA | CMD_MSG(STR_00B5_CAN_T_CLEAR_THIS_AREA));
+ }
+ }
+ break;
+
+ case WE_PLACE_PRESIZE: {
+ TileIndex tile = e->we.place.tile;
+
+ DoCommand(tile, 0x200, 0, DC_AUTO, CMD_BUILD_TUNNEL);
+ VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile);
+ break;
+ }
+
+ case WE_DESTROY:
+ if (_patches.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0);
+ break;
+ }
+}
+
+static const Widget _build_road_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 227, 0, 13, STR_1802_ROAD_CONSTRUCTION, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_STICKYBOX, RESIZE_NONE, 7, 228, 239, 0, 13, 0x0, STR_STICKY_BUTTON},
+
+{ WWT_IMGBTN, RESIZE_NONE, 7, 0, 21, 14, 35, SPR_IMG_ROAD_NW, STR_180B_BUILD_ROAD_SECTION},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 22, 43, 14, 35, SPR_IMG_ROAD_NE, STR_180B_BUILD_ROAD_SECTION},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 44, 65, 14, 35, SPR_IMG_DYNAMITE, STR_018D_DEMOLISH_BUILDINGS_ETC},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 66, 87, 14, 35, SPR_IMG_ROAD_DEPOT, STR_180C_BUILD_ROAD_VEHICLE_DEPOT},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 88, 109, 14, 35, SPR_IMG_BUS_STATION, STR_180D_BUILD_BUS_STATION},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 110, 131, 14, 35, SPR_IMG_TRUCK_BAY, STR_180E_BUILD_TRUCK_LOADING_BAY},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 132, 173, 14, 35, SPR_IMG_BRIDGE, STR_180F_BUILD_ROAD_BRIDGE},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 174, 195, 14, 35, SPR_IMG_ROAD_TUNNEL, STR_1810_BUILD_ROAD_TUNNEL},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 196, 217, 14, 35, SPR_IMG_REMOVE, STR_1811_TOGGLE_BUILD_REMOVE_FOR},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 218, 239, 14, 35, SPR_IMG_LANDSCAPING, STR_LANDSCAPING_TOOLBAR_TIP},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _build_road_desc = {
+ WDP_ALIGN_TBR, 22, 240, 36,
+ WC_BUILD_TOOLBAR, 0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON,
+ _build_road_widgets,
+ BuildRoadToolbWndProc
+};
+
+void ShowBuildRoadToolbar(void)
+{
+ if (!IsValidPlayer(_current_player)) return;
+
+ DeleteWindowById(WC_BUILD_TOOLBAR, 0);
+ AllocateWindowDesc(&_build_road_desc);
+ if (_patches.link_terraform_toolbar) ShowTerraformToolbar();
+}
+
+static const Widget _build_road_scen_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 140, 0, 13, STR_1802_ROAD_CONSTRUCTION, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_STICKYBOX, RESIZE_NONE, 7, 141, 152, 0, 13, 0x0, STR_STICKY_BUTTON},
+
+{ WWT_IMGBTN, RESIZE_NONE, 7, 0, 21, 14, 35, SPR_IMG_ROAD_NW, STR_180B_BUILD_ROAD_SECTION},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 22, 43, 14, 35, SPR_IMG_ROAD_NE, STR_180B_BUILD_ROAD_SECTION},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 44, 65, 14, 35, SPR_IMG_DYNAMITE, STR_018D_DEMOLISH_BUILDINGS_ETC},
+{ WWT_EMPTY, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL},
+{ WWT_EMPTY, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL},
+{ WWT_EMPTY, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 66, 107, 14, 35, SPR_IMG_BRIDGE, STR_180F_BUILD_ROAD_BRIDGE},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 108, 129, 14, 35, SPR_IMG_ROAD_TUNNEL, STR_1810_BUILD_ROAD_TUNNEL},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 130, 151, 14, 35, SPR_IMG_REMOVE, STR_1811_TOGGLE_BUILD_REMOVE_FOR},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _build_road_scen_desc = {
+ WDP_AUTO, WDP_AUTO, 152, 36,
+ WC_SCEN_BUILD_ROAD, 0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON,
+ _build_road_scen_widgets,
+ BuildRoadToolbWndProc
+};
+
+void ShowBuildRoadScenToolbar(void)
+{
+ AllocateWindowDescFront(&_build_road_scen_desc, 0);
+}
+
+static void BuildRoadDepotWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_CREATE: LowerWindowWidget(w, _road_depot_orientation + 3); break;
+
+ case WE_PAINT:
+ DrawWindowWidgets(w);
+
+ DrawRoadDepotSprite(70, 17, DIAGDIR_NE);
+ DrawRoadDepotSprite(70, 69, DIAGDIR_SE);
+ DrawRoadDepotSprite( 2, 69, DIAGDIR_SW);
+ DrawRoadDepotSprite( 2, 17, DIAGDIR_NW);
+ break;
+
+ case WE_CLICK: {
+ switch (e->we.click.widget) {
+ case 3: case 4: case 5: case 6:
+ RaiseWindowWidget(w, _road_depot_orientation + 3);
+ _road_depot_orientation = e->we.click.widget - 3;
+ LowerWindowWidget(w, _road_depot_orientation + 3);
+ SndPlayFx(SND_15_BEEP);
+ SetWindowDirty(w);
+ break;
+ }
+ } break;
+
+ case WE_MOUSELOOP:
+ if (WP(w,def_d).close) DeleteWindow(w);
+ break;
+
+ case WE_DESTROY:
+ if (!WP(w,def_d).close) ResetObjectToPlace();
+ break;
+ }
+}
+
+static const Widget _build_road_depot_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 139, 0, 13, STR_1806_ROAD_DEPOT_ORIENTATION, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 139, 14, 121, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 14, 71, 136, 17, 66, 0x0, STR_1813_SELECT_ROAD_VEHICLE_DEPOT},
+{ WWT_PANEL, RESIZE_NONE, 14, 71, 136, 69, 118, 0x0, STR_1813_SELECT_ROAD_VEHICLE_DEPOT},
+{ WWT_PANEL, RESIZE_NONE, 14, 3, 68, 69, 118, 0x0, STR_1813_SELECT_ROAD_VEHICLE_DEPOT},
+{ WWT_PANEL, RESIZE_NONE, 14, 3, 68, 17, 66, 0x0, STR_1813_SELECT_ROAD_VEHICLE_DEPOT},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _build_road_depot_desc = {
+ WDP_AUTO, WDP_AUTO, 140, 122,
+ WC_BUILD_DEPOT, WC_BUILD_TOOLBAR,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _build_road_depot_widgets,
+ BuildRoadDepotWndProc
+};
+
+static void ShowRoadDepotPicker(void)
+{
+ AllocateWindowDesc(&_build_road_depot_desc);
+}
+
+static void RoadStationPickerWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_CREATE:
+ LowerWindowWidget(w, _road_station_picker_orientation + 3);
+ LowerWindowWidget(w, _station_show_coverage + 7);
+ break;
+
+ case WE_PAINT: {
+ int image;
+
+ if (WP(w,def_d).close) return;
+
+ DrawWindowWidgets(w);
+
+ if (_station_show_coverage) {
+ int rad = _patches.modified_catchment ? CA_TRUCK /* = CA_BUS */ : 4;
+ SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
+ } else {
+ SetTileSelectSize(1, 1);
+ }
+
+ image = (w->window_class == WC_BUS_STATION) ? 0x47 : 0x43;
+
+ StationPickerDrawSprite(103, 35, 0, image);
+ StationPickerDrawSprite(103, 85, 0, image+1);
+ StationPickerDrawSprite(35, 85, 0, image+2);
+ StationPickerDrawSprite(35, 35, 0, image+3);
+
+ DrawStationCoverageAreaText(2, 146,
+ ((w->window_class == WC_BUS_STATION) ? (1<<CT_PASSENGERS) : ~(1<<CT_PASSENGERS)),
+ 3);
+
+ } break;
+
+ case WE_CLICK: {
+ switch (e->we.click.widget) {
+ case 3: case 4: case 5: case 6:
+ RaiseWindowWidget(w, _road_station_picker_orientation + 3);
+ _road_station_picker_orientation = e->we.click.widget - 3;
+ LowerWindowWidget(w, _road_station_picker_orientation + 3);
+ SndPlayFx(SND_15_BEEP);
+ SetWindowDirty(w);
+ break;
+ case 7: case 8:
+ RaiseWindowWidget(w, _station_show_coverage + 7);
+ _station_show_coverage = e->we.click.widget - 7;
+ LowerWindowWidget(w, _station_show_coverage + 7);
+ SndPlayFx(SND_15_BEEP);
+ SetWindowDirty(w);
+ break;
+ }
+ } break;
+
+ case WE_MOUSELOOP: {
+ if (WP(w,def_d).close) {
+ DeleteWindow(w);
+ return;
+ }
+
+ CheckRedrawStationCoverage(w);
+ } break;
+
+ case WE_DESTROY:
+ if (!WP(w,def_d).close) ResetObjectToPlace();
+ break;
+ }
+}
+
+static const Widget _bus_station_picker_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 139, 0, 13, STR_3042_BUS_STATION_ORIENTATION, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 139, 14, 176, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 14, 71, 136, 17, 66, 0x0, STR_3051_SELECT_BUS_STATION_ORIENTATION},
+{ WWT_PANEL, RESIZE_NONE, 14, 71, 136, 69, 118, 0x0, STR_3051_SELECT_BUS_STATION_ORIENTATION},
+{ WWT_PANEL, RESIZE_NONE, 14, 3, 68, 69, 118, 0x0, STR_3051_SELECT_BUS_STATION_ORIENTATION},
+{ WWT_PANEL, RESIZE_NONE, 14, 3, 68, 17, 66, 0x0, STR_3051_SELECT_BUS_STATION_ORIENTATION},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 10, 69, 133, 144, STR_02DB_OFF, STR_3065_DON_T_HIGHLIGHT_COVERAGE},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 70, 129, 133, 144, STR_02DA_ON, STR_3064_HIGHLIGHT_COVERAGE_AREA},
+{ WWT_LABEL, RESIZE_NONE, 7, 0, 139, 120, 133, STR_3066_COVERAGE_AREA_HIGHLIGHT, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _bus_station_picker_desc = {
+ WDP_AUTO, WDP_AUTO, 140, 177,
+ WC_BUS_STATION, WC_BUILD_TOOLBAR,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _bus_station_picker_widgets,
+ RoadStationPickerWndProc
+};
+
+static void ShowBusStationPicker(void)
+{
+ AllocateWindowDesc(&_bus_station_picker_desc);
+}
+
+static const Widget _truck_station_picker_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 139, 0, 13, STR_3043_TRUCK_STATION_ORIENT, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 139, 14, 176, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 14, 71, 136, 17, 66, 0x0, STR_3052_SELECT_TRUCK_LOADING_BAY},
+{ WWT_PANEL, RESIZE_NONE, 14, 71, 136, 69, 118, 0x0, STR_3052_SELECT_TRUCK_LOADING_BAY},
+{ WWT_PANEL, RESIZE_NONE, 14, 3, 68, 69, 118, 0x0, STR_3052_SELECT_TRUCK_LOADING_BAY},
+{ WWT_PANEL, RESIZE_NONE, 14, 3, 68, 17, 66, 0x0, STR_3052_SELECT_TRUCK_LOADING_BAY},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 10, 69, 133, 144, STR_02DB_OFF, STR_3065_DON_T_HIGHLIGHT_COVERAGE},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 70, 129, 133, 144, STR_02DA_ON, STR_3064_HIGHLIGHT_COVERAGE_AREA},
+{ WWT_LABEL, RESIZE_NONE, 7, 0, 139, 120, 133, STR_3066_COVERAGE_AREA_HIGHLIGHT, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _truck_station_picker_desc = {
+ WDP_AUTO, WDP_AUTO, 140, 177,
+ WC_TRUCK_STATION, WC_BUILD_TOOLBAR,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _truck_station_picker_widgets,
+ RoadStationPickerWndProc
+};
+
+static void ShowTruckStationPicker(void)
+{
+ AllocateWindowDesc(&_truck_station_picker_desc);
+}
+
+void InitializeRoadGui(void)
+{
+ _road_depot_orientation = 3;
+ _road_station_picker_orientation = 3;
+}
diff --git a/src/road_map.c b/src/road_map.c
new file mode 100644
index 000000000..cccd2e76a
--- /dev/null
+++ b/src/road_map.c
@@ -0,0 +1,54 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "bridge_map.h"
+#include "functions.h"
+#include "road_map.h"
+#include "station.h"
+#include "tunnel_map.h"
+#include "station_map.h"
+#include "depot.h"
+
+
+RoadBits GetAnyRoadBits(TileIndex tile)
+{
+ switch (GetTileType(tile)) {
+ case MP_STREET:
+ switch (GetRoadTileType(tile)) {
+ default:
+ case ROAD_TILE_NORMAL: return GetRoadBits(tile);
+ case ROAD_TILE_CROSSING: return GetCrossingRoadBits(tile);
+ case ROAD_TILE_DEPOT: return DiagDirToRoadBits(GetRoadDepotDirection(tile));
+ }
+
+ case MP_STATION:
+ if (!IsRoadStopTile(tile)) return 0;
+ return DiagDirToRoadBits(GetRoadStopDir(tile));
+
+ case MP_TUNNELBRIDGE:
+ if (IsTunnel(tile)) {
+ if (GetTunnelTransportType(tile) != TRANSPORT_ROAD) return 0;
+ return DiagDirToRoadBits(ReverseDiagDir(GetTunnelDirection(tile)));
+ } else {
+ if (GetBridgeTransportType(tile) != TRANSPORT_ROAD) return 0;
+ return DiagDirToRoadBits(ReverseDiagDir(GetBridgeRampDirection(tile)));
+ }
+
+ default: return 0;
+ }
+}
+
+
+TrackBits GetAnyRoadTrackBits(TileIndex tile)
+{
+ uint32 r;
+
+ // Don't allow local authorities to build roads through road depots or road stops.
+ if ((IsTileType(tile, MP_STREET) && IsTileDepotType(tile, TRANSPORT_ROAD)) || IsTileType(tile, MP_STATION)) {
+ return 0;
+ }
+
+ r = GetTileTrackStatus(tile, TRANSPORT_ROAD);
+ return (byte)(r | (r >> 8));
+}
diff --git a/src/road_map.h b/src/road_map.h
new file mode 100644
index 000000000..258c41e3b
--- /dev/null
+++ b/src/road_map.h
@@ -0,0 +1,213 @@
+/* $Id$ */
+
+#ifndef ROAD_MAP_H
+#define ROAD_MAP_H
+
+#include "macros.h"
+#include "rail.h"
+#include "road.h"
+#include "tile.h"
+
+
+typedef enum RoadTileType {
+ ROAD_TILE_NORMAL,
+ ROAD_TILE_CROSSING,
+ ROAD_TILE_DEPOT
+} RoadTileType;
+
+static inline RoadTileType GetRoadTileType(TileIndex t)
+{
+ assert(IsTileType(t, MP_STREET));
+ return (RoadTileType)GB(_m[t].m5, 4, 4);
+}
+
+static inline bool IsLevelCrossing(TileIndex t)
+{
+ return GetRoadTileType(t) == ROAD_TILE_CROSSING;
+}
+
+static inline bool IsLevelCrossingTile(TileIndex t)
+{
+ return IsTileType(t, MP_STREET) && IsLevelCrossing(t);
+}
+
+static inline RoadBits GetRoadBits(TileIndex t)
+{
+ assert(GetRoadTileType(t) == ROAD_TILE_NORMAL);
+ return (RoadBits)GB(_m[t].m5, 0, 4);
+}
+
+static inline void SetRoadBits(TileIndex t, RoadBits r)
+{
+ assert(GetRoadTileType(t) == ROAD_TILE_NORMAL); // XXX incomplete
+ SB(_m[t].m5, 0, 4, r);
+}
+
+
+static inline Axis GetCrossingRoadAxis(TileIndex t)
+{
+ assert(GetRoadTileType(t) == ROAD_TILE_CROSSING);
+ return (Axis)GB(_m[t].m5, 3, 1);
+}
+
+static inline RoadBits GetCrossingRoadBits(TileIndex tile)
+{
+ return GetCrossingRoadAxis(tile) == AXIS_X ? ROAD_X : ROAD_Y;
+}
+
+static inline TrackBits GetCrossingRailBits(TileIndex tile)
+{
+ return AxisToTrackBits(OtherAxis(GetCrossingRoadAxis(tile)));
+}
+
+
+// TODO swap owner of road and rail
+static inline Owner GetCrossingRoadOwner(TileIndex t)
+{
+ assert(GetRoadTileType(t) == ROAD_TILE_CROSSING);
+ return (Owner)_m[t].m3;
+}
+
+static inline void SetCrossingRoadOwner(TileIndex t, Owner o)
+{
+ assert(GetRoadTileType(t) == ROAD_TILE_CROSSING);
+ _m[t].m3 = o;
+}
+
+static inline void UnbarCrossing(TileIndex t)
+{
+ assert(GetRoadTileType(t) == ROAD_TILE_CROSSING);
+ CLRBIT(_m[t].m5, 2);
+}
+
+static inline void BarCrossing(TileIndex t)
+{
+ assert(GetRoadTileType(t) == ROAD_TILE_CROSSING);
+ SETBIT(_m[t].m5, 2);
+}
+
+static inline bool IsCrossingBarred(TileIndex t)
+{
+ assert(GetRoadTileType(t) == ROAD_TILE_CROSSING);
+ return HASBIT(_m[t].m5, 2);
+}
+
+#define IsOnDesert IsOnSnow
+static inline bool IsOnSnow(TileIndex t)
+{
+ return HASBIT(_m[t].m4, 7);
+}
+
+#define ToggleDesert ToggleSnow
+static inline void ToggleSnow(TileIndex t)
+{
+ TOGGLEBIT(_m[t].m4, 7);
+}
+
+
+typedef enum Roadside {
+ ROADSIDE_BARREN = 0,
+ ROADSIDE_GRASS = 1,
+ ROADSIDE_PAVED = 2,
+ ROADSIDE_STREET_LIGHTS = 3,
+ ROADSIDE_TREES = 5,
+ ROADSIDE_GRASS_ROAD_WORKS = 6,
+ ROADSIDE_PAVED_ROAD_WORKS = 7
+} Roadside;
+
+static inline Roadside GetRoadside(TileIndex tile)
+{
+ return (Roadside)GB(_m[tile].m4, 4, 3);
+}
+
+static inline void SetRoadside(TileIndex tile, Roadside s)
+{
+ SB(_m[tile].m4, 4, 3, s);
+}
+
+static inline bool HasRoadWorks(TileIndex t)
+{
+ return GetRoadside(t) >= ROADSIDE_GRASS_ROAD_WORKS;
+}
+
+static inline bool IncreaseRoadWorksCounter(TileIndex t)
+{
+ AB(_m[t].m4, 0, 4, 1);
+
+ return GB(_m[t].m4, 0, 4) == 15;
+}
+
+static inline void StartRoadWorks(TileIndex t)
+{
+ assert(!HasRoadWorks(t));
+ /* Remove any trees or lamps in case or roadwork */
+ switch (GetRoadside(t)) {
+ case ROADSIDE_BARREN:
+ case ROADSIDE_GRASS: SetRoadside(t, ROADSIDE_GRASS_ROAD_WORKS); break;
+ default: SetRoadside(t, ROADSIDE_PAVED_ROAD_WORKS); break;
+ }
+}
+
+static inline void TerminateRoadWorks(TileIndex t)
+{
+ assert(HasRoadWorks(t));
+ SetRoadside(t, (Roadside)(GetRoadside(t) - ROADSIDE_GRASS_ROAD_WORKS + ROADSIDE_GRASS));
+ /* Stop the counter */
+ SB(_m[t].m4, 0, 4, 0);
+}
+
+
+static inline DiagDirection GetRoadDepotDirection(TileIndex t)
+{
+ assert(GetRoadTileType(t) == ROAD_TILE_DEPOT);
+ return (DiagDirection)GB(_m[t].m5, 0, 2);
+}
+
+
+/**
+ * Returns the RoadBits on an arbitrary tile
+ * Special behavior:
+ * - road depots: entrance is treated as road piece
+ * - road tunnels: entrance is treated as road piece
+ * - bridge ramps: start of the ramp is treated as road piece
+ * - bridge middle parts: bridge itself is ignored
+ */
+RoadBits GetAnyRoadBits(TileIndex);
+
+
+TrackBits GetAnyRoadTrackBits(TileIndex tile);
+
+
+static inline void MakeRoadNormal(TileIndex t, Owner owner, RoadBits bits, TownID town)
+{
+ SetTileType(t, MP_STREET);
+ SetTileOwner(t, owner);
+ _m[t].m2 = town;
+ _m[t].m3 = 0;
+ _m[t].m4 = 0 << 7 | 0 << 4 | 0;
+ _m[t].m5 = ROAD_TILE_NORMAL << 4 | bits;
+}
+
+
+static inline void MakeRoadCrossing(TileIndex t, Owner road, Owner rail, Axis roaddir, RailType rt, uint town)
+{
+ SetTileType(t, MP_STREET);
+ SetTileOwner(t, rail);
+ _m[t].m2 = town;
+ _m[t].m3 = road;
+ _m[t].m4 = 0 << 7 | 0 << 4 | rt;
+ _m[t].m5 = ROAD_TILE_CROSSING << 4 | roaddir << 3 | 0 << 2;
+}
+
+
+static inline void MakeRoadDepot(TileIndex t, Owner owner, DiagDirection dir)
+{
+ SetTileType(t, MP_STREET);
+ SetTileOwner(t, owner);
+ _m[t].m2 = 0;
+ _m[t].m3 = 0;
+ _m[t].m4 = 0;
+ _m[t].m5 = ROAD_TILE_DEPOT << 4 | dir;
+}
+
+#endif /* ROAD_MAP_H */
diff --git a/src/roadveh.h b/src/roadveh.h
new file mode 100644
index 000000000..e0c497b46
--- /dev/null
+++ b/src/roadveh.h
@@ -0,0 +1,22 @@
+/* $Id$ */
+
+#ifndef ROADVEH_H
+#define ROADVEH_H
+
+#include "vehicle.h"
+
+
+static inline bool IsRoadVehInDepot(const Vehicle* v)
+{
+ assert(v->type == VEH_Road);
+ return v->u.road.state == 254;
+}
+
+static inline bool IsRoadVehInDepotStopped(const Vehicle* v)
+{
+ return IsRoadVehInDepot(v) && v->vehstatus & VS_STOPPED;
+}
+
+void CcCloneRoadVeh(bool success, TileIndex tile, uint32 p1, uint32 p2);
+
+#endif /* ROADVEH_H */
diff --git a/src/roadveh_cmd.c b/src/roadveh_cmd.c
new file mode 100644
index 000000000..48f6ad180
--- /dev/null
+++ b/src/roadveh_cmd.c
@@ -0,0 +1,1826 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include <limits.h>
+#include "openttd.h"
+#include "debug.h"
+#include "functions.h"
+#include "road_map.h"
+#include "roadveh.h"
+#include "station_map.h"
+#include "table/strings.h"
+#include "map.h"
+#include "tile.h"
+#include "vehicle.h"
+#include "engine.h"
+#include "command.h"
+#include "station.h"
+#include "news.h"
+#include "pathfind.h"
+#include "npf.h"
+#include "player.h"
+#include "sound.h"
+#include "depot.h"
+#include "bridge.h"
+#include "tunnel_map.h"
+#include "bridge_map.h"
+#include "vehicle_gui.h"
+#include "newgrf_callbacks.h"
+#include "newgrf_engine.h"
+#include "newgrf_text.h"
+#include "newgrf_sound.h"
+#include "yapf/yapf.h"
+#include "date.h"
+
+static const uint16 _roadveh_images[63] = {
+ 0xCD4, 0xCDC, 0xCE4, 0xCEC, 0xCF4, 0xCFC, 0xD0C, 0xD14,
+ 0xD24, 0xD1C, 0xD2C, 0xD04, 0xD1C, 0xD24, 0xD6C, 0xD74,
+ 0xD7C, 0xC14, 0xC1C, 0xC24, 0xC2C, 0xC34, 0xC3C, 0xC4C,
+ 0xC54, 0xC64, 0xC5C, 0xC6C, 0xC44, 0xC5C, 0xC64, 0xCAC,
+ 0xCB4, 0xCBC, 0xD94, 0xD9C, 0xDA4, 0xDAC, 0xDB4, 0xDBC,
+ 0xDCC, 0xDD4, 0xDE4, 0xDDC, 0xDEC, 0xDC4, 0xDDC, 0xDE4,
+ 0xE2C, 0xE34, 0xE3C, 0xC14, 0xC1C, 0xC2C, 0xC3C, 0xC4C,
+ 0xC5C, 0xC64, 0xC6C, 0xC74, 0xC84, 0xC94, 0xCA4
+};
+
+static const uint16 _roadveh_full_adder[63] = {
+ 0, 88, 0, 0, 0, 0, 48, 48,
+ 48, 48, 0, 0, 64, 64, 0, 16,
+ 16, 0, 88, 0, 0, 0, 0, 48,
+ 48, 48, 48, 0, 0, 64, 64, 0,
+ 16, 16, 0, 88, 0, 0, 0, 0,
+ 48, 48, 48, 48, 0, 0, 64, 64,
+ 0, 16, 16, 0, 8, 8, 8, 8,
+ 0, 0, 0, 8, 8, 8, 8
+};
+
+
+static const uint16 _road_veh_fp_ax_and[4] = {
+ 0x1009, 0x16, 0x520, 0x2A00
+};
+
+static const byte _road_reverse_table[4] = {
+ 6, 7, 14, 15
+};
+
+static const uint16 _road_pf_table_3[4] = {
+ 0x910, 0x1600, 0x2005, 0x2A
+};
+
+int GetRoadVehImage(const Vehicle* v, Direction direction)
+{
+ int img = v->spritenum;
+ int image;
+
+ if (is_custom_sprite(img)) {
+ image = GetCustomVehicleSprite(v, direction);
+ if (image != 0) return image;
+ img = orig_road_vehicle_info[v->engine_type - ROAD_ENGINES_INDEX].image_index;
+ }
+
+ image = direction + _roadveh_images[img];
+ if (v->cargo_count >= v->cargo_cap / 2) image += _roadveh_full_adder[img];
+ return image;
+}
+
+void DrawRoadVehEngine(int x, int y, EngineID engine, uint32 image_ormod)
+{
+ int spritenum = RoadVehInfo(engine)->image_index;
+
+ if (is_custom_sprite(spritenum)) {
+ int sprite = GetCustomVehicleIcon(engine, DIR_W);
+
+ if (sprite != 0) {
+ DrawSprite(sprite | image_ormod, x, y);
+ return;
+ }
+ spritenum = orig_road_vehicle_info[engine - ROAD_ENGINES_INDEX].image_index;
+ }
+ DrawSprite((6 + _roadveh_images[spritenum]) | image_ormod, x, y);
+}
+
+static int32 EstimateRoadVehCost(EngineID engine_type)
+{
+ return ((_price.roadveh_base >> 3) * RoadVehInfo(engine_type)->base_cost) >> 5;
+}
+
+/** Build a road vehicle.
+ * @param tile tile of depot where road vehicle is built
+ * @param p1 bus/truck type being built (engine)
+ * @param p2 bit 0 when set, the unitnumber will be 0, otherwise it will be a free number
+ */
+int32 CmdBuildRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ int32 cost;
+ Vehicle *v;
+ UnitID unit_num;
+ Engine *e;
+
+ if (!IsEngineBuildable(p1, VEH_Road, _current_player)) return_cmd_error(STR_ENGINE_NOT_BUILDABLE);
+
+ SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
+
+ cost = EstimateRoadVehCost(p1);
+ if (flags & DC_QUERY_COST) return cost;
+
+ /* The ai_new queries the vehicle cost before building the route,
+ * so we must check against cheaters no sooner than now. --pasky */
+ if (!IsTileDepotType(tile, TRANSPORT_ROAD)) return CMD_ERROR;
+ if (!IsTileOwner(tile, _current_player)) return CMD_ERROR;
+
+ v = AllocateVehicle();
+ if (v == NULL || IsOrderPoolFull())
+ return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
+
+ /* find the first free roadveh id */
+ unit_num = HASBIT(p2, 0) ? 0 : GetFreeUnitNumber(VEH_Road);
+ if (unit_num > _patches.max_roadveh)
+ return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
+
+ if (flags & DC_EXEC) {
+ int x;
+ int y;
+
+ const RoadVehicleInfo *rvi = RoadVehInfo(p1);
+
+ v->unitnumber = unit_num;
+ v->direction = 0;
+ v->owner = _current_player;
+
+ v->tile = tile;
+ x = TileX(tile) * TILE_SIZE + TILE_SIZE / 2;
+ y = TileY(tile) * TILE_SIZE + TILE_SIZE / 2;
+ v->x_pos = x;
+ v->y_pos = y;
+ v->z_pos = GetSlopeZ(x,y);
+ v->z_height = 6;
+
+ v->u.road.state = 254;
+ v->vehstatus = VS_HIDDEN|VS_STOPPED|VS_DEFPAL;
+
+ v->spritenum = rvi->image_index;
+ v->cargo_type = rvi->cargo_type;
+ v->cargo_subtype = 0;
+ v->cargo_cap = rvi->capacity;
+// v->cargo_count = 0;
+ v->value = cost;
+// v->day_counter = 0;
+// v->next_order_param = v->next_order = 0;
+// v->load_unload_time_rem = 0;
+// v->progress = 0;
+
+// v->u.road.unk2 = 0;
+// v->u.road.overtaking = 0;
+
+ v->last_station_visited = INVALID_STATION;
+ v->max_speed = rvi->max_speed;
+ v->engine_type = (byte)p1;
+
+ e = GetEngine(p1);
+ v->reliability = e->reliability;
+ v->reliability_spd_dec = e->reliability_spd_dec;
+ v->max_age = e->lifelength * 366;
+ _new_vehicle_id = v->index;
+
+ v->string_id = STR_SV_ROADVEH_NAME;
+
+ v->service_interval = _patches.servint_roadveh;
+
+ v->date_of_last_service = _date;
+ v->build_year = _cur_year;
+
+ v->type = VEH_Road;
+ v->cur_image = 0xC15;
+ v->random_bits = VehicleRandomBits();
+
+ VehiclePositionChanged(v);
+ GetPlayer(_current_player)->num_engines[p1]++;
+
+ InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
+ RebuildVehicleLists();
+ InvalidateWindow(WC_COMPANY, v->owner);
+ if (IsLocalPlayer())
+ InvalidateWindow(WC_REPLACE_VEHICLE, VEH_Road); // updates the replace Road window
+ }
+
+ return cost;
+}
+
+/** Start/Stop a road vehicle.
+ * @param tile unused
+ * @param p1 road vehicle ID to start/stop
+ * @param p2 unused
+ */
+int32 CmdStartStopRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle *v;
+ uint16 callback;
+
+ if (!IsValidVehicleID(p1)) return CMD_ERROR;
+
+ v = GetVehicle(p1);
+
+ if (v->type != VEH_Road || !CheckOwnership(v->owner)) return CMD_ERROR;
+
+ /* Check if this road veh can be started/stopped. The callback will fail or
+ * return 0xFF if it can. */
+ callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
+ if (callback != CALLBACK_FAILED && callback != 0xFF) {
+ StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
+ return_cmd_error(error);
+ }
+
+ if (flags & DC_EXEC) {
+ if (IsRoadVehInDepotStopped(v)) {
+ DeleteVehicleNews(p1, STR_9016_ROAD_VEHICLE_IS_WAITING);
+ }
+
+ v->vehstatus ^= VS_STOPPED;
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
+ }
+
+ return 0;
+}
+
+void ClearSlot(Vehicle *v)
+{
+ RoadStop *rs = v->u.road.slot;
+ if (v->u.road.slot == NULL) return;
+
+ v->u.road.slot = NULL;
+ v->u.road.slot_age = 0;
+
+ assert(rs->num_vehicles != 0);
+ rs->num_vehicles--;
+
+ DEBUG(ms, 3, "Clearing slot at 0x%X", rs->xy);
+}
+
+/** Sell a road vehicle.
+ * @param tile unused
+ * @param p1 vehicle ID to be sold
+ * @param p2 unused
+ */
+int32 CmdSellRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle *v;
+
+ if (!IsValidVehicleID(p1)) return CMD_ERROR;
+
+ v = GetVehicle(p1);
+
+ if (v->type != VEH_Road || !CheckOwnership(v->owner)) return CMD_ERROR;
+
+ SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
+
+ if (!IsRoadVehInDepotStopped(v)) {
+ return_cmd_error(STR_9013_MUST_BE_STOPPED_INSIDE);
+ }
+
+ if (flags & DC_EXEC) {
+ // Invalidate depot
+ InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
+ RebuildVehicleLists();
+ InvalidateWindow(WC_COMPANY, v->owner);
+ DeleteWindowById(WC_VEHICLE_VIEW, v->index);
+ ClearSlot(v);
+ DeleteDepotHighlightOfVehicle(v);
+ DeleteVehicle(v);
+ if (IsLocalPlayer()) InvalidateWindow(WC_REPLACE_VEHICLE, VEH_Road);
+ }
+
+ return -(int32)v->value;
+}
+
+typedef struct RoadFindDepotData {
+ uint best_length;
+ TileIndex tile;
+ byte owner;
+} RoadFindDepotData;
+
+static const DiagDirection _road_pf_directions[] = {
+ DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE, 255, 255,
+ DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE, 255, 255
+};
+
+static bool EnumRoadSignalFindDepot(TileIndex tile, void* data, int track, uint length, byte* state)
+{
+ RoadFindDepotData* rfdd = data;
+
+ tile += TileOffsByDiagDir(_road_pf_directions[track]);
+
+ if (IsTileType(tile, MP_STREET) &&
+ GetRoadTileType(tile) == ROAD_TILE_DEPOT &&
+ IsTileOwner(tile, rfdd->owner) &&
+ length < rfdd->best_length) {
+ rfdd->best_length = length;
+ rfdd->tile = tile;
+ }
+ return false;
+}
+
+static const Depot* FindClosestRoadDepot(const Vehicle* v)
+{
+ TileIndex tile = v->tile;
+
+ if (_patches.yapf.road_use_yapf) {
+ Depot* ret = YapfFindNearestRoadDepot(v);
+ return ret;
+ } else if (_patches.new_pathfinding_all) {
+ NPFFoundTargetData ftd;
+ /* See where we are now */
+ Trackdir trackdir = GetVehicleTrackdir(v);
+
+ ftd = NPFRouteToDepotBreadthFirst(v->tile, trackdir, TRANSPORT_ROAD, v->owner, INVALID_RAILTYPE);
+ if (ftd.best_bird_dist == 0) {
+ return GetDepotByTile(ftd.node.tile); /* Target found */
+ } else {
+ return NULL; /* Target not found */
+ }
+ /* We do not search in two directions here, why should we? We can't reverse right now can we? */
+ } else {
+ RoadFindDepotData rfdd;
+ DiagDirection i;
+
+ rfdd.owner = v->owner;
+ rfdd.best_length = (uint)-1;
+
+ /* search in all directions */
+ for (i = 0; i != 4; i++) {
+ FollowTrack(tile, 0x2000 | TRANSPORT_ROAD, i, EnumRoadSignalFindDepot, NULL, &rfdd);
+ }
+
+ if (rfdd.best_length == (uint)-1) return NULL;
+
+ return GetDepotByTile(rfdd.tile);
+ }
+}
+
+/** Send a road vehicle to the depot.
+ * @param tile unused
+ * @param p1 vehicle ID to send to the depot
+ * @param p2 various bitmasked elements
+ * - p2 bit 0-3 - DEPOT_ flags (see vehicle.h)
+ * - p2 bit 8-10 - VLW flag (for mass goto depot)
+ */
+int32 CmdSendRoadVehToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle *v;
+ const Depot *dep;
+
+ if (p2 & DEPOT_MASS_SEND) {
+ /* Mass goto depot requested */
+ if (!ValidVLWFlags(p2 & VLW_MASK)) return CMD_ERROR;
+ return SendAllVehiclesToDepot(VEH_Road, flags, p2 & DEPOT_SERVICE, _current_player, (p2 & VLW_MASK), p1);
+ }
+
+ if (!IsValidVehicleID(p1)) return CMD_ERROR;
+
+ v = GetVehicle(p1);
+
+ if (v->type != VEH_Road || !CheckOwnership(v->owner)) return CMD_ERROR;
+
+ if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
+
+ if (IsRoadVehInDepot(v)) return CMD_ERROR;
+
+ /* If the current orders are already goto-depot */
+ if (v->current_order.type == OT_GOTO_DEPOT) {
+ if (!!(p2 & DEPOT_SERVICE) == HASBIT(v->current_order.flags, OFB_HALT_IN_DEPOT)) {
+ /* We called with a different DEPOT_SERVICE setting.
+ * Now we change the setting to apply the new one and let the vehicle head for the same depot.
+ * Note: the if is (true for requesting service == true for ordered to stop in depot) */
+ if (flags & DC_EXEC) {
+ TOGGLEBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ }
+ return 0;
+ }
+
+ if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
+ if (flags & DC_EXEC) {
+ /* If the orders to 'goto depot' are in the orders list (forced servicing),
+ * then skip to the next order; effectively cancelling this forced service */
+ if (HASBIT(v->current_order.flags, OFB_PART_OF_ORDERS))
+ v->cur_order_index++;
+
+ v->current_order.type = OT_DUMMY;
+ v->current_order.flags = 0;
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ }
+ return 0;
+ }
+
+ dep = FindClosestRoadDepot(v);
+ if (dep == NULL) return_cmd_error(STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT);
+
+ if (flags & DC_EXEC) {
+ ClearSlot(v);
+ v->current_order.type = OT_GOTO_DEPOT;
+ v->current_order.flags = OF_NON_STOP;
+ if (!(p2 & DEPOT_SERVICE)) SETBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
+ v->current_order.refit_cargo = CT_INVALID;
+ v->current_order.dest = dep->index;
+ v->dest_tile = dep->xy;
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ }
+
+ return 0;
+}
+
+/** Turn a roadvehicle around.
+ * @param tile unused
+ * @param p1 vehicle ID to turn
+ * @param p2 unused
+ */
+int32 CmdTurnRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle *v;
+
+ if (!IsValidVehicleID(p1)) return CMD_ERROR;
+
+ v = GetVehicle(p1);
+
+ if (v->type != VEH_Road || !CheckOwnership(v->owner)) return CMD_ERROR;
+
+ if (v->vehstatus & VS_STOPPED ||
+ v->u.road.crashed_ctr != 0 ||
+ v->breakdown_ctr != 0 ||
+ v->u.road.overtaking != 0 ||
+ v->u.road.state == 255 ||
+ IsRoadVehInDepot(v) ||
+ v->cur_speed < 5) {
+ return CMD_ERROR;
+ }
+
+ if (IsTunnelTile(v->tile) && DirToDiagDir(v->direction) == GetTunnelDirection(v->tile)) return CMD_ERROR;
+ if (IsBridgeTile(v->tile) && DirToDiagDir(v->direction) == GetBridgeRampDirection(v->tile)) return CMD_ERROR;
+
+ if (flags & DC_EXEC) v->u.road.reverse_ctr = 180;
+
+ return 0;
+}
+
+
+static void MarkRoadVehDirty(Vehicle *v)
+{
+ v->cur_image = GetRoadVehImage(v, v->direction);
+ MarkAllViewportsDirty(v->left_coord, v->top_coord, v->right_coord + 1, v->bottom_coord + 1);
+}
+
+static void UpdateRoadVehDeltaXY(Vehicle *v)
+{
+#define MKIT(a,b,c,d) ((a&0xFF)<<24) | ((b&0xFF)<<16) | ((c&0xFF)<<8) | ((d&0xFF)<<0)
+ static const uint32 _delta_xy_table[8] = {
+ MKIT(3, 3, -1, -1),
+ MKIT(3, 7, -1, -3),
+ MKIT(3, 3, -1, -1),
+ MKIT(7, 3, -3, -1),
+ MKIT(3, 3, -1, -1),
+ MKIT(3, 7, -1, -3),
+ MKIT(3, 3, -1, -1),
+ MKIT(7, 3, -3, -1),
+ };
+#undef MKIT
+ uint32 x = _delta_xy_table[v->direction];
+ v->x_offs = GB(x, 0, 8);
+ v->y_offs = GB(x, 8, 8);
+ v->sprite_width = GB(x, 16, 8);
+ v->sprite_height = GB(x, 24, 8);
+}
+
+static void ClearCrashedStation(Vehicle *v)
+{
+ RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile));
+
+ // mark station as not busy
+ CLRBIT(rs->status, 7);
+
+ // free parking bay
+ SETBIT(rs->status, HASBIT(v->u.road.state, 1) ? 1 : 0);
+}
+
+static void RoadVehDelete(Vehicle *v)
+{
+ DeleteWindowById(WC_VEHICLE_VIEW, v->index);
+ InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
+
+ RebuildVehicleLists();
+ InvalidateWindow(WC_COMPANY, v->owner);
+
+ if (IsTileType(v->tile, MP_STATION)) ClearCrashedStation(v);
+
+ BeginVehicleMove(v);
+ EndVehicleMove(v);
+
+ ClearSlot(v);
+ DeleteVehicle(v);
+}
+
+static byte SetRoadVehPosition(Vehicle *v, int x, int y)
+{
+ byte new_z, old_z;
+
+ // need this hint so it returns the right z coordinate on bridges.
+ v->x_pos = x;
+ v->y_pos = y;
+ new_z = GetSlopeZ(x, y);
+
+ old_z = v->z_pos;
+ v->z_pos = new_z;
+
+ VehiclePositionChanged(v);
+ EndVehicleMove(v);
+ return old_z;
+}
+
+static void RoadVehSetRandomDirection(Vehicle *v)
+{
+ static const DirDiff delta[] = {
+ DIRDIFF_45LEFT, DIRDIFF_SAME, DIRDIFF_SAME, DIRDIFF_45RIGHT
+ };
+
+ uint32 r = Random();
+
+ v->direction = ChangeDir(v->direction, delta[r & 3]);
+ BeginVehicleMove(v);
+ UpdateRoadVehDeltaXY(v);
+ v->cur_image = GetRoadVehImage(v, v->direction);
+ SetRoadVehPosition(v, v->x_pos, v->y_pos);
+}
+
+static void RoadVehIsCrashed(Vehicle *v)
+{
+ v->u.road.crashed_ctr++;
+ if (v->u.road.crashed_ctr == 2) {
+ CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE);
+ } else if (v->u.road.crashed_ctr <= 45) {
+ if ((v->tick_counter & 7) == 0) RoadVehSetRandomDirection(v);
+ } else if (v->u.road.crashed_ctr >= 2220) {
+ RoadVehDelete(v);
+ }
+}
+
+static void* EnumCheckRoadVehCrashTrain(Vehicle* v, void* data)
+{
+ const Vehicle* u = data;
+
+ return
+ v->type == VEH_Train &&
+ myabs(v->z_pos - u->z_pos) <= 6 &&
+ myabs(v->x_pos - u->x_pos) <= 4 &&
+ myabs(v->y_pos - u->y_pos) <= 4 ?
+ v : NULL;
+}
+
+static void RoadVehCrash(Vehicle *v)
+{
+ uint16 pass;
+
+ v->u.road.crashed_ctr++;
+ v->vehstatus |= VS_CRASHED;
+ ClearSlot(v);
+
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+
+ pass = 1;
+ if (v->cargo_type == CT_PASSENGERS) pass += v->cargo_count;
+ v->cargo_count = 0;
+
+ SetDParam(0, pass);
+ AddNewsItem(
+ (pass == 1) ?
+ STR_9031_ROAD_VEHICLE_CRASH_DRIVER : STR_9032_ROAD_VEHICLE_CRASH_DIE,
+ NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ACCIDENT, 0),
+ v->index,
+ 0
+ );
+
+ ModifyStationRatingAround(v->tile, v->owner, -160, 22);
+ SndPlayVehicleFx(SND_12_EXPLOSION, v);
+}
+
+static void RoadVehCheckTrainCrash(Vehicle *v)
+{
+ TileIndex tile;
+
+ if (v->u.road.state == 255) return;
+
+ tile = v->tile;
+
+ if (!IsLevelCrossingTile(tile)) return;
+
+ if (VehicleFromPos(tile, v, EnumCheckRoadVehCrashTrain) != NULL)
+ RoadVehCrash(v);
+}
+
+static void HandleBrokenRoadVeh(Vehicle *v)
+{
+ if (v->breakdown_ctr != 1) {
+ v->breakdown_ctr = 1;
+ v->cur_speed = 0;
+
+ if (v->breakdowns_since_last_service != 255)
+ v->breakdowns_since_last_service++;
+
+ InvalidateWindow(WC_VEHICLE_VIEW, v->index);
+ InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
+
+ if (!PlayVehicleSound(v, VSE_BREAKDOWN)) {
+ SndPlayVehicleFx((_opt.landscape != LT_CANDY) ?
+ SND_0F_VEHICLE_BREAKDOWN : SND_35_COMEDY_BREAKDOWN, v);
+ }
+
+ if (!(v->vehstatus & VS_HIDDEN)) {
+ Vehicle *u = CreateEffectVehicleRel(v, 4, 4, 5, EV_BREAKDOWN_SMOKE);
+ if (u != NULL) u->u.special.unk0 = v->breakdown_delay * 2;
+ }
+ }
+
+ if ((v->tick_counter & 1) == 0) {
+ if (--v->breakdown_delay == 0) {
+ v->breakdown_ctr = 0;
+ InvalidateWindow(WC_VEHICLE_VIEW, v->index);
+ }
+ }
+}
+
+static void ProcessRoadVehOrder(Vehicle *v)
+{
+ const Order *order;
+
+ switch (v->current_order.type) {
+ case OT_GOTO_DEPOT:
+ // Let a depot order in the orderlist interrupt.
+ if (!(v->current_order.flags & OF_PART_OF_ORDERS)) return;
+ if (v->current_order.flags & OF_SERVICE_IF_NEEDED &&
+ !VehicleNeedsService(v)) {
+ v->cur_order_index++;
+ }
+ break;
+
+ case OT_LOADING:
+ case OT_LEAVESTATION:
+ return;
+
+ default: break;
+ }
+
+ if (v->cur_order_index >= v->num_orders) v->cur_order_index = 0;
+
+ order = GetVehicleOrder(v, v->cur_order_index);
+
+ if (order == NULL) {
+ v->current_order.type = OT_NOTHING;
+ v->current_order.flags = 0;
+ v->dest_tile = 0;
+ ClearSlot(v);
+ return;
+ }
+
+ if (order->type == v->current_order.type &&
+ order->flags == v->current_order.flags &&
+ order->dest == v->current_order.dest) {
+ return;
+ }
+
+ v->current_order = *order;
+
+ switch (order->type) {
+ case OT_GOTO_STATION: {
+ const RoadStop* rs;
+
+ if (order->dest == v->last_station_visited) {
+ v->last_station_visited = INVALID_STATION;
+ }
+
+ rs = GetPrimaryRoadStop(
+ GetStation(order->dest),
+ v->cargo_type == CT_PASSENGERS ? RS_BUS : RS_TRUCK
+ );
+
+ if (rs != NULL) {
+ TileIndex dest = rs->xy;
+ uint mindist = DistanceManhattan(v->tile, rs->xy);
+
+ for (rs = rs->next; rs != NULL; rs = rs->next) {
+ uint dist = DistanceManhattan(v->tile, rs->xy);
+
+ if (dist < mindist) {
+ mindist = dist;
+ dest = rs->xy;
+ }
+ }
+ v->dest_tile = dest;
+ } else {
+ // There is no stop left at the station, so don't even TRY to go there
+ v->cur_order_index++;
+ v->dest_tile = 0;
+ }
+ break;
+ }
+
+ case OT_GOTO_DEPOT:
+ v->dest_tile = GetDepot(order->dest)->xy;
+ break;
+
+ default:
+ v->dest_tile = 0;
+ break;
+ }
+
+ InvalidateVehicleOrder(v);
+}
+
+static void HandleRoadVehLoading(Vehicle *v)
+{
+ switch (v->current_order.type) {
+ case OT_LOADING: {
+ Order b;
+
+ if (--v->load_unload_time_rem != 0) return;
+
+ if (CanFillVehicle(v) && (v->current_order.flags & OF_FULL_LOAD ||
+ (_patches.gradual_loading && !HASBIT(v->load_status, LS_LOADING_FINISHED)))) {
+ SET_EXPENSES_TYPE(EXPENSES_ROADVEH_INC);
+ if (LoadUnloadVehicle(v, false)) {
+ InvalidateWindow(WC_ROADVEH_LIST, v->owner);
+ MarkRoadVehDirty(v);
+ }
+ return;
+ }
+
+ b = v->current_order;
+ v->current_order.type = OT_LEAVESTATION;
+ v->current_order.flags = 0;
+ if (!(b.flags & OF_NON_STOP)) return;
+ break;
+ }
+
+ case OT_DUMMY: break;
+
+ default: return;
+ }
+
+ v->cur_order_index++;
+ InvalidateVehicleOrder(v);
+}
+
+static void StartRoadVehSound(const Vehicle* v)
+{
+ if (!PlayVehicleSound(v, VSE_START)) {
+ SoundFx s = RoadVehInfo(v->engine_type)->sfx;
+ if (s == SND_19_BUS_START_PULL_AWAY && (v->tick_counter & 3) == 0)
+ s = SND_1A_BUS_START_PULL_AWAY_WITH_HORN;
+ SndPlayVehicleFx(s, v);
+ }
+}
+
+typedef struct RoadVehFindData {
+ int x;
+ int y;
+ const Vehicle* veh;
+ Direction dir;
+} RoadVehFindData;
+
+static void* EnumCheckRoadVehClose(Vehicle *v, void* data)
+{
+ static const int8 dist_x[] = { -4, -8, -4, -1, 4, 8, 4, 1 };
+ static const int8 dist_y[] = { -4, -1, 4, 8, 4, 1, -4, -8 };
+
+ const RoadVehFindData* rvf = data;
+
+ short x_diff = v->x_pos - rvf->x;
+ short y_diff = v->y_pos - rvf->y;
+
+ return
+ rvf->veh != v &&
+ v->type == VEH_Road &&
+ !IsRoadVehInDepot(v) &&
+ myabs(v->z_pos - rvf->veh->z_pos) < 6 &&
+ v->direction == rvf->dir &&
+ (dist_x[v->direction] >= 0 || (x_diff > dist_x[v->direction] && x_diff <= 0)) &&
+ (dist_x[v->direction] <= 0 || (x_diff < dist_x[v->direction] && x_diff >= 0)) &&
+ (dist_y[v->direction] >= 0 || (y_diff > dist_y[v->direction] && y_diff <= 0)) &&
+ (dist_y[v->direction] <= 0 || (y_diff < dist_y[v->direction] && y_diff >= 0)) ?
+ v : NULL;
+}
+
+static Vehicle* RoadVehFindCloseTo(Vehicle* v, int x, int y, Direction dir)
+{
+ RoadVehFindData rvf;
+ Vehicle *u;
+
+ if (v->u.road.reverse_ctr != 0) return NULL;
+
+ rvf.x = x;
+ rvf.y = y;
+ rvf.dir = dir;
+ rvf.veh = v;
+ u = VehicleFromPos(TileVirtXY(x, y), &rvf, EnumCheckRoadVehClose);
+
+ // This code protects a roadvehicle from being blocked for ever
+ // If more than 1480 / 74 days a road vehicle is blocked, it will
+ // drive just through it. The ultimate backup-code of TTD.
+ // It can be disabled.
+ if (u == NULL) {
+ v->u.road.blocked_ctr = 0;
+ return NULL;
+ }
+
+ if (++v->u.road.blocked_ctr > 1480) return NULL;
+
+ return u;
+}
+
+static void RoadVehArrivesAt(const Vehicle* v, Station* st)
+{
+ if (v->cargo_type == CT_PASSENGERS) {
+ /* Check if station was ever visited before */
+ if (!(st->had_vehicle_of_type & HVOT_BUS)) {
+ uint32 flags;
+
+ st->had_vehicle_of_type |= HVOT_BUS;
+ SetDParam(0, st->index);
+ flags = (v->owner == _local_player) ? NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ARRIVAL_PLAYER, 0) : NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ARRIVAL_OTHER, 0);
+ AddNewsItem(
+ STR_902F_CITIZENS_CELEBRATE_FIRST,
+ flags,
+ v->index,
+ 0);
+ }
+ } else {
+ /* Check if station was ever visited before */
+ if (!(st->had_vehicle_of_type & HVOT_TRUCK)) {
+ uint32 flags;
+
+ st->had_vehicle_of_type |= HVOT_TRUCK;
+ SetDParam(0, st->index);
+ flags = (v->owner == _local_player) ? NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ARRIVAL_PLAYER, 0) : NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ARRIVAL_OTHER, 0);
+ AddNewsItem(
+ STR_9030_CITIZENS_CELEBRATE_FIRST,
+ flags,
+ v->index,
+ 0
+ );
+ }
+ }
+}
+
+static bool RoadVehAccelerate(Vehicle *v)
+{
+ uint spd = v->cur_speed + 1 + (v->u.road.overtaking != 0 ? 1 : 0);
+ byte t;
+
+ // Clamp
+ spd = min(spd, v->max_speed);
+ if (v->u.road.state == 255) spd = min(spd, SetSpeedLimitOnBridge(v));
+
+ //updates statusbar only if speed have changed to save CPU time
+ if (spd != v->cur_speed) {
+ v->cur_speed = spd;
+ if (_patches.vehicle_speed) {
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ }
+ }
+
+ // Decrease somewhat when turning
+ if (!(v->direction & 1)) spd = spd * 3 >> 2;
+
+ if (spd == 0) return false;
+
+ if ((byte)++spd == 0) return true;
+
+ v->progress = (t = v->progress) - (byte)spd;
+
+ return (t < v->progress);
+}
+
+static Direction RoadVehGetNewDirection(const Vehicle* v, int x, int y)
+{
+ static const Direction _roadveh_new_dir[] = {
+ DIR_N , DIR_NW, DIR_W , 0,
+ DIR_NE, DIR_N , DIR_SW, 0,
+ DIR_E , DIR_SE, DIR_S
+ };
+
+ x = x - v->x_pos + 1;
+ y = y - v->y_pos + 1;
+
+ if ((uint)x > 2 || (uint)y > 2) return v->direction;
+ return _roadveh_new_dir[y * 4 + x];
+}
+
+static Direction RoadVehGetSlidingDirection(const Vehicle* v, int x, int y)
+{
+ Direction new = RoadVehGetNewDirection(v, x, y);
+ Direction old = v->direction;
+ DirDiff delta;
+
+ if (new == old) return old;
+ delta = (DirDifference(new, old) > DIRDIFF_REVERSE ? DIRDIFF_45LEFT : DIRDIFF_45RIGHT);
+ return ChangeDir(old, delta);
+}
+
+typedef struct OvertakeData {
+ const Vehicle* u;
+ const Vehicle* v;
+ TileIndex tile;
+ byte tilebits;
+} OvertakeData;
+
+static void* EnumFindVehToOvertake(Vehicle* v, void* data)
+{
+ const OvertakeData* od = data;
+
+ return
+ v->tile == od->tile && v->type == VEH_Road && v != od->u && v != od->v ?
+ v : NULL;
+}
+
+static bool FindRoadVehToOvertake(OvertakeData *od)
+{
+ uint32 bits;
+
+ bits = GetTileTrackStatus(od->tile, TRANSPORT_ROAD) & 0x3F;
+
+ if (!(od->tilebits & bits) || (bits & 0x3C) || (bits & 0x3F3F0000))
+ return true;
+ return VehicleFromPos(od->tile, od, EnumFindVehToOvertake) != NULL;
+}
+
+static void RoadVehCheckOvertake(Vehicle *v, Vehicle *u)
+{
+ OvertakeData od;
+ byte tt;
+
+ od.v = v;
+ od.u = u;
+
+ if (u->max_speed >= v->max_speed &&
+ !(u->vehstatus & VS_STOPPED) &&
+ u->cur_speed != 0) {
+ return;
+ }
+
+ if (v->direction != u->direction || !(v->direction & 1)) return;
+
+ if (v->u.road.state >= 32 || (v->u.road.state & 7) > 1) return;
+
+ tt = GetTileTrackStatus(v->tile, TRANSPORT_ROAD) & 0x3F;
+ if ((tt & 3) == 0) return;
+ if ((tt & 0x3C) != 0) return;
+
+ if (tt == 3) tt = (v->direction & 2) ? 2 : 1;
+ od.tilebits = tt;
+
+ od.tile = v->tile;
+ if (FindRoadVehToOvertake(&od)) return;
+
+ od.tile = v->tile + TileOffsByDiagDir(DirToDiagDir(v->direction));
+ if (FindRoadVehToOvertake(&od)) return;
+
+ if (od.u->cur_speed == 0 || od.u->vehstatus& VS_STOPPED) {
+ v->u.road.overtaking_ctr = 0x11;
+ v->u.road.overtaking = 0x10;
+ } else {
+// if (FindRoadVehToOvertake(&od)) return;
+ v->u.road.overtaking_ctr = 0;
+ v->u.road.overtaking = 0x10;
+ }
+}
+
+static void RoadZPosAffectSpeed(Vehicle *v, byte old_z)
+{
+ if (old_z == v->z_pos) return;
+
+ if (old_z < v->z_pos) {
+ v->cur_speed = v->cur_speed * 232 / 256; // slow down by ~10%
+ } else {
+ uint16 spd = v->cur_speed + 2;
+ if (spd <= v->max_speed) v->cur_speed = spd;
+ }
+}
+
+static int PickRandomBit(uint bits)
+{
+ uint num = 0;
+ uint b = bits;
+ uint i;
+
+ do {
+ if (b & 1) num++;
+ } while (b >>= 1);
+
+ num = RandomRange(num);
+
+ for (i = 0; !(bits & 1) || (int)--num >= 0; bits >>= 1, i++) {}
+ return i;
+}
+
+typedef struct {
+ TileIndex dest;
+ uint maxtracklen;
+ uint mindist;
+} FindRoadToChooseData;
+
+static bool EnumRoadTrackFindDist(TileIndex tile, void* data, int track, uint length, byte* state)
+{
+ FindRoadToChooseData* frd = data;
+ uint dist = DistanceManhattan(tile, frd->dest);
+
+ if (dist <= frd->mindist) {
+ if (dist != frd->mindist || length < frd->maxtracklen) {
+ frd->maxtracklen = length;
+ }
+ frd->mindist = dist;
+ }
+ return false;
+}
+
+static inline NPFFoundTargetData PerfNPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailTypeMask railtypes)
+{
+
+ void* perf = NpfBeginInterval();
+ NPFFoundTargetData ret = NPFRouteToStationOrTile(tile, trackdir, target, type, owner, railtypes);
+ int t = NpfEndInterval(perf);
+ DEBUG(yapf, 4, "[NPFR] %d us - %d rounds - %d open - %d closed -- ", t, 0, _aystar_stats_open_size, _aystar_stats_closed_size);
+ return ret;
+}
+
+// Returns direction to choose
+// or -1 if the direction is currently blocked
+static int RoadFindPathToDest(Vehicle* v, TileIndex tile, DiagDirection enterdir)
+{
+#define return_track(x) {best_track = x; goto found_best_track; }
+
+ uint16 signal;
+ uint bitmask;
+ TileIndex desttile;
+ FindRoadToChooseData frd;
+ int best_track;
+ uint best_dist, best_maxlen;
+ uint i;
+
+ {
+ uint32 r = GetTileTrackStatus(tile, TRANSPORT_ROAD);
+ signal = GB(r, 16, 16);
+ bitmask = GB(r, 0, 16);
+ }
+
+ if (IsTileType(tile, MP_STREET)) {
+ if (GetRoadTileType(tile) == ROAD_TILE_DEPOT && (!IsTileOwner(tile, v->owner) || GetRoadDepotDirection(tile) == enterdir)) {
+ /* Road depot owned by another player or with the wrong orientation */
+ bitmask = 0;
+ }
+ } else if (IsTileType(tile, MP_STATION) && IsRoadStopTile(tile)) {
+ if (!IsTileOwner(tile, v->owner) || GetRoadStopDir(tile) == enterdir) {
+ /* different station owner or wrong orientation */
+ bitmask = 0;
+ } else {
+ /* Our station */
+ RoadStopType rstype = (v->cargo_type == CT_PASSENGERS) ? RS_BUS : RS_TRUCK;
+
+ if (GetRoadStopType(tile) != rstype) {
+ // wrong station type
+ bitmask = 0;
+ } else {
+ // proper station type, check if there is free loading bay
+ const RoadStop *rs = GetRoadStopByTile(tile, rstype);
+ if (rs == NULL || (!_patches.roadveh_queue && GB(rs->status, 0, 2) == 0)) {
+ // station is full and RV queuing is off
+ bitmask = 0;
+ }
+ }
+ }
+ }
+ /* The above lookups should be moved to GetTileTrackStatus in the
+ * future, but that requires more changes to the pathfinder and other
+ * stuff, probably even more arguments to GTTS.
+ */
+
+ /* remove unreachable tracks */
+ bitmask &= _road_veh_fp_ax_and[enterdir];
+ if (bitmask == 0) {
+ /* No reachable tracks, so we'll reverse */
+ return_track(_road_reverse_table[enterdir]);
+ }
+
+ if (v->u.road.reverse_ctr != 0) {
+ /* What happens here?? */
+ v->u.road.reverse_ctr = 0;
+ if (v->tile != tile) {
+ return_track(_road_reverse_table[enterdir]);
+ }
+ }
+
+ desttile = v->dest_tile;
+ if (desttile == 0) {
+ // Pick a random track
+ return_track(PickRandomBit(bitmask));
+ }
+
+ // Only one track to choose between?
+ if (!(KillFirstBit2x64(bitmask))) {
+ return_track(FindFirstBit2x64(bitmask));
+ }
+
+ if (_patches.yapf.road_use_yapf) {
+ Trackdir trackdir = YapfChooseRoadTrack(v, tile, enterdir);
+ if (trackdir != INVALID_TRACKDIR) return_track(trackdir);
+ return_track(PickRandomBit(bitmask));
+ } else if (_patches.new_pathfinding_all) {
+ NPFFindStationOrTileData fstd;
+ NPFFoundTargetData ftd;
+ byte trackdir;
+
+ NPFFillWithOrderData(&fstd, v);
+ trackdir = DiagdirToDiagTrackdir(enterdir);
+ //debug("Finding path. Enterdir: %d, Trackdir: %d", enterdir, trackdir);
+
+ ftd = PerfNPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, &fstd, TRANSPORT_ROAD, v->owner, INVALID_RAILTYPE);
+ if (ftd.best_trackdir == 0xff) {
+ /* We are already at our target. Just do something */
+ //TODO: maybe display error?
+ //TODO: go straight ahead if possible?
+ return_track(FindFirstBit2x64(bitmask));
+ } else {
+ /* If ftd.best_bird_dist is 0, we found our target and ftd.best_trackdir contains
+ the direction we need to take to get there, if ftd.best_bird_dist is not 0,
+ we did not find our target, but ftd.best_trackdir contains the direction leading
+ to the tile closest to our target. */
+ return_track(ftd.best_trackdir);
+ }
+ } else {
+ DiagDirection dir;
+
+ if (IsTileType(desttile, MP_STREET)) {
+ if (GetRoadTileType(desttile) == ROAD_TILE_DEPOT) {
+ dir = GetRoadDepotDirection(desttile);
+ goto do_it;
+ }
+ } else if (IsTileType(desttile, MP_STATION)) {
+ if (IsRoadStop(desttile)) {
+ dir = GetRoadStopDir(desttile);
+do_it:;
+ /* When we are heading for a depot or station, we just
+ * pretend we are heading for the tile in front, we'll
+ * see from there */
+ desttile += TileOffsByDiagDir(dir);
+ if (desttile == tile && bitmask & _road_pf_table_3[dir]) {
+ /* If we are already in front of the
+ * station/depot and we can get in from here,
+ * we enter */
+ return_track(FindFirstBit2x64(bitmask & _road_pf_table_3[dir]));
+ }
+ }
+ }
+ // do pathfind
+ frd.dest = desttile;
+
+ best_track = -1;
+ best_dist = (uint)-1;
+ best_maxlen = (uint)-1;
+ i = 0;
+ do {
+ if (bitmask & 1) {
+ if (best_track == -1) best_track = i; // in case we don't find the path, just pick a track
+ frd.maxtracklen = (uint)-1;
+ frd.mindist = (uint)-1;
+ FollowTrack(tile, 0x2000 | TRANSPORT_ROAD, _road_pf_directions[i], EnumRoadTrackFindDist, NULL, &frd);
+
+ if (frd.mindist < best_dist || (frd.mindist==best_dist && frd.maxtracklen < best_maxlen)) {
+ best_dist = frd.mindist;
+ best_maxlen = frd.maxtracklen;
+ best_track = i;
+ }
+ }
+ } while (++i,(bitmask>>=1) != 0);
+ }
+
+found_best_track:;
+
+ if (HASBIT(signal, best_track)) return -1;
+
+ return best_track;
+}
+
+static uint RoadFindPathToStop(const Vehicle *v, TileIndex tile)
+{
+ uint dist;
+ if (_patches.yapf.road_use_yapf) {
+ // use YAPF
+ dist = YapfRoadVehDistanceToTile(v, tile);
+ } else {
+ // use NPF
+ NPFFindStationOrTileData fstd;
+ byte trackdir = GetVehicleTrackdir(v);
+ assert(trackdir != 0xFF);
+
+ fstd.dest_coords = tile;
+ fstd.station_index = INVALID_STATION; // indicates that the destination is a tile, not a station
+
+ dist = NPFRouteToStationOrTile(v->tile, trackdir, &fstd, TRANSPORT_ROAD, v->owner, INVALID_RAILTYPE).best_path_dist;
+ // change units from NPF_TILE_LENGTH to # of tiles
+ if (dist != UINT_MAX)
+ dist = (dist + NPF_TILE_LENGTH - 1) / NPF_TILE_LENGTH;
+ }
+ return dist;
+}
+
+typedef struct RoadDriveEntry {
+ byte x,y;
+} RoadDriveEntry;
+
+#include "table/roadveh.h"
+
+static const byte _road_veh_data_1[] = {
+ 20, 20, 16, 16, 0, 0, 0, 0,
+ 19, 19, 15, 15, 0, 0, 0, 0,
+ 16, 16, 12, 12, 0, 0, 0, 0,
+ 15, 15, 11, 11
+};
+
+static const byte _roadveh_data_2[4] = { 0, 1, 8, 9 };
+
+static void RoadVehController(Vehicle *v)
+{
+ Direction new_dir;
+ Direction old_dir;
+ RoadDriveEntry rd;
+ int x,y;
+ uint32 r;
+
+ // decrease counters
+ v->tick_counter++;
+ if (v->u.road.reverse_ctr != 0) v->u.road.reverse_ctr--;
+
+ // handle crashed
+ if (v->u.road.crashed_ctr != 0) {
+ RoadVehIsCrashed(v);
+ return;
+ }
+
+ RoadVehCheckTrainCrash(v);
+
+ // road vehicle has broken down?
+ if (v->breakdown_ctr != 0) {
+ if (v->breakdown_ctr <= 2) {
+ HandleBrokenRoadVeh(v);
+ return;
+ }
+ v->breakdown_ctr--;
+ }
+
+ if (v->vehstatus & VS_STOPPED) return;
+
+ ProcessRoadVehOrder(v);
+ HandleRoadVehLoading(v);
+
+ if (v->current_order.type == OT_LOADING) return;
+
+ if (IsRoadVehInDepot(v)) {
+ DiagDirection dir;
+ const RoadDriveEntry* rdp;
+ byte rd2;
+
+ v->cur_speed = 0;
+
+ dir = GetRoadDepotDirection(v->tile);
+ v->direction = DiagDirToDir(dir);
+
+ rd2 = _roadveh_data_2[dir];
+ rdp = _road_drive_data[(_opt.road_side << 4) + rd2];
+
+ x = TileX(v->tile) * TILE_SIZE + (rdp[6].x & 0xF);
+ y = TileY(v->tile) * TILE_SIZE + (rdp[6].y & 0xF);
+
+ if (RoadVehFindCloseTo(v, x, y, v->direction) != NULL) return;
+
+ VehicleServiceInDepot(v);
+
+ StartRoadVehSound(v);
+
+ BeginVehicleMove(v);
+
+ v->vehstatus &= ~VS_HIDDEN;
+ v->u.road.state = rd2;
+ v->u.road.frame = 6;
+
+ v->cur_image = GetRoadVehImage(v, v->direction);
+ UpdateRoadVehDeltaXY(v);
+ SetRoadVehPosition(v,x,y);
+
+ InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
+ return;
+ }
+
+ if (!RoadVehAccelerate(v)) return;
+
+ if (v->u.road.overtaking != 0) {
+ if (++v->u.road.overtaking_ctr >= 35)
+ /* If overtaking just aborts at a random moment, we can have a out-of-bound problem,
+ * if the vehicle started a corner. To protect that, only allow an abort of
+ * overtake if we are on straight road, which are the 8 states below */
+ if (v->u.road.state == 0 || v->u.road.state == 1 ||
+ v->u.road.state == 8 || v->u.road.state == 9 ||
+ v->u.road.state == 16 || v->u.road.state == 17 ||
+ v->u.road.state == 24 || v->u.road.state == 25) {
+ v->u.road.overtaking = 0;
+ }
+ }
+
+ BeginVehicleMove(v);
+
+ if (v->u.road.state == 255) {
+ GetNewVehiclePosResult gp;
+
+ GetNewVehiclePos(v, &gp);
+
+ if (RoadVehFindCloseTo(v, gp.x, gp.y, v->direction) != NULL) {
+ v->cur_speed = 0;
+ return;
+ }
+
+ if ((IsTunnelTile(gp.new_tile) || IsBridgeTile(gp.new_tile)) && VehicleEnterTile(v, gp.new_tile, gp.x, gp.y) & 4) {
+ //new_dir = RoadGetNewDirection(v, gp.x, gp.y)
+ v->cur_image = GetRoadVehImage(v, v->direction);
+ UpdateRoadVehDeltaXY(v);
+ SetRoadVehPosition(v,gp.x,gp.y);
+ return;
+ }
+
+ v->x_pos = gp.x;
+ v->y_pos = gp.y;
+ VehiclePositionChanged(v);
+ if (!(v->vehstatus & VS_HIDDEN)) EndVehicleMove(v);
+ return;
+ }
+
+ rd = _road_drive_data[(v->u.road.state + (_opt.road_side << 4)) ^ v->u.road.overtaking][v->u.road.frame + 1];
+
+// switch to another tile
+ if (rd.x & 0x80) {
+ TileIndex tile = v->tile + TileOffsByDiagDir(rd.x & 3);
+ int dir = RoadFindPathToDest(v, tile, rd.x & 3);
+ uint32 r;
+ Direction newdir;
+ const RoadDriveEntry *rdp;
+
+ if (dir == -1) {
+ v->cur_speed = 0;
+ return;
+ }
+
+again:
+ if ((dir & 7) >= 6) {
+ /* Turning around */
+ tile = v->tile;
+ }
+
+ rdp = _road_drive_data[(dir + (_opt.road_side << 4)) ^ v->u.road.overtaking];
+
+ x = TileX(tile) * TILE_SIZE + rdp[0].x;
+ y = TileY(tile) * TILE_SIZE + rdp[0].y;
+
+ newdir = RoadVehGetSlidingDirection(v, x, y);
+ if (RoadVehFindCloseTo(v, x, y, newdir) != NULL) return;
+
+ r = VehicleEnterTile(v, tile, x, y);
+ if (r & 8) {
+ if (!IsTileType(tile, MP_TUNNELBRIDGE)) {
+ v->cur_speed = 0;
+ return;
+ }
+ dir = _road_reverse_table[rd.x&3];
+ goto again;
+ }
+
+ if (IS_BYTE_INSIDE(v->u.road.state, 0x20, 0x30) && IsTileType(v->tile, MP_STATION)) {
+ if ((dir & 7) >= 6) {
+ v->cur_speed = 0;
+ return;
+ }
+ if (IsRoadStop(v->tile)) {
+ RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile));
+
+ // reached a loading bay, mark it as used and clear the usage bit
+ SETBIT(rs->status, v->u.road.state & 2 ? 1 : 0); // occupied bay
+ CLRBIT(rs->status, 7); // usage bit
+ }
+ }
+
+ if (!(r & 4)) {
+ v->tile = tile;
+ v->u.road.state = (byte)dir;
+ v->u.road.frame = 0;
+ }
+ if (newdir != v->direction) {
+ v->direction = newdir;
+ v->cur_speed -= v->cur_speed >> 2;
+ }
+
+ v->cur_image = GetRoadVehImage(v, newdir);
+ UpdateRoadVehDeltaXY(v);
+ RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y));
+ return;
+ }
+
+ if (rd.x & 0x40) {
+ int dir = RoadFindPathToDest(v, v->tile, rd.x & 3);
+ uint32 r;
+ int tmp;
+ Direction newdir;
+ const RoadDriveEntry *rdp;
+
+ if (dir == -1) {
+ v->cur_speed = 0;
+ return;
+ }
+
+ tmp = (_opt.road_side << 4) + dir;
+ rdp = _road_drive_data[tmp];
+
+ x = TileX(v->tile) * TILE_SIZE + rdp[1].x;
+ y = TileY(v->tile) * TILE_SIZE + rdp[1].y;
+
+ newdir = RoadVehGetSlidingDirection(v, x, y);
+ if (RoadVehFindCloseTo(v, x, y, newdir) != NULL) return;
+
+ r = VehicleEnterTile(v, v->tile, x, y);
+ if (r & 8) {
+ v->cur_speed = 0;
+ return;
+ }
+
+ v->u.road.state = tmp & ~16;
+ v->u.road.frame = 1;
+
+ if (newdir != v->direction) {
+ v->direction = newdir;
+ v->cur_speed -= v->cur_speed >> 2;
+ }
+
+ v->cur_image = GetRoadVehImage(v, newdir);
+ UpdateRoadVehDeltaXY(v);
+ RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y));
+ return;
+ }
+
+ x = (v->x_pos & ~15) + (rd.x & 15);
+ y = (v->y_pos & ~15) + (rd.y & 15);
+
+ new_dir = RoadVehGetSlidingDirection(v, x, y);
+
+ if (!IS_BYTE_INSIDE(v->u.road.state, 0x20, 0x30)) {
+ Vehicle* u = RoadVehFindCloseTo(v, x, y, new_dir);
+
+ if (u != NULL) {
+ if (v->u.road.overtaking == 0) RoadVehCheckOvertake(v, u);
+ return;
+ }
+ }
+
+ old_dir = v->direction;
+ if (new_dir != old_dir) {
+ v->direction = new_dir;
+ v->cur_speed -= (v->cur_speed >> 2);
+ if (old_dir != v->u.road.state) {
+ v->cur_image = GetRoadVehImage(v, new_dir);
+ UpdateRoadVehDeltaXY(v);
+ SetRoadVehPosition(v, v->x_pos, v->y_pos);
+ return;
+ }
+ }
+
+ if (v->u.road.state >= 0x20 &&
+ _road_veh_data_1[v->u.road.state - 0x20 + (_opt.road_side<<4)] == v->u.road.frame) {
+ RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile));
+ Station* st = GetStationByTile(v->tile);
+
+ if (v->current_order.type != OT_LEAVESTATION &&
+ v->current_order.type != OT_GOTO_DEPOT) {
+ Order old_order;
+
+ CLRBIT(rs->status, 7);
+
+ v->last_station_visited = GetStationIndex(v->tile);
+
+ RoadVehArrivesAt(v, st);
+
+ old_order = v->current_order;
+ v->current_order.type = OT_LOADING;
+ v->current_order.flags = 0;
+
+ if (old_order.type == OT_GOTO_STATION &&
+ v->current_order.dest == v->last_station_visited) {
+ v->current_order.flags =
+ (old_order.flags & (OF_FULL_LOAD | OF_UNLOAD | OF_TRANSFER)) | OF_NON_STOP;
+ }
+
+ SET_EXPENSES_TYPE(EXPENSES_ROADVEH_INC);
+ if (LoadUnloadVehicle(v, true)) {
+ InvalidateWindow(WC_ROADVEH_LIST, v->owner);
+ MarkRoadVehDirty(v);
+ }
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ return;
+ }
+
+ if (v->current_order.type != OT_GOTO_DEPOT) {
+ if (HASBIT(rs->status, 7)) {
+ v->cur_speed = 0;
+ return;
+ }
+ v->current_order.type = OT_NOTHING;
+ v->current_order.flags = 0;
+ ClearSlot(v);
+ }
+ SETBIT(rs->status, 7);
+
+ if (rs == v->u.road.slot) {
+ //we have arrived at the correct station
+ ClearSlot(v);
+ } else if (v->u.road.slot != NULL) {
+ //we have arrived at the wrong station
+ //XXX The question is .. what to do? Actually we shouldn't be here
+ //but I guess we need to clear the slot
+ DEBUG(ms, 0, "Vehicle %d (index %d) arrived at wrong stop", v->unitnumber, v->index);
+ if (v->tile != v->dest_tile) {
+ DEBUG(ms, 2, " current tile 0x%X is not destination tile 0x%X. Route problem", v->tile, v->dest_tile);
+ }
+ if (v->dest_tile != v->u.road.slot->xy) {
+ DEBUG(ms, 2, " stop tile 0x%X is not destination tile 0x%X. Multistop desync", v->u.road.slot->xy, v->dest_tile);
+ }
+ if (v->current_order.type != OT_GOTO_STATION) {
+ DEBUG(ms, 2, " current order type (%d) is not OT_GOTO_STATION", v->current_order.type);
+ } else {
+ if (v->current_order.dest != st->index)
+ DEBUG(ms, 2, " current station %d is not target station in current_order.station (%d)",
+ st->index, v->current_order.dest);
+ }
+
+ DEBUG(ms, 2, " force a slot clearing");
+ ClearSlot(v);
+ }
+
+ StartRoadVehSound(v);
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ }
+
+ r = VehicleEnterTile(v, v->tile, x, y);
+ if (r & 8) {
+ v->cur_speed = 0;
+ return;
+ }
+
+ if ((r & 4) == 0) v->u.road.frame++;
+
+ v->cur_image = GetRoadVehImage(v, v->direction);
+ UpdateRoadVehDeltaXY(v);
+ RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y));
+}
+
+static void AgeRoadVehCargo(Vehicle *v)
+{
+ if (_age_cargo_skip_counter != 0) return;
+ if (v->cargo_days != 255) v->cargo_days++;
+}
+
+void RoadVeh_Tick(Vehicle *v)
+{
+ AgeRoadVehCargo(v);
+ RoadVehController(v);
+}
+
+static void CheckIfRoadVehNeedsService(Vehicle *v)
+{
+ const Depot* depot;
+
+ if (_patches.servint_roadveh == 0) return;
+ if (!VehicleNeedsService(v)) return;
+ if (v->vehstatus & VS_STOPPED) return;
+ if (_patches.gotodepot && VehicleHasDepotOrders(v)) return;
+
+ // Don't interfere with a depot visit scheduled by the user, or a
+ // depot visit by the order list.
+ if (v->current_order.type == OT_GOTO_DEPOT &&
+ (v->current_order.flags & (OF_HALT_IN_DEPOT | OF_PART_OF_ORDERS)) != 0)
+ return;
+
+ // If we already got a slot at a stop, use that FIRST, and go to a depot later
+ if (v->u.road.slot != NULL) return;
+
+ if (IsRoadVehInDepot(v)) {
+ VehicleServiceInDepot(v);
+ return;
+ }
+
+ // XXX If we already have a depot order, WHY do we search over and over?
+ depot = FindClosestRoadDepot(v);
+
+ if (depot == NULL || DistanceManhattan(v->tile, depot->xy) > 12) {
+ if (v->current_order.type == OT_GOTO_DEPOT) {
+ v->current_order.type = OT_DUMMY;
+ v->current_order.flags = 0;
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ }
+ return;
+ }
+
+ if (v->current_order.type == OT_GOTO_DEPOT &&
+ v->current_order.flags & OF_NON_STOP &&
+ !CHANCE16(1, 20)) {
+ return;
+ }
+
+ v->current_order.type = OT_GOTO_DEPOT;
+ v->current_order.flags = OF_NON_STOP;
+ v->current_order.dest = depot->index;
+ v->dest_tile = depot->xy;
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+}
+
+void OnNewDay_RoadVeh(Vehicle *v)
+{
+ int32 cost;
+
+ if ((++v->day_counter & 7) == 0) DecreaseVehicleValue(v);
+ if (v->u.road.blocked_ctr == 0) CheckVehicleBreakdown(v);
+
+ AgeVehicle(v);
+ CheckIfRoadVehNeedsService(v);
+
+ CheckOrders(v);
+
+ //Current slot has expired
+ if (v->current_order.type == OT_GOTO_STATION && v->u.road.slot != NULL && v->u.road.slot_age-- == 0) {
+ DEBUG(ms, 3, "Slot expired for vehicle %d (index %d) at stop 0x%X",
+ v->unitnumber, v->index, v->u.road.slot->xy);
+ ClearSlot(v);
+ }
+
+ if (v->vehstatus & VS_STOPPED) return;
+
+ /* update destination */
+ if (v->current_order.type == OT_GOTO_STATION && v->u.road.slot == NULL && !(v->vehstatus & VS_CRASHED)) {
+ Station* st = GetStation(v->current_order.dest);
+ RoadStop* rs = GetPrimaryRoadStop(st, v->cargo_type == CT_PASSENGERS ? RS_BUS : RS_TRUCK);
+ RoadStop* best = NULL;
+
+ if (rs != NULL) {
+ if (DistanceManhattan(v->tile, st->xy) < 16) {
+ uint dist, badness;
+ uint minbadness = UINT_MAX;
+
+ DEBUG(ms, 2, "Attempting to obtain a slot for vehicle %d (index %d) at station %d (0x%X)",
+ v->unitnumber, v->index, st->index, st->xy
+ );
+ /* Now we find the nearest road stop that has a free slot */
+ for (; rs != NULL; rs = rs->next) {
+ dist = RoadFindPathToStop(v, rs->xy);
+ if (dist == UINT_MAX) {
+ DEBUG(ms, 4, " stop 0x%X is unreachable, not treating further", rs->xy);
+ continue;
+ }
+ badness = (rs->num_vehicles + 1) * (rs->num_vehicles + 1) + dist;
+
+ DEBUG(ms, 4, " stop 0x%X has %d vehicle%s waiting", rs->xy, rs->num_vehicles, rs->num_vehicles == 1 ? "":"s");
+ DEBUG(ms, 4, " distance is %u", dist);
+ DEBUG(ms, 4, " badness %u", badness);
+
+ if (badness < minbadness) {
+ best = rs;
+ minbadness = badness;
+ }
+ }
+
+ if (best != NULL) {
+ best->num_vehicles++;
+ DEBUG(ms, 3, "Assigned to stop 0x%X", best->xy);
+
+ v->u.road.slot = best;
+ v->dest_tile = best->xy;
+ v->u.road.slot_age = 14;
+ } else {
+ DEBUG(ms, 3, "Could not find a suitable stop");
+ }
+ } else {
+ DEBUG(ms, 5, "Distance from station too far. Postponing slotting for vehicle %d (index %d) at station %d, (0x%X)",
+ v->unitnumber, v->index, st->index, st->xy);
+ }
+ } else {
+ DEBUG(ms, 4, "No road stop for vehicle %d (index %d) at station %d (0x%X)",
+ v->unitnumber, v->index, st->index, st->xy);
+ }
+ }
+
+ cost = RoadVehInfo(v->engine_type)->running_cost * _price.roadveh_running / 364;
+
+ v->profit_this_year -= cost >> 8;
+
+ SET_EXPENSES_TYPE(EXPENSES_ROADVEH_RUN);
+ SubtractMoneyFromPlayerFract(v->owner, cost);
+
+ InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
+ InvalidateWindowClasses(WC_ROADVEH_LIST);
+}
+
+
+void RoadVehiclesYearlyLoop(void)
+{
+ Vehicle *v;
+
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == VEH_Road) {
+ v->profit_last_year = v->profit_this_year;
+ v->profit_this_year = 0;
+ InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
+ }
+ }
+}
+
+/** Refit a road vehicle to the specified cargo type
+ * @param tile unused
+ * @param p1 Vehicle ID of the vehicle to refit
+ * @param p2 Bitstuffed elements
+ * - p2 = (bit 0-7) - the new cargo type to refit to
+ * - p2 = (bit 8-15) - the new cargo subtype to refit to
+ */
+int32 CmdRefitRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle *v;
+ int32 cost;
+ CargoID new_cid = GB(p2, 0, 8);
+ byte new_subtype = GB(p2, 8, 8);
+ uint16 capacity = CALLBACK_FAILED;
+
+ if (!IsValidVehicleID(p1)) return CMD_ERROR;
+
+ v = GetVehicle(p1);
+
+ if (v->type != VEH_Road || !CheckOwnership(v->owner)) return CMD_ERROR;
+ if (!IsRoadVehInDepotStopped(v)) return_cmd_error(STR_9013_MUST_BE_STOPPED_INSIDE);
+
+ if (new_cid > NUM_CARGO || !CanRefitTo(v->engine_type, new_cid)) return CMD_ERROR;
+
+ SET_EXPENSES_TYPE(EXPENSES_ROADVEH_RUN);
+
+ if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_REFIT_CAPACITY)) {
+ /* Back up the cargo type */
+ CargoID temp_cid = v->cargo_type;
+ byte temp_subtype = v->cargo_subtype;
+ v->cargo_type = new_cid;
+ v->cargo_subtype = new_subtype;
+
+ /* Check the refit capacity callback */
+ capacity = GetVehicleCallback(CBID_VEHICLE_REFIT_CAPACITY, 0, 0, v->engine_type, v);
+
+ /* Restore the original cargo type */
+ v->cargo_type = temp_cid;
+ v->cargo_subtype = temp_subtype;
+ }
+
+ if (capacity == CALLBACK_FAILED) {
+ /* callback failed or not used, use default capacity */
+ const RoadVehicleInfo *rvi = RoadVehInfo(v->engine_type);
+
+ CargoID old_cid = rvi->cargo_type;
+ /* normally, the capacity depends on the cargo type, a vehicle can
+ * carry twice as much mail/goods as normal cargo, and four times as
+ * many passengers
+ */
+ capacity = rvi->capacity;
+ switch (old_cid) {
+ case CT_PASSENGERS: break;
+ case CT_MAIL:
+ case CT_GOODS: capacity *= 2; break;
+ default: capacity *= 4; break;
+ }
+ switch (new_cid) {
+ case CT_PASSENGERS: break;
+ case CT_MAIL:
+ case CT_GOODS: capacity /= 2; break;
+ default: capacity /= 4; break;
+ }
+ }
+ _returned_refit_capacity = capacity;
+
+ cost = 0;
+ if (IsHumanPlayer(v->owner) && new_cid != v->cargo_type) {
+ cost = GetRefitCost(v->engine_type);
+ }
+
+ if (flags & DC_EXEC) {
+ v->cargo_cap = capacity;
+ v->cargo_count = (v->cargo_type == new_cid) ? min(capacity, v->cargo_count) : 0;
+ v->cargo_type = new_cid;
+ v->cargo_subtype = new_subtype;
+ InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
+ InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
+ RebuildVehicleLists();
+ }
+
+ return cost;
+}
diff --git a/src/roadveh_gui.c b/src/roadveh_gui.c
new file mode 100644
index 000000000..ba382b04a
--- /dev/null
+++ b/src/roadveh_gui.c
@@ -0,0 +1,546 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "debug.h"
+#include "functions.h"
+#include "roadveh.h"
+#include "table/sprites.h"
+#include "table/strings.h"
+#include "map.h"
+#include "window.h"
+#include "gui.h"
+#include "gfx.h"
+#include "vehicle.h"
+#include "viewport.h"
+#include "station.h"
+#include "command.h"
+#include "player.h"
+#include "engine.h"
+#include "depot.h"
+#include "vehicle_gui.h"
+#include "newgrf_engine.h"
+#include "date.h"
+
+/**
+ * Draw the purchase info details of road vehicle at a given location.
+ * @param x,y location where to draw the info
+ * @param engine_number the engine of which to draw the info of
+ */
+void DrawRoadVehPurchaseInfo(int x, int y, uint w, EngineID engine_number)
+{
+ const RoadVehicleInfo *rvi = RoadVehInfo(engine_number);
+ const Engine *e = GetEngine(engine_number);
+ bool refittable = (_engine_info[engine_number].refit_mask != 0);
+ YearMonthDay ymd;
+ ConvertDateToYMD(e->intro_date, &ymd);
+
+ /* Purchase cost - Max speed */
+ SetDParam(0, rvi->base_cost * (_price.roadveh_base>>3)>>5);
+ SetDParam(1, rvi->max_speed / 2);
+ DrawString(x, y, STR_PURCHASE_INFO_COST_SPEED, 0);
+ y += 10;
+
+ /* Running cost */
+ SetDParam(0, rvi->running_cost * _price.roadveh_running >> 8);
+ DrawString(x, y, STR_PURCHASE_INFO_RUNNINGCOST, 0);
+ y += 10;
+
+ /* Cargo type + capacity */
+ SetDParam(0, rvi->cargo_type);
+ SetDParam(1, rvi->capacity);
+ SetDParam(2, refittable ? STR_9842_REFITTABLE : STR_EMPTY);
+ DrawString(x, y, STR_PURCHASE_INFO_CAPACITY, 0);
+ y += 10;
+
+ /* Design date - Life length */
+ SetDParam(0, ymd.year);
+ SetDParam(1, e->lifelength);
+ DrawString(x, y, STR_PURCHASE_INFO_DESIGNED_LIFE, 0);
+ y += 10;
+
+ /* Reliability */
+ SetDParam(0, e->reliability * 100 >> 16);
+ DrawString(x, y, STR_PURCHASE_INFO_RELIABILITY, 0);
+ y += 10;
+
+ /* Additional text from NewGRF */
+ y += ShowAdditionalText(x, y, w, engine_number);
+ y += ShowRefitOptionsList(x, y, w, engine_number);
+}
+
+void DrawRoadVehImage(const Vehicle *v, int x, int y, VehicleID selection)
+{
+ PalSpriteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
+ DrawSprite(GetRoadVehImage(v, DIR_W) | pal, x + 14, y + 6);
+
+ if (v->index == selection) {
+ DrawFrameRect(x - 1, y - 1, x + 28, y + 12, 15, FR_BORDERONLY);
+ }
+}
+
+static void RoadVehDetailsWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ const Vehicle *v = GetVehicle(w->window_number);
+ StringID str;
+
+ SetWindowWidgetDisabledState(w, 2, v->owner != _local_player);
+ // disable service-scroller when interval is set to disabled
+ SetWindowWidgetDisabledState(w, 5, !_patches.servint_roadveh);
+ SetWindowWidgetDisabledState(w, 6, !_patches.servint_roadveh);
+
+ SetDParam(0, v->string_id);
+ SetDParam(1, v->unitnumber);
+ DrawWindowWidgets(w);
+
+ /* Draw running cost */
+ {
+ int year = v->age / 366;
+
+ SetDParam(1, year);
+
+ SetDParam(0, (v->age + 365 < v->max_age) ? STR_AGE : STR_AGE_RED);
+ SetDParam(2, v->max_age / 366);
+ SetDParam(3, RoadVehInfo(v->engine_type)->running_cost * _price.roadveh_running >> 8);
+ DrawString(2, 15, STR_900D_AGE_RUNNING_COST_YR, 0);
+ }
+
+ /* Draw max speed */
+ {
+ SetDParam(0, v->max_speed / 2);
+ DrawString(2, 25, STR_900E_MAX_SPEED, 0);
+ }
+
+ /* Draw profit */
+ {
+ SetDParam(0, v->profit_this_year);
+ SetDParam(1, v->profit_last_year);
+ DrawString(2, 35, STR_900F_PROFIT_THIS_YEAR_LAST_YEAR, 0);
+ }
+
+ /* Draw breakdown & reliability */
+ {
+ SetDParam(0, v->reliability * 100 >> 16);
+ SetDParam(1, v->breakdowns_since_last_service);
+ DrawString(2, 45, STR_9010_RELIABILITY_BREAKDOWNS, 0);
+ }
+
+ /* Draw service interval text */
+ {
+ SetDParam(0, v->service_interval);
+ SetDParam(1, v->date_of_last_service);
+ DrawString(13, 90, _patches.servint_ispercent?STR_SERVICING_INTERVAL_PERCENT:STR_883C_SERVICING_INTERVAL_DAYS, 0);
+ }
+
+ DrawRoadVehImage(v, 3, 57, INVALID_VEHICLE);
+
+ SetDParam(0, GetCustomEngineName(v->engine_type));
+ SetDParam(1, v->build_year);
+ SetDParam(2, v->value);
+ DrawString(34, 57, STR_9011_BUILT_VALUE, 0);
+
+ SetDParam(0, v->cargo_type);
+ SetDParam(1, v->cargo_cap);
+ DrawString(34, 67, STR_9012_CAPACITY, 0);
+
+ str = STR_8812_EMPTY;
+ if (v->cargo_count != 0) {
+ SetDParam(0, v->cargo_type);
+ SetDParam(1, v->cargo_count);
+ SetDParam(2, v->cargo_source);
+ str = STR_8813_FROM;
+ }
+ DrawString(34, 78, str, 0);
+ } break;
+
+ case WE_CLICK: {
+ int mod;
+ const Vehicle *v;
+ switch (e->we.click.widget) {
+ case 2: /* rename */
+ v = GetVehicle(w->window_number);
+ SetDParam(0, v->unitnumber);
+ ShowQueryString(v->string_id, STR_902C_NAME_ROAD_VEHICLE, 31, 150, w, CS_ALPHANUMERAL);
+ break;
+
+ case 5: /* increase int */
+ mod = _ctrl_pressed? 5 : 10;
+ goto do_change_service_int;
+ case 6: /* decrease int */
+ mod = _ctrl_pressed? -5 : -10;
+do_change_service_int:
+ v = GetVehicle(w->window_number);
+
+ mod = GetServiceIntervalClamped(mod + v->service_interval);
+ if (mod == v->service_interval) return;
+
+ DoCommandP(v->tile, v->index, mod, NULL, CMD_CHANGE_SERVICE_INT | CMD_MSG(STR_018A_CAN_T_CHANGE_SERVICING));
+ break;
+ }
+ } break;
+
+ case WE_ON_EDIT_TEXT: {
+ if (e->we.edittext.str[0] != '\0') {
+ _cmd_text = e->we.edittext.str;
+ DoCommandP(0, w->window_number, 0, NULL,
+ CMD_NAME_VEHICLE | CMD_MSG(STR_902D_CAN_T_NAME_ROAD_VEHICLE));
+ }
+ } break;
+
+ }
+}
+
+static const Widget _roadveh_details_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 339, 0, 13, STR_900C_DETAILS, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 340, 379, 0, 13, STR_01AA_NAME, STR_902E_NAME_ROAD_VEHICLE},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 379, 14, 55, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 379, 56, 88, 0x0, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 0, 10, 89, 94, STR_0188, STR_884D_INCREASE_SERVICING_INTERVAL},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 0, 10, 95, 100, STR_0189, STR_884E_DECREASE_SERVICING_INTERVAL},
+{ WWT_PANEL, RESIZE_NONE, 14, 11, 379, 89, 100, 0x0, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _roadveh_details_desc = {
+ WDP_AUTO, WDP_AUTO, 380, 101,
+ WC_VEHICLE_DETAILS,WC_VEHICLE_VIEW,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _roadveh_details_widgets,
+ RoadVehDetailsWndProc
+};
+
+static void ShowRoadVehDetailsWindow(const Vehicle *v)
+{
+ Window *w;
+ VehicleID veh = v->index;
+
+ DeleteWindowById(WC_VEHICLE_ORDERS, veh);
+ DeleteWindowById(WC_VEHICLE_DETAILS, veh);
+
+ w = AllocateWindowDescFront(&_roadveh_details_desc, veh);
+ w->caption_color = v->owner;
+}
+
+void CcCloneRoadVeh(bool success, TileIndex tile, uint32 p1, uint32 p2)
+{
+ if (success) ShowRoadVehViewWindow(GetVehicle(_new_vehicle_id));
+}
+
+static void RoadVehViewWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ Vehicle *v = GetVehicle(w->window_number);
+ StringID str;
+ bool is_localplayer = v->owner == _local_player;
+
+ SetWindowWidgetDisabledState(w, 7, !is_localplayer);
+ SetWindowWidgetDisabledState(w, 8, !is_localplayer);
+ SetWindowWidgetDisabledState(w, 11, !is_localplayer);
+ /* Disable refit button if vehicle not refittable */
+ SetWindowWidgetDisabledState(w, 12, !is_localplayer ||
+ _engine_info[v->engine_type].refit_mask == 0);
+
+ /* draw widgets & caption */
+ SetDParam(0, v->string_id);
+ SetDParam(1, v->unitnumber);
+ DrawWindowWidgets(w);
+
+ if (v->u.road.crashed_ctr != 0) {
+ str = STR_8863_CRASHED;
+ } else if (v->breakdown_ctr == 1) {
+ str = STR_885C_BROKEN_DOWN;
+ } else if (v->vehstatus & VS_STOPPED) {
+ str = STR_8861_STOPPED;
+ } else {
+ switch (v->current_order.type) {
+ case OT_GOTO_STATION: {
+ SetDParam(0, v->current_order.dest);
+ SetDParam(1, v->cur_speed / 2);
+ str = STR_HEADING_FOR_STATION + _patches.vehicle_speed;
+ } break;
+
+ case OT_GOTO_DEPOT: {
+ Depot *depot = GetDepot(v->current_order.dest);
+ SetDParam(0, depot->town_index);
+ SetDParam(1, v->cur_speed / 2);
+ if (HASBIT(v->current_order.flags, OFB_HALT_IN_DEPOT) && !HASBIT(v->current_order.flags, OFB_PART_OF_ORDERS)) {
+ str = STR_HEADING_FOR_ROAD_DEPOT + _patches.vehicle_speed;
+ } else {
+ str = STR_HEADING_FOR_ROAD_DEPOT_SERVICE + _patches.vehicle_speed;
+ }
+ } break;
+
+ case OT_LOADING:
+ case OT_LEAVESTATION:
+ str = STR_882F_LOADING_UNLOADING;
+ break;
+
+ default:
+ if (v->num_orders == 0) {
+ str = STR_NO_ORDERS + _patches.vehicle_speed;
+ SetDParam(0, v->cur_speed / 2);
+ } else {
+ str = STR_EMPTY;
+ }
+ break;
+ }
+ }
+
+ /* draw the flag plus orders */
+ DrawSprite(v->vehstatus & VS_STOPPED ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, 2, w->widget[5].top + 1);
+ DrawStringCenteredTruncated(w->widget[5].left + 8, w->widget[5].right, w->widget[5].top + 1, str, 0);
+ DrawWindowViewport(w);
+ } break;
+
+ case WE_CLICK: {
+ const Vehicle *v = GetVehicle(w->window_number);
+
+ switch (e->we.click.widget) {
+ case 5: /* start stop */
+ DoCommandP(v->tile, v->index, 0, NULL, CMD_START_STOP_ROADVEH | CMD_MSG(STR_9015_CAN_T_STOP_START_ROAD_VEHICLE));
+ break;
+ case 6: /* center main view */
+ ScrollMainWindowTo(v->x_pos, v->y_pos);
+ break;
+ case 7: /* goto depot */
+ DoCommandP(v->tile, v->index, _ctrl_pressed ? DEPOT_SERVICE : 0, NULL, CMD_SEND_ROADVEH_TO_DEPOT | CMD_MSG(STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT));
+ break;
+ case 8: /* turn around */
+ DoCommandP(v->tile, v->index, 0, NULL, CMD_TURN_ROADVEH | CMD_MSG(STR_9033_CAN_T_MAKE_VEHICLE_TURN));
+ break;
+ case 9: /* show orders */
+ ShowOrdersWindow(v);
+ break;
+ case 10: /* show details */
+ ShowRoadVehDetailsWindow(v);
+ break;
+ case 11: /* clone vehicle */
+ DoCommandP(v->tile, v->index, _ctrl_pressed ? 1 : 0, CcCloneRoadVeh, CMD_CLONE_VEHICLE | CMD_MSG(STR_9009_CAN_T_BUILD_ROAD_VEHICLE));
+ break;
+ case 12: /* Refit vehicle */
+ ShowVehicleRefitWindow(v, INVALID_VEH_ORDER_ID);
+ break;
+ }
+ } break;
+
+ case WE_RESIZE:
+ w->viewport->width += e->we.sizing.diff.x;
+ w->viewport->height += e->we.sizing.diff.y;
+ w->viewport->virtual_width += e->we.sizing.diff.x;
+ w->viewport->virtual_height += e->we.sizing.diff.y;
+ break;
+
+ case WE_DESTROY:
+ DeleteWindowById(WC_VEHICLE_REFIT, w->window_number);
+ DeleteWindowById(WC_VEHICLE_ORDERS, w->window_number);
+ DeleteWindowById(WC_VEHICLE_DETAILS, w->window_number);
+ break;
+
+ case WE_MOUSELOOP: {
+ const Vehicle *v = GetVehicle(w->window_number);
+ bool rv_stopped = IsRoadVehInDepotStopped(v);
+
+ /* Widget 7 (send to depot) must be hidden if the truck/bus is already stopped in depot.
+ * Widget 11 (clone) should then be shown, since cloning is allowed only while in depot and stopped.
+ * This sytem allows to have two buttons, on top of each other.
+ * The same system applies to widget 8 and 12, force turn around and refit. */
+ if (rv_stopped != IsWindowWidgetHidden(w, 7) || rv_stopped == IsWindowWidgetHidden(w, 11)) {
+ SetWindowWidgetHiddenState(w, 7, rv_stopped); // send to depot
+ SetWindowWidgetHiddenState(w, 8, rv_stopped); // force turn around
+ SetWindowWidgetHiddenState(w, 11, !rv_stopped); // clone
+ SetWindowWidgetHiddenState(w, 12, !rv_stopped); // refit
+ SetWindowDirty(w);
+ }
+ }
+ }
+}
+
+static const Widget _roadveh_view_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW },
+{ WWT_CAPTION, RESIZE_RIGHT, 14, 11, 237, 0, 13, STR_9002, STR_018C_WINDOW_TITLE_DRAG_THIS },
+{ WWT_STICKYBOX, RESIZE_LR, 14, 238, 249, 0, 13, 0x0, STR_STICKY_BUTTON },
+{ WWT_PANEL, RESIZE_RB, 14, 0, 231, 14, 103, 0x0, STR_NULL },
+{ WWT_INSET, RESIZE_RB, 14, 2, 229, 16, 101, 0x0, STR_NULL },
+{ WWT_PUSHBTN, RESIZE_RTB, 14, 0, 237, 104, 115, 0x0, STR_901C_CURRENT_VEHICLE_ACTION },
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 232, 249, 14, 31, SPR_CENTRE_VIEW_VEHICLE, STR_901E_CENTER_MAIN_VIEW_ON_VEHICLE },
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 232, 249, 32, 49, SPR_SEND_ROADVEH_TODEPOT,STR_901F_SEND_VEHICLE_TO_DEPOT },
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 232, 249, 50, 67, SPR_FORCE_VEHICLE_TURN, STR_9020_FORCE_VEHICLE_TO_TURN_AROUND },
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 232, 249, 68, 85, SPR_SHOW_ORDERS, STR_901D_SHOW_VEHICLE_S_ORDERS },
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 232, 249, 86, 103, SPR_SHOW_VEHICLE_DETAILS,STR_9021_SHOW_ROAD_VEHICLE_DETAILS },
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 232, 249, 32, 49, SPR_CLONE_ROADVEH, STR_CLONE_ROAD_VEHICLE_INFO },
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 232, 249, 50, 67, SPR_REFIT_VEHICLE, STR_REFIT_ROAD_VEHICLE_TO_CARRY },
+{ WWT_PANEL, RESIZE_LRB, 14, 232, 249, 104, 103, 0x0, STR_NULL },
+{ WWT_RESIZEBOX, RESIZE_LRTB, 14, 238, 249, 104, 115, 0x0, STR_NULL },
+{ WIDGETS_END }
+};
+
+static const WindowDesc _roadveh_view_desc = {
+ WDP_AUTO, WDP_AUTO, 250, 116,
+ WC_VEHICLE_VIEW,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
+ _roadveh_view_widgets,
+ RoadVehViewWndProc,
+};
+
+void ShowRoadVehViewWindow(const Vehicle *v)
+{
+ Window *w = AllocateWindowDescFront(&_roadveh_view_desc, v->index);
+
+ if (w != NULL) {
+ w->caption_color = v->owner;
+ AssignWindowViewport(w, 3, 17, 0xE2, 0x54, w->window_number | (1 << 31), 0);
+ }
+}
+
+
+static void DrawNewRoadVehWindow(Window *w)
+{
+ EngineID selected_id;
+ EngineID e;
+ uint count;
+ int pos;
+ int sel;
+ int y;
+
+ SetWindowWidgetDisabledState(w, 5, w->window_number == 0);
+
+ count = 0;
+ for (e = ROAD_ENGINES_INDEX; e < ROAD_ENGINES_INDEX + NUM_ROAD_ENGINES; e++) {
+ if (HASBIT(GetEngine(e)->player_avail, _local_player)) count++;
+ }
+ SetVScrollCount(w, count);
+
+ DrawWindowWidgets(w);
+
+ y = 15;
+ sel = WP(w,buildvehicle_d).sel_index;
+ pos = w->vscroll.pos;
+ selected_id = INVALID_ENGINE;
+ for (e = ROAD_ENGINES_INDEX; e < ROAD_ENGINES_INDEX + NUM_ROAD_ENGINES; e++) {
+ if (!HASBIT(GetEngine(e)->player_avail, _local_player)) continue;
+ if (sel == 0) selected_id = e;
+ if (IS_INT_INSIDE(--pos, -w->vscroll.cap, 0)) {
+ DrawString(60, y + 2, GetCustomEngineName(e), sel == 0 ? 0xC : 0x10);
+ DrawRoadVehEngine(30, y + 6, e, GetEnginePalette(e, _local_player));
+ y += 14;
+ }
+ sel--;
+ }
+
+ WP(w,buildvehicle_d).sel_engine = selected_id;
+ if (selected_id != INVALID_ENGINE) {
+ const Widget *wi = &w->widget[4];
+ DrawRoadVehPurchaseInfo(2, wi->top + 1, wi->right - wi->left - 2, selected_id);
+ }
+}
+
+void CcBuildRoadVeh(bool success, TileIndex tile, uint32 p1, uint32 p2)
+{
+ const Vehicle *v;
+
+ if (!success) return;
+
+ v = GetVehicle(_new_vehicle_id);
+ if (v->tile == _backup_orders_tile) {
+ _backup_orders_tile = 0;
+ RestoreVehicleOrders(v, _backup_orders_data);
+ }
+ ShowRoadVehViewWindow(v);
+}
+
+static void NewRoadVehWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT:
+ DrawNewRoadVehWindow(w);
+ break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 2: { /* listbox */
+ uint i = (e->we.click.pt.y - 14) / 14;
+ if (i < w->vscroll.cap) {
+ WP(w,buildvehicle_d).sel_index = i + w->vscroll.pos;
+ SetWindowDirty(w);
+ }
+ } break;
+
+ case 5: { /* build */
+ EngineID sel_eng = WP(w,buildvehicle_d).sel_engine;
+ if (sel_eng != INVALID_ENGINE)
+ DoCommandP(w->window_number, sel_eng, 0, CcBuildRoadVeh, CMD_BUILD_ROAD_VEH | CMD_MSG(STR_9009_CAN_T_BUILD_ROAD_VEHICLE));
+ } break;
+
+ case 6: { /* rename */
+ EngineID sel_eng = WP(w,buildvehicle_d).sel_engine;
+ if (sel_eng != INVALID_ENGINE) {
+ WP(w,buildvehicle_d).rename_engine = sel_eng;
+ ShowQueryString(GetCustomEngineName(sel_eng), STR_9036_RENAME_ROAD_VEHICLE_TYPE, 31, 160, w, CS_ALPHANUMERAL);
+ }
+ } break;
+ }
+ break;
+
+ case WE_ON_EDIT_TEXT:
+ if (e->we.edittext.str[0] != '\0') {
+ _cmd_text = e->we.edittext.str;
+ DoCommandP(0, WP(w, buildvehicle_d).rename_engine, 0, NULL,
+ CMD_RENAME_ENGINE | CMD_MSG(STR_9037_CAN_T_RENAME_ROAD_VEHICLE));
+ }
+ break;
+
+ case WE_RESIZE: {
+ if (e->we.sizing.diff.y == 0) break;
+
+ w->vscroll.cap += e->we.sizing.diff.y / 14;
+ w->widget[2].data = (w->vscroll.cap << 8) + 1;
+ } break;
+
+ }
+}
+
+static const Widget _new_road_veh_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 247, 0, 13, STR_9006_NEW_ROAD_VEHICLES, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_MATRIX, RESIZE_BOTTOM, 14, 0, 235, 14, 125, 0x801, STR_9026_ROAD_VEHICLE_SELECTION},
+{ WWT_SCROLLBAR, RESIZE_BOTTOM, 14, 236, 247, 14, 125, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WWT_PANEL, RESIZE_TB, 14, 0, 247, 126, 217, 0x0, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 117, 218, 229, STR_9007_BUILD_VEHICLE, STR_9027_BUILD_THE_HIGHLIGHTED_ROAD},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 118, 235, 218, 229, STR_9034_RENAME, STR_9035_RENAME_ROAD_VEHICLE_TYPE},
+{ WWT_RESIZEBOX, RESIZE_TB, 14, 236, 247, 218, 229, 0x0, STR_RESIZE_BUTTON},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _new_road_veh_desc = {
+ WDP_AUTO, WDP_AUTO, 248, 230,
+ WC_BUILD_VEHICLE,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
+ _new_road_veh_widgets,
+ NewRoadVehWndProc
+};
+
+void ShowBuildRoadVehWindow(TileIndex tile)
+{
+ Window *w;
+
+ DeleteWindowById(WC_BUILD_VEHICLE, tile);
+
+ w = AllocateWindowDescFront(&_new_road_veh_desc, tile);
+ w->vscroll.cap = 8;
+ w->widget[2].data = (w->vscroll.cap << 8) + 1;
+
+ w->resize.step_height = 14;
+ w->resize.height = w->height - 14 * 4; /* Minimum of 4 vehicles in the display */
+
+ if (tile != 0) {
+ w->caption_color = GetTileOwner(tile);
+ } else {
+ w->caption_color = _local_player;
+ }
+}
+
+
diff --git a/src/saveload.c b/src/saveload.c
new file mode 100644
index 000000000..75396aeee
--- /dev/null
+++ b/src/saveload.c
@@ -0,0 +1,1686 @@
+/* $Id$ */
+
+/** @file
+ * All actions handling saving and loading goes on in this file. The general actions
+ * are as follows for saving a game (loading is analogous):
+ * <ol>
+ * <li>initialize the writer by creating a temporary memory-buffer for it
+ * <li>go through all to-be saved elements, each 'chunk' (ChunkHandler) prefixed by a label
+ * <li>use their description array (SaveLoad) to know what elements to save and in what version
+ * of the game it was active (used when loading)
+ * <li>write all data byte-by-byte to the temporary buffer so it is endian-safe
+ * <li>when the buffer is full; flush it to the output (eg save to file) (_sl.buf, _sl.bufp, _sl.bufe)
+ * <li>repeat this until everything is done, and flush any remaining output to file
+ * </ol>
+ * @see ChunkHandler
+ * @see SaveLoad
+ */
+#include "stdafx.h"
+#include "openttd.h"
+#include "debug.h"
+#include "functions.h"
+#include "hal.h"
+#include "vehicle.h"
+#include "station.h"
+#include "thread.h"
+#include "town.h"
+#include "player.h"
+#include "saveload.h"
+#include "network/network.h"
+#include "variables.h"
+#include <setjmp.h>
+
+const uint16 SAVEGAME_VERSION = 43;
+uint16 _sl_version; /// the major savegame version identifier
+byte _sl_minor_version; /// the minor savegame version, DO NOT USE!
+
+typedef void WriterProc(uint len);
+typedef uint ReaderProc(void);
+
+/** The saveload struct, containing reader-writer functions, bufffer, version, etc. */
+static struct {
+ bool save; /// are we doing a save or a load atm. True when saving
+ byte need_length; /// ???
+ byte block_mode; /// ???
+ bool error; /// did an error occur or not
+
+ int obj_len; /// the length of the current object we are busy with
+ int array_index, last_array_index; /// in the case of an array, the current and last positions
+
+ uint32 offs_base; /// the offset in number of bytes since we started writing data (eg uncompressed savegame size)
+
+ WriterProc *write_bytes; /// savegame writer function
+ ReaderProc *read_bytes; /// savegame loader function
+
+ const ChunkHandler* const *chs; /// the chunk of data that is being processed atm (vehicles, signs, etc.)
+ const SaveLoad* const *includes; /// the internal layouf of the given chunk
+
+ /** When saving/loading savegames, they are always saved to a temporary memory-place
+ * to be flushed to file (save) or to final place (load) when full. */
+ byte *bufp, *bufe; /// bufp(ointer) gives the current position in the buffer bufe(nd) gives the end of the buffer
+
+ // these 3 may be used by compressor/decompressors.
+ byte *buf; /// pointer to temporary memory to read/write, initialized by SaveLoadFormat->initread/write
+ byte *buf_ori; /// pointer to the original memory location of buf, used to free it afterwards
+ uint bufsize; /// the size of the temporary memory *buf
+ FILE *fh; /// the file from which is read or written to
+
+ void (*excpt_uninit)(void); /// the function to execute on any encountered error
+ const char *excpt_msg; /// the error message
+ jmp_buf excpt; /// @todo used to jump to "exception handler"; really ugly
+} _sl;
+
+
+enum NeedLengthValues {NL_NONE = 0, NL_WANTLENGTH = 1, NL_CALCLENGTH = 2};
+
+/**
+ * Fill the input buffer by reading from the file with the given reader
+ */
+static void SlReadFill(void)
+{
+ uint len = _sl.read_bytes();
+ assert(len != 0);
+
+ _sl.bufp = _sl.buf;
+ _sl.bufe = _sl.buf + len;
+ _sl.offs_base += len;
+}
+
+static inline uint32 SlGetOffs(void) {return _sl.offs_base - (_sl.bufe - _sl.bufp);}
+
+/** Return the size in bytes of a certain type of normal/atomic variable
+ * as it appears in memory. @see VarTypes
+ * @param conv @VarType type of variable that is used for calculating the size
+ * @return Return the size of this type in bytes */
+static inline byte SlCalcConvMemLen(VarType conv)
+{
+ static const byte conv_mem_size[] = {1, 1, 1, 2, 2, 4, 4, 8, 8, 0};
+ byte length = GB(conv, 4, 4);
+ assert(length < lengthof(conv_mem_size));
+ return conv_mem_size[length];
+}
+
+/** Return the size in bytes of a certain type of normal/atomic variable
+ * as it appears in a saved game. @see VarTypes
+ * @param conv @VarType type of variable that is used for calculating the size
+ * @return Return the size of this type in bytes */
+static inline byte SlCalcConvFileLen(VarType conv)
+{
+ static const byte conv_file_size[] = {1, 1, 2, 2, 4, 4, 8, 8, 2};
+ byte length = GB(conv, 0, 4);
+ assert(length < lengthof(conv_file_size));
+ return conv_file_size[length];
+}
+
+/* Return the size in bytes of a reference (pointer) */
+static inline size_t SlCalcRefLen(void) {return 2;}
+
+/** Flush the output buffer by writing to disk with the given reader.
+ * If the buffer pointer has not yet been set up, set it up now. Usually
+ * only called when the buffer is full, or there is no more data to be processed
+ */
+static void SlWriteFill(void)
+{
+ // flush the buffer to disk (the writer)
+ if (_sl.bufp != NULL) {
+ uint len = _sl.bufp - _sl.buf;
+ _sl.offs_base += len;
+ if (len) _sl.write_bytes(len);
+ }
+
+ /* All the data from the buffer has been written away, rewind to the beginning
+ * to start reading in more data */
+ _sl.bufp = _sl.buf;
+ _sl.bufe = _sl.buf + _sl.bufsize;
+}
+
+/** Error handler, calls longjmp to simulate an exception.
+ * @todo this was used to have a central place to handle errors, but it is
+ * pretty ugly, and seriously interferes with any multithreaded approaches */
+static void NORETURN SlError(const char *msg)
+{
+ _sl.excpt_msg = msg;
+ longjmp(_sl.excpt, 0);
+}
+
+/** Read in a single byte from file. If the temporary buffer is full,
+ * flush it to its final destination
+ * @return return the read byte from file
+ */
+static inline byte SlReadByteInternal(void)
+{
+ if (_sl.bufp == _sl.bufe) SlReadFill();
+ return *_sl.bufp++;
+}
+
+/** Wrapper for SlReadByteInternal */
+byte SlReadByte(void) {return SlReadByteInternal();}
+
+/** Write away a single byte from memory. If the temporary buffer is full,
+ * flush it to its destination (file)
+ * @param b the byte that is currently written
+ */
+static inline void SlWriteByteInternal(byte b)
+{
+ if (_sl.bufp == _sl.bufe) SlWriteFill();
+ *_sl.bufp++ = b;
+}
+
+/** Wrapper for SlWriteByteInternal */
+void SlWriteByte(byte b) {SlWriteByteInternal(b);}
+
+static inline int SlReadUint16(void)
+{
+ int x = SlReadByte() << 8;
+ return x | SlReadByte();
+}
+
+static inline uint32 SlReadUint32(void)
+{
+ uint32 x = SlReadUint16() << 16;
+ return x | SlReadUint16();
+}
+
+static inline uint64 SlReadUint64(void)
+{
+ uint32 x = SlReadUint32();
+ uint32 y = SlReadUint32();
+ return (uint64)x << 32 | y;
+}
+
+static inline void SlWriteUint16(uint16 v)
+{
+ SlWriteByte(GB(v, 8, 8));
+ SlWriteByte(GB(v, 0, 8));
+}
+
+static inline void SlWriteUint32(uint32 v)
+{
+ SlWriteUint16(GB(v, 16, 16));
+ SlWriteUint16(GB(v, 0, 16));
+}
+
+static inline void SlWriteUint64(uint64 x)
+{
+ SlWriteUint32((uint32)(x >> 32));
+ SlWriteUint32((uint32)x);
+}
+
+/**
+ * Read in the header descriptor of an object or an array.
+ * If the highest bit is set (7), then the index is bigger than 127
+ * elements, so use the next byte to read in the real value.
+ * The actual value is then both bytes added with the first shifted
+ * 8 bits to the left, and dropping the highest bit (which only indicated a big index).
+ * x = ((x & 0x7F) << 8) + SlReadByte();
+ * @return Return the value of the index
+ */
+static uint SlReadSimpleGamma(void)
+{
+ uint i = SlReadByte();
+ if (HASBIT(i, 7)) {
+ i &= ~0x80;
+ if (HASBIT(i, 6)) {
+ i &= ~0x40;
+ if (HASBIT(i, 5)) {
+ i &= ~0x20;
+ if (HASBIT(i, 4))
+ SlError("Unsupported gamma");
+ i = (i << 8) | SlReadByte();
+ }
+ i = (i << 8) | SlReadByte();
+ }
+ i = (i << 8) | SlReadByte();
+ }
+ return i;
+}
+
+/**
+ * Write the header descriptor of an object or an array.
+ * If the element is bigger than 127, use 2 bytes for saving
+ * and use the highest byte of the first written one as a notice
+ * that the length consists of 2 bytes, etc.. like this:
+ * 0xxxxxxx
+ * 10xxxxxx xxxxxxxx
+ * 110xxxxx xxxxxxxx xxxxxxxx
+ * 1110xxxx xxxxxxxx xxxxxxxx xxxxxxxx
+ * @param i Index being written
+ */
+
+static void SlWriteSimpleGamma(uint i)
+{
+ if (i >= (1 << 7)) {
+ if (i >= (1 << 14)) {
+ if (i >= (1 << 21)) {
+ assert(i < (1 << 28));
+ SlWriteByte((byte)0xE0 | (i>>24));
+ SlWriteByte((byte)(i>>16));
+ } else {
+ SlWriteByte((byte)0xC0 | (i>>16));
+ }
+ SlWriteByte((byte)(i>>8));
+ } else {
+ SlWriteByte((byte)(0x80 | (i>>8)));
+ }
+ }
+ SlWriteByte(i);
+}
+
+/** Return how many bytes used to encode a gamma value */
+static inline uint SlGetGammaLength(uint i) {
+ return 1 + (i >= (1 << 7)) + (i >= (1 << 14)) + (i >= (1 << 21));
+}
+
+static inline uint SlReadSparseIndex(void) {return SlReadSimpleGamma();}
+static inline void SlWriteSparseIndex(uint index) {SlWriteSimpleGamma(index);}
+
+static inline uint SlReadArrayLength(void) {return SlReadSimpleGamma();}
+static inline void SlWriteArrayLength(uint length) {SlWriteSimpleGamma(length);}
+static inline uint SlGetArrayLength(uint length) {return SlGetGammaLength(length);}
+
+void SlSetArrayIndex(uint index)
+{
+ _sl.need_length = NL_WANTLENGTH;
+ _sl.array_index = index;
+}
+
+/**
+ * Iterate through the elements of an array and read the whole thing
+ * @return The index of the object, or -1 if we have reached the end of current block
+ */
+int SlIterateArray(void)
+{
+ int index;
+ static uint32 next_offs;
+
+ /* After reading in the whole array inside the loop
+ * we must have read in all the data, so we must be at end of current block. */
+ assert(next_offs == 0 || SlGetOffs() == next_offs);
+
+ while (true) {
+ uint length = SlReadArrayLength();
+ if (length == 0) {
+ next_offs = 0;
+ return -1;
+ }
+
+ _sl.obj_len = --length;
+ next_offs = SlGetOffs() + length;
+
+ switch (_sl.block_mode) {
+ case CH_SPARSE_ARRAY: index = (int)SlReadSparseIndex(); break;
+ case CH_ARRAY: index = _sl.array_index++; break;
+ default:
+ DEBUG(sl, 0, "SlIterateArray error");
+ return -1; // error
+ }
+
+ if (length != 0) return index;
+ }
+}
+
+/**
+ * Sets the length of either a RIFF object or the number of items in an array.
+ * This lets us load an object or an array of arbitrary size
+ * @param length The length of the sought object/array
+ */
+void SlSetLength(size_t length)
+{
+ assert(_sl.save);
+
+ switch (_sl.need_length) {
+ case NL_WANTLENGTH:
+ _sl.need_length = NL_NONE;
+ switch (_sl.block_mode) {
+ case CH_RIFF:
+ // Ugly encoding of >16M RIFF chunks
+ // The lower 24 bits are normal
+ // The uppermost 4 bits are bits 24:27
+ assert(length < (1<<28));
+ SlWriteUint32((length & 0xFFFFFF) | ((length >> 24) << 28));
+ break;
+ case CH_ARRAY:
+ assert(_sl.last_array_index <= _sl.array_index);
+ while (++_sl.last_array_index <= _sl.array_index)
+ SlWriteArrayLength(1);
+ SlWriteArrayLength(length + 1);
+ break;
+ case CH_SPARSE_ARRAY:
+ SlWriteArrayLength(length + 1 + SlGetArrayLength(_sl.array_index)); // Also include length of sparse index.
+ SlWriteSparseIndex(_sl.array_index);
+ break;
+ default: NOT_REACHED();
+ } break;
+ case NL_CALCLENGTH:
+ _sl.obj_len += length;
+ break;
+ }
+}
+
+/**
+ * Save/Load bytes. These do not need to be converted to Little/Big Endian
+ * so directly write them or read them to/from file
+ * @param ptr The source or destination of the object being manipulated
+ * @param length number of bytes this fast CopyBytes lasts
+ */
+static void SlCopyBytes(void *ptr, size_t length)
+{
+ byte *p = (byte*)ptr;
+
+ if (_sl.save) {
+ for (; length != 0; length--) {SlWriteByteInternal(*p++);}
+ } else {
+ for (; length != 0; length--) {*p++ = SlReadByteInternal();}
+ }
+}
+
+/** Read in bytes from the file/data structure but don't do
+ * anything with them, discarding them in effect
+ * @param length The amount of bytes that is being treated this way
+ */
+static inline void SlSkipBytes(size_t length)
+{
+ for (; length != 0; length--) SlReadByte();
+}
+
+/* Get the length of the current object */
+uint SlGetFieldLength(void) {return _sl.obj_len;}
+
+/** Return a signed-long version of the value of a setting
+ * @param ptr pointer to the variable
+ * @param conv type of variable, can be a non-clean
+ * type, eg one with other flags because it is parsed
+ * @return returns the value of the pointer-setting */
+int64 ReadValue(const void *ptr, VarType conv)
+{
+ switch (GetVarMemType(conv)) {
+ case SLE_VAR_BL: return (*(bool*)ptr != 0);
+ case SLE_VAR_I8: return *(int8* )ptr;
+ case SLE_VAR_U8: return *(byte* )ptr;
+ case SLE_VAR_I16: return *(int16* )ptr;
+ case SLE_VAR_U16: return *(uint16*)ptr;
+ case SLE_VAR_I32: return *(int32* )ptr;
+ case SLE_VAR_U32: return *(uint32*)ptr;
+ case SLE_VAR_I64: return *(int64* )ptr;
+ case SLE_VAR_U64: return *(uint64*)ptr;
+ case SLE_VAR_NULL:return 0;
+ default: NOT_REACHED();
+ }
+
+ /* useless, but avoids compiler warning this way */
+ return 0;
+}
+
+/** Write the value of a setting
+ * @param ptr pointer to the variable
+ * @param conv type of variable, can be a non-clean type, eg
+ * with other flags. It is parsed upon read
+ * @param var the new value being given to the variable */
+void WriteValue(void *ptr, VarType conv, int64 val)
+{
+ switch (GetVarMemType(conv)) {
+ case SLE_VAR_BL: *(bool *)ptr = (val != 0); break;
+ case SLE_VAR_I8: *(int8 *)ptr = val; break;
+ case SLE_VAR_U8: *(byte *)ptr = val; break;
+ case SLE_VAR_I16: *(int16 *)ptr = val; break;
+ case SLE_VAR_U16: *(uint16*)ptr = val; break;
+ case SLE_VAR_I32: *(int32 *)ptr = val; break;
+ case SLE_VAR_U32: *(uint32*)ptr = val; break;
+ case SLE_VAR_I64: *(int64 *)ptr = val; break;
+ case SLE_VAR_U64: *(uint64*)ptr = val; break;
+ case SLE_VAR_NULL: break;
+ default: NOT_REACHED();
+ }
+}
+
+/**
+ * Handle all conversion and typechecking of variables here.
+ * In the case of saving, read in the actual value from the struct
+ * and then write them to file, endian safely. Loading a value
+ * goes exactly the opposite way
+ * @param ptr The object being filled/read
+ * @param conv @VarType type of the current element of the struct
+ */
+static void SlSaveLoadConv(void *ptr, VarType conv)
+{
+ int64 x = 0;
+
+ if (_sl.save) { /* SAVE values */
+ /* Read a value from the struct. These ARE endian safe. */
+ x = ReadValue(ptr, conv);
+
+ /* Write the value to the file and check if its value is in the desired range */
+ switch (GetVarFileType(conv)) {
+ case SLE_FILE_I8: assert(x >= -128 && x <= 127); SlWriteByte(x);break;
+ case SLE_FILE_U8: assert(x >= 0 && x <= 255); SlWriteByte(x);break;
+ case SLE_FILE_I16:assert(x >= -32768 && x <= 32767); SlWriteUint16(x);break;
+ case SLE_FILE_STRINGID:
+ case SLE_FILE_U16:assert(x >= 0 && x <= 65535); SlWriteUint16(x);break;
+ case SLE_FILE_I32:
+ case SLE_FILE_U32: SlWriteUint32((uint32)x);break;
+ case SLE_FILE_I64:
+ case SLE_FILE_U64: SlWriteUint64(x);break;
+ default: NOT_REACHED();
+ }
+ } else { /* LOAD values */
+
+ /* Read a value from the file */
+ switch (GetVarFileType(conv)) {
+ case SLE_FILE_I8: x = (int8 )SlReadByte(); break;
+ case SLE_FILE_U8: x = (byte )SlReadByte(); break;
+ case SLE_FILE_I16: x = (int16 )SlReadUint16(); break;
+ case SLE_FILE_U16: x = (uint16)SlReadUint16(); break;
+ case SLE_FILE_I32: x = (int32 )SlReadUint32(); break;
+ case SLE_FILE_U32: x = (uint32)SlReadUint32(); break;
+ case SLE_FILE_I64: x = (int64 )SlReadUint64(); break;
+ case SLE_FILE_U64: x = (uint64)SlReadUint64(); break;
+ case SLE_FILE_STRINGID: x = RemapOldStringID((uint16)SlReadUint16()); break;
+ default: NOT_REACHED();
+ }
+
+ /* Write The value to the struct. These ARE endian safe. */
+ WriteValue(ptr, conv, x);
+ }
+}
+
+/** Calculate the net length of a string. This is in almost all cases
+ * just strlen(), but if the string is not properly terminated, we'll
+ * resort to the maximum length of the buffer.
+ * @param ptr pointer to the stringbuffer
+ * @param length maximum length of the string (buffer). If -1 we don't care
+ * about a maximum length, but take string length as it is.
+ * @return return the net length of the string */
+static inline size_t SlCalcNetStringLen(const char *ptr, size_t length)
+{
+ return minu(strlen(ptr), length - 1);
+}
+
+/** Calculate the gross length of the string that it
+ * will occupy in the savegame. This includes the real length, returned
+ * by SlCalcNetStringLen and the length that the index will occupy.
+ * @param ptr pointer to the stringbuffer
+ * @param length maximum length of the string (buffer size, etc.)
+ * @return return the gross length of the string */
+static inline size_t SlCalcStringLen(const void *ptr, size_t length, VarType conv)
+{
+ size_t len;
+ const char *str;
+
+ switch (GetVarMemType(conv)) {
+ default: NOT_REACHED();
+ case SLE_VAR_STR:
+ case SLE_VAR_STRQ:
+ str = *(const char**)ptr;
+ len = -1;
+ break;
+ case SLE_VAR_STRB:
+ case SLE_VAR_STRBQ:
+ str = (const char*)ptr;
+ len = length;
+ break;
+ }
+
+ len = SlCalcNetStringLen(str, len);
+ return len + SlGetArrayLength(len); // also include the length of the index
+}
+
+/**
+ * Save/Load a string.
+ * @param ptr the string being manipulated
+ * @param the length of the string (full length)
+ * @param conv must be SLE_FILE_STRING */
+static void SlString(void *ptr, size_t length, VarType conv)
+{
+ size_t len;
+
+ if (_sl.save) { /* SAVE string */
+ switch (GetVarMemType(conv)) {
+ default: NOT_REACHED();
+ case SLE_VAR_STRB:
+ case SLE_VAR_STRBQ:
+ len = SlCalcNetStringLen(ptr, length);
+ break;
+ case SLE_VAR_STR:
+ case SLE_VAR_STRQ:
+ ptr = *(char**)ptr;
+ len = SlCalcNetStringLen(ptr, -1);
+ break;
+ }
+
+ SlWriteArrayLength(len);
+ SlCopyBytes(ptr, len);
+ } else { /* LOAD string */
+ len = SlReadArrayLength();
+
+ switch (GetVarMemType(conv)) {
+ default: NOT_REACHED();
+ case SLE_VAR_STRB:
+ case SLE_VAR_STRBQ:
+ if (len >= length) {
+ DEBUG(sl, 1, "String length in savegame is bigger than buffer, truncating");
+ SlCopyBytes(ptr, length);
+ SlSkipBytes(len - length);
+ len = length - 1;
+ } else {
+ SlCopyBytes(ptr, len);
+ }
+ break;
+ case SLE_VAR_STR:
+ case SLE_VAR_STRQ: /* Malloc'd string, free previous incarnation, and allocate */
+ free(*(char**)ptr);
+ *(char**)ptr = malloc(len + 1); // terminating '\0'
+ ptr = *(char**)ptr;
+ SlCopyBytes(ptr, len);
+ break;
+ }
+
+ ((char*)ptr)[len] = '\0'; // properly terminate the string
+ }
+}
+
+/**
+ * Return the size in bytes of a certain type of atomic array
+ * @param length The length of the array counted in elements
+ * @param conv @VarType type of the variable that is used in calculating the size
+ */
+static inline size_t SlCalcArrayLen(uint length, VarType conv)
+{
+ return SlCalcConvFileLen(conv) * length;
+}
+
+/**
+ * Save/Load an array.
+ * @param array The array being manipulated
+ * @param length The length of the array in elements
+ * @param conv @VarType type of the atomic array (int, byte, uint64, etc.)
+ */
+void SlArray(void *array, uint length, VarType conv)
+{
+ // Automatically calculate the length?
+ if (_sl.need_length != NL_NONE) {
+ SlSetLength(SlCalcArrayLen(length, conv));
+ // Determine length only?
+ if (_sl.need_length == NL_CALCLENGTH) return;
+ }
+
+ /* NOTICE - handle some buggy stuff, in really old versions everything was saved
+ * as a byte-type. So detect this, and adjust array size accordingly */
+ if (!_sl.save && _sl_version == 0) {
+ if (conv == SLE_INT16 || conv == SLE_UINT16 || conv == SLE_STRINGID ||
+ conv == SLE_INT32 || conv == SLE_UINT32) {
+ length *= SlCalcConvFileLen(conv);
+ conv = SLE_INT8;
+ }
+ }
+
+ /* If the size of elements is 1 byte both in file and memory, no special
+ * conversion is needed, use specialized copy-copy function to speed up things */
+ if (conv == SLE_INT8 || conv == SLE_UINT8) {
+ SlCopyBytes(array, length);
+ } else {
+ byte *a = (byte*)array;
+ byte mem_size = SlCalcConvMemLen(conv);
+
+ for (; length != 0; length --) {
+ SlSaveLoadConv(a, conv);
+ a += mem_size; // get size
+ }
+ }
+}
+
+/* Are we going to save this object or not? */
+static inline bool SlIsObjectValidInSavegame(const SaveLoad *sld)
+{
+ if (_sl_version < sld->version_from || _sl_version > sld->version_to) return false;
+ if (sld->conv & SLF_SAVE_NO) return false;
+
+ return true;
+}
+
+/** Are we going to load this variable when loading a savegame or not?
+ * @note If the variable is skipped it is skipped in the savegame
+ * bytestream itself as well, so there is no need to skip it somewhere else */
+static inline bool SlSkipVariableOnLoad(const SaveLoad *sld)
+{
+ if ((sld->conv & SLF_NETWORK_NO) && !_sl.save && _networking && !_network_server) {
+ SlSkipBytes(SlCalcConvMemLen(sld->conv) * sld->length);
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Calculate the size of an object.
+ * @param sld The @SaveLoad description of the object so we know how to manipulate it
+ */
+static size_t SlCalcObjLength(const void *object, const SaveLoad *sld)
+{
+ size_t length = 0;
+
+ // Need to determine the length and write a length tag.
+ for (; sld->cmd != SL_END; sld++) {
+ length += SlCalcObjMemberLength(object, sld);
+ }
+ return length;
+}
+
+size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld)
+{
+ assert(_sl.save);
+
+ switch (sld->cmd) {
+ case SL_VAR:
+ case SL_REF:
+ case SL_ARR:
+ case SL_STR:
+ /* CONDITIONAL saveload types depend on the savegame version */
+ if (!SlIsObjectValidInSavegame(sld)) break;
+
+ switch (sld->cmd) {
+ case SL_VAR: return SlCalcConvFileLen(sld->conv);
+ case SL_REF: return SlCalcRefLen();
+ case SL_ARR: return SlCalcArrayLen(sld->length, sld->conv);
+ case SL_STR: return SlCalcStringLen(GetVariableAddress(object, sld), sld->length, sld->conv);
+ default: NOT_REACHED();
+ }
+ break;
+ case SL_WRITEBYTE: return 1; // a byte is logically of size 1
+ case SL_INCLUDE: return SlCalcObjLength(object, _sl.includes[sld->version_from]);
+ default: NOT_REACHED();
+ }
+ return 0;
+}
+
+
+static uint ReferenceToInt(const void* obj, SLRefType rt);
+static void* IntToReference(uint index, SLRefType rt);
+
+
+bool SlObjectMember(void *ptr, const SaveLoad *sld)
+{
+ VarType conv = GB(sld->conv, 0, 8);
+ switch (sld->cmd) {
+ case SL_VAR:
+ case SL_REF:
+ case SL_ARR:
+ case SL_STR:
+ /* CONDITIONAL saveload types depend on the savegame version */
+ if (!SlIsObjectValidInSavegame(sld)) return false;
+ if (SlSkipVariableOnLoad(sld)) return false;
+
+ switch (sld->cmd) {
+ case SL_VAR: SlSaveLoadConv(ptr, conv); break;
+ case SL_REF: /* Reference variable, translate */
+ /// @todo XXX - another artificial limitof 65K elements of pointers?
+ if (_sl.save) { // XXX - read/write pointer as uint16? What is with higher indeces?
+ SlWriteUint16(ReferenceToInt(*(void**)ptr, conv));
+ } else {
+ *(void**)ptr = IntToReference(SlReadUint16(), conv);
+ }
+ break;
+ case SL_ARR: SlArray(ptr, sld->length, conv); break;
+ case SL_STR: SlString(ptr, sld->length, conv); break;
+ default: NOT_REACHED();
+ }
+ break;
+
+ /* SL_WRITEBYTE translates a value of a variable to another one upon
+ * saving or loading.
+ * XXX - variable renaming abuse
+ * game_value: the value of the variable ingame is abused by sld->version_from
+ * file_value: the value of the variable in the savegame is abused by sld->version_to */
+ case SL_WRITEBYTE:
+ if (_sl.save) {
+ SlWriteByte(sld->version_to);
+ } else {
+ *(byte*)ptr = sld->version_from;
+ }
+ break;
+
+ /* SL_INCLUDE loads common code for a type
+ * XXX - variable renaming abuse
+ * include_index: common code to include from _desc_includes[], abused by sld->version_from */
+ case SL_INCLUDE:
+ SlObject(ptr, _sl.includes[sld->version_from]);
+ break;
+ default: NOT_REACHED();
+ }
+ return true;
+}
+
+/**
+ * Main SaveLoad function.
+ * @param object The object that is being saved or loaded
+ * @param sld The @SaveLoad description of the object so we know how to manipulate it
+ */
+void SlObject(void *object, const SaveLoad *sld)
+{
+ // Automatically calculate the length?
+ if (_sl.need_length != NL_NONE) {
+ SlSetLength(SlCalcObjLength(object, sld));
+ if (_sl.need_length == NL_CALCLENGTH) return;
+ }
+
+ for (; sld->cmd != SL_END; sld++) {
+ void *ptr = GetVariableAddress(object, sld);
+ SlObjectMember(ptr, sld);
+ }
+}
+
+/**
+ * Save or Load (a list of) global variables
+ * @param desc The global variable that is being loaded or saved
+ */
+void SlGlobList(const SaveLoadGlobVarList *sldg)
+{
+ if (_sl.need_length != NL_NONE) {
+ SlSetLength(SlCalcObjLength(NULL, (const SaveLoad*)sldg));
+ if (_sl.need_length == NL_CALCLENGTH) return;
+ }
+
+ for (; sldg->cmd != SL_END; sldg++) {
+ SlObjectMember(sldg->address, (const SaveLoad*)sldg);
+ }
+}
+
+/**
+ * Do something of which I have no idea what it is :P
+ * @param proc The callback procedure that is called
+ * @param arg The variable that will be used for the callback procedure
+ */
+void SlAutolength(AutolengthProc *proc, void *arg)
+{
+ uint32 offs;
+
+ assert(_sl.save);
+
+ // Tell it to calculate the length
+ _sl.need_length = NL_CALCLENGTH;
+ _sl.obj_len = 0;
+ proc(arg);
+
+ // Setup length
+ _sl.need_length = NL_WANTLENGTH;
+ SlSetLength(_sl.obj_len);
+
+ offs = SlGetOffs() + _sl.obj_len;
+
+ // And write the stuff
+ proc(arg);
+
+ assert(offs == SlGetOffs());
+}
+
+/**
+ * Load a chunk of data (eg vehicles, stations, etc.)
+ * @param ch The chunkhandler that will be used for the operation
+ */
+static void SlLoadChunk(const ChunkHandler *ch)
+{
+ byte m = SlReadByte();
+ size_t len;
+ uint32 endoffs;
+
+ _sl.block_mode = m;
+ _sl.obj_len = 0;
+
+ switch (m) {
+ case CH_ARRAY:
+ _sl.array_index = 0;
+ ch->load_proc();
+ break;
+ case CH_SPARSE_ARRAY:
+ ch->load_proc();
+ break;
+ default:
+ if ((m & 0xF) == CH_RIFF) {
+ // Read length
+ len = (SlReadByte() << 16) | ((m >> 4) << 24);
+ len += SlReadUint16();
+ _sl.obj_len = len;
+ endoffs = SlGetOffs() + len;
+ ch->load_proc();
+ assert(SlGetOffs() == endoffs);
+ } else {
+ SlError("Invalid chunk type");
+ }
+ break;
+ }
+}
+
+/* Stub Chunk handlers to only calculate length and do nothing else */
+static ChunkSaveLoadProc *_tmp_proc_1;
+static inline void SlStubSaveProc2(void *arg) {_tmp_proc_1();}
+static void SlStubSaveProc(void) {SlAutolength(SlStubSaveProc2, NULL);}
+
+/** Save a chunk of data (eg. vehicles, stations, etc.). Each chunk is
+ * prefixed by an ID identifying it, followed by data, and terminator where appropiate
+ * @param ch The chunkhandler that will be used for the operation
+ */
+static void SlSaveChunk(const ChunkHandler *ch)
+{
+ ChunkSaveLoadProc *proc = ch->save_proc;
+
+ SlWriteUint32(ch->id);
+ DEBUG(sl, 2, "Saving chunk %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
+
+ if (ch->flags & CH_AUTO_LENGTH) {
+ // Need to calculate the length. Solve that by calling SlAutoLength in the save_proc.
+ _tmp_proc_1 = proc;
+ proc = SlStubSaveProc;
+ }
+
+ _sl.block_mode = ch->flags & CH_TYPE_MASK;
+ switch (ch->flags & CH_TYPE_MASK) {
+ case CH_RIFF:
+ _sl.need_length = NL_WANTLENGTH;
+ proc();
+ break;
+ case CH_ARRAY:
+ _sl.last_array_index = 0;
+ SlWriteByte(CH_ARRAY);
+ proc();
+ SlWriteArrayLength(0); // Terminate arrays
+ break;
+ case CH_SPARSE_ARRAY:
+ SlWriteByte(CH_SPARSE_ARRAY);
+ proc();
+ SlWriteArrayLength(0); // Terminate arrays
+ break;
+ default: NOT_REACHED();
+ }
+}
+
+/** Save all chunks */
+static void SlSaveChunks(void)
+{
+ const ChunkHandler *ch;
+ const ChunkHandler* const *chsc;
+ uint p;
+
+ for (p = 0; p != CH_NUM_PRI_LEVELS; p++) {
+ for (chsc = _sl.chs; (ch = *chsc++) != NULL;) {
+ while (true) {
+ if (((ch->flags >> CH_PRI_SHL) & (CH_NUM_PRI_LEVELS - 1)) == p)
+ SlSaveChunk(ch);
+ if (ch->flags & CH_LAST)
+ break;
+ ch++;
+ }
+ }
+ }
+
+ // Terminator
+ SlWriteUint32(0);
+}
+
+/** Find the ChunkHandler that will be used for processing the found
+ * chunk in the savegame or in memory
+ * @param id the chunk in question
+ * @return returns the appropiate chunkhandler
+ */
+static const ChunkHandler *SlFindChunkHandler(uint32 id)
+{
+ const ChunkHandler *ch;
+ const ChunkHandler *const *chsc;
+ for (chsc = _sl.chs; (ch=*chsc++) != NULL;) {
+ for (;;) {
+ if (ch->id == id) return ch;
+ if (ch->flags & CH_LAST) break;
+ ch++;
+ }
+ }
+ return NULL;
+}
+
+/** Load all chunks */
+static void SlLoadChunks(void)
+{
+ uint32 id;
+ const ChunkHandler *ch;
+
+ for (id = SlReadUint32(); id != 0; id = SlReadUint32()) {
+ DEBUG(sl, 2, "Loading chunk %c%c%c%c", id >> 24, id >> 16, id >> 8, id);
+
+ ch = SlFindChunkHandler(id);
+ if (ch == NULL) SlError("found unknown tag in savegame (sync error)");
+ SlLoadChunk(ch);
+ }
+}
+
+//*******************************************
+//********** START OF LZO CODE **************
+//*******************************************
+#define LZO_SIZE 8192
+
+#include "minilzo.h"
+
+static uint ReadLZO(void)
+{
+ byte out[LZO_SIZE + LZO_SIZE / 64 + 16 + 3 + 8];
+ uint32 tmp[2];
+ uint32 size;
+ uint len;
+
+ // Read header
+ if (fread(tmp, sizeof(tmp), 1, _sl.fh) != 1) SlError("file read failed");
+
+ // Check if size is bad
+ ((uint32*)out)[0] = size = tmp[1];
+
+ if (_sl_version != 0) {
+ tmp[0] = TO_BE32(tmp[0]);
+ size = TO_BE32(size);
+ }
+
+ if (size >= sizeof(out)) SlError("inconsistent size");
+
+ // Read block
+ if (fread(out + sizeof(uint32), size, 1, _sl.fh) != 1) SlError("file read failed");
+
+ // Verify checksum
+ if (tmp[0] != lzo_adler32(0, out, size + sizeof(uint32))) SlError("bad checksum");
+
+ // Decompress
+ lzo1x_decompress(out + sizeof(uint32)*1, size, _sl.buf, &len, NULL);
+ return len;
+}
+
+// p contains the pointer to the buffer, len contains the pointer to the length.
+// len bytes will be written, p and l will be updated to reflect the next buffer.
+static void WriteLZO(uint size)
+{
+ byte out[LZO_SIZE + LZO_SIZE / 64 + 16 + 3 + 8];
+ byte wrkmem[sizeof(byte*)*4096];
+ uint outlen;
+
+ lzo1x_1_compress(_sl.buf, size, out + sizeof(uint32)*2, &outlen, wrkmem);
+ ((uint32*)out)[1] = TO_BE32(outlen);
+ ((uint32*)out)[0] = TO_BE32(lzo_adler32(0, out + sizeof(uint32), outlen + sizeof(uint32)));
+ if (fwrite(out, outlen + sizeof(uint32)*2, 1, _sl.fh) != 1) SlError("file write failed");
+}
+
+static bool InitLZO(void)
+{
+ _sl.bufsize = LZO_SIZE;
+ _sl.buf = _sl.buf_ori = (byte*)malloc(LZO_SIZE);
+ return true;
+}
+
+static void UninitLZO(void)
+{
+ free(_sl.buf_ori);
+}
+
+//*********************************************
+//******** START OF NOCOMP CODE (uncompressed)*
+//*********************************************
+static uint ReadNoComp(void)
+{
+ return fread(_sl.buf, 1, LZO_SIZE, _sl.fh);
+}
+
+static void WriteNoComp(uint size)
+{
+ fwrite(_sl.buf, 1, size, _sl.fh);
+}
+
+static bool InitNoComp(void)
+{
+ _sl.bufsize = LZO_SIZE;
+ _sl.buf = _sl.buf_ori =(byte*)malloc(LZO_SIZE);
+ return true;
+}
+
+static void UninitNoComp(void)
+{
+ free(_sl.buf_ori);
+}
+
+//********************************************
+//********** START OF MEMORY CODE (in ram)****
+//********************************************
+
+#include "table/strings.h"
+#include "table/sprites.h"
+#include "gfx.h"
+#include "gui.h"
+
+typedef struct ThreadedSave {
+ uint count;
+ bool ff_state;
+ bool saveinprogress;
+ CursorID cursor;
+} ThreadedSave;
+
+/* A maximum size of of 128K * 500 = 64.000KB savegames */
+STATIC_OLD_POOL(Savegame, byte, 17, 500, NULL, NULL)
+static ThreadedSave _ts;
+
+static bool InitMem(void)
+{
+ _ts.count = 0;
+
+ CleanPool(&_Savegame_pool);
+ AddBlockToPool(&_Savegame_pool);
+
+ /* A block from the pool is a contigious area of memory, so it is safe to write to it sequentially */
+ _sl.bufsize = GetSavegamePoolSize();
+ _sl.buf = GetSavegame(_ts.count);
+ return true;
+}
+
+static void UnInitMem(void)
+{
+ CleanPool(&_Savegame_pool);
+}
+
+static void WriteMem(uint size)
+{
+ _ts.count += size;
+ /* Allocate new block and new buffer-pointer */
+ AddBlockIfNeeded(&_Savegame_pool, _ts.count);
+ _sl.buf = GetSavegame(_ts.count);
+}
+
+//********************************************
+//********** START OF ZLIB CODE **************
+//********************************************
+
+#if defined(WITH_ZLIB)
+#include <zlib.h>
+
+static z_stream _z;
+
+static bool InitReadZlib(void)
+{
+ memset(&_z, 0, sizeof(_z));
+ if (inflateInit(&_z) != Z_OK) return false;
+
+ _sl.bufsize = 4096;
+ _sl.buf = _sl.buf_ori = (byte*)malloc(4096 + 4096); // also contains fread buffer
+ return true;
+}
+
+static uint ReadZlib(void)
+{
+ int r;
+
+ _z.next_out = _sl.buf;
+ _z.avail_out = 4096;
+
+ do {
+ // read more bytes from the file?
+ if (_z.avail_in == 0) {
+ _z.avail_in = fread(_z.next_in = _sl.buf + 4096, 1, 4096, _sl.fh);
+ }
+
+ // inflate the data
+ r = inflate(&_z, 0);
+ if (r == Z_STREAM_END)
+ break;
+
+ if (r != Z_OK)
+ SlError("inflate() failed");
+ } while (_z.avail_out);
+
+ return 4096 - _z.avail_out;
+}
+
+static void UninitReadZlib(void)
+{
+ inflateEnd(&_z);
+ free(_sl.buf_ori);
+}
+
+static bool InitWriteZlib(void)
+{
+ memset(&_z, 0, sizeof(_z));
+ if (deflateInit(&_z, 6) != Z_OK) return false;
+
+ _sl.bufsize = 4096;
+ _sl.buf = _sl.buf_ori = (byte*)malloc(4096); // also contains fread buffer
+ return true;
+}
+
+static void WriteZlibLoop(z_streamp z, byte *p, uint len, int mode)
+{
+ byte buf[1024]; // output buffer
+ int r;
+ uint n;
+ z->next_in = p;
+ z->avail_in = len;
+ do {
+ z->next_out = buf;
+ z->avail_out = sizeof(buf);
+ r = deflate(z, mode);
+ // bytes were emitted?
+ if ((n=sizeof(buf) - z->avail_out) != 0) {
+ if (fwrite(buf, n, 1, _sl.fh) != 1) SlError("file write error");
+ }
+ if (r == Z_STREAM_END)
+ break;
+ if (r != Z_OK) SlError("zlib returned error code");
+ } while (z->avail_in || !z->avail_out);
+}
+
+static void WriteZlib(uint len)
+{
+ WriteZlibLoop(&_z, _sl.buf, len, 0);
+}
+
+static void UninitWriteZlib(void)
+{
+ // flush any pending output.
+ if (_sl.fh) WriteZlibLoop(&_z, NULL, 0, Z_FINISH);
+ deflateEnd(&_z);
+ free(_sl.buf_ori);
+}
+
+#endif /* WITH_ZLIB */
+
+//*******************************************
+//************* END OF CODE *****************
+//*******************************************
+
+// these define the chunks
+extern const ChunkHandler _misc_chunk_handlers[];
+extern const ChunkHandler _setting_chunk_handlers[];
+extern const ChunkHandler _player_chunk_handlers[];
+extern const ChunkHandler _engine_chunk_handlers[];
+extern const ChunkHandler _veh_chunk_handlers[];
+extern const ChunkHandler _waypoint_chunk_handlers[];
+extern const ChunkHandler _depot_chunk_handlers[];
+extern const ChunkHandler _order_chunk_handlers[];
+extern const ChunkHandler _town_chunk_handlers[];
+extern const ChunkHandler _sign_chunk_handlers[];
+extern const ChunkHandler _station_chunk_handlers[];
+extern const ChunkHandler _industry_chunk_handlers[];
+extern const ChunkHandler _economy_chunk_handlers[];
+extern const ChunkHandler _animated_tile_chunk_handlers[];
+extern const ChunkHandler _newgrf_chunk_handlers[];
+
+static const ChunkHandler * const _chunk_handlers[] = {
+ _misc_chunk_handlers,
+ _setting_chunk_handlers,
+ _veh_chunk_handlers,
+ _waypoint_chunk_handlers,
+ _depot_chunk_handlers,
+ _order_chunk_handlers,
+ _industry_chunk_handlers,
+ _economy_chunk_handlers,
+ _engine_chunk_handlers,
+ _town_chunk_handlers,
+ _sign_chunk_handlers,
+ _station_chunk_handlers,
+ _player_chunk_handlers,
+ _animated_tile_chunk_handlers,
+ _newgrf_chunk_handlers,
+ NULL,
+};
+
+// used to include a vehicle desc in another desc.
+extern const SaveLoad _common_veh_desc[];
+static const SaveLoad* const _desc_includes[] = {
+ _common_veh_desc
+};
+
+/**
+ * Pointers cannot be saved to a savegame, so this functions gets
+ * the index of the item, and if not available, it hussles with
+ * pointers (looks really bad :()
+ * Remember that a NULL item has value 0, and all
+ * indeces have +1, so vehicle 0 is saved as index 1.
+ * @param obj The object that we want to get the index of
+ * @param rt @SLRefType type of the object the index is being sought of
+ * @return Return the pointer converted to an index of the type pointed to
+ */
+static uint ReferenceToInt(const void *obj, SLRefType rt)
+{
+ if (obj == NULL) return 0;
+
+ switch (rt) {
+ case REF_VEHICLE_OLD: // Old vehicles we save as new onces
+ case REF_VEHICLE: return ((const Vehicle*)obj)->index + 1;
+ case REF_STATION: return ((const Station*)obj)->index + 1;
+ case REF_TOWN: return ((const Town*)obj)->index + 1;
+ case REF_ORDER: return ((const Order*)obj)->index + 1;
+ case REF_ROADSTOPS: return ((const RoadStop*)obj)->index + 1;
+ case REF_ENGINE_RENEWS: return ((const EngineRenew*)obj)->index + 1;
+ default: NOT_REACHED();
+ }
+
+ return 0; // avoid compiler warning
+}
+
+/**
+ * Pointers cannot be loaded from a savegame, so this function
+ * gets the index from the savegame and returns the appropiate
+ * pointer from the already loaded base.
+ * Remember that an index of 0 is a NULL pointer so all indeces
+ * are +1 so vehicle 0 is saved as 1.
+ * @param index The index that is being converted to a pointer
+ * @param rt @SLRefType type of the object the pointer is sought of
+ * @return Return the index converted to a pointer of any type
+ */
+static void *IntToReference(uint index, SLRefType rt)
+{
+ /* After version 4.3 REF_VEHICLE_OLD is saved as REF_VEHICLE,
+ * and should be loaded like that */
+ if (rt == REF_VEHICLE_OLD && !CheckSavegameVersionOldStyle(4, 4))
+ rt = REF_VEHICLE;
+
+ /* No need to look up NULL pointers, just return immediately */
+ if (rt != REF_VEHICLE_OLD && index == 0)
+ return NULL;
+
+ index--; // correct for the NULL index
+
+ switch (rt) {
+ case REF_ORDER: {
+ if (!AddBlockIfNeeded(&_Order_pool, index))
+ error("Orders: failed loading savegame: too many orders");
+ return GetOrder(index);
+ }
+ case REF_VEHICLE: {
+ if (!AddBlockIfNeeded(&_Vehicle_pool, index))
+ error("Vehicles: failed loading savegame: too many vehicles");
+ return GetVehicle(index);
+ }
+ case REF_STATION: {
+ if (!AddBlockIfNeeded(&_Station_pool, index))
+ error("Stations: failed loading savegame: too many stations");
+ return GetStation(index);
+ }
+ case REF_TOWN: {
+ if (!AddBlockIfNeeded(&_Town_pool, index))
+ error("Towns: failed loading savegame: too many towns");
+ return GetTown(index);
+ }
+ case REF_ROADSTOPS: {
+ if (!AddBlockIfNeeded(&_RoadStop_pool, index))
+ error("RoadStops: failed loading savegame: too many RoadStops");
+ return GetRoadStop(index);
+ }
+ case REF_ENGINE_RENEWS: {
+ if (!AddBlockIfNeeded(&_EngineRenew_pool, index))
+ error("EngineRenews: failed loading savegame: too many EngineRenews");
+ return GetEngineRenew(index);
+ }
+
+ case REF_VEHICLE_OLD: {
+ /* Old vehicles were saved differently:
+ * invalid vehicle was 0xFFFF,
+ * and the index was not - 1.. correct for this */
+ index++;
+ if (index == INVALID_VEHICLE)
+ return NULL;
+
+ if (!AddBlockIfNeeded(&_Vehicle_pool, index))
+ error("Vehicles: failed loading savegame: too many vehicles");
+ return GetVehicle(index);
+ }
+ default: NOT_REACHED();
+ }
+
+ return NULL;
+}
+
+/** The format for a reader/writer type of a savegame */
+typedef struct {
+ const char *name; /// name of the compressor/decompressor (debug-only)
+ uint32 tag; /// the 4-letter tag by which it is identified in the savegame
+
+ bool (*init_read)(void); /// function executed upon initalization of the loader
+ ReaderProc *reader; /// function that loads the data from the file
+ void (*uninit_read)(void); /// function executed when reading is finished
+
+ bool (*init_write)(void); /// function executed upon intialization of the saver
+ WriterProc *writer; /// function that saves the data to the file
+ void (*uninit_write)(void); /// function executed when writing is done
+} SaveLoadFormat;
+
+static const SaveLoadFormat _saveload_formats[] = {
+ {"memory", 0, NULL, NULL, NULL, InitMem, WriteMem, UnInitMem},
+ {"lzo", TO_BE32X('OTTD'), InitLZO, ReadLZO, UninitLZO, InitLZO, WriteLZO, UninitLZO},
+ {"none", TO_BE32X('OTTN'), InitNoComp, ReadNoComp, UninitNoComp, InitNoComp, WriteNoComp, UninitNoComp},
+#if defined(WITH_ZLIB)
+ {"zlib", TO_BE32X('OTTZ'), InitReadZlib, ReadZlib, UninitReadZlib, InitWriteZlib, WriteZlib, UninitWriteZlib},
+#else
+ {"zlib", TO_BE32X('OTTZ'), NULL, NULL, NULL, NULL, NULL, NULL},
+#endif
+};
+
+/**
+ * Return the savegameformat of the game. Whether it was create with ZLIB compression
+ * uncompressed, or another type
+ * @param s Name of the savegame format. If NULL it picks the first available one
+ * @return Pointer to @SaveLoadFormat struct giving all characteristics of this type of savegame
+ */
+static const SaveLoadFormat *GetSavegameFormat(const char *s)
+{
+ const SaveLoadFormat *def = endof(_saveload_formats) - 1;
+
+ // find default savegame format, the highest one with which files can be written
+ while (!def->init_write) def--;
+
+ if (s != NULL && s[0] != '\0') {
+ const SaveLoadFormat *slf;
+ for (slf = &_saveload_formats[0]; slf != endof(_saveload_formats); slf++) {
+ if (slf->init_write != NULL && strcmp(s, slf->name) == 0)
+ return slf;
+ }
+
+ ShowInfoF("Savegame format '%s' is not available. Reverting to '%s'.", s, def->name);
+ }
+ return def;
+}
+
+// actual loader/saver function
+void InitializeGame(int mode, uint size_x, uint size_y);
+extern bool AfterLoadGame(void);
+extern void BeforeSaveGame(void);
+extern bool LoadOldSaveGame(const char *file);
+
+/** Small helper function to close the to be loaded savegame an signal error */
+static inline SaveOrLoadResult AbortSaveLoad(void)
+{
+ if (_sl.fh != NULL) fclose(_sl.fh);
+
+ _sl.fh = NULL;
+ return SL_ERROR;
+}
+
+/** Update the gui accordingly when starting saving
+ * and set locks on saveload. Also turn off fast-forward cause with that
+ * saving takes Aaaaages */
+void SaveFileStart(void)
+{
+ _ts.ff_state = _fast_forward;
+ _fast_forward = false;
+ if (_cursor.sprite == SPR_CURSOR_MOUSE) SetMouseCursor(SPR_CURSOR_ZZZ);
+
+ SendWindowMessage(WC_STATUS_BAR, 0, true, 0, 0);
+ _ts.saveinprogress = true;
+}
+
+/** Update the gui accordingly when saving is done and release locks
+ * on saveload */
+void SaveFileDone(void)
+{
+ _fast_forward = _ts.ff_state;
+ if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE);
+
+ SendWindowMessage(WC_STATUS_BAR, 0, false, 0, 0);
+ _ts.saveinprogress = false;
+}
+
+/** Show a gui message when saving has failed */
+void SaveFileError(void)
+{
+ ShowErrorMessage(STR_4007_GAME_SAVE_FAILED, STR_NULL, 0, 0);
+ SaveFileDone();
+}
+
+static OTTDThread* save_thread;
+
+/** We have written the whole game into memory, _Savegame_pool, now find
+ * and appropiate compressor and start writing to file.
+ */
+static void* SaveFileToDisk(void *arg)
+{
+ const SaveLoadFormat *fmt;
+ uint32 hdr[2];
+
+ /* XXX - Setup setjmp error handler if an error occurs anywhere deep during
+ * loading/saving execute a longjmp() and continue execution here */
+ if (setjmp(_sl.excpt)) {
+ AbortSaveLoad();
+ _sl.excpt_uninit();
+
+ fprintf(stderr, "Save game failed: %s.", _sl.excpt_msg);
+ if (arg != NULL) {
+ OTTD_SendThreadMessage(MSG_OTTD_SAVETHREAD_ERROR);
+ } else {
+ SaveFileError();
+ }
+ return NULL;
+ }
+
+ fmt = GetSavegameFormat(_savegame_format);
+
+ /* We have written our stuff to memory, now write it to file! */
+ hdr[0] = fmt->tag;
+ hdr[1] = TO_BE32(SAVEGAME_VERSION << 16);
+ if (fwrite(hdr, sizeof(hdr), 1, _sl.fh) != 1) SlError("file write failed");
+
+ if (!fmt->init_write()) SlError("cannot initialize compressor");
+
+ {
+ uint i;
+ uint count = 1 << Savegame_POOL_BLOCK_SIZE_BITS;
+
+ assert(_ts.count == _sl.offs_base);
+ for (i = 0; i != _Savegame_pool.current_blocks - 1; i++) {
+ _sl.buf = _Savegame_pool.blocks[i];
+ fmt->writer(count);
+ }
+
+ /* The last block is (almost) always not fully filled, so only write away
+ * as much data as it is in there */
+ _sl.buf = _Savegame_pool.blocks[i];
+ fmt->writer(_ts.count - (i * count));
+ }
+
+ fmt->uninit_write();
+ assert(_ts.count == _sl.offs_base);
+ GetSavegameFormat("memory")->uninit_write(); // clean the memorypool
+ fclose(_sl.fh);
+
+ if (arg != NULL) OTTD_SendThreadMessage(MSG_OTTD_SAVETHREAD_DONE);
+ return NULL;
+}
+
+void WaitTillSaved(void)
+{
+ OTTDJoinThread(save_thread);
+ save_thread = NULL;
+}
+
+/**
+ * Main Save or Load function where the high-level saveload functions are
+ * handled. It opens the savegame, selects format and checks versions
+ * @param filename The name of the savegame being created/loaded
+ * @param mode Save or load. Load can also be a TTD(Patch) game. Use SL_LOAD, SL_OLD_LOAD or SL_SAVE
+ * @return Return the results of the action. SL_OK, SL_ERROR or SL_REINIT ("unload" the game)
+ */
+SaveOrLoadResult SaveOrLoad(const char *filename, int mode)
+{
+ uint32 hdr[2];
+ const SaveLoadFormat *fmt;
+
+ /* An instance of saving is already active, so don't go saving again */
+ if (_ts.saveinprogress && mode == SL_SAVE) {
+ // if not an autosave, but a user action, show error message
+ if (!_do_autosave) ShowErrorMessage(INVALID_STRING_ID, STR_SAVE_STILL_IN_PROGRESS, 0, 0);
+ return SL_OK;
+ }
+ WaitTillSaved();
+
+ /* Load a TTDLX or TTDPatch game */
+ if (mode == SL_OLD_LOAD) {
+ InitializeGame(IG_DATE_RESET, 256, 256); // set a mapsize of 256x256 for TTDPatch games or it might get confused
+ if (!LoadOldSaveGame(filename)) return SL_REINIT;
+ _sl_version = 0;
+ AfterLoadGame();
+ return SL_OK;
+ }
+
+ _sl.fh = (mode == SL_SAVE) ? fopen(filename, "wb") : fopen(filename, "rb");
+ if (_sl.fh == NULL) {
+ DEBUG(sl, 0, "Cannot open savegame '%s' for saving/loading.", filename);
+ return SL_ERROR;
+ }
+
+ _sl.bufe = _sl.bufp = NULL;
+ _sl.offs_base = 0;
+ _sl.save = mode;
+ _sl.includes = _desc_includes;
+ _sl.chs = _chunk_handlers;
+
+ /* XXX - Setup setjmp error handler if an error occurs anywhere deep during
+ * loading/saving execute a longjmp() and continue execution here */
+ if (setjmp(_sl.excpt)) {
+ AbortSaveLoad();
+
+ // deinitialize compressor.
+ _sl.excpt_uninit();
+
+ /* A saver/loader exception!! reinitialize all variables to prevent crash! */
+ if (mode == SL_LOAD) {
+ ShowInfoF("Load game failed: %s.", _sl.excpt_msg);
+ return SL_REINIT;
+ }
+
+ ShowInfoF("Save game failed: %s.", _sl.excpt_msg);
+ return SL_ERROR;
+ }
+
+ /* General tactic is to first save the game to memory, then use an available writer
+ * to write it to file, either in threaded mode if possible, or single-threaded */
+ if (mode == SL_SAVE) { /* SAVE game */
+ fmt = GetSavegameFormat("memory"); // write to memory
+
+ _sl.write_bytes = fmt->writer;
+ _sl.excpt_uninit = fmt->uninit_write;
+ if (!fmt->init_write()) {
+ DEBUG(sl, 0, "Initializing writer '%s' failed.", fmt->name);
+ return AbortSaveLoad();
+ }
+
+ _sl_version = SAVEGAME_VERSION;
+
+ BeforeSaveGame();
+ SlSaveChunks();
+ SlWriteFill(); // flush the save buffer
+
+ SaveFileStart();
+ if (_network_server ||
+ (save_thread = OTTDCreateThread(&SaveFileToDisk, (void*)"")) == NULL) {
+ DEBUG(sl, 1, "Cannot create savegame thread, reverting to single-threaded mode...");
+ SaveFileToDisk(NULL);
+ SaveFileDone();
+ }
+
+ } else { /* LOAD game */
+ assert(mode == SL_LOAD);
+
+ if (fread(hdr, sizeof(hdr), 1, _sl.fh) != 1) {
+ DEBUG(sl, 0, "Cannot read savegame header, aborting");
+ return AbortSaveLoad();
+ }
+
+ // see if we have any loader for this type.
+ for (fmt = _saveload_formats; ; fmt++) {
+ /* No loader found, treat as version 0 and use LZO format */
+ if (fmt == endof(_saveload_formats)) {
+ DEBUG(sl, 0, "Unknown savegame type, trying to load it as the buggy format");
+ rewind(_sl.fh);
+ _sl_version = 0;
+ _sl_minor_version = 0;
+ fmt = _saveload_formats + 1; // LZO
+ break;
+ }
+
+ if (fmt->tag == hdr[0]) {
+ // check version number
+ _sl_version = TO_BE32(hdr[1]) >> 16;
+ /* Minor is not used anymore from version 18.0, but it is still needed
+ * in versions before that (4 cases) which can't be removed easy.
+ * Therefor it is loaded, but never saved (or, it saves a 0 in any scenario).
+ * So never EVER use this minor version again. -- TrueLight -- 22-11-2005 */
+ _sl_minor_version = (TO_BE32(hdr[1]) >> 8) & 0xFF;
+
+ DEBUG(sl, 1, "Loading savegame version %d", _sl_version);
+
+ /* Is the version higher than the current? */
+ if (_sl_version > SAVEGAME_VERSION) {
+ DEBUG(sl, 0, "Savegame version invalid");
+ return AbortSaveLoad();
+ }
+ break;
+ }
+ }
+
+ _sl.read_bytes = fmt->reader;
+ _sl.excpt_uninit = fmt->uninit_read;
+
+ // loader for this savegame type is not implemented?
+ if (fmt->init_read == NULL) {
+ ShowInfoF("Loader for '%s' is not available.", fmt->name);
+ return AbortSaveLoad();
+ }
+
+ if (!fmt->init_read()) {
+ DEBUG(sl, 0, "Initializing loader '%s' failed", fmt->name);
+ return AbortSaveLoad();
+ }
+
+ /* Old maps were hardcoded to 256x256 and thus did not contain
+ * any mapsize information. Pre-initialize to 256x256 to not to
+ * confuse old games */
+ InitializeGame(IG_DATE_RESET, 256, 256);
+
+ SlLoadChunks();
+ fmt->uninit_read();
+ fclose(_sl.fh);
+
+ /* After loading fix up savegame for any internal changes that
+ * might've occured since then. If it fails, load back the old game */
+ if (!AfterLoadGame()) return SL_REINIT;
+ }
+
+ return SL_OK;
+}
+
+/** Do a save when exiting the game (patch option) _patches.autosave_on_exit */
+void DoExitSave(void)
+{
+ char buf[200];
+ snprintf(buf, sizeof(buf), "%s%sexit.sav", _paths.autosave_dir, PATHSEP);
+ SaveOrLoad(buf, SL_SAVE);
+}
+
+#if 0
+/**
+ * Function to get the type of the savegame by looking at the file header.
+ * NOTICE: Not used right now, but could be used if extensions of savegames are garbled
+ * @param file Savegame to be checked
+ * @return SL_OLD_LOAD or SL_LOAD of the file
+ */
+int GetSavegameType(char *file)
+{
+ const SaveLoadFormat *fmt;
+ uint32 hdr;
+ FILE *f;
+ int mode = SL_OLD_LOAD;
+
+ f = fopen(file, "rb");
+ if (fread(&hdr, sizeof(hdr), 1, f) != 1) {
+ DEBUG(sl, 0, "Savegame is obsolete or invalid format");
+ mode = SL_LOAD; // don't try to get filename, just show name as it is written
+ } else {
+ // see if we have any loader for this type.
+ for (fmt = _saveload_formats; fmt != endof(_saveload_formats); fmt++) {
+ if (fmt->tag == hdr) {
+ mode = SL_LOAD; // new type of savegame
+ break;
+ }
+ }
+ }
+
+ fclose(f);
+ return mode;
+}
+#endif
diff --git a/src/saveload.h b/src/saveload.h
new file mode 100644
index 000000000..5d490b35a
--- /dev/null
+++ b/src/saveload.h
@@ -0,0 +1,305 @@
+/* $Id$ */
+
+#ifndef SAVELOAD_H
+#define SAVELOAD_H
+
+typedef enum SaveOrLoadResult {
+ SL_OK = 0, // completed successfully
+ SL_ERROR = 1, // error that was caught before internal structures were modified
+ SL_REINIT = 2, // error that was caught in the middle of updating game state, need to clear it. (can only happen during load)
+} SaveOrLoadResult;
+
+typedef enum SaveOrLoadMode {
+ SL_INVALID = -1,
+ SL_LOAD = 0,
+ SL_SAVE = 1,
+ SL_OLD_LOAD = 2,
+ SL_PNG = 3,
+ SL_BMP = 4,
+} SaveOrLoadMode;
+
+SaveOrLoadResult SaveOrLoad(const char *filename, int mode);
+void WaitTillSaved(void);
+void DoExitSave(void);
+
+
+typedef void ChunkSaveLoadProc(void);
+typedef void AutolengthProc(void *arg);
+
+typedef struct {
+ uint32 id;
+ ChunkSaveLoadProc *save_proc;
+ ChunkSaveLoadProc *load_proc;
+ uint32 flags;
+} ChunkHandler;
+
+typedef struct {
+ byte null;
+} NullStruct;
+
+typedef enum SLRefType {
+ REF_ORDER = 0,
+ REF_VEHICLE = 1,
+ REF_STATION = 2,
+ REF_TOWN = 3,
+ REF_VEHICLE_OLD = 4,
+ REF_ROADSTOPS = 5,
+ REF_ENGINE_RENEWS = 6,
+} SLRefType;
+
+#define SL_MAX_VERSION 255
+
+enum {
+ INC_VEHICLE_COMMON = 0,
+};
+
+enum {
+ CH_RIFF = 0,
+ CH_ARRAY = 1,
+ CH_SPARSE_ARRAY = 2,
+ CH_TYPE_MASK = 3,
+ CH_LAST = 8,
+ CH_AUTO_LENGTH = 16,
+
+ CH_PRI_0 = 0 << 4,
+ CH_PRI_1 = 1 << 4,
+ CH_PRI_2 = 2 << 4,
+ CH_PRI_3 = 3 << 4,
+ CH_PRI_SHL = 4,
+ CH_NUM_PRI_LEVELS = 4,
+};
+
+/** VarTypes is the general bitmasked magic type that tells us
+ * certain characteristics about the variable it refers to. For example
+ * SLE_FILE_* gives the size(type) as it would be in the savegame and
+ * SLE_VAR_* the size(type) as it is in memory during runtime. These are
+ * the first 8 bytes (0-3 SLE_FILE, 4-7 SLE_VAR).
+ * Bytes 8-15 are reserved for various flags as explained below */
+enum VarTypes {
+ /* 4 bytes allocated a maximum of 16 types for NumberType */
+ SLE_FILE_I8 = 0,
+ SLE_FILE_U8 = 1,
+ SLE_FILE_I16 = 2,
+ SLE_FILE_U16 = 3,
+ SLE_FILE_I32 = 4,
+ SLE_FILE_U32 = 5,
+ SLE_FILE_I64 = 6,
+ SLE_FILE_U64 = 7,
+ SLE_FILE_STRINGID = 8, ///< StringID offset into strings-array
+ SLE_FILE_STRING = 9,
+ /* 6 more possible file-primitives */
+
+ /* 4 bytes allocated a maximum of 16 types for NumberType */
+ SLE_VAR_BL = 0 << 4,
+ SLE_VAR_I8 = 1 << 4,
+ SLE_VAR_U8 = 2 << 4,
+ SLE_VAR_I16 = 3 << 4,
+ SLE_VAR_U16 = 4 << 4,
+ SLE_VAR_I32 = 5 << 4,
+ SLE_VAR_U32 = 6 << 4,
+ SLE_VAR_I64 = 7 << 4,
+ SLE_VAR_U64 = 8 << 4,
+ SLE_VAR_NULL = 9 << 4, ///< useful to write zeros in savegame.
+ SLE_VAR_STRB = 10 << 4, ///< string (with pre-allocated buffer)
+ SLE_VAR_STRBQ = 11 << 4, ///< string enclosed in quotes (with pre-allocated buffer)
+ SLE_VAR_STR = 12 << 4, ///< string pointer
+ SLE_VAR_STRQ = 13 << 4, ///< string pointer enclosed in quotes
+ /* 2 more possible memory-primitives */
+
+ /* Shortcut values */
+ SLE_VAR_CHAR = SLE_VAR_I8,
+
+ /* Default combinations of variables. As savegames change, so can variables
+ * and thus it is possible that the saved value and internal size do not
+ * match and you need to specify custom combo. The defaults are listed here */
+ SLE_BOOL = SLE_FILE_I8 | SLE_VAR_BL,
+ SLE_INT8 = SLE_FILE_I8 | SLE_VAR_I8,
+ SLE_UINT8 = SLE_FILE_U8 | SLE_VAR_U8,
+ SLE_INT16 = SLE_FILE_I16 | SLE_VAR_I16,
+ SLE_UINT16 = SLE_FILE_U16 | SLE_VAR_U16,
+ SLE_INT32 = SLE_FILE_I32 | SLE_VAR_I32,
+ SLE_UINT32 = SLE_FILE_U32 | SLE_VAR_U32,
+ SLE_INT64 = SLE_FILE_I64 | SLE_VAR_I64,
+ SLE_UINT64 = SLE_FILE_U64 | SLE_VAR_U64,
+ SLE_CHAR = SLE_FILE_I8 | SLE_VAR_CHAR,
+ SLE_STRINGID = SLE_FILE_STRINGID | SLE_VAR_U16,
+ SLE_STRINGBUF = SLE_FILE_STRING | SLE_VAR_STRB,
+ SLE_STRINGBQUOTE = SLE_FILE_STRING | SLE_VAR_STRBQ,
+ SLE_STRING = SLE_FILE_STRING | SLE_VAR_STR,
+ SLE_STRINGQUOTE = SLE_FILE_STRING | SLE_VAR_STRQ,
+
+ /* Shortcut values */
+ SLE_UINT = SLE_UINT32,
+ SLE_INT = SLE_INT32,
+ SLE_STRB = SLE_STRINGBUF,
+ SLE_STRBQ = SLE_STRINGBQUOTE,
+ SLE_STR = SLE_STRING,
+ SLE_STRQ = SLE_STRINGQUOTE,
+
+ /* 8 bytes allocated for a maximum of 8 flags
+ * Flags directing saving/loading of a variable */
+ SLF_SAVE_NO = 1 << 8, ///< do not save with savegame, basically player-based
+ SLF_CONFIG_NO = 1 << 9, ///< do not save to config file
+ SLF_NETWORK_NO = 1 << 10, ///< do not synchronize over network (but it is saved if SSF_SAVE_NO is not set)
+ /* 5 more possible flags */
+};
+
+typedef uint32 VarType;
+
+enum SaveLoadTypes {
+ SL_VAR = 0,
+ SL_REF = 1,
+ SL_ARR = 2,
+ SL_STR = 3,
+ // non-normal save-load types
+ SL_WRITEBYTE = 8,
+ SL_INCLUDE = 9,
+ SL_END = 15
+};
+
+typedef byte SaveLoadType;
+
+/** SaveLoad type struct. Do NOT use this directly but use the SLE_ macros defined just below! */
+typedef struct SaveLoad {
+ SaveLoadType cmd; ///< the action to take with the saved/loaded type, All types need different action
+ VarType conv; ///< type of the variable to be saved, int
+ uint16 length; ///< (conditional) length of the variable (eg. arrays) (max array size is 65536 elements)
+ uint16 version_from; ///< save/load the variable starting from this savegame version
+ uint16 version_to; ///< save/load the variable until this savegame version
+ /* NOTE: This element either denotes the address of the variable for a global
+ * variable, or the offset within a struct which is then bound to a variable
+ * during runtime. Decision on which one to use is controlled by the function
+ * that is called to save it. address: SlGlobList, offset: SlObject */
+ void *address; ///< address of variable OR offset of variable in the struct (max offset is 65536)
+} SaveLoad;
+
+/* Same as SaveLoad but global variables are used (for better readability); */
+typedef SaveLoad SaveLoadGlobVarList;
+
+/* Simple variables, references (pointers) and arrays */
+#define SLE_GENERAL(cmd, base, variable, type, length, from, to) {cmd, type, length, from, to, (void*)offsetof(base, variable)}
+#define SLE_CONDVAR(base, variable, type, from, to) SLE_GENERAL(SL_VAR, base, variable, type, 0, from, to)
+#define SLE_CONDREF(base, variable, type, from, to) SLE_GENERAL(SL_REF, base, variable, type, 0, from, to)
+#define SLE_CONDARR(base, variable, type, length, from, to) SLE_GENERAL(SL_ARR, base, variable, type, length, from, to)
+#define SLE_CONDSTR(base, variable, type, length, from, to) SLE_GENERAL(SL_STR, base, variable, type, length, from, to)
+
+#define SLE_VAR(base, variable, type) SLE_CONDVAR(base, variable, type, 0, SL_MAX_VERSION)
+#define SLE_REF(base, variable, type) SLE_CONDREF(base, variable, type, 0, SL_MAX_VERSION)
+#define SLE_ARR(base, variable, type, length) SLE_CONDARR(base, variable, type, length, 0, SL_MAX_VERSION)
+#define SLE_STR(base, variable, type, length) SLE_CONDSTR(base, variable, type, length, 0, SL_MAX_VERSION)
+
+#define SLE_CONDNULL(length, from, to) SLE_CONDARR(NullStruct, null, SLE_FILE_U8 | SLE_VAR_NULL | SLF_CONFIG_NO, length, from, to)
+
+/* Translate values ingame to different values in the savegame and vv */
+#define SLE_WRITEBYTE(base, variable, game_value, file_value) SLE_GENERAL(SL_WRITEBYTE, base, variable, 0, 0, game_value, file_value)
+/* Load common code and put it into each struct (currently only for vehicles */
+#define SLE_INCLUDE(base, variable, include_index) SLE_GENERAL(SL_INCLUDE, base, variable, 0, 0, include_index, 0)
+
+/* The same as the ones at the top, only the offset is given directly; used for unions */
+#define SLE_GENERALX(cmd, offset, type, param1, param2) {cmd, type, 0, param1, param2, (void*)(offset)}
+#define SLE_CONDVARX(offset, type, from, to) SLE_GENERALX(SL_VAR, offset, type, from, to)
+#define SLE_CONDREFX(offset, type, from, to) SLE_GENERALX(SL_REF, offset, type, from, to)
+
+#define SLE_VARX(offset, type) SLE_CONDVARX(offset, type, 0, SL_MAX_VERSION)
+#define SLE_REFX(offset, type) SLE_CONDREFX(offset, type, 0, SL_MAX_VERSION)
+
+#define SLE_WRITEBYTEX(offset, something) SLE_GENERALX(SL_WRITEBYTE, offset, 0, something, 0)
+#define SLE_INCLUDEX(offset, type) SLE_GENERALX(SL_INCLUDE, offset, type, 0, SL_MAX_VERSION)
+
+/* End marker */
+#define SLE_END() {SL_END, 0, 0, 0, 0, NULL}
+
+/* Simple variables, references (pointers) and arrays, but for global variables */
+#define SLEG_GENERAL(cmd, variable, type, length, from, to) {cmd, type, length, from, to, (void*)&variable}
+
+#define SLEG_CONDVAR(variable, type, from, to) SLEG_GENERAL(SL_VAR, variable, type, 0, from, to)
+#define SLEG_CONDREF(variable, type, from, to) SLEG_GENERAL(SL_REF, variable, type, 0, from, to)
+#define SLEG_CONDARR(variable, type, length, from, to) SLEG_GENERAL(SL_ARR, variable, type, length, from, to)
+#define SLEG_CONDSTR(variable, type, length, from, to) SLEG_GENERAL(SL_STR, variable, type, length, from, to)
+
+#define SLEG_VAR(variable, type) SLEG_CONDVAR(variable, type, 0, SL_MAX_VERSION)
+#define SLEG_REF(variable, type) SLEG_CONDREF(variable, type, 0, SL_MAX_VERSION)
+#define SLEG_ARR(variable, type) SLEG_CONDARR(variable, type, lengthof(variable), 0, SL_MAX_VERSION)
+#define SLEG_STR(variable, type) SLEG_CONDSTR(variable, type, lengthof(variable), 0, SL_MAX_VERSION)
+
+#define SLEG_CONDNULL(length, from, to) {SL_ARR, SLE_FILE_U8 | SLE_VAR_NULL | SLF_CONFIG_NO, length, from, to, (void*)NULL}
+
+#define SLEG_END() {SL_END, 0, 0, 0, 0, NULL}
+
+/** Checks if the savegame is below major.minor.
+ */
+static inline bool CheckSavegameVersionOldStyle(uint16 major, byte minor)
+{
+ extern uint16 _sl_version;
+ extern byte _sl_minor_version;
+ return (_sl_version < major) || (_sl_version == major && _sl_minor_version < minor);
+}
+
+/** Checks if the savegame is below version.
+ */
+static inline bool CheckSavegameVersion(uint16 version)
+{
+ extern uint16 _sl_version;
+ return _sl_version < version;
+}
+
+/** Checks if some version from/to combination falls within the range of the
+ * active savegame version */
+static inline bool SlIsObjectCurrentlyValid(uint16 version_from, uint16 version_to)
+{
+ extern const uint16 SAVEGAME_VERSION;
+ if (SAVEGAME_VERSION < version_from || SAVEGAME_VERSION > version_to) return false;
+
+ return true;
+}
+
+/* Get the NumberType of a setting. This describes the integer type
+ * as it is represented in memory
+ * @param type VarType holding information about the variable-type
+ * @return return the SLE_VAR_* part of a variable-type description */
+static inline VarType GetVarMemType(VarType type)
+{
+ return type & 0xF0; // GB(type, 4, 4) << 4;
+}
+
+/* Get the FileType of a setting. This describes the integer type
+ * as it is represented in a savegame/file
+ * @param type VarType holding information about the variable-type
+ * @param return the SLE_FILE_* part of a variable-type description */
+static inline VarType GetVarFileType(VarType type)
+{
+ return type & 0xF; // GB(type, 0, 4);
+}
+
+/** Get the address of the variable. Which one to pick depends on the object
+ * pointer. If it is NULL we are dealing with global variables so the address
+ * is taken. If non-null only the offset is stored in the union and we need
+ * to add this to the address of the object */
+static inline void *GetVariableAddress(const void *object, const SaveLoad *sld)
+{
+ return (byte*)object + (ptrdiff_t)sld->address;
+}
+
+int64 ReadValue(const void *ptr, VarType conv);
+void WriteValue(void *ptr, VarType conv, int64 val);
+
+void SlSetArrayIndex(uint index);
+int SlIterateArray(void);
+
+void SlAutolength(AutolengthProc *proc, void *arg);
+uint SlGetFieldLength(void);
+void SlSetLength(size_t length);
+size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld);
+
+byte SlReadByte(void);
+void SlWriteByte(byte b);
+
+void SlGlobList(const SaveLoadGlobVarList *sldg);
+void SlArray(void *array, uint length, VarType conv);
+void SlObject(void *object, const SaveLoad *sld);
+bool SlObjectMember(void *object, const SaveLoad *sld);
+
+void SaveFileStart(void);
+void SaveFileDone(void);
+void SaveFileError(void);
+#endif /* SAVELOAD_H */
diff --git a/src/screenshot.c b/src/screenshot.c
new file mode 100644
index 000000000..5a73fa52a
--- /dev/null
+++ b/src/screenshot.c
@@ -0,0 +1,575 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "debug.h"
+#include "functions.h"
+#include "strings.h"
+#include "table/strings.h"
+#include "gfx.h"
+#include "hal.h"
+#include "viewport.h"
+#include "player.h"
+#include "screenshot.h"
+#include "variables.h"
+#include "date.h"
+
+char _screenshot_format_name[8];
+uint _num_screenshot_formats;
+uint _cur_screenshot_format;
+ScreenshotType current_screenshot_type;
+
+// called by the ScreenShot proc to generate screenshot lines.
+typedef void ScreenshotCallback(void *userdata, Pixel *buf, uint y, uint pitch, uint n);
+typedef bool ScreenshotHandlerProc(const char *name, ScreenshotCallback *callb, void *userdata, uint w, uint h, int pixelformat, const Colour *palette);
+
+typedef struct {
+ const char *name;
+ const char *extension;
+ ScreenshotHandlerProc *proc;
+} ScreenshotFormat;
+
+//************************************************
+//*** SCREENSHOT CODE FOR WINDOWS BITMAP (.BMP)
+//************************************************
+#if defined(_MSC_VER) || defined(__WATCOMC__)
+#pragma pack(push, 1)
+#endif
+
+typedef struct BitmapFileHeader {
+ uint16 type;
+ uint32 size;
+ uint32 reserved;
+ uint32 off_bits;
+} GCC_PACK BitmapFileHeader;
+assert_compile(sizeof(BitmapFileHeader) == 14);
+
+#if defined(_MSC_VER) || defined(__WATCOMC__)
+#pragma pack(pop)
+#endif
+
+typedef struct BitmapInfoHeader {
+ uint32 size;
+ int32 width, height;
+ uint16 planes, bitcount;
+ uint32 compression, sizeimage, xpels, ypels, clrused, clrimp;
+} BitmapInfoHeader;
+assert_compile(sizeof(BitmapInfoHeader) == 40);
+
+typedef struct RgbQuad {
+ byte blue, green, red, reserved;
+} RgbQuad;
+assert_compile(sizeof(RgbQuad) == 4);
+
+// generic .BMP writer
+static bool MakeBmpImage(const char *name, ScreenshotCallback *callb, void *userdata, uint w, uint h, int pixelformat, const Colour *palette)
+{
+ BitmapFileHeader bfh;
+ BitmapInfoHeader bih;
+ RgbQuad rq[256];
+ Pixel *buff;
+ FILE *f;
+ uint i, padw;
+ uint n, maxlines;
+
+ // only implemented for 8bit images so far.
+ if (pixelformat != 8)
+ return false;
+
+ f = fopen(name, "wb");
+ if (f == NULL) return false;
+
+ // each scanline must be aligned on a 32bit boundary
+ padw = ALIGN(w, 4);
+
+ // setup the file header
+ bfh.type = TO_LE16('MB');
+ bfh.size = TO_LE32(sizeof(bfh) + sizeof(bih) + sizeof(RgbQuad) * 256 + padw * h);
+ bfh.reserved = 0;
+ bfh.off_bits = TO_LE32(sizeof(bfh) + sizeof(bih) + sizeof(RgbQuad) * 256);
+
+ // setup the info header
+ bih.size = TO_LE32(sizeof(BitmapInfoHeader));
+ bih.width = TO_LE32(w);
+ bih.height = TO_LE32(h);
+ bih.planes = TO_LE16(1);
+ bih.bitcount = TO_LE16(8);
+ bih.compression = 0;
+ bih.sizeimage = 0;
+ bih.xpels = 0;
+ bih.ypels = 0;
+ bih.clrused = 0;
+ bih.clrimp = 0;
+
+ // convert the palette to the windows format
+ for (i = 0; i != 256; i++) {
+ rq[i].red = palette[i].r;
+ rq[i].green = palette[i].g;
+ rq[i].blue = palette[i].b;
+ rq[i].reserved = 0;
+ }
+
+ // write file header and info header and palette
+ if (fwrite(&bfh, sizeof(bfh), 1, f) != 1) return false;
+ if (fwrite(&bih, sizeof(bih), 1, f) != 1) return false;
+ if (fwrite(rq, sizeof(rq), 1, f) != 1) return false;
+
+ // use by default 64k temp memory
+ maxlines = clamp(65536 / padw, 16, 128);
+
+ // now generate the bitmap bits
+ buff = malloc(padw * maxlines); // by default generate 128 lines at a time.
+ if (buff == NULL) {
+ fclose(f);
+ return false;
+ }
+ memset(buff, 0, padw * maxlines); // zero the buffer to have the padding bytes set to 0
+
+ // start at the bottom, since bitmaps are stored bottom up.
+ do {
+ // determine # lines
+ n = min(h, maxlines);
+ h -= n;
+
+ // render the pixels
+ callb(userdata, buff, h, padw, n);
+
+ // write each line
+ while (n)
+ if (fwrite(buff + (--n) * padw, padw, 1, f) != 1) {
+ free(buff);
+ fclose(f);
+ return false;
+ }
+ } while (h != 0);
+
+ free(buff);
+ fclose(f);
+
+ return true;
+}
+
+//********************************************************
+//*** SCREENSHOT CODE FOR PORTABLE NETWORK GRAPHICS (.PNG)
+//********************************************************
+#if defined(WITH_PNG)
+#include <png.h>
+
+static void PNGAPI png_my_error(png_structp png_ptr, png_const_charp message)
+{
+ DEBUG(misc, 0, "[libpng] error: %s - %s", message, (char *)png_get_error_ptr(png_ptr));
+ longjmp(png_ptr->jmpbuf, 1);
+}
+
+static void PNGAPI png_my_warning(png_structp png_ptr, png_const_charp message)
+{
+ DEBUG(misc, 1, "[libpng] warning: %s - %s", message, (char *)png_get_error_ptr(png_ptr));
+}
+
+static bool MakePNGImage(const char *name, ScreenshotCallback *callb, void *userdata, uint w, uint h, int pixelformat, const Colour *palette)
+{
+ png_color rq[256];
+ Pixel *buff;
+ FILE *f;
+ uint i, y, n;
+ uint maxlines;
+ png_structp png_ptr;
+ png_infop info_ptr;
+
+ // only implemented for 8bit images so far.
+ if (pixelformat != 8)
+ return false;
+
+ f = fopen(name, "wb");
+ if (f == NULL) return false;
+
+ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (char *)name, png_my_error, png_my_warning);
+
+ if (png_ptr == NULL) {
+ fclose(f);
+ return false;
+ }
+
+ info_ptr = png_create_info_struct(png_ptr);
+ if (info_ptr == NULL) {
+ png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
+ fclose(f);
+ return false;
+ }
+
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+ fclose(f);
+ return false;
+ }
+
+ png_init_io(png_ptr, f);
+
+ png_set_filter(png_ptr, 0, PNG_FILTER_NONE);
+
+ png_set_IHDR(png_ptr, info_ptr, w, h, pixelformat, PNG_COLOR_TYPE_PALETTE,
+ PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+
+ // convert the palette to the .PNG format.
+ for (i = 0; i != 256; i++) {
+ rq[i].red = palette[i].r;
+ rq[i].green = palette[i].g;
+ rq[i].blue = palette[i].b;
+ }
+
+ png_set_PLTE(png_ptr, info_ptr, rq, 256);
+ png_write_info(png_ptr, info_ptr);
+ png_set_flush(png_ptr, 512);
+
+ // use by default 64k temp memory
+ maxlines = clamp(65536 / w, 16, 128);
+
+ // now generate the bitmap bits
+ buff = malloc(w * maxlines); // by default generate 128 lines at a time.
+ if (buff == NULL) {
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+ fclose(f);
+ return false;
+ }
+ memset(buff, 0, w * maxlines); // zero the buffer to have the padding bytes set to 0
+
+ y = 0;
+ do {
+ // determine # lines to write
+ n = min(h - y, maxlines);
+
+ // render the pixels into the buffer
+ callb(userdata, buff, y, w, n);
+ y += n;
+
+ // write them to png
+ for (i = 0; i != n; i++)
+ png_write_row(png_ptr, buff + i * w);
+ } while (y != h);
+
+ png_write_end(png_ptr, info_ptr);
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+
+ free(buff);
+ fclose(f);
+ return true;
+}
+#endif /* WITH_PNG */
+
+
+//************************************************
+//*** SCREENSHOT CODE FOR ZSOFT PAINTBRUSH (.PCX)
+//************************************************
+
+typedef struct {
+ byte manufacturer;
+ byte version;
+ byte rle;
+ byte bpp;
+ uint32 unused;
+ uint16 xmax, ymax;
+ uint16 hdpi, vdpi;
+ byte pal_small[16*3];
+ byte reserved;
+ byte planes;
+ uint16 pitch;
+ uint16 cpal;
+ uint16 width;
+ uint16 height;
+ byte filler[54];
+} PcxHeader;
+assert_compile(sizeof(PcxHeader) == 128);
+
+static bool MakePCXImage(const char *name, ScreenshotCallback *callb, void *userdata, uint w, uint h, int pixelformat, const Colour *palette)
+{
+ Pixel *buff;
+ FILE *f;
+ uint maxlines;
+ uint y;
+ PcxHeader pcx;
+ bool success;
+
+ if (pixelformat != 8 || w == 0)
+ return false;
+
+ f = fopen(name, "wb");
+ if (f == NULL) return false;
+
+ memset(&pcx, 0, sizeof(pcx));
+
+ // setup pcx header
+ pcx.manufacturer = 10;
+ pcx.version = 5;
+ pcx.rle = 1;
+ pcx.bpp = 8;
+ pcx.xmax = TO_LE16(w - 1);
+ pcx.ymax = TO_LE16(h - 1);
+ pcx.hdpi = TO_LE16(320);
+ pcx.vdpi = TO_LE16(320);
+
+ pcx.planes = 1;
+ pcx.cpal = TO_LE16(1);
+ pcx.width = pcx.pitch = TO_LE16(w);
+ pcx.height = TO_LE16(h);
+
+ // write pcx header
+ if (fwrite(&pcx, sizeof(pcx), 1, f) != 1) {
+ fclose(f);
+ return false;
+ }
+
+ // use by default 64k temp memory
+ maxlines = clamp(65536 / w, 16, 128);
+
+ // now generate the bitmap bits
+ buff = malloc(w * maxlines); // by default generate 128 lines at a time.
+ if (buff == NULL) {
+ fclose(f);
+ return false;
+ }
+ memset(buff, 0, w * maxlines); // zero the buffer to have the padding bytes set to 0
+
+ y = 0;
+ do {
+ // determine # lines to write
+ uint n = min(h - y, maxlines);
+ uint i;
+
+ // render the pixels into the buffer
+ callb(userdata, buff, y, w, n);
+ y += n;
+
+ // write them to pcx
+ for (i = 0; i != n; i++) {
+ const Pixel* bufp = buff + i * w;
+ byte runchar = bufp[0];
+ uint runcount = 1;
+ uint j;
+
+ // for each pixel...
+ for (j = 1; j < w; j++) {
+ Pixel ch = bufp[j];
+
+ if (ch != runchar || runcount >= 0x3f) {
+ if (runcount > 1 || (runchar & 0xC0) == 0xC0)
+ if (fputc(0xC0 | runcount, f) == EOF) {
+ free(buff);
+ fclose(f);
+ return false;
+ }
+ if (fputc(runchar, f) == EOF) {
+ free(buff);
+ fclose(f);
+ return false;
+ }
+ runcount = 0;
+ runchar = ch;
+ }
+ runcount++;
+ }
+
+ // write remaining bytes..
+ if (runcount > 1 || (runchar & 0xC0) == 0xC0)
+ if (fputc(0xC0 | runcount, f) == EOF) {
+ free(buff);
+ fclose(f);
+ return false;
+ }
+ if (fputc(runchar, f) == EOF) {
+ free(buff);
+ fclose(f);
+ return false;
+ }
+ }
+ } while (y != h);
+
+ free(buff);
+
+ // write 8-bit color palette
+ if (fputc(12, f) == EOF) {
+ fclose(f);
+ return false;
+ }
+
+ if (sizeof(*palette) == 3) {
+ success = fwrite(palette, 256 * sizeof(*palette), 1, f) == 1;
+ } else {
+ /* If the palette is word-aligned, copy it to a temporary byte array */
+ byte tmp[256 * 3];
+ uint i;
+
+ for (i = 0; i < 256; i++) {
+ tmp[i * 3 + 0] = palette[i].r;
+ tmp[i * 3 + 1] = palette[i].g;
+ tmp[i * 3 + 2] = palette[i].b;
+ }
+ success = fwrite(tmp, sizeof(tmp), 1, f) == 1;
+ }
+
+ fclose(f);
+
+ return success;
+}
+
+//************************************************
+//*** GENERIC SCREENSHOT CODE
+//************************************************
+
+static const ScreenshotFormat _screenshot_formats[] = {
+#if defined(WITH_PNG)
+ {"PNG", "png", &MakePNGImage},
+#endif
+ {"BMP", "bmp", &MakeBmpImage},
+ {"PCX", "pcx", &MakePCXImage},
+};
+
+void InitializeScreenshotFormats(void)
+{
+ int i, j;
+ for (i = 0, j = 0; i != lengthof(_screenshot_formats); i++)
+ if (!strcmp(_screenshot_format_name, _screenshot_formats[i].extension)) {
+ j = i;
+ break;
+ }
+ _cur_screenshot_format = j;
+ _num_screenshot_formats = lengthof(_screenshot_formats);
+ current_screenshot_type = SC_NONE;
+}
+
+const char *GetScreenshotFormatDesc(int i)
+{
+ return _screenshot_formats[i].name;
+}
+
+void SetScreenshotFormat(int i)
+{
+ _cur_screenshot_format = i;
+ strcpy(_screenshot_format_name, _screenshot_formats[i].extension);
+}
+
+// screenshot generator that dumps the current video buffer
+static void CurrentScreenCallback(void *userdata, Pixel *buf, uint y, uint pitch, uint n)
+{
+ for (; n > 0; --n) {
+ memcpy(buf, _screen.dst_ptr + y * _screen.pitch, _screen.width);
+ ++y;
+ buf += pitch;
+ }
+}
+
+// generate a large piece of the world
+static void LargeWorldCallback(void *userdata, Pixel *buf, uint y, uint pitch, uint n)
+{
+ ViewPort *vp = (ViewPort *)userdata;
+ DrawPixelInfo dpi, *old_dpi;
+ int wx, left;
+
+ old_dpi = _cur_dpi;
+ _cur_dpi = &dpi;
+
+ dpi.dst_ptr = buf;
+ dpi.height = n;
+ dpi.width = vp->width;
+ dpi.pitch = pitch;
+ dpi.zoom = 0;
+ dpi.left = 0;
+ dpi.top = y;
+
+ left = 0;
+ while (vp->width - left != 0) {
+ wx = min(vp->width - left, 1600);
+ left += wx;
+
+ ViewportDoDraw(vp,
+ ((left - wx - vp->left) << vp->zoom) + vp->virtual_left,
+ ((y - vp->top) << vp->zoom) + vp->virtual_top,
+ ((left - vp->left) << vp->zoom) + vp->virtual_left,
+ (((y + n) - vp->top) << vp->zoom) + vp->virtual_top
+ );
+ }
+
+ _cur_dpi = old_dpi;
+}
+
+static char *MakeScreenshotName(const char *ext)
+{
+ static char filename[256];
+ char *base;
+ int serial;
+
+ if (_game_mode == GM_EDITOR || _game_mode == GM_MENU || _local_player == PLAYER_SPECTATOR) {
+ sprintf(_screenshot_name, "screenshot");
+ } else {
+ const Player* p = GetPlayer(_local_player);
+ SetDParam(0, p->name_1);
+ SetDParam(1, p->name_2);
+ SetDParam(2, _date);
+ GetString(_screenshot_name, STR_4004, lastof(_screenshot_name));
+ }
+
+ base = strchr(_screenshot_name, 0);
+ base[0] = '.'; strcpy(base + 1, ext);
+
+ serial = 0;
+ for (;;) {
+ snprintf(filename, sizeof(filename), "%s%s", _paths.personal_dir, _screenshot_name);
+ if (!FileExists(filename))
+ break;
+ sprintf(base, " #%d.%s", ++serial, ext);
+ }
+
+ return filename;
+}
+
+void SetScreenshotType(ScreenshotType t)
+{
+ current_screenshot_type = t;
+}
+
+bool IsScreenshotRequested(void)
+{
+ return (current_screenshot_type != SC_NONE);
+}
+
+static bool MakeSmallScreenshot(void)
+{
+ const ScreenshotFormat *sf = _screenshot_formats + _cur_screenshot_format;
+ return sf->proc(MakeScreenshotName(sf->extension), CurrentScreenCallback, NULL, _screen.width, _screen.height, 8, _cur_palette);
+}
+
+static bool MakeWorldScreenshot(void)
+{
+ ViewPort vp;
+ const ScreenshotFormat *sf;
+
+ vp.zoom = 0;
+ vp.left = 0;
+ vp.top = 0;
+ vp.virtual_left = -(int)MapMaxX() * TILE_PIXELS;
+ vp.virtual_top = 0;
+ vp.virtual_width = (MapMaxX() + MapMaxY()) * TILE_PIXELS;
+ vp.width = vp.virtual_width;
+ vp.virtual_height = (MapMaxX() + MapMaxY()) * TILE_PIXELS >> 1;
+ vp.height = vp.virtual_height;
+
+ sf = _screenshot_formats + _cur_screenshot_format;
+ return sf->proc(MakeScreenshotName(sf->extension), LargeWorldCallback, &vp, vp.width, vp.height, 8, _cur_palette);
+}
+
+bool MakeScreenshot(void)
+{
+ switch (current_screenshot_type) {
+ case SC_VIEWPORT:
+ UndrawMouseCursor();
+ DrawDirtyBlocks();
+ current_screenshot_type = SC_NONE;
+ return MakeSmallScreenshot();
+ case SC_WORLD:
+ current_screenshot_type = SC_NONE;
+ return MakeWorldScreenshot();
+ default: return false;
+ }
+}
+
+
+
diff --git a/src/screenshot.h b/src/screenshot.h
new file mode 100644
index 000000000..b8cc7df89
--- /dev/null
+++ b/src/screenshot.h
@@ -0,0 +1,25 @@
+/* $Id$ */
+
+#ifndef SCREENSHOT_H
+#define SCREENSHOT_H
+
+void InitializeScreenshotFormats(void);
+
+const char *GetScreenshotFormatDesc(int i);
+void SetScreenshotFormat(int i);
+
+typedef enum ScreenshotType {
+ SC_NONE,
+ SC_VIEWPORT,
+ SC_WORLD
+} ScreenshotType;
+
+bool MakeScreenshot(void);
+void SetScreenshotType(ScreenshotType t);
+bool IsScreenshotRequested(void);
+
+extern char _screenshot_format_name[8];
+extern uint _num_screenshot_formats;
+extern uint _cur_screenshot_format;
+
+#endif /* SCREENSHOT_H */
diff --git a/src/sdl.c b/src/sdl.c
new file mode 100644
index 000000000..f6474b6e1
--- /dev/null
+++ b/src/sdl.c
@@ -0,0 +1,139 @@
+/* $Id$ */
+
+#include "stdafx.h"
+
+#ifdef WITH_SDL
+
+#include "openttd.h"
+#include "sdl.h"
+#include <SDL.h>
+
+#ifdef UNIX
+#include <signal.h>
+
+#ifdef __MORPHOS__
+ // The system supplied definition of SIG_DFL is wrong on MorphOS
+ #undef SIG_DFL
+ #define SIG_DFL (void (*)(int))0
+#endif
+#endif
+
+static int _sdl_usage;
+
+#ifdef DYNAMICALLY_LOADED_SDL
+
+#include "win32.h"
+
+#define M(x) x "\0"
+static const char sdl_files[] =
+ M("sdl.dll")
+ M("SDL_Init")
+ M("SDL_InitSubSystem")
+ M("SDL_GetError")
+ M("SDL_QuitSubSystem")
+ M("SDL_UpdateRect")
+ M("SDL_UpdateRects")
+ M("SDL_SetColors")
+ M("SDL_WM_SetCaption")
+ M("SDL_ShowCursor")
+ M("SDL_FreeSurface")
+ M("SDL_PollEvent")
+ M("SDL_WarpMouse")
+ M("SDL_GetTicks")
+ M("SDL_OpenAudio")
+ M("SDL_PauseAudio")
+ M("SDL_CloseAudio")
+ M("SDL_LockSurface")
+ M("SDL_UnlockSurface")
+ M("SDL_GetModState")
+ M("SDL_Delay")
+ M("SDL_Quit")
+ M("SDL_SetVideoMode")
+ M("SDL_EnableKeyRepeat")
+ M("SDL_EnableUNICODE")
+ M("SDL_VideoDriverName")
+ M("SDL_ListModes")
+ M("SDL_GetKeyState")
+ M("SDL_LoadBMP_RW")
+ M("SDL_RWFromFile")
+ M("SDL_SetColorKey")
+ M("SDL_WM_SetIcon")
+ M("SDL_MapRGB")
+ M("")
+;
+#undef M
+
+SDLProcs sdl_proc;
+
+static const char *LoadSdlDLL(void)
+{
+ if (sdl_proc.SDL_Init != NULL)
+ return NULL;
+ if (!LoadLibraryList((Function *)(void *)&sdl_proc, sdl_files))
+ return "Unable to load sdl.dll";
+ return NULL;
+}
+
+#endif // DYNAMICALLY_LOADED_SDL
+
+
+#ifdef UNIX
+static void SdlAbort(int sig)
+{
+ /* Own hand-made parachute for the cases of failed assertions. */
+ SDL_CALL SDL_Quit();
+
+ switch (sig) {
+ case SIGSEGV:
+ case SIGFPE:
+ signal(sig, SIG_DFL);
+ raise(sig);
+ break;
+
+ default:
+ break;
+ }
+}
+#endif
+
+
+const char* SdlOpen(uint32 x)
+{
+#ifdef DYNAMICALLY_LOADED_SDL
+ {
+ const char *s = LoadSdlDLL();
+ if (s != NULL) return s;
+ }
+#endif
+ if (_sdl_usage++ == 0) {
+ if (SDL_CALL SDL_Init(x) == -1)
+ return SDL_CALL SDL_GetError();
+ } else if (x != 0) {
+ if (SDL_CALL SDL_InitSubSystem(x) == -1)
+ return SDL_CALL SDL_GetError();
+ }
+
+#ifdef UNIX
+ signal(SIGABRT, SdlAbort);
+ signal(SIGSEGV, SdlAbort);
+ signal(SIGFPE, SdlAbort);
+#endif
+
+ return NULL;
+}
+
+void SdlClose(uint32 x)
+{
+ if (x != 0)
+ SDL_CALL SDL_QuitSubSystem(x);
+ if (--_sdl_usage == 0) {
+ SDL_CALL SDL_Quit();
+ #ifdef UNIX
+ signal(SIGABRT, SIG_DFL);
+ signal(SIGSEGV, SIG_DFL);
+ signal(SIGFPE, SIG_DFL);
+ #endif
+ }
+}
+
+#endif
diff --git a/src/sdl.h b/src/sdl.h
new file mode 100644
index 000000000..9fe374095
--- /dev/null
+++ b/src/sdl.h
@@ -0,0 +1,58 @@
+/* $Id$ */
+
+#ifndef SDL_H
+#define SDL_H
+
+const char* SdlOpen(uint32 x);
+void SdlClose(uint32 x);
+
+#ifdef WIN32
+ #define DYNAMICALLY_LOADED_SDL
+#endif
+
+#ifdef DYNAMICALLY_LOADED_SDL
+ #include <SDL.h>
+
+ typedef struct SDLProcs {
+ int (SDLCALL *SDL_Init)(Uint32);
+ int (SDLCALL *SDL_InitSubSystem)(Uint32);
+ char *(SDLCALL *SDL_GetError)(void);
+ void (SDLCALL *SDL_QuitSubSystem)(Uint32);
+ void (SDLCALL *SDL_UpdateRect)(SDL_Surface *, Sint32, Sint32, Uint32, Uint32);
+ void (SDLCALL *SDL_UpdateRects)(SDL_Surface *, int, SDL_Rect *);
+ int (SDLCALL *SDL_SetColors)(SDL_Surface *, SDL_Color *, int, int);
+ void (SDLCALL *SDL_WM_SetCaption)(const char *, const char *);
+ int (SDLCALL *SDL_ShowCursor)(int);
+ void (SDLCALL *SDL_FreeSurface)(SDL_Surface *);
+ int (SDLCALL *SDL_PollEvent)(SDL_Event *);
+ void (SDLCALL *SDL_WarpMouse)(Uint16, Uint16);
+ uint32 (SDLCALL *SDL_GetTicks)(void);
+ int (SDLCALL *SDL_OpenAudio)(SDL_AudioSpec *, SDL_AudioSpec*);
+ void (SDLCALL *SDL_PauseAudio)(int);
+ void (SDLCALL *SDL_CloseAudio)(void);
+ int (SDLCALL *SDL_LockSurface)(SDL_Surface*);
+ void (SDLCALL *SDL_UnlockSurface)(SDL_Surface*);
+ SDLMod (SDLCALL *SDL_GetModState)(void);
+ void (SDLCALL *SDL_Delay)(Uint32);
+ void (SDLCALL *SDL_Quit)(void);
+ SDL_Surface *(SDLCALL *SDL_SetVideoMode)(int, int, int, Uint32);
+ int (SDLCALL *SDL_EnableKeyRepeat)(int, int);
+ void (SDLCALL *SDL_EnableUNICODE)(int);
+ void (SDLCALL *SDL_VideoDriverName)(char *, int);
+ SDL_Rect **(SDLCALL *SDL_ListModes)(void *, int);
+ Uint8 *(SDLCALL *SDL_GetKeyState)(int *);
+ SDL_Surface *(SDLCALL *SDL_LoadBMP_RW)(SDL_RWops *, int);
+ SDL_RWops *(SDLCALL *SDL_RWFromFile)(const char *, const char *);
+ int (SDLCALL *SDL_SetColorKey)(SDL_Surface *, Uint32, Uint32);
+ void (SDLCALL *SDL_WM_SetIcon)(SDL_Surface *, Uint8 *);
+ Uint32 (SDLCALL *SDL_MapRGB)(SDL_PixelFormat *, Uint8, Uint8, Uint8);
+ } SDLProcs;
+
+ extern SDLProcs sdl_proc;
+
+ #define SDL_CALL sdl_proc.
+#else
+ #define SDL_CALL
+#endif
+
+#endif /* SDL_H */
diff --git a/src/settings.c b/src/settings.c
new file mode 100644
index 000000000..b6d7fa895
--- /dev/null
+++ b/src/settings.c
@@ -0,0 +1,1861 @@
+/* $Id$ */
+
+/** @file
+ * All actions handling saving and loading of the settings/configuration goes on in this file.
+ * The file consists of four parts:
+ * <ol>
+ * <li>Parsing the configuration file (openttd.cfg). This is achieved with the ini_ functions which
+ * handle various types, such as normal 'key = value' pairs, lists and value combinations of
+ * lists, strings, integers, 'bit'-masks and element selections.
+ * <li>Defining the data structures that go into the configuration. These include for example
+ * the _patches struct, but also network-settings, banlists, newgrf, etc. There are a lot
+ * of helper macros available for the various types, and also saving/loading of these settings
+ * in a savegame is handled inside these structures.
+ * <li>Handle reading and writing to the setting-structures from inside the game either from
+ * the console for example or through the gui with CMD_ functions.
+ * <li>Handle saving/loading of the PATS chunk inside the savegame.
+ * </ol>
+ * @see SettingDesc
+ * @see SaveLoad
+ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "currency.h"
+#include "functions.h"
+#include "macros.h"
+#include "screenshot.h"
+#include "sound.h"
+#include "string.h"
+#include "variables.h"
+#include "network/network.h"
+#include "settings.h"
+#include "command.h"
+#include "console.h"
+#include "saveload.h"
+#include "npf.h"
+#include "yapf/yapf.h"
+#include "newgrf.h"
+#include "newgrf_config.h"
+#include "genworld.h"
+#include "date.h"
+#include "rail.h"
+#ifdef WITH_FREETYPE
+#include "gfx.h"
+#include "fontcache.h"
+#endif
+
+/** The patch values that are used for new games and/or modified in config file */
+Patches _patches_newgame;
+
+typedef struct IniFile IniFile;
+typedef struct IniItem IniItem;
+typedef struct IniGroup IniGroup;
+typedef struct SettingsMemoryPool SettingsMemoryPool;
+
+typedef const char *SettingListCallbackProc(const IniItem *item, uint index);
+typedef void SettingDescProc(IniFile *ini, const SettingDesc *desc, const char *grpname, void *object);
+typedef void SettingDescProcList(IniFile *ini, const char *grpname, char **list, uint len, SettingListCallbackProc proc);
+
+static void pool_init(SettingsMemoryPool **pool);
+static void *pool_alloc(SettingsMemoryPool **pool, uint size);
+static void *pool_strdup(SettingsMemoryPool **pool, const char *mem, uint size);
+static void pool_free(SettingsMemoryPool **pool);
+static bool IsSignedVarMemType(VarType vt);
+
+struct SettingsMemoryPool {
+ uint pos,size;
+ SettingsMemoryPool *next;
+ byte mem[1];
+};
+
+static SettingsMemoryPool *pool_new(uint minsize)
+{
+ SettingsMemoryPool *p;
+ if (minsize < 4096 - 12) minsize = 4096 - 12;
+
+ p = malloc(sizeof(SettingsMemoryPool) - 1 + minsize);
+ p->pos = 0;
+ p->size = minsize;
+ p->next = NULL;
+ return p;
+}
+
+static void pool_init(SettingsMemoryPool **pool)
+{
+ *pool = pool_new(0);
+}
+
+static void *pool_alloc(SettingsMemoryPool **pool, uint size)
+{
+ uint pos;
+ SettingsMemoryPool *p = *pool;
+
+ size = ALIGN(size, sizeof(void*));
+
+ // first check if there's memory in the next pool
+ if (p->next && p->next->pos + size <= p->next->size) {
+ p = p->next;
+ // then check if there's not memory in the cur pool
+ } else if (p->pos + size > p->size) {
+ SettingsMemoryPool *n = pool_new(size);
+ *pool = n;
+ n->next = p;
+ p = n;
+ }
+
+ pos = p->pos;
+ p->pos += size;
+ return p->mem + pos;
+}
+
+static void *pool_strdup(SettingsMemoryPool **pool, const char *mem, uint size)
+{
+ byte *p = pool_alloc(pool, size + 1);
+ p[size] = 0;
+ memcpy(p, mem, size);
+ return p;
+}
+
+static void pool_free(SettingsMemoryPool **pool)
+{
+ SettingsMemoryPool *p = *pool, *n;
+ *pool = NULL;
+ while (p) {
+ n = p->next;
+ free(p);
+ p = n;
+ }
+}
+
+// structs describing the ini format.
+struct IniItem {
+ char *name;
+ char *value;
+ char *comment;
+ IniItem *next;
+};
+
+struct IniGroup {
+ char *name; // name of group
+ char *comment; //comment for group
+ IniItem *item, **last_item;
+ IniGroup *next;
+ IniFile *ini;
+ IniGroupType type; // type of group
+};
+
+struct IniFile {
+ SettingsMemoryPool *pool;
+ IniGroup *group, **last_group;
+ char *comment; // last comment in file
+};
+
+// allocate an inifile object
+static IniFile *ini_alloc(void)
+{
+ IniFile *ini;
+ SettingsMemoryPool *pool;
+ pool_init(&pool);
+ ini = (IniFile*)pool_alloc(&pool, sizeof(IniFile));
+ ini->pool = pool;
+ ini->group = NULL;
+ ini->last_group = &ini->group;
+ ini->comment = NULL;
+ return ini;
+}
+
+// allocate an ini group object
+static IniGroup *ini_group_alloc(IniFile *ini, const char *grpt, int len)
+{
+ IniGroup *grp = pool_alloc(&ini->pool, sizeof(IniGroup));
+ grp->ini = ini;
+ grp->name = pool_strdup(&ini->pool, grpt, len);
+ if (!strcmp(grp->name, "newgrf") || !strcmp(grp->name, "servers") || !strcmp(grp->name, "bans")) {
+ grp->type = IGT_LIST;
+ } else {
+ grp->type = IGT_VARIABLES;
+ }
+ grp->next = NULL;
+ grp->item = NULL;
+ grp->comment = NULL;
+ grp->last_item = &grp->item;
+ *ini->last_group = grp;
+ ini->last_group = &grp->next;
+ return grp;
+}
+
+static IniItem *ini_item_alloc(IniGroup *group, const char *name, int len)
+{
+ IniItem *item = pool_alloc(&group->ini->pool, sizeof(IniItem));
+ item->name = pool_strdup(&group->ini->pool, name, len);
+ item->next = NULL;
+ item->comment = NULL;
+ item->value = NULL;
+ *group->last_item = item;
+ group->last_item = &item->next;
+ return item;
+}
+
+// load an ini file into the "abstract" format
+static IniFile *ini_load(const char *filename)
+{
+ char buffer[1024], c, *s, *t, *e;
+ FILE *in;
+ IniFile *ini;
+ IniGroup *group = NULL;
+ IniItem *item;
+
+ char *comment = NULL;
+ uint comment_size = 0;
+ uint comment_alloc = 0;
+
+ ini = ini_alloc();
+
+ in = fopen(filename, "r");
+ if (in == NULL) return ini;
+
+ // for each line in the file
+ while (fgets(buffer, sizeof(buffer), in)) {
+
+ // trim whitespace from the left side
+ for (s = buffer; *s == ' ' || *s == '\t'; s++);
+
+ // trim whitespace from right side.
+ e = s + strlen(s);
+ while (e > s && ((c=e[-1]) == '\n' || c == '\r' || c == ' ' || c == '\t')) e--;
+ *e = '\0';
+
+ // skip comments and empty lines
+ if (*s == '#' || *s == ';' || *s == '\0') {
+ uint ns = comment_size + (e - s + 1);
+ uint a = comment_alloc;
+ uint pos;
+ // add to comment
+ if (ns > a) {
+ a = max(a, 128);
+ do a*=2; while (a < ns);
+ comment = realloc(comment, comment_alloc = a);
+ }
+ pos = comment_size;
+ comment_size += (e - s + 1);
+ comment[pos + e - s] = '\n'; // comment newline
+ memcpy(comment + pos, s, e - s); // copy comment contents
+ continue;
+ }
+
+ // it's a group?
+ if (s[0] == '[') {
+ if (e[-1] != ']') {
+ ShowInfoF("ini: invalid group name '%s'\n", buffer);
+ } else {
+ e--;
+ }
+ s++; // skip [
+ group = ini_group_alloc(ini, s, e - s);
+ if (comment_size) {
+ group->comment = pool_strdup(&ini->pool, comment, comment_size);
+ comment_size = 0;
+ }
+ } else if (group) {
+ // find end of keyname
+ for (t = s; *t != '\0' && *t != '=' && *t != '\t' && *t != ' '; t++);
+
+ // it's an item in an existing group
+ item = ini_item_alloc(group, s, t-s);
+ if (comment_size) {
+ item->comment = pool_strdup(&ini->pool, comment, comment_size);
+ comment_size = 0;
+ }
+
+ // find start of parameter
+ while (*t == '=' || *t == ' ' || *t == '\t') t++;
+
+
+ // remove starting quotation marks
+ if (*t == '\"') t++;
+ // remove ending quotation marks
+ e = t + strlen(t);
+ if (e > t && e[-1] == '\"') e--;
+ *e = '\0';
+
+ item->value = pool_strdup(&ini->pool, t, e - t);
+ } else {
+ // it's an orphan item
+ ShowInfoF("ini: '%s' outside of group\n", buffer);
+ }
+ }
+
+ if (comment_size > 0) {
+ ini->comment = pool_strdup(&ini->pool, comment, comment_size);
+ comment_size = 0;
+ }
+
+ free(comment);
+ fclose(in);
+
+ return ini;
+}
+
+// lookup a group or make a new one
+static IniGroup *ini_getgroup(IniFile *ini, const char *name, int len)
+{
+ IniGroup *group;
+
+ if (len == -1) len = strlen(name);
+
+ // does it exist already?
+ for (group = ini->group; group; group = group->next)
+ if (!memcmp(group->name, name, len) && group->name[len] == 0)
+ return group;
+
+ // otherwise make a new one
+ group = ini_group_alloc(ini, name, len);
+ group->comment = pool_strdup(&ini->pool, "\n", 1);
+ return group;
+}
+
+// lookup an item or make a new one
+static IniItem *ini_getitem(IniGroup *group, const char *name, bool create)
+{
+ IniItem *item;
+ uint len = strlen(name);
+
+ for (item = group->item; item; item = item->next)
+ if (strcmp(item->name, name) == 0) return item;
+
+ if (!create) return NULL;
+
+ // otherwise make a new one
+ return ini_item_alloc(group, name, len);
+}
+
+// save ini file from the "abstract" format.
+static bool ini_save(const char *filename, IniFile *ini)
+{
+ FILE *f;
+ IniGroup *group;
+ IniItem *item;
+
+ f = fopen(filename, "w");
+ if (f == NULL) return false;
+
+ for (group = ini->group; group != NULL; group = group->next) {
+ if (group->comment) fputs(group->comment, f);
+ fprintf(f, "[%s]\n", group->name);
+ for (item = group->item; item != NULL; item = item->next) {
+ assert(item->value != NULL);
+ if (item->comment != NULL) fputs(item->comment, f);
+
+ /* Don't give an equal sign to list items that don't have a parameter */
+ if (group->type == IGT_LIST && *item->value == '\0') {
+ fprintf(f, "%s\n", item->name);
+ } else {
+ fprintf(f, "%s = %s\n", item->name, item->value);
+ }
+ }
+ }
+ if (ini->comment) fputs(ini->comment, f);
+
+ fclose(f);
+ return true;
+}
+
+static void ini_free(IniFile *ini)
+{
+ pool_free(&ini->pool);
+}
+
+/** Find the index value of a ONEofMANY type in a string seperated by |
+ * @param many full domain of values the ONEofMANY setting can have
+ * @param one the current value of the setting for which a value needs found
+ * @param onelen force calculation of the *one parameter
+ * @return the integer index of the full-list, or -1 if not found */
+static int lookup_oneofmany(const char *many, const char *one, int onelen)
+{
+ const char *s;
+ int idx;
+
+ if (onelen == -1) onelen = strlen(one);
+
+ // check if it's an integer
+ if (*one >= '0' && *one <= '9')
+ return strtoul(one, NULL, 0);
+
+ idx = 0;
+ for (;;) {
+ // find end of item
+ s = many;
+ while (*s != '|' && *s != 0) s++;
+ if (s - many == onelen && !memcmp(one, many, onelen)) return idx;
+ if (*s == 0) return -1;
+ many = s + 1;
+ idx++;
+ }
+}
+
+/** Find the set-integer value MANYofMANY type in a string
+ * @param many full domain of values the MANYofMANY setting can have
+ * @param str the current string value of the setting, each individual
+ * of seperated by a whitespace\tab or | character
+ * @return the 'fully' set integer, or -1 if a set is not found */
+static uint32 lookup_manyofmany(const char *many, const char *str)
+{
+ const char *s;
+ int r;
+ uint32 res = 0;
+
+ for (;;) {
+ // skip "whitespace"
+ while (*str == ' ' || *str == '\t' || *str == '|') str++;
+ if (*str == 0) break;
+
+ s = str;
+ while (*s != 0 && *s != ' ' && *s != '\t' && *s != '|') s++;
+
+ r = lookup_oneofmany(many, str, s - str);
+ if (r == -1) return (uint32)-1;
+
+ SETBIT(res, r); // value found, set it
+ if (*s == 0) break;
+ str = s + 1;
+ }
+ return res;
+}
+
+/** Parse an integerlist string and set each found value
+ * @param p the string to be parsed. Each element in the list is seperated by a
+ * comma or a space character
+ * @param items pointer to the integerlist-array that will be filled with values
+ * @param maxitems the maximum number of elements the integerlist-array has
+ * @return returns the number of items found, or -1 on an error */
+static int parse_intlist(const char *p, int *items, int maxitems)
+{
+ int n = 0, v;
+ char *end;
+
+ for (;;) {
+ v = strtol(p, &end, 0);
+ if (p == end || n == maxitems) return -1;
+ p = end;
+ items[n++] = v;
+ if (*p == '\0') break;
+ if (*p != ',' && *p != ' ') return -1;
+ p++;
+ }
+
+ return n;
+}
+
+/** Load parsed string-values into an integer-array (intlist)
+ * @param str the string that contains the values (and will be parsed)
+ * @param array pointer to the integer-arrays that will be filled
+ * @param nelems the number of elements the array holds. Maximum is 64 elements
+ * @param type the type of elements the array holds (eg INT8, UINT16, etc.)
+ * @return return true on success and false on error */
+static bool load_intlist(const char *str, void *array, int nelems, VarType type)
+{
+ int items[64];
+ int i, nitems;
+
+ if (str == NULL) {
+ memset(items, 0, sizeof(items));
+ nitems = nelems;
+ } else {
+ nitems = parse_intlist(str, items, lengthof(items));
+ if (nitems != nelems) return false;
+ }
+
+ switch (type) {
+ case SLE_VAR_BL:
+ case SLE_VAR_I8:
+ case SLE_VAR_U8:
+ for (i = 0; i != nitems; i++) ((byte*)array)[i] = items[i];
+ break;
+ case SLE_VAR_I16:
+ case SLE_VAR_U16:
+ for (i = 0; i != nitems; i++) ((uint16*)array)[i] = items[i];
+ break;
+ case SLE_VAR_I32:
+ case SLE_VAR_U32:
+ for (i = 0; i != nitems; i++) ((uint32*)array)[i] = items[i];
+ break;
+ default: NOT_REACHED();
+ }
+
+ return true;
+}
+
+/** Convert an integer-array (intlist) to a string representation. Each value
+ * is seperated by a comma or a space character
+ * @param buf output buffer where the string-representation will be stored
+ * @param array pointer to the integer-arrays that is read from
+ * @param nelems the number of elements the array holds.
+ * @param type the type of elements the array holds (eg INT8, UINT16, etc.) */
+static void make_intlist(char *buf, const void *array, int nelems, VarType type)
+{
+ int i, v = 0;
+ const byte *p = (const byte*)array;
+
+ for (i = 0; i != nelems; i++) {
+ switch (type) {
+ case SLE_VAR_BL:
+ case SLE_VAR_I8: v = *(int8*)p; p += 1; break;
+ case SLE_VAR_U8: v = *(byte*)p; p += 1; break;
+ case SLE_VAR_I16: v = *(int16*)p; p += 2; break;
+ case SLE_VAR_U16: v = *(uint16*)p; p += 2; break;
+ case SLE_VAR_I32: v = *(int32*)p; p += 4; break;
+ case SLE_VAR_U32: v = *(uint32*)p; p += 4; break;
+ default: NOT_REACHED();
+ }
+ buf += sprintf(buf, (i == 0) ? "%d" : ",%d", v);
+ }
+}
+
+/** Convert a ONEofMANY structure to a string representation.
+ * @param buf output buffer where the string-representation will be stored
+ * @param many the full-domain string of possible values
+ * @param id the value of the variable and whose string-representation must be found */
+static void make_oneofmany(char *buf, const char *many, int id)
+{
+ int orig_id = id;
+
+ // Look for the id'th element
+ while (--id >= 0) {
+ for (; *many != '|'; many++) {
+ if (*many == '\0') { // not found
+ sprintf(buf, "%d", orig_id);
+ return;
+ }
+ }
+ many++; // pass the |-character
+ }
+
+ // copy string until next item (|) or the end of the list if this is the last one
+ while (*many != '\0' && *many != '|') *buf++ = *many++;
+ *buf = '\0';
+}
+
+/** Convert a MANYofMANY structure to a string representation.
+ * @param buf output buffer where the string-representation will be stored
+ * @param many the full-domain string of possible values
+ * @param x the value of the variable and whose string-representation must
+ * be found in the bitmasked many string */
+static void make_manyofmany(char *buf, const char *many, uint32 x)
+{
+ const char *start;
+ int i = 0;
+ bool init = true;
+
+ for (; x != 0; x >>= 1, i++) {
+ start = many;
+ while (*many != 0 && *many != '|') many++; // advance to the next element
+
+ if (HASBIT(x, 0)) { // item found, copy it
+ if (!init) *buf++ = '|';
+ init = false;
+ if (start == many) {
+ buf += sprintf(buf, "%d", i);
+ } else {
+ memcpy(buf, start, many - start);
+ buf += many - start;
+ }
+ }
+
+ if (*many == '|') many++;
+ }
+
+ *buf = '\0';
+}
+
+/** Convert a string representation (external) of a setting to the internal rep.
+ * @param desc SettingDesc struct that holds all information about the variable
+ * @param str input string that will be parsed based on the type of desc
+ * @return return the parsed value of the setting */
+static const void *string_to_val(const SettingDescBase *desc, const char *str)
+{
+ switch (desc->cmd) {
+ case SDT_NUMX: {
+ char *end;
+ unsigned long val = strtoul(str, &end, 0);
+ if (*end != '\0') ShowInfoF("ini: trailing characters at end of setting '%s'", desc->name);
+ return (void*)val;
+ }
+ case SDT_ONEOFMANY: {
+ long r = lookup_oneofmany(desc->many, str, -1);
+ if (r != -1) return (void*)r;
+ ShowInfoF("ini: invalid value '%s' for '%s'", str, desc->name);
+ return 0;
+ }
+ case SDT_MANYOFMANY: {
+ unsigned long r = lookup_manyofmany(desc->many, str);
+ if (r != (unsigned long)-1) return (void*)r;
+ ShowInfoF("ini: invalid value '%s' for '%s'", str, desc->name);
+ return 0;
+ }
+ case SDT_BOOLX:
+ if (strcmp(str, "true") == 0 || strcmp(str, "on") == 0 || strcmp(str, "1") == 0)
+ return (void*)true;
+ if (strcmp(str, "false") == 0 || strcmp(str, "off") == 0 || strcmp(str, "0") == 0)
+ return (void*)false;
+ ShowInfoF("ini: invalid setting value '%s' for '%s'", str, desc->name);
+ break;
+
+ case SDT_STRING:
+ case SDT_INTLIST: return str;
+ }
+
+ return NULL;
+}
+
+/** Set the value of a setting and if needed clamp the value to
+ * the preset minimum and maximum.
+ * @param ptr the variable itself
+ * @param sd pointer to the 'information'-database of the variable
+ * @param val signed long version of the new value
+ * @pre SettingDesc is of type SDT_BOOLX, SDT_NUMX,
+ * SDT_ONEOFMANY or SDT_MANYOFMANY. Other types are not supported as of now */
+static void Write_ValidateSetting(void *ptr, const SettingDesc *sd, int32 val)
+{
+ const SettingDescBase *sdb = &sd->desc;
+
+ if (sdb->cmd != SDT_BOOLX &&
+ sdb->cmd != SDT_NUMX &&
+ sdb->cmd != SDT_ONEOFMANY &&
+ sdb->cmd != SDT_MANYOFMANY) {
+ return;
+ }
+
+ /* We cannot know the maximum value of a bitset variable, so just have faith */
+ if (sdb->cmd != SDT_MANYOFMANY) {
+ /* We need to take special care of the uint32 type as we receive from the function
+ * a signed integer. While here also bail out on 64-bit settings as those are not
+ * supported. Unsigned 8 and 16-bit variables are safe since they fit into a signed
+ * 32-bit variable
+ * TODO: Support 64-bit settings/variables */
+ switch (GetVarMemType(sd->save.conv)) {
+ case SLE_VAR_BL:
+ case SLE_VAR_I8:
+ case SLE_VAR_U8:
+ case SLE_VAR_I16:
+ case SLE_VAR_U16:
+ case SLE_VAR_I32: {
+ /* Override the minimum value. No value below sdb->min, except special value 0 */
+ int32 min = ((sdb->flags & SGF_0ISDISABLED) && val <= sdb->min) ? 0 : sdb->min;
+ val = clamp(val, min, sdb->max);
+ } break;
+ case SLE_VAR_U32: {
+ /* Override the minimum value. No value below sdb->min, except special value 0 */
+ uint min = ((sdb->flags & SGF_0ISDISABLED) && (uint)val <= (uint)sdb->min) ? 0 : sdb->min;
+ WriteValue(ptr, SLE_VAR_U32, (int64)clampu(val, min, sdb->max));
+ return;
+ }
+ case SLE_VAR_I64:
+ case SLE_VAR_U64:
+ default: NOT_REACHED(); break;
+ }
+ }
+
+ WriteValue(ptr, sd->save.conv, (int64)val);
+}
+
+/** Load values from a group of an IniFile structure into the internal representation
+ * @param ini pointer to IniFile structure that holds administrative information
+ * @param sd pointer to SettingDesc structure whose internally pointed variables will
+ * be given values
+ * @param grpname the group of the IniFile to search in for the new values */
+static void ini_load_settings(IniFile *ini, const SettingDesc *sd, const char *grpname, void *object)
+{
+ IniGroup *group;
+ IniGroup *group_def = ini_getgroup(ini, grpname, -1);
+ IniItem *item;
+ const void *p;
+ void *ptr;
+ const char *s;
+
+ for (; sd->save.cmd != SL_END; sd++) {
+ const SettingDescBase *sdb = &sd->desc;
+ const SaveLoad *sld = &sd->save;
+
+ if (!SlIsObjectCurrentlyValid(sld->version_from, sld->version_to)) continue;
+
+ // XXX - wtf is this?? (group override?)
+ s = strchr(sdb->name, '.');
+ if (s != NULL) {
+ group = ini_getgroup(ini, sdb->name, s - sdb->name);
+ s++;
+ } else {
+ s = sdb->name;
+ group = group_def;
+ }
+
+ item = ini_getitem(group, s, false);
+ p = (item == NULL) ? sdb->def : string_to_val(sdb, item->value);
+ ptr = GetVariableAddress(object, sld);
+
+ switch (sdb->cmd) {
+ case SDT_BOOLX: /* All four are various types of (integer) numbers */
+ case SDT_NUMX:
+ case SDT_ONEOFMANY:
+ case SDT_MANYOFMANY:
+ Write_ValidateSetting(ptr, sd, (unsigned long)p); break;
+
+ case SDT_STRING:
+ switch (GetVarMemType(sld->conv)) {
+ case SLE_VAR_STRB:
+ case SLE_VAR_STRBQ:
+ if (p != NULL) ttd_strlcpy((char*)ptr, p, sld->length);
+ break;
+ case SLE_VAR_STR:
+ case SLE_VAR_STRQ:
+ if (p != NULL) {
+ free(*(char**)ptr);
+ *(char**)ptr = strdup((const char*)p);
+ }
+ break;
+ case SLE_VAR_CHAR: *(char*)ptr = *(char*)p; break;
+ default: NOT_REACHED(); break;
+ }
+ break;
+
+ case SDT_INTLIST: {
+ if (!load_intlist(p, ptr, sld->length, GetVarMemType(sld->conv)))
+ ShowInfoF("ini: error in array '%s'", sdb->name);
+ break;
+ }
+ default: NOT_REACHED(); break;
+ }
+ }
+}
+
+/** Save the values of settings to the inifile.
+ * @param ini pointer to IniFile structure
+ * @param sd read-only SettingDesc structure which contains the unmodified,
+ * loaded values of the configuration file and various information about it
+ * @param grpname holds the name of the group (eg. [network]) where these will be saved
+ * The function works as follows: for each item in the SettingDesc structure we
+ * have a look if the value has changed since we started the game (the original
+ * values are reloaded when saving). If settings indeed have changed, we get
+ * these and save them.
+ */
+static void ini_save_settings(IniFile *ini, const SettingDesc *sd, const char *grpname, void *object)
+{
+ IniGroup *group_def = NULL, *group;
+ IniItem *item;
+ char buf[512];
+ const char *s;
+ void *ptr;
+
+ for (; sd->save.cmd != SL_END; sd++) {
+ const SettingDescBase *sdb = &sd->desc;
+ const SaveLoad *sld = &sd->save;
+
+ /* If the setting is not saved to the configuration
+ * file, just continue with the next setting */
+ if (!SlIsObjectCurrentlyValid(sld->version_from, sld->version_to)) continue;
+ if (sld->conv & SLF_CONFIG_NO) continue;
+
+ // XXX - wtf is this?? (group override?)
+ s = strchr(sdb->name, '.');
+ if (s != NULL) {
+ group = ini_getgroup(ini, sdb->name, s - sdb->name);
+ s++;
+ } else {
+ if (group_def == NULL) group_def = ini_getgroup(ini, grpname, -1);
+ s = sdb->name;
+ group = group_def;
+ }
+
+ item = ini_getitem(group, s, true);
+ ptr = GetVariableAddress(object, sld);
+
+ if (item->value != NULL) {
+ // check if the value is the same as the old value
+ const void *p = string_to_val(sdb, item->value);
+
+ /* The main type of a variable/setting is in bytes 8-15
+ * The subtype (what kind of numbers do we have there) is in 0-7 */
+ switch (sdb->cmd) {
+ case SDT_BOOLX:
+ case SDT_NUMX:
+ case SDT_ONEOFMANY:
+ case SDT_MANYOFMANY:
+ switch (GetVarMemType(sld->conv)) {
+ case SLE_VAR_BL:
+ if (*(bool*)ptr == (bool)(unsigned long)p) continue;
+ break;
+ case SLE_VAR_I8:
+ case SLE_VAR_U8:
+ if (*(byte*)ptr == (byte)(unsigned long)p) continue;
+ break;
+ case SLE_VAR_I16:
+ case SLE_VAR_U16:
+ if (*(uint16*)ptr == (uint16)(unsigned long)p) continue;
+ break;
+ case SLE_VAR_I32:
+ case SLE_VAR_U32:
+ if (*(uint32*)ptr == (uint32)(unsigned long)p) continue;
+ break;
+ default: NOT_REACHED();
+ }
+ break;
+ default: break; /* Assume the other types are always changed */
+ }
+ }
+
+ /* Value has changed, get the new value and put it into a buffer */
+ switch (sdb->cmd) {
+ case SDT_BOOLX:
+ case SDT_NUMX:
+ case SDT_ONEOFMANY:
+ case SDT_MANYOFMANY: {
+ uint32 i = (uint32)ReadValue(ptr, sld->conv);
+
+ switch (sdb->cmd) {
+ case SDT_BOOLX: strcpy(buf, (i != 0) ? "true" : "false"); break;
+ case SDT_NUMX: sprintf(buf, IsSignedVarMemType(sld->conv) ? "%d" : "%u", i); break;
+ case SDT_ONEOFMANY: make_oneofmany(buf, sdb->many, i); break;
+ case SDT_MANYOFMANY: make_manyofmany(buf, sdb->many, i); break;
+ default: NOT_REACHED();
+ }
+ } break;
+
+ case SDT_STRING:
+ switch (GetVarMemType(sld->conv)) {
+ case SLE_VAR_STRB: strcpy(buf, (char*)ptr); break;
+ case SLE_VAR_STRBQ:sprintf(buf, "\"%s\"", (char*)ptr); break;
+ case SLE_VAR_STR: strcpy(buf, *(char**)ptr); break;
+ case SLE_VAR_STRQ: sprintf(buf, "\"%s\"", *(char**)ptr); break;
+ case SLE_VAR_CHAR: sprintf(buf, "\"%c\"", *(char*)ptr); break;
+ default: NOT_REACHED();
+ }
+ break;
+
+ case SDT_INTLIST:
+ make_intlist(buf, ptr, sld->length, GetVarMemType(sld->conv));
+ break;
+ default: NOT_REACHED();
+ }
+
+ /* The value is different, that means we have to write it to the ini */
+ item->value = pool_strdup(&ini->pool, buf, strlen(buf));
+ }
+}
+
+/** Loads all items from a 'grpname' section into a list
+ * The list parameter can be a NULL pointer, in this case nothing will be
+ * saved and a callback function should be defined that will take over the
+ * list-handling and store the data itself somewhere.
+ * @param IniFile handle to the ini file with the source data
+ * @param grpname character string identifying the section-header of the ini
+ * file that will be parsed
+ * @param list pointer to an string(pointer) array that will store the parsed
+ * entries of the given section
+ * @param len the maximum number of items available for the above list
+ * @param proc callback function that can override how the values are stored
+ * inside the list */
+static void ini_load_setting_list(IniFile *ini, const char *grpname, char **list, uint len, SettingListCallbackProc proc)
+{
+ IniGroup *group = ini_getgroup(ini, grpname, -1);
+ IniItem *item;
+ const char *entry;
+ uint i, j;
+
+ if (group == NULL) return;
+
+ for (i = j = 0, item = group->item; item != NULL; item = item->next) {
+ entry = (proc != NULL) ? proc(item, i++) : item->name;
+
+ if (entry == NULL || list == NULL) continue;
+
+ if (j == len) break;
+ list[j++] = strdup(entry);
+ }
+}
+
+/** Saves all items from a list into the 'grpname' section
+ * The list parameter can be a NULL pointer, in this case a callback function
+ * should be defined that will provide the source data to be saved.
+ * @param IniFile handle to the ini file where the destination data is saved
+ * @param grpname character string identifying the section-header of the ini file
+ * @param list pointer to an string(pointer) array that will be used as the
+ * source to be saved into the relevant ini section
+ * @param len the maximum number of items available for the above list
+ * @param proc callback function that can will provide the source data if defined */
+static void ini_save_setting_list(IniFile *ini, const char *grpname, char **list, uint len, SettingListCallbackProc proc)
+{
+ IniGroup *group = ini_getgroup(ini, grpname, -1);
+ IniItem *item = NULL;
+ const char *entry;
+ uint i;
+ bool first = true;
+
+ if (proc == NULL && list == NULL) return;
+ if (group == NULL) return;
+ group->item = NULL;
+
+ for (i = 0; i != len; i++) {
+ entry = (proc != NULL) ? proc(NULL, i) : list[i];
+
+ if (entry == NULL || *entry == '\0') continue;
+
+ if (first) { // add first item to the head of the group
+ item = ini_item_alloc(group, entry, strlen(entry));
+ item->value = item->name;
+ group->item = item;
+ first = false;
+ } else { // all other items are attached to the previous one
+ item->next = ini_item_alloc(group, entry, strlen(entry));
+ item = item->next;
+ item->value = item->name;
+ }
+ }
+}
+
+//***************************
+// OTTD specific INI stuff
+//***************************
+
+/** Settings-macro usage:
+ * The list might look daunting at first, but is in general easy to understand.
+ * We have two types of list:
+ * 1. SDTG_something
+ * 2. SDT_something
+ * The 'G' stands for global, so this is the one you will use for a
+ * SettingDescGlobVarList section meaning global variables. The other uses a
+ * Base/Offset and runtime variable selection mechanism, known from the saveload * convention (it also has global so it should not be hard).
+ * Of each type there are again two versions, the normal one and one prefixed
+ * with 'COND'.
+ * COND means that the setting is only valid in certain savegame versions
+ * (since patches are saved to the savegame, this bookkeeping is necessary.
+ * Now there are a lot of types. Easy ones are:
+ * - VAR: any number type, 'type' field specifies what number. eg int8 or uint32
+ * - BOOL: a boolean number type
+ * - STR: a string or character. 'type' field specifies what string. Normal, string, or quoted
+ * A bit more difficult to use are MMANY (meaning ManyOfMany) and OMANY (OneOfMany)
+ * These are actually normal numbers, only bitmasked. In MMANY several bits can
+ * be set, in the other only one.
+ * The most complex type is INTLIST. This is basically an array of numbers. If
+ * the intlist is only valid in certain savegame versions because for example
+ * it has grown in size its length cannot be automatically be calculated so
+ * use SDT(G)_CONDLISTO() meaning Old.
+ * If nothing fits you, you can use the GENERAL macros, but it exposes the
+ * internal structure somewhat so it needs a little looking. There are _NULL()
+ * macros as well, these fill up space so you can add more patches there (in
+ * place) and you DON'T have to increase the savegame version. */
+
+#define NSD_GENERAL(name, def, cmd, guiflags, min, max, interval, many, str, proc)\
+ {name, (const void*)(def), cmd, guiflags, min, max, interval, many, str, proc}
+
+/* Macros for various objects to go in the configuration file.
+ * This section is for global variables */
+#define SDTG_GENERAL(name, sdt_cmd, sle_cmd, type, flags, guiflags, var, length, def, min, max, interval, full, str, proc, from, to)\
+{NSD_GENERAL(name, def, sdt_cmd, guiflags, min, max, interval, full, str, proc), SLEG_GENERAL(sle_cmd, var, type | flags, length, from, to)}
+
+#define SDTG_CONDVAR(name, type, flags, guiflags, var, def, min, max, interval, str, proc, from, to)\
+ SDTG_GENERAL(name, SDT_NUMX, SL_VAR, type, flags, guiflags, var, 0, def, min, max, interval, NULL, str, proc, from, to)
+#define SDTG_VAR(name, type, flags, guiflags, var, def, min, max, interval, str, proc)\
+ SDTG_CONDVAR(name, type, flags, guiflags, var, def, min, max, interval, str, proc, 0, SL_MAX_VERSION)
+
+#define SDTG_CONDBOOL(name, flags, guiflags, var, def, str, proc, from, to)\
+ SDTG_GENERAL(name, SDT_BOOLX, SL_VAR, SLE_UINT8, flags, guiflags, var, 0, def, 0, 1, 0, NULL, str, proc, from, to)
+#define SDTG_BOOL(name, flags, guiflags, var, def, str, proc)\
+ SDTG_CONDBOOL(name, flags, guiflags, var, def, str, proc, 0, SL_MAX_VERSION)
+
+#define SDTG_CONDLIST(name, type, length, flags, guiflags, var, def, str, proc, from, to)\
+ SDTG_GENERAL(name, SDT_INTLIST, SL_ARR, type, flags, guiflags, var, length, def, 0, 0, 0, NULL, str, proc, from, to)
+#define SDTG_LIST(name, type, flags, guiflags, var, def, str, proc)\
+ SDTG_GENERAL(name, SDT_INTLIST, SL_ARR, type, flags, guiflags, var, lengthof(var), def, 0, 0, 0, NULL, str, proc, 0, SL_MAX_VERSION)
+
+#define SDTG_CONDSTR(name, type, length, flags, guiflags, var, def, str, proc, from, to)\
+ SDTG_GENERAL(name, SDT_STRING, SL_STR, type, flags, guiflags, var, length, def, 0, 0, 0, NULL, str, proc, from, to)
+#define SDTG_STR(name, type, flags, guiflags, var, def, str, proc)\
+ SDTG_GENERAL(name, SDT_STRING, SL_STR, type, flags, guiflags, var, lengthof(var), def, 0, 0, 0, NULL, str, proc, 0, SL_MAX_VERSION)
+
+#define SDTG_CONDOMANY(name, type, flags, guiflags, var, def, max, full, str, proc, from, to)\
+ SDTG_GENERAL(name, SDT_ONEOFMANY, SL_VAR, type, flags, guiflags, var, 0, def, 0, max, 0, full, str, proc, from, to)
+#define SDTG_OMANY(name, type, flags, guiflags, var, def, max, full, str, proc)\
+ SDTG_CONDOMANY(name, type, flags, guiflags, var, def, max full, str, proc, 0, SL_MAX_VERSION)
+
+#define SDTG_CONDMMANY(name, type, flags, guiflags, var, def, full, str, proc, from, to)\
+ SDTG_GENERAL(name, SDT_MANYOFMANY, SL_VAR, type, flags, guiflags, var, 0, def, 0, 0, 0, full, str, proc, from, to)
+#define SDTG_MMANY(name, type, flags, guiflags, var, def, full, str, proc)\
+ SDTG_CONDMMANY(name, type, flags, guiflags, var, def, full, str, proc, 0, SL_MAX_VERSION)
+
+#define SDTG_CONDNULL(length, from, to)\
+ {{"", NULL, 0, 0, 0, 0, 0, NULL, STR_NULL, NULL}, SLEG_CONDNULL(length, from, to)}
+
+#define SDTG_END() {{NULL, NULL, 0, 0, 0, 0, 0, NULL, STR_NULL, NULL}, SLEG_END()}
+
+/* Macros for various objects to go in the configuration file.
+ * This section is for structures where their various members are saved */
+#define SDT_GENERAL(name, sdt_cmd, sle_cmd, type, flags, guiflags, base, var, length, def, min, max, interval, full, str, proc, from, to)\
+ {NSD_GENERAL(name, def, sdt_cmd, guiflags, min, max, interval, full, str, proc), SLE_GENERAL(sle_cmd, base, var, type | flags, length, from, to)}
+
+#define SDT_CONDVAR(base, var, type, from, to, flags, guiflags, def, min, max, interval, str, proc)\
+ SDT_GENERAL(#var, SDT_NUMX, SL_VAR, type, flags, guiflags, base, var, 1, def, min, max, interval, NULL, str, proc, from, to)
+#define SDT_VAR(base, var, type, flags, guiflags, def, min, max, interval, str, proc)\
+ SDT_CONDVAR(base, var, type, 0, SL_MAX_VERSION, flags, guiflags, def, min, max, interval, str, proc)
+
+#define SDT_CONDBOOL(base, var, from, to, flags, guiflags, def, str, proc)\
+ SDT_GENERAL(#var, SDT_BOOLX, SL_VAR, SLE_BOOL, flags, guiflags, base, var, 1, def, 0, 1, 0, NULL, str, proc, from, to)
+#define SDT_BOOL(base, var, flags, guiflags, def, str, proc)\
+ SDT_CONDBOOL(base, var, 0, SL_MAX_VERSION, flags, guiflags, def, str, proc)
+
+#define SDT_CONDLIST(base, var, type, from, to, flags, guiflags, def, str, proc)\
+ SDT_GENERAL(#var, SDT_INTLIST, SL_ARR, type, flags, guiflags, base, var, lengthof(((base*)8)->var), def, 0, 0, 0, NULL, str, proc, from, to)
+#define SDT_LIST(base, var, type, flags, guiflags, def, str, proc)\
+ SDT_CONDLIST(base, var, type, 0, SL_MAX_VERSION, flags, guiflags, def, str, proc)
+#define SDT_CONDLISTO(base, var, length, type, from, to, flags, guiflags, def, str, proc)\
+ SDT_GENERAL(#var, SDT_INTLIST, SL_ARR, type, flags, guiflags, base, var, length, def, 0, 0, 0, NULL, str, proc, from, to)
+
+#define SDT_CONDSTR(base, var, type, from, to, flags, guiflags, def, str, proc)\
+ SDT_GENERAL(#var, SDT_STRING, SL_STR, type, flags, guiflags, base, var, lengthof(((base*)8)->var), def, 0, 0, 0, NULL, str, proc, from, to)
+#define SDT_STR(base, var, type, flags, guiflags, def, str, proc)\
+ SDT_CONDSTR(base, var, type, 0, SL_MAX_VERSION, flags, guiflags, def, str, proc)
+#define SDT_CONDSTRO(base, var, length, type, from, to, flags, def, str, proc)\
+ SDT_GENERAL(#var, SDT_STRING, SL_STR, type, flags, 0, base, var, length, def, 0, 0, NULL, str, proc, from, to)
+
+#define SDT_CONDCHR(base, var, from, to, flags, guiflags, def, str, proc)\
+ SDT_GENERAL(#var, SDT_STRING, SL_VAR, SLE_CHAR, flags, guiflags, base, var, 1, def, 0, 0, 0, NULL, str, proc, from, to)
+#define SDT_CHR(base, var, flags, guiflags, def, str, proc)\
+ SDT_CONDCHR(base, var, 0, SL_MAX_VERSION, flags, guiflags, def, str, proc)
+
+#define SDT_CONDOMANY(base, var, type, from, to, flags, guiflags, def, max, full, str, proc)\
+ SDT_GENERAL(#var, SDT_ONEOFMANY, SL_VAR, type, flags, guiflags, base, var, 1, def, 0, max, 0, full, str, proc, from, to)
+#define SDT_OMANY(base, var, type, flags, guiflags, def, max, full, str, proc)\
+ SDT_CONDOMANY(base, var, type, 0, SL_MAX_VERSION, flags, guiflags, def, max, full, str, proc)
+
+#define SDT_CONDMMANY(base, var, type, from, to, flags, guiflags, def, full, str, proc)\
+ SDT_GENERAL(#var, SDT_MANYOFMANY, SL_VAR, type, flags, guiflags, base, var, 1, def, 0, 0, 0, full, str, proc, from, to)
+#define SDT_MMANY(base, var, type, flags, guiflags, def, full, str, proc)\
+ SDT_CONDMMANY(base, var, type, 0, SL_MAX_VERSION, flags, guiflags, def, full, str, proc)
+
+#define SDT_CONDNULL(length, from, to)\
+ {{"", NULL, 0, 0, 0, 0, 0, NULL, STR_NULL, NULL}, SLE_CONDNULL(length, from, to)}
+
+#define SDT_END() {{NULL, NULL, 0, 0, 0, 0, 0, NULL, STR_NULL, NULL}, SLE_END()}
+
+/* Shortcuts for macros below. Logically if we don't save the value
+ * we also don't sync it in a network game */
+#define S SLF_SAVE_NO | SLF_NETWORK_NO
+#define NS SLF_SAVE_NO
+#define C SLF_CONFIG_NO
+#define N SLF_NETWORK_NO
+
+#define D0 SGF_0ISDISABLED
+#define NC SGF_NOCOMMA
+#define MS SGF_MULTISTRING
+#define NO SGF_NETWORK_ONLY
+#define CR SGF_CURRENCY
+
+#include "table/strings.h"
+
+/* Begin - Callback Functions for the various settings */
+#include "window.h"
+#include "gui.h"
+#include "town.h"
+#include "gfx.h"
+// virtual PositionMainToolbar function, calls the right one.
+static int32 v_PositionMainToolbar(int32 p1)
+{
+ if (_game_mode != GM_MENU) PositionMainToolbar(NULL);
+ return 0;
+}
+
+static int32 AiNew_PatchActive_Warning(int32 p1)
+{
+ if (p1 == 1) ShowErrorMessage(INVALID_STRING_ID, TEMP_AI_ACTIVATED, 0, 0);
+ return 0;
+}
+
+static int32 Ai_In_Multiplayer_Warning(int32 p1)
+{
+ if (p1 == 1) {
+ ShowErrorMessage(INVALID_STRING_ID, TEMP_AI_MULTIPLAYER, 0, 0);
+ _patches.ainew_active = true;
+ }
+ return 0;
+}
+
+static int32 PopulationInLabelActive(int32 p1)
+{
+ Town* t;
+
+ FOR_ALL_TOWNS(t) UpdateTownVirtCoord(t);
+
+ return 0;
+}
+
+static int32 RedrawScreen(int32 p1)
+{
+ MarkWholeScreenDirty();
+ return 0;
+}
+
+static int32 InValidateDetailsWindow(int32 p1)
+{
+ InvalidateWindowClasses(WC_VEHICLE_DETAILS);
+ return 0;
+}
+
+static int32 InvalidateStationBuildWindow(int32 p1)
+{
+ InvalidateWindow(WC_BUILD_STATION, 0);
+ return 0;
+}
+
+/* Check service intervals of vehicles, p1 is value of % or day based servicing */
+static int32 CheckInterval(int32 p1)
+{
+ bool warning;
+ const Patches *ptc = (_game_mode == GM_MENU) ? &_patches_newgame : &_patches;
+
+ if (p1) {
+ warning = ( (IS_INT_INSIDE(ptc->servint_trains, 5, 90+1) || ptc->servint_trains == 0) &&
+ (IS_INT_INSIDE(ptc->servint_roadveh, 5, 90+1) || ptc->servint_roadveh == 0) &&
+ (IS_INT_INSIDE(ptc->servint_aircraft, 5, 90+1) || ptc->servint_aircraft == 0) &&
+ (IS_INT_INSIDE(ptc->servint_ships, 5, 90+1) || ptc->servint_ships == 0) );
+ } else {
+ warning = ( (IS_INT_INSIDE(ptc->servint_trains, 30, 800+1) || ptc->servint_trains == 0) &&
+ (IS_INT_INSIDE(ptc->servint_roadveh, 30, 800+1) || ptc->servint_roadveh == 0) &&
+ (IS_INT_INSIDE(ptc->servint_aircraft, 30, 800+1) || ptc->servint_aircraft == 0) &&
+ (IS_INT_INSIDE(ptc->servint_ships, 30, 800+1) || ptc->servint_ships == 0) );
+ }
+
+ if (!warning)
+ ShowErrorMessage(INVALID_STRING_ID, STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE, 0, 0);
+
+ return InValidateDetailsWindow(0);
+}
+
+static int32 EngineRenewUpdate(int32 p1)
+{
+ DoCommandP(0, 0, _patches.autorenew, NULL, CMD_SET_AUTOREPLACE);
+ return 0;
+}
+
+static int32 EngineRenewMonthsUpdate(int32 p1)
+{
+ DoCommandP(0, 1, _patches.autorenew_months, NULL, CMD_SET_AUTOREPLACE);
+ return 0;
+}
+
+static int32 EngineRenewMoneyUpdate(int32 p1)
+{
+ DoCommandP(0, 2, _patches.autorenew_money, NULL, CMD_SET_AUTOREPLACE);
+ return 0;
+}
+/* End - Callback Functions */
+
+#ifndef EXTERNAL_PLAYER
+#define EXTERNAL_PLAYER "timidity"
+#endif
+
+static const SettingDesc _music_settings[] = {
+ SDT_VAR(MusicFileSettings, playlist, SLE_UINT8, S, 0, 0, 0, 5, 1, STR_NULL, NULL),
+ SDT_VAR(MusicFileSettings, music_vol, SLE_UINT8, S, 0, 128, 0, 100, 1, STR_NULL, NULL),
+ SDT_VAR(MusicFileSettings, effect_vol, SLE_UINT8, S, 0, 128, 0, 100, 1, STR_NULL, NULL),
+ SDT_LIST(MusicFileSettings, custom_1, SLE_UINT8, S, 0, NULL, STR_NULL, NULL),
+ SDT_LIST(MusicFileSettings, custom_2, SLE_UINT8, S, 0, NULL, STR_NULL, NULL),
+ SDT_BOOL(MusicFileSettings, playing, S, 0, true, STR_NULL, NULL),
+ SDT_BOOL(MusicFileSettings, shuffle, S, 0, false, STR_NULL, NULL),
+ SDT_STR(MusicFileSettings, extmidi, SLE_STRB, S, 0, EXTERNAL_PLAYER, STR_NULL, NULL),
+ SDT_END()
+};
+
+/* win32_v.c only settings */
+#ifdef WIN32
+extern bool _force_full_redraw, _double_size, _window_maximize;
+extern uint _display_hz, _fullscreen_bpp;
+
+static const SettingDescGlobVarList _win32_settings[] = {
+ SDTG_VAR("display_hz", SLE_UINT, S, 0, _display_hz, 0, 0, 120, 0, STR_NULL, NULL),
+ SDTG_BOOL("force_full_redraw", S, 0, _force_full_redraw,false, STR_NULL, NULL),
+ SDTG_VAR("fullscreen_bpp", SLE_UINT, S, 0, _fullscreen_bpp, 8, 8, 32, 0, STR_NULL, NULL),
+ SDTG_BOOL("double_size", S, 0, _double_size, false, STR_NULL, NULL),
+ SDTG_BOOL("window_maximize", S, 0, _window_maximize, false, STR_NULL, NULL),
+ SDTG_END()
+};
+#endif /* WIN32 */
+
+static const SettingDescGlobVarList _misc_settings[] = {
+ SDTG_MMANY("display_opt", SLE_UINT8, S, 0, _display_opt, (DO_SHOW_TOWN_NAMES|DO_SHOW_STATION_NAMES|DO_SHOW_SIGNS|DO_FULL_ANIMATION|DO_FULL_DETAIL|DO_TRANS_BUILDINGS|DO_WAYPOINTS), "SHOW_TOWN_NAMES|SHOW_STATION_NAMES|SHOW_SIGNS|FULL_ANIMATION|TRANS_BUILDINGS|FULL_DETAIL|WAYPOINTS", STR_NULL, NULL),
+ SDTG_VAR("news_display_opt", SLE_UINT, S, 0, _news_display_opt,0xAAAAAAAA,0,0xAAAAAAAA,0,STR_NULL, NULL), // default to all full messages: 10101010101010101010 = 0xAAAAAAAA
+ SDTG_BOOL("news_ticker_sound", S, 0, _news_ticker_sound, true, STR_NULL, NULL),
+ SDTG_BOOL("fullscreen", S, 0, _fullscreen, false, STR_NULL, NULL),
+ SDTG_STR("videodriver", SLE_STRB,C|S,0, _ini_videodriver, NULL, STR_NULL, NULL),
+ SDTG_STR("musicdriver", SLE_STRB,C|S,0, _ini_musicdriver, NULL, STR_NULL, NULL),
+ SDTG_STR("sounddriver", SLE_STRB,C|S,0, _ini_sounddriver, NULL, STR_NULL, NULL),
+ SDTG_STR("language", SLE_STRB, S, 0, _dynlang.curr_file, NULL, STR_NULL, NULL),
+ SDTG_LIST("resolution", SLE_UINT16, S, 0, _cur_resolution, "640,480", STR_NULL, NULL),
+ SDTG_STR("screenshot_format",SLE_STRB, S, 0, _screenshot_format_name,NULL, STR_NULL, NULL),
+ SDTG_STR("savegame_format", SLE_STRB, S, 0, _savegame_format, NULL, STR_NULL, NULL),
+ SDTG_BOOL("rightclick_emulate", S, 0, _rightclick_emulate, false, STR_NULL, NULL),
+#ifdef WITH_FREETYPE
+ SDTG_STR("small_font", SLE_STRB, S, 0, _freetype.small_font, NULL, STR_NULL, NULL),
+ SDTG_STR("medium_font", SLE_STRB, S, 0, _freetype.medium_font, NULL, STR_NULL, NULL),
+ SDTG_STR("large_font", SLE_STRB, S, 0, _freetype.large_font, NULL, STR_NULL, NULL),
+ SDTG_VAR("small_size", SLE_UINT, S, 0, _freetype.small_size, 6, 0, 72, 0, STR_NULL, NULL),
+ SDTG_VAR("medium_size", SLE_UINT, S, 0, _freetype.medium_size, 10, 0, 72, 0, STR_NULL, NULL),
+ SDTG_VAR("large_size", SLE_UINT, S, 0, _freetype.large_size, 16, 0, 72, 0, STR_NULL, NULL),
+#endif
+ SDTG_END()
+};
+
+#ifdef ENABLE_NETWORK
+static const SettingDescGlobVarList _network_settings[] = {
+ SDTG_VAR("sync_freq", SLE_UINT16,C|S,0, _network_sync_freq, 100, 0, 100, 0, STR_NULL, NULL),
+ SDTG_VAR("frame_freq", SLE_UINT8,C|S,0, _network_frame_freq, 0, 0, 100, 0, STR_NULL, NULL),
+ SDTG_VAR("max_join_time", SLE_UINT16, S, 0, _network_max_join_time, 500, 0, 32000, 0, STR_NULL, NULL),
+ SDTG_BOOL("pause_on_join", S, 0, _network_pause_on_join, true, STR_NULL, NULL),
+ SDTG_STR("server_bind_ip", SLE_STRB, S, 0, _network_server_bind_ip_host, "0.0.0.0", STR_NULL, NULL),
+ SDTG_VAR("server_port", SLE_UINT16, S, 0, _network_server_port, NETWORK_DEFAULT_PORT, 0, 65535, 0, STR_NULL, NULL),
+ SDTG_BOOL("server_advertise", S, 0, _network_advertise, false, STR_NULL, NULL),
+ SDTG_VAR("lan_internet", SLE_UINT8, S, 0, _network_lan_internet, 0, 0, 1, 0, STR_NULL, NULL),
+ SDTG_STR("player_name", SLE_STRB, S, 0, _network_player_name, NULL, STR_NULL, NULL),
+ SDTG_STR("server_password", SLE_STRB, S, 0, _network_server_password, NULL, STR_NULL, NULL),
+ SDTG_STR("rcon_password", SLE_STRB, S, 0, _network_rcon_password, NULL, STR_NULL, NULL),
+ SDTG_STR("server_name", SLE_STRB, S, 0, _network_server_name, NULL, STR_NULL, NULL),
+ SDTG_STR("connect_to_ip", SLE_STRB, S, 0, _network_default_ip, NULL, STR_NULL, NULL),
+ SDTG_STR("network_id", SLE_STRB, S, 0, _network_unique_id, NULL, STR_NULL, NULL),
+ SDTG_BOOL("autoclean_companies", S, 0, _network_autoclean_companies, false, STR_NULL, NULL),
+ SDTG_VAR("autoclean_unprotected",SLE_UINT8, S, 0, _network_autoclean_unprotected,12, 0, 60, 0, STR_NULL, NULL),
+ SDTG_VAR("autoclean_protected", SLE_UINT8, S, 0, _network_autoclean_protected, 36, 0, 180, 0, STR_NULL, NULL),
+ SDTG_VAR("max_companies", SLE_UINT8, S, 0, _network_game_info.companies_max, 8, 0, 8, 0, STR_NULL, NULL),
+ SDTG_VAR("max_clients", SLE_UINT8, S, 0, _network_game_info.clients_max, 10, 0, 10, 0, STR_NULL, NULL),
+ SDTG_VAR("max_spectators", SLE_UINT8, S, 0, _network_game_info.spectators_max, 10, 0, 10, 0, STR_NULL, NULL),
+ SDTG_VAR("restart_game_year", SLE_INT32, S,D0, _network_restart_game_year, 0, MIN_YEAR, MAX_YEAR, 1, STR_NULL, NULL),
+ SDTG_VAR("min_players", SLE_UINT8, S, 0, _network_min_players, 0, 0, 10, 0, STR_NULL, NULL),
+ SDTG_END()
+};
+#endif /* ENABLE_NETWORK */
+
+static const SettingDesc _gameopt_settings[] = {
+ /* In version 4 a new difficulty setting has been added to the difficulty settings,
+ * town attitude towards demolishing. Needs special handling because some dimwit thought
+ * it funny to have the GameDifficulty struct be an array while it is a struct of
+ * same-sized members
+ * XXX - To save file-space and since values are never bigger than about 10? only
+ * save the first 16 bits in the savegame. Question is why the values are still int32
+ * and why not byte for example? */
+ SDT_GENERAL("diff_custom", SDT_INTLIST, SL_ARR, (SLE_FILE_I16 | SLE_VAR_I32), 0, 0, GameOptions, diff, 17, 0, 0, 0, 0, NULL, STR_NULL, NULL, 0, 3),
+ SDT_GENERAL("diff_custom", SDT_INTLIST, SL_ARR, (SLE_FILE_I16 | SLE_VAR_I32), 0, 0, GameOptions, diff, 18, 0, 0, 0, 0, NULL, STR_NULL, NULL, 4, SL_MAX_VERSION),
+ SDT_VAR(GameOptions, diff_level,SLE_UINT8, 0, 0, 9, 0, 9, 0, STR_NULL, NULL),
+ SDT_OMANY(GameOptions, currency, SLE_UINT8, N, 0, 0, CUSTOM_CURRENCY_ID, "GBP|USD|EUR|YEN|ATS|BEF|CHF|CZK|DEM|DKK|ESP|FIM|FRF|GRD|HUF|ISK|ITL|NLG|NOK|PLN|ROL|RUR|SIT|SEK|YTL|SKK|BRR|custom", STR_NULL, NULL),
+ SDT_OMANY(GameOptions, units, SLE_UINT8, N, 0, 1, 2, "imperial|metric|si", STR_NULL, NULL),
+ SDT_OMANY(GameOptions, town_name, SLE_UINT8, 0, 0, 0, 20, "english|french|german|american|latin|silly|swedish|dutch|finnish|polish|slovakish|norwegian|hungarian|austrian|romanian|czech|swiss|danish|turkish|italian|catalan", STR_NULL, NULL),
+ SDT_OMANY(GameOptions, landscape, SLE_UINT8, 0, 0, 0, 3, "normal|hilly|desert|candy", STR_NULL, NULL),
+ SDT_VAR(GameOptions, snow_line, SLE_UINT8, 0, 0, 1, 0, 56, 0, STR_NULL, NULL),
+ SDT_CONDOMANY(GameOptions,autosave, SLE_UINT8, 0, 22, N, 0, 0, 0, "", STR_NULL, NULL),
+ SDT_CONDOMANY(GameOptions,autosave, SLE_UINT8,23, SL_MAX_VERSION, S, 0, 1, 4, "off|monthly|quarterly|half year|yearly", STR_NULL, NULL),
+ SDT_OMANY(GameOptions, road_side, SLE_UINT8, 0, 0, 1, 1, "left|right", STR_NULL, NULL),
+ SDT_END()
+};
+
+/* Some patches do not need to be synchronised when playing in multiplayer.
+ * These include for example the GUI settings and will not be saved with the
+ * savegame.
+ * It is also a bit tricky since you would think that service_interval
+ * for example doesn't need to be synched. Every client assigns the
+ * service_interval value to the v->service_interval, meaning that every client
+ * assigns his value. If the setting was player-based, that would mean that
+ * vehicles could decide on different moments that they are heading back to a
+ * service depot, causing desyncs on a massive scale. */
+const SettingDesc _patch_settings[] = {
+ /***************************************************************************/
+ /* User-interface section of the GUI-configure patches window */
+ SDT_BOOL(Patches, vehicle_speed, S, 0, true, STR_CONFIG_PATCHES_VEHICLESPEED, NULL),
+ SDT_BOOL(Patches, status_long_date, S, 0, true, STR_CONFIG_PATCHES_LONGDATE, NULL),
+ SDT_BOOL(Patches, show_finances, S, 0, true, STR_CONFIG_PATCHES_SHOWFINANCES, NULL),
+ SDT_BOOL(Patches, autoscroll, S, 0, false, STR_CONFIG_PATCHES_AUTOSCROLL, NULL),
+ SDT_BOOL(Patches, reverse_scroll, S, 0, false, STR_CONFIG_PATCHES_REVERSE_SCROLLING, NULL),
+ SDT_BOOL(Patches, measure_tooltip, S, 0, false, STR_CONFIG_PATCHES_MEASURE_TOOLTIP, NULL),
+ SDT_VAR(Patches, errmsg_duration, SLE_UINT8, S, 0, 5, 0, 20, 0, STR_CONFIG_PATCHES_ERRMSG_DURATION, NULL),
+ SDT_VAR(Patches, toolbar_pos, SLE_UINT8, S,MS, 0, 0, 2, 0, STR_CONFIG_PATCHES_TOOLBAR_POS, v_PositionMainToolbar),
+ SDT_VAR(Patches, window_snap_radius, SLE_UINT8, S,D0, 10, 1, 32, 0, STR_CONFIG_PATCHES_SNAP_RADIUS, NULL),
+ SDT_BOOL(Patches, invisible_trees, S, 0, false, STR_CONFIG_PATCHES_INVISIBLE_TREES, RedrawScreen),
+ SDT_BOOL(Patches, population_in_label, S, 0, true, STR_CONFIG_PATCHES_POPULATION_IN_LABEL, PopulationInLabelActive),
+ SDT_VAR(Patches, map_x, SLE_UINT8, S, 0, 8, 6, 11, 0, STR_CONFIG_PATCHES_MAP_X, NULL),
+ SDT_VAR(Patches, map_y, SLE_UINT8, S, 0, 8, 6, 11, 0, STR_CONFIG_PATCHES_MAP_Y, NULL),
+ SDT_BOOL(Patches, link_terraform_toolbar, S, 0, false, STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR,NULL),
+ SDT_VAR(Patches, liveries, SLE_UINT8, S,MS, 2, 0, 2, 0, STR_CONFIG_PATCHES_LIVERIES, RedrawScreen),
+ SDT_BOOL(Patches, prefer_teamchat, S, 0, false, STR_CONFIG_PATCHES_PREFER_TEAMCHAT, NULL),
+
+ /***************************************************************************/
+ /* Construction section of the GUI-configure patches window */
+ SDT_BOOL(Patches, build_on_slopes, 0, 0, true, STR_CONFIG_PATCHES_BUILDONSLOPES, NULL),
+ SDT_BOOL(Patches, extra_dynamite, 0, 0, false, STR_CONFIG_PATCHES_EXTRADYNAMITE, NULL),
+ SDT_BOOL(Patches, longbridges, 0, 0, true, STR_CONFIG_PATCHES_LONGBRIDGES, NULL),
+ SDT_BOOL(Patches, signal_side, N, 0, true, STR_CONFIG_PATCHES_SIGNALSIDE, RedrawScreen),
+ SDT_BOOL(Patches, always_small_airport, 0, 0, false, STR_CONFIG_PATCHES_SMALL_AIRPORTS, NULL),
+ SDT_VAR(Patches, drag_signals_density,SLE_UINT8,S, 0, 4, 1, 20, 0, STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY,NULL),
+
+ /***************************************************************************/
+ /* Vehicle section of the GUI-configure patches window */
+ SDT_BOOL(Patches, realistic_acceleration, 0, 0, false, STR_CONFIG_PATCHES_REALISTICACCEL, NULL),
+ SDT_BOOL(Patches, forbid_90_deg, 0, 0, false, STR_CONFIG_PATCHES_FORBID_90_DEG, NULL),
+ SDT_BOOL(Patches, mammoth_trains, 0, 0, true, STR_CONFIG_PATCHES_MAMMOTHTRAINS, NULL),
+ SDT_BOOL(Patches, gotodepot, 0, 0, true, STR_CONFIG_PATCHES_GOTODEPOT, NULL),
+ SDT_BOOL(Patches, roadveh_queue, 0, 0, true, STR_CONFIG_PATCHES_ROADVEH_QUEUE, NULL),
+ SDT_BOOL(Patches, new_pathfinding_all, 0, 0, false, STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL, NULL),
+
+ SDT_CONDBOOL(Patches, yapf.ship_use_yapf, 28, SL_MAX_VERSION, 0, 0, false, STR_CONFIG_PATCHES_YAPF_SHIPS, NULL),
+ SDT_CONDBOOL(Patches, yapf.road_use_yapf, 28, SL_MAX_VERSION, 0, 0, true, STR_CONFIG_PATCHES_YAPF_ROAD, NULL),
+ SDT_CONDBOOL(Patches, yapf.rail_use_yapf, 28, SL_MAX_VERSION, 0, 0, true, STR_CONFIG_PATCHES_YAPF_RAIL, NULL),
+
+ SDT_BOOL(Patches, train_income_warn, S, 0, true, STR_CONFIG_PATCHES_WARN_INCOME_LESS, NULL),
+ SDT_VAR(Patches, order_review_system,SLE_UINT8, S,MS, 2, 0, 2, 0, STR_CONFIG_PATCHES_ORDER_REVIEW, NULL),
+ SDT_BOOL(Patches, never_expire_vehicles, 0, 0, false, STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES,NULL),
+ SDT_BOOL(Patches, lost_train_warn, S, 0, true, STR_CONFIG_PATCHES_WARN_LOST_TRAIN, NULL),
+ SDT_BOOL(Patches, autorenew, S, 0, false, STR_CONFIG_PATCHES_AUTORENEW_VEHICLE, EngineRenewUpdate),
+ SDT_VAR(Patches, autorenew_months, SLE_INT16, S, 0, 6, -12, 12, 0, STR_CONFIG_PATCHES_AUTORENEW_MONTHS, EngineRenewMonthsUpdate),
+ SDT_VAR(Patches, autorenew_money, SLE_UINT, S,CR,100000, 0, 2000000, 0, STR_CONFIG_PATCHES_AUTORENEW_MONEY, EngineRenewMoneyUpdate),
+ SDT_VAR(Patches, max_trains, SLE_UINT16, 0, 0, 500, 0, 5000, 0, STR_CONFIG_PATCHES_MAX_TRAINS, NULL),
+ SDT_VAR(Patches, max_roadveh, SLE_UINT16, 0, 0, 500, 0, 5000, 0, STR_CONFIG_PATCHES_MAX_ROADVEH, NULL),
+ SDT_VAR(Patches, max_aircraft, SLE_UINT16, 0, 0, 200, 0, 5000, 0, STR_CONFIG_PATCHES_MAX_AIRCRAFT, NULL),
+ SDT_VAR(Patches, max_ships, SLE_UINT16, 0, 0, 300, 0, 5000, 0, STR_CONFIG_PATCHES_MAX_SHIPS, NULL),
+ SDT_BOOL(Patches, servint_ispercent, 0, 0, false, STR_CONFIG_PATCHES_SERVINT_ISPERCENT, CheckInterval),
+ SDT_VAR(Patches, servint_trains, SLE_UINT16, 0,D0, 150, 5, 800, 0, STR_CONFIG_PATCHES_SERVINT_TRAINS, InValidateDetailsWindow),
+ SDT_VAR(Patches, servint_roadveh, SLE_UINT16, 0,D0, 150, 5, 800, 0, STR_CONFIG_PATCHES_SERVINT_ROADVEH, InValidateDetailsWindow),
+ SDT_VAR(Patches, servint_ships, SLE_UINT16, 0,D0, 360, 5, 800, 0, STR_CONFIG_PATCHES_SERVINT_SHIPS, InValidateDetailsWindow),
+ SDT_VAR(Patches, servint_aircraft, SLE_UINT16, 0,D0, 100, 5, 800, 0, STR_CONFIG_PATCHES_SERVINT_AIRCRAFT, InValidateDetailsWindow),
+ SDT_BOOL(Patches, no_servicing_if_no_breakdowns, 0, 0, false, STR_CONFIG_PATCHES_NOSERVICE, NULL),
+ SDT_BOOL(Patches, wagon_speed_limits, 0, 0, true, STR_CONFIG_PATCHES_WAGONSPEEDLIMITS, NULL),
+ SDT_CONDBOOL(Patches, disable_elrails, 38, SL_MAX_VERSION, 0, 0, false, STR_CONFIG_PATCHES_DISABLE_ELRAILS, SettingsDisableElrail),
+ SDT_CONDVAR(Patches, freight_trains, SLE_UINT8, 39, SL_MAX_VERSION, 0, 0, 1, 1, 255, 1, STR_CONFIG_PATCHES_FREIGHT_TRAINS, NULL),
+
+ /***************************************************************************/
+ /* Station section of the GUI-configure patches window */
+ SDT_BOOL(Patches, join_stations, 0, 0, true, STR_CONFIG_PATCHES_JOINSTATIONS, NULL),
+ SDT_BOOL(Patches, full_load_any, 0, 0, true, STR_CONFIG_PATCHES_FULLLOADANY, NULL),
+ SDT_BOOL(Patches, improved_load, 0, 0, false, STR_CONFIG_PATCHES_IMPROVEDLOAD, NULL),
+ SDT_BOOL(Patches, selectgoods, 0, 0, true, STR_CONFIG_PATCHES_SELECTGOODS, NULL),
+ SDT_BOOL(Patches, new_nonstop, 0, 0, false, STR_CONFIG_PATCHES_NEW_NONSTOP, NULL),
+ SDT_BOOL(Patches, nonuniform_stations, 0, 0, true, STR_CONFIG_PATCHES_NONUNIFORM_STATIONS,NULL),
+ SDT_VAR(Patches, station_spread,SLE_UINT8,0, 0, 12, 4, 64, 0, STR_CONFIG_PATCHES_STATION_SPREAD, InvalidateStationBuildWindow),
+ SDT_BOOL(Patches, serviceathelipad, 0, 0, true, STR_CONFIG_PATCHES_SERVICEATHELIPAD, NULL),
+ SDT_BOOL(Patches, modified_catchment, 0, 0, true, STR_CONFIG_PATCHES_CATCHMENT, NULL),
+ SDT_CONDBOOL(Patches, gradual_loading, 40, SL_MAX_VERSION, 0, 0, true, STR_CONFIG_PATCHES_GRADUAL_LOADING, NULL),
+
+ /***************************************************************************/
+ /* Economy section of the GUI-configure patches window */
+ SDT_BOOL(Patches, inflation, 0, 0, true, STR_CONFIG_PATCHES_INFLATION, NULL),
+ SDT_BOOL(Patches, build_rawmaterial_ind, 0, 0, false, STR_CONFIG_PATCHES_BUILDXTRAIND, NULL),
+ SDT_BOOL(Patches, multiple_industry_per_town, 0, 0, false, STR_CONFIG_PATCHES_MULTIPINDTOWN, NULL),
+ SDT_BOOL(Patches, same_industry_close, 0, 0, false, STR_CONFIG_PATCHES_SAMEINDCLOSE, NULL),
+ SDT_BOOL(Patches, bribe, 0, 0, true, STR_CONFIG_PATCHES_BRIBE, NULL),
+ SDT_VAR(Patches, snow_line_height,SLE_UINT8, 0, 0, 7, 2, 13, 0, STR_CONFIG_PATCHES_SNOWLINE_HEIGHT, NULL),
+ SDT_VAR(Patches, colored_news_year,SLE_INT32, 0,NC, 2000, MIN_YEAR, MAX_YEAR, 1, STR_CONFIG_PATCHES_COLORED_NEWS_YEAR,NULL),
+ SDT_VAR(Patches, starting_year, SLE_INT32, 0,NC, 1950, MIN_YEAR, MAX_YEAR, 1, STR_CONFIG_PATCHES_STARTING_YEAR,NULL),
+ SDT_VAR(Patches, ending_year, SLE_INT32,0,NC|NO,2051, MIN_YEAR, MAX_YEAR, 1, STR_CONFIG_PATCHES_ENDING_YEAR, NULL),
+ SDT_BOOL(Patches, smooth_economy, 0, 0, true, STR_CONFIG_PATCHES_SMOOTH_ECONOMY, NULL),
+ SDT_BOOL(Patches, allow_shares, 0, 0, true, STR_CONFIG_PATCHES_ALLOW_SHARES, NULL),
+
+ /***************************************************************************/
+ /* AI section of the GUI-configure patches window */
+ SDT_BOOL(Patches, ainew_active, 0, 0, false, STR_CONFIG_PATCHES_AINEW_ACTIVE, AiNew_PatchActive_Warning),
+ SDT_BOOL(Patches, ai_in_multiplayer, 0, 0, false, STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER, Ai_In_Multiplayer_Warning),
+ SDT_BOOL(Patches, ai_disable_veh_train, 0, 0, false, STR_CONFIG_PATCHES_AI_BUILDS_TRAINS, NULL),
+ SDT_BOOL(Patches, ai_disable_veh_roadveh, 0, 0, false, STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH, NULL),
+ SDT_BOOL(Patches, ai_disable_veh_aircraft,0, 0, false, STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT,NULL),
+ SDT_BOOL(Patches, ai_disable_veh_ship, 0, 0, false, STR_CONFIG_PATCHES_AI_BUILDS_SHIPS, NULL),
+
+ /***************************************************************************/
+ /* Patches without any GUI representation */
+ SDT_BOOL(Patches, keep_all_autosave, S, 0, false, STR_NULL, NULL),
+ SDT_BOOL(Patches, autosave_on_exit, S, 0, false, STR_NULL, NULL),
+ SDT_VAR(Patches, max_num_autosaves, SLE_UINT8, S, 0, 16, 0, 255, 0, STR_NULL, NULL),
+ SDT_BOOL(Patches, bridge_pillars, S, 0, true, STR_NULL, NULL),
+ SDT_VAR(Patches, extend_vehicle_life, SLE_UINT8, 0, 0, 0, 0, 100, 0, STR_NULL, NULL),
+ SDT_BOOL(Patches, auto_euro, S, 0, true, STR_NULL, NULL),
+ SDT_VAR(Patches, dist_local_authority,SLE_UINT8, 0, 0, 20, 5, 60, 0, STR_NULL, NULL),
+ SDT_VAR(Patches, wait_oneway_signal, SLE_UINT8, 0, 0, 15, 2, 100, 0, STR_NULL, NULL),
+ SDT_VAR(Patches, wait_twoway_signal, SLE_UINT8, 0, 0, 41, 2, 100, 0, STR_NULL, NULL),
+
+ /***************************************************************************/
+ /* New Pathfinding patch settings */
+ SDT_VAR(Patches, pf_maxlength, SLE_UINT16, 0, 0, 4096, 64, 65535, 0, STR_NULL, NULL),
+ SDT_VAR(Patches, pf_maxdepth, SLE_UINT8, 0, 0, 48, 4, 255, 0, STR_NULL, NULL),
+ /* The maximum number of nodes to search */
+ SDT_VAR(Patches, npf_max_search_nodes,SLE_UINT, 0, 0, 10000, 500, 100000, 0, STR_NULL, NULL),
+
+ /* When a red signal is encountered, a small detour can be made around
+ * it. This specifically occurs when a track is doubled, in which case
+ * the detour is typically 2 tiles. It is also often used at station
+ * entrances, when there is a choice of multiple platforms. If we take
+ * a typical 4 platform station, the detour is 4 tiles. To properly
+ * support larger stations we increase this value.
+ * We want to prevent that trains that want to leave at one side of a
+ * station, leave through the other side, turn around, enter the
+ * station on another platform and exit the station on the right side
+ * again, just because the sign at the right side was red. If we take
+ * a typical 5 length station, this detour is 10 or 11 tiles (not
+ * sure), so we set the default penalty at 10 (the station tile
+ * penalty will further prevent this.
+ * We give presignal exits (and combo's) a different (larger) penalty, because
+ * we really don't want trains waiting in front of a presignal exit. */
+ SDT_VAR(Patches, npf_rail_firstred_penalty, SLE_UINT, 0, 0, (10 * NPF_TILE_LENGTH), 0, 100000, 0, STR_NULL, NULL),
+ SDT_VAR(Patches, npf_rail_firstred_exit_penalty,SLE_UINT, 0, 0, (100 * NPF_TILE_LENGTH),0, 100000, 0, STR_NULL, NULL),
+ /* This penalty is for when the last signal before the target is red.
+ * This is useful for train stations, where there are multiple
+ * platforms to choose from, which lie in different signal blocks.
+ * Every target in a occupied signal block (ie an occupied platform)
+ * will get this penalty. */
+ SDT_VAR(Patches, npf_rail_lastred_penalty, SLE_UINT, 0, 0, (10 * NPF_TILE_LENGTH), 0, 100000, 0, STR_NULL, NULL),
+ /* When a train plans a route over a station tile, this penalty is
+ * applied. We want that trains plan a route around a typical, 4x5
+ * station, which means two tiles to the right, and two tiles back to
+ * the left around it, or 5 tiles of station through it. If we assign
+ * a penalty of 1 tile for every station tile passed, the route will
+ * be around it. */
+ SDT_VAR(Patches, npf_rail_station_penalty, SLE_UINT, 0, 0, (1 * NPF_TILE_LENGTH), 0, 100000, 0, STR_NULL, NULL),
+ SDT_VAR(Patches, npf_rail_slope_penalty, SLE_UINT, 0, 0, (1 * NPF_TILE_LENGTH), 0, 100000, 0, STR_NULL, NULL),
+ /* This penalty is applied when a train makes a turn. Its value of 1 makes
+ * sure that it has a minimal impact on the pathfinding, only when two
+ * paths have equal length it will make a difference */
+ SDT_VAR(Patches, npf_rail_curve_penalty, SLE_UINT, 0, 0, 1, 0, 100000, 0, STR_NULL, NULL),
+ /* Ths penalty is applied when a vehicle reverses inside a depot (doesn't
+ * apply to ships, as they can just come out the other end). XXX: Is this a
+ * good value? */
+ SDT_VAR(Patches, npf_rail_depot_reverse_penalty,SLE_UINT, 0, 0, (NPF_TILE_LENGTH * 50), 0, 100000, 0, STR_NULL, NULL),
+ SDT_VAR(Patches, npf_buoy_penalty, SLE_UINT, 0, 0, (2 * NPF_TILE_LENGTH), 0, 100000, 0, STR_NULL, NULL),
+ /* This penalty is applied when a ship makes a turn. It is bigger than the
+ * rail curve penalty, since ships (realisticly) have more trouble with
+ * making turns */
+ SDT_VAR(Patches, npf_water_curve_penalty, SLE_UINT, 0, 0, (NPF_TILE_LENGTH / 4), 0, 100000, 0, STR_NULL, NULL),
+ /* This is the penalty for road, same as for rail. */
+ SDT_VAR(Patches, npf_road_curve_penalty, SLE_UINT, 0, 0, 1, 0, 100000, 0, STR_NULL, NULL),
+ /* This is the penalty for level crossings, for both road and rail vehicles */
+ SDT_VAR(Patches, npf_crossing_penalty, SLE_UINT, 0, 0, (3 * NPF_TILE_LENGTH), 0, 100000, 0, STR_NULL, NULL),
+
+
+ // The maximum number of nodes to search
+ SDT_CONDBOOL(Patches, yapf.disable_node_optimization , 28, SL_MAX_VERSION, 0, 0, false , STR_NULL, NULL),
+ SDT_CONDVAR (Patches, yapf.max_search_nodes , SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 10000 , 500, 1000000, 0, STR_NULL, NULL),
+ SDT_CONDBOOL(Patches, yapf.rail_firstred_twoway_eol , 28, SL_MAX_VERSION, 0, 0, true , STR_NULL, NULL),
+ SDT_CONDVAR (Patches, yapf.rail_firstred_penalty , SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 10 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
+ SDT_CONDVAR (Patches, yapf.rail_firstred_exit_penalty , SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 100 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
+ SDT_CONDVAR (Patches, yapf.rail_lastred_penalty , SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 10 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
+ SDT_CONDVAR (Patches, yapf.rail_lastred_exit_penalty , SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 100 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
+ SDT_CONDVAR (Patches, yapf.rail_station_penalty , SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 30 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
+ SDT_CONDVAR (Patches, yapf.rail_slope_penalty , SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 2 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
+ SDT_CONDVAR (Patches, yapf.rail_curve45_penalty , SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 1 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
+ SDT_CONDVAR (Patches, yapf.rail_curve90_penalty , SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 6 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
+ // This penalty is applied when a train reverses inside a depot
+ SDT_CONDVAR (Patches, yapf.rail_depot_reverse_penalty , SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 50 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
+ // This is the penalty for level crossings (for trains only)
+ SDT_CONDVAR (Patches, yapf.rail_crossing_penalty , SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 3 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
+ // look-ahead how many signals are checked
+ SDT_CONDVAR (Patches, yapf.rail_look_ahead_max_signals, SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 10 , 1, 100, 0, STR_NULL, NULL),
+ // look-ahead n-th red signal penalty polynomial: penalty = p2 * n^2 + p1 * n + p0
+ SDT_CONDVAR (Patches, yapf.rail_look_ahead_signal_p0 , SLE_INT , 28, SL_MAX_VERSION, 0, 0, 500 , -1000000, 1000000, 0, STR_NULL, NULL),
+ SDT_CONDVAR (Patches, yapf.rail_look_ahead_signal_p1 , SLE_INT , 28, SL_MAX_VERSION, 0, 0, -100 , -1000000, 1000000, 0, STR_NULL, NULL),
+ SDT_CONDVAR (Patches, yapf.rail_look_ahead_signal_p2 , SLE_INT , 28, SL_MAX_VERSION, 0, 0, 5 , -1000000, 1000000, 0, STR_NULL, NULL),
+ // penalties for too long or too short station platforms
+ SDT_CONDVAR (Patches, yapf.rail_longer_platform_penalty, SLE_UINT, 33, SL_MAX_VERSION, 0, 0, 8 * YAPF_TILE_LENGTH, 0, 20000, 0, STR_NULL, NULL),
+ SDT_CONDVAR (Patches, yapf.rail_longer_platform_per_tile_penalty, SLE_UINT, 33, SL_MAX_VERSION, 0, 0, 0 * YAPF_TILE_LENGTH, 0, 20000, 0, STR_NULL, NULL),
+ SDT_CONDVAR (Patches, yapf.rail_shorter_platform_penalty, SLE_UINT, 33, SL_MAX_VERSION, 0, 0, 40 * YAPF_TILE_LENGTH, 0, 20000, 0, STR_NULL, NULL),
+ SDT_CONDVAR (Patches, yapf.rail_shorter_platform_per_tile_penalty, SLE_UINT, 33, SL_MAX_VERSION, 0, 0, 0 * YAPF_TILE_LENGTH, 0, 20000, 0, STR_NULL, NULL),
+ // road vehicles - penalties
+ SDT_CONDVAR (Patches, yapf.road_slope_penalty , SLE_UINT, 33, SL_MAX_VERSION, 0, 0, 2 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
+ SDT_CONDVAR (Patches, yapf.road_curve_penalty , SLE_UINT, 33, SL_MAX_VERSION, 0, 0, 1 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
+ SDT_CONDVAR (Patches, yapf.road_crossing_penalty , SLE_UINT, 33, SL_MAX_VERSION, 0, 0, 3 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
+
+ /***************************************************************************/
+ /* Terrain genation related patch options */
+ SDT_CONDVAR(Patches, land_generator, SLE_UINT8, 30, SL_MAX_VERSION, 0, MS, 1, 0, 1, 0, STR_CONFIG_PATCHES_LAND_GENERATOR, NULL),
+ SDT_CONDVAR(Patches, oil_refinery_limit, SLE_UINT8, 30, SL_MAX_VERSION, 0, 0, 16, 12, 48, 0, STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE, NULL),
+ SDT_CONDVAR(Patches, tgen_smoothness, SLE_UINT8, 30, SL_MAX_VERSION, 0, MS, 1, 0, 3, 0, STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN, NULL),
+ SDT_CONDVAR(Patches, generation_seed, SLE_UINT32, 30, SL_MAX_VERSION, 0, 0, GENERATE_NEW_SEED, 0, MAX_UVALUE(uint32), 0, STR_NULL, NULL),
+ SDT_CONDVAR(Patches, tree_placer, SLE_UINT8, 30, SL_MAX_VERSION, 0, MS, 2, 0, 2, 0, STR_CONFIG_PATCHES_TREE_PLACER, NULL),
+ SDT_VAR (Patches, heightmap_rotation, SLE_UINT8, S, MS, 0, 0, 1, 0, STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION, NULL),
+ SDT_VAR (Patches, se_flat_world_height, SLE_UINT8, S, 0, 0, 0, 15, 0, STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT, NULL),
+
+ SDT_END()
+};
+
+static const SettingDesc _currency_settings[] = {
+ SDT_VAR(CurrencySpec, rate, SLE_UINT16, S, 0, 1, 0, 100, 0, STR_NULL, NULL),
+ SDT_CHR(CurrencySpec, separator, S, 0, ".", STR_NULL, NULL),
+ SDT_VAR(CurrencySpec, to_euro, SLE_INT32, S, 0, 0, 0,1000, 0, STR_NULL, NULL),
+ SDT_STR(CurrencySpec, prefix, SLE_STRBQ, S, 0, NULL, STR_NULL, NULL),
+ SDT_STR(CurrencySpec, suffix, SLE_STRBQ, S, 0, " credits", STR_NULL, NULL),
+ SDT_END()
+};
+
+/* Undefine for the shortcut macros above */
+#undef S
+#undef C
+#undef N
+
+#undef D0
+#undef NC
+#undef MS
+#undef NO
+#undef CR
+
+
+/* Load a GRF configuration from the given group name */
+static GRFConfig *GRFLoadConfig(IniFile *ini, const char *grpname, bool is_static)
+{
+ IniGroup *group = ini_getgroup(ini, grpname, -1);
+ IniItem *item;
+ GRFConfig *first = NULL;
+ GRFConfig **curr = &first;
+
+ if (group == NULL) return NULL;
+
+ for (item = group->item; item != NULL; item = item->next) {
+ GRFConfig *c = calloc(1, sizeof(*c));
+ c->filename = strdup(item->name);
+
+ /* Parse parameters */
+ if (*item->value != '\0') {
+ c->num_params = parse_intlist(item->value, (int*)c->param, lengthof(c->param));
+ if (c->num_params == (byte)-1) {
+ ShowInfoF("ini: error in array '%s'", item->name);
+ c->num_params = 0;
+ }
+ }
+
+ /* Check if item is valid */
+ if (!FillGRFDetails(c, is_static)) {
+ const char *msg;
+
+ if (HASBIT(c->flags, GCF_NOT_FOUND)) {
+ msg = "not found";
+ } else if (HASBIT(c->flags, GCF_UNSAFE)) {
+ msg = "unsafe for static use";
+ } else if (HASBIT(c->flags, GCF_SYSTEM)) {
+ msg = "system NewGRF";
+ } else {
+ msg = "unknown";
+ }
+
+ ShowInfoF("ini: ignoring invalid NewGRF '%s': %s", item->name, msg);
+ ClearGRFConfig(&c);
+ continue;
+ }
+
+ /* Mark file as static to avoid saving in savegame. */
+ if (is_static) SETBIT(c->flags, GCF_STATIC);
+
+ /* Add item to list */
+ *curr = c;
+ curr = &c->next;
+ }
+
+ return first;
+}
+
+
+/* Save a GRF configuration to the given group name */
+static void GRFSaveConfig(IniFile *ini, const char *grpname, const GRFConfig *list)
+{
+ IniGroup *group = ini_getgroup(ini, grpname, -1);
+ IniItem **item;
+ const GRFConfig *c;
+
+ if (group == NULL) return;
+ group->item = NULL;
+ item = &group->item;
+
+ for (c = list; c != NULL; c = c->next) {
+ char params[512];
+ GRFBuildParamList(params, c, lastof(params));
+
+ *item = ini_item_alloc(group, c->filename, strlen(c->filename));
+ (*item)->value = pool_strdup(&ini->pool, params, strlen(params));
+ item = &(*item)->next;
+ }
+}
+
+/* Common handler for saving/loading variables to the configuration file */
+static void HandleSettingDescs(IniFile *ini, SettingDescProc *proc, SettingDescProcList *proc_list)
+{
+ proc(ini, (const SettingDesc*)_misc_settings, "misc", NULL);
+ proc(ini, (const SettingDesc*)_music_settings, "music", &msf);
+#ifdef WIN32
+ proc(ini, (const SettingDesc*)_win32_settings, "win32", NULL);
+#endif /* WIN32 */
+
+ proc(ini, _gameopt_settings, "gameopt", &_opt_newgame);
+ proc(ini, _patch_settings, "patches", &_patches_newgame);
+ proc(ini, _currency_settings,"currency", &_custom_currency);
+
+#ifdef ENABLE_NETWORK
+ proc(ini, (const SettingDesc*)_network_settings, "network", NULL);
+ proc_list(ini, "servers", _network_host_list, lengthof(_network_host_list), NULL);
+ proc_list(ini, "bans", _network_ban_list, lengthof(_network_ban_list), NULL);
+#endif /* ENABLE_NETWORK */
+}
+
+/** Load the values from the configuration files */
+void LoadFromConfig(void)
+{
+ IniFile *ini = ini_load(_config_file);
+ HandleSettingDescs(ini, ini_load_settings, ini_load_setting_list);
+ _grfconfig_newgame = GRFLoadConfig(ini, "newgrf", false);
+ _grfconfig_static = GRFLoadConfig(ini, "newgrf-static", true);
+ ini_free(ini);
+}
+
+/** Save the values to the configuration file */
+void SaveToConfig(void)
+{
+ IniFile *ini = ini_load(_config_file);
+ HandleSettingDescs(ini, ini_save_settings, ini_save_setting_list);
+ GRFSaveConfig(ini, "newgrf", _grfconfig_newgame);
+ GRFSaveConfig(ini, "newgrf-static", _grfconfig_static);
+ ini_save(_config_file, ini);
+ ini_free(ini);
+}
+
+static const SettingDesc *GetSettingDescription(uint index)
+{
+ if (index >= lengthof(_patch_settings)) return NULL;
+ return &_patch_settings[index];
+}
+
+/** Network-safe changing of patch-settings (server-only).
+ * @param p1 the index of the patch in the SettingDesc array which identifies it
+ * @param p2 the new value for the patch
+ * The new value is properly clamped to its minimum/maximum when setting
+ * @see _patch_settings
+ */
+int32 CmdChangePatchSetting(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ const SettingDesc *sd = GetSettingDescription(p1);
+
+ if (sd == NULL) return CMD_ERROR;
+ if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ Patches *patches_ptr = (_game_mode == GM_MENU) ? &_patches_newgame : &_patches;
+ void *var = GetVariableAddress(patches_ptr, &sd->save);
+ Write_ValidateSetting(var, sd, (int32)p2);
+ if (sd->desc.proc != NULL) sd->desc.proc((int32)ReadValue(var, sd->save.conv));
+
+ InvalidateWindow(WC_GAME_OPTIONS, 0);
+ }
+
+ return 0;
+}
+
+/** Top function to save the new value of an element of the Patches struct
+ * @param index offset in the SettingDesc array of the Patches struct which
+ * identifies the patch member we want to change
+ * @param object pointer to a valid patches struct that has its settings change.
+ * This only affects patch-members that are not needed to be the same on all
+ * clients in a network game.
+ * @param value new value of the patch */
+bool SetPatchValue(uint index, const Patches *object, int32 value)
+{
+ const SettingDesc *sd = &_patch_settings[index];
+ /* If an item is player-based, we do not send it over the network
+ * (if any) to change. Also *hack*hack* we update the _newgame version
+ * of patches because changing a player-based setting in a game also
+ * changes its defaults. At least that is the convention we have chosen */
+ if (sd->save.conv & SLF_NETWORK_NO) {
+ void *var = GetVariableAddress(object, &sd->save);
+ Write_ValidateSetting(var, sd, value);
+
+ if (_game_mode != GM_MENU) {
+ void *var2 = GetVariableAddress(&_patches_newgame, &sd->save);
+ Write_ValidateSetting(var2, sd, value);
+ }
+ if (sd->desc.proc != NULL) sd->desc.proc((int32)ReadValue(var, sd->save.conv));
+ InvalidateWindow(WC_GAME_OPTIONS, 0);
+ return true;
+ }
+
+ /* send non-player-based settings over the network */
+ if (!_networking || (_networking && _network_server)) {
+ return DoCommandP(0, index, value, NULL, CMD_CHANGE_PATCH_SETTING);
+ }
+ return false;
+}
+
+const SettingDesc *GetPatchFromName(const char *name, uint *i)
+{
+ const SettingDesc *sd;
+
+ for (*i = 0, sd = _patch_settings; sd->save.cmd != SL_END; sd++, (*i)++) {
+ if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue;
+ if (strcmp(sd->desc.name, name) == 0) return sd;
+ }
+
+ return NULL;
+}
+
+/* Those 2 functions need to be here, else we have to make some stuff non-static
+ * and besides, it is also better to keep stuff like this at the same place */
+bool IConsoleSetPatchSetting(const char *name, int32 value)
+{
+ bool success;
+ uint index;
+ const SettingDesc *sd = GetPatchFromName(name, &index);
+ const Patches *patches_ptr;
+ void *ptr;
+
+ if (sd == NULL) {
+ IConsolePrintF(_icolour_warn, "'%s' is an unknown patch setting.", name);
+ return true;
+ }
+
+ patches_ptr = (_game_mode == GM_MENU) ? &_patches_newgame : &_patches;
+ ptr = GetVariableAddress(patches_ptr, &sd->save);
+
+ success = SetPatchValue(index, patches_ptr, value);
+ return success;
+}
+
+void IConsoleGetPatchSetting(const char *name)
+{
+ char value[20];
+ uint index;
+ const SettingDesc *sd = GetPatchFromName(name, &index);
+ const void *ptr;
+
+ if (sd == NULL) {
+ IConsolePrintF(_icolour_warn, "'%s' is an unknown patch setting.", name);
+ return;
+ }
+
+ ptr = GetVariableAddress((_game_mode == GM_MENU) ? &_patches_newgame : &_patches, &sd->save);
+
+ if (sd->desc.cmd == SDT_BOOLX) {
+ snprintf(value, sizeof(value), (*(bool*)ptr == 1) ? "on" : "off");
+ } else {
+ snprintf(value, sizeof(value), "%d", (int32)ReadValue(ptr, sd->save.conv));
+ }
+
+ IConsolePrintF(_icolour_warn, "Current value for '%s' is: '%s' (min: %s%d, max: %d)",
+ name, value, (sd->desc.flags & SGF_0ISDISABLED) ? "(0) " : "", sd->desc.min, sd->desc.max);
+}
+
+/** Save and load handler for patches/settings
+ * @param osd SettingDesc struct containing all information
+ * @param object can be either NULL in which case we load global variables or
+ * a pointer to a struct which is getting saved */
+static void LoadSettings(const SettingDesc *osd, void *object)
+{
+ for (; osd->save.cmd != SL_END; osd++) {
+ const SaveLoad *sld = &osd->save;
+ void *ptr = GetVariableAddress(object, sld);
+
+ if (!SlObjectMember(ptr, sld)) continue;
+ }
+}
+
+/** Loadhandler for a list of global variables
+ * @note this is actually a stub for LoadSettings with the
+ * object pointer set to NULL */
+static inline void LoadSettingsGlobList(const SettingDescGlobVarList *sdg)
+{
+ LoadSettings((const SettingDesc*)sdg, NULL);
+}
+
+/** Save and load handler for patches/settings
+ * @param osd SettingDesc struct containing all information
+ * @param object can be either NULL in which case we load global variables or
+ * a pointer to a struct which is getting saved */
+static void SaveSettings(const SettingDesc *sd, void *object)
+{
+ /* We need to write the CH_RIFF header, but unfortunately can't call
+ * SlCalcLength() because we have a different format. So do this manually */
+ const SettingDesc *i;
+ size_t length = 0;
+ for (i = sd; i->save.cmd != SL_END; i++) {
+ const void *ptr = GetVariableAddress(object, &i->save);
+ length += SlCalcObjMemberLength(ptr, &i->save);
+ }
+ SlSetLength(length);
+
+ for (i = sd; i->save.cmd != SL_END; i++) {
+ void *ptr = GetVariableAddress(object, &i->save);
+ SlObjectMember(ptr, &i->save);
+ }
+}
+
+/** Savehandler for a list of global variables
+ * @note this is actually a stub for SaveSettings with the
+ * object pointer set to NULL */
+static inline void SaveSettingsGlobList(const SettingDescGlobVarList *sdg)
+{
+ SaveSettings((const SettingDesc*)sdg, NULL);
+}
+
+static void Load_OPTS(void)
+{
+ /* Copy over default setting since some might not get loaded in
+ * a networking environment. This ensures for example that the local
+ * autosave-frequency stays when joining a network-server */
+ _opt = _opt_newgame;
+ LoadSettings(_gameopt_settings, &_opt);
+}
+
+static void Save_OPTS(void)
+{
+ SaveSettings(_gameopt_settings, &_opt);
+}
+
+static void Load_PATS(void)
+{
+ /* Copy over default setting since some might not get loaded in
+ * a networking environment. This ensures for example that the local
+ * signal_side stays when joining a network-server */
+ _patches = _patches_newgame;
+ LoadSettings(_patch_settings, &_patches);
+}
+
+static void Save_PATS(void)
+{
+ SaveSettings(_patch_settings, &_patches);
+}
+
+void CheckConfig(void)
+{
+ // fix up news_display_opt from old to new
+ int i;
+ uint32 tmp;
+ for (i = 0, tmp = _news_display_opt; i != 10; i++, tmp >>= 2) {
+ if ((tmp & 0x3) == 0x3) { // old settings
+ _news_display_opt = 0xAAAAAAAA; // set all news-messages to full 1010101010...
+ break;
+ }
+ }
+
+ // Increase old default values for pf_maxdepth and pf_maxlength
+ // to support big networks.
+ if (_patches_newgame.pf_maxdepth == 16 && _patches_newgame.pf_maxlength == 512) {
+ _patches_newgame.pf_maxdepth = 48;
+ _patches_newgame.pf_maxlength = 4096;
+ }
+}
+
+void UpdatePatches(void)
+{
+ /* Since old(er) savegames don't have any patches saved, we initialise
+ * them with the default values just as it was in the old days.
+ * Also new games need this copying-over */
+ _patches = _patches_newgame; /* backwards compatibility */
+}
+
+const ChunkHandler _setting_chunk_handlers[] = {
+ { 'OPTS', Save_OPTS, Load_OPTS, CH_RIFF},
+ { 'PATS', Save_PATS, Load_PATS, CH_RIFF | CH_LAST},
+};
+
+static bool IsSignedVarMemType(VarType vt)
+{
+ switch (GetVarMemType(vt)) {
+ case SLE_VAR_I8:
+ case SLE_VAR_I16:
+ case SLE_VAR_I32:
+ case SLE_VAR_I64:
+ return true;
+ }
+ return false;
+}
diff --git a/src/settings.h b/src/settings.h
new file mode 100644
index 000000000..0ab3ecef3
--- /dev/null
+++ b/src/settings.h
@@ -0,0 +1,77 @@
+/* $Id$ */
+
+#ifndef SETTINGS_H
+#define SETTINGS_H
+
+#include "saveload.h"
+
+/** Convention/Type of settings. This is then further specified if necessary
+ * with the SLE_ (SLE_VAR/SLE_FILE) enums in saveload.h
+ * @see VarTypes
+ * @see SettingDescBase */
+enum SettingDescType {
+ /* 4 bytes allocated a maximum of 16 types for GenericType */
+ SDT_NUMX = 0, // any number-type
+ SDT_BOOLX = 1, // a boolean number
+ SDT_ONEOFMANY = 2, // bitmasked number where only ONE bit may be set
+ SDT_MANYOFMANY = 3, // bitmasked number where MULTIPLE bits may be set
+ SDT_INTLIST = 4, // list of integers seperated by a comma ','
+ SDT_STRING = 5, // string with a pre-allocated buffer
+ /* 10 more possible primitives */
+};
+
+enum SettingGuiFlag {
+ /* 8 bytes allocated for a maximum of 8 flags
+ * Flags directing saving/loading of a variable */
+ SGF_0ISDISABLED = 1 << 0, ///< a value of zero means the feature is disabled
+ SGF_NOCOMMA = 1 << 1, ///< number without any thousand seperators (no formatting)
+ SGF_MULTISTRING = 1 << 2, ///< the value represents a limited number of string-options (internally integer)
+ SGF_NETWORK_ONLY = 1 << 3, ///< this setting only applies to network games
+ SGF_CURRENCY = 1 << 4, ///< the number represents money, so when reading value multiply by exchange rate
+ /* 3 more possible flags */
+};
+
+typedef int32 OnChange(int32 var);
+typedef byte SettingDescType;
+typedef byte SettingGuiFlag;
+
+typedef struct SettingDescBase {
+ const char *name; ///< name of the setting. Used in configuration file and for console
+ const void *def; ///< default value given when none is present
+ SettingDescType cmd; ///< various flags for the variable
+ SettingGuiFlag flags; ///< handles how a setting would show up in the GUI (text/currency, etc.)
+ int32 min, max; ///< minimum and maximum values
+ int32 interval; ///< the interval to use between settings in the 'patches' window. If interval is '0' the interval is dynamically determined
+ const char *many; ///< ONE/MANY_OF_MANY: string of possible values for this type
+ StringID str; ///< (translated) string with descriptive text; gui and console
+ OnChange *proc; ///< callback procedure for when the value is changed
+} SettingDescBase;
+
+typedef struct SettingDesc {
+ SettingDescBase desc; ///< Settings structure (going to configuration file)
+ SaveLoad save; ///< Internal structure (going to savegame, parts to config)
+} SettingDesc;
+
+/* NOTE: The only difference between SettingDesc and SettingDescGlob is
+ * that one uses global variables as a source and the other offsets
+ * in a struct which are bound to a certain variable during runtime.
+ * The only way to differentiate between these two is to check if an object
+ * has been passed to the function or not. If not, then it is a global variable
+ * and save->variable has its address, otherwise save->variable only holds the
+ * offset in a certain struct */
+typedef SettingDesc SettingDescGlobVarList;
+
+typedef enum {
+ IGT_VARIABLES = 0, ///< values of the form "landscape = hilly"
+ IGT_LIST = 1, ///< a list of values, seperated by \n and terminated by the next group block
+} IniGroupType;
+
+/** The patch values that are used for new games and/or modified in config file */
+extern Patches _patches_newgame;
+
+bool IConsoleSetPatchSetting(const char *name, int32 value);
+void IConsoleGetPatchSetting(const char *name);
+const SettingDesc *GetPatchFromName(const char *name, uint *i);
+bool SetPatchValue(uint index, const Patches *object, int32 value);
+
+#endif /* SETTINGS_H */
diff --git a/src/settings_gui.c b/src/settings_gui.c
new file mode 100644
index 000000000..f6806f424
--- /dev/null
+++ b/src/settings_gui.c
@@ -0,0 +1,1140 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "currency.h"
+#include "functions.h"
+#include "string.h"
+#include "strings.h" // XXX GetCurrentCurrencyRate()
+#include "table/sprites.h"
+#include "table/strings.h"
+#include "window.h"
+#include "gui.h"
+#include "gfx.h"
+#include "command.h"
+#include "engine.h"
+#include "screenshot.h"
+#include "newgrf.h"
+#include "network/network.h"
+#include "town.h"
+#include "variables.h"
+#include "settings.h"
+#include "vehicle.h"
+#include "date.h"
+
+static uint32 _difficulty_click_a;
+static uint32 _difficulty_click_b;
+static byte _difficulty_timeout;
+
+static const StringID _units_dropdown[] = {
+ STR_UNITS_IMPERIAL,
+ STR_UNITS_METRIC,
+ STR_UNITS_SI,
+ INVALID_STRING_ID
+};
+
+static const StringID _driveside_dropdown[] = {
+ STR_02E9_DRIVE_ON_LEFT,
+ STR_02EA_DRIVE_ON_RIGHT,
+ INVALID_STRING_ID
+};
+
+static const StringID _autosave_dropdown[] = {
+ STR_02F7_OFF,
+ STR_AUTOSAVE_1_MONTH,
+ STR_02F8_EVERY_3_MONTHS,
+ STR_02F9_EVERY_6_MONTHS,
+ STR_02FA_EVERY_12_MONTHS,
+ INVALID_STRING_ID,
+};
+
+static const StringID _designnames_dropdown[] = {
+ STR_02BE_DEFAULT,
+ STR_02BF_CUSTOM,
+ INVALID_STRING_ID
+};
+
+static StringID *BuildDynamicDropdown(StringID base, int num)
+{
+ static StringID buf[32 + 1];
+ StringID *p = buf;
+ while (--num>=0) *p++ = base++;
+ *p = INVALID_STRING_ID;
+ return buf;
+}
+
+static int GetCurRes(void)
+{
+ int i;
+
+ for (i = 0; i != _num_resolutions; i++) {
+ if (_resolutions[i][0] == _screen.width &&
+ _resolutions[i][1] == _screen.height) {
+ break;
+ }
+ }
+ return i;
+}
+
+static inline bool RoadVehiclesAreBuilt(void)
+{
+ const Vehicle* v;
+
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == VEH_Road) return true;
+ }
+ return false;
+}
+
+
+static void ShowCustCurrency(void);
+
+static void GameOptionsWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ int i;
+ StringID str = STR_02BE_DEFAULT;
+
+ SetWindowWidgetDisabledState(w, 21, !(_vehicle_design_names & 1));
+ if (!IsWindowWidgetDisabled(w, 21)) str = STR_02BF_CUSTOM;
+ SetDParam(0, str);
+ SetDParam(1, _currency_specs[_opt_ptr->currency].name);
+ SetDParam(2, STR_UNITS_IMPERIAL + _opt_ptr->units);
+ SetDParam(3, STR_02E9_DRIVE_ON_LEFT + _opt_ptr->road_side);
+ SetDParam(4, STR_TOWNNAME_ORIGINAL_ENGLISH + _opt_ptr->town_name);
+ SetDParam(5, _autosave_dropdown[_opt_ptr->autosave]);
+ SetDParam(6, SPECSTR_LANGUAGE_START + _dynlang.curr);
+ i = GetCurRes();
+ SetDParam(7, i == _num_resolutions ? STR_RES_OTHER : SPECSTR_RESOLUTION_START + i);
+ SetDParam(8, SPECSTR_SCREENSHOT_START + _cur_screenshot_format);
+ SetWindowWidgetLoweredState(w, 28, _fullscreen);
+
+ DrawWindowWidgets(w);
+ DrawString(20, 175, STR_OPTIONS_FULLSCREEN, 0); // fullscreen
+ } break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 4: case 5: /* Setup currencies dropdown */
+ ShowDropDownMenu(w, BuildCurrencyDropdown(), _opt_ptr->currency, 5, _game_mode == GM_MENU ? 0 : ~GetMaskOfAllowedCurrencies(), 0);;
+ return;
+ case 7: case 8: /* Setup distance unit dropdown */
+ ShowDropDownMenu(w, _units_dropdown, _opt_ptr->units, 8, 0, 0);
+ return;
+ case 10: case 11: { /* Setup road-side dropdown */
+ int i = 0;
+
+ /* You can only change the drive side if you are in the menu or ingame with
+ * no vehicles present. In a networking game only the server can change it */
+ if ((_game_mode != GM_MENU && RoadVehiclesAreBuilt()) || (_networking && !_network_server))
+ i = (-1) ^ (1 << _opt_ptr->road_side); // disable the other value
+
+ ShowDropDownMenu(w, _driveside_dropdown, _opt_ptr->road_side, 11, i, 0);
+ } return;
+ case 13: case 14: { /* Setup townname dropdown */
+ int i = _opt_ptr->town_name;
+ ShowDropDownMenu(w, BuildDynamicDropdown(STR_TOWNNAME_ORIGINAL_ENGLISH, SPECSTR_TOWNNAME_LAST - SPECSTR_TOWNNAME_START + 1), i, 14, (_game_mode == GM_MENU) ? 0 : (-1) ^ (1 << i), 0);
+ return;
+ }
+ case 16: case 17: /* Setup autosave dropdown */
+ ShowDropDownMenu(w, _autosave_dropdown, _opt_ptr->autosave, 17, 0, 0);
+ return;
+ case 19: case 20: /* Setup customized vehicle-names dropdown */
+ ShowDropDownMenu(w, _designnames_dropdown, (_vehicle_design_names & 1) ? 1 : 0, 20, (_vehicle_design_names & 2) ? 0 : 2, 0);
+ return;
+ case 21: /* Save customized vehicle-names to disk */
+ return;
+ case 23: case 24: /* Setup interface language dropdown */
+ ShowDropDownMenu(w, _dynlang.dropdown, _dynlang.curr, 24, 0, 0);
+ return;
+ case 26: case 27: /* Setup resolution dropdown */
+ ShowDropDownMenu(w, BuildDynamicDropdown(SPECSTR_RESOLUTION_START, _num_resolutions), GetCurRes(), 27, 0, 0);
+ return;
+ case 28: /* Click fullscreen on/off */
+ SetWindowWidgetLoweredState(w, 28, !_fullscreen);
+ ToggleFullScreen(!_fullscreen); // toggle full-screen on/off
+ SetWindowDirty(w);
+ return;
+ case 30: case 31: /* Setup screenshot format dropdown */
+ ShowDropDownMenu(w, BuildDynamicDropdown(SPECSTR_SCREENSHOT_START, _num_screenshot_formats), _cur_screenshot_format, 31, 0, 0);
+ return;
+ }
+ break;
+
+ case WE_DROPDOWN_SELECT:
+ switch (e->we.dropdown.button) {
+ case 20: /* Vehicle design names */
+ if (e->we.dropdown.index == 0) {
+ DeleteCustomEngineNames();
+ MarkWholeScreenDirty();
+ } else if (!(_vehicle_design_names & 1)) {
+ LoadCustomEngineNames();
+ MarkWholeScreenDirty();
+ }
+ break;
+ case 5: /* Currency */
+ if (e->we.dropdown.index == CUSTOM_CURRENCY_ID) ShowCustCurrency();
+ _opt_ptr->currency = e->we.dropdown.index;
+ MarkWholeScreenDirty();
+ break;
+ case 8: /* Measuring units */
+ _opt_ptr->units = e->we.dropdown.index;
+ MarkWholeScreenDirty();
+ break;
+ case 11: /* Road side */
+ if (_opt_ptr->road_side != e->we.dropdown.index) { // only change if setting changed
+ DoCommandP(0, e->we.dropdown.index, 0, NULL, CMD_SET_ROAD_DRIVE_SIDE | CMD_MSG(STR_00B4_CAN_T_DO_THIS));
+ MarkWholeScreenDirty();
+ }
+ break;
+ case 14: /* Town names */
+ if (_game_mode == GM_MENU) {
+ _opt_ptr->town_name = e->we.dropdown.index;
+ InvalidateWindow(WC_GAME_OPTIONS, 0);
+ }
+ break;
+ case 17: /* Autosave options */
+ _opt.autosave = _opt_newgame.autosave = e->we.dropdown.index;
+ SetWindowDirty(w);
+ break;
+ case 24: /* Change interface language */
+ ReadLanguagePack(e->we.dropdown.index);
+ MarkWholeScreenDirty();
+ break;
+ case 27: /* Change resolution */
+ if (e->we.dropdown.index < _num_resolutions && ChangeResInGame(_resolutions[e->we.dropdown.index][0],_resolutions[e->we.dropdown.index][1]))
+ SetWindowDirty(w);
+ break;
+ case 31: /* Change screenshot format */
+ SetScreenshotFormat(e->we.dropdown.index);
+ SetWindowDirty(w);
+ break;
+ }
+ break;
+
+ case WE_DESTROY:
+ DeleteWindowById(WC_CUSTOM_CURRENCY, 0);
+ break;
+ }
+
+}
+
+/** Change the side of the road vehicles drive on (server only).
+ * @param tile unused
+ * @param p1 the side of the road; 0 = left side and 1 = right side
+ * @param p2 unused
+ */
+int32 CmdSetRoadDriveSide(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ /* Check boundaries and you can only change this if NO vehicles have been built yet,
+ * except in the intro-menu where of course it's always possible to do so. */
+ if (p1 > 1 || (_game_mode != GM_MENU && RoadVehiclesAreBuilt())) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ _opt_ptr->road_side = p1;
+ InvalidateWindow(WC_GAME_OPTIONS,0);
+ }
+ return 0;
+}
+
+static const Widget _game_options_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 369, 0, 13, STR_00B1_GAME_OPTIONS, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 369, 14, 238, 0x0, STR_NULL},
+{ WWT_FRAME, RESIZE_NONE, 14, 10, 179, 20, 55, STR_02E0_CURRENCY_UNITS, STR_NULL},
+{ WWT_INSET, RESIZE_NONE, 14, 20, 169, 34, 45, STR_02E1, STR_02E2_CURRENCY_UNITS_SELECTION},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 158, 168, 35, 44, STR_0225, STR_02E2_CURRENCY_UNITS_SELECTION},
+{ WWT_FRAME, RESIZE_NONE, 14, 190, 359, 20, 55, STR_MEASURING_UNITS, STR_NULL},
+{ WWT_INSET, RESIZE_NONE, 14, 200, 349, 34, 45, STR_02E4, STR_MEASURING_UNITS_SELECTION},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 338, 348, 35, 44, STR_0225, STR_MEASURING_UNITS_SELECTION},
+{ WWT_FRAME, RESIZE_NONE, 14, 10, 179, 62, 97, STR_02E6_ROAD_VEHICLES, STR_NULL},
+{ WWT_INSET, RESIZE_NONE, 14, 20, 169, 76, 87, STR_02E7, STR_02E8_SELECT_SIDE_OF_ROAD_FOR},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 158, 168, 77, 86, STR_0225, STR_02E8_SELECT_SIDE_OF_ROAD_FOR},
+{ WWT_FRAME, RESIZE_NONE, 14, 190, 359, 62, 97, STR_02EB_TOWN_NAMES, STR_NULL},
+{ WWT_INSET, RESIZE_NONE, 14, 200, 349, 76, 87, STR_02EC, STR_02ED_SELECT_STYLE_OF_TOWN_NAMES},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 338, 348, 77, 86, STR_0225, STR_02ED_SELECT_STYLE_OF_TOWN_NAMES},
+{ WWT_FRAME, RESIZE_NONE, 14, 10, 179, 104, 139, STR_02F4_AUTOSAVE, STR_NULL},
+{ WWT_INSET, RESIZE_NONE, 14, 20, 169, 118, 129, STR_02F5, STR_02F6_SELECT_INTERVAL_BETWEEN},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 158, 168, 119, 128, STR_0225, STR_02F6_SELECT_INTERVAL_BETWEEN},
+
+{ WWT_FRAME, RESIZE_NONE, 14, 10, 359, 194, 228, STR_02BC_VEHICLE_DESIGN_NAMES, STR_NULL},
+{ WWT_INSET, RESIZE_NONE, 14, 20, 119, 207, 218, STR_02BD, STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 108, 118, 208, 217, STR_0225, STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 130, 349, 207, 218, STR_02C0_SAVE_CUSTOM_NAMES, STR_02C2_SAVE_CUSTOMIZED_VEHICLE},
+
+{ WWT_FRAME, RESIZE_NONE, 14, 190, 359, 104, 139, STR_OPTIONS_LANG, STR_NULL},
+{ WWT_INSET, RESIZE_NONE, 14, 200, 349, 118, 129, STR_OPTIONS_LANG_CBO, STR_OPTIONS_LANG_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 338, 348, 119, 128, STR_0225, STR_OPTIONS_LANG_TIP},
+
+{ WWT_FRAME, RESIZE_NONE, 14, 10, 179, 146, 190, STR_OPTIONS_RES, STR_NULL},
+{ WWT_INSET, RESIZE_NONE, 14, 20, 169, 160, 171, STR_OPTIONS_RES_CBO, STR_OPTIONS_RES_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 158, 168, 161, 170, STR_0225, STR_OPTIONS_RES_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 149, 169, 176, 184, STR_EMPTY, STR_OPTIONS_FULLSCREEN_TIP},
+
+{ WWT_FRAME, RESIZE_NONE, 14, 190, 359, 146, 190, STR_OPTIONS_SCREENSHOT_FORMAT, STR_NULL},
+{ WWT_INSET, RESIZE_NONE, 14, 200, 349, 160, 171, STR_OPTIONS_SCREENSHOT_FORMAT_CBO, STR_OPTIONS_SCREENSHOT_FORMAT_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 338, 348, 161, 170, STR_0225, STR_OPTIONS_SCREENSHOT_FORMAT_TIP},
+
+{ WIDGETS_END},
+};
+
+static const WindowDesc _game_options_desc = {
+ WDP_CENTER, WDP_CENTER, 370, 239,
+ WC_GAME_OPTIONS,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _game_options_widgets,
+ GameOptionsWndProc
+};
+
+
+void ShowGameOptions(void)
+{
+ DeleteWindowById(WC_GAME_OPTIONS, 0);
+ AllocateWindowDesc(&_game_options_desc);
+}
+
+typedef struct {
+ int16 min;
+ int16 max;
+ int16 step;
+ StringID str;
+} GameSettingData;
+
+static const GameSettingData _game_setting_info[] = {
+ { 0, 7, 1, STR_NULL},
+ { 0, 3, 1, STR_6830_IMMEDIATE},
+ { 0, 2, 1, STR_6816_LOW},
+ { 0, 3, 1, STR_26816_NONE},
+ {100, 500, 50, STR_NULL},
+ { 2, 4, 1, STR_NULL},
+ { 0, 2, 1, STR_6820_LOW},
+ { 0, 4, 1, STR_681B_VERY_SLOW},
+ { 0, 2, 1, STR_6820_LOW},
+ { 0, 2, 1, STR_6823_NONE},
+ { 0, 3, 1, STR_6826_X1_5},
+ { 0, 2, 1, STR_6820_LOW},
+ { 0, 3, 1, STR_682A_VERY_FLAT},
+ { 0, 3, 1, STR_VERY_LOW},
+ { 0, 1, 1, STR_682E_STEADY},
+ { 0, 1, 1, STR_6834_AT_END_OF_LINE_AND_AT_STATIONS},
+ { 0, 1, 1, STR_6836_OFF},
+ { 0, 2, 1, STR_6839_PERMISSIVE},
+};
+
+static inline bool GetBitAndShift(uint32 *b)
+{
+ uint32 x = *b;
+ *b >>= 1;
+ return HASBIT(x, 0);
+}
+
+/*
+ * A: competitors
+ * B: start time in months / 3
+ * C: town count (2 = high, 0 = low)
+ * D: industry count (3 = high, 0 = none)
+ * E: inital loan / 1000 (in GBP)
+ * F: interest rate
+ * G: running costs (0 = low, 2 = high)
+ * H: construction speed of competitors (0 = very slow, 4 = very fast)
+ * I: intelligence (0-2)
+ * J: breakdowns (0 = off, 2 = normal)
+ * K: subsidy multiplier (0 = 1.5, 3 = 4.0)
+ * L: construction cost (0-2)
+ * M: terrain type (0 = very flat, 3 = mountainous)
+ * N: amount of water (0 = very low, 3 = high)
+ * O: economy (0 = steady, 1 = fluctuating)
+ * P: Train reversing (0 = end of line + stations, 1 = end of line)
+ * Q: disasters
+ * R: area restructuring (0 = permissive, 2 = hostile)
+ */
+static const int16 _default_game_diff[3][GAME_DIFFICULTY_NUM] = { /*
+ A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R*/
+ {2, 2, 1, 3, 300, 2, 0, 2, 0, 1, 2, 0, 1, 0, 0, 0, 0, 0}, //easy
+ {4, 1, 1, 2, 150, 3, 1, 3, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1}, //medium
+ {7, 0, 2, 2, 100, 4, 1, 3, 2, 2, 0, 2, 3, 2, 1, 1, 1, 2}, //hard
+};
+
+void SetDifficultyLevel(int mode, GameOptions *gm_opt)
+{
+ int i;
+ assert(mode <= 3);
+
+ gm_opt->diff_level = mode;
+ if (mode != 3) { // not custom
+ for (i = 0; i != GAME_DIFFICULTY_NUM; i++)
+ ((int*)&gm_opt->diff)[i] = _default_game_diff[mode][i];
+ }
+}
+
+extern void StartupEconomy(void);
+
+enum {
+ GAMEDIFF_WND_TOP_OFFSET = 45,
+ GAMEDIFF_WND_ROWSIZE = 9
+};
+
+// Temporary holding place of values in the difficulty window until 'Save' is clicked
+static GameOptions _opt_mod_temp;
+// 0x383E = (1 << 13) | (1 << 12) | (1 << 11) | (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1)
+#define DIFF_INGAME_DISABLED_BUTTONS 0x383E
+
+static void GameDifficultyWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_CREATE: // Setup disabled buttons when creating window
+ /* disable all other difficulty buttons during gameplay except for 'custom' */
+ SetWindowWidgetDisabledState(w, 3, _game_mode == GM_NORMAL);
+ SetWindowWidgetDisabledState(w, 4, _game_mode == GM_NORMAL);
+ SetWindowWidgetDisabledState(w, 5, _game_mode == GM_NORMAL);
+ SetWindowWidgetDisabledState(w, 6, _game_mode == GM_NORMAL);
+ SetWindowWidgetDisabledState(w, 7, _game_mode == GM_EDITOR || _networking); // highscore chart in multiplayer
+ SetWindowWidgetDisabledState(w, 10, _networking && !_network_server); // Save-button in multiplayer (and if client)
+
+ break;
+ case WE_PAINT: {
+ uint32 click_a, click_b, disabled;
+ int i;
+ int y, value;
+
+ DrawWindowWidgets(w);
+
+ click_a = _difficulty_click_a;
+ click_b = _difficulty_click_b;
+
+ /* XXX - Disabled buttons in normal gameplay. Bitshifted for each button to see if
+ * that bit is set. If it is set, the button is disabled */
+ disabled = (_game_mode == GM_NORMAL) ? DIFF_INGAME_DISABLED_BUTTONS : 0;
+
+ y = GAMEDIFF_WND_TOP_OFFSET;
+ for (i = 0; i != GAME_DIFFICULTY_NUM; i++) {
+ DrawFrameRect( 5, y, 5 + 8, y + 8, 3, GetBitAndShift(&click_a) ? FR_LOWERED : 0);
+ DrawFrameRect(15, y, 15 + 8, y + 8, 3, GetBitAndShift(&click_b) ? FR_LOWERED : 0);
+ if (GetBitAndShift(&disabled) || (_networking && !_network_server)) {
+ int color = PALETTE_MODIFIER_GREYOUT | _colour_gradient[COLOUR_YELLOW][2];
+ GfxFillRect( 6, y + 1, 6 + 8, y + 8, color);
+ GfxFillRect(16, y + 1, 16 + 8, y + 8, color);
+ }
+
+ DrawStringCentered(10, y, STR_6819, 0);
+ DrawStringCentered(20, y, STR_681A, 0);
+
+
+ value = _game_setting_info[i].str + ((int*)&_opt_mod_temp.diff)[i];
+ if (i == 4) value *= 1000; // XXX - handle currency option
+ SetDParam(0, value);
+ DrawString(30, y, STR_6805_MAXIMUM_NO_COMPETITORS + i, 0);
+
+ y += GAMEDIFF_WND_ROWSIZE + 2; // space items apart a bit
+ }
+ } break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 8: { /* Difficulty settings widget, decode click */
+ const GameSettingData *info;
+ int x, y;
+ uint btn, dis;
+ int val;
+
+ // Don't allow clients to make any changes
+ if (_networking && !_network_server)
+ return;
+
+ x = e->we.click.pt.x - 5;
+ if (!IS_INT_INSIDE(x, 0, 21)) // Button area
+ return;
+
+ y = e->we.click.pt.y - GAMEDIFF_WND_TOP_OFFSET;
+ if (y < 0)
+ return;
+
+ // Get button from Y coord.
+ btn = y / (GAMEDIFF_WND_ROWSIZE + 2);
+ if (btn >= GAME_DIFFICULTY_NUM || y % (GAMEDIFF_WND_ROWSIZE + 2) >= 9)
+ return;
+
+ // Clicked disabled button?
+ dis = (_game_mode == GM_NORMAL) ? DIFF_INGAME_DISABLED_BUTTONS : 0;
+
+ if (HASBIT(dis, btn))
+ return;
+
+ _difficulty_timeout = 5;
+
+ val = ((int*)&_opt_mod_temp.diff)[btn];
+
+ info = &_game_setting_info[btn]; // get information about the difficulty setting
+ if (x >= 10) {
+ // Increase button clicked
+ val = min(val + info->step, info->max);
+ SETBIT(_difficulty_click_b, btn);
+ } else {
+ // Decrease button clicked
+ val = max(val - info->step, info->min);
+ SETBIT(_difficulty_click_a, btn);
+ }
+
+ // save value in temporary variable
+ ((int*)&_opt_mod_temp.diff)[btn] = val;
+ SetDifficultyLevel(3, &_opt_mod_temp); // set difficulty level to custom
+ SetWindowDirty(w);
+ } break;
+ case 3: case 4: case 5: case 6: /* Easy / Medium / Hard / Custom */
+ // temporarily change difficulty level
+ RaiseWindowWidget(w, _opt_mod_temp.diff_level + 3);
+ SetDifficultyLevel(e->we.click.widget - 3, &_opt_mod_temp);
+ LowerWindowWidget(w, _opt_mod_temp.diff_level + 3);
+ SetWindowDirty(w);
+ break;
+ case 7: /* Highscore Table */
+ ShowHighscoreTable(_opt_mod_temp.diff_level, -1);
+ break;
+ case 10: { /* Save button - save changes */
+ int btn, val;
+ for (btn = 0; btn != GAME_DIFFICULTY_NUM; btn++) {
+ val = ((int*)&_opt_mod_temp.diff)[btn];
+ // if setting has changed, change it
+ if (val != ((int*)&_opt_ptr->diff)[btn])
+ DoCommandP(0, btn, val, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
+ }
+ DoCommandP(0, -1, _opt_mod_temp.diff_level, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
+ DeleteWindow(w);
+ // If we are in the editor, we should reload the economy.
+ // This way when you load a game, the max loan and interest rate
+ // are loaded correctly.
+ if (_game_mode == GM_EDITOR)
+ StartupEconomy();
+ break;
+ }
+ case 11: /* Cancel button - close window, abandon changes */
+ DeleteWindow(w);
+ break;
+ } break;
+
+ case WE_MOUSELOOP: /* Handle the visual 'clicking' of the buttons */
+ if (_difficulty_timeout != 0 && !--_difficulty_timeout) {
+ _difficulty_click_a = 0;
+ _difficulty_click_b = 0;
+ SetWindowDirty(w);
+ }
+ break;
+ }
+}
+
+#undef DIFF_INGAME_DISABLED_BUTTONS
+
+static const Widget _game_difficulty_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 10, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 10, 11, 369, 0, 13, STR_6800_DIFFICULTY_LEVEL, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 10, 0, 369, 14, 29, 0x0, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 3, 10, 96, 16, 27, STR_6801_EASY, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 3, 97, 183, 16, 27, STR_6802_MEDIUM, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 3, 184, 270, 16, 27, STR_6803_HARD, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 3, 271, 357, 16, 27, STR_6804_CUSTOM, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 10, 0, 369, 30, 41, STR_6838_SHOW_HI_SCORE_CHART, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 10, 0, 369, 42, 262, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 10, 0, 369, 263, 278, 0x0, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 3, 105, 185, 265, 276, STR_OPTIONS_SAVE_CHANGES, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 3, 186, 266, 265, 276, STR_012E_CANCEL, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _game_difficulty_desc = {
+ WDP_CENTER, WDP_CENTER, 370, 279,
+ WC_GAME_OPTIONS,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _game_difficulty_widgets,
+ GameDifficultyWndProc
+};
+
+void ShowGameDifficulty(void)
+{
+ DeleteWindowById(WC_GAME_OPTIONS, 0);
+ /* Copy current settings (ingame or in intro) to temporary holding place
+ * change that when setting stuff, copy back on clicking 'OK' */
+ _opt_mod_temp = *_opt_ptr;
+ AllocateWindowDesc(&_game_difficulty_desc);
+}
+
+static const char *_patches_ui[] = {
+ "vehicle_speed",
+ "status_long_date",
+ "show_finances",
+ "autoscroll",
+ "reverse_scroll",
+ "errmsg_duration",
+ "toolbar_pos",
+ "measure_tooltip",
+ "window_snap_radius",
+ "invisible_trees",
+ "population_in_label",
+ "link_terraform_toolbar",
+ "liveries",
+ "prefer_teamchat",
+};
+
+static const char *_patches_construction[] = {
+ "build_on_slopes",
+ "extra_dynamite",
+ "longbridges",
+ "signal_side",
+ "always_small_airport",
+ "drag_signals_density",
+ "oil_refinery_limit",
+};
+
+static const char *_patches_stations[] = {
+ "join_stations",
+ "full_load_any",
+ "improved_load",
+ "selectgoods",
+ "new_nonstop",
+ "nonuniform_stations",
+ "station_spread",
+ "serviceathelipad",
+ "modified_catchment",
+ "gradual_loading",
+};
+
+static const char *_patches_economy[] = {
+ "inflation",
+ "build_rawmaterial_ind",
+ "multiple_industry_per_town",
+ "same_industry_close",
+ "bribe",
+ "colored_news_year",
+ "ending_year",
+ "smooth_economy",
+ "allow_shares",
+};
+
+static const char *_patches_ai[] = {
+ "ainew_active",
+ "ai_in_multiplayer",
+ "ai_disable_veh_train",
+ "ai_disable_veh_roadveh",
+ "ai_disable_veh_aircraft",
+ "ai_disable_veh_ship",
+};
+
+static const char *_patches_vehicles[] = {
+ "realistic_acceleration",
+ "forbid_90_deg",
+ "mammoth_trains",
+ "gotodepot",
+ "roadveh_queue",
+ "new_pathfinding_all",
+ "yapf.ship_use_yapf",
+ "yapf.road_use_yapf",
+ "yapf.rail_use_yapf",
+ "train_income_warn",
+ "order_review_system",
+ "never_expire_vehicles",
+ "lost_train_warn",
+ "autorenew",
+ "autorenew_months",
+ "autorenew_money",
+ "max_trains",
+ "max_roadveh",
+ "max_aircraft",
+ "max_ships",
+ "servint_ispercent",
+ "servint_trains",
+ "servint_roadveh",
+ "servint_ships",
+ "servint_aircraft",
+ "no_servicing_if_no_breakdowns",
+ "wagon_speed_limits",
+ "disable_elrails",
+ "freight_trains",
+};
+
+typedef struct PatchEntry {
+ const SettingDesc *setting;
+ uint index;
+} PatchEntry;
+
+typedef struct PatchPage {
+ const char **names;
+ PatchEntry *entries;
+ byte num;
+} PatchPage;
+
+/* PatchPage holds the categories, the number of elements in each category
+ * and (in NULL) a dynamic array of settings based on the string-representations
+ * of the settings. This way there is no worry about indeces, and such */
+static PatchPage _patches_page[] = {
+ {_patches_ui, NULL, lengthof(_patches_ui)},
+ {_patches_construction, NULL, lengthof(_patches_construction)},
+ {_patches_vehicles, NULL, lengthof(_patches_vehicles)},
+ {_patches_stations, NULL, lengthof(_patches_stations)},
+ {_patches_economy, NULL, lengthof(_patches_economy)},
+ {_patches_ai, NULL, lengthof(_patches_ai)},
+};
+
+/** The main patches window. Shows a number of categories on top and
+ * a selection of patches in that category.
+ * Uses WP(w, def_d) macro - data_1, data_2, data_3 */
+static void PatchesSelectionWndProc(Window *w, WindowEvent *e)
+{
+ static Patches *patches_ptr;
+
+ switch (e->event) {
+ case WE_CREATE: {
+ static bool first_time = true;
+
+ patches_ptr = (_game_mode == GM_MENU) ? &_patches_newgame : &_patches;
+
+ /* Build up the dynamic settings-array only once per OpenTTD session */
+ if (first_time) {
+ PatchPage *page;
+ for (page = &_patches_page[0]; page != endof(_patches_page); page++) {
+ uint i;
+
+ page->entries = malloc(page->num * sizeof(*page->entries));
+ for (i = 0; i != page->num; i++) {
+ uint index;
+ const SettingDesc *sd = GetPatchFromName(page->names[i], &index);
+ assert(sd != NULL);
+
+ page->entries[i].setting = sd;
+ page->entries[i].index = index;
+ }
+ }
+ first_time = false;
+ }
+ LowerWindowWidget(w, 4);
+ } break;
+
+ case WE_PAINT: {
+ int x, y;
+ const PatchPage *page = &_patches_page[WP(w,def_d).data_1];
+ uint i;
+
+ /* Set up selected category */
+ DrawWindowWidgets(w);
+
+ x = 5;
+ y = 47;
+ for (i = 0; i != page->num; i++) {
+ const SettingDesc *sd = page->entries[i].setting;
+ const SettingDescBase *sdb = &sd->desc;
+ const void *var = GetVariableAddress(patches_ptr, &sd->save);
+ bool editable = true;
+ bool disabled = false;
+
+ // We do not allow changes of some items when we are a client in a networkgame
+ if (!(sd->save.conv & SLF_NETWORK_NO) && _networking && !_network_server) editable = false;
+ if ((sdb->flags & SGF_NETWORK_ONLY) && !_networking) editable = false;
+
+ if (sdb->cmd == SDT_BOOLX) {
+ static const int _bool_ctabs[2][2] = {{9, 4}, {7, 6}};
+ /* Draw checkbox for boolean-value either on/off */
+ bool on = (*(bool*)var);
+
+ DrawFrameRect(x, y, x + 19, y + 8, _bool_ctabs[!!on][!!editable], on ? FR_LOWERED : 0);
+ SetDParam(0, on ? STR_CONFIG_PATCHES_ON : STR_CONFIG_PATCHES_OFF);
+ } else {
+ int32 value;
+
+ value = (int32)ReadValue(var, sd->save.conv);
+
+ /* Draw [<][>] boxes for settings of an integer-type */
+ DrawArrowButtons(x, y, 3, WP(w,def_d).data_2 - (i * 2), (editable && value != sdb->min), (editable && value != sdb->max));
+
+ disabled = (value == 0) && (sdb->flags & SGF_0ISDISABLED);
+ if (disabled) {
+ SetDParam(0, STR_CONFIG_PATCHES_DISABLED);
+ } else {
+ if (sdb->flags & SGF_CURRENCY) {
+ SetDParam(0, STR_CONFIG_PATCHES_CURRENCY);
+ } else if (sdb->flags & SGF_MULTISTRING) {
+ SetDParam(0, sdb->str + value + 1);
+ } else {
+ SetDParam(0, (sdb->flags & SGF_NOCOMMA) ? STR_CONFIG_PATCHES_INT32 : STR_7024);
+ }
+ SetDParam(1, value);
+ }
+ }
+ DrawString(30, y, (sdb->str) + disabled, 0);
+ y += 11;
+ }
+ break;
+ }
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 3: {
+ const PatchPage *page = &_patches_page[WP(w,def_d).data_1];
+ const SettingDesc *sd;
+ void *var;
+ int32 value;
+ int x, y;
+ byte btn;
+
+ y = e->we.click.pt.y - 46 - 1;
+ if (y < 0) return;
+
+ x = e->we.click.pt.x - 5;
+ if (x < 0) return;
+
+ btn = y / 11;
+ if (y % 11 > 9) return;
+ if (btn >= page->num) return;
+
+ sd = page->entries[btn].setting;
+
+ /* return if action is only active in network, or only settable by server */
+ if ((sd->desc.flags & SGF_NETWORK_ONLY) && !_networking) return;
+ if (!(sd->save.conv & SLF_NETWORK_NO) && _networking && !_network_server) return;
+
+ var = GetVariableAddress(patches_ptr, &sd->save);
+ value = (int32)ReadValue(var, sd->save.conv);
+
+ /* clicked on the icon on the left side. Either scroller or bool on/off */
+ if (x < 21) {
+ const SettingDescBase *sdb = &sd->desc;
+ int32 oldvalue = value;
+
+ switch (sdb->cmd) {
+ case SDT_BOOLX: value ^= 1; break;
+ case SDT_NUMX: {
+ /* Add a dynamic step-size to the scroller. In a maximum of
+ * 50-steps you should be able to get from min to max,
+ * unless specified otherwise in the 'interval' variable
+ * of the current patch. */
+ uint32 step = (sdb->interval == 0) ? ((sdb->max - sdb->min) / 50) : sdb->interval;
+ if (step == 0) step = 1;
+
+ // don't allow too fast scrolling
+ if ((w->flags4 & WF_TIMEOUT_MASK) > 2 << WF_TIMEOUT_SHL) {
+ _left_button_clicked = false;
+ return;
+ }
+
+ /* Increase or decrease the value and clamp it to extremes */
+ if (x >= 10) {
+ value += step;
+ if (value > sdb->max) value = sdb->max;
+ } else {
+ value -= step;
+ if (value < sdb->min) value = (sdb->flags & SGF_0ISDISABLED) ? 0 : sdb->min;
+ }
+
+ /* Set up scroller timeout */
+ if (value != oldvalue) {
+ WP(w,def_d).data_2 = btn * 2 + 1 + ((x >= 10) ? 1 : 0);
+ w->flags4 |= 5 << WF_TIMEOUT_SHL;
+ _left_button_clicked = false;
+ }
+ } break;
+ default: NOT_REACHED();
+ }
+
+ if (value != oldvalue) {
+ SetPatchValue(page->entries[btn].index, patches_ptr, value);
+ SetWindowDirty(w);
+ }
+ } else {
+ /* only open editbox for types that its sensible for */
+ if (sd->desc.cmd != SDT_BOOLX && !(sd->desc.flags & SGF_MULTISTRING)) {
+ /* Show the correct currency-translated value */
+ if (sd->desc.flags & SGF_CURRENCY) value *= _currency->rate;
+
+ WP(w,def_d).data_3 = btn;
+ SetDParam(0, value);
+ ShowQueryString(STR_CONFIG_PATCHES_INT32, STR_CONFIG_PATCHES_QUERY_CAPT, 10, 100, w, CS_NUMERAL);
+ }
+ }
+
+ break;
+ }
+ case 4: case 5: case 6: case 7: case 8: case 9:
+ RaiseWindowWidget(w, WP(w, def_d).data_1 + 4);
+ WP(w, def_d).data_1 = e->we.click.widget - 4;
+ LowerWindowWidget(w, WP(w, def_d).data_1 + 4);
+ DeleteWindowById(WC_QUERY_STRING, 0);
+ SetWindowDirty(w);
+ break;
+ }
+ break;
+
+ case WE_TIMEOUT:
+ WP(w,def_d).data_2 = 0;
+ SetWindowDirty(w);
+ break;
+
+ case WE_ON_EDIT_TEXT: {
+ if (e->we.edittext.str != NULL) {
+ const PatchEntry *pe = &_patches_page[WP(w,def_d).data_1].entries[WP(w,def_d).data_3];
+ const SettingDesc *sd = pe->setting;
+ int32 value = atoi(e->we.edittext.str);
+
+ /* Save the correct currency-translated value */
+ if (sd->desc.flags & SGF_CURRENCY) value /= _currency->rate;
+
+ SetPatchValue(pe->index, patches_ptr, value);
+ SetWindowDirty(w);
+ }
+ break;
+ }
+
+ case WE_DESTROY:
+ DeleteWindowById(WC_QUERY_STRING, 0);
+ break;
+ }
+}
+
+static const Widget _patches_selection_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 10, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 10, 11, 369, 0, 13, STR_CONFIG_PATCHES_CAPTION, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 10, 0, 369, 14, 41, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 10, 0, 369, 42, 370, 0x0, STR_NULL},
+
+{ WWT_TEXTBTN, RESIZE_NONE, 3, 10, 96, 16, 27, STR_CONFIG_PATCHES_GUI, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 3, 97, 183, 16, 27, STR_CONFIG_PATCHES_CONSTRUCTION, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 3, 184, 270, 16, 27, STR_CONFIG_PATCHES_VEHICLES, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 3, 271, 357, 16, 27, STR_CONFIG_PATCHES_STATIONS, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 3, 10, 96, 28, 39, STR_CONFIG_PATCHES_ECONOMY, STR_NULL},
+{ WWT_TEXTBTN, RESIZE_NONE, 3, 97, 183, 28, 39, STR_CONFIG_PATCHES_AI, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _patches_selection_desc = {
+ WDP_CENTER, WDP_CENTER, 370, 371,
+ WC_GAME_OPTIONS,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+ _patches_selection_widgets,
+ PatchesSelectionWndProc,
+};
+
+void ShowPatchesSelection(void)
+{
+ DeleteWindowById(WC_GAME_OPTIONS, 0);
+ AllocateWindowDesc(&_patches_selection_desc);
+}
+
+
+/**
+ * Draw [<][>] boxes.
+ * @param x the x position to draw
+ * @param y the y position to draw
+ * @param ctab the color of the buttons
+ * @param state 0 = none clicked, 1 = first clicked, 2 = second clicked
+ * @param clickable_left is the left button clickable?
+ * @param clickable_right is the right button clickable?
+ */
+void DrawArrowButtons(int x, int y, int ctab, byte state, bool clickable_left, bool clickable_right)
+{
+ int color = PALETTE_MODIFIER_GREYOUT | _colour_gradient[COLOUR_YELLOW][2];
+
+ DrawFrameRect(x, y + 1, x + 9, y + 9, ctab, (state == 1) ? FR_LOWERED : 0);
+ DrawFrameRect(x + 10, y + 1, x + 19, y + 9, ctab, (state == 2) ? FR_LOWERED : 0);
+ DrawStringCentered(x + 5, y + 1, STR_6819, 0); // [<]
+ DrawStringCentered(x + 15, y + 1, STR_681A, 0); // [>]
+
+ /* Grey out the buttons that aren't clickable */
+ if (!clickable_left)
+ GfxFillRect(x + 1, y + 1, x + 1 + 8, y + 8, color);
+ if (!clickable_right)
+ GfxFillRect(x + 11, y + 1, x + 11 + 8, y + 8, color);
+}
+
+static char _str_separator[2];
+
+static void CustCurrencyWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ int x;
+ int y = 20;
+ int clk = WP(w,def_d).data_1;
+ DrawWindowWidgets(w);
+
+ // exchange rate
+ DrawArrowButtons(10, y, 3, GB(clk, 0, 2), true, true);
+ SetDParam(0, 1);
+ SetDParam(1, 1);
+ DrawString(35, y + 1, STR_CURRENCY_EXCHANGE_RATE, 0);
+ y += 12;
+
+ // separator
+ DrawFrameRect(10, y + 1, 29, y + 9, 0, GB(clk, 2, 2) ? FR_LOWERED : 0);
+ x = DrawString(35, y + 1, STR_CURRENCY_SEPARATOR, 0);
+ DoDrawString(_str_separator, x + 4, y + 1, 6);
+ y += 12;
+
+ // prefix
+ DrawFrameRect(10, y + 1, 29, y + 9, 0, GB(clk, 4, 2) ? FR_LOWERED : 0);
+ x = DrawString(35, y + 1, STR_CURRENCY_PREFIX, 0);
+ DoDrawString(_custom_currency.prefix, x + 4, y + 1, 6);
+ y += 12;
+
+ // suffix
+ DrawFrameRect(10, y + 1, 29, y + 9, 0, GB(clk, 6, 2) ? FR_LOWERED : 0);
+ x = DrawString(35, y + 1, STR_CURRENCY_SUFFIX, 0);
+ DoDrawString(_custom_currency.suffix, x + 4, y + 1, 6);
+ y += 12;
+
+ // switch to euro
+ DrawArrowButtons(10, y, 3, GB(clk, 8, 2), true, true);
+ SetDParam(0, _custom_currency.to_euro);
+ DrawString(35, y + 1, (_custom_currency.to_euro != CF_NOEURO) ? STR_CURRENCY_SWITCH_TO_EURO : STR_CURRENCY_SWITCH_TO_EURO_NEVER, 0);
+ y += 12;
+
+ // Preview
+ y += 12;
+ SetDParam(0, 10000);
+ DrawString(35, y + 1, STR_CURRENCY_PREVIEW, 0);
+ break;
+ }
+
+ case WE_CLICK: {
+ int line = (e->we.click.pt.y - 20) / 12;
+ int len = 0;
+ int x = e->we.click.pt.x;
+ StringID str = 0;
+ CharSetFilter afilter = CS_ALPHANUMERAL;
+
+ switch (line) {
+ case 0: // rate
+ if (IS_INT_INSIDE(x, 10, 30)) { // clicked buttons
+ if (x < 20) {
+ if (_custom_currency.rate > 1) _custom_currency.rate--;
+ WP(w,def_d).data_1 = 1 << (line * 2 + 0);
+ } else {
+ if (_custom_currency.rate < 5000) _custom_currency.rate++;
+ WP(w,def_d).data_1 = 1 << (line * 2 + 1);
+ }
+ } else { // enter text
+ SetDParam(0, _custom_currency.rate);
+ str = STR_CONFIG_PATCHES_INT32;
+ len = 4;
+ afilter = CS_NUMERAL;
+ }
+ break;
+
+ case 1: // separator
+ if (IS_INT_INSIDE(x, 10, 30)) { // clicked button
+ WP(w,def_d).data_1 = 1 << (line * 2 + 1);
+ }
+ str = BindCString(_str_separator);
+ len = 1;
+ break;
+
+ case 2: // prefix
+ if (IS_INT_INSIDE(x, 10, 30)) { // clicked button
+ WP(w,def_d).data_1 = 1 << (line * 2 + 1);
+ }
+ str = BindCString(_custom_currency.prefix);
+ len = 12;
+ break;
+
+ case 3: // suffix
+ if (IS_INT_INSIDE(x, 10, 30)) { // clicked button
+ WP(w,def_d).data_1 = 1 << (line * 2 + 1);
+ }
+ str = BindCString(_custom_currency.suffix);
+ len = 12;
+ break;
+
+ case 4: // to euro
+ if (IS_INT_INSIDE(x, 10, 30)) { // clicked buttons
+ if (x < 20) {
+ _custom_currency.to_euro = (_custom_currency.to_euro <= 2000) ?
+ CF_NOEURO : _custom_currency.to_euro - 1;
+ WP(w,def_d).data_1 = 1 << (line * 2 + 0);
+ } else {
+ _custom_currency.to_euro =
+ clamp(_custom_currency.to_euro + 1, 2000, MAX_YEAR);
+ WP(w,def_d).data_1 = 1 << (line * 2 + 1);
+ }
+ } else { // enter text
+ SetDParam(0, _custom_currency.to_euro);
+ str = STR_CONFIG_PATCHES_INT32;
+ len = 4;
+ afilter = CS_NUMERAL;
+ }
+ break;
+ }
+
+ if (len != 0) {
+ WP(w, def_d).data_2 = line;
+ ShowQueryString(str, STR_CURRENCY_CHANGE_PARAMETER, len + 1, 250, w, afilter);
+ }
+
+ w->flags4 |= 5 << WF_TIMEOUT_SHL;
+ SetWindowDirty(w);
+ break;
+ }
+
+ case WE_ON_EDIT_TEXT: {
+ const char *b = e->we.edittext.str;
+
+ switch (WP(w,def_d).data_2) {
+ case 0: /* Exchange rate */
+ _custom_currency.rate = clamp(atoi(b), 1, 5000);
+ break;
+
+ case 1: /* Thousands seperator */
+ _custom_currency.separator = (b[0] == '\0') ? ' ' : b[0];
+ ttd_strlcpy(_str_separator, b, lengthof(_str_separator));
+ break;
+
+ case 2: /* Currency prefix */
+ ttd_strlcpy(_custom_currency.prefix, b, lengthof(_custom_currency.prefix));
+ break;
+
+ case 3: /* Currency suffix */
+ ttd_strlcpy(_custom_currency.suffix, b, lengthof(_custom_currency.suffix));
+ break;
+
+ case 4: { /* Year to switch to euro */
+ int val = atoi(b);
+
+ _custom_currency.to_euro =
+ (val < 2000 ? CF_NOEURO : min(val, MAX_YEAR));
+ break;
+ }
+ }
+ MarkWholeScreenDirty();
+ break;
+ }
+
+ case WE_TIMEOUT:
+ WP(w,def_d).data_1 = 0;
+ SetWindowDirty(w);
+ break;
+
+ case WE_DESTROY:
+ DeleteWindowById(WC_QUERY_STRING, 0);
+ MarkWholeScreenDirty();
+ break;
+ }
+}
+
+static const Widget _cust_currency_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 229, 0, 13, STR_CURRENCY_WINDOW, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 229, 14, 119, 0x0, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _cust_currency_desc = {
+ WDP_CENTER, WDP_CENTER, 230, 120,
+ WC_CUSTOM_CURRENCY, 0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _cust_currency_widgets,
+ CustCurrencyWndProc,
+};
+
+static void ShowCustCurrency(void)
+{
+ _str_separator[0] = _custom_currency.separator;
+ _str_separator[1] = '\0';
+
+ DeleteWindowById(WC_CUSTOM_CURRENCY, 0);
+ AllocateWindowDesc(&_cust_currency_desc);
+}
diff --git a/src/ship.h b/src/ship.h
new file mode 100644
index 000000000..4f91276ef
--- /dev/null
+++ b/src/ship.h
@@ -0,0 +1,22 @@
+/* $Id$ */
+
+#ifndef SHIP_H
+#define SHIP_H
+
+#include "vehicle.h"
+
+void CcCloneShip(bool success, TileIndex tile, uint32 p1, uint32 p2);
+void RecalcShipStuff(Vehicle *v);
+
+static inline bool IsShipInDepot(const Vehicle* v)
+{
+ assert(v->type == VEH_Ship);
+ return v->u.ship.state == 0x80;
+}
+
+static inline bool IsShipInDepotStopped(const Vehicle* v)
+{
+ return IsShipInDepot(v) && v->vehstatus & VS_STOPPED;
+}
+
+#endif /* SHIP_H */
diff --git a/src/ship_cmd.c b/src/ship_cmd.c
new file mode 100644
index 000000000..f72323915
--- /dev/null
+++ b/src/ship_cmd.c
@@ -0,0 +1,1110 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "ship.h"
+#include "table/strings.h"
+#include "functions.h"
+#include "map.h"
+#include "tile.h"
+#include "vehicle.h"
+#include "command.h"
+#include "pathfind.h"
+#include "station_map.h"
+#include "station.h"
+#include "news.h"
+#include "engine.h"
+#include "player.h"
+#include "sound.h"
+#include "npf.h"
+#include "depot.h"
+#include "vehicle_gui.h"
+#include "newgrf_engine.h"
+#include "water_map.h"
+#include "yapf/yapf.h"
+#include "debug.h"
+#include "newgrf_callbacks.h"
+#include "newgrf_text.h"
+#include "newgrf_sound.h"
+#include "date.h"
+
+static const uint16 _ship_sprites[] = {0x0E5D, 0x0E55, 0x0E65, 0x0E6D};
+static const byte _ship_sometracks[4] = {0x19, 0x16, 0x25, 0x2A};
+
+static byte GetTileShipTrackStatus(TileIndex tile)
+{
+ uint32 r = GetTileTrackStatus(tile, TRANSPORT_WATER);
+ return r | r >> 8;
+}
+
+void DrawShipEngine(int x, int y, EngineID engine, uint32 image_ormod)
+{
+ int spritenum = ShipVehInfo(engine)->image_index;
+
+ if (is_custom_sprite(spritenum)) {
+ int sprite = GetCustomVehicleIcon(engine, DIR_W);
+
+ if (sprite != 0) {
+ DrawSprite(sprite | image_ormod, x, y);
+ return;
+ }
+ spritenum = orig_ship_vehicle_info[engine - SHIP_ENGINES_INDEX].image_index;
+ }
+ DrawSprite((6 + _ship_sprites[spritenum]) | image_ormod, x, y);
+}
+
+int GetShipImage(const Vehicle* v, Direction direction)
+{
+ int spritenum = v->spritenum;
+
+ if (is_custom_sprite(spritenum)) {
+ int sprite = GetCustomVehicleSprite(v, direction);
+
+ if (sprite != 0) return sprite;
+ spritenum = orig_ship_vehicle_info[v->engine_type - SHIP_ENGINES_INDEX].image_index;
+ }
+ return _ship_sprites[spritenum] + direction;
+}
+
+static const Depot* FindClosestShipDepot(const Vehicle* v)
+{
+ const Depot* depot;
+ const Depot* best_depot = NULL;
+ uint dist;
+ uint best_dist = (uint)-1;
+ TileIndex tile;
+ TileIndex tile2 = v->tile;
+
+ if (_patches.new_pathfinding_all) {
+ NPFFoundTargetData ftd;
+ byte trackdir = GetVehicleTrackdir(v);
+ ftd = NPFRouteToDepotTrialError(v->tile, trackdir, TRANSPORT_WATER, v->owner, INVALID_RAILTYPE);
+ if (ftd.best_bird_dist == 0) {
+ best_depot = GetDepotByTile(ftd.node.tile); /* Found target */
+ } else {
+ best_depot = NULL; /* Did not find target */
+ }
+ } else {
+ FOR_ALL_DEPOTS(depot) {
+ tile = depot->xy;
+ if (IsTileDepotType(tile, TRANSPORT_WATER) && IsTileOwner(tile, v->owner)) {
+ dist = DistanceManhattan(tile, tile2);
+ if (dist < best_dist) {
+ best_dist = dist;
+ best_depot = depot;
+ }
+ }
+ }
+ }
+ return best_depot;
+}
+
+static void CheckIfShipNeedsService(Vehicle *v)
+{
+ const Depot* depot;
+
+ if (_patches.servint_ships == 0) return;
+ if (!VehicleNeedsService(v)) return;
+ if (v->vehstatus & VS_STOPPED) return;
+
+ if (v->current_order.type == OT_GOTO_DEPOT &&
+ v->current_order.flags & OF_HALT_IN_DEPOT)
+ return;
+
+ if (_patches.gotodepot && VehicleHasDepotOrders(v)) return;
+
+ if (IsShipInDepot(v)) {
+ VehicleServiceInDepot(v);
+ return;
+ }
+
+ depot = FindClosestShipDepot(v);
+
+ if (depot == NULL || DistanceManhattan(v->tile, depot->xy) > 12) {
+ if (v->current_order.type == OT_GOTO_DEPOT) {
+ v->current_order.type = OT_DUMMY;
+ v->current_order.flags = 0;
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ }
+ return;
+ }
+
+ v->current_order.type = OT_GOTO_DEPOT;
+ v->current_order.flags = OF_NON_STOP;
+ v->current_order.dest = depot->index;
+ v->dest_tile = depot->xy;
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+}
+
+void OnNewDay_Ship(Vehicle *v)
+{
+ int32 cost;
+
+ if ((++v->day_counter & 7) == 0)
+ DecreaseVehicleValue(v);
+
+ CheckVehicleBreakdown(v);
+ AgeVehicle(v);
+ CheckIfShipNeedsService(v);
+
+ CheckOrders(v);
+
+ if (v->vehstatus & VS_STOPPED) return;
+
+ cost = ShipVehInfo(v->engine_type)->running_cost * _price.ship_running / 364;
+ v->profit_this_year -= cost >> 8;
+
+ SET_EXPENSES_TYPE(EXPENSES_SHIP_RUN);
+ SubtractMoneyFromPlayerFract(v->owner, cost);
+
+ InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
+ //we need this for the profit
+ InvalidateWindowClasses(WC_SHIPS_LIST);
+}
+
+static void HandleBrokenShip(Vehicle *v)
+{
+ if (v->breakdown_ctr != 1) {
+ v->breakdown_ctr = 1;
+ v->cur_speed = 0;
+
+ if (v->breakdowns_since_last_service != 255)
+ v->breakdowns_since_last_service++;
+
+ InvalidateWindow(WC_VEHICLE_VIEW, v->index);
+ InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
+
+ if (!PlayVehicleSound(v, VSE_BREAKDOWN)) {
+ SndPlayVehicleFx((_opt.landscape != LT_CANDY) ?
+ SND_10_TRAIN_BREAKDOWN : SND_3A_COMEDY_BREAKDOWN_2, v);
+ }
+
+ if (!(v->vehstatus & VS_HIDDEN)) {
+ Vehicle *u = CreateEffectVehicleRel(v, 4, 4, 5, EV_BREAKDOWN_SMOKE);
+ if (u != NULL) u->u.special.unk0 = v->breakdown_delay * 2;
+ }
+ }
+
+ if (!(v->tick_counter & 1)) {
+ if (!--v->breakdown_delay) {
+ v->breakdown_ctr = 0;
+ InvalidateWindow(WC_VEHICLE_VIEW, v->index);
+ }
+ }
+}
+
+static void MarkShipDirty(Vehicle *v)
+{
+ v->cur_image = GetShipImage(v, v->direction);
+ MarkAllViewportsDirty(v->left_coord, v->top_coord, v->right_coord + 1, v->bottom_coord + 1);
+}
+
+static void PlayShipSound(Vehicle *v)
+{
+ if (!PlayVehicleSound(v, VSE_START)) {
+ SndPlayVehicleFx(ShipVehInfo(v->engine_type)->sfx, v);
+ }
+}
+
+static void ProcessShipOrder(Vehicle *v)
+{
+ const Order *order;
+
+ switch (v->current_order.type) {
+ case OT_GOTO_DEPOT:
+ if (!(v->current_order.flags & OF_PART_OF_ORDERS)) return;
+ if (v->current_order.flags & OF_SERVICE_IF_NEEDED &&
+ !VehicleNeedsService(v)) {
+ v->cur_order_index++;
+ }
+ break;
+
+ case OT_LOADING:
+ case OT_LEAVESTATION:
+ return;
+
+ default: break;
+ }
+
+ if (v->cur_order_index >= v->num_orders) v->cur_order_index = 0;
+
+ order = GetVehicleOrder(v, v->cur_order_index);
+
+ if (order == NULL) {
+ v->current_order.type = OT_NOTHING;
+ v->current_order.flags = 0;
+ v->dest_tile = 0;
+ return;
+ }
+
+ if (order->type == v->current_order.type &&
+ order->flags == v->current_order.flags &&
+ order->dest == v->current_order.dest)
+ return;
+
+ v->current_order = *order;
+
+ if (order->type == OT_GOTO_STATION) {
+ const Station *st;
+
+ if (order->dest == v->last_station_visited)
+ v->last_station_visited = INVALID_STATION;
+
+ st = GetStation(order->dest);
+ if (st->dock_tile != 0) {
+ v->dest_tile = TILE_ADD(st->dock_tile, ToTileIndexDiff(GetDockOffset(st->dock_tile)));
+ }
+ } else if (order->type == OT_GOTO_DEPOT) {
+ v->dest_tile = GetDepot(order->dest)->xy;
+ } else {
+ v->dest_tile = 0;
+ }
+
+ InvalidateVehicleOrder(v);
+
+ InvalidateWindowClasses(WC_SHIPS_LIST);
+}
+
+static void HandleShipLoading(Vehicle *v)
+{
+ if (v->current_order.type == OT_NOTHING) return;
+
+ if (v->current_order.type != OT_DUMMY) {
+ if (v->current_order.type != OT_LOADING) return;
+ if (--v->load_unload_time_rem) return;
+
+ if (CanFillVehicle(v) && (v->current_order.flags & OF_FULL_LOAD ||
+ (_patches.gradual_loading && !HASBIT(v->load_status, LS_LOADING_FINISHED)))) {
+ SET_EXPENSES_TYPE(EXPENSES_SHIP_INC);
+ if (LoadUnloadVehicle(v, false)) {
+ InvalidateWindow(WC_SHIPS_LIST, v->owner);
+ MarkShipDirty(v);
+ }
+ return;
+ }
+ PlayShipSound(v);
+
+ {
+ Order b = v->current_order;
+ v->current_order.type = OT_LEAVESTATION;
+ v->current_order.flags = 0;
+ if (!(b.flags & OF_NON_STOP)) return;
+ }
+ }
+
+ v->cur_order_index++;
+ InvalidateVehicleOrder(v);
+}
+
+static void UpdateShipDeltaXY(Vehicle *v, int dir)
+{
+#define MKIT(d,c,b,a) ((a&0xFF)<<24) | ((b&0xFF)<<16) | ((c&0xFF)<<8) | ((d&0xFF)<<0)
+ static const uint32 _delta_xy_table[8] = {
+ MKIT( -3, -3, 6, 6),
+ MKIT(-16, -3, 32, 6),
+ MKIT( -3, -3, 6, 6),
+ MKIT( -3, -16, 6, 32),
+ MKIT( -3, -3, 6, 6),
+ MKIT(-16, -3, 32, 6),
+ MKIT( -3, -3, 6, 6),
+ MKIT( -3, -16, 6, 32),
+ };
+#undef MKIT
+ uint32 x = _delta_xy_table[dir];
+ v->x_offs = GB(x, 0, 8);
+ v->y_offs = GB(x, 8, 8);
+ v->sprite_width = GB(x, 16, 8);
+ v->sprite_height = GB(x, 24, 8);
+}
+
+void RecalcShipStuff(Vehicle *v)
+{
+ UpdateShipDeltaXY(v, v->direction);
+ v->cur_image = GetShipImage(v, v->direction);
+ MarkShipDirty(v);
+ InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
+}
+
+static const TileIndexDiffC _ship_leave_depot_offs[] = {
+ {-1, 0},
+ { 0, -1}
+};
+
+static void CheckShipLeaveDepot(Vehicle *v)
+{
+ TileIndex tile;
+ Axis axis;
+ uint m;
+
+ if (!IsShipInDepot(v)) return;
+
+ tile = v->tile;
+ axis = GetShipDepotAxis(tile);
+
+ // Check first side
+ if (_ship_sometracks[axis] & GetTileShipTrackStatus(TILE_ADD(tile, ToTileIndexDiff(_ship_leave_depot_offs[axis])))) {
+ m = (axis == AXIS_X) ? 0x101 : 0x207;
+ // Check second side
+ } else if (_ship_sometracks[axis + 2] & GetTileShipTrackStatus(TILE_ADD(tile, -2 * ToTileIndexDiff(_ship_leave_depot_offs[axis])))) {
+ m = (axis == AXIS_X) ? 0x105 : 0x203;
+ } else {
+ return;
+ }
+ v->direction = GB(m, 0, 8);
+ v->u.ship.state = GB(m, 8, 8);
+ v->vehstatus &= ~VS_HIDDEN;
+
+ v->cur_speed = 0;
+ RecalcShipStuff(v);
+
+ PlayShipSound(v);
+ VehicleServiceInDepot(v);
+ InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
+ InvalidateWindowClasses(WC_SHIPS_LIST);
+}
+
+static bool ShipAccelerate(Vehicle *v)
+{
+ uint spd;
+ byte t;
+
+ spd = min(v->cur_speed + 1, v->max_speed);
+
+ //updates statusbar only if speed have changed to save CPU time
+ if (spd != v->cur_speed) {
+ v->cur_speed = spd;
+ if (_patches.vehicle_speed)
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ }
+
+ // Decrease somewhat when turning
+ if (!(v->direction & 1)) spd = spd * 3 / 4;
+
+ if (spd == 0) return false;
+ if ((byte)++spd == 0) return true;
+
+ v->progress = (t = v->progress) - (byte)spd;
+
+ return (t < v->progress);
+}
+
+static int32 EstimateShipCost(EngineID engine_type)
+{
+ return ShipVehInfo(engine_type)->base_cost * (_price.ship_base>>3)>>5;
+}
+
+static void ShipArrivesAt(const Vehicle* v, Station* st)
+{
+ /* Check if station was ever visited before */
+ if (!(st->had_vehicle_of_type & HVOT_SHIP)) {
+ uint32 flags;
+
+ st->had_vehicle_of_type |= HVOT_SHIP;
+
+ SetDParam(0, st->index);
+ flags = (v->owner == _local_player) ? NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ARRIVAL_PLAYER, 0) : NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ARRIVAL_OTHER, 0);
+ AddNewsItem(
+ STR_9833_CITIZENS_CELEBRATE_FIRST,
+ flags,
+ v->index,
+ 0);
+ }
+}
+
+typedef struct {
+ TileIndex skiptile;
+ TileIndex dest_coords;
+ uint best_bird_dist;
+ uint best_length;
+} PathFindShip;
+
+static bool ShipTrackFollower(TileIndex tile, PathFindShip *pfs, int track, uint length, byte *state)
+{
+ // Found dest?
+ if (tile == pfs->dest_coords) {
+ pfs->best_bird_dist = 0;
+
+ pfs->best_length = minu(pfs->best_length, length);
+ return true;
+ }
+
+ // Skip this tile in the calculation
+ if (tile != pfs->skiptile) {
+ pfs->best_bird_dist = minu(pfs->best_bird_dist, DistanceMaxPlusManhattan(pfs->dest_coords, tile));
+ }
+
+ return false;
+}
+
+static const byte _ship_search_directions[6][4] = {
+ { 0, 9, 2, 9 },
+ { 9, 1, 9, 3 },
+ { 9, 0, 3, 9 },
+ { 1, 9, 9, 2 },
+ { 3, 2, 9, 9 },
+ { 9, 9, 1, 0 },
+};
+
+static const byte _pick_shiptrack_table[6] = {1, 3, 2, 2, 0, 0};
+
+static uint FindShipTrack(Vehicle *v, TileIndex tile, int dir, uint bits, TileIndex skiptile, int *track)
+{
+ PathFindShip pfs;
+ int i, best_track;
+ uint best_bird_dist = 0;
+ uint best_length = 0;
+ uint r;
+ byte ship_dir = v->direction & 3;
+
+ pfs.dest_coords = v->dest_tile;
+ pfs.skiptile = skiptile;
+
+ best_track = -1;
+
+ do {
+ i = FIND_FIRST_BIT(bits);
+ bits = KILL_FIRST_BIT(bits);
+
+ pfs.best_bird_dist = (uint)-1;
+ pfs.best_length = (uint)-1;
+
+ FollowTrack(tile, 0x3800 | TRANSPORT_WATER, _ship_search_directions[i][dir], (TPFEnumProc*)ShipTrackFollower, NULL, &pfs);
+
+ if (best_track >= 0) {
+ if (pfs.best_bird_dist != 0) {
+ /* neither reached the destination, pick the one with the smallest bird dist */
+ if (pfs.best_bird_dist > best_bird_dist) goto bad;
+ if (pfs.best_bird_dist < best_bird_dist) goto good;
+ } else {
+ if (pfs.best_length > best_length) goto bad;
+ if (pfs.best_length < best_length) goto good;
+ }
+
+ /* if we reach this position, there's two paths of equal value so far.
+ * pick one randomly. */
+ r = GB(Random(), 0, 8);
+ if (_pick_shiptrack_table[i] == ship_dir) r += 80;
+ if (_pick_shiptrack_table[best_track] == ship_dir) r -= 80;
+ if (r <= 127) goto bad;
+ }
+good:;
+ best_track = i;
+ best_bird_dist = pfs.best_bird_dist;
+ best_length = pfs.best_length;
+bad:;
+
+ } while (bits != 0);
+
+ *track = best_track;
+ return best_bird_dist;
+}
+
+static inline NPFFoundTargetData PerfNPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailTypeMask railtypes)
+{
+
+ void* perf = NpfBeginInterval();
+ NPFFoundTargetData ret = NPFRouteToStationOrTile(tile, trackdir, target, type, owner, railtypes);
+ int t = NpfEndInterval(perf);
+ DEBUG(yapf, 4, "[NPFW] %d us - %d rounds - %d open - %d closed -- ", t, 0, _aystar_stats_open_size, _aystar_stats_closed_size);
+ return ret;
+}
+
+/* returns the track to choose on the next tile, or -1 when it's better to
+ * reverse. The tile given is the tile we are about to enter, enterdir is the
+ * direction in which we are entering the tile */
+static int ChooseShipTrack(Vehicle *v, TileIndex tile, int enterdir, uint tracks)
+{
+ assert(enterdir>=0 && enterdir<=3);
+
+ if (_patches.yapf.ship_use_yapf) {
+ Trackdir trackdir = YapfChooseShipTrack(v, tile, enterdir, tracks);
+ return (trackdir != INVALID_TRACKDIR) ? (int)TrackdirToTrack(trackdir) : -1;
+ } else if (_patches.new_pathfinding_all) {
+ NPFFindStationOrTileData fstd;
+ NPFFoundTargetData ftd;
+ TileIndex src_tile = TILE_ADD(tile, TileOffsByDiagDir(ReverseDiagDir(enterdir)));
+ byte trackdir = GetVehicleTrackdir(v);
+ assert (trackdir != 0xFF); /* Check that we are not in a depot */
+
+ NPFFillWithOrderData(&fstd, v);
+
+ ftd = PerfNPFRouteToStationOrTile(src_tile, trackdir, &fstd, TRANSPORT_WATER, v->owner, INVALID_RAILTYPE);
+
+ if (ftd.best_trackdir != 0xff) {
+ /* If ftd.best_bird_dist is 0, we found our target and ftd.best_trackdir contains
+ the direction we need to take to get there, if ftd.best_bird_dist is not 0,
+ we did not find our target, but ftd.best_trackdir contains the direction leading
+ to the tile closest to our target. */
+ return ftd.best_trackdir & 7; /* TODO: Wrapper function? */
+ } else {
+ return -1; /* Already at target, reverse? */
+ }
+ } else {
+ uint b;
+ uint tot_dist, dist;
+ int track;
+ TileIndex tile2;
+
+ tile2 = TILE_ADD(tile, -TileOffsByDiagDir(enterdir));
+ tot_dist = (uint)-1;
+
+ /* Let's find out how far it would be if we would reverse first */
+ b = GetTileShipTrackStatus(tile2) & _ship_sometracks[ReverseDiagDir(enterdir)] & v->u.ship.state;
+ if (b != 0) {
+ dist = FindShipTrack(v, tile2, ReverseDiagDir(enterdir), b, tile, &track);
+ if (dist != (uint)-1)
+ tot_dist = dist + 1;
+ }
+ /* And if we would not reverse? */
+ dist = FindShipTrack(v, tile, enterdir, tracks, 0, &track);
+ if (dist > tot_dist)
+ /* We could better reverse */
+ return -1;
+ return track;
+ }
+}
+
+static const Direction _new_vehicle_direction_table[] = {
+ DIR_N , DIR_NW, DIR_W , 0,
+ DIR_NE, DIR_N , DIR_SW, 0,
+ DIR_E , DIR_SE, DIR_S
+};
+
+static int ShipGetNewDirectionFromTiles(TileIndex new_tile, TileIndex old_tile)
+{
+ uint offs = (TileY(new_tile) - TileY(old_tile) + 1) * 4 +
+ TileX(new_tile) - TileX(old_tile) + 1;
+ assert(offs < 11 && offs != 3 && offs != 7);
+ return _new_vehicle_direction_table[offs];
+}
+
+static int ShipGetNewDirection(Vehicle *v, int x, int y)
+{
+ uint offs = (y - v->y_pos + 1) * 4 + (x - v->x_pos + 1);
+ assert(offs < 11 && offs != 3 && offs != 7);
+ return _new_vehicle_direction_table[offs];
+}
+
+static int GetAvailShipTracks(TileIndex tile, int dir)
+{
+ uint32 r = GetTileTrackStatus(tile, TRANSPORT_WATER);
+ return (byte) ((r | r >> 8)) & _ship_sometracks[dir];
+}
+
+static const byte _ship_subcoord[4][6][3] = {
+ {
+ {15, 8, 1},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ {15, 8, 2},
+ {15, 7, 0},
+ { 0, 0, 0},
+ },
+ {
+ { 0, 0, 0},
+ { 8, 0, 3},
+ { 7, 0, 2},
+ { 0, 0, 0},
+ { 8, 0, 4},
+ { 0, 0, 0},
+ },
+ {
+ { 0, 8, 5},
+ { 0, 0, 0},
+ { 0, 7, 6},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 8, 4},
+ },
+ {
+ { 0, 0, 0},
+ { 8,15, 7},
+ { 0, 0, 0},
+ { 8,15, 6},
+ { 0, 0, 0},
+ { 7,15, 0},
+ }
+};
+
+static void ShipController(Vehicle *v)
+{
+ GetNewVehiclePosResult gp;
+ uint32 r;
+ const byte *b;
+ Direction dir;
+ int track;
+ int tracks;
+
+ v->tick_counter++;
+
+ if (v->breakdown_ctr != 0) {
+ if (v->breakdown_ctr <= 2) {
+ HandleBrokenShip(v);
+ return;
+ }
+ v->breakdown_ctr--;
+ }
+
+ if (v->vehstatus & VS_STOPPED) return;
+
+ ProcessShipOrder(v);
+ HandleShipLoading(v);
+
+ if (v->current_order.type == OT_LOADING) return;
+
+ CheckShipLeaveDepot(v);
+
+ if (!ShipAccelerate(v)) return;
+
+ BeginVehicleMove(v);
+
+ if (GetNewVehiclePos(v, &gp)) {
+ // staying in tile
+ if (IsShipInDepot(v)) {
+ gp.x = v->x_pos;
+ gp.y = v->y_pos;
+ } else {
+ /* isnot inside depot */
+ r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
+ if (r & 0x8) goto reverse_direction;
+
+ /* A leave station order only needs one tick to get processed, so we can
+ * always skip ahead. */
+ if (v->current_order.type == OT_LEAVESTATION) {
+ v->current_order.type = OT_NOTHING;
+ v->current_order.flags = 0;
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ } else if (v->dest_tile != 0) {
+ /* We have a target, let's see if we reached it... */
+ if (v->current_order.type == OT_GOTO_STATION &&
+ IsBuoyTile(v->dest_tile) &&
+ DistanceManhattan(v->dest_tile, gp.new_tile) <= 3) {
+ /* We got within 3 tiles of our target buoy, so let's skip to our
+ * next order */
+ v->cur_order_index++;
+ v->current_order.type = OT_DUMMY;
+ InvalidateVehicleOrder(v);
+ } else {
+ /* Non-buoy orders really need to reach the tile */
+ if (v->dest_tile == gp.new_tile) {
+ if (v->current_order.type == OT_GOTO_DEPOT) {
+ if ((gp.x&0xF)==8 && (gp.y&0xF)==8) {
+ VehicleEnterDepot(v);
+ return;
+ }
+ } else if (v->current_order.type == OT_GOTO_STATION) {
+ Station *st;
+
+ v->last_station_visited = v->current_order.dest;
+
+ /* Process station in the orderlist. */
+ st = GetStation(v->current_order.dest);
+ if (st->facilities & FACIL_DOCK) { /* ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations */
+ v->current_order.type = OT_LOADING;
+ v->current_order.flags &= OF_FULL_LOAD | OF_UNLOAD | OF_TRANSFER;
+ v->current_order.flags |= OF_NON_STOP;
+ ShipArrivesAt(v, st);
+
+ SET_EXPENSES_TYPE(EXPENSES_SHIP_INC);
+ if (LoadUnloadVehicle(v, true)) {
+ InvalidateWindow(WC_SHIPS_LIST, v->owner);
+ MarkShipDirty(v);
+ }
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ } else { /* leave stations without docks right aways */
+ v->current_order.type = OT_LEAVESTATION;
+ v->current_order.flags = 0;
+ v->cur_order_index++;
+ InvalidateVehicleOrder(v);
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ DiagDirection diagdir;
+ // new tile
+ if (TileX(gp.new_tile) >= MapMaxX() || TileY(gp.new_tile) >= MapMaxY())
+ goto reverse_direction;
+
+ dir = ShipGetNewDirectionFromTiles(gp.new_tile, gp.old_tile);
+ assert(dir == DIR_NE || dir == DIR_SE || dir == DIR_SW || dir == DIR_NW);
+ diagdir = DirToDiagDir(dir);
+ tracks = GetAvailShipTracks(gp.new_tile, diagdir);
+ if (tracks == 0)
+ goto reverse_direction;
+
+ // Choose a direction, and continue if we find one
+ track = ChooseShipTrack(v, gp.new_tile, diagdir, tracks);
+ if (track < 0)
+ goto reverse_direction;
+
+ b = _ship_subcoord[diagdir][track];
+
+ gp.x = (gp.x&~0xF) | b[0];
+ gp.y = (gp.y&~0xF) | b[1];
+
+ /* Call the landscape function and tell it that the vehicle entered the tile */
+ r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
+ if (r&0x8) goto reverse_direction;
+
+ if (!(r&0x4)) {
+ v->tile = gp.new_tile;
+ v->u.ship.state = 1 << track;
+ }
+
+ v->direction = b[2];
+ }
+
+ /* update image of ship, as well as delta XY */
+ dir = ShipGetNewDirection(v, gp.x, gp.y);
+ v->x_pos = gp.x;
+ v->y_pos = gp.y;
+ v->z_pos = GetSlopeZ(gp.x, gp.y);
+
+getout:
+ UpdateShipDeltaXY(v, dir);
+ v->cur_image = GetShipImage(v, dir);
+ VehiclePositionChanged(v);
+ EndVehicleMove(v);
+ return;
+
+reverse_direction:
+ dir = ReverseDir(v->direction);
+ v->direction = dir;
+ goto getout;
+}
+
+static void AgeShipCargo(Vehicle *v)
+{
+ if (_age_cargo_skip_counter != 0) return;
+ if (v->cargo_days != 255) v->cargo_days++;
+}
+
+void Ship_Tick(Vehicle *v)
+{
+ AgeShipCargo(v);
+ ShipController(v);
+}
+
+
+void ShipsYearlyLoop(void)
+{
+ Vehicle *v;
+
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == VEH_Ship) {
+ v->profit_last_year = v->profit_this_year;
+ v->profit_this_year = 0;
+ InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
+ }
+ }
+}
+
+/** Build a ship.
+ * @param tile tile of depot where ship is built
+ * @param p1 ship type being built (engine)
+ * @param p2 bit 0 when set, the unitnumber will be 0, otherwise it will be a free number
+ */
+int32 CmdBuildShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ int32 value;
+ Vehicle *v;
+ UnitID unit_num;
+ Engine *e;
+
+ if (!IsEngineBuildable(p1, VEH_Ship, _current_player)) return_cmd_error(STR_ENGINE_NOT_BUILDABLE);
+
+ SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
+
+ value = EstimateShipCost(p1);
+ if (flags & DC_QUERY_COST) return value;
+
+ /* The ai_new queries the vehicle cost before building the route,
+ * so we must check against cheaters no sooner than now. --pasky */
+ if (!IsTileDepotType(tile, TRANSPORT_WATER)) return CMD_ERROR;
+ if (!IsTileOwner(tile, _current_player)) return CMD_ERROR;
+
+ v = AllocateVehicle();
+ unit_num = HASBIT(p2, 0) ? 0 : GetFreeUnitNumber(VEH_Ship);
+
+ if (v == NULL || IsOrderPoolFull() || unit_num > _patches.max_ships)
+ return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
+
+ if (flags & DC_EXEC) {
+ int x;
+ int y;
+
+ const ShipVehicleInfo *svi = ShipVehInfo(p1);
+
+ v->unitnumber = unit_num;
+
+ v->owner = _current_player;
+ v->tile = tile;
+ x = TileX(tile) * TILE_SIZE + TILE_SIZE / 2;
+ y = TileY(tile) * TILE_SIZE + TILE_SIZE / 2;
+ v->x_pos = x;
+ v->y_pos = y;
+ v->z_pos = GetSlopeZ(x,y);
+
+ v->z_height = 6;
+ v->sprite_width = 6;
+ v->sprite_height = 6;
+ v->x_offs = -3;
+ v->y_offs = -3;
+ v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
+
+ v->spritenum = svi->image_index;
+ v->cargo_type = svi->cargo_type;
+ v->cargo_subtype = 0;
+ v->cargo_cap = svi->capacity;
+ v->value = value;
+
+ v->last_station_visited = INVALID_STATION;
+ v->max_speed = svi->max_speed;
+ v->engine_type = p1;
+
+ e = GetEngine(p1);
+ v->reliability = e->reliability;
+ v->reliability_spd_dec = e->reliability_spd_dec;
+ v->max_age = e->lifelength * 366;
+ _new_vehicle_id = v->index;
+
+ v->string_id = STR_SV_SHIP_NAME;
+ v->u.ship.state = 0x80;
+
+ v->service_interval = _patches.servint_ships;
+ v->date_of_last_service = _date;
+ v->build_year = _cur_year;
+ v->cur_image = 0x0E5E;
+ v->type = VEH_Ship;
+ v->random_bits = VehicleRandomBits();
+
+ VehiclePositionChanged(v);
+ GetPlayer(_current_player)->num_engines[p1]++;
+
+ InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
+ RebuildVehicleLists();
+ InvalidateWindow(WC_COMPANY, v->owner);
+ if (IsLocalPlayer())
+ InvalidateWindow(WC_REPLACE_VEHICLE, VEH_Ship); // updates the replace Ship window
+ }
+
+ return value;
+}
+
+/** Sell a ship.
+ * @param tile unused
+ * @param p1 vehicle ID to be sold
+ * @param p2 unused
+ */
+int32 CmdSellShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle *v;
+
+ if (!IsValidVehicleID(p1)) return CMD_ERROR;
+
+ v = GetVehicle(p1);
+
+ if (v->type != VEH_Ship || !CheckOwnership(v->owner)) return CMD_ERROR;
+
+ SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
+
+ if (!IsShipInDepotStopped(v)) {
+ return_cmd_error(STR_980B_SHIP_MUST_BE_STOPPED_IN);
+ }
+
+ if (flags & DC_EXEC) {
+ InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
+ RebuildVehicleLists();
+ InvalidateWindow(WC_COMPANY, v->owner);
+ DeleteWindowById(WC_VEHICLE_VIEW, v->index);
+ DeleteDepotHighlightOfVehicle(v);
+ DeleteVehicle(v);
+ if (IsLocalPlayer())
+ InvalidateWindow(WC_REPLACE_VEHICLE, VEH_Ship); // updates the replace Ship window
+ }
+
+ return -(int32)v->value;
+}
+
+/** Start/Stop a ship.
+ * @param tile unused
+ * @param p1 ship ID to start/stop
+ * @param p2 unused
+ */
+int32 CmdStartStopShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle *v;
+ uint16 callback;
+
+ if (!IsValidVehicleID(p1)) return CMD_ERROR;
+
+ v = GetVehicle(p1);
+
+ if (v->type != VEH_Ship || !CheckOwnership(v->owner)) return CMD_ERROR;
+
+ /* Check if this ship can be started/stopped. The callback will fail or
+ * return 0xFF if it can. */
+ callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
+ if (callback != CALLBACK_FAILED && callback != 0xFF) {
+ StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
+ return_cmd_error(error);
+ }
+
+ if (flags & DC_EXEC) {
+ if (IsShipInDepotStopped(v)) {
+ DeleteVehicleNews(p1, STR_981C_SHIP_IS_WAITING_IN_DEPOT);
+ }
+
+ v->vehstatus ^= VS_STOPPED;
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
+ InvalidateWindowClasses(WC_SHIPS_LIST);
+ }
+
+ return 0;
+}
+
+/** Send a ship to the depot.
+ * @param tile unused
+ * @param p1 vehicle ID to send to the depot
+ * @param p2 various bitmasked elements
+ * - p2 bit 0-3 - DEPOT_ flags (see vehicle.h)
+ * - p2 bit 8-10 - VLW flag (for mass goto depot)
+ */
+int32 CmdSendShipToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle *v;
+ const Depot *dep;
+
+ if (p2 & DEPOT_MASS_SEND) {
+ /* Mass goto depot requested */
+ if (!ValidVLWFlags(p2 & VLW_MASK)) return CMD_ERROR;
+ return SendAllVehiclesToDepot(VEH_Ship, flags, p2 & DEPOT_SERVICE, _current_player, (p2 & VLW_MASK), p1);
+ }
+
+ if (!IsValidVehicleID(p1)) return CMD_ERROR;
+
+ v = GetVehicle(p1);
+
+ if (v->type != VEH_Ship || !CheckOwnership(v->owner)) return CMD_ERROR;
+
+ if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
+
+ if (IsShipInDepot(v)) return CMD_ERROR;
+
+ /* If the current orders are already goto-depot */
+ if (v->current_order.type == OT_GOTO_DEPOT) {
+ if (!!(p2 & DEPOT_SERVICE) == HASBIT(v->current_order.flags, OFB_HALT_IN_DEPOT)) {
+ /* We called with a different DEPOT_SERVICE setting.
+ * Now we change the setting to apply the new one and let the vehicle head for the same depot.
+ * Note: the if is (true for requesting service == true for ordered to stop in depot) */
+ if (flags & DC_EXEC) {
+ TOGGLEBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ }
+ return 0;
+ }
+
+ if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
+ if (flags & DC_EXEC) {
+ /* If the orders to 'goto depot' are in the orders list (forced servicing),
+ * then skip to the next order; effectively cancelling this forced service */
+ if (HASBIT(v->current_order.flags, OFB_PART_OF_ORDERS))
+ v->cur_order_index++;
+
+ v->current_order.type = OT_DUMMY;
+ v->current_order.flags = 0;
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ }
+ return 0;
+ }
+
+ dep = FindClosestShipDepot(v);
+ if (dep == NULL) return_cmd_error(STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT);
+
+ if (flags & DC_EXEC) {
+ v->dest_tile = dep->xy;
+ v->current_order.type = OT_GOTO_DEPOT;
+ v->current_order.flags = OF_NON_STOP;
+ if (!(p2 & DEPOT_SERVICE)) SETBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
+ v->current_order.refit_cargo = CT_INVALID;
+ v->current_order.dest = dep->index;
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ }
+
+ return 0;
+}
+
+
+/** Refits a ship to the specified cargo type.
+ * @param tile unused
+ * @param p1 vehicle ID of the ship to refit
+ * @param p2 various bitstuffed elements
+ * - p2 = (bit 0-7) - the new cargo type to refit to (p2 & 0xFF)
+ * - p2 = (bit 8-15) - the new cargo subtype to refit to
+ */
+int32 CmdRefitShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle *v;
+ int32 cost;
+ CargoID new_cid = GB(p2, 0, 8); //gets the cargo number
+ byte new_subtype = GB(p2, 8, 8);
+ uint16 capacity = CALLBACK_FAILED;
+
+ if (!IsValidVehicleID(p1)) return CMD_ERROR;
+
+ v = GetVehicle(p1);
+
+ if (v->type != VEH_Ship || !CheckOwnership(v->owner)) return CMD_ERROR;
+
+ if (!IsShipInDepotStopped(v)) {
+ return_cmd_error(STR_980B_SHIP_MUST_BE_STOPPED_IN);
+ }
+
+ /* Check cargo */
+ if (!ShipVehInfo(v->engine_type)->refittable) return CMD_ERROR;
+ if (new_cid > NUM_CARGO || !CanRefitTo(v->engine_type, new_cid)) return CMD_ERROR;
+
+ SET_EXPENSES_TYPE(EXPENSES_SHIP_RUN);
+
+ /* Check the refit capacity callback */
+ if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_REFIT_CAPACITY)) {
+ /* Back up the existing cargo type */
+ CargoID temp_cid = v->cargo_type;
+ byte temp_subtype = v->cargo_subtype;
+ v->cargo_type = new_cid;
+ v->cargo_subtype = new_subtype;
+
+ capacity = GetVehicleCallback(CBID_VEHICLE_REFIT_CAPACITY, 0, 0, v->engine_type, v);
+
+ /* Restore the cargo type */
+ v->cargo_type = temp_cid;
+ v->cargo_subtype = temp_subtype;
+ }
+
+ if (capacity == CALLBACK_FAILED) {
+ capacity = ShipVehInfo(v->engine_type)->capacity;
+ }
+ _returned_refit_capacity = capacity;
+
+ cost = 0;
+ if (IsHumanPlayer(v->owner) && new_cid != v->cargo_type) {
+ cost = GetRefitCost(v->engine_type);
+ }
+
+ if (flags & DC_EXEC) {
+ v->cargo_cap = capacity;
+ v->cargo_count = (v->cargo_type == new_cid) ? min(v->cargo_cap, v->cargo_count) : 0;
+ v->cargo_type = new_cid;
+ v->cargo_subtype = new_subtype;
+ InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
+ InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
+ RebuildVehicleLists();
+ }
+
+ return cost;
+
+}
diff --git a/src/ship_gui.c b/src/ship_gui.c
new file mode 100644
index 000000000..010ea71e5
--- /dev/null
+++ b/src/ship_gui.c
@@ -0,0 +1,527 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "debug.h"
+#include "functions.h"
+#include "ship.h"
+#include "table/strings.h"
+#include "table/sprites.h"
+#include "map.h"
+#include "window.h"
+#include "gui.h"
+#include "gfx.h"
+#include "vehicle.h"
+#include "viewport.h"
+#include "station.h"
+#include "command.h"
+#include "player.h"
+#include "engine.h"
+#include "depot.h"
+#include "vehicle_gui.h"
+#include "newgrf_engine.h"
+#include "date.h"
+
+/**
+ * Draw the purchase info details of a ship at a given location.
+ * @param x,y location where to draw the info
+ * @param engine_number the engine of which to draw the info of
+ */
+void DrawShipPurchaseInfo(int x, int y, uint w, EngineID engine_number)
+{
+ YearMonthDay ymd;
+ const ShipVehicleInfo *svi = ShipVehInfo(engine_number);
+ const Engine *e;
+
+ /* Purchase cost - Max speed */
+ SetDParam(0, svi->base_cost * (_price.ship_base>>3)>>5);
+ SetDParam(1, svi->max_speed / 2);
+ DrawString(x,y, STR_PURCHASE_INFO_COST_SPEED, 0);
+ y += 10;
+
+ /* Cargo type + capacity */
+ SetDParam(0, svi->cargo_type);
+ SetDParam(1, svi->capacity);
+ SetDParam(2, svi->refittable ? STR_9842_REFITTABLE : STR_EMPTY);
+ DrawString(x,y, STR_PURCHASE_INFO_CAPACITY, 0);
+ y += 10;
+
+ /* Running cost */
+ SetDParam(0, svi->running_cost * _price.ship_running >> 8);
+ DrawString(x,y, STR_PURCHASE_INFO_RUNNINGCOST, 0);
+ y += 10;
+
+ /* Design date - Life length */
+ e = GetEngine(engine_number);
+ ConvertDateToYMD(e->intro_date, &ymd);
+ SetDParam(0, ymd.year);
+ SetDParam(1, e->lifelength);
+ DrawString(x,y, STR_PURCHASE_INFO_DESIGNED_LIFE, 0);
+ y += 10;
+
+ /* Reliability */
+ SetDParam(0, e->reliability * 100 >> 16);
+ DrawString(x,y, STR_PURCHASE_INFO_RELIABILITY, 0);
+ y += 10;
+
+ /* Additional text from NewGRF */
+ y += ShowAdditionalText(x, y, w, engine_number);
+ if (svi->refittable) y += ShowRefitOptionsList(x, y, w, engine_number);
+}
+
+void DrawShipImage(const Vehicle *v, int x, int y, VehicleID selection)
+{
+ DrawSprite(GetShipImage(v, DIR_W) | GetVehiclePalette(v), x + 32, y + 10);
+
+ if (v->index == selection) {
+ DrawFrameRect(x - 5, y - 1, x + 67, y + 21, 15, FR_BORDERONLY);
+ }
+}
+
+static void ShipDetailsWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ const Vehicle *v = GetVehicle(w->window_number);
+ StringID str;
+
+ SetWindowWidgetDisabledState(w, 2, v->owner != _local_player);
+ // disable service-scroller when interval is set to disabled
+ SetWindowWidgetDisabledState(w, 5, !_patches.servint_ships);
+ SetWindowWidgetDisabledState(w, 6, !_patches.servint_ships);
+
+ SetDParam(0, v->string_id);
+ SetDParam(1, v->unitnumber);
+ DrawWindowWidgets(w);
+
+ /* Draw running cost */
+ {
+ int year = v->age / 366;
+
+ SetDParam(1, year);
+
+ SetDParam(0, (v->age + 365 < v->max_age) ? STR_AGE : STR_AGE_RED);
+ SetDParam(2, v->max_age / 366);
+ SetDParam(3, ShipVehInfo(v->engine_type)->running_cost * _price.ship_running >> 8);
+ DrawString(2, 15, STR_9812_AGE_RUNNING_COST_YR, 0);
+ }
+
+ /* Draw max speed */
+ {
+ SetDParam(0, v->max_speed / 2);
+ DrawString(2, 25, STR_9813_MAX_SPEED, 0);
+ }
+
+ /* Draw profit */
+ {
+ SetDParam(0, v->profit_this_year);
+ SetDParam(1, v->profit_last_year);
+ DrawString(2, 35, STR_9814_PROFIT_THIS_YEAR_LAST_YEAR, 0);
+ }
+
+ /* Draw breakdown & reliability */
+ {
+ SetDParam(0, v->reliability * 100 >> 16);
+ SetDParam(1, v->breakdowns_since_last_service);
+ DrawString(2, 45, STR_9815_RELIABILITY_BREAKDOWNS, 0);
+ }
+
+ /* Draw service interval text */
+ {
+ SetDParam(0, v->service_interval);
+ SetDParam(1, v->date_of_last_service);
+ DrawString(13, 90, _patches.servint_ispercent?STR_SERVICING_INTERVAL_PERCENT:STR_883C_SERVICING_INTERVAL_DAYS, 0);
+ }
+
+ DrawShipImage(v, 3, 57, INVALID_VEHICLE);
+
+ SetDParam(1, v->build_year);
+ SetDParam(0, GetCustomEngineName(v->engine_type));
+ SetDParam(2, v->value);
+ DrawString(74, 57, STR_9816_BUILT_VALUE, 0);
+
+ SetDParam(0, v->cargo_type);
+ SetDParam(1, v->cargo_cap);
+ DrawString(74, 67, STR_9817_CAPACITY, 0);
+
+ str = STR_8812_EMPTY;
+ if (v->cargo_count != 0) {
+ SetDParam(0, v->cargo_type);
+ SetDParam(1, v->cargo_count);
+ SetDParam(2, v->cargo_source);
+ str = STR_8813_FROM;
+ }
+ DrawString(74, 78, str, 0);
+ } break;
+
+ case WE_CLICK: {
+ int mod;
+ const Vehicle *v;
+ switch (e->we.click.widget) {
+ case 2: /* rename */
+ v = GetVehicle(w->window_number);
+ SetDParam(0, v->unitnumber);
+ ShowQueryString(v->string_id, STR_9831_NAME_SHIP, 31, 150, w, CS_ALPHANUMERAL);
+ break;
+ case 5: /* increase int */
+ mod = _ctrl_pressed? 5 : 10;
+ goto do_change_service_int;
+ case 6: /* decrease int */
+ mod = _ctrl_pressed?- 5 : -10;
+do_change_service_int:
+ v = GetVehicle(w->window_number);
+
+ mod = GetServiceIntervalClamped(mod + v->service_interval);
+ if (mod == v->service_interval) return;
+
+ DoCommandP(v->tile, v->index, mod, NULL, CMD_CHANGE_SERVICE_INT | CMD_MSG(STR_018A_CAN_T_CHANGE_SERVICING));
+ break;
+ }
+ } break;
+
+ case WE_ON_EDIT_TEXT:
+ if (e->we.edittext.str[0] != '\0') {
+ _cmd_text = e->we.edittext.str;
+ DoCommandP(0, w->window_number, 0, NULL,
+ CMD_NAME_VEHICLE | CMD_MSG(STR_9832_CAN_T_NAME_SHIP));
+ }
+ break;
+ }
+}
+
+
+static const Widget _ship_details_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 364, 0, 13, STR_9811_DETAILS, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 365, 404, 0, 13, STR_01AA_NAME, STR_982F_NAME_SHIP},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 404, 14, 55, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 404, 56, 88, 0x0, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 0, 10, 89, 94, STR_0188, STR_884D_INCREASE_SERVICING_INTERVAL},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 0, 10, 95, 100, STR_0189, STR_884E_DECREASE_SERVICING_INTERVAL},
+{ WWT_PANEL, RESIZE_NONE, 14, 11, 404, 89, 100, 0x0, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _ship_details_desc = {
+ WDP_AUTO, WDP_AUTO, 405, 101,
+ WC_VEHICLE_DETAILS,WC_VEHICLE_VIEW,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _ship_details_widgets,
+ ShipDetailsWndProc
+};
+
+static void ShowShipDetailsWindow(const Vehicle *v)
+{
+ Window *w;
+ VehicleID veh = v->index;
+
+ DeleteWindowById(WC_VEHICLE_ORDERS, veh);
+ DeleteWindowById(WC_VEHICLE_DETAILS, veh);
+ w = AllocateWindowDescFront(&_ship_details_desc, veh);
+ w->caption_color = v->owner;
+}
+
+void CcBuildShip(bool success, TileIndex tile, uint32 p1, uint32 p2)
+{
+ const Vehicle *v;
+ if (!success) return;
+
+ v = GetVehicle(_new_vehicle_id);
+ if (v->tile == _backup_orders_tile) {
+ _backup_orders_tile = 0;
+ RestoreVehicleOrders(v, _backup_orders_data);
+ }
+ ShowShipViewWindow(v);
+}
+
+void CcCloneShip(bool success, TileIndex tile, uint32 p1, uint32 p2)
+{
+ if (success) ShowShipViewWindow(GetVehicle(_new_vehicle_id));
+}
+
+static void NewShipWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ EngineID selected_id;
+ EngineID eid;
+ int count;
+ int pos;
+ int sel;
+ int y;
+
+ SetWindowWidgetDisabledState(w, 5, w->window_number == 0);
+
+ count = 0;
+ for (eid = SHIP_ENGINES_INDEX; eid < SHIP_ENGINES_INDEX + NUM_SHIP_ENGINES; eid++) {
+ if (HASBIT(GetEngine(eid)->player_avail, _local_player)) count++;
+ }
+ SetVScrollCount(w, count);
+
+ DrawWindowWidgets(w);
+
+ y = 15;
+ sel = WP(w,buildvehicle_d).sel_index;
+ pos = w->vscroll.pos;
+ selected_id = INVALID_ENGINE;
+ for (eid = SHIP_ENGINES_INDEX; eid < SHIP_ENGINES_INDEX + NUM_SHIP_ENGINES; eid++) {
+ if (!HASBIT(GetEngine(eid)->player_avail, _local_player)) continue;
+ if (sel == 0) selected_id = eid;
+ if (IS_INT_INSIDE(--pos, -w->vscroll.cap, 0)) {
+ DrawString(77, y + 7, GetCustomEngineName(eid), sel == 0 ? 0xC : 0x10);
+ DrawShipEngine(37, y + 10, eid, GetEnginePalette(eid, _local_player));
+ y += 24;
+ }
+ sel--;
+ }
+
+ WP(w,buildvehicle_d).sel_engine = selected_id;
+
+ if (selected_id != INVALID_ENGINE) {
+ const Widget *wi = &w->widget[4];
+ DrawShipPurchaseInfo(2, wi->top + 1, wi->right - wi->left - 2, selected_id);
+ }
+ break;
+ }
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 2: { /* listbox */
+ uint i = (e->we.click.pt.y - 14) / 24;
+ if (i < w->vscroll.cap) {
+ WP(w,buildvehicle_d).sel_index = i + w->vscroll.pos;
+ SetWindowDirty(w);
+ }
+ } break;
+ case 5: { /* build */
+ EngineID sel_eng = WP(w,buildvehicle_d).sel_engine;
+ if (sel_eng != INVALID_ENGINE)
+ DoCommandP(w->window_number, sel_eng, 0, CcBuildShip, CMD_BUILD_SHIP | CMD_MSG(STR_980D_CAN_T_BUILD_SHIP));
+ } break;
+
+ case 6: { /* rename */
+ EngineID sel_eng = WP(w,buildvehicle_d).sel_engine;
+ if (sel_eng != INVALID_ENGINE) {
+ WP(w, buildvehicle_d).rename_engine = sel_eng;
+ ShowQueryString(GetCustomEngineName(sel_eng), STR_9838_RENAME_SHIP_TYPE, 31, 160, w, CS_ALPHANUMERAL);
+ }
+ } break;
+ }
+ break;
+
+ case WE_ON_EDIT_TEXT:
+ if (e->we.edittext.str[0] != '\0') {
+ _cmd_text = e->we.edittext.str;
+ DoCommandP(0, WP(w, buildvehicle_d).rename_engine, 0, NULL,
+ CMD_RENAME_ENGINE | CMD_MSG(STR_9839_CAN_T_RENAME_SHIP_TYPE));
+ }
+ break;
+
+ case WE_RESIZE:
+ w->vscroll.cap += e->we.sizing.diff.y / 24;
+ w->widget[2].data = (w->vscroll.cap << 8) + 1;
+ break;
+
+ }
+}
+
+static const Widget _new_ship_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 254, 0, 13, STR_9808_NEW_SHIPS, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_MATRIX, RESIZE_BOTTOM, 14, 0, 242, 14, 109, 0x401, STR_9825_SHIP_SELECTION_LIST_CLICK},
+{ WWT_SCROLLBAR, RESIZE_BOTTOM, 14, 243, 254, 14, 109, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WWT_PANEL, RESIZE_TB, 14, 0, 254, 110, 201, 0x0, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 121, 202, 213, STR_9809_BUILD_SHIP, STR_9826_BUILD_THE_HIGHLIGHTED_SHIP},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 122, 242, 202, 213, STR_9836_RENAME, STR_9837_RENAME_SHIP_TYPE},
+{ WWT_RESIZEBOX, RESIZE_TB, 14, 243, 254, 202, 213, 0x0, STR_RESIZE_BUTTON},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _new_ship_desc = {
+ WDP_AUTO, WDP_AUTO, 255, 214,
+ WC_BUILD_VEHICLE,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
+ _new_ship_widgets,
+ NewShipWndProc
+};
+
+
+void ShowBuildShipWindow(TileIndex tile)
+{
+ Window *w;
+
+ DeleteWindowById(WC_BUILD_VEHICLE, tile);
+
+ w = AllocateWindowDescFront(&_new_ship_desc, tile);
+ w->vscroll.cap = 4;
+ w->widget[2].data = (w->vscroll.cap << 8) + 1;
+
+ w->resize.step_height = 24;
+
+ if (tile != 0) {
+ w->caption_color = GetTileOwner(tile);
+ } else {
+ w->caption_color = _local_player;
+ }
+
+}
+
+
+static void ShipViewWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ Vehicle *v = GetVehicle(w->window_number);
+ StringID str;
+ bool refitable_and_stopped_in_depot = ShipVehInfo(v->engine_type)->refittable && IsShipInDepotStopped(v);
+ bool is_localplayer = v->owner == _local_player;
+
+ SetWindowWidgetDisabledState(w, 7, !is_localplayer);
+ SetWindowWidgetDisabledState(w, 8,
+ !is_localplayer || // Disable if owner is not local player
+ !refitable_and_stopped_in_depot); // Disable if the ship is not refitable or stopped in a depot
+ SetWindowWidgetDisabledState(w, 11, !is_localplayer);
+
+ /* draw widgets & caption */
+ SetDParam(0, v->string_id);
+ SetDParam(1, v->unitnumber);
+ DrawWindowWidgets(w);
+
+ if (v->breakdown_ctr == 1) {
+ str = STR_885C_BROKEN_DOWN;
+ } else if (v->vehstatus & VS_STOPPED) {
+ str = STR_8861_STOPPED;
+ } else {
+ switch (v->current_order.type) {
+ case OT_GOTO_STATION: {
+ SetDParam(0, v->current_order.dest);
+ SetDParam(1, v->cur_speed / 2);
+ str = STR_HEADING_FOR_STATION + _patches.vehicle_speed;
+ } break;
+
+ case OT_GOTO_DEPOT: {
+ Depot *depot = GetDepot(v->current_order.dest);
+ SetDParam(0, depot->town_index);
+ SetDParam(1, v->cur_speed / 2);
+ if (HASBIT(v->current_order.flags, OFB_HALT_IN_DEPOT) && !HASBIT(v->current_order.flags, OFB_PART_OF_ORDERS)) {
+ str = STR_HEADING_FOR_SHIP_DEPOT + _patches.vehicle_speed;
+ } else {
+ str = STR_HEADING_FOR_SHIP_DEPOT_SERVICE + _patches.vehicle_speed;
+ }
+ } break;
+
+ case OT_LOADING:
+ case OT_LEAVESTATION:
+ str = STR_882F_LOADING_UNLOADING;
+ break;
+
+ default:
+ if (v->num_orders == 0) {
+ str = STR_NO_ORDERS + _patches.vehicle_speed;
+ SetDParam(0, v->cur_speed / 2);
+ } else {
+ str = STR_EMPTY;
+ }
+ break;
+ }
+ }
+
+ /* draw the flag plus orders */
+ DrawSprite(v->vehstatus & VS_STOPPED ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, 2, w->widget[5].top + 1);
+ DrawStringCenteredTruncated(w->widget[5].left + 8, w->widget[5].right, w->widget[5].top + 1, str, 0);
+ DrawWindowViewport(w);
+ } break;
+
+ case WE_CLICK: {
+ const Vehicle *v = GetVehicle(w->window_number);
+
+ switch (e->we.click.widget) {
+ case 5: /* start stop */
+ DoCommandP(v->tile, v->index, 0, NULL, CMD_START_STOP_SHIP | CMD_MSG(STR_9818_CAN_T_STOP_START_SHIP));
+ break;
+ case 6: /* center main view */
+ ScrollMainWindowTo(v->x_pos, v->y_pos);
+ break;
+ case 7: /* goto hangar */
+ DoCommandP(v->tile, v->index, _ctrl_pressed ? DEPOT_SERVICE : 0, NULL, CMD_SEND_SHIP_TO_DEPOT | CMD_MSG(STR_9819_CAN_T_SEND_SHIP_TO_DEPOT));
+ break;
+ case 8: /* refit */
+ ShowVehicleRefitWindow(v, INVALID_VEH_ORDER_ID);
+ break;
+ case 9: /* show orders */
+ ShowOrdersWindow(v);
+ break;
+ case 10: /* show details */
+ ShowShipDetailsWindow(v);
+ break;
+ case 11: {
+ /* clone vehicle */
+ DoCommandP(v->tile, v->index, _ctrl_pressed ? 1 : 0, CcCloneShip, CMD_CLONE_VEHICLE | CMD_MSG(STR_980D_CAN_T_BUILD_SHIP));
+ } break;
+ }
+ } break;
+
+ case WE_RESIZE:
+ w->viewport->width += e->we.sizing.diff.x;
+ w->viewport->height += e->we.sizing.diff.y;
+ w->viewport->virtual_width += e->we.sizing.diff.x;
+ w->viewport->virtual_height += e->we.sizing.diff.y;
+ break;
+
+ case WE_DESTROY:
+ DeleteWindowById(WC_VEHICLE_ORDERS, w->window_number);
+ DeleteWindowById(WC_VEHICLE_REFIT, w->window_number);
+ DeleteWindowById(WC_VEHICLE_DETAILS, w->window_number);
+ break;
+
+ case WE_MOUSELOOP: {
+ const Vehicle *v = GetVehicle(w->window_number);
+ bool ship_stopped = IsShipInDepotStopped(v);
+
+ /* Widget 7 (send to depot) must be hidden if the ship is already stopped in depot.
+ * Widget 11 (clone) should then be shown, since cloning is allowed only while in depot and stopped.
+ * This sytem allows to have two buttons, on top of each otherother*/
+ if (ship_stopped != IsWindowWidgetHidden(w, 7) || ship_stopped == IsWindowWidgetHidden(w, 11)) {
+ SetWindowWidgetHiddenState(w, 7, ship_stopped); // send to depot
+ SetWindowWidgetHiddenState(w, 11, !ship_stopped); // clone
+ SetWindowDirty(w);
+ }
+ }
+ }
+}
+
+static const Widget _ship_view_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_RIGHT, 14, 11, 237, 0, 13, STR_980F, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_STICKYBOX, RESIZE_LR, 14, 238, 249, 0, 13, 0x0, STR_STICKY_BUTTON},
+{ WWT_PANEL, RESIZE_RB, 14, 0, 231, 14, 103, 0x0, STR_NULL},
+{ WWT_INSET, RESIZE_RB, 14, 2, 229, 16, 101, 0x0, STR_NULL},
+{ WWT_PUSHBTN, RESIZE_RTB, 14, 0, 237, 104, 115, 0x0, STR_9827_CURRENT_SHIP_ACTION_CLICK},
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 232, 249, 14, 31, SPR_CENTRE_VIEW_VEHICLE, STR_9829_CENTER_MAIN_VIEW_ON_SHIP},
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 232, 249, 32, 49, SPR_SEND_SHIP_TODEPOT, STR_982A_SEND_SHIP_TO_DEPOT},
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 232, 249, 50, 67, SPR_REFIT_VEHICLE, STR_983A_REFIT_CARGO_SHIP_TO_CARRY},
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 232, 249, 68, 85, SPR_SHOW_ORDERS, STR_9828_SHOW_SHIP_S_ORDERS},
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 232, 249, 86, 103, SPR_SHOW_VEHICLE_DETAILS,STR_982B_SHOW_SHIP_DETAILS},
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 232, 249, 32, 49, SPR_CLONE_SHIP, STR_CLONE_SHIP_INFO},
+{ WWT_PANEL, RESIZE_LRB, 14, 232, 249, 104, 103, 0x0, STR_NULL },
+{ WWT_RESIZEBOX, RESIZE_LRTB, 14, 238, 249, 104, 115, 0x0, STR_NULL },
+{ WIDGETS_END }
+};
+
+static const WindowDesc _ship_view_desc = {
+ WDP_AUTO, WDP_AUTO, 250, 116,
+ WC_VEHICLE_VIEW,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
+ _ship_view_widgets,
+ ShipViewWndProc
+};
+
+void ShowShipViewWindow(const Vehicle *v)
+{
+ Window *w = AllocateWindowDescFront(&_ship_view_desc, v->index);
+
+ if (w != NULL) {
+ w->caption_color = v->owner;
+ AssignWindowViewport(w, 3, 17, 0xE2, 0x54, w->window_number | (1 << 31), 0);
+ }
+}
diff --git a/src/signs.c b/src/signs.c
new file mode 100644
index 000000000..4b2d48cd1
--- /dev/null
+++ b/src/signs.c
@@ -0,0 +1,277 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "table/strings.h"
+#include "functions.h"
+#include "player.h"
+#include "signs.h"
+#include "saveload.h"
+#include "command.h"
+#include "variables.h"
+
+static Sign *_new_sign;
+
+/**
+ * Called if a new block is added to the sign-pool
+ */
+static void SignPoolNewBlock(uint start_item)
+{
+ Sign *si;
+
+ /* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
+ * TODO - This is just a temporary stage, this will be removed. */
+ for (si = GetSign(start_item); si != NULL; si = (si->index + 1U < GetSignPoolSize()) ? GetSign(si->index + 1U) : NULL) si->index = start_item++;
+}
+
+/* Initialize the sign-pool */
+DEFINE_OLD_POOL(Sign, Sign, SignPoolNewBlock, NULL)
+
+/**
+ *
+ * Update the coordinate of one sign
+ *
+ */
+static void UpdateSignVirtCoords(Sign *si)
+{
+ Point pt = RemapCoords(si->x, si->y, si->z);
+ SetDParam(0, si->str);
+ UpdateViewportSignPos(&si->sign, pt.x, pt.y - 6, STR_2806);
+}
+
+/**
+ *
+ * Update the coordinates of all signs
+ *
+ */
+void UpdateAllSignVirtCoords(void)
+{
+ Sign *si;
+
+ FOR_ALL_SIGNS(si) UpdateSignVirtCoords(si);
+
+}
+
+/**
+ *
+ * Marks the region of a sign as dirty
+ *
+ * @param si Pointer to the Sign
+ */
+static void MarkSignDirty(Sign *si)
+{
+ MarkAllViewportsDirty(
+ si->sign.left - 6,
+ si->sign.top - 3,
+ si->sign.left + si->sign.width_1 * 4 + 12,
+ si->sign.top + 45);
+}
+
+/**
+ *
+ * Allocates a new sign
+ *
+ * @return The pointer to the new sign, or NULL if there is no more free space
+ */
+static Sign *AllocateSign(void)
+{
+ Sign *si;
+
+ /* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
+ * TODO - This is just a temporary stage, this will be removed. */
+ for (si = GetSign(0); si != NULL; si = (si->index + 1U < GetSignPoolSize()) ? GetSign(si->index + 1U) : NULL) {
+ if (!IsValidSign(si)) {
+ uint index = si->index;
+
+ memset(si, 0, sizeof(Sign));
+ si->index = index;
+
+ return si;
+ }
+ }
+
+ /* Check if we can add a block to the pool */
+ if (AddBlockToPool(&_Sign_pool))
+ return AllocateSign();
+
+ return NULL;
+}
+
+void DestroySign(Sign *si)
+{
+ DeleteName(si->str);
+}
+
+/**
+ * Place a sign at the given coordinates. Ownership of sign has
+ * no effect whatsoever except for the colour the sign gets for easy recognition,
+ * but everybody is able to rename/remove it.
+ * @param tile tile to place sign at
+ * @param p1 unused
+ * @param p2 unused
+ */
+int32 CmdPlaceSign(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Sign *si;
+
+ /* Try to locate a new sign */
+ si = AllocateSign();
+ if (si == NULL) return_cmd_error(STR_2808_TOO_MANY_SIGNS);
+
+ /* When we execute, really make the sign */
+ if (flags & DC_EXEC) {
+ int x = TileX(tile) * TILE_SIZE;
+ int y = TileY(tile) * TILE_SIZE;
+
+ si->str = STR_280A_SIGN;
+ si->x = x;
+ si->y = y;
+ si->owner = _current_player; // owner of the sign; just eyecandy
+ si->z = GetSlopeZ(x,y);
+ UpdateSignVirtCoords(si);
+ MarkSignDirty(si);
+ InvalidateWindow(WC_SIGN_LIST, 0);
+ _sign_sort_dirty = true;
+ _new_sign = si;
+ }
+
+ return 0;
+}
+
+/** Rename a sign. If the new name of the sign is empty, we assume
+ * the user wanted to delete it. So delete it. Ownership of signs
+ * has no meaning/effect whatsoever except for eyecandy
+ * @param tile unused
+ * @param p1 index of the sign to be renamed/removed
+ * @param p2 unused
+ */
+int32 CmdRenameSign(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ if (!IsValidSignID(p1)) return CMD_ERROR;
+
+ /* If _cmd_text 0 means the new text for the sign is non-empty.
+ * So rename the sign. If it is empty, it has no name, so delete it */
+ if (_cmd_text[0] != '\0') {
+ /* Create the name */
+ StringID str = AllocateName(_cmd_text, 0);
+ if (str == 0) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ Sign *si = GetSign(p1);
+
+ /* Delete the old name */
+ DeleteName(si->str);
+ /* Assign the new one */
+ si->str = str;
+ si->owner = _current_player;
+
+ /* Update; mark sign dirty twice, because it can either becom longer, or shorter */
+ MarkSignDirty(si);
+ UpdateSignVirtCoords(si);
+ MarkSignDirty(si);
+ InvalidateWindow(WC_SIGN_LIST, 0);
+ _sign_sort_dirty = true;
+ } else {
+ /* Free the name, because we did not assign it yet */
+ DeleteName(str);
+ }
+ } else { /* Delete sign */
+ if (flags & DC_EXEC) {
+ Sign *si = GetSign(p1);
+
+ MarkSignDirty(si);
+ DeleteSign(si);
+
+ InvalidateWindow(WC_SIGN_LIST, 0);
+ _sign_sort_dirty = true;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ *
+ * Callback function that is called after a sign is placed
+ *
+ */
+void CcPlaceSign(bool success, TileIndex tile, uint32 p1, uint32 p2)
+{
+ if (success) {
+ ShowRenameSignWindow(_new_sign);
+ ResetObjectToPlace();
+ }
+}
+
+/**
+ *
+ * PlaceProc function, called when someone pressed the button if the
+ * sign-tool is selected
+ *
+ */
+void PlaceProc_Sign(TileIndex tile)
+{
+ DoCommandP(tile, 0, 0, CcPlaceSign, CMD_PLACE_SIGN | CMD_MSG(STR_2809_CAN_T_PLACE_SIGN_HERE));
+}
+
+/**
+ *
+ * Initialize the signs
+ *
+ */
+void InitializeSigns(void)
+{
+ CleanPool(&_Sign_pool);
+ AddBlockToPool(&_Sign_pool);
+}
+
+static const SaveLoad _sign_desc[] = {
+ SLE_VAR(Sign, str, SLE_UINT16),
+ SLE_CONDVAR(Sign, x, SLE_FILE_I16 | SLE_VAR_I32, 0, 4),
+ SLE_CONDVAR(Sign, y, SLE_FILE_I16 | SLE_VAR_I32, 0, 4),
+ SLE_CONDVAR(Sign, x, SLE_INT32, 5, SL_MAX_VERSION),
+ SLE_CONDVAR(Sign, y, SLE_INT32, 5, SL_MAX_VERSION),
+ SLE_CONDVAR(Sign, owner, SLE_UINT8, 6, SL_MAX_VERSION),
+ SLE_VAR(Sign, z, SLE_UINT8),
+ SLE_END()
+};
+
+/**
+ *
+ * Save all signs
+ *
+ */
+static void Save_SIGN(void)
+{
+ Sign *si;
+
+ FOR_ALL_SIGNS(si) {
+ SlSetArrayIndex(si->index);
+ SlObject(si, _sign_desc);
+ }
+}
+
+/**
+ *
+ * Load all signs
+ *
+ */
+static void Load_SIGN(void)
+{
+ int index;
+ while ((index = SlIterateArray()) != -1) {
+ Sign *si;
+
+ if (!AddBlockIfNeeded(&_Sign_pool, index))
+ error("Signs: failed loading savegame: too many signs");
+
+ si = GetSign(index);
+ SlObject(si, _sign_desc);
+ }
+
+ _sign_sort_dirty = true;
+}
+
+const ChunkHandler _sign_chunk_handlers[] = {
+ { 'SIGN', Save_SIGN, Load_SIGN, CH_ARRAY | CH_LAST},
+};
diff --git a/src/signs.h b/src/signs.h
new file mode 100644
index 000000000..9c9fd2982
--- /dev/null
+++ b/src/signs.h
@@ -0,0 +1,68 @@
+/* $Id$ */
+
+#ifndef SIGNS_H
+#define SIGNS_H
+
+#include "oldpool.h"
+
+typedef struct Sign {
+ StringID str;
+ ViewportSign sign;
+ int32 x;
+ int32 y;
+ byte z;
+ PlayerID owner; // placed by this player. Anyone can delete them though. OWNER_NONE for gray signs from old games.
+
+ SignID index;
+} Sign;
+
+DECLARE_OLD_POOL(Sign, Sign, 2, 16000)
+
+static inline SignID GetMaxSignIndex(void)
+{
+ /* TODO - This isn't the real content of the function, but
+ * with the new pool-system this will be replaced with one that
+ * _really_ returns the highest index. Now it just returns
+ * the next safe value we are sure about everything is below.
+ */
+ return GetSignPoolSize() - 1;
+}
+
+static inline uint GetNumSigns(void)
+{
+ return GetSignPoolSize();
+}
+
+/**
+ * Check if a Sign really exists.
+ */
+static inline bool IsValidSign(const Sign *si)
+{
+ return si->str != STR_NULL;
+}
+
+static inline bool IsValidSignID(uint index)
+{
+ return index < GetSignPoolSize() && IsValidSign(GetSign(index));
+}
+
+void DestroySign(Sign *si);
+
+static inline void DeleteSign(Sign *si)
+{
+ DestroySign(si);
+ si->str = STR_NULL;
+}
+
+#define FOR_ALL_SIGNS_FROM(ss, start) for (ss = GetSign(start); ss != NULL; ss = (ss->index + 1U < GetSignPoolSize()) ? GetSign(ss->index + 1U) : NULL) if (IsValidSign(ss))
+#define FOR_ALL_SIGNS(ss) FOR_ALL_SIGNS_FROM(ss, 0)
+
+VARDEF bool _sign_sort_dirty;
+
+void UpdateAllSignVirtCoords(void);
+void PlaceProc_Sign(TileIndex tile);
+
+/* misc.c */
+void ShowRenameSignWindow(const Sign *si);
+
+#endif /* SIGNS_H */
diff --git a/src/slope.h b/src/slope.h
new file mode 100644
index 000000000..0708bc5d5
--- /dev/null
+++ b/src/slope.h
@@ -0,0 +1,41 @@
+/* $Id$ */
+
+#ifndef SLOPE_H
+#define SLOPE_H
+
+typedef enum Slope {
+ SLOPE_FLAT = 0x00,
+ SLOPE_W = 0x01,
+ SLOPE_S = 0x02,
+ SLOPE_E = 0x04,
+ SLOPE_N = 0x08,
+ SLOPE_STEEP = 0x10,
+ SLOPE_NW = SLOPE_N | SLOPE_W,
+ SLOPE_SW = SLOPE_S | SLOPE_W,
+ SLOPE_SE = SLOPE_S | SLOPE_E,
+ SLOPE_NE = SLOPE_N | SLOPE_E,
+ SLOPE_EW = SLOPE_E | SLOPE_W,
+ SLOPE_NS = SLOPE_N | SLOPE_S,
+ SLOPE_ELEVATED = SLOPE_N | SLOPE_E | SLOPE_S | SLOPE_W,
+ SLOPE_NWS = SLOPE_N | SLOPE_W | SLOPE_S,
+ SLOPE_WSE = SLOPE_W | SLOPE_S | SLOPE_E,
+ SLOPE_SEN = SLOPE_S | SLOPE_E | SLOPE_N,
+ SLOPE_ENW = SLOPE_E | SLOPE_N | SLOPE_W,
+ SLOPE_STEEP_W = SLOPE_STEEP | SLOPE_NWS,
+ SLOPE_STEEP_S = SLOPE_STEEP | SLOPE_WSE,
+ SLOPE_STEEP_E = SLOPE_STEEP | SLOPE_SEN,
+ SLOPE_STEEP_N = SLOPE_STEEP | SLOPE_ENW
+} Slope;
+
+static inline bool IsSteepSlope(Slope s)
+{
+ return (s & SLOPE_STEEP) != 0;
+}
+
+static inline Slope ComplementSlope(Slope s)
+{
+ assert(!IsSteepSlope(s));
+ return (Slope)(0xF ^ s);
+}
+
+#endif /* SLOPE_H */
diff --git a/src/smallmap_gui.c b/src/smallmap_gui.c
new file mode 100644
index 000000000..65e040656
--- /dev/null
+++ b/src/smallmap_gui.c
@@ -0,0 +1,1114 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "functions.h"
+#include "bridge_map.h"
+#include "clear_map.h"
+#include "industry_map.h"
+#include "station_map.h"
+#include "table/strings.h"
+#include "table/sprites.h"
+#include "map.h"
+#include "tile.h"
+#include "gui.h"
+#include "tree_map.h"
+#include "tunnel_map.h"
+#include "window.h"
+#include "gfx.h"
+#include "viewport.h"
+#include "player.h"
+#include "vehicle.h"
+#include "town.h"
+#include "sound.h"
+#include "variables.h"
+
+static const Widget _smallmap_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 13, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_RIGHT, 13, 11, 433, 0, 13, STR_00B0_MAP, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_STICKYBOX, RESIZE_LR, 13, 434, 445, 0, 13, 0x0, STR_STICKY_BUTTON},
+{ WWT_PANEL, RESIZE_RB, 13, 0, 445, 14, 257, 0x0, STR_NULL},
+{ WWT_INSET, RESIZE_RB, 13, 2, 443, 16, 255, 0x0, STR_NULL},
+{ WWT_IMGBTN, RESIZE_LRTB, 13, 380, 401, 258, 279, SPR_IMG_SHOW_COUNTOURS, STR_0191_SHOW_LAND_CONTOURS_ON_MAP},
+{ WWT_IMGBTN, RESIZE_LRTB, 13, 402, 423, 258, 279, SPR_IMG_SHOW_VEHICLES, STR_0192_SHOW_VEHICLES_ON_MAP},
+{ WWT_IMGBTN, RESIZE_LRTB, 13, 424, 445, 258, 279, SPR_IMG_INDUSTRY, STR_0193_SHOW_INDUSTRIES_ON_MAP},
+{ WWT_IMGBTN, RESIZE_LRTB, 13, 380, 401, 280, 301, SPR_IMG_SHOW_ROUTES, STR_0194_SHOW_TRANSPORT_ROUTES_ON},
+{ WWT_IMGBTN, RESIZE_LRTB, 13, 402, 423, 280, 301, SPR_IMG_PLANTTREES, STR_0195_SHOW_VEGETATION_ON_MAP},
+{ WWT_IMGBTN, RESIZE_LRTB, 13, 424, 445, 280, 301, SPR_IMG_COMPANY_GENERAL, STR_0196_SHOW_LAND_OWNERS_ON_MAP},
+{ WWT_IMGBTN, RESIZE_LRTB, 13, 358, 379, 258, 279, SPR_IMG_SMALLMAP, STR_SMALLMAP_CENTER},
+{ WWT_IMGBTN, RESIZE_LRTB, 13, 358, 379, 280, 301, SPR_IMG_TOWN, STR_0197_TOGGLE_TOWN_NAMES_ON_OFF},
+{ WWT_PANEL, RESIZE_RTB, 13, 0, 357, 258, 301, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_RTB, 13, 0, 433, 302, 313, 0x0, STR_NULL},
+{ WWT_RESIZEBOX, RESIZE_LRTB, 13, 434, 445, 302, 313, 0x0, STR_RESIZE_BUTTON},
+{ WIDGETS_END},
+};
+
+static int _smallmap_type;
+static bool _smallmap_show_towns = true;
+
+#define MK(a,b) a, b
+#define MKEND() 0xFFFF
+#define MS(a,b) (a | 0x100), b
+
+/* Legend text giving the colours to look for on the minimap */
+static const uint16 _legend_land_contours[] = {
+ MK(0x5A, STR_00F0_100M),
+ MK(0x5C, STR_00F1_200M),
+ MK(0x5E, STR_00F2_300M),
+ MK(0x1F, STR_00F3_400M),
+ MK(0x27, STR_00F4_500M),
+
+ MS(0xD7, STR_00EB_ROADS),
+ MK(0x0A, STR_00EC_RAILROADS),
+ MK(0x98, STR_00ED_STATIONS_AIRPORTS_DOCKS),
+ MK(0xB5, STR_00EE_BUILDINGS_INDUSTRIES),
+ MK(0x0F, STR_00EF_VEHICLES),
+ MKEND()
+};
+
+static const uint16 _legend_vehicles[] = {
+ MK(0xB8, STR_00F5_TRAINS),
+ MK(0xBF, STR_00F6_ROAD_VEHICLES),
+ MK(0x98, STR_00F7_SHIPS),
+ MK(0x0F, STR_00F8_AIRCRAFT),
+ MS(0xD7, STR_00F9_TRANSPORT_ROUTES),
+ MK(0xB5, STR_00EE_BUILDINGS_INDUSTRIES),
+ MKEND()
+};
+
+static const uint16 _legend_industries_normal[] = {
+ MK(0xD7, STR_00FA_COAL_MINE),
+ MK(0xB8, STR_00FB_POWER_STATION),
+ MK(0x56, STR_00FC_FOREST),
+ MK(0xC2, STR_00FD_SAWMILL),
+ MK(0xBF, STR_00FE_OIL_REFINERY),
+ MK(0x0F, STR_0105_BANK),
+
+ MS(0x30, STR_00FF_FARM),
+ MK(0xAE, STR_0100_FACTORY),
+ MK(0x98, STR_0102_OIL_WELLS),
+ MK(0x37, STR_0103_IRON_ORE_MINE),
+ MK(0x0A, STR_0104_STEEL_MILL),
+ MKEND()
+};
+
+static const uint16 _legend_industries_hilly[] = {
+ MK(0xD7, STR_00FA_COAL_MINE),
+ MK(0xB8, STR_00FB_POWER_STATION),
+ MK(0x56, STR_00FC_FOREST),
+ MK(0x0A, STR_0106_PAPER_MILL),
+ MK(0xBF, STR_00FE_OIL_REFINERY),
+ MK(0x37, STR_0108_FOOD_PROCESSING_PLANT),
+ MS(0x30, STR_00FF_FARM),
+
+ MK(0xAE, STR_0101_PRINTING_WORKS),
+ MK(0x98, STR_0102_OIL_WELLS),
+ MK(0xC2, STR_0107_GOLD_MINE),
+ MK(0x0F, STR_0105_BANK),
+ MKEND()
+};
+
+static const uint16 _legend_industries_desert[] = {
+ MK(0xBF, STR_00FE_OIL_REFINERY),
+ MK(0x98, STR_0102_OIL_WELLS),
+ MK(0x0F, STR_0105_BANK),
+ MK(0xB8, STR_0109_DIAMOND_MINE),
+ MK(0x37, STR_0108_FOOD_PROCESSING_PLANT),
+ MK(0x0A, STR_010A_COPPER_ORE_MINE),
+ MK(0x30, STR_00FF_FARM),
+ MS(0x56, STR_010B_FRUIT_PLANTATION),
+
+ MK(0x27, STR_010C_RUBBER_PLANTATION),
+ MK(0x25, STR_010D_WATER_SUPPLY),
+ MK(0xD0, STR_010E_WATER_TOWER),
+ MK(0xAE, STR_0100_FACTORY),
+ MK(0xC2, STR_010F_LUMBER_MILL),
+ MKEND()
+};
+
+static const uint16 _legend_industries_candy[] = {
+ MK(0x30, STR_0110_COTTON_CANDY_FOREST),
+ MK(0xAE, STR_0111_CANDY_FACTORY),
+ MK(0x27, STR_0112_BATTERY_FARM),
+ MK(0x37, STR_0113_COLA_WELLS),
+ MK(0xD0, STR_0114_TOY_SHOP),
+ MK(0x0A, STR_0115_TOY_FACTORY),
+ MS(0x25, STR_0116_PLASTIC_FOUNTAINS),
+
+ MK(0xB8, STR_0117_FIZZY_DRINK_FACTORY),
+ MK(0x98, STR_0118_BUBBLE_GENERATOR),
+ MK(0xC2, STR_0119_TOFFEE_QUARRY),
+ MK(0x0F, STR_011A_SUGAR_MINE),
+ MKEND()
+};
+
+static const uint16 _legend_routes[] = {
+ MK(0xD7, STR_00EB_ROADS),
+ MK(0x0A, STR_00EC_RAILROADS),
+ MK(0xB5, STR_00EE_BUILDINGS_INDUSTRIES),
+ MS(0x56, STR_011B_RAILROAD_STATION),
+
+ MK(0xC2, STR_011C_TRUCK_LOADING_BAY),
+ MK(0xBF, STR_011D_BUS_STATION),
+ MK(0xB8, STR_011E_AIRPORT_HELIPORT),
+ MK(0x98, STR_011F_DOCK),
+ MKEND()
+};
+
+static const uint16 _legend_vegetation[] = {
+ MK(0x52, STR_0120_ROUGH_LAND),
+ MK(0x54, STR_0121_GRASS_LAND),
+ MK(0x37, STR_0122_BARE_LAND),
+ MK(0x25, STR_0123_FIELDS),
+ MK(0x57, STR_0124_TREES),
+ MK(0xD0, STR_00FC_FOREST),
+ MS(0x0A, STR_0125_ROCKS),
+
+ MK(0xC2, STR_012A_DESERT),
+ MK(0x98, STR_012B_SNOW),
+ MK(0xD7, STR_00F9_TRANSPORT_ROUTES),
+ MK(0xB5, STR_00EE_BUILDINGS_INDUSTRIES),
+ MKEND()
+};
+
+static const uint16 _legend_land_owners[] = {
+ MK(0xCA, STR_0126_WATER),
+ MK(0x54, STR_0127_NO_OWNER),
+ MK(0xB4, STR_0128_TOWNS),
+ MK(0x20, STR_0129_INDUSTRIES),
+ MKEND()
+};
+#undef MK
+#undef MS
+#undef MKEND
+
+
+enum { IND_OFFS = 6 };
+static const uint16 * const _legend_table[] = {
+ _legend_land_contours,
+ _legend_vehicles,
+ NULL,
+ _legend_routes,
+ _legend_vegetation,
+ _legend_land_owners,
+
+ _legend_industries_normal,
+ _legend_industries_hilly,
+ _legend_industries_desert,
+ _legend_industries_candy,
+};
+
+#if defined(OTTD_ALIGNMENT)
+ static inline void WRITE_PIXELS(Pixel* d, uint32 val)
+ {
+# if defined(TTD_BIG_ENDIAN)
+ d[0] = GB(val, 24, 8);
+ d[1] = GB(val, 16, 8);
+ d[2] = GB(val, 8, 8);
+ d[3] = GB(val, 0, 8);
+# elif defined(TTD_LITTLE_ENDIAN)
+ d[0] = GB(val, 0, 8);
+ d[1] = GB(val, 8, 8);
+ d[2] = GB(val, 16, 8);
+ d[3] = GB(val, 24, 8);
+# endif
+ }
+
+/* need to use OR, otherwise we will overwrite the wrong pixels at the edges :( */
+ static inline void WRITE_PIXELS_OR(Pixel *d, uint32 val)
+ {
+# if defined(TTD_BIG_ENDIAN)
+ d[0] |= GB(val, 24, 8);
+ d[1] |= GB(val, 16, 8);
+ d[2] |= GB(val, 8, 8);
+ d[3] |= GB(val, 0, 8);
+# elif defined(TTD_LITTLE_ENDIAN)
+ d[0] |= GB(val, 0, 8);
+ d[1] |= GB(val, 8, 8);
+ d[2] |= GB(val, 16, 8);
+ d[3] |= GB(val, 24, 8);
+# endif
+ }
+#else
+# define WRITE_PIXELS(dst, val) *(uint32*)(dst) = (val);
+# define WRITE_PIXELS_OR(dst,val) *(uint32*)(dst) |= (val);
+#endif
+
+#define MKCOLOR(x) TO_LE32X(x)
+
+/* Height encodings; 16 levels XXX - needs updating for more/finer heights! */
+static const uint32 _map_height_bits[16] = {
+ MKCOLOR(0x5A5A5A5A),
+ MKCOLOR(0x5A5B5A5B),
+ MKCOLOR(0x5B5B5B5B),
+ MKCOLOR(0x5B5C5B5C),
+ MKCOLOR(0x5C5C5C5C),
+ MKCOLOR(0x5C5D5C5D),
+ MKCOLOR(0x5D5D5D5D),
+ MKCOLOR(0x5D5E5D5E),
+ MKCOLOR(0x5E5E5E5E),
+ MKCOLOR(0x5E5F5E5F),
+ MKCOLOR(0x5F5F5F5F),
+ MKCOLOR(0x5F1F5F1F),
+ MKCOLOR(0x1F1F1F1F),
+ MKCOLOR(0x1F271F27),
+ MKCOLOR(0x27272727),
+ MKCOLOR(0x27272727),
+};
+
+typedef struct AndOr {
+ uint32 mor;
+ uint32 mand;
+} AndOr;
+
+static inline uint32 ApplyMask(uint32 colour, const AndOr *mask)
+{
+ return (colour & mask->mand) | mask->mor;
+}
+
+
+static const AndOr _smallmap_contours_andor[] = {
+ {MKCOLOR(0x00000000), MKCOLOR(0xFFFFFFFF)},
+ {MKCOLOR(0x000A0A00), MKCOLOR(0xFF0000FF)},
+ {MKCOLOR(0x00D7D700), MKCOLOR(0xFF0000FF)},
+ {MKCOLOR(0x00B5B500), MKCOLOR(0xFF0000FF)},
+ {MKCOLOR(0x00000000), MKCOLOR(0xFFFFFFFF)},
+ {MKCOLOR(0x98989898), MKCOLOR(0x00000000)},
+ {MKCOLOR(0xCACACACA), MKCOLOR(0x00000000)},
+ {MKCOLOR(0x00000000), MKCOLOR(0xFFFFFFFF)},
+ {MKCOLOR(0xB5B5B5B5), MKCOLOR(0x00000000)},
+ {MKCOLOR(0x00000000), MKCOLOR(0xFFFFFFFF)},
+ {MKCOLOR(0x00B5B500), MKCOLOR(0xFF0000FF)},
+ {MKCOLOR(0x000A0A00), MKCOLOR(0xFF0000FF)},
+};
+
+static const AndOr _smallmap_vehicles_andor[] = {
+ {MKCOLOR(0x00000000), MKCOLOR(0xFFFFFFFF)},
+ {MKCOLOR(0x00D7D700), MKCOLOR(0xFF0000FF)},
+ {MKCOLOR(0x00D7D700), MKCOLOR(0xFF0000FF)},
+ {MKCOLOR(0x00B5B500), MKCOLOR(0xFF0000FF)},
+ {MKCOLOR(0x00000000), MKCOLOR(0xFFFFFFFF)},
+ {MKCOLOR(0x00D7D700), MKCOLOR(0xFF0000FF)},
+ {MKCOLOR(0xCACACACA), MKCOLOR(0x00000000)},
+ {MKCOLOR(0x00000000), MKCOLOR(0xFFFFFFFF)},
+ {MKCOLOR(0xB5B5B5B5), MKCOLOR(0x00000000)},
+ {MKCOLOR(0x00000000), MKCOLOR(0xFFFFFFFF)},
+ {MKCOLOR(0x00B5B500), MKCOLOR(0xFF0000FF)},
+ {MKCOLOR(0x00D7D700), MKCOLOR(0xFF0000FF)},
+};
+
+static const AndOr _smallmap_vegetation_andor[] = {
+ {MKCOLOR(0x00000000), MKCOLOR(0xFFFFFFFF)},
+ {MKCOLOR(0x00D7D700), MKCOLOR(0xFF0000FF)},
+ {MKCOLOR(0x00D7D700), MKCOLOR(0xFF0000FF)},
+ {MKCOLOR(0x00B5B500), MKCOLOR(0xFF0000FF)},
+ {MKCOLOR(0x00575700), MKCOLOR(0xFF0000FF)},
+ {MKCOLOR(0x00D7D700), MKCOLOR(0xFF0000FF)},
+ {MKCOLOR(0xCACACACA), MKCOLOR(0x00000000)},
+ {MKCOLOR(0x00000000), MKCOLOR(0xFFFFFFFF)},
+ {MKCOLOR(0xB5B5B5B5), MKCOLOR(0x00000000)},
+ {MKCOLOR(0x00000000), MKCOLOR(0xFFFFFFFF)},
+ {MKCOLOR(0x00B5B500), MKCOLOR(0xFF0000FF)},
+ {MKCOLOR(0x00D7D700), MKCOLOR(0xFF0000FF)},
+};
+
+typedef uint32 GetSmallMapPixels(TileIndex tile); // typedef callthrough function
+
+/**
+ * Draws one column of the small map in a certain mode onto the screen buffer. This
+ * function looks exactly the same for all types
+ *
+ * @param dst Pointer to a part of the screen buffer to write to.
+ * @param xc The X coordinate of the first tile in the column.
+ * @param yc The Y coordinate of the first tile in the column
+ * @param pitch Number of pixels to advance in the screen buffer each time a pixel is written.
+ * @param reps Number of lines to draw
+ * @param mask ?
+ * @param proc Pointer to the colour function
+ * @see GetSmallMapPixels(TileIndex)
+ */
+static void DrawSmallMapStuff(Pixel *dst, uint xc, uint yc, int pitch, int reps, uint32 mask, GetSmallMapPixels *proc)
+{
+ Pixel *dst_ptr_end = _screen.dst_ptr + _screen.width * _screen.height - _screen.width;
+
+ do {
+ // check if the tile (xc,yc) is within the map range
+ if (xc < MapMaxX() && yc < MapMaxY()) {
+ // check if the dst pointer points to a pixel inside the screen buffer
+ if (dst > _screen.dst_ptr && dst < dst_ptr_end)
+ WRITE_PIXELS_OR(dst, proc(TileXY(xc, yc)) & mask);
+ }
+ // switch to next tile in the column
+ } while (xc++, yc++, dst += pitch, --reps != 0);
+}
+
+
+static inline TileType GetEffectiveTileType(TileIndex tile)
+{
+ TileType t = GetTileType(tile);
+
+ if (t == MP_TUNNELBRIDGE) {
+ TransportType tt;
+
+ if (IsTunnel(tile)) {
+ tt = GetTunnelTransportType(tile);
+ } else {
+ tt = GetBridgeTransportType(tile);
+ }
+ switch (tt) {
+ case TRANSPORT_RAIL: t = MP_RAILWAY; break;
+ case TRANSPORT_ROAD: t = MP_STREET; break;
+ default: t = MP_WATER; break;
+ }
+ }
+ return t;
+}
+
+/**
+ * Return the color a tile would be displayed with in the small map in mode "Contour".
+ * @param tile The tile of which we would like to get the color.
+ * @return The color of tile in the small map in mode "Contour"
+ */
+static inline uint32 GetSmallMapContoursPixels(TileIndex tile)
+{
+ TileType t = GetEffectiveTileType(tile);
+
+ return
+ ApplyMask(_map_height_bits[TileHeight(tile)], &_smallmap_contours_andor[t]);
+}
+
+/**
+ * Return the color a tile would be displayed with in the small map in mode "Vehicles".
+ *
+ * @param t The tile of which we would like to get the color.
+ * @return The color of tile in the small map in mode "Vehicles"
+ */
+static inline uint32 GetSmallMapVehiclesPixels(TileIndex tile)
+{
+ TileType t = GetEffectiveTileType(tile);
+
+ return ApplyMask(MKCOLOR(0x54545454), &_smallmap_vehicles_andor[t]);
+}
+
+/* Industry colours... a total of 175 gfx - XXX - increase if more industries */
+static const byte _industry_smallmap_colors[175] = {
+ 215, 215, 215, 215, 215, 215, 215, 184,
+ 184, 184, 184, 194, 194, 194, 194, 194,
+ 86, 86, 191, 191, 191, 191, 191, 191,
+ 152, 152, 152, 152, 152, 152, 152, 152,
+ 152, 48, 48, 48, 48, 48, 48, 174,
+ 174, 174, 174, 174, 174, 174, 174, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 15, 15, 55, 55, 55, 55,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 194, 194, 194, 194, 194, 194, 194, 194,
+ 194, 194, 194, 194, 194, 194, 194, 194,
+ 194, 15, 15, 184, 184, 184, 184, 184,
+ 184, 184, 184, 184, 55, 55, 55, 55,
+ 55, 55, 55, 55, 55, 55, 55, 55,
+ 55, 55, 55, 55, 86, 39, 37, 37,
+ 208, 174, 174, 174, 174, 194, 194, 194,
+ 194, 48, 48, 174, 174, 174, 174, 39,
+ 39, 55, 208, 208, 208, 208, 10, 10,
+ 10, 10, 10, 10, 37, 37, 37, 37,
+ 37, 37, 37, 37, 184, 184, 184, 184,
+ 152, 152, 152, 152, 194, 194, 194, 15,
+ 15, 15, 15, 15, 15, 15, 15,
+};
+
+/**
+ * Return the color a tile would be displayed with in the small map in mode "Industries".
+ *
+ * @param tile The tile of which we would like to get the color.
+ * @return The color of tile in the small map in mode "Industries"
+ */
+static inline uint32 GetSmallMapIndustriesPixels(TileIndex tile)
+{
+ TileType t = GetEffectiveTileType(tile);
+
+ if (t == MP_INDUSTRY) {
+ return _industry_smallmap_colors[GetIndustryGfx(tile)] * 0x01010101;
+ }
+
+ return ApplyMask(MKCOLOR(0x54545454), &_smallmap_vehicles_andor[t]);
+}
+
+/**
+ * Return the color a tile would be displayed with in the small map in mode "Routes".
+ *
+ * @param t The tile of which we would like to get the color.
+ * @return The color of tile in the small map in mode "Routes"
+ */
+static inline uint32 GetSmallMapRoutesPixels(TileIndex tile)
+{
+ TileType t = GetEffectiveTileType(tile);
+ uint32 bits;
+
+ if (t == MP_STATION) {
+ switch (GetStationType(tile)) {
+ case STATION_RAIL: bits = MKCOLOR(0x56565656); break;
+ case STATION_AIRPORT: bits = MKCOLOR(0xB8B8B8B8); break;
+ case STATION_TRUCK: bits = MKCOLOR(0xC2C2C2C2); break;
+ case STATION_BUS: bits = MKCOLOR(0xBFBFBFBF); break;
+ case STATION_DOCK: bits = MKCOLOR(0x98989898); break;
+ default: bits = MKCOLOR(0xFFFFFFFF); break;
+ }
+ } else {
+ // ground color
+ bits = ApplyMask(MKCOLOR(0x54545454), &_smallmap_contours_andor[t]);
+ }
+ return bits;
+}
+
+
+static const uint32 _vegetation_clear_bits[] = {
+ MKCOLOR(0x54545454), ///< full grass
+ MKCOLOR(0x52525252), ///< rough land
+ MKCOLOR(0x0A0A0A0A), ///< rocks
+ MKCOLOR(0x25252525), ///< fields
+ MKCOLOR(0x98989898), ///< snow
+ MKCOLOR(0xC2C2C2C2), ///< desert
+ MKCOLOR(0x54545454), ///< unused
+ MKCOLOR(0x54545454), ///< unused
+};
+
+static inline uint32 GetSmallMapVegetationPixels(TileIndex tile)
+{
+ TileType t = GetEffectiveTileType(tile);
+ uint32 bits;
+
+ switch (t) {
+ case MP_CLEAR:
+ if (IsClearGround(tile, CLEAR_GRASS) && GetClearDensity(tile) < 3) {
+ bits = MKCOLOR(0x37373737);
+ } else {
+ bits = _vegetation_clear_bits[GetClearGround(tile)];
+ }
+ break;
+
+ case MP_INDUSTRY:
+ bits = GetIndustryType(tile) == IT_FOREST ? MKCOLOR(0xD0D0D0D0) : MKCOLOR(0xB5B5B5B5);
+ break;
+
+ case MP_TREES:
+ if (GetTreeGround(tile) == TREE_GROUND_SNOW_DESERT) {
+ bits = (_opt.landscape == LT_HILLY) ? MKCOLOR(0x98575798) : MKCOLOR(0xC25757C2);
+ } else {
+ bits = MKCOLOR(0x54575754);
+ }
+ break;
+
+ default:
+ bits = ApplyMask(MKCOLOR(0x54545454), &_smallmap_vehicles_andor[t]);
+ break;
+ }
+
+ return bits;
+}
+
+
+static uint32 _owner_colors[OWNER_END + 1];
+
+/**
+ * Return the color a tile would be displayed with in the small map in mode "Owner".
+ *
+ * @param t The tile of which we would like to get the color.
+ * @return The color of tile in the small map in mode "Owner"
+ */
+static inline uint32 GetSmallMapOwnerPixels(TileIndex tile)
+{
+ Owner o;
+
+ switch (GetTileType(tile)) {
+ case MP_INDUSTRY: o = OWNER_END; break;
+ case MP_HOUSE: o = OWNER_TOWN; break;
+ default: o = GetTileOwner(tile); break;
+ }
+
+ return _owner_colors[o];
+}
+
+
+static const uint32 _smallmap_mask_left[3] = {
+ MKCOLOR(0xFF000000),
+ MKCOLOR(0xFFFF0000),
+ MKCOLOR(0xFFFFFF00),
+};
+
+static const uint32 _smallmap_mask_right[] = {
+ MKCOLOR(0x000000FF),
+ MKCOLOR(0x0000FFFF),
+ MKCOLOR(0x00FFFFFF),
+};
+
+/* each tile has 4 x pixels and 1 y pixel */
+
+static GetSmallMapPixels *_smallmap_draw_procs[] = {
+ GetSmallMapContoursPixels,
+ GetSmallMapVehiclesPixels,
+ GetSmallMapIndustriesPixels,
+ GetSmallMapRoutesPixels,
+ GetSmallMapVegetationPixels,
+ GetSmallMapOwnerPixels,
+};
+
+static const byte _vehicle_type_colors[6] = {
+ 184, 191, 152, 15, 215, 184
+};
+
+
+static void DrawVertMapIndicator(int x, int y, int x2, int y2)
+{
+ GfxFillRect(x, y, x2, y + 3, 69);
+ GfxFillRect(x, y2 - 3, x2, y2, 69);
+}
+
+static void DrawHorizMapIndicator(int x, int y, int x2, int y2)
+{
+ GfxFillRect(x, y, x + 3, y2, 69);
+ GfxFillRect(x2 - 3, y, x2, y2, 69);
+}
+
+/**
+ * Draws the small map.
+ *
+ * Basically, the small map is draw column of pixels by column of pixels. The pixels
+ * are drawn directly into the screen buffer. The final map is drawn in multiple passes.
+ * The passes are:
+ * <ol><li>The colors of tiles in the different modes.</li>
+ * <li>Town names (optional)</li>
+ *
+ * @param dpi pointer to pixel to write onto
+ * @param w pointer to Window struct
+ * @param type type of map requested (vegetation, owners, routes, etc)
+ * @param show_towns true if the town names should be displayed, false if not.
+ */
+static void DrawSmallMap(DrawPixelInfo *dpi, Window *w, int type, bool show_towns)
+{
+ DrawPixelInfo *old_dpi;
+ int dx,dy, x, y, x2, y2;
+ Pixel *ptr;
+ int tile_x;
+ int tile_y;
+ ViewPort *vp;
+
+ old_dpi = _cur_dpi;
+ _cur_dpi = dpi;
+
+ /* clear it */
+ GfxFillRect(dpi->left, dpi->top, dpi->left + dpi->width - 1, dpi->top + dpi->height - 1, 0);
+
+ /* setup owner table */
+ if (type == 5) {
+ const Player *p;
+
+ /* fill with some special colors */
+ _owner_colors[OWNER_TOWN] = MKCOLOR(0xB4B4B4B4);
+ _owner_colors[OWNER_NONE] = MKCOLOR(0x54545454);
+ _owner_colors[OWNER_WATER] = MKCOLOR(0xCACACACA);
+ _owner_colors[OWNER_END] = MKCOLOR(0x20202020); /* industry */
+
+ /* now fill with the player colors */
+ FOR_ALL_PLAYERS(p) {
+ if (p->is_active) {
+ _owner_colors[p->index] =
+ _colour_gradient[p->player_color][5] * 0x01010101;
+ }
+ }
+ }
+
+ tile_x = WP(w,smallmap_d).scroll_x / TILE_SIZE;
+ tile_y = WP(w,smallmap_d).scroll_y / TILE_SIZE;
+
+ dx = dpi->left + WP(w,smallmap_d).subscroll;
+ tile_x -= dx / 4;
+ tile_y += dx / 4;
+ dx &= 3;
+
+ dy = dpi->top;
+ tile_x += dy / 2;
+ tile_y += dy / 2;
+
+ if (dy & 1) {
+ tile_x++;
+ dx += 2;
+ if (dx > 3) {
+ dx -= 4;
+ tile_x--;
+ tile_y++;
+ }
+ }
+
+ ptr = dpi->dst_ptr - dx - 4;
+ x = - dx - 4;
+ y = 0;
+
+ for (;;) {
+ uint32 mask = 0xFFFFFFFF;
+ int reps;
+ int t;
+
+ /* distance from left edge */
+ if (x < 0) {
+ if (x < -3) goto skip_column;
+ /* mask to use at the left edge */
+ mask = _smallmap_mask_left[x + 3];
+ }
+
+ /* distance from right edge */
+ t = dpi->width - x;
+ if (t < 4) {
+ if (t <= 0) break; /* exit loop */
+ /* mask to use at the right edge */
+ mask &= _smallmap_mask_right[t - 1];
+ }
+
+ /* number of lines */
+ reps = (dpi->height - y + 1) / 2;
+ if (reps > 0) {
+// assert(ptr >= dpi->dst_ptr);
+ DrawSmallMapStuff(ptr, tile_x, tile_y, dpi->pitch * 2, reps, mask, _smallmap_draw_procs[type]);
+ }
+
+skip_column:
+ if (y == 0) {
+ tile_y++;
+ y++;
+ ptr += dpi->pitch;
+ } else {
+ tile_x--;
+ y--;
+ ptr -= dpi->pitch;
+ }
+ ptr += 2;
+ x += 2;
+ }
+
+ /* draw vehicles? */
+ if (type == 0 || type == 1) {
+ Vehicle *v;
+ bool skip;
+ byte color;
+
+ FOR_ALL_VEHICLES(v) {
+ if (v->type != VEH_Special &&
+ (v->vehstatus & (VS_HIDDEN | VS_UNCLICKABLE)) == 0) {
+ // Remap into flat coordinates.
+ Point pt = RemapCoords(
+ v->x_pos / TILE_SIZE - WP(w,smallmap_d).scroll_x / TILE_SIZE, // divide each one separately because (a-b)/c != a/c-b/c in integer world
+ v->y_pos / TILE_SIZE - WP(w,smallmap_d).scroll_y / TILE_SIZE, // dtto
+ 0);
+ x = pt.x;
+ y = pt.y;
+
+ // Check if y is out of bounds?
+ y -= dpi->top;
+ if (!IS_INT_INSIDE(y, 0, dpi->height)) continue;
+
+ // Default is to draw both pixels.
+ skip = false;
+
+ // Offset X coordinate
+ x -= WP(w,smallmap_d).subscroll + 3 + dpi->left;
+
+ if (x < 0) {
+ // if x+1 is 0, that means we're on the very left edge,
+ // and should thus only draw a single pixel
+ if (++x != 0) continue;
+ skip = true;
+ } else if (x >= dpi->width - 1) {
+ // Check if we're at the very right edge, and if so draw only a single pixel
+ if (x != dpi->width - 1) continue;
+ skip = true;
+ }
+
+ // Calculate pointer to pixel and the color
+ ptr = dpi->dst_ptr + y * dpi->pitch + x;
+ color = (type == 1) ? _vehicle_type_colors[v->type-0x10] : 0xF;
+
+ // And draw either one or two pixels depending on clipping
+ ptr[0] = color;
+ if (!skip) ptr[1] = color;
+ }
+ }
+ }
+
+ if (show_towns) {
+ const Town *t;
+
+ FOR_ALL_TOWNS(t) {
+ // Remap the town coordinate
+ Point pt = RemapCoords(
+ (int)(TileX(t->xy) * TILE_SIZE - WP(w, smallmap_d).scroll_x) / TILE_SIZE,
+ (int)(TileY(t->xy) * TILE_SIZE - WP(w, smallmap_d).scroll_y) / TILE_SIZE,
+ 0);
+ x = pt.x - WP(w,smallmap_d).subscroll + 3 - (t->sign.width_2 >> 1);
+ y = pt.y;
+
+ // Check if the town sign is within bounds
+ if (x + t->sign.width_2 > dpi->left &&
+ x < dpi->left + dpi->width &&
+ y + 6 > dpi->top &&
+ y < dpi->top + dpi->height) {
+ // And draw it.
+ SetDParam(0, t->index);
+ DrawString(x, y, STR_2056, 12);
+ }
+ }
+ }
+
+ // Draw map indicators
+ {
+ Point pt;
+
+ // Find main viewport.
+ vp = FindWindowById(WC_MAIN_WINDOW,0)->viewport;
+
+ pt = RemapCoords(WP(w, smallmap_d).scroll_x, WP(w, smallmap_d).scroll_y, 0);
+
+ x = vp->virtual_left - pt.x;
+ y = vp->virtual_top - pt.y;
+ x2 = (x + vp->virtual_width) / TILE_SIZE;
+ y2 = (y + vp->virtual_height) / TILE_SIZE;
+ x /= TILE_SIZE;
+ y /= TILE_SIZE;
+
+ x -= WP(w,smallmap_d).subscroll;
+ x2 -= WP(w,smallmap_d).subscroll;
+
+ DrawVertMapIndicator(x, y, x, y2);
+ DrawVertMapIndicator(x2, y, x2, y2);
+
+ DrawHorizMapIndicator(x, y, x2, y);
+ DrawHorizMapIndicator(x, y2, x2, y2);
+ }
+ _cur_dpi = old_dpi;
+}
+
+void SmallMapCenterOnCurrentPos(Window *w)
+{
+ int x, y;
+ ViewPort *vp;
+ vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
+
+ x = ((vp->virtual_width - (w->widget[4].right - w->widget[4].left) * TILE_SIZE) / 2 + vp->virtual_left) / 4;
+ y = ((vp->virtual_height - (w->widget[4].bottom - w->widget[4].top ) * TILE_SIZE) / 2 + vp->virtual_top ) / 2 - TILE_SIZE * 2;
+ WP(w, smallmap_d).scroll_x = (y - x) & ~0xF;
+ WP(w, smallmap_d).scroll_y = (x + y) & ~0xF;
+ SetWindowDirty(w);
+}
+
+static void SmallMapWindowProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ const uint16 *tbl;
+ int x, y, y_org;
+ DrawPixelInfo new_dpi;
+
+ /* draw the window */
+ SetDParam(0, STR_00E5_CONTOURS + _smallmap_type);
+ DrawWindowWidgets(w);
+
+ /* draw the legend */
+ tbl = _legend_table[(_smallmap_type != 2) ? _smallmap_type : (_opt.landscape + IND_OFFS)];
+ x = 4;
+ y_org = w->height - 44 - 11;
+ y = y_org;
+ for (;;) {
+ GfxFillRect(x, y + 1, x + 8, y + 5, 0);
+ GfxFillRect(x + 1, y + 2, x + 7, y + 4, (byte)tbl[0]);
+ DrawString(x + 11, y, tbl[1], 0);
+
+ tbl += 2;
+ y += 6;
+
+ if (tbl[0] == 0xFFFF) {
+ break;
+ } else if (tbl[0] & 0x100) {
+ x += 123;
+ y = y_org;
+ }
+ }
+
+ if (!FillDrawPixelInfo(&new_dpi, 3, 17, w->width - 28 + 22, w->height - 64 - 11))
+ return;
+
+ DrawSmallMap(&new_dpi, w, _smallmap_type, _smallmap_show_towns);
+ } break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 4: { // Map window
+ Window *w2 = FindWindowById(WC_MAIN_WINDOW, 0);
+ Point pt;
+
+ /*
+ * XXX: scrolling with the left mouse button is done by subsequently
+ * clicking with the left mouse button; clicking once centers the
+ * large map at the selected point. So by unclicking the left mouse
+ * button here, it gets reclicked during the next inputloop, which
+ * would make it look like the mouse is being dragged, while it is
+ * actually being (virtually) clicked every inputloop.
+ */
+ _left_button_clicked = false;
+
+ pt = RemapCoords(WP(w,smallmap_d).scroll_x, WP(w,smallmap_d).scroll_y, 0);
+ WP(w2, vp_d).scrollpos_x = pt.x + ((_cursor.pos.x - w->left + 2) << 4) - (w2->viewport->virtual_width >> 1);
+ WP(w2, vp_d).scrollpos_y = pt.y + ((_cursor.pos.y - w->top - 16) << 4) - (w2->viewport->virtual_height >> 1);
+
+ SetWindowDirty(w);
+ } break;
+
+ case 5: // Show land contours
+ case 6: // Show vehicles
+ case 7: // Show industries
+ case 8: // Show transport routes
+ case 9: // Show vegetation
+ case 10: // Show land owners
+ RaiseWindowWidget(w, _smallmap_type + 5);
+ _smallmap_type = e->we.click.widget - 5;
+ LowerWindowWidget(w, _smallmap_type + 5);
+
+ SetWindowDirty(w);
+ SndPlayFx(SND_15_BEEP);
+ break;
+
+ case 11: // Center the smallmap again
+ SmallMapCenterOnCurrentPos(w);
+
+ SetWindowDirty(w);
+ SndPlayFx(SND_15_BEEP);
+ break;
+
+ case 12: // Toggle town names
+ ToggleWidgetLoweredState(w, 12);
+ _smallmap_show_towns = IsWindowWidgetLowered(w, 12);
+
+ SetWindowDirty(w);
+ SndPlayFx(SND_15_BEEP);
+ break;
+ }
+ break;
+
+ case WE_RCLICK:
+ if (e->we.click.widget == 4) {
+ if (_scrolling_viewport) return;
+ _scrolling_viewport = true;
+ _cursor.delta.x = 0;
+ _cursor.delta.y = 0;
+ }
+ break;
+
+ case WE_MOUSELOOP:
+ /* update the window every now and then */
+ if ((++w->vscroll.pos & 0x1F) == 0) SetWindowDirty(w);
+ break;
+
+ case WE_SCROLL: {
+ int x;
+ int y;
+ int sub;
+ int hx;
+ int hy;
+ int hvx;
+ int hvy;
+
+ _cursor.fix_at = true;
+
+ x = WP(w, smallmap_d).scroll_x;
+ y = WP(w, smallmap_d).scroll_y;
+
+ sub = WP(w, smallmap_d).subscroll + e->we.scroll.delta.x;
+
+ x -= (sub >> 2) << 4;
+ y += (sub >> 2) << 4;
+ sub &= 3;
+
+ x += (e->we.scroll.delta.y >> 1) << 4;
+ y += (e->we.scroll.delta.y >> 1) << 4;
+
+ if (e->we.scroll.delta.y & 1) {
+ x += TILE_SIZE;
+ sub += 2;
+ if (sub > 3) {
+ sub -= 4;
+ x -= TILE_SIZE;
+ y += TILE_SIZE;
+ }
+ }
+
+ hx = (w->widget[4].right - w->widget[4].left) / 2;
+ hy = (w->widget[4].bottom - w->widget[4].top ) / 2;
+ hvx = hx * -4 + hy * 8;
+ hvy = hx * 4 + hy * 8;
+ if (x < -hvx) {
+ x = -hvx;
+ sub = 0;
+ }
+ if (x > (int)MapMaxX() * TILE_SIZE - hvx) {
+ x = MapMaxX() * TILE_SIZE - hvx;
+ sub = 0;
+ }
+ if (y < -hvy) {
+ y = -hvy;
+ sub = 0;
+ }
+ if (y > (int)MapMaxY() * TILE_SIZE - hvy) {
+ y = MapMaxY() * TILE_SIZE - hvy;
+ sub = 0;
+ }
+
+ WP(w, smallmap_d).scroll_x = x;
+ WP(w, smallmap_d).scroll_y = y;
+ WP(w, smallmap_d).subscroll = sub;
+
+ SetWindowDirty(w);
+ } break;
+ }
+}
+
+static const WindowDesc _smallmap_desc = {
+ WDP_AUTO, WDP_AUTO, 446, 314,
+ WC_SMALLMAP,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON | WDF_RESIZABLE,
+ _smallmap_widgets,
+ SmallMapWindowProc
+};
+
+void ShowSmallMap(void)
+{
+ Window *w;
+
+ w = AllocateWindowDescFront(&_smallmap_desc, 0);
+ if (w == NULL) return;
+
+ LowerWindowWidget(w, _smallmap_type + 5);
+ SetWindowWidgetLoweredState(w, 12, _smallmap_show_towns);
+ w->resize.width = 350;
+ w->resize.height = 250;
+
+ SmallMapCenterOnCurrentPos(w);
+}
+
+/* Extra ViewPort Window Stuff */
+static const Widget _extra_view_port_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_RIGHT, 14, 11, 287, 0, 13, STR_EXTRA_VIEW_PORT_TITLE, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_STICKYBOX, RESIZE_LR, 14, 288, 299, 0, 13, 0x0, STR_STICKY_BUTTON},
+{ WWT_PANEL, RESIZE_RB, 14, 0, 299, 14, 233, 0x0, STR_NULL},
+{ WWT_INSET, RESIZE_RB, 14, 2, 297, 16, 231, 0x0, STR_NULL},
+{ WWT_PUSHIMGBTN, RESIZE_TB, 14, 0, 21, 234, 255, SPR_IMG_ZOOMIN, STR_017F_ZOOM_THE_VIEW_IN},
+{ WWT_PUSHIMGBTN, RESIZE_TB, 14, 22, 43, 234, 255, SPR_IMG_ZOOMOUT, STR_0180_ZOOM_THE_VIEW_OUT},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 44, 171, 234, 255, STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW, STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 172, 298, 234, 255, STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN, STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT},
+{ WWT_PANEL, RESIZE_RTB, 14, 299, 299, 234, 255, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_RTB, 14, 0, 287, 256, 267, 0x0, STR_NULL},
+{ WWT_RESIZEBOX, RESIZE_LRTB, 14, 288, 299, 256, 267, 0x0, STR_RESIZE_BUTTON},
+{ WIDGETS_END},
+};
+
+static void ExtraViewPortWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_CREATE: /* Disable zoom in button */
+ DisableWindowWidget(w, 5);
+ break;
+
+ case WE_PAINT:
+ // set the number in the title bar
+ SetDParam(0, w->window_number + 1);
+
+ DrawWindowWidgets(w);
+ DrawWindowViewport(w);
+ break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 5: DoZoomInOutWindow(ZOOM_IN, w); break;
+ case 6: DoZoomInOutWindow(ZOOM_OUT, w); break;
+
+ case 7: { /* location button (move main view to same spot as this view) 'Paste Location' */
+ Window *w2 = FindWindowById(WC_MAIN_WINDOW, 0);
+ int x = WP(w, vp_d).scrollpos_x; // Where is the main looking at
+ int y = WP(w, vp_d).scrollpos_y;
+
+ // set this view to same location. Based on the center, adjusting for zoom
+ WP(w2, vp_d).scrollpos_x = x - (w2->viewport->virtual_width - w->viewport->virtual_width) / 2;
+ WP(w2, vp_d).scrollpos_y = y - (w2->viewport->virtual_height - w->viewport->virtual_height) / 2;
+ } break;
+
+ case 8: { /* inverse location button (move this view to same spot as main view) 'Copy Location' */
+ const Window *w2 = FindWindowById(WC_MAIN_WINDOW, 0);
+ int x = WP(w2, const vp_d).scrollpos_x;
+ int y = WP(w2, const vp_d).scrollpos_y;
+
+ WP(w, vp_d).scrollpos_x = x + (w2->viewport->virtual_width - w->viewport->virtual_width) / 2;
+ WP(w, vp_d).scrollpos_y = y + (w2->viewport->virtual_height - w->viewport->virtual_height) / 2;
+ } break;
+ }
+ break;
+
+ case WE_RESIZE:
+ w->viewport->width += e->we.sizing.diff.x;
+ w->viewport->height += e->we.sizing.diff.y;
+ w->viewport->virtual_width += e->we.sizing.diff.x;
+ w->viewport->virtual_height += e->we.sizing.diff.y;
+ break;
+
+ case WE_SCROLL: {
+ ViewPort *vp = IsPtInWindowViewport(w, _cursor.pos.x, _cursor.pos.y);
+
+ if (vp == NULL) {
+ _cursor.fix_at = false;
+ _scrolling_viewport = false;
+ }
+
+ WP(w, vp_d).scrollpos_x += e->we.scroll.delta.x << vp->zoom;
+ WP(w, vp_d).scrollpos_y += e->we.scroll.delta.y << vp->zoom;
+ } break;
+
+ case WE_MOUSEWHEEL:
+ ZoomInOrOutToCursorWindow(e->we.wheel.wheel < 0, w);
+ break;
+
+
+ case WE_MESSAGE:
+ /* Only handle zoom message if intended for us (msg ZOOM_IN/ZOOM_OUT) */
+ if (e->we.message.wparam != w->window_number) break;
+ HandleZoomMessage(w, w->viewport, 5, 6);
+ break;
+ }
+}
+
+static const WindowDesc _extra_view_port_desc = {
+ WDP_AUTO, WDP_AUTO, 300, 268,
+ WC_EXTRA_VIEW_PORT,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
+ _extra_view_port_widgets,
+ ExtraViewPortWndProc
+};
+
+void ShowExtraViewPortWindow(void)
+{
+ Window *w, *v;
+ int i = 0;
+
+ // find next free window number for extra viewport
+ while (FindWindowById(WC_EXTRA_VIEW_PORT, i) != NULL) i++;
+
+ w = AllocateWindowDescFront(&_extra_view_port_desc, i);
+ if (w != NULL) {
+ int x, y;
+ // the main window with the main view
+ v = FindWindowById(WC_MAIN_WINDOW, 0);
+ // New viewport start ats (zero,zero)
+ AssignWindowViewport(w, 3, 17, 294, 214, 0 , 0);
+
+ // center on same place as main window (zoom is maximum, no adjustment needed)
+ x = WP(v, vp_d).scrollpos_x;
+ y = WP(v, vp_d).scrollpos_y;
+ WP(w, vp_d).scrollpos_x = x + (v->viewport->virtual_width - (294)) / 2;
+ WP(w, vp_d).scrollpos_y = y + (v->viewport->virtual_height - (214)) / 2;
+ }
+}
diff --git a/src/sound.c b/src/sound.c
new file mode 100644
index 000000000..7e78b07dd
--- /dev/null
+++ b/src/sound.c
@@ -0,0 +1,244 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "functions.h"
+#include "map.h"
+#include "mixer.h"
+#include "sound.h"
+#include "vehicle.h"
+#include "window.h"
+#include "viewport.h"
+#include "fileio.h"
+#include "newgrf_sound.h"
+
+static uint _file_count;
+static FileEntry *_files;
+
+#define SOUND_SLOT 63
+// Number of levels of panning per side
+#define PANNING_LEVELS 16
+
+
+static void OpenBankFile(const char *filename)
+{
+ FileEntry *fe;
+ uint count;
+ uint i;
+
+ FioOpenFile(SOUND_SLOT, filename);
+ count = FioReadDword() / 8;
+ fe = calloc(count, sizeof(*fe));
+
+ if (fe == NULL) {
+ _file_count = 0;
+ _files = NULL;
+ return;
+ }
+
+ _file_count = count;
+ _files = fe;
+
+ FioSeekTo(0, SEEK_SET);
+
+ for (i = 0; i != count; i++) {
+ fe[i].file_offset = FioReadDword();
+ fe[i].file_size = FioReadDword();
+ }
+
+ for (i = 0; i != count; i++, fe++) {
+ char name[255];
+
+ FioSeekTo(fe->file_offset, SEEK_SET);
+
+ // Check for special case, see else case
+ FioReadBlock(name, FioReadByte()); // Read the name of the sound
+ if (strcmp(name, "Corrupt sound") != 0) {
+ FioSeekTo(12, SEEK_CUR); // Skip past RIFF header
+
+ // Read riff tags
+ for (;;) {
+ uint32 tag = FioReadDword();
+ uint32 size = FioReadDword();
+
+ if (tag == ' tmf') {
+ FioReadWord(); // wFormatTag
+ fe->channels = FioReadWord(); // wChannels
+ FioReadDword(); // samples per second
+ fe->rate = 11025; // seems like all samples should be played at this rate.
+ FioReadDword(); // avg bytes per second
+ FioReadWord(); // alignment
+ fe->bits_per_sample = FioReadByte(); // bits per sample
+ FioSeekTo(size - (2 + 2 + 4 + 4 + 2 + 1), SEEK_CUR);
+ } else if (tag == 'atad') {
+ fe->file_size = size;
+ fe->file_offset = FioGetPos() | (SOUND_SLOT << 24);
+ break;
+ } else {
+ fe->file_size = 0;
+ break;
+ }
+ }
+ } else {
+ /*
+ * Special case for the jackhammer sound
+ * (name in sample.cat is "Corrupt sound")
+ * It's no RIFF file, but raw PCM data
+ */
+ fe->channels = 1;
+ fe->rate = 11025;
+ fe->bits_per_sample = 8;
+ fe->file_offset = FioGetPos() | (SOUND_SLOT << 24);
+ }
+ }
+}
+
+uint GetNumOriginalSounds(void)
+{
+ return _file_count;
+}
+
+static bool SetBankSource(MixerChannel *mc, uint bank)
+{
+ const FileEntry *fe;
+ int8 *mem;
+ uint i;
+
+ if (bank >= GetNumSounds()) return false;
+ fe = GetSound(bank);
+
+ if (fe->file_size == 0) return false;
+
+ mem = malloc(fe->file_size);
+ if (mem == NULL) return false;
+
+ FioSeekToFile(fe->file_offset);
+ FioReadBlock(mem, fe->file_size);
+
+ for (i = 0; i != fe->file_size; i++)
+ mem[i] += -128; // Convert unsigned sound data to signed
+
+ assert(fe->bits_per_sample == 8 && fe->channels == 1 && fe->file_size != 0 && fe->rate != 0);
+
+ MxSetChannelRawSrc(mc, mem, fe->file_size, fe->rate, MX_AUTOFREE);
+
+ return true;
+}
+
+bool SoundInitialize(const char *filename)
+{
+ OpenBankFile(filename);
+ return true;
+}
+
+// Low level sound player
+static void StartSound(uint sound, int panning, uint volume)
+{
+ MixerChannel *mc;
+ uint left_vol, right_vol;
+
+ if (volume == 0) return;
+ mc = MxAllocateChannel();
+ if (mc == NULL) return;
+ if (!SetBankSource(mc, sound)) return;
+
+ panning = clamp(panning, -PANNING_LEVELS, PANNING_LEVELS);
+ left_vol = (volume * PANNING_LEVELS) - (volume * panning);
+ right_vol = (volume * PANNING_LEVELS) + (volume * panning);
+ MxSetChannelVolume(mc, left_vol * 128 / PANNING_LEVELS, right_vol * 128 / PANNING_LEVELS);
+ MxActivateChannel(mc);
+}
+
+
+static const byte _vol_factor_by_zoom[] = {255, 190, 134};
+
+static const byte _sound_base_vol[] = {
+ 128, 90, 128, 128, 128, 128, 128, 128,
+ 128, 90, 90, 128, 128, 128, 128, 128,
+ 128, 128, 128, 80, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 90, 90, 90, 128, 90, 128,
+ 128, 90, 128, 128, 128, 90, 128, 128,
+ 128, 128, 128, 128, 90, 128, 128, 128,
+ 128, 90, 128, 128, 128, 128, 128, 128,
+ 128, 128, 90, 90, 90, 128, 128, 128,
+ 90,
+};
+
+static const byte _sound_idx[] = {
+ 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 40, 0,
+ 1, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71,
+ 72,
+};
+
+void SndCopyToPool(void)
+{
+ uint i;
+
+ for (i = 0; i < _file_count; i++) {
+ FileEntry *orig = &_files[_sound_idx[i]];
+ FileEntry *fe = AllocateFileEntry();
+
+ *fe = *orig;
+ fe->volume = _sound_base_vol[i];
+ fe->priority = 0;
+ }
+}
+
+static void SndPlayScreenCoordFx(SoundFx sound, int x, int y)
+{
+ Window* const *wz;
+
+ if (msf.effect_vol == 0) return;
+
+ FOR_ALL_WINDOWS(wz) {
+ const ViewPort *vp = (*wz)->viewport;
+
+ if (vp != NULL &&
+ IS_INSIDE_1D(x, vp->virtual_left, vp->virtual_width) &&
+ IS_INSIDE_1D(y, vp->virtual_top, vp->virtual_height)) {
+ int left = (x - vp->virtual_left);
+
+ StartSound(
+ sound,
+ left / (vp->virtual_width / ((PANNING_LEVELS << 1) + 1)) - PANNING_LEVELS,
+ (GetSound(sound)->volume * msf.effect_vol * _vol_factor_by_zoom[vp->zoom]) >> 15
+ );
+ return;
+ }
+ }
+
+}
+
+void SndPlayTileFx(SoundFx sound, TileIndex tile)
+{
+ /* emits sound from center of the tile */
+ int x = TileX(tile) * TILE_SIZE + TILE_SIZE / 2;
+ int y = TileY(tile) * TILE_SIZE + TILE_SIZE / 2;
+ Point pt = RemapCoords(x, y, GetSlopeZ(x, y));
+ SndPlayScreenCoordFx(sound, pt.x, pt.y);
+}
+
+void SndPlayVehicleFx(SoundFx sound, const Vehicle *v)
+{
+ SndPlayScreenCoordFx(sound,
+ (v->left_coord + v->right_coord) / 2,
+ (v->top_coord + v->bottom_coord) / 2
+ );
+}
+
+void SndPlayFx(SoundFx sound)
+{
+ StartSound(
+ sound,
+ 0,
+ (GetSound(sound)->volume * msf.effect_vol) >> 7
+ );
+}
diff --git a/src/sound.h b/src/sound.h
new file mode 100644
index 000000000..fd5638558
--- /dev/null
+++ b/src/sound.h
@@ -0,0 +1,113 @@
+/* $Id$ */
+
+#ifndef SOUND_H
+#define SOUND_H
+
+typedef struct MusicFileSettings {
+ byte playlist;
+ byte music_vol;
+ byte effect_vol;
+ byte custom_1[33];
+ byte custom_2[33];
+ bool playing;
+ bool shuffle;
+ char extmidi[80];
+} MusicFileSettings;
+
+VARDEF MusicFileSettings msf;
+
+typedef struct FileEntry {
+ uint32 file_offset;
+ uint32 file_size;
+ uint16 rate;
+ uint8 bits_per_sample;
+ uint8 channels;
+ uint8 volume;
+ uint8 priority;
+} FileEntry;
+
+bool SoundInitialize(const char *filename);
+uint GetNumOriginalSounds(void);
+
+typedef enum SoundFx {
+ SND_02_SPLAT, // 0 == 0x00 !
+ SND_03_FACTORY_WHISTLE,
+ SND_04_TRAIN,
+ SND_05_TRAIN_THROUGH_TUNNEL,
+ SND_06_SHIP_HORN,
+ SND_07_FERRY_HORN,
+ SND_08_PLANE_TAKE_OFF,
+ SND_09_JET,
+ SND_0A_TRAIN_HORN,
+ SND_0B_MINING_MACHINERY,
+ SND_0C_ELECTRIC_SPARK,
+ SND_0D_STEAM,
+ SND_0E_LEVEL_CROSSING,
+ SND_0F_VEHICLE_BREAKDOWN,
+ SND_10_TRAIN_BREAKDOWN,
+ SND_11_CRASH,
+ SND_12_EXPLOSION, // 16 == 0x10
+ SND_13_BIG_CRASH,
+ SND_14_CASHTILL,
+ SND_15_BEEP, // 19 == 0x13
+ SND_16_MORSE, // 20 == 0x14
+ SND_17_SKID_PLANE,
+ SND_18_HELICOPTER,
+ SND_19_BUS_START_PULL_AWAY,
+ SND_1A_BUS_START_PULL_AWAY_WITH_HORN,
+ SND_1B_TRUCK_START,
+ SND_1C_TRUCK_START_2,
+ SND_1D_APPLAUSE,
+ SND_1E_OOOOH,
+ SND_1F_SPLAT, // 29 == 0x1D
+ SND_20_SPLAT_2, // 30 == 0x1E
+ SND_21_JACKHAMMER,
+ SND_22_CAR_HORN,
+ SND_23_CAR_HORN_2,
+ SND_24_SHEEP,
+ SND_25_COW,
+ SND_26_HORSE,
+ SND_27_BLACKSMITH_ANVIL,
+ SND_28_SAWMILL, // 38 == 0x26 !
+ SND_00_GOOD_YEAR, // 39 == 0x27 !
+ SND_01_BAD_YEAR, // 40 == 0x28 !
+ SND_29_RIP, // 41 == 0x29 !
+ SND_2A_EXTRACT_AND_POP,
+ SND_2B_COMEDY_HIT,
+ SND_2C_MACHINERY,
+ SND_2D_RIP_2,
+ SND_2E_EXTRACT_AND_POP,
+ SND_2F_POP,
+ SND_30_CARTOON_SOUND,
+ SND_31_EXTRACT,
+ SND_32_POP_2,
+ SND_33_PLASTIC_MINE,
+ SND_34_WIND,
+ SND_35_COMEDY_BREAKDOWN,
+ SND_36_CARTOON_CRASH,
+ SND_37_BALLOON_SQUEAK,
+ SND_38_CHAINSAW,
+ SND_39_HEAVY_WIND,
+ SND_3A_COMEDY_BREAKDOWN_2,
+ SND_3B_JET_OVERHEAD,
+ SND_3C_COMEDY_CAR,
+ SND_3D_ANOTHER_JET_OVERHEAD,
+ SND_3E_COMEDY_CAR_2,
+ SND_3F_COMEDY_CAR_3,
+ SND_40_COMEDY_CAR_START_AND_PULL_AWAY,
+ SND_41_MAGLEV,
+ SND_42_LOON_BIRD,
+ SND_43_LION,
+ SND_44_MONKEYS,
+ SND_45_PLANE_CRASHING,
+ SND_46_PLANE_ENGINE_SPUTTERING,
+ SND_47_MAGLEV_2,
+ SND_48_DISTANT_BIRD // 72 == 0x48
+} SoundFx;
+
+void SndPlayTileFx(SoundFx sound, TileIndex tile);
+void SndPlayVehicleFx(SoundFx sound, const Vehicle *v);
+void SndPlayFx(SoundFx sound);
+void SndCopyToPool(void);
+
+#endif /* SOUND_H */
diff --git a/src/sound/cocoa_s.c b/src/sound/cocoa_s.c
new file mode 100644
index 000000000..3b758ad71
--- /dev/null
+++ b/src/sound/cocoa_s.c
@@ -0,0 +1,149 @@
+/* $Id$ */
+
+/*****************************************************************************
+ * Cocoa sound driver *
+ * Known things left to do: *
+ * - Might need to do endian checking for it to work on both ppc and x86 *
+ *****************************************************************************/
+
+#ifdef WITH_COCOA
+
+#include <AudioUnit/AudioUnit.h>
+
+/* Name conflict */
+#define Rect OTTDRect
+#define Point OTTDPoint
+#define WindowClass OTTDWindowClass
+/* Defined in stdbool.h */
+#ifndef __cplusplus
+# ifndef __BEOS__
+# undef bool
+# undef false
+# undef true
+# endif
+#endif
+
+#include "../stdafx.h"
+#include "../openttd.h"
+#include "../debug.h"
+#include "../driver.h"
+#include "../mixer.h"
+#include "../sdl.h"
+
+#include "cocoa_s.h"
+
+#undef WindowClass
+#undef Point
+#undef Rect
+
+
+static AudioUnit _outputAudioUnit;
+
+/* The CoreAudio callback */
+static OSStatus audioCallback(void *inRefCon, AudioUnitRenderActionFlags inActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, AudioBuffer *ioData)
+{
+ MxMixSamples(ioData->mData, ioData->mDataByteSize / 4);
+
+ return noErr;
+}
+
+
+static const char *CocoaSoundStart(const char * const *parm)
+{
+ Component comp;
+ ComponentDescription desc;
+ struct AudioUnitInputCallback callback;
+ AudioStreamBasicDescription requestedDesc;
+
+ /* Setup a AudioStreamBasicDescription with the requested format */
+ requestedDesc.mFormatID = kAudioFormatLinearPCM;
+ requestedDesc.mFormatFlags = kLinearPCMFormatFlagIsPacked;
+ requestedDesc.mChannelsPerFrame = 2;
+ requestedDesc.mSampleRate = GetDriverParamInt(parm, "hz", 11025);
+
+ requestedDesc.mBitsPerChannel = 16;
+ requestedDesc.mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
+
+#ifdef TTD_BIG_ENDIAN
+ requestedDesc.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
+#endif
+
+ requestedDesc.mFramesPerPacket = 1;
+ requestedDesc.mBytesPerFrame = requestedDesc.mBitsPerChannel * requestedDesc.mChannelsPerFrame / 8;
+ requestedDesc.mBytesPerPacket = requestedDesc.mBytesPerFrame * requestedDesc.mFramesPerPacket;
+
+
+ /* Locate the default output audio unit */
+ desc.componentType = kAudioUnitComponentType;
+ desc.componentSubType = kAudioUnitSubType_Output;
+ desc.componentManufacturer = kAudioUnitID_DefaultOutput;
+ desc.componentFlags = 0;
+ desc.componentFlagsMask = 0;
+
+ comp = FindNextComponent (NULL, &desc);
+ if (comp == NULL) {
+ return "cocoa_s: Failed to start CoreAudio: FindNextComponent returned NULL";
+ }
+
+ /* Open & initialize the default output audio unit */
+ if (OpenAComponent(comp, &_outputAudioUnit) != noErr) {
+ return "cocoa_s: Failed to start CoreAudio: OpenAComponent";
+ }
+
+ if (AudioUnitInitialize(_outputAudioUnit) != noErr) {
+ return "cocoa_s: Failed to start CoreAudio: AudioUnitInitialize";
+ }
+
+ /* Set the input format of the audio unit. */
+ if (AudioUnitSetProperty(_outputAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &requestedDesc, sizeof(requestedDesc)) != noErr) {
+ return "cocoa_s: Failed to start CoreAudio: AudioUnitSetProperty (kAudioUnitProperty_StreamFormat)";
+ }
+
+ /* Set the audio callback */
+ callback.inputProc = audioCallback;
+ callback.inputProcRefCon = NULL;
+ if (AudioUnitSetProperty(_outputAudioUnit, kAudioUnitProperty_SetInputCallback, kAudioUnitScope_Input, 0, &callback, sizeof(callback)) != noErr) {
+ return "cocoa_s: Failed to start CoreAudio: AudioUnitSetProperty (kAudioUnitProperty_SetInputCallback)";
+ }
+
+ /* Finally, start processing of the audio unit */
+ if (AudioOutputUnitStart(_outputAudioUnit) != noErr) {
+ return "cocoa_s: Failed to start CoreAudio: AudioOutputUnitStart";
+ }
+
+ /* We're running! */
+ return NULL;
+}
+
+
+static void CocoaSoundStop(void)
+{
+ struct AudioUnitInputCallback callback;
+
+ /* stop processing the audio unit */
+ if (AudioOutputUnitStop(_outputAudioUnit) != noErr) {
+ DEBUG(driver, 0, "cocoa_s: Core_CloseAudio: AudioOutputUnitStop failed");
+ return;
+ }
+
+ /* Remove the input callback */
+ callback.inputProc = 0;
+ callback.inputProcRefCon = 0;
+ if (AudioUnitSetProperty(_outputAudioUnit, kAudioUnitProperty_SetInputCallback, kAudioUnitScope_Input, 0, &callback, sizeof(callback)) != noErr) {
+ DEBUG(driver, 0, "cocoa_s: Core_CloseAudio: AudioUnitSetProperty (kAudioUnitProperty_SetInputCallback) failed");
+ return;
+ }
+
+ if (CloseComponent(_outputAudioUnit) != noErr) {
+ DEBUG(driver, 0, "cocoa_s: Core_CloseAudio: CloseComponent failed");
+ return;
+ }
+}
+
+
+const HalSoundDriver _cocoa_sound_driver = {
+ CocoaSoundStart,
+ CocoaSoundStop,
+};
+
+#endif /* WITH_COCOA */
diff --git a/src/sound/cocoa_s.h b/src/sound/cocoa_s.h
new file mode 100644
index 000000000..7db5f7023
--- /dev/null
+++ b/src/sound/cocoa_s.h
@@ -0,0 +1,10 @@
+/* $Id$ */
+
+#ifndef SOUND_COCOA_H
+#define SOUND_COCOA_H
+
+#include "../hal.h"
+
+extern const HalSoundDriver _cocoa_sound_driver;
+
+#endif
diff --git a/src/sound/null_s.c b/src/sound/null_s.c
new file mode 100644
index 000000000..f68c4b13a
--- /dev/null
+++ b/src/sound/null_s.c
@@ -0,0 +1,13 @@
+/* $Id$ */
+
+#include "../stdafx.h"
+#include "../openttd.h"
+#include "null_s.h"
+
+static const char *NullSoundStart(const char * const *parm) { return NULL; }
+static void NullSoundStop(void) {}
+
+const HalSoundDriver _null_sound_driver = {
+ NullSoundStart,
+ NullSoundStop,
+};
diff --git a/src/sound/null_s.h b/src/sound/null_s.h
new file mode 100644
index 000000000..6ccd19aed
--- /dev/null
+++ b/src/sound/null_s.h
@@ -0,0 +1,10 @@
+/* $Id$ */
+
+#ifndef SOUND_NULL_H
+#define SOUND_NULL_H
+
+#include "../hal.h"
+
+extern const HalSoundDriver _null_sound_driver;
+
+#endif
diff --git a/src/sound/sdl_s.c b/src/sound/sdl_s.c
new file mode 100644
index 000000000..4b1da52d6
--- /dev/null
+++ b/src/sound/sdl_s.c
@@ -0,0 +1,47 @@
+/* $Id$ */
+
+#include "../stdafx.h"
+
+#ifdef WITH_SDL
+
+#include "../openttd.h"
+#include "../driver.h"
+#include "../mixer.h"
+#include "../sdl.h"
+#include "sdl_s.h"
+#include <SDL.h>
+
+static void CDECL fill_sound_buffer(void *userdata, Uint8 *stream, int len)
+{
+ MxMixSamples(stream, len / 4);
+}
+
+static const char *SdlSoundStart(const char * const *parm)
+{
+ SDL_AudioSpec spec;
+
+ const char *s = SdlOpen(SDL_INIT_AUDIO);
+ if (s != NULL) return s;
+
+ spec.freq = GetDriverParamInt(parm, "hz", 11025);
+ spec.format = AUDIO_S16SYS;
+ spec.channels = 2;
+ spec.samples = 512;
+ spec.callback = fill_sound_buffer;
+ SDL_CALL SDL_OpenAudio(&spec, &spec);
+ SDL_CALL SDL_PauseAudio(0);
+ return NULL;
+}
+
+static void SdlSoundStop(void)
+{
+ SDL_CALL SDL_CloseAudio();
+ SdlClose(SDL_INIT_AUDIO);
+}
+
+const HalSoundDriver _sdl_sound_driver = {
+ SdlSoundStart,
+ SdlSoundStop,
+};
+
+#endif
diff --git a/src/sound/sdl_s.h b/src/sound/sdl_s.h
new file mode 100644
index 000000000..6fc2b6dc0
--- /dev/null
+++ b/src/sound/sdl_s.h
@@ -0,0 +1,10 @@
+/* $Id$ */
+
+#ifndef SOUND_SDL_H
+#define SOUND_SDL_H
+
+#include "../hal.h"
+
+extern const HalSoundDriver _sdl_sound_driver;
+
+#endif
diff --git a/src/sound/win32_s.c b/src/sound/win32_s.c
new file mode 100644
index 000000000..a39cee985
--- /dev/null
+++ b/src/sound/win32_s.c
@@ -0,0 +1,87 @@
+/* $Id$ */
+
+#include "../stdafx.h"
+#include "../openttd.h"
+#include "../driver.h"
+#include "../functions.h"
+#include "../mixer.h"
+#include "win32_s.h"
+#include <windows.h>
+#include <mmsystem.h>
+
+static HWAVEOUT _waveout;
+static WAVEHDR _wave_hdr[2];
+static int _bufsize;
+
+static void PrepareHeader(WAVEHDR *hdr)
+{
+ hdr->dwBufferLength = _bufsize * 4;
+ hdr->dwFlags = 0;
+ hdr->lpData = malloc(_bufsize * 4);
+ if (hdr->lpData == NULL ||
+ waveOutPrepareHeader(_waveout, hdr, sizeof(WAVEHDR)) != MMSYSERR_NOERROR)
+ error("waveOutPrepareHeader failed");
+}
+
+static void FillHeaders(void)
+{
+ WAVEHDR *hdr;
+
+ for (hdr = _wave_hdr; hdr != endof(_wave_hdr); hdr++) {
+ if (!(hdr->dwFlags & WHDR_INQUEUE)) {
+ MxMixSamples(hdr->lpData, hdr->dwBufferLength / 4);
+ if (waveOutWrite(_waveout, hdr, sizeof(WAVEHDR)) != MMSYSERR_NOERROR)
+ error("waveOutWrite failed");
+ }
+ }
+}
+
+static void CALLBACK waveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance,
+ DWORD dwParam1, DWORD dwParam2)
+{
+ switch (uMsg) {
+ case WOM_DONE:
+ if (_waveout) FillHeaders();
+ break;
+
+ default:
+ break;
+ }
+}
+
+static const char *Win32SoundStart(const char* const* parm)
+{
+ WAVEFORMATEX wfex;
+ int hz;
+
+ _bufsize = GetDriverParamInt(parm, "bufsize", 1024);
+ hz = GetDriverParamInt(parm, "hz", 11025);
+ wfex.wFormatTag = WAVE_FORMAT_PCM;
+ wfex.nChannels = 2;
+ wfex.nSamplesPerSec = hz;
+ wfex.nAvgBytesPerSec = hz * 2 * 2;
+ wfex.nBlockAlign = 4;
+ wfex.wBitsPerSample = 16;
+ if (waveOutOpen(&_waveout, WAVE_MAPPER, &wfex, (DWORD_PTR)&waveOutProc, 0, CALLBACK_FUNCTION) != MMSYSERR_NOERROR)
+ return "waveOutOpen failed";
+ PrepareHeader(&_wave_hdr[0]);
+ PrepareHeader(&_wave_hdr[1]);
+ FillHeaders();
+ return NULL;
+}
+
+static void Win32SoundStop(void)
+{
+ HWAVEOUT waveout = _waveout;
+
+ _waveout = NULL;
+ waveOutReset(waveout);
+ waveOutUnprepareHeader(waveout, &_wave_hdr[0], sizeof(WAVEHDR));
+ waveOutUnprepareHeader(waveout, &_wave_hdr[1], sizeof(WAVEHDR));
+ waveOutClose(waveout);
+}
+
+const HalSoundDriver _win32_sound_driver = {
+ Win32SoundStart,
+ Win32SoundStop,
+};
diff --git a/src/sound/win32_s.h b/src/sound/win32_s.h
new file mode 100644
index 000000000..65c6a957d
--- /dev/null
+++ b/src/sound/win32_s.h
@@ -0,0 +1,10 @@
+/* $Id$ */
+
+#ifndef SOUND_WIN32_H
+#define SOUND_WIN32_H
+
+#include "../hal.h"
+
+extern const HalSoundDriver _win32_sound_driver;
+
+#endif
diff --git a/src/sprite.h b/src/sprite.h
new file mode 100644
index 000000000..9dca01a66
--- /dev/null
+++ b/src/sprite.h
@@ -0,0 +1,45 @@
+/* $Id$ */
+
+#ifndef SPRITE_H
+#define SPRITE_H
+
+
+/* The following describes bunch of sprites to be drawn together in a single 3D
+ * bounding box. Used especially for various multi-sprite buildings (like
+ * depots or stations): */
+
+typedef struct DrawTileSeqStruct {
+ int8 delta_x; // 0x80 is sequence terminator
+ int8 delta_y;
+ int8 delta_z;
+ byte size_x;
+ byte size_y;
+ byte size_z;
+ uint32 image;
+} DrawTileSeqStruct;
+
+typedef struct DrawTileSprites {
+ SpriteID ground_sprite;
+ const DrawTileSeqStruct* seq;
+} DrawTileSprites;
+
+/**
+ * This structure is the same for both Industries and Houses.
+ * Buildings here reference a general type of construction
+ */
+typedef struct DrawBuildingsTileStruct {
+ SpriteID ground;
+ SpriteID building;
+ byte subtile_x:4;
+ byte subtile_y:4;
+ byte width:4;
+ byte height:4;
+ byte dz;
+ byte draw_proc; /* this allows to specify a special drawing procedure.*/
+} DrawBuildingsTileStruct;
+
+// Iterate through all DrawTileSeqStructs in DrawTileSprites.
+#define foreach_draw_tile_seq(idx, list) for (idx = list; ((byte) idx->delta_x) != 0x80; idx++)
+
+
+#endif /* SPRITE_H */
diff --git a/src/spritecache.c b/src/spritecache.c
new file mode 100644
index 000000000..e8c031fad
--- /dev/null
+++ b/src/spritecache.c
@@ -0,0 +1,461 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "debug.h"
+#include "functions.h"
+#include "macros.h"
+#include "spritecache.h"
+#include "table/sprites.h"
+#include "fileio.h"
+
+#define SPRITE_CACHE_SIZE 1024*1024
+
+#define WANT_NEW_LRU
+
+
+static void* _sprite_ptr[MAX_SPRITES];
+static uint32 _sprite_file_pos[MAX_SPRITES];
+
+#if defined(WANT_NEW_LRU)
+static int16 _sprite_lru_new[MAX_SPRITES];
+#else
+static uint16 _sprite_lru[MAX_SPRITES];
+static uint16 _sprite_lru_cur[MAX_SPRITES];
+#endif
+
+typedef struct MemBlock {
+ uint32 size;
+ byte data[VARARRAY_SIZE];
+} MemBlock;
+
+static uint _sprite_lru_counter;
+static MemBlock *_spritecache_ptr;
+static int _compact_cache_counter;
+
+static void CompactSpriteCache(void);
+
+static bool ReadSpriteHeaderSkipData(void)
+{
+ uint16 num = FioReadWord();
+ byte type;
+
+ if (num == 0) return false;
+
+ type = FioReadByte();
+ if (type == 0xFF) {
+ FioSkipBytes(num);
+ /* Some NewGRF files have "empty" pseudo-sprites which are 1
+ * byte long. Catch these so the sprites won't be displayed. */
+ return num != 1;
+ }
+
+ FioSkipBytes(7);
+ num -= 8;
+ if (num == 0) return true;
+
+ if (type & 2) {
+ FioSkipBytes(num);
+ } else {
+ while (num > 0) {
+ int8 i = FioReadByte();
+ if (i >= 0) {
+ num -= i;
+ FioSkipBytes(i);
+ } else {
+ i = -(i >> 3);
+ num -= i;
+ FioReadByte();
+ }
+ }
+ }
+
+ return true;
+}
+
+/* Check if the given Sprite ID exists */
+bool SpriteExists(SpriteID id)
+{
+ /* Special case for Sprite ID zero -- its position is also 0... */
+ return _sprite_file_pos[id] != 0 || id == 0;
+}
+
+static void* AllocSprite(size_t);
+
+static void* ReadSprite(SpriteID id)
+{
+ uint num;
+ byte type;
+
+ DEBUG(sprite, 9, "Load sprite %d", id);
+
+ if (!SpriteExists(id)) {
+ error(
+ "Tried to load non-existing sprite #%d.\n"
+ "Probable cause: Wrong/missing NewGRFs",
+ id
+ );
+ }
+
+ FioSeekToFile(_sprite_file_pos[id]);
+
+ num = FioReadWord();
+ type = FioReadByte();
+ if (type == 0xFF) {
+ byte* dest = AllocSprite(num);
+
+ _sprite_ptr[id] = dest;
+ FioReadBlock(dest, num);
+
+ return dest;
+ } else {
+ uint height = FioReadByte();
+ uint width = FioReadWord();
+ Sprite* sprite;
+ byte* dest;
+
+ num = (type & 0x02) ? width * height : num - 8;
+ sprite = AllocSprite(sizeof(*sprite) + num);
+ _sprite_ptr[id] = sprite;
+ sprite->info = type;
+ sprite->height = (id != 142) ? height : 10; // Compensate for a TTD bug
+ sprite->width = width;
+ sprite->x_offs = FioReadWord();
+ sprite->y_offs = FioReadWord();
+
+ dest = sprite->data;
+ while (num > 0) {
+ int8 i = FioReadByte();
+
+ if (i >= 0) {
+ num -= i;
+ for (; i > 0; --i) *dest++ = FioReadByte();
+ } else {
+ const byte* rel = dest - (((i & 7) << 8) | FioReadByte());
+
+ i = -(i >> 3);
+ num -= i;
+
+ for (; i > 0; --i) *dest++ = *rel++;
+ }
+ }
+
+ return sprite;
+ }
+}
+
+
+bool LoadNextSprite(int load_index, byte file_index)
+{
+ uint32 file_pos = FioGetPos() | (file_index << 24);
+
+ if (!ReadSpriteHeaderSkipData()) return false;
+
+ if (load_index >= MAX_SPRITES) {
+ error("Tried to load too many sprites (#%d; max %d)", load_index, MAX_SPRITES);
+ }
+
+ _sprite_file_pos[load_index] = file_pos;
+
+ _sprite_ptr[load_index] = NULL;
+
+#if defined(WANT_NEW_LRU)
+ _sprite_lru_new[load_index] = 0;
+#else
+ _sprite_lru[load_index] = 0xFFFF;
+ _sprite_lru_cur[load_index] = 0;
+#endif
+
+ return true;
+}
+
+
+void DupSprite(SpriteID old, SpriteID new)
+{
+ _sprite_file_pos[new] = _sprite_file_pos[old];
+ _sprite_ptr[new] = NULL;
+}
+
+
+void SkipSprites(uint count)
+{
+ for (; count > 0; --count) {
+ if (!ReadSpriteHeaderSkipData()) return;
+ }
+}
+
+
+#define S_FREE_MASK 1
+
+static inline MemBlock* NextBlock(MemBlock* block)
+{
+ return (MemBlock*)((byte*)block + (block->size & ~S_FREE_MASK));
+}
+
+static uint32 GetSpriteCacheUsage(void)
+{
+ uint32 tot_size = 0;
+ MemBlock* s;
+
+ for (s = _spritecache_ptr; s->size != 0; s = NextBlock(s))
+ if (!(s->size & S_FREE_MASK)) tot_size += s->size;
+
+ return tot_size;
+}
+
+
+void IncreaseSpriteLRU(void)
+{
+ int i;
+
+ // Increase all LRU values
+#if defined(WANT_NEW_LRU)
+ if (_sprite_lru_counter > 16384) {
+ DEBUG(sprite, 3, "Fixing lru %d, inuse=%d", _sprite_lru_counter, GetSpriteCacheUsage());
+
+ for (i = 0; i != MAX_SPRITES; i++)
+ if (_sprite_ptr[i] != NULL) {
+ if (_sprite_lru_new[i] >= 0) {
+ _sprite_lru_new[i] = -1;
+ } else if (_sprite_lru_new[i] != -32768) {
+ _sprite_lru_new[i]--;
+ }
+ }
+ _sprite_lru_counter = 0;
+ }
+#else
+ for (i = 0; i != MAX_SPRITES; i++)
+ if (_sprite_ptr[i] != NULL && _sprite_lru[i] != 65535)
+ _sprite_lru[i]++;
+ // Reset the lru counter.
+ _sprite_lru_counter = 0;
+#endif
+
+ // Compact sprite cache every now and then.
+ if (++_compact_cache_counter >= 740) {
+ CompactSpriteCache();
+ _compact_cache_counter = 0;
+ }
+}
+
+// Called when holes in the sprite cache should be removed.
+// That is accomplished by moving the cached data.
+static void CompactSpriteCache(void)
+{
+ MemBlock *s;
+
+ DEBUG(sprite, 3, "Compacting sprite cache, inuse=%d", GetSpriteCacheUsage());
+
+ for (s = _spritecache_ptr; s->size != 0;) {
+ if (s->size & S_FREE_MASK) {
+ MemBlock* next = NextBlock(s);
+ MemBlock temp;
+ void** i;
+
+ // Since free blocks are automatically coalesced, this should hold true.
+ assert(!(next->size & S_FREE_MASK));
+
+ // If the next block is the sentinel block, we can safely return
+ if (next->size == 0)
+ break;
+
+ // Locate the sprite belonging to the next pointer.
+ for (i = _sprite_ptr; *i != next->data; ++i) {
+ assert(i != endof(_sprite_ptr));
+ }
+
+ *i = s->data; // Adjust sprite array entry
+ // Swap this and the next block
+ temp = *s;
+ memmove(s, next, next->size);
+ s = NextBlock(s);
+ *s = temp;
+
+ // Coalesce free blocks
+ while (NextBlock(s)->size & S_FREE_MASK) {
+ s->size += NextBlock(s)->size & ~S_FREE_MASK;
+ }
+ } else {
+ s = NextBlock(s);
+ }
+ }
+}
+
+static void DeleteEntryFromSpriteCache(void)
+{
+ int i;
+ int best = -1;
+ MemBlock* s;
+ int cur_lru;
+
+ DEBUG(sprite, 3, "DeleteEntryFromSpriteCache, inuse=%d", GetSpriteCacheUsage());
+
+#if defined(WANT_NEW_LRU)
+ cur_lru = 0xffff;
+ for (i = 0; i != MAX_SPRITES; i++) {
+ if (_sprite_ptr[i] != NULL && _sprite_lru_new[i] < cur_lru) {
+ cur_lru = _sprite_lru_new[i];
+ best = i;
+ }
+ }
+#else
+ {
+ uint16 cur_lru = 0, cur_lru_cur = 0xffff;
+ for (i = 0; i != MAX_SPRITES; i++) {
+ if (_sprite_ptr[i] == NULL || _sprite_lru[i] < cur_lru) continue;
+
+ // Found a sprite with a higher LRU value, then remember it.
+ if (_sprite_lru[i] != cur_lru) {
+ cur_lru = _sprite_lru[i];
+ best = i;
+
+ // Else if both sprites were very recently referenced, compare by the cur value instead.
+ } else if (cur_lru == 0 && _sprite_lru_cur[i] <= cur_lru_cur) {
+ cur_lru_cur = _sprite_lru_cur[i];
+ cur_lru = _sprite_lru[i];
+ best = i;
+ }
+ }
+ }
+#endif
+
+ // Display an error message and die, in case we found no sprite at all.
+ // This shouldn't really happen, unless all sprites are locked.
+ if (best == -1)
+ error("Out of sprite memory");
+
+ // Mark the block as free (the block must be in use)
+ s = (MemBlock*)_sprite_ptr[best] - 1;
+ assert(!(s->size & S_FREE_MASK));
+ s->size |= S_FREE_MASK;
+ _sprite_ptr[best] = NULL;
+
+ // And coalesce adjacent free blocks
+ for (s = _spritecache_ptr; s->size != 0; s = NextBlock(s)) {
+ if (s->size & S_FREE_MASK) {
+ while (NextBlock(s)->size & S_FREE_MASK) {
+ s->size += NextBlock(s)->size & ~S_FREE_MASK;
+ }
+ }
+ }
+}
+
+static void* AllocSprite(size_t mem_req)
+{
+ mem_req += sizeof(MemBlock);
+
+ /* Align this to an uint32 boundary. This also makes sure that the 2 least
+ * bits are not used, so we could use those for other things. */
+ mem_req = ALIGN(mem_req, sizeof(uint32));
+
+ for (;;) {
+ MemBlock* s;
+
+ for (s = _spritecache_ptr; s->size != 0; s = NextBlock(s)) {
+ if (s->size & S_FREE_MASK) {
+ size_t cur_size = s->size & ~S_FREE_MASK;
+
+ /* Is the block exactly the size we need or
+ * big enough for an additional free block? */
+ if (cur_size == mem_req ||
+ cur_size >= mem_req + sizeof(MemBlock)) {
+ // Set size and in use
+ s->size = mem_req;
+
+ // Do we need to inject a free block too?
+ if (cur_size != mem_req) {
+ NextBlock(s)->size = (cur_size - mem_req) | S_FREE_MASK;
+ }
+
+ return s->data;
+ }
+ }
+ }
+
+ // Reached sentinel, but no block found yet. Delete some old entry.
+ DeleteEntryFromSpriteCache();
+ }
+}
+
+#if defined(NEW_ROTATION)
+#define X15(x) else if (s >= x && s < (x+15)) { s = _rotate_tile_sprite[s - x] + x; }
+#define X19(x) else if (s >= x && s < (x+19)) { s = _rotate_tile_sprite[s - x] + x; }
+#define MAP(from,to,map) else if (s >= from && s <= to) { s = map[s - from] + from; }
+
+
+static uint RotateSprite(uint s)
+{
+ static const byte _rotate_tile_sprite[19] = { 0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 17, 18, 16, 15 };
+ static const byte _coast_map[9] = {0, 4, 3, 1, 2, 6, 8, 5, 7};
+ static const byte _fence_map[6] = {1, 0, 5, 4, 3, 2};
+
+ if (0);
+ X19(752)
+ X15(990-1)
+ X19(3924)
+ X19(3943)
+ X19(3962)
+ X19(3981)
+ X19(4000)
+ X19(4023)
+ X19(4042)
+ MAP(4061, 4069, _coast_map)
+ X19(4126)
+ X19(4145)
+ X19(4164)
+ X19(4183)
+ X19(4202)
+ X19(4221)
+ X19(4240)
+ X19(4259)
+ X19(4259)
+ X19(4278)
+ MAP(4090, 4095, _fence_map)
+ MAP(4096, 4101, _fence_map)
+ MAP(4102, 4107, _fence_map)
+ MAP(4108, 4113, _fence_map)
+ MAP(4114, 4119, _fence_map)
+ MAP(4120, 4125, _fence_map)
+ return s;
+}
+#endif
+
+const void *GetRawSprite(SpriteID sprite)
+{
+ void* p;
+
+ assert(sprite < MAX_SPRITES);
+
+#if defined(NEW_ROTATION)
+ sprite = RotateSprite(sprite);
+#endif
+
+ // Update LRU
+#if defined(WANT_NEW_LRU)
+ _sprite_lru_new[sprite] = ++_sprite_lru_counter;
+#else
+ _sprite_lru_cur[sprite] = ++_sprite_lru_counter;
+ _sprite_lru[sprite] = 0;
+#endif
+
+ p = _sprite_ptr[sprite];
+ // Load the sprite, if it is not loaded, yet
+ if (p == NULL) p = ReadSprite(sprite);
+ return p;
+}
+
+
+void GfxInitSpriteMem(void)
+{
+ // initialize sprite cache heap
+ if (_spritecache_ptr == NULL) _spritecache_ptr = malloc(SPRITE_CACHE_SIZE);
+
+ // A big free block
+ _spritecache_ptr->size = (SPRITE_CACHE_SIZE - sizeof(MemBlock)) | S_FREE_MASK;
+ // Sentinel block (identified by size == 0)
+ NextBlock(_spritecache_ptr)->size = 0;
+
+ memset(_sprite_ptr, 0, sizeof(_sprite_ptr));
+
+ _compact_cache_counter = 0;
+}
diff --git a/src/spritecache.h b/src/spritecache.h
new file mode 100644
index 000000000..3a5676a63
--- /dev/null
+++ b/src/spritecache.h
@@ -0,0 +1,35 @@
+/* $Id$ */
+
+#ifndef SPRITECACHE_H
+#define SPRITECACHE_H
+
+typedef struct Sprite {
+ byte info;
+ byte height;
+ uint16 width;
+ int16 x_offs;
+ int16 y_offs;
+ byte data[VARARRAY_SIZE];
+} Sprite;
+
+const void *GetRawSprite(SpriteID sprite);
+bool SpriteExists(SpriteID sprite);
+
+static inline const Sprite *GetSprite(SpriteID sprite)
+{
+ return GetRawSprite(sprite);
+}
+
+static inline const byte *GetNonSprite(SpriteID sprite)
+{
+ return GetRawSprite(sprite);
+}
+
+void GfxInitSpriteMem(void);
+void IncreaseSpriteLRU(void);
+
+bool LoadNextSprite(int load_index, byte file_index);
+void DupSprite(SpriteID old, SpriteID new);
+void SkipSprites(uint count);
+
+#endif /* SPRITECACHE_H */
diff --git a/src/station.h b/src/station.h
new file mode 100644
index 000000000..aaa168384
--- /dev/null
+++ b/src/station.h
@@ -0,0 +1,237 @@
+/* $Id$ */
+
+#ifndef STATION_H
+#define STATION_H
+
+#include "player.h"
+#include "oldpool.h"
+#include "sprite.h"
+#include "tile.h"
+#include "newgrf_station.h"
+
+typedef struct GoodsEntry {
+ uint16 waiting_acceptance;
+ byte days_since_pickup;
+ byte rating;
+ StationID enroute_from;
+ byte enroute_time;
+ byte last_speed;
+ byte last_age;
+ int32 feeder_profit;
+} GoodsEntry;
+
+typedef enum RoadStopType {
+ RS_BUS,
+ RS_TRUCK
+} RoadStopType;
+
+enum {
+ INVALID_STATION = 0xFFFF,
+ ROAD_STOP_LIMIT = 16,
+};
+
+typedef struct RoadStop {
+ TileIndex xy;
+ bool used;
+ byte status;
+ RoadStopID index;
+ byte num_vehicles;
+ StationID station;
+ struct RoadStop *next;
+ struct RoadStop *prev;
+} RoadStop;
+
+typedef struct StationSpecList {
+ const StationSpec *spec;
+ uint32 grfid; /// GRF ID of this custom station
+ uint8 localidx; /// Station ID within GRF of station
+} StationSpecList;
+
+struct Station {
+ TileIndex xy;
+ RoadStop *bus_stops;
+ RoadStop *truck_stops;
+ TileIndex train_tile;
+ TileIndex airport_tile;
+ TileIndex dock_tile;
+ Town *town;
+ uint16 string_id;
+
+ ViewportSign sign;
+
+ uint16 had_vehicle_of_type;
+
+ byte time_since_load;
+ byte time_since_unload;
+ byte delete_ctr;
+ PlayerID owner;
+ byte facilities;
+ byte airport_type;
+
+ // trainstation width/height
+ byte trainst_w, trainst_h;
+
+ /** List of custom stations (StationSpecs) allocated to the station */
+ uint8 num_specs;
+ StationSpecList *speclist;
+
+ Date build_date;
+
+ //uint16 airport_flags;
+ uint32 airport_flags;
+ StationID index;
+
+ byte last_vehicle_type;
+ GoodsEntry goods[NUM_CARGO];
+
+ uint16 random_bits;
+ byte waiting_triggers;
+
+ /* Stuff that is no longer used, but needed for conversion */
+ TileIndex bus_tile_obsolete;
+ TileIndex lorry_tile_obsolete;
+
+ byte truck_stop_status_obsolete;
+ byte bus_stop_status_obsolete;
+ byte blocked_months_obsolete;
+
+ Rect rect; ///< Station spread out rectangle (not saved) maintained by StationRect_xxx() functions
+};
+
+enum {
+ FACIL_TRAIN = 0x01,
+ FACIL_TRUCK_STOP = 0x02,
+ FACIL_BUS_STOP = 0x04,
+ FACIL_AIRPORT = 0x08,
+ FACIL_DOCK = 0x10,
+};
+
+enum {
+// HVOT_PENDING_DELETE = 1 << 0, // not needed anymore
+ HVOT_TRAIN = 1 << 1,
+ HVOT_BUS = 1 << 2,
+ HVOT_TRUCK = 1 << 3,
+ HVOT_AIRCRAFT = 1 << 4,
+ HVOT_SHIP = 1 << 5,
+ /* This bit is used to mark stations. No, it does not belong here, but what
+ * can we do? ;-) */
+ HVOT_BUOY = 1 << 6
+};
+
+enum {
+ CA_BUS = 3,
+ CA_TRUCK = 3,
+ CA_AIR_OILPAD = 3,
+ CA_TRAIN = 4,
+ CA_AIR_HELIPORT = 4,
+ CA_AIR_SMALL = 4,
+ CA_AIR_LARGE = 5,
+ CA_DOCK = 5,
+ CA_AIR_METRO = 6,
+ CA_AIR_INTER = 8,
+ CA_AIR_COMMUTER = 4,
+ CA_AIR_HELIDEPOT = 4,
+ CA_AIR_INTERCON = 10,
+ CA_AIR_HELISTATION = 4,
+};
+
+void ModifyStationRatingAround(TileIndex tile, PlayerID owner, int amount, uint radius);
+
+void ShowStationViewWindow(StationID station);
+void UpdateAllStationVirtCoord(void);
+
+/* sorter stuff */
+void RebuildStationLists(void);
+void ResortStationLists(void);
+
+DECLARE_OLD_POOL(Station, Station, 6, 1000)
+
+static inline StationID GetMaxStationIndex(void)
+{
+ /* TODO - This isn't the real content of the function, but
+ * with the new pool-system this will be replaced with one that
+ * _really_ returns the highest index. Now it just returns
+ * the next safe value we are sure about everything is below.
+ */
+ return GetStationPoolSize() - 1;
+}
+
+static inline uint GetNumStations(void)
+{
+ return GetStationPoolSize();
+}
+
+/**
+ * Check if a station really exists.
+ */
+static inline bool IsValidStation(const Station *st)
+{
+ return st->xy != 0;
+}
+
+static inline bool IsValidStationID(StationID index)
+{
+ return index < GetStationPoolSize() && IsValidStation(GetStation(index));
+}
+
+void DestroyStation(Station *st);
+
+static inline void DeleteStation(Station *st)
+{
+ DestroyStation(st);
+ st->xy = 0;
+}
+
+#define FOR_ALL_STATIONS_FROM(st, start) for (st = GetStation(start); st != NULL; st = (st->index + 1U < GetStationPoolSize()) ? GetStation(st->index + 1U) : NULL) if (IsValidStation(st))
+#define FOR_ALL_STATIONS(st) FOR_ALL_STATIONS_FROM(st, 0)
+
+
+/* Stuff for ROADSTOPS */
+
+DECLARE_OLD_POOL(RoadStop, RoadStop, 5, 2000)
+
+/**
+ * Check if a RaodStop really exists.
+ */
+static inline bool IsValidRoadStop(const RoadStop *rs)
+{
+ return rs->used;
+}
+
+void DestroyRoadStop(RoadStop* rs);
+
+static inline void DeleteRoadStop(RoadStop *rs)
+{
+ DestroyRoadStop(rs);
+ rs->used = false;
+}
+
+#define FOR_ALL_ROADSTOPS_FROM(rs, start) for (rs = GetRoadStop(start); rs != NULL; rs = (rs->index + 1U < GetRoadStopPoolSize()) ? GetRoadStop(rs->index + 1U) : NULL) if (IsValidRoadStop(rs))
+#define FOR_ALL_ROADSTOPS(rs) FOR_ALL_ROADSTOPS_FROM(rs, 0)
+
+/* End of stuff for ROADSTOPS */
+
+
+void AfterLoadStations(void);
+void GetProductionAroundTiles(AcceptedCargo produced, TileIndex tile, int w, int h, int rad);
+void GetAcceptanceAroundTiles(AcceptedCargo accepts, TileIndex tile, int w, int h, int rad);
+uint GetStationPlatforms(const Station *st, TileIndex tile);
+uint GetPlatformLength(TileIndex tile, DiagDirection dir);
+void MarkStationTilesDirty(const Station *st);
+
+
+const DrawTileSprites *GetStationTileLayout(byte gfx);
+void StationPickerDrawSprite(int x, int y, RailType railtype, int image);
+
+RoadStop * GetRoadStopByTile(TileIndex tile, RoadStopType type);
+RoadStop * GetPrimaryRoadStop(const Station *st, RoadStopType type);
+uint GetNumRoadStops(const Station* st, RoadStopType type);
+RoadStop * AllocateRoadStop( void );
+void ClearSlot(Vehicle *v);
+
+static inline bool IsBuoy(const Station* st)
+{
+ return (st->had_vehicle_of_type & HVOT_BUOY) != 0; /* XXX: We should really ditch this ugly coding and switch to something sane... */
+}
+
+#endif /* STATION_H */
diff --git a/src/station_cmd.c b/src/station_cmd.c
new file mode 100644
index 000000000..73d6d1bac
--- /dev/null
+++ b/src/station_cmd.c
@@ -0,0 +1,3280 @@
+/* $Id$ */
+
+/** @file station_cmd.c */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "bridge_map.h"
+#include "debug.h"
+#include "functions.h"
+#include "station_map.h"
+#include "table/sprites.h"
+#include "table/strings.h"
+#include "map.h"
+#include "tile.h"
+#include "station.h"
+#include "gfx.h"
+#include "window.h"
+#include "viewport.h"
+#include "command.h"
+#include "town.h"
+#include "vehicle.h"
+#include "news.h"
+#include "saveload.h"
+#include "economy.h"
+#include "player.h"
+#include "airport.h"
+#include "sprite.h"
+#include "depot.h"
+#include "train.h"
+#include "water_map.h"
+#include "industry_map.h"
+#include "newgrf_callbacks.h"
+#include "newgrf_station.h"
+#include "yapf/yapf.h"
+#include "date.h"
+
+typedef enum StationRectModes
+{
+ RECT_MODE_TEST = 0,
+ RECT_MODE_TRY,
+ RECT_MODE_FORCE
+} StationRectMode;
+
+static void StationRect_Init(Station *st);
+static bool StationRect_IsEmpty(Station *st);
+static bool StationRect_BeforeAddTile(Station *st, TileIndex tile, StationRectMode mode);
+static bool StationRect_BeforeAddRect(Station *st, TileIndex tile, int w, int h, StationRectMode mode);
+static bool StationRect_AfterRemoveTile(Station *st, TileIndex tile);
+static bool StationRect_AfterRemoveRect(Station *st, TileIndex tile, int w, int h);
+
+
+/**
+ * Called if a new block is added to the station-pool
+ */
+static void StationPoolNewBlock(uint start_item)
+{
+ Station *st;
+
+ /* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
+ * TODO - This is just a temporary stage, this will be removed. */
+ for (st = GetStation(start_item); st != NULL; st = (st->index + 1U < GetStationPoolSize()) ? GetStation(st->index + 1U) : NULL) st->index = start_item++;
+}
+
+static void StationPoolCleanBlock(uint start_item, uint end_item)
+{
+ uint i;
+
+ for (i = start_item; i <= end_item; i++) {
+ Station *st = GetStation(i);
+ free(st->speclist);
+ st->speclist = NULL;
+ }
+}
+
+/**
+ * Called if a new block is added to the roadstop-pool
+ */
+static void RoadStopPoolNewBlock(uint start_item)
+{
+ RoadStop *rs;
+
+ /* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
+ * TODO - This is just a temporary stage, this will be removed. */
+ for (rs = GetRoadStop(start_item); rs != NULL; rs = (rs->index + 1U < GetRoadStopPoolSize()) ? GetRoadStop(rs->index + 1U) : NULL) rs->index = start_item++;
+}
+
+DEFINE_OLD_POOL(Station, Station, StationPoolNewBlock, StationPoolCleanBlock)
+DEFINE_OLD_POOL(RoadStop, RoadStop, RoadStopPoolNewBlock, NULL)
+
+
+extern void UpdateAirplanesOnNewStation(Station *st);
+
+static bool TileBelongsToRailStation(const Station *st, TileIndex tile)
+{
+ return IsTileType(tile, MP_STATION) && GetStationIndex(tile) == st->index && IsRailwayStation(tile);
+}
+
+void MarkStationTilesDirty(const Station *st)
+{
+ TileIndex tile = st->train_tile;
+ int w, h;
+
+ // XXX No station is recorded as 0, not INVALID_TILE...
+ if (tile == 0) return;
+
+ for (h = 0; h < st->trainst_h; h++) {
+ for (w = 0; w < st->trainst_w; w++) {
+ if (TileBelongsToRailStation(st, tile)) {
+ MarkTileDirtyByTile(tile);
+ }
+ tile += TileDiffXY(1, 0);
+ }
+ tile += TileDiffXY(-w, 1);
+ }
+}
+
+static void MarkStationDirty(const Station* st)
+{
+ if (st->sign.width_1 != 0) {
+ InvalidateWindowWidget(WC_STATION_VIEW, st->index, 1);
+
+ MarkAllViewportsDirty(
+ st->sign.left - 6,
+ st->sign.top,
+ st->sign.left + (st->sign.width_1 << 2) + 12,
+ st->sign.top + 48);
+ }
+}
+
+static void InitializeRoadStop(RoadStop *road_stop, RoadStop *previous, TileIndex tile, StationID index)
+{
+ road_stop->xy = tile;
+ road_stop->used = true;
+ road_stop->status = 3; //stop is free
+ road_stop->next = NULL;
+ road_stop->prev = previous;
+ road_stop->station = index;
+ road_stop->num_vehicles = 0;
+}
+
+RoadStop* GetPrimaryRoadStop(const Station* st, RoadStopType type)
+{
+ switch (type) {
+ case RS_BUS: return st->bus_stops;
+ case RS_TRUCK: return st->truck_stops;
+ default: NOT_REACHED();
+ }
+
+ return NULL;
+}
+
+RoadStop* GetRoadStopByTile(TileIndex tile, RoadStopType type)
+{
+ const Station* st = GetStationByTile(tile);
+ RoadStop* rs;
+
+ for (rs = GetPrimaryRoadStop(st, type); rs->xy != tile; rs = rs->next) {
+ assert(rs->next != NULL);
+ }
+
+ return rs;
+}
+
+uint GetNumRoadStopsInStation(const Station* st, RoadStopType type)
+{
+ uint num = 0;
+ const RoadStop *rs;
+
+ assert(st != NULL);
+ for (rs = GetPrimaryRoadStop(st, type); rs != NULL; rs = rs->next) num++;
+
+ return num;
+}
+
+RoadStop *AllocateRoadStop(void)
+{
+ RoadStop *rs;
+
+ /* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
+ * TODO - This is just a temporary stage, this will be removed. */
+ for (rs = GetRoadStop(0); rs != NULL; rs = (rs->index + 1U < GetRoadStopPoolSize()) ? GetRoadStop(rs->index + 1U) : NULL) {
+ if (!IsValidRoadStop(rs)) {
+ RoadStopID index = rs->index;
+
+ memset(rs, 0, sizeof(*rs));
+ rs->index = index;
+
+ return rs;
+ }
+ }
+
+ /* Check if we can add a block to the pool */
+ if (AddBlockToPool(&_RoadStop_pool)) return AllocateRoadStop();
+
+ return NULL;
+}
+
+/* Calculate the radius of the station. Basicly it is the biggest
+ * radius that is available within the station */
+static uint FindCatchmentRadius(const Station* st)
+{
+ uint ret = 0;
+
+ if (st->bus_stops != NULL) ret = max(ret, CA_BUS);
+ if (st->truck_stops != NULL) ret = max(ret, CA_TRUCK);
+ if (st->train_tile) ret = max(ret, CA_TRAIN);
+ if (st->dock_tile) ret = max(ret, CA_DOCK);
+
+ if (st->airport_tile) {
+ switch (st->airport_type) {
+ case AT_OILRIG: ret = max(ret, CA_AIR_OILPAD); break;
+ case AT_SMALL: ret = max(ret, CA_AIR_SMALL); break;
+ case AT_HELIPORT: ret = max(ret, CA_AIR_HELIPORT); break;
+ case AT_LARGE: ret = max(ret, CA_AIR_LARGE); break;
+ case AT_METROPOLITAN: ret = max(ret, CA_AIR_METRO); break;
+ case AT_INTERNATIONAL: ret = max(ret, CA_AIR_INTER); break;
+ case AT_COMMUTER: ret = max(ret, CA_AIR_COMMUTER); break;
+ case AT_HELIDEPOT: ret = max(ret, CA_AIR_HELIDEPOT); break;
+ case AT_INTERCON: ret = max(ret, CA_AIR_INTERCON); break;
+ case AT_HELISTATION: ret = max(ret, CA_AIR_HELISTATION); break;
+ }
+ }
+
+ return ret;
+}
+
+#define CHECK_STATIONS_ERR ((Station*)-1)
+
+static Station* GetStationAround(TileIndex tile, int w, int h, StationID closest_station)
+{
+ // check around to see if there's any stations there
+ BEGIN_TILE_LOOP(tile_cur, w + 2, h + 2, tile - TileDiffXY(1, 1))
+ if (IsTileType(tile_cur, MP_STATION)) {
+ StationID t = GetStationIndex(tile_cur);
+ {
+ Station *st = GetStation(t);
+ // you cannot take control of an oilrig!!
+ if (st->airport_type == AT_OILRIG && st->facilities == (FACIL_AIRPORT|FACIL_DOCK))
+ continue;
+ }
+
+ if (closest_station == INVALID_STATION) {
+ closest_station = t;
+ } else if (closest_station != t) {
+ _error_message = STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING;
+ return CHECK_STATIONS_ERR;
+ }
+ }
+ END_TILE_LOOP(tile_cur, w + 2, h + 2, tile - TileDiffXY(1, 1))
+ return (closest_station == INVALID_STATION) ? NULL : GetStation(closest_station);
+}
+
+static Station *AllocateStation(void)
+{
+ Station *st = NULL;
+
+ /* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
+ * TODO - This is just a temporary stage, this will be removed. */
+ for (st = GetStation(0); st != NULL; st = (st->index + 1U < GetStationPoolSize()) ? GetStation(st->index + 1U) : NULL) {
+ if (!IsValidStation(st)) {
+ StationID index = st->index;
+
+ memset(st, 0, sizeof(Station));
+ st->index = index;
+
+ return st;
+ }
+ }
+
+ /* Check if we can add a block to the pool */
+ if (AddBlockToPool(&_Station_pool)) return AllocateStation();
+
+ _error_message = STR_3008_TOO_MANY_STATIONS_LOADING;
+ return NULL;
+}
+
+
+/**
+ * Counts the numbers of tiles matching a specific type in the area around
+ * @param tile the center tile of the 'count area'
+ * @param type the type of tile searched for
+ * @param industry when type == MP_INDUSTRY, the type of the industry,
+ * in all other cases this parameter is ignored
+ * @result the noumber of matching tiles around
+ */
+static int CountMapSquareAround(TileIndex tile, TileType type, IndustryType industry)
+{
+ TileIndex cur_tile;
+ int dx, dy;
+ int num = 0;
+
+ for (dx = -3; dx <= 3; dx++) {
+ for (dy = -3; dy <= 3; dy++) {
+ cur_tile = TILE_MASK(tile + TileDiffXY(dx, dy));
+
+ if (IsTileType(cur_tile, type)) {
+ switch (type) {
+ case MP_INDUSTRY:
+ if (GetIndustryType(cur_tile) == industry)
+ num++;
+ break;
+
+ case MP_WATER:
+ if (!IsWater(cur_tile))
+ break;
+ /* FALL THROUGH WHEN WATER TILE */
+ case MP_TREES:
+ num++;
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ return num;
+}
+
+#define M(x) ((x) - STR_SV_STNAME)
+
+static bool GenerateStationName(Station *st, TileIndex tile, int flag)
+{
+ static const uint32 _gen_station_name_bits[] = {
+ 0, /* 0 */
+ 1 << M(STR_SV_STNAME_AIRPORT), /* 1 */
+ 1 << M(STR_SV_STNAME_OILFIELD), /* 2 */
+ 1 << M(STR_SV_STNAME_DOCKS), /* 3 */
+ 0x1FF << M(STR_SV_STNAME_BUOY_1), /* 4 */
+ 1 << M(STR_SV_STNAME_HELIPORT), /* 5 */
+ };
+
+ Town *t = st->town;
+ uint32 free_names = (uint32)-1;
+ int found;
+ uint z,z2;
+ unsigned long tmp;
+
+ {
+ Station *s;
+
+ FOR_ALL_STATIONS(s) {
+ if (s != st && s->town==t) {
+ uint str = M(s->string_id);
+ if (str <= 0x20) {
+ if (str == M(STR_SV_STNAME_FOREST))
+ str = M(STR_SV_STNAME_WOODS);
+ CLRBIT(free_names, str);
+ }
+ }
+ }
+ }
+
+ /* check default names */
+ tmp = free_names & _gen_station_name_bits[flag];
+ if (tmp != 0) {
+ found = FindFirstBit(tmp);
+ goto done;
+ }
+
+ /* check mine? */
+ if (HASBIT(free_names, M(STR_SV_STNAME_MINES))) {
+ if (CountMapSquareAround(tile, MP_INDUSTRY, IT_COAL_MINE) >= 2 ||
+ CountMapSquareAround(tile, MP_INDUSTRY, IT_IRON_MINE) >= 2 ||
+ CountMapSquareAround(tile, MP_INDUSTRY, IT_COPPER_MINE) >= 2 ||
+ CountMapSquareAround(tile, MP_INDUSTRY, IT_GOLD_MINE) >= 2 ||
+ CountMapSquareAround(tile, MP_INDUSTRY, IT_DIAMOND_MINE) >= 2) {
+ found = M(STR_SV_STNAME_MINES);
+ goto done;
+ }
+ }
+
+ /* check close enough to town to get central as name? */
+ if (DistanceMax(tile,t->xy) < 8) {
+ found = M(STR_SV_STNAME);
+ if (HASBIT(free_names, M(STR_SV_STNAME))) goto done;
+
+ found = M(STR_SV_STNAME_CENTRAL);
+ if (HASBIT(free_names, M(STR_SV_STNAME_CENTRAL))) goto done;
+ }
+
+ /* Check lakeside */
+ if (HASBIT(free_names, M(STR_SV_STNAME_LAKESIDE)) &&
+ DistanceFromEdge(tile) < 20 &&
+ CountMapSquareAround(tile, MP_WATER, 0) >= 5) {
+ found = M(STR_SV_STNAME_LAKESIDE);
+ goto done;
+ }
+
+ /* Check woods */
+ if (HASBIT(free_names, M(STR_SV_STNAME_WOODS)) && (
+ CountMapSquareAround(tile, MP_TREES, 0) >= 8 ||
+ CountMapSquareAround(tile, MP_INDUSTRY, IT_FOREST) >= 2)
+ ) {
+ found = _opt.landscape == LT_DESERT ?
+ M(STR_SV_STNAME_FOREST) : M(STR_SV_STNAME_WOODS);
+ goto done;
+ }
+
+ /* check elevation compared to town */
+ z = GetTileZ(tile);
+ z2 = GetTileZ(t->xy);
+ if (z < z2) {
+ found = M(STR_SV_STNAME_VALLEY);
+ if (HASBIT(free_names, M(STR_SV_STNAME_VALLEY))) goto done;
+ } else if (z > z2) {
+ found = M(STR_SV_STNAME_HEIGHTS);
+ if (HASBIT(free_names, M(STR_SV_STNAME_HEIGHTS))) goto done;
+ }
+
+ /* check direction compared to town */
+ {
+ static const int8 _direction_and_table[] = {
+ ~( (1<<M(STR_SV_STNAME_WEST)) | (1<<M(STR_SV_STNAME_EAST)) | (1<<M(STR_SV_STNAME_NORTH)) ),
+ ~( (1<<M(STR_SV_STNAME_SOUTH)) | (1<<M(STR_SV_STNAME_WEST)) | (1<<M(STR_SV_STNAME_NORTH)) ),
+ ~( (1<<M(STR_SV_STNAME_SOUTH)) | (1<<M(STR_SV_STNAME_EAST)) | (1<<M(STR_SV_STNAME_NORTH)) ),
+ ~( (1<<M(STR_SV_STNAME_SOUTH)) | (1<<M(STR_SV_STNAME_WEST)) | (1<<M(STR_SV_STNAME_EAST)) ),
+ };
+
+ free_names &= _direction_and_table[
+ (TileX(tile) < TileX(t->xy)) +
+ (TileY(tile) < TileY(t->xy)) * 2];
+ }
+
+ tmp = free_names & ((1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<6)|(1<<7)|(1<<12)|(1<<26)|(1<<27)|(1<<28)|(1<<29)|(1<<30));
+ if (tmp == 0) {
+ _error_message = STR_3007_TOO_MANY_STATIONS_LOADING;
+ return false;
+ }
+ found = FindFirstBit(tmp);
+
+done:
+ st->string_id = found + STR_SV_STNAME;
+ return true;
+}
+#undef M
+
+static Station* GetClosestStationFromTile(TileIndex tile, uint threshold, PlayerID owner)
+{
+ Station* best_station = NULL;
+ Station* st;
+
+ FOR_ALL_STATIONS(st) {
+ if ((owner == PLAYER_SPECTATOR || st->owner == owner)) {
+ uint cur_dist = DistanceManhattan(tile, st->xy);
+
+ if (cur_dist < threshold) {
+ threshold = cur_dist;
+ best_station = st;
+ }
+ }
+ }
+
+ return best_station;
+}
+
+static void StationInitialize(Station *st, TileIndex tile)
+{
+ GoodsEntry *ge;
+
+ st->xy = tile;
+ st->airport_tile = st->dock_tile = st->train_tile = 0;
+ st->bus_stops = st->truck_stops = NULL;
+ st->had_vehicle_of_type = 0;
+ st->time_since_load = 255;
+ st->time_since_unload = 255;
+ st->delete_ctr = 0;
+ st->facilities = 0;
+
+ st->last_vehicle_type = VEH_Invalid;
+
+ for (ge = st->goods; ge != endof(st->goods); ge++) {
+ ge->waiting_acceptance = 0;
+ ge->days_since_pickup = 0;
+ ge->enroute_from = INVALID_STATION;
+ ge->rating = 175;
+ ge->last_speed = 0;
+ ge->last_age = 0xFF;
+ ge->feeder_profit = 0;
+ }
+
+ st->random_bits = Random();
+ st->waiting_triggers = 0;
+
+ StationRect_Init(st);
+}
+
+// Update the virtual coords needed to draw the station sign.
+// st = Station to update for.
+static void UpdateStationVirtCoord(Station *st)
+{
+ Point pt = RemapCoords2(TileX(st->xy) * TILE_SIZE, TileY(st->xy) * TILE_SIZE);
+
+ pt.y -= 32;
+ if (st->facilities & FACIL_AIRPORT && st->airport_type == AT_OILRIG) pt.y -= 16;
+
+ SetDParam(0, st->index);
+ SetDParam(1, st->facilities);
+ UpdateViewportSignPos(&st->sign, pt.x, pt.y, STR_305C_0);
+}
+
+// Update the virtual coords needed to draw the station sign for all stations.
+void UpdateAllStationVirtCoord(void)
+{
+ Station* st;
+
+ FOR_ALL_STATIONS(st) {
+ UpdateStationVirtCoord(st);
+ }
+}
+
+// Update the station virt coords while making the modified parts dirty.
+static void UpdateStationVirtCoordDirty(Station *st)
+{
+ MarkStationDirty(st);
+ UpdateStationVirtCoord(st);
+ MarkStationDirty(st);
+}
+
+// Get a mask of the cargo types that the station accepts.
+static uint GetAcceptanceMask(const Station *st)
+{
+ uint mask = 0;
+ uint i;
+
+ for (i = 0; i != NUM_CARGO; i++) {
+ if (st->goods[i].waiting_acceptance & 0x8000) mask |= 1 << i;
+ }
+ return mask;
+}
+
+// Items contains the two cargo names that are to be accepted or rejected.
+// msg is the string id of the message to display.
+static void ShowRejectOrAcceptNews(const Station *st, uint32 items, StringID msg)
+{
+ if (items) {
+ SetDParam(2, GB(items, 16, 16));
+ SetDParam(1, GB(items, 0, 16));
+ SetDParam(0, st->index);
+ AddNewsItem(msg + (GB(items, 16, 16) ? 1 : 0), NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_TILE, NT_ACCEPTANCE, 0), st->xy, 0);
+ }
+}
+
+// Get a list of the cargo types being produced around the tile.
+void GetProductionAroundTiles(AcceptedCargo produced, TileIndex tile,
+ int w, int h, int rad)
+{
+ int x,y;
+ int x1,y1,x2,y2;
+ int xc,yc;
+
+ memset(produced, 0, sizeof(AcceptedCargo));
+
+ x = TileX(tile);
+ y = TileY(tile);
+
+ // expand the region by rad tiles on each side
+ // while making sure that we remain inside the board.
+ x2 = min(x + w + rad, MapSizeX());
+ x1 = max(x - rad, 0);
+
+ y2 = min(y + h + rad, MapSizeY());
+ y1 = max(y - rad, 0);
+
+ assert(x1 < x2);
+ assert(y1 < y2);
+ assert(w > 0);
+ assert(h > 0);
+
+ for (yc = y1; yc != y2; yc++) {
+ for (xc = x1; xc != x2; xc++) {
+ if (!(IS_INSIDE_1D(xc, x, w) && IS_INSIDE_1D(yc, y, h))) {
+ GetProducedCargoProc *gpc;
+ TileIndex tile = TileXY(xc, yc);
+
+ gpc = _tile_type_procs[GetTileType(tile)]->get_produced_cargo_proc;
+ if (gpc != NULL) {
+ CargoID cargos[2] = { CT_INVALID, CT_INVALID };
+
+ gpc(tile, cargos);
+ if (cargos[0] != CT_INVALID) {
+ produced[cargos[0]]++;
+ if (cargos[1] != CT_INVALID) {
+ produced[cargos[1]]++;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+// Get a list of the cargo types that are accepted around the tile.
+void GetAcceptanceAroundTiles(AcceptedCargo accepts, TileIndex tile,
+ int w, int h, int rad)
+{
+ int x,y;
+ int x1,y1,x2,y2;
+ int xc,yc;
+
+ memset(accepts, 0, sizeof(AcceptedCargo));
+
+ x = TileX(tile);
+ y = TileY(tile);
+
+ // expand the region by rad tiles on each side
+ // while making sure that we remain inside the board.
+ x2 = min(x + w + rad, MapSizeX());
+ y2 = min(y + h + rad, MapSizeY());
+ x1 = max(x - rad, 0);
+ y1 = max(y - rad, 0);
+
+ assert(x1 < x2);
+ assert(y1 < y2);
+ assert(w > 0);
+ assert(h > 0);
+
+ for (yc = y1; yc != y2; yc++) {
+ for (xc = x1; xc != x2; xc++) {
+ TileIndex tile = TileXY(xc, yc);
+
+ if (!IsTileType(tile, MP_STATION)) {
+ AcceptedCargo ac;
+ uint i;
+
+ GetAcceptedCargo(tile, ac);
+ for (i = 0; i < lengthof(ac); ++i) accepts[i] += ac[i];
+ }
+ }
+ }
+}
+
+typedef struct ottd_Rectangle {
+ uint min_x;
+ uint min_y;
+ uint max_x;
+ uint max_y;
+} ottd_Rectangle;
+
+static inline void MergePoint(ottd_Rectangle* rect, TileIndex tile)
+{
+ uint x = TileX(tile);
+ uint y = TileY(tile);
+
+ if (rect->min_x > x) rect->min_x = x;
+ if (rect->min_y > y) rect->min_y = y;
+ if (rect->max_x < x) rect->max_x = x;
+ if (rect->max_y < y) rect->max_y = y;
+}
+
+// Update the acceptance for a station.
+// show_msg controls whether to display a message that acceptance was changed.
+static void UpdateStationAcceptance(Station *st, bool show_msg)
+{
+ uint old_acc, new_acc;
+ const RoadStop *cur_rs;
+ int i;
+ ottd_Rectangle rect;
+ int rad;
+ AcceptedCargo accepts;
+
+ rect.min_x = MapSizeX();
+ rect.min_y = MapSizeY();
+ rect.max_x = rect.max_y = 0;
+ // Don't update acceptance for a buoy
+ if (IsBuoy(st)) return;
+
+ /* old accepted goods types */
+ old_acc = GetAcceptanceMask(st);
+
+ // Put all the tiles that span an area in the table.
+ if (st->train_tile != 0) {
+ MergePoint(&rect, st->train_tile);
+ MergePoint(&rect,
+ st->train_tile + TileDiffXY(st->trainst_w - 1, st->trainst_h - 1)
+ );
+ }
+
+ if (st->airport_tile != 0) {
+ const AirportFTAClass* afc = GetAirport(st->airport_type);
+
+ MergePoint(&rect, st->airport_tile);
+ MergePoint(&rect,
+ st->airport_tile + TileDiffXY(afc->size_x - 1, afc->size_y - 1)
+ );
+ }
+
+ if (st->dock_tile != 0) MergePoint(&rect, st->dock_tile);
+
+ for (cur_rs = st->bus_stops; cur_rs != NULL; cur_rs = cur_rs->next) {
+ MergePoint(&rect, cur_rs->xy);
+ }
+
+ for (cur_rs = st->truck_stops; cur_rs != NULL; cur_rs = cur_rs->next) {
+ MergePoint(&rect, cur_rs->xy);
+ }
+
+ rad = (_patches.modified_catchment) ? FindCatchmentRadius(st) : 4;
+
+ // And retrieve the acceptance.
+ if (rect.max_x >= rect.min_x) {
+ GetAcceptanceAroundTiles(
+ accepts,
+ TileXY(rect.min_x, rect.min_y),
+ rect.max_x - rect.min_x + 1,
+ rect.max_y - rect.min_y + 1,
+ rad
+ );
+ } else {
+ memset(accepts, 0, sizeof(accepts));
+ }
+
+ // Adjust in case our station only accepts fewer kinds of goods
+ for (i = 0; i != NUM_CARGO; i++) {
+ uint amt = min(accepts[i], 15);
+
+ // Make sure the station can accept the goods type.
+ if ((i != CT_PASSENGERS && !(st->facilities & (byte)~FACIL_BUS_STOP)) ||
+ (i == CT_PASSENGERS && !(st->facilities & (byte)~FACIL_TRUCK_STOP)))
+ amt = 0;
+
+ SB(st->goods[i].waiting_acceptance, 12, 4, amt);
+ }
+
+ // Only show a message in case the acceptance was actually changed.
+ new_acc = GetAcceptanceMask(st);
+ if (old_acc == new_acc)
+ return;
+
+ // show a message to report that the acceptance was changed?
+ if (show_msg && st->owner == _local_player && st->facilities) {
+ uint32 accept=0, reject=0; /* these contain two string ids each */
+ const StringID *str = _cargoc.names_s;
+
+ do {
+ if (new_acc & 1) {
+ if (!(old_acc & 1)) accept = (accept << 16) | *str;
+ } else {
+ if (old_acc & 1) reject = (reject << 16) | *str;
+ }
+ } while (str++,(new_acc>>=1) != (old_acc>>=1));
+
+ ShowRejectOrAcceptNews(st, accept, STR_3040_NOW_ACCEPTS);
+ ShowRejectOrAcceptNews(st, reject, STR_303E_NO_LONGER_ACCEPTS);
+ }
+
+ // redraw the station view since acceptance changed
+ InvalidateWindowWidget(WC_STATION_VIEW, st->index, 4);
+}
+
+static void UpdateStationSignCoord(Station *st)
+{
+ Rect *r = &st->rect;
+
+ if (StationRect_IsEmpty(st)) return; // no tiles belong to this station
+
+ // clamp sign coord to be inside the station rect
+ st->xy = TileXY(clampu(TileX(st->xy), r->left, r->right), clampu(TileY(st->xy), r->top, r->bottom));
+ UpdateStationVirtCoordDirty(st);
+}
+
+// This is called right after a station was deleted.
+// It checks if the whole station is free of substations, and if so, the station will be
+// deleted after a little while.
+static void DeleteStationIfEmpty(Station* st)
+{
+ if (st->facilities == 0) {
+ st->delete_ctr = 0;
+ RebuildStationLists();
+ InvalidateWindow(WC_STATION_LIST, st->owner);
+ }
+ /* station remains but it probably lost some parts - station sign should stay in the station boundaries */
+ UpdateStationSignCoord(st);
+}
+
+static int32 ClearTile_Station(TileIndex tile, byte flags);
+
+// Tries to clear the given area. Returns the cost in case of success.
+// Or an error code if it failed.
+int32 CheckFlatLandBelow(TileIndex tile, uint w, uint h, uint flags, uint invalid_dirs, StationID* station)
+{
+ int32 cost = 0, ret;
+
+ Slope tileh;
+ uint z;
+ int allowed_z = -1;
+ int flat_z;
+
+ BEGIN_TILE_LOOP(tile_cur, w, h, tile)
+ if (MayHaveBridgeAbove(tile_cur) && IsBridgeAbove(tile_cur)) {
+ return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
+ }
+
+ if (!EnsureNoVehicle(tile_cur)) return CMD_ERROR;
+
+ tileh = GetTileSlope(tile_cur, &z);
+
+ /* Prohibit building if
+ * 1) The tile is "steep" (i.e. stretches two height levels)
+ * -OR-
+ * 2) The tile is non-flat if
+ * a) the player building is an "old-school" AI
+ * -OR-
+ * b) the build_on_slopes switch is disabled
+ */
+ if (IsSteepSlope(tileh) ||
+ ((_is_old_ai_player || !_patches.build_on_slopes) && tileh != SLOPE_FLAT)) {
+ return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
+ }
+
+ flat_z = z;
+ if (tileh != SLOPE_FLAT) {
+ // need to check so the entrance to the station is not pointing at a slope.
+ if ((invalid_dirs&1 && !(tileh & SLOPE_NE) && (uint)w_cur == w) ||
+ (invalid_dirs&2 && !(tileh & SLOPE_SE) && h_cur == 1) ||
+ (invalid_dirs&4 && !(tileh & SLOPE_SW) && w_cur == 1) ||
+ (invalid_dirs&8 && !(tileh & SLOPE_NW) && (uint)h_cur == h)) {
+ return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
+ }
+ cost += _price.terraform;
+ flat_z += TILE_HEIGHT;
+ }
+
+ // get corresponding flat level and make sure that all parts of the station have the same level.
+ if (allowed_z == -1) {
+ // first tile
+ allowed_z = flat_z;
+ } else if (allowed_z != flat_z) {
+ return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
+ }
+
+ // if station is set, then we have special handling to allow building on top of already existing stations.
+ // so station points to INVALID_STATION if we can build on any station. or it points to a station if we're only allowed to build
+ // on exactly that station.
+ if (station != NULL && IsTileType(tile_cur, MP_STATION)) {
+ if (!IsRailwayStation(tile_cur)) {
+ return ClearTile_Station(tile_cur, DC_AUTO); // get error message
+ } else {
+ StationID st = GetStationIndex(tile_cur);
+ if (*station == INVALID_STATION) {
+ *station = st;
+ } else if (*station != st) {
+ return_cmd_error(STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING);
+ }
+ }
+ } else {
+ ret = DoCommand(tile_cur, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+ if (CmdFailed(ret)) return ret;
+ cost += ret;
+ }
+ END_TILE_LOOP(tile_cur, w, h, tile)
+
+ return cost;
+}
+
+static bool CanExpandRailroadStation(Station* st, uint* fin, Axis axis)
+{
+ uint curw = st->trainst_w, curh = st->trainst_h;
+ TileIndex tile = fin[0];
+ uint w = fin[1];
+ uint h = fin[2];
+
+ if (_patches.nonuniform_stations) {
+ // determine new size of train station region..
+ int x = min(TileX(st->train_tile), TileX(tile));
+ int y = min(TileY(st->train_tile), TileY(tile));
+ curw = max(TileX(st->train_tile) + curw, TileX(tile) + w) - x;
+ curh = max(TileY(st->train_tile) + curh, TileY(tile) + h) - y;
+ tile = TileXY(x, y);
+ } else {
+ // check so the orientation is the same
+ if (GetRailStationAxis(st->train_tile) != axis) {
+ _error_message = STR_306D_NONUNIFORM_STATIONS_DISALLOWED;
+ return false;
+ }
+
+ // check if the new station adjoins the old station in either direction
+ if (curw == w && st->train_tile == tile + TileDiffXY(0, h)) {
+ // above
+ curh += h;
+ } else if (curw == w && st->train_tile == tile - TileDiffXY(0, curh)) {
+ // below
+ tile -= TileDiffXY(0, curh);
+ curh += h;
+ } else if (curh == h && st->train_tile == tile + TileDiffXY(w, 0)) {
+ // to the left
+ curw += w;
+ } else if (curh == h && st->train_tile == tile - TileDiffXY(curw, 0)) {
+ // to the right
+ tile -= TileDiffXY(curw, 0);
+ curw += w;
+ } else {
+ _error_message = STR_306D_NONUNIFORM_STATIONS_DISALLOWED;
+ return false;
+ }
+ }
+ // make sure the final size is not too big.
+ if (curw > _patches.station_spread || curh > _patches.station_spread) {
+ _error_message = STR_306C_STATION_TOO_SPREAD_OUT;
+ return false;
+ }
+
+ // now tile contains the new value for st->train_tile
+ // curw, curh contain the new value for width and height
+ fin[0] = tile;
+ fin[1] = curw;
+ fin[2] = curh;
+ return true;
+}
+
+static inline byte *CreateSingle(byte *layout, int n)
+{
+ int i = n;
+ do *layout++ = 0; while (--i);
+ layout[((n-1) >> 1)-n] = 2;
+ return layout;
+}
+
+static inline byte *CreateMulti(byte *layout, int n, byte b)
+{
+ int i = n;
+ do *layout++ = b; while (--i);
+ if (n > 4) {
+ layout[0-n] = 0;
+ layout[n-1-n] = 0;
+ }
+ return layout;
+}
+
+static void GetStationLayout(byte *layout, int numtracks, int plat_len, const StationSpec *statspec)
+{
+ if (statspec != NULL && statspec->lengths >= plat_len &&
+ statspec->platforms[plat_len - 1] >= numtracks &&
+ statspec->layouts[plat_len - 1][numtracks - 1]) {
+ /* Custom layout defined, follow it. */
+ memcpy(layout, statspec->layouts[plat_len - 1][numtracks - 1],
+ plat_len * numtracks);
+ return;
+ }
+
+ if (plat_len == 1) {
+ CreateSingle(layout, numtracks);
+ } else {
+ if (numtracks & 1) layout = CreateSingle(layout, plat_len);
+ numtracks >>= 1;
+
+ while (--numtracks >= 0) {
+ layout = CreateMulti(layout, plat_len, 4);
+ layout = CreateMulti(layout, plat_len, 6);
+ }
+ }
+}
+
+/** Build railroad station
+ * @param tile_org starting position of station dragging/placement
+ * @param p1 various bitstuffed elements
+ * - p1 = (bit 0) - orientation (p1 & 1)
+ * - p1 = (bit 8-15) - number of tracks
+ * - p1 = (bit 16-23) - platform length
+ * @param p2 various bitstuffed elements
+ * - p2 = (bit 0- 3) - railtype (p2 & 0xF)
+ * - p2 = (bit 8-15) - custom station class
+ * - p2 = (bit 16-23) - custom station id
+ */
+int32 CmdBuildRailroadStation(TileIndex tile_org, uint32 flags, uint32 p1, uint32 p2)
+{
+ Station *st;
+ int w_org, h_org;
+ int32 cost, ret;
+ StationID est;
+ int plat_len, numtracks;
+ Axis axis;
+ uint finalvalues[3];
+ const StationSpec *statspec;
+ int specindex;
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ /* Does the authority allow this? */
+ if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile_org)) return CMD_ERROR;
+ if (!ValParamRailtype(p2 & 0xF)) return CMD_ERROR;
+
+ /* unpack parameters */
+ axis = p1 & 1;
+ numtracks = GB(p1, 8, 8);
+ plat_len = GB(p1, 16, 8);
+ /* w = length, h = num_tracks */
+ if (axis == AXIS_X) {
+ w_org = plat_len;
+ h_org = numtracks;
+ } else {
+ h_org = plat_len;
+ w_org = numtracks;
+ }
+
+ if (h_org > _patches.station_spread || w_org > _patches.station_spread) return CMD_ERROR;
+
+ // these values are those that will be stored in train_tile and station_platforms
+ finalvalues[0] = tile_org;
+ finalvalues[1] = w_org;
+ finalvalues[2] = h_org;
+
+ // Make sure the area below consists of clear tiles. (OR tiles belonging to a certain rail station)
+ est = INVALID_STATION;
+ // If DC_EXEC is in flag, do not want to pass it to CheckFlatLandBelow, because of a nice bug
+ // for detail info, see: https://sourceforge.net/tracker/index.php?func=detail&aid=1029064&group_id=103924&atid=636365
+ ret = CheckFlatLandBelow(tile_org, w_org, h_org, flags & ~DC_EXEC, 5 << axis, _patches.nonuniform_stations ? &est : NULL);
+ if (CmdFailed(ret)) return ret;
+ cost = ret + (numtracks * _price.train_station_track + _price.train_station_length) * plat_len;
+
+ // Make sure there are no similar stations around us.
+ st = GetStationAround(tile_org, w_org, h_org, est);
+ if (st == CHECK_STATIONS_ERR) return CMD_ERROR;
+
+ // See if there is a deleted station close to us.
+ if (st == NULL) {
+ st = GetClosestStationFromTile(tile_org, 8, _current_player);
+ if (st != NULL && st->facilities) st = NULL;
+ }
+
+ if (st != NULL) {
+ // Reuse an existing station.
+ if (st->owner != OWNER_NONE && st->owner != _current_player)
+ return_cmd_error(STR_3009_TOO_CLOSE_TO_ANOTHER_STATION);
+
+ if (st->train_tile != 0) {
+ // check if we want to expanding an already existing station?
+ if (_is_old_ai_player || !_patches.join_stations)
+ return_cmd_error(STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD);
+ if (!CanExpandRailroadStation(st, finalvalues, axis))
+ return CMD_ERROR;
+ }
+
+ //XXX can't we pack this in the "else" part of the if above?
+ if (!StationRect_BeforeAddRect(st, tile_org, w_org, h_org, RECT_MODE_TEST)) return CMD_ERROR;
+ } else {
+ // Create a new station
+ st = AllocateStation();
+ if (st == NULL) return CMD_ERROR;
+
+ st->town = ClosestTownFromTile(tile_org, (uint)-1);
+ if (IsValidPlayer(_current_player) && (flags & DC_EXEC))
+ SETBIT(st->town->have_ratings, _current_player);
+
+ if (!GenerateStationName(st, tile_org, 0)) return CMD_ERROR;
+
+ if (flags & DC_EXEC) StationInitialize(st, tile_org);
+ }
+
+ /* Check if the given station class is valid */
+ if (GB(p2, 8, 8) >= STAT_CLASS_MAX) return CMD_ERROR;
+
+ /* Check if we can allocate a custom stationspec to this station */
+ statspec = GetCustomStationSpec(GB(p2, 8, 8), GB(p2, 16, 8));
+ specindex = AllocateSpecToStation(statspec, st, flags & DC_EXEC);
+ if (specindex == -1) return CMD_ERROR;
+
+ if (statspec != NULL) {
+ /* Perform NewStation checks */
+
+ /* Check if the station size is permitted */
+ if (HASBIT(statspec->disallowed_platforms, numtracks - 1) || HASBIT(statspec->disallowed_lengths, plat_len - 1)) {
+ return CMD_ERROR;
+ }
+
+ /* Check if the station is buildable */
+ if (HASBIT(statspec->callbackmask, CBM_STATION_AVAIL) && GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE) == 0) {
+ return CMD_ERROR;
+ }
+ }
+
+ if (flags & DC_EXEC) {
+ TileIndexDiff tile_delta;
+ byte *layout_ptr;
+ byte numtracks_orig;
+ Track track;
+
+ // Now really clear the land below the station
+ // It should never return CMD_ERROR.. but you never know ;)
+ // (a bit strange function name for it, but it really does clear the land, when DC_EXEC is in flags)
+ ret = CheckFlatLandBelow(tile_org, w_org, h_org, flags, 5 << axis, _patches.nonuniform_stations ? &est : NULL);
+ if (CmdFailed(ret)) return ret;
+
+ st->train_tile = finalvalues[0];
+ if (!st->facilities) st->xy = finalvalues[0];
+ st->facilities |= FACIL_TRAIN;
+ st->owner = _current_player;
+
+ st->trainst_w = finalvalues[1];
+ st->trainst_h = finalvalues[2];
+
+ st->build_date = _date;
+
+ StationRect_BeforeAddRect(st, tile_org, w_org, h_org, RECT_MODE_TRY);
+
+ tile_delta = (axis == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
+ track = AxisToTrack(axis);
+
+ layout_ptr = alloca(numtracks * plat_len);
+ GetStationLayout(layout_ptr, numtracks, plat_len, statspec);
+
+ numtracks_orig = numtracks;
+
+ do {
+ TileIndex tile = tile_org;
+ int w = plat_len;
+ do {
+ byte layout = *layout_ptr++;
+ MakeRailStation(tile, st->owner, st->index, axis, layout, GB(p2, 0, 4));
+ SetCustomStationSpecIndex(tile, specindex);
+ SetStationTileRandomBits(tile, GB(Random(), 0, 4));
+
+ if (statspec != NULL) {
+ /* Use a fixed axis for GetPlatformInfo as our platforms / numtracks are always the right way around */
+ uint32 platinfo = GetPlatformInfo(AXIS_X, 0, plat_len, numtracks_orig, plat_len - w, numtracks_orig - numtracks, false);
+ uint16 callback = GetStationCallback(CBID_STATION_TILE_LAYOUT, platinfo, 0, statspec, st, tile);
+ if (callback != CALLBACK_FAILED && callback < 8) SetStationGfx(tile, callback + axis);
+ }
+
+ tile += tile_delta;
+ } while (--w);
+ SetSignalsOnBothDir(tile_org, track);
+ YapfNotifyTrackLayoutChange(tile_org, track);
+ tile_org += tile_delta ^ TileDiffXY(1, 1); // perpendicular to tile_delta
+ } while (--numtracks);
+
+ MarkStationTilesDirty(st);
+ UpdateStationVirtCoordDirty(st);
+ UpdateStationAcceptance(st, false);
+ RebuildStationLists();
+ InvalidateWindow(WC_STATION_LIST, st->owner);
+ }
+
+ return cost;
+}
+
+static void MakeRailwayStationAreaSmaller(Station *st)
+{
+ uint w = st->trainst_w;
+ uint h = st->trainst_h;
+ TileIndex tile = st->train_tile;
+ uint i;
+
+restart:
+
+ // too small?
+ if (w != 0 && h != 0) {
+ // check the left side, x = constant, y changes
+ for (i = 0; !TileBelongsToRailStation(st, tile + TileDiffXY(0, i));) {
+ // the left side is unused?
+ if (++i == h) {
+ tile += TileDiffXY(1, 0);
+ w--;
+ goto restart;
+ }
+ }
+
+ // check the right side, x = constant, y changes
+ for (i = 0; !TileBelongsToRailStation(st, tile + TileDiffXY(w - 1, i));) {
+ // the right side is unused?
+ if (++i == h) {
+ w--;
+ goto restart;
+ }
+ }
+
+ // check the upper side, y = constant, x changes
+ for (i = 0; !TileBelongsToRailStation(st, tile + TileDiffXY(i, 0));) {
+ // the left side is unused?
+ if (++i == w) {
+ tile += TileDiffXY(0, 1);
+ h--;
+ goto restart;
+ }
+ }
+
+ // check the lower side, y = constant, x changes
+ for (i = 0; !TileBelongsToRailStation(st, tile + TileDiffXY(i, h - 1));) {
+ // the left side is unused?
+ if (++i == w) {
+ h--;
+ goto restart;
+ }
+ }
+ } else {
+ tile = 0;
+ }
+
+ st->trainst_w = w;
+ st->trainst_h = h;
+ st->train_tile = tile;
+}
+
+/** Remove a single tile from a railroad station.
+ * This allows for custom-built station with holes and weird layouts
+ * @param tile tile of station piece to remove
+ * @param p1 unused
+ * @param p2 unused
+ */
+int32 CmdRemoveFromRailroadStation(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Station *st;
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ // make sure the specified tile belongs to the current player, and that it is a railroad station.
+ if (!IsTileType(tile, MP_STATION) || !IsRailwayStation(tile) || !_patches.nonuniform_stations) return CMD_ERROR;
+ st = GetStationByTile(tile);
+ if (_current_player != OWNER_WATER && (!CheckOwnership(st->owner) || !EnsureNoVehicle(tile))) return CMD_ERROR;
+
+ // if we reached here, it means we can actually delete it. do that.
+ if (flags & DC_EXEC) {
+ uint specindex = GetCustomStationSpecIndex(tile);
+ Track track = GetRailStationTrack(tile);
+ DoClearSquare(tile);
+ StationRect_AfterRemoveTile(st, tile);
+ SetSignalsOnBothDir(tile, track);
+ YapfNotifyTrackLayoutChange(tile, track);
+
+ DeallocateSpecFromStation(st, specindex);
+
+ // now we need to make the "spanned" area of the railway station smaller if we deleted something at the edges.
+ // we also need to adjust train_tile.
+ MakeRailwayStationAreaSmaller(st);
+ MarkStationTilesDirty(st);
+ UpdateStationSignCoord(st);
+
+ // if we deleted the whole station, delete the train facility.
+ if (st->train_tile == 0) {
+ st->facilities &= ~FACIL_TRAIN;
+ UpdateStationVirtCoordDirty(st);
+ DeleteStationIfEmpty(st);
+ }
+ }
+ return _price.remove_rail_station;
+}
+
+// determine the number of platforms for the station
+uint GetStationPlatforms(const Station *st, TileIndex tile)
+{
+ TileIndex t;
+ TileIndexDiff delta;
+ Axis axis;
+ uint len;
+ assert(TileBelongsToRailStation(st, tile));
+
+ len = 0;
+ axis = GetRailStationAxis(tile);
+ delta = (axis == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
+
+ // find starting tile..
+ t = tile;
+ do {
+ t -= delta;
+ len++;
+ } while (TileBelongsToRailStation(st, t) && GetRailStationAxis(t) == axis);
+
+ // find ending tile
+ t = tile;
+ do {
+ t += delta;
+ len++;
+ } while (TileBelongsToRailStation(st, t) && GetRailStationAxis(t) == axis);
+
+ return len - 1;
+}
+
+/** Determines the REMAINING length of a platform, starting at (and including)
+ * the given tile.
+ * @param tile the tile from which to start searching. Must be a railway station tile
+ * @param dir The direction in which to search.
+ * @return The platform length
+ */
+uint GetPlatformLength(TileIndex tile, DiagDirection dir)
+{
+ TileIndex start_tile = tile;
+ uint length = 0;
+ assert(IsRailwayStationTile(tile));
+ assert(dir < DIAGDIR_END);
+
+ do {
+ length ++;
+ tile += TileOffsByDiagDir(dir);
+ } while (IsCompatibleTrainStationTile(tile, start_tile));
+
+ return length;
+}
+
+
+static int32 RemoveRailroadStation(Station *st, TileIndex tile, uint32 flags)
+{
+ int w,h;
+ int32 cost = 0;
+
+ /* if there is flooding and non-uniform stations are enabled, remove platforms tile by tile */
+ if (_current_player == OWNER_WATER && _patches.nonuniform_stations)
+ return DoCommand(tile, 0, 0, DC_EXEC, CMD_REMOVE_FROM_RAILROAD_STATION);
+
+ /* Current player owns the station? */
+ if (_current_player != OWNER_WATER && !CheckOwnership(st->owner))
+ return CMD_ERROR;
+
+ /* determine width and height of platforms */
+ tile = st->train_tile;
+ w = st->trainst_w;
+ h = st->trainst_h;
+
+ assert(w != 0 && h != 0);
+
+ /* clear all areas of the station */
+ do {
+ int w_bak = w;
+ do {
+ // for nonuniform stations, only remove tiles that are actually train station tiles
+ if (TileBelongsToRailStation(st, tile)) {
+ if (!EnsureNoVehicle(tile))
+ return CMD_ERROR;
+ cost += _price.remove_rail_station;
+ if (flags & DC_EXEC) {
+ Track track = GetRailStationTrack(tile);
+ DoClearSquare(tile);
+ SetSignalsOnBothDir(tile, track);
+ YapfNotifyTrackLayoutChange(tile, track);
+ }
+ }
+ tile += TileDiffXY(1, 0);
+ } while (--w);
+ w = w_bak;
+ tile += TileDiffXY(-w, 1);
+ } while (--h);
+
+ if (flags & DC_EXEC) {
+ StationRect_AfterRemoveRect(st, st->train_tile, st->trainst_w, st->trainst_h);
+
+ st->train_tile = 0;
+ st->trainst_w = st->trainst_h = 0;
+ st->facilities &= ~FACIL_TRAIN;
+
+ free(st->speclist);
+ st->num_specs = 0;
+ st->speclist = NULL;
+
+ UpdateStationVirtCoordDirty(st);
+ DeleteStationIfEmpty(st);
+ }
+
+ return cost;
+}
+
+int32 DoConvertStationRail(TileIndex tile, RailType totype, bool exec)
+{
+ const Station* st = GetStationByTile(tile);
+
+ if (!CheckOwnership(st->owner) || !EnsureNoVehicle(tile)) return CMD_ERROR;
+
+ // tile is not a railroad station?
+ if (!IsRailwayStation(tile)) return CMD_ERROR;
+
+ if (GetRailType(tile) == totype) return CMD_ERROR;
+
+ // 'hidden' elrails can't be downgraded to normal rail when elrails are disabled
+ if (_patches.disable_elrails && totype == RAILTYPE_RAIL && GetRailType(tile) == RAILTYPE_ELECTRIC) return CMD_ERROR;
+
+ if (exec) {
+ SetRailType(tile, totype);
+ MarkTileDirtyByTile(tile);
+ YapfNotifyTrackLayoutChange(tile, GetRailStationTrack(tile));
+ }
+
+ return _price.build_rail >> 1;
+}
+
+/** Heavy wizardry used to add a roadstop to a station.
+ * To understand the function, lets first look at what is passed around,
+ * especially the last two parameters. CmdBuildRoadStop allocates a road
+ * stop and needs to put that stop into the linked list of road stops.
+ * It (CmdBuildRoadStop) has a **currstop pointer which points to element
+ * in the linked list of stops (each element in this list being a pointer
+ * in itself, hence the double pointer). We (FindRoadStopSpot) need to
+ * modify this pointer (**currstop) thus we need to pass by reference,
+ * obtaining a triple pointer (***currstop). When finished, **currstop
+ * in CmdBuildRoadStop will contain the address of the pointer which will
+ * then point into the global roadstop array. *prev (in CmdBuildRoadStop)
+ * is the pointer tino the global roadstop array which has *currstop in
+ * its ->next element.
+ * @param[in] truck_station Determines whether a stop is RS_BUS or RS_TRUCK
+ * @param[in] station The station to do the whole procedure for
+ * @param[out] currstop See the detailed function description
+ * @param prev See the detailed function description
+ */
+static void FindRoadStopSpot(bool truck_station, Station* st, RoadStop*** currstop, RoadStop** prev)
+{
+ RoadStop **primary_stop = (truck_station) ? &st->truck_stops : &st->bus_stops;
+ assert(*prev == NULL);
+
+ if (*primary_stop == NULL) {
+ //we have no roadstop of the type yet, so write a "primary stop"
+ *currstop = primary_stop;
+ } else {
+ //there are stops already, so append to the end of the list
+ *prev = *primary_stop;
+ *currstop = &(*primary_stop)->next;
+ while (**currstop != NULL) {
+ *prev = (*prev)->next;
+ *currstop = &(**currstop)->next;
+ }
+ }
+}
+
+/** Build a bus or truck stop
+ * @param tile tile to build the stop at
+ * @param p1 entrance direction (DiagDirection)
+ * @param p2 0 for Bus stops, 1 for truck stops
+ */
+int32 CmdBuildRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Station *st;
+ RoadStop *road_stop;
+ RoadStop **currstop;
+ RoadStop *prev = NULL;
+ int32 cost;
+ int32 ret;
+ bool type = !!p2;
+
+ /* Saveguard the parameters */
+ if (!IsValidDiagDirection(p1)) return CMD_ERROR;
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile))
+ return CMD_ERROR;
+
+ ret = CheckFlatLandBelow(tile, 1, 1, flags, 1 << p1, NULL);
+ if (CmdFailed(ret)) return ret;
+ cost = ret;
+
+ st = GetStationAround(tile, 1, 1, -1);
+ if (st == CHECK_STATIONS_ERR) return CMD_ERROR;
+
+ /* Find a station close to us */
+ if (st == NULL) {
+ st = GetClosestStationFromTile(tile, 8, _current_player);
+ if (st != NULL && st->facilities != 0) st = NULL;
+ }
+
+ //give us a road stop in the list, and check if something went wrong
+ road_stop = AllocateRoadStop();
+ if (road_stop == NULL) {
+ return_cmd_error(type ? STR_3008B_TOO_MANY_TRUCK_STOPS : STR_3008A_TOO_MANY_BUS_STOPS);
+ }
+
+ if (st != NULL &&
+ GetNumRoadStopsInStation(st, RS_BUS) + GetNumRoadStopsInStation(st, RS_TRUCK) >= ROAD_STOP_LIMIT) {
+ return_cmd_error(type ? STR_3008B_TOO_MANY_TRUCK_STOPS : STR_3008A_TOO_MANY_BUS_STOPS);
+ }
+
+ if (st != NULL) {
+ if (st->owner != OWNER_NONE && st->owner != _current_player) {
+ return_cmd_error(STR_3009_TOO_CLOSE_TO_ANOTHER_STATION);
+ }
+
+ if (!StationRect_BeforeAddTile(st, tile, RECT_MODE_TEST)) return CMD_ERROR;
+
+ FindRoadStopSpot(type, st, &currstop, &prev);
+ } else {
+ Town *t;
+
+ st = AllocateStation();
+ if (st == NULL) return CMD_ERROR;
+
+ st->town = t = ClosestTownFromTile(tile, (uint)-1);
+
+ FindRoadStopSpot(type, st, &currstop, &prev);
+
+ if (IsValidPlayer(_current_player) && (flags & DC_EXEC)) {
+ SETBIT(t->have_ratings, _current_player);
+ }
+
+ st->sign.width_1 = 0;
+
+ if (!GenerateStationName(st, tile, 0)) return CMD_ERROR;
+
+ if (flags & DC_EXEC) StationInitialize(st, tile);
+ }
+
+ cost += (type) ? _price.build_truck_station : _price.build_bus_station;
+
+ if (flags & DC_EXEC) {
+ //point to the correct item in the _busstops or _truckstops array
+ *currstop = road_stop;
+
+ //initialize an empty station
+ InitializeRoadStop(road_stop, prev, tile, st->index);
+ if (!st->facilities) st->xy = tile;
+ st->facilities |= (type) ? FACIL_TRUCK_STOP : FACIL_BUS_STOP;
+ st->owner = _current_player;
+
+ st->build_date = _date;
+
+ StationRect_BeforeAddTile(st, tile, RECT_MODE_TRY);
+
+ MakeRoadStop(tile, st->owner, st->index, type, p1);
+
+ UpdateStationVirtCoordDirty(st);
+ UpdateStationAcceptance(st, false);
+ RebuildStationLists();
+ InvalidateWindow(WC_STATION_LIST, st->owner);
+ }
+ return cost;
+}
+
+// Remove a bus station
+static int32 RemoveRoadStop(Station *st, uint32 flags, TileIndex tile)
+{
+ RoadStop **primary_stop;
+ RoadStop *cur_stop;
+ bool is_truck = IsTruckStop(tile);
+
+ if (_current_player != OWNER_WATER && !CheckOwnership(st->owner)) {
+ return CMD_ERROR;
+ }
+
+ if (is_truck) { // truck stop
+ primary_stop = &st->truck_stops;
+ cur_stop = GetRoadStopByTile(tile, RS_TRUCK);
+ } else {
+ primary_stop = &st->bus_stops;
+ cur_stop = GetRoadStopByTile(tile, RS_BUS);
+ }
+
+ assert(cur_stop != NULL);
+
+ if (!EnsureNoVehicle(tile)) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ //we only had one stop left
+ if (cur_stop->next == NULL && cur_stop->prev == NULL) {
+ //so we remove ALL stops
+ *primary_stop = NULL;
+ st->facilities &= (is_truck) ? ~FACIL_TRUCK_STOP : ~FACIL_BUS_STOP;
+ } else if (cur_stop == *primary_stop) {
+ //removed the first stop in the list
+ //need to set the primary element to the next stop
+ *primary_stop = (*primary_stop)->next;
+ }
+
+ DeleteRoadStop(cur_stop);
+ DoClearSquare(tile);
+ StationRect_AfterRemoveTile(st, tile);
+
+ UpdateStationVirtCoordDirty(st);
+ DeleteStationIfEmpty(st);
+ }
+
+ return (is_truck) ? _price.remove_truck_station : _price.remove_bus_station;
+}
+
+
+
+// FIXME -- need to move to its corresponding Airport variable
+// Country Airfield (small)
+static const byte _airport_sections_country[] = {
+ 54, 53, 52, 65,
+ 58, 57, 56, 55,
+ 64, 63, 63, 62
+};
+
+// City Airport (large)
+static const byte _airport_sections_town[] = {
+ 31, 9, 33, 9, 9, 32,
+ 27, 36, 29, 34, 8, 10,
+ 30, 11, 35, 13, 20, 21,
+ 51, 12, 14, 17, 19, 28,
+ 38, 13, 15, 16, 18, 39,
+ 26, 22, 23, 24, 25, 26
+};
+
+// Metropolitain Airport (large) - 2 runways
+static const byte _airport_sections_metropolitan[] = {
+ 31, 9, 33, 9, 9, 32,
+ 27, 36, 29, 34, 8, 10,
+ 30, 11, 35, 13, 20, 21,
+ 102, 8, 8, 8, 8, 28,
+ 83, 84, 84, 84, 84, 83,
+ 26, 23, 23, 23, 23, 26
+};
+
+// International Airport (large) - 2 runways
+static const byte _airport_sections_international[] = {
+ 88, 89, 89, 89, 89, 89, 88,
+ 51, 8, 8, 8, 8, 8, 32,
+ 30, 8, 11, 27, 11, 8, 10,
+ 32, 8, 11, 27, 11, 8, 114,
+ 87, 8, 11, 85, 11, 8, 114,
+ 87, 8, 8, 8, 8, 8, 90,
+ 26, 23, 23, 23, 23, 23, 26
+};
+
+// Intercontinental Airport (vlarge) - 4 runways
+static const byte _airport_sections_intercontinental[] = {
+ 102, 120, 89, 89, 89, 89, 89, 89, 118,
+ 120, 22, 22, 22, 22, 22, 22, 119, 117,
+ 87, 54, 87, 8, 8, 8, 8, 51, 117,
+ 87, 162, 87, 85, 116, 116, 8, 9, 10,
+ 87, 8, 8, 11, 31, 11, 8, 160, 32,
+ 32, 160, 8, 11, 27, 11, 8, 8, 10,
+ 87, 8, 8, 11, 30, 11, 8, 8, 10,
+ 87, 142, 8, 11, 29, 11, 10, 163, 10,
+ 87, 164, 87, 8, 8, 8, 10, 37, 117,
+ 87, 120, 89, 89, 89, 89, 89, 89, 119,
+ 121, 22, 22, 22, 22, 22, 22, 119, 37
+};
+
+
+// Commuter Airfield (small)
+static const byte _airport_sections_commuter[] = {
+ 85, 30, 115, 115, 32,
+ 87, 8, 8, 8, 10,
+ 87, 11, 11, 11, 10,
+ 26, 23, 23, 23, 26
+};
+
+// Heliport
+static const byte _airport_sections_heliport[] = {
+ 66,
+};
+
+// Helidepot
+static const byte _airport_sections_helidepot[] = {
+ 124, 32,
+ 122, 123
+};
+
+// Helistation
+static const byte _airport_sections_helistation[] = {
+ 32, 134, 159, 158,
+ 161, 142, 142, 157
+};
+
+static const byte * const _airport_sections[] = {
+ _airport_sections_country, // Country Airfield (small)
+ _airport_sections_town, // City Airport (large)
+ _airport_sections_heliport, // Heliport
+ _airport_sections_metropolitan, // Metropolitain Airport (large)
+ _airport_sections_international, // International Airport (xlarge)
+ _airport_sections_commuter, // Commuter Airport (small)
+ _airport_sections_helidepot, // Helidepot
+ _airport_sections_intercontinental, // Intercontinental Airport (xxlarge)
+ _airport_sections_helistation // Helistation
+};
+
+/** Place an Airport.
+ * @param tile tile where airport will be built
+ * @param p1 airport type, @see airport.h
+ * @param p2 unused
+ */
+int32 CmdBuildAirport(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Town *t;
+ Station *st;
+ int32 cost;
+ int32 ret;
+ int w, h;
+ bool airport_upgrade = true;
+ const AirportFTAClass* afc;
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ /* Check if a valid, buildable airport was chosen for construction */
+ if (p1 > lengthof(_airport_sections) || !HASBIT(GetValidAirports(), p1)) return CMD_ERROR;
+
+ if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile))
+ return CMD_ERROR;
+
+ t = ClosestTownFromTile(tile, (uint)-1);
+
+ /* Check if local auth refuses a new airport */
+ {
+ uint num = 0;
+ FOR_ALL_STATIONS(st) {
+ if (st->town == t && st->facilities&FACIL_AIRPORT && st->airport_type != AT_OILRIG)
+ num++;
+ }
+ if (num >= 2) {
+ SetDParam(0, t->index);
+ return_cmd_error(STR_2035_LOCAL_AUTHORITY_REFUSES);
+ }
+ }
+
+ afc = GetAirport(p1);
+ w = afc->size_x;
+ h = afc->size_y;
+
+ ret = CheckFlatLandBelow(tile, w, h, flags, 0, NULL);
+ if (CmdFailed(ret)) return ret;
+ cost = ret;
+
+ st = GetStationAround(tile, w, h, -1);
+ if (st == CHECK_STATIONS_ERR) return CMD_ERROR;
+
+ /* Find a station close to us */
+ if (st == NULL) {
+ st = GetClosestStationFromTile(tile, 8, _current_player);
+ if (st != NULL && st->facilities) st = NULL;
+ }
+
+ if (st != NULL) {
+ if (st->owner != OWNER_NONE && st->owner != _current_player)
+ return_cmd_error(STR_3009_TOO_CLOSE_TO_ANOTHER_STATION);
+
+ if (!StationRect_BeforeAddRect(st, tile, w, h, RECT_MODE_TEST)) return CMD_ERROR;
+
+ if (st->airport_tile != 0)
+ return_cmd_error(STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT);
+ } else {
+ airport_upgrade = false;
+
+ st = AllocateStation();
+ if (st == NULL) return CMD_ERROR;
+
+ st->town = t;
+
+ if (IsValidPlayer(_current_player) && (flags & DC_EXEC))
+ SETBIT(t->have_ratings, _current_player);
+
+ st->sign.width_1 = 0;
+
+ // if airport type equals Heliport then generate
+ // type 5 name, which is heliport, otherwise airport names (1)
+ if (!GenerateStationName(st, tile, (p1 == AT_HELIPORT)||(p1 == AT_HELIDEPOT)||(p1 == AT_HELISTATION) ? 5 : 1))
+ return CMD_ERROR;
+
+ if (flags & DC_EXEC) StationInitialize(st, tile);
+ }
+
+ cost += _price.build_airport * w * h;
+
+ if (flags & DC_EXEC) {
+ st->owner = _current_player;
+ st->airport_tile = tile;
+ if (!st->facilities) st->xy = tile;
+ st->facilities |= FACIL_AIRPORT;
+ st->airport_type = (byte)p1;
+ st->airport_flags = 0;
+
+ st->build_date = _date;
+
+ StationRect_BeforeAddRect(st, tile, w, h, RECT_MODE_TRY);
+
+ /* if airport was demolished while planes were en-route to it, the
+ * positions can no longer be the same (v->u.air.pos), since different
+ * airports have different indexes. So update all planes en-route to this
+ * airport. Only update if
+ * 1. airport is upgraded
+ * 2. airport is added to existing station (unfortunately unavoideable)
+ */
+ if (airport_upgrade) UpdateAirplanesOnNewStation(st);
+
+ {
+ const byte *b = _airport_sections[p1];
+
+ BEGIN_TILE_LOOP(tile_cur, w, h, tile) {
+ MakeAirport(tile_cur, st->owner, st->index, *b++);
+ } END_TILE_LOOP(tile_cur, w, h, tile)
+ }
+
+ UpdateStationVirtCoordDirty(st);
+ UpdateStationAcceptance(st, false);
+ RebuildStationLists();
+ InvalidateWindow(WC_STATION_LIST, st->owner);
+ }
+
+ return cost;
+}
+
+static int32 RemoveAirport(Station *st, uint32 flags)
+{
+ TileIndex tile;
+ int w,h;
+ int32 cost;
+ const AirportFTAClass* afc;
+
+ if (_current_player != OWNER_WATER && !CheckOwnership(st->owner))
+ return CMD_ERROR;
+
+ tile = st->airport_tile;
+
+ afc = GetAirport(st->airport_type);
+ w = afc->size_x;
+ h = afc->size_y;
+
+ cost = w * h * _price.remove_airport;
+
+ BEGIN_TILE_LOOP(tile_cur, w, h, tile) {
+ if (!EnsureNoVehicle(tile_cur)) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ DeleteAnimatedTile(tile_cur);
+ DoClearSquare(tile_cur);
+ }
+ } END_TILE_LOOP(tile_cur, w,h,tile)
+
+ if (flags & DC_EXEC) {
+ uint i;
+
+ for (i = 0; i < afc->nof_depots; ++i) {
+ DeleteWindowById(
+ WC_VEHICLE_DEPOT, tile + ToTileIndexDiff(afc->airport_depots[i])
+ );
+ }
+
+ StationRect_AfterRemoveRect(st, tile, w, h);
+
+ st->airport_tile = 0;
+ st->facilities &= ~FACIL_AIRPORT;
+
+ UpdateStationVirtCoordDirty(st);
+ DeleteStationIfEmpty(st);
+ }
+
+ return cost;
+}
+
+/** Build a buoy.
+ * @param tile tile where to place the bouy
+ * @param p1 unused
+ * @param p2 unused
+ */
+int32 CmdBuildBuoy(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Station *st;
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ if (!IsClearWaterTile(tile) || tile == 0) return_cmd_error(STR_304B_SITE_UNSUITABLE);
+
+ st = AllocateStation();
+ if (st == NULL) return CMD_ERROR;
+
+ st->town = ClosestTownFromTile(tile, (uint)-1);
+ st->sign.width_1 = 0;
+
+ if (!GenerateStationName(st, tile, 4)) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ StationInitialize(st, tile);
+ st->dock_tile = tile;
+ st->facilities |= FACIL_DOCK;
+ /* Buoys are marked in the Station struct by this flag. Yes, it is this
+ * braindead.. */
+ st->had_vehicle_of_type |= HVOT_BUOY;
+ st->owner = OWNER_NONE;
+
+ st->build_date = _date;
+
+ MakeBuoy(tile, st->index);
+
+ UpdateStationVirtCoordDirty(st);
+ UpdateStationAcceptance(st, false);
+ RebuildStationLists();
+ InvalidateWindow(WC_STATION_LIST, st->owner);
+ }
+
+ return _price.build_dock;
+}
+
+/* Checks if any ship is servicing the buoy specified. Returns yes or no */
+static bool CheckShipsOnBuoy(Station *st)
+{
+ const Vehicle *v;
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == VEH_Ship) {
+ const Order *order;
+ FOR_VEHICLE_ORDERS(v, order) {
+ if (order->type == OT_GOTO_STATION && order->dest == st->index) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+static int32 RemoveBuoy(Station *st, uint32 flags)
+{
+ TileIndex tile;
+
+ /* XXX: strange stuff */
+ if (!IsValidPlayer(_current_player)) return_cmd_error(INVALID_STRING_ID);
+
+ tile = st->dock_tile;
+
+ if (CheckShipsOnBuoy(st)) return_cmd_error(STR_BUOY_IS_IN_USE);
+ if (!EnsureNoVehicle(tile)) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ st->dock_tile = 0;
+ /* Buoys are marked in the Station struct by this flag. Yes, it is this
+ * braindead.. */
+ st->facilities &= ~FACIL_DOCK;
+ st->had_vehicle_of_type &= ~HVOT_BUOY;
+
+ MakeWater(tile);
+ MarkTileDirtyByTile(tile);
+
+ UpdateStationVirtCoordDirty(st);
+ DeleteStationIfEmpty(st);
+ }
+
+ return _price.remove_truck_station;
+}
+
+static const TileIndexDiffC _dock_tileoffs_chkaround[] = {
+ {-1, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, -1}
+};
+static const byte _dock_w_chk[4] = { 2, 1, 2, 1 };
+static const byte _dock_h_chk[4] = { 1, 2, 1, 2 };
+
+/** Build a dock/haven.
+ * @param tile tile where dock will be built
+ * @param p1 unused
+ * @param p2 unused
+ */
+int32 CmdBuildDock(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ TileIndex tile_cur;
+ DiagDirection direction;
+ int32 cost;
+ Station *st;
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ switch (GetTileSlope(tile, NULL)) {
+ case SLOPE_SW: direction = DIAGDIR_NE; break;
+ case SLOPE_SE: direction = DIAGDIR_NW; break;
+ case SLOPE_NW: direction = DIAGDIR_SE; break;
+ case SLOPE_NE: direction = DIAGDIR_SW; break;
+ default: return_cmd_error(STR_304B_SITE_UNSUITABLE);
+ }
+
+ if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile)) return CMD_ERROR;
+
+ if (!EnsureNoVehicle(tile)) return CMD_ERROR;
+
+ cost = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+ if (CmdFailed(cost)) return CMD_ERROR;
+
+ tile_cur = tile + TileOffsByDiagDir(direction);
+
+ if (!EnsureNoVehicle(tile_cur)) return CMD_ERROR;
+
+ if (!IsTileType(tile_cur, MP_WATER) || GetTileSlope(tile_cur, NULL) != SLOPE_FLAT) {
+ return_cmd_error(STR_304B_SITE_UNSUITABLE);
+ }
+
+ cost = DoCommand(tile_cur, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+ if (CmdFailed(cost)) return CMD_ERROR;
+
+ tile_cur += TileOffsByDiagDir(direction);
+ if (!IsTileType(tile_cur, MP_WATER) || GetTileSlope(tile_cur, NULL) != SLOPE_FLAT) {
+ return_cmd_error(STR_304B_SITE_UNSUITABLE);
+ }
+
+ /* middle */
+ st = GetStationAround(
+ tile + ToTileIndexDiff(_dock_tileoffs_chkaround[direction]),
+ _dock_w_chk[direction], _dock_h_chk[direction], -1);
+ if (st == CHECK_STATIONS_ERR) return CMD_ERROR;
+
+ /* Find a station close to us */
+ if (st == NULL) {
+ st = GetClosestStationFromTile(tile, 8, _current_player);
+ if (st!=NULL && st->facilities) st = NULL;
+ }
+
+ if (st != NULL) {
+ if (st->owner != OWNER_NONE && st->owner != _current_player)
+ return_cmd_error(STR_3009_TOO_CLOSE_TO_ANOTHER_STATION);
+
+ if (!StationRect_BeforeAddRect(st, tile, _dock_w_chk[direction], _dock_h_chk[direction], RECT_MODE_TEST)) return CMD_ERROR;
+
+ if (st->dock_tile != 0) return_cmd_error(STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK);
+ } else {
+ Town *t;
+
+ st = AllocateStation();
+ if (st == NULL) return CMD_ERROR;
+
+ st->town = t = ClosestTownFromTile(tile, (uint)-1);
+
+ if (IsValidPlayer(_current_player) && (flags & DC_EXEC))
+ SETBIT(t->have_ratings, _current_player);
+
+ st->sign.width_1 = 0;
+
+ if (!GenerateStationName(st, tile, 3)) return CMD_ERROR;
+
+ if (flags & DC_EXEC) StationInitialize(st, tile);
+ }
+
+ if (flags & DC_EXEC) {
+ st->dock_tile = tile;
+ if (!st->facilities) st->xy = tile;
+ st->facilities |= FACIL_DOCK;
+ st->owner = _current_player;
+
+ st->build_date = _date;
+
+ StationRect_BeforeAddRect(st, tile, _dock_w_chk[direction], _dock_h_chk[direction], RECT_MODE_TRY);
+
+ MakeDock(tile, st->owner, st->index, direction);
+
+ UpdateStationVirtCoordDirty(st);
+ UpdateStationAcceptance(st, false);
+ RebuildStationLists();
+ InvalidateWindow(WC_STATION_LIST, st->owner);
+ }
+ return _price.build_dock;
+}
+
+static int32 RemoveDock(Station *st, uint32 flags)
+{
+ TileIndex tile1;
+ TileIndex tile2;
+
+ if (!CheckOwnership(st->owner)) return CMD_ERROR;
+
+ tile1 = st->dock_tile;
+ tile2 = tile1 + TileOffsByDiagDir(GetDockDirection(tile1));
+
+ if (!EnsureNoVehicle(tile1)) return CMD_ERROR;
+ if (!EnsureNoVehicle(tile2)) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ DoClearSquare(tile1);
+ MakeWater(tile2);
+
+ StationRect_AfterRemoveTile(st, tile1);
+ StationRect_AfterRemoveTile(st, tile2);
+
+ MarkTileDirtyByTile(tile2);
+
+ st->dock_tile = 0;
+ st->facilities &= ~FACIL_DOCK;
+
+ UpdateStationVirtCoordDirty(st);
+ DeleteStationIfEmpty(st);
+ }
+
+ return _price.remove_dock;
+}
+
+#include "table/station_land.h"
+
+const DrawTileSprites *GetStationTileLayout(byte gfx)
+{
+ return &_station_display_datas[gfx];
+}
+
+static void DrawTile_Station(TileInfo *ti)
+{
+ uint32 image;
+ const DrawTileSeqStruct *dtss;
+ const DrawTileSprites *t = NULL;
+ RailType railtype = GetRailType(ti->tile);
+ const RailtypeInfo *rti = GetRailTypeInfo(railtype);
+ uint32 relocation = 0;
+ const Station *st = NULL;
+ const StationSpec *statspec = NULL;
+ PlayerID owner = GetTileOwner(ti->tile);
+ uint32 palette;
+
+ if (IsValidPlayer(owner)) {
+ palette = PLAYER_SPRITE_COLOR(owner);
+ } else {
+ // Some stations are not owner by a player, namely oil rigs
+ palette = PALETTE_TO_GREY;
+ }
+
+ // don't show foundation for docks
+ if (ti->tileh != SLOPE_FLAT && !IsDock(ti->tile))
+ DrawFoundation(ti, ti->tileh);
+
+ if (IsCustomStationSpecIndex(ti->tile)) {
+ // look for customization
+ st = GetStationByTile(ti->tile);
+ statspec = st->speclist[GetCustomStationSpecIndex(ti->tile)].spec;
+
+ //debug("Cust-o-mized %p", statspec);
+
+ if (statspec != NULL) {
+ uint tile = GetStationGfx(ti->tile);
+
+ relocation = GetCustomStationRelocation(statspec, st, ti->tile);
+
+ if (HASBIT(statspec->callbackmask, CBM_CUSTOM_LAYOUT)) {
+ uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0, 0, statspec, st, ti->tile);
+ if (callback != CALLBACK_FAILED) tile = (callback & ~1) + GetRailStationAxis(ti->tile);
+ }
+
+ /* Ensure the chosen tile layout is valid for this custom station */
+ if (statspec->renderdata != NULL) {
+ t = &statspec->renderdata[tile < statspec->tiles ? tile : GetRailStationAxis(ti->tile)];
+ }
+ }
+ }
+
+ if (t == NULL || t->seq == NULL) t = &_station_display_datas[GetStationGfx(ti->tile)];
+
+ image = t->ground_sprite;
+ if (HASBIT(image, 31)) {
+ CLRBIT(image, 31);
+ image += GetCustomStationGroundRelocation(statspec, st, ti->tile);
+ image += rti->custom_ground_offset;
+ } else {
+ image += rti->total_offset;
+ }
+ if (image & PALETTE_MODIFIER_COLOR) image |= palette;
+
+ // station_land array has been increased from 82 elements to 114
+ // but this is something else. If AI builds station with 114 it looks all weird
+ DrawGroundSprite(image);
+
+ if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC && IsStationTileElectrifiable(ti->tile)) DrawCatenary(ti);
+
+ foreach_draw_tile_seq(dtss, t->seq) {
+ image = dtss->image;
+ if (HASBIT(image, 30)) {
+ CLRBIT(image, 30);
+ image += rti->total_offset;
+ } else {
+ image += relocation;
+ }
+
+ if (_display_opt & DO_TRANS_BUILDINGS) {
+ MAKE_TRANSPARENT(image);
+ } else if (image & PALETTE_MODIFIER_COLOR) {
+ image |= palette;
+ }
+
+ if ((byte)dtss->delta_z != 0x80) {
+ AddSortableSpriteToDraw(
+ image,
+ ti->x + dtss->delta_x, ti->y + dtss->delta_y,
+ dtss->size_x, dtss->size_y,
+ dtss->size_z, ti->z + dtss->delta_z
+ );
+ } else {
+ AddChildSpriteScreen(image, dtss->delta_x, dtss->delta_y);
+ }
+ }
+}
+
+void StationPickerDrawSprite(int x, int y, RailType railtype, int image)
+{
+ uint32 ormod, img;
+ const DrawTileSeqStruct *dtss;
+ const DrawTileSprites *t;
+ const RailtypeInfo *rti = GetRailTypeInfo(railtype);
+
+ ormod = PLAYER_SPRITE_COLOR(_local_player);
+
+ t = &_station_display_datas[image];
+
+ img = t->ground_sprite;
+ if (img & PALETTE_MODIFIER_COLOR) img |= ormod;
+ DrawSprite(img + rti->total_offset, x, y);
+
+ foreach_draw_tile_seq(dtss, t->seq) {
+ Point pt = RemapCoords(dtss->delta_x, dtss->delta_y, dtss->delta_z);
+ DrawSprite((dtss->image | ormod) + rti->total_offset, x + pt.x, y + pt.y);
+ }
+}
+
+static uint GetSlopeZ_Station(TileIndex tile, uint x, uint y)
+{
+ return GetTileMaxZ(tile);
+}
+
+static Slope GetSlopeTileh_Station(TileIndex tile, Slope tileh)
+{
+ return SLOPE_FLAT;
+}
+
+static void GetAcceptedCargo_Station(TileIndex tile, AcceptedCargo ac)
+{
+ /* not used */
+}
+
+static void GetTileDesc_Station(TileIndex tile, TileDesc *td)
+{
+ StringID str;
+
+ td->owner = GetTileOwner(tile);
+ td->build_date = GetStationByTile(tile)->build_date;
+
+ switch (GetStationType(tile)) {
+ default: NOT_REACHED();
+ case STATION_RAIL: str = STR_305E_RAILROAD_STATION; break;
+ case STATION_AIRPORT:
+ str = (IsHangar(tile) ? STR_305F_AIRCRAFT_HANGAR : STR_3060_AIRPORT);
+ break;
+ case STATION_TRUCK: str = STR_3061_TRUCK_LOADING_AREA; break;
+ case STATION_BUS: str = STR_3062_BUS_STATION; break;
+ case STATION_OILRIG: str = STR_4807_OIL_RIG; break;
+ case STATION_DOCK: str = STR_3063_SHIP_DOCK; break;
+ case STATION_BUOY: str = STR_3069_BUOY; break;
+ }
+ td->str = str;
+}
+
+
+static uint32 GetTileTrackStatus_Station(TileIndex tile, TransportType mode)
+{
+ switch (mode) {
+ case TRANSPORT_RAIL:
+ if (IsRailwayStation(tile) && !IsStationTileBlocked(tile)) {
+ return TrackToTrackBits(GetRailStationTrack(tile)) * 0x101;
+ }
+ break;
+
+ case TRANSPORT_WATER:
+ // buoy is coded as a station, it is always on open water
+ if (IsBuoy_(tile)) return TRACK_BIT_ALL * 0x101;
+ break;
+
+ case TRANSPORT_ROAD:
+ if (IsRoadStopTile(tile)) {
+ return AxisToTrackBits(DiagDirToAxis(GetRoadStopDir(tile))) * 0x101;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+
+static void TileLoop_Station(TileIndex tile)
+{
+ // FIXME -- GetTileTrackStatus_Station -> animated stationtiles
+ // hardcoded.....not good
+ switch (GetStationGfx(tile)) {
+ case GFX_RADAR_LARGE_FIRST:
+ case GFX_WINDSACK_FIRST : // for small airport
+ case GFX_RADAR_INTERNATIONAL_FIRST:
+ case GFX_RADAR_METROPOLITAN_FIRST:
+ case GFX_RADAR_DISTRICTWE_FIRST: // radar district W-E airport
+ case GFX_WINDSACK_INTERCON_FIRST : // for intercontinental airport
+ AddAnimatedTile(tile);
+ break;
+
+ case GFX_OILRIG_BASE: //(station part)
+ case GFX_BUOY_BASE:
+ TileLoop_Water(tile);
+ break;
+
+ default: break;
+ }
+}
+
+
+static void AnimateTile_Station(TileIndex tile)
+{
+ typedef struct AnimData {
+ StationGfx from; // first sprite
+ StationGfx to; // last sprite
+ byte delay;
+ } AnimData;
+
+ static const AnimData data[] = {
+ { GFX_RADAR_LARGE_FIRST, GFX_RADAR_LARGE_LAST, 3 },
+ { GFX_WINDSACK_FIRST, GFX_WINDSACK_LAST, 1 },
+ { GFX_RADAR_INTERNATIONAL_FIRST, GFX_RADAR_INTERNATIONAL_LAST, 3 },
+ { GFX_RADAR_METROPOLITAN_FIRST, GFX_RADAR_METROPOLITAN_LAST, 3 },
+ { GFX_RADAR_DISTRICTWE_FIRST, GFX_RADAR_DISTRICTWE_LAST, 3 },
+ { GFX_WINDSACK_INTERCON_FIRST, GFX_WINDSACK_INTERCON_LAST, 1 }
+ };
+
+ StationGfx gfx = GetStationGfx(tile);
+ const AnimData* i;
+
+ for (i = data; i != endof(data); i++) {
+ if (i->from <= gfx && gfx <= i->to) {
+ if ((_tick_counter & i->delay) == 0) {
+ SetStationGfx(tile, gfx < i->to ? gfx + 1 : i->from);
+ MarkTileDirtyByTile(tile);
+ }
+ break;
+ }
+ }
+}
+
+
+static void ClickTile_Station(TileIndex tile)
+{
+ if (IsHangar(tile)) {
+ ShowDepotWindow(tile, VEH_Aircraft);
+ } else {
+ ShowStationViewWindow(GetStationIndex(tile));
+ }
+}
+
+static const byte _enter_station_speedtable[12] = {
+ 215, 195, 175, 155, 135, 115, 95, 75, 55, 35, 15, 0
+};
+
+static uint32 VehicleEnter_Station(Vehicle *v, TileIndex tile, int x, int y)
+{
+ if (v->type == VEH_Train) {
+ if (IsRailwayStation(tile) && IsFrontEngine(v) &&
+ !IsCompatibleTrainStationTile(tile + TileOffsByDiagDir(DirToDiagDir(v->direction)), tile)) {
+ StationID station_id = GetStationIndex(tile);
+
+ if ((!(v->current_order.flags & OF_NON_STOP) && !_patches.new_nonstop) ||
+ (v->current_order.type == OT_GOTO_STATION && v->current_order.dest == station_id)) {
+ if (!(_patches.new_nonstop && v->current_order.flags & OF_NON_STOP) &&
+ v->current_order.type != OT_LEAVESTATION &&
+ v->last_station_visited != station_id) {
+ DiagDirection dir = DirToDiagDir(v->direction);
+
+ x &= 0xF;
+ y &= 0xF;
+
+ if (DiagDirToAxis(dir) != AXIS_X) intswap(x, y);
+ if (y == TILE_SIZE / 2) {
+ if (dir != DIAGDIR_SE && dir != DIAGDIR_SW) x = TILE_SIZE - 1 - x;
+ if (x == 12) return 2 | (station_id << 8); /* enter station */
+ if (x < 12) {
+ uint16 spd;
+
+ v->vehstatus |= VS_TRAIN_SLOWING;
+ spd = _enter_station_speedtable[x];
+ if (spd < v->cur_speed) v->cur_speed = spd;
+ }
+ }
+ }
+ }
+ }
+ } else if (v->type == VEH_Road) {
+ if (v->u.road.state < 16 && !HASBIT(v->u.road.state, 2) && v->u.road.frame == 0) {
+ if (IsRoadStop(tile)) {
+ /* Attempt to allocate a parking bay in a road stop */
+ RoadStop *rs = GetRoadStopByTile(tile, GetRoadStopType(tile));
+
+ /* rs->status bits 0 and 1 describe current the two parking spots.
+ * 0 means occupied, 1 means free. */
+
+ // Check if station is busy or if there are no free bays.
+ if (HASBIT(rs->status, 7) || GB(rs->status, 0, 2) == 0)
+ return 8;
+
+ v->u.road.state += 32;
+
+ // if the first bay is free, allocate that, else the second bay must be free.
+ if (HASBIT(rs->status, 0)) {
+ CLRBIT(rs->status, 0);
+ } else {
+ CLRBIT(rs->status, 1);
+ v->u.road.state += 2;
+ }
+
+ // mark the station as busy
+ SETBIT(rs->status, 7);
+ }
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * Cleanup a RoadStop. Make sure no vehicles try to go to this roadstop.
+ */
+void DestroyRoadStop(RoadStop* rs)
+{
+ Vehicle *v;
+
+ /* Clear the slot assignment of all vehicles heading for this road stop */
+ if (rs->num_vehicles != 0) {
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == VEH_Road && v->u.road.slot == rs) {
+ ClearSlot(v);
+ }
+ }
+ }
+ assert(rs->num_vehicles == 0);
+
+ if (rs->prev != NULL) rs->prev->next = rs->next;
+ if (rs->next != NULL) rs->next->prev = rs->prev;
+}
+
+/**
+ * Clean up a station by clearing vehicle orders and invalidating windows.
+ * Aircraft-Hangar orders need special treatment here, as the hangars are
+ * actually part of a station (tiletype is STATION), but the order type
+ * is OT_GOTO_DEPOT.
+ * @param st Station to be deleted
+ */
+void DestroyStation(Station *st)
+{
+ StationID index;
+
+ index = st->index;
+
+ DeleteName(st->string_id);
+ MarkStationDirty(st);
+ RebuildStationLists();
+ InvalidateWindowClasses(WC_STATION_LIST);
+
+ DeleteWindowById(WC_STATION_VIEW, index);
+
+ /* Now delete all orders that go to the station */
+ RemoveOrderFromAllVehicles(OT_GOTO_STATION, index);
+
+ //Subsidies need removal as well
+ DeleteSubsidyWithStation(index);
+
+ free(st->speclist);
+}
+
+void DeleteAllPlayerStations(void)
+{
+ Station *st;
+
+ FOR_ALL_STATIONS(st) {
+ if (IsValidPlayer(st->owner)) DeleteStation(st);
+ }
+}
+
+/* this function is called for one station each tick */
+static void StationHandleBigTick(Station *st)
+{
+ UpdateStationAcceptance(st, true);
+
+ if (st->facilities == 0 && ++st->delete_ctr >= 8) DeleteStation(st);
+
+}
+
+static inline void byte_inc_sat(byte *p) { byte b = *p + 1; if (b != 0) *p = b; }
+
+static void UpdateStationRating(Station *st)
+{
+ GoodsEntry *ge;
+ int rating;
+ StationID index;
+ int waiting;
+ bool waiting_changed = false;
+
+ byte_inc_sat(&st->time_since_load);
+ byte_inc_sat(&st->time_since_unload);
+
+ ge = st->goods;
+ do {
+ if (ge->enroute_from != INVALID_STATION) {
+ byte_inc_sat(&ge->enroute_time);
+ byte_inc_sat(&ge->days_since_pickup);
+
+ rating = 0;
+
+ {
+ int b = ge->last_speed;
+ if ((b-=85) >= 0)
+ rating += b >> 2;
+ }
+
+ {
+ byte age = ge->last_age;
+ (age >= 3) ||
+ (rating += 10, age >= 2) ||
+ (rating += 10, age >= 1) ||
+ (rating += 13, true);
+ }
+
+ if (IsValidPlayer(st->owner) && HASBIT(st->town->statues, st->owner)) rating += 26;
+
+ {
+ byte days = ge->days_since_pickup;
+ if (st->last_vehicle_type == VEH_Ship)
+ days >>= 2;
+ (days > 21) ||
+ (rating += 25, days > 12) ||
+ (rating += 25, days > 6) ||
+ (rating += 45, days > 3) ||
+ (rating += 35, true);
+ }
+
+ {
+ waiting = GB(ge->waiting_acceptance, 0, 12);
+ (rating -= 90, waiting > 1500) ||
+ (rating += 55, waiting > 1000) ||
+ (rating += 35, waiting > 600) ||
+ (rating += 10, waiting > 300) ||
+ (rating += 20, waiting > 100) ||
+ (rating += 10, true);
+ }
+
+ {
+ int or = ge->rating; // old rating
+
+ // only modify rating in steps of -2, -1, 0, 1 or 2
+ ge->rating = rating = or + clamp(clamp(rating, 0, 255) - or, -2, 2);
+
+ // if rating is <= 64 and more than 200 items waiting, remove some random amount of goods from the station
+ if (rating <= 64 && waiting >= 200) {
+ int dec = Random() & 0x1F;
+ if (waiting < 400) dec &= 7;
+ waiting -= dec + 1;
+ waiting_changed = true;
+ }
+
+ // if rating is <= 127 and there are any items waiting, maybe remove some goods.
+ if (rating <= 127 && waiting != 0) {
+ uint32 r = Random();
+ if ( (uint)rating <= (r & 0x7F) ) {
+ waiting = max(waiting - ((r >> 8)&3) - 1, 0);
+ waiting_changed = true;
+ }
+ }
+
+ if (waiting_changed) SB(ge->waiting_acceptance, 0, 12, waiting);
+ }
+ }
+ } while (++ge != endof(st->goods));
+
+ index = st->index;
+
+ if (waiting_changed) {
+ InvalidateWindow(WC_STATION_VIEW, index);
+ } else {
+ InvalidateWindowWidget(WC_STATION_VIEW, index, 5);
+ }
+}
+
+/* called for every station each tick */
+static void StationHandleSmallTick(Station *st)
+{
+ byte b;
+
+ if (st->facilities == 0) return;
+
+ b = st->delete_ctr + 1;
+ if (b >= 185) b = 0;
+ st->delete_ctr = b;
+
+ if (b == 0) UpdateStationRating(st);
+}
+
+void OnTick_Station(void)
+{
+ uint i;
+ Station *st;
+
+ if (_game_mode == GM_EDITOR) return;
+
+ i = _station_tick_ctr;
+ if (++_station_tick_ctr > GetMaxStationIndex()) _station_tick_ctr = 0;
+
+ if (IsValidStationID(i)) StationHandleBigTick(GetStation(i));
+
+ FOR_ALL_STATIONS(st) {
+ StationHandleSmallTick(st);
+ }
+}
+
+void StationMonthlyLoop(void)
+{
+}
+
+
+void ModifyStationRatingAround(TileIndex tile, PlayerID owner, int amount, uint radius)
+{
+ Station *st;
+
+ FOR_ALL_STATIONS(st) {
+ if (st->owner == owner &&
+ DistanceManhattan(tile, st->xy) <= radius) {
+ uint i;
+
+ for (i = 0; i != NUM_CARGO; i++) {
+ GoodsEntry* ge = &st->goods[i];
+
+ if (ge->enroute_from != INVALID_STATION) {
+ ge->rating = clamp(ge->rating + amount, 0, 255);
+ }
+ }
+ }
+ }
+}
+
+static void UpdateStationWaiting(Station *st, int type, uint amount)
+{
+ SB(st->goods[type].waiting_acceptance, 0, 12,
+ min(0xFFF, GB(st->goods[type].waiting_acceptance, 0, 12) + amount)
+ );
+
+ st->goods[type].enroute_time = 0;
+ st->goods[type].enroute_from = st->index;
+ InvalidateWindow(WC_STATION_VIEW, st->index);
+ MarkStationTilesDirty(st);
+}
+
+/** Rename a station
+ * @param tile unused
+ * @param p1 station ID that is to be renamed
+ * @param p2 unused
+ */
+int32 CmdRenameStation(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ StringID str;
+ Station *st;
+
+ if (!IsValidStationID(p1) || _cmd_text[0] == '\0') return CMD_ERROR;
+ st = GetStation(p1);
+
+ if (!CheckOwnership(st->owner)) return CMD_ERROR;
+
+ str = AllocateNameUnique(_cmd_text, 6);
+ if (str == 0) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ StringID old_str = st->string_id;
+
+ st->string_id = str;
+ UpdateStationVirtCoord(st);
+ DeleteName(old_str);
+ ResortStationLists();
+ MarkWholeScreenDirty();
+ } else {
+ DeleteName(str);
+ }
+
+ return 0;
+}
+
+
+uint MoveGoodsToStation(TileIndex tile, int w, int h, int type, uint amount)
+{
+ Station* around[8];
+ uint i;
+ uint moved;
+ uint best_rating, best_rating2;
+ Station *st1, *st2;
+ uint t;
+ int rad = 0;
+ int w_prod; //width and height of the "producer" of the cargo
+ int h_prod;
+ int max_rad;
+
+ for (i = 0; i < lengthof(around); i++) around[i] = NULL;
+
+ if (_patches.modified_catchment) {
+ w_prod = w;
+ h_prod = h;
+ w += 16;
+ h += 16;
+ max_rad = 8;
+ } else {
+ w_prod = 0;
+ h_prod = 0;
+ w += 8;
+ h += 8;
+ max_rad = 4;
+ }
+
+ BEGIN_TILE_LOOP(cur_tile, w, h, tile - TileDiffXY(max_rad, max_rad))
+ Station* st;
+
+ cur_tile = TILE_MASK(cur_tile);
+ if (!IsTileType(cur_tile, MP_STATION)) continue;
+
+ st = GetStationByTile(cur_tile);
+
+ for (i = 0; i != lengthof(around); i++) {
+ if (around[i] == NULL) {
+ if (!IsBuoy(st) &&
+ (st->town->exclusive_counter == 0 || st->town->exclusivity == st->owner) && // check exclusive transport rights
+ st->goods[type].rating != 0 &&
+ (!_patches.selectgoods || st->goods[type].last_speed > 0) && // if last_speed is 0, no vehicle has been there.
+ ((st->facilities & ~FACIL_BUS_STOP) != 0 || type == CT_PASSENGERS) && // if we have other fac. than a bus stop, or the cargo is passengers
+ ((st->facilities & ~FACIL_TRUCK_STOP) != 0 || type != CT_PASSENGERS)) { // if we have other fac. than a cargo bay or the cargo is not passengers
+ int x_dist;
+ int y_dist;
+
+ if (_patches.modified_catchment) {
+ // min and max coordinates of the producer relative
+ const int x_min_prod = 9;
+ const int x_max_prod = 8 + w_prod;
+ const int y_min_prod = 9;
+ const int y_max_prod = 8 + h_prod;
+
+ rad = FindCatchmentRadius(st);
+
+ x_dist = min(w_cur - x_min_prod, x_max_prod - w_cur);
+ if (w_cur < x_min_prod) {
+ x_dist = x_min_prod - w_cur;
+ } else if (w_cur > x_max_prod) {
+ x_dist = w_cur - x_max_prod;
+ }
+
+ y_dist = min(h_cur - y_min_prod, y_max_prod - h_cur);
+ if (h_cur < y_min_prod) {
+ y_dist = y_min_prod - h_cur;
+ } else if (h_cur > y_max_prod) {
+ y_dist = h_cur - y_max_prod;
+ }
+ } else {
+ x_dist = 0;
+ y_dist = 0;
+ }
+
+ if (x_dist <= rad && y_dist <= rad) around[i] = st;
+ }
+ break;
+ } else if (around[i] == st) {
+ break;
+ }
+ }
+ END_TILE_LOOP(cur_tile, w, h, tile - TileDiffXY(max_rad, max_rad))
+
+ /* no stations around at all? */
+ if (around[0] == NULL) return 0;
+
+ if (around[1] == NULL) {
+ /* only one station around */
+ moved = (amount * around[0]->goods[type].rating >> 8) + 1;
+ UpdateStationWaiting(around[0], type, moved);
+ return moved;
+ }
+
+ /* several stations around, find the two with the highest rating */
+ st2 = st1 = NULL;
+ best_rating = best_rating2 = 0;
+
+ for (i = 0; i != lengthof(around) && around[i] != NULL; i++) {
+ if (around[i]->goods[type].rating >= best_rating) {
+ best_rating2 = best_rating;
+ st2 = st1;
+
+ best_rating = around[i]->goods[type].rating;
+ st1 = around[i];
+ } else if (around[i]->goods[type].rating >= best_rating2) {
+ best_rating2 = around[i]->goods[type].rating;
+ st2 = around[i];
+ }
+ }
+
+ assert(st1 != NULL);
+ assert(st2 != NULL);
+ assert(best_rating != 0 || best_rating2 != 0);
+
+ /* the 2nd highest one gets a penalty */
+ best_rating2 >>= 1;
+
+ /* amount given to station 1 */
+ t = (best_rating * (amount + 1)) / (best_rating + best_rating2);
+
+ moved = 0;
+ if (t != 0) {
+ moved = t * best_rating / 256 + 1;
+ amount -= t;
+ UpdateStationWaiting(st1, type, moved);
+ }
+
+ if (amount != 0) {
+ amount = amount * best_rating2 / 256 + 1;
+ moved += amount;
+ UpdateStationWaiting(st2, type, amount);
+ }
+
+ return moved;
+}
+
+void BuildOilRig(TileIndex tile)
+{
+ uint j;
+ Station *st = AllocateStation();
+
+ if (st == NULL) {
+ DEBUG(misc, 0, "Can't allocate station for oilrig at 0x%X, reverting to oilrig only", tile);
+ return;
+ }
+ if (!GenerateStationName(st, tile, 2)) {
+ DEBUG(misc, 0, "Can't allocate station-name for oilrig at 0x%X, reverting to oilrig only", tile);
+ return;
+ }
+
+ st->town = ClosestTownFromTile(tile, (uint)-1);
+ st->sign.width_1 = 0;
+
+ MakeOilrig(tile, st->index);
+
+ st->owner = OWNER_NONE;
+ st->airport_flags = 0;
+ st->airport_type = AT_OILRIG;
+ st->xy = tile;
+ st->bus_stops = NULL;
+ st->truck_stops = NULL;
+ st->airport_tile = tile;
+ st->dock_tile = tile;
+ st->train_tile = 0;
+ st->had_vehicle_of_type = 0;
+ st->time_since_load = 255;
+ st->time_since_unload = 255;
+ st->delete_ctr = 0;
+ st->last_vehicle_type = VEH_Invalid;
+ st->facilities = FACIL_AIRPORT | FACIL_DOCK;
+ st->build_date = _date;
+
+ for (j = 0; j != NUM_CARGO; j++) {
+ st->goods[j].waiting_acceptance = 0;
+ st->goods[j].days_since_pickup = 0;
+ st->goods[j].enroute_from = INVALID_STATION;
+ st->goods[j].rating = 175;
+ st->goods[j].last_speed = 0;
+ st->goods[j].last_age = 255;
+ }
+
+ UpdateStationVirtCoordDirty(st);
+ UpdateStationAcceptance(st, false);
+}
+
+void DeleteOilRig(TileIndex tile)
+{
+ Station* st = GetStationByTile(tile);
+
+ DoClearSquare(tile);
+
+ st->dock_tile = 0;
+ st->airport_tile = 0;
+ st->facilities &= ~(FACIL_AIRPORT | FACIL_DOCK);
+ st->airport_flags = 0;
+ UpdateStationVirtCoordDirty(st);
+ DeleteStation(st);
+}
+
+static void ChangeTileOwner_Station(TileIndex tile, PlayerID old_player, PlayerID new_player)
+{
+ if (!IsTileOwner(tile, old_player)) return;
+
+ if (new_player != PLAYER_SPECTATOR) {
+ Station* st = GetStationByTile(tile);
+
+ SetTileOwner(tile, new_player);
+ st->owner = new_player;
+ RebuildStationLists();
+ InvalidateWindowClasses(WC_STATION_LIST);
+ } else {
+ DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
+ }
+}
+
+static int32 ClearTile_Station(TileIndex tile, byte flags)
+{
+ Station *st;
+
+ if (flags & DC_AUTO) {
+ switch (GetStationType(tile)) {
+ case STATION_RAIL: return_cmd_error(STR_300B_MUST_DEMOLISH_RAILROAD);
+ case STATION_AIRPORT: return_cmd_error(STR_300E_MUST_DEMOLISH_AIRPORT_FIRST);
+ case STATION_TRUCK: return_cmd_error(STR_3047_MUST_DEMOLISH_TRUCK_STATION);
+ case STATION_BUS: return_cmd_error(STR_3046_MUST_DEMOLISH_BUS_STATION);
+ case STATION_BUOY: return_cmd_error(STR_306A_BUOY_IN_THE_WAY);
+ case STATION_DOCK: return_cmd_error(STR_304D_MUST_DEMOLISH_DOCK_FIRST);
+ case STATION_OILRIG:
+ SetDParam(0, STR_4807_OIL_RIG);
+ return_cmd_error(STR_4800_IN_THE_WAY);
+ }
+ }
+
+ st = GetStationByTile(tile);
+
+ switch (GetStationType(tile)) {
+ case STATION_RAIL: return RemoveRailroadStation(st, tile, flags);
+ case STATION_AIRPORT: return RemoveAirport(st, flags);
+ case STATION_TRUCK:
+ case STATION_BUS: return RemoveRoadStop(st, flags, tile);
+ case STATION_BUOY: return RemoveBuoy(st, flags);
+ case STATION_DOCK: return RemoveDock(st, flags);
+ default: break;
+ }
+
+ return CMD_ERROR;
+}
+
+void InitializeStations(void)
+{
+ /* Clean the station pool and create 1 block in it */
+ CleanPool(&_Station_pool);
+ AddBlockToPool(&_Station_pool);
+
+ /* Clean the roadstop pool and create 1 block in it */
+ CleanPool(&_RoadStop_pool);
+ AddBlockToPool(&_RoadStop_pool);
+
+ _station_tick_ctr = 0;
+
+}
+
+
+void AfterLoadStations(void)
+{
+ Station *st;
+ uint i;
+ TileIndex tile;
+
+ /* Update the speclists of all stations to point to the currently loaded custom stations. */
+ FOR_ALL_STATIONS(st) {
+ for (i = 0; i < st->num_specs; i++) {
+ if (st->speclist[i].grfid == 0) continue;
+
+ st->speclist[i].spec = GetCustomStationSpecByGrf(st->speclist[i].grfid, st->speclist[i].localidx);
+ }
+ }
+
+ for (tile = 0; tile < MapSize(); tile++) {
+ if (GetTileType(tile) != MP_STATION) continue;
+ st = GetStationByTile(tile);
+ StationRect_BeforeAddTile(st, tile, RECT_MODE_FORCE);
+ }
+}
+
+
+const TileTypeProcs _tile_type_station_procs = {
+ DrawTile_Station, /* draw_tile_proc */
+ GetSlopeZ_Station, /* get_slope_z_proc */
+ ClearTile_Station, /* clear_tile_proc */
+ GetAcceptedCargo_Station, /* get_accepted_cargo_proc */
+ GetTileDesc_Station, /* get_tile_desc_proc */
+ GetTileTrackStatus_Station, /* get_tile_track_status_proc */
+ ClickTile_Station, /* click_tile_proc */
+ AnimateTile_Station, /* animate_tile_proc */
+ TileLoop_Station, /* tile_loop_clear */
+ ChangeTileOwner_Station, /* change_tile_owner_clear */
+ NULL, /* get_produced_cargo_proc */
+ VehicleEnter_Station, /* vehicle_enter_tile_proc */
+ GetSlopeTileh_Station, /* get_slope_tileh_proc */
+};
+
+static const SaveLoad _roadstop_desc[] = {
+ SLE_VAR(RoadStop,xy, SLE_UINT32),
+ SLE_VAR(RoadStop,used, SLE_BOOL),
+ SLE_VAR(RoadStop,status, SLE_UINT8),
+ /* Index was saved in some versions, but this is not needed */
+ SLE_CONDNULL(4, 0, 8),
+ SLE_VAR(RoadStop,station, SLE_UINT16),
+ SLE_CONDNULL(1, 0, 25),
+
+ SLE_REF(RoadStop,next, REF_ROADSTOPS),
+ SLE_REF(RoadStop,prev, REF_ROADSTOPS),
+
+ SLE_CONDNULL(4, 0, 24),
+ SLE_CONDNULL(1, 25, 25),
+
+ SLE_END()
+};
+
+static const SaveLoad _station_desc[] = {
+ SLE_CONDVAR(Station, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+ SLE_CONDVAR(Station, xy, SLE_UINT32, 6, SL_MAX_VERSION),
+ SLE_CONDVAR(Station, bus_tile_obsolete, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+ SLE_CONDVAR(Station, lorry_tile_obsolete, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+ SLE_CONDVAR(Station, train_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+ SLE_CONDVAR(Station, train_tile, SLE_UINT32, 6, SL_MAX_VERSION),
+ SLE_CONDVAR(Station, airport_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+ SLE_CONDVAR(Station, airport_tile, SLE_UINT32, 6, SL_MAX_VERSION),
+ SLE_CONDVAR(Station, dock_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+ SLE_CONDVAR(Station, dock_tile, SLE_UINT32, 6, SL_MAX_VERSION),
+ SLE_REF(Station, town, REF_TOWN),
+ SLE_VAR(Station, trainst_w, SLE_UINT8),
+ SLE_CONDVAR(Station, trainst_h, SLE_UINT8, 2, SL_MAX_VERSION),
+
+ // alpha_order was stored here in savegame format 0 - 3
+ SLE_CONDNULL(1, 0, 3),
+
+ SLE_VAR(Station, string_id, SLE_STRINGID),
+ SLE_VAR(Station, had_vehicle_of_type, SLE_UINT16),
+
+ SLE_VAR(Station, time_since_load, SLE_UINT8),
+ SLE_VAR(Station, time_since_unload, SLE_UINT8),
+ SLE_VAR(Station, delete_ctr, SLE_UINT8),
+ SLE_VAR(Station, owner, SLE_UINT8),
+ SLE_VAR(Station, facilities, SLE_UINT8),
+ SLE_VAR(Station, airport_type, SLE_UINT8),
+
+ // truck/bus_stop_status was stored here in savegame format 0 - 6
+ SLE_CONDVAR(Station, truck_stop_status_obsolete, SLE_UINT8, 0, 5),
+ SLE_CONDVAR(Station, bus_stop_status_obsolete, SLE_UINT8, 0, 5),
+
+ // blocked_months was stored here in savegame format 0 - 4.0
+ SLE_CONDVAR(Station, blocked_months_obsolete, SLE_UINT8, 0, 4),
+
+ SLE_CONDVAR(Station, airport_flags, SLE_VAR_U32 | SLE_FILE_U16, 0, 2),
+ SLE_CONDVAR(Station, airport_flags, SLE_UINT32, 3, SL_MAX_VERSION),
+
+ SLE_CONDNULL(2, 0, 25), /* Ex last-vehicle */
+ SLE_CONDVAR(Station, last_vehicle_type, SLE_UINT8, 26, SL_MAX_VERSION),
+
+ // Was custom station class and id
+ SLE_CONDNULL(2, 3, 25),
+ SLE_CONDVAR(Station, build_date, SLE_FILE_U16 | SLE_VAR_I32, 3, 30),
+ SLE_CONDVAR(Station, build_date, SLE_INT32, 31, SL_MAX_VERSION),
+
+ SLE_CONDREF(Station, bus_stops, REF_ROADSTOPS, 6, SL_MAX_VERSION),
+ SLE_CONDREF(Station, truck_stops, REF_ROADSTOPS, 6, SL_MAX_VERSION),
+
+ /* Used by newstations for graphic variations */
+ SLE_CONDVAR(Station, random_bits, SLE_UINT16, 27, SL_MAX_VERSION),
+ SLE_CONDVAR(Station, waiting_triggers, SLE_UINT8, 27, SL_MAX_VERSION),
+ SLE_CONDVAR(Station, num_specs, SLE_UINT8, 27, SL_MAX_VERSION),
+
+ // reserve extra space in savegame here. (currently 32 bytes)
+ SLE_CONDNULL(32, 2, SL_MAX_VERSION),
+
+ SLE_END()
+};
+
+static const SaveLoad _goods_desc[] = {
+ SLE_VAR(GoodsEntry, waiting_acceptance, SLE_UINT16),
+ SLE_VAR(GoodsEntry, days_since_pickup, SLE_UINT8),
+ SLE_VAR(GoodsEntry, rating, SLE_UINT8),
+ SLE_CONDVAR(GoodsEntry, enroute_from, SLE_FILE_U8 | SLE_VAR_U16, 0, 6),
+ SLE_CONDVAR(GoodsEntry, enroute_from, SLE_UINT16, 7, SL_MAX_VERSION),
+ SLE_VAR(GoodsEntry, enroute_time, SLE_UINT8),
+ SLE_VAR(GoodsEntry, last_speed, SLE_UINT8),
+ SLE_VAR(GoodsEntry, last_age, SLE_UINT8),
+ SLE_CONDVAR(GoodsEntry, feeder_profit, SLE_INT32, 14, SL_MAX_VERSION),
+
+ SLE_END()
+};
+
+static const SaveLoad _station_speclist_desc[] = {
+ SLE_CONDVAR(StationSpecList, grfid, SLE_UINT32, 27, SL_MAX_VERSION),
+ SLE_CONDVAR(StationSpecList, localidx, SLE_UINT8, 27, SL_MAX_VERSION),
+
+ SLE_END()
+};
+
+
+static void SaveLoad_STNS(Station *st)
+{
+ uint i;
+
+ SlObject(st, _station_desc);
+ for (i = 0; i != NUM_CARGO; i++) {
+ SlObject(&st->goods[i], _goods_desc);
+
+ /* In older versions, enroute_from had 0xFF as INVALID_STATION, is now 0xFFFF */
+ if (CheckSavegameVersion(7) && st->goods[i].enroute_from == 0xFF) {
+ st->goods[i].enroute_from = INVALID_STATION;
+ }
+ }
+
+ if (st->num_specs != 0) {
+ /* Allocate speclist memory when loading a game */
+ if (st->speclist == NULL) st->speclist = calloc(st->num_specs, sizeof(*st->speclist));
+ for (i = 0; i < st->num_specs; i++) SlObject(&st->speclist[i], _station_speclist_desc);
+ }
+}
+
+static void Save_STNS(void)
+{
+ Station *st;
+ // Write the stations
+ FOR_ALL_STATIONS(st) {
+ SlSetArrayIndex(st->index);
+ SlAutolength((AutolengthProc*)SaveLoad_STNS, st);
+ }
+}
+
+static void Load_STNS(void)
+{
+ int index;
+ while ((index = SlIterateArray()) != -1) {
+ Station *st;
+
+ if (!AddBlockIfNeeded(&_Station_pool, index))
+ error("Stations: failed loading savegame: too many stations");
+
+ st = GetStation(index);
+ SaveLoad_STNS(st);
+
+ // this means it's an oldstyle savegame without support for nonuniform stations
+ if (st->train_tile != 0 && st->trainst_h == 0) {
+ uint w = GB(st->trainst_w, 4, 4);
+ uint h = GB(st->trainst_w, 0, 4);
+
+ if (GetRailStationAxis(st->train_tile) == AXIS_Y) uintswap(w, h);
+ st->trainst_w = w;
+ st->trainst_h = h;
+ }
+
+ /* In older versions, we had just 1 tile for a bus/lorry, now we have more..
+ * convert, if needed */
+ if (CheckSavegameVersion(6)) {
+ if (st->bus_tile_obsolete != 0) {
+ st->bus_stops = AllocateRoadStop();
+ if (st->bus_stops == NULL)
+ error("Station: too many busstations in savegame");
+
+ InitializeRoadStop(st->bus_stops, NULL, st->bus_tile_obsolete, st->index);
+ }
+ if (st->lorry_tile_obsolete != 0) {
+ st->truck_stops = AllocateRoadStop();
+ if (st->truck_stops == NULL)
+ error("Station: too many truckstations in savegame");
+
+ InitializeRoadStop(st->truck_stops, NULL, st->lorry_tile_obsolete, st->index);
+ }
+ }
+ }
+
+ /* This is to ensure all pointers are within the limits of _stations_size */
+ if (_station_tick_ctr > GetMaxStationIndex()) _station_tick_ctr = 0;
+}
+
+static void Save_ROADSTOP(void)
+{
+ RoadStop *rs;
+
+ FOR_ALL_ROADSTOPS(rs) {
+ SlSetArrayIndex(rs->index);
+ SlObject(rs, _roadstop_desc);
+ }
+}
+
+static void Load_ROADSTOP(void)
+{
+ int index;
+ Vehicle *v;
+
+ while ((index = SlIterateArray()) != -1) {
+ RoadStop *rs;
+
+ if (!AddBlockIfNeeded(&_RoadStop_pool, index))
+ error("RoadStops: failed loading savegame: too many RoadStops");
+
+ rs = GetRoadStop(index);
+ SlObject(rs, _roadstop_desc);
+ }
+
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == VEH_Road && v->u.road.slot != NULL) v->u.road.slot->num_vehicles++;
+ }
+}
+
+const ChunkHandler _station_chunk_handlers[] = {
+ { 'STNS', Save_STNS, Load_STNS, CH_ARRAY },
+ { 'ROAD', Save_ROADSTOP, Load_ROADSTOP, CH_ARRAY | CH_LAST},
+};
+
+
+static inline bool PtInRectXY(Rect *r, int x, int y)
+{
+ return (r->left <= x && x <= r->right && r->top <= y && y <= r->bottom);
+}
+
+static void StationRect_Init(Station *st)
+{
+ Rect *r = &st->rect;
+ r->left = r->top = r->right = r->bottom = 0;
+}
+
+static bool StationRect_IsEmpty(Station *st)
+{
+ return (st->rect.left == 0 || st->rect.left > st->rect.right || st->rect.top > st->rect.bottom);
+}
+
+static bool StationRect_BeforeAddTile(Station *st, TileIndex tile, StationRectMode mode)
+{
+ Rect *r = &st->rect;
+ int x = TileX(tile);
+ int y = TileY(tile);
+ if (StationRect_IsEmpty(st)) {
+ // we are adding the first station tile
+ r->left = r->right = x;
+ r->top = r->bottom = y;
+ } else if (!PtInRectXY(r, x, y)) {
+ // current rect is not empty and new point is outside this rect
+ // make new spread-out rectangle
+ Rect new_rect = {min(x, r->left), min(y, r->top), max(x, r->right), max(y, r->bottom)};
+ // check new rect dimensions against preset max
+ int w = new_rect.right - new_rect.left + 1;
+ int h = new_rect.bottom - new_rect.top + 1;
+ if (mode != RECT_MODE_FORCE && (w > _patches.station_spread || h > _patches.station_spread)) {
+ assert(mode != RECT_MODE_TRY);
+ _error_message = STR_306C_STATION_TOO_SPREAD_OUT;
+ return false;
+ }
+ // spread-out ok, return true
+ if (mode != RECT_MODE_TEST) {
+ // we should update the station rect
+ *r = new_rect;
+ }
+ } else {
+ ; // new point is inside the rect, we don't need to do anything
+ }
+ return true;
+}
+
+static bool StationRect_BeforeAddRect(Station *st, TileIndex tile, int w, int h, StationRectMode mode)
+{
+ return StationRect_BeforeAddTile(st, tile, mode) && StationRect_BeforeAddTile(st, TILE_ADDXY(tile, w - 1, h - 1), mode);
+}
+
+static inline bool ScanRectForStationTiles(StationID st_id, int left, int top, int right, int bottom)
+{
+ TileIndex top_left = TileXY(left, top);
+ int width = right - left + 1;
+ int height = bottom - top + 1;
+ BEGIN_TILE_LOOP(tile, width, height, top_left)
+ if (IsTileType(tile, MP_STATION) && GetStationIndex(tile) == st_id) return true;
+ END_TILE_LOOP(tile, width, height, top_left);
+ return false;
+}
+
+static bool StationRect_AfterRemoveTile(Station *st, TileIndex tile)
+{
+ Rect *r = &st->rect;
+ int x = TileX(tile);
+ int y = TileY(tile);
+ bool reduce_x, reduce_y;
+
+ // look if removed tile was on the bounding rect edge
+ // and try to reduce the rect by this edge
+ // do it until we have empty rect or nothing to do
+ for (;;) {
+ // check if removed tile is on rect edge
+ bool left_edge = (x == r->left);
+ bool right_edge = (x == r->right);
+ bool top_edge = (y == r->top);
+ bool bottom_edge = (y == r->bottom);
+ // can we reduce the rect in either direction?
+ reduce_x = ((left_edge || right_edge) && !ScanRectForStationTiles(st->index, x, r->top, x, r->bottom));
+ reduce_y = ((top_edge || bottom_edge) && !ScanRectForStationTiles(st->index, r->left, y, r->right, y));
+ if (!(reduce_x || reduce_y)) break; // nothing to do (can't reduce)
+ if (reduce_x) {
+ // reduce horizontally
+ if (left_edge) {
+ // move left edge right
+ r->left = x = x + 1;
+ } else {
+ // move right edge left
+ r->right = x = x - 1;
+ }
+ }
+ if (reduce_y) {
+ // reduce vertically
+ if (top_edge) {
+ // move top edge down
+ r->top = y = y + 1;
+ } else {
+ // move bottom edge up
+ r->bottom = y = y - 1;
+ }
+ }
+ if (r->left > r->right || r->top > r->bottom) {
+ // can't continue, if the remaining rectangle is empty
+ StationRect_Init(st);
+ return true; // empty remaining rect
+ }
+ }
+ return false; // non-empty remaining rect
+}
+
+static bool StationRect_AfterRemoveRect(Station *st, TileIndex tile, int w, int h)
+{
+ bool empty;
+ assert(PtInRectXY(&st->rect, TileX(tile), TileY(tile)));
+ assert(PtInRectXY(&st->rect, TileX(tile) + w - 1, TileY(tile) + h - 1));
+ empty = StationRect_AfterRemoveTile(st, tile);
+ if (w != 1 || h != 1) empty = empty || StationRect_AfterRemoveTile(st, TILE_ADDXY(tile, w - 1, h - 1));
+ return empty;
+}
diff --git a/src/station_gui.c b/src/station_gui.c
new file mode 100644
index 000000000..55428a793
--- /dev/null
+++ b/src/station_gui.c
@@ -0,0 +1,825 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "debug.h"
+#include "functions.h"
+#include "strings.h"
+#include "table/strings.h"
+#include "window.h"
+#include "gui.h"
+#include "station.h"
+#include "gfx.h"
+#include "player.h"
+#include "economy.h"
+#include "town.h"
+#include "command.h"
+#include "variables.h"
+#include "vehicle_gui.h"
+#include "date.h"
+#include "vehicle.h"
+
+enum StationListWidgets {
+ STATIONLIST_WIDGET_CLOSEBOX = 0,
+ STATIONLIST_WIDGET_LIST = 3,
+ STATIONLIST_WIDGET_TRAIN =6,
+ STATIONLIST_WIDGET_TRUCK,
+ STATIONLIST_WIDGET_BUS,
+ STATIONLIST_WIDGET_AIRPLANE,
+ STATIONLIST_WIDGET_SHIP,
+ STATIONLIST_WIDGET_CARGOSTART = 12,
+ STATIONLIST_WIDGET_NOCARGOWAITING = 24,
+ STATIONLIST_WIDGET_FACILALL = 26,
+ STATIONLIST_WIDGET_CARGOALL,
+ STATIONLIST_WIDGET_SORTBY,
+ STATIONLIST_WIDGET_SORTCRITERIA,
+ STATIONLIST_WIDGET_SORTDROPBTN,
+ CARGO_ALL_SELECTED = 0x1FFF,
+};
+
+typedef int CDECL StationSortListingTypeFunction(const void*, const void*);
+
+static StationSortListingTypeFunction StationNameSorter;
+static StationSortListingTypeFunction StationTypeSorter;
+static StationSortListingTypeFunction StationWaitingSorter;
+static StationSortListingTypeFunction StationRatingMaxSorter;
+
+/** Draw small boxes of cargo amount and ratings data at the given
+ * coordinates. If amount exceeds 576 units, it is shown 'full', same
+ * goes for the rating: at above 90% orso (224) it is also 'full'
+ * Each cargo-bar is 16 pixels wide and 6 pixels high
+ * Each rating 14 pixels wide and 1 pixel high and is 1 pixel below the cargo-bar
+ * @param x,y X/Y coordinate to draw the box at
+ * @param type Cargo type
+ * @param amount Cargo amount
+ * @param rating ratings data for that particular cargo */
+static void StationsWndShowStationRating(int x, int y, CargoID type, uint amount, byte rating)
+{
+ int colour = _cargo_colours[type];
+ uint w = (minu(amount, 576) + 5) / 36;
+
+ /* Draw total cargo (limited) on station (fits into 16 pixels) */
+ if (w != 0) GfxFillRect(x, y, x + w - 1, y + 6, colour);
+
+ /* Draw a one pixel-wide bar of additional cargo meter, useful
+ * for stations with only a small amount (<=30) */
+ if (w == 0) {
+ uint rest = amount / 5;
+ if (rest != 0) {
+ w += x;
+ GfxFillRect(w, y + 6 - rest, w, y + 6, colour);
+ }
+ }
+
+ DrawString(x + 1, y, _cargoc.names_short[type], 0x10);
+
+ /* Draw green/red ratings bar (fits into 14 pixels) */
+ y += 8;
+ GfxFillRect(x + 1, y, x + 14, y, 0xB8);
+ rating = minu(rating, 224) / 16;
+ if (rating != 0) GfxFillRect(x + 1, y, x + rating, y, 0xD0);
+}
+
+const StringID _station_sort_listing[] = {
+ STR_SORT_BY_DROPDOWN_NAME,
+ STR_SORT_BY_FACILITY,
+ STR_SORT_BY_WAITING,
+ STR_SORT_BY_RATING_MAX,
+ INVALID_STRING_ID
+};
+
+static char _bufcache[64];
+static const Station* _last_station;
+static int _internal_sort_order;
+
+static int CDECL StationNameSorter(const void *a, const void *b)
+{
+ const Station* st1 = *(const Station**)a;
+ const Station* st2 = *(const Station**)b;
+ char buf1[64];
+ int r;
+
+ SetDParam(0, st1->index);
+ GetString(buf1, STR_STATION, lastof(buf1));
+
+ if (st2 != _last_station) {
+ _last_station = st2;
+ SetDParam(0, st2->index);
+ GetString(_bufcache, STR_STATION, lastof(_bufcache));
+ }
+
+ r = strcmp(buf1, _bufcache); // sort by name
+ return (_internal_sort_order & 1) ? -r : r;
+}
+
+static int CDECL StationTypeSorter(const void *a, const void *b)
+{
+ const Station* st1 = *(const Station**)a;
+ const Station* st2 = *(const Station**)b;
+ return (_internal_sort_order & 1) ? st2->facilities - st1->facilities : st1->facilities - st2->facilities;
+}
+
+static int CDECL StationWaitingSorter(const void *a, const void *b)
+{
+ const Station* st1 = *(const Station**)a;
+ const Station* st2 = *(const Station**)b;
+ int sum1 = 0, sum2 = 0;
+ int j;
+
+ for (j = 0; j < NUM_CARGO; j++) {
+ if (st1->goods[j].waiting_acceptance & 0xfff) sum1 += GetTransportedGoodsIncome(st1->goods[j].waiting_acceptance & 0xfff, 20, 50, j);
+ if (st2->goods[j].waiting_acceptance & 0xfff) sum2 += GetTransportedGoodsIncome(st2->goods[j].waiting_acceptance & 0xfff, 20, 50, j);
+ }
+
+ return (_internal_sort_order & 1) ? sum2 - sum1 : sum1 - sum2;
+}
+
+static int CDECL StationRatingMaxSorter(const void *a, const void *b)
+{
+ const Station* st1 = *(const Station**)a;
+ const Station* st2 = *(const Station**)b;
+ byte maxr1 = 0;
+ byte maxr2 = 0;
+ int j;
+
+ for (j = 0; j < NUM_CARGO; j++) {
+ if (st1->goods[j].waiting_acceptance & 0xfff) maxr1 = max(maxr1, st1->goods[j].rating);
+ if (st2->goods[j].waiting_acceptance & 0xfff) maxr2 = max(maxr2, st2->goods[j].rating);
+ }
+
+ return (_internal_sort_order & 1) ? maxr2 - maxr1 : maxr1 - maxr2;
+}
+
+typedef enum StationListFlags {
+ SL_ORDER = 0x01,
+ SL_RESORT = 0x02,
+ SL_REBUILD = 0x04,
+} StationListFlags;
+
+typedef struct plstations_d {
+ const Station** sort_list;
+ uint16 list_length;
+ byte sort_type;
+ StationListFlags flags;
+ uint16 resort_timer; //was byte refresh_counter;
+} plstations_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(plstations_d));
+
+void RebuildStationLists(void)
+{
+ Window* const *wz;
+
+ FOR_ALL_WINDOWS(wz) {
+ Window *w = *wz;
+ if (w->window_class == WC_STATION_LIST) {
+ WP(w, plstations_d).flags |= SL_REBUILD;
+ SetWindowDirty(w);
+ }
+ }
+}
+
+void ResortStationLists(void)
+{
+ Window* const *wz;
+
+ FOR_ALL_WINDOWS(wz) {
+ Window *w = *wz;
+ if (w->window_class == WC_STATION_LIST) {
+ WP(w, plstations_d).flags |= SL_RESORT;
+ SetWindowDirty(w);
+ }
+ }
+}
+
+static void BuildStationsList(plstations_d* sl, PlayerID owner, byte facilities, uint16 cargo_filter)
+{
+ uint n = 0;
+ uint i, j;
+ const Station** station_sort;
+ const Station *st;
+
+ if (!(sl->flags & SL_REBUILD)) return;
+
+ /* Create array for sorting */
+ station_sort = malloc((GetMaxStationIndex() + 1) * sizeof(station_sort[0]));
+ if (station_sort == NULL) error("Could not allocate memory for the station-sorting-list");
+
+ DEBUG(misc, 3, "Building station list for player %d", owner);
+
+ FOR_ALL_STATIONS(st) {
+ if (st->owner == owner) {
+ if (facilities & st->facilities) { //only stations with selected facilities
+ int num_waiting_cargo = 0;
+ for (j = 0; j < NUM_CARGO; j++) {
+ if (st->goods[j].waiting_acceptance & 0xFFF) {
+ num_waiting_cargo++; //count number of waiting cargo
+ if (HASBIT(cargo_filter, j)) {
+ station_sort[n++] = st;
+ break;
+ }
+ }
+ }
+ //stations without waiting cargo
+ if (num_waiting_cargo == 0 && HASBIT(cargo_filter, NUM_CARGO)) {
+ station_sort[n++] = st;
+ }
+ }
+ }
+ }
+
+ free((void*)sl->sort_list);
+ sl->sort_list = malloc(n * sizeof(sl->sort_list[0]));
+ if (n != 0 && sl->sort_list == NULL) error("Could not allocate memory for the station-sorting-list");
+ sl->list_length = n;
+
+ for (i = 0; i < n; ++i) sl->sort_list[i] = station_sort[i];
+
+ sl->flags &= ~SL_REBUILD;
+ sl->flags |= SL_RESORT;
+ free((void*)station_sort);
+}
+
+static void SortStationsList(plstations_d *sl)
+{
+ static StationSortListingTypeFunction* const _station_sorter[] = {
+ &StationNameSorter,
+ &StationTypeSorter,
+ &StationWaitingSorter,
+ &StationRatingMaxSorter
+ };
+
+ if (!(sl->flags & SL_RESORT)) return;
+
+ _internal_sort_order = sl->flags & SL_ORDER;
+ _last_station = NULL; // used for "cache" in namesorting
+ qsort((void*)sl->sort_list, sl->list_length, sizeof(sl->sort_list[0]), _station_sorter[sl->sort_type]);
+
+ sl->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
+ sl->flags &= ~SL_RESORT;
+}
+
+static void PlayerStationsWndProc(Window *w, WindowEvent *e)
+{
+ const PlayerID owner = w->window_number;
+ static byte facilities = FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK;
+ static uint16 cargo_filter = CARGO_ALL_SELECTED;
+ plstations_d *sl = &WP(w, plstations_d);
+
+ switch (e->event) {
+ case WE_CREATE: { /* set up resort timer */
+ int i;
+ for (i = 0; i < 5; i++) {
+ if (HASBIT(facilities, i)) LowerWindowWidget(w, i + STATIONLIST_WIDGET_TRAIN);
+ }
+ for (i = 0; i < NUM_CARGO; i++) {
+ if (HASBIT(cargo_filter, i)) LowerWindowWidget(w, i + STATIONLIST_WIDGET_CARGOSTART);
+ }
+ SetWindowWidgetLoweredState(w, STATIONLIST_WIDGET_FACILALL, facilities == (FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK));
+ SetWindowWidgetLoweredState(w, STATIONLIST_WIDGET_CARGOALL, cargo_filter == CARGO_ALL_SELECTED);
+ SetWindowWidgetLoweredState(w, STATIONLIST_WIDGET_NOCARGOWAITING, HASBIT(cargo_filter, STATIONLIST_WIDGET_NOCARGOWAITING - NUM_CARGO));
+
+ sl->sort_list = NULL;
+ sl->flags = SL_REBUILD;
+ sl->sort_type = 0;
+ sl->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
+ break;
+ }
+
+ case WE_PAINT: {
+ BuildStationsList(sl, owner, facilities, cargo_filter);
+ SortStationsList(sl);
+
+ SetVScrollCount(w, sl->list_length);
+
+ /* draw widgets, with player's name in the caption */
+ {
+ const Player* p = GetPlayer(owner);
+ SetDParam(0, p->name_1);
+ SetDParam(1, p->name_2);
+ SetDParam(2, w->vscroll.count);
+ DrawWindowWidgets(w);
+ }
+
+ {
+ int max;
+ int i, cg_ofst;
+ int x = 0, y = 0, xb = 2; // offset from top of widget
+
+ /* draw sorting criteria string */
+ DrawString(85, 26, _station_sort_listing[sl->sort_type], 0x10);
+ /* draw arrow pointing up/down for ascending/descending sorting */
+ DoDrawString(sl->flags & SL_ORDER ? DOWNARROW : UPARROW, 69, 26, 0x10);
+
+
+ x = 89;
+ y = 14;
+
+ for (i = 0; i < NUM_CARGO; i++) {
+ cg_ofst = IsWindowWidgetLowered(w, i + STATIONLIST_WIDGET_CARGOSTART) ? 2 : 1;
+
+ GfxFillRect(x + cg_ofst, y + cg_ofst, x + cg_ofst + 10 , y + cg_ofst + 7, _cargo_colours[i]);
+ DrawStringCentered(x + 6 + cg_ofst, y + cg_ofst, _cargoc.names_short[i], 0x10);
+ x += 14;
+ }
+
+ x += 6;
+ cg_ofst = IsWindowWidgetLowered(w, STATIONLIST_WIDGET_NOCARGOWAITING) ? 2 : 1;
+ DrawStringCentered(x + cg_ofst, y + cg_ofst, STR_ABBREV_NONE, 16);
+ x += 14;
+ cg_ofst = IsWindowWidgetLowered(w, STATIONLIST_WIDGET_CARGOALL) ? 2 : 1;
+ DrawStringCentered(x + cg_ofst, y + cg_ofst, STR_ABBREV_ALL, 16);
+
+ cg_ofst = IsWindowWidgetLowered(w, STATIONLIST_WIDGET_FACILALL) ? 2 : 1;
+ DrawString(71 + cg_ofst, y + cg_ofst, STR_ABBREV_ALL, 16);
+
+ if (w->vscroll.count == 0) { // player has no stations
+ DrawString(xb, 40, STR_304A_NONE, 0);
+ return;
+ }
+
+ max = min(w->vscroll.pos + w->vscroll.cap, sl->list_length);
+ y = 40; // start of the list-widget
+
+ for (i = w->vscroll.pos; i < max; ++i) { // do until max number of stations of owner
+ const Station *st = sl->sort_list[i];
+ CargoID j;
+ int x;
+
+ assert(st->xy != 0);
+ assert(st->owner == owner);
+
+ SetDParam(0, st->index);
+ SetDParam(1, st->facilities);
+ x = DrawString(xb, y, STR_3049_0, 0) + 5;
+
+ // show cargo waiting and station ratings
+ for (j = 0; j != NUM_CARGO; j++) {
+ uint amount = GB(st->goods[j].waiting_acceptance, 0, 12);
+
+ if (amount != 0) {
+ StationsWndShowStationRating(x, y, j, amount, st->goods[j].rating);
+ x += 20;
+ }
+ }
+ y += 10;
+ }
+ }
+ } break;
+
+ case WE_CLICK: {
+ switch (e->we.click.widget) {
+ case STATIONLIST_WIDGET_LIST: {
+ const Station* st;
+
+ uint32 id_v = (e->we.click.pt.y - 41) / 10;
+
+ if (id_v >= w->vscroll.cap) return; // click out of bounds
+
+ id_v += w->vscroll.pos;
+
+ if (id_v >= sl->list_length) return; // click out of list bound
+
+ st = sl->sort_list[id_v];
+ assert(st->owner == owner);
+ ScrollMainWindowToTile(st->xy);
+ break;
+ }
+
+ case STATIONLIST_WIDGET_TRAIN:
+ case STATIONLIST_WIDGET_TRUCK:
+ case STATIONLIST_WIDGET_BUS:
+ case STATIONLIST_WIDGET_AIRPLANE:
+ case STATIONLIST_WIDGET_SHIP:
+ if (_ctrl_pressed) {
+ TOGGLEBIT(facilities, e->we.click.widget - STATIONLIST_WIDGET_TRAIN);
+ ToggleWidgetLoweredState(w, e->we.click.widget);
+ } else {
+ int i;
+ for (i = 0; facilities != 0; i++, facilities >>= 1) {
+ if (HASBIT(facilities, 0)) RaiseWindowWidget(w, i + STATIONLIST_WIDGET_TRAIN);
+ }
+ SETBIT(facilities, e->we.click.widget - STATIONLIST_WIDGET_TRAIN);
+ LowerWindowWidget(w, e->we.click.widget);
+ }
+ SetWindowWidgetLoweredState(w, STATIONLIST_WIDGET_FACILALL, facilities == (FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK));
+ sl->flags |= SL_REBUILD;
+ SetWindowDirty(w);
+ break;
+
+ case STATIONLIST_WIDGET_FACILALL: {
+ int i;
+ for (i = 0; i < 5; i++) {
+ LowerWindowWidget(w, i + STATIONLIST_WIDGET_TRAIN);
+ }
+ LowerWindowWidget(w, STATIONLIST_WIDGET_FACILALL);
+
+ facilities = FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK;
+ sl->flags |= SL_REBUILD;
+ SetWindowDirty(w);
+ break;
+ }
+ case STATIONLIST_WIDGET_CARGOALL: {
+ int i;
+ for (i = 0; i < NUM_CARGO; i++) {
+ LowerWindowWidget(w, i + STATIONLIST_WIDGET_CARGOSTART);
+ }
+ LowerWindowWidget(w, STATIONLIST_WIDGET_NOCARGOWAITING);
+ LowerWindowWidget(w, STATIONLIST_WIDGET_CARGOALL);
+
+ cargo_filter = CARGO_ALL_SELECTED;
+ sl->flags |= SL_REBUILD;
+ SetWindowDirty(w);
+ break;
+ }
+ case STATIONLIST_WIDGET_SORTBY: /*flip sorting method asc/desc*/
+ TOGGLEBIT(sl->flags, 0); //DESC-flag
+ sl->flags |= SL_RESORT;
+ w->flags4 |= 5 << WF_TIMEOUT_SHL;
+ LowerWindowWidget(w, STATIONLIST_WIDGET_SORTBY);
+ SetWindowDirty(w);
+ break;
+
+ case STATIONLIST_WIDGET_SORTCRITERIA:
+ case STATIONLIST_WIDGET_SORTDROPBTN: /* select sorting criteria dropdown menu */
+ ShowDropDownMenu(w, _station_sort_listing, sl->sort_type, STATIONLIST_WIDGET_SORTDROPBTN, 0, 0);
+ break;
+
+ default:
+ if (e->we.click.widget >= STATIONLIST_WIDGET_CARGOSTART && e->we.click.widget <= STATIONLIST_WIDGET_NOCARGOWAITING) { //change cargo_filter
+ if (_ctrl_pressed) {
+ TOGGLEBIT(cargo_filter, e->we.click.widget - STATIONLIST_WIDGET_CARGOSTART);
+ ToggleWidgetLoweredState(w, e->we.click.widget);
+ } else {
+ int i;
+ for (i = 0; cargo_filter != 0; i++, cargo_filter >>= 1) {
+ if (HASBIT(cargo_filter, 0)) RaiseWindowWidget(w, i + STATIONLIST_WIDGET_CARGOSTART);
+ }
+ SETBIT(cargo_filter, e->we.click.widget - STATIONLIST_WIDGET_CARGOSTART);
+ LowerWindowWidget(w, e->we.click.widget);
+ }
+ sl->flags |= SL_REBUILD;
+ SetWindowWidgetLoweredState(w, STATIONLIST_WIDGET_CARGOALL, cargo_filter == CARGO_ALL_SELECTED);
+ SetWindowDirty(w);
+ }
+ }
+ } break;
+
+ case WE_DROPDOWN_SELECT: /* we have selected a dropdown item in the list */
+ if (sl->sort_type != e->we.dropdown.index) {
+ // value has changed -> resort
+ sl->sort_type = e->we.dropdown.index;
+ sl->flags |= SL_RESORT;
+ }
+ SetWindowDirty(w);
+ break;
+
+ case WE_TICK:
+ if (--sl->resort_timer == 0) {
+ DEBUG(misc, 3, "Periodic rebuild station list player %d", owner);
+ sl->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
+ sl->flags |= VL_REBUILD;
+ SetWindowDirty(w);
+ }
+ break;
+
+ case WE_TIMEOUT:
+ RaiseWindowWidget(w, STATIONLIST_WIDGET_SORTBY);
+ SetWindowDirty(w);
+ break;
+
+ case WE_RESIZE:
+ w->vscroll.cap += e->we.sizing.diff.y / 10;
+ break;
+ }
+}
+
+static const Widget _player_stations_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_RIGHT, 14, 11, 345, 0, 13, STR_3048_STATIONS, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_STICKYBOX, RESIZE_LR, 14, 346, 357, 0, 13, 0x0, STR_STICKY_BUTTON},
+{ WWT_PANEL, RESIZE_RB, 14, 0, 345, 37, 161, 0x0, STR_3057_STATION_NAMES_CLICK_ON},
+{ WWT_SCROLLBAR, RESIZE_LRB, 14, 346, 357, 37, 149, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WWT_RESIZEBOX, RESIZE_LRTB, 14, 346, 357, 150, 161, 0x0, STR_RESIZE_BUTTON},
+//Index 6
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 0, 13, 14, 24, STR_TRAIN, STR_USE_CTRL_TO_SELECT_MORE},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 14, 27, 14, 24, STR_LORRY, STR_USE_CTRL_TO_SELECT_MORE},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 28, 41, 14, 24, STR_BUS, STR_USE_CTRL_TO_SELECT_MORE},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 42, 55, 14, 24, STR_PLANE, STR_USE_CTRL_TO_SELECT_MORE},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 56, 69, 14, 24, STR_SHIP, STR_USE_CTRL_TO_SELECT_MORE},
+//Index 11
+{ WWT_PANEL, RESIZE_NONE, 14, 83, 88, 14, 24, 0x0, STR_USE_CTRL_TO_SELECT_MORE},
+{ WWT_PANEL, RESIZE_NONE, 14, 89, 102, 14, 24, 0x0, STR_USE_CTRL_TO_SELECT_MORE},
+{ WWT_PANEL, RESIZE_NONE, 14, 103, 116, 14, 24, 0x0, STR_USE_CTRL_TO_SELECT_MORE},
+{ WWT_PANEL, RESIZE_NONE, 14, 117, 130, 14, 24, 0x0, STR_USE_CTRL_TO_SELECT_MORE},
+{ WWT_PANEL, RESIZE_NONE, 14, 131, 144, 14, 24, 0x0, STR_USE_CTRL_TO_SELECT_MORE},
+{ WWT_PANEL, RESIZE_NONE, 14, 145, 158, 14, 24, 0x0, STR_USE_CTRL_TO_SELECT_MORE},
+{ WWT_PANEL, RESIZE_NONE, 14, 159, 172, 14, 24, 0x0, STR_USE_CTRL_TO_SELECT_MORE},
+{ WWT_PANEL, RESIZE_NONE, 14, 173, 186, 14, 24, 0x0, STR_USE_CTRL_TO_SELECT_MORE},
+{ WWT_PANEL, RESIZE_NONE, 14, 187, 200, 14, 24, 0x0, STR_USE_CTRL_TO_SELECT_MORE},
+{ WWT_PANEL, RESIZE_NONE, 14, 201, 214, 14, 24, 0x0, STR_USE_CTRL_TO_SELECT_MORE},
+{ WWT_PANEL, RESIZE_NONE, 14, 215, 228, 14, 24, 0x0, STR_USE_CTRL_TO_SELECT_MORE},
+{ WWT_PANEL, RESIZE_NONE, 14, 229, 242, 14, 24, 0x0, STR_USE_CTRL_TO_SELECT_MORE},
+{ WWT_PANEL, RESIZE_NONE, 14, 243, 256, 14, 24, 0x0, STR_USE_CTRL_TO_SELECT_MORE},
+{ WWT_PANEL, RESIZE_NONE, 14, 257, 270, 14, 24, 0x0, STR_NO_WAITING_CARGO},
+{ WWT_PANEL, RESIZE_RIGHT, 14, 285, 357, 14, 24, 0x0, STR_NULL},
+
+//26
+{ WWT_PANEL, RESIZE_NONE, 14, 70, 83, 14, 24, 0x0, STR_SELECT_ALL_FACILITIES},
+{ WWT_PANEL, RESIZE_NONE, 14, 271, 284, 14, 24, 0x0, STR_SELECT_ALL_TYPES},
+
+//28
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 0, 80, 25, 36, STR_SORT_BY, STR_SORT_ORDER_TIP},
+{ WWT_PANEL, RESIZE_NONE, 14, 81, 232, 25, 36, 0x0, STR_SORT_CRITERIA_TIP},
+{ WWT_TEXTBTN, RESIZE_NONE, 14, 233, 243, 25, 36, STR_0225, STR_SORT_CRITERIA_TIP},
+{ WWT_PANEL, RESIZE_RIGHT, 14, 244, 357, 25, 36, 0x0, STR_NULL},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _player_stations_desc = {
+ WDP_AUTO, WDP_AUTO, 358, 162,
+ WC_STATION_LIST,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON | WDF_RESIZABLE,
+ _player_stations_widgets,
+ PlayerStationsWndProc
+};
+
+
+void ShowPlayerStations(PlayerID player)
+{
+ Window *w;
+
+ if (!IsValidPlayer(player)) return;
+
+ w = AllocateWindowDescFront(&_player_stations_desc, player);
+ if (w != NULL) {
+ w->caption_color = (byte)w->window_number;
+ w->vscroll.cap = 12;
+ w->resize.step_height = 10;
+ w->resize.height = w->height - 10 * 7; // minimum if 5 in the list
+ }
+}
+
+static const Widget _station_view_expanded_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 236, 0, 13, STR_300A_0, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_STICKYBOX, RESIZE_NONE, 14, 237, 248, 0, 13, 0x0, STR_STICKY_BUTTON},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 236, 14, 65, 0x0, STR_NULL},
+{ WWT_SCROLLBAR, RESIZE_NONE, 14, 237, 248, 14, 65, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WWT_EMPTY, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 248, 66, 197, 0x0, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 0, 63, 198, 209, STR_00E4_LOCATION, STR_3053_CENTER_MAIN_VIEW_ON_STATION},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 64, 128, 198, 209, STR_3033_ACCEPTS, STR_3056_SHOW_LIST_OF_ACCEPTED_CARGO},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 129, 192, 198, 209, STR_0130_RENAME, STR_3055_CHANGE_NAME_OF_STATION},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 193, 206, 198, 209, STR_TRAIN, STR_SCHEDULED_TRAINS_TIP },
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 207, 220, 198, 209, STR_LORRY, STR_SCHEDULED_ROAD_VEHICLES_TIP },
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 221, 234, 198, 209, STR_PLANE, STR_SCHEDULED_AIRCRAFT_TIP },
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 235, 248, 198, 209, STR_SHIP, STR_SCHEDULED_SHIPS_TIP },
+{ WIDGETS_END},
+};
+
+static const Widget _station_view_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 236, 0, 13, STR_300A_0, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_STICKYBOX, RESIZE_NONE, 14, 237, 248, 0, 13, 0x0, STR_STICKY_BUTTON},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 236, 14, 65, 0x0, STR_NULL},
+{ WWT_SCROLLBAR, RESIZE_NONE, 14, 237, 248, 14, 65, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 248, 66, 97, 0x0, STR_NULL},
+{ WWT_EMPTY, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 0, 63, 98, 109, STR_00E4_LOCATION, STR_3053_CENTER_MAIN_VIEW_ON_STATION},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 64, 128, 98, 109, STR_3032_RATINGS, STR_3054_SHOW_STATION_RATINGS},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 129, 192, 98, 109, STR_0130_RENAME, STR_3055_CHANGE_NAME_OF_STATION},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 193, 206, 98, 109, STR_TRAIN, STR_SCHEDULED_TRAINS_TIP },
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 207, 220, 98, 109, STR_LORRY, STR_SCHEDULED_ROAD_VEHICLES_TIP },
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 221, 234, 98, 109, STR_PLANE, STR_SCHEDULED_AIRCRAFT_TIP },
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 235, 248, 98, 109, STR_SHIP, STR_SCHEDULED_SHIPS_TIP },
+{ WIDGETS_END},
+};
+
+static void DrawStationViewWindow(Window *w)
+{
+ StationID station_id = w->window_number;
+ const Station* st = GetStation(station_id);
+ uint i;
+ uint num;
+ int x,y;
+ int pos;
+ StringID str;
+
+ num = 1;
+ for (i = 0; i != NUM_CARGO; i++) {
+ if (GB(st->goods[i].waiting_acceptance, 0, 12) != 0) {
+ num++;
+ if (st->goods[i].enroute_from != station_id) num++;
+ }
+ }
+ SetVScrollCount(w, num);
+
+ SetWindowWidgetDisabledState(w, 9, st->owner != _local_player);
+ SetWindowWidgetDisabledState(w, 10, !(st->facilities & FACIL_TRAIN));
+ SetWindowWidgetDisabledState(w, 11, !(st->facilities & FACIL_TRUCK_STOP) && !(st->facilities & FACIL_BUS_STOP));
+ SetWindowWidgetDisabledState(w, 12, !(st->facilities & FACIL_AIRPORT));
+ SetWindowWidgetDisabledState(w, 13, !(st->facilities & FACIL_DOCK));
+
+ SetDParam(0, st->index);
+ SetDParam(1, st->facilities);
+ DrawWindowWidgets(w);
+
+ x = 2;
+ y = 15;
+ pos = w->vscroll.pos;
+
+ if (--pos < 0) {
+ str = STR_00D0_NOTHING;
+ for (i = 0; i != NUM_CARGO; i++) {
+ if (GB(st->goods[i].waiting_acceptance, 0, 12) != 0) str = STR_EMPTY;
+ }
+ SetDParam(0, str);
+ DrawString(x, y, STR_0008_WAITING, 0);
+ y += 10;
+ }
+
+ i = 0;
+ do {
+ uint waiting = GB(st->goods[i].waiting_acceptance, 0, 12);
+ if (waiting == 0) continue;
+
+ num = (waiting + 5) / 10;
+ if (num != 0) {
+ int cur_x = x;
+ num = min(num, 23);
+ do {
+ DrawSprite(_cargoc.sprites[i], cur_x, y);
+ cur_x += 10;
+ } while (--num);
+ }
+
+ if ( st->goods[i].enroute_from == station_id) {
+ if (--pos < 0) {
+ SetDParam(1, waiting);
+ SetDParam(0, i);
+ DrawStringRightAligned(x + 234, y, STR_0009, 0);
+ y += 10;
+ }
+ } else {
+ /* enroute */
+ if (--pos < 0) {
+ SetDParam(1, waiting);
+ SetDParam(0, i);
+ DrawStringRightAligned(x + 234, y, STR_000A_EN_ROUTE_FROM, 0);
+ y += 10;
+ }
+
+ if (pos > -5 && --pos < 0) {
+ SetDParam(0, st->goods[i].enroute_from);
+ DrawStringRightAligned(x + 234, y, STR_000B, 0);
+ y += 10;
+ }
+ }
+ } while (pos > -5 && ++i != NUM_CARGO);
+
+ if (IsWindowOfPrototype(w, _station_view_widgets)) {
+ char *b = _userstring;
+ bool first = true;
+
+ b = InlineString(b, STR_000C_ACCEPTS);
+
+ for (i = 0; i != NUM_CARGO; i++) {
+ if (b >= endof(_userstring) - 5 - 1) break;
+ if (st->goods[i].waiting_acceptance & 0x8000) {
+ if (first) {
+ first = false;
+ } else {
+ /* Add a comma if this is not the first item */
+ *b++ = ',';
+ *b++ = ' ';
+ }
+ b = InlineString(b, _cargoc.names_s[i]);
+ }
+ }
+
+ /* If first is still true then no cargo is accepted */
+ if (first) b = InlineString(b, STR_00D0_NOTHING);
+
+ *b = '\0';
+ DrawStringMultiLine(2, 67, STR_SPEC_USERSTRING, 245);
+ } else {
+ DrawString(2, 67, STR_3034_LOCAL_RATING_OF_TRANSPORT, 0);
+
+ y = 77;
+ for (i = 0; i != NUM_CARGO; i++) {
+ if (st->goods[i].enroute_from != INVALID_STATION) {
+ SetDParam(0, _cargoc.names_s[i]);
+ SetDParam(2, st->goods[i].rating * 101 >> 8);
+ SetDParam(1, STR_3035_APPALLING + (st->goods[i].rating >> 5));
+ DrawString(8, y, STR_303D, 0);
+ y += 10;
+ }
+ }
+ }
+}
+
+
+static void StationViewWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT:
+ DrawStationViewWindow(w);
+ break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 7:
+ ScrollMainWindowToTile(GetStation(w->window_number)->xy);
+ break;
+
+ case 8:
+ SetWindowDirty(w);
+
+ /* toggle height/widget set */
+ if (IsWindowOfPrototype(w, _station_view_expanded_widgets)) {
+ AssignWidgetToWindow(w, _station_view_widgets);
+ w->height = 110;
+ } else {
+ AssignWidgetToWindow(w, _station_view_expanded_widgets);
+ w->height = 210;
+ }
+
+ SetWindowDirty(w);
+ break;
+
+ case 9: {
+ SetDParam(0, w->window_number);
+ ShowQueryString(STR_STATION, STR_3030_RENAME_STATION_LOADING, 31, 180, w, CS_ALPHANUMERAL);
+ } break;
+
+ case 10: { /* Show a list of scheduled trains to this station */
+ const Station *st = GetStation(w->window_number);
+ ShowVehicleListWindow(st->owner, w->window_number, VEH_Train);
+ break;
+ }
+
+ case 11: { /* Show a list of scheduled road-vehicles to this station */
+ const Station *st = GetStation(w->window_number);
+ ShowVehicleListWindow(st->owner, w->window_number, VEH_Road);
+ break;
+ }
+
+ case 12: { /* Show a list of scheduled aircraft to this station */
+ const Station *st = GetStation(w->window_number);
+ /* Since oilrigs have no owners, show the scheduled aircraft of current player */
+ PlayerID owner = (st->owner == OWNER_NONE) ? _current_player : st->owner;
+ ShowVehicleListWindow(owner, w->window_number, VEH_Aircraft);
+ break;
+ }
+
+ case 13: { /* Show a list of scheduled ships to this station */
+ const Station *st = GetStation(w->window_number);
+ /* Since oilrigs/bouys have no owners, show the scheduled ships of current player */
+ PlayerID owner = (st->owner == OWNER_NONE) ? _current_player : st->owner;
+ ShowVehicleListWindow(owner, w->window_number, VEH_Ship);
+ break;
+ }
+ }
+ break;
+
+ case WE_ON_EDIT_TEXT:
+ if (e->we.edittext.str[0] != '\0') {
+ _cmd_text = e->we.edittext.str;
+ DoCommandP(0, w->window_number, 0, NULL,
+ CMD_RENAME_STATION | CMD_MSG(STR_3031_CAN_T_RENAME_STATION));
+ }
+ break;
+
+ case WE_DESTROY: {
+ WindowNumber wno =
+ (w->window_number << 16) | GetStation(w->window_number)->owner;
+
+ DeleteWindowById(WC_TRAINS_LIST, wno);
+ DeleteWindowById(WC_ROADVEH_LIST, wno);
+ DeleteWindowById(WC_SHIPS_LIST, wno);
+ DeleteWindowById(WC_AIRCRAFT_LIST, wno);
+ break;
+ }
+ }
+}
+
+
+static const WindowDesc _station_view_desc = {
+ WDP_AUTO, WDP_AUTO, 249, 110,
+ WC_STATION_VIEW,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON,
+ _station_view_widgets,
+ StationViewWndProc
+};
+
+void ShowStationViewWindow(StationID station)
+{
+ Window *w;
+
+ w = AllocateWindowDescFront(&_station_view_desc, station);
+ if (w != NULL) {
+ PlayerID owner = GetStation(w->window_number)->owner;
+ if (owner != OWNER_NONE) w->caption_color = owner;
+ w->vscroll.cap = 5;
+ }
+}
diff --git a/src/station_map.c b/src/station_map.c
new file mode 100644
index 000000000..6341cd6ba
--- /dev/null
+++ b/src/station_map.c
@@ -0,0 +1,19 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "station_map.h"
+
+
+StationType GetStationType(TileIndex t)
+{
+ assert(IsTileType(t, MP_STATION));
+ if (IsRailwayStation(t)) return STATION_RAIL;
+ if (IsAirport(t)) return STATION_AIRPORT;
+ if (IsTruckStop(t)) return STATION_TRUCK;
+ if (IsBusStop(t)) return STATION_BUS;
+ if (IsOilRig(t)) return STATION_OILRIG;
+ if (IsDock(t)) return STATION_DOCK;
+ assert(IsBuoy_(t));
+ return STATION_BUOY;
+}
diff --git a/src/station_map.h b/src/station_map.h
new file mode 100644
index 000000000..c52769b14
--- /dev/null
+++ b/src/station_map.h
@@ -0,0 +1,304 @@
+/* $Id$ */
+
+#ifndef STATION_MAP_H
+#define STATION_MAP_H
+
+#include "rail_map.h"
+#include "station.h"
+
+typedef byte StationGfx;
+
+static inline StationID GetStationIndex(TileIndex t)
+{
+ assert(IsTileType(t, MP_STATION));
+ return (StationID)_m[t].m2;
+}
+
+static inline Station* GetStationByTile(TileIndex t)
+{
+ return GetStation(GetStationIndex(t));
+}
+
+
+enum {
+ GFX_RAILWAY_BASE = 0,
+ GFX_AIRPORT_BASE = 8,
+ GFX_RADAR_LARGE_FIRST = 39,
+ GFX_RADAR_LARGE_LAST = 50,
+ GFX_WINDSACK_FIRST = 58,
+ GFX_WINDSACK_LAST = 61,
+ GFX_TRUCK_BASE = 67,
+ GFX_BUS_BASE = 71,
+ GFX_OILRIG_BASE = 75,
+ GFX_DOCK_BASE = 76,
+ GFX_DOCK_BASE_WATER_PART = 80,
+ GFX_BUOY_BASE = 82,
+ GFX_AIRPORT_BASE_EXTENDED = 83,
+ GFX_RADAR_INTERNATIONAL_FIRST = 90,
+ GFX_RADAR_INTERNATIONAL_LAST = 101,
+ GFX_RADAR_METROPOLITAN_FIRST = 102,
+ GFX_RADAR_METROPOLITAN_LAST = 113,
+ GFX_RADAR_DISTRICTWE_FIRST = 145,
+ GFX_RADAR_DISTRICTWE_LAST = 156,
+ GFX_WINDSACK_INTERCON_FIRST = 164,
+ GFX_WINDSACK_INTERCON_LAST = 167,
+ GFX_BASE_END = 168
+};
+
+enum {
+ RAILWAY_SIZE = GFX_AIRPORT_BASE - GFX_RAILWAY_BASE,
+ AIRPORT_SIZE = GFX_TRUCK_BASE - GFX_AIRPORT_BASE,
+ TRUCK_SIZE = GFX_BUS_BASE - GFX_TRUCK_BASE,
+ BUS_SIZE = GFX_OILRIG_BASE - GFX_BUS_BASE,
+ DOCK_SIZE_TOTAL = GFX_BUOY_BASE - GFX_DOCK_BASE,
+ AIRPORT_SIZE_EXTENDED = GFX_BASE_END - GFX_AIRPORT_BASE_EXTENDED
+};
+
+typedef enum HangarTiles {
+ HANGAR_TILE_0 = 32,
+ HANGAR_TILE_1 = 65,
+ HANGAR_TILE_2 = 86,
+ HANGAR_TILE_3 = 129, // added for west facing hangar
+ HANGAR_TILE_4 = 130, // added for north facing hangar
+ HANGAR_TILE_5 = 131 // added for east facing hangar
+} HangarTiles;
+
+typedef enum StationType {
+ STATION_RAIL,
+ STATION_AIRPORT,
+ STATION_TRUCK,
+ STATION_BUS,
+ STATION_OILRIG,
+ STATION_DOCK,
+ STATION_BUOY
+} StationType;
+
+StationType GetStationType(TileIndex);
+
+static inline RoadStopType GetRoadStopType(TileIndex t)
+{
+ assert(GetStationType(t) == STATION_TRUCK || GetStationType(t) == STATION_BUS);
+ return GetStationType(t) == STATION_TRUCK ? RS_TRUCK : RS_BUS;
+}
+
+static inline StationGfx GetStationGfx(TileIndex t)
+{
+ assert(IsTileType(t, MP_STATION));
+ return _m[t].m5;
+}
+
+static inline void SetStationGfx(TileIndex t, StationGfx gfx)
+{
+ assert(IsTileType(t, MP_STATION));
+ _m[t].m5 = gfx;
+}
+
+static inline bool IsRailwayStation(TileIndex t)
+{
+ return GetStationGfx(t) < GFX_RAILWAY_BASE + RAILWAY_SIZE;
+}
+
+static inline bool IsRailwayStationTile(TileIndex t)
+{
+ return IsTileType(t, MP_STATION) && IsRailwayStation(t);
+}
+
+static inline bool IsHangar(TileIndex t)
+{
+ StationGfx gfx = GetStationGfx(t);
+ return
+ gfx == HANGAR_TILE_0 ||
+ gfx == HANGAR_TILE_1 ||
+ gfx == HANGAR_TILE_2 ||
+ gfx == HANGAR_TILE_3 ||
+ gfx == HANGAR_TILE_4 ||
+ gfx == HANGAR_TILE_5;
+}
+
+static inline bool IsAirport(TileIndex t)
+{
+ StationGfx gfx = GetStationGfx(t);
+ return
+ (IS_BYTE_INSIDE(gfx, GFX_AIRPORT_BASE, GFX_AIRPORT_BASE + AIRPORT_SIZE)) ||
+ (IS_BYTE_INSIDE(gfx, GFX_AIRPORT_BASE_EXTENDED, GFX_AIRPORT_BASE_EXTENDED + AIRPORT_SIZE_EXTENDED));
+}
+
+static inline bool IsTruckStop(TileIndex t)
+{
+ return IS_BYTE_INSIDE(GetStationGfx(t), GFX_TRUCK_BASE, GFX_TRUCK_BASE + TRUCK_SIZE);
+}
+
+static inline bool IsBusStop(TileIndex t)
+{
+ return IS_BYTE_INSIDE(GetStationGfx(t), GFX_BUS_BASE, GFX_BUS_BASE + BUS_SIZE);
+}
+
+static inline bool IsRoadStop(TileIndex t)
+{
+ return IsTruckStop(t) || IsBusStop(t);
+}
+
+static inline bool IsRoadStopTile(TileIndex t)
+{
+ return IsTileType(t, MP_STATION) && IsRoadStop(t);
+}
+
+/**
+ * Gets the direction the road stop entrance points towards.
+ */
+static inline DiagDirection GetRoadStopDir(TileIndex t)
+{
+ assert(IsRoadStopTile(t));
+ return (DiagDirection)((GetStationGfx(t) - GFX_TRUCK_BASE) & 3);
+}
+
+static inline bool IsOilRig(TileIndex t)
+{
+ return GetStationGfx(t) == GFX_OILRIG_BASE;
+}
+
+static inline bool IsDock(TileIndex t)
+{
+ return IS_BYTE_INSIDE(GetStationGfx(t), GFX_DOCK_BASE, GFX_DOCK_BASE + DOCK_SIZE_TOTAL);
+}
+
+static inline bool IsBuoy_(TileIndex t) // XXX _ due to naming conflict
+{
+ return GetStationGfx(t) == GFX_BUOY_BASE;
+}
+
+static inline bool IsBuoyTile(TileIndex t)
+{
+ return IsTileType(t, MP_STATION) && IsBuoy_(t);
+}
+
+
+static inline bool IsHangarTile(TileIndex t)
+{
+ return IsTileType(t, MP_STATION) && IsHangar(t);
+}
+
+
+static inline Axis GetRailStationAxis(TileIndex t)
+{
+ assert(IsRailwayStation(t));
+ return HASBIT(GetStationGfx(t), 0) ? AXIS_Y : AXIS_X;
+}
+
+
+static inline Track GetRailStationTrack(TileIndex t)
+{
+ return AxisToTrack(GetRailStationAxis(t));
+}
+
+static inline bool IsCompatibleTrainStationTile(TileIndex t1, TileIndex t2)
+{
+ assert(IsRailwayStationTile(t2));
+ return
+ IsRailwayStationTile(t1) &&
+ IsCompatibleRail(GetRailType(t1), GetRailType(t2)) &&
+ GetRailStationAxis(t1) == GetRailStationAxis(t2) &&
+ !IsStationTileBlocked(t1);
+}
+
+
+static inline DiagDirection GetDockDirection(TileIndex t)
+{
+ StationGfx gfx = GetStationGfx(t);
+ assert(gfx < GFX_DOCK_BASE_WATER_PART);
+ return (DiagDirection)(gfx - GFX_DOCK_BASE);
+}
+
+static inline TileIndexDiffC GetDockOffset(TileIndex t)
+{
+ static const TileIndexDiffC buoy_offset = {0, 0};
+ static const TileIndexDiffC oilrig_offset = {2, 0};
+ static const TileIndexDiffC dock_offset[DIAGDIR_END] = {
+ {-2, 0},
+ { 0, 2},
+ { 2, 0},
+ { 0, -2},
+ };
+ assert(IsTileType(t, MP_STATION));
+
+ if (IsBuoy_(t)) return buoy_offset;
+ if (IsOilRig(t)) return oilrig_offset;
+
+ assert(IsDock(t));
+
+ return dock_offset[GetDockDirection(t)];
+}
+
+static inline bool IsCustomStationSpecIndex(TileIndex t)
+{
+ assert(IsTileType(t, MP_STATION));
+ return _m[t].m4 != 0;
+}
+
+static inline void SetCustomStationSpecIndex(TileIndex t, byte specindex)
+{
+ assert(IsTileType(t, MP_STATION));
+ _m[t].m4 = specindex;
+}
+
+static inline uint GetCustomStationSpecIndex(TileIndex t)
+{
+ assert(IsTileType(t, MP_STATION));
+ return _m[t].m4;
+}
+
+static inline void SetStationTileRandomBits(TileIndex t, byte random_bits)
+{
+ assert(IsTileType(t, MP_STATION));
+ SB(_m[t].m3, 4, 4, random_bits);
+}
+
+static inline byte GetStationTileRandomBits(TileIndex t)
+{
+ assert(IsTileType(t, MP_STATION));
+ return GB(_m[t].m3, 4, 4);
+}
+
+static inline void MakeStation(TileIndex t, Owner o, StationID sid, byte m5)
+{
+ SetTileType(t, MP_STATION);
+ SetTileOwner(t, o);
+ _m[t].m2 = sid;
+ _m[t].m3 = 0;
+ _m[t].m4 = 0;
+ _m[t].m5 = m5;
+}
+
+static inline void MakeRailStation(TileIndex t, Owner o, StationID sid, Axis a, byte section, RailType rt)
+{
+ MakeStation(t, o, sid, section + a);
+ SetRailType(t, rt);
+}
+
+static inline void MakeRoadStop(TileIndex t, Owner o, StationID sid, RoadStopType rst, DiagDirection d)
+{
+ MakeStation(t, o, sid, (rst == RS_BUS ? GFX_BUS_BASE : GFX_TRUCK_BASE) + d);
+}
+
+static inline void MakeAirport(TileIndex t, Owner o, StationID sid, byte section)
+{
+ MakeStation(t, o, sid, section);
+}
+
+static inline void MakeBuoy(TileIndex t, StationID sid)
+{
+ MakeStation(t, OWNER_NONE, sid, GFX_BUOY_BASE);
+}
+
+static inline void MakeDock(TileIndex t, Owner o, StationID sid, DiagDirection d)
+{
+ MakeStation(t, o, sid, GFX_DOCK_BASE + d);
+ MakeStation(t + TileOffsByDiagDir(d), o, sid, GFX_DOCK_BASE_WATER_PART + DiagDirToAxis(d));
+}
+
+static inline void MakeOilrig(TileIndex t, StationID sid)
+{
+ MakeStation(t, OWNER_NONE, sid, GFX_OILRIG_BASE);
+}
+
+#endif /* STATION_MAP_H */
diff --git a/src/stdafx.h b/src/stdafx.h
new file mode 100644
index 000000000..8504e585c
--- /dev/null
+++ b/src/stdafx.h
@@ -0,0 +1,311 @@
+/* $Id$ */
+
+#ifndef STDAFX_H
+#define STDAFX_H
+
+#include <stdio.h>
+#include <stddef.h>
+#include <string.h>
+#include <stdlib.h>
+
+// MacOS X will use an NSAlert to display failed assertaions since they're lost unless running from a terminal
+// strgen always runs from terminal and don't need a window for asserts
+#if !defined(__APPLE__) || defined(STRGEN)
+# include <assert.h>
+#else
+# include "os/macosx/macos.h"
+#endif
+
+#if defined(UNIX) || defined(__MINGW32__)
+# include <sys/types.h>
+#endif
+
+#if defined(__OS2__)
+# include <types.h>
+# define strcasecmp stricmp
+#endif
+
+#ifdef __BEOS__
+# include <SupportDefs.h>
+#endif
+
+#ifdef SUNOS
+# include <alloca.h>
+#endif
+
+#ifdef __MORPHOS__
+// morphos defines certain amiga defines per default, we undefine them
+// here to make the rest of source less messy and more clear what is
+// required for morphos and what for amigaos
+# ifdef amigaos
+# undef amigaos
+# endif
+# ifdef __amigaos__
+# undef __amigaos__
+# endif
+# ifdef __AMIGA__
+# undef __AMIGA__
+# endif
+# ifdef AMIGA
+# undef AMIGA
+# endif
+# ifdef amiga
+# undef amiga
+# endif
+#endif /* __MORPHOS__ */
+
+#ifdef __APPLE__
+# include "os/macosx/osx_stdafx.h"
+// make endian swapping use Apple's macros to increase speed
+# define BSWAP32(x) Endian32_Swap(x)
+# define BSWAP16(x) Endian16_Swap(x)
+#else
+# define BSWAP32(x) ((((x) >> 24) & 0xFF) | (((x) >> 8) & 0xFF00) | (((x) << 8) & 0xFF0000) | (((x) << 24) & 0xFF000000))
+# define BSWAP16(x) ((x) >> 8 | (x) << 8)
+#endif /* __APPLE__ */
+
+// by default we use [] var arrays
+#define VARARRAY_SIZE
+
+
+// Stuff for GCC
+#if defined(__GNUC__)
+# define NORETURN __attribute__ ((noreturn))
+# define FORCEINLINE inline
+# define CDECL
+# define __int64 long long
+# define NOT_REACHED() assert(0)
+# define GCC_PACK __attribute__((packed))
+
+# if (__GNUC__ == 2)
+# undef VARARRAY_SIZE
+# define VARARRAY_SIZE 0
+# endif
+#endif /* __GNUC__ */
+
+#if defined(__WATCOMC__)
+# define NORETURN
+# define FORCEINLINE inline
+# define CDECL
+# define NOT_REACHED() assert(0)
+# define GCC_PACK
+# include <malloc.h>
+#endif /* __WATCOMC__ */
+
+#if defined(__MINGW32__) || defined(__CYGWIN__)
+# include <malloc.h> // alloca()
+#endif
+
+// Stuff for MSVC
+#if defined(_MSC_VER)
+# pragma once
+# define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+# pragma warning(disable: 4244) // 'conversion' conversion from 'type1' to 'type2', possible loss of data
+# pragma warning(disable: 4761) // integral size mismatch in argument : conversion supplied
+
+# if _MSC_VER >= 1400 // MSVC 2005 safety checks
+# pragma warning(disable: 4996) // 'strdup' was declared deprecated
+# define _CRT_SECURE_NO_DEPRECATE // all deprecated 'unsafe string functions
+# endif /* _MSC_VER >= 1400 */
+
+# include <malloc.h> // alloca()
+# define NORETURN __declspec(noreturn)
+# define FORCEINLINE __forceinline
+# define inline _inline
+# define CDECL _cdecl
+# if defined(_DEBUG)
+# define NOT_REACHED() assert(0)
+# else
+# define NOT_REACHED() _assume(0)
+# endif /* _DEBUG */
+ int CDECL snprintf(char *str, size_t size, const char *format, ...);
+# if _MSC_VER < 1400
+ int CDECL vsnprintf(char *str, size_t size, const char *format, va_list ap);
+# endif
+
+# if defined(WIN32) && !defined(_WIN64) && !defined(WIN64)
+# ifndef _W64
+# define _W64
+# endif
+ typedef _W64 int INT_PTR, *PINT_PTR;
+ typedef _W64 unsigned int UINT_PTR, *PUINT_PTR;
+# endif /* WIN32 && !_WIN64 && !WIN64 */
+
+# if _MSC_VER < 1300 // VC6 and lower
+# ifdef _WIN64
+ typedef __int64 intptr_t;
+# else
+ typedef _W64 int intptr_t;
+# endif
+# endif /* _MSC_VER < 1300 */
+
+# define GCC_PACK
+
+// This is needed to zlib uses the stdcall calling convention on visual studio, also used with libpng (VS6 warning)
+# if defined(WITH_ZLIB) || defined(WITH_PNG)
+# ifndef ZLIB_WINAPI
+# define ZLIB_WINAPI
+# endif
+# endif
+
+# define strcasecmp stricmp
+# define strncasecmp strnicmp
+// suppress: warning C4005: 'offsetof' : macro redefinition (VC8)
+# include <stddef.h>
+#endif /* defined(_MSC_VER) */
+
+/* NOTE: the string returned by these functions is only valid until the next
+ * call to the same function and is not thread- or reentrancy-safe */
+#if !defined(STRGEN)
+# if defined(WIN32) || defined(WIN64)
+# define fopen(file, mode) _wfopen(OTTD2FS(file), L ## mode)
+ const char *FS2OTTD(const wchar_t *name);
+ const wchar_t *OTTD2FS(const char *name);
+# else
+# define fopen(file, mode) fopen(OTTD2FS(file), mode)
+ const char *FS2OTTD(const char *name);
+ const char *OTTD2FS(const char *name);
+# endif /* WIN32 */
+#endif /* STRGEN */
+
+// Windows has always LITTLE_ENDIAN
+#if defined(WIN32) || defined(__OS2__) || defined(WIN64)
+# define TTD_LITTLE_ENDIAN
+#else
+// Else include endian[target/host].h, which has the endian-type, autodetected by the Makefile
+# if defined(STRGEN)
+# include "endian_host.h"
+# else
+# include "endian_target.h"
+# endif
+#endif /* WIN32 || __OS2__ || WIN64 */
+
+#if defined(WIN32) || defined(WIN64) || defined(__OS2__)
+# define PATHSEP "\\"
+# define PATHSEPCHAR '\\'
+#else
+# define PATHSEP "/"
+# define PATHSEPCHAR '/'
+#endif
+
+typedef unsigned char byte;
+#ifndef __BEOS__ // already defined
+ typedef unsigned char uint8;
+ typedef unsigned short uint16;
+ typedef unsigned int uint32;
+#endif
+
+// This is already defined in unix
+#if !defined(UNIX) && !defined(__CYGWIN__) && !defined(__BEOS__) && !defined(__MORPHOS__)
+ typedef unsigned int uint;
+#endif
+// Not defined in QNX Neutrino (6.x)
+#if defined(__QNXNTO__)
+ typedef unsigned int uint;
+#endif
+
+#ifndef __BEOS__
+
+// some platforms use 4 bytes bool in C++
+// C bool has to be the same
+# ifndef __cplusplus
+# ifdef FOUR_BYTE_BOOL
+ typedef unsigned long bool;
+# else /* FOUR_BYTE_BOOL */
+ typedef unsigned char bool;
+# endif /* FOUR_BYTE_BOOL */
+# endif /* __cplusplus */
+
+ typedef signed char int8;
+ typedef signed short int16;
+ typedef signed int int32;
+ typedef signed __int64 int64;
+ typedef unsigned __int64 uint64;
+#endif /* __BEOS__ */
+
+#if defined(ARM) || defined(__arm__) || defined(__alpha__)
+# define OTTD_ALIGNMENT
+#endif
+
+// Setup alignment and conversion macros
+#if defined(TTD_BIG_ENDIAN)
+ static inline uint32 TO_LE32(uint32 x) { return BSWAP32(x); }
+ static inline uint16 TO_LE16(uint16 x) { return BSWAP16(x); }
+ static inline uint32 FROM_LE32(uint32 x) { return BSWAP32(x); }
+ static inline uint16 FROM_LE16(uint16 x) { return BSWAP16(x); }
+# define TO_BE32(x) (x)
+# define TO_BE16(x) (x)
+# define FROM_BE32(x) (x)
+# define FROM_BE16(x) (x)
+# define TO_LE32X(x) BSWAP32(x)
+# define TO_BE32X(x) (x)
+#else
+ static inline uint32 TO_BE32(uint32 x) { return BSWAP32(x); }
+ static inline uint16 TO_BE16(uint16 x) { return BSWAP16(x); }
+ static inline uint32 FROM_BE32(uint32 x) { return BSWAP32(x); }
+ static inline uint16 FROM_BE16(uint16 x) { return BSWAP16(x); }
+# define TO_LE32(x) (x)
+# define TO_LE16(x) (x)
+# define FROM_LE32(x) (x)
+# define FROM_LE16(x) (x)
+# define TO_LE32X(x) (x)
+# define TO_BE32X(x) BSWAP32(x)
+#endif /* TTD_BIG_ENDIAN */
+
+#if !defined(GAME_DATA_DIR)
+# define GAME_DATA_DIR ""
+#endif
+
+#if !defined(PERSONAL_DIR)
+# define PERSONAL_DIR ""
+#endif
+
+#ifndef __cplusplus
+# ifndef __BEOS__
+ enum {
+ false = 0,
+ true = 1,
+ };
+# endif
+#endif /* __cplusplus */
+
+// Compile time assertions
+#ifdef __OS2__
+# define assert_compile(expr)
+#else
+# ifdef __cplusplus
+# define assert_compile(expr) extern "C" void __ct_assert__(int a[1 - 2 * !(expr)])
+# else /* __cplusplus */
+# define assert_compile(expr) void __ct_assert__(int a[1 - 2 * !(expr)])
+# endif /* !__cplusplus */
+#endif /* __OS2__ */
+
+assert_compile(sizeof(uint32) == 4);
+assert_compile(sizeof(uint16) == 2);
+assert_compile(sizeof(uint8) == 1);
+
+#define lengthof(x) (sizeof(x)/sizeof(x[0]))
+#define endof(x) (&x[lengthof(x)])
+#define lastof(x) (&x[lengthof(x) - 1])
+#ifndef offsetof
+# define offsetof(s,m) (size_t)&(((s *)0)->m)
+#endif
+
+
+// take care of some name clashes on macos
+#if defined(__APPLE__)
+# define GetString OTTD_GetString
+# define DrawString OTTD_DrawString
+# define Random OTTD_Random
+# define CloseConnection OTTD_CloseConnection
+#endif /* __APPLE */
+
+#ifdef __AMIGA__
+// it seems AmigaOS already have a Point declared
+# define Point OTTD_AMIGA_POINT
+#endif
+
+#define EXTERN_C_BEGIN extern "C" {
+#define EXTERN_C_END }
+
+#endif /* STDAFX_H */
diff --git a/src/strgen/strgen.c b/src/strgen/strgen.c
new file mode 100644
index 000000000..1726750f5
--- /dev/null
+++ b/src/strgen/strgen.c
@@ -0,0 +1,1399 @@
+/* $Id$ */
+
+#include "../stdafx.h"
+#include "../macros.h"
+#include "../string.h"
+#include "../table/control_codes.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#if (!defined(WIN32) && !defined(WIN64)) || defined(__CYGWIN__)
+#include <unistd.h>
+#endif
+
+#if defined WIN32 || defined __WATCOMC__
+#include <direct.h>
+#endif /* WIN32 || __WATCOMC__ */
+
+#ifdef __MORPHOS__
+#ifdef stderr
+#undef stderr
+#endif
+#define stderr stdout
+#endif /* __MORPHOS__ */
+
+#ifdef __WATCOMC__
+ uint _map_log_x; // an unpleasant hack required because Watcom is insisting on
+ uint _map_size_x; // these variables being valid references in map.h
+ uint _map_size_y;
+ uint _map_tile_mask;
+ uint _map_size;
+#endif /* __WATCOMC__ */
+
+/* Compiles a list of strings into a compiled string list */
+
+typedef void (*ParseCmdProc)(char *buf, int value);
+
+typedef struct LanguagePackHeader {
+ uint32 ident;
+ uint32 version; // 32-bits of auto generated version info which is basically a hash of strings.h
+ char name[32]; // the international name of this language
+ char own_name[32]; // the localized name of this language
+ char isocode[16]; // the ISO code for the language (not country code)
+ uint16 offsets[32]; // the offsets
+ byte plural_form; // plural form index
+ byte pad[3]; // pad header to be a multiple of 4
+} LanguagePackHeader;
+
+typedef struct CmdStruct {
+ const char *cmd;
+ ParseCmdProc proc;
+ long value;
+ int8 consumes;
+ byte flags;
+} CmdStruct;
+
+enum {
+ C_DONTCOUNT = 1,
+ C_CASE = 2,
+};
+
+
+typedef struct Case {
+ int caseidx;
+ char *string;
+ struct Case *next;
+} Case;
+
+static bool _masterlang;
+static bool _translated;
+static const char* _file = "(unknown file)";
+static int _cur_line;
+static int _errors, _warnings;
+
+typedef struct LangString {
+ char *name; // Name of the string
+ char *english; // English text
+ char *translated; // Translated text
+ uint16 hash_next; // next hash entry
+ uint16 index;
+ int line; // line of string in source-file
+ Case *english_case; // cases for english
+ Case *translated_case; // cases for foreign
+} LangString;
+
+static LangString *_strings[65536];
+
+
+#define HASH_SIZE 32767
+static uint16 _hash_head[HASH_SIZE];
+
+static byte _put_buf[4096];
+static int _put_pos;
+static int _next_string_id;
+
+static uint32 _hash;
+static char _lang_name[32], _lang_ownname[32], _lang_isocode[16];
+static byte _lang_pluralform;
+#define MAX_NUM_GENDER 8
+static char _genders[MAX_NUM_GENDER][8];
+static int _numgenders;
+
+// contains the name of all cases.
+#define MAX_NUM_CASES 50
+static char _cases[MAX_NUM_CASES][16];
+static int _numcases;
+
+// for each plural value, this is the number of plural forms.
+static const byte _plural_form_counts[] = { 2, 1, 2, 3, 3, 3, 3, 3, 4 };
+
+static const char *_cur_ident;
+
+typedef struct CmdPair {
+ const CmdStruct *a;
+ char *v;
+} CmdPair;
+
+typedef struct ParsedCommandStruct {
+ int np;
+ CmdPair pairs[32];
+ const CmdStruct *cmd[32]; // ordered by param #
+} ParsedCommandStruct;
+
+// Used when generating some advanced commands.
+static ParsedCommandStruct _cur_pcs;
+static int _cur_argidx;
+
+static uint HashStr(const char *s)
+{
+ uint hash = 0;
+ for (; *s != '\0'; s++) hash = ROL(hash, 3) ^ *s;
+ return hash % HASH_SIZE;
+}
+
+static void HashAdd(const char *s, LangString *ls)
+{
+ uint hash = HashStr(s);
+ ls->hash_next = _hash_head[hash];
+ _hash_head[hash] = ls->index + 1;
+}
+
+static LangString *HashFind(const char *s)
+{
+ int idx = _hash_head[HashStr(s)];
+
+ while (--idx >= 0) {
+ LangString* ls = _strings[idx];
+
+ if (strcmp(ls->name, s) == 0) return ls;
+ idx = ls->hash_next;
+ }
+ return NULL;
+}
+
+#ifdef _MSC_VER
+# define LINE_NUM_FMT "(%d)"
+#else
+# define LINE_NUM_FMT ":%d"
+#endif
+
+static void CDECL warning(const char *s, ...)
+{
+ char buf[1024];
+ va_list va;
+ va_start(va, s);
+ vsnprintf(buf, lengthof(buf), s, va);
+ va_end(va);
+ fprintf(stderr, "%s" LINE_NUM_FMT ": warning: %s\n", _file, _cur_line, buf);
+ _warnings++;
+}
+
+void CDECL error(const char *s, ...)
+{
+ char buf[1024];
+ va_list va;
+ va_start(va, s);
+ vsnprintf(buf, lengthof(buf), s, va);
+ va_end(va);
+ fprintf(stderr, "%s" LINE_NUM_FMT ": error: %s\n", _file, _cur_line, buf);
+ _errors++;
+}
+
+
+static void NORETURN CDECL fatal(const char *s, ...)
+{
+ char buf[1024];
+ va_list va;
+ va_start(va, s);
+ vsnprintf(buf, lengthof(buf), s, va);
+ va_end(va);
+ fprintf(stderr, "%s" LINE_NUM_FMT ": FATAL: %s\n", _file, _cur_line, buf);
+ exit(1);
+}
+
+static void PutByte(byte c)
+{
+ if (_put_pos == lengthof(_put_buf)) fatal("Put buffer too small");
+ _put_buf[_put_pos++] = c;
+}
+
+
+static void PutUtf8(uint32 value)
+{
+ if (value < 0x80) {
+ PutByte(value);
+ } else if (value < 0x800) {
+ PutByte(0xC0 + GB(value, 6, 5));
+ PutByte(0x80 + GB(value, 0, 6));
+ } else if (value < 0x10000) {
+ PutByte(0xE0 + GB(value, 12, 4));
+ PutByte(0x80 + GB(value, 6, 6));
+ PutByte(0x80 + GB(value, 0, 6));
+ } else if (value < 0x110000) {
+ PutByte(0xF0 + GB(value, 18, 3));
+ PutByte(0x80 + GB(value, 12, 6));
+ PutByte(0x80 + GB(value, 6, 6));
+ PutByte(0x80 + GB(value, 0, 6));
+ } else {
+ warning("Invalid unicode value U+0x%X", value);
+ }
+}
+
+
+size_t Utf8Validate(const char *s)
+{
+ uint32 c;
+
+ if (!HASBIT(s[0], 7)) {
+ /* 1 byte */
+ return 1;
+ } else if (GB(s[0], 5, 3) == 6 && IsUtf8Part(s[1])) {
+ /* 2 bytes */
+ c = GB(s[0], 0, 5) << 6 | GB(s[1], 0, 6);
+ if (c >= 0x80) return 2;
+ } else if (GB(s[0], 4, 4) == 14 && IsUtf8Part(s[1]) && IsUtf8Part(s[2])) {
+ /* 3 bytes */
+ c = GB(s[0], 0, 4) << 12 | GB(s[1], 0, 6) << 6 | GB(s[2], 0, 6);
+ if (c >= 0x800) return 3;
+ } else if (GB(s[0], 3, 5) == 30 && IsUtf8Part(s[1]) && IsUtf8Part(s[2]) && IsUtf8Part(s[3])) {
+ /* 4 bytes */
+ c = GB(s[0], 0, 3) << 18 | GB(s[1], 0, 6) << 12 | GB(s[2], 0, 6) << 6 | GB(s[3], 0, 6);
+ if (c >= 0x10000 && c <= 0x10FFFF) return 4;
+ }
+
+ return 0;
+}
+
+
+static void EmitSingleChar(char *buf, int value)
+{
+ if (*buf != '\0') warning("Ignoring trailing letters in command");
+ PutUtf8(value);
+}
+
+
+static void EmitSetX(char *buf, int value)
+{
+ char *err;
+ int x = strtol(buf, &err, 0);
+ if (*err != 0) fatal("SetX param invalid");
+ PutUtf8(SCC_SETX);
+ PutByte((byte)x);
+}
+
+
+static void EmitSetXY(char *buf, int value)
+{
+ char *err;
+ int x;
+ int y;
+
+ x = strtol(buf, &err, 0);
+ if (*err != ' ') fatal("SetXY param invalid");
+ y = strtol(err + 1, &err, 0);
+ if (*err != 0) fatal("SetXY param invalid");
+
+ PutUtf8(SCC_SETXY);
+ PutByte((byte)x);
+ PutByte((byte)y);
+}
+
+// The plural specifier looks like
+// {NUM} {PLURAL -1 passenger passengers} then it picks either passenger/passengers depending on the count in NUM
+
+// This is encoded like
+// CommandByte <ARG#> <NUM> {Length of each string} {each string}
+
+bool ParseRelNum(char **buf, int *value)
+{
+ const char* s = *buf;
+ char* end;
+ bool rel = false;
+ int v;
+
+ while (*s == ' ' || *s == '\t') s++;
+ if (*s == '+') {
+ rel = true;
+ s++;
+ }
+ v = strtol(s, &end, 0);
+ if (end == s) return false;
+ if (rel || v < 0) {
+ *value += v;
+ } else {
+ *value = v;
+ }
+ *buf = end;
+ return true;
+}
+
+// Parse out the next word, or NULL
+char *ParseWord(char **buf)
+{
+ char *s = *buf, *r;
+
+ while (*s == ' ' || *s == '\t') s++;
+ if (*s == '\0') return NULL;
+
+ if (*s == '"') {
+ r = ++s;
+ // parse until next " or NUL
+ for (;;) {
+ if (*s == '\0') break;
+ if (*s == '"') {
+ *s++ = '\0';
+ break;
+ }
+ s++;
+ }
+ } else {
+ // proceed until whitespace or NUL
+ r = s;
+ for (;;) {
+ if (*s == '\0') break;
+ if (*s == ' ' || *s == '\t') {
+ *s++ = '\0';
+ break;
+ }
+ s++;
+ }
+ }
+ *buf = s;
+ return r;
+}
+
+// Forward declaration
+static int TranslateArgumentIdx(int arg);
+
+static void EmitWordList(const char* const* words, uint nw)
+{
+ uint i;
+ uint j;
+
+ PutByte(nw);
+ for (i = 0; i < nw; i++) PutByte(strlen(words[i]));
+ for (i = 0; i < nw; i++) {
+ for (j = 0; words[i][j] != '\0'; j++) PutByte(words[i][j]);
+ }
+}
+
+static void EmitPlural(char *buf, int value)
+{
+ int argidx = _cur_argidx;
+ const char* words[5];
+ int nw = 0;
+
+ // Parse out the number, if one exists. Otherwise default to prev arg.
+ if (!ParseRelNum(&buf, &argidx)) argidx--;
+
+ // Parse each string
+ for (nw = 0; nw < 5; nw++) {
+ words[nw] = ParseWord(&buf);
+ if (words[nw] == NULL) break;
+ }
+
+ if (nw == 0)
+ fatal("%s: No plural words", _cur_ident);
+
+ if (_plural_form_counts[_lang_pluralform] != nw) {
+ if (_translated) {
+ fatal("%s: Invalid number of plural forms. Expecting %d, found %d.", _cur_ident,
+ _plural_form_counts[_lang_pluralform], nw);
+ } else {
+ warning("'%s' is untranslated. Tweaking english string to allow compilation for plural forms", _cur_ident);
+ if (nw > _plural_form_counts[_lang_pluralform]) {
+ nw = _plural_form_counts[_lang_pluralform];
+ } else {
+ for (; nw < _plural_form_counts[_lang_pluralform]; nw++) {
+ words[nw] = words[nw - 1];
+ }
+ }
+ }
+ }
+
+ PutUtf8(SCC_PLURAL_LIST);
+ PutByte(TranslateArgumentIdx(argidx));
+ EmitWordList(words, nw);
+}
+
+
+static void EmitGender(char *buf, int value)
+{
+ int argidx = _cur_argidx;
+ uint nw;
+
+ if (buf[0] == '=') {
+ buf++;
+
+ // This is a {G=DER} command
+ for (nw = 0; ; nw++) {
+ if (nw >= 8) fatal("G argument '%s' invalid", buf);
+ if (strcmp(buf, _genders[nw]) == 0) break;
+ }
+ // now nw contains the gender index
+ PutUtf8(SCC_GENDER_INDEX);
+ PutByte(nw);
+ } else {
+ const char* words[8];
+
+ // This is a {G 0 foo bar two} command.
+ // If no relative number exists, default to +0
+ if (!ParseRelNum(&buf, &argidx)) {}
+
+ for (nw = 0; nw < 8; nw++) {
+ words[nw] = ParseWord(&buf);
+ if (words[nw] == NULL) break;
+ }
+ if (nw != _numgenders) fatal("Bad # of arguments for gender command");
+ PutUtf8(SCC_GENDER_LIST);
+ PutByte(TranslateArgumentIdx(argidx));
+ EmitWordList(words, nw);
+ }
+}
+
+
+static const CmdStruct _cmd_structs[] = {
+ // Update position
+ {"SETX", EmitSetX, SCC_SETX, 0, 0},
+ {"SETXY", EmitSetXY, SCC_SETXY, 0, 0},
+
+ // Font size
+ {"TINYFONT", EmitSingleChar, SCC_TINYFONT, 0, 0},
+ {"BIGFONT", EmitSingleChar, SCC_BIGFONT, 0, 0},
+
+ // Colors
+ {"BLUE", EmitSingleChar, SCC_BLUE, 0, 0},
+ {"SILVER", EmitSingleChar, SCC_SILVER, 0, 0},
+ {"GOLD", EmitSingleChar, SCC_GOLD, 0, 0},
+ {"RED", EmitSingleChar, SCC_RED, 0, 0},
+ {"PURPLE", EmitSingleChar, SCC_PURPLE, 0, 0},
+ {"LTBROWN", EmitSingleChar, SCC_LTBROWN, 0, 0},
+ {"ORANGE", EmitSingleChar, SCC_ORANGE, 0, 0},
+ {"GREEN", EmitSingleChar, SCC_GREEN, 0, 0},
+ {"YELLOW", EmitSingleChar, SCC_YELLOW, 0, 0},
+ {"DKGREEN", EmitSingleChar, SCC_DKGREEN, 0, 0},
+ {"CREAM", EmitSingleChar, SCC_CREAM, 0, 0},
+ {"BROWN", EmitSingleChar, SCC_BROWN, 0, 0},
+ {"WHITE", EmitSingleChar, SCC_WHITE, 0, 0},
+ {"LTBLUE", EmitSingleChar, SCC_LTBLUE, 0, 0},
+ {"GRAY", EmitSingleChar, SCC_GRAY, 0, 0},
+ {"DKBLUE", EmitSingleChar, SCC_DKBLUE, 0, 0},
+ {"BLACK", EmitSingleChar, SCC_BLACK, 0, 0},
+
+ {"CURRCOMPACT", EmitSingleChar, SCC_CURRENCY_COMPACT, 1, 0}, // compact currency (32 bits)
+ {"REV", EmitSingleChar, SCC_REVISION, 0, 0}, // openttd revision string
+ {"SHORTCARGO", EmitSingleChar, SCC_CARGO_SHORT, 2, 0}, // short cargo description, only ### tons, or ### litres
+ {"CURRCOMPACT64", EmitSingleChar, SCC_CURRENCY_COMPACT_64, 2, 0}, // compact currency 64 bits
+
+ // These are special versions of {STRING1}
+ // The first string includes the second string.
+ {"COMPANY", EmitSingleChar, SCC_STRING1, 1, 0},
+ {"PLAYERNAME", EmitSingleChar, SCC_STRING1, 1, 0},
+ {"VEHICLE", EmitSingleChar, SCC_STRING1, 1, 0},
+
+ {"STRING1", EmitSingleChar, SCC_STRING1, 1, C_CASE}, // included string that consumes ONE argument
+ {"STRING2", EmitSingleChar, SCC_STRING2, 2, C_CASE}, // included string that consumes TWO arguments
+ {"STRING3", EmitSingleChar, SCC_STRING3, 3, C_CASE}, // included string that consumes THREE arguments
+ {"STRING4", EmitSingleChar, SCC_STRING4, 4, C_CASE}, // included string that consumes FOUR arguments
+ {"STRING5", EmitSingleChar, SCC_STRING5, 5, C_CASE}, // included string that consumes FIVE arguments
+
+ {"STATIONFEATURES", EmitSingleChar, SCC_STATION_FEATURES, 1, 0}, // station features string, icons of the features
+ {"INDUSTRY", EmitSingleChar, SCC_INDUSTRY_NAME, 1, 0}, // industry, takes an industry #
+ {"CARGO", EmitSingleChar, SCC_CARGO, 2, 0},
+ {"POWER", EmitSingleChar, SCC_POWER, 1, 0},
+ {"VOLUME", EmitSingleChar, SCC_VOLUME, 1, 0},
+ {"VOLUME_S", EmitSingleChar, SCC_VOLUME_SHORT, 1, 0},
+ {"WEIGHT", EmitSingleChar, SCC_WEIGHT, 1, 0},
+ {"WEIGHT_S", EmitSingleChar, SCC_WEIGHT_SHORT, 1, 0},
+ {"FORCE", EmitSingleChar, SCC_FORCE, 1, 0},
+ {"VELOCITY", EmitSingleChar, SCC_VELOCITY, 1, 0},
+
+ {"P", EmitPlural, 0, 0, C_DONTCOUNT}, // plural specifier
+ {"G", EmitGender, 0, 0, C_DONTCOUNT}, // gender specifier
+
+ {"DATE_TINY", EmitSingleChar, SCC_DATE_TINY, 1, 0},
+ {"DATE_SHORT", EmitSingleChar, SCC_DATE_SHORT, 1, 0},
+ {"DATE_LONG", EmitSingleChar, SCC_DATE_LONG, 1, 0},
+
+ {"SKIP", EmitSingleChar, SCC_SKIP, 1, 0},
+
+ {"STRING", EmitSingleChar, SCC_STRING, 1, C_CASE},
+
+ // Numbers
+ {"COMMA", EmitSingleChar, SCC_COMMA, 1, 0}, // Number with comma
+ {"NUM", EmitSingleChar, SCC_NUM, 1, 0}, // Signed number
+
+ {"CURRENCY", EmitSingleChar, SCC_CURRENCY, 1, 0},
+ {"CURRENCY64", EmitSingleChar, SCC_CURRENCY_64, 2, 0},
+
+ {"WAYPOINT", EmitSingleChar, SCC_WAYPOINT_NAME, 1, 0}, // waypoint name
+ {"STATION", EmitSingleChar, SCC_STATION_NAME, 1, 0},
+ {"TOWN", EmitSingleChar, SCC_TOWN_NAME, 1, 0},
+
+ // 0x9D is used for the pseudo command SETCASE
+ // 0x9E is used for case switching
+
+ {"", EmitSingleChar, '\n', 0, C_DONTCOUNT},
+ {"{", EmitSingleChar, '{', 0, C_DONTCOUNT},
+ {"UPARROW", EmitSingleChar, SCC_UPARROW, 0, 0},
+ {"SMALLUPARROW", EmitSingleChar, SCC_SMALLUPARROW, 0, 0},
+ {"SMALLDOWNARROW", EmitSingleChar, SCC_SMALLDOWNARROW, 0, 0},
+ {"TRAIN", EmitSingleChar, SCC_TRAIN, 0, 0},
+ {"LORRY", EmitSingleChar, SCC_LORRY, 0, 0},
+ {"BUS", EmitSingleChar, SCC_BUS, 0, 0},
+ {"PLANE", EmitSingleChar, SCC_PLANE, 0, 0},
+ {"SHIP", EmitSingleChar, SCC_SHIP, 0, 0},
+ {"NBSP", EmitSingleChar, 0xA0, 0, C_DONTCOUNT},
+ {"CENT", EmitSingleChar, 0xA2, 0, C_DONTCOUNT},
+ {"POUNDSIGN", EmitSingleChar, 0xA3, 0, C_DONTCOUNT},
+ {"EURO", EmitSingleChar, 0x20AC, 0, C_DONTCOUNT},
+ {"YENSIGN", EmitSingleChar, 0xA5, 0, C_DONTCOUNT},
+ {"COPYRIGHT", EmitSingleChar, 0xA9, 0, C_DONTCOUNT},
+ {"DOWNARROW", EmitSingleChar, SCC_DOWNARROW, 0, C_DONTCOUNT},
+ {"CHECKMARK", EmitSingleChar, SCC_CHECKMARK, 0, C_DONTCOUNT},
+ {"CROSS", EmitSingleChar, SCC_CROSS, 0, C_DONTCOUNT},
+ {"REGISTERED", EmitSingleChar, 0xAE, 0, C_DONTCOUNT},
+ {"RIGHTARROW", EmitSingleChar, SCC_RIGHTARROW, 0, C_DONTCOUNT},
+ {"SMALLLEFTARROW", EmitSingleChar, SCC_LESSTHAN, 0, C_DONTCOUNT},
+ {"SMALLRIGHTARROW",EmitSingleChar, SCC_GREATERTHAN, 0, C_DONTCOUNT},
+};
+
+
+static const CmdStruct *FindCmd(const char *s, int len)
+{
+ const CmdStruct* cs;
+
+ for (cs = _cmd_structs; cs != endof(_cmd_structs); cs++) {
+ if (strncmp(cs->cmd, s, len) == 0 && cs->cmd[len] == '\0') return cs;
+ }
+ return NULL;
+}
+
+static uint ResolveCaseName(const char *str, uint len)
+{
+ uint i;
+
+ for (i = 0; i < MAX_NUM_CASES; i++) {
+ if (memcmp(_cases[i], str, len) == 0 && _cases[i][len] == 0) return i + 1;
+ }
+ fatal("Invalid case-name '%s'", str);
+}
+
+
+// returns NULL on eof
+// else returns command struct
+static const CmdStruct *ParseCommandString(const char **str, char *param, int *argno, int *casei)
+{
+ const char *s = *str, *start;
+ const CmdStruct *cmd;
+ byte c;
+
+ *argno = -1;
+ *casei = -1;
+
+ // Scan to the next command, exit if there's no next command.
+ for (; *s != '{'; s++) {
+ if (*s == '\0') return NULL;
+ }
+ s++; // Skip past the {
+
+ if (*s >= '0' && *s <= '9') {
+ char *end;
+
+ *argno = strtoul(s, &end, 0);
+ if (*end != ':') fatal("missing arg #");
+ s = end + 1;
+ }
+
+ // parse command name
+ start = s;
+ do {
+ c = *s++;
+ } while (c != '}' && c != ' ' && c != '=' && c != '.' && c != 0);
+
+ cmd = FindCmd(start, s - start - 1);
+ if (cmd == NULL) {
+ error("Undefined command '%.*s'", s - start - 1, start);
+ return NULL;
+ }
+
+ if (c == '.') {
+ const char *casep = s;
+
+ if (!(cmd->flags & C_CASE))
+ fatal("Command '%s' can't have a case", cmd->cmd);
+
+ do c = *s++; while (c != '}' && c != ' ' && c != '\0');
+ *casei = ResolveCaseName(casep, s - casep - 1);
+ }
+
+ if (c == '\0') {
+ error("Missing } from command '%s'", start);
+ return NULL;
+ }
+
+
+ if (c != '}') {
+ if (c == '=') s--;
+ // copy params
+ start = s;
+ for (;;) {
+ c = *s++;
+ if (c == '}') break;
+ if (c == '\0') {
+ error("Missing } from command '%s'", start);
+ return NULL;
+ }
+ if (s - start == 250) fatal("param command too long");
+ *param++ = c;
+ }
+ }
+ *param = '\0';
+
+ *str = s;
+
+ return cmd;
+}
+
+
+static void HandlePragma(char *str)
+{
+ if (!memcmp(str, "id ", 3)) {
+ _next_string_id = strtoul(str + 3, NULL, 0);
+ } else if (!memcmp(str, "name ", 5)) {
+ ttd_strlcpy(_lang_name, str + 5, sizeof(_lang_name));
+ } else if (!memcmp(str, "ownname ", 8)) {
+ ttd_strlcpy(_lang_ownname, str + 8, sizeof(_lang_ownname));
+ } else if (!memcmp(str, "isocode ", 8)) {
+ ttd_strlcpy(_lang_isocode, str + 8, sizeof(_lang_isocode));
+ } else if (!memcmp(str, "plural ", 7)) {
+ _lang_pluralform = atoi(str + 7);
+ if (_lang_pluralform >= lengthof(_plural_form_counts))
+ fatal("Invalid pluralform %d", _lang_pluralform);
+ } else if (!memcmp(str, "gender ", 7)) {
+ char* buf = str + 7;
+
+ for (;;) {
+ const char* s = ParseWord(&buf);
+
+ if (s == NULL) break;
+ if (_numgenders >= MAX_NUM_GENDER) fatal("Too many genders, max %d", MAX_NUM_GENDER);
+ ttd_strlcpy(_genders[_numgenders], s, sizeof(_genders[_numgenders]));
+ _numgenders++;
+ }
+ } else if (!memcmp(str, "case ", 5)) {
+ char* buf = str + 5;
+
+ for (;;) {
+ const char* s = ParseWord(&buf);
+
+ if (s == NULL) break;
+ if (_numcases >= MAX_NUM_CASES) fatal("Too many cases, max %d", MAX_NUM_CASES);
+ ttd_strlcpy(_cases[_numcases], s, sizeof(_cases[_numcases]));
+ _numcases++;
+ }
+ } else {
+ fatal("unknown pragma '%s'", str);
+ }
+}
+
+static void ExtractCommandString(ParsedCommandStruct* p, const char* s, bool warnings)
+{
+ char param[100];
+ int argno;
+ int argidx = 0;
+ int casei;
+
+ memset(p, 0, sizeof(*p));
+
+ for (;;) {
+ // read until next command from a.
+ const CmdStruct* ar = ParseCommandString(&s, param, &argno, &casei);
+
+ if (ar == NULL) break;
+
+ // Sanity checking
+ if (argno != -1 && ar->consumes == 0) fatal("Non consumer param can't have a paramindex");
+
+ if (ar->consumes) {
+ if (argno != -1) argidx = argno;
+ if (argidx < 0 || argidx >= lengthof(p->cmd)) fatal("invalid param idx %d", argidx);
+ if (p->cmd[argidx] != NULL && p->cmd[argidx] != ar) fatal("duplicate param idx %d", argidx);
+
+ p->cmd[argidx++] = ar;
+ } else if (!(ar->flags & C_DONTCOUNT)) { // Ignore some of them
+ if (p->np >= lengthof(p->pairs)) fatal("too many commands in string, max %d", lengthof(p->pairs));
+ p->pairs[p->np].a = ar;
+ p->pairs[p->np].v = param[0] != '\0' ? strdup(param) : "";
+ p->np++;
+ }
+ }
+}
+
+
+static const CmdStruct *TranslateCmdForCompare(const CmdStruct *a)
+{
+ if (a == NULL) return NULL;
+
+ if (strcmp(a->cmd, "STRING1") == 0 ||
+ strcmp(a->cmd, "STRING2") == 0 ||
+ strcmp(a->cmd, "STRING3") == 0 ||
+ strcmp(a->cmd, "STRING4") == 0 ||
+ strcmp(a->cmd, "STRING5") == 0) {
+ return FindCmd("STRING", 6);
+ }
+
+ if (strcmp(a->cmd, "SKIP") == 0) return NULL;
+
+ return a;
+}
+
+
+static bool CheckCommandsMatch(char *a, char *b, const char *name)
+{
+ ParsedCommandStruct templ;
+ ParsedCommandStruct lang;
+ int i,j;
+ bool result = true;
+
+ ExtractCommandString(&templ, b, true);
+ ExtractCommandString(&lang, a, true);
+
+ // For each string in templ, see if we find it in lang
+ if (templ.np != lang.np) {
+ warning("%s: template string and language string have a different # of commands", name);
+ result = false;
+ }
+
+ for (i = 0; i < templ.np; i++) {
+ // see if we find it in lang, and zero it out
+ bool found = false;
+ for (j = 0; j < lang.np; j++) {
+ if (templ.pairs[i].a == lang.pairs[j].a &&
+ strcmp(templ.pairs[i].v, lang.pairs[j].v) == 0) {
+ // it was found in both. zero it out from lang so we don't find it again
+ lang.pairs[j].a = NULL;
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ warning("%s: command '%s' exists in template file but not in language file", name, templ.pairs[i].a->cmd);
+ result = false;
+ }
+ }
+
+ // if we reach here, all non consumer commands match up.
+ // Check if the non consumer commands match up also.
+ for (i = 0; i < lengthof(templ.cmd); i++) {
+ if (TranslateCmdForCompare(templ.cmd[i]) != TranslateCmdForCompare(lang.cmd[i])) {
+ warning("%s: Param idx #%d '%s' doesn't match with template command '%s'", name, i,
+ lang.cmd[i] == NULL ? "<empty>" : lang.cmd[i]->cmd,
+ templ.cmd[i] == NULL ? "<empty>" : templ.cmd[i]->cmd);
+ result = false;
+ }
+ }
+
+ return result;
+}
+
+static void HandleString(char *str, bool master)
+{
+ char *s,*t;
+ LangString *ent;
+ char *casep;
+
+ if (*str == '#') {
+ if (str[1] == '#' && str[2] != '#') HandlePragma(str + 2);
+ return;
+ }
+
+ // Ignore comments & blank lines
+ if (*str == ';' || *str == ' ' || *str == '\0') return;
+
+ s = strchr(str, ':');
+ if (s == NULL) {
+ error("Line has no ':' delimiter");
+ return;
+ }
+
+ // Trim spaces.
+ // After this str points to the command name, and s points to the command contents
+ for (t = s; t > str && (t[-1] == ' ' || t[-1] == '\t'); t--);
+ *t = 0;
+ s++;
+
+ /* Check string is valid UTF-8 */
+ {
+ const char *tmp;
+ for (tmp = s; *tmp != '\0';) {
+ size_t len = Utf8Validate(tmp);
+ if (len == 0) fatal("Invalid UTF-8 sequence in '%s'", s);
+ tmp += len;
+ }
+ }
+
+ // Check if the string has a case..
+ // The syntax for cases is IDENTNAME.case
+ casep = strchr(str, '.');
+ if (casep) *casep++ = 0;
+
+ // Check if this string already exists..
+ ent = HashFind(str);
+
+ if (master) {
+ if (ent != NULL && casep == NULL) {
+ error("String name '%s' is used multiple times", str);
+ return;
+ }
+
+ if (ent == NULL && casep != NULL) {
+ error("Base string name '%s' doesn't exist yet. Define it before defining a case.", str);
+ return;
+ }
+
+ if (ent == NULL) {
+ if (_strings[_next_string_id]) {
+ error("String ID 0x%X for '%s' already in use by '%s'", ent, str, _strings[_next_string_id]->name);
+ return;
+ }
+
+ // Allocate a new LangString
+ ent = calloc(1, sizeof(*ent));
+ _strings[_next_string_id] = ent;
+ ent->index = _next_string_id++;
+ ent->name = strdup(str);
+ ent->line = _cur_line;
+
+ HashAdd(str, ent);
+ }
+
+ if (casep != NULL) {
+ Case* c = malloc(sizeof(*c));
+
+ c->caseidx = ResolveCaseName(casep, strlen(casep));
+ c->string = strdup(s);
+ c->next = ent->english_case;
+ ent->english_case = c;
+ } else {
+ ent->english = strdup(s);
+ }
+
+ } else {
+ if (ent == NULL) {
+ warning("String name '%s' does not exist in master file", str);
+ return;
+ }
+
+ if (ent->translated && casep == NULL) {
+ error("String name '%s' is used multiple times", str);
+ return;
+ }
+
+ if (s[0] == ':' && s[1] == '\0' && casep == NULL) {
+ // Special syntax :: means we should just inherit the master string
+ ent->translated = strdup(ent->english);
+ } else {
+ // make sure that the commands match
+ if (!CheckCommandsMatch(s, ent->english, str)) return;
+
+ if (casep != NULL) {
+ Case* c = malloc(sizeof(*c));
+
+ c->caseidx = ResolveCaseName(casep, strlen(casep));
+ c->string = strdup(s);
+ c->next = ent->translated_case;
+ ent->translated_case = c;
+ } else {
+ ent->translated = strdup(s);
+ }
+ }
+ }
+}
+
+
+static void rstrip(char *buf)
+{
+ int i = strlen(buf);
+ while (i > 0 && (buf[i - 1] == '\r' || buf[i - 1] == '\n' || buf[i - 1] == ' ')) i--;
+ buf[i] = '\0';
+}
+
+
+static void ParseFile(const char *file, bool english)
+{
+ FILE *in;
+ char buf[2048];
+
+ _file = file;
+
+ // For each new file we parse, reset the genders.
+ _numgenders = 0;
+ // TODO:!! We can't reset the cases. In case the translated strings
+ // derive some strings from english....
+
+
+ in = fopen(file, "r");
+ if (in == NULL) fatal("Cannot open file");
+ _cur_line = 1;
+ while (fgets(buf, sizeof(buf),in) != NULL) {
+ rstrip(buf);
+ HandleString(buf, english);
+ _cur_line++;
+ }
+ fclose(in);
+}
+
+
+static uint32 MyHashStr(uint32 hash, const char *s)
+{
+ for (; *s != '\0'; s++) {
+ hash = ROL(hash, 3) ^ *s;
+ hash = (hash & 1 ? hash >> 1 ^ 0xDEADBEEF : hash >> 1);
+ }
+ return hash;
+}
+
+
+// make a hash of the file to get a unique "version number"
+static void MakeHashOfStrings(void)
+{
+ uint32 hash = 0;
+ uint i;
+
+ for (i = 0; i != lengthof(_strings); i++) {
+ const LangString* ls = _strings[i];
+
+ if (ls != NULL) {
+ const CmdStruct* cs;
+ const char* s;
+ char buf[256];
+ int argno;
+ int casei;
+
+ s = ls->name;
+ hash ^= i * 0x717239;
+ hash = (hash & 1 ? hash >> 1 ^ 0xDEADBEEF : hash >> 1);
+ hash = MyHashStr(hash, s + 1);
+
+ s = ls->english;
+ while ((cs = ParseCommandString(&s, buf, &argno, &casei)) != NULL) {
+ if (cs->flags & C_DONTCOUNT) continue;
+
+ hash ^= (cs - _cmd_structs) * 0x1234567;
+ hash = (hash & 1 ? hash >> 1 ^ 0xF00BAA4 : hash >> 1);
+ }
+ }
+ }
+ _hash = hash;
+}
+
+
+static uint CountInUse(uint grp)
+{
+ int i;
+
+ for (i = 0x800; --i >= 0;) if (_strings[(grp << 11) + i] != NULL) break;
+ return i + 1;
+}
+
+
+bool CompareFiles(const char *n1, const char *n2)
+{
+ FILE *f1, *f2;
+ char b1[4096];
+ char b2[4096];
+ size_t l1, l2;
+
+ f2 = fopen(n2, "rb");
+ if (f2 == NULL) return false;
+
+ f1 = fopen(n1, "rb");
+ if (f1 == NULL) fatal("can't open %s", n1);
+
+ do {
+ l1 = fread(b1, 1, sizeof(b1), f1);
+ l2 = fread(b2, 1, sizeof(b2), f2);
+
+ if (l1 != l2 || memcmp(b1, b2, l1)) {
+ fclose(f2);
+ fclose(f1);
+ return false;
+ }
+ } while (l1);
+
+ fclose(f2);
+ fclose(f1);
+ return true;
+}
+
+
+static void WriteStringsH(const char *filename)
+{
+ FILE *out;
+ int i;
+ int next = -1;
+ int lastgrp;
+
+ out = fopen("tmp.xxx", "w");
+ if (out == NULL) fatal("can't open tmp.xxx");
+
+ fprintf(out, "enum {");
+
+ lastgrp = 0;
+
+ for (i = 0; i != lengthof(_strings); i++) {
+ if (_strings[i] != NULL) {
+ if (lastgrp != (i >> 11)) {
+ lastgrp = (i >> 11);
+ fprintf(out, "};\n\nenum {");
+ }
+
+ fprintf(out, next == i ? "\t%s,\n" : "\n\t%s = 0x%X,\n", _strings[i]->name, i);
+ next = i + 1;
+ }
+ }
+
+ fprintf(out, "};\n");
+
+ fprintf(out,
+ "\nenum {\n"
+ "\tLANGUAGE_PACK_IDENT = 0x474E414C, // Big Endian value for 'LANG' (LE is 0x 4C 41 4E 47)\n"
+ "\tLANGUAGE_PACK_VERSION = 0x%X,\n"
+ "};\n", (uint)_hash
+ );
+
+ fclose(out);
+
+ if (CompareFiles("tmp.xxx", filename)) {
+ // files are equal. tmp.xxx is not needed
+ unlink("tmp.xxx");
+ } else {
+ // else rename tmp.xxx into filename
+#if defined(WIN32) || defined(WIN64)
+ unlink(filename);
+#endif
+ if (rename("tmp.xxx", filename) == -1) fatal("rename() failed");
+ }
+}
+
+static int TranslateArgumentIdx(int argidx)
+{
+ int i, sum;
+
+ if (argidx < 0 || argidx >= lengthof(_cur_pcs.cmd))
+ fatal("invalid argidx %d", argidx);
+
+ for (i = sum = 0; i < argidx; i++) {
+ const CmdStruct *cs = _cur_pcs.cmd[i];
+ sum += (cs != NULL) ? cs->consumes : 1;
+ }
+
+ return sum;
+}
+
+static void PutArgidxCommand(void)
+{
+ PutUtf8(SCC_ARG_INDEX);
+ PutByte(TranslateArgumentIdx(_cur_argidx));
+}
+
+
+static void PutCommandString(const char *str)
+{
+ const CmdStruct *cs;
+ char param[256];
+ int argno;
+ int casei;
+
+ _cur_argidx = 0;
+
+ while (*str != '\0') {
+ // Process characters as they are until we encounter a {
+ if (*str != '{') {
+ PutByte(*str++);
+ continue;
+ }
+ cs = ParseCommandString(&str, param, &argno, &casei);
+ if (cs == NULL) break;
+
+ if (casei != -1) {
+ PutUtf8(SCC_SETCASE); // {SETCASE}
+ PutByte(casei);
+ }
+
+ // For params that consume values, we need to handle the argindex properly
+ if (cs->consumes > 0) {
+ // Check if we need to output a move-param command
+ if (argno != -1 && argno != _cur_argidx) {
+ _cur_argidx = argno;
+ PutArgidxCommand();
+ }
+
+ // Output the one from the master string... it's always accurate.
+ cs = _cur_pcs.cmd[_cur_argidx++];
+ if (cs == NULL) {
+ fatal("%s: No argument exists at position %d", _cur_ident, _cur_argidx - 1);
+ }
+ }
+
+ cs->proc(param, cs->value);
+ }
+}
+
+static void WriteLength(FILE *f, uint length)
+{
+ if (length < 0xC0) {
+ fputc(length, f);
+ } else if (length < 0x4000) {
+ fputc((length >> 8) | 0xC0, f);
+ fputc(length & 0xFF, f);
+ } else {
+ fatal("string too long");
+ }
+}
+
+
+static void WriteLangfile(const char *filename, int show_todo)
+{
+ FILE *f;
+ uint in_use[32];
+ LanguagePackHeader hdr;
+ uint i;
+ uint j;
+
+ f = fopen(filename, "wb");
+ if (f == NULL) fatal("can't open %s", filename);
+
+ memset(&hdr, 0, sizeof(hdr));
+ for (i = 0; i != 32; i++) {
+ uint n = CountInUse(i);
+
+ in_use[i] = n;
+ hdr.offsets[i] = TO_LE16(n);
+ }
+
+ // see line 655: fprintf(..."\tLANGUAGE_PACK_IDENT = 0x474E414C,...)
+ hdr.ident = TO_LE32(0x474E414C); // Big Endian value for 'LANG'
+ hdr.version = TO_LE32(_hash);
+ hdr.plural_form = _lang_pluralform;
+ strcpy(hdr.name, _lang_name);
+ strcpy(hdr.own_name, _lang_ownname);
+ strcpy(hdr.isocode, _lang_isocode);
+
+ fwrite(&hdr, sizeof(hdr), 1, f);
+
+ for (i = 0; i != 32; i++) {
+ for (j = 0; j != in_use[i]; j++) {
+ const LangString* ls = _strings[(i << 11) + j];
+ const Case* casep;
+ const char* cmdp;
+
+ // For undefined strings, just set that it's an empty string
+ if (ls == NULL) {
+ WriteLength(f, 0);
+ continue;
+ }
+
+ _cur_ident = ls->name;
+ _cur_line = ls->line;
+
+ // Produce a message if a string doesn't have a translation.
+ if (show_todo > 0 && ls->translated == NULL) {
+ if (show_todo == 2) {
+ warning("'%s' is untranslated", ls->name);
+ } else {
+ const char *s = "<TODO> ";
+ while (*s != '\0') PutByte(*s++);
+ }
+ }
+
+ // Extract the strings and stuff from the english command string
+ ExtractCommandString(&_cur_pcs, ls->english, false);
+
+ if (ls->translated_case != NULL || ls->translated != NULL) {
+ casep = ls->translated_case;
+ cmdp = ls->translated;
+ } else {
+ casep = ls->english_case;
+ cmdp = ls->english;
+ }
+
+ _translated = _masterlang || (cmdp != ls->english);
+
+ if (casep != NULL) {
+ const Case* c;
+ uint num;
+
+ // Need to output a case-switch.
+ // It has this format
+ // <0x9E> <NUM CASES> <CASE1> <LEN1> <STRING1> <CASE2> <LEN2> <STRING2> <CASE3> <LEN3> <STRING3> <STRINGDEFAULT>
+ // Each LEN is printed using 2 bytes in big endian order.
+ PutUtf8(SCC_SWITCH_CASE);
+ // Count the number of cases
+ for (num = 0, c = casep; c; c = c->next) num++;
+ PutByte(num);
+
+ // Write each case
+ for (c = casep; c != NULL; c = c->next) {
+ int pos;
+
+ PutByte(c->caseidx);
+ // Make some space for the 16-bit length
+ pos = _put_pos;
+ PutByte(0);
+ PutByte(0);
+ // Write string
+ PutCommandString(c->string);
+ PutByte(0); // terminate with a zero
+ // Fill in the length
+ _put_buf[pos + 0] = GB(_put_pos - (pos + 2), 8, 8);
+ _put_buf[pos + 1] = GB(_put_pos - (pos + 2), 0, 8);
+ }
+ }
+
+ if (cmdp != NULL) PutCommandString(cmdp);
+
+ WriteLength(f, _put_pos);
+ fwrite(_put_buf, 1, _put_pos, f);
+ _put_pos = 0;
+ }
+ }
+
+ fputc(0, f);
+ fclose(f);
+}
+
+/** Multi-OS mkdirectory function */
+static inline void ottd_mkdir(const char *directory)
+{
+#if defined(WIN32) || defined(__WATCOMC__)
+ mkdir(directory);
+#else
+ mkdir(directory, 0755);
+#endif
+}
+
+/** Create a path consisting of an already existing path, a possible
+ * path seperator and the filename. The seperator is only appended if the path
+ * does not already end with a seperator */
+static inline char *mkpath(char *buf, size_t buflen, const char *path, const char *file)
+{
+ char *p;
+ ttd_strlcpy(buf, path, buflen); // copy directory into buffer
+
+ p = strchr(buf, '\0'); // add path seperator if necessary
+ if (p[-1] != PATHSEPCHAR && (size_t)(p - buf) + 1 < buflen) *p++ = PATHSEPCHAR;
+ ttd_strlcpy(p, file, buflen - (size_t)(p - buf)); // catenate filename at end of buffer
+ return buf;
+}
+
+#if defined(__MINGW32__) || defined(__CYGWIN__)
+/**
+ * On MingW, it is common that both / as \ are accepted in the
+ * params. To go with those flow, we rewrite all incoming /
+ * simply to \, so internally we can safely assume \.
+ */
+static inline char *replace_pathsep(char *s)
+{
+ char *c;
+
+ for (c = s; *c != '\0'; c++) if (*c == '/') *c = '\\';
+ return s;
+}
+#else
+static inline char *replace_pathsep(char *s) { return s; }
+#endif
+
+int CDECL main(int argc, char* argv[])
+{
+ char pathbuf[256];
+ const char *src_dir = ".";
+ const char *dest_dir = NULL;
+
+ int show_todo = 0;
+
+ while (argc > 1 && *argv[1] == '-') {
+ if (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0) {
+ puts("$Revision$");
+ return 0;
+ }
+
+ if (strcmp(argv[1], "-t") == 0 || strcmp(argv[1], "--todo") == 0) {
+ show_todo = 1;
+ argc--, argv++;
+ continue;
+ }
+
+ if (strcmp(argv[1], "-w") == 0 || strcmp(argv[1], "--warning") == 0) {
+ show_todo = 2;
+ argc--, argv++;
+ continue;
+ }
+
+ if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) {
+ puts(
+ "strgen - $Revision$\n"
+ " -v | --version print version information and exit\n"
+ " -t | --todo replace any untranslated strings with '<TODO>'\n"
+ " -w | --warning print a warning for any untranslated strings\n"
+ " -h | -? | --help print this help message and exit\n"
+ " -s | --source_dir search for english.txt in the specified directory\n"
+ " -d | --dest_dir put output file in the specified directory, create if needed\n"
+ " Run without parameters and strgen will search for english.txt and parse it,\n"
+ " creating strings.h. Passing an argument, strgen will translate that language\n"
+ " file using english.txt as a reference and output <language>.lng."
+ );
+ return 0;
+ }
+
+ if (argc > 2 && (strcmp(argv[1], "-s") == 0 || strcmp(argv[1], "--source_dir") == 0)) {
+ src_dir = replace_pathsep(argv[2]);
+ argc -= 2, argv += 2;
+ continue;
+ }
+
+ if (argc > 2 && (strcmp(argv[1], "-d") == 0 || strcmp(argv[1], "--dest_dir") == 0)) {
+ dest_dir = replace_pathsep(argv[2]);
+ argc -= 2, argv += 2;
+ continue;
+ }
+
+ fprintf(stderr, "Invalid arguments\n");
+ return 0;
+ }
+
+ if (dest_dir == NULL) dest_dir = src_dir; // if dest_dir is not specified, it equals src_dir
+
+ /* strgen has two modes of operation. If no (free) arguments are passed
+ * strgen generates strings.h to the destination directory. If it is supplied
+ * with a (free) parameter the program will translate that language to destination
+ * directory. As input english.txt is parsed from the source directory */
+ if (argc == 1) {
+ mkpath(pathbuf, lengthof(pathbuf), src_dir, "english.txt");
+
+ /* parse master file */
+ _masterlang = true;
+ ParseFile(pathbuf, true);
+ MakeHashOfStrings();
+ if (_errors) return 1;
+
+ /* write strings.h */
+ ottd_mkdir(dest_dir);
+ mkpath(pathbuf, lengthof(pathbuf), dest_dir, "strings.h");
+ WriteStringsH(pathbuf);
+ } else if (argc == 2) {
+ char *r;
+
+ mkpath(pathbuf, lengthof(pathbuf), src_dir, "english.txt");
+
+ /* parse master file and check if target file is correct */
+ _masterlang = false;
+ ParseFile(pathbuf, true);
+ MakeHashOfStrings();
+ ParseFile(replace_pathsep(argv[1]), false); // target file
+ if (_errors) return 1;
+
+ /* get the targetfile, strip any directories and append to destination path */
+ r = strrchr(argv[1], PATHSEPCHAR);
+ mkpath(pathbuf, lengthof(pathbuf), dest_dir, (r != NULL) ? &r[1] : argv[1]);
+
+ /* rename the .txt (input-extension) to .lng */
+ r = strrchr(pathbuf, '.');
+ if (r == NULL || strcmp(r, ".txt") != 0) r = strchr(pathbuf, '\0');
+ ttd_strlcpy(r, ".lng", (size_t)(r - pathbuf));
+ WriteLangfile(pathbuf, show_todo);
+
+ /* if showing warnings, print a summary of the language */
+ if (show_todo == 2) {
+ fprintf(stdout, "%d warnings and %d errors for %s\n", _warnings, _errors, pathbuf);
+ }
+ } else {
+ fprintf(stderr, "Invalid arguments\n");
+ }
+
+ return 0;
+}
diff --git a/src/string.c b/src/string.c
new file mode 100644
index 000000000..dba2c7131
--- /dev/null
+++ b/src/string.c
@@ -0,0 +1,247 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "functions.h"
+#include "string.h"
+#include "macros.h"
+#include "table/control_codes.h"
+
+#include <stdarg.h>
+#include <ctype.h> // required for tolower()
+
+void ttd_strlcat(char *dst, const char *src, size_t size)
+{
+ assert(size > 0);
+ for (; size > 0 && *dst != '\0'; --size, ++dst) {}
+ assert(size > 0);
+ while (--size > 0 && *src != '\0') *dst++ = *src++;
+ *dst = '\0';
+}
+
+
+void ttd_strlcpy(char *dst, const char *src, size_t size)
+{
+ assert(size > 0);
+ while (--size > 0 && *src != '\0') *dst++ = *src++;
+ *dst = '\0';
+}
+
+
+char* strecat(char* dst, const char* src, const char* last)
+{
+ assert(dst <= last);
+ for (; *dst != '\0'; ++dst)
+ if (dst == last) return dst;
+ for (; *src != '\0' && dst != last; ++dst, ++src) *dst = *src;
+ *dst = '\0';
+ return strecpy(dst, src, last);
+}
+
+
+char* strecpy(char* dst, const char* src, const char* last)
+{
+ assert(dst <= last);
+ for (; *src != '\0' && dst != last; ++dst, ++src) *dst = *src;
+ *dst = '\0';
+#if 1
+ if (dst == last && *src != '\0') {
+ error("String too long for destination buffer");
+ }
+#endif
+ return dst;
+}
+
+
+char* CDECL str_fmt(const char* str, ...)
+{
+ char buf[4096];
+ va_list va;
+ int len;
+ char* p;
+
+ va_start(va, str);
+ len = vsnprintf(buf, lengthof(buf), str, va);
+ va_end(va);
+ p = malloc(len + 1);
+ if (p != NULL) memcpy(p, buf, len + 1);
+ return p;
+}
+
+
+void str_validate(char *str)
+{
+ char *dst = str;
+ WChar c;
+ size_t len;
+
+ for (len = Utf8Decode(&c, str); c != '\0'; len = Utf8Decode(&c, str)) {
+ if (IsPrintable(c) && (c < SCC_SPRITE_START || c > SCC_SPRITE_END ||
+ IsValidChar(c - SCC_SPRITE_START, CS_ALPHANUMERAL))) {
+ /* Copy the character back. Even if dst is current the same as str
+ * (i.e. no characters have been changed) this is quicker than
+ * moving the pointers ahead by len */
+ do {
+ *dst++ = *str++;
+ } while (--len != 0);
+ } else {
+ /* Replace the undesirable character with a question mark */
+ str += len;
+ *dst++ = '?';
+ }
+ }
+
+ *dst = '\0';
+}
+
+
+void str_strip_colours(char *str)
+{
+ char *dst = str;
+ WChar c;
+ size_t len;
+
+ for (len = Utf8Decode(&c, str); c != '\0'; len = Utf8Decode(&c, str)) {
+ if (c < SCC_BLUE || c > SCC_BLACK) {
+ /* Copy the character back. Even if dst is current the same as str
+ * (i.e. no characters have been changed) this is quicker than
+ * moving the pointers ahead by len */
+ do {
+ *dst++ = *str++;
+ } while (--len != 0);
+ } else {
+ /* Just skip (strip) the colour codes */
+ str += len;
+ }
+ }
+ *dst = '\0';
+}
+
+/** Convert a given ASCII string to lowercase.
+ * NOTE: only support ASCII characters, no UTF8 fancy. As currently
+ * the function is only used to lowercase data-filenames if they are
+ * not found, this is sufficient. If more, or general functionality is
+ * needed, look to r7271 where it was removed because it was broken when
+ * using certain locales: eg in Turkish the uppercase 'I' was converted to
+ * '?', so just revert to the old functionality */
+void strtolower(char *str)
+{
+ for (; *str != '\0'; str++) *str = tolower(*str);
+}
+
+/**
+ * Only allow certain keys. You can define the filter to be used. This makes
+ * sure no invalid keys can get into an editbox, like BELL.
+ * @param key character to be checked
+ * @param afilter the filter to use
+ * @return true or false depending if the character is printable/valid or not
+ */
+bool IsValidChar(WChar key, CharSetFilter afilter)
+{
+ switch (afilter) {
+ case CS_ALPHANUMERAL: return IsPrintable(key);
+ case CS_NUMERAL: return (key >= '0' && key <= '9');
+ case CS_ALPHA: return IsPrintable(key) && !(key >= '0' && key <= '9');
+ }
+
+ return false;
+}
+
+#ifdef WIN32
+int CDECL snprintf(char *str, size_t size, const char *format, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start(ap, format);
+ ret = vsnprintf(str, size, format, ap);
+ va_end(ap);
+ return ret;
+}
+
+#ifdef _MSC_VER
+int CDECL vsnprintf(char *str, size_t size, const char *format, va_list ap)
+{
+ int ret;
+ ret = _vsnprintf(str, size, format, ap);
+ if (ret < 0) str[size - 1] = '\0';
+ return ret;
+}
+#endif /* _MSC_VER */
+
+#endif /* WIN32 */
+
+
+/* UTF-8 handling routines */
+
+
+/* Decode and consume the next UTF-8 encoded character
+ * @param c Buffer to place decoded character.
+ * @param s Character stream to retrieve character from.
+ * @return Number of characters in the sequence.
+ */
+size_t Utf8Decode(WChar *c, const char *s)
+{
+ assert(c != NULL);
+
+ if (!HASBIT(s[0], 7)) {
+ /* Single byte character: 0xxxxxxx */
+ *c = s[0];
+ return 1;
+ } else if (GB(s[0], 5, 3) == 6) {
+ if (IsUtf8Part(s[1])) {
+ /* Double byte character: 110xxxxx 10xxxxxx */
+ *c = GB(s[0], 0, 5) << 6 | GB(s[1], 0, 6);
+ if (*c >= 0x80) return 2;
+ }
+ } else if (GB(s[0], 4, 4) == 14) {
+ if (IsUtf8Part(s[1]) && IsUtf8Part(s[2])) {
+ /* Triple byte character: 1110xxxx 10xxxxxx 10xxxxxx */
+ *c = GB(s[0], 0, 4) << 12 | GB(s[1], 0, 6) << 6 | GB(s[2], 0, 6);
+ if (*c >= 0x800) return 3;
+ }
+ } else if (GB(s[0], 3, 5) == 30) {
+ if (IsUtf8Part(s[1]) && IsUtf8Part(s[2]) && IsUtf8Part(s[3])) {
+ /* 4 byte character: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
+ *c = GB(s[0], 0, 3) << 18 | GB(s[1], 0, 6) << 12 | GB(s[2], 0, 6) << 6 | GB(s[3], 0, 6);
+ if (*c >= 0x10000 && *c <= 0x10FFFF) return 4;
+ }
+ }
+
+ //DEBUG(misc, 1, "[utf8] invalid UTF-8 sequence");
+ *c = '?';
+ return 1;
+}
+
+
+/* Encode a unicode character and place it in the buffer
+ * @param buf Buffer to place character.
+ * @param c Unicode character to encode.
+ * @return Number of characters in the encoded sequence.
+ */
+size_t Utf8Encode(char *buf, WChar c)
+{
+ if (c < 0x80) {
+ *buf = c;
+ return 1;
+ } else if (c < 0x800) {
+ *buf++ = 0xC0 + GB(c, 6, 5);
+ *buf = 0x80 + GB(c, 0, 6);
+ return 2;
+ } else if (c < 0x10000) {
+ *buf++ = 0xE0 + GB(c, 12, 4);
+ *buf++ = 0x80 + GB(c, 6, 6);
+ *buf = 0x80 + GB(c, 0, 6);
+ return 3;
+ } else if (c < 0x110000) {
+ *buf++ = 0xF0 + GB(c, 18, 3);
+ *buf++ = 0x80 + GB(c, 12, 6);
+ *buf++ = 0x80 + GB(c, 6, 6);
+ *buf = 0x80 + GB(c, 0, 6);
+ return 4;
+ }
+
+ //DEBUG(misc, 1, "[utf8] can't UTF-8 encode value 0x%X", c);
+ *buf = '?';
+ return 1;
+}
diff --git a/src/string.h b/src/string.h
new file mode 100644
index 000000000..2dbc06eee
--- /dev/null
+++ b/src/string.h
@@ -0,0 +1,114 @@
+/* $Id$ */
+
+#ifndef STRING_H
+#define STRING_H
+
+#include "macros.h"
+
+/*
+ * dst: destination buffer
+ * src: string to copy/concatenate
+ * size: size of the destination buffer
+ * usage: ttd_strlcpy(dst, src, lengthof(dst));
+ */
+void ttd_strlcat(char *dst, const char *src, size_t size);
+void ttd_strlcpy(char *dst, const char *src, size_t size);
+
+/*
+ * dst: destination buffer
+ * src: string to copy
+ * last: pointer to the last element in the dst array
+ * if NULL no boundary check is performed
+ * returns a pointer to the terminating \0 in the destination buffer
+ * usage: strecpy(dst, src, lastof(dst));
+ */
+char* strecat(char* dst, const char* src, const char* last);
+char* strecpy(char* dst, const char* src, const char* last);
+
+char* CDECL str_fmt(const char* str, ...);
+
+/** Scans the string for valid characters and if it finds invalid ones,
+ * replaces them with a question mark '?' */
+void str_validate(char *str);
+
+/** Scans the string for colour codes and strips them */
+void str_strip_colours(char *str);
+
+/**
+ * Valid filter types for IsValidChar.
+ */
+typedef enum CharSetFilter {
+ CS_ALPHANUMERAL, //! Both numeric and alphabetic and spaces and stuff
+ CS_NUMERAL, //! Only numeric ones
+ CS_ALPHA, //! Only alphabetic values
+} CharSetFilter;
+
+/** Convert the given string to lowercase, only works with ASCII! */
+void strtolower(char *str);
+
+
+/** Get the length of a string, within a limited buffer */
+static inline int ttd_strnlen(const char *str, int maxlen)
+{
+ const char *t;
+ for (t = str; *t != '\0' && t - str < maxlen; t++);
+ return t - str;
+}
+
+
+typedef uint32 WChar;
+
+/**
+ * Only allow certain keys. You can define the filter to be used. This makes
+ * sure no invalid keys can get into an editbox, like BELL.
+ * @param key character to be checked
+ * @param afilter the filter to use
+ * @return true or false depending if the character is printable/valid or not
+ */
+bool IsValidChar(WChar key, CharSetFilter afilter);
+
+size_t Utf8Decode(WChar *c, const char *s);
+size_t Utf8Encode(char *buf, WChar c);
+
+
+static inline WChar Utf8Consume(const char **s)
+{
+ WChar c;
+ *s += Utf8Decode(&c, *s);
+ return c;
+}
+
+
+/** Return the length of a UTF-8 encoded character.
+ * @param c Unicode character.
+ * @return Length of UTF-8 encoding for character.
+ */
+static inline size_t Utf8CharLen(WChar c)
+{
+ if (c < 0x80) return 1;
+ if (c < 0x800) return 2;
+ if (c < 0x10000) return 3;
+ if (c < 0x110000) return 4;
+
+ /* Invalid valid, we encode as a '?' */
+ return 1;
+}
+
+
+/* Check if the given character is part of a UTF8 sequence */
+static inline bool IsUtf8Part(char c)
+{
+ return GB(c, 6, 2) == 2;
+}
+
+
+static inline bool IsPrintable(WChar c)
+{
+ if (c < 0x20) return false;
+ if (c < 0xE000) return true;
+ if (c < 0xE200) return false;
+ return true;
+}
+
+
+#endif /* STRING_H */
diff --git a/src/strings.c b/src/strings.c
new file mode 100644
index 000000000..d94674193
--- /dev/null
+++ b/src/strings.c
@@ -0,0 +1,1311 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "currency.h"
+#include "functions.h"
+#include "string.h"
+#include "strings.h"
+#include "table/strings.h"
+#include "namegen.h"
+#include "station.h"
+#include "town.h"
+#include "vehicle.h"
+#include "news.h"
+#include "screenshot.h"
+#include "waypoint.h"
+#include "industry.h"
+#include "variables.h"
+#include "newgrf_text.h"
+#include "table/landscape_const.h"
+#include "table/control_codes.h"
+#include "music.h"
+#include "date.h"
+#include "industry.h"
+
+#ifdef WIN32
+/* for opendir/readdir/closedir */
+# include "fios.h"
+#else
+# include <sys/types.h>
+# include <dirent.h>
+#endif /* WIN32 */
+
+char _userstring[128];
+
+static char *StationGetSpecialString(char *buff, int x, const char* last);
+static char *GetSpecialTownNameString(char *buff, int ind, uint32 seed, const char* last);
+static char *GetSpecialPlayerNameString(char *buff, int ind, const int32 *argv, const char* last);
+
+static char *FormatString(char *buff, const char *str, const int32 *argv, uint casei, const char* last);
+
+typedef struct LanguagePack {
+ uint32 ident;
+ uint32 version; // 32-bits of auto generated version info which is basically a hash of strings.h
+ char name[32]; // the international name of this language
+ char own_name[32]; // the localized name of this language
+ char isocode[16]; // the ISO code for the language (not country code)
+ uint16 offsets[32]; // the offsets
+ byte plural_form; // how to compute plural forms
+ byte pad[3]; // pad header to be a multiple of 4
+ char data[VARARRAY_SIZE];
+} LanguagePack;
+
+static char **_langpack_offs;
+static LanguagePack *_langpack;
+static uint _langtab_num[32]; // Offset into langpack offs
+static uint _langtab_start[32]; // Offset into langpack offs
+
+static const StringID _cargo_string_list[NUM_LANDSCAPE][NUM_CARGO] = {
+ { /* LT_NORMAL */
+ STR_PASSENGERS,
+ STR_TONS,
+ STR_BAGS,
+ STR_LITERS,
+ STR_ITEMS,
+ STR_CRATES,
+ STR_TONS,
+ STR_TONS,
+ STR_TONS,
+ STR_TONS,
+ STR_BAGS,
+ STR_RES_OTHER
+ },
+
+ { /* LT_HILLY */
+ STR_PASSENGERS,
+ STR_TONS,
+ STR_BAGS,
+ STR_LITERS,
+ STR_ITEMS,
+ STR_CRATES,
+ STR_TONS,
+ STR_TONS,
+ STR_RES_OTHER,
+ STR_TONS,
+ STR_BAGS,
+ STR_TONS
+ },
+
+ { /* LT_DESERT */
+ STR_PASSENGERS,
+ STR_LITERS,
+ STR_BAGS,
+ STR_LITERS,
+ STR_TONS,
+ STR_CRATES,
+ STR_TONS,
+ STR_TONS,
+ STR_TONS,
+ STR_LITERS,
+ STR_BAGS,
+ STR_TONS
+ },
+
+ { /* LT_CANDY */
+ STR_PASSENGERS,
+ STR_TONS,
+ STR_BAGS,
+ STR_NOTHING,
+ STR_NOTHING,
+ STR_TONS,
+ STR_TONS,
+ STR_LITERS,
+ STR_TONS,
+ STR_NOTHING,
+ STR_LITERS,
+ STR_NOTHING
+ }
+};
+
+
+// Read an int64 from the argv array.
+static inline int64 GetInt64(const int32 **argv)
+{
+ int64 result;
+
+ assert(argv);
+ result = (uint32)(*argv)[0] + ((uint64)(uint32)(*argv)[1] << 32);
+ (*argv)+=2;
+ return result;
+}
+
+// Read an int32 from the argv array.
+static inline int32 GetInt32(const int32 **argv)
+{
+ assert(argv);
+ return *(*argv)++;
+}
+
+// Read an array from the argv array.
+static inline const int32 *GetArgvPtr(const int32 **argv, int n)
+{
+ const int32 *result;
+ assert(*argv);
+ result = *argv;
+ (*argv) += n;
+ return result;
+}
+
+
+#define NUM_BOUND_STRINGS 8
+
+// Array to hold the bound strings.
+static const char *_bound_strings[NUM_BOUND_STRINGS];
+
+// This index is used to implement a "round-robin" allocating of
+// slots for BindCString. NUM_BOUND_STRINGS slots are reserved.
+// Which means that after NUM_BOUND_STRINGS calls to BindCString,
+// the indices will be reused.
+static int _bind_index;
+
+static const char *GetStringPtr(StringID string)
+{
+ return _langpack_offs[_langtab_start[string >> 11] + (string & 0x7FF)];
+}
+
+// The highest 8 bits of string contain the "case index".
+// These 8 bits will only be set when FormatString wants to print
+// the string in a different case. No one else except FormatString
+// should set those bits, therefore string CANNOT be StringID, but uint32.
+static char *GetStringWithArgs(char *buffr, uint string, const int32 *argv, const char* last)
+{
+ uint index = GB(string, 0, 11);
+ uint tab = GB(string, 11, 5);
+ char buff[512];
+
+ if (GB(string, 0, 16) == 0) error("!invalid string id 0 in GetString");
+
+ switch (tab) {
+ case 4:
+ if (index >= 0xC0)
+ return GetSpecialTownNameString(buffr, index - 0xC0, GetInt32(&argv), last);
+ break;
+
+ case 14:
+ if (index >= 0xE4)
+ return GetSpecialPlayerNameString(buffr, index - 0xE4, argv, last);
+ break;
+
+ // User defined name
+ case 15:
+ return GetName(buffr, index, last);
+
+ case 26:
+ /* Include string within newgrf text (format code 81) */
+ if (HASBIT(index, 10)) {
+ StringID string = GetGRFStringID(0, 0xD000 + GB(index, 0, 10));
+ return GetStringWithArgs(buffr, string, argv, last);
+ }
+ break;
+
+ case 28:
+ GetGRFString(buff, index, lastof(buff));
+ return FormatString(buffr, buff, argv, 0, last);
+
+ case 29:
+ GetGRFString(buff, index + 0x800, lastof(buff));
+ return FormatString(buffr, buff, argv, 0, last);
+
+ case 30:
+ GetGRFString(buff, index + 0x1000, lastof(buff));
+ return FormatString(buffr, buff, argv, 0, last);
+
+ case 31:
+ // dynamic strings. These are NOT to be passed through the formatter,
+ // but passed through verbatim.
+ if (index < (STR_SPEC_USERSTRING & 0x7FF)) {
+ return strecpy(buffr, _bound_strings[index], last);
+ }
+
+ return FormatString(buffr, _userstring, NULL, 0, last);
+ }
+
+ if (index >= _langtab_num[tab]) {
+ error(
+ "!String 0x%X is invalid. "
+ "Probably because an old version of the .lng file.\n", string
+ );
+ }
+
+ return FormatString(buffr, GetStringPtr(GB(string, 0, 16)), argv, GB(string, 24, 8), last);
+}
+
+char *GetString(char *buffr, StringID string, const char* last)
+{
+ return GetStringWithArgs(buffr, string, (int32*)_decode_parameters, last);
+}
+
+
+char *InlineString(char *buf, StringID string)
+{
+ buf += Utf8Encode(buf, SCC_STRING_ID);
+ buf += Utf8Encode(buf, string);
+ return buf;
+}
+
+
+// This function takes a C-string and allocates a temporary string ID.
+// The duration of the bound string is valid only until the next GetString,
+// so be careful.
+StringID BindCString(const char *str)
+{
+ int idx = (++_bind_index) & (NUM_BOUND_STRINGS - 1);
+ _bound_strings[idx] = str;
+ return idx + STR_SPEC_DYNSTRING;
+}
+
+// This function is used to "bind" a C string to a OpenTTD dparam slot.
+void SetDParamStr(uint n, const char *str)
+{
+ SetDParam(n, BindCString(str));
+}
+
+void InjectDParam(int amount)
+{
+ memmove(_decode_parameters + amount, _decode_parameters, sizeof(_decode_parameters) - amount * sizeof(uint32));
+}
+
+static const uint32 _divisor_table[] = {
+ 1000000000,
+ 100000000,
+ 10000000,
+ 1000000,
+
+ 100000,
+ 10000,
+ 1000,
+ 100,
+ 10,
+ 1
+};
+
+// TODO
+static char *FormatCommaNumber(char *buff, int32 number, const char* last)
+{
+ uint32 quot,divisor;
+ int i;
+ uint32 tot;
+ uint32 num;
+
+ if (number < 0) {
+ *buff++ = '-';
+ number = -number;
+ }
+
+ num = number;
+
+ tot = 0;
+ for (i = 0; i != 10; i++) {
+ divisor = _divisor_table[i];
+ quot = 0;
+ if (num >= divisor) {
+ quot = num / _divisor_table[i];
+ num = num % _divisor_table[i];
+ }
+ if (tot |= quot || i == 9) {
+ *buff++ = '0' + quot;
+ if (i == 0 || i == 3 || i == 6) *buff++ = ',';
+ }
+ }
+
+ *buff = '\0';
+
+ return buff;
+}
+
+// TODO
+static char *FormatNoCommaNumber(char *buff, int32 number, const char* last)
+{
+ uint32 quot,divisor;
+ int i;
+ uint32 tot;
+ uint32 num;
+
+ if (number < 0) {
+ buff = strecpy(buff, "-", last);
+ number = -number;
+ }
+
+ num = number;
+
+ tot = 0;
+ for (i = 0; i != 10; i++) {
+ divisor = _divisor_table[i];
+ quot = 0;
+ if (num >= divisor) {
+ quot = num / _divisor_table[i];
+ num = num % _divisor_table[i];
+ }
+ if (tot |= quot || i == 9) {
+ *buff++ = '0' + quot;
+ }
+ }
+
+ *buff = '\0';
+
+ return buff;
+}
+
+
+static char *FormatYmdString(char *buff, Date date, const char* last)
+{
+ YearMonthDay ymd;
+
+ ConvertDateToYMD(date, &ymd);
+
+ buff = strecpy(buff, GetStringPtr(ymd.day + STR_01AC_1ST - 1), last);
+ buff = strecpy(buff, " ", last);
+ buff = strecpy(buff, GetStringPtr(STR_0162_JAN + ymd.month), last);
+ buff = strecpy(buff, " ", last);
+
+ return FormatNoCommaNumber(buff, ymd.year, last);
+}
+
+static char *FormatMonthAndYear(char *buff, Date date, const char* last)
+{
+ YearMonthDay ymd;
+
+ ConvertDateToYMD(date, &ymd);
+
+ buff = strecpy(buff, GetStringPtr(STR_MONTH_JAN + ymd.month), last);
+ buff = strecpy(buff, " ", last);
+
+ return FormatNoCommaNumber(buff, ymd.year, last);
+}
+
+static char *FormatTinyDate(char *buff, Date date, const char* last)
+{
+ YearMonthDay ymd;
+
+ ConvertDateToYMD(date, &ymd);
+ buff += snprintf(
+ buff, last - buff + 1,
+ " %02i-%02i-%04i", ymd.day, ymd.month + 1, ymd.year
+ );
+
+ return buff;
+}
+
+static char *FormatGenericCurrency(char *buff, const CurrencySpec *spec, int64 number, bool compact, const char* last)
+{
+ const char* multiplier = "";
+ char buf[40];
+ char* p;
+ int j;
+
+ // multiply by exchange rate
+ number *= spec->rate;
+
+ // convert from negative
+ if (number < 0) {
+ buff = strecpy(buff, "-", last);
+ number = -number;
+ }
+
+ /* Add prefix part, folowing symbol_pos specification.
+ * Here, it can can be either 0 (prefix) or 2 (both prefix anf suffix).
+ * The only remaining value is 1 (suffix), so everything that is not 1 */
+ if (spec->symbol_pos != 1) buff = strecpy(buff, spec->prefix, last);
+
+ // for huge numbers, compact the number into k or M
+ if (compact) {
+ if (number >= 1000000000) {
+ number = (number + 500000) / 1000000;
+ multiplier = "M";
+ } else if (number >= 1000000) {
+ number = (number + 500) / 1000;
+ multiplier = "k";
+ }
+ }
+
+ // convert to ascii number and add commas
+ p = endof(buf);
+ *--p = '\0';
+ j = 4;
+ do {
+ if (--j == 0) {
+ *--p = spec->separator;
+ j = 3;
+ }
+ *--p = '0' + number % 10;
+ } while ((number /= 10) != 0);
+ buff = strecpy(buff, p, last);
+
+ buff = strecpy(buff, multiplier, last);
+
+ /* Add suffix part, folowing symbol_pos specification.
+ * Here, it can can be either 1 (suffix) or 2 (both prefix anf suffix).
+ * The only remaining value is 1 (prefix), so everything that is not 0 */
+ if (spec->symbol_pos != 0) buff = strecpy(buff, spec->suffix, last);
+
+ return buff;
+}
+
+static int DeterminePluralForm(int32 n)
+{
+ // The absolute value determines plurality
+ if (n < 0) n = -n;
+
+ switch (_langpack->plural_form) {
+ // Two forms, singular used for one only
+ // Used in:
+ // Danish, Dutch, English, German, Norwegian, Swedish, Estonian, Finnish,
+ // Greek, Hebrew, Italian, Portuguese, Spanish, Esperanto
+ case 0:
+ default:
+ return n != 1;
+
+ // Only one form
+ // Used in:
+ // Hungarian, Japanese, Korean, Turkish
+ case 1:
+ return 0;
+
+ // Two forms, singular used for zero and one
+ // Used in:
+ // French, Brazilian Portuguese
+ case 2:
+ return n > 1;
+
+ // Three forms, special case for zero
+ // Used in:
+ // Latvian
+ case 3:
+ return n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2;
+
+ // Three forms, special case for one and two
+ // Used in:
+ // Gaelige (Irish)
+ case 4:
+ return n==1 ? 0 : n==2 ? 1 : 2;
+
+ // Three forms, special case for numbers ending in 1[2-9]
+ // Used in:
+ // Lithuanian
+ case 5:
+ return n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2;
+
+ // Three forms, special cases for numbers ending in 1 and 2, 3, 4, except those ending in 1[1-4]
+ // Used in:
+ // Croatian, Czech, Russian, Slovak, Ukrainian
+ case 6:
+ return n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;
+
+ // Three forms, special case for one and some numbers ending in 2, 3, or 4
+ // Used in:
+ // Polish
+ case 7:
+ return n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;
+
+ // Four forms, special case for one and all numbers ending in 02, 03, or 04
+ // Used in:
+ // Slovenian
+ case 8:
+ return n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;
+ }
+}
+
+static const char *ParseStringChoice(const char *b, uint form, char *dst, int *dstlen)
+{
+ //<NUM> {Length of each string} {each string}
+ uint n = (byte)*b++;
+ uint pos,i, mylen=0,mypos=0;
+
+ for (i = pos = 0; i != n; i++) {
+ uint len = (byte)*b++;
+ if (i == form) {
+ mypos = pos;
+ mylen = len;
+ }
+ pos += len;
+ }
+ *dstlen = mylen;
+ memcpy(dst, b + mypos, mylen);
+ return b + pos;
+}
+
+typedef struct Units {
+ int s_m; ///< Multiplier for velocity
+ int s_s; ///< Shift for velocity
+ StringID velocity; ///< String for velocity
+ int p_m; ///< Multiplier for power
+ int p_s; ///< Shift for power
+ StringID power; ///< String for velocity
+ int w_m; ///< Multiplier for weight
+ int w_s; ///< Shift for weight
+ StringID s_weight; ///< Short string for weight
+ StringID l_weight; ///< Long string for weight
+ int v_m; ///< Multiplier for volume
+ int v_s; ///< Shift for volume
+ StringID s_volume; ///< Short string for volume
+ StringID l_volume; ///< Long string for volume
+ int f_m; ///< Multiplier for force
+ int f_s; ///< Shift for force
+ StringID force; ///< String for force
+} Units;
+
+/* Unit conversions */
+static const Units units[] = {
+ { // Imperial (Original, mph, hp, metric ton, litre, kN)
+ 10, 4, STR_UNITS_VELOCITY_IMPERIAL,
+ 1, 0, STR_UNITS_POWER_IMPERIAL,
+ 1, 0, STR_UNITS_WEIGHT_SHORT_METRIC, STR_UNITS_WEIGHT_LONG_METRIC,
+ 1000, 0, STR_UNITS_VOLUME_SHORT_METRIC, STR_UNITS_VOLUME_LONG_METRIC,
+ 1, 0, STR_UNITS_FORCE_SI,
+ },
+ { // Metric (km/h, hp, metric ton, litre, kN)
+ 1, 0, STR_UNITS_VELOCITY_METRIC,
+ 1, 0, STR_UNITS_POWER_METRIC,
+ 1, 0, STR_UNITS_WEIGHT_SHORT_METRIC, STR_UNITS_WEIGHT_LONG_METRIC,
+ 1000, 0, STR_UNITS_VOLUME_SHORT_METRIC, STR_UNITS_VOLUME_LONG_METRIC,
+ 1, 0, STR_UNITS_FORCE_SI,
+ },
+ { // SI (m/s, kilowatt, kilogram, cubic metres, kilonewton)
+ 284, 10, STR_UNITS_VELOCITY_SI,
+ 764, 10, STR_UNITS_POWER_SI,
+ 1000, 0, STR_UNITS_WEIGHT_SHORT_SI, STR_UNITS_WEIGHT_LONG_SI,
+ 1, 0, STR_UNITS_VOLUME_SHORT_SI, STR_UNITS_VOLUME_LONG_SI,
+ 1, 0, STR_UNITS_FORCE_SI,
+ },
+};
+
+static char* FormatString(char* buff, const char* str, const int32* argv, uint casei, const char* last)
+{
+ extern const char _openttd_revision[];
+ WChar b;
+ const int32 *argv_orig = argv;
+ uint modifier = 0;
+
+ while ((b = Utf8Consume(&str)) != '\0') {
+ switch (b) {
+ case SCC_SETX: // {SETX}
+ if (buff + Utf8CharLen(SCC_SETX) + 1 < last) {
+ buff += Utf8Encode(buff, SCC_SETX);
+ *buff++ = *str++;
+ }
+ break;
+
+ case SCC_SETXY: // {SETXY}
+ if (buff + Utf8CharLen(SCC_SETXY) + 2 < last) {
+ buff += Utf8Encode(buff, SCC_SETXY);
+ *buff++ = *str++;
+ *buff++ = *str++;
+ }
+ break;
+
+ case SCC_STRING_ID: // {STRINL}
+ buff = GetStringWithArgs(buff, Utf8Consume(&str), argv, last);
+ break;
+
+ case SCC_DATE_LONG: // {DATE_LONG}
+ buff = FormatYmdString(buff, GetInt32(&argv), last);
+ break;
+
+ case SCC_DATE_SHORT: // {DATE_SHORT}
+ buff = FormatMonthAndYear(buff, GetInt32(&argv), last);
+ break;
+
+ case SCC_VELOCITY: {// {VELOCITY}
+ int32 args[1];
+ assert(_opt_ptr->units < lengthof(units));
+ args[0] = GetInt32(&argv) * units[_opt_ptr->units].s_m >> units[_opt_ptr->units].s_s;
+ buff = FormatString(buff, GetStringPtr(units[_opt_ptr->units].velocity), args, modifier >> 24, last);
+ modifier = 0;
+ break;
+ }
+
+ case SCC_CURRENCY_COMPACT: /* {CURRCOMPACT} */
+ buff = FormatGenericCurrency(buff, _currency, GetInt32(&argv), true, last);
+ break;
+
+ case SCC_REVISION: /* {REV} */
+ buff = strecpy(buff, _openttd_revision, last);
+ break;
+
+ case SCC_CARGO_SHORT: { /* {SHORTCARGO} */
+ // Short description of cargotypes. Layout:
+ // 8-bit = cargo type
+ // 16-bit = cargo count
+ StringID cargo_str = _cargo_types_base_values[_opt_ptr->landscape].units_volume[GetInt32(&argv)];
+ switch (cargo_str) {
+ case STR_TONS: {
+ int32 args[1];
+ assert(_opt_ptr->units < lengthof(units));
+ args[0] = GetInt32(&argv) * units[_opt_ptr->units].w_m >> units[_opt_ptr->units].w_s;
+ buff = FormatString(buff, GetStringPtr(units[_opt_ptr->units].l_weight), args, modifier >> 24, last);
+ modifier = 0;
+ break;
+ }
+
+ case STR_LITERS: {
+ int32 args[1];
+ assert(_opt_ptr->units < lengthof(units));
+ args[0] = GetInt32(&argv) * units[_opt_ptr->units].v_m >> units[_opt_ptr->units].v_s;
+ buff = FormatString(buff, GetStringPtr(units[_opt_ptr->units].l_volume), args, modifier >> 24, last);
+ modifier = 0;
+ break;
+ }
+
+ default:
+ buff = FormatCommaNumber(buff, GetInt32(&argv), last);
+ buff = strecpy(buff, " ", last);
+ buff = strecpy(buff, GetStringPtr(cargo_str), last);
+ break;
+ }
+ } break;
+
+ case SCC_CURRENCY_COMPACT_64: { /* {CURRCOMPACT64} */
+ // 64 bit compact currency-unit
+ buff = FormatGenericCurrency(buff, _currency, GetInt64(&argv), true, last);
+ break;
+ }
+
+ case SCC_STRING1: { /* {STRING1} */
+ // String that consumes ONE argument
+ uint str = modifier + GetInt32(&argv);
+ buff = GetStringWithArgs(buff, str, GetArgvPtr(&argv, 1), last);
+ modifier = 0;
+ break;
+ }
+
+ case SCC_STRING2: { /* {STRING2} */
+ // String that consumes TWO arguments
+ uint str = modifier + GetInt32(&argv);
+ buff = GetStringWithArgs(buff, str, GetArgvPtr(&argv, 2), last);
+ modifier = 0;
+ break;
+ }
+
+ case SCC_STRING3: { /* {STRING3} */
+ // String that consumes THREE arguments
+ uint str = modifier + GetInt32(&argv);
+ buff = GetStringWithArgs(buff, str, GetArgvPtr(&argv, 3), last);
+ modifier = 0;
+ break;
+ }
+
+ case SCC_STRING4: { /* {STRING4} */
+ // String that consumes FOUR arguments
+ uint str = modifier + GetInt32(&argv);
+ buff = GetStringWithArgs(buff, str, GetArgvPtr(&argv, 4), last);
+ modifier = 0;
+ break;
+ }
+
+ case SCC_STRING5: { /* {STRING5} */
+ // String that consumes FIVE arguments
+ uint str = modifier + GetInt32(&argv);
+ buff = GetStringWithArgs(buff, str, GetArgvPtr(&argv, 5), last);
+ modifier = 0;
+ break;
+ }
+
+ case SCC_STATION_FEATURES: { /* {STATIONFEATURES} */
+ buff = StationGetSpecialString(buff, GetInt32(&argv), last);
+ break;
+ }
+
+ case SCC_INDUSTRY_NAME: { /* {INDUSTRY} */
+ const Industry* i = GetIndustry(GetInt32(&argv));
+ int32 args[2];
+
+ // industry not valid anymore?
+ if (!IsValidIndustry(i)) break;
+
+ // First print the town name and the industry type name
+ // The string STR_INDUSTRY_PATTERN controls the formatting
+ args[0] = i->town->index;
+ args[1] = GetIndustrySpec(i->type)->name;
+ buff = FormatString(buff, GetStringPtr(STR_INDUSTRY_FORMAT), args, modifier >> 24, last);
+ modifier = 0;
+ break;
+ }
+
+ case SCC_VOLUME: { // {VOLUME}
+ int32 args[1];
+ assert(_opt_ptr->units < lengthof(units));
+ args[0] = GetInt32(&argv) * units[_opt_ptr->units].v_m >> units[_opt_ptr->units].v_s;
+ buff = FormatString(buff, GetStringPtr(units[_opt_ptr->units].l_volume), args, modifier >> 24, last);
+ modifier = 0;
+ break;
+ }
+
+ case SCC_GENDER_LIST: { // {G 0 Der Die Das}
+ const char* s = GetStringPtr(argv_orig[(byte)*str++]); // contains the string that determines gender.
+ int len;
+ int gender = 0;
+ if (s != NULL && Utf8Consume(&s) == SCC_GENDER_INDEX) gender = (byte)s[0];
+ str = ParseStringChoice(str, gender, buff, &len);
+ buff += len;
+ break;
+ }
+
+ case SCC_DATE_TINY: { // {DATE_TINY}
+ buff = FormatTinyDate(buff, GetInt32(&argv), last);
+ break;
+ }
+
+ case SCC_CARGO: { // {CARGO}
+ // Layout now is:
+ // 8bit - cargo type
+ // 16-bit - cargo count
+ CargoID cargo = GetInt32(&argv);
+ StringID cargo_str = (cargo == CT_INVALID) ? STR_8838_N_A : _cargoc.names_long[cargo];
+ buff = GetStringWithArgs(buff, cargo_str, argv++, last);
+ break;
+ }
+
+ case SCC_POWER: { // {POWER}
+ int32 args[1];
+ assert(_opt_ptr->units < lengthof(units));
+ args[0] = GetInt32(&argv) * units[_opt_ptr->units].p_m >> units[_opt_ptr->units].p_s;
+ buff = FormatString(buff, GetStringPtr(units[_opt_ptr->units].power), args, modifier >> 24, last);
+ modifier = 0;
+ break;
+ }
+
+ case SCC_VOLUME_SHORT: { // {VOLUME_S}
+ int32 args[1];
+ assert(_opt_ptr->units < lengthof(units));
+ args[0] = GetInt32(&argv) * units[_opt_ptr->units].v_m >> units[_opt_ptr->units].v_s;
+ buff = FormatString(buff, GetStringPtr(units[_opt_ptr->units].s_volume), args, modifier >> 24, last);
+ modifier = 0;
+ break;
+ }
+
+ case SCC_WEIGHT: { // {WEIGHT}
+ int32 args[1];
+ assert(_opt_ptr->units < lengthof(units));
+ args[0] = GetInt32(&argv) * units[_opt_ptr->units].w_m >> units[_opt_ptr->units].w_s;
+ buff = FormatString(buff, GetStringPtr(units[_opt_ptr->units].l_weight), args, modifier >> 24, last);
+ modifier = 0;
+ break;
+ }
+
+ case SCC_WEIGHT_SHORT: { // {WEIGHT_S}
+ int32 args[1];
+ assert(_opt_ptr->units < lengthof(units));
+ args[0] = GetInt32(&argv) * units[_opt_ptr->units].w_m >> units[_opt_ptr->units].w_s;
+ buff = FormatString(buff, GetStringPtr(units[_opt_ptr->units].s_weight), args, modifier >> 24, last);
+ modifier = 0;
+ break;
+ }
+
+ case SCC_FORCE: { // {FORCE}
+ int32 args[1];
+ assert(_opt_ptr->units < lengthof(units));
+ args[0] = GetInt32(&argv) * units[_opt_ptr->units].f_m >> units[_opt_ptr->units].f_s;
+ buff = FormatString(buff, GetStringPtr(units[_opt_ptr->units].force), args, modifier >> 24, last);
+ modifier = 0;
+ break;
+ }
+
+ case SCC_SKIP: // {SKIP}
+ argv++;
+ break;
+
+ // This sets up the gender for the string.
+ // We just ignore this one. It's used in {G 0 Der Die Das} to determine the case.
+ case SCC_GENDER_INDEX: // {GENDER 0}
+ str++;
+ break;
+
+ case SCC_STRING: {// {STRING}
+ uint str = modifier + GetInt32(&argv);
+ // WARNING. It's prohibited for the included string to consume any arguments.
+ // For included strings that consume argument, you should use STRING1, STRING2 etc.
+ // To debug stuff you can set argv to NULL and it will tell you
+ buff = GetStringWithArgs(buff, str, argv, last);
+ modifier = 0;
+ break;
+ }
+
+ case SCC_COMMA: // {COMMA}
+ buff = FormatCommaNumber(buff, GetInt32(&argv), last);
+ break;
+
+ case SCC_ARG_INDEX: // Move argument pointer
+ argv = argv_orig + (byte)*str++;
+ break;
+
+ case SCC_PLURAL_LIST: { // {P}
+ int32 v = argv_orig[(byte)*str++]; // contains the number that determines plural
+ int len;
+ str = ParseStringChoice(str, DeterminePluralForm(v), buff, &len);
+ buff += len;
+ break;
+ }
+
+ case SCC_NUM: // {NUM}
+ buff = FormatNoCommaNumber(buff, GetInt32(&argv), last);
+ break;
+
+ case SCC_CURRENCY: // {CURRENCY}
+ buff = FormatGenericCurrency(buff, _currency, GetInt32(&argv), false, last);
+ break;
+
+ case SCC_WAYPOINT_NAME: { // {WAYPOINT}
+ int32 temp[2];
+ Waypoint *wp = GetWaypoint(GetInt32(&argv));
+ StringID str;
+ if (wp->string != STR_NULL) {
+ str = wp->string;
+ } else {
+ temp[0] = wp->town_index;
+ temp[1] = wp->town_cn + 1;
+ str = wp->town_cn == 0 ? STR_WAYPOINTNAME_CITY : STR_WAYPOINTNAME_CITY_SERIAL;
+ }
+ buff = GetStringWithArgs(buff, str, temp, last);
+ break;
+ }
+
+ case SCC_STATION_NAME: { // {STATION}
+ const Station* st = GetStation(GetInt32(&argv));
+
+ if (!IsValidStation(st)) { // station doesn't exist anymore
+ buff = GetStringWithArgs(buff, STR_UNKNOWN_DESTINATION, NULL, last);
+ } else {
+ int32 temp[2];
+ temp[0] = st->town->townnametype;
+ temp[1] = st->town->townnameparts;
+ buff = GetStringWithArgs(buff, st->string_id, temp, last);
+ }
+ break;
+ }
+
+ case SCC_TOWN_NAME: { // {TOWN}
+ const Town* t = GetTown(GetInt32(&argv));
+ int32 temp[1];
+
+ assert(IsValidTown(t));
+
+ temp[0] = t->townnameparts;
+ buff = GetStringWithArgs(buff, t->townnametype, temp, last);
+ break;
+ }
+
+ case SCC_CURRENCY_64: { // {CURRENCY64}
+ buff = FormatGenericCurrency(buff, _currency, GetInt64(&argv), false, last);
+ break;
+ }
+
+ case SCC_SETCASE: { // {SETCASE}
+ // This is a pseudo command, it's outputted when someone does {STRING.ack}
+ // The modifier is added to all subsequent GetStringWithArgs that accept the modifier.
+ modifier = (byte)*str++ << 24;
+ break;
+ }
+
+ case SCC_SWITCH_CASE: { // {Used to implement case switching}
+ // <0x9E> <NUM CASES> <CASE1> <LEN1> <STRING1> <CASE2> <LEN2> <STRING2> <CASE3> <LEN3> <STRING3> <STRINGDEFAULT>
+ // Each LEN is printed using 2 bytes in big endian order.
+ uint num = (byte)*str++;
+ while (num) {
+ if ((byte)str[0] == casei) {
+ // Found the case, adjust str pointer and continue
+ str += 3;
+ break;
+ }
+ // Otherwise skip to the next case
+ str += 3 + (str[1] << 8) + str[2];
+ num--;
+ }
+ break;
+ }
+
+ default:
+ if (buff + Utf8CharLen(b) < last) buff += Utf8Encode(buff, b);
+ break;
+ }
+ }
+ *buff = '\0';
+ return buff;
+}
+
+
+static char *StationGetSpecialString(char *buff, int x, const char* last)
+{
+ if ((x & 0x01) && (buff + Utf8CharLen(SCC_TRAIN) < last)) buff += Utf8Encode(buff, SCC_TRAIN);
+ if ((x & 0x02) && (buff + Utf8CharLen(SCC_LORRY) < last)) buff += Utf8Encode(buff, SCC_LORRY);
+ if ((x & 0x04) && (buff + Utf8CharLen(SCC_BUS) < last)) buff += Utf8Encode(buff, SCC_BUS);
+ if ((x & 0x08) && (buff + Utf8CharLen(SCC_PLANE) < last)) buff += Utf8Encode(buff, SCC_PLANE);
+ if ((x & 0x10) && (buff + Utf8CharLen(SCC_SHIP) < last)) buff += Utf8Encode(buff, SCC_SHIP);
+ *buff = '\0';
+ return buff;
+}
+
+static char *GetSpecialTownNameString(char *buff, int ind, uint32 seed, const char* last)
+{
+ char name[512];
+
+ _town_name_generators[ind](name, seed, lastof(name));
+ return strecpy(buff, name, last);
+}
+
+static const char* const _silly_company_names[] = {
+ "Bloggs Brothers",
+ "Tiny Transport Ltd.",
+ "Express Travel",
+ "Comfy-Coach & Co.",
+ "Crush & Bump Ltd.",
+ "Broken & Late Ltd.",
+ "Sam Speedy & Son",
+ "Supersonic Travel",
+ "Mike's Motors",
+ "Lightning International",
+ "Pannik & Loozit Ltd.",
+ "Inter-City Transport",
+ "Getout & Pushit Ltd."
+};
+
+static const char* const _surname_list[] = {
+ "Adams",
+ "Allan",
+ "Baker",
+ "Bigwig",
+ "Black",
+ "Bloggs",
+ "Brown",
+ "Campbell",
+ "Gordon",
+ "Hamilton",
+ "Hawthorn",
+ "Higgins",
+ "Green",
+ "Gribble",
+ "Jones",
+ "McAlpine",
+ "MacDonald",
+ "McIntosh",
+ "Muir",
+ "Murphy",
+ "Nelson",
+ "O'Donnell",
+ "Parker",
+ "Phillips",
+ "Pilkington",
+ "Quigley",
+ "Sharkey",
+ "Thomson",
+ "Watkins"
+};
+
+static const char* const _silly_surname_list[] = {
+ "Grumpy",
+ "Dozy",
+ "Speedy",
+ "Nosey",
+ "Dribble",
+ "Mushroom",
+ "Cabbage",
+ "Sniffle",
+ "Fishy",
+ "Swindle",
+ "Sneaky",
+ "Nutkins"
+};
+
+static const char _initial_name_letters[] = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
+ 'K', 'L', 'M', 'N', 'P', 'R', 'S', 'T', 'W',
+};
+
+static char *GenAndCoName(char *buff, uint32 arg, const char* last)
+{
+ const char* const* base;
+ uint num;
+
+ if (_opt_ptr->landscape == LT_CANDY) {
+ base = _silly_surname_list;
+ num = lengthof(_silly_surname_list);
+ } else {
+ base = _surname_list;
+ num = lengthof(_surname_list);
+ }
+
+ buff = strecpy(buff, base[num * GB(arg, 16, 8) >> 8], last);
+ buff = strecpy(buff, " & Co.", last);
+
+ return buff;
+}
+
+static char *GenPresidentName(char *buff, uint32 x, const char* last)
+{
+ char initial[] = "?. ";
+ const char* const* base;
+ uint num;
+ uint i;
+
+ initial[0] = _initial_name_letters[sizeof(_initial_name_letters) * GB(x, 0, 8) >> 8];
+ buff = strecpy(buff, initial, last);
+
+ i = (sizeof(_initial_name_letters) + 35) * GB(x, 8, 8) >> 8;
+ if (i < sizeof(_initial_name_letters)) {
+ initial[0] = _initial_name_letters[i];
+ buff = strecpy(buff, initial, last);
+ }
+
+ if (_opt_ptr->landscape == LT_CANDY) {
+ base = _silly_surname_list;
+ num = lengthof(_silly_surname_list);
+ } else {
+ base = _surname_list;
+ num = lengthof(_surname_list);
+ }
+
+ buff = strecpy(buff, base[num * GB(x, 16, 8) >> 8], last);
+
+ return buff;
+}
+
+static char *GetSpecialPlayerNameString(char *buff, int ind, const int32 *argv, const char* last)
+{
+ switch (ind) {
+ case 1: // not used
+ return strecpy(buff, _silly_company_names[GetInt32(&argv) & 0xFFFF], last);
+
+ case 2: // used for Foobar & Co company names
+ return GenAndCoName(buff, GetInt32(&argv), last);
+
+ case 3: // President name
+ return GenPresidentName(buff, GetInt32(&argv), last);
+
+ case 4: // song names
+ return strecpy(buff, origin_songs_specs[GetInt32(&argv) - 1].song_name, last);
+ }
+
+ // town name?
+ if (IS_INT_INSIDE(ind - 6, 0, SPECSTR_TOWNNAME_LAST-SPECSTR_TOWNNAME_START + 1)) {
+ buff = GetSpecialTownNameString(buff, ind - 6, GetInt32(&argv), last);
+ return strecpy(buff, " Transport", last);
+ }
+
+ // language name?
+ if (IS_INT_INSIDE(ind, (SPECSTR_LANGUAGE_START - 0x70E4), (SPECSTR_LANGUAGE_END - 0x70E4) + 1)) {
+ int i = ind - (SPECSTR_LANGUAGE_START - 0x70E4);
+ return strecpy(buff,
+ i == _dynlang.curr ? _langpack->own_name : _dynlang.ent[i].name, last);
+ }
+
+ // resolution size?
+ if (IS_INT_INSIDE(ind, (SPECSTR_RESOLUTION_START - 0x70E4), (SPECSTR_RESOLUTION_END - 0x70E4) + 1)) {
+ int i = ind - (SPECSTR_RESOLUTION_START - 0x70E4);
+ buff += snprintf(
+ buff, last - buff + 1, "%dx%d", _resolutions[i][0], _resolutions[i][1]
+ );
+ return buff;
+ }
+
+ // screenshot format name?
+ if (IS_INT_INSIDE(ind, (SPECSTR_SCREENSHOT_START - 0x70E4), (SPECSTR_SCREENSHOT_END - 0x70E4) + 1)) {
+ int i = ind - (SPECSTR_SCREENSHOT_START - 0x70E4);
+ return strecpy(buff, GetScreenshotFormatDesc(i), last);
+ }
+
+ assert(0);
+ return NULL;
+}
+
+// remap a string ID from the old format to the new format
+StringID RemapOldStringID(StringID s)
+{
+ switch (s) {
+ case 0x0006: return STR_SV_EMPTY;
+ case 0x7000: return STR_SV_UNNAMED;
+ case 0x70E4: return SPECSTR_PLAYERNAME_ENGLISH;
+ case 0x70E9: return SPECSTR_PLAYERNAME_ENGLISH;
+ case 0x8864: return STR_SV_TRAIN_NAME;
+ case 0x902B: return STR_SV_ROADVEH_NAME;
+ case 0x9830: return STR_SV_SHIP_NAME;
+ case 0xA02F: return STR_SV_AIRCRAFT_NAME;
+
+ default:
+ if (IS_INT_INSIDE(s, 0x300F, 0x3030)) {
+ return s - 0x300F + STR_SV_STNAME;
+ } else {
+ return s;
+ }
+ }
+}
+
+bool ReadLanguagePack(int lang_index)
+{
+ int tot_count, i;
+ LanguagePack *lang_pack;
+ size_t len;
+ char **langpack_offs;
+ char *s;
+
+ {
+ char *lang = str_fmt("%s%s", _paths.lang_dir, _dynlang.ent[lang_index].file);
+ lang_pack = ReadFileToMem(lang, &len, 200000);
+ free(lang);
+ }
+ if (lang_pack == NULL) return false;
+ if (len < sizeof(LanguagePack) ||
+ lang_pack->ident != TO_LE32(LANGUAGE_PACK_IDENT) ||
+ lang_pack->version != TO_LE32(LANGUAGE_PACK_VERSION)) {
+ free(lang_pack);
+ return false;
+ }
+
+#if defined(TTD_BIG_ENDIAN)
+ for (i = 0; i != 32; i++) {
+ lang_pack->offsets[i] = ReadLE16Aligned(&lang_pack->offsets[i]);
+ }
+#endif
+
+ tot_count = 0;
+ for (i = 0; i != 32; i++) {
+ uint num = lang_pack->offsets[i];
+ _langtab_start[i] = tot_count;
+ _langtab_num[i] = num;
+ tot_count += num;
+ }
+
+ // Allocate offsets
+ langpack_offs = malloc(tot_count * sizeof(*langpack_offs));
+
+ // Fill offsets
+ s = lang_pack->data;
+ for (i = 0; i != tot_count; i++) {
+ len = (byte)*s;
+ *s++ = '\0'; // zero terminate the string before.
+ if (len >= 0xC0) len = ((len & 0x3F) << 8) + (byte)*s++;
+ langpack_offs[i] = s;
+ s += len;
+ }
+
+ free(_langpack);
+ _langpack = lang_pack;
+
+ free(_langpack_offs);
+ _langpack_offs = langpack_offs;
+
+ ttd_strlcpy(_dynlang.curr_file, _dynlang.ent[lang_index].file, sizeof(_dynlang.curr_file));
+
+ _dynlang.curr = lang_index;
+ SetCurrentGrfLangID(_langpack->isocode);
+ return true;
+}
+
+/** Determine the current charset based on the environment
+ * First check some default values, after this one we passed ourselves
+ * and if none exist return the value for $LANG
+ * @param environment variable to check conditionally if default ones are not
+ * set. Pass NULL if you don't want additional checks.
+ * @return return string containing current charset, or NULL if not-determinable */
+const char *GetCurrentLocale(const char *param)
+{
+ const char *env;
+
+ env = getenv("LANGUAGE");
+ if (env != NULL) return env;
+
+ env = getenv("LC_ALL");
+ if (env != NULL) return env;
+
+ if (param != NULL) {
+ env = getenv(param);
+ if (env != NULL) return env;
+ }
+
+ return getenv("LANG");
+}
+
+static int CDECL LanguageCompareFunc(const void *a, const void *b)
+{
+ return strcmp(*(const char* const *)a, *(const char* const *)b);
+}
+
+static int GetLanguageList(char **languages, int max)
+{
+ DIR *dir;
+ struct dirent *dirent;
+ int num = 0;
+
+ dir = opendir(_paths.lang_dir);
+ if (dir != NULL) {
+ while ((dirent = readdir(dir)) != NULL) {
+ const char *d_name = FS2OTTD(dirent->d_name);
+ char *t = strrchr(d_name, '.');
+
+ if (t != NULL && strcmp(t, ".lng") == 0) {
+ languages[num++] = strdup(d_name);
+ if (num == max) break;
+ }
+ }
+ closedir(dir);
+ }
+
+ qsort(languages, num, sizeof(char*), LanguageCompareFunc);
+ return num;
+}
+
+// make a list of the available language packs. put the data in _dynlang struct.
+void InitializeLanguagePacks(void)
+{
+ DynamicLanguages *dl = &_dynlang;
+ int i;
+ int n;
+ int m;
+ int def;
+ int def2;
+ int fallback;
+ LanguagePack hdr;
+ FILE *in;
+ char *files[MAX_LANG];
+ const char* lang;
+
+ lang = GetCurrentLocale("LC_MESSAGES");
+ if (lang == NULL) lang = "en_GB";
+
+ n = GetLanguageList(files, lengthof(files));
+
+ def = -1;
+ def2 = -1;
+ fallback = 0;
+
+ // go through the language files and make sure that they are valid.
+ for (i = m = 0; i != n; i++) {
+ size_t j;
+
+ char *s = str_fmt("%s%s", _paths.lang_dir, files[i]);
+ in = fopen(s, "rb");
+ free(s);
+ if (in == NULL ||
+ (j = fread(&hdr, sizeof(hdr), 1, in), fclose(in), j) != 1 ||
+ hdr.ident != TO_LE32(LANGUAGE_PACK_IDENT) ||
+ hdr.version != TO_LE32(LANGUAGE_PACK_VERSION)) {
+ free(files[i]);
+ continue;
+ }
+
+ dl->ent[m].file = files[i];
+ dl->ent[m].name = strdup(hdr.name);
+
+ if (strcmp(hdr.isocode, "en_GB") == 0) fallback = m;
+ if (strncmp(hdr.isocode, lang, 2) == 0) def2 = m;
+ if (strncmp(hdr.isocode, lang, 5) == 0) def = m;
+
+ m++;
+ }
+ if (def == -1) def = (def2 != -1 ? def2 : fallback);
+
+ if (m == 0)
+ error(n == 0 ? "No available language packs" : "Invalid version of language packs");
+
+ dl->num = m;
+ for (i = 0; i != dl->num; i++) dl->dropdown[i] = SPECSTR_LANGUAGE_START + i;
+ dl->dropdown[i] = INVALID_STRING_ID;
+
+ for (i = 0; i != dl->num; i++)
+ if (strcmp(dl->ent[i].file, dl->curr_file) == 0) {
+ def = i;
+ break;
+ }
+
+ if (!ReadLanguagePack(def))
+ error("can't read language pack '%s'", dl->ent[def].file);
+}
diff --git a/src/strings.h b/src/strings.h
new file mode 100644
index 000000000..dd4fd179d
--- /dev/null
+++ b/src/strings.h
@@ -0,0 +1,14 @@
+/* $Id$ */
+
+#ifndef STRINGS_H
+#define STRINGS_H
+
+char *InlineString(char *buf, uint16 string);
+char *GetString(char *buffr, uint16 string, const char* last);
+
+extern char _userstring[128];
+
+void InjectDParam(int amount);
+int32 GetParamInt32(void);
+
+#endif /* STRINGS_H */
diff --git a/src/subsidy_gui.c b/src/subsidy_gui.c
new file mode 100644
index 000000000..a1b40ad90
--- /dev/null
+++ b/src/subsidy_gui.c
@@ -0,0 +1,176 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "table/strings.h"
+#include "functions.h"
+#include "window.h"
+#include "station.h"
+#include "industry.h"
+#include "town.h"
+#include "player.h"
+#include "gfx.h"
+#include "economy.h"
+#include "variables.h"
+#include "date.h"
+
+static void HandleSubsidyClick(int y)
+{
+ const Subsidy *s;
+ uint num;
+ int offs;
+ TileIndex xy;
+
+ if (y < 0) return;
+
+ num = 0;
+ for (s = _subsidies; s != endof(_subsidies); s++) {
+ if (s->cargo_type != CT_INVALID && s->age < 12) {
+ y -= 10;
+ if (y < 0) goto handle_click;
+ num++;
+ }
+ }
+
+ if (num == 0) {
+ y -= 10;
+ if (y < 0) return;
+ }
+
+ y -= 11;
+ if (y < 0) return;
+
+ for (s = _subsidies; s != endof(_subsidies); s++) {
+ if (s->cargo_type != CT_INVALID && s->age >= 12) {
+ y -= 10;
+ if (y < 0) goto handle_click;
+ }
+ }
+ return;
+
+handle_click:
+
+ /* determine from coordinate for subsidy and try to scroll to it */
+ offs = s->from;
+ if (s->age >= 12) {
+ xy = GetStation(offs)->xy;
+ } else if (s->cargo_type == CT_PASSENGERS || s->cargo_type == CT_MAIL) {
+ xy = GetTown(offs)->xy;
+ } else {
+ xy = GetIndustry(offs)->xy;
+
+ }
+ if (!ScrollMainWindowToTile(xy)) {
+ /* otherwise determine to coordinate for subsidy and scroll to it */
+ offs = s->to;
+ if (s->age >= 12) {
+ xy = GetStation(offs)->xy;
+ } else if (s->cargo_type == CT_PASSENGERS || s->cargo_type == CT_MAIL || s->cargo_type == CT_GOODS || s->cargo_type == CT_FOOD) {
+ xy = GetTown(offs)->xy;
+ } else {
+ xy = GetIndustry(offs)->xy;
+ }
+ ScrollMainWindowToTile(xy);
+ }
+}
+
+static void DrawSubsidiesWindow(const Window *w)
+{
+ YearMonthDay ymd;
+ const Subsidy *s;
+ uint num;
+ int x;
+ int y;
+
+ DrawWindowWidgets(w);
+
+ ConvertDateToYMD(_date, &ymd);
+
+ y = 15;
+ x = 1;
+ DrawString(x, y, STR_2026_SUBSIDIES_ON_OFFER_FOR, 0);
+ y += 10;
+ num = 0;
+
+ for (s = _subsidies; s != endof(_subsidies); s++) {
+ if (s->cargo_type != CT_INVALID && s->age < 12) {
+ int x2;
+
+ SetupSubsidyDecodeParam(s, 1);
+ x2 = DrawString(x + 2, y, STR_2027_FROM_TO, 0);
+
+ SetDParam(0, _date - ymd.day + 384 - s->age * 32);
+ DrawString(x2, y, STR_2028_BY, 0);
+ y += 10;
+ num++;
+ }
+ }
+
+ if (num == 0) {
+ DrawString(x + 2, y, STR_202A_NONE, 0);
+ y += 10;
+ }
+
+ DrawString(x, y + 1, STR_202B_SERVICES_ALREADY_SUBSIDISED, 0);
+ y += 10;
+ num = 0;
+
+ for (s = _subsidies; s != endof(_subsidies); s++) {
+ if (s->cargo_type != CT_INVALID && s->age >= 12) {
+ const Player *p;
+ int xt;
+
+ SetupSubsidyDecodeParam(s, 1);
+
+ p = GetPlayer(GetStation(s->to)->owner);
+ SetDParam(3, p->name_1);
+ SetDParam(4, p->name_2);
+
+ xt = DrawString(x + 2, y, STR_202C_FROM_TO, 0);
+
+ SetDParam(0, _date - ymd.day + 768 - s->age * 32);
+ DrawString(xt, y, STR_202D_UNTIL, 0);
+ y += 10;
+ num++;
+ }
+ }
+
+ if (num == 0) DrawString(x + 2, y, STR_202A_NONE, 0);
+}
+
+static void SubsidiesListWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: DrawSubsidiesWindow(w); break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 3:
+ HandleSubsidyClick(e->we.click.pt.y - 25);
+ break;
+ }
+ break;
+ }
+}
+
+static const Widget _subsidies_list_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 13, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 13, 11, 617, 0, 13, STR_2025_SUBSIDIES, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_STICKYBOX, RESIZE_NONE, 13, 618, 629, 0, 13, STR_NULL, STR_STICKY_BUTTON},
+{ WWT_PANEL, RESIZE_NONE, 13, 0, 629, 14, 126, 0x0, STR_01FD_CLICK_ON_SERVICE_TO_CENTER},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _subsidies_list_desc = {
+ WDP_AUTO, WDP_AUTO, 630, 127,
+ WC_SUBSIDIES_LIST,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON,
+ _subsidies_list_widgets,
+ SubsidiesListWndProc
+};
+
+
+void ShowSubsidiesList(void)
+{
+ AllocateWindowDescFront(&_subsidies_list_desc, 0);
+}
diff --git a/src/table/ai_rail.h b/src/table/ai_rail.h
new file mode 100644
index 000000000..8e6a49c50
--- /dev/null
+++ b/src/table/ai_rail.h
@@ -0,0 +1,480 @@
+/* $Id$ */
+
+typedef struct {
+ byte mode;
+ byte attr;
+ TileIndexDiffC tileoffs;
+} AiDefaultBlockData;
+
+typedef struct {
+ byte p0;
+ byte p1;
+ byte p2;
+ byte p3;
+ byte dir;
+ AiDefaultBlockData data[VARARRAY_SIZE];
+} AiDefaultRailBlock;
+
+typedef struct {
+ byte dir;
+ AiDefaultBlockData data[VARARRAY_SIZE];
+} AiDefaultRoadBlock;
+
+
+#define MKHDR(a,b,c,d,e) a,b,c,d,e,{
+#define MKDEPOT(a, b, c) {0, a, {b, c}}
+#define MKSTATION(a, b, c) {1, a, {b, c}}
+#define MKRAIL(a, b, c) {2, a, {b, c}}
+#define MKCLRRAIL(a, b, c) {3, a, {b, c}}
+#define MKEND {4, 0, {0, 0}}}
+
+static const AiDefaultRailBlock _raildata_ai_0 = {
+ MKHDR(1, 2, 1, 0, 1)
+ MKDEPOT(2, -1, 1),
+ MKSTATION(0x15, 0, -1),
+ MKRAIL(0x26, 0, 1),
+ MKCLRRAIL(1, 0, 2),
+ MKEND
+};
+
+static const AiDefaultRailBlock _raildata_ai_1 = {
+ MKHDR(1, 2, 1, 0, 3)
+ MKDEPOT(2, -1, -1),
+ MKRAIL(0x26, 0, -1),
+ MKSTATION(0x15, 0, 0),
+ MKCLRRAIL(3, 0, -2),
+ MKEND
+};
+
+static const AiDefaultRailBlock _raildata_ai_2 = {
+ MKHDR(1, 2, 1, 0, 0)
+ MKDEPOT(1, -1, -1),
+ MKRAIL(0x15, -1, 0),
+ MKSTATION(0x14, 0, 0),
+ MKCLRRAIL(0, -2, 0),
+ MKEND
+};
+
+static const AiDefaultRailBlock _raildata_ai_3 = {
+ MKHDR(1, 2, 1, 0, 2)
+ MKDEPOT(1, 1, -1),
+ MKRAIL(0x15, 1, 0),
+ MKSTATION(0x14, -1, 0),
+ MKCLRRAIL(2, 2, 0),
+ MKEND
+};
+
+static const AiDefaultRailBlock _raildata_ai_4 = {
+ MKHDR(1, 2, 2, 0, 255)
+ MKSTATION(0x15, 0, 0),
+ MKCLRRAIL(3, 0, -1),
+ MKCLRRAIL(1, 0, 2),
+ MKEND
+};
+
+static const AiDefaultRailBlock _raildata_ai_5 = {
+ MKHDR(1, 2, 2, 0, 255)
+ MKSTATION(0x14, 0, 0),
+ MKCLRRAIL(0, -1, 0),
+ MKCLRRAIL(2, 2, 0),
+ MKEND
+};
+
+static const AiDefaultRailBlock _raildata_ai_6 = {
+ MKHDR(2, 3, 1, 0, 1)
+ MKSTATION(0x27, 0, -2),
+ MKRAIL(0xC2, 0, 1),
+ MKRAIL(0xC2, 1, 1),
+ MKRAIL(0x1A, 0, 2),
+ MKRAIL(0x26, 1, 2),
+ MKDEPOT(3, 1, 3),
+ MKCLRRAIL(1, 0, 3),
+ MKEND
+};
+
+static const AiDefaultRailBlock _raildata_ai_7 = {
+ MKHDR(2, 3, 1, 0, 3)
+ MKDEPOT(1, 0, -3),
+ MKRAIL(0x1A, 0, -2),
+ MKRAIL(0x26, 1, -2),
+ MKRAIL(0xC2, 0, -1),
+ MKRAIL(0xC2, 1, -1),
+ MKSTATION(0x27, 0, 0),
+ MKCLRRAIL(3, 1, -3),
+ MKEND
+};
+
+static const AiDefaultRailBlock _raildata_ai_8 = {
+ MKHDR(2, 3, 1, 0, 2)
+ MKSTATION(0x26, -2, 0),
+ MKRAIL(0xC1, 1, 0),
+ MKRAIL(0xC1, 1, 1),
+ MKRAIL(0x29, 2, 0),
+ MKRAIL(0x15, 2, 1),
+ MKDEPOT(0, 3, 0),
+ MKCLRRAIL(2, 3, 1),
+ MKEND
+};
+
+static const AiDefaultRailBlock _raildata_ai_9 = {
+ MKHDR(2, 3, 1, 0, 0)
+ MKDEPOT(2, -3, -1),
+ MKRAIL(0x29, -2, -1),
+ MKRAIL(0x15, -2, 0),
+ MKRAIL(0xC1, -1, -1),
+ MKRAIL(0xC1, -1, 0),
+ MKSTATION(0x26, 0, -1),
+ MKCLRRAIL(0, -3, 0),
+ MKEND
+};
+
+static const AiDefaultRailBlock _raildata_ai_10 = {
+ MKHDR(2, 3, 2, 0, 255)
+ MKRAIL(0x1A, 0, -3),
+ MKRAIL(0x20, 1, -3),
+ MKRAIL(0xC2, 0, -2),
+ MKRAIL(0xC2, 1, -2),
+ MKSTATION(0x27, 0, -1),
+ MKRAIL(0xC2, 0, 2),
+ MKRAIL(0xC2, 1, 2),
+ MKRAIL(0x1A, 0, 3),
+ MKRAIL(0x4, 1, 3),
+ MKCLRRAIL(3, 0, -4),
+ MKCLRRAIL(1, 0, 4),
+ MKEND
+};
+
+static const AiDefaultRailBlock _raildata_ai_11 = {
+ MKHDR(2, 3, 2, 0, 255)
+ MKRAIL(0x29, -3, 0),
+ MKRAIL(0x10, -3, 1),
+ MKRAIL(0xC1, -2, 0),
+ MKRAIL(0xC1, -2, 1),
+ MKSTATION(0x26, -1, 0),
+ MKRAIL(0xC1, 2, 0),
+ MKRAIL(0xC1, 2, 1),
+ MKRAIL(0x29, 3, 0),
+ MKRAIL(0x4, 3, 1),
+ MKCLRRAIL(0, -4, 0),
+ MKCLRRAIL(2, 4, 0),
+ MKEND
+};
+
+static const AiDefaultRailBlock _raildata_ai_12 = {
+ MKHDR(2, 3, 2, 1, 3)
+ MKRAIL(0x88, -1, -3),
+ MKRAIL(0x6, 0, -3),
+ MKRAIL(0x2, -1, -2),
+ MKRAIL(0x42, 0, -2),
+ MKRAIL(0x2, -1, -1),
+ MKRAIL(0x2, 0, -1),
+ MKRAIL(0x2, -1, 0),
+ MKRAIL(0x2, 0, 0),
+ MKRAIL(0x82, -1, 1),
+ MKRAIL(0x2, 0, 1),
+ MKRAIL(0xA, -1, 2),
+ MKRAIL(0x44, 0, 2),
+ MKCLRRAIL(3, 0, -4),
+ MKCLRRAIL(1, -1, 3),
+ MKEND
+};
+
+static const AiDefaultRailBlock _raildata_ai_13 = {
+ MKHDR(2, 3, 2, 1, 0)
+ MKRAIL(0x21, -3, 0),
+ MKRAIL(0x50, -3, 1),
+ MKRAIL(0x81, -2, 0),
+ MKRAIL(0x1, -2, 1),
+ MKRAIL(0x1, -1, 0),
+ MKRAIL(0x1, -1, 1),
+ MKRAIL(0x1, 0, 0),
+ MKRAIL(0x1, 0, 1),
+ MKRAIL(0x1, 1, 0),
+ MKRAIL(0x41, 1, 1),
+ MKRAIL(0xA0, 2, 0),
+ MKRAIL(0x11, 2, 1),
+ MKCLRRAIL(0, -4, 0),
+ MKCLRRAIL(2, 3, 1),
+ MKEND
+};
+
+static const AiDefaultRailBlock _raildata_ai_14 = {
+ MKHDR(2, 3, 2, 1, 1)
+ MKRAIL(0x88, -1, -3),
+ MKRAIL(0x6, 0, -3),
+ MKRAIL(0x2, -1, -2),
+ MKRAIL(0x42, 0, -2),
+ MKRAIL(0x2, -1, -1),
+ MKRAIL(0x2, 0, -1),
+ MKRAIL(0x2, -1, 0),
+ MKRAIL(0x2, 0, 0),
+ MKRAIL(0x82, -1, 1),
+ MKRAIL(0x2, 0, 1),
+ MKRAIL(0xA, -1, 2),
+ MKRAIL(0x44, 0, 2),
+ MKCLRRAIL(1, -1, 3),
+ MKCLRRAIL(3, 0, -4),
+ MKEND
+};
+
+static const AiDefaultRailBlock _raildata_ai_15 = {
+ MKHDR(2, 3, 2, 1, 2)
+ MKRAIL(0x21, -3, 0),
+ MKRAIL(0x50, -3, 1),
+ MKRAIL(0x81, -2, 0),
+ MKRAIL(0x1, -2, 1),
+ MKRAIL(0x1, -1, 0),
+ MKRAIL(0x1, -1, 1),
+ MKRAIL(0x1, 0, 0),
+ MKRAIL(0x1, 0, 1),
+ MKRAIL(0x1, 1, 0),
+ MKRAIL(0x41, 1, 1),
+ MKRAIL(0xA0, 2, 0),
+ MKRAIL(0x11, 2, 1),
+ MKCLRRAIL(2, 3, 1),
+ MKCLRRAIL(0, -4, 0),
+ MKEND
+};
+
+static const AiDefaultRailBlock _raildata_ai_16 = {
+ MKHDR(1, 3, 1, 0, 1)
+ MKSTATION(0x17, 0, -2),
+ MKRAIL(0x1A, 0, 1),
+ MKCLRRAIL(1, 0, 2),
+ MKDEPOT(0, 1, 1),
+ MKEND
+};
+
+static const AiDefaultRailBlock _raildata_ai_17 = {
+ MKHDR(1, 3, 1, 0, 3)
+ MKCLRRAIL(3, 0, -2),
+ MKRAIL(0x26, 0, -1),
+ MKDEPOT(2, -1, -1),
+ MKSTATION(0x17, 0, 0),
+ MKEND
+};
+
+static const AiDefaultRailBlock _raildata_ai_18 = {
+ MKHDR(1, 3, 1, 0, 0)
+ MKCLRRAIL(0, -2, 0),
+ MKRAIL(0x29, -1, 0),
+ MKDEPOT(3, -1, 1),
+ MKSTATION(0x16, 0, 0),
+ MKEND
+};
+
+static const AiDefaultRailBlock _raildata_ai_19 = {
+ MKHDR(1, 3, 1, 0, 2)
+ MKSTATION(0x16, -2, 0),
+ MKDEPOT(2, 0, -1),
+ MKRAIL(0x20, 1, -1),
+ MKRAIL(0x15, 1, 0),
+ MKCLRRAIL(2, 2, 0),
+ MKEND
+};
+
+static const AiDefaultRailBlock _raildata_ai_20 = {
+ MKHDR(2, 3, 1, 0, 1)
+ MKSTATION(0x26, -2, 0),
+ MKRAIL(0xC1, 1, 0),
+ MKRAIL(0xC1, 1, 1),
+ MKRAIL(0x26, 2, 0),
+ MKRAIL(0x26, 2, 1),
+ MKDEPOT(1, 2, -1),
+ MKCLRRAIL(1, 2, 2),
+ MKEND
+};
+
+static const AiDefaultRailBlock _raildata_ai_21 = {
+ MKHDR(2, 3, 1, 0, 3)
+ MKDEPOT(2, -3, -1),
+ MKRAIL(0x3F, -2, -1),
+ MKRAIL(0x10, -2, 0),
+ MKRAIL(0xC1, -1, -1),
+ MKRAIL(0xC1, -1, 0),
+ MKSTATION(0x26, 0, -1),
+ MKCLRRAIL(3, -2, -2),
+ MKEND
+};
+
+static const AiDefaultRailBlock _raildata_ai_22 = {
+ MKHDR(2, 3, 1, 0, 0)
+ MKSTATION(0x27, 0, -2),
+ MKRAIL(0xC2, 0, 1),
+ MKRAIL(0xC2, 1, 1),
+ MKRAIL(0x15, 0, 2),
+ MKRAIL(0x4, 1, 2),
+ MKRAIL(0x15, -1, 2),
+ MKDEPOT(1, -1, 1),
+ MKCLRRAIL(0, -2, 2),
+ MKEND
+};
+
+static const AiDefaultRailBlock _raildata_ai_23 = {
+ MKHDR(2, 3, 1, 0, 2)
+ MKDEPOT(1, 0, -3),
+ MKRAIL(0x1A, 0, -2),
+ MKRAIL(0x29, 1, -2),
+ MKRAIL(0xC2, 0, -1),
+ MKRAIL(0xC2, 1, -1),
+ MKSTATION(0x27, 0, 0),
+ MKCLRRAIL(2, 2, -2),
+ MKEND
+};
+
+
+
+static const AiDefaultRailBlock * const _default_rail_track_data[] = {
+ &_raildata_ai_0,
+ &_raildata_ai_1,
+ &_raildata_ai_2,
+ &_raildata_ai_3,
+ &_raildata_ai_4,
+ &_raildata_ai_5,
+ &_raildata_ai_6,
+ &_raildata_ai_7,
+ &_raildata_ai_8,
+ &_raildata_ai_9,
+ &_raildata_ai_10,
+ &_raildata_ai_11,
+ &_raildata_ai_12,
+ &_raildata_ai_13,
+ &_raildata_ai_14,
+ &_raildata_ai_15,
+ &_raildata_ai_16,
+ &_raildata_ai_17,
+ &_raildata_ai_18,
+ &_raildata_ai_19,
+ &_raildata_ai_20,
+ &_raildata_ai_21,
+ &_raildata_ai_22,
+ &_raildata_ai_23,
+ NULL
+};
+
+#undef MKHDR
+
+#define MKHDR(a) a,{
+
+static const AiDefaultRoadBlock _roaddata_ai_0 = {
+ MKHDR(0)
+ MKDEPOT(2, -1,1),
+ MKSTATION(0x2, -1,0),
+ MKRAIL(0xC, 0,0),
+ MKRAIL(0x9, 0,1),
+ MKCLRRAIL(0, 0,-1),
+ MKCLRRAIL(0, 1,0),
+ MKCLRRAIL(0, 1,1),
+ MKCLRRAIL(0, 0,2),
+ MKEND
+};
+
+static const AiDefaultRoadBlock _roaddata_ai_1 = {
+ MKHDR(0)
+ MKDEPOT(1, 0,-1),
+ MKSTATION(0x1, 1,-1),
+ MKRAIL(0x3, 0,0),
+ MKRAIL(0x9, 1,0),
+ MKCLRRAIL(0, -1,0),
+ MKCLRRAIL(0, 0,1),
+ MKCLRRAIL(0, 1,1),
+ MKCLRRAIL(0, 2,0),
+ MKEND
+};
+
+static const AiDefaultRoadBlock _roaddata_ai_2 = {
+ MKHDR(0)
+ MKDEPOT(3, 1,1),
+ MKSTATION(0x3, 0,1),
+ MKRAIL(0x6, 0,0),
+ MKRAIL(0xC, 1,0),
+ MKCLRRAIL(0, -1,0),
+ MKCLRRAIL(0, 0,-1),
+ MKCLRRAIL(0, 1,-1),
+ MKCLRRAIL(0, 2,0),
+ MKEND
+};
+
+static const AiDefaultRoadBlock _roaddata_ai_3 = {
+ MKHDR(0)
+ MKDEPOT(0, 1,0),
+ MKSTATION(0x0, 1,1),
+ MKRAIL(0x6, 0,0),
+ MKRAIL(0x3, 0,1),
+ MKCLRRAIL(0, 0,-1),
+ MKCLRRAIL(0, -1,0),
+ MKCLRRAIL(0, -1,1),
+ MKCLRRAIL(0, 0,2),
+ MKEND
+};
+
+static const AiDefaultRoadBlock _roaddata_ai_4 = {
+ MKHDR(1)
+ MKSTATION(0x2, -1,0),
+ MKRAIL(0x8, 0,0),
+ MKCLRRAIL(0, 0,-1),
+ MKCLRRAIL(0, 1,0),
+ MKCLRRAIL(0, 0,1),
+ MKEND
+};
+
+static const AiDefaultRoadBlock _roaddata_ai_5 = {
+ MKHDR(1)
+ MKSTATION(0x3, 0,1),
+ MKRAIL(0x4, 0,0),
+ MKCLRRAIL(0, -1,0),
+ MKCLRRAIL(0, 0,-1),
+ MKCLRRAIL(0, 1,0),
+ MKEND
+};
+
+static const AiDefaultRoadBlock _roaddata_ai_6 = {
+ MKHDR(1)
+ MKSTATION(0x0, 1,1),
+ MKRAIL(0x2, 0,1),
+ MKCLRRAIL(0, 0,0),
+ MKCLRRAIL(0, -1,0),
+ MKCLRRAIL(0, 0,2),
+ MKEND
+};
+
+static const AiDefaultRoadBlock _roaddata_ai_7 = {
+ MKHDR(1)
+ MKSTATION(0x1, 1,-1),
+ MKRAIL(0x1, 1,0),
+ MKCLRRAIL(0, 0,0),
+ MKCLRRAIL(0, 1,1),
+ MKCLRRAIL(0, 2,0),
+ MKEND
+};
+
+
+static const AiDefaultRoadBlock * const _road_default_block_data[] = {
+ &_roaddata_ai_0,
+ &_roaddata_ai_1,
+ &_roaddata_ai_2,
+ &_roaddata_ai_3,
+ &_roaddata_ai_4,
+ &_roaddata_ai_5,
+ &_roaddata_ai_6,
+ &_roaddata_ai_7,
+ NULL
+};
+
+#define MKAIR(a, b, c) {0, a, {b, c}}
+
+static const AiDefaultBlockData _airportdata_ai_0[] = {
+ MKAIR(1, 0, 0),
+ {1, 0, {0, 0}},
+};
+
+static const AiDefaultBlockData _airportdata_ai_1[] = {
+ MKAIR(0, 0, 0),
+ {1, 0, {0, 0}}
+};
+
+static const AiDefaultBlockData * const _airport_default_block_data[] = {
+ _airportdata_ai_0, // city airport
+ _airportdata_ai_1, // country airport
+ NULL
+};
diff --git a/src/table/animcursors.h b/src/table/animcursors.h
new file mode 100644
index 000000000..856527f93
--- /dev/null
+++ b/src/table/animcursors.h
@@ -0,0 +1,79 @@
+/* $Id$ */
+
+/** @file animcursors.h
+ * This file defines all the the animated cursors.
+ * Animated cursors consist of the number of sprites that are
+ * displayed in a round-robin manner. Each sprite also has a time
+ * associated that indicates how many ticks the corresponding sprite
+ * is to be displayed. Currently all this information is recorded in a single
+ * array. @todo This should be converted into an array of structs on the long run
+ * All these arrays end up in an array of pointers called _animcursors.
+ */
+
+/** Creates two array entries that define one
+ * status of the cursor.
+ * @param Sprite The Sprite to be displayed
+ * @param display_time The Number of ticks to display the sprite
+ */
+#define ANIM_CURSOR_LINE(Sprite, display_time) Sprite, display_time,
+
+/** This indicates the termination of the cursor list
+ */
+#define ANIM_CURSOR_END() 0xFFFF
+
+/** Animated cursor elements for demolishion
+ */
+static const CursorID _demolish_animcursor[] = {
+ ANIM_CURSOR_LINE(0x2C0, 8)
+ ANIM_CURSOR_LINE(0x2C1, 8)
+ ANIM_CURSOR_LINE(0x2C2, 8)
+ ANIM_CURSOR_LINE(0x2C3, 8)
+ ANIM_CURSOR_END()
+};
+
+/** Animated cursor elements for lower land
+ */
+static const CursorID _lower_land_animcursor[] = {
+ ANIM_CURSOR_LINE(0x2BB, 10)
+ ANIM_CURSOR_LINE(0x2BC, 10)
+ ANIM_CURSOR_LINE(0x2BD, 29)
+ ANIM_CURSOR_END()
+};
+
+/** Animated cursor elements for raise land
+ */
+static const CursorID _raise_land_animcursor[] = {
+ ANIM_CURSOR_LINE(0x2B8, 10)
+ ANIM_CURSOR_LINE(0x2B9, 10)
+ ANIM_CURSOR_LINE(0x2BA, 29)
+ ANIM_CURSOR_END()
+};
+
+/** Animated cursor elements for the goto icon
+ */
+static const CursorID _order_goto_animcursor[] = {
+ ANIM_CURSOR_LINE(0x2CC, 10)
+ ANIM_CURSOR_LINE(0x2CD, 10)
+ ANIM_CURSOR_LINE(0x2CE, 29)
+ ANIM_CURSOR_END()
+};
+
+/** Animated cursor elements for the build signal icon
+ */
+static const CursorID _build_signals_animcursor[] = {
+ ANIM_CURSOR_LINE(0x50C, 20)
+ ANIM_CURSOR_LINE(0x50D, 20)
+ ANIM_CURSOR_END()
+};
+
+/** This is an array of pointers to all the animated cursor
+ * definitions we have above. This is the only thing that is
+ * accessed directly from other files
+ */
+static const CursorID * const _animcursors[] = {
+ _demolish_animcursor,
+ _lower_land_animcursor,
+ _raise_land_animcursor,
+ _order_goto_animcursor,
+ _build_signals_animcursor
+};
diff --git a/src/table/autorail.h b/src/table/autorail.h
new file mode 100644
index 000000000..d94747ec1
--- /dev/null
+++ b/src/table/autorail.h
@@ -0,0 +1,72 @@
+/* $Id$ */
+
+/* Rail selection types (directions):
+ * / \ / \ / \ / \ / \ / \
+ * / /\ /\ \ /===\ / \ /| \ / |\
+ * \/ / \ \/ \ / \===/ \| / \ |/
+ * \ / \ / \ / \ / \ / \ /
+ * 0 1 2 3 4 5
+ */
+
+// mark invalid tiles red
+#define RED(c) c | PALETTE_SEL_TILE_RED
+
+// table maps each of the six rail directions and tileh combinations to a sprite
+// invalid entries are required to make sure that this array can be quickly accessed
+static const int _AutorailTilehSprite[][6] = {
+// type 0 1 2 3 4 5
+ { 0, 8, 16, 25, 34, 42 }, // tileh = 0
+ { 5, 13, RED(22), RED(31), 35, 42 }, // tileh = 1
+ { 5, 10, 16, 26, RED(38), RED(46) }, // tileh = 2
+ { 5, 9, RED(23), 26, 35, RED(46) }, // tileh = 3
+ { 2, 10, RED(19), RED(28), 34, 43 }, // tileh = 4
+ { 1, 9, 17, 26, 35, 43 }, // tileh = 5
+ { 1, 10, RED(20), 26, RED(38), 43 }, // tileh = 6
+ { 1, 9, 17, 26, 35, 43 }, // tileh = 7
+ { 2, 13, 17, 25, RED(40), RED(48) }, // tileh = 8
+ { 1, 13, 17, RED(32), 35, RED(48) }, // tileh = 9
+ { 1, 9, 17, 26, 35, 43 }, // tileh = 10
+ { 1, 9, 17, 26, 35, 43 }, // tileh = 11
+ { 2, 9, 17, RED(29), RED(40), 43 }, // tileh = 12
+ { 1, 9, 17, 26, 35, 43 }, // tileh = 13
+ { 1, 9, 17, 26, 35, 43 }, // tileh = 14
+ { 0, 1, 2, 3, 4, 5 }, // invalid (15)
+ { 0, 1, 2, 3, 4, 5 }, // invalid (16)
+ { 0, 1, 2, 3, 4, 5 }, // invalid (17)
+ { 0, 1, 2, 3, 4, 5 }, // invalid (18)
+ { 0, 1, 2, 3, 4, 5 }, // invalid (19)
+ { 0, 1, 2, 3, 4, 5 }, // invalid (20)
+ { 0, 1, 2, 3, 4, 5 }, // invalid (21)
+ { 0, 1, 2, 3, 4, 5 }, // invalid (22)
+ { 6, 11, 17, 27, RED(39), RED(47) }, // tileh = 23
+ { 0, 1, 2, 3, 4, 5 }, // invalid (24)
+ { 0, 1, 2, 3, 4, 5 }, // invalid (25)
+ { 0, 1, 2, 3, 4, 5 }, // invalid (26)
+ { 7, 15, RED(24), RED(33), 36, 44 }, // tileh = 27
+ { 0, 1, 2, 3, 4, 5 }, // invalid (28)
+ { 3, 14, 18, 26, RED(41), RED(49) }, // tileh = 29
+ { 4, 12, RED(21), RED(30), 37, 45 } // tileh = 30
+};
+#undef RED
+
+
+// maps each pixel of a tile (16x16) to a selection type
+// (0,0) is the top corner, (16,16) the bottom corner
+static const byte _AutorailPiece[][16] = {
+ { 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5 },
+ { 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5 },
+ { 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5 },
+ { 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5 },
+ { 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5 },
+ { 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5 },
+ { 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
+ { 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 },
+ { 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
+ { 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3 },
+ { 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3 },
+ { 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3 },
+ { 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3 },
+ { 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3 },
+ { 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3 }
+};
diff --git a/src/table/bridge_land.h b/src/table/bridge_land.h
new file mode 100644
index 000000000..8589c6e20
--- /dev/null
+++ b/src/table/bridge_land.h
@@ -0,0 +1,521 @@
+/* $Id$ */
+
+/** @file bridge_land.h This file contains all the sprites for bridges
+ * It consists of a number of arrays.
+ * <ul><li>_bridge_sprite_table_n_m. Defines all the sprites of a bridge besides the pylons.
+ * n defines the number of the bridge type, m the number of the section. the highest m for
+ * each bridge set defines the heads.<br>
+ * Sprites for middle secionts are arranged in groups of four, the elements are:
+ * <ol><li>Element containing the track. This element is logically behind the vehicle.</li>
+ * <li>Element containing the structure that is logically between the vehicle and the camera</li>
+ * <li>Element containing the pylons.</li></ol>
+ * First group is for railway in X direction, second for railway in Y direction, two groups each follow for road, monorail and maglev<p>
+ * <br>Elements for heads are arranged in groups of eight:
+ * <ol><li>X direction, north end, flat</li>
+ * <li>Y direction, north end, flat</li>
+ * <li>X direction, south end, flat</li>
+ * <li>Y direction, south end, flat</li>
+ * <li>X direction, north end, sloped</li>
+ * <li>Y direction, north end, sloped</li>
+ * <li>X direction, south end, sloped</li>
+ * <li>Y direction, south end, sloped</li></ol>
+ * This is repeated 4 times, for rail, road, monorail, maglev</li>
+ * </ul>
+ */
+
+static const PalSpriteID _bridge_sprite_table_2_0[] = {
+ 0x9C3, 0x9C7, 0x9C9, 0x0, 0x9C4, 0x9C8, 0x9CA, 0x0,
+ 0x9C5, 0x9C7, 0x9C9, 0x0, 0x9C6, 0x9C8, 0x9CA, 0x0,
+ 0x10E4, 0x9C7, 0x9C9, 0x0, 0x10E5, 0x9C8, 0x9CA, 0x0,
+ 0x110C, 0x9C7, 0x9C9, 0x0, 0x110D, 0x9C8, 0x9CA, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_2_1[] = {
+ 0x986, 0x988, 0x985, 0x987, 0x98A, 0x98C, 0x989, 0x98B,
+ 0x98E | PALETTE_TO_STRUCT_WHITE, 0x990 | PALETTE_TO_STRUCT_WHITE, 0x98D | PALETTE_TO_STRUCT_WHITE, 0x98F | PALETTE_TO_STRUCT_WHITE, 0x992 | PALETTE_TO_STRUCT_WHITE, 0x994 | PALETTE_TO_STRUCT_WHITE, 0x991 | PALETTE_TO_STRUCT_WHITE, 0x993 | PALETTE_TO_STRUCT_WHITE,
+ 0x10E7 | PALETTE_TO_STRUCT_WHITE, 0x10E9 | PALETTE_TO_STRUCT_WHITE, 0x10E6 | PALETTE_TO_STRUCT_WHITE, 0x10E8 | PALETTE_TO_STRUCT_WHITE, 0x10EB | PALETTE_TO_STRUCT_WHITE, 0x10ED | PALETTE_TO_STRUCT_WHITE, 0x10EA | PALETTE_TO_STRUCT_WHITE, 0x10EC | PALETTE_TO_STRUCT_WHITE,
+ 0x110F | PALETTE_TO_STRUCT_WHITE, 0x1111 | PALETTE_TO_STRUCT_WHITE, 0x110E | PALETTE_TO_STRUCT_WHITE, 0x1110 | PALETTE_TO_STRUCT_WHITE, 0x1113 | PALETTE_TO_STRUCT_WHITE, 0x1115 | PALETTE_TO_STRUCT_WHITE, 0x1112 | PALETTE_TO_STRUCT_WHITE, 0x1114 | PALETTE_TO_STRUCT_WHITE,
+};
+
+static const PalSpriteID _bridge_sprite_table_4_0[] = {
+ 0x9A9, 0x99F, 0x9B1, 0x0, 0x9A5, 0x997, 0x9AD, 0x0,
+ 0x99D, 0x99F, 0x9B1, 0x0, 0x995, 0x997, 0x9AD, 0x0,
+ 0x10F2, 0x99F, 0x9B1, 0x0, 0x10EE, 0x997, 0x9AD, 0x0,
+ 0x111A, 0x99F, 0x9B1, 0x0, 0x1116, 0x997, 0x9AD, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_4_1[] = {
+ 0x9AA, 0x9A0, 0x9B2, 0x0, 0x9A6, 0x998, 0x9AE, 0x0,
+ 0x99E, 0x9A0, 0x9B2, 0x0, 0x996, 0x998, 0x9AE, 0x0,
+ 0x10F3, 0x9A0, 0x9B2, 0x0, 0x10EF, 0x998, 0x9AE, 0x0,
+ 0x111B, 0x9A0, 0x9B2, 0x0, 0x1117, 0x998, 0x9AE, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_4_2[] = {
+ 0x9AC, 0x9A4, 0x9B4, 0x0, 0x9A8, 0x99C, 0x9B0, 0x0,
+ 0x9A2, 0x9A4, 0x9B4, 0x0, 0x99A, 0x99C, 0x9B0, 0x0,
+ 0x10F5, 0x9A4, 0x9B4, 0x0, 0x10F1, 0x99C, 0x9B0, 0x0,
+ 0x111D, 0x9A4, 0x9B4, 0x0, 0x1119, 0x99C, 0x9B0, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_4_3[] = {
+ 0x9AB, 0x9A3, 0x9B3, 0x0, 0x9A7, 0x99B, 0x9AF, 0x0,
+ 0x9A1, 0x9A3, 0x9B3, 0x0, 0x999, 0x99B, 0x9AF, 0x0,
+ 0x10F4, 0x9A3, 0x9B3, 0x0, 0x10F0, 0x99B, 0x9AF, 0x0,
+ 0x111C, 0x9A3, 0x9B3, 0x0, 0x1118, 0x99B, 0x9AF, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_4_4[] = {
+ 0x9B6, 0x9BA, 0x9BC, 0x0, 0x9B5, 0x9B9, 0x9BB, 0x0,
+ 0x9B8, 0x9BA, 0x9BC, 0x0, 0x9B7, 0x9B9, 0x9BB, 0x0,
+ 0x10F7, 0x9BA, 0x9BC, 0x0, 0x10F6, 0x9B9, 0x9BB, 0x0,
+ 0x111F, 0x9BA, 0x9BC, 0x0, 0x111E, 0x9B9, 0x9BB, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_4_5[] = {
+ 0x9BD, 0x9C1, 0x0, 0x0, 0x9BE, 0x9C2, 0x0, 0x0,
+ 0x9BF, 0x9C1, 0x0, 0x0, 0x9C0, 0x9C2, 0x0, 0x0,
+ 0x10F8, 0x9C1, 0x0, 0x0, 0x10F9, 0x9C2, 0x0, 0x0,
+ 0x1120, 0x9C1, 0x0, 0x0, 0x1121, 0x9C2, 0x0, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_4_6[] = {
+ 0x986, 0x988, 0x985, 0x987, 0x98A, 0x98C, 0x989, 0x98B,
+ 0x98E, 0x990, 0x98D, 0x98F, 0x992, 0x994, 0x991, 0x993,
+ 0x10E7, 0x10E9, 0x10E6, 0x10E8, 0x10EB, 0x10ED, 0x10EA, 0x10EC,
+ 0x110F, 0x1111, 0x110E, 0x1110, 0x1113, 0x1115, 0x1112, 0x1114,
+};
+
+static const PalSpriteID _bridge_sprite_table_5_0[] = {
+ 0x9A9 | PALETTE_TO_STRUCT_YELLOW, 0x99F | PALETTE_TO_STRUCT_YELLOW, 0x9B1 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x9A5 | PALETTE_TO_STRUCT_YELLOW, 0x997 | PALETTE_TO_STRUCT_YELLOW, 0x9AD | PALETTE_TO_STRUCT_YELLOW, 0x0,
+ 0x99D | PALETTE_TO_STRUCT_YELLOW, 0x99F | PALETTE_TO_STRUCT_YELLOW, 0x9B1 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x995 | PALETTE_TO_STRUCT_YELLOW, 0x997 | PALETTE_TO_STRUCT_YELLOW, 0x9AD | PALETTE_TO_STRUCT_YELLOW, 0x0,
+ 0x10F2 | PALETTE_TO_STRUCT_YELLOW, 0x99F | PALETTE_TO_STRUCT_YELLOW, 0x9B1 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x10EE | PALETTE_TO_STRUCT_YELLOW, 0x997 | PALETTE_TO_STRUCT_YELLOW, 0x9AD | PALETTE_TO_STRUCT_YELLOW, 0x0,
+ 0x111A | PALETTE_TO_STRUCT_YELLOW, 0x99F | PALETTE_TO_STRUCT_YELLOW, 0x9B1 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x1116 | PALETTE_TO_STRUCT_YELLOW, 0x997 | PALETTE_TO_STRUCT_YELLOW, 0x9AD | PALETTE_TO_STRUCT_YELLOW, 0x0,
+ SPR_PILLARS_BASE + 2
+};
+
+static const PalSpriteID _bridge_sprite_table_5_1[] = {
+ 0x9AA | PALETTE_TO_STRUCT_YELLOW, 0x9A0 | PALETTE_TO_STRUCT_YELLOW, 0x9B2 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x9A6 | PALETTE_TO_STRUCT_YELLOW, 0x998 | PALETTE_TO_STRUCT_YELLOW, 0x9AE | PALETTE_TO_STRUCT_YELLOW, 0x0,
+ 0x99E | PALETTE_TO_STRUCT_YELLOW, 0x9A0 | PALETTE_TO_STRUCT_YELLOW, 0x9B2 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x996 | PALETTE_TO_STRUCT_YELLOW, 0x998 | PALETTE_TO_STRUCT_YELLOW, 0x9AE | PALETTE_TO_STRUCT_YELLOW, 0x0,
+ 0x10F3 | PALETTE_TO_STRUCT_YELLOW, 0x9A0 | PALETTE_TO_STRUCT_YELLOW, 0x9B2 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x10EF | PALETTE_TO_STRUCT_YELLOW, 0x998 | PALETTE_TO_STRUCT_YELLOW, 0x9AE | PALETTE_TO_STRUCT_YELLOW, 0x0,
+ 0x111B | PALETTE_TO_STRUCT_YELLOW, 0x9A0 | PALETTE_TO_STRUCT_YELLOW, 0x9B2 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x1117 | PALETTE_TO_STRUCT_YELLOW, 0x998 | PALETTE_TO_STRUCT_YELLOW, 0x9AE | PALETTE_TO_STRUCT_YELLOW, 0x0,
+ SPR_PILLARS_BASE + 3
+};
+
+static const PalSpriteID _bridge_sprite_table_5_2[] = {
+ 0x9AC | PALETTE_TO_STRUCT_YELLOW, 0x9A4 | PALETTE_TO_STRUCT_YELLOW, 0x9B4 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x9A8 | PALETTE_TO_STRUCT_YELLOW, 0x99C | PALETTE_TO_STRUCT_YELLOW, 0x9B0 | PALETTE_TO_STRUCT_YELLOW, 0x0,
+ 0x9A2 | PALETTE_TO_STRUCT_YELLOW, 0x9A4 | PALETTE_TO_STRUCT_YELLOW, 0x9B4 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x99A | PALETTE_TO_STRUCT_YELLOW, 0x99C | PALETTE_TO_STRUCT_YELLOW, 0x9B0 | PALETTE_TO_STRUCT_YELLOW, 0x0,
+ 0x10F5 | PALETTE_TO_STRUCT_YELLOW, 0x9A4 | PALETTE_TO_STRUCT_YELLOW, 0x9B4 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x10F1 | PALETTE_TO_STRUCT_YELLOW, 0x99C | PALETTE_TO_STRUCT_YELLOW, 0x9B0 | PALETTE_TO_STRUCT_YELLOW, 0x0,
+ 0x111D | PALETTE_TO_STRUCT_YELLOW, 0x9A4 | PALETTE_TO_STRUCT_YELLOW, 0x9B4 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x1119 | PALETTE_TO_STRUCT_YELLOW, 0x99C | PALETTE_TO_STRUCT_YELLOW, 0x9B0 | PALETTE_TO_STRUCT_YELLOW, 0x0,
+ SPR_PILLARS_BASE + 3
+};
+
+static const PalSpriteID _bridge_sprite_table_5_3[] = {
+ 0x9AB | PALETTE_TO_STRUCT_YELLOW, 0x9A3 | PALETTE_TO_STRUCT_YELLOW, 0x9B3 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x9A7 | PALETTE_TO_STRUCT_YELLOW, 0x99B | PALETTE_TO_STRUCT_YELLOW, 0x9AF | PALETTE_TO_STRUCT_YELLOW, 0x0,
+ 0x9A1 | PALETTE_TO_STRUCT_YELLOW, 0x9A3 | PALETTE_TO_STRUCT_YELLOW, 0x9B3 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x999 | PALETTE_TO_STRUCT_YELLOW, 0x99B | PALETTE_TO_STRUCT_YELLOW, 0x9AF | PALETTE_TO_STRUCT_YELLOW, 0x0,
+ 0x10F4 | PALETTE_TO_STRUCT_YELLOW, 0x9A3 | PALETTE_TO_STRUCT_YELLOW, 0x9B3 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x10F0 | PALETTE_TO_STRUCT_YELLOW, 0x99B | PALETTE_TO_STRUCT_YELLOW, 0x9AF | PALETTE_TO_STRUCT_YELLOW, 0x0,
+ 0x111C | PALETTE_TO_STRUCT_YELLOW, 0x9A3 | PALETTE_TO_STRUCT_YELLOW, 0x9B3 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x1118 | PALETTE_TO_STRUCT_YELLOW, 0x99B | PALETTE_TO_STRUCT_YELLOW, 0x9AF | PALETTE_TO_STRUCT_YELLOW, 0x0,
+ SPR_PILLARS_BASE + 2
+};
+
+static const PalSpriteID _bridge_sprite_table_5_4[] = {
+ 0x9B6 | PALETTE_TO_STRUCT_YELLOW, 0x9BA | PALETTE_TO_STRUCT_YELLOW, 0x9BC | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x9B5 | PALETTE_TO_STRUCT_YELLOW, 0x9B9 | PALETTE_TO_STRUCT_YELLOW, 0x9BB | PALETTE_TO_STRUCT_YELLOW, 0x0,
+ 0x9B8 | PALETTE_TO_STRUCT_YELLOW, 0x9BA | PALETTE_TO_STRUCT_YELLOW, 0x9BC | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x9B7 | PALETTE_TO_STRUCT_YELLOW, 0x9B9 | PALETTE_TO_STRUCT_YELLOW, 0x9BB | PALETTE_TO_STRUCT_YELLOW, 0x0,
+ 0x10F7 | PALETTE_TO_STRUCT_YELLOW, 0x9BA | PALETTE_TO_STRUCT_YELLOW, 0x9BC | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x10F6 | PALETTE_TO_STRUCT_YELLOW, 0x9B9 | PALETTE_TO_STRUCT_YELLOW, 0x9BB | PALETTE_TO_STRUCT_YELLOW, 0x0,
+ 0x111F | PALETTE_TO_STRUCT_YELLOW, 0x9BA | PALETTE_TO_STRUCT_YELLOW, 0x9BC | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x111E | PALETTE_TO_STRUCT_YELLOW, 0x9B9 | PALETTE_TO_STRUCT_YELLOW, 0x9BB | PALETTE_TO_STRUCT_YELLOW, 0x0,
+ SPR_PILLARS_BASE + 5, 0x0, 0x0, 0x0, SPR_PILLARS_BASE + 4
+};
+
+static const PalSpriteID _bridge_sprite_table_5_5[] = {
+ 0x9BD | PALETTE_TO_STRUCT_YELLOW, 0x9C1 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x0, 0x9BE | PALETTE_TO_STRUCT_YELLOW, 0x9C2 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x0,
+ 0x9BF | PALETTE_TO_STRUCT_YELLOW, 0x9C1 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x0, 0x9C0 | PALETTE_TO_STRUCT_YELLOW, 0x9C2 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x0,
+ 0x10F8 | PALETTE_TO_STRUCT_YELLOW, 0x9C1 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x0, 0x10F9 | PALETTE_TO_STRUCT_YELLOW, 0x9C2 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x0,
+ 0x1120 | PALETTE_TO_STRUCT_YELLOW, 0x9C1 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x0, 0x1121 | PALETTE_TO_STRUCT_YELLOW, 0x9C2 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x0,
+ 0x0, SPR_PILLARS_BASE + 2
+};
+
+static const PalSpriteID _bridge_sprite_table_5_6[] = {
+ 0x986, 0x988, 0x985, 0x987, 0x98A, 0x98C, 0x989, 0x98B,
+ 0x98E | PALETTE_TO_STRUCT_YELLOW, 0x990 | PALETTE_TO_STRUCT_YELLOW, 0x98D | PALETTE_TO_STRUCT_YELLOW, 0x98F | PALETTE_TO_STRUCT_YELLOW, 0x992 | PALETTE_TO_STRUCT_YELLOW, 0x994 | PALETTE_TO_STRUCT_YELLOW, 0x991 | PALETTE_TO_STRUCT_YELLOW, 0x993 | PALETTE_TO_STRUCT_YELLOW,
+ 0x10E7 | PALETTE_TO_STRUCT_YELLOW, 0x10E9 | PALETTE_TO_STRUCT_YELLOW, 0x10E6 | PALETTE_TO_STRUCT_YELLOW, 0x10E8 | PALETTE_TO_STRUCT_YELLOW, 0x10EB | PALETTE_TO_STRUCT_YELLOW, 0x10ED | PALETTE_TO_STRUCT_YELLOW, 0x10EA | PALETTE_TO_STRUCT_YELLOW, 0x10EC | PALETTE_TO_STRUCT_YELLOW,
+ 0x110F | PALETTE_TO_STRUCT_YELLOW, 0x1111 | PALETTE_TO_STRUCT_YELLOW, 0x110E | PALETTE_TO_STRUCT_YELLOW, 0x1110 | PALETTE_TO_STRUCT_YELLOW, 0x1113 | PALETTE_TO_STRUCT_YELLOW, 0x1115 | PALETTE_TO_STRUCT_YELLOW, 0x1112 | PALETTE_TO_STRUCT_YELLOW, 0x1114 | PALETTE_TO_STRUCT_YELLOW,
+ 0x0, SPR_PILLARS_BASE + 2,
+};
+
+static const PalSpriteID _bridge_sprite_table_3_0[] = {
+ 0x9A9 | PALETTE_TO_STRUCT_CONCRETE, 0x99F | PALETTE_TO_STRUCT_CONCRETE, 0x9B1 | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x9A5 | PALETTE_TO_STRUCT_CONCRETE, 0x997 | PALETTE_TO_STRUCT_CONCRETE, 0x9AD | PALETTE_TO_STRUCT_CONCRETE, 0x0,
+ 0x99D | PALETTE_TO_STRUCT_CONCRETE, 0x99F | PALETTE_TO_STRUCT_CONCRETE, 0x9B1 | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x995 | PALETTE_TO_STRUCT_CONCRETE, 0x997 | PALETTE_TO_STRUCT_CONCRETE, 0x9AD | PALETTE_TO_STRUCT_CONCRETE, 0x0,
+ 0x10F2 | PALETTE_TO_STRUCT_CONCRETE, 0x99F | PALETTE_TO_STRUCT_CONCRETE, 0x9B1 | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x10EE | PALETTE_TO_STRUCT_CONCRETE, 0x997 | PALETTE_TO_STRUCT_CONCRETE, 0x9AD | PALETTE_TO_STRUCT_CONCRETE, 0x0,
+ 0x111A | PALETTE_TO_STRUCT_CONCRETE, 0x99F | PALETTE_TO_STRUCT_CONCRETE, 0x9B1 | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x1116 | PALETTE_TO_STRUCT_CONCRETE, 0x997 | PALETTE_TO_STRUCT_CONCRETE, 0x9AD | PALETTE_TO_STRUCT_CONCRETE, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_3_1[] = {
+ 0x9AA | PALETTE_TO_STRUCT_CONCRETE, 0x9A0 | PALETTE_TO_STRUCT_CONCRETE, 0x9B2 | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x9A6 | PALETTE_TO_STRUCT_CONCRETE, 0x998 | PALETTE_TO_STRUCT_CONCRETE, 0x9AE | PALETTE_TO_STRUCT_CONCRETE, 0x0,
+ 0x99E | PALETTE_TO_STRUCT_CONCRETE, 0x9A0 | PALETTE_TO_STRUCT_CONCRETE, 0x9B2 | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x996 | PALETTE_TO_STRUCT_CONCRETE, 0x998 | PALETTE_TO_STRUCT_CONCRETE, 0x9AE | PALETTE_TO_STRUCT_CONCRETE, 0x0,
+ 0x10F3 | PALETTE_TO_STRUCT_CONCRETE, 0x9A0 | PALETTE_TO_STRUCT_CONCRETE, 0x9B2 | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x10EF | PALETTE_TO_STRUCT_CONCRETE, 0x998 | PALETTE_TO_STRUCT_CONCRETE, 0x9AE | PALETTE_TO_STRUCT_CONCRETE, 0x0,
+ 0x111B | PALETTE_TO_STRUCT_CONCRETE, 0x9A0 | PALETTE_TO_STRUCT_CONCRETE, 0x9B2 | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x1117 | PALETTE_TO_STRUCT_CONCRETE, 0x998 | PALETTE_TO_STRUCT_CONCRETE, 0x9AE | PALETTE_TO_STRUCT_CONCRETE, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_3_2[] = {
+ 0x9AC | PALETTE_TO_STRUCT_CONCRETE, 0x9A4 | PALETTE_TO_STRUCT_CONCRETE, 0x9B4 | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x9A8 | PALETTE_TO_STRUCT_CONCRETE, 0x99C | PALETTE_TO_STRUCT_CONCRETE, 0x9B0 | PALETTE_TO_STRUCT_CONCRETE, 0x0,
+ 0x9A2 | PALETTE_TO_STRUCT_CONCRETE, 0x9A4 | PALETTE_TO_STRUCT_CONCRETE, 0x9B4 | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x99A | PALETTE_TO_STRUCT_CONCRETE, 0x99C | PALETTE_TO_STRUCT_CONCRETE, 0x9B0 | PALETTE_TO_STRUCT_CONCRETE, 0x0,
+ 0x10F5 | PALETTE_TO_STRUCT_CONCRETE, 0x9A4 | PALETTE_TO_STRUCT_CONCRETE, 0x9B4 | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x10F1 | PALETTE_TO_STRUCT_CONCRETE, 0x99C | PALETTE_TO_STRUCT_CONCRETE, 0x9B0 | PALETTE_TO_STRUCT_CONCRETE, 0x0,
+ 0x111D | PALETTE_TO_STRUCT_CONCRETE, 0x9A4 | PALETTE_TO_STRUCT_CONCRETE, 0x9B4 | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x1119 | PALETTE_TO_STRUCT_CONCRETE, 0x99C | PALETTE_TO_STRUCT_CONCRETE, 0x9B0 | PALETTE_TO_STRUCT_CONCRETE, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_3_3[] = {
+ 0x9AB | PALETTE_TO_STRUCT_CONCRETE, 0x9A3 | PALETTE_TO_STRUCT_CONCRETE, 0x9B3 | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x9A7 | PALETTE_TO_STRUCT_CONCRETE, 0x99B | PALETTE_TO_STRUCT_CONCRETE, 0x9AF | PALETTE_TO_STRUCT_CONCRETE, 0x0,
+ 0x9A1 | PALETTE_TO_STRUCT_CONCRETE, 0x9A3 | PALETTE_TO_STRUCT_CONCRETE, 0x9B3 | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x999 | PALETTE_TO_STRUCT_CONCRETE, 0x99B | PALETTE_TO_STRUCT_CONCRETE, 0x9AF | PALETTE_TO_STRUCT_CONCRETE, 0x0,
+ 0x10F4 | PALETTE_TO_STRUCT_CONCRETE, 0x9A3 | PALETTE_TO_STRUCT_CONCRETE, 0x9B3 | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x10F0 | PALETTE_TO_STRUCT_CONCRETE, 0x99B | PALETTE_TO_STRUCT_CONCRETE, 0x9AF | PALETTE_TO_STRUCT_CONCRETE, 0x0,
+ 0x111C | PALETTE_TO_STRUCT_CONCRETE, 0x9A3 | PALETTE_TO_STRUCT_CONCRETE, 0x9B3 | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x1118 | PALETTE_TO_STRUCT_CONCRETE, 0x99B | PALETTE_TO_STRUCT_CONCRETE, 0x9AF | PALETTE_TO_STRUCT_CONCRETE, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_3_4[] = {
+ 0x9B6 | PALETTE_TO_STRUCT_CONCRETE, 0x9BA | PALETTE_TO_STRUCT_CONCRETE, 0x9BC | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x9B5 | PALETTE_TO_STRUCT_CONCRETE, 0x9B9 | PALETTE_TO_STRUCT_CONCRETE, 0x9BB | PALETTE_TO_STRUCT_CONCRETE, 0x0,
+ 0x9B8 | PALETTE_TO_STRUCT_CONCRETE, 0x9BA | PALETTE_TO_STRUCT_CONCRETE, 0x9BC | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x9B7 | PALETTE_TO_STRUCT_CONCRETE, 0x9B9 | PALETTE_TO_STRUCT_CONCRETE, 0x9BB | PALETTE_TO_STRUCT_CONCRETE, 0x0,
+ 0x10F7 | PALETTE_TO_STRUCT_CONCRETE, 0x9BA | PALETTE_TO_STRUCT_CONCRETE, 0x9BC | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x10F6 | PALETTE_TO_STRUCT_CONCRETE, 0x9B9 | PALETTE_TO_STRUCT_CONCRETE, 0x9BB | PALETTE_TO_STRUCT_CONCRETE, 0x0,
+ 0x111F | PALETTE_TO_STRUCT_CONCRETE, 0x9BA | PALETTE_TO_STRUCT_CONCRETE, 0x9BC | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x111E | PALETTE_TO_STRUCT_CONCRETE, 0x9B9 | PALETTE_TO_STRUCT_CONCRETE, 0x9BB | PALETTE_TO_STRUCT_CONCRETE, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_3_5[] = {
+ 0x9BD | PALETTE_TO_STRUCT_CONCRETE, 0x9C1 | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x0, 0x9BE | PALETTE_TO_STRUCT_CONCRETE, 0x9C2 | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x0,
+ 0x9BF | PALETTE_TO_STRUCT_CONCRETE, 0x9C1 | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x0, 0x9C0 | PALETTE_TO_STRUCT_CONCRETE, 0x9C2 | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x0,
+ 0x10F8 | PALETTE_TO_STRUCT_CONCRETE, 0x9C1 | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x0, 0x10F9 | PALETTE_TO_STRUCT_CONCRETE, 0x9C2 | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x0,
+ 0x1120 | PALETTE_TO_STRUCT_CONCRETE, 0x9C1 | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x0, 0x1121 | PALETTE_TO_STRUCT_CONCRETE, 0x9C2 | PALETTE_TO_STRUCT_CONCRETE, 0x0, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_3_6[] = {
+ 0x986, 0x988, 0x985, 0x987, 0x98A, 0x98C, 0x989, 0x98B,
+ 0x98E | PALETTE_TO_STRUCT_CONCRETE, 0x990 | PALETTE_TO_STRUCT_CONCRETE, 0x98D | PALETTE_TO_STRUCT_CONCRETE, 0x98F | PALETTE_TO_STRUCT_CONCRETE, 0x992 | PALETTE_TO_STRUCT_CONCRETE, 0x994 | PALETTE_TO_STRUCT_CONCRETE, 0x991 | PALETTE_TO_STRUCT_CONCRETE, 0x993 | PALETTE_TO_STRUCT_CONCRETE,
+ 0x10E7 | PALETTE_TO_STRUCT_CONCRETE, 0x10E9 | PALETTE_TO_STRUCT_CONCRETE, 0x10E6 | PALETTE_TO_STRUCT_CONCRETE, 0x10E8 | PALETTE_TO_STRUCT_CONCRETE, 0x10EB | PALETTE_TO_STRUCT_CONCRETE, 0x10ED | PALETTE_TO_STRUCT_CONCRETE, 0x10EA | PALETTE_TO_STRUCT_CONCRETE, 0x10EC | PALETTE_TO_STRUCT_CONCRETE,
+ 0x110F | PALETTE_TO_STRUCT_CONCRETE, 0x1111 | PALETTE_TO_STRUCT_CONCRETE, 0x110E | PALETTE_TO_STRUCT_CONCRETE, 0x1110 | PALETTE_TO_STRUCT_CONCRETE, 0x1113 | PALETTE_TO_STRUCT_CONCRETE, 0x1115 | PALETTE_TO_STRUCT_CONCRETE, 0x1112 | PALETTE_TO_STRUCT_CONCRETE, 0x1114 | PALETTE_TO_STRUCT_CONCRETE,
+ 0x0, SPR_PILLARS_BASE + 2,
+};
+
+static const PalSpriteID _bridge_sprite_table_1_1[] = {
+ 0x986, 0x988, 0x985, 0x987, 0x98A, 0x98C, 0x989, 0x98B,
+ 0x98E | PALETTE_TO_STRUCT_RED, 0x990 | PALETTE_TO_STRUCT_RED, 0x98D | PALETTE_TO_STRUCT_RED, 0x98F | PALETTE_TO_STRUCT_RED, 0x992 | PALETTE_TO_STRUCT_RED, 0x994 | PALETTE_TO_STRUCT_RED, 0x991 | PALETTE_TO_STRUCT_RED, 0x993 | PALETTE_TO_STRUCT_RED,
+ 0x10E7 | PALETTE_TO_STRUCT_RED, 0x10E9 | PALETTE_TO_STRUCT_RED, 0x10E6 | PALETTE_TO_STRUCT_RED, 0x10E8 | PALETTE_TO_STRUCT_RED, 0x10EB | PALETTE_TO_STRUCT_RED, 0x10ED | PALETTE_TO_STRUCT_RED, 0x10EA | PALETTE_TO_STRUCT_RED, 0x10EC | PALETTE_TO_STRUCT_RED,
+ 0x110F | PALETTE_TO_STRUCT_RED, 0x1111 | PALETTE_TO_STRUCT_RED, 0x110E | PALETTE_TO_STRUCT_RED, 0x1110 | PALETTE_TO_STRUCT_RED, 0x1113 | PALETTE_TO_STRUCT_RED, 0x1115 | PALETTE_TO_STRUCT_RED, 0x1112 | PALETTE_TO_STRUCT_RED, 0x1114 | PALETTE_TO_STRUCT_RED,
+};
+
+static const PalSpriteID _bridge_sprite_table_6_0[] = {
+ 0x9CD, 0x9D9, 0x0, 0x0, 0x9CE, 0x9DA, 0x0, 0x0,
+ 0x9D3, 0x9D9, 0x0, 0x0, 0x9D4, 0x9DA, 0x0, 0x0,
+ 0x10FC, 0x9D9, 0x0, 0x0, 0x10FD, 0x9DA, 0x0, 0x0,
+ 0x1124, 0x9D9, 0x0, 0x0, 0x1125, 0x9DA, 0x0, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_6_1[] = {
+ 0x9CB, 0x9D7, 0x9DD, 0x0, 0x9D0, 0x9DC, 0x9E0, 0x0,
+ 0x9D1, 0x9D7, 0x9DD, 0x0, 0x9D6, 0x9DC, 0x9E0, 0x0,
+ 0x10FA, 0x9D7, 0x9DD, 0x0, 0x10FF, 0x9DC, 0x9E0, 0x0,
+ 0x1122, 0x9D7, 0x9DD, 0x0, 0x1127, 0x9DC, 0x9E0, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_6_2[] = {
+ 0x9CC, 0x9D8, 0x9DE, 0x0, 0x9CF, 0x9DB, 0x9DF, 0x0,
+ 0x9D2, 0x9D8, 0x9DE, 0x0, 0x9D5, 0x9DB, 0x9DF, 0x0,
+ 0x10FB, 0x9D8, 0x9DE, 0x0, 0x10FE, 0x9DB, 0x9DF, 0x0,
+ 0x1123, 0x9D8, 0x9DE, 0x0, 0x1126, 0x9DB, 0x9DF, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_6_3[] = {
+ 0x986, 0x988, 0x985, 0x987, 0x98A, 0x98C, 0x989, 0x98B,
+ 0x98E, 0x990, 0x98D, 0x98F, 0x992, 0x994, 0x991, 0x993,
+ 0x10E7, 0x10E9, 0x10E6, 0x10E8, 0x10EB, 0x10ED, 0x10EA, 0x10EC,
+ 0x110F, 0x1111, 0x110E, 0x1110, 0x1113, 0x1115, 0x1112, 0x1114,
+};
+
+static const PalSpriteID _bridge_sprite_table_7_0[] = {
+ 0x9CD | PALETTE_TO_STRUCT_BROWN, 0x9D9 | PALETTE_TO_STRUCT_BROWN, 0x0, 0x0, 0x9CE | PALETTE_TO_STRUCT_BROWN, 0x9DA | PALETTE_TO_STRUCT_BROWN, 0x0, 0x0,
+ 0x9D3 | PALETTE_TO_STRUCT_BROWN, 0x9D9 | PALETTE_TO_STRUCT_BROWN, 0x0, 0x0, 0x9D4 | PALETTE_TO_STRUCT_BROWN, 0x9DA | PALETTE_TO_STRUCT_BROWN, 0x0, 0x0,
+ 0x10FC | PALETTE_TO_STRUCT_BROWN, 0x9D9 | PALETTE_TO_STRUCT_BROWN, 0x0, 0x0, 0x10FD | PALETTE_TO_STRUCT_BROWN, 0x9DA | PALETTE_TO_STRUCT_BROWN, 0x0, 0x0,
+ 0x1124 | PALETTE_TO_STRUCT_BROWN, 0x9D9 | PALETTE_TO_STRUCT_BROWN, 0x0, 0x0, 0x1125 | PALETTE_TO_STRUCT_BROWN, 0x9DA | PALETTE_TO_STRUCT_BROWN, 0x0, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_7_1[] = {
+ 0x9CB | PALETTE_TO_STRUCT_BROWN, 0x9D7 | PALETTE_TO_STRUCT_BROWN, 0x9DD | PALETTE_TO_STRUCT_BROWN, 0x0, 0x9D0 | PALETTE_TO_STRUCT_BROWN, 0x9DC | PALETTE_TO_STRUCT_BROWN, 0x9E0 | PALETTE_TO_STRUCT_BROWN, 0x0,
+ 0x9D1 | PALETTE_TO_STRUCT_BROWN, 0x9D7 | PALETTE_TO_STRUCT_BROWN, 0x9DD | PALETTE_TO_STRUCT_BROWN, 0x0, 0x9D6 | PALETTE_TO_STRUCT_BROWN, 0x9DC | PALETTE_TO_STRUCT_BROWN, 0x9E0 | PALETTE_TO_STRUCT_BROWN, 0x0,
+ 0x10FA | PALETTE_TO_STRUCT_BROWN, 0x9D7 | PALETTE_TO_STRUCT_BROWN, 0x9DD | PALETTE_TO_STRUCT_BROWN, 0x0, 0x10FF | PALETTE_TO_STRUCT_BROWN, 0x9DC | PALETTE_TO_STRUCT_BROWN, 0x9E0 | PALETTE_TO_STRUCT_BROWN, 0x0,
+ 0x1122 | PALETTE_TO_STRUCT_BROWN, 0x9D7 | PALETTE_TO_STRUCT_BROWN, 0x9DD | PALETTE_TO_STRUCT_BROWN, 0x0, 0x1127 | PALETTE_TO_STRUCT_BROWN, 0x9DC | PALETTE_TO_STRUCT_BROWN, 0x9E0 | PALETTE_TO_STRUCT_BROWN, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_7_2[] = {
+ 0x9CC | PALETTE_TO_STRUCT_BROWN, 0x9D8 | PALETTE_TO_STRUCT_BROWN, 0x9DE | PALETTE_TO_STRUCT_BROWN, 0x0, 0x9CF | PALETTE_TO_STRUCT_BROWN, 0x9DB | PALETTE_TO_STRUCT_BROWN, 0x9DF | PALETTE_TO_STRUCT_BROWN, 0x0,
+ 0x9D2 | PALETTE_TO_STRUCT_BROWN, 0x9D8 | PALETTE_TO_STRUCT_BROWN, 0x9DE | PALETTE_TO_STRUCT_BROWN, 0x0, 0x9D5 | PALETTE_TO_STRUCT_BROWN, 0x9DB | PALETTE_TO_STRUCT_BROWN, 0x9DF | PALETTE_TO_STRUCT_BROWN, 0x0,
+ 0x10FB | PALETTE_TO_STRUCT_BROWN, 0x9D8 | PALETTE_TO_STRUCT_BROWN, 0x9DE | PALETTE_TO_STRUCT_BROWN, 0x0, 0x10FE | PALETTE_TO_STRUCT_BROWN, 0x9DB | PALETTE_TO_STRUCT_BROWN, 0x9DF | PALETTE_TO_STRUCT_BROWN, 0x0,
+ 0x1123 | PALETTE_TO_STRUCT_BROWN, 0x9D8 | PALETTE_TO_STRUCT_BROWN, 0x9DE | PALETTE_TO_STRUCT_BROWN, 0x0, 0x1126 | PALETTE_TO_STRUCT_BROWN, 0x9DB | PALETTE_TO_STRUCT_BROWN, 0x9DF | PALETTE_TO_STRUCT_BROWN, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_7_3[] = {
+ 0x986, 0x988, 0x985, 0x987, 0x98A, 0x98C, 0x989, 0x98B,
+ 0x98E | PALETTE_TO_STRUCT_BROWN, 0x990 | PALETTE_TO_STRUCT_BROWN, 0x98D | PALETTE_TO_STRUCT_BROWN, 0x98F | PALETTE_TO_STRUCT_BROWN, 0x992 | PALETTE_TO_STRUCT_BROWN, 0x994 | PALETTE_TO_STRUCT_BROWN, 0x991 | PALETTE_TO_STRUCT_BROWN, 0x993 | PALETTE_TO_STRUCT_BROWN,
+ 0x10E7 | PALETTE_TO_STRUCT_BROWN, 0x10E9 | PALETTE_TO_STRUCT_BROWN, 0x10E6 | PALETTE_TO_STRUCT_BROWN, 0x10E8 | PALETTE_TO_STRUCT_BROWN, 0x10EB | PALETTE_TO_STRUCT_BROWN, 0x10ED | PALETTE_TO_STRUCT_BROWN, 0x10EA | PALETTE_TO_STRUCT_BROWN, 0x10EC | PALETTE_TO_STRUCT_BROWN,
+ 0x110F | PALETTE_TO_STRUCT_BROWN, 0x1111 | PALETTE_TO_STRUCT_BROWN, 0x110E | PALETTE_TO_STRUCT_BROWN, 0x1110 | PALETTE_TO_STRUCT_BROWN, 0x1113 | PALETTE_TO_STRUCT_BROWN, 0x1115 | PALETTE_TO_STRUCT_BROWN, 0x1112 | PALETTE_TO_STRUCT_BROWN, 0x1114 | PALETTE_TO_STRUCT_BROWN,
+};
+
+static const PalSpriteID _bridge_sprite_table_8_0[] = {
+ 0x9CD | PALETTE_TO_STRUCT_RED, 0x9D9 | PALETTE_TO_STRUCT_RED, 0x0, 0x0, 0x9CE | PALETTE_TO_STRUCT_RED, 0x9DA | PALETTE_TO_STRUCT_RED, 0x0, 0x0,
+ 0x9D3 | PALETTE_TO_STRUCT_RED, 0x9D9 | PALETTE_TO_STRUCT_RED, 0x0, 0x0, 0x9D4 | PALETTE_TO_STRUCT_RED, 0x9DA | PALETTE_TO_STRUCT_RED, 0x0, 0x0,
+ 0x10FC | PALETTE_TO_STRUCT_RED, 0x9D9 | PALETTE_TO_STRUCT_RED, 0x0, 0x0, 0x10FD | PALETTE_TO_STRUCT_RED, 0x9DA | PALETTE_TO_STRUCT_RED, 0x0, 0x0,
+ 0x1124 | PALETTE_TO_STRUCT_RED, 0x9D9 | PALETTE_TO_STRUCT_RED, 0x0, 0x0, 0x1125 | PALETTE_TO_STRUCT_RED, 0x9DA | PALETTE_TO_STRUCT_RED, 0x0, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_8_1[] = {
+ 0x9CB | PALETTE_TO_STRUCT_RED, 0x9D7 | PALETTE_TO_STRUCT_RED, 0x9DD | PALETTE_TO_STRUCT_RED, 0x0, 0x9D0 | PALETTE_TO_STRUCT_RED, 0x9DC | PALETTE_TO_STRUCT_RED, 0x9E0 | PALETTE_TO_STRUCT_RED, 0x0,
+ 0x9D1 | PALETTE_TO_STRUCT_RED, 0x9D7 | PALETTE_TO_STRUCT_RED, 0x9DD | PALETTE_TO_STRUCT_RED, 0x0, 0x9D6 | PALETTE_TO_STRUCT_RED, 0x9DC | PALETTE_TO_STRUCT_RED, 0x9E0 | PALETTE_TO_STRUCT_RED, 0x0,
+ 0x10FA | PALETTE_TO_STRUCT_RED, 0x9D7 | PALETTE_TO_STRUCT_RED, 0x9DD | PALETTE_TO_STRUCT_RED, 0x0, 0x10FF | PALETTE_TO_STRUCT_RED, 0x9DC | PALETTE_TO_STRUCT_RED, 0x9E0 | PALETTE_TO_STRUCT_RED, 0x0,
+ 0x1122 | PALETTE_TO_STRUCT_RED, 0x9D7 | PALETTE_TO_STRUCT_RED, 0x9DD | PALETTE_TO_STRUCT_RED, 0x0, 0x1127 | PALETTE_TO_STRUCT_RED, 0x9DC | PALETTE_TO_STRUCT_RED, 0x9E0 | PALETTE_TO_STRUCT_RED, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_8_2[] = {
+ 0x9CC | PALETTE_TO_STRUCT_RED, 0x9D8 | PALETTE_TO_STRUCT_RED, 0x9DE | PALETTE_TO_STRUCT_RED, 0x0, 0x9CF | PALETTE_TO_STRUCT_RED, 0x9DB | PALETTE_TO_STRUCT_RED, 0x9DF | PALETTE_TO_STRUCT_RED, 0x0,
+ 0x9D2 | PALETTE_TO_STRUCT_RED, 0x9D8 | PALETTE_TO_STRUCT_RED, 0x9DE | PALETTE_TO_STRUCT_RED, 0x0, 0x9D5 | PALETTE_TO_STRUCT_RED, 0x9DB | PALETTE_TO_STRUCT_RED, 0x9DF | PALETTE_TO_STRUCT_RED, 0x0,
+ 0x10FB | PALETTE_TO_STRUCT_RED, 0x9D8 | PALETTE_TO_STRUCT_RED, 0x9DE | PALETTE_TO_STRUCT_RED, 0x0, 0x10FE | PALETTE_TO_STRUCT_RED, 0x9DB | PALETTE_TO_STRUCT_RED, 0x9DF | PALETTE_TO_STRUCT_RED, 0x0,
+ 0x1123 | PALETTE_TO_STRUCT_RED, 0x9D8 | PALETTE_TO_STRUCT_RED, 0x9DE | PALETTE_TO_STRUCT_RED, 0x0, 0x1126 | PALETTE_TO_STRUCT_RED, 0x9DB | PALETTE_TO_STRUCT_RED, 0x9DF | PALETTE_TO_STRUCT_RED, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_8_3[] = {
+ 0x986, 0x988, 0x985, 0x987, 0x98A, 0x98C, 0x989, 0x98B,
+ 0x98E | PALETTE_TO_STRUCT_RED, 0x990 | PALETTE_TO_STRUCT_RED, 0x98D | PALETTE_TO_STRUCT_RED, 0x98F | PALETTE_TO_STRUCT_RED, 0x992 | PALETTE_TO_STRUCT_RED, 0x994 | PALETTE_TO_STRUCT_RED, 0x991 | PALETTE_TO_STRUCT_RED, 0x993 | PALETTE_TO_STRUCT_RED,
+ 0x10E7 | PALETTE_TO_STRUCT_RED, 0x10E9 | PALETTE_TO_STRUCT_RED, 0x10E6 | PALETTE_TO_STRUCT_RED, 0x10E8 | PALETTE_TO_STRUCT_RED, 0x10EB | PALETTE_TO_STRUCT_RED, 0x10ED | PALETTE_TO_STRUCT_RED, 0x10EA | PALETTE_TO_STRUCT_RED, 0x10EC | PALETTE_TO_STRUCT_RED,
+ 0x110F | PALETTE_TO_STRUCT_RED, 0x1111 | PALETTE_TO_STRUCT_RED, 0x110E | PALETTE_TO_STRUCT_RED, 0x1110 | PALETTE_TO_STRUCT_RED, 0x1113 | PALETTE_TO_STRUCT_RED, 0x1115 | PALETTE_TO_STRUCT_RED, 0x1112 | PALETTE_TO_STRUCT_RED, 0x1114 | PALETTE_TO_STRUCT_RED,
+};
+
+static const PalSpriteID _bridge_sprite_table_0_0[] = {
+ 0x9F2, 0x9F6, 0x9F8, 0x0, 0x9F1, 0x9F5, 0x9F7, 0x0,
+ 0x9F4, 0x9F6, 0x9F8, 0x0, 0x9F3, 0x9F5, 0x9F7, 0x0,
+ 0x1109, 0x9F6, 0x9F8, 0x0, 0x1108, 0x9F5, 0x9F7, 0x0,
+ 0x1131, 0x9F6, 0x9F8, 0x0, 0x1130, 0x9F5, 0x9F7, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_0_1[] = {
+ 0x9EE, 0x9ED, 0x9F0, 0x9EF, 0x9EA, 0x9E9, 0x9EB, 0x9EC,
+ 0x9E6, 0x9E5, 0x9E8, 0x9E7, 0x9E2, 0x9E1, 0x9E3, 0x9E4,
+ 0x1105, 0x1104, 0x1107, 0x1106, 0x1101, 0x1100, 0x1102, 0x1103,
+ 0x112D, 0x112C, 0x112F, 0x112E, 0x1129, 0x1128, 0x112A, 0x112B,
+};
+
+static const PalSpriteID _bridge_sprite_table_1_0[] = {
+ 0x9BD | PALETTE_TO_STRUCT_RED, 0x9C1 | PALETTE_TO_STRUCT_RED, 0x9C9, 0x0, 0x9BE | PALETTE_TO_STRUCT_RED, 0x9C2 | PALETTE_TO_STRUCT_RED, 0x9CA, 0x0,
+ 0x9BF | PALETTE_TO_STRUCT_RED, 0x9C1 | PALETTE_TO_STRUCT_RED, 0x9C9, 0x0, 0x9C0 | PALETTE_TO_STRUCT_RED, 0x9C2 | PALETTE_TO_STRUCT_RED, 0x9CA, 0x0,
+ 0x10F8 | PALETTE_TO_STRUCT_RED, 0x9C1 | PALETTE_TO_STRUCT_RED, 0x9C9, 0x0, 0x10F9 | PALETTE_TO_STRUCT_RED, 0x9C2 | PALETTE_TO_STRUCT_RED, 0x9CA, 0x0,
+ 0x1120 | PALETTE_TO_STRUCT_RED, 0x9C1 | PALETTE_TO_STRUCT_RED, 0x9C9, 0x0, 0x1121 | PALETTE_TO_STRUCT_RED, 0x9C2 | PALETTE_TO_STRUCT_RED, 0x9CA, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_9_0[] = {
+ 0x9F9, 0x9FD, 0x9C9, 0x0, 0x9FA, 0x9FE, 0x9CA, 0x0,
+ 0x9FB, 0x9FD, 0x9C9, 0x0, 0x9FC, 0x9FE, 0x9CA, 0x0,
+ 0x110A, 0x9FD, 0x9C9, 0x0, 0x110B, 0x9FE, 0x9CA, 0x0,
+ 0x1132, 0x9FD, 0x9C9, 0x0, 0x1133, 0x9FE, 0x9CA, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_10_0[] = {
+ 0xA0B, 0xA01, 0x0, 0x0, 0xA0C, 0xA02, 0x0, 0x0,
+ 0xA11, 0xA01, 0x0, 0x0, 0xA12, 0xA02, 0x0, 0x0,
+ 0xA17, 0xA01, 0x0, 0x0, 0xA18, 0xA02, 0x0, 0x0,
+ 0xA1D, 0xA01, 0x0, 0x0, 0xA1E, 0xA02, 0x0, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_10_1[] = {
+ 0xA09, 0x9FF, 0xA05, 0x0, 0xA0E, 0xA04, 0xA08, 0x0,
+ 0xA0F, 0x9FF, 0xA05, 0x0, 0xA14, 0xA04, 0xA08, 0x0,
+ 0xA15, 0x9FF, 0xA05, 0x0, 0xA1A, 0xA04, 0xA08, 0x0,
+ 0xA1B, 0x9FF, 0xA05, 0x0, 0xA20, 0xA04, 0xA08, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_10_2[] = {
+ 0xA0A, 0xA00, 0xA06, 0x0, 0xA0D, 0xA03, 0xA07, 0x0,
+ 0xA10, 0xA00, 0xA06, 0x0, 0xA13, 0xA03, 0xA07, 0x0,
+ 0xA16, 0xA00, 0xA06, 0x0, 0xA19, 0xA03, 0xA07, 0x0,
+ 0xA1C, 0xA00, 0xA06, 0x0, 0xA1F, 0xA03, 0xA07, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_11_0[] = {
+ 0xA0B | PALETTE_TO_STRUCT_YELLOW, 0xA01 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x0, 0xA0C | PALETTE_TO_STRUCT_YELLOW, 0xA02 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x0,
+ 0xA11 | PALETTE_TO_STRUCT_YELLOW, 0xA01 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x0, 0xA12 | PALETTE_TO_STRUCT_YELLOW, 0xA02 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x0,
+ 0xA17 | PALETTE_TO_STRUCT_YELLOW, 0xA01 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x0, 0xA18 | PALETTE_TO_STRUCT_YELLOW, 0xA02 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x0,
+ 0xA1D | PALETTE_TO_STRUCT_YELLOW, 0xA01 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x0, 0xA1E | PALETTE_TO_STRUCT_YELLOW, 0xA02 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_11_1[] = {
+ 0xA09 | PALETTE_TO_STRUCT_YELLOW, 0x9FF | PALETTE_TO_STRUCT_YELLOW, 0xA05 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0xA0E | PALETTE_TO_STRUCT_YELLOW, 0xA04 | PALETTE_TO_STRUCT_YELLOW, 0xA08 | PALETTE_TO_STRUCT_YELLOW, 0x0,
+ 0xA0F | PALETTE_TO_STRUCT_YELLOW, 0x9FF | PALETTE_TO_STRUCT_YELLOW, 0xA05 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0xA14 | PALETTE_TO_STRUCT_YELLOW, 0xA04 | PALETTE_TO_STRUCT_YELLOW, 0xA08 | PALETTE_TO_STRUCT_YELLOW, 0x0,
+ 0xA15 | PALETTE_TO_STRUCT_YELLOW, 0x9FF | PALETTE_TO_STRUCT_YELLOW, 0xA05 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0xA1A | PALETTE_TO_STRUCT_YELLOW, 0xA04 | PALETTE_TO_STRUCT_YELLOW, 0xA08 | PALETTE_TO_STRUCT_YELLOW, 0x0,
+ 0xA1B | PALETTE_TO_STRUCT_YELLOW, 0x9FF | PALETTE_TO_STRUCT_YELLOW, 0xA05 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0xA20 | PALETTE_TO_STRUCT_YELLOW, 0xA04 | PALETTE_TO_STRUCT_YELLOW, 0xA08 | PALETTE_TO_STRUCT_YELLOW, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_11_2[] = {
+ 0xA0A | PALETTE_TO_STRUCT_YELLOW, 0xA00 | PALETTE_TO_STRUCT_YELLOW, 0xA06 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0xA0D | PALETTE_TO_STRUCT_YELLOW, 0xA03 | PALETTE_TO_STRUCT_YELLOW, 0xA07 | PALETTE_TO_STRUCT_YELLOW, 0x0,
+ 0xA10 | PALETTE_TO_STRUCT_YELLOW, 0xA00 | PALETTE_TO_STRUCT_YELLOW, 0xA06 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0xA13 | PALETTE_TO_STRUCT_YELLOW, 0xA03 | PALETTE_TO_STRUCT_YELLOW, 0xA07 | PALETTE_TO_STRUCT_YELLOW, 0x0,
+ 0xA16 | PALETTE_TO_STRUCT_YELLOW, 0xA00 | PALETTE_TO_STRUCT_YELLOW, 0xA06 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0xA19 | PALETTE_TO_STRUCT_YELLOW, 0xA03 | PALETTE_TO_STRUCT_YELLOW, 0xA07 | PALETTE_TO_STRUCT_YELLOW, 0x0,
+ 0xA1C | PALETTE_TO_STRUCT_YELLOW, 0xA00 | PALETTE_TO_STRUCT_YELLOW, 0xA06 | PALETTE_TO_STRUCT_YELLOW, 0x0, 0xA1F | PALETTE_TO_STRUCT_YELLOW, 0xA03 | PALETTE_TO_STRUCT_YELLOW, 0xA07 | PALETTE_TO_STRUCT_YELLOW, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_12_0[] = {
+ 0xA0B | PALETTE_TO_STRUCT_GREY, 0xA01 | PALETTE_TO_STRUCT_GREY, 0x0, 0x0, 0xA0C | PALETTE_TO_STRUCT_GREY, 0xA02 | PALETTE_TO_STRUCT_GREY, 0x0, 0x0,
+ 0xA11 | PALETTE_TO_STRUCT_GREY, 0xA01 | PALETTE_TO_STRUCT_GREY, 0x0, 0x0, 0xA12 | PALETTE_TO_STRUCT_GREY, 0xA02 | PALETTE_TO_STRUCT_GREY, 0x0, 0x0,
+ 0xA17 | PALETTE_TO_STRUCT_GREY, 0xA01 | PALETTE_TO_STRUCT_GREY, 0x0, 0x0, 0xA18 | PALETTE_TO_STRUCT_GREY, 0xA02 | PALETTE_TO_STRUCT_GREY, 0x0, 0x0,
+ 0xA1D | PALETTE_TO_STRUCT_GREY, 0xA01 | PALETTE_TO_STRUCT_GREY, 0x0, 0x0, 0xA1E | PALETTE_TO_STRUCT_GREY, 0xA02 | PALETTE_TO_STRUCT_GREY, 0x0, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_12_1[] = {
+ 0xA09 | PALETTE_TO_STRUCT_GREY, 0x9FF | PALETTE_TO_STRUCT_GREY, 0xA05 | PALETTE_TO_STRUCT_GREY, 0x0, 0xA0E | PALETTE_TO_STRUCT_GREY, 0xA04 | PALETTE_TO_STRUCT_GREY, 0xA08 | PALETTE_TO_STRUCT_GREY, 0x0,
+ 0xA0F | PALETTE_TO_STRUCT_GREY, 0x9FF | PALETTE_TO_STRUCT_GREY, 0xA05 | PALETTE_TO_STRUCT_GREY, 0x0, 0xA14 | PALETTE_TO_STRUCT_GREY, 0xA04 | PALETTE_TO_STRUCT_GREY, 0xA08 | PALETTE_TO_STRUCT_GREY, 0x0,
+ 0xA15 | PALETTE_TO_STRUCT_GREY, 0x9FF | PALETTE_TO_STRUCT_GREY, 0xA05 | PALETTE_TO_STRUCT_GREY, 0x0, 0xA1A | PALETTE_TO_STRUCT_GREY, 0xA04 | PALETTE_TO_STRUCT_GREY, 0xA08 | PALETTE_TO_STRUCT_GREY, 0x0,
+ 0xA1B | PALETTE_TO_STRUCT_GREY, 0x9FF | PALETTE_TO_STRUCT_GREY, 0xA05 | PALETTE_TO_STRUCT_GREY, 0x0, 0xA20 | PALETTE_TO_STRUCT_GREY, 0xA04 | PALETTE_TO_STRUCT_GREY, 0xA08 | PALETTE_TO_STRUCT_GREY, 0x0,
+};
+
+static const PalSpriteID _bridge_sprite_table_12_2[] = {
+ 0xA0A | PALETTE_TO_STRUCT_GREY, 0xA00 | PALETTE_TO_STRUCT_GREY, 0xA06 | PALETTE_TO_STRUCT_GREY, 0x0, 0xA0D | PALETTE_TO_STRUCT_GREY, 0xA03 | PALETTE_TO_STRUCT_GREY, 0xA07 | PALETTE_TO_STRUCT_GREY, 0x0,
+ 0xA10 | PALETTE_TO_STRUCT_GREY, 0xA00 | PALETTE_TO_STRUCT_GREY, 0xA06 | PALETTE_TO_STRUCT_GREY, 0x0, 0xA13 | PALETTE_TO_STRUCT_GREY, 0xA03 | PALETTE_TO_STRUCT_GREY, 0xA07 | PALETTE_TO_STRUCT_GREY, 0x0,
+ 0xA16 | PALETTE_TO_STRUCT_GREY, 0xA00 | PALETTE_TO_STRUCT_GREY, 0xA06 | PALETTE_TO_STRUCT_GREY, 0x0, 0xA19 | PALETTE_TO_STRUCT_GREY, 0xA03 | PALETTE_TO_STRUCT_GREY, 0xA07 | PALETTE_TO_STRUCT_GREY, 0x0,
+ 0xA1C | PALETTE_TO_STRUCT_GREY, 0xA00 | PALETTE_TO_STRUCT_GREY, 0xA06 | PALETTE_TO_STRUCT_GREY, 0x0, 0xA1F | PALETTE_TO_STRUCT_GREY, 0xA03 | PALETTE_TO_STRUCT_GREY, 0xA07 | PALETTE_TO_STRUCT_GREY, 0x0,
+};
+
+static const uint32 * const _bridge_sprite_table_2[] = {
+ _bridge_sprite_table_2_0,
+ _bridge_sprite_table_2_0,
+ _bridge_sprite_table_2_0,
+ _bridge_sprite_table_2_0,
+ _bridge_sprite_table_2_0,
+ _bridge_sprite_table_2_0,
+ _bridge_sprite_table_2_1,
+};
+
+static const uint32 * const _bridge_sprite_table_4[] = {
+ _bridge_sprite_table_4_0,
+ _bridge_sprite_table_4_1,
+ _bridge_sprite_table_4_2,
+ _bridge_sprite_table_4_3,
+ _bridge_sprite_table_4_4,
+ _bridge_sprite_table_4_5,
+ _bridge_sprite_table_4_6,
+};
+
+static const uint32 * const _bridge_sprite_table_5[] = {
+ _bridge_sprite_table_5_0,
+ _bridge_sprite_table_5_1,
+ _bridge_sprite_table_5_2,
+ _bridge_sprite_table_5_3,
+ _bridge_sprite_table_5_4,
+ _bridge_sprite_table_5_5,
+ _bridge_sprite_table_5_6,
+};
+
+static const uint32 * const _bridge_sprite_table_3[] = {
+ _bridge_sprite_table_3_0,
+ _bridge_sprite_table_3_1,
+ _bridge_sprite_table_3_2,
+ _bridge_sprite_table_3_3,
+ _bridge_sprite_table_3_4,
+ _bridge_sprite_table_3_5,
+ _bridge_sprite_table_3_6,
+};
+
+static const uint32 * const _bridge_sprite_table_6[] = {
+ _bridge_sprite_table_6_0,
+ _bridge_sprite_table_6_1,
+ _bridge_sprite_table_6_2,
+ _bridge_sprite_table_6_2,
+ _bridge_sprite_table_6_2,
+ _bridge_sprite_table_6_2,
+ _bridge_sprite_table_6_3,
+};
+
+static const uint32 * const _bridge_sprite_table_7[] = {
+ _bridge_sprite_table_7_0,
+ _bridge_sprite_table_7_1,
+ _bridge_sprite_table_7_2,
+ _bridge_sprite_table_7_2,
+ _bridge_sprite_table_7_2,
+ _bridge_sprite_table_7_2,
+ _bridge_sprite_table_7_3,
+};
+
+static const uint32 * const _bridge_sprite_table_8[] = {
+ _bridge_sprite_table_8_0,
+ _bridge_sprite_table_8_1,
+ _bridge_sprite_table_8_2,
+ _bridge_sprite_table_8_2,
+ _bridge_sprite_table_8_2,
+ _bridge_sprite_table_8_2,
+ _bridge_sprite_table_8_3,
+};
+
+static const uint32 * const _bridge_sprite_table_0[] = {
+ _bridge_sprite_table_0_0,
+ _bridge_sprite_table_0_0,
+ _bridge_sprite_table_0_0,
+ _bridge_sprite_table_0_0,
+ _bridge_sprite_table_0_0,
+ _bridge_sprite_table_0_0,
+ _bridge_sprite_table_0_1,
+};
+
+static const uint32 * const _bridge_sprite_table_1[] = {
+ _bridge_sprite_table_1_0,
+ _bridge_sprite_table_1_0,
+ _bridge_sprite_table_1_0,
+ _bridge_sprite_table_1_0,
+ _bridge_sprite_table_1_0,
+ _bridge_sprite_table_1_0,
+ _bridge_sprite_table_1_1,
+};
+
+static const uint32 * const _bridge_sprite_table_9[] = {
+ _bridge_sprite_table_9_0,
+ _bridge_sprite_table_9_0,
+ _bridge_sprite_table_9_0,
+ _bridge_sprite_table_9_0,
+ _bridge_sprite_table_9_0,
+ _bridge_sprite_table_9_0,
+ _bridge_sprite_table_4_6,
+};
+
+static const uint32 * const _bridge_sprite_table_10[] = {
+ _bridge_sprite_table_10_0,
+ _bridge_sprite_table_10_1,
+ _bridge_sprite_table_10_2,
+ _bridge_sprite_table_10_2,
+ _bridge_sprite_table_10_2,
+ _bridge_sprite_table_10_2,
+ _bridge_sprite_table_4_6,
+};
+
+static const uint32 * const _bridge_sprite_table_11[] = {
+ _bridge_sprite_table_11_0,
+ _bridge_sprite_table_11_1,
+ _bridge_sprite_table_11_2,
+ _bridge_sprite_table_11_2,
+ _bridge_sprite_table_11_2,
+ _bridge_sprite_table_11_2,
+ _bridge_sprite_table_5_6,
+};
+
+static const uint32 * const _bridge_sprite_table_12[] = {
+ _bridge_sprite_table_12_0,
+ _bridge_sprite_table_12_1,
+ _bridge_sprite_table_12_2,
+ _bridge_sprite_table_12_2,
+ _bridge_sprite_table_12_2,
+ _bridge_sprite_table_12_2,
+ _bridge_sprite_table_3_6,
+};
+
+static const uint32 * const * const _bridge_sprite_table[MAX_BRIDGES] = {
+ _bridge_sprite_table_0,
+ _bridge_sprite_table_1,
+ _bridge_sprite_table_2,
+ _bridge_sprite_table_3,
+ _bridge_sprite_table_4,
+ _bridge_sprite_table_5,
+ _bridge_sprite_table_6,
+ _bridge_sprite_table_7,
+ _bridge_sprite_table_8,
+ _bridge_sprite_table_9,
+ _bridge_sprite_table_10,
+ _bridge_sprite_table_11,
+ _bridge_sprite_table_12
+};
diff --git a/src/table/build_industry.h b/src/table/build_industry.h
new file mode 100644
index 000000000..c05cbe32d
--- /dev/null
+++ b/src/table/build_industry.h
@@ -0,0 +1,1600 @@
+/* $Id$ */
+
+
+
+#define MK(x,y, m) {{x, y}, m}
+
+#define MKEND {{-0x80, 0}, 0}
+
+static const IndustryTileTable _tile_table_coal_mine_0[] = {
+ MK(1,1, 0),
+ MK(1,2, 2),
+ MK(0,0, 5),
+ MK(1,0, 6),
+ MK(2,0, 3),
+ MK(2,2, 3),
+ MKEND
+};
+
+static const IndustryTileTable _tile_table_coal_mine_1[] = {
+ MK(1,1, 0),
+ MK(1,2, 2),
+ MK(2,0, 0),
+ MK(2,1, 2),
+ MK(1,0, 3),
+ MK(0,0, 3),
+ MK(0,1, 4),
+ MK(0,2, 4),
+ MK(2,2, 4),
+ MKEND
+};
+
+static const IndustryTileTable _tile_table_coal_mine_2[] = {
+ MK(0,0, 0),
+ MK(0,1, 2),
+ MK(0,2, 5),
+ MK(1,0, 3),
+ MK(1,1, 3),
+ MK(1,2, 6),
+ MKEND
+};
+
+static const IndustryTileTable _tile_table_coal_mine_3[] = {
+ MK(0,1, 0),
+ MK(0,2, 2),
+ MK(0,3, 4),
+ MK(1,0, 5),
+ MK(1,1, 0),
+ MK(1,2, 2),
+ MK(1,3, 3),
+ MK(2,0, 6),
+ MK(2,1, 4),
+ MK(2,2, 3),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_coal_mine[] = {
+ _tile_table_coal_mine_0,
+ _tile_table_coal_mine_1,
+ _tile_table_coal_mine_2,
+ _tile_table_coal_mine_3,
+};
+
+static const IndustryTileTable _tile_table_power_station_0[] = {
+ MK(0,0, 7),
+ MK(0,1, 9),
+ MK(1,0, 7),
+ MK(1,1, 8),
+ MK(2,0, 7),
+ MK(2,1, 8),
+ MK(3,0, 10),
+ MK(3,1, 10),
+ MKEND
+};
+
+static const IndustryTileTable _tile_table_power_station_1[] = {
+ MK(0,1, 7),
+ MK(0,2, 7),
+ MK(1,0, 8),
+ MK(1,1, 8),
+ MK(1,2, 7),
+ MK(2,0, 9),
+ MK(2,1, 10),
+ MK(2,2, 9),
+ MKEND
+};
+
+static const IndustryTileTable _tile_table_power_station_2[] = {
+ MK(0,0, 7),
+ MK(0,1, 7),
+ MK(1,0, 9),
+ MK(1,1, 8),
+ MK(2,0, 10),
+ MK(2,1, 9),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_power_station[] = {
+ _tile_table_power_station_0,
+ _tile_table_power_station_1,
+ _tile_table_power_station_2,
+};
+
+static const IndustryTileTable _tile_table_sawmill_0[] = {
+ MK(1,0, 14),
+ MK(1,1, 12),
+ MK(1,2, 11),
+ MK(2,0, 14),
+ MK(2,1, 13),
+ MK(0,0, 15),
+ MK(0,1, 15),
+ MK(0,2, 12),
+ MKEND
+};
+
+static const IndustryTileTable _tile_table_sawmill_1[] = {
+ MK(0,0, 15),
+ MK(0,1, 11),
+ MK(0,2, 14),
+ MK(1,0, 15),
+ MK(1,1, 13),
+ MK(1,2, 12),
+ MK(2,0, 11),
+ MK(2,1, 13),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_sawmill[] = {
+ _tile_table_sawmill_0,
+ _tile_table_sawmill_1,
+};
+
+static const IndustryTileTable _tile_table_forest_0[] = {
+ MK(0,0, 16),
+ MK(0,1, 16),
+ MK(0,2, 16),
+ MK(0,3, 16),
+ MK(1,0, 16),
+ MK(1,1, 16),
+ MK(1,2, 16),
+ MK(1,3, 16),
+ MK(2,0, 16),
+ MK(2,1, 16),
+ MK(2,2, 16),
+ MK(2,3, 16),
+ MK(3,0, 16),
+ MK(3,1, 16),
+ MK(3,2, 16),
+ MK(3,3, 16),
+ MK(1,4, 16),
+ MK(2,4, 16),
+ MKEND
+};
+
+static const IndustryTileTable _tile_table_forest_1[] = {
+ MK(0,0, 16),
+ MK(1,0, 16),
+ MK(2,0, 16),
+ MK(3,0, 16),
+ MK(4,0, 16),
+ MK(0,1, 16),
+ MK(1,1, 16),
+ MK(2,1, 16),
+ MK(3,1, 16),
+ MK(4,1, 16),
+ MK(0,2, 16),
+ MK(1,2, 16),
+ MK(2,2, 16),
+ MK(3,2, 16),
+ MK(4,2, 16),
+ MK(0,3, 16),
+ MK(1,3, 16),
+ MK(2,3, 16),
+ MK(3,3, 16),
+ MK(4,3, 16),
+ MK(1,4, 16),
+ MK(2,4, 16),
+ MK(3,4, 16),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_forest[] = {
+ _tile_table_forest_0,
+ _tile_table_forest_1,
+};
+
+static const IndustryTileTable _tile_table_oil_refinery_0[] = {
+ MK(0,0, 20),
+ MK(0,1, 21),
+ MK(0,2, 22),
+ MK(0,3, 21),
+ MK(1,0, 20),
+ MK(1,1, 19),
+ MK(1,2, 22),
+ MK(1,3, 20),
+ MK(2,1, 18),
+ MK(2,2, 18),
+ MK(2,3, 18),
+ MK(3,2, 18),
+ MK(3,3, 18),
+ MK(2,0, 23),
+ MK(3,1, 23),
+ MKEND
+};
+
+static const IndustryTileTable _tile_table_oil_refinery_1[] = {
+ MK(0,0, 18),
+ MK(0,1, 18),
+ MK(0,2, 21),
+ MK(0,3, 22),
+ MK(0,4, 20),
+ MK(1,0, 18),
+ MK(1,1, 18),
+ MK(1,2, 19),
+ MK(1,3, 20),
+ MK(2,0, 18),
+ MK(2,1, 18),
+ MK(2,2, 19),
+ MK(2,3, 22),
+ MK(1,4, 23),
+ MK(2,4, 23),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_oil_refinery[] = {
+ _tile_table_oil_refinery_0,
+ _tile_table_oil_refinery_1,
+};
+
+static const IndustryTileTable _tile_table_oil_rig_0[] = {
+ MK(0,0, 24),
+ MK(0,1, 24),
+ MK(0,2, 25),
+ MK(1,0, 26),
+ MK(1,1, 27),
+ MK(1,2, 28),
+ MK(-4,-5, 255),
+ MK(-4,-4, 255),
+ MK(-4,-3, 255),
+ MK(-4,-2, 255),
+ MK(-4,-1, 255),
+ MK(-4,0, 255),
+ MK(-4,1, 255),
+ MK(-4,2, 255),
+ MK(-4,3, 255),
+ MK(-4,4, 255),
+ MK(-4,5, 255),
+ MK(-3,5, 255),
+ MK(-2,5, 255),
+ MK(-1,5, 255),
+ MK(0,6, 255),
+ MK(1,6, 255),
+ MK(2,6, 255),
+ MK(3,6, 255),
+ MK(4,6, 255),
+ MK(5,6, 255),
+ MK(5,5, 255),
+ MK(5,4, 255),
+ MK(5,3, 255),
+ MK(5,2, 255),
+ MK(5,1, 255),
+ MK(5,0, 255),
+ MK(5,-1, 255),
+ MK(5,-2, 255),
+ MK(5,-3, 255),
+ MK(5,-4, 255),
+ MK(4,-4, 255),
+ MK(3,-4, 255),
+ MK(2,-4, 255),
+ MK(1,-4, 255),
+ MK(0,-4, 255),
+ MK(-1,-5, 255),
+ MK(-2,-5, 255),
+ MK(-3,-5, 255),
+ MK(2,0, 255),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_oil_rig[] = {
+ _tile_table_oil_rig_0,
+};
+
+static const IndustryTileTable _tile_table_factory_0[] = {
+ MK(0,0, 39),
+ MK(0,1, 40),
+ MK(1,0, 41),
+ MK(1,1, 42),
+ MK(0,2, 39),
+ MK(0,3, 40),
+ MK(1,2, 41),
+ MK(1,3, 42),
+ MK(2,1, 39),
+ MK(2,2, 40),
+ MK(3,1, 41),
+ MK(3,2, 42),
+ MKEND
+};
+
+static const IndustryTileTable _tile_table_factory_1[] = {
+ MK(0,0, 39),
+ MK(0,1, 40),
+ MK(1,0, 41),
+ MK(1,1, 42),
+ MK(2,0, 39),
+ MK(2,1, 40),
+ MK(3,0, 41),
+ MK(3,1, 42),
+ MK(1,2, 39),
+ MK(1,3, 40),
+ MK(2,2, 41),
+ MK(2,3, 42),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_factory[] = {
+ _tile_table_factory_0,
+ _tile_table_factory_1,
+};
+
+static const IndustryTileTable _tile_table_printing_works_0[] = {
+ MK(0,0, 43),
+ MK(0,1, 44),
+ MK(1,0, 45),
+ MK(1,1, 46),
+ MK(0,2, 43),
+ MK(0,3, 44),
+ MK(1,2, 45),
+ MK(1,3, 46),
+ MK(2,1, 43),
+ MK(2,2, 44),
+ MK(3,1, 45),
+ MK(3,2, 46),
+ MKEND
+};
+
+static const IndustryTileTable _tile_table_printing_works_1[] = {
+ MK(0,0, 43),
+ MK(0,1, 44),
+ MK(1,0, 45),
+ MK(1,1, 46),
+ MK(2,0, 43),
+ MK(2,1, 44),
+ MK(3,0, 45),
+ MK(3,1, 46),
+ MK(1,2, 43),
+ MK(1,3, 44),
+ MK(2,2, 45),
+ MK(2,3, 46),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_printing_works[] = {
+ _tile_table_printing_works_0,
+ _tile_table_printing_works_1,
+};
+
+static const IndustryTileTable _tile_table_steel_mill_0[] = {
+ MK(2,1, 52),
+ MK(2,2, 53),
+ MK(3,1, 54),
+ MK(3,2, 55),
+ MK(0,0, 56),
+ MK(1,0, 57),
+ MK(0,1, 56),
+ MK(1,1, 57),
+ MK(0,2, 56),
+ MK(1,2, 57),
+ MK(2,0, 56),
+ MK(3,0, 57),
+ MKEND
+};
+
+static const IndustryTileTable _tile_table_steel_mill_1[] = {
+ MK(0,0, 52),
+ MK(0,1, 53),
+ MK(1,0, 54),
+ MK(1,1, 55),
+ MK(2,0, 52),
+ MK(2,1, 53),
+ MK(3,0, 54),
+ MK(3,1, 55),
+ MK(0,2, 56),
+ MK(1,2, 57),
+ MK(2,2, 56),
+ MK(3,2, 57),
+ MK(1,3, 56),
+ MK(2,3, 57),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_steel_mill[] = {
+ _tile_table_steel_mill_0,
+ _tile_table_steel_mill_1,
+};
+
+static const IndustryTileTable _tile_table_farm_0[] = {
+ MK(1,0, 33),
+ MK(1,1, 34),
+ MK(1,2, 36),
+ MK(0,0, 37),
+ MK(0,1, 37),
+ MK(0,2, 36),
+ MK(2,0, 35),
+ MK(2,1, 38),
+ MK(2,2, 38),
+ MKEND
+};
+
+static const IndustryTileTable _tile_table_farm_1[] = {
+ MK(1,1, 33),
+ MK(1,2, 34),
+ MK(0,0, 35),
+ MK(0,1, 36),
+ MK(0,2, 36),
+ MK(0,3, 35),
+ MK(1,0, 37),
+ MK(1,3, 38),
+ MK(2,0, 37),
+ MK(2,1, 37),
+ MK(2,2, 38),
+ MK(2,3, 38),
+ MKEND
+};
+
+static const IndustryTileTable _tile_table_farm_2[] = {
+ MK(2,0, 33),
+ MK(2,1, 34),
+ MK(0,0, 36),
+ MK(0,1, 36),
+ MK(0,2, 37),
+ MK(0,3, 37),
+ MK(1,0, 35),
+ MK(1,1, 38),
+ MK(1,2, 38),
+ MK(1,3, 37),
+ MK(2,2, 37),
+ MK(2,3, 35),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_farm[] = {
+ _tile_table_farm_0,
+ _tile_table_farm_1,
+ _tile_table_farm_2,
+};
+
+static const IndustryTileTable _tile_table_copper_mine_0[] = {
+ MK(0,0, 47),
+ MK(0,1, 49),
+ MK(0,2, 51),
+ MK(1,0, 47),
+ MK(1,1, 49),
+ MK(1,2, 50),
+ MK(2,0, 51),
+ MK(2,1, 51),
+ MKEND
+};
+
+static const IndustryTileTable _tile_table_copper_mine_1[] = {
+ MK(0,0, 50),
+ MK(0,1, 47),
+ MK(0,2, 49),
+ MK(1,0, 47),
+ MK(1,1, 49),
+ MK(1,2, 51),
+ MK(2,0, 51),
+ MK(2,1, 47),
+ MK(2,2, 49),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_copper_mine[] = {
+ _tile_table_copper_mine_0,
+ _tile_table_copper_mine_1,
+};
+
+static const IndustryTileTable _tile_table_oil_well_0[] = {
+ MK(0,0, 29),
+ MK(1,0, 29),
+ MK(2,0, 29),
+ MK(0,1, 29),
+ MK(0,2, 29),
+ MKEND
+};
+
+static const IndustryTileTable _tile_table_oil_well_1[] = {
+ MK(0,0, 29),
+ MK(1,0, 29),
+ MK(1,1, 29),
+ MK(2,2, 29),
+ MK(2,3, 29),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_oil_well[] = {
+ _tile_table_oil_well_0,
+ _tile_table_oil_well_1,
+};
+
+static const IndustryTileTable _tile_table_bank_0[] = {
+ MK(0,0, 58),
+ MK(1,0, 59),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_bank[] = {
+ _tile_table_bank_0,
+};
+
+static const IndustryTileTable _tile_table_food_process_0[] = {
+ MK(0,0, 60),
+ MK(1,0, 60),
+ MK(2,0, 60),
+ MK(0,1, 60),
+ MK(1,1, 60),
+ MK(2,1, 60),
+ MK(0,2, 61),
+ MK(1,2, 61),
+ MK(2,2, 63),
+ MK(0,3, 62),
+ MK(1,3, 62),
+ MK(2,3, 63),
+ MKEND
+};
+
+static const IndustryTileTable _tile_table_food_process_1[] = {
+ MK(0,0, 61),
+ MK(1,0, 60),
+ MK(2,0, 61),
+ MK(3,0, 61),
+ MK(0,1, 62),
+ MK(1,1, 63),
+ MK(2,1, 63),
+ MK(3,1, 63),
+ MK(0,2, 60),
+ MK(1,2, 60),
+ MK(2,2, 60),
+ MK(3,2, 60),
+ MK(0,3, 62),
+ MK(1,3, 62),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_food_process[] = {
+ _tile_table_food_process_0,
+ _tile_table_food_process_1,
+};
+
+static const IndustryTileTable _tile_table_paper_mill_0[] = {
+ MK(0,0, 64),
+ MK(1,0, 65),
+ MK(2,0, 66),
+ MK(3,0, 67),
+ MK(0,1, 68),
+ MK(1,1, 69),
+ MK(2,1, 67),
+ MK(3,1, 67),
+ MK(0,2, 66),
+ MK(1,2, 71),
+ MK(2,2, 71),
+ MK(3,2, 70),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_paper_mill[] = {
+ _tile_table_paper_mill_0,
+};
+
+static const IndustryTileTable _tile_table_gold_mine_0[] = {
+ MK(0,0, 72),
+ MK(0,1, 73),
+ MK(0,2, 74),
+ MK(0,3, 75),
+ MK(1,0, 76),
+ MK(1,1, 77),
+ MK(1,2, 78),
+ MK(1,3, 79),
+ MK(2,0, 80),
+ MK(2,1, 81),
+ MK(2,2, 82),
+ MK(2,3, 83),
+ MK(3,0, 84),
+ MK(3,1, 85),
+ MK(3,2, 86),
+ MK(3,3, 87),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_gold_mine[] = {
+ _tile_table_gold_mine_0,
+};
+
+static const IndustryTileTable _tile_table_bank2_0[] = {
+ MK(0,0, 89),
+ MK(1,0, 90),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_bank2[] = {
+ _tile_table_bank2_0,
+};
+
+static const IndustryTileTable _tile_table_diamond_mine_0[] = {
+ MK(0,0, 91),
+ MK(0,1, 92),
+ MK(0,2, 93),
+ MK(1,0, 94),
+ MK(1,1, 95),
+ MK(1,2, 96),
+ MK(2,0, 97),
+ MK(2,1, 98),
+ MK(2,2, 99),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_diamond_mine[] = {
+ _tile_table_diamond_mine_0,
+};
+
+static const IndustryTileTable _tile_table_iron_mine_0[] = {
+ MK(0,0, 100),
+ MK(0,1, 101),
+ MK(0,2, 102),
+ MK(0,3, 103),
+ MK(1,0, 104),
+ MK(1,1, 105),
+ MK(1,2, 106),
+ MK(1,3, 107),
+ MK(2,0, 108),
+ MK(2,1, 109),
+ MK(2,2, 110),
+ MK(2,3, 111),
+ MK(3,0, 112),
+ MK(3,1, 113),
+ MK(3,2, 114),
+ MK(3,3, 115),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_iron_mine[] = {
+ _tile_table_iron_mine_0,
+};
+
+static const IndustryTileTable _tile_table_fruit_plantation_0[] = {
+ MK(0,0, 116),
+ MK(0,1, 116),
+ MK(0,2, 116),
+ MK(0,3, 116),
+ MK(1,0, 116),
+ MK(1,1, 116),
+ MK(1,2, 116),
+ MK(1,3, 116),
+ MK(2,0, 116),
+ MK(2,1, 116),
+ MK(2,2, 116),
+ MK(2,3, 116),
+ MK(3,0, 116),
+ MK(3,1, 116),
+ MK(3,2, 116),
+ MK(3,3, 116),
+ MK(4,0, 116),
+ MK(4,1, 116),
+ MK(4,2, 116),
+ MK(4,3, 116),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_fruit_plantation[] = {
+ _tile_table_fruit_plantation_0,
+};
+
+static const IndustryTileTable _tile_table_rubber_plantation_0[] = {
+ MK(0,0, 117),
+ MK(0,1, 117),
+ MK(0,2, 117),
+ MK(0,3, 117),
+ MK(1,0, 117),
+ MK(1,1, 117),
+ MK(1,2, 117),
+ MK(1,3, 117),
+ MK(2,0, 117),
+ MK(2,1, 117),
+ MK(2,2, 117),
+ MK(2,3, 117),
+ MK(3,0, 117),
+ MK(3,1, 117),
+ MK(3,2, 117),
+ MK(3,3, 117),
+ MK(4,0, 117),
+ MK(4,1, 117),
+ MK(4,2, 117),
+ MK(4,3, 117),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_rubber_plantation[] = {
+ _tile_table_rubber_plantation_0,
+};
+
+static const IndustryTileTable _tile_table_water_supply_0[] = {
+ MK(0,0, 118),
+ MK(0,1, 119),
+ MK(1,0, 118),
+ MK(1,1, 119),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_water_supply[] = {
+ _tile_table_water_supply_0,
+};
+
+static const IndustryTileTable _tile_table_water_tower_0[] = {
+ MK(0,0, 120),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_water_tower[] = {
+ _tile_table_water_tower_0,
+};
+
+static const IndustryTileTable _tile_table_factory2_0[] = {
+ MK(0,0, 121),
+ MK(0,1, 122),
+ MK(1,0, 123),
+ MK(1,1, 124),
+ MK(0,2, 121),
+ MK(0,3, 122),
+ MK(1,2, 123),
+ MK(1,3, 124),
+ MKEND
+};
+
+static const IndustryTileTable _tile_table_factory2_1[] = {
+ MK(0,0, 121),
+ MK(0,1, 122),
+ MK(1,0, 123),
+ MK(1,1, 124),
+ MK(2,0, 121),
+ MK(2,1, 122),
+ MK(3,0, 123),
+ MK(3,1, 124),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_factory2[] = {
+ _tile_table_factory2_0,
+ _tile_table_factory2_1,
+};
+
+static const IndustryTileTable _tile_table_farm2_0[] = {
+ MK(1,0, 33),
+ MK(1,1, 34),
+ MK(1,2, 36),
+ MK(0,0, 37),
+ MK(0,1, 37),
+ MK(0,2, 36),
+ MK(2,0, 35),
+ MK(2,1, 38),
+ MK(2,2, 38),
+ MKEND
+};
+
+static const IndustryTileTable _tile_table_farm2_1[] = {
+ MK(1,1, 33),
+ MK(1,2, 34),
+ MK(0,0, 35),
+ MK(0,1, 36),
+ MK(0,2, 36),
+ MK(0,3, 35),
+ MK(1,0, 37),
+ MK(1,3, 38),
+ MK(2,0, 37),
+ MK(2,1, 37),
+ MK(2,2, 38),
+ MK(2,3, 38),
+ MKEND
+};
+
+static const IndustryTileTable _tile_table_farm2_2[] = {
+ MK(2,0, 33),
+ MK(2,1, 34),
+ MK(0,0, 36),
+ MK(0,1, 36),
+ MK(0,2, 37),
+ MK(0,3, 37),
+ MK(1,0, 35),
+ MK(1,1, 38),
+ MK(1,2, 38),
+ MK(1,3, 37),
+ MK(2,2, 37),
+ MK(2,3, 35),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_farm2[] = {
+ _tile_table_farm2_0,
+ _tile_table_farm2_1,
+ _tile_table_farm2_2,
+};
+
+static const IndustryTileTable _tile_table_lumber_mill_0[] = {
+ MK(0,0, 125),
+ MK(0,1, 126),
+ MK(1,0, 127),
+ MK(1,1, 128),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_lumber_mill[] = {
+ _tile_table_lumber_mill_0,
+};
+
+static const IndustryTileTable _tile_table_cotton_candy_0[] = {
+ MK(0,0, 129),
+ MK(0,1, 129),
+ MK(0,2, 129),
+ MK(0,3, 129),
+ MK(1,0, 129),
+ MK(1,1, 129),
+ MK(1,2, 129),
+ MK(1,3, 129),
+ MK(2,0, 129),
+ MK(2,1, 129),
+ MK(2,2, 129),
+ MK(2,3, 129),
+ MK(3,0, 129),
+ MK(3,1, 129),
+ MK(3,2, 129),
+ MK(3,3, 129),
+ MK(1,4, 129),
+ MK(2,4, 129),
+ MKEND
+};
+
+static const IndustryTileTable _tile_table_cotton_candy_1[] = {
+ MK(0,0, 129),
+ MK(1,0, 129),
+ MK(2,0, 129),
+ MK(3,0, 129),
+ MK(4,0, 129),
+ MK(0,1, 129),
+ MK(1,1, 129),
+ MK(2,1, 129),
+ MK(3,1, 129),
+ MK(4,1, 129),
+ MK(0,2, 129),
+ MK(1,2, 129),
+ MK(2,2, 129),
+ MK(3,2, 129),
+ MK(4,2, 129),
+ MK(0,3, 129),
+ MK(1,3, 129),
+ MK(2,3, 129),
+ MK(3,3, 129),
+ MK(4,3, 129),
+ MK(1,4, 129),
+ MK(2,4, 129),
+ MK(3,4, 129),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_cotton_candy[] = {
+ _tile_table_cotton_candy_0,
+ _tile_table_cotton_candy_1,
+};
+
+static const IndustryTileTable _tile_table_candy_factory_0[] = {
+ MK(0,0, 131),
+ MK(0,1, 132),
+ MK(1,0, 133),
+ MK(1,1, 134),
+ MK(0,2, 131),
+ MK(0,3, 132),
+ MK(1,2, 133),
+ MK(1,3, 134),
+ MK(2,1, 131),
+ MK(2,2, 132),
+ MK(3,1, 133),
+ MK(3,2, 134),
+ MKEND
+};
+
+static const IndustryTileTable _tile_table_candy_factory_1[] = {
+ MK(0,0, 131),
+ MK(0,1, 132),
+ MK(1,0, 133),
+ MK(1,1, 134),
+ MK(2,0, 131),
+ MK(2,1, 132),
+ MK(3,0, 133),
+ MK(3,1, 134),
+ MK(1,2, 131),
+ MK(1,3, 132),
+ MK(2,2, 133),
+ MK(2,3, 134),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_candy_factory[] = {
+ _tile_table_candy_factory_0,
+ _tile_table_candy_factory_1,
+};
+
+static const IndustryTileTable _tile_table_battery_farm_0[] = {
+ MK(0,0, 135),
+ MK(0,1, 135),
+ MK(0,2, 135),
+ MK(0,3, 135),
+ MK(1,0, 135),
+ MK(1,1, 135),
+ MK(1,2, 135),
+ MK(1,3, 135),
+ MK(2,0, 135),
+ MK(2,1, 135),
+ MK(2,2, 135),
+ MK(2,3, 135),
+ MK(3,0, 135),
+ MK(3,1, 135),
+ MK(3,2, 135),
+ MK(3,3, 135),
+ MK(4,0, 135),
+ MK(4,1, 135),
+ MK(4,2, 135),
+ MK(4,3, 135),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_battery_farm[] = {
+ _tile_table_battery_farm_0,
+};
+
+static const IndustryTileTable _tile_table_cola_wells_0[] = {
+ MK(0,0, 137),
+ MK(0,1, 137),
+ MK(0,2, 137),
+ MK(1,0, 137),
+ MK(1,1, 137),
+ MK(1,2, 137),
+ MK(2,1, 137),
+ MK(2,2, 137),
+ MKEND
+};
+
+static const IndustryTileTable _tile_table_cola_wells_1[] = {
+ MK(0,1, 137),
+ MK(0,2, 137),
+ MK(0,3, 137),
+ MK(1,0, 137),
+ MK(1,1, 137),
+ MK(1,2, 137),
+ MK(2,1, 137),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_cola_wells[] = {
+ _tile_table_cola_wells_0,
+ _tile_table_cola_wells_1,
+};
+
+static const IndustryTileTable _tile_table_toy_shop_0[] = {
+ MK(0,0, 138),
+ MK(0,1, 139),
+ MK(1,0, 140),
+ MK(1,1, 141),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_toy_shop[] = {
+ _tile_table_toy_shop_0,
+};
+
+static const IndustryTileTable _tile_table_toy_factory_0[] = {
+ MK(0,0, 147),
+ MK(0,1, 142),
+ MK(1,0, 147),
+ MK(1,1, 143),
+ MK(2,0, 147),
+ MK(2,1, 144),
+ MK(3,0, 146),
+ MK(3,1, 145),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_toy_factory[] = {
+ _tile_table_toy_factory_0,
+};
+
+static const IndustryTileTable _tile_table_plastic_fountain_0[] = {
+ MK(0,0, 148),
+ MK(0,1, 151),
+ MK(0,2, 154),
+ MKEND
+};
+
+static const IndustryTileTable _tile_table_plastic_fountain_1[] = {
+ MK(0,0, 148),
+ MK(1,0, 151),
+ MK(2,0, 154),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_plastic_fountain[] = {
+ _tile_table_plastic_fountain_0,
+ _tile_table_plastic_fountain_1,
+};
+
+static const IndustryTileTable _tile_table_fizzy_drink_0[] = {
+ MK(0,0, 156),
+ MK(0,1, 157),
+ MK(1,0, 158),
+ MK(1,1, 159),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_fizzy_drink[] = {
+ _tile_table_fizzy_drink_0,
+};
+
+static const IndustryTileTable _tile_table_bubble_generator_0[] = {
+ MK(0,0, 163),
+ MK(0,1, 160),
+ MK(1,0, 163),
+ MK(1,1, 161),
+ MK(2,0, 163),
+ MK(2,1, 162),
+ MK(0,2, 163),
+ MK(0,3, 160),
+ MK(1,2, 163),
+ MK(1,3, 161),
+ MK(2,2, 163),
+ MK(2,3, 162),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_bubble_generator[] = {
+ _tile_table_bubble_generator_0,
+};
+
+static const IndustryTileTable _tile_table_toffee_quarry_0[] = {
+ MK(0,0, 164),
+ MK(1,0, 165),
+ MK(2,0, 166),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_toffee_quarry[] = {
+ _tile_table_toffee_quarry_0,
+};
+
+static const IndustryTileTable _tile_table_sugar_mine_0[] = {
+ MK(0,0, 167),
+ MK(0,1, 168),
+ MK(1,0, 169),
+ MK(1,1, 170),
+ MK(2,0, 171),
+ MK(2,1, 172),
+ MK(3,0, 173),
+ MK(3,1, 174),
+ MKEND
+};
+
+static const IndustryTileTable * const _tile_table_sugar_mine[] = {
+ _tile_table_sugar_mine_0,
+};
+
+#undef MK
+#undef MKEND
+
+/* Procedures that can be run to check whether an industry may
+ * build at location the given to the procedure */
+typedef enum CheckProcs {
+ CHECK_NOTHING = 0,
+ CHECK_FOREST = 1,
+ CHECK_REFINERY = 2,
+ CHECK_FARM = 3,
+ CHECK_PLANTATION = 4,
+ CHECK_WATER = 5,
+ CHECK_LUMBERMILL = 6,
+ CHECK_BUBBLEGEN = 7,
+ CHECK_OIL_RIG = 8,
+ CHECK_END,
+} CheckProc;
+
+#define MK(tbl, d, c1, c2, c3, proc, p1, r1, p2, r2, m, a1, a2, a3, pr, clim, in, s1, s2, s3) \
+ {tbl, lengthof(tbl), d, {c1, c2, c3}, proc, {p1, p2}, {r1, r2}, m, \
+ {a1, a2, a3}, pr, clim, in, s1, s2, s3}
+
+static const IndustrySpec _industry_specs[] = {
+ /* Format:
+ tile table cost multiplier
+ cannot be close to these industries (3 times) check proc
+ (produced cargo + rate) (twice) minimum cargo moved to station
+ 3 accepted cargo
+ industry life climate availability
+ industry name
+ messages : Closure production up production down */
+ MK(_tile_table_coal_mine, 210,
+ IT_POWER_STATION, IT_INVALID, IT_INVALID, CHECK_NOTHING,
+ CT_COAL, 15, CT_INVALID, 0, 5,
+ CT_INVALID, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_PRODUCTION, 1 << LT_NORMAL | 1 << LT_HILLY,
+ STR_4802_COAL_MINE,
+ STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4836_NEW_COAL_SEAM_FOUND_AT, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_power_station, 30,
+ IT_COAL_MINE, IT_INVALID, IT_INVALID, CHECK_NOTHING,
+ CT_INVALID, 0, CT_INVALID, 0, 5,
+ CT_COAL, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_NOT_CLOSABLE, 1 << LT_NORMAL | 1 << LT_HILLY,
+ STR_4803_POWER_STATION,
+ STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_sawmill, 28,
+ IT_FOREST, IT_INVALID, IT_INVALID, CHECK_NOTHING,
+ CT_GOODS, 0, CT_INVALID, 0, 5,
+ CT_WOOD, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_CLOSABLE, 1 << LT_NORMAL,
+ STR_4804_SAWMILL,
+ STR_4833_SUPPLY_PROBLEMS_CAUSE_TO, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_forest, 200,
+ IT_SAWMILL, IT_PAPER_MILL, IT_INVALID, CHECK_FOREST,
+ CT_WOOD, 13, CT_INVALID, 0, 30,
+ CT_INVALID, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_PRODUCTION, 1 << LT_NORMAL | 1 << LT_HILLY,
+ STR_4805_FOREST,
+ STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_483A_INSECT_INFESTATION_CAUSES),
+
+ MK(_tile_table_oil_refinery, 31,
+ IT_OIL_RIG, IT_INVALID, IT_INVALID, CHECK_REFINERY,
+ CT_GOODS, 0, CT_INVALID, 0, 5,
+ CT_OIL, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_CLOSABLE, 1 << LT_NORMAL | 1 << LT_HILLY | 1 << LT_DESERT,
+ STR_4806_OIL_REFINERY,
+ STR_4833_SUPPLY_PROBLEMS_CAUSE_TO, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_oil_rig, 240,
+ IT_OIL_REFINERY, IT_INVALID, IT_INVALID, CHECK_OIL_RIG,
+ CT_OIL, 15, CT_PASSENGERS, 2, 5,
+ CT_INVALID, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_PRODUCTION, 1 << LT_NORMAL,
+ STR_4807_OIL_RIG,
+ STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4837_NEW_OIL_RESERVES_FOUND, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_factory, 26,
+ IT_FARM, IT_STEEL_MILL, IT_INVALID, CHECK_NOTHING,
+ CT_GOODS, 0, CT_INVALID, 0, 5,
+ CT_LIVESTOCK, CT_GRAIN, CT_STEEL,
+ INDUSTRYLIFE_CLOSABLE, 1 << LT_NORMAL,
+ STR_4808_FACTORY,
+ STR_4833_SUPPLY_PROBLEMS_CAUSE_TO, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_printing_works, 26,
+ IT_PAPER_MILL, IT_INVALID, IT_INVALID, CHECK_NOTHING,
+ CT_GOODS, 0, CT_INVALID, 0, 5,
+ CT_PAPER, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_CLOSABLE, 1 << LT_HILLY,
+ STR_4809_PRINTING_WORKS,
+ STR_4833_SUPPLY_PROBLEMS_CAUSE_TO, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_steel_mill, 27,
+ IT_IRON_MINE, IT_FACTORY, IT_INVALID, CHECK_NOTHING,
+ CT_STEEL, 0, CT_INVALID, 0, 5,
+ CT_IRON_ORE, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_CLOSABLE, 1 << LT_NORMAL,
+ STR_480A_STEEL_MILL,
+ STR_4833_SUPPLY_PROBLEMS_CAUSE_TO, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_farm, 250,
+ IT_FACTORY, IT_FOOD_PROCESS, IT_INVALID, CHECK_FARM,
+ CT_GRAIN, 10, CT_LIVESTOCK, 10, 5,
+ CT_INVALID, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_PRODUCTION, 1 << LT_NORMAL | 1 << LT_HILLY,
+ STR_480B_FARM,
+ STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4838_IMPROVED_FARMING_METHODS, STR_483A_INSECT_INFESTATION_CAUSES),
+
+ MK(_tile_table_copper_mine, 205,
+ IT_FACTORY_2, IT_INVALID, IT_INVALID, CHECK_NOTHING,
+ CT_COPPER_ORE, 10, CT_INVALID, 0, 5,
+ CT_INVALID, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_PRODUCTION, 1 << LT_DESERT,
+ STR_480C_COPPER_ORE_MINE,
+ STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_oil_well, 220,
+ IT_OIL_REFINERY, IT_INVALID, IT_INVALID, CHECK_NOTHING,
+ CT_OIL, 12, CT_INVALID, 0, 5,
+ CT_INVALID, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_PRODUCTION, 1 << LT_NORMAL | 1 << LT_HILLY | 1 << LT_DESERT,
+ STR_480D_OIL_WELLS,
+ STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4837_NEW_OIL_RESERVES_FOUND, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_bank, 193,
+ IT_BANK_TEMP, IT_INVALID, IT_INVALID, CHECK_NOTHING,
+ CT_VALUABLES, 6, CT_INVALID, 0, 5,
+ CT_VALUABLES, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_NOT_CLOSABLE, 1 << LT_NORMAL,
+ STR_480E_BANK,
+ STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_food_process, 26,
+ IT_FRUIT_PLANTATION, IT_FARM, IT_FARM_2, CHECK_NOTHING,
+ CT_FOOD, 0, CT_INVALID, 0, 5,
+ CT_FRUIT, CT_MAIZE, CT_INVALID,
+ INDUSTRYLIFE_CLOSABLE, 1 << LT_HILLY | 1 << LT_DESERT,
+ STR_480F_FOOD_PROCESSING_PLANT,
+ STR_4833_SUPPLY_PROBLEMS_CAUSE_TO, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_paper_mill, 28,
+ IT_FOREST, IT_PRINTING_WORKS, IT_INVALID, CHECK_NOTHING,
+ CT_PAPER, 0, CT_INVALID, 0, 5,
+ CT_WOOD, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_CLOSABLE, 1 << LT_HILLY,
+ STR_4810_PAPER_MILL,
+ STR_4833_SUPPLY_PROBLEMS_CAUSE_TO, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_gold_mine, 208,
+ IT_BANK_TROPIC_ARCTIC, IT_INVALID, IT_INVALID, CHECK_NOTHING,
+ CT_GOLD, 7, CT_INVALID, 0, 5,
+ CT_INVALID, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_PRODUCTION, 1 << LT_DESERT,
+ STR_4811_GOLD_MINE,
+ STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_bank2, 19,
+ IT_GOLD_MINE, IT_DIAMOND_MINE, IT_INVALID, CHECK_NOTHING,
+ CT_INVALID, 0, CT_INVALID, 0, 5,
+ CT_GOLD, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_NOT_CLOSABLE, 1 << LT_HILLY | 1 << LT_DESERT,
+ STR_4812_BANK,
+ STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_diamond_mine, 213,
+ IT_BANK_TROPIC_ARCTIC, IT_INVALID, IT_INVALID, CHECK_NOTHING,
+ CT_DIAMONDS, 7, CT_INVALID, 0, 5,
+ CT_INVALID, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_PRODUCTION, 1 << LT_DESERT,
+ STR_4813_DIAMOND_MINE,
+ STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_iron_mine, 220,
+ IT_STEEL_MILL, IT_INVALID, IT_INVALID, CHECK_NOTHING,
+ CT_IRON_ORE, 10, CT_INVALID, 0, 5,
+ CT_INVALID, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_PRODUCTION, 1 << LT_NORMAL,
+ STR_4814_IRON_ORE_MINE,
+ STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_fruit_plantation, 225,
+ IT_FOOD_PROCESS, IT_INVALID, IT_INVALID, CHECK_PLANTATION,
+ CT_FRUIT, 10, CT_INVALID, 0, 15,
+ CT_INVALID, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_PRODUCTION, 1 << LT_DESERT,
+ STR_4815_FRUIT_PLANTATION,
+ STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4838_IMPROVED_FARMING_METHODS, STR_483A_INSECT_INFESTATION_CAUSES),
+
+ MK(_tile_table_rubber_plantation, 218,
+ IT_FACTORY_2, IT_INVALID, IT_INVALID, CHECK_PLANTATION,
+ CT_RUBBER, 10, CT_INVALID, 0, 15,
+ CT_INVALID, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_PRODUCTION, 1 << LT_DESERT,
+ STR_4816_RUBBER_PLANTATION,
+ STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4838_IMPROVED_FARMING_METHODS, STR_483A_INSECT_INFESTATION_CAUSES),
+
+ MK(_tile_table_water_supply, 199,
+ IT_WATER_TOWER, IT_INVALID, IT_INVALID, CHECK_WATER,
+ CT_WATER, 12, CT_INVALID, 0, 5,
+ CT_INVALID, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_PRODUCTION, 1 << LT_DESERT,
+ STR_4817_WATER_SUPPLY,
+ STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_water_tower, 14,
+ IT_WATER_SUPPLY, IT_INVALID, IT_INVALID, CHECK_WATER,
+ CT_INVALID, 0, CT_INVALID, 0, 5,
+ CT_WATER, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_NOT_CLOSABLE, 1 << LT_DESERT,
+ STR_4818_WATER_TOWER,
+ STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_factory2, 26,
+ IT_RUBBER_PLANTATION, IT_COPPER_MINE, IT_LUMBER_MILL, CHECK_PLANTATION,
+ CT_GOODS, 0, CT_INVALID, 0, 5,
+ CT_RUBBER, CT_COPPER_ORE, CT_WOOD,
+ INDUSTRYLIFE_CLOSABLE, 1 << LT_DESERT,
+ STR_4819_FACTORY,
+ STR_4833_SUPPLY_PROBLEMS_CAUSE_TO, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_farm2, 250,
+ IT_FOOD_PROCESS, IT_INVALID, IT_INVALID, CHECK_PLANTATION,
+ CT_MAIZE, 11, CT_INVALID, 0, 5,
+ CT_INVALID, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_PRODUCTION, 1 << LT_DESERT,
+ STR_481A_FARM,
+ STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4838_IMPROVED_FARMING_METHODS, STR_483A_INSECT_INFESTATION_CAUSES),
+
+ MK(_tile_table_lumber_mill, 17,
+ IT_FACTORY_2, IT_INVALID, IT_INVALID, CHECK_LUMBERMILL,
+ CT_WOOD, 0, CT_INVALID, 0, 5,
+ CT_INVALID, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_CLOSABLE, 1 << LT_DESERT,
+ STR_481B_LUMBER_MILL,
+ STR_4834_LACK_OF_NEARBY_TREES_CAUSES, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_cotton_candy, 195,
+ IT_CANDY_FACTORY, IT_INVALID, IT_INVALID, CHECK_NOTHING,
+ CT_COTTON_CANDY, 13, CT_INVALID, 0, 30,
+ CT_INVALID, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_PRODUCTION, 1 << LT_CANDY,
+ STR_481C_COTTON_CANDY_FOREST,
+ STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4838_IMPROVED_FARMING_METHODS, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_candy_factory, 26,
+ IT_COTTON_CANDY, IT_TOFFEE_QUARRY, IT_SUGAR_MINE, CHECK_NOTHING,
+ CT_CANDY, 0, CT_INVALID, 0, 5,
+ CT_SUGAR, CT_TOFFEE, CT_COTTON_CANDY,
+ INDUSTRYLIFE_CLOSABLE, 1 << LT_CANDY,
+ STR_481D_CANDY_FACTORY,
+ STR_4833_SUPPLY_PROBLEMS_CAUSE_TO, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_battery_farm, 187,
+ IT_TOY_FACTORY, IT_INVALID, IT_INVALID, CHECK_NOTHING,
+ CT_BATTERIES, 11, CT_INVALID, 0, 30,
+ CT_INVALID, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_PRODUCTION, 1 << LT_CANDY,
+ STR_481E_BATTERY_FARM,
+ STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4838_IMPROVED_FARMING_METHODS, STR_483A_INSECT_INFESTATION_CAUSES),
+
+ MK(_tile_table_cola_wells, 193,
+ IT_FIZZY_DRINK_FACTORY, IT_INVALID, IT_INVALID, CHECK_NOTHING,
+ CT_COLA, 12, CT_INVALID, 0, 5,
+ CT_INVALID, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_PRODUCTION, 1 << LT_CANDY,
+ STR_481F_COLA_WELLS,
+ STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_toy_shop, 17,
+ IT_TOY_FACTORY, IT_INVALID, IT_INVALID, CHECK_NOTHING,
+ CT_INVALID, 0, CT_INVALID, 0, 5,
+ CT_TOYS, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_NOT_CLOSABLE, 1 << LT_CANDY,
+ STR_4820_TOY_SHOP,
+ STR_4833_SUPPLY_PROBLEMS_CAUSE_TO, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_toy_factory, 20,
+ IT_PLASTIC_FOUNTAINS, IT_BATTERY_FARM, IT_TOY_SHOP, CHECK_NOTHING,
+ CT_TOYS, 0, CT_INVALID, 0, 5,
+ CT_PLASTIC, CT_BATTERIES, CT_INVALID,
+ INDUSTRYLIFE_CLOSABLE, 1 << LT_CANDY,
+ STR_4821_TOY_FACTORY,
+ STR_4833_SUPPLY_PROBLEMS_CAUSE_TO, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_plastic_fountain, 192,
+ IT_TOY_FACTORY, IT_INVALID, IT_INVALID, CHECK_NOTHING,
+ CT_PLASTIC, 14, CT_INVALID, 0, 5,
+ CT_INVALID, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_PRODUCTION, 1 << LT_CANDY,
+ STR_4822_PLASTIC_FOUNTAINS,
+ STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_fizzy_drink, 22,
+ IT_COLA_WELLS, IT_BUBBLE_GENERATOR, IT_INVALID, CHECK_NOTHING,
+ CT_FIZZY_DRINKS, 0, CT_INVALID, 0, 5,
+ CT_COLA, CT_BUBBLES, CT_INVALID,
+ INDUSTRYLIFE_CLOSABLE, 1 << LT_CANDY,
+ STR_4823_FIZZY_DRINK_FACTORY,
+ STR_4833_SUPPLY_PROBLEMS_CAUSE_TO, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_bubble_generator, 203,
+ IT_FIZZY_DRINK_FACTORY, IT_INVALID, IT_INVALID, CHECK_BUBBLEGEN,
+ CT_BUBBLES, 13, CT_INVALID, 0, 5,
+ CT_INVALID, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_PRODUCTION, 1 << LT_CANDY,
+ STR_4824_BUBBLE_GENERATOR,
+ STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_toffee_quarry, 213,
+ IT_CANDY_FACTORY, IT_INVALID, IT_INVALID, CHECK_NOTHING,
+ CT_TOFFEE, 10, CT_INVALID, 0, 5,
+ CT_INVALID, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_PRODUCTION, 1 << LT_CANDY,
+ STR_4825_TOFFEE_QUARRY,
+ STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50),
+
+ MK(_tile_table_sugar_mine, 210,
+ IT_CANDY_FACTORY, IT_INVALID, IT_INVALID, CHECK_NOTHING,
+ CT_SUGAR, 11, CT_INVALID, 0, 5,
+ CT_INVALID, CT_INVALID, CT_INVALID,
+ INDUSTRYLIFE_PRODUCTION, 1 << LT_CANDY,
+ STR_4826_SUGAR_MINE,
+ STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50),
+};
+#undef MK
+
+
+static const byte _industry_create_table_0[] = {
+ 4, 4,
+ 5, 3,
+ 5, 2,
+ 8, 0,
+ 5, 1,
+ 4, 11,
+ 5, 18,
+ 9, 9,
+ 5, 8,
+ 5, 6,
+ 0
+};
+
+static const byte _industry_create_table_1[] = {
+ 4, 4,
+ 5, 3,
+ 5, 14,
+ 8, 0,
+ 5, 1,
+ 5, 11,
+ 5, 13,
+ 9, 9,
+ 4, 15,
+ 5, 7,
+ 6, 16,
+ 0
+};
+
+static const byte _industry_create_table_2[] = {
+ 4, 4,
+ 5, 11,
+ 5, 16,
+ 4, 13,
+ 4, 17,
+ 4, 10,
+ 4, 19,
+ 4, 20,
+ 4, 21,
+ 8, 22,
+ 4, 13,
+ 4, 23,
+ 2, 24,
+ 0
+};
+
+static const byte _industry_create_table_3[] = {
+ 5, 26,
+ 5, 27,
+ 4, 28,
+ 5, 29,
+ 4, 30,
+ 5, 31,
+ 5, 32,
+ 4, 33,
+ 5, 34,
+ 5, 35,
+ 4, 36,
+ 0
+};
+
+static const byte * const _industry_create_table[4] = {
+ _industry_create_table_0,
+ _industry_create_table_1,
+ _industry_create_table_2,
+ _industry_create_table_3,
+};
+
+
+#define PAS CT_PASSENGERS
+
+#define COL CT_COAL
+#define RUB CT_RUBBER
+#define SUG CT_SUGAR
+
+#define MAL CT_MAIL
+
+#define OIL CT_OIL
+#define TOY CT_TOYS
+
+#define LIV CT_LIVESTOCK // Fruit too
+#define BAT CT_BATTERIES
+
+#define GRA CT_GRAIN
+#define WHT CT_WHEAT // Maize too
+#define TOF CT_TOFFEE
+
+#define WOD CT_WOOD
+#define CLA CT_COLA
+
+#define IRN CT_IRON_ORE
+#define COP CT_COPPER_ORE
+#define CCY CT_COTTON_CANDY
+
+#define STL CT_STEEL
+#define PAP CT_PAPER
+#define WAT CT_WATER
+#define BBL CT_BUBBLES
+
+#define VAL CT_VALUABLES
+#define GLD CT_GOLD // Diamonds too
+#define PLC CT_PLASTIC
+
+#define INV CT_INVALID
+
+static const CargoID _industry_section_accepts_1[] = {
+ INV, INV, INV, PAS, INV, INV, INV, INV,
+ PAS, INV, INV, PAS, PAS, PAS, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, PAS,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, PAS, PAS, INV, INV, INV, INV, GRA,
+ GRA, GRA, GRA, INV, INV, INV, INV, INV,
+ INV, INV, PAS, PAS, PAS, PAS, PAS, PAS,
+ PAS, PAS, PAS, PAS, WHT, WHT, WHT, WHT,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, COP, COP, COP, COP, INV, INV, INV,
+ INV, INV, INV, CCY, CCY, CCY, CCY, INV,
+ INV, INV, INV, INV, INV, INV, BAT, BAT,
+ BAT, BAT, BAT, BAT, INV, INV, INV, INV,
+ INV, INV, INV, INV, BBL, BBL, BBL, BBL,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV
+};
+
+
+static const CargoID _industry_section_accepts_2[] = {
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, STL,
+ STL, STL, STL, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, WOD, WOD, WOD, WOD, INV, INV, INV,
+ INV, INV, INV, TOF, TOF, TOF, TOF, INV,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV
+};
+
+static const CargoID _industry_section_accepts_3[] = {
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ COL, INV, INV, INV, INV, WOD, INV, INV,
+ INV, INV, INV, INV, OIL, INV, INV, INV,
+ PAS, MAL, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, LIV,
+ LIV, LIV, LIV, PAP, PAP, PAP, PAP, INV,
+ INV, INV, INV, INV, IRN, IRN, IRN, IRN,
+ IRN, IRN, VAL, VAL, LIV, LIV, LIV, LIV,
+ WOD, WOD, WOD, WOD, WOD, WOD, WOD, WOD,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, GLD, GLD, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ WAT, RUB, RUB, RUB, RUB, INV, INV, INV,
+ INV, INV, INV, SUG, SUG, SUG, SUG, INV,
+ INV, INV, TOY, TOY, TOY, TOY, PLC, PLC,
+ PLC, PLC, PLC, PLC, INV, INV, INV, INV,
+ INV, INV, INV, INV, CLA, CLA, CLA, CLA,
+ INV, INV, INV, INV, INV, INV, INV, INV,
+ INV, INV, INV, INV, INV, INV, INV
+};
+
+#undef PAS
+#undef COL
+#undef RUB
+#undef SUG
+#undef MAL
+#undef OIL
+#undef TOY
+#undef LIV
+#undef BAT
+#undef GRA
+#undef WHT
+#undef TOF
+#undef WOD
+#undef CLA
+#undef IRN
+#undef COP
+#undef CCY
+#undef STL
+#undef PAP
+#undef WAT
+#undef BBL
+#undef VAL
+#undef GLD
+#undef PLC
+#undef INV
diff --git a/src/table/clear_land.h b/src/table/clear_land.h
new file mode 100644
index 000000000..581c86855
--- /dev/null
+++ b/src/table/clear_land.h
@@ -0,0 +1,62 @@
+/* $Id$ */
+
+static const SpriteID _landscape_clear_sprites[8] = {
+ 0xFA0,
+ 0xFB3,
+ 0xFB4,
+ 0xFB5,
+ 0xFB6,
+ 0xFA0,
+ 0xFB3,
+ 0xFB4,
+};
+
+static const byte _fence_mod_by_tileh[32] = {
+ 0, 2, 4, 0, 0, 2, 4, 0,
+ 0, 2, 4, 0, 0, 2, 4, 0,
+ 0, 2, 4, 0, 0, 2, 4, 4,
+ 0, 2, 4, 2, 0, 2, 4, 0,
+};
+
+static const byte _fence_mod_by_tileh_2[32] = {
+ 1, 1, 5, 5, 3, 3, 1, 1,
+ 1, 1, 5, 5, 3, 3, 1, 1,
+ 1, 1, 5, 5, 3, 3, 1, 5,
+ 1, 1, 5, 5, 3, 3, 3, 1,
+};
+
+
+static const SpriteID _clear_land_fence_sprites_1[7] = {
+ 0xFFA,
+ 0x1000,
+ 0x1006,
+ 0x100C,
+ 0x1012,
+ 0x1018,
+};
+
+static const SpriteID _clear_land_sprites_1[16] = {
+ 0x101E,
+ 0x1031,
+ 0x1044,
+ 0x1057,
+ 0x106A,
+ 0x107D,
+ 0x1090,
+ 0x10A3,
+ 0x10B6,
+};
+
+static const SpriteID _clear_land_sprites_2[8] = {
+ 0x118D,
+ 0x11A0,
+ 0x11B3,
+ 0x11C6,
+};
+
+static const SpriteID _clear_land_sprites_3[8] = {
+ 0x118D,
+ 0x11A0,
+ 0x11B3,
+ 0x11C6,
+};
diff --git a/src/table/control_codes.h b/src/table/control_codes.h
new file mode 100644
index 000000000..a1ff42a89
--- /dev/null
+++ b/src/table/control_codes.h
@@ -0,0 +1,105 @@
+/* $Id$ */
+
+#ifndef CONTROL_CODES_H
+#define CONTROL_CODES_H
+
+/* List of string control codes used for string formatting, displaying, and
+ * by strgen to generate the language files. */
+
+enum {
+ SCC_CONTROL_START = 0xE000,
+ SCC_CONTROL_END = 0xE1FF,
+
+ SCC_SPRITE_START = 0xE200,
+ SCC_SPRITE_END = SCC_SPRITE_START + 0xFF,
+
+ /* Display control codes */
+ SCC_SETX = SCC_CONTROL_START,
+ SCC_SETXY,
+ SCC_TINYFONT,
+ SCC_BIGFONT,
+
+ /* Formatting control codes */
+ SCC_REVISION,
+ SCC_STATION_FEATURES,
+ SCC_INDUSTRY_NAME,
+ SCC_WAYPOINT_NAME,
+ SCC_STATION_NAME,
+ SCC_TOWN_NAME,
+
+ SCC_CURRENCY_COMPACT,
+ SCC_CURRENCY_COMPACT_64,
+ SCC_CURRENCY,
+ SCC_CURRENCY_64,
+
+ SCC_CARGO,
+ SCC_CARGO_SHORT,
+ SCC_POWER,
+ SCC_VOLUME,
+ SCC_VOLUME_SHORT,
+ SCC_WEIGHT,
+ SCC_WEIGHT_SHORT,
+ SCC_FORCE,
+ SCC_VELOCITY,
+
+ SCC_DATE_TINY,
+ SCC_DATE_SHORT,
+ SCC_DATE_LONG,
+
+ SCC_STRING1,
+ SCC_STRING2,
+ SCC_STRING3,
+ SCC_STRING4,
+ SCC_STRING5,
+
+ SCC_SKIP,
+ SCC_STRING,
+ SCC_COMMA,
+ SCC_NUM,
+
+ SCC_STRING_ID,
+ SCC_PLURAL_LIST,
+ SCC_GENDER_LIST,
+ SCC_GENDER_INDEX,
+ SCC_ARG_INDEX,
+ SCC_SETCASE,
+ SCC_SWITCH_CASE,
+
+ /* Colour codes */
+ SCC_BLUE,
+ SCC_SILVER,
+ SCC_GOLD,
+ SCC_RED,
+ SCC_PURPLE,
+ SCC_LTBROWN,
+ SCC_ORANGE,
+ SCC_GREEN,
+ SCC_YELLOW,
+ SCC_DKGREEN,
+ SCC_CREAM,
+ SCC_BROWN,
+ SCC_WHITE,
+ SCC_LTBLUE,
+ SCC_GRAY,
+ SCC_DKBLUE,
+ SCC_BLACK,
+
+ /* Special printable symbols.
+ * These are mapped to the original glyphs */
+ SCC_LESSTHAN = SCC_SPRITE_START + 0x3C,
+ SCC_GREATERTHAN = SCC_SPRITE_START + 0x3E,
+ SCC_UPARROW = SCC_SPRITE_START + 0x80,
+ SCC_SMALLUPARROW = SCC_SPRITE_START + 0x90,
+ SCC_SMALLDOWNARROW = SCC_SPRITE_START + 0x91,
+ SCC_TRAIN = SCC_SPRITE_START + 0x94,
+ SCC_LORRY = SCC_SPRITE_START + 0x95,
+ SCC_BUS = SCC_SPRITE_START + 0x96,
+ SCC_PLANE = SCC_SPRITE_START + 0x97,
+ SCC_SHIP = SCC_SPRITE_START + 0x98,
+ SCC_DOWNARROW = SCC_SPRITE_START + 0xAA,
+ SCC_CHECKMARK = SCC_SPRITE_START + 0xAC,
+ SCC_CROSS = SCC_SPRITE_START + 0xAD,
+ SCC_RIGHTARROW = SCC_SPRITE_START + 0xAF,
+};
+
+#endif /* CONTROL_CODES_H */
diff --git a/src/table/elrail_data.h b/src/table/elrail_data.h
new file mode 100644
index 000000000..1ed5751b4
--- /dev/null
+++ b/src/table/elrail_data.h
@@ -0,0 +1,445 @@
+/* $Id$ */
+/** @file elrail_data.h Stores all the data for overhead wire and pylon drawing.
+ * @see elrail.c */
+
+#ifndef ELRAIL_DATA_H
+#define ELRAIL_DATA_H
+
+/** Tile Location group.
+ * This defines whether the X and or Y coordinate of a tile is even */
+typedef enum TLG {
+ XEVEN_YEVEN = 0,
+ XEVEN_YODD = 1,
+ XODD_YEVEN = 2,
+ XODD_YODD = 3,
+ TLG_END
+} TLG;
+
+/** When determining the pylon configuration on the edge, two tiles are taken
+ * into account: the tile being drawn itself (the home tile, the one in
+ * ti->tile), and the neighbouring tile */
+typedef enum {
+ TS_HOME = 0,
+ TS_NEIGHBOUR = 1,
+
+ TS_END
+} TileSource;
+
+enum {
+ NUM_TRACKS_AT_PCP = 6
+};
+
+/** Which PPPs are possible at all on a given PCP */
+static byte AllowedPPPonPCP[DIAGDIR_END] = {
+ 1 << DIR_N | 1 << DIR_E | 1 << DIR_SE | 1 << DIR_S | 1 << DIR_W | 1 << DIR_NW,
+ 1 << DIR_N | 1 << DIR_NE | 1 << DIR_E | 1 << DIR_S | 1 << DIR_SW | 1 << DIR_W,
+ 1 << DIR_N | 1 << DIR_E | 1 << DIR_SE | 1 << DIR_S | 1 << DIR_W | 1 << DIR_NW,
+ 1 << DIR_N | 1 << DIR_NE | 1 << DIR_E | 1 << DIR_S | 1 << DIR_SW | 1 << DIR_W,
+};
+
+/** Which of the PPPs are inside the tile. For the two PPPs on the tile border
+ * the following system is used: if you rotate the PCP so that it is in the
+ * north, the eastern PPP belongs to the tile. */
+static byte OwnedPPPonPCP[DIAGDIR_END] = {
+ 1 << DIR_SE | 1 << DIR_S | 1 << DIR_SW | 1 << DIR_W,
+ 1 << DIR_N | 1 << DIR_SW | 1 << DIR_W | 1 << DIR_NW,
+ 1 << DIR_N | 1 << DIR_NE | 1 << DIR_E | 1 << DIR_NW,
+ 1 << DIR_NE | 1 << DIR_E | 1 << DIR_SE | 1 << DIR_S
+};
+
+/** Maps a track bit onto two PCP positions */
+static const DiagDirection PCPpositions[TRACK_END][2] = {
+ {DIAGDIR_NE, DIAGDIR_SW}, /* X */
+ {DIAGDIR_SE, DIAGDIR_NW}, /* Y */
+ {DIAGDIR_NW, DIAGDIR_NE}, /* UPPER */
+ {DIAGDIR_SE, DIAGDIR_SW}, /* LOWER */
+ {DIAGDIR_SW, DIAGDIR_NW}, /* LEFT */
+ {DIAGDIR_NE, DIAGDIR_SE}, /* RIGHT */
+};
+
+#define PCP_NOT_ON_TRACK 0xFF
+/** Preferred points of each trackbit. Those are the ones perpendicular to the
+ * track, plus the point in extension of the track (to mark end-of-track). PCPs
+ * which are not on either end of the track are fully preferred.
+ * @see PCPpositions */
+static byte PreferredPPPofTrackAtPCP[TRACK_END][DIAGDIR_END] = {
+ { /* X */
+ 1 << DIR_NE | 1 << DIR_SE | 1 << DIR_NW, /* NE */
+ PCP_NOT_ON_TRACK, /* SE */
+ 1 << DIR_SE | 1 << DIR_SW | 1 << DIR_NW, /* SW */
+ PCP_NOT_ON_TRACK /* NE */
+ }, { /* Y */
+ PCP_NOT_ON_TRACK,
+ 1 << DIR_NE | 1 << DIR_SE | 1 << DIR_SW,
+ PCP_NOT_ON_TRACK,
+ 1 << DIR_SW | 1 << DIR_NW | 1 << DIR_NE
+ }, { /* UPPER */
+ 1 << DIR_E | 1 << DIR_N | 1 << DIR_S,
+ PCP_NOT_ON_TRACK,
+ PCP_NOT_ON_TRACK,
+ 1 << DIR_W | 1 << DIR_N | 1 << DIR_S
+ }, { /* LOWER */
+ PCP_NOT_ON_TRACK,
+ 1 << DIR_E | 1 << DIR_N | 1 << DIR_S,
+ 1 << DIR_W | 1 << DIR_N | 1 << DIR_S,
+ PCP_NOT_ON_TRACK
+ }, { /* LEFT */
+ PCP_NOT_ON_TRACK,
+ PCP_NOT_ON_TRACK,
+ 1 << DIR_S | 1 << DIR_E | 1 << DIR_W,
+ 1 << DIR_N | 1 << DIR_E | 1 << DIR_W
+ }, { /* RIGHT */
+ 1 << DIR_N | 1 << DIR_E | 1 << DIR_W,
+ 1 << DIR_S | 1 << DIR_E | 1 << DIR_W,
+ PCP_NOT_ON_TRACK,
+ PCP_NOT_ON_TRACK
+ }
+};
+#undef PCP_NOT_ON_TRACK
+
+
+#define NUM_IGNORE_GROUPS 3
+#define IGNORE_NONE 0xFF
+/** In case we have a staight line, we place pylon only every two tiles,
+ * so there are certain tiles which we ignore. A straight line is found if
+ * we have exactly two PPPs. */
+static byte IgnoredPCP[NUM_IGNORE_GROUPS][TLG_END][DIAGDIR_END] = {
+ { /* Ignore group 1, X and Y tracks */
+ { /* X even, Y even */
+ IGNORE_NONE,
+ 1 << DIR_NE | 1 << DIR_SW,
+ 1 << DIR_NW | 1 << DIR_SE,
+ IGNORE_NONE
+ }, { /* X even, Y odd */
+ IGNORE_NONE,
+ IGNORE_NONE,
+ 1 << DIR_NW | 1 << DIR_SE,
+ 1 << DIR_NE | 1 << DIR_SW
+ }, { /* X odd, Y even */
+ 1 << DIR_NW | 1 << DIR_SE,
+ 1 << DIR_NE | 1 << DIR_SW,
+ IGNORE_NONE,
+ IGNORE_NONE
+ }, { /* X odd, Y odd */
+ 1 << DIR_NW | 1 << DIR_SE,
+ IGNORE_NONE,
+ IGNORE_NONE,
+ 1 << DIR_NE | 1 << DIR_SW
+ }
+ },
+ { /* Ignore group 2, LEFT and RIGHT tracks */
+ {
+ 1 << DIR_E | 1 << DIR_W,
+ IGNORE_NONE,
+ IGNORE_NONE,
+ 1 << DIR_E | 1 << DIR_W
+ }, {
+ IGNORE_NONE,
+ 1 << DIR_E | 1 << DIR_W,
+ 1 << DIR_E | 1 << DIR_W,
+ IGNORE_NONE
+ }, {
+ IGNORE_NONE,
+ 1 << DIR_E | 1 << DIR_W,
+ 1 << DIR_E | 1 << DIR_W,
+ IGNORE_NONE
+ }, {
+ 1 << DIR_E | 1 << DIR_W,
+ IGNORE_NONE,
+ IGNORE_NONE,
+ 1 << DIR_E | 1 << DIR_W
+ }
+ },
+ { /* Ignore group 3, UPPER and LOWER tracks */
+ {
+ 1 << DIR_N | 1 << DIR_S,
+ 1 << DIR_N | 1 << DIR_S,
+ IGNORE_NONE,
+ IGNORE_NONE
+ }, {
+ IGNORE_NONE,
+ IGNORE_NONE,
+ 1 << DIR_N | 1 << DIR_S,
+ 1 << DIR_N | 1 << DIR_S
+ }, {
+ IGNORE_NONE,
+ IGNORE_NONE,
+ 1 << DIR_N | 1 << DIR_S ,
+ 1 << DIR_N | 1 << DIR_S
+ }, {
+ 1 << DIR_N | 1 << DIR_S,
+ 1 << DIR_N | 1 << DIR_S,
+ IGNORE_NONE,
+ IGNORE_NONE
+ }
+ }
+};
+
+#undef NO_IGNORE
+
+/** Which pylons can definately NOT be built */
+static byte DisallowedPPPofTrackAtPCP[TRACK_END][DIAGDIR_END] = {
+ {1 << DIR_SW | 1 << DIR_NE, 0, 1 << DIR_SW | 1 << DIR_NE, 0 }, /* X */
+ {0, 1 << DIR_NW | 1 << DIR_SE, 0, 1 << DIR_NW | 1 << DIR_SE}, /* Y */
+ {1 << DIR_W | 1 << DIR_E, 0, 0, 1 << DIR_W | 1 << DIR_E }, /* UPPER */
+ {0, 1 << DIR_W | 1 << DIR_E, 1 << DIR_W | 1 << DIR_E, 0 }, /* LOWER */
+ {0, 0, 1 << DIR_S | 1 << DIR_N, 1 << DIR_N | 1 << DIR_S }, /* LEFT */
+ {1 << DIR_S | 1 << DIR_N, 1 << DIR_S | 1 << DIR_N, 0, 0, }, /* RIGHT */
+};
+
+/* This array stores which track bits can meet at a tile edge */
+static const Track TracksAtPCP[DIAGDIR_END][NUM_TRACKS_AT_PCP] = {
+ {TRACK_X, TRACK_X, TRACK_UPPER, TRACK_LOWER, TRACK_LEFT, TRACK_RIGHT},
+ {TRACK_Y, TRACK_Y, TRACK_UPPER, TRACK_LOWER, TRACK_LEFT, TRACK_RIGHT},
+ {TRACK_X, TRACK_X, TRACK_UPPER, TRACK_LOWER, TRACK_LEFT, TRACK_RIGHT},
+ {TRACK_Y, TRACK_Y, TRACK_UPPER, TRACK_LOWER, TRACK_LEFT, TRACK_RIGHT},
+};
+
+/* takes each of the 6 track bits from the array above and
+ * assigns it to the home tile or neighbour tile */
+static const TileSource TrackSourceTile[DIAGDIR_END][NUM_TRACKS_AT_PCP] = {
+ {TS_HOME, TS_NEIGHBOUR, TS_HOME , TS_NEIGHBOUR, TS_NEIGHBOUR, TS_HOME },
+ {TS_HOME, TS_NEIGHBOUR, TS_NEIGHBOUR, TS_HOME , TS_NEIGHBOUR, TS_HOME },
+ {TS_HOME, TS_NEIGHBOUR, TS_NEIGHBOUR, TS_HOME , TS_HOME , TS_NEIGHBOUR},
+ {TS_HOME, TS_NEIGHBOUR, TS_HOME , TS_NEIGHBOUR, TS_HOME , TS_NEIGHBOUR},
+};
+
+/* Several PPPs maybe exist, here they are sorted in order of preference. */
+static const Direction PPPorder[DIAGDIR_END][TLG_END][DIR_END] = { /* X - Y */
+ { /* PCP 0 */
+ {DIR_NE, DIR_NW, DIR_SE, DIR_SW, DIR_N, DIR_E, DIR_S, DIR_W}, /* evn - evn */
+ {DIR_NE, DIR_SE, DIR_SW, DIR_NW, DIR_S, DIR_W, DIR_N, DIR_E}, /* evn - odd */
+ {DIR_SW, DIR_NW, DIR_NE, DIR_SE, DIR_S, DIR_W, DIR_N, DIR_E}, /* odd - evn */
+ {DIR_SW, DIR_SE, DIR_NE, DIR_NW, DIR_N, DIR_E, DIR_S, DIR_W}, /* odd - odd */
+ }, {/* PCP 1 */
+ {DIR_NE, DIR_NW, DIR_SE, DIR_SW, DIR_S, DIR_E, DIR_N, DIR_W}, /* evn - evn */
+ {DIR_NE, DIR_SE, DIR_SW, DIR_NW, DIR_N, DIR_W, DIR_S, DIR_E}, /* evn - odd */
+ {DIR_SW, DIR_NW, DIR_NE, DIR_SE, DIR_N, DIR_W, DIR_S, DIR_E}, /* odd - evn */
+ {DIR_SW, DIR_SE, DIR_NE, DIR_NW, DIR_S, DIR_E, DIR_N, DIR_W}, /* odd - odd */
+ }, {/* PCP 2 */
+ {DIR_NE, DIR_NW, DIR_SE, DIR_SW, DIR_S, DIR_W, DIR_N, DIR_E}, /* evn - evn */
+ {DIR_NE, DIR_SE, DIR_SW, DIR_NW, DIR_N, DIR_E, DIR_S, DIR_W}, /* evn - odd */
+ {DIR_SW, DIR_NW, DIR_NE, DIR_SE, DIR_N, DIR_E, DIR_S, DIR_W}, /* odd - evn */
+ {DIR_SW, DIR_SE, DIR_NE, DIR_NW, DIR_S, DIR_W, DIR_N, DIR_E}, /* odd - odd */
+ }, {/* PCP 3 */
+ {DIR_NE, DIR_NW, DIR_SE, DIR_SW, DIR_N, DIR_W, DIR_S, DIR_E}, /* evn - evn */
+ {DIR_NE, DIR_SE, DIR_SW, DIR_NW, DIR_S, DIR_E, DIR_N, DIR_W}, /* evn - odd */
+ {DIR_SW, DIR_NW, DIR_NE, DIR_SE, DIR_S, DIR_E, DIR_N, DIR_W}, /* odd - evn */
+ {DIR_SW, DIR_SE, DIR_NE, DIR_NW, DIR_N, DIR_W, DIR_S, DIR_E}, /* odd - odd */
+ }
+};
+/* Geometric placement of the PCP relative to the tile origin */
+static const int8 x_pcp_offsets[DIAGDIR_END] = {0, 8, 15, 8};
+static const int8 y_pcp_offsets[DIAGDIR_END] = {8, 15, 8, 0};
+/* Geometric placement of the PPP relative to the PCP*/
+static const int8 x_ppp_offsets[DIR_END] = {-3, -4, -3, 0, 3, 4, 3, 0};
+static const int8 y_ppp_offsets[DIR_END] = {-3, 0, 3, 4, 3, 0, -3, -4};
+/* The type of pylon to draw at each PPP */
+static const SpriteID pylons_normal[] = {
+ SPR_PYLON_EW_N,
+ SPR_PYLON_Y_NE,
+ SPR_PYLON_NS_E,
+ SPR_PYLON_X_SE,
+ SPR_PYLON_EW_S,
+ SPR_PYLON_Y_SW,
+ SPR_PYLON_NS_W,
+ SPR_PYLON_X_NW
+};
+
+static const SpriteID pylons_bridge[] = {
+ SPR_PYLON_X_NW,
+ SPR_PYLON_X_SE,
+ SPR_PYLON_Y_NE,
+ SPR_PYLON_Y_SW
+};
+
+typedef struct {
+ SpriteID image;
+ int8 x_offset;
+ int8 y_offset;
+ int8 x_size;
+ int8 y_size;
+ int8 z_size;
+ int8 z_offset;
+} SortableSpriteStruct;
+
+enum {
+ /** Distance between wire and rail */
+ ELRAIL_ELEVATION = 8,
+ /** Corrects an off-by-one error in some places (tileh 12 and 9) (TODO -- find source of error) */
+ ELRAIL_ELEV_CORR = ELRAIL_ELEVATION + 1,
+ /** Wires that a draw one level higher than the north corner. */
+ ELRAIL_ELEVRAISE = ELRAIL_ELEVATION + TILE_HEIGHT
+};
+
+static const SortableSpriteStruct CatenarySpriteData[] = {
+/* X direction */
+ /* Flat tiles: */
+ /* Wires */
+ { SPR_WIRE_X_SW, 0, 8, 16, 1, 1, ELRAIL_ELEVATION }, //! 0: Wire in X direction, pylon on the SW end only
+ { SPR_WIRE_X_NE, 0, 8, 16, 1, 1, ELRAIL_ELEVATION }, //! 1: Wire in X direction, pylon on the NE end
+ { SPR_WIRE_X_SHORT, 0, 8, 16, 1, 1, ELRAIL_ELEVATION }, //! 2: Wire in X direction, pylon on both ends
+
+ /* "up" tiles */
+ /* Wires */
+ { SPR_WIRE_X_SW_UP, 0, 8, 16, 8, 1, ELRAIL_ELEVRAISE }, //! 3: Wire in X pitch up, pylon on the SW end only
+ { SPR_WIRE_X_NE_UP, 0, 8, 16, 8, 1, ELRAIL_ELEVRAISE }, //! 4: Wire in X pitch up, pylon on the NE end
+ { SPR_WIRE_X_SHORT_UP, 0, 8, 16, 8, 1, ELRAIL_ELEVRAISE }, //! 5: Wire in X pitch up, pylon on both ends
+
+ /* "down" tiles */
+ /* Wires */
+ { SPR_WIRE_X_SW_DOWN, 0, 8, 16, 8, 1, ELRAIL_ELEV_CORR }, //! 6: Wire in X pitch down, pylon on the SW end
+ { SPR_WIRE_X_NE_DOWN, 0, 8, 16, 8, 1, ELRAIL_ELEV_CORR }, //! 7: Wire in X pitch down, pylon on the NE end
+ { SPR_WIRE_X_SHORT_DOWN, 0, 8, 16, 8, 1, ELRAIL_ELEV_CORR }, //! 8: Wire in X pitch down, pylon on both ends
+
+
+/* Y direction */
+ /* Flat tiles: */
+ /* Wires */
+ { SPR_WIRE_Y_SE, 8, 0, 1, 16, 1, ELRAIL_ELEVATION }, //! 9: Wire in Y direction, pylon on the SE end only
+ { SPR_WIRE_Y_NW, 8, 0, 1, 16, 1, ELRAIL_ELEVATION }, //!10: Wire in Y direction, pylon on the NW end
+ { SPR_WIRE_Y_SHORT, 8, 0, 1, 16, 1, ELRAIL_ELEVATION }, //!11: Wire in Y direction, pylon on both ends
+
+ /* "up" tiles */
+ /* Wires */
+ { SPR_WIRE_Y_SE_UP, 8, 0, 8, 16, 1, ELRAIL_ELEVRAISE }, //!12: Wire in Y pitch up, pylon on the SE end only
+ { SPR_WIRE_Y_NW_UP, 8, 0, 8, 16, 1, ELRAIL_ELEVRAISE }, //!13: Wire in Y pitch up, pylon on the NW end
+ { SPR_WIRE_Y_SHORT_UP, 8, 0, 8, 16, 1, ELRAIL_ELEVRAISE }, //!14: Wire in Y pitch up, pylon on both ends
+
+ /* "down" tiles */
+ /* Wires */
+ { SPR_WIRE_Y_SE_DOWN, 8, 0, 8, 16, 1, ELRAIL_ELEV_CORR }, //!15: Wire in Y pitch down, pylon on the SE end
+ { SPR_WIRE_Y_NW_DOWN, 8, 0, 8, 16, 1, ELRAIL_ELEV_CORR }, //!16: Wire in Y pitch down, pylon on the NW end
+ { SPR_WIRE_Y_SHORT_DOWN, 8, 0, 8, 16, 1, ELRAIL_ELEV_CORR }, //!17: Wire in Y pitch down, pylon on both ends
+
+/* NS Direction */
+ { SPR_WIRE_NS_SHORT, 8, 0, 8, 8, 1, ELRAIL_ELEVATION }, //!18: LEFT trackbit wire, pylon on both ends
+ { SPR_WIRE_NS_SHORT, 0, 8, 8, 8, 1, ELRAIL_ELEVATION }, //!19: RIGHT trackbit wire, pylon on both ends
+
+ { SPR_WIRE_NS_N, 8, 0, 8, 8, 1, ELRAIL_ELEVATION }, //!20: LEFT trackbit wire, pylon on N end
+ { SPR_WIRE_NS_N, 0, 8, 8, 8, 1, ELRAIL_ELEVATION }, //!21: RIGHT trackbit wire, pylon on N end
+
+ { SPR_WIRE_NS_S, 8, 0, 8, 8, 1, ELRAIL_ELEVATION }, //!22: LEFT trackbit wire, pylon on S end
+ { SPR_WIRE_NS_S, 0, 8, 8, 8, 1, ELRAIL_ELEVATION }, //!23: RIGHT trackbit wire, pylon on S end
+
+/* EW Direction */
+ { SPR_WIRE_EW_SHORT, 8, 0, 8, 8, 1, ELRAIL_ELEVATION }, //!24: UPPER trackbit wire, pylon on both ends
+ { SPR_WIRE_EW_SHORT, 16, 8, 8, 8, 1, ELRAIL_ELEVATION }, //!25: LOWER trackbit wire, pylon on both ends
+
+ { SPR_WIRE_EW_W, 8, 0, 8, 8, 1, ELRAIL_ELEVATION }, //!28: UPPER trackbit wire, pylon on both ends
+ { SPR_WIRE_EW_W, 16, 8, 8, 8, 1, ELRAIL_ELEVATION }, //!29: LOWER trackbit wire, pylon on both ends
+
+ { SPR_WIRE_EW_E, 8, 0, 8, 8, 1, ELRAIL_ELEVATION }, //!32: UPPER trackbit wire, pylon on both ends
+ { SPR_WIRE_EW_E, 16, 8, 8, 8, 1, ELRAIL_ELEVATION } //!33: LOWER trackbit wire, pylon on both ends
+};
+
+static const SortableSpriteStruct CatenarySpriteData_Depot[] = {
+ { SPR_WIRE_DEPOT_NE, 0, 8, 8, 1, 1, ELRAIL_ELEVATION }, //! Wire for NE depot exit
+ { SPR_WIRE_DEPOT_SE, 8, 0, 1, 8, 1, ELRAIL_ELEVATION }, //! Wire for SE depot exit
+ { SPR_WIRE_DEPOT_SW, 0, 8, 8, 1, 1, ELRAIL_ELEVATION }, //! Wire for SW depot exit
+ { SPR_WIRE_DEPOT_NW, 8, 0, 1, 8, 1, ELRAIL_ELEVATION } //! Wire for NW depot exit
+};
+
+/** Refers to a certain element of the catenary.
+ * Identifiers for Wires:
+ * <ol><li>Direction of the wire</li>
+ * <li>Slope of the tile for diagonals, placement inside the track for horiz/vertical pieces</li>
+ * <li>Place where a pylon shoule be</li></ol>
+ * Identifiers for Pylons:
+ * <ol><li>Direction of the wire</li>
+ * <li>Slope of the tile</li>
+ * <li>Position of the Pylon relative to the track</li>
+ * <li>Position of the Pylon inside the tile</li></ol>
+ */
+typedef enum {
+ WIRE_X_FLAT_SW,
+ WIRE_X_FLAT_NE,
+ WIRE_X_FLAT_BOTH,
+
+ WIRE_X_UP_SW,
+ WIRE_X_UP_NE,
+ WIRE_X_UP_BOTH,
+
+ WIRE_X_DOWN_SW,
+ WIRE_X_DOWN_NE,
+ WIRE_X_DOWN_BOTH,
+
+ WIRE_Y_FLAT_SE,
+ WIRE_Y_FLAT_NW,
+ WIRE_Y_FLAT_BOTH,
+
+ WIRE_Y_UP_SE,
+ WIRE_Y_UP_NW,
+ WIRE_Y_UP_BOTH,
+
+ WIRE_Y_DOWN_SE,
+ WIRE_Y_DOWN_NW,
+ WIRE_Y_DOWN_BOTH,
+
+ WIRE_NS_W_BOTH,
+ WIRE_NS_E_BOTH,
+
+ WIRE_NS_W_N,
+ WIRE_NS_E_N,
+
+ WIRE_NS_W_S,
+ WIRE_NS_E_S,
+
+ WIRE_EW_N_BOTH,
+ WIRE_EW_S_BOTH,
+
+ WIRE_EW_N_W,
+ WIRE_EW_S_W,
+
+ WIRE_EW_N_E,
+ WIRE_EW_S_E,
+
+ INVALID_CATENARY = 0xFF
+} CatenarySprite;
+
+/* Selects a Wire (with white and grey ends) depending on whether:
+ * a) none (should never happen)
+ * b) the first
+ * c) the second
+ * d) both
+ * PCP exists.*/
+static const CatenarySprite Wires[5][TRACK_END][4] = {
+ { /* Tileh == 0 */
+ {INVALID_CATENARY, WIRE_X_FLAT_NE, WIRE_X_FLAT_SW, WIRE_X_FLAT_BOTH},
+ {INVALID_CATENARY, WIRE_Y_FLAT_SE, WIRE_Y_FLAT_NW, WIRE_Y_FLAT_BOTH},
+ {INVALID_CATENARY, WIRE_EW_N_W, WIRE_EW_N_E, WIRE_EW_N_BOTH},
+ {INVALID_CATENARY, WIRE_EW_S_E, WIRE_EW_S_W, WIRE_EW_S_BOTH},
+ {INVALID_CATENARY, WIRE_NS_W_S, WIRE_NS_W_N, WIRE_NS_W_BOTH},
+ {INVALID_CATENARY, WIRE_NS_E_N, WIRE_NS_E_S, WIRE_NS_E_BOTH},
+ }, { /* Tileh == 3 */
+ {INVALID_CATENARY, WIRE_X_UP_NE, WIRE_X_UP_SW, WIRE_X_UP_BOTH},
+ {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+ {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+ {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+ {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+ {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+ }, { /* Tileh == 6 */
+ {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+ {INVALID_CATENARY, WIRE_Y_UP_SE, WIRE_Y_UP_NW, WIRE_Y_UP_BOTH},
+ {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+ {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+ {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+ {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+ }, { /* Tileh == 9 */
+ {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+ {INVALID_CATENARY, WIRE_Y_DOWN_SE, WIRE_Y_DOWN_NW, WIRE_Y_DOWN_BOTH},
+ {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+ {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+ {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+ {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+ }, { /* Tileh == 12 */
+ {INVALID_CATENARY, WIRE_X_DOWN_NE, WIRE_X_DOWN_SW, WIRE_X_DOWN_BOTH},
+ {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+ {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+ {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+ {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+ {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+ }
+};
+
+#endif /* ELRAIL_DATA_H */
diff --git a/src/table/engines.h b/src/table/engines.h
new file mode 100644
index 000000000..08c4cea00
--- /dev/null
+++ b/src/table/engines.h
@@ -0,0 +1,689 @@
+/* $Id$ */
+
+#ifndef ENGINES_H
+#define ENGINES_H
+
+/** @file table/engines.h
+ * This file contains all the data for vehicles
+ */
+
+#include "../sound.h"
+
+/** Writes the properties of a train or road vehicle into the EngineInfo struct.
+ * @see EngineInfo
+ * @param a Introduction date
+ * @param e Rail Type of the vehicle
+ * @param f Bitmask of the climates
+ * @note the 5 between d and e is the load amount
+ */
+#define MK(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, b, c, d, 5, e, f, 0, 8, 0, 0 }
+/** Writes the properties of a train carriage into the EngineInfo struct.
+ * @see EngineInfo
+ * @param a Introduction date
+ * @param e Rail Type of the vehicle
+ * @param f Bitmask of the climates
+ * @note the 0x80 in parameter b sets the "is carriage bit"
+ * @note the 5 between d and e is the load amount
+ */
+#define MW(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, b | 0x80, c, d, 5, e, f, 0, 8, 0, 0 }
+
+/** Writes the properties of a ship into the EngineInfo struct.
+ * @see MK
+ * @note the 10 between d and e is the load amount
+ */
+#define MS(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, b, c, d, 10, e, f, 0, 8, 0, 0 }
+
+/** Writes the properties of an aeroplane into the EngineInfo struct.
+ * @see MK
+ * @note the 20 between d and e is the load amount
+ */
+#define MA(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, b, c, d, 20, e, f, 0, 8, 0, 0 }
+
+// Rail types
+// R = Conventional railway
+// E = Electrified railway
+// M = Monorail
+// L = MagLev
+#define R 0
+#define E 1
+#define M 2
+#define L 3
+// Climates
+// T = Temperate
+// A = Arctic
+// S = Sub-Tropic
+// Y = Toyland
+#define T 1
+#define A 2
+#define S 4
+#define Y 8
+const EngineInfo orig_engine_info[] = {
+ MK( 1827, 20, 15, 30, R, T ), /* 0 Kirby Paul Tank (Steam) */
+ MK( 12784, 20, 22, 30, R, A|S ), /* 1 MJS 250 (Diesel) */
+ MK( 9497, 20, 20, 50, R, Y), /* 2 Ploddyphut Choo-Choo */
+ MK( 11688, 20, 20, 30, R, Y), /* 3 Powernaut Choo-Choo */
+ MK( 16802, 20, 20, 30, R, Y), /* 4 Mightymover Choo-Choo */
+ MK( 18993, 20, 20, 30, R, Y), /* 5 Ploddyphut Diesel */
+ MK( 20820, 20, 20, 30, R, Y), /* 6 Powernaut Diesel */
+ MK( 8766, 20, 20, 30, R, A|S ), /* 7 Wills 2-8-0 (Steam) */
+ MK( 5114, 20, 21, 30, R, T ), /* 8 Chaney 'Jubilee' (Steam) */
+ MK( 5479, 20, 20, 30, R, T ), /* 9 Ginzu 'A4' (Steam) */
+ MK( 12419, 20, 23, 25, R, T ), /* 10 SH '8P' (Steam) */
+ MK( 13149, 20, 12, 30, R, T ), /* 11 Manley-Morel DMU (Diesel) */
+ MK( 23376, 20, 15, 35, R, T ), /* 12 'Dash' (Diesel) */
+ MK( 14976, 20, 18, 28, R, T ), /* 13 SH/Hendry '25' (Diesel) */
+ MK( 14245, 20, 20, 30, R, T ), /* 14 UU '37' (Diesel) */
+ MK( 15341, 20, 22, 33, R, T ), /* 15 Floss '47' (Diesel) */
+ MK( 14976, 20, 20, 25, R, A|S ), /* 16 CS 4000 (Diesel) */
+ MK( 16437, 20, 20, 30, R, A|S ), /* 17 CS 2400 (Diesel) */
+ MK( 18993, 20, 22, 30, R, A|S ), /* 18 Centennial (Diesel) */
+ MK( 13880, 20, 22, 30, R, A|S ), /* 19 Kelling 3100 (Diesel) */
+ MK( 20454, 20, 22, 30, R, A|S ), /* 20 Turner Turbo (Diesel) */
+ MK( 16071, 20, 22, 30, R, A|S ), /* 21 MJS 1000 (Diesel) */
+ MK( 20820, 20, 20, 25, R, T ), /* 22 SH '125' (Diesel) */
+ MK( 16437, 20, 23, 30, E, T ), /* 23 SH '30' (Electric) */
+ MK( 19359, 20, 23, 80, E, T ), /* 24 SH '40' (Electric) */
+ MK( 23376, 20, 25, 30, E, T ), /* 25 'T.I.M.' (Electric) */
+ MK( 26298, 20, 25, 50, E, T ), /* 26 'AsiaStar' (Electric) */
+ MW( 1827, 20, 20, 50, R, T|A|S|Y), /* 27 Passenger Carriage */
+ MW( 1827, 20, 20, 50, R, T|A|S|Y), /* 28 Mail Van */
+ MW( 1827, 20, 20, 50, R, T|A ), /* 29 Coal Truck */
+ MW( 1827, 20, 20, 50, R, T|A|S ), /* 30 Oil Tanker */
+ MW( 1827, 20, 20, 50, R, T|A ), /* 31 Livestock Van */
+ MW( 1827, 20, 20, 50, R, T|A|S ), /* 32 Goods Van */
+ MW( 1827, 20, 20, 50, R, T|A|S ), /* 33 Grain Hopper */
+ MW( 1827, 20, 20, 50, R, T|A|S ), /* 34 Wood Truck */
+ MW( 1827, 20, 20, 50, R, T ), /* 35 Iron Ore Hopper */
+ MW( 1827, 20, 20, 50, R, T ), /* 36 Steel Truck */
+ MW( 1827, 20, 20, 50, R, T|A|S ), /* 37 Armoured Van */
+ MW( 1827, 20, 20, 50, R, A|S ), /* 38 Food Van */
+ MW( 1827, 20, 20, 50, R, A ), /* 39 Paper Truck */
+ MW( 1827, 20, 20, 50, R, S ), /* 40 Copper Ore Hopper */
+ MW( 1827, 20, 20, 50, R, S ), /* 41 Water Tanker */
+ MW( 1827, 20, 20, 50, R, S ), /* 42 Fruit Truck */
+ MW( 1827, 20, 20, 50, R, S ), /* 43 Rubber Truck */
+ MW( 1827, 20, 20, 50, R, Y), /* 44 Sugar Truck */
+ MW( 1827, 20, 20, 50, R, Y), /* 45 Candyfloss Hopper */
+ MW( 1827, 20, 20, 50, R, Y), /* 46 Toffee Hopper */
+ MW( 1827, 20, 20, 50, R, Y), /* 47 Bubble Van */
+ MW( 1827, 20, 20, 50, R, Y), /* 48 Cola Tanker */
+ MW( 1827, 20, 20, 50, R, Y), /* 49 Sweet Van */
+ MW( 1827, 20, 20, 50, R, Y), /* 50 Toy Van */
+ MW( 1827, 20, 20, 50, R, Y), /* 51 Battery Truck */
+ MW( 1827, 20, 20, 50, R, Y), /* 52 Fizzy Drink Truck */
+ MW( 1827, 20, 20, 50, R, Y), /* 53 Plastic Truck */
+ MK( 28490, 20, 20, 50, M, T|A|S ), /* 54 'X2001' (Electric) */
+ MK( 31047, 20, 20, 50, M, T|A|S ), /* 55 'Millennium Z1' (Electric) */
+ MK( 28855, 20, 20, 50, M, Y), /* 56 Wizzowow Z99 */
+ MW( 1827, 20, 20, 50, M, T|A|S|Y), /* 57 Passenger Carriage */
+ MW( 1827, 20, 20, 50, M, T|A|S|Y), /* 58 Mail Van */
+ MW( 1827, 20, 20, 50, M, T|A ), /* 59 Coal Truck */
+ MW( 1827, 20, 20, 50, M, T|A|S ), /* 60 Oil Tanker */
+ MW( 1827, 20, 20, 50, M, T|A ), /* 61 Livestock Van */
+ MW( 1827, 20, 20, 50, M, T|A|S ), /* 62 Goods Van */
+ MW( 1827, 20, 20, 50, M, T|A|S ), /* 63 Grain Hopper */
+ MW( 1827, 20, 20, 50, M, T|A|S ), /* 64 Wood Truck */
+ MW( 1827, 20, 20, 50, M, T ), /* 65 Iron Ore Hopper */
+ MW( 1827, 20, 20, 50, M, T ), /* 66 Steel Truck */
+ MW( 1827, 20, 20, 50, M, T|A|S ), /* 67 Armoured Van */
+ MW( 1827, 20, 20, 50, M, A|S ), /* 68 Food Van */
+ MW( 1827, 20, 20, 50, M, A ), /* 69 Paper Truck */
+ MW( 1827, 20, 20, 50, M, S ), /* 70 Copper Ore Hopper */
+ MW( 1827, 20, 20, 50, M, S ), /* 71 Water Tanker */
+ MW( 1827, 20, 20, 50, M, S ), /* 72 Fruit Truck */
+ MW( 1827, 20, 20, 50, M, S ), /* 73 Rubber Truck */
+ MW( 1827, 20, 20, 50, M, Y), /* 74 Sugar Truck */
+ MW( 1827, 20, 20, 50, M, Y), /* 75 Candyfloss Hopper */
+ MW( 1827, 20, 20, 50, M, Y), /* 76 Toffee Hopper */
+ MW( 1827, 20, 20, 50, M, Y), /* 77 Bubble Van */
+ MW( 1827, 20, 20, 50, M, Y), /* 78 Cola Tanker */
+ MW( 1827, 20, 20, 50, M, Y), /* 79 Sweet Van */
+ MW( 1827, 20, 20, 50, M, Y), /* 80 Toy Van */
+ MW( 1827, 20, 20, 50, M, Y), /* 81 Battery Truck */
+ MW( 1827, 20, 20, 50, M, Y), /* 82 Fizzy Drink Truck */
+ MW( 1827, 20, 20, 50, M, Y), /* 83 Plastic Truck */
+ MK( 36525, 20, 20, 50, L, T|A|S ), /* 84 Lev1 'Leviathan' (Electric) */
+ MK( 39447, 20, 20, 50, L, T|A|S ), /* 85 Lev2 'Cyclops' (Electric) */
+ MK( 42004, 20, 20, 50, L, T|A|S ), /* 86 Lev3 'Pegasus' (Electric) */
+ MK( 42735, 20, 20, 50, L, T|A|S ), /* 87 Lev4 'Chimaera' (Electric) */
+ MK( 36891, 20, 20, 60, L, Y), /* 88 Wizzowow Rocketeer */
+ MW( 1827, 20, 20, 50, L, T|A|S|Y), /* 89 Passenger Carriage */
+ MW( 1827, 20, 20, 50, L, T|A|S|Y), /* 90 Mail Van */
+ MW( 1827, 20, 20, 50, L, T|A ), /* 91 Coal Truck */
+ MW( 1827, 20, 20, 50, L, T|A|S ), /* 92 Oil Tanker */
+ MW( 1827, 20, 20, 50, L, T|A ), /* 93 Livestock Van */
+ MW( 1827, 20, 20, 50, L, T|A|S ), /* 94 Goods Van */
+ MW( 1827, 20, 20, 50, L, T|A|S ), /* 95 Grain Hopper */
+ MW( 1827, 20, 20, 50, L, T|A|S ), /* 96 Wood Truck */
+ MW( 1827, 20, 20, 50, L, T ), /* 97 Iron Ore Hopper */
+ MW( 1827, 20, 20, 50, L, T ), /* 98 Steel Truck */
+ MW( 1827, 20, 20, 50, L, T|A|S ), /* 99 Armoured Van */
+ MW( 1827, 20, 20, 50, L, A|S ), /* 100 Food Van */
+ MW( 1827, 20, 20, 50, L, A ), /* 101 Paper Truck */
+ MW( 1827, 20, 20, 50, L, S ), /* 102 Copper Ore Hopper */
+ MW( 1827, 20, 20, 50, L, S ), /* 103 Water Tanker */
+ MW( 1827, 20, 20, 50, L, S ), /* 104 Fruit Truck */
+ MW( 1827, 20, 20, 50, L, S ), /* 105 Rubber Truck */
+ MW( 1827, 20, 20, 50, L, Y), /* 106 Sugar Truck */
+ MW( 1827, 20, 20, 50, L, Y), /* 107 Candyfloss Hopper */
+ MW( 1827, 20, 20, 50, L, Y), /* 108 Toffee Hopper */
+ MW( 1827, 20, 20, 50, L, Y), /* 109 Bubble Van */
+ MW( 1827, 20, 20, 50, L, Y), /* 110 Cola Tanker */
+ MW( 1827, 20, 20, 50, L, Y), /* 111 Sweet Van */
+ MW( 1827, 20, 20, 50, L, Y), /* 112 Toy Van */
+ MW( 1827, 20, 20, 50, L, Y), /* 113 Battery Truck */
+ MW( 1827, 20, 20, 50, L, Y), /* 114 Fizzy Drink Truck */
+ MW( 1827, 20, 20, 50, L, Y), /* 115 Plastic Truck */
+ MK( 3378, 20, 12, 40, 0, T|A|S ), /* 116 MPS Regal Bus */
+ MK( 16071, 20, 15, 30, 0, T|A|S ), /* 117 Hereford Leopard Bus */
+ MK( 24107, 20, 15, 40, 0, T|A|S ), /* 118 Foster Bus */
+ MK( 32142, 20, 15, 80, 0, T|A|S ), /* 119 Foster MkII Superbus */
+ MK( 9132, 20, 15, 40, 0, Y), /* 120 Ploddyphut MkI Bus */
+ MK( 18993, 20, 15, 40, 0, Y), /* 121 Ploddyphut MkII Bus */
+ MK( 32873, 20, 15, 80, 0, Y), /* 122 Ploddyphut MkIII Bus */
+ MK( 5479, 20, 15, 55, 0, T|A ), /* 123 Balogh Coal Truck */
+ MK( 20089, 20, 15, 55, 0, T|A ), /* 124 Uhl Coal Truck */
+ MK( 33969, 20, 15, 85, 0, T|A ), /* 125 DW Coal Truck */
+ MK( 5479, 20, 15, 55, 0, T|A|S ), /* 126 MPS Mail Truck */
+ MK( 21550, 20, 15, 55, 0, T|A|S ), /* 127 Reynard Mail Truck */
+ MK( 35795, 20, 15, 85, 0, T|A|S ), /* 128 Perry Mail Truck */
+ MK( 5479, 20, 15, 55, 0, Y), /* 129 MightyMover Mail Truck */
+ MK( 21550, 20, 15, 55, 0, Y), /* 130 Powernaught Mail Truck */
+ MK( 35795, 20, 15, 85, 0, Y), /* 131 Wizzowow Mail Truck */
+ MK( 5479, 20, 15, 55, 0, T|A|S ), /* 132 Witcombe Oil Tanker */
+ MK( 19359, 20, 15, 55, 0, T|A|S ), /* 133 Foster Oil Tanker */
+ MK( 31047, 20, 15, 85, 0, T|A|S ), /* 134 Perry Oil Tanker */
+ MK( 5479, 20, 15, 55, 0, T|A ), /* 135 Talbott Livestock Van */
+ MK( 21915, 20, 15, 55, 0, T|A ), /* 136 Uhl Livestock Van */
+ MK( 37256, 20, 15, 85, 0, T|A ), /* 137 Foster Livestock Van */
+ MK( 5479, 20, 15, 55, 0, T|A|S ), /* 138 Balogh Goods Truck */
+ MK( 19724, 20, 15, 55, 0, T|A|S ), /* 139 Craighead Goods Truck */
+ MK( 31047, 20, 15, 85, 0, T|A|S ), /* 140 Goss Goods Truck */
+ MK( 5479, 20, 15, 55, 0, T|A|S ), /* 141 Hereford Grain Truck */
+ MK( 21185, 20, 15, 55, 0, T|A|S ), /* 142 Thomas Grain Truck */
+ MK( 32873, 20, 15, 85, 0, T|A|S ), /* 143 Goss Grain Truck */
+ MK( 5479, 20, 15, 55, 0, T|A|S ), /* 144 Witcombe Wood Truck */
+ MK( 19724, 20, 15, 55, 0, T|A|S ), /* 145 Foster Wood Truck */
+ MK( 35430, 20, 15, 85, 0, T|A|S ), /* 146 Moreland Wood Truck */
+ MK( 5479, 20, 15, 55, 0, T ), /* 147 MPS Iron Ore Truck */
+ MK( 20820, 20, 15, 55, 0, T ), /* 148 Uhl Iron Ore Truck */
+ MK( 33238, 20, 15, 85, 0, T ), /* 149 Chippy Iron Ore Truck */
+ MK( 5479, 20, 15, 55, 0, T ), /* 150 Balogh Steel Truck */
+ MK( 21185, 20, 15, 55, 0, T ), /* 151 Uhl Steel Truck */
+ MK( 31777, 20, 15, 85, 0, T ), /* 152 Kelling Steel Truck */
+ MK( 5479, 20, 15, 55, 0, T|A|S ), /* 153 Balogh Armoured Truck */
+ MK( 22281, 20, 15, 55, 0, T|A|S ), /* 154 Uhl Armoured Truck */
+ MK( 33603, 20, 15, 85, 0, T|A|S ), /* 155 Foster Armoured Truck */
+ MK( 5479, 20, 15, 55, 0, A|S ), /* 156 Foster Food Van */
+ MK( 18628, 20, 15, 55, 0, A|S ), /* 157 Perry Food Van */
+ MK( 30681, 20, 15, 85, 0, A|S ), /* 158 Chippy Food Van */
+ MK( 5479, 20, 15, 55, 0, A ), /* 159 Uhl Paper Truck */
+ MK( 21185, 20, 15, 55, 0, A ), /* 160 Balogh Paper Truck */
+ MK( 31777, 20, 15, 85, 0, A ), /* 161 MPS Paper Truck */
+ MK( 5479, 20, 15, 55, 0, S ), /* 162 MPS Copper Ore Truck */
+ MK( 20820, 20, 15, 55, 0, S ), /* 163 Uhl Copper Ore Truck */
+ MK( 33238, 20, 15, 85, 0, S ), /* 164 Goss Copper Ore Truck */
+ MK( 5479, 20, 15, 55, 0, S ), /* 165 Uhl Water Tanker */
+ MK( 20970, 20, 15, 55, 0, S ), /* 166 Balogh Water Tanker */
+ MK( 33388, 20, 15, 85, 0, S ), /* 167 MPS Water Tanker */
+ MK( 5479, 20, 15, 55, 0, S ), /* 168 Balogh Fruit Truck */
+ MK( 21335, 20, 15, 55, 0, S ), /* 169 Uhl Fruit Truck */
+ MK( 33753, 20, 15, 85, 0, S ), /* 170 Kelling Fruit Truck */
+ MK( 5479, 20, 15, 55, 0, S ), /* 171 Balogh Rubber Truck */
+ MK( 20604, 20, 15, 55, 0, S ), /* 172 Uhl Rubber Truck */
+ MK( 33023, 20, 15, 85, 0, S ), /* 173 RMT Rubber Truck */
+ MK( 5479, 20, 15, 55, 0, Y), /* 174 MightyMover Sugar Truck */
+ MK( 19724, 20, 15, 55, 0, Y), /* 175 Powernaught Sugar Truck */
+ MK( 33238, 20, 15, 85, 0, Y), /* 176 Wizzowow Sugar Truck */
+ MK( 5479, 20, 15, 55, 0, Y), /* 177 MightyMover Cola Truck */
+ MK( 20089, 20, 15, 55, 0, Y), /* 178 Powernaught Cola Truck */
+ MK( 33603, 20, 15, 85, 0, Y), /* 179 Wizzowow Cola Truck */
+ MK( 5479, 20, 15, 55, 0, Y), /* 180 MightyMover Candyfloss Truck */
+ MK( 20454, 20, 15, 55, 0, Y), /* 181 Powernaught Candyfloss Truck */
+ MK( 33969, 20, 15, 85, 0, Y), /* 182 Wizzowow Candyfloss Truck */
+ MK( 5479, 20, 15, 55, 0, Y), /* 183 MightyMover Toffee Truck */
+ MK( 20820, 20, 15, 55, 0, Y), /* 184 Powernaught Toffee Truck */
+ MK( 34334, 20, 15, 85, 0, Y), /* 185 Wizzowow Toffee Truck */
+ MK( 5479, 20, 15, 55, 0, Y), /* 186 MightyMover Toy Van */
+ MK( 21185, 20, 15, 55, 0, Y), /* 187 Powernaught Toy Van */
+ MK( 34699, 20, 15, 85, 0, Y), /* 188 Wizzowow Toy Van */
+ MK( 5479, 20, 15, 55, 0, Y), /* 189 MightyMover Sweet Truck */
+ MK( 21550, 20, 15, 55, 0, Y), /* 190 Powernaught Sweet Truck */
+ MK( 35064, 20, 15, 85, 0, Y), /* 191 Wizzowow Sweet Truck */
+ MK( 5479, 20, 15, 55, 0, Y), /* 192 MightyMover Battery Truck */
+ MK( 19874, 20, 15, 55, 0, Y), /* 193 Powernaught Battery Truck */
+ MK( 35430, 20, 15, 85, 0, Y), /* 194 Wizzowow Battery Truck */
+ MK( 5479, 20, 15, 55, 0, Y), /* 195 MightyMover Fizzy Drink Truck */
+ MK( 20239, 20, 15, 55, 0, Y), /* 196 Powernaught Fizzy Drink Truck */
+ MK( 35795, 20, 15, 85, 0, Y), /* 197 Wizzowow Fizzy Drink Truck */
+ MK( 5479, 20, 15, 55, 0, Y), /* 198 MightyMover Plastic Truck */
+ MK( 20604, 20, 15, 55, 0, Y), /* 199 Powernaught Plastic Truck */
+ MK( 32873, 20, 15, 85, 0, Y), /* 200 Wizzowow Plastic Truck */
+ MK( 5479, 20, 15, 55, 0, Y), /* 201 MightyMover Bubble Truck */
+ MK( 20970, 20, 15, 55, 0, Y), /* 202 Powernaught Bubble Truck */
+ MK( 33023, 20, 15, 85, 0, Y), /* 203 Wizzowow Bubble Truck */
+ MS( 2922, 5, 30, 50, 0, T|A|S ), /* 204 MPS Oil Tanker */
+ MS( 17167, 5, 30, 90, 0, T|A|S ), /* 205 CS-Inc. Oil Tanker */
+ MS( 2192, 5, 30, 55, 0, T|A|S ), /* 206 MPS Passenger Ferry */
+ MS( 18628, 5, 30, 90, 0, T|A|S ), /* 207 FFP Passenger Ferry */
+ MS( 17257, 10, 25, 90, 0, T|A|S ), /* 208 Bakewell 300 Hovercraft */
+ MS( 9587, 5, 30, 40, 0, Y), /* 209 Chugger-Chug Passenger Ferry */
+ MS( 20544, 5, 30, 90, 0, Y), /* 210 Shivershake Passenger Ferry */
+ MS( 2557, 5, 30, 55, 0, T|A|S ), /* 211 Yate Cargo ship */
+ MS( 19724, 5, 30, 98, 0, T|A|S ), /* 212 Bakewell Cargo ship */
+ MS( 9587, 5, 30, 45, 0, Y), /* 213 Mightymover Cargo ship */
+ MS( 22371, 5, 30, 90, 0, Y), /* 214 Powernaut Cargo ship */
+ MA( 2922, 20, 20, 20, 0, T|A|S ), /* 215 Sampson U52 */
+ MA( 9922, 20, 24, 20, 0, T|A|S ), /* 216 Coleman Count */
+ MA( 12659, 20, 18, 20, 0, T|A|S ), /* 217 FFP Dart */
+ MA( 17652, 20, 25, 35, 0, T|A|S ), /* 218 Yate Haugan */
+ MA( 4929, 20, 30, 30, 0, T|A|S ), /* 219 Bakewell Cotswald LB-3 */
+ MA( 13695, 20, 23, 25, 0, T|A|S ), /* 220 Bakewell Luckett LB-8 */
+ MA( 16341, 20, 26, 30, 0, T|A|S ), /* 221 Bakewell Luckett LB-9 */
+ MA( 21395, 20, 25, 30, 0, T|A|S ), /* 222 Bakewell Luckett LB80 */
+ MA( 18263, 20, 20, 30, 0, T|A|S ), /* 223 Bakewell Luckett LB-10 */
+ MA( 25233, 20, 25, 30, 0, T|A|S ), /* 224 Bakewell Luckett LB-11 */
+ MA( 15371, 20, 22, 25, 0, T|A|S ), /* 225 Yate Aerospace YAC 1-11 */
+ MA( 15461, 20, 25, 25, 0, T|A|S ), /* 226 Darwin 100 */
+ MA( 16952, 20, 22, 25, 0, T|A|S ), /* 227 Darwin 200 */
+ MA( 17227, 20, 25, 30, 0, T|A|S ), /* 228 Darwin 300 */
+ MA( 22371, 20, 25, 35, 0, T|A|S ), /* 229 Darwin 400 */
+ MA( 22341, 20, 25, 30, 0, T|A|S ), /* 230 Darwin 500 */
+ MA( 27209, 20, 25, 30, 0, T|A|S ), /* 231 Darwin 600 */
+ MA( 17988, 20, 20, 30, 0, T|A|S ), /* 232 Guru Galaxy */
+ MA( 18993, 20, 24, 35, 0, T|A|S ), /* 233 Airtaxi A21 */
+ MA( 22401, 20, 24, 30, 0, T|A|S ), /* 234 Airtaxi A31 */
+ MA( 24472, 20, 24, 30, 0, T|A|S ), /* 235 Airtaxi A32 */
+ MA( 26724, 20, 24, 30, 0, T|A|S ), /* 236 Airtaxi A33 */
+ MA( 22005, 20, 25, 30, 0, T|A|S ), /* 237 Yate Aerospace YAe46 */
+ MA( 24107, 20, 20, 35, 0, T|A|S ), /* 238 Dinger 100 */
+ MA( 29310, 20, 25, 60, 0, T|A|S ), /* 239 AirTaxi A34-1000 */
+ MA( 35520, 20, 22, 30, 0, T|A|S ), /* 240 Yate Z-Shuttle */
+ MA( 36981, 20, 22, 30, 0, T|A|S ), /* 241 Kelling K1 */
+ MA( 38807, 20, 22, 50, 0, T|A|S ), /* 242 Kelling K6 */
+ MA( 42094, 20, 25, 30, 0, T|A|S ), /* 243 Kelling K7 */
+ MA( 44651, 20, 23, 30, 0, T|A|S ), /* 244 Darwin 700 */
+ MA( 40268, 20, 25, 30, 0, T|A|S ), /* 245 FFP Hyperdart 2 */
+ MA( 33693, 20, 25, 50, 0, T|A|S ), /* 246 Dinger 200 */
+ MA( 32963, 20, 20, 60, 0, T|A|S ), /* 247 Dinger 1000 */
+ MA( 9222, 20, 20, 35, 0, Y), /* 248 Ploddyphut 100 */
+ MA( 12874, 20, 20, 35, 0, Y), /* 249 Ploddyphut 500 */
+ MA( 16892, 20, 20, 35, 0, Y), /* 250 Flashbang X1 */
+ MA( 21275, 20, 20, 99, 0, Y), /* 251 Juggerplane M1 */
+ MA( 23832, 20, 20, 99, 0, Y), /* 252 Flashbang Wizzer */
+ MA( 13575, 20, 20, 40, 0, T|A|S ), /* 253 Tricario Helicopter */
+ MA( 28215, 20, 20, 30, 0, T|A|S ), /* 254 Guru X2 Helicopter */
+ MK( 13575, 20, 20, 99, 0, Y), /* 255 */
+};
+#undef Y
+#undef S
+#undef A
+#undef T
+#undef L
+#undef M
+#undef R
+#undef E
+#undef MK
+#undef MW
+#undef MS
+#undef MA
+
+/** Writes the properties of a rail vehicle into the RailVehicleInfo struct.
+ * @see RailVehicleInfo
+ * @param a image_index
+ * @param b flags
+ * @param c base_cost
+ * @param d max_speed (kph)
+ * @param e power (hp)
+ * @param f weight
+ * @param g running_cost_base
+ * @param h running_cost_class / engclass
+ * @param i capacity
+ * @param j cargo_type
+ * @param k ai_rank
+ * Tractive effort coefficient by default is the same as TTDPatch, 0.30*256=76
+ */
+#define RVI(a, b, c, d, e, f, g, h, i, j, k) { a, b, c, d, e, f, g, h, h, i, j, k, 0, 0, 0, 0, 76, 0 }
+#define M RVI_MULTIHEAD
+#define W RVI_WAGON
+#define S 0
+#define D 1
+#define E 2
+const RailVehicleInfo orig_rail_vehicle_info[NUM_TRAIN_ENGINES] = {
+ // image_index max_speed (kph) running_cost_base
+ // | flags | power (hp) | running_cost_class & engclass
+ // | | base_cost | weight | | capacity
+ // | | | | | | | | | cargo_type
+ // | | | | | | | | | |
+ RVI( 2, 0, 7, 64, 300, 47, 50, S, 0, 0 , 1 ), /* 0 */
+ RVI( 19, 0, 8, 80, 600, 65, 65, D, 0, 0 , 4 ), /* 1 */
+ RVI( 2, 0, 10, 72, 400, 85, 90, S, 0, 0 , 7 ), /* 2 */
+ RVI( 0, 0, 15, 96, 900, 130, 130, S, 0, 0 , 19 ), /* 3 */
+ RVI( 1, 0, 19, 112, 1000, 140, 145, S, 0, 0 , 20 ), /* 4 */
+ RVI( 12, 0, 16, 120, 1400, 95, 125, D, 0, 0 , 30 ), /* 5 */
+ RVI( 14, 0, 20, 152, 2000, 120, 135, D, 0, 0 , 31 ), /* 6 */
+ RVI( 3, 0, 14, 88, 1100, 145, 130, S, 0, 0 , 19 ), /* 7 */
+ RVI( 0, 0, 13, 112, 1000, 131, 120, S, 0, 0 , 20 ), /* 8 */
+ RVI( 1, 0, 19, 128, 1200, 162, 140, S, 0, 0 , 21 ), /* 9 */
+ RVI( 0, 0, 22, 144, 1600, 170, 130, S, 0, 0 , 22 ), /* 10 */
+ RVI( 8, M, 11, 112, 600/2,32/2, 85/2, D, 38, CT_PASSENGERS , 10 ), /* 11 */
+ RVI( 10, M, 14, 120, 700/2,38/2, 70/2, D, 40, CT_PASSENGERS , 11 ), /* 12 */
+ RVI( 4, 0, 15, 128, 1250, 72, 95, D, 0, 0 , 30 ), /* 13 */
+ RVI( 5, 0, 17, 144, 1750, 101, 120, D, 0, 0 , 31 ), /* 14 */
+ RVI( 4, 0, 18, 160, 2580, 112, 140, D, 0, 0 , 32 ), /* 15 */
+ RVI( 14, 0, 23, 96, 4000, 150, 135, D, 0, 0 , 33 ), /* 16 */
+ RVI( 12, 0, 16, 112, 2400, 120, 105, D, 0, 0 , 34 ), /* 17 */
+ RVI( 13, 0, 30, 112, 6600, 207, 155, D, 0, 0 , 35 ), /* 18 */
+ RVI( 15, 0, 18, 104, 1500, 110, 105, D, 0, 0 , 29 ), /* 19 */
+ RVI( 16, M, 35, 160, 3500/2,95/2, 205/2, D, 0, 0 , 45 ), /* 20 */
+ RVI( 18, 0, 21, 104, 2200, 120, 145, D, 0, 0 , 32 ), /* 21 */
+ RVI( 6, M, 20, 200, 4500/2,70/2, 190/2, D, 4, CT_MAIL , 50 ), /* 22 */
+ RVI( 20, 0, 26, 160, 3600, 84, 180, E, 0, 0 , 40 ), /* 23 */
+ RVI( 20, 0, 30, 176, 5000, 82, 205, E, 0, 0 , 41 ), /* 24 */
+ RVI( 21, M, 40, 240, 7000/2,90/2, 240/2, E, 0, 0 , 51 ), /* 25 */
+ RVI( 23, M, 43, 264, 8000/2,95/2, 250/2, E, 0, 0 , 52 ), /* 26 */
+ RVI( 33, W, 247, 0, 0, 25, 0, 0, 40, CT_PASSENGERS , 0 ), /* 27 */
+ RVI( 35, W, 228, 0, 0, 21, 0, 0, 30, CT_MAIL , 0 ), /* 28 */
+ RVI( 34, W, 176, 0, 0, 18, 0, 0, 30, CT_COAL , 0 ), /* 29 */
+ RVI( 36, W, 200, 0, 0, 24, 0, 0, 30, CT_OIL , 0 ), /* 30 */
+ RVI( 37, W, 192, 0, 0, 20, 0, 0, 25, CT_LIVESTOCK , 0 ), /* 31 */
+ RVI( 38, W, 190, 0, 0, 21, 0, 0, 25, CT_GOODS , 0 ), /* 32 */
+ RVI( 39, W, 182, 0, 0, 19, 0, 0, 30, CT_GRAIN , 0 ), /* 33 */
+ RVI( 40, W, 181, 0, 0, 16, 0, 0, 30, CT_WOOD , 0 ), /* 34 */
+ RVI( 41, W, 179, 0, 0, 19, 0, 0, 30, CT_IRON_ORE , 0 ), /* 35 */
+ RVI( 42, W, 196, 0, 0, 18, 0, 0, 20, CT_STEEL , 0 ), /* 36 */
+ RVI( 43, W, 255, 0, 0, 30, 0, 0, 20, CT_VALUABLES , 0 ), /* 37 */
+ RVI( 44, W, 191, 0, 0, 22, 0, 0, 25, CT_FOOD , 0 ), /* 38 */
+ RVI( 45, W, 196, 0, 0, 18, 0, 0, 20, CT_PAPER , 0 ), /* 39 */
+ RVI( 46, W, 179, 0, 0, 19, 0, 0, 30, CT_COPPER_ORE , 0 ), /* 40 */
+ RVI( 47, W, 199, 0, 0, 25, 0, 0, 25, CT_WATER , 0 ), /* 41 */
+ RVI( 48, W, 182, 0, 0, 18, 0, 0, 25, CT_FRUIT , 0 ), /* 42 */
+ RVI( 49, W, 185, 0, 0, 19, 0, 0, 21, CT_RUBBER , 0 ), /* 43 */
+ RVI( 50, W, 176, 0, 0, 19, 0, 0, 30, CT_SUGAR , 0 ), /* 44 */
+ RVI( 51, W, 178, 0, 0, 20, 0, 0, 30, CT_COTTON_CANDY, 0 ), /* 45 */
+ RVI( 52, W, 192, 0, 0, 20, 0, 0, 30, CT_TOFFEE , 0 ), /* 46 */
+ RVI( 53, W, 190, 0, 0, 21, 0, 0, 20, CT_BUBBLES , 0 ), /* 47 */
+ RVI( 54, W, 182, 0, 0, 24, 0, 0, 25, CT_COLA , 0 ), /* 48 */
+ RVI( 55, W, 181, 0, 0, 21, 0, 0, 25, CT_CANDY , 0 ), /* 49 */
+ RVI( 56, W, 183, 0, 0, 21, 0, 0, 20, CT_TOYS , 0 ), /* 50 */
+ RVI( 57, W, 196, 0, 0, 18, 0, 0, 22, CT_BATTERIES , 0 ), /* 51 */
+ RVI( 58, W, 193, 0, 0, 18, 0, 0, 25, CT_FIZZY_DRINKS, 0 ), /* 52 */
+ RVI( 59, W, 191, 0, 0, 18, 0, 0, 30, CT_PLASTIC , 0 ), /* 53 */
+ RVI( 25, 0, 52, 304, 9000, 95, 230, E, 0, 0 , 60 ), /* 54 */
+ RVI( 26, M, 60, 336, 10000/2,85/2, 240/2, E, 25, CT_PASSENGERS , 62 ), /* 55 */
+ RVI( 26, 0, 53, 320, 5000, 95, 230, E, 0, 0 , 63 ), /* 56 */
+ RVI( 60, W, 247, 0, 0, 25, 0, 0, 45, CT_PASSENGERS , 0 ), /* 57 */
+ RVI( 62, W, 228, 0, 0, 21, 0, 0, 35, CT_MAIL , 0 ), /* 58 */
+ RVI( 61, W, 176, 0, 0, 18, 0, 0, 35, CT_COAL , 0 ), /* 59 */
+ RVI( 63, W, 200, 0, 0, 24, 0, 0, 35, CT_OIL , 0 ), /* 60 */
+ RVI( 64, W, 192, 0, 0, 20, 0, 0, 30, CT_LIVESTOCK , 0 ), /* 61 */
+ RVI( 65, W, 190, 0, 0, 21, 0, 0, 30, CT_GOODS , 0 ), /* 62 */
+ RVI( 66, W, 182, 0, 0, 19, 0, 0, 35, CT_GRAIN , 0 ), /* 63 */
+ RVI( 67, W, 181, 0, 0, 16, 0, 0, 35, CT_WOOD , 0 ), /* 64 */
+ RVI( 68, W, 179, 0, 0, 19, 0, 0, 35, CT_IRON_ORE , 0 ), /* 65 */
+ RVI( 69, W, 196, 0, 0, 18, 0, 0, 25, CT_STEEL , 0 ), /* 66 */
+ RVI( 70, W, 255, 0, 0, 30, 0, 0, 25, CT_VALUABLES , 0 ), /* 67 */
+ RVI( 71, W, 191, 0, 0, 22, 0, 0, 30, CT_FOOD , 0 ), /* 68 */
+ RVI( 72, W, 196, 0, 0, 18, 0, 0, 25, CT_PAPER , 0 ), /* 69 */
+ RVI( 73, W, 179, 0, 0, 19, 0, 0, 35, CT_COPPER_ORE , 0 ), /* 70 */
+ RVI( 47, W, 199, 0, 0, 25, 0, 0, 30, CT_WATER , 0 ), /* 71 */
+ RVI( 48, W, 182, 0, 0, 18, 0, 0, 30, CT_FRUIT , 0 ), /* 72 */
+ RVI( 49, W, 185, 0, 0, 19, 0, 0, 26, CT_RUBBER , 0 ), /* 73 */
+ RVI( 50, W, 176, 0, 0, 19, 0, 0, 35, CT_SUGAR , 0 ), /* 74 */
+ RVI( 51, W, 178, 0, 0, 20, 0, 0, 35, CT_COTTON_CANDY, 0 ), /* 75 */
+ RVI( 52, W, 192, 0, 0, 20, 0, 0, 35, CT_TOFFEE , 0 ), /* 76 */
+ RVI( 53, W, 190, 0, 0, 21, 0, 0, 25, CT_BUBBLES , 0 ), /* 77 */
+ RVI( 54, W, 182, 0, 0, 24, 0, 0, 30, CT_COLA , 0 ), /* 78 */
+ RVI( 55, W, 181, 0, 0, 21, 0, 0, 30, CT_CANDY , 0 ), /* 79 */
+ RVI( 56, W, 183, 0, 0, 21, 0, 0, 25, CT_TOYS , 0 ), /* 80 */
+ RVI( 57, W, 196, 0, 0, 18, 0, 0, 27, CT_BATTERIES , 0 ), /* 81 */
+ RVI( 58, W, 193, 0, 0, 18, 0, 0, 30, CT_FIZZY_DRINKS, 0 ), /* 82 */
+ RVI( 59, W, 191, 0, 0, 18, 0, 0, 35, CT_PLASTIC , 0 ), /* 83 */
+ RVI( 28, 0, 70, 400, 10000, 105, 250, E, 0, 0 , 70 ), /* 84 */
+ RVI( 29, 0, 74, 448, 12000, 120, 253, E, 0, 0 , 71 ), /* 85 */
+ RVI( 30, 0, 82, 480, 15000, 130, 254, E, 0, 0 , 72 ), /* 86 */
+ RVI( 31, M, 95, 640, 20000/2,150/2,255/2, E, 0, 0 , 73 ), /* 87 */
+ RVI( 28, 0, 70, 480, 10000, 120, 250, E, 0, 0 , 74 ), /* 88 */
+ RVI( 60, W, 247, 0, 0, 25, 0, 0, 47, CT_PASSENGERS , 0 ), /* 89 */
+ RVI( 62, W, 228, 0, 0, 21, 0, 0, 37, CT_MAIL , 0 ), /* 90 */
+ RVI( 61, W, 176, 0, 0, 18, 0, 0, 37, CT_COAL , 0 ), /* 91 */
+ RVI( 63, W, 200, 0, 0, 24, 0, 0, 37, CT_OIL , 0 ), /* 92 */
+ RVI( 64, W, 192, 0, 0, 20, 0, 0, 32, CT_LIVESTOCK , 0 ), /* 93 */
+ RVI( 65, W, 190, 0, 0, 21, 0, 0, 32, CT_GOODS , 0 ), /* 94 */
+ RVI( 66, W, 182, 0, 0, 19, 0, 0, 37, CT_GRAIN , 0 ), /* 95 */
+ RVI( 67, W, 181, 0, 0, 16, 0, 0, 37, CT_WOOD , 0 ), /* 96 */
+ RVI( 68, W, 179, 0, 0, 19, 0, 0, 37, CT_IRON_ORE , 0 ), /* 97 */
+ RVI( 69, W, 196, 0, 0, 18, 0, 0, 27, CT_STEEL , 0 ), /* 98 */
+ RVI( 70, W, 255, 0, 0, 30, 0, 0, 27, CT_VALUABLES , 0 ), /* 99 */
+ RVI( 71, W, 191, 0, 0, 22, 0, 0, 32, CT_FOOD , 0 ), /* 100 */
+ RVI( 72, W, 196, 0, 0, 18, 0, 0, 27, CT_PAPER , 0 ), /* 101 */
+ RVI( 73, W, 179, 0, 0, 19, 0, 0, 37, CT_COPPER_ORE , 0 ), /* 102 */
+ RVI( 47, W, 199, 0, 0, 25, 0, 0, 32, CT_WATER , 0 ), /* 103 */
+ RVI( 48, W, 182, 0, 0, 18, 0, 0, 32, CT_FRUIT , 0 ), /* 104 */
+ RVI( 49, W, 185, 0, 0, 19, 0, 0, 28, CT_RUBBER , 0 ), /* 105 */
+ RVI( 50, W, 176, 0, 0, 19, 0, 0, 37, CT_SUGAR , 0 ), /* 106 */
+ RVI( 51, W, 178, 0, 0, 20, 0, 0, 37, CT_COTTON_CANDY, 0 ), /* 107 */
+ RVI( 52, W, 192, 0, 0, 20, 0, 0, 37, CT_TOFFEE , 0 ), /* 108 */
+ RVI( 53, W, 190, 0, 0, 21, 0, 0, 27, CT_BUBBLES , 0 ), /* 109 */
+ RVI( 54, W, 182, 0, 0, 24, 0, 0, 32, CT_COLA , 0 ), /* 110 */
+ RVI( 55, W, 181, 0, 0, 21, 0, 0, 32, CT_CANDY , 0 ), /* 111 */
+ RVI( 56, W, 183, 0, 0, 21, 0, 0, 27, CT_TOYS , 0 ), /* 112 */
+ RVI( 57, W, 196, 0, 0, 18, 0, 0, 29, CT_BATTERIES , 0 ), /* 113 */
+ RVI( 58, W, 193, 0, 0, 18, 0, 0, 32, CT_FIZZY_DRINKS, 0 ), /* 114 */
+ RVI( 59, W, 191, 0, 0, 18, 0, 0, 37, CT_PLASTIC , 0 ), /* 115 */
+};
+#undef E
+#undef D
+#undef S
+#undef W
+#undef M
+#undef RVI
+
+/** Writes the properties of a ship into the ShipVehicleInfo struct.
+ * @see ShipVehicleInfo
+ * @param a image_index
+ * @param b base_cost
+ * @param c max_speed
+ * @param d cargo_type
+ * @param e cargo_amount
+ * @param f running_cost
+ * @param g sound effect
+ * @param h refittable
+ */
+#define SVI(a, b, c, d, e, f, g, h) { a, b, c, d, e, f, g, h }
+const ShipVehicleInfo orig_ship_vehicle_info[NUM_SHIP_ENGINES] = {
+ // image_index cargo_type cargo_amount refittable
+ // | base_cost | | running_cost |
+ // | | max_speed | | sfx |
+ // | | | | | | | |
+ SVI( 1, 160, 48, CT_OIL, 220, 140, SND_06_SHIP_HORN, 0 ), /* 0 */
+ SVI( 1, 176, 80, CT_OIL, 350, 125, SND_06_SHIP_HORN, 0 ), /* 1 */
+ SVI( 2, 96, 64, CT_PASSENGERS, 100, 90, SND_07_FERRY_HORN, 0 ), /* 2 */
+ SVI( 2, 112, 128, CT_PASSENGERS, 130, 80, SND_07_FERRY_HORN, 0 ), /* 3 */
+ SVI( 3, 148, 224, CT_PASSENGERS, 100, 190, SND_07_FERRY_HORN, 0 ), /* 4 */
+ SVI( 2, 96, 64, CT_PASSENGERS, 100, 90, SND_07_FERRY_HORN, 0 ), /* 5 */
+ SVI( 2, 112, 128, CT_PASSENGERS, 130, 80, SND_07_FERRY_HORN, 0 ), /* 6 */
+ SVI( 0, 128, 48, CT_GOODS, 160, 150, SND_06_SHIP_HORN, 1 ), /* 7 */
+ SVI( 0, 144, 80, CT_GOODS, 190, 113, SND_06_SHIP_HORN, 1 ), /* 8 */
+ SVI( 0, 128, 48, CT_GOODS, 160, 150, SND_06_SHIP_HORN, 1 ), /* 9 */
+ SVI( 0, 144, 80, CT_GOODS, 190, 113, SND_06_SHIP_HORN, 1 ), /* 10 */
+};
+#undef SVI
+
+/** Writes the properties of an aircraft into the AircraftVehicleInfo struct.
+ * @see AircraftVehicleInfo
+ * @param a image_index
+ * @param b base_cost
+ * @param c running_Cost
+ * @param d subtype (bit 0 - plane, bit 1 - large plane)
+ * @param e sound effect
+ * @param f acceleration
+ * @param g max_speed
+ * @param h mail_capacity
+ * @param i passenger_capacity
+ */
+#define AVI(a, b, c, d, e, f, g, h, i) { a, b, c, d, e, f, g, h, i }
+#define H 0
+#define P AIR_CTOL
+#define J AIR_CTOL | AIR_FAST
+const AircraftVehicleInfo orig_aircraft_vehicle_info[NUM_AIRCRAFT_ENGINES] = {
+ // image_index sfx acceleration
+ // | base_cost | | max_speed
+ // | | running_cost | | mail_capacity
+ // | | | subtype | | | | passenger_capacity
+ // | | | | | | | | |
+ AVI( 1, 14, 85, P, SND_08_PLANE_TAKE_OFF, 18, 37, 4, 25 ), /* 0 */
+ AVI( 0, 15, 100, P, SND_08_PLANE_TAKE_OFF, 20, 37, 8, 65 ), /* 1 */
+ AVI( 2, 16, 130, J, SND_09_JET, 35, 74, 10, 90 ), /* 2 */
+ AVI( 8, 75, 250, J, SND_3B_JET_OVERHEAD, 50, 181, 20, 100 ), /* 3 */
+ AVI( 5, 15, 98, P, SND_08_PLANE_TAKE_OFF, 20, 37, 6, 30 ), /* 4 */
+ AVI( 6, 18, 240, J, SND_09_JET, 40, 74, 30, 200 ), /* 5 */
+ AVI( 2, 17, 150, P, SND_09_JET, 35, 74, 15, 100 ), /* 6 */
+ AVI( 2, 18, 245, J, SND_09_JET, 40, 74, 30, 150 ), /* 7 */
+ AVI( 3, 19, 192, J, SND_09_JET, 40, 74, 40, 220 ), /* 8 */
+ AVI( 3, 20, 190, J, SND_09_JET, 40, 74, 25, 230 ), /* 9 */
+ AVI( 2, 16, 135, J, SND_09_JET, 35, 74, 10, 95 ), /* 10 */
+ AVI( 2, 18, 240, J, SND_09_JET, 40, 74, 35, 170 ), /* 11 */
+ AVI( 4, 17, 155, J, SND_09_JET, 40, 74, 15, 110 ), /* 12 */
+ AVI( 7, 30, 253, J, SND_3D_ANOTHER_JET_OVERHEAD, 40, 74, 50, 300 ), /* 13 */
+ AVI( 4, 18, 210, J, SND_09_JET, 40, 74, 25, 200 ), /* 14 */
+ AVI( 4, 19, 220, J, SND_09_JET, 40, 74, 25, 240 ), /* 15 */
+ AVI( 4, 27, 230, J, SND_09_JET, 40, 74, 40, 260 ), /* 16 */
+ AVI( 3, 25, 225, J, SND_09_JET, 40, 74, 35, 240 ), /* 17 */
+ AVI( 4, 20, 235, J, SND_09_JET, 40, 74, 30, 260 ), /* 18 */
+ AVI( 4, 19, 220, J, SND_09_JET, 40, 74, 25, 210 ), /* 19 */
+ AVI( 4, 18, 170, J, SND_09_JET, 40, 74, 20, 160 ), /* 20 */
+ AVI( 4, 26, 210, J, SND_09_JET, 40, 74, 20, 220 ), /* 21 */
+ AVI( 6, 16, 125, P, SND_09_JET, 50, 74, 10, 80 ), /* 22 */
+ AVI( 2, 17, 145, P, SND_09_JET, 40, 74, 10, 85 ), /* 23 */
+ AVI( 11, 16, 130, J, SND_09_JET, 40, 74, 10, 75 ), /* 24 */
+ AVI( 10, 16, 149, J, SND_09_JET, 40, 74, 10, 85 ), /* 25 */
+ AVI( 15, 17, 170, J, SND_09_JET, 40, 74, 18, 65 ), /* 26 */
+ AVI( 12, 18, 210, J, SND_09_JET, 40, 74, 25, 110 ), /* 27 */
+ AVI( 13, 20, 230, J, SND_09_JET, 40, 74, 60, 180 ), /* 28 */
+ AVI( 14, 21, 220, J, SND_09_JET, 40, 74, 65, 150 ), /* 29 */
+ AVI( 16, 19, 160, J, SND_09_JET, 40, 181, 45, 85 ), /* 30 */
+ AVI( 17, 24, 248, J, SND_3D_ANOTHER_JET_OVERHEAD, 40, 74, 80, 400 ), /* 31 */
+ AVI( 18, 80, 251, J, SND_3B_JET_OVERHEAD, 50, 181, 45, 130 ), /* 32 */
+ AVI( 20, 13, 85, P, SND_45_PLANE_CRASHING, 18, 37, 5, 25 ), /* 33 */
+ AVI( 21, 18, 100, P, SND_46_PLANE_ENGINE_SPUTTERING, 20, 37, 9, 60 ), /* 34 */
+ AVI( 22, 25, 140, P, SND_09_JET, 40, 74, 12, 90 ), /* 35 */
+ AVI( 23, 32, 220, J, SND_3D_ANOTHER_JET_OVERHEAD, 40, 74, 40, 200 ), /* 36 */
+ AVI( 24, 80, 255, J, SND_3B_JET_OVERHEAD, 50, 181, 30, 100 ), /* 37 */
+ AVI( 9, 15, 81, H, SND_09_JET, 20, 25, 15, 40 ), /* 38 */
+ AVI( 19, 17, 77, H, SND_09_JET, 20, 40, 20, 55 ), /* 39 */
+ AVI( 25, 15, 80, H, SND_09_JET, 20, 25, 10, 40 ), /* 40 */
+};
+#undef J
+#undef P
+#undef H
+#undef AVI
+
+/** Writes the properties of a road vehicle into the RoadVehicleInfo struct.
+ * @see RoadVehicleInfo
+ * @param a image_index
+ * @param b base_cost
+ * @param c running_cost
+ * @param d sound effect
+ * @param e max_speed
+ * @param f capacity
+ * @param g cargo_type
+ */
+#define RVI(a, b, c, d, e, f, g) { a, b, c, d, e, f, g }
+const RoadVehicleInfo orig_road_vehicle_info[NUM_ROAD_ENGINES] = {
+ // image_index sfx max_speed
+ // | base_cost | | capacity
+ // | | running_cost | | cargo_type
+ // | | | | | | |
+ RVI( 0, 120, 91, SND_19_BUS_START_PULL_AWAY, 112, 31, CT_PASSENGERS ), /* 0 */
+ RVI( 17, 140, 128, SND_1C_TRUCK_START_2, 176, 35, CT_PASSENGERS ), /* 1 */
+ RVI( 17, 150, 178, SND_1B_TRUCK_START, 224, 37, CT_PASSENGERS ), /* 2 */
+ RVI( 34, 160, 240, SND_1B_TRUCK_START, 255, 40, CT_PASSENGERS ), /* 3 */
+ RVI( 51, 120, 91, SND_3C_COMEDY_CAR, 112, 30, CT_PASSENGERS ), /* 4 */
+ RVI( 51, 140, 171, SND_3E_COMEDY_CAR_2, 192, 35, CT_PASSENGERS ), /* 5 */
+ RVI( 51, 160, 240, SND_3C_COMEDY_CAR, 240, 38, CT_PASSENGERS ), /* 6 */
+ RVI( 1, 108, 90, SND_19_BUS_START_PULL_AWAY, 96, 20, CT_COAL ), /* 7 */
+ RVI( 18, 128, 168, SND_19_BUS_START_PULL_AWAY, 176, 25, CT_COAL ), /* 8 */
+ RVI( 35, 138, 240, SND_19_BUS_START_PULL_AWAY, 224, 28, CT_COAL ), /* 9 */
+ RVI( 2, 115, 90, SND_19_BUS_START_PULL_AWAY, 96, 22, CT_MAIL ), /* 10 */
+ RVI( 19, 135, 168, SND_19_BUS_START_PULL_AWAY, 176, 28, CT_MAIL ), /* 11 */
+ RVI( 36, 145, 240, SND_19_BUS_START_PULL_AWAY, 224, 30, CT_MAIL ), /* 12 */
+ RVI( 57, 115, 90, SND_3E_COMEDY_CAR_2, 96, 22, CT_MAIL ), /* 13 */
+ RVI( 57, 135, 168, SND_3C_COMEDY_CAR, 176, 28, CT_MAIL ), /* 14 */
+ RVI( 57, 145, 240, SND_3E_COMEDY_CAR_2, 224, 30, CT_MAIL ), /* 15 */
+ RVI( 3, 110, 90, SND_19_BUS_START_PULL_AWAY, 96, 21, CT_OIL ), /* 16 */
+ RVI( 20, 140, 168, SND_19_BUS_START_PULL_AWAY, 176, 25, CT_OIL ), /* 17 */
+ RVI( 37, 150, 240, SND_19_BUS_START_PULL_AWAY, 224, 27, CT_OIL ), /* 18 */
+ RVI( 4, 105, 90, SND_19_BUS_START_PULL_AWAY, 96, 14, CT_LIVESTOCK ), /* 19 */
+ RVI( 21, 130, 168, SND_19_BUS_START_PULL_AWAY, 176, 16, CT_LIVESTOCK ), /* 20 */
+ RVI( 38, 140, 240, SND_19_BUS_START_PULL_AWAY, 224, 18, CT_LIVESTOCK ), /* 21 */
+ RVI( 5, 107, 90, SND_19_BUS_START_PULL_AWAY, 96, 14, CT_GOODS ), /* 22 */
+ RVI( 22, 130, 168, SND_19_BUS_START_PULL_AWAY, 176, 16, CT_GOODS ), /* 23 */
+ RVI( 39, 140, 240, SND_19_BUS_START_PULL_AWAY, 224, 18, CT_GOODS ), /* 24 */
+ RVI( 6, 114, 90, SND_19_BUS_START_PULL_AWAY, 96, 20, CT_GRAIN ), /* 25 */
+ RVI( 23, 133, 168, SND_19_BUS_START_PULL_AWAY, 176, 25, CT_GRAIN ), /* 26 */
+ RVI( 40, 143, 240, SND_19_BUS_START_PULL_AWAY, 224, 30, CT_GRAIN ), /* 27 */
+ RVI( 7, 118, 90, SND_19_BUS_START_PULL_AWAY, 96, 20, CT_WOOD ), /* 28 */
+ RVI( 24, 137, 168, SND_19_BUS_START_PULL_AWAY, 176, 22, CT_WOOD ), /* 29 */
+ RVI( 41, 147, 240, SND_19_BUS_START_PULL_AWAY, 224, 24, CT_WOOD ), /* 30 */
+ RVI( 8, 121, 90, SND_19_BUS_START_PULL_AWAY, 96, 22, CT_IRON_ORE ), /* 31 */
+ RVI( 25, 140, 168, SND_19_BUS_START_PULL_AWAY, 176, 25, CT_IRON_ORE ), /* 32 */
+ RVI( 42, 150, 240, SND_19_BUS_START_PULL_AWAY, 224, 27, CT_IRON_ORE ), /* 33 */
+ RVI( 9, 112, 90, SND_19_BUS_START_PULL_AWAY, 96, 15, CT_STEEL ), /* 34 */
+ RVI( 26, 135, 168, SND_19_BUS_START_PULL_AWAY, 176, 18, CT_STEEL ), /* 35 */
+ RVI( 43, 145, 240, SND_19_BUS_START_PULL_AWAY, 224, 20, CT_STEEL ), /* 36 */
+ RVI( 10, 145, 90, SND_19_BUS_START_PULL_AWAY, 96, 12, CT_VALUABLES ), /* 37 */
+ RVI( 27, 170, 168, SND_19_BUS_START_PULL_AWAY, 176, 15, CT_VALUABLES ), /* 38 */
+ RVI( 44, 180, 240, SND_19_BUS_START_PULL_AWAY, 224, 16, CT_VALUABLES ), /* 39 */
+ RVI( 11, 112, 90, SND_19_BUS_START_PULL_AWAY, 96, 17, CT_FOOD ), /* 40 */
+ RVI( 28, 134, 168, SND_19_BUS_START_PULL_AWAY, 176, 20, CT_FOOD ), /* 41 */
+ RVI( 45, 144, 240, SND_19_BUS_START_PULL_AWAY, 224, 22, CT_FOOD ), /* 42 */
+ RVI( 12, 112, 90, SND_19_BUS_START_PULL_AWAY, 96, 15, CT_PAPER ), /* 43 */
+ RVI( 29, 135, 168, SND_19_BUS_START_PULL_AWAY, 176, 18, CT_PAPER ), /* 44 */
+ RVI( 46, 145, 240, SND_19_BUS_START_PULL_AWAY, 224, 20, CT_PAPER ), /* 45 */
+ RVI( 13, 121, 90, SND_19_BUS_START_PULL_AWAY, 96, 22, CT_COPPER_ORE ), /* 46 */
+ RVI( 30, 140, 168, SND_19_BUS_START_PULL_AWAY, 176, 25, CT_COPPER_ORE ), /* 47 */
+ RVI( 47, 150, 240, SND_19_BUS_START_PULL_AWAY, 224, 27, CT_COPPER_ORE ), /* 48 */
+ RVI( 14, 111, 90, SND_19_BUS_START_PULL_AWAY, 96, 21, CT_WATER ), /* 49 */
+ RVI( 31, 141, 168, SND_19_BUS_START_PULL_AWAY, 176, 25, CT_WATER ), /* 50 */
+ RVI( 48, 151, 240, SND_19_BUS_START_PULL_AWAY, 224, 27, CT_WATER ), /* 51 */
+ RVI( 15, 118, 90, SND_19_BUS_START_PULL_AWAY, 96, 18, CT_FRUIT ), /* 52 */
+ RVI( 32, 148, 168, SND_19_BUS_START_PULL_AWAY, 176, 20, CT_FRUIT ), /* 53 */
+ RVI( 49, 158, 240, SND_19_BUS_START_PULL_AWAY, 224, 23, CT_FRUIT ), /* 54 */
+ RVI( 16, 117, 90, SND_19_BUS_START_PULL_AWAY, 96, 17, CT_RUBBER ), /* 55 */
+ RVI( 33, 147, 168, SND_19_BUS_START_PULL_AWAY, 176, 19, CT_RUBBER ), /* 56 */
+ RVI( 50, 157, 240, SND_19_BUS_START_PULL_AWAY, 224, 22, CT_RUBBER ), /* 57 */
+ RVI( 52, 117, 90, SND_3F_COMEDY_CAR_3, 96, 17, CT_SUGAR ), /* 58 */
+ RVI( 52, 147, 168, SND_40_COMEDY_CAR_START_AND_PULL_AWAY, 176, 19, CT_SUGAR ), /* 59 */
+ RVI( 52, 157, 240, SND_3F_COMEDY_CAR_3, 224, 22, CT_SUGAR ), /* 60 */
+ RVI( 53, 117, 90, SND_40_COMEDY_CAR_START_AND_PULL_AWAY, 96, 17, CT_COLA ), /* 61 */
+ RVI( 53, 147, 168, SND_3F_COMEDY_CAR_3, 176, 19, CT_COLA ), /* 62 */
+ RVI( 53, 157, 240, SND_40_COMEDY_CAR_START_AND_PULL_AWAY, 224, 22, CT_COLA ), /* 63 */
+ RVI( 54, 117, 90, SND_3F_COMEDY_CAR_3, 96, 17, CT_COTTON_CANDY ), /* 64 */
+ RVI( 54, 147, 168, SND_40_COMEDY_CAR_START_AND_PULL_AWAY, 176, 19, CT_COTTON_CANDY ), /* 65 */
+ RVI( 54, 157, 240, SND_3F_COMEDY_CAR_3, 224, 22, CT_COTTON_CANDY ), /* 66 */
+ RVI( 55, 117, 90, SND_40_COMEDY_CAR_START_AND_PULL_AWAY, 96, 17, CT_TOFFEE ), /* 67 */
+ RVI( 55, 147, 168, SND_3F_COMEDY_CAR_3, 176, 19, CT_TOFFEE ), /* 68 */
+ RVI( 55, 157, 240, SND_40_COMEDY_CAR_START_AND_PULL_AWAY, 224, 22, CT_TOFFEE ), /* 69 */
+ RVI( 56, 117, 90, SND_3F_COMEDY_CAR_3, 96, 17, CT_TOYS ), /* 70 */
+ RVI( 56, 147, 168, SND_40_COMEDY_CAR_START_AND_PULL_AWAY, 176, 19, CT_TOYS ), /* 71 */
+ RVI( 56, 157, 240, SND_3F_COMEDY_CAR_3, 224, 22, CT_TOYS ), /* 72 */
+ RVI( 58, 117, 90, SND_40_COMEDY_CAR_START_AND_PULL_AWAY, 96, 17, CT_CANDY ), /* 73 */
+ RVI( 58, 147, 168, SND_3F_COMEDY_CAR_3, 176, 19, CT_CANDY ), /* 74 */
+ RVI( 58, 157, 240, SND_40_COMEDY_CAR_START_AND_PULL_AWAY, 224, 22, CT_CANDY ), /* 75 */
+ RVI( 59, 117, 90, SND_3F_COMEDY_CAR_3, 96, 17, CT_BATTERIES ), /* 76 */
+ RVI( 59, 147, 168, SND_40_COMEDY_CAR_START_AND_PULL_AWAY, 176, 19, CT_BATTERIES ), /* 77 */
+ RVI( 59, 157, 240, SND_3F_COMEDY_CAR_3, 224, 22, CT_BATTERIES ), /* 78 */
+ RVI( 60, 117, 90, SND_40_COMEDY_CAR_START_AND_PULL_AWAY, 96, 17, CT_FIZZY_DRINKS ), /* 79 */
+ RVI( 60, 147, 168, SND_3F_COMEDY_CAR_3, 176, 19, CT_FIZZY_DRINKS ), /* 80 */
+ RVI( 60, 157, 240, SND_40_COMEDY_CAR_START_AND_PULL_AWAY, 224, 22, CT_FIZZY_DRINKS ), /* 81 */
+ RVI( 61, 117, 90, SND_3F_COMEDY_CAR_3, 96, 17, CT_PLASTIC ), /* 82 */
+ RVI( 61, 147, 168, SND_40_COMEDY_CAR_START_AND_PULL_AWAY, 176, 19, CT_PLASTIC ), /* 83 */
+ RVI( 61, 157, 240, SND_3F_COMEDY_CAR_3, 224, 22, CT_PLASTIC ), /* 84 */
+ RVI( 62, 117, 90, SND_40_COMEDY_CAR_START_AND_PULL_AWAY, 96, 17, CT_BUBBLES ), /* 85 */
+ RVI( 62, 147, 168, SND_3F_COMEDY_CAR_3, 176, 19, CT_BUBBLES ), /* 86 */
+ RVI( 62, 157, 240, SND_40_COMEDY_CAR_START_AND_PULL_AWAY, 224, 22, CT_BUBBLES ), /* 87 */
+};
+#undef RVI
+
+#endif /* ENGINES_H */
diff --git a/src/table/files.h b/src/table/files.h
new file mode 100644
index 000000000..4dfdfebb6
--- /dev/null
+++ b/src/table/files.h
@@ -0,0 +1,64 @@
+/* $Id$ */
+
+/*
+ MD5 sums of graphics files
+
+ DOS -
+
+ TRG1.GRF 9311676280e5b14077a8ee41c1b42192
+ TRGC.GRF ed446637e034104c5559b32c18afe78d
+ TRGH.GRF ee6616fb0e6ef6b24892c58c93d86fc9
+ TRGI.GRF da6a6c9dcc451eec88d79211437b76a8
+ TRGT.GRF fcde1d7e8a74197d72a62695884b909e
+ SAMPLE.CAT 422ea3dd074d2859bb51639a6e0e85da
+
+ WINDOWS -
+
+ TRG1R.GRF b04ce593d8c5016e07473a743d7d3358
+ TRGCR.GRF 3668f410c761a050b5e7095a2b14879b
+ TRGHR.GRF 06bf2b7a31766f048baac2ebe43457b1
+ TRGIR.GRF 0c2484ff6be49fc63a83be6ab5c38f32
+ TRGTR.GRF de53650517fe661ceaa3138c6edb0eb8
+ SAMPLE.CAT 9212e81e72badd4bbe1eaeae66458e10
+*/
+
+
+static FileList files_dos = {
+ {
+ { "TRG1.GRF", {0x93, 0x11, 0x67, 0x62, 0x80, 0xe5, 0xb1, 0x40, 0x77, 0xa8, 0xee, 0x41, 0xc1, 0xb4, 0x21, 0x92} }, // 0 - 4792 inclusive
+ { "TRGI.GRF", {0xda, 0x6a, 0x6c, 0x9d, 0xcc, 0x45, 0x1e, 0xec, 0x88, 0xd7, 0x92, 0x11, 0x43, 0x7b, 0x76, 0xa8} }, // 4793 - 4889 inclusive
+ { "dosdummy.grf", {0x07, 0x01, 0xe6, 0xc4, 0x07, 0x6a, 0x5b, 0xc3, 0xf4, 0x9f, 0x01, 0xad, 0x21, 0x6c, 0xa0, 0xc2} }, // 4890 - 4895 inclusive
+ { NULL, { 0 } }
+ }, {
+ { "TRGC.GRF", {0xed, 0x44, 0x66, 0x37, 0xe0, 0x34, 0x10, 0x4c, 0x55, 0x59, 0xb3, 0x2c, 0x18, 0xaf, 0xe7, 0x8d} },
+ { "TRGH.GRF", {0xee, 0x66, 0x16, 0xfb, 0x0e, 0x6e, 0xf6, 0xb2, 0x48, 0x92, 0xc5, 0x8c, 0x93, 0xd8, 0x6f, 0xc9} },
+ { "TRGT.GRF", {0xfc, 0xde, 0x1d, 0x7e, 0x8a, 0x74, 0x19, 0x7d, 0x72, 0xa6, 0x26, 0x95, 0x88, 0x4b, 0x90, 0x9e} }
+ }
+};
+
+static FileList files_win = {
+ {
+ { "TRG1R.GRF", {0xb0, 0x4c, 0xe5, 0x93, 0xd8, 0xc5, 0x01, 0x6e, 0x07, 0x47, 0x3a, 0x74, 0x3d, 0x7d, 0x33, 0x58} }, // 0 - 4792 inclusive
+ { "TRGIR.GRF", {0x0c, 0x24, 0x84, 0xff, 0x6b, 0xe4, 0x9f, 0xc6, 0x3a, 0x83, 0xbe, 0x6a, 0xb5, 0xc3, 0x8f, 0x32} }, // 4793 - 4895 inclusive
+ { NULL, { 0 } },
+ { NULL, { 0 } }
+ }, {
+ { "TRGCR.GRF", {0x36, 0x68, 0xf4, 0x10, 0xc7, 0x61, 0xa0, 0x50, 0xb5, 0xe7, 0x09, 0x5a, 0x2b, 0x14, 0x87, 0x9b} },
+ { "TRGHR.GRF", {0x06, 0xbf, 0x2b, 0x7a, 0x31, 0x76, 0x6f, 0x04, 0x8b, 0xaa, 0xc2, 0xeb, 0xe4, 0x34, 0x57, 0xb1} },
+ { "TRGTR.GRF", {0xde, 0x53, 0x65, 0x05, 0x17, 0xfe, 0x66, 0x1c, 0xea, 0xa3, 0x13, 0x8c, 0x6e, 0xdb, 0x0e, 0xb8} }
+ }
+};
+
+static MD5File sample_cat_win = { "SAMPLE.CAT", {0x92, 0x12, 0xe8, 0x1e, 0x72, 0xba, 0xdd, 0x4b, 0xbe, 0x1e, 0xae, 0xae, 0x66, 0x45, 0x8e, 0x10} };
+static MD5File sample_cat_dos = { "SAMPLE.CAT", {0x42, 0x2e, 0xa3, 0xdd, 0x07, 0x4d, 0x28, 0x59, 0xbb, 0x51, 0x63, 0x9a, 0x6e, 0x0e, 0x85, 0xda} };
+
+static MD5File files_openttd[] = {
+ { "nsignalsw.grf", { 0x65, 0xb9, 0xd7, 0x30, 0x56, 0x06, 0xcc, 0x9e, 0x27, 0x57, 0xc8, 0xe4, 0x9b, 0xb3, 0x66, 0x81 } },
+ { "2ccmap.grf", { 0x20, 0x03, 0x32, 0x1a, 0x43, 0x6c, 0xc1, 0x05, 0x80, 0xbd, 0x43, 0xeb, 0xe1, 0xfd, 0x0c, 0x62 } },
+ { "airports.grf", { 0xfd, 0xa4, 0x38, 0xd6, 0x9c, 0x81, 0x74, 0xfe, 0xa0, 0x98, 0xa2, 0x14, 0x4b, 0x15, 0xb8, 0x4b } },
+ { "autorail.grf", { 0xed, 0x44, 0x7f, 0xbb, 0x19, 0x44, 0x48, 0x4c, 0x07, 0x8a, 0xb1, 0xc1, 0x5c, 0x12, 0x3a, 0x60 } },
+ { "canalsw.grf", { 0x13, 0x9c, 0x98, 0xcf, 0xb8, 0x7c, 0xd7, 0x1f, 0xca, 0x34, 0xa5, 0x6b, 0x65, 0x31, 0xec, 0x0f } },
+ { "elrailsw.grf", { 0x4f, 0xf9, 0xac, 0x79, 0x50, 0x28, 0x9b, 0xe2, 0x15, 0x30, 0xa8, 0x1e, 0xd5, 0xfd, 0xe1, 0xda } },
+ { "openttd.grf", { 0x59, 0x22, 0x19, 0xe0, 0x6e, 0xe7, 0xb6, 0xa3, 0x55, 0x53, 0xcc, 0x9e, 0xbc, 0xaf, 0xcc, 0x83 } },
+ { "trkfoundw.grf", { 0x12, 0x33, 0x3f, 0xa3, 0xd1, 0x86, 0x8b, 0x04, 0x53, 0x18, 0x9c, 0xee, 0xf9, 0x2d, 0xf5, 0x95 } },
+};
diff --git a/src/table/genland.h b/src/table/genland.h
new file mode 100644
index 000000000..4007f8db3
--- /dev/null
+++ b/src/table/genland.h
@@ -0,0 +1,159 @@
+/* $Id$ */
+
+#define M(x, y) {x, y}
+
+static const TileIndexDiffC _make_desert_or_rainforest_data[] = {
+ M(-5, -6),
+ M(-4, -6),
+ M(-3, -6),
+ M(-2, -6),
+ M(-1, -6),
+ M( 0, -5),
+ M( 1, -5),
+ M( 2, -5),
+ M( 3, -5),
+ M( 4, -5),
+ M( 5, -5),
+ M(-5, -5),
+ M(-4, -5),
+ M(-3, -5),
+ M(-2, -5),
+ M(-1, -5),
+ M( 0, -4),
+ M( 1, -4),
+ M( 2, -4),
+ M( 3, -4),
+ M( 4, -4),
+ M( 5, -4),
+ M(-5, -4),
+ M(-4, -4),
+ M(-3, -4),
+ M(-2, -4),
+ M(-1, -4),
+ M( 0, -3),
+ M( 1, -3),
+ M( 2, -3),
+ M( 3, -3),
+ M( 4, -3),
+ M( 5, -3),
+ M(-5, -3),
+ M(-4, -3),
+ M(-3, -3),
+ M(-2, -3),
+ M(-1, -3),
+ M( 0, -2),
+ M( 1, -2),
+ M( 2, -2),
+ M( 3, -2),
+ M( 4, -2),
+ M( 5, -2),
+ M(-5, -2),
+ M(-4, -2),
+ M(-3, -2),
+ M(-2, -2),
+ M(-1, -2),
+ M( 0, -1),
+ M( 1, -1),
+ M( 2, -1),
+ M( 3, -1),
+ M( 4, -1),
+ M( 5, -1),
+ M(-5, -1),
+ M(-4, -1),
+ M(-3, -1),
+ M(-2, -1),
+ M(-1, -1),
+ M( 0, 0),
+ M( 1, 0),
+ M( 2, 0),
+ M( 3, 0),
+ M( 4, 0),
+ M( 5, 0),
+ M(-5, 0),
+ M(-4, 0),
+ M(-3, 0),
+ M(-2, 0),
+ M(-1, 0),
+ M( 0, 1),
+ M( 1, 1),
+ M( 2, 1),
+ M( 3, 1),
+ M( 4, 1),
+ M( 5, 1),
+ M(-5, 1),
+ M(-4, 1),
+ M(-3, 1),
+ M(-2, 1),
+ M(-1, 1),
+ M( 0, 2),
+ M( 1, 2),
+ M( 2, 2),
+ M( 3, 2),
+ M( 4, 2),
+ M( 5, 2),
+ M(-5, 2),
+ M(-4, 2),
+ M(-3, 2),
+ M(-2, 2),
+ M(-1, 2),
+ M( 0, 3),
+ M( 1, 3),
+ M( 2, 3),
+ M( 3, 3),
+ M( 4, 3),
+ M( 5, 3),
+ M(-5, 3),
+ M(-4, 3),
+ M(-3, 3),
+ M(-2, 3),
+ M(-1, 3),
+ M( 0, 4),
+ M( 1, 4),
+ M( 2, 4),
+ M( 3, 4),
+ M( 4, 4),
+ M( 5, 4),
+ M(-5, 4),
+ M(-4, 4),
+ M(-3, 4),
+ M(-2, 4),
+ M(-1, 4),
+ M( 0, 5),
+ M( 1, 5),
+ M( 2, 5),
+ M( 3, 5),
+ M( 4, 5),
+ M( 5, 5),
+ M( 6, -3),
+ M(-6, -4),
+ M(-3, 5),
+ M(-3, -7),
+ M( 6, -2),
+ M(-6, -3),
+ M(-2, 5),
+ M(-2, -7),
+ M( 6, -1),
+ M(-6, -2),
+ M(-1, 5),
+ M(-1, -7),
+ M( 6, 0),
+ M(-6, -1),
+ M( 0, 6),
+ M( 0, -6),
+ M( 6, 1),
+ M(-6, 0),
+ M( 1, 6),
+ M( 1, -6),
+ M( 6, 2),
+ M(-6, 1),
+ M( 2, 6),
+ M( 2, -6),
+ M( 6, 3),
+ M(-6, 2),
+ M( 3, 6),
+ M( 3, -6)
+};
+
+
+
+#undef M
diff --git a/src/table/industry_land.h b/src/table/industry_land.h
new file mode 100644
index 000000000..60beb74fb
--- /dev/null
+++ b/src/table/industry_land.h
@@ -0,0 +1,1022 @@
+/* $Id$ */
+
+typedef struct DrawIndustrySpec1Struct {
+ byte x;
+ byte image_1;
+ byte image_2;
+ byte image_3;
+} DrawIndustrySpec1Struct;
+
+typedef struct DrawIndustrySpec4Struct {
+ byte image_1;
+ byte image_2;
+ byte image_3;
+} DrawIndustrySpec4Struct;
+
+#define M(s1, s2, sx, sy, w, h, dz, p) { s1, s2, sx, sy, w - 1, h - 1, dz, p }
+
+static const DrawBuildingsTileStruct _industry_draw_tile_data[NUM_INDUSTRY_GFXES * 4] = {
+ M( 0xf54, 0x7db, 7, 0, 9, 9, 10, 0),
+ M( 0xf54, 0x7dc, 7, 0, 9, 9, 30, 0),
+ M( 0xf54, 0x7dd, 7, 0, 9, 9, 30, 0),
+ M( 0x7e6, 0x7dd, 7, 0, 9, 9, 30, 0),
+ M( 0x7e6, 0x7dd, 7, 0, 9, 9, 30, 0),
+ M( 0x7e6, 0x7de, 7, 0, 9, 9, 30, 0),
+ M( 0x7e6, 0x7df, 7, 0, 9, 9, 30, 0),
+ M( 0x7e6, 0x7df, 7, 0, 9, 9, 30, 0),
+ M( 0xf54, 0x7e0, 1, 2, 15, 9, 30, 0),
+ M( 0xf54, 0x7e1, 1, 2, 15, 9, 30, 0),
+ M( 0xf54, 0x7e2, 1, 2, 15, 9, 30, 0),
+ M( 0x7e6, 0x7e2, 1, 2, 15, 9, 30, 0),
+ M( 0xf54, 0x7e3, 4, 4, 9, 9, 30, 0),
+ M( 0xf54, 0x7e4, 4, 4, 9, 9, 30, 0),
+ M( 0xf54, 0x7e5, 4, 4, 9, 9, 30, 0),
+ M( 0x7e6, 0x7e5, 4, 4, 9, 9, 30, 0),
+ M( 0xf54, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0xf54, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0x7e6, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0x7e9, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0xf54, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0xf54, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0x7e6, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0x7e7, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0xf54, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0xf54, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0x7e6, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0x7e8, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0xf54, 0x7fd, 1, 1, 14, 14, 5, 0),
+ M( 0xf54, 0x7fe, 1, 1, 14, 14, 44, 0),
+ M( 0xf54, 0x7ff, 1, 1, 14, 14, 44, 0),
+ M( 0xf54, 0x7ff, 1, 1, 14, 14, 44, 0),
+ M( 0xf54, 0x800, 0, 2, 16, 12, 6, 0),
+ M( 0xf54, 0x801, 0, 2, 16, 12, 47, 0),
+ M( 0xf54, 0x802, 0, 2, 16, 12, 50, 0),
+ M( 0xf54, 0x802, 0, 2, 16, 12, 50, 0),
+ M( 0xf54, 0x803, 1, 0, 14, 15, 5, 0),
+ M( 0xf54, 0x804, 1, 0, 14, 15, 19, 0),
+ M( 0xf54, 0x805, 1, 0, 14, 15, 21, 0),
+ M( 0xf54, 0x805, 1, 0, 14, 15, 21, 0),
+ M( 0xf54, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0xf54, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0xf54, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0xf54, 0x806, 1, 2, 14, 11, 32, 5),
+ M( 0xf54, 0x80d, 1, 0, 13, 16, 8, 0),
+ M( 0xf54, 0x80e, 1, 0, 13, 16, 20, 0),
+ M( 0xf54, 0x80f, 1, 0, 13, 16, 20, 0),
+ M( 0xf54, 0x80f, 1, 0, 13, 16, 20, 0),
+ M( 0xf54, 0x810, 0, 1, 16, 14, 8, 0),
+ M( 0xf54, 0x811, 0, 1, 16, 14, 21, 0),
+ M( 0xf54, 0x812, 0, 1, 16, 14, 21, 0),
+ M( 0xf54, 0x812, 0, 1, 16, 14, 21, 0),
+ M( 0xf54, 0x813, 1, 1, 14, 14, 12, 0),
+ M( 0xf54, 0x814, 1, 1, 14, 14, 15, 0),
+ M( 0xf54, 0x815, 1, 1, 14, 14, 22, 0),
+ M( 0xf54, 0x815, 1, 1, 14, 14, 22, 0),
+ M( 0xf54, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0xf54, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0xf54, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0xf54, 0x816, 0, 0, 16, 15, 20, 0),
+ M( 0xf54, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0xf54, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0xf54, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0xf54, 0x817, 0, 1, 16, 13, 19, 0),
+ M( 0x81d, 0x818, 0, 0, 16, 16, 10, 0),
+ M( 0x81d, 0x819, 0, 0, 16, 16, 15, 0),
+ M( 0x81d, 0x81a, 0, 0, 16, 16, 31, 0),
+ M( 0x81d, 0x81b, 0, 0, 16, 16, 39, 0),
+ M( 0x81d, 0x81c, 0, 0, 16, 16, 7, 0),
+ M( 0x81d, 0x81c, 0, 0, 16, 16, 7, 0),
+ M( 0x81d, 0x81c, 0, 0, 16, 16, 7, 0),
+ M( 0x81d, 0x81c, 0, 0, 16, 16, 7, 0),
+ M( 0xf54, 0x81e | PALETTE_MODIFIER_COLOR, 1, 1, 14, 14, 4, 0),
+ M( 0xf54, 0x81f | PALETTE_MODIFIER_COLOR, 1, 1, 14, 14, 24, 0),
+ M( 0xf54, 0x820 | PALETTE_MODIFIER_COLOR, 1, 1, 14, 14, 27, 0),
+ M( 0x58c, 0x820 | PALETTE_MODIFIER_COLOR, 1, 1, 14, 14, 27, 0),
+ M( 0xf54, 0x821 | PALETTE_MODIFIER_COLOR, 3, 3, 10, 9, 3, 0),
+ M( 0xf54, 0x822 | PALETTE_MODIFIER_COLOR, 3, 3, 10, 9, 63, 0),
+ M( 0xf54, 0x823 | PALETTE_MODIFIER_COLOR, 3, 3, 10, 9, 62, 0),
+ M( 0x58c, 0x823 | PALETTE_MODIFIER_COLOR, 3, 3, 10, 9, 62, 0),
+ M( 0xf54, 0x824 | PALETTE_MODIFIER_COLOR, 4, 4, 7, 7, 3, 0),
+ M( 0xf54, 0x825 | PALETTE_MODIFIER_COLOR, 4, 4, 7, 7, 72, 0),
+ M( 0xf54, 0x825 | PALETTE_MODIFIER_COLOR, 4, 4, 7, 7, 72, 0),
+ M( 0x58c, 0x826 | PALETTE_MODIFIER_COLOR, 4, 4, 7, 7, 80, 0),
+ M( 0xf54, 0x827 | PALETTE_MODIFIER_COLOR, 2, 0, 12, 16, 51, 0),
+ M( 0xf54, 0x828 | PALETTE_MODIFIER_COLOR, 2, 0, 12, 16, 51, 0),
+ M( 0xf54, 0x829 | PALETTE_MODIFIER_COLOR, 2, 0, 12, 16, 51, 0),
+ M( 0x58c, 0x829 | PALETTE_MODIFIER_COLOR, 2, 0, 12, 16, 51, 0),
+ M( 0xf54, 0x82a | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 26, 0),
+ M( 0xf54, 0x82b | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 44, 0),
+ M( 0xf54, 0x82c | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 46, 0),
+ M( 0x58c, 0x82c | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 46, 0),
+ M( 0xf54, 0x82d, 3, 1, 10, 13, 2, 0),
+ M( 0xf54, 0x82e, 3, 1, 10, 13, 11, 0),
+ M( 0xf54, 0x82f, 3, 1, 10, 13, 11, 0),
+ M( 0x58c, 0x82f, 3, 1, 10, 13, 11, 0),
+ M( 0xfdd, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0xfdd, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0xfdd, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0xfdd, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0xfdd, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0xfdd, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0xfdd, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0xfdd, 0x833, 0, 0, 16, 16, 20, 0),
+ M( 0xfdd, 0x837, 0, 0, 16, 16, 20, 0),
+ M( 0xfdd, 0x834, 0, 0, 16, 16, 20, 0),
+ M( 0xfdd, 0x834, 0, 0, 16, 16, 20, 0),
+ M( 0xfdd, 0x830, 0, 0, 16, 16, 20, 0),
+ M( 0xfdd, 0x838, 0, 0, 16, 16, 20, 0),
+ M( 0xfdd, 0x835, 0, 0, 16, 16, 20, 0),
+ M( 0xfdd, 0x835, 0, 0, 16, 16, 20, 0),
+ M( 0xfdd, 0x831, 0, 0, 16, 16, 20, 0),
+ M( 0xfdd, 0x839, 0, 0, 16, 16, 20, 0),
+ M( 0xfdd, 0x836, 0, 0, 16, 16, 20, 0),
+ M( 0xfdd, 0x836, 0, 0, 16, 16, 20, 0),
+ M( 0xfdd, 0x832, 0, 0, 16, 16, 20, 0),
+ M( 0x7e6, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0x87d, 0x87e, 0, 0, 16, 16, 20, 0),
+ M( 0x87d, 0x87e, 0, 0, 16, 16, 20, 0),
+ M( 0x87d, 0x87e, 0, 0, 16, 16, 20, 0),
+ M( 0x87d, 0x87e, 0, 0, 16, 16, 20, 0),
+ M( 0x87d, 0x87f, 0, 0, 16, 16, 20, 0),
+ M( 0x87d, 0x880, 0, 0, 16, 16, 20, 0),
+ M( 0x87d, 0x881, 0, 0, 16, 16, 20, 0),
+ M( 0x87d, 0x882, 0, 0, 16, 16, 20, 0),
+ M( 0x87d, 0x883, 0, 0, 16, 16, 20, 0),
+ M( 0x87d, 0x883, 0, 0, 16, 16, 20, 0),
+ M( 0x87d, 0x882, 0, 0, 16, 16, 20, 0),
+ M( 0x87d, 0x881, 0, 0, 16, 16, 20, 0),
+ M( 0x87d, 0x880, 0, 0, 16, 16, 20, 0),
+ M( 0x87d, 0x87f, 0, 0, 16, 16, 20, 0),
+ M( 0x87d, 0x87e, 0, 0, 16, 16, 20, 0),
+ M( 0x83a, 0x83c | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 18, 0),
+ M( 0x83a, 0x83c | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 18, 0),
+ M( 0x83a, 0x83c | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 18, 0),
+ M( 0x83a, 0x83c | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 18, 0),
+ M( 0x83b, 0x83d | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 18, 0),
+ M( 0x83b, 0x83d | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 18, 0),
+ M( 0x83b, 0x83d | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 18, 0),
+ M( 0x83b, 0x83d | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 18, 0),
+ M( 0x7e6, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0x83e, 0x83f | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 18, 0),
+ M( 0x83e, 0x83f | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 18, 0),
+ M( 0x83e, 0x83f | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 18, 0),
+ M( 0x7e6, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0x840, 0x841, 0, 0, 16, 16, 18, 0),
+ M( 0x840, 0x841, 0, 0, 16, 16, 18, 0),
+ M( 0x840, 0x841, 0, 0, 16, 16, 18, 0),
+ M( 0x7e6, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0x842, 0x843, 0, 0, 16, 16, 30, 0),
+ M( 0x842, 0x843, 0, 0, 16, 16, 30, 0),
+ M( 0x842, 0x843, 0, 0, 16, 16, 30, 0),
+ M( 0x7e6, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0x844, 0x845, 0, 0, 16, 16, 16, 0),
+ M( 0x844, 0x845, 0, 0, 16, 16, 16, 0),
+ M( 0x844, 0x845, 0, 0, 16, 16, 16, 0),
+ M( 0x7e6, 0x869, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x86d, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x86d, 0, 0, 16, 16, 50, 0),
+ M( 0x862 | PALETTE_MODIFIER_COLOR, 0x866 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x86a, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x86e, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x86e, 0, 0, 16, 16, 50, 0),
+ M( 0x863 | PALETTE_MODIFIER_COLOR, 0x867 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x86b, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x86f, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x86f, 0, 0, 16, 16, 50, 0),
+ M( 0x864 | PALETTE_MODIFIER_COLOR, 0x868 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x86c, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x870, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x870, 0, 0, 16, 16, 50, 0),
+ M( 0x865 | PALETTE_MODIFIER_COLOR, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0xf54, 0x871 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x875 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x875 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x879 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x872 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x876 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x876 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x87a | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x873 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x877 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x877 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x87b | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x874 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x878 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x878 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x87c | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x7ea, 3, 2, 8, 8, 18, 0),
+ M( 0xf54, 0x7eb, 3, 2, 8, 8, 37, 0),
+ M( 0xf54, 0x7ec, 3, 2, 8, 8, 49, 0),
+ M( 0x7e6, 0x7ec, 3, 2, 8, 8, 49, 0),
+ M( 0x7e6, 0x7ec, 3, 2, 8, 8, 49, 0),
+ M( 0x7e6, 0x7ed, 3, 2, 8, 8, 49, 0),
+ M( 0x7e6, 0x7ee, 3, 2, 8, 8, 49, 0),
+ M( 0x7e6, 0x7ee, 3, 2, 8, 8, 49, 0),
+ M( 0xf54, 0x7ef, 3, 2, 10, 7, 20, 0),
+ M( 0xf54, 0x7f0, 3, 2, 10, 7, 40, 0),
+ M( 0xf54, 0x7f1, 3, 2, 10, 7, 40, 0),
+ M( 0x7e6, 0x7f1, 3, 2, 10, 7, 40, 0),
+ M( 0xf54, 0x7f2, 4, 4, 7, 8, 22, 0),
+ M( 0xf54, 0x7f3, 4, 4, 7, 8, 22, 0),
+ M( 0xf54, 0x7f4, 4, 4, 7, 8, 22, 0),
+ M( 0x7e6, 0x7f4, 4, 4, 7, 8, 22, 0),
+ M( 0xf54, 0x7f5, 2, 1, 11, 13, 12, 0),
+ M( 0xf54, 0x7f6, 2, 1, 11, 13, 12, 0),
+ M( 0xf54, 0x7f7, 2, 1, 11, 13, 12, 0),
+ M( 0x7e6, 0x7f7, 2, 1, 11, 13, 12, 0),
+ M( 0x7e6, 0x85c, 0, 0, 1, 1, 1, 0),
+ M( 0x851, 0x852, 0, 0, 16, 16, 20, 0),
+ M( 0x851, 0x852, 0, 0, 16, 16, 20, 0),
+ M( 0x846 | PALETTE_MODIFIER_COLOR, 0x847 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 20, 0),
+ M( 0x7e6, 0x85d, 0, 0, 1, 1, 1, 0),
+ M( 0x853, 0x854, 0, 0, 16, 16, 20, 0),
+ M( 0x853, 0x854, 0, 0, 16, 16, 20, 0),
+ M( 0x848 | PALETTE_MODIFIER_COLOR, 0x849 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 20, 0),
+ M( 0x7e6, 0x85e, 0, 0, 1, 1, 1, 0),
+ M( 0x855, 0x856, 0, 0, 16, 16, 20, 0),
+ M( 0x855, 0x856, 0, 0, 16, 16, 20, 0),
+ M( 0x84a | PALETTE_MODIFIER_COLOR, 0x84b | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 20, 0),
+ M( 0x7e6, 0x85f, 0, 0, 1, 1, 1, 0),
+ M( 0x857, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0x857, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0x84c | PALETTE_MODIFIER_COLOR, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0x7e6, 0x860, 0, 0, 1, 1, 1, 0),
+ M( 0x858, 0x859, 0, 0, 16, 16, 20, 0),
+ M( 0x858, 0x859, 0, 0, 16, 16, 20, 0),
+ M( 0x84d | PALETTE_MODIFIER_COLOR, 0x84e | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 20, 0),
+ M( 0x7e6, 0x861, 0, 0, 1, 1, 1, 0),
+ M( 0x85a, 0x85b, 0, 0, 16, 16, 20, 0),
+ M( 0x85a, 0x85b, 0, 0, 16, 16, 20, 0),
+ M( 0x84f | PALETTE_MODIFIER_COLOR, 0x850 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 20, 0),
+ M( 0x7e6, 0x884, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x884, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x884, 0, 0, 16, 16, 25, 0),
+ M( 0x886, 0x884, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x885, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x885, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x885, 0, 0, 16, 16, 25, 0),
+ M( 0x887, 0x885, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x88c | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x88d | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x88d | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x88e | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x88f | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x890 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x890 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x891 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x892 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x893 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x893 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x894 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x895 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x896 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x896 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x897 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x898, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x899, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x899, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x89a, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8a6, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x89b, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x89c, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x89c, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x89d, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x89e, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x89f, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8a0, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8a0, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x89f, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8a0, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8a1, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8a2, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8a3, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8a4, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8a2, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8a3, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8a5, 0, 0, 16, 16, 25, 0),
+ M( 0x8a7, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8b7, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8b7, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8c7, 0, 0, 16, 16, 25, 0),
+ M( 0x8a8, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8b8, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8b8, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8c8, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8a9, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8b9, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8b9, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8c9, 0, 0, 16, 16, 25, 0),
+ M( 0x8aa, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8ba, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8ba, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8ca, 0, 0, 16, 16, 25, 0),
+ M( 0x8ab, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8bb, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8bb, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8cb, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8ac, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8bc, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8bc, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8cc, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8ad, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8bd, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8bd, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8cd, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8ae, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8be, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8be, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8ce, 0x8d7, 0, 0, 16, 16, 35, 0),
+ M( 0x8af, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8bf, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8bf, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8cf, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8b0, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8c0, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8c0, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8d0, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8b1, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8c1, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8c1, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8d1, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8b2, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8c2, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8c2, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8d2, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8b3, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8c3, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8c3, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8d3, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8b4, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8c4, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8c4, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8d4, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8b5, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8c5, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8c5, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8d5, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8b6, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8c6, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8c6, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8d6, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8ce, 0x8d7, 0, 0, 16, 16, 35, 0),
+ M( 0x8ce, 0x8d8, 0, 0, 16, 16, 35, 0),
+ M( 0x8ce, 0x8d9, 0, 0, 16, 16, 35, 0),
+ M( 0x8ce, 0x8d9, 0, 0, 16, 16, 35, 0),
+ M( 0x7e6, 0x88a, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x88a, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x88a, 0, 0, 16, 16, 25, 0),
+ M( 0x888, 0x88a, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x88b, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x88b, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x88b, 0, 0, 16, 16, 25, 0),
+ M( 0x889, 0x88b, 0, 0, 16, 16, 25, 0),
+ M( 0x8da, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8e3, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8e3, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8ec, 0, 0, 16, 16, 25, 0),
+ M( 0x8db, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8e4, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8e4, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8ed, 0, 0, 16, 16, 25, 0),
+ M( 0x8dc, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8e5, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8e5, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8ee, 0, 0, 16, 16, 25, 0),
+ M( 0x8dd, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8e6, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8e6, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8ef, 0, 0, 16, 16, 25, 0),
+ M( 0x8de, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8e7, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8e7, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8f0, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8df, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8e8, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8e8, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8f1, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8e0, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8e9, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8e9, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x8f2, 0, 0, 16, 16, 25, 0),
+ M( 0x8e1, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8ea, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8ea, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8f3, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8e2, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8eb, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8eb, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8f4, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8f5, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x905, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x905, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x915, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8f6, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x906, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x906, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x916, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8f7, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x907, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x907, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x917, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8f8, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x908, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x908, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x918, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8f9, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x909, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x909, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x919, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8fa, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x90a, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x90a, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x91a, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8fb, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x90b, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x90b, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x91b, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8fc, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x90c, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x90c, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x91c, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8fd, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x90d, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x90d, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x91d, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8fe, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x90e, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x90e, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x91e, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x8ff, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x90f, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x90f, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x91f, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x900, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x910, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x910, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x920, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x901, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x911, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x911, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x921, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x902, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x912, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x912, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x922, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x903, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x913, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x913, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x923, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x904, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x914, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x914, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x924, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x925, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x925, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x925, 0x926, 0, 0, 16, 16, 30, 0),
+ M( 0x925, 0x926, 0, 0, 16, 16, 30, 0),
+ M( 0x925, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x925, 0x0, 0, 0, 16, 16, 25, 0),
+ M( 0x925, 0x927, 0, 0, 16, 16, 30, 0),
+ M( 0x925, 0x927, 0, 0, 16, 16, 30, 0),
+ M( 0x11c6, 0x92b | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x11c6, 0x92c | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x11c6, 0x92c | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x11c6, 0x92d | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x11c6, 0x92e | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x11c6, 0x92f | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x11c6, 0x92f | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x11c6, 0x930 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x11c6, 0x928 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x11c6, 0x929 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x11c6, 0x929 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x11c6, 0x92a | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 25, 0),
+ M( 0x7e6, 0x869, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x86d, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x86d, 0, 0, 16, 16, 50, 0),
+ M( 0x862 | PALETTE_MODIFIER_COLOR, 0x866 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x86a, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x86e, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x86e, 0, 0, 16, 16, 50, 0),
+ M( 0x863 | PALETTE_MODIFIER_COLOR, 0x867 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x86b, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x86f, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x86f, 0, 0, 16, 16, 50, 0),
+ M( 0x864 | PALETTE_MODIFIER_COLOR, 0x868 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x86c, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x870, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x870, 0, 0, 16, 16, 50, 0),
+ M( 0x865 | PALETTE_MODIFIER_COLOR, 0x0, 0, 0, 1, 1, 0, 0),
+ M( 0x7e6, 0x931, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x935, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x935, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x939, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x932, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x936, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x936, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x93a, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x933, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x937, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x937, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x93b, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x934, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x938, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x938, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x93c, 0, 0, 16, 16, 50, 0),
+ M( 0x81d, 0x818, 0, 0, 16, 16, 10, 0),
+ M( 0x81d, 0x819, 0, 0, 16, 16, 15, 0),
+ M( 0x81d, 0x81a, 0, 0, 16, 16, 31, 0),
+ M( 0x81d, 0x81b, 0, 0, 16, 16, 39, 0),
+ M( 0x81d, 0x81c, 0, 0, 16, 16, 7, 0),
+ M( 0x81d, 0x81c, 0, 0, 16, 16, 7, 0),
+ M( 0x81d, 0x81c, 0, 0, 16, 16, 7, 0),
+ M( 0x81d, 0x81c, 0, 0, 16, 16, 7, 0),
+ M( 0x7e6, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x1245 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x1248 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x1248 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x124b | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x1247 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x124a | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x124a | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x124d | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x1246 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x1249 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x1249 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x124c | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0x81d, 0x124e, 0, 0, 16, 16, 10, 0),
+ M( 0x81d, 0x124f, 0, 0, 16, 16, 10, 0),
+ M( 0x81d, 0x1250, 0, 0, 16, 16, 10, 0),
+ M( 0x81d, 0x1251, 0, 0, 16, 16, 10, 0),
+ M( 0x81d, 0x1252, 0, 0, 16, 16, 10, 0),
+ M( 0x81d, 0x1252, 0, 0, 16, 16, 10, 0),
+ M( 0x81d, 0x1252, 0, 0, 16, 16, 10, 0),
+ M( 0x81d, 0x1252, 0, 0, 16, 16, 10, 0),
+ M( 0x81d, 0x1253, 0, 0, 16, 16, 10, 0),
+ M( 0x81d, 0x1254, 0, 0, 16, 16, 10, 0),
+ M( 0x81d, 0x1254, 0, 0, 16, 16, 10, 0),
+ M( 0x81d, 0x1255, 0, 0, 16, 16, 10, 0),
+ M( 0x7e6, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x125b, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x125e, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x125e, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x1261, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x125c, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x125f, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x125f, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x1262, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x125d, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x1260, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x1260, 0, 0, 16, 16, 50, 0),
+ M( 0x7e6, 0x1263, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x1264, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x1264, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x1268, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x1265, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x1265, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x1269, 0, 0, 16, 16, 50, 4),
+ M( 0x1243, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x1266, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x1266, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x126a, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x1267, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x1267, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x126b, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x126c, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1271, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1271, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1271, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1271, 0x1279, 0, 0, 16, 16, 50, 0),
+ M( 0x1272, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1272, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1272, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1272, 0x127a, 0, 0, 16, 16, 50, 0),
+ M( 0x1273, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1273, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1273, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1273, 0x127b, 0, 0, 16, 16, 50, 0),
+ M( 0x1274, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1274, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1274, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1274, 0x127c, 0, 0, 16, 16, 50, 0),
+ M( 0x1275, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1275, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1275, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1275, 0x127d, 0, 0, 16, 16, 50, 0),
+ M( 0x1276, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1276, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1276, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1276, 0x127e, 0, 0, 16, 16, 50, 0),
+ M( 0x1277, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1277, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1277, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1277, 0x127f, 0, 0, 16, 16, 50, 0),
+ M( 0x1278, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1278, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1278, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1278, 0x1280, 0, 0, 16, 16, 50, 0),
+ M( 0x1244, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1244, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1244, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1244, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1244, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1244, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1244, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1244, 0x1284 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0x1244, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1244, 0x1283 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0x1244, 0x1283 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0x1244, 0x1286 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0x1244, 0x1281 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0x1244, 0x1282 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0x1244, 0x1282 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0x1244, 0x1285 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x1287 | PALETTE_TO_RED, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x1287 | PALETTE_TO_RED, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x1287 | PALETTE_TO_RED, 0, 0, 16, 16, 50, 0),
+ M( 0x1244, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1244, 0x1288 | PALETTE_TO_RED, 0, 0, 16, 16, 50, 0),
+ M( 0x1244, 0x1288 | PALETTE_TO_RED, 0, 0, 16, 16, 50, 0),
+ M( 0x1244, 0x1288 | PALETTE_TO_RED, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1243, 0x1289 | PALETTE_TO_RED, 0, 0, 16, 16, 50, 3),
+ M( 0x1243, 0x1289 | PALETTE_TO_RED, 0, 0, 16, 16, 50, 3),
+ M( 0x1243, 0x1289 | PALETTE_TO_RED, 0, 0, 16, 16, 50, 3),
+ M( 0x1244, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1244, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1244, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x1244, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0xf8d, 0x129b, 0, 0, 16, 16, 50, 0),
+ M( 0xf8d, 0x129b, 0, 0, 16, 16, 50, 0),
+ M( 0xf8d, 0x129b, 0, 0, 16, 16, 50, 0),
+ M( 0xf8d, 0x129b, 0, 0, 16, 16, 50, 0),
+ M( 0xf8d, 0x129c, 0, 0, 16, 16, 50, 2),
+ M( 0xf8d, 0x129c, 0, 0, 16, 16, 50, 2),
+ M( 0xf8d, 0x129c, 0, 0, 16, 16, 50, 2),
+ M( 0xf8d, 0x129c, 0, 0, 16, 16, 50, 2),
+ M( 0xf8d, 0x129d, 0, 0, 16, 16, 50, 0),
+ M( 0xf8d, 0x129d, 0, 0, 16, 16, 50, 0),
+ M( 0xf8d, 0x129d, 0, 0, 16, 16, 50, 0),
+ M( 0xf8d, 0x129d, 0, 0, 16, 16, 50, 0),
+ M( 0x12a0 | PALETTE_MODIFIER_COLOR, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x12a0 | PALETTE_MODIFIER_COLOR, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x12a0 | PALETTE_MODIFIER_COLOR, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x12a0 | PALETTE_MODIFIER_COLOR, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x12a1 | PALETTE_MODIFIER_COLOR, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x12a1 | PALETTE_MODIFIER_COLOR, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x12a1 | PALETTE_MODIFIER_COLOR, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x12a1 | PALETTE_MODIFIER_COLOR, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x12a2 | PALETTE_MODIFIER_COLOR, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x12a2 | PALETTE_MODIFIER_COLOR, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x12a2 | PALETTE_MODIFIER_COLOR, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x12a2 | PALETTE_MODIFIER_COLOR, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x12a3 | PALETTE_MODIFIER_COLOR, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x12a3 | PALETTE_MODIFIER_COLOR, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x12a3 | PALETTE_MODIFIER_COLOR, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0x12a3 | PALETTE_MODIFIER_COLOR, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0xf8d, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0xf8d, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0xf8d, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0xf8d, 0x0, 0, 0, 16, 16, 50, 0),
+ M( 0xf8d, 0x12a4 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0xf8d, 0x12a4 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0xf8d, 0x12a4 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0xf8d, 0x12a4 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0xf8d, 0x12a6 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0xf8d, 0x12a6 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0xf8d, 0x12a6 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0xf8d, 0x12a6 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 0),
+ M( 0xf8d, 0x12a5 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 1),
+ M( 0xf8d, 0x12a5 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 1),
+ M( 0xf8d, 0x12a5 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 1),
+ M( 0xf8d, 0x12a5 | PALETTE_MODIFIER_COLOR, 0, 0, 16, 16, 50, 1),
+};
+
+static const DrawIndustrySpec1Struct _draw_industry_spec1[96] = {
+ { 8, 4, 0, 0},
+ { 6, 0, 1, 0},
+ { 4, 0, 2, 0},
+ { 6, 0, 3, 0},
+ { 8, 0, 4, 0},
+ { 10, 0, 5, 0},
+ { 12, 0, 6, 0},
+ { 10, 0, 1, 0},
+ { 8, 0, 2, 0},
+ { 6, 0, 3, 0},
+ { 4, 0, 4, 0},
+ { 6, 0, 5, 1},
+ { 8, 0, 6, 1},
+ { 10, 0, 1, 1},
+ { 12, 0, 2, 1},
+ { 10, 0, 3, 1},
+ { 8, 1, 4, 1},
+ { 6, 1, 5, 1},
+ { 4, 1, 6, 1},
+ { 6, 1, 1, 1},
+ { 8, 1, 2, 1},
+ { 10, 1, 3, 1},
+ { 12, 1, 4, 1},
+ { 10, 1, 5, 2},
+ { 8, 1, 6, 2},
+ { 6, 1, 1, 2},
+ { 4, 1, 2, 2},
+ { 6, 1, 3, 2},
+ { 8, 1, 4, 2},
+ { 10, 1, 5, 2},
+ { 12, 1, 6, 2},
+ { 10, 1, 1, 2},
+ { 8, 2, 2, 2},
+ { 6, 2, 3, 2},
+ { 4, 2, 4, 3},
+ { 6, 2, 5, 3},
+ { 8, 2, 6, 3},
+ { 10, 2, 1, 3},
+ { 12, 2, 2, 3},
+ { 10, 2, 3, 3},
+ { 8, 2, 4, 3},
+ { 6, 2, 5, 3},
+ { 4, 2, 6, 3},
+ { 6, 2, 1, 3},
+ { 8, 2, 2, 3},
+ { 10, 2, 3, 4},
+ { 12, 2, 4, 4},
+ { 10, 2, 5, 4},
+ { 8, 3, 6, 4},
+ { 6, 3, 1, 4},
+ { 4, 3, 2, 4},
+ { 6, 3, 3, 4},
+ { 8, 3, 4, 4},
+ { 10, 3, 5, 4},
+ { 12, 3, 6, 4},
+ { 10, 3, 1, 4},
+ { 8, 3, 2, 4},
+ { 6, 3, 3, 4},
+ { 4, 3, 4, 4},
+ { 6, 3, 5, 4},
+ { 8, 3, 6, 4},
+ { 10, 3, 1, 4},
+ { 12, 3, 2, 4},
+ { 10, 3, 3, 4},
+ { 8, 4, 4, 4},
+ { 6, 4, 5, 4},
+ { 4, 4, 6, 4},
+ { 6, 4, 0, 4},
+ { 8, 4, 0, 4},
+ { 10, 4, 0, 4},
+ { 12, 4, 0, 4},
+ { 10, 4, 0, 4},
+ { 8, 4, 0, 4},
+ { 6, 4, 0, 4},
+ { 4, 4, 0, 4},
+ { 6, 4, 0, 4},
+ { 8, 4, 0, 4},
+ { 10, 4, 0, 4},
+ { 12, 4, 0, 4},
+ { 10, 4, 0, 4},
+ { 8, 4, 0, 4},
+ { 6, 4, 0, 4},
+ { 4, 4, 0, 4},
+ { 6, 4, 0, 4},
+ { 8, 4, 0, 4},
+ { 10, 4, 0, 4},
+ { 12, 4, 0, 4},
+ { 10, 4, 0, 4},
+ { 8, 4, 0, 4},
+ { 6, 4, 0, 4},
+ { 4, 4, 0, 4},
+ { 6, 4, 0, 4},
+ { 8, 4, 0, 4},
+ { 10, 4, 0, 4},
+ { 12, 4, 0, 4},
+ { 10, 4, 0, 4},
+};
+
+static const byte _drawtile_proc1_x[5] = {
+ 22, 17, 14, 10, 8
+};
+
+static const byte _drawtile_proc1_y[5] = {
+ 73, 70, 69, 66, 41
+};
+
+static const DrawIndustrySpec4Struct _industry_anim_offs_3[] = {
+ {255, 255, 0},
+ { 0, 255, 0},
+ { 1, 255, 0},
+ { 2, 255, 0},
+ { 3, 255, 0},
+ { 4, 255, 0},
+ { 5, 255, 0},
+ { 6, 255, 0},
+ { 7, 255, 0},
+ { 8, 255, 0},
+ { 9, 255, 0},
+ { 10, 255, 0},
+ { 11, 255, 0},
+ { 12, 255, 0},
+ { 13, 255, 0},
+ { 14, 255, 0},
+ { 15, 255, 0},
+ { 16, 255, 0},
+ { 17, 255, 0},
+ { 18, 255, 0},
+ { 18, 255, 1},
+ { 18, 255, 2},
+ { 18, 255, 4},
+ { 18, 255, 6},
+ { 18, 255, 8},
+ { 18, 255, 11},
+ { 18, 255, 14},
+ { 18, 255, 17},
+ { 18, 255, 20},
+ { 18, 255, 24},
+ {255, 0, 29},
+ {255, 0, 24},
+ {255, 0, 20},
+ {255, 0, 17},
+ {255, 0, 14},
+ {255, 0, 11},
+ {255, 0, 8},
+ {255, 0, 6},
+ {255, 0, 4},
+ {255, 0, 2},
+ {255, 0, 1},
+ {255, 1, 0},
+ {255, 2, 0},
+ {255, 3, 0},
+ {255, 4, 0},
+ {255, 5, 0},
+ {255, 6, 0},
+ {255, 7, 0},
+ {255, 8, 0},
+ {255, 255, 0},
+};
+
+static const byte _industry_anim_offs[] = {
+ 255, 0, 0, 0, 2, 4, 6, 8, 10, 9,
+ 7, 5, 3, 1, 255, 0, 0, 0, 2, 4,
+ 6, 8, 10, 9, 7, 5, 3, 1, 255, 0,
+ 0, 0, 2, 4, 6, 8, 10, 9, 7, 5,
+ 3, 1, 255, 0, 0, 0, 2, 4, 6, 8,
+ 10, 9, 7, 5, 3, 1, 255, 0, 0, 0,
+ 2, 4, 6, 8, 10, 9, 7, 5, 3, 1
+};
+
+static const byte _industry_anim_offs_2[] = {
+ 68, 69, 71, 74, 77, 80, 83, 85, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 85, 84, 83, 82, 81, 80, 79, 78,
+ 77, 76, 75, 74, 73, 72, 71, 70, 69, 68,
+};
+
+static const byte _coal_plant_sparks_x[] = {11, 11, 14, 13, 18, 15};
+static const byte _coal_plant_sparks_y[] = {23, 11, 6, 3, 1, 0};
+
+#define N 255
+/**
+ * Next frame in an animation
+ * The indices into this table are the ones as described by
+ * the enum with GFX_*s in industry_map.h.
+ */
+static const byte _industry_section_animation_next[NUM_INDUSTRY_GFXES] = {
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, 16, N, N, N, N, N, N, // <- growing forest
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, 129, N, N, N, N, N, // <- growing candyfloss
+135, N, N, N, N, N, N, N, // <- 'growing' batteries
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N,
+};
+
+/**
+ * Animation to start when goods is produced
+ * The indices into this table are the ones as described by
+ * the enum with GFX_*s in industry_map.h.
+ */
+static const byte _industry_produce_section[NUM_INDUSTRY_GFXES] = {
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+17, N, N, N, N, N, N, N, // <- chopping forest
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, 130, N, N, N, N, N, 136, // <- chopping candyfloss and reaping batteries
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N, N,
+N, N, N, N, N, N, N,
+};
+
+#undef N
+
+/**
+ * The indices into this table are the ones as described by
+ * the enum with GFX_*s in industry_map.h.
+ */
+static const byte _industry_section_bits[NUM_INDUSTRY_GFXES] = {
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 4, 2, 16, 16, 16, 16, // <- temperate bank
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 4, 2, 16, 16, 16, 16, 16, // <- sub-arctic/sub-tropical bank
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16,
+};
+
+/**
+ * When true, the tile has to be drawn using the animation
+ * state instead of the construction state.
+ * The indices into this table are the ones as described by
+ * the enum with GFX_*s in industry_map.h.
+ */
+static const bool _industry_section_draw_animation_state[NUM_INDUSTRY_GFXES] = {
+ false, true, false, false, false, false, false, false, // <- animated wheel tower of coal mine
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, true, true, // <- animated oil well
+ true, false, false, false, false, false, false, false, // <- animated oil well
+ false, false, false, false, false, false, false, false,
+ true, false, false, false, false, false, false, false, // <- animated wheel tower of copper mine
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ true, false, false, false, false, false, false, false, // <- animated wheel tower of gold mine
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false,
+};
diff --git a/src/table/landscape_const.h b/src/table/landscape_const.h
new file mode 100644
index 000000000..518a48047
--- /dev/null
+++ b/src/table/landscape_const.h
@@ -0,0 +1,257 @@
+/* $Id$ */
+
+#include "sprites.h"
+
+typedef struct CargoTypesValues {
+ StringID names[NUM_CARGO];
+ StringID units_volume[NUM_CARGO];
+ byte weights[NUM_CARGO];
+ SpriteID sprites[NUM_CARGO];
+
+ uint16 initial_cargo_payment[NUM_CARGO];
+ byte transit_days_table_1[NUM_CARGO];
+ byte transit_days_table_2[NUM_CARGO];
+} CargoTypesValues;
+
+
+static const CargoTypesValues _cargo_types_base_values[4] = {
+ {
+ /* normal names */
+ {
+ STR_000F_PASSENGERS,
+ STR_0010_COAL,
+ STR_0011_MAIL,
+ STR_0012_OIL,
+ STR_0013_LIVESTOCK,
+ STR_0014_GOODS,
+ STR_0015_GRAIN,
+ STR_0016_WOOD,
+ STR_0017_IRON_ORE,
+ STR_0018_STEEL,
+ STR_0019_VALUABLES,
+ STR_000E,
+ },
+
+ { /* normal units of volume */
+ STR_PASSENGERS,
+ STR_TONS,
+ STR_BAGS,
+ STR_LITERS,
+ STR_ITEMS,
+ STR_CRATES,
+ STR_TONS,
+ STR_TONS,
+ STR_TONS,
+ STR_TONS,
+ STR_BAGS,
+ STR_RES_OTHER
+ },
+
+ /* normal weights */
+ {
+ 1, 16, 4, 16, 3, 8, 16, 16, 16, 16, 2, 0,
+ },
+
+ /* normal sprites */
+ {
+ SPR_CARGO_PASSENGER, SPR_CARGO_COAL, SPR_CARGO_MAIL, SPR_CARGO_OIL, SPR_CARGO_LIVESTOCK,
+ SPR_CARGO_GOODS, SPR_CARGO_GRAIN, SPR_CARGO_WOOD, SPR_CARGO_IRON_ORE, SPR_CARGO_STEEL,
+ SPR_CARGO_VALUES_GOLD, SPR_ASCII_SPACE
+ },
+
+ /* normal initial cargo payment */
+ {
+ 3185, 5916, 4550, 4437, 4322, 6144, 4778, 5005, 5120, 5688, 7509, 5688
+ },
+
+ /* normal transit days table 1 */
+ {
+ 0, 7, 20, 25, 4, 5, 4, 15, 9, 7, 1, 0,
+ },
+
+ /* normal transit days table 2 */
+ {
+ 24, 255, 90, 255, 18, 28, 40, 255, 255, 255, 32, 30,
+ },
+ },
+
+ {
+ /* hilly names */
+ {
+ STR_000F_PASSENGERS,
+ STR_0010_COAL,
+ STR_0011_MAIL,
+ STR_0012_OIL,
+ STR_0013_LIVESTOCK,
+ STR_0014_GOODS,
+ STR_0022_WHEAT,
+ STR_0016_WOOD,
+ STR_000E,
+ STR_001F_PAPER,
+ STR_0020_GOLD,
+ STR_001E_FOOD,
+ },
+
+ { /* hilly units of volume */
+ STR_PASSENGERS,
+ STR_TONS,
+ STR_BAGS,
+ STR_LITERS,
+ STR_ITEMS,
+ STR_CRATES,
+ STR_TONS,
+ STR_TONS,
+ STR_RES_OTHER,
+ STR_TONS,
+ STR_BAGS,
+ STR_TONS
+ },
+
+ /* hilly weights */
+ {
+ 1, 16, 4, 16, 3, 8, 16, 16, 0, 16, 8, 16
+ },
+
+ /* hilly sprites */
+ {
+ SPR_CARGO_PASSENGER, SPR_CARGO_COAL, SPR_CARGO_MAIL, SPR_CARGO_OIL, SPR_CARGO_LIVESTOCK,
+ SPR_CARGO_GOODS, SPR_CARGO_GRAIN, SPR_CARGO_WOOD, SPR_ASCII_SPACE, SPR_CARGO_PAPER,
+ SPR_CARGO_VALUES_GOLD, SPR_CARGO_FOOD
+ },
+
+ /* hilly initial cargo payment */
+ {
+ 3185, 5916, 4550, 4437, 4322, 6144, 4778, 5005, 5120, 5461, 5802, 5688
+ },
+
+ /* hilly transit days table 1 */
+ {
+ 0, 7, 20, 25, 4, 5, 4, 15, 9, 7, 10, 0,
+ },
+
+ /* hilly transit days table 2 */
+ {
+ 24, 255, 90, 255, 18, 28, 40, 255, 255, 60, 40, 30
+ },
+ },
+
+ {
+ /* desert names */
+ {
+ STR_000F_PASSENGERS,
+ STR_0023_RUBBER,
+ STR_0011_MAIL,
+ STR_0012_OIL,
+ STR_001C_FRUIT,
+ STR_0014_GOODS,
+ STR_001B_MAIZE,
+ STR_0016_WOOD,
+ STR_001A_COPPER_ORE,
+ STR_0021_WATER,
+ STR_001D_DIAMONDS,
+ STR_001E_FOOD
+ },
+
+ { /* desert units of volume */
+ STR_PASSENGERS,
+ STR_LITERS,
+ STR_BAGS,
+ STR_LITERS,
+ STR_TONS,
+ STR_CRATES,
+ STR_TONS,
+ STR_TONS,
+ STR_TONS,
+ STR_LITERS,
+ STR_BAGS,
+ STR_TONS
+ },
+
+ /* desert weights */
+ {
+ 1, 16, 4, 16, 16, 8, 16, 16, 16, 16, 2, 16,
+ },
+
+ /* desert sprites */
+ {
+ SPR_CARGO_PASSENGER, SPR_CARGO_RUBBER, SPR_CARGO_MAIL, SPR_CARGO_OIL, SPR_CARGO_FRUIT,
+ SPR_CARGO_GOODS, SPR_CARGO_GRAIN, SPR_CARGO_WOOD, SPR_CARGO_COPPER_ORE, SPR_CARGO_WATERCOLA,
+ SPR_CARGO_DIAMONDS, SPR_CARGO_FOOD
+ },
+
+ /* desert initial cargo payment */
+ {
+ 3185, 4437, 4550, 4892, 4209, 6144, 4322, 7964, 4892, 4664, 5802, 5688
+ },
+
+ /* desert transit days table 1 */
+ {
+ 0, 2, 20, 25, 0, 5, 4, 15, 12, 20, 10, 0
+ },
+
+ /* desert transit days table 2 */
+ {
+ 24, 20, 90, 255, 15, 28, 40, 255, 255, 80, 255, 30
+ },
+ },
+
+ {
+ /* candy names */
+ {
+ STR_000F_PASSENGERS,
+ STR_0024_SUGAR,
+ STR_0011_MAIL,
+ STR_0025_TOYS,
+ STR_002B_BATTERIES,
+ STR_0026_CANDY,
+ STR_002A_TOFFEE,
+ STR_0027_COLA,
+ STR_0028_COTTON_CANDY,
+ STR_0029_BUBBLES,
+ STR_002C_PLASTIC,
+ STR_002D_FIZZY_DRINKS,
+ },
+
+ { /* candy unitrs of volume */
+ STR_PASSENGERS,
+ STR_TONS,
+ STR_BAGS,
+ STR_NOTHING,
+ STR_NOTHING,
+ STR_TONS,
+ STR_TONS,
+ STR_LITERS,
+ STR_TONS,
+ STR_NOTHING,
+ STR_LITERS,
+ STR_NOTHING
+ },
+
+ /* candy weights */
+ {
+ 1, 16, 4, 2, 4, 5, 16, 16, 16, 1, 16, 2
+ },
+
+ /* candy sprites */
+ {
+ SPR_CARGO_PASSENGER, SPR_CARGO_SUGAR, SPR_CARGO_MAIL, SPR_CARGO_TOYS, SPR_CARGO_BATTERIES,
+ SPR_CARGO_CANDY, SPR_CARGO_TOFFEE, SPR_CARGO_WATERCOLA, SPR_CARGO_COTTONCANDY, SPR_CARGO_BUBBLES,
+ SPR_CARGO_PLASTIC, SPR_CARGO_FIZZYDRINK
+ },
+
+ /* candy initial cargo payment */
+ {
+ 3185, 4437, 4550, 5574, 4322, 6144, 4778, 4892, 5005, 5077, 4664, 6250
+ },
+
+ /* candy transit days table 1 */
+ {
+ 0, 20, 20, 25, 2, 8, 14, 5, 10, 20, 30, 30,
+ },
+
+ /* candy transit days table 2 */
+ {
+ 24, 255, 90, 255, 30, 40, 60, 75, 25, 80, 255, 50
+ },
+ }
+};
diff --git a/src/table/landscape_sprite.h b/src/table/landscape_sprite.h
new file mode 100644
index 000000000..88f5f48b1
--- /dev/null
+++ b/src/table/landscape_sprite.h
@@ -0,0 +1,167 @@
+/* $Id$ */
+
+static const SpriteID _landscape_spriteindexes_1[] = {
+ 0xF67, 0xF9F,
+ 0xAAD, 0xAB0,
+ 0x83A, 0x845,
+ 0xFA0, 0xFC9,
+ 0x43F, 0x45E,
+ 0x566, 0x56D,
+ 0x945, 0x94C,
+ 0x3ED, 0x40C,
+ 0x515, 0x51C,
+ 0x55A, 0x561,
+ 0x534, 0x546,
+ 0x93D, 0x944,
+ 0x955, 0x95C,
+ 0xFDD, 0xFEC,
+ 0x87D, 0x883,
+ 0xA2B, 0xA39,
+ 0x497, 0x4B0,
+ 0x572, 0x575,
+ 0x94D, 0x954,
+ 0x818, 0x81D,
+ 0x3DE, 0x3EB,
+0x1212, 0x1212,
+END
+};
+
+static const SpriteID _landscape_spriteindexes_2[] = {
+ 0xF67, 0xF9F,
+ 0xAAD, 0xAB0,
+ 0xFA0, 0xFC9,
+ 0x43F, 0x45E,
+ 0x566, 0x56D,
+ 0x945, 0x94C,
+ 0x3ED, 0x40C,
+ 0x515, 0x51C,
+ 0x55A, 0x561,
+ 0x547, 0x559,
+ 0x93D, 0x944,
+ 0x955, 0x95C,
+ 0xFDD, 0xFEC,
+ 0x87D, 0x883,
+ 0xA2B, 0xA39,
+ 0x497, 0x4B0,
+ 0x572, 0x575,
+ 0x94D, 0x954,
+ 0x5AE, 0x5AF,
+0x118D, 0x11D8,
+ 0x534, 0x546,
+ 0x40D, 0x426,
+ 0x45F, 0x478,
+ 0x4B1, 0x4CA,
+ 0x95D, 0x97C,
+ 0x3DE, 0x3EB,
+ 0x562, 0x565,
+ 0x56E, 0x571,
+ 0x57A, 0x57D,
+ 0x83A, 0x845,
+ 0xFF5, 0xFF5,
+ 0xFF8, 0xFF8,
+0x1212, 0x1212,
+END
+};
+
+static const SpriteID _landscape_spriteindexes_3[] = {
+ 0xF54, 0xF9F,
+ 0xFDD, 0xFE5,
+ 0xFEC, 0xFEC,
+ 0xFA0, 0xFC9,
+ 0x818, 0x81D,
+ 0x521, 0x546,
+ 0x57E, 0x57F,
+ 0x3ED, 0x40C,
+ 0x43F, 0x45E,
+ 0x491, 0x4B0,
+ 0xA48, 0xA48,
+ 0x4FB, 0x50A,
+ 0x55A, 0x561,
+ 0x566, 0x56D,
+ 0x572, 0x579,
+ 0x427, 0x42C,
+ 0x479, 0x47E,
+ 0x4CB, 0x4D0,
+ 0x4EF, 0x4FA,
+ 0xE9D, 0xECC,
+ 0xF3D, 0xF40,
+ 0xB59, 0xB60,
+ 0xE5D, 0xE6C,
+ 0xA49, 0xA59,
+ 0xA63, 0xA68,
+ 0xA5A, 0xA62,
+ 0xA78, 0xA83,
+ 0xA69, 0xA77,
+ 0xA84, 0xAA3,
+ 0xAA7, 0xAAC,
+ 0xA2B, 0xA47,
+ 0x3DE, 0x3EB,
+ 0x47F, 0x488,
+ 0x4D1, 0x4DA,
+ 0x42D, 0x436,
+ 0x515, 0x51C,
+ 0x580, 0x585,
+ 0xC14, 0xCB3,
+ 0xAAD, 0xAB0,
+ 0xAB5, 0xB00,
+ 0xB69, 0xB70,
+ 0xB61, 0xB68,
+ 0xBC9, 0xBD0,
+ 0xBD9, 0xBE0,
+ 0xBA9, 0xBB0,
+ 0xBC1, 0xBC4,
+ 0x2D0, 0x2D0,
+ 0xAA5, 0xAA6,
+ 0x50F, 0x50F,
+ 0x2EA, 0x2EA,
+ 0x2ED, 0x2EE,
+ 0x512, 0x513,
+ 0x4EB, 0x4EE,
+ 0x4E7, 0x4EA,
+ 0x985, 0xA28,
+0x10E4, 0x1133,
+ 0x93D, 0x95C,
+ 0x97D, 0x984,
+ 0x7DA, 0x7DA,
+ 0x2E6, 0x2E6,
+ 0x1, 0x1,
+ 0xE54, 0xE54,
+ 0x51F, 0x520,
+ 0x514, 0x514,
+ 0x511, 0x511,
+ 0x322, 0x322,
+END
+};
+
+
+/* Slope graphics indexes temperate climate
+Skip first 3 sprites and only load the proper set */
+static const SpriteID _slopes_spriteindexes_0[] = {
+ SKIP, 3,
+ SPR_SLOPES_BASE, SPR_SLOPES_BASE + 73,
+ END
+};
+
+/* Slope graphics indexes arctic climate
+Skip first 79 sprites and only load the proper set */
+static const SpriteID _slopes_spriteindexes_1[] = {
+ SKIP, 79,
+ SPR_SLOPES_BASE, SPR_SLOPES_BASE + 73,
+ END
+};
+
+/* Slope graphics indexes tropical climate
+Skip first 155 sprites and only load the proper set */
+static const SpriteID _slopes_spriteindexes_2[] = {
+ SKIP, 155,
+ SPR_SLOPES_BASE, SPR_SLOPES_BASE + 73,
+ END
+};
+
+/* Slope graphics indexes toyland climate
+Skip first 231 sprites and only load the proper set */
+static const SpriteID _slopes_spriteindexes_3[] = {
+ SKIP, 231,
+ SPR_SLOPES_BASE, SPR_SLOPES_BASE + 73,
+ END
+};
diff --git a/src/table/namegen.h b/src/table/namegen.h
new file mode 100644
index 000000000..a5d9974d6
--- /dev/null
+++ b/src/table/namegen.h
@@ -0,0 +1,3302 @@
+/* $Id$ */
+
+#include "../stdafx.h"
+#include "../openttd.h"
+
+static const char *name_original_english_1[] = {
+ "Great ",
+ "Little ",
+ "New ",
+ "Fort ",
+};
+
+static const char *name_original_english_2[] = {
+ "Wr",
+ "B",
+ "C",
+ "Ch",
+ "Br",
+ "D",
+ "Dr",
+ "F",
+ "Fr",
+ "Fl",
+ "G",
+ "Gr",
+ "H",
+ "L",
+ "M",
+ "N",
+ "P",
+ "Pr",
+ "Pl",
+ "R",
+ "S",
+ "S",
+ "Sl",
+ "T",
+ "Tr",
+ "W"
+};
+
+static const char *name_original_english_3[] = {
+ "ar",
+ "a",
+ "e",
+ "in",
+ "on",
+ "u",
+ "un",
+ "en"
+};
+
+static const char *name_original_english_4[] = {
+ "n",
+ "ning",
+ "ding",
+ "d",
+ "",
+ "t"
+ "fing"
+};
+
+static const char *name_original_english_5[] = {
+ "ville",
+ "ham",
+ "field",
+ "ton",
+ "town",
+ "bridge",
+ "bury",
+ "wood",
+ "ford",
+ "hall",
+ "ston",
+ "way",
+ "stone",
+ "borough",
+ "ley",
+ "head",
+ "bourne",
+ "pool",
+ "worth",
+ "hill",
+ "well",
+ "hattan",
+ "burg",
+};
+
+static const char *name_original_english_6[] = {
+ "-on-sea",
+ " Bay",
+ " Market",
+ " Cross",
+ " Bridge",
+ " Falls",
+ " City",
+ " Ridge",
+ " Springs"
+};
+
+static const char *name_additional_english_prefix[] = {
+ "Great ",
+ "Little ",
+ "New ",
+ "Fort ",
+ "St. ",
+ "Old "
+};
+
+static const char *name_additional_english_1a[] = {
+ "Pen",
+ "Lough",
+ "Stam",
+ "Aber",
+ "Acc",
+ "Ex",
+ "Ax",
+ "Bre",
+ "Cum",
+ "Dun",
+ "Fin",
+ "Inver",
+ "Kin",
+ "Mon",
+ "Nan",
+ "Nant",
+ "Pit",
+ "Pol",
+ "Pont",
+ "Strath",
+ "Tre",
+ "Tilly",
+ "Beck",
+ "Canter",
+ "Bath",
+ "Liver",
+ "Mal",
+ "Ox",
+ "Bletch",
+ "Maccles",
+ "Grim",
+ "Wind",
+ "Sher",
+ "Gates",
+ "Orp",
+ "Brom",
+ "Lewis",
+ "Whit",
+ "White",
+ "Worm",
+ "Tyne",
+ "Avon",
+ "Stan"
+};
+
+static const char *name_additional_english_1b1[] = {
+ "Wr",
+ "B",
+ "C",
+ "Ch",
+ "Br",
+ "D",
+ "Dr",
+ "F",
+ "Fr",
+ "Fl",
+ "G",
+ "Gr",
+ "H",
+ "L",
+ "M",
+ "N",
+ "P",
+ "Pr",
+ "Pl",
+ "R",
+ "S",
+ "S",
+ "Sl",
+ "T",
+ "Tr",
+ "W"
+};
+
+static const char *name_additional_english_1b2[] = {
+ "ar",
+ "a",
+ "e",
+ "in",
+ "on",
+ "u",
+ "o",
+ "ee",
+ "es",
+ "ea",
+ "un",
+ "en"
+};
+
+static const char *name_additional_english_1b3a[] = {
+ "n",
+ "d",
+ "",
+ "t",
+ "",
+ ""
+};
+
+static const char *name_additional_english_1b3b[] = {
+ "ning",
+ "ding",
+ "fing"
+};
+
+static const char *name_additional_english_2[] = {
+ "ville",
+ "ham",
+ "field",
+ "ton",
+ "town",
+ "borough",
+ "bridge",
+ "bury",
+ "wood",
+ "ditch",
+ "ford",
+ "hall",
+ "dean",
+ "leigh",
+ "dore",
+ "ston",
+ "stow",
+ "church",
+ "wich",
+ "low",
+ "way",
+ "stone",
+ "minster",
+ "ley",
+ "head",
+ "bourne",
+ "pool",
+ "worth",
+ "hill",
+ "well",
+ "hattan",
+ "burg",
+ "berg",
+ "burgh",
+ "port",
+ "stoke",
+ "haven",
+ "stable",
+ "stock",
+ "side",
+ "brook",
+ "don",
+ "den",
+ "down",
+ "nor",
+ "grove",
+ "combe",
+ "by",
+ "say",
+ "ney",
+ "chester",
+ "dale",
+ "ness",
+ "shaw",
+ "thwaite"
+};
+
+static const char *name_additional_english_3[] = {
+ "-on-sea",
+ " Bay",
+ " Market",
+ " Beeches",
+ " Common",
+ " Park",
+ " Heath",
+ " Marsh",
+ " Green",
+ " Castle",
+ " End",
+ " Rivers",
+ " Cross",
+ " Bridge",
+ " Falls",
+ " City",
+ " Ridge",
+ " Springs"
+};
+
+static const char *name_austrian_a1[] = {
+ "Bad ",
+ "Deutsch ",
+ "Gross ",
+ "Klein ",
+ "Markt ",
+ "Maria "
+};
+
+static const char *name_austrian_a2[] = {
+ "Aus",
+ "Alten",
+ "Braun",
+ "Vösl",
+ "Mittern",
+ "Nuss",
+ "Neu",
+ "Walters",
+ "Breiten",
+ "Eisen",
+ "Feld",
+ "Mittern",
+ "Gall",
+ "Obern",
+ "Grat",
+ "Heiligen",
+ "Hof",
+ "Holla",
+ "Stein",
+ "Eber",
+ "Eggen",
+ "Enzers",
+ "Frauen",
+ "Herren",
+ "Hof",
+ "Hütt",
+ "Kaisers",
+ "Königs",
+ "Knittel",
+ "Lang",
+ "Ober",
+ "Ollers",
+ "Pfaffen",
+ "Potten",
+ "Salz",
+ "Schwarz",
+ "Stocker",
+ "Unter",
+ "Utten",
+ "Vösen",
+ "Vill",
+ "Weissen"
+};
+
+static const char *name_austrian_a3[] = {
+ "see",
+ "bach",
+ "dorf",
+ "ach",
+ "stein",
+ "hofen",
+ "au",
+ "ach",
+ "kirch",
+ "kirchen",
+ "kreuz",
+ "brunn",
+ "siedl",
+ "markt",
+ "wang",
+ "haag"
+};
+
+static const char *name_austrian_a4[] = {
+ "Bruck",
+ "Brunn",
+ "Gams",
+ "Grein",
+ "Ried",
+ "Faak",
+ "Zell",
+ "Spital",
+ "Kirchberg",
+ "Saal",
+ "Taferl",
+ "Wald"
+};
+
+static const char *name_austrian_a5[] = {
+ "St. ",
+ "Sankt "
+};
+
+static const char *name_austrian_a6[] = {
+ "Aegyd",
+ "Andrä",
+ "Georgen",
+ "Jakob",
+ "Johann",
+ "Leonhard",
+ "Marein",
+ "Lorenzen",
+ "Margarethen",
+ "Martin",
+ "Michael",
+ "Nikolai",
+ "Oswald",
+ "Peter",
+ "Pölten",
+ "Stefan",
+ "Stephan",
+ "Thomas",
+ "Veit",
+ "Wolfgang"
+};
+
+static const char *name_austrian_f1[] = {
+ " an der ",
+ " ob der "
+};
+
+static const char *name_austrian_f2[] = {
+ "Donau",
+ "Steyr",
+ "Lafnitz",
+ "Leitha",
+ "Thaya",
+ "Gail",
+ "Drau",
+ "Salzach",
+ "Ybbs",
+ "Traisen",
+ "Enns",
+ "Mur",
+ "Ill"
+};
+
+static const char *name_austrian_b1[] = {
+ " am "
+};
+
+static const char *name_austrian_b2[] = {
+ "Brenner",
+ "Dachstein",
+ "Gebirge",
+ "Grossglockner",
+ "Hausruck",
+ "Semmering",
+ "Wagram",
+ "Wechsel",
+ "Wilden Kaiser",
+ "Ziller"
+};
+
+static const char *name_german_real[] = {
+ "Berlin",
+ "Bonn",
+ "Bremen",
+ "Cottbus",
+ "Chemnitz",
+ "Dortmund",
+ "Dresden",
+ "Erfurt",
+ "Erlangen",
+ "Essen",
+ "Fulda",
+ "Gera",
+ "Kassel",
+ "Kiel",
+ "Köln",
+ "Lübeck",
+ "Magdeburg",
+ "München",
+ "Potsdam",
+ "Stuttgart",
+ "Wiesbaden"
+};
+
+static const char *name_german_pre[] = {
+ "Bad ",
+ "Klein ",
+ "Neu "
+};
+
+static const char *name_german_1[] = {
+ "Alb",
+ "Als",
+ "Ander",
+ "Arns",
+ "Bruns",
+ "Bam",
+ "Biele",
+ "Cloppen",
+ "Co",
+ "Duis",
+ "Düssel",
+ "Dannen",
+ "Elb",
+ "Els",
+ "Elster",
+ "Eichen",
+ "Ems",
+ "Fahr",
+ "Falken",
+ "Flens",
+ "Frank",
+ "Frei",
+ "Freuden",
+ "Fried",
+ "Fürsten",
+ "Hahn",
+ "Ham",
+ "Harz",
+ "Heidel",
+ "Hers",
+ "Herz",
+ "Holz",
+ "Hildes",
+ "Inns",
+ "Ilsen",
+ "Ingols",
+ "Kel",
+ "Kies",
+ "Korn",
+ "Kor",
+ "Kreuz",
+ "Kulm",
+ "Langen",
+ "Lim",
+ "Lohr",
+ "Lüne",
+ "Mel",
+ "Michels",
+ "Mühl",
+ "Naum",
+ "Nest",
+ "Nord",
+ "Nort",
+ "Nien",
+ "Nidda",
+ "Nieder",
+ "Nürn",
+ "Ober",
+ "Offen",
+ "Osna",
+ "Olden",
+ "Ols",
+ "Oranien",
+ "Pader",
+ "Quedlin",
+ "Quer",
+ "Ravens",
+ "Regens",
+ "Rott",
+ "Ros",
+ "Rüssels",
+ "Saal",
+ "Saar",
+ "Salz",
+ "Schöne",
+ "Schwein",
+ "Sonder",
+ "Sonnen",
+ "Stein",
+ "Strals",
+ "Straus",
+ "Süd",
+ "Ton",
+ "Unter",
+ "Ur",
+ "Vor",
+ "Wald",
+ "War",
+ "Wert",
+ "Wester",
+ "Witten",
+ "Wolfs",
+ "Würz"
+};
+
+static const char *name_german_2[] = {
+ "bach",
+ "berg",
+ "brück",
+ "brücken",
+ "burg",
+ "dorf",
+ "feld",
+ "furt",
+ "hausen",
+ "haven",
+ "heim",
+ "horst",
+ "mund",
+ "münster",
+ "stadt",
+ "wald"
+};
+
+static const char *name_german_3_an_der[] = {
+ " an der "
+};
+
+static const char *name_german_3_am[] = {
+ " am "
+};
+
+static const char *name_german_4_an_der[] = {
+ "Oder",
+ "Spree",
+ "Donau",
+ "Saale",
+ "Elbe"
+};
+
+static const char *name_german_4_am[] = {
+ "Main"
+};
+
+static const char *name_spanish_real[] = {
+ "Caracas",
+ "Maracay",
+ "Maracaibo",
+ "Velencia",
+ "El Dorado",
+ "Morrocoy",
+ "Cata",
+ "Cataito",
+ "Ciudad Bolivar",
+ "Barquisimeto",
+ "Merida",
+ "Puerto Ordaz",
+ "Santa Elena",
+ "San Juan",
+ "San Luis",
+ "San Rafael",
+ "Santiago",
+ "Barcelona",
+ "Barinas",
+ "San Cristobal",
+ "San Fransisco",
+ "San Martin",
+ "Guayana",
+ "San Carlos",
+ "El Limon",
+ "Coro",
+ "Corocoro",
+ "Puerto Ayacucho",
+ "Elorza",
+ "Arismendi",
+ "Trujillo",
+ "Carupano",
+ "Anaco",
+ "Lima",
+ "Cuzco",
+ "Iquitos",
+ "Callao",
+ "Huacho",
+ "Camana",
+ "Puerto Chala",
+ "Santa Cruz",
+ "Quito",
+ "Cuenca",
+ "Huacho",
+ "Tulcan",
+ "Esmereldas",
+ "Ibarra",
+ "San Lorenzo",
+ "Macas",
+ "Morana",
+ "Machala",
+ "Zamora",
+ "Latacunga",
+ "Tena",
+ "Cochabamba",
+ "Ascencion",
+ "Magdalena",
+ "Santa Ana",
+ "Manoa",
+ "Sucre",
+ "Oruro",
+ "Uyuni",
+ "Potosi",
+ "Tupiza",
+ "La Quiaca",
+ "Yacuiba",
+ "San Borja",
+ "Fuerte Olimpio",
+ "Fortin Esteros",
+ "Campo Grande",
+ "Bogota",
+ "El Banco",
+ "Zaragosa",
+ "Neiva",
+ "Mariano",
+ "Cali",
+ "La Palma",
+ "Andoas",
+ "Barranca",
+ "Montevideo",
+ "Valdivia",
+ "Arica",
+ "Temuco",
+ "Tocopilla",
+ "Mendoza",
+ "Santa Rosa"
+};
+
+static const char *name_french_real[] = {
+ "Agincourt",
+ "Lille",
+ "Dinan",
+ "Aubusson",
+ "Rodez",
+ "Bergerac",
+ "Bordeaux",
+ "Bayonne",
+ "Montpellier",
+ "Montelimar",
+ "Valence",
+ "Digne",
+ "Nice",
+ "Cannes",
+ "St. Tropez",
+ "Marseilles",
+ "Narbonne",
+ "Sète",
+ "Aurillac",
+ "Gueret",
+ "Le Creusot",
+ "Nevers",
+ "Auxerre",
+ "Versailles",
+ "Meaux",
+ "Châlons",
+ "Compiègne",
+ "Metz",
+ "Chaumont",
+ "Langres",
+ "Bourg",
+ "Lyons",
+ "Vienne",
+ "Grenoble",
+ "Toulon",
+ "Rennes",
+ "Le Mans",
+ "Angers",
+ "Nantes",
+ "Châteauroux",
+ "Orléans",
+ "Lisieux",
+ "Cherbourg",
+ "Morlaix",
+ "Cognac",
+ "Agen",
+ "Tulle",
+ "Blois",
+ "Troyes",
+ "Charolles",
+ "Grenoble",
+ "Chambéry",
+ "Tours",
+ "St. Brieuc",
+ "St. Malo",
+ "La Rochelle",
+ "St. Flour",
+ "Le Puy",
+ "Vichy",
+ "St. Valery",
+ "Beaujolais",
+ "Narbonne",
+ "Albi",
+ "St. Valery",
+ "Biarritz",
+ "Béziers",
+ "Nîmes",
+ "Chamonix",
+ "Angoulème",
+ "Alençon"
+};
+
+static const char *name_silly_1[] = {
+ "Binky",
+ "Blubber",
+ "Bumble",
+ "Crinkle",
+ "Crusty",
+ "Dangle",
+ "Dribble",
+ "Flippety",
+ "Google",
+ "Muffin",
+ "Nosey",
+ "Pinker",
+ "Quack",
+ "Rumble",
+ "Sleepy",
+ "Sliggles",
+ "Snooze",
+ "Teddy",
+ "Tinkle",
+ "Twister",
+ "Pinker",
+ "Hippo",
+ "Itchy",
+ "Jelly",
+ "Jingle",
+ "Jolly",
+ "Kipper",
+ "Lazy",
+ "Frogs",
+ "Mouse",
+ "Quack",
+ "Cheeky",
+ "Lumpy",
+ "Grumpy",
+ "Mangle",
+ "Fiddle",
+ "Slugs",
+ "Noodles",
+ "Poodles",
+ "Shiver",
+ "Rumble",
+ "Pixie",
+ "Puddle",
+ "Riddle",
+ "Rattle",
+ "Rickety",
+ "Waffle",
+ "Sagging",
+ "Sausage",
+ "Egg",
+ "Sleepy",
+ "Scatter",
+ "Scramble",
+ "Silly",
+ "Simple",
+ "Trickle",
+ "Slippery",
+ "Slimey",
+ "Slumber",
+ "Soggy",
+ "Sliggles",
+ "Splutter",
+ "Sulky",
+ "Swindle",
+ "Swivel",
+ "Tasty",
+ "Tangle",
+ "Toggle",
+ "Trotting",
+ "Tumble",
+ "Snooze",
+ "Water",
+ "Windy",
+ "Amble",
+ "Bubble",
+ "Cheery",
+ "Cheese",
+ "Cockle",
+ "Cracker",
+ "Crumple",
+ "Teddy",
+ "Evil",
+ "Fairy",
+ "Falling",
+ "Fishy",
+ "Fizzle",
+ "Frosty",
+ "Griddle"
+};
+
+static const char *name_silly_2[] = {
+ "ton",
+ "bury",
+ "bottom",
+ "ville",
+ "well",
+ "weed",
+ "worth",
+ "wig",
+ "wick",
+ "wood",
+ "pool",
+ "head",
+ "burg",
+ "gate",
+ "bridge"
+};
+
+static const char *name_swedish_1[] = {
+ "Gamla ",
+ "Lilla ",
+ "Nya ",
+ "Stora "
+};
+
+static const char *name_swedish_2[] = {
+ "Boll",
+ "Bor",
+ "Ed",
+ "En",
+ "Erik",
+ "Es",
+ "Fin",
+ "Fisk",
+ "Grön",
+ "Hag",
+ "Halm",
+ "Karl",
+ "Kram",
+ "Kung",
+ "Land",
+ "Lid",
+ "Lin",
+ "Mal",
+ "Malm",
+ "Marie",
+ "Ner",
+ "Norr",
+ "Oskar",
+ "Sand",
+ "Skog",
+ "Stock",
+ "Stor",
+ "Ström",
+ "Sund",
+ "Söder",
+ "Tall",
+ "Tratt",
+ "Troll",
+ "Upp",
+ "Var",
+ "Väster",
+ "Ängel",
+ "Öster"
+};
+
+static const char *name_swedish_2a[] = {
+ "B",
+ "Br",
+ "D",
+ "Dr",
+ "Dv",
+ "F",
+ "Fj",
+ "Fl",
+ "Fr",
+ "G",
+ "Gl",
+ "Gn",
+ "Gr",
+ "H",
+ "J",
+ "K",
+ "Kl",
+ "Kn",
+ "Kr",
+ "Kv",
+ "L",
+ "M",
+ "N",
+ "P",
+ "Pl",
+ "Pr",
+ "R",
+ "S",
+ "Sk",
+ "Skr",
+ "Sl",
+ "Sn",
+ "Sp",
+ "Spr",
+ "St",
+ "Str",
+ "Sv",
+ "T",
+ "Tr",
+ "Tv",
+ "V",
+ "Vr"
+};
+
+static const char *name_swedish_2b[] = {
+ "a",
+ "e",
+ "i",
+ "o",
+ "u",
+ "y",
+ "Ã¥",
+ "ä",
+ "ö"
+};
+
+static const char *name_swedish_2c[] = {
+ "ck",
+ "d",
+ "dd",
+ "g",
+ "gg",
+ "l",
+ "ld",
+ "m",
+ "n",
+ "nd",
+ "ng",
+ "nn",
+ "p",
+ "pp",
+ "r",
+ "rd",
+ "rk",
+ "rp",
+ "rr",
+ "rt",
+ "s",
+ "sk",
+ "st",
+ "t",
+ "tt",
+ "v"
+};
+
+static const char *name_swedish_3[] = {
+ "arp",
+ "berg",
+ "boda",
+ "borg",
+ "bro",
+ "bukten",
+ "by",
+ "byn",
+ "fors",
+ "hammar",
+ "hamn",
+ "holm",
+ "hus",
+ "hättan",
+ "kulle",
+ "köping",
+ "lund",
+ "löv",
+ "sala",
+ "skrona",
+ "slätt",
+ "spång",
+ "stad",
+ "sund",
+ "svall",
+ "svik",
+ "såker",
+ "udde",
+ "valla",
+ "viken",
+ "älv",
+ "Ã¥s"
+};
+
+static const char *name_dutch_1[] = {
+ "Nieuw ",
+ "Oud ",
+ "Groot ",
+ "Zuid ",
+ "Noord ",
+ "Oost ",
+ "West ",
+ "Klein "
+};
+
+static const char *name_dutch_2[] = {
+ "Hoog",
+ "Laag",
+ "Zuider",
+ "Zuid",
+ "Ooster",
+ "Oost",
+ "Wester",
+ "West",
+ "Hoofd",
+ "Midden",
+ "Eind",
+ "Amster",
+ "Amstel",
+ "Dord",
+ "Rotter",
+ "Haar",
+ "Til",
+ "Enk",
+ "Dok",
+ "Veen",
+ "Leidsch",
+ "Lely",
+ "En",
+ "Kaats",
+ "U",
+ "Maas",
+ "Mar",
+ "Bla",
+ "Al",
+ "Alk",
+ "Eer",
+ "Drie",
+ "Ter",
+ "Groes",
+ "Goes",
+ "Soest",
+ "Coe",
+ "Uit",
+ "Zwaag",
+ "Hellen",
+ "Slie",
+ "IJ",
+ "Grubben",
+ "Groen",
+ "Lek",
+ "Ridder",
+ "Schie",
+ "Olde",
+ "Roose",
+ "Haar",
+ "Til",
+ "Loos",
+ "Hil"
+};
+
+static const char *name_dutch_3[] = {
+ "Drog",
+ "Nat",
+ "Valk",
+ "Bob",
+ "Dedem",
+ "Kollum",
+ "Best",
+ "Hoend",
+ "Leeuw",
+ "Graaf",
+ "Uithuis",
+ "Purm",
+ "Hard",
+ "Hell",
+ "Werk",
+ "Spijk",
+ "Vink",
+ "Wams",
+ "Heerhug",
+ "Koning"
+};
+
+static const char *name_dutch_4[] = {
+ "e",
+ "er",
+ "el",
+ "en",
+ "o",
+ "s"
+};
+
+static const char *name_dutch_5[] = {
+ "stad",
+ "vorst",
+ "dorp",
+ "dam",
+ "beek",
+ "doorn",
+ "zijl",
+ "zijlen",
+ "lo",
+ "muiden",
+ "meden",
+ "vliet",
+ "nisse",
+ "daal",
+ "vorden",
+ "vaart",
+ "mond",
+ "zaal",
+ "water",
+ "duinen",
+ "heuvel",
+ "geest",
+ "kerk",
+ "meer",
+ "maar",
+ "hoorn",
+ "rade",
+ "wijk",
+ "berg",
+ "heim",
+ "sum",
+ "richt",
+ "burg",
+ "recht",
+ "drecht",
+ "trecht",
+ "tricht",
+ "dricht",
+ "lum",
+ "rum",
+ "halen",
+ "oever",
+ "wolde",
+ "veen",
+ "hoven",
+ "gast",
+ "kum",
+ "hage",
+ "dijk",
+ "zwaag",
+ "pomp",
+ "huizen",
+ "bergen",
+ "schede",
+ "mere",
+ "end"
+};
+
+static const char *name_finnish_real[] = {
+ "Aijala",
+ "Kisko",
+ "Espoo",
+ "Helsinki",
+ "Tapiola",
+ "Järvelä",
+ "Lahti",
+ "Kotka",
+ "Hamina",
+ "Loviisa",
+ "Kouvola",
+ "Tampere",
+ "Oulu",
+ "Salo",
+ "Malmi",
+ "Pelto",
+ "Koski",
+ "Iisalmi",
+ "Raisio",
+ "Taavetti",
+ "Joensuu",
+ "Imatra",
+ "Tapanila",
+ "Pasila",
+ "Turku",
+ "Kupittaa",
+ "Vaasa",
+ "Pori",
+ "Rauma",
+ "Kolari",
+ "Lieksa"
+};
+
+static const char *name_finnish_1[] = {
+ "Hiekka",
+ "Haapa",
+ "Mylly",
+ "Sauna",
+ "Uusi",
+ "Vanha",
+ "Kesä",
+ "Kuusi",
+ "Pelto",
+ "Tuomi",
+ "Terva",
+ "Olki",
+ "Heinä",
+ "Seinä",
+ "Rova",
+ "Koivu",
+ "Kokko",
+ "Mänty",
+ "Pihlaja",
+ "Petäjä",
+ "Kielo",
+ "Kauha",
+ "Viita",
+ "Kivi",
+ "Riihi",
+ "Ääne",
+ "Niini"
+};
+
+static const char *name_finnish_2[] = {
+ "Lappeen",
+ "Lohjan",
+ "Savon",
+ "Lapin",
+ "Pitäjän",
+ "Martin",
+ "Kuusan",
+ "Kemi",
+ "Keri",
+ "Hämeen",
+ "Kangas"
+};
+
+static const char *name_finnish_3[] = {
+ "harju",
+ "linna",
+ "järvi",
+ "kallio",
+ "mäki",
+ "nummi",
+ "joki",
+ "kylä",
+ "lampi",
+ "lahti",
+ "metsä",
+ "suo",
+ "laakso",
+ "niitty",
+ "luoto",
+ "hovi",
+ "ranta",
+ "koski",
+ "salo"
+};
+
+static const char *name_polish_1_m[] = {
+ "Wielki ",
+ "Mały ",
+ "ZÅ‚y ",
+ "Dobry ",
+ "Nowy ",
+ "Stary ",
+ "ZÅ‚oty ",
+ "Zielony ",
+ "Biały ",
+ "Modry ",
+ "Dębowy "
+};
+
+static const char *name_polish_1_f[] = {
+ "Wielka ",
+ "Mała ",
+ "ZÅ‚a ",
+ "Dobra ",
+ "Nowa ",
+ "Stara ",
+ "ZÅ‚ota ",
+ "Zielona ",
+ "Biała ",
+ "Modra ",
+ "Dębowa "
+};
+
+static const char *name_polish_1_n[] = {
+ "Wielkie ",
+ "Małe ",
+ "ZÅ‚e ",
+ "Dobre ",
+ "Nowe ",
+ "Stare ",
+ "ZÅ‚ote ",
+ "Zielone ",
+ "Białe ",
+ "Modre ",
+ "Dębowe "
+};
+
+static const char *name_polish_2_o[] = {
+ "Frombork",
+ "Gniezno",
+ "Olsztyn",
+ "Toruń",
+ "Bydgoszcz",
+ "Terespol",
+ "Kraków",
+ "Poznań",
+ "Wrocław",
+ "Katowice",
+ "Cieszyn",
+ "Bytom",
+ "Frombork",
+ "Hel",
+ "Konin",
+ "Lublin",
+ "Malbork",
+ "Sopot",
+ "Sosnowiec",
+ "Gdańsk",
+ "Gdynia",
+ "Sieradz",
+ "Sandomierz",
+ "Szczyrk",
+ "Szczytno",
+ "Szczecin",
+ "Zakopane",
+ "Szklarska Poręba",
+ "Bochnia",
+ "Golub-Dobrzyn",
+ "Chojnice",
+ "Ostrowiec",
+ "Otwock",
+ "Wolsztyn"
+};
+
+static const char *name_polish_2_m[] = {
+ "Jarocin",
+ "Gogolin",
+ "Tomaszów",
+ "Piotrków",
+ "Lidzbark",
+ "Rypin",
+ "Radzymin",
+ "Wołomin",
+ "Pruszków",
+ "Olsztynek",
+ "Rypin",
+ "Cisek",
+ "Krotoszyn",
+ "Stoczek",
+ "Lubin",
+ "Lubicz",
+ "Milicz",
+ "Targ",
+ "Ostrów",
+ "Ozimek",
+ "Puck",
+ "Rzepin",
+ "Siewierz",
+ "Stargard",
+ "Starogard",
+ "Turek",
+ "Tymbark",
+ "Wolsztyn",
+ "Strzepcz",
+ "Strzebielin",
+ "Sochaczew",
+ "Grębocin",
+ "Gniew",
+ "Lubliniec",
+ "Lubasz",
+ "Lutomiersk",
+ "Niemodlin",
+ "Przeworsk",
+ "Ursus",
+ "Tyczyn",
+ "Sztum",
+ "Szczebrzeszyn",
+ "Wolin",
+ "Wrzeszcz",
+ "Zgierz",
+ "Zieleniec",
+ "Drobin",
+ "Garwolin"
+};
+
+static const char *name_polish_2_f[] = {
+ "Szprotawa",
+ "Pogorzelica",
+ "Motława",
+ "Lubawa",
+ "Nidzica",
+ "Kruszwica",
+ "Bierawa",
+ "Brodnica",
+ "Chojna",
+ "Krzepica",
+ "Ruda",
+ "Rumia",
+ "Tuchola",
+ "Trzebinia",
+ "Ustka",
+ "Warszawa",
+ "Bobowa",
+ "Dukla",
+ "Krynica",
+ "Murowana",
+ "Niemcza",
+ "Zaspa",
+ "Zawoja",
+ "Wola",
+ "Limanowa",
+ "Rabka",
+ "Skawina",
+ "Pilawa"
+};
+
+static const char *name_polish_2_n[] = {
+ "Lipsko",
+ "Pilzno",
+ "Przodkowo",
+ "Strzelno",
+ "Susz",
+ "Jaworzno",
+ "Choszczno",
+ "Mogilno",
+ "Luzino",
+ "Miasto",
+ "Dziadowo",
+ "Kowalewo",
+ "Legionowo",
+ "Miastko",
+ "Zabrze",
+ "Zawiercie",
+ "Kochanowo",
+ "Miechucino",
+ "Mirachowo",
+ "Robakowo",
+ "Kosakowo",
+ "Borne",
+ "Braniewo",
+ "Sulinowo",
+ "Chmielno",
+ "Jastrzębie",
+ "Gryfino",
+ "Koronowo",
+ "Lubichowo",
+ "Opoczno"
+};
+
+static const char *name_polish_3_m[] = {
+ " Wybudowanie",
+ " Świętokrzyski",
+ " Górski",
+ " Morski",
+ " Zdrój",
+ " Wody",
+ " Bajoro",
+ " Krajeński",
+ " ÅšlÄ…ski",
+ " Mazowiecki",
+ " Pomorski",
+ " Wielki",
+ " Maly",
+ " Warmiński",
+ " Mazurski",
+ " Mniejszy",
+ " Większy",
+ " Górny",
+ " Dolny",
+ " Wielki",
+ " Stary",
+ " Nowy",
+ " Wielkopolski",
+ " Wzgórze",
+ " Mosty",
+ " Kujawski",
+ " Małopolski",
+ " Podlaski",
+ " Lesny"
+};
+
+static const char *name_polish_3_f[] = {
+ " Wybudowanie",
+ " Świętokrzyska",
+ " Górska",
+ " Morska",
+ " Zdrój",
+ " Woda",
+ " Bajoro",
+ " Krajeńska",
+ " ÅšlÄ…ska",
+ " Mazowiecka",
+ " Pomorska",
+ " Wielka",
+ " Mała",
+ " Warmińska",
+ " Mazurska",
+ " Mniejsza",
+ " Większa",
+ " Górna",
+ " Dolna",
+ " Wielka",
+ " Stara",
+ " Nowa",
+ " Wielkopolska",
+ " Wzgórza",
+ " Mosty",
+ " Kujawska",
+ " Malopolska",
+ " Podlaska",
+ " Leśna"
+};
+
+static const char *name_polish_3_n[] = {
+ " Wybudowanie",
+ " Åšwietokrzyskie",
+ " Górskie",
+ " Morskie",
+ " Zdrój",
+ " Wody",
+ " Bajoro",
+ " Krajeńskie",
+ " ÅšlÄ…skie",
+ " Mazowieckie",
+ " Pomorskie",
+ " Wielkie",
+ " Małe",
+ " Warmińskie ",
+ " Mazurskie ",
+ " Mniejsze",
+ " Większe",
+ " Górne",
+ " Dolne",
+ " Wielkie",
+ " Stare",
+ " Nowe",
+ " Wielkopolskie",
+ " Wzgórze",
+ " Mosty",
+ " Kujawskie",
+ " Małopolskie",
+ " Podlaskie",
+ " Leśne"
+};
+
+static const char *name_czech_real[] = {
+ "AÅ¡",
+ "Benešov",
+ "Beroun",
+ "Bezdružice",
+ "Blansko",
+ "Břeclav",
+ "Brno",
+ "Bruntál",
+ "Česká Lípa",
+ "České Budějovice",
+ "Český Krumlov",
+ "DÄ›Äín",
+ "Domažlice",
+ "Dubí",
+ "Frýdek-Místek",
+ "HavlíÄkův Brod",
+ "Hodonín",
+ "Hradec Králové",
+ "Humpolec",
+ "Cheb",
+ "Chomutov",
+ "Chrudim",
+ "Jablonec nad Nisou",
+ "Jeseník",
+ "JiÄín",
+ "Jihlava",
+ "Jindřichův Hradec",
+ "Karlovy Vary",
+ "Karviná",
+ "Kladno",
+ "Klatovy",
+ "Kolín",
+ "Kosmonosy",
+ "Kroměříž",
+ "Kutná Hora",
+ "Liberec",
+ "Litoměřice",
+ "Louny",
+ "Manětín",
+ "Mělník",
+ "Mladá Boleslav",
+ "Most",
+ "Náchod",
+ "Nový JiÄín",
+ "Nymburk",
+ "Olomouc",
+ "Opava",
+ "OráÄov",
+ "Ostrava",
+ "Pardubice",
+ "Pelhřimov",
+ "Polžice",
+ "Písek",
+ "Plzeň",
+ "Praha",
+ "Prachatice",
+ "Přerov",
+ "Příbram",
+ "Prostějov",
+ "Rakovník",
+ "Rokycany",
+ "Rudná",
+ "Rychnov nad Kněžnou",
+ "Semily",
+ "Sokolov",
+ "Strakonice",
+ "Středokluky",
+ "Å umperk",
+ "Svitavy",
+ "Tábor",
+ "Tachov",
+ "Teplice",
+ "TÅ™ebíÄ",
+ "Trutnov",
+ "Uherské Hradiště",
+ "Ústí nad Labem",
+ "Ústí nad Orlicí",
+ "Vsetín",
+ "Vyškov",
+ "ŽÄár nad Sázavou",
+ "Zlín",
+ "Znojmo"
+};
+
+
+/* The advanced hyperintelligent Czech town names generator! */
+/* The tables and MakeCzechTownName() is (c) Petr Baudis 2005 (GPL'd)
+ * Feel free to ask me about anything unclear or if you need help
+ * with cloning this for your own language. */
+
+// Sing., pl.
+typedef enum CzechGender {
+ CZG_SMASC,
+ CZG_SFEM,
+ CZG_SNEUT,
+ CZG_PMASC,
+ CZG_PFEM,
+ CZG_PNEUT,
+ // Special for substantive stems - the ending chooses the gender.
+ CZG_FREE,
+ // Like CZG_FREE, but disallow CZG_SNEUT.
+ CZG_NFREE
+} CzechGender;
+typedef enum CzechPattern {
+ CZP_JARNI,
+ CZP_MLADY,
+ CZP_PRIVL
+} CzechPattern;
+/* [CzechGender][CzechPattern] - replaces the last character of the adjective
+ * by this. */
+// XXX: [CZG_SMASC][CZP_PRIVL] needs special handling: -ovX -> -uv.
+static const char *name_czech_patmod[][3] = {
+ /* CZG_SMASC */ { "í", "ý", "X" },
+ /* CZG_SFEM */ { "í", "á", "a" },
+ /* CZG_SNEUT */ { "í", "é", "o" },
+ /* CZG_PMASC */ { "í", "é", "y" },
+ /* CZG_PFEM */ { "í", "é", "y" },
+ /* CZG_PNEUT */ { "í", "á", "a" }
+};
+
+// This way the substantives can choose only some adjectives/endings:
+// At least one of these flags must be satisfied:
+typedef enum CzechAllow {
+ CZA_SHORT = 1,
+ CZA_MIDDLE = 2,
+ CZA_LONG = 4,
+ CZA_ALL = ~0
+} CzechAllow;
+// All these flags must be satisfied (in the stem->others direction):
+typedef enum CzechChoose {
+ CZC_NONE = 0, // No requirements.
+ CZC_COLOR = 1,
+ CZC_POSTFIX = 2, // Matched if postfix was inserted.
+ CZC_NOPOSTFIX = 4, // Matched if no postfix was inserted.
+ CZC_ANY = ~0
+} CzechChoose;
+
+typedef struct CzechNameSubst {
+ CzechGender gender;
+ CzechAllow allow;
+ CzechChoose choose;
+ const char *name;
+} CzechNameSubst;
+
+typedef struct CzechNameAdj {
+ CzechPattern pattern;
+ CzechChoose choose;
+ const char *name;
+} CzechNameAdj;
+
+// Some of items which should be common are doubled.
+static const CzechNameAdj name_czech_adj[] = {
+ { CZP_JARNI, CZC_ANY, "Horní" },
+ { CZP_JARNI, CZC_ANY, "Horní" },
+ { CZP_JARNI, CZC_ANY, "Dolní" },
+ { CZP_JARNI, CZC_ANY, "Dolní" },
+ { CZP_JARNI, CZC_ANY, "Přední" },
+ { CZP_JARNI, CZC_ANY, "Zadní" },
+ { CZP_JARNI, CZC_ANY, "Kostelní" },
+ { CZP_JARNI, CZC_ANY, "Havraní" },
+ { CZP_JARNI, CZC_ANY, "ŘíÄní" },
+ { CZP_JARNI, CZC_ANY, "Jezerní" },
+ { CZP_MLADY, CZC_ANY, "Velký" },
+ { CZP_MLADY, CZC_ANY, "Velký" },
+ { CZP_MLADY, CZC_ANY, "Malý" },
+ { CZP_MLADY, CZC_ANY, "Malý" },
+ { CZP_MLADY, CZC_ANY, "Vysoký" },
+ { CZP_MLADY, CZC_ANY, "Český" },
+ { CZP_MLADY, CZC_ANY, "Moravský" },
+ { CZP_MLADY, CZC_ANY, "Slovácký" },
+ { CZP_MLADY, CZC_ANY, "Slezský" },
+ { CZP_MLADY, CZC_ANY, "Uherský" },
+ { CZP_MLADY, CZC_ANY, "Starý" },
+ { CZP_MLADY, CZC_ANY, "Starý" },
+ { CZP_MLADY, CZC_ANY, "Nový" },
+ { CZP_MLADY, CZC_ANY, "Nový" },
+ { CZP_MLADY, CZC_ANY, "Mladý" },
+ { CZP_MLADY, CZC_ANY, "Královský" },
+ { CZP_MLADY, CZC_ANY, "Kamenný" },
+ { CZP_MLADY, CZC_ANY, "Cihlový" },
+ { CZP_MLADY, CZC_ANY, "Divný" },
+ { CZP_MLADY, CZC_COLOR, "Červená" },
+ { CZP_MLADY, CZC_COLOR, "Červená" },
+ { CZP_MLADY, CZC_COLOR, "Červená" },
+ { CZP_MLADY, CZC_COLOR, "Zelená" },
+ { CZP_MLADY, CZC_COLOR, "Žlutá" },
+ { CZP_MLADY, CZC_COLOR, "Sivá" },
+ { CZP_MLADY, CZC_COLOR, "Šedá" },
+ { CZP_MLADY, CZC_COLOR, "Bílá" },
+ { CZP_MLADY, CZC_COLOR, "Bílá" },
+ { CZP_MLADY, CZC_COLOR, "Modrá" },
+ { CZP_MLADY, CZC_COLOR, "Růžová" },
+ { CZP_MLADY, CZC_COLOR, "Černá" },
+ { CZP_PRIVL, CZC_ANY, "Králova" },
+ { CZP_PRIVL, CZC_ANY, "Janova" },
+ { CZP_PRIVL, CZC_ANY, "Karlova" },
+ { CZP_PRIVL, CZC_ANY, "Kryštofova" },
+ { CZP_PRIVL, CZC_ANY, "Jiříkova" },
+ { CZP_PRIVL, CZC_ANY, "Petrova" },
+ { CZP_PRIVL, CZC_ANY, "Sudovo" },
+};
+
+// Considered a stem for choose/allow matching purposes.
+static const CzechNameSubst name_czech_subst_full[] = {
+ { CZG_SMASC, CZA_ALL, CZC_COLOR, "Sedlec" },
+ { CZG_SMASC, CZA_ALL, CZC_COLOR, "Brod" },
+ { CZG_SMASC, CZA_ALL, CZC_COLOR, "Brod" },
+ { CZG_SMASC, CZA_ALL, CZC_NONE, "Úval" },
+ { CZG_SMASC, CZA_ALL, CZC_COLOR, "ŽÄár" },
+ { CZG_SMASC, CZA_ALL, CZC_COLOR, "Smrk" },
+ { CZG_SFEM, CZA_ALL, CZC_COLOR, "Hora" },
+ { CZG_SFEM, CZA_ALL, CZC_COLOR, "Lhota" },
+ { CZG_SFEM, CZA_ALL, CZC_COLOR, "Lhota" },
+ { CZG_SFEM, CZA_ALL, CZC_COLOR, "Hlava" },
+ { CZG_SFEM, CZA_ALL, CZC_COLOR, "Lípa" },
+ { CZG_SNEUT, CZA_ALL, CZC_COLOR, "Pole" },
+ { CZG_SNEUT, CZA_ALL, CZC_COLOR, "Údolí" },
+ { CZG_PMASC, CZA_ALL, CZC_NONE, "Úvaly" },
+ { CZG_PFEM, CZA_ALL, CZC_COLOR, "Luka" },
+ { CZG_PNEUT, CZA_ALL, CZC_COLOR, "Pole" },
+};
+
+// TODO: More stems needed. --pasky
+static const CzechNameSubst name_czech_subst_stem[] = {
+ { CZG_SMASC, CZA_MIDDLE, CZC_COLOR, "Kostel" },
+ { CZG_SMASC, CZA_MIDDLE, CZC_COLOR, "Klášter" },
+ { CZG_SMASC, CZA_SHORT, CZC_COLOR, "Lhot" },
+ { CZG_SFEM, CZA_SHORT, CZC_COLOR, "Lhot" },
+ { CZG_SFEM, CZA_SHORT, CZC_COLOR, "Hur" },
+ { CZG_FREE, CZA_MIDDLE | CZA_LONG, CZC_NONE, "Sedl" },
+ { CZG_FREE, CZA_SHORT | CZA_MIDDLE | CZA_LONG, CZC_COLOR, "Hrad" },
+ { CZG_NFREE, CZA_MIDDLE, CZC_NONE, "Pras" },
+ { CZG_NFREE, CZA_MIDDLE, CZC_NONE, "Baž" },
+ { CZG_NFREE, CZA_MIDDLE, CZC_NONE, "Tes" },
+ { CZG_NFREE, CZA_MIDDLE, CZC_NONE, "Už" },
+ { CZG_NFREE, CZA_MIDDLE | CZA_LONG, CZC_POSTFIX, "BÅ™" },
+ { CZG_NFREE, CZA_MIDDLE | CZA_LONG, CZC_NONE, "Vod" },
+ { CZG_NFREE, CZA_MIDDLE | CZA_LONG, CZC_NONE, "Jan" },
+ { CZG_NFREE, CZA_LONG, CZC_NONE, "Prach" },
+ { CZG_NFREE, CZA_LONG, CZC_NONE, "Kunr" },
+ { CZG_NFREE, CZA_LONG, CZC_NONE, "Strak" },
+ { CZG_NFREE, CZA_LONG, CZC_NONE, "Vít" },
+ { CZG_NFREE, CZA_LONG, CZC_NONE, "Vyš" },
+ { CZG_NFREE, CZA_LONG, CZC_NONE, "Žat" },
+ { CZG_NFREE, CZA_LONG, CZC_NONE, "Žer" },
+ { CZG_NFREE, CZA_LONG, CZC_NONE, "Střed" },
+ { CZG_NFREE, CZA_LONG, CZC_NONE, "Harv" },
+ { CZG_NFREE, CZA_LONG, CZC_NONE, "Pruh" },
+ { CZG_NFREE, CZA_LONG, CZC_NONE, "Tach" },
+ { CZG_NFREE, CZA_LONG, CZC_NONE, "Písn" },
+ { CZG_NFREE, CZA_LONG, CZC_NONE, "Jin" },
+ { CZG_NFREE, CZA_LONG, CZC_NONE, "Jes" },
+ { CZG_NFREE, CZA_LONG, CZC_NONE, "Jar" },
+ { CZG_NFREE, CZA_LONG, CZC_NONE, "Sok" },
+ { CZG_NFREE, CZA_LONG, CZC_NONE, "Hod" },
+ { CZG_NFREE, CZA_LONG, CZC_NONE, "Net" },
+ { CZG_FREE, CZA_LONG, CZC_NONE, "Praž" },
+ { CZG_FREE, CZA_LONG, CZC_NONE, "Nerat" },
+ { CZG_FREE, CZA_LONG, CZC_NONE, "Kral" },
+ { CZG_FREE, CZA_LONG, CZC_NONE, "Hut" },
+ { CZG_FREE, CZA_LONG, CZC_NOPOSTFIX, "Pan" },
+ { CZG_FREE, CZA_SHORT | CZA_MIDDLE | CZA_LONG, CZC_NOPOSTFIX, "Odstřed" },
+ { CZG_FREE, CZA_SHORT | CZA_MIDDLE | CZA_LONG, CZC_COLOR, "Mrat" },
+ { CZG_FREE, CZA_LONG, CZC_COLOR, "Hlav" },
+ { CZG_FREE, CZA_SHORT | CZA_MIDDLE, CZC_NONE, "Měř" },
+ { CZG_FREE, CZA_MIDDLE | CZA_LONG, CZC_NONE, "Lip" },
+};
+
+// Optional postfix inserted between stem and ending.
+static const char *name_czech_subst_postfix[] = {
+ "av", "an", "at",
+ "ov", "on", "ot",
+ "ev", "en", "et",
+};
+
+// This array must have the both neutral genders at the end!
+static const CzechNameSubst name_czech_subst_ending[] = {
+ { CZG_SMASC, CZA_SHORT | CZA_MIDDLE, CZC_ANY, "ec" },
+ { CZG_SMASC, CZA_SHORT | CZA_MIDDLE, CZC_ANY, "ín" },
+ { CZG_SMASC, CZA_SHORT | CZA_MIDDLE | CZA_LONG, CZC_ANY, "ov" },
+ { CZG_SMASC, CZA_SHORT | CZA_LONG, CZC_ANY, "kov" },
+ { CZG_SMASC, CZA_LONG, CZC_POSTFIX, "ín" },
+ { CZG_SMASC, CZA_LONG, CZC_POSTFIX, "ník" },
+ { CZG_SMASC, CZA_LONG, CZC_ANY, "burk" },
+ { CZG_SFEM, CZA_SHORT, CZC_ANY, "ka" },
+ { CZG_SFEM, CZA_MIDDLE, CZC_ANY, "inka" },
+ { CZG_SFEM, CZA_MIDDLE, CZC_ANY, "ná" },
+ { CZG_SFEM, CZA_LONG, CZC_ANY, "ava" },
+ { CZG_PMASC, CZA_LONG, CZC_POSTFIX, "íky" },
+ { CZG_PMASC, CZA_LONG, CZC_ANY, "upy" },
+ { CZG_PMASC, CZA_LONG, CZC_ANY, "olupy" },
+ { CZG_PFEM, CZA_LONG, CZC_ANY, "avy" },
+ { CZG_PFEM, CZA_SHORT | CZA_MIDDLE | CZA_LONG, CZC_ANY, "ice" },
+ { CZG_PFEM, CZA_SHORT | CZA_MIDDLE | CZA_LONG, CZC_ANY, "iÄky" },
+ { CZG_PNEUT, CZA_SHORT | CZA_MIDDLE, CZC_ANY, "na" },
+ { CZG_SNEUT, CZA_SHORT | CZA_MIDDLE, CZC_ANY, "no" },
+ { CZG_SNEUT, CZA_LONG, CZC_ANY, "iště" },
+};
+
+static const char *name_czech_suffix[] = {
+ "nad Cidlinou",
+ "nad Dyjí",
+ "nad Jihlavou",
+ "nad Labem",
+ "nad Lesy",
+ "nad Moravou",
+ "nad Nisou",
+ "nad Odrou",
+ "nad Ostravicí",
+ "nad Sázavou",
+ "nad Vltavou",
+ "pod Pradědem",
+ "pod Radhoštěm",
+ "pod Řípem",
+ "pod Sněžkou",
+ "pod Å piÄákem",
+ "pod Sedlem",
+ "v Čechách",
+ "na MoravÄ›",
+};
+
+
+
+static const char *name_romanian_real[]= {
+ "Adjud",
+ "Alba Iulia",
+ "Alexandria",
+ "Babadag",
+ "Bacãu",
+ "Baia Mare",
+ "Bãile Herculane",
+ "Bãilesti",
+ "Bârlad",
+ "Bicaz",
+ "Bistrita",
+ "Blaj",
+ "Borsec",
+ "Botosani",
+ "Brãila",
+ "Brasov",
+ "Bucuresti",
+ "Buftea",
+ "Buzãu",
+ "Cãlãrasi",
+ "Caransebes",
+ "Cernavodã",
+ "Cluj-Napoca",
+ "Constanta",
+ "Covasna",
+ "Craiova",
+ "Dej",
+ "Deva",
+ "Dorohoi",
+ "Dr.-Tr. Severin",
+ "Drãgãsani",
+ "Fãgãras",
+ "Fãlticeni",
+ "Fetesti",
+ "Focsani",
+ "Galati",
+ "Gheorgheni",
+ "Giurgiu",
+ "Hârsova",
+ "Hunedoara",
+ "Husi",
+ "Iasi",
+ "Isaccea",
+ "Lugoj",
+ "Mãcin",
+ "Mangalia",
+ "Medgidia",
+ "Medias",
+ "Miercurea Ciuc",
+ "Mizil",
+ "Motru",
+ "Nãsãud",
+ "Nãvodari",
+ "Odobesti",
+ "Oltenita",
+ "Onesti",
+ "Oradea",
+ "Orsova",
+ "Petrosani",
+ "Piatra Neamt",
+ "Pitesti",
+ "Ploiesti",
+ "Predeal",
+ "Râmnicu Vâlcea",
+ "Reghin",
+ "Resita",
+ "Roman",
+ "Rosiorii de Vede",
+ "Satu Mare",
+ "Sebes",
+ "Sfântu Gheorghe",
+ "Sibiu",
+ "Sighisoara",
+ "Sinaia",
+ "Slatina",
+ "Slobozia",
+ "Sovata",
+ "Suceava",
+ "Sulina",
+ "Tãndãrei",
+ "Târgoviste",
+ "Târgu Jiu",
+ "Târgu Mures",
+ "Tecuci",
+ "Timisoara",
+ "Tulcea",
+ "Turda",
+ "Turnu Mãgurele",
+ "Urziceni",
+ "Vaslui",
+ "Vatra Dornei",
+ "Victoria",
+ "Videle",
+ "Zalãu"
+};
+
+static const char *name_slovak_real[] = {
+ "Bratislava",
+ "Banovce nad Bebravou",
+ "Banska Bystrica",
+ "Banska Stiavnica",
+ "Bardejov",
+ "Brezno",
+ "Brezova pod Bradlom",
+ "Bytca",
+ "Cadca",
+ "Cierna nad Tisou",
+ "Detva",
+ "Detva",
+ "Dolny Kubin",
+ "Dolny Kubin",
+ "Dunajska Streda",
+ "Gabcikovo",
+ "Galanta",
+ "Gbely",
+ "Gelnica",
+ "Handlova",
+ "Hlohovec",
+ "Holic",
+ "Humenne",
+ "Hurbanovo",
+ "Kezmarok",
+ "Komarno",
+ "Kosice",
+ "Kremnica",
+ "Krompachy",
+ "Kuty",
+ "Leopoldov",
+ "Levoca",
+ "Liptovsky Mikulas",
+ "Lucenec",
+ "Malacky",
+ "Martin",
+ "Medzilaborce",
+ "Michalovce",
+ "Modra",
+ "Myjava",
+ "Namestovo",
+ "Nitra",
+ "Nova Bana",
+ "Nove Mesto nad Vahom",
+ "Nove Zamky",
+ "Partizanske",
+ "Pezinok",
+ "Piestany",
+ "Poltar",
+ "Poprad",
+ "Povazska Bystrica",
+ "Prievidza",
+ "Puchov",
+ "Revuca",
+ "Rimavska Sobota",
+ "Roznava",
+ "Ruzomberok",
+ "Sabinov",
+ "Sala",
+ "Senec",
+ "Senica",
+ "Sered",
+ "Skalica",
+ "Sladkovicovo",
+ "Smolenice",
+ "Snina",
+ "Stara Lubovna",
+ "Stara Tura",
+ "Strazske",
+ "Stropkov",
+ "Stupava",
+ "Sturovo",
+ "Sulekovo",
+ "Topolcany",
+ "Trebisov",
+ "Trencin",
+ "Trnava",
+ "Turcianske Teplice",
+ "Tvrdosin",
+ "Vrable",
+ "Vranov nad Toplov",
+ "Zahorska Bystrica",
+ "Zdiar",
+ "Ziar nad Hronom",
+ "Zilina",
+ "Zlate Moravce",
+ "Zvolen"
+};
+
+static const char *name_norwegian_1[] = {
+ "Arna",
+ "Aust",
+ "Bjørk",
+ "Bjørn",
+ "Brand",
+ "Bøver",
+ "Drag",
+ "Drø",
+ "Eids",
+ "Egge",
+ "Fager",
+ "Finns",
+ "Flat",
+ "Foll",
+ "Foss",
+ "Fugle",
+ "Furu",
+ "Gaus",
+ "Galte",
+ "Geir",
+ "Gløs",
+ "Gran",
+ "Grind",
+ "Grims",
+ "Grøn",
+ "Grøt",
+ "Gulle",
+ "Haka",
+ "Hammer",
+ "Haug",
+ "Hol",
+ "Hon",
+ "Hop",
+ "Hov",
+ "Jess",
+ "Kabel",
+ "Kjerns",
+ "Kjerring",
+ "Knatte",
+ "Krok",
+ "Køy",
+ "Lang",
+ "Lauv",
+ "Leir",
+ "Lund",
+ "Logn",
+ "Lo",
+ "Lyng",
+ "Løn",
+ "Mesna",
+ "Mel",
+ "Mo",
+ "Nar",
+ "Nitte",
+ "Nord",
+ "Odd",
+ "Ola",
+ "Otte",
+ "Ran",
+ "Rev",
+ "Rog",
+ "Roms",
+ "Rosen",
+ "Sand",
+ "Sau",
+ "Sel",
+ "Sol",
+ "Sjur",
+ "Skår",
+ "Slått",
+ "Stjør",
+ "Stor",
+ "Svart",
+ "Svens",
+ "Svin",
+ "Sylte",
+ "Syn",
+ "Tran",
+ "Vass",
+ "Ved",
+ "Vest",
+ "Vesle",
+ "Vik",
+ "VÃ¥g"
+};
+
+static const char *name_norwegian_2[] = {
+ "aker",
+ "anger",
+ "bakken",
+ "bekk",
+ "berg",
+ "botn",
+ "breen",
+ "bu",
+ "bugen",
+ "by",
+ "bygd",
+ "bø",
+ "dal",
+ "egga",
+ "eid",
+ "elv",
+ "enga",
+ "foss",
+ "fjell",
+ "fjord",
+ "foten",
+ "gard",
+ "grend",
+ "hammer",
+ "haug",
+ "havn",
+ "heim",
+ "hella",
+ "hovda",
+ "høa",
+ "høgda",
+ "kampen",
+ "kjølen",
+ "kollen",
+ "kroken",
+ "land",
+ "lia",
+ "mark",
+ "moen",
+ "myr",
+ "nes",
+ "nuten",
+ "osen",
+ "rike",
+ "rud",
+ "sand",
+ "set",
+ "sjøen",
+ "skogen",
+ "slette",
+ "snipa",
+ "stad",
+ "stua",
+ "stulen",
+ "sund",
+ "svingen",
+ "sætra",
+ "tinden",
+ "tun",
+ "vang",
+ "vatn",
+ "veid",
+ "vik",
+ "voll",
+ "våg",
+ "um",
+ "Ã¥sen"
+};
+
+static const char *name_norwegian_real[] = {
+ "Alta",
+ "Arendal",
+ "Askim",
+ "Bergen",
+ "Bodø",
+ "Brevik",
+ "Bryne",
+ "Brønnøysund",
+ "Drammen",
+ "Drøbak",
+ "Egersund",
+ "Elverum",
+ "Farsund",
+ "Fauske",
+ "Finnsnes",
+ "Flekkefjord",
+ "Flora",
+ "Fosnavåg",
+ "Fredrikstad",
+ "Førde",
+ "Gjøvik",
+ "Grimstad",
+ "Halden",
+ "Hamar",
+ "Hammerfest",
+ "Harstad",
+ "Haugesund",
+ "Holmestrand",
+ "Horten",
+ "Jørpeland",
+ "Kirkenes",
+ "Kolvereid",
+ "Kongsberg",
+ "Kongsvinger",
+ "Kopervik",
+ "Kragerø",
+ "Kristiansand",
+ "Kristiansund",
+ "Langesund",
+ "Larvik",
+ "Leirvik",
+ "Leknes",
+ "Levanger",
+ "Lillehammer",
+ "Lillesand",
+ "Lillestrøm",
+ "Lyngdal",
+ "Lørenskog",
+ "Mandal",
+ "Mo i Rana",
+ "Molde",
+ "Mosjøen",
+ "Moss",
+ "Mysen",
+ "Måløy",
+ "Namsos",
+ "Narvik",
+ "Notodden",
+ "Odda",
+ "Oslo",
+ "Otta",
+ "Porsgrunn",
+ "Ringerike",
+ "Risør",
+ "Rjukan",
+ "Sandefjord",
+ "Sandnes",
+ "Sandnessjøen",
+ "Sandvika",
+ "Sarpsborg",
+ "Sauda",
+ "Ski",
+ "Skien",
+ "Skudeneshavn",
+ "Sortland",
+ "Stathelle",
+ "Stavanger",
+ "Steinkjer",
+ "Stjørdal",
+ "Stokmarknes",
+ "Stord",
+ "Svelvik",
+ "Svolvær",
+ "Tromsø",
+ "Trondheim",
+ "Tvedestrand",
+ "Tønsberg",
+ "Ulsteinvik",
+ "Vadsø",
+ "Vardø",
+ "Verdalsøra",
+ "Ã…krehamn",
+ "Ã…lesund",
+ "Ã…ndalsnes"
+};
+
+static const char *name_hungarian_1[] = {
+ "Nagy-",
+ "Kis-",
+ "Felső-",
+ "Alsó-",
+ "Új-"
+};
+
+static const char *name_hungarian_2[] = {
+ "Bodrog",
+ "Dráva",
+ "Duna",
+ "Hejő",
+ "Hernád",
+ "Rába",
+ "Sajó",
+ "Szamos",
+ "Tisza",
+ "Zala",
+ "Balaton",
+ "Fertő",
+ "Bakony",
+ "Cserhát",
+ "Bihar",
+ "Hajdú",
+ "Jász",
+ "Kun",
+ "Magyar",
+ "Nógrád",
+ "Nyír",
+ "Somogy",
+ "Székely",
+ "Buda",
+ "Győr",
+ "Pest",
+ "Fehér",
+ "Cserép",
+ "Erdő",
+ "Hegy",
+ "Homok",
+ "Mező",
+ "Puszta",
+ "Sár",
+ "Császár",
+ "Herceg",
+ "Király",
+ "Nemes",
+ "Püspök",
+ "Szent",
+ "Almás",
+ "Szilvás",
+ "Agg",
+ "Aranyos",
+ "Békés",
+ "Egyházas",
+ "Gagy",
+ "Heves",
+ "Kapos",
+ "Tápió",
+ "Torna",
+ "Vas",
+ "Vámos",
+ "Vásáros"
+};
+
+static const char *name_hungarian_3[] = {
+ "apáti",
+ "bába",
+ "bikk",
+ "dob",
+ "fa",
+ "föld",
+ "hegyes",
+ "kak",
+ "kereszt",
+ "kürt",
+ "ladány",
+ "mérges",
+ "szalonta",
+ "telek",
+ "vas",
+ "völgy"
+};
+
+static const char *name_hungarian_4[] = {
+ "alja",
+ "egyháza",
+ "háza",
+ "úr",
+ "vár"
+};
+
+static const char *name_hungarian_real[] = {
+ "Ajka",
+ "Aszód",
+ "Badacsony",
+ "Baja",
+ "Budapest",
+ "Debrecen",
+ "Eger",
+ "Fonyód",
+ "Gödöllő",
+ "Győr",
+ "Gyula",
+ "Karcag",
+ "Kecskemét",
+ "Keszthely",
+ "Kisköre",
+ "Kocsord",
+ "Komárom",
+ "KÅ‘szeg",
+ "Makó",
+ "Mohács",
+ "Miskolc",
+ "Ózd",
+ "Paks",
+ "Pápa",
+ "Pécs",
+ "Polgár",
+ "Sarkad",
+ "Siófok",
+ "Szeged",
+ "Szentes",
+ "Szolnok",
+ "Tihany",
+ "Tokaj",
+ "Vác",
+ "Záhony",
+ "Zirc"
+};
+
+static const char *name_swiss_real[] = {
+ "Aarau",
+ "Aesch",
+ "Altdorf",
+ "Arosa",
+ "Appenzell",
+ "Arbon",
+ "Altstätten",
+ "Baar",
+ "Baden",
+ "Bellinzona",
+ "Brig-Glis",
+ "Bienne",
+ "Bulle",
+ "Binningen",
+ "Burgdorf",
+ "Bern",
+ "Basel",
+ "Bülach",
+ "Carouge",
+ "Cham",
+ "Chiasso",
+ "Chur",
+ "Davos",
+ "Delémont",
+ "Dietikon",
+ "Dübendorf",
+ "Emmen",
+ "Freienbach-Pfäffikon",
+ "Fribourg",
+ "Frauenfeld",
+ "Genève",
+ "Glarus",
+ "Gossau",
+ "Grenchen",
+ "Herisau",
+ "Horgen",
+ "Horw",
+ "Illnau-Effretikon",
+ "Ittigen",
+ "Jona",
+ "Kriens",
+ "Kloten",
+ "Köniz",
+ "Kreuzlingen",
+ "Küsnacht",
+ "Agen",
+ "Lancy",
+ "La Chaux-de-Fonds",
+ "Lenzburg",
+ "Lugano",
+ "Langenthal",
+ "Littau",
+ "Le Locle",
+ "La Neuveville",
+ "Locarno",
+ "Liestal",
+ "La Tour-de-Peilz",
+ "Lausanne",
+ "Lyss",
+ "Luzern",
+ "Martigny",
+ "Münchenstein",
+ "Meyrin",
+ "Montreux",
+ "Monthey",
+ "Morges",
+ "Murten",
+ "Moutier",
+ "Muttenz",
+ "Neuchâtel",
+ "Neuhausen am Rheinfall",
+ "Nyon",
+ "Olten",
+ "Onex",
+ "Opfikon",
+ "Ostermundigen",
+ "Payerne",
+ "Peseux",
+ "Prilly",
+ "Pully",
+ "Rapperswil",
+ "Richterswil",
+ "Regensdorf",
+ "Rheinfelden",
+ "Riehen",
+ "Renens",
+ "Romanshorn",
+ "Rorschach",
+ "Stans",
+ "Schaffhausen",
+ "Steffisburg",
+ "St. Gallen",
+ "Schlieren",
+ "Sierre",
+ "Solothurn",
+ "St. Moritz",
+ "Sion",
+ "Spiez",
+ "Stäfa",
+ "Sursee",
+ "Schwyz",
+ "Thalwil",
+ "Thônex",
+ "Thun",
+ "Uster",
+ "Uzwil",
+ "Vernier",
+ "Volketswil",
+ "Versoix",
+ "Vevey",
+ "Wädenswil",
+ "Wettingen",
+ "Wil",
+ "Wallisellen",
+ "Winterthur",
+ "Wohlen",
+ "Worb",
+ "Wetzikon",
+ "Yverdon-les-Bains",
+ "Zollikon",
+ "Zofingen",
+ "Zürich",
+ "Zug",
+};
+
+static const char *name_danish_1[] = {
+ "Gamle ",
+ "Lille ",
+ "Nye ",
+ "Store ",
+ "Kirke ",
+ "Nørre ",
+ "Vester ",
+ "Sønder ",
+ "Øster ",
+ "Hvide ",
+ "Høje ",
+ "Kongens ",
+};
+
+static const char *name_danish_2[] = {
+ "Ager",
+ "Alle",
+ "Aske",
+ "Balle",
+ "Bede",
+ "Birke",
+ "Bjerring",
+ "Bjæver",
+ "Blommens",
+ "Blok",
+ "Bolder",
+ "Bred",
+ "Charlotten",
+ "Christians",
+ "Danne",
+ "Diana",
+ "Es",
+ "Fredens",
+ "Frederiks",
+ "Fugle",
+ "FÃ¥re",
+ "Gille",
+ "Gis",
+ "Givs",
+ "Glams",
+ "Glo",
+ "Guld",
+ "Had",
+ "Haralds",
+ "Hassel",
+ "Hede",
+ "Helle",
+ "Hessel",
+ "Hjorts",
+ "Hol",
+ "Horn",
+ "Humle",
+ "Høj",
+ "Hør",
+ "Is",
+ "Jyde",
+ "Jægers",
+ "Karls",
+ "Klov",
+ "Kokke",
+ "Kvist",
+ "Lang",
+ "Lange",
+ "Mari",
+ "Nord",
+ "Ny",
+ "Oks",
+ "Ring",
+ "Røde",
+ "Rung",
+ "Rør",
+ "Rud",
+ "Saks",
+ "Salt",
+ "Skam",
+ "Silke",
+ "Skod",
+ "Skæl",
+ "Skær",
+ "Sol",
+ "Svend",
+ "Svine",
+ "Strand",
+ "Stubbe",
+ "Ting",
+ "Tjære",
+ "Tore",
+ "Uger",
+ "Ulf",
+ "Val",
+ "Vand",
+ "Vej",
+ "Vor",
+ "Vær",
+ "Ør",
+ "Ã…l"
+};
+
+static const char *name_danish_3[] = {
+ "basse",
+ "borg",
+ "berg",
+ "bro",
+ "by",
+ "havn",
+ "strup",
+ "holm",
+ "hus",
+ "købing",
+ "lund",
+ "lunde",
+ "sund",
+ "ovre",
+ "høj",
+ "dal",
+ "sted",
+ "sten",
+ "løse",
+ "rød",
+ "magle",
+ "sø",
+ "bjerg",
+ "bæk",
+ "drup",
+ "lev",
+ "bo",
+ "lyst",
+ "feld",
+ "skov"
+};
+
+static const char *name_turkish_prefix[] = {
+ "Akça",
+ "Altın",
+ "Bahçe",
+ "Boz",
+ "Büyük",
+ "Çay",
+ "DoÄŸu",
+ "Eski",
+ "Güzel",
+ "Kızıl",
+ "Küçük",
+ "Orta",
+ "Sarı",
+ "Sultan",
+ "Ulu",
+ "Yeni"
+};
+
+static const char *name_turkish_middle[] = {
+ "agaç",
+ "ayva",
+ "çam",
+ "elma",
+ "kurt",
+ "pazar",
+ "yalı"
+};
+
+static const char *name_turkish_suffix[] = {
+ "dere",
+ "hisar",
+ "kale",
+ "kaya",
+ "kent",
+ "köy",
+ "ova",
+ "özü",
+ "ören",
+ "pazar",
+ "saray",
+ "tepe",
+ "yer",
+ "yurt"
+};
+
+static const char *name_turkish_real[] = {
+ "Adana",
+ "Adıyaman",
+ "Afyon",
+ "Ağrı",
+ "Amasya",
+ "Antalya",
+ "Artvin",
+ "Balıkesir",
+ "Bilecik",
+ "Bitlis",
+ "Bolu",
+ "Burdur",
+ "Bursa",
+ "Çanakkale",
+ "Çankırı",
+ "Denizli",
+ "Diyarbakır",
+ "Edirne",
+ "Elazığ",
+ "Erzurum",
+ "Eskisehir",
+ "Giresun",
+ "Gümüşhane",
+ "Hatay",
+ "Isparta",
+ "İçel",
+ "Ä°stanbul",
+ "Ä°zmir",
+ "Kars",
+ "Kastamonu",
+ "Kayseri",
+ "Kirklareli",
+ "Kocaeli",
+ "Konya",
+ "Kütahya",
+ "Malatya",
+ "Manisa",
+ "KahramanmaraÅŸ",
+ "Mardin",
+ "MuÄŸla",
+ "MuÅŸ",
+ "NevÅŸehir",
+ "NiÄŸde",
+ "Rize",
+ "Sakarya",
+ "Samsun",
+ "Siirt",
+ "Sinop",
+ "Sivas",
+ "Trabzon",
+ "Şanlıurfa",
+ "Van",
+ "Yozgat",
+ "Zonguldak",
+ "Aksaray",
+ "Bayburt",
+ "Karaman",
+ "Şırnak",
+ "Bartın",
+ "Ardahan",
+ "Iğdır",
+ "Yalova",
+ "Karabük",
+ "Osmaniye",
+ "Düzce"
+};
+
+static const char *name_italian_real[] = {
+ "Roma",
+ "Milano",
+ "Napoli",
+ "Torino",
+ "Venezia",
+ "Firenze",
+ "Palermo",
+ "Genova",
+ "Parma",
+ "Bologna",
+ "Bari",
+ "Cagliari",
+ "Sassari",
+ "Pisa",
+ "Aosta",
+ "Brescia",
+ "Verona",
+ "Bolzano",
+ "Padova",
+ "Udine",
+ "Trieste",
+ "Livorno",
+ "Ancona",
+ "Perugia",
+ "Pescara",
+ "L'Aquila",
+ "Campobasso",
+ "Potenza",
+ "Cosenza",
+ "Reggio Calabria",
+ "Catania",
+ "Caltanisetta",
+ "Agrigento",
+ "La Spezia",
+ "Modena",
+ "Vicenza",
+ "Mantova",
+ "Cremona",
+ "Piacenza",
+ "Reggio Emilia",
+ "Foggia",
+ "Benevento",
+ "Salerno",
+ "Catanzaro",
+ "Lecce",
+ "Como",
+ "Lecco",
+ "Sondrio",
+ "Trento",
+ "Desenzano",
+ "Cuneo",
+ "Asti",
+ "Lodi",
+ "Novara",
+ "Biella",
+ "Vercelli",
+ "Rieti",
+ "Nuoro",
+ "Oristano",
+ "Matera",
+ "Taranto",
+ "Varese",
+ "Bergamo",
+ "Pavia",
+ "Caserta",
+ "Frosinone",
+ "Latina",
+ "Enna",
+ "Ragusa",
+ "Siracusa",
+ "Pordenone",
+ "Imperia",
+ "Verbania",
+ "Alessandria",
+ "Messina",
+ "Siena",
+ "Arezzo",
+ "Grosseto",
+};
+
+static const char *name_italian_pref[] = {
+ "Alpe ",
+ "Borgo ",
+ "Cascina ",
+ "Castel ",
+ "Fonte ",
+ "Forte ",
+ "Malga ",
+ "Pieve ",
+ "Poggio ",
+ "Rocca ",
+ "Villa ",
+ "Villar ",
+};
+
+static const char *name_italian_1m[] = {
+ "Bel",
+ "Borgo",
+ "Bosco",
+ "Campo",
+ "Capo",
+ "Casal",
+ "Castel",
+ "Colle",
+ "Fiume",
+ "Fonte",
+ "Lago",
+ "Mezzo",
+ "Monte",
+ "Mon",
+ "Orto",
+ "Passo",
+ "Prato",
+ "Poggio",
+ "Ponte",
+ "Pozzo",
+ "Sasso",
+ "Tra",
+ "Tre",
+ "Ver",
+ "Vico",
+};
+
+static const char *name_italian_1f[] = {
+ "Acqua",
+ "Bra",
+ "Cala",
+ "Casa",
+ "Chiesa",
+ "Citta",
+ "Civita",
+ "Corte",
+ "Costa",
+ "Croce",
+ "Fontana",
+ "Grotta",
+ "Guardia",
+ "Mezza",
+ "Palma",
+ "Pietra",
+ "Ripa",
+ "Rocca",
+ "Serra",
+ "Torre",
+ "Val",
+ "Valle",
+ "Villa",
+};
+
+static const char *name_italian_2[] = {
+ "bell",
+ "bianc",
+ "cald",
+ "chiar",
+ "cort",
+ "ferrat",
+ "fier",
+ "fredd",
+ "gioios",
+ "grec",
+ "guzz",
+ "lung",
+ "long",
+ "migli",
+ "negr",
+ "ner",
+ "nov",
+ "nuov",
+ "ross",
+ "rotond",
+ "scur",
+ "secc",
+ "sett",
+ "vecchi",
+ "ventos",
+ "vers",
+ "viv",
+};
+
+static const char *name_italian_2i[] = {
+ "",
+ "breve",
+ "brevi",
+ "chiari",
+ "ferro",
+ "fieschi",
+ "fiore",
+ "fonte",
+ "forte",
+ "gate",
+ "leone",
+ "maggiore",
+ "minore",
+ "mole",
+ "monte",
+ "poli",
+ "scuri",
+ "terra",
+ "te",
+ "torrione",
+ "vento",
+ "verde",
+ "versiere",
+};
+
+
+static const char *name_italian_3[] = {
+ " Marittimo",
+ " Marittima",
+ " del Capo",
+ " del Monte",
+ " di Sopra",
+ " di Sotto",
+ " sui Monti",
+ " dei Marmi",
+ " dei Sassi",
+ " delle Fonti",
+ " sui Prati",
+ " a Mare",
+ " Superiore",
+ " Inferiore",
+ " Terme",
+ " Alta",
+ " Bassa",
+ " Brianza",
+ " Vesuviano",
+ " Scrivia",
+ " Ticino",
+};
+
+static const char *name_italian_river1[] = {
+ " del",
+ " sul",
+ " al",
+ " nel",
+};
+
+static const char *name_italian_river2[] = {
+ "l'Adda",
+ "l'Adige",
+ "le Alpi",
+ "l'Arno",
+ " Bormida",
+ " Brenta",
+ "la Dora Baltea",
+ " Lambro",
+ " Mincio",
+ " Naviglio",
+ "l'Oglio",
+ "l'Olona",
+ "l'Ombrone",
+ " Panaro",
+ " Piave",
+ " Po",
+ " Reno",
+ " Scrivia",
+ " Secchia",
+ " Serio",
+ " Tagliamento",
+ " Tanaro",
+ " Taro",
+ " Ticino",
+ " Tevere",
+};
+
+static const char *name_catalan_real[] = {
+ "Barcelona",
+ "Hospitalet",
+ "Cerdanyola",
+ "Martorell",
+ "Badalona",
+ "Tarragona",
+ "Lleida",
+ "Girona",
+ "Sabadell",
+ "Terrassa",
+ "Reus",
+ "Valls",
+ "Vic",
+ "Vielha",
+ "Amposta",
+ "Tortosa",
+ "Berga",
+ "Olot",
+ "Mollerussa",
+ "Banyoles",
+ "Figueres",
+ "Balaguer",
+ "Vilafranca del Penedès",
+ "La seu d'Urgell",
+ "Pont de Suert",
+ "Igualada",
+ "Manresa",
+ "Solsona",
+ "Les borges blanques",
+ "Tremp",
+ "Sort",
+ "Colera",
+ "Portbou",
+ "El Vendrell",
+ "Falset",
+ "Ripoll",
+ "Cervera",
+ "Gandesa",
+ "Mataró",
+ "Montblanc",
+ "Vilanova i la Geltrú",
+ "Tàrrega",
+ "Camprodon",
+ "Campdevànol",
+ "Cambrils",
+ "Begur",
+ "Set Cases",
+ "Palafrugell",
+ "Begues",
+ "El Bruc",
+ "Cadaqués",
+ "Collbató",
+ "Cervelló",
+ "Esparraguera",
+ "Abrera",
+ "Alp",
+ "Das",
+ "Cercs",
+ "Manlleu",
+ "Masnou",
+ "Molins de rei",
+ "Monistrol",
+ "Rocallaura",
+ "Rubí",
+ "Ripollet",
+ "Sitges",
+ "Roses",
+};
+
+static const char *name_catalan_pref[] = {
+ "Pont de ",
+ "Parets de ",
+ "Canet de ",
+ "Castellar de ",
+ "Corbera de ",
+ "Arenys de ",
+ "Calella de ",
+ "La seu de ",
+ "La bisbal de ",
+ "Torroella de ",
+ "Port de ",
+ "Vilafranca de ",
+ "Vilanova de ",
+ "Caldes de ",
+ "La Conca de ",
+ "Olesa de ",
+ "La Roca de ",
+ "Sant Esteve de ",
+ "Sant Andreu de ",
+ "Sant Jordi de ",
+ "Sant Joan de ",
+ "Sant Feliu de ",
+ "Sant Quirze de ",
+ "Sant Sadurní de ",
+ "Santa Coloma de ",
+ "Santa Margarida de ",
+ "Santa Maria de ",
+ "Sant Martí de ",
+ "Sant Pere de ",
+ "Sant Julià de ",
+ "Sant Vicenç de ",
+
+};
+
+static const char *name_catalan_1m[] = {
+ "Torrent",
+ "Cami",
+ "Mont",
+ "Bell",
+ "Puig",
+ "Riu",
+};
+
+static const char *name_catalan_1f[] = {
+ "Aigua",
+ "Selva ",
+ "Vall",
+ "Serra",
+ "Torre",
+ "Riba",
+ "Vall",
+ "Terra",
+};
+
+static const char *name_catalan_2m[] = {
+ "alt",
+ "baix",
+ "fosc",
+ "pelat",
+ "ventós",
+ "negre",
+ "roig",
+ "gris",
+};
+
+static const char *name_catalan_2f[] = {
+ "baixa",
+ "alta",
+ "fosca",
+ "clara",
+ "negra",
+ "roja",
+ "grisa",
+ "freda",
+};
+
+static const char *name_catalan_3[] = {
+ " despí",
+ " desvern",
+ " del camí",
+ " de Mar",
+ " de Dalt",
+ " de Baix",
+ " del Vallès",
+ " de Berguedà",
+ " de Conflent",
+ " de la plana",
+};
+
+static const char *name_catalan_river1[] = {
+ " d'Anoia",
+ " de Ter",
+ " de Llobregat",
+ " d'Ebre",
+ " de Segre",
+ " de Francolí",
+};
diff --git a/src/table/palettes.h b/src/table/palettes.h
new file mode 100644
index 000000000..fc931c7c2
--- /dev/null
+++ b/src/table/palettes.h
@@ -0,0 +1,199 @@
+/* $Id$ */
+
+#define M(r, g, b) { r, g, b }
+static const Colour _palettes[][256] = {
+ /* palette 1 (TTD Windows) */
+ {
+ M( 0, 0, 0), M(212, 0, 212), M(212, 0, 212), M(212, 0, 212),
+ M(212, 0, 212), M(212, 0, 212), M(212, 0, 212), M(212, 0, 212),
+ M(212, 0, 212), M(212, 0, 212), M(168, 168, 168), M(184, 184, 184),
+ M(200, 200, 200), M(216, 216, 216), M(232, 232, 232), M(252, 252, 252),
+ M( 52, 60, 72), M( 68, 76, 92), M( 88, 96, 112), M(108, 116, 132),
+ M(132, 140, 152), M(156, 160, 172), M(176, 184, 196), M(204, 208, 220),
+ M( 48, 44, 4), M( 64, 60, 12), M( 80, 76, 20), M( 96, 92, 28),
+ M(120, 120, 64), M(148, 148, 100), M(176, 176, 132), M(204, 204, 168),
+ M(100, 100, 100), M(116, 116, 116), M(104, 80, 44), M(124, 104, 72),
+ M(152, 132, 92), M(184, 160, 120), M(212, 188, 148), M(244, 220, 176),
+ M(132, 132, 132), M( 88, 4, 16), M(112, 16, 32), M(136, 32, 52),
+ M(160, 56, 76), M(188, 84, 108), M(204, 104, 124), M(220, 132, 144),
+ M(236, 156, 164), M(252, 188, 192), M(252, 212, 0), M(252, 232, 60),
+ M(252, 248, 128), M( 76, 40, 0), M( 96, 60, 8), M(116, 88, 28),
+ M(136, 116, 56), M(156, 136, 80), M(176, 156, 108), M(196, 180, 136),
+ M( 68, 24, 0), M( 96, 44, 4), M(128, 68, 8), M(156, 96, 16),
+ M(184, 120, 24), M(212, 156, 32), M(232, 184, 16), M(252, 212, 0),
+ M(252, 248, 128), M(252, 252, 192), M( 32, 4, 0), M( 64, 20, 8),
+ M( 84, 28, 16), M(108, 44, 28), M(128, 56, 40), M(148, 72, 56),
+ M(168, 92, 76), M(184, 108, 88), M(196, 128, 108), M(212, 148, 128),
+ M( 8, 52, 0), M( 16, 64, 0), M( 32, 80, 4), M( 48, 96, 4),
+ M( 64, 112, 12), M( 84, 132, 20), M(104, 148, 28), M(128, 168, 44),
+ M( 64, 64, 64), M( 44, 68, 32), M( 60, 88, 48), M( 80, 104, 60),
+ M(104, 124, 76), M(128, 148, 92), M(152, 176, 108), M(180, 204, 124),
+ M( 16, 52, 24), M( 32, 72, 44), M( 56, 96, 72), M( 76, 116, 88),
+ M( 96, 136, 108), M(120, 164, 136), M(152, 192, 168), M(184, 220, 200),
+ M( 32, 24, 0), M( 56, 28, 0), M( 80, 80, 80), M( 88, 52, 12),
+ M(104, 64, 24), M(124, 84, 44), M(140, 108, 64), M(160, 128, 88),
+ M( 76, 40, 16), M( 96, 52, 24), M(116, 68, 40), M(136, 84, 56),
+ M(164, 96, 64), M(184, 112, 80), M(204, 128, 96), M(212, 148, 112),
+ M(224, 168, 128), M(236, 188, 148), M( 80, 28, 4), M(100, 40, 20),
+ M(120, 56, 40), M(140, 76, 64), M(160, 100, 96), M(184, 136, 136),
+ M( 36, 40, 68), M( 48, 52, 84), M( 64, 64, 100), M( 80, 80, 116),
+ M(100, 100, 136), M(132, 132, 164), M(172, 172, 192), M(212, 212, 224),
+ M( 48, 48, 48), M( 64, 44, 144), M( 88, 64, 172), M(104, 76, 196),
+ M(120, 88, 224), M(140, 104, 252), M(160, 136, 252), M(188, 168, 252),
+ M( 0, 24, 108), M( 0, 36, 132), M( 0, 52, 160), M( 0, 72, 184),
+ M( 0, 96, 212), M( 24, 120, 220), M( 56, 144, 232), M( 88, 168, 240),
+ M(128, 196, 252), M(188, 224, 252), M( 16, 64, 96), M( 24, 80, 108),
+ M( 40, 96, 120), M( 52, 112, 132), M( 80, 140, 160), M(116, 172, 192),
+ M(156, 204, 220), M(204, 240, 252), M(172, 52, 52), M(212, 52, 52),
+ M(252, 52, 52), M(252, 100, 88), M(252, 144, 124), M(252, 184, 160),
+ M(252, 216, 200), M(252, 244, 236), M( 72, 20, 112), M( 92, 44, 140),
+ M(112, 68, 168), M(140, 100, 196), M(168, 136, 224), M(204, 180, 252),
+ M(204, 180, 252), M(232, 208, 252), M( 60, 0, 0), M( 92, 0, 0),
+ M(128, 0, 0), M(160, 0, 0), M(196, 0, 0), M(224, 0, 0),
+ M(252, 0, 0), M(252, 80, 0), M(252, 108, 0), M(252, 136, 0),
+ M(252, 164, 0), M(252, 192, 0), M(252, 220, 0), M(252, 252, 0),
+ M(204, 136, 8), M(228, 144, 4), M(252, 156, 0), M(252, 176, 48),
+ M(252, 196, 100), M(252, 216, 152), M( 8, 24, 88), M( 12, 36, 104),
+ M( 20, 52, 124), M( 28, 68, 140), M( 40, 92, 164), M( 56, 120, 188),
+ M( 72, 152, 216), M(100, 172, 224), M( 92, 156, 52), M(108, 176, 64),
+ M(124, 200, 76), M(144, 224, 92), M(224, 244, 252), M(204, 240, 252),
+ M(180, 220, 236), M(132, 188, 216), M( 88, 152, 172), M( 16, 16, 16),
+ M( 32, 32, 32), M( 8, 92, 104), M( 16, 100, 112), M( 24, 108, 120),
+ M( 32, 116, 128), M( 44, 124, 140), M( 92, 164, 184), M(116, 180, 196),
+ M(148, 200, 216), M(180, 220, 232), M(216, 244, 252), M( 0, 0, 0),
+ M( 0, 0, 0), M( 0, 0, 0), M( 0, 0, 0), M( 0, 0, 0),
+ M(252, 60, 0), M(252, 80, 0), M(252, 104, 0), M(252, 128, 0),
+ M(252, 148, 0), M(252, 172, 0), M(252, 196, 0), M(252, 0, 0),
+ M(252, 0, 0), M( 0, 0, 0), M( 0, 0, 0), M( 0, 0, 0),
+ M(252, 228, 0), M(148, 148, 148), M(212, 0, 212), M(212, 0, 212),
+ M(212, 0, 212), M(212, 0, 212), M(212, 0, 212), M(212, 0, 212),
+ M(212, 0, 212), M(212, 0, 212), M(212, 0, 212), M(252, 252, 252)
+ },
+
+ /* palette 2 (mixed TTD DOS + TTD Windows palette */
+ {
+ M( 0, 0, 0), M( 16, 16, 16), M( 32, 32, 32), M( 48, 48, 48),
+ M( 65, 64, 65), M( 82, 80, 82), M( 98, 101, 98), M(115, 117, 115),
+ M(131, 133, 131), M(148, 149, 148), M(168, 168, 168), M(184, 184, 184),
+ M(200, 200, 200), M(216, 216, 216), M(232, 232, 232), M(252, 252, 252),
+ M( 52, 60, 72), M( 68, 76, 92), M( 88, 96, 112), M(108, 116, 132),
+ M(132, 140, 152), M(156, 160, 172), M(176, 184, 196), M(204, 208, 220),
+ M( 48, 44, 4), M( 64, 60, 12), M( 80, 76, 20), M( 96, 92, 28),
+ M(120, 120, 64), M(148, 148, 100), M(176, 176, 132), M(204, 204, 168),
+ M( 72, 44, 4), M( 88, 60, 20), M(104, 80, 44), M(124, 104, 72),
+ M(152, 132, 92), M(184, 160, 120), M(212, 188, 148), M(244, 220, 176),
+ M( 64, 0, 4), M( 88, 4, 16), M(112, 16, 32), M(136, 32, 52),
+ M(160, 56, 76), M(188, 84, 108), M(204, 104, 124), M(220, 132, 144),
+ M(236, 156, 164), M(252, 188, 192), M(252, 212, 0), M(252, 232, 60),
+ M(252, 248, 128), M( 76, 40, 0), M( 96, 60, 8), M(116, 88, 28),
+ M(136, 116, 56), M(156, 136, 80), M(176, 156, 108), M(196, 180, 136),
+ M( 68, 24, 0), M( 96, 44, 4), M(128, 68, 8), M(156, 96, 16),
+ M(184, 120, 24), M(212, 156, 32), M(232, 184, 16), M(252, 212, 0),
+ M(252, 248, 128), M(252, 252, 192), M( 32, 4, 0), M( 64, 20, 8),
+ M( 84, 28, 16), M(108, 44, 28), M(128, 56, 40), M(148, 72, 56),
+ M(168, 92, 76), M(184, 108, 88), M(196, 128, 108), M(212, 148, 128),
+ M( 8, 52, 0), M( 16, 64, 0), M( 32, 80, 4), M( 48, 96, 4),
+ M( 64, 112, 12), M( 84, 132, 20), M(104, 148, 28), M(128, 168, 44),
+ M( 28, 52, 24), M( 44, 68, 32), M( 60, 88, 48), M( 80, 104, 60),
+ M(104, 124, 76), M(128, 148, 92), M(152, 176, 108), M(180, 204, 124),
+ M( 16, 52, 24), M( 32, 72, 44), M( 56, 96, 72), M( 76, 116, 88),
+ M( 96, 136, 108), M(120, 164, 136), M(152, 192, 168), M(184, 220, 200),
+ M( 32, 24, 0), M( 56, 28, 0), M( 72, 40, 0), M( 88, 52, 12),
+ M(104, 64, 24), M(124, 84, 44), M(140, 108, 64), M(160, 128, 88),
+ M( 76, 40, 16), M( 96, 52, 24), M(116, 68, 40), M(136, 84, 56),
+ M(164, 96, 64), M(184, 112, 80), M(204, 128, 96), M(212, 148, 112),
+ M(224, 168, 128), M(236, 188, 148), M( 80, 28, 4), M(100, 40, 20),
+ M(120, 56, 40), M(140, 76, 64), M(160, 100, 96), M(184, 136, 136),
+ M( 36, 40, 68), M( 48, 52, 84), M( 64, 64, 100), M( 80, 80, 116),
+ M(100, 100, 136), M(132, 132, 164), M(172, 172, 192), M(212, 212, 224),
+ M( 40, 20, 112), M( 64, 44, 144), M( 88, 64, 172), M(104, 76, 196),
+ M(120, 88, 224), M(140, 104, 252), M(160, 136, 252), M(188, 168, 252),
+ M( 0, 24, 108), M( 0, 36, 132), M( 0, 52, 160), M( 0, 72, 184),
+ M( 0, 96, 212), M( 24, 120, 220), M( 56, 144, 232), M( 88, 168, 240),
+ M(128, 196, 252), M(188, 224, 252), M( 16, 64, 96), M( 24, 80, 108),
+ M( 40, 96, 120), M( 52, 112, 132), M( 80, 140, 160), M(116, 172, 192),
+ M(156, 204, 220), M(204, 240, 252), M(172, 52, 52), M(212, 52, 52),
+ M(252, 52, 52), M(252, 100, 88), M(252, 144, 124), M(252, 184, 160),
+ M(252, 216, 200), M(252, 244, 236), M( 72, 20, 112), M( 92, 44, 140),
+ M(112, 68, 168), M(140, 100, 196), M(168, 136, 224), M(204, 180, 252),
+ M(204, 180, 252), M(232, 208, 252), M( 60, 0, 0), M( 92, 0, 0),
+ M(128, 0, 0), M(160, 0, 0), M(196, 0, 0), M(224, 0, 0),
+ M(252, 0, 0), M(252, 80, 0), M(252, 108, 0), M(252, 136, 0),
+ M(252, 164, 0), M(252, 192, 0), M(252, 220, 0), M(252, 252, 0),
+ M(204, 136, 8), M(228, 144, 4), M(252, 156, 0), M(252, 176, 48),
+ M(252, 196, 100), M(252, 216, 152), M( 8, 24, 88), M( 12, 36, 104),
+ M( 20, 52, 124), M( 28, 68, 140), M( 40, 92, 164), M( 56, 120, 188),
+ M( 72, 152, 216), M(100, 172, 224), M( 92, 156, 52), M(108, 176, 64),
+ M(124, 200, 76), M(144, 224, 92), M(224, 244, 252), M(204, 240, 252),
+ M(180, 220, 236), M(132, 188, 216), M( 88, 152, 172), M( 16, 16, 16),
+ M( 32, 32, 32), M( 8, 92, 104), M( 16, 100, 112), M( 24, 108, 120),
+ M( 32, 116, 128), M( 44, 124, 140), M( 92, 164, 184), M(116, 180, 196),
+ M(148, 200, 216), M(180, 220, 232), M(216, 244, 252), M( 0, 0, 0),
+ M( 0, 0, 0), M( 0, 0, 0), M( 0, 0, 0), M( 0, 0, 0),
+ M(252, 60, 0), M(252, 80, 0), M(252, 104, 0), M(252, 128, 0),
+ M(252, 148, 0), M(252, 172, 0), M(252, 196, 0), M(252, 0, 0),
+ M(252, 0, 0), M( 0, 0, 0), M( 0, 0, 0), M( 0, 0, 0),
+ M(252, 228, 0), M(148, 148, 148), M( 16, 101, 115), M( 24, 109, 123),
+ M( 32, 117, 131), M( 41, 125, 139), M( 90, 165, 189), M(115, 182, 197),
+ M(148, 202, 222), M(180, 222, 238), M(222, 246, 255), M(252, 252, 252)
+ }
+};
+
+#define GET_PALETTE(x) _palettes[x]
+
+typedef struct {
+ Colour a[15]; // dark blue water
+ Colour ac[15]; // dark blue water Toyland
+ Colour lighthouse[12]; // lighthouse & stadium
+ Colour oil_ref[21]; // oil refinery
+ Colour e[15]; // ???
+ Colour b[45]; // glittery water
+ Colour bc[45]; // glittery water Toyland
+} ExtraPaletteValues;
+
+static const ExtraPaletteValues _extra_palette_values = {
+ { M( 32, 68, 112), M( 36, 72, 116), M( 40, 76, 120), M( 44, 80, 124),
+ M( 48, 84, 128) },
+ { M( 28, 108, 124), M( 32, 112, 128), M( 36, 116, 132), M( 40, 120, 136),
+ M( 44, 124, 140) },
+ { M(240, 208, 0), M( 0, 0, 0), M( 0, 0, 0), M( 0, 0, 0) },
+ { M(252, 60, 0), M(252, 84, 0), M(252, 108, 0), M(252, 124, 0),
+ M(252, 148, 0), M(252, 172, 0), M(252, 196, 0) },
+ { M( 76, 24, 8), M(108, 44, 24), M(144, 72, 52), M(176, 108, 84),
+ M(212, 148, 128) },
+ { M(216, 244, 252), M(172, 208, 224), M(132, 172, 196), M(100, 132, 168),
+ M( 72, 100, 144), M( 72, 100, 144), M( 72, 100, 144), M( 72, 100, 144),
+ M( 72, 100, 144), M( 72, 100, 144), M( 72, 100, 144), M( 72, 100, 144),
+ M(100, 132, 168), M(132, 172, 196), M(172, 208, 224) },
+ { M(216, 244, 252), M(180, 220, 232), M(148, 200, 216), M(116, 180, 196),
+ M( 92, 164, 184), M( 92, 164, 184), M( 92, 164, 184), M( 92, 164, 184),
+ M( 92, 164, 184), M( 92, 164, 184), M( 92, 164, 184), M( 92, 164, 184),
+ M(116, 180, 196), M(148, 200, 216), M(180, 220, 232) }
+};
+#undef M
+
+// Color table for colors in lang files (e.g. {BLACK})
+typedef struct StringColor {
+ byte text;
+ byte shadow;
+} StringColor;
+
+static const StringColor _string_colormap[] = {
+ { 150, 215 }, // BLUE
+ { 12, 215 }, // SILVER
+ { 189, 215 }, // GOLD
+ { 184, 215 }, // RED
+ { 174, 215 }, // PURPLE
+ { 30, 215 }, // LTBROWN
+ { 195, 215 }, // ORANGE
+ { 209, 215 }, // GREEN
+ { 68, 215 }, // YELLOW
+ { 95, 215 }, // DKGREEN
+ { 79, 215 }, // CREAM
+ { 116, 215 }, // BROWN
+ { 15, 215 }, // WHITE
+ { 152, 215 }, // LTBLUE
+ { 32, 215 }, // GRAY
+ { 133, 215 }, // DKBLUE
+ { 215, 0 }, // BLACK
+};
diff --git a/src/table/road_land.h b/src/table/road_land.h
new file mode 100644
index 000000000..52e013bd9
--- /dev/null
+++ b/src/table/road_land.h
@@ -0,0 +1,281 @@
+/* $Id$ */
+
+#define TILE_SEQ_LINE(img, dx, dy, sx, sy) { dx, dy, 0, sx, sy, 20, img },
+#define TILE_SEQ_END() { 0, 0, 0, 0, 0, 0, 0 }
+
+static const DrawTileSeqStruct _road_depot_NE[] = {
+ TILE_SEQ_LINE(0x584 | PALETTE_MODIFIER_COLOR, 0, 15, 16, 1)
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _road_depot_SE[] = {
+ TILE_SEQ_LINE(0x580, 0, 0, 1, 16)
+ TILE_SEQ_LINE(0x581 | PALETTE_MODIFIER_COLOR, 15, 0, 1, 16)
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _road_depot_SW[] = {
+ TILE_SEQ_LINE(0x582, 0, 0, 16, 1)
+ TILE_SEQ_LINE(0x583 | PALETTE_MODIFIER_COLOR, 0, 15, 16, 1)
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _road_depot_NW[] = {
+ TILE_SEQ_LINE(0x585 | PALETTE_MODIFIER_COLOR, 15, 0, 1, 16)
+ TILE_SEQ_END()
+};
+
+static const DrawTileSprites _road_depot[] = {
+ { 0xA4A, _road_depot_NE },
+ { 0xA4A, _road_depot_SE },
+ { 0xA4A, _road_depot_SW },
+ { 0xA4A, _road_depot_NW }
+};
+
+#undef TILE_SEQ_BEGIN
+#undef TILE_SEQ_LINE
+#undef TILE_SEQ_END
+
+
+static const SpriteID _road_tile_sprites_1[16] = {
+ 0, 0x546, 0x545, 0x53B, 0x544, 0x534, 0x53E, 0x539,
+ 0x543, 0x53C, 0x535, 0x538, 0x53D, 0x537, 0x53A, 0x536
+};
+
+
+
+#define MAKELINE(a, b, c) { a, b, c },
+#define ENDLINE { 0, 0, 0 }
+static const DrawRoadTileStruct _road_display_datas2_0[] = {
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_1[] = {
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_2[] = {
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_3[] = {
+ MAKELINE(0x57f, 1, 8)
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_4[] = {
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_5[] = {
+ MAKELINE(0x57f, 1, 8)
+ MAKELINE(0x57e, 14, 8)
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_6[] = {
+ MAKELINE(0x57e, 8, 1)
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_7[] = {
+ MAKELINE(0x57f, 1, 8)
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_8[] = {
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_9[] = {
+ MAKELINE(0x57f, 8, 14)
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_10[] = {
+ MAKELINE(0x57f, 8, 14)
+ MAKELINE(0x57e, 8, 1)
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_11[] = {
+ MAKELINE(0x57f, 8, 14)
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_12[] = {
+ MAKELINE(0x57e, 8, 1)
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_13[] = {
+ MAKELINE(0x57e, 14, 8)
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_14[] = {
+ MAKELINE(0x57e, 8, 1)
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_15[] = {
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_16[] = {
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_17[] = {
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_18[] = {
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_19[] = {
+ MAKELINE(0x1212, 0, 2)
+ MAKELINE(0x1212, 3, 9)
+ MAKELINE(0x1212, 10, 12)
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_20[] = {
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_21[] = {
+ MAKELINE(0x1212, 0, 2)
+ MAKELINE(0x1212, 0, 10)
+ MAKELINE(0x1212, 12, 2)
+ MAKELINE(0x1212, 12, 10)
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_22[] = {
+ MAKELINE(0x1212, 10, 0)
+ MAKELINE(0x1212, 3, 3)
+ MAKELINE(0x1212, 0, 10)
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_23[] = {
+ MAKELINE(0x1212, 0, 2)
+ MAKELINE(0x1212, 0, 10)
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_24[] = {
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_25[] = {
+ MAKELINE(0x1212, 12, 2)
+ MAKELINE(0x1212, 9, 9)
+ MAKELINE(0x1212, 2, 12)
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_26[] = {
+ MAKELINE(0x1212, 2, 0)
+ MAKELINE(0x1212, 10, 0)
+ MAKELINE(0x1212, 2, 12)
+ MAKELINE(0x1212, 10, 12)
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_27[] = {
+ MAKELINE(0x1212, 2, 12)
+ MAKELINE(0x1212, 10, 12)
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_28[] = {
+ MAKELINE(0x1212, 2, 0)
+ MAKELINE(0x1212, 9, 3)
+ MAKELINE(0x1212, 12, 10)
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_29[] = {
+ MAKELINE(0x1212, 12, 2)
+ MAKELINE(0x1212, 12, 10)
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_30[] = {
+ MAKELINE(0x1212, 2, 0)
+ MAKELINE(0x1212, 10, 0)
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_31[] = {
+ ENDLINE
+};
+
+static const DrawRoadTileStruct _road_display_datas2_32[] = {
+ ENDLINE
+};
+
+#undef MAKELINE
+#undef ENDLINE
+
+static const DrawRoadTileStruct* const _road_display_table_1[] = {
+ _road_display_datas2_32,_road_display_datas2_32,
+ _road_display_datas2_32,_road_display_datas2_32,
+ _road_display_datas2_32,_road_display_datas2_32,
+ _road_display_datas2_32,_road_display_datas2_32,
+ _road_display_datas2_32,_road_display_datas2_32,
+ _road_display_datas2_32,_road_display_datas2_32,
+ _road_display_datas2_32,_road_display_datas2_32,
+ _road_display_datas2_32,_road_display_datas2_32,
+};
+
+static const DrawRoadTileStruct* const _road_display_table_2[] = {
+ _road_display_datas2_0,
+ _road_display_datas2_1,
+ _road_display_datas2_2,
+ _road_display_datas2_3,
+ _road_display_datas2_4,
+ _road_display_datas2_5,
+ _road_display_datas2_6,
+ _road_display_datas2_7,
+ _road_display_datas2_8,
+ _road_display_datas2_9,
+ _road_display_datas2_10,
+ _road_display_datas2_11,
+ _road_display_datas2_12,
+ _road_display_datas2_13,
+ _road_display_datas2_14,
+ _road_display_datas2_15,
+};
+
+static const DrawRoadTileStruct* const _road_display_table_3[] = {
+ _road_display_datas2_16,
+ _road_display_datas2_17,
+ _road_display_datas2_18,
+ _road_display_datas2_19,
+ _road_display_datas2_20,
+ _road_display_datas2_21,
+ _road_display_datas2_22,
+ _road_display_datas2_23,
+
+ _road_display_datas2_24,
+ _road_display_datas2_25,
+ _road_display_datas2_26,
+ _road_display_datas2_27,
+ _road_display_datas2_28,
+ _road_display_datas2_29,
+ _road_display_datas2_30,
+ _road_display_datas2_31,
+};
+
+static const DrawRoadTileStruct* const * const _road_display_table[] = {
+ _road_display_table_1,
+ _road_display_table_1,
+ _road_display_table_1,
+ _road_display_table_2,
+ _road_display_table_1,
+ _road_display_table_3,
+};
diff --git a/src/table/roadveh.h b/src/table/roadveh.h
new file mode 100644
index 000000000..fa8f18e1f
--- /dev/null
+++ b/src/table/roadveh.h
@@ -0,0 +1,1077 @@
+/* $Id$ */
+
+static const RoadDriveEntry _roadveh_drive_data_0[] = {
+ {15, 5},
+ {14, 5},
+ {13, 5},
+ {12, 5},
+ {11, 5},
+ {10, 5},
+ { 9, 5},
+ { 8, 5},
+ { 7, 5},
+ { 6, 5},
+ { 5, 5},
+ { 4, 5},
+ { 3, 5},
+ { 2, 5},
+ { 1, 5},
+ { 0, 5},
+ {0x80, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_1[] = {
+ {5, 0},
+ {5, 1},
+ {5, 2},
+ {5, 3},
+ {5, 4},
+ {5, 5},
+ {5, 6},
+ {5, 7},
+ {5, 8},
+ {5, 9},
+ {5, 10},
+ {5, 11},
+ {5, 12},
+ {5, 13},
+ {5, 14},
+ {5, 15},
+ {0x81, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_2[] = {
+ {5, 0},
+ {5, 1},
+ {5, 2},
+ {4, 3},
+ {3, 4},
+ {2, 5},
+ {1, 5},
+ {0, 5},
+ {0x80, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_3[] = {
+ {15, 5},
+ {14, 5},
+ {13, 5},
+ {12, 5},
+ {11, 5},
+ {10, 5},
+ { 9, 6},
+ { 8, 7},
+ { 7, 8},
+ { 6, 9},
+ { 5, 10},
+ { 5, 11},
+ { 5, 12},
+ { 5, 13},
+ { 5, 14},
+ { 5, 15},
+ {0x81, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_4[] = {
+ { 5, 0},
+ { 5, 1},
+ { 5, 2},
+ { 5, 3},
+ { 5, 4},
+ { 5, 5},
+ { 6, 6},
+ { 7, 7},
+ { 8, 8},
+ { 9, 9},
+ {10, 9},
+ {11, 9},
+ {12, 9},
+ {13, 9},
+ {14, 9},
+ {15, 9},
+ {0x82, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_5[] = {
+ {0, 9},
+ {1, 9},
+ {2, 9},
+ {3, 10},
+ {4, 11},
+ {5, 12},
+ {5, 13},
+ {5, 14},
+ {5, 15},
+ {0x81, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_6[] = {
+ {0, 6},
+ {0, 7},
+ {0, 8},
+ {0, 9},
+ {0x42, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_7[] = {
+ {6, 15},
+ {7, 15},
+ {8, 15},
+ {9, 15},
+ {0x43, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_8[] = {
+ { 0, 9},
+ { 1, 9},
+ { 2, 9},
+ { 3, 9},
+ { 4, 9},
+ { 5, 9},
+ { 6, 9},
+ { 7, 9},
+ { 8, 9},
+ { 9, 9},
+ {10, 9},
+ {11, 9},
+ {12, 9},
+ {13, 9},
+ {14, 9},
+ {15, 9},
+ {0x82, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_9[] = {
+ {9, 15},
+ {9, 14},
+ {9, 13},
+ {9, 12},
+ {9, 11},
+ {9, 10},
+ {9, 9},
+ {9, 8},
+ {9, 7},
+ {9, 6},
+ {9, 5},
+ {9, 4},
+ {9, 3},
+ {9, 2},
+ {9, 1},
+ {9, 0},
+ {0x83, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_10[] = {
+ {0, 9},
+ {1, 9},
+ {2, 9},
+ {3, 9},
+ {4, 9},
+ {5, 9},
+ {6, 8},
+ {7, 7},
+ {8, 6},
+ {9, 5},
+ {9, 4},
+ {9, 3},
+ {9, 2},
+ {9, 1},
+ {9, 0},
+ {0x83, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_11[] = {
+ { 9, 15},
+ { 9, 14},
+ { 9, 13},
+ {10, 12},
+ {11, 11},
+ {12, 10},
+ {13, 9},
+ {14, 9},
+ {15, 9},
+ {0x82, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_12[] = {
+ {15, 5},
+ {14, 5},
+ {13, 5},
+ {12, 4},
+ {11, 3},
+ {10, 2},
+ { 9, 1},
+ { 9, 0},
+ {0x83, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_13[] = {
+ {9, 15},
+ {9, 14},
+ {9, 13},
+ {9, 12},
+ {9, 11},
+ {9, 10},
+ {8, 9},
+ {7, 8},
+ {6, 7},
+ {5, 6},
+ {4, 5},
+ {3, 5},
+ {2, 5},
+ {1, 5},
+ {0, 5},
+ {0x80, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_14[] = {
+ {15, 8},
+ {15, 7},
+ {15, 6},
+ {15, 5},
+ {0x40, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_15[] = {
+ {8, 0},
+ {7, 0},
+ {6, 0},
+ {5, 0},
+ {0x41, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_16[] = {
+ {15, 9},
+ {14, 9},
+ {13, 9},
+ {12, 9},
+ {11, 9},
+ {10, 9},
+ { 9, 9},
+ { 8, 9},
+ { 7, 9},
+ { 6, 9},
+ { 5, 9},
+ { 4, 9},
+ { 3, 9},
+ { 2, 9},
+ { 1, 9},
+ { 0, 9},
+ {0x80, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_17[] = {
+ {9, 0},
+ {9, 1},
+ {9, 2},
+ {9, 3},
+ {9, 4},
+ {9, 5},
+ {9, 6},
+ {9, 7},
+ {9, 8},
+ {9, 9},
+ {9, 10},
+ {9, 11},
+ {9, 12},
+ {9, 13},
+ {9, 14},
+ {9, 15},
+ {0x81, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_18[] = {
+ {9, 0},
+ {9, 1},
+ {9, 2},
+ {9, 3},
+ {9, 4},
+ {9, 5},
+ {8, 6},
+ {7, 7},
+ {6, 8},
+ {5, 9},
+ {4, 9},
+ {3, 9},
+ {2, 9},
+ {1, 9},
+ {0, 9},
+ {0x80, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_19[] = {
+ {15, 9},
+ {14, 9},
+ {13, 9},
+ {12, 10},
+ {11, 11},
+ {10, 12},
+ { 9, 13},
+ { 9, 14},
+ { 9, 15},
+ {0x81, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_20[] = {
+ { 9, 0},
+ { 9, 1},
+ {10, 2},
+ {11, 3},
+ {12, 4},
+ {13, 5},
+ {14, 5},
+ {15, 5},
+ {0x82, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_21[] = {
+ {0, 5},
+ {1, 5},
+ {2, 5},
+ {3, 5},
+ {4, 5},
+ {5, 6},
+ {6, 7},
+ {7, 8},
+ {8, 9},
+ {9, 10},
+ {9, 11},
+ {9, 12},
+ {9, 13},
+ {9, 14},
+ {9, 15},
+ {0x81, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_22[] = {
+ {0, 8},
+ {0, 7},
+ {0, 6},
+ {0, 5},
+ {0x42, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_23[] = {
+ {8, 15},
+ {7, 15},
+ {6, 15},
+ {5, 15},
+ {0x43, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_24[] = {
+ { 0, 5},
+ { 1, 5},
+ { 2, 5},
+ { 3, 5},
+ { 4, 5},
+ { 5, 5},
+ { 6, 5},
+ { 7, 5},
+ { 8, 5},
+ { 9, 5},
+ {10, 5},
+ {11, 5},
+ {12, 5},
+ {13, 5},
+ {14, 5},
+ {15, 5},
+ {0x82, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_25[] = {
+ {5, 15},
+ {5, 14},
+ {5, 13},
+ {5, 12},
+ {5, 11},
+ {5, 10},
+ {5, 9},
+ {5, 8},
+ {5, 7},
+ {5, 6},
+ {5, 5},
+ {5, 4},
+ {5, 3},
+ {5, 2},
+ {5, 1},
+ {5, 0},
+ {0x83, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_26[] = {
+ {0, 5},
+ {1, 5},
+ {2, 5},
+ {3, 4},
+ {4, 3},
+ {5, 2},
+ {5, 1},
+ {5, 0},
+ {0x83, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_27[] = {
+ { 5, 15},
+ { 5, 14},
+ { 5, 13},
+ { 5, 12},
+ { 5, 11},
+ { 5, 10},
+ { 6, 9},
+ { 7, 8},
+ { 8, 7},
+ { 9, 6},
+ {10, 5},
+ {11, 5},
+ {12, 5},
+ {13, 5},
+ {14, 5},
+ {15, 5},
+ {0x82, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_28[] = {
+ {15, 9},
+ {14, 9},
+ {13, 9},
+ {12, 9},
+ {11, 9},
+ {10, 9},
+ { 9, 9},
+ { 8, 8},
+ { 7, 7},
+ { 6, 6},
+ { 5, 5},
+ { 5, 4},
+ { 5, 3},
+ { 5, 2},
+ { 5, 1},
+ { 5, 0},
+ {0x83, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_29[] = {
+ {5, 15},
+ {5, 14},
+ {5, 13},
+ {5, 12},
+ {4, 11},
+ {3, 10},
+ {2, 9},
+ {1, 9},
+ {0, 9},
+ {0x80, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_30[] = {
+ {15, 6},
+ {15, 7},
+ {15, 8},
+ {15, 9},
+ {0x40, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_31[] = {
+ {6, 0},
+ {7, 0},
+ {8, 0},
+ {9, 0},
+ {0x41, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_32[] = {
+ {15, 5},
+ {14, 5},
+ {13, 6},
+ {13, 7},
+ {13, 8},
+ {13, 9},
+ {13, 10},
+ {13, 11},
+ {12, 12},
+ {11, 12},
+ {10, 12},
+ { 9, 12},
+ { 8, 12},
+ { 7, 12},
+ { 6, 12},
+ { 5, 11},
+ { 5, 10},
+ { 5, 9},
+ { 5, 8},
+ { 5, 7},
+ { 5, 6},
+ { 5, 7},
+ { 5, 8},
+ { 5, 9},
+ { 5, 10},
+ { 5, 11},
+ { 6, 12},
+ { 7, 12},
+ { 8, 12},
+ { 9, 12},
+ {10, 12},
+ {11, 12},
+ {12, 12},
+ {13, 11},
+ {13, 10},
+ {14, 9},
+ {15, 9},
+ {0x82, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_33[] = {
+ { 5, 0},
+ { 5, 1},
+ { 6, 2},
+ { 7, 2},
+ { 8, 2},
+ { 9, 2},
+ {10, 2},
+ {11, 2},
+ {12, 3},
+ {12, 4},
+ {12, 5},
+ {12, 6},
+ {12, 7},
+ {12, 8},
+ {12, 9},
+ {11, 10},
+ {10, 10},
+ { 9, 10},
+ { 8, 10},
+ { 7, 10},
+ { 6, 10},
+ { 7, 10},
+ { 8, 10},
+ { 9, 10},
+ {10, 10},
+ {11, 10},
+ {12, 9},
+ {12, 8},
+ {12, 7},
+ {12, 6},
+ {12, 5},
+ {12, 4},
+ {12, 3},
+ {11, 2},
+ {10, 2},
+ { 9, 1},
+ { 9, 0},
+ {0x83, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_34[] = {
+ {15, 5},
+ {14, 5},
+ {13, 6},
+ {13, 7},
+ {13, 8},
+ {13, 9},
+ {13, 10},
+ {13, 11},
+ {12, 12},
+ {11, 12},
+ {10, 12},
+ { 9, 11},
+ { 9, 10},
+ { 9, 9},
+ { 9, 8},
+ { 9, 7},
+ { 9, 6},
+ { 9, 7},
+ { 9, 8},
+ { 9, 9},
+ { 9, 10},
+ { 9, 11},
+ {10, 12},
+ {11, 12},
+ {12, 12},
+ {13, 11},
+ {13, 10},
+ {14, 9},
+ {15, 9},
+ {0x82, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_35[] = {
+ { 5, 0},
+ { 5, 1},
+ { 6, 2},
+ { 7, 2},
+ { 8, 2},
+ { 9, 2},
+ {10, 2},
+ {11, 2},
+ {12, 3},
+ {12, 4},
+ {12, 5},
+ {11, 6},
+ {10, 6},
+ { 9, 6},
+ { 8, 6},
+ { 7, 6},
+ { 6, 6},
+ { 7, 6},
+ { 8, 6},
+ { 9, 6},
+ {10, 6},
+ {11, 6},
+ {12, 5},
+ {12, 4},
+ {12, 3},
+ {11, 2},
+ {10, 2},
+ { 9, 1},
+ { 9, 0},
+ {0x83, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_40[] = {
+ { 0, 9},
+ { 1, 9},
+ { 2, 8},
+ { 2, 7},
+ { 2, 6},
+ { 2, 5},
+ { 2, 4},
+ { 3, 3},
+ { 4, 3},
+ { 5, 3},
+ { 6, 3},
+ { 7, 3},
+ { 8, 3},
+ { 9, 3},
+ {10, 4},
+ {10, 5},
+ {10, 6},
+ {10, 7},
+ {10, 8},
+ {10, 9},
+ {10, 8},
+ {10, 7},
+ {10, 6},
+ {10, 5},
+ {10, 4},
+ { 9, 3},
+ { 8, 3},
+ { 7, 3},
+ { 6, 3},
+ { 5, 3},
+ { 4, 3},
+ { 3, 3},
+ { 2, 4},
+ { 1, 5},
+ { 0, 5},
+ {0x80, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_41[] = {
+ {9, 15},
+ {9, 14},
+ {8, 13},
+ {7, 13},
+ {6, 13},
+ {5, 13},
+ {4, 13},
+ {3, 12},
+ {3, 11},
+ {3, 10},
+ {3, 9},
+ {3, 8},
+ {3, 7},
+ {3, 6},
+ {4, 5},
+ {5, 5},
+ {6, 5},
+ {7, 5},
+ {8, 5},
+ {9, 5},
+ {8, 5},
+ {7, 5},
+ {6, 5},
+ {5, 5},
+ {4, 5},
+ {3, 6},
+ {3, 7},
+ {3, 8},
+ {3, 9},
+ {3, 10},
+ {3, 11},
+ {3, 12},
+ {4, 13},
+ {5, 14},
+ {5, 15},
+ {0x81, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_42[] = {
+ {0, 9},
+ {1, 9},
+ {2, 8},
+ {2, 7},
+ {2, 6},
+ {2, 5},
+ {2, 4},
+ {3, 3},
+ {4, 3},
+ {5, 3},
+ {6, 4},
+ {6, 5},
+ {6, 6},
+ {6, 7},
+ {6, 8},
+ {6, 9},
+ {6, 8},
+ {6, 7},
+ {6, 6},
+ {6, 5},
+ {6, 4},
+ {5, 3},
+ {4, 3},
+ {3, 3},
+ {2, 4},
+ {1, 5},
+ {0, 5},
+ {0x80, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_43[] = {
+ {9, 15},
+ {9, 14},
+ {8, 13},
+ {7, 13},
+ {6, 13},
+ {5, 13},
+ {4, 13},
+ {3, 12},
+ {3, 11},
+ {3, 10},
+ {4, 9},
+ {5, 9},
+ {6, 9},
+ {7, 9},
+ {8, 9},
+ {9, 9},
+ {8, 9},
+ {7, 9},
+ {6, 9},
+ {5, 9},
+ {4, 9},
+ {3, 10},
+ {3, 11},
+ {3, 12},
+ {4, 13},
+ {5, 14},
+ {5, 15},
+ {0x81, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_48[] = {
+ {15, 9},
+ {14, 9},
+ {13, 10},
+ {13, 11},
+ {12, 12},
+ {11, 12},
+ {10, 12},
+ { 9, 12},
+ { 8, 12},
+ { 7, 12},
+ { 6, 12},
+ { 5, 11},
+ { 5, 10},
+ { 5, 9},
+ { 5, 8},
+ { 5, 7},
+ { 5, 6},
+ { 5, 7},
+ { 5, 8},
+ { 5, 9},
+ { 5, 10},
+ { 5, 11},
+ { 6, 12},
+ { 7, 12},
+ { 8, 12},
+ { 9, 12},
+ {10, 12},
+ {11, 12},
+ {12, 12},
+ {13, 11},
+ {13, 10},
+ {13, 9},
+ {13, 8},
+ {13, 7},
+ {13, 6},
+ {14, 5},
+ {15, 5},
+ {0x82, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_49[] = {
+ { 9, 0},
+ { 9, 1},
+ {10, 2},
+ {11, 2},
+ {12, 3},
+ {12, 4},
+ {12, 5},
+ {12, 6},
+ {12, 7},
+ {12, 8},
+ {12, 9},
+ {11, 10},
+ {10, 10},
+ { 9, 10},
+ { 8, 10},
+ { 7, 10},
+ { 6, 10},
+ { 7, 10},
+ { 8, 10},
+ { 9, 10},
+ {10, 10},
+ {11, 10},
+ {12, 9},
+ {12, 8},
+ {12, 7},
+ {12, 6},
+ {12, 5},
+ {12, 4},
+ {12, 3},
+ {11, 2},
+ {10, 2},
+ { 9, 2},
+ { 8, 2},
+ { 7, 2},
+ { 6, 2},
+ { 5, 1},
+ { 5, 0},
+ {0x83, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_50[] = {
+ {15, 9},
+ {14, 9},
+ {13, 10},
+ {13, 11},
+ {12, 12},
+ {11, 12},
+ {10, 12},
+ { 9, 11},
+ { 9, 10},
+ { 9, 9},
+ { 9, 8},
+ { 9, 7},
+ { 9, 6},
+ { 9, 7},
+ { 9, 8},
+ { 9, 9},
+ { 9, 10},
+ { 9, 11},
+ {10, 12},
+ {11, 12},
+ {12, 12},
+ {13, 11},
+ {13, 10},
+ {13, 9},
+ {13, 8},
+ {13, 7},
+ {13, 6},
+ {14, 5},
+ {15, 5},
+ {0x82, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_51[] = {
+ { 9, 0},
+ { 9, 1},
+ {10, 2},
+ {11, 2},
+ {12, 3},
+ {12, 4},
+ {12, 5},
+ {11, 6},
+ {10, 6},
+ { 9, 6},
+ { 8, 6},
+ { 7, 6},
+ { 6, 6},
+ { 7, 6},
+ { 8, 6},
+ { 9, 6},
+ {10, 6},
+ {11, 6},
+ {12, 5},
+ {12, 4},
+ {12, 3},
+ {11, 2},
+ {10, 2},
+ { 9, 2},
+ { 8, 2},
+ { 7, 2},
+ { 6, 2},
+ { 5, 1},
+ { 5, 0},
+ {0x83, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_56[] = {
+ { 0, 5},
+ { 1, 5},
+ { 2, 4},
+ { 3, 3},
+ { 4, 3},
+ { 5, 3},
+ { 6, 3},
+ { 7, 3},
+ { 8, 3},
+ { 9, 3},
+ {10, 4},
+ {10, 5},
+ {10, 6},
+ {10, 7},
+ {10, 8},
+ {10, 9},
+ {10, 8},
+ {10, 7},
+ {10, 6},
+ {10, 5},
+ {10, 4},
+ { 9, 3},
+ { 8, 3},
+ { 7, 3},
+ { 6, 3},
+ { 5, 3},
+ { 4, 3},
+ { 3, 3},
+ { 2, 4},
+ { 2, 5},
+ { 2, 6},
+ { 2, 7},
+ { 2, 8},
+ { 1, 9},
+ { 0, 9},
+ {0x80, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_57[] = {
+ {5, 15},
+ {5, 14},
+ {4, 13},
+ {3, 12},
+ {3, 11},
+ {3, 10},
+ {3, 9},
+ {3, 8},
+ {3, 7},
+ {3, 6},
+ {4, 5},
+ {5, 5},
+ {6, 5},
+ {7, 5},
+ {8, 5},
+ {9, 5},
+ {8, 5},
+ {7, 5},
+ {6, 5},
+ {5, 5},
+ {4, 5},
+ {3, 6},
+ {3, 7},
+ {3, 8},
+ {3, 9},
+ {3, 10},
+ {3, 11},
+ {3, 12},
+ {4, 13},
+ {5, 13},
+ {6, 13},
+ {7, 13},
+ {8, 13},
+ {9, 14},
+ {9, 15},
+ {0x81, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_58[] = {
+ {0, 5},
+ {1, 5},
+ {2, 4},
+ {3, 3},
+ {4, 3},
+ {5, 3},
+ {6, 4},
+ {6, 5},
+ {6, 6},
+ {6, 7},
+ {6, 8},
+ {6, 9},
+ {6, 8},
+ {6, 7},
+ {6, 6},
+ {6, 5},
+ {6, 4},
+ {5, 3},
+ {4, 3},
+ {3, 3},
+ {2, 4},
+ {2, 5},
+ {2, 6},
+ {2, 7},
+ {2, 8},
+ {1, 9},
+ {0, 9},
+ {0x80, 0}
+};
+static const RoadDriveEntry _roadveh_drive_data_59[] = {
+ {5, 15},
+ {5, 14},
+ {4, 13},
+ {3, 12},
+ {3, 11},
+ {3, 10},
+ {4, 9},
+ {5, 9},
+ {6, 9},
+ {7, 9},
+ {8, 9},
+ {9, 9},
+ {8, 9},
+ {7, 9},
+ {6, 9},
+ {5, 9},
+ {4, 9},
+ {3, 10},
+ {3, 11},
+ {3, 12},
+ {4, 13},
+ {5, 13},
+ {6, 13},
+ {7, 13},
+ {8, 13},
+ {9, 14},
+ {9, 15},
+ {0x81, 0}
+};
+
+static const RoadDriveEntry * const _road_drive_data[] = {
+ _roadveh_drive_data_0,
+ _roadveh_drive_data_1,
+ _roadveh_drive_data_2,
+ _roadveh_drive_data_3,
+ _roadveh_drive_data_4,
+ _roadveh_drive_data_5,
+ _roadveh_drive_data_6,
+ _roadveh_drive_data_7,
+ _roadveh_drive_data_8,
+ _roadveh_drive_data_9,
+ _roadveh_drive_data_10,
+ _roadveh_drive_data_11,
+ _roadveh_drive_data_12,
+ _roadveh_drive_data_13,
+ _roadveh_drive_data_14,
+ _roadveh_drive_data_15,
+ _roadveh_drive_data_16,
+ _roadveh_drive_data_17,
+ _roadveh_drive_data_18,
+ _roadveh_drive_data_19,
+ _roadveh_drive_data_20,
+ _roadveh_drive_data_21,
+ _roadveh_drive_data_22,
+ _roadveh_drive_data_23,
+ _roadveh_drive_data_24,
+ _roadveh_drive_data_25,
+ _roadveh_drive_data_26,
+ _roadveh_drive_data_27,
+ _roadveh_drive_data_28,
+ _roadveh_drive_data_29,
+ _roadveh_drive_data_30,
+ _roadveh_drive_data_31,
+ _roadveh_drive_data_32,
+ _roadveh_drive_data_33,
+ _roadveh_drive_data_34,
+ _roadveh_drive_data_35,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _roadveh_drive_data_40,
+ _roadveh_drive_data_41,
+ _roadveh_drive_data_42,
+ _roadveh_drive_data_43,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _roadveh_drive_data_48,
+ _roadveh_drive_data_49,
+ _roadveh_drive_data_50,
+ _roadveh_drive_data_51,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _roadveh_drive_data_56,
+ _roadveh_drive_data_57,
+ _roadveh_drive_data_58,
+ _roadveh_drive_data_59,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+};
diff --git a/src/table/sprites.h b/src/table/sprites.h
new file mode 100644
index 000000000..071c5ddfb
--- /dev/null
+++ b/src/table/sprites.h
@@ -0,0 +1,1397 @@
+/* $Id$ */
+
+#ifndef SPRITES_H
+#define SPRITES_H
+
+/** @file sprites.h
+ * This file contails all sprite-related enums and defines. These consist mainly of
+ * the sprite numbers and a bunch of masks and macros to handle sprites and to get
+ * rid of all the magic numbers in the code.
+ *
+ * @NOTE:
+ * ALL SPRITE NUMBERS BELOW 5126 are in the main files
+ * SPR_CANALS_BASE is in canalsw.grf
+ * SPR_SLOPES_BASE is in trkfoundw.grf
+ * SPR_OPENTTD_BASE is in openttd.grf
+ *
+ * All elements which consist of two elements should
+ * have the same name and then suffixes
+ * _GROUND and _BUILD for building-type sprites
+ * _REAR and _FRONT for transport-type sprites (tiles where vehicles are on)
+ * These sprites are split because of the Z order of the elements
+ * (like some parts of a bridge are behind the vehicle, while others are before)
+ *
+ *
+ * All sprites which are described here are referenced only one to a handful of times
+ * throughout the code. When introducing new sprite enums, use meaningful names.
+ * Don't be lazy and typing, and only use abbrevations when their meaning is clear or
+ * the length of the enum would get out of hand. In that case EXPLAIN THE ABBREVATION
+ * IN THIS FILE, and perhaps add some comments in the code where it is used.
+ * Now, don't whine about this being too much typing work if the enums are like
+ * 30 characters in length. If your editor doen't help you simplifying your work,
+ * get a proper editor. If your Operating Systems don't have any decent editors,
+ * get a proper Operating System.
+ *
+ * @todo Split the "Sprites" enum into smaller chunks and document them
+ */
+
+
+enum Sprites {
+ SPR_SELECT_TILE = 752,
+ SPR_DOT = 774, // corner marker for lower/raise land
+ SPR_DOT_SMALL = 4078,
+ SPR_WHITE_POINT = 4079,
+
+ /* ASCII */
+ SPR_ASCII_SPACE = 2,
+ SPR_ASCII_SPACE_SMALL = 226,
+ SPR_ASCII_SPACE_BIG = 450,
+
+ /* Extra graphic spritenumbers */
+ OPENTTD_SPRITES_COUNT = 116, // number of gfx-sprites in openttd.grf
+ SPR_SIGNALS_BASE = 4896,
+ SPR_CANALS_BASE = SPR_SIGNALS_BASE + 486,
+ SPR_SLOPES_BASE = SPR_CANALS_BASE + 70,
+ SPR_AUTORAIL_BASE = SPR_SLOPES_BASE + 78,
+ SPR_ELRAIL_BASE = SPR_AUTORAIL_BASE + 55,
+ SPR_2CCMAP_BASE = SPR_ELRAIL_BASE + 53,
+ SPR_OPENTTD_BASE = SPR_2CCMAP_BASE + 256,
+
+ SPR_BLOT = SPR_OPENTTD_BASE + 29, // colored circle (mainly used as vehicle profit marker and for sever compatibility)
+
+ SPR_PIN_UP = SPR_OPENTTD_BASE + 55, // pin icon
+ SPR_PIN_DOWN = SPR_OPENTTD_BASE + 56,
+ SPR_BOX_EMPTY = SPR_OPENTTD_BASE + 59,
+ SPR_BOX_CHECKED = SPR_OPENTTD_BASE + 60,
+ SPR_WINDOW_RESIZE = SPR_OPENTTD_BASE + 87, // resize icon
+ SPR_HOUSE_ICON = SPR_OPENTTD_BASE + 94,
+ // arrow icons pointing in all 4 directions
+ SPR_ARROW_DOWN = SPR_OPENTTD_BASE + 88,
+ SPR_ARROW_UP = SPR_OPENTTD_BASE + 89,
+ SPR_ARROW_LEFT = SPR_OPENTTD_BASE + 90,
+ SPR_ARROW_RIGHT = SPR_OPENTTD_BASE + 91,
+
+ SPR_LARGE_SMALL_WINDOW = 682,
+
+ /* Clone vehicles stuff */
+ SPR_CLONE_TRAIN = SPR_OPENTTD_BASE + 92,
+ SPR_CLONE_ROADVEH = SPR_OPENTTD_BASE + 109,
+ SPR_CLONE_SHIP = SPR_OPENTTD_BASE + 111,
+ SPR_CLONE_AIRCRAFT = SPR_OPENTTD_BASE + 113,
+
+ SPR_SELL_TRAIN = SPR_OPENTTD_BASE + 96,
+ SPR_SELL_ROADVEH = SPR_OPENTTD_BASE + 97,
+ SPR_SELL_SHIP = SPR_OPENTTD_BASE + 98,
+ SPR_SELL_AIRCRAFT = SPR_OPENTTD_BASE + 99,
+ SPR_SELL_ALL_TRAIN = SPR_OPENTTD_BASE + 100,
+ SPR_SELL_ALL_ROADVEH = SPR_OPENTTD_BASE + 101,
+ SPR_SELL_ALL_SHIP = SPR_OPENTTD_BASE + 102,
+ SPR_SELL_ALL_AIRCRAFT = SPR_OPENTTD_BASE + 103,
+ SPR_REPLACE_TRAIN = SPR_OPENTTD_BASE + 104,
+ SPR_REPLACE_ROADVEH = SPR_OPENTTD_BASE + 105,
+ SPR_REPLACE_SHIP = SPR_OPENTTD_BASE + 106,
+ SPR_REPLACE_AIRCRAFT = SPR_OPENTTD_BASE + 107,
+ SPR_SELL_CHAIN_TRAIN = SPR_OPENTTD_BASE + 108,
+
+ SPR_SHARED_ORDERS_ICON = SPR_OPENTTD_BASE + 115,
+
+ /* Network GUI sprites */
+ SPR_SQUARE = SPR_OPENTTD_BASE + 20, // colored square (used for newgrf compatibility)
+ SPR_LOCK = SPR_OPENTTD_BASE + 19, // lock icon (for password protected servers)
+ SPR_FLAGS_BASE = SPR_OPENTTD_BASE + 83, // start of the flags block (in same order as enum NetworkLanguage)
+
+ SPR_AIRPORTX_BASE = SPR_OPENTTD_BASE + OPENTTD_SPRITES_COUNT, // The sprites used for other airport angles
+ SPR_NEWAIRPORT_TARMAC = SPR_AIRPORTX_BASE,
+ SPR_NSRUNWAY1 = SPR_AIRPORTX_BASE + 1,
+ SPR_NSRUNWAY2 = SPR_AIRPORTX_BASE + 2,
+ SPR_NSRUNWAY3 = SPR_AIRPORTX_BASE + 3,
+ SPR_NSRUNWAY4 = SPR_AIRPORTX_BASE + 4,
+ SPR_NSRUNWAY_END = SPR_AIRPORTX_BASE + 5,
+ SPR_NEWHANGAR_S = SPR_AIRPORTX_BASE + 6,
+ SPR_NEWHANGAR_S_WALL = SPR_AIRPORTX_BASE + 7,
+ SPR_NEWHANGAR_W = SPR_AIRPORTX_BASE + 8,
+ SPR_NEWHANGAR_W_WALL = SPR_AIRPORTX_BASE + 9,
+ SPR_NEWHANGAR_N = SPR_AIRPORTX_BASE + 10,
+ SPR_NEWHANGAR_E = SPR_AIRPORTX_BASE + 11,
+ SPR_NEWHELIPAD = SPR_AIRPORTX_BASE + 12,
+ SPR_GRASS_RIGHT = SPR_AIRPORTX_BASE + 13,
+ SPR_GRASS_LEFT = SPR_AIRPORTX_BASE + 14,
+
+ /* Manager face sprites */
+ SPR_GRADIENT = 874, // background gradient behind manager face
+
+ /* is itself no foundation sprite, because tileh 0 has no foundation */
+ SPR_FOUNDATION_BASE = 989,
+
+ /* Shadow cell */
+ SPR_SHADOW_CELL = 1004,
+
+ /* Sliced view shadow cells */
+ /* Maybe we have different ones in the future */
+ SPR_MAX_SLICE = SPR_OPENTTD_BASE + 64,
+ SPR_MIN_SLICE = SPR_OPENTTD_BASE + 64,
+
+ /* Unmovables spritenumbers */
+ SPR_UNMOVABLE_TRANSMITTER = 2601,
+ SPR_UNMOVABLE_LIGHTHOUSE = 2602,
+ SPR_TINYHQ_NORTH = 2603,
+ SPR_TINYHQ_EAST = 2604,
+ SPR_TINYHQ_WEST = 2605,
+ SPR_TINYHQ_SOUTH = 2606,
+ SPR_SMALLHQ_NORTH = 2607,
+ SPR_SMALLHQ_EAST = 2608,
+ SPR_SMALLHQ_WEST = 2609,
+ SPR_SMALLHQ_SOUTH = 2610,
+ SPR_MEDIUMHQ_NORTH = 2611,
+ SPR_MEDIUMHQ_NORTH_WALL = 2612,
+ SPR_MEDIUMHQ_EAST = 2613,
+ SPR_MEDIUMHQ_EAST_WALL = 2614,
+ SPR_MEDIUMHQ_WEST = 2615,
+ SPR_MEDIUMHQ_WEST_WALL = 2616, //very tiny piece of wall
+ SPR_MEDIUMHQ_SOUTH = 2617,
+ SPR_LARGEHQ_NORTH_GROUND = 2618,
+ SPR_LARGEHQ_NORTH_BUILD = 2619,
+ SPR_LARGEHQ_EAST_GROUND = 2620,
+ SPR_LARGEHQ_EAST_BUILD = 2621,
+ SPR_LARGEHQ_WEST_GROUND = 2622,
+ SPR_LARGEHQ_WEST_BUILD = 2623,
+ SPR_LARGEHQ_SOUTH = 2624,
+ SPR_HUGEHQ_NORTH_GROUND = 2625,
+ SPR_HUGEHQ_NORTH_BUILD = 2626,
+ SPR_HUGEHQ_EAST_GROUND = 2627,
+ SPR_HUGEHQ_EAST_BUILD = 2628,
+ SPR_HUGEHQ_WEST_GROUND = 2629,
+ SPR_HUGEHQ_WEST_BUILD = 2630,
+ SPR_HUGEHQ_SOUTH = 2631,
+ SPR_CONCRETE_GROUND = 1420,
+ SPR_STATUE_COMPANY = 2632,
+ SPR_BOUGHT_LAND = 4790,
+
+ /* sprites for rail and rail stations*/
+ SPR_RAIL_SNOW_OFFSET = 26,
+ SPR_MONO_SNOW_OFFSET = 26,
+ SPR_MGLV_SNOW_OFFSET = 26,
+
+ SPR_RAIL_SINGLE_Y = 1005,
+ SPR_RAIL_SINGLE_X = 1006,
+ SPR_RAIL_SINGLE_NORTH = 1007,
+ SPR_RAIL_SINGLE_SOUTH = 1008,
+ SPR_RAIL_SINGLE_EAST = 1009,
+ SPR_RAIL_SINGLE_WEST = 1010,
+ SPR_RAIL_TRACK_Y = 1011,
+ SPR_RAIL_TRACK_X = 1012,
+ SPR_RAIL_TRACK_BASE = 1018,
+ SPR_RAIL_TRACK_N_S = 1035,
+ SPR_RAIL_TRACK_Y_SNOW = 1037,
+ SPR_RAIL_TRACK_X_SNOW = 1038,
+ SPR_RAIL_DEPOT_SE_1 = 1063,
+ SPR_RAIL_DEPOT_SE_2 = 1064,
+ SPR_RAIL_DEPOT_SW_1 = 1065,
+ SPR_RAIL_DEPOT_SW_2 = 1066,
+ SPR_RAIL_DEPOT_NE = 1067,
+ SPR_RAIL_DEPOT_NW = 1068,
+ SPR_RAIL_PLATFORM_Y_FRONT = 1069,
+ SPR_RAIL_PLATFORM_X_REAR = 1070,
+ SPR_RAIL_PLATFORM_Y_REAR = 1071,
+ SPR_RAIL_PLATFORM_X_FRONT = 1072,
+ SPR_RAIL_PLATFORM_BUILDING_X = 1073,
+ SPR_RAIL_PLATFORM_BUILDING_Y = 1074,
+ SPR_RAIL_PLATFORM_PILLARS_Y_FRONT = 1075,
+ SPR_RAIL_PLATFORM_PILLARS_X_REAR = 1076,
+ SPR_RAIL_PLATFORM_PILLARS_Y_REAR = 1077,
+ SPR_RAIL_PLATFORM_PILLARS_X_FRONT = 1078,
+ SPR_RAIL_ROOF_STRUCTURE_X_TILE_A = 1079, //First half of the roof structure
+ SPR_RAIL_ROOF_STRUCTURE_Y_TILE_A = 1080,
+ SPR_RAIL_ROOF_STRUCTURE_X_TILE_B = 1081, //Second half of the roof structure
+ SPR_RAIL_ROOF_STRUCTURE_Y_TILE_B = 1082,
+ SPR_RAIL_ROOF_GLASS_X_TILE_A = 1083, //First half of the roof glass
+ SPR_RAIL_ROOF_GLASS_Y_TILE_A = 1084,
+ SPR_RAIL_ROOF_GLASS_X_TILE_B = 1085, //second half of the roof glass
+ SPR_RAIL_ROOF_GLASS_Y_TILE_B = 1086,
+ SPR_MONO_SINGLE_Y = 1087,
+ SPR_MONO_SINGLE_X = 1088,
+ SPR_MONO_SINGLE_NORTH = 1089,
+ SPR_MONO_SINGLE_SOUTH = 1090,
+ SPR_MONO_SINGLE_EAST = 1091,
+ SPR_MONO_SINGLE_WEST = 1092,
+ SPR_MONO_TRACK_Y = 1093,
+ SPR_MONO_TRACK_BASE = 1100,
+ SPR_MONO_TRACK_N_S = 1117,
+ SPR_MGLV_SINGLE_Y = 1169,
+ SPR_MGLV_SINGLE_X = 1170,
+ SPR_MGLV_SINGLE_NORTH = 1171,
+ SPR_MGLV_SINGLE_SOUTH = 1172,
+ SPR_MGLV_SINGLE_EAST = 1173,
+ SPR_MGLV_SINGLE_WEST = 1174,
+ SPR_MGLV_TRACK_Y = 1175,
+ SPR_MGLV_TRACK_BASE = 1182,
+ SPR_MGLV_TRACK_N_S = 1199,
+ SPR_WAYPOINT_X_1 = SPR_OPENTTD_BASE + 15,
+ SPR_WAYPOINT_X_2 = SPR_OPENTTD_BASE + 16,
+ SPR_WAYPOINT_Y_1 = SPR_OPENTTD_BASE + 17,
+ SPR_WAYPOINT_Y_2 = SPR_OPENTTD_BASE + 18,
+ OFFSET_TILEH_IMPOSSIBLE = 0,
+ OFFSET_TILEH_1 = 14,
+ OFFSET_TILEH_2 = 15,
+ OFFSET_TILEH_3 = 22,
+ OFFSET_TILEH_4 = 13,
+ OFFSET_TILEH_6 = 21,
+ OFFSET_TILEH_7 = 17,
+ OFFSET_TILEH_8 = 12,
+ OFFSET_TILEH_9 = 23,
+ OFFSET_TILEH_11 = 18,
+ OFFSET_TILEH_12 = 20,
+ OFFSET_TILEH_13 = 19,
+ OFFSET_TILEH_14 = 16,
+
+ /* Elrail stuff */
+ /* Wires. First identifier is the direction of the track, second is the required placement of the pylon.
+ * "short" denotes a wire that requires a pylon on each end. Third identifier is the direction of the slope
+ * (in positive coordinate direction) */
+ SPR_WIRE_X_SHORT = SPR_ELRAIL_BASE + 3,
+ SPR_WIRE_Y_SHORT = SPR_ELRAIL_BASE + 4,
+ SPR_WIRE_EW_SHORT = SPR_ELRAIL_BASE + 5,
+ SPR_WIRE_NS_SHORT = SPR_ELRAIL_BASE + 6,
+ SPR_WIRE_X_SHORT_DOWN = SPR_ELRAIL_BASE + 7,
+ SPR_WIRE_Y_SHORT_UP = SPR_ELRAIL_BASE + 8,
+ SPR_WIRE_X_SHORT_UP = SPR_ELRAIL_BASE + 9,
+ SPR_WIRE_Y_SHORT_DOWN = SPR_ELRAIL_BASE + 10,
+
+ SPR_WIRE_X_SW = SPR_ELRAIL_BASE + 11,
+ SPR_WIRE_Y_SE = SPR_ELRAIL_BASE + 12,
+ SPR_WIRE_EW_E = SPR_ELRAIL_BASE + 13,
+ SPR_WIRE_NS_S = SPR_ELRAIL_BASE + 14,
+ SPR_WIRE_X_SW_DOWN = SPR_ELRAIL_BASE + 15,
+ SPR_WIRE_Y_SE_UP = SPR_ELRAIL_BASE + 16,
+ SPR_WIRE_X_SW_UP = SPR_ELRAIL_BASE + 17,
+ SPR_WIRE_Y_SE_DOWN = SPR_ELRAIL_BASE + 18,
+
+ SPR_WIRE_X_NE = SPR_ELRAIL_BASE + 19,
+ SPR_WIRE_Y_NW = SPR_ELRAIL_BASE + 20,
+ SPR_WIRE_EW_W = SPR_ELRAIL_BASE + 21,
+ SPR_WIRE_NS_N = SPR_ELRAIL_BASE + 22,
+ SPR_WIRE_X_NE_DOWN = SPR_ELRAIL_BASE + 23,
+ SPR_WIRE_Y_NW_UP = SPR_ELRAIL_BASE + 24,
+ SPR_WIRE_X_NE_UP = SPR_ELRAIL_BASE + 25,
+ SPR_WIRE_Y_NW_DOWN = SPR_ELRAIL_BASE + 26,
+
+ /* Tunnel entries */
+ SPR_WIRE_DEPOT_SW = SPR_ELRAIL_BASE + 27,
+ SPR_WIRE_DEPOT_NW = SPR_ELRAIL_BASE + 28,
+ SPR_WIRE_DEPOT_NE = SPR_ELRAIL_BASE + 29,
+ SPR_WIRE_DEPOT_SE = SPR_ELRAIL_BASE + 30,
+
+
+ /* Pylons, first identifier is the direction of the track, second the placement relative to the track */
+ SPR_PYLON_Y_NE = SPR_ELRAIL_BASE + 31,
+ SPR_PYLON_Y_SW = SPR_ELRAIL_BASE + 32,
+ SPR_PYLON_X_NW = SPR_ELRAIL_BASE + 33,
+ SPR_PYLON_X_SE = SPR_ELRAIL_BASE + 34,
+ SPR_PYLON_EW_N = SPR_ELRAIL_BASE + 35,
+ SPR_PYLON_EW_S = SPR_ELRAIL_BASE + 36,
+ SPR_PYLON_NS_W = SPR_ELRAIL_BASE + 37,
+ SPR_PYLON_NS_E = SPR_ELRAIL_BASE + 38,
+
+ /* sprites for airports and airfields*/
+ /* Small airports are AIRFIELD, everything else is AIRPORT */
+ SPR_HELIPORT = 2633,
+ SPR_AIRPORT_APRON = 2634,
+ SPR_AIRPORT_AIRCRAFT_STAND = 2635,
+ SPR_AIRPORT_TAXIWAY_NS_WEST = 2636,
+ SPR_AIRPORT_TAXIWAY_EW_SOUTH = 2637,
+ SPR_AIRPORT_TAXIWAY_XING_SOUTH = 2638,
+ SPR_AIRPORT_TAXIWAY_XING_WEST = 2639,
+ SPR_AIRPORT_TAXIWAY_NS_CTR = 2640,
+ SPR_AIRPORT_TAXIWAY_XING_EAST = 2641,
+ SPR_AIRPORT_TAXIWAY_NS_EAST = 2642,
+ SPR_AIRPORT_TAXIWAY_EW_NORTH = 2643,
+ SPR_AIRPORT_TAXIWAY_EW_CTR = 2644,
+ SPR_AIRPORT_RUNWAY_EXIT_A = 2645,
+ SPR_AIRPORT_RUNWAY_EXIT_B = 2646,
+ SPR_AIRPORT_RUNWAY_EXIT_C = 2647,
+ SPR_AIRPORT_RUNWAY_EXIT_D = 2648,
+ SPR_AIRPORT_RUNWAY_END = 2649, //We should have different ends
+ SPR_AIRPORT_TERMINAL_A = 2650,
+ SPR_AIRPORT_TOWER = 2651,
+ SPR_AIRPORT_CONCOURSE = 2652,
+ SPR_AIRPORT_TERMINAL_B = 2653,
+ SPR_AIRPORT_TERMINAL_C = 2654,
+ SPR_AIRPORT_HANGAR_FRONT = 2655,
+ SPR_AIRPORT_HANGAR_REAR = 2656,
+ SPR_AIRFIELD_HANGAR_FRONT = 2657,
+ SPR_AIRFIELD_HANGAR_REAR = 2658,
+ SPR_AIRPORT_JETWAY_1 = 2659,
+ SPR_AIRPORT_JETWAY_2 = 2660,
+ SPR_AIRPORT_JETWAY_3 = 2661,
+ SPR_AIRPORT_PASSENGER_TUNNEL = 2662,
+ SPR_AIRPORT_FENCE_Y = 2663,
+ SPR_AIRPORT_FENCE_X = 2664,
+ SPR_AIRFIELD_TERM_A = 2665,
+ SPR_AIRFIELD_TERM_B = 2666,
+ SPR_AIRFIELD_TERM_C_GROUND = 2667,
+ SPR_AIRFIELD_TERM_C_BUILD = 2668,
+ SPR_AIRFIELD_APRON_A = 2669,
+ SPR_AIRFIELD_APRON_B = 2670,
+ SPR_AIRFIELD_APRON_C = 2671,
+ SPR_AIRFIELD_APRON_D = 2672,
+ SPR_AIRFIELD_RUNWAY_NEAR_END = 2673,
+ SPR_AIRFIELD_RUNWAY_MIDDLE = 2674,
+ SPR_AIRFIELD_RUNWAY_FAR_END = 2675,
+ SPR_AIRFIELD_WIND_1 = 2676,
+ SPR_AIRFIELD_WIND_2 = 2677,
+ SPR_AIRFIELD_WIND_3 = 2678,
+ SPR_AIRFIELD_WIND_4 = 2679,
+ SPR_AIRPORT_RADAR_1 = 2680,
+ SPR_AIRPORT_RADAR_2 = 2681,
+ SPR_AIRPORT_RADAR_3 = 2682,
+ SPR_AIRPORT_RADAR_4 = 2683,
+ SPR_AIRPORT_RADAR_5 = 2684,
+ SPR_AIRPORT_RADAR_6 = 2685,
+ SPR_AIRPORT_RADAR_7 = 2686,
+ SPR_AIRPORT_RADAR_8 = 2687,
+ SPR_AIRPORT_RADAR_9 = 2688,
+ SPR_AIRPORT_RADAR_A = 2689,
+ SPR_AIRPORT_RADAR_B = 2690,
+ SPR_AIRPORT_RADAR_C = 2691,
+ SPR_AIRPORT_HELIPAD = SPR_OPENTTD_BASE + 28,
+ SPR_AIRPORT_HELIDEPOT_OFFICE = 2095,
+
+ /* Road Stops */
+ /* Road stops have a ground tile and 3 buildings, one on each side
+ * (except the side where the entry is). These are marked _A _B and _C */
+ SPR_BUS_STOP_NE_GROUND = 2692,
+ SPR_BUS_STOP_SE_GROUND = 2693,
+ SPR_BUS_STOP_SW_GROUND = 2694,
+ SPR_BUS_STOP_NW_GROUND = 2695,
+ SPR_BUS_STOP_NE_BUILD_A = 2696,
+ SPR_BUS_STOP_SE_BUILD_A = 2697,
+ SPR_BUS_STOP_SW_BUILD_A = 2698,
+ SPR_BUS_STOP_NW_BUILD_A = 2699,
+ SPR_BUS_STOP_NE_BUILD_B = 2700,
+ SPR_BUS_STOP_SE_BUILD_B = 2701,
+ SPR_BUS_STOP_SW_BUILD_B = 2702,
+ SPR_BUS_STOP_NW_BUILD_B = 2703,
+ SPR_BUS_STOP_NE_BUILD_C = 2704,
+ SPR_BUS_STOP_SE_BUILD_C = 2705,
+ SPR_BUS_STOP_SW_BUILD_C = 2706,
+ SPR_BUS_STOP_NW_BUILD_C = 2707,
+ SPR_TRUCK_STOP_NE_GROUND = 2708,
+ SPR_TRUCK_STOP_SE_GROUND = 2709,
+ SPR_TRUCK_STOP_SW_GROUND = 2710,
+ SPR_TRUCK_STOP_NW_GROUND = 2711,
+ SPR_TRUCK_STOP_NE_BUILD_A = 2712,
+ SPR_TRUCK_STOP_SE_BUILD_A = 2713,
+ SPR_TRUCK_STOP_SW_BUILD_A = 2714,
+ SPR_TRUCK_STOP_NW_BUILD_A = 2715,
+ SPR_TRUCK_STOP_NE_BUILD_B = 2716,
+ SPR_TRUCK_STOP_SE_BUILD_B = 2717,
+ SPR_TRUCK_STOP_SW_BUILD_B = 2718,
+ SPR_TRUCK_STOP_NW_BUILD_B = 2719,
+ SPR_TRUCK_STOP_NE_BUILD_C = 2720,
+ SPR_TRUCK_STOP_SE_BUILD_C = 2721,
+ SPR_TRUCK_STOP_SW_BUILD_C = 2722,
+ SPR_TRUCK_STOP_NW_BUILD_C = 2723,
+
+ /* Sprites for docks */
+ /* Docks consist of two tiles, the sloped one and the flat one */
+ SPR_DOCK_SLOPE_NE = 2727,
+ SPR_DOCK_SLOPE_SE = 2728,
+ SPR_DOCK_SLOPE_SW = 2729,
+ SPR_DOCK_SLOPE_NW = 2730,
+ SPR_DOCK_FLAT_X = 2731, //for NE and SW
+ SPR_DOCK_FLAT_Y = 2732, //for NW and SE
+ SPR_BUOY = 4076, //XXX this sucks, because it displays wrong stuff on canals
+
+ /* Sprites for road */
+ SPR_ROAD_Y = 1332,
+ SPR_ROAD_X = 1333,
+ SPR_ROAD_Y_SNOW = 1351,
+ SPR_ROAD_X_SNOW = 1352,
+
+ SPR_EXCAVATION_X = 1414,
+ SPR_EXCAVATION_Y = 1415,
+
+ /* Landscape sprites */
+ SPR_FLAT_BARE_LAND = 3924,
+ SPR_FLAT_1_THIRD_GRASS_TILE = 3943,
+ SPR_FLAT_2_THIRD_GRASS_TILE = 3962,
+ SPR_FLAT_GRASS_TILE = 3981,
+ SPR_FLAT_ROUGH_LAND = 4000,
+ SPR_FLAT_ROUGH_LAND_1 = 4019,
+ SPR_FLAT_ROUGH_LAND_2 = 4020,
+ SPR_FLAT_ROUGH_LAND_3 = 4021,
+ SPR_FLAT_ROUGH_LAND_4 = 4022,
+ SPR_FLAT_ROCKY_LAND_1 = 4023,
+ SPR_FLAT_ROCKY_LAND_2 = 4042,
+ SPR_FLAT_WATER_TILE = 4061,
+ SPR_FLAT_1_QUART_SNOWY_TILE = 4493,
+ SPR_FLAT_2_QUART_SNOWY_TILE = 4512,
+ SPR_FLAT_3_QUART_SNOWY_TILE = 4531,
+ SPR_FLAT_SNOWY_TILE = 4550,
+
+ /* Hedge, Farmland-fence sprites */
+ SPR_HEDGE_BUSHES = 4090,
+ SPR_HEDGE_BUSHES_WITH_GATE = 4096,
+ SPR_HEDGE_FENCE = 4102,
+ SPR_HEDGE_BLOOMBUSH_YELLOW = 4108,
+ SPR_HEDGE_BLOOMBUSH_RED = 4114,
+ SPR_HEDGE_STONE = 4120,
+
+ /* Farmland sprites, only flat tiles listed, various stages */
+ SPR_FARMLAND_BARE = 4126,
+ SPR_FARMLAND_STATE_1 = 4145,
+ SPR_FARMLAND_STATE_2 = 4164,
+ SPR_FARMLAND_STATE_3 = 4183,
+ SPR_FARMLAND_STATE_4 = 4202,
+ SPR_FARMLAND_STATE_5 = 4221,
+ SPR_FARMLAND_STATE_6 = 4240,
+ SPR_FARMLAND_STATE_7 = 4259,
+ SPR_FARMLAND_HAYPACKS = 4278,
+
+ /* Shores */
+ SPR_NO_SHORE = 0, //used for tileh which have no shore
+ SPR_SHORE_TILEH_4 = 4062,
+ SPR_SHORE_TILEH_1 = 4063,
+ SPR_SHORE_TILEH_2 = 4064,
+ SPR_SHORE_TILEH_8 = 4065,
+ SPR_SHORE_TILEH_6 = 4066,
+ SPR_SHORE_TILEH_12 = 4067,
+ SPR_SHORE_TILEH_3 = 4068,
+ SPR_SHORE_TILEH_9 = 4069,
+
+ /* Water-related sprites */
+ SPR_SHIP_DEPOT_SE_FRONT = 4070,
+ SPR_SHIP_DEPOT_SW_FRONT = 4071,
+ SPR_SHIP_DEPOT_NW = 4072,
+ SPR_SHIP_DEPOT_NE = 4073,
+ SPR_SHIP_DEPOT_SE_REAR = 4074,
+ SPR_SHIP_DEPOT_SW_REAR = 4075,
+ //here come sloped water sprites
+ SPR_WATER_SLOPE_Y_UP = SPR_CANALS_BASE + 5, //Water flowing negative Y direction
+ SPR_WATER_SLOPE_X_DOWN = SPR_CANALS_BASE + 6, //positive X
+ SPR_WATER_SLOPE_X_UP = SPR_CANALS_BASE + 7, //negative X
+ SPR_WATER_SLOPE_Y_DOWN = SPR_CANALS_BASE + 8, //positive Y
+ //sprites for the shiplifts
+ //there are 4 kinds of shiplifts, each of them is 3 tiles long.
+ //the four kinds are running in the X and Y direction and
+ //are "lowering" either in the "+" or the "-" direction.
+ //the three tiles are the center tile (where the slope is)
+ //and a bottom and a top tile
+ SPR_SHIPLIFT_Y_UP_CENTER_REAR = SPR_CANALS_BASE + 9,
+ SPR_SHIPLIFT_X_DOWN_CENTER_REAR = SPR_CANALS_BASE + 10,
+ SPR_SHIPLIFT_X_UP_CENTER_REAR = SPR_CANALS_BASE + 11,
+ SPR_SHIPLIFT_Y_DOWN_CENTER_REAR = SPR_CANALS_BASE + 12,
+ SPR_SHIPLIFT_Y_UP_CENTER_FRONT = SPR_CANALS_BASE + 13,
+ SPR_SHIPLIFT_X_DOWN_CENTER_FRONT = SPR_CANALS_BASE + 14,
+ SPR_SHIPLIFT_X_UP_CENTER_FRONT = SPR_CANALS_BASE + 15,
+ SPR_SHIPLIFT_Y_DOWN_CENTER_FRONT = SPR_CANALS_BASE + 16,
+ SPR_SHIPLIFT_Y_UP_BOTTOM_REAR = SPR_CANALS_BASE + 17,
+ SPR_SHIPLIFT_X_DOWN_BOTTOM_REAR = SPR_CANALS_BASE + 18,
+ SPR_SHIPLIFT_X_UP_BOTTOM_REAR = SPR_CANALS_BASE + 19,
+ SPR_SHIPLIFT_Y_DOWN_BOTTOM_REAR = SPR_CANALS_BASE + 20,
+ SPR_SHIPLIFT_Y_UP_BOTTOM_FRONT = SPR_CANALS_BASE + 21,
+ SPR_SHIPLIFT_X_DOWN_BOTTOM_FRONT = SPR_CANALS_BASE + 22,
+ SPR_SHIPLIFT_X_UP_BOTTOM_FRONT = SPR_CANALS_BASE + 23,
+ SPR_SHIPLIFT_Y_DOWN_BOTTOM_FRONT = SPR_CANALS_BASE + 24,
+ SPR_SHIPLIFT_Y_UP_TOP_REAR = SPR_CANALS_BASE + 25,
+ SPR_SHIPLIFT_X_DOWN_TOP_REAR = SPR_CANALS_BASE + 26,
+ SPR_SHIPLIFT_X_UP_TOP_REAR = SPR_CANALS_BASE + 27,
+ SPR_SHIPLIFT_Y_DOWN_TOP_REAR = SPR_CANALS_BASE + 28,
+ SPR_SHIPLIFT_Y_UP_TOP_FRONT = SPR_CANALS_BASE + 29,
+ SPR_SHIPLIFT_X_DOWN_TOP_FRONT = SPR_CANALS_BASE + 30,
+ SPR_SHIPLIFT_X_UP_TOP_FRONT = SPR_CANALS_BASE + 31,
+ SPR_SHIPLIFT_Y_DOWN_TOP_FRONT = SPR_CANALS_BASE + 32,
+
+ /* Sprites for tunnels and bridges */
+ SPR_TUNNEL_ENTRY_REAR_RAIL = 2365,
+ SPR_TUNNEL_ENTRY_REAR_MONO = 2373,
+ SPR_TUNNEL_ENTRY_REAR_MAGLEV = 2381,
+ SPR_TUNNEL_ENTRY_REAR_ROAD = 2389,
+
+ /* Level crossings */
+ SPR_CROSSING_OFF_X_RAIL = 1370,
+ SPR_CROSSING_OFF_X_MONO = 1382,
+ SPR_CROSSING_OFF_X_MAGLEV = 1394,
+
+ /* bridge type sprites */
+ SPR_PILLARS_BASE = SPR_OPENTTD_BASE + 30,
+
+ /* Wooden bridge (type 0) */
+ SPR_BTWDN_RAIL_Y_REAR = 2545,
+ SPR_BTWDN_RAIL_X_REAR = 2546,
+ SPR_BTWDN_ROAD_Y_REAR = 2547,
+ SPR_BTWDN_ROAD_X_REAR = 2548,
+ SPR_BTWDN_Y_FRONT = 2549,
+ SPR_BTWDN_X_FRONT = 2550,
+ SPR_BTWDN_Y_PILLAR = 2551,
+ SPR_BTWDN_X_PILLAR = 2552,
+ SPR_BTWDN_MONO_Y_REAR = 4360,
+ SPR_BTWDN_MONO_X_REAR = 4361,
+ SPR_BTWDN_MGLV_Y_REAR = 4400,
+ SPR_BTWDN_MGLV_X_REAR = 4401,
+ /* ramps */
+ SPR_BTWDN_ROAD_RAMP_Y_DOWN = 2529,
+ SPR_BTWDN_ROAD_RAMP_X_DOWN = 2530,
+ SPR_BTWDN_ROAD_RAMP_X_UP = 2531, //for some weird reason the order is swapped
+ SPR_BTWDN_ROAD_RAMP_Y_UP = 2532, //between X and Y.
+ SPR_BTWDN_ROAD_Y_SLOPE_UP = 2533,
+ SPR_BTWDN_ROAD_X_SLOPE_UP = 2534,
+ SPR_BTWDN_ROAD_Y_SLOPE_DOWN = 2535,
+ SPR_BTWDN_ROAD_X_SLOPE_DOWN = 2536,
+ SPR_BTWDN_RAIL_RAMP_Y_DOWN = 2537,
+ SPR_BTWDN_RAIL_RAMP_X_DOWN = 2538,
+ SPR_BTWDN_RAIL_RAMP_X_UP = 2539, //for some weird reason the order is swapped
+ SPR_BTWDN_RAIL_RAMP_Y_UP = 2540, //between X and Y.
+ SPR_BTWDN_RAIL_Y_SLOPE_UP = 2541,
+ SPR_BTWDN_RAIL_X_SLOPE_UP = 2542,
+ SPR_BTWDN_RAIL_Y_SLOPE_DOWN = 2543,
+ SPR_BTWDN_RAIL_X_SLOPE_DOWN = 2544,
+ SPR_BTWDN_MONO_RAMP_Y_DOWN = 4352,
+ SPR_BTWDN_MONO_RAMP_X_DOWN = 4353,
+ SPR_BTWDN_MONO_RAMP_X_UP = 4354, //for some weird reason the order is swapped
+ SPR_BTWDN_MONO_RAMP_Y_UP = 4355, //between X and Y.
+ SPR_BTWDN_MONO_Y_SLOPE_UP = 4356,
+ SPR_BTWDN_MONO_X_SLOPE_UP = 4357,
+ SPR_BTWDN_MONO_Y_SLOPE_DOWN = 4358,
+ SPR_BTWDN_MONO_X_SLOPE_DOWN = 4359,
+ SPR_BTWDN_MGLV_RAMP_Y_DOWN = 4392,
+ SPR_BTWDN_MGLV_RAMP_X_DOWN = 4393,
+ SPR_BTWDN_MGLV_RAMP_X_UP = 4394, //for some weird reason the order is swapped
+ SPR_BTWDN_MGLV_RAMP_Y_UP = 4395, //between X and Y.
+ SPR_BTWDN_MGLV_Y_SLOPE_UP = 4396,
+ SPR_BTWDN_MGLV_X_SLOPE_UP = 4397,
+ SPR_BTWDN_MGLV_Y_SLOPE_DOWN = 4398,
+ SPR_BTWDN_MGLV_X_SLOPE_DOWN = 4399,
+
+ /* Steel Girder with arches */
+ /* BTSGA == Bridge Type Steel Girder Arched */
+ /* This is bridge type number 2 */
+ SPR_BTSGA_RAIL_X_REAR = 2499,
+ SPR_BTSGA_RAIL_Y_REAR = 2500,
+ SPR_BTSGA_ROAD_X_REAR = 2501,
+ SPR_BTSGA_ROAD_Y_REAR = 2502,
+ SPR_BTSGA_X_FRONT = 2503,
+ SPR_BTSGA_Y_FRONT = 2504,
+ SPR_BTSGA_X_PILLAR = 2505,
+ SPR_BTSGA_Y_PILLAR = 2606,
+ SPR_BTSGA_MONO_X_REAR = 4324,
+ SPR_BTSGA_MONO_Y_REAR = 4325,
+ SPR_BTSGA_MGLV_X_REAR = 4364,
+ SPR_BTSGA_MGLV_Y_REAR = 4365,
+
+ /* BTSUS == Suspension bridge */
+ /* TILE_* denotes the different tiles a suspension bridge
+ * can have
+ * TILE_A and TILE_B are the "beginnings" and "ends" of the
+ * suspension system. they have small rectangluar endcaps
+ * TILE_C and TILE_D look almost identical to TILE_A and
+ * TILE_B, but they do not have the "endcaps". They form the
+ * middle part
+ * TILE_E is a condensed configuration of two pillars. while they
+ * are usually 2 pillars apart, they only have 1 pillar separation
+ * here
+ * TILE_F is an extended configuration of pillars. they are
+ * plugged in when pillars should be 3 tiles apart
+ */
+ SPR_BTSUS_ROAD_Y_REAR_TILE_A = 2453,
+ SPR_BTSUS_ROAD_Y_REAR_TILE_B = 2454,
+ SPR_BTSUS_Y_FRONT_TILE_A = 2455,
+ SPR_BTSUS_Y_FRONT_TILE_B = 2456,
+ SPR_BTSUS_ROAD_Y_REAR_TILE_D = 2457,
+ SPR_BTSUS_ROAD_Y_REAR_TILE_C = 2458,
+ SPR_BTSUS_Y_FRONT_TILE_D = 2459,
+ SPR_BTSUS_Y_FRONT_TILE_C = 2460,
+ SPR_BTSUS_ROAD_X_REAR_TILE_A = 2461,
+ SPR_BTSUS_ROAD_X_REAR_TILE_B = 2462,
+ SPR_BTSUS_X_FRONT_TILE_A = 2463,
+ SPR_BTSUS_X_FRONT_TILE_B = 2464,
+ SPR_BTSUS_ROAD_X_TILE_D = 2465,
+ SPR_BTSUS_ROAD_X_TILE_C = 2466,
+ SPR_BTSUS_X_FRONT_TILE_D = 2467,
+ SPR_BTSUS_X_FRONT_TILE_C = 2468,
+ SPR_BTSUS_RAIL_Y_REAR_TILE_A = 2469,
+ SPR_BTSUS_RAIL_Y_REAR_TILE_B = 2470,
+ SPR_BTSUS_RAIL_Y_REAR_TILE_D = 2471,
+ SPR_BTSUS_RAIL_Y_REAR_TILE_C = 2472,
+ SPR_BTSUS_RAIL_X_REAR_TILE_A = 2473,
+ SPR_BTSUS_RAIL_X_REAR_TILE_B = 2474,
+ SPR_BTSUS_RAIL_X_REAR_TILE_D = 2475,
+ SPR_BTSUS_RAIL_X_REAR_TILE_C = 2476,
+ SPR_BTSUS_Y_PILLAR_TILE_A = 2477,
+ SPR_BTSUS_Y_PILLAR_TILE_B = 2478,
+ SPR_BTSUS_Y_PILLAR_TILE_D = 2479,
+ SPR_BTSUS_Y_PILLAR_TILE_C = 2480,
+ SPR_BTSUS_X_PILLAR_TILE_A = 2481,
+ SPR_BTSUS_X_PILLAR_TILE_B = 2482,
+ SPR_BTSUS_X_PILLAR_TILE_D = 2483,
+ SPR_BTSUS_X_PILLAR_TILE_C = 2484,
+ SPR_BTSUS_RAIL_Y_REAR_TILE_E = 2485,
+ SPR_BTSUS_RAIL_X_REAR_TILE_E = 2486,
+ SPR_BTSUS_ROAD_Y_REAR_TILE_E = 2487,
+ SPR_BTSUS_ROAD_X_REAR_TILE_E = 2488,
+ SPR_BTSUS_Y_FRONT_TILE_E = 2489,
+ SPR_BTSUS_X_FRONT_TILE_E = 2490,
+ SPR_BTSUS_Y_PILLAR_TILE_E = 2491,
+ SPR_BTSUS_X_PILLAR_TILE_E = 2492,
+ SPR_BTSUS_RAIL_X_REAR_TILE_F = 2493,
+ SPR_BTSUS_RAIL_Y_REAR_TILE_F = 2494,
+ SPR_BTSUS_ROAD_X_REAR_TILE_F = 2495,
+ SPR_BTSUS_ROAD_Y_REAR_TILE_F = 2496,
+ SPR_BTSUS_X_FRONT = 2497,
+ SPR_BTSUS_Y_FRONT = 2498,
+ SPR_BTSUS_MONO_Y_REAR_TILE_A = 4334,
+ SPR_BTSUS_MONO_Y_REAR_TILE_B = 4335,
+ SPR_BTSUS_MONO_Y_REAR_TILE_D = 4336,
+ SPR_BTSUS_MONO_Y_REAR_TILE_C = 4337,
+ SPR_BTSUS_MONO_X_REAR_TILE_A = 4338,
+ SPR_BTSUS_MONO_X_REAR_TILE_B = 4339,
+ SPR_BTSUS_MONO_X_REAR_TILE_D = 4340,
+ SPR_BTSUS_MONO_X_REAR_TILE_C = 4341,
+ SPR_BTSUS_MONO_Y_REAR_TILE_E = 4342,
+ SPR_BTSUS_MONO_X_REAR_TILE_E = 4343,
+ SPR_BTSUS_MONO_X_REAR_TILE_F = 4344,
+ SPR_BTSUS_MONO_Y_REAR_TILE_F = 4345,
+ SPR_BTSUS_MGLV_Y_REAR_TILE_A = 4374,
+ SPR_BTSUS_MGLV_Y_REAR_TILE_B = 4375,
+ SPR_BTSUS_MGLV_Y_REAR_TILE_D = 4376,
+ SPR_BTSUS_MGLV_Y_REAR_TILE_C = 4377,
+ SPR_BTSUS_MGLV_X_REAR_TILE_A = 4378,
+ SPR_BTSUS_MGLV_X_REAR_TILE_B = 4379,
+ SPR_BTSUS_MGLV_X_REAR_TILE_D = 4380,
+ SPR_BTSUS_MGLV_X_REAR_TILE_C = 4381,
+ SPR_BTSUS_MGLV_Y_REAR_TILE_E = 4382,
+ SPR_BTSUS_MGLV_X_REAR_TILE_E = 4383,
+ SPR_BTSUS_MGLV_X_REAR_TILE_F = 4384,
+ SPR_BTSUS_MGLV_Y_REAR_TILE_F = 4385,
+
+ /* cantilever bridges */
+ /* They have three different kinds of tiles:
+ * END(ing), MID(dle), BEG(ginning) */
+ SPR_BTCAN_RAIL_X_BEG = 2507,
+ SPR_BTCAN_RAIL_X_MID = 2508,
+ SPR_BTCAN_RAIL_X_END = 2509,
+ SPR_BTCAN_RAIL_Y_END = 2510,
+ SPR_BTCAN_RAIL_Y_MID = 2511,
+ SPR_BTCAN_RAIL_Y_BEG = 2512,
+ SPR_BTCAN_ROAD_X_BEG = 2513,
+ SPR_BTCAN_ROAD_X_MID = 2514,
+ SPR_BTCAN_ROAD_X_END = 2515,
+ SPR_BTCAN_ROAD_Y_END = 2516,
+ SPR_BTCAN_ROAD_Y_MID = 2517,
+ SPR_BTCAN_ROAD_Y_BEG = 2518,
+ SPR_BTCAN_X_FRONT_BEG = 2519,
+ SPR_BTCAN_X_FRONT_MID = 2520,
+ SPR_BTCAN_X_FRONT_END = 2521,
+ SPR_BTCAN_Y_FRONT_END = 2522,
+ SPR_BTCAN_Y_FRONT_MID = 2523,
+ SPR_BTCAN_Y_FRONT_BEG = 2524,
+ SPR_BTCAN_X_PILLAR_BEG = 2525,
+ SPR_BTCAN_X_PILLAR_MID = 2526,
+ SPR_BTCAN_Y_PILLAR_MID = 2527,
+ SPR_BTCAN_Y_PILLAR_BEG = 2528,
+ SPR_BTCAN_MONO_X_BEG = 4346,
+ SPR_BTCAN_MONO_X_MID = 4347,
+ SPR_BTCAN_MONO_X_END = 4348,
+ SPR_BTCAN_MONO_Y_END = 4349,
+ SPR_BTCAN_MONO_Y_MID = 4350,
+ SPR_BTCAN_MONO_Y_BEG = 4351,
+ SPR_BTCAN_MGLV_X_BEG = 4386,
+ SPR_BTCAN_MGLV_X_MID = 4387,
+ SPR_BTCAN_MGLV_X_END = 4388,
+ SPR_BTCAN_MGLV_Y_END = 4389,
+ SPR_BTCAN_MGLV_Y_MID = 4390,
+ SPR_BTCAN_MGLV_Y_BEG = 4391,
+
+ /* little concrete bridge */
+ SPR_BTCON_RAIL_X = 2493,
+ SPR_BTCON_RAIL_Y = 2494,
+ SPR_BTCON_ROAD_X = 2495,
+ SPR_BTCON_ROAD_Y = 2496,
+ SPR_BTCON_X_FRONT = 2497,
+ SPR_BTCON_Y_FRONT = 2498,
+ SPR_BTCON_X_PILLAR = 2505,
+ SPR_BTCON_Y_PILLAR = 2506,
+ SPR_BTCON_MONO_X = 4344,
+ SPR_BTCON_MONO_Y = 4345,
+ SPR_BTCON_MGLV_X = 4384,
+ SPR_BTCON_MGLV_Y = 4385,
+
+ /* little steel girder bridge */
+ SPR_BTGIR_RAIL_X = 2553,
+ SPR_BTGIR_RAIL_Y = 2554,
+ SPR_BTGIR_ROAD_X = 2555,
+ SPR_BTGIR_ROAD_Y = 2556,
+ SPR_BTGIR_X_FRONT = 2557,
+ SPR_BTGIR_Y_FRONT = 2558,
+ SPR_BTGIR_X_PILLAR = 2505,
+ SPR_BTGIR_Y_PILLAR = 2506,
+ SPR_BTGIR_MONO_X = 4362,
+ SPR_BTGIR_MONO_Y = 4363,
+ SPR_BTGIR_MGLV_X = 4402,
+ SPR_BTGIR_MGLV_Y = 4403,
+
+ /* tubular bridges */
+ /* tubular bridges have 3 kinds of tiles:
+ * a start tile (with only half a tube on the far side, marked _BEG
+ * a middle tile (full tunnel), marked _MID
+ * and an end tile (half a tube on the near side, maked _END
+ */
+ SPR_BTTUB_X_FRONT_BEG = 2559,
+ SPR_BTTUB_X_FRONT_MID = 2660,
+ SPR_BTTUB_X_FRONT_END = 2561,
+ SPR_BTTUB_Y_FRONT_END = 2562,
+ SPR_BTTUB_Y_FRONT_MID = 2563,
+ SPR_BTTUB_Y_FRONT_BEG = 2564,
+ SPR_BTTUB_X_RAIL_REAR_BEG = 2569,
+ SPR_BTTUB_X_RAIL_REAR_MID = 2570,
+ SPR_BTTUB_X_RAIL_REAR_END = 2571,
+ SPR_BTTUB_Y_RAIL_REAR_BEG = 2572,
+ SPR_BTTUB_Y_RAIL_REAR_MID = 2573,
+ SPR_BTTUB_Y_RAIL_REAR_END = 2574,
+ SPR_BTTUB_X_ROAD_REAR_BEG = 2575,
+ SPR_BTTUB_X_ROAD_REAR_MID = 2576,
+ SPR_BTTUB_X_ROAD_REAR_END = 2577,
+ SPR_BTTUB_Y_ROAD_REAR_BEG = 2578,
+ SPR_BTTUB_Y_ROAD_REAR_MID = 2579,
+ SPR_BTTUB_Y_ROAD_REAR_END = 2580,
+ SPR_BTTUB_X_MONO_REAR_BEG = 2581,
+ SPR_BTTUB_X_MONO_REAR_MID = 2582,
+ SPR_BTTUB_X_MONO_REAR_END = 2583,
+ SPR_BTTUB_Y_MONO_REAR_BEG = 2584,
+ SPR_BTTUB_Y_MONO_REAR_MID = 2585,
+ SPR_BTTUB_Y_MONO_REAR_END = 2586,
+ SPR_BTTUB_X_MGLV_REAR_BEG = 2587,
+ SPR_BTTUB_X_MGLV_REAR_MID = 2588,
+ SPR_BTTUB_X_MGLV_REAR_END = 2589,
+ SPR_BTTUB_Y_MGLV_REAR_BEG = 2590,
+ SPR_BTTUB_Y_MGLV_REAR_MID = 2591,
+ SPR_BTTUB_Y_MGLV_REAR_END = 2592,
+
+
+ /* ramps (for all bridges except wood and tubular?)*/
+ SPR_BTGEN_RAIL_X_SLOPE_DOWN = 2437,
+ SPR_BTGEN_RAIL_X_SLOPE_UP = 2438,
+ SPR_BTGEN_RAIL_Y_SLOPE_DOWN = 2439,
+ SPR_BTGEN_RAIL_Y_SLOPE_UP = 2440,
+ SPR_BTGEN_RAIL_RAMP_X_UP = 2441,
+ SPR_BTGEN_RAIL_RAMP_X_DOWN = 2442,
+ SPR_BTGEN_RAIL_RAMP_Y_UP = 2443,
+ SPR_BTGEN_RAIL_RAMP_Y_DOWN = 2444,
+ SPR_BTGEN_ROAD_X_SLOPE_DOWN = 2445,
+ SPR_BTGEN_ROAD_X_SLOPE_UP = 2446,
+ SPR_BTGEN_ROAD_Y_SLOPE_DOWN = 2447,
+ SPR_BTGEN_ROAD_Y_SLOPE_UP = 2448,
+ SPR_BTGEN_ROAD_RAMP_X_UP = 2449,
+ SPR_BTGEN_ROAD_RAMP_X_DOWN = 2450,
+ SPR_BTGEN_ROAD_RAMP_Y_UP = 2451,
+ SPR_BTGEN_ROAD_RAMP_Y_DOWN = 2452,
+ SPR_BTGEN_MONO_X_SLOPE_DOWN = 4326,
+ SPR_BTGEN_MONO_X_SLOPE_UP = 4327,
+ SPR_BTGEN_MONO_Y_SLOPE_DOWN = 4328,
+ SPR_BTGEN_MONO_Y_SLOPE_UP = 4329,
+ SPR_BTGEN_MONO_RAMP_X_UP = 4330,
+ SPR_BTGEN_MONO_RAMP_X_DOWN = 4331,
+ SPR_BTGEN_MONO_RAMP_Y_UP = 4332,
+ SPR_BTGEN_MONO_RAMP_Y_DOWN = 4333,
+ SPR_BTGEN_MGLV_X_SLOPE_DOWN = 4366,
+ SPR_BTGEN_MGLV_X_SLOPE_UP = 4367,
+ SPR_BTGEN_MGLV_Y_SLOPE_DOWN = 4368,
+ SPR_BTGEN_MGLV_Y_SLOPE_UP = 4369,
+ SPR_BTGEN_MGLV_RAMP_X_UP = 4370,
+ SPR_BTGEN_MGLV_RAMP_X_DOWN = 4371,
+ SPR_BTGEN_MGLV_RAMP_Y_UP = 4372,
+ SPR_BTGEN_MGLV_RAMP_Y_DOWN = 4373,
+
+ /* Vehicle view sprites */
+ SPR_CENTRE_VIEW_VEHICLE = 683,
+ SPR_SEND_TRAIN_TODEPOT = 685,
+ SPR_SEND_ROADVEH_TODEPOT = 686,
+ SPR_SEND_AIRCRAFT_TODEPOT = 687,
+ SPR_SEND_SHIP_TODEPOT = 688,
+
+ SPR_IGNORE_SIGNALS = 689,
+ SPR_SHOW_ORDERS = 690,
+ SPR_SHOW_VEHICLE_DETAILS = 691,
+ SPR_REFIT_VEHICLE = 692,
+ SPR_FORCE_VEHICLE_TURN = 715,
+
+ /* Vehicle sprite-flags (red/green) */
+ SPR_FLAG_VEH_STOPPED = 3090,
+ SPR_FLAG_VEH_RUNNING = 3091,
+
+ SPR_VEH_BUS_SW_VIEW = 3097,
+ SPR_VEH_BUS_SIDE_VIEW = 3098,
+
+ /* Rotor sprite numbers */
+ SPR_ROTOR_STOPPED = 3901,
+ SPR_ROTOR_MOVING_1 = 3902,
+ SPR_ROTOR_MOVING_3 = 3904,
+
+ /* Town/house sprites */
+ SPR_LIFT = 1443,
+
+ //used in town_land.h
+ //CNST1..3 = Those are the different stages of construction
+ //The last 2 hexas correspond to the type of building it represent, if any
+ SPR_CNST1_TALLOFFICE_00 = 1421,
+ SPR_CNST2_TALLOFFICE_00 = 1422,
+ SPR_CNST3_TALLOFFICE_00 = 1423,
+ SPR_GROUND_TALLOFFICE_00 = 1424,
+ SPR_BUILD_TALLOFFICE_00 = 1425, //temperate
+ SPR_CNST1_OFFICE_01 = 1426,
+ SPR_CNST2_OFFICE_01 = 1427,
+ SPR_BUILD_OFFICE_01 = 1428, //temperate
+ SPR_GROUND_OFFICE_01 = 1429,
+ SPR_CNST1_SMLBLCKFLATS_02 = 1430, //Small Block of Flats
+ SPR_CNST2_SMLBLCKFLATS_02 = 1431,
+ SPR_BUILD_SMLBLCKFLATS_02 = 1432, //temperate
+ SPR_GROUND_SMLBLCKFLATS_02 = 1433,
+ SPR_CNST1_TEMPCHURCH = 1434,
+ SPR_CNST2_TEMPCHURCH = 1435,
+ SPR_BUILD_TEMPCHURCH = 1436,
+ SPR_GROUND_TEMPCHURCH = 1437,
+ SPR_CNST1_LARGEOFFICE_04 = 1440,
+ SPR_CNST2_LARGEOFFICE_04 = 1441,
+ SPR_BUILD_LARGEOFFICE_04 = 1442, // temperate, sub-arctic, subtropical
+ SPR_BUILD_LARGEOFFICE_04_SNOW = 4569, // same, with snow
+ // These are in fact two houses for the same houseID. so V1 and V2
+ SPR_CNST1_TOWNHOUSE_06_V1 = 1444,
+ SPR_CNST2_TOWNHOUSE_06_V1 = 1445,
+ SPR_BUILD_TOWNHOUSE_06_V1 = 1446, // 1st variation
+ SPR_GRND_TOWNHOUSE_06_V1 = 1447,
+ SPR_CNST1_TOWNHOUSE_06_V2 = 1501, // used as ground, but is stage1
+ SPR_CNST1_TOWNHOUSE_06_V2_P = 1502, // pipes extensions for previous
+ SPR_CNST2_TOWNHOUSE_06_V2_G = 1503, // Ground of cnst stage 2
+ SPR_CNST2_TOWNHOUSE_06_V2 = 1504, // real cnst stage 2
+ SPR_GRND_TOWNHOUSE_06_V2 = 1505,
+ SPR_BUILD_TOWNHOUSE_06_V2 = 1506, // 2nd variation
+ SPR_CNST1_HOTEL_07_NW = 1448,
+ SPR_CNST2_HOTEL_07_NW = 1449,
+ SPR_BUILD_HOTEL_07_NW = 1450,
+ SPR_CNST1_HOTEL_07_SE = 1451,
+ SPR_CNST2_HOTEL_07_SE = 1452,
+ SPR_BUILD_HOTEL_07_SE = 1453,
+ SPR_STATUE_HORSERIDER_09 = 1454,
+ SPR_FOUNTAIN_0A = 1455,
+ SPR_PARKSTATUE_0B = 1456,
+ SPR_PARKALLEY_0C = 1457,
+ SPR_CNST1_OFFICE_0D = 1458,
+ SPR_CNST2_OFFICE_0D = 1459,
+ SPR_BUILD_OFFICE_0D = 1460,
+ SPR_CNST1_SHOPOFFICE_0E = 1461,
+ SPR_CNST2_SHOPOFFICE_0E = 1462,
+ SPR_BUILD_SHOPOFFICE_0E = 1463,
+ SPR_CNST1_SHOPOFFICE_0F = 1464,
+ SPR_CNST2_SHOPOFFICE_0F = 1465,
+ SPR_BUILD_SHOPOFFICE_0F = 1466,
+
+ /* Easter egg/disaster sprites */
+ SPR_BLIMP = 3905, // Zeppelin
+ SPR_BLIMP_CRASHING = 3906,
+ SPR_BLIMP_CRASHED = 3907,
+ SPR_UFO_SMALL_SCOUT = 3908, // XCOM - UFO Defense
+ SPR_UFO_SMALL_SCOUT_DARKER = 3909,
+ SPR_SUB_SMALL_NE = 3910, // Silent Service
+ SPR_SUB_SMALL_SE = 3911,
+ SPR_SUB_SMALL_SW = 3912,
+ SPR_SUB_SMALL_NW = 3913,
+ SPR_SUB_LARGE_NE = 3914,
+ SPR_SUB_LARGE_SE = 3915,
+ SPR_SUB_LARGE_SW = 3916,
+ SPR_SUB_LARGE_NW = 3917,
+ SPR_F_15 = 3918, // F-15 Strike Eagle
+ SPR_F_15_FIRING = 3919,
+ SPR_UFO_HARVESTER = 3920, // XCOM - UFO Defense
+ SPR_XCOM_SKYRANGER = 3921,
+ SPR_AH_64A = 3922, // Gunship
+ SPR_AH_64A_FIRING = 3923,
+
+ /* main_gui.c */
+ SPR_IMG_TERRAFORM_UP = 694,
+ SPR_IMG_TERRAFORM_DOWN = 695,
+ SPR_IMG_DYNAMITE = 703,
+ SPR_IMG_ROCKS = 4084,
+ SPR_IMG_LIGHTHOUSE_DESERT = 4085, // XXX - is Desert image on the desert-climate
+ SPR_IMG_TRANSMITTER = 4086,
+ SPR_IMG_LEVEL_LAND = SPR_OPENTTD_BASE + 61,
+ SPR_IMG_BUILD_CANAL = SPR_OPENTTD_BASE + 58,
+ SPR_IMG_BUILD_LOCK = SPR_CANALS_BASE + 69,
+ SPR_IMG_PLACE_SIGN = SPR_OPENTTD_BASE + 63,
+ SPR_IMG_PAUSE = 726,
+ SPR_IMG_FASTFORWARD = SPR_OPENTTD_BASE + 54,
+ SPR_IMG_SETTINGS = 751,
+ SPR_IMG_SAVE = 724,
+ SPR_IMG_SMALLMAP = 708,
+ SPR_IMG_TOWN = 4077,
+ SPR_IMG_SUBSIDIES = 679,
+ SPR_IMG_COMPANY_LIST = 1299,
+ SPR_IMG_COMPANY_FINANCE = 737,
+ SPR_IMG_COMPANY_GENERAL = 743,
+ SPR_IMG_GRAPHS = 745,
+ SPR_IMG_COMPANY_LEAGUE = 684,
+ SPR_IMG_SHOW_COUNTOURS = 738,
+ SPR_IMG_SHOW_VEHICLES = 739,
+ SPR_IMG_SHOW_ROUTES = 740,
+ SPR_IMG_INDUSTRY = 741,
+ SPR_IMG_PLANTTREES = 742,
+ SPR_IMG_TRAINLIST = 731,
+ SPR_IMG_TRUCKLIST = 732,
+ SPR_IMG_SHIPLIST = 733,
+ SPR_IMG_AIRPLANESLIST = 734,
+ SPR_IMG_ZOOMIN = 735,
+ SPR_IMG_ZOOMOUT = 736,
+ SPR_IMG_BUILDRAIL = 727,
+ SPR_IMG_BUILDROAD = 728,
+ SPR_IMG_BUILDWATER = 729,
+ SPR_IMG_BUILDAIR = 730,
+ SPR_IMG_LANDSCAPING = 4083,
+ SPR_IMG_MUSIC = 713,
+ SPR_IMG_MESSAGES = 680,
+ SPR_IMG_QUERY = 723,
+ SPR_IMG_SIGN = 4082,
+ SPR_IMG_BUY_LAND = 4791,
+
+ /* OPEN TRANSPORT TYCOON in gamescreen */
+ SPR_OTTD_O = 4842,
+ SPR_OTTD_P = 4841,
+ SPR_OTTD_E = SPR_OPENTTD_BASE + 13,
+ SPR_OTTD_D = SPR_OPENTTD_BASE + 14,
+ SPR_OTTD_N = 4839,
+ SPR_OTTD_T = 4836,
+ SPR_OTTD_R = 4837,
+ SPR_OTTD_A = 4838,
+ SPR_OTTD_S = 4840,
+ SPR_OTTD_Y = 4843,
+ SPR_OTTD_C = 4844,
+
+ SPR_HIGHSCORE_CHART_BEGIN = 4804,
+ SPR_TYCOON_IMG1_BEGIN = 4814,
+ SPR_TYCOON_IMG2_BEGIN = 4824,
+
+ /* Industry sprites */
+ SPR_IT_SUGAR_MINE_SIEVE = 4775,
+ SPR_IT_SUGAR_MINE_CLOUDS = 4784,
+ SPR_IT_SUGAR_MINE_PILE = 4780,
+ SPR_IT_TOFFEE_QUARRY_TOFFEE = 4766,
+ SPR_IT_TOFFEE_QUARRY_SHOVEL = 4767,
+ SPR_IT_BUBBLE_GENERATOR_SPRING = 4746,
+ SPR_IT_BUBBLE_GENERATOR_BUBBLE = 4747,
+ SPR_IT_TOY_FACTORY_STAMP_HOLDER = 4717,
+ SPR_IT_TOY_FACTORY_STAMP = 4718,
+ SPR_IT_TOY_FACTORY_CLAY = 4719,
+ SPR_IT_TOY_FACTORY_ROBOT = 4720,
+ SPR_IT_POWER_PLANT_TRANSFORMERS = 2054,
+
+ /*small icons of cargo available in station waiting*/
+ SPR_CARGO_PASSENGER = 4297,
+ SPR_CARGO_COAL = 4298,
+ SPR_CARGO_MAIL = 4299,
+ SPR_CARGO_OIL = 4300,
+ SPR_CARGO_LIVESTOCK = 4301,
+ SPR_CARGO_GOODS = 4302,
+ SPR_CARGO_GRAIN = 4303,
+ SPR_CARGO_WOOD = 4304,
+ SPR_CARGO_IRON_ORE = 4305,
+ SPR_CARGO_STEEL = 4306,
+ SPR_CARGO_VALUES_GOLD = 4307, /*shared between temperate and arctic*/
+ SPR_CARGO_FRUIT = 4308,
+ SPR_CARGO_COPPER_ORE = 4309,
+ SPR_CARGO_WATERCOLA = 4310, /*shared between desert and toyland*/
+ SPR_CARGO_DIAMONDS = 4311,
+ SPR_CARGO_FOOD = 4312,
+ SPR_CARGO_PAPER = 4313,
+ SPR_CARGO_RUBBER = 4314,
+ SPR_CARGO_CANDY = 4315,
+ SPR_CARGO_SUGAR = 4316,
+ SPR_CARGO_TOYS = 4317,
+ SPR_CARGO_COTTONCANDY = 4318,
+ SPR_CARGO_FIZZYDRINK = 4319,
+ SPR_CARGO_TOFFEE = 4320,
+ SPR_CARGO_BUBBLES = 4321,
+ SPR_CARGO_PLASTIC = 4322,
+ SPR_CARGO_BATTERIES = 4323,
+
+ /* Effect vehicles */
+ SPR_BULLDOZER_NE = 1416,
+ SPR_BULLDOZER_SE = 1417,
+ SPR_BULLDOZER_SW = 1418,
+ SPR_BULLDOZER_NW = 1419,
+
+ SPR_SMOKE_0 = 2040,
+ SPR_SMOKE_1 = 2041,
+ SPR_SMOKE_2 = 2042,
+ SPR_SMOKE_3 = 2043,
+ SPR_SMOKE_4 = 2044,
+
+ SPR_DIESEL_SMOKE_0 = 3073,
+ SPR_DIESEL_SMOKE_1 = 3074,
+ SPR_DIESEL_SMOKE_2 = 3075,
+ SPR_DIESEL_SMOKE_3 = 3076,
+ SPR_DIESEL_SMOKE_4 = 3077,
+ SPR_DIESEL_SMOKE_5 = 3078,
+
+ SPR_STEAM_SMOKE_0 = 3079,
+ SPR_STEAM_SMOKE_1 = 3080,
+ SPR_STEAM_SMOKE_2 = 3081,
+ SPR_STEAM_SMOKE_3 = 3082,
+ SPR_STEAM_SMOKE_4 = 3083,
+
+ SPR_ELECTRIC_SPARK_0 = 3084,
+ SPR_ELECTRIC_SPARK_1 = 3085,
+ SPR_ELECTRIC_SPARK_2 = 3086,
+ SPR_ELECTRIC_SPARK_3 = 3087,
+ SPR_ELECTRIC_SPARK_4 = 3088,
+ SPR_ELECTRIC_SPARK_5 = 3089,
+
+ SPR_CHIMNEY_SMOKE_0 = 3701,
+ SPR_CHIMNEY_SMOKE_1 = 3702,
+ SPR_CHIMNEY_SMOKE_2 = 3703,
+ SPR_CHIMNEY_SMOKE_3 = 3704,
+ SPR_CHIMNEY_SMOKE_4 = 3705,
+ SPR_CHIMNEY_SMOKE_5 = 3706,
+ SPR_CHIMNEY_SMOKE_6 = 3707,
+ SPR_CHIMNEY_SMOKE_7 = 3708,
+
+ SPR_EXPLOSION_LARGE_0 = 3709,
+ SPR_EXPLOSION_LARGE_1 = 3710,
+ SPR_EXPLOSION_LARGE_2 = 3711,
+ SPR_EXPLOSION_LARGE_3 = 3712,
+ SPR_EXPLOSION_LARGE_4 = 3713,
+ SPR_EXPLOSION_LARGE_5 = 3714,
+ SPR_EXPLOSION_LARGE_6 = 3715,
+ SPR_EXPLOSION_LARGE_7 = 3716,
+ SPR_EXPLOSION_LARGE_8 = 3717,
+ SPR_EXPLOSION_LARGE_9 = 3718,
+ SPR_EXPLOSION_LARGE_A = 3719,
+ SPR_EXPLOSION_LARGE_B = 3720,
+ SPR_EXPLOSION_LARGE_C = 3721,
+ SPR_EXPLOSION_LARGE_D = 3722,
+ SPR_EXPLOSION_LARGE_E = 3723,
+ SPR_EXPLOSION_LARGE_F = 3724,
+
+ SPR_EXPLOSION_SMALL_0 = 3725,
+ SPR_EXPLOSION_SMALL_1 = 3726,
+ SPR_EXPLOSION_SMALL_2 = 3727,
+ SPR_EXPLOSION_SMALL_3 = 3728,
+ SPR_EXPLOSION_SMALL_4 = 3729,
+ SPR_EXPLOSION_SMALL_5 = 3730,
+ SPR_EXPLOSION_SMALL_6 = 3731,
+ SPR_EXPLOSION_SMALL_7 = 3732,
+ SPR_EXPLOSION_SMALL_8 = 3733,
+ SPR_EXPLOSION_SMALL_9 = 3734,
+ SPR_EXPLOSION_SMALL_A = 3735,
+ SPR_EXPLOSION_SMALL_B = 3736,
+
+ SPR_BREAKDOWN_SMOKE_0 = 3737,
+ SPR_BREAKDOWN_SMOKE_1 = 3738,
+ SPR_BREAKDOWN_SMOKE_2 = 3739,
+ SPR_BREAKDOWN_SMOKE_3 = 3740,
+
+ SPR_BUBBLE_0 = 4748,
+ SPR_BUBBLE_1 = 4749,
+ SPR_BUBBLE_2 = 4750,
+ SPR_BUBBLE_GENERATE_0 = 4751,
+ SPR_BUBBLE_GENERATE_1 = 4752,
+ SPR_BUBBLE_GENERATE_2 = 4753,
+ SPR_BUBBLE_GENERATE_3 = 4754,
+ SPR_BUBBLE_BURST_0 = 4755,
+ SPR_BUBBLE_BURST_1 = 4756,
+ SPR_BUBBLE_BURST_2 = 4757,
+ SPR_BUBBLE_ABSORB_0 = 4758,
+ SPR_BUBBLE_ABSORB_1 = 4759,
+ SPR_BUBBLE_ABSORB_2 = 4760,
+ SPR_BUBBLE_ABSORB_3 = 4761,
+ SPR_BUBBLE_ABSORB_4 = 4762,
+
+ /* Electrified rail build menu */
+ SPR_BUILD_NS_ELRAIL = SPR_ELRAIL_BASE + 39,
+ SPR_BUILD_X_ELRAIL = SPR_ELRAIL_BASE + 40,
+ SPR_BUILD_EW_ELRAIL = SPR_ELRAIL_BASE + 41,
+ SPR_BUILD_Y_ELRAIL = SPR_ELRAIL_BASE + 42,
+ SPR_BUILD_TUNNEL_ELRAIL = SPR_ELRAIL_BASE + 47,
+
+ /* airport_gui.c */
+ SPR_IMG_AIRPORT = 744,
+
+ /* dock_gui.c */
+ SPR_IMG_SHIP_DEPOT = 748,
+ SPR_IMG_SHIP_DOCK = 746,
+ SPR_IMG_BOUY = 693,
+
+ /* music_gui.c */
+ SPR_IMG_SKIP_TO_PREV = 709,
+ SPR_IMG_SKIP_TO_NEXT = 710,
+ SPR_IMG_STOP_MUSIC = 711,
+ SPR_IMG_PLAY_MUSIC = 712,
+
+ /* road_gui.c */
+ SPR_IMG_ROAD_NW = 1309,
+ SPR_IMG_ROAD_NE = 1310,
+ SPR_IMG_ROAD_DEPOT = 1295,
+ SPR_IMG_BUS_STATION = 749,
+ SPR_IMG_TRUCK_BAY = 750,
+ SPR_IMG_BRIDGE = 2594,
+ SPR_IMG_ROAD_TUNNEL = 2429,
+ SPR_IMG_REMOVE = 714,
+
+ /* rail_gui.c */
+ SPR_IMG_RAIL_NS = 1251,
+ SPR_IMG_RAIL_NE = 1252,
+ SPR_IMG_RAIL_EW = 1253,
+ SPR_IMG_RAIL_NW = 1254,
+ SPR_IMG_AUTORAIL = SPR_OPENTTD_BASE + 0,
+ SPR_IMG_AUTOMONO = SPR_OPENTTD_BASE + 1,
+ SPR_IMG_AUTOMAGLEV = SPR_OPENTTD_BASE + 2,
+
+ SPR_IMG_WAYPOINT = SPR_OPENTTD_BASE + 3,
+
+ SPR_IMG_DEPOT_RAIL = 1294,
+ SPR_IMG_DEPOT_MONO = SPR_OPENTTD_BASE + 9,
+ SPR_IMG_DEPOT_MAGLEV = SPR_OPENTTD_BASE + 10,
+
+ SPR_IMG_RAIL_STATION = 1298,
+ SPR_IMG_RAIL_SIGNALS = 1291,
+
+ SPR_IMG_TUNNEL_RAIL = 2430,
+ SPR_IMG_TUNNEL_MONO = 2431,
+ SPR_IMG_TUNNEL_MAGLEV = 2432,
+
+ SPR_IMG_CONVERT_RAIL = SPR_OPENTTD_BASE + 22,
+ SPR_IMG_CONVERT_MONO = SPR_OPENTTD_BASE + 24,
+ SPR_IMG_CONVERT_MAGLEV = SPR_OPENTTD_BASE + 26,
+
+ /* intro_gui.c, genworld_gui.c */
+ SPR_SELECT_TEMPERATE = 4882,
+ SPR_SELECT_TEMPERATE_PUSHED = 4883,
+ SPR_SELECT_SUB_ARCTIC = 4884,
+ SPR_SELECT_SUB_ARCTIC_PUSHED = 4885,
+ SPR_SELECT_SUB_TROPICAL = 4886,
+ SPR_SELECT_SUB_TROPICAL_PUSHED = 4887,
+ SPR_SELECT_TOYLAND = 4888,
+ SPR_SELECT_TOYLAND_PUSHED = 4889,
+};
+
+/** Cursor sprite numbers */
+typedef enum CursorSprites {
+ /* Terraform */
+ /* Cursors */
+ SPR_CURSOR_MOUSE = 0,
+ SPR_CURSOR_ZZZ = 1,
+ SPR_CURSOR_BOUY = 702,
+ SPR_CURSOR_QUERY = 719,
+ SPR_CURSOR_HQ = 720,
+ SPR_CURSOR_SHIP_DEPOT = 721,
+ SPR_CURSOR_SIGN = 722,
+
+ SPR_CURSOR_TREE = 2010,
+ SPR_CURSOR_BUY_LAND = 4792,
+ SPR_CURSOR_LEVEL_LAND = SPR_OPENTTD_BASE + 62,
+
+ SPR_CURSOR_TOWN = 4080,
+ SPR_CURSOR_INDUSTRY = 4081,
+ SPR_CURSOR_ROCKY_AREA = 4087,
+ SPR_CURSOR_LIGHTHOUSE = 4088,
+ SPR_CURSOR_TRANSMITTER = 4089,
+
+ /* airport cursors */
+ SPR_CURSOR_AIRPORT = 2724,
+
+ /* dock cursors */
+ SPR_CURSOR_DOCK = 3668,
+ SPR_CURSOR_CANAL = SPR_OPENTTD_BASE + 8,
+ SPR_CURSOR_LOCK = SPR_OPENTTD_BASE + 57,
+
+ /* shared road & rail cursors */
+ SPR_CURSOR_BRIDGE = 2593,
+
+ /* rail cursors */
+ SPR_CURSOR_NS_TRACK = 1263,
+ SPR_CURSOR_SWNE_TRACK = 1264,
+ SPR_CURSOR_EW_TRACK = 1265,
+ SPR_CURSOR_NWSE_TRACK = 1266,
+
+ SPR_CURSOR_NS_MONO = 1267,
+ SPR_CURSOR_SWNE_MONO = 1268,
+ SPR_CURSOR_EW_MONO = 1269,
+ SPR_CURSOR_NWSE_MONO = 1270,
+
+ SPR_CURSOR_NS_MAGLEV = 1271,
+ SPR_CURSOR_SWNE_MAGLEV = 1272,
+ SPR_CURSOR_EW_MAGLEV = 1273,
+ SPR_CURSOR_NWSE_MAGLEV = 1274,
+
+ SPR_CURSOR_NS_ELRAIL = SPR_ELRAIL_BASE + 43,
+ SPR_CURSOR_SWNE_ELRAIL = SPR_ELRAIL_BASE + 44,
+ SPR_CURSOR_EW_ELRAIL = SPR_ELRAIL_BASE + 45,
+ SPR_CURSOR_NWSE_ELRAIL = SPR_ELRAIL_BASE + 46,
+
+ SPR_CURSOR_RAIL_STATION = 1300,
+
+ SPR_CURSOR_TUNNEL_RAIL = 2434,
+ SPR_CURSOR_TUNNEL_ELRAIL = SPR_ELRAIL_BASE + 48,
+ SPR_CURSOR_TUNNEL_MONO = 2435,
+ SPR_CURSOR_TUNNEL_MAGLEV = 2436,
+
+ SPR_CURSOR_AUTORAIL = SPR_OPENTTD_BASE + 4,
+ SPR_CURSOR_AUTOMONO = SPR_OPENTTD_BASE + 5,
+ SPR_CURSOR_AUTOMAGLEV = SPR_OPENTTD_BASE + 6,
+
+ SPR_CURSOR_WAYPOINT = SPR_OPENTTD_BASE + 7,
+
+ SPR_CURSOR_RAIL_DEPOT = 1296,
+ SPR_CURSOR_MONO_DEPOT = SPR_OPENTTD_BASE + 11,
+ SPR_CURSOR_MAGLEV_DEPOT = SPR_OPENTTD_BASE + 12,
+
+ SPR_CURSOR_CONVERT_RAIL = SPR_OPENTTD_BASE + 23,
+ SPR_CURSOR_CONVERT_MONO = SPR_OPENTTD_BASE + 25,
+ SPR_CURSOR_CONVERT_MAGLEV = SPR_OPENTTD_BASE + 27,
+
+ /* road cursors */
+ SPR_CURSOR_ROAD_NESW = 1311,
+ SPR_CURSOR_ROAD_NWSE = 1312,
+
+ SPR_CURSOR_ROAD_DEPOT = 1297,
+ SPR_CURSOR_BUS_STATION = 2725,
+ SPR_CURSOR_TRUCK_STATION = 2726,
+ SPR_CURSOR_ROAD_TUNNEL = 2433,
+
+ SPR_CURSOR_CLONE_TRAIN = SPR_OPENTTD_BASE + 93,
+ SPR_CURSOR_CLONE_ROADVEH = SPR_OPENTTD_BASE + 110,
+ SPR_CURSOR_CLONE_SHIP = SPR_OPENTTD_BASE + 112,
+ SPR_CURSOR_CLONE_AIRPLANE = SPR_OPENTTD_BASE + 114,
+} CursorSprite;
+
+/// Animation macro in table/animcursors.h (_animcursors[])
+enum AnimCursors {
+ ANIMCURSOR_DEMOLISH = -1, ///< 704 - 707 - demolish dynamite
+ ANIMCURSOR_LOWERLAND = -2, ///< 699 - 701 - lower land tool
+ ANIMCURSOR_RAISELAND = -3, ///< 696 - 698 - raise land tool
+ ANIMCURSOR_PICKSTATION = -4, ///< 716 - 718 - goto-order icon
+ ANIMCURSOR_BUILDSIGNALS = -5, ///< 1292 - 1293 - build signal
+};
+
+/**
+ * Bitmask setup. For the graphics system, 32 bits are used to define
+ * the sprite to be displayed. This variable contains various information:<p>
+ * <ul><li> SPRITE_WIDTH is the number of bits used for the actual sprite to be displayed.
+ * This always starts at bit 0.</li>
+ * <li> TRANSPARENT_BIT is the bit number which toggles sprite transparency</li>
+ * <li> RECOLOR_BIT toggles the recoloring system</li>
+ * <li> PALETTE_SPRITE_WIDTH and PALETTE_SPRITE_START determine the position and number of
+ * bits used for the recoloring process. For transparency, it must be 0x322.</li>
+ */
+enum SpriteSetup {
+ TRANSPARENT_BIT = 31, ///< toggles transparency in the sprite
+ RECOLOR_BIT = 15, ///< toggles recoloring in the sprite
+ PALETTE_SPRITE_START = 16, ///< number of the first bit of the sprite containing the recolor palette
+ PALETTE_SPRITE_WIDTH = 14, ///< number of bits of the sprite containing the recolor palette
+ SPRITE_WIDTH = 14, ///< number of bits for the sprite number
+};
+
+/**
+ * these masks change the colors of the palette for a sprite.
+ * Apart from this bit, a sprite number is needed to define
+ * the palette used for recoloring. This palette is stored
+ * in the bits marked by PALETTE_SPRITE_MASK.
+ * @note Do not modify this enum. Alter SpriteSetup instead
+ * @see SpriteSetup
+ */
+enum Modifiers {
+ ///when a sprite is to be displayed transparently, this bit needs to be set.
+ PALETTE_MODIFIER_TRANSPARENT = 1 << TRANSPARENT_BIT,
+ ///this bit is set when a recoloring process is in action
+ PALETTE_MODIFIER_COLOR = 1 << RECOLOR_BIT,
+
+ //This is used for the GfxFillRect function
+ ///Used to draw a "grey out" rectangle. @see GfxFillRect
+ PALETTE_MODIFIER_GREYOUT = 1 << TRANSPARENT_BIT,
+ ///Set when a colortable mode is used. @see GfxFillRect
+ USE_COLORTABLE = 1 << RECOLOR_BIT,
+};
+
+/** Masks needed for sprite operations.
+ * @note Do not modify this enum. Alter SpriteSetup instead
+ * @see SpriteSetup */
+enum SpriteMasks {
+ ///Maximum number of sprites that can be loaded at a given time.
+ MAX_SPRITES = 1 << SPRITE_WIDTH,
+ ///The mask to for the main sprite
+ SPRITE_MASK = MAX_SPRITES - 1,
+ ///The mask for the auxiliary sprite (the one that takes care of recoloring)
+ PALETTE_SPRITE_MASK = ((1 << PALETTE_SPRITE_WIDTH) - 1) << PALETTE_SPRITE_START,
+ ///Mask for the auxiliary sprites if it is locate in the LSBs
+ COLORTABLE_MASK = (1 << PALETTE_SPRITE_WIDTH) - 1
+};
+
+assert_compile( (1 << TRANSPARENT_BIT & SPRITE_MASK) == 0 );
+assert_compile( (1 << RECOLOR_BIT & SPRITE_MASK) == 0 );
+assert_compile( TRANSPARENT_BIT != RECOLOR_BIT );
+assert_compile( (1 << TRANSPARENT_BIT & PALETTE_SPRITE_MASK) == 0);
+assert_compile( (1 << RECOLOR_BIT & PALETTE_SPRITE_MASK) == 0 );
+assert_compile( (PALETTE_SPRITE_MASK & SPRITE_MASK) == 0 );
+assert_compile( SPRITE_WIDTH + PALETTE_SPRITE_WIDTH <= 30 );
+
+enum Recoloring {
+ PALETTE_RECOLOR_START = 0x307,
+};
+
+#define PALETTE_RECOLOR_SPRITE(a) (a << PALETTE_SPRITE_START | PALETTE_MODIFIER_COLOR)
+enum PaletteSprites {
+ //note: these numbers are already the modified once the renderer needs.
+ //the actual sprite number is the upper 16 bits of the number
+
+ ///Here a puslating red tile is drawn if you try to build a wrong tunnel or raise/lower land where it is not possible
+ PALETTE_TILE_RED_PULSATING = PALETTE_RECOLOR_SPRITE(0x303),
+ ///makes a square red. is used when removing rails or other stuff
+ PALETTE_SEL_TILE_RED = PALETTE_RECOLOR_SPRITE(0x304),
+ ///This draws a blueish square (catchment areas for example)
+ PALETTE_SEL_TILE_BLUE = PALETTE_RECOLOR_SPRITE(0x305),
+ //0x306 is a real sprite (the little dot you get when you try to raise/lower a corner of the map
+ //here the color switches begin
+ //use this if you add stuff to the value, so that the resulting color
+ //is not a fixed value.
+ //NOTE THAT THE SWITCH 0x8000 is NOT present in _TO_COLORS yet!
+ PALETTE_TO_COLORS = PALETTE_RECOLOR_START << PALETTE_SPRITE_START,
+ PALETTE_TO_DARK_BLUE = PALETTE_RECOLOR_SPRITE(PALETTE_RECOLOR_START),
+ PALETTE_TO_PALE_GREEN = PALETTE_RECOLOR_SPRITE(0x308),
+ PALETTE_TO_PINK = PALETTE_RECOLOR_SPRITE(0x309),
+ PALETTE_TO_YELLOW = PALETTE_RECOLOR_SPRITE(0x30A),
+ PALETTE_TO_RED = PALETTE_RECOLOR_SPRITE(0x30B),
+ PALETTE_TO_LIGHT_BLUE = PALETTE_RECOLOR_SPRITE(0x30C),
+ PALETTE_TO_GREEN = PALETTE_RECOLOR_SPRITE(0x30D),
+ PALETTE_TO_DARK_GREEN = PALETTE_RECOLOR_SPRITE(0x30E),
+ PALETTE_TO_BLUE = PALETTE_RECOLOR_SPRITE(0x30F),
+ PALETTE_TO_CREAM = PALETTE_RECOLOR_SPRITE(0x310),
+ //maybe don't use as player color because it doesn't display in the graphs?
+ PALETTE_TO_MAUVE = PALETTE_RECOLOR_SPRITE(0x311),
+ PALETTE_TO_PURPLE = PALETTE_RECOLOR_SPRITE(0x312),
+ PALETTE_TO_ORANGE = PALETTE_RECOLOR_SPRITE(0x313),
+ PALETTE_TO_BROWN = PALETTE_RECOLOR_SPRITE(0x314),
+ PALETTE_TO_GREY = PALETTE_RECOLOR_SPRITE(0x315),
+ PALETTE_TO_WHITE = PALETTE_RECOLOR_SPRITE(0x316),
+ //sets color to bare land stuff, for rail and road (and crossings)
+ PALETTE_TO_BARE_LAND = PALETTE_RECOLOR_SPRITE(0x317),
+ //XXX is 318-31A really not used?
+ PALETTE_TO_STRUCT_BLUE = PALETTE_RECOLOR_SPRITE(0x31B),
+ //structure color to something brownish (for the cantilever bridges for example)
+ PALETTE_TO_STRUCT_BROWN = PALETTE_RECOLOR_SPRITE(0x31C),
+ PALETTE_TO_STRUCT_WHITE = PALETTE_RECOLOR_SPRITE(0x31D),
+ //sets bridge or structure to red, little concrete one and cantilever use this one for example
+ PALETTE_TO_STRUCT_RED = PALETTE_RECOLOR_SPRITE(0x31E),
+ PALETTE_TO_STRUCT_GREEN = PALETTE_RECOLOR_SPRITE(0x31F),
+ PALETTE_TO_STRUCT_CONCRETE = PALETTE_RECOLOR_SPRITE(0x320), //Sets the suspension bridge to concrete, also other strucutures use it
+ PALETTE_TO_STRUCT_YELLOW = PALETTE_RECOLOR_SPRITE(0x321), //Sets the bridge color to yellow (suspension and tubular)
+ PALETTE_TO_TRANSPARENT = 0x322 << PALETTE_SPRITE_START | PALETTE_MODIFIER_TRANSPARENT, //This sets the sprite to transparent
+ //This is used for changing the tubular bridges to the silicon display, or some grayish color
+ PALETTE_TO_STRUCT_GREY = PALETTE_RECOLOR_SPRITE(0x323),
+ PALETTE_CRASH = PALETTE_RECOLOR_SPRITE(0x324), //this changes stuff to the "crash color"
+ //XXX another place where structures are colored.
+ //I'm not sure which colors these are
+ PALETTE_59E = PALETTE_RECOLOR_SPRITE(0x59E),
+ PALETTE_59F = PALETTE_RECOLOR_SPRITE(0x59F),
+};
+#undef PALETTE_RECOLOR_SPRITE
+
+#define MAKE_TRANSPARENT(img) (img = (img & SPRITE_MASK) | PALETTE_TO_TRANSPARENT)
+
+#endif /* SPRITES_H */
diff --git a/src/table/station_land.h b/src/table/station_land.h
new file mode 100644
index 000000000..1c5864c2a
--- /dev/null
+++ b/src/table/station_land.h
@@ -0,0 +1,1203 @@
+/* $Id$ */
+
+#define TILE_SEQ_END() { 0x80, 0, 0, 0, 0, 0, 0 }
+
+static const DrawTileSeqStruct _station_display_datas_0[] = {
+ { 0, 0, 0, 16, 5, 2, SPR_RAIL_PLATFORM_X_REAR | PALETTE_MODIFIER_COLOR },
+ { 0, 11, 0, 16, 5, 2, SPR_RAIL_PLATFORM_X_FRONT | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_1[] = {
+ { 0, 0, 0, 5, 16, 2, SPR_RAIL_PLATFORM_Y_REAR | PALETTE_MODIFIER_COLOR },
+ { 11, 0, 0, 5, 16, 2, SPR_RAIL_PLATFORM_Y_FRONT | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_2[] = {
+ { 0, 0, 0, 16, 5, 2, SPR_RAIL_PLATFORM_BUILDING_X | PALETTE_MODIFIER_COLOR },
+ { 0, 11, 0, 16, 5, 2, SPR_RAIL_PLATFORM_X_FRONT | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_3[] = {
+ { 0, 0, 0, 5, 16, 2, SPR_RAIL_PLATFORM_BUILDING_Y | PALETTE_MODIFIER_COLOR },
+ { 11, 0, 0, 5, 16, 2, SPR_RAIL_PLATFORM_Y_FRONT | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_4[] = {
+ { 0, 0, 0, 16, 5, 7, SPR_RAIL_PLATFORM_PILLARS_X_REAR | PALETTE_MODIFIER_COLOR },
+ { 0, 11, 0, 16, 5, 2, SPR_RAIL_PLATFORM_X_FRONT | PALETTE_MODIFIER_COLOR },
+ { 0, 0, 16, 16, 16, 10, SPR_RAIL_ROOF_STRUCTURE_X_TILE_A | PALETTE_MODIFIER_COLOR },
+ { 0, 0,0x80, 0, 0, 0, SPR_RAIL_ROOF_GLASS_X_TILE_A | PALETTE_TO_TRANSPARENT },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_5[] = {
+ { 0, 0, 0, 5, 16, 2, SPR_RAIL_PLATFORM_PILLARS_Y_REAR | PALETTE_MODIFIER_COLOR },
+ { 11, 0, 0, 5, 16, 2, SPR_RAIL_PLATFORM_Y_FRONT | PALETTE_MODIFIER_COLOR },
+ { 0, 0, 16, 16, 16, 10, SPR_RAIL_ROOF_STRUCTURE_Y_TILE_A | PALETTE_MODIFIER_COLOR },
+ { 0, 0,0x80, 0, 0, 0, SPR_RAIL_ROOF_GLASS_Y_TILE_A | PALETTE_TO_TRANSPARENT },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_6[] = {
+ { 0, 0, 0, 16, 5, 2, SPR_RAIL_PLATFORM_X_REAR | PALETTE_MODIFIER_COLOR },
+ { 0, 11, 0, 16, 5, 2, SPR_RAIL_PLATFORM_PILLARS_X_FRONT | PALETTE_MODIFIER_COLOR },
+ { 0, 0, 16, 16, 16, 10, SPR_RAIL_ROOF_STRUCTURE_X_TILE_B | PALETTE_MODIFIER_COLOR },
+ { 0, 0,0x80, 0, 0, 0, SPR_RAIL_ROOF_GLASS_X_TILE_B | PALETTE_TO_TRANSPARENT },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_7[] = {
+ { 0, 0, 0, 5, 16, 2, SPR_RAIL_PLATFORM_Y_REAR | PALETTE_MODIFIER_COLOR },
+ { 11, 0, 0, 5, 16, 2, SPR_RAIL_PLATFORM_PILLARS_Y_FRONT | PALETTE_MODIFIER_COLOR },
+ { 0, 0, 16, 16, 16, 10, SPR_RAIL_ROOF_STRUCTURE_Y_TILE_B | PALETTE_MODIFIER_COLOR },
+ { 0, 0,0x80, 0, 0, 0, SPR_RAIL_ROOF_GLASS_Y_TILE_B | PALETTE_TO_TRANSPARENT },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_8[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_9[] = {
+ { 0, 0, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences north
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_10[] = {
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR }, // fences west
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_11[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_12[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_13[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_14[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_15[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_16[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_17[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_18[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_19[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_20[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_21[] = {
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_22[] = {
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_23[] = {
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_24[] = {
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_25[] = {
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_26[] = {
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_27[] = {
+ { 2, 0, 0, 11, 16, 40, SPR_AIRPORT_TERMINAL_A | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_28[] = {
+ { 3, 3, 0, 10, 10, 60, SPR_AIRPORT_TOWER | PALETTE_MODIFIER_COLOR },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_29[] = {
+ { 0, 1, 0, 14, 14, 30, SPR_AIRPORT_CONCOURSE | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_30[] = {
+ { 3, 3, 0, 10, 11, 35, SPR_AIRPORT_TERMINAL_B | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_31[] = {
+ { 0, 3, 0, 16, 11, 40, SPR_AIRPORT_TERMINAL_C | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_32[] = {
+ { 14, 0, 0, 2, 16, 28, SPR_AIRPORT_HANGAR_FRONT | PALETTE_MODIFIER_COLOR },
+ { 0, 0, 0, 2, 16, 28, SPR_AIRPORT_HANGAR_REAR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_33[] = {
+ { 7, 11, 0, 3, 3, 14, SPR_AIRPORT_JETWAY_1 },
+ { 0, 0, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_34[] = {
+ { 2, 7, 0, 3, 3, 14, SPR_AIRPORT_JETWAY_2 },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_35[] = {
+ { 3, 2, 0, 3, 3, 14, SPR_AIRPORT_JETWAY_3 },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_36[] = {
+ { 0, 8, 0, 14, 3, 14, SPR_AIRPORT_PASSENGER_TUNNEL },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_37[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_38[] = {
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_39[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_1 },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_40[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_2 },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_41[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_3 },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_42[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_4 },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_43[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_5 },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_44[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_6 },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_45[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_7 },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_46[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_8 },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_47[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_9 },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_48[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_A },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_49[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_B },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_50[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_C },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_51[] = {
+ { 7, 7, 0, 2, 2, 70, SPR_UNMOVABLE_TRANSMITTER },
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_52[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_53[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_54[] = {
+ { 0, 0, 0, 15, 15, 30, SPR_AIRFIELD_TERM_C_BUILD | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_55[] = {
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_56[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_57[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_58[] = {
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ { 4, 11, 0, 1, 1, 20, SPR_AIRFIELD_WIND_1 | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_59[] = {
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ { 4, 11, 0, 1, 1, 20, SPR_AIRFIELD_WIND_2 | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_60[] = {
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ { 4, 11, 0, 1, 1, 20, SPR_AIRFIELD_WIND_3 | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_61[] = {
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ { 4, 11, 0, 1, 1, 20, SPR_AIRFIELD_WIND_4 | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_62[] = {
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_63[] = {
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_64[] = {
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_65[] = {
+ { 14, 0, 0, 2, 16, 28, SPR_AIRFIELD_HANGAR_FRONT | PALETTE_MODIFIER_COLOR },
+ { 0, 0, 0, 2, 16, 28, SPR_AIRFIELD_HANGAR_REAR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_66[] = {
+ { 0, 0, 0, 16, 16, 60, SPR_HELIPORT | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_67[] = {
+ { 0, 15, 0, 13, 1, 10, SPR_TRUCK_STOP_NE_BUILD_A | PALETTE_MODIFIER_COLOR },
+ { 13, 0, 0, 3, 16, 10, SPR_TRUCK_STOP_NE_BUILD_B | PALETTE_MODIFIER_COLOR },
+ { 2, 0, 0, 11, 1, 10, SPR_TRUCK_STOP_NE_BUILD_C | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_68[] = {
+ { 15, 3, 0, 1, 13, 10, SPR_TRUCK_STOP_SE_BUILD_A | PALETTE_MODIFIER_COLOR },
+ { 0, 0, 0, 16, 3, 10, SPR_TRUCK_STOP_SE_BUILD_B | PALETTE_MODIFIER_COLOR },
+ { 0, 3, 0, 1, 11, 10, SPR_TRUCK_STOP_SE_BUILD_C | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_69[] = {
+ { 3, 0, 0, 13, 1, 10, SPR_TRUCK_STOP_SW_BUILD_A | PALETTE_MODIFIER_COLOR },
+ { 0, 0, 0, 3, 16, 10, SPR_TRUCK_STOP_SW_BUILD_B | PALETTE_MODIFIER_COLOR },
+ { 3, 15, 0, 11, 1, 10, SPR_TRUCK_STOP_SW_BUILD_C | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_70[] = {
+ { 0, 0, 0, 1, 13, 10, SPR_TRUCK_STOP_NW_BUILD_A | PALETTE_MODIFIER_COLOR },
+ { 0, 13, 0, 16, 3, 10, SPR_TRUCK_STOP_NW_BUILD_B | PALETTE_MODIFIER_COLOR },
+ { 15, 2, 0, 1, 11, 10, SPR_TRUCK_STOP_NW_BUILD_C | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_71[] = {
+ { 2, 0, 0, 11, 1, 10, SPR_BUS_STOP_NE_BUILD_A | PALETTE_MODIFIER_COLOR },
+ { 13, 0, 0, 3, 16, 10, SPR_BUS_STOP_NE_BUILD_B | PALETTE_MODIFIER_COLOR },
+ { 0, 13, 0, 13, 3, 10, SPR_BUS_STOP_NE_BUILD_C | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_72[] = {
+ { 0, 3, 0, 1, 11, 10, SPR_BUS_STOP_SE_BUILD_A | PALETTE_MODIFIER_COLOR },
+ { 0, 0, 0, 16, 3, 10, SPR_BUS_STOP_SE_BUILD_B | PALETTE_MODIFIER_COLOR },
+ { 13, 3, 0, 3, 13, 10, SPR_BUS_STOP_SE_BUILD_C | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_73[] = {
+ { 3, 15, 0, 11, 1, 10, SPR_BUS_STOP_SW_BUILD_A | PALETTE_MODIFIER_COLOR },
+ { 0, 0, 0, 3, 16, 10, SPR_BUS_STOP_SW_BUILD_B | PALETTE_MODIFIER_COLOR },
+ { 3, 0, 0, 13, 3, 10, SPR_BUS_STOP_SW_BUILD_C | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_74[] = {
+ { 15, 2, 0, 1, 11, 10, SPR_BUS_STOP_NW_BUILD_A | PALETTE_MODIFIER_COLOR },
+ { 0, 13, 0, 16, 3, 10, SPR_BUS_STOP_NW_BUILD_B | PALETTE_MODIFIER_COLOR },
+ { 0, 0, 0, 3, 13, 10, SPR_BUS_STOP_NW_BUILD_C | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_75[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_76[] = {
+ { 0, 4, 0, 16, 8, 8, SPR_DOCK_SLOPE_NE },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_77[] = {
+ { 4, 0, 0, 8, 16, 8, SPR_DOCK_SLOPE_SE },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_78[] = {
+ { 0, 4, 0, 16, 8, 8, SPR_DOCK_SLOPE_SW },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_79[] = {
+ { 4, 0, 0, 8, 16, 8, SPR_DOCK_SLOPE_NW },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_80[] = {
+ { 0, 4, 0, 16, 8, 8, SPR_DOCK_FLAT_X },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_81[] = {
+ { 4, 0, 0, 8, 16, 8, SPR_DOCK_FLAT_Y },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _station_display_datas_82[] = {
+ TILE_SEQ_END()
+};
+
+// end of runway
+static const DrawTileSeqStruct _station_display_datas_083[] = {
+ TILE_SEQ_END()
+};
+
+// runway tiles
+static const DrawTileSeqStruct _station_display_datas_084[] = {
+ TILE_SEQ_END()
+};
+
+// control tower with concrete underground and no fence
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_085[] = {
+ { 3, 3, 0, 10, 10, 60, SPR_AIRPORT_TOWER | PALETTE_MODIFIER_COLOR }, // control tower
+ TILE_SEQ_END()
+};
+
+// new airportdepot, facing west
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_086[] = {
+ { 14, 0, 0, 2, 16, 28, SPR_AIRFIELD_HANGAR_FRONT | PALETTE_MODIFIER_COLOR },
+ { 0, 0, 0, 2, 16, 28, SPR_AIRFIELD_HANGAR_REAR },
+ TILE_SEQ_END()
+};
+
+// asphalt tile with fences in north
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_087[] = {
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+// end of runway
+static const DrawTileSeqStruct _station_display_datas_088[] = {
+ { 0, 0, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences
+ TILE_SEQ_END()
+};
+
+// runway tiles
+static const DrawTileSeqStruct _station_display_datas_089[] = {
+ { 0, 0, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences
+ TILE_SEQ_END()
+};
+
+// turning radar with concrete underground fences on south -- needs 12 tiles
+// concrete underground
+//BEGIN
+static const DrawTileSeqStruct _station_display_datas_090[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_1 }, // turning radar
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR }, //fences
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_091[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_2 },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_092[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_3 },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_093[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_4 },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_094[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_5 },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_095[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_6 },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_096[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_7 },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_097[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_8 },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_098[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_9 },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_099[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_A },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0100[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_B },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0101[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_C },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+//END
+
+// turning radar with concrete underground fences on north -- needs 12 tiles
+// concrete underground
+//BEGIN
+static const DrawTileSeqStruct _station_display_datas_0102[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_1 }, // turning radar
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0103[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_2 },
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0104[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_3 },
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0105[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_4 },
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0106[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_5 },
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0107[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_6 },
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0108[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_7 },
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0109[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_8 },
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0110[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_9 },
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0111[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_A },
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0112[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_B },
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0113[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_C },
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+//END
+
+// helipad for international airport
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0114[] = {
+ { 10, 6, 0, 0, 0, 0, SPR_AIRPORT_HELIPAD },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR }, // fences bottom
+ TILE_SEQ_END()
+};
+
+// helipad for commuter airport
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0115[] = {
+ { 10, 6, 0, 0, 0, 0, SPR_AIRPORT_HELIPAD },
+ { 0, 0, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences left
+ TILE_SEQ_END()
+};
+
+// helipad for continental airport
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0116[] = {
+ { 10, 6, 0, 0, 0, 0, SPR_AIRPORT_HELIPAD },
+ TILE_SEQ_END()
+};
+
+// asphalt tile with fences in north and south
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0117[] = {
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+// runway tiles with 2 corner fences
+static const DrawTileSeqStruct _station_display_datas_0118[] = {
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR }, // fences west
+ { 0, 0, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences north
+ TILE_SEQ_END()
+};
+
+// runway tiles with 2 corner fences
+static const DrawTileSeqStruct _station_display_datas_0119[] = {
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR }, // fences west
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences south
+ TILE_SEQ_END()
+};
+
+// runway tiles with 2 corner fences
+static const DrawTileSeqStruct _station_display_datas_0120[] = {
+ { 0, 0, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences north
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR }, // fences east
+ TILE_SEQ_END()
+};
+
+// runway tiles with 2 corner fences
+static const DrawTileSeqStruct _station_display_datas_0121[] = {
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR }, // fences east
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences south
+ TILE_SEQ_END()
+};
+
+// ======== new 2x2 helidepot ========
+// helipad tiles with 2 corner fences top+right
+static const DrawTileSeqStruct _station_display_datas_0122[] = {
+ { 10, 6, 0, 0, 0, 0, SPR_AIRPORT_HELIPAD },
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR }, // fences east
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences south
+ TILE_SEQ_END()
+};
+
+// tarmac tiles with 2 corner fences bottom+right
+static const DrawTileSeqStruct _station_display_datas_0123[] = {
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR }, // fences north
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences south
+ TILE_SEQ_END()
+};
+
+// helidepot office with concrete underground and no fence
+// concrete underground, fences top + left
+static const DrawTileSeqStruct _station_display_datas_0124[] = {
+ { 0, 0, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences left
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR }, // fences east
+ { 3, 3, 0, 10, 10, 60, SPR_AIRPORT_HELIDEPOT_OFFICE | PALETTE_MODIFIER_COLOR }, // helidepot office
+ TILE_SEQ_END()
+};
+
+// N/S runway plain
+static const DrawTileSeqStruct _station_display_datas_0125[] = {
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR }, // fences east
+ TILE_SEQ_END()
+};
+
+// N/S runway end
+static const DrawTileSeqStruct _station_display_datas_0126[] = {
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR }, // fences east
+ TILE_SEQ_END()
+};
+
+// N/S runway plain
+static const DrawTileSeqStruct _station_display_datas_0127[] = {
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR }, // fences bottom
+ TILE_SEQ_END()
+};
+
+// N/S runway end
+static const DrawTileSeqStruct _station_display_datas_0128[] = {
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR }, // fences bottom
+ TILE_SEQ_END()
+};
+
+// West facing hangar
+static const DrawTileSeqStruct _station_display_datas_0129[] = {
+ { 14, 0, 0, 2, 16, 28, SPR_NEWHANGAR_W | PALETTE_MODIFIER_COLOR },
+ { 0, 0, 0, 2, 16, 28, SPR_NEWHANGAR_W_WALL },
+ TILE_SEQ_END()
+};
+
+// North facing hangar
+static const DrawTileSeqStruct _station_display_datas_0130[] = {
+ { 14, 0, 0, 2, 16, 28, SPR_NEWHANGAR_N | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+// East facing hangar
+static const DrawTileSeqStruct _station_display_datas_0131[] = {
+ { 14, 0, 0, 2, 16, 28, SPR_NEWHANGAR_E | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+// helipad for district airport NS
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0132[] = {
+ { 10, 6, 0, 0, 0, 0, SPR_AIRPORT_HELIPAD },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR }, // fences bottom
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences right
+ TILE_SEQ_END()
+};
+
+// helipad for district airport NS
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0133[] = {
+ { 10, 6, 0, 0, 0, 0, SPR_AIRPORT_HELIPAD },
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences south
+ TILE_SEQ_END()
+};
+
+// helidepot office with concrete underground and fence north
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0134[] = {
+ { 0, 0, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences north
+ { 3, 3, 0, 10, 10, 60, SPR_AIRPORT_HELIDEPOT_OFFICE | PALETTE_MODIFIER_COLOR }, // helidepot office
+ TILE_SEQ_END()
+};
+
+// helidepot office with concrete underground and fence east
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0135[] = {
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR }, // fences east
+ { 3, 3, 0, 10, 10, 60, SPR_AIRPORT_HELIDEPOT_OFFICE | PALETTE_MODIFIER_COLOR }, // helidepot office
+ TILE_SEQ_END()
+};
+
+// helidepot office with concrete underground and fence west
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0136[] = {
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR }, // fences west
+ { 3, 3, 0, 10, 10, 60, SPR_AIRPORT_HELIDEPOT_OFFICE | PALETTE_MODIFIER_COLOR }, // helidepot office
+ TILE_SEQ_END()
+};
+
+// helidepot office with concrete underground and fence south
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0137[] = {
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences south
+ { 3, 3, 0, 10, 10, 60, SPR_AIRPORT_HELIDEPOT_OFFICE | PALETTE_MODIFIER_COLOR }, // helidepot office
+ TILE_SEQ_END()
+};
+
+// terminal with fence to east
+static const DrawTileSeqStruct _station_display_datas_0138[] = {
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR }, // fences east
+ TILE_SEQ_END()
+};
+
+// terminal with fence to south
+static const DrawTileSeqStruct _station_display_datas_0139[] = {
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences south
+ TILE_SEQ_END()
+};
+
+// terminal with fence to north
+static const DrawTileSeqStruct _station_display_datas_0140[] = {
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR }, // fences west
+ TILE_SEQ_END()
+};
+
+// concrete with fence to east
+static const DrawTileSeqStruct _station_display_datas_0141[] = {
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR }, // fences east
+ TILE_SEQ_END()
+};
+
+// concrete with fence to south
+static const DrawTileSeqStruct _station_display_datas_0142[] = {
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences south
+ TILE_SEQ_END()
+};
+
+// helipad for district airport EW
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0143[] = {
+ { 10, 6, 0, 0, 0, 0, SPR_AIRPORT_HELIPAD },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR }, // fences west
+ { 0, 0, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences north
+ TILE_SEQ_END()
+};
+
+// helipad for district airport EW
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0144[] = {
+ { 10, 6, 0, 0, 0, 0, SPR_AIRPORT_HELIPAD },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR }, // fences west
+ TILE_SEQ_END()
+};
+
+// turning radar with concrete underground fences on south -- needs 12 tiles
+// concrete underground
+//BEGIN
+static const DrawTileSeqStruct _station_display_datas_0145[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_1 }, // turning radar
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences south
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0146[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_2 },
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences south
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0147[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_3 },
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences south
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0148[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_4 },
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences south
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0149[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_5 },
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences south
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0150[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_6 },
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences south
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0151[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_7 },
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences south
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0152[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_8 },
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences south
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0153[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_9 },
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences south
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0154[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_A },
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences south
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0155[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_B },
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences south
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0156[] = {
+ { 7, 7, 0, 2, 2, 8, SPR_AIRPORT_RADAR_C },
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences south
+ TILE_SEQ_END()
+};
+//END
+
+// helipad for helistation
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0157[] = {
+ { 0, 1, 2, 0, 0, 0, SPR_NEWHELIPAD },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR }, // fences west
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences south
+ TILE_SEQ_END()
+};
+
+// helipad for helistation
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0158[] = {
+ { 0, 1, 2, 0, 0, 0, SPR_NEWHELIPAD },
+ { 15, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR }, // fences west
+ { 0, 0, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences north
+ TILE_SEQ_END()
+};
+
+// helipad for helistation
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0159[] = {
+ { 0, 1, 2, 0, 0, 0, SPR_NEWHELIPAD },
+ { 0, 0, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences north
+ TILE_SEQ_END()
+};
+
+// helidepot office with concrete underground - no fence
+static const DrawTileSeqStruct _station_display_datas_0160[] = {
+ { 3, 3, 0, 10, 10, 60, SPR_AIRPORT_HELIDEPOT_OFFICE | PALETTE_MODIFIER_COLOR }, // helidepot office
+ TILE_SEQ_END()
+};
+
+// concrete underground
+static const DrawTileSeqStruct _station_display_datas_0161[] = {
+ { 0, 0, 0, 1, 16, 6, SPR_AIRPORT_FENCE_Y | PALETTE_MODIFIER_COLOR }, // fences east
+ { 0, 15, 0, 16, 1, 6, SPR_AIRPORT_FENCE_X | PALETTE_MODIFIER_COLOR }, // fences south
+ TILE_SEQ_END()
+};
+
+// half grass half SPR_AIRPORT_APRON
+static const DrawTileSeqStruct _station_display_datas_0162[] = {
+ { 0, 0, 0, 0, 0, 0, SPR_GRASS_LEFT },
+ TILE_SEQ_END()
+};
+
+// half grass half SPR_AIRPORT_APRON
+static const DrawTileSeqStruct _station_display_datas_0163[] = {
+ { 0, 0, 0, 0, 0, 0, SPR_GRASS_RIGHT },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSprites _station_display_datas[] = {
+ { SPR_RAIL_TRACK_X, _station_display_datas_0 },
+ { SPR_RAIL_TRACK_Y, _station_display_datas_1 },
+ { SPR_RAIL_TRACK_X, _station_display_datas_2 },
+ { SPR_RAIL_TRACK_Y, _station_display_datas_3 },
+ { SPR_RAIL_TRACK_X, _station_display_datas_4 },
+ { SPR_RAIL_TRACK_Y, _station_display_datas_5 },
+ { SPR_RAIL_TRACK_X, _station_display_datas_6 },
+ { SPR_RAIL_TRACK_Y, _station_display_datas_7 },
+ { SPR_AIRPORT_APRON, _station_display_datas_8 },
+ { SPR_AIRPORT_APRON, _station_display_datas_9 },
+ { SPR_AIRPORT_APRON, _station_display_datas_10 },
+ { SPR_AIRPORT_AIRCRAFT_STAND, _station_display_datas_11 },
+ { SPR_AIRPORT_TAXIWAY_NS_WEST, _station_display_datas_12 },
+ { SPR_AIRPORT_TAXIWAY_EW_SOUTH, _station_display_datas_13 },
+ { SPR_AIRPORT_TAXIWAY_XING_SOUTH,_station_display_datas_14 },
+ { SPR_AIRPORT_TAXIWAY_XING_WEST, _station_display_datas_15 },
+ { SPR_AIRPORT_TAXIWAY_NS_CTR, _station_display_datas_16 },
+ { SPR_AIRPORT_TAXIWAY_XING_EAST, _station_display_datas_17 },
+ { SPR_AIRPORT_TAXIWAY_NS_EAST, _station_display_datas_18 },
+ { SPR_AIRPORT_TAXIWAY_EW_NORTH, _station_display_datas_19 },
+ { SPR_AIRPORT_TAXIWAY_EW_CTR, _station_display_datas_20 },
+ { SPR_AIRPORT_TAXIWAY_EW_NORTH, _station_display_datas_21 },
+ { SPR_AIRPORT_RUNWAY_EXIT_A, _station_display_datas_22 },
+ { SPR_AIRPORT_RUNWAY_EXIT_B, _station_display_datas_23 },
+ { SPR_AIRPORT_RUNWAY_EXIT_C, _station_display_datas_24 },
+ { SPR_AIRPORT_RUNWAY_EXIT_D, _station_display_datas_25 },
+ { SPR_AIRPORT_RUNWAY_END, _station_display_datas_26 },
+ { SPR_AIRPORT_APRON, _station_display_datas_27 },
+ { SPR_FLAT_GRASS_TILE, _station_display_datas_28 },
+ { SPR_AIRPORT_APRON, _station_display_datas_29 },
+ { SPR_AIRPORT_APRON, _station_display_datas_30 },
+ { SPR_AIRPORT_APRON, _station_display_datas_31 },
+ { SPR_AIRPORT_APRON, _station_display_datas_32 },
+ { SPR_AIRPORT_AIRCRAFT_STAND, _station_display_datas_33 },
+ { SPR_AIRPORT_AIRCRAFT_STAND, _station_display_datas_34 },
+ { SPR_AIRPORT_APRON, _station_display_datas_35 },
+ { SPR_AIRPORT_APRON, _station_display_datas_36 },
+ { SPR_FLAT_GRASS_TILE, _station_display_datas_37 },
+ { SPR_FLAT_GRASS_TILE, _station_display_datas_38 },
+ { SPR_FLAT_GRASS_TILE, _station_display_datas_39 },
+ { SPR_FLAT_GRASS_TILE, _station_display_datas_40 },
+ { SPR_FLAT_GRASS_TILE, _station_display_datas_41 },
+ { SPR_FLAT_GRASS_TILE, _station_display_datas_42 },
+ { SPR_FLAT_GRASS_TILE, _station_display_datas_43 },
+ { SPR_FLAT_GRASS_TILE, _station_display_datas_44 },
+ { SPR_FLAT_GRASS_TILE, _station_display_datas_45 },
+ { SPR_FLAT_GRASS_TILE, _station_display_datas_46 },
+ { SPR_FLAT_GRASS_TILE, _station_display_datas_47 },
+ { SPR_FLAT_GRASS_TILE, _station_display_datas_48 },
+ { SPR_FLAT_GRASS_TILE, _station_display_datas_49 },
+ { SPR_FLAT_GRASS_TILE, _station_display_datas_50 },
+ { SPR_FLAT_GRASS_TILE, _station_display_datas_51 },
+ { SPR_AIRFIELD_TERM_A, _station_display_datas_52 },
+ { SPR_AIRFIELD_TERM_B, _station_display_datas_53 },
+ { SPR_AIRFIELD_TERM_C_GROUND | PALETTE_MODIFIER_COLOR, _station_display_datas_54 },
+ { SPR_AIRFIELD_APRON_A, _station_display_datas_55 },
+ { SPR_AIRFIELD_APRON_B, _station_display_datas_56 },
+ { SPR_AIRFIELD_APRON_C, _station_display_datas_57 },
+ { SPR_AIRFIELD_APRON_D, _station_display_datas_58 },
+ { SPR_AIRFIELD_APRON_D, _station_display_datas_59 },
+ { SPR_AIRFIELD_APRON_D, _station_display_datas_60 },
+ { SPR_AIRFIELD_APRON_D, _station_display_datas_61 },
+ { SPR_AIRFIELD_RUNWAY_NEAR_END, _station_display_datas_62 },
+ { SPR_AIRFIELD_RUNWAY_MIDDLE, _station_display_datas_63 },
+ { SPR_AIRFIELD_RUNWAY_FAR_END, _station_display_datas_64 },
+ { SPR_AIRPORT_APRON, _station_display_datas_65 },
+ { SPR_FLAT_GRASS_TILE, _station_display_datas_66 },
+ { SPR_TRUCK_STOP_NE_GROUND | PALETTE_MODIFIER_COLOR, _station_display_datas_67 },
+ { SPR_TRUCK_STOP_SE_GROUND | PALETTE_MODIFIER_COLOR, _station_display_datas_68 },
+ { SPR_TRUCK_STOP_SW_GROUND | PALETTE_MODIFIER_COLOR, _station_display_datas_69 },
+ { SPR_TRUCK_STOP_NW_GROUND | PALETTE_MODIFIER_COLOR, _station_display_datas_70 },
+ { SPR_BUS_STOP_NE_GROUND | PALETTE_MODIFIER_COLOR, _station_display_datas_71 },
+ { SPR_BUS_STOP_SE_GROUND | PALETTE_MODIFIER_COLOR, _station_display_datas_72 },
+ { SPR_BUS_STOP_SW_GROUND | PALETTE_MODIFIER_COLOR, _station_display_datas_73 },
+ { SPR_BUS_STOP_NW_GROUND | PALETTE_MODIFIER_COLOR, _station_display_datas_74 },
+ { SPR_FLAT_WATER_TILE, _station_display_datas_75 },
+ { SPR_SHORE_TILEH_3, _station_display_datas_76 },
+ { SPR_SHORE_TILEH_9, _station_display_datas_77 },
+ { SPR_SHORE_TILEH_12, _station_display_datas_78 },
+ { SPR_SHORE_TILEH_6, _station_display_datas_79 },
+ { SPR_FLAT_WATER_TILE, _station_display_datas_80 },
+ { SPR_FLAT_WATER_TILE, _station_display_datas_81 },
+ { SPR_BUOY, _station_display_datas_82 },
+ { SPR_AIRPORT_RUNWAY_END, _station_display_datas_083 },
+ { SPR_AIRPORT_RUNWAY_EXIT_B, _station_display_datas_084 },
+ { SPR_AIRPORT_APRON, _station_display_datas_085 },
+ { SPR_AIRPORT_APRON, _station_display_datas_086 },
+ { SPR_AIRPORT_APRON, _station_display_datas_087 },
+ { SPR_AIRPORT_RUNWAY_END, _station_display_datas_088 },
+ { SPR_AIRPORT_RUNWAY_EXIT_B, _station_display_datas_089 },
+ { SPR_AIRPORT_APRON, _station_display_datas_090 },
+ { SPR_AIRPORT_APRON, _station_display_datas_091 },
+ { SPR_AIRPORT_APRON, _station_display_datas_092 },
+ { SPR_AIRPORT_APRON, _station_display_datas_093 },
+ { SPR_AIRPORT_APRON, _station_display_datas_094 },
+ { SPR_AIRPORT_APRON, _station_display_datas_095 },
+ { SPR_AIRPORT_APRON, _station_display_datas_096 },
+ { SPR_AIRPORT_APRON, _station_display_datas_097 },
+ { SPR_AIRPORT_APRON, _station_display_datas_098 },
+ { SPR_AIRPORT_APRON, _station_display_datas_099 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0100 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0101 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0102 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0103 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0104 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0105 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0106 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0107 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0108 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0109 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0110 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0111 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0112 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0113 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0114 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0115 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0116 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0117 },
+ { SPR_AIRPORT_RUNWAY_END, _station_display_datas_0118 },
+ { SPR_AIRPORT_RUNWAY_END, _station_display_datas_0119 },
+ { SPR_AIRPORT_RUNWAY_END, _station_display_datas_0120 },
+ { SPR_AIRPORT_RUNWAY_END, _station_display_datas_0121 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0122 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0123 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0124 },
+ { SPR_NSRUNWAY1, _station_display_datas_0125 },
+ { SPR_NSRUNWAY_END, _station_display_datas_0126 },
+ { SPR_NSRUNWAY1, _station_display_datas_0127 },
+ { SPR_NSRUNWAY_END, _station_display_datas_0128 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0129 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0130 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0131 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0132 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0133 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0134 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0135 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0136 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0137 },
+ { SPR_AIRPORT_AIRCRAFT_STAND, _station_display_datas_0138 },
+ { SPR_AIRPORT_AIRCRAFT_STAND, _station_display_datas_0139 },
+ { SPR_AIRPORT_AIRCRAFT_STAND, _station_display_datas_0140 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0141 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0142 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0143 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0144 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0145 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0146 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0147 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0148 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0149 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0150 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0151 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0152 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0153 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0154 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0155 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0156 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0157 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0158 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0159 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0160 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0161 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0162 },
+ { SPR_AIRPORT_APRON, _station_display_datas_0163 },
+ { SPR_FLAT_GRASS_TILE, _station_display_datas_58 },
+ { SPR_FLAT_GRASS_TILE, _station_display_datas_59 },
+ { SPR_FLAT_GRASS_TILE, _station_display_datas_60 },
+ { SPR_FLAT_GRASS_TILE, _station_display_datas_61 },
+};
diff --git a/src/table/town_land.h b/src/table/town_land.h
new file mode 100644
index 000000000..0a634aa44
--- /dev/null
+++ b/src/table/town_land.h
@@ -0,0 +1,2226 @@
+/* $Id$ */
+
+/** @file town_land.h */
+
+enum {
+ HOUSE_TEMP_CHURCH = 0x03,
+ HOUSE_STADIUM = 0x14,
+ HOUSE_MODERN_STADIUM = 0x20,
+ HOUSE_ARCT_CHURCH = 0x3c,
+ HOUSE_SNOW_CHURCH = 0x3d,
+ HOUSE_TROP_CHURCH = 0x53,
+ HOUSE_TOY_CHURCH = 0x5b,
+
+ HOUSE_MAX = 110
+};
+
+/** Writes the data into the Town Tile Drawing Struct
+ * @param s1 The first sprite of the building, mostly the ground sprite
+ * @param s2 The second sprite of the building.
+ * @param sx The x-position of the sprite within the tile
+ * @param xy the y-position of the sprite within the tile
+ * @param w the width of the sprite
+ * @param h the height of the sprite
+ * @param dz the virtual height of the sprite
+ * @param p set to 1 if a lift is present
+ * @see DrawTownTileStruct
+ */
+#define M(s1, s2, sx, sy, w, h, dz, p) {s1, s2, sx, sy, w - 1, h - 1, dz, p}
+
+static const DrawBuildingsTileStruct _town_draw_tile_data[] = {
+ M( 0xf54, 0x58d, 0, 0, 14, 14, 8, 0),
+ M( 0xf54, 0x58e, 0, 0, 14, 14, 60, 0),
+ M( 0xf54, 0x58f, 0, 0, 14, 14, 60, 0),
+ M( 0x590, 0x58f, 0, 0, 14, 14, 60, 0),
+ M( 0xf54, 0x58d, 0, 0, 14, 14, 8, 0),
+ M( 0xf54, 0x58e, 0, 0, 14, 14, 60, 0),
+ M( 0xf54, 0x591, 0, 0, 14, 14, 60, 0),
+ M( 0x590, 0x591, 0, 0, 14, 14, 60, 0),
+ M( 0xf54, 0x58d | PALETTE_TO_STRUCT_WHITE, 0, 0, 14, 14, 8, 0),
+ M( 0xf54, 0x58e | PALETTE_TO_STRUCT_WHITE, 0, 0, 14, 14, 60, 0),
+ M( 0xf54, 0x591 | PALETTE_TO_STRUCT_WHITE, 0, 0, 14, 14, 60, 0),
+ M( 0x590, 0x591 | PALETTE_TO_STRUCT_WHITE, 0, 0, 14, 14, 60, 0),
+ M( 0xf54, 0x58d | PALETTE_TO_STRUCT_CONCRETE, 0, 0, 14, 14, 8, 0),
+ M( 0xf54, 0x58e | PALETTE_TO_STRUCT_CONCRETE, 0, 0, 14, 14, 60, 0),
+ M( 0xf54, 0x591 | PALETTE_TO_STRUCT_CONCRETE, 0, 0, 14, 14, 60, 0),
+ M( 0x590, 0x591 | PALETTE_TO_STRUCT_CONCRETE, 0, 0, 14, 14, 60, 0),
+ M( 0xf54, 0x592, 0, 0, 14, 16, 11, 0),
+ M( 0xf54, 0x593, 0, 0, 14, 16, 33, 0),
+ M( 0xf54, 0x594, 0, 0, 14, 16, 33, 0),
+ M( 0x595, 0x594, 0, 0, 14, 16, 33, 0),
+ M( 0xf54, 0x592 | PALETTE_TO_STRUCT_WHITE, 0, 0, 16, 16, 11, 0),
+ M( 0xf54, 0x593 | PALETTE_TO_STRUCT_WHITE, 0, 0, 16, 16, 33, 0),
+ M( 0xf54, 0x594 | PALETTE_TO_STRUCT_WHITE, 0, 0, 16, 16, 33, 0),
+ M( 0x595, 0x594 | PALETTE_TO_STRUCT_WHITE, 0, 0, 16, 16, 33, 0),
+ M( 0xf54, 0x592 | PALETTE_TO_STRUCT_CONCRETE, 0, 0, 16, 16, 11, 0),
+ M( 0xf54, 0x593 | PALETTE_TO_STRUCT_CONCRETE, 0, 0, 16, 16, 33, 0),
+ M( 0xf54, 0x594 | PALETTE_TO_STRUCT_CONCRETE, 0, 0, 16, 16, 33, 0),
+ M( 0x595, 0x594 | PALETTE_TO_STRUCT_CONCRETE, 0, 0, 16, 16, 33, 0),
+ M( 0xf54, 0x592 | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 11, 0),
+ M( 0xf54, 0x593 | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 33, 0),
+ M( 0xf54, 0x594 | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 33, 0),
+ M( 0x595, 0x594 | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 33, 0),
+ M( 0xf54, 0x596, 0, 0, 12, 12, 6, 0),
+ M( 0xf54, 0x597, 0, 0, 12, 12, 17, 0),
+ M( 0xf54, 0x598, 0, 0, 12, 12, 17, 0),
+ M( 0x599, 0x598, 0, 0, 12, 12, 17, 0),
+ M( 0xf54, 0x596, 0, 0, 12, 12, 6, 0),
+ M( 0xf54, 0x597, 0, 0, 12, 12, 17, 0),
+ M( 0xf54, 0x598, 0, 0, 12, 12, 17, 0),
+ M( 0x599, 0x598, 0, 0, 12, 12, 17, 0),
+ M( 0xf54, 0x596, 0, 0, 12, 12, 6, 0),
+ M( 0xf54, 0x597, 0, 0, 12, 12, 17, 0),
+ M( 0xf54, 0x598, 0, 0, 12, 12, 17, 0),
+ M( 0x599, 0x598, 0, 0, 12, 12, 17, 0),
+ M( 0xf54, 0x596, 0, 0, 12, 12, 6, 0),
+ M( 0xf54, 0x597, 0, 0, 12, 12, 17, 0),
+ M( 0xf54, 0x598, 0, 0, 12, 12, 17, 0),
+ M( 0x599, 0x598, 0, 0, 12, 12, 17, 0),
+ M( 0xf54, 0x59a, 0, 0, 14, 16, 16, 0),
+ M( 0xf54, 0x59b, 0, 0, 14, 16, 22, 0),
+ M( 0xf54, 0x59c, 0, 0, 14, 16, 35, 0),
+ M( 0x59d, 0x59c, 0, 0, 14, 16, 35, 0),
+ M( 0xf54, 0x59a | PALETTE_59E, 0, 0, 14, 16, 16, 0),
+ M( 0xf54, 0x59b | PALETTE_59E, 0, 0, 14, 16, 22, 0),
+ M( 0xf54, 0x59c | PALETTE_59E, 0, 0, 14, 16, 35, 0),
+ M( 0x59d, 0x59c | PALETTE_59E, 0, 0, 14, 16, 35, 0),
+ M( 0xf54, 0x59a | PALETTE_59F, 0, 0, 14, 16, 16, 0),
+ M( 0xf54, 0x59b | PALETTE_59F, 0, 0, 14, 16, 22, 0),
+ M( 0xf54, 0x59c | PALETTE_59F, 0, 0, 14, 16, 35, 0),
+ M( 0x59d, 0x59c | PALETTE_59F, 0, 0, 14, 16, 35, 0),
+ M( 0xf54, 0x59a | PALETTE_59F, 0, 0, 14, 16, 16, 0),
+ M( 0xf54, 0x59b | PALETTE_59F, 0, 0, 14, 16, 22, 0),
+ M( 0xf54, 0x59c | PALETTE_59F, 0, 0, 14, 16, 35, 0),
+ M( 0x59d, 0x59c | PALETTE_59F, 0, 0, 14, 16, 35, 0),
+ M( 0xf54, 0x5a0, 0, 0, 15, 15, 5, 0),
+ M( 0xf54, 0x5a1, 0, 0, 15, 15, 53, 0),
+ M( 0xf54, 0x5a2, 0, 0, 15, 15, 53, 0),
+ M( 0x58c, 0x5a2, 0, 0, 15, 15, 53, 1),
+ M( 0xf54, 0x5a0, 0, 0, 15, 15, 5, 0),
+ M( 0xf54, 0x5a1, 0, 0, 15, 15, 53, 0),
+ M( 0xf54, 0x5a2, 0, 0, 15, 15, 53, 0),
+ M( 0x58c, 0x5a2, 0, 0, 15, 15, 53, 1),
+ M( 0xf54, 0x5a0, 0, 0, 15, 15, 5, 0),
+ M( 0xf54, 0x5a1, 0, 0, 15, 15, 53, 0),
+ M( 0xf54, 0x5a2, 0, 0, 15, 15, 53, 0),
+ M( 0x58c, 0x5a2, 0, 0, 15, 15, 53, 1),
+ M( 0xf54, 0x5a0, 0, 0, 15, 15, 5, 0),
+ M( 0xf54, 0x5a1, 0, 0, 15, 15, 53, 0),
+ M( 0xf54, 0x5a2, 0, 0, 15, 15, 53, 0),
+ M( 0x58c, 0x5a2, 0, 0, 15, 15, 53, 1),
+ M( 0xf54, 0x5a0, 0, 0, 15, 15, 5, 0),
+ M( 0xf54, 0x5a1, 0, 0, 15, 15, 53, 0),
+ M( 0xf54, 0x11d9, 0, 0, 15, 15, 53, 0),
+ M( 0x58c, 0x11d9, 0, 0, 15, 15, 53, 1),
+ M( 0xf54, 0x5a0, 0, 0, 15, 15, 5, 0),
+ M( 0xf54, 0x5a1, 0, 0, 15, 15, 53, 0),
+ M( 0xf54, 0x11d9, 0, 0, 15, 15, 53, 0),
+ M( 0x58c, 0x11d9, 0, 0, 15, 15, 53, 1),
+ M( 0xf54, 0x5a0, 0, 0, 15, 15, 5, 0),
+ M( 0xf54, 0x5a1, 0, 0, 15, 15, 53, 0),
+ M( 0xf54, 0x11d9, 0, 0, 15, 15, 53, 0),
+ M( 0x58c, 0x11d9, 0, 0, 15, 15, 53, 1),
+ M( 0xf54, 0x5a0, 0, 0, 15, 15, 5, 0),
+ M( 0xf54, 0x5a1, 0, 0, 15, 15, 53, 0),
+ M( 0xf54, 0x11d9, 0, 0, 15, 15, 53, 0),
+ M( 0x58c, 0x11d9, 0, 0, 15, 15, 53, 1),
+ M( 0xf54, 0x5a4, 0, 0, 16, 16, 16, 0),
+ M( 0xf54, 0x5a5, 0, 0, 16, 16, 16, 0),
+ M( 0xf54, 0x5a6, 0, 0, 16, 16, 16, 0),
+ M( 0x5a7, 0x5a6, 0, 0, 16, 16, 16, 0),
+ M( 0xf54, 0x5a4, 0, 0, 16, 16, 16, 0),
+ M( 0xf54, 0x5a5, 0, 0, 16, 16, 16, 0),
+ M( 0xf54, 0x5a6, 0, 0, 16, 16, 16, 0),
+ M( 0x5a7, 0x5a6, 0, 0, 16, 16, 16, 0),
+ M( 0x5dd, 0x5de, 0, 0, 16, 16, 16, 0),
+ M( 0x5df, 0x5e0, 0, 0, 16, 16, 16, 0),
+ M( 0x5e1, 0x5e2, 0, 0, 16, 16, 16, 0),
+ M( 0x5e1, 0x5e2, 0, 0, 16, 16, 16, 0),
+ M( 0x5dd, 0x5de, 0, 0, 16, 16, 16, 0),
+ M( 0x5df, 0x5e0, 0, 0, 16, 16, 16, 0),
+ M( 0x5e1, 0x5e2, 0, 0, 16, 16, 16, 0),
+ M( 0x5e1, 0x5e2, 0, 0, 16, 16, 16, 0),
+ M( 0xf54, 0x5a8, 0, 0, 16, 16, 15, 0),
+ M( 0xf54, 0x5a9, 0, 0, 16, 16, 38, 0),
+ M( 0xf54, 0x5aa, 0, 0, 16, 16, 45, 0),
+ M( 0x58c, 0x5aa, 0, 0, 16, 16, 45, 0),
+ M( 0xf54, 0x5a8, 0, 0, 16, 16, 15, 0),
+ M( 0xf54, 0x5a9, 0, 0, 16, 16, 38, 0),
+ M( 0xf54, 0x5aa, 0, 0, 16, 16, 45, 0),
+ M( 0x58c, 0x5aa, 0, 0, 16, 16, 45, 0),
+ M( 0xf54, 0x5a8, 0, 0, 16, 16, 15, 0),
+ M( 0xf54, 0x5a9, 0, 0, 16, 16, 38, 0),
+ M( 0xf54, 0x5aa, 0, 0, 16, 16, 45, 0),
+ M( 0x58c, 0x5aa, 0, 0, 16, 16, 45, 0),
+ M( 0xf54, 0x5a8, 0, 0, 16, 16, 15, 0),
+ M( 0xf54, 0x5a9, 0, 0, 16, 16, 38, 0),
+ M( 0xf54, 0x5aa, 0, 0, 16, 16, 45, 0),
+ M( 0x58c, 0x5aa, 0, 0, 16, 16, 45, 0),
+ M( 0xf54, 0x5ab, 0, 0, 16, 16, 15, 0),
+ M( 0xf54, 0x5ac, 0, 0, 16, 16, 38, 0),
+ M( 0xf54, 0x5ad, 0, 0, 16, 16, 45, 0),
+ M( 0x58c, 0x5ad, 0, 0, 16, 16, 45, 0),
+ M( 0xf54, 0x5ab, 0, 0, 16, 16, 15, 0),
+ M( 0xf54, 0x5ac, 0, 0, 16, 16, 38, 0),
+ M( 0xf54, 0x5ad, 0, 0, 16, 16, 45, 0),
+ M( 0x58c, 0x5ad, 0, 0, 16, 16, 45, 0),
+ M( 0xf54, 0x5ab, 0, 0, 16, 16, 15, 0),
+ M( 0xf54, 0x5ac, 0, 0, 16, 16, 38, 0),
+ M( 0xf54, 0x5ad, 0, 0, 16, 16, 45, 0),
+ M( 0x58c, 0x5ad, 0, 0, 16, 16, 45, 0),
+ M( 0xf54, 0x5ab, 0, 0, 16, 16, 15, 0),
+ M( 0xf54, 0x5ac, 0, 0, 16, 16, 38, 0),
+ M( 0xf54, 0x5ad, 0, 0, 16, 16, 45, 0),
+ M( 0x58c, 0x5ad, 0, 0, 16, 16, 45, 0),
+ M( 0xf54, 0x0, 6, 5, 3, 6, 8, 0),
+ M( 0x58c, 0x0, 6, 5, 3, 6, 8, 0),
+ M( 0x58c, 0x5ae, 6, 5, 3, 6, 8, 0),
+ M( 0x58c, 0x5ae, 6, 5, 3, 6, 8, 0),
+ M( 0xf54, 0x0, 6, 5, 3, 6, 8, 0),
+ M( 0x58c, 0x0, 6, 5, 3, 6, 8, 0),
+ M( 0x58c, 0x5ae, 6, 5, 3, 6, 8, 0),
+ M( 0x58c, 0x5ae, 6, 5, 3, 6, 8, 0),
+ M( 0xf54, 0x0, 6, 5, 3, 6, 8, 0),
+ M( 0x58c, 0x0, 6, 5, 3, 6, 8, 0),
+ M( 0x58c, 0x5ae, 6, 5, 3, 6, 8, 0),
+ M( 0x58c, 0x5ae, 6, 5, 3, 6, 8, 0),
+ M( 0xf54, 0x0, 6, 5, 3, 6, 8, 0),
+ M( 0x58c, 0x0, 6, 5, 3, 6, 8, 0),
+ M( 0x58c, 0x5ae, 6, 5, 3, 6, 8, 0),
+ M( 0x58c, 0x5ae, 6, 5, 3, 6, 8, 0),
+ M( 0xf54, 0x0, 3, 3, 9, 9, 8, 0),
+ M( 0x58c, 0x0, 3, 3, 9, 9, 8, 0),
+ M( 0x58c, 0x5af, 3, 3, 9, 9, 8, 0),
+ M( 0x58c, 0x5af, 3, 3, 9, 9, 8, 0),
+ M( 0xf54, 0x0, 3, 3, 9, 9, 8, 0),
+ M( 0x58c, 0x0, 3, 3, 9, 9, 8, 0),
+ M( 0x58c, 0x5af, 3, 3, 9, 9, 8, 0),
+ M( 0x58c, 0x5af, 3, 3, 9, 9, 8, 0),
+ M( 0xf54, 0x0, 3, 3, 9, 9, 8, 0),
+ M( 0x58c, 0x0, 3, 3, 9, 9, 8, 0),
+ M( 0x58c, 0x5af, 3, 3, 9, 9, 8, 0),
+ M( 0x58c, 0x5af, 3, 3, 9, 9, 8, 0),
+ M( 0xf54, 0x0, 3, 3, 9, 9, 8, 0),
+ M( 0x58c, 0x0, 3, 3, 9, 9, 8, 0),
+ M( 0x58c, 0x5af, 3, 3, 9, 9, 8, 0),
+ M( 0x58c, 0x5af, 3, 3, 9, 9, 8, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 15, 0),
+ M( 0xf8d, 0x5b0, 0, 0, 16, 16, 15, 0),
+ M( 0xf8d, 0x5b0, 0, 0, 16, 16, 15, 0),
+ M( 0xf8d, 0x5b0, 0, 0, 16, 16, 15, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 15, 0),
+ M( 0xf8d, 0x5b0, 0, 0, 16, 16, 15, 0),
+ M( 0xf8d, 0x5b0, 0, 0, 16, 16, 15, 0),
+ M( 0xf8d, 0x5b0, 0, 0, 16, 16, 15, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 15, 0),
+ M( 0xf8d, 0x5b0, 0, 0, 16, 16, 15, 0),
+ M( 0xf8d, 0x5b0, 0, 0, 16, 16, 15, 0),
+ M( 0xf8d, 0x5b0, 0, 0, 16, 16, 15, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 15, 0),
+ M( 0xf8d, 0x5b0, 0, 0, 16, 16, 15, 0),
+ M( 0xf8d, 0x5b0, 0, 0, 16, 16, 15, 0),
+ M( 0xf8d, 0x5b0, 0, 0, 16, 16, 15, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 15, 0),
+ M( 0xf8d, 0x5b1, 0, 0, 16, 16, 15, 0),
+ M( 0xf8d, 0x5b1, 0, 0, 16, 16, 15, 0),
+ M( 0xf8d, 0x5b1, 0, 0, 16, 16, 15, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 15, 0),
+ M( 0xf8d, 0x5b1, 0, 0, 16, 16, 15, 0),
+ M( 0xf8d, 0x5b1, 0, 0, 16, 16, 15, 0),
+ M( 0xf8d, 0x5b1, 0, 0, 16, 16, 15, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 15, 0),
+ M( 0xf8d, 0x5b1, 0, 0, 16, 16, 15, 0),
+ M( 0xf8d, 0x5b1, 0, 0, 16, 16, 15, 0),
+ M( 0xf8d, 0x5b1, 0, 0, 16, 16, 15, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 15, 0),
+ M( 0xf8d, 0x5b1, 0, 0, 16, 16, 15, 0),
+ M( 0xf8d, 0x5b1, 0, 0, 16, 16, 15, 0),
+ M( 0xf8d, 0x5b1, 0, 0, 16, 16, 15, 0),
+ M( 0xf54, 0x5b2, 0, 0, 16, 16, 8, 0),
+ M( 0xf54, 0x5b3, 0, 0, 16, 16, 42, 0),
+ M( 0xf54, 0x5b4, 0, 0, 16, 16, 42, 0),
+ M( 0x58c, 0x5b4, 0, 0, 16, 16, 42, 0),
+ M( 0xf54, 0x5b2 | PALETTE_TO_STRUCT_WHITE, 0, 0, 16, 16, 8, 0),
+ M( 0xf54, 0x5b3 | PALETTE_TO_STRUCT_WHITE, 0, 0, 16, 16, 42, 0),
+ M( 0xf54, 0x5b4 | PALETTE_TO_STRUCT_WHITE, 0, 0, 16, 16, 42, 0),
+ M( 0x58c, 0x5b4 | PALETTE_TO_STRUCT_WHITE, 0, 0, 16, 16, 42, 0),
+ M( 0xf54, 0x5b2 | PALETTE_TO_STRUCT_RED, 0, 0, 16, 16, 8, 0),
+ M( 0xf54, 0x5b3 | PALETTE_TO_STRUCT_RED, 0, 0, 16, 16, 42, 0),
+ M( 0xf54, 0x5b4 | PALETTE_TO_STRUCT_RED, 0, 0, 16, 16, 42, 0),
+ M( 0x58c, 0x5b4 | PALETTE_TO_STRUCT_RED, 0, 0, 16, 16, 42, 0),
+ M( 0xf54, 0x5b2 | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 8, 0),
+ M( 0xf54, 0x5b3 | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 42, 0),
+ M( 0xf54, 0x5b4 | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 42, 0),
+ M( 0x58c, 0x5b4 | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 42, 0),
+ M( 0xf54, 0x5b5, 1, 3, 14, 11, 7, 0),
+ M( 0xf54, 0x5b6, 1, 3, 14, 11, 53, 0),
+ M( 0xf54, 0x5b7, 1, 3, 14, 11, 53, 0),
+ M( 0x58c, 0x5b7, 1, 3, 14, 11, 53, 0),
+ M( 0xf54, 0x5b5, 1, 3, 14, 11, 7, 0),
+ M( 0xf54, 0x5b6, 1, 3, 14, 11, 53, 0),
+ M( 0xf54, 0x5b7, 1, 3, 14, 11, 53, 0),
+ M( 0x58c, 0x5b7, 1, 3, 14, 11, 53, 0),
+ M( 0xf54, 0x5b5, 1, 3, 14, 11, 7, 0),
+ M( 0xf54, 0x5b6, 1, 3, 14, 11, 53, 0),
+ M( 0xf54, 0x5b7, 1, 3, 14, 11, 53, 0),
+ M( 0x58c, 0x5b7, 1, 3, 14, 11, 53, 0),
+ M( 0xf54, 0x5b5, 1, 3, 14, 11, 7, 0),
+ M( 0xf54, 0x5b6, 1, 3, 14, 11, 53, 0),
+ M( 0xf54, 0x5b7, 1, 3, 14, 11, 53, 0),
+ M( 0x58c, 0x5b7, 1, 3, 14, 11, 53, 0),
+ M( 0xf54, 0x5b8, 3, 1, 11, 14, 6, 0),
+ M( 0xf54, 0x5b9, 3, 1, 11, 14, 28, 0),
+ M( 0xf54, 0x5ba, 3, 1, 11, 14, 28, 0),
+ M( 0x58c, 0x5ba, 3, 1, 11, 14, 28, 0),
+ M( 0xf54, 0x5b8, 3, 1, 11, 14, 6, 0),
+ M( 0xf54, 0x5b9, 3, 1, 11, 14, 28, 0),
+ M( 0xf54, 0x5ba, 3, 1, 11, 14, 28, 0),
+ M( 0x58c, 0x5ba, 3, 1, 11, 14, 28, 0),
+ M( 0xf54, 0x5b8, 3, 1, 11, 14, 6, 0),
+ M( 0xf54, 0x5b9, 3, 1, 11, 14, 28, 0),
+ M( 0xf54, 0x5ba, 3, 1, 11, 14, 28, 0),
+ M( 0x58c, 0x5ba, 3, 1, 11, 14, 28, 0),
+ M( 0xf54, 0x5b8, 3, 1, 11, 14, 6, 0),
+ M( 0xf54, 0x5b9, 3, 1, 11, 14, 28, 0),
+ M( 0xf54, 0x5ba, 3, 1, 11, 14, 28, 0),
+ M( 0x58c, 0x5ba, 3, 1, 11, 14, 28, 0),
+ M( 0xf54, 0x5bb, 2, 0, 13, 16, 6, 0),
+ M( 0xf54, 0x5bc, 2, 0, 13, 16, 45, 0),
+ M( 0xf54, 0x5bd, 2, 0, 13, 16, 46, 0),
+ M( 0x58c, 0x5bd, 2, 0, 13, 16, 46, 0),
+ M( 0xf54, 0x5bb, 2, 0, 13, 16, 6, 0),
+ M( 0xf54, 0x5bc, 2, 0, 13, 16, 45, 0),
+ M( 0xf54, 0x5bd, 2, 0, 13, 16, 46, 0),
+ M( 0x58c, 0x5bd, 2, 0, 13, 16, 46, 0),
+ M( 0xf54, 0x5bb | PALETTE_TO_STRUCT_BLUE, 2, 0, 13, 16, 6, 0),
+ M( 0xf54, 0x5bc | PALETTE_TO_STRUCT_BLUE, 2, 0, 13, 16, 45, 0),
+ M( 0xf54, 0x5bd | PALETTE_TO_STRUCT_BLUE, 2, 0, 13, 16, 46, 0),
+ M( 0x58c, 0x5bd | PALETTE_TO_STRUCT_BLUE, 2, 0, 13, 16, 46, 0),
+ M( 0xf54, 0x5bb | PALETTE_TO_STRUCT_WHITE, 2, 0, 13, 16, 6, 0),
+ M( 0xf54, 0x5bc | PALETTE_TO_STRUCT_WHITE, 2, 0, 13, 16, 45, 0),
+ M( 0xf54, 0x5bd | PALETTE_TO_STRUCT_WHITE, 2, 0, 13, 16, 46, 0),
+ M( 0x58c, 0x5bd | PALETTE_TO_STRUCT_WHITE, 2, 0, 13, 16, 46, 0),
+ M( 0xf54, 0x5be | PALETTE_TO_RED, 2, 0, 13, 16, 13, 0),
+ M( 0xf54, 0x5bf | PALETTE_TO_RED, 2, 0, 13, 16, 110, 0),
+ M( 0xf54, 0x5c0 | PALETTE_TO_RED, 2, 0, 13, 16, 110, 0),
+ M( 0x58c, 0x5c0 | PALETTE_TO_RED, 2, 0, 13, 16, 110, 0),
+ M( 0xf54, 0x5be | PALETTE_TO_BLUE, 2, 0, 13, 16, 13, 0),
+ M( 0xf54, 0x5bf | PALETTE_TO_BLUE, 2, 0, 13, 16, 110, 0),
+ M( 0xf54, 0x5c0 | PALETTE_TO_BLUE, 2, 0, 13, 16, 110, 0),
+ M( 0x58c, 0x5c0 | PALETTE_TO_BLUE, 2, 0, 13, 16, 110, 0),
+ M( 0xf54, 0x5be | PALETTE_TO_ORANGE, 2, 0, 13, 16, 13, 0),
+ M( 0xf54, 0x5bf | PALETTE_TO_ORANGE, 2, 0, 13, 16, 110, 0),
+ M( 0xf54, 0x5c0 | PALETTE_TO_ORANGE, 2, 0, 13, 16, 110, 0),
+ M( 0x58c, 0x5c0 | PALETTE_TO_ORANGE, 2, 0, 13, 16, 110, 0),
+ M( 0xf54, 0x5be | PALETTE_TO_GREEN, 2, 0, 13, 16, 13, 0),
+ M( 0xf54, 0x5bf | PALETTE_TO_GREEN, 2, 0, 13, 16, 110, 0),
+ M( 0xf54, 0x5c0 | PALETTE_TO_GREEN, 2, 0, 13, 16, 110, 0),
+ M( 0x58c, 0x5c0 | PALETTE_TO_GREEN, 2, 0, 13, 16, 110, 0),
+ M( 0xf54, 0x5c1, 1, 2, 15, 12, 4, 0),
+ M( 0xf54, 0x5c2, 1, 2, 15, 12, 24, 0),
+ M( 0xf54, 0x5c3, 1, 2, 15, 12, 31, 0),
+ M( 0x58c, 0x5c3, 1, 2, 15, 12, 31, 0),
+ M( 0xf54, 0x5c1, 1, 2, 15, 12, 4, 0),
+ M( 0xf54, 0x5c2, 1, 2, 15, 12, 24, 0),
+ M( 0xf54, 0x5c3, 1, 2, 15, 12, 31, 0),
+ M( 0x58c, 0x5c3, 1, 2, 15, 12, 31, 0),
+ M( 0xf54, 0x5c1, 1, 2, 15, 12, 4, 0),
+ M( 0xf54, 0x5c2, 1, 2, 15, 12, 24, 0),
+ M( 0xf54, 0x5c3, 1, 2, 15, 12, 31, 0),
+ M( 0x58c, 0x5c3, 1, 2, 15, 12, 31, 0),
+ M( 0xf54, 0x5c1, 1, 2, 15, 12, 4, 0),
+ M( 0xf54, 0x5c2, 1, 2, 15, 12, 24, 0),
+ M( 0xf54, 0x5c3, 1, 2, 15, 12, 31, 0),
+ M( 0x58c, 0x5c3, 1, 2, 15, 12, 31, 0),
+ M( 0xf54, 0x5c4, 1, 0, 14, 15, 20, 0),
+ M( 0xf54, 0x5c5, 1, 0, 14, 15, 42, 0),
+ M( 0xf54, 0x5c6, 1, 0, 14, 15, 42, 0),
+ M( 0x58c, 0x5c6, 1, 0, 14, 15, 42, 0),
+ M( 0xf54, 0x5c4, 1, 0, 14, 15, 20, 0),
+ M( 0xf54, 0x5c5, 1, 0, 14, 15, 42, 0),
+ M( 0xf54, 0x5c6, 1, 0, 14, 15, 42, 0),
+ M( 0x58c, 0x5c6, 1, 0, 14, 15, 42, 0),
+ M( 0xf54, 0x5c4, 1, 0, 14, 15, 20, 0),
+ M( 0xf54, 0x5c5, 1, 0, 14, 15, 42, 0),
+ M( 0xf54, 0x5c6, 1, 0, 14, 15, 42, 0),
+ M( 0x58c, 0x5c6, 1, 0, 14, 15, 42, 0),
+ M( 0xf54, 0x5c4, 1, 0, 14, 15, 20, 0),
+ M( 0xf54, 0x5c5, 1, 0, 14, 15, 42, 0),
+ M( 0xf54, 0x5c6, 1, 0, 14, 15, 42, 0),
+ M( 0x58c, 0x5c6, 1, 0, 14, 15, 42, 0),
+ M( 0x5c7, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x5c7, 0x5cb, 0, 0, 16, 16, 20, 0),
+ M( 0x5c7, 0x5cb, 0, 0, 16, 16, 20, 0),
+ M( 0x5c7, 0x5cb, 0, 0, 16, 16, 20, 0),
+ M( 0x5c7, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x5c7, 0x5cb, 0, 0, 16, 16, 20, 0),
+ M( 0x5c7, 0x5cb, 0, 0, 16, 16, 20, 0),
+ M( 0x5c7, 0x5cb, 0, 0, 16, 16, 20, 0),
+ M( 0x5c7, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x5c7, 0x5cb, 0, 0, 16, 16, 20, 0),
+ M( 0x5c7, 0x5cb, 0, 0, 16, 16, 20, 0),
+ M( 0x5c7, 0x5cb, 0, 0, 16, 16, 20, 0),
+ M( 0x5c7, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x5c7, 0x5cb, 0, 0, 16, 16, 20, 0),
+ M( 0x5c7, 0x5cb, 0, 0, 16, 16, 20, 0),
+ M( 0x5c7, 0x5cb, 0, 0, 16, 16, 20, 0),
+ M( 0x5c8, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x5c8, 0x5cc, 0, 0, 16, 16, 20, 0),
+ M( 0x5c8, 0x5cc, 0, 0, 16, 16, 20, 0),
+ M( 0x5c8, 0x5cc, 0, 0, 16, 16, 20, 0),
+ M( 0x5c8, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x5c8, 0x5cc, 0, 0, 16, 16, 20, 0),
+ M( 0x5c8, 0x5cc, 0, 0, 16, 16, 20, 0),
+ M( 0x5c8, 0x5cc, 0, 0, 16, 16, 20, 0),
+ M( 0x5c8, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x5c8, 0x5cc, 0, 0, 16, 16, 20, 0),
+ M( 0x5c8, 0x5cc, 0, 0, 16, 16, 20, 0),
+ M( 0x5c8, 0x5cc, 0, 0, 16, 16, 20, 0),
+ M( 0x5c8, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x5c8, 0x5cc, 0, 0, 16, 16, 20, 0),
+ M( 0x5c8, 0x5cc, 0, 0, 16, 16, 20, 0),
+ M( 0x5c8, 0x5cc, 0, 0, 16, 16, 20, 0),
+ M( 0x5c9, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x5c9, 0x5cd, 0, 0, 16, 16, 20, 0),
+ M( 0x5c9, 0x5cd, 0, 0, 16, 16, 20, 0),
+ M( 0x5c9, 0x5cd, 0, 0, 16, 16, 20, 0),
+ M( 0x5c9, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x5c9, 0x5cd, 0, 0, 16, 16, 20, 0),
+ M( 0x5c9, 0x5cd, 0, 0, 16, 16, 20, 0),
+ M( 0x5c9, 0x5cd, 0, 0, 16, 16, 20, 0),
+ M( 0x5c9, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x5c9, 0x5cd, 0, 0, 16, 16, 20, 0),
+ M( 0x5c9, 0x5cd, 0, 0, 16, 16, 20, 0),
+ M( 0x5c9, 0x5cd, 0, 0, 16, 16, 20, 0),
+ M( 0x5c9, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x5c9, 0x5cd, 0, 0, 16, 16, 20, 0),
+ M( 0x5c9, 0x5cd, 0, 0, 16, 16, 20, 0),
+ M( 0x5c9, 0x5cd, 0, 0, 16, 16, 20, 0),
+ M( 0x5ca, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x5ca, 0x5ce, 0, 0, 16, 16, 20, 0),
+ M( 0x5ca, 0x5ce, 0, 0, 16, 16, 20, 0),
+ M( 0x5ca, 0x5ce, 0, 0, 16, 16, 20, 0),
+ M( 0x5ca, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x5ca, 0x5ce, 0, 0, 16, 16, 20, 0),
+ M( 0x5ca, 0x5ce, 0, 0, 16, 16, 20, 0),
+ M( 0x5ca, 0x5ce, 0, 0, 16, 16, 20, 0),
+ M( 0x5ca, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x5ca, 0x5ce, 0, 0, 16, 16, 20, 0),
+ M( 0x5ca, 0x5ce, 0, 0, 16, 16, 20, 0),
+ M( 0x5ca, 0x5ce, 0, 0, 16, 16, 20, 0),
+ M( 0x5ca, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x5ca, 0x5ce, 0, 0, 16, 16, 20, 0),
+ M( 0x5ca, 0x5ce, 0, 0, 16, 16, 20, 0),
+ M( 0x5ca, 0x5ce, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x5d4, 0, 0, 16, 16, 22, 0),
+ M( 0x5d3, 0x5d4, 0, 0, 16, 16, 22, 0),
+ M( 0x5d3, 0x5d4, 0, 0, 16, 16, 22, 0),
+ M( 0x5d3, 0x5d4, 0, 0, 16, 16, 22, 0),
+ M( 0xf54, 0x5d6, 0, 0, 16, 16, 22, 0),
+ M( 0x5d5, 0x5d6, 0, 0, 16, 16, 22, 0),
+ M( 0x5d5, 0x5d6, 0, 0, 16, 16, 22, 0),
+ M( 0x5d5, 0x5d6, 0, 0, 16, 16, 22, 0),
+ M( 0xf54, 0x5d0, 0, 0, 16, 16, 21, 0),
+ M( 0x5cf, 0x5d0, 0, 0, 16, 16, 21, 0),
+ M( 0x5cf, 0x5d0, 0, 0, 16, 16, 21, 0),
+ M( 0x5cf, 0x5d0, 0, 0, 16, 16, 21, 0),
+ M( 0xf54, 0x5d2, 0, 0, 16, 16, 11, 0),
+ M( 0x5d1, 0x5d2, 0, 0, 16, 16, 11, 0),
+ M( 0x5d1, 0x5d2, 0, 0, 16, 16, 11, 0),
+ M( 0x5d1, 0x5d2, 0, 0, 16, 16, 11, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M( 0x5d7, 0x5d8, 0, 0, 16, 16, 22, 0),
+ M( 0x5d7, 0x5d8, 0, 0, 16, 16, 22, 0),
+ M( 0x5d7, 0x5d8, 0, 0, 16, 16, 22, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M( 0x5d7, 0x5d8, 0, 0, 16, 16, 22, 0),
+ M( 0x5d7, 0x5d8, 0, 0, 16, 16, 22, 0),
+ M( 0x5d7, 0x5d8, 0, 0, 16, 16, 22, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M( 0x5d7, 0x5d8, 0, 0, 16, 16, 22, 0),
+ M( 0x5d7, 0x5d8, 0, 0, 16, 16, 22, 0),
+ M( 0x5d7, 0x5d8, 0, 0, 16, 16, 22, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M( 0x5d7, 0x5d8, 0, 0, 16, 16, 22, 0),
+ M( 0x5d7, 0x5d8, 0, 0, 16, 16, 22, 0),
+ M( 0x5d7, 0x5d8, 0, 0, 16, 16, 22, 0),
+ M( 0x5d9, 0x0, 0, 0, 16, 16, 22, 0),
+ M( 0x5da, 0x0, 0, 0, 16, 16, 22, 0),
+ M( 0x5db, 0x5dc, 0, 0, 16, 16, 22, 0),
+ M( 0x5db, 0x5dc, 0, 0, 16, 16, 22, 0),
+ M( 0x622, 0x623, 0, 0, 16, 16, 22, 0),
+ M( 0x624, 0x625, 0, 0, 16, 16, 22, 0),
+ M( 0x626, 0x627, 0, 0, 16, 16, 22, 0),
+ M( 0x626, 0x627, 0, 0, 16, 16, 22, 0),
+ M( 0x5e3, 0x5e4, 0, 0, 16, 16, 22, 0),
+ M( 0x5e5, 0x5e6, 0, 0, 16, 16, 22, 0),
+ M( 0x5e7, 0x5e8, 0, 0, 16, 16, 22, 0),
+ M( 0x5e7, 0x5e8, 0, 0, 16, 16, 22, 0),
+ M( 0x5e9, 0x5ea, 0, 0, 16, 16, 22, 0),
+ M( 0x5eb, 0x5ec, 0, 0, 16, 16, 22, 0),
+ M( 0x5ed, 0x5ee, 0, 0, 16, 16, 22, 0),
+ M( 0x5ed, 0x5ee, 0, 0, 16, 16, 22, 0),
+ M( 0x5ef, 0x0, 0, 0, 16, 16, 22, 0),
+ M( 0x5f0, 0x5f1, 0, 0, 16, 16, 22, 0),
+ M( 0x5f2, 0x5f3, 0, 0, 16, 16, 22, 0),
+ M( 0x5f2, 0x5f3, 0, 0, 16, 16, 22, 0),
+ M( 0x5ef, 0x0, 0, 0, 16, 16, 22, 0),
+ M( 0x5f0, 0x5f1, 0, 0, 16, 16, 22, 0),
+ M( 0x5f2, 0x5f3, 0, 0, 16, 16, 22, 0),
+ M( 0x5f2, 0x5f3, 0, 0, 16, 16, 22, 0),
+ M( 0x5f4, 0x5f5, 0, 0, 16, 16, 22, 0),
+ M( 0x5f6, 0x5f7, 0, 0, 16, 16, 22, 0),
+ M( 0x5f8, 0x5f9, 0, 0, 16, 16, 22, 0),
+ M( 0x5f8, 0x5f9, 0, 0, 16, 16, 22, 0),
+ M( 0x5f4, 0x5f5, 0, 0, 16, 16, 22, 0),
+ M( 0x5f6, 0x5f7, 0, 0, 16, 16, 22, 0),
+ M( 0x5f8, 0x5f9, 0, 0, 16, 16, 22, 0),
+ M( 0x5f8, 0x5f9, 0, 0, 16, 16, 22, 0),
+ M( 0x5fa, 0x5fb, 0, 0, 16, 16, 85, 0),
+ M( 0x5fc, 0x5fd, 0, 0, 16, 16, 85, 0),
+ M( 0x5fe, 0x5ff, 0, 0, 16, 16, 85, 0),
+ M( 0x5fe, 0x5ff, 0, 0, 16, 16, 85, 0),
+ M( 0x5fa, 0x5fb, 0, 0, 16, 16, 85, 0),
+ M( 0x5fc, 0x5fd, 0, 0, 16, 16, 85, 0),
+ M( 0x5fe, 0x5ff, 0, 0, 16, 16, 85, 0),
+ M( 0x5fe, 0x5ff, 0, 0, 16, 16, 85, 0),
+ M( 0x60a, 0x60b, 0, 0, 16, 16, 95, 0),
+ M( 0x60c, 0x60d, 0, 0, 16, 16, 95, 0),
+ M( 0x60e, 0x60f, 0, 0, 16, 16, 95, 0),
+ M( 0x60e, 0x60f, 0, 0, 16, 16, 95, 0),
+ M( 0x60a, 0x60b, 0, 0, 16, 16, 95, 0),
+ M( 0x60c, 0x60d, 0, 0, 16, 16, 95, 0),
+ M( 0x60e, 0x60f, 0, 0, 16, 16, 95, 0),
+ M( 0x60e, 0x60f, 0, 0, 16, 16, 95, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M( 0x600, 0x601, 0, 0, 16, 16, 55, 0),
+ M( 0x600, 0x601, 0, 0, 16, 16, 55, 0),
+ M( 0x600, 0x601, 0, 0, 16, 16, 55, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M( 0x600 | PALETTE_TO_STRUCT_WHITE, 0x601 | PALETTE_TO_STRUCT_WHITE, 0, 0, 16, 16, 55, 0),
+ M( 0x600 | PALETTE_TO_STRUCT_WHITE, 0x601 | PALETTE_TO_STRUCT_WHITE, 0, 0, 16, 16, 55, 0),
+ M( 0x600 | PALETTE_TO_STRUCT_WHITE, 0x601 | PALETTE_TO_STRUCT_WHITE, 0, 0, 16, 16, 55, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M( 0x602, 0x603, 0, 0, 16, 16, 42, 0),
+ M( 0x602, 0x603, 0, 0, 16, 16, 42, 0),
+ M( 0x602, 0x603, 0, 0, 16, 16, 42, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M( 0x602 | PALETTE_TO_STRUCT_CONCRETE, 0x603 | PALETTE_TO_STRUCT_CONCRETE, 0, 0, 16, 16, 42, 0),
+ M( 0x602 | PALETTE_TO_STRUCT_CONCRETE, 0x603 | PALETTE_TO_STRUCT_CONCRETE, 0, 0, 16, 16, 42, 0),
+ M( 0x602 | PALETTE_TO_STRUCT_CONCRETE, 0x603 | PALETTE_TO_STRUCT_CONCRETE, 0, 0, 16, 16, 42, 0),
+ M( 0x604, 0x605, 0, 0, 16, 16, 88, 0),
+ M( 0x606, 0x607, 0, 0, 16, 16, 88, 0),
+ M( 0x608, 0x609, 0, 0, 16, 16, 88, 0),
+ M( 0x608, 0x609, 0, 0, 16, 16, 88, 0),
+ M( 0x604, 0x605, 0, 0, 16, 16, 88, 0),
+ M( 0x606, 0x607, 0, 0, 16, 16, 88, 0),
+ M( 0x608, 0x609, 0, 0, 16, 16, 88, 0),
+ M( 0x608, 0x609, 0, 0, 16, 16, 88, 0),
+ M( 0x604, 0x605, 0, 0, 16, 16, 88, 0),
+ M( 0x606, 0x607, 0, 0, 16, 16, 88, 0),
+ M( 0x608, 0x609, 0, 0, 16, 16, 88, 0),
+ M( 0x608, 0x609, 0, 0, 16, 16, 88, 0),
+ M( 0x604, 0x605, 0, 0, 16, 16, 88, 0),
+ M( 0x606, 0x607, 0, 0, 16, 16, 88, 0),
+ M( 0x608, 0x609, 0, 0, 16, 16, 88, 0),
+ M( 0x608, 0x609, 0, 0, 16, 16, 88, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M( 0x610, 0x611, 0, 0, 16, 16, 40, 0),
+ M( 0x610, 0x611, 0, 0, 16, 16, 40, 0),
+ M( 0x610, 0x611, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M( 0x610, 0x611, 0, 0, 16, 16, 40, 0),
+ M( 0x610, 0x611, 0, 0, 16, 16, 40, 0),
+ M( 0x610, 0x611, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M( 0x610, 0x611, 0, 0, 16, 16, 40, 0),
+ M( 0x610, 0x611, 0, 0, 16, 16, 40, 0),
+ M( 0x610, 0x611, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M( 0x610, 0x611, 0, 0, 16, 16, 40, 0),
+ M( 0x610, 0x611, 0, 0, 16, 16, 40, 0),
+ M( 0x610, 0x611, 0, 0, 16, 16, 40, 0),
+ M( 0x612, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x612, 0x616, 0, 0, 16, 16, 20, 0),
+ M( 0x612, 0x616, 0, 0, 16, 16, 20, 0),
+ M( 0x612, 0x616, 0, 0, 16, 16, 20, 0),
+ M( 0x612, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x612, 0x616, 0, 0, 16, 16, 20, 0),
+ M( 0x612, 0x616, 0, 0, 16, 16, 20, 0),
+ M( 0x612, 0x616, 0, 0, 16, 16, 20, 0),
+ M( 0x612, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x612, 0x616, 0, 0, 16, 16, 20, 0),
+ M( 0x612, 0x616, 0, 0, 16, 16, 20, 0),
+ M( 0x612, 0x616, 0, 0, 16, 16, 20, 0),
+ M( 0x612, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x612, 0x616, 0, 0, 16, 16, 20, 0),
+ M( 0x612, 0x616, 0, 0, 16, 16, 20, 0),
+ M( 0x612, 0x616, 0, 0, 16, 16, 20, 0),
+ M( 0x613, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x613, 0x617, 0, 0, 16, 16, 20, 0),
+ M( 0x613, 0x617, 0, 0, 16, 16, 20, 0),
+ M( 0x613, 0x617, 0, 0, 16, 16, 20, 0),
+ M( 0x613, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x613, 0x617, 0, 0, 16, 16, 20, 0),
+ M( 0x613, 0x617, 0, 0, 16, 16, 20, 0),
+ M( 0x613, 0x617, 0, 0, 16, 16, 20, 0),
+ M( 0x613, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x613, 0x617, 0, 0, 16, 16, 20, 0),
+ M( 0x613, 0x617, 0, 0, 16, 16, 20, 0),
+ M( 0x613, 0x617, 0, 0, 16, 16, 20, 0),
+ M( 0x613, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x613, 0x617, 0, 0, 16, 16, 20, 0),
+ M( 0x613, 0x617, 0, 0, 16, 16, 20, 0),
+ M( 0x613, 0x617, 0, 0, 16, 16, 20, 0),
+ M( 0x614, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x614, 0x618, 0, 0, 16, 16, 20, 0),
+ M( 0x614, 0x618, 0, 0, 16, 16, 20, 0),
+ M( 0x614, 0x618, 0, 0, 16, 16, 20, 0),
+ M( 0x614, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x614, 0x618, 0, 0, 16, 16, 20, 0),
+ M( 0x614, 0x618, 0, 0, 16, 16, 20, 0),
+ M( 0x614, 0x618, 0, 0, 16, 16, 20, 0),
+ M( 0x614, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x614, 0x618, 0, 0, 16, 16, 20, 0),
+ M( 0x614, 0x618, 0, 0, 16, 16, 20, 0),
+ M( 0x614, 0x618, 0, 0, 16, 16, 20, 0),
+ M( 0x614, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x614, 0x618, 0, 0, 16, 16, 20, 0),
+ M( 0x614, 0x618, 0, 0, 16, 16, 20, 0),
+ M( 0x614, 0x618, 0, 0, 16, 16, 20, 0),
+ M( 0x615, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x615, 0x619, 0, 0, 16, 16, 20, 0),
+ M( 0x615, 0x619, 0, 0, 16, 16, 20, 0),
+ M( 0x615, 0x619, 0, 0, 16, 16, 20, 0),
+ M( 0x615, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x615, 0x619, 0, 0, 16, 16, 20, 0),
+ M( 0x615, 0x619, 0, 0, 16, 16, 20, 0),
+ M( 0x615, 0x619, 0, 0, 16, 16, 20, 0),
+ M( 0x615, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x615, 0x619, 0, 0, 16, 16, 20, 0),
+ M( 0x615, 0x619, 0, 0, 16, 16, 20, 0),
+ M( 0x615, 0x619, 0, 0, 16, 16, 20, 0),
+ M( 0x615, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0x615, 0x619, 0, 0, 16, 16, 20, 0),
+ M( 0x615, 0x619, 0, 0, 16, 16, 20, 0),
+ M( 0x615, 0x619, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M( 0x61a, 0x61b, 0, 0, 16, 16, 100, 0),
+ M( 0x61a, 0x61b, 0, 0, 16, 16, 100, 0),
+ M( 0x61c, 0x61d, 0, 0, 16, 16, 100, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M( 0x61a, 0x61b, 0, 0, 16, 16, 100, 0),
+ M( 0x61a, 0x61b, 0, 0, 16, 16, 100, 0),
+ M( 0x61c, 0x61d, 0, 0, 16, 16, 100, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M( 0x61a, 0x61b, 0, 0, 16, 16, 100, 0),
+ M( 0x61a, 0x61b, 0, 0, 16, 16, 100, 0),
+ M( 0x61c, 0x61d, 0, 0, 16, 16, 100, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M( 0x61a, 0x61b, 0, 0, 16, 16, 100, 0),
+ M( 0x61a, 0x61b, 0, 0, 16, 16, 100, 0),
+ M( 0x61c, 0x61d, 0, 0, 16, 16, 100, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M( 0x61e, 0x61f, 0, 0, 16, 16, 25, 0),
+ M( 0x61e, 0x61f, 0, 0, 16, 16, 25, 0),
+ M( 0x61e, 0x61f, 0, 0, 16, 16, 25, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M( 0x61e | PALETTE_TO_STRUCT_WHITE, 0x61f | PALETTE_TO_STRUCT_WHITE, 0, 0, 16, 16, 25, 0),
+ M( 0x61e | PALETTE_TO_STRUCT_WHITE, 0x61f | PALETTE_TO_STRUCT_WHITE, 0, 0, 16, 16, 25, 0),
+ M( 0x61e | PALETTE_TO_STRUCT_WHITE, 0x61f | PALETTE_TO_STRUCT_WHITE, 0, 0, 16, 16, 25, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M( 0x620, 0x621, 0, 0, 16, 16, 25, 0),
+ M( 0x620, 0x621, 0, 0, 16, 16, 25, 0),
+ M( 0x620, 0x621, 0, 0, 16, 16, 25, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M( 0x620 | PALETTE_TO_CREAM, 0x621 | PALETTE_TO_CREAM, 0, 0, 16, 16, 25, 0),
+ M( 0x620 | PALETTE_TO_CREAM, 0x621 | PALETTE_TO_CREAM, 0, 0, 16, 16, 25, 0),
+ M( 0x620 | PALETTE_TO_CREAM, 0x621 | PALETTE_TO_CREAM, 0, 0, 16, 16, 25, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M(0x11da, 0x11db, 0, 0, 16, 16, 25, 0),
+ M(0x11da, 0x11db, 0, 0, 16, 16, 25, 0),
+ M(0x11da, 0x11db, 0, 0, 16, 16, 25, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M( 0x11da | PALETTE_TO_STRUCT_WHITE, 0x11db | PALETTE_TO_STRUCT_WHITE, 0, 0, 16, 16, 25, 0),
+ M( 0x11da | PALETTE_TO_STRUCT_WHITE, 0x11db | PALETTE_TO_STRUCT_WHITE, 0, 0, 16, 16, 25, 0),
+ M( 0x11da | PALETTE_TO_STRUCT_WHITE, 0x11db | PALETTE_TO_STRUCT_WHITE, 0, 0, 16, 16, 25, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M(0x11dc, 0x11dd, 0, 0, 16, 16, 25, 0),
+ M(0x11dc, 0x11dd, 0, 0, 16, 16, 25, 0),
+ M(0x11dc, 0x11dd, 0, 0, 16, 16, 25, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M( 0x11dc | PALETTE_TO_CREAM, 0x11dd | PALETTE_TO_CREAM, 0, 0, 16, 16, 25, 0),
+ M( 0x11dc | PALETTE_TO_CREAM, 0x11dd | PALETTE_TO_CREAM, 0, 0, 16, 16, 25, 0),
+ M( 0x11dc | PALETTE_TO_CREAM, 0x11dd | PALETTE_TO_CREAM, 0, 0, 16, 16, 25, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M(0x1134, 0x1135, 0, 0, 16, 16, 40, 0),
+ M(0x1134, 0x1135, 0, 0, 16, 16, 40, 0),
+ M(0x1134, 0x1135, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M(0x1134, 0x1135, 0, 0, 16, 16, 40, 0),
+ M(0x1134, 0x1135, 0, 0, 16, 16, 40, 0),
+ M(0x1134, 0x1135, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M(0x1134, 0x1135, 0, 0, 16, 16, 40, 0),
+ M(0x1134, 0x1135, 0, 0, 16, 16, 40, 0),
+ M(0x1134, 0x1135, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 22, 0),
+ M(0x1134, 0x1135, 0, 0, 16, 16, 40, 0),
+ M(0x1134, 0x1135, 0, 0, 16, 16, 40, 0),
+ M(0x1134, 0x1135, 0, 0, 16, 16, 40, 0),
+ M(0x1136, 0x1137, 0, 0, 16, 16, 20, 0),
+ M(0x1136, 0x1137, 0, 0, 16, 16, 20, 0),
+ M(0x113b, 0x113c, 0, 0, 16, 16, 20, 0),
+ M(0x113b, 0x113c, 0, 0, 16, 16, 20, 0),
+ M(0x1136, 0x1137, 0, 0, 16, 16, 20, 0),
+ M(0x1136, 0x1137, 0, 0, 16, 16, 20, 0),
+ M(0x113b, 0x113c, 0, 0, 16, 16, 20, 0),
+ M(0x113b, 0x113c, 0, 0, 16, 16, 20, 0),
+ M(0x1136, 0x1137, 0, 0, 16, 16, 20, 0),
+ M(0x1136, 0x1137, 0, 0, 16, 16, 20, 0),
+ M(0x113b, 0x113c, 0, 0, 16, 16, 20, 0),
+ M(0x113b, 0x113c, 0, 0, 16, 16, 20, 0),
+ M(0x1136, 0x1137, 0, 0, 16, 16, 20, 0),
+ M(0x1136, 0x1137, 0, 0, 16, 16, 20, 0),
+ M(0x113b, 0x113c, 0, 0, 16, 16, 20, 0),
+ M(0x113b, 0x113c, 0, 0, 16, 16, 20, 0),
+ M(0x1138, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x1138, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x113d, 0x113e, 0, 0, 16, 16, 20, 0),
+ M(0x113d, 0x113e, 0, 0, 16, 16, 20, 0),
+ M(0x1138, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x1138, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x113d, 0x113e, 0, 0, 16, 16, 20, 0),
+ M(0x113d, 0x113e, 0, 0, 16, 16, 20, 0),
+ M(0x1138, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x1138, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x113d, 0x113e, 0, 0, 16, 16, 20, 0),
+ M(0x113d, 0x113e, 0, 0, 16, 16, 20, 0),
+ M(0x1138, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x1138, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x113d, 0x113e, 0, 0, 16, 16, 20, 0),
+ M(0x113d, 0x113e, 0, 0, 16, 16, 20, 0),
+ M(0x1139, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x1139, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x113f, 0x1140, 0, 0, 16, 16, 20, 0),
+ M(0x113f, 0x1140, 0, 0, 16, 16, 20, 0),
+ M(0x1139, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x1139, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x113f, 0x1140, 0, 0, 16, 16, 20, 0),
+ M(0x113f, 0x1140, 0, 0, 16, 16, 20, 0),
+ M(0x1139, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x1139, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x113f, 0x1140, 0, 0, 16, 16, 20, 0),
+ M(0x113f, 0x1140, 0, 0, 16, 16, 20, 0),
+ M(0x1139, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x1139, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x113f, 0x1140, 0, 0, 16, 16, 20, 0),
+ M(0x113f, 0x1140, 0, 0, 16, 16, 20, 0),
+ M(0x113a, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x113a, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x1141, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x1141, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x113a, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x113a, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x1141, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x1141, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x113a, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x113a, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x1141, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x1141, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x113a, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x113a, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x1141, 0x0, 0, 0, 16, 16, 20, 0),
+ M(0x1141, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x1144, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1145, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1146, 0, 0, 16, 16, 40, 0),
+ M(0x1142, 0x1146, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1144, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1145, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1146, 0, 0, 16, 16, 40, 0),
+ M(0x1142, 0x1146, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1144, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1145, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1146, 0, 0, 16, 16, 40, 0),
+ M(0x1142, 0x1146, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1144, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1145, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1146, 0, 0, 16, 16, 40, 0),
+ M(0x1142, 0x1146, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1144, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1145, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1146, 0, 0, 16, 16, 40, 0),
+ M(0x1143, 0x1147, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1144, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1145, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1146, 0, 0, 16, 16, 40, 0),
+ M(0x1143, 0x1147, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1144, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1145, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1146, 0, 0, 16, 16, 40, 0),
+ M(0x1143, 0x1147, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1144, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1145, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1146, 0, 0, 16, 16, 40, 0),
+ M(0x1143, 0x1147, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1148, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1149, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x114a, 0, 0, 16, 16, 40, 0),
+ M(0x1142, 0x114a, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1148, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1149, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x114a, 0, 0, 16, 16, 40, 0),
+ M(0x1142, 0x114a, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1148, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1149, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x114a, 0, 0, 16, 16, 40, 0),
+ M(0x1142, 0x114a, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1148, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1149, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x114a, 0, 0, 16, 16, 40, 0),
+ M(0x1142, 0x114a, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1148, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1149, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x114a, 0, 0, 16, 16, 40, 0),
+ M(0x1143, 0x114b, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1148, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1149, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x114a, 0, 0, 16, 16, 40, 0),
+ M(0x1143, 0x114b, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1148, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1149, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x114a, 0, 0, 16, 16, 40, 0),
+ M(0x1143, 0x114b, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1148, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1149, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x114a, 0, 0, 16, 16, 40, 0),
+ M(0x1143, 0x114b, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x114e, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x114f, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1150, 0, 0, 16, 16, 40, 0),
+ M(0x114c, 0x1150, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x114e | PALETTE_TO_PINK, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x114f | PALETTE_TO_PINK, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1150 | PALETTE_TO_PINK, 0, 0, 16, 16, 40, 0),
+ M(0x114c, 0x1150 | PALETTE_TO_PINK, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x114e | PALETTE_TO_CREAM, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x114f | PALETTE_TO_CREAM, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1150 | PALETTE_TO_CREAM, 0, 0, 16, 16, 40, 0),
+ M(0x114c, 0x1150 | PALETTE_TO_CREAM, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x114e | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x114f | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1150 | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 40, 0),
+ M(0x114c, 0x1150 | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x114e, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x114f, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1150, 0, 0, 16, 16, 40, 0),
+ M(0x114d, 0x1151, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x114e | PALETTE_TO_PINK, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x114f | PALETTE_TO_PINK, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1150 | PALETTE_TO_PINK, 0, 0, 16, 16, 40, 0),
+ M(0x114d, 0x1151 | PALETTE_TO_PINK, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x114e | PALETTE_TO_CREAM, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x114f | PALETTE_TO_CREAM, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1150 | PALETTE_TO_CREAM, 0, 0, 16, 16, 40, 0),
+ M(0x114d, 0x1151 | PALETTE_TO_CREAM, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x114e | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x114f | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1150 | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 40, 0),
+ M(0x114d, 0x1151 | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1153, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1154, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1155, 0, 0, 16, 16, 60, 0),
+ M(0x1152, 0x1155, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1153 | PALETTE_TO_RED, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1154 | PALETTE_TO_RED, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1155 | PALETTE_TO_RED, 0, 0, 16, 16, 60, 0),
+ M(0x1152, 0x1155 | PALETTE_TO_RED, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1153 | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1154 | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1155 | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 60, 0),
+ M(0x1152, 0x1155 | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1153 | PALETTE_TO_GREY, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1154 | PALETTE_TO_GREY, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1155 | PALETTE_TO_GREY, 0, 0, 16, 16, 60, 0),
+ M(0x1152, 0x1155 | PALETTE_TO_GREY, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1153, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1154, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11de, 0, 0, 16, 16, 60, 0),
+ M(0x1152, 0x11de, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1153 | PALETTE_TO_RED, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1154 | PALETTE_TO_RED, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11de | PALETTE_TO_RED, 0, 0, 16, 16, 60, 0),
+ M(0x1152, 0x11de | PALETTE_TO_RED, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1153 | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1154 | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11de | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 60, 0),
+ M(0x1152, 0x11de | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1153 | PALETTE_TO_GREY, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1154 | PALETTE_TO_GREY, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11de | PALETTE_TO_GREY, 0, 0, 16, 16, 60, 0),
+ M(0x1152, 0x11de | PALETTE_TO_GREY, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1157, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1158, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1159, 0, 0, 16, 16, 60, 0),
+ M(0x1156, 0x1159, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1157 | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1158 | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1159 | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 60, 0),
+ M(0x1156, 0x1159 | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1157 | PALETTE_TO_CREAM, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1158 | PALETTE_TO_CREAM, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1159 | PALETTE_TO_CREAM, 0, 0, 16, 16, 60, 0),
+ M(0x1156, 0x1159 | PALETTE_TO_CREAM, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1157 | PALETTE_TO_YELLOW, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1158 | PALETTE_TO_YELLOW, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1159 | PALETTE_TO_YELLOW, 0, 0, 16, 16, 60, 0),
+ M(0x1156, 0x1159 | PALETTE_TO_YELLOW, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1157, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1158, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11df, 0, 0, 16, 16, 60, 0),
+ M(0x1156, 0x11df, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1157 | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1158 | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11df | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 60, 0),
+ M(0x1156, 0x11df | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1157 | PALETTE_TO_CREAM, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1158 | PALETTE_TO_CREAM, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11df | PALETTE_TO_CREAM, 0, 0, 16, 16, 60, 0),
+ M(0x1156, 0x11df | PALETTE_TO_CREAM, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1157 | PALETTE_TO_YELLOW, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1158 | PALETTE_TO_YELLOW, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11df | PALETTE_TO_YELLOW, 0, 0, 16, 16, 60, 0),
+ M(0x1156, 0x11df | PALETTE_TO_YELLOW, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x115b, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x115c, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x115d, 0, 0, 16, 16, 60, 0),
+ M(0x115a, 0x115d, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x115b | PALETTE_TO_RED, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x115c | PALETTE_TO_RED, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x115d | PALETTE_TO_RED, 0, 0, 16, 16, 60, 0),
+ M(0x115a, 0x115d | PALETTE_TO_RED, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x115b | PALETTE_TO_ORANGE, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x115c | PALETTE_TO_ORANGE, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x115d | PALETTE_TO_ORANGE, 0, 0, 16, 16, 60, 0),
+ M(0x115a, 0x115d | PALETTE_TO_ORANGE, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x115b | PALETTE_TO_BROWN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x115c | PALETTE_TO_BROWN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x115d | PALETTE_TO_BROWN, 0, 0, 16, 16, 60, 0),
+ M(0x115a, 0x115d | PALETTE_TO_BROWN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x115b, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x115c, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11e0, 0, 0, 16, 16, 60, 0),
+ M(0x115a, 0x11e0, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x115b | PALETTE_TO_RED, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x115c | PALETTE_TO_RED, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11e0 | PALETTE_TO_RED, 0, 0, 16, 16, 60, 0),
+ M(0x115a, 0x11e0 | PALETTE_TO_RED, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x115b | PALETTE_TO_ORANGE, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x115c | PALETTE_TO_ORANGE, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11e0 | PALETTE_TO_ORANGE, 0, 0, 16, 16, 60, 0),
+ M(0x115a, 0x11e0 | PALETTE_TO_ORANGE, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x115b | PALETTE_TO_BROWN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x115c | PALETTE_TO_BROWN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11e0 | PALETTE_TO_BROWN, 0, 0, 16, 16, 60, 0),
+ M(0x115a, 0x11e0 | PALETTE_TO_BROWN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1160, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x1161, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x1162, 0, 0, 16, 16, 20, 0),
+ M(0x115e, 0x1162, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x1160, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x1161, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x1162, 0, 0, 16, 16, 20, 0),
+ M(0x115e, 0x1162, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x1166, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x1167, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x1168, 0, 0, 16, 16, 20, 0),
+ M(0x1164, 0x1168, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x1166, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x1167, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x1168, 0, 0, 16, 16, 20, 0),
+ M(0x1164, 0x1168, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x1160, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x1161, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x1162, 0, 0, 16, 16, 20, 0),
+ M(0x115f, 0x1163, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x1160, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x1161, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x1162, 0, 0, 16, 16, 20, 0),
+ M(0x115f, 0x1163, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x1166, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x1167, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x1168, 0, 0, 16, 16, 20, 0),
+ M(0x1165, 0x1169, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x1166, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x1167, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x1168, 0, 0, 16, 16, 20, 0),
+ M(0x1165, 0x1169, 0, 0, 16, 16, 20, 0),
+ M(0x116b, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x116c, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x116d, 0, 0, 16, 16, 40, 0),
+ M(0x116a, 0x116d, 0, 0, 16, 16, 40, 0),
+ M(0x116b, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x116c, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x116d, 0, 0, 16, 16, 40, 0),
+ M(0x116a, 0x116d, 0, 0, 16, 16, 40, 0),
+ M(0x116b, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x116c, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x116d, 0, 0, 16, 16, 40, 0),
+ M(0x116a, 0x116d, 0, 0, 16, 16, 40, 0),
+ M(0x116b, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x116c, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x116d, 0, 0, 16, 16, 40, 0),
+ M(0x116a, 0x116d, 0, 0, 16, 16, 40, 0),
+ M(0x116b, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x116c, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e2, 0, 0, 16, 16, 40, 0),
+ M(0x116a, 0x11e2, 0, 0, 16, 16, 40, 0),
+ M(0x116b, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x116c, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e2, 0, 0, 16, 16, 40, 0),
+ M(0x116a, 0x11e2, 0, 0, 16, 16, 40, 0),
+ M(0x116b, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x116c, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e2, 0, 0, 16, 16, 40, 0),
+ M(0x116a, 0x11e2, 0, 0, 16, 16, 40, 0),
+ M(0x116b, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x116c, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e2, 0, 0, 16, 16, 40, 0),
+ M(0x116a, 0x11e2, 0, 0, 16, 16, 40, 0),
+ M(0x116f, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1170, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1171, 0, 0, 16, 16, 40, 0),
+ M(0x116e, 0x1171, 0, 0, 16, 16, 40, 0),
+ M(0x116f, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1170, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1171, 0, 0, 16, 16, 40, 0),
+ M(0x116e, 0x1171, 0, 0, 16, 16, 40, 0),
+ M(0x116f, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1170, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1171, 0, 0, 16, 16, 40, 0),
+ M(0x116e, 0x1171, 0, 0, 16, 16, 40, 0),
+ M(0x116f, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1170, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1171, 0, 0, 16, 16, 40, 0),
+ M(0x116e, 0x1171, 0, 0, 16, 16, 40, 0),
+ M(0x116f, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1170, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e3, 0, 0, 16, 16, 40, 0),
+ M(0x116e, 0x11e3, 0, 0, 16, 16, 40, 0),
+ M(0x116f, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1170, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e3, 0, 0, 16, 16, 40, 0),
+ M(0x116e, 0x11e3, 0, 0, 16, 16, 40, 0),
+ M(0x116f, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1170, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e3, 0, 0, 16, 16, 40, 0),
+ M(0x116e, 0x11e3, 0, 0, 16, 16, 40, 0),
+ M(0x116f, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1170, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e3, 0, 0, 16, 16, 40, 0),
+ M(0x116e, 0x11e3, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1173, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1174, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1175, 0, 0, 16, 16, 40, 0),
+ M(0x1172, 0x1175, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1173 | PALETTE_TO_BROWN, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1174 | PALETTE_TO_BROWN, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1175 | PALETTE_TO_BROWN, 0, 0, 16, 16, 40, 0),
+ M(0x1172, 0x1175 | PALETTE_TO_BROWN, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1173 | PALETTE_TO_CREAM, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1174 | PALETTE_TO_CREAM, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1175 | PALETTE_TO_CREAM, 0, 0, 16, 16, 40, 0),
+ M(0x1172, 0x1175 | PALETTE_TO_CREAM, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1173 | PALETTE_TO_GREY, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1174 | PALETTE_TO_GREY, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1175 | PALETTE_TO_GREY, 0, 0, 16, 16, 40, 0),
+ M(0x1172, 0x1175 | PALETTE_TO_GREY, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1173, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1174, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1175, 0, 0, 16, 16, 40, 0),
+ M(0x11e4, 0x11e5, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1173 | PALETTE_TO_BROWN, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1174 | PALETTE_TO_BROWN, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1175 | PALETTE_TO_BROWN, 0, 0, 16, 16, 40, 0),
+ M(0x11e4, 0x11e5 | PALETTE_TO_BROWN, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1173 | PALETTE_TO_CREAM, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1174 | PALETTE_TO_CREAM, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1175 | PALETTE_TO_CREAM, 0, 0, 16, 16, 40, 0),
+ M(0x11e4, 0x11e5 | PALETTE_TO_CREAM, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1173 | PALETTE_TO_GREY, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1174 | PALETTE_TO_GREY, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1175 | PALETTE_TO_GREY, 0, 0, 16, 16, 40, 0),
+ M(0x11e4, 0x11e5 | PALETTE_TO_GREY, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1176, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1176, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1176, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1176, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1176, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1176, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1176 | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1176 | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1176 | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1176 | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1176 | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1176 | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e6, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11e6, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11e6, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e6, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11e6, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11e6, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e6 | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11e6 | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11e6 | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e6 | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11e6 | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11e6 | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 60, 0),
+ M(0x1177, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1179, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x117b, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x117b, 0, 0, 16, 16, 40, 0),
+ M(0x1177, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1179, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x117b, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x117b, 0, 0, 16, 16, 40, 0),
+ M(0x1177, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1179, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x117b, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x117b, 0, 0, 16, 16, 40, 0),
+ M(0x1177, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1179, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x117b, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x117b, 0, 0, 16, 16, 40, 0),
+ M(0x1178, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x117a, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x117c, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x117c, 0, 0, 16, 16, 40, 0),
+ M(0x1178, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x117a, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x117c, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x117c, 0, 0, 16, 16, 40, 0),
+ M(0x1178, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x117a, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x117c, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x117c, 0, 0, 16, 16, 40, 0),
+ M(0x1178, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x117a, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x117c, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x117c, 0, 0, 16, 16, 40, 0),
+ M(0x1177, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1179, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e7, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e7, 0, 0, 16, 16, 40, 0),
+ M(0x1177, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1179, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e7, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e7, 0, 0, 16, 16, 40, 0),
+ M(0x1177, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1179, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e7, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e7, 0, 0, 16, 16, 40, 0),
+ M(0x1177, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1179, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e7, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e7, 0, 0, 16, 16, 40, 0),
+ M(0x1178, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x117a, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e8, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e8, 0, 0, 16, 16, 40, 0),
+ M(0x1178, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x117a, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e8, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e8, 0, 0, 16, 16, 40, 0),
+ M(0x1178, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x117a, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e8, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e8, 0, 0, 16, 16, 40, 0),
+ M(0x1178, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x117a, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e8, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11e8, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x117d, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x117e, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x117f, 0, 0, 16, 16, 50, 0),
+ M( 0x58c, 0x117f, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x117d, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x117e, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x117f, 0, 0, 16, 16, 50, 0),
+ M( 0x58c, 0x117f, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x117d | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x117e | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x117f | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 50, 0),
+ M( 0x58c, 0x117f | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x117d | PALETTE_TO_STRUCT_WHITE, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x117e | PALETTE_TO_STRUCT_WHITE, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x117f | PALETTE_TO_STRUCT_WHITE, 0, 0, 16, 16, 50, 0),
+ M( 0x58c, 0x117f | PALETTE_TO_STRUCT_WHITE, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x117d, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x117e, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x11e1, 0, 0, 16, 16, 50, 0),
+ M( 0x58c, 0x11e1, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x117d, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x117e, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x11e1, 0, 0, 16, 16, 50, 0),
+ M( 0x58c, 0x11e1, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x117d | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x117e | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x11e1 | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 50, 0),
+ M( 0x58c, 0x11e3 | PALETTE_TO_STRUCT_BROWN, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x117d | PALETTE_TO_STRUCT_WHITE, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x117e | PALETTE_TO_STRUCT_WHITE, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x11e1 | PALETTE_TO_STRUCT_WHITE, 0, 0, 16, 16, 50, 0),
+ M( 0x58c, 0x11e1 | PALETTE_TO_STRUCT_WHITE, 0, 0, 16, 16, 50, 0),
+ M(0x1180, 0x1181, 0, 0, 16, 16, 10, 0),
+ M(0x1183, 0x1182 | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 60, 0),
+ M(0x1183, 0x1182 | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 60, 0),
+ M(0x1183, 0x1184 | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 60, 0),
+ M(0x1180, 0x1181, 0, 0, 16, 16, 10, 0),
+ M(0x1183, 0x1182 | PALETTE_TO_ORANGE, 0, 0, 16, 16, 60, 0),
+ M(0x1183, 0x1182 | PALETTE_TO_ORANGE, 0, 0, 16, 16, 60, 0),
+ M(0x1183, 0x1184 | PALETTE_TO_ORANGE, 0, 0, 16, 16, 60, 0),
+ M(0x1180, 0x1181, 0, 0, 16, 16, 10, 0),
+ M(0x1183, 0x1182 | PALETTE_TO_BROWN, 0, 0, 16, 16, 60, 0),
+ M(0x1183, 0x1182 | PALETTE_TO_BROWN, 0, 0, 16, 16, 60, 0),
+ M(0x1183, 0x1184 | PALETTE_TO_BROWN, 0, 0, 16, 16, 60, 0),
+ M(0x1180, 0x1181, 0, 0, 16, 16, 10, 0),
+ M(0x1183, 0x1182 | PALETTE_TO_GREY, 0, 0, 16, 16, 60, 0),
+ M(0x1183, 0x1182 | PALETTE_TO_GREY, 0, 0, 16, 16, 60, 0),
+ M(0x1183, 0x1184 | PALETTE_TO_GREY, 0, 0, 16, 16, 60, 0),
+ M(0x1180, 0x1181, 0, 0, 16, 16, 10, 0),
+ M(0x1183, 0x1182 | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 60, 0),
+ M(0x1183, 0x1182 | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 60, 0),
+ M(0x1183, 0x11e9 | PALETTE_TO_DARK_GREEN, 0, 0, 16, 16, 60, 0),
+ M(0x1180, 0x1181, 0, 0, 16, 16, 10, 0),
+ M(0x1183, 0x1182 | PALETTE_TO_ORANGE, 0, 0, 16, 16, 60, 0),
+ M(0x1183, 0x1182 | PALETTE_TO_ORANGE, 0, 0, 16, 16, 60, 0),
+ M(0x1183, 0x11e9 | PALETTE_TO_ORANGE, 0, 0, 16, 16, 60, 0),
+ M(0x1180, 0x1181, 0, 0, 16, 16, 10, 0),
+ M(0x1183, 0x1182 | PALETTE_TO_BROWN, 0, 0, 16, 16, 60, 0),
+ M(0x1183, 0x1182 | PALETTE_TO_BROWN, 0, 0, 16, 16, 60, 0),
+ M(0x1183, 0x11e9 | PALETTE_TO_BROWN, 0, 0, 16, 16, 60, 0),
+ M(0x1180, 0x1181, 0, 0, 16, 16, 10, 0),
+ M(0x1183, 0x1182 | PALETTE_TO_GREY, 0, 0, 16, 16, 60, 0),
+ M(0x1183, 0x1182 | PALETTE_TO_GREY, 0, 0, 16, 16, 60, 0),
+ M(0x1183, 0x11e9 | PALETTE_TO_GREY, 0, 0, 16, 16, 60, 0),
+ M(0x1185, 0x1187, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x1189, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x1189, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x118b, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x1187, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x1189, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x1189, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x118b, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x1187, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x1189, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x1189, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x118b, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x1187, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x1189, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x1189, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x118b, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x1188, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x118a, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x118a, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x118c, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x1188, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x118a, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x118a, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x118c, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x1188, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x118a, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x118a, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x118c, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x1188, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x118a, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x118a, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x118c, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x1187, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x1189, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x1189, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x11ea, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x1187, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x1189, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x1189, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x11ea, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x1187, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x1189, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x1189, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x11ea, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x1187, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x1189, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x1189, 0, 0, 16, 16, 10, 0),
+ M(0x1185, 0x11ea, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x1188, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x118a, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x118a, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x11eb, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x1188, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x118a, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x118a, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x11eb, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x1188, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x118a, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x118a, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x11eb, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x1188, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x118a, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x118a, 0, 0, 16, 16, 10, 0),
+ M(0x1186, 0x11eb, 0, 0, 16, 16, 10, 0),
+ M( 0xf54, 0x11ec, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11ed, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11ed, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11ee, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11ec, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11ed, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11ed, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11ee, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11ec, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11ed, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11ed, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11ee, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11ec, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11ed, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11ed, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11ee, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11ef, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f1, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11ef, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f1, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11ef, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f1, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11ef, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f1, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f2, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f3, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f3, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f4, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f2, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f3, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f3, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f4, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f2, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f3, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f3, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f4, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f2, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f3, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f3, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11f4, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x11f5, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x11f5, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x11f5, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x11f6, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x11f6, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x11f6, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x11f7, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x11f7, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x11f7, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x11f8, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x11f8, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x11f8, 0, 0, 16, 16, 20, 0),
+ M( 0xf54, 0x11f9, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11fa, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11fa, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11fb, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11f9, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11fa, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11fa, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11fb, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11f9, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11fa, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11fa, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11fb, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11f9, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11fa, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11fa, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x11fb, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11fc, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11fc, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11fc, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11fc, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11fc, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11fc, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11fc, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11fc, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11fc, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x0, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11fc, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11fc, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11fc, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11fd, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11fe, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11fe, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11ff, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11fd, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11fe, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11fe, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11ff, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11fd, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11fe, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11fe, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11ff, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11fd, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11fe, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11fe, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x11ff, 0, 0, 16, 16, 40, 0),
+ M( 0xf54, 0x1200, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1201, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1201, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1202, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1200 | PALETTE_TO_PINK, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1201 | PALETTE_TO_PINK, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1201 | PALETTE_TO_PINK, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1202 | PALETTE_TO_PINK, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1200 | PALETTE_TO_YELLOW, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1201 | PALETTE_TO_YELLOW, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1201 | PALETTE_TO_YELLOW, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1202 | PALETTE_TO_YELLOW, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1200 | PALETTE_TO_RED, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1201 | PALETTE_TO_RED, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1201 | PALETTE_TO_RED, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1202 | PALETTE_TO_RED, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1203, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1204, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1204, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1205, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1203 | PALETTE_TO_PINK, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1204 | PALETTE_TO_PINK, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1204 | PALETTE_TO_PINK, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1205 | PALETTE_TO_PINK, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1203 | PALETTE_TO_YELLOW, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1204 | PALETTE_TO_YELLOW, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1204 | PALETTE_TO_YELLOW, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1205 | PALETTE_TO_YELLOW, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1203 | PALETTE_TO_RED, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1204 | PALETTE_TO_RED, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1204 | PALETTE_TO_RED, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1205 | PALETTE_TO_RED, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x1206, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x1208, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x1208, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x120a, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x1206, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x1208, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x1208, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x120a, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x1206, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x1208, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x1208, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x120a, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x1206, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x1208, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x1208, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x120a, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x1207, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x1209, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x1209, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x120b, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x1207, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x1209, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x1209, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x120b, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x1207, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x1209, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x1209, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x120b, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x1207, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x1209, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x1209, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x120b, 0, 0, 16, 16, 80, 0),
+ M( 0xf54, 0x120c, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x120d, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x120d, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x120e, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x120c, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x120d, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x120d, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x120e, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x120c, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x120d, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x120d, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x120e, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x120c, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x120d, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x120d, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x120e, 0, 0, 16, 16, 60, 0),
+ M( 0xf54, 0x120f, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x1210, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x1210, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x1211, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x120f, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x1210, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x1210, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x1211, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x120f, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x1210, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x1210, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x1211, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x120f, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x1210, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x1210, 0, 0, 16, 16, 50, 0),
+ M( 0xf54, 0x1211, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1213, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1214, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1214, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1215, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1213 | PALETTE_TO_RED, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1214 | PALETTE_TO_RED, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1214 | PALETTE_TO_RED, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1215 | PALETTE_TO_RED, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1213 | PALETTE_TO_PINK, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1214 | PALETTE_TO_PINK, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1214 | PALETTE_TO_PINK, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1215 | PALETTE_TO_PINK, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1213 | PALETTE_TO_PALE_GREEN, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1214 | PALETTE_TO_PALE_GREEN, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1214 | PALETTE_TO_PALE_GREEN, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1215 | PALETTE_TO_PALE_GREEN, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1216, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1217, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1217, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1218, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1216, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1217, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1217, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1218, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1216, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1217, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1217, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1218, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1216, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1217, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1217, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1218, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1219, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x121a, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x121a, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x121b, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1219, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x121a, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x121a, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x121b, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1219, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x121a, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x121a, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x121b, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1219, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x121a, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x121a, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x121b, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x121c, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x121d, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x121d, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x121e, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x121c, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x121d, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x121d, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x121e, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x121c, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x121d, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x121d, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x121e, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x121c, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x121d, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x121d, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x121e, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x121f, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1220, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1220, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1221, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x121f | PALETTE_TO_PINK, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1220 | PALETTE_TO_PINK, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1220 | PALETTE_TO_PINK, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1221 | PALETTE_TO_PINK, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x121f | PALETTE_TO_MAUVE, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1220 | PALETTE_TO_MAUVE, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1220 | PALETTE_TO_MAUVE, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1221 | PALETTE_TO_MAUVE, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x121f | PALETTE_TO_CREAM, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1220 | PALETTE_TO_CREAM, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1220 | PALETTE_TO_CREAM, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1221 | PALETTE_TO_CREAM, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1222, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1223, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1223, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1224, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1222 | PALETTE_TO_PINK, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1223 | PALETTE_TO_PINK, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1223 | PALETTE_TO_PINK, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1224 | PALETTE_TO_PINK, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1222 | PALETTE_TO_CREAM, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1223 | PALETTE_TO_CREAM, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1223 | PALETTE_TO_CREAM, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1224 | PALETTE_TO_CREAM, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1222 | PALETTE_TO_PALE_GREEN, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1223 | PALETTE_TO_PALE_GREEN, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1223 | PALETTE_TO_PALE_GREEN, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1224 | PALETTE_TO_PALE_GREEN, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1225, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1226, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1226, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1227, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1225 | PALETTE_TO_PINK, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1226 | PALETTE_TO_PINK, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1226 | PALETTE_TO_PINK, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1227 | PALETTE_TO_PINK, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1225 | PALETTE_TO_RED, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1226 | PALETTE_TO_RED, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1226 | PALETTE_TO_RED, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1227 | PALETTE_TO_RED, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1225 | PALETTE_TO_PALE_GREEN, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1226 | PALETTE_TO_PALE_GREEN, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1226 | PALETTE_TO_PALE_GREEN, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1227 | PALETTE_TO_PALE_GREEN, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1228, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1229, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1229, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x122a, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1228, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1229, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1229, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x122a, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1228, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1229, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1229, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x122a, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1228, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1229, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1229, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x122a, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x122b, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x122d, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x122d, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x122f, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x122b, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x122d, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x122d, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x122f, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x122b, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x122d, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x122d, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x122f, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x122b, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x122d, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x122d, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x122f, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x122c, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x122e, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x122e, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1230, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x122c, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x122e, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x122e, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1230, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x122c, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x122e, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x122e, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1230, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x122c, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x122e, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x122e, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1230, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1231, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1232, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1232, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1233, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1231, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1232, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1232, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1233, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1231, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1232, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1232, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1233, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1231, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1232, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1232, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1233, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1234, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1235, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1235, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1236, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1234, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1235, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1235, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1236, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1234, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1235, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1235, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1236, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1234, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1235, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1235, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1236, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1237, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1238, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1238, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1239, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1237, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1238, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1238, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1239, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1237, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1238, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1238, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1239, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1237, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1238, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1238, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1239, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x123a, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x123b, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x123b, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x123c, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x123a, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x123b, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x123b, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x123c, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x123a, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x123b, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x123b, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x123c, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x123a, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x123b, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x123b, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x123c, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x123d, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x123e, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x123e, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x123f, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x123d, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x123e, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x123e, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x123f, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x123d, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x123e, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x123e, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x123f, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x123d, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x123e, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x123e, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x123f, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1240, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1241, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1241, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1242, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1240, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1241, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1241, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1242, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1240, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1241, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1241, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1242, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1240, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1241, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1241, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1242, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x0, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1256, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1256, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1256, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x0, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1256 | PALETTE_TO_PALE_GREEN, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1256 | PALETTE_TO_PALE_GREEN, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1256 | PALETTE_TO_PALE_GREEN, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x0, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1256 | PALETTE_TO_RED, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1256 | PALETTE_TO_RED, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1256 | PALETTE_TO_RED, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x0, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1256 | PALETTE_TO_CREAM, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1256 | PALETTE_TO_CREAM, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x1256 | PALETTE_TO_CREAM, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1257, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1258, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1258, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1259, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1257, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1258, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1258, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1259, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1257, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1258, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1258, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1259, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1257, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1258, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1258, 0, 0, 16, 16, 50, 0),
+ M(0x1243, 0x1259, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x0, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x125a, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x125a, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x125a, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x0, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x125a, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x125a, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x125a, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x0, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x125a, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x125a, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x125a, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x0, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x125a, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x125a, 0, 0, 16, 16, 50, 0),
+ M(0x1244, 0x125a, 0, 0, 16, 16, 50, 0),
+};
+#undef M
+// 4 variants * 4 build stages
+assert_compile(lengthof(_town_draw_tile_data) == HOUSE_MAX * 4 * 4);
+
+
+static const StringID _town_tile_names[] = {
+ STR_200F_TALL_OFFICE_BLOCK,
+ STR_2010_OFFICE_BLOCK,
+ STR_2011_SMALL_BLOCK_OF_FLATS,
+ STR_2012_CHURCH,
+ STR_2013_LARGE_OFFICE_BLOCK,
+ STR_2013_LARGE_OFFICE_BLOCK,
+ STR_2014_TOWN_HOUSES,
+ STR_2015_HOTEL,
+ STR_2015_HOTEL,
+ STR_2016_STATUE,
+ STR_2017_FOUNTAIN,
+ STR_2018_PARK,
+ STR_2018_PARK,
+ STR_2019_OFFICE_BLOCK,
+ STR_201A_SHOPS_AND_OFFICES,
+ STR_201A_SHOPS_AND_OFFICES,
+ STR_201A_SHOPS_AND_OFFICES,
+ STR_201B_MODERN_OFFICE_BUILDING,
+ STR_201C_WAREHOUSE,
+ STR_201D_OFFICE_BLOCK,
+ STR_201E_STADIUM,
+ STR_201E_STADIUM,
+ STR_201E_STADIUM,
+ STR_201E_STADIUM,
+ STR_201F_OLD_HOUSES,
+ STR_2036_COTTAGES,
+ STR_2037_HOUSES,
+ STR_2038_FLATS,
+ STR_2039_TALL_OFFICE_BLOCK,
+ STR_203A_SHOPS_AND_OFFICES,
+ STR_203B_SHOPS_AND_OFFICES,
+ STR_203C_THEATER,
+ STR_203D_STADIUM,
+ STR_203D_STADIUM,
+ STR_203D_STADIUM,
+ STR_203D_STADIUM,
+ STR_203E_OFFICES,
+ STR_203F_HOUSES,
+ STR_203F_HOUSES,
+ STR_2040_CINEMA,
+ STR_2041_SHOPPING_MALL,
+ STR_2041_SHOPPING_MALL,
+ STR_2041_SHOPPING_MALL,
+ STR_2041_SHOPPING_MALL,
+ STR_2038_FLATS,
+ STR_2038_FLATS,
+ STR_203F_HOUSES,
+ STR_203F_HOUSES,
+ STR_203F_HOUSES,
+ STR_203F_HOUSES,
+ STR_200F_TALL_OFFICE_BLOCK,
+ STR_200F_TALL_OFFICE_BLOCK,
+ STR_200F_TALL_OFFICE_BLOCK,
+ STR_200F_TALL_OFFICE_BLOCK,
+ STR_200F_TALL_OFFICE_BLOCK,
+ STR_200F_TALL_OFFICE_BLOCK,
+ STR_203F_HOUSES,
+ STR_203F_HOUSES,
+ STR_201A_SHOPS_AND_OFFICES,
+ STR_201A_SHOPS_AND_OFFICES,
+ STR_2012_CHURCH,
+ STR_2012_CHURCH,
+ STR_203F_HOUSES,
+ STR_203F_HOUSES,
+ STR_201A_SHOPS_AND_OFFICES,
+ STR_201A_SHOPS_AND_OFFICES,
+ STR_2015_HOTEL,
+ STR_2015_HOTEL,
+ STR_2015_HOTEL,
+ STR_2015_HOTEL,
+ STR_201A_SHOPS_AND_OFFICES,
+ STR_201A_SHOPS_AND_OFFICES,
+ STR_200F_TALL_OFFICE_BLOCK,
+ STR_200F_TALL_OFFICE_BLOCK,
+ STR_200F_TALL_OFFICE_BLOCK,
+ STR_200F_TALL_OFFICE_BLOCK,
+ STR_200F_TALL_OFFICE_BLOCK,
+ STR_200F_TALL_OFFICE_BLOCK,
+ STR_203F_HOUSES,
+ STR_203F_HOUSES,
+ STR_203F_HOUSES,
+ STR_203F_HOUSES,
+ STR_2038_FLATS,
+ STR_2012_CHURCH,
+ STR_203F_HOUSES,
+ STR_2038_FLATS,
+ STR_2038_FLATS,
+ STR_200F_TALL_OFFICE_BLOCK,
+ STR_200F_TALL_OFFICE_BLOCK,
+ STR_2038_FLATS,
+ STR_200F_TALL_OFFICE_BLOCK,
+ STR_2012_CHURCH,
+ STR_203F_HOUSES,
+ STR_203F_HOUSES,
+ STR_203F_HOUSES,
+ STR_203F_HOUSES,
+ STR_203F_HOUSES,
+ STR_203F_HOUSES,
+ STR_200F_TALL_OFFICE_BLOCK,
+ STR_203F_HOUSES,
+ STR_203F_HOUSES,
+ STR_200F_TALL_OFFICE_BLOCK,
+ STR_2059_IGLOO,
+ STR_205A_TEPEES,
+ STR_201A_SHOPS_AND_OFFICES,
+ STR_201A_SHOPS_AND_OFFICES,
+ STR_200F_TALL_OFFICE_BLOCK,
+ STR_2016_STATUE,
+ STR_205B_TEAPOT_HOUSE,
+ STR_205C_PIGGY_BANK,
+};
+assert_compile(lengthof(_town_tile_names) == HOUSE_MAX);
+
+static const uint16 _housetype_flags[] = {
+ 0x1010, 0x1018, 0x100E, 0x100F, 0x7010, 0x0810, 0x100F, 0x1014,
+ 0x0000, 0x7018, 0x7010, 0x1004, 0x1008, 0x1018, 0x101C, 0x101C,
+ 0x101C, 0x7010, 0x1010, 0x1010, 0x100F, 0x0000, 0x0000, 0x0000,
+ 0x1003, 0x1001, 0x100F, 0x101C, 0x101C, 0x101C, 0x5014, 0x1018,
+ 0x700F, 0x0000, 0x0000, 0x0000, 0x7018, 0x2003, 0x0803, 0x101C,
+ 0x101E, 0x0000, 0x0000, 0x0000, 0x201C, 0x081C, 0x200F, 0x080F,
+ 0x2007, 0x0807, 0x6018, 0x0818, 0x2018, 0x0818, 0x6018, 0x0818,
+ 0x2001, 0x0801, 0x201E, 0x081E, 0x200F, 0x080F, 0x2007, 0x0807,
+ 0x201C, 0x081C, 0x201C, 0x0000, 0x081C, 0x0000, 0x601C, 0x081C,
+ 0x2018, 0x0818, 0x201C, 0x0000, 0x081C, 0x0000, 0x401E, 0x401E,
+ 0x401E, 0x4001, 0x401C, 0x400E, 0x401E, 0x401C, 0x401C, 0x4018,
+ 0x4000, 0x401C, 0x4018, 0x801F, 0x801F, 0x8003, 0x800F, 0x800F,
+ 0x800F, 0x800F, 0x801C, 0x801F, 0x0000, 0x801C, 0x8001, 0x8001,
+ 0x801C, 0x801C, 0x801C, 0x801C, 0x801F, 0x801F,
+};
+assert_compile(lengthof(_housetype_flags) == HOUSE_MAX);
+
+static const byte _housetype_extra_flags[] = {
+ 0, 0, 0, 0, 32, 32, 0, 8,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 16, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 16, 0, 0, 0, 0, 0, 0, 0,
+ 16, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 8, 0, 8, 0, 0, 0,
+ 0, 0, 4, 0, 4, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 4,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 8, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+};
+assert_compile(lengthof(_housetype_extra_flags) == HOUSE_MAX);
+
+static const byte _housetype_population[] = {
+ 187, 85, 40, 5, 220, 220, 30, 140,
+ 0, 0, 0, 0, 0, 150, 95, 95,
+ 95, 130, 6, 110, 65, 0, 0, 0,
+ 15, 12, 13, 100, 170, 100, 180, 35,
+ 65, 0, 0, 0, 140, 15, 15, 35,
+ 180, 0, 0, 0, 80, 80, 16, 16,
+ 14, 14, 135, 135, 170, 170, 210, 210,
+ 10, 10, 25, 25, 6, 6, 17, 17,
+ 90, 90, 140, 0, 140, 0, 105, 105,
+ 190, 190, 250, 0, 250, 0, 16, 16,
+ 16, 7, 45, 8, 18, 90, 120, 250,
+ 0, 80, 180, 8, 18, 7, 15, 17,
+ 19, 21, 75, 35, 0, 85, 11, 10,
+ 67, 86, 95, 30, 25, 18,
+};
+assert_compile(lengthof(_housetype_population) == HOUSE_MAX);
+
+static const byte _housetype_mailamount[] = {
+ 70, 55, 20, 2, 85, 85, 12, 22,
+ 22, 0, 0, 0, 0, 65, 48, 48,
+ 48, 50, 10, 55, 5, 5, 5, 5,
+ 6, 7, 8, 35, 50, 40, 64, 23,
+ 5, 5, 5, 5, 65, 6, 6, 23,
+ 5, 5, 5, 5, 20, 20, 6, 6,
+ 6, 6, 60, 60, 70, 70, 80, 80,
+ 5, 5, 20, 20, 2, 2, 7, 7,
+ 45, 45, 25, 25, 25, 25, 50, 50,
+ 75, 75, 60, 60, 60, 60, 6, 6,
+ 5, 4, 15, 3, 7, 24, 25, 80,
+ 80, 23, 90, 3, 5, 3, 6, 6,
+ 6, 6, 20, 9, 0, 18, 3, 3,
+ 22, 23, 28, 10, 8, 7,
+};
+assert_compile(lengthof(_housetype_mailamount) == HOUSE_MAX);
+
+static const byte _housetype_remove_cost[] = {
+ 150, 140, 100, 90, 160, 160, 80, 180,
+ 180, 65, 65, 60, 60, 130, 110, 105,
+ 107, 200, 145, 155, 250, 250, 250, 250,
+ 70, 75, 71, 135, 145, 132, 155, 220,
+ 250, 250, 250, 250, 170, 70, 70, 210,
+ 250, 250, 250, 250, 100, 100, 70, 70,
+ 80, 80, 150, 150, 170, 170, 200, 200,
+ 60, 60, 100, 100, 85, 85, 80, 80,
+ 140, 140, 160, 160, 160, 160, 130, 130,
+ 190, 190, 140, 140, 140, 140, 80, 80,
+ 80, 30, 130, 90, 80, 110, 120, 190,
+ 190, 110, 180, 90, 90, 70, 80, 80,
+ 80, 80, 160, 90, 90, 150, 60, 60,
+ 140, 145, 165, 90, 75, 85,
+};
+assert_compile(lengthof(_housetype_remove_cost) == HOUSE_MAX);
+
+static const uint16 _housetype_remove_ratingmod[] = {
+ 140, 130, 90, 230, 160, 160, 80, 150,
+ 150, 40, 40, 75, 75, 110, 100, 100,
+ 100, 150, 110, 110, 300, 300, 300, 300,
+ 75, 75, 75, 100, 170, 135, 180, 230,
+ 300, 300, 300, 300, 250, 75, 75, 230,
+ 300, 300, 300, 300, 90, 90, 70, 70,
+ 70, 70, 120, 120, 130, 130, 140, 140,
+ 60, 60, 80, 80, 230, 230, 80, 80,
+ 110, 110, 160, 160, 160, 160, 105, 105,
+ 135, 135, 200, 200, 200, 200, 80, 80,
+ 80, 30, 95, 200, 80, 95, 95, 140,
+ 140, 95, 150, 200, 90, 50, 75, 75,
+ 75, 75, 130, 80, 80, 130, 45, 45,
+ 130, 130, 130, 70, 65, 95,
+};
+assert_compile(lengthof(_housetype_remove_ratingmod) == HOUSE_MAX);
+
+
+typedef struct {
+ Year min, max;
+} HousetypeYear;
+
+static const HousetypeYear _housetype_years[] = {
+ { 1963, MAX_YEAR },
+ { 1957, MAX_YEAR },
+ { 1968, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 1975, MAX_YEAR },
+ { 1975, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 1959, MAX_YEAR },
+ { 1959, MAX_YEAR },
+ { 1945, MAX_YEAR },
+ { 1945, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 1935, MAX_YEAR },
+ { 1951, MAX_YEAR },
+ { 1930, 1960 },
+ { 1930, 1960 },
+ { 1930, 1960 },
+ { 1977, MAX_YEAR },
+ { 1983, MAX_YEAR },
+ { 1985, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, 1951 },
+ { 0, 1952 },
+ { 1931, MAX_YEAR },
+ { 1935, MAX_YEAR },
+ { 1963, MAX_YEAR },
+ { 0, 1955 },
+ { 1973, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 1958, MAX_YEAR },
+ { 1958, MAX_YEAR },
+ { 1958, MAX_YEAR },
+ { 1958, MAX_YEAR },
+ { 2000, MAX_YEAR },
+ { 0, 1960 },
+ { 0, 1960 },
+ { 1945, MAX_YEAR },
+ { 1983, MAX_YEAR },
+ { 1983, MAX_YEAR },
+ { 1983, MAX_YEAR },
+ { 1983, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, 1963 },
+ { 0, 1963 },
+ { 1966, MAX_YEAR },
+ { 1966, MAX_YEAR },
+ { 1970, MAX_YEAR },
+ { 1970, MAX_YEAR },
+ { 1974, MAX_YEAR },
+ { 1974, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, 1960 },
+ { 0, 1960 },
+ { 1972, MAX_YEAR },
+ { 1972, MAX_YEAR },
+ { 1972, MAX_YEAR },
+ { 1972, MAX_YEAR },
+ { 1963, MAX_YEAR },
+ { 1963, MAX_YEAR },
+ { 1978, MAX_YEAR },
+ { 1978, MAX_YEAR },
+ { 1967, MAX_YEAR },
+ { 1967, MAX_YEAR },
+ { 1967, MAX_YEAR },
+ { 1967, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 1973, MAX_YEAR },
+ { 1962, MAX_YEAR },
+ { 1984, MAX_YEAR },
+ { 1984, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 1993, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+ { 0, MAX_YEAR },
+};
+assert_compile(lengthof(_housetype_years) == HOUSE_MAX);
+
+static const byte _housetype_cargo_passengers[] = {
+ 8, 8, 8, 2, 10, 10, 4, 6,
+ 6, 2, 2, 2, 2, 8, 6, 6,
+ 6, 10, 6, 6, 4, 4, 4, 4,
+ 3, 3, 3, 7, 8, 6, 8, 8,
+ 4, 4, 4, 4, 8, 3, 3, 8,
+ 8, 8, 8, 8, 5, 5, 3, 3,
+ 3, 3, 8, 8, 9, 9, 10, 10,
+ 2, 2, 3, 3, 2, 2, 3, 3,
+ 6, 6, 6, 6, 6, 6, 7, 7,
+ 9, 9, 7, 7, 7, 7, 3, 3,
+ 3, 3, 6, 2, 3, 6, 6, 8,
+ 8, 6, 8, 2, 6, 3, 3, 3,
+ 3, 3, 8, 4, 4, 8, 3, 3,
+ 8, 8, 8, 4, 3, 3,
+};
+assert_compile(lengthof(_housetype_cargo_passengers) == HOUSE_MAX);
+
+static const byte _housetype_cargo_mail[] = {
+ 3, 3, 3, 0, 4, 4, 1, 1,
+ 1, 0, 0, 0, 0, 2, 2, 2,
+ 2, 3, 3, 2, 0, 0, 0, 0,
+ 1, 1, 1, 2, 3, 2, 3, 2,
+ 0, 0, 0, 0, 3, 1, 1, 2,
+ 2, 2, 2, 2, 2, 2, 1, 1,
+ 1, 1, 3, 3, 3, 3, 3, 3,
+ 1, 1, 1, 1, 0, 0, 1, 1,
+ 2, 2, 1, 1, 1, 1, 2, 2,
+ 3, 3, 2, 2, 2, 2, 1, 1,
+ 1, 1, 2, 0, 1, 2, 2, 3,
+ 3, 2, 3, 0, 2, 1, 1, 1,
+ 1, 1, 4, 1, 1, 4, 1, 1,
+ 4, 4, 4, 1, 1, 2,
+};
+assert_compile(lengthof(_housetype_cargo_mail) == HOUSE_MAX);
+
+static const byte _housetype_cargo_goods[] = {
+ 4, 4, 1, 0, 6, 6, 0, 2,
+ 2, 0, 0, 0, 0, 4, 3, 3,
+ 3, 6, 8, 6, 0, 0, 0, 0,
+ 0, 0, 0, 2, 3, 3, 3, 2,
+ 0, 0, 0, 0, 2, 0, 0, 2,
+ 3, 3, 3, 3, 0, 0, 0, 0,
+ 0, 0, 4, 4, 4, 4, 5, 5,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 3, 3, 0, 2, 0, 2, 3, 3,
+ 4, 4, 2, 2, 2, 2, 0, 0,
+ 0, 0, 1, 0, 0, 1, 1, 4,
+ 4, 1, 4, 0, 2, 1, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 1,
+ 0, 0, 2, 2, 2, 0
+};
+assert_compile(lengthof(_housetype_cargo_goods) == HOUSE_MAX);
+
+static const byte _housetype_cargo_food[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 1, 0,
+ 0, 0, 0, 0, 2, 2, 2, 2,
+ 2, 2, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 0, 0, 1, 1,
+ 0, 0, 3, 0, 3, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 2, 2,
+ 2, 1, 0, 0, 2, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 4, 4, 0, 0, 0, 4
+};
+assert_compile(lengthof(_housetype_cargo_food) == HOUSE_MAX);
+
+static const byte _house_more_flags[] = {
+ 8, 8, 8, 8, 8, 8, 8, 12,
+ 0, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 15, 0, 0, 0,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 15, 0, 0, 0, 8, 8, 8, 8,
+ 15, 0, 0, 0, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 12, 0, 12, 0, 8, 8,
+ 8, 8, 10, 0, 10, 0, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 10,
+ 0, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 12, 0, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8,
+};
+assert_compile(lengthof(_house_more_flags) == HOUSE_MAX);
diff --git a/src/table/track_land.h b/src/table/track_land.h
new file mode 100644
index 000000000..78031e840
--- /dev/null
+++ b/src/table/track_land.h
@@ -0,0 +1,52 @@
+/* $Id$ */
+
+#define TILE_SEQ_LINE(img, dx, dy, sx, sy) { dx, dy, 0, sx, sy, 23, img },
+#define TILE_SEQ_END() { 0x80, 0, 0, 0, 0, 0, 0 }
+
+
+static const DrawTileSeqStruct _depot_gfx_NE[] = {
+ TILE_SEQ_LINE(SPR_RAIL_DEPOT_NE | PALETTE_MODIFIER_COLOR, 2, 13, 13, 1)
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _depot_gfx_SE[] = {
+ TILE_SEQ_LINE(SPR_RAIL_DEPOT_SE_1 | PALETTE_MODIFIER_COLOR, 2, 2, 1, 13)
+ TILE_SEQ_LINE(SPR_RAIL_DEPOT_SE_2 | PALETTE_MODIFIER_COLOR, 13, 2, 1, 13)
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _depot_gfx_SW[] = {
+ TILE_SEQ_LINE(SPR_RAIL_DEPOT_SW_1 | PALETTE_MODIFIER_COLOR, 2, 2, 13, 1)
+ TILE_SEQ_LINE(SPR_RAIL_DEPOT_SW_2 | PALETTE_MODIFIER_COLOR, 2, 13, 13, 1)
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _depot_gfx_NW[] = {
+ TILE_SEQ_LINE(SPR_RAIL_DEPOT_NW | PALETTE_MODIFIER_COLOR, 13, 2, 1, 13)
+ TILE_SEQ_END()
+};
+
+static const DrawTileSprites _depot_gfx_table[] = {
+ { SPR_FLAT_GRASS_TILE, _depot_gfx_NE },
+ { SPR_RAIL_TRACK_Y, _depot_gfx_SE },
+ { SPR_RAIL_TRACK_X, _depot_gfx_SW },
+ { SPR_FLAT_GRASS_TILE, _depot_gfx_NW }
+};
+
+
+static const DrawTileSeqStruct _waypoint_gfx_X[] = {
+ TILE_SEQ_LINE(PALETTE_MODIFIER_COLOR | SPR_WAYPOINT_X_1, 0, 0, 16, 5)
+ TILE_SEQ_LINE(PALETTE_MODIFIER_COLOR | SPR_WAYPOINT_X_2, 0, 11, 16, 5)
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _waypoint_gfx_Y[] = {
+ TILE_SEQ_LINE(PALETTE_MODIFIER_COLOR | SPR_WAYPOINT_Y_1, 0, 0, 5, 16)
+ TILE_SEQ_LINE(PALETTE_MODIFIER_COLOR | SPR_WAYPOINT_Y_2, 11, 0, 5, 16)
+ TILE_SEQ_END()
+};
+
+static const DrawTileSprites _waypoint_gfx_table[] = {
+ { SPR_RAIL_TRACK_X, _waypoint_gfx_X },
+ { SPR_RAIL_TRACK_Y, _waypoint_gfx_Y }
+};
diff --git a/src/table/train_cmd.h b/src/table/train_cmd.h
new file mode 100644
index 000000000..1bf8e70c8
--- /dev/null
+++ b/src/table/train_cmd.h
@@ -0,0 +1,57 @@
+/* $Id$ */
+
+static const SpriteID _engine_sprite_base[] = {
+0x0B59, 0x0B61, 0x0B69, 0x0BE1, 0x0B71, 0x0B75, 0x0B7D, 0x0B7D,
+0x0B85, 0x0B85, 0x0B8D, 0x0B8D, 0x0BC9, 0x0BD1, 0x0BD9, 0x0BE9,
+0x0BED, 0x0BED, 0x0BF5, 0x0BF9, 0x0B79, 0x0B9D, 0x0B9D, 0x0B95,
+0x0B95, 0x0BA5, 0x0BA9, 0x0BA9, 0x0BC1, 0x0BC5, 0x0BB1, 0x0BB9,
+0x0BB9, 0x0AAD, 0x0AB1, 0x0AB5, 0x0AB9, 0x0ABD, 0x0AC1, 0x0AC9,
+0x0ACD, 0x0AD5, 0x0AD1, 0x0AD9, 0x0AC5, 0x0AD1, 0x0AD5, 0x0AF9,
+0x0AFD, 0x0B05, 0x0AB9, 0x0AC1, 0x0AC9, 0x0AD1, 0x0AD9, 0x0AE1,
+0x0AE5, 0x0AE9, 0x0AF1, 0x0AF9, 0x0B0D, 0x0B11, 0x0B15, 0x0B19,
+0x0B1D, 0x0B21, 0x0B29, 0x0B2D, 0x0B35, 0x0B31, 0x0B39, 0x0B25,
+0x0B31, 0x0B35,
+};
+
+/* For how many directions do we have sprites? (8 or 4; if 4, the other 4
+ * directions are symmetric. */
+static const byte _engine_sprite_and[] = {
+7, 7, 7, 7, 3, 3, 7, 7,
+7, 7, 7, 7, 7, 7, 7, 3,
+7, 7, 3, 7, 3, 7, 7, 7,
+7, 3, 7, 7, 3, 3, 7, 7,
+7, 3, 3, 3, 3, 3, 3, 3,
+3, 3, 3, 3, 3, 3, 3, 3,
+3, 3, 3, 3, 3, 3, 3, 3,
+3, 3, 3, 3, 3, 3, 3, 3,
+3, 3, 3, 3, 3, 3, 3, 3,
+3, 3,
+};
+
+/* Non-zero for multihead trains. */
+static const byte _engine_sprite_add[] = {
+0, 0, 0, 0, 0, 0, 0, 4,
+0, 4, 0, 4, 0, 0, 0, 0,
+0, 4, 0, 0, 0, 0, 4, 0,
+4, 0, 0, 4, 0, 0, 0, 0,
+4, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0,
+0, 0,
+};
+
+
+static const byte _wagon_full_adder[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 44, 0, 0, 0, 0, 24,
+ 24, 24, 24, 0, 0, 32, 32, 0,
+ 4, 4, 4, 4, 4, 4, 4, 0,
+ 0, 4, 4, 4, 0, 44, 0, 0,
+ 0, 0, 24, 24, 24, 24, 0, 0,
+ 32, 32
+};
diff --git a/src/table/tree_land.h b/src/table/tree_land.h
new file mode 100644
index 000000000..9d68681d6
--- /dev/null
+++ b/src/table/tree_land.h
@@ -0,0 +1,228 @@
+/* $Id$ */
+
+#ifndef TREE_LAND_H
+#define TREE_LAND_H
+
+static const SpriteID _tree_sprites_1[] = {
+ SPR_FLAT_1_QUART_SNOWY_TILE,
+ SPR_FLAT_2_QUART_SNOWY_TILE,
+ SPR_FLAT_3_QUART_SNOWY_TILE,
+ SPR_FLAT_SNOWY_TILE
+};
+
+static const byte _tree_base_by_landscape[4] = {0, 12, 20, 32};
+static const byte _tree_count_by_landscape[4] = {12, 8, 12, 9};
+
+typedef struct TreePos {
+ uint8 x;
+ uint8 y;
+} TreePos;
+
+static const TreePos _tree_layout_xy[][4] = {
+ { { 9, 3 }, { 1, 8 }, { 0, 0 }, { 8, 9 } },
+ { { 4, 4 }, { 9, 1 }, { 6, 9 }, { 0, 9 } },
+ { { 9, 1 }, { 0, 9 }, { 6, 6 }, { 3, 0 } },
+ { { 3, 9 }, { 8, 2 }, { 9, 9 }, { 1, 5 } }
+};
+
+static const PalSpriteID _tree_layout_sprite[164+(79-48+1)][4] = {
+ { 0x652, 0x659, 0x660, 0x667}, /* 0 */
+ { 0x652, 0x667, 0x66e, 0x675}, /* 1 */
+ { 0x652, 0x66e, 0x659, 0x675}, /* 2 */
+ { 0x652, 0x652, 0x660, 0x66e}, /* 3 */
+ { 0x660, 0x667, 0x659, 0x652}, /* 4 */
+ { 0x660, 0x675, 0x660, 0x660}, /* 5 */
+ { 0x660, 0x652, 0x652, 0x66e}, /* 6 */
+ { 0x660, 0x675, 0x667, 0x659}, /* 7 */
+ { 0x675, 0x660, 0x675, 0x675}, /* 8 */
+ { 0x675, 0x659, 0x652, 0x652}, /* 9 */
+ { 0x675, 0x66e, 0x652, 0x652}, /* 10 */
+ { 0x675, 0x667, 0x659, 0x667}, /* 11 */
+ { 0x628, 0x652, 0x660, 0x62f}, /* 12 */
+ { 0x628, 0x636, 0x675, 0x644}, /* 13 */
+ { 0x628, 0x652, 0x63d, 0x66e}, /* 14 */
+ { 0x628, 0x667, 0x644, 0x652}, /* 15 */
+ { 0x644, 0x659, 0x660, 0x628}, /* 16 */
+ { 0x644, 0x64b, 0x659, 0x636}, /* 17 */
+ { 0x644, 0x675, 0x652, 0x63d}, /* 18 */
+ { 0x644, 0x63d, 0x66e, 0x652}, /* 19 */
+ { 0x636, 0x636, 0x628, 0x636}, /* 20 */
+ { 0x636, 0x63d, 0x636, 0x636}, /* 21 */
+ { 0x636, 0x64b, 0x636, 0x636}, /* 22 */
+ { 0x636, 0x636, 0x636, 0x636}, /* 23 */
+ { 0x64b, 0x628, 0x62f, 0x636}, /* 24 */
+ { 0x64b, 0x63d, 0x644, 0x636}, /* 25 */
+ { 0x64b, 0x636, 0x63d, 0x628}, /* 26 */
+ { 0x64b, 0x64b, 0x636, 0x63d}, /* 27 */
+ { 0x62f, 0x644, 0x644, 0x636}, /* 28 */
+ { 0x62f, 0x62f, 0x636, 0x628}, /* 29 */
+ { 0x62f, 0x64b, 0x636, 0x636}, /* 30 */
+ { 0x62f, 0x636, 0x62f, 0x636}, /* 31 */
+ { 0x67c, 0x675, 0x683, 0x67c}, /* 32 */
+ { 0x67c, 0x69f, 0x67c, 0x659}, /* 33 */
+ { 0x67c, 0x67c, 0x67c, 0x6a6}, /* 34 */
+ { 0x67c, 0x691, 0x66e, 0x68a}, /* 35 */
+ { 0x68a, 0x68a, 0x698, 0x68a}, /* 36 */
+ { 0x68a, 0x698, 0x683, 0x68a}, /* 37 */
+ { 0x68a, 0x67c, 0x691, 0x68a}, /* 38 */
+ { 0x68a, 0x683, 0x6a6, 0x69f}, /* 39 */
+ { 0x698, 0x68a, 0x698, 0x652}, /* 40 */
+ { 0x698, 0x698, 0x660, 0x667}, /* 41 */
+ { 0x698, 0x67c, 0x6a6, 0x698}, /* 42 */
+ { 0x698, 0x698, 0x698, 0x691}, /* 43 */
+ { 0x6a6, 0x6a6, 0x67c, 0x660}, /* 44 */
+ { 0x6a6, 0x69f, 0x6a6, 0x652}, /* 45 */
+ { 0x6a6, 0x67c, 0x6a6, 0x691}, /* 46 */
+ { 0x6a6, 0x691, 0x69f, 0x6a6}, /* 47 */
+ { 0x6ad, 0x6ad, 0x6ad, 0x6ad}, /* 48 */
+ { 0x6ad, 0x6ad, 0x6c2, 0x6d0}, /* 49 */
+ { 0x6ad, 0x6d7, 0x6ad, 0x6ad}, /* 50 */
+ { 0x6ad, 0x6d0, 0x6c9, 0x6ad}, /* 51 */
+ { 0x6d0, 0x6d0, 0x6d0, 0x6ad}, /* 52 */
+ { 0x6d0, 0x6ad, 0x6d7, 0x6c9}, /* 53 */
+ { 0x6d0, 0x6d7, 0x6d0, 0x6c2}, /* 54 */
+ { 0x6d0, 0x6d0, 0x6d0, 0x6ad}, /* 55 */
+ { 0x6d7, 0x6d7, 0x6d7, 0x6d7}, /* 56 */
+ { 0x6d7, 0x6d7, 0x6ad, 0x6ad}, /* 57 */
+ { 0x6d7, 0x6d0, 0x6d7, 0x6ad}, /* 58 */
+ { 0x6d7, 0x6d7, 0x6d0, 0x6ad}, /* 59 */
+ { 0x6c2, 0x6d0, 0x6c9, 0x6c2}, /* 60 */
+ { 0x6c2, 0x6c9, 0x6c2, 0x6ad}, /* 61 */
+ { 0x6c2, 0x6c2, 0x6c2, 0x6ad}, /* 62 */
+ { 0x6c2, 0x6c2, 0x6c2, 0x6c9}, /* 63 */
+ { 0x6c9, 0x6d0, 0x6b4, 0x6c2}, /* 64 */
+ { 0x6c9, 0x6bb, 0x6de, 0x6d7}, /* 65 */
+ { 0x6c9, 0x6c2, 0x6bb, 0x6b4}, /* 66 */
+ { 0x6c9, 0x6bb, 0x6c2, 0x6de}, /* 67 */
+ { 0x6b4, 0x6b4, 0x6de, 0x6c9}, /* 68 */
+ { 0x6b4, 0x6bb, 0x6bb, 0x6ad}, /* 69 */
+ { 0x6b4, 0x6de, 0x6bb, 0x6b4}, /* 70 */
+ { 0x6b4, 0x6ad, 0x6c2, 0x6de}, /* 71 */
+ { 0x6bb, 0x6d0, 0x6de, 0x6c2}, /* 72 */
+ { 0x6bb, 0x6b4, 0x6bb, 0x6d7}, /* 73 */
+ { 0x6bb, 0x6de, 0x6bb, 0x6b4}, /* 74 */
+ { 0x6bb, 0x6c9, 0x6c2, 0x6de}, /* 75 */
+ { 0x6de, 0x6d7, 0x6de, 0x6c2}, /* 76 */
+ { 0x6de, 0x6bb, 0x6de, 0x6d0}, /* 77 */
+ { 0x6de, 0x6de, 0x6bb, 0x6b4}, /* 78 */
+ { 0x6de, 0x6c9, 0x6c2, 0x6de}, /* 79 */
+ { 0x72b, 0x732, 0x72b, 0x739}, /* 80 */
+ { 0x72b, 0x747, 0x755, 0x72b}, /* 81 */
+ { 0x72b, 0x72b, 0x76a, 0x786}, /* 82 */
+ { 0x72b, 0x74e, 0x72b, 0x72b}, /* 83 */
+ { 0x732, 0x732, 0x72b, 0x739}, /* 84 */
+ { 0x732, 0x747, 0x732, 0x732}, /* 85 */
+ { 0x732, 0x732, 0x755, 0x794}, /* 86 */
+ { 0x732, 0x74e, 0x732, 0x78d}, /* 87 */
+ { 0x747, 0x732, 0x747, 0x740}, /* 88 */
+ { 0x747, 0x747, 0x732, 0x76a}, /* 89 */
+ { 0x747, 0x72b, 0x755, 0x747}, /* 90 */
+ { 0x747, 0x786, 0x732, 0x747}, /* 91 */
+ { 0x74e, 0x74e, 0x72b, 0x794}, /* 92 */
+ { 0x74e, 0x755, 0x732, 0x74e}, /* 93 */
+ { 0x74e, 0x72b, 0x786, 0x747}, /* 94 */
+ { 0x74e, 0x74e, 0x732, 0x794}, /* 95 */
+ { 0x76a, 0x76a, 0x74e, 0x74e}, /* 96 */
+ { 0x76a, 0x794, 0x732, 0x76a}, /* 97 */
+ { 0x76a, 0x732, 0x786, 0x76a}, /* 98 */
+ { 0x76a, 0x786, 0x732, 0x78d}, /* 99 */
+ { 0x78d, 0x78d, 0x74e, 0x794}, /* 100 */
+ { 0x78d, 0x732, 0x739, 0x747}, /* 101 */
+ { 0x78d, 0x732, 0x786, 0x76a}, /* 102 */
+ { 0x78d, 0x786, 0x78d, 0x794}, /* 103 */
+ { 0x786, 0x786, 0x740, 0x732}, /* 104 */
+ { 0x786, 0x786, 0x72b, 0x732}, /* 105 */
+ { 0x786, 0x732, 0x786, 0x786}, /* 106 */
+ { 0x786, 0x786, 0x78d, 0x794}, /* 107 */
+ { 0x778, 0x778, 0x77f, 0x778}, /* 108 */
+ { 0x778, 0x77f, 0x778, 0x77f}, /* 109 */
+ { 0x778, 0x77f, 0x77f, 0x778}, /* 110 */
+ { 0x778, 0x778, 0x778, 0x77f}, /* 111 */
+ { 0x75c, 0x71d, 0x75c, 0x724}, /* 112 */
+ { 0x75c, 0x72b, 0x75c, 0x763}, /* 113 */
+ { 0x75c, 0x75c, 0x771, 0x71d}, /* 114 */
+ { 0x75c, 0x771, 0x75c, 0x75c}, /* 115 */
+ { 0x771, 0x771, 0x75c, 0x71d}, /* 116 */
+ { 0x771, 0x747, 0x75c, 0x771}, /* 117 */
+ { 0x771, 0x75c, 0x771, 0x724}, /* 118 */
+ { 0x771, 0x771, 0x75c, 0x763}, /* 119 */
+ { 0x71d, 0x71d, 0x771, 0x724}, /* 120 */
+ { 0x71d, 0x74e, 0x763, 0x71d}, /* 121 */
+ { 0x71d, 0x724, 0x794, 0x71d}, /* 122 */
+ { 0x71d, 0x71d, 0x75c, 0x78d}, /* 123 */
+ { 0x794, 0x724, 0x75c, 0x794}, /* 124 */
+ { 0x794, 0x794, 0x75c, 0x71d}, /* 125 */
+ { 0x794, 0x724, 0x794, 0x71d}, /* 126 */
+ { 0x794, 0x794, 0x771, 0x78d}, /* 127 */
+ { 0x79b | PALETTE_TO_RED, 0x79b | PALETTE_TO_PALE_GREEN, 0x79b | PALETTE_TO_MAUVE, 0x79b | PALETTE_TO_PURPLE}, /* 128 */
+ { 0x79b, 0x79b | PALETTE_TO_GREY, 0x79b | PALETTE_TO_GREEN, 0x79b | PALETTE_TO_WHITE}, /* 129 */
+ { 0x79b | PALETTE_TO_GREEN, 0x79b | PALETTE_TO_ORANGE, 0x79b | PALETTE_TO_PINK, 0x79b}, /* 130 */
+ { 0x79b | PALETTE_TO_YELLOW, 0x79b | PALETTE_TO_RED, 0x79b | PALETTE_TO_CREAM, 0x79b | PALETTE_TO_RED}, /* 131 */
+ { 0x7a2, 0x7a2 | PALETTE_TO_RED, 0x7a2 | PALETTE_TO_PINK, 0x7a2 | PALETTE_TO_PURPLE}, /* 132 */
+ { 0x7a2 | PALETTE_TO_MAUVE, 0x7a2 | PALETTE_TO_GREEN, 0x7a2 | PALETTE_TO_PINK, 0x7a2 | PALETTE_TO_GREY}, /* 133 */
+ { 0x7a2 | PALETTE_TO_RED, 0x7a2 | PALETTE_TO_PALE_GREEN, 0x7a2 | PALETTE_TO_YELLOW, 0x7a2 | PALETTE_TO_WHITE}, /* 134 */
+ { 0x7a2 | PALETTE_TO_ORANGE, 0x7a2 | PALETTE_TO_MAUVE, 0x7a2 | PALETTE_TO_CREAM, 0x7a2 | PALETTE_TO_BROWN}, /* 135 */
+ { 0x7a9 | PALETTE_TO_RED, 0x7a9, 0x7a9 | PALETTE_TO_ORANGE, 0x7a9 | PALETTE_TO_GREY}, /* 136 */
+ { 0x7a9 | PALETTE_TO_ORANGE, 0x7a9 | PALETTE_TO_GREEN, 0x7a9 | PALETTE_TO_PALE_GREEN, 0x7a9 | PALETTE_TO_MAUVE}, /* 137 */
+ { 0x7a9 | PALETTE_TO_PINK, 0x7a9 | PALETTE_TO_RED, 0x7a9 | PALETTE_TO_GREEN, 0x7a9 | PALETTE_TO_BROWN}, /* 138 */
+ { 0x7a9 | PALETTE_TO_GREEN, 0x7a9, 0x7a9 | PALETTE_TO_RED, 0x7a9 | PALETTE_TO_CREAM}, /* 139 */
+ { 0x7b0, 0x7b0, 0x7b0, 0x7b0}, /* 140 */
+ { 0x7b0, 0x7b0, 0x7b0, 0x7b0}, /* 141 */
+ { 0x7b0, 0x7b0, 0x7b0, 0x7b0}, /* 142 */
+ { 0x7b0, 0x7b0, 0x7b0, 0x7b0}, /* 143 */
+ { 0x7b7 | PALETTE_TO_PINK, 0x7b7 | PALETTE_TO_RED, 0x7b7 | PALETTE_TO_ORANGE, 0x7b7 | PALETTE_TO_MAUVE}, /* 144 */
+ { 0x7b7 | PALETTE_TO_RED, 0x7b7, 0x7b7 | PALETTE_TO_GREY, 0x7b7 | PALETTE_TO_CREAM}, /* 145 */
+ { 0x7b7 | PALETTE_TO_GREEN, 0x7b7 | PALETTE_TO_BROWN, 0x7b7 | PALETTE_TO_PINK, 0x7b7 | PALETTE_TO_RED}, /* 146 */
+ { 0x7b7, 0x7b7 | PALETTE_TO_PALE_GREEN, 0x7b7 | PALETTE_TO_ORANGE, 0x7b7 | PALETTE_TO_RED}, /* 147 */
+ { 0x7be | PALETTE_TO_RED, 0x7be | PALETTE_TO_PINK, 0x7be | PALETTE_TO_GREEN, 0x7be}, /* 148 */
+ { 0x7be | PALETTE_TO_GREEN, 0x7be | PALETTE_TO_BROWN, 0x7be | PALETTE_TO_PURPLE, 0x7be | PALETTE_TO_GREY}, /* 149 */
+ { 0x7be | PALETTE_TO_MAUVE, 0x7be | PALETTE_TO_CREAM, 0x7be | PALETTE_TO_ORANGE, 0x7be | PALETTE_TO_RED}, /* 150 */
+ { 0x7be, 0x7be | PALETTE_TO_RED, 0x7be | PALETTE_TO_PALE_GREEN, 0x7be | PALETTE_TO_PINK}, /* 151 */
+ { 0x7c5 | PALETTE_TO_YELLOW, 0x7c5 | PALETTE_TO_RED, 0x7c5 | PALETTE_TO_WHITE, 0x7c5 | PALETTE_TO_CREAM}, /* 152 */
+ { 0x7c5 | PALETTE_TO_RED, 0x7c5 | PALETTE_TO_PALE_GREEN, 0x7c5 | PALETTE_TO_BROWN, 0x7c5 | PALETTE_TO_YELLOW}, /* 153 */
+ { 0x7c5, 0x7c5 | PALETTE_TO_PURPLE, 0x7c5 | PALETTE_TO_GREEN, 0x7c5 | PALETTE_TO_YELLOW}, /* 154 */
+ { 0x7c5 | PALETTE_TO_PINK, 0x7c5 | PALETTE_TO_CREAM, 0x7c5, 0x7c5 | PALETTE_TO_GREY}, /* 155 */
+ { 0x7cc | PALETTE_TO_YELLOW, 0x7cc | PALETTE_TO_GREY, 0x7cc | PALETTE_TO_PURPLE, 0x7cc | PALETTE_TO_BROWN}, /* 156 */
+ { 0x7cc | PALETTE_TO_GREEN, 0x7cc, 0x7cc | PALETTE_TO_CREAM, 0x7cc | PALETTE_TO_WHITE}, /* 157 */
+ { 0x7cc | PALETTE_TO_RED, 0x7cc | PALETTE_TO_PALE_GREEN, 0x7cc | PALETTE_TO_MAUVE, 0x7cc | PALETTE_TO_RED}, /* 158 */
+ { 0x7cc | PALETTE_TO_PINK, 0x7cc | PALETTE_TO_ORANGE, 0x7cc | PALETTE_TO_GREEN, 0x7cc | PALETTE_TO_YELLOW}, /* 159 */
+ { 0x7d3 | PALETTE_TO_RED, 0x7d3 | PALETTE_TO_PINK, 0x7d3 | PALETTE_TO_BROWN, 0x7d3 | PALETTE_TO_WHITE}, /* 160 */
+ { 0x7d3 | PALETTE_TO_GREEN, 0x7d3 | PALETTE_TO_ORANGE, 0x7d3 | PALETTE_TO_GREY, 0x7d3 | PALETTE_TO_MAUVE}, /* 161 */
+ { 0x7d3 | PALETTE_TO_YELLOW, 0x7d3 | PALETTE_TO_PALE_GREEN, 0x7d3, 0x7d3 | PALETTE_TO_CREAM}, /* 162 */
+ { 0x7d3 | PALETTE_TO_GREY, 0x7d3 | PALETTE_TO_RED, 0x7d3 | PALETTE_TO_WHITE, 0x7d3}, /* 163 */
+ /* the extra things follow */
+ { 0x6e5, 0x6e5, 0x6e5, 0x6e5}, /* 0 */
+ { 0x6e5, 0x6e5, 0x6fa, 0x708}, /* 1 */
+ { 0x6e5, 0x70f, 0x6e5, 0x6e5}, /* 2 */
+ { 0x6e5, 0x708, 0x701, 0x6e5}, /* 3 */
+ { 0x708, 0x708, 0x708, 0x6e5}, /* 4 */
+ { 0x708, 0x6e5, 0x70f, 0x701}, /* 5 */
+ { 0x708, 0x70f, 0x708, 0x6fa}, /* 6 */
+ { 0x708, 0x708, 0x708, 0x6e5}, /* 7 */
+ { 0x70f, 0x70f, 0x70f, 0x70f}, /* 8 */
+ { 0x70f, 0x70f, 0x6e5, 0x6e5}, /* 9 */
+ { 0x70f, 0x708, 0x70f, 0x6e5}, /* 10 */
+ { 0x70f, 0x70f, 0x708, 0x6e5}, /* 11 */
+ { 0x6fa, 0x708, 0x701, 0x6fa}, /* 12 */
+ { 0x6fa, 0x701, 0x6fa, 0x6e5}, /* 13 */
+ { 0x6fa, 0x6fa, 0x6fa, 0x6e5}, /* 14 */
+ { 0x6fa, 0x6fa, 0x6fa, 0x701}, /* 15 */
+ { 0x701, 0x708, 0x6ec, 0x6fa}, /* 16 */
+ { 0x701, 0x6f3, 0x716, 0x70f}, /* 17 */
+ { 0x701, 0x6fa, 0x6f3, 0x6ec}, /* 18 */
+ { 0x701, 0x6f3, 0x6fa, 0x716}, /* 19 */
+ { 0x6ec, 0x6ec, 0x716, 0x701}, /* 20 */
+ { 0x6ec, 0x6f3, 0x6f3, 0x6e5}, /* 21 */
+ { 0x6ec, 0x716, 0x6f3, 0x6ec}, /* 22 */
+ { 0x6ec, 0x6e5, 0x6fa, 0x716}, /* 23 */
+ { 0x6f3, 0x708, 0x716, 0x6fa}, /* 24 */
+ { 0x6f3, 0x6ec, 0x6f3, 0x70f}, /* 25 */
+ { 0x6f3, 0x716, 0x6f3, 0x6ec}, /* 26 */
+ { 0x6f3, 0x701, 0x6fa, 0x716}, /* 27 */
+ { 0x716, 0x70f, 0x716, 0x6fa}, /* 28 */
+ { 0x716, 0x6f3, 0x716, 0x708}, /* 29 */
+ { 0x716, 0x716, 0x6f3, 0x6ec}, /* 30 */
+ { 0x716, 0x701, 0x6fa, 0x716}, /* 31 */
+};
+
+#endif /* TREE_LAND_H */
diff --git a/src/table/unicode.h b/src/table/unicode.h
new file mode 100644
index 000000000..2bbd6624c
--- /dev/null
+++ b/src/table/unicode.h
@@ -0,0 +1,21 @@
+/* $Id$ */
+
+
+typedef struct DefaultUnicodeMapping {
+ WChar code; ///< Unicode value
+ byte key; ///< Character index of sprite
+} DefaultUnicodeMapping;
+
+
+/* Default unicode mapping table for sprite based glyphs.
+ * This table allows us use unicode characters even though the glyphs don't
+ * exist, or are in the wrong place, in the standard sprite fonts.
+ * This is not used for FreeType rendering */
+
+static DefaultUnicodeMapping _default_unicode_map[] = {
+ { 0x010D, 0x63 }, /* Small letter c with caron */
+ { 0x0160, 0xA6 }, /* Capital letter s with caron */
+ { 0x0161, 0xA8 }, /* Small letter s with caron */
+ { 0x017E, 0xB8 }, /* Small letter z with caron */
+ { 0x20AC, 0xA4 }, /* Euro symbol */
+};
diff --git a/src/table/unmovable_land.h b/src/table/unmovable_land.h
new file mode 100644
index 000000000..9b9e7d6cd
--- /dev/null
+++ b/src/table/unmovable_land.h
@@ -0,0 +1,131 @@
+/* $Id$ */
+
+typedef struct DrawTileUnmovableStruct {
+ uint16 image;
+ byte subcoord_x;
+ byte subcoord_y;
+ byte width;
+ byte height;
+ byte z_size;
+ byte unused;
+} DrawTileUnmovableStruct;
+
+#define TILE_SEQ_END() { 0x80, 0, 0, 0, 0, 0, 0 }
+
+static const DrawTileUnmovableStruct _draw_tile_unmovable_data[] = {
+ {0xA29, 7, 7, 2, 2, 70, 0},
+ {0xA2A, 4, 4, 7, 7, 61, 0},
+};
+
+
+static const DrawTileSeqStruct _unmovable_display_datas_0[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _unmovable_display_datas_1[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _unmovable_display_datas_2[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _unmovable_display_datas_3[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _unmovable_display_datas_4[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _unmovable_display_datas_5[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _unmovable_display_datas_6[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _unmovable_display_datas_7[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _unmovable_display_datas_8[] = {
+ { 0, 0, 0, 16, 16, 20, 0xA34 | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _unmovable_display_datas_9[] = {
+ { 0, 0, 0, 16, 16, 20, 0xA36 | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _unmovable_display_datas_10[] = {
+ { 0, 0, 0, 16, 16, 20, 0xA38 | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _unmovable_display_datas_11[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _unmovable_display_datas_12[] = {
+ { 0, 0, 0, 16, 16, 50, 0xA3B | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _unmovable_display_datas_13[] = {
+ { 0, 0, 0, 16, 16, 50, 0xA3D | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _unmovable_display_datas_14[] = {
+ { 0, 0, 0, 16, 16, 50, 0xA3F | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _unmovable_display_datas_15[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _unmovable_display_datas_16[] = {
+ { 0, 0, 0, 16, 16, 60, 0xA42 | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _unmovable_display_datas_17[] = {
+ { 0, 0, 0, 16, 16, 60, 0xA44 | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _unmovable_display_datas_18[] = {
+ { 0, 0, 0, 16, 16, 60, 0xA46 | PALETTE_MODIFIER_COLOR },
+ TILE_SEQ_END()
+};
+
+static const DrawTileSeqStruct _unmovable_display_datas_19[] = {
+ TILE_SEQ_END()
+};
+
+static const DrawTileSprites _unmovable_display_datas[] = {
+ { 0xA2B | PALETTE_MODIFIER_COLOR, _unmovable_display_datas_0 },
+ { 0xA2C | PALETTE_MODIFIER_COLOR, _unmovable_display_datas_1 },
+ { 0xA2D | PALETTE_MODIFIER_COLOR, _unmovable_display_datas_2 },
+ { 0xA2E | PALETTE_MODIFIER_COLOR, _unmovable_display_datas_3 },
+ { 0xA2F | PALETTE_MODIFIER_COLOR, _unmovable_display_datas_4 },
+ { 0xA30 | PALETTE_MODIFIER_COLOR, _unmovable_display_datas_5 },
+ { 0xA31 | PALETTE_MODIFIER_COLOR, _unmovable_display_datas_6 },
+ { 0xA32 | PALETTE_MODIFIER_COLOR, _unmovable_display_datas_7 },
+ { 0xA33 | PALETTE_MODIFIER_COLOR, _unmovable_display_datas_8 },
+ { 0xA35 | PALETTE_MODIFIER_COLOR, _unmovable_display_datas_9 },
+ { 0xA37 | PALETTE_MODIFIER_COLOR, _unmovable_display_datas_10 },
+ { 0xA39 | PALETTE_MODIFIER_COLOR, _unmovable_display_datas_11 },
+ { 0xA3A | PALETTE_MODIFIER_COLOR, _unmovable_display_datas_12 },
+ { 0xA3C | PALETTE_MODIFIER_COLOR, _unmovable_display_datas_13 },
+ { 0xA3E | PALETTE_MODIFIER_COLOR, _unmovable_display_datas_14 },
+ { 0xA40 | PALETTE_MODIFIER_COLOR, _unmovable_display_datas_15 },
+ { 0xA41 | PALETTE_MODIFIER_COLOR, _unmovable_display_datas_16 },
+ { 0xA43 | PALETTE_MODIFIER_COLOR, _unmovable_display_datas_17 },
+ { 0xA45 | PALETTE_MODIFIER_COLOR, _unmovable_display_datas_18 },
+ { 0xA47 | PALETTE_MODIFIER_COLOR, _unmovable_display_datas_19 },
+};
diff --git a/src/table/water_land.h b/src/table/water_land.h
new file mode 100644
index 000000000..96cef5f39
--- /dev/null
+++ b/src/table/water_land.h
@@ -0,0 +1,151 @@
+/* $Id$ */
+
+typedef struct WaterDrawTileStruct {
+ byte delta_x;
+ byte delta_y;
+ byte delta_z;
+ byte width;
+ byte height;
+ byte unk;
+ SpriteID image;
+} WaterDrawTileStruct;
+
+#define BEGIN(image) { 0, 0, 0, 0, 0, 0, image }
+#define END(y) { 0x80, y, 0, 0, 0, 0, 0 }
+
+static const WaterDrawTileStruct _shipdepot_display_seq_1[] = {
+ BEGIN(0xFDD),
+ { 0, 15, 0, 16, 1, 0x14, 0xFE8 | PALETTE_MODIFIER_COLOR },
+ END(0)
+};
+
+static const WaterDrawTileStruct _shipdepot_display_seq_2[] = {
+ BEGIN(0xFDD),
+ { 0, 0, 0, 16, 1, 0x14, 0xFEA },
+ { 0, 15, 0, 16, 1, 0x14, 0xFE6 | PALETTE_MODIFIER_COLOR },
+ END(0)
+};
+
+static const WaterDrawTileStruct _shipdepot_display_seq_3[] = {
+ BEGIN(0xFDD),
+ { 15, 0, 0, 1, 0x10, 0x14, 0xFE9 | PALETTE_MODIFIER_COLOR },
+ END(0)
+};
+
+static const WaterDrawTileStruct _shipdepot_display_seq_4[] = {
+ BEGIN(0xFDD),
+ { 0, 0, 0, 1, 16, 0x14, 0xFEB },
+ { 15, 0, 0, 1, 16, 0x14, 0xFE7 | PALETTE_MODIFIER_COLOR },
+ END(0)
+};
+
+static const WaterDrawTileStruct* const _shipdepot_display_seq[] = {
+ _shipdepot_display_seq_1,
+ _shipdepot_display_seq_2,
+ _shipdepot_display_seq_3,
+ _shipdepot_display_seq_4,
+};
+
+static const WaterDrawTileStruct _shiplift_display_seq_0[] = {
+ BEGIN(SPR_CANALS_BASE + 6),
+ { 0, 0, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 0 + 1 },
+ { 0, 0xF, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 4 + 1 },
+ END(0)
+};
+
+static const WaterDrawTileStruct _shiplift_display_seq_1[] = {
+ BEGIN(SPR_CANALS_BASE + 5),
+ { 0, 0, 0, 1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 0 },
+ { 0xF, 0, 0, 1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 4 },
+ END(0)
+};
+
+static const WaterDrawTileStruct _shiplift_display_seq_2[] = {
+ BEGIN(SPR_CANALS_BASE + 7),
+ { 0, 0, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 0 + 2 },
+ { 0, 0xF, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 4 + 2 },
+ END(0)
+};
+
+static const WaterDrawTileStruct _shiplift_display_seq_3[] = {
+ BEGIN(SPR_CANALS_BASE + 8),
+ { 0, 0, 0, 1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 0 + 3 },
+ { 0xF, 0, 0, 1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 4 + 3 },
+ END(0)
+};
+
+static const WaterDrawTileStruct _shiplift_display_seq_0b[] = {
+ BEGIN(0xFDD),
+ { 0, 0, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 8 + 1 },
+ { 0, 0xF, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 12 + 1 },
+ END(0)
+};
+
+static const WaterDrawTileStruct _shiplift_display_seq_1b[] = {
+ BEGIN(0xFDD),
+ { 0, 0, 0, 0x1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 8 },
+ { 0xF, 0, 0, 0x1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 12 },
+ END(0)
+};
+
+static const WaterDrawTileStruct _shiplift_display_seq_2b[] = {
+ BEGIN(0xFDD),
+ { 0, 0, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 8 + 2 },
+ { 0, 0xF, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 12 + 2 },
+ END(0)
+};
+
+static const WaterDrawTileStruct _shiplift_display_seq_3b[] = {
+ BEGIN(0xFDD),
+ { 0, 0, 0, 1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 8 + 3 },
+ { 0xF, 0, 0, 1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 12 + 3 },
+ END(0)
+};
+
+static const WaterDrawTileStruct _shiplift_display_seq_0t[] = {
+ BEGIN(0xFDD),
+ { 0, 0, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 16 + 1 },
+ { 0, 0xF, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 20 + 1 },
+ END(8)
+};
+
+static const WaterDrawTileStruct _shiplift_display_seq_1t[] = {
+ BEGIN(0xFDD),
+ { 0, 0, 0, 0x1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 16 },
+ { 0xF, 0, 0, 0x1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 20 },
+ END(8)
+};
+
+static const WaterDrawTileStruct _shiplift_display_seq_2t[] = {
+ BEGIN(0xFDD),
+ { 0, 0, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 16 + 2 },
+ { 0, 0xF, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 20 + 2 },
+ END(8)
+};
+
+static const WaterDrawTileStruct _shiplift_display_seq_3t[] = {
+ BEGIN(0xFDD),
+ { 0, 0, 0, 1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 16 + 3 },
+ { 0xF, 0, 0, 1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 20 + 3 },
+ END(8)
+};
+
+static const WaterDrawTileStruct* const _shiplift_display_seq[] = {
+ _shiplift_display_seq_0,
+ _shiplift_display_seq_1,
+ _shiplift_display_seq_2,
+ _shiplift_display_seq_3,
+
+ _shiplift_display_seq_0b,
+ _shiplift_display_seq_1b,
+ _shiplift_display_seq_2b,
+ _shiplift_display_seq_3b,
+
+ _shiplift_display_seq_0t,
+ _shiplift_display_seq_1t,
+ _shiplift_display_seq_2t,
+ _shiplift_display_seq_3t,
+};
+
+#undef BEGIN
+#undef END
diff --git a/src/terraform_gui.c b/src/terraform_gui.c
new file mode 100644
index 000000000..f0a48b2e2
--- /dev/null
+++ b/src/terraform_gui.c
@@ -0,0 +1,289 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "bridge_map.h"
+#include "clear_map.h"
+#include "table/sprites.h"
+#include "table/strings.h"
+#include "functions.h"
+#include "player.h"
+#include "tile.h"
+#include "window.h"
+#include "gui.h"
+#include "viewport.h"
+#include "gfx.h"
+#include "sound.h"
+#include "command.h"
+#include "vehicle.h"
+#include "signs.h"
+#include "variables.h"
+
+void CcTerraform(bool success, TileIndex tile, uint32 p1, uint32 p2)
+{
+ if (success) {
+ SndPlayTileFx(SND_1F_SPLAT, tile);
+ } else {
+ SetRedErrorSquare(_terraform_err_tile);
+ }
+}
+
+
+/** Scenario editor command that generates desert areas */
+static void GenerateDesertArea(TileIndex end, TileIndex start)
+{
+ int size_x, size_y;
+ int sx = TileX(start);
+ int sy = TileY(start);
+ int ex = TileX(end);
+ int ey = TileY(end);
+
+ if (_game_mode != GM_EDITOR) return;
+
+ if (ex < sx) intswap(ex, sx);
+ if (ey < sy) intswap(ey, sy);
+ size_x = (ex - sx) + 1;
+ size_y = (ey - sy) + 1;
+
+ _generating_world = true;
+ BEGIN_TILE_LOOP(tile, size_x, size_y, TileXY(sx, sy)) {
+ if (GetTileType(tile) != MP_WATER) {
+ SetTropicZone(tile, (_ctrl_pressed) ? TROPICZONE_INVALID : TROPICZONE_DESERT);
+ DoCommandP(tile, 0, 0, NULL, CMD_LANDSCAPE_CLEAR);
+ MarkTileDirtyByTile(tile);
+ }
+ } END_TILE_LOOP(tile, size_x, size_y, 0);
+ _generating_world = false;
+}
+
+/** Scenario editor command that generates rocky areas */
+static void GenerateRockyArea(TileIndex end, TileIndex start)
+{
+ int size_x, size_y;
+ bool success = false;
+ int sx = TileX(start);
+ int sy = TileY(start);
+ int ex = TileX(end);
+ int ey = TileY(end);
+
+ if (_game_mode != GM_EDITOR) return;
+
+ if (ex < sx) intswap(ex, sx);
+ if (ey < sy) intswap(ey, sy);
+ size_x = (ex - sx) + 1;
+ size_y = (ey - sy) + 1;
+
+ BEGIN_TILE_LOOP(tile, size_x, size_y, TileXY(sx, sy)) {
+ switch (GetTileType(tile)) {
+ case MP_CLEAR:
+ MakeClear(tile, CLEAR_ROCKS, 3);
+ break;
+
+ case MP_TREES:
+ MakeClear(tile, CLEAR_ROCKS, 3);
+ ClearBridgeMiddle(tile);
+ break;
+
+ default: continue;
+ }
+ MarkTileDirtyByTile(tile);
+ success = true;
+ } END_TILE_LOOP(tile, size_x, size_y, 0);
+
+ if (success) SndPlayTileFx(SND_1F_SPLAT, end);
+}
+
+/**
+ * A central place to handle all X_AND_Y dragged GUI functions.
+ * @param e @WindowEvent variable holding in its higher bits (excluding the lower
+ * 4, since that defined the X_Y drag) the type of action to be performed
+ * @return Returns true if the action was found and handled, and false otherwise. This
+ * allows for additional implements that are more local. For example X_Y drag
+ * of convertrail which belongs in rail_gui.c and not terraform_gui.c
+ **/
+bool GUIPlaceProcDragXY(const WindowEvent *e)
+{
+ TileIndex start_tile = e->we.place.starttile;
+ TileIndex end_tile = e->we.place.tile;
+
+ switch (e->we.place.userdata >> 4) {
+ case GUI_PlaceProc_DemolishArea >> 4:
+ DoCommandP(end_tile, start_tile, 0, CcPlaySound10, CMD_CLEAR_AREA | CMD_MSG(STR_00B5_CAN_T_CLEAR_THIS_AREA));
+ break;
+ case GUI_PlaceProc_LevelArea >> 4:
+ DoCommandP(end_tile, start_tile, 0, CcPlaySound10, CMD_LEVEL_LAND | CMD_AUTO);
+ break;
+ case GUI_PlaceProc_RockyArea >> 4:
+ GenerateRockyArea(end_tile, start_tile);
+ break;
+ case GUI_PlaceProc_DesertArea >> 4:
+ GenerateDesertArea(end_tile, start_tile);
+ break;
+ case GUI_PlaceProc_WaterArea >> 4:
+ DoCommandP(end_tile, start_tile, _ctrl_pressed, CcBuildCanal, CMD_BUILD_CANAL | CMD_AUTO | CMD_MSG(STR_CANT_BUILD_CANALS));
+ break;
+ default: return false;
+ }
+
+ return true;
+}
+
+typedef void OnButtonClick(Window *w);
+
+static const uint16 _terraform_keycodes[] = {
+ 'Q',
+ 'W',
+ 'E',
+ 'D',
+ 'U',
+ 'I',
+ 'O',
+};
+
+void PlaceProc_DemolishArea(TileIndex tile)
+{
+ VpStartPlaceSizing(tile, VPM_X_AND_Y | GUI_PlaceProc_DemolishArea);
+}
+
+static void PlaceProc_RaiseLand(TileIndex tile)
+{
+ DoCommandP(
+ tile, SLOPE_N, 1, CcTerraform,
+ CMD_TERRAFORM_LAND | CMD_AUTO | CMD_MSG(STR_0808_CAN_T_RAISE_LAND_HERE)
+ );
+}
+
+static void PlaceProc_LowerLand(TileIndex tile)
+{
+ DoCommandP(
+ tile, SLOPE_N, 0, CcTerraform,
+ CMD_TERRAFORM_LAND | CMD_AUTO | CMD_MSG(STR_0809_CAN_T_LOWER_LAND_HERE)
+ );
+}
+
+void PlaceProc_LevelLand(TileIndex tile)
+{
+ VpStartPlaceSizing(tile, VPM_X_AND_Y | GUI_PlaceProc_LevelArea);
+}
+
+static void TerraformClick_Lower(Window *w)
+{
+ HandlePlacePushButton(w, 4, ANIMCURSOR_LOWERLAND, 2, PlaceProc_LowerLand);
+}
+
+static void TerraformClick_Raise(Window *w)
+{
+ HandlePlacePushButton(w, 5, ANIMCURSOR_RAISELAND, 2, PlaceProc_RaiseLand);
+}
+
+static void TerraformClick_Level(Window *w)
+{
+ HandlePlacePushButton(w, 6, SPR_CURSOR_LEVEL_LAND, 2, PlaceProc_LevelLand);
+}
+
+static void TerraformClick_Dynamite(Window *w)
+{
+ HandlePlacePushButton(w, 7, ANIMCURSOR_DEMOLISH , 1, PlaceProc_DemolishArea);
+}
+
+static void TerraformClick_BuyLand(Window *w)
+{
+ HandlePlacePushButton(w, 8, SPR_CURSOR_BUY_LAND, 1, PlaceProc_BuyLand);
+}
+
+static void TerraformClick_Trees(Window *w)
+{
+ /* This button is NOT a place-push-button, so don't treat it as such */
+ ShowBuildTreesToolbar();
+}
+
+static void TerraformClick_PlaceSign(Window *w)
+{
+ HandlePlacePushButton(w, 10, SPR_CURSOR_SIGN, 1, PlaceProc_Sign);
+}
+
+static OnButtonClick * const _terraform_button_proc[] = {
+ TerraformClick_Lower,
+ TerraformClick_Raise,
+ TerraformClick_Level,
+ TerraformClick_Dynamite,
+ TerraformClick_BuyLand,
+ TerraformClick_Trees,
+ TerraformClick_PlaceSign,
+};
+
+static void TerraformToolbWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT:
+ DrawWindowWidgets(w);
+ break;
+
+ case WE_CLICK:
+ if (e->we.click.widget >= 4) _terraform_button_proc[e->we.click.widget - 4](w);
+ break;
+
+ case WE_KEYPRESS: {
+ uint i;
+
+ for (i = 0; i != lengthof(_terraform_keycodes); i++) {
+ if (e->we.keypress.keycode == _terraform_keycodes[i]) {
+ e->we.keypress.cont = false;
+ _terraform_button_proc[i](w);
+ break;
+ }
+ }
+ break;
+ }
+
+ case WE_PLACE_OBJ:
+ _place_proc(e->we.place.tile);
+ return;
+
+ case WE_PLACE_DRAG:
+ VpSelectTilesWithMethod(e->we.place.pt.x, e->we.place.pt.y, e->we.place.userdata & 0xF);
+ break;
+
+ case WE_PLACE_MOUSEUP:
+ if (e->we.place.pt.x != -1 &&
+ (e->we.place.userdata & 0xF) == VPM_X_AND_Y) { // dragged actions
+ GUIPlaceProcDragXY(e);
+ }
+ break;
+
+ case WE_ABORT_PLACE_OBJ:
+ RaiseWindowButtons(w);
+ break;
+ }
+}
+
+static const Widget _terraform_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 7, 11, 145, 0, 13, STR_LANDSCAPING_TOOLBAR, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{WWT_STICKYBOX, RESIZE_NONE, 7, 146, 157, 0, 13, STR_NULL, STR_STICKY_BUTTON},
+
+{ WWT_PANEL, RESIZE_NONE, 7, 66, 69, 14, 35, 0x0, STR_NULL},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 0, 21, 14, 35, SPR_IMG_TERRAFORM_DOWN, STR_018E_LOWER_A_CORNER_OF_LAND},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 22, 43, 14, 35, SPR_IMG_TERRAFORM_UP, STR_018F_RAISE_A_CORNER_OF_LAND},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 44, 65, 14, 35, SPR_IMG_LEVEL_LAND, STR_LEVEL_LAND_TOOLTIP},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 70, 91, 14, 35, SPR_IMG_DYNAMITE, STR_018D_DEMOLISH_BUILDINGS_ETC},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 92, 113, 14, 35, SPR_IMG_BUY_LAND, STR_0329_PURCHASE_LAND_FOR_FUTURE},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 114, 135, 14, 35, SPR_IMG_PLANTTREES, STR_0185_PLANT_TREES_PLACE_SIGNS},
+{ WWT_IMGBTN, RESIZE_NONE, 7, 136, 157, 14, 35, SPR_IMG_PLACE_SIGN, STR_0289_PLACE_SIGN},
+
+{ WIDGETS_END},
+};
+
+static const WindowDesc _terraform_desc = {
+ WDP_ALIGN_TBR, 22+36, 158, 36,
+ WC_SCEN_LAND_GEN, 0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON,
+ _terraform_widgets,
+ TerraformToolbWndProc
+};
+
+void ShowTerraformToolbar(void)
+{
+ if (!IsValidPlayer(_current_player)) return;
+ AllocateWindowDescFront(&_terraform_desc, 0);
+}
diff --git a/src/texteff.c b/src/texteff.c
new file mode 100644
index 000000000..c65cb8675
--- /dev/null
+++ b/src/texteff.c
@@ -0,0 +1,384 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "functions.h"
+#include "macros.h"
+#include "strings.h"
+#include "gfx.h"
+#include "viewport.h"
+#include "saveload.h"
+#include "hal.h"
+#include "console.h"
+#include "string.h"
+#include "variables.h"
+#include "table/sprites.h"
+#include <stdarg.h> /* va_list */
+#include "date.h"
+
+enum {
+ MAX_TEXTMESSAGE_LENGTH = 150,
+ MAX_TEXT_MESSAGES = 30,
+ MAX_CHAT_MESSAGES = 10,
+ MAX_ANIMATED_TILES = 256,
+};
+
+typedef struct TextEffect {
+ StringID string_id;
+ int32 x;
+ int32 y;
+ int32 right;
+ int32 bottom;
+ uint16 duration;
+ uint32 params_1;
+ uint32 params_2;
+} TextEffect;
+
+
+typedef struct TextMessage {
+ char message[MAX_TEXTMESSAGE_LENGTH];
+ uint16 color;
+ Date end_date;
+} TextMessage;
+
+static TextEffect _text_effect_list[MAX_TEXT_MESSAGES];
+static TextMessage _textmsg_list[MAX_CHAT_MESSAGES];
+TileIndex _animated_tile_list[MAX_ANIMATED_TILES];
+
+static bool _textmessage_dirty = false;
+static bool _textmessage_visible = false;
+
+/* The chatbox grows from the bottom so the coordinates are pixels from
+ * the left and pixels from the bottom. The height is the maximum height */
+static const Oblong _textmsg_box = {10, 30, 500, 150};
+static Pixel _textmessage_backup[150 * 500]; // (height * width)
+
+extern void memcpy_pitch(void *dst, void *src, int w, int h, int srcpitch, int dstpitch);
+
+static inline uint GetTextMessageCount(void)
+{
+ uint i;
+
+ for (i = 0; i < MAX_CHAT_MESSAGES; i++) {
+ if (_textmsg_list[i].message[0] == '\0') break;
+ }
+
+ return i;
+}
+
+/* Add a text message to the 'chat window' to be shown
+ * @param color The colour this message is to be shown in
+ * @param duration The duration of the chat message in game-days
+ * @param message message itself in printf() style */
+void CDECL AddTextMessage(uint16 color, uint8 duration, const char *message, ...)
+{
+ char buf[MAX_TEXTMESSAGE_LENGTH];
+ const char *bufp;
+ va_list va;
+ uint msg_count;
+ uint16 lines;
+
+ va_start(va, message);
+ vsnprintf(buf, lengthof(buf), message, va);
+ va_end(va);
+
+ /* Force linebreaks for strings that are too long */
+ lines = GB(FormatStringLinebreaks(buf, _textmsg_box.width - 8), 0, 16) + 1;
+ if (lines >= MAX_CHAT_MESSAGES) return;
+
+ msg_count = GetTextMessageCount();
+ /* We want to add more chat messages than there is free space for, remove 'old' */
+ if (lines > MAX_CHAT_MESSAGES - msg_count) {
+ int i = lines - (MAX_CHAT_MESSAGES - msg_count);
+ memmove(&_textmsg_list[0], &_textmsg_list[i], sizeof(_textmsg_list[0]) * (msg_count - i));
+ msg_count = MAX_CHAT_MESSAGES - lines;
+ }
+
+ for (bufp = buf; lines != 0; lines--) {
+ TextMessage *tmsg = &_textmsg_list[msg_count++];
+ ttd_strlcpy(tmsg->message, bufp, sizeof(tmsg->message));
+
+ /* The default colour for a message is player colour. Replace this with
+ * white for any additional lines */
+ tmsg->color = (bufp == buf && color & IS_PALETTE_COLOR) ? color : (0x1D - 15) | IS_PALETTE_COLOR;
+ tmsg->end_date = _date + duration;
+
+ bufp += strlen(bufp) + 1; // jump to 'next line' in the formatted string
+ }
+
+ _textmessage_dirty = true;
+}
+
+void InitTextMessage(void)
+{
+ uint i;
+
+ for (i = 0; i < MAX_CHAT_MESSAGES; i++) {
+ _textmsg_list[i].message[0] = '\0';
+ }
+}
+
+/* Hide the textbox */
+void UndrawTextMessage(void)
+{
+ if (_textmessage_visible) {
+ /* Sometimes we also need to hide the cursor
+ * This is because both textmessage and the cursor take a shot of the
+ * screen before drawing.
+ * Now the textmessage takes his shot and paints his data before the cursor
+ * does, so in the shot of the cursor is the screen-data of the textmessage
+ * included when the cursor hangs somewhere over the textmessage. To
+ * avoid wrong repaints, we undraw the cursor in that case, and everything
+ * looks nicely ;)
+ * (and now hope this story above makes sense to you ;))
+ */
+
+ if (_cursor.visible) {
+ if (_cursor.draw_pos.x + _cursor.draw_size.x >= _textmsg_box.x &&
+ _cursor.draw_pos.x <= _textmsg_box.x + _textmsg_box.width &&
+ _cursor.draw_pos.y + _cursor.draw_size.y >= _screen.height - _textmsg_box.y - _textmsg_box.height &&
+ _cursor.draw_pos.y <= _screen.height - _textmsg_box.y) {
+ UndrawMouseCursor();
+ }
+ }
+
+ _textmessage_visible = false;
+ /* Put our 'shot' back to the screen */
+ memcpy_pitch(
+ _screen.dst_ptr + _textmsg_box.x + (_screen.height - _textmsg_box.y - _textmsg_box.height) * _screen.pitch,
+ _textmessage_backup,
+ _textmsg_box.width, _textmsg_box.height, _textmsg_box.width, _screen.pitch);
+
+ /* And make sure it is updated next time */
+ _video_driver->make_dirty(_textmsg_box.x, _screen.height - _textmsg_box.y - _textmsg_box.height, _textmsg_box.width, _textmsg_box.height);
+
+ _textmessage_dirty = true;
+ }
+}
+
+/* Check if a message is expired every day */
+void TextMessageDailyLoop(void)
+{
+ uint i;
+
+ for (i = 0; i < MAX_CHAT_MESSAGES; i++) {
+ TextMessage *tmsg = &_textmsg_list[i];
+ if (tmsg->message[0] == '\0') continue;
+
+ /* Message has expired, remove from the list */
+ if (tmsg->end_date < _date) {
+ /* Move the remaining messages over the current message */
+ if (i != MAX_CHAT_MESSAGES - 1) memmove(tmsg, tmsg + 1, sizeof(*tmsg) * (MAX_CHAT_MESSAGES - i - 1));
+
+ /* Mark the last item as empty */
+ _textmsg_list[MAX_CHAT_MESSAGES - 1].message[0] = '\0';
+ _textmessage_dirty = true;
+
+ /* Go one item back, because we moved the array 1 to the left */
+ i--;
+ }
+ }
+}
+
+/* Draw the textmessage-box */
+void DrawTextMessage(void)
+{
+ uint y, count;
+
+ if (!_textmessage_dirty) return;
+
+ /* First undraw if needed */
+ UndrawTextMessage();
+
+ if (_iconsole_mode == ICONSOLE_FULL) return;
+
+ /* Check if we have anything to draw at all */
+ count = GetTextMessageCount();
+ if (count == 0) return;
+
+ /* Make a copy of the screen as it is before painting (for undraw) */
+ memcpy_pitch(
+ _textmessage_backup,
+ _screen.dst_ptr + _textmsg_box.x + (_screen.height - _textmsg_box.y - _textmsg_box.height) * _screen.pitch,
+ _textmsg_box.width, _textmsg_box.height, _screen.pitch, _textmsg_box.width);
+
+ _cur_dpi = &_screen; // switch to _screen painting
+
+ /* Paint a half-transparent box behind the text messages */
+ GfxFillRect(
+ _textmsg_box.x,
+ _screen.height - _textmsg_box.y - count * 13 - 2,
+ _textmsg_box.x + _textmsg_box.width - 1,
+ _screen.height - _textmsg_box.y - 2,
+ 0x322 | USE_COLORTABLE // black, but with some alpha for background
+ );
+
+ /* Paint the messages starting with the lowest at the bottom */
+ for (y = 13; count-- != 0; y += 13) {
+ DoDrawString(_textmsg_list[count].message, _textmsg_box.x + 3, _screen.height - _textmsg_box.y - y + 1, _textmsg_list[count].color);
+ }
+
+ /* Make sure the data is updated next flush */
+ _video_driver->make_dirty(_textmsg_box.x, _screen.height - _textmsg_box.y - _textmsg_box.height, _textmsg_box.width, _textmsg_box.height);
+
+ _textmessage_visible = true;
+ _textmessage_dirty = false;
+}
+
+static void MarkTextEffectAreaDirty(TextEffect *te)
+{
+ MarkAllViewportsDirty(
+ te->x,
+ te->y - 1,
+ (te->right - te->x)*2 + te->x + 1,
+ (te->bottom - (te->y - 1)) * 2 + (te->y - 1) + 1
+ );
+}
+
+void AddTextEffect(StringID msg, int x, int y, uint16 duration)
+{
+ TextEffect *te;
+ int w;
+ char buffer[100];
+
+ if (_game_mode == GM_MENU) return;
+
+ for (te = _text_effect_list; te->string_id != INVALID_STRING_ID; ) {
+ if (++te == endof(_text_effect_list)) return;
+ }
+
+ te->string_id = msg;
+ te->duration = duration;
+ te->y = y - 5;
+ te->bottom = y + 5;
+ te->params_1 = GetDParam(0);
+ te->params_2 = GetDParam(4);
+
+ GetString(buffer, msg, lastof(buffer));
+ w = GetStringBoundingBox(buffer).width;
+
+ te->x = x - (w >> 1);
+ te->right = x + (w >> 1) - 1;
+ MarkTextEffectAreaDirty(te);
+}
+
+static void MoveTextEffect(TextEffect *te)
+{
+ if (te->duration < 8) {
+ te->string_id = INVALID_STRING_ID;
+ } else {
+ te->duration -= 8;
+ te->y--;
+ te->bottom--;
+ }
+ MarkTextEffectAreaDirty(te);
+}
+
+void MoveAllTextEffects(void)
+{
+ TextEffect *te;
+
+ for (te = _text_effect_list; te != endof(_text_effect_list); te++) {
+ if (te->string_id != INVALID_STRING_ID) MoveTextEffect(te);
+ }
+}
+
+void InitTextEffects(void)
+{
+ TextEffect *te;
+
+ for (te = _text_effect_list; te != endof(_text_effect_list); te++) {
+ te->string_id = INVALID_STRING_ID;
+ }
+}
+
+void DrawTextEffects(DrawPixelInfo *dpi)
+{
+ const TextEffect* te;
+
+ switch (dpi->zoom) {
+ case 0:
+ for (te = _text_effect_list; te != endof(_text_effect_list); te++) {
+ if (te->string_id != INVALID_STRING_ID &&
+ dpi->left <= te->right &&
+ dpi->top <= te->bottom &&
+ dpi->left + dpi->width > te->x &&
+ dpi->top + dpi->height > te->y) {
+ AddStringToDraw(te->x, te->y, te->string_id, te->params_1, te->params_2);
+ }
+ }
+ break;
+
+ case 1:
+ for (te = _text_effect_list; te != endof(_text_effect_list); te++) {
+ if (te->string_id != INVALID_STRING_ID &&
+ dpi->left <= te->right * 2 - te->x &&
+ dpi->top <= te->bottom * 2 - te->y &&
+ dpi->left + dpi->width > te->x &&
+ dpi->top + dpi->height > te->y) {
+ AddStringToDraw(te->x, te->y, (StringID)(te->string_id-1), te->params_1, te->params_2);
+ }
+ }
+ break;
+ }
+}
+
+void DeleteAnimatedTile(TileIndex tile)
+{
+ TileIndex *ti;
+
+ for (ti = _animated_tile_list; ti != endof(_animated_tile_list); ti++) {
+ if (tile == *ti) {
+ /* remove the hole */
+ memmove(ti, ti + 1, (lastof(_animated_tile_list) - ti) * sizeof(*ti));
+ /* and clear last item */
+ *lastof(_animated_tile_list) = 0;
+ MarkTileDirtyByTile(tile);
+ return;
+ }
+ }
+}
+
+bool AddAnimatedTile(TileIndex tile)
+{
+ TileIndex *ti;
+
+ for (ti = _animated_tile_list; ti != endof(_animated_tile_list); ti++) {
+ if (tile == *ti || *ti == 0) {
+ *ti = tile;
+ MarkTileDirtyByTile(tile);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void AnimateAnimatedTiles(void)
+{
+ const TileIndex* ti;
+
+ for (ti = _animated_tile_list; ti != endof(_animated_tile_list) && *ti != 0; ti++) {
+ AnimateTile(*ti);
+ }
+}
+
+void InitializeAnimatedTiles(void)
+{
+ memset(_animated_tile_list, 0, sizeof(_animated_tile_list));
+}
+
+static void SaveLoad_ANIT(void)
+{
+ /* In pre version 6, we has 16bit per tile, now we have 32bit per tile, convert it ;) */
+ if (CheckSavegameVersion(6)) {
+ SlArray(_animated_tile_list, lengthof(_animated_tile_list), SLE_FILE_U16 | SLE_VAR_U32);
+ } else {
+ SlArray(_animated_tile_list, lengthof(_animated_tile_list), SLE_UINT32);
+ }
+}
+
+
+const ChunkHandler _animated_tile_chunk_handlers[] = {
+ { 'ANIT', SaveLoad_ANIT, SaveLoad_ANIT, CH_RIFF | CH_LAST},
+};
diff --git a/src/tgp.c b/src/tgp.c
new file mode 100644
index 000000000..d7f9722f9
--- /dev/null
+++ b/src/tgp.c
@@ -0,0 +1,829 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include <math.h>
+#include "openttd.h"
+#include "clear_map.h"
+#include "functions.h"
+#include "map.h"
+#include "table/strings.h"
+#include "clear_map.h"
+#include "tile.h"
+#include "variables.h"
+#include "void_map.h"
+#include "tgp.h"
+#include "console.h"
+#include "genworld.h"
+
+/*
+ * OTTD Perlin Noise Landscape Generator, aka TerraGenesis Perlin
+ *
+ * Quickie guide to Perlin Noise
+ * Perlin noise is a predictable pseudo random number sequence. By generating
+ * it in 2 dimensions, it becomes a useful random map, that for a given seed
+ * and starting X & Y is entirely predictable. On the face of it, that may not
+ * be useful. However, it means that if you want to replay a map in a different
+ * terrain, or just vary the sea level, you just re-run the generator with the
+ * same seed. The seed is an int32, and is randomised on each run of New Game.
+ * The Scenario Generator does not randomise the value, so that you can
+ * experiment with one terrain until you are happy, or click "Random" for a new
+ * random seed.
+ *
+ * Perlin Noise is a series of "octaves" of random noise added together. By
+ * reducing the amplitude of the noise with each octave, the first octave of
+ * noise defines the main terrain sweep, the next the ripples on that, and the
+ * next the ripples on that. I use 6 octaves, with the amplitude controlled by
+ * a power ratio, usually known as a persistence or p value. This I vary by the
+ * smoothness selection, as can be seen in the table below. The closer to 1,
+ * the more of that octave is added. Each octave is however raised to the power
+ * of its position in the list, so the last entry in the "smooth" row, 0.35, is
+ * raised to the power of 6, so can only add 0.001838... of the amplitude to
+ * the running total.
+ *
+ * In other words; the first p value sets the general shape of the terrain, the
+ * second sets the major variations to that, ... until finally the smallest
+ * bumps are added.
+ *
+ * Usefully, this routine is totally scaleable; so when 32bpp comes along, the
+ * terrain can be as bumpy as you like! It is also infinitely expandable; a
+ * single random seed terrain continues in X & Y as far as you care to
+ * calculate. In theory, we could use just one seed value, but randomly select
+ * where in the Perlin XY space we use for the terrain. Personally I prefer
+ * using a simple (0, 0) to (X, Y), with a varying seed.
+ *
+ *
+ * Other things i have had to do: mountainous wasnt mountainous enough, and
+ * since we only have 0..15 heights available, I add a second generated map
+ * (with a modified seed), onto the original. This generally raises the
+ * terrain, which then needs scaling back down. Overall effect is a general
+ * uplift.
+ *
+ * However, the values on the top of mountains are then almost guaranteed to go
+ * too high, so large flat plateaus appeared at height 15. To counter this, I
+ * scale all heights above 12 to proportion up to 15. It still makes the
+ * mountains have flatish tops, rather than craggy peaks, but at least they
+ * arent smooth as glass.
+ *
+ *
+ * For a full discussion of Perlin Noise, please visit:
+ * http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
+ *
+ *
+ * Evolution II
+ *
+ * The algorithm as described in the above link suggests to compute each tile height
+ * as composition of several noise waves. Some of them are computed directly by
+ * noise(x, y) function, some are calculated using linear approximation. Our
+ * first implementation of perlin_noise_2D() used 4 noise(x, y) calls plus
+ * 3 linear interpolations. It was called 6 times for each tile. This was a bit
+ * CPU expensive.
+ *
+ * The following implementation uses optimized algorithm that should produce
+ * the same quality result with much less computations, but more memory accesses.
+ * The overal speedup should be 300% to 800% depending on CPU and memory speed.
+ *
+ * I will try to explain it on the example below:
+ *
+ * Have a map of 4 x 4 tiles, our simplifiead noise generator produces only two
+ * values -1 and +1, use 3 octaves with wave lenght 1, 2 and 4, with amplitudes
+ * 3, 2, 1. Original algorithm produces:
+ *
+ * h00 = lerp(lerp(-3, 3, 0/4), lerp(3, -3, 0/4), 0/4) + lerp(lerp(-2, 2, 0/2), lerp( 2, -2, 0/2), 0/2) + -1 = lerp(-3.0, 3.0, 0/4) + lerp(-2, 2, 0/2) + -1 = -3.0 + -2 + -1 = -6.0
+ * h01 = lerp(lerp(-3, 3, 1/4), lerp(3, -3, 1/4), 0/4) + lerp(lerp(-2, 2, 1/2), lerp( 2, -2, 1/2), 0/2) + 1 = lerp(-1.5, 1.5, 0/4) + lerp( 0, 0, 0/2) + 1 = -1.5 + 0 + 1 = -0.5
+ * h02 = lerp(lerp(-3, 3, 2/4), lerp(3, -3, 2/4), 0/4) + lerp(lerp( 2, -2, 0/2), lerp(-2, 2, 0/2), 0/2) + -1 = lerp( 0, 0, 0/4) + lerp( 2, -2, 0/2) + -1 = 0 + 2 + -1 = 1.0
+ * h03 = lerp(lerp(-3, 3, 3/4), lerp(3, -3, 3/4), 0/4) + lerp(lerp( 2, -2, 1/2), lerp(-2, 2, 1/2), 0/2) + 1 = lerp( 1.5, -1.5, 0/4) + lerp( 0, 0, 0/2) + 1 = 1.5 + 0 + 1 = 2.5
+ *
+ * h10 = lerp(lerp(-3, 3, 0/4), lerp(3, -3, 0/4), 1/4) + lerp(lerp(-2, 2, 0/2), lerp( 2, -2, 0/2), 1/2) + 1 = lerp(-3.0, 3.0, 1/4) + lerp(-2, 2, 1/2) + 1 = -1.5 + 0 + 1 = -0.5
+ * h11 = lerp(lerp(-3, 3, 1/4), lerp(3, -3, 1/4), 1/4) + lerp(lerp(-2, 2, 1/2), lerp( 2, -2, 1/2), 1/2) + -1 = lerp(-1.5, 1.5, 1/4) + lerp( 0, 0, 1/2) + -1 = -0.75 + 0 + -1 = -1.75
+ * h12 = lerp(lerp(-3, 3, 2/4), lerp(3, -3, 2/4), 1/4) + lerp(lerp( 2, -2, 0/2), lerp(-2, 2, 0/2), 1/2) + 1 = lerp( 0, 0, 1/4) + lerp( 2, -2, 1/2) + 1 = 0 + 0 + 1 = 1.0
+ * h13 = lerp(lerp(-3, 3, 3/4), lerp(3, -3, 3/4), 1/4) + lerp(lerp( 2, -2, 1/2), lerp(-2, 2, 1/2), 1/2) + -1 = lerp( 1.5, -1.5, 1/4) + lerp( 0, 0, 1/2) + -1 = 0.75 + 0 + -1 = -0.25
+ *
+ *
+ * Optimization 1:
+ *
+ * 1) we need to allocate a bit more tiles: (size_x + 1) * (size_y + 1) = (5 * 5):
+ *
+ * 2) setup corner values using amplitude 3
+ * { -3.0 X X X 3.0 }
+ * { X X X X X }
+ * { X X X X X }
+ * { X X X X X }
+ * { 3.0 X X X -3.0 }
+ *
+ * 3a) interpolate values in the middle
+ * { -3.0 X 0.0 X 3.0 }
+ * { X X X X X }
+ * { 0.0 X 0.0 X 0.0 }
+ * { X X X X X }
+ * { 3.0 X 0.0 X -3.0 }
+ *
+ * 3b) add patches with amplitude 2 to them
+ * { -5.0 X 2.0 X 1.0 }
+ * { X X X X X }
+ * { 2.0 X -2.0 X 2.0 }
+ * { X X X X X }
+ * { 1.0 X 2.0 X -5.0 }
+ *
+ * 4a) interpolate values in the middle
+ * { -5.0 -1.5 2.0 1.5 1.0 }
+ * { -1.5 -0.75 0.0 0.75 1.5 }
+ * { 2.0 0.0 -2.0 0.0 2.0 }
+ * { 1.5 0.75 0.0 -0.75 -1.5 }
+ * { 1.0 1.5 2.0 -1.5 -5.0 }
+ *
+ * 4b) add patches with amplitude 1 to them
+ * { -6.0 -0.5 1.0 2.5 0.0 }
+ * { -0.5 -1.75 1.0 -0.25 2.5 }
+ * { 1.0 1.0 -3.0 1.0 1.0 }
+ * { 2.5 -0.25 1.0 -1.75 -0.5 }
+ * { 0.0 2.5 1.0 -0.5 -6.0 }
+ *
+ *
+ *
+ * Optimization 2:
+ *
+ * As you can see above, each noise function was called just once. Therefore
+ * we don't need to use noise function that calculates the noise from x, y and
+ * some prime. The same quality result we can obtain using standard Random()
+ * function instead.
+ *
+ */
+
+#ifndef M_PI_2
+#define M_PI_2 1.57079632679489661923
+#define M_PI 3.14159265358979323846
+#endif /* M_PI_2 */
+
+/** Fixed point type for heights */
+typedef int16 height_t;
+static const int height_decimal_bits = 4;
+static const height_t _invalid_height = -32768;
+
+/** Fixed point array for amplitudes (and percent values) */
+typedef int amplitude_t;
+static const int amplitude_decimal_bits = 10;
+
+/** Height map - allocated array of heights (MapSizeX() + 1) x (MapSizeY() + 1) */
+typedef struct HeightMap
+{
+ height_t *h; //! array of heights
+ uint dim_x; //! height map size_x MapSizeX() + 1
+ uint total_size; //! height map total size
+ uint size_x; //! MapSizeX()
+ uint size_y; //! MapSizeY()
+} HeightMap;
+
+/** Global height map instance */
+static HeightMap _height_map = {NULL, 0, 0, 0, 0};
+
+/** Height map accessors */
+#define HeightMapXY(x, y) _height_map.h[(x) + (y) * _height_map.dim_x]
+
+/** Conversion: int to height_t */
+#define I2H(i) ((i) << height_decimal_bits)
+/** Conversion: height_t to int */
+#define H2I(i) ((i) >> height_decimal_bits)
+
+/** Conversion: int to amplitude_t */
+#define I2A(i) ((i) << amplitude_decimal_bits)
+/** Conversion: amplitude_t to int */
+#define A2I(i) ((i) >> amplitude_decimal_bits)
+
+/** Conversion: amplitude_t to height_t */
+#define A2H(a) ((height_decimal_bits < amplitude_decimal_bits) \
+ ? ((a) >> (amplitude_decimal_bits - height_decimal_bits)) \
+ : ((a) << (height_decimal_bits - amplitude_decimal_bits)))
+
+/** Walk through all items of _height_map.h */
+#define FOR_ALL_TILES_IN_HEIGHT(h) for (h = _height_map.h; h < &_height_map.h[_height_map.total_size]; h++)
+
+/** Noise amplitudes (multiplied by 1024)
+ * - indexed by "smoothness setting" and log2(frequency) */
+static const amplitude_t _amplitudes_by_smoothness_and_frequency[4][12] = {
+ // Very smooth
+ {1000, 350, 123, 43, 15, 1, 1, 0, 0, 0, 0, 0},
+ // Smooth
+ {1000, 1000, 403, 200, 64, 8, 1, 0, 0, 0, 0, 0},
+ // Rough
+ {1000, 1200, 800, 500, 200, 16, 4, 0, 0, 0, 0, 0},
+ // Very Rough
+ {1500, 1000, 1200, 1000, 500, 32, 20, 0, 0, 0, 0, 0},
+};
+
+/** Desired water percentage (100% == 1024) - indexed by _opt.diff.quantity_sea_lakes */
+static const amplitude_t _water_percent[4] = {20, 80, 250, 400};
+
+/** Desired maximum height - indexed by _opt.diff.terrain_type */
+static const int8 _max_height[4] = {
+ 6, // Very flat
+ 9, // Flat
+ 12, // Hilly
+ 15 // Mountainous
+};
+
+/** Check if a X/Y set are within the map. */
+static inline bool IsValidXY(uint x, uint y)
+{
+ return ((int)x) >= 0 && x < _height_map.size_x && ((int)y) >= 0 && y < _height_map.size_y;
+}
+
+
+/** Allocate array of (MapSizeX()+1)*(MapSizeY()+1) heights and init the _height_map structure members */
+static inline bool AllocHeightMap(void)
+{
+ height_t *h;
+
+ _height_map.size_x = MapSizeX();
+ _height_map.size_y = MapSizeY();
+
+ /* Allocate memory block for height map row pointers */
+ _height_map.total_size = (_height_map.size_x + 1) * (_height_map.size_y + 1);
+ _height_map.dim_x = _height_map.size_x + 1;
+ _height_map.h = calloc(_height_map.total_size, sizeof(*_height_map.h));
+ if (_height_map.h == NULL) return false;
+
+ /* Iterate through height map initialize values */
+ FOR_ALL_TILES_IN_HEIGHT(h) *h = _invalid_height;
+
+ return true;
+}
+
+/** Free height map */
+static inline void FreeHeightMap(void)
+{
+ if (_height_map.h == NULL) return;
+ free(_height_map.h);
+ _height_map.h = NULL;
+}
+
+/** RandomHeight() generator */
+static inline height_t RandomHeight(amplitude_t rMax)
+{
+ amplitude_t ra = (Random() << 16) | (Random() & 0x0000FFFF);
+ height_t rh;
+ /* Scale the amplitude for better resolution */
+ rMax *= 16;
+ /* Spread height into range -rMax..+rMax */
+ rh = A2H(ra % (2 * rMax + 1) - rMax);
+ return rh;
+}
+
+/** One interpolation and noise round */
+static bool ApplyNoise(uint log_frequency, amplitude_t amplitude)
+{
+ uint size_min = min(_height_map.size_x, _height_map.size_y);
+ uint step = size_min >> log_frequency;
+ uint x, y;
+
+ assert(_height_map.h != NULL);
+
+ /* Are we finished? */
+ if (step == 0) return false;
+
+ if (log_frequency == 0) {
+ /* This is first round, we need to establish base heights with step = size_min */
+ for (y = 0; y <= _height_map.size_y; y += step) {
+ for (x = 0; x <= _height_map.size_x; x += step) {
+ height_t height = (amplitude > 0) ? RandomHeight(amplitude) : 0;
+ HeightMapXY(x, y) = height;
+ }
+ }
+ return true;
+ }
+
+ /* It is regular iteration round.
+ * Interpolate height values at odd x, even y tiles */
+ for (y = 0; y <= _height_map.size_y; y += 2 * step) {
+ for (x = 0; x < _height_map.size_x; x += 2 * step) {
+ height_t h00 = HeightMapXY(x + 0 * step, y);
+ height_t h02 = HeightMapXY(x + 2 * step, y);
+ height_t h01 = (h00 + h02) / 2;
+ HeightMapXY(x + 1 * step, y) = h01;
+ }
+ }
+
+ /* Interpolate height values at odd y tiles */
+ for (y = 0; y < _height_map.size_y; y += 2 * step) {
+ for (x = 0; x <= _height_map.size_x; x += step) {
+ height_t h00 = HeightMapXY(x, y + 0 * step);
+ height_t h20 = HeightMapXY(x, y + 2 * step);
+ height_t h10 = (h00 + h20) / 2;
+ HeightMapXY(x, y + 1 * step) = h10;
+ }
+ }
+
+ for (y = 0; y <= _height_map.size_y; y += step) {
+ for (x = 0; x <= _height_map.size_x; x += step) {
+ HeightMapXY(x, y) += RandomHeight(amplitude);
+ }
+ }
+ return (step > 1);
+}
+
+/** Base Perlin noise generator - fills height map with raw Perlin noise */
+static void HeightMapGenerate(void)
+{
+ uint size_min = min(_height_map.size_x, _height_map.size_y);
+ uint iteration_round = 0;
+ amplitude_t amplitude;
+ bool continue_iteration;
+ uint log_size_min, log_frequency_min;
+ int log_frequency;
+
+ /* Find first power of two that fits */
+ for (log_size_min = 6; (1U << log_size_min) < size_min; log_size_min++) { }
+ log_frequency_min = log_size_min - 6;
+
+ do {
+ log_frequency = iteration_round - log_frequency_min;
+ if (log_frequency >= 0) {
+ amplitude = _amplitudes_by_smoothness_and_frequency[_patches.tgen_smoothness][log_frequency];
+ } else {
+ amplitude = 0;
+ }
+ continue_iteration = ApplyNoise(iteration_round, amplitude);
+ iteration_round++;
+ } while(continue_iteration);
+}
+
+/** Returns min, max and average height from height map */
+static void HeightMapGetMinMaxAvg(height_t *min_ptr, height_t *max_ptr, height_t *avg_ptr)
+{
+ height_t h_min, h_max, h_avg, *h;
+ int64 h_accu = 0;
+ h_min = h_max = HeightMapXY(0, 0);
+
+ /* Get h_min, h_max and accumulate heights into h_accu */
+ FOR_ALL_TILES_IN_HEIGHT(h) {
+ if (*h < h_min) h_min = *h;
+ if (*h > h_max) h_max = *h;
+ h_accu += *h;
+ }
+
+ /* Get average height */
+ h_avg = (height_t)(h_accu / (_height_map.size_x * _height_map.size_y));
+
+ /* Return required results */
+ if (min_ptr != NULL) *min_ptr = h_min;
+ if (max_ptr != NULL) *max_ptr = h_max;
+ if (avg_ptr != NULL) *avg_ptr = h_avg;
+}
+
+/** Dill histogram and return pointer to its base point - to the count of zero heights */
+static int *HeightMapMakeHistogram(height_t h_min, height_t h_max, int *hist_buf)
+{
+ int *hist = hist_buf - h_min;
+ height_t *h;
+
+ /* Fill histogram */
+ FOR_ALL_TILES_IN_HEIGHT(h) {
+ assert(*h >= h_min);
+ assert(*h <= h_max);
+ hist[*h]++;
+ }
+ return hist;
+}
+
+/** Applies sine wave redistribution onto height map */
+static void HeightMapSineTransform(height_t h_min, height_t h_max)
+{
+ height_t *h;
+
+ FOR_ALL_TILES_IN_HEIGHT(h) {
+ double fheight;
+
+ if (*h < h_min) continue;
+
+ /* Transform height into 0..1 space */
+ fheight = (double)(*h - h_min) / (double)(h_max - h_min);
+ /* Apply sine transform depending on landscape type */
+ switch(_opt.landscape) {
+ case LT_CANDY:
+ case LT_NORMAL:
+ /* Move and scale 0..1 into -1..+1 */
+ fheight = 2 * fheight - 1;
+ /* Sine transform */
+ fheight = sin(fheight * M_PI_2);
+ /* Transform it back from -1..1 into 0..1 space */
+ fheight = 0.5 * (fheight + 1);
+ break;
+
+ case LT_HILLY:
+ {
+ /* Arctic terrain needs special height distribution.
+ * Redistribute heights to have more tiles at highest (75%..100%) range */
+ double sine_upper_limit = 0.75;
+ double linear_compression = 2;
+ if (fheight >= sine_upper_limit) {
+ /* Over the limit we do linear compression up */
+ fheight = 1.0 - (1.0 - fheight) / linear_compression;
+ } else {
+ double m = 1.0 - (1.0 - sine_upper_limit) / linear_compression;
+ /* Get 0..sine_upper_limit into -1..1 */
+ fheight = 2.0 * fheight / sine_upper_limit - 1.0;
+ /* Sine wave transform */
+ fheight = sin(fheight * M_PI_2);
+ /* Get -1..1 back to 0..(1 - (1 - sine_upper_limit) / linear_compression) == 0.0..m */
+ fheight = 0.5 * (fheight + 1.0) * m;
+ }
+ }
+ break;
+
+ case LT_DESERT:
+ {
+ /* Desert terrain needs special height distribution.
+ * Half of tiles should be at lowest (0..25%) heights */
+ double sine_lower_limit = 0.5;
+ double linear_compression = 2;
+ if (fheight <= sine_lower_limit) {
+ /* Under the limit we do linear compression down */
+ fheight = fheight / linear_compression;
+ } else {
+ double m = sine_lower_limit / linear_compression;
+ /* Get sine_lower_limit..1 into -1..1 */
+ fheight = 2.0 * ((fheight - sine_lower_limit) / (1.0 - sine_lower_limit)) - 1.0;
+ /* Sine wave transform */
+ fheight = sin(fheight * M_PI_2);
+ /* Get -1..1 back to (sine_lower_limit / linear_compression)..1.0 */
+ fheight = 0.5 * ((1.0 - m) * fheight + (1.0 + m));
+ }
+ }
+ break;
+
+ default:
+ NOT_REACHED();
+ break;
+ }
+ /* Transform it back into h_min..h_max space */
+ *h = fheight * (h_max - h_min) + h_min;
+ if (*h < 0) *h = I2H(0);
+ if (*h >= h_max) *h = h_max - 1;
+ }
+}
+
+/** Adjusts heights in height map to contain required amount of water tiles */
+static void HeightMapAdjustWaterLevel(amplitude_t water_percent, height_t h_max_new)
+{
+ height_t h_min, h_max, h_avg, h_water_level;
+ int water_tiles, desired_water_tiles;
+ height_t *h;
+ int *hist_buf, *hist;
+
+ HeightMapGetMinMaxAvg(&h_min, &h_max, &h_avg);
+
+ /* Allocate histogram buffer and clear its cells */
+ hist_buf = calloc(h_max - h_min + 1, sizeof(*hist_buf));
+ /* Fill histogram */
+ hist = HeightMapMakeHistogram(h_min, h_max, hist_buf);
+
+ /* How many water tiles do we want? */
+ desired_water_tiles = (int)(((int64)water_percent) * (int64)(_height_map.size_x * _height_map.size_y)) >> amplitude_decimal_bits;
+
+ /* Raise water_level and accumulate values from histogram until we reach required number of water tiles */
+ for (h_water_level = h_min, water_tiles = 0; h_water_level < h_max; h_water_level++) {
+ water_tiles += hist[h_water_level];
+ if (water_tiles >= desired_water_tiles) break;
+ }
+
+ /* We now have the proper water level value.
+ * Transform the height map into new (normalized) height map:
+ * values from range: h_min..h_water_level will become negative so it will be clamped to 0
+ * values from range: h_water_level..h_max are transformed into 0..h_max_new
+ * , where h_max_new is 4, 8, 12 or 16 depending on terrain type (very flat, flat, hilly, mountains)
+ */
+ FOR_ALL_TILES_IN_HEIGHT(h) {
+ /* Transform height from range h_water_level..h_max into 0..h_max_new range */
+ *h = (height_t)(((int)h_max_new) * (*h - h_water_level) / (h_max - h_water_level)) + I2H(1);
+ /* Make sure all values are in the proper range (0..h_max_new) */
+ if (*h < 0) *h = I2H(0);
+ if (*h >= h_max_new) *h = h_max_new - 1;
+ }
+
+ free(hist_buf);
+}
+
+static double perlin_coast_noise_2D(const double x, const double y, const double p, const int prime);
+
+/**
+ * This routine sculpts in from the edge a random amount, again a Perlin
+ * sequence, to avoid the rigid flat-edge slopes that were present before. The
+ * Perlin noise map doesnt know where we are going to slice across, and so we
+ * often cut straight through high terrain. the smoothing routine makes it
+ * legal, gradually increasing up from the edge to the original terrain height.
+ * By cutting parts of this away, it gives a far more irregular edge to the
+ * map-edge. Sometimes it works beautifully with the existing sea & lakes, and
+ * creates a very realistic coastline. Other times the variation is less, and
+ * the map-edge shows its cliff-like roots.
+ *
+ * This routine may be extended to randomly sculpt the height of the terrain
+ * near the edge. This will have the coast edge at low level (1-3), rising in
+ * smoothed steps inland to about 15 tiles in. This should make it look as
+ * though the map has been built for the map size, rather than a slice through
+ * a larger map.
+ *
+ * Please note that all the small numbers; 53, 101, 167, etc. are small primes
+ * to help give the perlin noise a bit more of a random feel.
+ */
+static void HeightMapCoastLines(void)
+{
+ int smallest_size = min(_patches.map_x, _patches.map_y);
+ const int margin = 4;
+ uint y, x;
+ uint max_x;
+ uint max_y;
+
+ /* Lower to sea level */
+ for (y = 0; y <= _height_map.size_y; y++) {
+ /* Top right */
+ max_x = myabs((perlin_coast_noise_2D(_height_map.size_y - y, y, 0.9, 53) + 0.25) * 5 + (perlin_coast_noise_2D(y, y, 0.35, 179) + 1) * 12);
+ max_x = max((smallest_size * smallest_size / 16) + max_x, (smallest_size * smallest_size / 16) + margin - max_x);
+ if (smallest_size < 8 && max_x > 5) max_x /= 1.5;
+ for (x = 0; x < max_x; x++) {
+ HeightMapXY(x, y) = 0;
+ }
+
+ /* Bottom left */
+ max_x = myabs((perlin_coast_noise_2D(_height_map.size_y - y, y, 0.85, 101) + 0.3) * 6 + (perlin_coast_noise_2D(y, y, 0.45, 67) + 0.75) * 8);
+ max_x = max((smallest_size * smallest_size / 16) + max_x, (smallest_size * smallest_size / 16) + margin - max_x);
+ if (smallest_size < 8 && max_x > 5) max_x /= 1.5;
+ for (x = _height_map.size_x; x > (_height_map.size_x - 1 - max_x); x--) {
+ HeightMapXY(x, y) = 0;
+ }
+ }
+
+ /* Lower to sea level */
+ for (x = 0; x <= _height_map.size_x; x++) {
+ /* Top left */
+ max_y = myabs((perlin_coast_noise_2D(x, _height_map.size_y / 2, 0.9, 167) + 0.4) * 5 + (perlin_coast_noise_2D(x, _height_map.size_y / 3, 0.4, 211) + 0.7) * 9);
+ max_y = max((smallest_size * smallest_size / 16) + max_y, (smallest_size * smallest_size / 16) + margin - max_y);
+ if (smallest_size < 8 && max_y > 5) max_y /= 1.5;
+ for (y = 0; y < max_y; y++) {
+ HeightMapXY(x, y) = 0;
+ }
+
+
+ /* Bottom right */
+ max_y = myabs((perlin_coast_noise_2D(x, _height_map.size_y / 3, 0.85, 71) + 0.25) * 6 + (perlin_coast_noise_2D(x, _height_map.size_y / 3, 0.35, 193) + 0.75) * 12);
+ max_y = max((smallest_size * smallest_size / 16) + max_y, (smallest_size * smallest_size / 16) + margin - max_y);
+ if (smallest_size < 8 && max_y > 5) max_y /= 1.5;
+ for (y = _height_map.size_y; y > (_height_map.size_y - 1 - max_y); y--) {
+ HeightMapXY(x, y) = 0;
+ }
+ }
+}
+
+/** Start at given point, move in given direction, find and Smooth coast in that direction */
+static void HeightMapSmoothCoastInDirection(int org_x, int org_y, int dir_x, int dir_y)
+{
+ const int max_coast_dist_from_edge = 35;
+ const int max_coast_Smooth_depth = 35;
+
+ int x, y;
+ int ed; // coast distance from edge
+ int depth;
+
+ height_t h_prev = 16;
+ height_t h;
+
+ assert(IsValidXY(org_x, org_y));
+
+ /* Search for the coast (first non-water tile) */
+ for (x = org_x, y = org_y, ed = 0; IsValidXY(x, y) && ed < max_coast_dist_from_edge; x += dir_x, y += dir_y, ed++) {
+ /* Coast found? */
+ if (HeightMapXY(x, y) > 15) break;
+
+ /* Coast found in the neighborhood? */
+ if (IsValidXY(x + dir_y, y + dir_x) && HeightMapXY(x + dir_y, y + dir_x) > 0) break;
+
+ /* Coast found in the neighborhood on the other side */
+ if (IsValidXY(x - dir_y, y - dir_x) && HeightMapXY(x - dir_y, y - dir_x) > 0) break;
+ }
+
+ /* Coast found or max_coast_dist_from_edge has been reached.
+ * Soften the coast slope */
+ for (depth = 0; IsValidXY(x, y) && depth <= max_coast_Smooth_depth; depth++, x += dir_x, y += dir_y) {
+ h = HeightMapXY(x, y);
+ h = min(h, h_prev + (4 + depth)); // coast softening formula
+ HeightMapXY(x, y) = h;
+ h_prev = h;
+ }
+}
+
+/** Smooth coasts by modulating height of tiles close to map edges with cosine of distance from edge */
+static void HeightMapSmoothCoasts(void)
+{
+ uint x, y;
+ /* First Smooth NW and SE coasts (y close to 0 and y close to size_y) */
+ for (x = 0; x < _height_map.size_x; x++) {
+ HeightMapSmoothCoastInDirection(x, 0, 0, 1);
+ HeightMapSmoothCoastInDirection(x, _height_map.size_y - 1, 0, -1);
+ }
+ /* First Smooth NE and SW coasts (x close to 0 and x close to size_x) */
+ for (y = 0; y < _height_map.size_y; y++) {
+ HeightMapSmoothCoastInDirection(0, y, 1, 0);
+ HeightMapSmoothCoastInDirection(_height_map.size_x - 1, y, -1, 0);
+ }
+}
+
+/**
+ * This routine provides the essential cleanup necessary before OTTD can
+ * display the terrain. When generated, the terrain heights can jump more than
+ * one level between tiles. This routine smooths out those differences so that
+ * the most it can change is one level. When OTTD can support cliffs, this
+ * routine may not be necessary.
+ */
+static void HeightMapSmoothSlopes(height_t dh_max)
+{
+ int x, y;
+ for (y = 1; y <= (int)_height_map.size_y; y++) {
+ for (x = 1; x <= (int)_height_map.size_x; x++) {
+ height_t h_max = min(HeightMapXY(x - 1, y), HeightMapXY(x, y - 1)) + dh_max;
+ if (HeightMapXY(x, y) > h_max) HeightMapXY(x, y) = h_max;
+ }
+ }
+ for (y = _height_map.size_y - 1; y >= 0; y--) {
+ for (x = _height_map.size_x - 1; x >= 0; x--) {
+ height_t h_max = min(HeightMapXY(x + 1, y), HeightMapXY(x, y + 1)) + dh_max;
+ if (HeightMapXY(x, y) > h_max) HeightMapXY(x, y) = h_max;
+ }
+ }
+}
+
+/** Height map terraform post processing:
+ * - water level adjusting
+ * - coast Smoothing
+ * - slope Smoothing
+ * - height histogram redistribution by sine wave transform */
+static void HeightMapNormalize(void)
+{
+ const amplitude_t water_percent = _water_percent[_opt.diff.quantity_sea_lakes];
+ const height_t h_max_new = I2H(_max_height[_opt.diff.terrain_type]);
+ const height_t roughness = 7 + 3 * _patches.tgen_smoothness;
+
+ HeightMapAdjustWaterLevel(water_percent, h_max_new);
+
+ HeightMapCoastLines();
+ HeightMapSmoothSlopes(roughness);
+
+ HeightMapSmoothCoasts();
+ HeightMapSmoothSlopes(roughness);
+
+ HeightMapSineTransform(12, h_max_new);
+ HeightMapSmoothSlopes(16);
+}
+
+static inline int perlin_landXY(uint x, uint y)
+{
+ return HeightMapXY(x, y);
+}
+
+
+/* The following decimals are the octave power modifiers for the Perlin noise */
+static const double _perlin_p_values[][7] = { // perlin frequency per power
+ { 0.35, 0.35, 0.35, 0.35, 0.35, 0.25, 0.539 }, // Very smooth
+ { 0.45, 0.55, 0.45, 0.45, 0.35, 0.25, 0.89 }, // Smooth
+ { 0.85, 0.80, 0.70, 0.45, 0.45, 0.35, 1.825 }, // Rough 1.825
+ { 0.95, 0.85, 0.80, 0.55, 0.55, 0.45, 2.245 } // Very Rough 2.25
+};
+
+/**
+ * The Perlin Noise calculation using large primes
+ * The initial number is adjusted by two values; the generation_seed, and the
+ * passed parameter; prime.
+ * prime is used to allow the perlin noise generator to create useful random
+ * numbers from slightly different series.
+ */
+static double int_noise(const long x, const long y, const int prime)
+{
+ long n = x + y * prime + _patches.generation_seed;
+
+ n = (n << 13) ^ n;
+
+ /* Pseudo-random number generator, using several large primes */
+ return 1.0 - (double)((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0;
+}
+
+
+/**
+ * Hj. Malthaner's routine included 2 different noise smoothing methods.
+ * We now use the "raw" int_noise one.
+ * However, it may be useful to move to the other routine in future.
+ * So it is included too.
+ */
+static double smoothed_noise(const int x, const int y, const int prime)
+{
+#if 0
+ /* A hilly world (four corner smooth) */
+ const double sides = int_noise(x - 1, y) + int_noise(x + 1, y) + int_noise(x, y - 1) + int_noise(x, y + 1);
+ const double center = int_noise(x, y);
+ return (sides + sides + center * 4) / 8.0;
+#endif
+
+ /* This gives very hilly world */
+ return int_noise(x, y, prime);
+}
+
+
+/**
+ * This routine determines the interpolated value between a and b
+ */
+static inline double linear_interpolate(const double a, const double b, const double x)
+{
+ return a + x * (b - a);
+}
+
+
+/**
+ * This routine returns the smoothed interpolated noise for an x and y, using
+ * the values from the surrounding positions.
+ */
+static double interpolated_noise(const double x, const double y, const int prime)
+{
+ const int integer_X = (int)x;
+ const int integer_Y = (int)y;
+
+ const double fractional_X = x - (double)integer_X;
+ const double fractional_Y = y - (double)integer_Y;
+
+ const double v1 = smoothed_noise(integer_X, integer_Y, prime);
+ const double v2 = smoothed_noise(integer_X + 1, integer_Y, prime);
+ const double v3 = smoothed_noise(integer_X, integer_Y + 1, prime);
+ const double v4 = smoothed_noise(integer_X + 1, integer_Y + 1, prime);
+
+ const double i1 = linear_interpolate(v1, v2, fractional_X);
+ const double i2 = linear_interpolate(v3, v4, fractional_X);
+
+ return linear_interpolate(i1, i2, fractional_Y);
+}
+
+
+/**
+ * This is a similar function to the main perlin noise calculation, but uses
+ * the value p passed as a parameter rather than selected from the predefined
+ * sequences. as you can guess by its title, i use this to create the indented
+ * coastline, which is just another perlin sequence.
+ */
+static double perlin_coast_noise_2D(const double x, const double y, const double p, const int prime)
+{
+ double total = 0.0;
+ int i;
+
+ for (i = 0; i < 6; i++) {
+ const double frequency = (double)(1 << i);
+ const double amplitude = pow(p, (double)i);
+
+ total += interpolated_noise((x * frequency) / 64.0, (y * frequency) / 64.0, prime) * amplitude;
+ }
+
+ return total;
+}
+
+
+/** A small helper function */
+static void TgenSetTileHeight(TileIndex tile, int height)
+{
+ SetTileHeight(tile, height);
+ MakeClear(tile, CLEAR_GRASS, 3);
+}
+
+/**
+ * The main new land generator using Perlin noise. Desert landscape is handled
+ * different to all others to give a desert valley between two high mountains.
+ * Clearly if a low height terrain (flat/very flat) is chosen, then the tropic
+ * areas wont be high enough, and there will be very little tropic on the map.
+ * Thus Tropic works best on Hilly or Mountainous.
+ */
+void GenerateTerrainPerlin(void)
+{
+ uint x, y;
+
+ if (!AllocHeightMap()) return;
+ GenerateWorldSetAbortCallback(FreeHeightMap);
+
+ HeightMapGenerate();
+
+ IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
+
+ HeightMapNormalize();
+
+ IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
+
+ /* Transfer height map into OTTD map */
+ for (y = 2; y < _height_map.size_y - 2; y++) {
+ for (x = 2; x < _height_map.size_x - 2; x++) {
+ int height = H2I(HeightMapXY(x, y));
+ if (height < 0) height = 0;
+ if (height > 15) height = 15;
+ TgenSetTileHeight(TileXY(x, y), height);
+ }
+ }
+
+ IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
+
+ /* Recreate void tiles at the border in case they have been affected by generation */
+ for (y = 0; y < _height_map.size_y - 1; y++) MakeVoid(_height_map.size_x * y + _height_map.size_x - 1);
+ for (x = 0; x < _height_map.size_x; x++) MakeVoid(_height_map.size_x * y + x);
+
+ FreeHeightMap();
+ GenerateWorldSetAbortCallback(NULL);
+}
diff --git a/src/tgp.h b/src/tgp.h
new file mode 100644
index 000000000..1e51eecbe
--- /dev/null
+++ b/src/tgp.h
@@ -0,0 +1,8 @@
+/* $Id$ */
+
+#ifndef TGP_H
+#define TGP_H
+
+void GenerateTerrainPerlin(void);
+
+#endif /* TGP_H */
diff --git a/src/thread.c b/src/thread.c
new file mode 100644
index 000000000..ab2cfd21d
--- /dev/null
+++ b/src/thread.c
@@ -0,0 +1,157 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "thread.h"
+#include <stdlib.h>
+
+#if defined(__AMIGA__) || defined(__MORPHOS__) || defined(NO_THREADS)
+OTTDThread *OTTDCreateThread(OTTDThreadFunc function, void *arg) { return NULL; }
+void *OTTDJoinThread(OTTDThread *t) { return NULL; }
+void OTTDExitThread(void) { NOT_REACHED(); };
+
+#elif defined(__OS2__)
+
+#define INCL_DOS
+#include <os2.h>
+#include <process.h>
+
+struct OTTDThread {
+ TID thread;
+ OTTDThreadFunc func;
+ void* arg;
+ void* ret;
+};
+
+static void Proxy(void* arg)
+{
+ OTTDThread* t = arg;
+ t->ret = t->func(t->arg);
+}
+
+OTTDThread* OTTDCreateThread(OTTDThreadFunc function, void* arg)
+{
+ OTTDThread* t = malloc(sizeof(*t));
+
+ if (t == NULL) return NULL;
+
+ t->func = function;
+ t->arg = arg;
+ t->thread = _beginthread(Proxy, NULL, 32768, t);
+ if (t->thread != -1) {
+ return t;
+ } else {
+ free(t);
+ return NULL;
+ }
+}
+
+void* OTTDJoinThread(OTTDThread* t)
+{
+ void* ret;
+
+ if (t == NULL) return NULL;
+
+ DosWaitThread(&t->thread, DCWW_WAIT);
+ ret = t->ret;
+ free(t);
+ return ret;
+}
+
+void OTTDExitThread(void)
+{
+ _endthread();
+}
+
+#elif defined(UNIX)
+
+#include <pthread.h>
+
+struct OTTDThread {
+ pthread_t thread;
+};
+
+OTTDThread* OTTDCreateThread(OTTDThreadFunc function, void* arg)
+{
+ OTTDThread* t = malloc(sizeof(*t));
+
+ if (t == NULL) return NULL;
+
+ if (pthread_create(&t->thread, NULL, function, arg) == 0) {
+ return t;
+ } else {
+ free(t);
+ return NULL;
+ }
+}
+
+void* OTTDJoinThread(OTTDThread* t)
+{
+ void* ret;
+
+ if (t == NULL) return NULL;
+
+ pthread_join(t->thread, &ret);
+ free(t);
+ return ret;
+}
+
+void OTTDExitThread(void)
+{
+ pthread_exit(NULL);
+}
+
+#elif defined(WIN32)
+
+#include <windows.h>
+
+struct OTTDThread {
+ HANDLE thread;
+ OTTDThreadFunc func;
+ void* arg;
+ void* ret;
+};
+
+static DWORD WINAPI Proxy(LPVOID arg)
+{
+ OTTDThread* t = arg;
+ t->ret = t->func(t->arg);
+ return 0;
+}
+
+OTTDThread* OTTDCreateThread(OTTDThreadFunc function, void* arg)
+{
+ OTTDThread* t = malloc(sizeof(*t));
+ DWORD dwThreadId;
+
+ if (t == NULL) return NULL;
+
+ t->func = function;
+ t->arg = arg;
+ t->thread = CreateThread(NULL, 0, Proxy, t, 0, &dwThreadId);
+
+ if (t->thread != NULL) {
+ return t;
+ } else {
+ free(t);
+ return NULL;
+ }
+}
+
+void* OTTDJoinThread(OTTDThread* t)
+{
+ void* ret;
+
+ if (t == NULL) return NULL;
+
+ WaitForSingleObject(t->thread, INFINITE);
+ CloseHandle(t->thread);
+ ret = t->ret;
+ free(t);
+ return ret;
+}
+
+void OTTDExitThread(void)
+{
+ ExitThread(0);
+}
+#endif
diff --git a/src/thread.h b/src/thread.h
new file mode 100644
index 000000000..900b87849
--- /dev/null
+++ b/src/thread.h
@@ -0,0 +1,14 @@
+/* $Id$ */
+
+#ifndef THREAD_H
+#define THREAD_H
+
+typedef struct OTTDThread OTTDThread;
+
+typedef void* (*OTTDThreadFunc)(void*);
+
+OTTDThread* OTTDCreateThread(OTTDThreadFunc, void*);
+void* OTTDJoinThread(OTTDThread*);
+void OTTDExitThread(void);
+
+#endif /* THREAD_H */
diff --git a/src/tile.c b/src/tile.c
new file mode 100644
index 000000000..ba6900a36
--- /dev/null
+++ b/src/tile.c
@@ -0,0 +1,63 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "tile.h"
+
+Slope GetTileSlope(TileIndex tile, uint *h)
+{
+ uint a;
+ uint b;
+ uint c;
+ uint d;
+ uint min;
+ uint r;
+
+ assert(tile < MapSize());
+
+ if (TileX(tile) == MapMaxX() || TileY(tile) == MapMaxY()) {
+ if (h != NULL) *h = 0;
+ return 0;
+ }
+
+ min = a = TileHeight(tile);
+ b = TileHeight(tile + TileDiffXY(1, 0));
+ if (min >= b) min = b;
+ c = TileHeight(tile + TileDiffXY(0, 1));
+ if (min >= c) min = c;
+ d = TileHeight(tile + TileDiffXY(1, 1));
+ if (min >= d) min = d;
+
+ r = SLOPE_FLAT;
+ if ((a -= min) != 0) r += (--a << 4) + SLOPE_N;
+ if ((c -= min) != 0) r += (--c << 4) + SLOPE_E;
+ if ((d -= min) != 0) r += (--d << 4) + SLOPE_S;
+ if ((b -= min) != 0) r += (--b << 4) + SLOPE_W;
+
+ if (h != NULL) *h = min * TILE_HEIGHT;
+
+ return r;
+}
+
+uint GetTileZ(TileIndex tile)
+{
+ uint h;
+ GetTileSlope(tile, &h);
+ return h;
+}
+
+
+uint GetTileMaxZ(TileIndex t)
+{
+ uint max;
+ uint h;
+
+ h = TileHeight(t);
+ max = h;
+ h = TileHeight(t + TileDiffXY(1, 0));
+ if (h > max) max = h;
+ h = TileHeight(t + TileDiffXY(0, 1));
+ if (h > max) max = h;
+ h = TileHeight(t + TileDiffXY(1, 1));
+ if (h > max) max = h;
+ return max * 8;
+}
diff --git a/src/tile.h b/src/tile.h
new file mode 100644
index 000000000..97123645f
--- /dev/null
+++ b/src/tile.h
@@ -0,0 +1,121 @@
+/* $Id$ */
+
+#ifndef TILE_H
+#define TILE_H
+
+#include "macros.h"
+#include "map.h"
+#include "slope.h"
+
+typedef enum TileTypes {
+ MP_CLEAR,
+ MP_RAILWAY,
+ MP_STREET,
+ MP_HOUSE,
+ MP_TREES,
+ MP_STATION,
+ MP_WATER,
+ MP_VOID, // invisible tiles at the SW and SE border
+ MP_INDUSTRY,
+ MP_TUNNELBRIDGE,
+ MP_UNMOVABLE,
+} TileType;
+
+typedef enum TropicZones {
+ TROPICZONE_INVALID = 0,
+ TROPICZONE_DESERT = 1,
+ TROPICZONE_RAINFOREST = 2,
+} TropicZone;
+
+Slope GetTileSlope(TileIndex tile, uint *h);
+uint GetTileZ(TileIndex tile);
+uint GetTileMaxZ(TileIndex tile);
+
+static inline uint TileHeight(TileIndex tile)
+{
+ assert(tile < MapSize());
+ return GB(_m[tile].type_height, 0, 4);
+}
+
+static inline void SetTileHeight(TileIndex tile, uint height)
+{
+ assert(tile < MapSize());
+ assert(height < 16);
+ SB(_m[tile].type_height, 0, 4, height);
+}
+
+static inline uint TilePixelHeight(TileIndex tile)
+{
+ return TileHeight(tile) * TILE_HEIGHT;
+}
+
+static inline TileType GetTileType(TileIndex tile)
+{
+ assert(tile < MapSize());
+ return (TileType)GB(_m[tile].type_height, 4, 4);
+}
+
+static inline void SetTileType(TileIndex tile, TileType type)
+{
+ assert(tile < MapSize());
+ /* VOID tiles (and no others) are exactly allowed at the lower left and right
+ * edges of the map */
+ assert((TileX(tile) == MapMaxX() || TileY(tile) == MapMaxY()) == (type == MP_VOID));
+ SB(_m[tile].type_height, 4, 4, type);
+}
+
+static inline bool IsTileType(TileIndex tile, TileType type)
+{
+ return GetTileType(tile) == type;
+}
+
+
+static inline Owner GetTileOwner(TileIndex tile)
+{
+ assert(tile < MapSize());
+ assert(!IsTileType(tile, MP_HOUSE));
+ assert(!IsTileType(tile, MP_VOID));
+ assert(!IsTileType(tile, MP_INDUSTRY));
+
+ return (Owner)_m[tile].m1;
+}
+
+static inline void SetTileOwner(TileIndex tile, Owner owner)
+{
+ assert(tile < MapSize());
+ assert(!IsTileType(tile, MP_HOUSE));
+ assert(!IsTileType(tile, MP_VOID));
+ assert(!IsTileType(tile, MP_INDUSTRY));
+
+ _m[tile].m1 = owner;
+}
+
+static inline bool IsTileOwner(TileIndex tile, Owner owner)
+{
+ return GetTileOwner(tile) == owner;
+}
+
+/**
+ * Set the tropic zone
+ * @param tile the tile to set the zone of
+ * @param type the new type
+ * @pre assert(tile < MapSize());
+ */
+static inline void SetTropicZone(TileIndex tile, TropicZone type)
+{
+ assert(tile < MapSize());
+ SB(_m[tile].extra, 0, 2, type);
+}
+
+/**
+ * Get the tropic zone
+ * @param tile the tile to get the zone of
+ * @pre assert(tile < MapSize());
+ * @return the zone type
+ */
+static inline TropicZone GetTropicZone(TileIndex tile)
+{
+ assert(tile < MapSize());
+ return (TropicZone)GB(_m[tile].extra, 0, 2);
+}
+#endif /* TILE_H */
diff --git a/src/town.h b/src/town.h
new file mode 100644
index 000000000..d1edca1c8
--- /dev/null
+++ b/src/town.h
@@ -0,0 +1,230 @@
+/* $Id$ */
+
+#ifndef TOWN_H
+#define TOWN_H
+
+#include "oldpool.h"
+#include "player.h"
+
+enum {
+ INVALID_TOWN = 0xFFFF,
+};
+
+struct Town {
+ TileIndex xy;
+
+ // Current population of people and amount of houses.
+ uint16 num_houses;
+ uint32 population;
+
+ // Town name
+ uint16 townnametype;
+ uint32 townnameparts;
+
+ // NOSAVE: Location of name sign, UpdateTownVirtCoord updates this.
+ ViewportSign sign;
+
+ // Makes sure we don't build certain house types twice.
+ // bit 0 = Building funds received
+ // bit 1 = CHURCH
+ // bit 2 = STADIUM
+ byte flags12;
+
+ // Which players have a statue?
+ byte statues;
+
+ // Player ratings as well as a mask that determines which players have a rating.
+ byte have_ratings;
+ uint8 unwanted[MAX_PLAYERS]; // how many months companies aren't wanted by towns (bribe)
+ PlayerID exclusivity; // which player has exslusivity
+ uint8 exclusive_counter; // months till the exclusivity expires
+ int16 ratings[MAX_PLAYERS];
+
+ // Maximum amount of passengers and mail that can be transported.
+ uint32 max_pass;
+ uint32 max_mail;
+ uint32 new_max_pass;
+ uint32 new_max_mail;
+ uint32 act_pass;
+ uint32 act_mail;
+ uint32 new_act_pass;
+ uint32 new_act_mail;
+
+ // Amount of passengers that were transported.
+ byte pct_pass_transported;
+ byte pct_mail_transported;
+
+ // Amount of food and paper that was transported. Actually a bit mask would be enough.
+ uint16 act_food;
+ uint16 act_water;
+ uint16 new_act_food;
+ uint16 new_act_water;
+
+ // Time until we rebuild a house.
+ byte time_until_rebuild;
+
+ // When to grow town next time.
+ byte grow_counter;
+ byte growth_rate;
+
+ // Fund buildings program in action?
+ byte fund_buildings_months;
+
+ // Fund road reconstruction in action?
+ byte road_build_months;
+
+ // Index in town array
+ TownID index;
+
+ // NOSAVE: UpdateTownRadius updates this given the house count.
+ uint16 radius[5];
+};
+
+uint32 GetWorldPopulation(void);
+
+void UpdateTownVirtCoord(Town *t);
+void InitializeTown(void);
+void ShowTownViewWindow(TownID town);
+void ExpandTown(Town *t);
+Town *CreateRandomTown(uint attempts, uint size_mode);
+
+enum {
+ ROAD_REMOVE = 0,
+ UNMOVEABLE_REMOVE = 1,
+ TUNNELBRIDGE_REMOVE = 1,
+ INDUSTRY_REMOVE = 2
+};
+
+enum {
+ // These refer to the maximums, so Appalling is -1000 to -400
+ // MAXIMUM RATINGS BOUNDARIES
+ RATING_MINIMUM = -1000,
+ RATING_APPALLING = -400,
+ RATING_VERYPOOR = -200,
+ RATING_POOR = 0,
+ RATING_MEDIOCRE = 200,
+ RATING_GOOD = 400,
+ RATING_VERYGOOD = 600,
+ RATING_EXCELLENT = 800,
+ RATING_OUTSTANDING = 1000, // OUTSTANDING
+
+ RATING_MAXIMUM = RATING_OUTSTANDING,
+
+ // RATINGS AFFECTING NUMBERS
+ RATING_TREE_DOWN_STEP = -35,
+ RATING_TREE_MINIMUM = RATING_MINIMUM,
+ RATING_TREE_UP_STEP = 7,
+ RATING_TREE_MAXIMUM = 220,
+
+ RATING_TUNNEL_BRIDGE_DOWN_STEP = -250,
+ RATING_TUNNEL_BRIDGE_MINIMUM = 0,
+
+ RATING_INDUSTRY_DOWN_STEP = -1500,
+ RATING_INDUSTRY_MINIMUM = RATING_MINIMUM,
+
+ RATING_ROAD_DOWN_STEP = -50,
+ RATING_ROAD_MINIMUM = -100,
+ RATING_HOUSE_MINIMUM = RATING_MINIMUM,
+
+ RATING_BRIBE_UP_STEP = 200,
+ RATING_BRIBE_MAXIMUM = 800,
+ RATING_BRIBE_DOWN_TO = -50 // XXX SHOULD BE SOMETHING LOWER?
+};
+
+enum {
+/* This is the base "normal" number of towns on the 8x8 map, when
+ * one town should get grown per tick. The other numbers of towns
+ * are then scaled based on that. */
+ TOWN_GROWTH_FREQUENCY = 23,
+/* Simple value that indicates the house has reached final stage of construction*/
+ TOWN_HOUSE_COMPLETED = 3,
+};
+
+/* This enum is used in conjonction with town->flags12.
+ * IT simply states what bit is used for.
+ * It is pretty unrealistic (IMHO) to only have one church/stadium
+ * per town, NO MATTER the population of it.
+ * And there are 5 more bits available on flags12...
+ */
+enum {
+ TOWN_IS_FUNDED = 0, // Town has received some funds for
+ TOWN_HAS_CHURCH = 1, // There can be only one church by town.
+ TOWN_HAS_STADIUM = 2 // There can be only one stadium by town.
+};
+
+bool CheckforTownRating(uint32 flags, Town *t, byte type);
+
+VARDEF const Town** _town_sort;
+
+DECLARE_OLD_POOL(Town, Town, 3, 8000)
+
+/**
+ * Check if a Town really exists.
+ */
+static inline bool IsValidTown(const Town* town)
+{
+ return town->xy != 0;
+}
+
+static inline bool IsValidTownID(TownID index)
+{
+ return index < GetTownPoolSize() && IsValidTown(GetTown(index));
+}
+
+VARDEF uint _total_towns;
+
+static inline TownID GetMaxTownIndex(void)
+{
+ /* TODO - This isn't the real content of the function, but
+ * with the new pool-system this will be replaced with one that
+ * _really_ returns the highest index. Now it just returns
+ * the next safe value we are sure about everything is below.
+ */
+ return GetTownPoolSize() - 1;
+}
+
+static inline uint GetNumTowns(void)
+{
+ return _total_towns;
+}
+
+/**
+ * Return a random valid town.
+ */
+static inline Town *GetRandomTown(void)
+{
+ int num = RandomRange(GetNumTowns());
+ TownID index = INVALID_TOWN;
+
+ while (num >= 0) {
+ num--;
+
+ index++;
+ /* Make sure we have a valid industry */
+ while (!IsValidTownID(index)) {
+ index++;
+ assert(index <= GetMaxTownIndex());
+ }
+ }
+
+ return GetTown(index);
+}
+
+void DestroyTown(Town *t);
+
+static inline void DeleteTown(Town *t)
+{
+ DestroyTown(t);
+ t->xy = 0;
+}
+
+#define FOR_ALL_TOWNS_FROM(t, start) for (t = GetTown(start); t != NULL; t = (t->index + 1U < GetTownPoolSize()) ? GetTown(t->index + 1U) : NULL) if (IsValidTown(t))
+#define FOR_ALL_TOWNS(t) FOR_ALL_TOWNS_FROM(t, 0)
+
+VARDEF bool _town_sort_dirty;
+VARDEF byte _town_sort_order;
+
+VARDEF Town *_cleared_town;
+VARDEF int _cleared_town_rating;
+
+#endif /* TOWN_H */
diff --git a/src/town_cmd.c b/src/town_cmd.c
new file mode 100644
index 000000000..9c00cf25a
--- /dev/null
+++ b/src/town_cmd.c
@@ -0,0 +1,1965 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "functions.h"
+#include "strings.h"
+#include "road_map.h"
+#include "table/strings.h"
+#include "table/sprites.h"
+#include "map.h"
+#include "tile.h"
+#include "town_map.h"
+#include "tunnel_map.h"
+#include "viewport.h"
+#include "town.h"
+#include "command.h"
+#include "gfx.h"
+#include "industry.h"
+#include "station.h"
+#include "player.h"
+#include "news.h"
+#include "saveload.h"
+#include "economy.h"
+#include "gui.h"
+#include "unmovable_map.h"
+#include "water_map.h"
+#include "variables.h"
+#include "bridge.h"
+#include "bridge_map.h"
+#include "date.h"
+#include "table/town_land.h"
+#include "genworld.h"
+
+/**
+ * Called if a new block is added to the town-pool
+ */
+static void TownPoolNewBlock(uint start_item)
+{
+ Town *t;
+
+ /* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
+ * TODO - This is just a temporary stage, this will be removed. */
+ for (t = GetTown(start_item); t != NULL; t = (t->index + 1U < GetTownPoolSize()) ? GetTown(t->index + 1U) : NULL) t->index = start_item++;
+}
+
+/* Initialize the town-pool */
+DEFINE_OLD_POOL(Town, Town, TownPoolNewBlock, NULL)
+
+void DestroyTown(Town *t)
+{
+ Industry *i;
+ TileIndex tile;
+
+ /* Delete town authority window
+ * and remove from list of sorted towns */
+ DeleteWindowById(WC_TOWN_VIEW, t->index);
+ _town_sort_dirty = true;
+ _total_towns--;
+
+ /* Delete all industries belonging to the town */
+ FOR_ALL_INDUSTRIES(i) if (i->town == t) DeleteIndustry(i);
+
+ /* Go through all tiles and delete those belonging to the town */
+ for (tile = 0; tile < MapSize(); ++tile) {
+ switch (GetTileType(tile)) {
+ case MP_HOUSE:
+ if (GetTownByTile(tile) == t) DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
+ break;
+
+ case MP_STREET:
+ case MP_TUNNELBRIDGE:
+ if (IsTileOwner(tile, OWNER_TOWN) &&
+ ClosestTownFromTile(tile, (uint)-1) == t)
+ DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ DeleteName(t->townnametype);
+ DeleteSubsidyWithTown(t->index);
+
+ MarkWholeScreenDirty();
+}
+
+// Local
+static int _grow_town_result;
+
+static bool BuildTownHouse(Town *t, TileIndex tile);
+static void ClearTownHouse(Town *t, TileIndex tile);
+static void DoBuildTownHouse(Town *t, TileIndex tile);
+
+static void TownDrawHouseLift(const TileInfo *ti)
+{
+ AddChildSpriteScreen(SPR_LIFT, 14, 60 - GetLiftPosition(ti->tile));
+}
+
+typedef void TownDrawTileProc(const TileInfo *ti);
+static TownDrawTileProc * const _town_draw_tile_procs[1] = {
+ TownDrawHouseLift
+};
+
+
+static void DrawTile_Town(TileInfo *ti)
+{
+ const DrawBuildingsTileStruct *dcts;
+ uint32 image;
+
+ /* Retrieve pointer to the draw town tile struct */
+ {
+ /* this "randomizes" on the (up to) 4 variants of a building */
+ uint variant;
+ variant = ti->x >> 4;
+ variant ^= ti->x >> 6;
+ variant ^= ti->y >> 4;
+ variant -= ti->y >> 6;
+ variant &= 3;
+ dcts = &_town_draw_tile_data[GetHouseType(ti->tile) << 4 | variant << 2 | GetHouseBuildingStage(ti->tile)];
+ }
+
+ if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
+ DrawGroundSprite(dcts->ground);
+
+ /* Add a house on top of the ground? */
+ image = dcts->building;
+ if (image != 0) {
+ if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
+
+ AddSortableSpriteToDraw(image,
+ ti->x + dcts->subtile_x,
+ ti->y + dcts->subtile_y,
+ dcts->width + 1,
+ dcts->height + 1,
+ dcts->dz,
+ ti->z
+ );
+
+ if (_display_opt & DO_TRANS_BUILDINGS) return;
+ }
+
+ {
+ int proc = dcts->draw_proc - 1;
+
+ if (proc >= 0) _town_draw_tile_procs[proc](ti);
+ }
+}
+
+static uint GetSlopeZ_Town(TileIndex tile, uint x, uint y)
+{
+ return GetTileMaxZ(tile);
+}
+
+static Slope GetSlopeTileh_Town(TileIndex tile, Slope tileh)
+{
+ return SLOPE_FLAT;
+}
+
+static void AnimateTile_Town(TileIndex tile)
+{
+ int pos, dest;
+
+ if (_tick_counter & 3) return;
+
+ // If the house is not one with a lift anymore, then stop this animating.
+ // Not exactly sure when this happens, but probably when a house changes.
+ // Before this was just a return...so it'd leak animated tiles..
+ // That bug seems to have been here since day 1??
+ if (!(_housetype_extra_flags[GetHouseType(tile)] & 0x20)) {
+ DeleteAnimatedTile(tile);
+ return;
+ }
+
+ if (!IsLiftMoving(tile)) {
+ int i;
+
+ /** Building has 6 floors, number 0 .. 6, where 1 is illegal.
+ * This is due to the fact that the first floor is, in the graphics,
+ * the height of 2 'normal' floors.
+ * Furthermore, there are 6 lift positions from floor N (incl) to floor N + 1 (excl) */
+ do {
+ i = (Random() & 7) - 1;
+ } while (i < 0 || i == 1 || i * 6 == GetLiftPosition(tile));
+
+ SetLiftDestination(tile, i);
+ }
+
+ pos = GetLiftPosition(tile);
+ dest = GetLiftDestination(tile) * 6;
+ pos += (pos < dest) ? 1 : -1;
+ SetLiftPosition(tile, pos);
+
+ if (pos == dest) HaltLift(tile);
+
+ MarkTileDirtyByTile(tile);
+}
+
+static void UpdateTownRadius(Town *t);
+
+static bool IsCloseToTown(TileIndex tile, uint dist)
+{
+ const Town* t;
+
+ FOR_ALL_TOWNS(t) {
+ if (DistanceManhattan(tile, t->xy) < dist) return true;
+ }
+ return false;
+}
+
+static void MarkTownSignDirty(Town *t)
+{
+ MarkAllViewportsDirty(
+ t->sign.left-6,
+ t->sign.top-3,
+ t->sign.left+t->sign.width_1*4+12,
+ t->sign.top + 45
+ );
+}
+
+void UpdateTownVirtCoord(Town *t)
+{
+ Point pt;
+
+ MarkTownSignDirty(t);
+ pt = RemapCoords2(TileX(t->xy) * TILE_SIZE, TileY(t->xy) * TILE_SIZE);
+ SetDParam(0, t->index);
+ SetDParam(1, t->population);
+ UpdateViewportSignPos(&t->sign, pt.x, pt.y - 24,
+ _patches.population_in_label ? STR_TOWN_LABEL_POP : STR_TOWN_LABEL);
+ MarkTownSignDirty(t);
+}
+
+static void ChangePopulation(Town *t, int mod)
+{
+ t->population += mod;
+ InvalidateWindow(WC_TOWN_VIEW, t->index);
+ UpdateTownVirtCoord(t);
+
+ if (_town_sort_order & 2) _town_sort_dirty = true;
+}
+
+uint32 GetWorldPopulation(void)
+{
+ uint32 pop;
+ const Town* t;
+
+ pop = 0;
+ FOR_ALL_TOWNS(t) pop += t->population;
+ return pop;
+}
+
+static void MakeSingleHouseBigger(TileIndex tile)
+{
+ assert(IsTileType(tile, MP_HOUSE));
+
+ if (LiftHasDestination(tile)) return;
+
+ IncHouseConstructionTick(tile);
+ if (GetHouseConstructionTick(tile) != 0) return;
+
+ IncHouseBuildingStage(tile); /*increase construction stage of one more step*/
+
+ if (GetHouseBuildingStage(tile) == TOWN_HOUSE_COMPLETED){
+ /*Now, construction is completed. Can add population of building to the town*/
+ ChangePopulation(GetTownByTile(tile), _housetype_population[GetHouseType(tile)]);
+ }
+ MarkTileDirtyByTile(tile);
+}
+
+static void MakeTownHouseBigger(TileIndex tile)
+{
+ uint flags = _house_more_flags[GetHouseType(tile)];
+ if (flags & 8) MakeSingleHouseBigger(TILE_ADDXY(tile, 0, 0));
+ if (flags & 4) MakeSingleHouseBigger(TILE_ADDXY(tile, 0, 1));
+ if (flags & 2) MakeSingleHouseBigger(TILE_ADDXY(tile, 1, 0));
+ if (flags & 1) MakeSingleHouseBigger(TILE_ADDXY(tile, 1, 1));
+}
+
+static void TileLoop_Town(TileIndex tile)
+{
+ int house;
+ Town *t;
+ uint32 r;
+
+ if (GetHouseBuildingStage(tile) != TOWN_HOUSE_COMPLETED) {
+ /*Construction is not completed. See if we can go further in construction*/
+ MakeTownHouseBigger(tile);
+ return;
+ }
+
+ house = GetHouseType(tile);
+ if ((_housetype_extra_flags[house] & 0x20) && !LiftHasDestination(tile) && CHANCE16(1, 2) && AddAnimatedTile(tile)) BeginLiftMovement(tile);
+
+ t = GetTownByTile(tile);
+
+ r = Random();
+
+ if (GB(r, 0, 8) < _housetype_population[house]) {
+ uint amt = GB(r, 0, 8) / 8 + 1;
+ uint moved;
+
+ if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
+ t->new_max_pass += amt;
+ moved = MoveGoodsToStation(tile, 1, 1, CT_PASSENGERS, amt);
+ t->new_act_pass += moved;
+ }
+
+ if (GB(r, 8, 8) < _housetype_mailamount[house] ) {
+ uint amt = GB(r, 8, 8) / 8 + 1;
+ uint moved;
+
+ if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
+ t->new_max_mail += amt;
+ moved = MoveGoodsToStation(tile, 1, 1, CT_MAIL, amt);
+ t->new_act_mail += moved;
+ }
+
+ if (_house_more_flags[house] & 8 && HASBIT(t->flags12, TOWN_IS_FUNDED) && --t->time_until_rebuild == 0) {
+ t->time_until_rebuild = GB(r, 16, 6) + 130;
+
+ _current_player = OWNER_TOWN;
+
+ ClearTownHouse(t, tile);
+
+ // rebuild with another house?
+ if (GB(r, 24, 8) >= 12) DoBuildTownHouse(t, tile);
+
+ _current_player = OWNER_NONE;
+ }
+}
+
+static void ClickTile_Town(TileIndex tile)
+{
+ /* not used */
+}
+
+static int32 ClearTile_Town(TileIndex tile, byte flags)
+{
+ int house, rating;
+ int32 cost;
+ Town *t;
+
+ // safety checks
+ if (!EnsureNoVehicle(tile)) return CMD_ERROR;
+ if (flags&DC_AUTO && !(flags&DC_AI_BUILDING)) return_cmd_error(STR_2004_BUILDING_MUST_BE_DEMOLISHED);
+
+ house = GetHouseType(tile);
+ cost = _price.remove_house * _housetype_remove_cost[house] >> 8;
+
+ rating = _housetype_remove_ratingmod[house];
+ _cleared_town_rating += rating;
+ _cleared_town = t = GetTownByTile(tile);
+
+ if (IsValidPlayer(_current_player)) {
+ if (rating > t->ratings[_current_player] && !(flags & DC_NO_TOWN_RATING) && !_cheats.magic_bulldozer.value) {
+ SetDParam(0, t->index);
+ return_cmd_error(STR_2009_LOCAL_AUTHORITY_REFUSES);
+ }
+ }
+
+ if (flags & DC_EXEC) {
+ ChangeTownRating(t, -rating, RATING_HOUSE_MINIMUM);
+ ClearTownHouse(t, tile);
+ }
+
+ return cost;
+}
+
+static void GetAcceptedCargo_Town(TileIndex tile, AcceptedCargo ac)
+{
+ byte type = GetHouseType(tile);
+
+ ac[CT_PASSENGERS] = _housetype_cargo_passengers[type];
+ ac[CT_MAIL] = _housetype_cargo_mail[type];
+ ac[CT_GOODS] = _housetype_cargo_goods[type];
+ ac[CT_FOOD] = _housetype_cargo_food[type];
+}
+
+static void GetTileDesc_Town(TileIndex tile, TileDesc *td)
+{
+ td->str = _town_tile_names[GetHouseType(tile)];
+ if (GetHouseBuildingStage(tile) != TOWN_HOUSE_COMPLETED) {
+ SetDParamX(td->dparam, 0, td->str);
+ td->str = STR_2058_UNDER_CONSTRUCTION;
+ }
+
+ td->owner = OWNER_TOWN;
+}
+
+static uint32 GetTileTrackStatus_Town(TileIndex tile, TransportType mode)
+{
+ /* not used */
+ return 0;
+}
+
+static void ChangeTileOwner_Town(TileIndex tile, PlayerID old_player, PlayerID new_player)
+{
+ /* not used */
+}
+
+
+static const TileIndexDiffC _roadblock_tileadd[] = {
+ { 0, -1},
+ { 1, 0},
+ { 0, 1},
+ {-1, 0},
+
+ // Store the first 3 elements again.
+ // Lets us rotate without using &3.
+ { 0, -1},
+ { 1, 0},
+ { 0, 1}
+};
+
+
+static bool GrowTown(Town *t);
+
+static void TownTickHandler(Town *t)
+{
+ if (HASBIT(t->flags12, TOWN_IS_FUNDED)) {
+ int i = t->grow_counter - 1;
+ if (i < 0) {
+ if (GrowTown(t)) {
+ i = t->growth_rate;
+ } else {
+ i = 0;
+ }
+ }
+ t->grow_counter = i;
+ }
+
+ UpdateTownRadius(t);
+}
+
+void OnTick_Town(void)
+{
+ if (_game_mode == GM_EDITOR) return;
+
+ /* Make sure each town's tickhandler invocation frequency is about the
+ * same - TOWN_GROWTH_FREQUENCY - independent on the number of towns. */
+ for (_cur_town_iter += GetMaxTownIndex() + 1;
+ _cur_town_iter >= TOWN_GROWTH_FREQUENCY;
+ _cur_town_iter -= TOWN_GROWTH_FREQUENCY) {
+ uint32 i = _cur_town_ctr;
+
+ if (++_cur_town_ctr > GetMaxTownIndex())
+ _cur_town_ctr = 0;
+
+ if (IsValidTownID(i)) TownTickHandler(GetTown(i));
+ }
+}
+
+static RoadBits GetTownRoadMask(TileIndex tile)
+{
+ TrackBits b = GetAnyRoadTrackBits(tile);
+ RoadBits r = 0;
+
+ if (b & TRACK_BIT_X) r |= ROAD_X;
+ if (b & TRACK_BIT_Y) r |= ROAD_Y;
+ if (b & TRACK_BIT_UPPER) r |= ROAD_NE | ROAD_NW;
+ if (b & TRACK_BIT_LOWER) r |= ROAD_SE | ROAD_SW;
+ if (b & TRACK_BIT_LEFT) r |= ROAD_NW | ROAD_SW;
+ if (b & TRACK_BIT_RIGHT) r |= ROAD_NE | ROAD_SE;
+ return r;
+}
+
+static bool IsRoadAllowedHere(TileIndex tile, int dir)
+{
+ Slope k;
+ Slope slope;
+
+ // If this assertion fails, it might be because the world contains
+ // land at the edges. This is not ok.
+ TILE_ASSERT(tile);
+
+ for (;;) {
+ // Check if there already is a road at this point?
+ if (GetAnyRoadTrackBits(tile) == 0) {
+ // No, try to build one in the direction.
+ // if that fails clear the land, and if that fails exit.
+ // This is to make sure that we can build a road here later.
+ if (CmdFailed(DoCommand(tile, (dir & 1 ? ROAD_X : ROAD_Y), 0, DC_AUTO, CMD_BUILD_ROAD)) &&
+ CmdFailed(DoCommand(tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR)))
+ return false;
+ }
+
+ slope = GetTileSlope(tile, NULL);
+ if (slope == SLOPE_FLAT) {
+no_slope:
+ // Tile has no slope
+ // Disallow the road if any neighboring tile has a road.
+ if (HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir+1]))), dir^2) ||
+ HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir+3]))), dir^2) ||
+ HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir+1]) + ToTileIndexDiff(_roadblock_tileadd[dir+2]))), dir) ||
+ HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir+3]) + ToTileIndexDiff(_roadblock_tileadd[dir+2]))), dir))
+ return false;
+
+ // Otherwise allow
+ return true;
+ }
+
+ // If the tile is not a slope in the right direction, then
+ // maybe terraform some.
+ k = (dir & 1) ? SLOPE_NE : SLOPE_NW;
+ if (k != slope && ComplementSlope(k) != slope) {
+ uint32 r = Random();
+
+ if (CHANCE16I(1, 8, r) && !_generating_world) {
+ int32 res;
+
+ if (CHANCE16I(1, 16, r)) {
+ res = DoCommand(tile, slope, 0, DC_EXEC | DC_AUTO | DC_NO_WATER,
+ CMD_TERRAFORM_LAND);
+ } else {
+ res = DoCommand(tile, slope ^ 0xF, 1, DC_EXEC | DC_AUTO | DC_NO_WATER,
+ CMD_TERRAFORM_LAND);
+ }
+ if (CmdFailed(res) && CHANCE16I(1, 3, r)) {
+ // We can consider building on the slope, though.
+ goto no_slope;
+ }
+ }
+ return false;
+ }
+ return true;
+ }
+}
+
+static bool TerraformTownTile(TileIndex tile, int edges, int dir)
+{
+ int32 r;
+
+ TILE_ASSERT(tile);
+
+ r = DoCommand(tile, edges, dir, DC_AUTO | DC_NO_WATER, CMD_TERRAFORM_LAND);
+ if (CmdFailed(r) || r >= 126 * 16) return false;
+ DoCommand(tile, edges, dir, DC_AUTO | DC_NO_WATER | DC_EXEC, CMD_TERRAFORM_LAND);
+ return true;
+}
+
+static void LevelTownLand(TileIndex tile)
+{
+ Slope tileh;
+
+ TILE_ASSERT(tile);
+
+ // Don't terraform if land is plain or if there's a house there.
+ if (IsTileType(tile, MP_HOUSE)) return;
+ tileh = GetTileSlope(tile, NULL);
+ if (tileh == SLOPE_FLAT) return;
+
+ // First try up, then down
+ if (!TerraformTownTile(tile, ~tileh & 0xF, 1)) {
+ TerraformTownTile(tile, tileh & 0xF, 0);
+ }
+}
+
+static void GrowTownInTile(TileIndex* tile_ptr, RoadBits mask, int block, Town* t1)
+{
+ RoadBits rcmd;
+ TileIndex tmptile;
+ DiagDirection i;
+ int j;
+ TileIndex tile = *tile_ptr;
+
+ TILE_ASSERT(tile);
+
+ if (mask == 0) {
+ int a;
+ int b;
+
+ // Tile has no road. First reset the status counter
+ // to say that this is the last iteration.
+ _grow_town_result = 0;
+
+ // Remove hills etc
+ LevelTownLand(tile);
+
+ // Is a road allowed here?
+ if (!IsRoadAllowedHere(tile, block)) return;
+
+ // Randomize new road block numbers
+ a = block;
+ b = block ^ 2;
+ if (CHANCE16(1, 4)) {
+ do {
+ a = GB(Random(), 0, 2);
+ } while (a == b);
+ }
+
+ if (!IsRoadAllowedHere(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a])), a)) {
+ // A road is not allowed to continue the randomized road,
+ // return if the road we're trying to build is curved.
+ if (a != (b ^ 2)) return;
+
+ // Return if neither side of the new road is a house
+ if (!IsTileType(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a + 1])), MP_HOUSE) &&
+ !IsTileType(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a + 3])), MP_HOUSE))
+ return;
+
+ // That means that the road is only allowed if there is a house
+ // at any side of the new road.
+ }
+ rcmd = (1 << a) + (1 << b);
+
+ } else if (block < 5 && !HASBIT(mask,block^2)) {
+ // Continue building on a partial road.
+ // Always OK.
+ _grow_town_result = 0;
+ rcmd = 1 << (block ^ 2);
+ } else {
+ int i;
+
+ // Reached a tunnel/bridge? Then continue at the other side of it.
+ if (IsTileType(tile, MP_TUNNELBRIDGE)) {
+ if (IsTunnel(tile) && GetTunnelTransportType(tile) == TRANSPORT_ROAD) {
+ *tile_ptr = GetOtherTunnelEnd(tile);
+ } else if (IsBridge(tile) && GetBridgeTransportType(tile) == TRANSPORT_ROAD) {
+ *tile_ptr = GetOtherBridgeEnd(tile);
+ }
+ return;
+ }
+
+ // Possibly extend the road in a direction.
+ // Randomize a direction and if it has a road, bail out.
+ i = GB(Random(), 0, 2);
+ if (HASBIT(mask, i)) return;
+
+ // This is the tile we will reach if we extend to this direction.
+ tmptile = TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[i]));
+
+ // Don't do it if it reaches to water.
+ if (IsClearWaterTile(tmptile)) return;
+
+ // Build a house at the edge. 60% chance or
+ // always ok if no road allowed.
+ if (!IsRoadAllowedHere(tmptile, i) || CHANCE16(6, 10)) {
+ // But not if there already is a house there.
+ if (!IsTileType(tmptile, MP_HOUSE)) {
+ // Level the land if possible
+ LevelTownLand(tmptile);
+
+ // And build a house.
+ // Set result to -1 if we managed to build it.
+ if (BuildTownHouse(t1, tmptile)) _grow_town_result = -1;
+ }
+ return;
+ }
+
+ _grow_town_result = 0;
+ rcmd = 1 << i;
+ }
+
+ // Return if a water tile
+ if (IsClearWaterTile(tile)) return;
+
+ // Determine direction of slope,
+ // and build a road if not a special slope.
+ switch (GetTileSlope(tile, NULL)) {
+ case SLOPE_SW: i = DIAGDIR_NE; break;
+ case SLOPE_SE: i = DIAGDIR_NW; break;
+ case SLOPE_NW: i = DIAGDIR_SE; break;
+ case SLOPE_NE: i = DIAGDIR_SW; break;
+
+ default:
+build_road_and_exit:
+ if (!CmdFailed(DoCommand(tile, rcmd, t1->index, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD))) {
+ _grow_town_result = -1;
+ }
+ return;
+ }
+
+ tmptile = tile;
+
+ // Now it contains the direction of the slope
+ j = -11; // max 11 tile long bridges
+ do {
+ if (++j == 0)
+ goto build_road_and_exit;
+ tmptile = TILE_MASK(tmptile + TileOffsByDiagDir(i));
+ } while (IsClearWaterTile(tmptile));
+
+ // no water tiles in between?
+ if (j == -10)
+ goto build_road_and_exit;
+
+ // Quit if it selecting an appropiate bridge type fails a large number of times.
+ j = 22;
+ {
+ int32 bridge_len = GetBridgeLength(tile, tmptile);
+ do {
+ byte bridge_type = RandomRange(MAX_BRIDGES - 1);
+ if (CheckBridge_Stuff(bridge_type, bridge_len)) {
+ if (!CmdFailed(DoCommand(tile, tmptile, 0x8000 + bridge_type, DC_EXEC | DC_AUTO, CMD_BUILD_BRIDGE)))
+ _grow_town_result = -1;
+
+ // obviously, if building any bridge would fail, there is no need to try other bridge-types
+ return;
+ }
+ } while (--j != 0);
+ }
+}
+
+// Returns true if a house was built, or no if the build failed.
+static int GrowTownAtRoad(Town *t, TileIndex tile)
+{
+ int block = 5; // special case
+
+ TILE_ASSERT(tile);
+
+ // Number of times to search.
+ _grow_town_result = 10 + t->num_houses * 4 / 9;
+
+ do {
+ // Get a bitmask of the road blocks on a tile
+ RoadBits mask = GetTownRoadMask(tile);
+
+ // Try to grow the town from this point
+ GrowTownInTile(&tile,mask,block,t);
+
+ // Exclude the source position from the bitmask
+ // and return if no more road blocks available
+ CLRBIT(mask, (block ^ 2));
+ if (mask == 0)
+ return _grow_town_result;
+
+ // Select a random bit from the blockmask, walk a step
+ // and continue the search from there.
+ do block = Random() & 3; while (!HASBIT(mask,block));
+ tile += ToTileIndexDiff(_roadblock_tileadd[block]);
+
+ if (IsTileType(tile, MP_STREET)) {
+ /* Don't allow building over roads of other cities */
+ if (IsTileOwner(tile, OWNER_TOWN) && GetTownByTile(tile) != t) {
+ _grow_town_result = -1;
+ } else if (_game_mode == GM_EDITOR) {
+ /* If we are in the SE, and this road-piece has no town owner yet, it just found an
+ * owner :) (happy happy happy road now) */
+ SetTileOwner(tile, OWNER_TOWN);
+ SetTownIndex(tile, t->index);
+ }
+ }
+
+ // Max number of times is checked.
+ } while (--_grow_town_result >= 0);
+
+ return (_grow_town_result == -2);
+}
+
+// Generate a random road block
+// The probability of a straight road
+// is somewhat higher than a curved.
+static RoadBits GenRandomRoadBits(void)
+{
+ uint32 r = Random();
+ uint a = GB(r, 0, 2);
+ uint b = GB(r, 8, 2);
+ if (a == b) b ^= 2;
+ return (1 << a) + (1 << b);
+}
+
+// Grow the town
+// Returns true if a house was built, or no if the build failed.
+static bool GrowTown(Town *t)
+{
+ TileIndex tile;
+ const TileIndexDiffC *ptr;
+ PlayerID old_player;
+
+ static const TileIndexDiffC _town_coord_mod[] = {
+ {-1, 0},
+ { 1, 1},
+ { 1, -1},
+ {-1, -1},
+ {-1, 0},
+ { 0, 2},
+ { 2, 0},
+ { 0, -2},
+ {-1, -1},
+ {-2, 2},
+ { 2, 2},
+ { 2, -2},
+ { 0, 0}
+ };
+
+ // Current player is a town
+ old_player = _current_player;
+ _current_player = OWNER_TOWN;
+
+ // Find a road that we can base the construction on.
+ tile = t->xy;
+ for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) {
+ if (GetAnyRoadTrackBits(tile) != 0) {
+ int r = GrowTownAtRoad(t, tile);
+ _current_player = old_player;
+ return r;
+ }
+ tile = TILE_ADD(tile, ToTileIndexDiff(*ptr));
+ }
+
+ // No road available, try to build a random road block by
+ // clearing some land and then building a road there.
+ tile = t->xy;
+ for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) {
+ /* Only work with plain land that not already has a house */
+ if (!IsTileType(tile, MP_HOUSE) && GetTileSlope(tile, NULL) == SLOPE_FLAT) {
+ if (!CmdFailed(DoCommand(tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR))) {
+ DoCommand(tile, GenRandomRoadBits(), t->index, DC_EXEC | DC_AUTO, CMD_BUILD_ROAD);
+ _current_player = old_player;
+ return true;
+ }
+ }
+ tile = TILE_ADD(tile, ToTileIndexDiff(*ptr));
+ }
+
+ _current_player = old_player;
+ return false;
+}
+
+static void UpdateTownRadius(Town *t)
+{
+ static const uint16 _town_radius_data[23][5] = {
+ { 4, 0, 0, 0, 0}, // 0
+ { 16, 0, 0, 0, 0},
+ { 25, 0, 0, 0, 0},
+ { 36, 0, 0, 0, 0},
+ { 49, 0, 4, 0, 0},
+ { 64, 0, 4, 0, 0}, // 20
+ { 64, 0, 9, 0, 1},
+ { 64, 0, 9, 0, 4},
+ { 64, 0, 16, 0, 4},
+ { 81, 0, 16, 0, 4},
+ { 81, 0, 16, 0, 4}, // 40
+ { 81, 0, 25, 0, 9},
+ { 81, 36, 25, 0, 9},
+ { 81, 36, 25, 16, 9},
+ { 81, 49, 0, 25, 9},
+ { 81, 64, 0, 25, 9}, // 60
+ { 81, 64, 0, 36, 9},
+ { 81, 64, 0, 36, 16},
+ {100, 81, 0, 49, 16},
+ {100, 81, 0, 49, 25},
+ {121, 81, 0, 49, 25}, // 80
+ {121, 81, 0, 49, 25},
+ {121, 81, 0, 49, 36}, // 88
+ };
+
+ if (t->num_houses < 92) {
+ memcpy(t->radius, _town_radius_data[t->num_houses / 4], sizeof(t->radius));
+ } else {
+ int mass = t->num_houses / 8;
+ // At least very roughly extrapolate. Empirical numbers dancing between
+ // overwhelming by cottages and skyscrapers outskirts.
+ t->radius[0] = mass * mass;
+ // Actually we are proportional to sqrt() but that's right because
+ // we are covering an area.
+ t->radius[1] = mass * 7;
+ t->radius[2] = 0;
+ t->radius[3] = mass * 4;
+ t->radius[4] = mass * 3;
+ //debug("%d (->%d): %d %d %d %d\n", t->num_houses, mass, t->radius[0], t->radius[1], t->radius[3], t->radius[4]);
+ }
+}
+
+static bool CreateTownName(uint32 *townnameparts)
+{
+ Town *t2;
+ char buf1[64];
+ char buf2[64];
+ uint32 r;
+ /* Do not set too low tries, since when we run out of names, we loop
+ * for #tries only one time anyway - then we stop generating more
+ * towns. Do not show it too high neither, since looping through all
+ * the other towns may take considerable amount of time (10000 is
+ * too much). */
+ int tries = 1000;
+ uint16 townnametype = SPECSTR_TOWNNAME_START + _opt.town_name;
+
+ assert(townnameparts);
+
+ for (;;) {
+restart:
+ r = Random();
+
+ SetDParam(0, r);
+ GetString(buf1, townnametype, lastof(buf1));
+
+ // Check size and width
+ if (strlen(buf1) >= 31 || GetStringBoundingBox(buf1).width > 130) continue;
+
+ FOR_ALL_TOWNS(t2) {
+ // We can't just compare the numbers since
+ // several numbers may map to a single name.
+ SetDParam(0, t2->index);
+ GetString(buf2, STR_TOWN, lastof(buf2));
+ if (strcmp(buf1, buf2) == 0) {
+ if (tries-- < 0) return false;
+ goto restart;
+ }
+ }
+ *townnameparts = r;
+ return true;
+ }
+}
+
+void UpdateTownMaxPass(Town *t)
+{
+ t->max_pass = t->population >> 3;
+ t->max_mail = t->population >> 4;
+}
+
+static void DoCreateTown(Town *t, TileIndex tile, uint32 townnameparts, uint size_mode)
+{
+ int x, i;
+
+ // clear the town struct
+ i = t->index;
+ memset(t, 0, sizeof(Town));
+ t->index = i;
+ _total_towns++;
+
+ t->xy = tile;
+ t->num_houses = 0;
+ t->time_until_rebuild = 10;
+ UpdateTownRadius(t);
+ t->flags12 = 0;
+ t->population = 0;
+ t->grow_counter = 0;
+ t->growth_rate = 250;
+ t->new_max_pass = 0;
+ t->new_max_mail = 0;
+ t->new_act_pass = 0;
+ t->new_act_mail = 0;
+ t->max_pass = 0;
+ t->max_mail = 0;
+ t->act_pass = 0;
+ t->act_mail = 0;
+
+ t->pct_pass_transported = 0;
+ t->pct_mail_transported = 0;
+ t->fund_buildings_months = 0;
+ t->new_act_food = 0;
+ t->new_act_water = 0;
+ t->act_food = 0;
+ t->act_water = 0;
+
+ for (i = 0; i != MAX_PLAYERS; i++)
+ t->ratings[i] = 500;
+
+ t->have_ratings = 0;
+ t->exclusivity = (byte)-1;
+ t->exclusive_counter = 0;
+ t->statues = 0;
+
+ t->townnametype = SPECSTR_TOWNNAME_START + _opt.town_name;
+ t->townnameparts = townnameparts;
+
+ UpdateTownVirtCoord(t);
+ _town_sort_dirty = true;
+
+ if (size_mode == 0) {
+ x = (Random() & 0xF) + 8;
+ } else {
+ x = (size_mode - 1) * 16 + 3;
+ }
+
+ t->num_houses += x;
+ UpdateTownRadius(t);
+
+ i = x * 4;
+ do {
+ GrowTown(t);
+ } while (--i);
+
+ t->num_houses -= x;
+ UpdateTownRadius(t);
+ UpdateTownMaxPass(t);
+}
+
+static Town *AllocateTown(void)
+{
+ Town *t;
+
+ /* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
+ * TODO - This is just a temporary stage, this will be removed. */
+ for (t = GetTown(0); t != NULL; t = (t->index + 1U < GetTownPoolSize()) ? GetTown(t->index + 1U) : NULL) {
+ if (!IsValidTown(t)) {
+ TownID index = t->index;
+
+ memset(t, 0, sizeof(Town));
+ t->index = index;
+
+ return t;
+ }
+ }
+
+ /* Check if we can add a block to the pool */
+ if (AddBlockToPool(&_Town_pool))
+ return AllocateTown();
+
+ return NULL;
+}
+
+/** Create a new town.
+ * This obviously only works in the scenario editor. Function not removed
+ * as it might be possible in the future to fund your own town :)
+ * @param tile coordinates where town is built
+ * @param p1 size of the town (0 = random, 1 = small, 2 = medium, 3 = large)
+ * @param p2 unused
+ */
+int32 CmdBuildTown(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Town *t;
+ uint32 townnameparts;
+
+ /* Only in the scenario editor */
+ if (_game_mode != GM_EDITOR) return CMD_ERROR;
+
+ SET_EXPENSES_TYPE(EXPENSES_OTHER);
+
+ // Check if too close to the edge of map
+ if (DistanceFromEdge(tile) < 12)
+ return_cmd_error(STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP);
+
+ // Can only build on clear flat areas, possibly with trees.
+ if ((!IsTileType(tile, MP_CLEAR) && !IsTileType(tile, MP_TREES)) || GetTileSlope(tile, NULL) != SLOPE_FLAT) {
+ return_cmd_error(STR_0239_SITE_UNSUITABLE);
+ }
+
+ // Check distance to all other towns.
+ if (IsCloseToTown(tile, 20))
+ return_cmd_error(STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN);
+
+ // Get a unique name for the town.
+ if (!CreateTownName(&townnameparts))
+ return_cmd_error(STR_023A_TOO_MANY_TOWNS);
+
+ // Allocate town struct
+ t = AllocateTown();
+ if (t == NULL) return_cmd_error(STR_023A_TOO_MANY_TOWNS);
+
+ // Create the town
+ if (flags & DC_EXEC) {
+ _generating_world = true;
+ DoCreateTown(t, tile, townnameparts, p1);
+ _generating_world = false;
+ }
+ return 0;
+}
+
+Town *CreateRandomTown(uint attempts, uint size_mode)
+{
+ TileIndex tile;
+ Town *t;
+ uint32 townnameparts;
+
+ do {
+ // Generate a tile index not too close from the edge
+ tile = RandomTile();
+ if (DistanceFromEdge(tile) < 20) continue;
+
+ // Make sure the tile is plain
+ if (!IsTileType(tile, MP_CLEAR) || GetTileSlope(tile, NULL) != SLOPE_FLAT) continue;
+
+ // Check not too close to a town
+ if (IsCloseToTown(tile, 20)) continue;
+
+ // Get a unique name for the town.
+ if (!CreateTownName(&townnameparts)) break;
+
+ // Allocate a town struct
+ t = AllocateTown();
+ if (t == NULL) break;
+
+ DoCreateTown(t, tile, townnameparts, size_mode);
+ return t;
+ } while (--attempts);
+ return NULL;
+}
+
+static const byte _num_initial_towns[3] = {11, 23, 46};
+
+bool GenerateTowns(void)
+{
+ uint num = 0;
+ uint n = ScaleByMapSize(_num_initial_towns[_opt.diff.number_towns] + (Random() & 7));
+
+ SetGeneratingWorldProgress(GWP_TOWN, n);
+
+ do {
+ IncreaseGeneratingWorldProgress(GWP_TOWN);
+ // try 20 times to create a random-sized town for the first loop.
+ if (CreateRandomTown(20, 0) != NULL) num++;
+ } while (--n);
+
+ // give it a last try, but now more aggressive
+ if (num == 0 && CreateRandomTown(10000, 0) == NULL) {
+ if (GetNumTowns() == 0) {
+ /* XXX - can we handle that more gracefully? */
+ if (_game_mode != GM_EDITOR) error("Could not generate any town");
+
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static bool CheckBuildHouseMode(TileIndex tile, Slope tileh, int mode)
+{
+ int b;
+ Slope slope;
+
+ static const byte _masks[8] = {
+ 0xC,0x3,0x9,0x6,
+ 0x3,0xC,0x6,0x9,
+ };
+
+ slope = GetTileSlope(tile, NULL);
+ if (IsSteepSlope(slope)) return false;
+
+ if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return false;
+
+ b = 0;
+ if ((slope != SLOPE_FLAT && ~slope & _masks[mode])) b = ~b;
+ if ((tileh != SLOPE_FLAT && ~tileh & _masks[mode+4])) b = ~b;
+ if (b)
+ return false;
+
+ return !CmdFailed(DoCommand(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR));
+}
+
+
+uint GetTownRadiusGroup(const Town* t, TileIndex tile)
+{
+ uint dist = DistanceSquare(tile, t->xy);
+ uint smallest;
+ uint i;
+
+ if (t->fund_buildings_months && dist <= 25) return 4;
+
+ smallest = 0;
+ for (i = 0; i != lengthof(t->radius); i++) {
+ if (dist < t->radius[i]) smallest = i;
+ }
+
+ return smallest;
+}
+
+static bool CheckFree2x2Area(TileIndex tile)
+{
+ int i;
+
+ static const TileIndexDiffC _tile_add[] = {
+ {0 , 0 },
+ {0 - 0, 1 - 0},
+ {1 - 0, 0 - 1},
+ {1 - 1, 1 - 0}
+ };
+
+ for (i = 0; i != 4; i++) {
+ tile += ToTileIndexDiff(_tile_add[i]);
+
+ if (GetTileSlope(tile, NULL) != SLOPE_FLAT) return false;
+
+ if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return false;
+
+ if (CmdFailed(DoCommand(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER | DC_FORCETEST, CMD_LANDSCAPE_CLEAR)))
+ return false;
+ }
+
+ return true;
+}
+
+static void DoBuildTownHouse(Town *t, TileIndex tile)
+{
+ int i;
+ uint bitmask;
+ int house;
+ Slope slope;
+ uint z;
+ uint oneof = 0;
+
+ // Above snow?
+ slope = GetTileSlope(tile, &z);
+
+ // Get the town zone type
+ {
+ uint rad = GetTownRadiusGroup(t, tile);
+
+ int land = _opt.landscape;
+ if (land == LT_HILLY && z >= _opt.snow_line) land = -1;
+
+ bitmask = (1 << rad) + (1 << (land + 12));
+ }
+
+ // bits 0-4 are used
+ // bits 11-15 are used
+ // bits 5-10 are not used.
+ {
+ byte houses[lengthof(_housetype_flags)];
+ int num = 0;
+
+ // Generate a list of all possible houses that can be built.
+ for (i=0; i!=lengthof(_housetype_flags); i++) {
+ if ((~_housetype_flags[i] & bitmask) == 0)
+ houses[num++] = (byte)i;
+ }
+
+ for (;;) {
+ house = houses[RandomRange(num)];
+
+ if (_cur_year < _housetype_years[house].min || _cur_year > _housetype_years[house].max)
+ continue;
+
+ // Special houses that there can be only one of.
+ switch (house) {
+ case HOUSE_TEMP_CHURCH:
+ case HOUSE_ARCT_CHURCH:
+ case HOUSE_SNOW_CHURCH:
+ case HOUSE_TROP_CHURCH:
+ case HOUSE_TOY_CHURCH:
+ SETBIT(oneof, TOWN_HAS_CHURCH);
+ break;
+ case HOUSE_STADIUM:
+ case HOUSE_MODERN_STADIUM:
+ SETBIT(oneof, TOWN_HAS_STADIUM);
+ break;
+ default:
+ oneof = 0;
+ break;
+ }
+
+ if (HASBITS(t->flags12 , oneof)) continue;
+
+ // Make sure there is no slope?
+ if (_housetype_extra_flags[house] & 0x12 && slope != SLOPE_FLAT) continue;
+
+ if (_housetype_extra_flags[house] & 0x10) {
+ if (CheckFree2x2Area(tile) ||
+ CheckFree2x2Area(tile += TileDiffXY(-1, 0)) ||
+ CheckFree2x2Area(tile += TileDiffXY( 0, -1)) ||
+ CheckFree2x2Area(tile += TileDiffXY( 1, 0))) {
+ break;
+ }
+ tile += TileDiffXY(0, 1);
+ } else if (_housetype_extra_flags[house] & 4) {
+ if (CheckBuildHouseMode(tile + TileDiffXY(1, 0), slope, 0)) break;
+
+ if (CheckBuildHouseMode(tile + TileDiffXY(-1, 0), slope, 1)) {
+ tile += TileDiffXY(-1, 0);
+ break;
+ }
+ } else if (_housetype_extra_flags[house] & 8) {
+ if (CheckBuildHouseMode(tile + TileDiffXY(0, 1), slope, 2)) break;
+
+ if (CheckBuildHouseMode(tile + TileDiffXY(0, -1), slope, 3)) {
+ tile += TileDiffXY(0, -1);
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ }
+
+ t->num_houses++;
+
+ // Special houses that there can be only one of.
+ t->flags12 |= oneof;
+
+ {
+ byte construction_counter = 0, construction_stage = 0, size_flags;
+
+ if (_generating_world) {
+ uint32 r = Random();
+
+ construction_stage = TOWN_HOUSE_COMPLETED;
+ if (CHANCE16(1, 7)) construction_stage = GB(r, 0, 2);
+
+ if (construction_stage == TOWN_HOUSE_COMPLETED) {
+ ChangePopulation(t, _housetype_population[house]);
+ } else {
+ construction_counter = GB(r, 2, 2);
+ }
+ }
+ size_flags = GB(_housetype_extra_flags[house], 2, 3);
+ MakeTownHouse(tile, t->index, construction_counter, construction_stage, size_flags, house);
+ }
+}
+
+static bool BuildTownHouse(Town *t, TileIndex tile)
+{
+ int32 r;
+
+ // make sure it's possible
+ if (!EnsureNoVehicle(tile)) return false;
+ if (IsSteepSlope(GetTileSlope(tile, NULL))) return false;
+ if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return false;
+
+ r = DoCommand(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR);
+ if (CmdFailed(r)) return false;
+
+ DoBuildTownHouse(t, tile);
+ return true;
+}
+
+
+static void DoClearTownHouseHelper(TileIndex tile)
+{
+ assert(IsTileType(tile, MP_HOUSE));
+ DoClearSquare(tile);
+ DeleteAnimatedTile(tile);
+}
+
+static void ClearTownHouse(Town *t, TileIndex tile)
+{
+ uint house = GetHouseType(tile);
+ uint eflags;
+
+ assert(IsTileType(tile, MP_HOUSE));
+
+ // need to align the tile to point to the upper left corner of the house
+ if (house >= 3) { // house id 0,1,2 MUST be single tile houses, or this code breaks.
+ if (_housetype_extra_flags[house-1] & 0x04) {
+ house--;
+ tile += TileDiffXY(-1, 0);
+ } else if (_housetype_extra_flags[house-1] & 0x18) {
+ house--;
+ tile += TileDiffXY(0, -1);
+ } else if (_housetype_extra_flags[house-2] & 0x10) {
+ house-=2;
+ tile += TileDiffXY(-1, 0);
+ } else if (_housetype_extra_flags[house-3] & 0x10) {
+ house-=3;
+ tile += TileDiffXY(-1, -1);
+ }
+ }
+
+ // Remove population from the town if the house is finished.
+ if (GetHouseBuildingStage(tile) == TOWN_HOUSE_COMPLETED) {
+ ChangePopulation(t, -_housetype_population[house]);
+ }
+
+ t->num_houses--;
+
+ // Clear flags for houses that only may exist once/town.
+ switch (house) {
+ case HOUSE_TEMP_CHURCH:
+ case HOUSE_ARCT_CHURCH:
+ case HOUSE_SNOW_CHURCH:
+ case HOUSE_TROP_CHURCH:
+ case HOUSE_TOY_CHURCH:
+ CLRBIT(t->flags12, TOWN_HAS_CHURCH);
+ break;
+ case HOUSE_STADIUM:
+ case HOUSE_MODERN_STADIUM:
+ CLRBIT(t->flags12, TOWN_HAS_STADIUM);
+ break;
+ default:
+ break;
+ }
+
+ // Do the actual clearing of tiles
+ eflags = _housetype_extra_flags[house];
+ DoClearTownHouseHelper(tile);
+ if (eflags & 0x14) DoClearTownHouseHelper(tile + TileDiffXY(1, 0));
+ if (eflags & 0x18) DoClearTownHouseHelper(tile + TileDiffXY(0, 1));
+ if (eflags & 0x10) DoClearTownHouseHelper(tile + TileDiffXY(1, 1));
+}
+
+/** Rename a town (server-only).
+ * @param tile unused
+ * @param p1 town ID to rename
+ * @param p2 unused
+ */
+int32 CmdRenameTown(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ StringID str;
+ Town *t;
+
+ if (!IsValidTownID(p1) || _cmd_text[0] == '\0') return CMD_ERROR;
+
+ t = GetTown(p1);
+
+ str = AllocateNameUnique(_cmd_text, 4);
+ if (str == 0) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ DeleteName(t->townnametype);
+ t->townnametype = str;
+
+ UpdateTownVirtCoord(t);
+ _town_sort_dirty = true;
+ UpdateAllStationVirtCoord();
+ MarkWholeScreenDirty();
+ } else {
+ DeleteName(str);
+ }
+ return 0;
+}
+
+// Called from GUI
+void ExpandTown(Town *t)
+{
+ int amount, n;
+
+ _generating_world = true;
+
+ /* The more houses, the faster we grow */
+ amount = RandomRange(t->num_houses / 10) + 3;
+ t->num_houses += amount;
+ UpdateTownRadius(t);
+
+ n = amount * 10;
+ do GrowTown(t); while (--n);
+
+ t->num_houses -= amount;
+ UpdateTownRadius(t);
+
+ UpdateTownMaxPass(t);
+ _generating_world = false;
+}
+
+const byte _town_action_costs[8] = {
+ 2, 4, 9, 35, 48, 53, 117, 175
+};
+
+static void TownActionAdvertiseSmall(Town* t)
+{
+ ModifyStationRatingAround(t->xy, _current_player, 0x40, 10);
+}
+
+static void TownActionAdvertiseMedium(Town* t)
+{
+ ModifyStationRatingAround(t->xy, _current_player, 0x70, 15);
+}
+
+static void TownActionAdvertiseLarge(Town* t)
+{
+ ModifyStationRatingAround(t->xy, _current_player, 0xA0, 20);
+}
+
+static void TownActionRoadRebuild(Town* t)
+{
+ const Player* p;
+
+ t->road_build_months = 6;
+
+ SetDParam(0, t->index);
+
+ p = GetPlayer(_current_player);
+ SetDParam(1, p->name_1);
+ SetDParam(2, p->name_2);
+
+ AddNewsItem(STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING,
+ NEWS_FLAGS(NM_NORMAL, NF_TILE, NT_GENERAL, 0), t->xy, 0);
+}
+
+static bool DoBuildStatueOfCompany(TileIndex tile)
+{
+ PlayerID old;
+ int32 r;
+
+ if (GetTileSlope(tile, NULL) != SLOPE_FLAT) return false;
+
+ if (!IsTileType(tile, MP_HOUSE) &&
+ !IsTileType(tile, MP_CLEAR) &&
+ !IsTileType(tile, MP_TREES)) {
+ return false;
+ }
+
+ old = _current_player;
+ _current_player = OWNER_NONE;
+ r = DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
+ _current_player = old;
+
+ if (CmdFailed(r)) return false;
+
+ MakeStatue(tile, _current_player);
+ MarkTileDirtyByTile(tile);
+
+ return true;
+}
+
+/**
+ * Search callback function for TownActionBuildStatue
+ * @param data that is passed by the caller. In this case, nothing
+ * @result of the test
+ */
+static bool SearchTileForStatue(TileIndex tile, uint32 data)
+{
+ return DoBuildStatueOfCompany(tile);
+}
+
+/**
+ * Perform a 9x9 tiles circular search from the center of the town
+ * in order to find a free tile to place a statue
+ * @param t town to search in
+ */
+static void TownActionBuildStatue(Town* t)
+{
+ TileIndex tile = t->xy;
+
+ if (CircularTileSearch(tile, 9, SearchTileForStatue, 0))
+ SETBIT(t->statues, _current_player); ///< Once found and built, "inform" the Town
+}
+
+static void TownActionFundBuildings(Town* t)
+{
+ // Build next tick
+ t->grow_counter = 1;
+ // If we were not already growing
+ SETBIT(t->flags12, TOWN_IS_FUNDED);
+ // And grow for 3 months
+ t->fund_buildings_months = 3;
+}
+
+static void TownActionBuyRights(Town* t)
+{
+ t->exclusive_counter = 12;
+ t->exclusivity = _current_player;
+
+ ModifyStationRatingAround(t->xy, _current_player, 130, 17);
+}
+
+static void TownActionBribe(Town* t)
+{
+ if (!RandomRange(15)) {
+ Station *st;
+
+ // set as unwanted for 6 months
+ t->unwanted[_current_player] = 6;
+
+ // set all close by station ratings to 0
+ FOR_ALL_STATIONS(st) {
+ if (st->town == t && st->owner == _current_player) {
+ uint i;
+
+ for (i = 0; i != NUM_CARGO; i++) st->goods[i].rating = 0;
+ }
+ }
+
+ // only show errormessage to the executing player. All errors are handled command.c
+ // but this is special, because it can only 'fail' on a DC_EXEC
+ if (IsLocalPlayer()) ShowErrorMessage(STR_BRIBE_FAILED_2, STR_BRIBE_FAILED, 0, 0);
+
+ /* decrease by a lot!
+ * ChangeTownRating is only for stuff in demolishing. Bribe failure should
+ * be independent of any cheat settings
+ */
+ if (t->ratings[_current_player] > RATING_BRIBE_DOWN_TO) {
+ t->ratings[_current_player] = RATING_BRIBE_DOWN_TO;
+ }
+ } else {
+ ChangeTownRating(t, RATING_BRIBE_UP_STEP, RATING_BRIBE_MAXIMUM);
+ }
+}
+
+typedef void TownActionProc(Town* t);
+static TownActionProc * const _town_action_proc[] = {
+ TownActionAdvertiseSmall,
+ TownActionAdvertiseMedium,
+ TownActionAdvertiseLarge,
+ TownActionRoadRebuild,
+ TownActionBuildStatue,
+ TownActionFundBuildings,
+ TownActionBuyRights,
+ TownActionBribe
+};
+
+extern uint GetMaskOfTownActions(int *nump, PlayerID pid, const Town *t);
+
+/** Do a town action.
+ * This performs an action such as advertising, building a statue, funding buildings,
+ * but also bribing the town-council
+ * @param tile unused
+ * @param p1 town to do the action at
+ * @param p2 action to perform, @see _town_action_proc for the list of available actions
+ */
+int32 CmdDoTownAction(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ int32 cost;
+ Town *t;
+
+ if (!IsValidTownID(p1) || p2 > lengthof(_town_action_proc)) return CMD_ERROR;
+
+ t = GetTown(p1);
+
+ if (!HASBIT(GetMaskOfTownActions(NULL, _current_player, t), p2)) return CMD_ERROR;
+
+ SET_EXPENSES_TYPE(EXPENSES_OTHER);
+
+ cost = (_price.build_industry >> 8) * _town_action_costs[p2];
+
+ if (flags & DC_EXEC) {
+ _town_action_proc[p2](t);
+ InvalidateWindow(WC_TOWN_AUTHORITY, p1);
+ }
+
+ return cost;
+}
+
+static void UpdateTownGrowRate(Town *t)
+{
+ int n;
+ Station *st;
+ byte m;
+ Player *p;
+
+ // Reset player ratings if they're low
+ FOR_ALL_PLAYERS(p) {
+ if (p->is_active && t->ratings[p->index] <= 200) {
+ t->ratings[p->index] += 5;
+ }
+ }
+
+ n = 0;
+ FOR_ALL_STATIONS(st) {
+ if (DistanceSquare(st->xy, t->xy) <= t->radius[0]) {
+ if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
+ n++;
+ if (IsValidPlayer(st->owner) && t->ratings[st->owner] <= 1000-12)
+ t->ratings[st->owner] += 12;
+ } else {
+ if (IsValidPlayer(st->owner) && t->ratings[st->owner] >= -1000+15)
+ t->ratings[st->owner] -= 15;
+ }
+ }
+ }
+
+ CLRBIT(t->flags12, TOWN_IS_FUNDED);
+
+ if (t->fund_buildings_months != 0) {
+ static const byte _grow_count_values[6] = {
+ 60, 60, 60, 50, 40, 30
+ };
+ m = _grow_count_values[min(n, 5)];
+ t->fund_buildings_months--;
+ } else if (n == 0) {
+ m = 160;
+ if (!CHANCE16(1, 12))
+ return;
+ } else {
+ static const byte _grow_count_values[5] = {
+ 210, 150, 110, 80, 50
+ };
+ m = _grow_count_values[min(n, 5) - 1];
+ }
+
+ if (_opt.landscape == LT_HILLY) {
+ if (TilePixelHeight(t->xy) >= _opt.snow_line && t->act_food == 0 && t->population > 90)
+ return;
+ } else if (_opt.landscape == LT_DESERT) {
+ if (GetTropicZone(t->xy) == TROPICZONE_DESERT && (t->act_food==0 || t->act_water==0) && t->population > 60)
+ return;
+ }
+
+ t->growth_rate = m / (t->num_houses / 50 + 1);
+ if (m <= t->grow_counter)
+ t->grow_counter = m;
+
+ SETBIT(t->flags12, TOWN_IS_FUNDED);
+}
+
+static void UpdateTownAmounts(Town *t)
+{
+ // Using +1 here to prevent overflow and division by zero
+ t->pct_pass_transported = t->new_act_pass * 256 / (t->new_max_pass + 1);
+
+ t->max_pass = t->new_max_pass; t->new_max_pass = 0;
+ t->act_pass = t->new_act_pass; t->new_act_pass = 0;
+ t->act_food = t->new_act_food; t->new_act_food = 0;
+ t->act_water = t->new_act_water; t->new_act_water = 0;
+
+ // Using +1 here to prevent overflow and division by zero
+ t->pct_mail_transported = t->new_act_mail * 256 / (t->new_max_mail + 1);
+ t->max_mail = t->new_max_mail; t->new_max_mail = 0;
+ t->act_mail = t->new_act_mail; t->new_act_mail = 0;
+
+ InvalidateWindow(WC_TOWN_VIEW, t->index);
+}
+
+static void UpdateTownUnwanted(Town *t)
+{
+ const Player* p;
+
+ FOR_ALL_PLAYERS(p) {
+ if (t->unwanted[p->index] > 0) t->unwanted[p->index]--;
+ }
+}
+
+bool CheckIfAuthorityAllows(TileIndex tile)
+{
+ Town *t;
+
+ if (!IsValidPlayer(_current_player)) return true;
+
+ t = ClosestTownFromTile(tile, _patches.dist_local_authority);
+ if (t == NULL) return true;
+
+ if (t->ratings[_current_player] > -200) return true;
+
+ _error_message = STR_2009_LOCAL_AUTHORITY_REFUSES;
+ SetDParam(0, t->index);
+
+ return false;
+}
+
+
+Town* CalcClosestTownFromTile(TileIndex tile, uint threshold)
+{
+ Town *t;
+ uint dist, best = threshold;
+ Town *best_town = NULL;
+
+ FOR_ALL_TOWNS(t) {
+ dist = DistanceManhattan(tile, t->xy);
+ if (dist < best) {
+ best = dist;
+ best_town = t;
+ }
+ }
+
+ return best_town;
+}
+
+
+Town *ClosestTownFromTile(TileIndex tile, uint threshold)
+{
+ if (IsTileType(tile, MP_HOUSE) || (
+ IsTileType(tile, MP_STREET) &&
+ (IsLevelCrossing(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile)) == OWNER_TOWN
+ )) {
+ return GetTownByTile(tile);
+ } else {
+ return CalcClosestTownFromTile(tile, threshold);
+ }
+}
+
+
+void ChangeTownRating(Town *t, int add, int max)
+{
+ int rating;
+
+ // if magic_bulldozer cheat is active, town doesn't penaltize for removing stuff
+ if (t == NULL ||
+ !IsValidPlayer(_current_player) ||
+ (_cheats.magic_bulldozer.value && add < 0)) {
+ return;
+ }
+
+ SETBIT(t->have_ratings, _current_player);
+
+ rating = t->ratings[_current_player];
+
+ if (add < 0) {
+ if (rating > max) {
+ rating += add;
+ if (rating < max) rating = max;
+ }
+ } else {
+ if (rating < max) {
+ rating += add;
+ if (rating > max) rating = max;
+ }
+ }
+ t->ratings[_current_player] = rating;
+}
+
+/* penalty for removing town-owned stuff */
+static const int _default_rating_settings [3][3] = {
+ // ROAD_REMOVE, TUNNELBRIDGE_REMOVE, INDUSTRY_REMOVE
+ { 0, 128, 384}, // Permissive
+ { 48, 192, 480}, // Neutral
+ { 96, 384, 768}, // Hostile
+};
+
+bool CheckforTownRating(uint32 flags, Town *t, byte type)
+{
+ int modemod;
+
+ // if magic_bulldozer cheat is active, town doesn't restrict your destructive actions
+ if (t == NULL || !IsValidPlayer(_current_player) || _cheats.magic_bulldozer.value)
+ return true;
+
+ /* check if you're allowed to remove the street/bridge/tunnel/industry
+ * owned by a town no removal if rating is lower than ... depends now on
+ * difficulty setting. Minimum town rating selected by difficulty level
+ */
+ modemod = _default_rating_settings[_opt.diff.town_council_tolerance][type];
+
+ if (t->ratings[_current_player] < 16 + modemod && !(flags & DC_NO_TOWN_RATING)) {
+ SetDParam(0, t->index);
+ _error_message = STR_2009_LOCAL_AUTHORITY_REFUSES;
+ return false;
+ }
+
+ return true;
+}
+
+void TownsMonthlyLoop(void)
+{
+ Town *t;
+
+ FOR_ALL_TOWNS(t) {
+ if (t->road_build_months != 0) t->road_build_months--;
+
+ if (t->exclusive_counter != 0)
+ if (--t->exclusive_counter == 0) t->exclusivity = (byte)-1;
+
+ UpdateTownGrowRate(t);
+ UpdateTownAmounts(t);
+ UpdateTownUnwanted(t);
+ }
+}
+
+void InitializeTowns(void)
+{
+ Subsidy *s;
+
+ /* Clean the town pool and create 1 block in it */
+ CleanPool(&_Town_pool);
+ AddBlockToPool(&_Town_pool);
+
+ memset(_subsidies, 0, sizeof(_subsidies));
+ for (s=_subsidies; s != endof(_subsidies); s++)
+ s->cargo_type = CT_INVALID;
+
+ _cur_town_ctr = 0;
+ _cur_town_iter = 0;
+ _total_towns = 0;
+ _town_sort_dirty = true;
+}
+
+const TileTypeProcs _tile_type_town_procs = {
+ DrawTile_Town, /* draw_tile_proc */
+ GetSlopeZ_Town, /* get_slope_z_proc */
+ ClearTile_Town, /* clear_tile_proc */
+ GetAcceptedCargo_Town, /* get_accepted_cargo_proc */
+ GetTileDesc_Town, /* get_tile_desc_proc */
+ GetTileTrackStatus_Town, /* get_tile_track_status_proc */
+ ClickTile_Town, /* click_tile_proc */
+ AnimateTile_Town, /* animate_tile_proc */
+ TileLoop_Town, /* tile_loop_clear */
+ ChangeTileOwner_Town, /* change_tile_owner_clear */
+ NULL, /* get_produced_cargo_proc */
+ NULL, /* vehicle_enter_tile_proc */
+ GetSlopeTileh_Town, /* get_slope_tileh_proc */
+};
+
+
+// Save and load of towns.
+static const SaveLoad _town_desc[] = {
+ SLE_CONDVAR(Town, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+ SLE_CONDVAR(Town, xy, SLE_UINT32, 6, SL_MAX_VERSION),
+
+ SLE_CONDVAR(Town, population, SLE_FILE_U16 | SLE_VAR_U32, 0, 2),
+ SLE_CONDVAR(Town, population, SLE_UINT32, 3, SL_MAX_VERSION),
+
+
+ SLE_VAR(Town, num_houses, SLE_UINT16),
+ SLE_VAR(Town, townnametype, SLE_UINT16),
+ SLE_VAR(Town, townnameparts, SLE_UINT32),
+
+ SLE_VAR(Town, flags12, SLE_UINT8),
+ SLE_VAR(Town, statues, SLE_UINT8),
+
+ // sort_index_obsolete was stored here in savegame format 0 - 1
+ SLE_CONDNULL(1, 0, 1),
+
+ SLE_VAR(Town, have_ratings, SLE_UINT8),
+ SLE_ARR(Town, ratings, SLE_INT16, 8),
+ // failed bribe attempts are stored since savegame format 4
+ SLE_CONDARR(Town, unwanted, SLE_INT8, 8, 4,SL_MAX_VERSION),
+
+ SLE_CONDVAR(Town, max_pass, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
+ SLE_CONDVAR(Town, max_mail, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
+ SLE_CONDVAR(Town, new_max_pass, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
+ SLE_CONDVAR(Town, new_max_mail, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
+ SLE_CONDVAR(Town, act_pass, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
+ SLE_CONDVAR(Town, act_mail, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
+ SLE_CONDVAR(Town, new_act_pass, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
+ SLE_CONDVAR(Town, new_act_mail, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
+
+ SLE_CONDVAR(Town, max_pass, SLE_UINT32, 9, SL_MAX_VERSION),
+ SLE_CONDVAR(Town, max_mail, SLE_UINT32, 9, SL_MAX_VERSION),
+ SLE_CONDVAR(Town, new_max_pass, SLE_UINT32, 9, SL_MAX_VERSION),
+ SLE_CONDVAR(Town, new_max_mail, SLE_UINT32, 9, SL_MAX_VERSION),
+ SLE_CONDVAR(Town, act_pass, SLE_UINT32, 9, SL_MAX_VERSION),
+ SLE_CONDVAR(Town, act_mail, SLE_UINT32, 9, SL_MAX_VERSION),
+ SLE_CONDVAR(Town, new_act_pass, SLE_UINT32, 9, SL_MAX_VERSION),
+ SLE_CONDVAR(Town, new_act_mail, SLE_UINT32, 9, SL_MAX_VERSION),
+
+ SLE_VAR(Town, pct_pass_transported, SLE_UINT8),
+ SLE_VAR(Town, pct_mail_transported, SLE_UINT8),
+
+ SLE_VAR(Town, act_food, SLE_UINT16),
+ SLE_VAR(Town, act_water, SLE_UINT16),
+ SLE_VAR(Town, new_act_food, SLE_UINT16),
+ SLE_VAR(Town, new_act_water, SLE_UINT16),
+
+ SLE_VAR(Town, time_until_rebuild, SLE_UINT8),
+ SLE_VAR(Town, grow_counter, SLE_UINT8),
+ SLE_VAR(Town, growth_rate, SLE_UINT8),
+ SLE_VAR(Town, fund_buildings_months, SLE_UINT8),
+ SLE_VAR(Town, road_build_months, SLE_UINT8),
+
+ SLE_VAR(Town, exclusivity, SLE_UINT8),
+ SLE_VAR(Town, exclusive_counter, SLE_UINT8),
+ // reserve extra space in savegame here. (currently 30 bytes)
+ SLE_CONDNULL(30, 2, SL_MAX_VERSION),
+
+ SLE_END()
+};
+
+static void Save_TOWN(void)
+{
+ Town *t;
+
+ FOR_ALL_TOWNS(t) {
+ SlSetArrayIndex(t->index);
+ SlObject(t, _town_desc);
+ }
+}
+
+static void Load_TOWN(void)
+{
+ int index;
+
+ _total_towns = 0;
+
+ while ((index = SlIterateArray()) != -1) {
+ Town *t;
+
+ if (!AddBlockIfNeeded(&_Town_pool, index))
+ error("Towns: failed loading savegame: too many towns");
+
+ t = GetTown(index);
+ SlObject(t, _town_desc);
+
+ _total_towns++;
+ }
+
+ /* This is to ensure all pointers are within the limits of
+ * the size of the TownPool */
+ if (_cur_town_ctr > GetMaxTownIndex())
+ _cur_town_ctr = 0;
+}
+
+void AfterLoadTown(void)
+{
+ Town *t;
+ FOR_ALL_TOWNS(t) {
+ UpdateTownRadius(t);
+ UpdateTownVirtCoord(t);
+ }
+ _town_sort_dirty = true;
+}
+
+
+const ChunkHandler _town_chunk_handlers[] = {
+ { 'CITY', Save_TOWN, Load_TOWN, CH_ARRAY | CH_LAST},
+};
diff --git a/src/town_gui.c b/src/town_gui.c
new file mode 100644
index 000000000..f580cd324
--- /dev/null
+++ b/src/town_gui.c
@@ -0,0 +1,524 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "debug.h"
+#include "functions.h"
+#include "strings.h"
+#include "table/sprites.h"
+#include "table/strings.h"
+#include "town.h"
+#include "window.h"
+#include "gfx.h"
+#include "viewport.h"
+#include "gui.h"
+#include "command.h"
+#include "player.h"
+#include "network/network.h"
+#include "variables.h"
+
+static const Widget _town_authority_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 13, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 13, 11, 316, 0, 13, STR_2022_LOCAL_AUTHORITY, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PANEL, RESIZE_NONE, 13, 0, 316, 14, 105, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 13, 0, 304, 106, 157, 0x0, STR_2043_LIST_OF_THINGS_TO_DO_AT},
+{ WWT_SCROLLBAR, RESIZE_NONE, 13, 305, 316, 106, 157, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WWT_PANEL, RESIZE_NONE, 13, 0, 316, 158, 209, 0x0, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 13, 0, 316, 210, 221, STR_2042_DO_IT, STR_2044_CARRY_OUT_THE_HIGHLIGHTED},
+{ WIDGETS_END},
+};
+
+extern const byte _town_action_costs[8];
+extern void DrawPlayerIcon(PlayerID pid, int x, int y);
+
+/** Get a list of available actions to do at a town.
+ * @param *nump if not NULL add put the number of available actions in it
+ * @param pid the player that is querying the town
+ * @param *t the town that is queried
+ * @return bitmasked value of enabled actions
+ */
+uint GetMaskOfTownActions(int *nump, PlayerID pid, const Town *t)
+{
+ int32 avail, ref;
+ int num = 0;
+ uint avail_buttons = 0x7F; // by default all buttons except bribe are enabled.
+ uint buttons = 0;
+
+ if (pid != PLAYER_SPECTATOR) {
+ uint i;
+
+ // bribe option enabled?
+ if (_patches.bribe) {
+ // if unwanted, disable everything.
+ if (t->unwanted[pid]) {
+ avail_buttons = 0;
+ } else if (t->ratings[pid] < RATING_BRIBE_MAXIMUM) {
+ SETBIT(avail_buttons, 7); // Allow bribing
+ }
+ }
+
+ // Things worth more than this are not shown
+ avail = GetPlayer(pid)->player_money + _price.station_value * 200;
+ ref = _price.build_industry >> 8;
+
+ for (i = 0; i != lengthof(_town_action_costs); i++, avail_buttons >>= 1) {
+ if (HASBIT(avail_buttons, 0) && avail >= _town_action_costs[i] * ref) {
+ SETBIT(buttons, i);
+ num++;
+ }
+ }
+
+ /* Disable build statue if already built */
+ if (HASBIT(t->statues, pid)) {
+ CLRBIT(buttons, 4);
+ num--;
+ }
+
+ }
+
+ if (nump != NULL) *nump = num;
+ return buttons;
+}
+
+static int GetNthSetBit(uint32 bits, int n)
+{
+ int i = 0;
+
+ if (n >= 0) {
+ do {
+ if (bits & 1 && --n < 0) return i;
+ i++;
+ } while (bits >>= 1);
+ }
+ return -1;
+}
+
+static void TownAuthorityWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ const Town *t = GetTown(w->window_number);
+ int numact;
+ uint buttons = GetMaskOfTownActions(&numact, _local_player, t);
+
+ SetVScrollCount(w, numact + 1);
+
+ if (WP(w,def_d).data_1 != -1 && !HASBIT(buttons, WP(w,def_d).data_1))
+ WP(w,def_d).data_1 = -1;
+
+ SetWindowWidgetDisabledState(w, 6, WP(w, def_d).data_1 == -1);
+
+ {
+ int y;
+ const Player *p;
+ int r;
+ StringID str;
+
+ SetDParam(0, w->window_number);
+ DrawWindowWidgets(w);
+
+ DrawString(2, 15, STR_2023_TRANSPORT_COMPANY_RATINGS, 0);
+
+ // Draw list of players
+ y = 25;
+ FOR_ALL_PLAYERS(p) {
+ if (p->is_active && (HASBIT(t->have_ratings, p->index) || t->exclusivity == p->index)) {
+ DrawPlayerIcon(p->index, 2, y);
+
+ SetDParam(0, p->name_1);
+ SetDParam(1, p->name_2);
+ SetDParam(2, GetPlayerNameString(p->index, 3));
+
+ r = t->ratings[p->index];
+ (str = STR_3035_APPALLING, r <= RATING_APPALLING) || // Apalling
+ (str++, r <= RATING_VERYPOOR) || // Very Poor
+ (str++, r <= RATING_POOR) || // Poor
+ (str++, r <= RATING_MEDIOCRE) || // Mediocore
+ (str++, r <= RATING_GOOD) || // Good
+ (str++, r <= RATING_VERYGOOD) || // Very Good
+ (str++, r <= RATING_EXCELLENT) || // Excellent
+ (str++, true); // Outstanding
+
+ SetDParam(4, str);
+ if (t->exclusivity == p->index) // red icon for player with exclusive rights
+ DrawSprite(SPR_BLOT | PALETTE_TO_RED, 18, y);
+
+ DrawString(28, y, STR_2024, 0);
+ y += 10;
+ }
+ }
+ }
+
+ // Draw actions list
+ {
+ int y = 107, i;
+ int pos = w->vscroll.pos;
+
+ if (--pos < 0) {
+ DrawString(2, y, STR_2045_ACTIONS_AVAILABLE, 0);
+ y += 10;
+ }
+ for (i = 0; buttons; i++, buttons >>= 1) {
+ if (pos <= -5) break;
+
+ if (buttons&1 && --pos < 0) {
+ DrawString(3, y, STR_2046_SMALL_ADVERTISING_CAMPAIGN + i, 6);
+ y += 10;
+ }
+ }
+ }
+
+ {
+ int i = WP(w,def_d).data_1;
+
+ if (i != -1) {
+ SetDParam(1, (_price.build_industry >> 8) * _town_action_costs[i]);
+ SetDParam(0, STR_2046_SMALL_ADVERTISING_CAMPAIGN + i);
+ DrawStringMultiLine(2, 159, STR_204D_INITIATE_A_SMALL_LOCAL + i, 313);
+ }
+ }
+
+ } break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 3: { /* listbox */
+ const Town *t = GetTown(w->window_number);
+ int y = (e->we.click.pt.y - 0x6B) / 10;
+
+ if (!IS_INT_INSIDE(y, 0, 5)) return;
+
+ y = GetNthSetBit(GetMaskOfTownActions(NULL, _local_player, t), y + w->vscroll.pos - 1);
+ if (y >= 0) {
+ WP(w,def_d).data_1 = y;
+ SetWindowDirty(w);
+ }
+ break;
+ }
+
+ case 6: { /* carry out the action */
+ DoCommandP(GetTown(w->window_number)->xy, w->window_number, WP(w,def_d).data_1, NULL, CMD_DO_TOWN_ACTION | CMD_MSG(STR_00B4_CAN_T_DO_THIS));
+ break;
+ }
+ }
+ break;
+
+ case WE_4:
+ SetWindowDirty(w);
+ break;
+ }
+}
+
+static const WindowDesc _town_authority_desc = {
+ WDP_AUTO, WDP_AUTO, 317, 222,
+ WC_TOWN_AUTHORITY,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+ _town_authority_widgets,
+ TownAuthorityWndProc
+};
+
+static void ShowTownAuthorityWindow(uint town)
+{
+ Window *w = AllocateWindowDescFront(&_town_authority_desc, town);
+
+ if (w != NULL) {
+ w->vscroll.cap = 5;
+ WP(w,def_d).data_1 = -1;
+ }
+}
+
+static void TownViewWndProc(Window *w, WindowEvent *e)
+{
+ Town *t = GetTown(w->window_number);
+
+ switch (e->event) {
+ case WE_PAINT:
+ // disable renaming town in network games if you are not the server
+ SetWindowWidgetDisabledState(w, 8, _networking && !_network_server);
+
+ SetDParam(0, t->index);
+ DrawWindowWidgets(w);
+
+ SetDParam(0, t->population);
+ SetDParam(1, t->num_houses);
+ DrawString(2, 107, STR_2006_POPULATION, 0);
+
+ SetDParam(0, t->act_pass);
+ SetDParam(1, t->max_pass);
+ DrawString(2, 117, STR_200D_PASSENGERS_LAST_MONTH_MAX, 0);
+
+ SetDParam(0, t->act_mail);
+ SetDParam(1, t->max_mail);
+ DrawString(2, 127, STR_200E_MAIL_LAST_MONTH_MAX, 0);
+
+ DrawWindowViewport(w);
+ break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 6: /* scroll to location */
+ ScrollMainWindowToTile(t->xy);
+ break;
+
+ case 7: /* town authority */
+ ShowTownAuthorityWindow(w->window_number);
+ break;
+
+ case 8: /* rename */
+ SetDParam(0, w->window_number);
+ ShowQueryString(STR_TOWN, STR_2007_RENAME_TOWN, 31, 130, w, CS_ALPHANUMERAL);
+ break;
+
+ case 9: /* expand town */
+ ExpandTown(t);
+ break;
+
+ case 10: /* delete town */
+ DeleteTown(t);
+ break;
+ }
+ break;
+
+ case WE_ON_EDIT_TEXT:
+ if (e->we.edittext.str[0] != '\0') {
+ _cmd_text = e->we.edittext.str;
+ DoCommandP(0, w->window_number, 0, NULL,
+ CMD_RENAME_TOWN | CMD_MSG(STR_2008_CAN_T_RENAME_TOWN));
+ }
+ break;
+ }
+}
+
+
+static const Widget _town_view_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 13, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 13, 11, 247, 0, 13, STR_2005, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_STICKYBOX, RESIZE_NONE, 13, 248, 259, 0, 13, 0x0, STR_STICKY_BUTTON},
+{ WWT_PANEL, RESIZE_NONE, 13, 0, 259, 14, 105, 0x0, STR_NULL},
+{ WWT_INSET, RESIZE_NONE, 13, 2, 257, 16, 103, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 13, 0, 259, 106, 137, 0x0, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 13, 0, 85, 138, 149, STR_00E4_LOCATION, STR_200B_CENTER_THE_MAIN_VIEW_ON},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 13, 86, 171, 138, 149, STR_2020_LOCAL_AUTHORITY, STR_2021_SHOW_INFORMATION_ON_LOCAL},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 13, 172, 259, 138, 149, STR_0130_RENAME, STR_200C_CHANGE_TOWN_NAME},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _town_view_desc = {
+ WDP_AUTO, WDP_AUTO, 260, 150,
+ WC_TOWN_VIEW,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON,
+ _town_view_widgets,
+ TownViewWndProc
+};
+
+static const Widget _town_view_scen_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 13, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 13, 11, 172, 0, 13, STR_2005, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_STICKYBOX, RESIZE_NONE, 13, 248, 259, 0, 13, 0x0, STR_STICKY_BUTTON},
+{ WWT_PANEL, RESIZE_NONE, 13, 0, 259, 14, 105, 0x0, STR_NULL},
+{ WWT_INSET, RESIZE_NONE, 13, 2, 257, 16, 103, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 13, 0, 259, 106, 137, 0x0, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 13, 0, 85, 138, 149, STR_00E4_LOCATION, STR_200B_CENTER_THE_MAIN_VIEW_ON},
+{ WWT_EMPTY, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 13, 173, 247, 0, 13, STR_0130_RENAME, STR_200C_CHANGE_TOWN_NAME},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 13, 86, 171, 138, 149, STR_023C_EXPAND, STR_023B_INCREASE_SIZE_OF_TOWN},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 13, 172, 259, 138, 149, STR_0290_DELETE, STR_0291_DELETE_THIS_TOWN_COMPLETELY},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _town_view_scen_desc = {
+ WDP_AUTO, WDP_AUTO, 260, 150,
+ WC_TOWN_VIEW,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON,
+ _town_view_scen_widgets,
+ TownViewWndProc
+};
+
+void ShowTownViewWindow(TownID town)
+{
+ Window *w;
+
+ if (_game_mode != GM_EDITOR) {
+ w = AllocateWindowDescFront(&_town_view_desc, town);
+ } else {
+ w = AllocateWindowDescFront(&_town_view_scen_desc, town);
+ }
+
+ if (w != NULL) {
+ w->flags4 |= WF_DISABLE_VP_SCROLL;
+ AssignWindowViewport(w, 3, 17, 0xFE, 0x56, GetTown(town)->xy, 1);
+ }
+}
+
+static const Widget _town_directory_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 13, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 13, 11, 195, 0, 13, STR_2000_TOWNS, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_STICKYBOX, RESIZE_NONE, 13, 196, 207, 0, 13, 0x0, STR_STICKY_BUTTON},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 13, 0, 98, 14, 25, STR_SORT_BY_NAME, STR_SORT_ORDER_TIP},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 13, 99, 195, 14, 25, STR_SORT_BY_POPULATION, STR_SORT_ORDER_TIP},
+{ WWT_PANEL, RESIZE_BOTTOM, 13, 0, 195, 26, 189, 0x0, STR_200A_TOWN_NAMES_CLICK_ON_NAME},
+{ WWT_SCROLLBAR, RESIZE_BOTTOM, 13, 196, 207, 14, 189, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WWT_PANEL, RESIZE_TB, 13, 0, 195, 190, 201, 0x0, STR_NULL},
+{ WWT_RESIZEBOX, RESIZE_TB, 13, 196, 207, 190, 201, 0x0, STR_RESIZE_BUTTON},
+{ WIDGETS_END},
+};
+
+
+// used to get a sorted list of the towns
+static uint _num_town_sort;
+
+static char _bufcache[64];
+static const Town* _last_town;
+
+static int CDECL TownNameSorter(const void *a, const void *b)
+{
+ const Town* ta = *(const Town**)a;
+ const Town* tb = *(const Town**)b;
+ char buf1[64];
+ int r;
+
+ SetDParam(0, ta->index);
+ GetString(buf1, STR_TOWN, lastof(buf1));
+
+ /* If 'b' is the same town as in the last round, use the cached value
+ * We do this to speed stuff up ('b' is called with the same value a lot of
+ * times after eachother) */
+ if (tb != _last_town) {
+ _last_town = tb;
+ SetDParam(0, tb->index);
+ GetString(_bufcache, STR_TOWN, lastof(_bufcache));
+ }
+
+ r = strcmp(buf1, _bufcache);
+ if (_town_sort_order & 1) r = -r;
+ return r;
+}
+
+static int CDECL TownPopSorter(const void *a, const void *b)
+{
+ const Town* ta = *(const Town**)a;
+ const Town* tb = *(const Town**)b;
+ int r = ta->population - tb->population;
+ if (_town_sort_order & 1) r = -r;
+ return r;
+}
+
+static void MakeSortedTownList(void)
+{
+ const Town* t;
+ uint n = 0;
+
+ /* Create array for sorting */
+ _town_sort = realloc((void*)_town_sort, (GetMaxTownIndex() + 1) * sizeof(_town_sort[0]));
+ if (_town_sort == NULL) error("Could not allocate memory for the town-sorting-list");
+
+ FOR_ALL_TOWNS(t) _town_sort[n++] = t;
+
+ _num_town_sort = n;
+
+ _last_town = NULL; // used for "cache"
+ qsort((void*)_town_sort, n, sizeof(_town_sort[0]), _town_sort_order & 2 ? TownPopSorter : TownNameSorter);
+
+ DEBUG(misc, 3, "Resorting towns list");
+}
+
+
+static void TownDirectoryWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ if (_town_sort_dirty) {
+ _town_sort_dirty = false;
+ MakeSortedTownList();
+ }
+
+ SetVScrollCount(w, _num_town_sort);
+
+ DrawWindowWidgets(w);
+ DoDrawString(_town_sort_order & 1 ? DOWNARROW : UPARROW, (_town_sort_order <= 1) ? 88 : 187, 15, 0x10);
+
+ {
+ int n = 0;
+ uint16 i = w->vscroll.pos;
+ int y = 28;
+
+ while (i < _num_town_sort) {
+ const Town* t = _town_sort[i];
+
+ assert(t->xy);
+
+ SetDParam(0, t->index);
+ SetDParam(1, t->population);
+ DrawString(2, y, STR_2057, 0);
+
+ y += 10;
+ i++;
+ if (++n == w->vscroll.cap) break; // max number of towns in 1 window
+ }
+ SetDParam(0, GetWorldPopulation());
+ DrawString(3, w->height - 12 + 2, STR_TOWN_POPULATION, 0);
+ }
+ } break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 3: { /* Sort by Name ascending/descending */
+ _town_sort_order = (_town_sort_order == 0) ? 1 : 0;
+ _town_sort_dirty = true;
+ SetWindowDirty(w);
+ } break;
+
+ case 4: { /* Sort by Population ascending/descending */
+ _town_sort_order = (_town_sort_order == 2) ? 3 : 2;
+ _town_sort_dirty = true;
+ SetWindowDirty(w);
+ } break;
+
+ case 5: { /* Click on Town Matrix */
+ const Town* t;
+
+ uint16 id_v = (e->we.click.pt.y - 28) / 10;
+
+ if (id_v >= w->vscroll.cap) return; // click out of bounds
+
+ id_v += w->vscroll.pos;
+
+ if (id_v >= _num_town_sort) return; // click out of town bounds
+
+ t = _town_sort[id_v];
+ assert(t->xy);
+ ScrollMainWindowToTile(t->xy);
+ break;
+ }
+ }
+ break;
+
+ case WE_4:
+ SetWindowDirty(w);
+ break;
+
+ case WE_RESIZE:
+ w->vscroll.cap += e->we.sizing.diff.y / 10;
+ break;
+ }
+}
+
+static const WindowDesc _town_directory_desc = {
+ WDP_AUTO, WDP_AUTO, 208, 202,
+ WC_TOWN_DIRECTORY,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
+ _town_directory_widgets,
+ TownDirectoryWndProc
+};
+
+
+void ShowTownDirectory(void)
+{
+ Window *w = AllocateWindowDescFront(&_town_directory_desc, 0);
+
+ if (w != NULL) {
+ w->vscroll.cap = 16;
+ w->resize.step_height = 10;
+ w->resize.height = w->height - 10 * 6; // minimum of 10 items in the list, each item 10 high
+ }
+}
diff --git a/src/town_map.h b/src/town_map.h
new file mode 100644
index 000000000..bc546cd10
--- /dev/null
+++ b/src/town_map.h
@@ -0,0 +1,197 @@
+/* $Id$ */
+
+/** @file town_map.h Accessors for towns */
+
+#ifndef TOWN_MAP_H
+#define TOWN_MAP_H
+
+#include "town.h"
+
+static inline int GetHouseType(TileIndex t)
+{
+ assert(IsTileType(t, MP_HOUSE));
+ return _m[t].m4;
+}
+
+static inline TownID GetTownIndex(TileIndex t)
+{
+ assert(IsTileType(t, MP_HOUSE) || IsTileType(t, MP_STREET)); // XXX incomplete
+ return _m[t].m2;
+}
+
+/**
+ * Set the town index for a road or house tile.
+ * @param tile the tile
+ * @param index the index of the town
+ */
+static inline void SetTownIndex(TileIndex t, TownID index)
+{
+ assert(IsTileType(t, MP_STREET) || IsTileType(t, MP_HOUSE));
+ _m[t].m2 = index;
+}
+
+static inline bool LiftHasDestination(TileIndex t)
+{
+ return HASBIT(_m[t].m5, 7);
+}
+
+static inline void SetLiftDestination(TileIndex t, byte dest)
+{
+ SB(_m[t].m5, 0, 6, dest);
+ SETBIT(_m[t].m1, 7); /* Start moving */
+}
+
+static inline byte GetLiftDestination(TileIndex t)
+{
+ return GB(_m[t].m5, 0, 6);
+}
+
+static inline bool IsLiftMoving(TileIndex t)
+{
+ return HASBIT(_m[t].m1, 7);
+}
+
+static inline void BeginLiftMovement(TileIndex t)
+{
+ SETBIT(_m[t].m5, 7);
+}
+
+static inline void HaltLift(TileIndex t)
+{
+ CLRBIT(_m[t].m1, 7);
+ CLRBIT(_m[t].m5, 7);
+ SB(_m[t].m5, 0, 6, 0);
+
+ DeleteAnimatedTile(t);
+}
+
+static inline byte GetLiftPosition(TileIndex t)
+{
+ return GB(_m[t].m1, 0, 7);
+}
+
+static inline void SetLiftPosition(TileIndex t, byte pos)
+{
+ SB(_m[t].m1, 0, 7, pos);
+}
+
+static inline Town* GetTownByTile(TileIndex t)
+{
+ return GetTown(GetTownIndex(t));
+}
+
+
+Town* CalcClosestTownFromTile(TileIndex tile, uint threshold);
+
+
+static inline void MakeHouseTile(TileIndex t, TownID tid, byte counter, byte stage, byte type)
+{
+ assert(IsTileType(t, MP_CLEAR));
+
+ SetTileType(t, MP_HOUSE);
+ _m[t].m1 = 0;
+ _m[t].m2 = tid;
+ SB(_m[t].m3, 6, 2, stage);
+ _m[t].m4 = type;
+ SB(_m[t].m5, 0, 2, counter);
+
+ MarkTileDirtyByTile(t);
+}
+
+enum {
+ TWO_BY_TWO_BIT = 2, ///< House is two tiles in X and Y directions
+ ONE_BY_TWO_BIT = 1, ///< House is two tiles in Y direction
+ TWO_BY_ONE_BIT = 0, ///< House is two tiles in X direction
+};
+
+static inline void MakeTownHouse(TileIndex t, TownID tid, byte counter, byte stage, byte size, byte type)
+{
+ MakeHouseTile(t, tid, counter, stage, type);
+ if (HASBIT(size, TWO_BY_TWO_BIT) || HASBIT(size, ONE_BY_TWO_BIT)) MakeHouseTile(t + TileDiffXY(0, 1), tid, counter, stage, ++type);
+ if (HASBIT(size, TWO_BY_TWO_BIT) || HASBIT(size, TWO_BY_ONE_BIT)) MakeHouseTile(t + TileDiffXY(1, 0), tid, counter, stage, ++type);
+ if (HASBIT(size, TWO_BY_TWO_BIT)) MakeHouseTile(t + TileDiffXY(1, 1), tid, counter, stage, ++type);
+}
+
+/**
+ * House Construction Scheme.
+ * Construction counter, for buildings under construction. Incremented on every
+ * periodic tile processing.
+ * On wraparound, the stage of building in is increased.
+ * (Get|Set|Inc)HouseBuildingStage are taking care of the real stages,
+ * (as the sprite for the next phase of house building)
+ * (Get|Set|Inc)HouseConstructionTick is simply a tick counter between the
+ * different stages
+ */
+
+/**
+ * Gets the building stage of a house
+ * @param tile the tile of the house to get the building stage of
+ * @pre IsTileType(t, MP_HOUSE)
+ * @return the building stage of the house
+ */
+static inline byte GetHouseBuildingStage(TileIndex t)
+{
+ assert(IsTileType(t, MP_HOUSE));
+ return GB(_m[t].m3, 6, 2);
+}
+
+/**
+ * Sets the building stage of a house
+ * @param tile the tile of the house to set the building stage of
+ * @param stage the new stage
+ * @pre IsTileType(t, MP_HOUSE)
+ */
+static inline void SetHouseBuildingStage(TileIndex t, byte stage)
+{
+ assert(IsTileType(t, MP_HOUSE));
+ SB(_m[t].m3, 6, 2, stage);
+}
+
+/**
+ * Increments the building stage of a house
+ * @param tile the tile of the house to increment the building stage of
+ * @pre IsTileType(t, MP_HOUSE)
+ */
+static inline void IncHouseBuildingStage( TileIndex t )
+{
+ assert(IsTileType(t, MP_HOUSE));
+ AB(_m[t].m3, 6, 2, 1);
+}
+
+/**
+ * Gets the construction stage of a house
+ * @param tile the tile of the house to get the construction stage of
+ * @pre IsTileType(t, MP_HOUSE)
+ * @return the construction stage of the house
+ */
+static inline byte GetHouseConstructionTick(TileIndex t)
+{
+ assert(IsTileType(t, MP_HOUSE));
+ return GB(_m[t].m5, 0, 3);
+}
+
+/**
+ * Sets the construction stage of a house
+ * @param tile the tile of the house to set the construction stage of
+ * @param stage the new stage
+ * @pre IsTileType(t, MP_HOUSE)
+ */
+static inline void SetHouseConstructionTick(TileIndex t, byte stage)
+{
+ assert(IsTileType(t, MP_HOUSE));
+ SB(_m[t].m5, 0, 3, stage);
+}
+
+/**
+ * Sets the increment stage of a house
+ * @param tile the tile of the house to increment the construction stage of
+ * @pre IsTileType(t, MP_HOUSE)
+ */
+static inline void IncHouseConstructionTick(TileIndex t)
+{
+ assert(IsTileType(t, MP_HOUSE));
+ AB(_m[t].m5, 0, 3, 1);
+}
+
+
+#endif /* TOWN_MAP_H */
diff --git a/src/train.h b/src/train.h
new file mode 100644
index 000000000..aead2f2ca
--- /dev/null
+++ b/src/train.h
@@ -0,0 +1,227 @@
+/* $Id$ */
+
+#ifndef TRAIN_H
+#define TRAIN_H
+
+#include "stdafx.h"
+#include "vehicle.h"
+
+
+/*
+ * enum to handle train subtypes
+ * Do not access it directly unless you have to. Use the access functions below
+ * This is an enum to tell what bit to access as it is a bitmask
+ */
+
+typedef enum TrainSubtypes {
+ Train_Front = 0, // Leading engine of a train
+ Train_Articulated_Part = 1, // Articulated part of an engine
+ Train_Wagon = 2, // Wagon
+ Train_Engine = 3, // Engine, that can be front engines, but might be placed behind another engine
+ Train_Free_Wagon = 4, // First in a wagon chain (in depot)
+ Train_Multiheaded = 5, // Engine is a multiheaded
+} TrainSubtype;
+
+
+/** Check if a vehicle is front engine
+ * @param v vehicle to check
+ * @return Returns true if vehicle is a front engine
+ */
+static inline bool IsFrontEngine(const Vehicle *v)
+{
+ return HASBIT(v->subtype, Train_Front);
+}
+
+/** Set front engine state
+ * @param v vehicle to change
+ */
+static inline void SetFrontEngine(Vehicle *v)
+{
+ SETBIT(v->subtype, Train_Front);
+}
+
+/** Remove the front engine state
+ * @param v vehicle to change
+ */
+static inline void ClearFrontEngine(Vehicle *v)
+{
+ CLRBIT(v->subtype, Train_Front);
+}
+
+/** Check if a vehicle is an articulated part of an engine
+ * @param v vehicle to check
+ * @return Returns true if vehicle is an articulated part
+ */
+static inline bool IsArticulatedPart(const Vehicle *v)
+{
+ return HASBIT(v->subtype, Train_Articulated_Part);
+}
+
+/** Set a vehicle to be an articulated part
+ * @param v vehicle to change
+ */
+static inline void SetArticulatedPart(Vehicle *v)
+{
+ SETBIT(v->subtype, Train_Articulated_Part);
+}
+
+/** Clear a vehicle from being an articulated part
+ * @param v vehicle to change
+ */
+static inline void ClearArticulatedPart(Vehicle *v)
+{
+ CLRBIT(v->subtype, Train_Articulated_Part);
+}
+
+/** Check if a vehicle is a wagon
+ * @param v vehicle to check
+ * @return Returns true if vehicle is a wagon
+ */
+static inline bool IsTrainWagon(const Vehicle *v)
+{
+ return HASBIT(v->subtype, Train_Wagon);
+}
+
+/** Set a vehicle to be a wagon
+ * @param v vehicle to change
+ */
+static inline void SetTrainWagon(Vehicle *v)
+{
+ SETBIT(v->subtype, Train_Wagon);
+}
+
+/** Clear wagon property
+ * @param v vehicle to change
+ */
+static inline void ClearTrainWagon(Vehicle *v)
+{
+ CLRBIT(v->subtype, Train_Wagon);
+}
+
+/** Check if a vehicle is an engine (can be first in a train)
+ * @param v vehicle to check
+ * @return Returns true if vehicle is an engine
+ */
+static inline bool IsTrainEngine(const Vehicle *v)
+{
+ return HASBIT(v->subtype, Train_Engine);
+}
+
+/** Set engine status
+ * @param v vehicle to change
+ */
+static inline void SetTrainEngine(Vehicle *v)
+{
+ SETBIT(v->subtype, Train_Engine);
+}
+
+/** Clear engine status
+ * @param v vehicle to change
+ */
+static inline void ClearTrainEngine(Vehicle *v)
+{
+ CLRBIT(v->subtype, Train_Engine);
+}
+
+/** Check if a vehicle is a free wagon (got no engine in front of it)
+ * @param v vehicle to check
+ * @return Returns true if vehicle is a free wagon
+ */
+static inline bool IsFreeWagon(const Vehicle *v)
+{
+ return HASBIT(v->subtype, Train_Free_Wagon);
+}
+
+/** Set if a vehicle is a free wagon
+ * @param v vehicle to change
+ */
+static inline void SetFreeWagon(Vehicle *v)
+{
+ SETBIT(v->subtype, Train_Free_Wagon);
+}
+
+/** Clear a vehicle from being a free wagon
+ * @param v vehicle to change
+ */
+static inline void ClearFreeWagon(Vehicle *v)
+{
+ CLRBIT(v->subtype, Train_Free_Wagon);
+}
+
+/** Check if a vehicle is a multiheaded engine
+ * @param v vehicle to check
+ * @return Returns true if vehicle is a multiheaded engine
+ */
+static inline bool IsMultiheaded(const Vehicle *v)
+{
+ return HASBIT(v->subtype, Train_Multiheaded);
+}
+
+/** Set if a vehicle is a multiheaded engine
+ * @param v vehicle to change
+ */
+static inline void SetMultiheaded(Vehicle *v)
+{
+ SETBIT(v->subtype, Train_Multiheaded);
+}
+
+/** Clear multiheaded engine property
+ * @param v vehicle to change
+ */
+static inline void ClearMultiheaded(Vehicle *v)
+{
+ CLRBIT(v->subtype, Train_Multiheaded);
+}
+
+/** Check if an engine has an articulated part.
+ * @param v Vehicle.
+ * @return True if the engine has an articulated part.
+ */
+static inline bool EngineHasArticPart(const Vehicle *v)
+{
+ return (v->next != NULL && IsArticulatedPart(v->next));
+}
+
+/**
+ * Get the next part of a multi-part engine.
+ * Will only work on a multi-part engine (EngineHasArticPart(v) == true),
+ * Result is undefined for normal engine.
+ */
+static inline Vehicle *GetNextArticPart(const Vehicle *v)
+{
+ assert(EngineHasArticPart(v));
+ return v->next;
+}
+
+/** Get the last part of a multi-part engine.
+ * @param v Vehicle.
+ * @return Last part of the engine.
+ */
+static inline Vehicle *GetLastEnginePart(Vehicle *v)
+{
+ while (EngineHasArticPart(v)) v = GetNextArticPart(v);
+ return v;
+}
+
+/** Get the next real (non-articulated part) vehicle in the consist.
+ * @param v Vehicle.
+ * @return Next vehicle in the consist.
+ */
+static inline Vehicle *GetNextVehicle(const Vehicle *v)
+{
+ while (EngineHasArticPart(v)) v = GetNextArticPart(v);
+
+ /* v now contains the last artic part in the engine */
+ return v->next;
+}
+
+void ConvertOldMultiheadToNew(void);
+void ConnectMultiheadedTrains(void);
+uint CountArticulatedParts(EngineID engine_type);
+
+int CheckTrainInDepot(const Vehicle *v, bool needs_to_be_stopped);
+void CcCloneTrain(bool success, TileIndex tile, uint32 p1, uint32 p2);
+
+byte FreightWagonMult(CargoID cargo);
+
+#endif /* TRAIN_H */
diff --git a/src/train_cmd.c b/src/train_cmd.c
new file mode 100644
index 000000000..c1c5746bb
--- /dev/null
+++ b/src/train_cmd.c
@@ -0,0 +1,3810 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "bridge_map.h"
+#include "debug.h"
+#include "functions.h"
+#include "gui.h"
+#include "station_map.h"
+#include "table/strings.h"
+#include "map.h"
+#include "tile.h"
+#include "tunnel_map.h"
+#include "vehicle.h"
+#include "command.h"
+#include "pathfind.h"
+#include "npf.h"
+#include "station.h"
+#include "table/train_cmd.h"
+#include "news.h"
+#include "engine.h"
+#include "player.h"
+#include "sound.h"
+#include "depot.h"
+#include "waypoint.h"
+#include "vehicle_gui.h"
+#include "train.h"
+#include "bridge.h"
+#include "newgrf_callbacks.h"
+#include "newgrf_engine.h"
+#include "newgrf_sound.h"
+#include "newgrf_text.h"
+#include "direction.h"
+#include "yapf/yapf.h"
+#include "date.h"
+
+static bool TrainCheckIfLineEnds(Vehicle *v);
+static void TrainController(Vehicle *v, bool update_image);
+
+static const byte _vehicle_initial_x_fract[4] = {10, 8, 4, 8};
+static const byte _vehicle_initial_y_fract[4] = { 8, 4, 8, 10};
+static const byte _state_dir_table[4] = { 0x20, 8, 0x10, 4 };
+
+
+/** Return the cargo weight multiplier to use for a rail vehicle
+ * @param cargo Cargo type to get multiplier for
+ * @return Cargo weight multiplier
+ */
+byte FreightWagonMult(CargoID cargo)
+{
+ // XXX NewCargos introduces a specific "is freight" flag for this test.
+ if (cargo == CT_PASSENGERS || cargo == CT_MAIL) return 1;
+ return _patches.freight_trains;
+}
+
+
+/**
+ * Recalculates the cached total power of a train. Should be called when the consist is changed
+ * @param v First vehicle of the consist.
+ */
+void TrainPowerChanged(Vehicle* v)
+{
+ Vehicle* u;
+ uint32 power = 0;
+ uint32 max_te = 0;
+
+ for (u = v; u != NULL; u = u->next) {
+ const RailVehicleInfo *rvi_u;
+ bool engine_has_power = true;
+ bool wagon_has_power = true;
+
+ /* Power is not added for articulated parts */
+ if (IsArticulatedPart(u)) continue;
+
+ if (IsLevelCrossingTile(u->tile)) {
+ if (!HasPowerOnRail(u->u.rail.railtype, GetRailTypeCrossing(u->tile))) engine_has_power = false;
+ if (!HasPowerOnRail(v->u.rail.railtype, GetRailTypeCrossing(u->tile))) wagon_has_power = false;
+ } else {
+ if (!HasPowerOnRail(u->u.rail.railtype, GetRailType(u->tile))) engine_has_power = false;
+ if (!HasPowerOnRail(v->u.rail.railtype, GetRailType(u->tile))) wagon_has_power = false;
+ }
+
+ rvi_u = RailVehInfo(u->engine_type);
+
+ if (engine_has_power && rvi_u->power != 0) {
+ power += rvi_u->power;
+ /* Tractive effort in (tonnes * 1000 * 10 =) N */
+ max_te += (u->u.rail.cached_veh_weight * 10000 * rvi_u->tractive_effort) / 256;
+ }
+
+ if (HASBIT(u->u.rail.flags, VRF_POWEREDWAGON) && (wagon_has_power)) {
+ power += RailVehInfo(u->u.rail.first_engine)->pow_wag_power;
+ }
+ }
+
+ if (v->u.rail.cached_power != power || v->u.rail.cached_max_te != max_te) {
+ v->u.rail.cached_power = power;
+ v->u.rail.cached_max_te = max_te;
+ InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ }
+}
+
+
+/**
+ * Recalculates the cached weight of a train and its vehicles. Should be called each time the cargo on
+ * the consist changes.
+ * @param v First vehicle of the consist.
+ */
+static void TrainCargoChanged(Vehicle* v)
+{
+ Vehicle *u;
+ uint32 weight = 0;
+
+ for (u = v; u != NULL; u = u->next) {
+ const RailVehicleInfo *rvi = RailVehInfo(u->engine_type);
+ uint32 vweight = (_cargoc.weights[u->cargo_type] * u->cargo_count * FreightWagonMult(u->cargo_type)) / 16;
+
+ // Vehicle weight is not added for articulated parts.
+ if (!IsArticulatedPart(u)) {
+ // vehicle weight is the sum of the weight of the vehicle and the weight of its cargo
+ vweight += rvi->weight;
+
+ // powered wagons have extra weight added
+ if (HASBIT(u->u.rail.flags, VRF_POWEREDWAGON))
+ vweight += RailVehInfo(u->u.rail.first_engine)->pow_wag_weight;
+ }
+
+ // consist weight is the sum of the weight of all vehicles in the consist
+ weight += vweight;
+
+ // store vehicle weight in cache
+ u->u.rail.cached_veh_weight = vweight;
+ };
+
+ // store consist weight in cache
+ v->u.rail.cached_weight = weight;
+
+ /* Now update train power (tractive effort is dependent on weight) */
+ TrainPowerChanged(v);
+}
+
+
+/**
+ * Recalculates the cached stuff of a train. Should be called each time a vehicle is added
+ * to/removed from the chain, and when the game is loaded.
+ * Note: this needs to be called too for 'wagon chains' (in the depot, without an engine)
+ * @param v First vehicle of the chain.
+ */
+void TrainConsistChanged(Vehicle* v)
+{
+ const RailVehicleInfo *rvi_v;
+ Vehicle *u;
+ uint16 max_speed = 0xFFFF;
+ EngineID first_engine;
+
+ assert(v->type == VEH_Train);
+
+ assert(IsFrontEngine(v) || IsFreeWagon(v));
+
+ rvi_v = RailVehInfo(v->engine_type);
+ first_engine = IsFrontEngine(v) ? v->engine_type : INVALID_ENGINE;
+ v->u.rail.cached_total_length = 0;
+ v->u.rail.compatible_railtypes = 0;
+
+ for (u = v; u != NULL; u = u->next) {
+ const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type);
+ uint16 veh_len;
+
+ // Update the v->first cache. This is faster than having to brute force it later.
+ if (u->first == NULL) u->first = v;
+
+ // update the 'first engine'
+ u->u.rail.first_engine = (v == u) ? INVALID_ENGINE : first_engine;
+ u->u.rail.railtype = GetEngine(u->engine_type)->railtype;
+
+ if (IsTrainEngine(u)) first_engine = u->engine_type;
+
+ if (rvi_u->visual_effect != 0) {
+ u->u.rail.cached_vis_effect = rvi_u->visual_effect;
+ } else {
+ if (IsTrainWagon(u) || IsArticulatedPart(u)) {
+ // Wagons and articulated parts have no effect by default
+ u->u.rail.cached_vis_effect = 0x40;
+ } else if (rvi_u->engclass == 0) {
+ // Steam is offset by -4 units
+ u->u.rail.cached_vis_effect = 4;
+ } else {
+ // Diesel fumes and sparks come from the centre
+ u->u.rail.cached_vis_effect = 8;
+ }
+ }
+
+ if (!IsArticulatedPart(u)) {
+ // check if its a powered wagon
+ CLRBIT(u->u.rail.flags, VRF_POWEREDWAGON);
+
+ /* Check powered wagon / visual effect callback */
+ if (HASBIT(EngInfo(u->engine_type)->callbackmask, CBM_WAGON_POWER)) {
+ uint16 callback = GetVehicleCallback(CBID_TRAIN_WAGON_POWER, 0, 0, u->engine_type, u);
+
+ if (callback != CALLBACK_FAILED) u->u.rail.cached_vis_effect = callback;
+ }
+
+ if ((rvi_v->pow_wag_power != 0) && (rvi_u->flags & RVI_WAGON) && UsesWagonOverride(u)) {
+ if (u->u.rail.cached_vis_effect < 0x40) {
+ /* wagon is powered */
+ SETBIT(u->u.rail.flags, VRF_POWEREDWAGON); // cache 'powered' status
+ }
+ }
+
+ /* Do not count powered wagons for the compatible railtypes, as wagons always
+ have railtype normal */
+ if (rvi_u->power > 0) {
+ v->u.rail.compatible_railtypes |= GetRailTypeInfo(u->u.rail.railtype)->powered_railtypes;
+ }
+
+ /* Some electric engines can be allowed to run on normal rail. It happens to all
+ * existing electric engines when elrails are disabled and then re-enabled */
+ if (HASBIT(u->u.rail.flags, VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL)) {
+ u->u.rail.railtype = RAILTYPE_RAIL;
+ u->u.rail.compatible_railtypes |= (1 << RAILTYPE_RAIL);
+ }
+
+ // max speed is the minimum of the speed limits of all vehicles in the consist
+ if (!(rvi_u->flags & RVI_WAGON) || _patches.wagon_speed_limits)
+ if (rvi_u->max_speed != 0 && !UsesWagonOverride(u))
+ max_speed = min(rvi_u->max_speed, max_speed);
+ }
+
+ // check the vehicle length (callback)
+ veh_len = CALLBACK_FAILED;
+ if (HASBIT(EngInfo(u->engine_type)->callbackmask, CBM_VEHICLE_LENGTH)) {
+ veh_len = GetVehicleCallback(CBID_TRAIN_VEHICLE_LENGTH, 0, 0, u->engine_type, u);
+ }
+ if (veh_len == CALLBACK_FAILED) veh_len = rvi_u->shorten_factor;
+ veh_len = clamp(veh_len, 0, u->next == NULL ? 7 : 5); // the clamp on vehicles not the last in chain is stricter, as too short wagons can break the 'follow next vehicle' code
+ u->u.rail.cached_veh_length = 8 - veh_len;
+ v->u.rail.cached_total_length += u->u.rail.cached_veh_length;
+
+ };
+
+ // store consist weight/max speed in cache
+ v->u.rail.cached_max_speed = max_speed;
+
+ // recalculate cached weights and power too (we do this *after* the rest, so it is known which wagons are powered and need extra weight added)
+ TrainCargoChanged(v);
+}
+
+/* These two arrays are used for realistic acceleration. XXX: How should they
+ * be interpreted? */
+static const byte _curve_neighbours45[8][2] = {
+ {7, 1},
+ {0, 2},
+ {1, 3},
+ {2, 4},
+ {3, 5},
+ {4, 6},
+ {5, 7},
+ {6, 0},
+};
+
+static const byte _curve_neighbours90[8][2] = {
+ {6, 2},
+ {7, 3},
+ {0, 4},
+ {1, 5},
+ {2, 6},
+ {3, 7},
+ {4, 0},
+ {5, 1},
+};
+
+enum AccelType {
+ AM_ACCEL,
+ AM_BRAKE
+};
+
+static bool TrainShouldStop(const Vehicle* v, TileIndex tile)
+{
+ const Order* o = &v->current_order;
+ StationID sid = GetStationIndex(tile);
+
+ assert(v->type == VEH_Train);
+ //When does a train drive through a station
+ //first we deal with the "new nonstop handling"
+ if (_patches.new_nonstop && o->flags & OF_NON_STOP && sid == o->dest) {
+ return false;
+ }
+
+ if (v->last_station_visited == sid) return false;
+
+ if (sid != o->dest && (o->flags & OF_NON_STOP || _patches.new_nonstop)) {
+ return false;
+ }
+
+ return true;
+}
+
+//new acceleration
+static int GetTrainAcceleration(Vehicle *v, bool mode)
+{
+ const Vehicle *u;
+ int num = 0; //number of vehicles, change this into the number of axles later
+ int power = 0;
+ int mass = 0;
+ int max_speed = 2000;
+ int area = 120;
+ int friction = 35; //[1e-3]
+ int drag_coeff = 20; //[1e-4]
+ int incl = 0;
+ int resistance;
+ int speed = v->cur_speed; //[mph]
+ int force = 0x3FFFFFFF;
+ int pos = 0;
+ int lastpos = -1;
+ int curvecount[2] = {0, 0};
+ int sum = 0;
+ int numcurve = 0;
+ int max_te = v->u.rail.cached_max_te; // [N]
+
+ speed *= 10;
+ speed /= 16;
+
+ //first find the curve speed limit
+ for (u = v; u->next != NULL; u = u->next, pos++) {
+ Direction dir = u->direction;
+ Direction ndir = u->next->direction;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ if ( _curve_neighbours45[dir][i] == ndir) {
+ curvecount[i]++;
+ if (lastpos != -1) {
+ numcurve++;
+ sum += pos - lastpos;
+ if (pos - lastpos == 1) {
+ max_speed = 88;
+ }
+ }
+ lastpos = pos;
+ }
+ }
+
+ //if we have a 90 degree turn, fix the speed limit to 60
+ if (_curve_neighbours90[dir][0] == ndir ||
+ _curve_neighbours90[dir][1] == ndir) {
+ max_speed = 61;
+ }
+ }
+
+ if (numcurve > 0) sum /= numcurve;
+
+ if ((curvecount[0] != 0 || curvecount[1] != 0) && max_speed > 88) {
+ int total = curvecount[0] + curvecount[1];
+
+ if (curvecount[0] == 1 && curvecount[1] == 1) {
+ max_speed = 0xFFFF;
+ } else if (total > 1) {
+ max_speed = 232 - (13 - clamp(sum, 1, 12)) * (13 - clamp(sum, 1, 12));
+ }
+ }
+
+ max_speed += (max_speed / 2) * v->u.rail.railtype;
+
+ if (IsTileType(v->tile, MP_STATION) && IsFrontEngine(v)) {
+ if (TrainShouldStop(v, v->tile)) {
+ uint station_length = GetPlatformLength(v->tile, DirToDiagDir(v->direction));
+ int delta_v;
+
+ max_speed = 120;
+
+ delta_v = v->cur_speed / (station_length + 1);
+ if (v->max_speed > (v->cur_speed - delta_v))
+ max_speed = v->cur_speed - (delta_v / 10);
+
+ max_speed = max(max_speed, 25 * station_length);
+ }
+ }
+
+ mass = v->u.rail.cached_weight;
+ power = v->u.rail.cached_power * 746;
+ max_speed = min(max_speed, v->u.rail.cached_max_speed);
+
+ for (u = v; u != NULL; u = u->next) {
+ num++;
+ drag_coeff += 3;
+
+ if (u->u.rail.track == 0x80) max_speed = min(max_speed, 61);
+
+ if (HASBIT(u->u.rail.flags, VRF_GOINGUP)) {
+ incl += u->u.rail.cached_veh_weight * 60; //3% slope, quite a bit actually
+ } else if (HASBIT(u->u.rail.flags, VRF_GOINGDOWN)) {
+ incl -= u->u.rail.cached_veh_weight * 60;
+ }
+ }
+
+ v->max_speed = max_speed;
+
+ if (v->u.rail.railtype != RAILTYPE_MAGLEV) {
+ resistance = 13 * mass / 10;
+ resistance += 60 * num;
+ resistance += friction * mass * speed / 1000;
+ resistance += (area * drag_coeff * speed * speed) / 10000;
+ } else {
+ resistance = (area * (drag_coeff / 2) * speed * speed) / 10000;
+ }
+ resistance += incl;
+ resistance *= 4; //[N]
+
+ /* Due to the mph to m/s conversion below, at speeds below 3 mph the force is
+ * actually double the train's power */
+ if (speed > 2) {
+ switch (v->u.rail.railtype) {
+ case RAILTYPE_RAIL:
+ case RAILTYPE_ELECTRIC:
+ case RAILTYPE_MONO:
+ force = power / speed; //[N]
+ force *= 22;
+ force /= 10;
+ if (mode == AM_ACCEL && force > max_te) force = max_te;
+ break;
+
+ case RAILTYPE_MAGLEV:
+ force = power / 25;
+ break;
+ }
+ } else {
+ //"kickoff" acceleration
+ force = (mode == AM_ACCEL && v->u.rail.railtype != RAILTYPE_MAGLEV) ? min(max_te, power) : power;
+ force = max(force, (mass * 8) + resistance);
+ }
+
+ if (force <= 0) force = 10000;
+
+ if (v->u.rail.railtype != RAILTYPE_MAGLEV) force = min(force, mass * 10 * 200);
+
+ if (mode == AM_ACCEL) {
+ return (force - resistance) / (mass * 4);
+ } else {
+ return min((-force - resistance) / (mass * 4), -10000 / (mass * 4));
+ }
+}
+
+static void UpdateTrainAcceleration(Vehicle* v)
+{
+ uint power = 0;
+ uint weight = 0;
+
+ assert(IsFrontEngine(v));
+
+ weight = v->u.rail.cached_weight;
+ power = v->u.rail.cached_power;
+ v->max_speed = v->u.rail.cached_max_speed;
+
+ assert(weight != 0);
+
+ v->acceleration = clamp(power / weight * 4, 1, 255);
+}
+
+int GetTrainImage(const Vehicle* v, Direction direction)
+{
+ int img = v->spritenum;
+ int base;
+
+ if (HASBIT(v->u.rail.flags, VRF_REVERSE_DIRECTION)) direction = ReverseDir(direction);
+
+ if (is_custom_sprite(img)) {
+ base = GetCustomVehicleSprite(v, direction + 4 * IS_CUSTOM_SECONDHEAD_SPRITE(img));
+ if (base != 0) return base;
+ img = orig_rail_vehicle_info[v->engine_type].image_index;
+ }
+
+ base = _engine_sprite_base[img] + ((direction + _engine_sprite_add[img]) & _engine_sprite_and[img]);
+
+ if (v->cargo_count >= v->cargo_cap / 2) base += _wagon_full_adder[img];
+ return base;
+}
+
+void DrawTrainEngine(int x, int y, EngineID engine, uint32 image_ormod)
+{
+ const RailVehicleInfo *rvi = RailVehInfo(engine);
+
+ int img = rvi->image_index;
+ uint32 image = 0;
+
+ if (is_custom_sprite(img)) {
+ image = GetCustomVehicleIcon(engine, DIR_W);
+ if (image == 0) {
+ img = orig_rail_vehicle_info[engine].image_index;
+ } else {
+ y += _traininfo_vehicle_pitch;
+ }
+ }
+ if (image == 0) {
+ image = (6 & _engine_sprite_and[img]) + _engine_sprite_base[img];
+ }
+
+ if (rvi->flags & RVI_MULTIHEAD) {
+ DrawSprite(image | image_ormod, x - 14, y);
+ x += 15;
+ image = 0;
+ if (is_custom_sprite(img)) {
+ image = GetCustomVehicleIcon(engine, 2);
+ if (image == 0) img = orig_rail_vehicle_info[engine].image_index;
+ }
+ if (image == 0) {
+ image =
+ ((6 + _engine_sprite_add[img + 1]) & _engine_sprite_and[img + 1]) +
+ _engine_sprite_base[img + 1];
+ }
+ }
+ DrawSprite(image | image_ormod, x, y);
+}
+
+uint CountArticulatedParts(EngineID engine_type)
+{
+ uint16 callback;
+ uint i;
+
+ if (!HASBIT(EngInfo(engine_type)->callbackmask, CBM_ARTIC_ENGINE)) return 0;
+
+ for (i = 1; i < 10; i++) {
+ callback = GetVehicleCallback(CBID_TRAIN_ARTIC_ENGINE, i, 0, engine_type, NULL);
+ if (callback == CALLBACK_FAILED || callback == 0xFF) break;
+ }
+
+ return i - 1;
+}
+
+static void AddArticulatedParts(Vehicle **vl)
+{
+ const RailVehicleInfo *rvi_artic;
+ EngineID engine_type;
+ Vehicle *v = vl[0];
+ Vehicle *u = v;
+ uint16 callback;
+ bool flip_image;
+ uint i;
+
+ if (!HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_ARTIC_ENGINE)) return;
+
+ for (i = 1; i < 10; i++) {
+ callback = GetVehicleCallback(CBID_TRAIN_ARTIC_ENGINE, i, 0, v->engine_type, v);
+ if (callback == CALLBACK_FAILED || callback == 0xFF) return;
+
+ /* Attempt to use pre-allocated vehicles until they run out. This can happen
+ * if the callback returns different values depending on the cargo type. */
+ u->next = vl[i];
+ if (u->next == NULL) u->next = AllocateVehicle();
+ if (u->next == NULL) return;
+
+ u = u->next;
+
+ engine_type = GB(callback, 0, 7);
+ flip_image = HASBIT(callback, 7);
+ rvi_artic = RailVehInfo(engine_type);
+
+ // get common values from first engine
+ u->direction = v->direction;
+ u->owner = v->owner;
+ u->tile = v->tile;
+ u->x_pos = v->x_pos;
+ u->y_pos = v->y_pos;
+ u->z_pos = v->z_pos;
+ u->z_height = v->z_height;
+ u->u.rail.track = v->u.rail.track;
+ u->u.rail.railtype = v->u.rail.railtype;
+ u->build_year = v->build_year;
+ u->vehstatus = v->vehstatus & ~VS_STOPPED;
+ u->u.rail.first_engine = v->engine_type;
+
+ // get more settings from rail vehicle info
+ u->spritenum = rvi_artic->image_index;
+ if (flip_image) u->spritenum++;
+ u->cargo_type = rvi_artic->cargo_type;
+ u->cargo_subtype = 0;
+ u->cargo_cap = rvi_artic->capacity;
+ u->max_speed = 0;
+ u->max_age = 0;
+ u->engine_type = engine_type;
+ u->value = 0;
+ u->type = VEH_Train;
+ u->subtype = 0;
+ SetArticulatedPart(u);
+ u->cur_image = 0xAC2;
+ u->random_bits = VehicleRandomBits();
+
+ VehiclePositionChanged(u);
+ }
+}
+
+static int32 CmdBuildRailWagon(EngineID engine, TileIndex tile, uint32 flags)
+{
+ int32 value;
+ const RailVehicleInfo *rvi;
+ uint num_vehicles;
+
+ SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
+
+ rvi = RailVehInfo(engine);
+ value = (rvi->base_cost * _price.build_railwagon) >> 8;
+
+ num_vehicles = 1 + CountArticulatedParts(engine);
+
+ if (!(flags & DC_QUERY_COST)) {
+ Vehicle *vl[11]; // Allow for wagon and upto 10 artic parts.
+ Vehicle* v;
+ int x;
+ int y;
+
+ memset(&vl, 0, sizeof(vl));
+
+ if (!AllocateVehicles(vl, num_vehicles))
+ return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
+
+ if (flags & DC_EXEC) {
+ Vehicle *u, *w;
+ DiagDirection dir;
+
+ v = vl[0];
+ v->spritenum = rvi->image_index;
+
+ u = NULL;
+
+ FOR_ALL_VEHICLES(w) {
+ if (w->type == VEH_Train && w->tile == tile &&
+ IsFreeWagon(w) && w->engine_type == engine) {
+ u = GetLastVehicleInChain(w);
+ break;
+ }
+ }
+
+ v->engine_type = engine;
+
+ dir = GetRailDepotDirection(tile);
+
+ v->direction = DiagDirToDir(dir);
+ v->tile = tile;
+
+ x = TileX(tile) * TILE_SIZE | _vehicle_initial_x_fract[dir];
+ y = TileY(tile) * TILE_SIZE | _vehicle_initial_y_fract[dir];
+
+ v->x_pos = x;
+ v->y_pos = y;
+ v->z_pos = GetSlopeZ(x,y);
+ v->owner = _current_player;
+ v->z_height = 6;
+ v->u.rail.track = 0x80;
+ v->vehstatus = VS_HIDDEN | VS_DEFPAL;
+
+ v->subtype = 0;
+ SetTrainWagon(v);
+ if (u != NULL) {
+ u->next = v;
+ } else {
+ SetFreeWagon(v);
+ InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
+ }
+
+ v->cargo_type = rvi->cargo_type;
+ v->cargo_subtype = 0;
+ v->cargo_cap = rvi->capacity;
+ v->value = value;
+// v->day_counter = 0;
+
+ v->u.rail.railtype = GetEngine(engine)->railtype;
+
+ v->build_year = _cur_year;
+ v->type = VEH_Train;
+ v->cur_image = 0xAC2;
+ v->random_bits = VehicleRandomBits();
+
+ AddArticulatedParts(vl);
+
+ _new_vehicle_id = v->index;
+
+ VehiclePositionChanged(v);
+ TrainConsistChanged(GetFirstVehicleInChain(v));
+ GetPlayer(_current_player)->num_engines[engine]++;
+
+ InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
+ if (IsLocalPlayer()) {
+ InvalidateWindow(WC_REPLACE_VEHICLE, VEH_Train); // updates the replace Train window
+ }
+ }
+ }
+
+ return value;
+}
+
+// Move all free vehicles in the depot to the train
+static void NormalizeTrainVehInDepot(const Vehicle* u)
+{
+ const Vehicle* v;
+
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == VEH_Train && IsFreeWagon(v) &&
+ v->tile == u->tile &&
+ v->u.rail.track == 0x80) {
+ if (CmdFailed(DoCommand(0, v->index | (u->index << 16), 1, DC_EXEC,
+ CMD_MOVE_RAIL_VEHICLE)))
+ break;
+ }
+ }
+}
+
+static int32 EstimateTrainCost(const RailVehicleInfo* rvi)
+{
+ return rvi->base_cost * (_price.build_railvehicle >> 3) >> 5;
+}
+
+static void AddRearEngineToMultiheadedTrain(Vehicle* v, Vehicle* u, bool building)
+{
+ u->direction = v->direction;
+ u->owner = v->owner;
+ u->tile = v->tile;
+ u->x_pos = v->x_pos;
+ u->y_pos = v->y_pos;
+ u->z_pos = v->z_pos;
+ u->z_height = 6;
+ u->u.rail.track = 0x80;
+ u->vehstatus = v->vehstatus & ~VS_STOPPED;
+ u->subtype = 0;
+ SetMultiheaded(u);
+ u->spritenum = v->spritenum + 1;
+ u->cargo_type = v->cargo_type;
+ u->cargo_subtype = v->cargo_subtype;
+ u->cargo_cap = v->cargo_cap;
+ u->u.rail.railtype = v->u.rail.railtype;
+ if (building) v->next = u;
+ u->engine_type = v->engine_type;
+ u->build_year = v->build_year;
+ if (building) v->value >>= 1;
+ u->value = v->value;
+ u->type = VEH_Train;
+ u->cur_image = 0xAC2;
+ u->random_bits = VehicleRandomBits();
+ VehiclePositionChanged(u);
+}
+
+/** Build a railroad vehicle.
+ * @param tile tile of the depot where rail-vehicle is built
+ * @param p1 engine type id
+ * @param p2 bit 0 when set, the train will get number 0, otherwise it will get a free number
+ * bit 1 prevents any free cars from being added to the train
+ */
+int32 CmdBuildRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ const RailVehicleInfo *rvi;
+ int value;
+ Vehicle *v;
+ UnitID unit_num;
+ Engine *e;
+ uint num_vehicles;
+
+ /* Check if the engine-type is valid (for the player) */
+ if (!IsEngineBuildable(p1, VEH_Train, _current_player)) return_cmd_error(STR_ENGINE_NOT_BUILDABLE);
+
+ /* Check if the train is actually being built in a depot belonging
+ * to the player. Doesn't matter if only the cost is queried */
+ if (!(flags & DC_QUERY_COST)) {
+ if (!IsTileDepotType(tile, TRANSPORT_RAIL)) return CMD_ERROR;
+ if (!IsTileOwner(tile, _current_player)) return CMD_ERROR;
+ }
+
+ SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
+
+ rvi = RailVehInfo(p1);
+ e = GetEngine(p1);
+
+ /* Check if depot and new engine uses the same kind of tracks */
+ /* We need to see if the engine got power on the tile to avoid eletric engines in non-electric depots */
+ if (!HasPowerOnRail(e->railtype, GetRailType(tile))) return CMD_ERROR;
+
+ if (rvi->flags & RVI_WAGON) return CmdBuildRailWagon(p1, tile, flags);
+
+ value = EstimateTrainCost(rvi);
+
+ num_vehicles = (rvi->flags & RVI_MULTIHEAD) ? 2 : 1;
+ num_vehicles += CountArticulatedParts(p1);
+
+ if (!(flags & DC_QUERY_COST)) {
+ Vehicle *vl[12]; // Allow for upto 10 artic parts and dual-heads
+
+ memset(&vl, 0, sizeof(vl));
+
+ if (!AllocateVehicles(vl, num_vehicles) || IsOrderPoolFull())
+ return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
+
+ v = vl[0];
+
+ unit_num = HASBIT(p2, 0) ? 0 : GetFreeUnitNumber(VEH_Train);
+ if (unit_num > _patches.max_trains)
+ return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
+
+ if (flags & DC_EXEC) {
+ DiagDirection dir = GetRailDepotDirection(tile);
+ int x = TileX(tile) * TILE_SIZE + _vehicle_initial_x_fract[dir];
+ int y = TileY(tile) * TILE_SIZE + _vehicle_initial_y_fract[dir];
+
+ v->unitnumber = unit_num;
+ v->direction = DiagDirToDir(dir);
+ v->tile = tile;
+ v->owner = _current_player;
+ v->x_pos = x;
+ v->y_pos = y;
+ v->z_pos = GetSlopeZ(x,y);
+ v->z_height = 6;
+ v->u.rail.track = 0x80;
+ v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
+ v->spritenum = rvi->image_index;
+ v->cargo_type = rvi->cargo_type;
+ v->cargo_subtype = 0;
+ v->cargo_cap = rvi->capacity;
+ v->max_speed = rvi->max_speed;
+ v->value = value;
+ v->last_station_visited = INVALID_STATION;
+ v->dest_tile = 0;
+
+ v->engine_type = p1;
+
+ v->reliability = e->reliability;
+ v->reliability_spd_dec = e->reliability_spd_dec;
+ v->max_age = e->lifelength * 366;
+
+ v->string_id = STR_SV_TRAIN_NAME;
+ v->u.rail.railtype = e->railtype;
+ _new_vehicle_id = v->index;
+
+ v->service_interval = _patches.servint_trains;
+ v->date_of_last_service = _date;
+ v->build_year = _cur_year;
+ v->type = VEH_Train;
+ v->cur_image = 0xAC2;
+ v->random_bits = VehicleRandomBits();
+
+ v->subtype = 0;
+ SetFrontEngine(v);
+ SetTrainEngine(v);
+
+ VehiclePositionChanged(v);
+
+ if (rvi->flags & RVI_MULTIHEAD) {
+ SetMultiheaded(v);
+ AddRearEngineToMultiheadedTrain(vl[0], vl[1], true);
+ /* Now we need to link the front and rear engines together
+ * other_multiheaded_part is the pointer that links to the other half of the engine
+ * vl[0] is the front and vl[1] is the rear
+ */
+ vl[0]->u.rail.other_multiheaded_part = vl[1];
+ vl[1]->u.rail.other_multiheaded_part = vl[0];
+ } else {
+ AddArticulatedParts(vl);
+ }
+
+ TrainConsistChanged(v);
+ UpdateTrainAcceleration(v);
+
+ if (!HASBIT(p2, 1)) { // check if the cars should be added to the new vehicle
+ NormalizeTrainVehInDepot(v);
+ }
+
+ GetPlayer(_current_player)->num_engines[p1]++;
+ InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
+ RebuildVehicleLists();
+ InvalidateWindow(WC_COMPANY, v->owner);
+ if (IsLocalPlayer()) {
+ InvalidateWindow(WC_REPLACE_VEHICLE, VEH_Train); // updates the replace Train window
+ }
+ }
+ }
+
+ return value;
+}
+
+
+/* Check if all the wagons of the given train are in a depot, returns the
+ * number of cars (including loco) then. If not it returns -1 */
+int CheckTrainInDepot(const Vehicle *v, bool needs_to_be_stopped)
+{
+ int count;
+ TileIndex tile = v->tile;
+
+ /* check if stopped in a depot */
+ if (!IsTileDepotType(tile, TRANSPORT_RAIL) || v->cur_speed != 0) return -1;
+
+ count = 0;
+ for (; v != NULL; v = v->next) {
+ /* This count is used by the depot code to determine the number of engines
+ * in the consist. Exclude articulated parts so that autoreplacing to
+ * engines with more articulated parts than before works correctly.
+ *
+ * Also skip counting rear ends of multiheaded engines */
+ if (!IsArticulatedPart(v) && !(!IsTrainEngine(v) && IsMultiheaded(v))) count++;
+ if (v->u.rail.track != 0x80 || v->tile != tile ||
+ (IsFrontEngine(v) && needs_to_be_stopped && !(v->vehstatus & VS_STOPPED))) {
+ return -1;
+ }
+ }
+
+ return count;
+}
+
+/* Used to check if the train is inside the depot and verifying that the VS_STOPPED flag is set */
+inline int CheckTrainStoppedInDepot(const Vehicle *v)
+{
+ return CheckTrainInDepot(v, true);
+}
+
+/* Used to check if the train is inside the depot, but not checking the VS_STOPPED flag */
+inline bool CheckTrainIsInsideDepot(const Vehicle *v)
+{
+ return (CheckTrainInDepot(v, false) > 0);
+}
+
+/**
+ * Unlink a rail wagon from the consist.
+ * @param v Vehicle to remove.
+ * @param first The first vehicle of the consist.
+ * @return The first vehicle of the consist.
+ */
+static Vehicle *UnlinkWagon(Vehicle *v, Vehicle *first)
+{
+ Vehicle *u;
+
+ // unlinking the first vehicle of the chain?
+ if (v == first) {
+ v = GetNextVehicle(v);
+ if (v == NULL) return NULL;
+
+ if (IsTrainWagon(v)) SetFreeWagon(v);
+
+ return v;
+ }
+
+ for (u = first; GetNextVehicle(u) != v; u = GetNextVehicle(u)) {}
+ GetLastEnginePart(u)->next = GetNextVehicle(v);
+ return first;
+}
+
+static Vehicle *FindGoodVehiclePos(const Vehicle *src)
+{
+ Vehicle *dst;
+ EngineID eng = src->engine_type;
+ TileIndex tile = src->tile;
+
+ FOR_ALL_VEHICLES(dst) {
+ if (dst->type == VEH_Train && IsFreeWagon(dst) && dst->tile == tile) {
+ // check so all vehicles in the line have the same engine.
+ Vehicle *v = dst;
+
+ while (v->engine_type == eng) {
+ v = v->next;
+ if (v == NULL) return dst;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+/*
+ * add a vehicle v behind vehicle dest
+ * use this function since it sets flags as needed
+ */
+static void AddWagonToConsist(Vehicle *v, Vehicle *dest)
+{
+ UnlinkWagon(v, GetFirstVehicleInChain(v));
+ if (dest == NULL) return;
+
+ v->next = dest->next;
+ dest->next = v;
+ ClearFreeWagon(v);
+ ClearFrontEngine(v);
+}
+
+/*
+ * move around on the train so rear engines are placed correctly according to the other engines
+ * always call with the front engine
+ */
+static void NormaliseTrainConsist(Vehicle *v)
+{
+ Vehicle *u;
+
+ if (IsFreeWagon(v)) return;
+
+ assert(IsFrontEngine(v));
+
+ for (; v != NULL; v = GetNextVehicle(v)) {
+ if (!IsMultiheaded(v) || !IsTrainEngine(v)) continue;
+
+ /* make sure that there are no free cars before next engine */
+ for (u = v; u->next != NULL && !IsTrainEngine(u->next); u = u->next);
+
+ if (u == v->u.rail.other_multiheaded_part) continue;
+ AddWagonToConsist(v->u.rail.other_multiheaded_part, u);
+ }
+}
+
+/** Move a rail vehicle around inside the depot.
+ * @param tile unused
+ * @param p1 various bitstuffed elements
+ * - p1 (bit 0 - 15) source vehicle index
+ * - p1 (bit 16 - 31) what wagon to put the source wagon AFTER, XXX - INVALID_VEHICLE to make a new line
+ * @param p2 (bit 0) move all vehicles following the source vehicle
+ */
+int32 CmdMoveRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ VehicleID s = GB(p1, 0, 16);
+ VehicleID d = GB(p1, 16, 16);
+ Vehicle *src, *dst, *src_head, *dst_head;
+
+ if (!IsValidVehicleID(s)) return CMD_ERROR;
+
+ src = GetVehicle(s);
+
+ if (src->type != VEH_Train) return CMD_ERROR;
+
+ // if nothing is selected as destination, try and find a matching vehicle to drag to.
+ if (d == INVALID_VEHICLE) {
+ dst = IsTrainEngine(src) ? NULL : FindGoodVehiclePos(src);
+ } else {
+ dst = GetVehicle(d);
+ }
+
+ // if an articulated part is being handled, deal with its parent vehicle
+ while (IsArticulatedPart(src)) src = GetPrevVehicleInChain(src);
+ if (dst != NULL) {
+ while (IsArticulatedPart(dst)) dst = GetPrevVehicleInChain(dst);
+ }
+
+ // don't move the same vehicle..
+ if (src == dst) return 0;
+
+ /* the player must be the owner */
+ if (!CheckOwnership(src->owner) || (dst != NULL && !CheckOwnership(dst->owner)))
+ return CMD_ERROR;
+
+ /* locate the head of the two chains */
+ src_head = GetFirstVehicleInChain(src);
+ dst_head = NULL;
+ if (dst != NULL) {
+ dst_head = GetFirstVehicleInChain(dst);
+ // Now deal with articulated part of destination wagon
+ dst = GetLastEnginePart(dst);
+ }
+
+ if (dst != NULL && IsMultiheaded(dst) && !IsTrainEngine(dst) && IsTrainWagon(src)) {
+ /* We are moving a wagon to the rear part of a multiheaded engine */
+ if (dst->next == NULL) {
+ /* It's the last one, so we will add the wagon just before the rear engine */
+ dst = GetPrevVehicleInChain(dst);
+ /* Now if the vehicle we want to link to is the vehicle itself, drop out */
+ if (dst == src) return CMD_ERROR;
+ // if dst is NULL, it means that dst got a rear multiheaded engine as first engine. We can't use that
+ if (dst == NULL) return CMD_ERROR;
+ } else {
+ /* there are more units on this train, so we will add the wagon after the next one*/
+ dst = dst->next;
+ }
+ }
+
+ if (IsTrainEngine(src) && dst_head != NULL) {
+ /* we need to make sure that we didn't place it between a pair of multiheaded engines */
+ Vehicle *u, *engine = NULL;
+
+ for (u = dst_head; u != NULL; u = u->next) {
+ if (IsTrainEngine(u) && IsMultiheaded(u) && u->u.rail.other_multiheaded_part != NULL) {
+ engine = u;
+ }
+ if (engine != NULL && engine->u.rail.other_multiheaded_part == u) {
+ engine = NULL;
+ }
+ if (u == dst) {
+ if (engine != NULL) dst = engine->u.rail.other_multiheaded_part;
+ break;
+ }
+ }
+ }
+
+ if (IsMultiheaded(src) && !IsTrainEngine(src)) return_cmd_error(STR_REAR_ENGINE_FOLLOW_FRONT_ERROR);
+
+ // when moving all wagons, we can't have the same src_head and dst_head
+ if (HASBIT(p2, 0) && src_head == dst_head) return 0;
+
+ {
+ int src_len = 0;
+ int max_len = _patches.mammoth_trains ? 100 : 9;
+
+ // check if all vehicles in the source train are stopped inside a depot.
+ src_len = CheckTrainStoppedInDepot(src_head);
+ if (src_len < 0) return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
+
+ // check the destination row if the source and destination aren't the same.
+ if (src_head != dst_head) {
+ int dst_len = 0;
+
+ if (dst_head != NULL) {
+ // check if all vehicles in the dest train are stopped.
+ dst_len = CheckTrainStoppedInDepot(dst_head);
+ if (dst_len < 0) return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
+
+ assert(dst_head->tile == src_head->tile);
+ }
+
+ // We are moving between rows, so only count the wagons from the source
+ // row that are being moved.
+ if (HASBIT(p2, 0)) {
+ const Vehicle *u;
+ for (u = src_head; u != src && u != NULL; u = GetNextVehicle(u))
+ src_len--;
+ } else {
+ // If moving only one vehicle, just count that.
+ src_len = 1;
+ }
+
+ if (src_len + dst_len > max_len) {
+ // Abort if we're adding too many wagons to a train.
+ if (dst_head != NULL && IsFrontEngine(dst_head)) return_cmd_error(STR_8819_TRAIN_TOO_LONG);
+ // Abort if we're making a train on a new row.
+ if (dst_head == NULL && IsTrainEngine(src)) return_cmd_error(STR_8819_TRAIN_TOO_LONG);
+ }
+ } else {
+ // Abort if we're creating a new train on an existing row.
+ if (src_len > max_len && src == src_head && IsTrainEngine(GetNextVehicle(src_head)))
+ return_cmd_error(STR_8819_TRAIN_TOO_LONG);
+ }
+ }
+
+ // moving a loco to a new line?, then we need to assign a unitnumber.
+ if (dst == NULL && !IsFrontEngine(src) && IsTrainEngine(src)) {
+ UnitID unit_num = GetFreeUnitNumber(VEH_Train);
+ if (unit_num > _patches.max_trains)
+ return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
+
+ if (flags & DC_EXEC) src->unitnumber = unit_num;
+ }
+
+ if (dst_head != NULL) {
+ /* Check NewGRF Callback 0x1D */
+ uint16 callback = GetVehicleCallbackParent(CBID_TRAIN_ALLOW_WAGON_ATTACH, 0, 0, dst_head->engine_type, src, dst_head);
+ if (callback != CALLBACK_FAILED) {
+ if (callback == 0xFD) return_cmd_error(STR_INCOMPATIBLE_RAIL_TYPES);
+ if (callback < 0xFD) {
+ StringID error = GetGRFStringID(GetEngineGRFID(dst_head->engine_type), 0xD000 + callback);
+ return_cmd_error(error);
+ }
+ }
+ }
+
+ /* do it? */
+ if (flags & DC_EXEC) {
+ /* clear the ->first cache */
+ {
+ Vehicle *u;
+
+ for (u = src_head; u != NULL; u = u->next) u->first = NULL;
+ for (u = dst_head; u != NULL; u = u->next) u->first = NULL;
+ }
+
+ if (HASBIT(p2, 0)) {
+ // unlink ALL wagons
+ if (src != src_head) {
+ Vehicle *v = src_head;
+ while (GetNextVehicle(v) != src) v = GetNextVehicle(v);
+ GetLastEnginePart(v)->next = NULL;
+ } else {
+ InvalidateWindowData(WC_VEHICLE_DEPOT, src_head->tile); // We removed a line
+ src_head = NULL;
+ }
+ } else {
+ // if moving within the same chain, dont use dst_head as it may get invalidated
+ if (src_head == dst_head) dst_head = NULL;
+ // unlink single wagon from linked list
+ src_head = UnlinkWagon(src, src_head);
+ GetLastEnginePart(src)->next = NULL;
+ }
+
+ if (dst == NULL) {
+ /* We make a new line in the depot, so we know already that we invalidate the window data */
+ InvalidateWindowData(WC_VEHICLE_DEPOT, src->tile);
+
+ // move the train to an empty line. for locomotives, we set the type to TS_Front. for wagons, 4.
+ if (IsTrainEngine(src)) {
+ if (!IsFrontEngine(src)) {
+ // setting the type to 0 also involves setting up the orders field.
+ SetFrontEngine(src);
+ assert(src->orders == NULL);
+ src->num_orders = 0;
+ }
+ } else {
+ SetFreeWagon(src);
+ }
+ dst_head = src;
+ } else {
+ if (IsFrontEngine(src)) {
+ // the vehicle was previously a loco. need to free the order list and delete vehicle windows etc.
+ DeleteWindowById(WC_VEHICLE_VIEW, src->index);
+ DeleteVehicleOrders(src);
+ }
+
+ if (IsFrontEngine(src) || IsFreeWagon(src)) {
+ InvalidateWindowData(WC_VEHICLE_DEPOT, src->tile);
+ ClearFrontEngine(src);
+ ClearFreeWagon(src);
+ src->unitnumber = 0; // doesn't occupy a unitnumber anymore.
+ }
+
+ // link in the wagon(s) in the chain.
+ {
+ Vehicle *v;
+
+ for (v = src; GetNextVehicle(v) != NULL; v = GetNextVehicle(v));
+ GetLastEnginePart(v)->next = dst->next;
+ }
+ dst->next = src;
+ }
+ if (src->u.rail.other_multiheaded_part != NULL) {
+ if (src->u.rail.other_multiheaded_part == src_head) {
+ src_head = src_head->next;
+ }
+ AddWagonToConsist(src->u.rail.other_multiheaded_part, src);
+ // previous line set the front engine to the old front. We need to clear that
+ src->u.rail.other_multiheaded_part->first = NULL;
+ }
+
+ if (HASBIT(p2, 0) && src_head != NULL && src_head != src) {
+ /* if we stole a rear multiheaded engine, we better give it back to the front end */
+ Vehicle *engine = NULL, *u;
+ for (u = src_head; u != NULL; u = u->next) {
+ if (IsMultiheaded(u)) {
+ if (IsTrainEngine(u)) {
+ engine = u;
+ continue;
+ }
+ /* we got the rear engine to match with the front one */
+ engine = NULL;
+ }
+ }
+ if (engine != NULL && engine->u.rail.other_multiheaded_part != NULL) {
+ AddWagonToConsist(engine->u.rail.other_multiheaded_part, engine);
+ // previous line set the front engine to the old front. We need to clear that
+ engine->u.rail.other_multiheaded_part->first = NULL;
+ }
+ }
+
+ /* If there is an engine behind first_engine we moved away, it should become new first_engine
+ * To do this, CmdMoveRailVehicle must be called once more
+ * we can't loop forever here because next time we reach this line we will have a front engine */
+ if (src_head != NULL && !IsFrontEngine(src_head) && IsTrainEngine(src_head)) {
+ CmdMoveRailVehicle(0, flags, src_head->index | (INVALID_VEHICLE << 16), 1);
+ src_head = NULL; // don't do anything more to this train since the new call will do it
+ }
+
+ if (src_head != NULL) {
+ NormaliseTrainConsist(src_head);
+ TrainConsistChanged(src_head);
+ if (IsFrontEngine(src_head)) {
+ UpdateTrainAcceleration(src_head);
+ InvalidateWindow(WC_VEHICLE_DETAILS, src_head->index);
+ /* Update the refit button and window */
+ InvalidateWindow(WC_VEHICLE_REFIT, src_head->index);
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, src_head->index, 12);
+ }
+ /* Update the depot window */
+ InvalidateWindow(WC_VEHICLE_DEPOT, src_head->tile);
+ };
+
+ if (dst_head != NULL) {
+ NormaliseTrainConsist(dst_head);
+ TrainConsistChanged(dst_head);
+ if (IsFrontEngine(dst_head)) {
+ UpdateTrainAcceleration(dst_head);
+ InvalidateWindow(WC_VEHICLE_DETAILS, dst_head->index);
+ /* Update the refit button and window */
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, dst_head->index, 12);
+ InvalidateWindow(WC_VEHICLE_REFIT, dst_head->index);
+ }
+ /* Update the depot window */
+ InvalidateWindow(WC_VEHICLE_DEPOT, dst_head->tile);
+ }
+
+ RebuildVehicleLists();
+ }
+
+ return 0;
+}
+
+/** Start/Stop a train.
+ * @param tile unused
+ * @param p1 train to start/stop
+ * @param p2 unused
+ */
+int32 CmdStartStopTrain(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle *v;
+ uint16 callback;
+
+ if (!IsValidVehicleID(p1)) return CMD_ERROR;
+
+ v = GetVehicle(p1);
+
+ if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
+
+ /* Check if this train can be started/stopped. The callback will fail or
+ * return 0xFF if it can. */
+ callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
+ if (callback != CALLBACK_FAILED && callback != 0xFF) {
+ StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
+ return_cmd_error(error);
+ }
+
+ if (v->vehstatus & VS_STOPPED && v->u.rail.cached_power == 0) return_cmd_error(STR_TRAIN_START_NO_CATENARY);
+
+ if (flags & DC_EXEC) {
+ if (v->vehstatus & VS_STOPPED && v->u.rail.track == 0x80) {
+ DeleteVehicleNews(p1, STR_8814_TRAIN_IS_WAITING_IN_DEPOT);
+ }
+
+ v->u.rail.days_since_order_progr = 0;
+ v->vehstatus ^= VS_STOPPED;
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
+ }
+ return 0;
+}
+
+/** Sell a (single) train wagon/engine.
+ * @param tile unused
+ * @param p1 the wagon/engine index
+ * @param p2 the selling mode
+ * - p2 = 0: only sell the single dragged wagon/engine (and any belonging rear-engines)
+ * - p2 = 1: sell the vehicle and all vehicles following it in the chain
+ if the wagon is dragged, don't delete the possibly belonging rear-engine to some front
+ * - p2 = 2: when selling attached locos, rearrange all vehicles after it to separate lines;
+ * all wagons of the same type will go on the same line. Used by the AI currently
+ */
+int32 CmdSellRailWagon(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle *v, *tmp, *first;
+ Vehicle *new_f = NULL;
+ int32 cost = 0;
+
+ if (!IsValidVehicleID(p1) || p2 > 2) return CMD_ERROR;
+
+ v = GetVehicle(p1);
+
+ if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
+
+ SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
+
+ while (IsArticulatedPart(v)) v = GetPrevVehicleInChain(v);
+ first = GetFirstVehicleInChain(v);
+
+ // make sure the vehicle is stopped in the depot
+ if (CheckTrainStoppedInDepot(first) < 0) {
+ return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
+ }
+
+ if (IsMultiheaded(v) && !IsTrainEngine(v)) return_cmd_error(STR_REAR_ENGINE_FOLLOW_FRONT_ERROR);
+
+ if (flags & DC_EXEC) {
+ if (v == first && IsFrontEngine(first)) {
+ DeleteWindowById(WC_VEHICLE_VIEW, first->index);
+ }
+ if (IsLocalPlayer() && (p1 == 1 || !(RailVehInfo(v->engine_type)->flags & RVI_WAGON))) {
+ InvalidateWindow(WC_REPLACE_VEHICLE, VEH_Train);
+ }
+ InvalidateWindow(WC_VEHICLE_DEPOT, first->tile);
+ RebuildVehicleLists();
+ }
+
+ switch (p2) {
+ case 0: case 2: { /* Delete given wagon */
+ bool switch_engine = false; // update second wagon to engine?
+ byte ori_subtype = v->subtype; // backup subtype of deleted wagon in case DeleteVehicle() changes
+
+ /* 1. Delete the engine, if it is dualheaded also delete the matching
+ * rear engine of the loco (from the point of deletion onwards) */
+ Vehicle *rear = (IsMultiheaded(v) &&
+ IsTrainEngine(v)) ? v->u.rail.other_multiheaded_part : NULL;
+
+ if (rear != NULL) {
+ cost -= rear->value;
+ if (flags & DC_EXEC) {
+ UnlinkWagon(rear, first);
+ DeleteDepotHighlightOfVehicle(rear);
+ DeleteVehicle(rear);
+ }
+ }
+
+ /* 2. We are selling the first engine, some special action might be required
+ * here, so take attention */
+ if ((flags & DC_EXEC) && v == first) {
+ new_f = GetNextVehicle(first);
+
+ /* 2.1 If the first wagon is sold, update the first-> pointers to NULL */
+ for (tmp = first; tmp != NULL; tmp = tmp->next) tmp->first = NULL;
+
+ /* 2.2 If there are wagons present after the deleted front engine, check
+ * if the second wagon (which will be first) is an engine. If it is one,
+ * promote it as a new train, retaining the unitnumber, orders */
+ if (new_f != NULL) {
+ if (IsTrainEngine(new_f)) {
+ switch_engine = true;
+ /* Copy important data from the front engine */
+ new_f->unitnumber = first->unitnumber;
+ new_f->current_order = first->current_order;
+ new_f->cur_order_index = first->cur_order_index;
+ new_f->orders = first->orders;
+ if (first->prev_shared != NULL) {
+ first->prev_shared->next_shared = new_f;
+ new_f->prev_shared = first->prev_shared;
+ }
+
+ if (first->next_shared != NULL) {
+ first->next_shared->prev_shared = new_f;
+ new_f->next_shared = first->next_shared;
+ }
+
+ new_f->num_orders = first->num_orders;
+ first->orders = NULL; // XXX - to not to delete the orders */
+ if (IsLocalPlayer()) ShowTrainViewWindow(new_f);
+ }
+ }
+ }
+
+ /* 3. Delete the requested wagon */
+ cost -= v->value;
+ if (flags & DC_EXEC) {
+ first = UnlinkWagon(v, first);
+ DeleteDepotHighlightOfVehicle(v);
+ DeleteVehicle(v);
+
+ /* 4 If the second wagon was an engine, update it to front_engine
+ * which UnlinkWagon() has changed to TS_Free_Car */
+ if (switch_engine) SetFrontEngine(first);
+
+ /* 5. If the train still exists, update its acceleration, window, etc. */
+ if (first != NULL) {
+ NormaliseTrainConsist(first);
+ TrainConsistChanged(first);
+ if (IsFrontEngine(first)) {
+ InvalidateWindow(WC_VEHICLE_DETAILS, first->index);
+ InvalidateWindow(WC_VEHICLE_REFIT, first->index);
+ UpdateTrainAcceleration(first);
+ }
+ }
+
+
+ /* (6.) Borked AI. If it sells an engine it expects all wagons lined
+ * up on a new line to be added to the newly built loco. Replace it is.
+ * Totally braindead cause building a new engine adds all loco-less
+ * engines to its train anyways */
+ if (p2 == 2 && HASBIT(ori_subtype, Train_Front)) {
+ for (v = first; v != NULL; v = tmp) {
+ tmp = GetNextVehicle(v);
+ DoCommand(v->tile, v->index | INVALID_VEHICLE << 16, 0, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
+ }
+ }
+ }
+ } break;
+ case 1: { /* Delete wagon and all wagons after it given certain criteria */
+ /* Start deleting every vehicle after the selected one
+ * If we encounter a matching rear-engine to a front-engine
+ * earlier in the chain (before deletion), leave it alone */
+ for (; v != NULL; v = tmp) {
+ tmp = GetNextVehicle(v);
+
+ if (IsMultiheaded(v)) {
+ if (IsTrainEngine(v)) {
+ /* We got a front engine of a multiheaded set. Now we will sell the rear end too */
+ Vehicle *rear = v->u.rail.other_multiheaded_part;
+
+ if (rear != NULL) {
+ cost -= rear->value;
+ if (flags & DC_EXEC) {
+ first = UnlinkWagon(rear, first);
+ DeleteDepotHighlightOfVehicle(rear);
+ DeleteVehicle(rear);
+ }
+ }
+ } else if (v->u.rail.other_multiheaded_part != NULL) {
+ /* The front to this engine is earlier in this train. Do nothing */
+ continue;
+ }
+ }
+
+ cost -= v->value;
+ if (flags & DC_EXEC) {
+ first = UnlinkWagon(v, first);
+ DeleteDepotHighlightOfVehicle(v);
+ DeleteVehicle(v);
+ }
+ }
+
+ /* 3. If it is still a valid train after selling, update its acceleration and cached values */
+ if (flags & DC_EXEC && first != NULL) {
+ NormaliseTrainConsist(first);
+ TrainConsistChanged(first);
+ if (IsFrontEngine(first)) UpdateTrainAcceleration(first);
+ InvalidateWindow(WC_VEHICLE_DETAILS, first->index);
+ InvalidateWindow(WC_VEHICLE_REFIT, first->index);
+ }
+ } break;
+ }
+ return cost;
+}
+
+static void UpdateTrainDeltaXY(Vehicle *v, Direction direction)
+{
+#define MKIT(a,b,c,d) ((a&0xFF)<<24) | ((b&0xFF)<<16) | ((c&0xFF)<<8) | ((d&0xFF)<<0)
+ static const uint32 _delta_xy_table[8] = {
+ MKIT(3, 3, -1, -1),
+ MKIT(3, 7, -1, -3),
+ MKIT(3, 3, -1, -1),
+ MKIT(7, 3, -3, -1),
+ MKIT(3, 3, -1, -1),
+ MKIT(3, 7, -1, -3),
+ MKIT(3, 3, -1, -1),
+ MKIT(7, 3, -3, -1),
+ };
+#undef MKIT
+
+ uint32 x = _delta_xy_table[direction];
+
+ v->x_offs = GB(x, 0, 8);
+ v->y_offs = GB(x, 8, 8);
+ v->sprite_width = GB(x, 16, 8);
+ v->sprite_height = GB(x, 24, 8);
+}
+
+static void UpdateVarsAfterSwap(Vehicle *v)
+{
+ UpdateTrainDeltaXY(v, v->direction);
+ v->cur_image = GetTrainImage(v, v->direction);
+ BeginVehicleMove(v);
+ VehiclePositionChanged(v);
+ EndVehicleMove(v);
+}
+
+static void SetLastSpeed(Vehicle* v, int spd)
+{
+ int old = v->u.rail.last_speed;
+ if (spd != old) {
+ v->u.rail.last_speed = spd;
+ if (_patches.vehicle_speed || (old == 0) != (spd == 0))
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ }
+}
+
+static void SwapTrainFlags(byte *swap_flag1, byte *swap_flag2)
+{
+ byte flag1, flag2;
+
+ flag1 = *swap_flag1;
+ flag2 = *swap_flag2;
+
+ /* Clear the flags */
+ CLRBIT(*swap_flag1, VRF_GOINGUP);
+ CLRBIT(*swap_flag1, VRF_GOINGDOWN);
+ CLRBIT(*swap_flag2, VRF_GOINGUP);
+ CLRBIT(*swap_flag2, VRF_GOINGDOWN);
+
+ /* Reverse the rail-flags (if needed) */
+ if (HASBIT(flag1, VRF_GOINGUP)) {
+ SETBIT(*swap_flag2, VRF_GOINGDOWN);
+ } else if (HASBIT(flag1, VRF_GOINGDOWN)) {
+ SETBIT(*swap_flag2, VRF_GOINGUP);
+ }
+ if (HASBIT(flag2, VRF_GOINGUP)) {
+ SETBIT(*swap_flag1, VRF_GOINGDOWN);
+ } else if (HASBIT(flag2, VRF_GOINGDOWN)) {
+ SETBIT(*swap_flag1, VRF_GOINGUP);
+ }
+}
+
+static void ReverseTrainSwapVeh(Vehicle *v, int l, int r)
+{
+ Vehicle *a, *b;
+
+ /* locate vehicles to swap */
+ for (a = v; l != 0; l--) a = a->next;
+ for (b = v; r != 0; r--) b = b->next;
+
+ if (a != b) {
+ /* swap the hidden bits */
+ {
+ uint16 tmp = (a->vehstatus & ~VS_HIDDEN) | (b->vehstatus&VS_HIDDEN);
+ b->vehstatus = (b->vehstatus & ~VS_HIDDEN) | (a->vehstatus&VS_HIDDEN);
+ a->vehstatus = tmp;
+ }
+
+ /* swap variables */
+ swap_byte(&a->u.rail.track, &b->u.rail.track);
+ swap_byte(&a->direction, &b->direction);
+
+ /* toggle direction */
+ if (!(a->u.rail.track & 0x80)) a->direction = ReverseDir(a->direction);
+ if (!(b->u.rail.track & 0x80)) b->direction = ReverseDir(b->direction);
+
+ /* swap more variables */
+ swap_int32(&a->x_pos, &b->x_pos);
+ swap_int32(&a->y_pos, &b->y_pos);
+ swap_tile(&a->tile, &b->tile);
+ swap_byte(&a->z_pos, &b->z_pos);
+
+ SwapTrainFlags(&a->u.rail.flags, &b->u.rail.flags);
+
+ /* update other vars */
+ UpdateVarsAfterSwap(a);
+ UpdateVarsAfterSwap(b);
+
+ /* call the proper EnterTile function unless we are in a wormhole */
+ if (!(a->u.rail.track & 0x40)) VehicleEnterTile(a, a->tile, a->x_pos, a->y_pos);
+ if (!(b->u.rail.track & 0x40)) VehicleEnterTile(b, b->tile, b->x_pos, b->y_pos);
+ } else {
+ if (!(a->u.rail.track & 0x80)) a->direction = ReverseDir(a->direction);
+ UpdateVarsAfterSwap(a);
+
+ if (!(a->u.rail.track & 0x40)) VehicleEnterTile(a, a->tile, a->x_pos, a->y_pos);
+ }
+
+ /* Update train's power incase tiles were different rail type */
+ TrainPowerChanged(v);
+}
+
+/* Check if the vehicle is a train and is on the tile we are testing */
+static void *TestTrainOnCrossing(Vehicle *v, void *data)
+{
+ if (v->tile != *(const TileIndex*)data || v->type != VEH_Train) return NULL;
+ return v;
+}
+
+static void DisableTrainCrossing(TileIndex tile)
+{
+ if (IsLevelCrossingTile(tile) &&
+ VehicleFromPos(tile, &tile, TestTrainOnCrossing) == NULL && // empty?
+ IsCrossingBarred(tile)) {
+ UnbarCrossing(tile);
+ MarkTileDirtyByTile(tile);
+ }
+}
+
+/**
+ * Advances wagons for train reversing, needed for variable length wagons.
+ * Needs to be called once before the train is reversed, and once after it.
+ * @param v First vehicle in chain
+ * @param before Set to true for the call before reversing, false otherwise
+ */
+static void AdvanceWagons(Vehicle *v, bool before)
+{
+ Vehicle* base;
+ Vehicle* first;
+ int length;
+
+ base = v;
+ first = base->next;
+ length = CountVehiclesInChain(v);
+
+ while (length > 2) {
+ Vehicle* last;
+ int differential;
+ int i;
+
+ // find pairwise matching wagon
+ // start<>end, start+1<>end-1, ...
+ last = first;
+ for (i = length - 3; i > 0; i--) last = last->next;
+
+ differential = last->u.rail.cached_veh_length - base->u.rail.cached_veh_length;
+ if (before) differential *= -1;
+
+ if (differential > 0) {
+ Vehicle* tempnext;
+
+ // disconnect last car to make sure only this subset moves
+ tempnext = last->next;
+ last->next = NULL;
+
+ for (i = 0; i < differential; i++) TrainController(first, false);
+
+ last->next = tempnext;
+ }
+
+ base = first;
+ first = first->next;
+ length -= 2;
+ }
+}
+
+
+static void ReverseTrainDirection(Vehicle *v)
+{
+ int l = 0, r = -1;
+ Vehicle *u;
+
+ if (IsTileDepotType(v->tile, TRANSPORT_RAIL)) {
+ InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
+ }
+
+ /* Check if we were approaching a rail/road-crossing */
+ {
+ TileIndex tile = v->tile;
+ DiagDirection dir = DirToDiagDir(v->direction);
+
+ /* Determine the diagonal direction in which we will exit this tile */
+ if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[dir]) {
+ dir = ChangeDiagDir(dir, DIAGDIRDIFF_90LEFT);
+ }
+ /* Calculate next tile */
+ tile += TileOffsByDiagDir(dir);
+
+ /* Check if the train left a rail/road-crossing */
+ DisableTrainCrossing(tile);
+ }
+
+ // count number of vehicles
+ u = v;
+ do r++; while ( (u = u->next) != NULL );
+
+ AdvanceWagons(v, true);
+
+ /* swap start<>end, start+1<>end-1, ... */
+ do {
+ ReverseTrainSwapVeh(v, l++, r--);
+ } while (l <= r);
+
+ AdvanceWagons(v, false);
+
+ if (IsTileDepotType(v->tile, TRANSPORT_RAIL)) {
+ InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
+ }
+
+ CLRBIT(v->u.rail.flags, VRF_REVERSING);
+}
+
+/** Reverse train.
+ * @param tile unused
+ * @param p1 train to reverse
+ * @param p2 if true, reverse a unit in a train (needs to be in a depot)
+ */
+int32 CmdReverseTrainDirection(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle *v;
+
+ if (!IsValidVehicleID(p1)) return CMD_ERROR;
+
+ v = GetVehicle(p1);
+
+ if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
+
+ if (p2) {
+ // turn a single unit around
+ Vehicle *front;
+
+ if (IsMultiheaded(v) || HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_ARTIC_ENGINE)) {
+ return_cmd_error(STR_ONLY_TURN_SINGLE_UNIT);
+ }
+
+ front = GetFirstVehicleInChain(v);
+ // make sure the vehicle is stopped in the depot
+ if (CheckTrainStoppedInDepot(front) < 0) {
+ return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
+ }
+
+ if (flags & DC_EXEC) {
+ TOGGLEBIT(v->u.rail.flags, VRF_REVERSE_DIRECTION);
+ InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
+ InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
+ }
+ } else {
+ //turn the whole train around
+ if (v->u.rail.crash_anim_pos != 0 || v->breakdown_ctr != 0) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ if (_patches.realistic_acceleration && v->cur_speed != 0) {
+ TOGGLEBIT(v->u.rail.flags, VRF_REVERSING);
+ } else {
+ v->cur_speed = 0;
+ SetLastSpeed(v, 0);
+ ReverseTrainDirection(v);
+ }
+ }
+ }
+ return 0;
+}
+
+/** Force a train through a red signal
+ * @param tile unused
+ * @param p1 train to ignore the red signal
+ * @param p2 unused
+ */
+int32 CmdForceTrainProceed(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle *v;
+
+ if (!IsValidVehicleID(p1)) return CMD_ERROR;
+
+ v = GetVehicle(p1);
+
+ if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
+
+ if (flags & DC_EXEC) v->u.rail.force_proceed = 0x50;
+
+ return 0;
+}
+
+/** Refits a train to the specified cargo type.
+ * @param tile unused
+ * @param p1 vehicle ID of the train to refit
+ * param p2 various bitstuffed elements
+ * - p2 = (bit 0-7) - the new cargo type to refit to
+ * - p2 = (bit 8-15) - the new cargo subtype to refit to
+ */
+int32 CmdRefitRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ CargoID new_cid = GB(p2, 0, 8);
+ byte new_subtype = GB(p2, 8, 8);
+ Vehicle *v;
+ int32 cost;
+ uint num;
+
+ if (!IsValidVehicleID(p1)) return CMD_ERROR;
+
+ v = GetVehicle(p1);
+
+ if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
+ if (CheckTrainStoppedInDepot(v) < 0) return_cmd_error(STR_TRAIN_MUST_BE_STOPPED);
+
+ /* Check cargo */
+ if (new_cid > NUM_CARGO) return CMD_ERROR;
+
+ SET_EXPENSES_TYPE(EXPENSES_TRAIN_RUN);
+
+ cost = 0;
+ num = 0;
+
+ do {
+ /* XXX: We also refit all the attached wagons en-masse if they
+ * can be refitted. This is how TTDPatch does it. TODO: Have
+ * some nice [Refit] button near each wagon. --pasky */
+ if (!CanRefitTo(v->engine_type, new_cid)) continue;
+
+ if (v->cargo_cap != 0) {
+ const RailVehicleInfo *rvi = RailVehInfo(v->engine_type);
+ uint16 amount = CALLBACK_FAILED;
+
+ if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_REFIT_CAPACITY)) {
+ /* Back up the vehicle's cargo type */
+ CargoID temp_cid = v->cargo_type;
+ byte temp_subtype = v->cargo_subtype;
+ v->cargo_type = new_cid;
+ v->cargo_subtype = new_subtype;
+ /* Check the refit capacity callback */
+ amount = GetVehicleCallback(CBID_VEHICLE_REFIT_CAPACITY, 0, 0, v->engine_type, v);
+ /* Restore the original cargo type */
+ v->cargo_type = temp_cid;
+ v->cargo_subtype = temp_subtype;
+ }
+
+ if (amount == CALLBACK_FAILED) { // callback failed or not used, use default
+ CargoID old_cid = rvi->cargo_type;
+ /* normally, the capacity depends on the cargo type, a rail vehicle can
+ * carry twice as much mail/goods as normal cargo, and four times as
+ * many passengers
+ */
+ amount = rvi->capacity;
+ switch (old_cid) {
+ case CT_PASSENGERS: break;
+ case CT_MAIL:
+ case CT_GOODS: amount *= 2; break;
+ default: amount *= 4; break;
+ }
+ switch (new_cid) {
+ case CT_PASSENGERS: break;
+ case CT_MAIL:
+ case CT_GOODS: amount /= 2; break;
+ default: amount /= 4; break;
+ }
+ };
+
+ if (amount != 0) {
+ if (new_cid != v->cargo_type) {
+ cost += GetRefitCost(v->engine_type);
+ }
+
+ num += amount;
+ if (flags & DC_EXEC) {
+ v->cargo_count = (v->cargo_type == new_cid) ? min(amount, v->cargo_count) : 0;
+ v->cargo_type = new_cid;
+ v->cargo_cap = amount;
+ v->cargo_subtype = new_subtype;
+ InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
+ InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
+ RebuildVehicleLists();
+ }
+ }
+ }
+ } while ((v = v->next) != NULL);
+
+ _returned_refit_capacity = num;
+
+ /* Update the train's cached variables */
+ if (flags & DC_EXEC) TrainConsistChanged(GetFirstVehicleInChain(GetVehicle(p1)));
+
+ return cost;
+}
+
+typedef struct TrainFindDepotData {
+ uint best_length;
+ TileIndex tile;
+ PlayerID owner;
+ /**
+ * true if reversing is necessary for the train to get to this depot
+ * This value is unused when new depot finding and NPF are both disabled
+ */
+ bool reverse;
+} TrainFindDepotData;
+
+static bool NtpCallbFindDepot(TileIndex tile, TrainFindDepotData *tfdd, int track, uint length)
+{
+ if (IsTileType(tile, MP_RAILWAY) &&
+ IsTileOwner(tile, tfdd->owner) &&
+ IsRailDepot(tile)) {
+ /* approximate number of tiles by dividing by DIAG_FACTOR */
+ tfdd->best_length = length / DIAG_FACTOR;
+ tfdd->tile = tile;
+ return true;
+ }
+
+ return false;
+}
+
+// returns the tile of a depot to goto to. The given vehicle must not be
+// crashed!
+static TrainFindDepotData FindClosestTrainDepot(Vehicle *v, int max_distance)
+{
+ TrainFindDepotData tfdd;
+ TileIndex tile = v->tile;
+
+ assert(!(v->vehstatus & VS_CRASHED));
+
+ tfdd.owner = v->owner;
+ tfdd.best_length = (uint)-1;
+ tfdd.reverse = false;
+
+ if (IsTileDepotType(tile, TRANSPORT_RAIL)){
+ tfdd.tile = tile;
+ tfdd.best_length = 0;
+ return tfdd;
+ }
+
+ if (_patches.yapf.rail_use_yapf) {
+ bool found = YapfFindNearestRailDepotTwoWay(v, max_distance, NPF_INFINITE_PENALTY, &tfdd.tile, &tfdd.reverse);
+ tfdd.best_length = found ? max_distance / 2 : -1; // some fake distance or NOT_FOUND
+ } else if (_patches.new_pathfinding_all) {
+ NPFFoundTargetData ftd;
+ Vehicle* last = GetLastVehicleInChain(v);
+ Trackdir trackdir = GetVehicleTrackdir(v);
+ Trackdir trackdir_rev = ReverseTrackdir(GetVehicleTrackdir(last));
+
+ assert (trackdir != INVALID_TRACKDIR);
+ ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, last->tile, trackdir_rev, TRANSPORT_RAIL, v->owner, v->u.rail.compatible_railtypes, NPF_INFINITE_PENALTY);
+ if (ftd.best_bird_dist == 0) {
+ /* Found target */
+ tfdd.tile = ftd.node.tile;
+ /* Our caller expects a number of tiles, so we just approximate that
+ * number by this. It might not be completely what we want, but it will
+ * work for now :-) We can possibly change this when the old pathfinder
+ * is removed. */
+ tfdd.best_length = ftd.best_path_dist / NPF_TILE_LENGTH;
+ if (NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE)) tfdd.reverse = true;
+ }
+ } else {
+ // search in the forward direction first.
+ DiagDirection i;
+
+ i = DirToDiagDir(v->direction);
+ if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) {
+ i = ChangeDiagDir(i, DIAGDIRDIFF_90LEFT);
+ }
+ NewTrainPathfind(tile, 0, v->u.rail.compatible_railtypes, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd);
+ if (tfdd.best_length == (uint)-1){
+ tfdd.reverse = true;
+ // search in backwards direction
+ i = ReverseDiagDir(DirToDiagDir(v->direction));
+ if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) {
+ i = ChangeDiagDir(i, DIAGDIRDIFF_90LEFT);
+ }
+ NewTrainPathfind(tile, 0, v->u.rail.compatible_railtypes, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd);
+ }
+ }
+
+ return tfdd;
+}
+
+/** Send a train to a depot
+ * @param tile unused
+ * @param p1 train to send to the depot
+ * @param p2 various bitmasked elements
+ * - p2 bit 0-3 - DEPOT_ flags (see vehicle.h)
+ * - p2 bit 8-10 - VLW flag (for mass goto depot)
+ */
+int32 CmdSendTrainToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle *v;
+ TrainFindDepotData tfdd;
+
+ if (p2 & DEPOT_MASS_SEND) {
+ /* Mass goto depot requested */
+ if (!ValidVLWFlags(p2 & VLW_MASK)) return CMD_ERROR;
+ return SendAllVehiclesToDepot(VEH_Train, flags, p2 & DEPOT_SERVICE, _current_player, (p2 & VLW_MASK), p1);
+ }
+
+ if (!IsValidVehicleID(p1)) return CMD_ERROR;
+
+ v = GetVehicle(p1);
+
+ if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
+
+ if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
+
+ if (v->current_order.type == OT_GOTO_DEPOT) {
+ if (!!(p2 & DEPOT_SERVICE) == HASBIT(v->current_order.flags, OFB_HALT_IN_DEPOT)) {
+ /* We called with a different DEPOT_SERVICE setting.
+ * Now we change the setting to apply the new one and let the vehicle head for the same depot.
+ * Note: the if is (true for requesting service == true for ordered to stop in depot) */
+ if (flags & DC_EXEC) {
+ TOGGLEBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ }
+ return 0;
+ }
+
+ if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
+ if (flags & DC_EXEC) {
+ if (HASBIT(v->current_order.flags, OFB_PART_OF_ORDERS)) {
+ v->u.rail.days_since_order_progr = 0;
+ v->cur_order_index++;
+ }
+
+ v->current_order.type = OT_DUMMY;
+ v->current_order.flags = 0;
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ }
+ return 0;
+ }
+
+ /* check if at a standstill (not stopped only) in a depot
+ * the check is down here to make it possible to alter stop/service for trains entering the depot */
+ if (IsTileDepotType(v->tile, TRANSPORT_RAIL) && v->cur_speed == 0) return CMD_ERROR;
+
+ tfdd = FindClosestTrainDepot(v, 0);
+ if (tfdd.best_length == (uint)-1) return_cmd_error(STR_883A_UNABLE_TO_FIND_ROUTE_TO);
+
+ if (flags & DC_EXEC) {
+ v->dest_tile = tfdd.tile;
+ v->current_order.type = OT_GOTO_DEPOT;
+ v->current_order.flags = OF_NON_STOP;
+ if (!(p2 & DEPOT_SERVICE)) SETBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
+ v->current_order.dest = GetDepotByTile(tfdd.tile)->index;
+ v->current_order.refit_cargo = CT_INVALID;
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ /* If there is no depot in front, reverse automatically */
+ if (tfdd.reverse)
+ DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION);
+ }
+
+ return 0;
+}
+
+
+void OnTick_Train(void)
+{
+ _age_cargo_skip_counter = (_age_cargo_skip_counter == 0) ? 184 : (_age_cargo_skip_counter - 1);
+}
+
+static const int8 _vehicle_smoke_pos[8] = {
+ 1, 1, 1, 0, -1, -1, -1, 0
+};
+
+static void HandleLocomotiveSmokeCloud(const Vehicle* v)
+{
+ const Vehicle* u;
+ bool sound = false;
+
+ if (v->vehstatus & VS_TRAIN_SLOWING || v->load_unload_time_rem != 0 || v->cur_speed < 2)
+ return;
+
+ u = v;
+
+ do {
+ EngineID engtype = v->engine_type;
+ int effect_offset = GB(v->u.rail.cached_vis_effect, 0, 4) - 8;
+ byte effect_type = GB(v->u.rail.cached_vis_effect, 4, 2);
+ bool disable_effect = HASBIT(v->u.rail.cached_vis_effect, 6);
+ int x, y;
+
+ // no smoke?
+ if ((RailVehInfo(engtype)->flags & RVI_WAGON && effect_type == 0) ||
+ disable_effect ||
+ GetEngine(engtype)->railtype > RAILTYPE_ELECTRIC ||
+ v->vehstatus & VS_HIDDEN) {
+ continue;
+ }
+
+ // No smoke in depots or tunnels
+ if (IsTileDepotType(v->tile, TRANSPORT_RAIL) || IsTunnelTile(v->tile)) continue;
+
+ // No sparks for electric vehicles on nonelectrified tracks
+ if (!HasPowerOnRail(v->u.rail.railtype, GetTileRailType(v->tile, GetVehicleTrackdir(v)))) continue;
+
+ if (effect_type == 0) {
+ // Use default effect type for engine class.
+ effect_type = RailVehInfo(engtype)->engclass;
+ } else {
+ effect_type--;
+ }
+
+ x = _vehicle_smoke_pos[v->direction] * effect_offset;
+ y = _vehicle_smoke_pos[(v->direction + 2) % 8] * effect_offset;
+
+ if (HASBIT(v->u.rail.flags, VRF_REVERSE_DIRECTION)) {
+ x = -x;
+ y = -y;
+ }
+
+ switch (effect_type) {
+ case 0:
+ // steam smoke.
+ if (GB(v->tick_counter, 0, 4) == 0) {
+ CreateEffectVehicleRel(v, x, y, 10, EV_STEAM_SMOKE);
+ sound = true;
+ }
+ break;
+
+ case 1:
+ // diesel smoke
+ if (u->cur_speed <= 40 && CHANCE16(15, 128)) {
+ CreateEffectVehicleRel(v, 0, 0, 10, EV_DIESEL_SMOKE);
+ sound = true;
+ }
+ break;
+
+ case 2:
+ // blue spark
+ if (GB(v->tick_counter, 0, 2) == 0 && CHANCE16(1, 45)) {
+ CreateEffectVehicleRel(v, 0, 0, 10, EV_ELECTRIC_SPARK);
+ sound = true;
+ }
+ break;
+ }
+ } while ((v = v->next) != NULL);
+
+ if (sound) PlayVehicleSound(u, VSE_TRAIN_EFFECT);
+}
+
+static void TrainPlayLeaveStationSound(const Vehicle* v)
+{
+ static const SoundFx sfx[] = {
+ SND_04_TRAIN,
+ SND_0A_TRAIN_HORN,
+ SND_0A_TRAIN_HORN
+ };
+
+ EngineID engtype = v->engine_type;
+
+ if (PlayVehicleSound(v, VSE_START)) return;
+
+ switch (GetEngine(engtype)->railtype) {
+ case RAILTYPE_RAIL:
+ case RAILTYPE_ELECTRIC:
+ SndPlayVehicleFx(sfx[RailVehInfo(engtype)->engclass], v);
+ break;
+
+ case RAILTYPE_MONO: SndPlayVehicleFx(SND_47_MAGLEV_2, v); break;
+ case RAILTYPE_MAGLEV: SndPlayVehicleFx(SND_41_MAGLEV, v); break;
+ }
+}
+
+static bool CheckTrainStayInDepot(Vehicle *v)
+{
+ Vehicle *u;
+
+ // bail out if not all wagons are in the same depot or not in a depot at all
+ for (u = v; u != NULL; u = u->next) {
+ if (u->u.rail.track != 0x80 || u->tile != v->tile) return false;
+ }
+
+ // if the train got no power, then keep it in the depot
+ if (v->u.rail.cached_power == 0) {
+ v->vehstatus |= VS_STOPPED;
+ InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
+ return true;
+ }
+
+ if (v->u.rail.force_proceed == 0) {
+ if (++v->load_unload_time_rem < 37) {
+ InvalidateWindowClasses(WC_TRAINS_LIST);
+ return true;
+ }
+
+ v->load_unload_time_rem = 0;
+
+ if (UpdateSignalsOnSegment(v->tile, DirToDiagDir(v->direction))) {
+ InvalidateWindowClasses(WC_TRAINS_LIST);
+ return true;
+ }
+ }
+
+ VehicleServiceInDepot(v);
+ InvalidateWindowClasses(WC_TRAINS_LIST);
+ TrainPlayLeaveStationSound(v);
+
+ v->u.rail.track = 1;
+ if (v->direction & 2) v->u.rail.track = 2;
+
+ v->vehstatus &= ~VS_HIDDEN;
+ v->cur_speed = 0;
+
+ UpdateTrainDeltaXY(v, v->direction);
+ v->cur_image = GetTrainImage(v, v->direction);
+ VehiclePositionChanged(v);
+ UpdateSignalsOnSegment(v->tile, DirToDiagDir(v->direction));
+ UpdateTrainAcceleration(v);
+ InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
+
+ return false;
+}
+
+/* Check for station tiles */
+typedef struct TrainTrackFollowerData {
+ TileIndex dest_coords;
+ StationID station_index; // station index we're heading for
+ uint best_bird_dist;
+ uint best_track_dist;
+ byte best_track;
+} TrainTrackFollowerData;
+
+static bool NtpCallbFindStation(TileIndex tile, TrainTrackFollowerData *ttfd, int track, uint length)
+{
+ // heading for nowhere?
+ if (ttfd->dest_coords == 0) return false;
+
+ // did we reach the final station?
+ if ((ttfd->station_index == INVALID_STATION && tile == ttfd->dest_coords) || (
+ IsTileType(tile, MP_STATION) &&
+ IsRailwayStation(tile) &&
+ GetStationIndex(tile) == ttfd->station_index
+ )) {
+ /* We do not check for dest_coords if we have a station_index,
+ * because in that case the dest_coords are just an
+ * approximation of where the station is */
+ // found station
+ ttfd->best_track = track;
+ return true;
+ } else {
+ uint dist;
+
+ // didn't find station, keep track of the best path so far.
+ dist = DistanceManhattan(tile, ttfd->dest_coords);
+ if (dist < ttfd->best_bird_dist) {
+ ttfd->best_bird_dist = dist;
+ ttfd->best_track = track;
+ }
+ return false;
+ }
+}
+
+static void FillWithStationData(TrainTrackFollowerData* fd, const Vehicle* v)
+{
+ fd->dest_coords = v->dest_tile;
+ if (v->current_order.type == OT_GOTO_STATION) {
+ fd->station_index = v->current_order.dest;
+ } else {
+ fd->station_index = INVALID_STATION;
+ }
+}
+
+static const byte _initial_tile_subcoord[6][4][3] = {
+{{ 15, 8, 1 }, { 0, 0, 0 }, { 0, 8, 5 }, { 0, 0, 0 }},
+{{ 0, 0, 0 }, { 8, 0, 3 }, { 0, 0, 0 }, { 8, 15, 7 }},
+{{ 0, 0, 0 }, { 7, 0, 2 }, { 0, 7, 6 }, { 0, 0, 0 }},
+{{ 15, 8, 2 }, { 0, 0, 0 }, { 0, 0, 0 }, { 8, 15, 6 }},
+{{ 15, 7, 0 }, { 8, 0, 4 }, { 0, 0, 0 }, { 0, 0, 0 }},
+{{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 8, 4 }, { 7, 15, 0 }},
+};
+
+static const uint32 _reachable_tracks[4] = {
+ 0x10091009,
+ 0x00160016,
+ 0x05200520,
+ 0x2A002A00,
+};
+
+static const byte _search_directions[6][4] = {
+ { 0, 9, 2, 9 }, // track 1
+ { 9, 1, 9, 3 }, // track 2
+ { 9, 0, 3, 9 }, // track upper
+ { 1, 9, 9, 2 }, // track lower
+ { 3, 2, 9, 9 }, // track left
+ { 9, 9, 1, 0 }, // track right
+};
+
+static const byte _pick_track_table[6] = {1, 3, 2, 2, 0, 0};
+
+/* choose a track */
+static byte ChooseTrainTrack(Vehicle* v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirbits)
+{
+ TrainTrackFollowerData fd;
+ uint best_track;
+ // pathfinders are able to tell that route was only 'guessed'
+ bool path_not_found = false;
+
+#ifdef PF_BENCHMARK
+ TIC()
+#endif
+
+ assert((trackdirbits & ~0x3F) == 0);
+
+ /* quick return in case only one possible track is available */
+ if (KILL_FIRST_BIT(trackdirbits) == 0) return FIND_FIRST_BIT(trackdirbits);
+
+ if (_patches.yapf.rail_use_yapf) {
+ Trackdir trackdir = YapfChooseRailTrack(v, tile, enterdir, trackdirbits, &path_not_found);
+ if (trackdir != INVALID_TRACKDIR) {
+ best_track = TrackdirToTrack(trackdir);
+ } else {
+ best_track = FIND_FIRST_BIT(TrackdirBitsToTrackBits(trackdirbits));
+ }
+ } else if (_patches.new_pathfinding_all) { /* Use a new pathfinding for everything */
+ void* perf = NpfBeginInterval();
+ int time = 0;
+
+ NPFFindStationOrTileData fstd;
+ NPFFoundTargetData ftd;
+ Trackdir trackdir;
+
+ NPFFillWithOrderData(&fstd, v);
+ /* The enterdir for the new tile, is the exitdir for the old tile */
+ trackdir = GetVehicleTrackdir(v);
+ assert(trackdir != 0xff);
+
+ ftd = NPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.compatible_railtypes);
+
+ if (ftd.best_trackdir == 0xff) {
+ /* We are already at our target. Just do something */
+ //TODO: maybe display error?
+ //TODO: go straight ahead if possible?
+ best_track = FIND_FIRST_BIT(trackdirbits);
+ } else {
+ /* If ftd.best_bird_dist is 0, we found our target and ftd.best_trackdir contains
+ the direction we need to take to get there, if ftd.best_bird_dist is not 0,
+ we did not find our target, but ftd.best_trackdir contains the direction leading
+ to the tile closest to our target. */
+ if (ftd.best_bird_dist != 0) path_not_found = true;
+ /* Discard enterdir information, making it a normal track */
+ best_track = TrackdirToTrack(ftd.best_trackdir);
+ }
+
+ time = NpfEndInterval(perf);
+ DEBUG(yapf, 4, "[NPFT] %d us - %d rounds - %d open - %d closed -- ", time, 0, _aystar_stats_open_size, _aystar_stats_closed_size);
+ } else {
+ void* perf = NpfBeginInterval();
+ int time = 0;
+
+ FillWithStationData(&fd, v);
+
+ /* New train pathfinding */
+ fd.best_bird_dist = (uint)-1;
+ fd.best_track_dist = (uint)-1;
+ fd.best_track = 0xFF;
+
+ NewTrainPathfind(tile - TileOffsByDiagDir(enterdir), v->dest_tile,
+ v->u.rail.compatible_railtypes, enterdir, (NTPEnumProc*)NtpCallbFindStation, &fd);
+
+ // check whether the path was found or only 'guessed'
+ if (fd.best_bird_dist != 0) path_not_found = true;
+
+ if (fd.best_track == 0xff) {
+ // blaha
+ best_track = FIND_FIRST_BIT(trackdirbits);
+ } else {
+ best_track = fd.best_track & 7;
+ }
+
+ time = NpfEndInterval(perf);
+ DEBUG(yapf, 4, "[NTPT] %d us - %d rounds - %d open - %d closed -- ", time, 0, 0, 0);
+ }
+ // handle "path not found" state
+ if (path_not_found) {
+ // PF didn't find the route
+ if (!HASBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION)) {
+ // it is first time the problem occurred, set the "path not found" flag
+ SETBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION);
+ // and notify user about the event
+ if (_patches.lost_train_warn && v->owner == _local_player) {
+ SetDParam(0, v->unitnumber);
+ AddNewsItem(
+ STR_TRAIN_IS_LOST,
+ NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0),
+ v->index,
+ 0);
+ }
+ }
+ } else {
+ // route found, is the train marked with "path not found" flag?
+ if (HASBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION)) {
+ // clear the flag as the PF's problem was solved
+ CLRBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION);
+ // can we also delete the "News" item somehow?
+ }
+ }
+
+#ifdef PF_BENCHMARK
+ TOC("PF time = ", 1)
+#endif
+
+ return best_track;
+}
+
+
+static bool CheckReverseTrain(Vehicle *v)
+{
+ TrainTrackFollowerData fd;
+ int i, r;
+ int best_track;
+ uint best_bird_dist = 0;
+ uint best_track_dist = 0;
+ uint reverse, reverse_best;
+
+ if (_opt.diff.line_reverse_mode != 0 ||
+ v->u.rail.track & 0xC0 ||
+ !(v->direction & 1))
+ return false;
+
+ FillWithStationData(&fd, v);
+
+ best_track = -1;
+ reverse_best = reverse = 0;
+
+ assert(v->u.rail.track);
+
+ i = _search_directions[FIND_FIRST_BIT(v->u.rail.track)][DirToDiagDir(v->direction)];
+
+ if (_patches.yapf.rail_use_yapf) {
+ reverse_best = YapfCheckReverseTrain(v);
+ } else if (_patches.new_pathfinding_all) { /* Use a new pathfinding for everything */
+ NPFFindStationOrTileData fstd;
+ NPFFoundTargetData ftd;
+ byte trackdir, trackdir_rev;
+ Vehicle* last = GetLastVehicleInChain(v);
+
+ NPFFillWithOrderData(&fstd, v);
+
+ trackdir = GetVehicleTrackdir(v);
+ trackdir_rev = ReverseTrackdir(GetVehicleTrackdir(last));
+ assert(trackdir != 0xff);
+ assert(trackdir_rev != 0xff);
+
+ ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, last->tile, trackdir_rev, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.compatible_railtypes);
+ if (ftd.best_bird_dist != 0) {
+ /* We didn't find anything, just keep on going straight ahead */
+ reverse_best = false;
+ } else {
+ if (NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE)) {
+ reverse_best = true;
+ } else {
+ reverse_best = false;
+ }
+ }
+ } else {
+ for (;;) {
+ fd.best_bird_dist = (uint)-1;
+ fd.best_track_dist = (uint)-1;
+
+ NewTrainPathfind(v->tile, v->dest_tile, v->u.rail.compatible_railtypes, reverse ^ i, (NTPEnumProc*)NtpCallbFindStation, &fd);
+
+ if (best_track != -1) {
+ if (best_bird_dist != 0) {
+ if (fd.best_bird_dist != 0) {
+ /* neither reached the destination, pick the one with the smallest bird dist */
+ if (fd.best_bird_dist > best_bird_dist) goto bad;
+ if (fd.best_bird_dist < best_bird_dist) goto good;
+ } else {
+ /* we found the destination for the first time */
+ goto good;
+ }
+ } else {
+ if (fd.best_bird_dist != 0) {
+ /* didn't find destination, but we've found the destination previously */
+ goto bad;
+ } else {
+ /* both old & new reached the destination, compare track length */
+ if (fd.best_track_dist > best_track_dist) goto bad;
+ if (fd.best_track_dist < best_track_dist) goto good;
+ }
+ }
+
+ /* if we reach this position, there's two paths of equal value so far.
+ * pick one randomly. */
+ r = GB(Random(), 0, 8);
+ if (_pick_track_table[i] == (v->direction & 3)) r += 80;
+ if (_pick_track_table[best_track] == (v->direction & 3)) r -= 80;
+ if (r <= 127) goto bad;
+ }
+good:;
+ best_track = i;
+ best_bird_dist = fd.best_bird_dist;
+ best_track_dist = fd.best_track_dist;
+ reverse_best = reverse;
+bad:;
+ if (reverse != 0) break;
+ reverse = 2;
+ }
+ }
+
+ return reverse_best != 0;
+}
+
+static bool ProcessTrainOrder(Vehicle *v)
+{
+ const Order *order;
+ bool at_waypoint = false;
+
+ switch (v->current_order.type) {
+ case OT_GOTO_DEPOT:
+ if (!(v->current_order.flags & OF_PART_OF_ORDERS)) return false;
+ if ((v->current_order.flags & OF_SERVICE_IF_NEEDED) &&
+ !VehicleNeedsService(v)) {
+ v->cur_order_index++;
+ }
+ break;
+
+ case OT_LOADING:
+ case OT_LEAVESTATION:
+ return false;
+
+ default: break;
+ }
+
+ // check if we've reached the waypoint?
+ if (v->current_order.type == OT_GOTO_WAYPOINT && v->tile == v->dest_tile) {
+ v->cur_order_index++;
+ at_waypoint = true;
+ }
+
+ // check if we've reached a non-stop station while TTDPatch nonstop is enabled..
+ if (_patches.new_nonstop &&
+ v->current_order.flags & OF_NON_STOP &&
+ IsTileType(v->tile, MP_STATION) &&
+ v->current_order.dest == GetStationIndex(v->tile)) {
+ v->cur_order_index++;
+ }
+
+ // Get the current order
+ if (v->cur_order_index >= v->num_orders) v->cur_order_index = 0;
+
+ order = GetVehicleOrder(v, v->cur_order_index);
+
+ // If no order, do nothing.
+ if (order == NULL) {
+ v->current_order.type = OT_NOTHING;
+ v->current_order.flags = 0;
+ v->dest_tile = 0;
+ return false;
+ }
+
+ // If it is unchanged, keep it.
+ if (order->type == v->current_order.type &&
+ order->flags == v->current_order.flags &&
+ order->dest == v->current_order.dest)
+ return false;
+
+ // Otherwise set it, and determine the destination tile.
+ v->current_order = *order;
+
+ v->dest_tile = 0;
+
+ InvalidateVehicleOrder(v);
+
+ switch (order->type) {
+ case OT_GOTO_STATION:
+ if (order->dest == v->last_station_visited)
+ v->last_station_visited = INVALID_STATION;
+ v->dest_tile = GetStation(order->dest)->xy;
+ break;
+
+ case OT_GOTO_DEPOT:
+ v->dest_tile = GetDepot(order->dest)->xy;
+ break;
+
+ case OT_GOTO_WAYPOINT:
+ v->dest_tile = GetWaypoint(order->dest)->xy;
+ break;
+
+ default:
+ return false;
+ }
+
+ return !at_waypoint && CheckReverseTrain(v);
+}
+
+static void MarkTrainDirty(Vehicle *v)
+{
+ do {
+ v->cur_image = GetTrainImage(v, v->direction);
+ MarkAllViewportsDirty(v->left_coord, v->top_coord, v->right_coord + 1, v->bottom_coord + 1);
+ } while ((v = v->next) != NULL);
+}
+
+static void HandleTrainLoading(Vehicle *v, bool mode)
+{
+ if (v->current_order.type == OT_NOTHING) return;
+
+ if (v->current_order.type != OT_DUMMY) {
+ if (v->current_order.type != OT_LOADING) return;
+ if (mode) return;
+
+ // don't mark the train as lost if we're loading on the final station.
+ if (v->current_order.flags & OF_NON_STOP)
+ v->u.rail.days_since_order_progr = 0;
+
+ if (--v->load_unload_time_rem) return;
+
+ if (CanFillVehicle(v) && (v->current_order.flags & OF_FULL_LOAD ||
+ (_patches.gradual_loading && !HASBIT(v->load_status, LS_LOADING_FINISHED)))) {
+ v->u.rail.days_since_order_progr = 0; /* Prevent a train lost message for full loading trains */
+ SET_EXPENSES_TYPE(EXPENSES_TRAIN_INC);
+ if (LoadUnloadVehicle(v, false)) {
+ InvalidateWindow(WC_TRAINS_LIST, v->owner);
+ MarkTrainDirty(v);
+
+ // need to update acceleration and cached values since the goods on the train changed.
+ TrainCargoChanged(v);
+ UpdateTrainAcceleration(v);
+ }
+ return;
+ }
+
+ TrainPlayLeaveStationSound(v);
+
+ {
+ Order b = v->current_order;
+ v->current_order.type = OT_LEAVESTATION;
+ v->current_order.flags = 0;
+
+ // If this was not the final order, don't remove it from the list.
+ if (!(b.flags & OF_NON_STOP)) return;
+ }
+ }
+
+ v->u.rail.days_since_order_progr = 0;
+ v->cur_order_index++;
+ InvalidateVehicleOrder(v);
+}
+
+static int UpdateTrainSpeed(Vehicle *v)
+{
+ uint spd;
+ uint accel;
+
+ if (v->vehstatus & VS_STOPPED || HASBIT(v->u.rail.flags, VRF_REVERSING)) {
+ if (_patches.realistic_acceleration) {
+ accel = GetTrainAcceleration(v, AM_BRAKE) * 2;
+ } else {
+ accel = v->acceleration * -2;
+ }
+ } else {
+ if (_patches.realistic_acceleration) {
+ accel = GetTrainAcceleration(v, AM_ACCEL);
+ } else {
+ accel = v->acceleration;
+ }
+ }
+
+ spd = v->subspeed + accel * 2;
+ v->subspeed = (byte)spd;
+ {
+ int tempmax = v->max_speed;
+ if (v->cur_speed > v->max_speed)
+ tempmax = v->cur_speed - (v->cur_speed / 10) - 1;
+ v->cur_speed = spd = clamp(v->cur_speed + ((int)spd >> 8), 0, tempmax);
+ }
+
+ if (!(v->direction & 1)) spd = spd * 3 >> 2;
+
+ spd += v->progress;
+ v->progress = (byte)spd;
+ return (spd >> 8);
+}
+
+static void TrainEnterStation(Vehicle *v, StationID station)
+{
+ Station *st;
+ uint32 flags;
+
+ v->last_station_visited = station;
+
+ /* check if a train ever visited this station before */
+ st = GetStation(station);
+ if (!(st->had_vehicle_of_type & HVOT_TRAIN)) {
+ st->had_vehicle_of_type |= HVOT_TRAIN;
+ SetDParam(0, st->index);
+ flags = (v->owner == _local_player) ? NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ARRIVAL_PLAYER, 0) : NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ARRIVAL_OTHER, 0);
+ AddNewsItem(
+ STR_8801_CITIZENS_CELEBRATE_FIRST,
+ flags,
+ v->index,
+ 0
+ );
+ }
+
+ // Did we reach the final destination?
+ if (v->current_order.type == OT_GOTO_STATION &&
+ v->current_order.dest == station) {
+ // Yeah, keep the load/unload flags
+ // Non Stop now means if the order should be increased.
+ v->current_order.type = OT_LOADING;
+ v->current_order.flags &= OF_FULL_LOAD | OF_UNLOAD | OF_TRANSFER;
+ v->current_order.flags |= OF_NON_STOP;
+ } else {
+ // No, just do a simple load
+ v->current_order.type = OT_LOADING;
+ v->current_order.flags = 0;
+ }
+ v->current_order.dest = 0;
+
+ SET_EXPENSES_TYPE(EXPENSES_TRAIN_INC);
+ if (LoadUnloadVehicle(v, true) != 0) {
+ InvalidateWindow(WC_TRAINS_LIST, v->owner);
+ TrainCargoChanged(v);
+ UpdateTrainAcceleration(v);
+ }
+ MarkTrainDirty(v);
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+}
+
+static byte AfterSetTrainPos(Vehicle *v, bool new_tile)
+{
+ byte new_z, old_z;
+
+ // need this hint so it returns the right z coordinate on bridges.
+ new_z = GetSlopeZ(v->x_pos, v->y_pos);
+
+ old_z = v->z_pos;
+ v->z_pos = new_z;
+
+ if (new_tile) {
+ CLRBIT(v->u.rail.flags, VRF_GOINGUP);
+ CLRBIT(v->u.rail.flags, VRF_GOINGDOWN);
+
+ if (new_z != old_z) {
+ TileIndex tile = TileVirtXY(v->x_pos, v->y_pos);
+
+ // XXX workaround, whole UP/DOWN detection needs overhaul
+ if (!IsTunnelTile(tile)) {
+ SETBIT(v->u.rail.flags, (new_z > old_z) ? VRF_GOINGUP : VRF_GOINGDOWN);
+ }
+ }
+ }
+
+ VehiclePositionChanged(v);
+ EndVehicleMove(v);
+ return old_z;
+}
+
+static const Direction _new_vehicle_direction_table[11] = {
+ DIR_N , DIR_NW, DIR_W , 0,
+ DIR_NE, DIR_N , DIR_SW, 0,
+ DIR_E , DIR_SE, DIR_S
+};
+
+static Direction GetNewVehicleDirectionByTile(TileIndex new_tile, TileIndex old_tile)
+{
+ uint offs = (TileY(new_tile) - TileY(old_tile) + 1) * 4 +
+ TileX(new_tile) - TileX(old_tile) + 1;
+ assert(offs < 11);
+ return _new_vehicle_direction_table[offs];
+}
+
+static Direction GetNewVehicleDirection(const Vehicle *v, int x, int y)
+{
+ uint offs = (y - v->y_pos + 1) * 4 + (x - v->x_pos + 1);
+ assert(offs < 11);
+ return _new_vehicle_direction_table[offs];
+}
+
+static int GetDirectionToVehicle(const Vehicle *v, int x, int y)
+{
+ byte offs;
+
+ x -= v->x_pos;
+ if (x >= 0) {
+ offs = (x > 2) ? 0 : 1;
+ } else {
+ offs = (x < -2) ? 2 : 1;
+ }
+
+ y -= v->y_pos;
+ if (y >= 0) {
+ offs += ((y > 2) ? 0 : 1) * 4;
+ } else {
+ offs += ((y < -2) ? 2 : 1) * 4;
+ }
+
+ assert(offs < 11);
+ return _new_vehicle_direction_table[offs];
+}
+
+/* Check if the vehicle is compatible with the specified tile */
+static bool CheckCompatibleRail(const Vehicle *v, TileIndex tile)
+{
+ switch (GetTileType(tile)) {
+ case MP_RAILWAY:
+ case MP_STATION:
+ // normal tracks, jump to owner check
+ break;
+
+ case MP_STREET:
+ // tracks over roads, do owner check of tracks
+ return
+ IsTileOwner(tile, v->owner) && (
+ !IsFrontEngine(v) ||
+ IsCompatibleRail(v->u.rail.railtype, GetRailTypeCrossing(tile))
+ );
+
+ default:
+ return true;
+ }
+
+ return
+ IsTileOwner(tile, v->owner) && (
+ !IsFrontEngine(v) ||
+ HASBIT(v->u.rail.compatible_railtypes, GetRailType(tile))
+ );
+}
+
+typedef struct {
+ byte small_turn, large_turn;
+ byte z_up; // fraction to remove when moving up
+ byte z_down; // fraction to remove when moving down
+} RailtypeSlowdownParams;
+
+static const RailtypeSlowdownParams _railtype_slowdown[] = {
+ // normal accel
+ {256 / 4, 256 / 2, 256 / 4, 2}, // normal
+ {256 / 4, 256 / 2, 256 / 4, 2}, // electrified
+ {256 / 4, 256 / 2, 256 / 4, 2}, // monorail
+ {0, 256 / 2, 256 / 4, 2}, // maglev
+};
+
+/* Modify the speed of the vehicle due to a turn */
+static void AffectSpeedByDirChange(Vehicle* v, Direction new_dir)
+{
+ DirDiff diff;
+ const RailtypeSlowdownParams *rsp;
+
+ if (_patches.realistic_acceleration) return;
+
+ diff = DirDifference(v->direction, new_dir);
+ if (diff == DIRDIFF_SAME) return;
+
+ rsp = &_railtype_slowdown[v->u.rail.railtype];
+ v->cur_speed -= (diff == DIRDIFF_45RIGHT || diff == DIRDIFF_45LEFT ? rsp->small_turn : rsp->large_turn) * v->cur_speed >> 8;
+}
+
+/* Modify the speed of the vehicle due to a change in altitude */
+static void AffectSpeedByZChange(Vehicle *v, byte old_z)
+{
+ const RailtypeSlowdownParams *rsp;
+ if (old_z == v->z_pos || _patches.realistic_acceleration) return;
+
+ rsp = &_railtype_slowdown[v->u.rail.railtype];
+
+ if (old_z < v->z_pos) {
+ v->cur_speed -= (v->cur_speed * rsp->z_up >> 8);
+ } else {
+ uint16 spd = v->cur_speed + rsp->z_down;
+ if (spd <= v->max_speed) v->cur_speed = spd;
+ }
+}
+
+static const DiagDirection _otherside_signal_directions[] = {
+ DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE, 0, 0,
+ DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE
+};
+
+static void TrainMovedChangeSignals(TileIndex tile, DiagDirection dir)
+{
+ if (IsTileType(tile, MP_RAILWAY) &&
+ GetRailTileType(tile) == RAIL_TILE_SIGNALS) {
+ uint i = FindFirstBit2x64(GetTrackBits(tile) * 0x101 & _reachable_tracks[dir]);
+ UpdateSignalsOnSegment(tile, _otherside_signal_directions[i]);
+ }
+}
+
+
+typedef struct TrainCollideChecker {
+ const Vehicle *v;
+ const Vehicle *v_skip;
+} TrainCollideChecker;
+
+static void *FindTrainCollideEnum(Vehicle *v, void *data)
+{
+ const TrainCollideChecker* tcc = data;
+
+ if (v != tcc->v &&
+ v != tcc->v_skip &&
+ v->type == VEH_Train &&
+ v->u.rail.track != 0x80 &&
+ myabs(v->z_pos - tcc->v->z_pos) <= 6 &&
+ myabs(v->x_pos - tcc->v->x_pos) < 6 &&
+ myabs(v->y_pos - tcc->v->y_pos) < 6) {
+ return v;
+ } else {
+ return NULL;
+ }
+}
+
+static void SetVehicleCrashed(Vehicle *v)
+{
+ Vehicle *u;
+
+ if (v->u.rail.crash_anim_pos != 0) return;
+
+ v->u.rail.crash_anim_pos++;
+
+ u = v;
+ BEGIN_ENUM_WAGONS(v)
+ v->vehstatus |= VS_CRASHED;
+ END_ENUM_WAGONS(v)
+
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, u->index, STATUS_BAR);
+}
+
+static uint CountPassengersInTrain(const Vehicle* v)
+{
+ uint num = 0;
+ BEGIN_ENUM_WAGONS(v)
+ if (v->cargo_type == CT_PASSENGERS) num += v->cargo_count;
+ END_ENUM_WAGONS(v)
+ return num;
+}
+
+/*
+ * Checks whether the specified train has a collision with another vehicle. If
+ * so, destroys this vehicle, and the other vehicle if its subtype has TS_Front.
+ * Reports the incident in a flashy news item, modifies station ratings and
+ * plays a sound.
+ */
+static void CheckTrainCollision(Vehicle *v)
+{
+ TrainCollideChecker tcc;
+ Vehicle *coll;
+ Vehicle *realcoll;
+ uint num;
+
+ /* can't collide in depot */
+ if (v->u.rail.track == 0x80) return;
+
+ assert(v->u.rail.track == 0x40 || TileVirtXY(v->x_pos, v->y_pos) == v->tile);
+
+ tcc.v = v;
+ tcc.v_skip = v->next;
+
+ /* find colliding vehicle */
+ realcoll = VehicleFromPos(TileVirtXY(v->x_pos, v->y_pos), &tcc, FindTrainCollideEnum);
+ if (realcoll == NULL) return;
+
+ coll = GetFirstVehicleInChain(realcoll);
+
+ /* it can't collide with its own wagons */
+ if (v == coll ||
+ (v->u.rail.track & 0x40 && (v->direction & 2) != (realcoll->direction & 2)))
+ return;
+
+ //two drivers + passangers killed in train v
+ num = 2 + CountPassengersInTrain(v);
+ if (!(coll->vehstatus & VS_CRASHED))
+ //two drivers + passangers killed in train coll (if it was not crashed already)
+ num += 2 + CountPassengersInTrain(coll);
+
+ SetVehicleCrashed(v);
+ if (IsFrontEngine(coll)) SetVehicleCrashed(coll);
+
+ SetDParam(0, num);
+ AddNewsItem(STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL,
+ NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_VEHICLE, NT_ACCIDENT, 0),
+ v->index,
+ 0
+ );
+
+ ModifyStationRatingAround(v->tile, v->owner, -160, 30);
+ SndPlayVehicleFx(SND_13_BIG_CRASH, v);
+}
+
+typedef struct VehicleAtSignalData {
+ TileIndex tile;
+ Direction direction;
+} VehicleAtSignalData;
+
+static void *CheckVehicleAtSignal(Vehicle *v, void *data)
+{
+ const VehicleAtSignalData* vasd = data;
+
+ if (v->type == VEH_Train && IsFrontEngine(v) && v->tile == vasd->tile) {
+ DirDiff diff = ChangeDirDiff(DirDifference(v->direction, vasd->direction), DIRDIFF_90RIGHT);
+
+ if (diff == DIRDIFF_90RIGHT || (v->cur_speed <= 5 && diff <= DIRDIFF_REVERSE)) return v;
+ }
+ return NULL;
+}
+
+static void TrainController(Vehicle *v, bool update_image)
+{
+ Vehicle *prev;
+ GetNewVehiclePosResult gp;
+ uint32 r, tracks,ts;
+ int i;
+ DiagDirection enterdir;
+ Direction dir;
+ Direction newdir;
+ Direction chosen_dir;
+ byte chosen_track;
+ byte old_z;
+
+ /* For every vehicle after and including the given vehicle */
+ for (prev = GetPrevVehicleInChain(v); v != NULL; prev = v, v = v->next) {
+ BeginVehicleMove(v);
+
+ if (v->u.rail.track != 0x40) {
+ /* Not inside tunnel */
+ if (GetNewVehiclePos(v, &gp)) {
+ /* Staying in the old tile */
+ if (v->u.rail.track == 0x80) {
+ /* inside depot */
+ gp.x = v->x_pos;
+ gp.y = v->y_pos;
+ } else {
+ /* is not inside depot */
+
+ if (!TrainCheckIfLineEnds(v)) return;
+
+ r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
+ if (r & 0x8) {
+ //debug("%x & 0x8", r);
+ goto invalid_rail;
+ }
+ if (r & 0x2) {
+ TrainEnterStation(v, r >> 8);
+ return;
+ }
+
+ if (v->current_order.type == OT_LEAVESTATION) {
+ v->current_order.type = OT_NOTHING;
+ v->current_order.flags = 0;
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ }
+ }
+ } else {
+ /* A new tile is about to be entered. */
+
+ byte bits;
+ /* Determine what direction we're entering the new tile from */
+ dir = GetNewVehicleDirectionByTile(gp.new_tile, gp.old_tile);
+ enterdir = DirToDiagDir(dir);
+ assert(enterdir==0 || enterdir==1 || enterdir==2 || enterdir==3);
+
+ /* Get the status of the tracks in the new tile and mask
+ * away the bits that aren't reachable. */
+ ts = GetTileTrackStatus(gp.new_tile, TRANSPORT_RAIL) & _reachable_tracks[enterdir];
+
+ /* Combine the from & to directions.
+ * Now, the lower byte contains the track status, and the byte at bit 16 contains
+ * the signal status. */
+ tracks = ts | (ts >> 8);
+ bits = tracks & 0xFF;
+ if ((_patches.new_pathfinding_all || _patches.yapf.rail_use_yapf) && _patches.forbid_90_deg && prev == NULL) {
+ /* We allow wagons to make 90 deg turns, because forbid_90_deg
+ * can be switched on halfway a turn */
+ bits &= ~TrackCrossesTracks(FIND_FIRST_BIT(v->u.rail.track));
+ }
+
+ if (bits == 0) {
+ //debug("%x == 0", bits);
+ goto invalid_rail;
+ }
+
+ /* Check if the new tile contrains tracks that are compatible
+ * with the current train, if not, bail out. */
+ if (!CheckCompatibleRail(v, gp.new_tile)) {
+ //debug("!CheckCompatibleRail(%p, %x)", v, gp.new_tile);
+ goto invalid_rail;
+ }
+
+ if (prev == NULL) {
+ /* Currently the locomotive is active. Determine which one of the
+ * available tracks to choose */
+ chosen_track = 1 << ChooseTrainTrack(v, gp.new_tile, enterdir, bits);
+ assert(chosen_track & tracks);
+
+ /* Check if it's a red signal and that force proceed is not clicked. */
+ if ( (tracks>>16)&chosen_track && v->u.rail.force_proceed == 0) goto red_light;
+ } else {
+ static byte _matching_tracks[8] = {0x30, 1, 0xC, 2, 0x30, 1, 0xC, 2};
+
+ /* The wagon is active, simply follow the prev vehicle. */
+ chosen_track = (byte)(_matching_tracks[GetDirectionToVehicle(prev, gp.x, gp.y)] & bits);
+ }
+
+ /* make sure chosen track is a valid track */
+ assert(chosen_track==1 || chosen_track==2 || chosen_track==4 || chosen_track==8 || chosen_track==16 || chosen_track==32);
+
+ /* Update XY to reflect the entrance to the new tile, and select the direction to use */
+ {
+ const byte *b = _initial_tile_subcoord[FIND_FIRST_BIT(chosen_track)][enterdir];
+ gp.x = (gp.x & ~0xF) | b[0];
+ gp.y = (gp.y & ~0xF) | b[1];
+ chosen_dir = b[2];
+ }
+
+ /* Call the landscape function and tell it that the vehicle entered the tile */
+ r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
+ if (r & 0x8) {
+ //debug("%x & 0x8", r);
+ goto invalid_rail;
+ }
+
+ if (IsLevelCrossingTile(v->tile) && v->next == NULL) {
+ UnbarCrossing(v->tile);
+ MarkTileDirtyByTile(v->tile);
+ }
+
+ if (IsFrontEngine(v)) v->load_unload_time_rem = 0;
+
+ if (!(r&0x4)) {
+ v->tile = gp.new_tile;
+
+ if (GetTileRailType(gp.new_tile, chosen_track) != GetTileRailType(gp.old_tile, v->u.rail.track)) {
+ TrainPowerChanged(GetFirstVehicleInChain(v));
+ }
+
+ v->u.rail.track = chosen_track;
+ assert(v->u.rail.track);
+ }
+
+ if (IsFrontEngine(v)) TrainMovedChangeSignals(gp.new_tile, enterdir);
+
+ /* Signals can only change when the first
+ * (above) or the last vehicle moves. */
+ if (v->next == NULL)
+ TrainMovedChangeSignals(gp.old_tile, ReverseDiagDir(enterdir));
+
+ if (prev == NULL) AffectSpeedByDirChange(v, chosen_dir);
+
+ v->direction = chosen_dir;
+ }
+ } else {
+ /* in tunnel on on a bridge */
+ GetNewVehiclePos(v, &gp);
+
+ SetSpeedLimitOnBridge(v);
+
+ if (!(IsTunnelTile(gp.new_tile) || IsBridgeTile(gp.new_tile)) || !(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y) & 0x4)) {
+ v->x_pos = gp.x;
+ v->y_pos = gp.y;
+ VehiclePositionChanged(v);
+ if (!(v->vehstatus & VS_HIDDEN)) EndVehicleMove(v);
+ continue;
+ }
+ }
+
+ /* update image of train, as well as delta XY */
+ newdir = GetNewVehicleDirection(v, gp.x, gp.y);
+ UpdateTrainDeltaXY(v, newdir);
+ if (update_image) v->cur_image = GetTrainImage(v, newdir);
+
+ v->x_pos = gp.x;
+ v->y_pos = gp.y;
+
+ /* update the Z position of the vehicle */
+ old_z = AfterSetTrainPos(v, (gp.new_tile != gp.old_tile));
+
+ if (prev == NULL) {
+ /* This is the first vehicle in the train */
+ AffectSpeedByZChange(v, old_z);
+ }
+ }
+ return;
+
+invalid_rail:
+ /* We've reached end of line?? */
+ if (prev != NULL) error("!Disconnecting train");
+ goto reverse_train_direction;
+
+red_light: {
+ /* We're in front of a red signal ?? */
+ /* find the first set bit in ts. need to do it in 2 steps, since
+ * FIND_FIRST_BIT only handles 6 bits at a time. */
+ i = FindFirstBit2x64(ts);
+
+ if (!HasSignalOnTrackdir(gp.new_tile, ReverseTrackdir(i))) {
+ v->cur_speed = 0;
+ v->subspeed = 0;
+ v->progress = 255 - 100;
+ if (++v->load_unload_time_rem < _patches.wait_oneway_signal * 20) return;
+ } else if (HasSignalOnTrackdir(gp.new_tile, i)){
+ v->cur_speed = 0;
+ v->subspeed = 0;
+ v->progress = 255-10;
+ if (++v->load_unload_time_rem < _patches.wait_twoway_signal * 73) {
+ TileIndex o_tile = gp.new_tile + TileOffsByDiagDir(enterdir);
+ VehicleAtSignalData vasd;
+ vasd.tile = o_tile;
+ vasd.direction = ReverseDir(dir);
+
+ /* check if a train is waiting on the other side */
+ if (VehicleFromPos(o_tile, &vasd, CheckVehicleAtSignal) == NULL) return;
+ }
+ }
+ }
+
+reverse_train_direction:
+ v->load_unload_time_rem = 0;
+ v->cur_speed = 0;
+ v->subspeed = 0;
+ ReverseTrainDirection(v);
+}
+
+extern TileIndex CheckTunnelBusy(TileIndex tile, uint *length);
+
+/**
+ * Deletes/Clears the last wagon of a crashed train. It takes the engine of the
+ * train, then goes to the last wagon and deletes that. Each call to this function
+ * will remove the last wagon of a crashed train. If this wagon was on a crossing,
+ * or inside a tunnel, recalculate the signals as they might need updating
+ * @param v the @Vehicle of which last wagon is to be removed
+ */
+static void DeleteLastWagon(Vehicle *v)
+{
+ Vehicle *u = v;
+
+ /* Go to the last wagon and delete the link pointing there
+ * *u is then the one-before-last wagon, and *v the last
+ * one which will physicially be removed */
+ for (; v->next != NULL; v = v->next) u = v;
+ u->next = NULL;
+
+ InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
+ DeleteWindowById(WC_VEHICLE_VIEW, v->index);
+ RebuildVehicleLists();
+ InvalidateWindow(WC_COMPANY, v->owner);
+
+ BeginVehicleMove(v);
+ EndVehicleMove(v);
+ DeleteVehicle(v);
+
+ if (!(v->u.rail.track & 0xC0))
+ SetSignalsOnBothDir(v->tile, FIND_FIRST_BIT(v->u.rail.track));
+
+ /* Check if the wagon was on a road/rail-crossing and disable it if no
+ * others are on it */
+ DisableTrainCrossing(v->tile);
+
+ if ( (v->u.rail.track == 0x40 && v->vehstatus & VS_HIDDEN) ) { // inside a tunnel
+ TileIndex endtile = CheckTunnelBusy(v->tile, NULL);
+
+ if (endtile == INVALID_TILE) return; // tunnel is busy (error returned)
+
+ switch (v->direction) {
+ case 1:
+ case 5:
+ SetSignalsOnBothDir(v->tile, 0);
+ SetSignalsOnBothDir(endtile, 0);
+ break;
+
+ case 3:
+ case 7:
+ SetSignalsOnBothDir(v->tile, 1);
+ SetSignalsOnBothDir(endtile, 1);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+static void ChangeTrainDirRandomly(Vehicle *v)
+{
+ static const DirDiff delta[] = {
+ DIRDIFF_45LEFT, DIRDIFF_SAME, DIRDIFF_SAME, DIRDIFF_45RIGHT
+ };
+
+ do {
+ /* We don't need to twist around vehicles if they're not visible */
+ if (!(v->vehstatus & VS_HIDDEN)) {
+ v->direction = ChangeDir(v->direction, delta[GB(Random(), 0, 2)]);
+ BeginVehicleMove(v);
+ UpdateTrainDeltaXY(v, v->direction);
+ v->cur_image = GetTrainImage(v, v->direction);
+ /* Refrain from updating the z position of the vehicle when on
+ a bridge, because AfterSetTrainPos will put the vehicle under
+ the bridge in that case */
+ if (!(v->u.rail.track & 0x40)) AfterSetTrainPos(v, false);
+ }
+ } while ((v = v->next) != NULL);
+}
+
+static void HandleCrashedTrain(Vehicle *v)
+{
+ int state = ++v->u.rail.crash_anim_pos;
+ uint32 r;
+ Vehicle *u;
+
+ if (state == 4 && !(v->u.rail.track & VS_HIDDEN)) {
+ CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE);
+ }
+
+ if (state <= 200 && CHANCE16R(1, 7, r)) {
+ int index = (r * 10 >> 16);
+
+ u = v;
+ do {
+ if (--index < 0) {
+ r = Random();
+
+ CreateEffectVehicleRel(u,
+ GB(r, 8, 3) + 2,
+ GB(r, 16, 3) + 2,
+ GB(r, 0, 3) + 5,
+ EV_EXPLOSION_SMALL);
+ break;
+ }
+ } while ((u = u->next) != NULL);
+ }
+
+ if (state <= 240 && !(v->tick_counter & 3)) ChangeTrainDirRandomly(v);
+
+ if (state >= 4440 && !(v->tick_counter&0x1F)) {
+ DeleteLastWagon(v);
+ InvalidateWindow(WC_REPLACE_VEHICLE, VEH_Train);
+ }
+}
+
+static void HandleBrokenTrain(Vehicle *v)
+{
+ if (v->breakdown_ctr != 1) {
+ v->breakdown_ctr = 1;
+ v->cur_speed = 0;
+
+ if (v->breakdowns_since_last_service != 255)
+ v->breakdowns_since_last_service++;
+
+ InvalidateWindow(WC_VEHICLE_VIEW, v->index);
+ InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
+
+ if (!PlayVehicleSound(v, VSE_BREAKDOWN)) {
+ SndPlayVehicleFx((_opt.landscape != LT_CANDY) ?
+ SND_10_TRAIN_BREAKDOWN : SND_3A_COMEDY_BREAKDOWN_2, v);
+ }
+
+ if (!(v->vehstatus & VS_HIDDEN)) {
+ Vehicle *u = CreateEffectVehicleRel(v, 4, 4, 5, EV_BREAKDOWN_SMOKE);
+ if (u != NULL) u->u.special.unk0 = v->breakdown_delay * 2;
+ }
+ }
+
+ if (!(v->tick_counter & 3)) {
+ if (!--v->breakdown_delay) {
+ v->breakdown_ctr = 0;
+ InvalidateWindow(WC_VEHICLE_VIEW, v->index);
+ }
+ }
+}
+
+static const byte _breakdown_speeds[16] = {
+ 225, 210, 195, 180, 165, 150, 135, 120, 105, 90, 75, 60, 45, 30, 15, 15
+};
+
+static bool TrainCheckIfLineEnds(Vehicle *v)
+{
+ TileIndex tile;
+ uint x,y;
+ uint16 break_speed;
+ DiagDirection dir;
+ int t;
+ uint32 ts;
+
+ t = v->breakdown_ctr;
+ if (t > 1) {
+ v->vehstatus |= VS_TRAIN_SLOWING;
+
+ break_speed = _breakdown_speeds[GB(~t, 4, 4)];
+ if (break_speed < v->cur_speed) v->cur_speed = break_speed;
+ } else {
+ v->vehstatus &= ~VS_TRAIN_SLOWING;
+ }
+
+ if (v->u.rail.track & 0x40) return true; // exit if inside a tunnel
+ if (v->u.rail.track & 0x80) return true; // exit if inside a depot
+
+ tile = v->tile;
+
+ if (IsTileType(tile, MP_TUNNELBRIDGE)) {
+ DiagDirection dir;
+
+ dir = IsTunnel(tile) ? GetTunnelDirection(tile) : GetBridgeRampDirection(tile);
+ if (DiagDirToDir(dir) == v->direction) return true;
+ }
+
+ // depot?
+ /* XXX -- When enabled, this makes it possible to crash trains of others
+ (by building a depot right against a station) */
+/* if (IsTileType(tile, MP_RAILWAY) && GetRailTileType(tile) == RAIL_TILE_DEPOT_WAYPOINT)
+ return true;*/
+
+ /* Determine the non-diagonal direction in which we will exit this tile */
+ dir = DirToDiagDir(v->direction);
+ if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[dir]) {
+ dir = ChangeDiagDir(dir, DIAGDIRDIFF_90LEFT);
+ }
+ /* Calculate next tile */
+ tile += TileOffsByDiagDir(dir);
+ // determine the track status on the next tile.
+ ts = GetTileTrackStatus(tile, TRANSPORT_RAIL) & _reachable_tracks[dir];
+
+ /* Calc position within the current tile ?? */
+ x = v->x_pos & 0xF;
+ y = v->y_pos & 0xF;
+
+ switch (v->direction) {
+ case DIR_N : x = ~x + ~y + 24; break;
+ case DIR_NW: x = y; /* FALLTHROUGH */
+ case DIR_NE: x = ~x + 16; break;
+ case DIR_E : x = ~x + y + 8; break;
+ case DIR_SE: x = y; break;
+ case DIR_S : x = x + y - 8; break;
+ case DIR_W : x = ~y + x + 8; break;
+ }
+
+ if (GB(ts, 0, 16) != 0) {
+ /* If we approach a rail-piece which we can't enter, or the back of a depot, don't enter it! */
+ if (x + 4 >= TILE_SIZE &&
+ (!CheckCompatibleRail(v, tile) ||
+ (IsTileDepotType(tile, TRANSPORT_RAIL) &&
+ GetRailDepotDirection(tile) == dir))) {
+ v->cur_speed = 0;
+ ReverseTrainDirection(v);
+ return false;
+ }
+ if ((ts &= (ts >> 16)) == 0) {
+ // make a rail/road crossing red
+ if (IsLevelCrossingTile(tile)) {
+ if (!IsCrossingBarred(tile)) {
+ BarCrossing(tile);
+ SndPlayVehicleFx(SND_0E_LEVEL_CROSSING, v);
+ MarkTileDirtyByTile(tile);
+ }
+ }
+ return true;
+ }
+ } else if (x + 4 >= TILE_SIZE) {
+ v->cur_speed = 0;
+ ReverseTrainDirection(v);
+ return false;
+ }
+
+ // slow down
+ v->vehstatus |= VS_TRAIN_SLOWING;
+ break_speed = _breakdown_speeds[x & 0xF];
+ if (!(v->direction & 1)) break_speed >>= 1;
+ if (break_speed < v->cur_speed) v->cur_speed = break_speed;
+
+ return true;
+}
+
+static void TrainLocoHandler(Vehicle *v, bool mode)
+{
+ int j;
+
+ /* train has crashed? */
+ if (v->u.rail.crash_anim_pos != 0) {
+ if (!mode) HandleCrashedTrain(v);
+ return;
+ }
+
+ if (v->u.rail.force_proceed != 0) v->u.rail.force_proceed--;
+
+ /* train is broken down? */
+ if (v->breakdown_ctr != 0) {
+ if (v->breakdown_ctr <= 2) {
+ HandleBrokenTrain(v);
+ return;
+ }
+ v->breakdown_ctr--;
+ }
+
+ if (HASBIT(v->u.rail.flags, VRF_REVERSING) && v->cur_speed == 0) {
+ ReverseTrainDirection(v);
+ }
+
+ /* exit if train is stopped */
+ if (v->vehstatus & VS_STOPPED && v->cur_speed == 0) return;
+
+ if (ProcessTrainOrder(v)) {
+ v->load_unload_time_rem = 0;
+ v->cur_speed = 0;
+ v->subspeed = 0;
+ ReverseTrainDirection(v);
+ return;
+ }
+
+ HandleTrainLoading(v, mode);
+
+ if (v->current_order.type == OT_LOADING) return;
+
+ if (CheckTrainStayInDepot(v)) return;
+
+ if (!mode) HandleLocomotiveSmokeCloud(v);
+
+ j = UpdateTrainSpeed(v);
+ if (j == 0) {
+ // if the vehicle has speed 0, update the last_speed field.
+ if (v->cur_speed != 0) return;
+ } else {
+ TrainCheckIfLineEnds(v);
+
+ do {
+ TrainController(v, true);
+ CheckTrainCollision(v);
+ if (v->cur_speed <= 0x100)
+ break;
+ } while (--j != 0);
+ }
+
+ SetLastSpeed(v, v->cur_speed);
+}
+
+
+void Train_Tick(Vehicle *v)
+{
+ if (_age_cargo_skip_counter == 0 && v->cargo_days != 0xff)
+ v->cargo_days++;
+
+ v->tick_counter++;
+
+ if (IsFrontEngine(v)) {
+ TrainLocoHandler(v, false);
+
+ // make sure vehicle wasn't deleted.
+ if (v->type == VEH_Train && IsFrontEngine(v))
+ TrainLocoHandler(v, true);
+ } else if (IsFreeWagon(v) && HASBITS(v->vehstatus, VS_CRASHED)) {
+ // Delete flooded standalone wagon
+ if (++v->u.rail.crash_anim_pos >= 4400)
+ DeleteVehicle(v);
+ }
+}
+
+#define MAX_ACCEPTABLE_DEPOT_DIST 16
+
+static void CheckIfTrainNeedsService(Vehicle *v)
+{
+ const Depot* depot;
+ TrainFindDepotData tfdd;
+
+ if (_patches.servint_trains == 0) return;
+ if (!VehicleNeedsService(v)) return;
+ if (v->vehstatus & VS_STOPPED) return;
+ if (_patches.gotodepot && VehicleHasDepotOrders(v)) return;
+
+ // Don't interfere with a depot visit scheduled by the user, or a
+ // depot visit by the order list.
+ if (v->current_order.type == OT_GOTO_DEPOT &&
+ (v->current_order.flags & (OF_HALT_IN_DEPOT | OF_PART_OF_ORDERS)) != 0)
+ return;
+
+ if (CheckTrainIsInsideDepot(v)) {
+ VehicleServiceInDepot(v);
+ return;
+ }
+
+ tfdd = FindClosestTrainDepot(v, MAX_ACCEPTABLE_DEPOT_DIST);
+ /* Only go to the depot if it is not too far out of our way. */
+ if (tfdd.best_length == (uint)-1 || tfdd.best_length > MAX_ACCEPTABLE_DEPOT_DIST) {
+ if (v->current_order.type == OT_GOTO_DEPOT) {
+ /* If we were already heading for a depot but it has
+ * suddenly moved farther away, we continue our normal
+ * schedule? */
+ v->current_order.type = OT_DUMMY;
+ v->current_order.flags = 0;
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ }
+ return;
+ }
+
+ depot = GetDepotByTile(tfdd.tile);
+
+ if (v->current_order.type == OT_GOTO_DEPOT &&
+ v->current_order.dest != depot->index &&
+ !CHANCE16(3, 16)) {
+ return;
+ }
+
+ v->current_order.type = OT_GOTO_DEPOT;
+ v->current_order.flags = OF_NON_STOP;
+ v->current_order.dest = depot->index;
+ v->dest_tile = tfdd.tile;
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+}
+
+int32 GetTrainRunningCost(const Vehicle *v)
+{
+ int32 cost = 0;
+
+ do {
+ const RailVehicleInfo *rvi = RailVehInfo(v->engine_type);
+ if (rvi->running_cost_base > 0)
+ cost += rvi->running_cost_base * _price.running_rail[rvi->running_cost_class];
+ } while ((v = GetNextVehicle(v)) != NULL);
+
+ return cost;
+}
+
+void OnNewDay_Train(Vehicle *v)
+{
+ TileIndex tile;
+
+ if ((++v->day_counter & 7) == 0) DecreaseVehicleValue(v);
+
+ if (IsFrontEngine(v)) {
+ CheckVehicleBreakdown(v);
+ AgeVehicle(v);
+
+ CheckIfTrainNeedsService(v);
+
+ CheckOrders(v);
+
+ /* update destination */
+ if (v->current_order.type == OT_GOTO_STATION &&
+ (tile = GetStation(v->current_order.dest)->train_tile) != 0) {
+ v->dest_tile = tile;
+ }
+
+ if ((v->vehstatus & VS_STOPPED) == 0) {
+ /* running costs */
+ int32 cost = GetTrainRunningCost(v) / 364;
+
+ v->profit_this_year -= cost >> 8;
+
+ SET_EXPENSES_TYPE(EXPENSES_TRAIN_RUN);
+ SubtractMoneyFromPlayerFract(v->owner, cost);
+
+ InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
+ InvalidateWindowClasses(WC_TRAINS_LIST);
+ }
+ }
+}
+
+void TrainsYearlyLoop(void)
+{
+ Vehicle *v;
+
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == VEH_Train && IsFrontEngine(v)) {
+
+ // show warning if train is not generating enough income last 2 years (corresponds to a red icon in the vehicle list)
+ if (_patches.train_income_warn && v->owner == _local_player && v->age >= 730 && v->profit_this_year < 0) {
+ SetDParam(1, v->profit_this_year);
+ SetDParam(0, v->unitnumber);
+ AddNewsItem(
+ STR_TRAIN_IS_UNPROFITABLE,
+ NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0),
+ v->index,
+ 0);
+ }
+
+ v->profit_last_year = v->profit_this_year;
+ v->profit_this_year = 0;
+ InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
+ }
+ }
+}
+
+
+void InitializeTrains(void)
+{
+ _age_cargo_skip_counter = 1;
+}
+
+/*
+ * Link front and rear multiheaded engines to each other
+ * This is done when loading a savegame
+ */
+void ConnectMultiheadedTrains(void)
+{
+ Vehicle *v;
+
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == VEH_Train) {
+ v->u.rail.other_multiheaded_part = NULL;
+ }
+ }
+
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == VEH_Train && IsFrontEngine(v)) {
+ Vehicle *u = v;
+
+ BEGIN_ENUM_WAGONS(u) {
+ if (u->u.rail.other_multiheaded_part != NULL) continue; // we already linked this one
+
+ if (IsMultiheaded(u)) {
+ if (!IsTrainEngine(u)) {
+ /* we got a rear car without a front car. We will convert it to a front one */
+ SetTrainEngine(u);
+ u->spritenum--;
+ }
+
+ {
+ Vehicle *w;
+
+ for (w = u->next; w != NULL && (w->engine_type != u->engine_type || w->u.rail.other_multiheaded_part != NULL); w = GetNextVehicle(w));
+ if (w != NULL) {
+ /* we found a car to partner with this engine. Now we will make sure it face the right way */
+ if (IsTrainEngine(w)) {
+ ClearTrainEngine(w);
+ w->spritenum++;
+ }
+ }
+
+ if (w != NULL) {
+ w->u.rail.other_multiheaded_part = u;
+ u->u.rail.other_multiheaded_part = w;
+ } else {
+ /* we got a front car and no rear cars. We will fake this one for forget that it should have been multiheaded */
+ ClearMultiheaded(u);
+ }
+ }
+ }
+ } END_ENUM_WAGONS(u)
+ }
+ }
+}
+
+/*
+ * Converts all trains to the new subtype format introduced in savegame 16.2
+ * It also links multiheaded engines or make them forget they are multiheaded if no suitable partner is found
+ */
+void ConvertOldMultiheadToNew(void)
+{
+ Vehicle *v;
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == VEH_Train) {
+ SETBIT(v->subtype, 7); // indicates that it's the old format and needs to be converted in the next loop
+ }
+ }
+
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == VEH_Train) {
+ if (HASBIT(v->subtype, 7) && ((v->subtype & ~0x80) == 0 || (v->subtype & ~0x80) == 4)) {
+ Vehicle *u = v;
+
+ BEGIN_ENUM_WAGONS(u) {
+ const RailVehicleInfo *rvi = RailVehInfo(u->engine_type);
+
+ CLRBIT(u->subtype, 7);
+ switch (u->subtype) {
+ case 0: /* TS_Front_Engine */
+ if (rvi->flags & RVI_MULTIHEAD) SetMultiheaded(u);
+ SetFrontEngine(u);
+ SetTrainEngine(u);
+ break;
+
+ case 1: /* TS_Artic_Part */
+ u->subtype = 0;
+ SetArticulatedPart(u);
+ break;
+
+ case 2: /* TS_Not_First */
+ u->subtype = 0;
+ if (rvi->flags & RVI_WAGON) {
+ // normal wagon
+ SetTrainWagon(u);
+ break;
+ }
+ if (rvi->flags & RVI_MULTIHEAD && rvi->image_index == u->spritenum - 1) {
+ // rear end of a multiheaded engine
+ SetMultiheaded(u);
+ break;
+ }
+ if (rvi->flags & RVI_MULTIHEAD) SetMultiheaded(u);
+ SetTrainEngine(u);
+ break;
+
+ case 4: /* TS_Free_Car */
+ u->subtype = 0;
+ SetTrainWagon(u);
+ SetFreeWagon(u);
+ break;
+ default: NOT_REACHED(); break;
+ }
+ } END_ENUM_WAGONS(u)
+ }
+ }
+ }
+}
diff --git a/src/train_gui.c b/src/train_gui.c
new file mode 100644
index 000000000..a99170b68
--- /dev/null
+++ b/src/train_gui.c
@@ -0,0 +1,1135 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "debug.h"
+#include "functions.h"
+#include "rail_map.h"
+#include "table/sprites.h"
+#include "table/strings.h"
+#include "map.h"
+#include "engine.h"
+#include "window.h"
+#include "gui.h"
+#include "gfx.h"
+#include "vehicle.h"
+#include "viewport.h"
+#include "station.h"
+#include "command.h"
+#include "player.h"
+#include "vehicle_gui.h"
+#include "depot.h"
+#include "train.h"
+#include "newgrf_engine.h"
+#include "date.h"
+#include "strings.h"
+
+enum BuildTrainWidgets {
+ BUILD_TRAIN_WIDGET_CLOSEBOX = 0,
+ BUILD_TRAIN_WIDGET_CAPTION,
+ BUILD_TRAIN_WIDGET_SORT_ASCENDING_DESCENDING,
+ BUILD_TRAIN_WIDGET_SORT_TEXT,
+ BUILD_TRAIN_WIDGET_SORT_DROPDOWN,
+ BUILD_TRAIN_WIDGET_LIST,
+ BUILD_TRAIN_WIDGET_SCROLLBAR,
+ BUILD_TRAIN_WIDGET_PANEL,
+ BUILD_TRAIN_WIDGET_BUILD,
+ BUILD_TRAIN_WIDGET_RENAME,
+ BUILD_TRAIN_WIDGET_RESIZE,
+};
+
+static const Widget _new_rail_vehicle_widgets[] = {
+ { WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+ { WWT_CAPTION, RESIZE_NONE, 14, 11, 227, 0, 13, STR_JUST_STRING, STR_018C_WINDOW_TITLE_DRAG_THIS},
+ { WWT_PUSHTXTBTN, RESIZE_NONE, 14, 0, 80, 14, 25, STR_SORT_BY, STR_SORT_ORDER_TIP},
+ { WWT_PANEL, RESIZE_NONE, 14, 81, 215, 14, 25, 0x0, STR_SORT_CRITERIA_TIP},
+ { WWT_TEXTBTN, RESIZE_NONE, 14, 216, 227, 14, 25, STR_0225, STR_SORT_CRITERIA_TIP},
+ { WWT_MATRIX, RESIZE_BOTTOM, 14, 0, 215, 26, 137, 0x801, STR_8843_TRAIN_VEHICLE_SELECTION},
+ { WWT_SCROLLBAR, RESIZE_BOTTOM, 14, 216, 227, 26, 137, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+ { WWT_PANEL, RESIZE_TB, 14, 0, 227, 138, 239, 0x0, STR_NULL},
+ { WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 107, 240, 251, STR_881F_BUILD_VEHICLE, STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN},
+ { WWT_PUSHTXTBTN, RESIZE_TB, 14, 108, 215, 240, 251, STR_8820_RENAME, STR_8845_RENAME_TRAIN_VEHICLE_TYPE},
+ { WWT_RESIZEBOX, RESIZE_TB, 14, 216, 227, 240, 251, 0x0, STR_RESIZE_BUTTON},
+ { WIDGETS_END},
+};
+
+static bool _internal_sort_order; // false = ascending, true = descending
+static byte _last_sort_criteria = 0;
+static bool _last_sort_order = false;
+
+static int CDECL TrainEngineNumberSorter(const void *a, const void *b)
+{
+ const EngineID va = *(const EngineID*)a;
+ const EngineID vb = *(const EngineID*)b;
+ int r = ListPositionOfEngine(va) - ListPositionOfEngine(vb);
+
+ return _internal_sort_order ? -r : r;
+}
+
+static int CDECL TrainEnginesThenWagonsSorter(const void *a, const void *b)
+{
+ EngineID va = *(const EngineID*)a;
+ EngineID vb = *(const EngineID*)b;
+ int val_a = ((RailVehInfo(va)->flags & RVI_WAGON) != 0) ? 1 : 0;
+ int val_b = ((RailVehInfo(vb)->flags & RVI_WAGON) != 0) ? 1 : 0;
+ int r = val_a - val_b;
+
+ /* Use EngineID to sort instead since we want consistent sorting */
+ if (r == 0) return TrainEngineNumberSorter(a, b);
+
+ return _internal_sort_order ? -r : r;
+}
+
+static int CDECL TrainEngineCostSorter(const void *a, const void *b)
+{
+ int va = RailVehInfo(*(const EngineID*)a)->base_cost;
+ int vb = RailVehInfo(*(const EngineID*)b)->base_cost;
+ int r = va - vb;
+
+ return _internal_sort_order ? -r : r;
+}
+
+static int CDECL TrainEngineSpeedSorter(const void *a, const void *b)
+{
+ int va = RailVehInfo(*(const EngineID*)a)->max_speed;
+ int vb = RailVehInfo(*(const EngineID*)b)->max_speed;
+ int r = va - vb;
+
+ return _internal_sort_order ? -r : r;
+}
+
+static int CDECL TrainEnginePowerSorter(const void *a, const void *b)
+{
+ const RailVehicleInfo *rvi_a = RailVehInfo(*(const EngineID*)a);
+ const RailVehicleInfo *rvi_b = RailVehInfo(*(const EngineID*)b);
+
+ int va = rvi_a->power << (rvi_a->flags & RVI_MULTIHEAD ? 1 : 0);
+ int vb = rvi_b->power << (rvi_b->flags & RVI_MULTIHEAD ? 1 : 0);
+ int r = va - vb;
+
+ return _internal_sort_order ? -r : r;
+}
+
+static int CDECL TrainEngineIntroDateSorter(const void *a, const void *b)
+{
+ int va = GetEngine(*(const EngineID*)a)->intro_date;
+ int vb = GetEngine(*(const EngineID*)b)->intro_date;
+ int r = va - vb;
+
+ return _internal_sort_order ? -r : r;
+}
+
+static EngineID _last_engine; // cached vehicle to hopefully speed up name-sorting
+
+static char _bufcache[64]; // used together with _last_vehicle to hopefully speed up stringsorting
+static int CDECL TrainEngineNameSorter(const void *a, const void *b)
+{
+ const EngineID va = *(const EngineID*)a;
+ const EngineID vb = *(const EngineID*)b;
+ char buf1[64];
+ int r;
+
+ GetString(buf1, GetCustomEngineName(va), lastof(buf1));
+
+ if (vb != _last_engine) {
+ _last_engine = vb;
+ _bufcache[0] = '\0';
+
+ GetString(_bufcache, GetCustomEngineName(vb), lastof(_bufcache));
+ }
+
+ r = strcasecmp(buf1, _bufcache); // sort by name
+
+ return _internal_sort_order ? -r : r;
+}
+
+static int CDECL TrainEngineRunningCostSorter(const void *a, const void *b)
+{
+ const RailVehicleInfo *rvi_a = RailVehInfo(*(const EngineID*)a);
+ const RailVehicleInfo *rvi_b = RailVehInfo(*(const EngineID*)b);
+
+ int va = rvi_a->running_cost_base * _price.running_rail[rvi_a->running_cost_class] * (rvi_a->flags & RVI_MULTIHEAD ? 2 : 1);
+ int vb = rvi_b->running_cost_base * _price.running_rail[rvi_b->running_cost_class] * (rvi_b->flags & RVI_MULTIHEAD ? 2 : 1);
+ int r = va - vb;
+
+ return _internal_sort_order ? -r : r;
+}
+
+static int CDECL TrainEnginePowerVsRunningCostSorter(const void *a, const void *b)
+{
+ const RailVehicleInfo *rvi_a = RailVehInfo(*(const EngineID*)a);
+ const RailVehicleInfo *rvi_b = RailVehInfo(*(const EngineID*)b);
+
+ /* Here we are using a few tricks to get the right sort.
+ * We want power/running cost, but since we usually got higher running cost than power and we store the result in an int,
+ * we will actually calculate cunning cost/power (to make it more than 1).
+ * Because of this, the return value have to be reversed as well and we return b - a instead of a - b.
+ * Another thing is that both power and running costs should be doubled for multiheaded engines.
+ * Since it would be multipling with 2 in both numerator and denumerator, it will even themselves out and we skip checking for multiheaded. */
+ int va = (rvi_a->running_cost_base * _price.running_rail[rvi_a->running_cost_class]) / max(1, rvi_a->power);
+ int vb = (rvi_b->running_cost_base * _price.running_rail[rvi_b->running_cost_class]) / max(1, rvi_b->power);
+ int r = vb - va;
+
+ return _internal_sort_order ? -r : r;
+}
+
+static int CDECL TrainEngineReliabilitySorter(const void *a, const void *b)
+{
+ int va = GetEngine(*(const EngineID*)a)->reliability;
+ int vb = GetEngine(*(const EngineID*)b)->reliability;
+ int r = va - vb;
+
+ return _internal_sort_order ? -r : r;
+}
+
+static EngList_SortTypeFunction * const _engine_sorter[] = {
+ &TrainEngineNumberSorter,
+ &TrainEngineCostSorter,
+ &TrainEngineSpeedSorter,
+ &TrainEnginePowerSorter,
+ &TrainEngineIntroDateSorter,
+ &TrainEngineNameSorter,
+ &TrainEngineRunningCostSorter,
+ &TrainEnginePowerVsRunningCostSorter,
+ &TrainEngineReliabilitySorter,
+};
+
+static const StringID _engine_sort_listing[] = {
+ STR_ENGINE_SORT_ENGINE_ID,
+ STR_ENGINE_SORT_COST,
+ STR_SORT_BY_MAX_SPEED,
+ STR_ENGINE_SORT_POWER,
+ STR_ENGINE_SORT_INTRO_DATE,
+ STR_SORT_BY_DROPDOWN_NAME,
+ STR_ENGINE_SORT_RUNNING_COST,
+ STR_ENGINE_SORT_POWER_VS_RUNNING_COST,
+ STR_SORT_BY_RELIABILITY,
+ INVALID_STRING_ID
+};
+
+/**
+ * Draw the purchase info details of train engine at a given location.
+ * @param x,y location where to draw the info
+ * @param engine_number the engine of which to draw the info of
+ */
+void DrawTrainEnginePurchaseInfo(int x, int y, uint w, EngineID engine_number)
+{
+ const RailVehicleInfo *rvi = RailVehInfo(engine_number);
+ const Engine *e = GetEngine(engine_number);
+ int multihead = (rvi->flags&RVI_MULTIHEAD?1:0);
+ YearMonthDay ymd;
+ ConvertDateToYMD(e->intro_date, &ymd);
+
+ /* Purchase Cost - Engine weight */
+ SetDParam(0, rvi->base_cost * (_price.build_railvehicle >> 3) >> 5);
+ SetDParam(1, rvi->weight << multihead);
+ DrawString(x,y, STR_PURCHASE_INFO_COST_WEIGHT, 0);
+ y += 10;
+
+ /* Max speed - Engine power */
+ SetDParam(0, rvi->max_speed);
+ SetDParam(1, rvi->power << multihead);
+ DrawString(x,y, STR_PURCHASE_INFO_SPEED_POWER, 0);
+ y += 10;
+
+ /* Max tractive effort - not applicable if old acceleration or maglev */
+ if (_patches.realistic_acceleration && e->railtype != RAILTYPE_MAGLEV) {
+ SetDParam(0, ((rvi->weight << multihead) * 10 * rvi->tractive_effort) / 256);
+ DrawString(x, y, STR_PURCHASE_INFO_MAX_TE, 0);
+ y += 10;
+ }
+
+ /* Running cost */
+ SetDParam(0, (rvi->running_cost_base * _price.running_rail[rvi->running_cost_class] >> 8) << multihead);
+ DrawString(x,y, STR_PURCHASE_INFO_RUNNINGCOST, 0);
+ y += 10;
+
+ /* Powered wagons power - Powered wagons extra weight */
+ if (rvi->pow_wag_power != 0) {
+ SetDParam(0, rvi->pow_wag_power);
+ SetDParam(1, rvi->pow_wag_weight);
+ DrawString(x,y, STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT, 0);
+ y += 10;
+ };
+
+ /* Cargo type + capacity, or N/A */
+ if (rvi->capacity == 0) {
+ SetDParam(0, CT_INVALID);
+ SetDParam(2, STR_EMPTY);
+ } else {
+ SetDParam(0, rvi->cargo_type);
+ SetDParam(1, (rvi->capacity * (CountArticulatedParts(engine_number) + 1)) << multihead);
+ SetDParam(2, STR_9842_REFITTABLE);
+ }
+ DrawString(x,y, STR_PURCHASE_INFO_CAPACITY, 0);
+ y += 10;
+
+ /* Design date - Life length */
+ SetDParam(0, ymd.year);
+ SetDParam(1, e->lifelength);
+ DrawString(x,y, STR_PURCHASE_INFO_DESIGNED_LIFE, 0);
+ y += 10;
+
+ /* Reliability */
+ SetDParam(0, e->reliability * 100 >> 16);
+ DrawString(x,y, STR_PURCHASE_INFO_RELIABILITY, 0);
+ y += 10;
+
+ /* Additional text from NewGRF */
+ y += ShowAdditionalText(x, y, w, engine_number);
+ if (rvi->capacity > 0) y += ShowRefitOptionsList(x, y, w, engine_number);
+}
+
+/**
+ * Draw the purchase info details of a train wagon at a given location.
+ * @param x,y location where to draw the info
+ * @param engine_number the engine of which to draw the info of
+ */
+void DrawTrainWagonPurchaseInfo(int x, int y, uint w, EngineID engine_number)
+{
+ const RailVehicleInfo *rvi = RailVehInfo(engine_number);
+ bool refittable = (EngInfo(engine_number)->refit_mask != 0);
+
+ /* Purchase cost */
+ SetDParam(0, (rvi->base_cost * _price.build_railwagon) >> 8);
+ DrawString(x, y, STR_PURCHASE_INFO_COST, 0);
+ y += 10;
+
+ /* Wagon weight - (including cargo) */
+ SetDParam(0, rvi->weight);
+ SetDParam(1, (_cargoc.weights[rvi->cargo_type] * rvi->capacity >> 4) + rvi->weight);
+ DrawString(x, y, STR_PURCHASE_INFO_WEIGHT_CWEIGHT, 0);
+ y += 10;
+
+ /* Cargo type + capacity, or N/A */
+ if (rvi->capacity == 0) {
+ SetDParam(0, CT_INVALID);
+ SetDParam(2, STR_EMPTY);
+ } else {
+ SetDParam(0, rvi->cargo_type);
+ SetDParam(1, rvi->capacity * (CountArticulatedParts(engine_number) + 1));
+ SetDParam(2, refittable ? STR_9842_REFITTABLE : STR_EMPTY);
+ }
+ DrawString(x, y, STR_PURCHASE_INFO_CAPACITY, 0);
+ y += 10;
+
+ /* Wagon speed limit, displayed if above zero */
+ if (rvi->max_speed > 0 && _patches.wagon_speed_limits) {
+ SetDParam(0, rvi->max_speed);
+ DrawString(x,y, STR_PURCHASE_INFO_SPEED, 0);
+ y += 10;
+ }
+
+ /* Additional text from NewGRF */
+ y += ShowAdditionalText(x, y, w, engine_number);
+ y += ShowRefitOptionsList(x, y, w, engine_number);
+}
+
+void CcBuildWagon(bool success, TileIndex tile, uint32 p1, uint32 p2)
+{
+ Vehicle *v, *found;
+
+ if (!success) return;
+
+ // find a locomotive in the depot.
+ found = NULL;
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == VEH_Train && IsFrontEngine(v) &&
+ v->tile == tile &&
+ v->u.rail.track == 0x80) {
+ if (found != NULL) return; // must be exactly one.
+ found = v;
+ }
+ }
+
+ // if we found a loco,
+ if (found != NULL) {
+ found = GetLastVehicleInChain(found);
+ // put the new wagon at the end of the loco.
+ DoCommandP(0, _new_vehicle_id | (found->index << 16), 0, NULL, CMD_MOVE_RAIL_VEHICLE);
+ RebuildVehicleLists();
+ }
+}
+
+void CcBuildLoco(bool success, TileIndex tile, uint32 p1, uint32 p2)
+{
+ const Vehicle *v;
+
+ if (!success) return;
+
+ v = GetVehicle(_new_vehicle_id);
+ if (tile == _backup_orders_tile) {
+ _backup_orders_tile = 0;
+ RestoreVehicleOrders(v, _backup_orders_data);
+ }
+ ShowTrainViewWindow(v);
+}
+
+void CcCloneTrain(bool success, TileIndex tile, uint32 p1, uint32 p2)
+{
+ if (success) ShowTrainViewWindow(GetVehicle(_new_vehicle_id));
+}
+
+static void engine_drawing_loop(const EngineList *engines, int x, int *y, EngineID sel, EngineID position, int16 show_max)
+{
+ int count = min(EngList_Count(engines), show_max);
+ for (; position < count; *y += 14, position++) {
+ EngineID id = (*engines)[position];
+ DrawString(x + 59, *y + 2, GetCustomEngineName(id), sel == id ? 0xC : 0x10);
+ DrawTrainEngine(x + 29, *y + 6, id, GetEnginePalette(id, _local_player));
+ }
+}
+
+static void GenerateBuildList(Window *w)
+{
+ EngineID eid, sel_id;
+ int num_engines = 0;
+ int num_wagons = 0;
+ buildvehicle_d *bv = &WP(w, buildvehicle_d);
+
+ bv->filter.railtype = (w->window_number == 0) ? RAILTYPE_END : GetRailType(w->window_number);
+
+ EngList_RemoveAll(&bv->eng_list);
+
+ /* Make list of all available train engines and wagons.
+ * Also check to see if the previously selected engine is still available,
+ * and if not, reset selection to INVALID_ENGINE. This could be the case
+ * when engines become obsolete and are removed */
+ for (sel_id = INVALID_ENGINE, eid = 0; eid < NUM_TRAIN_ENGINES; eid++) {
+ const Engine *e = GetEngine(eid);
+ const RailVehicleInfo *rvi = RailVehInfo(eid);
+
+ if (bv->filter.railtype != RAILTYPE_END && !HasPowerOnRail(e->railtype, bv->filter.railtype)) continue;
+ if (!IsEngineBuildable(eid, VEH_Train, _local_player)) continue;
+
+ EngList_Add(&bv->eng_list, eid);
+ if ((rvi->flags & RVI_WAGON) == 0) {
+ num_engines++;
+ } else {
+ num_wagons++;
+ }
+
+ if (eid == bv->sel_engine) sel_id = eid;
+ }
+
+ bv->sel_engine = sel_id;
+
+ // make engines first, and then wagons, sorted by ListPositionOfEngine()
+ _internal_sort_order = false;
+ EngList_Sort(&bv->eng_list, TrainEnginesThenWagonsSorter);
+
+ // and then sort engines
+ _internal_sort_order = bv->descending_sort_order;
+ EngList_SortPartial(&bv->eng_list, _engine_sorter[bv->sort_criteria], 0, num_engines);
+
+ // and finally sort wagons
+ EngList_SortPartial(&bv->eng_list, _engine_sorter[bv->sort_criteria], num_engines, num_wagons);
+}
+
+static void DrawTrainBuildWindow(Window *w)
+{
+ const buildvehicle_d *bv = &WP(w, buildvehicle_d);
+ int x = 1;
+ int y = 27;
+ EngineID selected_id = bv->sel_engine;
+ int max = w->vscroll.pos + w->vscroll.cap;
+
+ SetWindowWidgetDisabledState(w, BUILD_TRAIN_WIDGET_BUILD, w->window_number == 0); // Disable unless we got a depot to build in
+
+ SetVScrollCount(w, EngList_Count(&bv->eng_list));
+ SetDParam(0, bv->filter.railtype + STR_881C_NEW_RAIL_VEHICLES);
+ DrawWindowWidgets(w);
+
+ /* Draw the engines */
+ engine_drawing_loop(&bv->eng_list, x, &y, selected_id, w->vscroll.pos, max);
+
+ if (selected_id != INVALID_ENGINE) {
+ const RailVehicleInfo *rvi = RailVehInfo(selected_id);
+ const Widget *wi = &w->widget[BUILD_TRAIN_WIDGET_PANEL];
+
+ if (rvi->flags & RVI_WAGON) {
+ DrawTrainWagonPurchaseInfo(2, wi->top + 1, wi->right - wi->left - 2, selected_id);
+ } else {
+ DrawTrainEnginePurchaseInfo(2, wi->top + 1, wi->right - wi->left - 2, selected_id);
+ }
+ }
+ DrawString(85, 15, _engine_sort_listing[bv->sort_criteria], 0x10);
+ DoDrawString(bv->descending_sort_order ? DOWNARROW : UPARROW, 69, 15, 0x10);
+}
+
+static void NewRailVehicleWndProc(Window *w, WindowEvent *e)
+{
+ buildvehicle_d *bv = &WP(w, buildvehicle_d);
+ switch (e->event) {
+ case WE_CREATE:
+ EngList_Create(&bv->eng_list);
+ bv->sel_engine = INVALID_ENGINE;
+ bv->sort_criteria = _last_sort_criteria;
+ bv->descending_sort_order = _last_sort_order;
+ GenerateBuildList(w);
+ /* Select the first engine in the list as default when opening the window */
+ if (EngList_Count(&bv->eng_list) > 0) bv->sel_engine = bv->eng_list[0];
+ break;
+
+ case WE_INVALIDATE_DATA:
+ GenerateBuildList(w);
+ break;
+
+ case WE_DESTROY:
+ EngList_Destroy(&bv->eng_list);
+ break;
+
+ case WE_PAINT:
+ DrawTrainBuildWindow(w);
+ break;
+
+ case WE_CLICK: {
+ switch (e->we.click.widget) {
+ case BUILD_TRAIN_WIDGET_SORT_ASCENDING_DESCENDING:
+ bv->descending_sort_order ^= true;
+ _last_sort_order = bv->descending_sort_order;
+ GenerateBuildList(w);
+ SetWindowDirty(w);
+ break;
+
+ case BUILD_TRAIN_WIDGET_SORT_TEXT: case BUILD_TRAIN_WIDGET_SORT_DROPDOWN:/* Select sorting criteria dropdown menu */
+ ShowDropDownMenu(w, _engine_sort_listing, bv->sort_criteria, BUILD_TRAIN_WIDGET_SORT_DROPDOWN, 0, 0);
+ return;
+
+ case BUILD_TRAIN_WIDGET_LIST: {
+ uint i = ((e->we.click.pt.y - 26) / 14) + w->vscroll.pos;
+ uint num_items = EngList_Count(&bv->eng_list);
+ bv->sel_engine = (i < num_items) ? bv->eng_list[i] : INVALID_ENGINE;
+ SetWindowDirty(w);
+ break;
+ }
+
+ case BUILD_TRAIN_WIDGET_BUILD: {
+ EngineID sel_eng = bv->sel_engine;
+ if (sel_eng != INVALID_ENGINE)
+ DoCommandP(w->window_number, sel_eng, 0, (RailVehInfo(sel_eng)->flags & RVI_WAGON) ? CcBuildWagon : CcBuildLoco, CMD_BUILD_RAIL_VEHICLE | CMD_MSG(STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE));
+ break;
+ }
+
+ case BUILD_TRAIN_WIDGET_RENAME: {
+ EngineID sel_eng = bv->sel_engine;
+ if (sel_eng != INVALID_ENGINE) {
+ bv->rename_engine = sel_eng;
+ ShowQueryString(GetCustomEngineName(sel_eng), STR_886A_RENAME_TRAIN_VEHICLE_TYPE, 31, 160, w, CS_ALPHANUMERAL);
+ }
+ break;
+ }
+ }
+ }
+ break;
+
+ case WE_ON_EDIT_TEXT: {
+ if (e->we.edittext.str[0] != '\0') {
+ _cmd_text = e->we.edittext.str;
+ DoCommandP(0, bv->rename_engine, 0, NULL, CMD_RENAME_ENGINE | CMD_MSG(STR_886B_CAN_T_RENAME_TRAIN_VEHICLE));
+ }
+ break;
+ }
+
+ case WE_DROPDOWN_SELECT: /* we have selected a dropdown item in the list */
+ if (bv->sort_criteria != e->we.dropdown.index) {
+ bv->sort_criteria = _last_sort_criteria = e->we.dropdown.index;
+ GenerateBuildList(w);
+ SetWindowDirty(w);
+ }
+ break;
+
+ case WE_RESIZE: {
+ if (e->we.sizing.diff.y == 0) break;
+
+ w->vscroll.cap += e->we.sizing.diff.y / 14;
+ w->widget[BUILD_TRAIN_WIDGET_LIST].data = (w->vscroll.cap << 8) + 1;
+ break;
+ }
+ }
+}
+
+static const WindowDesc _new_rail_vehicle_desc = {
+ WDP_AUTO, WDP_AUTO, 228, 252,
+ WC_BUILD_VEHICLE,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
+ _new_rail_vehicle_widgets,
+ NewRailVehicleWndProc
+};
+
+void ShowBuildTrainWindow(TileIndex tile)
+{
+ Window *w;
+
+ DeleteWindowById(WC_BUILD_VEHICLE, tile);
+
+ w = AllocateWindowDescFront(&_new_rail_vehicle_desc, tile);
+ w->vscroll.cap = 8;
+ w->widget[BUILD_TRAIN_WIDGET_LIST].data = (w->vscroll.cap << 8) + 1;
+
+ w->resize.step_height = 14;
+ w->resize.height = w->height - 14 * 4; // Minimum of 4 vehicles in the display
+
+ if (tile != 0) {
+ w->caption_color = GetTileOwner(tile);
+ WP(w,buildvehicle_d).filter.railtype = GetRailType(tile);
+ } else {
+ w->caption_color = _local_player;
+ WP(w,buildvehicle_d).filter.railtype = RAILTYPE_END;
+ }
+}
+
+/**
+ * Get the number of pixels for the given wagon length.
+ * @param len Length measured in 1/8ths of a standard wagon.
+ * @return Number of pixels across.
+ */
+int WagonLengthToPixels(int len) {
+ return (len * _traininfo_vehicle_width) / 8;
+}
+
+void DrawTrainImage(const Vehicle *v, int x, int y, int count, int skip, VehicleID selection)
+{
+ DrawPixelInfo tmp_dpi, *old_dpi;
+ int dx = -(skip * 8) / _traininfo_vehicle_width;
+ /* Position of highlight box */
+ int highlight_l = 0;
+ int highlight_r = 0;
+
+ if (!FillDrawPixelInfo(&tmp_dpi, x - 2, y - 1, count + 1, 14)) return;
+
+ count = (count * 8) / _traininfo_vehicle_width;
+
+ old_dpi = _cur_dpi;
+ _cur_dpi = &tmp_dpi;
+
+ do {
+ int width = v->u.rail.cached_veh_length;
+
+ if (dx + width > 0) {
+ if (dx <= count) {
+ PalSpriteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
+ DrawSprite(GetTrainImage(v, DIR_W) | pal, 16 + WagonLengthToPixels(dx), 7 + (is_custom_sprite(RailVehInfo(v->engine_type)->image_index) ? _traininfo_vehicle_pitch : 0));
+ if (v->index == selection) {
+ /* Set the highlight position */
+ highlight_l = WagonLengthToPixels(dx) + 1;
+ highlight_r = WagonLengthToPixels(dx + width) + 1;
+ }
+ }
+ }
+ dx += width;
+
+ v = v->next;
+ } while (dx < count && v != NULL);
+
+ if (highlight_l != highlight_r) {
+ /* Draw the highlight. Now done after drawing all the engines, as
+ * the next engine after the highlight could overlap it. */
+ DrawFrameRect(highlight_l, 0, highlight_r, 13, 15, FR_BORDERONLY);
+ }
+
+ _cur_dpi = old_dpi;
+}
+
+static const Widget _train_view_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW },
+{ WWT_CAPTION, RESIZE_RIGHT, 14, 11, 237, 0, 13, STR_882E, STR_018C_WINDOW_TITLE_DRAG_THIS },
+{ WWT_STICKYBOX, RESIZE_LR, 14, 238, 249, 0, 13, 0x0, STR_STICKY_BUTTON },
+{ WWT_PANEL, RESIZE_RB, 14, 0, 231, 14, 121, 0x0, STR_NULL },
+{ WWT_INSET, RESIZE_RB, 14, 2, 229, 16, 119, 0x0, STR_NULL },
+{ WWT_PUSHBTN, RESIZE_RTB, 14, 0, 237, 122, 133, 0x0, STR_8846_CURRENT_TRAIN_ACTION_CLICK },
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 232, 249, 14, 31, SPR_CENTRE_VIEW_VEHICLE, STR_8848_CENTER_MAIN_VIEW_ON_TRAIN },
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 232, 249, 32, 49, SPR_SEND_TRAIN_TODEPOT, STR_8849_SEND_TRAIN_TO_DEPOT },
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 232, 249, 50, 67, SPR_IGNORE_SIGNALS, STR_884A_FORCE_TRAIN_TO_PROCEED },
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 232, 249, 68, 85, SPR_FORCE_VEHICLE_TURN, STR_884B_REVERSE_DIRECTION_OF_TRAIN },
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 232, 249, 86, 103, SPR_SHOW_ORDERS, STR_8847_SHOW_TRAIN_S_ORDERS },
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 232, 249, 104, 121, SPR_SHOW_VEHICLE_DETAILS,STR_884C_SHOW_TRAIN_DETAILS },
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 232, 249, 68, 85, SPR_REFIT_VEHICLE, STR_RAIL_REFIT_VEHICLE_TO_CARRY },
+{ WWT_PUSHIMGBTN, RESIZE_LR, 14, 232, 249, 32, 49, SPR_CLONE_TRAIN, STR_CLONE_TRAIN_INFO },
+{ WWT_PANEL, RESIZE_LRB, 14, 232, 249, 122, 121, 0x0, STR_NULL },
+{ WWT_RESIZEBOX, RESIZE_LRTB, 14, 238, 249, 122, 133, 0x0, STR_NULL },
+{ WIDGETS_END }
+};
+
+static void ShowTrainDetailsWindow(const Vehicle *v);
+
+static void TrainViewWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ const Vehicle *v, *u;
+ StringID str;
+ bool is_localplayer;
+
+ v = GetVehicle(w->window_number);
+
+ is_localplayer = v->owner == _local_player;
+ SetWindowWidgetDisabledState(w, 7, !is_localplayer);
+ SetWindowWidgetDisabledState(w, 8, !is_localplayer);
+ SetWindowWidgetDisabledState(w, 9, !is_localplayer);
+ SetWindowWidgetDisabledState(w, 13, !is_localplayer);
+
+ /* Disable cargo refit button, until we know we can enable it below. */
+ DisableWindowWidget(w, 12);
+
+ if (is_localplayer) {
+ /* See if any vehicle can be refitted */
+ for (u = v; u != NULL; u = u->next) {
+ if (EngInfo(u->engine_type)->refit_mask != 0 ||
+ (!(RailVehInfo(v->engine_type)->flags & RVI_WAGON) && v->cargo_cap != 0)) {
+ EnableWindowWidget(w, 12);
+ /* We have a refittable carriage, bail out */
+ break;
+ }
+ }
+ }
+
+ /* draw widgets & caption */
+ SetDParam(0, v->string_id);
+ SetDParam(1, v->unitnumber);
+ DrawWindowWidgets(w);
+
+ if (v->u.rail.crash_anim_pos != 0) {
+ str = STR_8863_CRASHED;
+ } else if (v->breakdown_ctr == 1) {
+ str = STR_885C_BROKEN_DOWN;
+ } else if (v->vehstatus & VS_STOPPED) {
+ if (v->u.rail.last_speed == 0) {
+ if (v->u.rail.cached_power == 0) {
+ str = STR_TRAIN_NO_POWER;
+ } else {
+ str = STR_8861_STOPPED;
+ }
+ } else {
+ SetDParam(0, v->u.rail.last_speed);
+ str = STR_TRAIN_STOPPING + _patches.vehicle_speed;
+ }
+ } else {
+ switch (v->current_order.type) {
+ case OT_GOTO_STATION: {
+ str = STR_HEADING_FOR_STATION + _patches.vehicle_speed;
+ SetDParam(0, v->current_order.dest);
+ SetDParam(1, v->u.rail.last_speed);
+ } break;
+
+ case OT_GOTO_DEPOT: {
+ Depot *dep = GetDepot(v->current_order.dest);
+ SetDParam(0, dep->town_index);
+ if (HASBIT(v->current_order.flags, OFB_HALT_IN_DEPOT) && !HASBIT(v->current_order.flags, OFB_PART_OF_ORDERS)) {
+ str = STR_HEADING_FOR_TRAIN_DEPOT + _patches.vehicle_speed;
+ } else {
+ str = STR_HEADING_FOR_TRAIN_DEPOT_SERVICE + _patches.vehicle_speed;
+ }
+ SetDParam(1, v->u.rail.last_speed);
+ } break;
+
+ case OT_LOADING:
+ case OT_LEAVESTATION:
+ str = STR_882F_LOADING_UNLOADING;
+ break;
+
+ case OT_GOTO_WAYPOINT: {
+ SetDParam(0, v->current_order.dest);
+ str = STR_HEADING_FOR_WAYPOINT + _patches.vehicle_speed;
+ SetDParam(1, v->u.rail.last_speed);
+ break;
+ }
+
+ default:
+ if (v->num_orders == 0) {
+ str = STR_NO_ORDERS + _patches.vehicle_speed;
+ SetDParam(0, v->u.rail.last_speed);
+ } else {
+ str = STR_EMPTY;
+ }
+ break;
+ }
+ }
+
+ /* draw the flag plus orders */
+ DrawSprite(v->vehstatus & VS_STOPPED ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, 2, w->widget[5].top + 1);
+ DrawStringCenteredTruncated(w->widget[5].left + 8, w->widget[5].right, w->widget[5].top + 1, str, 0);
+ DrawWindowViewport(w);
+ } break;
+
+ case WE_CLICK: {
+ int wid = e->we.click.widget;
+ Vehicle *v = GetVehicle(w->window_number);
+
+ switch (wid) {
+ case 5: /* start/stop train */
+ DoCommandP(v->tile, v->index, 0, NULL, CMD_START_STOP_TRAIN | CMD_MSG(STR_883B_CAN_T_STOP_START_TRAIN));
+ break;
+ case 6: /* center main view */
+ ScrollMainWindowTo(v->x_pos, v->y_pos);
+ break;
+ case 7: /* goto depot */
+ /* TrainGotoDepot has a nice randomizer in the pathfinder, which causes desyncs... */
+ DoCommandP(v->tile, v->index, _ctrl_pressed ? DEPOT_SERVICE : 0, NULL, CMD_SEND_TRAIN_TO_DEPOT | CMD_NO_TEST_IF_IN_NETWORK | CMD_MSG(STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT));
+ break;
+ case 8: /* force proceed */
+ DoCommandP(v->tile, v->index, 0, NULL, CMD_FORCE_TRAIN_PROCEED | CMD_MSG(STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL));
+ break;
+ case 9: /* reverse direction */
+ DoCommandP(v->tile, v->index, 0, NULL, CMD_REVERSE_TRAIN_DIRECTION | CMD_MSG(STR_8869_CAN_T_REVERSE_DIRECTION));
+ break;
+ case 10: /* show train orders */
+ ShowOrdersWindow(v);
+ break;
+ case 11: /* show train details */
+ ShowTrainDetailsWindow(v);
+ break;
+ case 12:
+ ShowVehicleRefitWindow(v, INVALID_VEH_ORDER_ID);
+ break;
+ case 13:
+ DoCommandP(v->tile, v->index, _ctrl_pressed ? 1 : 0, NULL, CMD_CLONE_VEHICLE | CMD_MSG(STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE));
+ break;
+ }
+ } break;
+
+ case WE_RESIZE:
+ w->viewport->width += e->we.sizing.diff.x;
+ w->viewport->height += e->we.sizing.diff.y;
+ w->viewport->virtual_width += e->we.sizing.diff.x;
+ w->viewport->virtual_height += e->we.sizing.diff.y;
+ break;
+
+ case WE_DESTROY:
+ DeleteWindowById(WC_VEHICLE_REFIT, w->window_number);
+ DeleteWindowById(WC_VEHICLE_ORDERS, w->window_number);
+ DeleteWindowById(WC_VEHICLE_DETAILS, w->window_number);
+ break;
+
+ case WE_MOUSELOOP: {
+ const Vehicle *v = GetVehicle(w->window_number);
+ bool train_stopped = CheckTrainStoppedInDepot(v) >= 0;
+
+ /* Widget 7 (send to depot) must be hidden if the train is already stopped in hangar.
+ * Widget 13 (clone) should then be shown, since cloning is allowed only while in depot and stopped.
+ * This sytem allows to have two buttons, on top of each other.
+ * The same system applies to widget 9 and 12, reverse direction and refit*/
+ if (train_stopped != IsWindowWidgetHidden(w, 7) || train_stopped == IsWindowWidgetHidden(w, 13)) {
+ SetWindowWidgetHiddenState(w, 7, train_stopped); // send to depot
+ SetWindowWidgetHiddenState(w, 9, train_stopped); // reverse direction
+ SetWindowWidgetHiddenState(w, 12, !train_stopped); // refit
+ SetWindowWidgetHiddenState(w, 13, !train_stopped); // clone
+ SetWindowDirty(w);
+ }
+ break;
+ }
+
+ }
+}
+
+static const WindowDesc _train_view_desc = {
+ WDP_AUTO, WDP_AUTO, 250, 134,
+ WC_VEHICLE_VIEW,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
+ _train_view_widgets,
+ TrainViewWndProc
+};
+
+void ShowTrainViewWindow(const Vehicle *v)
+{
+ Window *w = AllocateWindowDescFront(&_train_view_desc,v->index);
+
+ if (w != NULL) {
+ w->caption_color = v->owner;
+ AssignWindowViewport(w, 3, 17, 0xE2, 0x66, w->window_number | (1 << 31), 0);
+ }
+}
+
+static void TrainDetailsCargoTab(const Vehicle *v, int x, int y)
+{
+ if (v->cargo_cap != 0) {
+ uint num = v->cargo_count;
+ StringID str = STR_8812_EMPTY;
+
+ if (num != 0) {
+ SetDParam(0, v->cargo_type);
+ SetDParam(1, num);
+ SetDParam(2, v->cargo_source);
+ SetDParam(3, _patches.freight_trains);
+ str = FreightWagonMult(v->cargo_type) > 1 ? STR_FROM_MULT : STR_8813_FROM;
+ }
+ DrawString(x, y, str, 0);
+ }
+}
+
+static void TrainDetailsInfoTab(const Vehicle *v, int x, int y)
+{
+ if (RailVehInfo(v->engine_type)->flags & RVI_WAGON) {
+ SetDParam(0, GetCustomEngineName(v->engine_type));
+ SetDParam(1, v->value);
+ DrawString(x, y, STR_882D_VALUE, 0x10);
+ } else {
+ SetDParam(0, GetCustomEngineName(v->engine_type));
+ SetDParam(1, v->build_year);
+ SetDParam(2, v->value);
+ DrawString(x, y, STR_882C_BUILT_VALUE, 0x10);
+ }
+}
+
+static void TrainDetailsCapacityTab(const Vehicle *v, int x, int y)
+{
+ if (v->cargo_cap != 0) {
+ SetDParam(0, v->cargo_type);
+ SetDParam(1, v->cargo_cap);
+ SetDParam(2, _patches.freight_trains);
+ DrawString(x, y, FreightWagonMult(v->cargo_type) > 1 ? STR_CAPACITY_MULT : STR_013F_CAPACITY, 0);
+ }
+}
+
+
+static void DrawTrainDetailsWindow(Window *w)
+{
+ byte det_tab = WP(w, traindetails_d).tab;
+ const Vehicle *v;
+ const Vehicle *u;
+ AcceptedCargo act_cargo;
+ AcceptedCargo max_cargo;
+ uint i;
+ int num;
+ int x;
+ int y;
+ int sel;
+
+ num = 0;
+ u = v = GetVehicle(w->window_number);
+ if (det_tab == 3) { // Total cargo tab
+ for (i = 0; i < lengthof(act_cargo); i++) {
+ act_cargo[i] = 0;
+ max_cargo[i] = 0;
+ }
+
+ do {
+ act_cargo[u->cargo_type] += u->cargo_count;
+ max_cargo[u->cargo_type] += u->cargo_cap;
+ } while ((u = u->next) != NULL);
+
+ /* Set scroll-amount seperately from counting, as to not compute num double
+ * for more carriages of the same type
+ */
+ for (i = 0; i != NUM_CARGO; i++) {
+ if (max_cargo[i] > 0) num++; // only count carriages that the train has
+ }
+ num++; // needs one more because first line is description string
+ } else {
+ do {
+ if (!IsArticulatedPart(u) || u->cargo_cap != 0) num++;
+ } while ((u = u->next) != NULL);
+ }
+
+ SetVScrollCount(w, num);
+
+ DisableWindowWidget(w, det_tab + 9);
+ SetWindowWidgetDisabledState(w, 2, v->owner != _local_player);
+
+ /* disable service-scroller when interval is set to disabled */
+ SetWindowWidgetDisabledState(w, 6, !_patches.servint_trains);
+ SetWindowWidgetDisabledState(w, 7, !_patches.servint_trains);
+
+ SetDParam(0, v->string_id);
+ SetDParam(1, v->unitnumber);
+ DrawWindowWidgets(w);
+
+ SetDParam(1, v->age / 366);
+
+ x = 2;
+
+ SetDParam(0, (v->age + 365 < v->max_age) ? STR_AGE : STR_AGE_RED);
+ SetDParam(2, v->max_age / 366);
+ SetDParam(3, GetTrainRunningCost(v) >> 8);
+ DrawString(x, 15, STR_885D_AGE_RUNNING_COST_YR, 0);
+
+ SetDParam(2, v->u.rail.cached_max_speed);
+ SetDParam(1, v->u.rail.cached_power);
+ SetDParam(0, v->u.rail.cached_weight);
+ SetDParam(3, v->u.rail.cached_max_te / 1000);
+ DrawString(x, 25, (_patches.realistic_acceleration && v->u.rail.railtype != RAILTYPE_MAGLEV) ?
+ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :
+ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED, 0);
+
+ SetDParam(0, v->profit_this_year);
+ SetDParam(1, v->profit_last_year);
+ DrawString(x, 35, STR_885F_PROFIT_THIS_YEAR_LAST_YEAR, 0);
+
+ SetDParam(0, 100 * (v->reliability>>8) >> 8);
+ SetDParam(1, v->breakdowns_since_last_service);
+ DrawString(x, 45, STR_8860_RELIABILITY_BREAKDOWNS, 0);
+
+ SetDParam(0, v->service_interval);
+ SetDParam(1, v->date_of_last_service);
+ DrawString(x + 11, 57 + (w->vscroll.cap * 14), _patches.servint_ispercent ? STR_SERVICING_INTERVAL_PERCENT : STR_883C_SERVICING_INTERVAL_DAYS, 0);
+
+ y = 57;
+ sel = w->vscroll.pos;
+
+ // draw the first 3 details tabs
+ if (det_tab != 3) {
+ x = 1;
+ for (;;) {
+ if (--sel < 0 && sel >= -w->vscroll.cap) {
+ int dx = 0;
+ int px;
+ int py;
+
+ u = v;
+ do {
+ PalSpriteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
+ DrawSprite(GetTrainImage(u, DIR_W) | pal, x + 14 + WagonLengthToPixels(dx), y + 6 + (is_custom_sprite(RailVehInfo(u->engine_type)->image_index) ? _traininfo_vehicle_pitch : 0));
+ dx += u->u.rail.cached_veh_length;
+ u = u->next;
+ } while (u != NULL && IsArticulatedPart(u) && u->cargo_cap == 0);
+
+ px = x + WagonLengthToPixels(dx) + 2;
+ py = y + 2;
+ switch (det_tab) {
+ default: NOT_REACHED();
+ case 0: TrainDetailsCargoTab( v, px, py); break;
+ case 1:
+ // Only show name and value for the 'real' part
+ if (!IsArticulatedPart(v)) {
+ TrainDetailsInfoTab(v, px, py);
+ }
+ break;
+ case 2: TrainDetailsCapacityTab(v, px, py); break;
+ }
+ y += 14;
+
+ v = u;
+ } else {
+ // Move to the next line
+ do {
+ v = v->next;
+ } while (v != NULL && IsArticulatedPart(v) && v->cargo_cap == 0);
+ }
+ if (v == NULL) return;
+ }
+ } else {
+ // draw total cargo tab
+ DrawString(x, y + 2, STR_013F_TOTAL_CAPACITY_TEXT, 0);
+ for (i = 0; i != NUM_CARGO; i++) {
+ if (max_cargo[i] > 0 && --sel < 0 && sel > -w->vscroll.cap) {
+ y += 14;
+ SetDParam(0, i); // {CARGO} #1
+ SetDParam(1, act_cargo[i]); // {CARGO} #2
+ SetDParam(2, i); // {SHORTCARGO} #1
+ SetDParam(3, max_cargo[i]); // {SHORTCARGO} #2
+ SetDParam(4, _patches.freight_trains);
+ DrawString(x, y + 2, FreightWagonMult(i) > 1 ? STR_TOTAL_CAPACITY_MULT : STR_013F_TOTAL_CAPACITY, 0);
+ }
+ }
+ }
+}
+
+static void TrainDetailsWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT:
+ DrawTrainDetailsWindow(w);
+ break;
+ case WE_CLICK: {
+ int mod;
+ const Vehicle *v;
+ switch (e->we.click.widget) {
+ case 2: /* name train */
+ v = GetVehicle(w->window_number);
+ SetDParam(0, v->unitnumber);
+ ShowQueryString(v->string_id, STR_8865_NAME_TRAIN, 31, 150, w, CS_ALPHANUMERAL);
+ break;
+ case 6: /* inc serv interval */
+ mod = _ctrl_pressed? 5 : 10;
+ goto do_change_service_int;
+
+ case 7: /* dec serv interval */
+ mod = _ctrl_pressed? -5 : -10;
+do_change_service_int:
+ v = GetVehicle(w->window_number);
+
+ mod = GetServiceIntervalClamped(mod + v->service_interval);
+ if (mod == v->service_interval) return;
+
+ DoCommandP(v->tile, v->index, mod, NULL, CMD_CHANGE_SERVICE_INT | CMD_MSG(STR_018A_CAN_T_CHANGE_SERVICING));
+ break;
+ /* details buttons*/
+ case 9: // Cargo
+ case 10: // Information
+ case 11: // Capacities
+ case 12: // Total cargo
+ EnableWindowWidget(w, 9);
+ EnableWindowWidget(w, 10);
+ EnableWindowWidget(w, 11);
+ EnableWindowWidget(w, 12);
+ EnableWindowWidget(w, e->we.click.widget);
+ WP(w,traindetails_d).tab = e->we.click.widget - 9;
+ SetWindowDirty(w);
+ break;
+ }
+ } break;
+
+ case WE_ON_EDIT_TEXT:
+ if (e->we.edittext.str[0] != '\0') {
+ _cmd_text = e->we.edittext.str;
+ DoCommandP(0, w->window_number, 0, NULL,
+ CMD_NAME_VEHICLE | CMD_MSG(STR_8866_CAN_T_NAME_TRAIN));
+ }
+ break;
+
+ case WE_RESIZE:
+ if (e->we.sizing.diff.y == 0) break;
+
+ w->vscroll.cap += e->we.sizing.diff.y / 14;
+ w->widget[4].data = (w->vscroll.cap << 8) + 1;
+ break;
+ }
+}
+
+static const Widget _train_details_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 329, 0, 13, STR_8802_DETAILS, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 330, 369, 0, 13, STR_01AA_NAME, STR_8867_NAME_TRAIN},
+{ WWT_PANEL, RESIZE_NONE, 14, 0, 369, 14, 55, 0x0, STR_NULL},
+{ WWT_MATRIX, RESIZE_BOTTOM, 14, 0, 357, 56, 139, 0x601, STR_NULL},
+{ WWT_SCROLLBAR, RESIZE_BOTTOM, 14, 358, 369, 56, 139, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 10, 140, 145, STR_0188, STR_884D_INCREASE_SERVICING_INTERVAL},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 10, 146, 151, STR_0189, STR_884E_DECREASE_SERVICING_INTERVAL},
+{ WWT_PANEL, RESIZE_TB, 14, 11, 369, 140, 151, 0x0, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 89, 152, 163, STR_013C_CARGO, STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 90, 178, 152, 163, STR_013D_INFORMATION, STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 179, 268, 152, 163, STR_013E_CAPACITIES, STR_8851_SHOW_CAPACITIES_OF_EACH},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 269, 357, 152, 163, STR_013E_TOTAL_CARGO, STR_8852_SHOW_TOTAL_CARGO},
+{ WWT_RESIZEBOX, RESIZE_TB, 14, 358, 369, 152, 163, 0x0, STR_RESIZE_BUTTON},
+{ WIDGETS_END},
+};
+
+
+static const WindowDesc _train_details_desc = {
+ WDP_AUTO, WDP_AUTO, 370, 164,
+ WC_VEHICLE_DETAILS,WC_VEHICLE_VIEW,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
+ _train_details_widgets,
+ TrainDetailsWndProc
+};
+
+
+static void ShowTrainDetailsWindow(const Vehicle *v)
+{
+ Window *w;
+ VehicleID veh = v->index;
+
+ DeleteWindowById(WC_VEHICLE_ORDERS, veh);
+ DeleteWindowById(WC_VEHICLE_DETAILS, veh);
+
+ w = AllocateWindowDescFront(&_train_details_desc, veh);
+
+ w->caption_color = v->owner;
+ w->vscroll.cap = 6;
+ w->widget[4].data = (w->vscroll.cap << 8) + 1;
+
+ w->resize.step_height = 14;
+ w->resize.height = w->height - 14 * 2; /* Minimum of 4 wagons in the display */
+
+ WP(w,traindetails_d).tab = 0;
+}
diff --git a/src/tree_cmd.c b/src/tree_cmd.c
new file mode 100644
index 000000000..ccdbcfbad
--- /dev/null
+++ b/src/tree_cmd.c
@@ -0,0 +1,672 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "bridge_map.h"
+#include "clear_map.h"
+#include "table/strings.h"
+#include "table/sprites.h"
+#include "table/tree_land.h"
+#include "functions.h"
+#include "map.h"
+#include "tile.h"
+#include "tree_map.h"
+#include "viewport.h"
+#include "command.h"
+#include "town.h"
+#include "sound.h"
+#include "variables.h"
+#include "genworld.h"
+
+enum TreePlacer {
+ TP_NONE,
+ TP_ORIGINAL,
+ TP_IMPROVED,
+};
+
+static TreeType GetRandomTreeType(TileIndex tile, uint seed)
+{
+ switch (_opt.landscape) {
+ case LT_NORMAL:
+ return seed * TREE_COUNT_TEMPERATE / 256 + TREE_TEMPERATE;
+
+ case LT_HILLY:
+ return seed * TREE_COUNT_SUB_ARCTIC / 256 + TREE_SUB_ARCTIC;
+
+ case LT_DESERT:
+ switch (GetTropicZone(tile)) {
+ case TROPICZONE_INVALID: return seed * TREE_COUNT_SUB_TROPICAL / 256 + TREE_SUB_TROPICAL;
+ case TROPICZONE_DESERT: return (seed > 12) ? TREE_INVALID : TREE_CACTUS;
+ default: return seed * TREE_COUNT_RAINFOREST / 256 + TREE_RAINFOREST;
+ }
+
+ default:
+ return seed * TREE_COUNT_TOYLAND / 256 + TREE_TOYLAND;
+ }
+}
+
+static void PlaceTree(TileIndex tile, uint32 r)
+{
+ TreeType tree = GetRandomTreeType(tile, GB(r, 24, 8));
+
+ if (tree != TREE_INVALID) {
+ MakeTree(tile, tree, GB(r, 22, 2), min(GB(r, 16, 3), 6), TREE_GROUND_GRASS, 0);
+
+ // above snowline?
+ if (_opt.landscape == LT_HILLY && GetTileZ(tile) > _opt.snow_line) {
+ SetTreeGroundDensity(tile, TREE_GROUND_SNOW_DESERT, 3);
+ SetTreeCounter(tile, GB(r, 24, 3));
+ } else {
+ SetTreeGroundDensity(tile, GB(r, 28, 1), 0);
+ SetTreeCounter(tile, GB(r, 24, 4));
+ }
+ }
+}
+
+static void DoPlaceMoreTrees(TileIndex tile)
+{
+ uint i;
+
+ for (i = 0; i < 1000; i++) {
+ uint32 r = Random();
+ int x = GB(r, 0, 5) - 16;
+ int y = GB(r, 8, 5) - 16;
+ uint dist = myabs(x) + myabs(y);
+ TileIndex cur_tile = TILE_MASK(tile + TileDiffXY(x, y));
+
+ if (dist <= 13 &&
+ IsTileType(cur_tile, MP_CLEAR) &&
+ !IsBridgeAbove(cur_tile) &&
+ !IsClearGround(cur_tile, CLEAR_FIELDS) &&
+ !IsClearGround(cur_tile, CLEAR_ROCKS)) {
+ PlaceTree(cur_tile, r);
+ }
+ }
+}
+
+static void PlaceMoreTrees(void)
+{
+ uint i = ScaleByMapSize(GB(Random(), 0, 5) + 25);
+ do {
+ DoPlaceMoreTrees(RandomTile());
+ } while (--i);
+}
+
+/**
+ * Place a tree at the same height as an existing tree.
+ * This gives cool effects to the map.
+ */
+void PlaceTreeAtSameHeight(TileIndex tile, uint height)
+{
+ uint i;
+
+ for (i = 0; i < 1000; i++) {
+ uint32 r = Random();
+ int x = GB(r, 0, 5) - 16;
+ int y = GB(r, 8, 5) - 16;
+ TileIndex cur_tile = TILE_MASK(tile + TileDiffXY(x, y));
+
+ /* Keep in range of the existing tree */
+ if (myabs(x) + myabs(y) > 16) continue;
+
+ /* Clear tile, no farm-tiles or rocks */
+ if (!IsTileType(cur_tile, MP_CLEAR) ||
+ IsClearGround(cur_tile, CLEAR_FIELDS) ||
+ IsClearGround(cur_tile, CLEAR_ROCKS))
+ continue;
+
+ /* Not too much height difference */
+ if (myabs(GetTileZ(cur_tile) - height) > 2) continue;
+
+ /* Place one tree and quit */
+ PlaceTree(cur_tile, r);
+ break;
+ }
+}
+
+void PlaceTreesRandomly(void)
+{
+ uint i, j, ht;
+
+ i = ScaleByMapSize(1000);
+ do {
+ uint32 r = Random();
+ TileIndex tile = RandomTileSeed(r);
+
+ IncreaseGeneratingWorldProgress(GWP_TREE);
+
+ if (IsTileType(tile, MP_CLEAR) &&
+ !IsBridgeAbove(tile) &&
+ !IsClearGround(tile, CLEAR_FIELDS) &&
+ !IsClearGround(tile, CLEAR_ROCKS)) {
+ PlaceTree(tile, r);
+ if (_patches.tree_placer != TP_IMPROVED) continue;
+
+ /* Place a number of trees based on the tile height.
+ * This gives a cool effect of multiple trees close together.
+ * It is almost real life ;) */
+ ht = GetTileZ(tile);
+ /* The higher we get, the more trees we plant */
+ j = GetTileZ(tile) / TILE_HEIGHT * 2;
+ while (j--) {
+ /* Above snowline more trees! */
+ if (_opt.landscape == LT_HILLY && ht > _opt.snow_line) {
+ PlaceTreeAtSameHeight(tile, ht);
+ PlaceTreeAtSameHeight(tile, ht);
+ };
+
+ PlaceTreeAtSameHeight(tile, ht);
+ }
+ }
+ } while (--i);
+
+ /* place extra trees at rainforest area */
+ if (_opt.landscape == LT_DESERT) {
+ i = ScaleByMapSize(15000);
+
+ do {
+ uint32 r = Random();
+ TileIndex tile = RandomTileSeed(r);
+
+ IncreaseGeneratingWorldProgress(GWP_TREE);
+
+ if (IsTileType(tile, MP_CLEAR) &&
+ !IsBridgeAbove(tile) &&
+ !IsClearGround(tile, CLEAR_FIELDS) &&
+ GetTropicZone(tile) == TROPICZONE_RAINFOREST) {
+ PlaceTree(tile, r);
+ }
+ } while (--i);
+ }
+}
+
+void GenerateTrees(void)
+{
+ uint i, total;
+
+ if (_patches.tree_placer == TP_NONE) return;
+
+ if (_opt.landscape != LT_CANDY) PlaceMoreTrees();
+
+ switch (_patches.tree_placer) {
+ case TP_ORIGINAL: i = _opt.landscape == LT_HILLY ? 15 : 6; break;
+ case TP_IMPROVED: i = _opt.landscape == LT_HILLY ? 4 : 2; break;
+ default: NOT_REACHED(); return;
+ }
+
+ total = ScaleByMapSize(1000);
+ if (_opt.landscape == LT_DESERT) total += ScaleByMapSize(15000);
+ total *= i;
+ SetGeneratingWorldProgress(GWP_TREE, total);
+
+ for (; i != 0; i--) {
+ PlaceTreesRandomly();
+ }
+}
+
+/** Plant a tree.
+ * @param tile start tile of area-drag of tree plantation
+ * @param p1 tree type, -1 means random.
+ * @param p2 end tile of area-drag
+ */
+int32 CmdPlantTree(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ StringID msg = INVALID_STRING_ID;
+ int32 cost;
+ int ex;
+ int ey;
+ int sx, sy, x, y;
+
+ if (p2 >= MapSize()) return CMD_ERROR;
+ /* Check the tree type. It can be random or some valid value within the current climate */
+ if (p1 != (uint)-1 && p1 - _tree_base_by_landscape[_opt.landscape] >= _tree_count_by_landscape[_opt.landscape]) return CMD_ERROR;
+
+ SET_EXPENSES_TYPE(EXPENSES_OTHER);
+
+ // make sure sx,sy are smaller than ex,ey
+ ex = TileX(tile);
+ ey = TileY(tile);
+ sx = TileX(p2);
+ sy = TileY(p2);
+ if (ex < sx) intswap(ex, sx);
+ if (ey < sy) intswap(ey, sy);
+
+ cost = 0; // total cost
+
+ for (x = sx; x <= ex; x++) {
+ for (y = sy; y <= ey; y++) {
+ TileIndex tile = TileXY(x, y);
+
+ if (!EnsureNoVehicle(tile)) continue;
+
+ switch (GetTileType(tile)) {
+ case MP_TREES:
+ // no more space for trees?
+ if (_game_mode != GM_EDITOR && GetTreeCount(tile) == 3) {
+ msg = STR_2803_TREE_ALREADY_HERE;
+ continue;
+ }
+
+ if (flags & DC_EXEC) {
+ AddTreeCount(tile, 1);
+ MarkTileDirtyByTile(tile);
+ }
+ // 2x as expensive to add more trees to an existing tile
+ cost += _price.build_trees * 2;
+ break;
+
+ case MP_CLEAR:
+ if (!IsTileOwner(tile, OWNER_NONE) ||
+ IsBridgeAbove(tile)) {
+ msg = STR_2804_SITE_UNSUITABLE;
+ continue;
+ }
+
+ switch (GetClearGround(tile)) {
+ case CLEAR_FIELDS: cost += _price.clear_3; break;
+ case CLEAR_ROCKS: cost += _price.clear_2; break;
+ default: break;
+ }
+
+ if (flags & DC_EXEC) {
+ TreeType treetype;
+ uint growth;
+
+ if (_game_mode != GM_EDITOR && IsValidPlayer(_current_player)) {
+ Town *t = ClosestTownFromTile(tile, _patches.dist_local_authority);
+ if (t != NULL)
+ ChangeTownRating(t, RATING_TREE_UP_STEP, RATING_TREE_MAXIMUM);
+ }
+
+ treetype = p1;
+ if (treetype == TREE_INVALID) {
+ treetype = GetRandomTreeType(tile, GB(Random(), 24, 8));
+ if (treetype == TREE_INVALID) treetype = TREE_CACTUS;
+ }
+
+ growth = _game_mode == GM_EDITOR ? 3 : 0;
+ switch (GetClearGround(tile)) {
+ case CLEAR_ROUGH: MakeTree(tile, treetype, 0, growth, TREE_GROUND_ROUGH, 0); break;
+ case CLEAR_SNOW: MakeTree(tile, treetype, 0, growth, TREE_GROUND_SNOW_DESERT, GetClearDensity(tile)); break;
+ default: MakeTree(tile, treetype, 0, growth, TREE_GROUND_GRASS, 0); break;
+ }
+ MarkTileDirtyByTile(tile);
+
+ if (_game_mode == GM_EDITOR && IS_INT_INSIDE(treetype, TREE_RAINFOREST, TREE_CACTUS))
+ SetTropicZone(tile, TROPICZONE_RAINFOREST);
+ }
+ cost += _price.build_trees;
+ break;
+
+ default:
+ msg = STR_2804_SITE_UNSUITABLE;
+ break;
+ }
+ }
+ }
+
+ if (cost == 0) {
+ return_cmd_error(msg);
+ } else {
+ return cost;
+ }
+}
+
+typedef struct TreeListEnt {
+ uint32 image;
+ byte x,y;
+} TreeListEnt;
+
+static void DrawTile_Trees(TileInfo *ti)
+{
+ const uint32 *s;
+ const TreePos* d;
+ byte z;
+
+ switch (GetTreeGround(ti->tile)) {
+ case TREE_GROUND_GRASS: DrawClearLandTile(ti, 3); break;
+ case TREE_GROUND_ROUGH: DrawHillyLandTile(ti); break;
+ default: DrawGroundSprite(_tree_sprites_1[GetTreeDensity(ti->tile)] + _tileh_to_sprite[ti->tileh]); break;
+ }
+
+ DrawClearLandFence(ti);
+
+ z = ti->z;
+ if (ti->tileh != SLOPE_FLAT) {
+ z += 4;
+ if (IsSteepSlope(ti->tileh)) z += 4;
+ }
+
+ {
+ uint16 tmp = ti->x;
+ uint index;
+
+ tmp = ROR(tmp, 2);
+ tmp -= ti->y;
+ tmp = ROR(tmp, 3);
+ tmp -= ti->x;
+ tmp = ROR(tmp, 1);
+ tmp += ti->y;
+
+ d = _tree_layout_xy[GB(tmp, 4, 2)];
+
+ index = GB(tmp, 6, 2) + (GetTreeType(ti->tile) << 2);
+
+ /* different tree styles above one of the grounds */
+ if (GetTreeGround(ti->tile) == TREE_GROUND_SNOW_DESERT &&
+ GetTreeDensity(ti->tile) >= 2 &&
+ IS_INT_INSIDE(index, TREE_SUB_ARCTIC << 2, TREE_RAINFOREST << 2)) {
+ index += 164 - (TREE_SUB_ARCTIC << 2);
+ }
+
+ assert(index < lengthof(_tree_layout_sprite));
+ s = _tree_layout_sprite[index];
+ }
+
+ StartSpriteCombine();
+
+ if (!(_display_opt & DO_TRANS_BUILDINGS) || !_patches.invisible_trees) {
+ TreeListEnt te[4];
+ uint i;
+
+ /* put the trees to draw in a list */
+ i = GetTreeCount(ti->tile) + 1;
+ do {
+ uint32 image = s[0] + (--i == 0 ? GetTreeGrowth(ti->tile) : 3);
+ if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
+ te[i].image = image;
+ te[i].x = d->x;
+ te[i].y = d->y;
+ s++;
+ d++;
+ } while (i);
+
+ /* draw them in a sorted way */
+ for (;;) {
+ byte min = 0xFF;
+ TreeListEnt *tep = NULL;
+
+ i = GetTreeCount(ti->tile) + 1;
+ do {
+ if (te[--i].image != 0 && te[i].x + te[i].y < min) {
+ min = te[i].x + te[i].y;
+ tep = &te[i];
+ }
+ } while (i);
+
+ if (tep == NULL) break;
+
+ AddSortableSpriteToDraw(tep->image, ti->x + tep->x, ti->y + tep->y, 5, 5, 0x10, z);
+ tep->image = 0;
+ }
+ }
+
+ EndSpriteCombine();
+}
+
+
+static uint GetSlopeZ_Trees(TileIndex tile, uint x, uint y)
+{
+ uint z;
+ uint tileh = GetTileSlope(tile, &z);
+
+ return z + GetPartialZ(x & 0xF, y & 0xF, tileh);
+}
+
+static Slope GetSlopeTileh_Trees(TileIndex tile, Slope tileh)
+{
+ return tileh;
+}
+
+static int32 ClearTile_Trees(TileIndex tile, byte flags)
+{
+ uint num;
+
+ if ((flags & DC_EXEC) && IsValidPlayer(_current_player)) {
+ Town *t = ClosestTownFromTile(tile, _patches.dist_local_authority);
+ if (t != NULL)
+ ChangeTownRating(t, RATING_TREE_DOWN_STEP, RATING_TREE_MINIMUM);
+ }
+
+ num = GetTreeCount(tile) + 1;
+ if (IS_INT_INSIDE(GetTreeType(tile), TREE_RAINFOREST, TREE_CACTUS)) num *= 4;
+
+ if (flags & DC_EXEC) DoClearSquare(tile);
+
+ return num * _price.remove_trees;
+}
+
+static void GetAcceptedCargo_Trees(TileIndex tile, AcceptedCargo ac)
+{
+ /* not used */
+}
+
+static void GetTileDesc_Trees(TileIndex tile, TileDesc *td)
+{
+ TreeType tt = GetTreeType(tile);
+
+ if (IS_INT_INSIDE(tt, TREE_RAINFOREST, TREE_CACTUS)) {
+ td->str = STR_280F_RAINFOREST;
+ } else if (tt == TREE_CACTUS) {
+ td->str = STR_2810_CACTUS_PLANTS;
+ } else {
+ td->str = STR_280E_TREES;
+ }
+
+ td->owner = GetTileOwner(tile);
+}
+
+static void AnimateTile_Trees(TileIndex tile)
+{
+ /* not used */
+}
+
+static void TileLoopTreesDesert(TileIndex tile)
+{
+ switch (GetTropicZone(tile)) {
+ case TROPICZONE_DESERT:
+ if (GetTreeGround(tile) != TREE_GROUND_SNOW_DESERT) {
+ SetTreeGroundDensity(tile, TREE_GROUND_SNOW_DESERT, 3);
+ MarkTileDirtyByTile(tile);
+ }
+ break;
+
+ case TROPICZONE_RAINFOREST: {
+ static const SoundFx forest_sounds[] = {
+ SND_42_LOON_BIRD,
+ SND_43_LION,
+ SND_44_MONKEYS,
+ SND_48_DISTANT_BIRD
+ };
+ uint32 r = Random();
+
+ if (CHANCE16I(1, 200, r)) SndPlayTileFx(forest_sounds[GB(r, 16, 2)], tile);
+ break;
+ }
+
+ default: break;
+ }
+}
+
+static void TileLoopTreesAlps(TileIndex tile)
+{
+ int k = GetTileZ(tile) - _opt.snow_line + TILE_HEIGHT;
+
+ if (k < 0) {
+ if (GetTreeGround(tile) != TREE_GROUND_SNOW_DESERT) return;
+ SetTreeGroundDensity(tile, TREE_GROUND_GRASS, 0);
+ } else {
+ uint density = min((uint)k / TILE_HEIGHT, 3);
+
+ if (GetTreeGround(tile) != TREE_GROUND_SNOW_DESERT ||
+ GetTreeDensity(tile) != density) {
+ SetTreeGroundDensity(tile, TREE_GROUND_SNOW_DESERT, density);
+ } else {
+ if (GetTreeDensity(tile) == 3) {
+ uint32 r = Random();
+ if (CHANCE16I(1, 200, r)) {
+ SndPlayTileFx((r & 0x80000000) ? SND_39_HEAVY_WIND : SND_34_WIND, tile);
+ }
+ }
+ return;
+ }
+ }
+ MarkTileDirtyByTile(tile);
+}
+
+static void TileLoop_Trees(TileIndex tile)
+{
+ switch (_opt.landscape) {
+ case LT_DESERT: TileLoopTreesDesert(tile); break;
+ case LT_HILLY: TileLoopTreesAlps(tile); break;
+ }
+
+ TileLoopClearHelper(tile);
+
+ if (GetTreeCounter(tile) < 15) {
+ AddTreeCounter(tile, 1);
+ return;
+ }
+ SetTreeCounter(tile, 0);
+
+ switch (GetTreeGrowth(tile)) {
+ case 3: /* regular sized tree */
+ if (_opt.landscape == LT_DESERT &&
+ GetTreeType(tile) != TREE_CACTUS &&
+ GetTropicZone(tile) == TROPICZONE_DESERT) {
+ AddTreeGrowth(tile, 1);
+ } else {
+ switch (GB(Random(), 0, 3)) {
+ case 0: /* start destructing */
+ AddTreeGrowth(tile, 1);
+ break;
+
+ case 1: /* add a tree */
+ if (GetTreeCount(tile) < 3) {
+ AddTreeCount(tile, 1);
+ SetTreeGrowth(tile, 0);
+ break;
+ }
+ /* FALL THROUGH */
+
+ case 2: { /* add a neighbouring tree */
+ TreeType treetype = GetTreeType(tile);
+
+ tile += TileOffsByDir(Random() & 7);
+
+ if (!IsTileType(tile, MP_CLEAR) || IsBridgeAbove(tile)) return;
+
+ switch (GetClearGround(tile)) {
+ case CLEAR_GRASS:
+ if (GetClearDensity(tile) != 3) return;
+ MakeTree(tile, treetype, 0, 0, TREE_GROUND_GRASS, 0);
+ break;
+
+ case CLEAR_ROUGH: MakeTree(tile, treetype, 0, 0, TREE_GROUND_ROUGH, 0); break;
+ case CLEAR_SNOW: MakeTree(tile, treetype, 0, 0, TREE_GROUND_SNOW_DESERT, GetClearDensity(tile)); break;
+ default: return;
+ }
+ break;
+ }
+
+ default:
+ return;
+ }
+ }
+ break;
+
+ case 6: /* final stage of tree destruction */
+ if (GetTreeCount(tile) > 0) {
+ /* more than one tree, delete it */
+ AddTreeCount(tile, -1);
+ SetTreeGrowth(tile, 3);
+ } else {
+ /* just one tree, change type into MP_CLEAR */
+ switch (GetTreeGround(tile)) {
+ case TREE_GROUND_GRASS: MakeClear(tile, CLEAR_GRASS, 3); break;
+ case TREE_GROUND_ROUGH: MakeClear(tile, CLEAR_ROUGH, 3); break;
+ default: MakeClear(tile, CLEAR_SNOW, GetTreeDensity(tile)); break;
+ }
+ ClearBridgeMiddle(tile);
+ }
+ break;
+
+ default:
+ AddTreeGrowth(tile, 1);
+ break;
+ }
+
+ MarkTileDirtyByTile(tile);
+}
+
+void OnTick_Trees(void)
+{
+ uint32 r;
+ TileIndex tile;
+ ClearGround ct;
+ TreeType tree;
+
+ /* place a tree at a random rainforest spot */
+ if (_opt.landscape == LT_DESERT &&
+ (r = Random(), tile = RandomTileSeed(r), GetTropicZone(tile) == TROPICZONE_RAINFOREST) &&
+ IsTileType(tile, MP_CLEAR) &&
+ !IsBridgeAbove(tile) &&
+ (ct = GetClearGround(tile), ct == CLEAR_GRASS || ct == CLEAR_ROUGH) &&
+ (tree = GetRandomTreeType(tile, GB(r, 24, 8))) != TREE_INVALID) {
+ MakeTree(tile, tree, 0, 0, ct == CLEAR_ROUGH ? TREE_GROUND_ROUGH : TREE_GROUND_GRASS, 0);
+ }
+
+ // byte underflow
+ if (--_trees_tick_ctr != 0) return;
+
+ /* place a tree at a random spot */
+ r = Random();
+ tile = TILE_MASK(r);
+ if (IsTileType(tile, MP_CLEAR) &&
+ !IsBridgeAbove(tile) &&
+ (ct = GetClearGround(tile), ct == CLEAR_GRASS || ct == CLEAR_ROUGH || ct == CLEAR_SNOW) &&
+ (tree = GetRandomTreeType(tile, GB(r, 24, 8))) != TREE_INVALID) {
+ switch (ct) {
+ case CLEAR_GRASS: MakeTree(tile, tree, 0, 0, TREE_GROUND_GRASS, 0); break;
+ case CLEAR_ROUGH: MakeTree(tile, tree, 0, 0, TREE_GROUND_ROUGH, 0); break;
+ default: MakeTree(tile, tree, 0, 0, TREE_GROUND_SNOW_DESERT, GetClearDensity(tile)); break;
+ }
+ }
+}
+
+static void ClickTile_Trees(TileIndex tile)
+{
+ /* not used */
+}
+
+static uint32 GetTileTrackStatus_Trees(TileIndex tile, TransportType mode)
+{
+ return 0;
+}
+
+static void ChangeTileOwner_Trees(TileIndex tile, PlayerID old_player, PlayerID new_player)
+{
+ /* not used */
+}
+
+void InitializeTrees(void)
+{
+ _trees_tick_ctr = 0;
+}
+
+
+const TileTypeProcs _tile_type_trees_procs = {
+ DrawTile_Trees, /* draw_tile_proc */
+ GetSlopeZ_Trees, /* get_slope_z_proc */
+ ClearTile_Trees, /* clear_tile_proc */
+ GetAcceptedCargo_Trees, /* get_accepted_cargo_proc */
+ GetTileDesc_Trees, /* get_tile_desc_proc */
+ GetTileTrackStatus_Trees, /* get_tile_track_status_proc */
+ ClickTile_Trees, /* click_tile_proc */
+ AnimateTile_Trees, /* animate_tile_proc */
+ TileLoop_Trees, /* tile_loop_clear */
+ ChangeTileOwner_Trees, /* change_tile_owner_clear */
+ NULL, /* get_produced_cargo_proc */
+ NULL, /* vehicle_enter_tile_proc */
+ GetSlopeTileh_Trees, /* get_slope_tileh_proc */
+};
diff --git a/src/tree_map.h b/src/tree_map.h
new file mode 100644
index 000000000..326504659
--- /dev/null
+++ b/src/tree_map.h
@@ -0,0 +1,131 @@
+/* $Id$ */
+
+#ifndef TREE_MAP_H
+#define TREE_MAP_H
+
+#include "macros.h"
+
+typedef enum TreeType {
+ TREE_INVALID = -1,
+ TREE_TEMPERATE = 0,
+ TREE_SUB_ARCTIC = 12,
+ TREE_RAINFOREST = 20,
+ TREE_CACTUS = 27,
+ TREE_SUB_TROPICAL = 28,
+ TREE_TOYLAND = 32
+} TreeType;
+
+enum {
+ TREE_COUNT_TEMPERATE = TREE_SUB_ARCTIC - TREE_TEMPERATE,
+ TREE_COUNT_SUB_ARCTIC = TREE_RAINFOREST - TREE_SUB_ARCTIC,
+ TREE_COUNT_RAINFOREST = TREE_CACTUS - TREE_RAINFOREST,
+ TREE_COUNT_SUB_TROPICAL = TREE_SUB_TROPICAL - TREE_CACTUS,
+ TREE_COUNT_TOYLAND = 9
+};
+
+/* ground type, m2 bits 4...5
+ * valid densities (bits 6...7) in comments after the enum */
+typedef enum TreeGround {
+ TREE_GROUND_GRASS = 0, // 0
+ TREE_GROUND_ROUGH = 1, // 0
+ TREE_GROUND_SNOW_DESERT = 2 // 0-3 for snow, 3 for desert
+} TreeGround;
+
+
+static inline TreeType GetTreeType(TileIndex t)
+{
+ assert(IsTileType(t, MP_TREES));
+ return _m[t].m3;
+}
+
+
+static inline TreeGround GetTreeGround(TileIndex t)
+{
+ assert(IsTileType(t, MP_TREES));
+ return GB(_m[t].m2, 4, 2);
+}
+
+
+static inline uint GetTreeDensity(TileIndex t)
+{
+ assert(IsTileType(t, MP_TREES));
+ return GB(_m[t].m2, 6, 2);
+}
+
+
+static inline void SetTreeGroundDensity(TileIndex t, TreeGround g, uint d)
+{
+ assert(IsTileType(t, MP_TREES)); // XXX incomplete
+ SB(_m[t].m2, 4, 2, g);
+ SB(_m[t].m2, 6, 2, d);
+}
+
+
+static inline uint GetTreeCount(TileIndex t)
+{
+ assert(IsTileType(t, MP_TREES));
+ return GB(_m[t].m5, 6, 2);
+}
+
+static inline void AddTreeCount(TileIndex t, int c)
+{
+ assert(IsTileType(t, MP_TREES)); // XXX incomplete
+ _m[t].m5 += c << 6;
+}
+
+static inline void SetTreeCount(TileIndex t, uint c)
+{
+ assert(IsTileType(t, MP_TREES)); // XXX incomplete
+ SB(_m[t].m5, 6, 2, c);
+}
+
+
+static inline uint GetTreeGrowth(TileIndex t)
+{
+ assert(IsTileType(t, MP_TREES));
+ return GB(_m[t].m5, 0, 3);
+}
+
+static inline void AddTreeGrowth(TileIndex t, int a)
+{
+ assert(IsTileType(t, MP_TREES)); // XXX incomplete
+ _m[t].m5 += a;
+}
+
+static inline void SetTreeGrowth(TileIndex t, uint g)
+{
+ assert(IsTileType(t, MP_TREES)); // XXX incomplete
+ SB(_m[t].m5, 0, 3, g);
+}
+
+
+static inline uint GetTreeCounter(TileIndex t)
+{
+ assert(IsTileType(t, MP_TREES));
+ return GB(_m[t].m2, 0, 4);
+}
+
+static inline void AddTreeCounter(TileIndex t, int a)
+{
+ assert(IsTileType(t, MP_TREES)); // XXX incomplete
+ _m[t].m2 += a;
+}
+
+static inline void SetTreeCounter(TileIndex t, uint c)
+{
+ assert(IsTileType(t, MP_TREES)); // XXX incomplete
+ SB(_m[t].m2, 0, 4, c);
+}
+
+
+static inline void MakeTree(TileIndex t, TreeType type, uint count, uint growth, TreeGround ground, uint density)
+{
+ SetTileType(t, MP_TREES);
+ SetTileOwner(t, OWNER_NONE);
+ _m[t].m2 = density << 6 | ground << 4 | 0;
+ _m[t].m3 = type;
+ _m[t].m4 = 0 << 5 | 0 << 2;
+ _m[t].m5 = count << 6 | growth;
+}
+
+#endif /* TREE_MAP_H */
diff --git a/src/tunnel_map.c b/src/tunnel_map.c
new file mode 100644
index 000000000..a4945591d
--- /dev/null
+++ b/src/tunnel_map.c
@@ -0,0 +1,50 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "tile.h"
+#include "tunnel_map.h"
+
+TileIndex GetOtherTunnelEnd(TileIndex tile)
+{
+ DiagDirection dir = GetTunnelDirection(tile);
+ TileIndexDiff delta = TileOffsByDiagDir(dir);
+ uint z = GetTileZ(tile);
+
+ dir = ReverseDiagDir(dir);
+ do {
+ tile += delta;
+ } while (
+ !IsTunnelTile(tile) ||
+ GetTunnelDirection(tile) != dir ||
+ GetTileZ(tile) != z
+ );
+
+ return tile;
+}
+
+
+static bool IsTunnelInWayDir(TileIndex tile, uint z, DiagDirection dir)
+{
+ TileIndexDiff delta = TileOffsByDiagDir(dir);
+ uint height;
+
+ do {
+ tile -= delta;
+ height = GetTileZ(tile);
+ } while (z < height);
+
+ return
+ z == height &&
+ IsTunnelTile(tile) &&
+ GetTunnelDirection(tile) == dir;
+}
+
+bool IsTunnelInWay(TileIndex tile, uint z)
+{
+ return
+ IsTunnelInWayDir(tile, z, DIAGDIR_NE) ||
+ IsTunnelInWayDir(tile, z, DIAGDIR_SE) ||
+ IsTunnelInWayDir(tile, z, DIAGDIR_SW) ||
+ IsTunnelInWayDir(tile, z, DIAGDIR_NW);
+}
diff --git a/src/tunnel_map.h b/src/tunnel_map.h
new file mode 100644
index 000000000..c9a3a36a3
--- /dev/null
+++ b/src/tunnel_map.h
@@ -0,0 +1,75 @@
+/* $Id$ */
+
+#ifndef TUNNEL_MAP_H
+#define TUNNEL_MAP_H
+
+#include "direction.h"
+#include "macros.h"
+#include "map.h"
+#include "rail.h"
+
+
+static inline bool IsTunnel(TileIndex t)
+{
+ assert(IsTileType(t, MP_TUNNELBRIDGE));
+ return !HASBIT(_m[t].m5, 7);
+}
+
+
+static inline bool IsTunnelTile(TileIndex t)
+{
+ return IsTileType(t, MP_TUNNELBRIDGE) && IsTunnel(t);
+}
+
+
+static inline DiagDirection GetTunnelDirection(TileIndex t)
+{
+ assert(IsTunnelTile(t));
+ return (DiagDirection)GB(_m[t].m5, 0, 2);
+}
+
+
+static inline TransportType GetTunnelTransportType(TileIndex t)
+{
+ assert(IsTunnelTile(t));
+ return (TransportType)GB(_m[t].m5, 2, 2);
+}
+
+static inline bool HasTunnelSnowOrDesert(TileIndex t)
+{
+ assert(IsTunnelTile(t));
+ return HASBIT(_m[t].m4, 7);
+}
+
+static inline void SetTunnelSnowOrDesert(TileIndex t, bool snow_or_desert)
+{
+ assert(IsTunnelTile(t));
+ SB(_m[t].m4, 7, 1, snow_or_desert);
+}
+
+
+TileIndex GetOtherTunnelEnd(TileIndex);
+bool IsTunnelInWay(TileIndex, uint z);
+
+
+static inline void MakeRoadTunnel(TileIndex t, Owner o, DiagDirection d)
+{
+ SetTileType(t, MP_TUNNELBRIDGE);
+ SetTileOwner(t, o);
+ _m[t].m2 = 0;
+ _m[t].m3 = 0;
+ _m[t].m4 = 0;
+ _m[t].m5 = TRANSPORT_ROAD << 2 | d;
+}
+
+static inline void MakeRailTunnel(TileIndex t, Owner o, DiagDirection d, RailType r)
+{
+ SetTileType(t, MP_TUNNELBRIDGE);
+ SetTileOwner(t, o);
+ _m[t].m2 = 0;
+ _m[t].m3 = r;
+ _m[t].m4 = 0;
+ _m[t].m5 = TRANSPORT_RAIL << 2 | d;
+}
+
+#endif /* TUNNEL_MAP_H */
diff --git a/src/tunnelbridge_cmd.c b/src/tunnelbridge_cmd.c
new file mode 100644
index 000000000..7e38814c4
--- /dev/null
+++ b/src/tunnelbridge_cmd.c
@@ -0,0 +1,1313 @@
+/* $Id$ */
+
+/** @file tunnelbridge_cmd.c
+ * This file deals with tunnels and bridges (non-gui stuff)
+ * @todo seperate this file into two
+ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "bridge_map.h"
+#include "rail_map.h"
+#include "road_map.h"
+#include "table/sprites.h"
+#include "table/strings.h"
+#include "functions.h"
+#include "map.h"
+#include "tile.h"
+#include "tunnel_map.h"
+#include "unmovable_map.h"
+#include "vehicle.h"
+#include "viewport.h"
+#include "command.h"
+#include "player.h"
+#include "town.h"
+#include "sound.h"
+#include "variables.h"
+#include "bridge.h"
+#include "train.h"
+#include "water_map.h"
+#include "yapf/yapf.h"
+#include "date.h"
+#include "newgrf_sound.h"
+
+#include "table/bridge_land.h"
+
+const Bridge orig_bridge[] = {
+/*
+ year of availablity
+ | minimum length
+ | | maximum length
+ | | | price
+ | | | | maximum speed
+ | | | | | sprite to use in GUI string with description
+ | | | | | | | */
+ { 0, 0, 16, 80, 32, 0xA24 , STR_5012_WOODEN , NULL, 0 },
+ { 0, 0, 2, 112, 48, 0xA26 | PALETTE_TO_STRUCT_RED , STR_5013_CONCRETE , NULL, 0 },
+ { 1930, 0, 5, 144, 64, 0xA25 , STR_500F_GIRDER_STEEL , NULL, 0 },
+ { 0, 2, 10, 168, 80, 0xA22 | PALETTE_TO_STRUCT_CONCRETE, STR_5011_SUSPENSION_CONCRETE, NULL, 0 },
+ { 1930, 3, 16, 185, 96, 0xA22 , STR_500E_SUSPENSION_STEEL , NULL, 0 },
+ { 1930, 3, 16, 192, 112, 0xA22 | PALETTE_TO_STRUCT_YELLOW , STR_500E_SUSPENSION_STEEL , NULL, 0 },
+ { 1930, 3, 7, 224, 160, 0xA23 , STR_5010_CANTILEVER_STEEL , NULL, 0 },
+ { 1930, 3, 8, 232, 208, 0xA23 | PALETTE_TO_STRUCT_BROWN , STR_5010_CANTILEVER_STEEL , NULL, 0 },
+ { 1930, 3, 9, 248, 240, 0xA23 | PALETTE_TO_STRUCT_RED , STR_5010_CANTILEVER_STEEL , NULL, 0 },
+ { 1930, 0, 2, 240, 256, 0xA27 , STR_500F_GIRDER_STEEL , NULL, 0 },
+ { 1995, 2, 16, 255, 320, 0xA28 , STR_5014_TUBULAR_STEEL , NULL, 0 },
+ { 2005, 2, 32, 380, 512, 0xA28 | PALETTE_TO_STRUCT_YELLOW , STR_5014_TUBULAR_STEEL , NULL, 0 },
+ { 2010, 2, 32, 510, 608, 0xA28 | PALETTE_TO_STRUCT_GREY , STR_BRIDGE_TUBULAR_SILICON , NULL, 0 }
+};
+
+Bridge _bridge[MAX_BRIDGES];
+
+
+// calculate the price factor for building a long bridge.
+// basically the cost delta is 1,1, 1, 2,2, 3,3,3, 4,4,4,4, 5,5,5,5,5, 6,6,6,6,6,6, 7,7,7,7,7,7,7, 8,8,8,8,8,8,8,8,
+int CalcBridgeLenCostFactor(int x)
+{
+ int n;
+ int r;
+
+ if (x < 2) return x;
+ x -= 2;
+ for (n = 0, r = 2;; n++) {
+ if (x <= n) return r + x * n;
+ r += n * n;
+ x -= n;
+ }
+}
+
+#define M(x) (1 << (x))
+enum {
+ // foundation, whole tile is leveled up --> 3 corners raised
+ BRIDGE_FULL_LEVELED_FOUNDATION = M(SLOPE_WSE) | M(SLOPE_NWS) | M(SLOPE_ENW) | M(SLOPE_SEN),
+ // foundation, tile is partly leveled up --> 1 corner raised
+ BRIDGE_PARTLY_LEVELED_FOUNDATION = M(SLOPE_W) | M(SLOPE_S) | M(SLOPE_E) | M(SLOPE_N),
+ // no foundations (X,Y direction)
+ BRIDGE_NO_FOUNDATION = M(SLOPE_FLAT) | M(SLOPE_SW) | M(SLOPE_SE) | M(SLOPE_NW) | M(SLOPE_NE),
+ BRIDGE_HORZ_RAMP = (BRIDGE_PARTLY_LEVELED_FOUNDATION | BRIDGE_NO_FOUNDATION) & ~M(SLOPE_FLAT)
+};
+#undef M
+
+static inline const PalSpriteID *GetBridgeSpriteTable(int index, byte table)
+{
+ const Bridge *bridge = &_bridge[index];
+ assert(table < 7);
+ if (bridge->sprite_table == NULL || bridge->sprite_table[table] == NULL) {
+ return _bridge_sprite_table[index][table];
+ } else {
+ return bridge->sprite_table[table];
+ }
+}
+
+static inline byte GetBridgeFlags(int index) { return _bridge[index].flags;}
+
+
+/** Check the slope at the bridge ramps in three easy steps:
+ * - valid slopes without foundation
+ * - valid slopes with foundation
+ * - rest is invalid
+ */
+#define M(x) (1 << (x))
+static int32 CheckBridgeSlopeNorth(Axis axis, Slope tileh)
+{
+ uint32 valid;
+
+ valid = M(SLOPE_FLAT) | (axis == AXIS_X ? M(SLOPE_NE) : M(SLOPE_NW));
+ if (HASBIT(valid, tileh)) return 0;
+
+ valid =
+ BRIDGE_FULL_LEVELED_FOUNDATION | M(SLOPE_N) | M(SLOPE_STEEP_N) |
+ (axis == AXIS_X ? M(SLOPE_E) | M(SLOPE_STEEP_E) : M(SLOPE_W) | M(SLOPE_STEEP_W));
+ if (HASBIT(valid, tileh)) return _price.terraform;
+
+ return CMD_ERROR;
+}
+
+static int32 CheckBridgeSlopeSouth(Axis axis, Slope tileh)
+{
+ uint32 valid;
+
+ valid = M(SLOPE_FLAT) | (axis == AXIS_X ? M(SLOPE_SW) : M(SLOPE_SE));
+ if (HASBIT(valid, tileh)) return 0;
+
+ valid =
+ BRIDGE_FULL_LEVELED_FOUNDATION | M(SLOPE_S) | M(SLOPE_STEEP_S) |
+ (axis == AXIS_X ? M(SLOPE_W) | M(SLOPE_STEEP_W) : M(SLOPE_E) | M(SLOPE_STEEP_E));
+ if (HASBIT(valid, tileh)) return _price.terraform;
+
+ return CMD_ERROR;
+}
+#undef M
+
+
+uint32 GetBridgeLength(TileIndex begin, TileIndex end)
+{
+ int x1 = TileX(begin);
+ int y1 = TileY(begin);
+ int x2 = TileX(end);
+ int y2 = TileY(end);
+
+ return abs(x2 + y2 - x1 - y1) - 1;
+}
+
+bool CheckBridge_Stuff(byte bridge_type, uint bridge_len)
+{
+ const Bridge *b = &_bridge[bridge_type];
+ uint max; // max possible length of a bridge (with patch 100)
+
+ if (bridge_type >= MAX_BRIDGES) return false;
+ if (b->avail_year > _cur_year) return false;
+
+ max = b->max_length;
+ if (max >= 16 && _patches.longbridges) max = 100;
+
+ return b->min_length <= bridge_len && bridge_len <= max;
+}
+
+/** Build a Bridge
+ * @param end_tile end tile
+ * @param p1 packed start tile coords (~ dx)
+ * @param p2 various bitstuffed elements
+ * - p2 = (bit 0- 7) - bridge type (hi bh)
+ * - p2 = (bit 8-..) - rail type. bit15 ((x>>8)&0x80) means road bridge.
+ */
+int32 CmdBuildBridge(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ int bridge_type;
+ TransportType transport;
+ RailType railtype;
+ uint x;
+ uint y;
+ uint sx;
+ uint sy;
+ TileIndex tile_start;
+ TileIndex tile_end;
+ Slope tileh_start;
+ Slope tileh_end;
+ uint z_start;
+ uint z_end;
+ TileIndex tile;
+ TileIndexDiff delta;
+ uint bridge_len;
+ Axis direction;
+ int32 cost, terraformcost, ret;
+ bool allow_on_slopes;
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ /* unpack parameters */
+ bridge_type = GB(p2, 0, 8);
+
+ if (p1 >= MapSize()) return CMD_ERROR;
+
+ // type of bridge
+ if (HASBIT(p2, 15)) {
+ railtype = 0;
+ transport = TRANSPORT_ROAD;
+ } else {
+ if (!ValParamRailtype(GB(p2, 8, 8))) return CMD_ERROR;
+ railtype = GB(p2, 8, 8);
+ transport = TRANSPORT_RAIL;
+ }
+
+ x = TileX(end_tile);
+ y = TileY(end_tile);
+ sx = TileX(p1);
+ sy = TileY(p1);
+
+ /* check if valid, and make sure that (x,y) are smaller than (sx,sy) */
+ if (x == sx) {
+ if (y == sy) return_cmd_error(STR_5008_CANNOT_START_AND_END_ON);
+ direction = AXIS_Y;
+ if (y > sy) uintswap(y,sy);
+ } else if (y == sy) {
+ direction = AXIS_X;
+ if (x > sx) uintswap(x,sx);
+ } else {
+ return_cmd_error(STR_500A_START_AND_END_MUST_BE_IN);
+ }
+
+ /* set and test bridge length, availability */
+ bridge_len = sx + sy - x - y - 1;
+ if (!CheckBridge_Stuff(bridge_type, bridge_len)) return_cmd_error(STR_5015_CAN_T_BUILD_BRIDGE_HERE);
+
+ /* retrieve landscape height and ensure it's on land */
+ tile_start = TileXY(x, y);
+ tile_end = TileXY(sx, sy);
+ if (IsClearWaterTile(tile_start) || IsClearWaterTile(tile_end)) {
+ return_cmd_error(STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH);
+ }
+
+ tileh_start = GetTileSlope(tile_start, &z_start);
+ tileh_end = GetTileSlope(tile_end, &z_end);
+
+ if (IsSteepSlope(tileh_start)) z_start += TILE_HEIGHT;
+ if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh_start)) {
+ z_start += TILE_HEIGHT;
+ tileh_start = SLOPE_FLAT;
+ }
+
+ if (IsSteepSlope(tileh_end)) z_end += TILE_HEIGHT;
+ if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh_end)) {
+ z_end += TILE_HEIGHT;
+ tileh_end = SLOPE_FLAT;
+ }
+
+ if (z_start != z_end) return_cmd_error(STR_5009_LEVEL_LAND_OR_WATER_REQUIRED);
+
+ // Towns are not allowed to use bridges on slopes.
+ allow_on_slopes = (!_is_old_ai_player
+ && _current_player != OWNER_TOWN && _patches.build_on_slopes);
+
+ /* Try and clear the start landscape */
+
+ ret = DoCommand(tile_start, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+ if (CmdFailed(ret)) return ret;
+ cost = ret;
+
+ terraformcost = CheckBridgeSlopeNorth(direction, tileh_start);
+ if (CmdFailed(terraformcost) || (terraformcost != 0 && !allow_on_slopes))
+ return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
+ cost += terraformcost;
+
+ /* Try and clear the end landscape */
+
+ ret = DoCommand(tile_end, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+ if (CmdFailed(ret)) return ret;
+ cost += ret;
+
+ // false - end tile slope check
+ terraformcost = CheckBridgeSlopeSouth(direction, tileh_end);
+ if (CmdFailed(terraformcost) || (terraformcost != 0 && !allow_on_slopes))
+ return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
+ cost += terraformcost;
+
+ {
+ TileIndex Heads[] = {tile_start, tile_end};
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ if (MayHaveBridgeAbove(Heads[i])) {
+ if (IsBridgeAbove(Heads[i])) {
+ TileIndex north_head = GetNorthernBridgeEnd(Heads[i]);
+
+ if (direction == GetBridgeAxis(Heads[i])) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
+
+ if (z_start + TILE_HEIGHT == GetBridgeHeight(north_head)) {
+ return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
+ }
+ }
+ }
+ }
+ }
+
+ /* do the drill? */
+ if (flags & DC_EXEC) {
+ DiagDirection dir = AxisToDiagDir(direction);
+
+ if (transport == TRANSPORT_RAIL) {
+ MakeRailBridgeRamp(tile_start, _current_player, bridge_type, dir, railtype);
+ MakeRailBridgeRamp(tile_end, _current_player, bridge_type, ReverseDiagDir(dir), railtype);
+ } else {
+ MakeRoadBridgeRamp(tile_start, _current_player, bridge_type, dir);
+ MakeRoadBridgeRamp(tile_end, _current_player, bridge_type, ReverseDiagDir(dir));
+ }
+ MarkTileDirtyByTile(tile_start);
+ MarkTileDirtyByTile(tile_end);
+ }
+
+ delta = (direction == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
+ for (tile = tile_start + delta; tile != tile_end; tile += delta) {
+ uint z;
+
+ if (GetTileSlope(tile, &z) != SLOPE_FLAT && z >= z_start) return_cmd_error(STR_5009_LEVEL_LAND_OR_WATER_REQUIRED);
+
+ if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) {
+ /* Disallow crossing bridges for the time being */
+ return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
+ }
+
+ switch (GetTileType(tile)) {
+ case MP_WATER:
+ if (!EnsureNoVehicle(tile)) return_cmd_error(STR_980E_SHIP_IN_THE_WAY);
+ if (!IsWater(tile) && !IsCoast(tile)) goto not_valid_below;
+ break;
+
+ case MP_RAILWAY:
+ if (!IsPlainRailTile(tile)) goto not_valid_below;
+ break;
+
+ case MP_STREET:
+ if (GetRoadTileType(tile) == ROAD_TILE_DEPOT) goto not_valid_below;
+ break;
+
+ case MP_TUNNELBRIDGE:
+ if (IsTunnel(tile)) break;
+ if (direction == DiagDirToAxis(GetBridgeRampDirection(tile))) goto not_valid_below;
+ if (z_start < GetBridgeHeight(tile)) goto not_valid_below;
+ break;
+
+ case MP_UNMOVABLE:
+ if (!IsOwnedLand(tile)) goto not_valid_below;
+ break;
+
+ case MP_CLEAR:
+ if (IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
+ break;
+
+ default:
+not_valid_below:;
+ /* try and clear the middle landscape */
+ ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+ if (CmdFailed(ret)) return ret;
+ cost += ret;
+ break;
+ }
+
+ if (flags & DC_EXEC) {
+ SetBridgeMiddle(tile, direction);
+ MarkTileDirtyByTile(tile);
+ }
+ }
+
+ SetSignalsOnBothDir(tile_start, AxisToTrack(direction));
+ YapfNotifyTrackLayoutChange(tile_start, AxisToTrack(direction));
+
+ /* for human player that builds the bridge he gets a selection to choose from bridges (DC_QUERY_COST)
+ * It's unnecessary to execute this command every time for every bridge. So it is done only
+ * and cost is computed in "bridge_gui.c". For AI, Towns this has to be of course calculated
+ */
+ if (!(flags & DC_QUERY_COST)) {
+ const Bridge *b = &_bridge[bridge_type];
+
+ bridge_len += 2; // begin and end tiles/ramps
+
+ if (IsValidPlayer(_current_player) && !_is_old_ai_player)
+ bridge_len = CalcBridgeLenCostFactor(bridge_len);
+
+ cost += (int64)bridge_len * _price.build_bridge * b->price >> 8;
+ }
+
+ return cost;
+}
+
+
+/** Build Tunnel.
+ * @param tile start tile of tunnel
+ * @param p1 railtype, 0x200 for road tunnel
+ * @param p2 unused
+ */
+int32 CmdBuildTunnel(TileIndex start_tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ TileIndexDiff delta;
+ TileIndex end_tile;
+ DiagDirection direction;
+ Slope start_tileh;
+ Slope end_tileh;
+ uint start_z;
+ uint end_z;
+ int32 cost;
+ int32 ret;
+
+ _build_tunnel_endtile = 0;
+
+ if (p1 != 0x200 && !ValParamRailtype(p1)) return CMD_ERROR;
+
+ start_tileh = GetTileSlope(start_tile, &start_z);
+
+ switch (start_tileh) {
+ case SLOPE_SW: direction = DIAGDIR_SW; break;
+ case SLOPE_SE: direction = DIAGDIR_SE; break;
+ case SLOPE_NW: direction = DIAGDIR_NW; break;
+ case SLOPE_NE: direction = DIAGDIR_NE; break;
+ default: return_cmd_error(STR_500B_SITE_UNSUITABLE_FOR_TUNNEL);
+ }
+
+ ret = DoCommand(start_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+ if (CmdFailed(ret)) return ret;
+
+ /* XXX - do NOT change 'ret' in the loop, as it is used as the price
+ * for the clearing of the entrance of the tunnel. Assigning it to
+ * cost before the loop will yield different costs depending on start-
+ * position, because of increased-cost-by-length: 'cost += cost >> 3' */
+ cost = 0;
+ delta = TileOffsByDiagDir(direction);
+ end_tile = start_tile;
+ for (;;) {
+ end_tile += delta;
+ end_tileh = GetTileSlope(end_tile, &end_z);
+
+ if (start_z == end_z) break;
+
+ if (!_cheats.crossing_tunnels.value && IsTunnelInWay(end_tile, start_z)) {
+ return_cmd_error(STR_5003_ANOTHER_TUNNEL_IN_THE_WAY);
+ }
+
+ cost += _price.build_tunnel;
+ cost += cost >> 3; // add a multiplier for longer tunnels
+ if (cost >= 400000000) cost = 400000000;
+ }
+
+ /* Add the cost of the entrance */
+ cost += _price.build_tunnel + ret;
+
+ // if the command fails from here on we want the end tile to be highlighted
+ _build_tunnel_endtile = end_tile;
+
+ // slope of end tile must be complementary to the slope of the start tile
+ if (end_tileh != ComplementSlope(start_tileh)) {
+ ret = DoCommand(end_tile, end_tileh & start_tileh, 0, flags, CMD_TERRAFORM_LAND);
+ if (CmdFailed(ret)) return_cmd_error(STR_5005_UNABLE_TO_EXCAVATE_LAND);
+ } else {
+ ret = DoCommand(end_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+ if (CmdFailed(ret)) return ret;
+ }
+ cost += _price.build_tunnel + ret;
+
+ if (flags & DC_EXEC) {
+ if (GB(p1, 9, 1) == TRANSPORT_RAIL) {
+ MakeRailTunnel(start_tile, _current_player, direction, GB(p1, 0, 4));
+ MakeRailTunnel(end_tile, _current_player, ReverseDiagDir(direction), GB(p1, 0, 4));
+ UpdateSignalsOnSegment(start_tile, direction);
+ YapfNotifyTrackLayoutChange(start_tile, AxisToTrack(DiagDirToAxis(direction)));
+ } else {
+ MakeRoadTunnel(start_tile, _current_player, direction);
+ MakeRoadTunnel(end_tile, _current_player, ReverseDiagDir(direction));
+ }
+ }
+
+ return cost;
+}
+
+TileIndex CheckTunnelBusy(TileIndex tile, uint *length)
+{
+ uint z = GetTileZ(tile);
+ DiagDirection dir = GetTunnelDirection(tile);
+ TileIndexDiff delta = TileOffsByDiagDir(dir);
+ uint len = 0;
+ TileIndex starttile = tile;
+ Vehicle *v;
+
+ do {
+ tile += delta;
+ len++;
+ } while (
+ !IsTunnelTile(tile) ||
+ ReverseDiagDir(GetTunnelDirection(tile)) != dir ||
+ GetTileZ(tile) != z
+ );
+
+ v = FindVehicleBetween(starttile, tile, z);
+ if (v != NULL) {
+ _error_message = v->type == VEH_Train ?
+ STR_5000_TRAIN_IN_TUNNEL : STR_5001_ROAD_VEHICLE_IN_TUNNEL;
+ return INVALID_TILE;
+ }
+
+ if (length != NULL) *length = len;
+ return tile;
+}
+
+static inline bool CheckAllowRemoveTunnelBridge(TileIndex tile)
+{
+ /* Floods can remove anything as well as the scenario editor */
+ if (_current_player == OWNER_WATER || _game_mode == GM_EDITOR) return true;
+ /* Obviously if the bridge/tunnel belongs to us, or no-one, we can remove it */
+ if (CheckTileOwnership(tile) || IsTileOwner(tile, OWNER_NONE)) return true;
+ /* Otherwise we can only remove town-owned stuff with extra patch-settings, or cheat */
+ if (IsTileOwner(tile, OWNER_TOWN) && (_patches.extra_dynamite || _cheats.magic_bulldozer.value)) return true;
+ return false;
+}
+
+static int32 DoClearTunnel(TileIndex tile, uint32 flags)
+{
+ Town *t = NULL;
+ TileIndex endtile;
+ uint length;
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ if (!CheckAllowRemoveTunnelBridge(tile)) return CMD_ERROR;
+
+ endtile = CheckTunnelBusy(tile, &length);
+ if (endtile == INVALID_TILE) return CMD_ERROR;
+
+ _build_tunnel_endtile = endtile;
+
+ if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR) {
+ t = ClosestTownFromTile(tile, (uint)-1); // town penalty rating
+
+ /* Check if you are allowed to remove the tunnel owned by a town
+ * Removal depends on difficulty settings */
+ if (!CheckforTownRating(flags, t, TUNNELBRIDGE_REMOVE)) {
+ SetDParam(0, t->index);
+ return_cmd_error(STR_2009_LOCAL_AUTHORITY_REFUSES);
+ }
+ }
+
+ if (flags & DC_EXEC) {
+ // We first need to request the direction before calling DoClearSquare
+ // else the direction is always 0.. dah!! ;)
+ DiagDirection dir = GetTunnelDirection(tile);
+ Track track;
+
+ // Adjust the town's player rating. Do this before removing the tile owner info.
+ if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR)
+ ChangeTownRating(t, RATING_TUNNEL_BRIDGE_DOWN_STEP, RATING_TUNNEL_BRIDGE_MINIMUM);
+
+ DoClearSquare(tile);
+ DoClearSquare(endtile);
+ UpdateSignalsOnSegment(tile, ReverseDiagDir(dir));
+ UpdateSignalsOnSegment(endtile, dir);
+ track = AxisToTrack(DiagDirToAxis(dir));
+ YapfNotifyTrackLayoutChange(tile, track);
+ YapfNotifyTrackLayoutChange(endtile, track);
+ }
+ return _price.clear_tunnel * (length + 1);
+}
+
+
+static bool IsVehicleOnBridge(TileIndex starttile, TileIndex endtile, uint z)
+{
+ const Vehicle *v;
+ FOR_ALL_VEHICLES(v) {
+ if ((v->tile == starttile || v->tile == endtile) && v->z_pos == z) {
+ _error_message = VehicleInTheWayErrMsg(v);
+ return true;
+ }
+ }
+ return false;
+}
+
+static int32 DoClearBridge(TileIndex tile, uint32 flags)
+{
+ DiagDirection direction;
+ TileIndexDiff delta;
+ TileIndex endtile;
+ Town *t = NULL;
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ if (!CheckAllowRemoveTunnelBridge(tile)) return CMD_ERROR;
+
+ endtile = GetOtherBridgeEnd(tile);
+
+ if (!EnsureNoVehicle(tile) ||
+ !EnsureNoVehicle(endtile) ||
+ IsVehicleOnBridge(tile, endtile, GetBridgeHeight(tile))) {
+ return CMD_ERROR;
+ }
+
+ direction = GetBridgeRampDirection(tile);
+ delta = TileOffsByDiagDir(direction);
+
+ if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR) {
+ t = ClosestTownFromTile(tile, (uint)-1); // town penalty rating
+
+ /* Check if you are allowed to remove the bridge owned by a town
+ * Removal depends on difficulty settings */
+ if (!CheckforTownRating(flags, t, TUNNELBRIDGE_REMOVE)) {
+ SetDParam(0, t->index);
+ return_cmd_error(STR_2009_LOCAL_AUTHORITY_REFUSES);
+ }
+ }
+
+ if (flags & DC_EXEC) {
+ TileIndex c;
+ Track track;
+
+ //checks if the owner is town then decrease town rating by RATING_TUNNEL_BRIDGE_DOWN_STEP until
+ // you have a "Poor" (0) town rating
+ if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR)
+ ChangeTownRating(t, RATING_TUNNEL_BRIDGE_DOWN_STEP, RATING_TUNNEL_BRIDGE_MINIMUM);
+
+ DoClearSquare(tile);
+ DoClearSquare(endtile);
+ for (c = tile + delta; c != endtile; c += delta) {
+ ClearBridgeMiddle(c);
+ MarkTileDirtyByTile(c);
+ }
+
+ UpdateSignalsOnSegment(tile, ReverseDiagDir(direction));
+ UpdateSignalsOnSegment(endtile, direction);
+ track = AxisToTrack(DiagDirToAxis(direction));
+ YapfNotifyTrackLayoutChange(tile, track);
+ YapfNotifyTrackLayoutChange(endtile, track);
+ }
+
+ return (DistanceManhattan(tile, endtile) + 1) * _price.clear_bridge;
+}
+
+static int32 ClearTile_TunnelBridge(TileIndex tile, byte flags)
+{
+ if (IsTunnel(tile)) {
+ if (flags & DC_AUTO) return_cmd_error(STR_5006_MUST_DEMOLISH_TUNNEL_FIRST);
+ return DoClearTunnel(tile, flags);
+ } else if (IsBridge(tile)) { // XXX Is this necessary?
+ if (flags & DC_AUTO) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
+ return DoClearBridge(tile, flags);
+ }
+
+ return CMD_ERROR;
+}
+
+int32 DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec)
+{
+ TileIndex endtile;
+
+ if (IsTunnel(tile) && GetTunnelTransportType(tile) == TRANSPORT_RAIL) {
+ uint length;
+
+ if (!CheckTileOwnership(tile)) return CMD_ERROR;
+
+ if (GetRailType(tile) == totype) return CMD_ERROR;
+
+ // 'hidden' elrails can't be downgraded to normal rail when elrails are disabled
+ if (_patches.disable_elrails && totype == RAILTYPE_RAIL && GetRailType(tile) == RAILTYPE_ELECTRIC) return CMD_ERROR;
+
+ endtile = CheckTunnelBusy(tile, &length);
+ if (endtile == INVALID_TILE) return CMD_ERROR;
+
+ if (exec) {
+ Track track;
+ SetRailType(tile, totype);
+ SetRailType(endtile, totype);
+ MarkTileDirtyByTile(tile);
+ MarkTileDirtyByTile(endtile);
+
+ track = AxisToTrack(DiagDirToAxis(GetTunnelDirection(tile)));
+ YapfNotifyTrackLayoutChange(tile, track);
+ YapfNotifyTrackLayoutChange(endtile, track);
+ }
+ return (length + 1) * (_price.build_rail >> 1);
+ } else if (IsBridge(tile) && GetBridgeTransportType(tile) == TRANSPORT_RAIL) {
+
+ if (!CheckTileOwnership(tile)) return CMD_ERROR;
+
+ endtile = GetOtherBridgeEnd(tile);
+
+ if (!EnsureNoVehicle(tile) ||
+ !EnsureNoVehicle(endtile) ||
+ IsVehicleOnBridge(tile, endtile, GetBridgeHeight(tile))) {
+ return CMD_ERROR;
+ }
+
+ if (GetRailType(tile) == totype) return CMD_ERROR;
+
+ if (exec) {
+ TileIndexDiff delta;
+ Track track;
+
+ SetRailType(tile, totype);
+ SetRailType(endtile, totype);
+ MarkTileDirtyByTile(tile);
+ MarkTileDirtyByTile(endtile);
+
+ track = AxisToTrack(DiagDirToAxis(GetBridgeRampDirection(tile)));
+ YapfNotifyTrackLayoutChange(tile, track);
+ YapfNotifyTrackLayoutChange(endtile, track);
+
+ delta = TileOffsByDiagDir(GetBridgeRampDirection(tile));
+ for (tile += delta; tile != endtile; tile += delta) {
+ MarkTileDirtyByTile(tile); // TODO encapsulate this into a function
+ }
+ }
+
+ return (DistanceManhattan(tile, endtile) + 1) * (_price.build_rail >> 1);
+ } else {
+ return CMD_ERROR;
+ }
+}
+
+
+static void DrawBridgePillars(PalSpriteID image, const TileInfo* ti, Axis axis, uint type, int x, int y, int z)
+{
+ if (image != 0) {
+ bool drawfarpillar = !HASBIT(GetBridgeFlags(type), 0);
+ int back_height, front_height;
+ int i = z;
+ const byte *p;
+
+ static const byte _tileh_bits[4][8] = {
+ { 2, 1, 8, 4, 16, 2, 0, 9 },
+ { 1, 8, 4, 2, 2, 16, 9, 0 },
+ { 4, 8, 1, 2, 16, 2, 0, 9 },
+ { 2, 4, 8, 1, 2, 16, 9, 0 }
+ };
+
+ if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
+
+ p = _tileh_bits[(image & 1) * 2 + (axis == AXIS_X ? 0 : 1)];
+ front_height = ti->z + (ti->tileh & p[0] ? TILE_HEIGHT : 0);
+ back_height = ti->z + (ti->tileh & p[1] ? TILE_HEIGHT : 0);
+
+ if (IsSteepSlope(ti->tileh)) {
+ if (!(ti->tileh & p[2])) front_height += TILE_HEIGHT;
+ if (!(ti->tileh & p[3])) back_height += TILE_HEIGHT;
+ }
+
+ for (; z >= front_height || z >= back_height; z -= TILE_HEIGHT) {
+ /* HACK set height of the BB of pillars to 1, because the origin of the
+ * sprites is at the top
+ */
+ if (z >= front_height) { // front facing pillar
+ AddSortableSpriteToDraw(image, x, y, p[4], p[5], 1, z);
+ }
+
+ if (drawfarpillar && z >= back_height && z < i - TILE_HEIGHT) { // back facing pillar
+ AddSortableSpriteToDraw(image, x - p[6], y - p[7], p[4], p[5], 1, z);
+ }
+ }
+ }
+}
+
+uint GetBridgeFoundation(Slope tileh, Axis axis)
+{
+ uint i;
+
+ if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh)) return tileh;
+
+ // inclined sloped building
+ switch (tileh) {
+ case SLOPE_W:
+ case SLOPE_STEEP_W: i = 0; break;
+ case SLOPE_S:
+ case SLOPE_STEEP_S: i = 2; break;
+ case SLOPE_E:
+ case SLOPE_STEEP_E: i = 4; break;
+ case SLOPE_N:
+ case SLOPE_STEEP_N: i = 6; break;
+ default: return 0;
+ }
+ if (axis != AXIS_X) ++i;
+ return i + 15;
+}
+
+/**
+ * Draws a tunnel of bridge tile.
+ * For tunnels, this is rather simple, as you only needa draw the entrance.
+ * Bridges are a bit more complex. base_offset is where the sprite selection comes into play
+ * and it works a bit like a bitmask.<p> For bridge heads:
+ * <ul><li>Bit 0: direction</li>
+ * <li>Bit 1: northern or southern heads</li>
+ * <li>Bit 2: Set if the bridge head is sloped</li>
+ * <li>Bit 3 and more: Railtype Specific subset</li>
+ * </ul>
+ * Please note that in this code, "roads" are treated as railtype 1, whilst the real railtypes are 0, 2 and 3
+ */
+static void DrawTile_TunnelBridge(TileInfo *ti)
+{
+ uint32 image;
+
+ if (IsTunnel(ti->tile)) {
+ if (GetTunnelTransportType(ti->tile) == TRANSPORT_RAIL) {
+ image = GetRailTypeInfo(GetRailType(ti->tile))->base_sprites.tunnel;
+ } else {
+ image = SPR_TUNNEL_ENTRY_REAR_ROAD;
+ }
+
+ if (HasTunnelSnowOrDesert(ti->tile)) image += 32;
+
+ image += GetTunnelDirection(ti->tile) * 2;
+ DrawGroundSprite(image);
+ if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
+
+ AddSortableSpriteToDraw(image+1, ti->x + TILE_SIZE - 1, ti->y + TILE_SIZE - 1, 1, 1, 8, (byte)ti->z);
+ DrawBridgeMiddle(ti);
+ } else if (IsBridge(ti->tile)) { // XXX is this necessary?
+ int base_offset;
+ bool ice = HasBridgeSnowOrDesert(ti->tile);
+
+ if (GetBridgeTransportType(ti->tile) == TRANSPORT_RAIL) {
+ base_offset = GetRailTypeInfo(GetRailType(ti->tile))->bridge_offset;
+ assert(base_offset != 8); /* This one is used for roads */
+ } else {
+ base_offset = 8;
+ }
+
+ /* as the lower 3 bits are used for other stuff, make sure they are clear */
+ assert( (base_offset & 0x07) == 0x00);
+
+ if (!HASBIT(BRIDGE_NO_FOUNDATION, ti->tileh)) {
+ int f = GetBridgeFoundation(ti->tileh, DiagDirToAxis(GetBridgeRampDirection(ti->tile)));
+ if (f != 0) DrawFoundation(ti, f);
+ }
+
+ // HACK Wizardry to convert the bridge ramp direction into a sprite offset
+ base_offset += (6 - GetBridgeRampDirection(ti->tile)) % 4;
+
+ if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head
+
+ /* Table number 6 always refers to the bridge heads for any bridge type */
+ image = GetBridgeSpriteTable(GetBridgeType(ti->tile), 6)[base_offset];
+
+ if (!ice) {
+ DrawClearLandTile(ti, 3);
+ } else {
+ DrawGroundSprite(SPR_FLAT_SNOWY_TILE + _tileh_to_sprite[ti->tileh]);
+ }
+
+ if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
+
+ // draw ramp
+ if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
+ /* HACK set the height of the BB of a sloped ramp to 1 so a vehicle on
+ * it doesn't disappear behind it
+ */
+ AddSortableSpriteToDraw(
+ image, ti->x, ti->y, 16, 16, ti->tileh == SLOPE_FLAT ? 1 : 8, ti->z
+ );
+
+ DrawBridgeMiddle(ti);
+ }
+}
+
+
+/** Compute bridge piece. Computes the bridge piece to display depending on the position inside the bridge.
+ * bridges pieces sequence (middle parts)
+ * bridge len 1: 0
+ * bridge len 2: 0 1
+ * bridge len 3: 0 4 1
+ * bridge len 4: 0 2 3 1
+ * bridge len 5: 0 2 5 3 1
+ * bridge len 6: 0 2 3 2 3 1
+ * bridge len 7: 0 2 3 4 2 3 1
+ * #0 - always as first, #1 - always as last (if len>1)
+ * #2,#3 are to pair in order
+ * for odd bridges: #5 is going in the bridge middle if on even position, #4 on odd (counting from 0)
+ * @param north Northernmost tile of bridge
+ * @param south Southernmost tile of bridge
+ * @return Index of bridge piece
+ */
+static uint CalcBridgePiece(uint north, uint south)
+{
+ if (north == 1) {
+ return 0;
+ } else if (south == 1) {
+ return 1;
+ } else if (north < south) {
+ return north & 1 ? 3 : 2;
+ } else if (north > south) {
+ return south & 1 ? 2 : 3;
+ } else {
+ return north & 1 ? 5 : 4;
+ }
+}
+
+
+void DrawBridgeMiddle(const TileInfo* ti)
+{
+ const PalSpriteID* b;
+ PalSpriteID image;
+ uint base_offset;
+ TileIndex rampnorth;
+ TileIndex rampsouth;
+ Axis axis;
+ uint piece;
+ uint type;
+ int x;
+ int y;
+ uint z;
+
+ if (!IsBridgeAbove(ti->tile)) return;
+
+ rampnorth = GetNorthernBridgeEnd(ti->tile);
+ rampsouth = GetSouthernBridgeEnd(ti->tile);
+
+ axis = GetBridgeAxis(ti->tile);
+ piece = CalcBridgePiece(
+ DistanceManhattan(ti->tile, rampnorth),
+ DistanceManhattan(ti->tile, rampsouth)
+ );
+ type = GetBridgeType(rampsouth);
+
+ if (GetBridgeTransportType(rampsouth) == TRANSPORT_RAIL) {
+ base_offset = GetRailTypeInfo(GetRailType(rampsouth))->bridge_offset;
+ } else {
+ base_offset = 8;
+ }
+
+ b = base_offset + GetBridgeSpriteTable(type, piece);
+ if (axis != AXIS_X) b += 4;
+
+ x = ti->x;
+ y = ti->y;
+ z = GetBridgeHeight(rampsouth) - 3;
+
+ image = b[0];
+ if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
+ if (axis == AXIS_X) {
+ AddSortableSpriteToDraw(image, x, y, 16, 11, 1, z);
+ } else {
+ AddSortableSpriteToDraw(image, x, y, 11, 16, 1, z);
+ }
+
+ image = b[1];
+ if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
+
+ // draw roof, the component of the bridge which is logically between the vehicle and the camera
+ if (axis == AXIS_X) {
+ y += 12;
+ if (image & SPRITE_MASK) AddSortableSpriteToDraw(image, x, y, 16, 1, 0x28, z);
+ } else {
+ x += 12;
+ if (image & SPRITE_MASK) AddSortableSpriteToDraw(image, x, y, 1, 16, 0x28, z);
+ }
+
+ if (GetRailType(rampsouth) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
+
+ if (ti->z + 5 == z) {
+ // draw poles below for small bridges
+ image = b[2];
+ if (image != 0) {
+ if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
+ DrawGroundSpriteAt(image, x, y, z);
+ }
+ } else if (_patches.bridge_pillars) {
+ // draw pillars below for high bridges
+ DrawBridgePillars(b[2], ti, axis, type, x, y, z);
+ }
+}
+
+
+uint SetSpeedLimitOnBridge(Vehicle *v)
+{
+ uint bridge_speed;
+ if (v->vehstatus & VS_HIDDEN) return v->max_speed; /* in tunnel */
+
+ bridge_speed = _bridge[GetBridgeType(v->tile)].speed;
+
+ if (v->type == VEH_Road) bridge_speed *= 2; /* XXX give vehicles proper speeds */
+
+ if (v->cur_speed > bridge_speed) v->cur_speed = bridge_speed;
+ return bridge_speed;
+}
+
+
+
+static uint GetSlopeZ_TunnelBridge(TileIndex tile, uint x, uint y)
+{
+ uint z;
+ Slope tileh = GetTileSlope(tile, &z);
+
+ x &= 0xF;
+ y &= 0xF;
+
+ if (IsTunnel(tile)) {
+ uint pos = (DiagDirToAxis(GetTunnelDirection(tile)) == AXIS_X ? y : x);
+
+ // In the tunnel entrance?
+ if (5 <= pos && pos <= 10) return z;
+ } else {
+ DiagDirection dir = GetBridgeRampDirection(tile);
+ uint pos = (DiagDirToAxis(dir) == AXIS_X ? y : x);
+
+ // On the bridge ramp?
+ if (5 <= pos && pos <= 10) {
+ uint delta;
+
+ if (IsSteepSlope(tileh)) return z + TILE_HEIGHT * 2;
+ if (HASBIT(BRIDGE_HORZ_RAMP, tileh)) return z + TILE_HEIGHT;
+
+ if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh)) z += TILE_HEIGHT;
+ switch (dir) {
+ default: NOT_REACHED();
+ case DIAGDIR_NE: delta = (TILE_SIZE - 1 - x) / 2; break;
+ case DIAGDIR_SE: delta = y / 2; break;
+ case DIAGDIR_SW: delta = x / 2; break;
+ case DIAGDIR_NW: delta = (TILE_SIZE - 1 - y) / 2; break;
+ }
+ return z + 1 + delta;
+ } else {
+ uint f = GetBridgeFoundation(tileh, DiagDirToAxis(dir));
+
+ if (f != 0) {
+ if (IsSteepSlope(tileh)) {
+ z += TILE_HEIGHT;
+ } else if (f < 15) {
+ return z + TILE_HEIGHT;
+ }
+ tileh = _inclined_tileh[f - 15];
+ }
+ }
+ }
+
+ return z + GetPartialZ(x, y, tileh);
+}
+
+static Slope GetSlopeTileh_TunnelBridge(TileIndex tile, Slope tileh)
+{
+ if (IsTunnel(tile)) {
+ return tileh;
+ } else {
+ if (HASBIT(BRIDGE_NO_FOUNDATION, tileh)) {
+ return tileh;
+ } else {
+ uint f = GetBridgeFoundation(tileh, DiagDirToAxis(GetBridgeRampDirection(tile)));
+
+ if (f == 0) return tileh;
+ if (f < 15) return SLOPE_FLAT;
+ return _inclined_tileh[f - 15];
+ }
+ }
+}
+
+
+static void GetAcceptedCargo_TunnelBridge(TileIndex tile, AcceptedCargo ac)
+{
+ /* not used */
+}
+
+static const StringID _bridge_tile_str[(MAX_BRIDGES + 3) + (MAX_BRIDGES + 3)] = {
+ STR_501F_WOODEN_RAIL_BRIDGE,
+ STR_5020_CONCRETE_RAIL_BRIDGE,
+ STR_501C_STEEL_GIRDER_RAIL_BRIDGE,
+ STR_501E_REINFORCED_CONCRETE_SUSPENSION,
+ STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE,
+ STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE,
+ STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE,
+ STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE,
+ STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE,
+ STR_501C_STEEL_GIRDER_RAIL_BRIDGE,
+ STR_5027_TUBULAR_RAIL_BRIDGE,
+ STR_5027_TUBULAR_RAIL_BRIDGE,
+ STR_5027_TUBULAR_RAIL_BRIDGE,
+ 0, 0, 0,
+
+ STR_5025_WOODEN_ROAD_BRIDGE,
+ STR_5026_CONCRETE_ROAD_BRIDGE,
+ STR_5022_STEEL_GIRDER_ROAD_BRIDGE,
+ STR_5024_REINFORCED_CONCRETE_SUSPENSION,
+ STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE,
+ STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE,
+ STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE,
+ STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE,
+ STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE,
+ STR_5022_STEEL_GIRDER_ROAD_BRIDGE,
+ STR_5028_TUBULAR_ROAD_BRIDGE,
+ STR_5028_TUBULAR_ROAD_BRIDGE,
+ STR_5028_TUBULAR_ROAD_BRIDGE,
+ 0, 0, 0,
+};
+
+static void GetTileDesc_TunnelBridge(TileIndex tile, TileDesc *td)
+{
+ if (IsTunnel(tile)) {
+ td->str = (GetTunnelTransportType(tile) == TRANSPORT_RAIL) ?
+ STR_5017_RAILROAD_TUNNEL : STR_5018_ROAD_TUNNEL;
+ } else {
+ td->str = _bridge_tile_str[GetBridgeTransportType(tile) << 4 | GetBridgeType(tile)];
+ }
+ td->owner = GetTileOwner(tile);
+}
+
+
+static void AnimateTile_TunnelBridge(TileIndex tile)
+{
+ /* not used */
+}
+
+static void TileLoop_TunnelBridge(TileIndex tile)
+{
+ bool snow_or_desert = IsTunnelTile(tile) ? HasTunnelSnowOrDesert(tile) : HasBridgeSnowOrDesert(tile);
+ switch (_opt.landscape) {
+ case LT_HILLY:
+ if (snow_or_desert != (GetTileZ(tile) > _opt.snow_line)) {
+ if (IsTunnelTile(tile)) {
+ SetTunnelSnowOrDesert(tile, !snow_or_desert);
+ } else {
+ SetBridgeSnowOrDesert(tile, !snow_or_desert);
+ }
+ MarkTileDirtyByTile(tile);
+ }
+ break;
+
+ case LT_DESERT:
+ if (GetTropicZone(tile) == TROPICZONE_DESERT && !snow_or_desert) {
+ if (IsTunnelTile(tile)) {
+ SetTunnelSnowOrDesert(tile, true);
+ } else {
+ SetBridgeSnowOrDesert(tile, true);
+ }
+ MarkTileDirtyByTile(tile);
+ }
+ break;
+ }
+}
+
+static void ClickTile_TunnelBridge(TileIndex tile)
+{
+ /* not used */
+}
+
+
+static uint32 GetTileTrackStatus_TunnelBridge(TileIndex tile, TransportType mode)
+{
+ if (IsTunnel(tile)) {
+ if (GetTunnelTransportType(tile) != mode) return 0;
+ return AxisToTrackBits(DiagDirToAxis(GetTunnelDirection(tile))) * 0x101;
+ } else {
+ if (GetBridgeTransportType(tile) != mode) return 0;
+ return AxisToTrackBits(DiagDirToAxis(GetBridgeRampDirection(tile))) * 0x101;
+ }
+}
+
+static void ChangeTileOwner_TunnelBridge(TileIndex tile, PlayerID old_player, PlayerID new_player)
+{
+ if (!IsTileOwner(tile, old_player)) return;
+
+ if (new_player != PLAYER_SPECTATOR) {
+ SetTileOwner(tile, new_player);
+ } else {
+ DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
+ }
+}
+
+
+static const byte _tunnel_fractcoord_1[4] = {0x8E, 0x18, 0x81, 0xE8};
+static const byte _tunnel_fractcoord_2[4] = {0x81, 0x98, 0x87, 0x38};
+static const byte _tunnel_fractcoord_3[4] = {0x82, 0x88, 0x86, 0x48};
+static const byte _exit_tunnel_track[4] = {1, 2, 1, 2};
+
+static const byte _road_exit_tunnel_state[4] = {8, 9, 0, 1};
+static const byte _road_exit_tunnel_frame[4] = {2, 7, 9, 4};
+
+static const byte _tunnel_fractcoord_4[4] = {0x52, 0x85, 0x98, 0x29};
+static const byte _tunnel_fractcoord_5[4] = {0x92, 0x89, 0x58, 0x25};
+static const byte _tunnel_fractcoord_6[4] = {0x92, 0x89, 0x56, 0x45};
+static const byte _tunnel_fractcoord_7[4] = {0x52, 0x85, 0x96, 0x49};
+
+static uint32 VehicleEnter_TunnelBridge(Vehicle *v, TileIndex tile, int x, int y)
+{
+ int z = GetSlopeZ(x, y) - v->z_pos;
+
+ if (myabs(z) > 2) return 8;
+
+ if (IsTunnel(tile)) {
+ byte fc;
+ DiagDirection dir;
+ DiagDirection vdir;
+
+ if (v->type == VEH_Train) {
+ fc = (x & 0xF) + (y << 4);
+
+ dir = GetTunnelDirection(tile);
+ vdir = DirToDiagDir(v->direction);
+
+ if (v->u.rail.track != 0x40 && dir == vdir) {
+ if (IsFrontEngine(v) && fc == _tunnel_fractcoord_1[dir]) {
+ if (!PlayVehicleSound(v, VSE_TUNNEL) && v->spritenum < 4) {
+ SndPlayVehicleFx(SND_05_TRAIN_THROUGH_TUNNEL, v);
+ }
+ return 0;
+ }
+ if (fc == _tunnel_fractcoord_2[dir]) {
+ v->tile = tile;
+ v->u.rail.track = 0x40;
+ v->vehstatus |= VS_HIDDEN;
+ return 4;
+ }
+ }
+
+ if (dir == ReverseDiagDir(vdir) && fc == _tunnel_fractcoord_3[dir] && z == 0) {
+ /* We're at the tunnel exit ?? */
+ v->tile = tile;
+ v->u.rail.track = _exit_tunnel_track[dir];
+ assert(v->u.rail.track);
+ v->vehstatus &= ~VS_HIDDEN;
+ return 4;
+ }
+ } else if (v->type == VEH_Road) {
+ fc = (x & 0xF) + (y << 4);
+ dir = GetTunnelDirection(tile);
+ vdir = DirToDiagDir(v->direction);
+
+ // Enter tunnel?
+ if (v->u.road.state != 0xFF && dir == vdir) {
+ if (fc == _tunnel_fractcoord_4[dir] ||
+ fc == _tunnel_fractcoord_5[dir]) {
+ v->tile = tile;
+ v->u.road.state = 0xFF;
+ v->vehstatus |= VS_HIDDEN;
+ return 4;
+ } else {
+ return 0;
+ }
+ }
+
+ if (dir == ReverseDiagDir(vdir) && (
+ /* We're at the tunnel exit ?? */
+ fc == _tunnel_fractcoord_6[dir] ||
+ fc == _tunnel_fractcoord_7[dir]
+ ) &&
+ z == 0) {
+ v->tile = tile;
+ v->u.road.state = _road_exit_tunnel_state[dir];
+ v->u.road.frame = _road_exit_tunnel_frame[dir];
+ v->vehstatus &= ~VS_HIDDEN;
+ return 4;
+ }
+ }
+ } else if (IsBridge(tile)) { // XXX is this necessary?
+ DiagDirection dir;
+
+ if (v->type == VEH_Road || (v->type == VEH_Train && IsFrontEngine(v))) {
+ /* modify speed of vehicle */
+ uint16 spd = _bridge[GetBridgeType(tile)].speed;
+
+ if (v->type == VEH_Road) spd *= 2;
+ if (v->cur_speed > spd) v->cur_speed = spd;
+ }
+
+ dir = GetBridgeRampDirection(tile);
+ if (DirToDiagDir(v->direction) == dir) {
+ switch (dir) {
+ default: NOT_REACHED();
+ case DIAGDIR_NE: if ((x & 0xF) != 0) return 0; break;
+ case DIAGDIR_SE: if ((y & 0xF) != TILE_SIZE - 1) return 0; break;
+ case DIAGDIR_SW: if ((x & 0xF) != TILE_SIZE - 1) return 0; break;
+ case DIAGDIR_NW: if ((y & 0xF) != 0) return 0; break;
+ }
+ if (v->type == VEH_Train) {
+ v->u.rail.track = 0x40;
+ CLRBIT(v->u.rail.flags, VRF_GOINGUP);
+ CLRBIT(v->u.rail.flags, VRF_GOINGDOWN);
+ } else {
+ v->u.road.state = 0xFF;
+ }
+ return 4;
+ } else if (DirToDiagDir(v->direction) == ReverseDiagDir(dir)) {
+ v->tile = tile;
+ if (v->type == VEH_Train) {
+ if (v->u.rail.track == 0x40) {
+ v->u.rail.track = (DiagDirToAxis(dir) == AXIS_X ? 1 : 2);
+ return 4;
+ }
+ } else {
+ if (v->u.road.state == 0xFF) {
+ v->u.road.state = _road_exit_tunnel_state[dir];
+ v->u.road.frame = 0;
+ return 4;
+ }
+ }
+ return 0;
+ }
+ }
+ return 0;
+}
+
+const TileTypeProcs _tile_type_tunnelbridge_procs = {
+ DrawTile_TunnelBridge, /* draw_tile_proc */
+ GetSlopeZ_TunnelBridge, /* get_slope_z_proc */
+ ClearTile_TunnelBridge, /* clear_tile_proc */
+ GetAcceptedCargo_TunnelBridge, /* get_accepted_cargo_proc */
+ GetTileDesc_TunnelBridge, /* get_tile_desc_proc */
+ GetTileTrackStatus_TunnelBridge, /* get_tile_track_status_proc */
+ ClickTile_TunnelBridge, /* click_tile_proc */
+ AnimateTile_TunnelBridge, /* animate_tile_proc */
+ TileLoop_TunnelBridge, /* tile_loop_clear */
+ ChangeTileOwner_TunnelBridge, /* change_tile_owner_clear */
+ NULL, /* get_produced_cargo_proc */
+ VehicleEnter_TunnelBridge, /* vehicle_enter_tile_proc */
+ GetSlopeTileh_TunnelBridge, /* get_slope_tileh_proc */
+};
diff --git a/src/unix.c b/src/unix.c
new file mode 100644
index 000000000..267351b00
--- /dev/null
+++ b/src/unix.c
@@ -0,0 +1,386 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "functions.h"
+#include "window.h"
+#include "string.h"
+#include "table/strings.h"
+#include "variables.h"
+
+#include <dirent.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <signal.h>
+
+#ifdef USE_HOMEDIR
+#include <pwd.h>
+#endif
+
+#if (defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L) || defined(__GLIBC__)
+ #define HAS_STATVFS
+#endif
+
+#ifdef HAS_STATVFS
+#include <sys/statvfs.h>
+#endif
+
+
+#ifdef __MORPHOS__
+#include <exec/types.h>
+ULONG __stack = (1024*1024)*2; // maybe not that much is needed actually ;)
+
+// The system supplied definition of SIG_IGN does not match
+#undef SIG_IGN
+#define SIG_IGN (void (*)(int))1
+#endif /* __MORPHOS__ */
+
+#ifdef __AMIGA__
+#warning add stack symbol to avoid that user needs to set stack manually (tokai)
+// ULONG __stack =
+#endif
+
+#if defined(__APPLE__)
+ #if defined(WITH_SDL)
+ //the mac implementation needs this file included in the same file as main()
+ #include <SDL.h>
+ #endif
+#endif
+
+bool FiosIsRoot(const char *path)
+{
+#if !defined(__MORPHOS__) && !defined(__AMIGAOS__)
+ return path[1] == '\0';
+#else
+ /* On MorphOS or AmigaOS paths look like: "Volume:directory/subdirectory" */
+ const char *s = strchr(path, ':');
+ return s[1] == '\0';
+#endif
+}
+
+void FiosGetDrives(void)
+{
+ return;
+}
+
+bool FiosGetDiskFreeSpace(const char *path, uint32 *tot)
+{
+ uint32 free = 0;
+
+#ifdef HAS_STATVFS
+ {
+ struct statvfs s;
+
+ if (statvfs(path, &s) != 0) return false;
+ free = (uint64)s.f_frsize * s.f_bavail >> 20;
+ }
+#endif
+ if (tot != NULL) *tot = free;
+ return true;
+}
+
+bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb)
+{
+ char filename[MAX_PATH];
+
+#if defined(__MORPHOS__) || defined(__AMIGAOS__)
+ /* On MorphOS or AmigaOS paths look like: "Volume:directory/subdirectory" */
+ if (FiosIsRoot(path)) {
+ snprintf(filename, lengthof(filename), "%s:%s", path, ent->d_name);
+ } else // XXX - only next line!
+#endif
+ snprintf(filename, lengthof(filename), "%s" PATHSEP "%s", path, ent->d_name);
+
+ if (stat(filename, sb) != 0) return false;
+
+ return (ent->d_name[0] != '.'); // hidden file
+}
+
+#if defined(__BEOS__) || defined(__linux__)
+static void ChangeWorkingDirectory(char *exe)
+{
+ char *s = strrchr(exe, '/');
+ if (s != NULL) {
+ *s = '\0';
+ chdir(exe);
+ *s = '/';
+ }
+}
+#endif
+
+void ShowInfo(const char *str)
+{
+ puts(str);
+}
+
+void ShowOSErrorBox(const char *buf)
+{
+#if defined(__APPLE__)
+ // this creates an NSAlertPanel with the contents of 'buf'
+ // this is the native and nicest way to do this on OSX
+ ShowMacDialog( buf, "See readme for more info\nMost likely you are missing files from the original TTD", "Quit" );
+#else
+ // all systems, but OSX
+ fprintf(stderr, "\033[1;31mError: %s\033[0;39m\n", buf);
+#endif
+}
+
+#ifdef WITH_COCOA
+void cocoaSetWorkingDirectory(void);
+void cocoaSetupAutoreleasePool(void);
+void cocoaReleaseAutoreleasePool(void);
+#endif
+
+int CDECL main(int argc, char* argv[])
+{
+ int ret;
+
+#ifdef WITH_COCOA
+ cocoaSetupAutoreleasePool();
+ /* This is passed if we are launched by double-clicking */
+ if (argc >= 2 && strncmp(argv[1], "-psn", 4) == 0) {
+ argv[1] = NULL;
+ argc = 1;
+ cocoaSetWorkingDirectory();
+ }
+#endif
+
+ // change the working directory to enable doubleclicking in UIs
+#if defined(__BEOS__) || defined(__linux__)
+ ChangeWorkingDirectory(argv[0]);
+#endif
+
+ _random_seeds[1][1] = _random_seeds[1][0] = _random_seeds[0][1] = _random_seeds[0][0] = time(NULL);
+ SeedMT(_random_seeds[0][1]);
+
+ signal(SIGPIPE, SIG_IGN);
+
+ ret = ttd_main(argc, argv);
+
+#ifdef WITH_COCOA
+ cocoaReleaseAutoreleasePool();
+#endif
+
+ return ret;
+}
+
+void DeterminePaths(void)
+{
+ char *s;
+
+ _paths.game_data_dir = malloc(MAX_PATH);
+ ttd_strlcpy(_paths.game_data_dir, GAME_DATA_DIR, MAX_PATH);
+ #if defined SECOND_DATA_DIR
+ _paths.second_data_dir = malloc(MAX_PATH);
+ ttd_strlcpy(_paths.second_data_dir, SECOND_DATA_DIR, MAX_PATH);
+ #endif
+
+#if defined(USE_HOMEDIR)
+ {
+ const char *homedir = getenv("HOME");
+
+ if (homedir == NULL) {
+ const struct passwd *pw = getpwuid(getuid());
+ if (pw != NULL) homedir = pw->pw_dir;
+ }
+
+ _paths.personal_dir = str_fmt("%s" PATHSEP "%s", homedir, PERSONAL_DIR);
+ }
+
+#else /* not defined(USE_HOMEDIR) */
+
+ _paths.personal_dir = malloc(MAX_PATH);
+ ttd_strlcpy(_paths.personal_dir, PERSONAL_DIR, MAX_PATH);
+
+ // check if absolute or relative path
+ s = strchr(_paths.personal_dir, '/');
+
+ // add absolute path
+ if (s == NULL || _paths.personal_dir != s) {
+ getcwd(_paths.personal_dir, MAX_PATH);
+ s = strchr(_paths.personal_dir, 0);
+ *s++ = '/';
+ ttd_strlcpy(s, PERSONAL_DIR, MAX_PATH);
+ }
+
+#endif /* defined(USE_HOMEDIR) */
+
+ s = strchr(_paths.personal_dir, 0);
+
+ // append a / ?
+ if (s[-1] != '/') strcpy(s, "/");
+
+ _paths.save_dir = str_fmt("%ssave", _paths.personal_dir);
+ _paths.autosave_dir = str_fmt("%s/autosave", _paths.save_dir);
+ _paths.scenario_dir = str_fmt("%sscenario", _paths.personal_dir);
+ _paths.heightmap_dir = str_fmt("%sscenario/heightmap", _paths.personal_dir);
+ _paths.gm_dir = str_fmt("%sgm/", _paths.game_data_dir);
+ _paths.data_dir = str_fmt("%sdata/", _paths.game_data_dir);
+
+ if (_config_file == NULL)
+ _config_file = str_fmt("%sopenttd.cfg", _paths.personal_dir);
+
+ _highscore_file = str_fmt("%shs.dat", _paths.personal_dir);
+ _log_file = str_fmt("%sopenttd.log", _paths.personal_dir);
+
+#if defined CUSTOM_LANG_DIR
+ // sets the search path for lng files to the custom one
+ _paths.lang_dir = malloc( MAX_PATH );
+ ttd_strlcpy( _paths.lang_dir, CUSTOM_LANG_DIR, MAX_PATH);
+#else
+ _paths.lang_dir = str_fmt("%slang/", _paths.game_data_dir);
+#endif
+
+ // create necessary folders
+ mkdir(_paths.personal_dir, 0755);
+ mkdir(_paths.save_dir, 0755);
+ mkdir(_paths.autosave_dir, 0755);
+ mkdir(_paths.scenario_dir, 0755);
+ mkdir(_paths.heightmap_dir, 0755);
+}
+
+bool InsertTextBufferClipboard(Textbuf *tb)
+{
+ return false;
+}
+
+
+// multi os compatible sleep function
+
+#ifdef __AMIGA__
+// usleep() implementation
+# include <devices/timer.h>
+# include <dos/dos.h>
+
+ extern struct Device *TimerBase = NULL;
+ extern struct MsgPort *TimerPort = NULL;
+ extern struct timerequest *TimerRequest = NULL;
+#endif // __AMIGA__
+
+void CSleep(int milliseconds)
+{
+ #if !defined(__BEOS__) && !defined(__AMIGA__)
+ usleep(milliseconds * 1000);
+ #endif
+ #ifdef __BEOS__
+ snooze(milliseconds * 1000);
+ #endif
+ #if defined(__AMIGA__)
+ {
+ ULONG signals;
+ ULONG TimerSigBit = 1 << TimerPort->mp_SigBit;
+
+ // send IORequest
+ TimerRequest->tr_node.io_Command = TR_ADDREQUEST;
+ TimerRequest->tr_time.tv_secs = (milliseconds * 1000) / 1000000;
+ TimerRequest->tr_time.tv_micro = (milliseconds * 1000) % 1000000;
+ SendIO((struct IORequest *)TimerRequest);
+
+ if (!((signals = Wait(TimerSigBit | SIGBREAKF_CTRL_C)) & TimerSigBit) ) {
+ AbortIO((struct IORequest *)TimerRequest);
+ }
+ WaitIO((struct IORequest *)TimerRequest);
+ }
+ #endif // __AMIGA__
+}
+
+#ifdef WITH_ICONV
+
+#include <iconv.h>
+#include <errno.h>
+#include "debug.h"
+
+#define INTERNALCODE "UTF-8"
+
+/** Try and try to decipher the current locale from environmental
+ * variables. MacOSX is hardcoded, other OS's are dynamic. If no suitable
+ * locale can be found, don't do any conversion "" */
+static const char *GetLocalCode(void)
+{
+#if defined(__APPLE__)
+ return "UTF-8-MAC";
+#else
+ /* Strip locale (eg en_US.UTF-8) to only have UTF-8 */
+ const char *locale = GetCurrentLocale("LC_CTYPE");
+ if (locale != NULL) locale = strchr(locale, '.');
+
+ return (locale == NULL) ? "" : locale + 1;
+#endif
+}
+
+/** FYI: This is not thread-safe.
+ * convert between locales, which from and which to is set in the calling
+ * functions OTTD2FS() and FS2OTTD(). You should NOT use this function directly
+ * NOTE: iconv was added in OSX 10.3. 10.2.x will still have the invalid char
+ * issues. There aren't any easy fix for this */
+static const char *convert_tofrom_fs(iconv_t convd, const char *name)
+{
+ static char buf[1024];
+ /* Work around buggy iconv implementation where inbuf is wrongly typed as
+ * non-const. Correct implementation is at
+ * http://www.opengroup.org/onlinepubs/007908799/xsh/iconv.html */
+#if defined (__GLIBC__) || defined (__GNU_LIBRARY__)
+ char *inbuf = (char*)name;
+#else
+ const char *inbuf = name;
+#endif
+
+ char *outbuf = buf;
+ size_t outlen = sizeof(buf) - 1;
+ size_t inlen = strlen(name);
+
+ ttd_strlcpy(outbuf, name, sizeof(buf));
+
+ iconv(convd, NULL, NULL, NULL, NULL);
+ if (iconv(convd, &inbuf, &inlen, &outbuf, &outlen) == (size_t)(-1)) {
+ DEBUG(misc, 0, "[iconv] error converting '%s'. Errno %d", name, errno);
+ }
+
+ *outbuf = '\0';
+ // FIX: invalid characters will abort conversion, but they shouldn't occur?
+ return buf;
+}
+
+/** Convert from OpenTTD's encoding to that of the local environment
+ * @param name pointer to a valid string that will be converted
+ * @return pointer to a new stringbuffer that contains the converted string */
+const char *OTTD2FS(const char *name)
+{
+ static iconv_t convd = (iconv_t)(-1);
+
+ if (convd == (iconv_t)(-1)) {
+ const char *env = GetLocalCode();
+ convd = iconv_open(env, INTERNALCODE);
+ if (convd == (iconv_t)(-1)) {
+ DEBUG(misc, 0, "[iconv] conversion from codeset '%s' to '%s' unsupported", INTERNALCODE, env);
+ return name;
+ }
+ }
+
+ return convert_tofrom_fs(convd, name);
+}
+
+/** Convert to OpenTTD's encoding from that of the local environment
+ * @param name pointer to a valid string that will be converted
+ * @return pointer to a new stringbuffer that contains the converted string */
+const char *FS2OTTD(const char *name)
+{
+ static iconv_t convd = (iconv_t)(-1);
+
+ if (convd == (iconv_t)(-1)) {
+ const char *env = GetLocalCode();
+ convd = iconv_open(INTERNALCODE, env);
+ if (convd == (iconv_t)(-1)) {
+ DEBUG(misc, 0, "[iconv] conversion from codeset '%s' to '%s' unsupported", env, INTERNALCODE);
+ return name;
+ }
+ }
+
+ return convert_tofrom_fs(convd, name);
+}
+
+#else
+const char *FS2OTTD(const char *name) {return name;}
+const char *OTTD2FS(const char *name) {return name;}
+#endif /* WITH_ICONV */
diff --git a/src/unmovable.h b/src/unmovable.h
new file mode 100644
index 000000000..d7483aa6e
--- /dev/null
+++ b/src/unmovable.h
@@ -0,0 +1,8 @@
+/* $Id$ */
+
+#ifndef UNMOVABLE_H
+#define UNMOVABLE_H
+
+void UpdateCompanyHQ(Player *p, uint score);
+
+#endif /* UNMOVABLE_H */
diff --git a/src/unmovable_cmd.c b/src/unmovable_cmd.c
new file mode 100644
index 000000000..5c1666c22
--- /dev/null
+++ b/src/unmovable_cmd.c
@@ -0,0 +1,414 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "bridge_map.h"
+#include "table/strings.h"
+#include "table/sprites.h"
+#include "functions.h"
+#include "map.h"
+#include "tile.h"
+#include "command.h"
+#include "viewport.h"
+#include "player.h"
+#include "gui.h"
+#include "station.h"
+#include "economy.h"
+#include "town.h"
+#include "sprite.h"
+#include "unmovable_map.h"
+#include "variables.h"
+#include "table/unmovable_land.h"
+#include "genworld.h"
+
+/** Destroy a HQ.
+ * During normal gameplay you can only implicitely destroy a HQ when you are
+ * rebuilding it. Otherwise, only water can destroy it.
+ * @param tile tile coordinates where HQ is located to destroy
+ * @param flags docommand flags of calling function
+ */
+static int32 DestroyCompanyHQ(PlayerID pid, uint32 flags)
+{
+ Player* p = GetPlayer(pid);
+
+ SET_EXPENSES_TYPE(EXPENSES_PROPERTY);
+
+ if (flags & DC_EXEC) {
+ TileIndex t = p->location_of_house;
+
+ DoClearSquare(t + TileDiffXY(0, 0));
+ DoClearSquare(t + TileDiffXY(0, 1));
+ DoClearSquare(t + TileDiffXY(1, 0));
+ DoClearSquare(t + TileDiffXY(1, 1));
+ p->location_of_house = 0; // reset HQ position
+ InvalidateWindow(WC_COMPANY, pid);
+ }
+
+ // cost of relocating company is 1% of company value
+ return CalculateCompanyValue(p) / 100;
+}
+
+void UpdateCompanyHQ(Player *p, uint score)
+{
+ byte val;
+ TileIndex tile = p->location_of_house;
+
+ if (tile == 0) return;
+
+ (val = 0, score < 170) ||
+ (val++, score < 350) ||
+ (val++, score < 520) ||
+ (val++, score < 720) ||
+ (val++, true);
+
+ EnlargeCompanyHQ(tile, val);
+
+ MarkTileDirtyByTile(tile + TileDiffXY(0, 0));
+ MarkTileDirtyByTile(tile + TileDiffXY(0, 1));
+ MarkTileDirtyByTile(tile + TileDiffXY(1, 0));
+ MarkTileDirtyByTile(tile + TileDiffXY(1, 1));
+}
+
+/** Build or relocate the HQ. This depends if the HQ is already built or not
+ * @param tile tile where the HQ will be built or relocated to
+ * @param p1 unused
+ * @param p2 unused
+ */
+extern int32 CheckFlatLandBelow(TileIndex tile, uint w, uint h, uint flags, uint invalid_dirs, int *);
+int32 CmdBuildCompanyHQ(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Player *p = GetPlayer(_current_player);
+ int cost;
+ int32 ret;
+
+ SET_EXPENSES_TYPE(EXPENSES_PROPERTY);
+
+ ret = CheckFlatLandBelow(tile, 2, 2, flags, 0, NULL);
+ if (CmdFailed(ret)) return ret;
+ cost = ret;
+
+ if (p->location_of_house != 0) { /* Moving HQ */
+ cost += DestroyCompanyHQ(_current_player, flags);
+ }
+
+ if (flags & DC_EXEC) {
+ int score = UpdateCompanyRatingAndValue(p, false);
+
+ p->location_of_house = tile;
+
+ MakeCompanyHQ(tile, _current_player);
+
+ UpdateCompanyHQ(p, score);
+ InvalidateWindow(WC_COMPANY, p->index);
+ }
+
+ return cost;
+}
+
+static void DrawTile_Unmovable(TileInfo *ti)
+{
+ uint32 image, ormod;
+
+ switch (GetUnmovableType(ti->tile)) {
+ case UNMOVABLE_TRANSMITTER:
+ case UNMOVABLE_LIGHTHOUSE: {
+ const DrawTileUnmovableStruct* dtus;
+
+ if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
+ DrawClearLandTile(ti, 2);
+
+ dtus = &_draw_tile_unmovable_data[GetUnmovableType(ti->tile)];
+
+ image = dtus->image;
+ if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
+
+ AddSortableSpriteToDraw(
+ image, ti->x | dtus->subcoord_x, ti->y | dtus->subcoord_y,
+ dtus->width, dtus->height, dtus->z_size, ti->z
+ );
+ break;
+ }
+
+ case UNMOVABLE_STATUE:
+ DrawGroundSprite(SPR_CONCRETE_GROUND);
+
+ image = PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile));
+ image += PALETTE_MODIFIER_COLOR | SPR_STATUE_COMPANY;
+ if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
+ AddSortableSpriteToDraw(image, ti->x, ti->y, 16, 16, 25, ti->z);
+ break;
+
+ case UNMOVABLE_OWNED_LAND:
+ DrawClearLandTile(ti, 0);
+
+ AddSortableSpriteToDraw(
+ PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile)) + PALETTE_MODIFIER_COLOR + SPR_BOUGHT_LAND,
+ ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 10, GetSlopeZ(ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2)
+ );
+ DrawBridgeMiddle(ti);
+ break;
+
+ default: {
+ const DrawTileSeqStruct* dtss;
+ const DrawTileSprites* t;
+
+ assert(IsCompanyHQ(ti->tile));
+ if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
+
+ ormod = PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile));
+
+ t = &_unmovable_display_datas[GetCompanyHQSection(ti->tile)];
+ DrawGroundSprite(t->ground_sprite | ormod);
+
+ foreach_draw_tile_seq(dtss, t->seq) {
+ image = dtss->image;
+ if (_display_opt & DO_TRANS_BUILDINGS) {
+ MAKE_TRANSPARENT(image);
+ } else {
+ image |= ormod;
+ }
+ AddSortableSpriteToDraw(
+ image,
+ ti->x + dtss->delta_x, ti->y + dtss->delta_y,
+ dtss->size_x, dtss->size_y,
+ dtss->size_z, ti->z + dtss->delta_z
+ );
+ }
+ break;
+ }
+ }
+}
+
+static uint GetSlopeZ_Unmovable(TileIndex tile, uint x, uint y)
+{
+ if (IsOwnedLand(tile)) {
+ uint z;
+ uint tileh = GetTileSlope(tile, &z);
+
+ return z + GetPartialZ(x & 0xF, y & 0xF, tileh);
+ } else {
+ return GetTileMaxZ(tile);
+ }
+}
+
+static Slope GetSlopeTileh_Unmovable(TileIndex tile, Slope tileh)
+{
+ return IsOwnedLand(tile) ? tileh : SLOPE_FLAT;
+}
+
+static int32 ClearTile_Unmovable(TileIndex tile, byte flags)
+{
+ if (IsCompanyHQ(tile)) {
+ if (_current_player == OWNER_WATER) {
+ return DestroyCompanyHQ(GetTileOwner(tile), DC_EXEC);
+ } else {
+ return_cmd_error(STR_5804_COMPANY_HEADQUARTERS_IN);
+ }
+ }
+
+ if (IsOwnedLand(tile)) {
+ return DoCommand(tile, 0, 0, flags, CMD_SELL_LAND_AREA);
+ }
+
+ // checks if you're allowed to remove unmovable things
+ if (_game_mode != GM_EDITOR && _current_player != OWNER_WATER && ((flags & DC_AUTO || !_cheats.magic_bulldozer.value)) )
+ return_cmd_error(STR_5800_OBJECT_IN_THE_WAY);
+
+ if (flags & DC_EXEC) {
+ DoClearSquare(tile);
+ }
+
+ return 0;
+}
+
+static void GetAcceptedCargo_Unmovable(TileIndex tile, AcceptedCargo ac)
+{
+ uint level; // HQ level (depends on company performance) in the range 1..5.
+
+ if (!IsCompanyHQ(tile)) return;
+
+ /* HQ accepts passenger and mail; but we have to divide the values
+ * between 4 tiles it occupies! */
+
+ level = GetCompanyHQSize(tile) + 1;
+
+ // Top town building generates 10, so to make HQ interesting, the top
+ // type makes 20.
+ ac[CT_PASSENGERS] = max(1, level);
+
+ // Top town building generates 4, HQ can make up to 8. The
+ // proportion passengers:mail is different because such a huge
+ // commercial building generates unusually high amount of mail
+ // correspondence per physical visitor.
+ ac[CT_MAIL] = max(1, level / 2);
+}
+
+
+static void GetTileDesc_Unmovable(TileIndex tile, TileDesc *td)
+{
+ switch (GetUnmovableType(tile)) {
+ case UNMOVABLE_TRANSMITTER: td->str = STR_5801_TRANSMITTER; break;
+ case UNMOVABLE_LIGHTHOUSE: td->str = STR_5802_LIGHTHOUSE; break;
+ case UNMOVABLE_STATUE: td->str = STR_2016_STATUE; break;
+ case UNMOVABLE_OWNED_LAND: td->str = STR_5805_COMPANY_OWNED_LAND; break;
+ default: td->str = STR_5803_COMPANY_HEADQUARTERS; break;
+ }
+ td->owner = GetTileOwner(tile);
+}
+
+static void AnimateTile_Unmovable(TileIndex tile)
+{
+ /* not used */
+}
+
+static void TileLoop_Unmovable(TileIndex tile)
+{
+ uint level; // HQ level (depends on company performance) in the range 1..5.
+ uint32 r;
+
+ if (!IsCompanyHQ(tile)) return;
+
+ /* HQ accepts passenger and mail; but we have to divide the values
+ * between 4 tiles it occupies! */
+
+ level = GetCompanyHQSize(tile) + 1;
+ assert(level < 6);
+
+ r = Random();
+ // Top town buildings generate 250, so the top HQ type makes 256.
+ if (GB(r, 0, 8) < (256 / 4 / (6 - level))) {
+ uint amt = GB(r, 0, 8) / 8 / 4 + 1;
+ if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
+ MoveGoodsToStation(tile, 2, 2, CT_PASSENGERS, amt);
+ }
+
+ // Top town building generates 90, HQ can make up to 196. The
+ // proportion passengers:mail is about the same as in the acceptance
+ // equations.
+ if (GB(r, 8, 8) < (196 / 4 / (6 - level))) {
+ uint amt = GB(r, 8, 8) / 8 / 4 + 1;
+ if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
+ MoveGoodsToStation(tile, 2, 2, CT_MAIL, amt);
+ }
+}
+
+
+static uint32 GetTileTrackStatus_Unmovable(TileIndex tile, TransportType mode)
+{
+ return 0;
+}
+
+static void ClickTile_Unmovable(TileIndex tile)
+{
+ if (IsCompanyHQ(tile)) ShowPlayerCompany(GetTileOwner(tile));
+}
+
+
+/* checks, if a radio tower is within a 9x9 tile square around tile */
+static bool IsRadioTowerNearby(TileIndex tile)
+{
+ TileIndex tile_s = tile - TileDiffXY(4, 4);
+
+ BEGIN_TILE_LOOP(tile, 9, 9, tile_s)
+ if (IsTransmitterTile(tile)) return true;
+ END_TILE_LOOP(tile, 9, 9, tile_s)
+
+ return false;
+}
+
+void GenerateUnmovables(void)
+{
+ int i, li, j, loop_count;
+ TileIndex tile;
+ uint h;
+ uint maxx;
+ uint maxy;
+
+ if (_opt.landscape == LT_CANDY) return;
+
+ /* add radio tower */
+ i = ScaleByMapSize(1000);
+ j = ScaleByMapSize(15); // maximum number of radio towers on the map
+ li = ScaleByMapSize1D((Random() & 3) + 7);
+ SetGeneratingWorldProgress(GWP_UNMOVABLE, j + li);
+
+ do {
+ tile = RandomTile();
+ if (IsTileType(tile, MP_CLEAR) && GetTileSlope(tile, &h) == SLOPE_FLAT && h >= TILE_HEIGHT * 4) {
+ if (IsRadioTowerNearby(tile)) continue;
+ MakeTransmitter(tile);
+ IncreaseGeneratingWorldProgress(GWP_UNMOVABLE);
+ if (--j == 0) break;
+ }
+ } while (--i);
+
+ if (_opt.landscape == LT_DESERT) return;
+
+ /* add lighthouses */
+ i = li;
+ maxx = MapMaxX();
+ maxy = MapMaxY();
+ loop_count = 0;
+ do {
+ uint32 r;
+ DiagDirection dir;
+ int perimeter;
+
+restart:
+ /* Avoid infinite loops */
+ if (++loop_count > 1000) break;
+
+ r = Random();
+
+ /* Scatter the lighthouses more evenly around the perimeter */
+ perimeter = (GB(r, 16, 16) % (2 * (maxx + maxy))) - maxy;
+ for (dir = DIAGDIR_NE; perimeter > 0; dir++) {
+ perimeter -= (DiagDirToAxis(dir) == AXIS_X) ? maxx : maxy;
+ }
+
+ switch (dir) {
+ default:
+ case DIAGDIR_NE: tile = TileXY(maxx, r % maxy); break;
+ case DIAGDIR_SE: tile = TileXY(r % maxx, 0); break;
+ case DIAGDIR_SW: tile = TileXY(0, r % maxy); break;
+ case DIAGDIR_NW: tile = TileXY(r % maxx, maxy); break;
+ }
+ j = 20;
+ do {
+ if (--j == 0) goto restart;
+ tile = TILE_MASK(tile + TileOffsByDiagDir(dir));
+ } while (!(IsTileType(tile, MP_CLEAR) && GetTileSlope(tile, &h) == SLOPE_FLAT && h <= TILE_HEIGHT * 2));
+
+ assert(tile == TILE_MASK(tile));
+
+ MakeLighthouse(tile);
+ IncreaseGeneratingWorldProgress(GWP_UNMOVABLE);
+ } while (--i);
+}
+
+static void ChangeTileOwner_Unmovable(TileIndex tile, PlayerID old_player, PlayerID new_player)
+{
+ if (!IsTileOwner(tile, old_player)) return;
+
+ if (IsOwnedLand(tile) && new_player != PLAYER_SPECTATOR) {
+ SetTileOwner(tile, new_player);
+ } else {
+ DoClearSquare(tile);
+ }
+}
+
+const TileTypeProcs _tile_type_unmovable_procs = {
+ DrawTile_Unmovable, /* draw_tile_proc */
+ GetSlopeZ_Unmovable, /* get_slope_z_proc */
+ ClearTile_Unmovable, /* clear_tile_proc */
+ GetAcceptedCargo_Unmovable, /* get_accepted_cargo_proc */
+ GetTileDesc_Unmovable, /* get_tile_desc_proc */
+ GetTileTrackStatus_Unmovable, /* get_tile_track_status_proc */
+ ClickTile_Unmovable, /* click_tile_proc */
+ AnimateTile_Unmovable, /* animate_tile_proc */
+ TileLoop_Unmovable, /* tile_loop_clear */
+ ChangeTileOwner_Unmovable, /* change_tile_owner_clear */
+ NULL, /* get_produced_cargo_proc */
+ NULL, /* vehicle_enter_tile_proc */
+ GetSlopeTileh_Unmovable, /* get_slope_tileh_proc */
+};
diff --git a/src/unmovable_map.h b/src/unmovable_map.h
new file mode 100644
index 000000000..d016a7ac1
--- /dev/null
+++ b/src/unmovable_map.h
@@ -0,0 +1,121 @@
+/* $Id$ */
+
+#ifndef UNMOVABLE_MAP_H
+#define UNMOVABLE_MAP_H
+
+enum {
+ HQ_NUM_TILE = 4,
+ HQ_NUM_SIZE = 5
+};
+
+typedef enum UnmovableType {
+ UNMOVABLE_TRANSMITTER = 0,
+ UNMOVABLE_LIGHTHOUSE = 1,
+ UNMOVABLE_STATUE = 2,
+ UNMOVABLE_OWNED_LAND = 3,
+ UNMOVABLE_HQ_NORTH = 0x80,
+ UNMOVABLE_HQ_WEST = 0x81,
+ UNMOVABLE_HQ_EAST = 0x82,
+ UNMOVABLE_HQ_SOUTH = 0x83,
+
+ UNMOVABLE_HQ_END = UNMOVABLE_HQ_NORTH + HQ_NUM_SIZE * HQ_NUM_TILE
+} UnmovableType;
+
+
+
+static inline UnmovableType GetUnmovableType(TileIndex t)
+{
+ assert(IsTileType(t, MP_UNMOVABLE));
+ return _m[t].m5;
+}
+
+
+static inline bool IsTransmitterTile(TileIndex t)
+{
+ return
+ IsTileType(t, MP_UNMOVABLE) &&
+ GetUnmovableType(t) == UNMOVABLE_TRANSMITTER;
+}
+
+
+static inline bool IsOwnedLand(TileIndex t)
+{
+ assert(IsTileType(t, MP_UNMOVABLE));
+ return GetUnmovableType(t) == UNMOVABLE_OWNED_LAND;
+}
+
+static inline bool IsOwnedLandTile(TileIndex t)
+{
+ return IsTileType(t, MP_UNMOVABLE) && IsOwnedLand(t);
+}
+
+static inline bool IsCompanyHQ(TileIndex t)
+{
+ return IS_INT_INSIDE(GetUnmovableType(t), UNMOVABLE_HQ_NORTH, UNMOVABLE_HQ_END);
+}
+
+static inline byte GetCompanyHQSize(TileIndex t)
+{
+ assert(IsTileType(t, MP_UNMOVABLE) && IsCompanyHQ(t));
+ return GB(_m[t].m5, 2, 3);
+}
+
+static inline byte GetCompanyHQSection(TileIndex t)
+{
+ assert(IsTileType(t, MP_UNMOVABLE) && IsCompanyHQ(t));
+ return GB(_m[t].m5, 0, 5);
+}
+
+
+static inline void EnlargeCompanyHQ(TileIndex t, byte size)
+{
+ size *= 4;
+ if (size <= _m[t].m5 - UNMOVABLE_HQ_NORTH) return;
+
+ _m[t + TileDiffXY(0, 0)].m5 = UNMOVABLE_HQ_NORTH + size;
+ _m[t + TileDiffXY(0, 1)].m5 = UNMOVABLE_HQ_WEST + size;
+ _m[t + TileDiffXY(1, 0)].m5 = UNMOVABLE_HQ_EAST + size;
+ _m[t + TileDiffXY(1, 1)].m5 = UNMOVABLE_HQ_SOUTH + size;
+}
+
+
+static inline void MakeUnmovable(TileIndex t, UnmovableType u, Owner o)
+{
+ SetTileType(t, MP_UNMOVABLE);
+ SetTileOwner(t, o);
+ _m[t].m2 = 0;
+ _m[t].m3 = 0;
+ _m[t].m4 = 0;
+ _m[t].m5 = u;
+}
+
+
+static inline void MakeTransmitter(TileIndex t)
+{
+ MakeUnmovable(t, UNMOVABLE_TRANSMITTER, OWNER_NONE);
+}
+
+static inline void MakeLighthouse(TileIndex t)
+{
+ MakeUnmovable(t, UNMOVABLE_LIGHTHOUSE, OWNER_NONE);
+}
+
+static inline void MakeStatue(TileIndex t, Owner o)
+{
+ MakeUnmovable(t, UNMOVABLE_STATUE, o);
+}
+
+static inline void MakeOwnedLand(TileIndex t, Owner o)
+{
+ MakeUnmovable(t, UNMOVABLE_OWNED_LAND, o);
+}
+
+static inline void MakeCompanyHQ(TileIndex t, Owner o)
+{
+ MakeUnmovable(t + TileDiffXY(0, 0), UNMOVABLE_HQ_NORTH, o);
+ MakeUnmovable(t + TileDiffXY(0, 1), UNMOVABLE_HQ_WEST, o);
+ MakeUnmovable(t + TileDiffXY(1, 0), UNMOVABLE_HQ_EAST, o);
+ MakeUnmovable(t + TileDiffXY(1, 1), UNMOVABLE_HQ_SOUTH, o);
+}
+
+#endif /* UNMOVABLE_MAP_H */
diff --git a/src/variables.h b/src/variables.h
new file mode 100644
index 000000000..bbbe0b79b
--- /dev/null
+++ b/src/variables.h
@@ -0,0 +1,420 @@
+/* $Id$ */
+
+#ifndef VARIABLES_H
+#define VARIABLES_H
+
+#include "yapf/yapf_settings.h"
+
+// ********* START OF SAVE REGION
+#if !defined(MAX_PATH)
+# define MAX_PATH 260
+#endif
+
+// Prices and also the fractional part.
+VARDEF Prices _price;
+VARDEF uint16 _price_frac[NUM_PRICES];
+
+VARDEF uint32 _cargo_payment_rates[NUM_CARGO];
+VARDEF uint16 _cargo_payment_rates_frac[NUM_CARGO];
+
+typedef struct {
+ GameDifficulty diff;
+ byte diff_level;
+ byte currency;
+ byte units;
+ byte town_name;
+ byte landscape;
+ byte snow_line;
+ byte autosave;
+ byte road_side;
+} GameOptions;
+
+/* These are the options for the current game
+ * either ingame, or loaded. Also used for networking games */
+VARDEF GameOptions _opt;
+
+/* These are the default options for a new game */
+VARDEF GameOptions _opt_newgame;
+
+// Pointer to one of the two _opt OR _opt_newgame structs
+VARDEF GameOptions *_opt_ptr;
+
+// Amount of game ticks
+VARDEF uint16 _tick_counter;
+
+// This one is not used anymore.
+VARDEF VehicleID _vehicle_id_ctr_day;
+
+// Skip aging of cargo?
+VARDEF byte _age_cargo_skip_counter;
+
+// Available aircraft types
+VARDEF byte _avail_aircraft;
+
+// Position in tile loop
+VARDEF TileIndex _cur_tileloop_tile;
+
+// Also save scrollpos_x, scrollpos_y and zoom
+VARDEF uint16 _disaster_delay;
+
+// Determines what station to operate on in the
+// tick handler.
+VARDEF uint16 _station_tick_ctr;
+
+VARDEF uint32 _random_seeds[2][2];
+
+// Iterator through all towns in OnTick_Town
+VARDEF uint32 _cur_town_ctr;
+// Frequency iterator at the same place
+VARDEF uint32 _cur_town_iter;
+
+VARDEF uint _cur_player_tick_index;
+VARDEF uint _next_competitor_start;
+
+// Determines how often to run the tree loop
+VARDEF byte _trees_tick_ctr;
+
+// Keep track of current game position
+VARDEF int _saved_scrollpos_x;
+VARDEF int _saved_scrollpos_y;
+VARDEF byte _saved_scrollpos_zoom;
+
+// ********* END OF SAVE REGION
+
+typedef struct Patches {
+ bool modified_catchment; // different-size catchment areas
+ bool vehicle_speed; // show vehicle speed
+ bool build_on_slopes; // allow building on slopes
+ bool mammoth_trains; // allow very long trains
+ bool join_stations; // allow joining of train stations
+ bool full_load_any; // new full load calculation, any cargo must be full
+ bool improved_load; // improved loading algorithm
+ bool gradual_loading; // load vehicles gradually
+ byte station_spread; // amount a station may spread
+ bool inflation; // disable inflation
+ bool selectgoods; // only send the goods to station if a train has been there
+ bool longbridges; // allow 100 tile long bridges
+ bool gotodepot; // allow goto depot in orders
+ bool build_rawmaterial_ind; // allow building raw material industries
+ bool multiple_industry_per_town; // allow many industries of the same type per town
+ bool same_industry_close; // allow same type industries to be built close to each other
+ bool lost_train_warn; // if a train can't find its destination, show a warning
+ uint8 order_review_system;
+ bool train_income_warn; // if train is generating little income, show a warning
+ bool status_long_date; // always show long date in status bar
+ bool signal_side; // show signals on right side
+ bool show_finances; // show finances at end of year
+ bool new_nonstop; // ttdpatch compatible nonstop handling
+ bool roadveh_queue; // buggy road vehicle queueing
+ bool autoscroll; // scroll when moving mouse to the edge.
+ byte errmsg_duration; // duration of error message
+ byte land_generator; // the landscape generator
+ byte oil_refinery_limit; // distance oil refineries allowed from map edge
+ byte snow_line_height; // a number 0-15 that configured snow line height
+ byte tgen_smoothness; // how rough is the terrain from 0-3
+ uint32 generation_seed; // noise seed for world generation
+ byte tree_placer; // the tree placer algorithm
+ byte heightmap_rotation; // rotation director for the heightmap
+ byte se_flat_world_height; // land height a flat world gets in SE
+ bool bribe; // enable bribing the local authority
+ bool nonuniform_stations; // allow nonuniform train stations
+ bool always_small_airport; // always allow small airports
+ bool realistic_acceleration; // realistic acceleration for trains
+ bool wagon_speed_limits; // enable wagon speed limits
+ bool forbid_90_deg; // forbid trains to make 90 deg turns
+ bool invisible_trees; // don't show trees when buildings are transparent
+ bool no_servicing_if_no_breakdowns; // dont send vehicles to depot when breakdowns are disabled
+ bool link_terraform_toolbar; // display terraform toolbar when displaying rail, road, water and airport toolbars
+ bool reverse_scroll; // Right-Click-Scrolling scrolls in the opposite direction
+ bool disable_elrails; // when true, the elrails are disabled
+ bool measure_tooltip; // Show a permanent tooltip when dragging tools
+ byte liveries; // Options for displaying company liveries, 0=none, 1=self, 2=all
+ bool prefer_teamchat; // Choose the chat message target with <ENTER>, true=all players, false=your team
+
+ uint8 toolbar_pos; // position of toolbars, 0=left, 1=center, 2=right
+ uint8 window_snap_radius; // Windows snap at each other if closer than this
+
+ UnitID max_trains; // max trains in game per player (these are 16bit because the unitnumber field can't hold more)
+ UnitID max_roadveh; // max trucks in game per player
+ UnitID max_aircraft; // max planes in game per player
+ UnitID max_ships; // max ships in game per player
+
+ bool servint_ispercent; // service intervals are in percents
+ uint16 servint_trains; // service interval for trains
+ uint16 servint_roadveh; // service interval for road vehicles
+ uint16 servint_aircraft; // service interval for aircraft
+ uint16 servint_ships; // service interval for ships
+
+ bool autorenew;
+ int16 autorenew_months;
+ int32 autorenew_money;
+
+ byte pf_maxdepth; // maximum recursion depth when searching for a train route for new pathfinder
+ uint16 pf_maxlength; // maximum length when searching for a train route for new pathfinder
+
+
+ bool bridge_pillars; // show bridge pillars for high bridges
+
+ bool ai_disable_veh_train; // disable types for AI
+ bool ai_disable_veh_roadveh; // disable types for AI
+ bool ai_disable_veh_aircraft; // disable types for AI
+ bool ai_disable_veh_ship; // disable types for AI
+ Year starting_year; // starting date
+ Year ending_year; // end of the game (just show highscore)
+ Year colored_news_year; // when does newspaper become colored?
+
+ bool keep_all_autosave; // name the autosave in a different way.
+ bool autosave_on_exit; // save an autosave when you quit the game, but do not ask "Do you really want to quit?"
+ byte max_num_autosaves; // controls how many autosavegames are made before the game starts to overwrite (names them 0 to max_num_autosaves - 1)
+ bool extra_dynamite; // extra dynamite
+
+ bool never_expire_vehicles; // never expire vehicles
+ byte extend_vehicle_life; // extend vehicle life by this many years
+
+ bool auto_euro; // automatically switch to euro in 2002
+ bool serviceathelipad; // service helicopters at helipads automatically (no need to send to depot)
+ bool smooth_economy; // smooth economy
+ bool allow_shares; // allow the buying/selling of shares
+ byte dist_local_authority; // distance for town local authority, default 20
+
+ byte wait_oneway_signal; // waitingtime in days before a oneway signal
+ byte wait_twoway_signal; // waitingtime in days before a twoway signal
+
+ uint8 map_x; // Size of map
+ uint8 map_y;
+
+ byte drag_signals_density; // many signals density
+ bool ainew_active; // Is the new AI active?
+ bool ai_in_multiplayer; // Do we allow AIs in multiplayer
+
+ /*
+ * New Path Finding
+ */
+ bool new_pathfinding_all; /* Use the newest pathfinding algorithm for all */
+
+ /**
+ * The maximum amount of search nodes a single NPF run should take. This
+ * limit should make sure performance stays at acceptable levels at the cost
+ * of not being perfect anymore. This will probably be fixed in a more
+ * sophisticated way sometime soon
+ */
+ uint32 npf_max_search_nodes;
+
+ uint32 npf_rail_firstred_penalty; /* The penalty for when the first signal is red (and it is not an exit or combo signal) */
+ uint32 npf_rail_firstred_exit_penalty; /* The penalty for when the first signal is red (and it is an exit or combo signal) */
+ uint32 npf_rail_lastred_penalty; /* The penalty for when the last signal is red */
+ uint32 npf_rail_station_penalty; /* The penalty for station tiles */
+ uint32 npf_rail_slope_penalty; /* The penalty for sloping upwards */
+ uint32 npf_rail_curve_penalty; /* The penalty for curves */
+ uint32 npf_rail_depot_reverse_penalty; /* The penalty for reversing in depots */
+ uint32 npf_buoy_penalty; /* The penalty for going over (through) a buoy */
+ uint32 npf_water_curve_penalty; /* The penalty for curves */
+ uint32 npf_road_curve_penalty; /* The penalty for curves */
+ uint32 npf_crossing_penalty; /* The penalty for level crossings */
+
+ bool population_in_label; // Show the population of a town in his label?
+
+ uint8 freight_trains; ///< Value to multiply the weight of cargo by
+
+ /** YAPF settings */
+ YapfSettings yapf;
+
+} Patches;
+
+VARDEF Patches _patches;
+
+
+typedef struct Cheat {
+ bool been_used; // has this cheat been used before?
+ bool value; // tells if the bool cheat is active or not
+} Cheat;
+
+
+// WARNING! Do _not_ remove entries in Cheats struct or change the order
+// of the existing ones! Would break downward compatibility.
+// Only add new entries at the end of the struct!
+
+typedef struct Cheats {
+ Cheat magic_bulldozer; // dynamite industries, unmovables
+ Cheat switch_player; // change to another player
+ Cheat money; // get rich
+ Cheat crossing_tunnels; // allow tunnels that cross each other
+ Cheat build_in_pause; // build while in pause mode
+ Cheat no_jetcrash; // no jet will crash on small airports anymore
+ Cheat switch_climate;
+ Cheat change_date; // changes date ingame
+ Cheat setup_prod; // setup raw-material production in game
+ Cheat dummy; // empty cheat (enable running el-engines on normal rail)
+} Cheats;
+
+VARDEF Cheats _cheats;
+
+typedef struct Paths {
+ char *personal_dir; // includes cfg file and save folder
+ char *game_data_dir; // includes data, gm, lang
+ char *data_dir;
+ char *gm_dir;
+ char *lang_dir;
+ char *save_dir;
+ char *autosave_dir;
+ char *scenario_dir;
+ char *heightmap_dir;
+ char *second_data_dir;
+} Paths;
+
+VARDEF Paths _paths;
+
+// NOSAVE: Used in palette animations only, not really important.
+VARDEF int _timer_counter;
+
+
+VARDEF uint32 _frame_counter;
+
+VARDEF bool _is_old_ai_player; // current player is an oldAI player? (enables a lot of cheats..)
+
+VARDEF bool _do_autosave;
+VARDEF int _autosave_ctr;
+
+VARDEF byte _display_opt;
+VARDEF byte _pause;
+VARDEF int _caret_timer;
+VARDEF uint32 _news_display_opt;
+VARDEF bool _news_ticker_sound;
+VARDEF byte _game_mode;
+
+VARDEF StringID _error_message;
+VARDEF int32 _additional_cash_required;
+
+VARDEF uint32 _decode_parameters[20];
+
+VARDEF bool _ctrl_pressed; // Is Ctrl pressed?
+VARDEF bool _shift_pressed; // Is Shift pressed?
+VARDEF byte _dirkeys; // 1 = left, 2 = up, 4 = right, 8 = down
+
+VARDEF bool _fullscreen;
+VARDEF bool _fast_forward;
+VARDEF bool _rightclick_emulate;
+
+// IN/OUT parameters to commands
+VARDEF byte _yearly_expenses_type;
+VARDEF TileIndex _terraform_err_tile;
+VARDEF TileIndex _build_tunnel_endtile;
+VARDEF bool _generating_world;
+
+// Deals with the type of the savegame, independent of extension
+typedef struct {
+ int mode; // savegame/scenario type (old, new)
+ char name[MAX_PATH]; // name
+ char title[255]; // internal name of the game
+} SmallFiosItem;
+
+// Used when switching from the intro menu.
+VARDEF byte _switch_mode;
+VARDEF StringID _switch_mode_errorstr;
+VARDEF bool _exit_game;
+VARDEF SmallFiosItem _file_to_saveload;
+
+
+
+VARDEF Vehicle *_place_clicked_vehicle;
+
+VARDEF char _ini_videodriver[16], _ini_musicdriver[16], _ini_sounddriver[16];
+
+// Used for dynamic language support
+typedef struct {
+ int num; // number of languages
+ int curr; // currently selected language index
+ char curr_file[MAX_LANG]; // currently selected language file
+ StringID dropdown[MAX_LANG + 1]; // used in settings dialog
+ struct {
+ char *name;
+ char *file;
+ } ent[MAX_LANG];
+} DynamicLanguages;
+
+VARDEF DynamicLanguages _dynlang;
+
+VARDEF int _num_resolutions;
+VARDEF uint16 _resolutions[32][2];
+VARDEF uint16 _cur_resolution[2];
+
+VARDEF char _savegame_format[8];
+
+VARDEF char *_config_file;
+VARDEF char *_highscore_file;
+VARDEF char *_log_file;
+
+// NOSAVE: These can be recalculated from InitializeLandscapeVariables
+typedef struct {
+ StringID names_s[NUM_CARGO];
+ StringID names_long[NUM_CARGO];
+ StringID names_short[NUM_CARGO];
+ byte weights[NUM_CARGO];
+ SpriteID sprites[NUM_CARGO];
+ byte transit_days_1[NUM_CARGO];
+ byte transit_days_2[NUM_CARGO];
+} CargoConst;
+
+VARDEF CargoConst _cargoc;
+
+
+static inline void SetDParamX(uint32 *s, uint n, uint32 v)
+{
+ s[n] = v;
+}
+
+static inline uint32 GetDParamX(const uint32 *s, uint n)
+{
+ return s[n];
+}
+
+static inline void SetDParam(uint n, uint32 v)
+{
+ assert(n < lengthof(_decode_parameters));
+ _decode_parameters[n] = v;
+}
+
+static inline void SetDParam64(uint n, uint64 v)
+{
+ assert(n + 1 < lengthof(_decode_parameters));
+ _decode_parameters[n + 0] = v & 0xffffffff;
+ _decode_parameters[n + 1] = v >> 32;
+}
+
+static inline uint32 GetDParam(uint n)
+{
+ assert(n < lengthof(_decode_parameters));
+ return _decode_parameters[n];
+}
+
+// Used to bind a C string name to a dparam number.
+// NOTE: This has a short lifetime. You can't
+// use this string much later or it will be gone.
+void SetDParamStr(uint n, const char *str);
+
+// This function takes a C-string and allocates a temporary string ID.
+// The duration of the bound string is valid only until the next acll to GetString,
+// so be careful.
+StringID BindCString(const char *str);
+
+
+#define COPY_IN_DPARAM(offs,src,num) memcpy(_decode_parameters + offs, src, sizeof(uint32) * (num))
+#define COPY_OUT_DPARAM(dst,offs,num) memcpy(dst,_decode_parameters + offs, sizeof(uint32) * (num))
+
+
+#define SET_EXPENSES_TYPE(x) _yearly_expenses_type = x;
+
+/* landscape.c */
+extern const byte _tileh_to_sprite[32];
+extern const byte _inclined_tileh[16];
+
+extern const TileTypeProcs * const _tile_type_procs[16];
+
+/* misc */
+VARDEF char _screenshot_name[128];
+VARDEF byte _vehicle_design_names;
+
+/* Forking stuff */
+VARDEF bool _dedicated_forks;
+
+#endif /* VARIABLES_H */
diff --git a/src/vehicle.c b/src/vehicle.c
new file mode 100644
index 000000000..c2a2175f8
--- /dev/null
+++ b/src/vehicle.c
@@ -0,0 +1,3235 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "road_map.h"
+#include "roadveh.h"
+#include "ship.h"
+#include "spritecache.h"
+#include "table/sprites.h"
+#include "table/strings.h"
+#include "functions.h"
+#include "map.h"
+#include "tile.h"
+#include "vehicle.h"
+#include "gfx.h"
+#include "viewport.h"
+#include "news.h"
+#include "command.h"
+#include "saveload.h"
+#include "player.h"
+#include "engine.h"
+#include "sound.h"
+#include "debug.h"
+#include "vehicle_gui.h"
+#include "depot.h"
+#include "station.h"
+#include "rail.h"
+#include "train.h"
+#include "aircraft.h"
+#include "industry_map.h"
+#include "station_map.h"
+#include "water_map.h"
+#include "network/network.h"
+#include "yapf/yapf.h"
+#include "date.h"
+#include "newgrf_engine.h"
+#include "newgrf_sound.h"
+
+#define INVALID_COORD (-0x8000)
+#define GEN_HASH(x, y) ((GB((y), 6, 6) << 6) + GB((x), 7, 6))
+
+/*
+ * These command macros are used to call vehicle type specific commands with non type specific commands
+ * it should be used like: DoCommandP(x, y, p1, p2, flags, CMD_STARTSTOP_VEH(v->type))
+ * that line will start/stop a vehicle nomatter what type it is
+ * VEH_Train is used as an offset because the vehicle type values doesn't start with 0
+ */
+
+#define CMD_BUILD_VEH(x) _veh_build_proc_table[ x - VEH_Train]
+#define CMD_SELL_VEH(x) _veh_sell_proc_table [ x - VEH_Train]
+#define CMD_REFIT_VEH(x) _veh_refit_proc_table[ x - VEH_Train]
+
+static const uint32 _veh_build_proc_table[] = {
+ CMD_BUILD_RAIL_VEHICLE,
+ CMD_BUILD_ROAD_VEH,
+ CMD_BUILD_SHIP,
+ CMD_BUILD_AIRCRAFT,
+};
+static const uint32 _veh_sell_proc_table[] = {
+ CMD_SELL_RAIL_WAGON,
+ CMD_SELL_ROAD_VEH,
+ CMD_SELL_SHIP,
+ CMD_SELL_AIRCRAFT,
+};
+
+static const uint32 _veh_refit_proc_table[] = {
+ CMD_REFIT_RAIL_VEHICLE,
+ CMD_REFIT_ROAD_VEH,
+ CMD_REFIT_SHIP,
+ CMD_REFIT_AIRCRAFT,
+};
+
+const uint32 _send_to_depot_proc_table[] = {
+ CMD_SEND_TRAIN_TO_DEPOT,
+ CMD_SEND_ROADVEH_TO_DEPOT,
+ CMD_SEND_SHIP_TO_DEPOT,
+ CMD_SEND_AIRCRAFT_TO_HANGAR,
+};
+
+
+enum {
+ BLOCKS_FOR_SPECIAL_VEHICLES = 2, ///< Blocks needed for special vehicles
+};
+
+/**
+ * Called if a new block is added to the vehicle-pool
+ */
+static void VehiclePoolNewBlock(uint start_item)
+{
+ Vehicle *v;
+
+ /* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
+ * TODO - This is just a temporary stage, this will be removed. */
+ for (v = GetVehicle(start_item); v != NULL; v = (v->index + 1U < GetVehiclePoolSize()) ? GetVehicle(v->index + 1) : NULL) v->index = start_item++;
+}
+
+/* Initialize the vehicle-pool */
+DEFINE_OLD_POOL(Vehicle, Vehicle, VehiclePoolNewBlock, NULL)
+
+void VehicleServiceInDepot(Vehicle *v)
+{
+ v->date_of_last_service = _date;
+ v->breakdowns_since_last_service = 0;
+ v->reliability = GetEngine(v->engine_type)->reliability;
+ InvalidateWindow(WC_VEHICLE_DETAILS, v->index); // ensure that last service date and reliability are updated
+}
+
+bool VehicleNeedsService(const Vehicle *v)
+{
+ if (v->vehstatus & VS_CRASHED)
+ return false; /* Crashed vehicles don't need service anymore */
+
+ if (_patches.no_servicing_if_no_breakdowns && _opt.diff.vehicle_breakdowns == 0) {
+ return EngineHasReplacementForPlayer(GetPlayer(v->owner), v->engine_type); /* Vehicles set for autoreplacing needs to go to a depot even if breakdowns are turned off */
+ }
+
+ return _patches.servint_ispercent ?
+ (v->reliability < GetEngine(v->engine_type)->reliability * (100 - v->service_interval) / 100) :
+ (v->date_of_last_service + v->service_interval < _date);
+}
+
+StringID VehicleInTheWayErrMsg(const Vehicle* v)
+{
+ switch (v->type) {
+ case VEH_Train: return STR_8803_TRAIN_IN_THE_WAY;
+ case VEH_Road: return STR_9000_ROAD_VEHICLE_IN_THE_WAY;
+ case VEH_Aircraft: return STR_A015_AIRCRAFT_IN_THE_WAY;
+ default: return STR_980E_SHIP_IN_THE_WAY;
+ }
+}
+
+static void *EnsureNoVehicleProc(Vehicle *v, void *data)
+{
+ if (v->tile != *(const TileIndex*)data || v->type == VEH_Disaster)
+ return NULL;
+
+ _error_message = VehicleInTheWayErrMsg(v);
+ return v;
+}
+
+bool EnsureNoVehicle(TileIndex tile)
+{
+ return VehicleFromPos(tile, &tile, EnsureNoVehicleProc) == NULL;
+}
+
+static void *EnsureNoVehicleProcZ(Vehicle *v, void *data)
+{
+ const TileInfo *ti = data;
+
+ if (v->tile != ti->tile || v->type == VEH_Disaster) return NULL;
+ if (v->z_pos > ti->z) return NULL;
+
+ _error_message = VehicleInTheWayErrMsg(v);
+ return v;
+}
+
+
+bool EnsureNoVehicleOnGround(TileIndex tile)
+{
+ TileInfo ti;
+
+ ti.tile = tile;
+ ti.z = GetTileMaxZ(tile);
+ return VehicleFromPos(tile, &ti, EnsureNoVehicleProcZ) == NULL;
+}
+
+Vehicle *FindVehicleOnTileZ(TileIndex tile, byte z)
+{
+ TileInfo ti;
+
+ ti.tile = tile;
+ ti.z = z;
+
+ return VehicleFromPos(tile, &ti, EnsureNoVehicleProcZ);
+}
+
+Vehicle *FindVehicleBetween(TileIndex from, TileIndex to, byte z)
+{
+ int x1 = TileX(from);
+ int y1 = TileY(from);
+ int x2 = TileX(to);
+ int y2 = TileY(to);
+ Vehicle *veh;
+
+ /* Make sure x1 < x2 or y1 < y2 */
+ if (x1 > x2 || y1 > y2) {
+ intswap(x1,x2);
+ intswap(y1,y2);
+ }
+ FOR_ALL_VEHICLES(veh) {
+ if ((veh->type == VEH_Train || veh->type == VEH_Road) && (z==0xFF || veh->z_pos == z)) {
+ if ((veh->x_pos>>4) >= x1 && (veh->x_pos>>4) <= x2 &&
+ (veh->y_pos>>4) >= y1 && (veh->y_pos>>4) <= y2) {
+ return veh;
+ }
+ }
+ }
+ return NULL;
+}
+
+
+static void UpdateVehiclePosHash(Vehicle* v, int x, int y);
+
+void VehiclePositionChanged(Vehicle *v)
+{
+ int img = v->cur_image;
+ Point pt = RemapCoords(v->x_pos + v->x_offs, v->y_pos + v->y_offs, v->z_pos);
+ const Sprite* spr = GetSprite(img);
+
+ pt.x += spr->x_offs;
+ pt.y += spr->y_offs;
+
+ UpdateVehiclePosHash(v, pt.x, pt.y);
+
+ v->left_coord = pt.x;
+ v->top_coord = pt.y;
+ v->right_coord = pt.x + spr->width + 2;
+ v->bottom_coord = pt.y + spr->height + 2;
+}
+
+// Called after load to update coordinates
+void AfterLoadVehicles(void)
+{
+ Vehicle *v;
+
+ FOR_ALL_VEHICLES(v) {
+ v->first = NULL;
+ if (v->type == VEH_Train) v->u.rail.first_engine = INVALID_ENGINE;
+ }
+
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == VEH_Train && (IsFrontEngine(v) || IsFreeWagon(v)))
+ TrainConsistChanged(v);
+ }
+
+ FOR_ALL_VEHICLES(v) {
+ switch (v->type) {
+ case VEH_Train: v->cur_image = GetTrainImage(v, v->direction); break;
+ case VEH_Road: v->cur_image = GetRoadVehImage(v, v->direction); break;
+ case VEH_Ship: v->cur_image = GetShipImage(v, v->direction); break;
+ case VEH_Aircraft:
+ if (v->subtype == 0 || v->subtype == 2) {
+ v->cur_image = GetAircraftImage(v, v->direction);
+ if (v->next != NULL) v->next->cur_image = v->cur_image;
+ }
+ break;
+ default: break;
+ }
+
+ v->left_coord = INVALID_COORD;
+ VehiclePositionChanged(v);
+ }
+}
+
+static Vehicle *InitializeVehicle(Vehicle *v)
+{
+ VehicleID index = v->index;
+ memset(v, 0, sizeof(Vehicle));
+ v->index = index;
+
+ assert(v->orders == NULL);
+
+ v->left_coord = INVALID_COORD;
+ v->first = NULL;
+ v->next = NULL;
+ v->next_hash = INVALID_VEHICLE;
+ v->string_id = 0;
+ v->next_shared = NULL;
+ v->prev_shared = NULL;
+ v->depot_list = NULL;
+ v->random_bits = 0;
+ return v;
+}
+
+/**
+ * Get a value for a vehicle's random_bits.
+ * @return A random value from 0 to 255.
+ */
+byte VehicleRandomBits(void)
+{
+ return GB(Random(), 0, 8);
+}
+
+Vehicle *ForceAllocateSpecialVehicle(void)
+{
+ /* This stays a strange story.. there should always be room for special
+ * vehicles (special effects all over the map), but with 65k of vehicles
+ * is this realistic to double-check for that? For now we just reserve
+ * BLOCKS_FOR_SPECIAL_VEHICLES times block_size vehicles that may only
+ * be used for special vehicles.. should work nicely :) */
+
+ Vehicle *v;
+
+ /* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
+ * TODO - This is just a temporary stage, this will be removed. */
+ for (v = GetVehicle(0); v != NULL; v = (v->index + 1U < GetVehiclePoolSize()) ? GetVehicle(v->index + 1) : NULL) {
+ /* No more room for the special vehicles, return NULL */
+ if (v->index >= (1 << Vehicle_POOL_BLOCK_SIZE_BITS) * BLOCKS_FOR_SPECIAL_VEHICLES)
+ return NULL;
+
+ if (!IsValidVehicle(v)) return InitializeVehicle(v);
+ }
+
+ return NULL;
+}
+
+/*
+ * finds a free vehicle in the memory or allocates a new one
+ * returns a pointer to the first free vehicle or NULL if all vehicles are in use
+ * *skip_vehicles is an offset to where in the array we should begin looking
+ * this is to avoid looping though the same vehicles more than once after we learned that they are not free
+ * this feature is used by AllocateVehicles() since it need to allocate more than one and when
+ * another block is added to _Vehicle_pool, since we only do that when we know it's already full
+ */
+static Vehicle *AllocateSingleVehicle(VehicleID *skip_vehicles)
+{
+ /* See note by ForceAllocateSpecialVehicle() why we skip the
+ * first blocks */
+ Vehicle *v;
+ const int offset = (1 << Vehicle_POOL_BLOCK_SIZE_BITS) * BLOCKS_FOR_SPECIAL_VEHICLES;
+
+ /* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
+ * TODO - This is just a temporary stage, this will be removed. */
+ if (*skip_vehicles < (_Vehicle_pool.total_items - offset)) { // make sure the offset in the array is not larger than the array itself
+ for (v = GetVehicle(offset + *skip_vehicles); v != NULL; v = (v->index + 1U < GetVehiclePoolSize()) ? GetVehicle(v->index + 1) : NULL) {
+ (*skip_vehicles)++;
+ if (!IsValidVehicle(v)) return InitializeVehicle(v);
+ }
+ }
+
+ /* Check if we can add a block to the pool */
+ if (AddBlockToPool(&_Vehicle_pool))
+ return AllocateSingleVehicle(skip_vehicles);
+
+ return NULL;
+}
+
+
+Vehicle *AllocateVehicle(void)
+{
+ VehicleID counter = 0;
+ return AllocateSingleVehicle(&counter);
+}
+
+
+/** Allocates a lot of vehicles and frees them again
+ * @param vl pointer to an array of vehicles to get allocated. Can be NULL if the vehicles aren't needed (makes it test only)
+ * @param num number of vehicles to allocate room for
+ * @return true if there is room to allocate all the vehicles
+ */
+bool AllocateVehicles(Vehicle **vl, int num)
+{
+ int i;
+ Vehicle *v;
+ VehicleID counter = 0;
+
+ for (i = 0; i != num; i++) {
+ v = AllocateSingleVehicle(&counter);
+ if (v == NULL) {
+ return false;
+ }
+ if (vl != NULL) {
+ vl[i] = v;
+ }
+ }
+
+ return true;
+}
+
+
+VehicleID _vehicle_position_hash[0x1000];
+
+void *VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
+{
+ Point pt = RemapCoords(TileX(tile) * TILE_SIZE, TileY(tile) * TILE_SIZE, 0);
+
+ // The hash area to scan
+ const int xl = GB(pt.x - 174, 7, 6);
+ const int xu = GB(pt.x + 104, 7, 6);
+ const int yl = GB(pt.y - 294, 6, 6) << 6;
+ const int yu = GB(pt.y + 56, 6, 6) << 6;
+
+ int x;
+ int y;
+
+ for (y = yl;; y = (y + (1 << 6)) & (0x3F << 6)) {
+ for (x = xl;; x = (x + 1) & 0x3F) {
+ VehicleID veh = _vehicle_position_hash[(x + y) & 0xFFFF];
+
+ while (veh != INVALID_VEHICLE) {
+ Vehicle *v = GetVehicle(veh);
+ void* a = proc(v, data);
+
+ if (a != NULL) return a;
+ veh = v->next_hash;
+ }
+
+ if (x == xu) break;
+ }
+
+ if (y == yu) break;
+ }
+ return NULL;
+}
+
+
+static void UpdateVehiclePosHash(Vehicle* v, int x, int y)
+{
+ VehicleID *old_hash, *new_hash;
+ int old_x = v->left_coord;
+ int old_y = v->top_coord;
+ Vehicle *u;
+
+ new_hash = (x == INVALID_COORD) ? NULL : &_vehicle_position_hash[GEN_HASH(x,y)];
+ old_hash = (old_x == INVALID_COORD) ? NULL : &_vehicle_position_hash[GEN_HASH(old_x, old_y)];
+
+ if (old_hash == new_hash) return;
+
+ /* remove from hash table? */
+ if (old_hash != NULL) {
+ Vehicle *last = NULL;
+ VehicleID idx = *old_hash;
+ while ((u = GetVehicle(idx)) != v) {
+ idx = u->next_hash;
+ assert(idx != INVALID_VEHICLE);
+ last = u;
+ }
+
+ if (last == NULL) {
+ *old_hash = v->next_hash;
+ } else {
+ last->next_hash = v->next_hash;
+ }
+ }
+
+ /* insert into hash table? */
+ if (new_hash != NULL) {
+ v->next_hash = *new_hash;
+ *new_hash = v->index;
+ }
+}
+
+void ResetVehiclePosHash(void)
+{
+ uint i;
+ for (i = 0; i < lengthof(_vehicle_position_hash); i++) {
+ _vehicle_position_hash[i] = INVALID_VEHICLE;
+ }
+}
+
+void InitializeVehicles(void)
+{
+ uint i;
+
+ /* Clean the vehicle pool, and reserve enough blocks
+ * for the special vehicles, plus one for all the other
+ * vehicles (which is increased on-the-fly) */
+ CleanPool(&_Vehicle_pool);
+ AddBlockToPool(&_Vehicle_pool);
+ for (i = 0; i < BLOCKS_FOR_SPECIAL_VEHICLES; i++) {
+ AddBlockToPool(&_Vehicle_pool);
+ }
+
+ ResetVehiclePosHash();
+}
+
+Vehicle *GetLastVehicleInChain(Vehicle *v)
+{
+ while (v->next != NULL) v = v->next;
+ return v;
+}
+
+/** Finds the previous vehicle in a chain, by a brute force search.
+ * This old function is REALLY slow because it searches through all vehicles to
+ * find the previous vehicle, but if v->first has not been set, then this function
+ * will need to be used to find the previous one. This function should never be
+ * called by anything but GetFirstVehicleInChain
+ */
+static Vehicle *GetPrevVehicleInChain_bruteforce(const Vehicle *v)
+{
+ Vehicle *u;
+
+ FOR_ALL_VEHICLES(u) if (u->type == VEH_Train && u->next == v) return u;
+
+ return NULL;
+}
+
+/** Find the previous vehicle in a chain, by using the v->first cache.
+ * While this function is fast, it cannot be used in the GetFirstVehicleInChain
+ * function, otherwise you'll end up in an infinite loop call
+ */
+Vehicle *GetPrevVehicleInChain(const Vehicle *v)
+{
+ Vehicle *u;
+ assert(v != NULL);
+
+ u = GetFirstVehicleInChain(v);
+
+ // Check to see if this is the first
+ if (v == u) return NULL;
+
+ for (; u->next != v; u = u->next) assert(u->next != NULL);
+
+ return u;
+}
+
+/** Finds the first vehicle in a chain.
+ * This function reads out the v->first cache. Should the cache be dirty,
+ * it determines the first vehicle in a chain, and updates the cache.
+ */
+Vehicle *GetFirstVehicleInChain(const Vehicle *v)
+{
+ Vehicle* u;
+
+ assert(v != NULL);
+
+ if (v->first != NULL) {
+ if (IsFrontEngine(v->first) || IsFreeWagon(v->first)) return v->first;
+
+ DEBUG(misc, 0, "v->first cache faulty. We shouldn't be here, rebuilding cache!");
+ }
+
+ /* It is the fact (currently) that newly built vehicles do not have
+ * their ->first pointer set. When this is the case, go up to the
+ * first engine and set the pointers correctly. Also the first pointer
+ * is not saved in a savegame, so this has to be fixed up after loading */
+
+ /* Find the 'locomotive' or the first wagon in a chain */
+ while ((u = GetPrevVehicleInChain_bruteforce(v)) != NULL) v = u;
+
+ /* Set the first pointer of all vehicles in that chain to the first wagon */
+ if (IsFrontEngine(v) || IsFreeWagon(v))
+ for (u = (Vehicle *)v; u != NULL; u = u->next) u->first = (Vehicle *)v;
+
+ return (Vehicle*)v;
+}
+
+uint CountVehiclesInChain(const Vehicle* v)
+{
+ uint count = 0;
+ do count++; while ((v = v->next) != NULL);
+ return count;
+}
+
+/** Check if a vehicle is counted in num_engines in each player struct
+ * @param *v Vehicle to test
+ * @return true if the vehicle is counted in num_engines
+ */
+bool IsEngineCountable(const Vehicle *v)
+{
+ switch (v->type) {
+ case VEH_Aircraft: return (v->subtype <= 2); // don't count plane shadows and helicopter rotors
+ case VEH_Train:
+ return !IsArticulatedPart(v) && // tenders and other articulated parts
+ (!IsMultiheaded(v) || IsTrainEngine(v)); // rear parts of multiheaded engines
+ case VEH_Road:
+ case VEH_Ship:
+ return true;
+ default: return false; // Only count player buildable vehicles
+ }
+}
+
+void DestroyVehicle(Vehicle *v)
+{
+ if (IsEngineCountable(v)) GetPlayer(v->owner)->num_engines[v->engine_type]--;
+
+ DeleteVehicleNews(v->index, INVALID_STRING_ID);
+
+ DeleteName(v->string_id);
+ if (v->type == VEH_Road) ClearSlot(v);
+
+ if (v->type != VEH_Train || (v->type == VEH_Train && (IsFrontEngine(v) || IsFreeWagon(v)))) {
+ InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
+ }
+
+ UpdateVehiclePosHash(v, INVALID_COORD, 0);
+ v->next_hash = INVALID_VEHICLE;
+ if (v->orders != NULL) DeleteVehicleOrders(v);
+
+ /* Now remove any artic part. This will trigger an other
+ * destroy vehicle, which on his turn can remove any
+ * other artic parts. */
+ if (EngineHasArticPart(v)) DeleteVehicle(v->next);
+}
+
+void DeleteVehicleChain(Vehicle *v)
+{
+ do {
+ Vehicle *u = v;
+ v = GetNextVehicle(v);
+ DeleteVehicle(u);
+ } while (v != NULL);
+}
+
+
+void Aircraft_Tick(Vehicle *v);
+void RoadVeh_Tick(Vehicle *v);
+void Ship_Tick(Vehicle *v);
+void Train_Tick(Vehicle *v);
+static void EffectVehicle_Tick(Vehicle *v);
+void DisasterVehicle_Tick(Vehicle *v);
+static int32 MaybeReplaceVehicle(Vehicle *v, bool check, bool display_costs);
+
+// head of the linked list to tell what vehicles that visited a depot in a tick
+static Vehicle* _first_veh_in_depot_list;
+
+/** Adds a vehicle to the list of vehicles, that visited a depot this tick
+ * @param *v vehicle to add
+ */
+void VehicleEnteredDepotThisTick(Vehicle *v)
+{
+ // we need to set v->leave_depot_instantly as we have no control of it's contents at this time
+ if (HASBIT(v->current_order.flags, OFB_HALT_IN_DEPOT) && !HASBIT(v->current_order.flags, OFB_PART_OF_ORDERS) && v->current_order.type == OT_GOTO_DEPOT) {
+ // we keep the vehicle in the depot since the user ordered it to stay
+ v->leave_depot_instantly = false;
+ } else {
+ // the vehicle do not plan on stopping in the depot, so we stop it to ensure that it will not reserve the path
+ // out of the depot before we might autoreplace it to a different engine. The new engine would not own the reserved path
+ // we store that we stopped the vehicle, so autoreplace can start it again
+ v->vehstatus |= VS_STOPPED;
+ v->leave_depot_instantly = true;
+ }
+
+ if (_first_veh_in_depot_list == NULL) {
+ _first_veh_in_depot_list = v;
+ } else {
+ Vehicle *w = _first_veh_in_depot_list;
+ while (w->depot_list != NULL) w = w->depot_list;
+ w->depot_list = v;
+ }
+}
+
+typedef void VehicleTickProc(Vehicle*);
+static VehicleTickProc* _vehicle_tick_procs[] = {
+ Train_Tick,
+ RoadVeh_Tick,
+ Ship_Tick,
+ Aircraft_Tick,
+ EffectVehicle_Tick,
+ DisasterVehicle_Tick,
+};
+
+void CallVehicleTicks(void)
+{
+ Vehicle *v;
+
+#ifdef ENABLE_NETWORK
+ // hotfix for desync problem:
+ // for MP games invalidate the YAPF cache every tick to keep it exactly the same on the server and all clients
+ if (_networking) {
+ YapfNotifyTrackLayoutChange(0, 0);
+ }
+#endif //ENABLE_NETWORK
+
+ _first_veh_in_depot_list = NULL; // now we are sure it's initialized at the start of each tick
+
+ FOR_ALL_VEHICLES(v) {
+ _vehicle_tick_procs[v->type - 0x10](v);
+
+ switch (v->type) {
+ case VEH_Train:
+ case VEH_Road:
+ case VEH_Aircraft:
+ case VEH_Ship:
+ if (v->type == VEH_Train && IsTrainWagon(v)) continue;
+ if (v->type == VEH_Aircraft && v->subtype > 0) continue;
+
+ v->motion_counter += (v->direction & 1) ? (v->cur_speed * 3) / 4 : v->cur_speed;
+ /* Play a running sound if the motion counter passes 256 (Do we not skip sounds?) */
+ if (GB(v->motion_counter, 0, 8) < v->cur_speed) PlayVehicleSound(v, VSE_RUNNING);
+
+ /* Play an alterate running sound every 16 ticks */
+ if (GB(v->tick_counter, 0, 4) == 0) PlayVehicleSound(v, v->cur_speed > 0 ? VSE_RUNNING_16 : VSE_STOPPED_16);
+ }
+ }
+
+ // now we handle all the vehicles that entered a depot this tick
+ v = _first_veh_in_depot_list;
+ while (v != NULL) {
+ Vehicle *w = v->depot_list;
+ v->depot_list = NULL; // it should always be NULL at the end of each tick
+ MaybeReplaceVehicle(v, false, true);
+ v = w;
+ }
+}
+
+static bool CanFillVehicle_FullLoadAny(Vehicle *v)
+{
+ uint32 full = 0, not_full = 0;
+ bool keep_loading = false;
+ const GoodsEntry *ge = GetStation(v->last_station_visited)->goods;
+
+ //special handling of aircraft
+
+ //if the aircraft carries passengers and is NOT full, then
+ //continue loading, no matter how much mail is in
+ if (v->type == VEH_Aircraft &&
+ v->cargo_type == CT_PASSENGERS &&
+ v->cargo_cap != v->cargo_count) {
+ return true;
+ }
+
+ // patch should return "true" to continue loading, i.e. when there is no cargo type that is fully loaded.
+ do {
+ //Should never happen, but just in case future additions change this
+ assert(v->cargo_type<32);
+
+ if (v->cargo_cap != 0) {
+ uint32 mask = 1 << v->cargo_type;
+
+ if (v->cargo_cap == v->cargo_count) {
+ full |= mask;
+ } else if (GB(ge[v->cargo_type].waiting_acceptance, 0, 12) > 0 ||
+ (HASBIT(v->load_status, LS_CARGO_UNLOADING) && (ge[v->cargo_type].waiting_acceptance & 0x8000))) {
+ /* If there is any cargo waiting, or this vehicle is still unloading
+ * and the station accepts the cargo, don't leave the station. */
+ keep_loading = true;
+ } else {
+ not_full |= mask;
+ }
+ }
+ } while ((v = v->next) != NULL);
+
+ // continue loading if there is a non full cargo type and no cargo type that is full
+ return keep_loading || (not_full && (full & ~not_full) == 0);
+}
+
+bool CanFillVehicle(Vehicle *v)
+{
+ TileIndex tile = v->tile;
+
+ if (IsTileType(tile, MP_STATION) ||
+ (v->type == VEH_Ship && (
+ IsTileType(TILE_ADDXY(tile, 1, 0), MP_STATION) ||
+ IsTileType(TILE_ADDXY(tile, -1, 0), MP_STATION) ||
+ IsTileType(TILE_ADDXY(tile, 0, 1), MP_STATION) ||
+ IsTileType(TILE_ADDXY(tile, 0, -1), MP_STATION) ||
+ IsTileType(TILE_ADDXY(tile, -2, 0), MP_STATION)
+ ))) {
+
+ // If patch is active, use alternative CanFillVehicle-function
+ if (_patches.full_load_any && v->current_order.flags & OF_FULL_LOAD) return CanFillVehicle_FullLoadAny(v);
+
+ do {
+ if (v->cargo_count != v->cargo_cap) return true;
+ } while ((v = v->next) != NULL);
+ }
+ return false;
+}
+
+/** Check if a given engine type can be refitted to a given cargo
+ * @param engine_type Engine type to check
+ * @param cid_to check refit to this cargo-type
+ * @return true if it is possible, false otherwise
+ */
+bool CanRefitTo(EngineID engine_type, CargoID cid_to)
+{
+ CargoID cid = _global_cargo_id[_opt_ptr->landscape][cid_to];
+ return HASBIT(EngInfo(engine_type)->refit_mask, cid);
+}
+
+/** Find the first cargo type that an engine can be refitted to.
+ * @param engine Which engine to find cargo for.
+ * @return A climate dependent cargo type. CT_INVALID is returned if not refittable.
+ */
+CargoID FindFirstRefittableCargo(EngineID engine_type)
+{
+ CargoID cid;
+ uint32 refit_mask = EngInfo(engine_type)->refit_mask;
+
+ if (refit_mask != 0) {
+ for (cid = CT_PASSENGERS; cid < NUM_CARGO; cid++) {
+ if (HASBIT(refit_mask, _global_cargo_id[_opt_ptr->landscape][cid])) return cid;
+ }
+ }
+
+ return CT_INVALID;
+}
+
+/** Learn the price of refitting a certain engine
+* @param engine Which engine to refit
+* @return Price for refitting
+*/
+int32 GetRefitCost(EngineID engine_type)
+{
+ int32 base_cost = 0;
+
+ switch (GetEngine(engine_type)->type) {
+ case VEH_Ship: base_cost = _price.ship_base; break;
+ case VEH_Road: base_cost = _price.roadveh_base; break;
+ case VEH_Aircraft: base_cost = _price.aircraft_base; break;
+ case VEH_Train:
+ base_cost = 2 * ((RailVehInfo(engine_type)->flags & RVI_WAGON) ?
+ _price.build_railwagon : _price.build_railvehicle);
+ break;
+ default: NOT_REACHED(); break;
+ }
+ return (EngInfo(engine_type)->refit_cost * base_cost) >> 10;
+}
+
+static void DoDrawVehicle(const Vehicle *v)
+{
+ uint32 image = v->cur_image;
+
+ if (v->vehstatus & VS_SHADOW) {
+ MAKE_TRANSPARENT(image);
+ } else if (v->vehstatus & VS_DEFPAL) {
+ image |= (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
+ }
+
+ AddSortableSpriteToDraw(image, v->x_pos + v->x_offs, v->y_pos + v->y_offs,
+ v->sprite_width, v->sprite_height, v->z_height, v->z_pos);
+}
+
+void ViewportAddVehicles(DrawPixelInfo *dpi)
+{
+ // The bounding rectangle
+ const int l = dpi->left;
+ const int r = dpi->left + dpi->width;
+ const int t = dpi->top;
+ const int b = dpi->top + dpi->height;
+
+ // The hash area to scan
+ const int xl = GB(l - 70, 7, 6);
+ const int xu = GB(r, 7, 6);
+ const int yl = GB(t - 70, 6, 6) << 6;
+ const int yu = GB(b, 6, 6) << 6;
+
+ int x;
+ int y;
+
+ for (y = yl;; y = (y + (1 << 6)) & (0x3F << 6)) {
+ for (x = xl;; x = (x + 1) & 0x3F) {
+ VehicleID veh = _vehicle_position_hash[(x + y) & 0xFFFF];
+
+ while (veh != INVALID_VEHICLE) {
+ const Vehicle* v = GetVehicle(veh);
+
+ if (!(v->vehstatus & VS_HIDDEN) &&
+ l <= v->right_coord &&
+ t <= v->bottom_coord &&
+ r >= v->left_coord &&
+ b >= v->top_coord) {
+ DoDrawVehicle(v);
+ }
+ veh = v->next_hash;
+ }
+
+ if (x == xu) break;
+ }
+
+ if (y == yu) break;
+ }
+}
+
+static void ChimneySmokeInit(Vehicle *v)
+{
+ uint32 r = Random();
+ v->cur_image = SPR_CHIMNEY_SMOKE_0 + GB(r, 0, 3);
+ v->progress = GB(r, 16, 3);
+}
+
+static void ChimneySmokeTick(Vehicle *v)
+{
+ if (v->progress > 0) {
+ v->progress--;
+ } else {
+ TileIndex tile;
+
+ BeginVehicleMove(v);
+
+ tile = TileVirtXY(v->x_pos, v->y_pos);
+ if (!IsTileType(tile, MP_INDUSTRY)) {
+ EndVehicleMove(v);
+ DeleteVehicle(v);
+ return;
+ }
+
+ if (v->cur_image != SPR_CHIMNEY_SMOKE_7) {
+ v->cur_image++;
+ } else {
+ v->cur_image = SPR_CHIMNEY_SMOKE_0;
+ }
+ v->progress = 7;
+ VehiclePositionChanged(v);
+ EndVehicleMove(v);
+ }
+}
+
+static void SteamSmokeInit(Vehicle *v)
+{
+ v->cur_image = SPR_STEAM_SMOKE_0;
+ v->progress = 12;
+}
+
+static void SteamSmokeTick(Vehicle *v)
+{
+ bool moved = false;
+
+ BeginVehicleMove(v);
+
+ v->progress++;
+
+ if ((v->progress & 7) == 0) {
+ v->z_pos++;
+ moved = true;
+ }
+
+ if ((v->progress & 0xF) == 4) {
+ if (v->cur_image != SPR_STEAM_SMOKE_4) {
+ v->cur_image++;
+ } else {
+ EndVehicleMove(v);
+ DeleteVehicle(v);
+ return;
+ }
+ moved = true;
+ }
+
+ if (moved) {
+ VehiclePositionChanged(v);
+ EndVehicleMove(v);
+ }
+}
+
+static void DieselSmokeInit(Vehicle *v)
+{
+ v->cur_image = SPR_DIESEL_SMOKE_0;
+ v->progress = 0;
+}
+
+static void DieselSmokeTick(Vehicle *v)
+{
+ v->progress++;
+
+ if ((v->progress & 3) == 0) {
+ BeginVehicleMove(v);
+ v->z_pos++;
+ VehiclePositionChanged(v);
+ EndVehicleMove(v);
+ } else if ((v->progress & 7) == 1) {
+ BeginVehicleMove(v);
+ if (v->cur_image != SPR_DIESEL_SMOKE_5) {
+ v->cur_image++;
+ VehiclePositionChanged(v);
+ EndVehicleMove(v);
+ } else {
+ EndVehicleMove(v);
+ DeleteVehicle(v);
+ }
+ }
+}
+
+static void ElectricSparkInit(Vehicle *v)
+{
+ v->cur_image = SPR_ELECTRIC_SPARK_0;
+ v->progress = 1;
+}
+
+static void ElectricSparkTick(Vehicle *v)
+{
+ if (v->progress < 2) {
+ v->progress++;
+ } else {
+ v->progress = 0;
+ BeginVehicleMove(v);
+ if (v->cur_image != SPR_ELECTRIC_SPARK_5) {
+ v->cur_image++;
+ VehiclePositionChanged(v);
+ EndVehicleMove(v);
+ } else {
+ EndVehicleMove(v);
+ DeleteVehicle(v);
+ }
+ }
+}
+
+static void SmokeInit(Vehicle *v)
+{
+ v->cur_image = SPR_SMOKE_0;
+ v->progress = 12;
+}
+
+static void SmokeTick(Vehicle *v)
+{
+ bool moved = false;
+
+ BeginVehicleMove(v);
+
+ v->progress++;
+
+ if ((v->progress & 3) == 0) {
+ v->z_pos++;
+ moved = true;
+ }
+
+ if ((v->progress & 0xF) == 4) {
+ if (v->cur_image != SPR_SMOKE_4) {
+ v->cur_image++;
+ } else {
+ EndVehicleMove(v);
+ DeleteVehicle(v);
+ return;
+ }
+ moved = true;
+ }
+
+ if (moved) {
+ VehiclePositionChanged(v);
+ EndVehicleMove(v);
+ }
+}
+
+static void ExplosionLargeInit(Vehicle *v)
+{
+ v->cur_image = SPR_EXPLOSION_LARGE_0;
+ v->progress = 0;
+}
+
+static void ExplosionLargeTick(Vehicle *v)
+{
+ v->progress++;
+ if ((v->progress & 3) == 0) {
+ BeginVehicleMove(v);
+ if (v->cur_image != SPR_EXPLOSION_LARGE_F) {
+ v->cur_image++;
+ VehiclePositionChanged(v);
+ EndVehicleMove(v);
+ } else {
+ EndVehicleMove(v);
+ DeleteVehicle(v);
+ }
+ }
+}
+
+static void BreakdownSmokeInit(Vehicle *v)
+{
+ v->cur_image = SPR_BREAKDOWN_SMOKE_0;
+ v->progress = 0;
+}
+
+static void BreakdownSmokeTick(Vehicle *v)
+{
+ v->progress++;
+ if ((v->progress & 7) == 0) {
+ BeginVehicleMove(v);
+ if (v->cur_image != SPR_BREAKDOWN_SMOKE_3) {
+ v->cur_image++;
+ } else {
+ v->cur_image = SPR_BREAKDOWN_SMOKE_0;
+ }
+ VehiclePositionChanged(v);
+ EndVehicleMove(v);
+ }
+
+ v->u.special.unk0--;
+ if (v->u.special.unk0 == 0) {
+ BeginVehicleMove(v);
+ EndVehicleMove(v);
+ DeleteVehicle(v);
+ }
+}
+
+static void ExplosionSmallInit(Vehicle *v)
+{
+ v->cur_image = SPR_EXPLOSION_SMALL_0;
+ v->progress = 0;
+}
+
+static void ExplosionSmallTick(Vehicle *v)
+{
+ v->progress++;
+ if ((v->progress & 3) == 0) {
+ BeginVehicleMove(v);
+ if (v->cur_image != SPR_EXPLOSION_SMALL_B) {
+ v->cur_image++;
+ VehiclePositionChanged(v);
+ EndVehicleMove(v);
+ } else {
+ EndVehicleMove(v);
+ DeleteVehicle(v);
+ }
+ }
+}
+
+static void BulldozerInit(Vehicle *v)
+{
+ v->cur_image = SPR_BULLDOZER_NE;
+ v->progress = 0;
+ v->u.special.unk0 = 0;
+ v->u.special.unk2 = 0;
+}
+
+typedef struct BulldozerMovement {
+ byte direction:2;
+ byte image:2;
+ byte duration:3;
+} BulldozerMovement;
+
+static const BulldozerMovement _bulldozer_movement[] = {
+ { 0, 0, 4 },
+ { 3, 3, 4 },
+ { 2, 2, 7 },
+ { 0, 2, 7 },
+ { 1, 1, 3 },
+ { 2, 2, 7 },
+ { 0, 2, 7 },
+ { 1, 1, 3 },
+ { 2, 2, 7 },
+ { 0, 2, 7 },
+ { 3, 3, 6 },
+ { 2, 2, 6 },
+ { 1, 1, 7 },
+ { 3, 1, 7 },
+ { 0, 0, 3 },
+ { 1, 1, 7 },
+ { 3, 1, 7 },
+ { 0, 0, 3 },
+ { 1, 1, 7 },
+ { 3, 1, 7 }
+};
+
+static const struct {
+ int8 x;
+ int8 y;
+} _inc_by_dir[] = {
+ { -1, 0 },
+ { 0, 1 },
+ { 1, 0 },
+ { 0, -1 }
+};
+
+static void BulldozerTick(Vehicle *v)
+{
+ v->progress++;
+ if ((v->progress & 7) == 0) {
+ const BulldozerMovement* b = &_bulldozer_movement[v->u.special.unk0];
+
+ BeginVehicleMove(v);
+
+ v->cur_image = SPR_BULLDOZER_NE + b->image;
+
+ v->x_pos += _inc_by_dir[b->direction].x;
+ v->y_pos += _inc_by_dir[b->direction].y;
+
+ v->u.special.unk2++;
+ if (v->u.special.unk2 >= b->duration) {
+ v->u.special.unk2 = 0;
+ v->u.special.unk0++;
+ if (v->u.special.unk0 == lengthof(_bulldozer_movement)) {
+ EndVehicleMove(v);
+ DeleteVehicle(v);
+ return;
+ }
+ }
+ VehiclePositionChanged(v);
+ EndVehicleMove(v);
+ }
+}
+
+static void BubbleInit(Vehicle *v)
+{
+ v->cur_image = SPR_BUBBLE_GENERATE_0;
+ v->spritenum = 0;
+ v->progress = 0;
+}
+
+typedef struct BubbleMovement {
+ int8 x:4;
+ int8 y:4;
+ int8 z:4;
+ byte image:4;
+} BubbleMovement;
+
+#define MK(x, y, z, i) { x, y, z, i }
+#define ME(i) { i, 4, 0, 0 }
+
+static const BubbleMovement _bubble_float_sw[] = {
+ MK(0, 0, 1, 0),
+ MK(1, 0, 1, 1),
+ MK(0, 0, 1, 0),
+ MK(1, 0, 1, 2),
+ ME(1)
+};
+
+
+static const BubbleMovement _bubble_float_ne[] = {
+ MK( 0, 0, 1, 0),
+ MK(-1, 0, 1, 1),
+ MK( 0, 0, 1, 0),
+ MK(-1, 0, 1, 2),
+ ME(1)
+};
+
+static const BubbleMovement _bubble_float_se[] = {
+ MK(0, 0, 1, 0),
+ MK(0, 1, 1, 1),
+ MK(0, 0, 1, 0),
+ MK(0, 1, 1, 2),
+ ME(1)
+};
+
+static const BubbleMovement _bubble_float_nw[] = {
+ MK(0, 0, 1, 0),
+ MK(0, -1, 1, 1),
+ MK(0, 0, 1, 0),
+ MK(0, -1, 1, 2),
+ ME(1)
+};
+
+static const BubbleMovement _bubble_burst[] = {
+ MK(0, 0, 1, 2),
+ MK(0, 0, 1, 7),
+ MK(0, 0, 1, 8),
+ MK(0, 0, 1, 9),
+ ME(0)
+};
+
+static const BubbleMovement _bubble_absorb[] = {
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 1),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 2),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 1),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 2),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 1),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 2),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 1),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 2),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 1),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 2),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 1),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 2),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 1),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 2),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 1),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 2),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 1),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 2),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 1),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 2),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 1),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 2),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 1),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 2),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 1),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 2),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 1),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 2),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 1),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 2),
+ MK(0, 0, 1, 0),
+ MK(0, 0, 1, 1),
+ MK(2, 1, 3, 0),
+ MK(1, 1, 3, 1),
+ MK(2, 1, 3, 0),
+ MK(1, 1, 3, 2),
+ MK(2, 1, 3, 0),
+ MK(1, 1, 3, 1),
+ MK(2, 1, 3, 0),
+ MK(1, 0, 1, 2),
+ MK(0, 0, 1, 0),
+ MK(1, 0, 1, 1),
+ MK(0, 0, 1, 0),
+ MK(1, 0, 1, 2),
+ MK(0, 0, 1, 0),
+ MK(1, 0, 1, 1),
+ MK(0, 0, 1, 0),
+ MK(1, 0, 1, 2),
+ ME(2),
+ MK(0, 0, 0, 0xA),
+ MK(0, 0, 0, 0xB),
+ MK(0, 0, 0, 0xC),
+ MK(0, 0, 0, 0xD),
+ MK(0, 0, 0, 0xE),
+ ME(0)
+};
+#undef ME
+#undef MK
+
+static const BubbleMovement * const _bubble_movement[] = {
+ _bubble_float_sw,
+ _bubble_float_ne,
+ _bubble_float_se,
+ _bubble_float_nw,
+ _bubble_burst,
+ _bubble_absorb,
+};
+
+static void BubbleTick(Vehicle *v)
+{
+ /*
+ * Warning: those effects can NOT use Random(), and have to use
+ * InteractiveRandom(), because somehow someone forgot to save
+ * spritenum to the savegame, and so it will cause desyncs in
+ * multiplayer!! (that is: in ToyLand)
+ */
+ uint et;
+ const BubbleMovement *b;
+
+ v->progress++;
+ if ((v->progress & 3) != 0)
+ return;
+
+ BeginVehicleMove(v);
+
+ if (v->spritenum == 0) {
+ v->cur_image++;
+ if (v->cur_image < SPR_BUBBLE_GENERATE_3) {
+ VehiclePositionChanged(v);
+ EndVehicleMove(v);
+ return;
+ }
+ if (v->u.special.unk2 != 0) {
+ v->spritenum = GB(InteractiveRandom(), 0, 2) + 1;
+ } else {
+ v->spritenum = 6;
+ }
+ et = 0;
+ } else {
+ et = v->engine_type + 1;
+ }
+
+ b = &_bubble_movement[v->spritenum - 1][et];
+
+ if (b->y == 4 && b->x == 0) {
+ EndVehicleMove(v);
+ DeleteVehicle(v);
+ return;
+ }
+
+ if (b->y == 4 && b->x == 1) {
+ if (v->z_pos > 180 || CHANCE16I(1, 96, InteractiveRandom())) {
+ v->spritenum = 5;
+ SndPlayVehicleFx(SND_2F_POP, v);
+ }
+ et = 0;
+ }
+
+ if (b->y == 4 && b->x == 2) {
+ TileIndex tile;
+
+ et++;
+ SndPlayVehicleFx(SND_31_EXTRACT, v);
+
+ tile = TileVirtXY(v->x_pos, v->y_pos);
+ if (IsTileType(tile, MP_INDUSTRY) && GetIndustryGfx(tile) == 0xA2) AddAnimatedTile(tile);
+ }
+
+ v->engine_type = et;
+ b = &_bubble_movement[v->spritenum - 1][et];
+
+ v->x_pos += b->x;
+ v->y_pos += b->y;
+ v->z_pos += b->z;
+ v->cur_image = SPR_BUBBLE_0 + b->image;
+
+ VehiclePositionChanged(v);
+ EndVehicleMove(v);
+}
+
+
+typedef void EffectInitProc(Vehicle *v);
+typedef void EffectTickProc(Vehicle *v);
+
+static EffectInitProc * const _effect_init_procs[] = {
+ ChimneySmokeInit,
+ SteamSmokeInit,
+ DieselSmokeInit,
+ ElectricSparkInit,
+ SmokeInit,
+ ExplosionLargeInit,
+ BreakdownSmokeInit,
+ ExplosionSmallInit,
+ BulldozerInit,
+ BubbleInit,
+};
+
+static EffectTickProc * const _effect_tick_procs[] = {
+ ChimneySmokeTick,
+ SteamSmokeTick,
+ DieselSmokeTick,
+ ElectricSparkTick,
+ SmokeTick,
+ ExplosionLargeTick,
+ BreakdownSmokeTick,
+ ExplosionSmallTick,
+ BulldozerTick,
+ BubbleTick,
+};
+
+
+Vehicle *CreateEffectVehicle(int x, int y, int z, EffectVehicle type)
+{
+ Vehicle *v;
+
+ v = ForceAllocateSpecialVehicle();
+ if (v != NULL) {
+ v->type = VEH_Special;
+ v->subtype = type;
+ v->x_pos = x;
+ v->y_pos = y;
+ v->z_pos = z;
+ v->z_height = v->sprite_width = v->sprite_height = 1;
+ v->x_offs = v->y_offs = 0;
+ v->tile = 0;
+ v->vehstatus = VS_UNCLICKABLE;
+
+ _effect_init_procs[type](v);
+
+ VehiclePositionChanged(v);
+ BeginVehicleMove(v);
+ EndVehicleMove(v);
+ }
+ return v;
+}
+
+Vehicle *CreateEffectVehicleAbove(int x, int y, int z, EffectVehicle type)
+{
+ int safe_x = clamp(x, 0, MapMaxX() * TILE_SIZE);
+ int safe_y = clamp(y, 0, MapMaxY() * TILE_SIZE);
+ return CreateEffectVehicle(x, y, GetSlopeZ(safe_x, safe_y) + z, type);
+}
+
+Vehicle *CreateEffectVehicleRel(const Vehicle *v, int x, int y, int z, EffectVehicle type)
+{
+ return CreateEffectVehicle(v->x_pos + x, v->y_pos + y, v->z_pos + z, type);
+}
+
+static void EffectVehicle_Tick(Vehicle *v)
+{
+ _effect_tick_procs[v->subtype](v);
+}
+
+Vehicle *CheckClickOnVehicle(const ViewPort *vp, int x, int y)
+{
+ Vehicle *found = NULL, *v;
+ uint dist, best_dist = (uint)-1;
+
+ if ( (uint)(x -= vp->left) >= (uint)vp->width ||
+ (uint)(y -= vp->top) >= (uint)vp->height)
+ return NULL;
+
+ x = (x << vp->zoom) + vp->virtual_left;
+ y = (y << vp->zoom) + vp->virtual_top;
+
+ FOR_ALL_VEHICLES(v) {
+ if ((v->vehstatus & (VS_HIDDEN|VS_UNCLICKABLE)) == 0 &&
+ x >= v->left_coord && x <= v->right_coord &&
+ y >= v->top_coord && y <= v->bottom_coord) {
+
+ dist = max(
+ myabs( ((v->left_coord + v->right_coord)>>1) - x ),
+ myabs( ((v->top_coord + v->bottom_coord)>>1) - y )
+ );
+
+ if (dist < best_dist) {
+ found = v;
+ best_dist = dist;
+ }
+ }
+ }
+
+ return found;
+}
+
+
+void DecreaseVehicleValue(Vehicle *v)
+{
+ v->value -= v->value >> 8;
+ InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
+}
+
+static const byte _breakdown_chance[64] = {
+ 3, 3, 3, 3, 3, 3, 3, 3,
+ 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 8, 9, 9, 10, 10, 11, 11,
+ 12, 13, 13, 13, 13, 14, 15, 16,
+ 17, 19, 21, 25, 28, 31, 34, 37,
+ 40, 44, 48, 52, 56, 60, 64, 68,
+ 72, 80, 90, 100, 110, 120, 130, 140,
+ 150, 170, 190, 210, 230, 250, 250, 250,
+};
+
+void CheckVehicleBreakdown(Vehicle *v)
+{
+ int rel, rel_old;
+ uint32 r;
+ int chance;
+
+ /* decrease reliability */
+ v->reliability = rel = max((rel_old = v->reliability) - v->reliability_spd_dec, 0);
+ if ((rel_old >> 8) != (rel >> 8))
+ InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
+
+ if (v->breakdown_ctr != 0 || v->vehstatus & VS_STOPPED ||
+ v->cur_speed < 5 || _game_mode == GM_MENU) {
+ return;
+ }
+
+ r = Random();
+
+ /* increase chance of failure */
+ chance = v->breakdown_chance + 1;
+ if (CHANCE16I(1,25,r)) chance += 25;
+ v->breakdown_chance = min(255, chance);
+
+ /* calculate reliability value to use in comparison */
+ rel = v->reliability;
+ if (v->type == VEH_Ship) rel += 0x6666;
+
+ /* disabled breakdowns? */
+ if (_opt.diff.vehicle_breakdowns < 1) return;
+
+ /* reduced breakdowns? */
+ if (_opt.diff.vehicle_breakdowns == 1) rel += 0x6666;
+
+ /* check if to break down */
+ if (_breakdown_chance[(uint)min(rel, 0xffff) >> 10] <= v->breakdown_chance) {
+ v->breakdown_ctr = GB(r, 16, 6) + 0x3F;
+ v->breakdown_delay = GB(r, 24, 7) + 0x80;
+ v->breakdown_chance = 0;
+ }
+}
+
+static const StringID _vehicle_type_names[4] = {
+ STR_019F_TRAIN,
+ STR_019C_ROAD_VEHICLE,
+ STR_019E_SHIP,
+ STR_019D_AIRCRAFT,
+};
+
+static void ShowVehicleGettingOld(Vehicle *v, StringID msg)
+{
+ if (v->owner != _local_player) return;
+
+ // Do not show getting-old message if autorenew is active
+ if (GetPlayer(v->owner)->engine_renew) return;
+
+ SetDParam(0, _vehicle_type_names[v->type - 0x10]);
+ SetDParam(1, v->unitnumber);
+ AddNewsItem(msg, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0), v->index, 0);
+}
+
+void AgeVehicle(Vehicle *v)
+{
+ int age;
+
+ if (v->age < 65535)
+ v->age++;
+
+ age = v->age - v->max_age;
+ if (age == 366*0 || age == 366*1 || age == 366*2 || age == 366*3 || age == 366*4)
+ v->reliability_spd_dec <<= 1;
+
+ InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
+
+ if (age == -366) {
+ ShowVehicleGettingOld(v, STR_01A0_IS_GETTING_OLD);
+ } else if (age == 0) {
+ ShowVehicleGettingOld(v, STR_01A1_IS_GETTING_VERY_OLD);
+ } else if (age == 366*1 || age == 366*2 || age == 366*3 || age == 366*4 || age == 366*5) {
+ ShowVehicleGettingOld(v, STR_01A2_IS_GETTING_VERY_OLD_AND);
+ }
+}
+
+/** Starts or stops a lot of vehicles
+ * @param tile Tile of the depot where the vehicles are started/stopped (only used for depots)
+ * @param p1 Station/Order/Depot ID (only used for vehicle list windows)
+ * @param p2 bitmask
+ * - bit 0-4 Vehicle type
+ * - bit 5 false = start vehicles, true = stop vehicles
+ * - bit 6 if set, then it's a vehicle list window, not a depot and Tile is ignored in this case
+ * - bit 8-11 Vehicle List Window type (ignored unless bit 1 is set)
+ */
+int32 CmdMassStartStopVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle **vl = NULL;
+ uint16 engine_list_length = 0;
+ uint16 engine_count = 0;
+ int32 return_value = CMD_ERROR;
+ uint i;
+ uint stop_command;
+ byte vehicle_type = GB(p2, 0, 5);
+ bool start_stop = HASBIT(p2, 5);
+ bool vehicle_list_window = HASBIT(p2, 6);
+
+ switch (vehicle_type) {
+ case VEH_Train: stop_command = CMD_START_STOP_TRAIN; break;
+ case VEH_Road: stop_command = CMD_START_STOP_ROADVEH; break;
+ case VEH_Ship: stop_command = CMD_START_STOP_SHIP; break;
+ case VEH_Aircraft: stop_command = CMD_START_STOP_AIRCRAFT; break;
+ default: return CMD_ERROR;
+ }
+
+ if (vehicle_list_window) {
+ uint16 id = GB(p1, 0, 16);
+ uint16 window_type = p2 & VLW_MASK;
+
+ engine_count = GenerateVehicleSortList((const Vehicle***)&vl, &engine_list_length, vehicle_type, _current_player, id, id, id, window_type);
+ } else {
+ /* Get the list of vehicles in the depot */
+ BuildDepotVehicleList(vehicle_type, tile, &vl, &engine_list_length, &engine_count, NULL, NULL, NULL);
+ }
+
+ for (i = 0; i < engine_count; i++) {
+ const Vehicle *v = vl[i];
+ int32 ret;
+
+ if (!!(v->vehstatus & VS_STOPPED) != start_stop) continue;
+
+ if (!vehicle_list_window) {
+ if (vehicle_type == VEH_Train) {
+ if (CheckTrainInDepot(v, false) == -1) continue;
+ } else {
+ if (!(v->vehstatus & VS_HIDDEN)) continue;
+ }
+ }
+
+ ret = DoCommand(tile, v->index, 0, flags, stop_command);
+
+ if (!CmdFailed(ret)) {
+ return_value = 0;
+ /* We know that the command is valid for at least one vehicle.
+ * If we haven't set DC_EXEC, then there is no point in continueing because it will be valid */
+ if (!(flags & DC_EXEC)) break;
+ }
+ }
+
+ free(vl);
+ return return_value;
+}
+
+/** Sells all vehicles in a depot
+* @param tile Tile of the depot where the depot is
+* @param p1 Vehicle type
+* @param p2 unused
+*/
+int32 CmdDepotSellAllVehicles(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle **engines = NULL;
+ Vehicle **wagons = NULL;
+ uint16 engine_list_length = 0;
+ uint16 engine_count = 0;
+ uint16 wagon_list_length = 0;
+ uint16 wagon_count = 0;
+
+ int32 cost = 0;
+ uint i, sell_command, total_number_vehicles;
+ byte vehicle_type = GB(p1, 0, 8);
+
+ switch (vehicle_type) {
+ case VEH_Train: sell_command = CMD_SELL_RAIL_WAGON; break;
+ case VEH_Road: sell_command = CMD_SELL_ROAD_VEH; break;
+ case VEH_Ship: sell_command = CMD_SELL_SHIP; break;
+ case VEH_Aircraft: sell_command = CMD_SELL_AIRCRAFT; break;
+ default: return CMD_ERROR;
+ }
+
+ /* Get the list of vehicles in the depot */
+ BuildDepotVehicleList(vehicle_type, tile, &engines, &engine_list_length, &engine_count,
+ &wagons, &wagon_list_length, &wagon_count);
+
+ total_number_vehicles = engine_count + wagon_count;
+ for (i = 0; i < total_number_vehicles; i++) {
+ const Vehicle *v;
+ int32 ret;
+
+ if (i < engine_count) {
+ v = engines[i];
+ } else {
+ v = wagons[i - engine_count];
+ }
+
+ ret = DoCommand(tile, v->index, 1, flags, sell_command);
+
+ if (!CmdFailed(ret)) cost += ret;
+ }
+
+ free(engines);
+ free(wagons);
+ if (cost == 0) return CMD_ERROR; // no vehicles to sell
+ return cost;
+}
+
+/** Autoreplace all vehicles in the depot
+* @param tile Tile of the depot where the vehicles are
+* @param p1 Type of vehicle
+* @param p2 Unused
+*/
+int32 CmdDepotMassAutoReplace(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle **vl = NULL;
+ uint16 engine_list_length = 0;
+ uint16 engine_count = 0;
+ uint i, x = 0, y = 0, z = 0;
+ int32 cost = 0;
+ byte vehicle_type = GB(p1, 0, 8);
+
+
+ if (!IsTileOwner(tile, _current_player)) return CMD_ERROR;
+
+ /* Get the list of vehicles in the depot */
+ BuildDepotVehicleList(vehicle_type, tile, &vl, &engine_list_length, &engine_count, NULL, NULL, NULL);
+
+
+ for (i = 0; i < engine_count; i++) {
+ Vehicle *v = vl[i];
+ bool stopped = !(v->vehstatus & VS_STOPPED);
+ int32 ret;
+
+ /* Ensure that the vehicle completely in the depot */
+ if (!IsVehicleInDepot(v)) continue;
+
+ x = v->x_pos;
+ y = v->y_pos;
+ z = v->z_pos;
+
+ if (stopped) {
+ v->vehstatus |= VS_STOPPED; // Stop the vehicle
+ v->leave_depot_instantly = true;
+ }
+ ret = MaybeReplaceVehicle(v, !(flags & DC_EXEC), false);
+
+ if (!CmdFailed(ret)) {
+ cost += ret;
+ if (!(flags & DC_EXEC)) break;
+ /* There is a problem with autoreplace and newgrf
+ * It's impossible to tell the length of a train after it's being replaced before it's actually done
+ * Because of this, we can't estimate costs due to wagon removal and we will have to always return 0 and pay manually
+ * Since we pay after each vehicle is replaced and MaybeReplaceVehicle() check if the player got enough money
+ * we should never reach a condition where the player will end up with negative money from doing this */
+ SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
+ SubtractMoneyFromPlayer(ret);
+ }
+ }
+
+ if (cost == 0) {
+ cost = CMD_ERROR;
+ } else {
+ if (flags & DC_EXEC) {
+ /* Display the cost animation now that DoCommandP() can't do it for us (see previous comments) */
+ if (IsLocalPlayer()) ShowCostOrIncomeAnimation(x, y, z, cost);
+ }
+ cost = 0;
+ }
+
+ free(vl);
+ return cost;
+}
+
+/** Clone a vehicle. If it is a train, it will clone all the cars too
+ * @param tile tile of the depot where the cloned vehicle is build
+ * @param p1 the original vehicle's index
+ * @param p2 1 = shared orders, else copied orders
+ */
+int32 CmdCloneVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle *v_front, *v;
+ Vehicle *w_front, *w, *w_rear;
+ int cost, total_cost = 0;
+ uint32 build_argument = 2;
+
+ if (!IsValidVehicleID(p1)) return CMD_ERROR;
+ v = GetVehicle(p1);
+ v_front = v;
+ w = NULL;
+ w_front = NULL;
+ w_rear = NULL;
+
+
+ /*
+ * v_front is the front engine in the original vehicle
+ * v is the car/vehicle of the original vehicle, that is currently being copied
+ * w_front is the front engine of the cloned vehicle
+ * w is the car/vehicle currently being cloned
+ * w_rear is the rear end of the cloned train. It's used to add more cars and is only used by trains
+ */
+
+ if (!CheckOwnership(v->owner)) return CMD_ERROR;
+
+ if (v->type == VEH_Train && (!IsFrontEngine(v) || v->u.rail.crash_anim_pos >= 4400)) return CMD_ERROR;
+
+ // check that we can allocate enough vehicles
+ if (!(flags & DC_EXEC)) {
+ int veh_counter = 0;
+ do {
+ veh_counter++;
+ } while ((v = v->next) != NULL);
+
+ if (!AllocateVehicles(NULL, veh_counter)) {
+ return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
+ }
+ }
+
+ v = v_front;
+
+ do {
+
+ if (IsMultiheaded(v) && !IsTrainEngine(v)) {
+ /* we build the rear ends of multiheaded trains with the front ones */
+ continue;
+ }
+
+ cost = DoCommand(tile, v->engine_type, build_argument, flags, CMD_BUILD_VEH(v->type));
+ build_argument = 3; // ensure that we only assign a number to the first engine
+
+ if (CmdFailed(cost)) return cost;
+
+ total_cost += cost;
+
+ if (flags & DC_EXEC) {
+ w = GetVehicle(_new_vehicle_id);
+
+ if (v->cargo_type != w->cargo_type || v->cargo_subtype != w->cargo_subtype) {
+ // we can't pay for refitting because we can't estimate refitting costs for a vehicle before it's build
+ // if we pay for it anyway, the cost and the estimated cost will not be the same and we will have an assert
+ DoCommand(0, w->index, v->cargo_type | (v->cargo_subtype << 8), flags, CMD_REFIT_VEH(v->type));
+ }
+ if (v->type == VEH_Train && HASBIT(v->u.rail.flags, VRF_REVERSE_DIRECTION)) {
+ SETBIT(w->u.rail.flags, VRF_REVERSE_DIRECTION);
+ }
+
+ if (v->type == VEH_Train && !IsFrontEngine(v)) {
+ // this s a train car
+ // add this unit to the end of the train
+ DoCommand(0, (w_rear->index << 16) | w->index, 1, flags, CMD_MOVE_RAIL_VEHICLE);
+ } else {
+ // this is a front engine or not a train. It need orders
+ w_front = w;
+ w->service_interval = v->service_interval;
+ DoCommand(0, (v->index << 16) | w->index, p2 & 1 ? CO_SHARE : CO_COPY, flags, CMD_CLONE_ORDER);
+ }
+ w_rear = w; // trains needs to know the last car in the train, so they can add more in next loop
+ }
+ } while (v->type == VEH_Train && (v = GetNextVehicle(v)) != NULL);
+
+ if (flags & DC_EXEC && v_front->type == VEH_Train) {
+ // for trains this needs to be the front engine due to the callback function
+ _new_vehicle_id = w_front->index;
+ }
+
+ /* Set the expense type last as refitting will make the cost go towards
+ * running costs... */
+ SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
+ return total_cost;
+}
+
+/*
+ * move the cargo from one engine to another if possible
+ */
+static void MoveVehicleCargo(Vehicle *dest, Vehicle *source)
+{
+ Vehicle *v = dest;
+ int units_moved;
+
+ do {
+ do {
+ if (source->cargo_type != dest->cargo_type)
+ continue; // cargo not compatible
+
+ if (dest->cargo_count == dest->cargo_cap)
+ continue; // the destination vehicle is already full
+
+ units_moved = min(source->cargo_count, dest->cargo_cap - dest->cargo_count);
+ source->cargo_count -= units_moved;
+ dest->cargo_count += units_moved;
+ dest->cargo_source = source->cargo_source;
+
+ // copy the age of the cargo
+ dest->cargo_days = source->cargo_days;
+ dest->day_counter = source->day_counter;
+ dest->tick_counter = source->tick_counter;
+
+ } while (source->cargo_count > 0 && (dest = dest->next) != NULL);
+ dest = v;
+ } while ((source = source->next) != NULL);
+}
+
+static bool VerifyAutoreplaceRefitForOrders(const Vehicle *v, const EngineID engine_type)
+{
+ const Order *o;
+ const Vehicle *u;
+
+ if (v->type == VEH_Train) {
+ u = GetFirstVehicleInChain(v);
+ } else {
+ u = v;
+ }
+
+ FOR_VEHICLE_ORDERS(u, o) {
+ if (!(o->refit_cargo < NUM_CARGO)) continue;
+ if (!CanRefitTo(v->engine_type, o->refit_cargo)) continue;
+ if (!CanRefitTo(engine_type, o->refit_cargo)) return false;
+ }
+
+ return true;
+}
+
+/**
+ * Function to find what type of cargo to refit to when autoreplacing
+ * @param *v Original vehicle, that is being replaced
+ * @param engine_type The EngineID of the vehicle that is being replaced to
+ * @return The cargo type to replace to
+ * CT_NO_REFIT is returned if no refit is needed
+ * CT_INVALID is returned when both old and new vehicle got cargo capacity and refitting the new one to the old one's cargo type isn't possible
+ */
+static CargoID GetNewCargoTypeForReplace(Vehicle *v, EngineID engine_type)
+{
+ bool new_cargo_capacity = true;
+ CargoID new_cargo_type = CT_INVALID;
+
+ switch (v->type) {
+ case VEH_Train:
+ new_cargo_capacity = (RailVehInfo(engine_type)->capacity > 0);
+ new_cargo_type = RailVehInfo(engine_type)->cargo_type;
+ break;
+
+ case VEH_Road:
+ new_cargo_capacity = (RoadVehInfo(engine_type)->capacity > 0);
+ new_cargo_type = RoadVehInfo(engine_type)->cargo_type;
+ break;
+ case VEH_Ship:
+ new_cargo_capacity = (ShipVehInfo(engine_type)->capacity > 0);
+ new_cargo_type = ShipVehInfo(engine_type)->cargo_type;
+ break;
+
+ case VEH_Aircraft:
+ /* all aircraft starts as passenger planes with cargo capacity
+ * new_cargo_capacity is always true for aircraft, which is the init value. No need to set it here */
+ new_cargo_type = CT_PASSENGERS;
+ break;
+
+ default: NOT_REACHED(); break;
+ }
+
+ if (!new_cargo_capacity) return CT_NO_REFIT; // Don't try to refit an engine with no cargo capacity
+
+ if (v->cargo_type == new_cargo_type || CanRefitTo(engine_type, v->cargo_type)) {
+ if (VerifyAutoreplaceRefitForOrders(v, engine_type)) {
+ return v->cargo_type == new_cargo_type ? CT_NO_REFIT : v->cargo_type;
+ } else {
+ return CT_INVALID;
+ }
+ }
+ if (v->type != VEH_Train) return CT_INVALID; // We can't refit the vehicle to carry the cargo we want
+
+ /* Below this line it's safe to assume that the vehicle in question is a train */
+
+ if (v->cargo_cap != 0) return CT_INVALID; // trying to replace a vehicle with cargo capacity into another one with incompatible cargo type
+
+ /* the old engine didn't have cargo capacity, but the new one does
+ * now we will figure out what cargo the train is carrying and refit to fit this */
+ v = GetFirstVehicleInChain(v);
+ do {
+ if (v->cargo_cap == 0) continue;
+ /* Now we found a cargo type being carried on the train and we will see if it is possible to carry to this one */
+ if (v->cargo_type == new_cargo_type) return CT_NO_REFIT;
+ if (CanRefitTo(engine_type, v->cargo_type)) return v->cargo_type;
+ } while ((v=v->next) != NULL);
+ return CT_NO_REFIT; // We failed to find a cargo type on the old vehicle and we will not refit the new one
+}
+
+/* Replaces a vehicle (used to be called autorenew)
+ * This function is only called from MaybeReplaceVehicle()
+ * Must be called with _current_player set to the owner of the vehicle
+ * @param w Vehicle to replace
+ * @param flags is the flags to use when calling DoCommand(). Mainly DC_EXEC counts
+ * @return value is cost of the replacement or CMD_ERROR
+ */
+static int32 ReplaceVehicle(Vehicle **w, byte flags, int32 total_cost)
+{
+ int32 cost;
+ int32 sell_value;
+ Vehicle *old_v = *w;
+ const Player *p = GetPlayer(old_v->owner);
+ EngineID new_engine_type;
+ const UnitID cached_unitnumber = old_v->unitnumber;
+ bool new_front = false;
+ Vehicle *new_v = NULL;
+ char vehicle_name[32];
+ CargoID replacement_cargo_type;
+
+ new_engine_type = EngineReplacementForPlayer(p, old_v->engine_type);
+ if (new_engine_type == INVALID_ENGINE) new_engine_type = old_v->engine_type;
+
+ replacement_cargo_type = GetNewCargoTypeForReplace(old_v, new_engine_type);
+
+ /* check if we can't refit to the needed type, so no replace takes place to prevent the vehicle from altering cargo type */
+ if (replacement_cargo_type == CT_INVALID) return 0;
+
+ sell_value = DoCommand(0, old_v->index, 0, DC_QUERY_COST, CMD_SELL_VEH(old_v->type));
+
+ /* We give the player a loan of the same amount as the sell value.
+ * This is needed in case he needs the income from the sale to build the new vehicle.
+ * We take it back if building fails or when we really sell the old engine */
+ SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
+ SubtractMoneyFromPlayer(sell_value);
+
+ cost = DoCommand(old_v->tile, new_engine_type, 3, flags, CMD_BUILD_VEH(old_v->type));
+ if (CmdFailed(cost)) {
+ SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
+ SubtractMoneyFromPlayer(-sell_value); // Take back the money we just gave the player
+ return cost;
+ }
+
+ if (replacement_cargo_type != CT_NO_REFIT) cost += GetRefitCost(new_engine_type); // add refit cost
+
+ if (flags & DC_EXEC) {
+ new_v = GetVehicle(_new_vehicle_id);
+ *w = new_v; //we changed the vehicle, so MaybeReplaceVehicle needs to work on the new one. Now we tell it what the new one is
+
+ /* refit if needed */
+ if (replacement_cargo_type != CT_NO_REFIT) {
+ if (CmdFailed(DoCommand(0, new_v->index, replacement_cargo_type, DC_EXEC, CMD_REFIT_VEH(new_v->type)))) {
+ /* Being here shows a failure, which most likely is in GetNewCargoTypeForReplace() or incorrect estimation costs */
+ error("Autoreplace failed to refit. Replace engine %d to %d and refit to cargo %d", old_v->engine_type, new_v->engine_type, replacement_cargo_type);
+ }
+ }
+
+ if (new_v->type == VEH_Train && HASBIT(old_v->u.rail.flags, VRF_REVERSE_DIRECTION) && !IsMultiheaded(new_v) && !(new_v->next != NULL && IsArticulatedPart(new_v->next))) {
+ // we are autorenewing to a single engine, so we will turn it as the old one was turned as well
+ SETBIT(new_v->u.rail.flags, VRF_REVERSE_DIRECTION);
+ }
+
+ if (old_v->type == VEH_Train && !IsFrontEngine(old_v)) {
+ /* this is a railcar. We need to move the car into the train
+ * We add the new engine after the old one instead of replacing it. It will give the same result anyway when we
+ * sell the old engine in a moment
+ */
+ DoCommand(0, (GetPrevVehicleInChain(old_v)->index << 16) | new_v->index, 1, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
+ /* Now we move the old one out of the train */
+ DoCommand(0, (INVALID_VEHICLE << 16) | old_v->index, 0, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
+ } else {
+ // copy/clone the orders
+ DoCommand(0, (old_v->index << 16) | new_v->index, IsOrderListShared(old_v) ? CO_SHARE : CO_COPY, DC_EXEC, CMD_CLONE_ORDER);
+ new_v->cur_order_index = old_v->cur_order_index;
+ ChangeVehicleViewWindow(old_v, new_v);
+ new_v->profit_this_year = old_v->profit_this_year;
+ new_v->profit_last_year = old_v->profit_last_year;
+ new_v->service_interval = old_v->service_interval;
+ new_front = true;
+ new_v->unitnumber = old_v->unitnumber; // use the same unit number
+
+ new_v->current_order = old_v->current_order;
+ if (old_v->type == VEH_Train && GetNextVehicle(old_v) != NULL){
+ Vehicle *temp_v = GetNextVehicle(old_v);
+
+ // move the entire train to the new engine, excluding the old engine
+ if (IsMultiheaded(old_v) && temp_v == old_v->u.rail.other_multiheaded_part) {
+ // we got front and rear of a multiheaded engine right after each other. We should work with the next in line instead
+ temp_v = GetNextVehicle(temp_v);
+ }
+
+ if (temp_v != NULL) {
+ DoCommand(0, (new_v->index << 16) | temp_v->index, 1, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
+ }
+ }
+ }
+ /* We are done setting up the new vehicle. Now we move the cargo from the old one to the new one */
+ MoveVehicleCargo(new_v->type == VEH_Train ? GetFirstVehicleInChain(new_v) : new_v, old_v);
+
+ // Get the name of the old vehicle if it has a custom name.
+ if (!IsCustomName(old_v->string_id)) {
+ vehicle_name[0] = '\0';
+ } else {
+ GetName(vehicle_name, old_v->string_id & 0x7FF, lastof(vehicle_name));
+ }
+ } else { // flags & DC_EXEC not set
+ /* Ensure that the player will not end up having negative money while autoreplacing
+ * This is needed because the only other check is done after the income from selling the old vehicle is substracted from the cost */
+ if (p->money64 < (cost + total_cost)) {
+ SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
+ SubtractMoneyFromPlayer(-sell_value); // Pay back the loan
+ return CMD_ERROR;
+ }
+ }
+
+ /* Take back the money we just gave the player just before building the vehicle
+ * The player will get the same amount now that the sale actually takes place */
+ SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
+ SubtractMoneyFromPlayer(-sell_value);
+
+ /* sell the engine/ find out how much you get for the old engine (income is returned as negative cost) */
+ cost += DoCommand(0, old_v->index, 0, flags, CMD_SELL_VEH(old_v->type));
+
+ if (new_front) {
+ /* now we assign the old unitnumber to the new vehicle */
+ new_v->unitnumber = cached_unitnumber;
+ }
+
+ /* Transfer the name of the old vehicle */
+ if ((flags & DC_EXEC) && vehicle_name[0] != '\0') {
+ _cmd_text = vehicle_name;
+ DoCommand(0, new_v->index, 0, DC_EXEC, CMD_NAME_VEHICLE);
+ }
+
+ return cost;
+}
+
+/** replaces a vehicle if it's set for autoreplace or is too old
+ * (used to be called autorenew)
+ * @param v The vehicle to replace
+ * if the vehicle is a train, v needs to be the front engine
+ * @param check Checks if the replace is valid. No action is done at all
+ * @param display_costs If set, a cost animation is shown (only if check is false)
+ * @return CMD_ERROR if something went wrong. Otherwise the price of the replace
+ */
+static int32 MaybeReplaceVehicle(Vehicle *v, bool check, bool display_costs)
+{
+ Vehicle *w;
+ const Player *p = GetPlayer(v->owner);
+ byte flags = 0;
+ int32 cost, temp_cost = 0;
+ bool stopped = false;
+
+ /* Remember the length in case we need to trim train later on
+ * If it's not a train, the value is unused
+ * round up to the length of the tiles used for the train instead of the train length instead
+ * Useful when newGRF uses custom length */
+ uint16 old_total_length = (v->type == VEH_Train ?
+ (v->u.rail.cached_total_length + TILE_SIZE - 1) / TILE_SIZE * TILE_SIZE :
+ -1
+ );
+
+
+ _current_player = v->owner;
+
+ assert(v->type == VEH_Train || v->type == VEH_Road || v->type == VEH_Ship || v->type == VEH_Aircraft);
+
+ assert(v->vehstatus & VS_STOPPED); // the vehicle should have been stopped in VehicleEnteredDepotThisTick() if needed
+
+ if (v->leave_depot_instantly) {
+ // we stopped the vehicle to do this, so we have to remember to start it again when we are done
+ // we need to store this info as the engine might be replaced and lose this info
+ stopped = true;
+ }
+
+ for (;;) {
+ cost = 0;
+ w = v;
+ do {
+ if (w->type == VEH_Train && IsMultiheaded(w) && !IsTrainEngine(w)) {
+ /* we build the rear ends of multiheaded trains with the front ones */
+ continue;
+ }
+
+ // check if the vehicle should be replaced
+ if (!p->engine_renew ||
+ w->age - w->max_age < (p->engine_renew_months * 30) || // replace if engine is too old
+ w->max_age == 0) { // rail cars got a max age of 0
+ if (!EngineHasReplacementForPlayer(p, w->engine_type)) // updates to a new model
+ continue;
+ }
+
+ /* Now replace the vehicle */
+ temp_cost = ReplaceVehicle(&w, flags, cost);
+
+ if (flags & DC_EXEC &&
+ (w->type != VEH_Train || w->u.rail.first_engine == INVALID_ENGINE)) {
+ /* now we bought a new engine and sold the old one. We need to fix the
+ * pointers in order to avoid pointing to the old one for trains: these
+ * pointers should point to the front engine and not the cars
+ */
+ v = w;
+ }
+
+ if (!CmdFailed(temp_cost)) {
+ cost += temp_cost;
+ }
+ } while (w->type == VEH_Train && (w = GetNextVehicle(w)) != NULL);
+
+ if (!(flags & DC_EXEC) && (p->money64 < (int32)(cost + p->engine_renew_money) || cost == 0)) {
+ if (!check && p->money64 < (int32)(cost + p->engine_renew_money) && ( _local_player == v->owner ) && cost != 0) {
+ StringID message;
+ SetDParam(0, v->unitnumber);
+ switch (v->type) {
+ case VEH_Train: message = STR_TRAIN_AUTORENEW_FAILED; break;
+ case VEH_Road: message = STR_ROADVEHICLE_AUTORENEW_FAILED; break;
+ case VEH_Ship: message = STR_SHIP_AUTORENEW_FAILED; break;
+ case VEH_Aircraft: message = STR_AIRCRAFT_AUTORENEW_FAILED; break;
+ // This should never happen
+ default: NOT_REACHED(); message = 0; break;
+ }
+
+ AddNewsItem(message, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0), v->index, 0);
+ }
+ if (stopped) v->vehstatus &= ~VS_STOPPED;
+ if (display_costs) _current_player = OWNER_NONE;
+ return CMD_ERROR;
+ }
+
+ if (flags & DC_EXEC) {
+ break; // we are done replacing since the loop ran once with DC_EXEC
+ } else if (check) {
+ /* It's a test only and we know that we can do this
+ * NOTE: payment for wagon removal is NOT included in this price */
+ return cost;
+ }
+ // now we redo the loop, but this time we actually do stuff since we know that we can do it
+ flags |= DC_EXEC;
+ }
+
+ /* If setting is on to try not to exceed the old length of the train with the replacement */
+ if (v->type == VEH_Train && p->renew_keep_length) {
+ Vehicle *temp;
+ w = v;
+
+ while (v->u.rail.cached_total_length > old_total_length) {
+ // the train is too long. We will remove cars one by one from the start of the train until it's short enough
+ while (w != NULL && !(RailVehInfo(w->engine_type)->flags&RVI_WAGON) ) {
+ w = GetNextVehicle(w);
+ }
+ if (w == NULL) {
+ // we failed to make the train short enough
+ SetDParam(0, v->unitnumber);
+ AddNewsItem(STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0), v->index, 0);
+ break;
+ }
+ temp = w;
+ w = GetNextVehicle(w);
+ DoCommand(0, (INVALID_VEHICLE << 16) | temp->index, 0, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
+ MoveVehicleCargo(v, temp);
+ cost += DoCommand(0, temp->index, 0, DC_EXEC, CMD_SELL_RAIL_WAGON);
+ }
+ }
+
+ if (stopped) v->vehstatus &= ~VS_STOPPED;
+ if (display_costs) {
+ if (IsLocalPlayer()) ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost);
+ _current_player = OWNER_NONE;
+ }
+ return cost;
+}
+
+/* Extend the list size for BuildDepotVehicleList() */
+static inline void ExtendVehicleListSize(const Vehicle ***engine_list, uint16 *engine_list_length, uint16 step_size)
+{
+ *engine_list_length = min(*engine_list_length + step_size, GetMaxVehicleIndex() + 1);
+ *engine_list = realloc((void*)*engine_list, (*engine_list_length) * sizeof((*engine_list)[0]));
+}
+
+/** Generates a list of vehicles inside a depot
+ * Will enlarge allocated space for the list if they are too small, so it's ok to call with (pointer to NULL array, pointer to uninitised uint16, pointer to 0)
+ * If one of the lists is not needed (say wagons when finding ships), all the pointers regarding that list should be set to NULL
+ * @param Type type of vehicle
+ * @param tile The tile the depot is located in
+ * @param ***engine_list Pointer to a pointer to an array of vehicles in the depot (old list is freed and a new one is malloced)
+ * @param *engine_list_length Allocated size of engine_list. Needs to be set to 0 when engine_list points to a NULL array
+ * @param *engine_count The number of engines stored in the list
+ * @param ***wagon_list Pointer to a pointer to an array of free wagons in the depot (old list is freed and a new one is malloced)
+ * @param *wagon_list_length Allocated size of wagon_list. Needs to be set to 0 when wagon_list points to a NULL array
+ * @param *wagon_count The number of engines stored in the list
+ */
+void BuildDepotVehicleList(byte type, TileIndex tile, Vehicle ***engine_list, uint16 *engine_list_length, uint16 *engine_count, Vehicle ***wagon_list, uint16 *wagon_list_length, uint16 *wagon_count)
+{
+ Vehicle *v;
+
+ /* This function should never be called without an array to store results */
+ assert(!(engine_list == NULL && type != VEH_Train));
+ assert(!(type == VEH_Train && engine_list == NULL && wagon_list == NULL));
+
+ /* Both array and the length should either be NULL to disable the list or both should not be NULL */
+ assert((engine_list == NULL && engine_list_length == NULL) || (engine_list != NULL && engine_list_length != NULL));
+ assert((wagon_list == NULL && wagon_list_length == NULL) || (wagon_list != NULL && wagon_list_length != NULL));
+
+ assert(!(engine_list != NULL && engine_count == NULL));
+ assert(!(wagon_list != NULL && wagon_count == NULL));
+
+ if (engine_count != NULL) *engine_count = 0;
+ if (wagon_count != NULL) *wagon_count = 0;
+
+ switch (type) {
+ case VEH_Train:
+ FOR_ALL_VEHICLES(v) {
+ if (v->tile == tile && v->type == VEH_Train && v->u.rail.track == 0x80) {
+ if (IsFrontEngine(v)) {
+ if (engine_list == NULL) continue;
+ if (*engine_count == *engine_list_length) ExtendVehicleListSize((const Vehicle***)engine_list, engine_list_length, 25);
+ (*engine_list)[(*engine_count)++] = v;
+ } else if (IsFreeWagon(v)) {
+ if (wagon_list == NULL) continue;
+ if (*wagon_count == *wagon_list_length) ExtendVehicleListSize((const Vehicle***)wagon_list, wagon_list_length, 25);
+ (*wagon_list)[(*wagon_count)++] = v;
+ }
+ }
+ }
+ break;
+
+ case VEH_Road:
+ FOR_ALL_VEHICLES(v) {
+ if (v->tile == tile && v->type == VEH_Road && IsRoadVehInDepot(v)) {
+ if (*engine_count == *engine_list_length) ExtendVehicleListSize((const Vehicle***)engine_list, engine_list_length, 25);
+ (*engine_list)[(*engine_count)++] = v;
+ }
+ }
+ break;
+
+ case VEH_Ship:
+ FOR_ALL_VEHICLES(v) {
+ if (v->tile == tile && v->type == VEH_Ship && IsShipInDepot(v)) {
+ if (*engine_count == *engine_list_length) ExtendVehicleListSize((const Vehicle***)engine_list, engine_list_length, 25);
+ (*engine_list)[(*engine_count)++] = v;
+ }
+ }
+ break;
+
+ case VEH_Aircraft:
+ FOR_ALL_VEHICLES(v) {
+ if (v->tile == tile &&
+ v->type == VEH_Aircraft &&
+ v->subtype <= 2 &&
+ v->vehstatus & VS_HIDDEN) {
+ if (*engine_count == *engine_list_length) ExtendVehicleListSize((const Vehicle***)engine_list, engine_list_length, 25);
+ (*engine_list)[(*engine_count)++] = v;
+ }
+ }
+ break;
+
+ default: NOT_REACHED();
+ }
+}
+
+/**
+* @param sort_list list to store the list in. Either NULL or the length length_of_array tells
+* @param length_of_array informs the length allocated for sort_list. This is not the same as the number of vehicles in the list. Needs to be 0 when sort_list is NULL
+* @param type type of vehicle
+* @param owner PlayerID of owner to generate a list for
+* @param station index of station to generate a list for. INVALID_STATION when not used
+* @param order index of oder to generate a list for. INVALID_ORDER when not used
+* @param window_type tells what kind of window the list is for. Use the VLW flags in vehicle_gui.h
+* @return the number of vehicles added to the list
+*/
+uint GenerateVehicleSortList(const Vehicle ***sort_list, uint16 *length_of_array, byte type, PlayerID owner, StationID station, OrderID order, uint16 depot_airport_index, uint16 window_type)
+{
+ const uint subtype = (type != VEH_Aircraft) ? Train_Front : 2;
+ uint n = 0;
+ const Vehicle *v;
+
+ switch (window_type) {
+ case VLW_STATION_LIST: {
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == type && (
+ (type == VEH_Train && IsFrontEngine(v)) ||
+ (type != VEH_Train && v->subtype <= subtype))) {
+ const Order *order;
+
+ FOR_VEHICLE_ORDERS(v, order) {
+ if (order->type == OT_GOTO_STATION && order->dest == station) {
+ if (n == *length_of_array) ExtendVehicleListSize(sort_list, length_of_array, 50);
+ (*sort_list)[n++] = v;
+ break;
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ case VLW_SHARED_ORDERS: {
+ FOR_ALL_VEHICLES(v) {
+ /* Find a vehicle with the order in question */
+ if (v->orders != NULL && v->orders->index == order) break;
+ }
+
+ if (v != NULL && v->orders != NULL && v->orders->index == order) {
+ /* Only try to make the list if we found a vehicle using the order in question */
+ for (v = GetFirstVehicleFromSharedList(v); v != NULL; v = v->next_shared) {
+ if (n == *length_of_array) ExtendVehicleListSize(sort_list, length_of_array, 25);
+ (*sort_list)[n++] = v;
+ }
+ }
+ break;
+ }
+
+ case VLW_STANDARD: {
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == type && v->owner == owner && (
+ (type == VEH_Train && IsFrontEngine(v)) ||
+ (type != VEH_Train && v->subtype <= subtype))) {
+ /* TODO find a better estimate on the total number of vehicles for current player */
+ if (n == *length_of_array) ExtendVehicleListSize(sort_list, length_of_array, GetNumVehicles()/4);
+ (*sort_list)[n++] = v;
+ }
+ }
+ break;
+ }
+
+ case VLW_DEPOT_LIST: {
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == type && (
+ (type == VEH_Train && IsFrontEngine(v)) ||
+ (type != VEH_Train && v->subtype <= subtype))) {
+ const Order *order;
+
+ FOR_VEHICLE_ORDERS(v, order) {
+ if (order->type == OT_GOTO_DEPOT && order->dest == depot_airport_index) {
+ if (n == *length_of_array) ExtendVehicleListSize(sort_list, length_of_array, 25);
+ (*sort_list)[n++] = v;
+ break;
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ default: NOT_REACHED(); break;
+ }
+
+ if ((n + 100) < *length_of_array) {
+ /* We allocated way too much for sort_list.
+ * Now we will reduce how much we allocated.
+ * We will still make it have room for 50 extra vehicles to prevent having
+ * to move the whole array if just one vehicle is added later */
+ *length_of_array = n + 50;
+ *sort_list = realloc((void*)*sort_list, (*length_of_array) * sizeof((*sort_list)[0]));
+ }
+
+ return n;
+}
+
+/** send all vehicles of type to depots
+ * @param type type of vehicle
+ * @param flags the flags used for DoCommand()
+ * @param service should the vehicles only get service in the depots
+ * @param owner PlayerID of owner of the vehicles to send
+ * @param VLW_flag tells what kind of list requested the goto depot
+ * @return 0 for success and CMD_ERROR if no vehicle is able to go to depot
+ */
+int32 SendAllVehiclesToDepot(byte type, uint32 flags, bool service, PlayerID owner, uint16 vlw_flag, uint32 id)
+{
+ const Vehicle **sort_list = NULL;
+ uint n, i;
+ uint16 array_length = 0;
+
+ n = GenerateVehicleSortList(&sort_list, &array_length, type, owner, id, id, id, vlw_flag);
+
+ /* Send all the vehicles to a depot */
+ for (i = 0; i < n; i++) {
+ const Vehicle *v = sort_list[i];
+ int32 ret = DoCommand(v->tile, v->index, service | DEPOT_DONT_CANCEL, flags, CMD_SEND_TO_DEPOT(type));
+
+ /* Return 0 if DC_EXEC is not set this is a valid goto depot command)
+ * In this case we know that at least one vehicle can be sent to a depot
+ * and we will issue the command. We can now safely quit the loop, knowing
+ * it will succeed at least once. With DC_EXEC we really need to send them to the depot */
+ if (!CmdFailed(ret) && !(flags & DC_EXEC)) {
+ free((void*)sort_list);
+ return 0;
+ }
+ }
+
+ free((void*)sort_list);
+ return (flags & DC_EXEC) ? 0 : CMD_ERROR;
+}
+
+bool IsVehicleInDepot(const Vehicle *v)
+{
+ switch (v->type) {
+ case VEH_Train: return CheckTrainInDepot(v, false) != -1;
+ case VEH_Road: return IsRoadVehInDepot(v);
+ case VEH_Ship: return IsShipInDepot(v);
+ case VEH_Aircraft: return IsAircraftInHangar(v);
+ default: NOT_REACHED();
+ }
+ return false;
+}
+
+void VehicleEnterDepot(Vehicle *v)
+{
+ switch (v->type) {
+ case VEH_Train:
+ InvalidateWindowClasses(WC_TRAINS_LIST);
+ if (!IsFrontEngine(v)) v = GetFirstVehicleInChain(v);
+ UpdateSignalsOnSegment(v->tile, GetRailDepotDirection(v->tile));
+ v->load_unload_time_rem = 0;
+ break;
+
+ case VEH_Road:
+ InvalidateWindowClasses(WC_ROADVEH_LIST);
+ v->u.road.state = 254;
+ break;
+
+ case VEH_Ship:
+ InvalidateWindowClasses(WC_SHIPS_LIST);
+ v->u.ship.state = 0x80;
+ RecalcShipStuff(v);
+ break;
+
+ case VEH_Aircraft:
+ InvalidateWindowClasses(WC_AIRCRAFT_LIST);
+ HandleAircraftEnterHangar(v);
+ break;
+ default: NOT_REACHED();
+ }
+
+ if (v->type != VEH_Train) {
+ /* Trains update the vehicle list when the first unit enters the depot and calls VehicleEnterDepot() when the last unit enters.
+ * We only increase the number of vehicles when the first one enters, so we will not need to search for more vehicles in the depot */
+ InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
+ }
+ InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
+
+ v->vehstatus |= VS_HIDDEN;
+ v->cur_speed = 0;
+
+ VehicleServiceInDepot(v);
+
+ TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
+
+ if (v->current_order.type == OT_GOTO_DEPOT) {
+ Order t;
+
+ InvalidateWindow(WC_VEHICLE_VIEW, v->index);
+
+ t = v->current_order;
+ v->current_order.type = OT_DUMMY;
+ v->current_order.flags = 0;
+
+ if (t.refit_cargo < NUM_CARGO) {
+ int32 cost;
+
+ _current_player = v->owner;
+ cost = DoCommand(v->tile, v->index, t.refit_cargo | t.refit_subtype << 8, DC_EXEC, CMD_REFIT_VEH(v->type));
+
+ if (CmdFailed(cost)) {
+ v->leave_depot_instantly = false; // We ensure that the vehicle stays in the depot
+ if (v->owner == _local_player) {
+ /* Notify the user that we stopped the vehicle */
+ SetDParam(0, _vehicle_type_names[v->type - 0x10]);
+ SetDParam(1, v->unitnumber);
+ AddNewsItem(STR_ORDER_REFIT_FAILED, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0), v->index, 0);
+ }
+ } else if (v->owner == _local_player && cost != 0) {
+ ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost);
+ }
+ }
+
+ if (HASBIT(t.flags, OFB_PART_OF_ORDERS)) {
+ /* Part of orders */
+ if (v->type == VEH_Train) v->u.rail.days_since_order_progr = 0;
+ v->cur_order_index++;
+ } else if (HASBIT(t.flags, OFB_HALT_IN_DEPOT)) {
+ /* Force depot visit */
+ v->vehstatus |= VS_STOPPED;
+ if (v->owner == _local_player) {
+ StringID string;
+
+ switch (v->type) {
+ case VEH_Train: string = STR_8814_TRAIN_IS_WAITING_IN_DEPOT; break;
+ case VEH_Road: string = STR_9016_ROAD_VEHICLE_IS_WAITING; break;
+ case VEH_Ship: string = STR_981C_SHIP_IS_WAITING_IN_DEPOT; break;
+ case VEH_Aircraft: string = STR_A014_AIRCRAFT_IS_WAITING_IN; break;
+ default: NOT_REACHED(); string = STR_EMPTY; // Set the string to something to avoid a compiler warning
+ }
+
+ SetDParam(0, v->unitnumber);
+ AddNewsItem(string, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0), v->index, 0);
+ }
+ }
+ }
+}
+
+/** Give a custom name to your vehicle
+ * @param tile unused
+ * @param p1 vehicle ID to name
+ * @param p2 unused
+ */
+int32 CmdNameVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle *v;
+ StringID str;
+
+ if (!IsValidVehicleID(p1) || _cmd_text[0] == '\0') return CMD_ERROR;
+
+ v = GetVehicle(p1);
+
+ if (!CheckOwnership(v->owner)) return CMD_ERROR;
+
+ str = AllocateNameUnique(_cmd_text, 2);
+ if (str == 0) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ StringID old_str = v->string_id;
+ v->string_id = str;
+ DeleteName(old_str);
+ ResortVehicleLists();
+ MarkWholeScreenDirty();
+ } else {
+ DeleteName(str);
+ }
+
+ return 0;
+}
+
+
+/** Change the service interval of a vehicle
+ * @param tile unused
+ * @param p1 vehicle ID that is being service-interval-changed
+ * @param p2 new service interval
+ */
+int32 CmdChangeServiceInt(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Vehicle* v;
+ uint16 serv_int = GetServiceIntervalClamped(p2); /* Double check the service interval from the user-input */
+
+ if (serv_int != p2 || !IsValidVehicleID(p1)) return CMD_ERROR;
+
+ v = GetVehicle(p1);
+
+ if (!CheckOwnership(v->owner)) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ v->service_interval = serv_int;
+ InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
+ }
+
+ return 0;
+}
+
+
+static Rect _old_vehicle_coords;
+
+void BeginVehicleMove(Vehicle *v) {
+ _old_vehicle_coords.left = v->left_coord;
+ _old_vehicle_coords.top = v->top_coord;
+ _old_vehicle_coords.right = v->right_coord;
+ _old_vehicle_coords.bottom = v->bottom_coord;
+}
+
+void EndVehicleMove(Vehicle *v)
+{
+ MarkAllViewportsDirty(
+ min(_old_vehicle_coords.left,v->left_coord),
+ min(_old_vehicle_coords.top,v->top_coord),
+ max(_old_vehicle_coords.right,v->right_coord)+1,
+ max(_old_vehicle_coords.bottom,v->bottom_coord)+1
+ );
+}
+
+/* returns true if staying in the same tile */
+bool GetNewVehiclePos(const Vehicle *v, GetNewVehiclePosResult *gp)
+{
+ static const int8 _delta_coord[16] = {
+ -1,-1,-1, 0, 1, 1, 1, 0, /* x */
+ -1, 0, 1, 1, 1, 0,-1,-1, /* y */
+ };
+
+ int x = v->x_pos + _delta_coord[v->direction];
+ int y = v->y_pos + _delta_coord[v->direction + 8];
+
+ gp->x = x;
+ gp->y = y;
+ gp->old_tile = v->tile;
+ gp->new_tile = TileVirtXY(x, y);
+ return gp->old_tile == gp->new_tile;
+}
+
+static const Direction _new_direction_table[] = {
+ DIR_N , DIR_NW, DIR_W ,
+ DIR_NE, DIR_SE, DIR_SW,
+ DIR_E , DIR_SE, DIR_S
+};
+
+Direction GetDirectionTowards(const Vehicle* v, int x, int y)
+{
+ Direction dir;
+ DirDiff dirdiff;
+ int i = 0;
+
+ if (y >= v->y_pos) {
+ if (y != v->y_pos) i+=3;
+ i+=3;
+ }
+
+ if (x >= v->x_pos) {
+ if (x != v->x_pos) i++;
+ i++;
+ }
+
+ dir = v->direction;
+
+ dirdiff = DirDifference(_new_direction_table[i], dir);
+ if (dirdiff == DIRDIFF_SAME) return dir;
+ return ChangeDir(dir, dirdiff > DIRDIFF_REVERSE ? DIRDIFF_45LEFT : DIRDIFF_45RIGHT);
+}
+
+Trackdir GetVehicleTrackdir(const Vehicle* v)
+{
+ if (v->vehstatus & VS_CRASHED) return 0xFF;
+
+ switch (v->type) {
+ case VEH_Train:
+ if (v->u.rail.track == 0x80) /* We'll assume the train is facing outwards */
+ return DiagdirToDiagTrackdir(GetRailDepotDirection(v->tile)); /* Train in depot */
+
+ if (v->u.rail.track == 0x40) /* train in tunnel, so just use his direction and assume a diagonal track */
+ return DiagdirToDiagTrackdir(DirToDiagDir(v->direction));
+
+ return TrackDirectionToTrackdir(FIND_FIRST_BIT(v->u.rail.track),v->direction);
+
+ case VEH_Ship:
+ if (IsShipInDepot(v))
+ /* We'll assume the ship is facing outwards */
+ return DiagdirToDiagTrackdir(GetShipDepotDirection(v->tile));
+
+ return TrackDirectionToTrackdir(FIND_FIRST_BIT(v->u.ship.state),v->direction);
+
+ case VEH_Road:
+ if (IsRoadVehInDepot(v)) /* We'll assume the road vehicle is facing outwards */
+ return DiagdirToDiagTrackdir(GetRoadDepotDirection(v->tile));
+
+ if (IsRoadStopTile(v->tile)) /* We'll assume the road vehicle is facing outwards */
+ return DiagdirToDiagTrackdir(GetRoadStopDir(v->tile)); /* Road vehicle in a station */
+
+ /* If vehicle's state is a valid track direction (vehicle is not turning around) return it */
+ if ((v->u.road.state & 7) < 6) return v->u.road.state;
+
+ /* Vehicle is turning around, get the direction from vehicle's direction */
+ return DiagdirToDiagTrackdir(DirToDiagDir(v->direction));
+
+ /* case VEH_Aircraft: case VEH_Special: case VEH_Disaster: */
+ default: return 0xFF;
+ }
+}
+/* Return value has bit 0x2 set, when the vehicle enters a station. Then,
+ * result << 8 contains the id of the station entered. If the return value has
+ * bit 0x8 set, the vehicle could not and did not enter the tile. Are there
+ * other bits that can be set? */
+uint32 VehicleEnterTile(Vehicle *v, TileIndex tile, int x, int y)
+{
+ return _tile_type_procs[GetTileType(tile)]->vehicle_enter_tile_proc(v, tile, x, y);
+}
+
+UnitID GetFreeUnitNumber(byte type)
+{
+ UnitID unit, max = 0;
+ const Vehicle *u;
+ static bool *cache = NULL;
+ static UnitID gmax = 0;
+
+ switch (type) {
+ case VEH_Train: max = _patches.max_trains; break;
+ case VEH_Road: max = _patches.max_roadveh; break;
+ case VEH_Ship: max = _patches.max_ships; break;
+ case VEH_Aircraft: max = _patches.max_aircraft; break;
+ default: NOT_REACHED();
+ }
+
+ if (max == 0) {
+ /* we can't build any of this kind of vehicle, so we just return 1 instead of looking for a free number
+ * a max of 0 will cause the following code to write to a NULL pointer
+ * We know that 1 is bigger than the max allowed vehicle number, so it's the same as returning something, that is too big
+ */
+ return 1;
+ }
+
+ if (max > gmax) {
+ gmax = max;
+ free(cache);
+ cache = malloc((max + 1) * sizeof(*cache));
+ }
+
+ // Clear the cache
+ memset(cache, 0, (max + 1) * sizeof(*cache));
+
+ // Fill the cache
+ FOR_ALL_VEHICLES(u) {
+ if (u->type == type && u->owner == _current_player && u->unitnumber != 0 && u->unitnumber <= max)
+ cache[u->unitnumber] = true;
+ }
+
+ // Find the first unused unit number
+ for (unit = 1; unit <= max; unit++) {
+ if (!cache[unit]) break;
+ }
+
+ return unit;
+}
+
+static PalSpriteID GetEngineColourMap(EngineID engine_type, PlayerID player, EngineID parent_engine_type, CargoID cargo_type)
+{
+ SpriteID map;
+ const Player *p = GetPlayer(player);
+ LiveryScheme scheme = LS_DEFAULT;
+
+ /* The default livery is always available for use, but its in_use flag determines
+ * whether any _other_ liveries are in use. */
+ if (p->livery[LS_DEFAULT].in_use && (_patches.liveries == 2 || (_patches.liveries == 1 && player == _local_player))) {
+ /* Determine the livery scheme to use */
+ switch (GetEngine(engine_type)->type) {
+ case VEH_Train: {
+ switch (_engine_info[engine_type].railtype) {
+ case RAILTYPE_RAIL:
+ case RAILTYPE_ELECTRIC:
+ {
+ const RailVehicleInfo *rvi = RailVehInfo(engine_type);
+
+ if (cargo_type == CT_INVALID) cargo_type = rvi->cargo_type;
+ if (rvi->flags & RVI_WAGON) {
+ if (cargo_type == CT_PASSENGERS || cargo_type == CT_MAIL || cargo_type == CT_VALUABLES) {
+ if (parent_engine_type == INVALID_ENGINE) {
+ scheme = LS_PASSENGER_WAGON_STEAM;
+ } else {
+ switch (RailVehInfo(parent_engine_type)->engclass) {
+ case 0: scheme = LS_PASSENGER_WAGON_STEAM; break;
+ case 1: scheme = LS_PASSENGER_WAGON_DIESEL; break;
+ case 2: scheme = LS_PASSENGER_WAGON_ELECTRIC; break;
+ }
+ }
+ } else {
+ scheme = LS_FREIGHT_WAGON;
+ }
+ } else {
+ bool is_mu = HASBIT(_engine_info[engine_type].misc_flags, EF_RAIL_IS_MU);
+
+ switch (rvi->engclass) {
+ case 0: scheme = LS_STEAM; break;
+ case 1: scheme = is_mu ? LS_DMU : LS_DIESEL; break;
+ case 2: scheme = is_mu ? LS_EMU : LS_ELECTRIC; break;
+ }
+ }
+ break;
+ }
+
+ case RAILTYPE_MONO: scheme = LS_MONORAIL; break;
+ case RAILTYPE_MAGLEV: scheme = LS_MAGLEV; break;
+ }
+ break;
+ }
+
+ case VEH_Road: {
+ const RoadVehicleInfo *rvi = RoadVehInfo(engine_type);
+ if (cargo_type == CT_INVALID) cargo_type = rvi->cargo_type;
+ scheme = (cargo_type == CT_PASSENGERS) ? LS_BUS : LS_TRUCK;
+ break;
+ }
+
+ case VEH_Ship: {
+ const ShipVehicleInfo *svi = ShipVehInfo(engine_type);
+ if (cargo_type == CT_INVALID) cargo_type = svi->cargo_type;
+ scheme = (cargo_type == CT_PASSENGERS) ? LS_PASSENGER_SHIP : LS_FREIGHT_SHIP;
+ break;
+ }
+
+ case VEH_Aircraft: {
+ const AircraftVehicleInfo *avi = AircraftVehInfo(engine_type);
+ if (cargo_type == CT_INVALID) cargo_type = CT_PASSENGERS;
+ switch (avi->subtype) {
+ case 0: scheme = LS_HELICOPTER; break;
+ case 1: scheme = LS_SMALL_PLANE; break;
+ case 3: scheme = LS_LARGE_PLANE; break;
+ }
+ break;
+ }
+ }
+
+ /* Switch back to the default scheme if the resolved scheme is not in use */
+ if (!p->livery[scheme].in_use) scheme = LS_DEFAULT;
+ }
+
+ map = HASBIT(EngInfo(engine_type)->misc_flags, EF_USES_2CC) ?
+ (SPR_2CCMAP_BASE + p->livery[scheme].colour1 + p->livery[scheme].colour2 * 16) :
+ (PALETTE_RECOLOR_START + p->livery[scheme].colour1);
+
+ return SPRITE_PALETTE(map << PALETTE_SPRITE_START);
+}
+
+PalSpriteID GetEnginePalette(EngineID engine_type, PlayerID player)
+{
+ return GetEngineColourMap(engine_type, player, INVALID_ENGINE, CT_INVALID);
+}
+
+PalSpriteID GetVehiclePalette(const Vehicle *v)
+{
+ if (v->type == VEH_Train) {
+ return GetEngineColourMap(
+ (v->u.rail.first_engine != INVALID_ENGINE && (IsArticulatedPart(v) || UsesWagonOverride(v))) ?
+ v->u.rail.first_engine : v->engine_type,
+ v->owner,
+ v->u.rail.first_engine,
+ v->cargo_type);
+ }
+
+ return GetEngineColourMap(v->engine_type, v->owner, INVALID_ENGINE, v->cargo_type);
+}
+
+// Save and load of vehicles
+const SaveLoad _common_veh_desc[] = {
+ SLE_VAR(Vehicle, subtype, SLE_UINT8),
+
+ SLE_REF(Vehicle, next, REF_VEHICLE_OLD),
+ SLE_VAR(Vehicle, string_id, SLE_STRINGID),
+ SLE_CONDVAR(Vehicle, unitnumber, SLE_FILE_U8 | SLE_VAR_U16, 0, 7),
+ SLE_CONDVAR(Vehicle, unitnumber, SLE_UINT16, 8, SL_MAX_VERSION),
+ SLE_VAR(Vehicle, owner, SLE_UINT8),
+ SLE_CONDVAR(Vehicle, tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+ SLE_CONDVAR(Vehicle, tile, SLE_UINT32, 6, SL_MAX_VERSION),
+ SLE_CONDVAR(Vehicle, dest_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+ SLE_CONDVAR(Vehicle, dest_tile, SLE_UINT32, 6, SL_MAX_VERSION),
+
+ SLE_CONDVAR(Vehicle, x_pos, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+ SLE_CONDVAR(Vehicle, x_pos, SLE_UINT32, 6, SL_MAX_VERSION),
+ SLE_CONDVAR(Vehicle, y_pos, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+ SLE_CONDVAR(Vehicle, y_pos, SLE_UINT32, 6, SL_MAX_VERSION),
+ SLE_VAR(Vehicle, z_pos, SLE_UINT8),
+ SLE_VAR(Vehicle, direction, SLE_UINT8),
+
+ SLE_VAR(Vehicle, cur_image, SLE_UINT16),
+ SLE_VAR(Vehicle, spritenum, SLE_UINT8),
+ SLE_VAR(Vehicle, sprite_width, SLE_UINT8),
+ SLE_VAR(Vehicle, sprite_height, SLE_UINT8),
+ SLE_VAR(Vehicle, z_height, SLE_UINT8),
+ SLE_VAR(Vehicle, x_offs, SLE_INT8),
+ SLE_VAR(Vehicle, y_offs, SLE_INT8),
+ SLE_VAR(Vehicle, engine_type, SLE_UINT16),
+
+ SLE_VAR(Vehicle, max_speed, SLE_UINT16),
+ SLE_VAR(Vehicle, cur_speed, SLE_UINT16),
+ SLE_VAR(Vehicle, subspeed, SLE_UINT8),
+ SLE_VAR(Vehicle, acceleration, SLE_UINT8),
+ SLE_VAR(Vehicle, progress, SLE_UINT8),
+
+ SLE_VAR(Vehicle, vehstatus, SLE_UINT8),
+ SLE_CONDVAR(Vehicle, last_station_visited, SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
+ SLE_CONDVAR(Vehicle, last_station_visited, SLE_UINT16, 5, SL_MAX_VERSION),
+
+ SLE_VAR(Vehicle, cargo_type, SLE_UINT8),
+ SLE_CONDVAR(Vehicle, cargo_subtype, SLE_UINT8, 35, SL_MAX_VERSION),
+ SLE_VAR(Vehicle, cargo_days, SLE_UINT8),
+ SLE_CONDVAR(Vehicle, cargo_source, SLE_FILE_U8 | SLE_VAR_U16, 0, 6),
+ SLE_CONDVAR(Vehicle, cargo_source, SLE_UINT16, 7, SL_MAX_VERSION),
+ SLE_VAR(Vehicle, cargo_cap, SLE_UINT16),
+ SLE_VAR(Vehicle, cargo_count, SLE_UINT16),
+
+ SLE_VAR(Vehicle, day_counter, SLE_UINT8),
+ SLE_VAR(Vehicle, tick_counter, SLE_UINT8),
+
+ SLE_VAR(Vehicle, cur_order_index, SLE_UINT8),
+ SLE_VAR(Vehicle, num_orders, SLE_UINT8),
+
+ /* This next line is for version 4 and prior compatibility.. it temporarily reads
+ type and flags (which were both 4 bits) into type. Later on this is
+ converted correctly */
+ SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, type), SLE_UINT8, 0, 4),
+ SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
+
+ /* Orders for version 5 and on */
+ SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, type), SLE_UINT8, 5, SL_MAX_VERSION),
+ SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, flags), SLE_UINT8, 5, SL_MAX_VERSION),
+ SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, dest), SLE_UINT16, 5, SL_MAX_VERSION),
+
+ /* Refit in current order */
+ SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, refit_cargo), SLE_UINT8, 36, SL_MAX_VERSION),
+ SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, refit_subtype), SLE_UINT8, 36, SL_MAX_VERSION),
+
+ SLE_REF(Vehicle, orders, REF_ORDER),
+
+ SLE_CONDVAR(Vehicle, age, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
+ SLE_CONDVAR(Vehicle, age, SLE_INT32, 31, SL_MAX_VERSION),
+ SLE_CONDVAR(Vehicle, max_age, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
+ SLE_CONDVAR(Vehicle, max_age, SLE_INT32, 31, SL_MAX_VERSION),
+ SLE_CONDVAR(Vehicle, date_of_last_service, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
+ SLE_CONDVAR(Vehicle, date_of_last_service, SLE_INT32, 31, SL_MAX_VERSION),
+ SLE_CONDVAR(Vehicle, service_interval, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
+ SLE_CONDVAR(Vehicle, service_interval, SLE_INT32, 31, SL_MAX_VERSION),
+ SLE_VAR(Vehicle, reliability, SLE_UINT16),
+ SLE_VAR(Vehicle, reliability_spd_dec, SLE_UINT16),
+ SLE_VAR(Vehicle, breakdown_ctr, SLE_UINT8),
+ SLE_VAR(Vehicle, breakdown_delay, SLE_UINT8),
+ SLE_VAR(Vehicle, breakdowns_since_last_service, SLE_UINT8),
+ SLE_VAR(Vehicle, breakdown_chance, SLE_UINT8),
+ SLE_CONDVAR(Vehicle, build_year, SLE_FILE_U8 | SLE_VAR_I32, 0, 30),
+ SLE_CONDVAR(Vehicle, build_year, SLE_INT32, 31, SL_MAX_VERSION),
+
+ SLE_VAR(Vehicle, load_unload_time_rem, SLE_UINT16),
+ SLE_CONDVAR(Vehicle, load_status, SLE_UINT8, 40, SL_MAX_VERSION),
+
+ SLE_VAR(Vehicle, profit_this_year, SLE_INT32),
+ SLE_VAR(Vehicle, profit_last_year, SLE_INT32),
+ SLE_VAR(Vehicle, value, SLE_UINT32),
+
+ SLE_VAR(Vehicle, random_bits, SLE_UINT8),
+ SLE_VAR(Vehicle, waiting_triggers, SLE_UINT8),
+
+ SLE_REF(Vehicle, next_shared, REF_VEHICLE),
+ SLE_REF(Vehicle, prev_shared, REF_VEHICLE),
+
+ // reserve extra space in savegame here. (currently 10 bytes)
+ SLE_CONDNULL(10, 2, SL_MAX_VERSION),
+
+ SLE_END()
+};
+
+
+static const SaveLoad _train_desc[] = {
+ SLE_WRITEBYTE(Vehicle, type, VEH_Train, 0), // Train type. VEH_Train in mem, 0 in file.
+ SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
+ SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRail, crash_anim_pos), SLE_UINT16),
+ SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRail, force_proceed), SLE_UINT8),
+ SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRail, railtype), SLE_UINT8),
+ SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRail, track), SLE_UINT8),
+
+ SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleRail, flags), SLE_UINT8, 2, SL_MAX_VERSION),
+ SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleRail, days_since_order_progr), SLE_UINT16, 2, SL_MAX_VERSION),
+
+ SLE_CONDNULL(2, 2, 19),
+ // reserve extra space in savegame here. (currently 11 bytes)
+ SLE_CONDNULL(11, 2, SL_MAX_VERSION),
+
+ SLE_END()
+};
+
+static const SaveLoad _roadveh_desc[] = {
+ SLE_WRITEBYTE(Vehicle, type, VEH_Road, 1), // Road type. VEH_Road in mem, 1 in file.
+ SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
+ SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, state), SLE_UINT8),
+ SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, frame), SLE_UINT8),
+ SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, blocked_ctr), SLE_UINT16),
+ SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, overtaking), SLE_UINT8),
+ SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, overtaking_ctr), SLE_UINT8),
+ SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, crashed_ctr), SLE_UINT16),
+ SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, reverse_ctr), SLE_UINT8),
+
+ SLE_CONDREFX(offsetof(Vehicle, u) + offsetof(VehicleRoad, slot), REF_ROADSTOPS, 6, SL_MAX_VERSION),
+ SLE_CONDNULL(1, 6, SL_MAX_VERSION),
+ SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, slot_age), SLE_UINT8, 6, SL_MAX_VERSION),
+ // reserve extra space in savegame here. (currently 16 bytes)
+ SLE_CONDNULL(16, 2, SL_MAX_VERSION),
+
+ SLE_END()
+};
+
+static const SaveLoad _ship_desc[] = {
+ SLE_WRITEBYTE(Vehicle, type, VEH_Ship, 2), // Ship type. VEH_Ship in mem, 2 in file.
+ SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
+ SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleShip, state), SLE_UINT8),
+
+ // reserve extra space in savegame here. (currently 16 bytes)
+ SLE_CONDNULL(16, 2, SL_MAX_VERSION),
+
+ SLE_END()
+};
+
+static const SaveLoad _aircraft_desc[] = {
+ SLE_WRITEBYTE(Vehicle, type, VEH_Aircraft, 3), // Aircraft type. VEH_Aircraft in mem, 3 in file.
+ SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
+ SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleAir, crashed_counter), SLE_UINT16),
+ SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleAir, pos), SLE_UINT8),
+
+ SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleAir, targetairport), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
+ SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleAir, targetairport), SLE_UINT16, 5, SL_MAX_VERSION),
+
+ SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleAir, state), SLE_UINT8),
+
+ SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleAir, previous_pos), SLE_UINT8, 2, SL_MAX_VERSION),
+
+ // reserve extra space in savegame here. (currently 15 bytes)
+ SLE_CONDNULL(15, 2, SL_MAX_VERSION),
+
+ SLE_END()
+};
+
+static const SaveLoad _special_desc[] = {
+ SLE_WRITEBYTE(Vehicle,type,VEH_Special, 4),
+
+ SLE_VAR(Vehicle, subtype, SLE_UINT8),
+
+ SLE_CONDVAR(Vehicle, tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+ SLE_CONDVAR(Vehicle, tile, SLE_UINT32, 6, SL_MAX_VERSION),
+
+ SLE_CONDVAR(Vehicle, x_pos, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
+ SLE_CONDVAR(Vehicle, x_pos, SLE_INT32, 6, SL_MAX_VERSION),
+ SLE_CONDVAR(Vehicle, y_pos, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
+ SLE_CONDVAR(Vehicle, y_pos, SLE_INT32, 6, SL_MAX_VERSION),
+ SLE_VAR(Vehicle, z_pos, SLE_UINT8),
+
+ SLE_VAR(Vehicle, cur_image, SLE_UINT16),
+ SLE_VAR(Vehicle, sprite_width, SLE_UINT8),
+ SLE_VAR(Vehicle, sprite_height, SLE_UINT8),
+ SLE_VAR(Vehicle, z_height, SLE_UINT8),
+ SLE_VAR(Vehicle, x_offs, SLE_INT8),
+ SLE_VAR(Vehicle, y_offs, SLE_INT8),
+ SLE_VAR(Vehicle, progress, SLE_UINT8),
+ SLE_VAR(Vehicle, vehstatus, SLE_UINT8),
+
+ SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleSpecial, unk0), SLE_UINT16),
+ SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleSpecial, unk2), SLE_UINT8),
+
+ // reserve extra space in savegame here. (currently 16 bytes)
+ SLE_CONDNULL(16, 2, SL_MAX_VERSION),
+
+ SLE_END()
+};
+
+static const SaveLoad _disaster_desc[] = {
+ SLE_WRITEBYTE(Vehicle, type, VEH_Disaster, 5),
+
+ SLE_REF(Vehicle, next, REF_VEHICLE_OLD),
+
+ SLE_VAR(Vehicle, subtype, SLE_UINT8),
+ SLE_CONDVAR(Vehicle, tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+ SLE_CONDVAR(Vehicle, tile, SLE_UINT32, 6, SL_MAX_VERSION),
+ SLE_CONDVAR(Vehicle, dest_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+ SLE_CONDVAR(Vehicle, dest_tile, SLE_UINT32, 6, SL_MAX_VERSION),
+
+ SLE_CONDVAR(Vehicle, x_pos, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
+ SLE_CONDVAR(Vehicle, x_pos, SLE_INT32, 6, SL_MAX_VERSION),
+ SLE_CONDVAR(Vehicle, y_pos, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
+ SLE_CONDVAR(Vehicle, y_pos, SLE_INT32, 6, SL_MAX_VERSION),
+ SLE_VAR(Vehicle, z_pos, SLE_UINT8),
+ SLE_VAR(Vehicle, direction, SLE_UINT8),
+
+ SLE_VAR(Vehicle, x_offs, SLE_INT8),
+ SLE_VAR(Vehicle, y_offs, SLE_INT8),
+ SLE_VAR(Vehicle, sprite_width, SLE_UINT8),
+ SLE_VAR(Vehicle, sprite_height, SLE_UINT8),
+ SLE_VAR(Vehicle, z_height, SLE_UINT8),
+ SLE_VAR(Vehicle, owner, SLE_UINT8),
+ SLE_VAR(Vehicle, vehstatus, SLE_UINT8),
+ SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
+ SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, dest), SLE_UINT16, 5, SL_MAX_VERSION),
+
+ SLE_VAR(Vehicle, cur_image, SLE_UINT16),
+ SLE_CONDVAR(Vehicle, age, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
+ SLE_CONDVAR(Vehicle, age, SLE_INT32, 31, SL_MAX_VERSION),
+ SLE_VAR(Vehicle, tick_counter, SLE_UINT8),
+
+ SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleDisaster, image_override), SLE_UINT16),
+ SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleDisaster, unk2), SLE_UINT16),
+
+ // reserve extra space in savegame here. (currently 16 bytes)
+ SLE_CONDNULL(16, 2, SL_MAX_VERSION),
+
+ SLE_END()
+};
+
+
+static const void *_veh_descs[] = {
+ _train_desc,
+ _roadveh_desc,
+ _ship_desc,
+ _aircraft_desc,
+ _special_desc,
+ _disaster_desc,
+};
+
+// Will be called when the vehicles need to be saved.
+static void Save_VEHS(void)
+{
+ Vehicle *v;
+ // Write the vehicles
+ FOR_ALL_VEHICLES(v) {
+ SlSetArrayIndex(v->index);
+ SlObject(v, _veh_descs[v->type - 0x10]);
+ }
+}
+
+// Will be called when vehicles need to be loaded.
+static void Load_VEHS(void)
+{
+ int index;
+ Vehicle *v;
+
+ while ((index = SlIterateArray()) != -1) {
+ Vehicle *v;
+
+ if (!AddBlockIfNeeded(&_Vehicle_pool, index))
+ error("Vehicles: failed loading savegame: too many vehicles");
+
+ v = GetVehicle(index);
+ SlObject(v, _veh_descs[SlReadByte()]);
+
+ /* Old savegames used 'last_station_visited = 0xFF' */
+ if (CheckSavegameVersion(5) && v->last_station_visited == 0xFF)
+ v->last_station_visited = INVALID_STATION;
+
+ if (CheckSavegameVersion(5)) {
+ /* Convert the current_order.type (which is a mix of type and flags, because
+ * in those versions, they both were 4 bits big) to type and flags */
+ v->current_order.flags = (v->current_order.type & 0xF0) >> 4;
+ v->current_order.type = v->current_order.type & 0x0F;
+ }
+ }
+
+ /* Check for shared order-lists (we now use pointers for that) */
+ if (CheckSavegameVersionOldStyle(5, 2)) {
+ FOR_ALL_VEHICLES(v) {
+ Vehicle *u;
+
+ FOR_ALL_VEHICLES_FROM(u, v->index + 1) {
+ /* If a vehicle has the same orders, add the link to eachother
+ * in both vehicles */
+ if (v->orders == u->orders) {
+ v->next_shared = u;
+ u->prev_shared = v;
+ break;
+ }
+ }
+ }
+ }
+}
+
+const ChunkHandler _veh_chunk_handlers[] = {
+ { 'VEHS', Save_VEHS, Load_VEHS, CH_SPARSE_ARRAY | CH_LAST},
+};
diff --git a/src/vehicle.h b/src/vehicle.h
new file mode 100644
index 000000000..10ca04903
--- /dev/null
+++ b/src/vehicle.h
@@ -0,0 +1,484 @@
+/* $Id$ */
+
+#ifndef VEHICLE_H
+#define VEHICLE_H
+
+#include "oldpool.h"
+#include "order.h"
+#include "rail.h"
+
+enum {
+ VEH_Invalid = 0x00,
+ VEH_Train = 0x10,
+ VEH_Road = 0x11,
+ VEH_Ship = 0x12,
+ VEH_Aircraft = 0x13,
+ VEH_Special = 0x14,
+ VEH_Disaster = 0x15,
+} ;
+
+enum VehStatus {
+ VS_HIDDEN = 0x01,
+ VS_STOPPED = 0x02,
+ VS_UNCLICKABLE = 0x04,
+ VS_DEFPAL = 0x08,
+ VS_TRAIN_SLOWING = 0x10,
+ VS_SHADOW = 0x20,
+ VS_AIRCRAFT_BROKEN = 0x40,
+ VS_CRASHED = 0x80,
+};
+
+enum LoadStatus {
+ LS_LOADING_FINISHED,
+ LS_CARGO_UNLOADING,
+ LS_CARGO_PAID_FOR,
+};
+
+/* Effect vehicle types */
+typedef enum EffectVehicle {
+ EV_CHIMNEY_SMOKE = 0,
+ EV_STEAM_SMOKE = 1,
+ EV_DIESEL_SMOKE = 2,
+ EV_ELECTRIC_SPARK = 3,
+ EV_SMOKE = 4,
+ EV_EXPLOSION_LARGE = 5,
+ EV_BREAKDOWN_SMOKE = 6,
+ EV_EXPLOSION_SMALL = 7,
+ EV_BULLDOZER = 8,
+ EV_BUBBLE = 9
+} EffectVehicle;
+
+typedef struct VehicleRail {
+ uint16 last_speed; // NOSAVE: only used in UI
+ uint16 crash_anim_pos;
+ uint16 days_since_order_progr;
+
+ // cached values, recalculated on load and each time a vehicle is added to/removed from the consist.
+ uint16 cached_max_speed; // max speed of the consist. (minimum of the max speed of all vehicles in the consist)
+ uint32 cached_power; // total power of the consist.
+ uint8 cached_veh_length; // length of this vehicle in units of 1/8 of normal length, cached because this can be set by a callback
+ uint16 cached_total_length; ///< Length of the whole train, valid only for first engine.
+
+ // cached values, recalculated when the cargo on a train changes (in addition to the conditions above)
+ uint32 cached_weight; // total weight of the consist.
+ uint32 cached_veh_weight; // weight of the vehicle.
+ uint32 cached_max_te; // max tractive effort of consist
+ /**
+ * Position/type of visual effect.
+ * bit 0 - 3 = position of effect relative to vehicle. (0 = front, 8 = centre, 15 = rear)
+ * bit 4 - 5 = type of effect. (0 = default for engine class, 1 = steam, 2 = diesel, 3 = electric)
+ * bit 6 = disable visual effect.
+ * bit 7 = disable powered wagons.
+ */
+ byte cached_vis_effect;
+
+ // NOSAVE: for wagon override - id of the first engine in train
+ // 0xffff == not in train
+ EngineID first_engine;
+
+ byte track;
+ byte force_proceed;
+ byte railtype;
+ RailTypeMask compatible_railtypes;
+
+ byte flags;
+
+ // Link between the two ends of a multiheaded engine
+ Vehicle *other_multiheaded_part;
+} VehicleRail;
+
+enum {
+ VRF_REVERSING = 0,
+
+ // used to calculate if train is going up or down
+ VRF_GOINGUP = 1,
+ VRF_GOINGDOWN = 2,
+
+ // used to store if a wagon is powered or not
+ VRF_POWEREDWAGON = 3,
+
+ // used to reverse the visible direction of the vehicle
+ VRF_REVERSE_DIRECTION = 4,
+
+ // used to mark train as lost because PF can't find the route
+ VRF_NO_PATH_TO_DESTINATION = 5,
+
+ // used to mark that electric train engine is allowed to run on normal rail
+ VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL = 6,
+};
+
+typedef struct VehicleAir {
+ uint16 crashed_counter;
+ byte pos;
+ byte previous_pos;
+ StationID targetairport;
+ byte state;
+} VehicleAir;
+
+typedef struct VehicleRoad {
+ byte state;
+ byte frame;
+ uint16 blocked_ctr;
+ byte overtaking;
+ byte overtaking_ctr;
+ uint16 crashed_ctr;
+ byte reverse_ctr;
+ struct RoadStop *slot;
+ byte slot_age;
+} VehicleRoad;
+
+typedef struct VehicleSpecial {
+ uint16 unk0;
+ byte unk2;
+} VehicleSpecial;
+
+typedef struct VehicleDisaster {
+ uint16 image_override;
+ uint16 unk2;
+} VehicleDisaster;
+
+typedef struct VehicleShip {
+ byte state;
+} VehicleShip;
+
+
+struct Vehicle {
+ byte type; // type, ie roadven,train,ship,aircraft,special
+ byte subtype; // subtype (Filled with values from EffectVehicles or TrainSubTypes)
+
+ VehicleID index; // NOSAVE: Index in vehicle array
+
+ Vehicle *next; // next
+ Vehicle *first; // NOSAVE: pointer to the first vehicle in the chain
+ Vehicle *depot_list; //NOSAVE: linked list to tell what vehicles entered a depot during the last tick. Used by autoreplace
+
+ StringID string_id; // Displayed string
+
+ UnitID unitnumber; // unit number, for display purposes only
+ PlayerID owner; // which player owns the vehicle?
+
+ TileIndex tile; // Current tile index
+ TileIndex dest_tile; // Heading for this tile
+
+ int32 x_pos; // coordinates
+ int32 y_pos;
+ byte z_pos;
+ byte direction; // facing
+
+ byte spritenum; // currently displayed sprite index
+ // 0xfd == custom sprite, 0xfe == custom second head sprite
+ // 0xff == reserved for another custom sprite
+ uint16 cur_image; // sprite number for this vehicle
+ byte sprite_width; // width of vehicle sprite
+ byte sprite_height; // height of vehicle sprite
+ byte z_height; // z-height of vehicle sprite
+ int8 x_offs; // x offset for vehicle sprite
+ int8 y_offs; // y offset for vehicle sprite
+ EngineID engine_type;
+
+ // for randomized variational spritegroups
+ // bitmask used to resolve them; parts of it get reseeded when triggers
+ // of corresponding spritegroups get matched
+ byte random_bits;
+ byte waiting_triggers; // triggers to be yet matched
+
+ uint16 max_speed; // maximum speed
+ uint16 cur_speed; // current speed
+ byte subspeed; // fractional speed
+ byte acceleration; // used by train & aircraft
+ byte progress;
+ uint32 motion_counter;
+
+ byte vehstatus; // Status
+ StationID last_station_visited;
+
+ CargoID cargo_type; // type of cargo this vehicle is carrying
+ byte cargo_days; // how many days have the pieces been in transit
+ StationID cargo_source; // source of cargo
+ uint16 cargo_cap; // total capacity
+ uint16 cargo_count; // how many pieces are used
+ byte cargo_subtype; ///< Used for livery refits (NewGRF variations)
+
+ byte day_counter; // increased by one for each day
+ byte tick_counter; // increased by one for each tick
+
+ /* Begin Order-stuff */
+ Order current_order; ///< The current order (+ status, like: loading)
+ VehicleOrderID cur_order_index; ///< The index to the current order
+
+ Order *orders; ///< Pointer to the first order for this vehicle
+ VehicleOrderID num_orders; ///< How many orders there are in the list
+
+ Vehicle *next_shared; ///< If not NULL, this points to the next vehicle that shared the order
+ Vehicle *prev_shared; ///< If not NULL, this points to the prev vehicle that shared the order
+ /* End Order-stuff */
+
+ // Boundaries for the current position in the world and a next hash link.
+ // NOSAVE: All of those can be updated with VehiclePositionChanged()
+ int32 left_coord;
+ int32 top_coord;
+ int32 right_coord;
+ int32 bottom_coord;
+ VehicleID next_hash;
+
+ // Related to age and service time
+ Date age; // Age in days
+ Date max_age; // Maximum age
+ Date date_of_last_service;
+ Date service_interval;
+ uint16 reliability;
+ uint16 reliability_spd_dec;
+ byte breakdown_ctr;
+ byte breakdown_delay;
+ byte breakdowns_since_last_service;
+ byte breakdown_chance;
+ Year build_year;
+
+ bool leave_depot_instantly; // NOSAVE: stores if the vehicle needs to leave the depot it just entered. Used by autoreplace
+
+ uint16 load_unload_time_rem;
+ byte load_status;
+
+ int32 profit_this_year;
+ int32 profit_last_year;
+ uint32 value;
+
+ union {
+ VehicleRail rail;
+ VehicleAir air;
+ VehicleRoad road;
+ VehicleSpecial special;
+ VehicleDisaster disaster;
+ VehicleShip ship;
+ } u;
+};
+
+#define is_custom_sprite(x) (x >= 0xFD)
+#define IS_CUSTOM_FIRSTHEAD_SPRITE(x) (x == 0xFD)
+#define IS_CUSTOM_SECONDHEAD_SPRITE(x) (x == 0xFE)
+
+typedef void *VehicleFromPosProc(Vehicle *v, void *data);
+
+void VehicleServiceInDepot(Vehicle *v);
+Vehicle *AllocateVehicle(void);
+bool AllocateVehicles(Vehicle **vl, int num);
+Vehicle *ForceAllocateVehicle(void);
+Vehicle *ForceAllocateSpecialVehicle(void);
+void VehiclePositionChanged(Vehicle *v);
+void AfterLoadVehicles(void);
+Vehicle *GetLastVehicleInChain(Vehicle *v);
+Vehicle *GetPrevVehicleInChain(const Vehicle *v);
+Vehicle *GetFirstVehicleInChain(const Vehicle *v);
+uint CountVehiclesInChain(const Vehicle* v);
+bool IsEngineCountable(const Vehicle *v);
+void DeleteVehicleChain(Vehicle *v);
+void *VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc);
+void CallVehicleTicks(void);
+Vehicle *FindVehicleOnTileZ(TileIndex tile, byte z);
+
+void InitializeTrains(void);
+byte VehicleRandomBits(void);
+void ResetVehiclePosHash(void);
+
+bool CanFillVehicle(Vehicle *v);
+bool CanRefitTo(EngineID engine_type, CargoID cid_to);
+CargoID FindFirstRefittableCargo(EngineID engine_type);
+int32 GetRefitCost(EngineID engine_type);
+
+void ViewportAddVehicles(DrawPixelInfo *dpi);
+
+/* train_cmd.h */
+int GetTrainImage(const Vehicle* v, Direction direction);
+int GetAircraftImage(const Vehicle* v, Direction direction);
+int GetRoadVehImage(const Vehicle* v, Direction direction);
+int GetShipImage(const Vehicle* v, Direction direction);
+
+Vehicle *CreateEffectVehicle(int x, int y, int z, EffectVehicle type);
+Vehicle *CreateEffectVehicleAbove(int x, int y, int z, EffectVehicle type);
+Vehicle *CreateEffectVehicleRel(const Vehicle *v, int x, int y, int z, EffectVehicle type);
+
+uint32 VehicleEnterTile(Vehicle *v, TileIndex tile, int x, int y);
+
+StringID VehicleInTheWayErrMsg(const Vehicle* v);
+Vehicle *FindVehicleBetween(TileIndex from, TileIndex to, byte z);
+
+bool UpdateSignalsOnSegment(TileIndex tile, DiagDirection direction);
+void SetSignalsOnBothDir(TileIndex tile, byte track);
+
+Vehicle *CheckClickOnVehicle(const ViewPort *vp, int x, int y);
+
+void DecreaseVehicleValue(Vehicle *v);
+void CheckVehicleBreakdown(Vehicle *v);
+void AgeVehicle(Vehicle *v);
+void VehicleEnteredDepotThisTick(Vehicle *v);
+
+void BeginVehicleMove(Vehicle *v);
+void EndVehicleMove(Vehicle *v);
+
+void ShowAircraftViewWindow(const Vehicle* v);
+
+UnitID GetFreeUnitNumber(byte type);
+
+int LoadUnloadVehicle(Vehicle *v, bool just_arrived);
+
+void TrainConsistChanged(Vehicle *v);
+void TrainPowerChanged(Vehicle *v);
+int32 GetTrainRunningCost(const Vehicle *v);
+
+int CheckTrainStoppedInDepot(const Vehicle *v);
+
+bool VehicleNeedsService(const Vehicle *v);
+
+uint GenerateVehicleSortList(const Vehicle*** sort_list, uint16 *length_of_array, byte type, PlayerID owner, StationID station, OrderID order, uint16 depot_airport_index, uint16 window_type);
+void BuildDepotVehicleList(byte type, TileIndex tile, Vehicle ***engine_list, uint16 *engine_list_length, uint16 *engine_count, Vehicle ***wagon_list, uint16 *wagon_list_length, uint16 *wagon_count);
+int32 SendAllVehiclesToDepot(byte type, uint32 flags, bool service, PlayerID owner, uint16 vlw_flag, uint32 id);
+bool IsVehicleInDepot(const Vehicle *v);
+void VehicleEnterDepot(Vehicle *v);
+
+/* Flags to add to p2 for goto depot commands */
+/* Note: bits 8-10 are used for VLW flags */
+enum {
+ DEPOT_SERVICE = (1 << 0), // The vehicle will leave the depot right after arrival (serivce only)
+ DEPOT_MASS_SEND = (1 << 1), // Tells that it's a mass send to depot command (type in VLW flag)
+ DEPOT_DONT_CANCEL = (1 << 2), // Don't cancel current goto depot command if any
+ DEPOT_LOCATE_HANGAR = (1 << 3), // Find another airport if the target one lacks a hangar
+};
+
+typedef struct GetNewVehiclePosResult {
+ int x,y;
+ TileIndex old_tile;
+ TileIndex new_tile;
+} GetNewVehiclePosResult;
+
+/**
+ * Returns the Trackdir on which the vehicle is currently located.
+ * Works for trains and ships.
+ * Currently works only sortof for road vehicles, since they have a fuzzy
+ * concept of being "on" a trackdir. Dunno really what it returns for a road
+ * vehicle that is halfway a tile, never really understood that part. For road
+ * vehicles that are at the beginning or end of the tile, should just return
+ * the diagonal trackdir on which they are driving. I _think_.
+ * For other vehicles types, or vehicles with no clear trackdir (such as those
+ * in depots), returns 0xFF.
+ */
+Trackdir GetVehicleTrackdir(const Vehicle* v);
+
+/* returns true if staying in the same tile */
+bool GetNewVehiclePos(const Vehicle *v, GetNewVehiclePosResult *gp);
+Direction GetDirectionTowards(const Vehicle* v, int x, int y);
+
+#define BEGIN_ENUM_WAGONS(v) do {
+#define END_ENUM_WAGONS(v) } while ( (v=v->next) != NULL);
+
+DECLARE_OLD_POOL(Vehicle, Vehicle, 9, 125)
+
+static inline VehicleID GetMaxVehicleIndex(void)
+{
+ /* TODO - This isn't the real content of the function, but
+ * with the new pool-system this will be replaced with one that
+ * _really_ returns the highest index. Now it just returns
+ * the next safe value we are sure about everything is below.
+ */
+ return GetVehiclePoolSize() - 1;
+}
+
+static inline uint GetNumVehicles(void)
+{
+ return GetVehiclePoolSize();
+}
+
+/**
+ * Check if a Vehicle really exists.
+ */
+static inline bool IsValidVehicle(const Vehicle *v)
+{
+ return v->type != 0;
+}
+
+void DestroyVehicle(Vehicle *v);
+
+static inline void DeleteVehicle(Vehicle *v)
+{
+ DestroyVehicle(v);
+ v->type = 0;
+}
+
+#define FOR_ALL_VEHICLES_FROM(v, start) for (v = GetVehicle(start); v != NULL; v = (v->index + 1U < GetVehiclePoolSize()) ? GetVehicle(v->index + 1) : NULL) if (IsValidVehicle(v))
+#define FOR_ALL_VEHICLES(v) FOR_ALL_VEHICLES_FROM(v, 0)
+
+/**
+ * Check if an index is a vehicle-index (so between 0 and max-vehicles)
+ *
+ * @return Returns true if the vehicle-id is in range
+ */
+static inline bool IsValidVehicleID(uint index)
+{
+ return index < GetVehiclePoolSize() && IsValidVehicle(GetVehicle(index));
+}
+
+/* Returns order 'index' of a vehicle or NULL when it doesn't exists */
+static inline Order *GetVehicleOrder(const Vehicle *v, int index)
+{
+ Order *order = v->orders;
+
+ if (index < 0) return NULL;
+
+ while (order != NULL && index-- > 0)
+ order = order->next;
+
+ return order;
+}
+
+/* Returns the last order of a vehicle, or NULL if it doesn't exists */
+static inline Order *GetLastVehicleOrder(const Vehicle *v)
+{
+ Order *order = v->orders;
+
+ if (order == NULL) return NULL;
+
+ while (order->next != NULL)
+ order = order->next;
+
+ return order;
+}
+
+/* Get the first vehicle of a shared-list, so we only have to walk forwards */
+static inline Vehicle *GetFirstVehicleFromSharedList(const Vehicle *v)
+{
+ Vehicle *u = (Vehicle *)v;
+ while (u->prev_shared != NULL) u = u->prev_shared;
+
+ return u;
+}
+
+// NOSAVE: Return values from various commands.
+VARDEF VehicleID _new_vehicle_id;
+VARDEF uint16 _returned_refit_capacity;
+
+enum {
+ INVALID_VEHICLE = 0xFFFF,
+};
+
+/**
+ * Get the colour map for an engine. This used for unbuilt engines in the user interface.
+ * @param engine_type ID of engine
+ * @param player ID of player
+ * @return A ready-to-use palette modifier
+ */
+PalSpriteID GetEnginePalette(EngineID engine_type, PlayerID player);
+
+/**
+ * Get the colour map for a vehicle.
+ * @param v Vehicle to get colour map for
+ * @return A ready-to-use palette modifier
+ */
+PalSpriteID GetVehiclePalette(const Vehicle *v);
+
+/* A lot of code calls for the invalidation of the status bar, which is widget 5.
+ * Best is to have a virtual value for it when it needs to change again */
+#define STATUS_BAR 5
+
+extern const uint32 _send_to_depot_proc_table[];
+#define CMD_SEND_TO_DEPOT(x) _send_to_depot_proc_table[ x - VEH_Train]
+
+#endif /* VEHICLE_H */
diff --git a/src/vehicle_gui.c b/src/vehicle_gui.c
new file mode 100644
index 000000000..1c3d45b82
--- /dev/null
+++ b/src/vehicle_gui.c
@@ -0,0 +1,1945 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "debug.h"
+#include "functions.h"
+#include "player.h"
+#include "station.h"
+#include "strings.h"
+#include "table/sprites.h"
+#include "table/strings.h"
+#include "vehicle.h"
+#include "window.h"
+#include "engine.h"
+#include "gui.h"
+#include "command.h"
+#include "gfx.h"
+#include "variables.h"
+#include "vehicle_gui.h"
+#include "viewport.h"
+#include "train.h"
+#include "newgrf_callbacks.h"
+#include "newgrf_engine.h"
+#include "newgrf_text.h"
+#include "date.h"
+#include "ship.h"
+#include "aircraft.h"
+#include "roadveh.h"
+#include "depot.h"
+
+typedef struct Sorting {
+ Listing aircraft;
+ Listing roadveh;
+ Listing ship;
+ Listing train;
+} Sorting;
+
+static Sorting _sorting;
+
+typedef struct vehiclelist_d {
+ const Vehicle** sort_list; // List of vehicles (sorted)
+ Listing *_sorting; // pointer to the appropiate subcategory of _sorting
+ uint16 length_of_sort_list; // Keeps track of how many vehicle pointers sort list got space for
+ byte vehicle_type; // The vehicle type that is sorted
+ list_d l; // General list struct
+} vehiclelist_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(vehiclelist_d));
+
+static bool _internal_sort_order; // descending/ascending
+
+static RailType _railtype_selected_in_replace_gui;
+
+
+typedef int CDECL VehicleSortListingTypeFunction(const void*, const void*);
+
+static VehicleSortListingTypeFunction VehicleNumberSorter;
+static VehicleSortListingTypeFunction VehicleNameSorter;
+static VehicleSortListingTypeFunction VehicleAgeSorter;
+static VehicleSortListingTypeFunction VehicleProfitThisYearSorter;
+static VehicleSortListingTypeFunction VehicleProfitLastYearSorter;
+static VehicleSortListingTypeFunction VehicleCargoSorter;
+static VehicleSortListingTypeFunction VehicleReliabilitySorter;
+static VehicleSortListingTypeFunction VehicleMaxSpeedSorter;
+static VehicleSortListingTypeFunction VehicleModelSorter;
+static VehicleSortListingTypeFunction VehicleValueSorter;
+
+static VehicleSortListingTypeFunction* const _vehicle_sorter[] = {
+ &VehicleNumberSorter,
+ &VehicleNameSorter,
+ &VehicleAgeSorter,
+ &VehicleProfitThisYearSorter,
+ &VehicleProfitLastYearSorter,
+ &VehicleCargoSorter,
+ &VehicleReliabilitySorter,
+ &VehicleMaxSpeedSorter,
+ &VehicleModelSorter,
+ &VehicleValueSorter,
+};
+
+static const StringID _vehicle_sort_listing[] = {
+ STR_SORT_BY_NUMBER,
+ STR_SORT_BY_DROPDOWN_NAME,
+ STR_SORT_BY_AGE,
+ STR_SORT_BY_PROFIT_THIS_YEAR,
+ STR_SORT_BY_PROFIT_LAST_YEAR,
+ STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE,
+ STR_SORT_BY_RELIABILITY,
+ STR_SORT_BY_MAX_SPEED,
+ STR_SORT_BY_MODEL,
+ STR_SORT_BY_VALUE,
+ INVALID_STRING_ID
+};
+
+static const StringID _rail_types_list[] = {
+ STR_RAIL_VEHICLES,
+ STR_ELRAIL_VEHICLES,
+ STR_MONORAIL_VEHICLES,
+ STR_MAGLEV_VEHICLES,
+ INVALID_STRING_ID
+};
+
+void RebuildVehicleLists(void)
+{
+ Window* const *wz;
+
+ FOR_ALL_WINDOWS(wz) {
+ Window *w = *wz;
+
+ switch (w->window_class) {
+ case WC_TRAINS_LIST:
+ case WC_ROADVEH_LIST:
+ case WC_SHIPS_LIST:
+ case WC_AIRCRAFT_LIST:
+ WP(w, vehiclelist_d).l.flags |= VL_REBUILD;
+ SetWindowDirty(w);
+ break;
+ }
+ }
+}
+
+void ResortVehicleLists(void)
+{
+ Window* const *wz;
+
+ FOR_ALL_WINDOWS(wz) {
+ Window *w = *wz;
+
+ switch (w->window_class) {
+ case WC_TRAINS_LIST:
+ case WC_ROADVEH_LIST:
+ case WC_SHIPS_LIST:
+ case WC_AIRCRAFT_LIST:
+ WP(w, vehiclelist_d).l.flags |= VL_RESORT;
+ SetWindowDirty(w);
+ break;
+ }
+ }
+}
+
+static void BuildVehicleList(vehiclelist_d* vl, PlayerID owner, StationID station, OrderID order, uint16 depot_airport_index, uint16 window_type)
+{
+ if (!(vl->l.flags & VL_REBUILD)) return;
+
+ DEBUG(misc, 3, "Building vehicle list for player %d at station %d", owner, station);
+
+ vl->l.list_length = GenerateVehicleSortList(&vl->sort_list, &vl->length_of_sort_list, vl->vehicle_type, owner, station, order, depot_airport_index, window_type);
+
+ vl->l.flags &= ~VL_REBUILD;
+ vl->l.flags |= VL_RESORT;
+}
+
+static void SortVehicleList(vehiclelist_d *vl)
+{
+ if (!(vl->l.flags & VL_RESORT)) return;
+
+ _internal_sort_order = vl->l.flags & VL_DESC;
+ qsort((void*)vl->sort_list, vl->l.list_length, sizeof(vl->sort_list[0]),
+ _vehicle_sorter[vl->l.sort_type]);
+
+ vl->l.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
+ vl->l.flags &= ~VL_RESORT;
+}
+
+void DepotSortList(Vehicle **v, uint16 length)
+{
+ _internal_sort_order = 0;
+ qsort((void*)v, length, sizeof(v[0]), _vehicle_sorter[0]);
+}
+
+/* General Vehicle GUI based procedures that are independent of vehicle types */
+void InitializeVehiclesGuiList(void)
+{
+ _railtype_selected_in_replace_gui = RAILTYPE_RAIL;
+}
+
+// draw the vehicle profit button in the vehicle list window.
+void DrawVehicleProfitButton(const Vehicle *v, int x, int y)
+{
+ uint32 ormod;
+
+ // draw profit-based colored icons
+ if (v->age <= 365 * 2) {
+ ormod = PALETTE_TO_GREY;
+ } else if (v->profit_last_year < 0) {
+ ormod = PALETTE_TO_RED;
+ } else if (v->profit_last_year < 10000) {
+ ormod = PALETTE_TO_YELLOW;
+ } else {
+ ormod = PALETTE_TO_GREEN;
+ }
+ DrawSprite(SPR_BLOT | ormod, x, y);
+}
+
+typedef struct RefitOption {
+ CargoID cargo;
+ byte subtype;
+ uint16 value;
+ EngineID engine;
+} RefitOption;
+
+typedef struct RefitList {
+ uint num_lines;
+ RefitOption *items;
+} RefitList;
+
+static RefitList *BuildRefitList(const Vehicle *v)
+{
+ uint max_lines = 256;
+ RefitOption *refit = calloc(max_lines, sizeof(*refit));
+ RefitList *list = calloc(1, sizeof(*list));
+ Vehicle *u = (Vehicle*)v;
+ uint num_lines = 0;
+ uint i;
+
+ do {
+ CargoID cid;
+ uint32 cmask = EngInfo(u->engine_type)->refit_mask;
+ byte callbackmask = EngInfo(u->engine_type)->callbackmask;
+
+ /* Skip this engine if it has no capacity */
+ if (u->cargo_cap == 0) continue;
+
+ /* Loop through all cargos in the refit mask */
+ for (cid = 0; cmask != 0 && num_lines < max_lines; cmask >>= 1, cid++) {
+ CargoID lcid;
+
+ /* Skip cargo type if it's not listed */
+ if (!HASBIT(cmask, 0)) continue;
+
+ lcid = _local_cargo_id_ctype[cid];
+ if (lcid == CT_INVALID) continue;
+
+ /* Check the vehicle's callback mask for cargo suffixes */
+ if (HASBIT(callbackmask, CBM_CARGO_SUFFIX)) {
+ /* Make a note of the original cargo type. It has to be
+ * changed to test the cargo & subtype... */
+ CargoID temp_cargo = u->cargo_type;
+ byte temp_subtype = u->cargo_subtype;
+ byte refit_cyc;
+
+ u->cargo_type = lcid;
+
+ for (refit_cyc = 0; refit_cyc < 16 && num_lines < max_lines; refit_cyc++) {
+ bool duplicate = false;
+ uint16 callback;
+
+ u->cargo_subtype = refit_cyc;
+ callback = GetVehicleCallback(CBID_VEHICLE_CARGO_SUFFIX, 0, 0, u->engine_type, u);
+
+ if (callback == 0xFF) callback = CALLBACK_FAILED;
+ if (refit_cyc != 0 && callback == CALLBACK_FAILED) break;
+
+ /* Check if this cargo and subtype combination are listed */
+ for (i = 0; i < num_lines && !duplicate; i++) {
+ if (refit[i].cargo == lcid && refit[i].value == callback) duplicate = true;
+ }
+
+ if (duplicate) continue;
+
+ refit[num_lines].cargo = lcid;
+ refit[num_lines].subtype = refit_cyc;
+ refit[num_lines].value = callback;
+ refit[num_lines].engine = u->engine_type;
+ num_lines++;
+ }
+
+ /* Reset the vehicle's cargo type */
+ u->cargo_type = temp_cargo;
+ u->cargo_subtype = temp_subtype;
+ } else {
+ /* No cargo suffix callback -- use no subtype */
+ bool duplicate = false;
+
+ for (i = 0; i < num_lines && !duplicate; i++) {
+ if (refit[i].cargo == lcid && refit[i].value == CALLBACK_FAILED) duplicate = true;
+ }
+
+ if (!duplicate) {
+ refit[num_lines].cargo = lcid;
+ refit[num_lines].subtype = 0;
+ refit[num_lines].value = CALLBACK_FAILED;
+ refit[num_lines].engine = INVALID_ENGINE;
+ num_lines++;
+ }
+ }
+ }
+ } while (v->type == VEH_Train && (u = u->next) != NULL && num_lines < max_lines);
+
+ list->num_lines = num_lines;
+ list->items = refit;
+
+ return list;
+}
+
+/** Draw the list of available refit options for a consist.
+ * Draw the list and highlight the selected refit option (if any)
+ * @param *v first vehicle in consist to get the refit-options of
+ * @param sel selected refit cargo-type in the window
+ * @return the refit option that is hightlighted, NULL if none
+ */
+static RefitOption *DrawVehicleRefitWindow(const RefitList *list, int sel, uint pos, uint rows, uint delta)
+{
+ RefitOption *refit = list->items;
+ RefitOption *selected = NULL;
+ uint num_lines = list->num_lines;
+ uint y = 31;
+ uint i;
+
+ /* Draw the list, and find the selected cargo (by its position in list) */
+ for (i = 0; i < num_lines; i++) {
+ byte colour = 16;
+ if (sel == 0) {
+ selected = &refit[i];
+ colour = 12;
+ }
+
+ if (i >= pos && i < pos + rows) {
+ /* Draw the cargo name */
+ int last_x = DrawString(2, y, _cargoc.names_s[refit[i].cargo], colour);
+
+ /* If the callback succeeded, draw the cargo suffix */
+ if (refit[i].value != CALLBACK_FAILED) {
+ DrawString(last_x + 1, y, GetGRFStringID(GetEngineGRFID(refit[i].engine), 0xD000 + refit[i].value), colour);
+ }
+ y += delta;
+ }
+
+ sel--;
+ }
+
+ return selected;
+}
+
+static void VehicleRefitWndProc(Window *w, WindowEvent *e)
+{
+ switch (e->event) {
+ case WE_PAINT: {
+ Vehicle *v = GetVehicle(w->window_number);
+
+ if (v->type == VEH_Train) {
+ uint length = CountVehiclesInChain(v);
+
+ if (length != WP(w, refit_d).length) {
+ /* Consist length has changed, so rebuild the refit list */
+ free(WP(w, refit_d).list->items);
+ free(WP(w, refit_d).list);
+ WP(w, refit_d).list = BuildRefitList(v);
+ WP(w, refit_d).length = length;
+ }
+ }
+
+ SetVScrollCount(w, WP(w, refit_d).list->num_lines);
+
+ SetDParam(0, v->string_id);
+ SetDParam(1, v->unitnumber);
+ DrawWindowWidgets(w);
+
+ WP(w,refit_d).cargo = DrawVehicleRefitWindow(WP(w, refit_d).list, WP(w, refit_d).sel, w->vscroll.pos, w->vscroll.cap, w->resize.step_height);
+
+ if (WP(w,refit_d).cargo != NULL) {
+ int32 cost = 0;
+ switch (GetVehicle(w->window_number)->type) {
+ case VEH_Train: cost = CMD_REFIT_RAIL_VEHICLE; break;
+ case VEH_Road: cost = CMD_REFIT_ROAD_VEH; break;
+ case VEH_Ship: cost = CMD_REFIT_SHIP; break;
+ case VEH_Aircraft: cost = CMD_REFIT_AIRCRAFT; break;
+ }
+
+ cost = DoCommand(v->tile, v->index, WP(w,refit_d).cargo->cargo | WP(w,refit_d).cargo->subtype << 8, DC_QUERY_COST, cost);
+ if (!CmdFailed(cost)) {
+ SetDParam(0, WP(w,refit_d).cargo->cargo);
+ SetDParam(1, _returned_refit_capacity);
+ SetDParam(2, cost);
+ DrawString(2, w->widget[5].top + 1, STR_9840_NEW_CAPACITY_COST_OF_REFIT, 0);
+ }
+ }
+ } break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case 3: { // listbox
+ int y = e->we.click.pt.y - w->widget[3].top;
+ if (y >= 0) {
+ WP(w,refit_d).sel = (y / (int)w->resize.step_height) + w->vscroll.pos;
+ SetWindowDirty(w);
+ }
+ } break;
+ case 6: // refit button
+ if (WP(w,refit_d).cargo != NULL) {
+ const Vehicle *v = GetVehicle(w->window_number);
+
+ if (WP(w, refit_d).order == INVALID_VEH_ORDER_ID) {
+ int command = 0;
+
+ switch (v->type) {
+ case VEH_Train: command = CMD_REFIT_RAIL_VEHICLE | CMD_MSG(STR_RAIL_CAN_T_REFIT_VEHICLE); break;
+ case VEH_Road: command = CMD_REFIT_ROAD_VEH | CMD_MSG(STR_REFIT_ROAD_VEHICLE_CAN_T); break;
+ case VEH_Ship: command = CMD_REFIT_SHIP | CMD_MSG(STR_9841_CAN_T_REFIT_SHIP); break;
+ case VEH_Aircraft: command = CMD_REFIT_AIRCRAFT | CMD_MSG(STR_A042_CAN_T_REFIT_AIRCRAFT); break;
+ }
+ if (DoCommandP(v->tile, v->index, WP(w,refit_d).cargo->cargo | WP(w,refit_d).cargo->subtype << 8, NULL, command)) DeleteWindow(w);
+ } else {
+ if (DoCommandP(v->tile, v->index, WP(w,refit_d).cargo->cargo | WP(w,refit_d).cargo->subtype << 8 | WP(w, refit_d).order << 16, NULL, CMD_ORDER_REFIT)) DeleteWindow(w);
+ }
+ }
+ break;
+ }
+ break;
+
+ case WE_RESIZE:
+ w->vscroll.cap += e->we.sizing.diff.y / (int)w->resize.step_height;
+ w->widget[3].data = (w->vscroll.cap << 8) + 1;
+ break;
+
+ case WE_DESTROY:
+ free(WP(w, refit_d).list->items);
+ free(WP(w, refit_d).list);
+ break;
+ }
+}
+
+
+static const Widget _vehicle_refit_widgets[] = {
+ { WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+ { WWT_CAPTION, RESIZE_NONE, 14, 11, 239, 0, 13, STR_983B_REFIT, STR_018C_WINDOW_TITLE_DRAG_THIS},
+ { WWT_TEXTBTN, RESIZE_NONE, 14, 0, 239, 14, 27, STR_983F_SELECT_CARGO_TYPE_TO_CARRY, STR_983D_SELECT_TYPE_OF_CARGO_FOR},
+ { WWT_MATRIX, RESIZE_BOTTOM, 14, 0, 227, 28, 139, 0x801, STR_EMPTY},
+ { WWT_SCROLLBAR, RESIZE_BOTTOM, 14, 228, 239, 28, 139, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+ { WWT_PANEL, RESIZE_TB, 14, 0, 239, 140, 161, 0x0, STR_NULL},
+ { WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 227, 162, 173, 0x0, STR_NULL},
+ { WWT_RESIZEBOX, RESIZE_TB, 14, 228, 239, 162, 173, 0x0, STR_RESIZE_BUTTON},
+ { WIDGETS_END},
+};
+
+static const WindowDesc _vehicle_refit_desc = {
+ WDP_AUTO, WDP_AUTO, 240, 174,
+ WC_VEHICLE_REFIT,WC_VEHICLE_VIEW,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
+ _vehicle_refit_widgets,
+ VehicleRefitWndProc,
+};
+
+/** Show the refit window for a vehicle
+* @param *v The vehicle to show the refit window for
+*/
+void ShowVehicleRefitWindow(const Vehicle *v, VehicleOrderID order)
+{
+ Window *w;
+
+ DeleteWindowById(WC_VEHICLE_REFIT, v->index);
+
+ w = AllocateWindowDescFront(&_vehicle_refit_desc, v->index);
+ WP(w, refit_d).order = order;
+
+ if (w != NULL) {
+ w->caption_color = v->owner;
+ w->vscroll.cap = 8;
+ w->resize.step_height = 14;
+ WP(w, refit_d).sel = -1;
+ WP(w, refit_d).list = BuildRefitList(v);
+ if (v->type == VEH_Train) WP(w, refit_d).length = CountVehiclesInChain(v);
+ SetVScrollCount(w, WP(w, refit_d).list->num_lines);
+
+ switch (v->type) {
+ case VEH_Train:
+ w->widget[3].tooltips = STR_RAIL_SELECT_TYPE_OF_CARGO_FOR;
+ w->widget[6].data = STR_RAIL_REFIT_VEHICLE;
+ w->widget[6].tooltips = STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED;
+ break;
+ case VEH_Road:
+ w->widget[3].tooltips = STR_ROAD_SELECT_TYPE_OF_CARGO_FOR;
+ w->widget[6].data = STR_REFIT_ROAD_VEHICLE;
+ w->widget[6].tooltips = STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED;
+ break;
+ case VEH_Ship:
+ w->widget[3].tooltips = STR_983D_SELECT_TYPE_OF_CARGO_FOR;
+ w->widget[6].data = STR_983C_REFIT_SHIP;
+ w->widget[6].tooltips = STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED;
+ break;
+ case VEH_Aircraft:
+ w->widget[3].tooltips = STR_A03E_SELECT_TYPE_OF_CARGO_FOR;
+ w->widget[6].data = STR_A03D_REFIT_AIRCRAFT;
+ w->widget[6].tooltips = STR_A03F_REFIT_AIRCRAFT_TO_CARRY;
+ break;
+ default: NOT_REACHED();
+ }
+ }
+}
+
+/* Display additional text from NewGRF in the purchase information window */
+uint ShowAdditionalText(int x, int y, uint w, EngineID engine)
+{
+ uint16 callback = GetVehicleCallback(CBID_VEHICLE_ADDITIONAL_TEXT, 0, 0, engine, NULL);
+ if (callback == CALLBACK_FAILED) return 0;
+
+ // STR_02BD is used to start the string with {BLACK}
+ SetDParam(0, GetGRFStringID(GetEngineGRFID(engine), 0xD000 + callback));
+ return DrawStringMultiLine(x, y, STR_02BD, w);
+}
+
+/* Count the number of bits that are set in a mask */
+static uint CountBits(uint32 mask)
+{
+ uint c = 0;
+ for (; mask != 0; mask >>= 1) if (HASBIT(mask, 0)) c++;
+ return c;
+}
+
+/* Display list of cargo types of the engine, for the purchase information window */
+uint ShowRefitOptionsList(int x, int y, uint w, EngineID engine)
+{
+ /* List of cargo types of this engine */
+ uint32 cmask = EngInfo(engine)->refit_mask;
+ /* List of cargo types available in this climate */
+ uint32 lmask = _landscape_global_cargo_mask[_opt.landscape];
+ char *b = _userstring;
+
+ /* Draw nothing if the engine is not refittable */
+ if (CountBits(cmask) <= 1) return 0;
+
+ b = InlineString(b, STR_PURCHASE_INFO_REFITTABLE_TO);
+
+ if (cmask == lmask) {
+ /* Engine can be refitted to all types in this climate */
+ b = InlineString(b, STR_PURCHASE_INFO_ALL_TYPES);
+ } else {
+ CargoID cid;
+
+ /* Check if we are able to refit to more cargo types and unable to. If
+ * so, invert the cargo types to list those that we can't refit to. */
+ if (CountBits(cmask ^ lmask) < CountBits(cmask)) {
+ cmask ^= lmask;
+ b = InlineString(b, STR_PURCHASE_INFO_ALL_BUT);
+ }
+
+ /* Add each cargo type to the list */
+ for (cid = 0; cmask != 0; cmask >>= 1, cid++) {
+ if (!HASBIT(cmask, 0)) continue;
+
+ b = InlineString(b, _cargoc.names_s[_local_cargo_id_ctype[cid]]);
+ if (cmask > 1) b = strecpy(b, ", ", lastof(_userstring));
+ }
+ }
+
+ /* Terminate and display the completed string */
+ *b = '\0';
+ return DrawStringMultiLine(x, y, STR_SPEC_USERSTRING, w);
+}
+
+
+// if the sorting criteria had the same value, sort vehicle by unitnumber
+#define VEHICLEUNITNUMBERSORTER(r, a, b) {if (r == 0) {r = a->unitnumber - b->unitnumber;}}
+
+static int CDECL VehicleNumberSorter(const void *a, const void *b)
+{
+ const Vehicle* va = *(const Vehicle**)a;
+ const Vehicle* vb = *(const Vehicle**)b;
+ int r = va->unitnumber - vb->unitnumber;
+
+ return (_internal_sort_order & 1) ? -r : r;
+}
+
+static int CDECL VehicleNameSorter(const void *a, const void *b)
+{
+ static const Vehicle *last_vehicle[2] = { NULL, NULL };
+ static char last_name[2][64] = { "", "" };
+
+ const Vehicle* va = *(const Vehicle**)a;
+ const Vehicle* vb = *(const Vehicle**)b;
+ int r;
+
+ if (va != last_vehicle[0]) {
+ last_vehicle[0] = va;
+ if (IsCustomName(va->string_id)) {
+ GetString(last_name[0], va->string_id, lastof(last_name[0]));
+ } else {
+ last_name[0][0] = '\0';
+ }
+ }
+
+ if (vb != last_vehicle[1]) {
+ last_vehicle[1] = vb;
+ if (IsCustomName(vb->string_id)) {
+ GetString(last_name[1], vb->string_id, lastof(last_name[1]));
+ } else {
+ last_name[1][0] = '\0';
+ }
+ }
+
+ r = strcmp(last_name[0], last_name[1]); // sort by name
+
+ VEHICLEUNITNUMBERSORTER(r, va, vb);
+
+ return (_internal_sort_order & 1) ? -r : r;
+}
+
+static int CDECL VehicleAgeSorter(const void *a, const void *b)
+{
+ const Vehicle* va = *(const Vehicle**)a;
+ const Vehicle* vb = *(const Vehicle**)b;
+ int r = va->age - vb->age;
+
+ VEHICLEUNITNUMBERSORTER(r, va, vb);
+
+ return (_internal_sort_order & 1) ? -r : r;
+}
+
+static int CDECL VehicleProfitThisYearSorter(const void *a, const void *b)
+{
+ const Vehicle* va = *(const Vehicle**)a;
+ const Vehicle* vb = *(const Vehicle**)b;
+ int r = va->profit_this_year - vb->profit_this_year;
+
+ VEHICLEUNITNUMBERSORTER(r, va, vb);
+
+ return (_internal_sort_order & 1) ? -r : r;
+}
+
+static int CDECL VehicleProfitLastYearSorter(const void *a, const void *b)
+{
+ const Vehicle* va = *(const Vehicle**)a;
+ const Vehicle* vb = *(const Vehicle**)b;
+ int r = va->profit_last_year - vb->profit_last_year;
+
+ VEHICLEUNITNUMBERSORTER(r, va, vb);
+
+ return (_internal_sort_order & 1) ? -r : r;
+}
+
+static int CDECL VehicleCargoSorter(const void *a, const void *b)
+{
+ const Vehicle* va = *(const Vehicle**)a;
+ const Vehicle* vb = *(const Vehicle**)b;
+ const Vehicle* v;
+ AcceptedCargo cargoa;
+ AcceptedCargo cargob;
+ int r = 0;
+ int i;
+
+ memset(cargoa, 0, sizeof(cargoa));
+ memset(cargob, 0, sizeof(cargob));
+ for (v = va; v != NULL; v = v->next) cargoa[v->cargo_type] += v->cargo_cap;
+ for (v = vb; v != NULL; v = v->next) cargob[v->cargo_type] += v->cargo_cap;
+
+ for (i = 0; i < NUM_CARGO; i++) {
+ r = cargoa[i] - cargob[i];
+ if (r != 0) break;
+ }
+
+ VEHICLEUNITNUMBERSORTER(r, va, vb);
+
+ return (_internal_sort_order & 1) ? -r : r;
+}
+
+static int CDECL VehicleReliabilitySorter(const void *a, const void *b)
+{
+ const Vehicle* va = *(const Vehicle**)a;
+ const Vehicle* vb = *(const Vehicle**)b;
+ int r = va->reliability - vb->reliability;
+
+ VEHICLEUNITNUMBERSORTER(r, va, vb);
+
+ return (_internal_sort_order & 1) ? -r : r;
+}
+
+static int CDECL VehicleMaxSpeedSorter(const void *a, const void *b)
+{
+ const Vehicle* va = *(const Vehicle**)a;
+ const Vehicle* vb = *(const Vehicle**)b;
+ int max_speed_a = 0xFFFF, max_speed_b = 0xFFFF;
+ int r;
+ const Vehicle *ua = va, *ub = vb;
+
+ if (va->type == VEH_Train && vb->type == VEH_Train) {
+ do {
+ if (RailVehInfo(ua->engine_type)->max_speed != 0)
+ max_speed_a = min(max_speed_a, RailVehInfo(ua->engine_type)->max_speed);
+ } while ((ua = ua->next) != NULL);
+
+ do {
+ if (RailVehInfo(ub->engine_type)->max_speed != 0)
+ max_speed_b = min(max_speed_b, RailVehInfo(ub->engine_type)->max_speed);
+ } while ((ub = ub->next) != NULL);
+
+ r = max_speed_a - max_speed_b;
+ } else {
+ r = va->max_speed - vb->max_speed;
+ }
+
+ VEHICLEUNITNUMBERSORTER(r, va, vb);
+
+ return (_internal_sort_order & 1) ? -r : r;
+}
+
+static int CDECL VehicleModelSorter(const void *a, const void *b)
+{
+ const Vehicle* va = *(const Vehicle**)a;
+ const Vehicle* vb = *(const Vehicle**)b;
+ int r = va->engine_type - vb->engine_type;
+
+ VEHICLEUNITNUMBERSORTER(r, va, vb);
+
+ return (_internal_sort_order & 1) ? -r : r;
+}
+
+static int CDECL VehicleValueSorter(const void *a, const void *b)
+{
+ const Vehicle* va = *(const Vehicle**)a;
+ const Vehicle* vb = *(const Vehicle**)b;
+ const Vehicle *u;
+ int valuea = 0, valueb = 0;
+ int r;
+
+ for (u = va; u != NULL; u = u->next) valuea += u->value;
+ for (u = vb; u != NULL; u = u->next) valueb += u->value;
+
+ r = valuea - valueb;
+
+ VEHICLEUNITNUMBERSORTER(r, va, vb);
+
+ return (_internal_sort_order & 1) ? -r : r;
+}
+
+// this define is to match engine.c, but engine.c keeps it to itself
+// ENGINE_AVAILABLE is used in ReplaceVehicleWndProc
+#define ENGINE_AVAILABLE ((e->flags & 1 && HASBIT(info->climates, _opt.landscape)) || HASBIT(e->player_avail, _local_player))
+
+/* if show_outdated is selected, it do not sort psudo engines properly but it draws all engines
+ * if used compined with show_cars set to false, it will work as intended. Replace window do it like that
+ * this was a big hack even before show_outdated was added. Stupid newgrf :p
+ */
+static void train_engine_drawing_loop(int *x, int *y, int *pos, int *sel, EngineID *selected_id, RailType railtype,
+ uint8 lines_drawn, bool is_engine, bool show_cars, bool show_outdated, bool show_compatible)
+{
+ EngineID j;
+ byte colour;
+ const Player *p = GetPlayer(_local_player);
+
+ for (j = 0; j < NUM_TRAIN_ENGINES; j++) {
+ EngineID i = GetRailVehAtPosition(j);
+ const Engine *e = GetEngine(i);
+ const RailVehicleInfo *rvi = RailVehInfo(i);
+ const EngineInfo *info = EngInfo(i);
+
+ if (!EngineHasReplacementForPlayer(p, i) && p->num_engines[i] == 0 && show_outdated) continue;
+
+ if ((rvi->power == 0 && !show_cars) || (rvi->power != 0 && show_cars)) // show wagons or engines (works since wagons do not have power)
+ continue;
+
+ if (*sel == 0) *selected_id = j;
+
+
+ colour = *sel == 0 ? 0xC : 0x10;
+ if (!(ENGINE_AVAILABLE && show_outdated && RailVehInfo(i)->power && IsCompatibleRail(e->railtype, railtype))) {
+ if ((!IsCompatibleRail(e->railtype, railtype) && show_compatible)
+ || (e->railtype != railtype && !show_compatible)
+ || !(rvi->flags & RVI_WAGON) != is_engine ||
+ !HASBIT(e->player_avail, _local_player))
+ continue;
+#if 0
+ } else {
+ // TODO find a nice red colour for vehicles being replaced
+ if ( _autoreplace_array[i] != i )
+ colour = *sel == 0 ? 0x44 : 0x45;
+#endif
+ }
+
+ if (IS_INT_INSIDE(--*pos, -lines_drawn, 0)) {
+ DrawString(*x + 59, *y + 2, GetCustomEngineName(i),
+ colour);
+ // show_outdated is true only for left side, which is where we show old replacements
+ DrawTrainEngine(*x + 29, *y + 6, i, (p->num_engines[i] == 0 && show_outdated) ?
+ PALETTE_CRASH : GetEnginePalette(i, _local_player));
+ if ( show_outdated ) {
+ SetDParam(0, p->num_engines[i]);
+ DrawStringRightAligned(213, *y+5, STR_TINY_BLACK, 0);
+ }
+ *y += 14;
+ }
+ --*sel;
+ }
+}
+
+
+static void SetupScrollStuffForReplaceWindow(Window *w)
+{
+ EngineID selected_id[2] = { INVALID_ENGINE, INVALID_ENGINE };
+ const Player* p = GetPlayer(_local_player);
+ uint sel[2];
+ uint count = 0;
+ uint count2 = 0;
+ EngineID i;
+
+ sel[0] = WP(w,replaceveh_d).sel_index[0];
+ sel[1] = WP(w,replaceveh_d).sel_index[1];
+
+ switch (WP(w,replaceveh_d).vehicletype) {
+ case VEH_Train: {
+ RailType railtype = _railtype_selected_in_replace_gui;
+
+ w->widget[13].color = _player_colors[_local_player]; // sets the colour of that art thing
+ w->widget[16].color = _player_colors[_local_player]; // sets the colour of that art thing
+
+ for (i = 0; i < NUM_TRAIN_ENGINES; i++) {
+ EngineID eid = GetRailVehAtPosition(i);
+ const Engine* e = GetEngine(eid);
+ const EngineInfo* info = EngInfo(eid);
+
+ // left window contains compatible engines while right window only contains engines of the selected type
+ if (ENGINE_AVAILABLE &&
+ (RailVehInfo(eid)->power != 0) == (WP(w, replaceveh_d).wagon_btnstate != 0)) {
+ if (IsCompatibleRail(e->railtype, railtype) && (p->num_engines[eid] > 0 || EngineHasReplacementForPlayer(p, eid))) {
+ if (sel[0] == count) selected_id[0] = eid;
+ count++;
+ }
+ if (e->railtype == railtype && HASBIT(e->player_avail, _local_player)) {
+ if (sel[1] == count2) selected_id[1] = eid;
+ count2++;
+ }
+ }
+ }
+ break;
+ }
+
+ case VEH_Road: {
+ for (i = ROAD_ENGINES_INDEX; i < ROAD_ENGINES_INDEX + NUM_ROAD_ENGINES; i++) {
+ if (p->num_engines[i] > 0 || EngineHasReplacementForPlayer(p, i)) {
+ if (sel[0] == count) selected_id[0] = i;
+ count++;
+ }
+ }
+
+ if (selected_id[0] != INVALID_ENGINE) { // only draw right array if we have anything in the left one
+ CargoID cargo = RoadVehInfo(selected_id[0])->cargo_type;
+
+ for (i = ROAD_ENGINES_INDEX; i < ROAD_ENGINES_INDEX + NUM_ROAD_ENGINES; i++) {
+ if (cargo == RoadVehInfo(i)->cargo_type &&
+ HASBIT(GetEngine(i)->player_avail, _local_player)) {
+ if (sel[1] == count2) selected_id[1] = i;
+ count2++;
+ }
+ }
+ }
+ break;
+ }
+
+ case VEH_Ship: {
+ for (i = SHIP_ENGINES_INDEX; i < SHIP_ENGINES_INDEX + NUM_SHIP_ENGINES; i++) {
+ if (p->num_engines[i] > 0 || EngineHasReplacementForPlayer(p, i)) {
+ if (sel[0] == count) selected_id[0] = i;
+ count++;
+ }
+ }
+
+ if (selected_id[0] != INVALID_ENGINE) {
+ const ShipVehicleInfo* svi = ShipVehInfo(selected_id[0]);
+ CargoID cargo = svi->cargo_type;
+ byte refittable = svi->refittable;
+
+ for (i = SHIP_ENGINES_INDEX; i < SHIP_ENGINES_INDEX + NUM_SHIP_ENGINES; i++) {
+ if (HASBIT(GetEngine(i)->player_avail, _local_player) && (
+ ShipVehInfo(i)->cargo_type == cargo ||
+ ShipVehInfo(i)->refittable & refittable
+ )) {
+ if (sel[1] == count2) selected_id[1] = i;
+ count2++;
+ }
+ }
+ }
+ break;
+ }
+
+ case VEH_Aircraft: {
+ for (i = AIRCRAFT_ENGINES_INDEX; i < AIRCRAFT_ENGINES_INDEX + NUM_AIRCRAFT_ENGINES; i++) {
+ if (p->num_engines[i] > 0 || EngineHasReplacementForPlayer(p, i)) {
+ if (sel[0] == count) selected_id[0] = i;
+ count++;
+ }
+ }
+
+ if (selected_id[0] != INVALID_ENGINE) {
+ byte subtype = AircraftVehInfo(selected_id[0])->subtype;
+
+ for (i = AIRCRAFT_ENGINES_INDEX; i < AIRCRAFT_ENGINES_INDEX + NUM_AIRCRAFT_ENGINES; i++) {
+ if (HASBIT(GetEngine(i)->player_avail, _local_player) &&
+ (subtype & AIR_CTOL) == (AircraftVehInfo(i)->subtype & AIR_CTOL)) {
+ if (sel[1] == count2) selected_id[1] = i;
+ count2++;
+ }
+ }
+ }
+ break;
+ }
+ }
+ // sets up the number of items in each list
+ SetVScrollCount(w, count);
+ SetVScroll2Count(w, count2);
+ WP(w,replaceveh_d).sel_engine[0] = selected_id[0];
+ WP(w,replaceveh_d).sel_engine[1] = selected_id[1];
+
+ WP(w,replaceveh_d).count[0] = count;
+ WP(w,replaceveh_d).count[1] = count2;
+ return;
+}
+
+
+static void DrawEngineArrayInReplaceWindow(Window *w, int x, int y, int x2, int y2, int pos, int pos2,
+ int sel1, int sel2, EngineID selected_id1, EngineID selected_id2)
+{
+ int sel[2];
+ EngineID selected_id[2];
+ const Player *p = GetPlayer(_local_player);
+
+ sel[0] = sel1;
+ sel[1] = sel2;
+
+ selected_id[0] = selected_id1;
+ selected_id[1] = selected_id2;
+
+ switch (WP(w,replaceveh_d).vehicletype) {
+ case VEH_Train: {
+ RailType railtype = _railtype_selected_in_replace_gui;
+ DrawString(157, w->widget[14].top + 1, _rail_types_list[railtype], 0x10);
+ /* draw sorting criteria string */
+
+ /* Ensure that custom engines which substituted wagons
+ * are sorted correctly.
+ * XXX - DO NOT EVER DO THIS EVER AGAIN! GRRR hacking in wagons as
+ * engines to get more types.. Stays here until we have our own format
+ * then it is exit!!! */
+ if (WP(w,replaceveh_d).wagon_btnstate) {
+ train_engine_drawing_loop(&x, &y, &pos, &sel[0], &selected_id[0], railtype, w->vscroll.cap, true, false, true, true); // True engines
+ train_engine_drawing_loop(&x2, &y2, &pos2, &sel[1], &selected_id[1], railtype, w->vscroll.cap, true, false, false, false); // True engines
+ train_engine_drawing_loop(&x2, &y2, &pos2, &sel[1], &selected_id[1], railtype, w->vscroll.cap, false, false, false, false); // Feeble wagons
+ } else {
+ train_engine_drawing_loop(&x, &y, &pos, &sel[0], &selected_id[0], railtype, w->vscroll.cap, false, true, true, true);
+ train_engine_drawing_loop(&x2, &y2, &pos2, &sel[1], &selected_id[1], railtype, w->vscroll.cap, false, true, false, true);
+ }
+ break;
+ }
+
+ case VEH_Road: {
+ int num = NUM_ROAD_ENGINES;
+ const Engine* e = GetEngine(ROAD_ENGINES_INDEX);
+ EngineID engine_id = ROAD_ENGINES_INDEX;
+
+ do {
+ if (p->num_engines[engine_id] > 0 || EngineHasReplacementForPlayer(p, engine_id)) {
+ if (IS_INT_INSIDE(--pos, -w->vscroll.cap, 0)) {
+ DrawString(x+59, y+2, GetCustomEngineName(engine_id), sel[0]==0 ? 0xC : 0x10);
+ DrawRoadVehEngine(x+29, y+6, engine_id, p->num_engines[engine_id] > 0 ? GetEnginePalette(engine_id, _local_player) : PALETTE_CRASH);
+ SetDParam(0, p->num_engines[engine_id]);
+ DrawStringRightAligned(213, y+5, STR_TINY_BLACK, 0);
+ y += 14;
+ }
+ sel[0]--;
+ }
+
+ if (selected_id[0] != INVALID_ENGINE) {
+ byte cargo = RoadVehInfo(selected_id[0])->cargo_type;
+
+ if (RoadVehInfo(engine_id)->cargo_type == cargo && HASBIT(e->player_avail, _local_player)) {
+ if (IS_INT_INSIDE(--pos2, -w->vscroll.cap, 0) && RoadVehInfo(engine_id)->cargo_type == cargo) {
+ DrawString(x2+59, y2+2, GetCustomEngineName(engine_id), sel[1]==0 ? 0xC : 0x10);
+ DrawRoadVehEngine(x2+29, y2+6, engine_id, GetEnginePalette(engine_id, _local_player));
+ y2 += 14;
+ }
+ sel[1]--;
+ }
+ }
+ } while (++engine_id, ++e,--num);
+ break;
+ }
+
+ case VEH_Ship: {
+ int num = NUM_SHIP_ENGINES;
+ const Engine* e = GetEngine(SHIP_ENGINES_INDEX);
+ EngineID engine_id = SHIP_ENGINES_INDEX;
+
+ do {
+ if (p->num_engines[engine_id] > 0 || EngineHasReplacementForPlayer(p, engine_id)) {
+ if (IS_INT_INSIDE(--pos, -w->vscroll.cap, 0)) {
+ DrawString(x+75, y+7, GetCustomEngineName(engine_id), sel[0]==0 ? 0xC : 0x10);
+ DrawShipEngine(x+35, y+10, engine_id, p->num_engines[engine_id] > 0 ? GetEnginePalette(engine_id, _local_player) : PALETTE_CRASH);
+ SetDParam(0, p->num_engines[engine_id]);
+ DrawStringRightAligned(213, y+15, STR_TINY_BLACK, 0);
+ y += 24;
+ }
+ sel[0]--;
+ }
+
+ if (selected_id[0] != INVALID_ENGINE) {
+ CargoID cargo = ShipVehInfo(selected_id[0])->cargo_type;
+ bool refittable = ShipVehInfo(selected_id[0])->refittable;
+
+ if (HASBIT(e->player_avail, _local_player) && ( cargo == ShipVehInfo(engine_id)->cargo_type || refittable & ShipVehInfo(engine_id)->refittable)) {
+ if (IS_INT_INSIDE(--pos2, -w->vscroll.cap, 0)) {
+ DrawString(x2+75, y2+7, GetCustomEngineName(engine_id), sel[1]==0 ? 0xC : 0x10);
+ DrawShipEngine(x2+35, y2+10, engine_id, GetEnginePalette(engine_id, _local_player));
+ y2 += 24;
+ }
+ sel[1]--;
+ }
+ }
+ } while (++engine_id, ++e, --num);
+ break;
+ } //end of ship
+
+ case VEH_Aircraft: {
+ int num = NUM_AIRCRAFT_ENGINES;
+ const Engine* e = GetEngine(AIRCRAFT_ENGINES_INDEX);
+ EngineID engine_id = AIRCRAFT_ENGINES_INDEX;
+
+ do {
+ if (p->num_engines[engine_id] > 0 || EngineHasReplacementForPlayer(p, engine_id)) {
+ if (sel[0] == 0) selected_id[0] = engine_id;
+ if (IS_INT_INSIDE(--pos, -w->vscroll.cap, 0)) {
+ DrawString(x+62, y+7, GetCustomEngineName(engine_id), sel[0]==0 ? 0xC : 0x10);
+ DrawAircraftEngine(x+29, y+10, engine_id, p->num_engines[engine_id] > 0 ? GetEnginePalette(engine_id, _local_player) : PALETTE_CRASH);
+ SetDParam(0, p->num_engines[engine_id]);
+ DrawStringRightAligned(213, y+15, STR_TINY_BLACK, 0);
+ y += 24;
+ }
+ sel[0]--;
+ }
+
+ if (selected_id[0] != INVALID_ENGINE) {
+ byte subtype = AircraftVehInfo(selected_id[0])->subtype;
+
+ if ((subtype & AIR_CTOL) == (AircraftVehInfo(engine_id)->subtype & AIR_CTOL) &&
+ HASBIT(e->player_avail, _local_player)) {
+ if (sel[1] == 0) selected_id[1] = engine_id;
+ if (IS_INT_INSIDE(--pos2, -w->vscroll.cap, 0)) {
+ DrawString(x2+62, y2+7, GetCustomEngineName(engine_id), sel[1]==0 ? 0xC : 0x10);
+ DrawAircraftEngine(x2+29, y2+10, engine_id, GetEnginePalette(engine_id, _local_player));
+ y2 += 24;
+ }
+ sel[1]--;
+ }
+ }
+ } while (++engine_id, ++e,--num);
+ break;
+ } // end of aircraft
+ }
+}
+
+static void DrawVehiclePurchaseInfo(const int x, const int y, uint w, const EngineID engine_number)
+{
+ switch (GetEngine(engine_number)->type) {
+ case VEH_Train:
+ if ((RailVehInfo(engine_number)->flags & RVI_WAGON) == 0) {
+ DrawTrainEnginePurchaseInfo(x, y, w, engine_number);
+ } else {
+ DrawTrainWagonPurchaseInfo(x, y, w, engine_number);
+ }
+ break;
+
+ case VEH_Road: DrawRoadVehPurchaseInfo(x, y, w, engine_number); break;
+ case VEH_Ship: DrawShipPurchaseInfo(x, y, w, engine_number); break;
+ case VEH_Aircraft: DrawAircraftPurchaseInfo(x, y, w, engine_number); break;
+ default: NOT_REACHED();
+ }
+}
+
+static void ReplaceVehicleWndProc(Window *w, WindowEvent *e)
+{
+ static const StringID _vehicle_type_names[] = {
+ STR_019F_TRAIN,
+ STR_019C_ROAD_VEHICLE,
+ STR_019E_SHIP,
+ STR_019D_AIRCRAFT
+ };
+
+ switch (e->event) {
+ case WE_PAINT: {
+ Player *p = GetPlayer(_local_player);
+ int pos = w->vscroll.pos;
+ EngineID selected_id[2] = { INVALID_ENGINE, INVALID_ENGINE };
+ int x = 1;
+ int y = 15;
+ int pos2 = w->vscroll2.pos;
+ int x2 = 1 + 228;
+ int y2 = 15;
+ int sel[2];
+ byte i;
+ sel[0] = WP(w,replaceveh_d).sel_index[0];
+ sel[1] = WP(w,replaceveh_d).sel_index[1];
+
+ SetupScrollStuffForReplaceWindow(w);
+
+ selected_id[0] = WP(w,replaceveh_d).sel_engine[0];
+ selected_id[1] = WP(w,replaceveh_d).sel_engine[1];
+
+ // Disable the "Start Replacing" button if:
+ // Either list is empty
+ // or Both lists have the same vehicle selected
+ // or The selected replacement engine has a replacement (to prevent loops)
+ // or The right list (new replacement) has the existing replacement vehicle selected
+ SetWindowWidgetDisabledState(w, 4,
+ selected_id[0] == INVALID_ENGINE ||
+ selected_id[1] == INVALID_ENGINE ||
+ selected_id[0] == selected_id[1] ||
+ EngineReplacementForPlayer(p, selected_id[1]) != INVALID_ENGINE ||
+ EngineReplacementForPlayer(p, selected_id[0]) == selected_id[1]);
+
+ // Disable the "Stop Replacing" button if:
+ // The left list (existing vehicle) is empty
+ // or The selected vehicle has no replacement set up
+ SetWindowWidgetDisabledState(w, 6,
+ selected_id[0] == INVALID_ENGINE ||
+ !EngineHasReplacementForPlayer(p, selected_id[0]));
+
+ // now the actual drawing of the window itself takes place
+ SetDParam(0, _vehicle_type_names[WP(w, replaceveh_d).vehicletype - VEH_Train]);
+
+ if (WP(w, replaceveh_d).vehicletype == VEH_Train) {
+ // set on/off for renew_keep_length
+ SetDParam(1, p->renew_keep_length ? STR_CONFIG_PATCHES_ON : STR_CONFIG_PATCHES_OFF);
+
+ // set wagon/engine button
+ SetDParam(2, WP(w, replaceveh_d).wagon_btnstate ? STR_ENGINES : STR_WAGONS);
+ }
+
+ DrawWindowWidgets(w);
+
+ // sets up the string for the vehicle that is being replaced to
+ if (selected_id[0] != INVALID_ENGINE) {
+ if (!EngineHasReplacementForPlayer(p, selected_id[0])) {
+ SetDParam(0, STR_NOT_REPLACING);
+ } else {
+ SetDParam(0, GetCustomEngineName(EngineReplacementForPlayer(p, selected_id[0])));
+ }
+ } else {
+ SetDParam(0, STR_NOT_REPLACING_VEHICLE_SELECTED);
+ }
+
+ DrawString(145, w->widget[5].top + 1, STR_02BD, 0x10);
+
+ /* now we draw the two arrays according to what we just counted */
+ DrawEngineArrayInReplaceWindow(w, x, y, x2, y2, pos, pos2, sel[0], sel[1], selected_id[0], selected_id[1]);
+
+ WP(w,replaceveh_d).sel_engine[0] = selected_id[0];
+ WP(w,replaceveh_d).sel_engine[1] = selected_id[1];
+ /* now we draw the info about the vehicles we selected */
+ for (i = 0 ; i < 2 ; i++) {
+ if (selected_id[i] != INVALID_ENGINE) {
+ const Widget *wi = &w->widget[i == 0 ? 3 : 11];
+ DrawVehiclePurchaseInfo(wi->left + 2 , wi->top + 1, wi->right - wi->left - 2, selected_id[i]);
+ }
+ }
+ } break; // end of paint
+
+ case WE_CLICK: {
+ // these 3 variables is used if any of the lists is clicked
+ uint16 click_scroll_pos = w->vscroll2.pos;
+ uint16 click_scroll_cap = w->vscroll2.cap;
+ byte click_side = 1;
+
+ switch (e->we.click.widget) {
+ case 12:
+ WP(w, replaceveh_d).wagon_btnstate = !(WP(w, replaceveh_d).wagon_btnstate);
+ SetWindowDirty(w);
+ break;
+
+ case 14:
+ case 15: /* Railtype selection dropdown menu */
+ ShowDropDownMenu(w, _rail_types_list, _railtype_selected_in_replace_gui, 15, 0, ~GetPlayer(_local_player)->avail_railtypes);
+ break;
+
+ case 17: /* toggle renew_keep_length */
+ DoCommandP(0, 5, GetPlayer(_local_player)->renew_keep_length ? 0 : 1, NULL, CMD_SET_AUTOREPLACE);
+ break;
+
+ case 4: { /* Start replacing */
+ EngineID veh_from = WP(w, replaceveh_d).sel_engine[0];
+ EngineID veh_to = WP(w, replaceveh_d).sel_engine[1];
+ DoCommandP(0, 3, veh_from + (veh_to << 16), NULL, CMD_SET_AUTOREPLACE);
+ break;
+ }
+
+ case 6: { /* Stop replacing */
+ EngineID veh_from = WP(w, replaceveh_d).sel_engine[0];
+ DoCommandP(0, 3, veh_from + (INVALID_ENGINE << 16), NULL, CMD_SET_AUTOREPLACE);
+ break;
+ }
+
+ case 7:
+ // sets up that the left one was clicked. The default values are for the right one (9)
+ // this way, the code for 9 handles both sides
+ click_scroll_pos = w->vscroll.pos;
+ click_scroll_cap = w->vscroll.cap;
+ click_side = 0;
+ /* FALL THROUGH */
+
+ case 9: {
+ uint i = (e->we.click.pt.y - 14) / w->resize.step_height;
+ if (i < click_scroll_cap) {
+ WP(w,replaceveh_d).sel_index[click_side] = i + click_scroll_pos;
+ SetWindowDirty(w);
+ }
+ break;
+ }
+ }
+ break;
+ }
+
+ case WE_DROPDOWN_SELECT: /* we have selected a dropdown item in the list */
+ _railtype_selected_in_replace_gui = e->we.dropdown.index;
+ /* Reset scrollbar positions */
+ w->vscroll.pos = 0;
+ w->vscroll2.pos = 0;
+ SetWindowDirty(w);
+ break;
+
+ case WE_RESIZE:
+ w->vscroll.cap += e->we.sizing.diff.y / (int)w->resize.step_height;
+ w->vscroll2.cap += e->we.sizing.diff.y / (int)w->resize.step_height;
+
+ w->widget[7].data = (w->vscroll.cap << 8) + 1;
+ w->widget[9].data = (w->vscroll2.cap << 8) + 1;
+ break;
+ }
+}
+
+static const Widget _replace_rail_vehicle_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 443, 0, 13, STR_REPLACE_VEHICLES_WHITE, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_STICKYBOX, RESIZE_NONE, 14, 444, 455, 0, 13, STR_NULL, STR_STICKY_BUTTON},
+{ WWT_PANEL, RESIZE_TB, 14, 0, 227, 126, 227, 0x0, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 138, 240, 251, STR_REPLACE_VEHICLES_START, STR_REPLACE_HELP_START_BUTTON},
+{ WWT_PANEL, RESIZE_TB, 14, 139, 316, 228, 239, 0x0, STR_REPLACE_HELP_REPLACE_INFO_TAB},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 306, 443, 240, 251, STR_REPLACE_VEHICLES_STOP, STR_REPLACE_HELP_STOP_BUTTON},
+{ WWT_MATRIX, RESIZE_BOTTOM, 14, 0, 215, 14, 125, 0x801, STR_REPLACE_HELP_LEFT_ARRAY},
+{ WWT_SCROLLBAR, RESIZE_BOTTOM, 14, 216, 227, 14, 125, STR_NULL, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WWT_MATRIX, RESIZE_BOTTOM, 14, 228, 443, 14, 125, 0x801, STR_REPLACE_HELP_RIGHT_ARRAY},
+{ WWT_SCROLL2BAR, RESIZE_BOTTOM, 14, 444, 455, 14, 125, STR_NULL, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WWT_PANEL, RESIZE_TB, 14, 228, 455, 126, 227, 0x0, STR_NULL},
+// train specific stuff
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 138, 228, 239, STR_REPLACE_ENGINE_WAGON_SELECT, STR_REPLACE_ENGINE_WAGON_SELECT_HELP}, // widget 12
+{ WWT_PANEL, RESIZE_TB, 14, 139, 153, 240, 251, 0x0, STR_NULL},
+{ WWT_PANEL, RESIZE_TB, 14, 154, 277, 240, 251, 0x0, STR_REPLACE_HELP_RAILTYPE},
+{ WWT_TEXTBTN, RESIZE_TB, 14, 278, 289, 240, 251, STR_0225, STR_REPLACE_HELP_RAILTYPE},
+{ WWT_PANEL, RESIZE_TB, 14, 290, 305, 240, 251, 0x0, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 317, 455, 228, 239, STR_REPLACE_REMOVE_WAGON, STR_REPLACE_REMOVE_WAGON_HELP},
+// end of train specific stuff
+{ WWT_RESIZEBOX, RESIZE_TB, 14, 444, 455, 240, 251, STR_NULL, STR_RESIZE_BUTTON},
+{ WIDGETS_END},
+};
+
+static const Widget _replace_road_vehicle_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 443, 0, 13, STR_REPLACE_VEHICLES_WHITE, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_STICKYBOX, RESIZE_NONE, 14, 444, 455, 0, 13, STR_NULL, STR_STICKY_BUTTON},
+{ WWT_PANEL, RESIZE_TB, 14, 0, 227, 126, 217, 0x0, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 138, 218, 229, STR_REPLACE_VEHICLES_START, STR_REPLACE_HELP_START_BUTTON},
+{ WWT_PANEL, RESIZE_TB, 14, 139, 305, 218, 229, 0x0, STR_REPLACE_HELP_REPLACE_INFO_TAB},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 306, 443, 218, 229, STR_REPLACE_VEHICLES_STOP, STR_REPLACE_HELP_STOP_BUTTON},
+{ WWT_MATRIX, RESIZE_BOTTOM, 14, 0, 215, 14, 125, 0x801, STR_REPLACE_HELP_LEFT_ARRAY},
+{ WWT_SCROLLBAR, RESIZE_BOTTOM, 14, 216, 227, 14, 125, STR_NULL, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WWT_MATRIX, RESIZE_BOTTOM, 14, 228, 443, 14, 125, 0x801, STR_REPLACE_HELP_RIGHT_ARRAY},
+{ WWT_SCROLL2BAR, RESIZE_BOTTOM, 14, 444, 455, 14, 125, STR_NULL, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WWT_PANEL, RESIZE_TB, 14, 228, 455, 126, 217, 0x0, STR_NULL},
+{ WWT_RESIZEBOX, RESIZE_TB, 14, 444, 455, 218, 229, STR_NULL, STR_RESIZE_BUTTON},
+{ WIDGETS_END},
+};
+
+static const Widget _replace_ship_aircraft_vehicle_widgets[] = {
+{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+{ WWT_CAPTION, RESIZE_NONE, 14, 11, 443, 0, 13, STR_REPLACE_VEHICLES_WHITE, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_STICKYBOX, RESIZE_NONE, 14, 444, 455, 0, 13, STR_NULL, STR_STICKY_BUTTON},
+{ WWT_PANEL, RESIZE_TB, 14, 0, 227, 110, 201, 0x0, STR_NULL},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 138, 202, 213, STR_REPLACE_VEHICLES_START, STR_REPLACE_HELP_START_BUTTON},
+{ WWT_PANEL, RESIZE_TB, 14, 139, 305, 202, 213, 0x0, STR_REPLACE_HELP_REPLACE_INFO_TAB},
+{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 306, 443, 202, 213, STR_REPLACE_VEHICLES_STOP, STR_REPLACE_HELP_STOP_BUTTON},
+{ WWT_MATRIX, RESIZE_BOTTOM, 14, 0, 215, 14, 109, 0x401, STR_REPLACE_HELP_LEFT_ARRAY},
+{ WWT_SCROLLBAR, RESIZE_BOTTOM, 14, 216, 227, 14, 109, STR_NULL, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WWT_MATRIX, RESIZE_BOTTOM, 14, 228, 443, 14, 109, 0x401, STR_REPLACE_HELP_RIGHT_ARRAY},
+{ WWT_SCROLL2BAR, RESIZE_BOTTOM, 14, 444, 455, 14, 109, STR_NULL, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WWT_PANEL, RESIZE_TB, 14, 228, 455, 110, 201, 0x0, STR_NULL},
+{ WWT_RESIZEBOX, RESIZE_TB, 14, 444, 455, 202, 213, STR_NULL, STR_RESIZE_BUTTON},
+{ WIDGETS_END},
+};
+
+static const WindowDesc _replace_rail_vehicle_desc = {
+ WDP_AUTO, WDP_AUTO, 456, 252,
+ WC_REPLACE_VEHICLE,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
+ _replace_rail_vehicle_widgets,
+ ReplaceVehicleWndProc
+};
+
+static const WindowDesc _replace_road_vehicle_desc = {
+ WDP_AUTO, WDP_AUTO, 456, 230,
+ WC_REPLACE_VEHICLE,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
+ _replace_road_vehicle_widgets,
+ ReplaceVehicleWndProc
+};
+
+static const WindowDesc _replace_ship_aircraft_vehicle_desc = {
+ WDP_AUTO, WDP_AUTO, 456, 214,
+ WC_REPLACE_VEHICLE,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
+ _replace_ship_aircraft_vehicle_widgets,
+ ReplaceVehicleWndProc
+};
+
+
+static void ShowReplaceVehicleWindow(byte vehicletype)
+{
+ Window *w;
+
+ DeleteWindowById(WC_REPLACE_VEHICLE, vehicletype);
+
+ switch (vehicletype) {
+ case VEH_Train:
+ w = AllocateWindowDescFront(&_replace_rail_vehicle_desc, vehicletype);
+ w->vscroll.cap = 8;
+ w->resize.step_height = 14;
+ WP(w, replaceveh_d).wagon_btnstate = true;
+ break;
+ case VEH_Road:
+ w = AllocateWindowDescFront(&_replace_road_vehicle_desc, vehicletype);
+ w->vscroll.cap = 8;
+ w->resize.step_height = 14;
+ break;
+ case VEH_Ship:
+ case VEH_Aircraft:
+ w = AllocateWindowDescFront(&_replace_ship_aircraft_vehicle_desc, vehicletype);
+ w->vscroll.cap = 4;
+ w->resize.step_height = 24;
+ break;
+ default: return;
+ }
+
+ w->caption_color = _local_player;
+ WP(w, replaceveh_d).vehicletype = vehicletype;
+ w->vscroll2.cap = w->vscroll.cap; // these two are always the same
+}
+
+void InitializeGUI(void)
+{
+ memset(&_sorting, 0, sizeof(_sorting));
+}
+
+/** Assigns an already open vehicle window to a new vehicle.
+ * Assigns an already open vehicle window to a new vehicle. If the vehicle got
+ * any sub window open (orders and so on) it will change owner too.
+ * @param *from_v the current owner of the window
+ * @param *to_v the new owner of the window
+ */
+void ChangeVehicleViewWindow(const Vehicle *from_v, const Vehicle *to_v)
+{
+ Window *w;
+
+ w = FindWindowById(WC_VEHICLE_VIEW, from_v->index);
+ if (w != NULL) {
+ w->window_number = to_v->index;
+ WP(w, vp_d).follow_vehicle = to_v->index;
+ SetWindowDirty(w);
+
+ w = FindWindowById(WC_VEHICLE_ORDERS, from_v->index);
+ if (w != NULL) {
+ w->window_number = to_v->index;
+ SetWindowDirty(w);
+ }
+
+ w = FindWindowById(WC_VEHICLE_REFIT, from_v->index);
+ if (w != NULL) {
+ w->window_number = to_v->index;
+ SetWindowDirty(w);
+ }
+
+ w = FindWindowById(WC_VEHICLE_DETAILS, from_v->index);
+ if (w != NULL) {
+ w->window_number = to_v->index;
+ SetWindowDirty(w);
+ }
+ }
+}
+
+/*
+ * Start of functions regarding vehicle list windows
+ */
+
+enum {
+ PLY_WND_PRC__OFFSET_TOP_WIDGET = 26,
+ PLY_WND_PRC__SIZE_OF_ROW_SMALL = 26,
+ PLY_WND_PRC__SIZE_OF_ROW_BIG = 36,
+};
+
+enum VehicleListWindowWidgets {
+ VLW_WIDGET_CLOSEBOX = 0,
+ VLW_WIDGET_CAPTION,
+ VLW_WIDGET_STICKY,
+ VLW_WIDGET_SORT_ORDER,
+ VLW_WIDGET_SORT_BY_TEXT,
+ VLW_WIDGET_SORT_BY_PULLDOWN,
+ VLW_WIDGET_EMPTY_TOP_RIGHT,
+ VLW_WIDGET_LIST,
+ VLW_WIDGET_SCROLLBAR,
+ VLW_WIDGET_OTHER_PLAYER_FILLER,
+ VLW_WIDGET_NEW_VEHICLES,
+ VLW_WIDGET_MANAGE_VEHICLES,
+ VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN,
+ VLW_WIDGET_STOP_ALL,
+ VLW_WIDGET_START_ALL,
+ VLW_WIDGET_EMPTY_BOTTOM_RIGHT,
+ VLW_WIDGET_RESIZE,
+};
+
+static const Widget _vehicle_list_widgets[] = {
+ { WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
+ { WWT_CAPTION, RESIZE_RIGHT, 14, 11, 247, 0, 13, 0x0, STR_018C_WINDOW_TITLE_DRAG_THIS},
+ { WWT_STICKYBOX, RESIZE_LR, 14, 248, 259, 0, 13, 0x0, STR_STICKY_BUTTON},
+ { WWT_PUSHTXTBTN, RESIZE_NONE, 14, 0, 80, 14, 25, STR_SORT_BY, STR_SORT_ORDER_TIP},
+ { WWT_PANEL, RESIZE_NONE, 14, 81, 235, 14, 25, 0x0, STR_SORT_CRITERIA_TIP},
+ { WWT_TEXTBTN, RESIZE_NONE, 14, 236, 247, 14, 25, STR_0225, STR_SORT_CRITERIA_TIP},
+ { WWT_PANEL, RESIZE_RIGHT, 14, 248, 259, 14, 25, 0x0, STR_NULL},
+ { WWT_MATRIX, RESIZE_RB, 14, 0, 247, 26, 169, 0x0, STR_NULL},
+ { WWT_SCROLLBAR, RESIZE_LRB, 14, 248, 259, 26, 169, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+ /* Widget to be shown for other players hiding the following 6 widgets */
+ { WWT_PANEL, RESIZE_RTB, 14, 0, 247, 170, 181, 0x0, STR_NULL},
+
+ { WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 105, 170, 181, 0x0, STR_AVAILABLE_ENGINES_TIP},
+ { WWT_TEXTBTN, RESIZE_TB, 14, 106, 211, 170, 181, STR_MANAGE_LIST, STR_MANAGE_LIST_TIP},
+ { WWT_TEXTBTN, RESIZE_TB, 14, 212, 223, 170, 181, STR_0225, STR_MANAGE_LIST_TIP},
+
+ { WWT_PUSHIMGBTN, RESIZE_TB, 14, 224, 235, 170, 181, SPR_FLAG_VEH_STOPPED, STR_MASS_STOP_LIST_TIP},
+ { WWT_PUSHIMGBTN, RESIZE_TB, 14, 236, 247, 170, 181, SPR_FLAG_VEH_RUNNING, STR_MASS_START_LIST_TIP},
+ { WWT_PANEL, RESIZE_RTB, 14, 248, 247, 170, 181, 0x0, STR_NULL},
+ { WWT_RESIZEBOX, RESIZE_LRTB, 14, 248, 259, 170, 181, 0x0, STR_RESIZE_BUTTON},
+ { WIDGETS_END},
+};
+
+static void CreateVehicleListWindow(Window *w)
+{
+ vehiclelist_d *vl = &WP(w, vehiclelist_d);
+ uint16 window_type = w->window_number & VLW_MASK;
+ PlayerID player = GB(w->window_number, 0, 8);
+
+ vl->vehicle_type = GB(w->window_number, 11, 5);
+ vl->length_of_sort_list = 0;
+ vl->sort_list = NULL;
+ w->caption_color = player;
+
+ /* Hide the widgets that we will not use in this window
+ * Some windows contains actions only fit for the owner */
+ if (player == _local_player) {
+ HideWindowWidget(w, VLW_WIDGET_OTHER_PLAYER_FILLER);
+ SetWindowWidgetDisabledState(w, VLW_WIDGET_NEW_VEHICLES, window_type != VLW_STANDARD);
+ } else {
+ SetWindowWidgetsHiddenState(w, true,
+ VLW_WIDGET_NEW_VEHICLES,
+ VLW_WIDGET_MANAGE_VEHICLES,
+ VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN,
+ VLW_WIDGET_STOP_ALL,
+ VLW_WIDGET_START_ALL,
+ VLW_WIDGET_EMPTY_BOTTOM_RIGHT,
+ WIDGET_LIST_END);
+ }
+
+ /* Set up the window widgets */
+ switch (vl->vehicle_type) {
+ case VEH_Train:
+ w->widget[VLW_WIDGET_LIST].tooltips = STR_883D_TRAINS_CLICK_ON_TRAIN_FOR;
+ w->widget[VLW_WIDGET_NEW_VEHICLES].data = STR_8815_NEW_VEHICLES;
+ break;
+
+ case VEH_Road:
+ w->widget[VLW_WIDGET_LIST].tooltips = STR_901A_ROAD_VEHICLES_CLICK_ON;
+ w->widget[VLW_WIDGET_NEW_VEHICLES].data = STR_9004_NEW_VEHICLES;
+ break;
+
+ case VEH_Ship:
+ w->widget[VLW_WIDGET_LIST].tooltips = STR_9823_SHIPS_CLICK_ON_SHIP_FOR;
+ w->widget[VLW_WIDGET_NEW_VEHICLES].data = STR_9804_NEW_SHIPS;
+ break;
+
+ case VEH_Aircraft:
+ w->widget[VLW_WIDGET_LIST].tooltips = STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT;
+ w->widget[VLW_WIDGET_NEW_VEHICLES].data = STR_A003_NEW_AIRCRAFT;
+ break;
+
+ default: NOT_REACHED();
+ }
+
+ switch (window_type) {
+ case VLW_SHARED_ORDERS:
+ w->widget[VLW_WIDGET_CAPTION].data = STR_VEH_WITH_SHARED_ORDERS_LIST;
+ break;
+ case VLW_STANDARD: /* Company Name - standard widget setup */
+ switch (vl->vehicle_type) {
+ case VEH_Train: w->widget[VLW_WIDGET_CAPTION].data = STR_881B_TRAINS; break;
+ case VEH_Road: w->widget[VLW_WIDGET_CAPTION].data = STR_9001_ROAD_VEHICLES; break;
+ case VEH_Ship: w->widget[VLW_WIDGET_CAPTION].data = STR_9805_SHIPS; break;
+ case VEH_Aircraft: w->widget[VLW_WIDGET_CAPTION].data = STR_A009_AIRCRAFT; break;
+ default: NOT_REACHED(); break;
+ }
+ break;
+ case VLW_STATION_LIST: /* Station Name */
+ switch (vl->vehicle_type) {
+ case VEH_Train: w->widget[VLW_WIDGET_CAPTION].data = STR_SCHEDULED_TRAINS; break;
+ case VEH_Road: w->widget[VLW_WIDGET_CAPTION].data = STR_SCHEDULED_ROAD_VEHICLES; break;
+ case VEH_Ship: w->widget[VLW_WIDGET_CAPTION].data = STR_SCHEDULED_SHIPS; break;
+ case VEH_Aircraft: w->widget[VLW_WIDGET_CAPTION].data = STR_SCHEDULED_AIRCRAFT; break;
+ default: NOT_REACHED(); break;
+ }
+ break;
+
+ case VLW_DEPOT_LIST:
+ switch (vl->vehicle_type) {
+ case VEH_Train: w->widget[VLW_WIDGET_CAPTION].data = STR_VEHICLE_LIST_TRAIN_DEPOT; break;
+ case VEH_Road: w->widget[VLW_WIDGET_CAPTION].data = STR_VEHICLE_LIST_ROADVEH_DEPOT; break;
+ case VEH_Ship: w->widget[VLW_WIDGET_CAPTION].data = STR_VEHICLE_LIST_SHIP_DEPOT; break;
+ case VEH_Aircraft: w->widget[VLW_WIDGET_CAPTION].data = STR_VEHICLE_LIST_AIRCRAFT_DEPOT; break;
+ default: NOT_REACHED(); break;
+ }
+ break;
+ default: NOT_REACHED(); break;
+ }
+
+ switch (vl->vehicle_type) {
+ case VEH_Train:
+ w->resize.step_width = 1;
+ /* Fallthrough */
+ case VEH_Road:
+ w->vscroll.cap = 7;
+ w->resize.step_height = PLY_WND_PRC__SIZE_OF_ROW_SMALL;
+ w->resize.height = 220 - (PLY_WND_PRC__SIZE_OF_ROW_SMALL * 3); // Minimum of 4 vehicles
+ break;
+ case VEH_Ship:
+ case VEH_Aircraft:
+ w->vscroll.cap = 4;
+ w->resize.step_height = PLY_WND_PRC__SIZE_OF_ROW_BIG;
+ break;
+ default: NOT_REACHED();
+ }
+
+ w->widget[VLW_WIDGET_LIST].data = (w->vscroll.cap << 8) + 1;
+
+ /* Set up sorting. Make the window-specific _sorting variable
+ * point to the correct global _sorting struct so we are freed
+ * from having conditionals during window operation */
+ switch (vl->vehicle_type) {
+ case VEH_Train: vl->_sorting = &_sorting.train; break;
+ case VEH_Road: vl->_sorting = &_sorting.roadveh; break;
+ case VEH_Ship: vl->_sorting = &_sorting.ship; break;
+ case VEH_Aircraft: vl->_sorting = &_sorting.aircraft; break;
+ default: NOT_REACHED(); break;
+ }
+
+ vl->l.flags = VL_REBUILD | (vl->_sorting->order << (VL_DESC - 1));
+ vl->l.sort_type = vl->_sorting->criteria;
+ vl->sort_list = NULL;
+ vl->l.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS; // Set up resort timer
+}
+
+static void DrawSmallOrderList(const Vehicle *v, int x, int y)
+{
+ const Order *order;
+ int sel, i = 0;
+
+ sel = v->cur_order_index;
+
+ FOR_VEHICLE_ORDERS(v, order) {
+ if (sel == 0) DrawString(x - 6, y, STR_SMALL_RIGHT_ARROW, 16);
+ sel--;
+
+ if (order->type == OT_GOTO_STATION) {
+ if (v->type == VEH_Ship && IsBuoy(GetStation(order->dest))) continue;
+
+ SetDParam(0, order->dest);
+ DrawString(x, y, STR_A036, 0);
+
+ y += 6;
+ if (++i == 4) break;
+ }
+ }
+}
+
+static void DrawVehicleListWindow(Window *w)
+{
+ vehiclelist_d *vl = &WP(w, vehiclelist_d);
+ int x = 2;
+ int y = PLY_WND_PRC__OFFSET_TOP_WIDGET;
+ int max;
+ int i;
+ const PlayerID owner = (PlayerID)w->caption_color;
+ const Player *p = GetPlayer(owner);
+ const uint16 window_type = w->window_number & VLW_MASK;
+ const StationID station = (window_type == VLW_STATION_LIST) ? GB(w->window_number, 16, 16) : INVALID_STATION;
+ const OrderID order = (window_type == VLW_SHARED_ORDERS) ? GB(w->window_number, 16, 16) : INVALID_ORDER;
+ const uint16 depot_airport_index = (window_type == VLW_DEPOT_LIST) ? GB(w->window_number, 16, 16) : INVALID_STATION;
+
+ BuildVehicleList(vl, owner, station, order, depot_airport_index, window_type);
+ SortVehicleList(vl);
+ SetVScrollCount(w, vl->l.list_length);
+
+ /* draw the widgets */
+ switch (window_type) {
+ case VLW_SHARED_ORDERS: /* Shared Orders */
+ if (vl->l.list_length == 0) {
+ /* We can't open this window without vehicles using this order
+ * and we should close the window when deleting the order */
+ NOT_REACHED();
+ }
+ SetDParam(0, w->vscroll.count);
+ break;
+
+ case VLW_STANDARD: /* Company Name */
+ SetDParam(0, p->name_1);
+ SetDParam(1, p->name_2);
+ SetDParam(2, w->vscroll.count);
+ break;
+
+ case VLW_STATION_LIST: /* Station Name */
+ SetDParam(0, station);
+ SetDParam(1, w->vscroll.count);
+ break;
+
+ case VLW_DEPOT_LIST:
+ switch (vl->vehicle_type) {
+ case VEH_Train: SetDParam(0, STR_8800_TRAIN_DEPOT); break;
+ case VEH_Road: SetDParam(0, STR_9003_ROAD_VEHICLE_DEPOT); break;
+ case VEH_Ship: SetDParam(0, STR_9803_SHIP_DEPOT); break;
+ case VEH_Aircraft: SetDParam(0, STR_A002_AIRCRAFT_HANGAR); break;
+ default: NOT_REACHED(); break;
+ }
+ if (vl->vehicle_type == VEH_Aircraft) {
+ SetDParam(1, depot_airport_index); // Airport name
+ } else {
+ SetDParam(1, GetDepot(depot_airport_index)->town_index);
+ }
+ SetDParam(2, w->vscroll.count);
+ break;
+ default: NOT_REACHED(); break;
+ }
+
+ SetWindowWidgetsDisabledState(w, vl->l.list_length == 0,
+ VLW_WIDGET_MANAGE_VEHICLES,
+ VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN,
+ VLW_WIDGET_STOP_ALL,
+ VLW_WIDGET_START_ALL,
+ WIDGET_LIST_END);
+
+ DrawWindowWidgets(w);
+
+ /* draw sorting criteria string */
+ DrawString(85, 15, _vehicle_sort_listing[vl->l.sort_type], 0x10);
+ /* draw arrow pointing up/down for ascending/descending sorting */
+ DoDrawString(vl->l.flags & VL_DESC ? DOWNARROW : UPARROW, 69, 15, 0x10);
+
+ max = min(w->vscroll.pos + w->vscroll.cap, vl->l.list_length);
+ for (i = w->vscroll.pos; i < max; ++i) {
+ const Vehicle *v = vl->sort_list[i];
+ StringID str;
+
+ SetDParam(0, v->profit_this_year);
+ SetDParam(1, v->profit_last_year);
+
+ DrawVehicleImage(v, x + 19, y + 6, w->widget[VLW_WIDGET_LIST].right - w->widget[VLW_WIDGET_LIST].left - 20, 0, INVALID_VEHICLE);
+ DrawString(x + 19, y + w->resize.step_height - 8, STR_0198_PROFIT_THIS_YEAR_LAST_YEAR, 0);
+
+ if ((v->type == VEH_Train && v->string_id != STR_SV_TRAIN_NAME) ||
+ (v->type == VEH_Road && v->string_id != STR_SV_ROADVEH_NAME) ||
+ (v->type == VEH_Ship && v->string_id != STR_SV_SHIP_NAME) ||
+ (v->type == VEH_Aircraft && v->string_id != STR_SV_AIRCRAFT_NAME)) {
+
+ /* The vehicle got a name so we will print it */
+ SetDParam(0, v->string_id);
+ DrawString(x + 19, y, STR_01AB, 0);
+ }
+
+ if (w->resize.step_height == PLY_WND_PRC__SIZE_OF_ROW_BIG) DrawSmallOrderList(v, x + 138, y);
+
+ if (IsVehicleInDepot(v)) {
+ str = STR_021F;
+ } else {
+ str = (v->age > v->max_age - 366) ? STR_00E3 : STR_00E2;
+ }
+
+ SetDParam(0, v->unitnumber);
+ DrawString(x, y + 2, str, 0);
+
+ DrawVehicleProfitButton(v, x, y + 13);
+
+ y += w->resize.step_height;
+ }
+}
+
+/*
+ * bitmask for w->window_number
+ * 0-7 PlayerID (owner)
+ * 8-10 window type (use flags in vehicle_gui.h)
+ * 11-15 vehicle type (using VEH_, but can be compressed to fewer bytes if needed)
+ * 16-31 StationID or OrderID depending on window type (bit 8-10)
+ **/
+void PlayerVehWndProc(Window *w, WindowEvent *e)
+{
+ vehiclelist_d *vl = &WP(w, vehiclelist_d);
+
+ switch (e->event) {
+ case WE_CREATE:
+ CreateVehicleListWindow(w);
+ break;
+
+ case WE_PAINT:
+ DrawVehicleListWindow(w);
+ break;
+
+ case WE_CLICK: {
+ switch (e->we.click.widget) {
+ case VLW_WIDGET_SORT_ORDER: /* Flip sorting method ascending/descending */
+ vl->l.flags ^= VL_DESC;
+ vl->l.flags |= VL_RESORT;
+
+ vl->_sorting->order = !!(vl->l.flags & VL_DESC);
+ SetWindowDirty(w);
+ break;
+ case VLW_WIDGET_SORT_BY_TEXT: case VLW_WIDGET_SORT_BY_PULLDOWN:/* Select sorting criteria dropdown menu */
+ ShowDropDownMenu(w, _vehicle_sort_listing, vl->l.sort_type, VLW_WIDGET_SORT_BY_PULLDOWN, 0, 0);
+ return;
+ case VLW_WIDGET_LIST: { /* Matrix to show vehicles */
+ uint32 id_v = (e->we.click.pt.y - PLY_WND_PRC__OFFSET_TOP_WIDGET) / w->resize.step_height;
+ const Vehicle *v;
+
+ if (id_v >= w->vscroll.cap) return; // click out of bounds
+
+ id_v += w->vscroll.pos;
+
+ if (id_v >= vl->l.list_length) return; // click out of list bound
+
+ v = vl->sort_list[id_v];
+
+ switch (vl->vehicle_type) {
+ case VEH_Train: ShowTrainViewWindow(v); break;
+ case VEH_Road: ShowRoadVehViewWindow(v); break;
+ case VEH_Ship: ShowShipViewWindow(v); break;
+ case VEH_Aircraft: ShowAircraftViewWindow(v); break;
+ default: NOT_REACHED(); break;
+ }
+ } break;
+
+ case VLW_WIDGET_NEW_VEHICLES:
+ switch (vl->vehicle_type) {
+ case VEH_Train: ShowBuildTrainWindow(0); break;
+ case VEH_Road: ShowBuildRoadVehWindow(0); break;
+ case VEH_Ship: ShowBuildShipWindow(0); break;
+ case VEH_Aircraft: ShowBuildVehicleWindow(0, vl->vehicle_type); break;
+ }
+ break;
+
+ case VLW_WIDGET_MANAGE_VEHICLES:
+ case VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN: {
+ static StringID action_str[] = {
+ STR_REPLACE_VEHICLES,
+ STR_SEND_FOR_SERVICING,
+ STR_NULL,
+ INVALID_STRING_ID
+ };
+
+ static const StringID depot_name[] = {
+ STR_SEND_TRAIN_TO_DEPOT,
+ STR_SEND_ROAD_VEHICLE_TO_DEPOT,
+ STR_SEND_SHIP_TO_DEPOT,
+ STR_SEND_AIRCRAFT_TO_HANGAR
+ };
+
+ /* XXX - Substite string since the dropdown cannot handle dynamic strings */
+ action_str[2] = depot_name[vl->vehicle_type - VEH_Train];
+ ShowDropDownMenu(w, action_str, 0, VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN, 0, 0);
+ break;
+ }
+
+ case VLW_WIDGET_STOP_ALL:
+ case VLW_WIDGET_START_ALL:
+ DoCommandP(0, GB(w->window_number, 16, 16), (w->window_number & VLW_MASK) | (1 << 6) | (e->we.click.widget == VLW_WIDGET_START_ALL ? (1 << 5) : 0) | vl->vehicle_type, NULL, CMD_MASS_START_STOP);
+ break;
+ }
+ } break;
+
+ case WE_DROPDOWN_SELECT: /* we have selected a dropdown item in the list */
+ switch (e->we.dropdown.button) {
+ case VLW_WIDGET_SORT_BY_PULLDOWN:
+ if (vl->l.sort_type != e->we.dropdown.index) {
+ // value has changed -> resort
+ vl->l.flags |= VL_RESORT;
+ vl->l.sort_type = e->we.dropdown.index;
+ vl->_sorting->criteria = vl->l.sort_type;
+ }
+ break;
+ case VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN:
+ assert(vl->l.list_length != 0);
+
+ switch (e->we.dropdown.index) {
+ case 0: /* Replace window */
+ ShowReplaceVehicleWindow(vl->vehicle_type);
+ break;
+ case 1: /* Send for servicing */
+ DoCommandP(0, GB(w->window_number, 16, 16) /* StationID or OrderID (depending on VLW) */,
+ (w->window_number & VLW_MASK) | DEPOT_MASS_SEND | DEPOT_SERVICE,
+ NULL,
+ CMD_SEND_TO_DEPOT(vl->vehicle_type));
+ break;
+ case 2: /* Send to Depots */
+ DoCommandP(0, GB(w->window_number, 16, 16) /* StationID or OrderID (depending on VLW) */,
+ (w->window_number & VLW_MASK) | DEPOT_MASS_SEND,
+ NULL,
+ CMD_SEND_TO_DEPOT(vl->vehicle_type));
+ break;
+
+ default: NOT_REACHED();
+ }
+ break;
+ default: NOT_REACHED();
+ }
+ SetWindowDirty(w);
+ break;
+
+ case WE_DESTROY:
+ free((void*)vl->sort_list);
+ break;
+
+ case WE_TICK: /* resort the list every 20 seconds orso (10 days) */
+ if (--vl->l.resort_timer == 0) {
+ StationID station = ((w->window_number & VLW_MASK) == VLW_STATION_LIST) ? GB(w->window_number, 16, 16) : INVALID_STATION;
+ PlayerID owner = (PlayerID)w->caption_color;
+
+ DEBUG(misc, 3, "Periodic resort %d list player %d at station %d", vl->vehicle_type, owner, station);
+ vl->l.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
+ vl->l.flags |= VL_RESORT;
+ SetWindowDirty(w);
+ }
+ break;
+
+ case WE_RESIZE: /* Update the scroll + matrix */
+ w->vscroll.cap += e->we.sizing.diff.y / (int)w->resize.step_height;
+ w->widget[VLW_WIDGET_LIST].data = (w->vscroll.cap << 8) + 1;
+ break;
+ }
+}
+
+static const WindowDesc _player_vehicle_list_train_desc = {
+ WDP_AUTO, WDP_AUTO, 260, 182,
+ WC_TRAINS_LIST, 0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
+ _vehicle_list_widgets,
+ PlayerVehWndProc
+};
+
+static const WindowDesc _player_vehicle_list_road_veh_desc = {
+ WDP_AUTO, WDP_AUTO, 260, 182,
+ WC_ROADVEH_LIST,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
+ _vehicle_list_widgets,
+ PlayerVehWndProc
+};
+
+static const WindowDesc _player_vehicle_list_ship_desc = {
+ WDP_AUTO, WDP_AUTO, 260, 182,
+ WC_SHIPS_LIST,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
+ _vehicle_list_widgets,
+ PlayerVehWndProc
+};
+
+static const WindowDesc _player_vehicle_list_aircraft_desc = {
+ WDP_AUTO, WDP_AUTO, 260, 182,
+ WC_AIRCRAFT_LIST,0,
+ WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
+ _vehicle_list_widgets,
+ PlayerVehWndProc
+};
+
+static void ShowVehicleListWindowLocal(PlayerID player, byte vehicle_type, StationID station, OrderID order, uint16 depot_airport_index)
+{
+ Window *w;
+ WindowNumber num;
+
+ if (!IsValidPlayer(player)) return;
+
+ num = (vehicle_type << 11) | player;
+ if (order != INVALID_ORDER) {
+ num |= (order << 16) | VLW_SHARED_ORDERS;
+ } else if (depot_airport_index != INVALID_STATION) {
+ num |= (depot_airport_index << 16) | VLW_DEPOT_LIST;
+ } else if (station == INVALID_STATION) {
+ num |= VLW_STANDARD;
+ } else {
+ num |= (station << 16) | VLW_STATION_LIST;
+ }
+
+ /* The vehicle list windows have been unified. Just some strings need
+ * to be changed which happens in the WE_CREATE event and resizing
+ * some of the windows to the correct size */
+ switch (vehicle_type) {
+ default: NOT_REACHED();
+ case VEH_Train:
+ w = AllocateWindowDescFront(&_player_vehicle_list_train_desc, num);
+ if (w != NULL) ResizeWindow(w, 65, 38);
+ break;
+ case VEH_Road:
+ w = AllocateWindowDescFront(&_player_vehicle_list_road_veh_desc, num);
+ if (w != NULL) ResizeWindow(w, 0, 38);
+ break;
+ case VEH_Ship:
+ w = AllocateWindowDescFront(&_player_vehicle_list_ship_desc, num);
+ break;
+ case VEH_Aircraft:
+ w = AllocateWindowDescFront(&_player_vehicle_list_aircraft_desc, num);
+ break;
+ }
+
+ if (w != NULL) {
+ /* Set the minimum window size to the current window size */
+ w->resize.width = w->width;
+ w->resize.height = w->height;
+ }
+}
+
+void ShowVehicleListWindow(PlayerID player, StationID station, byte vehicle_type)
+{
+ ShowVehicleListWindowLocal(player, vehicle_type, station, INVALID_ORDER, INVALID_STATION);
+}
+
+void ShowVehWithSharedOrders(Vehicle *v, byte vehicle_type)
+{
+ if (v->orders == NULL) return; // no shared list to show
+ ShowVehicleListWindowLocal(v->owner, vehicle_type, INVALID_STATION, v->orders->index, INVALID_STATION);
+}
+
+void ShowVehDepotOrders(PlayerID player, byte vehicle_type, TileIndex depot_tile)
+{
+ uint16 depot_airport_index;
+
+ if (vehicle_type == VEH_Aircraft) {
+ depot_airport_index = GetStationIndex(depot_tile);
+ } else {
+ Depot *depot = GetDepotByTile(depot_tile);
+ if (depot == NULL) return; // no depot to show
+ depot_airport_index = depot->index;
+ }
+ ShowVehicleListWindowLocal(player, vehicle_type, INVALID_STATION, INVALID_ORDER, depot_airport_index);
+}
diff --git a/src/vehicle_gui.h b/src/vehicle_gui.h
new file mode 100644
index 000000000..76f6a5bcc
--- /dev/null
+++ b/src/vehicle_gui.h
@@ -0,0 +1,77 @@
+/* $Id$ */
+
+#ifndef VEHICLE_GUI_H
+#define VEHICLE_GUI_H
+
+#include "window.h"
+#include "vehicle.h"
+
+void DrawVehicleProfitButton(const Vehicle *v, int x, int y);
+void ShowVehicleRefitWindow(const Vehicle *v, VehicleOrderID order);
+void InitializeVehiclesGuiList(void);
+
+/* sorter stuff */
+void RebuildVehicleLists(void);
+void ResortVehicleLists(void);
+
+#define PERIODIC_RESORT_DAYS 10
+
+/* Vehicle List Window type flags */
+enum {
+ VLW_STANDARD = 0 << 8,
+ VLW_SHARED_ORDERS = 1 << 8,
+ VLW_STATION_LIST = 2 << 8,
+ VLW_DEPOT_LIST = 3 << 8,
+ VLW_MASK = 0x700,
+};
+
+static inline bool ValidVLWFlags(uint16 flags)
+{
+ return (flags == VLW_STANDARD || flags == VLW_SHARED_ORDERS || flags == VLW_STATION_LIST || flags == VLW_DEPOT_LIST);
+}
+
+void PlayerVehWndProc(Window *w, WindowEvent *e);
+
+void DrawTrainEnginePurchaseInfo(int x, int y, uint w, EngineID engine_number);
+void DrawTrainWagonPurchaseInfo(int x, int y, uint w, EngineID engine_number);
+void DrawRoadVehPurchaseInfo(int x, int y, uint w, EngineID engine_number);
+void DrawAircraftPurchaseInfo(int x, int y, uint w, EngineID engine_number);
+void DrawShipPurchaseInfo(int x, int y, uint w, EngineID engine_number);
+
+void DrawTrainImage(const Vehicle *v, int x, int y, int count, int skip, VehicleID selection);
+void DrawRoadVehImage(const Vehicle *v, int x, int y, VehicleID selection);
+void DrawShipImage(const Vehicle *v, int x, int y, VehicleID selection);
+void DrawAircraftImage(const Vehicle *v, int x, int y, VehicleID selection);
+
+void ShowBuildTrainWindow(TileIndex tile);
+void ShowBuildRoadVehWindow(TileIndex tile);
+void ShowBuildShipWindow(TileIndex tile);
+void ShowBuildVehicleWindow(TileIndex tile, byte type);
+
+void ChangeVehicleViewWindow(const Vehicle *from_v, const Vehicle *to_v);
+
+uint ShowAdditionalText(int x, int y, uint w, EngineID engine);
+uint ShowRefitOptionsList(int x, int y, uint w, EngineID engine);
+
+void ShowVehicleListWindow(PlayerID player, StationID station, byte vehicle_type);
+void ShowVehWithSharedOrders(Vehicle *v, byte vehicle_type);
+void ShowVehDepotOrders(PlayerID player, byte vehicle_type, TileIndex depot_tile);
+
+
+static inline void DrawVehicleImage(const Vehicle *v, int x, int y, int count, int skip, VehicleID selection)
+{
+ switch (v->type) {
+ case VEH_Train: DrawTrainImage(v, x, y, count, skip, selection); break;
+ case VEH_Road: DrawRoadVehImage(v, x, y, selection); break;
+ case VEH_Ship: DrawShipImage(v, x, y, selection); break;
+ case VEH_Aircraft: DrawAircraftImage(v, x, y, selection); break;
+ default: NOT_REACHED();
+ }
+}
+
+static inline byte GetVehicleListHeight(byte type)
+{
+ return (type == VEH_Train || type == VEH_Road) ? 14 : 24;
+}
+
+#endif /* VEHICLE_GUI_H */
diff --git a/src/video/cocoa_keys.h b/src/video/cocoa_keys.h
new file mode 100644
index 000000000..1e69c1425
--- /dev/null
+++ b/src/video/cocoa_keys.h
@@ -0,0 +1,127 @@
+/* $Id$ */
+
+#ifndef COCOA_KEYS_H
+#define COCOA_KEYS_H
+
+/* From SDL_QuartzKeys.h */
+/* These are the Macintosh key scancode constants -- from Inside Macintosh */
+
+#define QZ_ESCAPE 0x35
+#define QZ_F1 0x7A
+#define QZ_F2 0x78
+#define QZ_F3 0x63
+#define QZ_F4 0x76
+#define QZ_F5 0x60
+#define QZ_F6 0x61
+#define QZ_F7 0x62
+#define QZ_F8 0x64
+#define QZ_F9 0x65
+#define QZ_F10 0x6D
+#define QZ_F11 0x67
+#define QZ_F12 0x6F
+#define QZ_PRINT 0x69
+#define QZ_SCROLLOCK 0x6B
+#define QZ_PAUSE 0x71
+#define QZ_POWER 0x7F
+#define QZ_BACKQUOTE 0x0A
+#define QZ_BACKQUOTE2 0x32
+#define QZ_1 0x12
+#define QZ_2 0x13
+#define QZ_3 0x14
+#define QZ_4 0x15
+#define QZ_5 0x17
+#define QZ_6 0x16
+#define QZ_7 0x1A
+#define QZ_8 0x1C
+#define QZ_9 0x19
+#define QZ_0 0x1D
+#define QZ_MINUS 0x1B
+#define QZ_EQUALS 0x18
+#define QZ_BACKSPACE 0x33
+#define QZ_INSERT 0x72
+#define QZ_HOME 0x73
+#define QZ_PAGEUP 0x74
+#define QZ_NUMLOCK 0x47
+#define QZ_KP_EQUALS 0x51
+#define QZ_KP_DIVIDE 0x4B
+#define QZ_KP_MULTIPLY 0x43
+#define QZ_TAB 0x30
+#define QZ_q 0x0C
+#define QZ_w 0x0D
+#define QZ_e 0x0E
+#define QZ_r 0x0F
+#define QZ_t 0x11
+#define QZ_y 0x10
+#define QZ_u 0x20
+#define QZ_i 0x22
+#define QZ_o 0x1F
+#define QZ_p 0x23
+#define QZ_LEFTBRACKET 0x21
+#define QZ_RIGHTBRACKET 0x1E
+#define QZ_BACKSLASH 0x2A
+#define QZ_DELETE 0x75
+#define QZ_END 0x77
+#define QZ_PAGEDOWN 0x79
+#define QZ_KP7 0x59
+#define QZ_KP8 0x5B
+#define QZ_KP9 0x5C
+#define QZ_KP_MINUS 0x4E
+#define QZ_CAPSLOCK 0x39
+#define QZ_a 0x00
+#define QZ_s 0x01
+#define QZ_d 0x02
+#define QZ_f 0x03
+#define QZ_g 0x05
+#define QZ_h 0x04
+#define QZ_j 0x26
+#define QZ_k 0x28
+#define QZ_l 0x25
+#define QZ_SEMICOLON 0x29
+#define QZ_QUOTE 0x27
+#define QZ_RETURN 0x24
+#define QZ_KP4 0x56
+#define QZ_KP5 0x57
+#define QZ_KP6 0x58
+#define QZ_KP_PLUS 0x45
+#define QZ_LSHIFT 0x38
+#define QZ_z 0x06
+#define QZ_x 0x07
+#define QZ_c 0x08
+#define QZ_v 0x09
+#define QZ_b 0x0B
+#define QZ_n 0x2D
+#define QZ_m 0x2E
+#define QZ_COMMA 0x2B
+#define QZ_PERIOD 0x2F
+#define QZ_SLASH 0x2C
+#if 1 /* Panther now defines right side keys */
+#define QZ_RSHIFT 0x3C
+#endif
+#define QZ_UP 0x7E
+#define QZ_KP1 0x53
+#define QZ_KP2 0x54
+#define QZ_KP3 0x55
+#define QZ_KP_ENTER 0x4C
+#define QZ_LCTRL 0x3B
+#define QZ_LALT 0x3A
+#define QZ_LMETA 0x37
+#define QZ_SPACE 0x31
+#if 1 /* Panther now defines right side keys */
+#define QZ_RMETA 0x36
+#define QZ_RALT 0x3D
+#define QZ_RCTRL 0x3E
+#endif
+#define QZ_LEFT 0x7B
+#define QZ_DOWN 0x7D
+#define QZ_RIGHT 0x7C
+#define QZ_KP0 0x52
+#define QZ_KP_PERIOD 0x41
+
+/* Wierd, these keys are on my iBook under MacOS X */
+#define QZ_IBOOK_ENTER 0x34
+#define QZ_IBOOK_LEFT 0x3B
+#define QZ_IBOOK_RIGHT 0x3C
+#define QZ_IBOOK_DOWN 0x3D
+#define QZ_IBOOK_UP 0x3E
+
+#endif
diff --git a/src/video/cocoa_v.h b/src/video/cocoa_v.h
new file mode 100644
index 000000000..93d7b2639
--- /dev/null
+++ b/src/video/cocoa_v.h
@@ -0,0 +1,10 @@
+/* $Id$ */
+
+#ifndef VIDEO_COCOA_H
+#define VIDEO_COCOA_H
+
+#include "../hal.h"
+
+extern const HalVideoDriver _cocoa_video_driver;
+
+#endif
diff --git a/src/video/cocoa_v.m b/src/video/cocoa_v.m
new file mode 100644
index 000000000..f93f86ca4
--- /dev/null
+++ b/src/video/cocoa_v.m
@@ -0,0 +1,2064 @@
+/* $Id$ */
+
+/******************************************************************************
+ * Cocoa video driver *
+ * Known things left to do: *
+ * Nothing at the moment. *
+ ******************************************************************************/
+
+#ifdef WITH_COCOA
+
+#import <Cocoa/Cocoa.h>
+#import <sys/time.h> /* gettimeofday */
+#import <sys/param.h> /* for MAXPATHLEN */
+#import <unistd.h>
+
+/* Portions of CPS.h */
+typedef struct CPSProcessSerNum {
+ UInt32 lo;
+ UInt32 hi;
+} CPSProcessSerNum;
+
+extern OSErr CPSGetCurrentProcess(CPSProcessSerNum* psn);
+extern OSErr CPSEnableForegroundOperation(CPSProcessSerNum* psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
+extern OSErr CPSSetFrontProcess(CPSProcessSerNum* psn);
+
+/* From Menus.h (according to Xcode Developer Documentation) */
+extern void ShowMenuBar(void);
+extern void HideMenuBar(void);
+
+/* Disables a warning. This is needed since the method exists but has been dropped from the header, supposedly as of 10.4. */
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
+@interface NSApplication(NSAppleMenu)
+- (void)setAppleMenu:(NSMenu *)menu;
+@end
+#endif
+
+
+/* Defined in ppc/param.h or i386/param.h included from sys/param.h */
+#undef ALIGN
+/* Defined in stdbool.h */
+#ifndef __cplusplus
+# ifndef __BEOS__
+# undef bool
+# undef false
+# undef true
+# endif
+#endif
+
+#include "../stdafx.h"
+#include "../openttd.h"
+#include "../debug.h"
+#include "../functions.h"
+#include "../gfx.h"
+#include "../macros.h"
+#include "../sdl.h"
+#include "../window.h"
+#include "../network/network.h"
+#include "../variables.h"
+#include "../os/macosx/splash.h"
+
+#include "cocoa_v.h"
+#include "cocoa_keys.h"
+
+#undef Point
+#undef Rect
+
+
+/* Subclass of NSWindow to fix genie effect and support resize events */
+@interface OTTD_QuartzWindow : NSWindow
+- (void)miniaturize:(id)sender;
+- (void)display;
+- (void)setFrame:(NSRect)frameRect display:(BOOL)flag;
+- (void)appDidHide:(NSNotification*)note;
+- (void)appWillUnhide:(NSNotification*)note;
+- (void)appDidUnhide:(NSNotification*)note;
+- (id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag;
+@end
+
+/* Delegate for our NSWindow to send ask for quit on close */
+@interface OTTD_QuartzWindowDelegate : NSObject
+- (BOOL)windowShouldClose:(id)sender;
+@end
+
+@interface OTTDMain : NSObject
+@end
+
+
+/* Structure for rez switch gamma fades
+ * We can hide the monitor flicker by setting the gamma tables to 0
+ */
+#define QZ_GAMMA_TABLE_SIZE 256
+
+typedef struct {
+ CGGammaValue red[QZ_GAMMA_TABLE_SIZE];
+ CGGammaValue green[QZ_GAMMA_TABLE_SIZE];
+ CGGammaValue blue[QZ_GAMMA_TABLE_SIZE];
+} OTTD_QuartzGammaTable;
+
+/* Add methods to get at private members of NSScreen.
+ * Since there is a bug in Apple's screen switching code that does not update
+ * this variable when switching to fullscreen, we'll set it manually (but only
+ * for the main screen).
+ */
+@interface NSScreen (NSScreenAccess)
+ - (void) setFrame:(NSRect)frame;
+@end
+
+@implementation NSScreen (NSScreenAccess)
+- (void) setFrame:(NSRect)frame;
+{
+ _frame = frame;
+}
+@end
+
+
+static void QZ_Draw(void);
+static void QZ_UnsetVideoMode(void);
+static void QZ_UpdatePalette(uint start, uint count);
+static void QZ_WarpCursor(int x, int y);
+static void QZ_ShowMouse(void);
+static void QZ_HideMouse(void);
+static void CocoaVideoFullScreen(bool full_screen);
+
+
+static NSAutoreleasePool *_ottd_autorelease_pool;
+static OTTDMain *_ottd_main;
+
+
+static struct CocoaVideoData {
+ bool isset;
+ bool issetting;
+
+ CGDirectDisplayID display_id; /* 0 == main display (only support single display) */
+ CFDictionaryRef mode; /* current mode of the display */
+ CFDictionaryRef save_mode; /* original mode of the display */
+ CFArrayRef mode_list; /* list of available fullscreen modes */
+ CGDirectPaletteRef palette; /* palette of an 8-bit display */
+
+ uint32 device_width;
+ uint32 device_height;
+ uint32 device_bpp;
+
+ void *realpixels;
+ uint8 *pixels;
+ uint32 width;
+ uint32 height;
+ uint32 pitch;
+ bool fullscreen;
+
+ unsigned int current_mods;
+ bool tab_is_down;
+ bool emulating_right_button;
+
+ bool cursor_visible;
+ bool active;
+
+#ifdef _DEBUG
+ uint32 tEvent;
+#endif
+
+ OTTD_QuartzWindow *window;
+ NSQuickDrawView *qdview;
+
+#define MAX_DIRTY_RECTS 100
+ OTTDRect dirty_rects[MAX_DIRTY_RECTS];
+ int num_dirty_rects;
+
+ uint16 palette16[256];
+ uint32 palette32[256];
+} _cocoa_video_data;
+
+static bool _cocoa_video_started = false;
+static bool _cocoa_video_dialog = false;
+
+
+
+
+/******************************************************************************
+ * Game loop and accessories *
+ ******************************************************************************/
+
+static uint32 GetTick(void)
+{
+ struct timeval tim;
+
+ gettimeofday(&tim, NULL);
+ return tim.tv_usec / 1000 + tim.tv_sec * 1000;
+}
+
+static void QZ_CheckPaletteAnim(void)
+{
+ if (_pal_last_dirty != -1) {
+ QZ_UpdatePalette(_pal_first_dirty, _pal_last_dirty - _pal_first_dirty + 1);
+ _pal_last_dirty = -1;
+ }
+}
+
+
+
+typedef struct VkMapping {
+ unsigned short vk_from;
+ byte map_to;
+} VkMapping;
+
+#define AS(x, z) {x, z}
+
+static const VkMapping _vk_mapping[] = {
+ AS(QZ_BACKQUOTE, WKC_BACKQUOTE), // key left of '1'
+ AS(QZ_BACKQUOTE2, WKC_BACKQUOTE), // some keyboards have it on another scancode
+
+ // Pageup stuff + up/down
+ //AM(SDLK_PAGEUP, SDLK_PAGEDOWN, WKC_PAGEUP, WKC_PAGEDOWN), <==== Does this include HOME/END?
+ AS(QZ_PAGEUP, WKC_PAGEUP),
+ AS(QZ_PAGEDOWN, WKC_PAGEDOWN),
+
+ AS(QZ_UP, WKC_UP),
+ AS(QZ_DOWN, WKC_DOWN),
+ AS(QZ_LEFT, WKC_LEFT),
+ AS(QZ_RIGHT, WKC_RIGHT),
+
+ AS(QZ_HOME, WKC_HOME),
+ AS(QZ_END, WKC_END),
+
+ AS(QZ_INSERT, WKC_INSERT),
+ AS(QZ_DELETE, WKC_DELETE),
+
+ // Letters. QZ_[a-z] is not in numerical order so we can't use AM(...)
+ AS(QZ_a, 'A'),
+ AS(QZ_b, 'B'),
+ AS(QZ_c, 'C'),
+ AS(QZ_d, 'D'),
+ AS(QZ_e, 'E'),
+ AS(QZ_f, 'F'),
+ AS(QZ_g, 'G'),
+ AS(QZ_h, 'H'),
+ AS(QZ_i, 'I'),
+ AS(QZ_j, 'J'),
+ AS(QZ_k, 'K'),
+ AS(QZ_l, 'L'),
+ AS(QZ_m, 'M'),
+ AS(QZ_n, 'N'),
+ AS(QZ_o, 'O'),
+ AS(QZ_p, 'P'),
+ AS(QZ_q, 'Q'),
+ AS(QZ_r, 'R'),
+ AS(QZ_s, 'S'),
+ AS(QZ_t, 'T'),
+ AS(QZ_u, 'U'),
+ AS(QZ_v, 'V'),
+ AS(QZ_w, 'W'),
+ AS(QZ_x, 'X'),
+ AS(QZ_y, 'Y'),
+ AS(QZ_z, 'Z'),
+ // Same thing for digits
+ AS(QZ_0, '0'),
+ AS(QZ_1, '1'),
+ AS(QZ_2, '2'),
+ AS(QZ_3, '3'),
+ AS(QZ_4, '4'),
+ AS(QZ_5, '5'),
+ AS(QZ_6, '6'),
+ AS(QZ_7, '7'),
+ AS(QZ_8, '8'),
+ AS(QZ_9, '9'),
+
+ AS(QZ_ESCAPE, WKC_ESC),
+ AS(QZ_PAUSE, WKC_PAUSE),
+ AS(QZ_BACKSPACE, WKC_BACKSPACE),
+
+ AS(QZ_SPACE, WKC_SPACE),
+ AS(QZ_RETURN, WKC_RETURN),
+ AS(QZ_TAB, WKC_TAB),
+
+ // Function keys
+ AS(QZ_F1, WKC_F1),
+ AS(QZ_F2, WKC_F2),
+ AS(QZ_F3, WKC_F3),
+ AS(QZ_F4, WKC_F4),
+ AS(QZ_F5, WKC_F5),
+ AS(QZ_F6, WKC_F6),
+ AS(QZ_F7, WKC_F7),
+ AS(QZ_F8, WKC_F8),
+ AS(QZ_F9, WKC_F9),
+ AS(QZ_F10, WKC_F10),
+ AS(QZ_F11, WKC_F11),
+ AS(QZ_F12, WKC_F12),
+
+ // Numeric part.
+ AS(QZ_KP0, WKC_NUM_0),
+ AS(QZ_KP1, WKC_NUM_1),
+ AS(QZ_KP2, WKC_NUM_2),
+ AS(QZ_KP3, WKC_NUM_3),
+ AS(QZ_KP4, WKC_NUM_4),
+ AS(QZ_KP5, WKC_NUM_5),
+ AS(QZ_KP6, WKC_NUM_6),
+ AS(QZ_KP7, WKC_NUM_7),
+ AS(QZ_KP8, WKC_NUM_8),
+ AS(QZ_KP9, WKC_NUM_9),
+ AS(QZ_KP_DIVIDE, WKC_NUM_DIV),
+ AS(QZ_KP_MULTIPLY, WKC_NUM_MUL),
+ AS(QZ_KP_MINUS, WKC_NUM_MINUS),
+ AS(QZ_KP_PLUS, WKC_NUM_PLUS),
+ AS(QZ_KP_ENTER, WKC_NUM_ENTER),
+ AS(QZ_KP_PERIOD, WKC_NUM_DECIMAL)
+};
+
+
+static uint32 QZ_MapKey(unsigned short sym)
+{
+ const VkMapping *map;
+ uint32 key = 0;
+
+ for (map = _vk_mapping; map != endof(_vk_mapping); ++map) {
+ if (sym == map->vk_from) {
+ key = map->map_to;
+ break;
+ }
+ }
+
+ if (_cocoa_video_data.current_mods & NSShiftKeyMask) key |= WKC_SHIFT;
+ if (_cocoa_video_data.current_mods & NSControlKeyMask) key |= WKC_CTRL;
+ if (_cocoa_video_data.current_mods & NSAlternateKeyMask) key |= WKC_ALT;
+ if (_cocoa_video_data.current_mods & NSCommandKeyMask) key |= WKC_META;
+
+ return key << 16;
+}
+
+static void QZ_KeyEvent(unsigned short keycode, unsigned short unicode, BOOL down)
+{
+ switch (keycode) {
+ case QZ_UP: SB(_dirkeys, 1, 1, down); break;
+ case QZ_DOWN: SB(_dirkeys, 3, 1, down); break;
+ case QZ_LEFT: SB(_dirkeys, 0, 1, down); break;
+ case QZ_RIGHT: SB(_dirkeys, 2, 1, down); break;
+
+ case QZ_TAB: _cocoa_video_data.tab_is_down = down; break;
+
+ case QZ_RETURN:
+ case QZ_f:
+ if (down && (
+ (_cocoa_video_data.current_mods & NSControlKeyMask) ||
+ (_cocoa_video_data.current_mods & NSCommandKeyMask)
+ )) {
+ CocoaVideoFullScreen(!_fullscreen);
+ }
+ break;
+ }
+
+ if (down) {
+ uint32 pressed_key = QZ_MapKey(keycode) | unicode;
+ HandleKeypress(pressed_key);
+ DEBUG(driver, 2, "cocoa_v: QZ_KeyEvent: %x (%x), down, mapping: %x", keycode, unicode, pressed_key);
+ } else {
+ DEBUG(driver, 2, "cocoa_v: QZ_KeyEvent: %x (%x), up", keycode, unicode);
+ }
+}
+
+static void QZ_DoUnsidedModifiers(unsigned int newMods)
+{
+ const int mapping[] = { QZ_CAPSLOCK, QZ_LSHIFT, QZ_LCTRL, QZ_LALT, QZ_LMETA };
+
+ int i;
+ int bit;
+
+ if (_cocoa_video_data.current_mods == newMods) return;
+
+ /* Iterate through the bits, testing each against the current modifiers */
+ for (i = 0, bit = NSAlphaShiftKeyMask; bit <= NSCommandKeyMask; bit <<= 1, ++i) {
+ unsigned int currentMask, newMask;
+
+ currentMask = _cocoa_video_data.current_mods & bit;
+ newMask = newMods & bit;
+
+ if (currentMask && currentMask != newMask) { /* modifier up event */
+ /* If this was Caps Lock, we need some additional voodoo to make SDL happy (is this needed in ottd?) */
+ if (bit == NSAlphaShiftKeyMask) QZ_KeyEvent(mapping[i], 0, YES);
+ QZ_KeyEvent(mapping[i], 0, NO);
+ } else if (newMask && currentMask != newMask) { /* modifier down event */
+ QZ_KeyEvent(mapping[i], 0, YES);
+ /* If this was Caps Lock, we need some additional voodoo to make SDL happy (is this needed in ottd?) */
+ if (bit == NSAlphaShiftKeyMask) QZ_KeyEvent(mapping[i], 0, NO);
+ }
+ }
+
+ _cocoa_video_data.current_mods = newMods;
+}
+
+static void QZ_MouseMovedEvent(int x, int y)
+{
+ if (_cursor.fix_at) {
+ int dx = x - _cursor.pos.x;
+ int dy = y - _cursor.pos.y;
+
+ if (dx != 0 || dy != 0) {
+ _cursor.delta.x += dx;
+ _cursor.delta.y += dy;
+
+ QZ_WarpCursor(_cursor.pos.x, _cursor.pos.y);
+ }
+ } else {
+ _cursor.delta.x = x - _cursor.pos.x;
+ _cursor.delta.y = y - _cursor.pos.y;
+ _cursor.pos.x = x;
+ _cursor.pos.y = y;
+ _cursor.dirty = true;
+ }
+ HandleMouseEvents();
+}
+
+
+static void QZ_MouseButtonEvent(int button, BOOL down)
+{
+ switch (button) {
+ case 0:
+ if (down) {
+ _left_button_down = true;
+ } else {
+ _left_button_down = false;
+ _left_button_clicked = false;
+ }
+ HandleMouseEvents();
+ break;
+
+ case 1:
+ if (down) {
+ _right_button_down = true;
+ _right_button_clicked = true;
+ } else {
+ _right_button_down = false;
+ }
+ HandleMouseEvents();
+ break;
+ }
+}
+
+
+static inline NSPoint QZ_GetMouseLocation(NSEvent *event)
+{
+ NSPoint pt;
+
+ if (_cocoa_video_data.fullscreen) {
+ pt = [ NSEvent mouseLocation ];
+ pt.y = _cocoa_video_data.height - pt.y;
+ } else {
+ pt = [event locationInWindow];
+ pt = [_cocoa_video_data.qdview convertPoint:pt fromView:nil];
+ }
+
+ return pt;
+}
+
+static bool QZ_MouseIsInsideView(NSPoint *pt)
+{
+ if (_cocoa_video_data.fullscreen) {
+ return pt->x >= 0 && pt->y >= 0 && pt->x < _cocoa_video_data.width && pt->y < _cocoa_video_data.height;
+ } else {
+ return [ _cocoa_video_data.qdview mouse:*pt inRect:[ _cocoa_video_data.qdview bounds ] ];
+ }
+}
+
+
+static bool QZ_PollEvent(void)
+{
+ NSEvent *event;
+ NSPoint pt;
+ NSString *chars;
+#ifdef _DEBUG
+ uint32 et0, et;
+#endif
+
+#ifdef _DEBUG
+ et0 = GetTick();
+#endif
+ event = [ NSApp nextEventMatchingMask:NSAnyEventMask
+ untilDate: [ NSDate distantPast ]
+ inMode: NSDefaultRunLoopMode dequeue:YES ];
+#ifdef _DEBUG
+ et = GetTick();
+ _cocoa_video_data.tEvent+= et - et0;
+#endif
+
+ if (event == nil) return false;
+ if (!_cocoa_video_data.active) {
+ QZ_ShowMouse();
+ [NSApp sendEvent:event];
+ return true;
+ }
+
+ QZ_DoUnsidedModifiers( [ event modifierFlags ] );
+
+ switch ([event type]) {
+ case NSMouseMoved:
+ case NSOtherMouseDragged:
+ case NSRightMouseDragged:
+ case NSLeftMouseDragged:
+ pt = QZ_GetMouseLocation(event);
+ if (!QZ_MouseIsInsideView(&pt) &&
+ !_cocoa_video_data.emulating_right_button) {
+ QZ_ShowMouse();
+ [NSApp sendEvent:event];
+ break;
+ }
+
+ QZ_HideMouse();
+ QZ_MouseMovedEvent((int)pt.x, (int)pt.y);
+ break;
+
+ case NSLeftMouseDown:
+ if (!([ event modifierFlags ] & NSCommandKeyMask) ||
+ !QZ_MouseIsInsideView(&pt)) {
+ [NSApp sendEvent:event];
+ }
+
+ pt = QZ_GetMouseLocation(event);
+ if (!QZ_MouseIsInsideView(&pt)) {
+ QZ_ShowMouse();
+ break;
+ }
+
+ QZ_HideMouse();
+ QZ_MouseMovedEvent((int)pt.x, (int)pt.y);
+
+ /* Right mouse button emulation */
+ if ([ event modifierFlags ] & NSCommandKeyMask) {
+ _cocoa_video_data.emulating_right_button = true;
+ QZ_MouseButtonEvent(1, YES);
+ } else {
+ QZ_MouseButtonEvent(0, YES);
+ }
+ break;
+
+ case NSLeftMouseUp:
+ [NSApp sendEvent:event];
+
+ pt = QZ_GetMouseLocation(event);
+ if (!QZ_MouseIsInsideView(&pt)) {
+ QZ_ShowMouse();
+ break;
+ }
+
+ QZ_HideMouse();
+ QZ_MouseMovedEvent((int)pt.x, (int)pt.y);
+
+ /* Right mouse button emulation */
+ if (_cocoa_video_data.emulating_right_button) {
+ _cocoa_video_data.emulating_right_button = false;
+ QZ_MouseButtonEvent(1, NO);
+ } else {
+ QZ_MouseButtonEvent(0, NO);
+ }
+ break;
+
+ case NSRightMouseDown:
+ pt = QZ_GetMouseLocation(event);
+ if (!QZ_MouseIsInsideView(&pt)) {
+ QZ_ShowMouse();
+ [NSApp sendEvent:event];
+ break;
+ }
+
+ QZ_HideMouse();
+ QZ_MouseMovedEvent((int)pt.x, (int)pt.y);
+ QZ_MouseButtonEvent(1, YES);
+ break;
+
+ case NSRightMouseUp:
+ pt = QZ_GetMouseLocation(event);
+ if (!QZ_MouseIsInsideView(&pt)) {
+ QZ_ShowMouse();
+ [NSApp sendEvent:event];
+ break;
+ }
+
+ QZ_HideMouse();
+ QZ_MouseMovedEvent((int)pt.x, (int)pt.y);
+ QZ_MouseButtonEvent(1, NO);
+ break;
+
+#if 0
+ /* This is not needed since openttd currently only use two buttons */
+ case NSOtherMouseDown:
+ pt = QZ_GetMouseLocation(event);
+ if (!QZ_MouseIsInsideView(&pt)) {
+ QZ_ShowMouse();
+ [NSApp sendEvent:event];
+ break;
+ }
+
+ QZ_HideMouse();
+ QZ_MouseMovedEvent((int)pt.x, (int)pt.y);
+ QZ_MouseButtonEvent([ event buttonNumber ], YES);
+ break;
+
+ case NSOtherMouseUp:
+ pt = QZ_GetMouseLocation(event);
+ if (!QZ_MouseIsInsideView(&pt)) {
+ QZ_ShowMouse();
+ [NSApp sendEvent:event];
+ break;
+ }
+
+ QZ_HideMouse();
+ QZ_MouseMovedEvent((int)pt.x, (int)pt.y);
+ QZ_MouseButtonEvent([ event buttonNumber ], NO);
+ break;
+#endif
+
+ case NSKeyDown:
+ /* Quit, hide and minimize */
+ switch ([event keyCode]) {
+ case QZ_q:
+ case QZ_h:
+ case QZ_m:
+ if ([ event modifierFlags ] & NSCommandKeyMask) {
+ [NSApp sendEvent:event];
+ }
+ break;
+ }
+
+ chars = [ event characters ];
+ QZ_KeyEvent([event keyCode], [ chars length ] ? [ chars characterAtIndex:0 ] : 0, YES);
+ break;
+
+ case NSKeyUp:
+ /* Quit, hide and minimize */
+ switch ([event keyCode]) {
+ case QZ_q:
+ case QZ_h:
+ case QZ_m:
+ if ([ event modifierFlags ] & NSCommandKeyMask) {
+ [NSApp sendEvent:event];
+ }
+ break;
+ }
+
+ chars = [ event characters ];
+ QZ_KeyEvent([event keyCode], [ chars length ] ? [ chars characterAtIndex:0 ] : 0, NO);
+ break;
+
+ case NSScrollWheel:
+ if ([ event deltaY ] > 0.0) { /* Scroll up */
+ _cursor.wheel--;
+ } else if ([ event deltaY ] < 0.0) { /* Scroll down */
+ _cursor.wheel++;
+ } /* else: deltaY was 0.0 and we don't want to do anything */
+ break;
+
+ default:
+ [NSApp sendEvent:event];
+ }
+
+ return true;
+}
+
+
+static void QZ_GameLoop(void)
+{
+ uint32 next_tick = GetTick() + 30;
+ uint32 cur_ticks;
+ uint32 pal_tick = 0;
+#ifdef _DEBUG
+ uint32 et0, et, st0, st;
+#endif
+ int i;
+
+#ifdef _DEBUG
+ et0 = GetTick();
+ st = 0;
+#endif
+
+ _screen.dst_ptr = _cocoa_video_data.pixels;
+ DisplaySplashImage();
+ QZ_CheckPaletteAnim();
+ QZ_Draw();
+ CSleep(1);
+
+ for (i = 0; i < 2; i++) GameLoop();
+
+ _screen.dst_ptr = _cocoa_video_data.pixels;
+ UpdateWindows();
+ QZ_CheckPaletteAnim();
+ QZ_Draw();
+ CSleep(1);
+
+ for (;;) {
+ InteractiveRandom(); // randomness
+
+ while (QZ_PollEvent()) {}
+
+ if (_exit_game) break;
+
+#if defined(_DEBUG)
+ if (_cocoa_video_data.current_mods & NSShiftKeyMask)
+#else
+ if (_cocoa_video_data.tab_is_down)
+#endif
+ {
+ if (!_networking && _game_mode != GM_MENU) _fast_forward |= 2;
+ } else if (_fast_forward & 2) {
+ _fast_forward = 0;
+ }
+
+ cur_ticks = GetTick();
+ if ((_fast_forward && !_pause) || cur_ticks > next_tick)
+ next_tick = cur_ticks;
+
+ if (cur_ticks == next_tick) {
+ next_tick += 30;
+
+ _ctrl_pressed = !!(_cocoa_video_data.current_mods & NSControlKeyMask);
+ _shift_pressed = !!(_cocoa_video_data.current_mods & NSShiftKeyMask);
+#ifdef _DEBUG
+ _dbg_screen_rect = !!(_cocoa_video_data.current_mods & NSAlphaShiftKeyMask);
+#endif
+
+ GameLoop();
+
+ _screen.dst_ptr = _cocoa_video_data.pixels;
+ UpdateWindows();
+ if (++pal_tick > 4) {
+ QZ_CheckPaletteAnim();
+ pal_tick = 1;
+ }
+ QZ_Draw();
+ } else {
+#ifdef _DEBUG
+ st0 = GetTick();
+#endif
+ CSleep(1);
+#ifdef _DEBUG
+ st += GetTick() - st0;
+#endif
+ _screen.dst_ptr = _cocoa_video_data.pixels;
+ DrawTextMessage();
+ DrawMouseCursor();
+ QZ_Draw();
+ }
+ }
+
+#ifdef _DEBUG
+ et = GetTick();
+
+ DEBUG(driver, 1, "cocoa_v: nextEventMatchingMask took %i ms total", _cocoa_video_data.tEvent);
+ DEBUG(driver, 1, "cocoa_v: game loop took %i ms total (%i ms without sleep)", et - et0, et - et0 - st);
+ DEBUG(driver, 1, "cocoa_v: (nextEventMatchingMask total)/(game loop total) is %f%%", (double)_cocoa_video_data.tEvent / (double)(et - et0) * 100);
+ DEBUG(driver, 1, "cocoa_v: (nextEventMatchingMask total)/(game loop without sleep total) is %f%%", (double)_cocoa_video_data.tEvent / (double)(et - et0 - st) * 100);
+#endif
+}
+
+
+/******************************************************************************
+ * Windowed mode *
+ ******************************************************************************/
+
+/* This function makes the *game region* of the window 100% opaque.
+ * The genie effect uses the alpha component. Otherwise,
+ * it doesn't seem to matter what value it has.
+ */
+static void QZ_SetPortAlphaOpaque(void)
+{
+ if (_cocoa_video_data.device_bpp == 32) {
+ uint32* pixels = (uint32*)_cocoa_video_data.realpixels;
+ uint32 rowPixels = _cocoa_video_data.pitch / 4;
+ uint32 i;
+ uint32 j;
+
+ for (i = 0; i < _cocoa_video_data.height; i++)
+ for (j = 0; j < _cocoa_video_data.width; j++) {
+ pixels[i * rowPixels + j] |= 0xFF000000;
+ }
+ }
+}
+
+
+@implementation OTTD_QuartzWindow
+
+/* we override these methods to fix the miniaturize animation/dock icon bug */
+- (void)miniaturize:(id)sender
+{
+ /* make the alpha channel opaque so anim won't have holes in it */
+ QZ_SetPortAlphaOpaque ();
+
+ /* window is hidden now */
+ _cocoa_video_data.active = false;
+
+ QZ_ShowMouse();
+
+ [ super miniaturize:sender ];
+}
+
+- (void)display
+{
+ /* This method fires just before the window deminaturizes from the Dock.
+ * We'll save the current visible surface, let the window manager redraw any
+ * UI elements, and restore the surface. This way, no expose event
+ * is required, and the deminiaturize works perfectly.
+ */
+
+ QZ_SetPortAlphaOpaque();
+
+ /* save current visible surface */
+ [ self cacheImageInRect:[ _cocoa_video_data.qdview frame ] ];
+
+ /* let the window manager redraw controls, border, etc */
+ [ super display ];
+
+ /* restore visible surface */
+ [ self restoreCachedImage ];
+
+ /* window is visible again */
+ _cocoa_video_data.active = true;
+}
+
+- (void)setFrame:(NSRect)frameRect display:(BOOL)flag
+{
+ NSRect newViewFrame;
+ CGrafPtr thePort;
+
+ [ super setFrame:frameRect display:flag ];
+
+ /* Don't do anything if the window is currently beign created */
+ if (_cocoa_video_data.issetting) return;
+
+ if (_cocoa_video_data.window == nil) return;
+
+ newViewFrame = [ _cocoa_video_data.qdview frame ];
+
+ /* Update the pixels and pitch */
+ thePort = [ _cocoa_video_data.qdview qdPort ];
+ LockPortBits(thePort);
+
+ _cocoa_video_data.realpixels = GetPixBaseAddr(GetPortPixMap(thePort));
+ _cocoa_video_data.pitch = GetPixRowBytes(GetPortPixMap(thePort));
+
+ /* _cocoa_video_data.realpixels now points to the window's pixels
+ * We want it to point to the *view's* pixels
+ */
+ {
+ int vOffset = [ _cocoa_video_data.window frame ].size.height - newViewFrame.size.height - newViewFrame.origin.y;
+ int hOffset = newViewFrame.origin.x;
+
+ _cocoa_video_data.realpixels = (uint8*)_cocoa_video_data.realpixels + (vOffset * _cocoa_video_data.pitch) + hOffset * (_cocoa_video_data.device_bpp / 8);
+ }
+
+ UnlockPortBits(thePort);
+
+ /* Allocate new buffer */
+ free(_cocoa_video_data.pixels);
+ _cocoa_video_data.pixels = (uint8*)malloc(newViewFrame.size.width * newViewFrame.size.height);
+ assert(_cocoa_video_data.pixels != NULL);
+
+
+ /* Tell the game that the resolution changed */
+ _cocoa_video_data.width = newViewFrame.size.width;
+ _cocoa_video_data.height = newViewFrame.size.height;
+
+ _screen.width = _cocoa_video_data.width;
+ _screen.height = _cocoa_video_data.height;
+ _screen.pitch = _cocoa_video_data.width;
+
+ GameSizeChanged();
+
+ /* Redraw screen */
+ _cocoa_video_data.num_dirty_rects = MAX_DIRTY_RECTS;
+}
+
+- (void)appDidHide:(NSNotification*)note
+{
+ _cocoa_video_data.active = false;
+}
+
+
+- (void)appWillUnhide:(NSNotification*)note
+{
+ QZ_SetPortAlphaOpaque ();
+
+ /* save current visible surface */
+ [ self cacheImageInRect:[ _cocoa_video_data.qdview frame ] ];
+}
+
+- (void)appDidUnhide:(NSNotification*)note
+{
+ /* restore cached image, since it may not be current, post expose event too */
+ [ self restoreCachedImage ];
+
+ _cocoa_video_data.active = true;
+}
+
+
+- (id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag
+{
+ /* Make our window subclass receive these application notifications */
+ [ [ NSNotificationCenter defaultCenter ] addObserver:self
+ selector:@selector(appDidHide:) name:NSApplicationDidHideNotification object:NSApp ];
+
+ [ [ NSNotificationCenter defaultCenter ] addObserver:self
+ selector:@selector(appDidUnhide:) name:NSApplicationDidUnhideNotification object:NSApp ];
+
+ [ [ NSNotificationCenter defaultCenter ] addObserver:self
+ selector:@selector(appWillUnhide:) name:NSApplicationWillUnhideNotification object:NSApp ];
+
+ return [ super initWithContentRect:contentRect styleMask:styleMask backing:backingType defer:flag ];
+}
+
+@end
+
+@implementation OTTD_QuartzWindowDelegate
+- (BOOL)windowShouldClose:(id)sender
+{
+ HandleExitGameRequest();
+
+ return NO;
+}
+
+- (void)windowDidBecomeKey:(NSNotification*)aNotification
+{
+ _cocoa_video_data.active = true;
+}
+
+- (void)windowDidResignKey:(NSNotification*)aNotification
+{
+ _cocoa_video_data.active = false;
+}
+
+- (void)windowDidBecomeMain:(NSNotification*)aNotification
+{
+ _cocoa_video_data.active = true;
+}
+
+- (void)windowDidResignMain:(NSNotification*)aNotification
+{
+ _cocoa_video_data.active = false;
+}
+
+@end
+
+
+static void QZ_UpdateWindowPalette(uint start, uint count)
+{
+ uint i;
+
+ switch (_cocoa_video_data.device_bpp) {
+ case 32:
+ for (i = start; i < start + count; i++) {
+ uint32 clr32 = 0xff000000;
+ clr32 |= (uint32)_cur_palette[i].r << 16;
+ clr32 |= (uint32)_cur_palette[i].g << 8;
+ clr32 |= (uint32)_cur_palette[i].b;
+ _cocoa_video_data.palette32[i] = clr32;
+ }
+ break;
+ case 16:
+ for (i = start; i < start + count; i++) {
+ uint16 clr16 = 0x0000;
+ clr16 |= (uint16)((_cur_palette[i].r >> 3) & 0x1f) << 10;
+ clr16 |= (uint16)((_cur_palette[i].g >> 3) & 0x1f) << 5;
+ clr16 |= (uint16)((_cur_palette[i].b >> 3) & 0x1f);
+ _cocoa_video_data.palette16[i] = clr16;
+ }
+ break;
+ }
+
+ _cocoa_video_data.num_dirty_rects = MAX_DIRTY_RECTS;
+}
+
+static inline void QZ_WindowBlitIndexedPixelsToView32(uint left, uint top, uint right, uint bottom)
+{
+ const uint32* pal = _cocoa_video_data.palette32;
+ const uint8* src = _cocoa_video_data.pixels;
+ uint32* dst = (uint32*)_cocoa_video_data.realpixels;
+ uint width = _cocoa_video_data.width;
+ uint pitch = _cocoa_video_data.pitch / 4;
+ uint x;
+ uint y;
+
+ for (y = top; y < bottom; y++) {
+ for (x = left; x < right; x++) {
+ dst[y * pitch + x] = pal[src[y * width + x]];
+ }
+ }
+}
+
+static inline void QZ_WindowBlitIndexedPixelsToView16(uint left, uint top, uint right, uint bottom)
+{
+ const uint16* pal = _cocoa_video_data.palette16;
+ const uint8* src = _cocoa_video_data.pixels;
+ uint16* dst = (uint16*)_cocoa_video_data.realpixels;
+ uint width = _cocoa_video_data.width;
+ uint pitch = _cocoa_video_data.pitch / 2;
+ uint x;
+ uint y;
+
+ for (y = top; y < bottom; y++) {
+ for (x = left; x < right; x++) {
+ dst[y * pitch + x] = pal[src[y * width + x]];
+ }
+ }
+}
+
+static inline void QZ_WindowBlitIndexedPixelsToView(int left, int top, int right, int bottom)
+{
+ switch (_cocoa_video_data.device_bpp) {
+ case 32: QZ_WindowBlitIndexedPixelsToView32(left, top, right, bottom); break;
+ case 16: QZ_WindowBlitIndexedPixelsToView16(left, top, right, bottom); break;
+ }
+}
+
+static bool _resize_icon[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1,
+ 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1,
+ 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0,
+ 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0,
+ 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1,
+ 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1,
+ 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0,
+ 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0
+};
+
+static void QZ_DrawResizeIcon(void)
+{
+ int xoff = _cocoa_video_data.width - 16;
+ int yoff = _cocoa_video_data.height - 16;
+ int x;
+ int y;
+
+ for (y = 0; y < 16; y++) {
+ uint16* trg16 = (uint16*)_cocoa_video_data.realpixels + (yoff + y) * _cocoa_video_data.pitch / 2 + xoff;
+ uint32* trg32 = (uint32*)_cocoa_video_data.realpixels + (yoff + y) * _cocoa_video_data.pitch / 4 + xoff;
+
+ for (x = 0; x < 16; x++, trg16++, trg32++) {
+ if (!_resize_icon[y * 16 + x]) continue;
+
+ switch (_cocoa_video_data.device_bpp) {
+ case 32: *trg32 = 0xff000000; break;
+ case 16: *trg16 = 0x0000; break;
+ }
+ }
+ }
+}
+
+static void QZ_DrawWindow(void)
+{
+ int i;
+ RgnHandle dirty, temp;
+
+ /* Check if we need to do anything */
+ if (_cocoa_video_data.num_dirty_rects == 0 ||
+ [ _cocoa_video_data.window isMiniaturized ]) {
+ return;
+ }
+
+ if (_cocoa_video_data.num_dirty_rects >= MAX_DIRTY_RECTS) {
+ _cocoa_video_data.num_dirty_rects = 1;
+ _cocoa_video_data.dirty_rects[0].left = 0;
+ _cocoa_video_data.dirty_rects[0].top = 0;
+ _cocoa_video_data.dirty_rects[0].right = _cocoa_video_data.width;
+ _cocoa_video_data.dirty_rects[0].bottom = _cocoa_video_data.height;
+ }
+
+ dirty = NewRgn();
+ temp = NewRgn();
+
+ SetEmptyRgn(dirty);
+
+ /* Build the region of dirty rectangles */
+ for (i = 0; i < _cocoa_video_data.num_dirty_rects; i++) {
+ QZ_WindowBlitIndexedPixelsToView(
+ _cocoa_video_data.dirty_rects[i].left,
+ _cocoa_video_data.dirty_rects[i].top,
+ _cocoa_video_data.dirty_rects[i].right,
+ _cocoa_video_data.dirty_rects[i].bottom
+ );
+
+ MacSetRectRgn(
+ temp,
+ _cocoa_video_data.dirty_rects[i].left,
+ _cocoa_video_data.dirty_rects[i].top,
+ _cocoa_video_data.dirty_rects[i].right,
+ _cocoa_video_data.dirty_rects[i].bottom
+ );
+ MacUnionRgn(dirty, temp, dirty);
+ }
+
+ QZ_DrawResizeIcon();
+
+ /* Flush the dirty region */
+ QDFlushPortBuffer([ _cocoa_video_data.qdview qdPort ], dirty);
+ DisposeRgn(dirty);
+ DisposeRgn(temp);
+
+ _cocoa_video_data.num_dirty_rects = 0;
+}
+
+
+extern const char _openttd_revision[];
+
+static const char* QZ_SetVideoWindowed(uint width, uint height)
+{
+ char caption[50];
+ NSString *nsscaption;
+ unsigned int style;
+ NSRect contentRect;
+ BOOL isCustom = NO;
+
+ if (width > _cocoa_video_data.device_width)
+ width = _cocoa_video_data.device_width;
+ if (height > _cocoa_video_data.device_height)
+ height = _cocoa_video_data.device_height;
+
+ _cocoa_video_data.width = width;
+ _cocoa_video_data.height = height;
+
+ contentRect = NSMakeRect(0, 0, width, height);
+
+ /* Check if we should completely destroy the previous mode
+ * - If it is fullscreen
+ */
+ if (_cocoa_video_data.isset && _cocoa_video_data.fullscreen)
+ QZ_UnsetVideoMode();
+
+ /* Check if we should recreate the window */
+ if (_cocoa_video_data.window == nil) {
+ /* Set the window style */
+ style = NSTitledWindowMask;
+ style |= (NSMiniaturizableWindowMask | NSClosableWindowMask);
+ style |= NSResizableWindowMask;
+
+ /* Manually create a window, avoids having a nib file resource */
+ _cocoa_video_data.window = [ [ OTTD_QuartzWindow alloc ]
+ initWithContentRect:contentRect
+ styleMask:style
+ backing:NSBackingStoreBuffered
+ defer:NO ];
+
+ if (_cocoa_video_data.window == nil)
+ return "Could not create the Cocoa window";
+
+ snprintf(caption, sizeof(caption), "OpenTTD %s", _openttd_revision);
+ nsscaption = [ [ NSString alloc ] initWithCString:caption ];
+ [ _cocoa_video_data.window setTitle:nsscaption ];
+ [ _cocoa_video_data.window setMiniwindowTitle:nsscaption ];
+ [ nsscaption release ];
+
+ [ _cocoa_video_data.window setAcceptsMouseMovedEvents:YES ];
+ [ _cocoa_video_data.window setViewsNeedDisplay:NO ];
+
+ [ _cocoa_video_data.window setDelegate: [ [ [ OTTD_QuartzWindowDelegate alloc ] init ] autorelease ] ];
+ } else {
+ /* We already have a window, just change its size */
+ if (!isCustom) {
+ [ _cocoa_video_data.window setContentSize:contentRect.size ];
+ [ _cocoa_video_data.qdview setFrameSize:contentRect.size ];
+ }
+ }
+
+ [ _cocoa_video_data.window center ];
+
+ /* Only recreate the view if it doesn't already exist */
+ if (_cocoa_video_data.qdview == nil) {
+ _cocoa_video_data.qdview = [ [ NSQuickDrawView alloc ] initWithFrame:contentRect ];
+ [ _cocoa_video_data.qdview setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable ];
+ [ [ _cocoa_video_data.window contentView ] addSubview:_cocoa_video_data.qdview ];
+ [ _cocoa_video_data.qdview release ];
+ [ _cocoa_video_data.window makeKeyAndOrderFront:nil ];
+ }
+
+ LockPortBits([ _cocoa_video_data.qdview qdPort ]);
+ _cocoa_video_data.realpixels = GetPixBaseAddr(GetPortPixMap([ _cocoa_video_data.qdview qdPort ]));
+ _cocoa_video_data.pitch = GetPixRowBytes(GetPortPixMap([ _cocoa_video_data.qdview qdPort ]));
+ UnlockPortBits([ _cocoa_video_data.qdview qdPort ]);
+
+ /* _cocoa_video_data.realpixels now points to the window's pixels
+ * We want it to point to the *view's* pixels
+ */
+ {
+ int vOffset = [ _cocoa_video_data.window frame ].size.height - [ _cocoa_video_data.qdview frame ].size.height - [ _cocoa_video_data.qdview frame ].origin.y;
+ int hOffset = [ _cocoa_video_data.qdview frame ].origin.x;
+
+ _cocoa_video_data.realpixels = (uint8*)_cocoa_video_data.realpixels + (vOffset * _cocoa_video_data.pitch) + hOffset * (_cocoa_video_data.device_bpp / 8);
+ }
+
+ free(_cocoa_video_data.pixels);
+ _cocoa_video_data.pixels = (uint8*)malloc(width * height);
+ if (_cocoa_video_data.pixels == NULL) return "Failed to allocate 8-bit buffer";
+
+ _cocoa_video_data.fullscreen = false;
+
+ return NULL;
+}
+
+
+/******************************************************************************
+ * Fullscreen mode *
+ ******************************************************************************/
+
+/* Gamma functions to try to hide the flash from a rez switch
+ * Fade the display from normal to black
+ * Save gamma tables for fade back to normal
+ */
+static uint32 QZ_FadeGammaOut(OTTD_QuartzGammaTable* table)
+{
+ CGGammaValue redTable[QZ_GAMMA_TABLE_SIZE];
+ CGGammaValue greenTable[QZ_GAMMA_TABLE_SIZE];
+ CGGammaValue blueTable[QZ_GAMMA_TABLE_SIZE];
+ float percent;
+ int j;
+ unsigned int actual;
+
+ if (CGGetDisplayTransferByTable(
+ _cocoa_video_data.display_id, QZ_GAMMA_TABLE_SIZE,
+ table->red, table->green, table->blue, &actual
+ ) != CGDisplayNoErr ||
+ actual != QZ_GAMMA_TABLE_SIZE) {
+ return 1;
+ }
+
+ memcpy(redTable, table->red, sizeof(redTable));
+ memcpy(greenTable, table->green, sizeof(greenTable));
+ memcpy(blueTable, table->blue, sizeof(greenTable));
+
+ for (percent = 1.0; percent >= 0.0; percent -= 0.01) {
+ for (j = 0; j < QZ_GAMMA_TABLE_SIZE; j++) {
+ redTable[j] = redTable[j] * percent;
+ greenTable[j] = greenTable[j] * percent;
+ blueTable[j] = blueTable[j] * percent;
+ }
+
+ if (CGSetDisplayTransferByTable(
+ _cocoa_video_data.display_id, QZ_GAMMA_TABLE_SIZE,
+ redTable, greenTable, blueTable
+ ) != CGDisplayNoErr) {
+ CGDisplayRestoreColorSyncSettings();
+ return 1;
+ }
+
+ CSleep(10);
+ }
+
+ return 0;
+}
+
+/* Fade the display from black to normal
+ * Restore previously saved gamma values
+ */
+static uint32 QZ_FadeGammaIn(const OTTD_QuartzGammaTable* table)
+{
+ CGGammaValue redTable[QZ_GAMMA_TABLE_SIZE];
+ CGGammaValue greenTable[QZ_GAMMA_TABLE_SIZE];
+ CGGammaValue blueTable[QZ_GAMMA_TABLE_SIZE];
+ float percent;
+ int j;
+
+ memset(redTable, 0, sizeof(redTable));
+ memset(greenTable, 0, sizeof(greenTable));
+ memset(blueTable, 0, sizeof(greenTable));
+
+ for (percent = 0.0; percent <= 1.0; percent += 0.01) {
+ for (j = 0; j < QZ_GAMMA_TABLE_SIZE; j++) {
+ redTable[j] = table->red[j] * percent;
+ greenTable[j] = table->green[j] * percent;
+ blueTable[j] = table->blue[j] * percent;
+ }
+
+ if (CGSetDisplayTransferByTable(
+ _cocoa_video_data.display_id, QZ_GAMMA_TABLE_SIZE,
+ redTable, greenTable, blueTable
+ ) != CGDisplayNoErr) {
+ CGDisplayRestoreColorSyncSettings();
+ return 1;
+ }
+
+ CSleep(10);
+ }
+
+ return 0;
+}
+
+static const char* QZ_SetVideoFullScreen(int width, int height)
+{
+ const char* errstr = "QZ_SetVideoFullScreen error";
+ int exact_match;
+ CFNumberRef number;
+ int bpp;
+ int gamma_error;
+ OTTD_QuartzGammaTable gamma_table;
+ NSRect screen_rect;
+ CGError error;
+ NSPoint pt;
+
+ /* Destroy any previous mode */
+ if (_cocoa_video_data.isset) QZ_UnsetVideoMode();
+
+ /* See if requested mode exists */
+ _cocoa_video_data.mode = CGDisplayBestModeForParameters(_cocoa_video_data.display_id, 8, width, height, &exact_match);
+
+ /* If the mode wasn't an exact match, check if it has the right bpp, and update width and height */
+ if (!exact_match) {
+ number = CFDictionaryGetValue (_cocoa_video_data.mode, kCGDisplayBitsPerPixel);
+ CFNumberGetValue(number, kCFNumberSInt32Type, &bpp);
+ if (bpp != 8) {
+ errstr = "Failed to find display resolution";
+ goto ERR_NO_MATCH;
+ }
+
+ number = CFDictionaryGetValue(_cocoa_video_data.mode, kCGDisplayWidth);
+ CFNumberGetValue(number, kCFNumberSInt32Type, &width);
+
+ number = CFDictionaryGetValue(_cocoa_video_data.mode, kCGDisplayHeight);
+ CFNumberGetValue(number, kCFNumberSInt32Type, &height);
+ }
+
+ /* Fade display to zero gamma */
+ gamma_error = QZ_FadeGammaOut(&gamma_table);
+
+ /* Put up the blanking window (a window above all other windows) */
+ error = CGDisplayCapture(_cocoa_video_data.display_id);
+
+ if (CGDisplayNoErr != error) {
+ errstr = "Failed capturing display";
+ goto ERR_NO_CAPTURE;
+ }
+
+ /* Do the physical switch */
+ if (CGDisplaySwitchToMode(_cocoa_video_data.display_id, _cocoa_video_data.mode) != CGDisplayNoErr) {
+ errstr = "Failed switching display resolution";
+ goto ERR_NO_SWITCH;
+ }
+
+ _cocoa_video_data.realpixels = (uint8*)CGDisplayBaseAddress(_cocoa_video_data.display_id);
+ _cocoa_video_data.pitch = CGDisplayBytesPerRow(_cocoa_video_data.display_id);
+
+ _cocoa_video_data.width = CGDisplayPixelsWide(_cocoa_video_data.display_id);
+ _cocoa_video_data.height = CGDisplayPixelsHigh(_cocoa_video_data.display_id);
+ _cocoa_video_data.fullscreen = true;
+
+ /* Setup double-buffer emulation */
+ _cocoa_video_data.pixels = (uint8*)malloc(width * height);
+ if (_cocoa_video_data.pixels == NULL) {
+ errstr = "Failed to allocate memory for double buffering";
+ goto ERR_DOUBLEBUF;
+ }
+
+ if (!CGDisplayCanSetPalette(_cocoa_video_data.display_id)) {
+ errstr = "Not an indexed display mode.";
+ goto ERR_NOT_INDEXED;
+ }
+
+ /* If we don't hide menu bar, it will get events and interrupt the program */
+ HideMenuBar();
+
+ /* Fade the display to original gamma */
+ if (!gamma_error) QZ_FadeGammaIn(&gamma_table);
+
+ /* There is a bug in Cocoa where NSScreen doesn't synchronize
+ * with CGDirectDisplay, so the main screen's frame is wrong.
+ * As a result, coordinate translation produces incorrect results.
+ * We can hack around this bug by setting the screen rect ourselves.
+ * This hack should be removed if/when the bug is fixed.
+ */
+ screen_rect = NSMakeRect(0, 0, width, height);
+ [ [ NSScreen mainScreen ] setFrame:screen_rect ];
+
+ /* we're fullscreen, so flag all input states... */
+ _cocoa_video_data.active = true;
+
+
+ pt = [ NSEvent mouseLocation ];
+ pt.y = CGDisplayPixelsHigh(_cocoa_video_data.display_id) - pt.y;
+ if (QZ_MouseIsInsideView(&pt)) QZ_HideMouse();
+
+ return NULL;
+
+/* Since the blanking window covers *all* windows (even force quit) correct recovery is crucial */
+ERR_NOT_INDEXED:
+ free(_cocoa_video_data.pixels);
+ _cocoa_video_data.pixels = NULL;
+ERR_DOUBLEBUF:
+ CGDisplaySwitchToMode(_cocoa_video_data.display_id, _cocoa_video_data.save_mode);
+ERR_NO_SWITCH:
+ CGReleaseAllDisplays();
+ERR_NO_CAPTURE:
+ if (!gamma_error) QZ_FadeGammaIn(&gamma_table);
+ERR_NO_MATCH:
+ return errstr;
+}
+
+
+static void QZ_UpdateFullscreenPalette(uint first_color, uint num_colors)
+{
+ CGTableCount index;
+ CGDeviceColor color;
+
+ for (index = first_color; index < first_color+num_colors; index++) {
+ /* Clamp colors between 0.0 and 1.0 */
+ color.red = _cur_palette[index].r / 255.0;
+ color.blue = _cur_palette[index].b / 255.0;
+ color.green = _cur_palette[index].g / 255.0;
+
+ CGPaletteSetColorAtIndex(_cocoa_video_data.palette, color, index);
+ }
+
+ CGDisplaySetPalette(_cocoa_video_data.display_id, _cocoa_video_data.palette);
+}
+
+/* Wait for the VBL to occur (estimated since we don't have a hardware interrupt) */
+static void QZ_WaitForVerticalBlank(void)
+{
+ /* The VBL delay is based on Ian Ollmann's RezLib <iano@cco.caltech.edu> */
+ double refreshRate;
+ double linesPerSecond;
+ double target;
+ double position;
+ double adjustment;
+ CFNumberRef refreshRateCFNumber;
+
+ refreshRateCFNumber = CFDictionaryGetValue(_cocoa_video_data.mode, kCGDisplayRefreshRate);
+ if (refreshRateCFNumber == NULL) return;
+
+ if (CFNumberGetValue(refreshRateCFNumber, kCFNumberDoubleType, &refreshRate) == 0)
+ return;
+
+ if (refreshRate == 0) return;
+
+ linesPerSecond = refreshRate * _cocoa_video_data.height;
+ target = _cocoa_video_data.height;
+
+ /* Figure out the first delay so we start off about right */
+ position = CGDisplayBeamPosition(_cocoa_video_data.display_id);
+ if (position > target) position = 0;
+
+ adjustment = (target - position) / linesPerSecond;
+
+ CSleep((uint32)(adjustment * 1000));
+}
+
+
+static void QZ_DrawScreen(void)
+{
+ const uint8* src = _cocoa_video_data.pixels;
+ uint8* dst = (uint8*)_cocoa_video_data.realpixels;
+ uint pitch = _cocoa_video_data.pitch;
+ uint width = _cocoa_video_data.width;
+ uint num_dirty = _cocoa_video_data.num_dirty_rects;
+ uint i;
+
+ /* Check if we need to do anything */
+ if (num_dirty == 0) return;
+
+ if (num_dirty >= MAX_DIRTY_RECTS) {
+ num_dirty = 1;
+ _cocoa_video_data.dirty_rects[0].left = 0;
+ _cocoa_video_data.dirty_rects[0].top = 0;
+ _cocoa_video_data.dirty_rects[0].right = _cocoa_video_data.width;
+ _cocoa_video_data.dirty_rects[0].bottom = _cocoa_video_data.height;
+ }
+
+ QZ_WaitForVerticalBlank();
+ /* Build the region of dirty rectangles */
+ for (i = 0; i < num_dirty; i++) {
+ uint y = _cocoa_video_data.dirty_rects[i].top;
+ uint left = _cocoa_video_data.dirty_rects[i].left;
+ uint length = _cocoa_video_data.dirty_rects[i].right - left;
+ uint bottom = _cocoa_video_data.dirty_rects[i].bottom;
+
+ for (; y < bottom; y++) {
+ memcpy(dst + y * pitch + left, src + y * width + left, length);
+ }
+ }
+
+ _cocoa_video_data.num_dirty_rects = 0;
+}
+
+
+static int QZ_ListFullscreenModes(OTTDPoint* mode_list, int max_modes)
+{
+ CFIndex num_modes;
+ CFIndex i;
+ int list_size = 0;
+
+ num_modes = CFArrayGetCount(_cocoa_video_data.mode_list);
+
+ /* Build list of modes with the requested bpp */
+ for (i = 0; i < num_modes && list_size < max_modes; i++) {
+ CFDictionaryRef onemode;
+ CFNumberRef number;
+ int bpp;
+ int intvalue;
+ bool hasMode;
+ uint16 width, height;
+
+ onemode = CFArrayGetValueAtIndex(_cocoa_video_data.mode_list, i);
+ number = CFDictionaryGetValue(onemode, kCGDisplayBitsPerPixel);
+ CFNumberGetValue (number, kCFNumberSInt32Type, &bpp);
+
+ if (bpp != 8) continue;
+
+ number = CFDictionaryGetValue(onemode, kCGDisplayWidth);
+ CFNumberGetValue(number, kCFNumberSInt32Type, &intvalue);
+ width = (uint16)intvalue;
+
+ number = CFDictionaryGetValue(onemode, kCGDisplayHeight);
+ CFNumberGetValue(number, kCFNumberSInt32Type, &intvalue);
+ height = (uint16)intvalue;
+
+ /* Check if mode is already in the list */
+ {
+ int i;
+ hasMode = false;
+ for (i = 0; i < list_size; i++) {
+ if (mode_list[i].x == width && mode_list[i].y == height) {
+ hasMode = true;
+ break;
+ }
+ }
+ }
+
+ if (hasMode) continue;
+
+ /* Add mode to the list */
+ mode_list[list_size].x = width;
+ mode_list[list_size].y = height;
+ list_size++;
+ }
+
+ /* Sort list smallest to largest */
+ {
+ int i, j;
+ for (i = 0; i < list_size; i++) {
+ for (j = 0; j < list_size-1; j++) {
+ if (mode_list[j].x > mode_list[j + 1].x || (
+ mode_list[j].x == mode_list[j + 1].x &&
+ mode_list[j].y > mode_list[j + 1].y
+ )) {
+ uint tmpw = mode_list[j].x;
+ uint tmph = mode_list[j].y;
+
+ mode_list[j].x = mode_list[j + 1].x;
+ mode_list[j].y = mode_list[j + 1].y;
+
+ mode_list[j + 1].x = tmpw;
+ mode_list[j + 1].y = tmph;
+ }
+ }
+ }
+ }
+
+ return list_size;
+}
+
+
+/******************************************************************************
+ * Windowed and fullscreen common code *
+ ******************************************************************************/
+
+static void QZ_UpdatePalette(uint start, uint count)
+{
+ if (_cocoa_video_data.fullscreen) {
+ QZ_UpdateFullscreenPalette(start, count);
+ } else {
+ QZ_UpdateWindowPalette(start, count);
+ }
+}
+
+static void QZ_InitPalette(void)
+{
+ QZ_UpdatePalette(0, 256);
+}
+
+static void QZ_Draw(void)
+{
+ if (_cocoa_video_data.fullscreen) {
+ QZ_DrawScreen();
+ } else {
+ QZ_DrawWindow();
+ }
+}
+
+
+static const OTTDPoint _default_resolutions[] = {
+ { 640, 480},
+ { 800, 600},
+ {1024, 768},
+ {1152, 864},
+ {1280, 800},
+ {1280, 960},
+ {1280, 1024},
+ {1400, 1050},
+ {1600, 1200},
+ {1680, 1050},
+ {1920, 1200}
+};
+
+static void QZ_UpdateVideoModes(void)
+{
+ uint i, j, count;
+ OTTDPoint modes[32];
+ const OTTDPoint *current_modes;
+
+ if (_cocoa_video_data.fullscreen) {
+ count = QZ_ListFullscreenModes(modes, 32);
+ current_modes = modes;
+ } else {
+ count = lengthof(_default_resolutions);
+ current_modes = _default_resolutions;
+ }
+
+ for (i = 0, j = 0; j < lengthof(_resolutions) && i < count; i++) {
+ if (_cocoa_video_data.fullscreen || (
+ (uint)current_modes[i].x < _cocoa_video_data.device_width &&
+ (uint)current_modes[i].y < _cocoa_video_data.device_height)
+ ) {
+ _resolutions[j][0] = current_modes[i].x;
+ _resolutions[j][1] = current_modes[i].y;
+ j++;
+ }
+ }
+
+ _num_resolutions = j;
+}
+
+static void QZ_UnsetVideoMode(void)
+{
+ if (_cocoa_video_data.fullscreen) {
+ /* Release fullscreen resources */
+ OTTD_QuartzGammaTable gamma_table;
+ int gamma_error;
+ NSRect screen_rect;
+
+ gamma_error = QZ_FadeGammaOut(&gamma_table);
+
+ /* Restore original screen resolution/bpp */
+ CGDisplaySwitchToMode(_cocoa_video_data.display_id, _cocoa_video_data.save_mode);
+ CGReleaseAllDisplays();
+ ShowMenuBar();
+ /* Reset the main screen's rectangle
+ * See comment in QZ_SetVideoFullscreen for why we do this
+ */
+ screen_rect = NSMakeRect(0,0,_cocoa_video_data.device_width,_cocoa_video_data.device_height);
+ [ [ NSScreen mainScreen ] setFrame:screen_rect ];
+
+ if (!gamma_error) QZ_FadeGammaIn(&gamma_table);
+ } else {
+ /* Release window mode resources */
+ [ _cocoa_video_data.window close ];
+ _cocoa_video_data.window = nil;
+ _cocoa_video_data.qdview = nil;
+ }
+
+ free(_cocoa_video_data.pixels);
+ _cocoa_video_data.pixels = NULL;
+
+ /* Signal successful teardown */
+ _cocoa_video_data.isset = false;
+
+ QZ_ShowMouse();
+}
+
+
+static const char* QZ_SetVideoMode(uint width, uint height, bool fullscreen)
+{
+ const char *ret;
+
+ _cocoa_video_data.issetting = true;
+ if (fullscreen) {
+ /* Setup full screen video */
+ ret = QZ_SetVideoFullScreen(width, height);
+ } else {
+ /* Setup windowed video */
+ ret = QZ_SetVideoWindowed(width, height);
+ }
+ _cocoa_video_data.issetting = false;
+ if (ret != NULL) return ret;
+
+ /* Signal successful completion (used internally) */
+ _cocoa_video_data.isset = true;
+
+ /* Tell the game that the resolution has changed */
+ _screen.width = _cocoa_video_data.width;
+ _screen.height = _cocoa_video_data.height;
+ _screen.pitch = _cocoa_video_data.width;
+
+ QZ_UpdateVideoModes();
+ GameSizeChanged();
+
+ QZ_InitPalette();
+
+ return NULL;
+}
+
+static const char* QZ_SetVideoModeAndRestoreOnFailure(uint width, uint height, bool fullscreen)
+{
+ bool wasset = _cocoa_video_data.isset;
+ uint32 oldwidth = _cocoa_video_data.width;
+ uint32 oldheight = _cocoa_video_data.height;
+ bool oldfullscreen = _cocoa_video_data.fullscreen;
+ const char *ret;
+
+ ret = QZ_SetVideoMode(width, height, fullscreen);
+ if (ret != NULL && wasset) QZ_SetVideoMode(oldwidth, oldheight, oldfullscreen);
+
+ return ret;
+}
+
+static void QZ_VideoInit(void)
+{
+ memset(&_cocoa_video_data, 0, sizeof(_cocoa_video_data));
+
+ /* Initialize the video settings; this data persists between mode switches */
+ _cocoa_video_data.display_id = kCGDirectMainDisplay;
+ _cocoa_video_data.save_mode = CGDisplayCurrentMode(_cocoa_video_data.display_id);
+ _cocoa_video_data.mode_list = CGDisplayAvailableModes(_cocoa_video_data.display_id);
+ _cocoa_video_data.palette = CGPaletteCreateDefaultColorPalette();
+
+ /* Gather some information that is useful to know about the display */
+ /* Maybe this should be moved to QZ_SetVideoMode, in case this is changed after startup */
+ CFNumberGetValue(
+ CFDictionaryGetValue(_cocoa_video_data.save_mode, kCGDisplayBitsPerPixel),
+ kCFNumberSInt32Type, &_cocoa_video_data.device_bpp
+ );
+
+ CFNumberGetValue(
+ CFDictionaryGetValue(_cocoa_video_data.save_mode, kCGDisplayWidth),
+ kCFNumberSInt32Type, &_cocoa_video_data.device_width
+ );
+
+ CFNumberGetValue(
+ CFDictionaryGetValue(_cocoa_video_data.save_mode, kCGDisplayHeight),
+ kCFNumberSInt32Type, &_cocoa_video_data.device_height
+ );
+
+ _cocoa_video_data.cursor_visible = true;
+
+ /* register for sleep notifications so wake from sleep generates SDL_VIDEOEXPOSE */
+// QZ_RegisterForSleepNotifications();
+}
+
+
+/* Convert local coordinate to window server (CoreGraphics) coordinate */
+static CGPoint QZ_PrivateLocalToCG(NSPoint* p)
+{
+ CGPoint cgp;
+
+ if (!_cocoa_video_data.fullscreen) {
+ *p = [ _cocoa_video_data.qdview convertPoint:*p toView: nil ];
+ *p = [ _cocoa_video_data.window convertBaseToScreen:*p ];
+ p->y = _cocoa_video_data.device_height - p->y;
+ }
+
+ cgp.x = p->x;
+ cgp.y = p->y;
+
+ return cgp;
+}
+
+static void QZ_WarpCursor(int x, int y)
+{
+ NSPoint p;
+ CGPoint cgp;
+
+ /* Only allow warping when in foreground */
+ if (![ NSApp isActive ]) return;
+
+ p = NSMakePoint(x, y);
+ cgp = QZ_PrivateLocalToCG(&p);
+
+ /* this is the magic call that fixes cursor "freezing" after warp */
+ CGSetLocalEventsSuppressionInterval(0.0);
+ /* Do the actual warp */
+ CGWarpMouseCursorPosition(cgp);
+
+ /* Generate the mouse moved event */
+}
+
+static void QZ_ShowMouse(void)
+{
+ if (!_cocoa_video_data.cursor_visible) {
+ [ NSCursor unhide ];
+ _cocoa_video_data.cursor_visible = true;
+
+ // Hide the openttd cursor when leaving the window
+ if (_cocoa_video_data.isset)
+ UndrawMouseCursor();
+ _cursor.in_window = false;
+ }
+}
+
+static void QZ_HideMouse(void)
+{
+ if (_cocoa_video_data.cursor_visible) {
+#ifndef _DEBUG
+ [ NSCursor hide ];
+#endif
+ _cocoa_video_data.cursor_visible = false;
+
+ // Show the openttd cursor again
+ _cursor.in_window = true;
+ }
+}
+
+
+/******************************************************************************
+ * OS X application creation *
+ ******************************************************************************/
+
+/* The main class of the application, the application's delegate */
+@implementation OTTDMain
+/* Called when the internal event loop has just started running */
+- (void) applicationDidFinishLaunching: (NSNotification*) note
+{
+ /* Hand off to main application code */
+ QZ_GameLoop();
+
+ /* We're done, thank you for playing */
+ [ NSApp stop:_ottd_main ];
+}
+
+/* Display the in game quit confirmation dialog */
+- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*) sender
+{
+
+ HandleExitGameRequest();
+
+ return NSTerminateCancel; // NSTerminateLater ?
+}
+@end
+
+static void setApplicationMenu(void)
+{
+ /* warning: this code is very odd */
+ NSMenu *appleMenu;
+ NSMenuItem *menuItem;
+ NSString *title;
+ NSString *appName;
+
+ appName = @"OTTD";
+ appleMenu = [[NSMenu alloc] initWithTitle:appName];
+
+ /* Add menu items */
+ title = [@"About " stringByAppendingString:appName];
+ [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
+
+ [appleMenu addItem:[NSMenuItem separatorItem]];
+
+ title = [@"Hide " stringByAppendingString:appName];
+ [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
+
+ menuItem = (NSMenuItem*)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
+ [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
+
+ [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
+
+ [appleMenu addItem:[NSMenuItem separatorItem]];
+
+ title = [@"Quit " stringByAppendingString:appName];
+ [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
+
+
+ /* Put menu into the menubar */
+ menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
+ [menuItem setSubmenu:appleMenu];
+ [[NSApp mainMenu] addItem:menuItem];
+
+ /* Tell the application object that this is now the application menu */
+ [NSApp setAppleMenu:appleMenu];
+
+ /* Finally give up our references to the objects */
+ [appleMenu release];
+ [menuItem release];
+}
+
+/* Create a window menu */
+static void setupWindowMenu(void)
+{
+ NSMenu* windowMenu;
+ NSMenuItem* windowMenuItem;
+ NSMenuItem* menuItem;
+
+ windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
+
+ /* "Minimize" item */
+ menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
+ [windowMenu addItem:menuItem];
+ [menuItem release];
+
+ /* Put menu into the menubar */
+ windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
+ [windowMenuItem setSubmenu:windowMenu];
+ [[NSApp mainMenu] addItem:windowMenuItem];
+
+ /* Tell the application object that this is now the window menu */
+ [NSApp setWindowsMenu:windowMenu];
+
+ /* Finally give up our references to the objects */
+ [windowMenu release];
+ [windowMenuItem release];
+}
+
+static void setupApplication(void)
+{
+ CPSProcessSerNum PSN;
+
+ /* Ensure the application object is initialised */
+ [NSApplication sharedApplication];
+
+ /* Tell the dock about us */
+ if (!CPSGetCurrentProcess(&PSN) &&
+ !CPSEnableForegroundOperation(&PSN, 0x03, 0x3C, 0x2C, 0x1103) &&
+ !CPSSetFrontProcess(&PSN)) {
+ [NSApplication sharedApplication];
+ }
+
+ /* Set up the menubar */
+ [NSApp setMainMenu:[[NSMenu alloc] init]];
+ setApplicationMenu();
+ setupWindowMenu();
+
+ /* Create OTTDMain and make it the app delegate */
+ _ottd_main = [[OTTDMain alloc] init];
+ [NSApp setDelegate:_ottd_main];
+}
+
+
+/******************************************************************************
+ * Video driver interface *
+ ******************************************************************************/
+
+static void CocoaVideoStop(void)
+{
+ if (!_cocoa_video_started) return;
+
+ if (_cocoa_video_data.isset) QZ_UnsetVideoMode();
+
+ [_ottd_main release];
+
+ _cocoa_video_started = false;
+}
+
+static const char *CocoaVideoStart(const char * const *parm)
+{
+ const char *ret;
+
+ if (_cocoa_video_started) return "Already started";
+ _cocoa_video_started = true;
+
+ memset(&_cocoa_video_data, 0, sizeof(_cocoa_video_data));
+
+ setupApplication();
+
+ /* Don't create a window or enter fullscreen if we're just going to show a dialog. */
+ if (_cocoa_video_dialog) return NULL;
+
+ QZ_VideoInit();
+
+ ret = QZ_SetVideoMode(_cur_resolution[0], _cur_resolution[1], _fullscreen);
+ if (ret != NULL) CocoaVideoStop();
+
+ return ret;
+}
+
+static void CocoaVideoMakeDirty(int left, int top, int width, int height)
+{
+ if (_cocoa_video_data.num_dirty_rects < MAX_DIRTY_RECTS) {
+ _cocoa_video_data.dirty_rects[_cocoa_video_data.num_dirty_rects].left = left;
+ _cocoa_video_data.dirty_rects[_cocoa_video_data.num_dirty_rects].top = top;
+ _cocoa_video_data.dirty_rects[_cocoa_video_data.num_dirty_rects].right = left + width;
+ _cocoa_video_data.dirty_rects[_cocoa_video_data.num_dirty_rects].bottom = top + height;
+ }
+ _cocoa_video_data.num_dirty_rects++;
+}
+
+static void CocoaVideoMainLoop(void)
+{
+ /* Start the main event loop */
+ [NSApp run];
+}
+
+static bool CocoaVideoChangeRes(int w, int h)
+{
+ const char *ret = QZ_SetVideoModeAndRestoreOnFailure((uint)w, (uint)h, _cocoa_video_data.fullscreen);
+ if (ret != NULL) {
+ DEBUG(driver, 0, "cocoa_v: CocoaVideoChangeRes failed with message: %s", ret);
+ }
+
+ return ret == NULL;
+}
+
+static void CocoaVideoFullScreen(bool full_screen)
+{
+ const char *ret = QZ_SetVideoModeAndRestoreOnFailure(_cocoa_video_data.width, _cocoa_video_data.height, full_screen);
+ if (ret != NULL) {
+ DEBUG(driver, 0, "cocoa_v: CocoaVideoFullScreen failed with message: %s", ret);
+ }
+
+ _fullscreen = _cocoa_video_data.fullscreen;
+}
+
+const HalVideoDriver _cocoa_video_driver = {
+ CocoaVideoStart,
+ CocoaVideoStop,
+ CocoaVideoMakeDirty,
+ CocoaVideoMainLoop,
+ CocoaVideoChangeRes,
+ CocoaVideoFullScreen,
+};
+
+
+/* This is needed since sometimes assert is called before the videodriver is initialized */
+void CocoaDialog(const char* title, const char* message, const char* buttonLabel)
+{
+ bool wasstarted;
+
+ _cocoa_video_dialog = true;
+
+ wasstarted = _cocoa_video_started;
+ if (!_cocoa_video_started && CocoaVideoStart(NULL) != NULL) {
+ fprintf(stderr, "%s: %s\n", title, message);
+ return;
+ }
+
+ NSRunAlertPanel([NSString stringWithCString: title], [NSString stringWithCString: message], [NSString stringWithCString: buttonLabel], nil, nil);
+
+ if (!wasstarted) CocoaVideoStop();
+
+ _cocoa_video_dialog = false;
+}
+
+
+/* This is needed since OS X applications are started with the working dir set to / when double-clicked */
+void cocoaSetWorkingDirectory(void)
+{
+ char parentdir[MAXPATHLEN];
+ int chdir_ret;
+ CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
+ CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url);
+ if (CFURLGetFileSystemRepresentation(url2, true, (unsigned char*)parentdir, MAXPATHLEN)) {
+ chdir_ret = chdir(parentdir); /* chdir to the binary app's parent */
+ assert(chdir_ret == 0);
+ }
+ CFRelease(url);
+ CFRelease(url2);
+}
+
+/* These are called from main() to prevent a _NSAutoreleaseNoPool error when
+ * exiting before the cocoa video driver has been loaded
+ */
+void cocoaSetupAutoreleasePool(void)
+{
+ _ottd_autorelease_pool = [[NSAutoreleasePool alloc] init];
+}
+
+void cocoaReleaseAutoreleasePool(void)
+{
+ [_ottd_autorelease_pool release];
+}
+
+#endif /* WITH_COCOA */
diff --git a/src/video/dedicated_v.c b/src/video/dedicated_v.c
new file mode 100644
index 000000000..caa1c8963
--- /dev/null
+++ b/src/video/dedicated_v.c
@@ -0,0 +1,298 @@
+/* $Id$ */
+
+#include "../stdafx.h"
+
+#ifdef ENABLE_NETWORK
+
+#include "../openttd.h"
+#include "../debug.h"
+#include "../functions.h"
+#include "../gfx.h"
+#include "../network/network.h"
+#include "../window.h"
+#include "../console.h"
+#include "../variables.h"
+#include "../genworld.h"
+#include "dedicated_v.h"
+
+#ifdef BEOS_NET_SERVER
+#include <net/socket.h>
+#endif
+
+#ifdef __OS2__
+# include <sys/time.h> /* gettimeofday */
+# include <sys/types.h>
+# include <unistd.h>
+# include <conio.h>
+
+# define INCL_DOS
+# include <os2.h>
+
+# define STDIN 0 /* file descriptor for standard input */
+
+/**
+ * Switches OpenTTD to a console app at run-time, instead of a PM app
+ * Necessary to see stdout, etc. */
+static void OS2_SwitchToConsoleMode(void)
+{
+ PPIB pib;
+ PTIB tib;
+
+ DosGetInfoBlocks(&tib, &pib);
+
+ // Change flag from PM to VIO
+ pib->pib_ultype = 3;
+}
+#endif
+
+#ifdef UNIX
+# include <sys/time.h> /* gettimeofday */
+# include <sys/types.h>
+# include <unistd.h>
+# include <signal.h>
+# define STDIN 0 /* file descriptor for standard input */
+
+/* Signal handlers */
+static void DedicatedSignalHandler(int sig)
+{
+ _exit_game = true;
+ signal(sig, DedicatedSignalHandler);
+}
+#endif
+
+#ifdef WIN32
+#include <windows.h> /* GetTickCount */
+#include <conio.h>
+#include <time.h>
+#include <tchar.h>
+static HANDLE _hInputReady, _hWaitForInputHandling;
+static HANDLE _hThread; // Thread to close
+static char _win_console_thread_buffer[200];
+
+/* Windows Console thread. Just loop and signal when input has been received */
+static void WINAPI CheckForConsoleInput(void)
+{
+ while (true) {
+ fgets(_win_console_thread_buffer, lengthof(_win_console_thread_buffer), stdin);
+ /* Signal input waiting that input is read and wait for it being handled
+ * SignalObjectAndWait() should be used here, but it's unsupported in Win98< */
+ SetEvent(_hInputReady);
+ WaitForSingleObject(_hWaitForInputHandling, INFINITE);
+ }
+}
+
+static void CreateWindowsConsoleThread(void)
+{
+ DWORD dwThreadId;
+ /* Create event to signal when console input is ready */
+ _hInputReady = CreateEvent(NULL, false, false, NULL);
+ _hWaitForInputHandling = CreateEvent(NULL, false, false, NULL);
+ if (_hInputReady == NULL || _hWaitForInputHandling == NULL) error("Cannot create console event!");
+
+ _hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CheckForConsoleInput, NULL, 0, &dwThreadId);
+ if (_hThread == NULL) error("Cannot create console thread!");
+
+ DEBUG(driver, 2, "Windows console thread started");
+}
+
+static void CloseWindowsConsoleThread(void)
+{
+ CloseHandle(_hThread);
+ CloseHandle(_hInputReady);
+ CloseHandle(_hWaitForInputHandling);
+ DEBUG(driver, 2, "Windows console thread shut down");
+}
+
+#endif
+
+
+static void *_dedicated_video_mem;
+
+extern bool SafeSaveOrLoad(const char *filename, int mode, int newgm);
+extern void SwitchMode(int new_mode);
+
+
+static const char *DedicatedVideoStart(const char * const *parm)
+{
+ _screen.width = _screen.pitch = _cur_resolution[0];
+ _screen.height = _cur_resolution[1];
+ _dedicated_video_mem = malloc(_cur_resolution[0]*_cur_resolution[1]);
+
+ SetDebugString("net=6");
+
+#ifdef WIN32
+ // For win32 we need to allocate a console (debug mode does the same)
+ CreateConsole();
+ CreateWindowsConsoleThread();
+ SetConsoleTitle(_T("OpenTTD Dedicated Server"));
+#endif
+
+#ifdef __OS2__
+ // For OS/2 we also need to switch to console mode instead of PM mode
+ OS2_SwitchToConsoleMode();
+#endif
+
+ DEBUG(driver, 1, "Loading dedicated server");
+ return NULL;
+}
+
+static void DedicatedVideoStop(void)
+{
+#ifdef WIN32
+ CloseWindowsConsoleThread();
+#endif
+ free(_dedicated_video_mem);
+}
+
+static void DedicatedVideoMakeDirty(int left, int top, int width, int height) {}
+static bool DedicatedVideoChangeRes(int w, int h) { return false; }
+static void DedicatedVideoFullScreen(bool fs) {}
+
+#if defined(UNIX) || defined(__OS2__)
+static bool InputWaiting(void)
+{
+ struct timeval tv;
+ fd_set readfds;
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 1;
+
+ FD_ZERO(&readfds);
+ FD_SET(STDIN, &readfds);
+
+ /* don't care about writefds and exceptfds: */
+ return select(STDIN + 1, &readfds, NULL, NULL, &tv) > 0;
+}
+
+static uint32 GetTime(void)
+{
+ struct timeval tim;
+
+ gettimeofday(&tim, NULL);
+ return tim.tv_usec / 1000 + tim.tv_sec * 1000;
+}
+
+#else
+
+static bool InputWaiting(void)
+{
+ return WaitForSingleObject(_hInputReady, 1) == WAIT_OBJECT_0;
+}
+
+static uint32 GetTime(void)
+{
+ return GetTickCount();
+}
+
+#endif
+
+static void DedicatedHandleKeyInput(void)
+{
+ static char input_line[200] = "";
+
+ if (!InputWaiting()) return;
+
+ if (_exit_game) return;
+
+#if defined(UNIX) || defined(__OS2__)
+ if (fgets(input_line, lengthof(input_line), stdin) == NULL) return;
+#else
+ /* Handle console input, and singal console thread, it can accept input again */
+ strncpy(input_line, _win_console_thread_buffer, lengthof(input_line));
+ SetEvent(_hWaitForInputHandling);
+#endif
+
+ /* XXX - strtok() does not 'forget' \n\r if it is the first character! */
+ strtok(input_line, "\r\n"); // Forget about the final \n (or \r)
+ { /* Remove any special control characters */
+ uint i;
+ for (i = 0; i < lengthof(input_line); i++) {
+ if (input_line[i] == '\n' || input_line[i] == '\r') // cut missed beginning '\0'
+ input_line[i] = '\0';
+
+ if (input_line[i] == '\0')
+ break;
+
+ if (!IS_INT_INSIDE(input_line[i], ' ', 256))
+ input_line[i] = ' ';
+ }
+ }
+
+ IConsoleCmdExec(input_line); // execute command
+}
+
+static void DedicatedVideoMainLoop(void)
+{
+ uint32 next_tick;
+ uint32 cur_ticks;
+
+ next_tick = GetTime() + 30;
+
+ /* Signal handlers */
+#ifdef UNIX
+ signal(SIGTERM, DedicatedSignalHandler);
+ signal(SIGINT, DedicatedSignalHandler);
+ signal(SIGQUIT, DedicatedSignalHandler);
+#endif
+
+ // Load the dedicated server stuff
+ _is_network_server = true;
+ _network_dedicated = true;
+ _network_playas = PLAYER_SPECTATOR;
+ _local_player = PLAYER_SPECTATOR;
+
+ /* If SwitchMode is SM_LOAD, it means that the user used the '-g' options */
+ if (_switch_mode != SM_LOAD) {
+ StartNewGameWithoutGUI(GENERATE_NEW_SEED);
+ SwitchMode(_switch_mode);
+ _switch_mode = SM_NONE;
+ } else {
+ _switch_mode = SM_NONE;
+ /* First we need to test if the savegame can be loaded, else we will end up playing the
+ * intro game... */
+ if (!SafeSaveOrLoad(_file_to_saveload.name, _file_to_saveload.mode, GM_NORMAL)) {
+ /* Loading failed, pop out.. */
+ DEBUG(net, 0, "Loading requested map failed, aborting");
+ _networking = false;
+ } else {
+ /* We can load this game, so go ahead */
+ SwitchMode(SM_LOAD);
+ }
+ }
+
+ // Done loading, start game!
+
+ if (!_networking) {
+ DEBUG(net, 0, "Dedicated server could not be started, aborting");
+ return;
+ }
+
+ while (!_exit_game) {
+ InteractiveRandom(); // randomness
+
+ if (!_dedicated_forks)
+ DedicatedHandleKeyInput();
+
+ cur_ticks = GetTime();
+
+ if (cur_ticks >= next_tick) {
+ next_tick += 30;
+
+ GameLoop();
+ _screen.dst_ptr = _dedicated_video_mem;
+ UpdateWindows();
+ }
+ CSleep(1);
+ }
+}
+
+const HalVideoDriver _dedicated_video_driver = {
+ DedicatedVideoStart,
+ DedicatedVideoStop,
+ DedicatedVideoMakeDirty,
+ DedicatedVideoMainLoop,
+ DedicatedVideoChangeRes,
+ DedicatedVideoFullScreen,
+};
+
+#endif /* ENABLE_NETWORK */
diff --git a/src/video/dedicated_v.h b/src/video/dedicated_v.h
new file mode 100644
index 000000000..9ba1223d3
--- /dev/null
+++ b/src/video/dedicated_v.h
@@ -0,0 +1,10 @@
+/* $Id$ */
+
+#ifndef VIDEO_DEDICATED_H
+#define VIDEO_DEDICATED_H
+
+#include "../hal.h"
+
+extern const HalVideoDriver _dedicated_video_driver;
+
+#endif
diff --git a/src/video/null_v.c b/src/video/null_v.c
new file mode 100644
index 000000000..ecdd3486c
--- /dev/null
+++ b/src/video/null_v.c
@@ -0,0 +1,45 @@
+/* $Id$ */
+
+#include "../stdafx.h"
+#include "../openttd.h"
+#include "../gfx.h"
+#include "../variables.h"
+#include "../window.h"
+#include "null_v.h"
+
+static void* _null_video_mem = NULL;
+
+static const char* NullVideoStart(const char* const* parm)
+{
+ _screen.width = _screen.pitch = _cur_resolution[0];
+ _screen.height = _cur_resolution[1];
+ _null_video_mem = malloc(_cur_resolution[0] * _cur_resolution[1]);
+ return NULL;
+}
+
+static void NullVideoStop(void) { free(_null_video_mem); }
+
+static void NullVideoMakeDirty(int left, int top, int width, int height) {}
+
+static void NullVideoMainLoop(void)
+{
+ uint i;
+
+ for (i = 0; i < 1000; i++) {
+ GameLoop();
+ _screen.dst_ptr = _null_video_mem;
+ UpdateWindows();
+ }
+}
+
+static bool NullVideoChangeRes(int w, int h) { return false; }
+static void NullVideoFullScreen(bool fs) {}
+
+const HalVideoDriver _null_video_driver = {
+ NullVideoStart,
+ NullVideoStop,
+ NullVideoMakeDirty,
+ NullVideoMainLoop,
+ NullVideoChangeRes,
+ NullVideoFullScreen,
+};
diff --git a/src/video/null_v.h b/src/video/null_v.h
new file mode 100644
index 000000000..56922d9b3
--- /dev/null
+++ b/src/video/null_v.h
@@ -0,0 +1,10 @@
+/* $Id$ */
+
+#ifndef VIDEO_NULL_H
+#define VIDEO_NULL_H
+
+#include "../hal.h"
+
+extern const HalVideoDriver _null_video_driver;
+
+#endif
diff --git a/src/video/sdl_v.c b/src/video/sdl_v.c
new file mode 100644
index 000000000..e88de85a5
--- /dev/null
+++ b/src/video/sdl_v.c
@@ -0,0 +1,515 @@
+/* $Id$ */
+
+#include "../stdafx.h"
+
+#ifdef WITH_SDL
+
+#include "../openttd.h"
+#include "../debug.h"
+#include "../functions.h"
+#include "../gfx.h"
+#include "../macros.h"
+#include "../sdl.h"
+#include "../window.h"
+#include "../network/network.h"
+#include "../variables.h"
+#include "sdl_v.h"
+#include <SDL.h>
+
+static SDL_Surface *_sdl_screen;
+static bool _all_modes;
+
+#define MAX_DIRTY_RECTS 100
+static SDL_Rect _dirty_rects[MAX_DIRTY_RECTS];
+static int _num_dirty_rects;
+
+static void SdlVideoMakeDirty(int left, int top, int width, int height)
+{
+ if (_num_dirty_rects < MAX_DIRTY_RECTS) {
+ _dirty_rects[_num_dirty_rects].x = left;
+ _dirty_rects[_num_dirty_rects].y = top;
+ _dirty_rects[_num_dirty_rects].w = width;
+ _dirty_rects[_num_dirty_rects].h = height;
+ }
+ _num_dirty_rects++;
+}
+
+static void UpdatePalette(uint start, uint count)
+{
+ SDL_Color pal[256];
+ uint i;
+
+ for (i = 0; i != count; i++) {
+ pal[i].r = _cur_palette[start + i].r;
+ pal[i].g = _cur_palette[start + i].g;
+ pal[i].b = _cur_palette[start + i].b;
+ pal[i].unused = 0;
+ }
+
+ SDL_CALL SDL_SetColors(_sdl_screen, pal, start, count);
+}
+
+static void InitPalette(void)
+{
+ UpdatePalette(0, 256);
+}
+
+static void CheckPaletteAnim(void)
+{
+ if (_pal_last_dirty != -1) {
+ UpdatePalette(_pal_first_dirty, _pal_last_dirty - _pal_first_dirty + 1);
+ _pal_last_dirty = -1;
+ }
+}
+
+static void DrawSurfaceToScreen(void)
+{
+ int n = _num_dirty_rects;
+ if (n != 0) {
+ _num_dirty_rects = 0;
+ if (n > MAX_DIRTY_RECTS)
+ SDL_CALL SDL_UpdateRect(_sdl_screen, 0, 0, 0, 0);
+ else
+ SDL_CALL SDL_UpdateRects(_sdl_screen, n, _dirty_rects);
+ }
+}
+
+static const uint16 default_resolutions[][2] = {
+ { 640, 480},
+ { 800, 600},
+ {1024, 768},
+ {1152, 864},
+ {1280, 800},
+ {1280, 960},
+ {1280, 1024},
+ {1400, 1050},
+ {1600, 1200},
+ {1680, 1050},
+ {1920, 1200}
+};
+
+static void GetVideoModes(void)
+{
+ int i;
+ SDL_Rect **modes;
+
+ modes = SDL_CALL SDL_ListModes(NULL, SDL_SWSURFACE + (_fullscreen ? SDL_FULLSCREEN : 0));
+
+ if (modes == NULL)
+ error("sdl: no modes available");
+
+ _all_modes = (modes == (void*)-1);
+
+ if (_all_modes) {
+ // all modes available, put some default ones here
+ memcpy(_resolutions, default_resolutions, sizeof(default_resolutions));
+ _num_resolutions = lengthof(default_resolutions);
+ } else {
+ int n = 0;
+ for (i = 0; modes[i]; i++) {
+ int w = modes[i]->w;
+ int h = modes[i]->h;
+ if (IS_INT_INSIDE(w, 640, MAX_SCREEN_WIDTH + 1) &&
+ IS_INT_INSIDE(h, 480, MAX_SCREEN_HEIGHT + 1)) {
+ int j;
+ for (j = 0; j < n; j++) {
+ if (_resolutions[j][0] == w && _resolutions[j][1] == h) break;
+ }
+
+ if (j == n) {
+ _resolutions[j][0] = w;
+ _resolutions[j][1] = h;
+ if (++n == lengthof(_resolutions)) break;
+ }
+ }
+ }
+ _num_resolutions = n;
+ SortResolutions(_num_resolutions);
+ }
+}
+
+static void GetAvailableVideoMode(int *w, int *h)
+{
+ int i;
+ int best;
+ uint delta;
+
+ // all modes available?
+ if (_all_modes) return;
+
+ // is the wanted mode among the available modes?
+ for (i = 0; i != _num_resolutions; i++) {
+ if (*w == _resolutions[i][0] && *h == _resolutions[i][1]) return;
+ }
+
+ // use the closest possible resolution
+ best = 0;
+ delta = abs((_resolutions[0][0] - *w) * (_resolutions[0][1] - *h));
+ for (i = 1; i != _num_resolutions; ++i) {
+ uint newdelta = abs((_resolutions[i][0] - *w) * (_resolutions[i][1] - *h));
+ if (newdelta < delta) {
+ best = i;
+ delta = newdelta;
+ }
+ }
+ *w = _resolutions[best][0];
+ *h = _resolutions[best][1];
+}
+
+#ifndef ICON_DIR
+#define ICON_DIR "media"
+#endif
+
+#ifdef WIN32
+/* Let's redefine the LoadBMP macro with because we are dynamically
+ * loading SDL and need to 'SDL_CALL' all functions */
+#undef SDL_LoadBMP
+#define SDL_LoadBMP(file) SDL_LoadBMP_RW(SDL_CALL SDL_RWFromFile(file, "rb"), 1)
+#endif
+
+static bool CreateMainSurface(int w, int h)
+{
+ extern const char _openttd_revision[];
+ SDL_Surface *newscreen, *icon;
+ char caption[50];
+
+ GetAvailableVideoMode(&w, &h);
+
+ DEBUG(driver, 1, "SDL: using mode %dx%d", w, h);
+
+ /* Give the application an icon */
+ icon = SDL_CALL SDL_LoadBMP(ICON_DIR PATHSEP "openttd.32.bmp");
+ if (icon != NULL) {
+ /* Get the colourkey, which will be magenta */
+ uint32 rgbmap = SDL_CALL SDL_MapRGB(icon->format, 255, 0, 255);
+
+ SDL_CALL SDL_SetColorKey(icon, SDL_SRCCOLORKEY, rgbmap);
+ SDL_CALL SDL_WM_SetIcon(icon, NULL);
+ SDL_CALL SDL_FreeSurface(icon);
+ }
+
+ // DO NOT CHANGE TO HWSURFACE, IT DOES NOT WORK
+ newscreen = SDL_CALL SDL_SetVideoMode(w, h, 8, SDL_SWSURFACE | SDL_HWPALETTE | (_fullscreen ? SDL_FULLSCREEN : SDL_RESIZABLE));
+ if (newscreen == NULL)
+ return false;
+
+ _screen.width = newscreen->w;
+ _screen.height = newscreen->h;
+ _screen.pitch = newscreen->pitch;
+
+ _sdl_screen = newscreen;
+ InitPalette();
+
+ snprintf(caption, sizeof(caption), "OpenTTD %s", _openttd_revision);
+ SDL_CALL SDL_WM_SetCaption(caption, caption);
+ SDL_CALL SDL_ShowCursor(0);
+
+ GameSizeChanged();
+
+ return true;
+}
+
+typedef struct VkMapping {
+ uint16 vk_from;
+ byte vk_count;
+ byte map_to;
+} VkMapping;
+
+#define AS(x, z) {x, 0, z}
+#define AM(x, y, z, w) {x, y - x, z}
+
+static const VkMapping _vk_mapping[] = {
+ // Pageup stuff + up/down
+ AM(SDLK_PAGEUP, SDLK_PAGEDOWN, WKC_PAGEUP, WKC_PAGEDOWN),
+ AS(SDLK_UP, WKC_UP),
+ AS(SDLK_DOWN, WKC_DOWN),
+ AS(SDLK_LEFT, WKC_LEFT),
+ AS(SDLK_RIGHT, WKC_RIGHT),
+
+ AS(SDLK_HOME, WKC_HOME),
+ AS(SDLK_END, WKC_END),
+
+ AS(SDLK_INSERT, WKC_INSERT),
+ AS(SDLK_DELETE, WKC_DELETE),
+
+ // Map letters & digits
+ AM(SDLK_a, SDLK_z, 'A', 'Z'),
+ AM(SDLK_0, SDLK_9, '0', '9'),
+
+ AS(SDLK_ESCAPE, WKC_ESC),
+ AS(SDLK_PAUSE, WKC_PAUSE),
+ AS(SDLK_BACKSPACE, WKC_BACKSPACE),
+
+ AS(SDLK_SPACE, WKC_SPACE),
+ AS(SDLK_RETURN, WKC_RETURN),
+ AS(SDLK_TAB, WKC_TAB),
+
+ // Function keys
+ AM(SDLK_F1, SDLK_F12, WKC_F1, WKC_F12),
+
+ // Numeric part.
+ // What is the virtual keycode for numeric enter??
+ AM(SDLK_KP0, SDLK_KP9, WKC_NUM_0, WKC_NUM_9),
+ AS(SDLK_KP_DIVIDE, WKC_NUM_DIV),
+ AS(SDLK_KP_MULTIPLY, WKC_NUM_MUL),
+ AS(SDLK_KP_MINUS, WKC_NUM_MINUS),
+ AS(SDLK_KP_PLUS, WKC_NUM_PLUS),
+ AS(SDLK_KP_ENTER, WKC_NUM_ENTER),
+ AS(SDLK_KP_PERIOD, WKC_NUM_DECIMAL)
+};
+
+static uint32 ConvertSdlKeyIntoMy(SDL_keysym *sym)
+{
+ const VkMapping *map;
+ uint key = 0;
+
+ for (map = _vk_mapping; map != endof(_vk_mapping); ++map) {
+ if ((uint)(sym->sym - map->vk_from) <= map->vk_count) {
+ key = sym->sym - map->vk_from + map->map_to;
+ break;
+ }
+ }
+
+ // check scancode for BACKQUOTE key, because we want the key left of "1", not anything else (on non-US keyboards)
+#if defined(WIN32) || defined(__OS2__)
+ if (sym->scancode == 41) key = WKC_BACKQUOTE;
+#elif defined(__APPLE__)
+ if (sym->scancode == 10) key = WKC_BACKQUOTE;
+#elif defined(__MORPHOS__)
+ if (sym->scancode == 0) key = WKC_BACKQUOTE; // yes, that key is code '0' under MorphOS :)
+#elif defined(__BEOS__)
+ if (sym->scancode == 17) key = WKC_BACKQUOTE;
+#elif defined(__SVR4) && defined(__sun)
+ if (sym->scancode == 60) key = WKC_BACKQUOTE;
+ if (sym->scancode == 49) key = WKC_BACKSPACE;
+#elif defined(__sgi__)
+ if (sym->scancode == 22) key = WKC_BACKQUOTE;
+#else
+ if (sym->scancode == 49) key = WKC_BACKQUOTE;
+#endif
+
+ // META are the command keys on mac
+ if (sym->mod & KMOD_META) key |= WKC_META;
+ if (sym->mod & KMOD_SHIFT) key |= WKC_SHIFT;
+ if (sym->mod & KMOD_CTRL) key |= WKC_CTRL;
+ if (sym->mod & KMOD_ALT) key |= WKC_ALT;
+ // these two lines really help porting hotkey combos. Uncomment to use -- Bjarni
+#if 0
+ DEBUG(driver, 0, "Scancode character pressed %u", sym->scancode);
+ DEBUG(driver, 0, "Unicode character pressed %u", sym->unicode);
+#endif
+ return (key << 16) + sym->unicode;
+}
+
+static int PollEvent(void)
+{
+ SDL_Event ev;
+
+ if (!SDL_CALL SDL_PollEvent(&ev)) return -2;
+
+ switch (ev.type) {
+ case SDL_MOUSEMOTION:
+ if (_cursor.fix_at) {
+ int dx = ev.motion.x - _cursor.pos.x;
+ int dy = ev.motion.y - _cursor.pos.y;
+ if (dx != 0 || dy != 0) {
+ _cursor.delta.x += dx;
+ _cursor.delta.y += dy;
+ SDL_CALL SDL_WarpMouse(_cursor.pos.x, _cursor.pos.y);
+ }
+ } else {
+ _cursor.delta.x = ev.motion.x - _cursor.pos.x;
+ _cursor.delta.y = ev.motion.y - _cursor.pos.y;
+ _cursor.pos.x = ev.motion.x;
+ _cursor.pos.y = ev.motion.y;
+ _cursor.dirty = true;
+ }
+ HandleMouseEvents();
+ break;
+
+ case SDL_MOUSEBUTTONDOWN:
+ if (_rightclick_emulate && SDL_CALL SDL_GetModState() & KMOD_CTRL) {
+ ev.button.button = SDL_BUTTON_RIGHT;
+ }
+
+ switch (ev.button.button) {
+ case SDL_BUTTON_LEFT:
+ _left_button_down = true;
+ break;
+
+ case SDL_BUTTON_RIGHT:
+ _right_button_down = true;
+ _right_button_clicked = true;
+ break;
+
+ case SDL_BUTTON_WHEELUP: _cursor.wheel--; break;
+ case SDL_BUTTON_WHEELDOWN: _cursor.wheel++; break;
+
+ default: break;
+ }
+ HandleMouseEvents();
+ break;
+
+ case SDL_MOUSEBUTTONUP:
+ if (_rightclick_emulate) {
+ _right_button_down = false;
+ _left_button_down = false;
+ _left_button_clicked = false;
+ } else if (ev.button.button == SDL_BUTTON_LEFT) {
+ _left_button_down = false;
+ _left_button_clicked = false;
+ } else if (ev.button.button == SDL_BUTTON_RIGHT) {
+ _right_button_down = false;
+ }
+ HandleMouseEvents();
+ break;
+
+ case SDL_ACTIVEEVENT:
+ if (!(ev.active.state & SDL_APPMOUSEFOCUS)) break;
+
+ if (ev.active.gain) { // mouse entered the window, enable cursor
+ _cursor.in_window = true;
+ } else {
+ UndrawMouseCursor(); // mouse left the window, undraw cursor
+ _cursor.in_window = false;
+ }
+ break;
+
+ case SDL_QUIT: HandleExitGameRequest(); break;
+
+ case SDL_KEYDOWN: /* Toggle full-screen on ALT + ENTER/F */
+ if ((ev.key.keysym.mod & (KMOD_ALT | KMOD_META)) &&
+ (ev.key.keysym.sym == SDLK_RETURN || ev.key.keysym.sym == SDLK_f)) {
+ ToggleFullScreen(!_fullscreen);
+ } else {
+ HandleKeypress(ConvertSdlKeyIntoMy(&ev.key.keysym));
+ }
+ break;
+
+ case SDL_VIDEORESIZE: {
+ int w = clamp(ev.resize.w, 64, MAX_SCREEN_WIDTH);
+ int h = clamp(ev.resize.h, 64, MAX_SCREEN_HEIGHT);
+ ChangeResInGame(w, h);
+ break;
+ }
+ }
+ return -1;
+}
+
+static const char *SdlVideoStart(const char * const *parm)
+{
+ char buf[30];
+
+ const char *s = SdlOpen(SDL_INIT_VIDEO);
+ if (s != NULL) return s;
+
+ SDL_CALL SDL_VideoDriverName(buf, 30);
+ DEBUG(driver, 1, "SDL: using driver '%s'", buf);
+
+ GetVideoModes();
+ CreateMainSurface(_cur_resolution[0], _cur_resolution[1]);
+ MarkWholeScreenDirty();
+
+ SDL_CALL SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
+ SDL_CALL SDL_EnableUNICODE(1);
+ return NULL;
+}
+
+static void SdlVideoStop(void)
+{
+ SdlClose(SDL_INIT_VIDEO);
+}
+
+static void SdlVideoMainLoop(void)
+{
+ uint32 next_tick = SDL_CALL SDL_GetTicks() + 30;
+ uint32 cur_ticks;
+ uint32 pal_tick = 0;
+ uint32 mod;
+ int numkeys;
+ Uint8 *keys;
+
+ for (;;) {
+ InteractiveRandom(); // randomness
+
+ while (PollEvent() == -1) {}
+ if (_exit_game) return;
+
+ mod = SDL_CALL SDL_GetModState();
+ keys = SDL_CALL SDL_GetKeyState(&numkeys);
+#if defined(_DEBUG)
+ if (_shift_pressed)
+#else
+ /* Speedup when pressing tab, except when using ALT+TAB
+ * to switch to another application */
+ if (keys[SDLK_TAB] && (mod & KMOD_ALT) == 0)
+#endif
+ {
+ if (!_networking && _game_mode != GM_MENU) _fast_forward |= 2;
+ } else if (_fast_forward & 2) {
+ _fast_forward = 0;
+ }
+
+ cur_ticks = SDL_CALL SDL_GetTicks();
+ if ((_fast_forward && !_pause) || cur_ticks > next_tick)
+ next_tick = cur_ticks;
+
+ if (cur_ticks == next_tick) {
+ next_tick += 30;
+
+ _ctrl_pressed = !!(mod & KMOD_CTRL);
+ _shift_pressed = !!(mod & KMOD_SHIFT);
+#ifdef _DEBUG
+ _dbg_screen_rect = !!(mod & KMOD_CAPS);
+#endif
+
+ // determine which directional keys are down
+ _dirkeys =
+ (keys[SDLK_LEFT] ? 1 : 0) |
+ (keys[SDLK_UP] ? 2 : 0) |
+ (keys[SDLK_RIGHT] ? 4 : 0) |
+ (keys[SDLK_DOWN] ? 8 : 0);
+ GameLoop();
+
+ _screen.dst_ptr = _sdl_screen->pixels;
+ UpdateWindows();
+ if (++pal_tick > 4) {
+ CheckPaletteAnim();
+ pal_tick = 1;
+ }
+ DrawSurfaceToScreen();
+ } else {
+ SDL_CALL SDL_Delay(1);
+ _screen.dst_ptr = _sdl_screen->pixels;
+ DrawTextMessage();
+ DrawMouseCursor();
+ DrawSurfaceToScreen();
+ }
+ }
+}
+
+static bool SdlVideoChangeRes(int w, int h)
+{
+ return CreateMainSurface(w, h);
+}
+
+static void SdlVideoFullScreen(bool full_screen)
+{
+ _fullscreen = full_screen;
+ GetVideoModes(); // get the list of available video modes
+ if (_num_resolutions == 0 || !_video_driver->change_resolution(_cur_resolution[0], _cur_resolution[1])) {
+ // switching resolution failed, put back full_screen to original status
+ _fullscreen ^= true;
+ }
+}
+
+const HalVideoDriver _sdl_video_driver = {
+ SdlVideoStart,
+ SdlVideoStop,
+ SdlVideoMakeDirty,
+ SdlVideoMainLoop,
+ SdlVideoChangeRes,
+ SdlVideoFullScreen,
+};
+
+#endif
diff --git a/src/video/sdl_v.h b/src/video/sdl_v.h
new file mode 100644
index 000000000..07ba50f3c
--- /dev/null
+++ b/src/video/sdl_v.h
@@ -0,0 +1,10 @@
+/* $Id$ */
+
+#ifndef VIDEO_SDL_H
+#define VIDEO_SDL_H
+
+#include "../hal.h"
+
+extern const HalVideoDriver _sdl_video_driver;
+
+#endif
diff --git a/src/video/win32_v.c b/src/video/win32_v.c
new file mode 100644
index 000000000..7588653f0
--- /dev/null
+++ b/src/video/win32_v.c
@@ -0,0 +1,876 @@
+/* $Id$ */
+
+#include "../stdafx.h"
+#include "../openttd.h"
+#include "../functions.h"
+#include "../gfx.h"
+#include "../macros.h"
+#include "../network/network.h"
+#include "../variables.h"
+#include "../win32.h"
+#include "../window.h"
+#include "win32_v.h"
+#include <windows.h>
+#include <tchar.h>
+
+static struct {
+ HWND main_wnd;
+ HBITMAP dib_sect;
+ Pixel *bitmap_bits;
+ Pixel *buffer_bits;
+ Pixel *alloced_bits;
+ HPALETTE gdi_palette;
+ int width;
+ int height;
+ int width_org;
+ int height_org;
+ bool fullscreen;
+ bool double_size;
+ bool has_focus;
+ bool running;
+} _wnd;
+
+bool _force_full_redraw;
+bool _double_size;
+bool _window_maximize;
+uint _display_hz;
+uint _fullscreen_bpp;
+static uint16 _bck_resolution[2];
+
+static void MakePalette(void)
+{
+ LOGPALETTE *pal;
+ uint i;
+
+ pal = alloca(sizeof(LOGPALETTE) + (256-1) * sizeof(PALETTEENTRY));
+
+ pal->palVersion = 0x300;
+ pal->palNumEntries = 256;
+
+ for (i = 0; i != 256; i++) {
+ pal->palPalEntry[i].peRed = _cur_palette[i].r;
+ pal->palPalEntry[i].peGreen = _cur_palette[i].g;
+ pal->palPalEntry[i].peBlue = _cur_palette[i].b;
+ pal->palPalEntry[i].peFlags = 0;
+
+ }
+ _wnd.gdi_palette = CreatePalette(pal);
+ if (_wnd.gdi_palette == NULL) error("CreatePalette failed!\n");
+}
+
+static void UpdatePalette(HDC dc, uint start, uint count)
+{
+ RGBQUAD rgb[256];
+ uint i;
+
+ for (i = 0; i != count; i++) {
+ rgb[i].rgbRed = _cur_palette[start + i].r;
+ rgb[i].rgbGreen = _cur_palette[start + i].g;
+ rgb[i].rgbBlue = _cur_palette[start + i].b;
+ rgb[i].rgbReserved = 0;
+ }
+
+ SetDIBColorTable(dc, start, count, rgb);
+}
+
+typedef struct {
+ byte vk_from;
+ byte vk_count;
+ byte map_to;
+} VkMapping;
+
+#define AS(x, z) {x, 0, z}
+#define AM(x, y, z, w) {x, y - x, z}
+
+static const VkMapping _vk_mapping[] = {
+ // Pageup stuff + up/down
+ AM(VK_PRIOR,VK_DOWN, WKC_PAGEUP, WKC_DOWN),
+ // Map letters & digits
+ AM('A','Z','A','Z'),
+ AM('0','9','0','9'),
+
+ AS(VK_ESCAPE, WKC_ESC),
+ AS(VK_PAUSE, WKC_PAUSE),
+ AS(VK_BACK, WKC_BACKSPACE),
+ AM(VK_INSERT, VK_DELETE, WKC_INSERT, WKC_DELETE),
+
+ AS(VK_SPACE, WKC_SPACE),
+ AS(VK_RETURN, WKC_RETURN),
+ AS(VK_TAB, WKC_TAB),
+
+ // Function keys
+ AM(VK_F1, VK_F12, WKC_F1, WKC_F12),
+
+ // Numeric part.
+ // What is the virtual keycode for numeric enter??
+ AM(VK_NUMPAD0, VK_NUMPAD9, WKC_NUM_0, WKC_NUM_9),
+ AS(VK_DIVIDE, WKC_NUM_DIV),
+ AS(VK_MULTIPLY, WKC_NUM_MUL),
+ AS(VK_SUBTRACT, WKC_NUM_MINUS),
+ AS(VK_ADD, WKC_NUM_PLUS),
+ AS(VK_DECIMAL, WKC_NUM_DECIMAL)
+};
+
+static uint MapWindowsKey(uint sym)
+{
+ const VkMapping *map;
+ uint key = 0;
+
+ for (map = _vk_mapping; map != endof(_vk_mapping); ++map) {
+ if ((uint)(sym - map->vk_from) <= map->vk_count) {
+ key = sym - map->vk_from + map->map_to;
+ break;
+ }
+ }
+
+ if (GetAsyncKeyState(VK_SHIFT) < 0) key |= WKC_SHIFT;
+ if (GetAsyncKeyState(VK_CONTROL) < 0) key |= WKC_CTRL;
+ if (GetAsyncKeyState(VK_MENU) < 0) key |= WKC_ALT;
+ return key;
+}
+
+static bool AllocateDibSection(int w, int h);
+
+static void ClientSizeChanged(int w, int h)
+{
+ if (_wnd.double_size) {
+ w /= 2;
+ h /= 2;
+ }
+
+ // allocate new dib section of the new size
+ if (AllocateDibSection(w, h)) {
+ // mark all palette colors dirty
+ _pal_first_dirty = 0;
+ _pal_last_dirty = 255;
+ GameSizeChanged();
+
+ // redraw screen
+ if (_wnd.running) {
+ _screen.dst_ptr = _wnd.buffer_bits;
+ UpdateWindows();
+ }
+ }
+}
+
+#ifdef _DEBUG
+// Keep this function here..
+// It allows you to redraw the screen from within the MSVC debugger
+int RedrawScreenDebug(void)
+{
+ HDC dc,dc2;
+ static int _fooctr;
+ HBITMAP old_bmp;
+ HPALETTE old_palette;
+
+ _screen.dst_ptr = _wnd.buffer_bits;
+ UpdateWindows();
+
+ dc = GetDC(_wnd.main_wnd);
+ dc2 = CreateCompatibleDC(dc);
+
+ old_bmp = SelectObject(dc2, _wnd.dib_sect);
+ old_palette = SelectPalette(dc, _wnd.gdi_palette, FALSE);
+ BitBlt(dc, 0, 0, _wnd.width, _wnd.height, dc2, 0, 0, SRCCOPY);
+ SelectPalette(dc, old_palette, TRUE);
+ SelectObject(dc2, old_bmp);
+ DeleteDC(dc2);
+ ReleaseDC(_wnd.main_wnd, dc);
+
+ return _fooctr++;
+}
+#endif
+
+/* Windows 95 will not have a WM_MOUSELEAVE message, so define it if needed */
+#if !defined(WM_MOUSELEAVE)
+#define WM_MOUSELEAVE 0x02A3
+#endif
+#define TID_POLLMOUSE 1
+#define MOUSE_POLL_DELAY 75
+
+static void CALLBACK TrackMouseTimerProc(HWND hwnd, UINT msg, UINT event, DWORD time)
+{
+ RECT rc;
+ POINT pt;
+
+ /* Get the rectangle of our window and translate it to screen coordinates.
+ * Compare this with the current screen coordinates of the mouse and if it
+ * falls outside of the area or our window we have left the window. */
+ GetClientRect(hwnd, &rc);
+ MapWindowPoints(hwnd, HWND_DESKTOP, (LPPOINT)(LPRECT)&rc, 2);
+ GetCursorPos(&pt);
+
+ if (!PtInRect(&rc, pt) || (WindowFromPoint(pt) != hwnd)) {
+ KillTimer(hwnd, event);
+ PostMessage(hwnd, WM_MOUSELEAVE, 0, 0L);
+ }
+}
+
+static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_CREATE:
+ SetTimer(hwnd, TID_POLLMOUSE, MOUSE_POLL_DELAY, (TIMERPROC)TrackMouseTimerProc);
+ break;
+
+ case WM_PAINT: {
+ PAINTSTRUCT ps;
+ HDC dc,dc2;
+ HBITMAP old_bmp;
+ HPALETTE old_palette;
+
+ BeginPaint(hwnd, &ps);
+ dc = ps.hdc;
+ dc2 = CreateCompatibleDC(dc);
+ old_bmp = SelectObject(dc2, _wnd.dib_sect);
+ old_palette = SelectPalette(dc, _wnd.gdi_palette, FALSE);
+
+ if (_pal_last_dirty != -1) {
+ UpdatePalette(dc2, _pal_first_dirty, _pal_last_dirty - _pal_first_dirty + 1);
+ _pal_last_dirty = -1;
+ }
+
+ BitBlt(dc, 0, 0, _wnd.width, _wnd.height, dc2, 0, 0, SRCCOPY);
+ SelectPalette(dc, old_palette, TRUE);
+ SelectObject(dc2, old_bmp);
+ DeleteDC(dc2);
+ EndPaint(hwnd, &ps);
+ return 0;
+ }
+
+ case WM_PALETTECHANGED:
+ if ((HWND)wParam == hwnd) return 0;
+ /* FALLTHROUGH */
+
+ case WM_QUERYNEWPALETTE: {
+ HDC hDC = GetWindowDC(hwnd);
+ HPALETTE hOldPalette = SelectPalette(hDC, _wnd.gdi_palette, FALSE);
+ UINT nChanged = RealizePalette(hDC);
+
+ SelectPalette(hDC, hOldPalette, TRUE);
+ ReleaseDC(hwnd, hDC);
+ if (nChanged) InvalidateRect(hwnd, NULL, FALSE);
+ return 0;
+ }
+
+ case WM_CLOSE:
+ HandleExitGameRequest();
+ return 0;
+
+ case WM_DESTROY:
+ if (_window_maximize) {
+ _cur_resolution[0] = _bck_resolution[0];
+ _cur_resolution[1] = _bck_resolution[1];
+ }
+ return 0;
+
+ case WM_LBUTTONDOWN:
+ SetCapture(hwnd);
+ _left_button_down = true;
+ HandleMouseEvents();
+ return 0;
+
+ case WM_LBUTTONUP:
+ ReleaseCapture();
+ _left_button_down = false;
+ _left_button_clicked = false;
+ HandleMouseEvents();
+ return 0;
+
+ case WM_RBUTTONDOWN:
+ SetCapture(hwnd);
+ _right_button_down = true;
+ _right_button_clicked = true;
+ HandleMouseEvents();
+ return 0;
+
+ case WM_RBUTTONUP:
+ ReleaseCapture();
+ _right_button_down = false;
+ HandleMouseEvents();
+ return 0;
+
+ case WM_MOUSELEAVE:
+ UndrawMouseCursor();
+ _cursor.in_window = false;
+
+ if (!_left_button_down && !_right_button_down) MyShowCursor(true);
+ HandleMouseEvents();
+ return 0;
+
+ case WM_MOUSEMOVE: {
+ int x = (int16)LOWORD(lParam);
+ int y = (int16)HIWORD(lParam);
+ POINT pt;
+
+ /* If the mouse was not in the window and it has moved it means it has
+ * come into the window, so start drawing the mouse. Also start
+ * tracking the mouse for exiting the window */
+ if (!_cursor.in_window) {
+ _cursor.in_window = true;
+ SetTimer(hwnd, TID_POLLMOUSE, MOUSE_POLL_DELAY, (TIMERPROC)TrackMouseTimerProc);
+
+ DrawMouseCursor();
+ }
+
+ if (_wnd.double_size) {
+ x /= 2;
+ y /= 2;
+ }
+
+ if (_cursor.fix_at) {
+ int dx = x - _cursor.pos.x;
+ int dy = y - _cursor.pos.y;
+ if (dx != 0 || dy != 0) {
+ _cursor.delta.x += dx;
+ _cursor.delta.y += dy;
+
+ pt.x = _cursor.pos.x;
+ pt.y = _cursor.pos.y;
+
+ if (_wnd.double_size) {
+ pt.x *= 2;
+ pt.y *= 2;
+ }
+ ClientToScreen(hwnd, &pt);
+ SetCursorPos(pt.x, pt.y);
+ }
+ } else {
+ _cursor.delta.x += x - _cursor.pos.x;
+ _cursor.delta.y += y - _cursor.pos.y;
+ _cursor.pos.x = x;
+ _cursor.pos.y = y;
+ _cursor.dirty = true;
+ }
+ MyShowCursor(false);
+ HandleMouseEvents();
+ return 0;
+ }
+
+ case WM_KEYDOWN: {
+ // this is the rewritten ascii input function
+ // it disables windows deadkey handling --> more linux like :D
+ wchar_t w = 0;
+ byte ks[256];
+ uint scancode;
+ uint32 pressed_key;
+
+ GetKeyboardState(ks);
+ if (ToUnicode(wParam, 0, ks, &w, 1, 0) != 1) {
+ /* On win9x ToUnicode always fails, so fall back to ToAscii */
+ if (ToAscii(wParam, 0, ks, &w, 0) != 1) w = 0; // no translation was possible
+ }
+
+ pressed_key = w | MapWindowsKey(wParam) << 16;
+
+ scancode = GB(lParam, 16, 8);
+ if (scancode == 41) pressed_key = w | WKC_BACKQUOTE << 16;
+
+ if (GB(pressed_key, 16, 16) == ('D' | WKC_CTRL) && !_wnd.fullscreen) {
+ _double_size ^= 1;
+ _wnd.double_size = _double_size;
+ ClientSizeChanged(_wnd.width, _wnd.height);
+ MarkWholeScreenDirty();
+ }
+ HandleKeypress(pressed_key);
+ break;
+ }
+
+ case WM_SYSKEYDOWN: /* user presses F10 or Alt, both activating the title-menu */
+ switch (wParam) {
+ case VK_RETURN:
+ case 'F': /* Full Screen on ALT + ENTER/F */
+ ToggleFullScreen(!_wnd.fullscreen);
+ return 0;
+
+ case VK_MENU: /* Just ALT */
+ return 0; // do nothing
+
+ case VK_F10: /* F10, ignore activation of menu */
+ HandleKeypress(MapWindowsKey(wParam) << 16);
+ return 0;
+
+ default: /* ALT in combination with something else */
+ HandleKeypress(MapWindowsKey(wParam) << 16);
+ break;
+ }
+ break;
+
+ case WM_SIZE:
+ if (wParam != SIZE_MINIMIZED) {
+ /* Set maximized flag when we maximize (obviously), but also when we
+ * switched to fullscreen from a maximized state */
+ _window_maximize = (wParam == SIZE_MAXIMIZED || (_window_maximize && _fullscreen));
+ if (_window_maximize) {
+ _bck_resolution[0] = _cur_resolution[0];
+ _bck_resolution[1] = _cur_resolution[1];
+ }
+ ClientSizeChanged(LOWORD(lParam), HIWORD(lParam));
+ }
+ return 0;
+
+ case WM_SIZING: {
+ RECT* r = (RECT*)lParam;
+ RECT r2;
+ int w, h;
+
+ SetRect(&r2, 0, 0, 0, 0);
+ AdjustWindowRect(&r2, GetWindowLong(hwnd, GWL_STYLE), FALSE);
+
+ w = r->right - r->left - (r2.right - r2.left);
+ h = r->bottom - r->top - (r2.bottom - r2.top);
+ if (_wnd.double_size) {
+ w /= 2;
+ h /= 2;
+ }
+ w = clamp(w, 64, MAX_SCREEN_WIDTH);
+ h = clamp(h, 64, MAX_SCREEN_HEIGHT);
+ if (_wnd.double_size) {
+ w *= 2;
+ h *= 2;
+ }
+ SetRect(&r2, 0, 0, w, h);
+
+ AdjustWindowRect(&r2, GetWindowLong(hwnd, GWL_STYLE), FALSE);
+ w = r2.right - r2.left;
+ h = r2.bottom - r2.top;
+
+ switch (wParam) {
+ case WMSZ_BOTTOM:
+ r->bottom = r->top + h;
+ break;
+
+ case WMSZ_BOTTOMLEFT:
+ r->bottom = r->top + h;
+ r->left = r->right - w;
+ break;
+
+ case WMSZ_BOTTOMRIGHT:
+ r->bottom = r->top + h;
+ r->right = r->left + w;
+ break;
+
+ case WMSZ_LEFT:
+ r->left = r->right - w;
+ break;
+
+ case WMSZ_RIGHT:
+ r->right = r->left + w;
+ break;
+
+ case WMSZ_TOP:
+ r->top = r->bottom - h;
+ break;
+
+ case WMSZ_TOPLEFT:
+ r->top = r->bottom - h;
+ r->left = r->right - w;
+ break;
+
+ case WMSZ_TOPRIGHT:
+ r->top = r->bottom - h;
+ r->right = r->left + w;
+ break;
+ }
+ return TRUE;
+ }
+
+// needed for wheel
+#if !defined(WM_MOUSEWHEEL)
+# define WM_MOUSEWHEEL 0x020A
+#endif //WM_MOUSEWHEEL
+#if !defined(GET_WHEEL_DELTA_WPARAM)
+# define GET_WHEEL_DELTA_WPARAM(wparam) ((short)HIWORD(wparam))
+#endif //GET_WHEEL_DELTA_WPARAM
+
+ case WM_MOUSEWHEEL: {
+ int delta = GET_WHEEL_DELTA_WPARAM(wParam);
+
+ if (delta < 0) {
+ _cursor.wheel++;
+ } else if (delta > 0) {
+ _cursor.wheel--;
+ }
+ HandleMouseEvents();
+ return 0;
+ }
+
+ case WM_ACTIVATEAPP:
+ _wnd.has_focus = (bool)wParam;
+ break;
+ }
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+}
+
+static void RegisterWndClass(void)
+{
+ static bool registered = false;
+
+ if (!registered) {
+ HINSTANCE hinst = GetModuleHandle(NULL);
+ WNDCLASS wnd = {
+ 0,
+ WndProcGdi,
+ 0,
+ 0,
+ hinst,
+ LoadIcon(hinst, MAKEINTRESOURCE(100)),
+ LoadCursor(NULL, IDC_ARROW),
+ 0,
+ 0,
+ _T("OTTD")
+ };
+
+ registered = true;
+ if (!RegisterClass(&wnd)) error("RegisterClass failed");
+ }
+}
+
+static void MakeWindow(bool full_screen)
+{
+ _fullscreen = full_screen;
+
+ _wnd.double_size = _double_size && !full_screen;
+
+ // recreate window?
+ if ((full_screen || _wnd.fullscreen) && _wnd.main_wnd) {
+ DestroyWindow(_wnd.main_wnd);
+ _wnd.main_wnd = 0;
+ }
+
+ if (full_screen) {
+ DEVMODE settings;
+
+ memset(&settings, 0, sizeof(settings));
+ settings.dmSize = sizeof(settings);
+ settings.dmFields =
+ (_fullscreen_bpp != 0 ? DM_BITSPERPEL : 0) |
+ DM_PELSWIDTH |
+ DM_PELSHEIGHT |
+ (_display_hz != 0 ? DM_DISPLAYFREQUENCY : 0);
+ settings.dmBitsPerPel = _fullscreen_bpp;
+ settings.dmPelsWidth = _wnd.width_org;
+ settings.dmPelsHeight = _wnd.height_org;
+ settings.dmDisplayFrequency = _display_hz;
+
+ if (ChangeDisplaySettings(&settings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) {
+ MakeWindow(false);
+ return;
+ }
+ } else if (_wnd.fullscreen) {
+ // restore display?
+ ChangeDisplaySettings(NULL, 0);
+ }
+
+ {
+ RECT r;
+ DWORD style, showstyle;
+ int x, y, w, h;
+
+ showstyle = SW_SHOWNORMAL;
+ _wnd.fullscreen = full_screen;
+ if (_wnd.fullscreen) {
+ style = WS_POPUP;
+ SetRect(&r, 0, 0, _wnd.width_org, _wnd.height_org);
+ } else {
+ style = WS_OVERLAPPEDWINDOW;
+ /* On window creation, check if we were in maximize mode before */
+ if (_window_maximize) showstyle = SW_SHOWMAXIMIZED;
+ SetRect(&r, 0, 0, _wnd.width, _wnd.height);
+ }
+
+ AdjustWindowRect(&r, style, FALSE);
+ w = r.right - r.left;
+ h = r.bottom - r.top;
+ x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2;
+ y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2;
+
+ if (_wnd.main_wnd) {
+ ShowWindow(_wnd.main_wnd, SW_SHOWNORMAL); // remove maximize-flag
+ SetWindowPos(_wnd.main_wnd, 0, x, y, w, h, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
+ } else {
+ extern const char _openttd_revision[];
+ TCHAR Windowtitle[50];
+
+ _sntprintf(Windowtitle, sizeof(Windowtitle), _T("OpenTTD %s"), MB_TO_WIDE(_openttd_revision));
+
+ _wnd.main_wnd = CreateWindow(_T("OTTD"), Windowtitle, style, x, y, w, h, 0, 0, GetModuleHandle(NULL), 0);
+ if (_wnd.main_wnd == NULL) error("CreateWindow failed");
+ ShowWindow(_wnd.main_wnd, showstyle);
+ }
+ }
+ GameSizeChanged(); // invalidate all windows, force redraw
+}
+
+static bool AllocateDibSection(int w, int h)
+{
+ BITMAPINFO *bi;
+ HDC dc;
+
+ w = clamp(w, 64, MAX_SCREEN_WIDTH);
+ h = clamp(h, 64, MAX_SCREEN_HEIGHT);
+
+ if (w == _screen.width && h == _screen.height)
+ return false;
+
+ _screen.width = w;
+ _screen.pitch = ALIGN(w, 4);
+ _screen.height = h;
+
+ if (_wnd.alloced_bits) {
+ free(_wnd.alloced_bits);
+ _wnd.alloced_bits = NULL;
+ }
+
+ bi = alloca(sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256);
+ memset(bi, 0, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256);
+ bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+
+ if (_wnd.double_size) {
+ w = ALIGN(w, 4);
+ _wnd.alloced_bits = _wnd.buffer_bits = malloc(w * h);
+ w *= 2;
+ h *= 2;
+ }
+
+ bi->bmiHeader.biWidth = _wnd.width = w;
+ bi->bmiHeader.biHeight = -(_wnd.height = h);
+
+ bi->bmiHeader.biPlanes = 1;
+ bi->bmiHeader.biBitCount = 8;
+ bi->bmiHeader.biCompression = BI_RGB;
+
+ if (_wnd.dib_sect) DeleteObject(_wnd.dib_sect);
+
+ dc = GetDC(0);
+ _wnd.dib_sect = CreateDIBSection(dc, bi, DIB_RGB_COLORS, (VOID**)&_wnd.bitmap_bits, NULL, 0);
+ if (_wnd.dib_sect == NULL) error("CreateDIBSection failed");
+ ReleaseDC(0, dc);
+
+ if (!_wnd.double_size) _wnd.buffer_bits = _wnd.bitmap_bits;
+
+ return true;
+}
+
+static const uint16 default_resolutions[][2] = {
+ { 640, 480 },
+ { 800, 600 },
+ { 1024, 768 },
+ { 1152, 864 },
+ { 1280, 800 },
+ { 1280, 960 },
+ { 1280, 1024 },
+ { 1400, 1050 },
+ { 1600, 1200 },
+ { 1680, 1050 },
+ { 1920, 1200 }
+};
+
+static void FindResolutions(void)
+{
+ uint n = 0;
+ uint i;
+ DEVMODEA dm;
+
+ /* XXX - EnumDisplaySettingsW crashes with unicows.dll on Windows95
+ * Doesn't really matter since we don't pass a string anyways, but still
+ * a letdown */
+ for (i = 0; EnumDisplaySettingsA(NULL, i, &dm) != 0; i++) {
+ if (dm.dmBitsPerPel == 8 && IS_INT_INSIDE(dm.dmPelsWidth, 640, MAX_SCREEN_WIDTH + 1) &&
+ IS_INT_INSIDE(dm.dmPelsHeight, 480, MAX_SCREEN_HEIGHT + 1)) {
+ uint j;
+
+ for (j = 0; j < n; j++) {
+ if (_resolutions[j][0] == dm.dmPelsWidth && _resolutions[j][1] == dm.dmPelsHeight) break;
+ }
+
+ /* In the previous loop we have checked already existing/added resolutions if
+ * they are the same as the new ones. If this is not the case (j == n); we have
+ * looped all and found none, add the new one to the list. If we have reached the
+ * maximum amount of resolutions, then quit querying the display */
+ if (j == n) {
+ _resolutions[j][0] = dm.dmPelsWidth;
+ _resolutions[j][1] = dm.dmPelsHeight;
+ if (++n == lengthof(_resolutions)) break;
+ }
+ }
+ }
+
+ /* We have found no resolutions, show the default list */
+ if (n == 0) {
+ memcpy(_resolutions, default_resolutions, sizeof(default_resolutions));
+ n = lengthof(default_resolutions);
+ }
+
+ _num_resolutions = n;
+ SortResolutions(_num_resolutions);
+}
+
+
+static const char *Win32GdiStart(const char * const *parm)
+{
+ memset(&_wnd, 0, sizeof(_wnd));
+
+ RegisterWndClass();
+
+ MakePalette();
+
+ FindResolutions();
+
+ // fullscreen uses those
+ _wnd.width_org = _cur_resolution[0];
+ _wnd.height_org = _cur_resolution[1];
+
+ AllocateDibSection(_cur_resolution[0], _cur_resolution[1]);
+ MarkWholeScreenDirty();
+
+ MakeWindow(_fullscreen);
+
+ return NULL;
+}
+
+static void Win32GdiStop(void)
+{
+ DeleteObject(_wnd.gdi_palette);
+ DeleteObject(_wnd.dib_sect);
+ DestroyWindow(_wnd.main_wnd);
+
+ if (_wnd.fullscreen) ChangeDisplaySettings(NULL, 0);
+ if (_double_size) {
+ _cur_resolution[0] *= 2;
+ _cur_resolution[1] *= 2;
+ }
+
+ MyShowCursor(true);
+}
+
+// simple upscaler by 2
+static void filter(int left, int top, int width, int height)
+{
+ uint p = _screen.pitch;
+ const Pixel *s = _wnd.buffer_bits + top * p + left;
+ Pixel *d = _wnd.bitmap_bits + top * p * 4 + left * 2;
+
+ for (; height > 0; height--) {
+ int i;
+
+ for (i = 0; i != width; i++) {
+ d[i * 2] = d[i * 2 + 1] = d[i * 2 + p * 2] = d[i * 2 + 1 + p * 2] = s[i];
+ }
+ s += p;
+ d += p * 4;
+ }
+}
+
+static void Win32GdiMakeDirty(int left, int top, int width, int height)
+{
+ RECT r = { left, top, left + width, top + height };
+
+ if (_wnd.double_size) {
+ filter(left, top, width, height);
+ r.left *= 2;
+ r.top *= 2;
+ r.right *= 2;
+ r.bottom *= 2;
+ }
+ InvalidateRect(_wnd.main_wnd, &r, FALSE);
+}
+
+static void CheckPaletteAnim(void)
+{
+ if (_pal_last_dirty == -1)
+ return;
+ InvalidateRect(_wnd.main_wnd, NULL, FALSE);
+}
+
+static void Win32GdiMainLoop(void)
+{
+ MSG mesg;
+ uint32 next_tick = GetTickCount() + 30, cur_ticks;
+
+ _wnd.running = true;
+
+ for (;;) {
+ while (PeekMessage(&mesg, NULL, 0, 0, PM_REMOVE)) {
+ InteractiveRandom(); // randomness
+ DispatchMessage(&mesg);
+ }
+ if (_exit_game) return;
+
+#if defined(_DEBUG)
+ if (_wnd.has_focus && GetAsyncKeyState(VK_SHIFT) < 0 &&
+#else
+ /* Speed up using TAB, but disable for ALT+TAB of course */
+ if (_wnd.has_focus && GetAsyncKeyState(VK_TAB) < 0 && GetAsyncKeyState(VK_MENU) >= 0 &&
+#endif
+ !_networking && _game_mode != GM_MENU) {
+ _fast_forward |= 2;
+ } else if (_fast_forward & 2) {
+ _fast_forward = 0;
+ }
+
+ cur_ticks = GetTickCount();
+ if ((_fast_forward && !_pause) || cur_ticks > next_tick)
+ next_tick = cur_ticks;
+
+ if (cur_ticks == next_tick) {
+ next_tick += 30;
+ _ctrl_pressed = _wnd.has_focus && GetAsyncKeyState(VK_CONTROL)<0;
+ _shift_pressed = _wnd.has_focus && GetAsyncKeyState(VK_SHIFT)<0;
+#ifdef _DEBUG
+ _dbg_screen_rect = _wnd.has_focus && GetAsyncKeyState(VK_CAPITAL)<0;
+#endif
+
+ // determine which directional keys are down
+ if (_wnd.has_focus) {
+ _dirkeys =
+ (GetAsyncKeyState(VK_LEFT) < 0 ? 1 : 0) +
+ (GetAsyncKeyState(VK_UP) < 0 ? 2 : 0) +
+ (GetAsyncKeyState(VK_RIGHT) < 0 ? 4 : 0) +
+ (GetAsyncKeyState(VK_DOWN) < 0 ? 8 : 0);
+ } else {
+ _dirkeys = 0;
+ }
+
+ GameLoop();
+ _cursor.delta.x = _cursor.delta.y = 0;
+
+ if (_force_full_redraw) MarkWholeScreenDirty();
+
+ GdiFlush();
+ _screen.dst_ptr = _wnd.buffer_bits;
+ UpdateWindows();
+ CheckPaletteAnim();
+ } else {
+ Sleep(1);
+ GdiFlush();
+ _screen.dst_ptr = _wnd.buffer_bits;
+ DrawTextMessage();
+ DrawMouseCursor();
+ }
+ }
+}
+
+static bool Win32GdiChangeRes(int w, int h)
+{
+ _wnd.width = _wnd.width_org = w;
+ _wnd.height = _wnd.height_org = h;
+
+ MakeWindow(_fullscreen); // _wnd.fullscreen screws up ingame resolution switching
+
+ return true;
+}
+
+static void Win32GdiFullScreen(bool full_screen)
+{
+ MakeWindow(full_screen);
+}
+
+const HalVideoDriver _win32_video_driver = {
+ Win32GdiStart,
+ Win32GdiStop,
+ Win32GdiMakeDirty,
+ Win32GdiMainLoop,
+ Win32GdiChangeRes,
+ Win32GdiFullScreen,
+};
diff --git a/src/video/win32_v.h b/src/video/win32_v.h
new file mode 100644
index 000000000..c3b23a61a
--- /dev/null
+++ b/src/video/win32_v.h
@@ -0,0 +1,10 @@
+/* $Id$ */
+
+#ifndef VIDEO_WIN32_H
+#define VIDEO_WIN32_H
+
+#include "../hal.h"
+
+extern const HalVideoDriver _win32_video_driver;
+
+#endif
diff --git a/src/viewport.c b/src/viewport.c
new file mode 100644
index 000000000..fa19e7b60
--- /dev/null
+++ b/src/viewport.c
@@ -0,0 +1,2504 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "debug.h"
+#include "functions.h"
+#include "gui.h"
+#include "spritecache.h"
+#include "strings.h"
+#include "table/sprites.h"
+#include "table/strings.h"
+#include "map.h"
+#include "viewport.h"
+#include "window.h"
+#include "vehicle.h"
+#include "station.h"
+#include "gfx.h"
+#include "town.h"
+#include "signs.h"
+#include "waypoint.h"
+#include "variables.h"
+#include "train.h"
+
+#define VIEWPORT_DRAW_MEM (65536 * 2)
+
+/* viewport.c */
+// XXX - maximum viewports is maximum windows - 2 (main toolbar + status bar)
+static ViewPort _viewports[25 - 2];
+static uint32 _active_viewports; ///< bitmasked variable where each bit signifies if a viewport is in use or not
+assert_compile(lengthof(_viewports) < sizeof(_active_viewports) * 8);
+
+static bool _added_tile_sprite;
+static bool _offset_ground_sprites;
+
+/* The in-game coordiante system looks like this *
+ * *
+ * ^ Z *
+ * | *
+ * | *
+ * | *
+ * | *
+ * / \ *
+ * / \ *
+ * / \ *
+ * / \ *
+ * X < > Y *
+ */
+
+typedef struct StringSpriteToDraw {
+ uint16 string;
+ uint16 color;
+ struct StringSpriteToDraw *next;
+ int32 x;
+ int32 y;
+ uint32 params[2];
+ uint16 width;
+} StringSpriteToDraw;
+
+typedef struct TileSpriteToDraw {
+ uint32 image;
+ struct TileSpriteToDraw *next;
+ int32 x;
+ int32 y;
+ byte z;
+} TileSpriteToDraw;
+
+typedef struct ChildScreenSpriteToDraw {
+ uint32 image;
+ int32 x;
+ int32 y;
+ struct ChildScreenSpriteToDraw *next;
+} ChildScreenSpriteToDraw;
+
+typedef struct ParentSpriteToDraw {
+ uint32 image;
+ int32 left;
+ int32 top;
+ int32 right;
+ int32 bottom;
+ int32 xmin;
+ int32 ymin;
+ int32 xmax;
+ int32 ymax;
+ ChildScreenSpriteToDraw *child;
+ byte unk16;
+ byte zmin;
+ byte zmax;
+} ParentSpriteToDraw;
+
+// Quick hack to know how much memory to reserve when allocating from the spritelist
+// to prevent a buffer overflow.
+#define LARGEST_SPRITELIST_STRUCT ParentSpriteToDraw
+
+typedef struct ViewportDrawer {
+ DrawPixelInfo dpi;
+
+ byte *spritelist_mem;
+ const byte *eof_spritelist_mem;
+
+ StringSpriteToDraw **last_string, *first_string;
+ TileSpriteToDraw **last_tile, *first_tile;
+
+ ChildScreenSpriteToDraw **last_child;
+
+ ParentSpriteToDraw **parent_list;
+ ParentSpriteToDraw * const *eof_parent_list;
+
+ byte combine_sprites;
+
+ int offs_x, offs_y; // used when drawing ground sprites relative
+} ViewportDrawer;
+
+static ViewportDrawer *_cur_vd;
+
+TileHighlightData _thd;
+static TileInfo *_cur_ti;
+
+extern void SmallMapCenterOnCurrentPos(Window *w);
+
+static Point MapXYZToViewport(const ViewPort *vp, uint x, uint y, uint z)
+{
+ Point p = RemapCoords(x, y, z);
+ p.x -= vp->virtual_width / 2;
+ p.y -= vp->virtual_height / 2;
+ return p;
+}
+
+void InitViewports(void) {
+ memset(_viewports, 0, sizeof(_viewports));
+ _active_viewports = 0;
+}
+
+void DeleteWindowViewport(Window *w)
+{
+ CLRBIT(_active_viewports, w->viewport - _viewports);
+ w->viewport->width = 0;
+ w->viewport = NULL;
+}
+
+void AssignWindowViewport(Window *w, int x, int y,
+ int width, int height, uint32 follow_flags, byte zoom)
+{
+ ViewPort *vp;
+ Point pt;
+ uint32 bit;
+
+ for (vp = _viewports, bit = 0; ; vp++, bit++) {
+ assert(vp != endof(_viewports));
+ if (vp->width == 0) break;
+ }
+ SETBIT(_active_viewports, bit);
+
+ vp->left = x + w->left;
+ vp->top = y + w->top;
+ vp->width = width;
+ vp->height = height;
+
+ vp->zoom = zoom;
+
+ vp->virtual_width = width << zoom;
+ vp->virtual_height = height << zoom;
+
+ if (follow_flags & 0x80000000) {
+ const Vehicle *veh;
+
+ WP(w, vp_d).follow_vehicle = (VehicleID)(follow_flags & 0xFFFF);
+ veh = GetVehicle(WP(w, vp_d).follow_vehicle);
+ pt = MapXYZToViewport(vp, veh->x_pos, veh->y_pos, veh->z_pos);
+ } else {
+ uint x = TileX(follow_flags) * TILE_SIZE;
+ uint y = TileY(follow_flags) * TILE_SIZE;
+
+ WP(w, vp_d).follow_vehicle = INVALID_VEHICLE;
+ pt = MapXYZToViewport(vp, x, y, GetSlopeZ(x, y));
+ }
+
+ WP(w, vp_d).scrollpos_x = pt.x;
+ WP(w, vp_d).scrollpos_y = pt.y;
+ w->viewport = vp;
+ vp->virtual_left = 0;//pt.x;
+ vp->virtual_top = 0;//pt.y;
+}
+
+static Point _vp_move_offs;
+
+static void DoSetViewportPosition(Window* const *wz, int left, int top, int width, int height)
+{
+
+ for (; wz != _last_z_window; wz++) {
+ const Window *w = *wz;
+
+ if (left + width > w->left &&
+ w->left + w->width > left &&
+ top + height > w->top &&
+ w->top + w->height > top) {
+
+ if (left < w->left) {
+ DoSetViewportPosition(wz, left, top, w->left - left, height);
+ DoSetViewportPosition(wz, left + (w->left - left), top, width - (w->left - left), height);
+ return;
+ }
+
+ if (left + width > w->left + w->width) {
+ DoSetViewportPosition(wz, left, top, (w->left + w->width - left), height);
+ DoSetViewportPosition(wz, left + (w->left + w->width - left), top, width - (w->left + w->width - left) , height);
+ return;
+ }
+
+ if (top < w->top) {
+ DoSetViewportPosition(wz, left, top, width, (w->top - top));
+ DoSetViewportPosition(wz, left, top + (w->top - top), width, height - (w->top - top));
+ return;
+ }
+
+ if (top + height > w->top + w->height) {
+ DoSetViewportPosition(wz, left, top, width, (w->top + w->height - top));
+ DoSetViewportPosition(wz, left, top + (w->top + w->height - top), width , height - (w->top + w->height - top));
+ return;
+ }
+
+ return;
+ }
+ }
+
+ {
+ int xo = _vp_move_offs.x;
+ int yo = _vp_move_offs.y;
+
+ if (abs(xo) >= width || abs(yo) >= height) {
+ /* fully_outside */
+ RedrawScreenRect(left, top, left + width, top + height);
+ return;
+ }
+
+ GfxScroll(left, top, width, height, xo, yo);
+
+ if (xo > 0) {
+ RedrawScreenRect(left, top, xo + left, top + height);
+ left += xo;
+ width -= xo;
+ } else if (xo < 0) {
+ RedrawScreenRect(left+width+xo, top, left+width, top + height);
+ width += xo;
+ }
+
+ if (yo > 0) {
+ RedrawScreenRect(left, top, width+left, top + yo);
+ } else if (yo < 0) {
+ RedrawScreenRect(left, top + height + yo, width+left, top + height);
+ }
+ }
+}
+
+static void SetViewportPosition(Window *w, int x, int y)
+{
+ ViewPort *vp = w->viewport;
+ int old_left = vp->virtual_left;
+ int old_top = vp->virtual_top;
+ int i;
+ int left, top, width, height;
+
+ vp->virtual_left = x;
+ vp->virtual_top = y;
+
+ old_left >>= vp->zoom;
+ old_top >>= vp->zoom;
+ x >>= vp->zoom;
+ y >>= vp->zoom;
+
+ old_left -= x;
+ old_top -= y;
+
+ if (old_top == 0 && old_left == 0) return;
+
+ _vp_move_offs.x = old_left;
+ _vp_move_offs.y = old_top;
+
+ left = vp->left;
+ top = vp->top;
+ width = vp->width;
+ height = vp->height;
+
+ if (left < 0) {
+ width += left;
+ left = 0;
+ }
+
+ i = left + width - _screen.width;
+ if (i >= 0) width -= i;
+
+ if (width > 0) {
+ if (top < 0) {
+ height += top;
+ top = 0;
+ }
+
+ i = top + height - _screen.height;
+ if (i >= 0) height -= i;
+
+ if (height > 0) DoSetViewportPosition(FindWindowZPosition(w) + 1, left, top, width, height);
+ }
+}
+
+
+ViewPort *IsPtInWindowViewport(const Window *w, int x, int y)
+{
+ ViewPort *vp = w->viewport;
+
+ if (vp != NULL &&
+ IS_INT_INSIDE(x, vp->left, vp->left + vp->width) &&
+ IS_INT_INSIDE(y, vp->top, vp->top + vp->height))
+ return vp;
+
+ return NULL;
+}
+
+static Point TranslateXYToTileCoord(const ViewPort *vp, int x, int y)
+{
+ Point pt;
+ int a,b;
+ uint z;
+
+ if ( (uint)(x -= vp->left) >= (uint)vp->width ||
+ (uint)(y -= vp->top) >= (uint)vp->height) {
+ Point pt = {-1, -1};
+ return pt;
+ }
+
+ x = ((x << vp->zoom) + vp->virtual_left) >> 2;
+ y = ((y << vp->zoom) + vp->virtual_top) >> 1;
+
+#if !defined(NEW_ROTATION)
+ a = y-x;
+ b = y+x;
+#else
+ a = x+y;
+ b = x-y;
+#endif
+
+ /* we need to move variables in to the valid range, as the
+ * GetTileZoomCenterWindow() function can call here with invalid x and/or y,
+ * when the user tries to zoom out along the sides of the map */
+ a = clamp(a, 0, (int)(MapMaxX() * TILE_SIZE) - 1);
+ b = clamp(b, 0, (int)(MapMaxY() * TILE_SIZE) - 1);
+
+ z = GetSlopeZ(a, b ) / 2;
+ z = GetSlopeZ(a + z, b + z) / 2;
+ z = GetSlopeZ(a + z, b + z) / 2;
+ z = GetSlopeZ(a + z, b + z) / 2;
+ z = GetSlopeZ(a + z, b + z) / 2;
+
+ pt.x = a + z;
+ pt.y = b + z;
+
+ return pt;
+}
+
+/* When used for zooming, check area below current coordinates (x,y)
+ * and return the tile of the zoomed out/in position (zoom_x, zoom_y)
+ * when you just want the tile, make x = zoom_x and y = zoom_y */
+static Point GetTileFromScreenXY(int x, int y, int zoom_x, int zoom_y)
+{
+ Window *w;
+ ViewPort *vp;
+ Point pt;
+
+ if ( (w = FindWindowFromPt(x, y)) != NULL &&
+ (vp = IsPtInWindowViewport(w, x, y)) != NULL)
+ return TranslateXYToTileCoord(vp, zoom_x, zoom_y);
+
+ pt.y = pt.x = -1;
+ return pt;
+}
+
+Point GetTileBelowCursor(void)
+{
+ return GetTileFromScreenXY(_cursor.pos.x, _cursor.pos.y, _cursor.pos.x, _cursor.pos.y);
+}
+
+
+Point GetTileZoomCenterWindow(bool in, Window * w)
+{
+ int x, y;
+ ViewPort * vp;
+
+ vp = w->viewport;
+
+ if (in) {
+ x = ((_cursor.pos.x - vp->left) >> 1) + (vp->width >> 2);
+ y = ((_cursor.pos.y - vp->top) >> 1) + (vp->height >> 2);
+ } else {
+ x = vp->width - (_cursor.pos.x - vp->left);
+ y = vp->height - (_cursor.pos.y - vp->top);
+ }
+ /* Get the tile below the cursor and center on the zoomed-out center */
+ return GetTileFromScreenXY(_cursor.pos.x, _cursor.pos.y, x + vp->left, y + vp->top);
+}
+
+/** Update the status of the zoom-buttons according to the zoom-level
+ * of the viewport. This will update their status and invalidate accordingly
+ * @param window pointer to the window that has the zoom buttons
+ * @param vp pointer to the viewport whose zoom-level the buttons represent
+ * @param widget_zoom_in widget index for window with zoom-in button
+ * @param widget_zoom_out widget index for window with zoom-out button */
+void HandleZoomMessage(Window *w, const ViewPort *vp, byte widget_zoom_in, byte widget_zoom_out)
+{
+ SetWindowWidgetDisabledState(w, widget_zoom_in, vp->zoom == 0);
+ InvalidateWidget(w, widget_zoom_in);
+
+ SetWindowWidgetDisabledState(w, widget_zoom_out, vp->zoom == 2);
+ InvalidateWidget(w, widget_zoom_out);
+}
+
+void DrawGroundSpriteAt(uint32 image, int32 x, int32 y, byte z)
+{
+ ViewportDrawer *vd = _cur_vd;
+ TileSpriteToDraw *ts;
+
+ assert((image & SPRITE_MASK) < MAX_SPRITES);
+
+ if (vd->spritelist_mem >= vd->eof_spritelist_mem) {
+ DEBUG(sprite, 0, "Out of sprite memory");
+ return;
+ }
+ ts = (TileSpriteToDraw*)vd->spritelist_mem;
+
+ vd->spritelist_mem += sizeof(TileSpriteToDraw);
+
+ ts->image = image;
+ ts->next = NULL;
+ ts->x = x;
+ ts->y = y;
+ ts->z = z;
+ *vd->last_tile = ts;
+ vd->last_tile = &ts->next;
+}
+
+void DrawGroundSprite(uint32 image)
+{
+ if (_offset_ground_sprites) {
+ // offset ground sprite because of foundation?
+ AddChildSpriteScreen(image, _cur_vd->offs_x, _cur_vd->offs_y);
+ } else {
+ _added_tile_sprite = true;
+ DrawGroundSpriteAt(image, _cur_ti->x, _cur_ti->y, _cur_ti->z);
+ }
+}
+
+
+void OffsetGroundSprite(int x, int y)
+{
+ _cur_vd->offs_x = x;
+ _cur_vd->offs_y = y;
+ _offset_ground_sprites = true;
+}
+
+static void AddCombinedSprite(uint32 image, int x, int y, byte z)
+{
+ const ViewportDrawer *vd = _cur_vd;
+ Point pt = RemapCoords(x, y, z);
+ const Sprite* spr = GetSprite(image & SPRITE_MASK);
+
+ if (pt.x + spr->x_offs >= vd->dpi.left + vd->dpi.width ||
+ pt.x + spr->x_offs + spr->width <= vd->dpi.left ||
+ pt.y + spr->y_offs >= vd->dpi.top + vd->dpi.height ||
+ pt.y + spr->y_offs + spr->height <= vd->dpi.top)
+ return;
+
+ AddChildSpriteScreen(image, pt.x - vd->parent_list[-1]->left, pt.y - vd->parent_list[-1]->top);
+}
+
+
+void AddSortableSpriteToDraw(uint32 image, int x, int y, int w, int h, byte dz, byte z)
+{
+ ViewportDrawer *vd = _cur_vd;
+ ParentSpriteToDraw *ps;
+ const Sprite *spr;
+ Point pt;
+
+ assert((image & SPRITE_MASK) < MAX_SPRITES);
+
+ if (vd->combine_sprites == 2) {
+ AddCombinedSprite(image, x, y, z);
+ return;
+ }
+
+ vd->last_child = NULL;
+
+ if (vd->spritelist_mem >= vd->eof_spritelist_mem) {
+ DEBUG(sprite, 0, "Out of sprite memory");
+ return;
+ }
+ ps = (ParentSpriteToDraw*)vd->spritelist_mem;
+
+ if (vd->parent_list >= vd->eof_parent_list) {
+ // This can happen rarely, mostly when you zoom out completely
+ // and have a lot of stuff that moves (and is added to the
+ // sort-list, this function). To solve it, increase
+ // parent_list somewhere below to a higher number.
+ // This can not really hurt you, it just gives some black
+ // spots on the screen ;)
+ DEBUG(sprite, 0, "Out of sprite memory (parent_list)");
+ return;
+ }
+
+ pt = RemapCoords(x, y, z);
+ spr = GetSprite(image & SPRITE_MASK);
+ if ((ps->left = (pt.x += spr->x_offs)) >= vd->dpi.left + vd->dpi.width ||
+ (ps->right = (pt.x + spr->width )) <= vd->dpi.left ||
+ (ps->top = (pt.y += spr->y_offs)) >= vd->dpi.top + vd->dpi.height ||
+ (ps->bottom = (pt.y + spr->height)) <= vd->dpi.top) {
+ return;
+ }
+
+ vd->spritelist_mem += sizeof(ParentSpriteToDraw);
+
+ ps->image = image;
+ ps->xmin = x;
+ ps->xmax = x + w - 1;
+
+ ps->ymin = y;
+ ps->ymax = y + h - 1;
+
+ ps->zmin = z;
+ ps->zmax = z + dz - 1;
+
+ ps->unk16 = 0;
+ ps->child = NULL;
+ vd->last_child = &ps->child;
+
+ *vd->parent_list++ = ps;
+
+ if (vd->combine_sprites == 1) vd->combine_sprites = 2;
+}
+
+void StartSpriteCombine(void)
+{
+ _cur_vd->combine_sprites = 1;
+}
+
+void EndSpriteCombine(void)
+{
+ _cur_vd->combine_sprites = 0;
+}
+
+void AddChildSpriteScreen(uint32 image, int x, int y)
+{
+ ViewportDrawer *vd = _cur_vd;
+ ChildScreenSpriteToDraw *cs;
+
+ assert((image & SPRITE_MASK) < MAX_SPRITES);
+
+ if (vd->spritelist_mem >= vd->eof_spritelist_mem) {
+ DEBUG(sprite, 0, "Out of sprite memory");
+ return;
+ }
+ cs = (ChildScreenSpriteToDraw*)vd->spritelist_mem;
+
+ if (vd->last_child == NULL) return;
+
+ vd->spritelist_mem += sizeof(ChildScreenSpriteToDraw);
+
+ *vd->last_child = cs;
+ vd->last_child = &cs->next;
+
+ cs->image = image;
+ cs->x = x;
+ cs->y = y;
+ cs->next = NULL;
+}
+
+/* Returns a StringSpriteToDraw */
+void *AddStringToDraw(int x, int y, StringID string, uint32 params_1, uint32 params_2)
+{
+ ViewportDrawer *vd = _cur_vd;
+ StringSpriteToDraw *ss;
+
+ if (vd->spritelist_mem >= vd->eof_spritelist_mem) {
+ DEBUG(sprite, 0, "Out of sprite memory");
+ return NULL;
+ }
+ ss = (StringSpriteToDraw*)vd->spritelist_mem;
+
+ vd->spritelist_mem += sizeof(StringSpriteToDraw);
+
+ ss->string = string;
+ ss->next = NULL;
+ ss->x = x;
+ ss->y = y;
+ ss->params[0] = params_1;
+ ss->params[1] = params_2;
+ ss->width = 0;
+
+ *vd->last_string = ss;
+ vd->last_string = &ss->next;
+
+ return ss;
+}
+
+
+static void DrawSelectionSprite(uint32 image, const TileInfo *ti)
+{
+ if (_added_tile_sprite && !(_thd.drawstyle & HT_LINE)) { // draw on real ground
+ DrawGroundSpriteAt(image, ti->x, ti->y, ti->z + 7);
+ } else { // draw on top of foundation
+ AddSortableSpriteToDraw(image, ti->x, ti->y, 0x10, 0x10, 1, ti->z + 7);
+ }
+}
+
+static bool IsPartOfAutoLine(int px, int py)
+{
+ px -= _thd.selstart.x;
+ py -= _thd.selstart.y;
+
+ switch (_thd.drawstyle) {
+ case HT_LINE | HT_DIR_X: return py == 0; // x direction
+ case HT_LINE | HT_DIR_Y: return px == 0; // y direction
+ case HT_LINE | HT_DIR_HU: return px == -py || px == -py - 16; // horizontal upper
+ case HT_LINE | HT_DIR_HL: return px == -py || px == -py + 16; // horizontal lower
+ case HT_LINE | HT_DIR_VL: return px == py || px == py + 16; // vertival left
+ case HT_LINE | HT_DIR_VR: return px == py || px == py - 16; // vertical right
+ default:
+ NOT_REACHED();
+ }
+
+ /* useless, but avoids compiler warning this way */
+ return 0;
+}
+
+// [direction][side]
+static const int _AutorailType[6][2] = {
+ { HT_DIR_X, HT_DIR_X },
+ { HT_DIR_Y, HT_DIR_Y },
+ { HT_DIR_HU, HT_DIR_HL },
+ { HT_DIR_HL, HT_DIR_HU },
+ { HT_DIR_VL, HT_DIR_VR },
+ { HT_DIR_VR, HT_DIR_VL }
+};
+
+#include "table/autorail.h"
+
+static void DrawTileSelection(const TileInfo *ti)
+{
+ uint32 image;
+
+ // Draw a red error square?
+ if (_thd.redsq != 0 && _thd.redsq == ti->tile) {
+ DrawSelectionSprite(PALETTE_TILE_RED_PULSATING | (SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh]), ti);
+ return;
+ }
+
+ // no selection active?
+ if (_thd.drawstyle == 0) return;
+
+ // Inside the inner area?
+ if (IS_INSIDE_1D(ti->x, _thd.pos.x, _thd.size.x) &&
+ IS_INSIDE_1D(ti->y, _thd.pos.y, _thd.size.y)) {
+ if (_thd.drawstyle & HT_RECT) {
+ image = SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh];
+ if (_thd.make_square_red) image |= PALETTE_SEL_TILE_RED;
+ DrawSelectionSprite(image, ti);
+ } else if (_thd.drawstyle & HT_POINT) {
+ // Figure out the Z coordinate for the single dot.
+ byte z = ti->z;
+ if (ti->tileh & SLOPE_N) {
+ z += TILE_HEIGHT;
+ if (ti->tileh == SLOPE_STEEP_N) z += TILE_HEIGHT;
+ }
+ DrawGroundSpriteAt(_cur_dpi->zoom != 2 ? SPR_DOT : SPR_DOT_SMALL, ti->x, ti->y, z);
+ } else if (_thd.drawstyle & HT_RAIL /*&& _thd.place_mode == VHM_RAIL*/) {
+ // autorail highlight piece under cursor
+ uint type = _thd.drawstyle & 0xF;
+ assert(type <= 5);
+ image = SPR_AUTORAIL_BASE + _AutorailTilehSprite[ti->tileh][_AutorailType[type][0]];
+
+ if (_thd.make_square_red) image |= PALETTE_SEL_TILE_RED;
+ DrawSelectionSprite(image, ti);
+
+ } else if (IsPartOfAutoLine(ti->x, ti->y)) {
+ // autorail highlighting long line
+ int dir = _thd.drawstyle & ~0xF0;
+ uint side;
+
+ if (dir < 2) {
+ side = 0;
+ } else {
+ TileIndex start = TileVirtXY(_thd.selstart.x, _thd.selstart.y);
+ int diffx = myabs(TileX(start) - TileX(ti->tile));
+ int diffy = myabs(TileY(start) - TileY(ti->tile));
+ side = myabs(diffx - diffy);
+ }
+
+ image = SPR_AUTORAIL_BASE + _AutorailTilehSprite[ti->tileh][_AutorailType[dir][side]];
+
+ if (_thd.make_square_red) image |= PALETTE_SEL_TILE_RED;
+ DrawSelectionSprite(image, ti);
+ }
+ return;
+ }
+
+ // Check if it's inside the outer area?
+ if (_thd.outersize.x &&
+ _thd.size.x < _thd.size.x + _thd.outersize.x &&
+ IS_INSIDE_1D(ti->x, _thd.pos.x + _thd.offs.x, _thd.size.x + _thd.outersize.x) &&
+ IS_INSIDE_1D(ti->y, _thd.pos.y + _thd.offs.y, _thd.size.y + _thd.outersize.y)) {
+ // Draw a blue rect.
+ DrawSelectionSprite(PALETTE_SEL_TILE_BLUE | (SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh]), ti);
+ return;
+ }
+}
+
+static void ViewportAddLandscape(void)
+{
+ ViewportDrawer *vd = _cur_vd;
+ int x, y, width, height;
+ TileInfo ti;
+ bool direction;
+
+ _cur_ti = &ti;
+
+ // Transform into tile coordinates and round to closest full tile
+#if !defined(NEW_ROTATION)
+ x = ((vd->dpi.top >> 1) - (vd->dpi.left >> 2)) & ~0xF;
+ y = ((vd->dpi.top >> 1) + (vd->dpi.left >> 2) - 0x10) & ~0xF;
+#else
+ x = ((vd->dpi.top >> 1) + (vd->dpi.left >> 2) - 0x10) & ~0xF;
+ y = ((vd->dpi.left >> 2) - (vd->dpi.top >> 1)) & ~0xF;
+#endif
+ // determine size of area
+ {
+ Point pt = RemapCoords(x, y, 241);
+ width = (vd->dpi.left + vd->dpi.width - pt.x + 95) >> 6;
+ height = (vd->dpi.top + vd->dpi.height - pt.y) >> 5 << 1;
+ }
+
+ assert(width > 0);
+ assert(height > 0);
+
+ direction = false;
+
+ do {
+ int width_cur = width;
+ int x_cur = x;
+ int y_cur = y;
+
+ do {
+ TileType tt;
+
+ ti.x = x_cur;
+ ti.y = y_cur;
+ if (0 <= x_cur && x_cur < (int)MapMaxX() * TILE_SIZE &&
+ 0 <= y_cur && y_cur < (int)MapMaxY() * TILE_SIZE) {
+ TileIndex tile = TileVirtXY(x_cur, y_cur);
+
+ ti.tile = tile;
+ ti.tileh = GetTileSlope(tile, &ti.z);
+ tt = GetTileType(tile);
+ } else {
+ ti.tileh = SLOPE_FLAT;
+ ti.tile = 0;
+ ti.z = 0;
+ tt = MP_VOID;
+ }
+
+#if !defined(NEW_ROTATION)
+ y_cur += 0x10;
+ x_cur -= 0x10;
+#else
+ y_cur += 0x10;
+ x_cur += 0x10;
+#endif
+ _added_tile_sprite = false;
+ _offset_ground_sprites = false;
+
+ _tile_type_procs[tt]->draw_tile_proc(&ti);
+ DrawTileSelection(&ti);
+ } while (--width_cur);
+
+#if !defined(NEW_ROTATION)
+ if ( (direction^=1) != 0)
+ y += 0x10;
+ else
+ x += 0x10;
+#else
+ if ( (direction^=1) != 0)
+ x += 0x10;
+ else
+ y -= 0x10;
+#endif
+ } while (--height);
+}
+
+
+static void ViewportAddTownNames(DrawPixelInfo *dpi)
+{
+ Town *t;
+ int left, top, right, bottom;
+
+ if (!(_display_opt & DO_SHOW_TOWN_NAMES) || _game_mode == GM_MENU)
+ return;
+
+ left = dpi->left;
+ top = dpi->top;
+ right = left + dpi->width;
+ bottom = top + dpi->height;
+
+ switch (dpi->zoom) {
+ case 0:
+ FOR_ALL_TOWNS(t) {
+ if (bottom > t->sign.top &&
+ top < t->sign.top + 12 &&
+ right > t->sign.left &&
+ left < t->sign.left + t->sign.width_1) {
+ AddStringToDraw(t->sign.left + 1, t->sign.top + 1,
+ _patches.population_in_label ? STR_TOWN_LABEL_POP : STR_TOWN_LABEL,
+ t->index, t->population);
+ }
+ }
+ break;
+
+ case 1:
+ right += 2;
+ bottom += 2;
+
+ FOR_ALL_TOWNS(t) {
+ if (bottom > t->sign.top &&
+ top < t->sign.top + 24 &&
+ right > t->sign.left &&
+ left < t->sign.left + t->sign.width_1*2) {
+ AddStringToDraw(t->sign.left + 1, t->sign.top + 1,
+ _patches.population_in_label ? STR_TOWN_LABEL_POP : STR_TOWN_LABEL,
+ t->index, t->population);
+ }
+ }
+ break;
+
+ default: NOT_REACHED();
+ case 2:
+ right += 4;
+ bottom += 5;
+
+ FOR_ALL_TOWNS(t) {
+ if (bottom > t->sign.top &&
+ top < t->sign.top + 24 &&
+ right > t->sign.left &&
+ left < t->sign.left + t->sign.width_2*4) {
+ AddStringToDraw(t->sign.left + 5, t->sign.top + 1, STR_TOWN_LABEL_TINY_BLACK, t->index, 0);
+ AddStringToDraw(t->sign.left + 1, t->sign.top - 3, STR_TOWN_LABEL_TINY_WHITE, t->index, 0);
+ }
+ }
+ break;
+ }
+}
+
+
+static void AddStation(const Station *st, StringID str, uint16 width)
+{
+ StringSpriteToDraw *sstd;
+
+ sstd = AddStringToDraw(st->sign.left + 1, st->sign.top + 1, str, st->index, st->facilities);
+ if (sstd != NULL) {
+ sstd->color = (st->owner == OWNER_NONE || st->facilities == 0) ? 0xE : _player_colors[st->owner];
+ sstd->width = width;
+ }
+}
+
+
+static void ViewportAddStationNames(DrawPixelInfo *dpi)
+{
+ int left, top, right, bottom;
+ const Station *st;
+
+ if (!(_display_opt & DO_SHOW_STATION_NAMES) || _game_mode == GM_MENU)
+ return;
+
+ left = dpi->left;
+ top = dpi->top;
+ right = left + dpi->width;
+ bottom = top + dpi->height;
+
+ switch (dpi->zoom) {
+ case 0:
+ FOR_ALL_STATIONS(st) {
+ if (bottom > st->sign.top &&
+ top < st->sign.top + 12 &&
+ right > st->sign.left &&
+ left < st->sign.left + st->sign.width_1) {
+ AddStation(st, STR_305C_0, st->sign.width_1);
+ }
+ }
+ break;
+
+ case 1:
+ right += 2;
+ bottom += 2;
+ FOR_ALL_STATIONS(st) {
+ if (bottom > st->sign.top &&
+ top < st->sign.top + 24 &&
+ right > st->sign.left &&
+ left < st->sign.left + st->sign.width_1*2) {
+ AddStation(st, STR_305C_0, st->sign.width_1);
+ }
+ }
+ break;
+
+ default: NOT_REACHED();
+ case 2:
+ right += 4;
+ bottom += 5;
+ FOR_ALL_STATIONS(st) {
+ if (bottom > st->sign.top &&
+ top < st->sign.top + 24 &&
+ right > st->sign.left &&
+ left < st->sign.left + st->sign.width_2*4) {
+ AddStation(st, STR_STATION_SIGN_TINY, st->sign.width_2 | 0x8000);
+ }
+ }
+ break;
+ }
+}
+
+
+static void AddSign(const Sign *si, StringID str, uint16 width)
+{
+ StringSpriteToDraw *sstd;
+
+ sstd = AddStringToDraw(si->sign.left + 1, si->sign.top + 1, str, si->str, 0);
+ if (sstd != NULL) {
+ sstd->color = (si->owner == OWNER_NONE) ? 14 : _player_colors[si->owner];
+ sstd->width = width;
+ }
+}
+
+
+static void ViewportAddSigns(DrawPixelInfo *dpi)
+{
+ const Sign *si;
+ int left, top, right, bottom;
+
+ if (!(_display_opt & DO_SHOW_SIGNS))
+ return;
+
+ left = dpi->left;
+ top = dpi->top;
+ right = left + dpi->width;
+ bottom = top + dpi->height;
+
+ switch (dpi->zoom) {
+ case 0:
+ FOR_ALL_SIGNS(si) {
+ if (bottom > si->sign.top &&
+ top < si->sign.top + 12 &&
+ right > si->sign.left &&
+ left < si->sign.left + si->sign.width_1) {
+ AddSign(si, STR_2806, si->sign.width_1);
+ }
+ }
+ break;
+
+ case 1:
+ right += 2;
+ bottom += 2;
+ FOR_ALL_SIGNS(si) {
+ if (bottom > si->sign.top &&
+ top < si->sign.top + 24 &&
+ right > si->sign.left &&
+ left < si->sign.left + si->sign.width_1 * 2) {
+ AddSign(si, STR_2806, si->sign.width_1);
+ }
+ }
+ break;
+
+ default: NOT_REACHED();
+ case 2:
+ right += 4;
+ bottom += 5;
+ FOR_ALL_SIGNS(si) {
+ if (bottom > si->sign.top &&
+ top < si->sign.top + 24 &&
+ right > si->sign.left &&
+ left < si->sign.left + si->sign.width_2 * 4) {
+ AddSign(si, STR_2002, si->sign.width_2 | 0x8000);
+ }
+ }
+ break;
+ }
+}
+
+
+static void AddWaypoint(const Waypoint *wp, StringID str, uint16 width)
+{
+ StringSpriteToDraw *sstd;
+
+ sstd = AddStringToDraw(wp->sign.left + 1, wp->sign.top + 1, str, wp->index, 0);
+ if (sstd != NULL) {
+ sstd->color = (wp->deleted ? 0xE : 11);
+ sstd->width = width;
+ }
+}
+
+
+static void ViewportAddWaypoints(DrawPixelInfo *dpi)
+{
+ const Waypoint *wp;
+ int left, top, right, bottom;
+
+ if (!(_display_opt & DO_WAYPOINTS))
+ return;
+
+ left = dpi->left;
+ top = dpi->top;
+ right = left + dpi->width;
+ bottom = top + dpi->height;
+
+ switch (dpi->zoom) {
+ case 0:
+ FOR_ALL_WAYPOINTS(wp) {
+ if (bottom > wp->sign.top &&
+ top < wp->sign.top + 12 &&
+ right > wp->sign.left &&
+ left < wp->sign.left + wp->sign.width_1) {
+ AddWaypoint(wp, STR_WAYPOINT_VIEWPORT, wp->sign.width_1);
+ }
+ }
+ break;
+
+ case 1:
+ right += 2;
+ bottom += 2;
+ FOR_ALL_WAYPOINTS(wp) {
+ if (bottom > wp->sign.top &&
+ top < wp->sign.top + 24 &&
+ right > wp->sign.left &&
+ left < wp->sign.left + wp->sign.width_1*2) {
+ AddWaypoint(wp, STR_WAYPOINT_VIEWPORT, wp->sign.width_1);
+ }
+ }
+ break;
+
+ default: NOT_REACHED();
+ case 2:
+ right += 4;
+ bottom += 5;
+ FOR_ALL_WAYPOINTS(wp) {
+ if (bottom > wp->sign.top &&
+ top < wp->sign.top + 24 &&
+ right > wp->sign.left &&
+ left < wp->sign.left + wp->sign.width_2*4) {
+ AddWaypoint(wp, STR_WAYPOINT_VIEWPORT_TINY, wp->sign.width_2 | 0x8000);
+ }
+ }
+ break;
+ }
+}
+
+void UpdateViewportSignPos(ViewportSign *sign, int left, int top, StringID str)
+{
+ char buffer[128];
+ uint w;
+
+ sign->top = top;
+
+ GetString(buffer, str, lastof(buffer));
+ w = GetStringBoundingBox(buffer).width + 3;
+ sign->width_1 = w;
+ sign->left = left - w / 2;
+
+ /* zoomed out version */
+ _cur_fontsize = FS_SMALL;
+ w = GetStringBoundingBox(buffer).width + 3;
+ _cur_fontsize = FS_NORMAL;
+ sign->width_2 = w;
+}
+
+
+static void ViewportDrawTileSprites(TileSpriteToDraw *ts)
+{
+ do {
+ Point pt = RemapCoords(ts->x, ts->y, ts->z);
+ DrawSprite(ts->image, pt.x, pt.y);
+ ts = ts->next;
+ } while (ts != NULL);
+}
+
+static void ViewportSortParentSprites(ParentSpriteToDraw *psd[])
+{
+ while (*psd != NULL) {
+ ParentSpriteToDraw* ps = *psd;
+
+ if (!(ps->unk16 & 1)) {
+ ParentSpriteToDraw** psd2 = psd;
+
+ ps->unk16 |= 1;
+
+ while (*++psd2 != NULL) {
+ ParentSpriteToDraw* ps2 = *psd2;
+ ParentSpriteToDraw** psd3;
+
+ if (ps2->unk16 & 1) continue;
+
+ /* Decide which comparator to use, based on whether the bounding
+ * boxes overlap
+ */
+ if (ps->xmax > ps2->xmin && ps->xmin < ps2->xmax && // overlap in X?
+ ps->ymax > ps2->ymin && ps->ymin < ps2->ymax && // overlap in Y?
+ ps->zmax > ps2->zmin && ps->zmin < ps2->zmax) { // overlap in Z?
+ /* Use X+Y+Z as the sorting order, so sprites closer to the bottom of
+ * the screen and with higher Z elevation, are drawn in front.
+ * Here X,Y,Z are the coordinates of the "center of mass" of the sprite,
+ * i.e. X=(left+right)/2, etc.
+ * However, since we only care about order, don't actually divide / 2
+ */
+ if (ps->xmin + ps->xmax + ps->ymin + ps->ymax + ps->zmin + ps->zmax <=
+ ps2->xmin + ps2->xmax + ps2->ymin + ps2->ymax + ps2->zmin + ps2->zmax) {
+ continue;
+ }
+ } else {
+ if (ps->xmax < ps2->xmin ||
+ ps->ymax < ps2->ymin ||
+ ps->zmax < ps2->zmin || (
+ ps->xmin < ps2->xmax &&
+ ps->ymin < ps2->ymax &&
+ ps->zmin < ps2->zmax
+ )) {
+ continue;
+ }
+ }
+
+ // Swap the two sprites ps and ps2 using bubble-sort algorithm.
+ psd3 = psd;
+ do {
+ ParentSpriteToDraw* temp = *psd3;
+ *psd3 = ps2;
+ ps2 = temp;
+
+ psd3++;
+ } while (psd3 <= psd2);
+ }
+ } else {
+ psd++;
+ }
+ }
+}
+
+static void ViewportDrawParentSprites(ParentSpriteToDraw *psd[])
+{
+ for (; *psd != NULL; psd++) {
+ const ParentSpriteToDraw* ps = *psd;
+ Point pt = RemapCoords(ps->xmin, ps->ymin, ps->zmin);
+ const ChildScreenSpriteToDraw* cs;
+
+ DrawSprite(ps->image, pt.x, pt.y);
+
+ for (cs = ps->child; cs != NULL; cs = cs->next) {
+ DrawSprite(cs->image, ps->left + cs->x, ps->top + cs->y);
+ }
+ }
+}
+
+static void ViewportDrawStrings(DrawPixelInfo *dpi, const StringSpriteToDraw *ss)
+{
+ DrawPixelInfo dp;
+ byte zoom;
+
+ _cur_dpi = &dp;
+ dp = *dpi;
+
+ zoom = dp.zoom;
+ dp.zoom = 0;
+
+ dp.left >>= zoom;
+ dp.top >>= zoom;
+ dp.width >>= zoom;
+ dp.height >>= zoom;
+
+ do {
+ uint16 colour;
+
+ if (ss->width != 0) {
+ int x = (ss->x >> zoom) - 1;
+ int y = (ss->y >> zoom) - 1;
+ int bottom = y + 11;
+ int w = ss->width;
+
+ if (w & 0x8000) {
+ w &= ~0x8000;
+ y--;
+ bottom -= 6;
+ w -= 3;
+ }
+
+ /* Draw the rectangle if 'tranparent station signs' is off,
+ * or if we are drawing a general text sign (STR_2806) */
+ if (!(_display_opt & DO_TRANS_SIGNS) || ss->string == STR_2806)
+ DrawFrameRect(
+ x, y, x + w, bottom, ss->color,
+ (_display_opt & DO_TRANS_BUILDINGS) ? FR_TRANSPARENT : 0
+ );
+ }
+
+ SetDParam(0, ss->params[0]);
+ SetDParam(1, ss->params[1]);
+ /* if we didn't draw a rectangle, or if transparant building is on,
+ * draw the text in the color the rectangle would have */
+ if ((
+ (_display_opt & DO_TRANS_BUILDINGS) ||
+ (_display_opt & DO_TRANS_SIGNS && ss->string != STR_2806)
+ ) && ss->width != 0) {
+ /* Real colors need the IS_PALETTE_COLOR flag
+ * otherwise colors from _string_colormap are assumed. */
+ colour = _colour_gradient[ss->color][6] | IS_PALETTE_COLOR;
+ } else {
+ colour = 16;
+ }
+ DrawString(
+ ss->x >> zoom, (ss->y >> zoom) - (ss->width & 0x8000 ? 2 : 0),
+ ss->string, colour
+ );
+
+ ss = ss->next;
+ } while (ss != NULL);
+}
+
+void ViewportDoDraw(const ViewPort *vp, int left, int top, int right, int bottom)
+{
+ ViewportDrawer vd;
+ int mask;
+ int x;
+ int y;
+ DrawPixelInfo *old_dpi;
+
+ byte mem[VIEWPORT_DRAW_MEM];
+ ParentSpriteToDraw *parent_list[6144];
+
+ _cur_vd = &vd;
+
+ old_dpi = _cur_dpi;
+ _cur_dpi = &vd.dpi;
+
+ vd.dpi.zoom = vp->zoom;
+ mask = (-1) << vp->zoom;
+
+ vd.combine_sprites = 0;
+
+ vd.dpi.width = (right - left) & mask;
+ vd.dpi.height = (bottom - top) & mask;
+ vd.dpi.left = left & mask;
+ vd.dpi.top = top & mask;
+ vd.dpi.pitch = old_dpi->pitch;
+
+ x = ((vd.dpi.left - (vp->virtual_left&mask)) >> vp->zoom) + vp->left;
+ y = ((vd.dpi.top - (vp->virtual_top&mask)) >> vp->zoom) + vp->top;
+
+ vd.dpi.dst_ptr = old_dpi->dst_ptr + x - old_dpi->left + (y - old_dpi->top) * old_dpi->pitch;
+
+ vd.parent_list = parent_list;
+ vd.eof_parent_list = endof(parent_list);
+ vd.spritelist_mem = mem;
+ vd.eof_spritelist_mem = endof(mem) - sizeof(LARGEST_SPRITELIST_STRUCT);
+ vd.last_string = &vd.first_string;
+ vd.first_string = NULL;
+ vd.last_tile = &vd.first_tile;
+ vd.first_tile = NULL;
+
+ ViewportAddLandscape();
+#if !defined(NEW_ROTATION)
+ ViewportAddVehicles(&vd.dpi);
+ DrawTextEffects(&vd.dpi);
+
+ ViewportAddTownNames(&vd.dpi);
+ ViewportAddStationNames(&vd.dpi);
+ ViewportAddSigns(&vd.dpi);
+ ViewportAddWaypoints(&vd.dpi);
+#endif
+
+ // This assert should never happen (because the length of the parent_list
+ // is checked)
+ assert(vd.parent_list <= endof(parent_list));
+
+ if (vd.first_tile != NULL) ViewportDrawTileSprites(vd.first_tile);
+
+ /* null terminate parent sprite list */
+ *vd.parent_list = NULL;
+
+ ViewportSortParentSprites(parent_list);
+ ViewportDrawParentSprites(parent_list);
+
+ if (vd.first_string != NULL) ViewportDrawStrings(&vd.dpi, vd.first_string);
+
+ _cur_dpi = old_dpi;
+}
+
+// Make sure we don't draw a too big area at a time.
+// If we do, the sprite memory will overflow.
+static void ViewportDrawChk(const ViewPort *vp, int left, int top, int right, int bottom)
+{
+ if (((bottom - top) * (right - left) << vp->zoom) > 180000) {
+ if ((bottom - top) > (right - left)) {
+ int t = (top + bottom) >> 1;
+ ViewportDrawChk(vp, left, top, right, t);
+ ViewportDrawChk(vp, left, t, right, bottom);
+ } else {
+ int t = (left + right) >> 1;
+ ViewportDrawChk(vp, left, top, t, bottom);
+ ViewportDrawChk(vp, t, top, right, bottom);
+ }
+ } else {
+ ViewportDoDraw(vp,
+ ((left - vp->left) << vp->zoom) + vp->virtual_left,
+ ((top - vp->top) << vp->zoom) + vp->virtual_top,
+ ((right - vp->left) << vp->zoom) + vp->virtual_left,
+ ((bottom - vp->top) << vp->zoom) + vp->virtual_top
+ );
+ }
+}
+
+static inline void ViewportDraw(const ViewPort *vp, int left, int top, int right, int bottom)
+{
+ if (right <= vp->left || bottom <= vp->top) return;
+
+ if (left >= vp->left + vp->width) return;
+
+ if (left < vp->left) left = vp->left;
+ if (right > vp->left + vp->width) right = vp->left + vp->width;
+
+ if (top >= vp->top + vp->height) return;
+
+ if (top < vp->top) top = vp->top;
+ if (bottom > vp->top + vp->height) bottom = vp->top + vp->height;
+
+ ViewportDrawChk(vp, left, top, right, bottom);
+}
+
+void DrawWindowViewport(const Window *w)
+{
+ DrawPixelInfo *dpi = _cur_dpi;
+
+ dpi->left += w->left;
+ dpi->top += w->top;
+
+ ViewportDraw(w->viewport, dpi->left, dpi->top, dpi->left + dpi->width, dpi->top + dpi->height);
+
+ dpi->left -= w->left;
+ dpi->top -= w->top;
+}
+
+void UpdateViewportPosition(Window *w)
+{
+ const ViewPort *vp = w->viewport;
+
+ if (WP(w, vp_d).follow_vehicle != INVALID_VEHICLE) {
+ const Vehicle* veh = GetVehicle(WP(w,vp_d).follow_vehicle);
+ Point pt = MapXYZToViewport(vp, veh->x_pos, veh->y_pos, veh->z_pos);
+
+ SetViewportPosition(w, pt.x, pt.y);
+ } else {
+#if !defined(NEW_ROTATION)
+ int x;
+ int y;
+ int vx;
+ int vy;
+
+ // Center of the viewport is hot spot
+ x = WP(w,vp_d).scrollpos_x + vp->virtual_width / 2;
+ y = WP(w,vp_d).scrollpos_y + vp->virtual_height / 2;
+ // Convert viewport coordinates to map coordinates
+ // Calculation is scaled by 4 to avoid rounding errors
+ vx = -x + y * 2;
+ vy = x + y * 2;
+ // clamp to size of map
+ vx = clamp(vx, 0 * 4, MapMaxX() * TILE_SIZE * 4);
+ vy = clamp(vy, 0 * 4, MapMaxY() * TILE_SIZE * 4);
+ // Convert map coordinates to viewport coordinates
+ x = (-vx + vy) / 2;
+ y = ( vx + vy) / 4;
+ // Set position
+ WP(w, vp_d).scrollpos_x = x - vp->virtual_width / 2;
+ WP(w, vp_d).scrollpos_y = y - vp->virtual_height / 2;
+#else
+ int x,y,t;
+ int err;
+
+ x = WP(w,vp_d).scrollpos_x >> 2;
+ y = WP(w,vp_d).scrollpos_y >> 1;
+
+ t = x;
+ x = x + y;
+ y = x - y;
+ err= 0;
+
+ if (err != 0) {
+ /* coordinate remap */
+ Point pt = RemapCoords(x, y, 0);
+ t = (-1) << vp->zoom;
+ WP(w,vp_d).scrollpos_x = pt.x & t;
+ WP(w,vp_d).scrollpos_y = pt.y & t;
+ }
+#endif
+
+ SetViewportPosition(w, WP(w, vp_d).scrollpos_x, WP(w, vp_d).scrollpos_y);
+ }
+}
+
+static void MarkViewportDirty(const ViewPort *vp, int left, int top, int right, int bottom)
+{
+ right -= vp->virtual_left;
+ if (right <= 0) return;
+
+ bottom -= vp->virtual_top;
+ if (bottom <= 0) return;
+
+ left = max(0, left - vp->virtual_left);
+
+ if (left >= vp->virtual_width) return;
+
+ top = max(0, top - vp->virtual_top);
+
+ if (top >= vp->virtual_height) return;
+
+ SetDirtyBlocks(
+ (left >> vp->zoom) + vp->left,
+ (top >> vp->zoom) + vp->top,
+ (right >> vp->zoom) + vp->left,
+ (bottom >> vp->zoom) + vp->top
+ );
+}
+
+void MarkAllViewportsDirty(int left, int top, int right, int bottom)
+{
+ const ViewPort *vp = _viewports;
+ uint32 act = _active_viewports;
+ do {
+ if (act & 1) {
+ assert(vp->width != 0);
+ MarkViewportDirty(vp, left, top, right, bottom);
+ }
+ } while (vp++,act>>=1);
+}
+
+void MarkTileDirtyByTile(TileIndex tile)
+{
+ Point pt = RemapCoords(TileX(tile) * TILE_SIZE, TileY(tile) * TILE_SIZE, GetTileZ(tile));
+ MarkAllViewportsDirty(
+ pt.x - 31,
+ pt.y - 122,
+ pt.x - 31 + 67,
+ pt.y - 122 + 154
+ );
+}
+
+void MarkTileDirty(int x, int y)
+{
+ uint z = 0;
+ Point pt;
+
+ if (IS_INT_INSIDE(x, 0, MapSizeX() * TILE_SIZE) &&
+ IS_INT_INSIDE(y, 0, MapSizeY() * TILE_SIZE))
+ z = GetTileZ(TileVirtXY(x, y));
+ pt = RemapCoords(x, y, z);
+
+ MarkAllViewportsDirty(
+ pt.x - 31,
+ pt.y - 122,
+ pt.x - 31 + 67,
+ pt.y - 122 + 154
+ );
+}
+
+static void SetSelectionTilesDirty(void)
+{
+ int y_size, x_size;
+ int x = _thd.pos.x;
+ int y = _thd.pos.y;
+
+ x_size = _thd.size.x;
+ y_size = _thd.size.y;
+
+ if (_thd.outersize.x) {
+ x_size += _thd.outersize.x;
+ x += _thd.offs.x;
+ y_size += _thd.outersize.y;
+ y += _thd.offs.y;
+ }
+
+ assert(x_size > 0);
+ assert(y_size > 0);
+
+ x_size += x;
+ y_size += y;
+
+ do {
+ int y_bk = y;
+ do {
+ MarkTileDirty(x, y);
+ } while ( (y += TILE_SIZE) != y_size);
+ y = y_bk;
+ } while ( (x += TILE_SIZE) != x_size);
+}
+
+
+void SetSelectionRed(bool b)
+{
+ _thd.make_square_red = b;
+ SetSelectionTilesDirty();
+}
+
+
+static bool CheckClickOnTown(const ViewPort *vp, int x, int y)
+{
+ const Town *t;
+
+ if (!(_display_opt & DO_SHOW_TOWN_NAMES)) return false;
+
+ switch (vp->zoom) {
+ case 0:
+ x = x - vp->left + vp->virtual_left;
+ y = y - vp->top + vp->virtual_top;
+ FOR_ALL_TOWNS(t) {
+ if (y >= t->sign.top &&
+ y < t->sign.top + 12 &&
+ x >= t->sign.left &&
+ x < t->sign.left + t->sign.width_1) {
+ ShowTownViewWindow(t->index);
+ return true;
+ }
+ }
+ break;
+
+ case 1:
+ x = (x - vp->left + 1) * 2 + vp->virtual_left;
+ y = (y - vp->top + 1) * 2 + vp->virtual_top;
+ FOR_ALL_TOWNS(t) {
+ if (y >= t->sign.top &&
+ y < t->sign.top + 24 &&
+ x >= t->sign.left &&
+ x < t->sign.left + t->sign.width_1 * 2) {
+ ShowTownViewWindow(t->index);
+ return true;
+ }
+ }
+ break;
+
+ default:
+ x = (x - vp->left + 3) * 4 + vp->virtual_left;
+ y = (y - vp->top + 3) * 4 + vp->virtual_top;
+ FOR_ALL_TOWNS(t) {
+ if (y >= t->sign.top &&
+ y < t->sign.top + 24 &&
+ x >= t->sign.left &&
+ x < t->sign.left + t->sign.width_2 * 4) {
+ ShowTownViewWindow(t->index);
+ return true;
+ }
+ }
+ break;
+ }
+
+ return false;
+}
+
+
+static bool CheckClickOnStation(const ViewPort *vp, int x, int y)
+{
+ const Station *st;
+
+ if (!(_display_opt & DO_SHOW_STATION_NAMES)) return false;
+
+ switch (vp->zoom) {
+ case 0:
+ x = x - vp->left + vp->virtual_left;
+ y = y - vp->top + vp->virtual_top;
+ FOR_ALL_STATIONS(st) {
+ if (y >= st->sign.top &&
+ y < st->sign.top + 12 &&
+ x >= st->sign.left &&
+ x < st->sign.left + st->sign.width_1) {
+ ShowStationViewWindow(st->index);
+ return true;
+ }
+ }
+ break;
+
+ case 1:
+ x = (x - vp->left + 1) * 2 + vp->virtual_left;
+ y = (y - vp->top + 1) * 2 + vp->virtual_top;
+ FOR_ALL_STATIONS(st) {
+ if (y >= st->sign.top &&
+ y < st->sign.top + 24 &&
+ x >= st->sign.left &&
+ x < st->sign.left + st->sign.width_1 * 2) {
+ ShowStationViewWindow(st->index);
+ return true;
+ }
+ }
+ break;
+
+ default:
+ x = (x - vp->left + 3) * 4 + vp->virtual_left;
+ y = (y - vp->top + 3) * 4 + vp->virtual_top;
+ FOR_ALL_STATIONS(st) {
+ if (y >= st->sign.top &&
+ y < st->sign.top + 24 &&
+ x >= st->sign.left &&
+ x < st->sign.left + st->sign.width_2 * 4) {
+ ShowStationViewWindow(st->index);
+ return true;
+ }
+ }
+ break;
+ }
+
+ return false;
+}
+
+
+static bool CheckClickOnSign(const ViewPort *vp, int x, int y)
+{
+ const Sign *si;
+
+ if (!(_display_opt & DO_SHOW_SIGNS)) return false;
+
+ switch (vp->zoom) {
+ case 0:
+ x = x - vp->left + vp->virtual_left;
+ y = y - vp->top + vp->virtual_top;
+ FOR_ALL_SIGNS(si) {
+ if (y >= si->sign.top &&
+ y < si->sign.top + 12 &&
+ x >= si->sign.left &&
+ x < si->sign.left + si->sign.width_1) {
+ ShowRenameSignWindow(si);
+ return true;
+ }
+ }
+ break;
+
+ case 1:
+ x = (x - vp->left + 1) * 2 + vp->virtual_left;
+ y = (y - vp->top + 1) * 2 + vp->virtual_top;
+ FOR_ALL_SIGNS(si) {
+ if (y >= si->sign.top &&
+ y < si->sign.top + 24 &&
+ x >= si->sign.left &&
+ x < si->sign.left + si->sign.width_1 * 2) {
+ ShowRenameSignWindow(si);
+ return true;
+ }
+ }
+ break;
+
+ default:
+ x = (x - vp->left + 3) * 4 + vp->virtual_left;
+ y = (y - vp->top + 3) * 4 + vp->virtual_top;
+ FOR_ALL_SIGNS(si) {
+ if (y >= si->sign.top &&
+ y < si->sign.top + 24 &&
+ x >= si->sign.left &&
+ x < si->sign.left + si->sign.width_2 * 4) {
+ ShowRenameSignWindow(si);
+ return true;
+ }
+ }
+ break;
+ }
+
+ return false;
+}
+
+
+static bool CheckClickOnWaypoint(const ViewPort *vp, int x, int y)
+{
+ const Waypoint *wp;
+
+ if (!(_display_opt & DO_WAYPOINTS)) return false;
+
+ switch (vp->zoom) {
+ case 0:
+ x = x - vp->left + vp->virtual_left;
+ y = y - vp->top + vp->virtual_top;
+ FOR_ALL_WAYPOINTS(wp) {
+ if (y >= wp->sign.top &&
+ y < wp->sign.top + 12 &&
+ x >= wp->sign.left &&
+ x < wp->sign.left + wp->sign.width_1) {
+ ShowRenameWaypointWindow(wp);
+ return true;
+ }
+ }
+ break;
+
+ case 1:
+ x = (x - vp->left + 1) * 2 + vp->virtual_left;
+ y = (y - vp->top + 1) * 2 + vp->virtual_top;
+ FOR_ALL_WAYPOINTS(wp) {
+ if (y >= wp->sign.top &&
+ y < wp->sign.top + 24 &&
+ x >= wp->sign.left &&
+ x < wp->sign.left + wp->sign.width_1 * 2) {
+ ShowRenameWaypointWindow(wp);
+ return true;
+ }
+ }
+ break;
+
+ default:
+ x = (x - vp->left + 3) * 4 + vp->virtual_left;
+ y = (y - vp->top + 3) * 4 + vp->virtual_top;
+ FOR_ALL_WAYPOINTS(wp) {
+ if (y >= wp->sign.top &&
+ y < wp->sign.top + 24 &&
+ x >= wp->sign.left &&
+ x < wp->sign.left + wp->sign.width_2 * 4) {
+ ShowRenameWaypointWindow(wp);
+ return true;
+ }
+ }
+ break;
+ }
+
+ return false;
+}
+
+
+static void CheckClickOnLandscape(const ViewPort *vp, int x, int y)
+{
+ Point pt = TranslateXYToTileCoord(vp, x, y);
+
+ if (pt.x != -1) ClickTile(TileVirtXY(pt.x, pt.y));
+}
+
+
+static void SafeShowTrainViewWindow(const Vehicle* v)
+{
+ if (!IsFrontEngine(v)) v = GetFirstVehicleInChain(v);
+ ShowTrainViewWindow(v);
+}
+
+static void Nop(const Vehicle *v) {}
+
+typedef void OnVehicleClickProc(const Vehicle *v);
+static OnVehicleClickProc* const _on_vehicle_click_proc[] = {
+ SafeShowTrainViewWindow,
+ ShowRoadVehViewWindow,
+ ShowShipViewWindow,
+ ShowAircraftViewWindow,
+ Nop, // Special vehicles
+ Nop // Disaster vehicles
+};
+
+void HandleViewportClicked(const ViewPort *vp, int x, int y)
+{
+ const Vehicle *v;
+
+ if (CheckClickOnTown(vp, x, y)) return;
+ if (CheckClickOnStation(vp, x, y)) return;
+ if (CheckClickOnSign(vp, x, y)) return;
+ if (CheckClickOnWaypoint(vp, x, y)) return;
+ CheckClickOnLandscape(vp, x, y);
+
+ v = CheckClickOnVehicle(vp, x, y);
+ if (v != NULL) {
+ DEBUG(misc, 2, "Vehicle %d (index %d) at %p", v->unitnumber, v->index, v);
+ _on_vehicle_click_proc[v->type - 0x10](v);
+ }
+}
+
+Vehicle *CheckMouseOverVehicle(void)
+{
+ const Window *w;
+ const ViewPort *vp;
+
+ int x = _cursor.pos.x;
+ int y = _cursor.pos.y;
+
+ w = FindWindowFromPt(x, y);
+ if (w == NULL) return NULL;
+
+ vp = IsPtInWindowViewport(w, x, y);
+ return (vp != NULL) ? CheckClickOnVehicle(vp, x, y) : NULL;
+}
+
+
+
+void PlaceObject(void)
+{
+ Point pt;
+ Window *w;
+
+ pt = GetTileBelowCursor();
+ if (pt.x == -1) return;
+
+ if (_thd.place_mode == VHM_POINT) {
+ pt.x += 8;
+ pt.y += 8;
+ }
+
+ _tile_fract_coords.x = pt.x & 0xF;
+ _tile_fract_coords.y = pt.y & 0xF;
+
+ w = GetCallbackWnd();
+ if (w != NULL) {
+ WindowEvent e;
+
+ e.event = WE_PLACE_OBJ;
+ e.we.place.pt = pt;
+ e.we.place.tile = TileVirtXY(pt.x, pt.y);
+ w->wndproc(w, &e);
+ }
+}
+
+
+/* scrolls the viewport in a window to a given location */
+bool ScrollWindowTo(int x , int y, Window *w)
+{
+ Point pt;
+
+ pt = MapXYZToViewport(w->viewport, x, y, GetSlopeZ(x, y));
+ WP(w, vp_d).follow_vehicle = INVALID_VEHICLE;
+
+ if (WP(w, vp_d).scrollpos_x == pt.x && WP(w, vp_d).scrollpos_y == pt.y)
+ return false;
+
+ WP(w, vp_d).scrollpos_x = pt.x;
+ WP(w, vp_d).scrollpos_y = pt.y;
+ return true;
+}
+
+
+bool ScrollMainWindowTo(int x, int y)
+{
+ Window *w;
+ bool res = ScrollWindowTo(x, y, FindWindowById(WC_MAIN_WINDOW, 0));
+
+ /* If a user scrolls to a tile (via what way what so ever) and already is on
+ * that tile (e.g.: pressed twice), move the smallmap to that location,
+ * so you directly see where you are on the smallmap. */
+
+ if (res) return res;
+
+ w = FindWindowById(WC_SMALLMAP, 0);
+ if (w == NULL) return res;
+
+ SmallMapCenterOnCurrentPos(w);
+
+ return res;
+}
+
+
+bool ScrollMainWindowToTile(TileIndex tile)
+{
+ return ScrollMainWindowTo(TileX(tile) * TILE_SIZE + TILE_SIZE / 2, TileY(tile) * TILE_SIZE + TILE_SIZE / 2);
+}
+
+void SetRedErrorSquare(TileIndex tile)
+{
+ TileIndex old;
+
+ old = _thd.redsq;
+ _thd.redsq = tile;
+
+ if (tile != old) {
+ if (tile != 0) MarkTileDirtyByTile(tile);
+ if (old != 0) MarkTileDirtyByTile(old);
+ }
+}
+
+void SetTileSelectSize(int w, int h)
+{
+ _thd.new_size.x = w * TILE_SIZE;
+ _thd.new_size.y = h * TILE_SIZE;
+ _thd.new_outersize.x = 0;
+ _thd.new_outersize.y = 0;
+}
+
+void SetTileSelectBigSize(int ox, int oy, int sx, int sy)
+{
+ _thd.offs.x = ox * TILE_SIZE;
+ _thd.offs.y = oy * TILE_SIZE;
+ _thd.new_outersize.x = sx * TILE_SIZE;
+ _thd.new_outersize.y = sy * TILE_SIZE;
+}
+
+/* returns the best autorail highlight type from map coordinates */
+static byte GetAutorailHT(int x, int y)
+{
+ return HT_RAIL | _AutorailPiece[x & 0xF][y & 0xF];
+}
+
+// called regular to update tile highlighting in all cases
+void UpdateTileSelection(void)
+{
+ int x1;
+ int y1;
+
+ _thd.new_drawstyle = 0;
+
+ if (_thd.place_mode == VHM_SPECIAL) {
+ x1 = _thd.selend.x;
+ y1 = _thd.selend.y;
+ if (x1 != -1) {
+ int x2 = _thd.selstart.x;
+ int y2 = _thd.selstart.y;
+ x1 &= ~0xF;
+ y1 &= ~0xF;
+
+ if (x1 >= x2) intswap(x1,x2);
+ if (y1 >= y2) intswap(y1,y2);
+ _thd.new_pos.x = x1;
+ _thd.new_pos.y = y1;
+ _thd.new_size.x = x2 - x1 + TILE_SIZE;
+ _thd.new_size.y = y2 - y1 + TILE_SIZE;
+ _thd.new_drawstyle = _thd.next_drawstyle;
+ }
+ } else if (_thd.place_mode != VHM_NONE) {
+ Point pt = GetTileBelowCursor();
+ x1 = pt.x;
+ y1 = pt.y;
+ if (x1 != -1) {
+ switch (_thd.place_mode) {
+ case VHM_RECT:
+ _thd.new_drawstyle = HT_RECT;
+ break;
+ case VHM_POINT:
+ _thd.new_drawstyle = HT_POINT;
+ x1 += 8;
+ y1 += 8;
+ break;
+ case VHM_RAIL:
+ _thd.new_drawstyle = GetAutorailHT(pt.x, pt.y); // draw one highlighted tile
+ }
+ _thd.new_pos.x = x1 & ~0xF;
+ _thd.new_pos.y = y1 & ~0xF;
+ }
+ }
+
+ // redraw selection
+ if (_thd.drawstyle != _thd.new_drawstyle ||
+ _thd.pos.x != _thd.new_pos.x || _thd.pos.y != _thd.new_pos.y ||
+ _thd.size.x != _thd.new_size.x || _thd.size.y != _thd.new_size.y ||
+ _thd.outersize.x != _thd.new_outersize.x ||
+ _thd.outersize.y != _thd.new_outersize.y) {
+ // clear the old selection?
+ if (_thd.drawstyle) SetSelectionTilesDirty();
+
+ _thd.drawstyle = _thd.new_drawstyle;
+ _thd.pos = _thd.new_pos;
+ _thd.size = _thd.new_size;
+ _thd.outersize = _thd.new_outersize;
+ _thd.dirty = 0xff;
+
+ // draw the new selection?
+ if (_thd.new_drawstyle) SetSelectionTilesDirty();
+ }
+}
+
+// highlighting tiles while only going over them with the mouse
+void VpStartPlaceSizing(TileIndex tile, int user)
+{
+ _thd.userdata = user;
+ _thd.selend.x = TileX(tile) * TILE_SIZE;
+ _thd.selstart.x = TileX(tile) * TILE_SIZE;
+ _thd.selend.y = TileY(tile) * TILE_SIZE;
+ _thd.selstart.y = TileY(tile) * TILE_SIZE;
+ if (_thd.place_mode == VHM_RECT) {
+ _thd.place_mode = VHM_SPECIAL;
+ _thd.next_drawstyle = HT_RECT;
+ } else if (_thd.place_mode == VHM_RAIL) { // autorail one piece
+ _thd.place_mode = VHM_SPECIAL;
+ _thd.next_drawstyle = _thd.drawstyle;
+ } else {
+ _thd.place_mode = VHM_SPECIAL;
+ _thd.next_drawstyle = HT_POINT;
+ }
+ _special_mouse_mode = WSM_SIZING;
+}
+
+void VpSetPlaceSizingLimit(int limit)
+{
+ _thd.sizelimit = limit;
+}
+
+/**
+* Highlights all tiles between a set of two tiles. Used in dock and tunnel placement
+* @param from TileIndex of the first tile to highlight
+* @param to TileIndex of the last tile to highlight */
+void VpSetPresizeRange(TileIndex from, TileIndex to)
+{
+ uint distance = DistanceManhattan(from, to) + 1;
+
+ _thd.selend.x = TileX(to) * TILE_SIZE;
+ _thd.selend.y = TileY(to) * TILE_SIZE;
+ _thd.selstart.x = TileX(from) * TILE_SIZE;
+ _thd.selstart.y = TileY(from) * TILE_SIZE;
+ _thd.next_drawstyle = HT_RECT;
+
+ /* show measurement only if there is any length to speak of */
+ if (distance > 1) GuiShowTooltipsWithArgs(STR_MEASURE_LENGTH, 1, &distance);
+}
+
+static void VpStartPreSizing(void)
+{
+ _thd.selend.x = -1;
+ _special_mouse_mode = WSM_PRESIZE;
+}
+
+/* returns information about the 2x1 piece to be build.
+ * The lower bits (0-3) are the track type. */
+static byte Check2x1AutoRail(int mode)
+{
+ int fxpy = _tile_fract_coords.x + _tile_fract_coords.y;
+ int sxpy = (_thd.selend.x & 0xF) + (_thd.selend.y & 0xF);
+ int fxmy = _tile_fract_coords.x - _tile_fract_coords.y;
+ int sxmy = (_thd.selend.x & 0xF) - (_thd.selend.y & 0xF);
+
+ switch (mode) {
+ case 0: // end piece is lower right
+ if (fxpy >= 20 && sxpy <= 12) { /*SwapSelection(); DoRailroadTrack(0); */return 3; }
+ if (fxmy < -3 && sxmy > 3) {/* DoRailroadTrack(0); */return 5; }
+ return 1;
+
+ case 1:
+ if (fxmy > 3 && sxmy < -3) { /*SwapSelection(); DoRailroadTrack(0); */return 4; }
+ if (fxpy <= 12 && sxpy >= 20) { /*DoRailroadTrack(0); */return 2; }
+ return 1;
+
+ case 2:
+ if (fxmy > 3 && sxmy < -3) { /*DoRailroadTrack(3);*/ return 4; }
+ if (fxpy >= 20 && sxpy <= 12) { /*SwapSelection(); DoRailroadTrack(0); */return 3; }
+ return 0;
+
+ case 3:
+ if (fxmy < -3 && sxmy > 3) { /*SwapSelection(); DoRailroadTrack(3);*/ return 5; }
+ if (fxpy <= 12 && sxpy >= 20) { /*DoRailroadTrack(0); */return 2; }
+ return 0;
+ }
+
+ return 0; // avoids compiler warnings
+}
+
+/** Check if the direction of start and end tile should be swapped based on
+ * the dragging-style. Default directions are:
+ * in the case of a line (HT_RAIL, HT_LINE): DIR_NE, DIR_NW, DIR_N, DIR_E
+ * in the case of a rect (HT_RECT, HT_POINT): DIR_S, DIR_E
+ * For example dragging a rectangle area from south to north should be swapped to
+ * north-south (DIR_S) to obtain the same results with less code. This is what
+ * the return value signifies.
+ * @param style HighLightStyle dragging style
+ * @param start_tile, end_tile start and end tile of drag
+ * @param boolean value which when true means start/end should be swapped */
+static bool SwapDirection(HighLightStyle style, TileIndex start_tile, TileIndex end_tile)
+{
+ uint start_x = TileX(start_tile);
+ uint start_y = TileY(start_tile);
+ uint end_x = TileX(end_tile);
+ uint end_y = TileY(end_tile);
+
+ switch (style & HT_DRAG_MASK) {
+ case HT_RAIL:
+ case HT_LINE: return (end_x > start_x || (end_x == start_x && end_y > start_y));
+
+ case HT_RECT:
+ case HT_POINT: return (end_x != start_x && end_y < start_y);
+ default: NOT_REACHED();
+ }
+
+ return false;
+}
+
+/** Calculates height difference between one tile and another
+* Multiplies the result to suit the standard given by minimap - 50 meters high
+* To correctly get the height difference we need the direction we are dragging
+* in, as well as with what kind of tool we are dragging. For example a horizontal
+* autorail tool that starts in bottom and ends at the top of a tile will need the
+* maximum of SW,S and SE,N corners respectively. This is handled by the lookup table below
+* See _tileoffs_by_dir in map.c for the direction enums if you can't figure out
+* the values yourself.
+* @param style HightlightStyle of drag. This includes direction and style (autorail, rect, etc.)
+* @param distance amount of tiles dragged, important for horizontal/vertical drags
+* ignored for others
+* @param start_tile, end_tile start and end tile of drag operation
+* @return height difference between two tiles. Tile measurement tool utilizes
+* this value in its tooltips */
+static int CalcHeightdiff(HighLightStyle style, uint distance, TileIndex start_tile, TileIndex end_tile)
+{
+ bool swap = SwapDirection(style, start_tile, end_tile);
+ byte style_t;
+ uint h0, h1, ht; // start heigth, end height, and temp variable
+
+ if (start_tile == end_tile) return 0;
+ if (swap) swap_tile(&start_tile, &end_tile);
+
+ switch (style & HT_DRAG_MASK) {
+ case HT_RECT: {
+ static const TileIndexDiffC heightdiff_area_by_dir[] = {
+ /* Start */ {1, 0}, /* Dragging east */ {0, 0}, /* Dragging south */
+ /* End */ {0, 1}, /* Dragging east */ {1, 1} /* Dragging south */
+ };
+
+ /* In the case of an area we can determine whether we were dragging south or
+ * east by checking the X-coordinates of the tiles */
+ style_t = (byte)(TileX(end_tile) > TileX(start_tile));
+ start_tile = TILE_ADD(start_tile, ToTileIndexDiff(heightdiff_area_by_dir[style_t]));
+ end_tile = TILE_ADD(end_tile, ToTileIndexDiff(heightdiff_area_by_dir[2 + style_t]));
+ }
+ /* Fallthrough */
+ case HT_POINT:
+ h0 = TileHeight(start_tile);
+ h1 = TileHeight(end_tile);
+ break;
+ default: { /* All other types, this is mostly only line/autorail */
+ static const HighLightStyle flip_style_direction[] = {
+ HT_DIR_X, HT_DIR_Y, HT_DIR_HL, HT_DIR_HU, HT_DIR_VR, HT_DIR_VL
+ };
+ static const TileIndexDiffC heightdiff_line_by_dir[] = {
+ /* Start */ {1, 0}, {1, 1}, /* HT_DIR_X */ {0, 1}, {1, 1}, /* HT_DIR_Y */
+ /* Start */ {1, 0}, {0, 0}, /* HT_DIR_HU */ {1, 0}, {1, 1}, /* HT_DIR_HL */
+ /* Start */ {1, 0}, {1, 1}, /* HT_DIR_VL */ {0, 1}, {1, 1}, /* HT_DIR_VR */
+
+ /* Start */ {0, 1}, {0, 0}, /* HT_DIR_X */ {1, 0}, {0, 0}, /* HT_DIR_Y */
+ /* End */ {0, 1}, {0, 0}, /* HT_DIR_HU */ {1, 1}, {0, 1}, /* HT_DIR_HL */
+ /* End */ {1, 0}, {0, 0}, /* HT_DIR_VL */ {0, 0}, {0, 1}, /* HT_DIR_VR */
+ };
+
+ distance %= 2; // we're only interested if the distance is even or uneven
+ style &= HT_DIR_MASK;
+
+ /* To handle autorail, we do some magic to be able to use a lookup table.
+ * Firstly if we drag the other way around, we switch start&end, and if needed
+ * also flip the drag-position. Eg if it was on the left, and the distance is even
+ * that means the end, which is now the start is on the right */
+ if (swap && distance == 0) style = flip_style_direction[style];
+
+ /* Use lookup table for start-tile based on HighLightStyle direction */
+ style_t = style * 2;
+ assert(style_t < lengthof(heightdiff_line_by_dir) - 13);
+ h0 = TileHeight(TILE_ADD(start_tile, ToTileIndexDiff(heightdiff_line_by_dir[style_t])));
+ ht = TileHeight(TILE_ADD(start_tile, ToTileIndexDiff(heightdiff_line_by_dir[style_t + 1])));
+ h0 = maxu(h0, ht);
+
+ /* Use lookup table for end-tile based on HighLightStyle direction
+ * flip around side (lower/upper, left/right) based on distance */
+ if (distance == 0) style_t = flip_style_direction[style] * 2;
+ assert(style_t < lengthof(heightdiff_line_by_dir) - 13);
+ h1 = TileHeight(TILE_ADD(end_tile, ToTileIndexDiff(heightdiff_line_by_dir[12 + style_t])));
+ ht = TileHeight(TILE_ADD(end_tile, ToTileIndexDiff(heightdiff_line_by_dir[12 + style_t + 1])));
+ h1 = maxu(h1, ht);
+ } break;
+ }
+
+ if (swap) swap_uint32(&h0, &h1);
+ /* Minimap shows height in intervals of 50 meters, let's do the same */
+ return (int)(h1 - h0) * 50;
+}
+
+static const StringID measure_strings_length[] = {STR_NULL, STR_MEASURE_LENGTH, STR_MEASURE_LENGTH_HEIGHTDIFF};
+
+// while dragging
+static void CalcRaildirsDrawstyle(TileHighlightData *thd, int x, int y, int method)
+{
+ HighLightStyle b;
+ uint w, h;
+
+ int dx = thd->selstart.x - (thd->selend.x & ~0xF);
+ int dy = thd->selstart.y - (thd->selend.y & ~0xF);
+ w = myabs(dx) + 16;
+ h = myabs(dy) + 16;
+
+ if (TileVirtXY(thd->selstart.x, thd->selstart.y) == TileVirtXY(x, y)) { // check if we're only within one tile
+ if (method == VPM_RAILDIRS) {
+ b = GetAutorailHT(x, y);
+ } else { // rect for autosignals on one tile
+ b = HT_RECT;
+ }
+ } else if (h == 16) { // Is this in X direction?
+ if (dx == 16) { // 2x1 special handling
+ b = (Check2x1AutoRail(3)) | HT_LINE;
+ } else if (dx == -16) {
+ b = (Check2x1AutoRail(2)) | HT_LINE;
+ } else {
+ b = HT_LINE | HT_DIR_X;
+ }
+ y = thd->selstart.y;
+ } else if (w == 16) { // Or Y direction?
+ if (dy == 16) { // 2x1 special handling
+ b = (Check2x1AutoRail(1)) | HT_LINE;
+ } else if (dy == -16) { // 2x1 other direction
+ b = (Check2x1AutoRail(0)) | HT_LINE;
+ } else {
+ b = HT_LINE | HT_DIR_Y;
+ }
+ x = thd->selstart.x;
+ } else if (w > h * 2) { // still count as x dir?
+ b = HT_LINE | HT_DIR_X;
+ y = thd->selstart.y;
+ } else if (h > w * 2) { // still count as y dir?
+ b = HT_LINE | HT_DIR_Y;
+ x = thd->selstart.x;
+ } else { // complicated direction
+ int d = w - h;
+ thd->selend.x = thd->selend.x & ~0xF;
+ thd->selend.y = thd->selend.y & ~0xF;
+
+ // four cases.
+ if (x > thd->selstart.x) {
+ if (y > thd->selstart.y) {
+ // south
+ if (d == 0) {
+ b = (x & 0xF) > (y & 0xF) ? HT_LINE | HT_DIR_VL : HT_LINE | HT_DIR_VR;
+ } else if (d >= 0) {
+ x = thd->selstart.x + h;
+ b = HT_LINE | HT_DIR_VL;
+ // return px == py || px == py + 16;
+ } else {
+ y = thd->selstart.y + w;
+ b = HT_LINE | HT_DIR_VR;
+ } // return px == py || px == py - 16;
+ } else {
+ // west
+ if (d == 0) {
+ b = (x & 0xF) + (y & 0xF) >= 0x10 ? HT_LINE | HT_DIR_HL : HT_LINE | HT_DIR_HU;
+ } else if (d >= 0) {
+ x = thd->selstart.x + h;
+ b = HT_LINE | HT_DIR_HL;
+ } else {
+ y = thd->selstart.y - w;
+ b = HT_LINE | HT_DIR_HU;
+ }
+ }
+ } else {
+ if (y > thd->selstart.y) {
+ // east
+ if (d == 0) {
+ b = (x & 0xF) + (y & 0xF) >= 0x10 ? HT_LINE | HT_DIR_HL : HT_LINE | HT_DIR_HU;
+ } else if (d >= 0) {
+ x = thd->selstart.x - h;
+ b = HT_LINE | HT_DIR_HU;
+ // return px == -py || px == -py - 16;
+ } else {
+ y = thd->selstart.y + w;
+ b = HT_LINE | HT_DIR_HL;
+ } // return px == -py || px == -py + 16;
+ } else {
+ // north
+ if (d == 0) {
+ b = (x & 0xF) > (y & 0xF) ? HT_LINE | HT_DIR_VL : HT_LINE | HT_DIR_VR;
+ } else if (d >= 0) {
+ x = thd->selstart.x - h;
+ b = HT_LINE | HT_DIR_VR;
+ // return px == py || px == py - 16;
+ } else {
+ y = thd->selstart.y - w;
+ b = HT_LINE | HT_DIR_VL;
+ } //return px == py || px == py + 16;
+ }
+ }
+ }
+
+ if (_patches.measure_tooltip) {
+ TileIndex t0 = TileVirtXY(thd->selstart.x, thd->selstart.y);
+ TileIndex t1 = TileVirtXY(x, y);
+ uint distance = DistanceManhattan(t0, t1) + 1;
+ byte index = 0;
+ uint params[2];
+
+ if (distance != 1) {
+ int heightdiff = CalcHeightdiff(b, distance, t0, t1);
+ /* If we are showing a tooltip for horizontal or vertical drags,
+ * 2 tiles have a length of 1. To bias towards the ceiling we add
+ * one before division. It feels more natural to count 3 lengths as 2 */
+ if ((b & HT_DIR_MASK) != HT_DIR_X && (b & HT_DIR_MASK) != HT_DIR_Y) {
+ distance = (distance + 1) / 2;
+ }
+
+ params[index++] = distance;
+ if (heightdiff != 0) params[index++] = heightdiff;
+ }
+
+ GuiShowTooltipsWithArgs(measure_strings_length[index], index, params);
+ }
+
+ thd->selend.x = x;
+ thd->selend.y = y;
+ thd->next_drawstyle = b;
+}
+
+/**
+ * Selects tiles while dragging
+ * @param x X coordinate of end of selection
+ * @param y Y coordinate of end of selection
+ * @param method modifies the way tiles are selected. Possible
+ * methods are VPM_* in viewport.h */
+void VpSelectTilesWithMethod(int x, int y, int method)
+{
+ int sx, sy;
+ HighLightStyle style;
+
+ if (x == -1) {
+ _thd.selend.x = -1;
+ return;
+ }
+
+ /* Special handling of drag in any (8-way) direction */
+ if (method == VPM_RAILDIRS || method == VPM_SIGNALDIRS) {
+ _thd.selend.x = x;
+ _thd.selend.y = y;
+ CalcRaildirsDrawstyle(&_thd, x, y, method);
+ return;
+ }
+
+ if (_thd.next_drawstyle == HT_POINT) {
+ x += TILE_SIZE / 2;
+ y += TILE_SIZE / 2;
+ }
+
+ sx = _thd.selstart.x;
+ sy = _thd.selstart.y;
+
+ switch (method) {
+ case VPM_X_OR_Y: /* drag in X or Y direction */
+ if (myabs(sy - y) < myabs(sx - x)) {
+ y = sy;
+ style = HT_DIR_X;
+ } else {
+ x = sx;
+ style = HT_DIR_Y;
+ }
+ goto calc_heightdiff_single_direction;
+ case VPM_FIX_X: /* drag in Y direction */
+ x = sx;
+ style = HT_DIR_Y;
+ goto calc_heightdiff_single_direction;
+ case VPM_FIX_Y: /* drag in X direction */
+ y = sy;
+ style = HT_DIR_X;
+
+calc_heightdiff_single_direction:;
+ if (_patches.measure_tooltip) {
+ TileIndex t0 = TileVirtXY(sx, sy);
+ TileIndex t1 = TileVirtXY(x, y);
+ uint distance = DistanceManhattan(t0, t1) + 1;
+ byte index = 0;
+ uint params[2];
+
+ if (distance != 1) {
+ /* With current code passing a HT_LINE style to calculate the height
+ * difference is enough. However if/when a point-tool is created
+ * with this method, function should be called with new_style (below)
+ * instead of HT_LINE | style case HT_POINT is handled specially
+ * new_style := (_thd.next_drawstyle & HT_RECT) ? HT_LINE | style : _thd.next_drawstyle; */
+ int heightdiff = CalcHeightdiff(HT_LINE | style, 0, t0, t1);
+
+ params[index++] = distance;
+ if (heightdiff != 0) params[index++] = heightdiff;
+ }
+
+ GuiShowTooltipsWithArgs(measure_strings_length[index], index, params);
+ } break;
+
+ case VPM_X_AND_Y_LIMITED: { /* drag an X by Y constrained rect area */
+ int limit = (_thd.sizelimit - 1) * TILE_SIZE;
+ x = sx + clamp(x - sx, -limit, limit);
+ y = sy + clamp(y - sy, -limit, limit);
+ /* Fallthrough */
+ case VPM_X_AND_Y: /* drag an X by Y area */
+ if (_patches.measure_tooltip) {
+ static const StringID measure_strings_area[] = {
+ STR_NULL, STR_NULL, STR_MEASURE_AREA, STR_MEASURE_AREA_HEIGHTDIFF
+ };
+
+ TileIndex t0 = TileVirtXY(sx, sy);
+ TileIndex t1 = TileVirtXY(x, y);
+ uint dx = abs(TileX(t0) - TileX(t1)) + 1;
+ uint dy = abs(TileY(t0) - TileY(t1)) + 1;
+ byte index = 0;
+ uint params[3];
+
+ /* If dragging an area (eg dynamite tool) and it is actually a single
+ * row/column, change the type to 'line' to get proper calculation for height */
+ style = _thd.next_drawstyle;
+ if (style & HT_RECT) {
+ if (dx == 1) {
+ style = HT_LINE | HT_DIR_Y;
+ } else if (dy == 1) {
+ style = HT_LINE | HT_DIR_X;
+ }
+ }
+
+ if (dx != 1 || dy != 1) {
+ int heightdiff = CalcHeightdiff(style, 0, t0, t1);
+
+ params[index++] = dx;
+ params[index++] = dy;
+ if (heightdiff != 0) params[index++] = heightdiff;
+ }
+
+ GuiShowTooltipsWithArgs(measure_strings_area[index], index, params);
+ }
+ break;
+
+ }
+ default: NOT_REACHED();
+ }
+
+ _thd.selend.x = x;
+ _thd.selend.y = y;
+}
+
+// while dragging
+bool VpHandlePlaceSizingDrag(void)
+{
+ Window *w;
+ WindowEvent e;
+
+ if (_special_mouse_mode != WSM_SIZING) return true;
+
+ e.we.place.userdata = _thd.userdata;
+
+ // stop drag mode if the window has been closed
+ w = FindWindowById(_thd.window_class,_thd.window_number);
+ if (w == NULL) {
+ ResetObjectToPlace();
+ return false;
+ }
+
+ // while dragging execute the drag procedure of the corresponding window (mostly VpSelectTilesWithMethod() )
+ if (_left_button_down) {
+ e.event = WE_PLACE_DRAG;
+ e.we.place.pt = GetTileBelowCursor();
+ w->wndproc(w, &e);
+ return false;
+ }
+
+ // mouse button released..
+ // keep the selected tool, but reset it to the original mode.
+ _special_mouse_mode = WSM_NONE;
+ if (_thd.next_drawstyle == HT_RECT) {
+ _thd.place_mode = VHM_RECT;
+ } else if ((e.we.place.userdata & 0xF) == VPM_SIGNALDIRS) { // some might call this a hack... -- Dominik
+ _thd.place_mode = VHM_RECT;
+ } else if (_thd.next_drawstyle & HT_LINE) {
+ _thd.place_mode = VHM_RAIL;
+ } else if (_thd.next_drawstyle & HT_RAIL) {
+ _thd.place_mode = VHM_RAIL;
+ } else {
+ _thd.place_mode = VHM_POINT;
+ }
+ SetTileSelectSize(1, 1);
+
+ // and call the mouseup event.
+ e.event = WE_PLACE_MOUSEUP;
+ e.we.place.pt = _thd.selend;
+ e.we.place.tile = TileVirtXY(e.we.place.pt.x, e.we.place.pt.y);
+ e.we.place.starttile = TileVirtXY(_thd.selstart.x, _thd.selstart.y);
+ w->wndproc(w, &e);
+
+ return false;
+}
+
+void SetObjectToPlaceWnd(CursorID icon, byte mode, Window *w)
+{
+ SetObjectToPlace(icon, mode, w->window_class, w->window_number);
+}
+
+#include "table/animcursors.h"
+
+void SetObjectToPlace(CursorID icon, byte mode, WindowClass window_class, WindowNumber window_num)
+{
+ Window *w;
+
+ // undo clicking on button
+ if (_thd.place_mode != 0) {
+ _thd.place_mode = 0;
+ w = FindWindowById(_thd.window_class, _thd.window_number);
+ if (w != NULL) CallWindowEventNP(w, WE_ABORT_PLACE_OBJ);
+ }
+
+ SetTileSelectSize(1, 1);
+
+ _thd.make_square_red = false;
+
+ if (mode == VHM_DRAG) { // mode 4 is for dragdropping trains in the depot window
+ mode = 0;
+ _special_mouse_mode = WSM_DRAGDROP;
+ } else {
+ _special_mouse_mode = WSM_NONE;
+ }
+
+ _thd.place_mode = mode;
+ _thd.window_class = window_class;
+ _thd.window_number = window_num;
+
+ if (mode == VHM_SPECIAL) // special tools, like tunnels or docks start with presizing mode
+ VpStartPreSizing();
+
+ if ( (int)icon < 0)
+ SetAnimatedMouseCursor(_animcursors[~icon]);
+ else
+ SetMouseCursor(icon);
+}
+
+void ResetObjectToPlace(void)
+{
+ SetObjectToPlace(SPR_CURSOR_MOUSE, VHM_NONE, 0, 0);
+}
diff --git a/src/viewport.h b/src/viewport.h
new file mode 100644
index 000000000..b9d1fce7e
--- /dev/null
+++ b/src/viewport.h
@@ -0,0 +1,151 @@
+/* $Id$ */
+
+#ifndef VIEWPORT_H
+#define VIEWPORT_H
+
+struct ViewPort {
+ int left,top; // screen coordinates for the viewport
+ int width, height; // screen width/height for the viewport
+
+ int virtual_left, virtual_top; // virtual coordinates
+ int virtual_width, virtual_height; // these are just width << zoom, height << zoom
+
+ byte zoom;
+};
+
+void SetSelectionRed(bool);
+
+/* viewport.c */
+void InitViewports(void);
+void DeleteWindowViewport(Window *w);
+void AssignWindowViewport(Window *w, int x, int y,
+ int width, int height, uint32 follow_flags, byte zoom);
+ViewPort *IsPtInWindowViewport(const Window *w, int x, int y);
+Point GetTileBelowCursor(void);
+void UpdateViewportPosition(Window *w);
+
+enum {
+ ZOOM_IN = 0,
+ ZOOM_OUT = 1,
+ ZOOM_NONE = 2, // hack, used to update the button status
+};
+
+bool DoZoomInOutWindow(int how, Window *w);
+void ZoomInOrOutToCursorWindow(bool in, Window * w);
+Point GetTileZoomCenterWindow(bool in, Window * w);
+void HandleZoomMessage(Window *w, const ViewPort *vp, byte widget_zoom_in, byte widget_zoom_out);
+
+static inline void MaxZoomInOut(int how, Window *w)
+{
+ while (DoZoomInOutWindow(how, w) ) {};
+}
+
+void OffsetGroundSprite(int x, int y);
+
+void DrawGroundSprite(uint32 image);
+void DrawGroundSpriteAt(uint32 image, int32 x, int32 y, byte z);
+void AddSortableSpriteToDraw(uint32 image, int x, int y, int w, int h, byte dz, byte z);
+void *AddStringToDraw(int x, int y, StringID string, uint32 params_1, uint32 params_2);
+void AddChildSpriteScreen(uint32 image, int x, int y);
+
+
+void StartSpriteCombine(void);
+void EndSpriteCombine(void);
+
+void HandleViewportClicked(const ViewPort *vp, int x, int y);
+void PlaceObject(void);
+void SetRedErrorSquare(TileIndex tile);
+void SetTileSelectSize(int w, int h);
+void SetTileSelectBigSize(int ox, int oy, int sx, int sy);
+
+void VpStartPlaceSizing(TileIndex tile, int user);
+void VpSetPresizeRange(uint from, uint to);
+void VpSetPlaceSizingLimit(int limit);
+
+Vehicle *CheckMouseOverVehicle(void);
+
+enum {
+ VPM_X_OR_Y = 0,
+ VPM_FIX_X = 1,
+ VPM_FIX_Y = 2,
+ VPM_RAILDIRS = 3,
+ VPM_X_AND_Y = 4,
+ VPM_X_AND_Y_LIMITED = 5,
+ VPM_SIGNALDIRS = 6
+};
+
+// viewport highlight mode (for highlighting tiles below cursor)
+enum {
+ VHM_NONE = 0, // default
+ VHM_RECT = 1, // rectangle (stations, depots, ...)
+ VHM_POINT = 2, // point (lower land, raise land, level land, ...)
+ VHM_SPECIAL = 3, // special mode used for highlighting while dragging (and for tunnels/docks)
+ VHM_DRAG = 4, // dragging items in the depot windows
+ VHM_RAIL = 5, // rail pieces
+};
+
+void VpSelectTilesWithMethod(int x, int y, int method);
+
+// highlighting draw styles
+typedef byte HighLightStyle;
+enum HighLightStyles {
+ HT_NONE = 0x00,
+ HT_RECT = 0x80,
+ HT_POINT = 0x40,
+ HT_LINE = 0x20, /* used for autorail highlighting (longer streches)
+ * (uses lower bits to indicate direction) */
+ HT_RAIL = 0x10, /* autorail (one piece)
+ * (uses lower bits to indicate direction) */
+ HT_DRAG_MASK = 0xF0, ///< masks the drag-type
+
+ /* lower bits (used with HT_LINE and HT_RAIL):
+ * (see ASCII art in autorail.h for a visual interpretation) */
+ HT_DIR_X = 0, ///< X direction
+ HT_DIR_Y = 1, ///< Y direction
+ HT_DIR_HU = 2, ///< horizontal upper
+ HT_DIR_HL = 3, ///< horizontal lower
+ HT_DIR_VL = 4, ///< vertical left
+ HT_DIR_VR = 5, ///< vertical right
+ HT_DIR_MASK = 0x7 ///< masks the drag-direction
+};
+
+typedef struct TileHighlightData {
+ Point size;
+ Point outersize;
+ Point pos;
+ Point offs;
+
+ Point new_pos;
+ Point new_size;
+ Point new_outersize;
+
+ Point selend, selstart;
+
+ byte dirty;
+ byte sizelimit;
+
+ byte drawstyle; // lower bits 0-3 are reserved for detailed highlight information information
+ byte new_drawstyle; // only used in UpdateTileSelection() to as a buffer to compare if there was a change between old and new
+ byte next_drawstyle; // queued, but not yet drawn style
+
+ byte place_mode;
+ bool make_square_red;
+ WindowClass window_class;
+ WindowNumber window_number;
+
+ int userdata;
+ TileIndex redsq;
+} TileHighlightData;
+
+
+// common button handler
+bool HandlePlacePushButton(Window *w, int widget, uint32 cursor, int mode, PlaceProc *placeproc);
+
+VARDEF Point _tile_fract_coords;
+
+extern TileHighlightData _thd;
+
+
+void ViewportDoDraw(const ViewPort *vp, int left, int top, int right, int bottom);
+
+#endif /* VIEWPORT_H */
diff --git a/src/void_map.h b/src/void_map.h
new file mode 100644
index 000000000..552a8c705
--- /dev/null
+++ b/src/void_map.h
@@ -0,0 +1,18 @@
+/* $Id$ */
+
+#ifndef VOID_MAP_H
+#define VOID_MAP_H
+
+static inline void MakeVoid(TileIndex t)
+{
+ SetTileType(t, MP_VOID);
+ SetTileHeight(t, 0);
+ _m[t].m1 = 0;
+ _m[t].m2 = 0;
+ _m[t].m3 = 0;
+ _m[t].m4 = 0;
+ _m[t].m5 = 0;
+ _m[t].extra = 0;
+}
+
+#endif /* VOID_MAP_H */
diff --git a/src/water_cmd.c b/src/water_cmd.c
new file mode 100644
index 000000000..041f83e20
--- /dev/null
+++ b/src/water_cmd.c
@@ -0,0 +1,731 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "bridge_map.h"
+#include "station_map.h"
+#include "table/sprites.h"
+#include "table/strings.h"
+#include "functions.h"
+#include "map.h"
+#include "tile.h"
+#include "vehicle.h"
+#include "viewport.h"
+#include "command.h"
+#include "town.h"
+#include "news.h"
+#include "sound.h"
+#include "depot.h"
+#include "vehicle_gui.h"
+#include "train.h"
+#include "water_map.h"
+#include "newgrf.h"
+
+static const SpriteID _water_shore_sprites[] = {
+ 0,
+ SPR_SHORE_TILEH_1,
+ SPR_SHORE_TILEH_2,
+ SPR_SHORE_TILEH_3,
+ SPR_SHORE_TILEH_4,
+ 0,
+ SPR_SHORE_TILEH_6,
+ 0,
+ SPR_SHORE_TILEH_8,
+ SPR_SHORE_TILEH_9,
+ 0,
+ 0,
+ SPR_SHORE_TILEH_12,
+ 0,
+ 0
+};
+
+
+static void FloodVehicle(Vehicle *v);
+
+/** Build a ship depot.
+ * @param tile tile where ship depot is built
+ * @param p1 depot direction (0 == X or 1 == Y)
+ * @param p2 unused
+ */
+int32 CmdBuildShipDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ TileIndex tile2;
+
+ int32 cost, ret;
+ Depot *depot;
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ if (p1 > 1) return CMD_ERROR;
+
+ if (!EnsureNoVehicle(tile)) return CMD_ERROR;
+
+ tile2 = tile + (p1 ? TileDiffXY(0, 1) : TileDiffXY(1, 0));
+ if (!EnsureNoVehicle(tile2)) return CMD_ERROR;
+
+ if (!IsClearWaterTile(tile) || !IsClearWaterTile(tile2))
+ return_cmd_error(STR_3801_MUST_BE_BUILT_ON_WATER);
+
+ if (IsBridgeAbove(tile) || IsBridgeAbove(tile2)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
+
+ ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+ if (CmdFailed(ret)) return CMD_ERROR;
+ ret = DoCommand(tile2, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+ if (CmdFailed(ret)) return CMD_ERROR;
+
+ // pretend that we're not making land from the water even though we actually are.
+ cost = 0;
+
+ depot = AllocateDepot();
+ if (depot == NULL) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ depot->xy = tile;
+ depot->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
+
+ MakeShipDepot(tile,_current_player, DEPOT_NORTH, p1);
+ MakeShipDepot(tile2,_current_player, DEPOT_SOUTH, p1);
+ MarkTileDirtyByTile(tile);
+ MarkTileDirtyByTile(tile2);
+ }
+
+ return cost + _price.build_ship_depot;
+}
+
+static int32 RemoveShipDepot(TileIndex tile, uint32 flags)
+{
+ TileIndex tile2;
+
+ if (!IsShipDepot(tile)) return CMD_ERROR;
+ if (!CheckTileOwnership(tile)) return CMD_ERROR;
+ if (!EnsureNoVehicle(tile)) return CMD_ERROR;
+
+ tile2 = GetOtherShipDepotTile(tile);
+
+ if (!EnsureNoVehicle(tile2)) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ /* Kill the depot, which is registered at the northernmost tile. Use that one */
+ DeleteDepot(GetDepotByTile(tile2 < tile ? tile2 : tile));
+
+ MakeWater(tile);
+ MakeWater(tile2);
+ MarkTileDirtyByTile(tile);
+ MarkTileDirtyByTile(tile2);
+ }
+
+ return _price.remove_ship_depot;
+}
+
+// build a shiplift
+static int32 DoBuildShiplift(TileIndex tile, DiagDirection dir, uint32 flags)
+{
+ int32 ret;
+ int delta;
+
+ // middle tile
+ ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+ if (CmdFailed(ret)) return CMD_ERROR;
+
+ delta = TileOffsByDiagDir(dir);
+ // lower tile
+ ret = DoCommand(tile - delta, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+ if (CmdFailed(ret)) return CMD_ERROR;
+ if (GetTileSlope(tile - delta, NULL) != SLOPE_FLAT) {
+ return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
+ }
+
+ // upper tile
+ ret = DoCommand(tile + delta, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+ if (CmdFailed(ret)) return CMD_ERROR;
+ if (GetTileSlope(tile + delta, NULL) != SLOPE_FLAT) {
+ return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
+ }
+
+ if ((MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) ||
+ (MayHaveBridgeAbove(tile - delta) && IsBridgeAbove(tile - delta)) ||
+ (MayHaveBridgeAbove(tile + delta) && IsBridgeAbove(tile + delta))) {
+ return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
+ }
+
+ if (flags & DC_EXEC) {
+ MakeLock(tile, _current_player, dir);
+ MarkTileDirtyByTile(tile);
+ MarkTileDirtyByTile(tile - delta);
+ MarkTileDirtyByTile(tile + delta);
+ }
+
+ return _price.clear_water * 22 >> 3;
+}
+
+static int32 RemoveShiplift(TileIndex tile, uint32 flags)
+{
+ TileIndexDiff delta = TileOffsByDiagDir(GetLockDirection(tile));
+
+ if (!CheckTileOwnership(tile)) return CMD_ERROR;
+
+ // make sure no vehicle is on the tile.
+ if (!EnsureNoVehicle(tile) || !EnsureNoVehicle(tile + delta) || !EnsureNoVehicle(tile - delta))
+ return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ DoClearSquare(tile);
+ DoClearSquare(tile + delta);
+ DoClearSquare(tile - delta);
+ }
+
+ return _price.clear_water * 2;
+}
+
+static void MarkTilesAroundDirty(TileIndex tile)
+{
+ MarkTileDirtyByTile(TILE_ADDXY(tile, 0, 1));
+ MarkTileDirtyByTile(TILE_ADDXY(tile, 0, -1));
+ MarkTileDirtyByTile(TILE_ADDXY(tile, 1, 0));
+ MarkTileDirtyByTile(TILE_ADDXY(tile, -1, 0));
+}
+
+/** Builds a lock (ship-lift)
+ * @param tile tile where to place the lock
+ * @param p1 unused
+ * @param p2 unused
+ */
+int32 CmdBuildLock(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ DiagDirection dir;
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ switch (GetTileSlope(tile, NULL)) {
+ case SLOPE_SW: dir = DIAGDIR_SW; break;
+ case SLOPE_SE: dir = DIAGDIR_SE; break;
+ case SLOPE_NW: dir = DIAGDIR_NW; break;
+ case SLOPE_NE: dir = DIAGDIR_NE; break;
+ default: return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
+ }
+ return DoBuildShiplift(tile, dir, flags);
+}
+
+/** Build a piece of canal.
+ * @param tile end tile of stretch-dragging
+ * @param p1 start tile of stretch-dragging
+ * @param p2 ctrl pressed - toggles ocean / canals at sealevel
+ */
+int32 CmdBuildCanal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ int32 cost;
+ int size_x, size_y;
+ int x;
+ int y;
+ int sx, sy;
+
+ if (p1 >= MapSize()) return CMD_ERROR;
+
+ x = TileX(tile);
+ y = TileY(tile);
+ sx = TileX(p1);
+ sy = TileY(p1);
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ if (x < sx) intswap(x, sx);
+ if (y < sy) intswap(y, sy);
+ size_x = (x - sx) + 1;
+ size_y = (y - sy) + 1;
+
+ /* Outside the editor you can only drag canals, and not areas */
+ if (_game_mode != GM_EDITOR && (sx != x && sy != y)) return CMD_ERROR;
+
+ cost = 0;
+ BEGIN_TILE_LOOP(tile, size_x, size_y, TileXY(sx, sy)) {
+ int32 ret;
+
+ if (GetTileSlope(tile, NULL) != SLOPE_FLAT) {
+ return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
+ }
+
+ // can't make water of water!
+ if (IsTileType(tile, MP_WATER) && (!IsTileOwner(tile, OWNER_WATER) || HASBIT(p2, 0))) continue;
+
+ ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+ if (CmdFailed(ret)) return ret;
+ cost += ret;
+
+ if (flags & DC_EXEC) {
+ if (TileHeight(tile) == 0) {
+ MakeWater(tile);
+ } else {
+ MakeCanal(tile, _current_player);
+ }
+ MarkTileDirtyByTile(tile);
+ MarkTilesAroundDirty(tile);
+ }
+
+ cost += _price.clear_water;
+ } END_TILE_LOOP(tile, size_x, size_y, 0);
+
+ if (cost == 0) {
+ return_cmd_error(STR_1007_ALREADY_BUILT);
+ } else {
+ return cost;
+ }
+}
+
+static int32 ClearTile_Water(TileIndex tile, byte flags)
+{
+ switch (GetWaterTileType(tile)) {
+ case WATER_CLEAR:
+ if (flags & DC_NO_WATER) return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER);
+
+ // Make sure no vehicle is on the tile
+ if (!EnsureNoVehicle(tile)) return CMD_ERROR;
+
+ // Make sure it's not an edge tile.
+ if (!IS_INT_INSIDE(TileX(tile), 1, MapMaxX() - 1) ||
+ !IS_INT_INSIDE(TileY(tile), 1, MapMaxY() - 1)) {
+ return_cmd_error(STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP);
+ }
+
+ if (GetTileOwner(tile) != OWNER_WATER && !CheckTileOwnership(tile)) return CMD_ERROR;
+
+ if (flags & DC_EXEC) DoClearSquare(tile);
+ return _price.clear_water;
+
+ case WATER_COAST: {
+ Slope slope = GetTileSlope(tile, NULL);
+
+ // Make sure no vehicle is on the tile
+ if (!EnsureNoVehicle(tile)) return CMD_ERROR;
+
+ // Make sure it's not an edge tile.
+ if (!IS_INT_INSIDE(TileX(tile), 1, MapMaxX() - 1) ||
+ !IS_INT_INSIDE(TileY(tile), 1, MapMaxY() - 1)) {
+ return_cmd_error(STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP);
+ }
+
+ if (flags & DC_EXEC) DoClearSquare(tile);
+ if (slope == SLOPE_N || slope == SLOPE_E || slope == SLOPE_S || slope == SLOPE_W) {
+ return _price.clear_water;
+ } else {
+ return _price.purchase_land;
+ }
+ }
+
+ case WATER_LOCK: {
+ static const TileIndexDiffC _shiplift_tomiddle_offs[] = {
+ { 0, 0}, {0, 0}, { 0, 0}, {0, 0}, // middle
+ {-1, 0}, {0, 1}, { 1, 0}, {0, -1}, // lower
+ { 1, 0}, {0, -1}, {-1, 0}, {0, 1}, // upper
+ };
+
+ if (flags & DC_AUTO) return_cmd_error(STR_2004_BUILDING_MUST_BE_DEMOLISHED);
+ if (_current_player == OWNER_WATER) return CMD_ERROR;
+ // move to the middle tile..
+ return RemoveShiplift(tile + ToTileIndexDiff(_shiplift_tomiddle_offs[GetSection(tile)]), flags);
+ }
+
+ case WATER_DEPOT:
+ if (flags & DC_AUTO) return_cmd_error(STR_2004_BUILDING_MUST_BE_DEMOLISHED);
+ return RemoveShipDepot(tile, flags);
+
+ default:
+ NOT_REACHED();
+ return 0;
+ }
+
+ return 0; // useless but silences warning
+}
+
+// return true if a tile is a water tile.
+static bool IsWateredTile(TileIndex tile)
+{
+ switch (GetTileType(tile)) {
+ case MP_WATER:
+ if (!IsCoast(tile)) return true;
+
+ switch (GetTileSlope(tile, NULL)) {
+ case SLOPE_W:
+ case SLOPE_S:
+ case SLOPE_E:
+ case SLOPE_N:
+ return true;
+
+ default:
+ return false;
+ }
+
+ case MP_STATION: return IsOilRig(tile) || IsDock(tile) || IsBuoy_(tile);
+ default: return false;
+ }
+}
+
+// draw a canal styled water tile with dikes around
+void DrawCanalWater(TileIndex tile)
+{
+ uint wa;
+
+ // determine the edges around with water.
+ wa = IsWateredTile(TILE_ADDXY(tile, -1, 0)) << 0;
+ wa += IsWateredTile(TILE_ADDXY(tile, 0, 1)) << 1;
+ wa += IsWateredTile(TILE_ADDXY(tile, 1, 0)) << 2;
+ wa += IsWateredTile(TILE_ADDXY(tile, 0, -1)) << 3;
+
+ if (!(wa & 1)) DrawGroundSprite(SPR_CANALS_BASE + 57);
+ if (!(wa & 2)) DrawGroundSprite(SPR_CANALS_BASE + 58);
+ if (!(wa & 4)) DrawGroundSprite(SPR_CANALS_BASE + 59);
+ if (!(wa & 8)) DrawGroundSprite(SPR_CANALS_BASE + 60);
+
+ // right corner
+ switch (wa & 0x03) {
+ case 0: DrawGroundSprite(SPR_CANALS_BASE + 57 + 4); break;
+ case 3: if (!IsWateredTile(TILE_ADDXY(tile, -1, 1))) DrawGroundSprite(SPR_CANALS_BASE + 57 + 8); break;
+ }
+
+ // bottom corner
+ switch (wa & 0x06) {
+ case 0: DrawGroundSprite(SPR_CANALS_BASE + 57 + 5); break;
+ case 6: if (!IsWateredTile(TILE_ADDXY(tile, 1, 1))) DrawGroundSprite(SPR_CANALS_BASE + 57 + 9); break;
+ }
+
+ // left corner
+ switch (wa & 0x0C) {
+ case 0: DrawGroundSprite(SPR_CANALS_BASE + 57 + 6); break;
+ case 12: if (!IsWateredTile(TILE_ADDXY(tile, 1, -1))) DrawGroundSprite(SPR_CANALS_BASE + 57 + 10); break;
+ }
+
+ // upper corner
+ switch (wa & 0x09) {
+ case 0: DrawGroundSprite(SPR_CANALS_BASE + 57 + 7); break;
+ case 9: if (!IsWateredTile(TILE_ADDXY(tile, -1, -1))) DrawGroundSprite(SPR_CANALS_BASE + 57 + 11); break;
+ }
+}
+
+typedef struct LocksDrawTileStruct {
+ int8 delta_x, delta_y, delta_z;
+ byte width, height, depth;
+ SpriteID image;
+} LocksDrawTileStruct;
+
+#include "table/water_land.h"
+
+static void DrawWaterStuff(const TileInfo *ti, const WaterDrawTileStruct *wdts,
+ uint32 palette, uint base
+)
+{
+ DrawGroundSprite(wdts++->image);
+
+ for (; wdts->delta_x != 0x80; wdts++) {
+ uint32 image = wdts->image + base;
+ if (_display_opt & DO_TRANS_BUILDINGS) {
+ MAKE_TRANSPARENT(image);
+ } else {
+ image |= palette;
+ }
+ AddSortableSpriteToDraw(image, ti->x + wdts->delta_x, ti->y + wdts->delta_y, wdts->width, wdts->height, wdts->unk, ti->z + wdts->delta_z);
+ }
+}
+
+static void DrawTile_Water(TileInfo *ti)
+{
+ switch (GetWaterTileType(ti->tile)) {
+ case WATER_CLEAR:
+ DrawGroundSprite(SPR_FLAT_WATER_TILE);
+ if (ti->z != 0 || !IsTileOwner(ti->tile, OWNER_WATER)) DrawCanalWater(ti->tile);
+ DrawBridgeMiddle(ti);
+ break;
+
+ case WATER_COAST:
+ assert(!IsSteepSlope(ti->tileh));
+ if (_coast_base != 0) {
+ DrawGroundSprite(_coast_base + ti->tileh);
+ } else {
+ DrawGroundSprite(_water_shore_sprites[ti->tileh]);
+ }
+ DrawBridgeMiddle(ti);
+ break;
+
+ case WATER_LOCK: {
+ const WaterDrawTileStruct *t = _shiplift_display_seq[GetSection(ti->tile)];
+ DrawWaterStuff(ti, t, 0, ti->z > t[3].delta_y ? 24 : 0);
+ } break;
+
+ case WATER_DEPOT:
+ DrawWaterStuff(ti, _shipdepot_display_seq[GetSection(ti->tile)], PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile)), 0);
+ break;
+ }
+}
+
+void DrawShipDepotSprite(int x, int y, int image)
+{
+ const WaterDrawTileStruct *wdts = _shipdepot_display_seq[image];
+
+ DrawSprite(wdts++->image, x, y);
+
+ for (; wdts->delta_x != 0x80; wdts++) {
+ Point pt = RemapCoords(wdts->delta_x, wdts->delta_y, wdts->delta_z);
+ DrawSprite(wdts->image + PLAYER_SPRITE_COLOR(_local_player), x + pt.x, y + pt.y);
+ }
+}
+
+
+static uint GetSlopeZ_Water(TileIndex tile, uint x, uint y)
+{
+ uint z;
+ uint tileh = GetTileSlope(tile, &z);
+
+ return z + GetPartialZ(x & 0xF, y & 0xF, tileh);
+}
+
+static Slope GetSlopeTileh_Water(TileIndex tile, Slope tileh)
+{
+ return tileh;
+}
+
+static void GetAcceptedCargo_Water(TileIndex tile, AcceptedCargo ac)
+{
+ /* not used */
+}
+
+static void GetTileDesc_Water(TileIndex tile, TileDesc *td)
+{
+ switch (GetWaterTileType(tile)) {
+ case WATER_CLEAR:
+ if (TilePixelHeight(tile) == 0 || IsTileOwner(tile, OWNER_WATER)) {
+ td->str = STR_3804_WATER;
+ } else {
+ td->str = STR_LANDINFO_CANAL;
+ }
+ break;
+ case WATER_COAST: td->str = STR_3805_COAST_OR_RIVERBANK; break;
+ case WATER_LOCK : td->str = STR_LANDINFO_LOCK; break;
+ case WATER_DEPOT: td->str = STR_3806_SHIP_DEPOT; break;
+ default: assert(0); break;
+ }
+
+ td->owner = GetTileOwner(tile);
+}
+
+static void AnimateTile_Water(TileIndex tile)
+{
+ /* not used */
+}
+
+static void TileLoopWaterHelper(TileIndex tile, const TileIndexDiffC *offs)
+{
+ TileIndex target = TILE_ADD(tile, ToTileIndexDiff(offs[0]));
+
+ // type of this tile mustn't be water already.
+ if (IsTileType(target, MP_WATER)) return;
+
+ if (TileHeight(TILE_ADD(tile, ToTileIndexDiff(offs[1]))) != 0 ||
+ TileHeight(TILE_ADD(tile, ToTileIndexDiff(offs[2]))) != 0) {
+ return;
+ }
+
+ if (TileHeight(TILE_ADD(tile, ToTileIndexDiff(offs[3]))) != 0 ||
+ TileHeight(TILE_ADD(tile, ToTileIndexDiff(offs[4]))) != 0) {
+ // make coast..
+ switch (GetTileType(target)) {
+ case MP_RAILWAY: {
+ TrackBits tracks;
+ Slope slope;
+
+ if (!IsPlainRailTile(target)) break;
+
+ tracks = GetTrackBits(target);
+ slope = GetTileSlope(target, NULL);
+ if (!(
+ (slope == SLOPE_W && tracks == TRACK_BIT_RIGHT) ||
+ (slope == SLOPE_S && tracks == TRACK_BIT_UPPER) ||
+ (slope == SLOPE_E && tracks == TRACK_BIT_LEFT) ||
+ (slope == SLOPE_N && tracks == TRACK_BIT_LOWER)
+ )) {
+ break;
+ }
+ }
+ /* FALLTHROUGH */
+
+ case MP_CLEAR:
+ case MP_TREES:
+ _current_player = OWNER_WATER;
+ if (!CmdFailed(DoCommand(target, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR))) {
+ MakeShore(target);
+ MarkTileDirtyByTile(target);
+ }
+ break;
+
+ default:
+ break;
+ }
+ } else {
+ _current_player = OWNER_WATER;
+ {
+ Vehicle *v = FindVehicleOnTileZ(target, 0);
+ if (v != NULL) FloodVehicle(v);
+ }
+
+ if (!CmdFailed(DoCommand(target, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR))) {
+ MakeWater(target);
+ MarkTileDirtyByTile(target);
+ }
+ }
+}
+
+static void FloodVehicle(Vehicle *v)
+{
+ if (!(v->vehstatus & VS_CRASHED)) {
+ uint16 pass = 0;
+
+ if (v->type == VEH_Road) { // flood bus/truck
+ pass = 1; // driver
+ if (v->cargo_type == CT_PASSENGERS)
+ pass += v->cargo_count;
+
+ v->vehstatus |= VS_CRASHED;
+ v->u.road.crashed_ctr = 2000; // max 2220, disappear pretty fast
+ RebuildVehicleLists();
+ } else if (v->type == VEH_Train) {
+ Vehicle *u;
+
+ v = GetFirstVehicleInChain(v);
+ u = v;
+ if (IsFrontEngine(v)) pass = 4; // driver
+
+ // crash all wagons, and count passangers
+ BEGIN_ENUM_WAGONS(v)
+ if (v->cargo_type == CT_PASSENGERS) pass += v->cargo_count;
+ v->vehstatus |= VS_CRASHED;
+ END_ENUM_WAGONS(v)
+
+ v = u;
+ v->u.rail.crash_anim_pos = 4000; // max 4440, disappear pretty fast
+ RebuildVehicleLists();
+ } else {
+ return;
+ }
+
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
+ InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
+
+ SetDParam(0, pass);
+ AddNewsItem(STR_B006_FLOOD_VEHICLE_DESTROYED,
+ NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ACCIDENT, 0),
+ v->index,
+ 0);
+ CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE);
+ SndPlayVehicleFx(SND_12_EXPLOSION, v);
+ }
+}
+
+// called from tunnelbridge_cmd, and by TileLoop_Industry()
+void TileLoop_Water(TileIndex tile)
+{
+ static const TileIndexDiffC _tile_loop_offs_array[][5] = {
+ // tile to mod shore? shore?
+ {{-1, 0}, {0, 0}, {0, 1}, {-1, 0}, {-1, 1}},
+ {{ 0, 1}, {0, 1}, {1, 1}, { 0, 2}, { 1, 2}},
+ {{ 1, 0}, {1, 0}, {1, 1}, { 2, 0}, { 2, 1}},
+ {{ 0, -1}, {0, 0}, {1, 0}, { 0, -1}, { 1, -1}}
+ };
+
+ /* Ensure sea-level canals do not flood */
+ if ((IsTileType(tile, MP_WATER) || IsTileType(tile, MP_TUNNELBRIDGE)) &&
+ !IsTileOwner(tile, OWNER_WATER)) return;
+
+ if (IS_INT_INSIDE(TileX(tile), 1, MapSizeX() - 3 + 1) &&
+ IS_INT_INSIDE(TileY(tile), 1, MapSizeY() - 3 + 1)) {
+ uint i;
+
+ for (i = 0; i != lengthof(_tile_loop_offs_array); i++) {
+ TileLoopWaterHelper(tile, _tile_loop_offs_array[i]);
+ }
+ }
+ // _current_player can be changed by TileLoopWaterHelper.. reset it back
+ // here
+ _current_player = OWNER_NONE;
+
+ // edges
+ if (TileX(tile) == 0 && IS_INT_INSIDE(TileY(tile), 1, MapSizeY() - 3 + 1)) { //NE
+ TileLoopWaterHelper(tile, _tile_loop_offs_array[2]);
+ }
+
+ if (TileX(tile) == MapSizeX() - 2 && IS_INT_INSIDE(TileY(tile), 1, MapSizeY() - 3 + 1)) { //SW
+ TileLoopWaterHelper(tile, _tile_loop_offs_array[0]);
+ }
+
+ if (TileY(tile) == 0 && IS_INT_INSIDE(TileX(tile), 1, MapSizeX() - 3 + 1)) { //NW
+ TileLoopWaterHelper(tile, _tile_loop_offs_array[1]);
+ }
+
+ if (TileY(tile) == MapSizeY() - 2 && IS_INT_INSIDE(TileX(tile), 1, MapSizeX() - 3 + 1)) { //SE
+ TileLoopWaterHelper(tile, _tile_loop_offs_array[3]);
+ }
+}
+
+static uint32 GetTileTrackStatus_Water(TileIndex tile, TransportType mode)
+{
+ static const byte coast_tracks[] = {0, 32, 4, 0, 16, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0};
+
+ TrackBits ts;
+
+ if (mode != TRANSPORT_WATER) return 0;
+
+ switch (GetWaterTileType(tile)) {
+ case WATER_CLEAR: ts = TRACK_BIT_ALL; break;
+ case WATER_COAST: ts = coast_tracks[GetTileSlope(tile, NULL) & 0xF]; break;
+ case WATER_LOCK: ts = AxisToTrackBits(DiagDirToAxis(GetLockDirection(tile))); break;
+ case WATER_DEPOT: ts = AxisToTrackBits(GetShipDepotAxis(tile)); break;
+ default: return 0;
+ }
+ if (TileX(tile) == 0) {
+ // NE border: remove tracks that connects NE tile edge
+ ts &= ~(TRACK_BIT_X | TRACK_BIT_UPPER | TRACK_BIT_RIGHT);
+ }
+ if (TileY(tile) == 0) {
+ // NW border: remove tracks that connects NW tile edge
+ ts &= ~(TRACK_BIT_Y | TRACK_BIT_LEFT | TRACK_BIT_UPPER);
+ }
+ return ts * 0x101;
+}
+
+static void ClickTile_Water(TileIndex tile)
+{
+ if (GetWaterTileType(tile) == WATER_DEPOT) {
+ TileIndex tile2 = GetOtherShipDepotTile(tile);
+
+ ShowDepotWindow(tile < tile2 ? tile : tile2, VEH_Ship);
+ }
+}
+
+static void ChangeTileOwner_Water(TileIndex tile, PlayerID old_player, PlayerID new_player)
+{
+ if (!IsTileOwner(tile, old_player)) return;
+
+ if (new_player != PLAYER_SPECTATOR) {
+ SetTileOwner(tile, new_player);
+ } else {
+ DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
+ }
+}
+
+static uint32 VehicleEnter_Water(Vehicle *v, TileIndex tile, int x, int y)
+{
+ return 0;
+}
+
+
+const TileTypeProcs _tile_type_water_procs = {
+ DrawTile_Water, /* draw_tile_proc */
+ GetSlopeZ_Water, /* get_slope_z_proc */
+ ClearTile_Water, /* clear_tile_proc */
+ GetAcceptedCargo_Water, /* get_accepted_cargo_proc */
+ GetTileDesc_Water, /* get_tile_desc_proc */
+ GetTileTrackStatus_Water, /* get_tile_track_status_proc */
+ ClickTile_Water, /* click_tile_proc */
+ AnimateTile_Water, /* animate_tile_proc */
+ TileLoop_Water, /* tile_loop_clear */
+ ChangeTileOwner_Water, /* change_tile_owner_clear */
+ NULL, /* get_produced_cargo_proc */
+ VehicleEnter_Water, /* vehicle_enter_tile_proc */
+ GetSlopeTileh_Water, /* get_slope_tileh_proc */
+};
diff --git a/src/water_map.h b/src/water_map.h
new file mode 100644
index 000000000..db3308cbf
--- /dev/null
+++ b/src/water_map.h
@@ -0,0 +1,142 @@
+/* $Id$ */
+
+#ifndef WATER_MAP_H
+#define WATER_MAP_H
+
+typedef enum WaterTileType {
+ WATER_CLEAR,
+ WATER_COAST,
+ WATER_LOCK,
+ WATER_DEPOT,
+} WaterTileType;
+
+typedef enum DepotPart {
+ DEPOT_NORTH = 0x80,
+ DEPOT_SOUTH = 0x81,
+ DEPOT_END = 0x84,
+} DepotPart;
+
+typedef enum LockPart {
+ LOCK_MIDDLE = 0x10,
+ LOCK_LOWER = 0x14,
+ LOCK_UPPER = 0x18,
+ LOCK_END = 0x1C
+} LockPart;
+
+static inline WaterTileType GetWaterTileType(TileIndex t)
+{
+ if (_m[t].m5 == 0) return WATER_CLEAR;
+ if (_m[t].m5 == 1) return WATER_COAST;
+ if (IS_INT_INSIDE(_m[t].m5, LOCK_MIDDLE, LOCK_END)) return WATER_LOCK;
+
+ assert(IS_INT_INSIDE(_m[t].m5, DEPOT_NORTH, DEPOT_END));
+ return WATER_DEPOT;
+}
+
+static inline bool IsWater(TileIndex t)
+{
+ return GetWaterTileType(t) == WATER_CLEAR;
+}
+
+static inline bool IsCoast(TileIndex t)
+{
+ return GetWaterTileType(t) == WATER_COAST;
+}
+
+static inline bool IsClearWaterTile(TileIndex t)
+{
+ return IsTileType(t, MP_WATER) && IsWater(t) && GetTileSlope(t, NULL) == SLOPE_FLAT;
+}
+
+static inline TileIndex GetOtherShipDepotTile(TileIndex t)
+{
+ return t + (HASBIT(_m[t].m5, 0) ? -1 : 1) * (HASBIT(_m[t].m5, 1) ? TileDiffXY(0, 1) : TileDiffXY(1, 0));
+}
+
+static inline TileIndex IsShipDepot(TileIndex t)
+{
+ return IS_INT_INSIDE(_m[t].m5, DEPOT_NORTH, DEPOT_END);
+}
+
+static inline Axis GetShipDepotAxis(TileIndex t)
+{
+ return (Axis)GB(_m[t].m5, 1, 1);
+}
+
+static inline DiagDirection GetShipDepotDirection(TileIndex t)
+{
+ return XYNSToDiagDir(GetShipDepotAxis(t), GB(_m[t].m5, 0, 1));
+}
+
+static inline DiagDirection GetLockDirection(TileIndex t)
+{
+ return (DiagDirection)GB(_m[t].m5, 0, 2);
+}
+
+static inline byte GetSection(TileIndex t)
+{
+ assert(GetWaterTileType(t) == WATER_LOCK || GetWaterTileType(t) == WATER_DEPOT);
+ return GB(_m[t].m5, 0, 4);
+}
+
+
+static inline void MakeWater(TileIndex t)
+{
+ SetTileType(t, MP_WATER);
+ SetTileOwner(t, OWNER_WATER);
+ _m[t].m2 = 0;
+ _m[t].m3 = 0;
+ _m[t].m4 = 0;
+ _m[t].m5 = 0;
+}
+
+static inline void MakeShore(TileIndex t)
+{
+ SetTileType(t, MP_WATER);
+ SetTileOwner(t, OWNER_WATER);
+ _m[t].m2 = 0;
+ _m[t].m3 = 0;
+ _m[t].m4 = 0;
+ _m[t].m5 = 1;
+}
+
+static inline void MakeCanal(TileIndex t, Owner o)
+{
+ SetTileType(t, MP_WATER);
+ SetTileOwner(t, o);
+ _m[t].m2 = 0;
+ _m[t].m3 = 0;
+ _m[t].m4 = 0;
+ _m[t].m5 = 0;
+}
+
+static inline void MakeShipDepot(TileIndex t, Owner o, DepotPart base, Axis a)
+{
+ SetTileType(t, MP_WATER);
+ SetTileOwner(t, o);
+ _m[t].m2 = 0;
+ _m[t].m3 = 0;
+ _m[t].m4 = 0;
+ _m[t].m5 = base + a * 2;
+}
+
+static inline void MakeLockTile(TileIndex t, Owner o, byte section)
+{
+ SetTileType(t, MP_WATER);
+ SetTileOwner(t, o);
+ _m[t].m2 = 0;
+ _m[t].m3 = 0;
+ _m[t].m4 = 0;
+ _m[t].m5 = section;
+}
+
+static inline void MakeLock(TileIndex t, Owner o, DiagDirection d)
+{
+ TileIndexDiff delta = TileOffsByDiagDir(d);
+
+ MakeLockTile(t, o, LOCK_MIDDLE + d);
+ MakeLockTile(t - delta, o, LOCK_LOWER + d);
+ MakeLockTile(t + delta, o, LOCK_UPPER + d);
+}
+
+#endif /* WATER_MAP_H */
diff --git a/src/waypoint.c b/src/waypoint.c
new file mode 100644
index 000000000..e0bc48936
--- /dev/null
+++ b/src/waypoint.c
@@ -0,0 +1,442 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+
+#include "command.h"
+#include "functions.h"
+#include "gfx.h"
+#include "map.h"
+#include "order.h"
+#include "rail_map.h"
+#include "bridge_map.h"
+#include "saveload.h"
+#include "station.h"
+#include "tile.h"
+#include "town.h"
+#include "waypoint.h"
+#include "variables.h"
+#include "table/strings.h"
+#include "vehicle.h"
+#include "yapf/yapf.h"
+#include "date.h"
+
+enum {
+ MAX_WAYPOINTS_PER_TOWN = 64,
+};
+
+/**
+ * Called if a new block is added to the waypoint-pool
+ */
+static void WaypointPoolNewBlock(uint start_item)
+{
+ Waypoint *wp;
+
+ /* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
+ * TODO - This is just a temporary stage, this will be removed. */
+ for (wp = GetWaypoint(start_item); wp != NULL; wp = (wp->index + 1U < GetWaypointPoolSize()) ? GetWaypoint(wp->index + 1U) : NULL) wp->index = start_item++;
+}
+
+DEFINE_OLD_POOL(Waypoint, Waypoint, WaypointPoolNewBlock, NULL)
+
+/* Create a new waypoint */
+static Waypoint* AllocateWaypoint(void)
+{
+ Waypoint *wp;
+
+ /* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
+ * TODO - This is just a temporary stage, this will be removed. */
+ for (wp = GetWaypoint(0); wp != NULL; wp = (wp->index + 1U < GetWaypointPoolSize()) ? GetWaypoint(wp->index + 1U) : NULL) {
+ if (!IsValidWaypoint(wp)) {
+ uint index = wp->index;
+
+ memset(wp, 0, sizeof(*wp));
+ wp->index = index;
+
+ return wp;
+ }
+ }
+
+ /* Check if we can add a block to the pool */
+ if (AddBlockToPool(&_Waypoint_pool)) return AllocateWaypoint();
+
+ return NULL;
+}
+
+/* Update the sign for the waypoint */
+static void UpdateWaypointSign(Waypoint* wp)
+{
+ Point pt = RemapCoords2(TileX(wp->xy) * TILE_SIZE, TileY(wp->xy) * TILE_SIZE);
+ SetDParam(0, wp->index);
+ UpdateViewportSignPos(&wp->sign, pt.x, pt.y - 0x20, STR_WAYPOINT_VIEWPORT);
+}
+
+/* Redraw the sign of a waypoint */
+static void RedrawWaypointSign(const Waypoint* wp)
+{
+ MarkAllViewportsDirty(
+ wp->sign.left - 6,
+ wp->sign.top,
+ wp->sign.left + (wp->sign.width_1 << 2) + 12,
+ wp->sign.top + 48);
+}
+
+/* Update all signs */
+void UpdateAllWaypointSigns(void)
+{
+ Waypoint *wp;
+
+ FOR_ALL_WAYPOINTS(wp) {
+ UpdateWaypointSign(wp);
+ }
+}
+
+/* Internal handler to delete a waypoint */
+void DestroyWaypoint(Waypoint *wp)
+{
+ RemoveOrderFromAllVehicles(OT_GOTO_WAYPOINT, wp->index);
+
+ if (wp->string != STR_NULL) DeleteName(wp->string);
+
+ RedrawWaypointSign(wp);
+}
+
+/* Set the default name for a waypoint */
+static void MakeDefaultWaypointName(Waypoint* wp)
+{
+ Waypoint *local_wp;
+ bool used_waypoint[MAX_WAYPOINTS_PER_TOWN];
+ int i;
+
+ wp->town_index = ClosestTownFromTile(wp->xy, (uint)-1)->index;
+
+ memset(used_waypoint, 0, sizeof(used_waypoint));
+
+ /* Find an unused waypoint number belonging to this town */
+ FOR_ALL_WAYPOINTS(local_wp) {
+ if (wp == local_wp) continue;
+
+ if (local_wp->xy && local_wp->string == STR_NULL && local_wp->town_index == wp->town_index)
+ used_waypoint[local_wp->town_cn] = true;
+ }
+
+ /* Find an empty spot */
+ for (i = 0; used_waypoint[i] && i < MAX_WAYPOINTS_PER_TOWN; i++) {}
+
+ wp->string = STR_NULL;
+ wp->town_cn = i;
+}
+
+/* Find a deleted waypoint close to a tile. */
+static Waypoint *FindDeletedWaypointCloseTo(TileIndex tile)
+{
+ Waypoint *wp, *best = NULL;
+ uint thres = 8;
+
+ FOR_ALL_WAYPOINTS(wp) {
+ if (wp->deleted) {
+ uint cur_dist = DistanceManhattan(tile, wp->xy);
+
+ if (cur_dist < thres) {
+ thres = cur_dist;
+ best = wp;
+ }
+ }
+ }
+
+ return best;
+}
+
+/**
+ * Update waypoint graphics id against saved GRFID/localidx.
+ * This is to ensure the chosen graphics are correct if GRF files are changed.
+ */
+void AfterLoadWaypoints(void)
+{
+ Waypoint *wp;
+
+ FOR_ALL_WAYPOINTS(wp) {
+ uint i;
+
+ if (wp->grfid == 0) continue;
+
+ for (i = 0; i < GetNumCustomStations(STAT_CLASS_WAYP); i++) {
+ const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, i);
+ if (statspec != NULL && statspec->grfid == wp->grfid && statspec->localidx == wp->localidx) {
+ wp->stat_id = i;
+ break;
+ }
+ }
+ }
+}
+
+/** Convert existing rail to waypoint. Eg build a waypoint station over
+ * piece of rail
+ * @param tile tile where waypoint will be built
+ * @param p1 graphics for waypoint type, 0 indicates standard graphics
+ * @param p2 unused
+ *
+ * @todo When checking for the tile slope,
+ * distingush between "Flat land required" and "land sloped in wrong direction"
+ */
+int32 CmdBuildTrainWaypoint(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Waypoint *wp;
+ Slope tileh;
+ Axis axis;
+
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ /* if custom gfx are used, make sure it is within bounds */
+ if (p1 >= GetNumCustomStations(STAT_CLASS_WAYP)) return CMD_ERROR;
+
+ if (!IsTileType(tile, MP_RAILWAY) ||
+ GetRailTileType(tile) != RAIL_TILE_NORMAL || (
+ (axis = AXIS_X, GetTrackBits(tile) != TRACK_BIT_X) &&
+ (axis = AXIS_Y, GetTrackBits(tile) != TRACK_BIT_Y)
+ )) {
+ return_cmd_error(STR_1005_NO_SUITABLE_RAILROAD_TRACK);
+ }
+
+ if (!CheckTileOwnership(tile)) return CMD_ERROR;
+ if (!EnsureNoVehicle(tile)) return CMD_ERROR;
+
+ tileh = GetTileSlope(tile, NULL);
+ if (tileh != SLOPE_FLAT &&
+ (!_patches.build_on_slopes || IsSteepSlope(tileh) || !(tileh & (0x3 << axis)) || !(tileh & ~(0x3 << axis)))) {
+ return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
+ }
+
+ if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
+
+ /* Check if there is an already existing, deleted, waypoint close to us that we can reuse. */
+ wp = FindDeletedWaypointCloseTo(tile);
+ if (wp == NULL) {
+ wp = AllocateWaypoint();
+ if (wp == NULL) return CMD_ERROR;
+
+ wp->town_index = 0;
+ wp->string = STR_NULL;
+ wp->town_cn = 0;
+ }
+
+ if (flags & DC_EXEC) {
+ const StationSpec* statspec;
+
+ MakeRailWaypoint(tile, GetTileOwner(tile), axis, GetRailType(tile), wp->index);
+ MarkTileDirtyByTile(tile);
+
+ statspec = GetCustomStationSpec(STAT_CLASS_WAYP, p1);
+
+ if (statspec != NULL) {
+ wp->stat_id = p1;
+ wp->grfid = statspec->grfid;
+ wp->localidx = statspec->localidx;
+ } else {
+ // Specified custom graphics do not exist, so use default.
+ wp->stat_id = 0;
+ wp->grfid = 0;
+ wp->localidx = 0;
+ }
+
+ wp->deleted = 0;
+ wp->xy = tile;
+ wp->build_date = _date;
+
+ if (wp->town_index == 0) MakeDefaultWaypointName(wp);
+
+ UpdateWaypointSign(wp);
+ RedrawWaypointSign(wp);
+ YapfNotifyTrackLayoutChange(tile, AxisToTrack(axis));
+ }
+
+ return _price.build_train_depot;
+}
+
+/* Daily loop for waypoints */
+void WaypointsDailyLoop(void)
+{
+ Waypoint *wp;
+
+ /* Check if we need to delete a waypoint */
+ FOR_ALL_WAYPOINTS(wp) {
+ if (wp->deleted != 0 && --wp->deleted == 0) DeleteWaypoint(wp);
+ }
+}
+
+/* Remove a waypoint */
+int32 RemoveTrainWaypoint(TileIndex tile, uint32 flags, bool justremove)
+{
+ Waypoint *wp;
+
+ /* Make sure it's a waypoint */
+ if (!IsTileType(tile, MP_RAILWAY) ||
+ !IsRailWaypoint(tile) ||
+ (!CheckTileOwnership(tile) && _current_player != OWNER_WATER) ||
+ !EnsureNoVehicle(tile)) {
+ return CMD_ERROR;
+ }
+
+ if (flags & DC_EXEC) {
+ Track track = GetRailWaypointTrack(tile);
+ wp = GetWaypointByTile(tile);
+
+ wp->deleted = 30; // let it live for this many days before we do the actual deletion.
+ RedrawWaypointSign(wp);
+
+ if (justremove) {
+ MakeRailNormal(tile, GetTileOwner(tile), GetRailWaypointBits(tile), GetRailType(tile));
+ MarkTileDirtyByTile(tile);
+ } else {
+ DoClearSquare(tile);
+ SetSignalsOnBothDir(tile, track);
+ }
+ YapfNotifyTrackLayoutChange(tile, track);
+ }
+
+ return _price.remove_train_depot;
+}
+
+/** Delete a waypoint
+ * @param tile tile where waypoint is to be deleted
+ * @param p1 unused
+ * @param p2 unused
+ */
+int32 CmdRemoveTrainWaypoint(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+ return RemoveTrainWaypoint(tile, flags, true);
+}
+
+/** Rename a waypoint.
+ * @param tile unused
+ * @param p1 id of waypoint
+ * @param p2 unused
+ */
+int32 CmdRenameWaypoint(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+ Waypoint *wp;
+
+ if (!IsValidWaypointID(p1)) return CMD_ERROR;
+
+ if (_cmd_text[0] != '\0') {
+ StringID str = AllocateNameUnique(_cmd_text, 0);
+
+ if (str == 0) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ wp = GetWaypoint(p1);
+ if (wp->string != STR_NULL) DeleteName(wp->string);
+
+ wp->string = str;
+ wp->town_cn = 0;
+
+ UpdateWaypointSign(wp);
+ MarkWholeScreenDirty();
+ } else {
+ DeleteName(str);
+ }
+ } else {
+ if (flags & DC_EXEC) {
+ wp = GetWaypoint(p1);
+ if (wp->string != STR_NULL) DeleteName(wp->string);
+
+ MakeDefaultWaypointName(wp);
+ UpdateWaypointSign(wp);
+ MarkWholeScreenDirty();
+ }
+ }
+ return 0;
+}
+
+/* This hacks together some dummy one-shot Station structure for a waypoint. */
+Station *ComposeWaypointStation(TileIndex tile)
+{
+ Waypoint *wp = GetWaypointByTile(tile);
+ static Station stat;
+
+ stat.train_tile = stat.xy = wp->xy;
+ stat.town = GetTown(wp->town_index);
+ stat.string_id = wp->string == STR_NULL ? /* FIXME? */ 0 : wp->string;
+ stat.build_date = wp->build_date;
+
+ return &stat;
+}
+
+/* Draw a waypoint */
+void DrawWaypointSprite(int x, int y, int stat_id, RailType railtype)
+{
+ x += 33;
+ y += 17;
+
+ if (!DrawStationTile(x, y, railtype, AXIS_X, STAT_CLASS_WAYP, stat_id)) {
+ DrawDefaultWaypointSprite(x, y, railtype);
+ }
+}
+
+/* Fix savegames which stored waypoints in their old format */
+void FixOldWaypoints(void)
+{
+ Waypoint *wp;
+
+ /* Convert the old 'town_or_string', to 'string' / 'town' / 'town_cn' */
+ FOR_ALL_WAYPOINTS(wp) {
+ wp->town_index = ClosestTownFromTile(wp->xy, (uint)-1)->index;
+ wp->town_cn = 0;
+ if (wp->string & 0xC000) {
+ wp->town_cn = wp->string & 0x3F;
+ wp->string = STR_NULL;
+ }
+ }
+}
+
+void InitializeWaypoints(void)
+{
+ CleanPool(&_Waypoint_pool);
+ AddBlockToPool(&_Waypoint_pool);
+}
+
+static const SaveLoad _waypoint_desc[] = {
+ SLE_CONDVAR(Waypoint, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+ SLE_CONDVAR(Waypoint, xy, SLE_UINT32, 6, SL_MAX_VERSION),
+ SLE_CONDVAR(Waypoint, town_index, SLE_UINT16, 12, SL_MAX_VERSION),
+ SLE_CONDVAR(Waypoint, town_cn, SLE_UINT8, 12, SL_MAX_VERSION),
+ SLE_VAR(Waypoint, string, SLE_UINT16),
+ SLE_VAR(Waypoint, deleted, SLE_UINT8),
+
+ SLE_CONDVAR(Waypoint, build_date, SLE_FILE_U16 | SLE_VAR_I32, 3, 30),
+ SLE_CONDVAR(Waypoint, build_date, SLE_INT32, 31, SL_MAX_VERSION),
+ SLE_CONDVAR(Waypoint, localidx, SLE_UINT8, 3, SL_MAX_VERSION),
+ SLE_CONDVAR(Waypoint, grfid, SLE_UINT32, 17, SL_MAX_VERSION),
+
+ SLE_END()
+};
+
+static void Save_WAYP(void)
+{
+ Waypoint *wp;
+
+ FOR_ALL_WAYPOINTS(wp) {
+ SlSetArrayIndex(wp->index);
+ SlObject(wp, _waypoint_desc);
+ }
+}
+
+static void Load_WAYP(void)
+{
+ int index;
+
+ while ((index = SlIterateArray()) != -1) {
+ Waypoint *wp;
+
+ if (!AddBlockIfNeeded(&_Waypoint_pool, index))
+ error("Waypoints: failed loading savegame: too many waypoints");
+
+ wp = GetWaypoint(index);
+ SlObject(wp, _waypoint_desc);
+ }
+}
+
+const ChunkHandler _waypoint_chunk_handlers[] = {
+ { 'CHKP', Save_WAYP, Load_WAYP, CH_ARRAY | CH_LAST},
+};
diff --git a/src/waypoint.h b/src/waypoint.h
new file mode 100644
index 000000000..75366fb18
--- /dev/null
+++ b/src/waypoint.h
@@ -0,0 +1,73 @@
+/* $Id$ */
+
+#ifndef WAYPOINT_H
+#define WAYPOINT_H
+
+#include "oldpool.h"
+#include "rail_map.h"
+
+struct Waypoint {
+ TileIndex xy; ///< Tile of waypoint
+ WaypointID index; ///< Index of waypoint
+
+ TownID town_index; ///< Town associated with the waypoint
+ byte town_cn; ///< The Nth waypoint for this town (consecutive number)
+ StringID string; ///< If this is zero (i.e. no custom name), town + town_cn is used for naming
+
+ ViewportSign sign; ///< Dimensions of sign (not saved)
+ Date build_date; ///< Date of construction
+
+ byte stat_id; ///< ID of waypoint within the waypoint class (not saved)
+ uint32 grfid; ///< ID of GRF file
+ byte localidx; ///< Index of station within GRF file
+
+ byte deleted; ///< Delete counter. If greater than 0 then it is decremented until it reaches 0; the waypoint is then is deleted.
+};
+
+DECLARE_OLD_POOL(Waypoint, Waypoint, 3, 8000)
+
+/**
+ * Check if a Waypoint really exists.
+ */
+static inline bool IsValidWaypoint(const Waypoint *wp)
+{
+ return wp->xy != 0;
+}
+
+static inline bool IsValidWaypointID(WaypointID index)
+{
+ return index < GetWaypointPoolSize() && IsValidWaypoint(GetWaypoint(index));
+}
+
+void DestroyWaypoint(Waypoint *wp);
+
+static inline void DeleteWaypoint(Waypoint *wp)
+{
+ DestroyWaypoint(wp);
+ wp->xy = 0;
+}
+
+#define FOR_ALL_WAYPOINTS_FROM(wp, start) for (wp = GetWaypoint(start); wp != NULL; wp = (wp->index + 1U < GetWaypointPoolSize()) ? GetWaypoint(wp->index + 1U) : NULL) if (IsValidWaypoint(wp))
+#define FOR_ALL_WAYPOINTS(wp) FOR_ALL_WAYPOINTS_FROM(wp, 0)
+
+
+/**
+ * Fetch a waypoint by tile
+ * @param tile Tile of waypoint
+ * @return Waypoint
+ */
+static inline Waypoint *GetWaypointByTile(TileIndex tile)
+{
+ assert(IsTileType(tile, MP_RAILWAY) && IsRailWaypoint(tile));
+ return GetWaypoint(_m[tile].m2);
+}
+
+int32 RemoveTrainWaypoint(TileIndex tile, uint32 flags, bool justremove);
+Station *ComposeWaypointStation(TileIndex tile);
+void ShowRenameWaypointWindow(const Waypoint *cp);
+void DrawWaypointSprite(int x, int y, int image, RailType railtype);
+void FixOldWaypoints(void);
+void UpdateAllWaypointSigns(void);
+void AfterLoadWaypoints(void);
+
+#endif /* WAYPOINT_H */
diff --git a/src/widget.c b/src/widget.c
new file mode 100644
index 000000000..2c77ccd7c
--- /dev/null
+++ b/src/widget.c
@@ -0,0 +1,700 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "functions.h"
+#include "player.h"
+#include "table/sprites.h"
+#include "table/strings.h"
+#include "window.h"
+#include "gfx.h"
+#include "viewport.h"
+
+static Point HandleScrollbarHittest(const Scrollbar *sb, int top, int bottom)
+{
+ Point pt;
+ int height, count, pos, cap;
+
+ top += 10;
+ bottom -= 9;
+
+ height = (bottom - top);
+
+ pos = sb->pos;
+ count = sb->count;
+ cap = sb->cap;
+
+ if (count != 0) top += height * pos / count;
+
+ if (cap > count) cap = count;
+ if (count != 0) bottom -= (count - pos - cap) * height / count;
+
+ pt.x = top;
+ pt.y = bottom - 1;
+ return pt;
+}
+
+/*****************************************************
+ * Special handling for the scrollbar widget type.
+ * Handles the special scrolling buttons and other
+ * scrolling.
+ * Parameters:
+ * w - Window.
+ * wi - Pointer to the scrollbar widget.
+ * x - The X coordinate of the mouse click.
+ * y - The Y coordinate of the mouse click.
+ */
+
+void ScrollbarClickHandler(Window *w, const Widget *wi, int x, int y)
+{
+ int mi, ma, pos;
+ Scrollbar *sb;
+
+ switch (wi->type) {
+ case WWT_SCROLLBAR: {
+ // vertical scroller
+ w->flags4 &= ~WF_HSCROLL;
+ w->flags4 &= ~WF_SCROLL2;
+ mi = wi->top;
+ ma = wi->bottom;
+ pos = y;
+ sb = &w->vscroll;
+ break;
+ }
+ case WWT_SCROLL2BAR: {
+ // 2nd vertical scroller
+ w->flags4 &= ~WF_HSCROLL;
+ w->flags4 |= WF_SCROLL2;
+ mi = wi->top;
+ ma = wi->bottom;
+ pos = y;
+ sb = &w->vscroll2;
+ break;
+ }
+ case WWT_HSCROLLBAR: {
+ // horizontal scroller
+ w->flags4 &= ~WF_SCROLL2;
+ w->flags4 |= WF_HSCROLL;
+ mi = wi->left;
+ ma = wi->right;
+ pos = x;
+ sb = &w->hscroll;
+ break;
+ }
+ default: return; //this should never happen
+ }
+ if (pos <= mi+9) {
+ // Pressing the upper button?
+ w->flags4 |= WF_SCROLL_UP;
+ if (_scroller_click_timeout == 0) {
+ _scroller_click_timeout = 6;
+ if (sb->pos != 0) sb->pos--;
+ }
+ _left_button_clicked = false;
+ } else if (pos >= ma-10) {
+ // Pressing the lower button?
+ w->flags4 |= WF_SCROLL_DOWN;
+
+ if (_scroller_click_timeout == 0) {
+ _scroller_click_timeout = 6;
+ if ((byte)(sb->pos + sb->cap) < sb->count)
+ sb->pos++;
+ }
+ _left_button_clicked = false;
+ } else {
+ //
+ Point pt = HandleScrollbarHittest(sb, mi, ma);
+
+ if (pos < pt.x) {
+ sb->pos = max(sb->pos - sb->cap, 0);
+ } else if (pos > pt.y) {
+ sb->pos = min(
+ sb->pos + sb->cap,
+ max(sb->count - sb->cap, 0)
+ );
+ } else {
+ _scrollbar_start_pos = pt.x - mi - 9;
+ _scrollbar_size = ma - mi - 23;
+ w->flags4 |= WF_SCROLL_MIDDLE;
+ _scrolling_scrollbar = true;
+ _cursorpos_drag_start = _cursor.pos;
+ }
+ }
+
+ SetWindowDirty(w);
+}
+
+/** Returns the index for the widget located at the given position
+ * relative to the window. It includes all widget-corner pixels as well.
+ * @param *w Window to look inside
+ * @param x,y Window client coordinates
+ * @return A widget index, or -1 if no widget was found.
+ */
+int GetWidgetFromPos(const Window *w, int x, int y)
+{
+ uint index;
+ int found_index = -1;
+
+ // Go through the widgets and check if we find the widget that the coordinate is
+ // inside.
+ for (index = 0; index < w->widget_count; index++) {
+ const Widget *wi = &w->widget[index];
+ if (wi->type == WWT_EMPTY || wi->type == WWT_FRAME) continue;
+
+ if (x >= wi->left && x <= wi->right && y >= wi->top && y <= wi->bottom &&
+ !IsWindowWidgetHidden(w, index)) {
+ found_index = index;
+ }
+ }
+
+ return found_index;
+}
+
+
+void DrawFrameRect(int left, int top, int right, int bottom, int ctab, FrameFlags flags)
+{
+ uint dark = _colour_gradient[ctab][3];
+ uint medium_dark = _colour_gradient[ctab][5];
+ uint medium_light = _colour_gradient[ctab][6];
+ uint light = _colour_gradient[ctab][7];
+
+ if (flags & FR_TRANSPARENT) {
+ GfxFillRect(left, top, right, bottom, 0x322 | USE_COLORTABLE);
+ } else {
+ uint interior;
+
+ if (flags & FR_LOWERED) {
+ GfxFillRect(left, top, left, bottom, dark);
+ GfxFillRect(left + 1, top, right, top, dark);
+ GfxFillRect(right, top + 1, right, bottom - 1, light);
+ GfxFillRect(left + 1, bottom, right, bottom, light);
+ interior = (flags & FR_DARKENED ? medium_dark : medium_light);
+ } else {
+ GfxFillRect(left, top, left, bottom - 1, light);
+ GfxFillRect(left + 1, top, right - 1, top, light);
+ GfxFillRect(right, top, right, bottom - 1, dark);
+ GfxFillRect(left, bottom, right, bottom, dark);
+ interior = medium_dark;
+ }
+ if (!(flags & FR_BORDERONLY)) {
+ GfxFillRect(left + 1, top + 1, right - 1, bottom - 1, interior);
+ }
+ }
+}
+
+
+void DrawWindowWidgets(const Window *w)
+{
+ const DrawPixelInfo* dpi = _cur_dpi;
+ Rect r;
+ uint i;
+
+ for (i = 0; i < w->widget_count; i++) {
+ const Widget *wi = &w->widget[i];
+ bool clicked = IsWindowWidgetLowered(w, i);
+
+ if (dpi->left > (r.right=/*w->left + */wi->right) ||
+ dpi->left + dpi->width <= (r.left=wi->left/* + w->left*/) ||
+ dpi->top > (r.bottom=/*w->top +*/ wi->bottom) ||
+ dpi->top + dpi->height <= (r.top = /*w->top +*/ wi->top) ||
+ IsWindowWidgetHidden(w, i)) {
+ continue;
+ }
+
+ switch (wi->type & WWT_MASK) {
+ case WWT_IMGBTN:
+ case WWT_IMGBTN_2: {
+ int img = wi->data;
+ assert(img != 0);
+ DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->color, (clicked) ? FR_LOWERED : 0);
+
+ /* show different image when clicked for WWT_IMGBTN_2 */
+ if ((wi->type & WWT_MASK) == WWT_IMGBTN_2 && clicked) img++;
+ DrawSprite(img, r.left + 1 + clicked, r.top + 1 + clicked);
+ goto draw_default;
+ }
+
+ case WWT_PANEL: {
+ assert(wi->data == 0);
+ DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->color, (clicked) ? FR_LOWERED : 0);
+ goto draw_default;
+ }
+
+ case WWT_TEXTBTN:
+ case WWT_TEXTBTN_2: {
+ DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->color, (clicked) ? FR_LOWERED : 0);
+ }
+ /* fall through */
+
+ case WWT_LABEL: {
+ StringID str = wi->data;
+
+ if ((wi->type & WWT_MASK) == WWT_TEXTBTN_2 && clicked) str++;
+
+ DrawStringCentered(((r.left + r.right + 1) >> 1) + clicked, ((r.top + r.bottom + 1) >> 1) - 5 + clicked, str, 0);
+ goto draw_default;
+ }
+
+ case WWT_INSET: {
+ StringID str = wi->data;
+ DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->color, FR_LOWERED | FR_DARKENED);
+
+ if (str != STR_NULL) DrawStringTruncated(r.left + 2, r.top + 1, str, 0, r.right - r.left - 10);
+ goto draw_default;
+ }
+
+ case WWT_MATRIX: {
+ int c, d, ctr;
+ int x, amt1, amt2;
+ int color;
+
+ DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->color, (clicked) ? FR_LOWERED : 0);
+
+ c = GB(wi->data, 0, 8);
+ amt1 = (wi->right - wi->left + 1) / c;
+
+ d = GB(wi->data, 8, 8);
+ amt2 = (wi->bottom - wi->top + 1) / d;
+
+ color = _colour_gradient[wi->color & 0xF][6];
+
+ x = r.left;
+ for (ctr = c; ctr > 1; ctr--) {
+ x += amt1;
+ GfxFillRect(x, r.top + 1, x, r.bottom - 1, color);
+ }
+
+ x = r.top;
+ for (ctr = d; ctr > 1; ctr--) {
+ x += amt2;
+ GfxFillRect(r.left + 1, x, r.right - 1, x, color);
+ }
+
+ color = _colour_gradient[wi->color&0xF][4];
+
+ x = r.left - 1;
+ for (ctr = c; ctr > 1; ctr--) {
+ x += amt1;
+ GfxFillRect(x, r.top + 1, x, r.bottom - 1, color);
+ }
+
+ x = r.top - 1;
+ for (ctr = d; ctr > 1; ctr--) {
+ x += amt2;
+ GfxFillRect(r.left+1, x, r.right-1, x, color);
+ }
+
+ goto draw_default;
+ }
+
+ // vertical scrollbar
+ case WWT_SCROLLBAR: {
+ Point pt;
+ int c1,c2;
+
+ assert(r.right - r.left == 11); // XXX - to ensure the same sizes are used everywhere!
+
+ // draw up/down buttons
+ clicked = ((w->flags4 & (WF_SCROLL_UP | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_UP);
+ DrawFrameRect(r.left, r.top, r.right, r.top + 9, wi->color, (clicked) ? FR_LOWERED : 0);
+ DoDrawString(UPARROW, r.left + 2 + clicked, r.top + clicked, 0x10);
+
+ clicked = (((w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_DOWN));
+ DrawFrameRect(r.left, r.bottom - 9, r.right, r.bottom, wi->color, (clicked) ? FR_LOWERED : 0);
+ DoDrawString(DOWNARROW, r.left + 2 + clicked, r.bottom - 9 + clicked, 0x10);
+
+ c1 = _colour_gradient[wi->color&0xF][3];
+ c2 = _colour_gradient[wi->color&0xF][7];
+
+ // draw "shaded" background
+ GfxFillRect(r.left, r.top+10, r.right, r.bottom-10, c2);
+ GfxFillRect(r.left, r.top+10, r.right, r.bottom-10, c1 | PALETTE_MODIFIER_GREYOUT);
+
+ // draw shaded lines
+ GfxFillRect(r.left+2, r.top+10, r.left+2, r.bottom-10, c1);
+ GfxFillRect(r.left+3, r.top+10, r.left+3, r.bottom-10, c2);
+ GfxFillRect(r.left+7, r.top+10, r.left+7, r.bottom-10, c1);
+ GfxFillRect(r.left+8, r.top+10, r.left+8, r.bottom-10, c2);
+
+ pt = HandleScrollbarHittest(&w->vscroll, r.top, r.bottom);
+ DrawFrameRect(r.left, pt.x, r.right, pt.y, wi->color, (w->flags4 & (WF_SCROLL_MIDDLE | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_MIDDLE ? FR_LOWERED : 0);
+ break;
+ }
+ case WWT_SCROLL2BAR: {
+ Point pt;
+ int c1,c2;
+
+ assert(r.right - r.left == 11); // XXX - to ensure the same sizes are used everywhere!
+
+ // draw up/down buttons
+ clicked = ((w->flags4 & (WF_SCROLL_UP | WF_HSCROLL | WF_SCROLL2)) == (WF_SCROLL_UP | WF_SCROLL2));
+ DrawFrameRect(r.left, r.top, r.right, r.top + 9, wi->color, (clicked) ? FR_LOWERED : 0);
+ DoDrawString(UPARROW, r.left + 2 + clicked, r.top + clicked, 0x10);
+
+ clicked = ((w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL | WF_SCROLL2)) == (WF_SCROLL_DOWN | WF_SCROLL2));
+ DrawFrameRect(r.left, r.bottom - 9, r.right, r.bottom, wi->color, (clicked) ? FR_LOWERED : 0);
+ DoDrawString(DOWNARROW, r.left + 2 + clicked, r.bottom - 9 + clicked, 0x10);
+
+ c1 = _colour_gradient[wi->color&0xF][3];
+ c2 = _colour_gradient[wi->color&0xF][7];
+
+ // draw "shaded" background
+ GfxFillRect(r.left, r.top+10, r.right, r.bottom-10, c2);
+ GfxFillRect(r.left, r.top+10, r.right, r.bottom-10, c1 | PALETTE_MODIFIER_GREYOUT);
+
+ // draw shaded lines
+ GfxFillRect(r.left+2, r.top+10, r.left+2, r.bottom-10, c1);
+ GfxFillRect(r.left+3, r.top+10, r.left+3, r.bottom-10, c2);
+ GfxFillRect(r.left+7, r.top+10, r.left+7, r.bottom-10, c1);
+ GfxFillRect(r.left+8, r.top+10, r.left+8, r.bottom-10, c2);
+
+ pt = HandleScrollbarHittest(&w->vscroll2, r.top, r.bottom);
+ DrawFrameRect(r.left, pt.x, r.right, pt.y, wi->color, (w->flags4 & (WF_SCROLL_MIDDLE | WF_HSCROLL | WF_SCROLL2)) == (WF_SCROLL_MIDDLE | WF_SCROLL2) ? FR_LOWERED : 0);
+ break;
+ }
+
+ // horizontal scrollbar
+ case WWT_HSCROLLBAR: {
+ Point pt;
+ int c1,c2;
+
+ assert(r.bottom - r.top == 11); // XXX - to ensure the same sizes are used everywhere!
+
+ clicked = ((w->flags4 & (WF_SCROLL_UP | WF_HSCROLL)) == (WF_SCROLL_UP | WF_HSCROLL));
+ DrawFrameRect(r.left, r.top, r.left + 9, r.bottom, wi->color, (clicked) ? FR_LOWERED : 0);
+ DrawSprite(SPR_ARROW_LEFT, r.left + 1 + clicked, r.top + 1 + clicked);
+
+ clicked = ((w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL)) == (WF_SCROLL_DOWN | WF_HSCROLL));
+ DrawFrameRect(r.right-9, r.top, r.right, r.bottom, wi->color, (clicked) ? FR_LOWERED : 0);
+ DrawSprite(SPR_ARROW_RIGHT, r.right - 8 + clicked, r.top + 1 + clicked);
+
+ c1 = _colour_gradient[wi->color&0xF][3];
+ c2 = _colour_gradient[wi->color&0xF][7];
+
+ // draw "shaded" background
+ GfxFillRect(r.left+10, r.top, r.right-10, r.bottom, c2);
+ GfxFillRect(r.left+10, r.top, r.right-10, r.bottom, c1 | PALETTE_MODIFIER_GREYOUT);
+
+ // draw shaded lines
+ GfxFillRect(r.left+10, r.top+2, r.right-10, r.top+2, c1);
+ GfxFillRect(r.left+10, r.top+3, r.right-10, r.top+3, c2);
+ GfxFillRect(r.left+10, r.top+7, r.right-10, r.top+7, c1);
+ GfxFillRect(r.left+10, r.top+8, r.right-10, r.top+8, c2);
+
+ // draw actual scrollbar
+ pt = HandleScrollbarHittest(&w->hscroll, r.left, r.right);
+ DrawFrameRect(pt.x, r.top, pt.y, r.bottom, wi->color, (w->flags4 & (WF_SCROLL_MIDDLE | WF_HSCROLL)) == (WF_SCROLL_MIDDLE | WF_HSCROLL) ? FR_LOWERED : 0);
+
+ break;
+ }
+
+ case WWT_FRAME: {
+ int c1,c2;
+ int x2 = r.left; // by default the left side is the left side of the widget
+
+ if (wi->data != 0) x2 = DrawString(r.left + 6, r.top, wi->data, 0);
+
+ c1 = _colour_gradient[wi->color][3];
+ c2 = _colour_gradient[wi->color][7];
+
+ //Line from upper left corner to start of text
+ GfxFillRect(r.left, r.top+4, r.left+4,r.top+4, c1);
+ GfxFillRect(r.left+1, r.top+5, r.left+4,r.top+5, c2);
+
+ // Line from end of text to upper right corner
+ GfxFillRect(x2, r.top+4, r.right-1,r.top+4,c1);
+ GfxFillRect(x2, r.top+5, r.right-2,r.top+5,c2);
+
+ // Line from upper left corner to bottom left corner
+ GfxFillRect(r.left, r.top+5, r.left, r.bottom-1, c1);
+ GfxFillRect(r.left+1, r.top+6, r.left+1, r.bottom-2, c2);
+
+ //Line from upper right corner to bottom right corner
+ GfxFillRect(r.right-1, r.top+5, r.right-1, r.bottom-2, c1);
+ GfxFillRect(r.right, r.top+4, r.right, r.bottom-1, c2);
+
+ GfxFillRect(r.left+1, r.bottom-1, r.right-1, r.bottom-1, c1);
+ GfxFillRect(r.left, r.bottom, r.right, r.bottom, c2);
+
+ goto draw_default;
+ }
+
+ case WWT_STICKYBOX: {
+ assert(r.right - r.left == 11); // XXX - to ensure the same sizes are used everywhere!
+
+ clicked = !!(w->flags4 & WF_STICKY);
+ DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->color, (clicked) ? FR_LOWERED : 0);
+ DrawSprite((clicked) ? SPR_PIN_UP : SPR_PIN_DOWN, r.left + 2 + clicked, r.top + 3 + clicked);
+ break;
+ }
+
+ case WWT_RESIZEBOX: {
+ assert(r.right - r.left == 11); // XXX - to ensure the same sizes are used everywhere!
+
+ clicked = !!(w->flags4 & WF_SIZING);
+ DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->color, (clicked) ? FR_LOWERED : 0);
+ DrawSprite(SPR_WINDOW_RESIZE, r.left + 3 + clicked, r.top + 3 + clicked);
+ break;
+ }
+
+ case WWT_CLOSEBOX: {
+ assert(r.right - r.left == 10); // ensure the same sizes are used everywhere
+
+ DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->color, 0);
+ DrawString(r.left + 2, r.top + 2, STR_00C5, 0);
+ break;
+ }
+
+ case WWT_CAPTION: {
+ assert(r.bottom - r.top == 13); // XXX - to ensure the same sizes are used everywhere!
+ DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->color, FR_BORDERONLY);
+ DrawFrameRect(r.left+1, r.top+1, r.right-1, r.bottom-1, wi->color, (w->caption_color == 0xFF) ? FR_LOWERED | FR_DARKENED : FR_LOWERED | FR_DARKENED | FR_BORDERONLY);
+
+ if (w->caption_color != 0xFF) {
+ GfxFillRect(r.left+2, r.top+2, r.right-2, r.bottom-2, _colour_gradient[_player_colors[w->caption_color]][4]);
+ }
+
+ DrawStringCenteredTruncated(r.left + 2, r.right - 2, r.top+2, wi->data, 0x84);
+draw_default:;
+ if (IsWindowWidgetDisabled(w, i)) {
+ GfxFillRect(r.left+1, r.top+1, r.right-1, r.bottom-1, _colour_gradient[wi->color&0xF][2] | PALETTE_MODIFIER_GREYOUT);
+ }
+ }
+ }
+ }
+
+
+ if (w->flags4 & WF_WHITE_BORDER_MASK) {
+ //DrawFrameRect(w->left, w->top, w->left + w->width-1, w->top+w->height-1, 0xF, 0x10);
+ DrawFrameRect(0, 0, w->width-1, w->height-1, 0xF, FR_BORDERONLY);
+ }
+
+}
+
+static const Widget _dropdown_menu_widgets[] = {
+{ WWT_PANEL, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL},
+{ WWT_SCROLLBAR, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WIDGETS_END},
+};
+
+static int GetDropdownItem(const Window *w)
+{
+ byte item, counter;
+ int y;
+
+ if (GetWidgetFromPos(w, _cursor.pos.x - w->left, _cursor.pos.y - w->top) < 0)
+ return -1;
+
+ y = _cursor.pos.y - w->top - 2 + w->vscroll.pos * 10;
+
+ if (y < 0)
+ return - 1;
+
+ item = y / 10;
+ if (item >= WP(w,dropdown_d).num_items || (HASBIT(WP(w,dropdown_d).disabled_state, item) && !HASBIT(WP(w,dropdown_d).hidden_state, item)) || WP(w,dropdown_d).items[item] == 0)
+ return - 1;
+
+ // Skip hidden items -- +1 for each hidden item before the clicked item.
+ for (counter = 0; item >= counter; ++counter)
+ if (HASBIT(WP(w,dropdown_d).hidden_state, counter)) item++;
+
+ return item;
+}
+
+static void DropdownMenuWndProc(Window *w, WindowEvent *e)
+{
+ int item;
+
+ switch (e->event) {
+ case WE_PAINT: {
+ int x,y,i,sel;
+ int width, height;
+
+ DrawWindowWidgets(w);
+
+ x = 1;
+ y = 2 - w->vscroll.pos * 10;
+
+ sel = WP(w,dropdown_d).selected_index;
+ width = w->widget[0].right - 3;
+ height = w->widget[0].bottom - 3;
+
+ for (i = 0; WP(w,dropdown_d).items[i] != INVALID_STRING_ID; i++, sel--) {
+ if (HASBIT(WP(w,dropdown_d).hidden_state, i)) continue;
+
+ if (y >= 0 && y <= height) {
+ if (WP(w,dropdown_d).items[i] != STR_NULL) {
+ if (sel == 0) GfxFillRect(x + 1, y, x + width, y + 9, 0);
+ DrawStringTruncated(x + 2, y, WP(w,dropdown_d).items[i], sel == 0 ? 12 : 16, x + width);
+
+ if (HASBIT(WP(w,dropdown_d).disabled_state, i)) {
+ GfxFillRect(x, y, x + width, y + 9,
+ PALETTE_MODIFIER_GREYOUT | _colour_gradient[_dropdown_menu_widgets[0].color][5]
+ );
+ }
+ } else {
+ int c1 = _colour_gradient[_dropdown_menu_widgets[0].color][3];
+ int c2 = _colour_gradient[_dropdown_menu_widgets[0].color][7];
+
+ GfxFillRect(x + 1, y + 3, x + w->width - 5, y + 3, c1);
+ GfxFillRect(x + 1, y + 4, x + w->width - 5, y + 4, c2);
+ }
+ }
+ y += 10;
+ }
+ } break;
+
+ case WE_CLICK: {
+ if (e->we.click.widget != 0) break;
+ item = GetDropdownItem(w);
+ if (item >= 0) {
+ WP(w,dropdown_d).click_delay = 4;
+ WP(w,dropdown_d).selected_index = item;
+ SetWindowDirty(w);
+ }
+ } break;
+
+ case WE_MOUSELOOP: {
+ Window *w2 = FindWindowById(WP(w,dropdown_d).parent_wnd_class, WP(w,dropdown_d).parent_wnd_num);
+ if (w2 == NULL) {
+ DeleteWindow(w);
+ return;
+ }
+
+ if (WP(w,dropdown_d).click_delay != 0 && --WP(w,dropdown_d).click_delay == 0) {
+ WindowEvent e;
+ e.event = WE_DROPDOWN_SELECT;
+ e.we.dropdown.button = WP(w,dropdown_d).parent_button;
+ e.we.dropdown.index = WP(w,dropdown_d).selected_index;
+ w2->wndproc(w2, &e);
+ DeleteWindow(w);
+ return;
+ }
+
+ if (WP(w,dropdown_d).drag_mode) {
+ item = GetDropdownItem(w);
+
+ if (!_left_button_clicked) {
+ WP(w,dropdown_d).drag_mode = false;
+ if (item < 0) return;
+ WP(w,dropdown_d).click_delay = 2;
+ } else {
+ if (item < 0) return;
+ }
+
+ WP(w,dropdown_d).selected_index = item;
+ SetWindowDirty(w);
+ }
+ } break;
+
+ case WE_DESTROY: {
+ Window *w2 = FindWindowById(WP(w,dropdown_d).parent_wnd_class, WP(w,dropdown_d).parent_wnd_num);
+ if (w2 != NULL) {
+ RaiseWindowWidget(w2, WP(w,dropdown_d).parent_button);
+ InvalidateWidget(w2, WP(w,dropdown_d).parent_button);
+ }
+ } break;
+ }
+}
+
+void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int button, uint32 disabled_mask, uint32 hidden_mask)
+{
+ int i;
+ const Widget *wi;
+ Window *w2;
+ const Window *w3;
+ bool is_dropdown_menu_shown = IsWindowWidgetLowered(w, button);
+ int top, height;
+ int screen_top, screen_bottom;
+ bool scroll = false;
+
+ DeleteWindowById(WC_DROPDOWN_MENU, 0);
+
+ if (is_dropdown_menu_shown) return;
+
+ LowerWindowWidget(w, button);
+
+ InvalidateWidget(w, button);
+
+ for (i = 0; strings[i] != INVALID_STRING_ID; i++) {}
+ if (i == 0) return;
+
+ wi = &w->widget[button];
+
+ if (hidden_mask != 0) {
+ uint j;
+
+ for (j = 0; strings[j] != INVALID_STRING_ID; j++) {
+ if (HASBIT(hidden_mask, j)) i--;
+ }
+ }
+
+ /* The preferred position is just below the dropdown calling widget */
+ top = w->top + wi->bottom + 2;
+ height = i * 10 + 4;
+
+ w3 = FindWindowById(WC_STATUS_BAR, 0);
+ screen_bottom = w3 == NULL ? _screen.height : w3->top;
+
+ /* Check if the dropdown will fully fit below the widget */
+ if (top + height >= screen_bottom) {
+ w3 = FindWindowById(WC_MAIN_TOOLBAR, 0);
+ screen_top = w3 == NULL ? 0 : w3->top + w3->height;
+
+ /* If not, check if it will fit above the widget */
+ if (w->top + wi->top - height - 1 > screen_top) {
+ top = w->top + wi->top - height - 1;
+ } else {
+ /* ... and lastly if it won't, enable the scroll bar and fit the
+ * list in below the widget */
+ int rows = (screen_bottom - 4 - top) / 10;
+ height = rows * 10 + 4;
+ scroll = true;
+ }
+ }
+
+ w2 = AllocateWindow(
+ w->left + wi[-1].left + 1,
+ top,
+ wi->right - wi[-1].left + 1,
+ height,
+ DropdownMenuWndProc,
+ WC_DROPDOWN_MENU,
+ _dropdown_menu_widgets);
+
+ w2->widget[0].color = wi->color;
+ w2->widget[0].right = wi->right - wi[-1].left;
+ w2->widget[0].bottom = height - 1;
+
+ SetWindowWidgetHiddenState(w2, 1, !scroll);
+
+ if (scroll) {
+ /* We're scrolling, so enable the scroll bar and shrink the list by
+ * the scrollbar's width */
+ w2->widget[1].color = wi->color;
+ w2->widget[1].right = w2->widget[0].right;
+ w2->widget[1].left = w2->widget[1].right - 11;
+ w2->widget[1].bottom = height - 1;
+ w2->widget[0].right -= 12;
+
+ w2->vscroll.cap = (height - 4) / 10;
+ w2->vscroll.count = i;
+ }
+
+ w2->desc_flags = WDF_DEF_WIDGET;
+ w2->flags4 &= ~WF_WHITE_BORDER_MASK;
+
+ WP(w2,dropdown_d).disabled_state = disabled_mask;
+ WP(w2,dropdown_d).hidden_state = hidden_mask;
+
+ WP(w2,dropdown_d).parent_wnd_class = w->window_class;
+ WP(w2,dropdown_d).parent_wnd_num = w->window_number;
+ WP(w2,dropdown_d).parent_button = button;
+
+ WP(w2,dropdown_d).num_items = i;
+ WP(w2,dropdown_d).selected_index = selected;
+ WP(w2,dropdown_d).items = strings;
+
+ WP(w2,dropdown_d).click_delay = 0;
+ WP(w2,dropdown_d).drag_mode = true;
+}
diff --git a/src/win32.c b/src/win32.c
new file mode 100644
index 000000000..a0a3d05b4
--- /dev/null
+++ b/src/win32.c
@@ -0,0 +1,1140 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "debug.h"
+#include "functions.h"
+#include "macros.h"
+#include "saveload.h"
+#include "string.h"
+#include "gfx.h"
+#include "window.h"
+#include <windows.h>
+#include <winnt.h>
+#include <wininet.h>
+#include <io.h>
+#include <fcntl.h>
+#include <shlobj.h> // SHGetFolderPath
+#include "variables.h"
+#include "win32.h"
+#include "fios.h" // opendir/readdir/closedir
+#include <ctype.h>
+#include <tchar.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+static bool _has_console;
+
+#if defined(__MINGW32__)
+ #include <stdint.h>
+#endif
+
+static bool cursor_visible = true;
+
+bool MyShowCursor(bool show)
+{
+ if (cursor_visible == show) return show;
+
+ cursor_visible = show;
+ ShowCursor(show);
+
+ return !show;
+}
+
+/** Helper function needed by dynamically loading libraries
+ * XXX: Hurray for MS only having an ANSI GetProcAddress function
+ * on normal windows and no Wide version except for in Windows Mobile/CE */
+bool LoadLibraryList(Function proc[], const char *dll)
+{
+ while (*dll != '\0') {
+ HMODULE lib;
+ lib = LoadLibrary(MB_TO_WIDE(dll));
+
+ if (lib == NULL) return false;
+ for (;;) {
+ FARPROC p;
+
+ while (*dll++ != '\0');
+ if (*dll == '\0') break;
+#if defined(WINCE)
+ p = GetProcAddress(lib, MB_TO_WIDE(dll);
+#else
+ p = GetProcAddress(lib, dll);
+#endif
+ if (p == NULL) return false;
+ *proc++ = (Function)p;
+ }
+ dll++;
+ }
+ return true;
+}
+
+#ifdef _MSC_VER
+static const char *_exception_string = NULL;
+#endif
+
+void ShowOSErrorBox(const char *buf)
+{
+ MyShowCursor(true);
+ MessageBox(GetActiveWindow(), MB_TO_WIDE(buf), _T("Error!"), MB_ICONSTOP);
+
+// if exception tracker is enabled, we crash here to let the exception handler handle it.
+#if defined(WIN32_EXCEPTION_TRACKER) && !defined(_DEBUG)
+ if (*buf == '!') {
+ _exception_string = buf;
+ *(byte*)0 = 0;
+ }
+#endif
+}
+
+#ifdef _MSC_VER
+
+static void *_safe_esp;
+static char *_crash_msg;
+static bool _expanded;
+static bool _did_emerg_save;
+static int _ident;
+
+typedef struct DebugFileInfo {
+ uint32 size;
+ uint32 crc32;
+ SYSTEMTIME file_time;
+} DebugFileInfo;
+
+static uint32 *_crc_table;
+
+static void MakeCRCTable(uint32 *table) {
+ uint32 crc, poly = 0xEDB88320L;
+ int i;
+ int j;
+
+ _crc_table = table;
+
+ for (i = 0; i != 256; i++) {
+ crc = i;
+ for (j = 8; j != 0; j--) {
+ crc = (crc & 1 ? (crc >> 1) ^ poly : crc >> 1);
+ }
+ table[i] = crc;
+ }
+}
+
+static uint32 CalcCRC(byte *data, uint size, uint32 crc) {
+ for (; size > 0; size--) {
+ crc = ((crc >> 8) & 0x00FFFFFF) ^ _crc_table[(crc ^ *data++) & 0xFF];
+ }
+ return crc;
+}
+
+static void GetFileInfo(DebugFileInfo *dfi, const TCHAR *filename)
+{
+ HANDLE file;
+ memset(dfi, 0, sizeof(dfi));
+
+ file = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
+ if (file != INVALID_HANDLE_VALUE) {
+ byte buffer[1024];
+ DWORD numread;
+ uint32 filesize = 0;
+ FILETIME write_time;
+ uint32 crc = (uint32)-1;
+
+ for (;;) {
+ if (ReadFile(file, buffer, sizeof(buffer), &numread, NULL) == 0 || numread == 0)
+ break;
+ filesize += numread;
+ crc = CalcCRC(buffer, numread, crc);
+ }
+ dfi->size = filesize;
+ dfi->crc32 = crc ^ (uint32)-1;
+
+ if (GetFileTime(file, NULL, NULL, &write_time)) {
+ FileTimeToSystemTime(&write_time, &dfi->file_time);
+ }
+ CloseHandle(file);
+ }
+}
+
+
+static char *PrintModuleInfo(char *output, HMODULE mod)
+{
+ TCHAR buffer[MAX_PATH];
+ DebugFileInfo dfi;
+
+ GetModuleFileName(mod, buffer, MAX_PATH);
+ GetFileInfo(&dfi, buffer);
+ output += sprintf(output, " %-20s handle: %p size: %d crc: %.8X date: %d-%.2d-%.2d %.2d:%.2d:%.2d\r\n",
+ WIDE_TO_MB(buffer),
+ mod,
+ dfi.size,
+ dfi.crc32,
+ dfi.file_time.wYear,
+ dfi.file_time.wMonth,
+ dfi.file_time.wDay,
+ dfi.file_time.wHour,
+ dfi.file_time.wMinute,
+ dfi.file_time.wSecond
+ );
+ return output;
+}
+
+static char *PrintModuleList(char *output)
+{
+ BOOL (WINAPI *EnumProcessModules)(HANDLE, HMODULE*, DWORD, LPDWORD);
+
+ if (LoadLibraryList((Function*)&EnumProcessModules, "psapi.dll\0EnumProcessModules\0\0")) {
+ HMODULE modules[100];
+ DWORD needed;
+ BOOL res;
+ int count, i;
+
+ HANDLE proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
+ if (proc != NULL) {
+ res = EnumProcessModules(proc, modules, sizeof(modules), &needed);
+ CloseHandle(proc);
+ if (res) {
+ count = min(needed / sizeof(HMODULE), lengthof(modules));
+
+ for (i = 0; i != count; i++) output = PrintModuleInfo(output, modules[i]);
+ return output;
+ }
+ }
+ }
+ output = PrintModuleInfo(output, NULL);
+ return output;
+}
+
+static const TCHAR _crash_desc[] =
+ _T("A serious fault condition occured in the game. The game will shut down.\n")
+ _T("Press \"Submit report\" to send crash information to the developers. ")
+ _T("This will greatly help debugging. ")
+ _T("The information contained in the report is displayed below.\n")
+ _T("Press \"Emergency save\" to attempt saving the game.");
+
+static const TCHAR _save_succeeded[] =
+ _T("Emergency save succeeded.\n")
+ _T("Be aware that critical parts of the internal game state may have become ")
+ _T("corrupted. The saved game is not guaranteed to work.");
+
+static bool EmergencySave(void)
+{
+ SaveOrLoad("crash.sav", SL_SAVE);
+ return true;
+}
+
+/* Disable the crash-save submit code as it's not used */
+#if 0
+
+typedef struct {
+ HINTERNET (WINAPI *InternetOpen)(LPCTSTR,DWORD, LPCTSTR, LPCTSTR, DWORD);
+ HINTERNET (WINAPI *InternetConnect)(HINTERNET, LPCTSTR, INTERNET_PORT, LPCTSTR, LPCTSTR, DWORD, DWORD, DWORD);
+ HINTERNET (WINAPI *HttpOpenRequest)(HINTERNET, LPCTSTR, LPCTSTR, LPCTSTR, LPCTSTR, LPCTSTR *, DWORD, DWORD);
+ BOOL (WINAPI *HttpSendRequest)(HINTERNET, LPCTSTR, DWORD, LPVOID, DWORD);
+ BOOL (WINAPI *InternetCloseHandle)(HINTERNET);
+ BOOL (WINAPI *HttpQueryInfo)(HINTERNET, DWORD, LPVOID, LPDWORD, LPDWORD);
+} WinInetProcs;
+
+#define M(x) x "\0"
+#if defined(UNICODE)
+# define W(x) x "W"
+#else
+# define W(x) x "A"
+#endif
+static const char wininet_files[] =
+ M("wininet.dll")
+ M(W("InternetOpen"))
+ M(W("InternetConnect"))
+ M(W("HttpOpenRequest"))
+ M(W("HttpSendRequest"))
+ M("InternetCloseHandle")
+ M(W("HttpQueryInfo"))
+ M("");
+#undef W
+#undef M
+
+static WinInetProcs _wininet;
+
+static const TCHAR *SubmitCrashReport(HWND wnd, void *msg, size_t msglen, const TCHAR *arg)
+{
+ HINTERNET inet, conn, http;
+ const TCHAR *err = NULL;
+ DWORD code, len;
+ static TCHAR buf[100];
+ TCHAR buff[100];
+
+ if (_wininet.InternetOpen == NULL && !LoadLibraryList((Function*)&_wininet, wininet_files)) return _T("can't load wininet.dll");
+
+ inet = _wininet.InternetOpen(_T("OTTD"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 );
+ if (inet == NULL) { err = _T("internetopen failed"); goto error1; }
+
+ conn = _wininet.InternetConnect(inet, _T("www.openttd.org"), INTERNET_DEFAULT_HTTP_PORT, _T(""), _T(""), INTERNET_SERVICE_HTTP, 0, 0);
+ if (conn == NULL) { err = _T("internetconnect failed"); goto error2; }
+
+ _sntprintf(buff, lengthof(buff), _T("/crash.php?file=%s&ident=%d"), arg, _ident);
+
+ http = _wininet.HttpOpenRequest(conn, _T("POST"), buff, NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE , 0);
+ if (http == NULL) { err = _T("httpopenrequest failed"); goto error3; }
+
+ if (!_wininet.HttpSendRequest(http, _T("Content-type: application/binary"), -1, msg, (DWORD)msglen)) { err = _T("httpsendrequest failed"); goto error4; }
+
+ len = sizeof(code);
+ if (!_wininet.HttpQueryInfo(http, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &code, &len, 0)) { err = _T("httpqueryinfo failed"); goto error4; }
+
+ if (code != 200) {
+ int l = _sntprintf(buf, lengthof(buf), _T("Server said: %d "), code);
+ len = sizeof(buf) - l;
+ _wininet.HttpQueryInfo(http, HTTP_QUERY_STATUS_TEXT, buf + l, &len, 0);
+ err = buf;
+ }
+
+error4:
+ _wininet.InternetCloseHandle(http);
+error3:
+ _wininet.InternetCloseHandle(conn);
+error2:
+ _wininet.InternetCloseHandle(inet);
+error1:
+ return err;
+}
+
+static void SubmitFile(HWND wnd, const TCHAR *file)
+{
+ HANDLE h;
+ unsigned long size;
+ unsigned long read;
+ void *mem;
+
+ h = CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
+ if (h == NULL) return;
+
+ size = GetFileSize(h, NULL);
+ if (size > 500000) goto error1;
+
+ mem = malloc(size);
+ if (mem == NULL) goto error1;
+
+ if (!ReadFile(h, mem, size, &read, NULL) || read != size) goto error2;
+
+ SubmitCrashReport(wnd, mem, size, file);
+
+error2:
+ free(mem);
+error1:
+ CloseHandle(h);
+}
+
+#endif /* Disabled crash-submit procedures */
+
+static const TCHAR * const _expand_texts[] = {_T("S&how report >>"), _T("&Hide report <<") };
+
+static void SetWndSize(HWND wnd, int mode)
+{
+ RECT r,r2;
+ int offs;
+
+ GetWindowRect(wnd, &r);
+
+ SetDlgItemText(wnd, 15, _expand_texts[mode == 1]);
+
+ if (mode >= 0) {
+ GetWindowRect(GetDlgItem(wnd, 11), &r2);
+ offs = r2.bottom - r2.top + 10;
+ if (!mode) offs = -offs;
+ SetWindowPos(wnd, HWND_TOPMOST, 0, 0,
+ r.right - r.left, r.bottom - r.top + offs, SWP_NOMOVE | SWP_NOZORDER);
+ } else {
+ SetWindowPos(wnd, HWND_TOPMOST,
+ (GetSystemMetrics(SM_CXSCREEN) - (r.right - r.left)) / 2,
+ (GetSystemMetrics(SM_CYSCREEN) - (r.bottom - r.top)) / 2,
+ 0, 0, SWP_NOSIZE);
+ }
+}
+
+static bool DoEmergencySave(HWND wnd)
+{
+ bool b = false;
+
+ EnableWindow(GetDlgItem(wnd, 13), FALSE);
+ _did_emerg_save = true;
+ __try {
+ b = EmergencySave();
+ } __except (1) {}
+ return b;
+}
+
+static INT_PTR CALLBACK CrashDialogFunc(HWND wnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ switch (msg) {
+ case WM_INITDIALOG: {
+#if defined(UNICODE)
+ /* We need to put the crash-log in a seperate buffer because the default
+ * buffer in MB_TO_WIDE is not large enough (256 chars) */
+ wchar_t crash_msgW[8096];
+#endif
+ SetDlgItemText(wnd, 10, _crash_desc);
+ SetDlgItemText(wnd, 11, MB_TO_WIDE_BUFFER(_crash_msg, crash_msgW, lengthof(crash_msgW)));
+ SendDlgItemMessage(wnd, 11, WM_SETFONT, (WPARAM)GetStockObject(ANSI_FIXED_FONT), FALSE);
+ SetWndSize(wnd, -1);
+ } return TRUE;
+ case WM_COMMAND:
+ switch (wParam) {
+ case 12: /* Close */
+ ExitProcess(0);
+ case 13: /* Emergency save */
+ if (DoEmergencySave(wnd)) {
+ MessageBox(wnd, _save_succeeded, _T("Save successful"), MB_ICONINFORMATION);
+ } else {
+ MessageBox(wnd, _T("Save failed"), _T("Save failed"), MB_ICONINFORMATION);
+ }
+ break;
+/* Disable the crash-save submit code as it's not used */
+#if 0
+ case 14: { /* Submit crash report */
+ const TCHAR *s;
+
+ SetCursor(LoadCursor(NULL, IDC_WAIT));
+
+ s = SubmitCrashReport(wnd, _crash_msg, strlen(_crash_msg), _T(""));
+ if (s != NULL) {
+ MessageBox(wnd, s, _T("Error"), MB_ICONSTOP);
+ break;
+ }
+
+ // try to submit emergency savegame
+ if (_did_emerg_save || DoEmergencySave(wnd)) SubmitFile(wnd, _T("crash.sav"));
+
+ // try to submit the autosaved game
+ if (_opt.autosave) {
+ TCHAR buf[40];
+ _sntprintf(buf, lengthof(buf), _T("autosave%d.sav"), (_autosave_ctr - 1) & 3);
+ SubmitFile(wnd, buf);
+ }
+ EnableWindow(GetDlgItem(wnd, 14), FALSE);
+ SetCursor(LoadCursor(NULL, IDC_ARROW));
+ MessageBox(wnd, _T("Crash report submitted. Thank you."), _T("Crash Report"), MB_ICONINFORMATION);
+ } break;
+#endif /* Disabled crash-submit procedures */
+ case 15: /* Expand window to show crash-message */
+ _expanded ^= 1;
+ SetWndSize(wnd, _expanded);
+ break;
+ }
+ return TRUE;
+ case WM_CLOSE: ExitProcess(0);
+ }
+
+ return FALSE;
+}
+
+static void Handler2(void)
+{
+ ShowCursor(TRUE);
+ ShowWindow(GetActiveWindow(), FALSE);
+ DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(100), NULL, CrashDialogFunc);
+}
+
+extern bool CloseConsoleLogIfActive(void);
+
+static LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS *ep)
+{
+ extern const char _openttd_revision[];
+ char *output;
+ static bool had_exception = false;
+
+ if (had_exception) ExitProcess(0);
+ had_exception = true;
+
+ _ident = GetTickCount(); // something pretty unique
+
+ MakeCRCTable(alloca(256 * sizeof(uint32)));
+ _crash_msg = output = LocalAlloc(LMEM_FIXED, 8192);
+
+ {
+ SYSTEMTIME time;
+ GetLocalTime(&time);
+ output += sprintf(output,
+ "*** OpenTTD Crash Report ***\r\n"
+ "Date: %d-%.2d-%.2d %.2d:%.2d:%.2d\r\n"
+ "Build: %s built on " __DATE__ " " __TIME__ "\r\n",
+ time.wYear,
+ time.wMonth,
+ time.wDay,
+ time.wHour,
+ time.wMinute,
+ time.wSecond,
+ _openttd_revision
+ );
+ }
+
+ if (_exception_string)
+ output += sprintf(output, "Reason: %s\r\n", _exception_string);
+
+#ifdef _M_AMD64
+ output += sprintf(output, "Exception %.8X at %.16IX\r\n"
+ "Registers:\r\n"
+ "RAX: %.16llX RBX: %.16llX RCX: %.16llX RDX: %.16llX\r\n"
+ "RSI: %.16llX RDI: %.16llX RBP: %.16llX RSP: %.16llX\r\n"
+ "R8: %.16llX R9: %.16llX R10: %.16llX R11: %.16llX\r\n"
+ "R12: %.16llX R13: %.16llX R14: %.16llX R15: %.16llX\r\n"
+ "RIP: %.16llX EFLAGS: %.8X\r\n"
+ "\r\nBytes at CS:RIP:\r\n",
+ ep->ExceptionRecord->ExceptionCode,
+ ep->ExceptionRecord->ExceptionAddress,
+ ep->ContextRecord->Rax,
+ ep->ContextRecord->Rbx,
+ ep->ContextRecord->Rcx,
+ ep->ContextRecord->Rdx,
+ ep->ContextRecord->Rsi,
+ ep->ContextRecord->Rdi,
+ ep->ContextRecord->Rbp,
+ ep->ContextRecord->Rsp,
+ ep->ContextRecord->R8,
+ ep->ContextRecord->R9,
+ ep->ContextRecord->R10,
+ ep->ContextRecord->R11,
+ ep->ContextRecord->R12,
+ ep->ContextRecord->R13,
+ ep->ContextRecord->R14,
+ ep->ContextRecord->R15,
+ ep->ContextRecord->Rip,
+ ep->ContextRecord->EFlags
+ );
+#else
+ output += sprintf(output, "Exception %.8X at %.8X\r\n"
+ "Registers:\r\n"
+ " EAX: %.8X EBX: %.8X ECX: %.8X EDX: %.8X\r\n"
+ " ESI: %.8X EDI: %.8X EBP: %.8X ESP: %.8X\r\n"
+ " EIP: %.8X EFLAGS: %.8X\r\n"
+ "\r\nBytes at CS:EIP:\r\n",
+ ep->ExceptionRecord->ExceptionCode,
+ ep->ExceptionRecord->ExceptionAddress,
+ ep->ContextRecord->Eax,
+ ep->ContextRecord->Ebx,
+ ep->ContextRecord->Ecx,
+ ep->ContextRecord->Edx,
+ ep->ContextRecord->Esi,
+ ep->ContextRecord->Edi,
+ ep->ContextRecord->Ebp,
+ ep->ContextRecord->Esp,
+ ep->ContextRecord->Eip,
+ ep->ContextRecord->EFlags
+ );
+#endif
+
+ {
+#ifdef _M_AMD64
+ byte *b = (byte*)ep->ContextRecord->Rip;
+#else
+ byte *b = (byte*)ep->ContextRecord->Eip;
+#endif
+ int i;
+ for (i = 0; i != 24; i++) {
+ if (IsBadReadPtr(b, 1)) {
+ output += sprintf(output, " ??"); // OCR: WAS: , 0);
+ } else {
+ output += sprintf(output, " %.2X", *b);
+ }
+ b++;
+ }
+ output += sprintf(output,
+ "\r\n"
+ "\r\nStack trace: \r\n"
+ );
+ }
+
+ {
+ int i,j;
+#ifdef _M_AMD64
+ uint32 *b = (uint32*)ep->ContextRecord->Rsp;
+#else
+ uint32 *b = (uint32*)ep->ContextRecord->Esp;
+#endif
+ for (j = 0; j != 24; j++) {
+ for (i = 0; i != 8; i++) {
+ if (IsBadReadPtr(b,sizeof(uint32))) {
+ output += sprintf(output, " ????????"); //OCR: WAS - , 0);
+ } else {
+ output += sprintf(output, " %.8X", *b);
+ }
+ b++;
+ }
+ output += sprintf(output, "\r\n");
+ }
+ }
+
+ output += sprintf(output, "\r\nModule information:\r\n");
+ output = PrintModuleList(output);
+
+ {
+ OSVERSIONINFO os;
+ os.dwOSVersionInfoSize = sizeof(os);
+ GetVersionEx(&os);
+ output += sprintf(output, "\r\nSystem information:\r\n"
+ " Windows version %d.%d %d %s\r\n",
+ os.dwMajorVersion, os.dwMinorVersion, os.dwBuildNumber, os.szCSDVersion);
+ }
+
+ {
+ HANDLE file = CreateFile(_T("crash.log"), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
+ DWORD num_written;
+ if (file != INVALID_HANDLE_VALUE) {
+ WriteFile(file, _crash_msg, output - _crash_msg, &num_written, NULL);
+ CloseHandle(file);
+ }
+ }
+
+ /* Close any possible log files */
+ CloseConsoleLogIfActive();
+
+ if (_safe_esp) {
+#ifdef _M_AMD64
+ ep->ContextRecord->Rip = (DWORD64)Handler2;
+ ep->ContextRecord->Rsp = (DWORD64)_safe_esp;
+#else
+ ep->ContextRecord->Eip = (DWORD)Handler2;
+ ep->ContextRecord->Esp = (DWORD)_safe_esp;
+#endif
+ return EXCEPTION_CONTINUE_EXECUTION;
+ }
+
+
+ return EXCEPTION_EXECUTE_HANDLER;
+}
+
+static void Win32InitializeExceptions(void)
+{
+#ifdef _M_AMD64
+ extern void *_get_save_esp(void);
+ _safe_esp = _get_save_esp();
+#else
+ _asm {
+ mov _safe_esp, esp
+ }
+#endif
+
+ SetUnhandledExceptionFilter(ExceptionHandler);
+}
+#endif /* _MSC_VER */
+
+/* Code below for windows version of opendir/readdir/closedir copied and
+ * modified from Jan Wassenberg's GPL implementation posted over at
+ * http://www.gamedev.net/community/forums/topic.asp?topic_id=364584&whichpage=1&#2398903 */
+
+/* suballocator - satisfies most requests with a reusable static instance.
+ * this avoids hundreds of alloc/free which would fragment the heap.
+ * To guarantee reentrancy, we fall back to malloc if the instance is
+ * already in use (it's important to avoid suprises since this is such a
+ * low-level routine). */
+static DIR _global_dir;
+static bool _global_dir_is_in_use = false;
+
+static inline DIR *dir_calloc(void)
+{
+ DIR *d;
+
+ if (_global_dir_is_in_use) {
+ d = calloc(1, sizeof(*d));
+ } else {
+ _global_dir_is_in_use = true;
+ d = &_global_dir;
+ memset(d, 0, sizeof(*d));
+ }
+ return d;
+}
+
+static inline void dir_free(DIR *d)
+{
+ if (d == &_global_dir) {
+ _global_dir_is_in_use = false;
+ } else {
+ free(d);
+ }
+}
+
+DIR *opendir(const char *path)
+{
+ DIR *d;
+ UINT sem = SetErrorMode(SEM_FAILCRITICALERRORS); // disable 'no-disk' message box
+ DWORD fa = GetFileAttributesW(OTTD2FS(path));
+
+ if ((fa != INVALID_FILE_ATTRIBUTES) && (fa & FILE_ATTRIBUTE_DIRECTORY)) {
+ d = dir_calloc();
+ if (d != NULL) {
+ char search_path[MAX_PATH];
+ /* build search path for FindFirstFile */
+ snprintf(search_path, lengthof(search_path), "%s" PATHSEP "*", path);
+ d->hFind = FindFirstFileW(OTTD2FS(search_path), &d->fd);
+
+ if (d->hFind != INVALID_HANDLE_VALUE ||
+ GetLastError() == ERROR_NO_MORE_FILES) { // the directory is empty
+ d->ent.dir = d;
+ d->at_first_entry = true;
+ } else {
+ dir_free(d);
+ d = NULL;
+ }
+ } else {
+ errno = ENOMEM;
+ }
+ } else {
+ /* path not found or not a directory */
+ d = NULL;
+ errno = ENOENT;
+ }
+
+ SetErrorMode(sem); // restore previous setting
+ return d;
+}
+
+struct dirent *readdir(DIR *d)
+{
+ DWORD prev_err = GetLastError(); // avoid polluting last error
+
+ if (d->at_first_entry) {
+ /* the directory was empty when opened */
+ if (d->hFind == INVALID_HANDLE_VALUE) return NULL;
+ d->at_first_entry = false;
+ } else if (!FindNextFileW(d->hFind, &d->fd)) { // determine cause and bail
+ if (GetLastError() == ERROR_NO_MORE_FILES) SetLastError(prev_err);
+ return NULL;
+ }
+
+ /* This entry has passed all checks; return information about it.
+ * (note: d_name is a pointer; see struct dirent definition) */
+ d->ent.d_name = d->fd.cFileName;
+ return &d->ent;
+}
+
+int closedir(DIR *d)
+{
+ FindClose(d->hFind);
+ dir_free(d);
+ return 0;
+}
+
+bool FiosIsRoot(const char *file)
+{
+ return file[3] == '\0'; // C:\...
+}
+
+void FiosGetDrives(void)
+{
+ TCHAR drives[256];
+ const TCHAR *s;
+
+ GetLogicalDriveStrings(sizeof(drives), drives);
+ for (s = drives; *s != '\0';) {
+ FiosItem *fios = FiosAlloc();
+ fios->type = FIOS_TYPE_DRIVE;
+ fios->mtime = 0;
+ snprintf(fios->name, lengthof(fios->name), "%c:", s[0] & 0xFF);
+ ttd_strlcpy(fios->title, fios->name, lengthof(fios->title));
+ while (*s++ != '\0');
+ }
+}
+
+bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb)
+{
+ // hectonanoseconds between Windows and POSIX epoch
+ static const int64 posix_epoch_hns = 0x019DB1DED53E8000LL;
+ const WIN32_FIND_DATAW *fd = &ent->dir->fd;
+ if (fd->dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) return false;
+
+ sb->st_size = ((uint64) fd->nFileSizeHigh << 32) + fd->nFileSizeLow;
+ /* UTC FILETIME to seconds-since-1970 UTC
+ * we just have to subtract POSIX epoch and scale down to units of seconds.
+ * http://www.gamedev.net/community/forums/topic.asp?topic_id=294070&whichpage=1&#1860504
+ * XXX - not entirely correct, since filetimes on FAT aren't UTC but local,
+ * this won't entirely be correct, but we use the time only for comparsion. */
+ sb->st_mtime = (time_t)((*(uint64*)&fd->ftLastWriteTime - posix_epoch_hns) / 1E7);
+ sb->st_mode = (fd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)? S_IFDIR : S_IFREG;
+
+ return true;
+}
+
+bool FiosGetDiskFreeSpace(const char *path, uint32 *tot)
+{
+ UINT sem = SetErrorMode(SEM_FAILCRITICALERRORS); // disable 'no-disk' message box
+ bool retval = false;
+ TCHAR root[4];
+ DWORD spc, bps, nfc, tnc;
+
+ _sntprintf(root, lengthof(root), _T("%c:") _T(PATHSEP), path[0]);
+ if (tot != NULL && GetDiskFreeSpace(root, &spc, &bps, &nfc, &tnc)) {
+ *tot = ((spc * bps) * (uint64)nfc) >> 20;
+ retval = true;
+ }
+
+ SetErrorMode(sem); // reset previous setting
+ return retval;
+}
+
+static int ParseCommandLine(char *line, char **argv, int max_argc)
+{
+ int n = 0;
+
+ do {
+ // skip whitespace
+ while (*line == ' ' || *line == '\t') line++;
+
+ // end?
+ if (*line == '\0') break;
+
+ // special handling when quoted
+ if (*line == '"') {
+ argv[n++] = ++line;
+ while (*line != '"') {
+ if (*line == '\0') return n;
+ line++;
+ }
+ } else {
+ argv[n++] = line;
+ while (*line != ' ' && *line != '\t') {
+ if (*line == '\0') return n;
+ line++;
+ }
+ }
+ *line++ = '\0';
+ } while (n != max_argc);
+
+ return n;
+}
+
+void CreateConsole(void)
+{
+ HANDLE hand;
+ CONSOLE_SCREEN_BUFFER_INFO coninfo;
+
+ if (_has_console) return;
+ _has_console = true;
+
+ AllocConsole();
+
+ hand = GetStdHandle(STD_OUTPUT_HANDLE);
+ GetConsoleScreenBufferInfo(hand, &coninfo);
+ coninfo.dwSize.Y = 500;
+ SetConsoleScreenBufferSize(hand, coninfo.dwSize);
+
+ // redirect unbuffered STDIN, STDOUT, STDERR to the console
+#if !defined(__CYGWIN__)
+ *stdout = *_fdopen( _open_osfhandle((intptr_t)hand, _O_TEXT), "w" );
+ *stdin = *_fdopen(_open_osfhandle((intptr_t)GetStdHandle(STD_INPUT_HANDLE), _O_TEXT), "r" );
+ *stderr = *_fdopen(_open_osfhandle((intptr_t)GetStdHandle(STD_ERROR_HANDLE), _O_TEXT), "w" );
+#else
+ // open_osfhandle is not in cygwin
+ *stdout = *fdopen(1, "w" );
+ *stdin = *fdopen(0, "r" );
+ *stderr = *fdopen(2, "w" );
+#endif
+
+ setvbuf(stdin, NULL, _IONBF, 0);
+ setvbuf(stdout, NULL, _IONBF, 0);
+ setvbuf(stderr, NULL, _IONBF, 0);
+}
+
+void ShowInfo(const char *str)
+{
+ if (_has_console) {
+ puts(str);
+ } else {
+ bool old;
+
+ ReleaseCapture();
+ _left_button_clicked =_left_button_down = false;
+
+ old = MyShowCursor(true);
+ if (MessageBox(GetActiveWindow(), MB_TO_WIDE(str), _T("OpenTTD"), MB_ICONINFORMATION | MB_OKCANCEL) == IDCANCEL) {
+ CreateConsole();
+ }
+ MyShowCursor(old);
+ }
+}
+
+#ifdef __MINGW32__
+ /* _set_error_mode() constants&function (do not exist in mingw headers) */
+ #define _OUT_TO_DEFAULT 0
+ #define _OUT_TO_STDERR 1
+ #define _OUT_TO_MSGBOX 2
+ #define _REPORT_ERRMODE 3
+ int _set_error_mode(int);
+#endif
+
+int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
+ LPTSTR lpCmdLine, int nCmdShow)
+{
+ int argc;
+ char *argv[64]; // max 64 command line arguments
+ char *cmdline;
+
+#if defined(UNICODE)
+ /* For UNICODE we need to convert the commandline to char* _AND_
+ * save it because argv[] points into this buffer and thus needs to
+ * be available between subsequent calls to FS2OTTD() */
+ char cmdlinebuf[MAX_PATH];
+#endif
+
+ cmdline = WIDE_TO_MB_BUFFER(GetCommandLine(), cmdlinebuf, lengthof(cmdlinebuf));
+
+#if defined(_DEBUG)
+ CreateConsole();
+#endif
+
+ _set_error_mode(_OUT_TO_MSGBOX); // force assertion output to messagebox
+
+ /* setup random seed to something quite random */
+ _random_seeds[1][0] = _random_seeds[0][0] = GetTickCount();
+ _random_seeds[1][1] = _random_seeds[0][1] = _random_seeds[0][0] * 0x1234567;
+ SeedMT(_random_seeds[0][0]);
+
+ argc = ParseCommandLine(cmdline, argv, lengthof(argv));
+
+#if defined(WIN32_EXCEPTION_TRACKER)
+ Win32InitializeExceptions();
+#endif
+
+#if defined(WIN32_EXCEPTION_TRACKER_DEBUG)
+ _try {
+ LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS *ep);
+#endif
+ ttd_main(argc, argv);
+
+#if defined(WIN32_EXCEPTION_TRACKER_DEBUG)
+ } _except (ExceptionHandler(_exception_info())) {}
+#endif
+
+ return 0;
+}
+
+void DeterminePaths(void)
+{
+ char *s, *cfg;
+ wchar_t path[MAX_PATH];
+
+ _paths.personal_dir = _paths.game_data_dir = cfg = malloc(MAX_PATH);
+ GetCurrentDirectoryW(MAX_PATH - 1, path);
+ convert_from_fs(path, cfg, MAX_PATH);
+
+ cfg[0] = toupper(cfg[0]);
+ s = strchr(cfg, '\0');
+ if (s[-1] != '\\') strcpy(s, "\\");
+
+ _paths.save_dir = str_fmt("%ssave", cfg);
+ _paths.autosave_dir = str_fmt("%s\\autosave", _paths.save_dir);
+ _paths.scenario_dir = str_fmt("%sscenario", cfg);
+ _paths.heightmap_dir = str_fmt("%sscenario\\heightmap", cfg);
+ _paths.gm_dir = str_fmt("%sgm\\", cfg);
+ _paths.data_dir = str_fmt("%sdata\\", cfg);
+ _paths.lang_dir = str_fmt("%slang\\", cfg);
+
+ if (_config_file == NULL)
+ _config_file = str_fmt("%sopenttd.cfg", _paths.personal_dir);
+
+ _highscore_file = str_fmt("%shs.dat", _paths.personal_dir);
+ _log_file = str_fmt("%sopenttd.log", _paths.personal_dir);
+
+ // make (auto)save and scenario folder
+ CreateDirectoryW(OTTD2FS(_paths.save_dir), NULL);
+ CreateDirectoryW(OTTD2FS(_paths.autosave_dir), NULL);
+ CreateDirectoryW(OTTD2FS(_paths.scenario_dir), NULL);
+ CreateDirectoryW(OTTD2FS(_paths.heightmap_dir), NULL);
+}
+
+/**
+ * Insert a chunk of text from the clipboard onto the textbuffer. Get TEXT clipboard
+ * and append this up to the maximum length (either absolute or screenlength). If maxlength
+ * is zero, we don't care about the screenlength but only about the physical length of the string
+ * @param tb @Textbuf type to be changed
+ * @return Return true on successfull change of Textbuf, or false otherwise
+ */
+bool InsertTextBufferClipboard(Textbuf *tb)
+{
+ HGLOBAL cbuf;
+ char utf8_buf[512];
+ const char *ptr;
+
+ WChar c;
+ uint16 width, length;
+
+ if (IsClipboardFormatAvailable(CF_UNICODETEXT)) {
+ const char *ret;
+
+ OpenClipboard(NULL);
+ cbuf = GetClipboardData(CF_UNICODETEXT);
+
+ ptr = GlobalLock(cbuf);
+ ret = convert_from_fs((wchar_t*)ptr, utf8_buf, lengthof(utf8_buf));
+ GlobalUnlock(cbuf);
+ CloseClipboard();
+
+ if (*ret == '\0') return false;
+ } else if (IsClipboardFormatAvailable(CF_TEXT)) {
+ OpenClipboard(NULL);
+ cbuf = GetClipboardData(CF_TEXT);
+
+ ptr = GlobalLock(cbuf);
+ ttd_strlcpy(utf8_buf, ptr, lengthof(utf8_buf));
+ GlobalUnlock(cbuf);
+ CloseClipboard();
+ } else {
+ return false;
+ }
+
+ width = length = 0;
+
+ for (ptr = utf8_buf; (c = Utf8Consume(&ptr)) != '\0';) {
+ byte charwidth;
+
+ if (!IsPrintable(c)) break;
+ if (tb->length + length >= tb->maxlength - 1) break;
+ charwidth = GetCharacterWidth(FS_NORMAL, c);
+
+ if (tb->maxwidth != 0 && width + tb->width + charwidth > tb->maxwidth) break;
+
+ width += charwidth;
+ length += Utf8CharLen(c);
+ }
+
+ if (length == 0) return false;
+
+ memmove(tb->buf + tb->caretpos + length, tb->buf + tb->caretpos, tb->length - tb->caretpos);
+ memcpy(tb->buf + tb->caretpos, utf8_buf, length);
+ tb->width += width;
+ tb->caretxoffs += width;
+
+ tb->length += length;
+ tb->caretpos += length;
+ tb->buf[tb->length] = '\0'; // terminating zero
+
+ return true;
+}
+
+
+void CSleep(int milliseconds)
+{
+ Sleep(milliseconds);
+}
+
+
+// Utility function to get the current timestamp in milliseconds
+// Useful for profiling
+int64 GetTS(void)
+{
+ static double freq;
+ __int64 value;
+ if (!freq) {
+ QueryPerformanceFrequency((LARGE_INTEGER*)&value);
+ freq = (double)1000000 / value;
+ }
+ QueryPerformanceCounter((LARGE_INTEGER*)&value);
+ return (__int64)(value * freq);
+}
+
+/** Convert from OpenTTD's encoding to that of the local environment in
+ * UNICODE. OpenTTD encoding is UTF8, local is wide-char
+ * @param name pointer to a valid string that will be converted
+ * @param utf16_buf pointer to a valid wide-char buffer that will receive the
+ * converted string
+ * @param buflen length in wide characters of the receiving buffer
+ * @return pointer to utf16_buf. If conversion fails the string is of zero-length */
+wchar_t *convert_to_fs(const char *name, wchar_t *utf16_buf, size_t buflen)
+{
+ int len = MultiByteToWideChar(CP_UTF8, 0, name, -1, utf16_buf, buflen);
+ if (len == 0) {
+ DEBUG(misc, 0, "[utf8] error converting '%s'. Errno %d", name, GetLastError());
+ utf16_buf[0] = '\0';
+ }
+
+ return utf16_buf;
+}
+
+/** Convert from OpenTTD's encoding to that of the local environment in
+ * UNICODE. OpenTTD encoding is UTF8, local is wide-char.
+ * The returned value's contents can only be guaranteed until the next call to
+ * this function. So if the value is needed for anything else, use convert_from_fs
+ * @param name pointer to a valid string that will be converted
+ * @return pointer to the converted string; if failed string is of zero-length */
+const wchar_t *OTTD2FS(const char *name)
+{
+ static wchar_t utf16_buf[512];
+ return convert_to_fs(name, utf16_buf, lengthof(utf16_buf));
+}
+
+
+/** Convert to OpenTTD's encoding from that of the local environment in
+ * UNICODE. OpenTTD encoding is UTF8, local is wide-char
+ * @param name pointer to a valid string that will be converted
+ * @param utf8_buf pointer to a valid buffer that will receive the converted string
+ * @param buflen length in characters of the receiving buffer
+ * @return pointer to utf8_buf. If conversion fails the string is of zero-length */
+char *convert_from_fs(const wchar_t *name, char *utf8_buf, size_t buflen)
+{
+ int len = WideCharToMultiByte(CP_UTF8, 0, name, -1, utf8_buf, buflen, NULL, NULL);
+ if (len == 0) {
+ DEBUG(misc, 0, "[utf8] error converting wide-string. Errno %d", GetLastError());
+ utf8_buf[0] = '\0';
+ }
+
+ return utf8_buf;
+}
+
+/** Convert to OpenTTD's encoding from that of the local environment in
+ * UNICODE. OpenTTD encoding is UTF8, local is wide-char.
+ * The returned value's contents can only be guaranteed until the next call to
+ * this function. So if the value is needed for anything else, use convert_from_fs
+ * @param name pointer to a valid string that will be converted
+ * @return pointer to the converted string; if failed string is of zero-length */
+const char *FS2OTTD(const wchar_t *name)
+{
+ static char utf8_buf[512];
+ return convert_from_fs(name, utf8_buf, lengthof(utf8_buf));
+}
+
+/** Our very own SHGetFolderPath function for support of windows operating
+ * systems that don't have this function (eg Win9x, etc.). We try using the
+ * native function, and if that doesn't exist we will try a more crude approach
+ * of environment variables and hope for the best */
+HRESULT OTTDSHGetFolderPath(HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags, LPTSTR pszPath)
+{
+ static HRESULT (WINAPI *SHGetFolderPath)(HWND, int, HANDLE, DWORD, LPTSTR) = NULL;
+ static bool first_time = true;
+
+ /* We only try to load the library one time; if it fails, it fails */
+ if (first_time) {
+#if defined(UNICODE)
+# define W(x) x "W"
+#else
+# define W(x) x "A"
+#endif
+ if (!LoadLibraryList((Function*)&SHGetFolderPath, "SHFolder.dll\0" W("SHGetFolderPath") "\0\0")) {
+ DEBUG(misc, 0, "Unable to load " W("SHGetFolderPath") "from SHFolder.dll");
+ }
+#undef W
+ first_time = false;
+ }
+
+ if (SHGetFolderPath != NULL) return SHGetFolderPath(hwnd, csidl, hToken, dwFlags, pszPath);
+
+ /* SHGetFolderPath doesn't exist, try a more conservative approach,
+ * eg environment variables. This is only included for legacy modes
+ * MSDN says: that 'pszPath' is a "Pointer to a null-terminated string of
+ * length MAX_PATH which will receive the path" so let's assume that
+ * Windows 95 with Internet Explorer 5.0, Windows 98 with Internet Explorer 5.0,
+ * Windows 98 Second Edition (SE), Windows NT 4.0 with Internet Explorer 5.0,
+ * Windows NT 4.0 with Service Pack 4 (SP4) */
+ {
+ DWORD ret;
+ switch (csidl) {
+ case CSIDL_FONTS: /* Get the system font path, eg %WINDIR%\Fonts */
+ ret = GetEnvironmentVariable(_T("WINDIR"), pszPath, MAX_PATH);
+ if (ret == 0) break;
+ _tcsncat(pszPath, _T("\\Fonts"), MAX_PATH);
+
+ return (HRESULT)0;
+ break;
+ /* XXX - other types to go here when needed... */
+ }
+ }
+
+ return E_INVALIDARG;
+}
diff --git a/src/win32.h b/src/win32.h
new file mode 100644
index 000000000..bd4720789
--- /dev/null
+++ b/src/win32.h
@@ -0,0 +1,45 @@
+/* $Id$ */
+
+#ifndef WIN32_H
+#define WIN32_H
+
+#include <windows.h>
+bool MyShowCursor(bool show);
+
+typedef void (*Function)(int);
+bool LoadLibraryList(Function proc[], const char *dll);
+
+char *convert_from_fs(const wchar_t *name, char *utf8_buf, size_t buflen);
+wchar_t *convert_to_fs(const char *name, wchar_t *utf16_buf, size_t buflen);
+
+/* Function shortcuts for UTF-8 <> UNICODE conversion. When unicode is not
+ * defined these macros return the string passed to them, with UNICODE
+ * they return a pointer to the converted string. The only difference between
+ * XX_TO_YY and XX_TO_YY_BUFFER is that with the buffer variant you can
+ * specify where to put the converted string (and how long it can be). Without
+ * the buffer and internal buffer is used, of max 512 characters */
+#if defined(UNICODE)
+# define MB_TO_WIDE(str) OTTD2FS(str)
+# define MB_TO_WIDE_BUFFER(str, buffer, buflen) convert_to_fs(str, buffer, buflen)
+# define WIDE_TO_MB(str) FS2OTTD(str)
+# define WIDE_TO_MB_BUFFER(str, buffer, buflen) convert_from_fs(str, buffer, buflen)
+#else
+# define MB_TO_WIDE(str) (str)
+# define MB_TO_WIDE_BUFFER(str, buffer, buflen) (str)
+# define WIDE_TO_MB(str) (str)
+# define WIDE_TO_MB_BUFFER(str, buffer, buflen) (str)
+#endif
+
+/* Override SHGetFolderPath with our custom implementation */
+#if defined(SHGetFolderPath)
+#undef SHGetFolderPath
+#endif
+#define SHGetFolderPath OTTDSHGetFolderPath
+
+HRESULT OTTDSHGetFolderPath(HWND, int, HANDLE, DWORD, LPTSTR);
+
+#if defined(__MINGW32__)
+#define SHGFP_TYPE_CURRENT 0
+#endif /* __MINGW32__ */
+
+#endif /* WIN32_H */
diff --git a/src/win64.asm b/src/win64.asm
new file mode 100644
index 000000000..21bfebbde
--- /dev/null
+++ b/src/win64.asm
@@ -0,0 +1,17 @@
+ .CODE
+
+PUBLIC _get_save_esp
+_get_save_esp:
+ MOV RAX,RSP
+ RET
+
+PUBLIC _rdtsc
+_rdtsc:
+ RDTSC
+ MOV RCX,RDX
+ SHL RCX,32
+ AND RAX,0FFFFFFFFh
+ OR RAX,RCX
+ RET
+
+ END
diff --git a/src/window.c b/src/window.c
new file mode 100644
index 000000000..1a12c7c6b
--- /dev/null
+++ b/src/window.c
@@ -0,0 +1,2000 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include <stdarg.h>
+#include "openttd.h"
+#include "debug.h"
+#include "functions.h"
+#include "map.h"
+#include "player.h"
+#include "window.h"
+#include "gfx.h"
+#include "viewport.h"
+#include "console.h"
+#include "variables.h"
+#include "table/sprites.h"
+#include "genworld.h"
+
+// delta between mouse cursor and upper left corner of dragged window
+static Point _drag_delta;
+
+static Window _windows[25];
+Window *_z_windows[lengthof(_windows)];
+Window **_last_z_window; ///< always points to the next free space in the z-array
+
+void CDECL SetWindowWidgetsDisabledState(Window *w, bool disab_stat, int widgets, ...)
+{
+ va_list wdg_list;
+
+ va_start(wdg_list, widgets);
+
+ while (widgets != WIDGET_LIST_END) {
+ SetWindowWidgetDisabledState(w, widgets, disab_stat);
+ widgets = va_arg(wdg_list, int);
+ }
+
+ va_end(wdg_list);
+}
+
+void CDECL SetWindowWidgetsHiddenState(Window *w, bool hidden_stat, int widgets, ...)
+{
+ va_list wdg_list;
+
+ va_start(wdg_list, widgets);
+
+ while (widgets != WIDGET_LIST_END) {
+ SetWindowWidgetHiddenState(w, widgets, hidden_stat);
+ widgets = va_arg(wdg_list, int);
+ }
+
+ va_end(wdg_list);
+}
+
+void CDECL SetWindowWidgetsLoweredState(Window *w, bool lowered_stat, int widgets, ...)
+{
+ va_list wdg_list;
+
+ va_start(wdg_list, widgets);
+
+ while (widgets != WIDGET_LIST_END) {
+ SetWindowWidgetLoweredState(w, widgets, lowered_stat);
+ widgets = va_arg(wdg_list, int);
+ }
+
+ va_end(wdg_list);
+}
+
+void RaiseWindowButtons(Window *w)
+{
+ uint i;
+
+ for (i = 0; i < w->widget_count; i++) {
+ if (IsWindowWidgetLowered(w, i)) {
+ RaiseWindowWidget(w, i);
+ InvalidateWidget(w, i);
+ }
+ }
+}
+
+void HandleButtonClick(Window *w, byte widget)
+{
+ LowerWindowWidget(w, widget);
+ w->flags4 |= 5 << WF_TIMEOUT_SHL;
+ InvalidateWidget(w, widget);
+}
+
+
+static void StartWindowDrag(Window *w);
+static void StartWindowSizing(Window *w);
+
+static void DispatchLeftClickEvent(Window *w, int x, int y)
+{
+ WindowEvent e;
+ const Widget *wi;
+
+ e.we.click.pt.x = x;
+ e.we.click.pt.y = y;
+ e.event = WE_CLICK;
+
+ if (w->desc_flags & WDF_DEF_WIDGET) {
+ e.we.click.widget = GetWidgetFromPos(w, x, y);
+ if (e.we.click.widget < 0) return; /* exit if clicked outside of widgets */
+
+ /* don't allow any interaction if the button has been disabled */
+ if (IsWindowWidgetDisabled(w, e.we.click.widget)) return;
+
+ wi = &w->widget[e.we.click.widget];
+
+ if (wi->type & WWB_MASK) {
+ /* special widget handling for buttons*/
+ switch (wi->type) {
+ case WWT_PANEL | WWB_PUSHBUTTON: /* WWT_PUSHBTN */
+ case WWT_IMGBTN | WWB_PUSHBUTTON: /* WWT_PUSHIMGBTN */
+ case WWT_TEXTBTN | WWB_PUSHBUTTON: /* WWT_PUSHTXTBTN */
+ HandleButtonClick(w, e.we.click.widget);
+ break;
+ }
+ } else if (wi->type == WWT_SCROLLBAR || wi->type == WWT_SCROLL2BAR || wi->type == WWT_HSCROLLBAR) {
+ ScrollbarClickHandler(w, wi, e.we.click.pt.x, e.we.click.pt.y);
+ }
+
+ if (w->desc_flags & WDF_STD_BTN) {
+ if (e.we.click.widget == 0) { /* 'X' */
+ DeleteWindow(w);
+ return;
+ }
+
+ if (e.we.click.widget == 1) { /* 'Title bar' */
+ StartWindowDrag(w);
+ return;
+ }
+ }
+
+ if (w->desc_flags & WDF_RESIZABLE && wi->type == WWT_RESIZEBOX) {
+ StartWindowSizing(w);
+ InvalidateWidget(w, e.we.click.widget);
+ return;
+ }
+
+ if (w->desc_flags & WDF_STICKY_BUTTON && wi->type == WWT_STICKYBOX) {
+ w->flags4 ^= WF_STICKY;
+ InvalidateWidget(w, e.we.click.widget);
+ return;
+ }
+ }
+
+ w->wndproc(w, &e);
+}
+
+static void DispatchRightClickEvent(Window *w, int x, int y)
+{
+ WindowEvent e;
+
+ /* default tooltips handler? */
+ if (w->desc_flags & WDF_STD_TOOLTIPS) {
+ e.we.click.widget = GetWidgetFromPos(w, x, y);
+ if (e.we.click.widget < 0)
+ return; /* exit if clicked outside of widgets */
+
+ if (w->widget[e.we.click.widget].tooltips != 0) {
+ GuiShowTooltips(w->widget[e.we.click.widget].tooltips);
+ return;
+ }
+ }
+
+ e.event = WE_RCLICK;
+ e.we.click.pt.x = x;
+ e.we.click.pt.y = y;
+ w->wndproc(w, &e);
+}
+
+/** Dispatch the mousewheel-action to the window which will scroll any
+ * compatible scrollbars if the mouse is pointed over the bar or its contents
+ * @param *w Window
+ * @param widget the widget where the scrollwheel was used
+ * @param wheel scroll up or down
+ */
+static void DispatchMouseWheelEvent(Window *w, int widget, int wheel)
+{
+ const Widget *wi1, *wi2;
+ Scrollbar *sb;
+
+ if (widget < 0) return;
+
+ wi1 = &w->widget[widget];
+ wi2 = &w->widget[widget + 1];
+
+ /* The listbox can only scroll if scrolling was done on the scrollbar itself,
+ * or on the listbox (and the next item is (must be) the scrollbar)
+ * XXX - should be rewritten as a widget-dependent scroller but that's
+ * not happening until someone rewrites the whole widget-code */
+ if ((sb = &w->vscroll, wi1->type == WWT_SCROLLBAR) || (sb = &w->vscroll2, wi1->type == WWT_SCROLL2BAR) ||
+ (sb = &w->vscroll2, wi2->type == WWT_SCROLL2BAR) || (sb = &w->vscroll, wi2->type == WWT_SCROLLBAR) ) {
+
+ if (sb->count > sb->cap) {
+ int pos = clamp(sb->pos + wheel, 0, sb->count - sb->cap);
+ if (pos != sb->pos) {
+ sb->pos = pos;
+ SetWindowDirty(w);
+ }
+ }
+ }
+}
+
+static void DrawOverlappedWindow(Window* const *wz, int left, int top, int right, int bottom);
+
+void DrawOverlappedWindowForAll(int left, int top, int right, int bottom)
+{
+ Window* const *wz;
+ DrawPixelInfo bk;
+ _cur_dpi = &bk;
+
+ FOR_ALL_WINDOWS(wz) {
+ const Window *w = *wz;
+ if (right > w->left &&
+ bottom > w->top &&
+ left < w->left + w->width &&
+ top < w->top + w->height) {
+ DrawOverlappedWindow(wz, left, top, right, bottom);
+ }
+ }
+}
+
+static void DrawOverlappedWindow(Window* const *wz, int left, int top, int right, int bottom)
+{
+ Window* const *vz = wz;
+ int x;
+
+ while (++vz != _last_z_window) {
+ const Window *v = *vz;
+
+ if (right > v->left &&
+ bottom > v->top &&
+ left < v->left + v->width &&
+ top < v->top + v->height) {
+ if (left < (x=v->left)) {
+ DrawOverlappedWindow(wz, left, top, x, bottom);
+ DrawOverlappedWindow(wz, x, top, right, bottom);
+ return;
+ }
+
+ if (right > (x=v->left + v->width)) {
+ DrawOverlappedWindow(wz, left, top, x, bottom);
+ DrawOverlappedWindow(wz, x, top, right, bottom);
+ return;
+ }
+
+ if (top < (x=v->top)) {
+ DrawOverlappedWindow(wz, left, top, right, x);
+ DrawOverlappedWindow(wz, left, x, right, bottom);
+ return;
+ }
+
+ if (bottom > (x=v->top + v->height)) {
+ DrawOverlappedWindow(wz, left, top, right, x);
+ DrawOverlappedWindow(wz, left, x, right, bottom);
+ return;
+ }
+
+ return;
+ }
+ }
+
+ {
+ DrawPixelInfo *dp = _cur_dpi;
+ dp->width = right - left;
+ dp->height = bottom - top;
+ dp->left = left - (*wz)->left;
+ dp->top = top - (*wz)->top;
+ dp->pitch = _screen.pitch;
+ dp->dst_ptr = _screen.dst_ptr + top * _screen.pitch + left;
+ dp->zoom = 0;
+ CallWindowEventNP(*wz, WE_PAINT);
+ }
+}
+
+void CallWindowEventNP(Window *w, int event)
+{
+ WindowEvent e;
+
+ e.event = event;
+ w->wndproc(w, &e);
+}
+
+void SetWindowDirty(const Window *w)
+{
+ if (w == NULL) return;
+ SetDirtyBlocks(w->left, w->top, w->left + w->width, w->top + w->height);
+}
+
+/** Find the Window whose parent pointer points to this window
+ * @parent w Window to find child of
+ * @return return a Window pointer that is the child of w, or NULL otherwise */
+static Window *FindChildWindow(const Window *w)
+{
+ Window* const *wz;
+
+ FOR_ALL_WINDOWS(wz) {
+ Window *v = *wz;
+ if (v->parent == w) return v;
+ }
+
+ return NULL;
+}
+
+/** Find the z-value of a window. A window must already be open
+ * or the behaviour is undefined but function should never fail */
+Window **FindWindowZPosition(const Window *w)
+{
+ Window **wz;
+
+ for (wz = _z_windows; wz != _last_z_window; wz++) {
+ if (*wz == w) return wz;
+ }
+
+ DEBUG(misc, 3, "Window (class %d, number %d) is not open, probably removed by recursive calls",
+ w->window_class, w->window_number);
+ return NULL;
+}
+
+void DeleteWindow(Window *w)
+{
+ Window *v;
+ Window **wz;
+ if (w == NULL) return;
+
+ /* Delete any children a window might have in a head-recursive manner */
+ v = FindChildWindow(w);
+ if (v != NULL) DeleteWindow(v);
+
+ if (_thd.place_mode != VHM_NONE &&
+ _thd.window_class == w->window_class &&
+ _thd.window_number == w->window_number) {
+ ResetObjectToPlace();
+ }
+
+ CallWindowEventNP(w, WE_DESTROY);
+ if (w->viewport != NULL) DeleteWindowViewport(w);
+
+ SetWindowDirty(w);
+ free(w->widget);
+ w->widget = NULL;
+ w->widget_count = 0;
+ w->parent = NULL;
+
+ /* Find the window in the z-array, and effectively remove it
+ * by moving all windows after it one to the left */
+ wz = FindWindowZPosition(w);
+ if (wz == NULL) return;
+ memmove(wz, wz + 1, (byte*)_last_z_window - (byte*)wz);
+ _last_z_window--;
+}
+
+Window *FindWindowById(WindowClass cls, WindowNumber number)
+{
+ Window* const *wz;
+
+ FOR_ALL_WINDOWS(wz) {
+ Window *w = *wz;
+ if (w->window_class == cls && w->window_number == number) return w;
+ }
+
+ return NULL;
+}
+
+void DeleteWindowById(WindowClass cls, WindowNumber number)
+{
+ DeleteWindow(FindWindowById(cls, number));
+}
+
+void DeleteWindowByClass(WindowClass cls)
+{
+ Window* const *wz;
+
+restart_search:
+ /* When we find the window to delete, we need to restart the search
+ * as deleting this window could cascade in deleting (many) others
+ * anywhere in the z-array */
+ FOR_ALL_WINDOWS(wz) {
+ Window *w = *wz;
+ if (w->window_class == cls) {
+ DeleteWindow(w);
+ goto restart_search;
+ }
+ }
+}
+
+/** Delete all windows of a player. We identify windows of a player
+ * by looking at the caption colour. If it is equal to the player ID
+ * then we say the window belongs to the player and should be deleted
+ * @param id PlayerID player identifier */
+void DeletePlayerWindows(PlayerID id)
+{
+ Window* const *wz;
+
+restart_search:
+ /* When we find the window to delete, we need to restart the search
+ * as deleting this window could cascade in deleting (many) others
+ * anywhere in the z-array */
+ FOR_ALL_WINDOWS(wz) {
+ Window *w = *wz;
+ if (w->caption_color == id) {
+ DeleteWindow(w);
+ goto restart_search;
+ }
+ }
+
+ /* Also delete the player specific windows, that don't have a player-colour */
+ DeleteWindowById(WC_BUY_COMPANY, id);
+}
+
+/** Change the owner of all the windows one player can take over from another
+ * player in the case of a company merger. Do not change ownership of windows
+ * that need to be deleted once takeover is complete
+ * @param old_player PlayerID of original owner of the window
+ * @param new_player PlayerID of the new owner of the window */
+void ChangeWindowOwner(PlayerID old_player, PlayerID new_player)
+{
+ Window* const *wz;
+
+ FOR_ALL_WINDOWS(wz) {
+ Window *w = *wz;
+
+ if (w->caption_color != old_player) continue;
+ if (w->window_class == WC_PLAYER_COLOR) continue;
+ if (w->window_class == WC_FINANCES) continue;
+ if (w->window_class == WC_STATION_LIST) continue;
+ if (w->window_class == WC_TRAINS_LIST) continue;
+ if (w->window_class == WC_ROADVEH_LIST) continue;
+ if (w->window_class == WC_SHIPS_LIST) continue;
+ if (w->window_class == WC_AIRCRAFT_LIST) continue;
+ if (w->window_class == WC_BUY_COMPANY) continue;
+ if (w->window_class == WC_COMPANY) continue;
+
+ w->caption_color = new_player;
+ }
+}
+
+static void BringWindowToFront(const Window *w);
+
+/** Find a window and make it the top-window on the screen. The window
+ * gets a white border for a brief period of time to visualize its
+ * "activation"
+ * @return a pointer to the window thus activated */
+Window *BringWindowToFrontById(WindowClass cls, WindowNumber number)
+{
+ Window *w = FindWindowById(cls, number);
+
+ if (w != NULL) {
+ w->flags4 |= WF_WHITE_BORDER_MASK;
+ BringWindowToFront(w);
+ SetWindowDirty(w);
+ }
+
+ return w;
+}
+
+static inline bool IsVitalWindow(const Window *w)
+{
+ WindowClass wc = w->window_class;
+ return (wc == WC_MAIN_TOOLBAR || wc == WC_STATUS_BAR || wc == WC_NEWS_WINDOW || wc == WC_SEND_NETWORK_MSG);
+}
+
+/** On clicking on a window, make it the frontmost window of all. However
+ * there are certain windows that always need to be on-top; these include
+ * - Toolbar, Statusbar (always on)
+ * - New window, Chatbar (only if open)
+ * The window is marked dirty for a repaint if the window is actually moved
+ * @param w window that is put into the foreground
+ * @return pointer to the window, the same as the input pointer
+ */
+static void BringWindowToFront(const Window *w)
+{
+ Window *tempz;
+ Window **wz = FindWindowZPosition(w);
+ Window **vz = _last_z_window;
+
+ /* Bring the window just below the vital windows */
+ do {
+ if (--vz < _z_windows) return;
+ } while (IsVitalWindow(*vz));
+
+ if (wz == vz) return; // window is already in the right position
+ assert(wz < vz);
+
+ tempz = *wz;
+ memmove(wz, wz + 1, (byte*)vz - (byte*)wz);
+ *vz = tempz;
+
+ SetWindowDirty(w);
+}
+
+/** We have run out of windows, so find a suitable candidate for replacement.
+ * Keep all important windows intact. These are
+ * - Main window (gamefield), Toolbar, Statusbar (always on)
+ * - News window, Chatbar (when on)
+ * - Any sticked windows since we wanted to keep these
+ * @return w pointer to the window that is going to be deleted
+ */
+static Window *FindDeletableWindow(void)
+{
+ Window* const *wz;
+
+ FOR_ALL_WINDOWS(wz) {
+ Window *w = *wz;
+ if (w->window_class != WC_MAIN_WINDOW && !IsVitalWindow(w) && !(w->flags4 & WF_STICKY)) {
+ return w;
+ }
+ }
+ return NULL;
+}
+
+/** A window must be freed, and all are marked as important windows. Ease the
+ * restriction a bit by allowing to delete sticky windows. Keep important/vital
+ * windows intact (Main window, Toolbar, Statusbar, News Window, Chatbar)
+ * Start finding an appropiate candidate from the lowest z-values (bottom)
+ * @see FindDeletableWindow()
+ * @return w Pointer to the window that is being deleted
+ */
+static Window *ForceFindDeletableWindow(void)
+{
+ Window* const *wz;
+
+ for (wz = _z_windows;; wz++) {
+ Window *w = *wz;
+ assert(wz < _last_z_window);
+ if (w->window_class != WC_MAIN_WINDOW && !IsVitalWindow(w)) return w;
+ }
+}
+
+bool IsWindowOfPrototype(const Window *w, const Widget *widget)
+{
+ return (w->original_widget == widget);
+}
+
+/* Copies 'widget' to 'w->widget' to allow for resizable windows */
+void AssignWidgetToWindow(Window *w, const Widget *widget)
+{
+ w->original_widget = widget;
+
+ if (widget != NULL) {
+ uint index = 1;
+ const Widget *wi;
+
+ for (wi = widget; wi->type != WWT_LAST; wi++) index++;
+
+ w->widget = realloc(w->widget, sizeof(*w->widget) * index);
+ memcpy(w->widget, widget, sizeof(*w->widget) * index);
+ w->widget_count = index - 1;
+ } else {
+ w->widget = NULL;
+ w->widget_count = 0;
+ }
+}
+
+static Window *FindFreeWindow(void)
+{
+ Window *w;
+
+ for (w = _windows; w < endof(_windows); w++) {
+ Window* const *wz;
+ bool window_in_use = false;
+
+ FOR_ALL_WINDOWS(wz) {
+ if (*wz == w) {
+ window_in_use = true;
+ break;
+ }
+ }
+
+ if (!window_in_use) return w;
+ }
+
+ assert(_last_z_window == endof(_z_windows));
+ return NULL;
+}
+
+/* Open a new window.
+ * This function is called from AllocateWindow() or AllocateWindowDesc()
+ * See descriptions for those functions for usage
+ * See AllocateWindow() for description of arguments.
+ * Only addition here is window_number, which is the window_number being assigned to the new window
+ */
+static Window *LocalAllocateWindow(
+ int x, int y, int width, int height,
+ WindowProc *proc, WindowClass cls, const Widget *widget, int window_number)
+{
+ Window *w = FindFreeWindow();
+
+ /* We have run out of windows, close one and use that as the place for our new one */
+ if (w == NULL) {
+ w = FindDeletableWindow();
+ if (w == NULL) w = ForceFindDeletableWindow();
+ DeleteWindow(w);
+ }
+
+ // Set up window properties
+ memset(w, 0, sizeof(*w));
+ w->window_class = cls;
+ w->flags4 = WF_WHITE_BORDER_MASK; // just opened windows have a white border
+ w->caption_color = 0xFF;
+ w->left = x;
+ w->top = y;
+ w->width = width;
+ w->height = height;
+ w->wndproc = proc;
+ AssignWidgetToWindow(w, widget);
+ w->resize.width = width;
+ w->resize.height = height;
+ w->resize.step_width = 1;
+ w->resize.step_height = 1;
+ w->window_number = window_number;
+
+ {
+ Window **wz = _last_z_window;
+
+ /* Hacky way of specifying always-on-top windows. These windows are
+ * always above other windows because they are moved below them.
+ * status-bar is above news-window because it has been created earlier.
+ * Also, as the chat-window is excluded from this, it will always be
+ * the last window, thus always on top.
+ * XXX - Yes, ugly, probably needs something like w->always_on_top flag
+ * to implement correctly, but even then you need some kind of distinction
+ * between on-top of chat/news and status windows, because these conflict */
+ if (wz != _z_windows && w->window_class != WC_SEND_NETWORK_MSG) {
+ if (FindWindowById(WC_MAIN_TOOLBAR, 0) != NULL) wz--;
+ if (FindWindowById(WC_STATUS_BAR, 0) != NULL) wz--;
+ if (FindWindowById(WC_NEWS_WINDOW, 0) != NULL) wz--;
+ if (FindWindowById(WC_SEND_NETWORK_MSG, 0) != NULL) wz--;
+
+ assert(wz >= _z_windows);
+ if (wz != _last_z_window) memmove(wz + 1, wz, (byte*)_last_z_window - (byte*)wz);
+ }
+
+ *wz = w;
+ _last_z_window++;
+ }
+
+ SetWindowDirty(w);
+ CallWindowEventNP(w, WE_CREATE);
+
+ return w;
+}
+
+/**
+ * Open a new window. If there is no space for a new window, close an open
+ * window. Try to avoid stickied windows, but if there is no else, close one of
+ * those as well. Then make sure all created windows are below some always-on-top
+ * ones. Finally set all variables and call the WE_CREATE event
+ * @param x offset in pixels from the left of the screen
+ * @param y offset in pixels from the top of the screen
+ * @param width width in pixels of the window
+ * @param height height in pixels of the window
+ * @param *proc @see WindowProc function to call when any messages/updates happen to the window
+ * @param cls @see WindowClass class of the window, used for identification and grouping
+ * @param *widget @see Widget pointer to the window layout and various elements
+ * @return @see Window pointer of the newly created window
+ */
+Window *AllocateWindow(
+ int x, int y, int width, int height,
+ WindowProc *proc, WindowClass cls, const Widget *widget)
+{
+ return LocalAllocateWindow(x, y, width, height, proc, cls, widget, 0);
+}
+
+typedef struct SizeRect {
+ int left,top,width,height;
+} SizeRect;
+
+
+static SizeRect _awap_r;
+
+static bool IsGoodAutoPlace1(int left, int top)
+{
+ int right,bottom;
+ Window* const *wz;
+
+ _awap_r.left= left;
+ _awap_r.top = top;
+ right = _awap_r.width + left;
+ bottom = _awap_r.height + top;
+
+ if (left < 0 || top < 22 || right > _screen.width || bottom > _screen.height)
+ return false;
+
+ // Make sure it is not obscured by any window.
+ FOR_ALL_WINDOWS(wz) {
+ const Window *w = *wz;
+ if (w->window_class == WC_MAIN_WINDOW) continue;
+
+ if (right > w->left &&
+ w->left + w->width > left &&
+ bottom > w->top &&
+ w->top + w->height > top) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static bool IsGoodAutoPlace2(int left, int top)
+{
+ int width,height;
+ Window* const *wz;
+
+ _awap_r.left= left;
+ _awap_r.top = top;
+ width = _awap_r.width;
+ height = _awap_r.height;
+
+ if (left < -(width>>2) || left > _screen.width - (width>>1)) return false;
+ if (top < 22 || top > _screen.height - (height>>2)) return false;
+
+ // Make sure it is not obscured by any window.
+ FOR_ALL_WINDOWS(wz) {
+ const Window *w = *wz;
+ if (w->window_class == WC_MAIN_WINDOW) continue;
+
+ if (left + width > w->left &&
+ w->left + w->width > left &&
+ top + height > w->top &&
+ w->top + w->height > top) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static Point GetAutoPlacePosition(int width, int height)
+{
+ Window* const *wz;
+ Point pt;
+
+ _awap_r.width = width;
+ _awap_r.height = height;
+
+ if (IsGoodAutoPlace1(0, 24)) goto ok_pos;
+
+ FOR_ALL_WINDOWS(wz) {
+ const Window *w = *wz;
+ if (w->window_class == WC_MAIN_WINDOW) continue;
+
+ if (IsGoodAutoPlace1(w->left+w->width+2,w->top)) goto ok_pos;
+ if (IsGoodAutoPlace1(w->left- width-2,w->top)) goto ok_pos;
+ if (IsGoodAutoPlace1(w->left,w->top+w->height+2)) goto ok_pos;
+ if (IsGoodAutoPlace1(w->left,w->top- height-2)) goto ok_pos;
+ if (IsGoodAutoPlace1(w->left+w->width+2,w->top+w->height-height)) goto ok_pos;
+ if (IsGoodAutoPlace1(w->left- width-2,w->top+w->height-height)) goto ok_pos;
+ if (IsGoodAutoPlace1(w->left+w->width-width,w->top+w->height+2)) goto ok_pos;
+ if (IsGoodAutoPlace1(w->left+w->width-width,w->top- height-2)) goto ok_pos;
+ }
+
+ FOR_ALL_WINDOWS(wz) {
+ const Window *w = *wz;
+ if (w->window_class == WC_MAIN_WINDOW) continue;
+
+ if (IsGoodAutoPlace2(w->left+w->width+2,w->top)) goto ok_pos;
+ if (IsGoodAutoPlace2(w->left- width-2,w->top)) goto ok_pos;
+ if (IsGoodAutoPlace2(w->left,w->top+w->height+2)) goto ok_pos;
+ if (IsGoodAutoPlace2(w->left,w->top- height-2)) goto ok_pos;
+ }
+
+ {
+ int left=0,top=24;
+
+restart:;
+ FOR_ALL_WINDOWS(wz) {
+ const Window *w = *wz;
+
+ if (w->left == left && w->top == top) {
+ left += 5;
+ top += 5;
+ goto restart;
+ }
+ }
+
+ pt.x = left;
+ pt.y = top;
+ return pt;
+ }
+
+ok_pos:;
+ pt.x = _awap_r.left;
+ pt.y = _awap_r.top;
+ return pt;
+}
+
+static Window *LocalAllocateWindowDesc(const WindowDesc *desc, int window_number)
+{
+ Point pt;
+ Window *w;
+
+ /* By default position a child window at an offset of 10/10 of its parent.
+ * However if it falls too extremely outside window positions, reposition
+ * it to an automatic place */
+ if (desc->parent_cls != 0 /* WC_MAIN_WINDOW */ &&
+ (w = FindWindowById(desc->parent_cls, window_number)) != NULL &&
+ w->left < _screen.width - 20 && w->left > -60 && w->top < _screen.height - 20) {
+
+ pt.x = w->left + 10;
+ if (pt.x > _screen.width + 10 - desc->width) {
+ pt.x = (_screen.width + 10 - desc->width) - 20;
+ }
+ pt.y = w->top + 10;
+ } else {
+ switch (desc->left) {
+ case WDP_ALIGN_TBR: { /* Align the right side with the top toolbar */
+ w = FindWindowById(WC_MAIN_TOOLBAR, 0);
+ pt.x = (w->left + w->width) - desc->width;
+ } break;
+ case WDP_ALIGN_TBL: /* Align the left side with the top toolbar */
+ pt.x = FindWindowById(WC_MAIN_TOOLBAR, 0)->left;
+ break;
+ case WDP_AUTO: /* Find a good automatic position for the window */
+ pt = GetAutoPlacePosition(desc->width, desc->height);
+ goto allocate_window;
+ case WDP_CENTER: /* Centre the window horizontally */
+ pt.x = (_screen.width - desc->width) / 2;
+ break;
+ default:
+ pt.x = desc->left;
+ if (pt.x < 0) pt.x += _screen.width; // negative is from right of the screen
+ }
+
+ switch (desc->top) {
+ case WDP_CENTER: /* Centre the window vertically */
+ pt.y = (_screen.height - desc->height) / 2;
+ break;
+ /* WDP_AUTO sets the position at once and is controlled by desc->left.
+ * Both left and top must be set to WDP_AUTO */
+ case WDP_AUTO:
+ NOT_REACHED();
+ assert(desc->left == WDP_AUTO && desc->top != WDP_AUTO);
+ /* fallthrough */
+ default:
+ pt.y = desc->top;
+ if (pt.y < 0) pt.y += _screen.height; // negative is from bottom of the screen
+ break;
+ }
+ }
+
+allocate_window:
+ w = LocalAllocateWindow(pt.x, pt.y, desc->width, desc->height, desc->proc, desc->cls, desc->widgets, window_number);
+ w->desc_flags = desc->flags;
+ return w;
+}
+
+/**
+ * Open a new window.
+ * @param *desc The pointer to the WindowDesc to be created
+ * @return @see Window pointer of the newly created window
+ */
+Window *AllocateWindowDesc(const WindowDesc *desc)
+{
+ return LocalAllocateWindowDesc(desc, 0);
+}
+
+/**
+ * Open a new window.
+ * @param *desc The pointer to the WindowDesc to be created
+ * @param window_number the window number of the new window
+ * @return @see Window pointer of the newly created window
+ */
+Window *AllocateWindowDescFront(const WindowDesc *desc, int window_number)
+{
+ Window *w;
+
+ if (BringWindowToFrontById(desc->cls, window_number)) return NULL;
+ w = LocalAllocateWindowDesc(desc, window_number);
+ return w;
+}
+
+/** Do a search for a window at specific coordinates. For this we start
+ * at the topmost window, obviously and work our way down to the bottom
+ * @return a pointer to the found window if any, NULL otherwise */
+Window *FindWindowFromPt(int x, int y)
+{
+ Window* const *wz;
+
+ for (wz = _last_z_window; wz != _z_windows;) {
+ Window *w = *--wz;
+ if (IS_INSIDE_1D(x, w->left, w->width) && IS_INSIDE_1D(y, w->top, w->height)) {
+ return w;
+ }
+ }
+
+ return NULL;
+}
+
+void InitWindowSystem(void)
+{
+ IConsoleClose();
+
+ memset(&_windows, 0, sizeof(_windows));
+ _last_z_window = _z_windows;
+ InitViewports();
+ _no_scroll = 0;
+}
+
+void UnInitWindowSystem(void)
+{
+ Window **wz;
+ /* Delete all malloced widgets, and reset z-array */
+ FOR_ALL_WINDOWS(wz) {
+ free((*wz)->widget);
+ (*wz)->widget = NULL;
+ (*wz)->widget_count = 0;
+ *wz = NULL;
+ }
+ _last_z_window = _z_windows;
+}
+
+void ResetWindowSystem(void)
+{
+ UnInitWindowSystem();
+ InitWindowSystem();
+ _thd.pos.x = 0;
+ _thd.pos.y = 0;
+ _thd.new_pos.x = 0;
+ _thd.new_pos.y = 0;
+}
+
+static void DecreaseWindowCounters(void)
+{
+ Window *w;
+ Window* const *wz;
+
+ for (wz = _last_z_window; wz != _z_windows;) {
+ w = *--wz;
+ // Unclick scrollbar buttons if they are pressed.
+ if (w->flags4 & (WF_SCROLL_DOWN | WF_SCROLL_UP)) {
+ w->flags4 &= ~(WF_SCROLL_DOWN | WF_SCROLL_UP);
+ SetWindowDirty(w);
+ }
+ CallWindowEventNP(w, WE_MOUSELOOP);
+ }
+
+ for (wz = _last_z_window; wz != _z_windows;) {
+ w = *--wz;
+
+ if (w->flags4&WF_TIMEOUT_MASK && !(--w->flags4&WF_TIMEOUT_MASK)) {
+ CallWindowEventNP(w, WE_TIMEOUT);
+ if (w->desc_flags & WDF_UNCLICK_BUTTONS) RaiseWindowButtons(w);
+ }
+ }
+}
+
+Window *GetCallbackWnd(void)
+{
+ return FindWindowById(_thd.window_class, _thd.window_number);
+}
+
+static void HandlePlacePresize(void)
+{
+ Window *w;
+ WindowEvent e;
+
+ if (_special_mouse_mode != WSM_PRESIZE) return;
+
+ w = GetCallbackWnd();
+ if (w == NULL) return;
+
+ e.we.place.pt = GetTileBelowCursor();
+ if (e.we.place.pt.x == -1) {
+ _thd.selend.x = -1;
+ return;
+ }
+ e.we.place.tile = TileVirtXY(e.we.place.pt.x, e.we.place.pt.y);
+ e.event = WE_PLACE_PRESIZE;
+ w->wndproc(w, &e);
+}
+
+static bool HandleDragDrop(void)
+{
+ Window *w;
+ WindowEvent e;
+
+ if (_special_mouse_mode != WSM_DRAGDROP) return true;
+
+ if (_left_button_down) return false;
+
+ w = GetCallbackWnd();
+
+ ResetObjectToPlace();
+
+ if (w != NULL) {
+ // send an event in client coordinates.
+ e.event = WE_DRAGDROP;
+ e.we.dragdrop.pt.x = _cursor.pos.x - w->left;
+ e.we.dragdrop.pt.y = _cursor.pos.y - w->top;
+ e.we.dragdrop.widget = GetWidgetFromPos(w, e.we.dragdrop.pt.x, e.we.dragdrop.pt.y);
+ w->wndproc(w, &e);
+ }
+ return false;
+}
+
+static bool HandlePopupMenu(void)
+{
+ Window *w;
+ WindowEvent e;
+
+ if (!_popup_menu_active) return true;
+
+ w = FindWindowById(WC_TOOLBAR_MENU, 0);
+ if (w == NULL) {
+ _popup_menu_active = false;
+ return false;
+ }
+
+ if (_left_button_down) {
+ e.event = WE_POPUPMENU_OVER;
+ e.we.popupmenu.pt = _cursor.pos;
+ } else {
+ _popup_menu_active = false;
+ e.event = WE_POPUPMENU_SELECT;
+ e.we.popupmenu.pt = _cursor.pos;
+ }
+
+ w->wndproc(w, &e);
+
+ return false;
+}
+
+static bool HandleMouseOver(void)
+{
+ Window *w;
+ WindowEvent e;
+ static Window *last_w = NULL;
+
+ w = FindWindowFromPt(_cursor.pos.x, _cursor.pos.y);
+
+ // We changed window, put a MOUSEOVER event to the last window
+ if (last_w != NULL && last_w != w) {
+ e.event = WE_MOUSEOVER;
+ e.we.mouseover.pt.x = -1;
+ e.we.mouseover.pt.y = -1;
+ if (last_w->wndproc) last_w->wndproc(last_w, &e);
+ }
+ last_w = w;
+
+ if (w != NULL) {
+ // send an event in client coordinates.
+ e.event = WE_MOUSEOVER;
+ e.we.mouseover.pt.x = _cursor.pos.x - w->left;
+ e.we.mouseover.pt.y = _cursor.pos.y - w->top;
+ if (w->widget != NULL) {
+ e.we.mouseover.widget = GetWidgetFromPos(w, e.we.mouseover.pt.x, e.we.mouseover.pt.y);
+ }
+ w->wndproc(w, &e);
+ }
+
+ // Mouseover never stops execution
+ return true;
+}
+
+/** Update all the widgets of a window based on their resize flags
+ * Both the areas of the old window and the new sized window are set dirty
+ * ensuring proper redrawal.
+ * @param w Window to resize
+ * @param x delta x-size of changed window (positive if larger, etc.(
+ * @param y delta y-size of changed window */
+void ResizeWindow(Window *w, int x, int y)
+{
+ Widget *wi;
+ bool resize_height = false;
+ bool resize_width = false;
+
+ if (x == 0 && y == 0) return;
+
+ SetWindowDirty(w);
+ for (wi = w->widget; wi->type != WWT_LAST; wi++) {
+ /* Isolate the resizing flags */
+ byte rsizeflag = GB(wi->display_flags, 0, 4);
+
+ if (rsizeflag == RESIZE_NONE) continue;
+
+ /* Resize the widget based on its resize-flag */
+ if (rsizeflag & RESIZE_LEFT) {
+ wi->left += x;
+ resize_width = true;
+ }
+
+ if (rsizeflag & RESIZE_RIGHT) {
+ wi->right += x;
+ resize_width = true;
+ }
+
+ if (rsizeflag & RESIZE_TOP) {
+ wi->top += y;
+ resize_height = true;
+ }
+
+ if (rsizeflag & RESIZE_BOTTOM) {
+ wi->bottom += y;
+ resize_height = true;
+ }
+ }
+
+ /* We resized at least 1 widget, so let's resize the window totally */
+ if (resize_width) w->width += x;
+ if (resize_height) w->height += y;
+
+ SetWindowDirty(w);
+}
+
+static bool _dragging_window;
+
+static bool HandleWindowDragging(void)
+{
+ Window* const *wz;
+ // Get out immediately if no window is being dragged at all.
+ if (!_dragging_window) return true;
+
+ // Otherwise find the window...
+ FOR_ALL_WINDOWS(wz) {
+ Window *w = *wz;
+
+ if (w->flags4 & WF_DRAGGING) {
+ const Widget *t = &w->widget[1]; // the title bar ... ugh
+ const Window *v;
+ int x;
+ int y;
+ int nx;
+ int ny;
+
+ // Stop the dragging if the left mouse button was released
+ if (!_left_button_down) {
+ w->flags4 &= ~WF_DRAGGING;
+ break;
+ }
+
+ SetWindowDirty(w);
+
+ x = _cursor.pos.x + _drag_delta.x;
+ y = _cursor.pos.y + _drag_delta.y;
+ nx = x;
+ ny = y;
+
+ if (_patches.window_snap_radius != 0) {
+ Window* const *vz;
+
+ int hsnap = _patches.window_snap_radius;
+ int vsnap = _patches.window_snap_radius;
+ int delta;
+
+ FOR_ALL_WINDOWS(vz) {
+ const Window *v = *vz;
+
+ if (v == w) continue; // Don't snap at yourself
+
+ if (y + w->height > v->top && y < v->top + v->height) {
+ // Your left border <-> other right border
+ delta = abs(v->left + v->width - x);
+ if (delta <= hsnap) {
+ nx = v->left + v->width;
+ hsnap = delta;
+ }
+
+ // Your right border <-> other left border
+ delta = abs(v->left - x - w->width);
+ if (delta <= hsnap) {
+ nx = v->left - w->width;
+ hsnap = delta;
+ }
+ }
+
+ if (w->top + w->height >= v->top && w->top <= v->top + v->height) {
+ // Your left border <-> other left border
+ delta = abs(v->left - x);
+ if (delta <= hsnap) {
+ nx = v->left;
+ hsnap = delta;
+ }
+
+ // Your right border <-> other right border
+ delta = abs(v->left + v->width - x - w->width);
+ if (delta <= hsnap) {
+ nx = v->left + v->width - w->width;
+ hsnap = delta;
+ }
+ }
+
+ if (x + w->width > v->left && x < v->left + v->width) {
+ // Your top border <-> other bottom border
+ delta = abs(v->top + v->height - y);
+ if (delta <= vsnap) {
+ ny = v->top + v->height;
+ vsnap = delta;
+ }
+
+ // Your bottom border <-> other top border
+ delta = abs(v->top - y - w->height);
+ if (delta <= vsnap) {
+ ny = v->top - w->height;
+ vsnap = delta;
+ }
+ }
+
+ if (w->left + w->width >= v->left && w->left <= v->left + v->width) {
+ // Your top border <-> other top border
+ delta = abs(v->top - y);
+ if (delta <= vsnap) {
+ ny = v->top;
+ vsnap = delta;
+ }
+
+ // Your bottom border <-> other bottom border
+ delta = abs(v->top + v->height - y - w->height);
+ if (delta <= vsnap) {
+ ny = v->top + v->height - w->height;
+ vsnap = delta;
+ }
+ }
+ }
+ }
+
+ // Make sure the window doesn't leave the screen
+ // 13 is the height of the title bar
+ nx = clamp(nx, 13 - t->right, _screen.width - 13 - t->left);
+ ny = clamp(ny, 0, _screen.height - 13);
+
+ // Make sure the title bar isn't hidden by behind the main tool bar
+ v = FindWindowById(WC_MAIN_TOOLBAR, 0);
+ if (v != NULL) {
+ int v_bottom = v->top + v->height;
+ int v_right = v->left + v->width;
+ if (ny + t->top >= v->top && ny + t->top < v_bottom) {
+ if ((v->left < 13 && nx + t->left < v->left) ||
+ (v_right > _screen.width - 13 && nx + t->right > v_right)) {
+ ny = v_bottom;
+ } else {
+ if (nx + t->left > v->left - 13 &&
+ nx + t->right < v_right + 13) {
+ if (w->top >= v_bottom) {
+ ny = v_bottom;
+ } else if (w->left < nx) {
+ nx = v->left - 13 - t->left;
+ } else {
+ nx = v_right + 13 - t->right;
+ }
+ }
+ }
+ }
+ }
+
+ if (w->viewport != NULL) {
+ w->viewport->left += nx - w->left;
+ w->viewport->top += ny - w->top;
+ }
+ w->left = nx;
+ w->top = ny;
+
+ SetWindowDirty(w);
+ return false;
+ } else if (w->flags4 & WF_SIZING) {
+ WindowEvent e;
+ int x, y;
+
+ /* Stop the sizing if the left mouse button was released */
+ if (!_left_button_down) {
+ w->flags4 &= ~WF_SIZING;
+ SetWindowDirty(w);
+ break;
+ }
+
+ x = _cursor.pos.x - _drag_delta.x;
+ y = _cursor.pos.y - _drag_delta.y;
+
+ /* X and Y has to go by step.. calculate it.
+ * The cast to int is necessary else x/y are implicitly casted to
+ * unsigned int, which won't work. */
+ if (w->resize.step_width > 1) x -= x % (int)w->resize.step_width;
+
+ if (w->resize.step_height > 1) y -= y % (int)w->resize.step_height;
+
+ /* Check if we don't go below the minimum set size */
+ if ((int)w->width + x < (int)w->resize.width)
+ x = w->resize.width - w->width;
+ if ((int)w->height + y < (int)w->resize.height)
+ y = w->resize.height - w->height;
+
+ /* Window already on size */
+ if (x == 0 && y == 0) return false;
+
+ /* Now find the new cursor pos.. this is NOT _cursor, because
+ we move in steps. */
+ _drag_delta.x += x;
+ _drag_delta.y += y;
+
+ /* ResizeWindow sets both pre- and after-size to dirty for redrawal */
+ ResizeWindow(w, x, y);
+
+ e.event = WE_RESIZE;
+ e.we.sizing.size.x = x + w->width;
+ e.we.sizing.size.y = y + w->height;
+ e.we.sizing.diff.x = x;
+ e.we.sizing.diff.y = y;
+ w->wndproc(w, &e);
+ return false;
+ }
+ }
+
+ _dragging_window = false;
+ return false;
+}
+
+static void StartWindowDrag(Window *w)
+{
+ w->flags4 |= WF_DRAGGING;
+ _dragging_window = true;
+
+ _drag_delta.x = w->left - _cursor.pos.x;
+ _drag_delta.y = w->top - _cursor.pos.y;
+
+ BringWindowToFront(w);
+ DeleteWindowById(WC_DROPDOWN_MENU, 0);
+}
+
+static void StartWindowSizing(Window *w)
+{
+ w->flags4 |= WF_SIZING;
+ _dragging_window = true;
+
+ _drag_delta.x = _cursor.pos.x;
+ _drag_delta.y = _cursor.pos.y;
+
+ BringWindowToFront(w);
+ DeleteWindowById(WC_DROPDOWN_MENU, 0);
+}
+
+
+static bool HandleScrollbarScrolling(void)
+{
+ Window* const *wz;
+ int i;
+ int pos;
+ Scrollbar *sb;
+
+ // Get out quickly if no item is being scrolled
+ if (!_scrolling_scrollbar) return true;
+
+ // Find the scrolling window
+ FOR_ALL_WINDOWS(wz) {
+ Window *w = *wz;
+
+ if (w->flags4 & WF_SCROLL_MIDDLE) {
+ // Abort if no button is clicked any more.
+ if (!_left_button_down) {
+ w->flags4 &= ~WF_SCROLL_MIDDLE;
+ SetWindowDirty(w);
+ break;
+ }
+
+ if (w->flags4 & WF_HSCROLL) {
+ sb = &w->hscroll;
+ i = _cursor.pos.x - _cursorpos_drag_start.x;
+ } else if (w->flags4 & WF_SCROLL2){
+ sb = &w->vscroll2;
+ i = _cursor.pos.y - _cursorpos_drag_start.y;
+ } else {
+ sb = &w->vscroll;
+ i = _cursor.pos.y - _cursorpos_drag_start.y;
+ }
+
+ // Find the item we want to move to and make sure it's inside bounds.
+ pos = min(max(0, i + _scrollbar_start_pos) * sb->count / _scrollbar_size, max(0, sb->count - sb->cap));
+ if (pos != sb->pos) {
+ sb->pos = pos;
+ SetWindowDirty(w);
+ }
+ return false;
+ }
+ }
+
+ _scrolling_scrollbar = false;
+ return false;
+}
+
+static bool HandleViewportScroll(void)
+{
+ WindowEvent e;
+ Window *w;
+
+ if (!_scrolling_viewport) return true;
+
+ w = FindWindowFromPt(_cursor.pos.x, _cursor.pos.y);
+
+ if (!_right_button_down || w == NULL) {
+ _cursor.fix_at = false;
+ _scrolling_viewport = false;
+ return true;
+ }
+
+ if (_patches.reverse_scroll) {
+ e.we.scroll.delta.x = -_cursor.delta.x;
+ e.we.scroll.delta.y = -_cursor.delta.y;
+ } else {
+ e.we.scroll.delta.x = _cursor.delta.x;
+ e.we.scroll.delta.y = _cursor.delta.y;
+ }
+
+ /* Create a scroll-event and send it to the window */
+ e.event = WE_SCROLL;
+ w->wndproc(w, &e);
+
+ _cursor.delta.x = 0;
+ _cursor.delta.y = 0;
+ return false;
+}
+
+/** Check if a window can be made top-most window, and if so do
+ * it. If a window does not obscure any other windows, it will not
+ * be brought to the foreground. Also if the only obscuring windows
+ * are so-called system-windows, the window will not be moved.
+ * The function will return false when a child window of this window is a
+ * modal-popup; function returns a false and child window gets a white border
+ * @param w Window to bring on-top
+ * @return false if the window has an active modal child, true otherwise */
+static bool MaybeBringWindowToFront(const Window *w)
+{
+ bool bring_to_front = false;
+ Window* const *wz;
+ Window* const *uz;
+
+ if (w->window_class == WC_MAIN_WINDOW ||
+ IsVitalWindow(w) ||
+ w->window_class == WC_TOOLTIPS ||
+ w->window_class == WC_DROPDOWN_MENU) {
+ return true;
+ }
+
+ wz = FindWindowZPosition(w);
+ for (uz = wz; ++uz != _last_z_window;) {
+ Window *u = *uz;
+
+ /* A modal child will prevent the activation of the parent window */
+ if (u->parent == w && (u->desc_flags & WDF_MODAL)) {
+ u->flags4 |= WF_WHITE_BORDER_MASK;
+ SetWindowDirty(u);
+ return false;
+ }
+
+ if (u->window_class == WC_MAIN_WINDOW ||
+ IsVitalWindow(u) ||
+ u->window_class == WC_TOOLTIPS ||
+ u->window_class == WC_DROPDOWN_MENU) {
+ continue;
+ }
+
+ /* Window sizes don't interfere, leave z-order alone */
+ if (w->left + w->width <= u->left ||
+ u->left + u->width <= w->left ||
+ w->top + w->height <= u->top ||
+ u->top + u->height <= w->top) {
+ continue;
+ }
+
+ bring_to_front = true;
+ }
+
+ if (bring_to_front) BringWindowToFront(w);
+ return true;
+}
+
+/** Send a message from one window to another. The receiving window is found by
+ * @param w @see Window pointer pointing to the other window
+ * @param msg Specifies the message to be sent
+ * @param wparam Specifies additional message-specific information
+ * @param lparam Specifies additional message-specific information
+ */
+static void SendWindowMessageW(Window *w, uint msg, uint wparam, uint lparam)
+{
+ WindowEvent e;
+
+ e.event = WE_MESSAGE;
+ e.we.message.msg = msg;
+ e.we.message.wparam = wparam;
+ e.we.message.lparam = lparam;
+
+ w->wndproc(w, &e);
+}
+
+/** Send a message from one window to another. The receiving window is found by
+ * @param wnd_class @see WindowClass class AND
+ * @param wnd_num @see WindowNumber number, mostly 0
+ * @param msg Specifies the message to be sent
+ * @param wparam Specifies additional message-specific information
+ * @param lparam Specifies additional message-specific information
+ */
+void SendWindowMessage(WindowClass wnd_class, WindowNumber wnd_num, uint msg, uint wparam, uint lparam)
+{
+ Window *w = FindWindowById(wnd_class, wnd_num);
+ if (w != NULL) SendWindowMessageW(w, msg, wparam, lparam);
+}
+
+/** Send a message from one window to another. The message will be sent
+ * to ALL windows of the windowclass specified in the first parameter
+ * @param wnd_class @see WindowClass class
+ * @param msg Specifies the message to be sent
+ * @param wparam Specifies additional message-specific information
+ * @param lparam Specifies additional message-specific information
+ */
+void SendWindowMessageClass(WindowClass wnd_class, uint msg, uint wparam, uint lparam)
+{
+ Window* const *wz;
+
+ FOR_ALL_WINDOWS(wz) {
+ if ((*wz)->window_class == wnd_class) SendWindowMessageW(*wz, msg, wparam, lparam);
+ }
+}
+
+/** Handle keyboard input.
+ * @param key Lower 8 bits contain the ASCII character, the higher
+ * 16 bits the keycode */
+void HandleKeypress(uint32 key)
+{
+ Window* const *wz;
+ WindowEvent e;
+ /* Stores if a window with a textfield for typing is open
+ * If this is the case, keypress events are only passed to windows with text fields and
+ * to thein this main toolbar. */
+ bool query_open = false;
+
+ /*
+ * During the generation of the world, there might be
+ * another thread that is currently building for example
+ * a road. To not interfere with those tasks, we should
+ * NOT change the _current_player here.
+ *
+ * This is not necessary either, as the only events that
+ * can be handled are the 'close application' events
+ */
+ if (!IsGeneratingWorld()) _current_player = _local_player;
+
+ // Setup event
+ e.event = WE_KEYPRESS;
+ e.we.keypress.key = GB(key, 0, 16);
+ e.we.keypress.keycode = GB(key, 16, 16);
+ e.we.keypress.cont = true;
+
+ // check if we have a query string window open before allowing hotkeys
+ if (FindWindowById(WC_QUERY_STRING, 0) != NULL ||
+ FindWindowById(WC_SEND_NETWORK_MSG, 0) != NULL ||
+ FindWindowById(WC_GENERATE_LANDSCAPE, 0) != NULL ||
+ FindWindowById(WC_CONSOLE, 0) != NULL ||
+ FindWindowById(WC_SAVELOAD, 0) != NULL) {
+ query_open = true;
+ }
+
+ // Call the event, start with the uppermost window.
+ for (wz = _last_z_window; wz != _z_windows;) {
+ Window *w = *--wz;
+
+ // if a query window is open, only call the event for certain window types
+ if (query_open &&
+ w->window_class != WC_QUERY_STRING &&
+ w->window_class != WC_SEND_NETWORK_MSG &&
+ w->window_class != WC_GENERATE_LANDSCAPE &&
+ w->window_class != WC_CONSOLE &&
+ w->window_class != WC_SAVELOAD) {
+ continue;
+ }
+ w->wndproc(w, &e);
+ if (!e.we.keypress.cont) break;
+ }
+
+ if (e.we.keypress.cont) {
+ Window *w = FindWindowById(WC_MAIN_TOOLBAR, 0);
+ // When there is no toolbar w is null, check for that
+ if (w != NULL) w->wndproc(w, &e);
+ }
+}
+
+extern void UpdateTileSelection(void);
+extern bool VpHandlePlaceSizingDrag(void);
+
+static int _input_events_this_tick = 0;
+
+static void HandleAutoscroll(void)
+{
+ Window *w;
+ ViewPort *vp;
+ int x = _cursor.pos.x;
+ int y = _cursor.pos.y;
+
+ if (_input_events_this_tick != 0) {
+ /* HandleAutoscroll is called only once per GameLoop() - so we can clear the counter here */
+ _input_events_this_tick = 0;
+ /* there were some inputs this tick, don't scroll ??? */
+ return;
+ }
+
+ if (_patches.autoscroll && _game_mode != GM_MENU && !IsGeneratingWorld()) {
+ w = FindWindowFromPt(x, y);
+ if (w == NULL || w->flags4 & WF_DISABLE_VP_SCROLL) return;
+ vp = IsPtInWindowViewport(w, x, y);
+ if (vp != NULL) {
+ x -= vp->left;
+ y -= vp->top;
+ //here allows scrolling in both x and y axis
+#define scrollspeed 3
+ if (x - 15 < 0) {
+ WP(w, vp_d).scrollpos_x += (x - 15) * scrollspeed << vp->zoom;
+ } else if (15 - (vp->width - x) > 0) {
+ WP(w, vp_d).scrollpos_x += (15 - (vp->width - x)) * scrollspeed << vp->zoom;
+ }
+ if (y - 15 < 0) {
+ WP(w, vp_d).scrollpos_y += (y - 15) * scrollspeed << vp->zoom;
+ } else if (15 - (vp->height - y) > 0) {
+ WP(w,vp_d).scrollpos_y += (15 - (vp->height - y)) * scrollspeed << vp->zoom;
+ }
+#undef scrollspeed
+ }
+ }
+}
+
+void MouseLoop(int click, int mousewheel)
+{
+ int x,y;
+ Window *w;
+ ViewPort *vp;
+
+ DecreaseWindowCounters();
+ HandlePlacePresize();
+ UpdateTileSelection();
+ if (!VpHandlePlaceSizingDrag()) return;
+ if (!HandleDragDrop()) return;
+ if (!HandlePopupMenu()) return;
+ if (!HandleWindowDragging()) return;
+ if (!HandleScrollbarScrolling()) return;
+ if (!HandleViewportScroll()) return;
+ if (!HandleMouseOver()) return;
+
+ x = _cursor.pos.x;
+ y = _cursor.pos.y;
+
+ if (click == 0 && mousewheel == 0) return;
+
+ w = FindWindowFromPt(x, y);
+ if (w == NULL) return;
+ if (!MaybeBringWindowToFront(w)) return;
+ vp = IsPtInWindowViewport(w, x, y);
+
+ /* Don't allow any action in a viewport if either in menu of in generating world */
+ if (vp != NULL && (_game_mode == GM_MENU || IsGeneratingWorld())) return;
+
+ if (mousewheel != 0) {
+ WindowEvent e;
+
+ /* Send WE_MOUSEWHEEL event to window */
+ e.event = WE_MOUSEWHEEL;
+ e.we.wheel.wheel = mousewheel;
+ w->wndproc(w, &e);
+
+ /* Dispatch a MouseWheelEvent for widgets if it is not a viewport */
+ if (vp == NULL) DispatchMouseWheelEvent(w, GetWidgetFromPos(w, x - w->left, y - w->top), mousewheel);
+ }
+
+ if (vp != NULL) {
+ switch (click) {
+ case 1:
+ DEBUG(misc, 2, "Cursor: 0x%X (%d)", _cursor.sprite, _cursor.sprite);
+ if (_thd.place_mode != 0 &&
+ // query button and place sign button work in pause mode
+ _cursor.sprite != SPR_CURSOR_QUERY &&
+ _cursor.sprite != SPR_CURSOR_SIGN &&
+ _pause != 0 &&
+ !_cheats.build_in_pause.value) {
+ return;
+ }
+
+ if (_thd.place_mode == 0) {
+ HandleViewportClicked(vp, x, y);
+ } else {
+ PlaceObject();
+ }
+ break;
+
+ case 2:
+ if (!(w->flags4 & WF_DISABLE_VP_SCROLL)) {
+ _scrolling_viewport = true;
+ _cursor.fix_at = true;
+ }
+ break;
+ }
+ } else {
+ switch (click) {
+ case 1: DispatchLeftClickEvent(w, x - w->left, y - w->top); break;
+ case 2: DispatchRightClickEvent(w, x - w->left, y - w->top); break;
+ }
+ }
+}
+
+void HandleMouseEvents(void)
+{
+ int click;
+ int mousewheel;
+
+ /*
+ * During the generation of the world, there might be
+ * another thread that is currently building for example
+ * a road. To not interfere with those tasks, we should
+ * NOT change the _current_player here.
+ *
+ * This is not necessary either, as the only events that
+ * can be handled are the 'close application' events
+ */
+ if (!IsGeneratingWorld()) _current_player = _local_player;
+
+ // Mouse event?
+ click = 0;
+ if (_left_button_down && !_left_button_clicked) {
+ _left_button_clicked = true;
+ click = 1;
+ _input_events_this_tick++;
+ } else if (_right_button_clicked) {
+ _right_button_clicked = false;
+ click = 2;
+ _input_events_this_tick++;
+ }
+
+ mousewheel = 0;
+ if (_cursor.wheel) {
+ mousewheel = _cursor.wheel;
+ _cursor.wheel = 0;
+ _input_events_this_tick++;
+ }
+
+ MouseLoop(click, mousewheel);
+}
+
+void InputLoop(void)
+{
+ HandleMouseEvents();
+ HandleAutoscroll();
+}
+
+void UpdateWindows(void)
+{
+ Window* const *wz;
+ static int we4_timer = 0;
+ int t = we4_timer + 1;
+
+ if (t >= 100) {
+ for (wz = _last_z_window; wz != _z_windows;) {
+ CallWindowEventNP(*--wz, WE_4);
+ }
+ t = 0;
+ }
+ we4_timer = t;
+
+ for (wz = _last_z_window; wz != _z_windows;) {
+ Window *w = *--wz;
+ if (w->flags4 & WF_WHITE_BORDER_MASK) {
+ w->flags4 -= WF_WHITE_BORDER_ONE;
+
+ if (!(w->flags4 & WF_WHITE_BORDER_MASK)) SetWindowDirty(w);
+ }
+ }
+
+ DrawDirtyBlocks();
+
+ FOR_ALL_WINDOWS(wz) {
+ if ((*wz)->viewport != NULL) UpdateViewportPosition(*wz);
+ }
+ DrawTextMessage();
+ // Redraw mouse cursor in case it was hidden
+ DrawMouseCursor();
+}
+
+
+int GetMenuItemIndex(const Window *w, int x, int y)
+{
+ if ((x -= w->left) >= 0 && x < w->width && (y -= w->top + 1) >= 0) {
+ y /= 10;
+
+ if (y < WP(w, const menu_d).item_count &&
+ !HASBIT(WP(w, const menu_d).disabled_items, y)) {
+ return y;
+ }
+ }
+ return -1;
+}
+
+void InvalidateWindow(WindowClass cls, WindowNumber number)
+{
+ Window* const *wz;
+
+ FOR_ALL_WINDOWS(wz) {
+ const Window *w = *wz;
+ if (w->window_class == cls && w->window_number == number) SetWindowDirty(w);
+ }
+}
+
+void InvalidateWidget(const Window *w, byte widget_index)
+{
+ const Widget *wi = &w->widget[widget_index];
+
+ /* Don't redraw the window if the widget is invisible or of no-type */
+ if (wi->type == WWT_EMPTY || IsWindowWidgetHidden(w, widget_index)) return;
+
+ SetDirtyBlocks(w->left + wi->left, w->top + wi->top, w->left + wi->right + 1, w->top + wi->bottom + 1);
+}
+
+void InvalidateWindowWidget(WindowClass cls, WindowNumber number, byte widget_index)
+{
+ Window* const *wz;
+
+ FOR_ALL_WINDOWS(wz) {
+ const Window *w = *wz;
+ if (w->window_class == cls && w->window_number == number) {
+ InvalidateWidget(w, widget_index);
+ }
+ }
+}
+
+void InvalidateWindowClasses(WindowClass cls)
+{
+ Window* const *wz;
+
+ FOR_ALL_WINDOWS(wz) {
+ if ((*wz)->window_class == cls) SetWindowDirty(*wz);
+ }
+}
+
+void InvalidateThisWindowData(Window *w)
+{
+ CallWindowEventNP(w, WE_INVALIDATE_DATA);
+ SetWindowDirty(w);
+}
+
+void InvalidateWindowData(WindowClass cls, WindowNumber number)
+{
+ Window* const *wz;
+
+ FOR_ALL_WINDOWS(wz) {
+ Window *w = *wz;
+ if (w->window_class == cls && w->window_number == number) InvalidateThisWindowData(w);
+ }
+}
+
+void InvalidateWindowClassesData(WindowClass cls)
+{
+ Window* const *wz;
+
+ FOR_ALL_WINDOWS(wz) {
+ if ((*wz)->window_class == cls) InvalidateThisWindowData(*wz);
+ }
+}
+
+void CallWindowTickEvent(void)
+{
+ Window* const *wz;
+
+ for (wz = _last_z_window; wz != _z_windows;) {
+ CallWindowEventNP(*--wz, WE_TICK);
+ }
+}
+
+void DeleteNonVitalWindows(void)
+{
+ Window* const *wz;
+
+restart_search:
+ /* When we find the window to delete, we need to restart the search
+ * as deleting this window could cascade in deleting (many) others
+ * anywhere in the z-array */
+ FOR_ALL_WINDOWS(wz) {
+ Window *w = *wz;
+ if (w->window_class != WC_MAIN_WINDOW &&
+ w->window_class != WC_SELECT_GAME &&
+ w->window_class != WC_MAIN_TOOLBAR &&
+ w->window_class != WC_STATUS_BAR &&
+ w->window_class != WC_TOOLBAR_MENU &&
+ w->window_class != WC_TOOLTIPS &&
+ (w->flags4 & WF_STICKY) == 0) { // do not delete windows which are 'pinned'
+
+ DeleteWindow(w);
+ goto restart_search;
+ }
+ }
+}
+
+/* It is possible that a stickied window gets to a position where the
+ * 'close' button is outside the gaming area. You cannot close it then; except
+ * with this function. It closes all windows calling the standard function,
+ * then, does a little hacked loop of closing all stickied windows. Note
+ * that standard windows (status bar, etc.) are not stickied, so these aren't affected */
+void DeleteAllNonVitalWindows(void)
+{
+ Window* const *wz;
+
+ /* Delete every window except for stickied ones, then sticky ones as well */
+ DeleteNonVitalWindows();
+
+restart_search:
+ /* When we find the window to delete, we need to restart the search
+ * as deleting this window could cascade in deleting (many) others
+ * anywhere in the z-array */
+ FOR_ALL_WINDOWS(wz) {
+ if ((*wz)->flags4 & WF_STICKY) {
+ DeleteWindow(*wz);
+ goto restart_search;
+ }
+ }
+}
+
+/* Delete all always on-top windows to get an empty screen */
+void HideVitalWindows(void)
+{
+ DeleteWindowById(WC_MAIN_TOOLBAR, 0);
+ DeleteWindowById(WC_STATUS_BAR, 0);
+}
+
+int PositionMainToolbar(Window *w)
+{
+ DEBUG(misc, 5, "Repositioning Main Toolbar...");
+
+ if (w == NULL || w->window_class != WC_MAIN_TOOLBAR) {
+ w = FindWindowById(WC_MAIN_TOOLBAR, 0);
+ }
+
+ switch (_patches.toolbar_pos) {
+ case 1: w->left = (_screen.width - w->width) / 2; break;
+ case 2: w->left = _screen.width - w->width; break;
+ default: w->left = 0;
+ }
+ SetDirtyBlocks(0, 0, _screen.width, w->height); // invalidate the whole top part
+ return w->left;
+}
+
+void RelocateAllWindows(int neww, int newh)
+{
+ Window* const *wz;
+
+ FOR_ALL_WINDOWS(wz) {
+ Window *w = *wz;
+ int left, top;
+
+ if (w->window_class == WC_MAIN_WINDOW) {
+ ViewPort *vp = w->viewport;
+ vp->width = w->width = neww;
+ vp->height = w->height = newh;
+ vp->virtual_width = neww << vp->zoom;
+ vp->virtual_height = newh << vp->zoom;
+ continue; // don't modify top,left
+ }
+
+ /* XXX - this probably needs something more sane. For example specying
+ * in a 'backup'-desc that the window should always be centred. */
+ switch (w->window_class) {
+ case WC_MAIN_TOOLBAR:
+ top = w->top;
+ left = PositionMainToolbar(w); // changes toolbar orientation
+ break;
+
+ case WC_SELECT_GAME:
+ case WC_GAME_OPTIONS:
+ case WC_NETWORK_WINDOW:
+ top = (newh - w->height) >> 1;
+ left = (neww - w->width) >> 1;
+ break;
+
+ case WC_NEWS_WINDOW:
+ top = newh - w->height;
+ left = (neww - w->width) >> 1;
+ break;
+
+ case WC_STATUS_BAR:
+ top = newh - w->height;
+ left = (neww - w->width) >> 1;
+ break;
+
+ case WC_SEND_NETWORK_MSG:
+ top = (newh - 26); // 26 = height of status bar + height of chat bar
+ left = (neww - w->width) >> 1;
+ break;
+
+ case WC_CONSOLE:
+ IConsoleResize(w);
+ continue;
+
+ default:
+ left = w->left;
+ if (left + (w->width >> 1) >= neww) left = neww - w->width;
+ top = w->top;
+ if (top + (w->height >> 1) >= newh) top = newh - w->height;
+ break;
+ }
+
+ if (w->viewport != NULL) {
+ w->viewport->left += left - w->left;
+ w->viewport->top += top - w->top;
+ }
+
+ w->left = left;
+ w->top = top;
+ }
+}
diff --git a/src/window.h b/src/window.h
new file mode 100644
index 000000000..2e6fd8b94
--- /dev/null
+++ b/src/window.h
@@ -0,0 +1,843 @@
+/* $Id$ */
+
+#ifndef WINDOW_H
+#define WINDOW_H
+
+#include "macros.h"
+#include "string.h"
+#include "order.h"
+
+typedef struct WindowEvent WindowEvent;
+
+typedef void WindowProc(Window *w, WindowEvent *e);
+
+/* How the resize system works:
+ First, you need to add a WWT_RESIZEBOX to the widgets, and you need
+ to add the flag WDF_RESIZABLE to the window. Now the window is ready
+ to resize itself.
+ As you may have noticed, all widgets have a RESIZE_XXX in their line.
+ This lines controls how the widgets behave on resize. RESIZE_NONE means
+ it doesn't do anything. Any other option let's one of the borders
+ move with the changed width/height. So if a widget has
+ RESIZE_RIGHT, and the window is made 5 pixels wider by the user,
+ the right of the window will also be made 5 pixels wider.
+ Now, what if you want to clamp a widget to the bottom? Give it the flag
+ RESIZE_TB. This is RESIZE_TOP + RESIZE_BOTTOM. Now if the window gets
+ 5 pixels bigger, both the top and bottom gets 5 bigger, so the whole
+ widgets moves downwards without resizing, and appears to be clamped
+ to the bottom. Nice aint it?
+ You should know one more thing about this system. Most windows can't
+ handle an increase of 1 pixel. So there is a step function, which
+ let the windowsize only be changed by X pixels. You configure this
+ after making the window, like this:
+ w->resize.step_height = 10;
+ Now the window will only change in height in steps of 10.
+ You can also give a minimum width and height. The default value is
+ the default height/width of the window itself. You can change this
+ AFTER window-creation, with:
+ w->resize.width or w->resize.height.
+ That was all.. good luck, and enjoy :) -- TrueLight */
+
+enum ResizeFlags {
+ RESIZE_NONE = 0,
+
+ RESIZE_LEFT = 1,
+ RESIZE_RIGHT = 2,
+ RESIZE_TOP = 4,
+ RESIZE_BOTTOM = 8,
+
+ RESIZE_LR = RESIZE_LEFT | RESIZE_RIGHT,
+ RESIZE_RB = RESIZE_RIGHT | RESIZE_BOTTOM,
+ RESIZE_TB = RESIZE_TOP | RESIZE_BOTTOM,
+ RESIZE_LRB = RESIZE_LEFT | RESIZE_RIGHT | RESIZE_BOTTOM,
+ RESIZE_LRTB = RESIZE_LEFT | RESIZE_RIGHT | RESIZE_TOP | RESIZE_BOTTOM,
+ RESIZE_RTB = RESIZE_RIGHT | RESIZE_TOP | RESIZE_BOTTOM,
+
+ /* The following flags are used by the system to specify what is disabled, hidden, or clicked
+ * They are used in the same place as the above RESIZE_x flags, Widget visual_flags.
+ * These states are used in exceptions. If nothing is specified, they will indicate
+ * Enabled, visible or unclicked widgets*/
+ WIDG_DISABLED = 4, // widget is greyed out, not available
+ WIDG_HIDDEN = 5, // widget is made invisible
+ WIDG_LOWERED = 6, // widget is paint lowered, a pressed button in fact
+} ResizeFlag;
+
+/* used to indicate the end of widgets' list for vararg functions */
+enum {
+ WIDGET_LIST_END = -1,
+};
+
+typedef struct Widget {
+ byte type; ///< Widget type, see @WindowWidgetTypes
+ byte display_flags; ///< Resize direction, alignment, etc. during resizing, see @ResizeFlags
+ byte color; ///< Widget colour, see docs/ottd-colourtext-palette.png
+ uint16 left, right, top, bottom; ///< The position offsets inside the window
+ uint16 data; ///< The String/Image or special code (list-matrixes) of a widget
+ StringID tooltips; ///< Tooltips that are shown when rightclicking on a widget
+} Widget;
+
+typedef enum FrameFlags {
+ FR_TRANSPARENT = 0x01, ///< Makes the background transparent if set
+ FR_BORDERONLY = 0x10, ///< Draw border only, no background
+ FR_LOWERED = 0x20, ///< If set the frame is lowered and the background color brighter (ie. buttons when pressed)
+ FR_DARKENED = 0x40, ///< If set the background is darker, allows for lowered frames with normal background color when used with FR_LOWERED (ie. dropdown boxes)
+} FrameFlags;
+
+void DrawFrameRect(int left, int top, int right, int bottom, int color, FrameFlags flags);
+
+enum WindowEventCodes {
+ WE_CREATE,
+ WE_DESTROY,
+ WE_PAINT,
+ WE_KEYPRESS,
+ WE_CLICK,
+ WE_RCLICK,
+ WE_MOUSEOVER,
+ WE_MOUSELOOP,
+ WE_MOUSEWHEEL,
+ WE_TICK,
+ WE_4,
+ WE_TIMEOUT,
+ WE_PLACE_OBJ,
+ WE_ABORT_PLACE_OBJ,
+ WE_ON_EDIT_TEXT,
+ WE_ON_EDIT_TEXT_CANCEL,
+ WE_POPUPMENU_SELECT,
+ WE_POPUPMENU_OVER,
+ WE_DRAGDROP,
+ WE_PLACE_DRAG,
+ WE_PLACE_MOUSEUP,
+ WE_PLACE_PRESIZE,
+ WE_DROPDOWN_SELECT,
+ WE_RESIZE,
+ WE_MESSAGE,
+ WE_SCROLL,
+ WE_INVALIDATE_DATA,
+};
+
+struct WindowEvent {
+ byte event;
+ union {
+ struct{
+ Point pt;
+ int widget;
+ } click;
+
+ struct {
+ Point pt;
+ TileIndex tile;
+ TileIndex starttile;
+ int userdata;
+ } place;
+
+ struct {
+ Point pt;
+ int widget;
+ } dragdrop;
+
+ struct {
+ Point size;
+ Point diff;
+ } sizing;
+
+ struct {
+ char *str;
+ } edittext;
+
+ struct {
+ Point pt;
+ } popupmenu;
+
+ struct {
+ int button;
+ int index;
+ } dropdown;
+
+ struct {
+ Point pt;
+ int widget;
+ } mouseover;
+
+ struct {
+ bool cont; // continue the search? (default true)
+ uint16 key; // 16-bit Unicode value of the key
+ uint16 keycode;// untranslated key (including shift-state)
+ } keypress;
+
+ struct {
+ uint msg; // message to be sent
+ uint wparam; // additional message-specific information
+ uint lparam; // additional message-specific information
+ } message;
+
+ struct {
+ Point delta; // delta position against position of last call
+ } scroll;
+
+ struct {
+ int wheel; // how much was 'wheel'd'
+ } wheel;
+ } we;
+};
+
+enum WindowKeyCodes {
+ WKC_SHIFT = 0x8000,
+ WKC_CTRL = 0x4000,
+ WKC_ALT = 0x2000,
+ WKC_META = 0x1000,
+
+ // Special ones
+ WKC_NONE = 0,
+ WKC_ESC = 1,
+ WKC_BACKSPACE = 2,
+ WKC_INSERT = 3,
+ WKC_DELETE = 4,
+
+ WKC_PAGEUP = 5,
+ WKC_PAGEDOWN = 6,
+ WKC_END = 7,
+ WKC_HOME = 8,
+
+ // Arrow keys
+ WKC_LEFT = 9,
+ WKC_UP = 10,
+ WKC_RIGHT = 11,
+ WKC_DOWN = 12,
+
+ // Return & tab
+ WKC_RETURN = 13,
+ WKC_TAB = 14,
+
+ // Numerical keyboard
+ WKC_NUM_0 = 16,
+ WKC_NUM_1 = 17,
+ WKC_NUM_2 = 18,
+ WKC_NUM_3 = 19,
+ WKC_NUM_4 = 20,
+ WKC_NUM_5 = 21,
+ WKC_NUM_6 = 22,
+ WKC_NUM_7 = 23,
+ WKC_NUM_8 = 24,
+ WKC_NUM_9 = 25,
+ WKC_NUM_DIV = 26,
+ WKC_NUM_MUL = 27,
+ WKC_NUM_MINUS = 28,
+ WKC_NUM_PLUS = 29,
+ WKC_NUM_ENTER = 30,
+ WKC_NUM_DECIMAL = 31,
+
+ // Space
+ WKC_SPACE = 32,
+
+ // Function keys
+ WKC_F1 = 33,
+ WKC_F2 = 34,
+ WKC_F3 = 35,
+ WKC_F4 = 36,
+ WKC_F5 = 37,
+ WKC_F6 = 38,
+ WKC_F7 = 39,
+ WKC_F8 = 40,
+ WKC_F9 = 41,
+ WKC_F10 = 42,
+ WKC_F11 = 43,
+ WKC_F12 = 44,
+
+ // backquote is the key left of "1"
+ // we only store this key here, no matter what character is really mapped to it
+ // on a particular keyboard. (US keyboard: ` and ~ ; German keyboard: ^ and °)
+ WKC_BACKQUOTE = 45,
+ WKC_PAUSE = 46,
+
+ // 0-9 are mapped to 48-57
+ // A-Z are mapped to 65-90
+ // a-z are mapped to 97-122
+};
+
+typedef struct WindowDesc {
+ int16 left, top, width, height;
+ WindowClass cls;
+ WindowClass parent_cls;
+ uint32 flags;
+ const Widget *widgets;
+ WindowProc *proc;
+} WindowDesc;
+
+enum WindowDefaultFlag {
+ WDF_STD_TOOLTIPS = 1, /* use standard routine when displaying tooltips */
+ WDF_DEF_WIDGET = 2, /* default widget control for some widgets in the on click event */
+ WDF_STD_BTN = 4, /* default handling for close and drag widgets (widget no 0 and 1) */
+
+ WDF_UNCLICK_BUTTONS = 16, /* Unclick buttons when the window event times out */
+ WDF_STICKY_BUTTON = 32, /* Set window to sticky mode; they are not closed unless closed with 'X' (widget 2) */
+ WDF_RESIZABLE = 64, /* A window can be resized */
+ WDF_MODAL = 128, /* The window is a modal child of some other window, meaning the parent is 'inactive' */
+};
+
+/* can be used as x or y coordinates to cause a specific placement */
+enum WindowDefaultPosition {
+ WDP_AUTO = -1, ///< Find a place automatically
+ WDP_CENTER = -2, ///< Center the window (left/right or top/bottom)
+ WDP_ALIGN_TBR = -3, ///< Align the right side of the window with the right side of the main toolbar
+ WDP_ALIGN_TBL = -4, ///< Align the left side of the window with the left side of the main toolbar
+};
+
+typedef struct Textbuf {
+ char *buf; /* buffer in which text is saved */
+ uint16 maxlength, maxwidth; /* the maximum size of the buffer. Maxwidth specifies screensize in pixels, maxlength is in bytes */
+ uint16 length, width; /* the current size of the string. Width specifies screensize in pixels, length is in bytes */
+ bool caret; /* is the caret ("_") visible or not */
+ uint16 caretpos; /* the current position of the caret in the buffer, in bytes */
+ uint16 caretxoffs; /* the current position of the caret in pixels */
+} Textbuf;
+
+#define WP(ptr,str) (*(str*)(ptr)->custom)
+/* You cannot 100% reliably calculate the biggest custom struct as
+ * the number of pointers in it and alignment will have a huge impact.
+ * 96 is the largest window-size for 64-bit machines currently */
+#define WINDOW_CUSTOM_SIZE 96
+
+typedef struct Scrollbar {
+ uint16 count, cap, pos;
+} Scrollbar;
+
+typedef struct ResizeInfo {
+ uint width; /* Minimum width and height */
+ uint height;
+
+ uint step_width; /* In how big steps the width and height go */
+ uint step_height;
+} ResizeInfo;
+
+typedef struct WindowMessage {
+ int msg;
+ int wparam;
+ int lparam;
+} WindowMessage;
+
+struct Window {
+ uint16 flags4;
+ WindowClass window_class;
+ WindowNumber window_number;
+
+ int left, top;
+ int width, height;
+
+ Scrollbar hscroll, vscroll, vscroll2;
+ ResizeInfo resize;
+
+ byte caption_color;
+
+ WindowProc *wndproc;
+ ViewPort *viewport;
+ const Widget *original_widget;
+ Widget *widget;
+ uint widget_count;
+ uint32 desc_flags;
+
+ WindowMessage message;
+ Window *parent;
+ byte custom[WINDOW_CUSTOM_SIZE];
+};
+
+typedef struct querystr_d {
+ StringID caption;
+ Textbuf text;
+ const char *orig;
+ CharSetFilter afilter;
+ bool handled;
+} querystr_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(querystr_d));
+
+typedef struct {
+ byte item_count; /* follow_vehicle */
+ byte sel_index; /* scrollpos_x */
+ byte main_button; /* scrollpos_y */
+ byte action_id;
+ StringID string_id; /* unk30 */
+ uint16 checked_items; /* unk32 */
+ byte disabled_items;
+} menu_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(menu_d));
+
+typedef struct {
+ int16 data_1, data_2, data_3;
+ int16 data_4, data_5;
+ bool close;
+ byte byte_1;
+} def_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(def_d));
+
+typedef struct {
+ void *data;
+} void_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(void_d));
+
+typedef struct {
+ uint16 base;
+ uint16 count;
+} tree_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(tree_d));
+
+typedef struct {
+ StringID string_id;
+ byte paramcount;
+ uint32 params[5];
+} tooltips_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(tooltips_d));
+
+typedef struct {
+ byte vehicle_type;
+ union {
+ byte railtype;
+ byte acc_planes; // AIRCRAFT_ONLY, ALL, HELICOPTERS_ONLY
+ } filter;
+ byte sel_index; // deprecated value, used for 'unified' ship and road
+ bool descending_sort_order;
+ byte sort_criteria;
+ EngineID sel_engine;
+ EngineID rename_engine;
+ EngineList eng_list;
+} buildvehicle_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(buildvehicle_d));
+
+typedef struct {
+ byte vehicletype;
+ byte sel_index[2];
+ EngineID sel_engine[2];
+ uint16 count[2];
+ bool wagon_btnstate; // true means engine is selected
+} replaceveh_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(replaceveh_d));
+
+typedef struct {
+ VehicleID sel;
+ byte type;
+ bool generate_list;
+ uint16 engine_list_length;
+ uint16 wagon_list_length;
+ uint16 engine_count;
+ uint16 wagon_count;
+ Vehicle **vehicle_list;
+ Vehicle **wagon_list;
+} depot_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(depot_d));
+
+typedef struct {
+ int sel;
+} order_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(order_d));
+
+typedef struct {
+ byte tab;
+} traindetails_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(traindetails_d));
+
+typedef struct {
+ int32 scroll_x;
+ int32 scroll_y;
+ int32 subscroll;
+} smallmap_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(smallmap_d));
+
+typedef struct {
+ uint32 face;
+ byte gender;
+} facesel_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(facesel_d));
+
+typedef struct {
+ int sel;
+ struct RefitOption *cargo;
+ struct RefitList *list;
+ uint length;
+ VehicleOrderID order;
+} refit_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(refit_d));
+
+typedef struct {
+ VehicleID follow_vehicle;
+ int32 scrollpos_x;
+ int32 scrollpos_y;
+} vp_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(vp_d));
+
+// vp2_d is the same as vp_d, except for the data_# values..
+typedef struct {
+ VehicleID follow_vehicle;
+ int32 scrollpos_x;
+ int32 scrollpos_y;
+ byte data_1;
+ byte data_2;
+ byte data_3;
+} vp2_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(vp2_d));
+
+typedef struct {
+ uint16 follow_vehicle;
+ int32 scrollpos_x;
+ int32 scrollpos_y;
+ NewsItem *ni;
+} news_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(news_d));
+
+typedef struct {
+ uint32 background_img;
+ int8 rank;
+} highscore_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(highscore_d));
+
+typedef struct {
+ int height;
+ uint16 counter;
+} scroller_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(scroller_d));
+
+typedef enum SortListFlags {
+ VL_DESC = 0x01, // sort descending or ascending
+ VL_RESORT = 0x02, // instruct the code to resort the list in the next loop
+ VL_REBUILD = 0x04 // create sort-listing to use for qsort and friends
+} SortListFlags;
+
+typedef struct Listing {
+ bool order; // Ascending/descending
+ byte criteria; // Sorting criteria
+} Listing;
+
+typedef struct list_d {
+ uint16 list_length; // length of the list being sorted
+ byte sort_type; // what criteria to sort on
+ SortListFlags flags; // used to control sorting/resorting/etc.
+ uint16 resort_timer; // resort list after a given amount of ticks if set
+} list_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(list_d));
+
+typedef struct message_d {
+ int msg;
+ int wparam;
+ int lparam;
+} message_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(message_d));
+
+typedef struct dropdown_d {
+ uint32 disabled_state;
+ uint32 hidden_state;
+ WindowClass parent_wnd_class;
+ WindowNumber parent_wnd_num;
+ byte parent_button;
+ byte num_items;
+ byte selected_index;
+ const StringID *items;
+ byte click_delay;
+ bool drag_mode;
+} dropdown_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(dropdown_d));
+
+
+/****************** THESE ARE NOT WIDGET TYPES!!!!! *******************/
+enum WindowWidgetBehaviours {
+ WWB_PUSHBUTTON = 1 << 5,
+
+ WWB_MASK = 0xE0,
+};
+
+
+enum WindowWidgetTypes {
+ WWT_EMPTY,
+
+ WWT_PANEL, /* simple depressed panel */
+ WWT_INSET, /* pressed (inset) panel, most commonly used as combo box _text_ area */
+ WWT_IMGBTN, /* button with image */
+ WWT_IMGBTN_2, /* button with diff image when clicked */
+
+ WWT_TEXTBTN, /* button with text */
+ WWT_TEXTBTN_2, /* button with diff text when clicked */
+ WWT_LABEL, /* centered label */
+ WWT_MATRIX,
+ WWT_SCROLLBAR,
+ WWT_FRAME, /* frame */
+ WWT_CAPTION,
+
+ WWT_HSCROLLBAR,
+ WWT_STICKYBOX,
+ WWT_SCROLL2BAR, /* 2nd vertical scrollbar*/
+ WWT_RESIZEBOX,
+ WWT_CLOSEBOX,
+ WWT_LAST, /* Last Item. use WIDGETS_END to fill up padding!! */
+
+ WWT_MASK = 0x1F,
+
+ WWT_PUSHBTN = WWT_PANEL | WWB_PUSHBUTTON,
+ WWT_PUSHTXTBTN = WWT_TEXTBTN | WWB_PUSHBUTTON,
+ WWT_PUSHIMGBTN = WWT_IMGBTN | WWB_PUSHBUTTON,
+};
+
+#define WIDGETS_END WWT_LAST, RESIZE_NONE, 0, 0, 0, 0, 0, 0, STR_NULL
+
+enum WindowFlags {
+ WF_TIMEOUT_SHL = 0,
+ WF_TIMEOUT_MASK = 7,
+ WF_DRAGGING = 1 << 3,
+ WF_SCROLL_UP = 1 << 4,
+ WF_SCROLL_DOWN = 1 << 5,
+ WF_SCROLL_MIDDLE = 1 << 6,
+ WF_HSCROLL = 1 << 7,
+ WF_SIZING = 1 << 8,
+ WF_STICKY = 1 << 9,
+
+ WF_DISABLE_VP_SCROLL = 1 << 10,
+
+ WF_WHITE_BORDER_ONE = 1 << 11,
+ WF_WHITE_BORDER_MASK = 1 << 12 | WF_WHITE_BORDER_ONE,
+ WF_SCROLL2 = 1 << 13,
+};
+
+/* window.c */
+void CallWindowEventNP(Window *w, int event);
+void CallWindowTickEvent(void);
+void SetWindowDirty(const Window *w);
+void SendWindowMessage(WindowClass wnd_class, WindowNumber wnd_num, uint msg, uint wparam, uint lparam);
+void SendWindowMessageClass(WindowClass wnd_class, uint msg, uint wparam, uint lparam);
+
+Window *FindWindowById(WindowClass cls, WindowNumber number);
+void DeleteWindow(Window *w);
+void DeletePlayerWindows(PlayerID pi);
+void ChangeWindowOwner(PlayerID old_player, PlayerID new_player);
+Window *BringWindowToFrontById(WindowClass cls, WindowNumber number);
+Window *FindWindowFromPt(int x, int y);
+
+bool IsWindowOfPrototype(const Window *w, const Widget *widget);
+void AssignWidgetToWindow(Window *w, const Widget *widget);
+Window *AllocateWindow(
+ int x,
+ int y,
+ int width,
+ int height,
+ WindowProc *proc,
+ WindowClass cls,
+ const Widget *widget);
+
+Window *AllocateWindowDesc(const WindowDesc *desc);
+Window *AllocateWindowDescFront(const WindowDesc *desc, int window_number);
+
+void DrawWindowViewport(const Window *w);
+void ResizeWindow(Window *w, int x, int y);
+
+/**
+ * Sets the enabled/disabled status of a widget.
+ * By default, widgets are enabled.
+ * On certain conditions, they have to be disabled.
+ * @param w : Window on which the widget is located
+ * @param widget_index : index of this widget in the window
+ * @param disab_stat : status to use ie: disabled = true, enabled = false
+ */
+static inline void SetWindowWidgetDisabledState(Window *w, byte widget_index, bool disab_stat)
+{
+ assert(widget_index < w->widget_count);
+ SB(w->widget[widget_index].display_flags, WIDG_DISABLED, 1, !!disab_stat);
+}
+
+/**
+ * Sets a widget to disabled.
+ * @param w : Window on which the widget is located
+ * @param widget_index : index of this widget in the window
+ */
+static inline void DisableWindowWidget(Window *w, byte widget_index)
+{
+ SetWindowWidgetDisabledState(w, widget_index, true);
+}
+
+/**
+ * Sets a widget to Enabled.
+ * @param w : Window on which the widget is located
+ * @param widget_index : index of this widget in the window
+ */
+static inline void EnableWindowWidget(Window *w, byte widget_index)
+{
+ SetWindowWidgetDisabledState(w, widget_index, false);
+}
+
+/**
+ * Gets the enabled/disabled status of a widget.
+ * @param w : Window on which the widget is located
+ * @param widget_index : index of this widget in the window
+ * @return status of the widget ie: disabled = true, enabled = false
+ */
+static inline bool IsWindowWidgetDisabled(const Window *w, byte widget_index)
+{
+ assert(widget_index < w->widget_count);
+ return HASBIT(w->widget[widget_index].display_flags, WIDG_DISABLED);
+}
+
+/**
+ * Sets the hidden/shown status of a widget.
+ * By default, widgets are visible.
+ * On certain conditions, they have to be hidden.
+ * @param w Window on which the widget is located
+ * @param widget_index index of this widget in the window
+ * @param hidden_stat status to use ie. hidden = true, visible = false
+ */
+static inline void SetWindowWidgetHiddenState(Window *w, byte widget_index, bool hidden_stat)
+{
+ assert(widget_index < w->widget_count);
+ SB(w->widget[widget_index].display_flags, WIDG_HIDDEN, 1, !!hidden_stat);
+}
+
+/**
+ * Sets a widget hidden.
+ * @param w : Window on which the widget is located
+ * @param widget_index : index of this widget in the window
+ */
+static inline void HideWindowWidget(Window *w, byte widget_index)
+{
+ SetWindowWidgetHiddenState(w, widget_index, true);
+}
+
+/**
+ * Sets a widget visible.
+ * @param w : Window on which the widget is located
+ * @param widget_index : index of this widget in the window
+ */
+static inline void ShowWindowWidget(Window *w, byte widget_index)
+{
+ SetWindowWidgetHiddenState(w, widget_index, false);
+}
+
+/**
+ * Gets the visibility of a widget.
+ * @param w : Window on which the widget is located
+ * @param widget_index : index of this widget in the window
+ * @return status of the widget ie: hidden = true, visible = false
+ */
+static inline bool IsWindowWidgetHidden(const Window *w, byte widget_index)
+{
+ assert(widget_index < w->widget_count);
+ return HASBIT(w->widget[widget_index].display_flags, WIDG_HIDDEN);
+}
+
+/**
+ * Sets the lowered/raised status of a widget.
+ * @param w : Window on which the widget is located
+ * @param widget_index : index of this widget in the window
+ * @param hidden_stat : status to use ie: lowered = true, raised = false
+ */
+static inline void SetWindowWidgetLoweredState(Window *w, byte widget_index, bool lowered_stat)
+{
+ assert(widget_index < w->widget_count);
+ SB(w->widget[widget_index].display_flags, WIDG_LOWERED, 1, !!lowered_stat);
+}
+
+/**
+ * Invert the lowered/raised status of a widget.
+ * @param w : Window on which the widget is located
+ * @param widget_index : index of this widget in the window
+ */
+static inline void ToggleWidgetLoweredState(Window *w, byte widget_index)
+{
+ assert(widget_index < w->widget_count);
+ TOGGLEBIT(w->widget[widget_index].display_flags, WIDG_LOWERED);
+}
+
+/**
+ * Marks a widget as lowered.
+ * @param w : Window on which the widget is located
+ * @param widget_index : index of this widget in the window
+ */
+static inline void LowerWindowWidget(Window *w, byte widget_index)
+{
+ SetWindowWidgetLoweredState(w, widget_index, true);
+}
+
+/**
+ * Marks a widget as raised.
+ * @param w : Window on which the widget is located
+ * @param widget_index : index of this widget in the window
+ */
+static inline void RaiseWindowWidget(Window *w, byte widget_index)
+{
+ SetWindowWidgetLoweredState(w, widget_index, false);
+}
+
+/**
+ * Gets the lowered state of a widget.
+ * @param w : Window on which the widget is located
+ * @param widget_index : index of this widget in the window
+ * @return status of the widget ie: lowered = true, raised= false
+ */
+static inline bool IsWindowWidgetLowered(const Window *w, byte widget_index)
+{
+ assert(widget_index < w->widget_count);
+ return HASBIT(w->widget[widget_index].display_flags, WIDG_LOWERED);
+}
+
+void InitWindowSystem(void);
+void UnInitWindowSystem(void);
+void ResetWindowSystem(void);
+int GetMenuItemIndex(const Window *w, int x, int y);
+void InputLoop(void);
+void HandleKeypress(uint32 key);
+void HandleMouseEvents(void);
+void UpdateWindows(void);
+void InvalidateWidget(const Window *w, byte widget_index);
+void InvalidateThisWindowData(Window *w);
+void InvalidateWindowData(WindowClass cls, WindowNumber number);
+void RaiseWindowButtons(Window *w);
+void RelocateAllWindows(int neww, int newh);
+int PositionMainToolbar(Window *w);
+void CDECL SetWindowWidgetsDisabledState(Window *w, bool disab_stat, int widgets, ...);
+void CDECL SetWindowWidgetsHiddenState(Window *w, bool hidden_stat, int widgets, ...);
+void CDECL SetWindowWidgetsLoweredState(Window *w, bool lowered_stat, int widgets, ...);
+
+/* misc_gui.c*/
+void GuiShowTooltipsWithArgs(StringID str, uint paramcount, const uint params[]);
+static inline void GuiShowTooltips(StringID str)
+{
+ GuiShowTooltipsWithArgs(str, 0, NULL);
+}
+
+/* widget.c */
+int GetWidgetFromPos(const Window *w, int x, int y);
+void DrawWindowWidgets(const Window *w);
+void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int button, uint32 disabled_mask, uint32 hidden_mask);
+
+void HandleButtonClick(Window *w, byte widget);
+
+Window *GetCallbackWnd(void);
+void DeleteNonVitalWindows(void);
+void DeleteAllNonVitalWindows(void);
+void HideVitalWindows(void);
+void ShowVitalWindows(void);
+Window **FindWindowZPosition(const Window *w);
+
+/* window.c */
+extern Window *_z_windows[];
+extern Window **_last_z_window;
+#define FOR_ALL_WINDOWS(wz) for (wz = _z_windows; wz != _last_z_window; wz++)
+
+VARDEF Point _cursorpos_drag_start;
+
+VARDEF bool _left_button_down;
+VARDEF bool _left_button_clicked;
+
+VARDEF bool _right_button_down;
+VARDEF bool _right_button_clicked;
+
+VARDEF int _scrollbar_start_pos;
+VARDEF int _scrollbar_size;
+VARDEF byte _scroller_click_timeout;
+
+VARDEF bool _scrolling_scrollbar;
+VARDEF bool _scrolling_viewport;
+VARDEF bool _popup_menu_active;
+
+VARDEF byte _special_mouse_mode;
+enum SpecialMouseMode {
+ WSM_NONE = 0,
+ WSM_DRAGDROP = 1,
+ WSM_SIZING = 2,
+ WSM_PRESIZE = 3,
+};
+
+void ScrollbarClickHandler(Window *w, const Widget *wi, int x, int y);
+
+#endif /* WINDOW_H */
diff --git a/src/yapf/array.hpp b/src/yapf/array.hpp
new file mode 100644
index 000000000..e8eff1c8c
--- /dev/null
+++ b/src/yapf/array.hpp
@@ -0,0 +1,71 @@
+/* $Id$ */
+
+#ifndef ARRAY_HPP
+#define ARRAY_HPP
+
+#include "fixedsizearray.hpp"
+
+/** Flexible array with size limit. Implemented as fixed size
+ * array of fixed size arrays */
+template <class Titem_, int Tblock_size_ = 1024, int Tnum_blocks_ = Tblock_size_>
+class CArrayT {
+public:
+ typedef Titem_ Titem; ///< Titem is now visible from outside
+ typedef CFixedSizeArrayT<Titem_, Tblock_size_> CSubArray; ///< inner array
+ typedef CFixedSizeArrayT<CSubArray, Tnum_blocks_> CSuperArray; ///< outer array
+
+protected:
+ CSuperArray m_a; ///< array of arrays of items
+
+public:
+ static const int Tblock_size = Tblock_size_; ///< block size is now visible from outside
+ static const int Tnum_blocks = Tnum_blocks_; ///< number of blocks is now visible from outside
+ static const int Tcapacity = Tblock_size * Tnum_blocks; ///< total max number of items
+
+ /** implicit constructor */
+ FORCEINLINE CArrayT() { }
+ /** Clear (destroy) all items */
+ FORCEINLINE void Clear() {m_a.Clear();}
+ /** Return actual number of items */
+ FORCEINLINE int Size() const
+ {
+ int super_size = m_a.Size();
+ if (super_size == 0) return 0;
+ int sub_size = m_a[super_size - 1].Size();
+ return (super_size - 1) * Tblock_size + sub_size;
+ }
+ /** return true if array is empty */
+ FORCEINLINE bool IsEmpty() { return m_a.IsEmpty(); }
+ /** return true if array is full */
+ FORCEINLINE bool IsFull() { return m_a.IsFull() && m_a[Tnum_blocks - 1].IsFull(); }
+ /** return first sub-array with free space for new item */
+ FORCEINLINE CSubArray& FirstFreeSubArray()
+ {
+ int super_size = m_a.Size();
+ if (super_size > 0) {
+ CSubArray& sa = m_a[super_size - 1];
+ if (!sa.IsFull()) return sa;
+ }
+ return m_a.Add();
+ }
+ /** allocate but not construct new item */
+ FORCEINLINE Titem_& AddNC() { return FirstFreeSubArray().AddNC(); }
+ /** allocate and construct new item */
+ FORCEINLINE Titem_& Add() { return FirstFreeSubArray().Add(); }
+ /** indexed access (non-const) */
+ FORCEINLINE Titem& operator [] (int idx)
+ {
+ CSubArray& sa = m_a[idx / Tblock_size];
+ Titem& item = sa [idx % Tblock_size];
+ return item;
+ }
+ /** indexed access (const) */
+ FORCEINLINE const Titem& operator [] (int idx) const
+ {
+ CSubArray& sa = m_a[idx / Tblock_size];
+ Titem& item = sa [idx % Tblock_size];
+ return item;
+ }
+};
+
+#endif /* ARRAY_HPP */
diff --git a/src/yapf/autocopyptr.hpp b/src/yapf/autocopyptr.hpp
new file mode 100644
index 000000000..fb6bfa028
--- /dev/null
+++ b/src/yapf/autocopyptr.hpp
@@ -0,0 +1,83 @@
+/* $Id$ */
+
+#ifndef AUTOCOPYPTR_HPP
+#define AUTOCOPYPTR_HPP
+
+#if 0 // reenable when needed
+/** CAutoCopyPtrT - kind of CoW (Copy on Write) pointer.
+ * It is non-invasive smart pointer (reference counter is held outside
+ * of Tdata).
+ * When copied, its new copy shares the same underlaying structure Tdata.
+ * When dereferenced, its behavior depends on 2 factors:
+ * - whether the data is shared (used by more than one pointer)
+ * - type of access (read/write)
+ * When shared pointer is dereferenced for write, new clone of Tdata
+ * is made first.
+ * Can't be used for polymorphic data types (interfaces).
+ */
+template <class Tdata_>
+class CAutoCopyPtrT {
+protected:
+ typedef Tdata_ Tdata;
+
+ struct CItem {
+ int m_ref_cnt; ///< reference counter
+ Tdata m_data; ///< custom data itself
+
+ FORCEINLINE CItem() : m_ref_cnt(1) {};
+ FORCEINLINE CItem(const Tdata& data) : m_ref_cnt(1), m_data(data) {};
+ FORCEINLINE CItem(const CItem& src) : m_ref_cnt(1), m_data(src.m_data) {};
+ };
+
+ mutable CItem* m_pI; ///< points to the ref-counted data
+
+public:
+ FORCEINLINE CAutoCopyPtrT() : m_pI(NULL) {};
+ FORCEINLINE CAutoCopyPtrT(const Tdata& data) : m_pI(new CItem(data)) {};
+ FORCEINLINE CAutoCopyPtrT(const CAutoCopyPtrT& src) : m_pI(src.m_pI) {if (m_pI != NULL) m_pI->m_ref_cnt++;}
+ FORCEINLINE ~CAutoCopyPtrT() {if (m_pI == NULL || (--m_pI->m_ref_cnt) > 0) return; delete m_pI; m_pI = NULL;}
+
+ /** data accessor (read only) */
+ FORCEINLINE const Tdata& GetDataRO() const {if (m_pI == NULL) m_pI = new CItem(); return m_pI->m_data;}
+ /** data accessor (read / write) */
+ FORCEINLINE Tdata& GetDataRW() {CloneIfShared(); if (m_pI == NULL) m_pI = new CItem(); return m_pI->m_data;}
+
+ /** clone data if it is shared */
+ FORCEINLINE void CloneIfShared()
+ {
+ if (m_pI != NULL && m_pI->m_ref_cnt > 1) {
+ // we share data item with somebody, clone it to become an exclusive owner
+ CItem* pNewI = new CItem(*m_pI);
+ m_pI->m_ref_cnt--;
+ m_pI = pNewI;
+ }
+ }
+
+ /** assign pointer from the other one (maintaining ref counts) */
+ FORCEINLINE void Assign(const CAutoCopyPtrT& src)
+ {
+ if (m_pI == src.m_pI) return;
+ if (m_pI != NULL && (--m_pI->m_ref_cnt) <= 0) delete m_pI;
+ m_pI = src.m_pI;
+ if (m_pI != NULL) m_pI->m_ref_cnt++;
+ }
+
+ /** dereference operator (read only) */
+ FORCEINLINE const Tdata* operator -> () const {return &GetDataRO();}
+ /** dereference operator (read / write) */
+ FORCEINLINE Tdata* operator -> () {return &GetDataRW();}
+
+ /** assignment operator */
+ FORCEINLINE CAutoCopyPtrT& operator = (const CAutoCopyPtrT& src) {Assign(src); return *this;}
+
+ /** forwarding 'lower then' operator to the underlaying items */
+ FORCEINLINE bool operator < (const CAutoCopyPtrT& other) const
+ {
+ assert(m_pI != NULL);
+ assert(other.m_pI != NULL);
+ return (m_pI->m_data) < (other.m_pI->m_data);
+ }
+};
+
+#endif /* 0 */
+#endif /* AUTOCOPYPTR_HPP */
diff --git a/src/yapf/binaryheap.hpp b/src/yapf/binaryheap.hpp
new file mode 100644
index 000000000..7b72a25af
--- /dev/null
+++ b/src/yapf/binaryheap.hpp
@@ -0,0 +1,225 @@
+/* $Id$ */
+
+#ifndef BINARYHEAP_HPP
+#define BINARYHEAP_HPP
+
+//void* operator new (size_t size, void* p) {return p;}
+#if defined(_MSC_VER) && (_MSC_VER >= 1400)
+//void operator delete (void* p, void* p2) {}
+#endif
+
+
+/**
+ * Binary Heap as C++ template.
+ *
+ * For information about Binary Heap algotithm,
+ * see: http://www.policyalmanac.org/games/binaryHeaps.htm
+ *
+ * Implementation specific notes:
+ *
+ * 1) It allocates space for item pointers (array). Items are allocated elsewhere.
+ *
+ * 2) ItemPtr [0] is never used. Total array size is max_items + 1, because we
+ * use indices 1..max_items instead of zero based C indexing.
+ *
+ * 3) Item of the binary heap should support these public members:
+ * - 'lower-then' operator '<' - used for comparing items before moving
+ *
+ */
+
+template <class Titem_>
+class CBinaryHeapT {
+public:
+ typedef Titem_ *ItemPtr;
+private:
+ int m_size; ///< Number of items in the heap
+ int m_max_size; ///< Maximum number of items the heap can hold
+ ItemPtr* m_items; ///< The heap item pointers
+
+public:
+ explicit CBinaryHeapT(int max_items = 102400)
+ : m_size(0)
+ , m_max_size(max_items)
+ {
+ m_items = new ItemPtr[max_items + 1];
+ }
+
+ ~CBinaryHeapT()
+ {
+ Clear();
+ delete [] m_items;
+ m_items = NULL;
+ }
+
+public:
+ /** Return the number of items stored in the priority queue.
+ * @return number of items in the queue */
+ FORCEINLINE int Size() const {return m_size;};
+
+ /** Test if the priority queue is empty.
+ * @return true if empty */
+ FORCEINLINE bool IsEmpty() const {return (m_size == 0);};
+
+ /** Test if the priority queue is full.
+ * @return true if full. */
+ FORCEINLINE bool IsFull() const {return (m_size >= m_max_size);};
+
+ /** Find the smallest item in the priority queue.
+ * Return the smallest item, or throw assert if empty. */
+ FORCEINLINE Titem_& GetHead() {assert(!IsEmpty()); return *m_items[1];}
+
+ /** Insert new item into the priority queue, maintaining heap order.
+ * @return false if the queue is full. */
+ bool Push(Titem_& new_item);
+
+ /** Remove and return the smallest item from the priority queue. */
+ FORCEINLINE Titem_& PopHead() {Titem_& ret = GetHead(); RemoveHead(); return ret;};
+
+ /** Remove the smallest item from the priority queue. */
+ void RemoveHead();
+
+ /** Remove item specified by index */
+ void RemoveByIdx(int idx);
+
+ /** return index of the item that matches (using &item1 == &item2) the given item. */
+ int FindLinear(const Titem_& item) const;
+
+ /** Make the priority queue empty.
+ * All remaining items will remain untouched. */
+ void Clear() {m_size = 0;};
+
+ /** verifies the heap consistency (added during first YAPF debug phase) */
+ void CheckConsistency();
+};
+
+
+template <class Titem_>
+FORCEINLINE bool CBinaryHeapT<Titem_>::Push(Titem_& new_item)
+{
+ if (IsFull()) return false;
+
+ // make place for new item
+ int gap = ++m_size;
+ // Heapify up
+ for (int parent = gap / 2; (parent > 0) && (new_item < *m_items[parent]); gap = parent, parent /= 2)
+ m_items[gap] = m_items[parent];
+ m_items[gap] = &new_item;
+ CheckConsistency();
+ return true;
+}
+
+template <class Titem_>
+FORCEINLINE void CBinaryHeapT<Titem_>::RemoveHead()
+{
+ assert(!IsEmpty());
+
+ // at index 1 we have a gap now
+ int gap = 1;
+
+ // Heapify down:
+ // last item becomes a candidate for the head. Call it new_item.
+ Titem_& new_item = *m_items[m_size--];
+
+ // now we must maintain relation between parent and its children:
+ // parent <= any child
+ // from head down to the tail
+ int child = 2; // first child is at [parent * 2]
+
+ // while children are valid
+ while (child <= m_size) {
+ // choose the smaller child
+ if (child < m_size && *m_items[child + 1] < *m_items[child])
+ child++;
+ // is it smaller than our parent?
+ if (!(*m_items[child] < new_item)) {
+ // the smaller child is still bigger or same as parent => we are done
+ break;
+ }
+ // if smaller child is smaller than parent, it will become new parent
+ m_items[gap] = m_items[child];
+ gap = child;
+ // where do we have our new children?
+ child = gap * 2;
+ }
+ // move last item to the proper place
+ if (m_size > 0) m_items[gap] = &new_item;
+ CheckConsistency();
+}
+
+template <class Titem_>
+inline void CBinaryHeapT<Titem_>::RemoveByIdx(int idx)
+{
+ // at position idx we have a gap now
+ int gap = idx;
+ Titem_& last = *m_items[m_size];
+ if (idx < m_size) {
+ assert(idx >= 1);
+ m_size--;
+ // and the candidate item for fixing this gap is our last item 'last'
+ // Move gap / last item up:
+ while (gap > 1)
+ {
+ // compare [gap] with its parent
+ int parent = gap / 2;
+ if (last < *m_items[parent]) {
+ m_items[gap] = m_items[parent];
+ gap = parent;
+ } else {
+ // we don't need to continue upstairs
+ break;
+ }
+ }
+
+ // Heapify (move gap) down:
+ while (true) {
+ // where we do have our children?
+ int child = gap * 2; // first child is at [parent * 2]
+ if (child > m_size) break;
+ // choose the smaller child
+ if (child < m_size && *m_items[child + 1] < *m_items[child])
+ child++;
+ // is it smaller than our parent?
+ if (!(*m_items[child] < last)) {
+ // the smaller child is still bigger or same as parent => we are done
+ break;
+ }
+ // if smaller child is smaller than parent, it will become new parent
+ m_items[gap] = m_items[child];
+ gap = child;
+ }
+ // move parent to the proper place
+ if (m_size > 0) m_items[gap] = &last;
+ }
+ else {
+ assert(idx == m_size);
+ m_size--;
+ }
+ CheckConsistency();
+}
+
+template <class Titem_>
+inline int CBinaryHeapT<Titem_>::FindLinear(const Titem_& item) const
+{
+ if (IsEmpty()) return 0;
+ for (ItemPtr *ppI = m_items + 1, *ppLast = ppI + m_size; ppI <= ppLast; ppI++) {
+ if (*ppI == &item) {
+ return ppI - m_items;
+ }
+ }
+ return 0;
+}
+
+template <class Titem_>
+FORCEINLINE void CBinaryHeapT<Titem_>::CheckConsistency()
+{
+ // enable it if you suspect binary heap doesn't work well
+#if 0
+ for (int child = 2; child <= m_size; child++) {
+ int parent = child / 2;
+ assert(!(m_items[child] < m_items[parent]));
+ }
+#endif
+}
+
+
+#endif /* BINARYHEAP_HPP */
diff --git a/src/yapf/blob.hpp b/src/yapf/blob.hpp
new file mode 100644
index 000000000..1a20f3ac2
--- /dev/null
+++ b/src/yapf/blob.hpp
@@ -0,0 +1,342 @@
+/* $Id$ */
+
+#ifndef BLOB_HPP
+#define BLOB_HPP
+
+/** Type-safe version of memcpy().
+ * @param d destination buffer
+ * @param s source buffer
+ * @param num_items number of items to be copied (!not number of bytes!) */
+template <class Titem_>
+FORCEINLINE void MemCpyT(Titem_* d, const Titem_* s, int num_items = 1)
+{
+ memcpy(d, s, num_items * sizeof(Titem_));
+}
+
+
+/** Base class for simple binary blobs.
+ * Item is byte.
+ * The word 'simple' means:
+ * - no configurable allocator type (always made from heap)
+ * - no smart deallocation - deallocation must be called from the same
+ * module (DLL) where the blob was allocated
+ * - no configurable allocation policy (how big blocks should be allocated)
+ * - no extra ownership policy (i.e. 'copy on write') when blob is copied
+ * - no thread synchronization at all
+ *
+ * Internal member layout:
+ * 1. The only class member is pointer to the first item (see union ptr_u).
+ * 2. Allocated block contains the blob header (see CHdr) followed by the raw byte data.
+ * Always, when it allocates memory the allocated size is:
+ * sizeof(CHdr) + <data capacity>
+ * 3. Two 'virtual' members (m_size and m_max_size) are stored in the CHdr at beginning
+ * of the alloated block.
+ * 4. The pointer (in ptr_u) points behind the header (to the first data byte).
+ * When memory block is allocated, the sizeof(CHdr) it added to it.
+ * 5. Benefits of this layout:
+ * - items are accessed in the simplest possible way - just dereferencing the pointer,
+ * which is good for performance (assuming that data are accessed most often).
+ * - sizeof(blob) is the same as the size of any other pointer
+ * 6. Drawbacks of this layout:
+ * - the fact, that pointer to the alocated block is adjusted by sizeof(CHdr) before
+ * it is stored can lead to several confusions:
+ * - it is not common pattern so the implementation code is bit harder to read
+ * - valgrind can generate warning that allocated block is lost (not accessible)
+ * */
+class CBlobBaseSimple {
+protected:
+ /** header of the allocated memory block */
+ struct CHdr {
+ int m_size; ///< actual blob size in bytes
+ int m_max_size; ///< maximum (allocated) size in bytes
+ };
+
+ /** type used as class member */
+ union {
+ int8 *m_pData; ///< pointer to the first byte of data
+ CHdr *m_pHdr_1; ///< pointer just after the CHdr holding m_size and m_max_size
+ } ptr_u;
+
+public:
+ static const int Ttail_reserve = 4; ///< four extra bytes will be always allocated and zeroed at the end
+
+ /** default constructor - initializes empty blob */
+ FORCEINLINE CBlobBaseSimple() { InitEmpty(); }
+ /** copy constructor */
+ FORCEINLINE CBlobBaseSimple(const CBlobBaseSimple& src)
+ {
+ InitEmpty();
+ AppendRaw(src);
+ }
+ /** destructor */
+ FORCEINLINE ~CBlobBaseSimple() { Free(); }
+protected:
+ /** initialize the empty blob by setting the ptr_u.m_pHdr_1 pointer to the static CHdr with
+ * both m_size and m_max_size containing zero */
+ FORCEINLINE void InitEmpty() { static CHdr hdrEmpty[] = {{0, 0}, {0, 0}}; ptr_u.m_pHdr_1 = &hdrEmpty[1]; }
+ /** initialize blob by attaching it to the given header followed by data */
+ FORCEINLINE void Init(CHdr* hdr) { ptr_u.m_pHdr_1 = &hdr[1]; }
+ /** blob header accessor - use it rather than using the pointer arithmetics directly - non-const version */
+ FORCEINLINE CHdr& Hdr() { return ptr_u.m_pHdr_1[-1]; }
+ /** blob header accessor - use it rather than using the pointer arithmetics directly - const version */
+ FORCEINLINE const CHdr& Hdr() const { return ptr_u.m_pHdr_1[-1]; }
+ /** return reference to the actual blob size - used when the size needs to be modified */
+ FORCEINLINE int& RawSizeRef() { return Hdr().m_size; };
+
+public:
+ /** return true if blob doesn't contain valid data */
+ FORCEINLINE bool IsEmpty() const { return RawSize() == 0; }
+ /** return the number of valid data bytes in the blob */
+ FORCEINLINE int RawSize() const { return Hdr().m_size; };
+ /** return the current blob capacity in bytes */
+ FORCEINLINE int MaxRawSize() const { return Hdr().m_max_size; };
+ /** return pointer to the first byte of data - non-const version */
+ FORCEINLINE int8* RawData() { return ptr_u.m_pData; }
+ /** return pointer to the first byte of data - const version */
+ FORCEINLINE const int8* RawData() const { return ptr_u.m_pData; }
+#if 0 // reenable when needed
+ /** return the 32 bit CRC of valid data in the blob */
+ FORCEINLINE uint32 Crc32() const {return CCrc32::Calc(RawData(), RawSize());}
+#endif //0
+ /** invalidate blob's data - doesn't free buffer */
+ FORCEINLINE void Clear() { RawSizeRef() = 0; }
+ /** free the blob's memory */
+ FORCEINLINE void Free() { if (MaxRawSize() > 0) {RawFree(&Hdr()); InitEmpty();} }
+ /** copy data from another blob - replaces any existing blob's data */
+ FORCEINLINE void CopyFrom(const CBlobBaseSimple& src) { Clear(); AppendRaw(src); }
+ /** overtake ownership of data buffer from the source blob - source blob will become empty */
+ FORCEINLINE void MoveFrom(CBlobBaseSimple& src) { Free(); ptr_u.m_pData = src.ptr_u.m_pData; src.InitEmpty(); }
+ /** swap buffers (with data) between two blobs (this and source blob) */
+ FORCEINLINE void Swap(CBlobBaseSimple& src) { int8 *tmp = ptr_u.m_pData; ptr_u.m_pData = src.ptr_u.m_pData; src.ptr_u.m_pData = tmp; }
+
+ /** append new bytes at the end of existing data bytes - reallocates if necessary */
+ FORCEINLINE void AppendRaw(int8 *p, int num_bytes)
+ {
+ assert(p != NULL);
+ if (num_bytes > 0) {
+ memcpy(GrowRawSize(num_bytes), p, num_bytes);
+ } else {
+ assert(num_bytes >= 0);
+ }
+ }
+
+ /** append bytes from given source blob to the end of existing data bytes - reallocates if necessary */
+ FORCEINLINE void AppendRaw(const CBlobBaseSimple& src)
+ {
+ if (!src.IsEmpty())
+ memcpy(GrowRawSize(src.RawSize()), src.RawData(), src.RawSize());
+ }
+
+ /** Reallocate if there is no free space for num_bytes bytes.
+ * @return pointer to the new data to be added */
+ FORCEINLINE int8* MakeRawFreeSpace(int num_bytes)
+ {
+ assert(num_bytes >= 0);
+ int new_size = RawSize() + num_bytes;
+ if (new_size > MaxRawSize()) SmartAlloc(new_size);
+ FixTail();
+ return ptr_u.m_pData + RawSize();
+ }
+
+ /** Increase RawSize() by num_bytes.
+ * @return pointer to the new data added */
+ FORCEINLINE int8* GrowRawSize(int num_bytes)
+ {
+ int8* pNewData = MakeRawFreeSpace(num_bytes);
+ RawSizeRef() += num_bytes;
+ return pNewData;
+ }
+
+ /** Decrease RawSize() by num_bytes. */
+ FORCEINLINE void ReduceRawSize(int num_bytes)
+ {
+ if (MaxRawSize() > 0 && num_bytes > 0) {
+ assert(num_bytes <= RawSize());
+ if (num_bytes < RawSize()) RawSizeRef() -= num_bytes;
+ else RawSizeRef() = 0;
+ }
+ }
+ /** reallocate blob data if needed */
+ void SmartAlloc(int new_size)
+ {
+ int old_max_size = MaxRawSize();
+ if (old_max_size >= new_size) return;
+ // calculate minimum block size we need to allocate
+ int min_alloc_size = sizeof(CHdr) + new_size + Ttail_reserve;
+ // ask allocation policy for some reasonable block size
+ int alloc_size = AllocPolicy(min_alloc_size);
+ // allocate new block
+ CHdr* pNewHdr = RawAlloc(alloc_size);
+ // setup header
+ pNewHdr->m_size = RawSize();
+ pNewHdr->m_max_size = alloc_size - (sizeof(CHdr) + Ttail_reserve);
+ // copy existing data
+ if (RawSize() > 0)
+ memcpy(pNewHdr + 1, ptr_u.m_pData, pNewHdr->m_size);
+ // replace our block with new one
+ CHdr* pOldHdr = &Hdr();
+ Init(pNewHdr);
+ if (old_max_size > 0)
+ RawFree(pOldHdr);
+ }
+ /** simple allocation policy - can be optimized later */
+ FORCEINLINE static int AllocPolicy(int min_alloc)
+ {
+ if (min_alloc < (1 << 9)) {
+ if (min_alloc < (1 << 5)) return (1 << 5);
+ return (min_alloc < (1 << 7)) ? (1 << 7) : (1 << 9);
+ }
+ if (min_alloc < (1 << 15)) {
+ if (min_alloc < (1 << 11)) return (1 << 11);
+ return (min_alloc < (1 << 13)) ? (1 << 13) : (1 << 15);
+ }
+ if (min_alloc < (1 << 20)) {
+ if (min_alloc < (1 << 17)) return (1 << 17);
+ return (min_alloc < (1 << 19)) ? (1 << 19) : (1 << 20);
+ }
+ min_alloc = (min_alloc | ((1 << 20) - 1)) + 1;
+ return min_alloc;
+ }
+
+ /** all allocation should happen here */
+ static FORCEINLINE CHdr* RawAlloc(int num_bytes) { return (CHdr*)malloc(num_bytes); }
+ /** all deallocations should happen here */
+ static FORCEINLINE void RawFree(CHdr* p) { free(p); }
+ /** fixing the four bytes at the end of blob data - useful when blob is used to hold string */
+ FORCEINLINE void FixTail()
+ {
+ if (MaxRawSize() > 0) {
+ int8 *p = &ptr_u.m_pData[RawSize()];
+ for (int i = 0; i < Ttail_reserve; i++) p[i] = 0;
+ }
+ }
+};
+
+/** Blob - simple dynamic Titem_ array. Titem_ (template argument) is a placeholder for any type.
+ * Titem_ can be any integral type, pointer, or structure. Using Blob instead of just plain C array
+ * simplifies the resource management in several ways:
+ * 1. When adding new item(s) it automatically grows capacity if needed.
+ * 2. When variable of type Blob comes out of scope it automatically frees the data buffer.
+ * 3. Takes care about the actual data size (number of used items).
+ * 4. Dynamically constructs only used items (as opposite of static array which constructs all items) */
+template <class Titem_, class Tbase_ = CBlobBaseSimple>
+class CBlobT : public CBlobBaseSimple {
+ // make template arguments public:
+public:
+ typedef Titem_ Titem;
+ typedef Tbase_ Tbase;
+
+ static const int Titem_size = sizeof(Titem);
+
+ /** Default constructor - makes new Blob ready to accept any data */
+ FORCEINLINE CBlobT() : Tbase() {}
+ /** Copy constructor - make new blob to become copy of the original (source) blob */
+ FORCEINLINE CBlobT(const Tbase& src) : Tbase(src) {assert((RawSize() % Titem_size) == 0);}
+ /** Destructor - ensures that allocated memory (if any) is freed */
+ FORCEINLINE ~CBlobT() { Free(); }
+ /** Check the validity of item index (only in debug mode) */
+ FORCEINLINE void CheckIdx(int idx) { assert(idx >= 0); assert(idx < Size()); }
+ /** Return pointer to the first data item - non-const version */
+ FORCEINLINE Titem* Data() { return (Titem*)RawData(); }
+ /** Return pointer to the first data item - const version */
+ FORCEINLINE const Titem* Data() const { return (const Titem*)RawData(); }
+ /** Return pointer to the idx-th data item - non-const version */
+ FORCEINLINE Titem* Data(int idx) { CheckIdx(idx); return (Data() + idx); }
+ /** Return pointer to the idx-th data item - const version */
+ FORCEINLINE const Titem* Data(int idx) const { CheckIdx(idx); return (Data() + idx); }
+ /** Return number of items in the Blob */
+ FORCEINLINE int Size() const { return (RawSize() / Titem_size); }
+ /** Free the memory occupied by Blob destroying all items */
+ FORCEINLINE void Free()
+ {
+ assert((RawSize() % Titem_size) == 0);
+ int old_size = Size();
+ if (old_size > 0) {
+ // destroy removed items;
+ Titem* pI_last_to_destroy = Data(0);
+ for (Titem* pI = Data(old_size - 1); pI >= pI_last_to_destroy; pI--) pI->~Titem_();
+ }
+ Tbase::Free();
+ }
+ /** Grow number of data items in Blob by given number - doesn't construct items */
+ FORCEINLINE Titem* GrowSizeNC(int num_items) { return (Titem*)GrowRawSize(num_items * Titem_size); }
+ /** Grow number of data items in Blob by given number - constructs new items (using Titem_'s default constructor) */
+ FORCEINLINE Titem* GrowSizeC(int num_items)
+ {
+ Titem* pI = GrowSizeNC(num_items);
+ for (int i = num_items; i > 0; i--, pI++) new (pI) Titem();
+ }
+ /** Destroy given number of items and reduce the Blob's data size */
+ FORCEINLINE void ReduceSize(int num_items)
+ {
+ assert((RawSize() % Titem_size) == 0);
+ int old_size = Size();
+ assert(num_items <= old_size);
+ int new_size = (num_items <= old_size) ? (old_size - num_items) : 0;
+ // destroy removed items;
+ Titem* pI_last_to_destroy = Data(new_size);
+ for (Titem* pI = Data(old_size - 1); pI >= pI_last_to_destroy; pI--) pI->~Titem();
+ // remove them
+ ReduceRawSize(num_items * Titem_size);
+ }
+ /** Append one data item at the end (calls Titem_'s default constructor) */
+ FORCEINLINE Titem* AppendNew()
+ {
+ Titem& dst = *GrowSizeNC(1); // Grow size by one item
+ Titem* pNewItem = new (&dst) Titem(); // construct the new item by calling in-place new operator
+ return pNewItem;
+ }
+ /** Append the copy of given item at the end of Blob (using copy constructor) */
+ FORCEINLINE Titem* Append(const Titem& src)
+ {
+ Titem& dst = *GrowSizeNC(1); // Grow size by one item
+ Titem* pNewItem = new (&dst) Titem(src); // construct the new item by calling in-place new operator with copy ctor()
+ return pNewItem;
+ }
+ /** Add given items (ptr + number of items) at the end of blob */
+ FORCEINLINE Titem* Append(const Titem* pSrc, int num_items)
+ {
+ Titem* pDst = GrowSizeNC(num_items);
+ Titem* pDstOrg = pDst;
+ Titem* pDstEnd = pDst + num_items;
+ while (pDst < pDstEnd) new (pDst++) Titem(*(pSrc++));
+ return pDstOrg;
+ }
+ /** Remove item with the given index by replacing it by the last item and reducing the size by one */
+ FORCEINLINE void RemoveBySwap(int idx)
+ {
+ CheckIdx(idx);
+ // destroy removed item
+ Titem* pRemoved = Data(idx);
+ RemoveBySwap(pRemoved);
+ }
+ /** Remove item given by pointer replacing it by the last item and reducing the size by one */
+ FORCEINLINE void RemoveBySwap(Titem* pItem)
+ {
+ Titem* pLast = Data(Size() - 1);
+ assert(pItem >= Data() && pItem <= pLast);
+ // move last item to its new place
+ if (pItem != pLast) {
+ pItem->~Titem_();
+ new (pItem) Titem_(*pLast);
+ }
+ // destroy the last item
+ pLast->~Titem_();
+ // and reduce the raw blob size
+ ReduceRawSize(Titem_size);
+ }
+ /** Ensures that given number of items can be added to the end of Blob. Returns pointer to the
+ * first free (unused) item */
+ FORCEINLINE Titem* MakeFreeSpace(int num_items) { return (Titem*)MakeRawFreeSpace(num_items * Titem_size); }
+};
+
+// simple string implementation
+struct CStrA : public CBlobT<char>
+{
+ typedef CBlobT<char> base;
+ CStrA(const char* str = NULL) {Append(str);}
+ FORCEINLINE CStrA(const CBlobBaseSimple& src) : base(src) {}
+ void Append(const char* str) {if (str != NULL && str[0] != '\0') base::Append(str, (int)strlen(str));}
+};
+
+#endif /* BLOB_HPP */
diff --git a/src/yapf/countedptr.hpp b/src/yapf/countedptr.hpp
new file mode 100644
index 000000000..e63e47fb5
--- /dev/null
+++ b/src/yapf/countedptr.hpp
@@ -0,0 +1,100 @@
+/* $Id$ */
+
+#ifndef COUNTEDPTR_HPP
+#define COUNTEDPTR_HPP
+
+#if 0 // reenable when needed
+/** @file CCountedPtr - smart pointer implementation */
+
+/** CCountedPtr - simple reference counting smart pointer.
+ *
+ * One of the standard ways how to maintain object's lifetime.
+ *
+ * See http://ootips.org/yonat/4dev/smart-pointers.html for more
+ * general info about smart pointers.
+ *
+ * This class implements ref-counted pointer for objects/interfaces that
+ * support AddRef() and Release() methods.
+ */
+template <class Tcls_>
+class CCountedPtr {
+ /** redefine the template argument to make it visible for derived classes */
+public:
+ typedef Tcls_ Tcls;
+
+protected:
+ /** here we hold our pointer to the target */
+ Tcls* m_pT;
+
+public:
+ /** default (NULL) construct or construct from a raw pointer */
+ FORCEINLINE CCountedPtr(Tcls* pObj = NULL) : m_pT(pObj) {AddRef();};
+
+ /** copy constructor (invoked also when initializing from another smart ptr) */
+ FORCEINLINE CCountedPtr(const CCountedPtr& src) : m_pT(src.m_pT) {AddRef();};
+
+ /** destructor releasing the reference */
+ FORCEINLINE ~CCountedPtr() {Release();};
+
+protected:
+ /** add one ref to the underlaying object */
+ FORCEINLINE void AddRef() {if (m_pT != NULL) m_pT->AddRef();}
+
+public:
+ /** release smart pointer (and decrement ref count) if not null */
+ FORCEINLINE void Release() {if (m_pT != NULL) {m_pT->Release(); m_pT = NULL;}}
+
+ /** dereference of smart pointer - const way */
+ FORCEINLINE const Tcls* operator -> () const {assert(m_pT != NULL); return m_pT;};
+
+ /** dereference of smart pointer - non const way */
+ FORCEINLINE Tcls* operator -> () {assert(m_pT != NULL); return m_pT;};
+
+ /** raw pointer casting operator - const way */
+ FORCEINLINE operator const Tcls*() const {assert(m_pT == NULL); return m_pT;}
+
+ /** raw pointer casting operator - non-const way */
+ FORCEINLINE operator Tcls*() {assert(m_pT == NULL); return m_pT;}
+
+ /** operator & to support output arguments */
+ FORCEINLINE Tcls** operator &() {assert(m_pT == NULL); return &m_pT;}
+
+ /** assignment operator from raw ptr */
+ FORCEINLINE CCountedPtr& operator = (Tcls* pT) {Assign(pT); return *this;}
+
+ /** assignment operator from another smart ptr */
+ FORCEINLINE CCountedPtr& operator = (CCountedPtr& src) {Assign(src.m_pT); return *this;}
+
+ /** assignment operator helper */
+ FORCEINLINE void Assign(Tcls* pT);
+
+ /** one way how to test for NULL value */
+ FORCEINLINE bool IsNull() const {return m_pT == NULL;}
+
+ /** another way how to test for NULL value */
+ FORCEINLINE bool operator == (const CCountedPtr& sp) const {return m_pT == sp.m_pT;}
+
+ /** yet another way how to test for NULL value */
+ FORCEINLINE bool operator != (const CCountedPtr& sp) const {return m_pT != sp.m_pT;}
+
+ /** assign pointer w/o incrementing ref count */
+ FORCEINLINE void Attach(Tcls* pT) {Release(); m_pT = pT;}
+
+ /** detach pointer w/o decrementing ref count */
+ FORCEINLINE Tcls* Detach() {Tcls* pT = m_pT; m_pT = NULL; return pT;}
+};
+
+template <class Tcls_>
+FORCEINLINE void CCountedPtr<Tcls_>::Assign(Tcls* pT)
+{
+ // if they are the same, we do nothing
+ if (pT != m_pT) {
+ if (pT) pT->AddRef(); // AddRef new pointer if any
+ Tcls* pTold = m_pT; // save original ptr
+ m_pT = pT; // update m_pT to new value
+ if (pTold) pTold->Release(); // release old ptr if any
+ }
+}
+
+#endif /* 0 */
+#endif /* COUNTEDPTR_HPP */
diff --git a/src/yapf/crc32.hpp b/src/yapf/crc32.hpp
new file mode 100644
index 000000000..10e9a7ac4
--- /dev/null
+++ b/src/yapf/crc32.hpp
@@ -0,0 +1,65 @@
+/* $Id$ */
+
+#ifndef CRC32_HPP
+#define CRC32_HPP
+
+#if 0 // reenable when needed
+struct CCrc32
+{
+ static uint32 Calc(const void *pBuffer, int nCount)
+ {
+ uint32 crc = 0xffffffff;
+ const uint32* pTable = CrcTable();
+
+ uint8* begin = (uint8*)pBuffer;
+ uint8* end = begin + nCount;
+ for(uint8* cur = begin; cur < end; cur++)
+ crc = (crc >> 8) ^ pTable[cur[0] ^ (uint8)(crc & 0xff)];
+ crc ^= 0xffffffff;
+
+ return crc;
+ }
+
+ static const uint32* CrcTable()
+ {
+ static const uint32 Table[256] =
+ {
+ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
+ 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
+ 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
+ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
+ 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
+ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
+ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
+ 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
+ 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
+ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
+ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
+ 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
+ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
+ 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
+ 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
+ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
+ 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
+ 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
+ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
+ 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
+ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
+ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
+ 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
+ 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
+ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
+ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
+ 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
+ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
+ 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
+ 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
+ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
+ 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
+ };
+ return Table;
+ }
+};
+#endif // 0
+
+#endif /* CRC32_HPP */
diff --git a/src/yapf/fixedsizearray.hpp b/src/yapf/fixedsizearray.hpp
new file mode 100644
index 000000000..48b177f3c
--- /dev/null
+++ b/src/yapf/fixedsizearray.hpp
@@ -0,0 +1,99 @@
+/* $Id$ */
+
+#ifndef FIXEDSIZEARRAY_HPP
+#define FIXEDSIZEARRAY_HPP
+
+
+/** fixed size array
+ * Upon construction it preallocates fixed size block of memory
+ * for all items, but doesn't construct them. Item's construction
+ * is delayed. */
+template <class Titem_, int Tcapacity_>
+struct CFixedSizeArrayT {
+ /** the only member of fixed size array is pointer to the block
+ * of C array of items. Header can be found on the offset -sizeof(CHdr). */
+ Titem_ *m_items;
+
+ /** header for fixed size array */
+ struct CHdr
+ {
+ int m_num_items; ///< number of items in the array
+ int m_ref_cnt; ///< block reference counter (used by copy constructor and by destructor)
+ };
+
+ // make types and constants visible from outside
+ typedef Titem_ Titem; // type of array item
+
+ static const int Tcapacity = Tcapacity_; // the array capacity (maximum size)
+ static const int TitemSize = sizeof(Titem_); // size of item
+ static const int ThdrSize = sizeof(CHdr); // size of header
+
+ /** Default constructor. Preallocate space for items and header, then initialize header. */
+ CFixedSizeArrayT()
+ {
+ // allocate block for header + items (don't construct items)
+ m_items = (Titem*)(((int8*)malloc(ThdrSize + Tcapacity * sizeof(Titem))) + ThdrSize);
+ SizeRef() = 0; // initial number of items
+ RefCnt() = 1; // initial reference counter
+ }
+
+ /** Copy constructor. Preallocate space for items and header, then initialize header. */
+ CFixedSizeArrayT(const CFixedSizeArrayT<Titem_, Tcapacity_>& src)
+ {
+ // share block (header + items) with the source array
+ m_items = src.m_items;
+ RefCnt()++; // now we share block with the source
+ }
+
+ /** destroy remaining items and free the memory block */
+ ~CFixedSizeArrayT()
+ {
+ // release one reference to the shared block
+ if ((--RefCnt()) > 0) return; // and return if there is still some owner
+
+ Clear();
+ // free the memory block occupied by items
+ free(((int8*)m_items) - ThdrSize);
+ m_items = NULL;
+ }
+
+ /** Clear (destroy) all items */
+ FORCEINLINE void Clear()
+ {
+ // walk through all allocated items backward and destroy them
+ for (Titem* pItem = &m_items[Size() - 1]; pItem >= m_items; pItem--) {
+ pItem->~Titem_();
+ }
+ // number of items become zero
+ SizeRef() = 0;
+ }
+
+protected:
+ /** return reference to the array header (non-const) */
+ FORCEINLINE CHdr& Hdr() { return *(CHdr*)(((int8*)m_items) - ThdrSize); }
+ /** return reference to the array header (const) */
+ FORCEINLINE const CHdr& Hdr() const { return *(CHdr*)(((int8*)m_items) - ThdrSize); }
+ /** return reference to the block reference counter */
+ FORCEINLINE int& RefCnt() { return Hdr().m_ref_cnt; }
+ /** return reference to number of used items */
+ FORCEINLINE int& SizeRef() { return Hdr().m_num_items; }
+public:
+ /** return number of used items */
+ FORCEINLINE int Size() const { return Hdr().m_num_items; }
+ /** return true if array is full */
+ FORCEINLINE bool IsFull() const { return Size() >= Tcapacity; };
+ /** return true if array is empty */
+ FORCEINLINE bool IsEmpty() const { return Size() <= 0; };
+ /** index validation */
+ FORCEINLINE void CheckIdx(int idx) const { assert(idx >= 0); assert(idx < Size()); }
+ /** add (allocate), but don't construct item */
+ FORCEINLINE Titem& AddNC() { assert(!IsFull()); return m_items[SizeRef()++]; }
+ /** add and construct item using default constructor */
+ FORCEINLINE Titem& Add() { Titem& item = AddNC(); new(&item)Titem; return item; }
+ /** return item by index (non-const version) */
+ FORCEINLINE Titem& operator [] (int idx) { CheckIdx(idx); return m_items[idx]; }
+ /** return item by index (const version) */
+ FORCEINLINE const Titem& operator [] (int idx) const { CheckIdx(idx); return m_items[idx]; }
+};
+
+#endif /* FIXEDSIZEARRAY_HPP */
diff --git a/src/yapf/follow_track.cpp b/src/yapf/follow_track.cpp
new file mode 100644
index 000000000..ad2f0b724
--- /dev/null
+++ b/src/yapf/follow_track.cpp
@@ -0,0 +1,47 @@
+/* $Id$ */
+
+#include "../stdafx.h"
+#include "yapf.hpp"
+#include "follow_track.hpp"
+
+void FollowTrackInit(FollowTrack_t *This, const Vehicle* v)
+{
+ CFollowTrackWater& F = *(CFollowTrackWater*) This;
+ F.Init(v, NULL);
+}
+
+bool FollowTrackWater(FollowTrack_t *This, TileIndex old_tile, Trackdir old_td)
+{
+ CFollowTrackWater& F = *(CFollowTrackWater*) This;
+ return F.Follow(old_tile, old_td);
+}
+
+bool FollowTrackRoad(FollowTrack_t *This, TileIndex old_tile, Trackdir old_td)
+{
+ CFollowTrackRoad& F = *(CFollowTrackRoad*) This;
+ return F.Follow(old_tile, old_td);
+}
+
+bool FollowTrackRail(FollowTrack_t *This, TileIndex old_tile, Trackdir old_td)
+{
+ CFollowTrackRail& F = *(CFollowTrackRail*) This;
+ return F.Follow(old_tile, old_td);
+}
+
+bool FollowTrackWaterNo90(FollowTrack_t *This, TileIndex old_tile, Trackdir old_td)
+{
+ CFollowTrackWaterNo90& F = *(CFollowTrackWaterNo90*) This;
+ return F.Follow(old_tile, old_td);
+}
+
+bool FollowTrackRoadNo90(FollowTrack_t *This, TileIndex old_tile, Trackdir old_td)
+{
+ CFollowTrackRoadNo90& F = *(CFollowTrackRoadNo90*) This;
+ return F.Follow(old_tile, old_td);
+}
+
+bool FollowTrackRailNo90(FollowTrack_t *This, TileIndex old_tile, Trackdir old_td)
+{
+ CFollowTrackRailNo90& F = *(CFollowTrackRailNo90*) This;
+ return F.Follow(old_tile, old_td);
+}
diff --git a/src/yapf/follow_track.hpp b/src/yapf/follow_track.hpp
new file mode 100644
index 000000000..7864dc5e5
--- /dev/null
+++ b/src/yapf/follow_track.hpp
@@ -0,0 +1,279 @@
+/* $Id$ */
+
+#ifndef FOLLOW_TRACK_HPP
+#define FOLLOW_TRACK_HPP
+
+#include "yapf.hpp"
+
+/** Track follower helper template class (can serve pathfinders and vehicle
+ * controllers). See 6 different typedefs below for 3 different transport
+ * types w/ of w/o 90-deg turns allowed */
+template <TransportType Ttr_type_, bool T90deg_turns_allowed_ = true>
+struct CFollowTrackT : public FollowTrack_t
+{
+ CPerformanceTimer* m_pPerf;
+
+ FORCEINLINE CFollowTrackT(const Vehicle* v = NULL, CPerformanceTimer* pPerf = NULL)
+ {
+ Init(v, pPerf);
+ }
+
+ FORCEINLINE void Init(const Vehicle* v, CPerformanceTimer* pPerf)
+ {
+ assert(!IsRailTT() || (v != NULL && v->type == VEH_Train));
+ m_veh = v;
+ m_pPerf = pPerf;
+ // don't worry, all is inlined so compiler should remove unnecessary initializations
+ m_new_tile = INVALID_TILE;
+ m_new_td_bits = TRACKDIR_BIT_NONE;
+ m_exitdir = INVALID_DIAGDIR;
+ m_is_station = m_is_bridge = m_is_tunnel = false;
+ m_tiles_skipped = 0;
+ }
+
+ FORCEINLINE static TransportType TT() {return Ttr_type_;}
+ FORCEINLINE static bool IsWaterTT() {return TT() == TRANSPORT_WATER;}
+ FORCEINLINE static bool IsRailTT() {return TT() == TRANSPORT_RAIL;}
+ FORCEINLINE static bool IsRoadTT() {return TT() == TRANSPORT_ROAD;}
+ FORCEINLINE static bool Allow90degTurns() {return T90deg_turns_allowed_;}
+
+ /** main follower routine. Fills all members and return true on success.
+ * Otherwise returns false if track can't be followed. */
+ FORCEINLINE bool Follow(TileIndex old_tile, Trackdir old_td)
+ {
+ m_old_tile = old_tile;
+ m_old_td = old_td;
+ assert((GetTileTrackStatus(m_old_tile, TT()) & TrackdirToTrackdirBits(m_old_td)) != 0);
+ m_exitdir = TrackdirToExitdir(m_old_td);
+ if (EnteredDepot()) return true;
+ if (!CanExitOldTile()) return false;
+ FollowTileExit();
+ if (!QueryNewTileTrackStatus()) return TryReverse();
+ if (!CanEnterNewTile()) return false;
+ m_new_td_bits &= DiagdirReachesTrackdirs(m_exitdir);
+ if (!Allow90degTurns())
+ m_new_td_bits &= (TrackdirBits)~(int)TrackdirCrossesTrackdirs(m_old_td);
+ return (m_new_td_bits != TRACKDIR_BIT_NONE);
+ }
+
+protected:
+ /** Follow the m_exitdir from m_old_tile and fill m_new_tile and m_tiles_skipped */
+ FORCEINLINE void FollowTileExit()
+ {
+ m_is_station = m_is_bridge = m_is_tunnel = false;
+ m_tiles_skipped = 0;
+
+ // extra handling for tunnels in our direction
+ if (IsTunnelTile(m_old_tile)) {
+ DiagDirection tunnel_enterdir = GetTunnelDirection(m_old_tile);
+ if (tunnel_enterdir == m_exitdir) {
+ // we are entering the tunnel
+ FindLengthOfTunnelResult flotr = FindLengthOfTunnel(m_old_tile, m_exitdir);
+ m_new_tile = flotr.tile;
+ m_is_tunnel = true;
+ m_tiles_skipped = flotr.length - 1;
+ return;
+ }
+ assert(ReverseDiagDir(tunnel_enterdir) == m_exitdir);
+ }
+
+ // extra handling for bridge ramp in our direction
+ if (IsBridgeTile(m_old_tile)) {
+ DiagDirection bridge_enterdir = GetBridgeRampDirection(m_old_tile);
+ if (bridge_enterdir == m_exitdir) {
+ // we are entering the bridge ramp
+ m_new_tile = GetOtherBridgeEnd(m_old_tile);
+ uint32 bridge_length = GetBridgeLength(m_old_tile, m_new_tile);
+ m_tiles_skipped = bridge_length;
+ m_is_bridge = true;
+ return;
+ }
+ assert(ReverseDiagDir(bridge_enterdir) == m_exitdir);
+ }
+
+ // normal or station tile, do one step
+ TileIndexDiff diff = TileOffsByDiagDir(m_exitdir);
+ m_new_tile = TILE_ADD(m_old_tile, diff);
+
+ // special handling for stations
+ if (IsRailTT() && IsRailwayStationTile(m_new_tile)) {
+ m_is_station = true;
+ } else if (IsRoadTT() && IsRoadStopTile(m_new_tile)) {
+ m_is_station = true;
+ } else {
+ m_is_station = false;
+ }
+ }
+
+ /** stores track status (available trackdirs) for the new tile into m_new_td_bits */
+ FORCEINLINE bool QueryNewTileTrackStatus()
+ {
+ CPerfStart perf(*m_pPerf);
+ if (IsRailTT() && GetTileType(m_new_tile) == MP_RAILWAY && IsPlainRailTile(m_new_tile)) {
+ m_new_td_bits = (TrackdirBits)(GetTrackBits(m_new_tile) * 0x101);
+ } else {
+ uint32 ts = GetTileTrackStatus(m_new_tile, TT());
+ m_new_td_bits = (TrackdirBits)(ts & TRACKDIR_BIT_MASK);
+ }
+ return (m_new_td_bits != TRACKDIR_BIT_NONE);
+ }
+
+ /** return true if we can leave m_old_tile in m_exitdir */
+ FORCEINLINE bool CanExitOldTile()
+ {
+ // road stop can be left at one direction only
+ if (IsRoadTT() && IsRoadStopTile(m_old_tile)) {
+ DiagDirection exitdir = GetRoadStopDir(m_old_tile);
+ if (exitdir != m_exitdir)
+ return false;
+ }
+
+ // road depots can be also left in one direction only
+ if (IsRoadTT() && IsTileDepotType(m_old_tile, TT())) {
+ DiagDirection exitdir = GetRoadDepotDirection(m_old_tile);
+ if (exitdir != m_exitdir)
+ return false;
+ }
+ return true;
+ }
+
+ /** return true if we can enter m_new_tile from m_exitdir */
+ FORCEINLINE bool CanEnterNewTile()
+ {
+ if (IsRoadTT() && IsRoadStopTile(m_new_tile)) {
+ // road stop can be entered from one direction only
+ DiagDirection exitdir = GetRoadStopDir(m_new_tile);
+ if (ReverseDiagDir(exitdir) != m_exitdir)
+ return false;
+ }
+
+ // road and rail depots can also be entered from one direction only
+ if (IsRoadTT() && IsTileDepotType(m_new_tile, TT())) {
+ DiagDirection exitdir = GetRoadDepotDirection(m_new_tile);
+ if (ReverseDiagDir(exitdir) != m_exitdir)
+ return false;
+ // don't try to enter other player's depots
+ if (GetTileOwner(m_new_tile) != m_veh->owner) {
+ return false;
+ }
+ }
+ if (IsRailTT() && IsTileDepotType(m_new_tile, TT())) {
+ DiagDirection exitdir = GetRailDepotDirection(m_new_tile);
+ if (ReverseDiagDir(exitdir) != m_exitdir)
+ return false;
+ }
+
+ // rail transport is possible only on tiles with the same owner as vehicle
+ if (IsRailTT() && GetTileOwner(m_new_tile) != m_veh->owner) {
+ // different owner
+ return false;
+ }
+
+ // rail transport is possible only on compatible rail types
+ if (IsRailTT()) {
+ RailType rail_type = GetTileRailType(m_new_tile, DiagdirToDiagTrackdir(m_exitdir));
+ if (((1 << rail_type) & m_veh->u.rail.compatible_railtypes) == 0) {
+ // incompatible rail type
+ return false;
+ }
+ }
+
+ // tunnel holes and bridge ramps can be entered only from proper direction
+ if (!IsWaterTT() && IsTileType(m_new_tile, MP_TUNNELBRIDGE)) {
+ if (IsTunnel(m_new_tile)) {
+ if (!m_is_tunnel) {
+ DiagDirection tunnel_enterdir = GetTunnelDirection(m_new_tile);
+ if (tunnel_enterdir != m_exitdir) return false;
+ }
+ } else if (IsBridge(m_new_tile)) {
+ if (!m_is_bridge) {
+ DiagDirection ramp_enderdir = GetBridgeRampDirection(m_new_tile);
+ if (ramp_enderdir != m_exitdir) return false;
+ }
+ }
+ }
+
+ // special handling for rail stations - get to the end of platform
+ if (IsRailTT() && m_is_station) {
+ // entered railway station
+ // get platform length
+ uint length = GetPlatformLength(m_new_tile, TrackdirToExitdir(m_old_td));
+ // how big step we must do to get to the last platform tile;
+ m_tiles_skipped = length - 1;
+ // move to the platform end
+ TileIndexDiff diff = TileOffsByDiagDir(m_exitdir);
+ diff *= m_tiles_skipped;
+ m_new_tile = TILE_ADD(m_new_tile, diff);
+ return true;
+ }
+
+ return true;
+ }
+
+ /** return true if we entered depot and reversed inside */
+ FORCEINLINE bool EnteredDepot()
+ {
+ // rail and road depots cause reversing
+ if (!IsWaterTT() && IsTileDepotType(m_old_tile, TT())) {
+ DiagDirection exitdir = IsRailTT() ? GetRailDepotDirection(m_old_tile) : GetRoadDepotDirection(m_old_tile);
+ if (exitdir != m_exitdir) {
+ // reverse
+ m_new_tile = m_old_tile;
+ m_new_td_bits = TrackdirToTrackdirBits(ReverseTrackdir(m_old_td));
+ m_exitdir = exitdir;
+ m_tiles_skipped = 0;
+ m_is_tunnel = m_is_bridge = m_is_station = false;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /** return true if we successfully reversed at end of road/track */
+ FORCEINLINE bool TryReverse()
+ {
+ if (IsRoadTT()) {
+ // if we reached the end of road, we can reverse the RV and continue moving
+ m_exitdir = ReverseDiagDir(m_exitdir);
+ // new tile will be the same as old one
+ m_new_tile = m_old_tile;
+ // set new trackdir bits to all reachable trackdirs
+ QueryNewTileTrackStatus();
+ m_new_td_bits &= DiagdirReachesTrackdirs(m_exitdir);
+ if (m_new_td_bits != TRACKDIR_BIT_NONE) {
+ // we have some trackdirs reachable after reversal
+ return true;
+ }
+ }
+ return false;
+ }
+
+public:
+ /** Helper for pathfinders - get min/max speed on the m_old_tile/m_old_td */
+ int GetSpeedLimit(int *pmin_speed = NULL)
+ {
+ int min_speed = 0;
+ int max_speed = INT_MAX; // no limit
+
+ // for now we handle only on-bridge speed limit
+ if (!IsWaterTT() && IsBridgeTile(m_old_tile)) {
+ int spd = _bridge[GetBridgeType(m_old_tile)].speed;
+ if (IsRoadTT()) spd *= 2;
+ if (max_speed > spd) max_speed = spd;
+ }
+
+ // if min speed was requested, return it
+ if (pmin_speed) *pmin_speed = min_speed;
+ return max_speed;
+ }
+};
+
+typedef CFollowTrackT<TRANSPORT_WATER, true > CFollowTrackWater;
+typedef CFollowTrackT<TRANSPORT_ROAD , true > CFollowTrackRoad;
+typedef CFollowTrackT<TRANSPORT_RAIL , true > CFollowTrackRail;
+
+typedef CFollowTrackT<TRANSPORT_WATER, false> CFollowTrackWaterNo90;
+typedef CFollowTrackT<TRANSPORT_ROAD , false> CFollowTrackRoadNo90;
+typedef CFollowTrackT<TRANSPORT_RAIL , false> CFollowTrackRailNo90;
+
+#endif /* FOLLOW_TRACK_HPP */
diff --git a/src/yapf/hashtable.hpp b/src/yapf/hashtable.hpp
new file mode 100644
index 000000000..c6b52e50a
--- /dev/null
+++ b/src/yapf/hashtable.hpp
@@ -0,0 +1,240 @@
+/* $Id$ */
+
+#ifndef HASHTABLE_HPP
+#define HASHTABLE_HPP
+
+template <class Titem_>
+struct CHashTableSlotT
+{
+ typedef typename Titem_::Key Key; // make Titem_::Key a property of HashTable
+
+ Titem_* m_pFirst;
+
+ CHashTableSlotT() : m_pFirst(NULL) {}
+
+ /** hash table slot helper - clears the slot by simple forgetting its items */
+ FORCEINLINE void Clear() {m_pFirst = NULL;}
+
+ /** hash table slot helper - linear search for item with given key through the given blob - const version */
+ FORCEINLINE const Titem_* Find(const Key& key) const
+ {
+ for (const Titem_* pItem = m_pFirst; pItem != NULL; pItem = pItem->GetHashNext()) {
+ if (pItem->GetKey() == key) {
+ // we have found the item, return it
+ return pItem;
+ }
+ }
+ return NULL;
+ }
+
+ /** hash table slot helper - linear search for item with given key through the given blob - non-const version */
+ FORCEINLINE Titem_* Find(const Key& key)
+ {
+ for (Titem_* pItem = m_pFirst; pItem != NULL; pItem = pItem->GetHashNext()) {
+ if (pItem->GetKey() == key) {
+ // we have found the item, return it
+ return pItem;
+ }
+ }
+ return NULL;
+ }
+
+ /** hash table slot helper - add new item to the slot */
+ FORCEINLINE void Attach(Titem_& new_item)
+ {
+ assert(new_item.GetHashNext() == NULL);
+ new_item.SetHashNext(m_pFirst);
+ m_pFirst = &new_item;
+ }
+
+ /** hash table slot helper - remove item from a slot */
+ FORCEINLINE bool Detach(Titem_& item_to_remove)
+ {
+ if (m_pFirst == &item_to_remove) {
+ m_pFirst = item_to_remove.GetHashNext();
+ item_to_remove.SetHashNext(NULL);
+ return true;
+ }
+ Titem_* pItem = m_pFirst;
+ while (true) {
+ if (pItem == NULL) {
+ return false;
+ }
+ Titem_* pNextItem = pItem->GetHashNext();
+ if (pNextItem == &item_to_remove) break;
+ pItem = pNextItem;
+ }
+ pItem->SetHashNext(item_to_remove.GetHashNext());
+ item_to_remove.SetHashNext(NULL);
+ return true;
+ }
+
+ /** hash table slot helper - remove and return item from a slot */
+ FORCEINLINE Titem_* Detach(const Key& key)
+ {
+ // do we have any items?
+ if (m_pFirst == NULL) {
+ return NULL;
+ }
+ // is it our first item?
+ if (m_pFirst->GetKey() == key) {
+ Titem_& ret_item = *m_pFirst;
+ m_pFirst = m_pFirst->GetHashNext();
+ ret_item.SetHashNext(NULL);
+ return &ret_item;
+ }
+ // find it in the following items
+ Titem_* pPrev = m_pFirst;
+ for (Titem_* pItem = m_pFirst->GetHashNext(); pItem != NULL; pPrev = pItem, pItem = pItem->GetHashNext()) {
+ if (pItem->GetKey() == key) {
+ // we have found the item, unlink and return it
+ pPrev->SetHashNext(pItem->GetHashNext());
+ pItem->SetHashNext(NULL);
+ return pItem;
+ }
+ }
+ return NULL;
+ }
+};
+
+/** @class CHashTableT<Titem, Thash_bits> - simple hash table
+ * of pointers allocated elsewhere.
+ *
+ * Supports: Add/Find/Remove of Titems.
+ *
+ * Your Titem must meet some extra requirements to be CHashTableT
+ * compliant:
+ * - its constructor/destructor (if any) must be public
+ * - if the copying of item requires an extra resource management,
+ * you must define also copy constructor
+ * - must support nested type (struct, class or typedef) Titem::Key
+ * that defines the type of key class for that item
+ * - must support public method:
+ * const Key& GetKey() const; // return the item's key object
+ *
+ * In addition, the Titem::Key class must support:
+ * - public method that calculates key's hash:
+ * int CalcHash() const;
+ * - public 'equality' operator to compare the key with another one
+ * bool operator == (const Key& other) const;
+ */
+template <class Titem_, int Thash_bits_>
+class CHashTableT {
+public:
+ typedef Titem_ Titem; // make Titem_ visible from outside of class
+ typedef typename Titem_::Key Tkey; // make Titem_::Key a property of HashTable
+ static const int Thash_bits = Thash_bits_; // publish num of hash bits
+ static const int Tcapacity = 1 << Thash_bits; // and num of slots 2^bits
+
+protected:
+ /** each slot contains pointer to the first item in the list,
+ * Titem contains pointer to the next item - GetHashNext(), SetHashNext() */
+ typedef CHashTableSlotT<Titem_> Slot;
+
+ Slot* m_slots; // here we store our data (array of blobs)
+ int m_num_items; // item counter
+
+public:
+ // default constructor
+ FORCEINLINE CHashTableT()
+ {
+ // construct all slots
+ m_slots = new Slot[Tcapacity];
+ m_num_items = 0;
+ }
+
+ ~CHashTableT() {delete [] m_slots; m_num_items = 0; m_slots = NULL;}
+
+protected:
+ /** static helper - return hash for the given key modulo number of slots */
+ FORCEINLINE static int CalcHash(const Tkey& key)
+ {
+ int32 hash = key.CalcHash();
+ if ((8 * Thash_bits) < 32) hash ^= hash >> (min(8 * Thash_bits, 31));
+ if ((4 * Thash_bits) < 32) hash ^= hash >> (min(4 * Thash_bits, 31));
+ if ((2 * Thash_bits) < 32) hash ^= hash >> (min(2 * Thash_bits, 31));
+ if ((1 * Thash_bits) < 32) hash ^= hash >> (min(1 * Thash_bits, 31));
+ hash &= (1 << Thash_bits) - 1;
+ return hash;
+ }
+
+ /** static helper - return hash for the given item modulo number of slots */
+ FORCEINLINE static int CalcHash(const Titem_& item) {return CalcHash(item.GetKey());}
+
+public:
+ /** item count */
+ FORCEINLINE int Count() const {return m_num_items;}
+
+ /** simple clear - forget all items - used by CSegmentCostCacheT.Flush() */
+ FORCEINLINE void Clear() const {for (int i = 0; i < Tcapacity; i++) m_slots[i].Clear();}
+
+ /** const item search */
+ const Titem_* Find(const Tkey& key) const
+ {
+ int hash = CalcHash(key);
+ const Slot& slot = m_slots[hash];
+ const Titem_* item = slot.Find(key);
+ return item;
+ }
+
+ /** non-const item search */
+ Titem_* Find(const Tkey& key)
+ {
+ int hash = CalcHash(key);
+ Slot& slot = m_slots[hash];
+ Titem_* item = slot.Find(key);
+ return item;
+ }
+
+ /** non-const item search & optional removal (if found) */
+ Titem_* TryPop(const Tkey& key)
+ {
+ int hash = CalcHash(key);
+ Slot& slot = m_slots[hash];
+ Titem_* item = slot.Detach(key);
+ if (item != NULL) {
+ m_num_items--;
+ }
+ return item;
+ }
+
+ /** non-const item search & removal */
+ Titem_& Pop(const Tkey& key)
+ {
+ Titem_* item = TryPop(key);
+ assert(item != NULL);
+ return *item;
+ }
+
+ /** non-const item search & optional removal (if found) */
+ bool TryPop(Titem_& item)
+ {
+ const Tkey& key = item.GetKey();
+ int hash = CalcHash(key);
+ Slot& slot = m_slots[hash];
+ bool ret = slot.Detach(item);
+ if (ret) {
+ m_num_items--;
+ }
+ return ret;
+ }
+
+ /** non-const item search & removal */
+ void Pop(Titem_& item)
+ {
+ bool ret = TryPop(item);
+ assert(ret);
+ }
+
+ /** add one item - copy it from the given item */
+ void Push(Titem_& new_item)
+ {
+ int hash = CalcHash(new_item);
+ Slot& slot = m_slots[hash];
+ assert(slot.Find(new_item.GetKey()) == NULL);
+ slot.Attach(new_item);
+ m_num_items++;
+ }
+};
+
+#endif /* HASHTABLE_HPP */
diff --git a/src/yapf/nodelist.hpp b/src/yapf/nodelist.hpp
new file mode 100644
index 000000000..f51afbfd4
--- /dev/null
+++ b/src/yapf/nodelist.hpp
@@ -0,0 +1,130 @@
+/* $Id$ */
+
+#ifndef NODELIST_HPP
+#define NODELIST_HPP
+
+#include "array.hpp"
+#include "hashtable.hpp"
+#include "binaryheap.hpp"
+
+/** Hash table based node list multi-container class.
+ * Implements open list, closed list and priority queue for A-star
+ * path finder. */
+template <class Titem_, int Thash_bits_open_, int Thash_bits_closed_>
+class CNodeList_HashTableT {
+public:
+ /** make Titem_ visible from outside of class */
+ typedef Titem_ Titem;
+ /** make Titem_::Key a property of HashTable */
+ typedef typename Titem_::Key Key;
+ /** type that we will use as item container */
+ typedef CArrayT<Titem_, 65536, 256> CItemArray;
+ /** how pointers to open nodes will be stored */
+ typedef CHashTableT<Titem_, Thash_bits_open_ > COpenList;
+ /** how pointers to closed nodes will be stored */
+ typedef CHashTableT<Titem_, Thash_bits_closed_> CClosedList;
+ /** how the priority queue will be managed */
+ typedef CBinaryHeapT<Titem_> CPriorityQueue;
+
+protected:
+ /** here we store full item data (Titem_) */
+ CItemArray m_arr;
+ /** hash table of pointers to open item data */
+ COpenList m_open;
+ /** hash table of pointers to closed item data */
+ CClosedList m_closed;
+ /** priority queue of pointers to open item data */
+ CPriorityQueue m_open_queue;
+ /** new open node under construction */
+ Titem *m_new_node;
+public:
+ /** default constructor */
+ CNodeList_HashTableT()
+ : m_open_queue(204800)
+ {
+ m_new_node = NULL;
+ }
+ /** destructor */
+ ~CNodeList_HashTableT()
+ {
+ }
+ /** return number of open nodes */
+ FORCEINLINE int OpenCount() {return m_open.Count();}
+ /** return number of closed nodes */
+ FORCEINLINE int ClosedCount() {return m_closed.Count();}
+ /** allocate new data item from m_arr */
+ FORCEINLINE Titem_* CreateNewNode()
+ {
+ if (m_new_node == NULL) m_new_node = &m_arr.Add();
+ return m_new_node;
+ }
+ /** notify the nodelist, that we don't want to discard the given node */
+ FORCEINLINE void FoundBestNode(Titem_& item)
+ {
+ // for now it is enough to invalidate m_new_node if it is our given node
+ if (&item == m_new_node)
+ m_new_node = NULL;
+ // TODO: do we need to store best nodes found in some extra list/array? Probably not now.
+ }
+ /** insert given item as open node (into m_open and m_open_queue) */
+ FORCEINLINE void InsertOpenNode(Titem_& item)
+ {
+ assert(m_closed.Find(item.GetKey()) == NULL);
+ m_open.Push(item);
+ // TODO: check if m_open_queue is not full
+ assert(!m_open_queue.IsFull());
+ m_open_queue.Push(item);
+ if (&item == m_new_node)
+ m_new_node = NULL;
+ }
+ /** return the best open node */
+ FORCEINLINE Titem_* GetBestOpenNode()
+ {
+ if (!m_open_queue.IsEmpty()) {
+ Titem_& item = m_open_queue.GetHead();
+ return &item;
+ }
+ return NULL;
+ }
+ /** remove and return the best open node */
+ FORCEINLINE Titem_* PopBestOpenNode()
+ {
+ if (!m_open_queue.IsEmpty()) {
+ Titem_& item = m_open_queue.PopHead();
+ m_open.Pop(item);
+ return &item;
+ }
+ return NULL;
+ }
+ /** return the open node specified by a key or NULL if not found */
+ FORCEINLINE Titem_* FindOpenNode(const Key& key)
+ {
+ Titem_* item = m_open.Find(key);
+ return item;
+ }
+ /** remove and return the open node specified by a key */
+ FORCEINLINE Titem_& PopOpenNode(const Key& key)
+ {
+ Titem_& item = m_open.Pop(key);
+ int idxPop = m_open_queue.FindLinear(item);
+ m_open_queue.RemoveByIdx(idxPop);
+ return item;
+ }
+ /** close node */
+ FORCEINLINE void InsertClosedNode(Titem_& item)
+ {
+ assert(m_open.Find(item.GetKey()) == NULL);
+ m_closed.Push(item);
+ }
+ /** return the closed node specified by a key or NULL if not found */
+ FORCEINLINE Titem_* FindClosedNode(const Key& key)
+ {
+ Titem_* item = m_closed.Find(key);
+ return item;
+ }
+
+ FORCEINLINE int TotalCount() {return m_arr.Size();}
+ FORCEINLINE Titem_& ItemAt(int idx) {return m_arr[idx];}
+};
+
+#endif /* NODELIST_HPP */
diff --git a/src/yapf/track_dir.hpp b/src/yapf/track_dir.hpp
new file mode 100644
index 000000000..0239f853e
--- /dev/null
+++ b/src/yapf/track_dir.hpp
@@ -0,0 +1,35 @@
+/* $Id$ */
+
+#ifndef TRACK_DIR_HPP
+#define TRACK_DIR_HPP
+
+EXTERN_C_BEGIN
+#include "../tile.h"
+#include "../openttd.h"
+#include "../map.h"
+#include "../rail.h"
+EXTERN_C_END
+
+/** Helpers to allow to work with enum as with type safe bit set in C++ */
+#define DECLARE_ENUM_AS_BIT_MASK(mask_t) \
+ FORCEINLINE mask_t operator | (mask_t m1, mask_t m2) {return (mask_t)((int)m1 | m2);} \
+ FORCEINLINE mask_t operator & (mask_t m1, mask_t m2) {return (mask_t)((int)m1 & m2);} \
+ FORCEINLINE mask_t operator ^ (mask_t m1, mask_t m2) {return (mask_t)((int)m1 ^ m2);} \
+ FORCEINLINE mask_t& operator |= (mask_t& m1, mask_t m2) {m1 = m1 | m2; return m1;} \
+ FORCEINLINE mask_t& operator &= (mask_t& m1, mask_t m2) {m1 = m1 & m2; return m1;} \
+ FORCEINLINE mask_t& operator ^= (mask_t& m1, mask_t m2) {m1 = m1 ^ m2; return m1;} \
+ FORCEINLINE mask_t operator ~(mask_t m) {return (mask_t)(~(int)m);}
+
+/** probably redundant enum combining operators (as we have conversion functions) */
+#define DECLARE_ENUM_AS_BIT_INDEX(idx_t, mask_t) \
+ FORCEINLINE mask_t operator << (int m, idx_t i) {return (mask_t)(m << (int)i);} \
+ FORCEINLINE mask_t operator << (mask_t m, int i) {return (mask_t)(((int)m) << i);} \
+ FORCEINLINE mask_t operator >> (mask_t m, int i) {return (mask_t)(((int)m) >> i);}
+
+DECLARE_ENUM_AS_BIT_MASK(TrackBits)
+DECLARE_ENUM_AS_BIT_INDEX(Track, TrackBits)
+
+DECLARE_ENUM_AS_BIT_MASK(TrackdirBits)
+DECLARE_ENUM_AS_BIT_INDEX(Trackdir, TrackdirBits)
+
+#endif /* TRACK_DIR_HPP */
diff --git a/src/yapf/yapf.h b/src/yapf/yapf.h
new file mode 100644
index 000000000..6b58b4e08
--- /dev/null
+++ b/src/yapf/yapf.h
@@ -0,0 +1,120 @@
+/* $Id$ */
+
+#ifndef YAPF_H
+#define YAPF_H
+
+#include "../debug.h"
+
+/** Finds the best path for given ship.
+ * @param v the ship that needs to find a path
+ * @param tile the tile to find the path from (should be next tile the ship is about to enter)
+ * @param enterdir diagonal direction which the ship will enter this new tile from
+ * @param tracks available tracks on the new tile (to choose from)
+ * @return the best trackdir for next turn or INVALID_TRACKDIR if the path could not be found
+ */
+Trackdir YapfChooseShipTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks);
+
+/** Finds the best path for given road vehicle.
+ * @param v the RV that needs to find a path
+ * @param tile the tile to find the path from (should be next tile the RV is about to enter)
+ * @param enterdir diagonal direction which the RV will enter this new tile from
+ * @param tracks available tracks on the new tile (to choose from)
+ * @return the best trackdir for next turn or INVALID_TRACKDIR if the path could not be found
+ */
+Trackdir YapfChooseRoadTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir);
+
+/** Finds the best path for given train.
+ * @param v the train that needs to find a path
+ * @param tile the tile to find the path from (should be next tile the train is about to enter)
+ * @param enterdir diagonal direction which the RV will enter this new tile from
+ * @param trackdirs available trackdirs on the new tile (to choose from)
+ * @param no_path_found [out] true is returned if no path can be found (returned Trackdir is only a 'guess')
+ * @return the best trackdir for next turn or INVALID_TRACKDIR if the path could not be found
+ */
+Trackdir YapfChooseRailTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs, bool *path_not_found);
+
+/** Used by RV multistop feature to find the nearest road stop that has a free slot.
+ * @param v RV (its current tile will be the origin)
+ * @param tile destination tile
+ * @return distance from origin tile to the destination (number of road tiles) or UINT_MAX if path not found
+ */
+uint YapfRoadVehDistanceToTile(const Vehicle* v, TileIndex tile);
+
+/** Used when user sends RV to the nearest depot or if RV needs servicing.
+ * Returns the nearest depot (or NULL if depot was not found).
+ */
+Depot* YapfFindNearestRoadDepot(const Vehicle *v);
+
+/** Used when user sends train to the nearest depot or if train needs servicing.
+ * @v train that needs to go to some depot
+ * @max_distance max distance (number of track tiles) from the current train position
+ * (used also as optimization - the pathfinder can stop path finding if max_distance
+ * was reached and no depot was seen)
+ * @reverse_penalty penalty that should be added for the path that requires reversing the train first
+ * @depot_tile receives the depot tile if depot was found
+ * @reversed receives true if train needs to reversed first
+ * @return the true if depot was found.
+ */
+bool YapfFindNearestRailDepotTwoWay(Vehicle *v, int max_distance, int reverse_penalty, TileIndex* depot_tile, bool* reversed);
+
+/** Returns true if it is better to reverse the train before leaving station */
+bool YapfCheckReverseTrain(Vehicle* v);
+
+/** Use this function to notify YAPF that track layout (or signal configuration) has change */
+void YapfNotifyTrackLayoutChange(TileIndex tile, Track track);
+
+/** performance measurement helpers */
+void* NpfBeginInterval(void);
+int NpfEndInterval(void* perf);
+
+
+extern int _aystar_stats_open_size;
+extern int _aystar_stats_closed_size;
+
+
+/** Track followers. They should help whenever any new code will need to walk through
+ * tracks, road or water tiles (pathfinders, signal controllers, vehicle controllers).
+ * It is an attempt to introduce API that should simplify tasks listed above.
+ * If you will need to use it:
+ * 1. allocate/declare FollowTrack_t structure;
+ * 2. call FollowTrackInit() and provide vehicle (if relevant)
+ * 3. call one of 6 FollowTrackXxxx() APIs below
+ * 4. check return value (if true then continue else stop)
+ * 5. look at FollowTrack_t structure for the result
+ * 6. optionally repeat steps 3..5
+ * 7. in case of troubles contact KUDr
+ */
+
+/** Base struct for track followers. */
+typedef struct FollowTrack_t
+{
+ const Vehicle* m_veh; ///< moving vehicle
+ TileIndex m_old_tile; ///< the origin (vehicle moved from) before move
+ Trackdir m_old_td; ///< the trackdir (the vehicle was on) before move
+ TileIndex m_new_tile; ///< the new tile (the vehicle has entered)
+ TrackdirBits m_new_td_bits; ///< the new set of available trackdirs
+ DiagDirection m_exitdir; ///< exit direction (leaving the old tile)
+ bool m_is_tunnel; ///< last turn passed tunnel
+ bool m_is_bridge; ///< last turn passed bridge ramp
+ bool m_is_station; ///< last turn passed station
+ int m_tiles_skipped; ///< number of skipped tunnel or station tiles
+} FollowTrack_t;
+
+/** Initializes FollowTrack_t structure */
+void FollowTrackInit(FollowTrack_t *This, const Vehicle* v);
+
+/** Main track follower routines */
+bool FollowTrackWater (FollowTrack_t *This, TileIndex old_tile, Trackdir old_td);
+bool FollowTrackRoad (FollowTrack_t *This, TileIndex old_tile, Trackdir old_td);
+bool FollowTrackRail (FollowTrack_t *This, TileIndex old_tile, Trackdir old_td);
+bool FollowTrackWaterNo90(FollowTrack_t *This, TileIndex old_tile, Trackdir old_td);
+bool FollowTrackRoadNo90 (FollowTrack_t *This, TileIndex old_tile, Trackdir old_td);
+bool FollowTrackRailNo90 (FollowTrack_t *This, TileIndex old_tile, Trackdir old_td);
+
+/** Base tile length units */
+enum {
+ YAPF_TILE_LENGTH = 100,
+ YAPF_TILE_CORNER_LENGTH = 71
+};
+
+#endif /* YAPF_H */
diff --git a/src/yapf/yapf.hpp b/src/yapf/yapf.hpp
new file mode 100644
index 000000000..208f29c46
--- /dev/null
+++ b/src/yapf/yapf.hpp
@@ -0,0 +1,93 @@
+/* $Id$ */
+
+#ifndef YAPF_HPP
+#define YAPF_HPP
+
+
+
+#include "track_dir.hpp"
+
+EXTERN_C_BEGIN
+#include "../depot.h"
+#include "../road_map.h"
+#include "../tunnel_map.h"
+#include "../bridge_map.h"
+#include "../bridge.h"
+#include "../station.h"
+#include "../station_map.h"
+#include "../vehicle.h"
+#include "../date.h"
+#include "../functions.h"
+#include "yapf.h"
+#include "../pathfind.h"
+#include "../waypoint.h"
+#include "../debug.h"
+EXTERN_C_END
+
+EXTERN_C_BEGIN
+ extern Patches _patches_newgame;
+ extern uint64 _rdtsc(void);
+EXTERN_C_END
+
+#include <limits.h>
+#include <new>
+
+#if defined(_WIN32) || defined(_WIN64)
+# include <windows.h>
+#else
+# include <time.h>
+#endif
+
+struct CPerformanceTimer
+{
+ int64 m_start;
+ int64 m_acc;
+
+ CPerformanceTimer() : m_start(0), m_acc(0) {}
+
+ FORCEINLINE void Start() {m_start = QueryTime();}
+ FORCEINLINE void Stop() {m_acc += QueryTime() - m_start;}
+ FORCEINLINE int Get(int64 coef) {return (int)(m_acc * coef / QueryFrequency());}
+
+ FORCEINLINE int64 QueryTime() {return _rdtsc();}
+ FORCEINLINE int64 QueryFrequency() {return ((int64)2200 * 1000000);}
+};
+
+struct CPerfStartReal
+{
+ CPerformanceTimer* m_pperf;
+
+ FORCEINLINE CPerfStartReal(CPerformanceTimer& perf) : m_pperf(&perf) {if (m_pperf != NULL) m_pperf->Start();}
+ FORCEINLINE ~CPerfStartReal() {Stop();}
+ FORCEINLINE void Stop() {if (m_pperf != NULL) {m_pperf->Stop(); m_pperf = NULL;}}
+};
+
+struct CPerfStartFake
+{
+ FORCEINLINE CPerfStartFake(CPerformanceTimer& perf) {}
+ FORCEINLINE ~CPerfStartFake() {}
+ FORCEINLINE void Stop() {}
+};
+
+typedef CPerfStartFake CPerfStart;
+
+
+//#undef FORCEINLINE
+//#define FORCEINLINE inline
+
+#include "crc32.hpp"
+#include "blob.hpp"
+#include "fixedsizearray.hpp"
+#include "array.hpp"
+#include "hashtable.hpp"
+#include "binaryheap.hpp"
+#include "nodelist.hpp"
+#include "yapf_base.hpp"
+#include "yapf_node.hpp"
+#include "yapf_common.hpp"
+#include "follow_track.hpp"
+#include "yapf_costbase.hpp"
+#include "yapf_costcache.hpp"
+
+
+#endif /* YAPF_HPP */
diff --git a/src/yapf/yapf_base.hpp b/src/yapf/yapf_base.hpp
new file mode 100644
index 000000000..1d0417987
--- /dev/null
+++ b/src/yapf/yapf_base.hpp
@@ -0,0 +1,331 @@
+/* $Id$ */
+
+#ifndef YAPF_BASE_HPP
+#define YAPF_BASE_HPP
+
+EXTERN_C_BEGIN
+#include "../debug.h"
+EXTERN_C_END
+
+#include "fixedsizearray.hpp"
+#include "blob.hpp"
+#include "nodelist.hpp"
+
+extern int _total_pf_time_us;
+
+/** CYapfBaseT - A-star type path finder base class.
+ * Derive your own pathfinder from it. You must provide the following template argument:
+ * Types - used as collection of local types used in pathfinder
+ *
+ * Requirements for the Types struct:
+ * ----------------------------------
+ * The following types must be defined in the 'Types' argument:
+ * - Types::Tpf - your pathfinder derived from CYapfBaseT
+ * - Types::NodeList - open/closed node list (look at CNodeList_HashTableT)
+ * NodeList needs to have defined local type Titem - defines the pathfinder node type.
+ * Node needs to define local type Key - the node key in the collection ()
+ *
+ * For node list you can use template class CNodeList_HashTableT, for which
+ * you need to declare only your node type. Look at test_yapf.h for an example.
+ *
+ *
+ * Requrements to your pathfinder class derived from CYapfBaseT:
+ * -------------------------------------------------------------
+ * Your pathfinder derived class needs to implement following methods:
+ * FORCEINLINE void PfSetStartupNodes()
+ * FORCEINLINE void PfFollowNode(Node& org)
+ * FORCEINLINE bool PfCalcCost(Node& n)
+ * FORCEINLINE bool PfCalcEstimate(Node& n)
+ * FORCEINLINE bool PfDetectDestination(Node& n)
+ *
+ * For more details about those methods, look at the end of CYapfBaseT
+ * declaration. There are some examples. For another example look at
+ * test_yapf.h (part or unittest project).
+ */
+template <class Types>
+class CYapfBaseT {
+public:
+ typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
+ typedef typename Types::NodeList NodeList; ///< our node list
+ typedef typename NodeList::Titem Node; ///< this will be our node type
+ typedef typename Node::Key Key; ///< key to hash tables
+
+
+ NodeList m_nodes; ///< node list multi-container
+protected:
+ Node* m_pBestDestNode; ///< pointer to the destination node found at last round
+ Node* m_pBestIntermediateNode; ///< here should be node closest to the destination if path not found
+ const YapfSettings *m_settings; ///< current settings (_patches.yapf)
+ int m_max_search_nodes; ///< maximum number of nodes we are allowed to visit before we give up
+ const Vehicle* m_veh; ///< vehicle that we are trying to drive
+
+ int m_stats_cost_calcs; ///< stats - how many node's costs were calculated
+ int m_stats_cache_hits; ///< stats - how many node's costs were reused from cache
+
+public:
+ CPerformanceTimer m_perf_cost; ///< stats - total CPU time of this run
+ CPerformanceTimer m_perf_slope_cost; ///< stats - slope calculation CPU time
+ CPerformanceTimer m_perf_ts_cost; ///< stats - GetTrackStatus() CPU time
+ CPerformanceTimer m_perf_other_cost; ///< stats - other CPU time
+
+public:
+ int m_num_steps; ///< this is there for debugging purposes (hope it doesn't hurt)
+
+public:
+ /// default constructor
+ FORCEINLINE CYapfBaseT()
+ : m_pBestDestNode(NULL)
+ , m_pBestIntermediateNode(NULL)
+ , m_settings(&_patches.yapf)
+ , m_max_search_nodes(PfGetSettings().max_search_nodes)
+ , m_veh(NULL)
+ , m_stats_cost_calcs(0)
+ , m_stats_cache_hits(0)
+ , m_num_steps(0)
+ {
+ }
+
+ /// default destructor
+ ~CYapfBaseT() {}
+
+protected:
+ /// to access inherited path finder
+ FORCEINLINE Tpf& Yapf() {return *static_cast<Tpf*>(this);}
+
+public:
+ /// return current settings (can be custom - player based - but later)
+ FORCEINLINE const YapfSettings& PfGetSettings() const
+ {
+ return *m_settings;
+ }
+
+ /** Main pathfinder routine:
+ * - set startup node(s)
+ * - main loop that stops if:
+ * - the destination was found
+ * - or the open list is empty (no route to destination).
+ * - or the maximum amount of loops reached - m_max_search_nodes (default = 10000)
+ * @return true if the path was found */
+ inline bool FindPath(const Vehicle* v)
+ {
+ m_veh = v;
+
+ CPerformanceTimer perf;
+ perf.Start();
+ Yapf().PfSetStartupNodes();
+
+ while (true) {
+ m_num_steps++;
+ Node* n = m_nodes.GetBestOpenNode();
+ if (n == NULL)
+ break;
+
+ // if the best open node was worse than the best path found, we can finish
+ if (m_pBestDestNode != NULL && m_pBestDestNode->GetCost() < n->GetCostEstimate())
+ break;
+
+ Yapf().PfFollowNode(*n);
+ if (m_max_search_nodes == 0 || m_nodes.ClosedCount() < m_max_search_nodes) {
+ m_nodes.PopOpenNode(n->GetKey());
+ m_nodes.InsertClosedNode(*n);
+ } else {
+ m_pBestDestNode = m_pBestIntermediateNode;
+ break;
+ }
+ }
+ bool bDestFound = (m_pBestDestNode != NULL);
+
+ int16 veh_idx = (m_veh != NULL) ? m_veh->unitnumber : 0;
+
+// if (veh_idx != 433) return bDestFound;
+
+ perf.Stop();
+ int t = perf.Get(1000000);
+ _total_pf_time_us += t;
+ char ttc = Yapf().TransportTypeChar();
+ float cache_hit_ratio = (float)m_stats_cache_hits / (float)(m_stats_cache_hits + m_stats_cost_calcs) * 100.0f;
+ int cost = bDestFound ? m_pBestDestNode->m_cost : -1;
+ int dist = bDestFound ? m_pBestDestNode->m_estimate - m_pBestDestNode->m_cost : -1;
+ DEBUG(yapf, 3, "[YAPF%c]%c%4d- %d us - %d rounds - %d open - %d closed - CHR %4.1f%% - c%d(sc%d, ts%d, o%d) -- ", ttc, bDestFound ? '-' : '!', veh_idx, t, m_num_steps, m_nodes.OpenCount(), m_nodes.ClosedCount(), cache_hit_ratio, cost, dist, m_perf_cost.Get(1000000), m_perf_slope_cost.Get(1000000), m_perf_ts_cost.Get(1000000), m_perf_other_cost.Get(1000000));
+ return bDestFound;
+ }
+
+ /** If path was found return the best node that has reached the destination. Otherwise
+ * return the best visited node (which was nearest to the destination).
+ */
+ FORCEINLINE Node& GetBestNode()
+ {
+ return (m_pBestDestNode != NULL) ? *m_pBestDestNode : *m_pBestIntermediateNode;
+ }
+
+ /** Calls NodeList::CreateNewNode() - allocates new node that can be filled and used
+ * as argument for AddStartupNode() or AddNewNode()
+ */
+ FORCEINLINE Node& CreateNewNode()
+ {
+ Node& node = *m_nodes.CreateNewNode();
+ return node;
+ }
+
+ /** Add new node (created by CreateNewNode and filled with data) into open list */
+ FORCEINLINE void AddStartupNode(Node& n)
+ {
+ Yapf().PfNodeCacheFetch(n);
+ // insert the new node only if it is not there
+ if (m_nodes.FindOpenNode(n.m_key) == NULL) {
+ m_nodes.InsertOpenNode(n);
+ } else {
+ // if we are here, it means that node is already there - how it is possible?
+ // probably the train is in the position that both its ends point to the same tile/exit-dir
+ // very unlikely, but it happened
+ }
+ }
+
+ /** add multiple nodes - direct children of the given node */
+ FORCEINLINE void AddMultipleNodes(Node* parent, TileIndex tile, TrackdirBits td_bits)
+ {
+ bool is_choice = (KillFirstBit2x64(td_bits) != 0);
+ for (TrackdirBits rtds = td_bits; rtds != TRACKDIR_BIT_NONE; rtds = (TrackdirBits)KillFirstBit2x64(rtds)) {
+ Trackdir td = (Trackdir)FindFirstBit2x64(rtds);
+ Node& n = Yapf().CreateNewNode();
+ n.Set(parent, tile, td, is_choice);
+ Yapf().AddNewNode(n);
+ }
+ }
+
+ /** AddNewNode() - called by Tderived::PfFollowNode() for each child node.
+ * Nodes are evaluated here and added into open list */
+ void AddNewNode(Node& n)
+ {
+ // evaluate the node
+ bool bCached = Yapf().PfNodeCacheFetch(n);
+ if (!bCached) {
+ m_stats_cost_calcs++;
+ } else {
+ m_stats_cache_hits++;
+ }
+
+ bool bValid = Yapf().PfCalcCost(n);
+
+ if (bCached) {
+ Yapf().PfNodeCacheFlush(n);
+ }
+
+ if (bValid) bValid = Yapf().PfCalcEstimate(n);
+
+ // have the cost or estimate callbacks marked this node as invalid?
+ if (!bValid) return;
+
+ // detect the destination
+ bool bDestination = Yapf().PfDetectDestination(n);
+ if (bDestination) {
+ if (m_pBestDestNode == NULL || n < *m_pBestDestNode) {
+ m_pBestDestNode = &n;
+ }
+ m_nodes.FoundBestNode(n);
+ return;
+ }
+
+ if (m_max_search_nodes > 0 && (m_pBestIntermediateNode == NULL || (m_pBestIntermediateNode->GetCostEstimate() - m_pBestIntermediateNode->GetCost()) > (n.GetCostEstimate() - n.GetCost()))) {
+ m_pBestIntermediateNode = &n;
+ }
+
+ // check new node against open list
+ Node* openNode = m_nodes.FindOpenNode(n.GetKey());
+ if (openNode != NULL) {
+ // another node exists with the same key in the open list
+ // is it better than new one?
+ if (n.GetCostEstimate() < openNode->GetCostEstimate()) {
+ // update the old node by value from new one
+ m_nodes.PopOpenNode(n.GetKey());
+ *openNode = n;
+ // add the updated old node back to open list
+ m_nodes.InsertOpenNode(*openNode);
+ }
+ return;
+ }
+
+ // check new node against closed list
+ Node* closedNode = m_nodes.FindClosedNode(n.GetKey());
+ if (closedNode != NULL) {
+ // another node exists with the same key in the closed list
+ // is it better than new one?
+ int node_est = n.GetCostEstimate();
+ int closed_est = closedNode->GetCostEstimate();
+ if (node_est < closed_est) {
+ // If this assert occurs, you have probably problem in
+ // your Tderived::PfCalcCost() or Tderived::PfCalcEstimate().
+ // The problem could be:
+ // - PfCalcEstimate() gives too large numbers
+ // - PfCalcCost() gives too small numbers
+ // - You have used negative cost penalty in some cases (cost bonus)
+ assert(0);
+
+ return;
+ }
+ return;
+ }
+ // the new node is really new
+ // add it to the open list
+ m_nodes.InsertOpenNode(n);
+ }
+
+ const Vehicle* GetVehicle() const {return m_veh;}
+
+ // methods that should be implemented at derived class Types::Tpf (derived from CYapfBaseT)
+
+#if 0
+ /** Example: PfSetStartupNodes() - set source (origin) nodes */
+ FORCEINLINE void PfSetStartupNodes()
+ {
+ // example:
+ Node& n1 = *base::m_nodes.CreateNewNode();
+ .
+ . // setup node members here
+ .
+ base::m_nodes.InsertOpenNode(n1);
+ }
+
+ /** Example: PfFollowNode() - set following (child) nodes of the given node */
+ FORCEINLINE void PfFollowNode(Node& org)
+ {
+ for (each follower of node org) {
+ Node& n = *base::m_nodes.CreateNewNode();
+ .
+ . // setup node members here
+ .
+ n.m_parent = &org; // set node's parent to allow back tracking
+ AddNewNode(n);
+ }
+ }
+
+ /** Example: PfCalcCost() - set path cost from origin to the given node */
+ FORCEINLINE bool PfCalcCost(Node& n)
+ {
+ // evaluate last step cost
+ int cost = ...;
+ // set the node cost as sum of parent's cost and last step cost
+ n.m_cost = n.m_parent->m_cost + cost;
+ return true; // true if node is valid follower (i.e. no obstacle was found)
+ }
+
+ /** Example: PfCalcEstimate() - set path cost estimate from origin to the target through given node */
+ FORCEINLINE bool PfCalcEstimate(Node& n)
+ {
+ // evaluate the distance to our destination
+ int distance = ...;
+ // set estimate as sum of cost from origin + distance to the target
+ n.m_estimate = n.m_cost + distance;
+ return true; // true if node is valid (i.e. not too far away :)
+ }
+
+ /** Example: PfDetectDestination() - return true if the given node is our destination */
+ FORCEINLINE bool PfDetectDestination(Node& n)
+ {
+ bool bDest = (n.m_key.m_x == m_x2) && (n.m_key.m_y == m_y2);
+ return bDest;
+ }
+#endif
+};
+
+#endif /* YAPF_BASE_HPP */
diff --git a/src/yapf/yapf_common.cpp b/src/yapf/yapf_common.cpp
new file mode 100644
index 000000000..39d119858
--- /dev/null
+++ b/src/yapf/yapf_common.cpp
@@ -0,0 +1,29 @@
+/* $Id$ */
+
+#include "../stdafx.h"
+
+#include "yapf.hpp"
+#include "follow_track.hpp"
+#include "yapf_node_rail.hpp"
+#include "yapf_costbase.hpp"
+#include "yapf_costcache.hpp"
+
+/** translate tileh to the bitset of up-hill trackdirs */
+const TrackdirBits CYapfCostBase::c_upwards_slopes[] = {
+ TRACKDIR_BIT_NONE , // no tileh
+ TRACKDIR_BIT_X_SW | TRACKDIR_BIT_Y_NW, // 1
+ TRACKDIR_BIT_X_SW | TRACKDIR_BIT_Y_SE, // 2
+ TRACKDIR_BIT_X_SW , // 3
+ TRACKDIR_BIT_X_NE | TRACKDIR_BIT_Y_SE, // 4
+ TRACKDIR_BIT_NONE , // 5
+ TRACKDIR_BIT_Y_SE , // 6
+ TRACKDIR_BIT_NONE , // 7
+ TRACKDIR_BIT_X_NE | TRACKDIR_BIT_Y_NW, // 8,
+ TRACKDIR_BIT_Y_NW , // 9
+ TRACKDIR_BIT_NONE , //10
+ TRACKDIR_BIT_NONE , //11,
+ TRACKDIR_BIT_X_NE , //12
+ TRACKDIR_BIT_NONE , //13
+ TRACKDIR_BIT_NONE , //14
+ TRACKDIR_BIT_NONE , //15
+};
diff --git a/src/yapf/yapf_common.hpp b/src/yapf/yapf_common.hpp
new file mode 100644
index 000000000..869bc820c
--- /dev/null
+++ b/src/yapf/yapf_common.hpp
@@ -0,0 +1,163 @@
+/* $Id$ */
+
+#ifndef YAPF_COMMON_HPP
+#define YAPF_COMMON_HPP
+
+/** YAPF origin provider base class - used when origin is one tile / multiple trackdirs */
+template <class Types>
+class CYapfOriginTileT
+{
+public:
+ typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
+ typedef typename Types::NodeList::Titem Node; ///< this will be our node type
+ typedef typename Node::Key Key; ///< key to hash tables
+
+protected:
+ TileIndex m_orgTile; ///< origin tile
+ TrackdirBits m_orgTrackdirs; ///< origin trackdir mask
+
+ /// to access inherited path finder
+ FORCEINLINE Tpf& Yapf() {return *static_cast<Tpf*>(this);}
+
+public:
+ /// Set origin tile / trackdir mask
+ void SetOrigin(TileIndex tile, TrackdirBits trackdirs)
+ {
+ m_orgTile = tile;
+ m_orgTrackdirs = trackdirs;
+ }
+
+ /// Called when YAPF needs to place origin nodes into open list
+ void PfSetStartupNodes()
+ {
+ bool is_choice = (KillFirstBit2x64(m_orgTrackdirs) != 0);
+ for (TrackdirBits tdb = m_orgTrackdirs; tdb != TRACKDIR_BIT_NONE; tdb = (TrackdirBits)KillFirstBit2x64(tdb)) {
+ Trackdir td = (Trackdir)FindFirstBit2x64(tdb);
+ Node& n1 = Yapf().CreateNewNode();
+ n1.Set(NULL, m_orgTile, td, is_choice);
+ Yapf().AddStartupNode(n1);
+ }
+ }
+};
+
+/** YAPF origin provider base class - used when there are two tile/trackdir origins */
+template <class Types>
+class CYapfOriginTileTwoWayT
+{
+public:
+ typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
+ typedef typename Types::NodeList::Titem Node; ///< this will be our node type
+ typedef typename Node::Key Key; ///< key to hash tables
+
+protected:
+ TileIndex m_orgTile; ///< first origin tile
+ Trackdir m_orgTd; ///< first origin trackdir
+ TileIndex m_revTile; ///< second (reversed) origin tile
+ Trackdir m_revTd; ///< second (reversed) origin trackdir
+ int m_reverse_penalty; ///< penalty to be added for using the reversed origin
+ bool m_treat_first_red_two_way_signal_as_eol; ///< in some cases (leaving station) we need to handle first two-way signal differently
+
+ /// to access inherited path finder
+ FORCEINLINE Tpf& Yapf() {return *static_cast<Tpf*>(this);}
+
+public:
+ /// set origin (tiles, trackdirs, etc.)
+ void SetOrigin(TileIndex tile, Trackdir td, TileIndex tiler = INVALID_TILE, Trackdir tdr = INVALID_TRACKDIR, int reverse_penalty = 0, bool treat_first_red_two_way_signal_as_eol = true)
+ {
+ m_orgTile = tile;
+ m_orgTd = td;
+ m_revTile = tiler;
+ m_revTd = tdr;
+ m_reverse_penalty = reverse_penalty;
+ m_treat_first_red_two_way_signal_as_eol = treat_first_red_two_way_signal_as_eol;
+ }
+
+ /// Called when YAPF needs to place origin nodes into open list
+ void PfSetStartupNodes()
+ {
+ if (m_orgTile != INVALID_TILE && m_orgTd != INVALID_TRACKDIR) {
+ Node& n1 = Yapf().CreateNewNode();
+ n1.Set(NULL, m_orgTile, m_orgTd, false);
+ Yapf().AddStartupNode(n1);
+ }
+ if (m_revTile != INVALID_TILE && m_revTd != INVALID_TRACKDIR) {
+ Node& n2 = Yapf().CreateNewNode();
+ n2.Set(NULL, m_revTile, m_revTd, false);
+ n2.m_cost = m_reverse_penalty;
+ Yapf().AddStartupNode(n2);
+ }
+ }
+
+ /// return true if first two-way signal should be treated as dead end
+ FORCEINLINE bool TreatFirstRedTwoWaySignalAsEOL()
+ {
+ return Yapf().PfGetSettings().rail_firstred_twoway_eol && m_treat_first_red_two_way_signal_as_eol;
+ }
+};
+
+/** YAPF destination provider base class - used when destination is single tile / multiple trackdirs */
+template <class Types>
+class CYapfDestinationTileT
+{
+public:
+ typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
+ typedef typename Types::NodeList::Titem Node; ///< this will be our node type
+ typedef typename Node::Key Key; ///< key to hash tables
+
+protected:
+ TileIndex m_destTile; ///< destination tile
+ TrackdirBits m_destTrackdirs; ///< destination trackdir mask
+
+public:
+ /// set the destination tile / more trackdirs
+ void SetDestination(TileIndex tile, TrackdirBits trackdirs)
+ {
+ m_destTile = tile;
+ m_destTrackdirs = trackdirs;
+ }
+
+protected:
+ /// to access inherited path finder
+ Tpf& Yapf() {return *static_cast<Tpf*>(this);}
+
+public:
+ /// Called by YAPF to detect if node ends in the desired destination
+ FORCEINLINE bool PfDetectDestination(Node& n)
+ {
+ bool bDest = (n.m_key.m_tile == m_destTile) && ((m_destTrackdirs & TrackdirToTrackdirBits(n.GetTrackdir())) != TRACKDIR_BIT_NONE);
+ return bDest;
+ }
+
+ /** Called by YAPF to calculate cost estimate. Calculates distance to the destination
+ * adds it to the actual cost from origin and stores the sum to the Node::m_estimate */
+ inline bool PfCalcEstimate(Node& n)
+ {
+ int dx = abs(TileX(n.GetTile()) - TileX(m_destTile));
+ int dy = abs(TileY(n.GetTile()) - TileY(m_destTile));
+ assert(dx >= 0 && dy >= 0);
+ int dd = min(dx, dy);
+ int dxy = abs(dx - dy);
+ int d = 14 * dd + 10 * dxy;
+ n.m_estimate = n.m_cost + d /*+ d / 8*/;
+ return true;
+ }
+};
+
+/** YAPF template that uses Ttypes template argument to determine all YAPF
+ * components (base classes) from which the actual YAPF is composed.
+ * For example classes consult: CYapfRail_TypesT template and its instantiations:
+ * CYapfRail1, CYapfRail2, CYapfRail3, CYapfAnyDepotRail1, CYapfAnyDepotRail2, CYapfAnyDepotRail3 */
+template <class Ttypes>
+class CYapfT
+ : public Ttypes::PfBase ///< Instance of CYapfBaseT - main YAPF loop and support base class
+ , public Ttypes::PfCost ///< Cost calculation provider base class
+ , public Ttypes::PfCache ///< Segment cost cache provider
+ , public Ttypes::PfOrigin ///< Origin (tile or two-tile origin)
+ , public Ttypes::PfDestination ///< Destination detector and distance (estimate) calculation provider
+ , public Ttypes::PfFollow ///< Node follower (stepping provider)
+{
+};
+
+
+
+#endif /* YAPF_COMMON_HPP */
diff --git a/src/yapf/yapf_costbase.hpp b/src/yapf/yapf_costbase.hpp
new file mode 100644
index 000000000..df4d9e787
--- /dev/null
+++ b/src/yapf/yapf_costbase.hpp
@@ -0,0 +1,37 @@
+/* $Id$ */
+
+#ifndef YAPF_COSTBASE_HPP
+#define YAPF_COSTBASE_HPP
+
+struct CYapfCostBase {
+ static const TrackdirBits c_upwards_slopes[16];
+
+ FORCEINLINE static bool stSlopeCost(TileIndex tile, Trackdir td)
+ {
+ if (IsDiagonalTrackdir(td)) {
+ if (IsBridgeTile(tile)) {
+ // it is bridge ramp, check if we are entering the bridge
+ if (GetBridgeRampDirection(tile) != TrackdirToExitdir(td)) return false; // no, we are living it, no penalty
+ // we are entering the bridge
+ // if the tile slope is downwards, then bridge ramp has not upward slope
+ uint tile_slope = GetTileSlope(tile, NULL) & 0x0F;
+ if ((c_upwards_slopes[tile_slope] & TrackdirToTrackdirBits(ReverseTrackdir(td))) != 0) return false; // tile under ramp goes down, no penalty
+ // tile under ramp isn't going down, so ramp must go up
+ return true;
+ } else {
+ // not bridge ramp
+ if (IsTunnelTile(tile)) return false; // tunnel entry/exit doesn't slope
+ uint tile_slope = GetTileSlope(tile, NULL) & 0x0F;
+ if ((c_upwards_slopes[tile_slope] & TrackdirToTrackdirBits(td)) != 0) return true; // slopes uphill => apply penalty
+ }
+ }
+ return false;
+ }
+};
+
+struct CostRailSettings {
+ // look-ahead signal penalty
+};
+
+
+#endif /* YAPF_COSTBASE_HPP */
diff --git a/src/yapf/yapf_costcache.hpp b/src/yapf/yapf_costcache.hpp
new file mode 100644
index 000000000..c90d37302
--- /dev/null
+++ b/src/yapf/yapf_costcache.hpp
@@ -0,0 +1,196 @@
+/* $Id$ */
+#ifndef YAPF_COSTCACHE_HPP
+#define YAPF_COSTCACHE_HPP
+
+
+/** CYapfSegmentCostCacheNoneT - the formal only yapf cost cache provider that implements
+ * PfNodeCacheFetch() and PfNodeCacheFlush() callbacks. Used when nodes don't have CachedData
+ * defined (they don't count with any segment cost caching).
+ */
+template <class Types>
+class CYapfSegmentCostCacheNoneT
+{
+public:
+ typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
+ typedef typename Types::NodeList::Titem Node; ///< this will be our node type
+
+ /** Called by YAPF to attach cached or local segment cost data to the given node.
+ * @return true if globally cached data were used or false if local data was used */
+ FORCEINLINE bool PfNodeCacheFetch(Node& n)
+ {
+ return false;
+ };
+
+ /** Called by YAPF to flush the cached segment cost data back into cache storage.
+ * Current cache implementation doesn't use that. */
+ FORCEINLINE void PfNodeCacheFlush(Node& n)
+ {
+ };
+};
+
+
+/** CYapfSegmentCostCacheLocalT - the yapf cost cache provider that implements fake segment
+ * cost caching functionality for yapf. Used when node needs caching, but you don't want to
+ * cache the segment costs.
+ */
+template <class Types>
+class CYapfSegmentCostCacheLocalT
+{
+public:
+ typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
+ typedef typename Types::NodeList::Titem Node; ///< this will be our node type
+ typedef typename Node::Key Key; ///< key to hash tables
+ typedef typename Node::CachedData CachedData;
+ typedef typename CachedData::Key CacheKey;
+ typedef CArrayT<CachedData> LocalCache;
+
+protected:
+ LocalCache m_local_cache;
+
+ /// to access inherited path finder
+ FORCEINLINE Tpf& Yapf() {return *static_cast<Tpf*>(this);}
+
+public:
+ /** Called by YAPF to attach cached or local segment cost data to the given node.
+ * @return true if globally cached data were used or false if local data was used */
+ FORCEINLINE bool PfNodeCacheFetch(Node& n)
+ {
+ CacheKey key(n.GetKey());
+ Yapf().ConnectNodeToCachedData(n, *new (&m_local_cache.AddNC()) CachedData(key));
+ return false;
+ };
+
+ /** Called by YAPF to flush the cached segment cost data back into cache storage.
+ * Current cache implementation doesn't use that. */
+ FORCEINLINE void PfNodeCacheFlush(Node& n)
+ {
+ };
+};
+
+
+/** Base class for segment cost cache providers. Contains global counter
+ * of track layout changes and static notification function called whenever
+ * the track layout changes. It is implemented as base class because it needs
+ * to be shared between all rail YAPF types (one shared counter, one notification
+ * function. */
+struct CSegmentCostCacheBase
+{
+ static int s_rail_change_counter;
+
+ static void NotifyTrackLayoutChange(TileIndex tile, Track track) {s_rail_change_counter++;}
+};
+
+
+/** CSegmentCostCacheT - template class providing hash-map and storage (heap)
+ * of Tsegment structures. Each rail node contains pointer to the segment
+ * that contains cached (or non-cached) segment cost information. Nodes can
+ * differ by key type, but they use the same segment type. Segment key should
+ * be always the same (TileIndex + DiagDirection) that represent the beginning
+ * of the segment (origin tile and exit-dir from this tile).
+ * Different CYapfCachedCostT types can share the same type of CSegmentCostCacheT.
+ * Look at CYapfRailSegment (yapf_node_rail.hpp) for the segment example */
+template <class Tsegment>
+struct CSegmentCostCacheT
+ : public CSegmentCostCacheBase
+{
+ enum {c_hash_bits = 14};
+
+ typedef CHashTableT<Tsegment, c_hash_bits> HashTable;
+ typedef CArrayT<Tsegment> Heap;
+ typedef typename Tsegment::Key Key; ///< key to hash table
+
+ HashTable m_map;
+ Heap m_heap;
+
+ FORCEINLINE CSegmentCostCacheT() {}
+
+ /** flush (clear) the cache */
+ FORCEINLINE void Flush() {m_map.Clear(); m_heap.Clear();};
+
+ FORCEINLINE Tsegment& Get(Key& key, bool *found)
+ {
+ Tsegment* item = m_map.Find(key);
+ if (item == NULL) {
+ *found = false;
+ item = new (&m_heap.AddNC()) Tsegment(key);
+ m_map.Push(*item);
+ } else {
+ *found = true;
+ }
+ return *item;
+ }
+};
+
+/** CYapfSegmentCostCacheGlobalT - the yapf cost cache provider that adds the segment cost
+ * caching functionality to yapf. Using this class as base of your will provide the global
+ * segment cost caching services for your Nodes.
+*/
+template <class Types>
+class CYapfSegmentCostCacheGlobalT
+ : public CYapfSegmentCostCacheLocalT<Types>
+{
+public:
+ typedef CYapfSegmentCostCacheLocalT<Types> Tlocal;
+ typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
+ typedef typename Types::NodeList::Titem Node; ///< this will be our node type
+ typedef typename Node::Key Key; ///< key to hash tables
+ typedef typename Node::CachedData CachedData;
+ typedef typename CachedData::Key CacheKey;
+ typedef CSegmentCostCacheT<CachedData> Cache;
+
+protected:
+ Cache& m_global_cache;
+
+ FORCEINLINE CYapfSegmentCostCacheGlobalT() : m_global_cache(stGetGlobalCache()) {};
+
+ /// to access inherited path finder
+ FORCEINLINE Tpf& Yapf() {return *static_cast<Tpf*>(this);}
+
+ FORCEINLINE static Cache& stGetGlobalCache()
+ {
+ static int last_rail_change_counter = 0;
+ static Date last_date = 0;
+ static Cache C;
+
+ // some statistics
+ if (last_date != _date) {
+ last_date = _date;
+ DEBUG(yapf, 2, "Pf time today: %5d ms", _total_pf_time_us / 1000);
+ _total_pf_time_us = 0;
+ }
+
+ // delete the cache sometimes...
+ if (last_rail_change_counter != Cache::s_rail_change_counter) {
+ last_rail_change_counter = Cache::s_rail_change_counter;
+ C.Flush();
+ }
+ return C;
+ }
+
+public:
+ /** Called by YAPF to attach cached or local segment cost data to the given node.
+ * @return true if globally cached data were used or false if local data was used */
+ FORCEINLINE bool PfNodeCacheFetch(Node& n)
+ {
+ if (!Yapf().CanUseGlobalCache(n)) {
+ return Tlocal::PfNodeCacheFetch(n);
+ }
+ CacheKey key(n.GetKey());
+ bool found;
+ CachedData& item = m_global_cache.Get(key, &found);
+ Yapf().ConnectNodeToCachedData(n, item);
+ return found;
+ };
+
+ /** Called by YAPF to flush the cached segment cost data back into cache storage.
+ * Current cache implementation doesn't use that. */
+ FORCEINLINE void PfNodeCacheFlush(Node& n)
+ {
+ };
+
+};
+
+
+
+
+#endif /* YAPF_COSTCACHE_HPP */
diff --git a/src/yapf/yapf_costrail.hpp b/src/yapf/yapf_costrail.hpp
new file mode 100644
index 000000000..93062b5c2
--- /dev/null
+++ b/src/yapf/yapf_costrail.hpp
@@ -0,0 +1,381 @@
+/* $Id$ */
+
+#ifndef YAPF_COSTRAIL_HPP
+#define YAPF_COSTRAIL_HPP
+
+
+template <class Types>
+class CYapfCostRailT
+ : public CYapfCostBase
+ , public CostRailSettings
+{
+public:
+ typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
+ typedef typename Types::TrackFollower TrackFollower;
+ typedef typename Types::NodeList::Titem Node; ///< this will be our node type
+ typedef typename Node::Key Key; ///< key to hash tables
+ typedef typename Node::CachedData CachedData;
+
+protected:
+ int m_max_cost;
+ CBlobT<int> m_sig_look_ahead_costs;
+public:
+ bool m_stopped_on_first_two_way_signal;
+protected:
+
+ static const int s_max_segment_cost = 10000;
+
+ CYapfCostRailT()
+ : m_max_cost(0)
+ , m_stopped_on_first_two_way_signal(false)
+ {
+ // pre-compute look-ahead penalties into array
+ int p0 = Yapf().PfGetSettings().rail_look_ahead_signal_p0;
+ int p1 = Yapf().PfGetSettings().rail_look_ahead_signal_p1;
+ int p2 = Yapf().PfGetSettings().rail_look_ahead_signal_p2;
+ int *pen = m_sig_look_ahead_costs.GrowSizeNC(Yapf().PfGetSettings().rail_look_ahead_max_signals);
+ for (uint i = 0; i < Yapf().PfGetSettings().rail_look_ahead_max_signals; i++)
+ pen[i] = p0 + i * (p1 + i * p2);
+ }
+
+ /// to access inherited path finder
+ Tpf& Yapf() {return *static_cast<Tpf*>(this);}
+
+public:
+ FORCEINLINE int SlopeCost(TileIndex tile, Trackdir td)
+ {
+ CPerfStart perf_cost(Yapf().m_perf_slope_cost);
+ if (!stSlopeCost(tile, td)) return 0;
+ return Yapf().PfGetSettings().rail_slope_penalty;
+ }
+
+ FORCEINLINE int CurveCost(Trackdir td1, Trackdir td2)
+ {
+ int cost = 0;
+ if (TrackFollower::Allow90degTurns()
+ && ((TrackdirToTrackdirBits(td2) & (TrackdirBits)TrackdirCrossesTrackdirs(td1)) != 0)) {
+ // 90-deg curve penalty
+ cost += Yapf().PfGetSettings().rail_curve90_penalty;
+ } else if (td2 != NextTrackdir(td1)) {
+ // 45-deg curve penalty
+ cost += Yapf().PfGetSettings().rail_curve45_penalty;
+ }
+ return cost;
+ }
+
+ /** return one tile cost. If tile is a tunnel entry, it is moved to the end of tunnel */
+ FORCEINLINE int OneTileCost(TileIndex& tile, Trackdir trackdir)
+ {
+ int cost = 0;
+ // set base cost
+ if (IsDiagonalTrackdir(trackdir)) {
+ cost += YAPF_TILE_LENGTH;
+ switch (GetTileType(tile)) {
+ case MP_STREET:
+ /* Increase the cost for level crossings */
+ if (IsLevelCrossing(tile))
+ cost += Yapf().PfGetSettings().rail_crossing_penalty;
+ break;
+
+ case MP_STATION:
+ // penalty for passing station tiles
+ cost += Yapf().PfGetSettings().rail_station_penalty;
+ break;
+
+ default:
+ break;
+ }
+ } else {
+ // non-diagonal trackdir
+ cost = YAPF_TILE_CORNER_LENGTH;
+ }
+ return cost;
+ }
+
+ int SignalCost(Node& n, TileIndex tile, Trackdir trackdir)
+ {
+ int cost = 0;
+ // if there is one-way signal in the opposite direction, then it is not our way
+ CPerfStart perf_cost(Yapf().m_perf_other_cost);
+ if (IsTileType(tile, MP_RAILWAY)) {
+ bool has_signal_against = HasSignalOnTrackdir(tile, ReverseTrackdir(trackdir));
+ bool has_signal_along = HasSignalOnTrackdir(tile, trackdir);
+ if (has_signal_against && !has_signal_along) {
+ // one-way signal in opposite direction
+ n.m_segment->flags_u.flags_s.m_end_of_line = true;
+ } else if (has_signal_along) {
+ SignalState sig_state = GetSignalStateByTrackdir(tile, trackdir);
+ // cache the look-ahead polynomial constant only if we didn't pass more signals than the look-ahead limit is
+ int look_ahead_cost = (n.m_num_signals_passed < m_sig_look_ahead_costs.Size()) ? m_sig_look_ahead_costs.Data()[n.m_num_signals_passed] : 0;
+ if (sig_state != SIGNAL_STATE_RED) {
+ // green signal
+ n.flags_u.flags_s.m_last_signal_was_red = false;
+ // negative look-ahead red-signal penalties would cause problems later, so use them as positive penalties for green signal
+ if (look_ahead_cost < 0) {
+ // add its negation to the cost
+ cost -= look_ahead_cost;
+ }
+ } else {
+ // we have a red signal in our direction
+ // was it first signal which is two-way?
+ if (Yapf().TreatFirstRedTwoWaySignalAsEOL() && n.flags_u.flags_s.m_choice_seen && has_signal_against && n.m_num_signals_passed == 0) {
+ // yes, the first signal is two-way red signal => DEAD END
+ n.m_segment->flags_u.flags_s.m_end_of_line = true;
+ Yapf().m_stopped_on_first_two_way_signal = true;
+ return -1;
+ }
+ SignalType sig_type = GetSignalType(tile);
+ n.m_last_red_signal_type = sig_type;
+ n.flags_u.flags_s.m_last_signal_was_red = true;
+
+ // look-ahead signal penalty
+ if (look_ahead_cost > 0) {
+ // add the look ahead penalty only if it is positive
+ cost += look_ahead_cost;
+ }
+
+ // special signal penalties
+ if (n.m_num_signals_passed == 0) {
+ switch (sig_type) {
+ case SIGTYPE_COMBO:
+ case SIGTYPE_EXIT: cost += Yapf().PfGetSettings().rail_firstred_exit_penalty; break; // first signal is red pre-signal-exit
+ case SIGTYPE_NORMAL:
+ case SIGTYPE_ENTRY: cost += Yapf().PfGetSettings().rail_firstred_penalty; break;
+ };
+ }
+ }
+ n.m_num_signals_passed++;
+ n.m_segment->m_last_signal_tile = tile;
+ n.m_segment->m_last_signal_td = trackdir;
+ }
+ }
+ return cost;
+ }
+
+ FORCEINLINE int PlatformLengthPenalty(int platform_length)
+ {
+ int cost = 0;
+ const Vehicle* v = Yapf().GetVehicle();
+ assert(v != NULL);
+ assert(v->type == VEH_Train);
+ assert(v->u.rail.cached_total_length != 0);
+ int needed_platform_length = (v->u.rail.cached_total_length + TILE_SIZE - 1) / TILE_SIZE;
+ if (platform_length > needed_platform_length) {
+ // apply penalty for longer platform than needed
+ cost += Yapf().PfGetSettings().rail_longer_platform_penalty;
+ } else if (needed_platform_length > platform_length) {
+ // apply penalty for shorter platform than needed
+ cost += Yapf().PfGetSettings().rail_shorter_platform_penalty;
+ }
+ return cost;
+ }
+
+public:
+ FORCEINLINE void SetMaxCost(int max_cost) {m_max_cost = max_cost;}
+
+ /** Called by YAPF to calculate the cost from the origin to the given node.
+ * Calculates only the cost of given node, adds it to the parent node cost
+ * and stores the result into Node::m_cost member */
+ FORCEINLINE bool PfCalcCost(Node& n)
+ {
+ assert(!n.flags_u.flags_s.m_targed_seen);
+ CPerfStart perf_cost(Yapf().m_perf_cost);
+ int parent_cost = (n.m_parent != NULL) ? n.m_parent->m_cost : 0;
+ int first_tile_cost = 0;
+ int segment_cost = 0;
+ int extra_cost = 0;
+ const Vehicle* v = Yapf().GetVehicle();
+
+ // start at n.m_key.m_tile / n.m_key.m_td and walk to the end of segment
+ TileIndex prev_tile = (n.m_parent != NULL) ? n.m_parent->GetLastTile() : INVALID_TILE;
+ Trackdir prev_trackdir = (n.m_parent != NULL) ? n.m_parent->GetLastTrackdir() : INVALID_TRACKDIR;
+ TileType prev_tile_type = (n.m_parent != NULL) ? GetTileType(n.m_parent->GetLastTile()) : MP_VOID;
+
+ TileIndex tile = n.m_key.m_tile;
+ Trackdir trackdir = n.m_key.m_td;
+ TileType tile_type = GetTileType(tile);
+
+ RailType rail_type = GetTileRailType(tile, trackdir);
+
+ bool target_seen = Yapf().PfDetectDestination(tile, trackdir);
+
+ while (true) {
+ segment_cost += Yapf().OneTileCost(tile, trackdir);
+ segment_cost += Yapf().CurveCost(prev_trackdir, trackdir);
+ segment_cost += Yapf().SlopeCost(tile, trackdir);
+ segment_cost += Yapf().SignalCost(n, tile, trackdir);
+ if (n.m_segment->flags_u.flags_s.m_end_of_line) {
+ break;
+ }
+
+ // finish if we have reached the destination
+ if (target_seen) {
+ break;
+ }
+
+ // finish on first station tile - segment should end here to avoid target skipping
+ // when cached segments are used
+ if (tile_type == MP_STATION && prev_tile_type != MP_STATION) {
+ break;
+ }
+
+ // finish also on waypoint - same workaround as for first station tile
+ if (tile_type == MP_RAILWAY && IsRailWaypoint(tile)) {
+ break;
+ }
+
+ // if there are no reachable trackdirs on the next tile, we have end of road
+ TrackFollower F(v, &Yapf().m_perf_ts_cost);
+ if (!F.Follow(tile, trackdir)) {
+ // we can't continue?
+ // n.m_segment->flags_u.flags_s.m_end_of_line = true;
+ break;
+ }
+
+ // if there are more trackdirs available & reachable, we are at the end of segment
+ if (KillFirstBit2x64(F.m_new_td_bits) != 0) {
+ break;
+ }
+
+ Trackdir new_td = (Trackdir)FindFirstBit2x64(F.m_new_td_bits);
+
+ {
+ // end segment if train is about to enter simple loop with no junctions
+ // so next time it should stop on the next if
+ if (segment_cost > s_max_segment_cost && IsTileType(F.m_new_tile, MP_RAILWAY))
+ break;
+
+ // stop if train is on simple loop with no junctions
+ if (F.m_new_tile == n.m_key.m_tile && new_td == n.m_key.m_td)
+ return false;
+ }
+
+ // if tail type changes, finish segment (cached segment can't contain more rail types)
+ {
+ RailType new_rail_type = GetTileRailType(F.m_new_tile, (Trackdir)FindFirstBit2x64(F.m_new_td_bits));
+ if (new_rail_type != rail_type) {
+ break;
+ }
+ rail_type = new_rail_type;
+ }
+
+ // move to the next tile
+ prev_tile = tile;
+ prev_trackdir = trackdir;
+ prev_tile_type = tile_type;
+
+ tile = F.m_new_tile;
+ trackdir = new_td;
+ tile_type = GetTileType(tile);
+
+ target_seen = Yapf().PfDetectDestination(tile, trackdir);
+
+ // reversing in depot penalty
+ if (tile == prev_tile) {
+ segment_cost += Yapf().PfGetSettings().rail_depot_reverse_penalty;
+ break;
+ }
+
+ // if we skipped some tunnel tiles, add their cost
+ segment_cost += YAPF_TILE_LENGTH * F.m_tiles_skipped;
+
+ // add penalty for skipped station tiles
+ if (F.m_is_station)
+ {
+ if (target_seen) {
+ // it is our destination station
+ uint platform_length = F.m_tiles_skipped + 1;
+ segment_cost += PlatformLengthPenalty(platform_length);
+ } else {
+ // station is not our destination station, apply penalty for skipped platform tiles
+ segment_cost += Yapf().PfGetSettings().rail_station_penalty * F.m_tiles_skipped;
+ }
+ }
+
+ // add min/max speed penalties
+ int min_speed = 0;
+ int max_speed = F.GetSpeedLimit(&min_speed);
+ if (max_speed < v->max_speed)
+ segment_cost += YAPF_TILE_LENGTH * (v->max_speed - max_speed) / v->max_speed;
+ if (min_speed > v->max_speed)
+ segment_cost += YAPF_TILE_LENGTH * (min_speed - v->max_speed);
+
+ // finish if we already exceeded the maximum cost
+ if (m_max_cost > 0 && (parent_cost + first_tile_cost + segment_cost) > m_max_cost) {
+ return false;
+ }
+
+ if (first_tile_cost == 0) {
+ // we just have done first tile
+ first_tile_cost = segment_cost;
+ segment_cost = 0;
+
+ // look if we can reuse existing (cached) segment cost
+ if (n.m_segment->m_cost >= 0) {
+ // reuse the cached segment cost
+ break;
+ }
+ }
+ // segment cost was not filled yes, we have not cached it yet
+ n.SetLastTileTrackdir(tile, trackdir);
+
+ } // while (true)
+
+ if (first_tile_cost == 0) {
+ // we have just finished first tile
+ first_tile_cost = segment_cost;
+ segment_cost = 0;
+ }
+
+ // do we have cached segment cost?
+ if (n.m_segment->m_cost >= 0) {
+ // reuse the cached segment cost
+ segment_cost = n.m_segment->m_cost;
+ } else {
+ // save segment cost
+ n.m_segment->m_cost = segment_cost;
+
+ // save end of segment back to the node
+ n.SetLastTileTrackdir(tile, trackdir);
+ }
+
+ // special costs for the case we have reached our target
+ if (target_seen) {
+ n.flags_u.flags_s.m_targed_seen = true;
+ if (n.flags_u.flags_s.m_last_signal_was_red) {
+ if (n.m_last_red_signal_type == SIGTYPE_EXIT) {
+ // last signal was red pre-signal-exit
+ extra_cost += Yapf().PfGetSettings().rail_lastred_exit_penalty;
+ } else {
+ // last signal was red, but not exit
+ extra_cost += Yapf().PfGetSettings().rail_lastred_penalty;
+ }
+ }
+ }
+
+ // total node cost
+ n.m_cost = parent_cost + first_tile_cost + segment_cost + extra_cost;
+
+ return !n.m_segment->flags_u.flags_s.m_end_of_line;
+ }
+
+ FORCEINLINE bool CanUseGlobalCache(Node& n) const
+ {
+ return (n.m_parent != NULL)
+ && (n.m_parent->m_num_signals_passed >= m_sig_look_ahead_costs.Size());
+ }
+
+ FORCEINLINE void ConnectNodeToCachedData(Node& n, CachedData& ci)
+ {
+ n.m_segment = &ci;
+ if (n.m_segment->m_cost < 0) {
+ n.m_segment->m_last_tile = n.m_key.m_tile;
+ n.m_segment->m_last_td = n.m_key.m_td;
+ }
+ }
+
+};
+
+
+
+#endif /* YAPF_COSTRAIL_HPP */
diff --git a/src/yapf/yapf_destrail.hpp b/src/yapf/yapf_destrail.hpp
new file mode 100644
index 000000000..9a5bd0536
--- /dev/null
+++ b/src/yapf/yapf_destrail.hpp
@@ -0,0 +1,149 @@
+/* $Id$ */
+
+#ifndef YAPF_DESTRAIL_HPP
+#define YAPF_DESTRAIL_HPP
+
+class CYapfDestinationRailBase
+{
+protected:
+ RailTypeMask m_compatible_railtypes;
+
+public:
+ void SetDestination(Vehicle* v)
+ {
+ m_compatible_railtypes = v->u.rail.compatible_railtypes;
+ }
+
+ bool IsCompatibleRailType(RailType rt)
+ {
+ return HASBIT(m_compatible_railtypes, rt);
+ }
+};
+
+template <class Types>
+class CYapfDestinationAnyDepotRailT
+ : public CYapfDestinationRailBase
+{
+public:
+ typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
+ typedef typename Types::NodeList::Titem Node; ///< this will be our node type
+ typedef typename Node::Key Key; ///< key to hash tables
+
+ /// to access inherited path finder
+ Tpf& Yapf() {return *static_cast<Tpf*>(this);}
+
+ /// Called by YAPF to detect if node ends in the desired destination
+ FORCEINLINE bool PfDetectDestination(Node& n)
+ {
+ return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
+ }
+
+ /// Called by YAPF to detect if node ends in the desired destination
+ FORCEINLINE bool PfDetectDestination(TileIndex tile, Trackdir td)
+ {
+ bool bDest = IsTileDepotType(tile, TRANSPORT_RAIL);
+ return bDest;
+ }
+
+ /** Called by YAPF to calculate cost estimate. Calculates distance to the destination
+ * adds it to the actual cost from origin and stores the sum to the Node::m_estimate */
+ FORCEINLINE bool PfCalcEstimate(Node& n)
+ {
+ n.m_estimate = n.m_cost;
+ return true;
+ }
+};
+
+template <class Types>
+class CYapfDestinationTileOrStationRailT
+ : public CYapfDestinationRailBase
+{
+public:
+ typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
+ typedef typename Types::NodeList::Titem Node; ///< this will be our node type
+ typedef typename Node::Key Key; ///< key to hash tables
+
+protected:
+ TileIndex m_destTile;
+ TrackdirBits m_destTrackdirs;
+ StationID m_dest_station_id;
+
+ /// to access inherited path finder
+ Tpf& Yapf() {return *static_cast<Tpf*>(this);}
+
+ static TileIndex CalcStationCenterTile(StationID station)
+ {
+ const Station* st = GetStation(station);
+
+ uint x = TileX(st->train_tile) + st->trainst_w / 2;
+ uint y = TileY(st->train_tile) + st->trainst_h / 2;
+ // return the tile of our target coordinates
+ return TileXY(x, y);
+ }
+
+public:
+ void SetDestination(Vehicle* v)
+ {
+ if (v->current_order.type == OT_GOTO_STATION) {
+ m_destTile = CalcStationCenterTile(v->current_order.dest);
+ m_dest_station_id = v->current_order.dest;
+ m_destTrackdirs = INVALID_TRACKDIR_BIT;
+ } else {
+ m_destTile = v->dest_tile;
+ m_dest_station_id = INVALID_STATION;
+ m_destTrackdirs = (TrackdirBits)(GetTileTrackStatus(v->dest_tile, TRANSPORT_RAIL) & TRACKDIR_BIT_MASK);
+ }
+ CYapfDestinationRailBase::SetDestination(v);
+ }
+
+ /// Called by YAPF to detect if node ends in the desired destination
+ FORCEINLINE bool PfDetectDestination(Node& n)
+ {
+ return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
+ }
+
+ /// Called by YAPF to detect if node ends in the desired destination
+ FORCEINLINE bool PfDetectDestination(TileIndex tile, Trackdir td)
+ {
+ bool bDest;
+ if (m_dest_station_id != INVALID_STATION) {
+ bDest = IsRailwayStationTile(tile)
+ && (GetStationIndex(tile) == m_dest_station_id)
+ && (GetRailStationTrack(tile) == TrackdirToTrack(td));
+ } else {
+ bDest = (tile == m_destTile)
+ && ((m_destTrackdirs & TrackdirToTrackdirBits(td)) != TRACKDIR_BIT_NONE);
+ }
+ return bDest;
+ }
+
+ /** Called by YAPF to calculate cost estimate. Calculates distance to the destination
+ * adds it to the actual cost from origin and stores the sum to the Node::m_estimate */
+ FORCEINLINE bool PfCalcEstimate(Node& n)
+ {
+ static int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
+ static int dg_dir_to_y_offs[] = {0, 1, 0, -1};
+ if (PfDetectDestination(n)) {
+ n.m_estimate = n.m_cost;
+ return true;
+ }
+
+ TileIndex tile = n.GetLastTile();
+ DiagDirection exitdir = TrackdirToExitdir(n.GetLastTrackdir());
+ int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
+ int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
+ int x2 = 2 * TileX(m_destTile);
+ int y2 = 2 * TileY(m_destTile);
+ int dx = abs(x1 - x2);
+ int dy = abs(y1 - y2);
+ int dmin = min(dx, dy);
+ int dxy = abs(dx - dy);
+ int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2);
+ n.m_estimate = n.m_cost + d;
+ assert(n.m_estimate >= n.m_parent->m_estimate);
+ return true;
+ }
+};
+
+
+#endif /* YAPF_DESTRAIL_HPP */
diff --git a/src/yapf/yapf_node.hpp b/src/yapf/yapf_node.hpp
new file mode 100644
index 000000000..2fa82a6a6
--- /dev/null
+++ b/src/yapf/yapf_node.hpp
@@ -0,0 +1,77 @@
+/* $Id$ */
+
+#ifndef YAPF_NODE_HPP
+#define YAPF_NODE_HPP
+
+/** Yapf Node Key that evaluates hash from (and compares) tile & exit dir. */
+struct CYapfNodeKeyExitDir {
+ TileIndex m_tile;
+ Trackdir m_td;
+ DiagDirection m_exitdir;
+
+ FORCEINLINE void Set(TileIndex tile, Trackdir td)
+ {
+ m_tile = tile;
+ m_td = td;
+ m_exitdir = (m_td == INVALID_TRACKDIR) ? INVALID_DIAGDIR : TrackdirToExitdir(m_td);
+ }
+
+ FORCEINLINE int CalcHash() const {return m_exitdir | (m_tile << 2);}
+ FORCEINLINE bool operator == (const CYapfNodeKeyExitDir& other) const {return (m_tile == other.m_tile) && (m_exitdir == other.m_exitdir);}
+};
+
+struct CYapfNodeKeyTrackDir : public CYapfNodeKeyExitDir
+{
+ FORCEINLINE int CalcHash() const {return m_td | (m_tile << 4);}
+ FORCEINLINE bool operator == (const CYapfNodeKeyTrackDir& other) const {return (m_tile == other.m_tile) && (m_td == other.m_td);}
+};
+
+/** Yapf Node base */
+template <class Tkey_, class Tnode>
+struct CYapfNodeT {
+ typedef Tkey_ Key;
+ typedef Tnode Node;
+
+ Tkey_ m_key;
+ Node *m_hash_next;
+ Node *m_parent;
+ int m_cost;
+ int m_estimate;
+
+ FORCEINLINE void Set(Node *parent, TileIndex tile, Trackdir td, bool is_choice)
+ {
+ m_key.Set(tile, td);
+ m_hash_next = NULL;
+ m_parent = parent;
+ m_cost = 0;
+ m_estimate = 0;
+ }
+
+ FORCEINLINE Node* GetHashNext() {return m_hash_next;}
+ FORCEINLINE void SetHashNext(Node *pNext) {m_hash_next = pNext;}
+ FORCEINLINE TileIndex GetTile() const {return m_key.m_tile;}
+ FORCEINLINE Trackdir GetTrackdir() const {return m_key.m_td;}
+ FORCEINLINE const Tkey_& GetKey() const {return m_key;}
+ FORCEINLINE int GetCost() {return m_cost;}
+ FORCEINLINE int GetCostEstimate() {return m_estimate;}
+ FORCEINLINE bool operator < (const Node& other) const {return m_estimate < other.m_estimate;}
+};
+
+/** Yapf Node for ships */
+template <class Tkey_>
+struct CYapfShipNodeT
+ : CYapfNodeT<Tkey_, CYapfShipNodeT<Tkey_> >
+{
+
+};
+
+// now define two major node types (that differ by key type)
+typedef CYapfShipNodeT<CYapfNodeKeyExitDir> CYapfShipNodeExitDir;
+typedef CYapfShipNodeT<CYapfNodeKeyTrackDir> CYapfShipNodeTrackDir;
+
+// Default NodeList types
+typedef CNodeList_HashTableT<CYapfShipNodeExitDir , 14, 16> CShipNodeListExitDir;
+typedef CNodeList_HashTableT<CYapfShipNodeTrackDir, 16, 20> CShipNodeListTrackDir;
+
+
+#endif /* YAPF_NODE_HPP */
diff --git a/src/yapf/yapf_node_rail.hpp b/src/yapf/yapf_node_rail.hpp
new file mode 100644
index 000000000..df0186989
--- /dev/null
+++ b/src/yapf/yapf_node_rail.hpp
@@ -0,0 +1,113 @@
+/* $Id$ */
+
+#ifndef YAPF_NODE_RAIL_HPP
+#define YAPF_NODE_RAIL_HPP
+
+/** key for cached segment cost for rail YAPF */
+struct CYapfRailSegmentKey
+{
+ uint32 m_value;
+
+ FORCEINLINE CYapfRailSegmentKey(const CYapfRailSegmentKey& src) : m_value(src.m_value) {}
+ FORCEINLINE CYapfRailSegmentKey(const CYapfNodeKeyExitDir& node_key) {Set(node_key);}
+
+ FORCEINLINE void Set(const CYapfRailSegmentKey& src) {m_value = src.m_value;}
+ FORCEINLINE void Set(const CYapfNodeKeyExitDir& node_key) {m_value = (((int)node_key.m_tile) << 2) | node_key.m_exitdir;}
+
+ FORCEINLINE int32 CalcHash() const {return m_value;}
+ FORCEINLINE TileIndex GetTile() const {return (TileIndex)(m_value >> 2);}
+ FORCEINLINE DiagDirection GetExitDir() const {return (DiagDirection)(m_value & 3);}
+ FORCEINLINE bool operator == (const CYapfRailSegmentKey& other) const {return m_value == other.m_value;}
+};
+
+/** cached segment cost for rail YAPF */
+struct CYapfRailSegment
+{
+ typedef CYapfRailSegmentKey Key;
+
+ CYapfRailSegmentKey m_key;
+ TileIndex m_last_tile;
+ Trackdir m_last_td;
+ int m_cost;
+ TileIndex m_last_signal_tile;
+ Trackdir m_last_signal_td;
+ CYapfRailSegment* m_hash_next;
+ union {
+ byte m_flags;
+ struct {
+ bool m_end_of_line : 1;
+ } flags_s;
+ } flags_u;
+ byte m_reserve[3];
+
+ FORCEINLINE CYapfRailSegment(const CYapfRailSegmentKey& key)
+ : m_key(key)
+ , m_last_tile(INVALID_TILE)
+ , m_last_td(INVALID_TRACKDIR)
+ , m_cost(-1)
+ , m_last_signal_tile(INVALID_TILE)
+ , m_last_signal_td(INVALID_TRACKDIR)
+ , m_hash_next(NULL)
+ {
+ flags_u.m_flags = 0;
+ }
+
+ FORCEINLINE const Key& GetKey() const {return m_key;}
+ FORCEINLINE TileIndex GetTile() const {return m_key.GetTile();}
+ FORCEINLINE DiagDirection GetExitDir() const {return m_key.GetExitDir();}
+ FORCEINLINE CYapfRailSegment* GetHashNext() {return m_hash_next;}
+ FORCEINLINE void SetHashNext(CYapfRailSegment* next) {m_hash_next = next;}
+};
+
+/** Yapf Node for rail YAPF */
+template <class Tkey_>
+struct CYapfRailNodeT
+ : CYapfNodeT<Tkey_, CYapfRailNodeT<Tkey_> >
+{
+ typedef CYapfNodeT<Tkey_, CYapfRailNodeT<Tkey_> > base;
+ typedef CYapfRailSegment CachedData;
+
+ CYapfRailSegment *m_segment;
+ uint16 m_num_signals_passed;
+ union {
+ uint32 m_inherited_flags;
+ struct {
+ bool m_targed_seen : 1;
+ bool m_choice_seen : 1;
+ bool m_last_signal_was_red : 1;
+ } flags_s;
+ } flags_u;
+ SignalType m_last_red_signal_type;
+
+ FORCEINLINE void Set(CYapfRailNodeT* parent, TileIndex tile, Trackdir td, bool is_choice)
+ {
+ base::Set(parent, tile, td, is_choice);
+ m_segment = NULL;
+ if (parent == NULL) {
+ m_num_signals_passed = 0;
+ flags_u.m_inherited_flags = 0;
+ m_last_red_signal_type = SIGTYPE_NORMAL;
+ } else {
+ m_num_signals_passed = parent->m_num_signals_passed;
+ flags_u.m_inherited_flags = parent->flags_u.m_inherited_flags;
+ m_last_red_signal_type = parent->m_last_red_signal_type;
+ }
+ flags_u.flags_s.m_choice_seen |= is_choice;
+ }
+
+ FORCEINLINE TileIndex GetLastTile() const {assert(m_segment != NULL); return m_segment->m_last_tile;}
+ FORCEINLINE Trackdir GetLastTrackdir() const {assert(m_segment != NULL); return m_segment->m_last_td;}
+ FORCEINLINE void SetLastTileTrackdir(TileIndex tile, Trackdir td) {assert(m_segment != NULL); m_segment->m_last_tile = tile; m_segment->m_last_td = td;}
+};
+
+// now define two major node types (that differ by key type)
+typedef CYapfRailNodeT<CYapfNodeKeyExitDir> CYapfRailNodeExitDir;
+typedef CYapfRailNodeT<CYapfNodeKeyTrackDir> CYapfRailNodeTrackDir;
+
+// Default NodeList types
+typedef CNodeList_HashTableT<CYapfRailNodeExitDir , 10, 12> CRailNodeListExitDir;
+typedef CNodeList_HashTableT<CYapfRailNodeTrackDir, 12, 16> CRailNodeListTrackDir;
+
+
+
+#endif /* YAPF_NODE_RAIL_HPP */
diff --git a/src/yapf/yapf_node_road.hpp b/src/yapf/yapf_node_road.hpp
new file mode 100644
index 000000000..dc6f1be3a
--- /dev/null
+++ b/src/yapf/yapf_node_road.hpp
@@ -0,0 +1,36 @@
+/* $Id$ */
+
+#ifndef YAPF_NODE_ROAD_HPP
+#define YAPF_NODE_ROAD_HPP
+
+
+
+/** Yapf Node for road YAPF */
+template <class Tkey_>
+struct CYapfRoadNodeT
+ : CYapfNodeT<Tkey_, CYapfRoadNodeT<Tkey_> >
+{
+ typedef CYapfNodeT<Tkey_, CYapfRoadNodeT<Tkey_> > base;
+
+ TileIndex m_segment_last_tile;
+ Trackdir m_segment_last_td;
+
+ void Set(CYapfRoadNodeT* parent, TileIndex tile, Trackdir td, bool is_choice)
+ {
+ base::Set(parent, tile, td, is_choice);
+ m_segment_last_tile = tile;
+ m_segment_last_td = td;
+ }
+};
+
+// now define two major node types (that differ by key type)
+typedef CYapfRoadNodeT<CYapfNodeKeyExitDir> CYapfRoadNodeExitDir;
+typedef CYapfRoadNodeT<CYapfNodeKeyTrackDir> CYapfRoadNodeTrackDir;
+
+// Default NodeList types
+typedef CNodeList_HashTableT<CYapfRoadNodeExitDir , 8, 12> CRoadNodeListExitDir;
+typedef CNodeList_HashTableT<CYapfRoadNodeTrackDir, 10, 14> CRoadNodeListTrackDir;
+
+
+
+#endif /* YAPF_NODE_ROAD_HPP */
diff --git a/src/yapf/yapf_rail.cpp b/src/yapf/yapf_rail.cpp
new file mode 100644
index 000000000..1461b9402
--- /dev/null
+++ b/src/yapf/yapf_rail.cpp
@@ -0,0 +1,277 @@
+/* $Id$ */
+
+#include "../stdafx.h"
+
+#include "yapf.hpp"
+#include "yapf_node_rail.hpp"
+#include "yapf_costrail.hpp"
+#include "yapf_destrail.hpp"
+
+int _total_pf_time_us = 0;
+
+
+
+
+
+template <class Types>
+class CYapfFollowAnyDepotRailT
+{
+public:
+ typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
+ typedef typename Types::TrackFollower TrackFollower;
+ typedef typename Types::NodeList::Titem Node; ///< this will be our node type
+ typedef typename Node::Key Key; ///< key to hash tables
+
+protected:
+ /// to access inherited path finder
+ FORCEINLINE Tpf& Yapf() {return *static_cast<Tpf*>(this);}
+
+public:
+ /** Called by YAPF to move from the given node to the next tile. For each
+ * reachable trackdir on the new tile creates new node, initializes it
+ * and adds it to the open list by calling Yapf().AddNewNode(n) */
+ inline void PfFollowNode(Node& old_node)
+ {
+ TrackFollower F(Yapf().GetVehicle());
+ if (F.Follow(old_node.GetLastTile(), old_node.GetLastTrackdir()))
+ Yapf().AddMultipleNodes(&old_node, F.m_new_tile, F.m_new_td_bits);
+ }
+
+ /// return debug report character to identify the transportation type
+ FORCEINLINE char TransportTypeChar() const {return 't';}
+
+ static bool stFindNearestDepotTwoWay(Vehicle *v, TileIndex t1, Trackdir td1, TileIndex t2, Trackdir td2, int max_distance, int reverse_penalty, TileIndex* depot_tile, bool* reversed)
+ {
+ Tpf pf;
+ return pf.FindNearestDepotTwoWay(v, t1, td1, t2, td2, max_distance, reverse_penalty, depot_tile, reversed);
+ }
+
+ FORCEINLINE bool FindNearestDepotTwoWay(Vehicle *v, TileIndex t1, Trackdir td1, TileIndex t2, Trackdir td2, int max_distance, int reverse_penalty, TileIndex* depot_tile, bool* reversed)
+ {
+ // set origin and destination nodes
+ Yapf().SetOrigin(t1, td1, t2, td2, reverse_penalty, true);
+ Yapf().SetDestination(v);
+ Yapf().SetMaxCost(YAPF_TILE_LENGTH * max_distance);
+
+ // find the best path
+ bool bFound = Yapf().FindPath(v);
+ if (!bFound) return false;
+
+ // some path found
+ // get found depot tile
+ Node& n = Yapf().GetBestNode();
+ *depot_tile = n.GetLastTile();
+
+ // walk through the path back to the origin
+ Node* pNode = &n;
+ while (pNode->m_parent != NULL) {
+ pNode = pNode->m_parent;
+ }
+
+ // if the origin node is our front vehicle tile/Trackdir then we didn't reverse
+ // but we can also look at the cost (== 0 -> not reversed, == reverse_penalty -> reversed)
+ *reversed = (pNode->m_cost != 0);
+
+ return true;
+ }
+};
+
+template <class Types>
+class CYapfFollowRailT
+{
+public:
+ typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
+ typedef typename Types::TrackFollower TrackFollower;
+ typedef typename Types::NodeList::Titem Node; ///< this will be our node type
+ typedef typename Node::Key Key; ///< key to hash tables
+
+protected:
+ /// to access inherited path finder
+ FORCEINLINE Tpf& Yapf() {return *static_cast<Tpf*>(this);}
+
+public:
+ /** Called by YAPF to move from the given node to the next tile. For each
+ * reachable trackdir on the new tile creates new node, initializes it
+ * and adds it to the open list by calling Yapf().AddNewNode(n) */
+ inline void PfFollowNode(Node& old_node)
+ {
+ TrackFollower F(Yapf().GetVehicle());
+ if (F.Follow(old_node.GetLastTile(), old_node.GetLastTrackdir()))
+ Yapf().AddMultipleNodes(&old_node, F.m_new_tile, F.m_new_td_bits);
+ }
+
+ /// return debug report character to identify the transportation type
+ FORCEINLINE char TransportTypeChar() const {return 't';}
+
+ static Trackdir stChooseRailTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs, bool *path_not_found)
+ {
+ // create pathfinder instance
+ Tpf pf;
+ return pf.ChooseRailTrack(v, tile, enterdir, trackdirs, path_not_found);
+ }
+
+ FORCEINLINE Trackdir ChooseRailTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs, bool *path_not_found)
+ {
+ // set origin and destination nodes
+ Yapf().SetOrigin(v->tile, GetVehicleTrackdir(v), INVALID_TILE, INVALID_TRACKDIR, 1, true);
+ Yapf().SetDestination(v);
+
+ // find the best path
+ bool path_found = Yapf().FindPath(v);
+ if (path_not_found != NULL) {
+ // tell controller that the path was only 'guessed'
+ // treat the path as found if stopped on the first two way signal(s)
+ *path_not_found = !(path_found || Yapf().m_stopped_on_first_two_way_signal);
+ }
+
+ // if path not found - return INVALID_TRACKDIR
+ Trackdir next_trackdir = INVALID_TRACKDIR;
+ Node* pNode = &Yapf().GetBestNode();
+ if (pNode != NULL) {
+ // path was found or at least suggested
+ // walk through the path back to the origin
+ Node* pPrev = NULL;
+ while (pNode->m_parent != NULL) {
+ pPrev = pNode;
+ pNode = pNode->m_parent;
+ }
+ // return trackdir from the best origin node (one of start nodes)
+ Node& best_next_node = *pPrev;
+ assert(best_next_node.GetTile() == tile);
+ next_trackdir = best_next_node.GetTrackdir();
+ }
+ return next_trackdir;
+ }
+
+ static bool stCheckReverseTrain(Vehicle* v, TileIndex t1, Trackdir td1, TileIndex t2, Trackdir td2)
+ {
+ Tpf pf;
+ return pf.CheckReverseTrain(v, t1, td1, t2, td2);
+ }
+
+ FORCEINLINE bool CheckReverseTrain(Vehicle* v, TileIndex t1, Trackdir td1, TileIndex t2, Trackdir td2)
+ {
+ // create pathfinder instance
+ // set origin and destination nodes
+ Yapf().SetOrigin(t1, td1, t2, td2, 1, false);
+ Yapf().SetDestination(v);
+
+ // find the best path
+ bool bFound = Yapf().FindPath(v);
+
+ if (!bFound) return false;
+
+ // path was found
+ // walk through the path back to the origin
+ Node* pNode = &Yapf().GetBestNode();
+ while (pNode->m_parent != NULL) {
+ pNode = pNode->m_parent;
+ }
+
+ // check if it was reversed origin
+ Node& best_org_node = *pNode;
+ bool reversed = (best_org_node.m_cost != 0);
+ return reversed;
+ }
+};
+
+template <class Tpf_, class Ttrack_follower, class Tnode_list, template <class Types> class TdestinationT, template <class Types> class TfollowT>
+struct CYapfRail_TypesT
+{
+ typedef CYapfRail_TypesT<Tpf_, Ttrack_follower, Tnode_list, TdestinationT, TfollowT> Types;
+
+ typedef Tpf_ Tpf;
+ typedef Ttrack_follower TrackFollower;
+ typedef Tnode_list NodeList;
+ typedef CYapfBaseT<Types> PfBase;
+ typedef TfollowT<Types> PfFollow;
+ typedef CYapfOriginTileTwoWayT<Types> PfOrigin;
+ typedef TdestinationT<Types> PfDestination;
+ typedef CYapfSegmentCostCacheGlobalT<Types> PfCache;
+ typedef CYapfCostRailT<Types> PfCost;
+};
+
+struct CYapfRail1 : CYapfT<CYapfRail_TypesT<CYapfRail1 , CFollowTrackRail , CRailNodeListTrackDir, CYapfDestinationTileOrStationRailT, CYapfFollowRailT> > {};
+struct CYapfRail2 : CYapfT<CYapfRail_TypesT<CYapfRail2 , CFollowTrackRail , CRailNodeListExitDir , CYapfDestinationTileOrStationRailT, CYapfFollowRailT> > {};
+struct CYapfRail3 : CYapfT<CYapfRail_TypesT<CYapfRail3 , CFollowTrackRailNo90, CRailNodeListTrackDir, CYapfDestinationTileOrStationRailT, CYapfFollowRailT> > {};
+
+struct CYapfAnyDepotRail1 : CYapfT<CYapfRail_TypesT<CYapfAnyDepotRail1, CFollowTrackRail , CRailNodeListTrackDir, CYapfDestinationAnyDepotRailT , CYapfFollowAnyDepotRailT> > {};
+struct CYapfAnyDepotRail2 : CYapfT<CYapfRail_TypesT<CYapfAnyDepotRail2, CFollowTrackRail , CRailNodeListExitDir , CYapfDestinationAnyDepotRailT , CYapfFollowAnyDepotRailT> > {};
+struct CYapfAnyDepotRail3 : CYapfT<CYapfRail_TypesT<CYapfAnyDepotRail3, CFollowTrackRailNo90, CRailNodeListTrackDir, CYapfDestinationAnyDepotRailT , CYapfFollowAnyDepotRailT> > {};
+
+
+Trackdir YapfChooseRailTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs, bool *path_not_found)
+{
+ // default is YAPF type 2
+ typedef Trackdir (*PfnChooseRailTrack)(Vehicle*, TileIndex, DiagDirection, TrackdirBits, bool*);
+ PfnChooseRailTrack pfnChooseRailTrack = &CYapfRail2::stChooseRailTrack;
+
+ // check if non-default YAPF type needed
+ if (_patches.forbid_90_deg)
+ pfnChooseRailTrack = &CYapfRail3::stChooseRailTrack; // Trackdir, forbid 90-deg
+ else if (_patches.yapf.disable_node_optimization)
+ pfnChooseRailTrack = &CYapfRail1::stChooseRailTrack; // Trackdir, allow 90-deg
+
+ Trackdir td_ret = pfnChooseRailTrack(v, tile, enterdir, trackdirs, path_not_found);
+
+ return td_ret;
+}
+
+bool YapfCheckReverseTrain(Vehicle* v)
+{
+ // tile where the engine is
+ TileIndex tile = v->tile;
+ // tile where we have last wagon
+ Vehicle* last_veh = GetLastVehicleInChain(v);
+ // if we are in tunnel then give up
+ if (v->u.rail.track == 0x40 || last_veh->u.rail.track == 0x40) return false;
+ // get trackdirs of both ends
+ Trackdir td = GetVehicleTrackdir(v);
+ Trackdir td_rev = ReverseTrackdir(GetVehicleTrackdir(last_veh));
+
+
+ typedef bool (*PfnCheckReverseTrain)(Vehicle*, TileIndex, Trackdir, TileIndex, Trackdir);
+ PfnCheckReverseTrain pfnCheckReverseTrain = CYapfRail2::stCheckReverseTrain;
+
+ // check if non-default YAPF type needed
+ if (_patches.forbid_90_deg)
+ pfnCheckReverseTrain = &CYapfRail3::stCheckReverseTrain; // Trackdir, forbid 90-deg
+ else if (_patches.yapf.disable_node_optimization)
+ pfnCheckReverseTrain = &CYapfRail1::stCheckReverseTrain; // Trackdir, allow 90-deg
+
+ bool reverse = pfnCheckReverseTrain(v, tile, td, last_veh->tile, td_rev);
+
+ return reverse;
+}
+
+bool YapfFindNearestRailDepotTwoWay(Vehicle *v, int max_distance, int reverse_penalty, TileIndex* depot_tile, bool* reversed)
+{
+ *depot_tile = INVALID_TILE;
+ *reversed = false;
+
+ Vehicle* last_veh = GetLastVehicleInChain(v);
+
+ TileIndex tile = v->tile;
+ TileIndex last_tile = last_veh->tile;
+
+ // their trackdirs
+ Trackdir td = GetVehicleTrackdir(v);
+ Trackdir td_rev = ReverseTrackdir(GetVehicleTrackdir(last_veh));
+
+ typedef bool (*PfnFindNearestDepotTwoWay)(Vehicle*, TileIndex, Trackdir, TileIndex, Trackdir, int, int, TileIndex*, bool*);
+ PfnFindNearestDepotTwoWay pfnFindNearestDepotTwoWay = &CYapfAnyDepotRail2::stFindNearestDepotTwoWay;
+
+ // check if non-default YAPF type needed
+ if (_patches.forbid_90_deg)
+ pfnFindNearestDepotTwoWay = &CYapfAnyDepotRail3::stFindNearestDepotTwoWay; // Trackdir, forbid 90-deg
+ else if (_patches.yapf.disable_node_optimization)
+ pfnFindNearestDepotTwoWay = &CYapfAnyDepotRail1::stFindNearestDepotTwoWay; // Trackdir, allow 90-deg
+
+ bool ret = pfnFindNearestDepotTwoWay(v, tile, td, last_tile, td_rev, max_distance, reverse_penalty, depot_tile, reversed);
+ return ret;
+}
+
+/** if any track changes, this counter is incremented - that will invalidate segment cost cache */
+int CSegmentCostCacheBase::s_rail_change_counter = 0;
+
+void YapfNotifyTrackLayoutChange(TileIndex tile, Track track) {CSegmentCostCacheBase::NotifyTrackLayoutChange(tile, track);}
diff --git a/src/yapf/yapf_road.cpp b/src/yapf/yapf_road.cpp
new file mode 100644
index 000000000..02b306b31
--- /dev/null
+++ b/src/yapf/yapf_road.cpp
@@ -0,0 +1,451 @@
+/* $Id$ */
+
+#include "../stdafx.h"
+
+#include "yapf.hpp"
+#include "yapf_node_road.hpp"
+
+
+template <class Types>
+class CYapfCostRoadT
+{
+public:
+ typedef typename Types::Tpf Tpf; ///< pathfinder (derived from THIS class)
+ typedef typename Types::TrackFollower TrackFollower; ///< track follower helper
+ typedef typename Types::NodeList::Titem Node; ///< this will be our node type
+ typedef typename Node::Key Key; ///< key to hash tables
+
+protected:
+ /// to access inherited path finder
+ Tpf& Yapf() {return *static_cast<Tpf*>(this);}
+
+ int SlopeCost(TileIndex tile, TileIndex next_tile, Trackdir trackdir)
+ {
+ // height of the center of the current tile
+ int x1 = TileX(tile) * TILE_SIZE;
+ int y1 = TileY(tile) * TILE_SIZE;
+ int z1 = GetSlopeZ(x1 + TILE_SIZE / 2, y1 + TILE_SIZE / 2);
+
+ // height of the center of the next tile
+ int x2 = TileX(next_tile) * TILE_SIZE;
+ int y2 = TileY(next_tile) * TILE_SIZE;
+ int z2 = GetSlopeZ(x2 + TILE_SIZE / 2, y2 + TILE_SIZE / 2);
+
+ if (z2 - z1 > 1) {
+ /* Slope up */
+ return Yapf().PfGetSettings().road_slope_penalty;
+ }
+ return 0;
+ }
+
+ /** return one tile cost */
+ FORCEINLINE int OneTileCost(TileIndex tile, Trackdir trackdir)
+ {
+ int cost = 0;
+ // set base cost
+ if (IsDiagonalTrackdir(trackdir)) {
+ cost += YAPF_TILE_LENGTH;
+ switch (GetTileType(tile)) {
+ case MP_STREET:
+ /* Increase the cost for level crossings */
+ if (IsLevelCrossing(tile))
+ cost += Yapf().PfGetSettings().road_crossing_penalty;
+ break;
+
+ default:
+ break;
+ }
+ } else {
+ // non-diagonal trackdir
+ cost = YAPF_TILE_CORNER_LENGTH + Yapf().PfGetSettings().road_curve_penalty;
+ }
+ return cost;
+ }
+
+public:
+ /** Called by YAPF to calculate the cost from the origin to the given node.
+ * Calculates only the cost of given node, adds it to the parent node cost
+ * and stores the result into Node::m_cost member */
+ FORCEINLINE bool PfCalcCost(Node& n)
+ {
+ int segment_cost = 0;
+ // start at n.m_key.m_tile / n.m_key.m_td and walk to the end of segment
+ TileIndex tile = n.m_key.m_tile;
+ Trackdir trackdir = n.m_key.m_td;
+ while (true) {
+ // base tile cost depending on distance between edges
+ segment_cost += Yapf().OneTileCost(tile, trackdir);
+
+ // stop if we have just entered the depot
+ if (IsTileDepotType(tile, TRANSPORT_ROAD) && trackdir == DiagdirToDiagTrackdir(ReverseDiagDir(GetRoadDepotDirection(tile)))) {
+ // next time we will reverse and leave the depot
+ break;
+ }
+
+ // if there are no reachable trackdirs on new tile, we have end of road
+ TrackFollower F(Yapf().GetVehicle());
+ if (!F.Follow(tile, trackdir)) break;
+
+ // if there are more trackdirs available & reachable, we are at the end of segment
+ if (KillFirstBit2x64(F.m_new_td_bits) != 0) break;
+
+ Trackdir new_td = (Trackdir)FindFirstBit2x64(F.m_new_td_bits);
+
+ // stop if RV is on simple loop with no junctions
+ if (F.m_new_tile == n.m_key.m_tile && new_td == n.m_key.m_td) return false;
+
+ // if we skipped some tunnel tiles, add their cost
+ segment_cost += F.m_tiles_skipped * YAPF_TILE_LENGTH;
+
+ // add hilly terrain penalty
+ segment_cost += Yapf().SlopeCost(tile, F.m_new_tile, trackdir);
+
+ // add min/max speed penalties
+ int min_speed = 0;
+ int max_speed = F.GetSpeedLimit(&min_speed);
+ const Vehicle* v = Yapf().GetVehicle();
+ if (max_speed < v->max_speed) segment_cost += 1 * (v->max_speed - max_speed);
+ if (min_speed > v->max_speed) segment_cost += 10 * (min_speed - v->max_speed);
+
+ // move to the next tile
+ tile = F.m_new_tile;
+ trackdir = new_td;
+ };
+
+ // save end of segment back to the node
+ n.m_segment_last_tile = tile;
+ n.m_segment_last_td = trackdir;
+
+ // save also tile cost
+ int parent_cost = (n.m_parent != NULL) ? n.m_parent->m_cost : 0;
+ n.m_cost = parent_cost + segment_cost;
+ return true;
+ }
+};
+
+
+template <class Types>
+class CYapfDestinationAnyDepotRoadT
+{
+public:
+ typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
+ typedef typename Types::TrackFollower TrackFollower;
+ typedef typename Types::NodeList::Titem Node; ///< this will be our node type
+ typedef typename Node::Key Key; ///< key to hash tables
+
+ /// to access inherited path finder
+ Tpf& Yapf() {return *static_cast<Tpf*>(this);}
+
+ /// Called by YAPF to detect if node ends in the desired destination
+ FORCEINLINE bool PfDetectDestination(Node& n)
+ {
+ bool bDest = IsTileDepotType(n.m_segment_last_tile, TRANSPORT_ROAD);
+ return bDest;
+ }
+
+ /** Called by YAPF to calculate cost estimate. Calculates distance to the destination
+ * adds it to the actual cost from origin and stores the sum to the Node::m_estimate */
+ FORCEINLINE bool PfCalcEstimate(Node& n)
+ {
+ n.m_estimate = n.m_cost;
+ return true;
+ }
+};
+
+
+template <class Types>
+class CYapfDestinationTileRoadT
+{
+public:
+ typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
+ typedef typename Types::TrackFollower TrackFollower;
+ typedef typename Types::NodeList::Titem Node; ///< this will be our node type
+ typedef typename Node::Key Key; ///< key to hash tables
+
+protected:
+ TileIndex m_destTile;
+ TrackdirBits m_destTrackdirs;
+
+public:
+ void SetDestination(TileIndex tile, TrackdirBits trackdirs)
+ {
+ m_destTile = tile;
+ m_destTrackdirs = trackdirs;
+ }
+
+protected:
+ /// to access inherited path finder
+ Tpf& Yapf() {return *static_cast<Tpf*>(this);}
+
+public:
+ /// Called by YAPF to detect if node ends in the desired destination
+ FORCEINLINE bool PfDetectDestination(Node& n)
+ {
+ bool bDest = (n.m_segment_last_tile == m_destTile) && ((m_destTrackdirs & TrackdirToTrackdirBits(n.m_segment_last_td)) != TRACKDIR_BIT_NONE);
+ return bDest;
+ }
+
+ /** Called by YAPF to calculate cost estimate. Calculates distance to the destination
+ * adds it to the actual cost from origin and stores the sum to the Node::m_estimate */
+ inline bool PfCalcEstimate(Node& n)
+ {
+ static int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
+ static int dg_dir_to_y_offs[] = {0, 1, 0, -1};
+ if (PfDetectDestination(n)) {
+ n.m_estimate = n.m_cost;
+ return true;
+ }
+
+ TileIndex tile = n.m_segment_last_tile;
+ DiagDirection exitdir = TrackdirToExitdir(n.m_segment_last_td);
+ int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
+ int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
+ int x2 = 2 * TileX(m_destTile);
+ int y2 = 2 * TileY(m_destTile);
+ int dx = abs(x1 - x2);
+ int dy = abs(y1 - y2);
+ int dmin = min(dx, dy);
+ int dxy = abs(dx - dy);
+ int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2);
+ n.m_estimate = n.m_cost + d;
+ assert(n.m_estimate >= n.m_parent->m_estimate);
+ return true;
+ }
+};
+
+
+
+template <class Types>
+class CYapfFollowRoadT
+{
+public:
+ typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
+ typedef typename Types::TrackFollower TrackFollower;
+ typedef typename Types::NodeList::Titem Node; ///< this will be our node type
+ typedef typename Node::Key Key; ///< key to hash tables
+
+protected:
+ /// to access inherited path finder
+ FORCEINLINE Tpf& Yapf() {return *static_cast<Tpf*>(this);}
+
+public:
+
+ /** Called by YAPF to move from the given node to the next tile. For each
+ * reachable trackdir on the new tile creates new node, initializes it
+ * and adds it to the open list by calling Yapf().AddNewNode(n) */
+ inline void PfFollowNode(Node& old_node)
+ {
+ TrackFollower F(Yapf().GetVehicle());
+ if (F.Follow(old_node.m_segment_last_tile, old_node.m_segment_last_td))
+ Yapf().AddMultipleNodes(&old_node, F.m_new_tile, F.m_new_td_bits);
+ }
+
+ /// return debug report character to identify the transportation type
+ FORCEINLINE char TransportTypeChar() const {return 'r';}
+
+ static Trackdir stChooseRoadTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir)
+ {
+ Tpf pf;
+ return pf.ChooseRoadTrack(v, tile, enterdir);
+ }
+
+ FORCEINLINE Trackdir ChooseRoadTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir)
+ {
+ // handle special case - when next tile is destination tile
+ if (tile == v->dest_tile) {
+ // choose diagonal trackdir reachable from enterdir
+ return (Trackdir)DiagdirToDiagTrackdir(enterdir);
+ }
+ // our source tile will be the next vehicle tile (should be the given one)
+ TileIndex src_tile = tile;
+ // get available trackdirs on the start tile
+ uint ts = GetTileTrackStatus(tile, TRANSPORT_ROAD);
+ TrackdirBits src_trackdirs = (TrackdirBits)(ts & TRACKDIR_BIT_MASK);
+ // select reachable trackdirs only
+ src_trackdirs &= DiagdirReachesTrackdirs(enterdir);
+
+ // get available trackdirs on the destination tile
+ TileIndex dest_tile = v->dest_tile;
+ uint dest_ts = GetTileTrackStatus(dest_tile, TRANSPORT_ROAD);
+ TrackdirBits dest_trackdirs = (TrackdirBits)(dest_ts & TRACKDIR_BIT_MASK);
+
+ // set origin and destination nodes
+ Yapf().SetOrigin(src_tile, src_trackdirs);
+ Yapf().SetDestination(dest_tile, dest_trackdirs);
+
+ // find the best path
+ Yapf().FindPath(v);
+
+ // if path not found - return INVALID_TRACKDIR
+ Trackdir next_trackdir = INVALID_TRACKDIR;
+ Node* pNode = &Yapf().GetBestNode();
+ if (pNode != NULL) {
+ // path was found or at least suggested
+ // walk through the path back to its origin
+ while (pNode->m_parent != NULL) {
+ pNode = pNode->m_parent;
+ }
+ // return trackdir from the best origin node (one of start nodes)
+ Node& best_next_node = *pNode;
+ assert(best_next_node.GetTile() == tile);
+ next_trackdir = best_next_node.GetTrackdir();
+ }
+ return next_trackdir;
+ }
+
+ static uint stDistanceToTile(const Vehicle *v, TileIndex tile)
+ {
+ Tpf pf;
+ return pf.DistanceToTile(v, tile);
+ }
+
+ FORCEINLINE uint DistanceToTile(const Vehicle *v, TileIndex dst_tile)
+ {
+ // handle special case - when current tile is the destination tile
+ if (dst_tile == v->tile) {
+ // distance is zero in this case
+ return 0;
+ }
+
+ if (!SetOriginFromVehiclePos(v)) return UINT_MAX;
+
+ // set destination tile, trackdir
+ // get available trackdirs on the destination tile
+ uint dest_ts = GetTileTrackStatus(dst_tile, TRANSPORT_ROAD);
+ TrackdirBits dst_td_bits = (TrackdirBits)(dest_ts & TRACKDIR_BIT_MASK);
+ Yapf().SetDestination(dst_tile, dst_td_bits);
+
+ // find the best path
+ Yapf().FindPath(v);
+
+ // if path not found - return distance = UINT_MAX
+ uint dist = UINT_MAX;
+ Node* pNode = &Yapf().GetBestNode();
+ if (pNode != NULL) {
+ // path was found or at least suggested
+ // get the path cost estimate
+ dist = pNode->GetCostEstimate();
+ }
+
+ return dist;
+ }
+
+ /** Return true if the valid origin (tile/trackdir) was set from the current vehicle position. */
+ FORCEINLINE bool SetOriginFromVehiclePos(const Vehicle *v)
+ {
+ // set origin (tile, trackdir)
+ TileIndex src_tile = v->tile;
+ Trackdir src_td = GetVehicleTrackdir(v);
+ if ((GetTileTrackStatus(src_tile, TRANSPORT_ROAD) & TrackdirToTrackdirBits(src_td)) == 0) {
+ // sometimes the roadveh is not on the road (it resides on non-existing track)
+ // how should we handle that situation?
+ return false;
+ }
+ Yapf().SetOrigin(src_tile, TrackdirToTrackdirBits(src_td));
+ return true;
+ }
+
+ static Depot* stFindNearestDepot(const Vehicle* v, TileIndex tile, Trackdir td)
+ {
+ Tpf pf;
+ return pf.FindNearestDepot(v, tile, td);
+ }
+
+ FORCEINLINE Depot* FindNearestDepot(const Vehicle* v, TileIndex tile, Trackdir td)
+ {
+ // set origin and destination nodes
+ Yapf().SetOrigin(tile, TrackdirToTrackdirBits(td));
+
+ // find the best path
+ bool bFound = Yapf().FindPath(v);
+ if (!bFound) return false;
+
+ // some path found
+ // get found depot tile
+ Node& n = Yapf().GetBestNode();
+ TileIndex depot_tile = n.m_segment_last_tile;
+ assert(IsTileDepotType(depot_tile, TRANSPORT_ROAD));
+ Depot* ret = GetDepotByTile(depot_tile);
+ return ret;
+ }
+};
+
+template <class Tpf_, class Tnode_list, template <class Types> class Tdestination>
+struct CYapfRoad_TypesT
+{
+ typedef CYapfRoad_TypesT<Tpf_, Tnode_list, Tdestination> Types;
+
+ typedef Tpf_ Tpf;
+ typedef CFollowTrackRoad TrackFollower;
+ typedef Tnode_list NodeList;
+ typedef CYapfBaseT<Types> PfBase;
+ typedef CYapfFollowRoadT<Types> PfFollow;
+ typedef CYapfOriginTileT<Types> PfOrigin;
+ typedef Tdestination<Types> PfDestination;
+ typedef CYapfSegmentCostCacheNoneT<Types> PfCache;
+ typedef CYapfCostRoadT<Types> PfCost;
+};
+
+struct CYapfRoad1 : CYapfT<CYapfRoad_TypesT<CYapfRoad1 , CRoadNodeListTrackDir, CYapfDestinationTileRoadT > > {};
+struct CYapfRoad2 : CYapfT<CYapfRoad_TypesT<CYapfRoad2 , CRoadNodeListExitDir , CYapfDestinationTileRoadT > > {};
+
+struct CYapfRoadAnyDepot1 : CYapfT<CYapfRoad_TypesT<CYapfRoadAnyDepot1, CRoadNodeListTrackDir, CYapfDestinationAnyDepotRoadT> > {};
+struct CYapfRoadAnyDepot2 : CYapfT<CYapfRoad_TypesT<CYapfRoadAnyDepot2, CRoadNodeListExitDir , CYapfDestinationAnyDepotRoadT> > {};
+
+
+Trackdir YapfChooseRoadTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir)
+{
+ // default is YAPF type 2
+ typedef Trackdir (*PfnChooseRoadTrack)(Vehicle*, TileIndex, DiagDirection);
+ PfnChooseRoadTrack pfnChooseRoadTrack = &CYapfRoad2::stChooseRoadTrack; // default: ExitDir, allow 90-deg
+
+ // check if non-default YAPF type should be used
+ if (_patches.yapf.disable_node_optimization)
+ pfnChooseRoadTrack = &CYapfRoad1::stChooseRoadTrack; // Trackdir, allow 90-deg
+
+ Trackdir td_ret = pfnChooseRoadTrack(v, tile, enterdir);
+ return td_ret;
+}
+
+uint YapfRoadVehDistanceToTile(const Vehicle* v, TileIndex tile)
+{
+ // default is YAPF type 2
+ typedef uint (*PfnDistanceToTile)(const Vehicle*, TileIndex);
+ PfnDistanceToTile pfnDistanceToTile = &CYapfRoad2::stDistanceToTile; // default: ExitDir, allow 90-deg
+
+ // check if non-default YAPF type should be used
+ if (_patches.yapf.disable_node_optimization)
+ pfnDistanceToTile = &CYapfRoad1::stDistanceToTile; // Trackdir, allow 90-deg
+
+ // measure distance in YAPF units
+ uint dist = pfnDistanceToTile(v, tile);
+ // convert distance to tiles
+ if (dist != UINT_MAX)
+ dist = (dist + YAPF_TILE_LENGTH - 1) / YAPF_TILE_LENGTH;
+ return dist;
+}
+
+Depot* YapfFindNearestRoadDepot(const Vehicle *v)
+{
+ TileIndex tile = v->tile;
+ Trackdir trackdir = GetVehicleTrackdir(v);
+ if ((GetTileTrackStatus(tile, TRANSPORT_ROAD) & TrackdirToTrackdirBits(trackdir)) == 0)
+ return NULL;
+
+ // handle the case when our vehicle is already in the depot tile
+ if (IsTileType(tile, MP_STREET) && IsTileDepotType(tile, TRANSPORT_ROAD)) {
+ // only what we need to return is the Depot*
+ return GetDepotByTile(tile);
+ }
+
+ // default is YAPF type 2
+ typedef Depot* (*PfnFindNearestDepot)(const Vehicle*, TileIndex, Trackdir);
+ PfnFindNearestDepot pfnFindNearestDepot = &CYapfRoadAnyDepot2::stFindNearestDepot;
+
+ // check if non-default YAPF type should be used
+ if (_patches.yapf.disable_node_optimization)
+ pfnFindNearestDepot = &CYapfRoadAnyDepot1::stFindNearestDepot; // Trackdir, allow 90-deg
+
+ Depot* ret = pfnFindNearestDepot(v, tile, trackdir);
+ return ret;
+}
diff --git a/src/yapf/yapf_settings.h b/src/yapf/yapf_settings.h
new file mode 100644
index 000000000..193714dd1
--- /dev/null
+++ b/src/yapf/yapf_settings.h
@@ -0,0 +1,68 @@
+/* $Id$ */
+#if !defined(YAPF_SETTINGS_H) || defined(YS_DEF)
+
+# ifndef YAPF_SETTINGS_H
+# define YAPF_SETTINGS_H
+# endif
+
+# ifndef YS_DEF
+/*
+ * if YS_DEF is not defined, we will only do following declaration:
+ * typedef struct YapfSettings {
+ * bool disable_node_optimization;
+ * uint32 max_search_nodes;
+ * .... all other yapf related settings ...
+ * } YapfSettings;
+ *
+ * otherwise we will just expand YS_DEF_xx macros and then #undef them
+ */
+# define YS_DEF_BEGIN typedef struct YapfSettings {
+# define YS_DEF(type, name) type name;
+# define YS_DEF_END } YapfSettings;
+
+# endif /* !YS_DEF */
+
+# ifndef YS_DEF_BEGIN
+# define YS_DEF_BEGIN
+# endif // YS_DEF_BEGIN
+
+# ifndef YS_DEF_END
+# define YS_DEF_END
+# endif // YS_DEF_END
+
+YS_DEF_BEGIN
+ YS_DEF(bool , disable_node_optimization) ///< whether to use exit-dir instead of trackdir in node key
+ YS_DEF(uint32, max_search_nodes) ///< stop path-finding when this number of nodes visited
+ YS_DEF(bool , ship_use_yapf) ///< use YAPF for ships
+ YS_DEF(bool , road_use_yapf) ///< use YAPF for road
+ YS_DEF(bool , rail_use_yapf) ///< use YAPF for rail
+ YS_DEF(uint32, road_slope_penalty) ///< penalty for up-hill slope
+ YS_DEF(uint32, road_curve_penalty) ///< penalty for curves
+ YS_DEF(uint32, road_crossing_penalty) ///< penalty for level crossing
+ YS_DEF(bool , rail_firstred_twoway_eol) ///< treat first red two-way signal as dead end
+ YS_DEF(uint32, rail_firstred_penalty) ///< penalty for first red signal
+ YS_DEF(uint32, rail_firstred_exit_penalty) ///< penalty for first red exit signal
+ YS_DEF(uint32, rail_lastred_penalty) ///< penalty for last red signal
+ YS_DEF(uint32, rail_lastred_exit_penalty) ///< penalty for last red exit signal
+ YS_DEF(uint32, rail_station_penalty) ///< penalty for non-target station tile
+ YS_DEF(uint32, rail_slope_penalty) ///< penalty for up-hill slope
+ YS_DEF(uint32, rail_curve45_penalty) ///< penalty for curve
+ YS_DEF(uint32, rail_curve90_penalty) ///< penalty for 90-deg curve
+ YS_DEF(uint32, rail_depot_reverse_penalty) ///< penalty for reversing in the depot
+ YS_DEF(uint32, rail_crossing_penalty) ///< penalty for level crossing
+ YS_DEF(uint32, rail_look_ahead_max_signals)///< max. number of signals taken into consideration in look-ahead load balancer
+ YS_DEF(int32 , rail_look_ahead_signal_p0) ///< constant in polynomial penalty function
+ YS_DEF(int32 , rail_look_ahead_signal_p1) ///< constant in polynomial penalty function
+ YS_DEF(int32 , rail_look_ahead_signal_p2) ///< constant in polynomial penalty function
+
+ YS_DEF(uint32, rail_longer_platform_penalty) ///< penalty for longer station platform than train
+ YS_DEF(uint32, rail_longer_platform_per_tile_penalty) ///< penalty for longer station platform than train (per tile)
+ YS_DEF(uint32, rail_shorter_platform_penalty) ///< penalty for shorter station platform than train
+ YS_DEF(uint32, rail_shorter_platform_per_tile_penalty) ///< penalty for shorter station platform than train (per tile)
+YS_DEF_END
+
+#undef YS_DEF_BEGIN
+#undef YS_DEF
+#undef YS_DEF_END
+
+#endif /* !YAPF_SETTINGS_H || YS_DEF */
diff --git a/src/yapf/yapf_ship.cpp b/src/yapf/yapf_ship.cpp
new file mode 100644
index 000000000..038bdba43
--- /dev/null
+++ b/src/yapf/yapf_ship.cpp
@@ -0,0 +1,176 @@
+/* $Id$ */
+
+#include "../stdafx.h"
+
+#include "yapf.hpp"
+
+/** Node Follower module of YAPF for ships */
+template <class Types>
+class CYapfFollowShipT
+{
+public:
+ typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
+ typedef typename Types::TrackFollower TrackFollower;
+ typedef typename Types::NodeList::Titem Node; ///< this will be our node type
+ typedef typename Node::Key Key; ///< key to hash tables
+
+protected:
+ /// to access inherited path finder
+ FORCEINLINE Tpf& Yapf() {return *static_cast<Tpf*>(this);}
+
+public:
+ /** Called by YAPF to move from the given node to the next tile. For each
+ * reachable trackdir on the new tile creates new node, initializes it
+ * and adds it to the open list by calling Yapf().AddNewNode(n) */
+ inline void PfFollowNode(Node& old_node)
+ {
+ TrackFollower F;
+ if (F.Follow(old_node.m_key.m_tile, old_node.m_key.m_td))
+ Yapf().AddMultipleNodes(&old_node, F.m_new_tile, F.m_new_td_bits);
+ }
+
+ /// return debug report character to identify the transportation type
+ FORCEINLINE char TransportTypeChar() const {return 'w';}
+
+ static Trackdir ChooseShipTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks)
+ {
+ // handle special case - when next tile is destination tile
+ if (tile == v->dest_tile) {
+ // convert tracks to trackdirs
+ TrackdirBits trackdirs = (TrackdirBits)(tracks | ((int)tracks << 8));
+ // choose any trackdir reachable from enterdir
+ trackdirs &= DiagdirReachesTrackdirs(enterdir);
+ return (Trackdir)FindFirstBit2x64(trackdirs);
+ }
+
+ // move back to the old tile/trackdir (where ship is coming from)
+ TileIndex src_tile = TILE_ADD(tile, TileOffsByDiagDir(ReverseDiagDir(enterdir)));
+ Trackdir trackdir = GetVehicleTrackdir(v);
+ assert(IsValidTrackdir(trackdir));
+
+ // convert origin trackdir to TrackdirBits
+ TrackdirBits trackdirs = TrackdirToTrackdirBits(trackdir);
+ // get available trackdirs on the destination tile
+ TrackdirBits dest_trackdirs = (TrackdirBits)(GetTileTrackStatus(v->dest_tile, TRANSPORT_WATER) & TRACKDIR_BIT_MASK);
+
+ // create pathfinder instance
+ Tpf pf;
+ // set origin and destination nodes
+ pf.SetOrigin(src_tile, trackdirs);
+ pf.SetDestination(v->dest_tile, dest_trackdirs);
+ // find best path
+ bool bFound = pf.FindPath(v);
+
+ Trackdir next_trackdir = INVALID_TRACKDIR; // this would mean "path not found"
+ if (bFound) {
+ // path was found
+ // walk through the path back to the origin
+ Node* pNode = &pf.GetBestNode();
+ Node* pPrevNode = NULL;
+ while (pNode->m_parent != NULL) {
+ pPrevNode = pNode;
+ pNode = pNode->m_parent;
+ }
+ // return trackdir from the best next node (direct child of origin)
+ Node& best_next_node = *pPrevNode;
+ assert(best_next_node.GetTile() == tile);
+ next_trackdir = best_next_node.GetTrackdir();
+ }
+ return next_trackdir;
+ }
+};
+
+/** Cost Provider module of YAPF for ships */
+template <class Types>
+class CYapfCostShipT
+{
+public:
+ typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
+ typedef typename Types::NodeList::Titem Node; ///< this will be our node type
+ typedef typename Node::Key Key; ///< key to hash tables
+
+protected:
+ /// to access inherited path finder
+ Tpf& Yapf() {return *static_cast<Tpf*>(this);}
+
+public:
+ /** Called by YAPF to calculate the cost from the origin to the given node.
+ * Calculates only the cost of given node, adds it to the parent node cost
+ * and stores the result into Node::m_cost member */
+ FORCEINLINE bool PfCalcCost(Node& n)
+ {
+ // base tile cost depending on distance
+ int c = IsDiagonalTrackdir(n.GetTrackdir()) ? 10 : 7;
+ // additional penalty for curves
+ if (n.m_parent != NULL && n.GetTrackdir() != n.m_parent->GetTrackdir()) c += 3;
+ // apply it
+ n.m_cost = n.m_parent->m_cost + c;
+ return true;
+ }
+};
+
+/** Config struct of YAPF for ships.
+ * Defines all 6 base YAPF modules as classes providing services for CYapfBaseT.
+ */
+template <class Tpf_, class Ttrack_follower, class Tnode_list>
+struct CYapfShip_TypesT
+{
+ /** Types - shortcut for this struct type */
+ typedef CYapfShip_TypesT<Tpf_, Ttrack_follower, Tnode_list> Types;
+
+ /** Tpf - pathfinder type */
+ typedef Tpf_ Tpf;
+ /** track follower helper class */
+ typedef Ttrack_follower TrackFollower;
+ /** node list type */
+ typedef Tnode_list NodeList;
+ /** pathfinder components (modules) */
+ typedef CYapfBaseT<Types> PfBase; // base pathfinder class
+ typedef CYapfFollowShipT<Types> PfFollow; // node follower
+ typedef CYapfOriginTileT<Types> PfOrigin; // origin provider
+ typedef CYapfDestinationTileT<Types> PfDestination; // destination/distance provider
+ typedef CYapfSegmentCostCacheNoneT<Types> PfCache; // segment cost cache provider
+ typedef CYapfCostShipT<Types> PfCost; // cost provider
+};
+
+// YAPF type 1 - uses TileIndex/Trackdir as Node key, allows 90-deg turns
+struct CYapfShip1 : CYapfT<CYapfShip_TypesT<CYapfShip1, CFollowTrackWater , CShipNodeListTrackDir> > {};
+// YAPF type 2 - uses TileIndex/DiagDirection as Node key, allows 90-deg turns
+struct CYapfShip2 : CYapfT<CYapfShip_TypesT<CYapfShip2, CFollowTrackWater , CShipNodeListExitDir > > {};
+// YAPF type 3 - uses TileIndex/Trackdir as Node key, forbids 90-deg turns
+struct CYapfShip3 : CYapfT<CYapfShip_TypesT<CYapfShip3, CFollowTrackWaterNo90, CShipNodeListTrackDir> > {};
+
+/** Ship controller helper - path finder invoker */
+Trackdir YapfChooseShipTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks)
+{
+ // default is YAPF type 2
+ typedef Trackdir (*PfnChooseShipTrack)(Vehicle*, TileIndex, DiagDirection, TrackBits);
+ PfnChooseShipTrack pfnChooseShipTrack = CYapfShip2::ChooseShipTrack; // default: ExitDir, allow 90-deg
+
+ // check if non-default YAPF type needed
+ if (_patches.forbid_90_deg)
+ pfnChooseShipTrack = &CYapfShip3::ChooseShipTrack; // Trackdir, forbid 90-deg
+ else if (_patches.yapf.disable_node_optimization)
+ pfnChooseShipTrack = &CYapfShip1::ChooseShipTrack; // Trackdir, allow 90-deg
+
+ Trackdir td_ret = pfnChooseShipTrack(v, tile, enterdir, tracks);
+ return td_ret;
+}
+
+/** performance measurement helper */
+void* NpfBeginInterval()
+{
+ CPerformanceTimer& perf = *new CPerformanceTimer;
+ perf.Start();
+ return &perf;
+}
+
+/** performance measurement helper */
+int NpfEndInterval(void* vperf)
+{
+ CPerformanceTimer& perf = *(CPerformanceTimer*)vperf;
+ perf.Stop();
+ int t = perf.Get(1000000);
+ delete &perf;
+ return t;
+}